From b8def9310afa6bb5d7d8d2dd844e3d3fefbbe5ed Mon Sep 17 00:00:00 2001 From: Marc Robledo Date: Tue, 14 Mar 2017 20:32:40 +0100 Subject: [PATCH] first commit --- index.html | 91 ++++++++++++++ ips-patcher.appcache | 6 + ips-patcher.js | 290 +++++++++++++++++++++++++++++++++++++++++++ ips-patcher.png | Bin 0 -> 16225 bytes 4 files changed, 387 insertions(+) create mode 100644 index.html create mode 100644 ips-patcher.appcache create mode 100644 ips-patcher.js create mode 100644 ips-patcher.png diff --git a/index.html b/index.html new file mode 100644 index 0000000..033bea9 --- /dev/null +++ b/index.html @@ -0,0 +1,91 @@ + + + + IPS Patcher + + + + + + + + + + + + + + + + +
+
+ This small web app allows you to apply a IPS patch to your favorite retro games. +
+ + + + + +
+

Apply IPS patch

+
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+ +
+ +
+ + + + + +
+

Create IPS patch

+
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+ +
+ +
+
+ + + + + \ No newline at end of file diff --git a/ips-patcher.appcache b/ips-patcher.appcache new file mode 100644 index 0000000..bd20b70 --- /dev/null +++ b/ips-patcher.appcache @@ -0,0 +1,6 @@ +CACHE MANIFEST +# last update 2017-02-28 +# these belong to the CACHE block +index.html +ips-patcher.js +ips-patcher.png \ No newline at end of file diff --git a/ips-patcher.js b/ips-patcher.js new file mode 100644 index 0000000..20e0a7c --- /dev/null +++ b/ips-patcher.js @@ -0,0 +1,290 @@ +/* ips-patcher.js v20160416 - Marc Robledo 2016 - http://www.marcrobledo.com/license */ + + + + +/* Implement 3-byte reader/writer in MarcBinFile */ +MarcBinFile.prototype.readThreeBytes=function(offset){ + return (this.readByte(offset+0) << 16)+(this.readByte(offset+1) << 8)+(this.readByte(offset+2)) +} +MarcBinFile.prototype.writeThreeBytes=function(offset,val){ + this.writeBytes(offset, [(val & 0xff0000) >> 16, (val & 0x00ff00) >> 8, (val & 0x0000ff)]); +} + + + + + + +/* Shortcuts */ +function addEvent(e,ev,f){e.addEventListener(ev,f,false)} +function el(e){return document.getElementById(e)} + + + + + +/* + IPS file format + doc: http://www.smwiki.net/wiki/IPS_file_format +*/ +var RECORD_RLE=0x0000; +var RECORD_SIMPLE=1; +function IPS(){ + this.records=[]; + this.truncate=false; +} +IPS.prototype.addSimpleRecord=function(o, d){ + this.records.push({offset:o, type:RECORD_SIMPLE, data:d}) +} +IPS.prototype.addRLERecord=function(o, l, b){ + this.records.push({offset:o, type:RECORD_RLE, length:l, byte:b}) +} +IPS.prototype.toString=function(){ + nSimpleRecords=0; + nRLERecords=0; + for(var i=0; iromFile.fileSize){ + alert('Invalid ROM file (too big?).'); + return false; + } + }else{ + if(rec.offset+rec.data.length>romFile.fileSize){ + alert('Invalid ROM file (too big?).'); + return false; + } + } + } + + var patchedFile=new MarcBinFile(romFile.fileSize); + patchedFile.fileName=romFile.fileName.replace(/\.(.*?)$/, ' (patched).$1'); + var clonedFileSize=this.truncate || romFile.fileSize; + for(var i=0; i16777215) + alert('Too big ROM file'); + }); +} + +function openROM1(f){ + romFile1=new MarcBinFile(f, function(){ + if(romFile1.fileSize>16777215) + alert('Too big ROM file'); + }); +} +function openROM2(f){ + romFile2=new MarcBinFile(f, function(){ + if(romFile2.fileSize>16777215) + alert('Too big ROM file'); + }); +} + +function openIPS(f){ + tempFile=new MarcBinFile(f, readIPS); +} + + + + + + +function readIPS(){ + tempFile.littleEndian=false; + + if(tempFile.readString(0,5)!=='PATCH'){ + MarcDialogs.alert('Invalid IPS File'); + return false; + } + + + ipsFile=new IPS(); + var EOF=false; + var seek=5; + + while(seekmodified.fileSize){ + seekStart--; + } + for(var i=seekStart;i>0 && nearbyDifference;i--){ + var bc1=original.readByte(seek+i); + var bc2=modified.readByte(seek+i); + + if(bc1!=bc2){ + length+=i; + seek+=i; + break; + }else if(i==1){ + nearbyDifference=false; + } + } + } + + var data=modified.readBytes(originalSeek, length); + /* check RLE record */ + for(var i=1; i0;e++)d+=String.fromCharCode(c[e]);return d},MarcBinFile.prototype.writeByte=function(a,b){this.fileReader.dataView.setUint8(a,b,this.littleEndian)},MarcBinFile.prototype.writeByteSigned=function(a,b){this.fileReader.dataView.setInt8(a,b,this.littleEndian)},MarcBinFile.prototype.writeBytes=function(a,b){for(var c=0;cCgS9#w5)_Sk@s_yA! zdV2QJ%t)irF0t4`NJa=5vsf&4j1bN_7>uzEj$=E-%SnzCpTs0K!7+i@v5}Kw$p`@g zOGtn~iewPlM(aqLMYHwv^j1sP`syt=|9@}YTDq&dtGlbD9^wa2-Ca}l>b-ma<@Ztpg>yl{ zbs&$=lf~C*Vb0-s7SBAMNAY~7{yT)VBpk^-3eWlf8w^8-AW&elc^M?f=}~GBi^lNz z94O5M__K`n8v>@_^DzLGnGh%*_<9L6KMcATfvPnLYG6Rf839k9$DhOC8aeRQD%8wb z&;ne?z{2-N`Fnk>EY@J1hYsh}fxD#yoH&4apgIvlckTW7^K!KsyGorOycP*zi|Uz4 zTwQ#hkDm#EHo4~daJDoJ;cx-c=`=(l5q?GA_mO}VNNrOF!UGEA&je7KWe_ky*b9zn zJSXvdAYlFzrf$DrL+VI{P1hJx@tb_S!}DuN^^L#b#4*sl9<8wKV+C*O+X_=2bQPpB6^T^!#J$rq z{4)WpW$%g8YhojPJ*LeMy5+ZEp!B2mgWTPL-__(vG{%U=>jfv)R(!*jVT z5<>~%@i-Df3dOhqs22F9MTZm!#Wa{b=0i2lz;p06^j1P({QrL7>6&WpOTqSi31#bT zf$B_~W$*q#tKOs7rTYW3S_n8H1cDa+nE<*tBnQ)mRijsG*|FQyO6*+_=v$G)kSIK% z0@m{ts>)B#^I>LY4oamms)ZD)g(wn55fmB8SmSGP?{GnR|&%f2kD5p?|-{S^nzw8+2o(NEv^JnUT-u?+B07Y!PUIW#& zK`jh^P%XzljNtEP0(X4Fk&}AOM3NAy)e4+FTjjVQnM^`78U=<35p*9cO92a|L3EJ8 z{3H^>EZqeHR=igiw_gFR<$4MNK!<-;0eh=f9Q(A*iqCmouY6@)We(=&ky>3m(_!#{V8X^J>27ngmg=5h>R30WC=;lY!Hx z&+wlNMZ1Ooz{gt(P&37b(cHU42Wyi9Iueed8;B_w|GcKD9AD5+A}D&DTeYf-W?KbK zIqT|ZY4_hJ3kM&Ml(*kX&rTBI|1$z$oU0ky|5|S34d$tX_vy1+ZwKGFlyAK1zrG8C zVw^bNbzQ^ZEowI=`%YXK^y)iW;k5O zZ={1ZoHn&mslw#sBm%`ES^*jt^|fjZ%0-9&j+TJXrMlL@6+{TWA1rxo?gT=KV7T#{ z;>G=sL`r-93{^zL*APD_{!bzSC>+Sqsn2eIzj5l|6IwC-DI^AMy@@1fGrfG1ZD3yd%Xo`Qm@vP){BGs|dK^{ZI37SON``;fZ4uAc%k_4{} z0cafE51>i+H~P%Bf54~S_ga9vUP=SUafB4$RzsDWkV4O+$*5{v0?^;2LZtX7!stdN zl8K1s;l5aL?>|H;JO4)W!UF+U3FkEd2rnM#dd0P_HO}pML@6gfvJv$BS^y%cbH}Oi zjV%-k0?X7lng~SdeIk%f`hP_-sN;iBZPP~*g-ajNz3{b!4afrNr!?pr0WjU+u3Ig; z`4igw@Iwgl_VHlPMsqL85ZoU$^gj`RI8}lE*LZE>d<2R6ENA?oNO|WcXbpX} z(l;XLiyt6ByI!e8!Iyxx4` zbOM91SeyrvNCMDi6Q>JnL2HPAz6@;r<{XKBvJ^tK;g1hy-g3X;4h;BOX=4+B5es1U zxW6kjaqz*dBfD=j!U4CH*Dew_4gthsF)$31dkeW$(*S^KW8>+kR13X2Nc?MoePcTN z#s@>r$gW;Hj?}e_L_AdyA)~mt6;oh-lI?xvyYBaEWjHuEnt&}^w!px^0MPmnA*>b{ zZG?mJ1x(ZAF#`I1ety2r{eHtt6a)cl27oJ@i`Y1c&x(?Rn?2pILYfYfUO0(pjw z!@#W&1u;1Dl)v}*BmRT9!$XEGxIuCcot71b&6_PWpXMQ(&7&SI^RO%V%s28uQY#z| za{{1EC-F~2Ae=)1=Xjz21MUkD`akH>{$B$TC`f!@4yW>0KB)QOYb)02mpSNEYv3VX zpoEv#R0Y^^fWkBzfAvxCd-&3j-m>}aVpQOOcs#+S!O+k!E~2`j@qu*eP*hMjc>-{p zD(8G@0uuL2B9;N5KHDNF_DKT4P`r5I_Y5yNE-=A5R6x^yUEN7KKXWn|cAh?G=Xu~_1pPGVjLv^i52I=r zZf!TNzdZiF@XbmVC_%l zuDnzCk{~mVpaBZIJN56}^M6+b{(Pkh$?ysSI<`FtL7 zxg6KAt)^AK-Mb5!P(I7x;2>fbi*FLCE4nwjXWDd94I+QQXlyF|8(mA@_j1fFzndIM zBt>K#VYNg+DdT!z-;mC};Y-=X-du~1?9qv??d zgtRb!n6+^)W-7}nta?xniY$RAjrpP&j>ZRn%1;)PEZqAz@rtOK?R z$D3}1y1NM#iJb};{L`av@CvEVc}fLlXDbj1MZ7 zEDyTS^;)GtJEyQFH~2x_4a-_KAL=ezsDo41_ES+MspEi7cJ`b%48UpbzXXmd@ zpNmIQ)&<}i)(Tnxc6H0=kU5_zL=XRnV+7Wnfu|EyccmA#8u&Rg>Sq#nAmN7OVibx6 zs8lP+y%C;OE7PvK5oxsfQoqt?NXH6$TBrtE93lb|m6F4o*KKa1czq#JblxEDz~XvX zBzH=JSV)ip;B{6HJ@J`?S|`|E_zg(?Xd$b*`Hr%6>VR)ni`~ZDlrtwLS2Xvmumw*& z@(LXK#{8FUw&}xa$ZuO`x#7gYlxI)bwNfuGeO+37AEu_J8eoXbMfx0xf5~;y<=W&h zr2)L!#c4aL7QZVk`grm0Qu2u4&1;>Usc?S?flNv=SwC^1>Iy6>C%Zitf9kfHF;`DP zU;ept;@o9#6R!~pYhYKl{(MZyeAuJ>HIKD%h!oLeD$UK!aZVdgk}$`e?B}m2(Dk@0Exn)3(>k%3sinZXr9D) z9Pxo^hWKW-5`vT%bduQD>iKqROC6Tf-ObHxa<2q@oiRbXs_69ZYt`MoBmn6<=%M?H z6G5c1^Uurnseg3LX-D^?%MzK|VxlfO4P?qnhQYCiygzj+-Z*Fha;l9$Z4-CqP*p71 z@2wjv^5euNlIwJOdWM^LGIA!lSD4+ZdQf;x%3d!dv2B>|dPW2sZ^ z%Xd?d2m#=DqHyp}bw37yvV6{^uIWp|lu%58(@%Mq&YcK;-HHl!6!xydW8);YDNl|( zWb}IL21`O9;+UJupc&Va;JowtLzwTVIT^-|o6UjrXG!xKR(iC0*_>fu`- zeEi)ADO}x=0BV5`U3=}Cmd0X2mCxB~q0sNOn%kC6)-y+z>VV}8|9ZHx^?&7K&mB_y z$dXb(SG3L#MhjA!3t-}q_g^%leL)x}1dk*BWHN=KKEll=()}dT+7YzU2$@nQEjdpt zE5u{#L=5zAq%xMa?OB`D=(JeP*8{$>EKs0U^`TmEa8nr&@rDvABnDK_O|jr+2&I=B z;E7_`Q=mBKfm1;BRq%N=P{_0q`%uq7}$h* zzs$`xN}HA@9#vD2m?xww+`u(XJci+M(~+bIdD&W>H0=w;8oIt+?=Jv#fePh$2Qdm> z+XhH(QDM*CI1FwJ!{!}vNR7nsb;cK+152IsFB8%M@5`$I*K}!@1Ku7{}s)* zJ0qY|FU>6y{idxzITOG$U#%TM(Yc!{V!O5JX+g^6BI^BlF5(C$L?YpaN!R+&Bn8f$ zJIB3$WHq#dGPVei%5_@^00ZRU65@^Fy&>3fc@nl=n1ao_anloYO&zUd53ve@P>(Iz zFupMaLUlS(LhuNA09ll1Q?C}`=%Hyi@mvOu{5S(%$$(heLMgHsr!3YGP2y~IM78=b z2m^(~HkX3^AOwXO6uCG$mwIH6rx#HQm>nEJvBe*>@U@eV`R_xKxZ6r}hg8@Cd_avC zNG(W|yU_e<4P1yM5v9H`3q`K72>402E4`OExKggdn|^5s-tpmsV5k;up9eJuH!)jT zlX&F`ph%E=FG;|@OSaBs}`HV{qt!DNtPtA}N!17HN7H7ZPeyV$m(M`y$%? z5JU+50fdM#{K#(G+5En2=*hb@#aaYz^k6|GmbgEEHqfSC^#4e=R)1F_>?`m=Iz7O> zcvMs&ojdJdigEQpL_+vL>hY#}VceH5b*5Act&8mx84T=F;H|%~4|Lr8%-noEO{$5) z*K(8!Whe>xfOx@x3oqRcdoCS@XWw=T{^{!{;N?fNU??^cg3<6s3gq9}8fZ6Bn?%xY zUj&(j;mWo@DurMDnx_|h)ep7NfV#*e!t>12{w?JkJD{&43t8IzL3X@V)%vZ+eF3J1WB7#!@CDPO&wvzrk`w5BR)QomvRaWSLWbbmD3Mi>j_f)=B`<8%PgB-anB_?bIWEPpPAMyY_E|k^Lq-{ryu=E2v;aw646GGA3f%7GD<%jLBTXR_U;AVo;IMd~3U}m%e~Z zQZs@m=*$M~Uw!I#x%<3U6rRS-_Dp#8A9J9ji?IKyA-uN6u|+?LfLkNA3T)dk z1lul)!z)iuLJ1{-X?2-wqe^M$H=a|bipkP55k6P!ceu&qM&+1zoMWFur{=B*zta z{N7WbDJI8ND;;99b*}cBmQORt*1$Wu-T;i!l2}L-%RVDA3GS_L*vj3y7Y7}sfcC4m z{SN3zskrg!>6iS!K=E&_l+Y--opd^FD4B4Q+gnW>0z~u>WZKcD)6a!TA~IdPReeaO zlGKYbQM4;M$A`32h#!~*&wOhhg4jIld*dc5Sq9$=`WXEa_g!-x*tUBUuuv6Vd29}! z!CVnf(VCHkBpF6pKGNwW2tweZAP{RTL+7+c!jYu3HK*t#A*kTgRHEZmHS<5K{(Qy9 zb=OBP(snUKK2Dg0TQYhg9Rm!!7$n6g%2=F^x zc;~H`!ii^d@X~`NNRQcELM-(eTBkyx$km^GZrQr7mBWQsl?b98Z^;TJZr5vK5#-*; zq*m_r)5*~tPP$e9#%%QP9a@0qwp+o?s!^wJ|K^31+Pg`5RG=+5^LAgGOQ_F#mC;epT2f~G$UH~-3BBnk^E z#pavSW8`>WF+Bps5Y!567|FcG82pbZVyef z28L=)Jdvt_0%8m~!wgc_7%XNup>wWIVboeN*yq<^w_&Tig$s#yvGHC*XSXA9VZYOc z)BBpLV0{H0{Q7(Wh!8w}EyK`YWMr7ThbhBIB$RXwe7T!8GUCH#Ed&q!We!~D3Hade zAB0Fe#KXt^k_5!bg;E)=d(VD2{$vggf4=~+wAuYSv@j5@HGylHL(sGm^hSfKR^Ll& zf~=^>Zb^@$&j!|RrE2eUnev?Wro_i!>Sgz4=Bw{TEZ;!#l9D8~$(y20CqO3yJgsKl zngNy~xRup(+#rv4<&4B^2w8>*#+XLEHowp@U3+C<2oOpHV1#sd<{KrLotuR#ZyrTr z3V~Dg`s6GEaBChP96>4d&wO{1tGA^9;c`BMrWxG?d9)t12hBj6s8kYrwfM7=IK-YB zO1_l&aXIfD(r)>{dtm0U@^M_GE4{#J^u3d!zTLie>Oq=zsj%*dl_$cY<5%dg^NnE$ zC4I=9_Q`(@sxFW(alWV#@YW<{h`@|U0FgupUiqGbL@)yft{;T39foS9KORHcFjR_= z9Jb*2v(u0{<3Y$)J99vn*}<*ZQN#?S9tkK@mX+9Gwz70#Iu-g%v5`~X(mwH<9|JEN z{u8&P4510wmg!42y5M#);k*UhzRn&vtQkl5stR0ig8^^-=w=w-ABQamEfk+wm^|!q zE+sD(nMqZr3Z-IcO;SLbh-TCWJ7&Oh-zq~Un}Mrt8UfR?5V-Y+2*^{IP9?xqs_^^| zrckPx9VKNqW%AN2B(e*C(@7#SXJIbfB-YZtROM_1?`;&eq+SR=>HCNp&>$= zB3Y5Ro$Pi34x$^j(i^{Yi^GC+SV#|pm1Jrs|>eGxU{{#p2I;EGcXW?3*R)%O~mD*f(zG70BjK=rvw`@ z<|fpVfXZ6j>|F++6p9OkZM6LkszFuXO&=8P&zwdzPA^QPW-7Gs@sqwHkwrOz^uY7^ z0!*Ae1EEb0MB`ze-X*aGEmUE)23Nm-1TOk{`Wq2@U_uhbX)m&9$vQ9-9;%xVyl{^P zpZ}MSLq3;>#9+AhM8NYfG*oX1(CmN{U}qfAx^5!Pp4Mw{aDZ1&)5b3>u#vEYoz`4pw{GhksVlkWM$>Ao z>~E%2>h(5cXeMj2dK#F`%fh13Fux%(;ijjjVQOlcXAE;Q)6*a^YQW%F7(8b&R}&Fb zN;Sw$I&jS`!?5Qj2GxQGVKd%UH}0;8z(w8+`>^Au40!4O8hr6%PeG+x1~c5-CaSe6 zs)3O>5U(q4+48jWpJdl4N8oMC3=T{2kIq&>c|*lqI}bMNv2`XX~v;w-W)8 zh$1~rVvD$*+?#WASvYrYidP2_*URV^z2B`NLf&jaD5|0a2$nRZYL15+@52>8Hw2^C zphZ$<+(hhEVI@OJpxHi*9x&kW_e${8{Sy!ko4wTnjEZeENRFCll6KAspmICfcs{De z_gAIrS{-rSB%|=$$v_`QxvV5syZP-%UaJ>*n*4Wi2~)Wkfk_b>_FF(oyI%AH7t&)S z(k;jron`H58qmNH16+ISW(Y+l;QN1@2j-x(v6PaX6)LCrvjGM(RLC-TBsAcf!nM9v=J33EyTQx z-8YbYOOQg-^wq32-%u*j3|8^r^gV@q1ve=M@BP$4C>0)u7w#`YYEz_MySF|)O{wrS zHMAe26ats={)$#y1!r#IY~tSeTV%orV?Hd~|A0YQR~5|)kaLA!*=nFpVZv#g+hsuq zak|j$)kccd+TF5@gCZ+xH0=Lw54x}1ESiMLFns6_uZFLuo`J{ioQ33IloP>PF#&Zx z2`6>fw9N)L=tIxKdYKrn!yx}4Yx?zNs~XvQe!YPxnO(j7?I@OxUuwAcMiTAP!z6Tx zNGKq8u&nqc&JXH!_3O34g-8dU!@rgtBS}!ql_8-;;XR+c1oAUKgqOZoge2-%ZH<_~ zLr|IAro+g#1e$IA=w7ODaLECfqPBTiNy5tbelIKzKE*Up8ZP7|4nvpbTkFglqC_d; zDc?_WyU0xGp-x1Ob1G{O$C3)k%@rYzlHk@qyaw(WdKRAgI#n9mpsYa>(57!jlpar` z1St0&1X2TvT7~MBEwB<15LMTVt4>)y-zyx@tkz!sIaCz!Zma$vht1T~3?G_Ed1|uZ z!@@Z8`ng{;aVTUeyexao$eJ>TQ4#>t-~+#X1?+!o4DxejZfi?lIt_NF$>QYw5~tVl zyU%^&yib7cz@Ezo!7@U9Y5T5e3~KWTdds-swpPbYLIU>s`((Iy1qYu?!m`@%zazJ2 zGILxviE5QTmaQtHw>}ZUdR?w`ui2S-hVFCQbQ4_%=dnnCC{c}9%QG=NN}1U zO4j5C8RY5Zx;HHXS$4m$b{)zzZepI>zjYrzg=wixYrhYQNh<-O`H3312sFvuT<`1v zB7(W;0z?xQy!ZF^!ZY{G!>NZgD4q<1LA?#@wmoxIE_uLmATjR2&_xWkULJ#yiwr2w zdz33%pV!yJ=cUT)iVqWq3vI3N7RFL~Ed?YNSgc}r_T@ZE0LV$&pc|kd4o&uusbT#( zco(v82xccr$hlRp%rN))uV2rqP@1nod>{;$zBdB-%oOA@8t)uJnMG7hY!B98U}$gacdmN00z|wb%#@XUkwmL-5vL8HLIR z5o=TeAm=1``LwVLktCX3fE=Iqc-}##CT0N;r;51%&{HDd&N9SQ;j{w9X}08M$%?4n zO4|$Y*y zyl;IL?vYTvDYY=;o~1!g&7g!|Z|i3Ee+CXk$Pk!Kyyzg;IX&-^K@Utmj8fh~bJKxh z)LGt1n_+Fo6|h|*R*ulNJlFXP+VlarEj&G4+pLt<~;<+4+2VO&?dX2_G05j8K2jz z??m_;XyuCL#-3Fp;YcQ^SVx_baG5sSwg7@byYCJmqOZh=LBl8E@o!B+B(3+Zg?^8T zK%~pB4--)8`{vO>c;hdQLbX=r>1dtTC0KJ)i-q-@vP8ehbvpQ(bF379>6}XOZ`HTH zUn?l!Gq)j@#KcdFpZy-^rf31r?0NF;4CH1@8%_!=#02Xi0=!HSt&^+YwgYxtV?!}h z>)1QEbzI$Q@3FN^U(Psg8?r%;Kh=AbsXnM&+-v#|{gR1xc&)8zA>DwS`q9sWQo_?) z4VXL5;Mwm@Lt@x~jW}nz7bYTIgVN#22l19)*a2#|%DbJ){6JatD=L4xotP#qxS&y@ zzii7G{4QTF{U}r(6KO9f1)hYe-dzTd(&3(iSzxT$$rpy_DbUB3+($Ne{}}xhG5Z z(R$vK0>^YU^nzE^+nO`drjtK_q(HxC{F0+2F{(rUgaP0F+-aVsP3dAAT@tL-I-s>B zQ}C@nzYh+)Jpsj8lnTn~k}X&oee8H!M=uy)@o1fQC@Y{=tFNhPm1=0P zWq%w_9X$uRGYmquzC3`C8|lkYyR2v4j5lICLmQnrf)nI zg%ADv%V6Z<0P-^qH`74rgzEi9*Oq1)|MD9z)D-Y)qwU+b!RY81jO~lvyY+%iuyfDW z*3?(_AX4#+Up9GEjzQ3tCiYr@LE$VxRWPPP*owhd|Lp`!oS1?1W_v@bf?jwGDP}<# zOi?=y@BEE@5Z~^={H#Mo8wJJ9{q+n9JTP{N0ZPS&zy8=O@ao}n2oP;(41)Rz zlLUnJ=jQS-IGlnH{qbcmdKu%cak7q@;BMsymrcD0NDdATA;)ir@$qp!(UtbCT5=&a ztlS$;DjBaLvXayVI`}IZnBWx*@D_Lm#jvOT#|JnK1R`yG>|zV@$1M1(UpWFVJ$@FF zBWAq}dgBtoTKxp{`TT4N22oVM`_mV~z=baFG}cWGtQ7Tf_Ojsk&D@hKfuiil5*bv! zn%<#7Y8#$gwRQr)H$9}A>KQ;OP%Tn%RJ$kYwF(n+YNj!7;KGh;Ebuci_|iv?!H@5I z6;fMFu)@Y`au2;A0y!L0o-1L3+1VVV(s8)$kFS8?gADT1Re=eXu>$D2BO@co@jL1p zZ!c0AYIGE!iO+uiqVkGRKO_u{Pr$Rz7%5R zGmAquqzB@#{lYYqrd0UR*Uo_+tHRccBM^?-;8ucl=Mwgd2;|rtO01cfn1DNC33aM}euIM7^Wxky@iuC7;frYYko3O9GJ5FPRfZCFax-gPI^w ze<0mZVPsbfypj$NfB77|^7u529?)Uy{sfwo%FE}d{T>a< zre_@-99*^rfIeR;R$;E#6R;Otmq+3P6U4c#n09iz)S0Dt~%M6DPPi%Ei@G4#2(?94*r!ZMQPGXB{T6sQl3?ql+hE zCvrhTYRllr)UXX(FN#Aor^3_U%);{zO+!9YfWhr1Z#H2^LY(4xQtRtT0L1muliJ?; z#pbgTY2%2CS5gP1QWa8zaoGE&G~}l|Fe}4+h^5!1Wgx}>$VK|U8M#nGf`->WT%Z^ep57wZb|t zT9xkUwI0NsvfZv^6iEd1{G<-Lk_2^3kVr;gaHj#Mj!i>t&aB_#%J=6vGzU_7e(&3i z-$W3|7WQINKL5^BONpSHY8C%JNMumVqH(BMEiK6uJ{6p52UjW*l}MD#ND3?w2ar#J za0T`LrJjV6uxRr`A%lmY8(~phP%4Qr8sl2dFeqgLJ}TCZ;6msoS4mS7voJT41I2P+ za0iOYi*!D{W6S;s#D;Vj9F2*}+fIu{g)t~L^0Q^0J4hyI5+w~4iO|1MBTKTOS2K-F zR9aQ}Y(E82XSXex5v zM9<+?9Y#Oty&+4lch*+GEzza}lx7)Fw31>JX2|4DDUB+aNtYS43=Wi?5^q>RDxs8f zIdO#&KAMgO;)D=#f&uX@Vmca6izY+2rf`&9DS0q|t_JhdqD_5b$mBhP_P-?!;}?bz zf5aegG$`h3En{a_mIAb4MCc215$WG()2Rk?$BrF*S{f0|azsFcnHr2B^JU?oFUaus=%JNSa8*Q2Vu|UBU}~-k zEM-9fiRzzjpM&|A5kC!dmIT##2HW4De_-cN>tEqH2c7P5SpuMXHiv!Fx3lkzj|W`u z%9*&d$<+CaCVxxnCf!CGPh2cUpeQT)uf?JufiR!PwQJNRw1C`Otm{nM2Q?IkLQZl8 zD`IK}t0z#<@I#Pi%Xm2=1~IaxJ|Ub2N24j^R()uc$uWT~XyBt9AkB%WPW}|A$($=e zEobmq1F7u{F25xKm)$%F;};B|D)M;TWH~G(H=QsONzG1@fB@s%+#GD#vW2^EImZB-Hz0)dV0GSlwOqO0QU(3rZ|$ zbGutg0pfll0x>W;%EkRs+}?R%#0Jp=SE)BKsRT6T6g>dZZKf`&gZ5YftOnmJbuO=u zf#oWrh5h+piTWT@)-niM=;<2FW@ZpVB0i~^P@1HI5*JcC1GxUz((uOjZUtQlK_Tm` zs1oRU5)&*W0x3~R9Y{>D5)lM-NkC!xAAD&V%CDx;)Ki5zz-Oo;$M5|aMXcvTm_%f<}8J`v5#%i!OdFm41Fgn7poSLICMUH`g^5>Z`F&Bx6)J;EZ&N?N z^UcQJ(DM=Um*asKo+}f8V4DX~FW;(#-IQUfjll!0t>u=Z)@Cmu#)mADI3%zpK~MX% ztc`QXo(X)~7}U*R(}yHlMe#%oUipCohaNZw@i7K_t{&hfm%q%QN--WU)DZifh=8ml zau$&U7#bQ{k)g;sNpFh6)+<6VaU3zht0siw#;N^3tGz2es`><+ms?fs-4}cYAI(_u zq*7^9v%zsI$9=Q#FG9B2$QD{z#H)?cWZG;(!^H72NugPqwNYdJbpr7HMoBm4C?tsZ zumR~23-YH_c;-G-gV7S~zA}aXsMTx#mVPKH2?+3YA_Dq%=`rlaZA?j~(L@9WcWH1I zi6FJj_~`C8SkDp=CW$JYKAldz409_kgaJ0pu@}Fkl#5?Zc~{-WOxD&)ZXwr*$=`ls z=71bQ)3Iad20xl@*qd3lM9}5=8bsqZ?0jPgW{+y{)qg$9ZSME{);`Fe6TN{u%_EZT zZvx76ZNdbtL_q&0!n&Jy5Q#RQtb^q+0S_h5lu#W+;f7z+zKy2rSK^5zu!O&2=v;rq z`;T4VD5Nr_0P*VBCpVY(UYFEU+nDCHQ2=ea>?%fP4fPr#oz^-E^?W=!m1^@@e~4LX zRReXd4x4ss$W1AD=r8BNv|oYiZrwr72|)x)NCH`eORjLT4qAzTHk#IpZ~zejy-vP@ zWr={KZJ-n;U(J1-B8aa%f1`^C3m)%WygOZ9$fJQ^60AdCP%V|U@n(O zF<-#nD?E{u^x11sU)aag6z;)Xs71LHs82=bu@U5hO&1`cXi>QP_vWCK_28Dz?1SR8 zA*PV1OIQDpB%q@c5s)e%tAL`4BsrFo1YFds>PH^?-is$6{Kk{KXJR*iS%1r$-qtmY zCUhRM=YPb?v%hJVw*8N4kmG&;5@V#>Nz4;Lke9As%?@5a70>~NqqLLyoN^Newo!}O zBs~0uc~Fg);hmq{gX^%eBp^nie3K%&1U~#^9E+Q2 zODsT}A?qf5mmv^CQLM+|+kZ?=FOI@{etkb=mcazAl7OyB4Ap88NlZXs@a);M{62Q? z-reZLUQdy`w^XQph9ZQ?!5EC~7=%cyI|5MNe&bE6UJh3&L4=LMMd}B?Yip?+TqrIQ zH`F$s^jkCU3D$FN@e_tMlv_KMPcxvUvt+^iV>)n(N3f;|^3*+gNf zlbk`6GUlqqe@rOjKc_=@Qvhxo5l9_I^#p9A=5%)@`INd9<1ZorE*0y34B0kcnu^gu zR2`lP|8#o>AY6gV-o6QZN9AMWR`L@p=PV*gA@d2+>GUKL=-Xz`<))Q-gXl((qswzm z1VCS6LJX>qtyCd*Pg2?W0S%0}P$x>mRVk)_pWg&P)il%`Tc%rg*5gF%dc#2`atVOD zW+SMJ4?kD{-z>rItCFHL+gqLph?tfl0=fqx5(I`t%eHPzCXz4aG6lYwYca9ch0xH5 zfijypeOCGL4P)?zhjj=IdEh{6iMgycKA(x8=^O4021RJw<;3224-@U-2X_-!#^CE{ z9Tew0_`vV)hvJM0)l#i1Ot3JYfH*%A3s*+e;hT>fKJnD4<7dSTBDOX!xwZ!-!0I7U zJ(iAQpZ=R;$L3rp-Ir2!-J*gXrPriBq*?-Hqq_RK!U0NSn0BWIkIhZpTrZjEy0L+>0LguO|>Bt|M_QM69xe6p%9( z77w%Hm|#c@%>3~kd8CLkT=uph@EoNpOhD^L;1J(e(scD5N1mN{aCT}Q21a5H2b_$j ztoB?70VwtViA5nyz!ZP31e5nfmC@@AhzxtoIqwNTs4w6#0Wl6oS;kco)b;n`_Yfwq z6AFZ*7QFb~0@Rcu?7FI+*1il8NHC3?bq1x-&B(R?l$k2mh*CgT5FO}e{e{vWMJK*VVovx49`G!-iy&2Wek-m($@5f>h5tNl_IN?3~ zs~P3+ukrCSfpLCff7Tq4(+vR-up-d5v|guVO$GxyRM@gN2H*M5^YESjbqvzOI+)fX zN$?-=6YoKSn(tSS1l?EH(xI90AqxuAp|eOrTNWZbUoWe_^p~UY;pZWj_#$}bK2W_z zL!|SA0Gjg;DS1^)Mq|rCBc9qOb0Rwt4ZTFg8u2j&c3+)@AAG)m8~-BQ_|ZMwGDj#u z)ma~RDz$%D33sfU08B5jCIA>HH9mS}Y27F$b7(;r0;Bq{H!}58T4u{<)nfW1Jd~`S zFW5k|TbCJ4D~eRI2q@*Os)H8cCC*E_6)06JHLfByh`_i0umEo982s#S?7ny6NcK}s z)jhIh$0jjdq>qQbefF1D{UO6oz?sz7Ascy`|K3Laoyf&EAh4@*kec}Az%JaY^n#Q=@QF{*Aoudy=`P#W3b79O}c^3dN*{kMHTo&F0jsxUn<58E#o z<%y|%B>*k3SMNPSu2%R|4Zog>T+f!_`LkMQX@EpPr#E=wD?xnvUTu2kA8W<*uT$4z z%IiNLa6r=|xWfBU&Cx7ksDuGxS)L}=kxl|qqpDvCPk&yy{KY>oy@8@PZ$fy?12fbT zTc}q)M+P)pZ4E+k230ozJ1Mf9*E2|650up}J{SMcI)g?9H2WaOj`NXdL<9l;cTr;l z>U-mv;M?;h7&!H5X6Nrz3!DB(t;B9(8p=x5+pq*694=}XGnN%z!zw{X5Uh{HUsBK+^|7`&P%eZ( zD?l^&vsMD=jc`O{gC4YW56r{Uz$DLDCj4i0^z053mO>Qck{4D-3>Gso7Wa z3Lqkc4Pr6K?B(tpnh5N06=>4A>cl_^yIkCRTKUJd$jLu*LvwfedWlDHG(X%V8&`#R zGzHv9y|1XFiuzCxo4k) z%v2G~{1p&QS)@1k8uZ$u-rs~hyxEWz1&<+@t7Q`Tz-S~Z5`Z7g5Srk)fakUOLIjeD z7$hg}^pj`rREq;ws+GiTh!NfefxcC#|NHCFIZ|XcQ-W)41u1Cp)Hw(8Cj-T~OJUK! z%@=adYuiq938MM5`S>34zu>d`8m^001*TUabl?~~b~uaN&Ul`GDwza7Yy!*m?|EN? zjLrIN9o^N2xHxYxy`{V0|ZurZ-R|hseATrM~4VhzOtumFYa3xE}%WJ#*}(`v;Xh zg@`f+G@U&}xqC>wE-Qm(xVRJrn%ToG2J)w<ECxWVi zD3m@7ex|f9&EOoa@ns{St)W7zyi$Pa$0}^*+qN?J;2e8-+6RY|#@XO;*bTeD(&A9d z*x;TT0k-Qfs3VgAHB%4}Ju9mx)B3M{?ZoSxvn@-zTeyv!LtNM4Ppcrxz!jl3=zoDx zn?}fdhmUwct%dP@>V7RZa=BWKU4`6qtx}7OBasYp^`fvA?9ib%h|<}#S6ctEUV6?s z)UV7|g6wHki9cLoQ;#E;KZPdW;i{71Qb5IxbXczbO$?rL{~Au2kHT>NIxv5HCHTGz z`i^75ieMX~P-ac@S(va_^uEa6IwoicSrYZ3Qr-VRW5)8_j3g^Lh-9fA_b{^xhjG*Y z4-1u5R1ssSMlM#Wkv)nRN~5G11z#V=TTbFOCh*#E{4hdq#clv;g_0Q=iJ&r#(hVTM zFTtJEyeU*mlT3FqYQj5G$eeiYndiSdky6J3vhxe7Rq94SX)(b4AEF@LhIDXN z`;l+^dtej}KwuY5Ft}%MWf7$zK(tUA>YgwwD8?p^VlS8b{|PVvQ~e-cEJ!>900000 LNkvXXu0mjf>!i~V literal 0 HcmV?d00001