From aab2e85f5a1791dc711166a7a6fac1e188d09cba Mon Sep 17 00:00:00 2001 From: Hrishikesh Kale Date: Wed, 4 Feb 2015 00:55:44 -0800 Subject: [PATCH] added test for notes --- app/Mapper/User.php | 82 + app/Model/User.php | 19 + app/config/connect.php | 17 + app/sample.php | 13 + build/tools/composer.phar | Bin 0 -> 1053395 bytes build/tools/phpcs.phar | Bin 0 -> 479811 bytes build/tools/phpunit.phar | 72403 ++++++++++++++++++++++ composer.json | 9 + public/index.php | 15 + tests/Mapper/UserTest.php | 63 + tests/Mapper/files/user-seed.xml | 21 + tests/Model/UserTest.php | 15 + vendor/autoload.php | 7 + vendor/composer/ClassLoader.php | 413 + vendor/composer/autoload_classmap.php | 9 + vendor/composer/autoload_namespaces.php | 9 + vendor/composer/autoload_psr4.php | 10 + vendor/composer/autoload_real.php | 50 + 18 files changed, 73155 insertions(+) create mode 100644 app/Mapper/User.php create mode 100644 app/Model/User.php create mode 100644 app/config/connect.php create mode 100644 app/sample.php create mode 100755 build/tools/composer.phar create mode 100644 build/tools/phpcs.phar create mode 100644 build/tools/phpunit.phar create mode 100644 composer.json create mode 100644 public/index.php create mode 100644 tests/Mapper/UserTest.php create mode 100644 tests/Mapper/files/user-seed.xml create mode 100644 tests/Model/UserTest.php create mode 100644 vendor/autoload.php create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php diff --git a/app/Mapper/User.php b/app/Mapper/User.php new file mode 100644 index 0000000..823bbd0 --- /dev/null +++ b/app/Mapper/User.php @@ -0,0 +1,82 @@ +firstName = $input['firstName']; + $user->lastName = $input['lastName']; + $user->email = $input['email']; + + //should create domain + $dbhost = "localhost"; + $dbname = "user1"; + $dbuser = "root"; + $dbpass = "Dbtest123"; + + $conn = new \PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass); + + $sql = "INSERT INTO user (firstName,lastName,email) VALUES (:firstName,:lastName,:email)"; + $q = $conn->prepare($sql); + $q->execute(array( + ':firstName' => $user->firstName, + ':lastName' => $user->lastName, + ':email' => $user->email + )); + $user->id = $conn->lastInsertId(); + + + + return $user; + } + + + public function read($id) + { + + $user = new UserModel(); + $user->id = $id; + + //read this user from db + $dbhost = "localhost"; + $dbname = "user1"; + $dbuser = "root"; + $dbpass = "Dbtest123"; + + $conn = new \PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass); + + $sql = "select id,firstName,lastName,email from user where id=:id"; + $q = $conn->prepare($sql); + $q->execute(array( + ':id' => $user->id + )); + + $resultset = $q->fetch(\PDO::FETCH_ASSOC); + + if ($q->rowCount() == 0) { + throw new \Exception("User not found."); + + } else { + //create user model from resultset + + $user->firstName = $resultset['firstName']; + $user->lastName = $resultset['lastName']; + $user->email = $resultset['email']; + + + return $user; + } + } +} diff --git a/app/Model/User.php b/app/Model/User.php new file mode 100644 index 0000000..3bde2d2 --- /dev/null +++ b/app/Model/User.php @@ -0,0 +1,19 @@ +d>ztLm6=YeXJKG6-93{@($j(NPDs){4BbtrR4SdC zu2hApN_S@#5Jhp^o+z^TRGy$Lg0hLYA}WaZ(1!><6xqdvMR@#$r_b&EerLJgQeRb; z9@O{$zgFg^zVEx|o_p@O=br7}`=mXkjdrWFRBM!~jq}m^>iWQeoB7|;RRhsg(ZXu2 z9j(;r)d=N!xz&l9E73%AZN1s9wnp&h-A7T;FWf z&aQT%a$`BF*DBRU8+bKVnrO6BYc}>p>-B0G&(7DX7g(KD{kzU;xx-G>o0W2>x*Xvb zUoSN~o#q;Q)$y*fTcv@4QYjig->fZ1y+!%AImOsTwB0jhYrTI1p=^WI~H9H?Thvg-y|*F8&&I| zx;D#-D;HX|PPI6{FgZ0h2f(+NTMbZeOh|d)V5Ch(YvoNLEXFrU&kL*7M%3D9unGoU zsmMRTTFdRx!szUg*~O`uqt<#}gD2LPG01FgUj!CHCnC@`K}kO4lWeb|PBYpM@<*G^ zjTUFaD2Ae|$$JOx9T=EhEw{$T*2?SrqgZf6N7wPQ0NgMjwMMmAn3y>>J2O8uw>UX< za`E=@x#QEvZ(CfLJ~joCUvvGnPrl*W{nzh*3M#a!&)ulCs!@Ruz)LBJGDH1I;iiFs z#l<7zM;8_eefsFsTyglO=;lL@7`U@_*=390aM@+wblGK>eZyssz<<4xAco)as@mly*fR^ipL(U z6ET8nqH;;O)C*(AE>&D7TwWam0exTN4dFEl4f6?m=XX}AL zOFMq|Fxs;zhI0Z~3Xpg>sO^ZvI^I*?*7Ad|K7*#<;x0>-aiqcB*$;NBm8slzDr zf-&Bztk%vaL44ANisko@+;y9SxT+V335e6y1SL!Ykz0+DEPvrKGoNuNQBNpJ84}{Y z2Wcl*zWw3npXPN(de&`KF_C9m%{!}=Bt@?_YOs9U4?VBwfcEwRG``f_NCNo9|Dc$# zyzi}3|H%Pd-3x#Y>Uh0YZYPNG14ay%ulmZ3p+iGG!K^kfB^lH{C*?599yIscJQf5hweB@{&m`b{-e$d&5B-&2bT~bS<+gfrshs4mhdx*_VLAWyD}HB72y@l7 zW=i&*H*&JP^`UQgpF`-`mm}3W6uS~6alLs~e^7$`q^*-IfAl-P|4N6`voG_Va%Uqs zu*Z$XSbpovzBc3#dJgP#qn4ChKXZf9f@S-z_uu06hqI$H*}TvY&9YTGS!u_=*o}96 zlLBG6^bcP=x*Z^Mwd$5btxwaV5VfnPl(lvP4u!n@`NA%ngi-L@|+j#&331{mKv`| z*?6%$v+(O-ZSFVnv(S~Btx9H^HEgo7ociUlcREu2#_UoiB9;WnW`5(?a`)UW$ zk9}^tD+}d!O=)8JbASGc4>**5sN7cTq){n7Nl{_>h-1Yd!5|gWL(h?J*D$v?OVf?> z)H~uQDOxvd{8@hTM?U{@N2_bz$Ms9&tyXz6{>{;U?86l?mcQ_(kCz-wmne#>iB#0l zj~^1&yI^&2qOrX4;?k=f)>Ha)@^;wXbQr{tQe1wYaTLoJm)c))kX=I<*Dq00#y^SJ zPnpnWIrGL}405DvuEfyEN-&o1yzOyUdGGf1 z0f)u01ok?zu{7C&!6d@_*#(8e^4#fPIpA=v-5SoVwa(H;vw;X8sZ z*2VBKiMV7Fs~E^vjN~l8`m=|Fh2A9!GC+bj2%XzApq*p+1K<89=e%=Up~F=-0C}tF zxGewcZ~d3s9mrM`qADUl(p+ig*nKG1XFl`O4y|i3$aD@1Lcr*wmut6JKJUMM+p5FZ zs#^ggGWH*uY-0J@y$_mmAYCg;7a}?1{v}%oSib*bPk6cmyS@(>nQ>KJ&f)G?qaMWp z%hK1LcgW%O69+M#^VP}*WW#1k=rs)_%k>YxA()R_5G{sEqJ0Wp6ynA5nV)~$CmpYT ztT|gRcj&oIL;8tFDkPR~|I~ZKOt}&0r55zK8l<|Iqt)ej4UOLty(HOA4*ck%qt~?_ z$JNZ=1utg&jG!L!P{ohs_5bSuQx58>+rcjemE!#u*$}Y&mRH}n?lAjN57w19mt&B` z?ne(Pb}WDUT|e7f<&3L|Y%i%PU2Rl0r{PW~sOQ=;!E)tS7QW(0_3J2?iIQp5F~r$& zi?IU0+zS^4*@WeT?!5U&9A-b^EHJ6EHL7*T?cIhO%dv&4f-TpNU`aT0RYoU>QNt`# zmQVPxr#^Pu7+EhJqc>x@Vb55;@)5uEaEJ5cK5QWv#blyW6-G#{(Gl{SJbW(78z1?& zgATBt8cl3vi^eme{^1Z+9aQaDo!Hb?) z8^#!`8%)@;99^mHacDd0<^CAnZ(1)|K5*vSKkxARP4svwq$cHutfMTy@`5WqI)#%~?mPpQ>c+l?HU1F&WD*K5#57+g)p<)fO36uflz*MlO;0 z7h`yq&8t82P)DXq$8{KV>A*0R#Yq1qm@k+e!18Bb`uyPZ?^=i)%uz4E3)%dw&=6`zK@N4+N%!t8ZZNqBJ$#cwSAU< z@jbu%9S)?+8RqR%j@aKE?_A~#oN$Uh4(z;>BD9cZcPt16)x=b}k#GE6P9ukUbrO^43%`cV@KJa_L zErSrgmlVeEz93~^6&qh zL)yBpWY8|eUTk8Q*xx(2u4S`}bT9$Cpj|NJSROrl;#VEo)|AsO(mNo!^5I&; z6rta+v1R##m8rUe>^YB|SU$E1lfGcqF3Z1u{C$7xuzGTTfOX_-S6?4vDgw*rz2uRB zOL|HfGOa}EjFcSBj~l^Qe)#f3-{=@cTZk&weK+FDoXad<__vSwCa=4 za-np`Z#sak$hwdH(OTmiTfWM=&hlFqfB3t+V$We_#aN9jO|7kWHsjv}`8k^)EHC@Q zpgV*SiFtLd+S4G+d98{&*CbF7fswJ`_UTg@ky!BgN8DeZ*+DZ<%xs7^t zzAARdUQ&?Ss&bvf0{9~=HG7i;eg0_v6>H4{Llq}3k* z1{YP9fAZ-o|J=J!+y?B~X0uNEe%Bs_!SZ=e{qhYvfx#(E7(eyR3WMccPkPly9Y&V} zB4_kXYTj0DaDJ!>amI{2me>EtAKvKjwlifXt4kYab-0OIGF9r;AN;wn`d_yV5*cdK zSRWj-Z#E5-<-K2hZ*L8>M^8oI!GTkgFmlaUkmc%^er%ujv&&e|ffjf1udu3+3s~Os z>I*?#-`1LiY?W$T)~xrNoMicm*L)=~({{j^;3dJIaJgc`@~i*&_rVnI($RDJ6qbbB zkWRTuXn$t(W_jNO9`#hGP}fQY6$R;7%&9~%kF3*5H8oX!-bl^zhNqnh4*IUCVu0um zNdhA>_nJn|@=<^F-pG*|%JR}|ed8=L!L^t=Uu|?`wft#($AMzG|4Sc#=2rDB_eTJ* z{ZE@HVfnV-d2fgn?d#QkOY9R5_y#!7F*qzQyKyAAWD33DNOw}?{9Am=uCRRgHTUiH zu5_#ONm3-Nn=4EOVfogflP4Sia-`A=#$ib)*<}Aq7Gq_q#xYs%s&CSIEZ_E@ZVpOG*O*H^k0%_fF{hpN-||4M z&+_Mf{qKSb{%yJKdXSMd9|94@-m?6TgVj;TxQoQnGG<_<+J@$X=#)v(zqYx<^6qn= z_>2QUq%ptCY;_H)Hd|%+m0$VE|LK)Lwwy}L59_EAEJ+uHFa`t(f#sv0fAQH4p-ZR< z-t(PSwY-Lz)8)i}59{iblS{PAD=fgl091gR2Wefgs0Elw{( zQo!C)6mBpZg5|q!_|>LUAfNM&H^BiHH)qQotX8tPywirC<+HAS^P1PsAASU-Ie3pV zc4ztQzxnXxJu5k$P5~Ypf_#OZ*Q6L2Z2lp-UaB%Z+7NKJJY_ z6I>l#lOzD3--S(Yn)%1_*Z%7Hf8$L*DLYPaP1)vRo~{QQjaXJ*dM22%UCT?T?*8Ov zBV}ZqvE_y3qhI`_U{OK3rKgQ@DpCJqlYlHA_mt0uPIp=SBDW`N?R6SUFk9vK{Kirn z`SD9guus~ruSa_v3YM$y_=cbhT$#lq7bwyCFUI*S-|~t(Lng`oZ9$09B&^qi*904s zuZq6)cYJiZd^VaDu03PLw;K{H>z&se^NL-(ZxywWKFLaZ#H23EH+}if-nv!&>`HsP zk&)%APd=-&Ref{H2m-|ae;PZmEMM`K5FZ-O649+G#&k6N-U>io_KiwCmj77(mM1zA zT`EhcS~}iru7_Vl+-S=3cP@WVh%)v; zhat-pjAxj5VR_5#_kFLU(DYAd zn@Y0Uhg;e>%OAUM@$Ft~Zms{8k*@hZ1Qi~Oc zJF&`6Vo_urmRHTxLdeVOR4n^tq>XiDtvt#)^;xaMa`DPn2S-j>u-3qU zjaDyKF9Tz+IhH^A13z=#QKVlOHqdgjRcddptuz~(rFGR-OY`a#xd4hKE88_=pFYxKqgH$V75#hvBn|LZe<&l@-)7WvJcDsRj?2 zvBPrk!bcn4;3YDNrI?Sm&TgzhETo!zo%NCB2i|pc$U{7`n?6F$ zfOl(pS8deRA)#ma-xLE*nwH4&{73#KEU>%lh%_?3#O$|9M;asNU1sCM^5ysZObAup zw)>9Uj&OJLLOV3^Zd(yq-u;DNex1{5a`#QZnSL?Af1?RGmbGvG{Lx=~A994u)_qujSC|QFu}Y^;NURUp!oc#4U-;=|ZzyMSY`Y<&RouuAnHtOT z$gh6-Io`-KySZxXMuI+B%IKH#olOL7J1}?Hv4>d4SZ+RKy5Mcj-~Vm0x%WIu7a*3u z^`~zOX|t#A|K?J1=Lb#hu>9KR-yO1Ip`&CM_Ddiwd-y%(#bbH(ZykQJ6EtUaxP+Ec zol6GFud6@r7re<^cGI~8`?EWDLl2?G!1DGdKJ2Rwdsnk~ntC%#FZ|b+IkxeW#)B-M ze&!1`Z(~>ZC)yzF%gv?8^1c7G5E6I}?}j!C8~$75R?6RO;rk4GmfyY6_$SBy5?T=0 zGhyrH8*DXT`MK}@`Cs=Ib|tB`47%eD$H)3zqNu?=N_TH?XTIp6JE+1)P7A>dKD+WzGqfFS>K#mEO|R zcHb3g4@oOHGsZJ79`-nGh2_g%{j}f^WF}L_7TH>m%&%7K68j!C0nGBB-}i$ra@>#Z z2I?~yNJXLucE&bw4uSvVtaz4b7c3{9`nZa>Gk0n2FxF{jHYHoT#r!rb@A#2hZ}Qf5 zH3uDV$^T$~e*Pgk8Z1YvPyJ(W;nv;sM^|K9mxgCJz}KO!vnhUL?pJt@*i&f{osaq`X%%vhhWn-JS>0r)1L{kzg_8< z)|u4surJ??6^eafdFN-}7!odb)d&o699O{X13E(W7aO_J#4yXxJm3|7=|jIOg>tgW zh|fA=X4q)vf2KI?AC1#kzU3JY4qnDxN&UEu(gI?$@lST_dbm4DJ(eGO%S&(bj_u0U zh(VX0xmJ&Vv7w)Qf;PnRgD-wfaJTMis>Yy8%-ez$+lU{rwJTu4vRf>_Fj4wW@7BrP zFnA0)X-4@|ODX)HwluIDp8mv_y~SNkT!)?F5cVs%0G+?-JHO_wTqvd0$sxTH+%94D9Pjnmfv;m zu0L>^jbCaL1pXk?XIQ?ye(vQC{8I3TlkO}+0qtAMl6msjA;q8Nwcr2br+E{*Qf`by z@mR-ny3qtF%YXR$KMx#yDI*^2^|+aDvlWizPfmYF@T4P7v2zVDbO*VDIc=?(2Ey_y zZ)zWM((P((u(r&F8h7Z^)(Fdcp8x(|^G2pFp+gGYlF&;=F_xdca9OZqj$A?m*>jx! z$oyI?@4WrXKjfX*mH0ABxuzMDY8??PPDPf#@s#4n?vGYvw$E2_o~LJ_oC00g3d^G> zuL$ngU1_z}m$(m~c#w$`l+Aa3L&(Ou6iWGwk6Zap%eY|qxo`Y@NaDPdNiXJ@7=Cd( z71IP+{*S-=p?iEpcBP{mt#m}_kfVhBuuTt^e=+#wkZHRs2`M=huAYSii)4WNgBL$~ z+B>l;k&NNDSF)1O&>>WXWFBY0P74Z{<=30$)FzT z{ryPiA66mRztDdc1B;qeHy_eEf|X?y zoeY^5ISbJapvMidjeAWCVOe@dC1@czf^P?HAlq*v?e4nCIG*Lh{^m1(KSw%g3DZJg}VShiM4v%76cV)=}HlVSE=LL;{| zHZqMo+Zti{iMw9ja)RZod)w`a2RRd6`DvSZEMGNz*Nxsvj>y|-E1CX$)N~P+^Iu&E z@r4|>xzX`uN7w)1i87t61`?LlD|LQb~B zR%78{W!pf7>FAA4cgLP&(~{+%E}jg2`y98&jv7ST_G;TvV9$~VBLCA@{`?tE!5qiY zwi}wS-Bs-|U}sG`VY%l+FAEyOvo3)_pqKDifk~Xj&Z8kVyQ%pSYnA2TAOF9<>7Cq# zXmHwb_#jjLCrSC;)(Xr0uYTu;ypj*koG#h_%S_fgk+)a6nUz zUb*cSCpOx+V4=HrXRIxjolm|cxcqYbW7}>Et>ChRwVa9lB5RH1;pm4S=Cr&Nww#2T z+=DHXO7rvYeO%ZMeyN>X*j&%)+-d6^%k>u*f=}jB7-f!!#kFx9VweU=*1W^kMwXxZ zqu={8C+99!EeDH(!#bh}Pvm6tf(B&Nqkb;$0|}F<>h536H?{TN^B|xbV*lPPJX|U$D|j z;}s^jP9kwOlS=nO2wSSjEPwr-?H~8nW_B)w@g&GpzmP~VEYT`yKoppJIF+Iz*?_UhtYwx%e zf{IB7HlfXz*XWQn%5vf*?O-76#s*xkQxyB5asObDS-$uizxxI!-}Q;^;NG8-q;c1f zOU;uWaWd1gY`Maz8yy@ypx3F0wMvZ0Z!G`ixvvb7dmgFfG4(Cr(f=Qx*ED>M0%Upf zljp8;1ov+r;8Em}i}(70k5X7HKlq;Kg$-3VZ66j9LvBi76|&&BnP$rJzPCO)8(P{K0)r;>nmSyK00hB0I5aUN@FseZum8bNGiZ5x$a)EhH!9nals| zPwuZ4bd6vOZ?HbF{Lg7{akFhcG}FINaQ5q!odt zHOcaKh6dl`O`f@=CT-7vikf5972DET@_LJO`5-dpPq#5=*?h!$(693<*Bat`T*Q$H ztJ3dRqQ4{^%h$f=Q^AwOZLKDx0_ie4Z(n8tg5|BR{qFsa^utk=_q}?(2F* zEiR50N~5DCqlyzb4zX(-B_2KWY=}S zf3z&u(%~%qTD858_n6Atm1e!(ynsb7Tx2>HE;1b*D8SiPk4D<_@kO%Lj*ri1vvsyq z^G(^&J-n7QSrAb3PI922G<#G2IJSY^YA`KLl~k~hntB5Is@w)OE`xBw;kIgT3oD%J-t!s6otHj zu!hgRC_}nvNU_=%1?ogY0V~eGA>MO5a!9&^iRAsV$6A}uy?6E^z~H;^L-;9+wcb}O z$Jya9v9ravr-}AM?+Gvb5O^4yEXbPfKjndz=c~np7)ka9ol1Y!8yYoGq)*|_G>J%3$rN3)lAsrG_VKzZKarQUlEV*HgQ z0~b)vqWT(QZzl)>_4F6-#9rLsBhaxFU9#ev6e2uAubAKBheqO6!=Hfw78jMD| z+CT+I5Z{-1jn^U;`(l`TMSnjWQSR|)KnPt5tr1z1sBO&cMrWm1IJI~5nw4X>miCTb zyV5=r?QP?#=U(;YjZlixd0$i%T!#6*(ockTYI=?w>PcdJY@a5C4mx;ev(_kvakx1e zJlzgr32xME^=ui9kk;r<8{t~~;_z~Iaj5rX@K4PxQcyn%T@EyrdEg6{ zvPl;P6`1LrFkJ27=pcCNn&_T;0^{krHxScw=M)(jkPFrK;0|}(h%SAUo7Mr;`U}4& zqK`!swe`hL`7CrEML01M!-|P>qjm)~7F$pn%AMli>5KcHI%qT;-lqx>>Y#N4*42B_ zk@yLfraC&N_>4q3_yqdmds1Ah9KuEJAb6&U1XhKJ{7djjl+qX_J`bJ9)G#&9xlm?# za!3ojHT~Xv{tdICmtZWn&lQKBYdhJ1Eli;@4l7UaVVaA=5;k%OLZw)M(*^gu7KTR- z2_(hK*U}uof@q+AZ}0I4+8OG0qGv25mCHHF`K-j2wuVi1t07~uf< zHYg}8cBwQ?wb>i{JQU)l`%xVY9Kkt4+SsX%<;urPfQ=3q?LfBNAnHHI@JqNR(UJ}2LosyjvQizVqvM=UM+~3k$KVXbT$oi zlHU_t<&$^_-QS?_Y(a{w72Dv_I;^B>MWII{m1vOAq7m95H$^Zpm!px!{%E<@u9REL z{-hPHZLY(7z0l+{si76bd>M*g4g#;RWT3~kE_RxW`V&%K z8Up)ib$qx|sZ-grH;D(~i;adZ5M5OVjC|I%&@?U7WAU{$KM+`tp;K%FaLCwMBOXxXd(1P&T%+m|e zwTGh8a`k+Pn!q4v*94I(tEO<+e8CXhg=vH0oE8qCSxwL>D6%(4 z1&n!O%CXr41?pF<7mXyRBj(5uEPF=b@tNbFOUUF*-`nn<$EOn$xgc5tF#{D0TQYu6 zf#OK?V4^O@py>d4BhDLR+tiwi#z@{Sk5DgX0@uy~HNd&YInVmW2irCTWyS~t=hn)x zn6|EwXJ>6utILqu^7|Y^v~Qg*1<>^=aFc5l`DWhE)c2?E=gOH6DK+r%>I@8A>32pk zHLTab>`qzQ8fZ${h^I4W!|oKEZ8h0T{V-yXHanaov^>Srh8r~LXu}clTw?hTmL~4` zhI>4ko(XOt>N@@NEn% zhlE@3{8n|-+IxZ}jkA3Arr^j}cJ&OH+&}ysx0PiCZ6cSSy;8Oc)T?ovCJz6Lout}U zO*y|0tL1k3>mn8{zo-2;B0pG8{NI)>?Vv8!>Hh6PnqktlxN6}~*P&gqIZ|1a7?;rL zxdFE#GDeE}E5a(vNh^!vwwK2ISzopj@*-U{)khuGcyS<48f<6eK*IlwFh+7*&>8VD z`S@fzlQ)tOEH2X3gvr3{CE&Ln=NPhUtfGo#;GfE{#~Gn0Ib=)hySM`_Qpw#}bJQvO zQlJY%A&FH{dKa9tpv)eUr4nkdvsif6vuBscyXdy-ZE1e!!aOiY8sWsmNMjwQNl(+7v^ev)XE25WD~MiAMDzu8~8K;3SRmkit@A z^sf~uLXjX82>_U*t*9_+IE)q$lxuW=O&jqzQ9PmwjAFzva0TgDG>9*y+GqhrIGM#p zCuf+oSB@x{=Asf}1TKeKMQe+GE>1mc?LZ7GOTg7mXWhRiRbuk#_ZjN(q1aJ6-TNWM zPfx|Hat3(nqrloaTWKEbz(AlB>>X{Kk>K0uc`@AeN3Sp-L@^JyIepmA=C*ia_#M=z ztsrQK6Kx`_C4X;K;fTZolaWe_EEC`xD=XOW6Gt5l&*>RX2L8*6wq!U^<8~Njy6}hK zm`4x_@g+QWQ>twKRspbc0^mrxuSJW3^PyJ)$5EwzoWuZ7RRq%Si;)R5% zAmC5YVJWJY1|FgHu~JE+D75!m7YcAECsBuiPvnsZkQ~-zbnN)d+_CYaFs$Qh`=UMc zQ*OeU?Hwc7_y>@~&IqiKV`JR}#Fy^mCEhw-^Kb~;3TY1e>_}jVw9b)wEA48Peid1` z6r4yc?L`sj>`#-Zt?nj3VStxA_Cl~Ar+T`s2r}qOb*TP}m2$nlgfl>kgLfBiK5+2a z_ndCr!w|x7arEk&hl~94>fw9g8c2q<p@nYU-)c7N^q2qcP-I9QJqmIMjri%BTUAk3?9QT~3{hEw zqrJ7GMv#!{V82!3Bvi&qf^b|*bUF+qsWmn>J2$mBeSCgl{OHleiDQ%dvae_67y7)Laeqv$f=*;-!;^c{Av$@!&z7RxXEQ1t) z)PYrkZATLG7s)jsvYn<^v4Er{Y#rf|ZG~Zd?&l}bv?+j_B&SI~X(Qta0TATKK=A_K zz>33881Cg6jcelrITF+4>HvkUObX}mV!;~RmwrArHaGQ*6Vr23lUOq51*eF{8B{Lj zR-uV~dBEWAXV5*>#Ms#M{NniB-1r^Hp~}3OnO#5>X#6M|NkP;(i|}CeJizJFnwZR3 zo5qixm|8qOb9{>URbhs~)&fP&M{B$tHWyfEQTCmoI4{Ma&7BKWo_A78XzXa z1F{C>Fdk!B8=dM7vzbIiQLHhyTos|6YRBvc?!m;Q4!ozZK^wCd3lN>c>Zj+0E3MG4$B^8IWs+fiuG7WB2sNHX{0C1v&5d>3sf$2@ zRJ4Fa!t&^qv|jXRflq|Nz3suMQf@SwooJ~lxrP^DCxHcPZ69*985+`MRpJkVI*F-d z0WG~hbPEi@Zs#HGyxY`F3GJ-tHPXlU!mJ{K=J;NohDt@waDWWUuXh*dU<{=BFeqq! zdZq|M*yyF2r=qfJ;(!h$PC`NnZS0z;ENx(e4k6NoEzhKkqbYrcat?{ft^!%au4;`D zgehrysV_l-mR4DK1=)fKm?79azHsDVVH6>mI+J>f{>>;~EY45Oj?axR%*>4fZ1`S+ zvQVOiD8_nmyoflouLx|9-$_f?v{K#68B&ClfpBHD#~{|24=L10%E)1+-Rw!sP=9GM zkE%Hl2j1x4PEpaBmf)oO0f|deGeH~So^!Bcoj0=>h)Ot z^jG^Lc~xr$2JgeMpaDD>8u!TiWHx;RXWl2->oW7cna{ZpQ@`tN#miE9KjjQlAyaJ^ zXZ@XRKnpR>%~N*crD>?O(xx_-c!EE<(>?QaMK@}5KJLe>`1|c@RY)-sv|_DD7XZN(I<#z-iOGtJVNF5hu4N`UA;!igW{w>jKTh4zX+oJV zVgscbn~+6mS>Hz(7WrjpU&NoN%#>@%HOS6LN^Oy%@jeJM<%XUq%P2s)>6wDYDHCSuAmb@jRAaWVry&+?mIak zLzg^h!EnH2F`{Qhg8M&gEf;#Qe%v{mR#tyDEp;;0`_d0ORfql^?!Lf|_p|V(?udr7 zR$r*sdzj$i-E9lFhItF%bjM;&HyYewd>)>=9rob}>U$HKr3cMYbC}>zy4aCys-|2% z(JtnR=CLu16to(CTr3bBc;~7Y%Zw*+$BF15xHly#s?>M7})vN2f*iM2g`@ZRpfkPsIn{(!1doSKv(CXw`N>S!w$)s>@zM ziPqv!hVt6h=*(+>?`M44eG!5tB?3TW5i;dD^GsFk7dg=y8P~r?Lns+~(LEXDFc5M! z%nm7yS%R3(3`06ai<&@eSTKfCCzesYFwxG9LdHeh&k@yYIK9QtkOxT%N86jjcSreI zu@Kj${175uvp+)Yh*eJ^d5gg$2pI5r7dh&1gdD)7B7A@7_VKyn)5mW+Q1S;Nk5WkE zdpF+(3J17W!0mfTQHo$bMdd^fA}r7FBft(BpPe3!3Iq5b_ncvy7(LnbP1HCKYu_gL z!KG$>`Ow~t1Etghtp_Zk=E|1e+N5bm_3BCo!K=}TX|hu@N7?p#wHkJ&!F5rsBk{5| z8k4Vd{<_kWNVE|d04{QHyGGc)*UUhQ@Q=c#4QT@ba?2J z4OMNgHnEYTadvcV`AOyV+DP2U2wJc(n6OOy0CzMBRSWwDx`!}46BG+)24w9Ft6+Ap z3hDxxdAcc498o%@d(R3OOy{DN7Dy%AR(CiVU{9Z$=XO`B7_xBoT?3tP5kfya5_N~I zA)Ly7K64T>zL{|hmp9deG-AFz-1>$3cNgt8vypcGXjm7 ztGghTB`PmZ7T2msA?}4RypRP0C{+Ub`@{unk`&Mx9)a$niLi0A6v1ttAT6QmwKgnd zNSwrncoOj=yh_NTXcQ2UX*%k)F;@@CPke``g#)FWmo~ADpKbIlPNUO6c-_r&W)=2f z28giOi#&1&%RP;!kwfn4qm-qlLv^&$tT$Vu8#OB7p(PHLxW%wR7H%=geD}8+aVnJS z7s{J$B-aP`MJz%+8XthW(iXw_0}YV|j@I9&jxjtw*T4-Le4&~yzHDRb$Y^u|8u4HP z-;t5CI10F2k71J-gRDu&(lJQn3MBGqLi`A|jILWyPxUxXAP}z81cAULvJaK>b5S-t zV{ZWy-P`RtD1c;Rk)M)Y%)h`;oz^DTC!N1g(OuQo$Rd(8D(A{)G2KM3<6QHmz#)*s zsrU8^)SwF=1Ld~Zz3?=`9TXL@pSFTCRDm9L1SE!JNV#PD{T8K0c_(1B>&_EfkdDRT zG7lKRT>W|y1k40hz(k?5auqGNs$hxY5D^gd_&iMa)`;zcZ$pKMKb0z{3hmYMwNJjG za0V~v8UzeXgV<-hmw@+js_>6}(YY#u+`YjQKFBD|0@VG~d8m5CEoKAJl86v|?ux%M zl(ajn`#JeK!5D>U8dB9Y`Zmg)Xp`wP!1UrKXDGrXwUte33}j{ywY;)|J3SYo!tJlXjq1niiqp?}?;L7QYdo#Qe1eYT{j z?ZyR0mpJIRV%fNzBny|$c2$jRzV}4QW_sa7gHbAxv)CQkHWyZ{vmvRF`=Yh-CZZE5 zDZ`QHEk;oh3|19+bxilWa_7&m<`6ji1p8Exuz;#%_fbU>??`YIVvo>>I5{`NI>3nB zAZaCRpo>EUSGg9Uu!iR)Gnj*5dM-Yt@vhoBmd1MNn$i8E`vGVR4vnn^inN$LscZPs(v#J83H#p( z>ucBlZFqi1EX_IGm!tCq>1}-sd5Te8hs`r6c?RRD6x6Ks4|i=>hNE$SO5~8|iIlOV z6(6)CW8#FP0z1`k&xWvaP@Tx@$xp!dv}6-s!Yg1>sMmTLJ1%0DcD5UUhy~sw^l*%r zT@_1N7@)wH!h$=+;&fB>@pESSwCK{f)Vk4G-KbPy-sj95oOffQb%NTEs?yi*za}X* zf+K>-1M12VW4bGsRo8DzWYuGB27?W1+I`TLM@D29q~*w}kv^Irv?$Q@DQ1msEka+__D)lMFI`XBlB5=B7ZloV$Q9ThHeQFqa+?eYeGhyJ5w?oG4CKZ2T@m*-0tT{1Fu0FcbJCykqDAb=UvPrQ#Oq;!;^(yS+M;hqz)% zTs?>BEW%k8ILG8F{zsDuiV%k@czg>TN{e(TEs8@4k3BIV;oeR>twu?l2^N-ohmRBXHgOfxN}H4G+H=Aw$)#0V@0%AMp6^){Q@DIC@BM&TtKWyMi? z2$K(E-yj$k=}lLwaCK+B&Q5g0Fm3x=|;^= zJ$6G+_!Ht81VI{q#~&F^qh1y$Q_#vNzT)9b%hA%NdKEB98JtHH0;f&kbI2Ghu5^zY za4uIK_wL`ucxZtgfU$}+Os0~_nT4Yf?X3$ua7O|$u_qB{;*E+VV~gGecxeOf(^Cxc)EDwBj`+KsSQ>IF+3)=5wU z1I;CzsDi*Ar2qzy0>3zY{P4`;ZBxgm=EjdwsMvFi3%*tfTrDF$rGh-Qdru=vNM85+ z(&Eiy(NzaZo#jIZI?K8}_Tb?8!9({%SHanJ6*j|Mh0QQGkI5(Z3=QAA2F~yn@t5pP zQJz#whOn`0$#d+4v3a7(6%VX~n-(cG9;n0D;OdbPrSeF-cDAxwt9Mg7yyzOZtsv9M zHNqo8FSN=`9Y!Q1!;PtzN%%gGY>$-ABdHw+mrTYpyd-~049Y^yY^RO(>G;>Td{QYx zqR3<%gLMxc0l5Yt5?dm4i+2xM?R$r*<#n3P2mxx9YjSMr#`@V-d0AYBl+q#^A~>d2 zYiCyxSRM=~wpdG9!IWr~YeD99aQvZd_}`lnp&1?Y^#j}{C_^d_jxVdnEIytULbU^s zRfMl$Rzp;`B1&JbHP0E#g%NeNj}sob!wGtB_ll{qf%j!$+n#a+F)f%{;>u9CSl~jX;Txi>{y&}&>Yv*$qF49u?j23btQ-7mgi`Yi_ zEDsfgC~4Q=K*#0)n1fvNd-0ij36Q8MheMAxs+|&k@Py-=Ys&|(z4pc%Z|s^pDcP`% z{&z_mqkyP8DH8C@NRqJV;ev16j(!k_I$ShIHkR^<5^bL>Psu81rY#G^Joer`U^QH2nY@Q-%IPt)p zP=om^)X$P8yXa)Jqg<@JbgZOgG_`BXUNk%TUD(;;L~{TOj&Wcw5u%;yMjJ`(7_}X* zSYUB*7PbkhL914G*Rm(diY#- zX7mUMEfURW)K#~FjJKeRpRXDZsEonk81@^^6*>>~g!kZ42{u5S)|A{FTUL;{yErB! zaURPF+$GX5*AkUswxC!T94=emSi6m_vF7`O)gl{ad=$pU65CcON$opI0&kyJ0q_h$ z!2?oS6G$08=bd1w?Wqp7STNhVZ+qjOc?kUpZSdMTNwq?ERHg1lCe@mbaj^h11a=mh zDy(>W`pWm#CiedxmT$c;>Pw?Yx6Y15urj&!Au>&X_?6ovH||;Lg;BI;i?>5PP+h?Z zD)s@E4gdiGaYQ*=l6}7Y_vBjrt}QvjG014hundz(tCiXc?%L!U3=$21&OA;=7JCdf zO?%c`4yfS538#&VIUi_JMKm4CVn^~r;O{)obj#1|JJ*Y=>G`YXJiel=vpEhgkbV+ zd-IVI0<7|{v-c=qEzasb``#W0=^Ihcy!ES?3GpM< zI^LNXixnGb&dJ>OE_TxIGlC-jC8zYTq}p=O_RHz4NsOUN1e*9rVrfQ#9{2O^m_R() zqKiVFC=e4$EcTog#>tjYHNY56I;C`0a!(og3*j+5G`hqObTZ+$h&X()tU)ZwAqEU| z1;hK0Bc0vRHMD{Qd?36C6C1UIGK4t#g$9-HW90^j0dk!F z6X+)nPxWEen>fUX`Z2%sS~4qRrP*0Uci$iN8qlo4!V+6*QRy~j)>cwlw;nrUDf}AA z!u3biu4EnAOU$+lcZ6@-c#CQF2s$-DKA`2?0yjkh8uh$ z$)WP<=mk_!=6;7y(u1keKyDL_V{j5&;O#g%VWH+B4r>5}{bw=LJDc-}8{-ZoB*iA@ zSdvx7>o`!bfmGY`Q2(%j0*?97yb;gbZnF;22fXz>@AaG(Z;E(ASLhNk5TTXe(vUqi zTdy)AKs&gMm?Us8?X{Az4%TaxbNB=)-#Gh@$+QMPxqBkaE789K0+7^>&5kGz%^KTU zD>$EBwlC~}%JJ+@_F0_thbF|~$AGXHJV;13eOg+f(2pA;f64f1RZ`K#xW&IA%EM47 z99fLEb(%WF-CB-+V**F*V?##DH4&D1KHZijo-nKX*Xd`Bt0_JK9%%_yhVlJkjbpE1 zxiwN@XWgV8uh+ngZ98hJAYa%A!RSt$ydZdK6o3lh=>mgBGNtNaP^CJRD@k6>KXf61 zi5q##&`XeC#P|^Wqd;-lA)0h{8DD54PJ#DHtLp1^kdo?Km_wOG3c?h7v_$^aWHnYD zA9@cLC`xU?ky##bLI|!dB;t}Ira>lwBJ!k|c*hNL`lZ;deZP;th--1_=vyg#5Z5_h zY4@$-?@@!@gLY%v@)G@IP!wyWc8xt{_tk>%Um}hCbe~Wa5GlX*#6*)?u_PHZB{4nj znM4yTerSCd2VMri#$1E36rrrp_drE#Qo?k_+|f)U#QW{0BwT?z@cLl}SBIp%=(pR( zC#lVNPdQa78Ko=zA!&EOMU^6Mi{bH^5Ru7MPl-3~6ASZ~&=KKC=+{iKx&#j~#FXfS z86irYgU88^udm~>M%m($`J%5A8845+tmB26{Uz%Cc{Wb}mP{V|X+w+~^K@~0jG3YT zG6#^`>mbDwRbYeSpQpA3tzIF8$F*hvopZjbQ=eKR0$vzeFgJtew1qUxp{{YtBDE*b zET^2DAuD-@D!?i>j>6^0pYTyby;uiNj3#BBs2<60QzT(` zXS#Yp77tlBq0ej}aroIBZn{J6R@i`99KbPjj68CRs(B9W%3HJe1N3aiK9Pb^YtR7< zEoGp9oHfRw-A_$zf^kE_1mjp-JO#FE280$06s3|7?FvnL5M&~gIWkwBLVtF&ady7h zj)8N;Fiis@nJZz2LOSFC6}8-<#ol~)GQ0)#u|Qo{;8^Ptqf0YC1ELrDwn+Biz*_U` z%zL_CXSq(7?O2P|KFYUTB~%QN+jGW?lQW;F7%2eGI2IBEq_`yNcSl&@#O~m}J=_zy zi-RCJH7N(w$7g;<>^Oz_2t6B$n>h?^ljFz;j-D%H2OV>!=mv~yxMvX`z)5!&L+y!G z_6@q4_f0SlK_Hl+Fk{BX5?$(c@m}&mM8zz#$fR_6=W!gRhBSsca{e-3hv%nZ{c_@m z2R%QuFJyr;2TbS=v=7qqHmdcEByY>kb0@vxvaKrHHVqSs zjLxR58tG+A=4&yB5paarrbUL9Ps9GD)BFz!n0cq>j=a@B=aK7I$$lk=D8}T^z>v4u zlh88X^k72ub_ET{&n^_7an&X%rnM}_l7xGSVQbY6DCjis>*435C9KhFt_}8?`VeF1 z1`OjScJ*OjP{LAmvlvcJk%Bl@MrCi_!OZI_7T|{zws5{ng|dxe;hbk|9 zdC$QU+86Mo$84Do1Sb_Enky1UwFEA-q;%@lj`3(72NfP#Oh0=lXCH6NPRPS!_fUE2r4#A~BLv3GPUyUBQU5{6;+tgC^j~iFs7l z;0AUy^hFEWKJx=E87abvs^ne9F?d9`jV6!N%%Mt)u5bx4j3D*89|nmOh1slwGlmiY zim*YmiF2YXlwuUi$6$M>gsT~!84l!onBBy)#$&fr(UQ`*WyV-@A5vLyq8ON?t6C8S7Zw^P2(fZR~c|Q2ShMJuSN|Im)Hivgi3BOqbtu4F~zQs$fq&h;#%~Z9Bc4 zmTDnm+-E2=DBDqyX~I|1oigGh*w$ItKd~siu)FIS7Otoc`j+cK&ay5mc_I@ClSjV` z%jsw|y<*H~jsUO%(1WR^xkunThI1?zYCuwl%h}i^mRRNx*=XtcFh*<+u?CersA;MP z(u$A(4PT*dU!(0xu+k~uxdcXMh;TjGFQh-Un1H*n4y5Q1Yz&x)AE_XDs?~&L#2{*N z*+PwQqM@Wu$(D~833W7bY|y&+1CecyG_y3>v6M8Ho2`=7Vl2{b7n{0sM z-pM9EU792kk!i-TN4imEj6PmT(7B|45UcjhLL7GCX? z5nHZ*^f44!jYzfr5jZ*3%8gHK{rr zwDY6ZHsj~AjXZ--3L!Sr;4PW z=#;U6wv3c8teAVM0DA_+NllrFpNA2|qk@WlXho^1=My+QPR?pPG-M~M=V#SO50MqT zjK}eWoQY@Xz^0-o&qQMIeWN)qx7#FPaF9+ysWU+$Ux75DNv0l7+aeZ!sMPmk5$2$7 z#TCR(4c;gdJK~Ur@;GsUaU)EY$^`^E>2ARXNYtYmtJL=!drfWynUoj`IirI;7B{}p zsk(d^30B%4lZf_a4!Vhv(1Wlp5)(kt{V=}x+uqo~;z1ZuzU(DI@veK=@Gv!8_?;dn zJP6~1zinLPsgDO`SV(Tm>2aL65~47mb0(ued!NfHfIk%O5{Uh4GDH%53kZszUjuxM zw#88&Sugse?wa>Zz9=d;%HPazW&&^S1#o%vBrOo;qitowYV$S`g0e7Q$e>WE-)o8N z0tMP{YqhjXavRNQpCZ_f9*E<-0Nv#v{A=JKh64OPhro-f#&QIFV37um1#LFLWpdvm zoId)C@9oz!dGs@a^iZZgv3MCzWwqJw zWORw(sUI%zH0-3q;ol74VUg=8gi)<6;>+$-m4lk(Ij&(BPUH3uSj0GRUUG+Fl)J)C ze}^5UMs-IHCvpE;k!LvWi$>e$8>6Gc*jo>GM{DzDS2|CH?7choHR2P2&ftJy3vl5c zHz6oI4KTt%FPf0*XD6wK^f{=E(|}it`w=a5fhGyE=vSlYk{2&^6yfDm+wl`LT2txBK8+pPFnl z8ePTR7P2=U4hAl?i9U`TqK$=AQhOs4-_CkN-^eq_D;9HWvD5S`=9CVgh@5(di)e*j z_zlz6GK!=!bBXW=+asIpfdFKHnaAKwx}hkCe2JdhFYKR)`rGIu+mN7@H+vt+mP(<~ zbi{GHR48gz!~{pYAIDeVHaQ~ZCKdg)2(FfS^czmp$vLw%dG->eWtbiDN}?@fjdKf|>&(@|Aa(GUWPGv9#4{d9LwMxS-372V2*FQI74YBH=5pc8y*Or(5O4s| zIUi^Fp}m42>1+aVOK!F^84E}OUKtGs# z4lyHJD3yKF+fXw4@nqh%kmPnM4r@pX8>BQFl=gWfyBwpGRrF_ZsiYjOH1*7dspC9f zP}qq<&P7oU;Gap^2I^8FWJ5bh(e!r+6+rIJVNK{%6Y4tF6HIKC(8*Io<)~6FZe_8$ zWVy3bYxML`lcPKrU#^Tyy-XaM-~AGXeAm(X{YIeL;-J`GA=4<}l#_FK3nUB=0md#F z$mC9|2#oEX&NP{zK%72JHKK&|gt9ErZy%&wHi(IpKtsr*b2bdGZdwEuKsGZ-XqGNS zJN2mtr}gV+dMx|kpHMn_-aV}jVo1($e;flwz71A^(g-4XFwkl8^O zw?+QV-Afls0TKmn5o1J8ZZmOil=r6?5i})0)yKy%&eR+^L<8nl>^Gf2CNS@fg+;{q z0X9kV4O>pl7jo@(NIe*5Ewe2TQo${SW(FaQvz&vSe}ftjGi0-mb;IOfX%KzZu3t-{h0pPkTeiS<68FuLfqYp`!t@JzIlwuwR_vgytrb|^x_mWzf{S`vZ^um?I9{wWOJB}VE zO#xBB5kKwH&F5qdwRmWW(WtT2+6;Hv?JA){4LGf|#vBuva57J|*xp!zpbxajvxoLY z*BdhoEw6C`sIyLEk6UeTUtYT(d}W&9=)P9*hWQW9DfoNSNxDFi>KDFA2>}NF{g$0wCcrq6T7%u<@}FPjwZ@5D*+{+(o4mYIa#M1zoF%Dg;_T~p zxDt9IEGLIY;fVhO2M#c^MUir+UNjQTng*)kfu@+`g5g+JM=?YwLMGXL^ER=k zUyrFlCYau>E~k3LU%>2Ph7!Uha^)OXPt9Aa*Opq?jfw=n0l(Z9OBHoG_Z{O7?2;fP z=NTjhAaPcK5>ff~-bPsV~LW80?zG@_XH+R z_%n6TTNQP0vZ_C2N+OOa>0VgdRddvLxY9)bUcLj-ro0q{d>{ zOAyA8xjUgVqH4uRWo_9-&(|>*Ph%70UgaJL9hYySjKP*)sx>CJj(XrL4SA#^30hg! zY>Yo{E-V)47KSPsJ2&l{QND{xeT)1(Yp>JSoI}CsYpR;s(t8b2F%YJEJ-SvY;g+k&vmQ$Y|t$p{Bkj z#^@K@S}`&>ZmW*7%?_H`-b&VMSxQkacE6t_Y(Pp<{h83(qQR_b1I5(|q>69yq*Q{!CIOF8D&<{HBn=Pl<_HIs4; z`f86Rd;t$8J@75i@7{YAKS~QReD4lXD6iO>mAjs=+ujp`=4rQEfcDR~0l9p>T&q(B zAn5Yepu_jufXz$?f(=T8k}9jxfXzguVV;~rO|nofMd+s;5qhD4<6Glxyd>L9`w<$k zR-!!H7a}KNz?9)x93{|Ozu`Oz$_$KOjLs%?Mx5`fJ5{h03XzE{ie?l7w>emO-yskg6mD^;$!jV_ zBxo-EU6JtsDrQ!v=t0iWRWqF? z5m=%x+Mzp=ZAisW$VY<1B)H_$IDOE1BAIN243+hJ6n1`yC&U87K!L#V{NBxBo=}8i zhDr@UIQx`L>2LZHJBLSdCr;jQY8WRza1|=MPY{lw`2Dw{w!laq;F@AP+5y|@NQP_f zceeR=#|2%(lp=mY5cXp9?T|h-7f4e}&-NjaX^$Vl7y;v1d*M+rX^M=EA)az<{P-l5 z1xyPpzA9%?Dv3Ge9Q;-$ryS!R8j`OyvZ`DY-YDjlWFH%(-TG%LX~`C0mG!ndQrs)w z112S)B{(I&C|Z@|~A^f=;knKCH*;@RW9H3b2V6`1IyPQ>0$2)|%> zF&Vfo25^hYb05?uWZFPtye=p2J8#hnOn zfPezZF!;l2<1cSn=p)h1>M}(GehXcJsJUkZ9@B4;mDL+y!P0!7_U*JL+#GY7jwH$K z4k#+(#W2Ci0-Egj{Kna{NYCIQ)TCloLD0ZW_mA zNzAJ)Xd)SQjbtaY6ElZIwoS!$siYAPjdx+r856$cl7zt1p`dZatSWs?kV_yY2Q`^+ zDJRR3#3P4z6rH80+5}Axhjhfh;3|Z#WY*Dsl_7BUIwg3XIVBlLywp?v;0OmzHxINi zr$IGfKJtW< zJ@K3u2=$`1xqHaTeD|f;PrA;Q@9r z1mgG@I`7Ghv2l%Y&2p-)kDOQm=vw)rW;5y&oWI{`)vJwwpG{9DuIV%o^CXL!KuJA} z0p)l}kW!hOsh7D#qCcWe0wL4yW_3d-1Yd(iS4 zq>oOgZ<6gP$CK<4U7cmitE20p10c83%h5^1hwl%RGAJMf9?wi(f|24p$dUcSK=j({ zQ;6L!Qztd6ssD-`lg$!~>)6}jJlQpCAiiU6h9p8Js;8y8t|TmBekS))({q;2gex% zX)Xym@K*{kJh)ybqD!Gf>%3?r2APMOrMf2S;H-3XKE`7tx=yl(M@L7gx@BwyqcQIm z@-B;TQLQITS!tT{C8kFlNluyI)2i~NQ~HEA>znnxw2&P$8w2E_3`*eFzh|gu5%KNZ!D(4&O zi?{$r7$jy{5Sdb0(p@-(oanZ5g^$Qf1aA@2xqB9*!$5vOx0O_vjfB=^^vbYHc~9(PaiA;M z^esN52*?+A7A?fWPd2dFzFvy2i(=CzGzatcBq#WBK!p0dhk3<9Z`cgBx7)y-5>a@O z=>}-GQ)_JC;8^ku4^mI8s@5Md4}uy-W>7o9I4H2LjG8u)ppC!Q5pfco^2Z6;d(u53 zVl5=Q6yAWynLdE}DNxh0WiNDQPj;|)nt@Z5e`}5>odx(?*o7%mawD5$e}-X(1BK(~ zdHr%1Pe{WVId#;g3n5D-co~(&HPQL)ehoE#g$$C&QYe zAMqco4ESJDBRmUo1@#sTkrKTWmI}$11;0`w57K13a)=wQ7bsj}g1g0++m4tbb!QVN zL@>6BAxbjq)9q`_!JBc&9kVq69V4A|$r(rY^~wc#f(A0g6^95Jq8G}viX7b@bX<^q zDt%zU^#p}G2BY0hZxl=Q{HRv2-u4(5%{h;8Q>blW;FV(G)ZX@)*cG=IG0lzA*dln3Y5jtS!gmjQv#C+8;po2W@ z01TN3-dnkjxPgsQ9w)An! zXU1XuT-*juJO`ZIq6nNX*KuH9o)c{n~H)4S4emH>k?)pNVO@}}!1I?$f-foTThlzZ5LYoTB1dpYuQ+6pl<@b&*EAuO9oa4)0a z+_es6$Pq|y6zHBY(~U}fW4THj%RJ9rFk_~+GZt`aQfD<@Aw+l24q^t8+Z#{T#ihO8MO%$x|5 z^f3#9{&G?g$*S$D)Y(fh&g9-Y!$$9irMYaa*@qCu#Em{d3?3(x_>R@~;ni~#jsC?c zUPedL!W6`-WF~jP)R3RJp2g_^b_gI)Im1p4oDwL9Uj>YR<9dW@JOQY%o$y>=#?v6~ z*MaNgKql%Xpk}Am!D$x>8{Qw-8;G&+xtZ)d&PlCXwFkrDQX7>O9BTpI;}?WKjPs>( z1$+qka`U{kG#U*imXm}K*Y=XfRCUq4`-mx#-68TIOCsSUjL(VWxmKx_k`qLoD!bX- zNApT<=A1U(&0gH2c_aV6a^2Nyy@O15&oSAm%8Xc{`CG7TcjAe4p4kAhF|Va>O8Ck~ zqawEoz=?qaXnXC5D(L>0I8!^g3yTG9tgTz@!p=PIyF+p`w2cW!eVJRM z^Z(WBS2*Xk(ft|T9h022VXj8Vgjl5%;3%;U-unAv6|!m>VF zZP*=n`CB34^U}8qoTJfo%Z$qT-n&^{Cg<-rgTR%ux$>A>boc`;9Mxm(Fz9DIa@C)<^?O9l2XZD72CrD$rG>*7A%_fMrF0nzHj?b z&u}dnv}=%?+$^na+Rx||g5_t7!g@{5S{YZ&P-t*NDex&nLbPh_b5ZfCVW11gXbUF- z!0p+$cM0V6ni;>BuL6ePfw#Lu{Hip>y);Q5;`H`uU$RpbHcz5wtIw=#eie*FZ8}K!A~>_$2{ep(_{}NNrU&hVBCBR zh4}E4;4yu418pcVl~wq-)dH8-zLf3m$f?xvP|J{<@##{Gh5?zK9V69ae%K1Au}Cx=(MHB9q9bxqShofS1k3F?^<`pY)s z>j$Kszvkazr@r3W(POHs6g2Fi_>Bh>q?d4rHATc~v?BUEuV=ONs$_OXsNtGuqPZ}l z2K0nDxkUP-w@rbSYLS{@jTDa6s?Z6v%^%WQF-+s5oY?p^V7 zV!~H&_fQ7XGyL!9@GKwytsJq_9Ic(4x220~x92u>N{KEF+O{w8@N9Fv*y^hC{4-{F zo_pd7bP15?A$AJY7Udi_aVmso>l2tE?=cTK@9|1SQTF9_9nUI`a~;n(_X^ey2?Ha7 z42hjue)>qylSG_#&(@nuW!~vrINR4GW-k3^IH|!r+FIEgr;U~CgsCp`@@TfflQe`~ zwE4_w7dQzOSFq^Ec_(*qRUwrAM{$g=tYD9hWQim(i;6rEgNDnp9A-B%qAg)#VUE*A zk{r?2R;Kd_BsHl;rkBCv7jhuajvzdk3zr5QyFiNfCd5&yCpx5dDH|_yC14C~4z@yh zK;?-dIZzX~a!<<`b|n5W+7VpCpf zH|scW3tw+VzByb`+rkNEUWGQ~s@;~pf+GmUV|^9R_VS^WEEB!r8>T*eRjn!lE23s3 zDC4rLh%05{5pjeH^ZGE#4pVnEY0t^(uj8-@2;#8x%bsVQByR16$E|rm0!17HvLSAC zMSk;Axs9X$oWNno>GHBGYw2>pQeCcxuhJI_(4UZ+l<{l5=v5l)^A*oc#lH~V+zV`I zs*J9{`?ko;u)T;DXcKX=gm^S?f-)Eh2~Cy*z8z5EYxpcj;e3#*uI-Z8rE+T&ttVUI zwWf4~WSb%x`*eyIb6faZe<;ZsIdTDRCX48rtQdQY~yBG9k5{9=e!G zc4Hw-JUNb2<&fND#?FCZr89$5lhZg#eGpNa^U--6(Mj)|;)Yx~kXoEUm;h-(5hjQL zA@bWplhBe#23prI@JJrH+E=`^as#kjcr1&}Xf%%bOWKr~{424*q)W;D*L!Ha#Pbvx~u3KN^eWz=mD4w@JCmtE>>{AoG6?lBf^z*Q#wgxVld)| zxGac+a}BG@nr`69!lom1T~0ZnMtJN|q341oxom*bT8HUB&9xwPSfO#;4BK6uA6msM z_*Fi^b{r% zxk%C{NdY~>a7H#}v-&NSRh<3Ww-M|OyJ7!+e5?C7`;2t5Q)$Zd=~(u|oX%xGksW5< zL9Txzq6_495-JDofmq#G8fg+t?l;|p$hH`eN)SWj*p_3s+QN}-LisMa6f&hbs?p%y z_8_H_2_-rA#Ma-aD*^)*%PcF_CH|5}oG;QXsbLrLJfs>z@TX+8E-QuR@~Q`s zTtxOJBg2~51C-hV#N1-pWS1kq#LQGzlw!>Xy1a#3zLVX-{U^B9g!|CaPg~^+@-##q z(zF~h`N}qN&11j>vO~NYkQ7aihK!Ml9Jn;Y zZD^%uiy3uu@#Zo5Szt;H^Y7E6#nG#Whi@)Xw8j+2kK|rMP6s=Y%O2y7GvyrZH`0_5 z7Kg{2IGw`jPG;XR%LG>zV&><)h*=es^3w=q>h*zk$}s~9JGiZEVHKVWV2Pk1C0yJM z9Jm$G-SmU#T_^V5<)WX$M3$m()(`flg912+KwSu6eTZS?Mu^;4VxkI`4ZAiA&r`Ig zr0}6ts+n*&lia8)K$w(_KM0j%OHz%`ZHQ99I%LSsU#tVil6?YI)4 z*7r71B7PfN81VUaK(KxF+#kWm{NT|7w}*f(xlCT)E1Z-Zn_P@E)sTCY(^7pb0rhjx zrQf%lq0AyKN?B&pl^Q4~M9#e+DUDMV#qR>&a$0lMNlrC)KvT575H0#(1ohZJfU6yG zV5aSh(0aMDP%Ij>8cCuTRq38w$k|#~OU6nIw{}H4+xbZ^7$E~yX*OFKnVGgoSh4C? z=y~A_ZB9)DeA`N-c|TZad;bS~hiPeFy70HCT`b+rK30U9d=vE;Z7a1* z_i-82F;eR{AE!Ur%#6G?WHobw(682Fe%Al2Lu2X7LpGO_9bfyY$<7Lf+zQ906$4&SEq!A5|Xuz2SGTR)Pb<_kx?!JTXNm9DomzhCUN0(h28qiqU373-v+?yx}j8`5z>& zx+SOeGme>!^U80SojMS4M2?1aN?E(Z9+m`se$O63cNQ;)gTGw%75T7&ON3H-<<|vV z9Vg+HUD`3hy#y2nIHbQ0adgIm15Oor(io3^r8Xdni{>PgQ<5{2k9-9IQb6U(qS%MJ z{?qs&rrqku3)h4#bX(E2Cvw3#C#!Kb5ws7QyCf6=ss&DJf~}Q+WYosL`E)8<4H%!D z^NI(FYg)o+HS-avgWJKTTCox{g#a6e#Noo~;~ z9n%OnA}ZQ6g}>yrw<2r zG^L9R6-Q>B=M)w<`39v1CkV=)>&WC1(C*|not;PBe_ww0`4WGBy3*Nse|G$Ci7NBc z{iUZ%Pw{y1q1*^A$KgrqQT_RG@|&J#kb#5V_^^9$(nGa}+ni~H$W0`~p>nvZbiDC! zYbUj5TVLJaXp{D_EJJ_Xom?Ir4Sq~^VgAFZ(iejQ+EB9ilV(Asj6Ag?xVOq=jd+6R zCLs-Bh&Sj7XvD;rG&=GIy_ozBxe&n?-4ooiMsH98!Fg9k5&7)$^kUG!Wo;l(_lwcN z=yVDuN_7mg$0Txu>QBxI*;*bb8 z#1yUq9(LNG?5`271DBCROCnUKnHSsxw$K*u7mQyBjTj82FP(6EIe?1;v8Yi;tLNC* zuqA3mWFTxD*%f@p>N=}QRria#m2FJ6B0Et@p}-1-`PV_exi@>JAt~<{hJBS zs1XC(2STohqO_kee$37r6h-+*4y87dAk0@iRLXwn6=uCH7*^~7oKhf4_Uv_2EyBh3 zIK&h&q<$#eBFBH?seYeY+P!OGV~7P5@+yZtP*3!Nib^7?Fu)=5H#84gH~L{n0$5yX z88jBhK|)!~MNIxX=+nWgk}O7x%7{y)@)U9s=KwyThW&(RvuYPra@MCeMY@B@*%=2O zBO#^3dNnG2Wi#Z5vNmyEy;q(L$Sr@3gh+Up(3ln3I_;l+&^7KZ|IB6L|D{J1Hvzc{ zhP&z>Dgi@lT{nJF+cm!@*W+p?QoR>7gv8ME9^Io)cyJ$c6J#5q`t9LrxB)l~UgIxy z!D!P5t?m~@YiYUo9=0qxkEP15dn@#n;DC_*Y)k3@DkBRbV5bD__E4Rw6OdJa%SJ|y zV+k*O#2qXTG<~;(1%}7crDrZ*f5RBcWt2QV)qVG+)hgZDjHq=39hZiL6$CRuBq7_q^CXnkMg z<{(q@*9tNsE7hjhyn6j=9c)|6(~#i&lU0!MTw1K*zd_ZO+T&20VmkX^XdY|J?@EGw zSk9mLf?FMi5d2Rv!frT>#mRTIE6K7o4D&ZJ+o<(7C8_aEa@+Uz$>{R*P}DM{0Dv7z zDYgevs>4~C&kiODL|Y<%3W+n&ArbkY>1$s31CRX^iDDN5;)%2M^;nD!%~6mg*2N-w zh9(O3d^winv#AAH4o4q{v_VtXW*s1r%J2uQ$mj#t0PT;FB?HZruQM?KvL#A1YVjZ` zVMm9|a%i}44$X1=l^Vj+-WgNe0MJ|9m`$g4Xxtl^JW(%!Bkwi@srv#dav(%HIJJr$)_i0pwC$_2qtWn+g{sft$s1m<8Hxt< zwTg)T*M;0`lphHxyw~_fwcS}Cyq;EUdcn#~+bR(Q*JS^KwXDYVF~bA~vnE}G$f9)% zRAK}3F(LKlB2;WWvjzxdr<4A{`z}Oj@H;vLrYX74Mxtb#_1?2`1X&^Pe4=;LJeZk! z<=fb4Q|LzbVq@^9D=Ucx!{QH=2ic_<>u7kB%BuLRz0BKt;&ZIe=|QQGIKbGE7$W@v zfuxE~)|E-+B3?H7r*58eSd%{I%Qv7<$fW@P89@XqK78uPFySA1;+ur^G(j%8T)tU) zmOGZQS0>u$+~L53zyaIE}`~4-ZEN4WgA=o}OZ_no^YeqHh>1&jIp|1??1lwV; z8VJRMW#Dosg>pfuXlPM3gr02AX4zidhIn@BhS$ql{hR__3 zMyyW5QYpH0-y&4yVVa#}abtDX6%GT1T-^UfV5bq^(jdmT?O777c3Pf8#%38zh+7}88qi4Kpnc%zDOk{&=kTkC47w7y7=9VyhDBI?k4ZlP2Kt1jqSbFt*zBR{Ab#Prh+Hjoc-e$P zvskszY;J>@BPeM5-^pOcP$n+Kxw}~7wnEbA%ia(?Y1~0YXNV{-ST-%blzYL3{r+KD z*`kX0Jg;(JuR()kSU%S~nBhN3x|Q2h^$T;pa)#QnxUE?RM^j2XmV)nxw~Rh)4$)f+ zP9Law;j)I-J%sG(>XzHIy{nBKREIGV@a8Dn4yS-~EDi=2&7&HqV;KR(mrLSZiq~=p z6PC}=;}{YY3VN^|&MPRFE){WV2qsLv*^wri!97=4;@e?JvE&Mb3dj|d9E$nvB0?*1 z;Pc?Xz%+7V5CCAeDF*h=o&Y1q<*ZZ;KkBjpTq%T7Mfkx}6TXZt1{e};qKrcPm7cvB zN_|&1ITNc1r|MKA#`D71dU#X=$jw+JW0z> zUWTFpHDbBU?M+g}!Yq7XItDXyXHqH$_sI@7G;sM|&-AY)g!^&}In77Aku0mFae_;2 z;Rg15_p*lqtC7BwHYFcP&N>ojl1EAa@<*tt%d>wYkyfwbjKXLt(aP#Xo3|s7NWL=- zn#>dFG6@FczWoaS5mh4>B|TzC2a?PZuu1tS4VH@HfC9uj^XJooGhCL%B=lpERKvvNGB+J9BN0}S4~NBMN7^kC;viw? zV+x$MzQ#Vx{2_`6i_L39u?UW=y5-BCD#3EDAYoGB36&CYTq9FKb+jJRcBBdBVl>CE z?|7EH^$w!=@7C9fz35fN6ps*nxq*v@qMDc;YGLG2eq{B=CGzxU5iFg#EGmZ%5h4XS z82DWPJReo0;S3MS;BTx68C`SX5kD2Qlo7I>zMIGa@iH47Cb&fV$|TlE4>1Ll^E>Tn zoDiRrdc$ZHkn1Y&v6YqW_0_GlZ}(oUzFdb*Yg&`%Z(qE4v;LoNWP2vSM4kxUDc+|; zVkQ?)vXoI<;)vobos@QrNVhslqNtN@m~sIqFz1_=jn5}1+*?= z@r}IQ>YpKtsb49nR&54G3|KZ#0#omjT;26e7sU7e)h zsoPXaSix9E>YZOke4XruF&qR;lb~$HOC6eJtF1n))+lC<7}H@3(7+vo#`!|Dx&yP; zTzJ4@IH-hs@cvTr#%DUF`{IbkNRr2ak8nq$-r6{{Yxb5~ZQ;#CgPoluONVm7T#<`Wu9QGdDrc1%xnN79&x9D7m$(Yv31 z`{?II<~}cG!)Oj|_DE|}Jrw`O0UM0HG21mFMX8YUK?qk|+ai<=n z9CC3Og5i1M7m+8?G~hUy`sdxI9mD4x>)~@--`d`I{YtBbWUFYHvX~k*X8bSdPL`5uQBy`z@3tYez zN)7B0y`{Ap9^RjH?@#W-otsg>2MaJ5UyM5uHmLi$zPi1>_iXhIQ@dI#6nOT!=tnWUkR2uBp<*TWCER<<>;4FDkRXS& zGVA*u*0OxBf~G?617|T>?gxq*(lxOjd@pz{73QGJ_YnG{GRDK7@~!_lZ+tJGj;c7_ zCkLbRtLmwbM1s@C%2HH$fWWIN`AWqkk_Mr?B!wZiF6~1NOQja+$CL7zFN@M4sXZBT z1>Kc*hyVm}_cHpZa7Ylx*nA`#tGMU#uTGO*K8T(?ArNF$%RfEbP(ez>YSno_T#bf< zC<6r0`rSyyL*ZIwRIaUK>ehsmoPYj;p*mVO0QDaE075|(RzepjqkI5riZ6~$mk~%4 zoD-OU7xuNVL$U_{2ZE=O8paze$scl3NQ7my%FCaMdj^U8X`gIx@ zNi!!HkTlY;hLte|OV575#&rB{*Kxpwcg)0?c|twf%T?Nx+7_$3?cr;yrf2!NaFd|Z zr8>cbbPF(#Yoo&!mD_!)E$FI~0b)~&;6P$Z^hE?M+CS^OZY%`jP3oi*T=5hRN+LOg zv-JWuoPQ&%#NL+YN=QrD1rJZ+$&UVNM5|t=_c%G=@NUQla7JyRl!&ESd{>& zmD3~`sS*_>jkEKIz5}i~6`auoGz$AXClEkS4{x^|f)Jf>3EA`|$}yMPJ>vNjj>;iy z3pp!pO%-JKz*`G={d_OzniYsuNLLUfwy+bFBX|;L2@}PD&QnP_=cU@Vpax22vM`yg zQU=vrK7t+1rqz=0i>O|Nj?u-c|I@>qUfpI4v zRCOyjMSA~JxQiE!UJ>P{Cbud*}_3cVK_ZL<$;3~26c20#uVT!!zsnZg&&l85NQXQY`2NRY8ZarmM{x5 zh?IJf@jgj>FaN4%IoO*SY=Ktm<7X@2jQ*%@Ri`TQo&kPowD}`M_vF@Sx*42l zhnzTLTf6pi6Z-jG7K^Hkw+V`k$i~7i6PiUoT@nFPG_JZzV0MuVJO;tSW%7pRIsJW> zOGX?38pl2ND9JbTxr$W0tFJ$$4xJZ+16XDIbH#oK@lnmAjn$`4ty~(43 z{Tm9!8WW3nVBVG#d^AAKf!yP%;Q$LH8h zmU2K#fgZ$_8WYMZh)^r>;%(9GMtVo3#pF&YfXo>D1(?@0-_K&(^nItZ(x|FC9QW`4-Vt ze}x00clr%3q3Ms;AS`we|B;4mI~J6&+TINl0!AM@M%)|2o>|>FJtUP~v2j38^XRFp z$2usJ0Fws#gdm?|DekYqE33@0peQLkVkL>QXxJ zB&=Lh0c|!pPGN~cg@Mh*-< z$tD{54SRwXDaf?v^a*z=*$<0KTS<*a&6n)H9maCYMub>&e7V(p_+QE2QFRhcA#NPnt-jNIJAHbriJphOvPzrvnCvxt0_^y}QST@bnfF zbR>Pe7@P{EsT{F3bUJw@+a!#(P;nW4HluO5M!|MjeE_0407_Paf32&r-Gk-R_1YX9^}{jx zoI^2FJ5i_0pj7JUZehkIf1+R|&S{Z8AiE7ZHXD^D3tXVcOCsFKAVE-dIQ;*$rh=Nrf!*xLJU^~DB*ZT5hc zs{GFhSzf6V5yXvXadM2(^tz@%^D{t*j<3*wv70sTlS6|UQFj%2y4=5MyTSH#F=y1>bL}Fg2Q-bq5`jIKHuMznlz$_vM*%9JPJ}UqqMv8VV>M?wIUGETl4lfC zK~%b@OgZH7qTJ43fNhML!p(39_=Ts2?)&UG;HS4G{0Ah->)!7bqY z=C_-B-*3En_WJwnJqsJ#d%60@*IRnxY)ZTl3m*N;4sI6hA>jVr$Nv636rDalh0Hug zoB-UzGCCaY9wQLH(Xt^w9v*i&YvLLFZkIn|E@c~kKbr8Z9Og$FI;dX&l<^bqP_wpm zacY#~p|J1RQ}z{ysD6PaG2Dsa&URipuqw4Cml{j#98{Pm&o``_BHamX#T^gqnx%%t z<&_Q6ypbh`;y$8Z$)_NqhCmT=2qqm{uA+e_v^7Q%5+SvDo@^Kz3n7lD@MTuVB0Psn zK@{R>=`;aBT3~WTjQO*ME1xwdbKioW(9bk@}TX z$TZ-DNlNawRrp5nPUM5jy_uwby$~G?$XGE9+)clHybLL3^l%?RB#?#d*OkZ1kCq=L z555i$?s;o@0``$)I=QGdp9c|Ob|~|91j5&V&JtSnIvv82f4xelqFAT#&2xBewO*@A znlY9cXDFtD)eWKf01yaf=H0n#m>M;23Wg*FTc0H}Sj=>4_O9P+ZQsS>=EEmg#>Hk3 zdPXJ!gX68{BPY|f-t34>9T)z*6O0Tg;m{oRvsaE~iqS#Zf}{^p^iUw6G>Lc? zmX4UV=2!tE4MB=SU$-FAFsp1FQThY^i^8qhH3-VCC6fm(;>jf-2PY#Y-XJB%MNM8m z%Xli-rxXWc8jgX?yPZ@<{@7F6XF&{t!Wme2g~{OTtbaHFE`z3X)(1!_KtTK{!oL)e z1hW;jK4I7cRCOwOL6U@)=<>#MyrNbQO|bv*^lA;(c^-hTTQxoPFdwYoz1+a5~3 z;|55}{F30c2d#TQ?GAt59p0F$gIE69#cNgU<;J-M?fECQ7u5vB`8+@vnK(#gy@ z(2{lY@Jlp3xwetoCgq6O0Ds~otmy|%Y{fuAGnF;enxZgE+25>Nrg6=4cOiF3r`@3o zlB}(KtqL>vTtgtReS?9pHs9KaH%!f~dA#F5#CPvtP*d>h-q!(F{mw zoKbS#LRk!Fl|(-Wfm&lVgHr@l^9TX793&(W(4?I4HJnZ3C~~k&sMCO^km4pgpU?wG5s0+S(PmLWuLWG}L%4T9^LXT?RfUQzggihV0 zQYD0ZU~!OmcEB`frz7pgXw>AdT~F2y0}YaL=M#L^oGi?mYwchVrF{sAb=H2ICBDMmYg5EZL8sNrlIq&$I&c0J$`T{Cze2HMaee4+*DySh2$Xn-@E*V(gBf0 z_=w`*AHjY>?EIq5X9O>tE& zZr}|GH!4SD11P)QzTAJsN@|h&qHh~Tm~Yt=nBQF6o{c5So@rzv=v%K|8n@00J3#w! z@8F`d!JC9bxK1G9%2$%-M$)ml+Ph-f^*spA0#Us661dOUC@e;~P7&v1E%b-*4wN~q zuOCL)u(*~g%>5eQs2nis1BK1B6qoekGh5)DT(W+M3)Q+b+_Aus+p~-KCANu80*gt^ z=$xI#F?qZG*gK2*gU3bld9sU4f*xKTFd3)b2sgJe5{#Kf1cd(>7^%Xw z#+P^`Jv*;U?-)=QfA!ATY&$G<|DQ6oC0oefUyu_f{ZhTBl!je;6QMC>(;rKcBO9ae)Tq?f=oicvRJm6SH%CRz+EpBQM4)dGXUVwldkRE0i&ivTFb z=V*U2C6*}D(-e+1&tkQi_}p+V*z5#i1LUW{2g##Q;mEtG6^txK=-d$#y?)8Z8vJpH`g)zkwbw5iKn1S^7Q{g&q8_y}K*1;SXLD*$?vfFyx|sgG z_F|)TiOWNgBnyVBfIo#blKu}mLwE(m0w#%1;1!bH$+|~%xZ&Yw{BR$$;WnWiJ{z|- zSKoZw>JLBQeh|jlX5aAgo`aQL0AM`X{R*=hKiOS9KY!M{=~u1%9*fYVX;` z7G{tp$QBtHRFnk=gM>Se)Xu_=qxTG8{~CowQ8^D8y#v&)_-S|Yxs=N@wzY?P1xg#l zY2a7Y2QzV0ysSIwUh->D)a5T$bkOH0I4NO#ZIonVfEbU1+&H4IRpqy02zp?4+NlFC53Vw`7Di@%aDp9l z_F+t#c%y7ayNh9<#tV^tI6Q_|%?m4`3#&p2oQAO>WBJ+}Gc2P)5>t~6!0u4sPN=h1 ze1l8HirDS$A9tRvoZ|mS`2T(Ue~*7JJ@xf5^WDp{X&;fl~dr*y^$=%G94o&g{r}OjI ze0yRxST50wAzvLZ3MJHcxkajy&m`Bqooc2oetNlRUPa5m{%a#;D6`QrZrqqmgMU`T zG&rU=zCnNnI~5UQla;!KFH3jHxGA4hmoz_uJcD2h+%LxonB<0)C~xU#9>T)1Dm(xt7X zbZyu8kv+*PCI^-ANRov>WfDy|2fW|EykI;RG!ID5sBes4<+Tk~wU@ ztqFeJY9S15L`#c!w?a!zn;1+)x`%}xW*%UMJHhlTI4~yf1v9Lqk=Kj>z`O;};eTEB zCsMzt4cbOBb4(2}4Mxwc5OK#(WV;8la7z(TJ-o2KOhbI^;TAn>dniYd;0)eOvFkZzmH zjb;bb7II>L!R~kldIae|Re^H*)W=x48TEOjjPYFChwtXY8~WBA zw78ISsF)gd11G>3;V>j+;_ICKiuan2&Fi< zErBzb;hkyl8Y5Dx!Edv0Vh>gQaJd$Qe{rNB&i!n3i2E)Q9Uy+(Xiay?)MKn5VSM=8 z2mT*x8j7_;n-nf&nL-%w2%@jvttlmD5-S_^`vcYk1EXji$YwSBbEy#NvfU^S^Rrbr zjLQw_4>WFz0pX2Y0I z+1y&+!wqw9-fr)$y?ka;G!-_9OrrrlSkp0LG^hvVnouycPzuN*e>e?s5-U2K8bb-3 z5Vz{#StgYB$InM&TV&r0D29SeT&c*&Ngpz{7HO^}buuQB*1^D@>4jAT9nwY-1=gjd zFn}FIZc`jfW-7jT9SPCgrsM(p!Vs!YDh`QimVALlg%5L(hPT?#l;C*;D3s+206Hv z>a>O&LX~;KWr#dOYt-s=KS*h$NxvT%n(!A1ez-GQ@Ot}AEite?aGLP6^%%(*5@~)D zX$sUxNcC=r@x9vWBO(r~-DPQyLQwBlzJckTD0PjB&^W_@^(?QMkI@;
UOfFCH`RpAk{0M`GnErN9i^6dr6z=Rxof z0-4O!yod-Q{6%GloJkziQs$-8e)vP@>E>4~D)VHg+uB`zuzUW~i=TJf|KI=lzwbU@ zYJJ7G{WDy9@?`n*r%O*3A70Y-q5a_(=_T6F)XX-R;DVRI;W|I-Xp^0`bb@P!6AGz( zdOopq+wPeH!oMJ{maLBSpzx`8@eanM<4dvPP3J!|$L z)BtrtUn0_geyhN6X!hgnO$+Tmj!uTH?K6aQw7&Y^`29cnKlWGyi{TAV+E#rv?pxpn z5SFo5jRn=2d>F<0#H*+IqjVM^y9deR7$&jOk$`fR6+ieq5jUke$;JM90AhIFi z=R^N=bS{N37&ryQ2UC?Rh;f8)LZNY9w75wpPXM-r6udms{6Pzg zDD|buT|rk=76gbNM!Lie2(%}q6(JiL4f12c!ebG+d?Tr^Nw_Nz+DGKgT}TnJ>@wgu zkRE~@^USKbW3dqb-qGm*!M9-nQZ`$7x;gDe689V(yT`(@Whq#U`~Ueaxb;KWx40Uq|Ai_I(!Tq|YSjB! zY>|2yYrM4;)z@W7-e=2@0f>zd&(IS)`YgC@Z|2w)X>NRmTi!LqUoVrXcjZCYg=$+7`$~<9AVmLWIfB#%$|1S&T99+-Yxyje(Dc>wImVAyStBfcfaiJ?tZbm`&+=uE5&-x5T?r#wLJI6 zD}hlvZT#ota(|g&|1LTBnyT;R@JmfqwsA|NkXwa>hMs^Jg9ett3>o1 zg86z2Y{>r#0aC8UN;jRabhb|(s@-WRAnSwl@)4MEP?VuXm$6kn#@=y9#5eynD;Han zU~-pfMkaKvozuR^@NT|!(#J1q?_9J{P!TkwHAbLV;6(HV6c7f|g>3*qL&!uh>C}_7 zqyYp0Ty16f`sJ6750JcOqDf*E;$)H`SgI=dvtboUi}HIT(h+x5L8@PyDNk~cOBzYi zvn=3(HX%Y6z}O*2-f7Fb)X-^$Qj8KJNf77p)&0p6&M$tW{bi558xYCxfwVN9}UUP$gH0xOCv&?-ns1>di~Bv1yiqUW5uz$FK-BRwuV!WSo49eU;zSYOgB6>Tfi$3`E*?I> zv1&WeMq)U?1mQwqdnb~avasFnjd8;rbeO2L;QWhx2{NF!p;9dK^M{;f%)$;MCuabI z$?43lRf-igldo`Mk#GWNRr$>D6t=2|AaeWX3W`G0Wnvd0ULHAEbHf~wfy-pP?j3$gl;5{$;% zgpjN%aSW0MWn&BWS~mhR-?6sk72f}ySB`1jXZFxN)EKqS-XRzb=DW*44P9WyGUSNV zy;Cc%!A?fc7N&*GlIj4km6x&-^!gJ2e*AbRsV^4w=qHKXx78`(d`i!Fi zup;jGc3}CHcXEHR=q>}4#|L#m^}NfWBoMPGqC`?*f86BYJ8y@*jcaRZb4c0+yF(~d z=VW1Tc!~PUgM+MFD2us8Vt4YJ&hGZ-OQ;cnpUc0&FTYVUQWylQ_IVKGPV(*9&f|Bm zHbAEKzrT1V=OiUg{;C6cYAKn1MWBz7GHn#-piPN!G_5cdl5U!UY!`Tp8vDi>@~K*L z$4m4aLcNR9uHby>WUTn)jyI^9c-vRC1Sw5ibI(M+hSvsYJ?thgcHe9&XN3v zmm2=0&l3ph>u6yS0LJJDZiIuVfT5oO8c!q*M}mW+Sx$jSL%cJEq+3ALsB^0WsG@8$ zERFl8z2SQTo0b87h@#?PW&S-)c?qA!xMA@R7QS3sP@)uphVXO`@(@VGKe;LuZ02B> zP8f(;B~fxpbVK$RXN1MrIDySM7B9nl#bX#7hhtbp8(FA9)+)7FKm16%MSga?mGo94 z)~T08Z7V=MwRJkH*V)twjzl^nT_l2&fOTG2gZlg-df7}t5Obo?1XDS@MM|uT zS28Lb-wX}~mQ#l)V@4$(7S_RU5Oafbpl#tv!#5o|X~b!}cyLBn6u;lp5Y>+3dK*SY z;37S0UB(dE`|4$TI)+4%u)9zuSY-!!GMH>%9xwp*=n|J<3i1{U!X$$992wjm%2c8L z(GQ)SAHGH;>DL|bx5b~&FdH2S@O&-BgF48Bc20t+Zms_TZlO1OueYA9Z)JF3+(vRW z}XfujI#04ZpYZ7Z*?*M3=N8R>Ds{j%6~OyW{S(3+(rE~pcnd^Bp?dAW^8A; ze4ucX+r)*IDEh$p2>wUx2z&n14-cQ-pL8DX{sy&*M2wKl_{$}Nieb=|fvGvturw5b zl|!a3dAWjgeQ)CruU;d^=GFT5doMO#t#4N&AHqm1==`Ad=s~NC zx>OJ#W3S*@{DN!5DrJPc8g?83iwcv+6`G1l%kp_6jPe+8ab}QDm?q(JwWK@ff)sOa+9tq z*T)*&3MMa|vtzx!<)DVs)umL%ow_Wyi-Ov@3o+W$1=DOqK#)s`4_79kY#a{OE zqs2#|ItTYm_R(S*yqlf2c{kEP#%$qJTiUTRAY~wkJjN3}{IsBmY?I}vcC&D9srKl( z!?BgP>TSyy0vsqh82R(3iLFs^TlZOz&xKtGBt=&$nb4%QhDZY{*Vq^t*+|o8E;$pL z^Z1aQsV%hEBq)sf8W$hbIS4pNN$w3%IMTw!X)cr)p31(oI`=0_%dNGO{sB~%B;o>> zpPhn7pl#IFU?7O;+W0}!}oVzq5RP#opp&X=U->9~?) zM1^e4a2!crnktk%+_WS!`?*04`lxq+(4E?5HZjjMQ(juMZBFqDQ`vaEyYaedEcu@2 zT8o1MUGT3*_60**OLL~aJD9|UN*-okRe|_4bpHUm%u=~&-m}QxAwMWj3S)+z}Cs{50OQ^E0n;|?D5_v@$hh0mDNX^atG#Gb<-pty<3;3@&Q%qVi0xK{RwDcDDGVnVF3 zS0x}oNiAhrvcK(i7tTG9I+UP2Flt}ZfhRI|N-PcLKTtKvTn!A?2$S#_9dL^`%OI%O zN;}O%alDuz)%di-P0ah^ih^PX85^vobOx(GiH2NX!$IJwR7D)dLpPH7MtKzPy;iG> zR1WY+r8sJ6zXwBjHkyuur}sR1wG#@Bu(6#dF zH7hHFiKM1)GIo+}RVc+TK(r84DKCg&HtWNYAN4>b4GHjro%}x3vc>I?w9a>SgEh0Y zC`sAm;nv*%+5dydv;O|&ai-Anxn7;sevZt={vkr+5GhTuo00#J5rF~kh#*>3?j=Y> z@0d7-xrXX#X0{G+NCvgenHR1DFrf8{xJ0frWQpjvTQ3xaMCK^_Qbb;4u%-OZ0hG+# z5U}QCY1OBibHywjSO-CvltBb)3JaVR2B@4keSCKZF6r-v=Z#F7v?}RI&ytFZV9~Nh znX(Syr)CLe{p`EqwF`i0*LoUQ-w&lDX#8zYKH%sB-xsCg8#+t}tPmxhN4+IX;9Cz! zN2;V(*X*WtF6!RD$(iRE{!Idz%6!5nIC26>H)y5<6>zDU-gN3@eT9ilZ>`hi$pS^H zrKWFrbr%m$LQ8e>P1I92M~JHvM>^v&3d@bjS_t{{DID#$$y;vgL@QOp=F(|}+6}HfsUK3?)YOi*T1TkUnu&eKsrJX5r z02;J6A-xe#nYgW`lU5j3h#HoOQC#(0B$~g#Csgdgbg4ES^z&&3Y?ZaYZbTARU!bE9_izCX=m8*fL$I zx^Y6L5NZoiA&3RCWkQnbh?2OM@uG(HYC+H%)@veG!eA@&63J2O1{Sm~70;B{HOq~F zxs*Dp<$qOjXOqaOT|QUy^8p%yWA;TVU+SVu0kg0GY+Vjl2aOgVE^4C5 z&4PWE%~=HpDGf}c14NKTO&+0euc#x{D?H6VxM^2d8x2=W`k-_fr~#j#s6)*xD^4de`#ew*AwIx;ddJ4hs@(?eR((~^?&cb> zpv)BTf__O#JWBsEe)37|H*39vlhRmI)Q#IM{=OS?%~o%`iikXvN>&36!KStuym8eG zmQ^S)uxw3Q);PY&?Js7OKwqWx;96#sVyV#c;Fv)9v*Fy@n7TA>k%nt&j5R#Qbd!9)@#@*@@3-AuviHr~jTg@>K!wx+hFi)i zm&0*y-1iEGdT-Fgb*lmaDt+at?pLq^7D^#e1=t!T0YX4 zE0x_0`mkL5*gv?m8?HHVKt!EYhw4!lF-Pr9LeEPunR?GK7VAo81ml^)0Ss|>NN*af zGsVy#1_Eq%T}%JM0p&mhe^xv)3S$VMpiY~l%D5oto>d3&}%Zk03D3fSp zMh5Q98=9_9&X@6&;WxNy<0@pW5)57XTU*#{SgGJv;p}Zp%+e)cK1%vr4Ly=|2 zhG}f?|A^?Q<<_5B)qH?bxKfx8@X{blLZ1fQ?$i`vZW^b+q4aG%YM?sqg}PS9X% z6BJ}fjExoHM$6IZF<->;jZgx55nonTM##(vcOeK;BmqWBLh>P~J<=A3xO3 z_46G$xX9vc)M($D&+WCwuo-y5SoiLhp0N5^%1R0U&+TF91jSYc zO|XB60~xhwEATLE8+$js-qtPO@hWpL86S^4D*Tber7K@~GQrqrZGA&c#@C+X zYE2GC=T~n=u@PY8$S7*HaskE3T(U{FBq1q0%q}IuTx(|v>aeN+)HJ?~0R{H3+ZEAW zA_%w<-6xz@Ctz%WDajo1Yu()VL9!2T#=YT$5keZ02%-(}dcvDi*w82#r$H__FWm;% zCIrA53!s#!1^9n9817lfVfyNUKKtDx#Nz($(HH#Bm;BFf;f~O4u(iv|6XKMd0fM#k zGwEs@0FGQ7&pSOCD@ScXo4NjVF0bi522;O z&`>+G7o*-G{TSjVmre~M1h0r`ZbHe?E|D%860@skzh=G#M6C^E3i8$~K z$78w=&U&aYH$i=7S}58J_$(UGA(GG~B(@5g#aJ#(>>mS0%nkc;70M8*_TU4{$O`ln zcH!s&4-gr9qNbfTj~&Jg6IfEr@z!z2Nkw-X*C*1Gf5f;)Toa==3bXtxttwoh?Rl%? z!X4Hx&;|qqK&U#a8`Tsl6P%^&PE{>lzQ}veN^edOBIp(wuaU3>iX~@GZWu_Ns~!gy zfWf)&Un$zo<+`ao>?EW)X#(xU3AjYQgnS@F*0A+t5wqAj?ZdUl#gQzd=Fb60VL48P zB5YD(?of7~SIYwHZfkv`r z)V^EhFVws`sT`Q_%b@5*fpBy6&9_ir`D5eN^VfUdtZuKf#Gg__9%%VjGh37K-a^=% zHd)XrKV+W;E3ui(J8fDrClhGUWVz}k@C00Zh#ZiUi;MFKN=3}v51P2ocmY6SownW+ z>oiQ?j`2ceC#?^IUP}fs2H-%&@J3&%ITk`7Db+PD+?Nco^BDKbz>&oqI#lR8Lear@ zKmGR6&zc}^_$tCIcPIEDAgA%5^rO5XUVHby*iaW?UIW-;nu4ft2`vm5D*HiMNF z2|HLHeh`ge+?Psl>E2f2Y%u9MI@)TjQCFY{1{T@6mv3~X7o2A6CHUOrc-@--LI)!h zpYTkLd-o>~?@w5bLK;B4KLUABUn`KwZW^iw%w0M30r;r^n-;eOcnP7m8p<+d9F=7( zbPgi&2ErGc=2E0bio5uw^cFC~rAQ(y41$= zDgSEtcAx+(UHq0z)*a^fO%J^mM@|ksq~PExxCANX-_UXFly(+lSFSChFa0%G_0^{0 zOozQhFxAZfJrE?Jqf%?eT3yB8EyXj_@DpvbY=LWp3;}XQ)1?Dy+hBA>hJaQkG)1Q> zz}-BkOodYm>dJJE3}*q6N>o{bg{g?E;1cZC;(O}ZU=up7(tr%zB6D59>UMyV!(E$; z9(&(4-BN3kgt|Ffuy!6glfk2yJCTi%-|n%FYu7xK;!-|jJDw#1kzUG&{lQ}(!UL_y zgUd+=7Z9{ie`k066tN$Z-$*rQ>s!(v9YI5m2rXMy+n?m$AS?lQ;r>$57qY7gD>Tls zXIR6LhCF7k!4e89(c?!PmvFZ<5T8x!3ExEnXjGJBbs7%e#tl_s@eW^g@fE0N8~5>n zr^w90)qJS7bTR@HYTf&Ak6|$%1~{c+Q2=p}N;#H~WWuf`01+WL5hb|6R?7*o3|BH8 z$f(2)4?k?}Ts;^*`0(KAyQiM$L~ij^u||qpx3AhO&Jh|AM=W-&FTlF>iy^+4c68e+ zX!sQjT#J4AA&wQH>AQhuW*fBDPth9DCalvJrWij{L*Ifd{t8)NHu#u( zMjn*lGl+6qe`|v(BNEHPVR%W9bOsi#Q=j`on6)?>luR*VAxP*F`Da&1tV9|EdVv@? zXq0 zY6PXR(2SQY|K>j^nV^UW*Z;SPi5j2i|^vCafwNMgvq5i~-`=ogH+7a#j@ z9OpYP_?==<>kvE&6wGDsvF}jgS-vOYj`JoRT^`loZY}9C^qdZA*-H%HA73!;kyhtx z!aM^9?4eFV7@W8Q)vefL9J4Go5g4Jq&3Uemk4i1@s2Y1i3uYzi##G`>n0`$rTG#li z(HIc&>IIZyag*WVc!Vy##|;wzxHYFmViVH*;74q}(#DZx^nKnfkAC;_BD8Ave7 z_J|L3%2+5R;OF5%5`!Y$S;&ffZNfOIYH`P>#jDX%=k`~DpMg0CCzIS@=8I6(2m1r4 zwm?c0U7;IJ;ja~4t$V0|x6|S~ZDqTgCkP7fUG&_FZNONx zW+6zAbI-?ddx3}*M$Y0sDYipf#=Nm@<)`h3wkyj&p203S+wkXA%F`WPZf#tsH4w5b zZ@c%cW~U-Eng2`+m8`)lxhe%DlT5Dt%fabk@}@dfJqiYSVI&gpL?5T%h2mt=1)7%2 z4cp$(8KK_jyU9Bvod_CH>g@dSpfA@$%zHQj7t`!!jjxt~%vK6y6fxzi`;+C?R=L;rkzxetXhNm%fQN## zB8H&~M5XwcU^Mupup&7ewtt42p;tECX;ad`%{R1IXwq-qIxJL%-Vx$~>+C=++wZ1) z#mG19|6*jlL*^Ddw8#9jje?*CS6@D`3lrj+*~JB0`FfRM1j=23+>}p^CC1~*L2h~o zlap+f;$aN~EFrRjz#73lMcNcInjj|gQYWKJ;e0B&;8%VO;4y&1H@Gm@8R91{5UL$+75OAxiJ^8xh)ZiCMC}>OxhQ>HEy14OJ3?sPJ(sD%~ULiAh3@MI#@9c)zCj;N}zXK zenc7>NKHaUv|N}8=dQ|1oV29O-cK)%U?@?FZJ0>>Gx(M`%}m%Sn5cKxPEH(nr=m`> zetSI&0KqgSxfojQTF$KPGFJaR9N*F;Y8L>gfAP459uIuoJ36+)QJ`F}3bFpYX!4YSUqwscv-PLl^hGOXg~;cEe6@)ognTCWNCd??eN zkTIr!s%g@FGMcxU5*C>KA|07NJo~nfU?7ABCM-Nz0H-IMzCGd<&!2%*#8!r)ZkAr~ytz2-jz^gv2wzgAf*+Th)JE({ye=WK!c1y`T6R~<=O z@mFp0oDzSWQxi~A{0(4q=!Ui7O_-?u&L#zzF>Vg!J>30(x?uKHzmsWY3|LoP!k6dE zDoNotj)t{V;K=0~eE4f7>L-Yz$|O6nL&4sO8fl*gYKAZdn6O7@^4Pf~b65(C`{4;3VMDEk*4>mu5s@=0Si#R;V%t(b>L z7MNa0F9}uvs46Pr7k!LhI3xT>AVTX$f!GvS;5(U%dR-|kQWzeq*(mi(p&9{} z|9GmwO4)s7R<&^TLy?|vr>}x_N>%ymwW!9-&1yIxr1kMcVO9mN2%iNqG=&_%<`>%g zqVycbVblg@Cn&Y37`WsIRK$*ih#~~*9PW!{)>S}c|HH$JLs+=cN0-XxQZT?!EDo}b z*%ovc*qUz>LM{ldi$+g!rBg{G;xgj*u%L_w`zUOId=x0FVx)8OF}pp?S4uAa+fYfv zD}dNmJ}03JE`-zmk!U`Hk}or7&t zV{>LjrcSK|AYrS|K^ojKrY0qgS#{su%ia+6N>kq)5~!K0u93=2mqXoLgldTO5^-iA z5yi_u2E;g&ye7K)*x{QH6qP!d$U^jA>C{S{b(Jd0HoJTRw@6Xf#fI*(?m@Fk^D!w` zTw}E$GFc<=uYO_h-EInObvQ{(1f=yZ;j=p2^f@_x%G~A|jXUXM@%PF|w$;hTV{=^A z;FOY4DlW*m5_F=dpesxS0&lx>Fa#Oa{ zkZUKC+D z<2Vw5bbxR=%Q%(FTyXSy3w(l5Ic%F(5%(AUF@rDSUyTz+tLmY7FD z2felKXa@?KfZ$CWMoyUisUmt?|Bz$^Y3n0ZTk?&x6O)A93}b!GO>2X*EIS60iYD2{ zy_WXK+etVef&}{qNcqK`l}a=@$xgUhg{k4s`bZF>>n4LSAtMozXq!kO>9QP7h=8PP z1-2_+jbM{?7v&!W@zgrgBjR9+i3!Bs}vongs(b;mGnI2+bgF)x3hyIa*EYfta%Z&=v_f=!=nsktyPGY6bE2F@5 z%*IDSH;PAroe9W&#*}gV_dv+gvnRXk7UK}0Q+k~(WkE&)Xk*}l?;xUfA9G-(d0O$r zMVAO;jR5}2;T0oze2Vb>2N$T2s!cGoa5Dxzr^2dL2jd2?M$AH)46&T(~fz}l_OI!6$0+f^e-7cZ51OgrgXb4(!=bI^LE@$sX}TqiPQ-`syWsf_bDdD z+a!x4Vw>n6KnV7H^tkgu0uR!cZ;3*PLR*BGoKgo_1EHugWFSX^7u_d@v_4Rnb@&C` zl_xwzzxWDB7pmF!>0;(sGGuQ(h0PKsVG&MUDN)ant{-PaEh*0a(@;u>h)LQd6lE=+ z$_%4Q{Q@!{^unw<+{l|3d4yl@9DxR~gH?cxg?y`D zpe~XAlGs=53C}|47l*9`C$Pgi;m4^hqx)pqhZud!<|ckdnPoD*Pn;9*--YtqnJ*tXpYx}A+)1ut&9MR9HrvUR&voCzAqIQ6s|$Rh0_uB zmbq#zz%{{2-k3zN#GM=?T@UrPX?mb3!E&t|mm=o^i=jX{JwXXktuh+Atd>ttEF`7I z(YeD^Fice9c;+?*AH!u8L~-cjOiL31yz!I>W>$(LoS-yd)KZ0xS9e9q zY~Vm3c)%_@fl; z>S%~blq3mi+~`zmc8j1ei&)*E4e&xCMvtDWTApJt6qA|MGpp^E#66dkwWtv%u%5MR z=OjDDEa;fe;V|Q|Kg{Upy4j>}4CuRmtfz=dwz}KSGO^}#*cA`b+ws&3#&33rk z)~GUhZP{r~!Gf|GOe8`7T5GuESKHM|+1JBeuI5v%g-hPPIy)K-uW(H>O8*RzEwuX_ zms|J8_Cv)aE+$-rq%za03c59d({o6H@iE2Xs@}*(tN6B+k2dvn;BXTOh!lIYp~)+P$21;PF|{sKR$@KRT(w}J=OFg%4`;j7{(Vb zgQ!J-onR2g2z|+eAgibFK~NYrCQ~p&R49Ye;#>1t*T7iqBLITRCl$yg2$~KJ*UezO z&I_3xeF3034qECjN&Bl#Lws&?c1qaZexi3ZH(@u^4#zy(AYy;Rt`~)E>v260E9O|R zBpX5oP`(U>cN+`#Qa}{C?In%d|1~%_5{{rU=}0K46_2LxW;ZrjSy|uOd-eLiHa68D zEjt(;HsTcX9QMBs&L!QnQt7#@^UQM>5wPoxfVCvnAPDx?6(i2j46<-ScThUuYkrAjaiBiZz|7{=;(zFKtr% zQ;Li}MW8Bb@}U;S?())8{b-k8J?!lK@bKN|OYtXg;crmEmRP0XVP}~Ia|Xd|VDVq%r0llvJgBI@r!#+fPLm-O#BB1F!&2zhtO@H>qMN zW__tZsrTp=MS<<^!2Gm%Rba+QG*t~|RnGKK&eW{#xPq|Dxe4X*;{l-&R3nfp3i(k* zs3BgN)R~CM@?i+=4JP)A0LCm0u`L~mdIB*@^%T^jg(i+07?&2{*gYO1o$R}{ZM_mM zK6*A1#xRM`QPvbTxJS|iSKP682<^rY2Jo)+E=J?Mi;-WTpu?&FaD9bLR;h{;8I(pR zhe)sBg4hj@p!Sp|x-=x&uZ9K~EVudqasT13*pGxfeHe^TyEDd1`L?D#-i!0XbgazD zN(&bYhI^>7YaE4}$5K}4^QPdKQ`gR#ZIJ~Guqju&FwMumimTq#)(_|CXna6l8U88U zH|<$eO#|3VQ-4I?MTGk$J(XK>qe9AN+V_Jb{HS8!gnWpw)_!t-4o<`iK6wrcPT8DY z5`C-UQfl=VE~qWNA%a#ME;ng|@0~F}WHZP;C7MdJ$432&3ALSZMI_JRgpJ z(6TnqOhD5l0bIm^a*7TxJZS$1g*VDfTC751K+%je+sKNUA_z4C8C`sicqmaHtpyLW z{9R%ijqo#e3e)1~pFuy4x|{DwssZ^kri@F_60UaJj2?+V24y0cte-n9I78Za24!E^ za7|Q2BQ*+*w1Y%d$!yP?mHT|Rei&U+LZxCv5>*$4NaI|15YqeL z=drT~D2Cd!z9p?g95lqbg?oKboZ;X-6F6HepLFUK1yNlQ&-yJ~@iHC{4q*#(b6t*@ z1YT7~!kl5r#0B#pKoi(cn$6vY2qIHJd9hE3=U32n;-kEJdz=Uq^GS{^i!UxRLrU5av8;-=|H^8jc7 z0SX91*M)hbK#&;pK!YJnDy{C}v{s~9df7Y8S=YVAU5(&mk<)J|aL*bDL^T#cNxO1J z!#F8)ieq|*p$O!847bv+#ZWcd8 z5utd$yhx}?s83_vTjS5*^l}8e3a5>LQ!B&-KXphIZ+Ps(Y_chsVS*)Kg}%(PvD`!C z2gH+)NEt<@6=W3by!9b*C#b&R22wA30h zZLMI0q3pda8cK&0qK}&*HvIMf+}M7zz2ZWOM|O$w-)bYKtJOP&W_NgnCBa-gS>`P| z0?*&q_P6nB?e(jg{xGb2Ftu9*$Dn#R;#bit)V+4>Ja(_e+_^&k5Om#`%wdzZCJ>I|ZI1H^H)pi~3+idT#(Nv|QkFsW;vIQi=rIP0Ui} zw2$BxUX%U(#w*-vy}kF{`W9V_d*8g>c=1e~dM@2!;Px>|R`&ohHwKz6o73Bd%U-57 z)L=_r86YDvz(0Yook$&(K+jCv*4>U_{#+{ndHmNX$H0p_-lrun*=RI5(iS<0(DtLW zwL5GUVNawC!5&F!JDxGXaUQgO`{>{QACZ!d#B>VlszkTyOZyfD$S%gGC@ExrYk0`< zUscXX`@}l-B7T6?&aH#7#*9E=hrbpuWExqO0)t;X=Fb*ak*z{od5Q6)M!Ns?i z`-O?b-!RGt4ftnWi{fMzP3p`d`PhWI*R#p!yxJ~O%L!&tL)@$W4Xd()n1*c>eLCqM zY8WGJ+GRBzI3RUlx3jAhK%fsv>@^rsJy>y-kT_>~s|w<5eNk4WPs%j}ojFHX3o+XLxbMpg>DMDbO@p zsMsm)7|t!6@im8-_MQ_b`rxqU*og$&%i)?1ALilfQe+7$u>3IUvRtHjlM_zWw};=D%&>?9yQL_u=Rng)-@p+>Lw)!JP!-@vS#dGcYbAj1^ghrIr(jWE z=7Ev&>&RAPAsixtz%p%8MoCqw=#;)!g>>iw3(LE(wFvEqlR>kxqqHHcaD-+B5N4HJ3Si2-Su;c`#9RDb(q@1mJOL`<2o98B$Hp{}o#J+49$~aKQh{FUP6ytK z)L@j6OUFHTXE1ovj1cC6g9DpX41s!Q~7reR`$@S9{?wHIZR6r2VVNzh~g z_zza@jfJXsc)%JT)1G~OG0<7xBR`C)43^}VjJi-Ik6HT zc}w=Bt57zd^z4S2YN{{f-|h9k6I{z%qBIQDBe||tsj;3|ITa;-O8&z?`Z8f&toz^ON?~ed+%2ag zA}7@4xZo08*w;W&La-7892i)Dt%b$z{2VtLZ(k4yps0f;pIa6F_ zjLC!q81c_j69{oGK^C;(a@?VTc^(UbtX46wVgn-iwTV{VQ5e-?%=Jsr3%|GeT>%Ac znF219&OA^ym)zaWIZT%-M8H;fpO4O&IC4GV;$BQN)~zWfv%=eJuW@;;C}sAanjO)d zu2WLsFh+tF=D$BirWS1xhrBgj+yMyJJjEX_m8I4dQxzoT5V9F+$sCIPgq9NR313M* z3gQp#wrFHc{BYR+(EXcamHfE$w2QwMmn82-F1^zafn?r?WW8$Oscwlddqs|lWk9yX z#_o>mx5VZq{U$ltERO@t$Mkw=QwkM5dY{QMByp$H{^^IEUiaux_ut?B^xH>2>m}Qv z{n7%!5{BR(`KP;+&t08DDwn+b%O%WEVhqwDLGBlSKI7zdC4F44DOhhR6`-0~K*FAM zzllaKDslPF!19GY8*L&6_~sVvWZty!*<_74&Fx32o{=am(yk!2@N$?<12+Ld>0n=Vs!? z-EDuI#OyQaCW#7tTnMQ}My)Hyxm;nji)rT~NB^nF|EbV9*K7UMN|HFKYV%<;Qsk`v zPEMDdlNkT+`2htn_0Xl)mlwGFQ>>H;d?NdecJRFHER5};J%T0?FLKPPOdW_U%#V@S zq;a24Ld4oUT`Eh@-b5h}_K8W4IRk&~i{;i18e=l=2`|MjC90K+#ksrFY7fnQ74Y774Unu1%VW8~9w!+@w@^{~y>pO;3IN zZn?b@{`vxcVF@9170JbDZMGNs%CyIwN4!c;yMoV#(q8OdGYSC-?t%|O$9?R$aTr#< zI?IZEVffPY-|cd=`8)tNFP^UwBdq8Pyd7tU0B{y$i@(K{LL?!xs>KxSFDddhgZ$@_ zi=C8~l%8dEaI?TN{9OP7`02&f*T_-;kXP>AzkdR?;Qsv{FAqo55m9GK-T?q2%Eolj z*C&F$s{H&PVNlBix%zF%tvY6HxsFCM9VBLM2bnNgn1H?>aPF;*E>91oJihWS(@IFY zR_0a&n$S|Ti<|3XbF5xQxYe>%o4UcW{S?=!gftO0QS~|xHgJMc&0KD2NQ@rQB7^}! zNRLziM7rN*5`g;z@}v-mS*c3f=uM*I|Q8%iZ}rFkm58kN$L6wvXlR$%B*={f!z z?lyTygs@4%;ptaFxrtNgsgl!q>PRt3P19^ar{tf;4O-}Jd>!)=BnTb_RAbgLHh8|^ zoY);k%VJy12EV&{I_OR8k0Nr$o0R7IhGt+H=coM(?7p~*Lm9({=H^4*wV#`~wZ1>j zVX`_N_pag+WJ~&Ih)bTd;?pn=fD)x1?260+HGV5@-ZWoHa4|TsDR>xa(|Eu2H)MavDN)H25g4}W&{QzfIBel&W~zH=PJ9M_AsLVL4LB;)c>7CXf;ln1CWDhC zgjy@S&p*Ju!5-Gq@i!C`I20P=xQE+~_=pTMu2dHU3BYEE3+l>6%W>1rSWVr)AzqGG ztPG<^Kg_OdV+%=d$_bt5IhqMJWFB(-2sgqASyTo-om=ffRn%o$jqb2n%3j*-CkeaTKjhI`P&yS-k>58?KD1zw7ygm2`%h8K45?#Z{O+& zNR~psvbI0 z*c5sF72ZMBUTEWvdhfE@HXHAO-w5LPCFATN`QQ>4WBP6@j|ZzP!*w7kZ7P*-E=DDY zXOrEalB3qD-!Ea0?ahVS1$ex(tUk_Gw zwF!^083fK37RA+aPLU9pWyF|a!m?s%0`d~5r?w0!KM}dBYW3tEc~5fFsec2|rI1K5 zIu$QubVOT1LUjIDZiqC0eZ(o{>&QP7z$TMa0;V%e;Ix>3CF>NmH_8dY-J?}*WPAf} zGg9HGOV9YJx~hCe;M-P`UuRu8q?$m3=umGWYm<)&2ZW3Ii-u9TdHSzBA1brXT+JOH zk@x*8p%BSAxam<*azL(d0QW+UfPe-@dLZ>Z4D8c{hfJWk`6=-YE+*5w2L~fW{GfJH zKn;CRd@q>EO{_u8^q``f;>$ps4Y{waf@Dg;A19;XF8{+|@dmm5#fW!j?5KeHX<5R3q3+Gi^J3hr0|S);*;{Zqe! z8gdwteyM89$q2f}MCe~)wQ9`mZASwQri>778?kkYY3a3IaIeEI>0nU5dULjX9JE=1 z?X*3wH1^wqgSH21$iViv1w#91J?KE_gHUK}3-Oz7R@(2Qnh6l_aHX{a6K=d}k>w5E zv9}@zUys(Je8l3$LYgD)3ahko#i=kEhUU$+_6K4md&0vUXh0b4xBG-Y!+uD^z%o;Y zWMA50tw=QEzVwqIW|)U6IHA)V(F{!sJyWxoq%(oG%W)We@lXzD3J*P^f@L+@ATnKX zwFSz^Y}%ew)k6B*dny-b@3`|0qXekfPNchSc~<<;Kyo|!Ws|E(@l+}?2xY~cyhO?p zr75?!)Vu@v!M~E&7@(cJm9G;7unESo9JjE1{a1cGFB5P2p0@nz-f8RVSc-lmNw?dG zsYzG9OQwI87NCqH#XZ>Fgl@S@^Y5^Kx&?wrYf;wL`z^GnqE$nW8;G$hS{9{hW>o0$ z(O;nOcF|G#Y7II12muBr`nuzj;xkEq+maj~a-*3kYKlP0TM4YV(!f=xa8r2Wkf`hT z!)KSpkB{W4EK6!LdxDxt43YdZEfX)&E8dj&l`>`FV9Ia-04WW0{n|nBh`^qU@DZWx zFzP&jVURgd5ndP~%XXt$Q3S(;s=H!z7=!oejCR_9Nn6!_kqolOpq)}pS6rjj*TUB6 z;{0X+bETBDpY-?eHx1t92&(N^VLAI|r#->Kpl`pEYhKHjCnH>!p>vBoxUoKUWWnei z`4QMBsSLIWyF|k6d5351^uS<@P4oM&TUODzvJy9sTjRk9ZIMeD*p}{vY{}CV;l<^C zxtyP5hm&6^*GSL{9h;AJ?pwGhiP?$F?gi1^l|sH8U?>sD&&1qRy3wyXYBMb4<*P>>;}**+IbHLOv? zAMg|nZQh6(sX* z&%o@!72(h*n#p0bn64t@b&D<1Ws810Y#3zVgoY7oX3AyD{E5 zg@$YtppCQO{E4?J$>X2r#B`u`36Ouv{fpcPMvp#R0%R`2ho1FOPwNl?{a1X{Su*CN zhuIh$s>@rOh(2-fZ$Kqri1i^Iek(F-+clRang@N zL4axOIJVM$d9{=6`Lsh9`%7jfhtUuIwAJV>@Y7lp(+U;x;<&MeKvKKpHc9C`9Cq2$ zL*#OSoap|l{fH|JSvuPIz-csFhd&yd2SOr!C!}gI>sutcYog+7@s=V>$8hm@Ji^70 zbc)ukT|W7vB`95dT!~BlXL36?zP_ z3nNYwXQ}WeV62I9Jc8DzI5h?Rl=hzv5dS~E()eK=R+^;VY5%rhrfCy7<>?SF;HbhC z;_8YIhR>o0Zv=OHF~et&mi~YC-n~Dn<5(O0pHDHy@|lrg1lUgA6U7D#kPRmo^pn8J zj)e6N(jX@2mKh05Y@g45o~JH-TfNqd1UT9IJ!Efd)>?h3uCA`CuBxt9C~5X@LZ`|U zFVhgMs;s_-jB8@R(+xvkEI~LuD_(eeha3`RwTH)hhv)lan%!pxIb+<)Vw<)?X}{35 zT9&}1sv5<~vY%y{Ez`e{Kg)iVB{oe35Ic#e7%ZWiAzki zNi+j_l=2_dK+B1o92C~bxz2)?b=^s>mX z_4O&mG<&=E4o95z7dJ~5?USQfa9Y^1k~=1LF$Iw? z9at;bY^uzZC=~CwFUK(_)G*2=)kgzziG5l|!i#sLc-ipNVrQ_ANthPLeXjSS~<9(My5bT7q zd(~Phc_s%KlvWlqvi{UjhA+j+(!O;am52j6;vfWwh&nQ%+T;|#%F<@pI74MGuy%xA zu>R7ZkrEU5+};kLm1{*pWA6rC-p+);lW`OrI$!PWePaw|-)z(ug-%4#c5JOdv5n>& zFE93g!Kq}d_r|b7YH9j~MRW?(_5QVtjS7dLfqFO}k zE5+)P@o8Qw;^y6nPY3-6z|) z1v=t@tr!;t@P;JFMchR?QsALESVKtR*YFIu*8C!nCeR2r#7w2JnN`Rd%DJzM<{)%* z7Yi}qt#p|B%;SHrrl`gQtvgSV4q}G%TW3KW6-sSaz+3Iop3b-iPgg66Y`HFVRerBW zW%YI@Uy4i_D{nyX(VwU}uc@iRhrI{>g#&nRj~VEYyqN~2A$!e4ci9U);!a7CRz5j7 zdkEv&+2rM6boXj@N`5#i3C`(Gp;Haw(mP@y(m!z>w zf{u74?x#QDs6gW=vR`Y;qsiamVHKC+t}gpq+=Cm>8vl9&r;R_Q6PF#8<4dDL zV5-n1q)rJP$Wt~!I^ICn=?16xBvV&5BR%Fy(KN$D2S`5r%fKOZ)6OIEc&1%J50vCb z+wFBbErrAMCg}tB3eIt$a_w}Ig3i;%ILyBS*N_=Zirz(Nf&x(qYow1~$%WPME$WTZ z*p)7YLe&A_>y0;GvVzl~c{&-m!%=JX4vcG}OI&3T_@-}_tiy%rpwbfiO{OxiQx4z# zyW~AaR%0w^D7IUg+8668qTyT+6$;YtYRkzeO*N!GcUoc+uhD||;4Cwa z6iP?kfg_qOOAOI9oq`@nKnP1%QNq8v$m<3!QqYUWR}y#vQ!(8y85zo7WMmli4C3#c zq=-uxH0Ze|s;IP@*OtyHCMe*^sRXFYlE%Dd1@|PB+5q@=7hrLZ9Hx06B9nD0^atE=L=;v-G8dPlL4u&dNv4e3c8?Ek;R!3fwtu#poJ z-WPxNljLwWXCDch1)QL_lXK)!{Xj$og8=VJn%w{o5;yJ2KQO2}Nd59ne+9G)7bK1^ zW|IrWzzesb#1|?EMVl8a3EZ@)a|$h%&s*9?Vk#+Wp?;x@?Y@8jFE~QmB`pb$ssHh- zK0VZ*M3)Fa(GR=(V+Fa^ba_aiaTP~$H~<_26Z2*qGA9da^nd{5tWN~_Pe`WcH|jN& z?j)M$tD9fx!CMW}=e@!j%%ee!OPc3E7+*mL!(op6a9j?2T^Oj3S%}#m+GfeWLm5m4 zQ=gr)i9}&ayI%N%ks#Bo%)kb_=nX~M#?eJ>`PdSw(gAS@Km!^l0rGGEx&MM)jt>aT zNBk)#nHcu9A)M=nk_tSAYc4F=HPeVMt`4#N zJ2+godkW9mH@9xygnD~r|AfjgKi%iqsuqbIdasBl(2esqOiwf|g*Ita!b34qcmzfV z*f7Fc)_*R3e|e5P1-g}T5%J?TMfhV_MK&-JQCE9zs!BkKs=Hy25OvISpL5^mmw-~6>4>2o6NAG{ipSZ361jZ_rg4^1pd zt0WhF6fBWIfE&MPO}}g-4CrP5IS%sP0%R&?j{STiYk(-VWEhm{kV?qdgA;|(~$oOl}tgb8t0RoUR0~avE z;=y0QdqhJs&%!=Iq~X@qqaN=4iviH|3mrk)q8(%>5gKS9&t7<<2W}^MY``tMfkY09 zJv~^KRn>%sv{5Lb1`JYSFt?$-?%FzAnnO^2Tkpw6MM*;Jau^v+ZpIyiBuI|B6Epa* z5ybv!byar7zS%(=M9AFT02745Qcj~eh>JE*oe(!0HjJP_s{sxXmOTs4JR+GM`67o4 z(TL?fL!t@4x_N6=gAlPFS@l@rrE=h;!)#wd8cg6G-X5L9=Qu^W&L;@ILf)HVo>EHg zLYD4e{G_-Nu=wB7TP6(Y*2f6BM~_a=?(yER?<|e3nR_}QOd36W*8mr0kpF^o_LYHn z0kL=?)Dfx-Plao|CX=!2r8^!`6Ln#FVMo|DjCupjRUW8RR+gnFUlu7epNf2rzVvMW zieDlKDl<_|PX;`_VuUG?FZPc}WxwBSNyjx}T6_v=>mx5tN|6TIRMVYz(#}* z8xbxz5f0NF0#6#%ZAAZT@$cU@PQAAA5P1r?86N-q3j7(kS?R?T^x#5~`pC}7y>s$Q zjym$p|GOUUh9f4Jh+qN+hO2pat4mMPR?SY(!sx8`?&KWI3|En}0H3N01Zx7J1UOq~ zVj}?i^$i^aNj_sH@3Txp>nSSM=K)9zje3W?)pXj6O?-%zYJ{?N?gqVelC)KmZejT8sq%*_;pvIGS)Tzj!^cYy^Lt$mG5nVahRo zZ$}_4q-%jd`fLUrfXl77e?s~=;!pBFo*fD^dOaE6c3(&nnr!wG+U6KK=oQ=VMgq99 zKYlsF`M%YRDDo4A6;&ZYo$M}qwrVv7DPSMi*3IV?1551Mclt=rr4WT@3d_h>lm%$) zU*sp&2O7;7g=%=B8c5Pj9N2*w)%gg7Ny>Hf@;VwiC&!x2l=~BiAPqs2oL{(O3^R9n zNTVS18whxX;d<{2fEh%(go=T<^k6{RiEvCgPT<@wObePGV2Ll=5VXJIj6vGerc4}9 z55%TyGSL(y96tZQsLEBk^`;5smR7eVL>~rwX zdmGz*dBwdQGDlC2Xf1k=1sAIl}?8NRi7b|v4E}K zUEKz{*;AX&UAZ|JWj$)jdgQ=NJcAfkXY9t1j?#^ zpx}@4RqL=v{__4ZUHxl`U%LJ0-scFR{O0O0OdeMyF$rsc$4VGcy0NstqFdspAsOiZ zK2mfYP=p9j;G!8rUtEPzrzLN(hH9rS`iRYJ;Aplf1-Xxo(%F;E&}6m^iJE+aWi%DB zK@+UuPNZplE}-$Hk#9Eb;OHH7wq#gY5Cf>w3=ziT+arP$K#+lS{ZWI13d+c-B5dPD z@2f{N;w=Cry+l7VBGVWO6jTFS!v9f`Lhe>qTnB!W#ow4sW`PxTDZEWbZ%e%8K{3E! zaK)0j1iGkr5mjUUB$O|8dUpZ0tyKS>uS(fXGy-SlhGrC0^?~>eNR5X<;Z7S%@J2#$ zM3jGO8(|mr@=*sQZugU*4R2px!sT>ys{U1*mpTn`-W<2WFmh{Ty;28fc?utFt305C z_V<XF>-MgHq|%eoc+LwZy1x?+p$f@i;*Q}v=}>S~9Gx^^^jq-R6@jq5*; z_mE+s%sMJXV!p}ZfRUdGqKD@D$r&Gu66K~TKj6e;Aw>m0B?5rYjCogl0R@Q*%-IM%;QV=ES5+%6h{-W43k&i`8uC7jIa+p*SLPup+ zbs=S});mR;z7SYk4&8TVzljt z)(N@p2z$>qAC+!Ic$g-~a3M@^z!+V#$gDSeC0WYFn>6Y%E*3V$qZe?s>1E|taRXj| z1^0O3&og)l6=rbDZ^u7FgF77aEX?W`U)(@STV4X$`v+W{8KFV8On@)(0-WQyetsy)SHK53L|GC*g7Y(ep@7Wb|hA=-~j11YSs*QHz@Zm0=dW zwyj7xHP(IUtKB#F261W3L_Zt?Dp_Dqfy1?fIc3v#pe`saU`9ENi&PAM?k}=UIl`^+ z_uvjB;bV*;(gqjMa~+25uR9hE5=N2WzMiuoO2tb!*(V?aBa!cV3Ax--d5$|_)u@7n zUI>ZRRosFzI>qS$c1g0uN;b431?&0oJ-zZ+g7{N-G5A2P;kP4|j0@2Yypk+l2A7+( zlSn7?o=3yA!Je<-kY+z!x_%V^2%UYKL*;1n4sOvNa1Z?!fe8b&RHWO-RHXK4m?Fi! z0i5H^HaQv5_$G3)l5EHbZM2v86A6YewK|(?U+(PTQs z5`nk3`^sw0VaF8v^yoCd|2&8L2*B%7Sr#cn*q}Ya=I(Tz8><@@heJ#@8 z*8IIopEq4Z=t)n{jPNP=8XBK@@l z^5_Hk6cr+?LN=7kyq(W`*9JRV*OtXQpq0==^bZ&ca^;Oi;o@N#hsl4g^Z-BL@2hTO3axMs=sOv2yaV8T)T~SkF!4pq#)&Kbx(B6$=LB zWLTE~jMiAn!M1f7n&$e1D)m-bax~0?w7pCGG#0>62(WoqcvUy>V#&@|`K5orNUByL z|Bm*3(B5>X<*|j;WJBT&*TY+2IjSCigZr${=183saR8~EKT#TEOrpTU)G~gG18al+ zxBZn&SGt}T_&Wke2mNPH?`f((AA4$OWV^`hCHj0G?LtXc(Zf3_oD9w8P2__+*c0RF zf9heO7{#Jf&0TXc96kd7!8qu{3{oN!J|u1=ad-(@V8u?+6D5SsK6)t^P(=cX6hYfT zgy45mehkvtT85s7QzZoGh6t4dGSK z%pffn#<|u=1itf~+2UDRy<}csreJ(SEKR$!kmhr8(@;P#yB+cYA=ScH;yQN39bl#Yi#OBTD z%ZroZ{I^VCZl=yYMN#=tY@w+z{dDjX1O@i|zpB@qsbGME6I>uWUcU3~uQzVs#muwa#wXyTwej$X$1GmRVSJiDj>F^wYY*6nLg6m*7-Mv(o8@harcFf;h(_Ys^4^ zin53MUBw}eh!fr<{!*bu**@Gqq*)J}h#H$$)uMUqWT^Q zuyCxLV+@Jczk0-wQ7RZ8yQwM`M1RW&V&McKUP|^dd5m!+!iwo?dXtSb!F_BNE*6zF*`0W3B`qlEz zi>k`HVXPj!R|M5~iaQU?DMe@{gi7-Aj&0^K=|fw(*~OHLktRK70l$-S{WNbfqURVU_20#>uR7l+1UflcbV&Ahfspdi-wJ zZf@_--W(5AXHL$?bNgLlRrE}ITOpRgi<1*<(;L;0^{Lu}SZF#CY~)%Qc0tG@dDS*t z0=?bOTXCW?tAQT&tW+HrojfzU!aYIkmbA$ zTUS|?Vi3h?A`!;mH5%axS(tKySSpl;f}^3fe45rnb-* z(aLj9$W&<7XTV-Z>*NE}(p)_ZGtp6}uJKw6=C_Q;0zi?V@KVt=6yXDG$GFG=ne^W` zWvBrV^airhf^PzyH6=4q4Mk&(nj(ls2~sIOeo)#DVOd;T^!uQEN^^c;ZmfqWo`2vJ zl%8m|qCs9|Vf$#R>S#hQO5E&o;rRblQT*j6O>_P2&i=LKJ2%wq8$kp+QloutgK=Z8 zvL>>74mO(ZG5k02jTnVJd;^K;wRG$ROF+xh)C1bDWa(t36=oMqT!pAsIx~WQ1cb%_ zm&i_?Pap@5yW}uo>=y_W>}5W#XwM`>F<7SM7-$T9YbLGq)C4~ud_Z!O89Va9w9Red zrt2JljG)uC*oi3;T@_U_R{>4YiKLtXT9U>@wD~V^(r_HS7kp?sk9exGcTWx??Dyz% zTztv3H9vLR2+8}Ro=0I~CU{-9rMMQsEfdj6QONW&9AYoYOO|Vtl}mQ(z*eHizhJg6 zO>sOHOINloYN112=K7%-12a=!*vjX3#3!~h`&?OJg8+#bQ-7V`NsMCljw#L1NAPTF z(%luP)gcz+6RB0!dBZflD;L#%CPUH*!`8>EXN&PW(ibCX54ijBIHbE?-R%`YMr}C1#*RZo-;nXEE|a9Jr_9 z{BU1j#Q_cLgV!H6PiVMaY3nFmNr5y=^>v9vg+N;%89VO@5uO;FOc@SkxEhiH>$QbJ zW_(Mmgl0%UAH-u*y9urg>EV!t4KkrjubN{9B}#)+YN!Y6)qiE71*}qDw^DU8JIWxz zA<|8y=-tEu*$RqoA+5toBMnb^d(n!auwx+4Xo~djO;mQdnOi^zZphebXt(72@0V5Y_l52TEt+Qa4`+aHzwLU)uHg6B8GYOsGp0}0(h}NR{&Iy zhBheH3N5(O+u}!L9kMU|u>!pv6zB+*K2%6LM z9fiMcE`x4klP6jL(KbhyKwGEC|2LUQ3 znDWz;$0s)0x#uUtvg|rVsfEJCrE}`*Po}eB1_F;#dv=K#TQc+KUTmK4twz>P$Y1XP zVgFfbWIs}C9pb1mcz>s=8p?P!R>FR;ofR z=F40dB^#qa48BiDDfeu0iY)^Z=ObDlsR@2z0-oQl_8Fhr!ayJn^h=Z;p^J+DBubA= zrDJ7nX8Wc%^21Kis6H!AO{4`qqF@0h#cnHZH%sXXlvY%@*h0hC`-*1?N>?vhk)HA8 zKhM`|Vo_|2iq4>WWZqci9$F&IVU0}Sf$RQGhEgtNtTS2)%phXn^e!MVFLgLijlb`22+s{@=hTUsUzfCc{*8?db}0M~iO z%)9{{1P_}cbsY)U#>=;y0sgIEKfJCBk0@bU@a-EL!MQ)Acwa(P)@$gLlG%5$+3;pQ z?2Krugp=&8B?&-tUgC*BnH_B|@S4k(Q-{C<=0^-+`!{b*6OhmMhyQ6iVPD8e=G5i1m({fNHKH6DHGLp7~ zlHi-Q?IIy<9P5GOR4$^$q>6Ge|E%P?C5OXcTYNV2T{fwvYU10qXAq*9zBzsu zSJ8z-3j7eJtvLbZSzx@L1Dj*1%4#fX2iughrIDhFKBSrSt7y_!Mhr5=?LOGNA~#mF z{az&LIFOxLxI#kh>@7F2K6-FZx3NviGntyiFDYTHwrDKB+6?m>{=J+Wj}BqBcyX9s zIJmnD;}*txzIQed`9)j1Lv+12_Zq^DT%ijdMiMqGB-eW-{@H#Gq!p!yfU74?Mq$j0 zaM?jAWf_gv^B72@g0f@ND3k*wNU+YrPAyC$`spYZd&$d%b|!MnkMnFjtCf+Z^;h^{ zGtDpl6A`~PzM+S|t-T7Ko4B`z%30#!AMgnUMDYVcDv77dK9AYVF8|Bp*TL2A%{|Q+ zynfASOLO~0DH`44M)1Itt)<|m;@%cMIV3xATAP#6)Oe%b{;WZ(=_`HH+26fzsXJLO zaN_J%g?>3j;sK9!v``>8ObA-JZozqlq7X(IJRqUB55>>{m}C;o_;A;erY=`QNC3N- z&p{Ho7rf4$o7rns`Qz*dr7J6y+k>)CVaJB`7B%_`^%staOsV>5ZsuJ{<*|I@&i`2# zIAr=HuXDKE1rAB-Zt~gtyg;(W^r34=_>G_7^vG};8p3al8?^}+4NsW6G>uc29(C{C z`Bs!#YggDnlqzuV@1Nkf00RU@r>El)ZX7&ee#8;3A)F#_=>+1L&8x@$I#ZYyQ3ky5 zgZe7R#CU>{WSR^(O=@fAQx^o8wUA<@7zHj>&a#V_Tq>*I#&>|?XCM7!$?s-uB&Q{& z0{OV)fHj*pkp!gkLX?Fr9r^$7n`q+geHg%Ox;Ot43McgU=MEBWhKMuW;R&C}&iTPE zIih{Td%UoX)+-`M3Y)?e=P7fNZaXct&dC<1+V{bJxU@oU+=^5qq>-w^5(Hhg60~})+8M=9$g>*&$;R%SGc(yqwZ#;6}OLKz?-u#WEpIb83p{K z9)23AEh5RLz4dx>ddjDg_(iIWGwsAyD2&mN zGiap>6mqov)h-GszfYK%{s<|nX1&lxte#%acTp3ggQx(;Hn)(d8NlF@gT3)7Z*~tb z#+>Ka3SXkTY@d4(Yi0zF7l`oxb(0&0Ul<`bH0E^&#KigbzZ*<+U)~?$Wgj63c|6?_ z{Oj+QMy=qFynX;d^v4GaSF!63tjB=g?tZkpwvn#C0cjwd^psiY0ewGgC^JuMP$N+y85+XQ#wJjx3CescEU{Dm$erqDv2VbGf9Rt+3DYhZ4* zSo+n$qP;yhsC0%+tK6U7Had^H<;Xl|Qg;nc=oCP_(&PDt?n*fL5z5o^W3yu$-AHYv z!MkCoCh=mH?I>(oQBpwQQ0yJu2k8=pDu)Wt-EpfW@&<~2DtewRDl}CJQ>w61WKT?v zETO-`huAAW#wU@ErJWk4iOsN>D!DJ_R7a$ca6NLe`{fef?CsF&x@hlo&k&j{@SN{BXZ!0mKW;R#Vwhe|%oZIsHF&FU) znSyM*fkz6`7gjOR!kmz^_O)kqp~-$j31fJ>;dJv4|K4y7wTY3(U25x9Js+htfCWUm}eT>|CN z46l1QX*b#@Fnek0n%>FF-q&;|-DV85&vJ^un7E0Yj;7_WZ%BpS;A=F+eU#Ld-sP*m zU4|GHvamH%McERdBOQgKEfJ@$junF)(@Crx{gcMUJrdz3$hjF{H6a zYWw_ zo$~n8%JBJ}{qdV6z4wsRlyxByp82b?*P_M2PiSuV>$W$%+|qK^49VBRzq0PLLVBh+ zjPZle1c{e-p@mjq)rr1AiH+^qBuTk;=vWcQh%>I!Nn!IB;6vozn$k=lYYb2VS{SJa zZzmjPn6lMB+TS;`fwMi8hQr(Z>+dj&8yY|4!pBGff6|30Jgn^^yZJ+!!&CYz$lV1r z!s3OLbl};QaFaW|ez}t6n2wzE?nA(p7uzjU#I*CK5GjaxX7Z$heMjz0UMqWh;-E!J zMWsz7l`3lgMqy3ffhzN{>=fnh1=uT&!ahf1Rw$R#Cr5h^%j zzV21hXtN8-hP$$<2;3HTK)e~kRDpCMp3F0yJjv(z)iP6E_y45-hNz(xjAv?#vS>1< zB*0nw$Qn?5OT=CI2^3R`l%177{qnzlTb3(f`zt?FN~K`xdYsREB0p_TMU$)cpM#}4 zD>Y5=zNs#%ye-HxF*Q~_E{2>1C#_>FGLUSWk}$-o?N~COr8OjY?XRl7L2Ksh#K@Qy zTe3?62Mt>jv23C~@ZHh6%*NhpWLhM8WHKtE$HvIdooBscfjb2U^V49e;JX;~AD{H(CgxmeinBz0YIKZ?YlUg? zMr5jM&CZ3T!xkvDA8rw-VL+Xh+L61|KX ziOfjW+U(>UHyY*b`MaXU%1Kkva@^lf@Z^Q(M-M@+GKDx=cvogA$aSD43p%zLGi7>1 z{AtOKsHmNAiN-?2G&Wqttx!GXp4U31ZTKQE#fldM=Y1WVwwQLfEj}DGua%H<;ga)G zKQ7{`JUqwENjn?zC-DeIkDZ_Fi7U0kZ3m`;B(fWi)}DU%Wb=pJjkSA!S^Iu{cXR#w z^}m6z`p9v7XZ7^eDgHbB<5zGGE#LX|)vGs0zv2aa>AxOMUMvqa3V=ILEQQL#Ol_2y zIY|6A(`EGRp>tZ=4JArtlGX;{`s1^+clH6r3RJAFZajMS{lmw*Ya0)De_Y?(didlq z1h-KR7mNLDP%d+)B~63nhEOT(W9@WeU={N@2W#+6&R zjvPwOc_WWlqjTWmAR56w<-ykf_u3FATUS1p$nE~pEg&xekyCN02?U2(0`<1d8a~aL zC6uVo3xi1}2!5V&VsUj)%bcJ-XMr4@<9Yb_>F(CUzpsm;{(pcJsmf z<5vp-+8gLH?g03YUjbxdP87)fbq|@L7aAgKS6|~Y1`DNus(>M0VF1n;HQn|rj`Itn78eGJX_QqPm7##r7}HHIOgRlkq8^ah+X(_+Kz4*c=mj?Q zULRo`hy7LXaQwAN2F>tk*HA8Vo-t+=NXu{ctt2m3w1nnY_N4U*i1H1aFY7sqgFaZqqg}lBChUrXMmI$Miz@_60&2Dj z(druMgL@rvey*In*u}z|%7uusG^8&5)Gtp2MIreLN|FJ{mO~ajpgPzUkh?n#1z8%JbaA+d{;m75nDh|>fH_;!#}M+O7Y6ye?7kg zX~jJIL4AhPhXGh5K!^mUY7KeB>8Y|fb1AdUBeLrdU&=IU{#?g2XKL%w)7GiN8W^1)o~=TbILq&SA)-i?{Y$dSMftP$X~J*v!j@0T zF8iRxp)tH}cFBUb;dp9jbve64u_;ri0gpAk4xjM_0-2IC@QDWxe*D3wPI-hOsazjv z!ApyqMRC|z)j0{a>3S)Q80#e`8Y&C-CT-KkZ)8SBy!e%&iv6-keZ~l3&(gup)1lak z%oygZv7c=b(AXCl*XUEo(z%_vihEqMbQHU8bMbrvRMPlQ1D--8aXcGd*)di>e$;s6 zEFRT&#`d?^@A^=5kAz#tlK~_!#6Frk>ME--{9eJr63C^pohcCnDByVQ<$bp`b0kEZY;A9KK$p#+6B0^C$^ zF~h;$JtTzx=lOX04ponkG7vbpDT~fj%KA!Mj6#Fz*%*GU=X}`S{eq*m;tLEKku5MR z*g^pbxN3^=d&p{x?Y3e&_P2it%BOZA3oRbh)3E~->eEx3HN?zMtrTH_g#rKAg>2G7goUJz;Tg4|A7GO2|$n_wUfIN^;W6e^Jy zrfjVtF(t}_B^D9GVW-{1Psu@*;a|d!AdC>glQu@ll^+zg8eYWWk{ltclmWUf0Y+6F zdn6J13!IZOl5g>M*w-+-EydOjCqXl5De~h2o)cVlJwC>DV0$=vhg(Ll3)tDf^{+*X zU8z^@EqWz&=NT)>j#cIcDxgpkzIl1%xDeFRd@9TjG#yh#_k(m&v?y7eHfkOZBc-WC zQAK(@jnvcOI*N{-aE>H-bs|0tK%KmU=`DMW|6Gch8EZ zRc@DWso_pf-oV{DrF=0_l|YD}`n9ZiIQrMSP__K%wI0Eliy*%YJpY!-GraViWa0bW zch4p~bQV;hq>$Lt^VI%Kwj&FJ8Os%WT-VYPu~gh&6dj{*iZeK1SF-w zKVnBgVVG9WP9P}9xI<37hLBEiqo5e#PSMnX$FM5FswR5`7ubA9?kigmwxLV9{Op@B zQioyZ?W>WuJR6W=sD=(0VJnv)WG$qdG2d`17-o+vAP8m^SrUX1VDmcNfGF@{hbi}e zb1=nTm{Z~Zt8LzsY3#C539r2bX*AkY)~zP+mRZ!pC(#sV;}$uYQ3&c+1B@c30@6B3 z3X8?@ndx}{v*{_h8__8XvOVIioyue;oRoF9Y)_HeN;-rZ3N)AOE;Hr0F+kUDlK~}~ z#iNsh$zBq@+SD9iL)R+?Uya_#RerW**c%;7szJ&FNiDNyaeci*sKyLv^?_-o!IFiD zeFCQ%EsWKNd1?W1*??roSajv6YZgh+vf4s*^aPKBU~4?ZIIoc>NBy%enwNS+hvQ!v0UL&JDHs+drWmk zw5JhX&o&?JK6tYA6iO)${NOc&?muQoI1|_!7pOb^6?&ksB^va9 z1&TyXlA9l}^}q!Vvf&W4E#p)ZkJc?Nfrw3)Jjs?u`^Wg?yDT#w8qL}YryeJkb4*f9 z*IbDUK|mq0YjmglxTMgM>ct&p?7xFFg=Z%hoVy&fU9}7-()WgmX8Q`Nh~G-uS1^+a zEqC*5J6wAkCNw7k2WR$-r;3B9l+sLE7$ES14!1632wk@=gvkJ0LFt&^PNsbbHbRTS zMt%F{Z?E^hxZWH7K?m=|?jMb#20KKEV$m(cISvu3f)S2(JW+$rqSk9;gtBrO)DQTycm~A5x4{zdj%#zcp=oVT=0;KUZWNf zz8p2MV(hQ5Q-TKclE}Y|-=P&V&S|J%!VtqO8FN!DdSQqw2=_r06rT?l)}L3SFaGdH zu`e{osT0`$EE#S8Ga~0RZj|(^5FUol*YS8;Hl7>>egB3KE^Y&D2Pg&z{0G~91msau zfJ6=Pma{D|^c3ZjFkoP#aY&(=pmo%3+Tsu`-p(4jM`MB<_)s!ZB+0K$JCuT_}%^S9+j885#B|ZG+_yM5)h` zz$Z;OLO~|Dy^1)FdP^!QLnqsPhZ<*8$wX}{BG-9Ep6hSZBIKVsZFPnwjCtD|ggqFc zkk57gx@Ozq?y6Z1wcb@Ha!iX7ypEw6a(y z5|U9AZEgGFbBZxghPb`A=*Y;hoX${bQ4EI)BzFAI9mv8rM9ebp>4wVlwLK=?9KFD{ zjSR}|R7S=jBhdByaMbE5wvn^(7Aj5-k-9UOy^BNsAEg?mN|q(h3h>=5@<~Z`%%W#)&)6)tQ7-4U`r-R^nRh( zh)-Rv(%y!05S(PxACR$G{q4Tg&9d>dlmSQdh4#M7EO0-BKr)O z&zf7@1&^cBkCYQGjTe0L-Sp&0ZEIpzi<(BLQtaq#ou-F1l~oj+Hq2U+(~|WjCx{X8 zucCxz`KFOD>B&eU1la_BPp6Gr9+UD;I-Gq2QoM>CCV`|1_mxeI*Q`FapOj76Co~sp zXCzml^k`x!zJvwxNtcTo>))=J62FWaN3;_t)RGb958^*hOv4u7pBRV#>*Tz5bPnV0 z_?Qw|tiI+*kH_4gto7dEh<*=;Iafel%!9}=<2{H25eGP(s3{Dvc?clL463#B+4K-j zhSIT~mP}a!6?Csb9r)~(d6w15PHehirB)PzTsJrxJzzy5KLK`})pBQ0`_8O-H;h_m zVYdWp?|#PV6W!lhLEm{bAVG#!Bt4X%p5Y4~sLEBd5bhJqTPj7=5_aeqY~z9aw5l^nrZXaqqRRQvlg6%+Q}k2 zI;AqHs5;W9AZtD{zT&Iww6v@nv>Zx(yDizKL1+b_lIFrfjHFEex!5+%62J;#yKb~X zx{_Pbr^wsKB4vN^E0hzCE~Nu+4mqjk!Gyfi-5_}z9|j_ZTs2`z0u@KbJ>T8w`Rkwe_N@ z5N#t0s50k9xSc3yfpMc&X1Mdqe&G=c0c6m>LU|PlDQPO2BAgBS44K*fy0)rQhsnR6w8^T%F=8v*w6^2x?1fgO)U zK|GO0WZ>QQO~4vlHez>%s-`(ue;I^p1vQTe&c`x$2Sbz~=FDhS%#eeNw%cH~-wpoBQ99wbLCsd19iEZ7+0ku?x)yLf3mV1|RG6b+|b#Dt-@Lz6Ygm45hG zH(^oT2H++PGQHN4YD{WuE3C9uj$ z_Fds?1KvJ_yEA8nwCL zeNJRmIAj{OvHFwoAA6*yy%O_qPzatJP~%e~WVo8n7aZ@*i*UJ!oEdMuYZTN;v|tCTcP{ z1vgk`ssvG42DuSPNM6Msx#HnyCTGhvxr1ni*-Xg>6`Nn07*d5;$*K7@F8i>x6+-oq z$M0O7Sx;!x-)X& z<~T4Pmo&#fl%la@D@Bp30M8AA@m5i#T=(cSB+CePB)gBH)6#VB3#Xz^q#`Q*_*wR^^0T_IX`REv0;}BO+4v!}L zycB12b_Rit3e$JJ>G?75{`{G4P*mB2l7wPEyttX58-g3UkkaO<#6hB{Lk|VLNa;6)m~|! z=;#pdphG=MFhhZVCWrLjL5m0#_%%ET@uK6hTcXiAtLE?VaR7t$ z+D{}v7vri_&w9UT7Jv%EHDMx)&fu|CNK2q*t*tX9;a`n?5evxt5raI>t+FO-k-x)ulz+>+2`Ld#f`BN zW(dKa*FCTd_J20n6kfv}tLcYfzMoe|9Sm{H4iYKK1%{Me>j{liH9gOwq zwtPD{vnLijv`=5lr$hVnH9uj?pannqhN8z0T!cRPE^eoN5@nBwhlgk5BjTTY-yLxJ zmS->M3KDy=fX|3}WSE7VgNAB#trV7GbJ%9V$>a-*ac2SWf|1($^95n1gZ?`hs$njc zrU~aZPD^u3H3C>ykf|{|U4iq$R{B07M3X)YJ82s-Dpm(vFApbsXR|))dmSPWAX;=u z4NBY3o4T)DSE9VEPJ)`GC?Nct$4Ow&ip}3+qVFj*3?_la8FL|y2CNcQt+U+tCN>td z>}WC=IK0n&SOqa|697f0pyD|V>JcWu7;?9Uf_~j8(*8=KRk+ldgc9HH;cCI-@gYNx zFor%q=mZ!y@(*}x!pB;8eNb(oK@@x1f$y#y^zfS5I!_^dR_NwG9-mdak3;5uC`lZv zz#wL!3JkOUU8cR08Jg3kXG}U?MOC%oe#BEqyjel>yt<}}A(!bVN;1hbi7uswki_zo zv+ziggRqXSr%NIh(AP=J`XZV5E20V~>V=Cu`&n~53_oU;P%FXLN7 z;S(3a>Bn}KsO;%>UuUFKiR>SYiR?{bf;<7Dp#zxmaW!{&UwPxzPM?OCC+|ebIZKUnK|39^!uFfe3`3GVkh{_d)A{{8cX(c#GAO_&te#7P>tk#WzS(wuU-;lc>T4 z8dXCfzzJ`{awCx8t?+~e=$v%DB#@X4ae_y@+4)doFI0ne1$dGqNy&!^Id0NoIn|8uuyFO|)O~_Qup-z~h*~%b5 zeS8Sh?1ZG#?f6XuN5+JuD!opatoz!Mx0=X4G~TW)#F~*{2}Fabq7@?_(I~5IH#P?N zoiF}Al059HlH8Kg1~((@mz_jX*>}poMaj>RO#D+!|)<^)*_-DpTNiho!CZBEO0Uc zUIZGHkrOCx(DK48oiwTkW~5asv4Jq~CSofzunmDJ`|0X{v|(wCYcxuD>&7xYH%V)e zW<{8ZQ_x5)q`J7yC?xMfWu6%XOCwi79SW~o0wqE(B^-g+xw10w{lCA|OF2TBFP_Wo95<0mxmos0kSIK` zUiHhavR~z8zY1j`Qw@O*y6{uiaOC*6ntOr7275Eb*qE98A^xoPC(2P0GukcSMN5%1 zo8NDS??N$G-rFi~DobgSr&%O1$J==zAD(;G-8$c}lV|36wneac3e~K#;e1P)lAq-` z|Jt|dJyMHr4TPW$N%D5tK$>O?V0<1*%QnpRkI{I==B|Bp)LSFem5K&VM@>@>YL!!n zFKg(}63w=xt9A3WC5~0g*(T11kEbDL>|Ge}j0p4#$TQF}v<4Q2$r{U`#A-UprGpus zmX|WOU?K3;uCAtq<(uiMXSZ%@ADClWo&qQ{d{Kaqyb^6eD-G zpa)r6gDd^b^{uD3R=yPBpEV1kg?{^@;~Qd*DO*x-LcN>GHyhb?HGBDFlxXC5B)N*X ztZ;u4sa@p-ZP*y|-;QuzMglOe-Y^Yx1?8>+Cx}1I46Zzk42Sh{ZwUpEUr&~?m)SZ$ zI>Hq;Xul{n(+@zgwI)-fwKt-HI{chU}eWu-7>_PT#gHWExs{6>}2ocaK`I!b!MV;VnYfww7y@}@bGf(6_1qp)ot{%@;;TWX~asxj>6kI0!$tBLeL?0I5_P1x) zU47I4#Z`gd`p>UoTFy`mG>f!mq~tiv;ce*#H0-?@)!Kd_)(aLEn;T_R;byy3mxcYt zXOpkvQjV?hD23_=VXjS2xvaDi=A~j}LoJx4#*h$CqBt1UaQ2e7@Ur2ixAYAHbEfGH zTuEUZPx0GUlechHjWH=f1EKO&T$PiFoCLf`%mfQh1`dg`00Xa*?(yW^3a?fsowS_H zzK%H8R``xZGNf1$gMps|cI;CL6w8$FNQAPXOTcBhQrHyQ$t!-=-^IK`CiP_fH9w`}D8VOU_T6fdvw^BKs zlMk?7?}sZDqE7>?Ht6zXY01KZ-N<~<>B~q1$=ht+OuZ>5E?b1`3X3Rq!H3v1o{}b$ zCB}NBRt424J+{J6@hQ-G(z29@9fcxEcPx@T3Ne?1x$tVJH4yMynfi1TAe~C}4duQI zuB1u>Pl3xy&x%^w3*KW(Ng62j8r0Y~=kGWIHNw~tE&!oo1hHNYA|t6qwi(VD^OiB; z5<{#AjjIIq7$^fw8lj7qgDOFw#x+KN=Xf64=Ls67)oGEECiwoUYZ?QX2y`^(z*nD2*=zk4!g(h<~B%(_8MH8D=8 z7!(ctNa{`s3DYLVX=lN#CR5QmJI*n}+~jR1-HRYeo)_C$D7ja$kjgBKEfRFr3GSrd z!{F>)gZRs`$0!?>!1gwoZL-u+I)Q+SoT`DHW%tQW0t?pT8G+Hn6`#SbTO6)@R77Ax zzW769@8VuR4vrKsy!}QXbnd*ya8p3Z{8!TnEDiq}56T+*Ae#hG+&z|3S?qIDB+u}+ zN0*prVR4C9v1jQrZxUmdz&I;mz?;Y0K@C(I^k~2x@D*MJL~BT-mO{A!YxloAy311DmHk-%j&6IynPd^Qopokw#c+mkZgR&^00b(R}``g-ephi*E5l z*!GW@Ht_5fjDT_(nIES@%?MI)w$IyAL$%+-pvH5M9naD&YB29V#StbkmK$5eX}O+f zU?H5necX>nt2v1C^yIj_M8m;d5LOu~QRy->< z1l2fr_+onUdVIXn8~Al=0H0IBGm*Xj{n_k)FVh(zh{I^GpLKN_BjNL9cl#OF^m{FF zS7*rk9}ZQUw31~}GY*)KuhShF)@&3Ts@QP>cNu;EV~qnFwxtW3S)Cojl8-lRZMf}h zR%zQ`Vs1CUBFGkRoQB=w1$K_s0AN~p(^!ZGRE=sYnoI2iyvHz8UX49Bc1UI(u+Of9 zxRoPdB;ZgeUBUu#d%y)ZmQhC3@ZZ)OCnHC^%+MRQWh}YbvF>_M=jOn^5CZA5EQaP?4$Q(N0%TQ|`m>rjfaAfmSMZJj-_g z9E9aN^~_Z5R0Ji<6{L?#OoiswwZy085;q7x#QxONLMQ?+yGeCrDKb`@w6Jx7I^D9? zK^ggYmW4Pxp-58(BC*KN%oY!SJ=F)<<%c(>tl=7mWggD@>gHEb8H@E)SVLg{4!!u| zGaAiwwV*%Oc;kgo_$EdZCL2qY>kwVZ$`4Zl8?c+^#rSjf>LLpT$^+sxpgFnoo=Vip znV#q~JvdRLHS{Lv>%o*xV6|h)M?9o9B-BsMR<7={WLWS?or{{MTzk{DE~CJKwPw1T zX%&7)KuAE1a`sQco#k%(nD`+S3u@cWy_54}xeft>5Xi(1xVWJXsJZFeT>JER?T2-| zz7;zwwK<%CH3&Pdw2IXm+F)|`W#c;3#j1e`9BY(-5i9^^RvgMw`B#Dr^M`?q$UiUC z)KhCWwGlF`J%=pw-# zslddIjuu6dvDh`{p-jA0nGWElAz{J9_^RN{kbLz%QfurX?*Ps!=u3q{2(8J^iyE?Z zq;9KVX#*3uX2ANqT^sVw=6LUXI>TMxp+_8*l9UH(vmhQO_NGzCi~3)f=e>Q_^J^P* z`gn(9Ea+|0Ci2tDwVjm#X6e_{SEK3j(hc~f(!Geb!|eyR$RrD;8+qjQF3ioNw;@v` zOpedtp~OVE;h1x$NMI}g(*2*nNx`j&C6FIzyB?c(s{6bk^_g#GGJ_iQ0`;^TVAk{b zTxI9IulG)lXpgx4ivfk6Xlf)I8Z7_z^$q_nA&SR+L@17Nm<`$NU!5Q~*~rt%J>$!3*GMn4$V)gOAV6L`JUnE-sEm0fuYC<}u&kj#oprWfwvT$;%8FnHve z$gB&j$(yVd<6w?sPWuPNDW|c~auzI%`mVF>f^?yMXueBzaZxC_|U)tF^ zJtT#ZR~hpoTgSlAuW;4B2dWo|B}3*V8p_giDZ;EIc+W3MDuulZsB*=%$GHD=}N&hgH%J7y|%c8;$KkK6UYFCV|m zk?$GWb(zKXi5rSSr%omFd-+9Gfyk|JPh4YELTA0AXxMf^dPD+}{mg8FT?Wi%j9l)N?tJo`4ijkn6*1+%z0HyuFn^)NCO~EFDnx5a^bU}%fdn3VLvX?Z(fv#X8gH!$ zOi{NAOM21*)=DKn8n3A_Dp4kH2~qOcfupqDCS;X1s?a^KB|lj5#h<|CuLzX??tmz? z)dZ)kU4>;!&j$Le8EZ-4iOj~21a?5jbW^2y2(m1KX3tSC99>M8gvlf_J zTSH)Lv8AO@JQ+}UCxqy|dV5VIVQGMY@D?A66O%6~kjN*R2X2HO+`x?Ywi|MpYTDBBtPTpqA6gYN{VvWJD3OfaE5$v#! zL3J3$xm>|~q9DA|e=#{m0x-#=iNq*);@&_u3-}A;>2$;wmLW`bPnz9d_Y&#*p=S7J zaqtw}e>~df@BQ%`Fdu#7@x<_Ph%YRF;GoG%y9?o&ZA!A2azTOsAt_9_)v_F^c7el? zMoBaUu?~X<(w%@5gK}Z{P`EkM{8Xo^|0Jd)?)_wo%eu({TT*nhwD~NX6|(zT%eqM| zwYsGZKOIf6EbdQm$b{Qh1Nlte4q+5&0-n^6r6w-Kv`L+%r*gI@Y18HidC_E!C49N9 z8aAwokXVVE#+Evmx&$S$irnu9g|>oyg>iHIa*UJ!ILM3nlX2+9eqv{7!sa(Yq?n4m zSyctn9*7_a#s-RbuS5eux^ZqpPplG<;}xo?Vfh>}Uc3V>tdt?eropS)*1Rzftha@| z`n^}q3Fu8+&;c%-INCgX#Xo8Ox>)Tl319kzxEJ6>IN z!8zW4g!KBHL2Slgz$Zn^xoG61n~~;a#t%^@C#7HdSZp|8v-ff`ot+_`5XF&2XpBw9 zKF-7croe~3p?k6g_P}3pF-eEGOq*|oo9Lp%l_*^N;jNmh?s%5pz>`QgtPxuzk`lvKtQO1gjQvw>6}XQc#_nv^&L%a6nUx;i29l6W zXVCwz;n8rv_h5ChDv2m*-!ne!>LCOZ>;gz$k=}AmSp>T@i;{PzD-?Tcn7F|eumf+C zp)wVPJhROa1&itZ{Ao%qeK69W6y+lCuRDXsz`jggN4a;UU=u8<|2<6r^vfiE5aCv4yIO*inG!~f{?*G)ttn2d%^^rb4@Eem&ub(r$r3B1awNp#XgW(-OP;P%7icyj%gcA_Y)4+WO)!MVP(`zqu%VhrP$7f15t1U2xWfb6q~aYp z6F&=MQsyPh5ATRDt|e&FZXe{0Xkc$DG`+O!V+G13uogICG01{9S~W;JSh~(>`;Hos zRpPu!cXBrneI8bp`Kkzms$%+5(vj0gkf*>iYo%bH8mgdMdbFu5@p>Usm)V5@W>BNe z3THDAtbf7o6>W#qvi*p_cseyZl-){U*XD|8%3kTrH#GB#(N|jw)9Y=87e3#{WVASE zz`?K&UXh>tHzv&XXtjhbXsu+^tuHvQ-XIXce`T}$tk(&#wg}jN z&b$C8d4Eje7_bLZQw}PP|}v0+-!X!rvZAR8*KI;Me|DCqb4?;GP({8s5Qi zsopSZ#AEIdI)`A0@tGSSG^*(RN!19s#qzMmymsA1DC!q1W(@`8v~+5_;vM^|;hf5+ zQ+tPEI(0%cai19U-)JPMx0ZY%MVQo|vj#JWIBg6x#e$=d!{j9m;idQme1Uypg=Ia( zdWZqb+9b;}4w%8qMXj|056?SG`>yg$7Iy=r68*)f%@~CzOV=hs90`ZD$jPPtv*Xvt zCvT5~a|{k;90cpp5TlMVxKsxH+~H+w6j3F1OBy*=35cN!TeXE@F>>U6iTQ94|7&nr zs}7p=Z?0C;+r6%p%?v)u2E7$bVpm~jc)(={K1LN~Th@k>FTyA&jOEaK*`y?IiNzGb{w5;b~3JXwX6@=ndxy@QtQ)Ri6a_Ic4t;smhby_$h zY+kOd7urXa?2Is7x%G}>frZvc2VF9_6s`534f`#HxFQZtXAvX_qvCC##Cn8YI|oT0 zAX4qvC^+sGG8kpsz_yvV5)}nAS&3~|#O;(R3i%<^NOM9hcg==eLehrCn$_6ym8Yce zkQRVLL?Ob{q^82yLA{B#4&6Q|~y>byE&LB`06h^S4j#xS66#0D=XJ~J68c>@)UrvcfVcVIY!z_rIV}3 zX5cfgX7cM-sCtDk1pnv=K**1%Q5nnFIys;2jh|)&=@kN63pS&5Xdn#$#43v9YK>?e zt<(!+74}$R6|sw8;cW6D1!PBoD_5>wl#)nmYLI>}(lSid2?X6#xAf$;eQ|aAy7O-QW9*|s-Cj7-XG7=_mls}K z0b)F9=kmt*e9&h07Vv^est>8&Zktc1`WLfl{f2wUs*00n(T`}nM~NU0D|*teW% z-e%?l$_`(yn05!hENp9<7s84Of*XCp>maID!?IZ*La8943iA`35KTx$F4VNX;1aF~ zdiM`UDUg(Ilj&YW+{l$i??=CLvt6sy)^_GsuC)E|IC`RE<3+8|xZhadQ=py|6*>G3 zy?u|YYy5NZ0!}CBMr_{WV zfEsu(i0*z2EsIo;*JS6O0^)nIK~@E3N*U> zi-#NrEGMN~yL6{!WgU40WK+<@O1%EWfeUY;PneIU@yV?DvS+f}f4vMCFr#u?#~!~o zhQ4O8jRBNcHVnL6HyT)n-WsiWlw4@deYJ^qv}i4Hg*MxZ-qX-xTAmQPKNNPE(d@As zX!fzXOcjBaaTiX+y;ou{bz+vjh)Z8>DMM*>q}mEGj$RsJLtC)x6yV@OdK_=ug)5uk zc7y&exPa$Rzx=P?maqMWEI|F0pP37&s3Q|D#(vtS@~&kp#`iu(w*jrud~e2DU0vW1 zj!En&n?Bm+R5rY{VMc4!h4$RjXhWBGYS%B#`o$cZfnS%08-oXoe;e|aU7S%nXS%pJ z0@v7Z0V8hlL6!%wkiKXp^NJ6@!m*pmZqdwFxZOc$Zzyw%C1YhvV^wQ$E-}S}48N(F zw$v1vq}ywyei2QoXX*>Ke5J=FP#I}j@OqDfL}}nNp1MV*FL;G{W@o(rRMc1R#}{6k z@l?wVd=B!ifPVI-;b#@Vs(rRW$idYtq+z=COk-LkMOkgola~V=Z4?6wwDXsfXqKizy00j%<+k1nc%+ieZA%I6DDQ=6E_YqUH!anERHu}eSL=RJ7GXGgPUGFq2JD_# zcSrFR^n3hMui=ln2=aq#-TpDGBgsO!e(x{4$lL>Ig5$^O%V&@8K6&=|{_edekGGy~ zu04GGbW01x_y>BH7&9FLA~Nbr-n)A~6pU{7@CtpyKao@-_3X*!JbC%@aCCt1iiTr* z0e?9OFEojvoK4TM0kU~e{JX1-vQ-^>(jOi{ppbu25Q+0Ic-w0R2ULQ*6gMFvr?~mb zx?-4&Rm-4CU%3#$!VX*n&EcP($Dg|^!{?vhh|lFGRODm=)ObarnSiX9Elm9J zLFmRyt3%4SE?PxLkUGN%wQZ%X)zqP!dF0xfAY?elj648?#%4LgyWYTQ>j;XtA1MSA zM7S0FqgJ{BCEPo;Lx$ieNRtgcsRJ_VS@l^Fi)uD2!{^uN$SaCFdX>*hhNl{UTuhqEGdT(#Esz31|uk!7F-j&zUMY>3w280gvjoOp6E4zk=)U=gj zIP9i^lAlDfbQLXzWb4D5%iy?%#GcCrNgL%SgPGq(g%ZNl()t8krCYyz7;1=;;dUFI zvm6uqfK*u!FFC|YM4Z5USP?%qDq{x-nM0hJ__1toX~|@4 zE~V>}zT#%A>Jn+Tj0KVm__+7#?CkUg|1;}7+kCX>$Wu@`@XD~26l}~o*xffH?2a8K zD{#H{-NQ#u*Ee^6TzmBJKJMVyUH@V2;UnQXhN?LjkcK*kZ(ZeM@5v(XX>FXjM~Xcr zEnj3s;GByPy4s&Ocr%@~tae*RoYX~{$AY5;YJR(dr0y22tq$hq#GNN>C%&T$X#p1(NDxa@?#z8rdmtQo^wuBf{X3;ucQb{Yn z?5<@2>;t8=c0S^$L047g(cMdd7BqrbIv1(jGS>c z>RsC&S+!R=sHmmDKx?cilqmSSHD`)_EG5co@Ejn#5G9~FA!&|WD?z#Si8v;3ba3w# z+!8;Sg9FvW38I0m5_voe+MMcgGtcJ(y{>n1 zeE6z+%6D1Y*9f%hfvCGyrO-CV;e<~ zh#b?3t#TB$ha=J43ll~YkFI$GMeSz8+hXa85Jf@k2# z7BJXwx{G{sGT9&R%Nn6d8XcoXGa0AB8Cp5Kj3%h6Rdr%7(#dKzk3xi6O|j zUb=A8&-In-ZMSihwq>g=!;p2*d;98L?+odK9WGqUV#5+tRTc6u?tJ;SVsy*wo6Q5U z9ms7KRx}GoR?c4t7CUB({2&My%gi{HwzM%TmoUSAqwE3-RijS-d8Ps&a;b--;r(zp zk-G>#oCvl*8?+9Ej=t(7RQjC1Kf-=hlbduPK9q43K`8TRzv*zNv+3|A;pdO9_(Qxr zN262z=HWRxRUa%X#Z<)BMe@>ytA1Df0Ox^|B`$?y_W`pMl@UUcO4xMXyy5zEq2?kp zVqLVL+`FJLiLk^ivph;LqoIX^NKk;nIyf0L4N5aCI2}1sro;pg@e_q!zb|ff2vdB{+h-ENf@&HKoW4X}_CNVfx_mOBCkr1!oAd{hy z^EniTDEK3oWAi!^D;}L7hjP*+l2o6c9!%j@WWH*pe|Y;~>94L(Z1*dyl}DM{FDULv~Zu6L2qaMlEN|zH^|{XFbd^&!m8N8Mfo4S zKrUqDmw17de>izP?tQUx^P?d9e{A&2$DcBAYXnh4+^8|zvVkaH=z$d|LpPSuvUh4@ zam`gy+XAR4AvcT%A|Gnn+zs8AhvXZ+^U^B8QsR69FR%}xHbYsM#wHpbH9EzQ`={KN zRS!oqNsyGjr=>=c2Zju*rn5^Am3Y6uE|yrL5v>9NxxPp$3rjQ-lEt`mQm60|PO>9s z;TdcidjAFf9w9sJh?jX_EX6T&9jP~AJBGB4P*;SGgOh6@L=409r{7Yt?0cf=thfp}t_+{4&ZC|@ruXG$c$;&`VR2Q5N zlKvCvS6gvOvFf%Uf>XSgo#p3+Z=XHKsk9eRU?6;)76obYr#u48Mx^B9Jhod z{!Q#T;@RSKxug?}iImf$EleW;qK33&$Jt6kJp{O7my7#t+hEY$0pz`U#^=&QHg4CQ zV2Q+i8E2wk*L2P~BUyO*&D!cPbS>QlXJ2=Zt=PHX2cxhr*#3h+A~A#M<nj$vM7}{!fkVhg$tq}2OA@Et;Oz|HNmK+S07u`1t!fzt4b;Ly7^Pv zxWp=Jd`gDgEvF>rWDz!1l3tg9tJ9u{0VCif;H7K9Tj@6RR*f<(?L|CO_$}yCj4R=C z+CVZ)ne345ZMOFc{3fvqGU|r*KZ(A9E70?INwq}ul@bWqJa9|HH!wdV7I_zk-UpU? zPqij91hLRIP9w5Yy3!$RvoEhsc!5mEv`vC3F>eaY%7$V=x?JuCW7I7Rpg&+-e|kI} z+y2>D(uZdGwbt5GU8za2sP`Q%H-v^=ytVC%2lV^j4G94+%El;uT#Dy0{y&V4p&cWf zJ_9m--}!NGw)5cNJ`~DEDO~CJ7(17TPm0>l&L)RD8`G0LsJ`nzNqmJi(h;^ z_Q6KOFaFbx1r+`AU;x%?BQGOZH4hW$Znwn91;hW7>FPTpfxONR)Y0B-E8fQ9xuYW3`?pqZuH2L%#S}R9SyR5+ zgGfwh1HAM~l1It3hMzutGAo8W@IkjZXmnj#J4wHoG9v*mEl1+fUL;MglzsA&6l44I zVh(E_tg=x#;r&CIeD}vR9%XekBpnOsdmXFDl&y8sB)oP^SPzpXLJWZNNK!+Z1b+8m8Sd9q?rR46Z6avpR9>F9HxOV8Q zPR8nLLNJ9ElqNu)s69S#1s|zK5wx7)AgO% zr_Zk~5ALjfy8TlRzwY#|0ZrHR6P`6#Ew%(S%f3x?XD3401}Z-@-ZabUXb5~xV6EskC;_J{f zdLMA-Bo@oBZ7%awNxT+POH?#31!}|6DA;-oU?CGPs#Az3wYM7u!1*ssM5_7ZWVHR$ zx6ePn^DR#Ec`EJxuh`njxHX_Ng=3k?PnUjUgnTle96sYEm8__&0elF6kcrc&2Lts% z(J2rf7{s%Hly_oU=0%fS5hhVXo5J_EB|Jf63qlX?(oa1suTY1p3#=_zSK^nfN&+o* zTUiZ>2}sa^kqM5$hAg?oPr4$%#ggPYU(qPi{?e@+kD%A)I+taRn&n!Sn4Ug|0X{AP zBXY&C>NCnk@>9N+^?J*79`eb+V%}@&BFfk=CWoW=K$C;b|DZwq`2=2S1~bc3AO@N8 zPX3Sx+cw^i$l%Mc`ea%@4kg|Bbg(@dzT~;)4iO=-NXQVPfukRrwj$1K`I0^Odgp{d zopLrF%hqQq+i=+=sq*6cOPAccmMp%{ZSXEHkZ$b!OfQi(VUjQ|bmJ4dJ5hcx`);62;*zLGX!9ceZycx>n|<=`4PGg}OlI$qJYj(szABNZol zV}^~!%n8HWV=?d`vCjdlITnCA?hS|IpJA{X%EaR747)C}z?1W{)AKXoK^p3vkH;|B zR4>#A=e2?1*3fPl_`(2N{LXNAd@|fa2;~&8;^*kai|P1HZ-~3$GMJaNe6hKl%)WyL zd_EoD)o37df7VDr%Rm8X5##v$=SO zZn*P#Z@KsRU}t~~=UQuL`PZGn{`d?XB1Y~d?uqa1Y+d8qEeNR36YkJk`CR3WR?GxF znS5BHYV?g=Eca=)^^`WgkR_YYt((hMI)EU4(gZDMH+E^ST z&=gq(le5+EV{QopNd?>nIDlsI4J@`HGXeHKLtN*+q*nTDW#u!)!Dq|>P-C*dYMsMH zF56&m3vq^52ey9d%OAtd_))gd7bHoW-b)drXk8bkNbOOC6BqPFrdeewhArqE^x@Bu z4IS(~dvEt~zZZtFFCGGv;juG!7`XJ*ObhBP7~pWXAxYZ}k0w*tngSd7tZh)V6WPJv z6Q8t#Gm2YRmwZ~ zv5;B>ceej>e6m0OZ3nj&U6_oEb(GO^x|-~R;|!l>dq?+<_F-2WQxRe$bE>E-+IbNo zlcF@khApxuGt9S?-S#yN`w|np85gZ&ZpW90Hc*LGG`T(J&q0#@OxqT~S8VZRCM{t<7Bv^{f3iD-)|Aux=$ zADN#Y7LH(}3mqeuQZm=NAG@gvs%nT0J z6vN~+M1s9&=yZ2w0fR$0$H&x?N-xaVN-36XAgpg;dUa8eD9_pY;<_=n<7JfL8620q z!VIk7=ObntNs+xI^u#NKLBqMP02w7gYI>J23>$ZJP5krx1Q%llyKGtpl=3Oq5wbAJ zTey(|@2q#=i(^h7MX}h8e_&74>g&Dm%bXsPBC&PZCqUXSLBybCoIgGWj{2W|jpy4d zpWl#NR74TGUFrY&|FQS}?Qz}4+3^4R6f1>&NyZ{&DNfQdwp3Y?W2UsklCs^rq{E9M zSJKuLm*JAO)!O~+?|siN49>yXB_*ZJ)8|#M##|g=Fqjz(27|$Xza1khT3*NU;)ubC zb!TP$*Q=|a-XVlv0c#PmWKN~7f=&2Cq{^-(Q7ny5RtzVmxMfzV-c_BHDzuCXE@Cy7 zkD?!1>(-(P;~;*+O9AgbW8jJVjhLq`(<;hTiwvQ(qIQsDbQi0D+mhFcrT|x}_=7(o zvwV8cuKH##vf!z*{5Ff7!*_xR;uPTR!jOk61T7?J51Cf1{O)w?Q5pI~`o2`wzXvL6 zsDf71zXvLQqc-*2I1d>KHu7BlY(L+DhQN)@XOScv#MgfsRk1Za`hI*4_2&u`2?vk9 z{{j~PQsnmDw`vpCanr=1*_T|ea{q3kGQQ3>@kLJ zfI<%0NCO@%O{TX;lrfG93!9Da_NZ{w5U2CIGt%3mhTH)p4nqB*AZrXQ!qLhBfzBiE z2|6u$r5=^Dm0nM*)hmqZjSktMQ5;Q(4eKZmtXt&(ifOousHz0o=^d68<~X#<%AH(U zPfwfks6=#i9(>0B zgzzXU;>WW3rpj?;;Se|YG_-*!#KlYy#QJ!Bfe7u_f|f9jRIFKAo~i8UP9-`$1{}oR zGJh|t;#DH_#MaOrS4W+^*Z6q+!_N4xJYkX{i(nBb2UsxbjM`5$*(_LG1YHOtsEvE!S6tb)e8t=u1O`62FR0w-+26T@ zsr_bLZt^TY$2~m)86n;g&;3oYo#d{LHaYTu!08|dvcynqHG6IrH$*S(ZBqDp<2tGM z1zA;JV`d02>s_8fjO5;^O+4IYLY$x9yPv@T(G^j|*`gckp^72keoz-jk;PJj`nbsq-Gz90qxSH;D%mWA_l&KF&o2q|HRo1k7}*4~HCi`3q8Lrmq&HL&v6p!# zDlQ3yO*l)tT!J~@fui$KdgUv;BWLNYUzycGLT(e zEU>#Ul=<$w`!X}pQYwu;fUE*AfuO;dro@Tyw;7G~*&dO8tVhKNk_xX%H|1~8Or25G z6D8LbYIPSA=;wYI64tw*J$bB)OGlOa%F<(^1r=1$aP`<5HMnWCQ{^E%;|N)fOUv>{ z3AsL&arnCSl2LdN?;6M6_rjtf1h?ggkZ2-)>1yktxWj5oAjz!2D?w8=g4i|YkSd_3 z$2xRG_n#V9+_t7a!b$i6aXS%!J>nT|{&fLv9-nqak`0l|0-buuMEPP4ZkfUn3Q-@H zBi3SIQQpMb=Q`#qQsZ-Ir}=hcTE4cXuO>&yW_UUklR+$omrSX)KKlApZkc1j!O7jR ze8%$Ri>a>f^N=bNg>uF%N3j(lIh}u9L4p@HNF+KbqHz&#MonZ3d5J!w;~7gVviAR# zRs82;H6G)xhw%tCx*{f{BEev!Ft$s}V3T2?7wVE2 zGs#hOJjQwa@%Z$J(NoAC@sl=doPo{-^0nVs-XR}o9E=W;_U>ZD zz3zpiiA91#=u9^j)~DyM?i^2#?tFZA?Zx42ah?pb3mA1QgByDq9Eg-5-&GNdQcD8~P9g?XsKGuj4l0)0hrssIz zL%DQ&6cb=&=@2Y?Asus#Jv^Vl&kA!f|`AlnMqn zV2&Z^>NG=krEb9EC*c3WJ{**ytzg9d>P_Sh!A*d}XC6G|q?XCy6c~y$w60aNKxaZI zkj*vD?!h@DKZrC|S=O~u=Um+?{LOM?G;w%={4sIuX_7AWtm)AS4>5UCM{CNmk zS>i3A$m4ZABo{Sw@mi)cfV?`8BQK^6-k<%NfdDfLpG#-z@?xzM9R8_&tT1DlzI;lz ziXfW*63Gn&BOZPa@l}d|2^%7F3x@8&EIAm3GVt^3SNzW}h*LTLkYrc^9acdI3117c z387SGvHQO2aickp8+V**gbu=g|6X=2frt>EMX8+SkZ=uoxI>&EXGFRA805T+s1X6HD?n zhbvUU3pv9|i$-B}=8vJL@CQf0n!B$L?>>4xhI8QZ&0Gqy@>K?#?O5r#I}Jc)ol;k+ zncpOz%ip+t6SZ116q_M>!xI5pwH_g-03Oofxu`a$##4lbsMDmC0)_XPnI^8Y2yi< zkCP*82z!_GVFA0t)6Raf!!u=jm*R97H(J&k{he}p{;-pm2|pK-SCV&)GN|%_u;59h zR+tOQ>hvH*IRTxk;+PA_>hu6bxdIZU7fw*~4G)rPv;tcWmy0CsmIsHc+>GQA^^_^`R3N<^FJT(udOFw*2nTzT=i||5z2qtFaP|>^N09yx6$O`*7le3 zt*w9hSyPfb8GeUY}ql-0&zw@a1ediIry}%8h=2zm6 z@7Q6!ZdZ^|pa$sI1b~q!HIt%-y~u%`BPR8T4sp4K%kZoy&}|k~TU`-CU{PaLbuSRs&Ly3SM@`*8rAtuWFf!lCDeyocrhi;hW)Wn>Dop5)TfH&>c@`AG0sU?wD8=*O9`fc+r*F zb>b_cf{dFF;((;cOVr=_(qGHKj7_zq45szjEpiCyZs?}4Dz6CW=IP~LO3h( zst0Wi4sd(Z;~FKr-Qs$t1OSVVMX@R3FJ8g)Q(nU9RwC_(ovX_a{RmRLrt)kMQ^+0T zEfgM_F?(d`K~E`-Dy100k|GR;#thNeiJ9A=R)IGMLf=H_QN26w99n46m~Y@h51vR0 z{55A6NWU~os-X*(gSJ}3Jxpe9N;C%CAxL(~d#ggQ;XVK+8-YD~;JeP;_2o6hxyQUp z+Y|_CSEjL{IK-y1YsrKUPAJ1=hIAlIJ))97^GLdf3ro3;xFn^9XM!?cq9&#iCuaMM z!d-#v{cJF;lq*rIp@H>8V3?ZO{%w&mlUks32?uiPHqedZ78I@FY=Qf%uth)3XAYLI z6UO!wng1%o8e#Zi+AkxAS1!!3S={}oO$AGDrO~C z7^vcOhl>Z^#S)0CU7FM>eiAPA1tgHU@(%Q5ryOgEb}^dDbg|!p$-xo);Ske>LTwSL!H~C9) zFO*~T0Ags-&*f&HtPU&Ix_drrRM6%ec>p@&=?W~0NT?&%Ed760SN7NKD*h_BkCL+h z>2;7m5yKW__;?cjmb~5GjsD2pU^h^Dagf|qCP-)U{!sXM(--UXn?r=cA6Xq}7D>fB{^{%lSCMgJj-)bx zKozzS__zFDyc(zXV=d)*3l5K}N1xDq6+Xo&*vI>iAIP~+s}b&**=08|5}H*${!S0U zKb8y;!}ab~^_pWvcO1~KF`&37(5`qdD*91)gLK56Y%)4!sPkG$lCtJd9iFiOxJE)Q zVNI(MG4MMNq0h1;h#=YZ<`4-)#zcs(Ofv6s9pyNKEW%^W9rW~U-6cf6_(~iGIBg|a zgvF8(cGFg^cX6|bDA-e~= z<2j!mMPkhTCvVO!-j?52YxEUzDNe52$f%l|=^9sASjxC$UqN2PwfSaxJb5`8pUXop zoI-o+2W#IwKxUa0iqy&YXF8gGe)03pqo2j4^z-4*2wgaO{qxz$&u7d|xVO&wJO^HV zu=-#{enLyHJ`m+1xR}*#eTF~@yLVleMH-gQirQHme#QK1@`!t_(qx6zOe`Xao}I?T zUy{>&BI(AL%?Ams)~mGkNxqpQn%yQtI{#l@=dJ|rA6LXQE(K+tWN z3o{6HD+UZahdx{v?n|A^fq;sXl)4??6^d2@U^a{Ot|%~wYbJK7mDcbm6f~EK?}L#z zRuQ2RAC<=%&W}RQjF3_qV~3F%tg9))4g`zg7dt&dlm+mji;QwCJnWf$r1H%Ydvlgd z#(dr!kvNF{fR(~{9F4?rm7N=IqcCg))2_BQ1YTIeK`_bjkel|-n>9G?6Qptq*(qa) zEwgDJMEk6dmhpegX>6dv*oAfLiIb6HIVJ~bzqI^evSq9vJFYU3%gxHglzTBo5lqz5YmW-;Rzfd2?7 z0QW!IL%fn_n0$Z04>q9O*P!ShY_u|^c>Yi)TN0rv$%kMrYKY)eiKNNgQ_LUV9ziu{ zXwq)ISMd{-EEWBl=09+m`p>(!fAb5s6kM@TQ2%$nYIm+WU;G8zE@zNt;qG@g)>r(g zR8i04GdQwRYm!87(dCn0 zWHH~sY7Q#h`(+iB`dw8flzXuHE;QmErBF$_FZ;dy$CB}9jSITd21{K+{@z05Z~x!Q zQ{TYZ{Xk)NSP5MLRB1?71Xn;gg^cwcV(PV$_BY;f)&?KBp}@>#>J`alfXyZxXS=>u zTME7mZyi36Y|zBFkHGFM?TP_PDfD*RN|w@gYs{-kLkecl4{B)mYMI7ho8D>~AZ5&h zRkvO(3$itFxs+a7IV@v=Q8!4HeQ-hAO7$Xqg;ykSO9}II8A$i0s4f!A>w>Ul1~S}` zvssfk<^@TpA#REU7>@qYEo=Z&#r5S|@C5SVWZo*s&-zL#Pk+;wbd;TF53#=t;iMRg zdm#0vY`Q*TGl@JN#P2p2SX>Chy{$ukp7#_kTiz=3x2-|Cmy@4ZORo3J>OpbN$8BGq zLWbpl`y0LxnXU-h%b`vXno$V45po(IKuXXy56u=LHA=b%53=`pdiiF2J~`4;7s1bS z3%Tu>CG^f;Rvv7BYTe!Ej%$B^eU*{O+=lJ1|Frr*++%knfwyKza>=!o%BO;B*|-t) z-TJNdTS5-2l6=2;3l~;#PvS{$*|`bfJzJub!W^gI6oZ$gVce<}K?9d|>i7J^vaWTk zUDYzt@rs562-01-{MBD%tp{QD*GZe>kAB|!>EC`0HNh2sVad|3goKKwFG;nE(TR$^ z0d7-GFm3Pt0clu9pJJKCe?LN^)nrOS9hr7^x-U&c-$9DPA*l!W@L*y5|Au&$(eh7u zJ(L!-0Dh{JT81DE+{j|vq9J6*o7t-yWqs>i%FT3cimB!qun>8`)!F!sI`Z*5#qi)4 zLkRRJ76%2Oj1CNwp_~y&6^RefV-C3xcog0f5|12R<~DoXMq&HRx)$~X@E9Ez=Lh<; z)kwaS56JjXq0PzZ&b4bnNeGZ|I7*-GCBxNDeOBpZq^q5@^R7W09WVaqBHklor=Qp= zp})kiCcmmt7dXlkXcX)dOBGTq)v>vn_0E4lm|Tzle)vD z>3Ja?rCSIkX`FE}g!e*z-v9Z5U5L=@9%*25cV~M3$Mfms*}&AO;bTqCc#2kmjWq{_ zl?R{R{L9aWv!C}qyZ`CvHYoRN7Ok!B-5!0n@&JFZ;O1>sSz49#IU}gHhaCpgJ*^@y z|6ReLGZ~C}L2ipK6U9Vnv7b0?Vw{)fToI{v&G_~!^SzhW_e8CMkbT7__6v*` zwPSGeOiYwQHes$AZ@T1CqMp>}5XL22Qp4vj-g~hj&5u9ycYEs(Hu4Zs|F4hvf8Boo z%Q*MxuJR-%JTtrf9iA^Zmy1BYA6_nZQJl!j3PnVOk}0 z)|Y8(-B@lCcLTmN+*TPE%+5c~Q9o9DNqH+VHca#k?#hMTEd|8)x)!?eM& zrB70SRL2aY-v&O}WqsjAMF!>si(x)W+$=&RAReE%+8}j1KRjgeRs`j!0UFEl;9-|G#_rk{hnFqwQ|}e`~w;Zi_4X6#xLER?Om|X;BV7tzyX16L6&fpVjB8(;^2T;&9>Tz-G{HD zqlH#r0d>?UIyNqdLe*)z{BdW7+F4sZ`@+2K&lb*#aGdm@U~%AyT?a~k;ttI@PUr=5 zF5A(-kTV9lqEmXc36SKdh;rGD_qBCHZYc~DEasYdFX4R`sdVZ7yOGGb%dV~T>f0;J zR7XDl&ewyc%v?kLQFFL5%?hCi;5C35-yNRVSQUaW)NbKfUjCmbaBBCSMb%KVJ#_^U z$Hc6f-ngoYzCBd4*NdenYWcFoQ^==(?)P-w>gc02JR%8C;>EP_^(rcnMB5!)<~z!T zt8riD{G+Y8ZAi9OfQA)+eElp+$947IG6##4bnmEJsH*y?aM|ffoh=S~ce$10?CY5y zcj>Och`Z*_T{)%T$$y7JcWLjn%0W6YFw#m`1iwXui>Z>JtcSz4!KY#yB+wMv*qXBZ zD~9<1fO#gfHxi>Sif9ib&c7rIF6e~i?An$@^nSa$R0(k(jPAk{bngS{@!m|OB-rY7 zRoi0a)B8W){OsrZpFQ~bQ~dvDpCJ+oP9VNQ&~dR8LJ4p6Fv-o5x!i^LKpw>mH3164 z**B6RciFWOv$Vu9XdDci;@nTf>j!n@j*8vg1MH%~-VuJS5fH&*h_5{ViT z@j7;##$9*gs7k@MXk#6TgCl{ttwdiE7i?#97OZoXjjUtFxeCj#{OkEkuC*@WxD}b2 zdC3+Mh)4@~r@5HP%G6ZP!%05vqb&ol{lk%8wa)K7WK)O6dqMVALBvA5| zm?Y3_L5D~dWY&j8`Qe(gWLA2SzF0J%emKJi`|Bjtkx);ZIO!)u&lSKD-Df9tQCc>t zN>Y>1<}t-noC2CPwS73jgIluDP+0Io2qAxg2=d|J2cF5|97n%nQNd9NB4+(Nr%{qs zim^Cr@!g!Z))3MJiP4Ygw2og}hpCfaKvV9h zUMOPX6cs%Q4noisZJg?jpmZVcrXjqY1VEs;-HZ~A8fbkduD$?S>Jz%H5)e=Yr;nl? zh(*6|3JG7`)6-MX$kif-?zaVQjo{)EsJBP=FdidxO3bP0+~n9!4@u)7S;`!y&w0*G zWmX#o2Y`M=`I_8XeJ#9R&L)vLoC8=ECT4Xy8DEUIHOjKw;K5lvZu-owlcs6+=zMZk zWn}R%);JhPcx2oIU6c-FYjQL`ok^xPohaRT0$~3#e*5F}{CG~L6I6PPG-kvM?i`s0 z0<8h;%jui(8RASzrGBs^z#$LIYrcTT88rlIS94+v*O|;7zQAz`Za&UQCZ*Kky&tYV z#v;PJ)&&4ZvoL*UI(2A$h7U;u*1Dn5N{GgS44S zOu=~za_|u{Q=>b?t{}*Lc1uBII@gkz@G4)M259rR z%MP1z%9d0;*bDBZbQIlu$xv^82vg;ufVvNgp^k;UBtWs~3Y$&gKpU#~BMb`{+2!J+lxK}I@4ZPHcK zFkxSRAntXE_tn6>(^DVsHl!xj)wHP+o+n&8l2TQhgJ%W1k7b7HP?|U<4G?qI@@?kC z2bCmZ5%nq#yFtkWxsP8TLK8dJkA|9wd!k;M0894g9E==VADz_pS}O#updY=Sz%Ft9 zR+b9?k`;;0&DNYbR5%{e!({sr)1x;b{Q!o@Aj0G$)XWw;| zYj3!!WvNl|P|-Pdz09D7+VOM1Gg?q!1x!Ahn-nl%%VJ@}uA+o|= zY-|j)!`RGaVFUv(z5z+P*$030$G@x~&QeC8eNd9#Pa2dw+piDLT^jOg<7HVwif)IV zk(+eNw!-Zj%l|PsgRA8JXrF*LHvZquZDd`7wB*9)4|gKjQkT&0Cu^X*afdjSl*1YZ zrz^c|rTPAWXE65gHEt6k5xivU6cM~({wk!F^1I|RxW{;_1Idh~B67L%-2?kyr4Hi3 zj68exhj<0qGm)bgM~O_sg*n@2UoepUJWn%YIT2rC|7-VOTux4ozkuU+6Y|2-dCVQQ z#hgrojMYrAgRF$}XDD94d_nGP0fL^@{8n)X>C;xQ21Kvm?cUk)h)!tvYh#3@=Wrex zMS>A1>bQO+ZCP^t;NdH#55_zkt2ysjU{Koh5ifM}Mxknj_R>CIo0K(Px1sZx^d3`- z@esRj-@KfjzTFqqa|%7Mubfpq+(^)ekr&;h8mP>*q;3>I`egFqI>Nqpp6D6UL7XgV z?x^HYp;7;oUvsonScH{Nt~;9{nh?_!tjRd}$5O;D$VDA56(y#~7|&bA`wX2CNd(=Q zDo0MZvX!?&Ksz13LRbO*z|MbiwuLuS5T?F+!WStyoYWfh5m#8FB4~k%9KRpx);KdZ zpd1xg)oNU_wi7(e8_%2VodY>GQP-#q5nbIh+*O%}4Qdqxps&h>>9OmUs2;@HVvA-b z2x5#y6Y#&=a<4pD6H@2EIC4XOy*WHvxe)-7<{k}KN0edx+knuQ!B0S0T|ZLKsCiRA z;V?(@bi4nBb>O|htIcGZY9twwDJQ-wbAYbS4~RhS57e>_eu47fpR*fCc9`%qo)*Bt zW(hr`GG!nb7gGh?;qg5LLGpK8G)ZX zfD%;A)iw_*9CwK@;=23G9bhyEZUm0h2qQM9@+%Ut$}^}hXwx}3+yT6!Yh@Y}|GwvO z0bnY-B5LT)NTd3F|Bolr7aJQFQwcIO7Qvl}ei6V2Px;D&&z63^vr4AeBv3UPEJK}N z@yyXxnjk3jem`3eSwf)?<(cFsd97J!2lw{Ra~6}uHm`b#v*}gVn)T&7>$vSbd4)q> z9MXy8=p^bc31K291$cu-kXugMP_-R!w^iZk;}eh^X^O`dHl@2Qs2Cjk2%$wT=Awwz z=zQ|x@&XSx%}3L8?D!ncM_+0?gQ2}77YVO0mfY{qcpe6BJ|>f%SVua>L7xz|3P81l z6)70@beZdD2i=nuhg~C8;6v;+Wsj_wcA?-``?HT^4j6cmnK;Zq{Z(dr!F&q*T-)o~ zE-(?2tcnfpePnB1bEztg+Pf^CSfC4!fqzds(6^rZ@>2O1G}GVCF2-*#{TG{wLRFo$ z&22(VT^N@%vV1=PzTsb4L9jjGt^$4Pzpjban9${kJ(E^-w!HLhOBspyTYck!m161T zZ0&wTX>cC;oRqy6w<+e)_eLT5HY{w1%%QJqLt=0C%n{2r+zu>87_ zL?Ci5&QH%}w14voN>2wlyTja42RmLaqlu6`=csG`R)w!k`DAFQZ=Q49+8UNqn zSRl27H+zJMtD+p4yi7JKqzW%UWQ)iKE;f<=Eh@aUFw)??lKGp0Y#rV79#IGhCNVV| zcI@317&Q6|i23uWX=E)0n$f9#mS>~XeyPOZ2Do!t1P?zQN&W9CE67su&7<8FO?2WV zkEa)3aB8bH0pM-tkE(fxm@g#JCuy+6G@|+&0 zl~u}_y)yEl)Ys$bkEfdUZr}g>>hKgtYS1cFWIh8um8SnUd`AP-S|=Kvsy)qF_4g+{ zxwX&#Ap=aqWtBNLG@%odLOizN#2E5N^KB#@MULWM0x*S7Ri4)qzC+5?T$Wm$F8S8A>6b_DOqtyot4Uxb_mQzx&TmKK@06mUGk2b1-Tv_E7R` zfAPUDiC1WJV0Dn>SAFJ2BfZAZ&D?nfOprYrqvb=hvu!XWrB!Nl7RM(_8mvaL&gIeX z`on4dKAJ2CfsqKC?Ve_M2`AFdif-&TmTOSIGu2Hf7*eDYB-eC&FKum!eyS(?&eB5a z5vgZ{Df~4t#L^rW)Ulhy(jr1Zh}u18g#PPIK07EeDNXavC_}SAQfuK4^^-zXbFz?p z7U8HBL|T%M)GlQ`Jb#7!38%D(%vZYng#e5^5q!Cj+3k)kg$VYmcnlaWX4eKFoLbDq zo1try&wNc{>%T}cVXhb8lB0$}3V+4dfi9leTlyS8z{*Xn5PzLCN0e^#S@4j`c@@JA2^^4BE{JA)A} zlgnT_EFnRWjmV09r8z=LQoTfmzQF_y1(I(`P$R4tAdW@yWkIesHs}`{|Ec&pyW&+!mC7$w)tgy9_7l zxF+B`gPwmX8|P^@ay^C{Xu^j!GpP#J~E>?Ct5r z;ZL{)vca1muiy^<8HZtT!mTcaPY;vGV#-C;h;89P=I*v*OFcYLQp_hZg&?gKL8TCY zVa8zGHXUj&Vx!wWbJ;KX6%)!lxzaDs=y@JsQiRY2m*vR$K+yEmRSq*P?A;Wk(ma=0LhaU}gr{uRaI%ZYT11F0$RqbKu5Kco6|| z#X0b>_m0@y1thJj4#9*0=i$m8CSZZja~PHz!Otvl(_&t< z-n!z36+504N=vksL3gRzHX(rml-j;*S}_TA-Pv7v9c^NJ27dqVwk7hf>Wcr;{iFJb zubC=#BHPsxDWMpZK;)BBTR#zR}yrszEk3#N>`Os9a-?K0rxAR&AF6 zG3yq-A-<%&TH7=By|oW*hMGXRiziRtm`6+N^#UqHa1d3}?heL*dI5VKN^9OyKA9kA z>-pP3i~*t$qQ8*D*yo||deS{!P??0}1M$x?8vii_k3;f0@gz)fSSm+~w=OmZ0?(|Y z6N#aNSmgJgMzCf7^79@|*gLp*IYN&1^#?5UB4jS)&u01RuYY0URPk1KhsCU_2*es1 z5cvD#C*%-x+d%YRB9H4s9K@p55EPI_q4Zfaw;g(qH^fEbj+R`>CLFwo9P+>CU=k4f z$Si6Nd^Yi#G9nYx0t&g|b%Y`^{WbOqGob;uk6$11&^UpqF7GnKx)_#a{tB2SIDL!? zq=lGZHCtJ_JkQS%YHNHT8u&B>gVS7$6~Y)o0^f$(2Q|W;V9c@I14^7ze4-MuifTi! z1Gi{4h+)(if)#k00fUr@lk;<2JMH0U6^Nl#8G;%3Im{vY+4qHTK#1u#0&o192=_bHjk%;E1 zLw!K{h-+>-fNrib1kJeVGsdS_2T%J<6yNAH9fD`rIlMN9?dt*tM9r8@ z{B7{7vfyo1YO{`whUXl5G`qAx=-6xxT7KKv^VERQF^d&W-@ybO ze81?{U2Gr|#iES#iXRTQfmMOpr&X_glTzFMR|^ARymb?!$KeVKq_9nMiAZ>*QlgfAI{XF?GxR=! z4H!)vcg-K*;^qERJU~#BX=-3M(&bG7aQY3B=(?G(+yx7$x2G`dF80Y^M^@wDTb7p zco^sTn1^WG^y5GHNOOt9l^`0i{==_R{KN>oK-JN%dJPA6_=np>rVpa^>2Qc z<8bR!udt|rS&G6CplzYnnv&<}&x;-<`r~WWLRfDCEDDL0+ zxD^N6pD`Fr=%S_aIOi1+!!3@*xB+1!{IzkxbD}Ycp%OZiHVGiBLrKWAHF@nQ`)a5FE9A4if=HqZKFApsubsf2!%0715%Hs}Qql>>UvTtAbz<@NJQSXDwv|&& zkWH;*Wteeg))vi@$~wvb7*6D&lZ? zgmih}W+m@>Hed z3uGBVTDJYhvtO(sq~DgUbeWW31NDtS^@l5g6C;+l&_*JTw52*#u3+{bz%%-Pzmc09`A4{imqKjG{)_!WT->5#&pwz{6_PbA#>Vqy91?f>HD0T z(|X699sSlm3+J@PmUGVFlkRjF?KO*zz0LxRlWwNFZD7@@NChlaql>O^O=dmdi@^>; z1IM@rXfVs>hp1_-LLgmi*uFY7c3VyrX9c9x8-O%)(3+uGofZVpy>S$&%T{qz2C#Y6 zTi`L&2KYYhql1A41F&^Ly8<(E#ksJ!7nqNpf|7cRAhkTTd87df73abVzx|bPOSM~2 z!9(r1)GNoHbH+Zu-Q1qO((@AEi;9b5KF+G~qnps}918^V0={tIkjdpv{TQ$|Eh+2H=$Z@N-94stv%Y zQpnE*Rn;7TRuaw61y!mIz?pLfmZ?;#4ZwkzYDW9H=tQjnD7&8XelC=#H2`Jtc}gBy zul4}cE1Y}i&Q`CWbndY>wN{nEe|X4MwE^sGn^h(GABG4;*lN&%eQ8m^^ ziwCcK#S<A!ej2qVyh5NT~E7K=aJWS!5#PN^(Qk%lw+tDQ+ce*ul_=et&$?vsicLaQXv;A zGTtMIXHaTPGvd)vmxhGYEu-M}2+Gx7Mv?`$8sbp1=R)*GGacVhvqIBG(>(Y#vfDk+ zD_FuKx^BpKcl2~Frd$<6S(jHLX9b0cxhY=5OZ;LyJ{`T8%z)p^$*W78AdT>-2tFN; zPN&TCg)4n!V53(^tb4jnIpXxDiynii&B1P)Cb`;brQ#0sNobKIC%IVpLB$g_3!Pob zv;;$GZF;SLiZK(pvGQ!1Rv(hT+#uoJ=hbm;pxlIbeNDMvYYW#ps`{SPFP7)SvAS8P z&RS6_dv(Bo+*MfNciLad}jg@gK`oVE*0ETX; z027v+hU=o0;c<4g1Ux~nKWEXthU_ozefPmQZ3m-Y;q|Ubn!M>E@Bn*iR+qU{9};Hr zRO=lY{5wvTnSI-Zt|uUQowL}K)DIL(0s>xY{<~P4Qq_7%0fweM>h>92lN;9(SjtFA zuQIJzl4J1#vA z|6eg{6X^y{0I$OR3`JAoWl`v95>qtGd&}#dkE}0)jQ_y@A?8C~Ki3&G)1ZqPR;UlC zW=zkRUH>TTyU0VZs|mu6$|unLIQ*=>*%K)rso0L#shz^C25~_t{Q24p@LX@lq8c@H~0{}=2H1I(l|I|b3BGip9 zy+*791K6jQTB0H~O_RhWapfD0@F)^lOp^H&M|6(7Lvw^DBzPTFgE`PI$!5<@%D26a zkbLI_HVFK7BWUfubGs@m6*~mfj9G4P{LOn4UjDcBHu}t$@Z;%Md}%g#7WC?KDD&Nv zNTjXlf_Z1wBbfKeUoQ_&o}Gd3P^BejBVRs7YGd6F6>f6cIgg(%Z0j|v_IPM?Ryw7= z(g~)^ii-{UnarL}Pg6~(s==DuW_+jW0l1Ha0QV*XowQmZ&d44Su5jaQpUnF3(!9T! z1`S=opI+ZkzCkET1DhqGKnp7NCD;FgkZX^>K( ztD&=@0|UV|PR)qCw>E}SKV8d*IIuJBJd@;lC#@0J-8$7an{4?T8Py?N$g;g4virR_##zdf3soahye6o_qmkjWIo^$iIFx6@B#+(dfgW0(Od z>rwB=*OQAeAO232OM1*Jc|#I0uux8^>p29Z5W$}TpXR1)SkkqC<3iE7zOhw0TE4TtkFZ!g4kV8oY31B`!6aanak7*23t3kfu3C_k z=PtM+-ki)NnQp=+GBn=&=QrOUBhha9hAqnPfB$<+@JHQb-wHcoagqBA-3b6wN*UMi z%o_~RW8HQVlL$NYNLA#eaxdlIYmX}N9-I07%QNT)3_z0cu(49 zkM9*o^zAubjG99tDD^3xzQl|*66sr>K5P=|>~cP#^02v1BXbv@E8Ks=yd6kGrD@pt zG9{(}r;&)2tPCr7B0$6<_p!gSzq&Dcc6#!5w6e#?1CZl8K4Rd zoL*u%9R0(+rAuP>55K{GE6i?>rX0dQd=ei}?dAD+jJ|M@dUW^$;7~7rddGX@Ycu_c zfxmp* zgE|ddM3eip3vDw%>gUrSw4GkVWDp(nKcclSrk6)}$ErE1YwD|aRq0CLJ_aPV9E@L4 zoxeKToIM@$q9~HC~I^QKs0-0;7-IDoVBcm*EG-+pYz%iTp;(~|!^tg$9! zjTtmoTb47Fq6xZ#e1-d&7Z<#u`sVPb-N}E%rC{qUuY<^WjYl3JuQawIYl%D~p`Wk^ zoE}eJzFmQB0lVYk1S|Rs7XWelk82g>o$s~*fG zgJFkm8=Z{kD)LU&?&J0dUxo;i1xc^v?c-7-J*b6lwqyLXumk>DaHl_bmJlq4K1UdH ztwx9 zACJ#)19^OU^mb=Fo1Va{*Yy!t3{K;fHy-sAKg#y>WODR2oCyv8iMb5jTig%&!HHSF zFdxW)fL&RjhWq-A3euX+R<@_p6Zr4&zxGZPQ~~1NkmhlG{MF%EtCKU$-rj(Z=?E{y z_PL}NJidA#7Fcm2v;0Jyepm6(v>5_ITe^9?guFYx$RR`fo2E-2zIuf%E(mdZgtzFi zSkN8^8*YrS%*-xE&;PvrZqknn$$0yLcAN%tfQvN4-SRf=y>n)nRjyO6ktlv zUf>Cq5?(aI-Jbehxy@PNF~i9uYT*6aa+(Pp;j@}G6st~!E{2E4$15C{zVuD)1E{`Z zfvX4p#}!*yggw@+EQu*{@!93YvzMPkc#dbW**nI2V>OqHgyO&?Gu z`)m8S3{|++6(T3?%F^Vx-`Kw*2f^`o&Gr!Y9nigXm5q%t6Cv8&PAjXfU`#`rz@Y71 z!8yZ9H>B2Fh+je*BhC?};ol#fJVjlViXY)nS<7L zUE@2>;KR=xwh3~3^pEh*kK}yh*2bvnLqG|1{?&m=YQQXfpeuy#a`SlP^D1KYR1L4| z0FdpZpoJnCRk7jiV^f^+@mx`BMTJz<6ao^=m5%Wi7>T=L$A5mwht|zs4XcNVhDQ6{ zXEcFXm($tU3D+v?H6BR|uQTcO9DZrU9eSTXLRQ~QVR)WQz8}MRd~}Gj$7A@FM~5Sv zgTMw&nIA9>V0c-O&YNybyf#hL<7UPA^CBO5ykkh2x(Nk1j^YwKYB0 z4{&iI-uW2TzE(YFJKT&MpUeA-@Li8yUtFBcHtyU(60_HrFV^urUXUz*V47cIrmmrv zL)_0mr#FF^sIK?mOLgLE8;Hhks#)z}O03m6o^?p+37LT!^$B+?>zCN}y2E%petC$X zb=}S7eMVz{=O?r{1Bq9R(&4KXZ%uz3^GtTWoMjMDAL5mR6`MhLF_p4SqfRTUzAHPQ zu;n^1Dwxfg`vLZ;Kv5lFa#T~H3C|Rq=Rolx2DEf2nur)ruvLVUb`{Z1pIHsQb-47R zS0m~0#Qcp7fl4sA4ZNpad^h@Zw4l!CYRjcKX!J_k55)KwKQ=(lAcz$87tGGU>D*%YTxx`I+p8qi!8b&2TDbi=|f+4$) zD-F(dUmwD6pxNN!^;lu1CRam7F1;*R^`kq*BWSV-of_n|NK%xDeBj+Zc@kI_ImgDr z*S)DOCqY}U)f9P{wA<$s+#`nwX7|aqb`xG5%t-4P5^i>ctem!>8VIi?rE&9|(%tMG z>->lCv4CZkjLH2p6h)81@bRO}7vb~i<=K`wXg+^Su561Yvy?VtY!TIq)bSr7*%o~+ z;?+rpaP)wM@Bb-vz(IhabIiM@p2iBtq+JT9dbV7m&{s!X57<8&Vq|SZI^#{6!CJ1} z=TeB3`}4QX;46+%h1f8BJ~c@|*f-O|4SjsUj~%4SlvVDRTQYM9=9F=gt=&I6zdRj3 zpMH+T#C3-g#VZ3o^W-T_do915yg~$j$oaGLYq5CZzc@b>(GLDIGrwcMbR%8e@03Bv*5++T&of&8x)7K#W*?YhMWt$HI|jS*n}YVjQ2 zUgQoA)(-0SBC;V}+=$tatb}c;7@Q#9B&`D&ZT2EL?{P&zRV_jKzEVrDy610@^tcHD zX(KS(ux7XS9ztwGhJ?o&}suD-DP3qLEyF{WgPkRn?Wyi5Z*mpSxbcIJ|IAh-j zB4XE$KlpTxywc$Y0elB|9ZlfJr*E(`#!eD#E?=NoqYXkKFrj&dbAwl>b}=D)jWUnr zI+wIiZaWg%2$nMLbTxsf6scG&0-|PN4T)Qa8pFiD`U5;6IGEYsE9;!3;A#=p3B*ut zk|AjEI6=UXQJK!L1o#;n4DJP3FGC#ELfT5zkI4gAOt?dOOTkwyw1G8GZecfZVjVtQ z9U<~SB{JK%zD~b@C{$?6PFVh@oNL8mbM9i=*E1R-);d}&F->I^(b{eu>r*6Z_@7v+ zTA9H7A(ft6It*otLQE?Nd6(E!9DBZu%KQ)_H%8Sktg@nY<*)A+_zsYIO37MnuW|A9 zQ@QwhA9p*KUclViD(0BE-EDE0?R`uqtyD6466la+S+^>r^m5I&Y`K=j0whI9#*dY1 z6aJ=;cXE0u(SUsWTsBcx=$2DoSfXRL&FCY)IBI~PCOBjp4SqSbRN#)60!LP)B7&G%f=CWn+p` zF45q`0QU_R`TP#7ZJA6ChWgD+Fvqb&#Y(U!DMVET&+%8h%3$WGC6gzzzLL9^3iG`r$J6*$xR;ama(y=Z(5uJHSx1l|4k(L0}X#b!YfnW>u`kc z;To5P*8R>$lNlb#MszyghhQ2t99L{olOsPtC!|FKS{^@nw7I+a?CHVQ=JO{z54S+z z2x^IMJ5L_&K6{E!uo;pnlXZr^Y7bsP<|{=25kk%Kf4v-E(hFELQ+NMT9h`6-%bsd( zLT!12##c3-y3BwfU|rCxd5n-blPoMPC*vQ+j7|OV_1n}9!ayF|IC_<#O*;L`kVGfw zpe!;cXcu&a4dp#|>o|Q;1*k{_P6PiLF7D3|{pw)yPJ5G^o@#RnPPuIt{v6nGA9Maz zN3n^3u_fMwrk07`qj9bx;C}wOfdBNvf(JMTBQ;0?*_CAQ??4OR*3TW;RR_;qo-q|R z{Ku+2{_T zO){4jb@-wBv);_tI5bLE-MzVxM^vW82b=^=A~}7xsAS#~XBtCS!Z)p;!qfRuE_j=k z(0yr3XL3c^K`_93jv<*VHCDPP&=)w7t%nniW0C!WSsUalcGNO1ud|0m^yS7zSKC$_ z-B^{nl~wJ^(H(@`=%D6tL+B3?)%Q|ja{kIyOn*=ZyT#HN)!tI7+m82=u=)j%6Ohq; zEYPBwbK$2rtVghFcWVDD5p7T5lS5`NKb%cZ^PQIF+BOF?j`{C?H;1gfHJIIQ>2CIe z_iHO{o6P59vX1QXD-SM0ZZ#a7P0!i{6oagMWER*?z z%WX>Fc|T-r<;Jb&=WiKIh`Y+1hsTI*uaQGom+XRKGX!hp6tP>=%U7@C40XgXG^Z+} z&=eGIJkLhA)>m+SWtCo&n&|7d)^C~hF4VGaxn~&Ar#^aYK1cvT3-c}x%jUD@v(Z{K z`2ZX0d|BjMiC>u>OBxQn)v)v<%dj0bgGqnitGCCDphSuM>l#+oK3765Db_kf{v-vg zy>m>$Us<+x--wA|aBrjdpq0%zuR-7a#}sTYfX5hOjG1ShNyB^XhIgxmcda27GXK{d zl>&QqYEI1+pMkLLC^O=lpneE!ILtEWYG8Vl(i_gFqu)?|)aVkmth5(18{jaqWNG@S z#j|Zcbc)g{XYYYmS*dD^ohn5oSekH;PTotUB*{TX9~&rKDzYaRXpv5(V3&Rt6`xgl zB9DxAu;DX=b)J7q)QWllsReZ)(;vo$ z2Gec8y>c-n&)bNwN|%a2k&O}(U0Kzy?>)`cYo>a0`+SP4UT?~koyh*#jQ5Q-3yM!0 zRt~QmGywVO(kRbZkA4k?uBqvM;e}P=_cw!SS48*@93ty)ivc*dx5-ysy@ATR= zw)>~sezicOvS%Cnr`QiYf9q+Y#q@ai`YcgLGwoSYxsK}wOM%NZ5+eLhHvAaq>KKOW<9 z$H@$l=KH72%b-0lB7A(oz!QlUpPs+Eb38q|b9jzCqqwki=K{TBM6=gOK?L;H-yAE* zmzU>MSrVTPGsMMY{g&vt&^utC6m;j1oa5-6Y3NIbrmE`0-r}vpNvM!jk;wa12&)It zFe!k6-RXp%oB@cHf}kx}6=X@SKEwi5l_C-H=}h}tpkJ(a=wbGW|Ky(VGvH?>6QP!l zy3IF&5X~d#Hzr|U>sY1ehBe|xXs$FKREYC|#-&m zqbjq+G^0MKwR9>YvfgP6VNok#HmHpbGoki5X1R%D06W#?_8g-a( z3{M9A5YqE$K$4)Pf#DP+s9aba*H<{+;v{wOuTv;*CqNbXAR2D(t&d z<+|O`78Jj`DkC|NXdVY@g`j^Al7B@p690=p&)>KdAR4U zbOC=1Bv~T@>Ieu!Pmjh(3YQIx1z^N7mio_L>eUd}4`mu#4^nkUV>z)9+Ll;fb%$*L zV-HrEfA3DT`XWv*s1D2S((CBQ#%hx^ zrE{n@VOF4lW3kWNOp*z)9I9h;`8)c(I*Py3HAj;WjQN}URQXhGrxk!+v*wf)PNx zXoZ0|Jt-8!glED}sp8c!O?xwGCL^>O)D1k0ahp`eYu`AF;zJr~M}0`AJ=RzDR1b&0 z|JiIazy@dYSXa#uAYTHc5=)2J{I!_u3+(-(?+dy9b~a4n@%2m+Z#YNeSG>2Na^F6f zB~zbim_)ZM84*aG$RgQ}Ecc|$cGb)Mlq@Xhb*-M^*Nd22`Gl#bD1m5a4e|z z^>0DWMmE#XO8ua#Y-NsmHPtU75L?BMDT}GLwNkz1X|1FqpZASzN7Yi!BYhYytiZ*^ zwFzfPe64a^4FdU8(}q{{3IgFhD>vR8o_{Zk{-)>TYCso!jD5+b6C(3&a_pk_4N4RY z0c)sWB^%PnxvRGt-IaR(S~!_HZ@?O&ZCX)`h*kerHLwP#`?Z_Wa*I{1&jSDI^bI&^ zkUeyVhIl1jixakM;5Rt^RZno<3#AxXlR(!-DuG*s*1HDG?gwBfre?Z`ZRK-Z*G4`0 zr#`+wG2p~Gfu18odB+9l7ZnUz*PEG71iBc+o*`rps+I@QR3J^CzUddB?z&vNr#)hV zC*mf^bWx#WRjarBsy+^A!=cuHn!aGFq1+mIS4|D-du3?a?Y5okWjP2=k9?$?w?U+H z0ln~rjIiYqRjfPk<;O*5TlaJTctP$uk2m*IJifOe)mrarQUsSjGa?y#YKO2~Z;CI* zod%U*THws%^5|m4Du<-gdnWLQuVB5q1lFii5Um78w{k|WWEoPdpapXUb+aN!mN)}i zcRLrBUJ$eX8=xxu=0a*t0O9wwrJt=T$*%|W4ilgTzsvHl6x9tIVd1Mrhf0pD)(+|D49|+a1>xUXs6(T^mzhs20kU zwG?T^=E2qyNms?}PJD2oxi*An?A`m6mI3F#L7ul&=t3>mGTpV+KfEA!`~Tk{%OhZN6a^g(0%F?W@+P z!=0x?%Xz1px3-Kc2r5GdHpl+l8H#I9Z5vzJ+Fb0CC1wGQZrd*!nU%a78#Mqow9Q-k zZXpPZt<1daIEj^GvHFDxJw6UreR#Ez5eZ`bZ&?2l`Tl-Zz}QdyAHN2QX*G$b1Vciz zGLbr6#escl7}_rRjXJIkhN|R!C$0K-o2Y=^^d_Xlfdl$C&zpfN*HPzN$anE5PT)E( zg$7LrI_fmGehav(HIsV)gN;glpZ)UZ5MreU((yCE4F29y)&q>f0L zy|JLBD){pU+$&H@19qIjqNB241lD?mB(WGpqXz?rj*`OlIy`<<#5`gCT(~9Lh#tP{v_*4d9zg5rTu5g zDixwvh?z{!p4__q-0Ko|uZm7vDSw7eqz!(?cU^gCE2~#l4n$4(!Ad!3uc5z%`m87C zlKew9+dC|oAY%mtQQqP4kQUWPAvf|<%o%SO<3)9V z6@VG%zLICic(2<06=WVc@(LxldWqB8ePl)1HpYPhX%NoN9g--ILU5ADI(7gBKpL5gAR!n-q7;le&DX8~Gf0%@D8?7E)v z=RceWq^`>KWM&vX428b3B>h41V$xMHTr&LfCduUZqmMXfg=gIx(d<|EYg%3+93#fG zvie;roaimJ0F*>fsX`Gnc1ixX8V_CU08iO`{GBp0z;SxwfqGr%D%z2}PBsf>OkCcR zHW^WH(Cj!2KBuhZeV)MJnu)hFKUfZJ|cr3TW$ zr6U8%C(u%LZ(06xfOLs(@YjEgj}gg)JbeUX-P2Nqu;`#ToN^hqcWGbHAfyRYlp2JRAC!;Drqq?Y~b(&@~}O^HK{Oz|kyN&MeVMbG*{RC6C4^=v}2xN3qaXIE4%8_`PDce5-o6pH*O~ zf~caaeX$bT!=-8o0PFM|rk}H+QdO3**AW`Skb$ewkQb6JFUH?i8RV5T3GMFKMLP+J z?O}!pUVb-t6)hwGe6~|vEYhe5~ z-5$RgdWCdGnpGl|!WiwT$ezIJ5JYV6i3SM(u0C`nsU?YKcvKAP@Ht3KxRvy&O57bS zJkz_YHJ6sC5DE}R4DY|PBJcsXX{**!>ytBfnkJ39b_U3TrKB9Mk*vv5nHB8Xf?CC{ z9Y)|OYJPyeGZ>jmc#9Xegw1f%X(vxKWHTO16cLqjm*Hx8Np$FonyebnUOw_?6aYbY zy)bGlnlakXwIv#WiZBRMA9C$=vqD8nMX+p)n9-Nr)4*Q2v2ru9YPfUWJ*wm);O%7$ zunI#inD(ob4gr<>OhYicBh^4zTxsCkg_@0&tFs>`;2sQg9j5Ryb#4j(|0%jzVI1Ny z1WlJ@ZYKDXHax@SjicUYc%e3GDbNUeOXApT(X8yUrsi!h{SU+an*R#WOv{^WULArt zx&T3lgNIzYifCvE2kr_hbUD_yd^WOe@ip?UoZ+>N@$olwLBtbLeC5%<=rv+_>5-39 zi@ju`9}|nLbya1k$^^ACaq1kHcCqi^YfTniu(}3;1-&-zMZwna?ZoDsq=8)pM#XPt z3v$W{mVBj%a@oe7G|C@&{JLD%($`Tcl&CL`5H-$fw8sWIHlI+T{j)6@NBJX)&(zbaB8 zJPHEAZwP`gE{SriXwv4|;659qE8A>HP1qhQB9}<{LOB-mL~e7baMwCB0Elx8Yni5% ztaRW)znc)(ri9(`fq^#at(ya#&2a}t3q0`@c4HJKoMW1L|1j+hBTL2`wmz-%uIVUq zx22=6ZljCjhWg}^4mm4JPO@*Xaz{Pe`1h-ZM*y`aNR;$Lzshd$(MYnUWuyqe`6sH& zl3O(xTJc~pkWF~!K>CpTyxtx^DmkdVp_ScZcSpVuYmgo5(${POB@r{L+m2p_-r*ED zM;r^$l(=psis^jz{i{cDrUnF(r@NG|*xOuP>SNwn4+(^uBy@O{h1y>1l1FfImw5_c zi!9GEC^ZIKAaze#?2+;({fcESuQvHRPoU(RFE--ji-DPLv1hq3K5pA31AiqIQVp9J z%gqlmRI}FGFo!+eswNG#yh&<%5s~=_IQ5|KMT!`QzMSn^vua5q7EwW77B`B(ezUs&Y*( zcR;)&!xuuiHt(~=;jDLUC_9+z33CU;I}URpl+G|0^V-+X7N_4M2m?As&((L3C=FJN z=+@EB*IQ2xHlN~@`{~22gNIvN&%QnQdi(Li=R6IM^K+^7r)Qs|=I(P;!nZg=k8e9q zzIygeb%-vXwjVzFmxq6Ra`5Qc(=WC*A3aCg-}xzfRbl7Jzka>B^JEtle&4L{?DO4c zTTh-#jeo3a7+OyrA9!!M?mty^y~Zvyxd#;7jnIJ#qs_0jf$`?^gADC%O_i-D4|kqQ zguvaJB;L=%t<8rV(_O?C$Uoa1#O**7W3G5c9HbZG$u;iLr$W9fT@~=2efsX~@ZBy9avHwA1*5UEv4dW3XICXqep?)lU&}#jp1k zvVJ;Lte0xQC~N?-UOFGxSNUjzw5Co#d^Zc!fhuamuwX&Tq9!9syqXgP#r9^?o8#ZE z@ZA6;I$T-4%_sB}OGkSZS;6p%({J1R2>AX<-^RTO?@4rcm-yyWR42G~2^49@*o&q;Wi%S9{-^1SMtz}A8~)B!;zv6|1hljn+0^JxS*<)A>a}`hOJIm$TFVLy zM^%}jkxVUQ^CUNkJ{JP>x$G)x9z_* zsti~OfA0gQHQ(hi+DH)tesh`}9?~-Q^x>-Z!M%aUTAg_$5Az&JNYYxhU`{?CNkcJ$&c%GRBl z^Vk-HSVeu|Sn-ePO-*+uDrY(vmnGhuH~JD_WKES@$Ao|ss~9;v`GU9-!5;%H{oEdX zLROB?&*imHR2!c%$>_n!^zfKT1W>})B$p8ZCka%4JfGs;w?&%r=IP4W>ofc5wKqn~ zA1}+*z|ceDGDm*ZH*hNP_7+o0Xxh}-Tf}g@q2Ma3oVv``O4{S?K?Hbgf4QwUWQZK+ z2k=t&x}dJ2U!D}4LzI)r3nL2Rx$pzBF+`TR7}45 z!)+W>eUD?oOJsM&E#TLO(0QapFotPa5kN{BPCx-HjNx6agmW-&uC(DY7%MGc&rut( z2@PEw${QQpa!6^5hiueaJL0P}cU2Xej2qa=Qeamy5$#YG z-4Qqn{Y`k_GH3j@Esv_p@K_$5TvBL(>H3_O-mmQ2qkU=+=bpy5W#0PsWwazuNc;1M zl$ocFY=dpflfH+F)2lONrk2yl^YcT5*JbVORmGyQAJj3_mN;!Xn7;UT9L2`Mr25C| z&08fL6m31YmKB9`tOrYxdW}(^%XB0!%OSG0O4?j2L8&c(VM=SZJQ$oQ*y`Gw;HRUS zUy`}!z3Bm*oClRWrJ{qqhB*%tbRW?A^4{`#+47IL=eGgwEf;*DTE7$9(C2Wsi4jj% zK-mR$&F*~3O03xN?DB-`q}xAvJ0J^yZvj?Bm9J1?zo)IMU1m!+O58#byB{m2Ajg`_ z5#pn^a@Khd2W9h?*tT*#g7gNi63M}v)$LT-@leUP`~9GGi~;|OUvzhT@yGG0z6uF$ zB!8Nxd#;K)nX0J->T5IbrPKwn{2*6p<-&^~8aa-yJ|Upi3VWNjDmjj%rVdKcJZ2&@ zq%47Xrp9vGC+kO51Db=|3{cv%TFlWU=Y^0ektDR5roG?M!?zvKppietCQt0+bn(Qc zB1|kbtl|&4Wq^RY5M2U`iHb;4*9F})Y5`VtqD4+}(p!XySCFl#!{K*R=ImAUo}0dA z;TojKz2?<%ZYm=VEMpk)2gj2XfRb^Tj+?qqdv=P4)C6>AVF*s9d|7n9a3El zQSfIFR~QlUy5<13FsU!ccum$6QJ#t>KN+L4pGeYfVyci#NRt%%s7*>kYF!MS3fi91 zdK<6*xX|-AT-Ak^1%(d3dVw0e`^1?oezn^o^Kkl&e`H}oUrdiEFLzeXsTtSqV|R^r z5>97N{(5hCyjL=yUBVt4{}9j}n}ozGAe3feWEw;LO{ zg8uxAXFFfT5%$iLKR)?45IrJi+~XwrvK~oq3WYzhCHy^zxtB)~i=|1*O);6ItWe>@ zO5WIb{^#u{jw{+zTT{>JlZfl`x7g=3SHa4oWcXyH+YO7SZA68`~Xm0sHA7c2j z#1AUOs8B}x-ZW0AnA$D9P}dw8Qlbr&!i)Hk`QX6FyU;x#tb=Vbz@7Dp0T!ygG?|%^ zDxQgY0m~bl?gXq^n23%&nuWrN-5!fjU-O29eL$M`dwEa&?niD8c$4`#;>Bm0b&HnZW2HabBnGMZq+bv3v$+`@4Hc~W9OGQyv||K!gisH%D64iW=L=g z@Fx;yz{oEsy%)V`AK#?kYHt}gf|#p-rg5Xs_pzA!)NYx~Dy$!baiFwr0SzW4r4Ve0 zheC^L_dm~g0?2yl&YL!8In;lD^C5D;J#tG$nk84ErP(8ZhQhqh_Tb;m|VTltR6RlUcPwZr?qY>;fB9S*?nHqG|$n9VIpY;W+!YB!TLvL_sz+@qPY# z;-B>8wodmXFby_|_&eIEv5cr)-`%=K2w|Z5ao#xvW1Mn59>2JJr4KT6GM!fEU19IQ z6MTB%Z*k(#N*2%Y(d#MSG*0Ckqy5ucdG;wc{FzU*%<{kswm6iPhrg*Tv-adS7?l!- zht)B>ol-|y__LXU#xmaY9pScY#Qdmem{$4xZGAu2UqX%q1BwGeSf#%LaqXQTVkiZ~ zgX@C83hk5yDcj3+#Sd{*CyqEjqk{U7Ytd3&>Mjr89kqNuQD@+Du;kL}lWReWorYG1*QXnTDetvIFLL8(gEFC% zFBD2A1HwC0n5`Za7o{qi`TN@S3y*pm7^n33$M^w-ON9h|%Gk^Pn~Nt%qXPr%^mu%V zm$|Kl>#Kw60Y=5n>aJ^5fR;(p9l_q@_%jSbip7@ZJ%RP*+fs0spPJ*d`dTaM-@8)% zd!Wg8D#XqX{7UHQg)Qp>xdAR1Eo?)URC4JPf<66{7;g<`z(Rh(sA2-VfJ)#DGHJZ@$=nl`5d#hAiK@q`_gR0Uh~Zj?5cdgQaUJ0JfDzUmE<9y&G@ z(RRKOPFU<2j5K0|R%wNbKAJtN8KEGMEgYjyO|M>hHEEC@n~4rb&} zPJ<<#$#iWDV00g|2s!VjFZ}>@KFAhsU=FVT-8i0N-q+uWii*Sl{=&2d{@TcL3RY+n zBs%1Mv)Gw8dPNmOWkDC9&d8RNYA3m%nH(_QyfWp;1DYcpmb;A7$yJR~$8UtKKal|O znPljHHv0Vk9GN4_%_)c+yp!tgPbCt=&~Cs5bG51+S$8>C`FNi-L878c9NxD)CVli8 zu_CcaVPMANDJ1aimIQon!B(o*hpFg%lR5#|71-H${5_u9mU?O1>~bvI7r*xAH`}zf zUT?#Kta7f(4(b}S!vA$UQ!j_A#6Zp3i;4}|*RNlnV#NyV;$wyLdlI?|u}p!H<N}ke8TOa^Z+Qz6dfJM++T;yM-^J?t#8%~@6={Yj05m$ zECBKB@YUhPcoTbqpDIwe?Qm+j>cSn95Wt_f4)cbNpVsFSWEDLfA8%{0XVmDa_-h83 z!etiWwjoN%t&}F+6$4Oh!UTyh9@ynbMRX#UTtaR;z{W33y^C1)ct0i82eySf|eA8}C$2};3Fwf7!PFD0*NRaayc zXuxS{ckzVL0QoUA4!`Pe+_06Z0wjOYE4T8Ilu_*@RrRJY{U3V;5DY%qgWZ%O!~@P^ zn8^Rg?F!qn{Bhht<(4Y@Vd`6JTHm(9bUNCf#Kuc;buao=41-2%_xUF;IN?>L*ivgs z85>QnZdAKHx(kg=3_!vP#bht0=6X-;ZM5&73TXJ{4j@9BEXE}=Ja7}L!$q73?HEfy zu4NXMPm8@mC88_}e-cXmC%Y_o8MR7NEYLMlc3>)=vZy9|`-GV30CddBu&o-w4P~1E za@0soA&Hw64Gsvy;2~t^3q~fOz+E}nA8 zP!0vE83I1~R+Fyxn#4H4(7f)4a=Dow!&O;|>bb%xbaScxnr2vkDwV2Rde2k*_oX!M z#d2zuVyjG%>J>6SlnGEZr{n^@l=PbPCqjeTrPVO^t2*%##DElp2tfnzVip2~B?15Q z=`*p=R%$)VUMXF!A-Q=NI@E+Eb$Pbw%LJCyyfcmEqqBT>g(T|9yfSA$R)FltCP!^1 zM0J3zBcI47^G6S(jJ5pedq^Q)DX_Z~HmUwLXR>O+eCQ)=FsYEy#@su+rgpCO8^fei zkC{%|u(^8F^%M-h_@>&<>9xfgYz2(7;HBVlrvofq++&q5HN^$U0@OIOgCc*|I8Yqw zb#5>Saf%y(eR`Y^wR<-Ub{_y%Pbq|2hcA+e&k^MyBK>X}*=;WKX2Off`!xQ)a%^05 z$ADG{9uAz9BFy`TFtDb z9-Z*7qyq~mtc%#so?ooEObEcIOrfNWFivis4TpIacj3(W<>~I>g}+mQmHn!7+KzU9 znBoEqGPo498KTU73>nTk(+xTLe|@(_dWlwHS{ zRLMpWZ`70=CEgO|?CA`ze(@^4vif-`Da_VufDRX$p$RhzW1O55;a)C)MabhdLOGVF zbFd#PXZF9Jmx1>56xyo5MNy}O>MARi16#3DP(2|)F*2*CI&VLg!(f%A@Wk{{0d~5P zhLJt~VJykX%x`K~#HiQqiyzHx5W~^ii}j&W;VsHYyablap&da47is{MX*Z@z`#gOD zV;}X6Fo*UY`-I-uc>LtiCXcn;#q!;4Y{57}{8v#Aq;8O$PV)+#aBl}r6jf)v<7t9z z#eP$gMDJ~&&w&Bvevj6^JOxfPpC$3E?WIg)3Q1DUlf#*(D3VZ+G{aJ@G>Z*bXPFE# zZjnsQo*bOi=x@ua&ypZnWePMat8th5G;T?hEsTQbHyHtJD*u4@G(!W-vChG<^4A?f zdTFRG+pD0JntVBBPqU@DhmLNz?|7bKOv7NrEu_cJHCVwWxjt>;^~3-x>9z~n7ClZT z5l}V88~kM(XD&Jxb7sp5m4y&i#IsLN5{Ju40VTBoQdT7hyU|OcDlr}@FAR?v=5mS_ zYD4*|R=6p$Cg6D%Ef0YB^ia|qo*tgO{f{x6xUf$o@0aw}8K1K829lNVpkJJDTe|N< zMX0zfnYnSZ5`{m$ev5}WTvb{xg^WH@!OsCuBtI5!PLx!9?XE$eU%o2K&y8Ep&)+hu z39_E3#PYAnsVK#W->_G296lmDUNVu4Qs~yYeU_i=x7Ke_^_27Sn{o3KOj&@;Q(ytf zkhg}+X{lW)DTt`D_3*-aSDCRsq411rg}y}#)@mx1Qx?V1kglHYpb)lR?G?hfd?p)q z66*rGu)3_247QLA8DJ%Ab2zkvz*STezfQ7^tR>(^McDB?4!QU2^vlUByiNkiQJKry z!HV(9DJ-B?pj2&&`WdS}swQZ5NP8!-2fUb1PJ3V&UL4gcW!yS8x zNdac}-?XFgu}xI4P4!|w5tk(yFr8~^X_ie$*T8b)UcK(FzPLpYy4IxD5zJAf9rSu6 z74|DkD7@}ODA{B-#E0QMXDo2=PF%6 zL$Xu9nZ;ae8(QkaYhY)tZG+2+l<26Z@|AuzH>G~HB&HAIuD90)b+BpQqcY+w%~4~t zl5sZj~^vK!t@?_$kpmc}K`>n1$p za$A(O>rZ;WwG!A|s>tZO?A3%4MlCQ!S5H{#B1IxTBwP7~F)T^m4RPo}l(4uWmzR&s zEp;oGwxy1x(zLakLI^L*&9ya^Nac^L$&BFF|bO>WWbQ~Q+GlVVyqGTHL38?E|H6P33 z=DltnudQ)$@!uq9PaMmh#H(S0%gJd7ppAc+yTve$E|A+WoHV`)p!!x^!kH99ogOXWn!LL;(>{oDNLQs>2{s`(O z_HY?gfnvcK(vxGAZm03Jcti!n2Hv>Ipq(cVcb`4gs4iNLXfRjX6~a}6kryTw&w$5} zbUy$1a)NZC5M#oS9E>hc5acTfvDrMp)(s-Fjmv^j-NmpIIV^Rwjxh)`#eG5T4F)wy zKT$mR+xm<45YV0-V~7`feg^>HdC-$8H1%CE%f+vu^sdUo{&OMEjpU=A)^SfkIDPYy zTGGV!Tj8h8>Qc5xB7o(N8sQ{!$tudqmmu+ks7wqSl{U4jv^@Efu@MDTB@1bi;D9Y* zFv_1Yp{_iBJKt30t?U&jK1vO4-Gv1R-K{T7 zah*T>ivWaz(i5#{mWuM1&ZGk^NYgJ0vM35xBz#vGoB2@2U!I=Deou+gF>pubk*7kI?0Bs$ZSh4 zVLo^MuWV`b!djBlu!VOo&(2`2VDHqZqXO)FO=2$27NA8hhUUI@zXt3io(y~>pTc>x zJ*8^K+asqYEm_?J2AyYX3B%tJ@Vi}Uozpj}2lG|tFDY8uC=oj9U zi6k8|k4Kqv3UJ7JNo4dsFqWq6vefO$rgzLef#qAA`*5^##`M(iz%f+FtPHW^Cz0); zfUj{t2ezs@^3qzoL;h@Zwd{t>uJT2T>QjWYs9W+3N9yC_9=!`)s~)?4FXB2J$W!gn zBd#R+>kPgJD==+2#h|YP5M{JNGu^ErN$ZcSof@ka(|LAvsxM7zT>%y1>cm7r-Lefo zc#TbGhk>6IWK1H#NSz@Hn$xmOVHHAAQ+%LR(P5PkQ&Y})W^?FCwb57MGgS9eRO$k` z6x*GWt~P-R$td&{NKz=#t=LNtEx%%c(b7xIQ0G(Jz^>#})Xi#KyEsj63&Ca65o)ch zic0{}1QbfLZ=IV`CkI7Oxa^0*Kt0x|tZo^hmd+1|uA~oLmQ^ONW@S=Euhfh7gV-xc zh4?4ohh$;n+?;(PZrYDos>xRQjp6mgq6%^F_X(tzp2E5|yf&Dk_xc#sqTiYSCa=0M zHPszNY9tFlNU{ExHnvT}YT5+`a(4mxfe`_mpp&&V(%ufPRYc{;DxFSyW8U?z z{7aR*>uo2^|DbSsqR$o8+Q@t8%@x)so$w#_l*3|P3EFOis^qc>MeV15a^eShoM=mv zsyL`-_r>gEk+!gZb=H>P6n1Rx;+m~{-Cnyf7Vyu3%xfp1A6h|C&Rg(b# zS7Z)3Xo=W~dMqWYw)C-wlbap~y7aKz_l zvAt+lwp-&842Rt4gYb|%Z7D=CV@4sctTJY@1{Sr^iUvL+DB3;~A>0Ouowm$}@)04? z_Uj-Kf+;5n$<6+8STPF7feFduI8A|E!;!Yysa`~0yStDM=0UQyfs$hCDGS^r@!&bg zWiq@NzV9KERq}>{AR%$l{YvEbB)Oib1447Jnbc~^PC2P1A0_Un z%0fz3IP;kv3nA+za0RfMT3SvK)N_IQ4fSlGxg?XZs-F1OvMiBDJL?#SM^;cRMOXD-9o|4(X)}X`EkS=h*5q@{;)(?a^%X^JegQB1!Xq5`RVNTkk&o* z4a+psJjcXi@{}CZT-O8~ZtB!e4N>nys0d?qC9UA@cT@vvQO9Z@2&QS>v2$DdqePL0 zPi!yaTiMW1;7L=z@>B}u!PhS?S2CK$EQuXPXlX7gOibG;C<#i9FMF3)69nZreC9`C z^>AHX9~qk^6<=}WX4YkX(q$s7n9%c|=TbitOvu{CJVEWo{)}t=ke{nM7|#+F1@8Wk zSEL%6;$v*uRBr?X2a3ya9t_8u0XZkBMyW!j6yIc({_%BF2yf~oilBnY1 zFYo=M-pxof-gY;mN{3I9vv}N|^6XvBpUSq_RC7vmke;(KZbGC{KheCU_WD9&Z;p_)fZI_Ia0w;oY4{_k zs*igs`;&2FK#L4yW)W%+8VktumX2b%xxn{~;ek4W&Bkc9hIh{DW4)wOM63It<`d!~ zR6q7830`+_%c8bCz1F}b;7sJakCIt&}dZvn^DZT*+EjDpD! zXxN4=LG?jnoh}+xdKSSrI7Xr^2~?_SH5gu*O=M^z&49Inc*PNEF{SDBtMI}?xOp)s zs|8f{K}bb4=n{K1UFhtpcVm&aUzy!P^NXYLNRZT+qTLLa)k&7GOQ#{c0*ZCZDL2DB zACg(o9z87mQ?g=orRB@iK_PA_+Pv0+1lHQ%>PA=08tVUdBr3-g2r{Dy6`VSaCQfWP z?}=#Q@e$i;18+*^7QauJ=Qnv9D@Ik=S$8ouQWe(R(jKr?h%=FP%J<`R1BG96*R%u5 z#ekkcU}CDoxYQewHSx8%Gs3O1%{NykOg!_E;iRl7GHsjaYwq&)_U^^U?ols6B~AQu zEeU+s{|YY`ybDZSDzql~{E-2*p%-w6=SH~nWi;RNy*(Izjr(AY^=HiVTi%LFp0D~} zrq-eefGzPW?)eSXl6(m0hQR;t-Mn0b-1TnWx_PTA{P=`Q#VAZ-G2B(k^##RREGfZD znPObx>OrXGH(Z(PiXu3yVHC(&GC8;p=prF%9$HDMm#v#)6Zll>Du`=tD(rf*a%>F& z5+@SzEY<u=7K6|K%g`JuC3Mn20J?E{ZmMG89pn3(Wm^Bc*Hbl2;NJD zQZw6N_tw5+?6NP9zrL#_sbzKd*vAIQ+wwkEG(#`9YHA0N+T*%!2=Et=CB$Bs&USblxAA;ru~a0m7?wtF z&L5X7za~;?uY*A`BSOPVMnjw%UQ^Zg=AoxB*1*DGzvgZ(ia4{2V+1CtH z8CE=pb#F0;YB}@HUYW>ba6Z#@=;O7s#yEg023v~^2{bP^#2U~MQz_||bSghtOVk%>~ zP-VIpi$!J#G9BmbkdY^KJ~J?qal9qdv!NvFH!BTbzN}-6P|zM8YKVdfbxziwRAw0ilLtp0l{J<<=<(xvR(Fn z#jeC5e?7D!;Hl>M-rsm?*1})EAjT(2D%o0rk<2w3gVc+Kk=F zxrSQH*op>bQal=UVeM$|ageQMR*gQ&j8#%)_IqO=l)(~ZXnz!|;sZJs?!s=7GhV+p zZX$k#-zDh*Klm(A^Qh5OVqyvxP9H*9A&w#l=2ihb;kB@wnNSnRseslk@AN_K;N9lx!d2)%j#{)jsNu`^T~&qCs2Q)cJ5c zVaQhR!_@^0wN{g>+(mi!2&0xRl*A)7r!&o>m|r#{^9#^`udp@enAN|egxd1A)*x?b z(=#SRi9o3fM<=5=md#c(R0`U!sS~H7mUb|J|8C^xWSgRtgzCu8OEFLaim#XgA?*2T zXi@n+MfOybjFKwU;7mSXHR8NRtxe&Anvxk!@;yk6V$6y18tPy=8!Hu5;GY4v*4Vo~ zdJV3rKwnEZ3Dkr(pB@>#!%QSAqU#LIoPyy8pPUcr+3t?c7=a1Zba4dNqX5rmR96ft zfOP`x@XY@wua?nbQtQQimq;S0V{I3+!QJ%)SNzCoHXe;@l2sk){e9y=GTVPvxE`3phd*Dk{q>^ z5`mHkHjU)U9=8WaqwdWc^&9Q>a77J4LN8hwDez?*8oYP zwT*5$;-|;wmqXl8mcj;Uup`FggU0H=tgZ@n)ff}$ULG_R8NX4;sH$dqt#; zt&?4NK*Fhu%!)Rf=tb*k+77D=4zilC6DQXrM6J=AHqYW?=i>UT?@?~HcF<>=?D)gMuOOl?N_hXUq8c4K_OmZeox?Z4L@3DXLqyneCy?A=h^mOU%%X5m(uXbw*}!R z!}kM*7>Kj>PB3N*B!Lf}t1IU6>WvQNyDpUWZZ1!UgPX&RA+B#8U>NwsJaWCmtpVs( ze}|RNZFRPSs0wMbC7i4Z=o@0zl&}n0hdUY+)5cBPg`AA#(`3c#Hk#T zjFK#!d<{heD!#OFTTKO$&wcF9Q{@r|{I^AvNyw>_zjkj;&ZxO9h^?tQN3S;5#BNOk z*;wz)h4WH4U_d|}sQ%5Qe{r}AkJ6;~9Aa5di8;Y2ZDN~*ubvs(-A<#UQ#x(&6KE4w z)G?wgdM9s249&Nnaz<+Cql660-cw5Kw85Dq7HJ9`rM{u|+Z7oTs`^i07nqC)@#^i*`fHYx9 zT65Qm8@Lw`-2qm9(dJ>$g$03#@8XSZ`w10Dy)ep{Z$me*x}f4 zMOsmdy~m`Whr5uM{mWj=oV}nE%&6^j9BOzYLw0gjpeq4*014;iU`Q}^jRYxnJ+!%j zKwCsbAksTSFo)zZY0C@3rc;1ze{(4d&9Pj-VG=JHYV+%_#fy2~M@9(B;PW!)u8TAM_C2&XnfYgIHAKF&po(lOot|w%dbY z+qkjW7+x`obor|lABkby#_CFTM;R%^eCo7_i!d^XMZWe%vw6g9Z&Tm3E$4wpQRxRC z^zjfU6^<>@^Z%mgvu4bKvBlV0W0`lNaQ4|a|b4V~M; zVDW`#y+Khjpix4Vi~-bXw|}ucc!gPqNZO#mDnM66sL@wf-z^F@VNkQ1;L+UB2C_|$Z!~skW%I@z< z)YKcqHC;g*^iIBGgi2Ib&CSsWTOu0CXQSXzHw3PxJ!;gdDKV&wFmMy;R(9MNpUbJF z^X@wy#nGkFNe{_^^;i+KS${-dBL;;nRmx(V*|{DwWAHK^#Yog7m1JJ}W5;1JI$Ff} zBM^&7v{vz))3JErW_QYVrc!B^M;q#&&|C-mQEcm?g-qINp7h>{Q(buxW@sD$BJq5% zMjy5&ViA$3wUr9v9sc@j9^mh~+>J}jj4YHO()0P~w63nv`z&Es_6R01s**W8>kWD% z#tcoF!*v5VUh|uR65+?wsCvpiMFkZP1!?a7=jKTS0Hk9}L)la*2mSz(BO+Gz*W%aq zH#q*d<3>Z-CnaTQE=@=f9$HmkDTNKyAT6@Ml?-%@E{;??_32(jxU5Jk$?cf;OUXz}_;vOWAb}1|CGlmeVJA#5MnFD8c z9(9w?L^uVTeCgP3v%W%PK=)$Y^Q~tIG3NG6vF)5d+5U!!$>~bQW*KFp4nw1pvAc8D z8TGC%5N6oIQP9@m__HM`bvVA?I^4Uz^vh+R7+8ELPaBJmuzje4qcgd@YAz$e+v(bx zwrsu=%*ZjC#~^!%U1>F+d?SYdU7RbU8pcKz+(5&HxL)o z(=?@?Vl)YnSZOI3wfdeonoBd9{x3A4>p-Z$ z&>p!nv)s$YeIZedEo*HV6(yMCV7=&qRiAT|ZX3=&w?+4f08UIzZBDz{@Rh0LjRuf)XwY8a=zq-TwyHwp#dpkm)%*eAqLvy_&ejHIH>z(15^R3@>}n z`XhDBp5qJn0*`xxcdaHi|97_cHg`KOwqI@1Zc;vBDOWXSp|+YkFLpYA-Fl4>fIZ&| z>bzS2*X>=XKT}Jec)RO6JI~hl*Y!;zQ7SH>CVd}Px&Z?w1E>KQ`=jANyg%={qrP08 zae0lX1z5(|vlEw)i|XjS7>!`gU)-3@Y(r+2j8UrsAT-$FA@$e_JYmcD<7~@l29IYE ztaw#LRUsa1uYrOvLi=gGZH~Xq)_78x-qPTYv^Z#*Z7ct5Yq~> z;G*}~9@SCO#`?w!1d42dES#LYxRc3UNUE-{m)jfbFEbL0rD#9Y&S5M9>rZHcvn`+r za?BMDW6_dtWRxSY0^Alt_u5N@iiM7G+ADz{t3?h*Rn76mP+_spptHiz`9 zJbki8#>N9NBN2qoOfvqFiE+Mhv>MlR& zk9>kZ5yR8XQ@jw)T0Wn2j~RB52n;M^@fyedP?@!#UjFFc5r*}LKl~xd+V)ghMTAHa zr&etnll82J6c}>dA|gLk3Sc&1dQvwMcd+UW%gkAzI0dybQ>hk$bC@}%?3!+m6y{=1 zG0-FiG@q8@qA9p&0~~!CP$PaFv`g5nYd=V#3`L?5z?T05TG^RK%D2Bs<4MJ?#U>zQ zDEmW6iQhZAKC@s`K2g7NlZy)aDQvvba}zUQZDO7^&J81`OF=sK0b3c3)5{A$-fl=) zH7Uex&Y@%vrT)w@dw&3Rb|mT%s{_kwZ(62An{z+bNn` z@nW=0N^|>D`w_t~MJSLh&60f1r5XjW)y`zUYfds31VM8dWTne7#p|p-RPd~yoWN2a z;+|G9d$OEwik5rLb6l`_fqxT04H-!zuX2m2h2t(KO(d6V+Qz^wrH`=6WW;;(rpGip ztSNZ*P@j51`K))^y}pPZD!TEfNlhhEXYU|PqseJjDxAr@t}#egtbpZK106qSPAw#z zH%hE1Rusy$wM>kAgo{=i$(3#T8KEzzo)|}4dWG!z=7R#dl98JHPEI5kMS(Ik;V3}qmL#*$E8;*hC0EGlhaNy`*TXoet1 zK(C=9XGE0)91Xn>nvc+&ZA1d3KU6Jb6*KL@2Uj3ux@UHQ#U*S8T`ag~l_`#p|A=9@ z+#L&LZW>~72yw%yGaOvp07dk3LnbGs-owvwhGmUN;a_y7qo4I|5bipFH=0$7<7YZ4 zoF}53?;vIdo)8;1+`Bbn06#1Pn>-~E%GJOJ8Kkcdnk;%32lt(U6x-Vz*z8OZOI{bT zI6w#`NDDaY4*--*y4<>Ldr3s$LGyZa0U+V0E`3Zql{J2{wzBezc$Od#ge*dhH3pXg zk6-!)BT2JkJKZ8QByqFiN_wQW9Xs|C01)(ECGs4J*0+iwm)6pZ(7hSX@~3oEIRC5k zEkzO<7B{p>q+r&a*ey>Q0|6k#cR_Xw_8z{R!Um*%$NO+w%nS>VOh#FzVFyXSBDs?9 zXwSu0Md8SR3wBMaD#l&eP)8BNNdd?gu|d@Eiq=n3L_Mu##3kj8*b*u*RS#E8qNEw! zd0H+spB(+GlyZR0>YyaI1X=*U=_)sIW!Wu`Sv_3sh~Xlk8r@j$Pk0f;zvh)bD#O!+@S_3hNb_1V6}@xJh;6HP7WnL?k}a>?X8Vld*dBMgWG5}$33_=#&z&Zd!&7-q?{L6G3Y;M0qV!dP} z%2sACy=$Zm+OD)>|r(eY8~ZMiXwq2HK0dp z_IfW@x~dWjW^aOa^rgfug4MC|91|^+&Uc{8-(ZGkP0A!o?=&RY3&5vc?o1zVy2QIh6r10W(TPP)Gkc6ay z^rrO1nviR@3kY*n1=rZZ1AnEJ?llT$=h_+?-$zgtjy1GeP_j$Kupkb&!frG03T3bu zaNdA^0rl`?jX_`dF(X+)%}7{wKBP+V*dY4gaMXx2kNO-IB>KtP$oq@7iTlgZf%T+) zU`ynsZ|G_WHB|T|S`D*q#btxfhi#Ew?pK9au^qc)ukVm57T)09;V>kvlPA`JQWAR7 zmTjLf_e;C-@{Iygp!TJcZoAPs_W(2>y?KK}c!iCm&&7#vNC}ERY1gpG3 z6ZxJ}m0rYb47IPq+#=&qW>|{hcLnp8wCH$(Iw1O@VA^B&d~P6W~&lW`a6xd?@ zCJ<;YKZ-^;U=k8^UDN^_+$D|y)$|s*{!I?i=n+wzxQP|HHl5nsyW{b+mcBb4&)LY8 zhN?_!$S7vs#&DDD)RypW&SsGOWLhip4{ZEy@Y@@?LawSI@>Bixmd?+9dmC8H^y%lC z*3!DY&(Z82SI|*lthnhK*s8`NiR~Ee8^1>zg&S%{?O^Qe42;STXC54L#<~Wf%M!Dr zCqrZN!5>f2(~35b>@TQPUFmxRw&->15MrWcG%6$t&33DVDD@47M;jwuy-=ixV(|?C zy`un{M)t0#qEws-u7m6|*@E>a9GF0wi#j~l9V}n%>1Z=0oOLI=QC?e70WqBG$snS$ znjT~Yz;Htetm#JUF!*U93<y-~^Pyw&f%r)G z6>a?yNV0l1R#8$KVYg1=UBtX>b%nW+(W`PZ%<0Y;^%|BXa=QfXgcUO+)P#=M;9g?g zl%>_Vy#|fh40jT!-w_v>x~lP!!g%+OiOvB6LpJaXMtCAmaVbXcq-`vsTa=n38iX-v zuCWtQNr?AFS*W~8OI&c_GF2@-mSlXD^0qltR|9MJAvo|`WF-qnCxbloVFIpm%lX%N|kzCrKQKI^Tlzp2C-EU@u(df=KVM>v~lo! z-jXO>uA!z{M`n`c?w7bjFB51+*U0U+yl_f2+IxC6gWXne1K{rU< z!u&+=)AwT%-U)JAX|L{fR9}rYI+8@i)^6%rq*ZAn=Abo+s_vo0umd$EYqm4hk}|FX z59Nk5o`)!Gk1$|au%z}N!D{ZlC_)f?g`XKTl`dqy<_edV^g57D3k-e-%V1h z77QOM29r*H=oxk^IaoQw4=?XyR1HZtX(`#tuZFO%9}VFRLnJAqs&G64oCUYVN$;Y^jY@`C zA?zWvC$|MLP>o?!5J5-S^0<*C1lXr!mLMGe0akGhAIdPl18!NOoRwv>MK4fKjZk1> z2VP|wK5=>If}=?R*BK)9kS^16h7(QQ@= z)cqJ<1Il=1e(uGqaAzJCRTA7$;6>J!gD;3ExEhWTHZr0jmesE4Vj+ENmWco|nVpO! zl6@e=JI@3eQ-5w@&te+Ep^Km-wIil$@?_>8%ux7iYkPm$+Cg^9{XGcG#ZkX(*j2y( zg*}3ho6xU6_P=Xu8!tdW$eFpjw@*b8B^lbL6cg3w&O&|>cOg&dq_T~qrh3pU!pXUW zg2>zlGRlR%HbyFdpp2!dj*8jQ*5iZgx2FBes~Sx&>g zAc+vUWH)j)lJ^=f%-%jpju0q_*+BxLcm7^O9u?_cde6=_s!e>d+|>Rvl~ZEUwX!HE z(=eYrHLlf{TbGc7jQzDp5GhKCbwBo#d1MyVM(cWf(d%8cKL27BKVmD))sxU(xEz?- z59IVPcHWRd2#k>h$oUaZ(FZ-M0)o5Tgy$L#_NR-|&Oy`a@Xk$6&pbmAFuX4u=)oM<4} zHCj#wd_^EIatt9e-Nnt{5#%N;FpE4K1!7l4mI?xJsx(t(%jaHH3D;q;Xg<~~XKnuP zd{XRvjQOlskH^ESoBi|NU{^2ySyZ<_RIFZ@=q6+ki~3%snN?er3Sh5XkXwzg%n;g~ zPw6=@K|wupNg6fO$JTgzn=hXSg=a&VqC5;mv-F~&aR;m+rj2AVgIK}2!p)8S?cMJ? zdz(A!yX*MKlTD+(C`jb2V~y96$yeo##fi$&FjKBGVPh*~ao4drWi_fbOt{w|!P)5R z4AC&DC{`*6BxNSx70NJOK^Y^#FHffxB)hAQ7g`Z*csJYmHmVNo&MU?de+BpBCDnFf zLw{gDFm(C<%4TC_3&!*eOWH7koxf?ewsReoRA~@%v5DE22*E~Wh+UrS=ED7rw)t6)~J*B{;a_(sAL9DO{lvW$9 zPscdj1kwg@`o+(tcMSxjBAlG#j(C6`hT#i0IiUJ=2L150>O2$5r~X@J(-Zj3xN^lianTevOqU=Ff;_ zb?FqpQ{u>>|1g&Lj!^{R+<%a2tI~Z6at5xD5rLE>o=Iat?vfH}5Td8_lYygm&o_Ws zFxf%uA=jOtP(v1R(3ze^k6%<00(cia2@`jeGm4Pyp`{4ahUW1>X{PZ(0wSC|!{lK= zs)Isrq#2uC2|ToUl={mdc9QH@*RvlsRbrZ(t=YN~1pxYA*1ijCtK483S#V!Md8ur~ z{mLEYVCZz3yhgdBw|8`Ok`f{TiwMR3H!!O(JQntHO=~1ukyi2Re;E%`L*S~n8LW*2 zByd2|KM7e4ZlFC@C;e_=c8X`0Fhcm8PZfj|D-s#y!q(=H@oLLS_bv}oo@6VO0|Ba% z&522ggTA9sY244$?rk#0Wo@0HSq?Y71p>7jl zM7K!H&>#<=ao;4VUB}3o}#cR+{al!EpsK&gGv?qE8kd!xQzO@lf5b z><%=Szs4os{(3E!sAaEXW*=79f%}p&Kbt^7W}3D7U62N1wqWscS=waMsqa37#%xSx zNx8(i*^9u4_OoIHD1lR6nT9BbQ84iSV2^y*@&Z~vjmp=+i#v|ZBRat;?+it=YqdL;k&{5mEK zhi%}pkB=#wkqFVPSkUR>^_7fTCZZ#^;K|(3=#Xwd@ocO5SmmiTirpX5DyA}et~q@2 zpvr&mw3$8-6i7AAXeSVRe*$r=OyWwGB8utdWDMYVaGWsnavy$H8X$NA^TWr1>KTWZ z0TBJM#AojSgOT%$)LTc$KDwkQ+T$i1835$;^UBXkP6ynHTY3BQ;qu|Kf94xdUuU`f z_P#w!C{8EVxTOS$PJY}KjG4a7fg*0_U7@T3I`wQ(!U{1YM9yN<(3oxmMrBkJ`XLQC<%i&uFdZ{CCQR?lLuiyI znKH2l8onU(KxQ{)N`2TVVP!igHgLVDC4hU|UcKu|2PTqN(tnIIp)-ls+R%GtO3$8D zH}~yHTzlVOzI;gNPsi#FDq{=YJs>CyLdRL{A#EB1`Dnn|$Q->jAi`N$-hX&I9yqP^ zAyj}jv$OI-~OaLpQEp4z0FE?$!T+&N}!!%kdO?$lx+LwKo? zz(syX55q--*#4+H7;_;Jj*b*%dG(8(7I*O^IYX#E)|#u2q*pMd z57%fo_7*y>k9dO_5&gF*BFO0#h^&ng_AD$h;phqqnVw-dg1Fwsk!4s9_>5aRars{4 zjgS*RyrX9X+n&f&V=3Ao)8+IBZ#6#|@-ADZ(n}~l3NGC+HlMY&VyKD!ZyqG^{3G~? zR+lwD-(>hBLTk{yUY@AduFr&=f#E2yP2I;CC`nn6z${70ye63SgI>Vyx2;E!s0M9R zX9@5k7HcRmN8=W+9cWI62#B{I#rj6_tuSHxJgIPd1M=UdDnk5_> zl;t8yE*qAl2o4N~0$iZ4puozz&#`J#53KE9b9QVRV~Re9Pe`WnR&t^uvHx{i zs`|*_!;GizyH{7Vm6+md&=6X}PBUf>!&j(=)1^XbPfjP4z4@?vDJKIudrSKJWx)CnzH2j;N(UBq_;j8zvt1c9V=(m0G5#; zs3PeC1D^^S*v{dSwTX6Y!UeayUR`n8&}=yV43Z-%s?+W?-KN`W+-si?#}lep_}uAg zA_LM6yG2TbT7^JxNVuzjoN5yFkug6stnZ%&u%++;9WBiG(`tTy3H)Ks$w6<;J$a5y zi%89YA%<1Ij87&R+*H1A{;mD3=*9N-{thrtFAmF!B_aE6j6W1N0#y*ElX8UZdybv8 zHLL;0J$`jGmMTE3aPW|{lnI-rq%8wwH_@-j6Ojk#1QO!!A|e?mC<4yzW1!rP^LfdXJl$yQBGDNMahx0IL0Lqn3!O(-g$0-6d8PNEwvGo2LTqw3^f zbA6zJT@21i#Tg~shBd%=FDxmsIgG)H}wuaBnQH^%3a*YA88Ep=m6auF)8poH?KWIE&eW-?*B~FRjJI(Q|gd=R-lhMu7NMMg(jV!3H`=NBaPEa39RS z*2|dv_d^I+9`I?bL;gjxm6~0|qew(;%0aF%+M3%4IF}H@NoE#Uz1nMdG^O0+$H>VXZUF?=+blS!Q#tREw#8D)aSEw@0s$$grAX)x^oW8;-K459 zs6|?kE8W_aVW(AX2V>DZ1F`#CtSFO61-Sc~C;Bq@uJ7`2^xq;$kLkSDKu z#wW?afE>Df%0#rjj*c%x7=&UVTyaZB-#mQUr|`SK{p{yYL#a=f7Js4G3lF&Ri{G$& zfD}y>aYz8c&M^f@25wNH3kWc=paPuOU{G6IY(F;Ug{>+3n#?8I2=^}CGgbMiq2W^i z*ZkD#=$8PCekCqGrB>CN^WzVfQU<)wPQGnZ1uD8_wxGU?*-5A1cRyg44gYJ>-=Cp( zmcr`rkgM<&K6{FPa7@U9wWZd<4=Zo)FRiqe?>|{W-9xU(m!2&Cj+3U{CHr%DfH`TN zowvcB@*G=q+-di3kFa5&AN40k*U0oWITS;73IvEonhC?v(d{tMKvs|i zlDHLf@I%}p(oK{$#;Z#$88oR(NYUlN?KBkjTTkAMF6JQ}=}1}a&ZP3<44us4>!fjr z2)A+M){0+4ZRE;32`nrm!g8b5wF_VT>2PqP*~JFXtA{)4*7U!S#rRQ~=P65aH!c0w znFsdjF@n8@lj7ONMIX%<59y649=WHXd4s%9Z0=yc~F%ta-bIJl}&pg*>gB=tEH)CNh0LAxl_ z3Htx)@ecaqJN6qM$D~g?aVt5zHG-E~j$k*OLgHsV<*&m6=lgrch{}EdysA?at)1fk zRcI-k|Ke5+qej>B>;wW>PxgZvvL9&~e$p|OQ{~S5d}=V%L~(|8$^KJ^f8IO(aj!Rm z4%KtkE!7*w&f&eqL_}Q->H`-U~mx83Ds|$wK>9EnJ zSIAxEDb#_IBdMg=5nz-Cr|}yJK}%Rd)ZUvZoXK5fsy~hiD-4=D&M>C-KnqgXE+^O9&RI8SvVuO54OpV-OHW4{#*uII;ZaFH7qUQ?&) z>aqK=OGsRsRH2DA*l=X58WI)N0f)F^37gfN4-mNG$1QXtA$ghZEG1JV?}~9)BMCiS zJ=Ts0v%Z}I;q4p{jSe_2-QSIyOO_i8odx{n;z*+}T&{%S^ZfMS`YP&Ey=PCkfS`rR z(jsgIr&Y#3;vH_Jrm}CePgFSQSG)(Y?3jv1G20l!3eXSIghu7wUzXKZa9*Qjpgd_n z`jc%$9EHS>)#{nw`p1d5ouF z<|o=N{CPC}ecX{~;E+}Sdz8$wF`~ntDvP0;5HgO9i~@GSh8gBXXNss`T!!fcuEf3} z;}6s|#URCkGG6sMnN8|jXJG3HbHOCv%`BE-h|lrw&;Ka~mzHmo(7-~wzh=W6K! zBw+Kgh}nd>ov7%m$NGxE>Px^53z+vIaqiV+pl>kua*o5?$Xe=~#-mK^iJYa0j`~fl zCp%|#2p#VUIO%BUF+RRTQVb;ple=sWy<2nYv{*GH73MWCl(bsM1o~Q-fUm75#AX>V z*>LnB$AT?1l3oTE9snijW0m@thKhci-4Z7bC@SYvE7i_w80cT&gn;q)vU}9SI(8gq zIGILq{OBv-@hKItjNOXBvJyGYp*sj#TDrDJ9u4m8AR^dqQJMx|E~3dRSC6BtCCwQ+ z$vXuuF+P`Oe6@V_czFx~&D|^qF>P!b2sBGl0`nflUa74Fc9BZ5)19#j9}{ROFsyiM zC>pEF(G6@J@6$TNQ1p>v9r%-oeq zKXKI9dE6jqYk^u6;ACYftYX@VJc6|Zu!o9oVC{XKF$P=0r~+Fgwe;M|tXhtXX-Zfp zqh88KD^xDta!b#!d+T68Z&q}A=P=(b&5ioK6i=lVXQ_3${_X3q!DROjfswQc@MYXC z59PUIjsQ*B^F!2a@8X2YC2UfCP1P&!1AU1ILUQH)7F3_h^7Jm9qAzgn6(J|8v~g~B+@ zk2XmG0G$topkiqmpZmfj*jt6UkZ_#+dqQq-MW@8zdM-vF@NH0%|9L-rGy&GCryi znZEu>mI=lQ|LT&Bl2uUTgOFP zse)o_oXP2sn3pABR4qATboLm0eUPHmdtsjy^5j{Nv$Gyiv1RQq=?S$E5Zxl#8I?*7xl_b#N_-=YcMI}Lpa;)RYsj}f zh2bd4tadTlhBV>ADeS10zGZB~4sc?{$0#a9M?fP5ENqIf z=hs+hEIdHUqeK3QQv&7}((FV^~N8ZJ3UBkL0PG)E)V{Gh;>bTh5Lre5a`fuJ#kNrSVR=KXEuJnTSz z%sUI)0{$3y7z}aoicB*;9^})*UiBRfMwVoBIg3m<0nj$h;(I*d_i7N;GV2`v<&nJ~ao2><&I5mOcF)7E9~nk&o8%Z*0nFo1wccuY$q zNbn4O6;&>?nu}LTzT+TnqiPk4Q9Ge0Q&cJ;Mu}6VBTe0$5Cpi$JX}_zXqY8PAhV|4 zDRT;v6A?{`gEr3*qk{-Min-zyZI$XO4GMuLaQpP}WNWn3-tbgkBo?$tPp)=2E{qxJ zTUZqxTb>A63gP5#bZO|5vN(W=i|s1nVMHKV9}KBJFy|($xC31C2lqvdIR!Eod#Xz; z`+glDPR=+6AGfBd_usLv)ZTNS@#q>h9Z^sL`0BC3ns_WScZ4$6C&mw{iKtd@V#6yr zR2DfIdzK4lBcXb%k$QR;h+`n>21C8s<04L&)bR@jMB;&5&{hnTh}(GM(VcA7`PSBa$Sg`~N^L>V`(>3nN7?!76yE28cxUEhkMTM!7Eo{V&5F8}Om^AbfD{9Rh zUK+Xa^=%$LPJw7D9x0&wh*g39;(qFc2z83j{2(Lp6Yi&-jW75|-S^MBlP>yow~IF%&=+Q>dHgO;CF1$?|3B*kox;_4n27M@FZm*!f5$K z(&?EsrB6jQ^l@>0Ajn@Sf`Y1-P1zdd3BuK#n;vd7Aw_~5$9>$2>rVl`2Cdq3L_O+; zpQ5v_1!egU4@4kmVd6SR{r_ zf)^G4HS8(4?o3>xv+1Z;wt|ERIv%9s^B8ddF+~Lcons0XnFf0U3Qm%cgsld6{eg)1 z4lQAL#VmxHL|QES`dZ>B;saEcG(xzLUILKfk)T%d5{)2+hzFu-@UCU7Oh7Ai3w9jtKxvWyWp0I;Ay7)_`FkYO@sL zr3{}UnT@*;b#sQ(NYFy3 zxN=_F2{}JLLN!=oBOK_sZH*CE)?jjQA9%slf6~SsjWZX%?aPO1qDj+p5sz05vfbpy zuG!``IbxPuSqxDT<5^&-kdkptVLPi$sPrT8N}UqsIGMRvqL#HdHzL!qw6`?1!2=Dd znGC}>Fc>d{UR}t8s%3$1@h>EN}6#oqaG#(Fj8faE(Fl==#jl#C1=56kZ78Mg81- z|EY!3bO%4ItsIV#)pF_Jho^^QoSoD2V~Y89r=KF z%PRFIlg!b&yO}6plrNl&$7^c45X2&9gEeK~=u zA94J&%it#6dIcKv@e54<1r`RJ!{8026FanwH|e%djsswkmy}fc6_i@Xn7z<4;NKR= z%t>C0rL4HPZ)2SxhSMf-7)RnDrg+}R$PYAm34;P_n<4 z)?7Fm0!z5;zPv>+-!(74Vv~kQV=U1nezD%V6+>=UufSgJtmq&)RV(R9rnyzsxBUqK z1o8T5%3qg&FDh%QviTJeZ+4z9<=%tD25ID$LeyO@7qv}_Y55eSpD`(?)INq+aRhvO zD&|IIBoIVEG*wiPjvFT8pnmk=ugFR)RQgPJwsA4kjYniYi^uxYmnxZ%L2pC!CPgh^ z!f${x~Gf*URYZ|{s`Q0 zhCc|fU`0I$|Frj^%M0On7=G>1qZMj3UUc>!*I4a91!nK%B?ir;YbQeqnR<`w(U_7A z^Y#u7VPtj)dw^)=7_AI11s?HaLdp?mxK}!v2ckM;$gug3r)ngDpeD*{wBOO3P>H4{ z4YW>m5^!iAqY=LQSuDt*uRmgNE%I$ zx@EOVUs)CeLibd5dVSvDK?Aekw`FsP`5Vxn)d~PMmKQ)!N$H1gSwDRu^_A>r=fIDw4f)^w@H^&9Y9ba3 z4Jv^ETfEY$8scd@SK(o+7bUhI%tOeVUXrOP?I2Ongg7Mw+lxeuyYbEENLGhHCkPe< zr9f13t**QH8#+7+OQlxVFk+NREIov=GbS8GK5eCMg zhT8^IHbV6V)OXDc{Ni7fpR$rau3aA0A5e@w) zfGSsO5Jaa4>9|-cvcegKn@3u_5R$x-aCy@@bB}nG2M7Hq;5GLhr)h`RTsZ3Z{WS8WDvbK}J?&hI5+AY+6?0Qa$Llub3fb67~{y5kn`&*2h5%6jh0g z(2eP|WT+al4XxTJ=ijplHdE& zqPY1=l*E1J%0-;@F}DF|<)_Em}ry8%o1n7)BjsM({P&$hw zFTv*ET|5vt=+kwJ#ROc?9faRAy>;*(Q$3l~21<&89hmjVp?ZQ`weLE}qypN9JoA3r{GV{Wh{@&)Zmt}GShZMzGBn=G zM=S1ji5UhC;p0NKkfO}jbT&?H2saKY%F>$hkUdjlq}~2?d-pG${oT#YYMtbj!E7xq zJp2CTv(C${Kku&N4(Ofr{TB;5swuuj^rxn0wmi30u=%n{K`BnEr@+joFO`cJ$ycuDv zp(3BWmQ&;55lsEjO;QAU;0!zQa2tmr3|8BzJ|5~ZtfZi{MXgAp!p3j%ifvf3>*Q%r zn3xay`3*jIs&m=Y6Y&7Irviw_YW6Krq!`J~?`n^&c!MhY9N?f6Ly8?*+06sdV0Uyt`;z{f(0oe9j3~uVwnAF%B#3aYs_KeevkKTzXnE-T&X0!`puU?~& zfbLCwba-{r>Oif5a$6@=42>K$hP^mDHML(xGOTGKBU0+*><8m7Z^fH28%QG!uiJ3Y zy)cL)874D?hsEd(yChXge_z`M{)UQ4FTByPITn+w2%*?gquqFj|t6lwh~?&RilbiN%o2q=MU9n}fP5 zNzA>V@YJBiF1}o>P+@&*REGl$37fZbb}w9(2rQccFoco&^Wg|$DVJ51#vzqt>{h!P zOA`^Uo`G;sBTNrM-w-g*1%=(sf*VC$3DX%Wmy7P=prw4_%EzZxL}KDEG5K*|EYh|s zN_6I()^Sr#OC2Z48pc}$Z$6PI2K?cjroYD*cm&m-+L89YhSzUON3bMx4yL@H3NK07 zQ%8on`tYEs=3qyH9>z_^KzkB}#p4Nco$W~gvk3nWljm|H!;Qql*dyErAGDXX?w4%v zK9K&Yc}^t+UU^QY6Ud;;pD{Gw_7E7vovC!PT?&YZD(88DE|X*$*BW1O?TUpzuU%uR z2Z&aLIex{nQ1TdC5Hc@WVm^d>^~oV3 zyJVq3Aw_7=7XInoTgi~h%E>g!a8Voc&)QRuH|uz?cMgLdY4wMvjhYKt7^q}{m?SwQ z%)lLrpyQ5SQo`&@GQ+r+1o-v)P8RFR%GAxJrd%Fpo6g^$H;X(oR6{W&nt$Q7?0>YYP8Ga51>Sfh^ISMH0Pb!EH zP$$v}Ij{(vNlFp<#H+52>=q8ybGJ!jdu*GBq7}K?lB}$FKVD`t@Zcb~ zOLr~3PHc$VuqSO;+05C0goC61^7uh>SwHxlTGoR`U!UI%X&1l`gq*Jnf~jeDO! z+!QZ+k2VFj4!oA%fqC3~HEtY@cx@c44MbAwT2H*V4beA^N2{xNs@leUpP6(uwg1nk z)!{Y;iQlf(Bhi{cFSMK1R<&-6eM9<}*n60vP;^G`G)w#Ey+-X!5uRK!lhz>c7>EK< z?&N{3Cw@(>G9fbG7*U!IS}oObQSK!cn-!4tx7JNoU%3K-0;sGz@GL4BLtf5SfG*wf z0T91^r)V0W!3#$Hq=mwxWc11bF34m7MhRLwogZJ%R_3oztOVsY%R^MkyoO+I+RWX& z;xG3E)Y>tEz#5z;KA#$oPqL(GEvCyK+802{m`S2=O&mVj{z3d?Ma0!2_74Keal;x4 zxc7x#pE0(MkOraJIomqd?dA+^A_5AzJ^YyKlZ+17=>fWut*?-a5-Tb#V zTf3Xj)qd(!q#FNXukD!cx6s%bxpy%>RHe|8iy-Pnbc0+Z^ zW!6@xVjpI}xcBDezC)HqoG%gxT-*1vCdw)PYN>&Pbs*#P4N zML5E1xWD`}u`^?+JG~a_sm$Xr#Sbq$pdJ0x@P1Ms9&=N(fD!q ztPLBw{Iq{Y#Kc=kb>vmGq-FCk;;=>OcZ8D6jFo^dx(t?a*{v^tPI12KocdJzppu2J zjT>~cWBYhcERIQL_wnjuoVvmNy!BCk^kU)N*|5Q>k!v>BceW7THt97k`pCIJ!)p;f z#=UZ z8fS#DAr_T_i2gG~58yCBn4p9RcqJ{Rga&${2bH@u)57jmJ&DZC<#Wx*Sze?WjX=tHyR>o%vXVYV8>y@NAH#(Xu;H&wnv!|miJkhos|+R2;i&p zW9IZWcQ^NUzqe&5bV^#(Tf+~y>d^8`99!P{7!FP1&C5W z!oJdy-~#u6AYWBl95XGYIpeR^|8;xU8|Q|F1Zl{dt=CiD>~6l?T;JRDTEcF2FLgY0 za&L?ng2Cjpb&p4=M(uUvi$vzv4GXqd`E=Z9eLDWKq5t5kyXUXg*39c8N~-zPZd&a? z3DK4Iv`M96n!5H#MrntaEhTwInJ@xhzQ&7_*#aHGbnJbB*Ynvyn;6C4C4=NzYee0pEqK^Y)9zT&?9`RRz(OmQDod9a!Oao5KP?*95zB!bL}1?Bv|;dNQ^RS z6vVkfFW3icJY$>1wiQFL^|oRLn6s_?vH-%_nGG(ym-rr=pzzeTg^{02TY<&ZJRLH` z6b|`gArRTRe29?l%kBp-De|aegONA8e>b&`{IiX7MW=UI`_~Mo-usf>ZAwS zg~EgHCUnEr_HG~AIF3yiV9ue%YL&5tSCzp){S33yClJuocmpw5x&>riPShe}iy5C1DZ6wv8{C0O;egwfvTtkDvcgjzz(UH7(>`2(2PL~=%8c)7iu9AB|>yc~}&_=$%Z9b(tW>K4J?435Rw zd;$4ZNB8wUsoD`tM2<$)c8jLuVKsI=EU|P4Sr*+^J8mX&c?EUK)8nL8U7pK`d@H1) zsHC7ofP^85TyuxxG)CFmc(M6vQ_wE%M-`}RI1L7$$bUYEH{{Kzzlo6eubKEoLerxp z67S>Y-hSu#o0o7?ZV@_J1r}9(7oQ@uY!>gZt%Mg0bDIo#H~<%2WDP87jJ){5o8)>A zfXYkNt7w$D1_R?1@dct*`&p2TdGq4H$JoiZW#lHN{vR27IGdmhL(WVUS1wc&T8Rb; z$sQKf-s>%FmC8|!1jQraV`hH~#pFr73!&qLR6}#U!)2umwayZOnvTDa% z{?SBr`A1_BO+iKa#8~6YoL%SEQUFi|<*g+FGzN8BuVR@l>`;KU*Xu0yp9C+z z1Ra5aMY1Z#9iW@1MFCJWvp49~U1OxHHKRBvgM3Jw8^yHf?m(C&XsWZOzDC!2RR6U9 z;RR;%g;@B{dEXrZD5tFtWC)&;2NR7@0o_#ofX!umn=o6IR*rzH$*fg_c^*RjO9QS<;BR?3U;T$W;s^`}yBHBR&BMzM(zGV2$=y070IP`OI_M<5H9W%~g zeK9zjyNdY;t)Y$*{b(2AgH$FP-(5 zFQs>hJ4hCaG@6;)X?(uPIMMvg`|gMb^slyRd(TT=hR#d3Np> zqUfxYuen~D8j`9JB@ss1!!K}{k}N!={RU! z^p9b(Gpz&1jc$^$vc+~-I}gwSSxPT-VU^zAWPh3 z6&TvzI2H21v=V$$N%f;oi%>*#9UIW_67zT=13R*@~4NuW-t7E>V|Ig9evZ-q3RM9@Bnpoyx*%JUpEME^Kj) znOJAsJ87%i`GM5G?A}NlhYQK<9WHR5t*_;U2lvQ_Axf}r_;w3c;EW6t&DTS3tifxo zIB^IX(bJajR7n6lBVn;5M2@lXaJhj!h8$WvwQ+FN4s{B22DAFH6U!z7ZMM4GxH+WU zShNBN+J*T-w88x}2E9#z_@dXvrXdD{BxRfxZYP?zUn(o>VswzPsuz(}n(2)}>IAUL zw{-dgJn{XEdS^H$jNNkNkUYS}32!CaR~(I%6`?i0#?_(Y3B$p_GU7Bt>YEFk@kC{0 z8fzWk+J(1Bb;5R*ezw2*M_)-UvF737!^6YR+lPmb4i6tQ{;F<;FUaUl1%T$ij`5LoDoZ zF2f#Je6hUbco2kxgnyFQ0fZoO^?HDX3~&QEbksZVzUvQ1GA|H9cJfAo`(4+%O_dp? zEr}qFwrmT|MH*_Jka&ijYg!tMEm>#A`7fk#%?qHr`EYp^9u(4%Oj4zlR0_r>^eO9~ zTwh+^tjKR^Wl;y){)T@esn7;-%WcX^#w<%S9olug{2QpH^IU|@p6@|r_EZ67l<8|^m1y^Vm!70 zk_%1Plv%3mfNlz`p6T5Y?$QworZ~wVt;&ZJrY2t=(<6YR1R^5M7Pr%AhXcdan&dM9 zb@v)sEku=x*N%MAL;eR@9yPj0h&vHe;;6TLa<4}H^+ ziA8NBi4ZN)gF!_t!XmV(s5xM>nXF5^2$bFAZG!AIW~PKnxKE)BNGmFL0zom%jG!%*Y!8uVVaXj zmfjvuVu>NbS2#nkOo#Nf(FPaFjGXyps^Z%9c@`%Fj--{&3{lOc}Jv?C8feuSSlEKk>Ycb2_ zlg7dKgSXIR_rlb*7O}dqLG=eX>;bS61JTZmY4CuS6n4O2e{)C=e2pr#!{*ivF7OzD zj)^S~0gw`$)P(1%J5pv38IoEzOE4R-!e|YaH0cn4XIf}%px-n@D9xhdl*ZbPqS=Wc zLx}Pfg_h1xoK4KZ$%)YbGTl(DbO~e65R}Yv^e=HQDZkerWAbQZk`WtChX0mR|o5c4s)TJ2pr9LEO*l#c*OK8f>0Z$Si zC3*j_Q4sUXV-oA1+0fCK36EV#RMQY?q%K_)XPq>4*Ux+rBcub6Y z>;9VUnk5u=NckUE{21)H@b| z^HQA}+F}kkXWS_%$P6Zy%ZLN>E#5;?C{UOACOaJ@|LSxYMt}>u?SG(Xg?^HD^rI}( zZ^2n`&WdEq+2C6?A03t$jr>%>%SIIe#pRr#O_HeLA_mdN*O*joZrI%2$AMKVpmzf{ZANkZRQvGcK3fDKXx)SM{mwFc3-Bv2^ZiesKY*9wUh}<1 zAT^PRonJdz7_=lJb`dKQYKA}p@XJz21!5t>czkk9iZ&}~ad>(PPC&JAhQyxWPF*mI zp0OI4OH_i!6H>8?KgC@!Oai9RkqE^nW4!`u zDb&M}i=ExgZ#&!1pYLt%cQ)2{_HoJyuN7d?VhNwtC@qWX0mv{ffe5mr0ihJ|K69k&6Byn|Y$WD6PvF4gp%G1kUhiZ~<61g?(10(4ewq{bPHBF(PKJ}V zylNwh0lgrXSQ|oyJpodP4M2!3M4(Qy0{MFRYq^JqJq@q$N~yzdq1T+df^m!mL?sd! z@`41bYZZ?;Q4$a=)89h=vlCd-sT}37J`-Xz3lgfqK*OeA7N!BlO`D-N`=Q5`&|4y5 zdf2ca__Nx5RJ02bVC_001VTbl+l(QI5iJ2%h7i-N_E`Mwj;X+Oah%?r;5{2E-+50IElkU>cMHC@CwM(Rh#3Q}^<%CijPK<-YNUTkN3cb_AoV71s-)(`>i zf?!$~NjOoAzye)(pMNaLh?_p7Brkx#z(8oSJC-Ogxzt0kMlHrqBy?2(_#$5B&t&0Z zbg0{^5XY(nfE%MsOEk_VUI1y;^w`q)msX5HK3Ne)97_LE*>I)yH51_C@Fr^D-k`0Q z`pm)J3hWOw4m`&{heLHu#k zzI3Z)({!XM+>sXAKGoFWg1-Bm6tYKcuTpa6ut1ZE5kv zK3*biUE`~-8jp|&4mpe#kND-`zv!1^e)%ImFY-PrT-VJj{R9j$_$ro?t6VDnpH&uY zef|iE6BS770Q+XF&~E_6tSwM3p7+n>q)oqpu+;yf&Hlcz`r*0#++i?6(HJ>y&1EXx zy9@`l?qP9@OEw2y9fmyI;P1KnX$^jbCj?j7=GXc>)D1I-|I#$x-n#)NAJ#K;$ScID z{M-Kb9Z5&9zq_@$hf#h(L}pqraivw>+1aPca|uSun?ayurPy&7$lbuv4!VTkt3v-u z?*$0Z$-Kg+QvW|EH}uHvBR+$5xq8Yw#X!{&D=%j2ZUFe8k)#l2L{#aN#p)-&dsX7l z2^+fi6X>=gMtgY3I9Cw3JHhyb$gu|sA0IlT_QFQYH~taVh|*tB03c$`Y?6}uv-Iz{ zB}6lnPt6LhIP%}6ol|p9iC`?bOAaCc<_sB-sK7VugB@Wb0S{E7(tH`e^E>W1IK>M# zhTxIM9#_2g4z;y;wg|QjcT(EA23U;s1*4W7ke$VdMQ$!rGU+vux)k?2W$|1t_Aw}f zl_49_H2!&KXkus()s*wiT|0|Jw-T&)p7DSe02MrOn0BZB-#>|(S82c&d?1KG4%bkM zag%@nxZ2-ndMGQCWl;b&IMvrAx}09(b#n=xF;2q`KH=s+V3QqM9tmwJ(KrU65Ejds zb*Q)1sm-FFYkJ2-%HGg+dg-YuU7-NQlBw=+QC*Tlfx+G8AC|M~8bA)cd=HXyRuilk zjux6j;r3b}#9NVf)i{s1nno9 z0V_DUH&GM+DSgo0Yr!Ox%Eh_~4zG|GyWCU~A2 zbIjutjn+?A5)$zjy3OTa4EAS}30ULR4z5;=zJMZCr&c{Fo?gfj`PlZ?S_^N`GnXPr z-ay%_RFqYZr+h2b^F#s*JK=(z6vT4sDy?i#b&p`~0}-u-J-rt+!HqOP-x~Bw0@;&B z>jpma!EmX8MG2(+D^Tl^@+G@g&`RQ1G z!56%Um+%g^+n9fZLdE&#J4GkE38v2;WFlh*9^5PRyI zxpfjNn--0$2-Zt6F$E750KqpY*JP5+u*}nsu_MRNy(ZApZo?U_=_-J!cH60lPT&kP zl!Y4<1~X9-5b5*^i8=#=p}3PIibnx8l^9}a8+?@?M6U^9StQEOIZwi<{nU36T;5V_2cO1%o28#G%OP9r#GVQzhY!{5IZ?Y?g5qDbu1ak z%-|%d)yc0|u=lAIlf4jvB;7_6B0__>7?Rs_1RjXcvCy5`0&kE!UG;e?QbH1l$WiqO zPskc0$(yK1MC_(Yv>k?O$Zb$`%tAefrr7}i|X=~_d8ZY3M{YS83B zMNJ}@lkv&vFU3@p+TJFlTHYqL68%gln)nlSc0{gbC%@G+H6EZg)qW17i7dT-#u|}~ z2vMb8s_o`cXEhDDq#~gf6Blvh&YGzOA`<7BJ|Q;D9rO?VDRt-rEhaWP%7tT)Q+WX` zMKB_f`x-pO6_J^=seQSdOI{Ey9>Y3YAbC?-Bh?TFLlup4IrT9enEe>hrJ>Hf!`xRJKfdY?aOSKmx&?0vcIt2n%|40IQeSpQ z0+SE*Pkj+ju#fiqV|~F*1TjpW^>L9BLg`Vu_+AVMvImE>yC;YK;oIH-W+_Gp6v~gE zG1Itc5FVHsj2m+PG@7e_IR2N%kGsc@9{s8N=;6ufA6Fm#arKKo{qf|FM@N6^c8|J` zK7Z8f9UnnNXccPEtB=~NpEn*p zTKnSR+CxUl^2bFURxNS>uy{((G$$x4%Aic0%Yex2z2_~je`}HD`J`s`5z36vvijO8 z7z=<9Qku?O@fPAoW~!W^nkAHxaI22mxv&!yC95cVLdFjGQzM~l9D>{%PhvofS8u7y zwVin0TKdP`TL~bF7Q*2OnhJ(BRfS@9O#q>c-O@jFz>+o+AoKx&&`++uYjB}$)ZI>G z1Xm9}fT&21R^^EtMxkIyV5`t9!Mt?&Q{NlrtkQN3$d#t2jT_Jx5~x*t4qs&6=D6 zX`y*q#dn-9$OT?PEyWwcT|AoBFQ~ofr)C6mwgpPBsKr+0iI|qTXii2_5!)O~<>8Fc zRQjtKPi=d18A=iwtC~g?J>zAev-(%p7qkMP?_IarM#AFm=Ej>{q!aw}%k7Q7?8O@b z%lGTMyX)WAy#Lp|?bqBGf3sPwEANmqd+YVL0Lpu&HeenBcxl2T?0WF1Me?LSptZ_s zg;Oz&uMbUeio|E3F4JOEw3BOJVD_2_D?Iq&r(fQF_VXdn8s7R@3mpEk^jZ23mP^rt zA}sW9_?A5!NDsGsKKOwJ4&S1O@bBm5a?!p{7#y&l#l91Sv*QKyc8H&Yg`?BKXtKi3 zZ-2(G!)qLyJY8=;m#D|bzx<3YSKEglR{w;5U3_?W%2EsHexYbxrrJk^>dSBM|IDTO z&s-S&EUS(PYXZ-56Qi#TLXouGJbVl6SKj&%foMPheHi8&0Kl7u2m+@iTO@_=;;m`Q z&Q9{I(fsKbX({z@F>L3Ro>cwa51@hN&z25o_)vI$n zVK02h!=wMeF*Z1QF&J?#n4M*$j}Zy-#O2{J3*LQ5NQgaiO-%^rk6vfxt2^Tl9)oS7D9LtL0m#C zsWrKT@+Lo|M{9J6#QqCUde$?9f)BLYy5A-n4F z6=#Ns2WC?wspeX4O0FBs|M3`6qu7k7LANysgfIT|@E3LwNdX-w#FEoapd$Z!5EZfF zORh{38MWYcFkC(-#PbVbG|43G_(aGwOdIk&@P0}xI(G=6CbW!qPltw+N)>*M4^%1F ze2+Zm1Q;>G`%9|tBYxy&NFfx!BvUI{f@Of>x_3+^1FRQkzU}gl15^1R$j?fLh^VJ@ zgR0`RQYDHI&cqg3#!pQ10!1>)e?UluOSEiiePioK&DCTPyix=76Uf_W2V0ZCVK|EI z#i%rM=0$JLy$qwraR6u1NAgX2Pai){+@ZnyS*iliP+XSc1{G{9f;chBh|QsVt_V|X z^S#E!EiK%!YK|KO_)z8MRcm#{2={lt>y`agyU}tpdm<-RZA^@2LqOlN!*33ip8A_P z9vyQs60K9)j{;cJ)vaU6dzm^4A3Nr_KOnv%g2PadSq+)AvDN%rRj2on`S5|tpf|mM zAB+^NisDpYFbpS@Kxjx?ar9b_xmZ+?XpwNxvTPE`DM)e@xEWzVLWbxP#{Ia3rPRjg zQ?jMTOBw}Q$JH1}eg8<24xuyv_FPjnf7hb)cd#J)saOtwN)&Lu;zG|Y*tak@rz+vl zJ|-{cWjqk(ouY=1&-)iABRNE(qbSkra*`Ypgm8qW z464MC{)t#fRWor0eY4=2cA7o%;EAMi38450&D03bL9D4>@A&OdOc?Xqx(@qnOs_zv zJA!7pYY>E*(FGtAs+CFUB5YV!pn+aVWxid!i0t#F#Xf{#Sn(ybpanLiX<>R8nSS?r}E)niv^2|9rAB<30A$Q8Ti6Ri9Ju#HU8qNgE;^!32hlgSd z=fbQ``j=)#uF*kwnO6HP3qcEk4C_E|I$H|{t@Qty)DPVH&#HsTWS*m^I)w*fXy`2g zNOfQa1?+)at3)}RWp7C6pk7-3G(!hz>QrYhTe`6sQD`DdJJ@Q5CY#X+mlR>>diIC>RU}S$wIExU@plCj8ivPv% zo?1$tQ+yyI+QHetd08H6O_euBO4mkiFoc$1H3-I8u5I7}MV8SHY^$?x8mJY)M#(bs}5r zC+B0qli@h9BHBTcqhOjAqbf))+KZ{`nr`~BZGfSczvG2)W%F})6HxHxjQ0pu4JU*{ z0#V7top4we*Oh0ZpN46ii9^O139- zOu%102Y6r8 ztikfs5}J$SE$sw!EYOL^prmT(81BZ*f>vA&p#BuYRp4#X>42>s(Wq=e8Vwn-Cvro! z*6uGY{Bk*;#4tW_*@h)N!1PUqoR=`)yd+b`Q4eN>1L7HI19BcTe(zEf1fvcQoI;>U zD*3$3`W3-ShrQSGO3nvf9F8R2=Y)L`@-{##beP0Mvnc8@Gs)B-xqDu3cQ$u-w|8e} z>}WpkVxLrUK-%#!96W;BT+;+V-Uzp=W7Au&kqY7U`pb{dLEco}&7apd{<6P|U!9j* zueSC-LT|M#=AEi*78#^ITBo%w=AHg|{aNSD{_{V6lp&@~P3gw+I{kL~2!N+8veUWJ z#Y`u@H-jIM&Uv6oqS&5nsF|)*rqE~eoT#VNfnK2pmml>ehr{nQO&{Z;`DU+oaU!u( zFA-%RA9k2}rS>h~AS5E3`1!x=y?sMlN0Kl6Kc7Nj@k%5HJc(y_AL7^{fG5ng4GTE4 zdyPjcBVlU{h?T%Ln|MF_^ZV6X_vv#agq>vX-o2WMkgww1>ZPf%UsX;T7AK#NTEH!K{YT-(DKB+loiyZ&VTU@J?VW*6FH zceSPnUl$|Rv`MgmdzS%h#Ivri5DR6UOHa5UPh`Spq>AgzZCOuGO6?5%f?Ir+zb{6|xFkj`$?V}CTzj-+ep8NwCPUa)g4LA@l` z_r9@sAZS6ShFagXzWLTe=J~^w6#-y;4KM^72&Bi|XaKA}VkH_Lm*7n+ zdPk$DI>*5YL1NWfcB3W9eA)wk6za;BV&bbf?xMs^>sQWBC`S?xzZL=se;0sTaBVpu zfo-?R$lI>R)xwl{2d5|N>jCZc`DO1zcz!l4AREYI@ECwFHRh@(hgi{ZYs^&~<@Dzk z517>fGz?nHvL|smlWB4^(#t>~Pdm17)6~91Sw`6Q5%M|jAqUX_QRRg|RaKHf!bq={ zLLp8R!qRCx370d`8nj=>7m-@L<`-mW}^C7S`gh-=_10m13e3Hc%~Zb4l2U{PcZ zVAF9F*Zi)_V#d{;Wp|JmA=sAWkSFb^1#5n#8dNT|FtBFy;1+T)f+l|RvJOFZw3$~>w;*nB;#-PDQY>!RK zEL~o^0qO^)frVrbH~oI6Ei7%*TZf-DDwYGe zcynQoI&Crn+I(><@SD|t;E0%0R7iraFrtc{tG#xF0E%B7y%cB97cV&rEQhf<2FmhK z9e#E6QOd*RIh9XyCN*`{SfBh8>7h7B#2unBF=F%{<5dDK%V#?WS0`{tS28*7T@0R| z54kH2^CQtwTj2JM*EVHNe4CoGk}_Xz>xk?a(8Te8^M~Iur)mT42=rl4 zAx6?sL5gGaLdkL%?lO+F>^{;)sar>Pnh#Ns;GF)? zz_%V#h1JLO;AF(JD{{nufE5LRtU7ot%z5VX>Z(>;P$QwsIztd2ibHE7f)X1(nkq30 zBj(J(7mQ(#DXyW_m4CX+5cnp)$pE-^L~ zG6i>t?TQT9wIZb<$ToYth1`I{Q|x9k#kakRC6t|==6&hl$W{4Fq5NB~FSKjGgLX7e z{fJ^OV&_pk`9vH7@kK29oJovoNtL1pm!vM&c_MK1duT+s%IvZU^v1g<|9l1I1{*Xn zMMI&n9`vNJrz!`G_Y@T%6f?ZRy>A)L@quVb0S144^%bcQhL7VnJ@)N3Oj`j%*en5_ z`7B~))t_1lWAR3BvXfMy`+{0-hgMdivc&AE)H3iHtc}f9hd|>^*5xB`&=}ylAs`dJ z!+{QAJ!mzLsC2r}f;l=X#L%q>ho0YZI69K8jQ@BeF@|WycNt*9MUJkW7htDp(>aLIBq>WBDeUY~t;;4)0fdwS3iifh%6PD)#c{`yZFrh5*LA)_EV zL5bQ0I(5z(5x#WVLNsRCQMKeKnK>3RF=XM3`yyMiazjsUs(acVH)0THq$>*V{3rer1?n*E2?1bVY{k6 zRL}sNZ3-Nyt!0tiF)M$w<@h%)N5Fx#_%~gPd8ObAq`k0_q=vt1jnz@bHWVo)XKj%c z(wYLM)a=U(CV@gh3r19ZfYHPQA+M%U2yGD?QB)eM)y2@h`bt)gvY}5IcfPGFEIQ6x z>Yw8{LVo7)$+?R+oLHbz!C4t81fmkSda{z)kpvBu>cEO()lNxRIC_M^oSQl7ZY$S+ zk(h=f2{swxl&UP?d4hT!({j$ zNP5YPGnl%k!yni*Qji|^#{Cs=`g0_wmDfIdenB5X_5@L9EfbBj&U7`P1vJQTUJ^$D z=~3CXR~A9=tal;dz7Woo>cn^2y%zy>AhSikY@s^;{SjT1%h?BItU|FRlWv3ptp)=0 zt}s9smBIpyH6>ZW1Q5%31EOMPw!6Zv7h2rIt5T^ig#GN+R=yl08Vw8*(u)%1LYtRS z4mGvrAc%wXMecf@dObB9w*<-RnHI&Y0D(ck0F)hbZ^+l9VU^>LIrItg6 zD~|%F2(!>Y1t;bu?yK?fKvc^4P_-O}UT=og31U zCT@myqoAUOZLe%ppl+loOV_HT!J(VCu-#tJ=P&#coca+ar>oj)N>>nz%mKW7-Q-_I z88jscgL{_W<@0T6#KHI;q}c*_?0}SNj*j_^tD~06!u99Ct#A-eQd=(pVFQ{I${Ar` ztQX=Gp%jrSjs$WFED)A6hDhn`$s8RoMIjMQwY&UHKno z;_R;g;Z93g=*l3?;Htl2WU_6qq<7wiTbGM79m+VNB=+u-&UDO-sKLd0ec zbJY1eq(DbFlsXRqqY>26f`KqP)Ja+gkkwwN*c5+@$fMH6c3uAC{+;!cUjCKV%SEvbS3kErVuJ|x! z=f68P>u!xMk2^T;F!Q^NCkBr_;gqKqNr_8*DkbQAQl5?!Vb~6E`LzLOMI|Kym$ofu znPATxb=Gjf^h;4VA*RqWzdu^r=%f1 zs`-a3EN&LsW+vDM;t;R_8Br^zhX5G~?dz2BaZ$Y+mUxIDgD?=pt5kMN&m1pziE-Cg zwmV;YLdp7@UBK%GKD|&H;vlT24Bc~4Uw|`$`ENG=Km!0l+gcQ8`* zUcoBbJHI}ISbw*5bpbQvfXUOxu&?oaeAH%Yj3RO;M<=OSdHt90@zub`lZiVTJ=HE~8lDZfj} zZQOgG3x1z43_l7|167$h8DR*GWyf%86L7QBbs)hlOe%C$8r4ym9O`jQB!M=$eUb=3Pew+OBwVWG)I)LQN?hE0rRI`YX3P3J#9UkItU{vrNMS6XvHjMA zdng0}R3=X88!-=C9SQniyA9?Il@vUg!;r$uwAe|c5+_#-n}c+jj?aW;Ll_gju-2wQ zqxxDbLHe3`43o&m+7*h@wd86WktHEfn$vVlJ7BHNQn3?aXcDrRu-aT#bwn8$sES>H zA|q1@Ci<4mf)D1ioEH&aK@Ir_;-+f!TT<=-cV3Uj!&ifGsQQ7~`o}07EFRvQi3$L6 zw9uCZanvHH^VoK#0IH^bd8wd~XX~ykH;8pW*~8xWHEAB7?4g`D{ORx=**GjKql?~a ziBf)m6v`J8w8^mRLoSzcMGdJJm}My=ZY{bE=7^ow9{U+lxs6_2QgUK#u2KFC)u6Q^ zt;IucLl=qAf{w2U<_h#bqoZ=hXN<_S52w^}P^h;tevM0lbRDl(R)o%|{Fvw9hKh#t zX*GwFz1j>kv{IiY$3Qs_Cc@5|l(q~3^+tet3M`+qkhseu4IlI^%se1g1~>;??++%U zQ)sJ>_D0ACe;q5SytmR+VT7&gre^mwomEkA2gWz-eCRg5$)YKX?H*+*8;h4dnBsB6 z&~~9Nkd<>3-=>W-WPxkg5{azgae5JX>o`&yl8n@ge z0&y_)It4T>Bz;r-7&T)=yx@qr-hs>s!{bbGv-ge3!;j8B3%$_kk z8WTzwvmz)ZLFe4Y=Z06LmE;j1;b^MJEbXSj&%*w-IlCr2 zlSUP}r8Xvrs9F*<1~w;vjf1}1s;_q5n=xKc-#UunP48g7 z;iaDDox#nFXG|H=uQ`9yyPI!-RZ^NZe@(2y=djBBD?=`}BP?avpOB(=G&<$45$yRG zLCK=wS7>{SL?z|jLdmB{^}T!vVJGG%TLm`~#SDmNQoTcOfR{if;1Yo%!m`T_wi*&Y zj-yOQv$77I^I#)Dm{{Z477{n~1CEx2i<`iFDhLud zjXDyT-rBDMqTOq4q8lRt3w|IpmlK2I4`h_4vyrBbC8Am<_o^}(7|#cZnD(QXTd8Qo5G5g`PrJKY%HyXdHJfJ?Dchj^eyU8bo-iv|38*t6VJX5i|&DL7Gl1w{`I2r>7vz8)S0;y7g zOG6Xd4u=LuaPtY3h-k9^=-AQ*)3CSPa&5>Oa%Ro_M`=6u9=V0s%p8?gHLRkGvHXd1o;dQ?yVe)@H!ii$QQWr4`ZPckY?s1q8&OJ zx!_hW)`J0^oT?f~uWBMpggn6d#vK-LTyOyB*sOP6>z#ffxZa7Re0T#sz>Pk-5^gR# z0@Yf&ucVUMC^BHAc=Jd=duCtajKZyt9cDX5bfMFpwV!H2I7mN4)fs%mP?^i5qUH=L z;)x@FYjd4JP~kP+ur3=45K?kyH-9jkZ0P|he^^y8$x3UO*y$n}#A2s%gOOV*fIBtG z3tz#t>Hm36iHkC)@jNd9uM@!{E51aE3@iOoU01wRTDOIG09v8KXMpk`GiuZyL|qg}bSAWzMz4=BBB_ddL#IB2v$A7L;y zO`#>7Pt32dEhE$BAzjUcM~3g*rqH3oRwpz0#OF;{dcFw<>E0V1I$2WxVq&{ zF1H@a;mJUlLRuw_)ClZCwVeryW0N3-LQK~pw^-PZRpCwt8@5v5d&j22`wzW_H?>aMgU*mYU)54iwz(n!^*Ie zX4$gKc9vxXNJrW`O)u@~X77B2yX6QNp|})WfICSR*r&YDvSp0xzYq5AeMS)2qwSaT-p*q^hiG%T~}`fT`hHp2#a2Sue`+ z41kg5!q=58xh6i7?TZakZS$cYo1c-2C`!f9+Hg>BK_&@LR(iuUl%X1cAk1e-)P)0n zQ86O8^io(3c4pZ_WXZYi7?u@Xg3#RjfQtt51HI@+q-PUy{kB<@0xIxv<8Y>LuRNx{ zz4D;1l2r5|FAIK^n+PnTvX3+=_8Tk(bv?E$=-b#aL8*`di@R&*Dwy%i2zpiZb5N@< z6w<4IkC!#0gAJdB0~5X-mnv*9U>|ma2{H9Gqdw)>M6SG{m>i7~!5BBFuGno*f)+JbBXHe7XfJ@gAJtfLl2}>*LO?f2_*x!C|cq zE;7xognpjyG0k}1jk-cj@1>~0PG(g>9~jBu^Mkw(dKX+xruR|QU>~!pppQL7z})y# z;LUMnEY{J`jJKw`?DEFSS-*;vvRg&W>|V2)d8gB==6yahDyek~{ic|VZ|J#FztZ{i z2GIY;^TXXIyNJfQ_5A6c_l@f;vahZ5ug)%-`>oewpL0~)-`zcIoMF}4t76`BW4FqK<2``LTyt(^&!hv`U6_R@XWw^{k6>@l|3utX&uSU=H! z?%p|vIds+@>AMp4$=r;agtZt1mQONbP2Z5P3GTWrwqY-e=H?frOqiuN!(7r-!{ioL z$3pySs1QTA*|nshHf@1J&`k0gBvSw~&=i6eQteDLZ3&dpEt29k~ zn|?XVC}-<-QgcJ?8)W8&8al@f+{rPd(spCb(P?8nqHt<0UuHt<4b=-APi@CIMnelR z2~+C^M{9DDtj^MWyRi?d#+EY%7Uu`CfX38B=8gKNhmrB7iREd*4 zztAUHe^@}cGx-oYKPw&T7Ew1ef}xA_^FdJi*K`0xg{H5e+IRSlPe+I#=1L(`iZsEg zCxcG}b9fGiHm3KeBT)@%#No67SY^=_X2x2(f3;zb#u169)3#3Bt77PEPz<=-RlMz=0oeZ}1h!=Me zZPwe+$hA64^V}+MR`ENrNA^A1=o|CJrb{C&4MMi+q-#SOLGuflUvTAS_el0K^!6=%k(uUyXZX+?cVeEGk7d zQDc72%`d@aQZSDT$z$2e`e|Wz0WJ}_KAl!Kuky0p2sHGD>C=bw4F*Qf& zz-MU%RaRg15G)OXW92CuG}$n!iY%BqX|G*P#*ERo#!LAOi?U=dWf%3MIK`j@QXw8? z=-{PI4pxoi2xF%a;i{0oSDXmEh%SBgfkE1=SG`YdKlm6_+r>|PZj(T0tV-Wv5$1s6 z6$ZovCAC@@U)v)RGPL&eLVQcOEcU#?l}UFhyZwZFOz^ye)0d=TbX07p2K#1|ty0Rv zy&!nNos8lXCc+^Ua+lA?IQru_f{>Cs&mQk~f7m$Kezx&+8xy-k)C8MDPxNYQ;(*br z0adF@zgXdxhk!tdZrTic)CEqLphTj}wAFLM9su`@Q6UJFaENR2mA;px4yQ?9w>XC) zOT=LO3bzR@PlUpdd8IRZo+K}(yYtnB8pW*vi3lV4vFK|7dO~^%lR?vfArLk&0gUno z_)0UM%WNjFgfU66`PP9`*&6o5s2ZyR2;e!0aEDud-o6|l!yk;Zdi0oKF=dQ9@FQWK zj!v{Ii=nB=`uhLc{@3otL6;$cNHncqnu~2d-{0SU22+d{C823d0)oiHiMZtH<#hAN zlO!Kk15TYVJK-um2yrds6668K+feBM^Wf(oFD-ngVRDSaXB;)#v+6Gqk(dZ=%D97` z03=pg&N1mL<+P5=h;W!k80-(%dvAD?_QSPo4D>Aj{`k$=sPF4yT2stHgu=H2L6~+8 z4BIh21rTe{fSE?~I$G~021|khFkC>C4*0W5?HrsEA+jZdg&(|uN(*`5S&B|x=WkIR zwT!;ox+l>!mp+(`uO&So;*?Mez1g4_hh)NUlpf>SfZS}L&~gGL;kngok7a*EKk^1^ z7wR-ENz6k*#3*_3fJ;nbIapk%pa1%IU#uYlRKDFUKf;3-e_ea|)!Oox4DPU`$v@c# z#v(NfU^Py)ywT|73FOYVBtvmnOzqseW;T|cORbZt3mw)~4&gRygqobUviE}TDx{IqI=KSU_5>82C zkq$OTdaMX;If2MFz33I$$qzfvx`!M4f7(8@UKY{xWKgY>s$7gN`d%vgHP*7S6q=soerE_2lvxiK-Bu@np(GF$_O!yCpPI|DENNN#`-1;|@$H>E|9P@kX>B=vrEgfK ztGKe#TIshe_;&XKi{v|PBq!qOlijeL{7zF1MwfHB$s1)Y2m6~cP5*ZBzW;Cf$R_N& ze=~N_TDoU%(jNG8U}y&VXa6{{B3#)0;>@h7R}KTdjo7s-=nrN z$u?&*Q0!NOHhTx2>F|7tG0zl!=q^dgT#d?-~S>QxlVj~f-n$q_)$C2uY02b19=~_&Jb%-3TaG5mpzmbAMFL4X!7F zIoJEN45%6Cl}xCtZ=)z^YvrLoh;uUJhpZjxyJ?Podv)JDw!cLt`!d=d^c7Q$(1y-% zM^~u2{Yc>c6q{%+tNG`E)vz!N<%;p>*#`R>ulW@=hs|b%`b;JKZ?8Ykd0Se1)eN+Ot%AEPSqi$b8TJXNW?^2pazw&_I6^jAv?4pGQg9#pm^k}^LfH_x}H+bRBC z=YKcbHgH2Bwqx!oh&7aLX^sl=PyZg9Q8CiIjH)fG+ppYRGU^?%FtK5r$xIW55r0~N zEQiw~FC_xW+K!1r7Z&T+As47NB{Zbne(L0zY-~FYpmcKQYX)UCZnkdeT$4?6chgSn z`pPh8=lDVRMhgWMCqv?GT3^4jk(*bTuthPQxdv&`sV-QY4={zHDaqURpI>4BcTVZ{ zn4kPiEY#xED|>DrbQ-vnR3!&46P~9r=8cHJV7BEZe=5;+DNO3V^Mh-g11U0ZKM@{T~1qS!s@GBq*G=usgZF5Wb`7&-86Tp zfKJQ*^X}3pH8(iM*)d$DRKu;JZpxx5=Pxy2%cVekdcUxguXJu+!QD(~<4s4hk`Sc< z7FVL*<+QeB3sN^P-6@1C*vnv0=)m+aNU(0ZC>ysn{UlIUQx2q%rM`_N)cYUnt2!hAx}-E{SYsTrIQqJj8QYpID6vn`=cZWp=&<;auM zb%oHZTJVaxIObJj-Dsz=831B0GIP~{r-oQC6Ii#M8~n1ZL`^|z6Do{H6 zx}k6kat-!l<4$4x?HOjz1x{NP@Ab@UDxIo&hd*houl`ia2t z^?$IJ8zv~+*|s--+->bXek?vU@a;L+KCHNs(U%QwB;rN4H^nv0r6elmku@winf+}3 zS08V3zjDhar8kpvYBPmpWe*w;%NZTx=~aeQ&Rncl{n-DYnrZZJZ9{ zqVjZqlw_Fa^i zW+ZUQgB|Y@w-p}C-7X|g_K)7KGLZ5ZgxCYZ|HnJZuBd>^ z$7@MTi;W^8JjNTG_l74!8n}!m(;XKyP_xx)>c-5VI=em?sC-JB7%p}?j>lmbO9{%t zX=5O%)dcD;(q6wAos2X+K{KgqB7tuz!6bNWM-bVBn_aWwmZSi6(+(7 zfB>9IA@Kx3^u&Wzq$(ZSr7>D6mADpE~SUzA`; zT;8EvhzJNMwsW{&qygz+Nh5pjNy9rv8)IG?{9r88`Vj*;zu$ z%EM#`7jTG*>Ag{83v?JFva{9nxC+nD-=0I68wb{Li@j-Be8oZ{h8ji@)6-2FcHE7n z*K|>IF8?7x!-Y1RQ%1hA<+xCLV3ReO=5}8ybwK@cq;)0gLFr@n#FRJ%x~t@qS33lv zP={6|r(9fuAz)amR#2#O3h%Oj|DA?i*-;kUKKAP@bdNAkjmA$p7g3*X;7K}Fb05yX|AoNMCfw-r$O&vudVva-?&5el9tI-4{v>3xn6JYI~ zVN-rQ8b6bL3i<_JNt|bzOxHeRmI^teM1UO%>vOcDRz z^6q)Vv7`liPeN;|uDuBGbvjBQkhANjltNOEv#7+u`mbIo3EEpQD^5>Uq@BeRW(dIL z>acZMC;6P%RdgT?HAiF;D%IDsLw!u0!WdsBYtJ>pto&z9?3`gJK!7FnB}U0Z>kYSb zZE47@!p6m5^O120ESuO9qq@A`QJyQ^R#|BYqe%B2yrEfuY&ZbW9>!V46>m#Th+Hj~;PmUQ-UW{jvNNuISb6{c{R*&mwgUVhbuFSm zz^Z{(D43&;G|e>jU5R|(MYg{&{QeaSmx$jpEv@P zA^BNER(&orK4-WI;TtMS)Y%p?2x;rhb(vu(e^0NFWhO!K$9j&teY8iBO)5&B!B_&w zX7SR0&+UE%L~X~QsO5sj+qjae~`oO)g6&h>Oj4~L`9 z=iiOsVa`MO77JDcv9I_`G5 zt2oJ8r%bC?-WfS|EJBiJnZy7O*#on=xQ;1%R zydfr@@!ugivIrJVUCAf`y3kL_N}9P@;^}qXlPMm(pW9Kf@kj8NDKPoU{FRzVFXgCz z<5f6yWJwM3D~+ujSlY~PIG2+@&0{Rygv>QM#Zg8gLLOY7os7<}HJiXWPGtBd?~gXp zIgW>2dgo@3l(MJS-Z_V3AE+Gv7OP>dI=hla`KC@Z$?lQCumaQ>fREwh;Mx^jd$^OM*o(8%9M^4J&Nr=}b`+FKvW7yG3h% z#$oJ;|6pq$B4iwN*s;GCMa3X2JN}Qo^FG2z#X_(!n;A)jKw6NBa;kKPAtW_zD|;dN zCR}!P=@h8qb=Ee5eRSos&}yy8*ERgqhx}>Z2 zSNguYwty;Vm;bVI_CNiNe>?18nZ4od!V$q+(|`HE{#(tS`d7TeFzO#Z=LxCg0=cM6 z5t?$GA5Gm&yA5Fi7T-%vcL$LPUTc`zuH;ATciJENgI8CtRiR}?{oyL4u=i-k(wBD` zq;LSKO-{=c8@1(BoOz1QvH}pS8$kkf4Z0BLdRM2HU7q#-1MylCkhLK+mj@42u$y0F z%$@I>U!kTO!rUw2`TLUGf1B$B0LkXY2RDA(72+TK6d*?opO%_oWR)j34?oafP` zg5Mxu-YrHxAITgZybAg#d0_8-YSTSreJz@T$>lYCY*Esz z5@HIY&P^B=TSg!g?Kjv~N1<8LHZh(I4wSC&#!lszAmNAIgPp^F?LOPxf4cGHt_^J| z`c(Yb>B+H6+$b`rg_BWF#bbZ8KMj*pQ7C3YJ0X%`aMZy8%bo#3*l?5)9~h+w9h=e> zy1_Go-(jFNn|mBh|G4_i>erx)_5-C#8_mkY_ec*tI6d#Q<2r}LFQW0U<(Yk)q6F1hlqIBqbvC3pPshPp#5l_4&M$?h3Ydsql0C_Lk4Q%_d_^b zqVQOnfeTxLlZURWi`U~`pQp1S4qBJv(fMn%11DDOQn;)==&x4qQrIdENB_;;r_jx8 zBk0)nPu;(4>?2XzpSp)TPq%H{YzI*D&IS<9z|^Ajk_!g81r}KFayAj7`?5Ui)mCg? z=rG!mbd#E0m3_zwKAgIzxh0r;H{Ce|n!I^>$h0Se(-X@T*cLN?V+j=~C59lIA@Axi zt?pEu$Qo6;PLwdgZgzfol2OE8dSjUIUaz+faSIHwir)=RM;Dll%a&-sc~=JT2*2U1 zfgHxIZ|=4Fy=(k9?XR|WF8Ms0M4pKi+SU-QV1lpC*+pyd4rV!fThvJoP*q7v`J3~+fN=-KR})*J~BiHnn4)jPCKyiY!`VS54ZO>HV?rd zjXs3+!5M`~9w0lxl?>MgI=-oph02}(B`npyjK*)_>I^bU3-g&i#!%=4t-M2(ra%NM z=o{1lICf7#FBW7i0&XD#pBWT|N*pn8k;$DC`d#aOR+EEz>MZTcQVL*hCY_{P)V(2??Tj~GvQ+e2eH@SQ(ZwSNdnXk3)%eXLr9 z&~7kWNafs%i{mxVBPXR77CCr=nY2g}ML&57A_UBQ0EZ=p)wJx1C0@;7 z!5b|Dlx(R_J(d2(J+$|tdg2lr5BpR@W?$msTt)W@fe;dU{w~C($K}bWEy;Oi!vbG?+{WjD(W^2t=R-p8d~ukTX*65o-MO%1Xfvz zGE24st1m=g%IGrn-Msi7FiQ8sr-L)xwxG7}wRn|{c@wa6CQrLqX~@xzH(14Mtv}rR z`o8_S+xi+Y-=6+}u(X5TTY96_>hZo)ynJbEwU)DfgIVkJ(Cown`5SW3cQzXNC&Sld z-$(MYB1W-_~9Ys z43Je*7&50b7$U|Fay=yA_DXtv%sQG|w#2+W4Q~27lV$j8dHEmi+ z4SY1j#Gs;(3x$2f9z_vnN|Fd}lxekKTLPJN5-rM%J{?Sy2Vs$MTzUr*y`RIRiwkg& z=?U@$Z$`z6FwX5FNjf$p{4|Ww@gcbAQ_$;Suk67L1L+ZL64nwq3Lr7J#MIqDDr79! z95oHwq;|RaW^j!8fFs6aeQgbl#n;H{X#9GuKRRB+CNn(7`Ew1&2qfJbKx2TN=KS^Q zS^w`=FvJzR{i!2g;mGANN4^pxU%|A&&tbA6S7iIhB{e*qxx0omF zh<$M7O~pJ8SqQm&IcVu_@rf7*5$4#2ThCh(p|&YP0cRPuD-z@6eeXi9bz_ckNAJebeHZJkp$Xx>3A!E7Nz{QK1qg9ksP z1Oj$lb^6D175`0#l@uK+H96Ule;9kOzCZ&ZYpeRhuVFHwj%hWjeNwy$c5uU~QT7KP zgfKDfK3&FNLM{djIo3T|AAA^Ic6ccw<2zH-tHy+uY>uebT#=*2@a*DLQsjUgZSOu| zVhg?j0=2(wa!$Csp%=Jd3(o;6N?=%RohKD?HEqVa!VT`&#;3s6@rHFI$z88H15OI{ zO&jODpoB~t<8umlIX~0t1F5r;y_VgfI2AW}x>TNZ*VmUsVZ0hrY!r-+AtK`*FNidk z#I{sPi2+bHSLZ^C1o8`@yHJegYDF<8UQ$wW?RI}mxDcxv^!Ug=W>m1uA&EWYiX{cX2BTDRTz0R-p^H# zsd&M~<|?~&b#}p>mRk0?DjdM;=4!sFv$Q&MH4CHC>vNcn<|+)aK#$~em41TTVCR#; zd@%p%bo8n>ClQ@uqBnUfYA!JLaqfFJU(p{SWoK=Q#D|n1y)l?$c7wbt8GE{23HS6z zIqWPQ+mf#>#)TjDH=b?&*xh)t zgZw~lX}~^c9k?oSp{3IT!)^NGCTwKfvNCAd*SJBYp7TZmce7ZuoRYzVVU&{V zH?q};JTJc+d3CK0IA*G{@(|h@)31zhOowBC`=6ih>~C)YmYtJy z;D9Lr$0r^{UPHfio}JR6)2bcaabU+}I^AV3&NV%mIRzxX^hRvnu&y-DOIDaC?IMM z;lx7iFDegSi-u|wn@DzJdI4(x?;f_=uXyah^8Mxy@)OcEe|#-JUPIl0BybDgd?P=v zkuGHPp1|B!Vee)0U;P|>HmH$zG!KLqV(B?Xx3hNJmq#4%x zRao!mu->o2dcT16eg)S1C9L-=u-=~=R$UnBcEf^#^a_eephWwGIuY#n7&CxJ8lQ`l zk54IX<_36CvQhnK_E=TAEt3y9-^+{JK`2bE;F4wQ$`z6T&V{4TD5fUivn-cZ=>>?$ zZ=Q6SAnO&Ts(YP;sCyPiLHDh>=-gHz-~W)CJg#=BI>(Em!B@+yD^Y{4|wl!Gmb0;|XHM=+J{PVGfWLsO8QV8xd$QmGfPO^c{4?@m7gx=4m{_B^k z?FVZlmxr8$Ir+H@-hi><8Kp<5!k0Z@1nH3^NrnAQ-=4ncMc|6x@XOF z#B$$IG5y$&qAxFEf5SVZC^onIXayJI!u1&1F;&nNZR#A=HwE5FOV)2c} zU`=F?o&yN>>+{QmRIM9tD-K-{B;Gy6Dg|Q@9T3Wvd@yI5#q>beQSA!y&u(A}ZZ_ic zQBAK<)Ii5&BM<{!!Na$Nw}CxFv9YDFL#ZEw5EC0YwYHF6bY6|%VA(?iPA}cqDvYKV z^sRxNfyM{^rA#M>@WyyK2z|#iawG#}ss)PyDP|Zr>oMr1JdJj8qNOX6G@d^M_f=o~%SI{$DW|S*%f?D9UgcCQ%xN+x6EYt%i z5xyv2Xg4)QH4LJSLEUsF%v@73seo7*-HCpb>bEA$|#>w$rw5 zQQL^32^0)=39DQW+dJpSr&oQ4%TZJr2gKI>hu=~PU>3VLLv zgfxv%8!ypQJ^@oEGl~m!q{cRt4^^6=$pR{(NVUo`X)4n)pvMwAlf%)WL^{AKog4J5`rSMVp*KVm zx8<%}!lhk$?S69eu`r^|dXv+TVQ`{vVxbC&OdC-pCe;a7Gtm0r!GrDH$L{UEw$^g` z?53it%>4Jg$Dsz?E*Vs~~~Rm`27p)B<23@41+a@81X@ z3;ph(!B6QzHwLUr4p@1vIGh=$#|wH`HSG_TeI;!{!j@od8=d2}_o;6fYN7D?;QnEq z;beph1ja{TMoj==(z7l&;|nxinfFmN^`Z^jt=wzBlp{h+G>@)m?DCD==ZAInf-AUB zHk;0VXf(Abg{2XG6C+QhmT3MAYA|rNM6yudE!{i-vhM_yg^M53CinXU${4yTZk$NU z4j*g6r=E>M(`muPkd(}Ef{`?wwRRr17Qq`DN-I4suDUIWoCXk828Sq*%Xcm1Wm6l= z-^$BbQ*i(P-YJMBd;{_;eFbaR?4w1D2vA@Bc3w{@0*ezAI<8^}rsHXlDvgaw+xVS}kK<27aSR>KrvO!fi zo7FR%Td=es^c-ijO|0=-|BG8&4GBqu(0jsMXeE%OqvRI@!{zZy<9USS5VVDCmt;?}p^Lh2!s`+8bmdOl$nihyvZY*cVd z=8BIx3PT$Wi(?P46R$D}Y?JXOKr*3I@|#R}Cd0xq3H;!@YiRH_n$ylrUCj1E4kW5& z9k~m<^#)}rznPAhL_yHC?N1i-g8aR8w#l|v7hTFy<)6HO*!)&LCHQ%tHd8jYfJ zAj`a-98J@ZB5?g)V_tYW5joe{0~SRLDUhbh{+PXE9(%byr4mqrNgjxDnw+VN>LQgGrq+rl{6)C}C_`{Kk$Q$Q}0 zln;r+adkps0yd_2*~xaDwv4F#5-`fQ>j`|K@gvDs6@^Ro<1@wl(qMXXvXdt8)8h;v+uy`f1rf85d#z>r_Rp(UWfh*N62%+it@L#9|rOt&@7)FP5B zcYO;hNefy01kHeJs<5m7=I2kySn6w&_C{~U6jaiti!|Pc#$D2&=eb#t3-m~UB6A|5k7-rv7~x6KiumIDZn4|)){{BKbR8Q}gP=uJN9Gw{SC&3#cu*Zr|Or{dc zxI)*`NEj{Q4Q2~GSC!blHk0JVH+!*WV=Ygqr@HKF&);fz*Ob8`b&VaPT2@&E48jS3 zDk^wR&w&8q^$1#RiesXTddp_+Q?|_@VlytM&TgtiAmH+f4Q*1KnQE)hAvQE9wd$=c zydASJumZdR;_T;r;?sDea$3Wdo?cPj@ONL1G=j1maw+EHzzc;yp2}A=Ppyo6N)p!F zGAe6yjDUTetJBtL=yVx6Bgrgs3zEy+PSjDWs*tU-k4Y40;2%6C3yalm#Rs>degJ!w zT!C_Qp58tAc{BI2?x));%I^0-q0>R|Jx$>iOgC(0P$k$Yf;*$0j2hU*V^W+PAwKCi zfn`yZYlXvPl5@rOm2vj8)@4fI@p(opP!ko)7>(Pe&mq9zkKZT<(&a4NxNlN@4{;RX zo}=EpX}L0*sJZS*+@h^n3bcNFnbNL9>d7qla{b$xa^Yv}4ooFDmUC!NVCVK0? zOMv8*{%OYf+nMHTqbC1#<@L?yvxej6{Qg6kLWm(}Y zqDxk~6lTseK2>Xhl#~hMH}XrH^ z4#MCfK#FxeYm_+xO24d5U=RaTxLpx@o9S>EIVk^*8KI!66ID!(F=(-vh}SaAezeT= z#!G@~*3vVhw+06ey>zxF(=3eE-sKA?>mBhPr1K1$k1B2>*>JI`Eb7Uw=|l}NWaGAa zJDpk%X7wrF4p=`JiVkwUWdw?|$JWXl#p3n5lPd*|8aljmF8-Mx*&AKL*~MFhminn^Voj{r|Wc*0GnWGks|^U21+!PAYsY*fcoouKR#YKy6nazK7D zJfU@Oqhu*D1Gus5Fd;;r^;pb+!zOf8X%;Ltvtvyg6SmbKclUP=Hx74x+Rg^3tY4_W zVW>3d(dQN%fJ#FNnkEBW4Z*e`idCI~@Vv5fN8ee!)MK%!m!0iz|7qs{Q7pqWmDY34 z-)_y_e99AN7KxQCuGVF3(MJj1n!!HrRO;+HWv+nqSlTXyjTS9rWNjjk$TKA}oD=bi z!a>%n@hqux6N!r)U(k0jo+D>}+LSo;u|i4nw1_Y$`o4zcFqsN2a8kI+bSgmCQ2BHl z1ijULyt|7@jv?7L?fBFN!2>F#b52&uhInUf7_;MkWSyWLKU_y(*XDtkpyk|LhbKeO zrsQjbaND4eZ%{Z&-r;%76i%zZjRtXU;U=tS7lS&#N)>A z*$`DIbc>wM@D8`!E@` z>q;lkJHoah9yAsS?YJ-mWLeAV=cMK!bUI-ho$p9ojQl9x{dcP;F#HO?xA7ejW1WeQ@dPb3J;6LtDk z0^;@@YYH{O-b;CWnsG)k9#$C{IA+bO3(-9*d=v~n)eM0OqGHb8$czO<0%TV>Y1Niv zI~Z&!1+jyhrgv&+K`?-~B3me36H-3P)&>ufINjkoGm!%}B=l<2$Z6#ykxnTITuI1K z_o-n`eJX)60;~RT2cpCHvPWeUt}^jU3w}6V@_-8Y{QZ&;8hbL8 z*Ah~uoKJvSx`g7!27FL3G1#`VN%08J~<8cozMHztb5>YP(9jQBw zREt}m4nl@5M3I(QB1A4;H+r<_c=$F*Qeo2DQCR~ak_avc7jJkvv&Pa-@3FKSj)qGF*slJ|YsS-vyKh zaXEr|U)`LVb*vIbf|pSy7_6L#Py^!eMP=_vD3+pvP}C88=4GAP^BL_y5DSjW>lsv3 z0gddda5&~8)Pk;9lU_WcrNEZ>oe5+8(Y5EM-_sYSVYE4!ovEts!1DxBM%b4b}!=`_}&s7Vhl#EW?cvE95N@RNlR(x~dP zYYV>l4NWL*IC7bRl6_%I#TSWi{RF$D{3O_7ZR!A@zu^4+%bPdLusWe6l!^ip@#j)t z=2ce<*uDTgJM(QaZZU&sNSI)uJUBo>xMm)NMRBr#4RN8p*aCJDR>&RbnB5ye8!ZiI z4*{;>rU(lqLQw-|P`q3c(#;yv8;AmU83hUgxYw|{poCxc6fN>lgaevt_%QsBz8Id{ zsf#Tzn4Y>Run>;6P_FJgd%WA-{+Gk;XOgGMqlmx^cR@)SsNbjaKd*I|bLJP^t-VBm>|X{SdI)+vSe`su`#1#pumX7jEo%@543MHXSVJ>FuuMB0 z1jT%>iFF=Ef}M@CSBS(tx->@^rNgYF|Jq5TN>m=_RlTTCYY} zpj-tNSQaIoBOg0Ns0>RB{BuvheJ?d*lVqo@W>!+4Xjv34?x11ep~mnE<66k66;dJ1 z%V`6m#_*Ed9f?aM!yARJrZiP_pJb9M9@ZpA%P&%umix$^fW$oK(%AP{BfI3Kwf|oJ@~AzdOHzodynOJ2@UJzIM*G1dP&vdN ze_03Zud81@dT{heJ3;YmRCil{z%SFm&`E!Sak9(GGf_K=?@WDCFfFsta`foo>Q~YE zqleY*6{*m018DF-_2Kb>U=kiZByAHOjk+XUmc_wf^@)TuR_C8OmX=Ud)KfrFiKBXH zI3P;}A>%~9T||`Zw0{njIc*T2p~`QuOOVPReDUIFY5n0#P}$xCDt;c$Ap6$QaWPJbo``D#jO~W!-<3M7QSgX3~%d2n==3(>2IM>Vv-pY;@7XfA~6W-jZhoX z`HS{BvV^@@8rn_iz@L&QxU}jj6)Nn|*iDZvu@NpFjpg5SM3@n!Wdh+`kZ!F~1qqcY zD9i=c&|rBq$TmCG;axjoD38FEY6!RY}zv4Qi-;hVsiePflhVSpxCh4N0u)5ie7^1E4YZaN6$v1i}+QR+C9obcor|2 zq(qWbQ*12Wnd;{#zxz0)2$$C>5~Nv`DW!PQp7ClEDbXpXAv?Oo!B0=7RT~|@txdhd zZGWecuNT`#hNT;d?jsf`GFc)^o;hp5W{{p0u%#C_fvRAw4xQi-GVwRsUt4{Yo4+k-4s!Q;4$5mRr)E&EM9^vBmYqBV97hKl5^V$G@bY*}y{Tg=k5 z2taB%$-o|aP87=FwYNhgR~ZiyHUB$H)dyv`6SKjL0#8QovCX6coa7vZI*`9GApfbN znJ2LdmP1h$`^ivrOa@cY-~>rO(PL=M!LW-G@F%k@;=V5WX^ClRsiO6Y>#=#<=8UC7 z%tWMO@XAVv<0iHi#>=~{VsAs7rRrL`+e&cR3XsE_@j-iZxAjC85M36zkZuzZx!6Bz zL8I@soU~&F!SmaENaB&IY9zR^#HJRmVqPuEO)&pFunJ$X7sgNcCRmGm!c@_~A_Zn( z(b5b5HSWT~wTDq$F~l;?bgZ2QX2VhqkE5-E_po^JD2moF#=^CSs!vhUE3dR-$x8mO z*T)FEb9#!TUfttsCMl%G7!MJPTJkINge~WJMUQe9ISX5Wgy1P=Pc<~=9KqJrbj-*F zR$n_~$z4(regK43J_AL9IyI8F?A})kFegVfFuuRfE@T6I4M1&snn|5UB zpE49*dfQ5DqFe8@^^T8b3xz8Ub%=DbLrx)Uwu|mo|Ar=@H?UKf0U#}yWCC1gm`obk zq>%k#v-J$AB9DpWLE;0n{BW2XR4EM3-(pLl0Y;&5UE^QlChW*atDBMNV2$n_n0Eo<2 z2UI`!P{XQbYnkYe3s>j#j`-{;wr9^K3z+t&bQ2p~;ecriW`omhG*NTJ?zT z&-a)Bs=N7g3;sa$*E`P+4mX}W;rmzu1y4v};~}q~VWPKrsz9z){vjMdy{%o16R(TH zpH(@d_$BXULX6`w7i`eLjkPJ^RO|8yYRYN^nqsMBTN)N8g6y2*?vny+vy1MUN(-#v zFk^}y!Zx+=R_0)n%5&1dyp^Spj~WLn#Y|ZoRo-(g-Z#+cgq&{tB?&uz#*mW2pio3R zUr62FU8r!S;$&f$SsDihUpCyj%OH?2GFj2Y^i*9^Ipv6&7CKJjQ9AOO;*2n?gkiKU z%$vMb4^uwtvs;m^X$iq~5GtJFpdlUiLP!sCIMuDlUPwvDs&N@c!p;Yd9Z=gNnN>2N z)w_$ZA=dEh~pIQklkEupD(P@LwS9Ltn%4$zx92DY6u4?H8 zG^yg3)`ka7YP5pXIrg3~VVjp5=Rr3BsZ3_aEtODUyOx-=t*-^g&v!7g`sc}<#uBPN+ZK)0}Lk+?*|Z;&Oy zx3XAlYo}Yg6$ID7nTb<@z2dFULq75F7{=XB@yu}1)W$|W9{%mdUZ9m)Eezv)@eb7DF zee%=Jvp;dvGDGr3uu`JdU?)N(1~#J&Q^-)oI+00($CUc4H4-m4s|;a_3VF&4f?U+o zq1BZ;toymcW{AVj8#e&N002vxcMgdA)ktn4%HkMZ$i)45^y-koxHQN^J5C^K7{}W2 z^{Fwztd>0_anYIudsaq@qU3Tse1Hc0_;N4kR8l01wcJ;GzO)lH5|vKfy5Mt3#j

!g2tyXw_U5PxaV^g}ZZ?A}b)HHGei6=`IP{QtP%Rl5P8%NgM^hRR8_adSBlS3Wm znG&e44bX-Nq`_AjYN;o$!lbGiFo2-P;8sQ_@!ObYE?dJw?fM*g7-*A@nGM4W-28>V zXOr?diU6{^S(*U8{|!|Es?I{VjMo^fNRIG;_K3%*DMI(<=;|0({i8W! zjP8l0S22>=AYAo6_soU#oo|dcP;;#3d5B&RWbIJOy-%zFl=JkNs{BJ%@)I7jhLF3V zhN&$%$1dENxR<0TF4qQW&*&;^OtqtSDwSGQ@Ql#BJ&B<~@iC17*8;L}g8bs(xPOJi z&eS;f0d|eq0*{*L2xk6R4y+482O+M%An@5sF48*Q0RdIHK+yIvv9BMO0Ow#&v$v7V< zz!Y)z780`Xnu4%|u{TQEC5eHRC1D$)ic)n`a}}h7W+t9qo0Uj-Lr^ER@EB7PwxT@O z8Ktgxa6KL9RHgtI0RL*|gXu$;E*KcN|D19;t}nTW0&ZXm!+eauv1$zk7hcw4B-(=G zV2SGmoaW_36iV`qSJ zxd09m(>P?LipkcXo|AdW%gj7>4qyNURu5IYpu$eoa^9$UeRSI2abwL}w=z^Sge)!O zuDh>tT>*BA)FC{EOS>=e=i%T5vTLtaSSCHWq4SVHRV>O8fCbV(vMe6nZ6p@T7rUQz zii4zzbvZ947I_Gya4uxxH-Qw|e54sKbJ-$)UEyWKMTlG8zH!&QQfgCVlC%c34i_K4 z*<{<<*a+v=Ct7MOYEu)|cBl4YyQu0y+<*RRJcc4_PpK?B*v!2L7Rzp~EpZ7k4Q}5p zZVO>Yc2Moa7jx6lq@h>$?}o}`XShPtANFCk3%aSY(1z(tRbC{u!=b2FJIiTxe#{tg zEc^nB(zus_GkfU^FHS_3K#~^Yr(7$ASbiq_J}Y0~pX3Py8g7Gt(j$ReIf{m_h%UUa zOJ~E0${J$0t~3gU=@)jUvb)9}&5;-4uz9gziBpR*jjI)nB*upQK3Ha~y`r?UO?oz1 zcft=Xm%J(&@UIY_EJAC^rN{9_(>?Z?J(DO==-TB5Q zf_;o;kUsYaTmUyhp}c|oDVMF$i7OD2-I4TC>#n>3Nt&{&ac8{`9p0%M$Yvt(PGNUi@r#utY_#u4RaP|B(v1h1j;S!cMtBP)#oqRgEO==T7 zVeXw?y+)Gk!aQaoP6;5MQDrOr=)&%#5_(`cn&pfyT548ZUb*da1C1j?; zhQ#toM5q=r4#hYH*r^W8)xb0c?l^&@?CM64$xC4@cOI7o?pSd51rfPtby&4|yHAEx z)6VZMw9SJ-9_n{XOeH*5=h^U35j$<$rqm#sR+enr)ZU0M7l$}`)dA??Ch*1;j?C2q zX?^bLnBIKeupaDv9MrMccWP9yy_f(i<{^lUa%?jKje?lfeO>{O_dL!KPzx21DmKb= zDjr8m;3s;IAljqx)thc^0Sh6oPnWw})#eFf?s*d})Xd2WyvV{;^vS68p6opf4=1$FRtcyU1b?sc+g52q z!XZ&^9Aye?7>tJ#tlMk+$9LHL@HV;j1>&l^YTQ3|rjMC$!9h8vZdUajWM5qJoEO{H zs`7`Xf!xQ1RBp8s9HtPjhisNkeA2&H=KEv#szOh2I#^%dfBs~<`{&&s+$y`?Fvq-I zzrVe4u=|Y8`=V>^w_aVh#&B?jN8D=OjV|suGULP|hvP=NF>O!@jW5dm?SFp0v%h_C z6G)#8fU2YBXB;$QJCOekIR{z2D;kqCU|I+6&mnvU4AsPWHG1R3m_8n{ChXr0;;onw zvTZ@L%o*(u#=F%BWewt{8r_Ed4<;0nfMvHDUF5XCqlDf!O@`2=B+DRn-CX_x z$IqL3E_U9VTACuyae0}`uIx?%s=*-;=$wWKt0}GBIt^ND{m^_2;?Xp6yHej^^;jM&8susuSW3EZIw`?mw6H5>$`%EXr%!c zH6*x8EqrDxo&gequ<&8yQq;{Lr_Q>k8)OX{uEp<7{Mwo;hB4WE-=KZS*_(-`Y10<5 zvhLG-HWf;*0J-&6KxXyoFj7i&N^Tz4zOCrk>`V1%R=qND{v7jGM>CFosbN`POWeaZ z!$=bxq-wwOM$P>J`~WBWq+jPEu85;`S6WI&pUWq5wpzmdg7}oktqCmQwrOk}Qd;~p zeeFRyL8!T6?t!@~<>5hrC2eWyI-onUTuEgn2Hv6<-v~^!d2Z>`xc;5A48AMROSVPx zHscxT?PdLQ{02~TJ*|coFpQakxSw)B368;>a zT;e8j3yTCt}HM;Rs@-w;tbdnWh8 zxxDnY0IAY@l1>0qZj~Yp&9K>$Os#7n{!l7#>hpyGmCT-;!d*}=YwFudeS;E*9+k9k zx+uD9ws9>WQsRdcbAa@bV<4Bx#Pdo7CgokTZ{C6HETs~U%TDHKqSki})CzB{j040o zrE{etxex=3&N~EC?Q_s2wxH4HyTaS7(nsC1AvpC7l#p+(m06rg1$nJH1vrn-OYOVg zAsC*ftjOnfL6c;N5!g}DtnZVOSdEIV#xgZ_zVgr_g(3A(;3Zta%sUA9Z1(8N>zJfz z2OZg(u^xq!)R;VA{H=|2xD+@+RPUM;$vFoTCeP4Cf?_I~t5r|8jY*rEZQ`Lx4kic9 zqH^w>zk}%Ir-qq%w57N=E;1 zFUQ`621M5Ir!gfmnBrAkE1vU_#G|}ru7RAmGwO#=gXCo!e=>1lak%g_OTG&d z&KDC2CoON=5`}pteU3a$Lrfvm6+&ArE~4Th7_~F@Q=CiaE1fHAteZ?%Qw&|WgOtiR ziAe|*S8JfVB+Tr1_kd11Lpu2K~)hC74DTT~tAxhlAe+1G{lgxqHN9jtR7=T@@4M9AOM(n-{Mj9v7jEckXNDQvtsh6{Ssa^@-6qatrg2(zO(=oK07to znkPv**)u(fG1W=OAArC3ZODo$fk$$Sn}b+-6b(AToD@_mmwk-d8BBQ3$)|H-ZAvI(V(>=4$fQ& z_FH;LF)uP5mE7!$zH{J$A%P{;4$2iN$*N~+vI`ww^ZE<1i}=WntWQR-hsW7LHSfbC zr;N@|#Z4Z^%Ts7x-oHUS^d2+VSQt%s;a|X3h7+&(k0e6T6|XEHKoC(%sxyrh<%CP@ z_J~W0)xjVwMiKIGfAD(nfeCM_{FYMA;YeS?L_$z1Z2^zu=m5(NX^;W31~Hk2u1uJc zy~Ng)US-Sqpk4W;EF_=W^jL#8f<_|_qAB*^@**gy0FIHup(CQfBO>~j@TqLC@?RN^ z=FDswGREwdr^TQDx`;SCGrC!AEiQc=E;ciZ!K`QzB4vq|H7!($Xc7E0O}~_t>E<`i zYcVTz1~kLG$u?xV)KCmpDy5WIS^o~hWUY|cFybj>Q(QoR*aj>!^0aE?F{#c^^FaxA ze7^a&Hs?Zlj3xWLev_G}r|^RbuOrhzQFrO5=}=7ZVP;X9VB9KW?OV#15NFIcFZ?d;?iUwX(M7)z(ARX zT|r-~Jjfzj?KVJ>57~GjV-w`sa$!|i5n@$-bZCs6KYSNPo z>>OX7>S@d{?4v;k$yqA{3EZ}cY>?!MhhTuAr^_!S4McO(LN~G6Y{!^ubI9O8SBW=e zXmFjEaUWBD8l*`a)wg(95#w8cpzq_gkgYia18@KTGjHy$@bX=qX6Y? zfryJ@eXu_^3-aOQ+nJ8*yLwQgvP3W4Ra7^^2^vbGBb{i&av>#EYmhYaYrF!9AF*Ox zY-RTrIi@Ncwgy$m&QwOuC*{lW<`YK4#VjGN%{0b!$aWN!W5^!^oPJ?b?3l zPJH=^NfwM8T+mq!0vVAM-#sBwC197(AK{yN0)qr6&Au!o^q>4CmI!NCqZfa^P@=LELUcxz2Gu{c9PLnrS;hmV%gA*N|KR4`;q+u zCJJbaw;9a&o2ig5l%QjpwR@^_y>ot_*0sH>bUQ@6v9N~!F>sR9t10C(fFWo7 zjCSfV-cTrmr~dv{aOvR@iQnZASw}-W&$`rSx9SGxI*pxYXR&%m=|$F)J)GWE(+qD_ z;t*mfRDL(~T)xi%sJy!!9EjbZca>m;O1FvX{a4;)eW&Ns`)wd_eui6%W8k{kY)M#^Jv^3wtg7Bem#U&SnI*xR$tlo?_sg;ufCF^Ed3bg zb;-O<*W}~T#r1gj`pu}(=O{5G39 z;gS0i-Wd|n9hkr|a*V;SSU%6*_$u*}VS|ukd>eQoVEy1#n03b}g?xw%)s zhu84m3Z(M$esA2Lti3uNy;?i#L4h$|>q#WOL4Qq}UOnqugG4J7yaIx$)qIvB)96tK zCyzl23Tv*d;bQJom*DIb6Q;Pwz}P|o&9dt zlMTsJ>1}#_)JmUJ|6~m8zaNdE{wbhEi0a`x##iDbdyL(|xCW$;sy1BQNgkYAFpS># zSVKLaEseQ1Kx_=qL}&1NRa8cM+Z+24E(4i;3shilLArq*3D-A(+U<>7*%ZS&=Sp3J z4?PmcUEX(MA^-+A0US)J*)t+RSSXIDhE{eNbHP9qOg)49*h~-);7|Lw#oy}Gsv%qC zIii3db3LjEN5C~w9Olqk6>*x>Uh~_Zjz$P)WeZQJp>>7(TDlPBbjT@PV0?tTBXok`SLhf4u!isGoqBcQ97foX z!h&TA2*D>{1H@YI0~I;Wn0pD*z@&GYQM)(uJxJvZM)nx@jsW5wk{L4m;<)wTM4o&< zQF`WL6mI1e=Hpmv3kqV^Gb9yKHWnBc?0xy+8XVa!h98~`&R<`?ne0u*_kAB1az(YG zB!U;uF6KCIDwxA@uL+I;+rBpygreu)1?M9YOg-(XE*%B-pw~azkcOj$3rDEao3OUen0j z#fZjT-hu6!dRnEev%&cFfPz&+b2?l$29dOAGX|W!E_e29B&3YmX!6tl%0nHAPrLSQ z{WdiG*p?>C-_US5>$hoo4!Dcv@88tCtSnH?4NyCARhpB{ni&7G^*tn+-kA~}t5gyJ1iYspsqQ@r-2;igEXGOrA> z^RL_;?Gq8+`~m;g+l{JOO=-i3Cc_nsS|S)gKkI>`RIKS6^Jmm#ZWleWZE#hk#k;Km zU#t>NMBu!r%i=mJTFGLA!qAH9RFGL;+8f8w`pcUE$4b(% zp~;q%VaS@9N=15f8Gevc8ermIMUwN+CVGMaNyb2xoA^3=Qihzbr)U6| z&c>onwCQ?r4*@J$hacIN%$`)=M_y=Mxbx{ut0_rq>c55@eXV<0tr9R*9UIOrc^h@u z{p~DDnzQF@uk2KMWgk_r>eDh$AC*S4Nou60c^bTlu;yu_K9uTErvfc6=4Qk9b6!

yD1vij(U0JcCtJ{LhD9RR2s?9j%FX;-qyn z?KYhioXXlo46^0>>#%p6CVW@U$8Q@Zf^2aQ3ryQo*@~XEpjpIdyVx4yWb)f=4SFsz z2<1<}qUjC9j(h#=uC^7`%oYVxAbFhXV;1 zfBR18}(EZn6b?erxTeoiAx^?Ro z&}~pOJ#bl1lflc^NpzJb@In!9B;%dJ-dMUf>*|thTQ}(E4rs7gRzj3P*THwEU?eal zW*mCv%`e&noEEigA>Vr`OMM9ZbsG(euJ$3U?AHsj-qN+N>0|k|EzE_~n#AsgMtBoj ztxUZf_Jr>C1ezc51SPd&@^>s+K07jEevKwfP{7&~&ABNcsgB5)F#kX>$}nW@a$dS%vV~!mWQ_+Y*rj0w`l>i zyY)}B{An0Qdq&czTCbr$IQnCdwS0VAPiNgS{!z+M4=yhfC{){VOQ*0n3g2m@kU4SCrx@d(|LRs_b$(u!`Kd8nr}>|}R1SZHeh z+*J4dY4WyDlfo)#!8x;4U9Zt-Un@7BGpHk4QAVzy~) zV#l773}~Vyo{0)YJVgamx~YhH!RtJbS)#DR9}U|f(75WbHbt9Od|#8a*ya;#Nm9U# zI8T#unjU5hCPA7K07m6=u?Fv8M{TW{)}u>Hi7r(cEIUJPIT1<}(TAj$BP*Ni&#shU z=f}1XXa{p*peETyZP|DO#@VKv;mo744TPrjfm|9kV{ohx;?HCyH(-~{yyTk97mb)_ zTCWM0GTiZc3b)EEVX)OhiuV?pfhRC>6VO{plLvUv8x67FaQ z)Fl6lqr>6>je#V(^OZ`iY~`{k!y>}jHkOlPmkVLoTCrD-fvR>`hRr#R6jvg-%rkMV zSy&Vl^PIv)+L$8`1Ujr_NwdId)TUGw-viqh5sYxc6`SIoK6wlpi&5Ty&~AG}dxlC~ zBO)hhttCGUc@5hd3kotIj)Dz%_IFV$W-zLvY<_~rE zclRJPIY0ZnlMF)D*Sg^z)4g72yPIY+oLzTX#{kdn=_ z8l>Aocpm8nto<1F=!#e21yO_hlqX6jDNUanUmWz97IjS~?K5=iAZJ2&FXgX5nE`vk zGZlfbu)VjQKXc~%xGySA5jH-C4w7Mv<6kbuekb$Joi9#Jk4~J`NcC*L``IPhD=XqD zWTkD4@hOc&l7eXA6#TZ<=EczkUScvgDHAMipruqu%2%-!YGckSY2LRGCXM^V6(w=B z(+p$h_Ti&$yOEULT^%?dofKzijyRkonHTO`IAG7aDe5a+f&oDchhRW(Bpt}ZgR3|^ zGck2xZn`)*G&O{;`+2SoH3eLudsAMsNo{MzMu}>JF>9S{i=~GPBtf|((d~5vG%Try zki=#whlbQ_ne18D|1c~B*Aqz3>dXuukd*g_^)A^x1DBMwOfZ41FRN|`iaf}!o)a#D z|F;eb9JRo0=G|E&N2(K7iEabp*4T!ayK2*1=H7&#aRaM+lTMANL{Gt3^Q;#t{kD$| zz)6a_T#lxVNO@D_OR{?=wHi~XS^IjDLrV~pc~b)gZSaI02A5vaVf@D7l|lj(^Om1Q zn|PSuWhnb2(G;4=8Zt)@85{M#2lHDD2myhqWW+Zt?TbR0oogTrf=MRJtU?}u&m^v) zd&;fWT53>S6g8^cOCmOhKLPi#7c%6IvkUG@o-cX|`p_gu59dzxAtgaPBkv$VdKyvgc1V!4 zpI~zeHE&;N@Nrfhz$2pBrYC4lZrZ>gE|=D@2$gI8<_y#v^>v1h3}^W?(%D_A$jV`3 z^K74n&plRLs6y_cwMw7?!7}}BZgTN%Bd{vG(rZ|}Z0OSIAiQ(2V&KiYRstvQsV=hM z!8Whf*vr#+rL!SVB$1x>LfgudgBK;a{Sid7Ew>-Yw+}&yzXpKv{q$I&x4Sp`+ULIZ zb@xPHeFiKq+I2UmeQ11gXj-yN5{Bkp+?X#H9$CG%xuS1|PLGetH+j+5)AOJ_J>rTe zYC}tF*u1PMcB?$xxh~m8rnT_+$mH1MkR+X*8Jj9hj>vZ$$yq6D)dt65NXIHdZhw55c@U0A<3zOyQs$df)F03B*fLyu*HY9C2Ra!A3oq`d8 z08W+5Ra}uQL^xHc&uoZQDr{aXRj@u4HRcqrF5S8+kfuipeTCuG5=@W|jZ;Bd0rxbQ zk&w(=I9sj<$^981TpC_sN#g(v_?&14DneAmI(*x)EDEdlWryl|d_>-B2?wEYZkRyl zKUmr9W7E42#UH^w+CRgkRk+oc_;$EBJUZq()jtV=?8#_vPp5)XsLlYc4p~p}?fB?S zVR-zUWIQ`HT9~{BKWbsh;pnkIHs(nYcvs_UP!DNxLa>pcG(0jAp{CyzvB{w*-Hisc z1*-+=Q)Du{Hr5w6s-T4y8!nu>;P`M@9$ee(K?tUAg2Ac@13F6e;p|8p4xVG6@)*XgFR?b z`1RaSVIttDt$7hCBZbpWSSU`5m8GS%QuQg8d2HtNq===F2^oJQ8}(ZG$AsTUrbi~3 zW$|)lb8%^nUyBa90xA!0)Et$H!=9`8)o52nynu>`rlQO@(q?{@_X>q0uC$2LCy=!; zg|HqbmDks0kQZSdt=05vbyX0M0Z}|RQmU7hs};0e0Ts_V^nj^;*PL6R(lu$o=~6{x z7b{pQ%T#sRj!Rt)+2Hhy5asmr>2uMSu_@yANM)(+r1c|XeUma1KC-&CdR3@BM9~m* z-Xo_)33R2(8T8oNMm`5oa%ZH*0c-6QW3fpH%z*gkO z6g#1?`!3MsL2AyoyYJBp<4`L>vMRXc^{vg-jXFDEd3s`K5^T{w&!;npyk1^iokEn& zs=Pikc~)l9(Np7v&B}a@nMPe#DzMSD(lWwqL9Kj>Zz~9krNd!#ZM8Blj4=A%N2DOw ze6=t%JUQy06dtr6gEcK9^t}jpS+2SP_FmjR$b4gyQgOeG6MK-sX5T>_qn2irs$HQ4 zfdF0gYM<~hXL3JhkDWRzLtqT7wXqH>n1@uE-_+rXrqm%*6pv^I9CNh5fG$0S(@nU( zjCsaq#suQ{bb+!*@xsHDrdFyGGNv#_&z?r>MI6Y-Mt!4(KlvWOmao2n<9M{bwXcQs zjRH@>u9lY)jJvj3Sy&NLjBl+%&yy}3-`aFYogISIMgOzLvn5^!A>U3#l|ykF9yu+k zU_<%DG%lYmleX`y!xE6nS8A)}dR20PNb?G9yD?$xk(S`I>k!A8h0?& zp%IbXLH26=1a>y3m3r7{aXn*Sr4f^><*Qr5I+Gi<`f{~A{iyWmW(}t|F`p?uo3*Vv zPJ0t!)hQj9KI#}H-~Q+dPHZ#B6i!;psGJH`EmMw#6rer|ZKlr1RBW9%H9f3MHMKQ= zjnJlt9=Da#bm=N3yd(}6F}M`e^kahX^dqB%Q%<#T57I<^aD78Q%blCQB(D+z@?@??sgCBBZ``UvH5Jr!upl#p~T=Gg%&8By$^7UG|Ub5W!O8w0v0N7N<*?M@K z!xqJg^IaE9g%9==9xhyZ&wjTH$*YbTV-(gbo=x0fKkELU0pjV!Ri1OKZ**G+3oS{` z1hKQ}gUgl5^#ZJz=uN8z0j6O4|A|#C+nF&2c z;Y)?cC60!{%Le?6sDNCGa=Vp4q!ra)X4 z)Y!gNtz-)hMrz@$k~-wkp%S}h5#35TobSAVpThWfVPpiGaKRJ& zD+b5M2dAey>Dv~(m~k(j5Mc=7H$dCz6OG7z(er7(T{+z*A~G0%l6)~{!FV`Xbmu1^ zWZ=kGt(I`I0p41{%SMERP{J5Z4<0XGGY4ESlF4R_T+a#(n2s9CF&F8_WTlOvNH#*4 z&?y4v&dJYf6np$f`3DAtpBa2V_(r54LkXvNy@jD4(+`x4`oDc=T_Kh|LvKiQ53@JY z8DgL^^@muFrgAoxGtn8RIb#sM^X=1K2{A5~rD93UpsGcdH9p$6>AOs;5Ms148 z>M&oU7F7{o=vC^WA(0B5HJoULW2X5!`{^c|?y1yhLS$>Ar=UIUHl$L`@Ewskc#~4l zsamD{3e+NUl$)((9CTqehsOXTCAmol!Uu{@0i-J_;8|YX*yI8YA=SE|=Hu?$Wl(1WF%~I4YFi5{`)^qS)V7wf$i8#KA(*O? z(k|?Ev`+A{RIR5L$4ET&W-l%V5i>r>m%+!C9c1U&IVX$_3HFZ=F^gsFmeg zhalv9zoOEXFx&& z&0$$9qt!T*z{S1Q3=in?0<6D4{s65fC2Tf`-%o!}PrmEW8i)>B`}xLI6wEs=sU3Y) zFh8GySaOq6+2?c$9*?&nIC+bW8HGM4hi}Ljp7KzI5D!u_tH78=MnM#i7QV;~%qHdt97jtULn!rvq4~-2?PL2%C4DFjm z&}q%C8EqT6#U9k=i?jHh=}D<7-vwt~jMgjb)D3B)L6-_DDUSS5hoXoc`Uv8*!v}qr zT}$QS&NPiR<-0Hk9b8!!t;weImYYWayKLR%h1#8I94dllwuD1YY@t_FY{o5ZR?vT| ztC(uB|I@8^1T*XwMKFtsiq|qBP-2&KsMlN2`ggxNGwGc2UB0Li}MVpm(<Uj;4TenKtJS+0EP7J1oS=p`P~N`;-9?>f9SJ#A?9O6i)eZh0q}icDUU zC8kF(L(~B+A`LSHW2wA~IK#%H4pms@WAvHc5n!qW=k_i7((qApp&Y_y)1qc2_;?q~ zb#XXHs0dkE_`3>jcMruZT1^`ZA)%LIh~&A3dtKIqaRpC0jc|QJ9fy>O2NI$M44dDZ zaX}?iZn4{S3NGkUcxMr14hAhUskdAhcxShO#m=VwHD2D6_Ii4xQa`gbpXV8jDoh#h zVM4H{t<6NAt0BX$#=pBv7v-ze!V4>K&E-1!cC*(=V9piZ&x7GWB$7B7WfMbKy_z8d zK3`>#fix=G8Bh#F>j|1YMBqt4uTq|#En-cB9>&RpV|ES89XMI!U8AyiEGE7qV^3h% zXh&QM9HdJc$($MdV!JcvwCK(;3&cZr7J> zq|c!nt8k9nS_Y@C!7s*W(kVl-GmoudHDroNTK7gr7YFaQ?1MQ`*N{-2PBD@vXUdVt zLsfKw4ZUm2wc5@4ZoXbjnz44?=BQN*Jt-tpi+I|i=~NkXmfi?+al%TXqaSl<_IPT$+rk|IlX-yzY)dnYfa^?26| zueK&EP)U7EEf?+(1{8AYkWL$u7|WNPP{a1V_(Ee+*|k=NqtKkGZtuhrY(P^aFdgbScNOte}m?iYGtw_K+$UvJP6a{G~Ou}Y_pzcIkRPJ zfK8pm9K4II4aM+uT_k!!RUJ2$BlM)vg)T!FaN5`K27^PYlR|nH&P^U0>o_|C#;8$U z1et1En~bfHUo9_}7WhWa6vEgwTI)iEgaW?~LztCnURTy~CuQN#R0w@7ZD+bR#H06KM4 zvHJ$mK1{3X;Gj9{abuEW9(k(hfBLr?s8&~a5Hj^U+IsD;?~=yDgGV=>?sUg%t**0P ztA4+OZI8PBwQo9l9izRzRlC!@uC>0_y?zJV9`*Wb-*oi4X+}=o-6=^QIR=M5z;{x> z-|2>HzrVKa4*FX~&TG=$TJ;^B&0S~Tp;l+~^&M_>*weT;0HUUagAz{7zeO!B;&B|* zgldO{8iG(M4tG|G^WE;Mf7SUt+4HX@1;7JtrBk4*$*bP@K#O-3!#f)Sp0(fEo_F=% znTAJmx~uoKYBw(@zT5E5B2EZ3~7TGn%A? zfLp>h@J`ri%dL3`2@l+?0_pwKETcd?bObHdhJ4amBPIn}6_Ce*;WP*u5m+{TAzWmD ztv${T*?ffx3S{muhoWrmnrMu2DT4w*kILxR9-WMpC*Rz^5I z-gjSHhk^c2KX>4Fj{L%@PrARpKlwjCIf&=JKl$`03-bB7Pd+T4zx&A(_b9d)|=CwISsP zHTCe{#OM9^%k%l9e!nZ1dmSI~<34jAzypYO;^%Up-^m}Bj4a2(^65XAnEQBpE;q?9 zCjt5g_$Bd!mz#T#_CPN8&cv(m@i5+>3={IX+*iWq#P@DQ7_KAjjcBIe#kR7ugP(jZ z_kr#zT?ccyf607E5SqLhpTW;bRNbxFavvwt^xzM)$-NDK!OzKD?#1qEt-63TX)6+P z_u}tw;V<|(NqC4Rwt-{4cKly&?|oeIy^?#j_^&6o z51ql&_TDl4zi?su&@3}a`UfO^MAEN+VSDc+zCAtu%C>-*!9)LxH_o8umyX<*>p7X* zy6ewh`r4=N%H>u*x)(S-4?cZvwf|)9^Y?TN;Pv*Q6+Ar8uPYt=*TsK%zS;Zpg#6jJ zKHr0-VqR0EF$m19naz1?Nt6TR@1HHp|`|uC{G?MFYU*X4%r$HQoZ<~Jd zuIcT)OnZ(*xqjb2N8V@lY#-v&_94<}`w)qA<9?v=^k?7n{9!yi{KE(Ef9s*i?Y%D| z|MlWGuHSq84bP0fJo)I2|B`LH@Y412jqAmiC3pWHTK?A~|BB$kCT#t{_THbvleO?U z0>1H=K_?gKEdMEFx^QDz-rUc+w%)*s{xOsLUwrAthw$cW|KLAv zZ(rX&cl{eb{*5jW?fEmksP4WI{@;6&|9|)>{~tQc|HlUKf9a?9en39%n~{$n?vanz z9gvTGUGh=rz{k)1%#_Xn{_D5b_a1wIA8$U^&X3n0%bomh_H4cG#+N|0{ueKO=APWj znYXe=Ru1}Z@B4@N^5k1ry4ul8^LORI#O&DXhkhFA+h4x$O!2Eve`kB^P1{@O-p?ZK z!q=BE=>IG7?$hO0Ec^DCk#GAD`2uB7=;ddNFHb&O{OTmiT|cy{uqJPuL$POyf3&^z z)$K1U18u#${bdRi7B&99!MX8z@sDo24d}dt%HGb(wCMnM<18rp?XSG!#czM*!kJ4* zKL5fi51h>X2LC;F{X0iKS9{C#*JH%qwf&{1KY!1WzpDPbx%W%1d(gz+;J=2sw)cGj zn0^sIO6T!=ZGi3J;6hzPNALc$4Xc0K|9ij2F}3vYnYX>=?|kO^XD+?Og7)M4>CDl) zzwnk{9eV5Z`M3P)kNrUZ?>+YH$h~j-*k4?J$MuiA>H3*B9r^dwH(Y=G-n;+c$X{05 zPCfl%*O4z*Z}h)7_x_79aEi~9f3&w7~FU_sP^<{?*U=Xfqx22o76Xx^5$N=Idc7E$ER=n$hR>K?Xk|d zKK{+cXYM1I3qb1n{|h3B4BONHd&eMlUX-R&hFSjp7tU_@A%fe6xO1MJ?c2*t=n7oE61+< z=l6qL9FsTx43$0o*|!P5pxJkmDtmJMe{ufCAIO_Gq51cn=g*DLNWxp+{}RTB^yAat zxL+vzboo1&v|q_hKlYnv|McWP`)3#|+ebcMzwcu&)!*>#FFnrz|Md@?f42A?4A-M* z>h-Nx`nSHbz4uM{-v7<*z4zPaTjdjNLB6*!U-4W0#c%e1^T@ZiUjG{tfc*70e(cY; zUVr^_pMLrNH-7V(Lu|mezx>Q0R`CA0i@$|YTSu|&eOKlGhvolA<^NB}|BuW6za#(u zzWo0Z{!cC{&7U3Vc+-0pJKh9pKht&nhBS@jE`D=+i?jwiY(HE4ma-8D{VmS`p3vjp z?Ejq`|MR!Ex4-ts%nVIs-wbNFKGSjUv!~v4{k>o8|H6%r zt%ls7?)To$3-8M1ej9&(gukEKpUYM8H;=zF_#43A5904Xbmek?iof5(->=~BQ~3J? z{yvF!{P_cs_&AC-7It-%sN2ZzJu^_{-t%6Zrej@VAP;_v3F0f2Z+xoPWsMgU|mBe=itL ztn(B1pX7)9JoYzE=Kc#zFj+rtO?VexuHx^b58&@D5JX^WPOtMg1%^Ez3k{+W&SU{< zH4QMo`G9J8Q_~~Uzx&g_eE+Zf%%1oD;sby2#jlS&f#ILaEey^w3{7noHxw?;E^aLF zCX{+@_Hw1RB}ad^7AqV1zMkHm*-7)+nq8^D0}R_Uo3m3IqB%_742<$G!hz@Sf>|P}KS3-hU-{|1W;Fy@h;D~S zbK|h7+5VcwceqY;ml=uX}M7Z2p6}6DK-OJUDXhLCXlMwpBqGxse7ktF=g9^jFno}?7ynQB zB5LbvR3cGn-${Tt`9$t#f8fLdf(R-G{T|j%)%Ttp%H`gRvX%8@QF@m*!<BP%))5xs#i+DXU7ku2VQ-2`KYaIz6A!l9HG<}&Lq&8D79f)kvRm;*|DSvUM9c*?gST6Z9Q>1y1JZ}~oH)^QTOj@N>rddE{_0KeqO`3KYz%zHr_T>hKHMY2VDFx} z(pqhqSDnL5_78G%bLeu0M#DuIwcLR{a|`1zWsTW zgX46)ynZ=%&t38ruh(*~i@wj5b4LM9qI1?)zBKHa8dxq?&tKVb0+;kU4I> zVCP#7R{`Bs-Ekqhxcq;b^ zK!n(UuP6z1`K~!hedpbCmhyo;fE~l3MvC!ryg7-*QLYXs{_D9nk}8)GU~cY8sg5gc zU_}+m)Db*;X>+cY%l-OYqihH3C@&VT(w4tm&OLCC+;5cor{UXS#8N3?@x?;u}^b$Yo*4*BEAWIv*{@uGqYa>R;Np+>p&D{Oy z7NVQsnm94ZuP@+ss4eM>B}(BL+(st}x!f-WxXcJ6j4tMK|5K1^7$SK>B)Eh{m_gXI zp&Ae@^INWl{usV`Rc=yL`CjeMn*Vl6<9gwLdHZjUaE|5==W))%9nep{|MR^=0oZl$ zbC=ut_$XDx!%%~n${&4CLlYMF4boRK(qSr!fCO-u{&772{7I|luefm5Kc?_|E(dj2eh6Mu zECC-siF)<`UOiXMRdVaOWk9Q71yBa$_1sc!19@n9+JlXb0sK8IpYyWq@!Ppak?!)3 zpiC{dAaFJTuY$4=YxtSMn^JBOZ}WgyMfw`P)sSaV>dfb^;IocZ|3+>LpLwajlzU3v zF5{V)5tlsP>i-qMTIX;a{_-g&%P07M5tYuEaSAhtrVAa)U%2{DFG`?IcQS__$=c4x?rgok$-*=<;IY{ zEG33f(`N3PP;VKfFcIh8i?piHD38sb4dh$~47QLoDB!OT81>>m)&k(#J>UcOB6BGo zu5b9%44-b`aaHgg%-sh#lYp~>k5;v{f8P!vACKrP`>d3f1=f zR%J*cw;XGiATRC5j~?`}rU^ zcTp5JszW?@%iGzV0!f6rpide4V?p6U5}JL9eyH~+dY|e2MDH*3{!;I+^nRiDcY1%n_YZsjuiiiF{Z{XP=)JqIz3<(9 z{e2Jj4fT!p&GkLmx7qh=eZSfF`M!VI_xpW+(Dx^Of7bW^^?j@FFZ;H?91ANY}heFH}ZP7Pci_}PK~cHp^zPYwL91D_lC!+}2?_^W}p9(v%= z`wuM~`iVo&9QwsWXC54XaPGm6JovK@{=Elt5B zO@rjFL#)xz$mP_Lwl<#pZ1{fGFQ;awumr+t#V4R>@FQ^`@{=o@1{jAEv4X}u4)%O)*WhBM+_{GLB{>=JEC%?$_b5M}3NkA+OEkvVak*0Ee?H}L13iQV(1x_shLHkQCCF#F)@6+BK!<&9Sx9^L+Vy!`TM{Ntk1I?J7%7+m>EfjbRs@MSCZS26c2Jmr z;azanxFN%76?a4X(oQ z)ipUZb7pS3I5{*mgzKhx4MaA8BW)dk6x4X64fdKcV*BOM?g%oxNjrFO-f?rKHivQ; zH%w!qfKhrd4b;e&S0NRZ`H3+bZv`+6@=iV0B%qC2{4~ z0gYijw^qh2y_C@ge}2$Oj*y3gPIFw&E;G(WFGLxnzxfhhg6>?xQlzVc|H;#M*F7?d`;5Uo7a~UL zmR{@jaM67&kt6@%4=4MXHSHJHaUIPR*U@b*(Z-6V-<&jRb#lhSs0#k{M=*CQ>f6;_^x(8YfW0>6F32r4!{^P@RCDp(%r-*)&FHTK?dpogb(0Rm?CeF<;2}%r- zENyybXy)AX+*EOBUaT0DlBI%G~x?C>y8A z{z<)}A(sG;A%)VJrz^{_M652xatGNA=O6{7#hw-b!hvCFa4=-SAQytvRLk^iD6J~Z zCzh6=tFrsEa}}%AjcSvu_4>7-;3l6UhJjo=4Uwb!CB)5$7v->axZ&ryZxxG>S{+na zFRca;*~rQQ<{cvsSz3QgA#xeW0mI;cNb_jx$>ZLo&WZPR9%$>8ua8Ke_SHOkYom(P zK1m&i!v_zBAi}W(V42^-)+0^;BSTwn--D7zO=JjTZ*gAi3I_96?bTbs~bk*3Xf6!9h{dJs>l z0;Q@T(66l-U1gx5Rf$Z))ft#uiuMb9p6@CjoQHUNN_H~Aj3upZK;E0&&zI&AvIz2t zl^&8er@(4LH(UI|7Q#D^%!yHus_pDyqFLf!g z&tbP0fkG9zUU{J;o-QxTa1d;9H5(YuXf&WCkCp6W$pNMNW57(-N1K?dG~V1guZJ(= z3K6+ZMDl7kC?g}@Kf;Skc<9neqW@50GL$a>IstGxJbA;o}_eb`bNfy{CXB1+F`lt))kUuLjC#D_;$ zq7zoHNhYPHZTRv=1mwnG#3+^5O4CzV#V%K|9UGy@5Po*g6;_laklm^W(`{EfLYN7L zhm_EmaLn)`(>uhvJ=%nggq@5zT;@FBtVeY8sMTv-otzBjxB}JnO*8An49=)J>7=R} z&NVSAH+tEFIe_?yjM;`${5%*JV+GvKSk3D-o|rR0Ob&Z9X*eTJKn%1gqz#r=YK>6} zkx-n9^7_lxCCxU>7+cLeQ9L^`H*8$r`jYi97AV$*nRSti8+Q)7?g4vk zT;nI6f6lZ#}X&kF@um0&e0)Qr)(^A|R@@)E?9N}`M> zQSLLV@7m8PoEb?NyOGz)7`Ct{FN0Lc79)GYJZn9fSimcVFeJf7&YnS7l923W_nhp7 zM0aBJP;@!Npzi~86g-`mceWclsf-4fR%PLf*y&PM?ZrXQV%`qdR_IibnnDw|{ET;D z+yK(msSA^+`|Pq^=t0_Xyd@o70QqiLQLr-@Zx@H9bv@|1!y1}3ZtRs1ic=it0`0Q+ z(iQ2l@y|S6lmU^jbhSlAxvW?mHYB1Uz#V}$h2v-+ zRjnGv3~h%Swk$oK7n31vyQ#{%Q9CU8mbbg}cxSgU-?@5a6;U-ouhM4O+1u3kD3CZn zLIm>!)lRbt>Gc4DYrqz6eQd(|V(0udUPwD9tHRDpYLwQNG{^$#=;EH1WjAeFtMQKC zMB72{M}`$K-~0Z@Qx>sgO7ZV7_51Ib@BQ~^nsLp-+3I-5&jjXthp=g|B7$VHtWhAz&P~X|BD!W33L?ez(i%COwwt}&=QeJq<=_N=8 zZ4*C95rAH8*$q+}Yt7?kLQOEKxSgq&vq%wqUkOb|c-;Te!FQLvA=MBs#Oh<_h#s zOJeJU8z7aMpP`~13?rn87;GR+Zt?Bs~XY%y7ZmJS6u&?hp~_#N7ZcI{dN3`tR0grT9bRN->Jglir3IzhAt z_XJ!nFD8_W%+cjXeTp-%Ti1k$n-zBdpa`<0q)3uWy9OJs!Z*P(VR2(xlH4oYKd*XA z467LUBy3Z;R1-`0h#!?Z^@N((Y4uRG&;}6>Xn4j$S2^*3uOzmMsc(diODZF1v}X`U zp@A+L^rO=z4Ha}SHz3500~~2qfS!=(V?|yYgJpzM0UFXXNlw*UZ<(61j=eQvIyskW zku&0l!!}}(WP>U-ZHyy{ut-?6a6Dc^1WKm$Bs>iLZ0f|JwA9yr+2?vX(V4rPJ);>x zNF*0!?zoeWQSO$qSrXhBUWR(s*rXz%8&Hw7B;7K|Hk#b~i5m=BR20Oj>Q_KPZ(x$^ z(5VGnU)!385u>Yvx&2(wVDkx+fXTTA83?alUB%Qb@Hm}12GR;6mPs~yVHG|m0l!#9 zN;AOigwnrb<=7hY6;h}~)ivVKVzg_P6p7!%Yzh-uf^<9aX_AiCRV|Op6tl(v?uuiB zlDcP_$+oFnx5~Q#z;L+gCUZju4oZa^yiK?`IdCwri?)ZF#u`B&UmX8B`r%u z6;Y5Sb{!dK-~#4JDeEcm>U6Nsmxe)%^qj|3*vZf_xu+Hi-RXyGneBC7l&{pCFTo4V z904+4LvMtG=Tqw&S8zj?Y=4IXGsz3+@GUtBvb41-Eif#wTNm?7buG;>{w6_U<~@br z+NynGJsRkw$-!-#jajSKJFoj=J!Siyw@cyAn)Fpq=lU+}mPV5e31n*g_sJMJ@mv&- zDUdQv#YWtyd*?UFjJuE@nSHL6?~E+O12^e!smE^vt_i{>Ng7x^)GOLER{fms3u zG1v_wdFPykpx53ax?YElMpGJHXBp!Va@wV?AQdrKP%>SsoZ6j+7znOlT(&a5Sd9>_ zF``BOfKfv-H7K+Nqzw7E^;$#F8S4nyhIG5Zn6r9uY{Tpdcyd-%mqCu;Aw97#l7A28 zI#`&Y3#-esb#TBm2lVr_Ij!I)KhdEI(RyNa3+6na&#oW zZ!zC@{6~A+{b~i{Ol(ZDV=FsVc;)6=D1S2fxaa)wd=KksVoM87R7l-{WkYwyz)4O8 z@OGKrLkDymphB^mCQOCi)R?v&fhb9`AN6FHj^RQoHidd)O{mW`pePGQR$)j3SR`W} z4AY~Jyl-@DOno_=YlL;QZ=Yiw_{>}WsJ-fv-*oT?*k{R9Kk(T#R<&4ZO+$%~bM|H2 z@R%IaIJ04E$qstR1f#m;oj_Z8V#7&5M58UEu0V_Lx|Ir{;c(!@-fIv>Xg} zsUoz~@&`7t5Kg$c6%Z@{M$I>PY`EA?QV0n9ZJ?CU_Tr_Hd`9Wf$TS$LwN4mCZ^PzN z3rk{xCOb@=Tnn0NsIZwjO63>;TohAf8a7>2zs!2WHiUJ@ho?gUGQn`zjTwSPQ+WuMpbGvXj6I|3Jk~AnM^TBT1br` zhIP1lTsb`WvLUyn5h1`dA^_PKdyKEgHmXm-20ele$OT-TtROsN25U#`U{gYKk}%Ss zw0N}fFcoJRsV5{`;W*w$wP%tcRX_dof`N%Akv-zP7XpvqCP@Lj=s}mJ1vcKJQZ`(( znHZd#77TPp*vvP)d8Uaj}lPH5QUe*oSvh#SE!y7x^;H| zl9OHJe8Cs=uz0ErzJz;)hZ_~V*rl#(;8*108N?_-vP(;|36>!pL9^-lVg(zoDJhLt zqdX!KS`0EsZh2D0&0R4X3rhGT1js2xpaZjSWj&1sGH4Z+A=#4|04={@K!AZJlF(u! zl`y&EBrrldLR_GlMnj=vicCVZNag6AN!{HyuNODFD27hw?c4{4n0+|KkVhP=v7zbd zxjB9fya1rxYHM1S3+TOxP5RC1QX^ytZ0hKnkdzr@bmeVGIF}U=)Xh^0hU3&jbVES0 zG^;>HYs14g8T{D9_o-Pu=(l3yLp~hKf&}@*kFthn$#B!z!piNYLktgC2hyIgjT@Yq zJ!~-tRz~+Vt*vphGppN0yEBl9JCei)q+h@%*3)K$h=i)N*iTS_Z6d8dxs;=+MOMM7 zSg5vIXTD(dA)NbziOYG@2FAqTUN z5B07{0Sr@{G$OvRd39SdIx<$2W;lUv9LN5{`5!+SR%*~kru8CqvmINO4!C-4t-`2~ zAcQ7I9i8_Xjb^QAi|OKES=$T;7;)`F%1O#?b?oabFRX0jaoorvUg&(?3B9QkR)xk- zG&zWmAE?0|#Z(`8?h(8=>`6VkoRzxCRZa$LgMp3nKuo`hFqc`=9li5ZhVYDeoZ6Ub zl~N|?h@|uK1Ulhy+rdG-a88{Oz1_u4LjHh%HY9(}cPB6n9BM}*~ZzW#qzO^6G!sGz*wCxmh;Ddv>(r~k#M!XSjNUVnBMVQ zfN^5l0G%073u`6MS&e+3b$TrEG^*fuq^$!zfG4$r;=nReXv}aaIM|Go!2Qry0iHrY zFz^(2fcJ|JKH01!VQI|k8gBs}{{fO?TU0oykoBXuNxM?La6GX52t+i}hl(Ir$q}>H zxNJ#LrPfs&g^AMWl}N^K z%(G{3a0gw1_&_Y%HG1~+M4&#n!Q23hxRAmR2R?UQfX2S2cMX{?KYpS6h@QFf>LHOkRd9=+Dhk-Ce8GX zf^w+Kt1Bj}UOo3SUxxF$AW!eZO1*NqjMLS1gjuZSapqRgMg42@xHr>?;Dn@af@2?l z4&HUIoQzec;$RGzXEDX2pV#AK(L9_vf`--?c zrAk5^e~pVl2F?OM#iA&%gV1<%4~v3bols0lHk)!H$*Xk+J6saC!Z|H4hQ*+XeF%B9 zz>8BkOu+?!MJn^8!GWU*lvJI#?b)}7rShdQ|LQRwAXU!1;yth?A5<|o&|Ba9)% zbn^fdX{jiOwqt{IQ|O&8tF<^R>t?@&LDr7xhKh?5x-x$Sh%p^wmayY+ArpMhc^?wA zq<|2RS02bVjz`p<5Q+-)E}4+ zJuLK|7qW(Ql4EU7&+f8hW=9s%xp9?oTE9q)+dgBE6_I%d#!zk zW#?2FE{l^r1nD*}c47=Fud>Du1VZA-sOn=Rl}sHJU+5W?t=0~wiX_tmtYi6;6i${) zwoASoRN*OVgbDHlYGLS%=SIKHktrdN z+#{t@$asC;KHzjYr^h7hjymtfOMtN&nMXD;tna@#mUZv>jc_b5zNV4GF1< z4pAz}YJB(2@}^l~5Zg&3@#(j3^#8!V+6Uw`jjJgf*%8%^=@N`>=tV0BZwzR}b4lO3 zX*({~;bz&hJcwx%Ys7ahTjCsH!rtxMJE=ASuTP0|!2)r<%xwxenoAPwt4YgaRdc5D z^Jaz;kZiz=>$^o9|Fq4N>^1~BZ?YMlPj=Iin+<`DOq=CKD%w)|gvDu!-ayf@pU{3HA%Bay+_)6Sp$iuV|Wz9lYqi#B2ku(vZ6QZAn zEgA*sjkuda_W-`{h-f3z^6=oBy&bgPb;X<3?&#;6hU$kbu$B+p>e^8YQ1NMro^dPU zR7;b*fQoLzW^A|iJp0jkPznyUlLNdtR}&+(cVP^^2S zhB$PZb#TTQ)!pWX>}*p?%PgI&!Tg>kWEu&V@2QDJ=cIH;NWUk+rjCRfIZ{wfA8Y_N zEnQ&3Glmvq$wz8clh9?6wo3snrjd-dUUW8BnmT>l98Nd;vB4n0(IMS6?qMyd{DrtV zW!-rIP)e&^A#w?bCOa=2G-|Wu)cHi#P+Xh%dTDyla2qIBS<~p&2rFWnD|2h5O$+rj zH+Obuyf{5MG+dmU>+YO&;rT@vaN{K&ZiG905mK@vV@m{C8+qAni+zYLkGKml)iGB* zdmc~_A9)J#pFQ%(%NgC-+RS~(8j6=PC(D)~cHRJ$I)UrxAV9td2k2ygtAbN$DzeVk zWn&J{Mr+jUmT+uHoC(FcvZ?BQ;do*^2wKi4VVRir+Nr=!C5kDt(w`9h_;E_3S13ZA zk5f{#hPOehs#mnt73Yb#p5=U^$ri2dsxogUf{f8N>v)(%H?nGV5~2oggX)we^tF#b z4c3tJuRpehEjm1y{P4bF7&FUrwarz8^Xfd<)xQ5=1#IrCJpl6{oD-&skIYR^j*ZUD zot>B~j!(i>^21^3NO5d*d~SGXa^~DrQG@&7N&uLQ)e?ZPJK7qT*pWn%v3X`^8J$Nt zo+MD~APfw+Vvunr%ZsOY1q0w>9PV>2=b511zpuTs+Z|8V5@-f&klmf_@89QZ0eWqW zklBU06~lNL6i{YIof19>*+}FLM@$v*Sttme%=-}?NK!(8C7X_x1KA`DAR6C%O%#*9 zZiyir|NE&S$-c7B0Z(O9i)igDSHS}!BRBv^A<;d=Sw@qsXJdwGeG_o1f*`5{fxHY@ zS%TkVDrXn=oVasowMy%xXHZCk%DO_d-Xm1(%EqGGCR1qOiMhG@#1? z(Fwdon0;Vf-3RM3DwSjM$RHE8dnJJ0lp3%S$W1)H_mw077NA0U^_l)t=!RK zkQn3+%!wP}WycDX3P%;Xx0))0rPHX!c~Aw>O%f#3&mtc5%9dSR zg!wU9uu`+Q+ffysg{^o%4PjH2_Mx+zjuyF@Et+d9H6B#BDX?UbOqiJ@`A}Q!3U>Q= zg^3a_K$s$K0k@IZ23Cmlpc|=iDv9%v#~R(AEKcN_m5sF;<)KTI-~=}qnEDe&yhwn# zL*Ui|xke8moEF0nPGRfBl5~?QTTDF2u;;#cl~+6Dy}5DJC4s4KT?hrjB`G_+P)S{y zCCh*^jV-l1fLGkS8ex@4=hEcW#p&h+b|NgPZ$pyg=u$6ky#P)Lh-RYJsT@w8$|h3~ zn}DOQh55U)cy&{K(n?TzCElx-<@4}3^Wkp$8I&+ z<>REewXFze1>fD--9Ecsr1RV`eCGxso4fYa_P6gKmJKP95G>5HaJPxea`(dGOStvf z10jvnBr#&QSZEMey1fB;sMijApg6m(SqEp=vBrq~%&zaNF@x?_HO-c6mu605P6XUL zyB8^I?o&+Ju(;%mO{^JHO{;U%ZIv^Pltw=)W*g>sRmM1|raz`*rSG^4hh=nA)@gU` zUvdHu$7i7IBuk=mXm=?3tG5(jc+w}W9N>NiY(`-3e06KFJXBq#^@0m2)}zZYzfeAN z=KQ$36)UdO%Q9B>Z@W5HRxYmr1~>sG4!u$96t2{ny1*jXW{~%T+*_X0^!?rO`cFuV z*_dI-n2@*vMY*;E2Vi({R;TlNll6&5HG&R5TdYx{XFgTd?Hm`Ar-vp-onLR~!YUWs z{3yUj^m18lWMhdMPl@3Ywg~HBWfi50M#JS5FDFb;LGLPKF=pUlvZwCMVKk0+C7P#D1c573P8~(MA3nCOeM!gf+xVW-dsXf_B)k3Gjmi<8&D_^ z5uv&311$2C`IvfhGE5xGyo6|r^f7r6>SDUi8a{LG?EB`XN1xz=s`tVE!vn5xk`fqk zBd|;GCQ!t&=BUr681h-%XO{!{lE9k#H3Ajso`!VM^xev-S`7V|-;BaRdjj;1ZRK$LozE;D1FvBn>F$$FM8E-Xm zfuMNkNY#vE8lFnLjhU*9seK1=^&2-;(9FN3@_bpjsII*KQzzg*MX^3Ss)(V?R?>3BClS>h8)!f zKNdJ=#-(uV)frsY+b{zq(5Y*s6uCyl7nK8P4wO7+j&>&VfL3CL261$bfxPkii-8pJQ;*L@;AswC4DYb9&hYcB zJ>w$6jmvUDpy&rWVa<+esogG zGK=t9M+5^)?eGERiKSfgWLj7gI0l=2PS}P8j^`b4)n>i2I?_aqG$qi$>44fbgyW;q zCMnpW@&uqpRAI#I<0CkKf}7idX})8Lw?bP%qG6*W9InU`J7p4OV~?>n^&T8tL|J}H zZ|P7dG_1=ewU@pZ<*bTcz5$I?ZntBf$ng*$BHNifDq?uD^NzUK`wuLYHL6KD-k}7Fc%5sDrXQbxspJ)cx2RZotbJq6Wv}i3rl01f)_ECmv=m}a|!IZ zwGI`-=FDl@gWnknr*<3Mp(`gRRH(MJcd9Bd z;%#}pq^CskWK>Mhf*@J#S2dq>l^b$wVDj1TrTUko%*m~Fgg~?5Dn(d*j69L9`QGA#K)6Rp!g+}lbL)`i>#RWh=pYNEI=EPQP+3Z#+Ih=$mJ438 z!idmUI8-U~%!8~N2uPLA?j95`t)PvmoULB8F1fTTIqL?bbf>8&P8OTq8<3vWHW!c) z8e*$U2}n{oCIO{l;c$?xIXSKfIUETv)W8UCPEZC9TA`%l=z#4K8JBFJTmhqjLsIz< z@dfb4S*&BH!^(jXXXQMGI?C#BLkMCJq?W$-xeYw`5XG zt!3V3D?|ecmM}>8Ce+1e3{YUKw=!gaC@`I3;Y6BZ73A=ET8X177e(WCE;(d8>o~Bki^Q-^MaeaV;DOA3S(8|fgzvM~B&qiz;#9KO zh%^?#Aog=qGBi&^G{H^5LMZb|D>P+j=XDkZ0UOK4Kt@}06R8R_($2gwFKczBAQ~3o zwAJ{uJw}AgJGynHGqavrj(b;Ar;wROYeN)aN=bQ`L-akEECcx`bAnS!gY=!`;?A0s z(Mua^RmL?cv=(jhG)YW#ij2;M&=5FFiV~&`iMwL6$$pbdilo&rBH|_+0Thx!)DoSA zG0#=C^=;o**sALcY~_|)4b-+EOSBNE#;p9(dm5p^8Np<6yd-zJJMOIEYMq4@XQB@K z2W*PHRn3iEQSD-^WJUXm>4DH0lFM!{-%T&%2;QAWXv&BOOd+HaR03UKco|B3VR#FU zDfKa6L69|L5pF8qt~5+GC|kE|h@^IiEP(`33`AX|cm%VAf*DIP6(;{qm8QgKPU`V@ zN^!LnjMF$>RP~HL`fI1U-bQNpn(rz!%j~Trm+wq@b+cTZjdr0mq0zx-S8SAK0r=?Pzw_?cMG-w=wu=IO zkA0^yO2JwE2uf)`>q>+zH1hbhh&|H|=8i|3gBmD^AM{@`J{v5nOO<6r=?c%VA#ef? z=btaFRv^U@^Hug|bz@(KXB(n~l`{07_#5gEAh0!D*h-wOU?U3QTwry1Ih9?m7b+ zbR9i0XP+JUGdzH{i4DQG7tnV-Lg_D#|+G3t(Dq{wcICv8D6B^adR|*ehYtH`hinO31ULCpqVafcN=NFzb%s5 z$z>_V)v)$bmwoyR6M{88n+d};R0DULf`gbb#MRrW+$AH;OA~K6NJtq8ln8;y+Nh%> zjX73zpiTwI=*j@=tD#LCC0h{T(Y4>)t8@)74z5nxCZvI#KM>WZLa8j7-B95WS3{Y- z1FhUUKU_r+*vf`1B)&5ob;-Gb-X$HH1E&|oeQ6%CvNqi9FWMAqn_I!Oby`IdLM@G= zy@f#OAD?jIrZ{8Bt@FzQobvPE%8qbN2DI)#z!b za>9H%)kd?#E(&Q!@1lTXv0W7LV`HZ>Hb3hULe4LNS6eKU7;Zb23I@_nSt-t;1nI|g znURt0M>PiHjZix%MZ+`*sY1aYJet-wQ>m|p$%jOz8Aq>wVMFSp~0CY0Ut9W1u0&%-W z4n*YA((v#Q^#doQ1X++7v$LFg!1PTImz5I2V`3(kT|Cj)7}E)p0pbvrYG&M$c*R_Y z>Q8d|%kKW2byHAH58*n%>0SVVg2B`ke8)NGXdI;bCjK(aYnv}YhIohgp@`GjQ4KPw zMXzMi^X4z@GS60q4QF@PvLwmSt_Ya_26uN62Vl*B&3qc*Mj4#$kfs?r&qI_>Fbl0M z(ml8cLMDu%sPP$40@8$VQad4)n%s15j-!T2*y|a(PkedfNa*AuJ~PVPyuQ?U97QoP z;09H#RuE&GilVD(znx{~kYYN}hVK9l>boH)Bgh>^vZ0e+%vE@x4j#!jq3VUC$)JfW z>mczzcr$8b2suf>oE>JVvi0uFd4qqB|J!smbwMQXMHV=iTm4ooOAmaU3_uzn{`bx>-Dafz=;h10RC z-ED0+{|%la5$9sdJXh!Bt=e>R^B69P5xjN5K%rHoataYzs!+aI%UcV?DU56bEULhP$9@G3} zad?a#m<;XAH5|U;i2VApjz?=gE zE+SjQ6&1ndA{aFGTNLOhkzOe=$?XPta)^UN*ct@CXA^CK$@55T9J|BbM8k!uP{TuX zU7dEkPKYDji4MFB;VMqHrtc08TD4Am24vOtKA4#7T#~iyvk4LpX4V z2xh#5gNpWQ@II1Oif$9iS#`VrX&-Bv{Ch4xG2QgUEQDxlAu#y zsID)-Ay$p8QAv?9NfNWaBY%jKrv64fPOrn@HKPak}44I&0)RqHf}>&>)C?8F+0^kx_b%M&Q< zQDfxR5y$ymeu?N)T--+1B@lfj5q#m~kXotMq&N-DF&mq!ptiD6tuM%3E!Lph);z1p zH?Bd=XwWUTGJ_j1q=NM`xXPH<&C41-i67(DI{&5;Ot2DUM< zJ0Q)~Do%pqe}E<*i61|AhnRp%(@z0;RFcF4;jL%OiyngTh;*ZD?Hk8*U^8W*yt2WN z%8@Cptt7=IN{}T(19;6ahO8sksoA5dA``a;6OKHg#|4 zD*AxS7fxTZGga7_s&Y!MWgXE2THC?~4)uO)HdU*oYmD55?{0eJ-cDG7>imHNy`d-G zGx9x{KI2kC-^QjuZ!C4_M06KwhLSi*JJ=lG=QJzos)%sU<{slS-jvJQ(lp?B zELW$?x?dEUK#eDpG%3|Af(pdE6E70ng;P&_Lqzt8bX^5f@O|9u-xYrh7qVw3rpCFG zEm18nP@|d}?l`%PCT<_iX|1x0Bp`yZ>X*bzxIB4Ca0T=y&8DrGyOP-R?XRgYYv*sySsGVAT~Jq1(Vo< z?h@B_c8|z*(+J%n94tD!z{RA7U|W?X+~De2c;`xRXu1W55c*WmCkOk57)fytn^)N{ z#8Y9k-bo6=Qw0GgY85jeLICFJmqP+mi|{1r0#ia=6VjA%OWfijU03Y2T(eWI?r(uU zg#y4kB;p<~5nC*5R8_Lc1g#oC!wE!9OW`h*n`n3E(J@zt zWZ1#2qtkPKGNWIs2U*MyL}zcet?Z2L`E);lsx}AvRdOIf)MG#Lj?1cXCzm^qzB=7y zImfYUcH?X(1EYzv9UWqJ1CN8vjUvLnogRFGYf`=dJLkctn(WO@*)x!H z#Hc&@eCWJ3#N~{9Z7qL%B=1y42YA{WwRt0~)U*V;(FZg<`q4=@XsQwi{Ov|TxMv=? zT!_pFo>klg3DL%ct1u}f!>B6(1~ESX(T{bB6WA{ygW_m~YPU2lSr@l8b-C#Tri-o* zSUO%Y??V^Yx}7s6RAw1OKz>ZOFh>K&5M`?B27p6=ELkiY#0!*y5BA&4`%$+J% zf3l#;T17*NYIuZw*roAQ7%FY>;K4P7^{C3RGY()~S3p^(ew{>e5#foe2rs@EM^P&> zOS0t%Fbqo(zbweG2T9rx-H`Y;)Uzk#@JtMxw*=8_RGh#n77;_+(MZds?Q=A_VcLY!x}#JFJ6Pa1g99eIF!YUB2;Sl`5lFEO(yR~v$9omEPQ z(@(~}B?3W2N}oZ(qA}9818hi*bd_gedoY7iDBqBo8fV0k-=CAvpOhP~>73-5<@@sy z#{?&B-+G-gy~I>Daq4=Lv+`f$YfwEvtVOVsfdqNiH@j5lF*cN2<0q zHWJ{C^@z=_+Dcbe?Lor?TF@AUuJ>um_XxaDH-X*e#%4=31XQEk5t2DQRI3bJe4KcX z2rEdiV6+3Ih)1@4na<{jkBNT+D@9?RDVKN~hUTi4xgCckh4z5vv<(m0CxaGS#s#d$ z$y#8y^5Qf(jI$AuP=14F0~Wm35K~6uA;hu zZ@TB4d<)5aF&1M&DYL(zSNjMusgVG4ThR~0owzRIoq)NcMD#&0QUgj8MaS~Vp$KvW z2oP?(VG(%kqnp_t@xsmtt!A&bcA^X9u^(L8DIuox@nJbShD9>ROfoO-E=%QIt|F*%X70X>+}Fyh zs~dVQEeX6oBm4a7Ryh;)Kt|>@#A05rmooDo%E-TPt(1-UgBh6-N2{KV%0ubg81M}{ z=@dF*x1BT)@1%idoiq^dB+c8flLq3Qq`4b+(m=eEG<%~?8i;q2W^U3+1MyDM{Ea$k zAl^xuxnU;_#5+lHH|r$b42TUNc*taNR-D>>eH=c#Bd}V7yv}5pI92)vSYn>x4YR<< zNz!*nN2knrS=r;w?0bmWd6c7ETFuISIL5kthmoCgmE&CmRdE6(V(5-}&%i-qYB3rK zy|f|}E}4TmOtZkO8CBuaL|XWJLA_*?MXy&UWJwz#9nRN?{O=osFsuGM+MA4Z9@QQP z5RF{KtMx?i0BjaCN`zKWzqB=`*oVw+0fNaz} zE8?d`nGjhRUQeh3;cqyH3=TG)L@vT!fx6YK+ls2^8R zGFo0V@2!ZJcHdi3t-~_q--g}_(0SE+D~W!pw*q9cdMjDpHGjw6QUULVqZ?5T2Zd%w z&|w|Ew=x(Mf^$>Yc?f9!U5x?5HXSSFBU*hR*(+ z?1*5#ich=20?eQ};0i}Mb8J_rIR&qG|EaAJXx zrlyjkc~Z!ttJY`+5TqP9wUi{YT$Gg(uBq*aYG{;Ga&*d-wqD`~^+vL+VZBk7o$3v9 zChCnX$E_!1(6ZrTJF%&-K`+G#qL~__d-#h z)8Bt_Uu_MS0NOX~{CO?l2$X;h50Ik)aFXw%?z$C+iPLdoCKZ4RH@n3FX{Uv{sS8Pd z2Ic^3D|H??3{<;FZO$ka&33yfH6i0K7;B1F628!@#k^>N=Bzo-0_6hUR_1<^@WWBe zK7Tb$Dov~@-e4LSQs4n>8~?$ICT`)QjPc7Nc{NRQVyd|+yrXM^;VM?zq-D^Amod7y z{@RfSUUv_dU;JD;u^&Em60NJFcXswD*<1?B7->Y<*lNnR1cF)S15=lsWj&JDfh-RT zxe(1h4NY{$Rqp=77A2q@@$z#UsbS>IrZun(TAJ*gq zd`^EZ#!aGj&i%VtMt7crH3`39#yK#49bh=><9^YN< z?>gEAF=(as=Rcf37(AZXfBapQ+Eu#uSpEFQqY(_=JULZ-WNza0>FMIk-0;xk%(5PyU1+`5vt@J$%A4P<1WYp?3ixKG7bKvyw3?a4S|Z^27keLQxgaE6ONRzXfa>v6xIiPEQUFN`m-Q6gov) zQ24}4#8q;daDvKalt>V!uy+s$#_2r?r|=~G(Ny*W1qZn*OSW1THJ@ZkEtex=&V(Eh zW$DMpH5QKP7iW z=y-7>E9SY{N@a<{lp+jegd&|w%Qj4y$~f}m8{sW+KMfZJQjlT*c=-|0Io}*WxIRb$ z;IyN0hN2psx*yBzf($jnS8 zrWCILUJ77BnQ4~Q2^)VJ)-@(gfTZrhp1FzjA+Txg)Eb@KxkEum{n5wytz`^vj5F8{ zG;t?SS1W4g_;*$2QCr@$R_JEjaJ3BlJTJ?)o!a8E-^3x2=xkAIl}J@8*LG3Bd93cH z$Q9ft=m+;s1$D(U8$YVuVj(TN+p6r8t`=^wrdXMlD;(aPXSvHx?zHbaq34Q>;iy%M zMQr%!$24QnHWv++|K7SA}L6Vyv|i#mg{|z}a7}F)*4* z+D`bz3i=zecVBd-TwSZI!>O}rQF%FnVYYL2i2RG(*sIi{S{0rK70wW-OFyfJeMRD>JBW#Tg>LHZ2>KnzY6)va~ zZ)Am^6|PusaHoTu!<3>FhDRsGqRI!kE32{YLD3w)u@&4Ja_he zXD1#zOM`$Kvb*4qa{!m=kmGS{IG>-YwrE z_uLBO;7i-(8}rFA44eDKBoG7&4dP`=p$Ixk#U>alY5lk0?g1H{u!9}oIW5f2vb9SY z!-uA#`;>HvY!U=9+iPoZ}CdMo=4#T9%y3JX>T$~>Gr^MRfNf|H*0vN&v%nO4q zUbSj)j)`P7MP?9X{xL5D0rsJsRj}E1PWRlO_!o2 z?dnyRC~a~NDAOz4E=y9bUQ=(B6RdBXz#|Z`b@}Ya^L>X7C1E2;_?x*vG3#n=uUlEV z)Yw2s4g%$g%wf=w{~hB~GHcLRVX4A#EO{nNRS18GSz9oh>uRB30*>~V!g=g-NQ;zd z3&&kVSR)3+%h<;H@_C&%^aQ1~N`se*?2H&2`ArU;<$);WaO>V(AxTjx7_JzGYV@PT z7JQwomwb??@nPBSn_j&3^cXgk0W<~-w+4p9gpqX>JtE;Q4s;jH3tE1S|(7|vC zX3JUCgf%d@OVVE)YneLe#RO!Gscntx?nTQJQ~TTopP27B95yB5@pN9!d2kdt@P z^a%0fCAY)DN$6oU%b=US&1z-mG_h`mV;gMOu@?i1K8jW$lForDxfF^y=txbK9#l8} zW<8GIy!vQ4slZ0#rcdXz@AciN43stiL}US2^+*FBYN%x2#tYpO#pr|VD&d$#_p%4I z^zC-5spZk>Ij$*T_%*zu%E8L*J}qt?kkoK|k{c3Q*$`S2W}Wn2fDx@RY{=y;-X)i|r`5D1ycL)m^#6)})eYY}SL z2!1ktGdf6WBxgJH&gg1at~)^{H(qy=4}|3${)ekQ-e-m+O0VE6c+bR7Z%~v;=9za( zQqjY2b;8=n$~-wgI2%u@TT%>RyC}uw+nyo@Hg-r$RMOv|fLh?dJ@Z;g z*M>GBnYDTh-^5lt?<*l2%gaO-VOc&_Lp?WRy_m_;i?*dgK(b~I*Zo7}X@nEs4!NG6 zj1aM8KVFZHlA_lBxS%>M8=eSSyP<~(J0UC7LV8D^RXOWu3*u%O{&dO{C^2+Ru1#Ph z>T>^QY{w#h{%HF3-boLitKhY?Qkz-H4&tE8(_yHL#Zsu| z5xHnnpi4J$*Fg{Pb(rJ2wv=(OHB$nF)dH-RE6`y z@O{eI?a7O?thrJjvC0^V?^xO+EHNqE47-RmRF>=zT7cD1o2dLtFT-n-Yk zLpC8l$t0^Q0F5AnxirBy6n8q76ErblXNKGP_|9$=Dsv_?$R`Czf9MKHDm%!?q6gwN&5StS;oF- z>d@TiTEMVU!bzReADgH_Z7Ug{&QIfsz-D96Plqz?441rFE+# z^C!kg!d5k6?*@b^ zax@lE247CYzb|$lewwRT*p4ege1elbTS6aDGyEow9DTv z(6Da?Q@LIsH2~sJoG>(>?#6-OLn?0_K&uH6P>d?I*aIzNfMjX)F^EdNl|;(7pqiI6 z)H-R_Mk6%S;g}PnT>L}UM<|0_!O`pCbl&$pp2mkr`t`cv5xinDWi|;!3(*wcjSkNc zHLVv60neo$`2Y~D6o9<2AOA@OdSB>_?`YUFjuvx6Xq+C=b3y{aNB&%f3<*2R6R1ho zh^0Bj?ep-$+}fL9@g&zc=pOA;JzW8(f+!D)bMm&}UZz;+vz2B4& zV1=^4li|smNZ3ezK`b9S`(JyzyMI3Z{_|s^CzpVwp0C{3uh5S~5Xj!>{RYC%UwYWv zmSu)hZkbGI3~)U7N$V?4Nl%I@bYm~8Yhr)|Txi7>nA(u$c6x$_IUG$46HDHcLuvQv zL)UMBhu$-d>=5T#aO03+KtZY6SOjbVSUI`b0Q+n+0uO^I1IIBi5zw_Bnzd0E!WJBH zVGMgX7sUUE?#p-~&b*1I3=t4yyL7&&(Nnc4iz!mRrk5N5Dn^MbYENB ze);0r%NP64*S{mnaJ{u%rty#W*yz=)o4tFbL}C+U!K+x4UmXquOh9X4pM}kH3CHJT zF_lx?^Mr(Mc&COw4##RhzZCNc4ypUkPmt0Y2MJ|2oVR3QNuXJO4A3L|Mi>!J_K1N8 z>ror9=WD(G$*ln^awr6h6(Hf;D%$g0ae(VSrJ~t@$l=32fw^GcjL;=Aq!?@XZbqAQ zgO<(+D_(ucA2)8O<;L66QP{n=q=lS3!mYk|gRG+xa^H9iovdfW-k*|`&FW`((X6dc zy|R-O0CZ5aWq-`$^-CmjYXd_4273CG4UpETPg=LumqBRM*QdFDlhczHf&lVA29BNe ze8X>zQpxkKva2UF#E`Jt_~RYpS9A-1*qjPvv!Sb3F}7(|@(2@o3ccFHv0G3EOBGU2 z8SNRJQ1Di%ADe@RlL?h;>4Ce2TK#4?dh-@hi65oe zSs4^VPb2=emNY8E6I;cFa&Udwr6bWSBPJ{PBpFjQw7z@1wXyx(j@wlG4_-cgvf&Oe zmKN(m4ifP;tL44J8`porKfOJE{YifBU6&iJVAdQjqXWZ}cgy|tt)0gYX`@{Sb4Yb; z76dd^sad3&y~m7o(}UOi(Ouh55;L$37r{Vp)Ji;P8|6`&@d@P-gP~??f$wDe<8)Q9{c;t#Az0Ra-Wt({$)GQQ@!clH^l(`l248A> ztHi{=8z!Fwg}gM@(blya|Aj!}W&YHw7la$Nh_Twppw3$nN0G)ZZpZLwqjjaA3RpKF z(xP~FD5vz@Lm) z=C&Z-aUGruqYwC4Mh;;=SQ3W*%87T!f-cb;39Drh+!&HtOC9oQb6@t`r^|hK*GE6? zkES?c_1;!|NzOx9o5XW2_frN4kwOjHgS_Gni$Y$DicndxqRed);ieTidyo{L{bxkQ z;x@HNXiWCvTf0b(zc5MvdOkuzSFE5`{_2$UNfo5bhVl#}`wuT4Z@x%O1KmUF;H@7{sZa4*j+#UNRj>BFzSC<}v}bzE&ID`(f8uoeV0(w@4zeuIr1phI12wGeC>lEn;vVnz!HgPVAa7k+DVZi_0r=b4rVl2Q46LbcWR6-aHo({h6-u#qj{q z3hTuIL7|A2G||VYiX7A}{UxW0aV}>lRD0#4AB5nxTfz?JwgJI(rxH(I!D4*K17J{Q z8n)Ls29`FXP)~GjtZ(*XZX3Q{JIaFKI)NqUS*B}i54WE_UEkV3ZD|mVtKN`bEB6i2 zowwujqr>MwR#afiVUBq{Li`%SY zPK*notuieIRWm7DbPCE^cV&etqFn0`8g1T$2#*l-(P%O~^OMB123&=;x3Zzf9i#z# zPbbqdY>ICET8-7V3l>d+U<61VM}*^rsr~sTWV8rdL`&cN^FX^ z4piU4HMjoc<>vm@_7<4GzX8>7gxk!iuzIY6up`MKgc}KNw!w|YiecLhcq|c>s@8B* z`ull+&C(E@-~IBA|9dwRb=;}|n{SF+6cE~_wMS>Tm;JT3G+o1f0bOZ&OIlBHx!Job z4{`ULS3}xj%`}4m=iV3c_Hc+(|6MddV?3!TsD3*W$AY{}n=yhaL{*O;?`lCzc>2_5 zk@(Sg0=Fj@;f8+~G+z_U0|;z+NO?h!qsB5|7P1@44}<9s!VIbMyJ64mc|qTtXCmV> zWzPg%158bzZ3zm|`zA-uF2g%PX=FTxRT8DVkc1PCoWzM|O$aT&2vUs^flmXgBYlgO zMTFuJbAR@%I79AF!y$2hv_Ven01O}p5ZAJ`GJ^!clr+`bdVCGWJ;1`VVQbpYyg**0 zp|O2to5CU`nKL?fit(q_wez;+N@nB5TW@b6F0PvNVXPWNStN!{)ef{12my^W^W zZ<>zJAymtbhA;YFkAcv%?VdzwPm}$;J~+ba2X%=;+avLFNw>VDb`}VPDe3i?M9tjU z9IwLl^^Z7S$2{dr&*1-`Mue4Gctem;06l^I~>ecN=U6D%IN;#Hv3*t)zmoJ?TCb)wB zD_B0KNA&t4h!ZF?UIT527S@ZWq+F0G4@i{qd5xyzgwZTIMZoBtcK^48MTNiy`57sPhT&$7XasrA5ocs&)m-~o3(KO|j?;O%F67C%YmVY8a48j7fRn(>4 z!X%cMDzHPzr);+(C;1CqHP+^fF8A(!9(cCLK;OZ1JgHBTWD7zY*CPS3 z1E`p6ib@5`_Cw4xll&Z%KGRyGDT4-MDfHC+bu1_F8)^|OoMXuJ2LXyWH%!dqSNkX; zQBu*!%)%qUv?qk111}!8A@0~a)Ga$eIm8a-!P&k)PnZ`Z{G2%Ubd!z9h$9szppWA){O*ENd6HBF$?_C`Pu8=X}>Vw zz!Az23*aVkVcfGQ=j1>tiHOLNVj!MJa4_5?X$LW^Jn-(;If3MMEtAjNf%t88+cgkN zBh^-y4p6|6z-bV0r;;5CT-#(KSr#f(KLdyuwc!_`O!iL)$S=W1fzFP!)z@pMFubDE zHR!{eQ9x!731li0lx+bl3KuQOKnB{r8%#!AiX%wcY3V%!QVKMSygnd|OQl}i6Q2{n z*+)++7mg@!E`}XPE8HIiRzNlxeYP$B%JnCBcGsUh-q~M&{(SvUc!uD^WG#uc7P4P) zp%8wWekq=4bTq7|jG*9IZznfWV1ZDw4oUIEzDlM41v#t8W7Z&kx|K<3$~Gba$oyfD zro*Gxh<~#VgW}O}*oRXCr{SauH`b)i{ocRJE}Q(Y6H4mNr56FD$6>P3p*#GNyE&gB z_g65qv8eLn5IkWdHRXJfw5fW@ysw-e(JQ03JroFd$iI+7+oZ7gbEQgJP%FW$Or9W^ zpkC$xZLM`A;8Eaw5IrUVD`EB4dZX#{A>50&bs$z%l4rhyv9w%0Lx8aMMd&cAf%OSe z;xwUWZq3lsvo7f1>dtvIk*VUW3h}U4Bx3{PPk2u(LMJrzN?@2O)jSy@WO4oA2d6tf^lm5fOij* zEVg4oO`9H%Wk;!)tHWC#fUft^qw6^m*=|!zqNWy1F$9KB#H|vYtdukQqMFmFI}F`7 ztsrOS4LXAaDrDu&IwfR!O! zj!79O#>fNbMs_b1Z6B4~Wi!t`+*o2R6aGAA+rUn?(AG^tU5P)GGiJ5WV;}hpF`ap$ z>u)jf#>x2n&D$j8(=61j95k8=b6bEB$?Q9NI@4F7Uq?Z^x<&a(1jz>+uU{1nt`#Y8h8+*?8`F z5uPp(ZOjH0M;C=NKR4|Zz5ngS_y_uJ&-f=uOWXL1=CnR< zu$z8=^%VTIX1Mm{B0kzpPE4O8|=k}9)oS{nI+&8)Rxm$ulL;ulXHY&a6@hA?i*eTC%> z@35T~buW~n1rzq*d;$+K`i<1IeyGTv!FJPnzOajId~0udZu$xw)nD}`FL|zDnbrP{>kBq#{ntbJf)uvbZKIUirXa!S^k9ku zZb*5=%cOX6^oXYbb$I(g3jONu^{?t5{dx5&gAw=!n<}VfIjwfT!0zWAIe01VJ#Fv{ z>^5;zQ#JzAD!1tV%+6k-t5vrO9JyWFz>(Jy369V$i=e1FV733jxGAS-%!9TJ`|%1Q zv(jRJ{(SNBM1qeH+9oR%#N;B%7M_B^q<3|7b(KeC@rMKGqvdR>%nf?nw!^SV2Cydu zB8E`}g+%42^#WD291!^^syM92b(%>^H%Hw;Fq7+4pJwM)cA)AT_cWpo+^DL3^-Xe5 zebxING?8nO+QEvQ=E>Q?Ij+!1CDi+ueqwgy8Y2`4eo{a#J~MSOeU4BX-lQpBsu6lF zFYbobY~~n0*#lMRh-}oo5$Py^Ixpz!yE?km%OQ8%!nR9){iLTBh~y4K+_E^=;B69U z(NkvNy|dCp-F4x#a*jyl&9R1{BXg3aH!^wnFZ3{lFZ=@5PfbWi(=Sd9qKa$_<>%$S zU#_ow%?w#b(2d8~#xh2Lz9R)OP56^Et?c`bWqK2fbz&kH2M3CK?aNTz>vm8cj+jJF z@tumpmku3cF`aC(tVKPDt^E!U{hfdNFc-aw`bTikr|!dd>EAI@y3n;QUch@#T3O}f z(Pe;vy8s3UbP#__XR*chFQBjckB=db(-8wjp{w5x5Wxvwtci^vS!pPs!4O?5k=z2> zI=t3m;k#@ZzA(RRNtj&eD%zrsYBhvK;EwTkix)OivdfW&`j^_VC zGZiaQ=xz6>dehZXb6MBITF`BA|1Xl2aq@DUt!P%BmQ7NyKH}!hk8iPbJfAY6;V}&% z9gG;g|37H+#zg-jTQ}zIj2endYO_|bsFv6dnPIzBf-8`)YB%XiHqQ)&u#xvgTXafc zBRP~NuVFuPa5U9p#X5pG=_T7N5h;Bl?i^J^F_T-?O<*vqEJd@%tBU6rSE?$BB2|s_ zyr_`pjId9c9#%zbRaaE0UbaQEC#+!|`~3P=2-nCgXHYd_R{Pac!xLlFst5==(3 ztkL65U9x034CZpJQyV@9MC8FUW17cKPGB5-zbEYWRN5(Tgb{#Piw0?Fe`oVKPMz-d z`GDD0$eFr<>bKfT9pGt_pdCRAf(;iEEk2Tfi%!BVyGz+$BK9oiIayhe%^OWQ^;B+J zfC)84>KIQs9V&CsP-Vb=vWS%EL|(Op!!@Tz*2eMzYRYoKv_Ma;HF^ZcM3$CKZ7I8XrAe)RU*QQq+iwTKyPPvvPHe6Me z&6vRSV&h7@EP{J16L!le8$?h(iklZt6E{}vpcJKxv}FFnuhmjqON>miN-@d63T{UF z@xc#GmYCm^*s;PNqWmdi?E@ZB7C91CO+=akMz@LxSdO%2Mr`Ga=$-k>oHHsyCAKcK z+E-7ioxOQR1Hv^bBu`>Hp|wKjuqu?U4%cdk%+0fE9dQomu|}G<@J+FedZ4}^Ost(u zmYY5RCA~K`dtkE*b%XUM>2~E&GPb}m<|fjik_|#?Wx+Dc7){+(;!5_@QxnaSVAz1D zl;l-9wlZ@=W06iu-32;ow|P_@nWGK*xEiU4yNKR*hKscEe61d*$se}RCV$piUh(5< ztqhg2n^>gOEUiPPQ*bdcC18Q6pk2hzqFS+2Qc97Pc`?<5z|7F=ZVFH;FG`yQRJxtN zT1=hW27eOaa85vpz-d#yft#s7gy`&Cwi)#`?19hHqN_2@UtrQ|?PBc$1F205Dw;Z2 z2``yL5?<|S(Qqp?S}<^V_+aS-8^h>zw<)Z%o(1Nxv>Qgr9!w7d6$P$OSj5=9HfcHB2Tk}(niNPk@#fR zDAlBQH4RZ?9ZO$^V-3BFg&#Lzu=riGB~I#dDpoe3xKt%CB(dldCg&JMWKQk5At3AzQ~O?y@>L!#7D>Ri0FmAY91~CjPm{ zjNj!?D5=(wYpOFE2do#3ip7aoj$XEg4pg@Fe8L=rwbVlB#-fWM8*3!G z)u>j{>0Lbny@X{gioJ+Gr~3I|`OtB4pSIrx-tE+e*#!}V5OJ#XPu;l|KX$ISs2kg~ zMXpE%nt!2r{Ah&gHQdmGV~rpfWxmmp+Y-YCr==x5fwC*qplC`yH8-f3FZeB{aEI|C zm32OG;^A+N-VCimhlBuG%y_B$pgr&jB}F^@VAeNDOplUU()muQch31m>gH^txF-K^ zw@|Wyp>xaZ{(5l758~ZeuzSf{pUeNyN{%JwLyKMpkBxN+ns!*(YriTqXLgkBu?NWw~}@vSmi+~fZb^VgBHmZ z^Ta4^=XRB=TwgRiwN;xbC@7&m+b1*MYc)SCa}l3=ayaQ==YAJXX5pZ?8<6JoM{!#v z0h{Z+YI?TI@h+Vyvq@FV>=d`)+gX%I(S4A@oXVYvOS-W*ABk%!yMU5P7~A&5Jm<${ zdNI!lqKwR`rNTnVDckw;JsmD63d6k_gqr45myp&W&(c+R&t?yJS*i9|E=VkHMGgF9 z@|+>pS^z<8mcsCjmsNKg1k8N0!d+MV&|5j3;|9 z;PA^ozr3<=Mcg5`c)e}O_PJMH<`!&TrBR6GhI`KTjX^+H(%iL?Bk3^?#02J04!?$& zYA$q6)*0jGdMX0=#<-qqr|!upJgK;;7a!!Q!gcb#~+P^-AXr>almS}u&__>e3@`5 zUemI(NednF5yH`*R2(9Z3ut3_ZGA{44vEx4p*DcI-(d_=bNOv*x8N+i$Kf8sD6kEl z8&lLh|?VTaoH*Odd$IJ9~ z+MmjecyGbu3A(*?__~uXtQ7{*xAWzB)TM3OqUmv~tQbxtDeO!c~`CjCy$;LPXky3t}YsEr@~)J%~u?TTLKJW ziq}z|^mi6u?FOCvC8i7is+nx(5=hmnSBmv7VwV`D#42%EofPu|N+>b8<_{ZK)R^E) zoq;<@^`WG#1uhUYqYy@$a$j1FO}%5~gbz~Z` zN3Cwe+=Q`9D)07+xAtPZ1rp@5vZfq_7?2jyuXZSWFBi7mV9L`y0tVs8ZvEQF;6FbUNZ#P zx*ivAz8ZxcXJg6j3QC`xyKrK^)>s@(wxPUHL1JGor`j2EnLZ9jjy z{^X{tN(m*m#Dv{UK=}$f%`ZO^mQQ!0Oa?#h>l^HP-B%ER;W{~8Q2Kg^3*5|T6@ zUOctEs&ULGE(>M-P_!Lbmbl| z|GAH2Z6`d=FY7MD0PZy7>zlpzWfw9bjXN{v!UFa1(~@iHLUOy`S(uxNED4*u#gf68z`Rb6qn{;trnCdU> z)jUo*edS!F%FFbv^wDn?Ly4u+S66VV@DR5RfUU0k_v#QgLwo#{V~gLTlefdk=xp=k z-DomCp^5u#x-&q?jWQ4h)8)_zAXAJQW%5#Z`CLQ=yC0a)Y zr6Ge-4g=3IS;8bPom3hKHdH)%T`LNuFe59dgf8?Iv7t1EX)#?*l2hUuM#69$n%jD6 z8DM9yPO`i2$#rn|8Rp{L3CTDfoj{TfRalYUMhf8+?BMKt+FQOhy?*bO)}tBCmV`61 zZvpac*|rlkgKEl4QqvGuz8fB)b;+p1Tsf*SezsvMXaX>@O1=K8=>;eaOu@b7dqf|6 zaKEeCw|Z^mGHZI->k!xVGs({bl#fr(U`JxidkGj|pXTC{Onyp4`TXV;ShK0*5kw@E zL~bCUiqkWE&RaPL?*^kIN%3ZMo}%p+yvP*Se6iEgkGlOoZ)BLNT4bDM@^2?HSRVb5 zIq*ulOQ+NyKn%VD1jl2fm#;&O%MYKc+R44z#|>zfD!;wqZPEVHFgW6Ta^gx(8C39Y zueqMBl$PoNpWOGB<$W<-qBA@^#U(Ij4@jb`S|q`GJ=RGJCGf%{+4y|7Pg`gI)%ok! zm~xS0kmq#u1+t0u=^j!OK%bqCF^}~11VK?O8}VtgOi$Bh{f;B$a&(w@B61J36{e=hf9V z!l`$-g9U8v;hlZ~FA&QsXhTahVP3_M|G@ERzn>$&9XS1w^n)%q>z@|i5X(h9{RtHOC1U+L}n7d@9BVg+E0 zR(bey{!KMXlN~vf(|y#?)>6;9-h1c=bZCmw3LN2%AV?&vK-H9-5HAxr=6BeF7V^=x z=EJw+(ZSH)VdBsX$NnI$LJy>9jLbU5`N|QFHQ^2n5MP+6TxMd@zzfmx;f2idPhm|D z-Y_vjU;J|E8lI6}-@}B(HHXAi=+a-$hf}U}%<;l&sMr-;!|9RafX!tJSq64^^Xx;0 z;58sKz92PdfZ>24Ps%@FRG`fBKx5>$)n||c^CIV0vRq14xJrb&;`(ejkuFblZDxwt z8g#|WF{=BIMjmP>TV%}YXI0e(0jNLCgNEe1`A3kf@Ra=zKQBdtLA(XWHO!@!{YX^@GCSDAG4|W`y-L9 zG5NG|9qp6Ay-L8u9R*&*Q{PwEh9S>o!b8Z34N#g0vBx8tV0h@u8fy~*8KL8607R<< zC+NNELuGHYiHRy@oQ5F-Yeu~5-UJYk$+iKCPd|%CKX3hccd+ue^_Bl~d*wg&kx?E= z)Nhtgu7AEH_X$@>5K($;hI)!8DEhfOl68k2vI=)gZ__UL&Dcw$MqwB@s7xub<^uIa zN+ONxqJWnzs2U!(+TU@bgd;;@TGD|79hqHy+1MMuFiErxcFpe@KA*lV6q2EhVW``d z9<~j?D~-Sv21Tm)>jcj`&$MnV@lj{i@yY8E7ett&d^&BNU#koO9h00-Q4kIFMa-Sl z+!#94XrVB-L04{Zd3FTnQp*e$-q~z4L-EAI)I8Q&)*4wyiL<7uHU=ltABVVxlAiON znbx=uv2m})V{UUs* zS|6K#oM)m5<`zpZrnun7Y!}V4x1+;D$uL%1WcuO}tjSk{gCC5OBCMu~65c{$)#eG$ zY_!9Zlf+n1(fX+;`uQC0W}8h;-fc3Ke@|0tV7P?Mj9@?~Yl{VyLC>ha;b}!MF0M~> z3Z2{fX!?zeOiR-`GQxXKwTATvskQn`TAap*XhChi@KvaRNdXA+Ru$^iU+*cPp7-2y zgi{o`I4MAS0I>~Nwf?>l+Ir#TrPs#h!9-IG zy$HC;Riu|)7YVNS1?rlHd`hn3 z^^!xx?1w1%o4voV7k}yLos{EO|Cj4Xo_Ce-67K7~8Y9a8FA0mkAj1Bz_m_b9Uv$%j zDJsGRcR?t0$Sd?esvNY8F!hvDvy-7($NgK^u*ul8y75>xvOR@@N90N z$*Bo?hS09Q!JtnEKdsxmgSpebHCfZ&kU3K^Ty}_bd4*o;W+yZ>IzB(fI{x?-Scfie zYc1`m4SH~Sj?PBNnU5}JTe{M({XBhbrQyXuk$Qtgoro>nGp2JC5t^!u^rll4$1nc0@6kjs zOAp4}O+G{+OgU5R19lOox0G-|;mRJ0jmboyN0_}MaOk$9z@sCnZZe=^L!s5L*JRhe zLQpq3;K%VD9yqfkxM9QlMibt;sm64>I3#{pu3AWg6i5)Hq#aw=S@jq}d~-uh;Z4B0 z>O*c@I|c?a{gOajoC>39hCKr}M)-w-Gf@53Iba!Sao-Ka^J!?NVFx!YV}l7P+@wes zG)@)?S`)bhPU_cGA5H&oK0;>YP_JglKfHXr`9fn7)Owu1@Az@$BUb(>Nr* z5yCc*ay9x8ta7K6HYy=`*Me#N85A=l zPeOO#G%{*Ppt1cRuqon#4&GYK1s@y?u&}A-0$kl5iMED|kJ8peQ^r-?QbrInru z`uX~IYYP>8_GJC>R)GS%6ri`(Xi3N#MaeB*UZ(bhZdc_QcOZkN}MW?X|kA@a(7yb zw@o>-sx;=2T)2f%EX09adAwymILp_ausyj*b)Kxd+4at{X*49M^xYJoMDPQR;()$fimvZU&0)N zVik~@WW{nvYe3b%b0ZOxbS+`6>mIIGF1qXy7Z#jbli_rHKEV~VhOtC9^%WPrR|Vsm zO6_y5N<|lTIlN#{Mx>jP@?4tH+$C@0qfJo^7?6iG==x+Jz&AV_Mh>Q zN2Mr%rJEnFhE)#ALsLzq0zxLeq9Ko9XXdBZPpwt#6cnh65JM>W69xuL2beGOAW zb2q!yO2$KT2xl0VY*rbWSI`RD zDm$iZDaO1<^()og7>j(ba`I>SO8BdAwQ_u!*UDe@zG#BhRj=H>Y|R!6FtnNQu@_iA zMNI6etd;QmuJcwqhkc+GQvk2IS70BVq_xkS^>~I=18TEzyGuh|WQ!Qm?VlE?*>RL- zg&8#p`+O$gygpDqOTUv*QqDbHIHE79s?Kl!ke1ZLXm%#8r?aNnS83;J+F_(Z0+VW- zo*g16DpR;QDHrxun%%+gpUlj%vn<*vG}OltnzdWEfa>`C3>sX_Fw=pU7kA`&GEGE5 zq99Tp))4e5??U+(C>b=F42#Md2i<~CyVlEThEx16?nnmUEJNEe1nGCHIF?AIve-0t7X$ifBOQ?H zDA?{~Xj5rryIF^sySlB-mO}0AVVvSpE%=^`jwC~&3cCWjvAR+*5Dy$Po&=9-;x&!+ zbFil7T6|nhi2*gtidpV&@BHTWZLVQ@5W4+y<_%fyPwjx_O?73L67^9eT><~hieg0}mY2)SUbLfwYSMqV{Vt&nyl>EyD9 zps|`ZkGCFeQ>XEe4K$HH+ z$NM;P9YxX@b-WLwp(RMJh(jiO`+FyE``bjp_&QmT^(+{TmWuI_4@G9CbY7!dlrZm$ zOt}Tw7=`OW5i3-Pp}|j+NE`g@uSzg)_;RyRK0#{mg3Xgn7-dPH6ly9Rjo+9fJNrIT zm!X+>f-dP5>8p9bFiH8+zJcwoPNH>Wc9&9LPMbb-cmbo{5w*G=!)ZyoEpPpBN{{&1 zv|4uAu@JY0vWzk?Lx9wvvH=TmW~Rt1h6x5GM>kg1lh36CH=mu$91-itU z#a~5uL~r*gvltZHYQ`CGhOsYd1<8cyN-LekXa`_2OB5ks;tv+)&HBBt=8{B#2F1w73E1?fB50SA+oDJ74-`?mb6kHxcyb zYtvszJT!e>Qof?5cioR6!<;!o0C(Pev7!xL;i#J(jv~MIFiB#{NYGpM z$bz0^Y`}>|Nsv(MIBWG=Mr0yH)JCyx4#J#HJm*&BHd7qLYB%RN2ehA0$ z(Uwu@3f&?`2$6GYk$Ft0{N0v!c0T*11M7pQ$q+C-$xy{S^#uOx}?t z0UQ}HaEv9dVj84nWLLZ{+5K9J>IGRJATR-Hm$(Epi&Td}rO9zY96Rvy3OG4}V_}C# zNR!l?Y(rj3@}LQAI#TJ&zvHbQv!yT$zwC~{=C;r`=mdiN+t{&seYrMWl}2_OTV4JixjEfiwjhfMs5|4uIGK`n6Q%$Ah0Vf3C1Mv{{BI3azty z>$CD?5{S!7-GU=oC|K*WG>KaaQhi8}tP?8QhQ@^qYOCj&qn|h`l|-Jg#6gA9Zb+!5 z-MU=Q6_a+OBh9_WVf)9!$s0_`I$YSWQkx-8sAA?PYRGb<3tw4=%pn%10V?oTK5eC> z5d$lnHqeR3TkGaguyP-73{t~&LfaPlYgs4rC!@W&!do`IEla6c+{^YCXQ|Z$pQCTA zl<1V4{1*<9^g`GuECI4wOKA|B^H3g~mkeLN@X$2a5O&mR#tGJLMs^{269zMzICTwR z){jOA6^0&#TYxEYu9TnJL%os z?W-So*S7ev7qD1poe zM0nTftID9+b}~e2EnC-aR_*QD*nOW;H}1O8H2uEWegi_5UY!D&Yn4P~7R6G4nMDu5 z0#=M%QPU%6p(>*r7dg&Mh!)DMQGle|QoAF(K$GV0Y6CmQVx7tlFj2-zh7*RUyeSxd zRcD4iGE4*MDQ~&bSvlAY?jB$*yUn^Z?m1IUC(-PwtOcUSa0OWl#H7= zir(A1dTqLQRqnSDr5RY23c)EBnk)#LeOL7uWFcs_9vUg-fwK!yODnrl$))+gS9fF_ zL7RjijXrC^nCiG)+pn$t{>k=(^(XsV>rXd#o~>hNR$Pn;>~4R=?38U&^nBX~W?2P@ z)=ax1K*w{pLoL(2QzXNrB=gOMut~Z;xblQ|qZ^L{O~`4y8`Fyt1Vx-#5~Ny!Qn`mH7d8tIRdRI7Gk$IHWgxf?<&ofw%lajV=CL$!h)FYih0X1QLE*+N z@U1RUY%-Lw6?b=AF`WJuX!OT8C9R^keJ&ft>_RbSJmc*BvY?9QZO%MY6fP zN9UFi#G(p61K-HRoK2o|6-V_v`cj0S4&`bPn)Q1d+fP%q{+-p^6pWWI9BOe|(DQA%JF)1580@!%a=YvfPItSs@8WlYNL>tAdzp#Tfuo z8G)Boe{M*)J9*LCF2zwbsGUh&PQI=wT8Bc{LQYzT*DUS_S~CKuUv*6FNCNJnla-j= zDK)%&3fC%OQmZ?ZTWxelA?3~(tU}#!JVn}7Sv7gige*a^-)Y_Rp$ukfXa?1+gt339IUU>i-r77xmgLOT|dK&_X>A9EYqX`B@;C8hAGk9hKxOS8$&G`2%Ys3a!sZ= zrJ-=RIP+yo3&shOmaht zSs>*_S!CE%@8re2CY3y1w1Ut!ic8wEsumhnS^ZNPmTGn*y-r%CVAK}pWb&WX>MzT& znCGEg(GWI8O&`2}F?b_#TufF-oPykl%eQ5q{JdD95!!cZ+S>k(rwxC` zaTWHx+SRydgx@u?qEQ-ByAoEC%Z|Ba5QhUNL@{B~)HSDP$|+ zi~By)uqHa^CnTmfBWkcYS*Q;-vWN66taF1Zm0^3Be4ULYK)bCIFhDy=1`SSPUB{FR z1H!7GpzKRxjDpsw%q(i>LQ3zf#_IlUxtzG|ld1;oFMOI_u;EHOrFZL-$>9AAMVAVy zvP(a`UM&S`7o=hVCv$@o{|#@HTb^k|0f?)zQbp_1D#@tbLC zFMwN~5me@mkVcT!Hi^3r?C+h@DqYzAMckoW?LpoSC24YrgtPKdZK%%Ry8sXlGX zGPA|!S8{E1Q;5sKZ6?ntsBzCQfi&$-R3Y$L&_yvt>RRYa*%-vECZC3HC>>ZM zu53V1f~O@n*P9|GE9z-f_6$AlEvX_;#p}t4I$O-77&g0whtgjQ{zfx(JxP)B*YnY2 zD63p=jR^#cD}wKUId5akWt8Fl6BJS7;sY>HOCMLb0qEu|KjUVtMu z1n|YTaE1AE+$DTKztHDPb3Z4cVNDsoPR%p5JJ=!jeO!&^SGpP0D*#I0$E=>xVD?>7Xs;V%#i~Bm^$0LDmpXG6Q;4n;ov0-+7`;EP{Url zp@iFB6e_r_0M&O>0k@Sb)NfmX1SzuJMxG}M)f<`ngXSt-=iAjiuB|29?th4OZ(FQh zE)9ZP1pnNfoc5j$CO;g)uFo{-+@k#N^9n3q>3{w?)N)}iskOV>U*jtTQ6Qw~%4+}f z9-l)~BU4;U@g8!P_wSvIPloq#Ej&Xnq|W0h4vVUqt*cgsasT~r+J|=NpNuO2q79n0 z*Xf3mBQG6Qozif8*0pQh*MYt1inZQf+QL|QE85~l;%fgd{T!Y#Z-}?WZF=!DW5s&S z1~;h2*+cu6_A6P5c^*+Wbd;n4w!hFJ`3q+IOPCvMi%ihur1gV?A+EHPsk>~un5JlG zbaIkZt{BpL&^GgTL-Ogq#3WAm9d#Q_>Fs|KmMnnVlEkOYi!mfb!FHZ5??)5k0%q=y z>$dcwEo~>Xc>C zZE{YSYor;WUoy-2Jl7EGgx!L2t>NOFXmZC;HHQ|IT6kS|xJCWUK0^b22%t$7{{>e+ zag7r3GhpD$TK!699$`}M=tEkIde3H`DCrU>g2DirsDwT38h*=m^*o6!7&Yju0`C^M zL}xAsuV=^fW!>S9Uyf^*rBw5P{enJj$bo{q_%>@36%0zLVj7#pL00@+kBG`wK~%7K za`(Lmt=3V8U{uj*>6uDNpBsCW)Kp}_K>dw;SmlzT)E&I3*6;}oUBN~7AJr08jxCg9 zQq9Fv7d0vr+yB}>9-Jam3T46QI5r~(ILmaovSBCaDc4b)2tjnO$U^nnUD{7iOF zVmTH_KSX7>pk#BXORoizOMVKu97~%`VAKt&50QxK6gLlsj#!>`cQDs=XW)<-z5@fN zcrbkyY~O2o>oSnlz<>&dfgM^fERd8*w7d4iA?*rT^~hdX!Wh5{5ZQ2z==_voh6E1Q z^;%MiaTHW~UF*z757}K>5yu+MUX=I>gVPnR%_FEl1jlEkyceh>`Im}c2pl$V=&dqq9j;SN18FgDdmB@!{&$6BfOExSM9T` za}#?N;~{_(f_m&Djm+Ugn-voVfSl)0Z@F_MG!t7ZHz7ip$z8WV0O^Qoft$E+Q@4UX zlT>OLF@q7N7<4Ra*@WUQ3x3~D^B>q{Z9y7KmC#t|PfNdXn(JSE^h6UIDDS#Z+I2$< zRvg@aI)hKG#1gtVHw{uY$`z(M-&s8YPWg1;ZnkyCu$82ZNX6C zDt=?}EtW}F7Q-$}^yN2=%mV1dG`FGHX3cRyj4z=cW)so?Dq07+@VFpOL5W2F=b{RQ z__^tnm%6aa>f{A!p`b|yEMCSky2=Uz2P-~JQlqpOiA%DuhEe>51!YNVRCPD8)0GP= z`##mBsLt)#EmMwzE>aJ{`ZQCUM7rWpNY!%G+rT%5m3v)5D>2nTDib+Kdo@4h zBBPTxHBVJ9!B=uj(9O99maST|(4*NFqE%?Mg}CuFpXuc`cVl&}kF&b&KIPiz*$# zu0SpYqzZP*4MMsy(&KW09vF4R&s^zi@P@^877Z0)9Vpq1+boJV;y1L42WseGcqe9# zm=~HiUPZYJjaD^h&9HuDl`>+kE{`}UJfYcjm8U%!qEy-vI8X=*CKFF!2{^c#lI|4L z9GGfQ7Y|*{)QQAY>hP`;wQY}rD7|b-&5V{6>qJW5D@s;Zbb2BEeMeTct0L>&K?2sk z){Jkh-LO_`Q%E)oN%QtSttVv6Y@Segxpde<(V3{qB6!XUqD?fVfedqepJNCh5)J(n zOV;X14)izRRong)V)YNJj75O!`oeXc1?6bDlE*5M@VVSnbt9*y+!=IPPvkcUK#<$H zY;BzHiqJQe1C6EXZ8&V{XxSZH3zNQSO3UE{4`Ef4<;*geO`V(`t?!Z1-{}bFO`x~2&)?Yrs z9bEYqQhW1Y`}xM^^Cz1-J9wF{MYWd?x1S<~8mln@J3cP3OJ{5v&uWs!O;nLqZ@FtQxi~i+m11uIaK_vu}s;vmS0C@HhHy8Hql%(1J}oAOD!( zPw>4JxD-NC1-xDa?BMWlK3FewQLs)7VAI4^fi4r~LYRWaz?4BD%p;rpTCK3_vYm~X zY_*K%GvJ5S#KX4(+&Ofbe>6J+jj1Ao%%y0!vtrwDbhrP_cryAM{KaIzJQSo#k#DGRoNl8^dZPhj1VyMFB zxapjzzvkjJqw2-z1da0I{V5LPLk;oE+?E>^X0+GQ^$Ak(3@2Utvw{HwbmjE?^Wp0w zgjM0-3v6|mx@Yg*11)nb*FAC{BrSlYQ$5O#;}sB38a=W_n_hgY*GL5miS8w-&XF?@ zlo>0ABwm<8_PcL)S%k2*9-Ui!V)D`r$>a69h;yyiWPor3vO8$CtnsTF)0K z032Ix?MbX*I)N~o3^+vgoxvGynFn7O7ZC~FNy4{8Hfctr5dLVL4g||Z<*&cqBLc_g z2t0o^>G*V6DzSDk2I8Ov1oZ&I?iE{rJykVyHo@^IHR|Mz-nG~aOI?0bNuu=iAd;5Dt(VajF;9em_JScJ2cE~vVCY{8sx%@8UdV(0u z=iYfI1MZ;q!Z+wzlD-u|(TY>9tk*mj2#1#?(ipcYmbL-S2SNrxNG%9+#QEQRCI>;# zD~!Xeb+|UGMTDeykeFHnT7}2du+e{Oz2MdzB*}X(Mk!iPOe;t8Y%KkyGoa}p*pETY zi--4Ny{O{cBTQy_6tsdXu_&e9NP)qxfsr#~2|uIX&cS4XBxDFg)49mSZ+;{7$T}*b zp*ngATG`q~r`KOwx(T$9*d=Hp2VC{hN8#XTI5;`SolbcK-5yNSv5p;D4=_w4-q!eV zIYtO(w85d ziDQ%vKxIdTdR9hFYzsa-I>{NP>pmB&SH_WO7qU;fW6Tx9a@gD2zCg=0YAyaEKcMFN zqysrHWbjF%Q}oBEfViz}8URAkU=R~+5syYUn_NNgj@K@;lA$X`Zg{nYB zAzXG!4!Mrob`xwZ4YE5-C7WNb@l{WEo7UFSVQzy^KL2iX_7+31p@G6ouw0D`das;$ z20si1P%uH~K}HEPMqg5X_*z6bOknoXA65WqVS+4@Y)TuKGwJ(qJW=0ybh8i%7}c%9 z@05JzY^>$IIIiWs@)+9@7 zIVBD*mBHP?nK(fh!4(49Sv6Z&3Xh|TxzVn*YNr_mcfKV=UQ6f9mJFpj&@Q6`qEkRb z6SYylwYxqB2AvleyT~f)vNTQxh=>il4w%3(#p#HGXVoU7)-zsS9;Dm zORokK5gZK7-QRtgED}EFZfJNSMjPt$F-jx%V|a<6c7g9N@5h%=SGc2$gD;$$+D2ks zTzK{f*~IXU>vVk5OEsNB6VtOH7Y>lER0irj{DK%v&R&e@UQ8ueN%|L_VfW+!_h%B; zYJ_$)n4Ucajd01#^od{Y9t&tcp1}9;P}U#085|ImYN3_!yWvEFYtfD-UQWf`qp$E_ zdcdpi7? zX%mYLNjsh&1HEp7JFX3C`-@2G+EYmVpjr+Rs$W1=?&g40eS3mQHE9~xiGgeFks2?} zedMPOzYS_>>Q}%s&1ELIm1oN76?f(vU?RGoPxY+V$7sXr1>HIc#Vn_ zOPe&KVrpqU7i$3F^tM3rY8p3j2(zPiVMhDUblz;~i_NGRlNt(`2bP1Pu{0h1ErwSF z3uGB#yVtSdivr!SK)3{}*(Hb8U0-pbp#lR9%YIzHFqjaK%~OD2R*byq2Be5&K!m}S zm#m*dnj8bzTp)6yLoT$y_k4BcXTymR%>c$D3+dMu!d;dT?(cZ(@2!wZjH=7`v zgpWXH;^*v~30IFmWlYY;uL-h=Uj#Z6Kh@03VZu;Pn7g_;YH)nXDD#SEohHBxO_i<_ z!fJp2WQX1~r~VWq!c zxP7#g?J3S2goaW08mojLq{Y&~)CP;p0LocFjZ0mK1ZZuRqIHZa61~APz#deqhb-}O z-8Y6g3^M1;%BIft?BQs7ipc1w{G0Q~;PBnxmO9Kkn#9#5iR&;tA#+_xLSBa5yaOre1e23|CG(N<0OmgoADW#R5eaqow zzQ*t^9bkYO)n--5eb4PT_%@@A*=PCn(Rjc~H&jj7upi>hlKzKI2(Jh1e)+`#NY|ki zm8Y`4E4W>ajoL_HdWh*;F)!F&(6>#}W^9GPVSI!x^0>o%&^yf3+50Tf@!k54Lw6zxdPsA6`D*#E}*fN8##PT%4b9Y`q#!M~LdI zcf_z%<_yE}WG!$-UcyH(c;QB|mtDE*px_~ZYG~aNOlxy96E+=0N4t`j^`t!Br z-NDM=_Ez@4zj1x}>$SbL<=sDD!}sf7U;A~0?3YP_P?w$^yd7fkLJ!>ZPLYz%`D@`R=#g?eG-dhPTID2ZZSQv=`_Pf9Nc%6SOYTjw3zqu z+#>ox_GNJ0jVW_30}`)^(dJBk-BsMthM)uBcg*Jheg0MKr4 zFzp!Z*r8tCfk#wp&|v`MSDy`-?AjuN|(VPgbx7A-!t_QfBwc}J4#cB!iXHhlY(ku z%{+DGFSjCKDAOBn1y(KhV35k-^ZXLP%u_{&hy(K~D0?kG&1E6POJ;=ulQ4ZH2q>GK z4HBRcut#-KGDVNDjPT||LzH26bFkMfWw2X~E%HE{mHF}>1n7}$aL_A7G#v$}Kjc6^&WlQ@Iw84jN3I6UFE}BQp2)o#2_d> zg=~(F&yV5u;ennWLQ83=Og+CLES|Vl%*goIsa?O6fy;D}tjXfV1iOoe%X6rNEwa?( z+z7;}RSW~Eb78aLy2mMFWrKo^wh>I$g@*s54oYhHQw&N5UJXio@nM6KhAJ>8XWkh? zvXojk;vWx>$CLL9h(qguK9$DHrx)&f`b(8`N9k*rIXCgdFgws^ZOYBzby5d#Oe+z6({ zWVwI#(-~BygrODWfGJUw`|0?|$`!q@i!n!^l`99eE_lrA&e?2p2w7C7E%qpV>aHEy zwQ5}_+c7nGnr|Tyerf_S*wjWdp-A;~Uv33k_9YBL$M)$TQ(Zqenhv2a)yPyWB=oyN zL)rjA?8MeDZ|6{KPjONZVGvew*8!PVFc^{Zuj_buGCe=#CF8@xp5l{J-!$Nx4Hh_u z3kzLY&%uoA9!owr#=0v}J$qoC%HA!}JDtOpIM4R?Znh<$_r#i{S7KXl+=!^1mXMf? zAZTxPiS*97sOB9QCR>vHEYF}R!P$87>2nI`3=a7-wUB<7Y9T$Ip%s+SbqAF=JDSUZ zPIF1>046oZBfj}r>Hg^CHEvGLlyKKp|K7Ff{oQNR@9*8h7u*X2fz?|4n;;6D47nWr zhC))r9vqFa4dBQipI(A{gv5J{^^wp%8G84kupGD~;#lX(R> z$!9;r#bDo2OBHk?`Pv$|e!yHEUff%d;B_Yw(o7Ly_>p?NIR}5>M&dUTE7laR9Lz9} zxQ9^-zgUKjm~|%qQeeLUl)Ka^D53;)SmF`zVydKqGeXQ>sYG|RX}L%TC6OO=jTEpW z%PbJr@(Ci>(W)>UbMZI|cH-I)q?!<0u@kujE0{Ce=p-jH{?&ULL1B2D;KG&Hroxkv zAq|GJl2XldLFH%l<`S#c($l6MlyM=lA45BscJ#>~{=39?U80_5e?;=fiNF5}duu;{ z67XekO6_BhdB`ak_sAX{jeq2~S4ZbV{yoN040)*d_2B(L3jO$YbT;I9u>@bj6fmiz zSu(tnI19X4u{i2>=8fv-p0vF<;AxfMhBtU+ug98#Mr*IE?3%&|9a z80Ts8*Zk^NWk;olxXo?2omG&d;@+z_U$OUJzJBwSbd`FnckkBy-aS0woBQOY`*P); zwSv)qAc?xz1qz{Jo;#EH#wWR&e@;E*PHFJ!{PkdJf3Acwj%7)(pSlvIEQN&9R~#LR1l?uE9$x!Lx1xiAFOR!!uz2-QyvsFWSB8f& z4qlCdDlV284FHjr2C6{-b2i5y@0m1c9w-5FC(RQvly*T9jeFD7fsKYyrR-j({ssX_4@p%kj>|tJEpECgApdZH=El}(BT;pp##xF zyvmG1Iti%OS3jlBlq%0f#%bq$$V}n0UD{hHsnKQ(V)jLCwUI?g@2t?EgSZS}FX^JeR5 z0&TXeLSPK+e^g`RatFKGYr%8LbZ>hpz-`Z-Jc4Kp57Xl=XNuRizY7+7a6aNOnR0Pt zAiC_OEc;FApPZk}@ERN(({KR~$z09A4E*%iB?!JfQ9mYvsqkof=H_$SB9`?`8e7!M zqNv^2L5dpW9tC48V?A1O0@%o=dQTq&M0H+2)lmUJBZ?7hZS4Ri_8HbNEGlrVfW(8Q zFkilo`An>k*bEsqOM#Vrwu4zDyg-V;jpKl&DdBio6=W*iLwBJVk&(VF7A?Kfzz%Z` zz}#kDE5_6!jCEf<4f}5g2;lSPX`rbv>UwSGY$AyO3_EG-q28hL1Zx}kmdqI<=s7|> zZw7MXE$yT**arK@$>8*%hp%PVhcy!TLxtUugQE?smf-miE-g$Iw`f4S)S=OICrwn? zuEx^S`q!HvD^#95jj@^5{rv228m5(+GJ=4oNiFU{0&H z5yEUbYk;g95q#N;Feaa66v{G1JiN-Mj8=hHNQBbACo(J(k$%gHyW|yl>wMw z@2F4kz1HQ-%k}(&)ru$xYdEV1;UVoMIW4QFlJC?|@1h<_l^u-FRCX(^orOwzJ(ChO z0SXD(F7=@c{!P~siOoU}s7Ih{KUhaXV&xdHNG^1y^&-vmaKIq*DjGHe-r`CVeU1D9 zGki@-8{Y}P$#@|)bmcx^zy_O6X9@-3tlTd-(QrzHT3f>!(4u*nFV;0k4i|J?MU418 zMyvWeB3<;E!;5t2STo6|9?KFZETuRoZii~*rYx-b_vlL4+v6X2@FuGKTBM`R(lI)J z40lSqt%8&()A7-8&$OQZEv<+&@5U=p_a0;7VOGEOHyFk@m_gBhHyM%Zowq>H5tkfn z>D__OG~Px{*ti`dmHpy}0FAT;yP0du8>7okZp+|CprIg4Xlr-ow$rjVvFO-G^gl0{ z9t{vT{k5JVLa>uQkioZ+Z|E_EnAo)xX&=v)5B7;;60(8gu|A02gSpa`RMneRR?I0% zZCGo(F{&m7%WeZOfb4j1LO)+pyE+j0g_r5p6d;HL4m!fHGeAJ|W|Vnpknk6G&{*rjhp}?uS^dB4H^6REA+6UAg9zN6&Mbn_F zpVV2t+Cwj{vM1I6kd*aO7%2rLN)Vo-Hy9e6(^>A{`ZG`Vtgrl^+bjREzw-SJobI_< zKDqw+(k(FO}s&l zz_e{6?rVZ(U7>})R{G!(Ai8G2SJN7#ikDQ@m&&G~XVd2f6G?NG_1}7+lUf3)l)X;-t+sWljpGM` zyq7i6a(T z8m+9L_rAh*_S0iYcl2zO>28b&PK8Qlq@|BADtXugb{g8u(J)5Q1Ny=$H+wjYw=_x| zqn*a_sn}^$Jm_J6vW-}GGqKEsKj5)P%ItD~9b3gb^vXxvdFek04`dM7URewkSMF#v z5JbqSgh4b3)*P(^z*1#SLsmhW(GoV7U4XsDjAKS^tQ<0%kW94+l4`d>V~sJ2xG&@ph05fUl?cY#nt@85fSbicpqW0{_V3+d5jI~} z7P!BYbCrsEP_1qTtMc`rFjddy#RbuD+?@ucL^ufz$%;6kMb?8OB2JuP)^C~g;lz18 zVq!lgQ&5E*923eQ=#S5~_?is>xsQnJh{4J9M>!AP{~O#*rmFoZM)$MPiS4NX=QG6D zpfubkQj2#5*h*u${~mU0{{$&kL{}uR*=k2}3UPe~lt5t9C1Kt*Bnif-70^L5P)ej< z3oZi9>U`#vsPE=hnoa0$Mu&&PljpJ^b{%(h-BzGQfZ|y&L`S{6(C8@zIj;j0n8;_sw@2~c6t*+hz0^@U>+MC{bH9EQV zR*;eza}|ZTL$1==KYcrxtf_`K9^c=8^!Ul<{=Q5z|E42!c6_=iZA{-!N&+5=T!m1c7GV`&k4bZa6uQji?N5hYqw_G8GR1Kcwu zXiFE)PY`i{P|1W1c*!{?DHzos=0xlUP#L>a9$|J4k^$ z=1|Njc=gu#bRt4CJbA|;x0M3`6$6<=^(7vC36%naS%321-riDfvM-Bab_L9DxX$Kh z^Y6{z>2_i+x!#ECPx*$+ye<_wbI9{4OGq_NTgnkj)n&SH3EI!UwoEtC>$2UoiIt=W zgaS9wM>A$Z5MStGRD@sfC{IRQ(xt0T3u7d&M!{0W))m$Y*ob&H8tUwox3Jvdquhpe zTmj`KiBDMb;-~Lh`Jm|jQ#-{w;eaEsag-c+Gu-utIj;Xo1lTof4nA>?bN8xj#I~P1e=6eItGrG3+Hzkm}{2 zmEf>L`XGHQsKf^@<`4&3J+I*aNcUGnWvs>yjO;V`(NU>YQ;Ry@{;z)T?)~1a!{NJI zMD1#DRjWU-{|d1$G(!KTe}2$EoJ6jR6MOoW=o6nlp>b{4FhqRH5QM;2sG}Bb)jPZh zt2RjsVY(w06uLA>-Skg&ksMP}3&rtN0K;Z-N6+2+|9Xdhz)x>6&sfx;)n+-9L}`#kl8`~4r$JS37;mAl@%Yv#Go_c zU9utaP1+dsATs!#v37zk?&FF6u(LOUnC#S=-&~GO%Tq9{(Ee=lKCe&e*n-&OpzS48 z=vSm}|l=n}~m~ zowhyyG7m{Fx2O9K{uA;bAKh#8r^+2^w^4tBM_me{XR>88k(Oc0V-eIssH&99G%!li z!<)jP=*<0cv*##h!-lg2wc2M|ccxqZuSQ1U?hVa?V+k-7L{Z>dx8O?OzD{k2I)9ug*MxZ1{D_4QQ!mCbi`Ws-WwQVPO?a+c9?(f zoq3B~ZBQ8jl!$gPtzrV^n=eiQp+;PUHK44A71{)f2yEfQCNsad_6rCw6BgS7nNr!XuBS7B`oh18NF1 z{iU!wg-P)jMEq~w-)!t~sv}8h6-TFi*;Z2wBBI@Z9_w=C-d!7X6?b+=g3Ds#Lnohs%J?Th`=Gn{EX8AT=|RN-sV$0W7*%{PKE#NH}c|6?=3bby{X^*R-e9|ur%wYS9k9Ihl0A(I~=^v zRepQ>H@_1|c*;rw0<}P%5dItc%;;aG4~Ic~6=ITgkN+;?GVOeV zK?o!1mG9^!JvN93!x66Gk_M1W-QXi^eHE$oR{ghDnKztIHM=(a%goX3>}x-X{+-)* ze}m-g;ZH!%b$YdlU-;W-ESYDSmA){*XNBK+0qYYLqbb@}`4Z0I%E3m`ff3<*8 z7%n}SaZb)&FZZt<_CklWjA@c~E%4pw>@EBNcF%MUFMi}(=1DX9s9_r&6wA6}Dcn*` zvrWeqrRe1j_g79`Cgmf2!arU9Fu2EAF?Zj4#5c5hQJ z!&pm6(Hq#vrEmLN+fUd3SORTFyRBr(^Imn-aGh199YOH4TZ2rb@3(E;{ap?s;B#I# zLY%(>s;RtR5#ldb;!9X5GM4`Getf9{1AuC@B#6jJhE&dvaCs-*F?(ft)4a1NAYuq^ zPeyM>Cj-Pk@RO>J#f|99mL6N${l;?~V{SZyZkn8Nnr^(Y(9uVtj=t3!aBQyb`xOdy zqXGT^QD*Wte&tucLPcl75^<#xfi{{IqbJw}sVyd+_>DE_-@Q5h{vx!=-@k2ZI8MVY zrpMP`f1M}x|G8#|61!Dsm% z!AgebW2s``Np`|&A_=_Bv3V6xuOooi^P~mNVMXJp2e!^GcHwU$!H5X(jN>v8decS$ z=_K`dMUmj9zb$7>wDAJ*iuO!lqO!I*22!-zwXKhpw#1n&fHAQ)_6nsRN7l zjh$Qz;$2EsNj0mHjJh4J!$E5(FXi`!&cTXQO;k=7v3I9coLWZ@2q z2x*2xXT-#)IHNw9#*Qb>!ztbNwm`v@_-}3QO>%a@+e}o8srXWzH3*@*Hp|Q*vRXSI zKxG9G+La(s>n-n;L+mz!7A&4d^e6tQCAe`8!cT6 z0VOOW6@9tJ8Gaq0WQxL&g|d(}ocBImUTqH+KyA+b)rJ9EvGeK$y+s7mFy(B`SiW>! zSM9i_JEF7s#wCi4u$SU2rz6dG{Q9i@7HqH34pyjSc+!_1@RNgI0We=@H6u}4%`WQ` zyYx*tJF{8M+Foo)@2CDdF_vSIxhllJX@69UhJy)42xOLL&NSp2)gI_^1SZv@G5G(n z_w|2m9mn3k`>&7*sYHxylZ1gdMOGwNsxGL@nzurZrB=$pdAdCAOA*^-dptvALNZNrw&dgZ&<)%1)&Xv z_*yJ653?7p;Dh1e{2<4nC?$<*p&jrkyB{jJu9q+ZKU3+Xmeo?IAsT?xErZQcbr8k5 z@?EwL0$Wfl_Ic94+Nds?^r-)Yy(dA`Q!7V)?5Kar)<}8;K77-kfDP>gadIOz8)r_Q z36J-?9K)0r!J%NPR)?;q_T}a|NeiF_-LVp?p)=M8uVK=voz(JAXr@gkW5|@CV5)YS zfwT{yi3$Ux3vP~cBB;vYDJOa=sz{u;c4U`qg@{5hXB!9=%XDy29+PVt+7)??ev7Uq zAU`Wz4v;K`?ZN}k`17rz#f%UQI20xA!am3BGsg&o`x`TUQ6f3<3Grr-dOyqI+?s1^ zb%?x6$omn-tO7B=+!g9AFKPo6FH!|{iy}2Q#9E1*@zQk|hYS4!FcZv39qseV7zR={ zB@}81In#GYS5n|2f`@<^U8Oxqo3&Q)vD$3PmT21_rzAgAJ-KaP$D1TT8<%s3yG4vc z>=D&<9hP2m6Ff84P^fAok{i#pL$5B7OL0Iy4$=pxyDlcC_E{V1!#7)ZKczBfBVPx3 zppr>DA6`~*vQMC!;^=6ED%V3pWKW8MydeFxnYreuO)S4RMEeq6CVi<)MBbBG=~AfK z*d_C7%SZ~7n1xW$KIuqu(?(bAxB(7Gan)ODoYbS$w6TOKq3X-_l{jhgT_o-+Ns=F& z$&{wN0yl;{agGZdFEjVfk^@k|?xbK#2`MU+h?dq?<4Jfo(5R;o%l`8GRb&L0G+qY6 zSCe;$!IW4nHQooN+);L_`3Q4T+p4iAWlma)flaC~py&_Y-n$E1b9Zm2x4rhTx3l@( z_i{@tu?)Tx4~KkvS5j#e?-Tpfm3OtNSp-ovTdoD*D5)H7c8LiN{1-edxykcon%?0!Ke%q@J)JQ@Da7&mpD=tWdsDBA|X9Rf)HS{8Yq!a1Cb zr_-d7TiHjP=lmWqgM-N<*XE%7IEYEp>DoMtD0C5_vh}1BX{lv-IU`KMZp*Tj|yzH>SiXGa8@6 z1Je@g!@VskoD#_7p5zfI2RRE1HOkqV$-W(tu8D8SfF^c%b$j9a8n!`J@S3*?>(_l| zU+UgprBk)Yu-%j_-TU>;%CeFrMov{vx zLDXqq!eh~q@ZNh7UR<>cp<)C6;ro2ZXM#BNA$wcxO7=PFQTF~C9n0!B_b)4UNjFt7 zsvhYqrdlQGR{EOVNuRIMjjS=k&t+H+cIHfhsHcJxMa3TpvXJwp`>03w^C~Dh;3{?j z*maGXjW^Kfz-4w|>bhPh5O3L-U0m$4Uo|C%p#5+-J(I-3lLPODm}VLk1cu`cA@U`} z1j$owV#2?{s}ev1UnIGq7@pPf$r6QLPOtnh8i^By0GC@rhG5uUmKY=97DGuUsbgm= zrqYqCX1`~wMVoxP!(3ESzr}7v0kQtA7W!JCFiFC$UOJqs}ze7f>uBOcHISNr! z#vT9aAi{a)t7RH2HT!I)N`p4OySAKVlzz#qbo!7 z9maYb%P!UE%(4ivyOs=ddSVN@e`4o}QY|!fHKeH8_^fX|d9wDDL(=Ae!O*&G7{MWw z{^@Y;ZR|YRe7d%`kyb!3y{f>XiZ!wEf7Um)_mEaPtrIvLb*|RkN5c`^VL-0lO3=>- zYe)Sv;N|}Y>#ZqNy{Pux=z?zy%AA$HogQ7i()O#f`C8dJU-PsK(LP+ zUNOQX+j5Ry#^Oe={|F{IxsVG*G^QFNJyb*{PmFJUy(1{PSM{H!2wzg=&nOOg2h`#V-V*OXp{k)H}S!kz92sl31 zXMOMMOsKDnbyowS0Cv0aqjvk*h{xH3q#@e?}$3SX48py+o|3NH0UcMZj%fGMehMB4w zPVL=9;fA48ELT@6JpZ1Ne&|5>6j&bYF1E#u?tQq0ZT@z6FJ3M~)B490h>}8#`?*&TxaTH>d)tq!GX)?hv z$u|Q-8Hx3(92A(PBz|Q75-6M_8AKa0;kll~El%~uLAk3iOcs3?*pNHdKG;Tq{kHv( z$S%-Qx0vkZ)Tqj_$6tvR^a5BHlZ6QcV?Rw_`dyj_kC3C9o<;l%k?F5jSGS%%{(-k} zY^?8X?QCxB7OWVlQEi!Nudm-Guk4uBn)bG~$5g}}1OmJn=$+9@F4fQb2jz!bLl@8rI$1WNvKKHR0bru!+QEscR+qe8q;UoKFL%t_{A|D?{fT2w}6D z(STu7+W|F$vGwCC`c@?yo2~z^o?(>-mS1=0|qe^O~P**C{yiL3ZuDO)}_+m zgguPe8$e&%>c=I!32QNv-;IdgWknxh)hMDY6;j3 zz6T;RxON)TTI?LGpNyv$Sj;UR>W_r)ZT070uE^4?{p~w7eWThpn6BRsc2SCJDSxrL zy1TWr*ZcN|-qW=w8`o-*RzzxP%-`hR58IbDS!HVN=h`7I2Ad9!B+j-<{;sXB zZ|v@FJnZdlUfS`x$)$K89&7aSL(o|Ne(mXZ^I}m>aK!=Fp$?CSAA-b_t%sYBHs{5n zB4=RuVTR4*Z7pJY%2^XsuWqcc z+;g!aJV*-aAx8_~wq*y}k&8lWz6~)=!~rMNOeoTL3Y2%PwBU_ujgOJEzq8aDPg?!6 zv%%;HzfT9qTXQt^GocEdr$QO8-Rig0F`J$e(<^STiElcw=qRG+Y;*L`N60NS5}MKN zq7xUr%itCokq2vnd?aKwj9!M2@$>j0wuys)8%%p{V_ky*t7yZ)4si3zNiWl8s5#`T zknutA_P%-vc`0gL|5J(*$IQz|Gt1gduUx3Q$5R{35!ET{0L8JjY2U=zBoj-`)LCs@ z4%#PaGpxNy9~>n+VZ3V?l13eCVRThG4C%bqQJzft?^0~zaCnDg9OyEzF^;3lml?Ts z&rTlU-R9_c%p?Z#T~inwB%gTP6wqY+%0YKpdRHMbliAlOkJ>teR#%HD*ZOHP#x(0s zUS2SPUh5ntkWVw`oZLV!`9-H7xx~slS$f&z%w&#oCiu_y3xZ3Dc0lHey6E$j&q#M1 zEw@6A;Dibn5x(F!2n+Nx&l?XozewM(oOd!W8t=JI7Ah#>j#Zprg!>i1k{3xG^e+I; zsaMzKs`%mLx0PG5gbHg7$xqQ~{2Gp$s4`csR|UImft!${Ox0F; z7nnfBw!w>w;Yo1hyN5l2qgx9Vjlm(~oU}{AHhlLn*#i*yz};%_R5E9)IenjwTT{oh zWj$*hW7F}-r>2PR%H+vVUsDPs?K_R)RQ2xZZpov#qv!K2F-vVr<)Q2q`giqA+9z1= z!MQ;vt-S^*xGU*ZjQ#8*S9$PSC})bd&p()VE_}0R`|MkI{@Fckv36M^@se4gUG8l< z0Pzsn2l_R`2l0N|2gq(HsPG9=nvV`HkyDge_F5fY+CePfUwQGT>hSXReFm^roqg`* z>b^CLQ`m^XwZ9v8W#X#Zcp|Yh`)8esY{khWoJKr{BVJTod`zV&G^TH8x=@V;F*T~* zf4s#1{qX^I=MsZNxZtdRIB4y@J3Stc-Z63!7kEQG!Pn1Vh6A~r7%~=r9%>`Otmqg1 zd|tp`!U#Ss7hb*?B2BFCr%_O+HBS031}Dv*CB60c2y#7=<4=Yc(#9`+dpE`gDWJ)rL;$Nk}{U+FRr!2iC$dAOPIV7B=8n$8C{hK~*5^e~7c z-;)c}l)^7CK}yeApw7o<0hF#8FGkZ>!{cC~5HL8MtpRK_7ImPEzqlrlpR$Wfo=!7a zXrX;A@w|0QVo4G^grH{OC{)3J>bk3H-6+d4SLnNp9!9enuCo9O%>Z0=g&|l2TUVTX z1Wp?x+v3eBQZ6|w3N$Rf9}}W3zxyW)zQ9G{+}54SzOJ^XoM;*-u!Yjeri*+;IV+T7 zgGrqkx&*P*Wj4l?r(jo*<7y#jW?i4T6`vF==YlpjKQ?h{JQ68!uGNuJfXPDN2Di*E zV?rih%T$K7y$%-wodN&_PeN-l#y0(-iCA`FbkN3q^ZnNY$ga_}b{*5buWiNoQ{t(o zuu~yh9p2{JP`4YC$#`N)BJm`qx+9rE>1(i(ULG4&OiFrhwZs?u1~^poKiTn1SIXg@wDn7h`taI9~@?gc^T8mjsEdh55@$%g{kVYwHv)q z_bt?=eKtIk&?RQlM)vONhoATX*{drx@PX+R2!L5N3?pfM@Uk~OI~ksL+W+VrOb$lx z4<_#qMoa%doCl8fb_#g;6aA=Od`hZ`2~ZQx7yzP8p{MJ^+j1cG7! zfd|n;?Kb5iGMfiwt?IS)Gww}2zrbdf@Sr4CK*>L}ez}ncjZ}D;0cJQM50xsA(2nX? zbXmK{@jnd95jO8-mRrc`?yB2q>)Q6?7^-5q0u^u=GUIXEsQ2vYCKDWocu{%zaBb&r zn~VTPsAy7l{fF=L_2=1ZynDFyw_OzfB76VsE+dt{1c!36ThgON`grtJRRVzf!!8)P zx|9H{D{BB9JU*fY8_Jis6lSW`MarZk?A~YDS;B`m$s7ORY^REK7eqImJ;H4U6g}BB z2DbK~2@HH9ETGrM{W8d>1vi3tFC+=LP&v>InM$k=v4bUu0roo86XDnabZOi=-k`4u z#|Y-O*8`L3jKz=Qu6N5d$hR%z3o+GWB9*y6BL#gtoiwe4{NS*~G370U(fJs0y4cj( z{(if+wd>+a$kj@7hK(@~+K2C6{=}OOIL0=7Y6=Oxl>Gz+QnCRCB2s6-P|m&##*67u z6B1zRP+Q4`PM(b+tfdDtnzrGV+SSf+9`e(*Ci=!(WL8983LY2YpDs&x1}_J1({OU! z2y_AOFT4iFSl|XZu)DX0t?NgR*S;gS{s=D9IluArVR*Y3-hR9F>?x@D1Izv+y#4dm zUp995>h@>h-Nx?v+V*KZ<#WSA6(@Vnf-6+61~}!(*G~J+kDc2;f4=<7gQd>?@O1k2 zV(sCx=btSt-eJHdE8(A0;bPnt0Mt1ZE_iuNXYmy3TqOMp<^nDrIjVf?@{7od8@#1J zs#8L+EGFg643YiM9_+97PevD~tIt~p_5E+126%Ck`WajO0c_-;~w!6@~E9)+H~6B<=YWj z3K_qxj`ZD^Y%uz#gY7cNCamZpo{qA}2u_wtM`yTU;33Fhby)OD$Z!f@jfiq|TIf>dh!&I}24wLtlnYG8_}u9|>|k|6<&by_p|Bhn_H#VHZHD zV5`MVh$n)=s3*S@425DUNt}N2G(Un#6IC1|_{&IWNTO3Eiv9|--J`Gk)%;j)7~Gms zj=-7-X;&=?VlbiYk+A?mNqYu@2#f^%ZbuD5MA zd{rC=>{Zg0&CX-5F=Vu<`5A^|n$w_c_TS3N8%|-uV!xVU^{Fyxvha-L5ZOOtrGVLT zc|k09ox(Ltc0Lx53HAA8czFI8J9gOb!C@9mSyGwuUB3JcF*=9+${6p0*AWnpA`RyY0<#GQWDL1Nd`!^;fu(g zmx|~2#q+J=`N!gUF+S(rSvWW#dJ8~0#Dlg!YbqT_^#NCxD91g9I_ALl{U7fU237mrck z>luxq4w@p*RGaE{8=G3bMpLMRrkK4q!5OZAj3&e)>#xm5ayTt9)DE99ot&{f7(e|M zI2o$yd^oz`c0(u^<_)=wbWCeH)L?Pa$ELCf?%3Ok((U%5O0SQoprg-VrkYN+fW)Z) zLgf2JR9$#Uo0)ReRl1zr)^|arW8K0m6TzPMAP4sq*y=TS8P!2SiV5ghc7cO9m%vJs ze1ZdT6LPMuX3cScEMgLQ6H#(_v}U2mA%YUF3SnnmW;-;ZM=8w=R&Ws$y(R=ds>d$v zRQJ9cGfmVf9eKe6R|h88HcilG*dRH)O2HY2&nNxS6xPh?;HY&zmg7_I=TDtj z-TOlOCLRF3A4Farg-E&srI9{j=h)0bo8{LC7>#09h2hY*;97qzcjRiNT%70fxxxs= zJTD|}5VbY)vL0SC?dl6u=2b1)#Z4Vdc^BR^FrIXTaZ;ka-D~pHT{W z@s(2tYcNF6&nWC+^>GAPy}3$VJUy0no~KL}md(vI90RFmzwG=;6HLr}@|v@`iqEFn+6Xe~9it)_C@Q?d4J<)qLsxz~c!u-&sY7Hq@?(Rlwj{Vcu@^j? zQK)R2fe2f{#XPT&hTmRjAPl^QSmkR_DvaaU+6>zKxEJPm+auQO}?x zcNWVF*avdSFDo{uPr%i=7RiLuD2UB&vu=Ay(zkWmNDd;8;9(^t;#IJ#+G>VLGYc?j zY4qvLX@C0t9;lvPPuyHN%WsfF>CX)$%}$WRIGh_smRukQavFhz+lLc7tZ8l238CuG zMz2TXpGHF2mhC#O;-VSZ;vl&#?9s;s$AoySq20w=Z*+baXWZW+oPXNt-o+LPXxu%9 zOAcjtLPE)YyZ!0;r%&}QYw9SXB0_#qymc?S<`86RHxY$-pgf1kVw_gTadvFcnYmKM zafcg^MWqKGtJ&^uV7EmAZ`|@U4!mq4P!nRiO0`e@Trg$esuk@+U4ji|*-z^o6tXKf zy^NeHvQmQ=zZ%Y)+zFIH$X ze3fM_&ny=43b2(WCKHa8F2WNGmh=anuI^)TxpYs$7tnPe6PJv@KKP+hdj29m|veC$P78Zmq7W= z1U+n*PFoC>FjrOV*U0$Rr?2jOdVFv&iV`3d^!gUEpxr%!7uYmJyL)`EYm=XbP>uXg zER$$K*)qK}f5erNnmQ8VeoZrHE|p^{<4T$bB$#mDhY{Z`#19YOcJTmb)c~Q#|Mp5J zQ7zrc|1Rw!rh0MtqOSu?2c^#R8c#*!Z`ek)X{_D;S)>aBYG3kI$CtyAI1;KK`fvRM z!|gYp?)9FmAp|gK(3}*gDpm;>ddXLDF*JQMZ$iW8V7W9vjy{710OAg4_$H^|8@|~> zzu_xwSA4P^mZYn)ly9g6^GufQ4WH{4?Xiup{b4&Di#Wm@GC!mcMbuSXx}m77_$2!; zDw(JY%ShOIvVSIn*n2&A=OL|llbc*V4FKKhvo-W>!M45W^>QFfcu$i=UrmhA8C?%9=*oG z0-A#9t7zFze;VRQ0X8AyYgx)~A>{$fXs!^kUfTEDSoZ0fA6GbdlV#04th%7Gms+>D zOP4Nk+xP!;B?v|BKPHu9j~kosR+|4~+Wh4ZLi54Ysp-6tV;*R-N9W5s)|}~-v6Vc|-&l<+I`+eLk;K(pVGL?K))A;Hu|@eYKc)?i?Fcw( zKxXb@PMGypuZ$7o z^PD)>>G9I}9=lLi8jX73w0>@AS!_o9Czy@V5D6}>Lhb%~&Uc75C?lK|JkaE?4+kS8 zJq>R!ahAK2{gPs`{+i3fA6;6R_x+>o3czD%>b8=v{*pcV04YZ$Uf8LiRc#l)N~#Dlr=5W+TW;<;aw}@$Q3P4 zD@2kV{fQS8@K92j zwkS;(7-!r_WIM@PO@l3So2Jqz%*|TRZUZT3>?wVe5v(*X9t(9+gh)mon%R6JS5uT6 zQV$=#B^_6#g^ZZkE2<6YXcuyW2h1j5DmM=G+!f3KTGsI0yr%G5wJGcyga$cV$_D4C z=K89(Suskg&1#p#C@Fd<21io`u`|eIix8&YaT_2kBt_gHv?Zno=(M>}(3br`qhVbk zaqMtx2$RMGU?PnvHi3MWi!CAXpoTW(RM8a6T-p>ihS-o!Meo7Y#L1#;exTPT9c(*M zdzz0p&CF~cN9u;rcG*?X|B_mXcnjlg^U~=j?4R%~X)4@pCWpOQtr`d_T_p zb+!s5`hysD$!KMq7UmMvQk^il$!dLpxRqFIF$7qWABFrTb7MBQ@eTm60AjDg*vO9J z`<8w|+8|E{gorHlbJ)EBu|_DuVHv{m<%${YUZOt~KTuZFW~Rd4mUS{JO#opkF{R`~ zPuQ&U&qW|CNJAtHodcE8qfovXX58HPvyyDOEL*h zMd(-A`1-~4e0+K-6&zG(La0D~Po)JOGvcqk#B6;D^Q&x?71I!c8oJw*Nf8gf16=X8 z1ac_>e97(P7L+rCt?afMW1e@IKX(p-*C)?*12L><%TVc$?CO7$BPhMJD87Y@o zeL|Bsw&ZP{XsIeP1y*2z* zxKj75;ZM_d+!DuvC7e>atbs~(4<=QzD7W1J=?e@jpjE)jHW4Uk=m8h|3YjP0k~n93 z&QD)M$nppd_U!NISrl%(!8yAd&VSn=#kYE9Si;Xx7KQ;cU)U*KInYAlt0ap}ZrE|{ zB{A@`_X|JPBOkAC=-U;`#y4 zcSzttT`+@f!fDt7y`tja8AK$dAJ2n`0ab))xLnT9r%+4Bt@5$Df2Hd@yNnqsCPL0>TkDGKp!^g z5K8#6XUR@!Y25bf0DtK1ZfvjZtl?%r&PpB&Q(MmG!%d$gn8;yPkzK-hB4tmH!^TN9 z#xvRM(Nkvsg7b!>Zu3Tde(=1hS5(C+syb^-QR#vTN;Jk_$*V+(@L71-^sBD!6A1)O z5JV98Iqc@JV&guJ?t^3?+g;XZb=$~z6Y8crIZLGd_}6 z2_NzKDtxpE_Ysc=cd)QtLaJFL-|uwJhm6eb%Km|d``S+5QtM9ZtGi$hQOS3CIRxvo z!59&!tlMsNPw@?bnqofr+K*O$;9VknHQp7F!g7K)xoj?0RaD5TQjdzgA)SWDa0zk%;c>M957B;iC*10RnFx~eRycO`=Zu=7GE7%P74Ra zA$XvpD>=6y9%XQq@V^vX#otkdXu>sFWu^-OV*cxGZTK>dmIeRRFCXvczQi40 ziC?HaV1bFgc#Kp@oSz3fNLf6YB9~Y21~?A55%4dY+r5Wdd%HF<&8=4PCkw3imjHXT z_4x7D-+H@0JbAqN^e+HO!`RoSz=ST3h>auR|8{OM+z$dt21?9K^$EByXqH3e!yQaUYOYSE35_umpNgM+R_p8^ zD_%-dfgT7NV3$31Ns!|~Ng@Z$E<=UYKe}6sCYIhN(!^W4C@~*vDXg;BY81@s+(W3@ z`C3p|Wedl@qHE4~0RAPsamnoAvY}w;ZP|yJMQE0|l$ix`%FGH^i0)oJ=M{Mg^-}KC zhVZ=Tm}}#98HA6kXRSs_C%gW!l4p{*j;eIkC;Bh_kLp6YvCvTXvo4fb8Qe`Jw@-p9 zmE17@+>AIc^-fHz+pv6}GZ7B!{3riSp8dq!97uNZpZquf$$#@w%pP%qGMni?G5<~b zlQiv(-oSSqVHhq5b*ZRAu*q%=%Y$57KwkQqj!Q)~UL`2s#b~Jr(vY2IBN-0UxKo${ zhQM|66qbEz4Fi?ZiiVHU>taK|A&NioiA98D5hjumDuB0ZBSU+%)%_ex+KT{K?PckB z+3P;;5}MM;FvMjvcw?AwX{-AMbLjFg>3U zSR`x+0)5z=xE~|E(H-LuQXctx9xKLsWIf8uXJ^S!;PbLTdQ1%8!>t((I6DD`0=z;a zaG;Mc4{oTVLDulzV~k8WF6lTPq*u^}L8XSLsTbMHTS4og6q=wZrUwBWS6+9oAw2?t zc9?B`0w8J!cSL8gk7nd{RI{gGR2-h-LbJYb!;VLwF|O-H@rqoB{}1s-ISx7y%ylzA z4q{ZI<>3@7cQ7F~;@RqOin$Lj8%3d^$=kGI%f!|T#YzGrslzHEa{Ht8vtX>Nb=Z32 z7P24>k6LsOo_FEGC9k*oCojj7 z;rXjmI-C0=1j^`D%9ck7Ojt?-3gaM$IpNh|hcGUCi>n^<{1W~lgfRK7$WjxtHBthk z^JyavskQ9>YHf<-#s6Ky3+Q+US*PlpGq%=C5cK(zi<9%=*~wrV>E9~4{W4ufN#U8` z<^B)ZCp?>S_WS$M_z7P)`O!-n<>O9XyA~+ysSbf;AM0QVH&{o7rnf zNlTELG$PyQB5~j-7H2OV-&!sNDf{Hg63<@V{speWOFttHWPp#ggGLb(6g{} z=+asaw3vcsu^z^5(j$MFB$h6Dgl&);m}3M-gDFCayjn{BP!D5gjajb)Z8)U-5e)BXgX~60*Qt;+8ZXKV z

    Sto~JnF*Z?w8Dp1gjws2Dw4Ka`O^G0)E4Ga@9ygG!32s}eI6=qkubi)`Gz|;n zxDX8TD}kDb*W@kQN}Fzyo^D|ZsTHRZrNp@qEE_^s{z&GCS~t=7@x@wVg}9=Wy4S#)&hv1;MoeEQ8^i~fpkF`%(ZA{I7T1JW;Jz3GGKBlCwFxN-G_cLRklh=w}vj}8apZ?_*Ro9BHn|?OxV7i+bIF`lDdmevvvl<>(%IgJ zb+O4ERqs*i7Y#Q+&&hE)eCM9jhzb0cSQuQr`mhAUJX@?syFM~VI94pnd7ZlwHXheq ziL9$>ArJ-9U9kBWjxY~(t2>G{i!E&f0agm8a-C&ZT@0pVoyBVgGv_96h^CYNcA0oH z^Rn7Eew@pbY8g(0)0CH~1sAAsqqnW59{c-Sn4^i2qpIK0sFFbJLRk>yJ^-;IfiKiH zDvJ~GH&Wf#7n(uI*MyPU?f-{MXWbbf8-;XoeBiEytyB6Zuo7Njd$eu>=yICDinQ{wnzpl6 zUAbImJb!v?%+NQs+n zaYH`xP>mPI1#b})kW##8O~>Jqb{;Yupq9N&;D0RMnkm)bz4?G7O^MIb*+`kVd2JdP zImRo265_3Smq)j1>-zx=4V*UHg=K@A7%W8zS?~t&qmmimCaua3~X0O zJNYZA8N5(YWnbzC7x7Nft_D+ZgU6i?Nw=hE#+O<;SyPp`py)b$F-NclWShmVW;?WZ z7)X~!SxGR9jB6;DxK}ugoSr<{W?--ilN(cV3Q-9)(^cr_yI>9oFT;g!&){=81OE?> zS{4&wYkShr_dFsyHl$n8(|J#DQAz(Lywn&ieX|a= zp^q{ovX5Oe-Q2BWvnMV)oLm)ml=eeeE{vG_qymRKTrEf5EZHGnYMz|9NYtEkaq8KLv~q6dmCd zt$dR^!zl+pO1z4Luhst2N(e*I5lv)3>H;G-gpxL@(dnf!BP}m}uS=t8>adH96;0pT z)tyYns<$iiMMZUy$N{>xev`nJS?jj=Em$e>70|Z7Qrcu1m)mh}FWgM_L=b9zF#W9a zr$4>F`KR~$f4u+vPY>SrkFgYdKOJJj;QfmMhweSif|I2OEPDIagC+dC_{k9aF^hzY ze`GwdtHrU8^1C_qFWkKI5P3M;=SX^mY+T%hOxcBOi|QXd3kSV=tS+qW=9 z;wEStWr&UW^8x0lKi|*}6mLg!V8UB@o{dIoMzb z8LqXT5xE}1wEj=+{HGVEF9wrX{5P35Iz9I9cE7>3;I}wOI{U9rUp^l`kT1W%gc(V< zTXj<=nF!8a_v|iox}H&UfJ@(DFvxtl`aE_Iw4uN$p|jTD(Ox0z6&(LLW`!8Do_ztP z#`*YU{L=vX&Jndjn)BneWMS7?{TX};ckkkMh%C$d>tR{s9*!7fMNZ2SfKq{TS_9{^ zmAe&SFKdBS;k|5vmje~E)l?9sR%PzQPhr*-L~RlyA9LdAJc~07YACFFm4}i88mSl( zai(*(R9Fzy)>~>SU!17H;4qt3eN{>Ugpo??QU_cH1sDXPR&nrdL<7HS;@1m9;6moV z8O0-QB!>sgRLY}sQY_wZ=tXR^vI8j&>+g^J4=yv{Px&v1ir+~6p`OVrX)m9--jpa{ znY;eR6_<{Lza>5W_biG~8bPj@{o(W6hQAL}7XTB5vQ14PNOl9jw!DVbQL>^t_g%2uzrF%V1@)qy$@Ygfua>m4*L=E0ZO zQp5!g@j~bDVH0uqlVfDfLlgL`nd+7bT!US&;ie8vrF7U5Lj=j)pCVQMU~-B`keJ#% z(8HR3)E}N)Oro>vV^CwJSJT=(uzv%M+?uhmJnEl;cqMiL`-9R+m!9VfR0+Us0Q|6A zU!i-G<-nwih7wJLS!-n){OWyy5TO5JxrM+H^VlM|YBG2;9AD7IAQ>xxflXnnPtg(Z za1U78asdAT2Jr5Hd1&At!1DK~h5KS&wHA=I$N-4z?kQHq9R$2#;h-3b{Bk_h?!JTz zfn=D`Vz&kaKf*k{CRfa?CQ0uPpn;j~J)Hyc!QMAA(ONx|70hy&La)x^bjS=~V7oBF z%bt-wN#8mjw^-}smVihtx7biY1xnvrUQtNGjY9_ zLgCP*&s>npc3Du7Z!-2^rtKsIs2P|Pel$)>VOPLmqnE(S@v4#)5aUrZ&};Ez z@MgekDv)b@Jn12mEH+M<2aW0Kz}0?QjU*IDti75Ru3JS7bxJte06x%gOkCLpN0#nV zC*S}SdnbL^WT=!FiltIPUQnXE-!@4PFRu{Ng`_pWcQZ|h!O79VpQq!|F!2vZwuRLyIbq{g2iNq_2qb#?~W!aD=yB z{2g0P`i>a0o3dY|uZZ=}`jd$MqCXwYCj&Zt9uKDmfH)F>zL&E1i0P{SB$mtilj!a1 zPoni)e>zedCxcU*Qw@Oc5wk@-kRc@rbP*da@&K@yC~+h~Go*FspG?mPb=~yl;@)Y0#W(!wS4=TKNZ9;_<2uj ztn#NKvCN;JOWA$?R2a|kGwTJyqmC{Pd23SI4|H7F^K)Jv?hjw44_~Jb-!wj~+*@wl z3lLT^cpvErXeBM+>GRMY*dlpa$!0Mpi&{DKyQA;K55*OIXXjbvc`%QyJ&4Xb4=8UlXgO zSNcX-Rl(Yu1R&oe7-V05UxCLrIXrn&)M|o98t3@&O%6}qWbnRe#7{>i>#)4aA?m9P zBwjV)xFSQF!{n<1ro75wBKvF{$@~-fG4HsrXaSR@RD$?mp;Qx0GI9=*Z*qw8Cc~tO zt?n(8HFJ2vtit1tj=ag>ebI>Dmlb$?ljA3EGI-f+$iCDJ3*jYG=H7D6II&Ct2d}h4 zEfx9RyXqjxfMgV?4pBNnDhD79lNL=HrKH6xnW-XfRv;zriM(0)rWH{WQ2!*krrn?t zxt2W3DZa9NPliQ6VfbSgv!QDiYAaPvmsdF}>8ph9;D(IZlNk+^O5Vn+jP;Vz0Q42P zDB}aXiXBOr5P;H8Ift!O1**I%U{^&dN+r!Dn4r0`G+w0=J%@ddx-6d%cokt6_*R9& zN=Z48rz#fkD#DyGE0po?{Yx?a=a|3OWBl0Vf{azYw^CJn`YPw(RQ3JSCBo-4b*?25 z62jyYi()WmP)Nqc(p3erl1|zjkV>75oOlJBH8UwK|NolW=E1hSp$435hSpbViE_nU zIzdjbFvn5R(b{nRkeOyRFf;TTf!s;ge+^*LpCnt%@w6L-)nIqFvDScK9L=>EMRam3R0^$}YZp zcaC){-Z85Jo#SJHH;I+lkBW%&;9sw5`VsXhkRUoL~o)`X7MbR0HxvsitXmjcz9_ng9R~s z8sXWGF*C|bg9H$XrI@CJzHj$wDItXqmbxp5Z9rID5^v(;7{aaZquASx|=SW%%hiRjxEGGMj)Zl#YIn{lzo1&+`mt z*v!4BE=h|m7LHxOzRhhXR$dS9@l~CS2rA4roz&+U_R1IB1GWIE;+>LqLlIByqBOOc zBvB@kErw>ElAyhS{d6>}+v!QW3%*;9I2Fu$V8)KK15D&{DSYX>_kwAMml0au;>AS} zsI7P7ixym*M=i=$I11$MBn02Xi;2kh77p(pjgeN#Kaecp@JAZb_wxc`^g0Ll+y8Ol z#qnrzjx03?2N%zmenGc#IRbC+vomaCphcBDpn(S7NMKIrdM&cA`fmozx_2=eOb`2K zz?=t9r*O}{YW2^t?}EEU7}|!wwq{&A4_1NZ^IPwU{kUR%5k|czI zA%nzfi_=-X{5T}hlG<%>ZzpJwTPsWC=GB7{s?)hnSqHM_<1u|T{%LzW9a0n_Ehj2S zd2*SLg-)PY-}uQX+=2v(&^sm_b65irxhUM_|?1bU< z7#faF0LQ5*b3lBlaSli-rMzokwQcM>7@L95x-e&QY!{G^b2Fb1&STKYlRiSpVH!~3 z%FY{5MC;ay*cBVpZ?bg(>iTTH(WXWh?`)2dPJMhHzaEU_`%QAgJKuasWl@bx4xZg0 zv6RBubmKYyu0a4j_;bhgf{sfZ`GMV<2C^YP-MY{v(bxA|v57#^3 zDHtDo9rt%ii_K}&;tsogY`yB^5a^Mg+<~?NUTW^-bko=1k6P4HJUF% z1T8bmzVS{a^Td?t4bDsEIf(`W$siKEhn#KU5T}}DLGoqFOgPYD12sa?jSLukA4)>! z%<&m)pTpN3UU}}|y+2~GG}wj77I>e&>S&TE z^cg0J6^JHD#->OD4QvAoBjQvQtu-zd3M>Q@R%*5&Gd4xlOfELLE7N{e1vm1XwiLj$ zbvB+(ht!z;bI5Yoj$n4kR2zfa6lF5^{k7O#I@dy=T4qB@MA^zJDX&I^4&QS!xN<5+ zSik7PBhA+lc;9A+nIQ>?%rL<$OHKTwn4tu%nz4YI`J4kc3#I`TS@NGhokdP1@(Xt$ zafB0I>2@jV+{VuOS9A)Lu1pOj!7m=|t1*T5WW01a;!`r&&)Rn;TzURnEEULEkP4a} zSC z>G^&N;W?EEbm|r1tpG}_Mj(pSA@VPtsvchyDmgGx((sHXL07e+T|0UfsRXr02UQRmMj%@Y;E709dZMVr|0u1;+&l}eJ7FN3JDQ4%R+1%&ZXAX#@C5~ltX zbPe0dtEKKeOoj~Yj5n6|wjqV9DbevWzQOjH z_q)ey-A6cn^8Dv7evze~=~xam%yy7NR(Y^$&&E8RI3BgR+S7@{NtQAf=bL^BqbOM3 zTa_6CU{J1{eM+46puN=MDO8O?g7=|PVk0df^QCC-_+;Ea$7FV>oICDoDRHYnht(=; zaBcqqrf&v{c1aC*R}|8<&v6NCfs*Qz^z6tN)k4b4X`wHxh0IZtmij8jr5DW_FYS|! z#FwQE0t7{Y>fBY&>F?}de;%e(M_%QISwzi!c|nV6<24jKLAg5kk zbe%fgY%!5FvCkIF-D*Ax_}RJq9Q=B|lf)ac@bKd7WOzs?G7u35RYC)0lvx@@aSl_6 zld+yGbwP#mk>$uST*s})+=hV4I2x0U!k543C~>f`gh3K%tZ2eVsdnoYMW-!~eOXtG zM5qC9ayHdRKm9Mj&j}Ma z;@9O#NWah$n37JfIe8K_IUBe{h+M9Vxk8KmzN(pnUd+_aH`RhEaM8+Xg?o3a6{_m4 z)Nc1yP%FV1V%R(eNk2e_LWLAng2u#x#Fi&iGGW3Ta`)r zezFkCpQrE79{5wCHvg6WCGU;pY*2COxSEs7G?q(%l~_= z&v4a+%m@9dE5iDkzOV&Wa7l0hY9Mu$SYJuMS$k5ct{1YADckhqPML0Un!_Ah@>$#z z^h>F;IzL>_YAS1m=K;Z$lfY3A+7#aEW1^<L)%|MQOvx+Qtp%Ju#Jj|X?V z2XF6wga7sMW969Z+lA*#pDkej@`i*F5xbuWT;gN+^b4OPxQ9>se3BSuK0W7?1Ty1k znGX`hgNIc@w5xg=%)+C-kPq}q97hMn!E~{J}7FQHu^F#M0V=$CSPMx~2 zE{t6En#97av6a2OB*`i-oi6xb#eyrIQAH}$)s+&97`2NRc$B~-trHka1{U8`WVDU9 z_L z;!bc>yhA0A2DrhjNEchiAQgLHRR+xC(?wz2=GpVcZEV4WOK=^VWBMAfv2cE?6kw25PzeIed8AE^1A!X5v9 zh8DO*h7eTvK5pN}IuP4f@PeV2)+&p@3b@A+s>izMFEQsN1LigYg0gx~ykQntYW)!n ziyD;jh-2_ZwL>yfq@%zuc1r3hHa0E28oyY1b|G|ATdQ_cdvrZlaXfyk$-NAgW`hqB zh%L);(8TA)+09<(G6lQs1fgOn>3?D-m{@SPw;BDQvw9d+kj6($ulPWjO2wf?vt}rQ zl2(EUNkoKs~0$m7(5EpNz$@RVaaYWSzSe}FUu6NIvS zzIBVZkPPC!mX_V16$txUocGYjofu=4B9AtpG-b3ZzrRAz)5jEip>|9pp{~R{bZm zr9mSuFtmp9CI`$Q)M-!Gv@R8r$rJ^=Ba)bC&o#B5>P&*D7H~Q=iJ78U;y!eBib%6C zMQIFE|5y%^AYq|4bJ+v^lS|e>bS?^olfxUacrF_vY;=p@X)^$^27`hl`ftX=BW#lO zc;3E;d3Z9M^2{q3*e3FNpAb z3g~N`UkJRa)2vH(i37#Sbb*F_B5P*lYkP&=8-MkCdxiZOdv%Xjw9|bPcchr*OkQD+ z!AtQ-JWIic=C7F2ov+|6bMP=|<<$!M?(e+VN+f_|v4XC9F>iAvb^w;_U)LUQK7=Rf zs%v1)2w<^o@u&j$9cQ(tNyZv*UEFhC!~z~MhH^PdVdbUiPCOVB!(kPmVtu_%GfKHN ze)D2j3iWyI@#<J%eT4VqSz@em3DJ==G`lnRi8658naGfV0f*AG}i44cr`S6gWJChsb zz%%k^cC~+oVgJxdfRFhXK`dS*ct+!hWeVzLbOx(wN3BZYjVk~mCdrD5=#b{Cz>f!r zZ$@uBD1HoPn8MX_H~?h?Z~%eUj3Y3XDc!{0`g<51mJ5}5i-@97g&x%CM9JJ)j6f2J zki1QLQBtUa6UL0nNfJZy)?Q`iltAXi6OoLCbJiu%cFE`{Q==~zlaZ4lg_U4tRIZF+ z=;c(HI3;v4ki=Qj+#6@zx6N_b1j(#293^7v6{;Z(A23x8F6&T*!n6*l>xj{tQI zeeJaSN9t_qpKKz!eG0odd9@v`8RmNvhWv@xca&Yy(;c?6{S*R(Br^subPNQ-qytWv zm$E_63hChJ&=bijnn%Mato!j#wRixbbKEu}xSyPC9m|i=JNKc>HZyoQ- zFd|%KZiGvkLQ+9%3`U2zyOX$_=`C_OHH``^G7oZ^?d0m%m7EB}#{bHhZ6kJdGMEJ5 zWRRd>C0r7ppsc}DMw~CI`2rt@Ch|rvq1IL3nwx5*41ioF>?SNXR`p49wCI=z5<`2}_lM=g~y z*iY1>4aD&V!h%{au-k|uYkheQ4x>8t+2t#8=|jMKDCfd>3~X@-`_g)A^Ap=l6Ul?M zjRyQu=Eb3MvXuc34w?9#2@{crEm#^QMU9lTb+?YMSC4m-L0HN(2t#KL;U6LzW=3`3 z9rIc!ambq)z|R`HCKNo>(lfsWSxfZrFq)Gv$unUREsiDT?=QcWMv9$h zO)yd|*tubZyHP?2V<T^~S0KPFk*Rctw)Np~ghm%Ba zbPo-s0jA#6Wboe?xX13uzPWg+ekPfcHCiB)0}y-DA6QuQnF)e;)>80A$3jUKHT8hG zu7NUk$=w1EV><*KKZXa|tKs(owU<9Hi1>zaqvrv1#IxDrC8eW`Ix5&9eAkW=LX;i; zQL+?B7a9oM+!r8w3VFq|$-Kn|$NKBg_YuB1a~uz;ej895ieEzjB{})N;u9(-WJS;WD4YX$NCX> zV|YI&BkrUGD@I)TA)45MR47(>$}z##h7ROUnBulQBwQ3ulqjMDo){OJ#0JcauHiC7 zZp}%~ln!BrmV?;64}iHC`1lm@y|KO0kMEkq! z&@rzpeO%ySYuTAAuRlYch*gXYA~^6z%;SI&J-s+(;tUZkweUpJm=J>F#sy7XH~Md{ z-VH3;LbF-@dAotsLlS3n{tC8!-i;JqLpNv&)TmC>LoHjAmy_^!6f{o*?(05>1NSQhmxq2ipbP7`OJVKqM`-7OjLyFU^Z5! zar<<~nludb^I$kwCzILwriR7@s5BPPABDz*l+&23;AFwTU75BdrEThxy9w@kWIk^p ztv1&2j2KiQF!br`aTbmCO)|#HKJ%>;>!p5;w9n*oWS6w0aEqMOfnE$B-nmKO zgbA5jWOx7{3N8oGVQX3m2Dp?!#eNHz}-;hYQ)wjZsKHXso-mh7zxF3NMiQX zjpg(COVKFGe}>YpTiW9tBoKW{wu7#&UB2UyCT=V18;w--J^D;)Nh#aB*QHI|95>(= zx@G%g6YR^X3UgNjK&TK^!MsV^pu$-CjeDm@*zikyQ7|RcF9y+?HH`(X;gxRgdmEsj z{$%T%qruA_f#}rzt$giG7l)BscX?fFe{$4R21`o)Q*S&MgN=@O$R-I0`Dr|1{1u4p z!V-H0gO`Je$i+5HV1I_lgewdeKG+wqj6C7}3%#$xKlmfQs8=PxvPXQ7*1~&z!fW+h zIUsw&d$Om$mEQz0Qi1;T+2hB{*zT57H2%Q#HU4JpHyC3E9*ED)UT0adqhMjkbETc} zBVR<0EUjHL?p$0+ZI!3Auf_B~+8PaH0ON6os*;Z~U)rNMXc64s|4be9i zo+2}&i3M<2>r?D$y+MQ?^OG$@pq$BZJ1>Hd6J+_?|8&YbOt66tD}Z+{f!l-#94gpN zc{)Rx?>*eXgw!Y=Kx9o~$3!;}8mtAd3;`R*$$1g;J00Wv{?W2*!*SVOOO+-!r^-zg z8O>|vz1XmiQt-;()KQDv6;2+IhuSVhHDZZ9NEi{$Q+)R>g@KRq76V^`mrX>wLs+dh)f}T9E(swVJwS>Y=_8KUP~( z?NL)Bj9Z*Mjhn>WY{@CWqd`tGZ0p*{aC;c`plDOPg0(^pU>uq5Aqzinq<;A=>1a==I!So_|ri3QM zij5d+sU1BWF;HH+xosK)*%x-@CuGN1D zhbpesQcZLXuFxUY5q_$dl>Y`J?4HleYc+U_bJsjB`$WCNLVJ!}VMCeoID9r%;m%_Y zK=zDmWGnzwEST9@53% zvbVvfo}m-_)_*HhcDtzLtm1PGXK9HUoMj;99Y=$woP|?<)A`uST7f2rZjC_bd}rfI zY?Yx?VXN4xx7$2_Dr{w->)A>_UdmR6Kt}%GqPO*Ibu@f~Lr5@ozlEQSoUSwM_;h@P z6+)r-y7#lGCR+^QAM>+Rj;1Mj)u+HSSNiLo_@qGj3+NCS z8BL|IzJxqGl*3~v)_*bW+`WC*|0E6c(eRj2s2#~lxP-Jj29!BlL_^BKE(-E)0t>QS zDv}T62VR7h5)&S+DKU`FW_XI*Cy~6Ob^3yyQ%TzxI<{~d=M5j&CpkWEpLl?@v4Wm0 z<;H=-M<$GFaoi}_1RvKx)WG)&0lu$|jZ72j!9XiL`5#c=Fa>m$%vQOw0h^jCTXG7d z(P@2d;f$+V0;f>543)=Uv8hsc$rqO4*+s! zf)2j!T#!+9eFK^Zj7lTq9NQQYuZ4;WSsK6y*)DNPClsAi+PfTY6&KQ6qz2mw_O*k5 z7>Jd^jg^dcE`Mx(d+iOCfN53hwy=Ybg8{)mIpq~<>6dfh*XuckDj{YdeRPji=r7KH zo_Zg=l{jy;!ji#$j}ccooVecv z?uP`B1YFq-7c})5NHH8;$Yo9ucek_X-GiqddJ)9ZpmbuIBbqlLC-}{+Zeyg$&V~>q zim=S2nhio*m^`2pGY?FP1FNE(dk*eUvqn^L*)p@@gY~hV$w<0}j+~lJ*d!)AXRc)K z&PBi?(Wys6`7$x(@!_)WhxkR>9SS^%Kj(KeZ6t+zVoo^ z^s;BpZHdCKTiVKYDHsI`>t=%93?5w&9<`ORS|daElZmmyJ|en{QFaUYheR; z{8KBU>{~Y>z~|~6uIYdXx7dgZa?nM5jL|f2;ORsy*eFED?Ci;qH(8wk6tQLiH?TpZ z8Dxjs%AE7kC9f-8R#Y-3ih9mUs$;xfBx! z27H&Yk;U|yL7jva)J1(Yuu}pWn(Txr&l3?!-i&d*#)L~PiV_p}qH43NUlNF+0`_U` zcbdW(-cfH8`a;&b)}W427-(U3YtX@mP=h!%{FCg%+3VyC9~4>IUfk(Tkhrd+jn4ha zF^~O6_vxm;Q$K2TD-uJpA)&CcVJ;J(w2B~itcVaAWRwb`KW0|&@B~kq5Neby_$GWP zK(J*Yv$n`H{}oOJDh4eJa4IoGg7_9 zeI_|IHEkFRu!-i2M1nD%5aLECu-Dz9_3t;<|I&N1^>Cy2bZh6y+G8Y-h~+PmBlg(` z9Tq?dre{*CR!Q?Tq|%WGB4PL;Dy`Bu05Xq9`El=u?Tz00+U_2{BSVP%l|z=LV3?zy z%Npomp%SgSTo1AmPxPb_E>bbrlqsEnV+PDk!xCZ428{NO2Wx~hV6x5Clo5e;zhVTx zU{*bZu2_%2-$`(X)=AN9LaT(EHj;NNAx{c;-v0Ykugu)oN98gx;FZtj2yAl!;AgU` zliM4fYBGZ$W6E~X5ta59*{3vAoFEi}WKu;`GrSun>;Tx83n`4I5eO10*27k-D`f}j zwJWlV#)~GEvr3An_lB}JQJrzx23JGVF-)K%wwp*lZf9{xsPDkDvYl%yFDZdMS?zsU z|IzqrKWBQKp!2w{a{!{&nN~~E$A!p&07SFT4~cd(Urhw_6lucde0y2g=#rSDsoc;sr@O>xQ{FeHIT(b*a|#NT);N`WAdKL$3L;?K@bolsvZgz`YX8Y82Jc0Ia(feJf&TwoOO!fg|?x6lH`u$Wk13rp0 zbWr~m{jNLcY$8oXOr4Qm$LI>^U!u=V((I9KQ(aByi-}iCb_ew@(O<3wYWfU&OLDNm zdhO5}XGdtfP+eIxm>5*4;hH!MOCz|}xGuu3l^iL+H2#`6KtL50Wr6eqw z+(bM6;f$2?BRZFA1<6cM^C*kL!>2X{&VmG-)3Z7^1~fUb=4zFjtc|pl!PMyj){uVsUuS=#$=awjrSsaGT+n77u7O>>91RpjCbuEb;Lwm}g*d{8* zur2Mf${egTV>2x2PSHXGp2dP2sf)BXvbW8dt1-;t*H9P7YjJTf;`!S9hawRy{?(lz zv*vZ?#COU(OT=FY>sR(czo%bejva*0#5~^vhygQPPvo1S+i;*UM%TdI9L8yla zq-3zd{dGQ8Rt$qA3Ci0{Rfn751mYqeqJneF;vwGd4Nv1pLJ!n1OB>Co^&5RL=+E~9k_;0?w@m3#`z<1o}Dc-#Lt0I zKwK5wEQG&b9j+oH?NtzF3pi<2MflaL)zj0}DRbb?jV^oNy&}#+nSk!fMv4s$(mei3q_MGbfw*}2m^Zu3;xXPGZoF8^i zhrHilaCik)diJ4g#Jy=8=jB-dZyxsLw1vc3*stC=8y~*9N;f2At^xlYhSLQBJB$6p zJk^qDhYrXOeo>*`ZA>ed4bR?uaV<1Ax0`Tmy?3%cdc5{sZ*%*vU(7|&&20wS5xaWa-+c9} zBl^`xK=jpkdfsKy;y`1*u@`l7{CoQxcy%r$9B57}1XA^Jj3HbCQ)-TdXQS7n@lPY; zTwGj^B~7M(3mXUWDjY|L30dQWttwHfX=-V#4a`!aJN<~4!5z3Aw7QBcz$o`yHSOU;@p7tdlG?;`&qq$I(?7MyZ04V#}N>tdj|3*;zexJi)?@;3|c%H zMc_23hR8@pS;xTX%i1tmF7nwu)gew6aX;sf^*`a<_@b8ZTU*=x|Gwx$m9<~svccE- z<3jE;IKDW1H67yHjrL1ybn_Dq`wd3?aYD-u|DN_I^3!wM5Z;lD`r2OAeZ-VNlc1(=g@K*G^tBU=``{o^N{{eJhD z7ry@d`7iIo@2`GYTD&s^NbB!qpycK+(J!?!MijqqhFQ?$atp}Zh&cPArcd+zc{#|OxKm6|( zzwp*r_+qGAFKsYN8%mJICii>%o#!L~62Ug)BFgC{H@R>zW?0Q96`J=p!mh?S@+~6#txUD3O+s!gv<_eO8SRJ5 zl3FL@(MuKO_1%v$ z#Vw!CIQSRw1uo#_bULqo>z$1IM}wnI`;;-BD4`1=6CQd%P8d(W;z-&HTp`bpPF=}M z%!0w@BzNbb0l=4}wn%|Fr{~7oLtKpo47pL@cYQyL>9NB1Fi#J5E^wgdbP&EkVa^j1 z8_K6G?H~&mZ@PLqK7YhRd7;p+)10l6cH!VY?LQeD4f_n-nXA#(^*iaU`kh|Y_N+wZ zz6O%^#vC5C05PTQpWz33i0uew!U_du(zV<`&f{%0r1;OfSSfAn>}>5InE2_&a&iG4 zCdp**W;m8JtsXQM+-LMhaSF@IBZ2a8V;lY%9Cd@~-+xKxnYiE~ZFv|R@`B;}NDqf_ z>{sxRzJQ5?P8<#fm`{i|H2buKic1!;%6qc8`($lzy#R02rV|8bT4^g{E0P#BgInL* zdE8t7er+d56d~H@6Wp;IM7iFdx!m$=h2TOy98YkDmuVN(CpQD>XM2xuDPl^ACjmcv z>;67A1fSaV+SvW!>E7D^$y;IHThn()c>Gop{CT619&u%n4AZXGkj*hhe$Kp-5F(Tu zKuKy$qGIa0+}$)~B7--Tm{VRs2x2xBvHM{jX#~Hf5DYJM_SHyHG^u~(43j%pL-b0j zEZ_gw>Focwdgs9>&u=ZQESF|DM zj0?}lr)Mw_abpf9m~00!NSF)KFXLX278gBRQyzKjC^zi_V=23T?>SS}U7WufPlo4~ ziB!LQ!7o&rlHg7;+5hsnglxB@;jb@gc)yJZiOIY6b6{-szn1$~iS;*^Rz9BeU-I&s zwEj1Gf2(QDgec_Rh9P=67;y(=;F08!GO`WaXjC|}HNmhjxNYo4vCK$Srfep2CVgiGNigh9D zyvI{`9nHPKb+6Babgn3fBH5N(SQ>Ti!(?RzdV&ebuKv+^)2A>x9<;y#%w0rrexZyI9AFgB}(yoNwN4v=U#^aO~6c@z$1SW-?8 zNy29ICB2&@{Wex%w`IDe-vYfxbRnJK9%`jdTE<8NcTJ>aJ%_O_(HA~Ui~oH07pZYa zjzTyg(h|y?}vzh5@+F(nB@yIlomSO zK|#rNd|MLUL?%yUf-ksjS*Z1FXS3D*blPqm!?D*QaCuw+&P5lzVcnMu6iH~O;%a&_ zJcQ8j;{JWPb$7YdP5RHdcLw5v4nk4*b>J|AM<}6bLQ$q%%TPjncjbhnj^bA-TVA46 zhfHVA1LGK19Cj~x$?pYsvX-!NJ-VIFgFoIpxVsW9qI$c<6c$r>F z{b+bH_zri)!)T`=RC^8Jj-S<=_Xg{~YHHi@qyjF?7{7?HY1uiWX6+gd9hE-~43;@c zr>0(#9o^gZ z5cfV`64CwY{QL}-7`HmQqUig#$CH;T&>ac8vjbcm<)1Afng%Y2!nP1j(_bR7tcPb{ z_Ri{&%03&+pe}=+1U1vKo$v4{XyUHSqB=vjiWwl&%V(ceOPNOK8t~(fl5b4#Z;!bl zkIf5GSgDopj1}^%&C;nP`MOwdOpFeJtgpNGGmDO#VWL6H?zf|LB8=opIW{k-yGAI* z*JL_4%3%EA26i~0%G9!w1rSBxh90^GYNm`{4UZ8JYr>dl1yeF9u9jBv0`;Mrqu28v zD-`QNlv*no41pXQ%`4qyrGMZ*X(?37(1-+Jl7QF+#VLLzwc}G>7Nm3cVw?#Fe-0yi z5Cz*#llu-AjXtvVmnR6qCB!+^sYn+jmQoUhw&l7}zkd{LXs3I%e~=-bKq2BSz4|CP zg0JAK4_e*FKrobmPro0v0ZVGBFp(mH=>)1y9TnQmE21zTFk0bsN-}Y5x*TCbaXjS~ zVf!6tlKm=Lp=d_nX@9bfj?+>NZH2j)KsPS4^@UZ+CJ?8LT~J*28LVB8U0g_5H8cfE zCcH`9bkRW<-QkU!kwok4W)Y-0-g#O?l^%<`A`?iXze$q-u~aE*hiG4Z^z? zS-647%|=J4|Qi7 z32BvVNce#L3=K(i6gYMyN8$^nM;VTtkX2vmo#1k#o;VqioeF#wC;XoQw&LMNAO+9l z8zar49eE|9`G?t~Tu$He_!t-^*h`yKhLSlYGmyl9suG=Oq=S&~8w)2gq{Jc7l3=ZT zCHcSCd#GGJ~77sAsnRKfcRk2jf^g#yE*amQiO zMwI@^)G)h>-{Q*BeQqX$YMi4Ym>Kkv)Pnrs!KgOZ6Yy&@*ggemRdVU=-78#W6;$bH zfDnP)3f>Nu;p_F_dQ8x6_<}mub|MA|s6r|#=Nt(Ytx@^uR(R=D0AXf3F`GO>5M`Nb zCiJLqq@?vzs=1FS)Po+}hAHgtqc;h)3aR-o=6|cVy1^wozlB#WGNO|XB>j(DPJOcf zG`Ae4he^(ISu2jee}-4CHt-8vnmFGu)8wznakgeD&w}ZcraBWoH_uiusnC7?MUxv6 zIJl&&mC{Zs{Zf&H(Xw@~7FE$)F&CBo70$;wR>>8|U+@+=xzxp1xNX7~cZGWBSV9=v zs{eL;^sa$0U?g!IigJzqy|)b3h4*35KkW&1-=6n0U|01dR`;d>@7rE7FP_9E@R8nT z_T9!F!%1Ha5c8xLt1YY@GR{aNjzceNynHw0q!Jat6#LcKKR`BOcxHMSLPZ6RTg6sA z9~z@8n%Jx4YXnNl+6bdgTf-hC7AU$QTF4qIet-+n#bH0l(c$Lg4HyBXtMO~~G!j|a z^DT>XaoHz#Ht)3MY)@Rod@zFU@JogpR0|X=JVYEgxT3T>Jsl$T4yn?YHQaifQk})x z8ki>TB#H-EV=W+{?&icTqVN+egVpEz5@GdRK|-`nYf;gil2Z}3Gr*!5E<1ZE$0w~n zSS500S)JYF>%qzK>S`_$p7h~P*c^Q?4C@euDkf?@#yNIJ7%%C8=U*(%pm`cXcZlv? zEPazj+`=6jhAzG7tDS?teztUHcsk{7n)VYvbSsc7A24O`v+e<|JQq{#x&loEtvGgN zEjvpb*Lj9h(b6D)a^gtZx;f&3E|a`LzT{GL{bF)*J<(a}lQb@lyvV`3>CEd#-rI+0 z4=MA8xbP?!NtFo7&cY$j6Y*HN`aZqVj6a+^D!p+!>ihCIPdF+PLO`Vg7s z*3rn;_MV=7qRRoL8Vh~DvG#Cd$CHFKm)qIcd$#j*Z)ff4?xT6if4{f4?XYE5ciOHS zD0aix)#wK9mt>kjkRQAq9I}7-$Z@z-A=KN{SCztgh~Gu8$g3wBz({r53DOr>nG~wX zw6u)U_wZyq#b&qk#pkott`VE{QnMZlF$_YW!GgpWOb$j%Ki~U>L1T+|RIIpO2!bVG zpR`Zq;_{_N0Qx*=&FJve1zrU+PN`b?4zZI9K&Pb3aDNUG+@qK0Gh+)gFEDJyn9Idf zmhv}Pvo4`T)Oz6HHqPN_cKS7@u$(Eg)E3qixP{QeV`zV~X-}z zR&W(GKkRQ@mv=rr&~8-ND=iX#S3$*f$R)ekl@?;nT1R`esjG3ku5ALN1vZbJ0iPX8 zp6Hrj0A!LmI|KJfZi+j~1-IzUMf)X!;7UNiY?4F~)6UXzYjhpV_zxYNh z?8iLxGNCaNth&WFgVE7=@^Hv#fTQ7r)1l-4_Ifyxz0vEj8{*!~i^aMmm!YRN#Etgu zyVK+G=-t6VaF!k%Y){6AP|61fvMkk-5s37Bs@3jb+03GCTd_EcZzl6V!nGn? z^)>+_caKj7^FSi+qo{z2@~pWpf4`XGrX5O+7vrDOV3#}7$)P~;u}opmw@W&c53Jm8 zGhl<0qXRL<9z)E{qz6h$cW~wDIdQzR%QqwmtFmXm1;%L`o|6$l*jJt!VvA)y^F_|R z0V2qJ^P^lu^7}gWL8msO7Nvb(dbE954}6XuB!w~7vQNS4x=#G>iy<=drP3fNZnIwk z8ccqc*g*XF%r--ga#9XT>*Ct_ldMX!_o6kYXD7Wx?7SRK89=0SG<3-OGoQ?1fJ{Lt z@P@>7g>_7Z2t<&fYGPf52S&7(k`!ba+7}}P@BUhdqcP}>8fj?*hwqolNZ9F&4E76f z(jgDD4+hE9hCX^$Ser?yLJ>(=NHrbshxHrjsu|py_Q? z??e>y=4GBdxts`64&608Xm{!yL*1;e(9SYh@IEP_eRX;SrqBeNK~;rmo;hS{$M_>? z!~`xyJCr&siF5zAdpbUR-PMpPWMN7G zg98G(TiaFvC@T~(!ir^cggdN{2Hac)AX`rdl%?M~_dA1j)GpI@DK*#>3m8AFKR1;rDAiPKxoFd3V0Bi=P%a__4|yd(G$q9T zU3eM9Pm+Zd>PMXwh%02B=e(zkQ%&PjtTQtUqM4iq5Oook2C7~LF`31kqPu~_Ghx)x zduD|O;?Jy8KN7Q~7*i zm#jGlV&f25E0BQ&;{)44GFa%CK#mg>QiHT*S>e3y<#Dkyj<=N1D^F(qK@P|Ct}c*RFz7`=Dkd zo@FK}!bGxXGLnr!{(%!Ve=PnEooUQ_y&47Z7^by{8DVZ(0 zmcTIMkX|9U%{-L{P&02@8EycW4Hi~zC&*0u~3 zC~_(#Qx;oER4F>H(SsmcvdmTz1O3GCA?>}FzDln}pPzDKY9W|k{Uiqs|u5GSy# zk*+rs`}cd6^nz1yo;iHmJ%$N|Mj z-j8IG5Ud3HlNf)pLq>kAZ@$4OA6C;ix$1Vpc8~=8sh5lkTLf2U+>TG1EjN5y_Iqnf zlil>`!PuioXLUW=Qd`YEc2-ndkDY(qY{mo&Kj{Nj&t)fywfR5rytUvcmVP#Ma7E3DXg`6vc_c56a^uBrZugSMQk7ULjGQ(U`pw9e?amf$cB}OND)M^8O&vyzYWNl`@1eoc?1L3`Q&>CH;9d3dZXmQq)^Vhs>$VgG~`-yWZ}0 zf_9|CrgSsPG(3mlXK-_uo6==(IwA7e^QFDc%uIdOY9lfj z4<%BcgcJv~ujl=eoTzlyJ1^DDjgpk=^52^p3h;=(x$9O{7c)R zI|d9M53yPF^yZpe6wardkMXYnk?a1)@8SBX9el?*G0)esh_c^_sI34 zxoH{53PtJ=T5Oz8AEHU+VXi??9azlWoG&jlK$}#QA4&N%FV?IgIIWvHv@QWS$^sh_ zZ3CL<1KJ#LF2|-#zdk;;vEbO30a)gK*GxWbKoFZ!(TV`lg?w z?nL9T`B`L}GcyM=XYF^27W;DkN$NG+I=mvKi+iM2k9;wg;5}%NrZ@JP8D$0+8pJ3f zk5!Q@1_7i}U;q>i-*?x96=nG~29F{4@ zABnsuZKV1wS)B8G=^Bm|HkH}zx#y)k>Roeoq0^x0V)bc!0YVuMPG=p=YE-^7s5>KjG>da+5lp?_w@V}Zygs-F<)mZ$HtEo>f zlXThiGU|lB36iKI45=k?)Axj(v;aClXxHKmOrQv>l|f61P(>JaL8l!p<}3^vz(PE& oHSrqo&=nuFWvA@J1X*npLom*7*;*zM7jI9YbwYStkdV27xg*&hIf6f00dSGOkX}y+z)xWz zzj1Ul&@{1j)HX9UH#E_;1iuneU%!Cq*j^eMS6UjHg)}rYv@}fM-(T$D2O2i;e=>Yz z0)kSsG^#tgtW4EtXdXxXIB^Xb3;xFi{!jj=F1~m-8COrDe<}D6$bfy|YY<~e3mhOm zeSoZvuZunok0Utw`x1z<*tZDhC;&$wtQcr$er6A=LWpI5gfOr+H91k;CUb7^@ zVKb+U4fDXccoF?Wym82A0#GVKY7R#GrLQ^%M^hvv1|q{20DB?Bvgv4Oj%}$u4~Own zn5zzOEo2<)0@65PFmAu5m;6O^=v%%Nj(=CLE!@DB1kpLfY18Ly!(s^g1;b;L08nW^YAh=BF_KX;5 zq#q*<&2fR^2so0GZmj}*e4Gd&2&w!c($E)R$|v+HpTnV)OllQ~$L#VL&><5Jol8S= zsKrVRjs>$Jk14Wnv24T;r%`F?y`EG!PE83f$I4ufYRH&&ILlR|7U1xUsqppU9h6aKLFCck=~aOc>}e` zt~gD+lXnQwlPGHx;N$F#b2Y@f5O9bn)3u(7GI0VmsXMcNflOBafyo9RK*YJ~1>jx$ z!D2CYA^^XfL1#y%GMd_=5J=)%N)|2tjw0Sc4S z>qd~$h+0ZAUF!Py`G){-|0zw9vxtxh_E_}hGRR{6A6WE!2`0Y2epVj70p6}!xJ@3O z-ngk>pg{pyi$_pCC1AJL`v>+yKB^T-CKbxJ$B-}6ozF@Y!_5T|m9_NB15<%|J^8}QpzOJ5b zp3|2?5Go%iOlj-}OSK{2e_9GeoHw8|3&ar!o~|HznBx3Bd|k=aS%uO`0=lBjDFjHT zMV-g!0jD6!YK8dY%m}VHf~gb1iyWN+pd!jEK)k-S^b|zb{ugvzyemSp0T+ZUGIIC~ z0E55>fv+y}zT`r9-Twmb`x}C6lpqv*y_%>S2nnbR+a&Fff&)^Plh54>Rr~^=qM$_C zbr4$PU*-<-7Y?WgSe8hRor6w05_~O8|KJ9(|7qF?wh0dJ?(abk-H1XbfUlvlk3}G~ zKKPkzA0!LM%*g5_jhOfb;Rr5HNSFqO#m^`ll2Hmz@YN<-O&U_@{0oH{2**g7VvZvq z9B?{F(3*p4z6aomJgdNhmcc*b8zNcE&B+D#8;+$Y2U4VT86UU?WuP)jfmrC{`b|kfiu=6N;NSR{{<#+)& z(lW%c&7(Q^nHq;i>kLp812b8B`ryog*J*`V;z0KT2O1pYT1!T)#0xm}J~s2m%2)UoV=wkl;Qqvvm{X+xV}tnfc-H02|V35rDf!=LQ%lTB(ei5#iRyr;W|6W-F(-^Igonre$tVmUypGw&<56Edcb7$io5 zC$hB(aq;#AOV85QVTk;Onlz=J0Kk41Mq>alfjegqt{SI2fn)AGk4P!QtR4*??24o4X{dn(g9 zq9~ZCz=na~kLYNI5Ns$#381)mX2AfYpt4v)C_vh9_H=c{;h{HAli@8&@CpzJ+H++? z0xIhUgkY*L0a*xhDDv3mgjyJBXdF!6*9-BfT>I1Tjd3ACzJzI&_)~QHbpYOa(Vidw z0UqR1q@HrYx#|)Kpq)%Ud+49@01bE0rG5xcWjh9$y_Kf9p$*Z=eOlm!ZJrS@?fIRy zSOED4tx@`qbscEHKR`hN%o=b@hKAbi|ZlD-*@=GBLOk-_iY+Tr_4;U|4KU0z|dKF7SjDa z>;8f6w_O^@7|udsJP#NR`rcu^uD`qX?-+m6IfO(Z=xNhMV6G>--}XV#{+lK#c7q_D zA*x9^AXi^{*wO!$4vR?Bn?aE71`|n*lc0(pAHZ#%ey2uCZBfW(0L~1MFp&e! zreqGj!w!l5BO8Uz6J)F8Cb1m^`^bBE?%Pndzvog+HmoBK&Lq(O_|$(x*72kQ3H}JM zSbNk0P6+?^p7?BdQo|iid=xcGCooEQUvVTvUPpa|z$QM`Z->A^C~!3ZP9pgILvf5v znaZv-WaL6^pb2bH^;sNa)TCAv^oVBKQ3?e2Mb8`qz*?zd7LS2?`ujNwD$ext9|-#r z)zTB7rGz4@GzhEuZ*xWuXdvo+6!jHAeZO#9JVd2h6Qs7*^fo92FF~V*Ezrcr57)5b zU5nZ&lfY+mK_U8Abn5wF>ZdC$D&W+0{u?^h1cmsGDE?`Hf2{YCA;hP8C6Q)N)&qse zOXri;C<8z?+iZ6nBLBTfiFybLnY;xGp?T0W&JXf}tw;Dq2>p+fChLGgiuH;x&W>a0xG9fX_8SzSru)O3(oKaN%#E5Q0XEMe;h zCHgOPvuJ)bKcRFct4PwV0?V5BmX9T*qq;;SlWtb;6Ove?POtzt!JdwhJ&=TYD^YBH zLW)RqVOs-=h1VWpovgpNMxY~L-AGEEPe@h2h@>)k;Cpm2mb_3J>Mev(!HqvcIkWKz z=`MkLEmIpF;D^~)lkPw|8>&|jMu)a~AnT02CnU^76X_)&U%yf=R_|{4{~?^!_Jq7o z(2c}#;Q7biYdwI18d1v&+mXNRdO{Wxl!XI?JVs|c)*7NZe?gXMO;3ov9jz1aKnA1k z!5Sz7)yA6L75shA6B6nPk-S3|c!&SfqwgRg)qejQ!Wk`3NVSQTMD-fT_V@$GT1fRj z$Tq80GS%^fguSREY5+&Xb@>!R!oT-Q&^3*8dH&e&giMWS8rchCJcE(bT*yRq@}6Rv z*6)PSBPjGm06l!kUJOF(QtQJ_tXZJcGydk>ck^7Xw42$1Gc&b-C zVgU>uwmKntGP-H61?Uef7t#DD^jV!wh`t8RoF9SrIPUW@f#_84JCM2mYIH(a6GqZf z#siDabJWFd%>9$bXDwc=hA~AW1p(+}^L%Z^;l5r zIn;DHAsIL7ru4u~InLd{`XwgRl94q9VIerx@ZM342uE@j%~QYt~yp4$66eq9`cG41y>nlEOKG z`-F6<&VvM$4N8%K)Lff^PlsmXM4+UBCT+}NDDM?w!U-y`dR$4S6-VdNOt7hI8nOKLv~uL|HpYhK-l@Ra*H zGvUpgx8q#E;|-cbBDe)(?cw=LD|)C_-T-hZYX)o$P%b1Xfol_R;9z!>r>i^8-#Ww( zhiq<~om{*yIfjHuo~jJ8PzhgLGL(aQBSSghq6T-}NPHMaJgO^WAP)Vx0e#3p{c=Mx zr{;F2;0@qu2jupI6TuTa5P%VsqB-sx@YHSI+?c0QzuXW4-9RUAk}!JURNj{mg5i&% zb;VV%PucS{3A_7By|EE|eVo4~csvQ*&(Lx5cf!E$pvz1HfJX;#+d%D5t{G<<8v(b( zf$PH9;q^u*?|@&vYKm4E?m+(=w`=i02FgX(Oa@p382NgFJ2_Lwp4j{!qPu;h!|A9e zEeFw8{ykumWtSVEs6tYd2rXzfCa_}nrYW1yTvyX_`a=U#xAJswF5ci;1#(A)`~;Q} z#eWNC)oekJRVUgMXGwv57gR1j;J@Ej-e9{0;hDUXpTL zfr?iy_SgkgOxZ<#k3J*Nlg*z8Z9YB&^Itan8V4DuQvWaYz{~1W=Md!TF9K#o%zG24 z8!s;q1o0_vAIT+{dHMi?G4hy-6^NTo$SrwtriVaB2$MQs-0tUC1)0pLGW1NQsjeN; ztOb;$+uY<_i@}mbxI6%trd$kQ(g)VA-KvOkWdKILhTn7D#hC<|sLXA8GNCuc}K0p$EDjW(* zK$Ha$+0#`A=jH_N+LEF(nNfD4a!dk9(dwENkb?4V=9e6^dqz`KQ-Nx#gG0uXkMbA- zQ5N0h)`dKj>x#efKnZ73iJ=}438;L%`?LNZs5XME?*yLonMuWrQXyWjAgB&&yHPG- zen~~PJ)7D%X_NX!Q{7nd<*12jjuCLwzPVEg#nGa|31)K4zJGEFMMo~vp1Whs57DVv zE@bGW;srF8r=IwoP4k*8G}2lg;ea&Se->gY)Bn2TGAql%k~oZu6k3MCf?@Y-xenp~ zq9X|ZD~n7^vJgF%lY}k}wmcG6X3h{@le)?OLMP9$5Ih;(AR}$no#xSw5M1}4!Dpmc zNT3W-0upvVgF4|1aSPV>qEhw0W~d6PVE0gdnRg6QQQjJo%k;bS3X#Lm z-E%u|)N_FW*unN+(grF7*&!P?d$KGDNp_-pl5-%DXS5&XgVX;@qJ<=XNrI5&2hav$ zk8QxO_KOx_9nZhSK8h^lIS_Ju0S!)s;{@21eo$rwv6i!1_KfRJLth1JdClo1Tf zwXI~yAfnOOnE@cSbM&yoN$609u(Fh+ev2Cmf|@((Swzse~4RTxZr3RJkLt@m<#C_Q^hA_ID+<(`G9kz z(pheWiur?EAq-?b@eFm$D?r7i_YDaU;g3GCntGq8L4D#FFkMbl;t`1dhlOipIRhWP zWFA7E8^|^lM^F(?01BK+Z#1N!d=w4b4pN{S`CpH_!^#8x204@g+hcNf)J5Hq4iHu- z`1nG?Khz+9Ak_6H;tbs=$Ofs#!4e%@u%!Ecqp}J@9xkIm)r6LCG(fsw!87wAmByc< z1FA;S8klj7kIY180S2s^)TdgGK!QI;y46%i zx=gUF5j%K*xFM>z2Wz(fF(S=^|J{0o5ebiWs;>Zph^g#Ng#u8140LKS!ca~1a)f+W z(Cd)xfUhHU3D!6KLrH}go+97u)d-oQnMk@j10ve^vq~&d{#T~iixDzi6d*C-K;9^m zEyu39{GqEyCev@%B7|;1E6^sOF1p4S*sH$&P_C0f!=(sI&gp$I$gvP@MehKLayH1L zgDwDkkHUi{nG9sh5c`&VF+!FGv?v$_QXJ`! zEQc)ANr6GnTI>*?8!b2A0V%d*l(s_rKc?>0m3><{^ZG@HC|{=dm|(rCP!0HzC-_|>qXtON=ar-sG`dp4c2*Z+pb3fvVi#rZhn2)}*) zT@{Voy8%a_%qOgaL!BtU`YXSl`1o}{mrP@(z#WkY&JAcXXs%j zM)?BI-w6Lewi&gTIUp0e=(8M3XGJke{gDiFLJG1iLzRitjC0P2VXuFqd@4jn2aQFP zh2LSXC&MlZllcfe%Jm+IvZpOn4~q7WT$o6Z^mj{30Ok4uxL$r3xD2_ps8Qq8W*m8) z3V0_0a{pk~1GxSuIz7-@^X6|${|y~|JXY7m!xsl0M<$&blj*4!pdxFj9n4k6>-8u^ z*QRFfWE=jeS9{FfCbXgO9RTiU--Bxq-sB(Qq59Da+p~@a;I>;D@YRNSV@jgR++<>y zIN{v`z!T752Sl9O{rn~&tVRv;9mvpjKVl)2iE^Kp%#F#ork@o2h6rhMAhvl6h%|!I zx*!o%;gpPM%EjO{&Dl26KxyUz-8t76Vo#1!l^Musa6XTT0)DJ3wC~OaY z(nC=w7u_VCp*89sGBvCv4x>fzXF3`h3;Y~x2mCij{tW|p_=50hQ6yWO0VRvBvXe3t z;BQp`EV9v8DpKsfB=eK-Z!myP^`qdE5MT2z3*~qCNcD>pUsL}LxrW7!mhH&9&U8(6 zG9kF`zky=`7jAwqf^TS{I2S1YC08014bW-k{Yw=CZLka#BM69L#3YH`qWxR3H$z9i zD`Fr;BWi~2piOxDhx#|DDXo9g)Qr<#i2egD^}K+Z^a4kpLv(5dpyJ_kF)(o?W+1OX zT)b@vD_E#p2I##P(Cm@b^7eJ{g7;vc1ao9b@Ed?B?!Q`t9Yg#({FKdS!mFT*SQ`{3 zZ2I|gp@RMv#-W9O)pqC^GTBm|$t8@Qlp=4x-F9%}Jjg|P3pL$me{ub;T!jkbK~GGp z0ZV(Rx)x;lTX3B%(bU@pw4FfnYNjNo=aY=G0<4P-qbk__O=_L?mn2B!n29cg?!+5_ zXRZ1vUH~PayyvH+Cz!-h2CUwOx>8$8lH(a*YAEf+@*R~)0)<6>-qUoM+dNv{(-)BPEDb+>)H`A>d*^T2H!pf;X&#%eK>QP9g1lOe`sO64!H3dVH|| ztO&)THrvhSnyN6-N*|i41Z}Oh0G5#pb1fkYwLUnTW!i>snndPk3se%gg^$n=tQW0D zWvPa6k?&TZ3{h+(P1yk%K5A^oPU|%O4L5)QE*hd{!L0BVt&?v7=V}fe!mcs?gMQ!* z|EX&)Q|}7}&vN{t`t|$*5k1R79*($CQHR|#q_*+^`oRkR8E%HjS;BG z_Wmy%QxB#55(MKogf7TbAO}-{N(s$u=~H_Q<}dO zia!bPg@3qOL43+58M9V7_NeHL2Y2r9kX%(Cg#5U;ylMzd`C-Ue(4;#Wq?`J11yrN= z&^^G)YM8Lc+VcNkRV>6((uyqVIpV-`jF*icg;W2B)obbr9@;^wB&6j4=l&X9VMrg< zKvNE@A^!mv32d$iY5;h{9>mQ>i=dAHmvz6^O*mihj2VRkomr|jLxLrE-6(`~M1!Rv zPyvo_{&xuZ4}r#NX3GU)E1-)8d96zsuPztFrhE-$)^w+yd|XL{>mc}i%BlW z4>G^Tw$5`9n950$9uzZj3Usn^A$a=vgZuIRm_l}-wo?ZR5gsw7h1kl}=@`W(eV_zX zgbS*O8$c16C;CrAOe$9&=^zpLS2x%nheuxbhfS9To$hr2?a{`d1EKY(n=aWEMtEBo z9zwy%>jBB94myDI9e?n3Gi0!(l3~{UMY4hiYnsnU;XkxVoT@-Nd1>Dzkkj!0ffG}m z4G36>U_u}!X7|h1LJ}&AEV#Y<(^&x2A@cE02vq>ElH3pzcCm@d^zn;I-`m&O$s7KR ziNcJg*);%P>$oMhApThtEM!6o?5F{XqJ~mQ0xG^$^R_{)QCSE>T%s&?WfuO5%r7v( z+R(E53CIHR>wjSPL5-+$1Q121f-~8>iqV(&BJW?tSZvVj_!M|TdmRqTj#R2|Hp^7& z4azlDqhjhqJ>fV|-`_njSB8*r%@@1keu!akgnF~s|BR`+Y!N(T8OeUpXMa} zOgg^4Q2XOlk}mMaRG{x zJow?QI;0@%i<{o~SdM=2P)Uy%TdJs2?b=KsmS3dGs zJBHVZPLlwp8GQN+R`~yeF|i#XrfUrS1?rJ3U{!^TG`)gKrn2-$lt3zV;E6HRE(Z$y z157(!-g6lQrg95}02_eM%y9K}!R88Y~?7pG^IT={ySE$?gN1=|1{-E5xSKKOpwh2TdVw z^2UHO&^&$@09&oRhfSJFjgWw6UW9?pcNv|vJy7>zsZ^|AU_hOxpf_JYzC+#$4?dD; z>eU1@wmw%-j>kZN&Xl?os2M856XekG4FLAE2=MjCO)m@HqT%l-2!B7uTs$B?wF>&} zT^^_)dbFW}yoOfVvwIT+r!uIJ-Qys?$^+4z(NbeAP)&yB8tirjl_xah=rgW2!^7zKw^$o!SzMTFOdjyHf7AYAMT(gv$;u7c+RqH@NwrY{+g*yB1T%brpK1hdjKWSRK z+7Qj)Jb-IY(}e=arAM6u|3uK$QUTzf`UeZeP2=FY^&u& zuuct?B|ACQ^x}4=OlR5A)C-7w_AKXzGEup|AtU+~4QH%+Z}bv!IarlVbGAu93Mz{q zG78cz3fAc}MLCQ{mrSsP1Z{G#`v(8+0F)SRN|BV61stGh&G^4=JIEw~7ko^doWTbe z%~05GbkB+Oz3#t${SYdQ%1}&3GZpfuEl=oRrf8_l0!Aq}7!QUVM*qB8rZ`|JGeeSk zR1)N)6V9vUH$#?x_b!T!SW(pK$jzv+t6DLT;@`c?DgbN?-Mj;Q1Bg>9Bu)!2&MQc^ zzXfdnS-cu+bAf33$4ZLqF}Mgc#_I#SPAqc64s$3MW1De!SJG8_QtuV1VWvJEBXs&_ zUh;zS4%uIffXQS(&{T#>pxl)Ig-q(eqE0g7b~gMl-wuGwrNYt%aVbZBEl6)dM{p9+}1hPd_HdUkHII?^(!! zXK4q*#-YZH2lEya48ab~DJN`lSZb65nM6>}%LAU5Sk!?%iXukQ^QM@{94`v24Meve zfNnqGBCy0ILlHsK8QjhV?*}snAEF38G!834j~pf;S%NoH?szPX9eaSlNMRK~q^U50 z;dr2hfdxp`55wz(piyN1iUa)zgW7@KIPscCLz91E?n(#+&i*M(33Qiy3E;!Lpme&y zE;v7=UPZ2Qx}my?1-jC)aL2U0YzCaQuNSC9z&f02iy^NDLPk%bB|-(T6%oHy9Zm)` z#->e%e6*DnGLlV~q}gGx?KxyKjMc_VDUURo8n~*JG%!I3R3*F4?WKYe?2Qo0?bW1_ zCj8*V)Zebs!;#?Jf7)cVO$?Dgzj2!M=j}k@QfA8@!9NG4oc8C_)X9yi6M5E<=0YeF z90YFdO&f%)GlV4lG3}JAwt)B@HFiV={ypfG&-nXb903_1uSl9z1jqvx8{&7u0ifuZ zHh}aQ@W_ZkbQ`rDtlW=bSy;DWrW~XZpx8tP4Xq;4M1zcWjLjT-QfubCFt-!}^Fh|! zIABR|QIDlGuPIL;A`}Jwq!DvLYF;pwHwTUYj5Oe5;*pOflkpGs{{i9{0*q|D4>cQO zH>^JF@(OCxD|i+3lj+crKn)d6(VcP0Hv)SOEUV}Ju=3i`ERmp%fx$u?ajV1_8EB-v z;=X^mtY0BWvqB}0nAj)6&FCKx5EKwl{%vHpR9+%mpuqaDV`?T_e~yffr>DKSaIkxL zbza>0uteEd)x06Y)sfl-%a*Geb@tgT@QH7%_H{HV5UW_3(?%!wM7G|0Sf=!Te09yC({4F$ zZsxvn8n!vZ}d2>)R@NY=-wl}lEO0xTNlX?y=IbMNJ!ToS`@4Mu2WfM=Pp~}k)yj!bo`Rha8ea;)VzJE}7GqQrQ zT0~GmFr}ydNnf4ZZk|^>gB)Llf+KD{DBMnW@IdWgOfoS;yZ+QXwt-%67AuQ~_q|p3 zUzEIBsJYRm^@C8r=Bz4_lY{5&?ac($R>;KPaZP9*RsIQ#kXJYUsY=9gnS;jb^P79^ z>pDBP5|SIXkB{7&7egdEoK&h?R$=(Ge(z_RjGM-nGei#-7|PT)&tVVw`l@ezQrQZ( z5J8c%yY3#-x*b&6H`laZHj-WA)?7XJ>oxBj=|mZJ%}ZlFax{El6b+u8@A=n|fMnC* z6?&fs*X>Y^D-V`^R3YG2p=h@Lq`C<2)#}h>v)KAMDGu#oMO&I&h^G_`e|he}n13idM7jOEO#)0tkB}JVXqMrF6Br@$H4Is7lhj?Oyj?_1uJA_x$sR7So)5!Y|sYdt=Y(uIsfIB{Kcvo69&p$!L2= zoML4>5`HjTB*OGmqfE2B-Jn7KXC~kcTml4<5g8bnmRsZ z{_Ao9QR!C-zg)j=I7xec??WTo_0B_Q^YS(oo{wn$YZPnrS(L#^lq2SNEY@#Pq!d3G})$A?OwmYkDsr<%G@hH5g6Aaa;Der zl)A-;0(axB>wP!YGs>0EQ(rH{t=mqg&KAE$sH^VM*#Itwqt$CB?(+;5GR-fW!?aNS zLsNyuU5#rm1x}|4l!qq27wv!j=%dG%o>vxMpT2ujoX+rEoTnz&1Aj(L<$=f6N3w-s z^IcnA8KwLb?YFwW%kT@m_OtiV(4*E0cE+eh8Z`F~d}A+7;^w-lpSAIgQ*l~kt8{uK zpXU3BuopZFJtCxd0-uVF&WX`EcI*^S+`eUtEPjYKGX?8*u6ik5R;*mAw{hcKzG(U@ z$BrspEf$X$6S1eg!!6IReB{3CzE?@^buE^Gneoe$Pxh|u$$7B6E5=qKK(0YlTwQrz z3r)BppI!M&*Aner+i1iBcI*>p(kQFNEgDEkmlN5h#>A+@+9~o~CWj#K)>cq``{fo# zMmdF4XQMMberoSUrCRa(c;@ZfGu-{M>2#96&B|NznHO~~roB;l*F8W^TS}~OPN-w9 zTcO`G@ri=mCGVvpG<4bGbHapeLu9QvYlXB<4y@YWGP%c{*=)&reO?94>joKR4jvLt zKg6F+^ehz&(xeOdxYx3BqxagOi8Cd6r=t7US-9Se?H0NDR!HoyO1WaxQn?28PZ>Ei zrWusx`ssx}RX_y5Iwswe)0_)@f6|?9;Z=7P_^39M`?%mesu~e6b~*o;mV! z6wMqJ=Fa$n%0dknF{cdcgFQjV*{*Qo?j$2k!z!6jv8>&jBk61N{at%o zt+gc2-DY)nZ`ms|bw^hB|pjU3jRPn;U{YMcwgGj~7p)H*!*#dA54x}3;J)Uz;Gh<%&dSM5bd3`tgwla?3w{l4=jJZtIE6*(ylPG`Td$nKJ zZjWEZ+levJ`EI6-K^CWOX|-A8mGos>j)f(%jh~hsG5Hd9jp^{|yiB9mtfqGX zB9e($Sj`o(H?FwsddtY9>T^s?%!0#Q~mo%q^Q$)H>^R7>{V{9X|^Gx@3S1*f?+ZhxrBL@dXDGmKQ`E7&5(5Xq0sK#Hc|USNUDh(L(1Vl>yg0 zY`a(V-8j~@ZyVFfMndyv8iVtRHpCl0zUXu@xxetaF(=>axMKPdO>ufAr`xZG1=zWg zRGOB*?I~WXR9o`un;7qh0z<2^#vSDkH{4R;A0BvWdc&l^c*{D4szVaByKy#OZqGS) zI5qdxL?rRnoVdNbL)TnSNqz`s@9Dp9pdet@lklu;i*I+iLxUlwoxS?~1FgmfZ?;c< zd#U~{?}I+WH@QBSqf)m%8>H+S+B@d5*XO(EQ3c5nu8#uQuHSf@T1$o|6ndok0 z^KRO%6sWy^QQm-_v>%tDf7Lq9sc%i01{ii_y}XukcP;x}@70e4(~g`Gy!HI&n{n^3 zV8ZZ#Ygp*G&yrP*^=u`Fm6nQ~x!f@n^i5oLuqAJMYiZliot(bt3$jPImMN?83WiOb zbw9JUFvEl6y}!G-iY~pG2lM_Ax~SKN3};mft`UweZ_L?vkUr;y+fG+zk4=uvkKTNK<{` zjer5cwv2W0%^iLt-ZE>pHSbhD?jroapyKP|b^X4bS@u;u6OZb;?zHB_@22%E?^JJ% zR*w!ev(Mx-o$R+t<>ee*+}J_uk$ru|-l6fDM?+n~WeQ9Y{0mpBX}&Khie}&&jgWGA ze6`;FYi`>7#z(sQRo6%@lvN#5E)a@%p<-`ZcdLWv)CF!Dv6Dwc&4agcv|1!uISm&M zwOS{{zb9y2~xrMXs7uPa$MuRmTq;j)1Errm=nc7{Q2@kduxye7y! z(&=Cu|8aivkD4tN*Ncw4)>cl#cL{0sGF*#3-5|@Uxr*scUB>h6ubwM6@F_mhecBe` z>=ASQ-MgAE76;V#D7J4}_;Kf+if&(JpEqzam&R1jd~{Ywwr3KyIjKHWBN9|zTmuAddSDDBYU)4RKvfR$r*`m zexaGL+lwyh61&0XjPp|ZTbCc&%f8O{(k3V4+d8uD=|>mPoDt3(G`=?$miF4-H$F=L z>4}`))$>HRYLC)xTWp$d+dH;MKhsHf&PE@hL-Lw^s$V*_qDsPFVB}hdt6kE1f=x(gM=)Ty+U8RY= z-b?1km}dwrz8eua-(H5$xIn1_`_&udeL-Ud!J5rPW)P zd-FoV4O)V~ioL=F!;(S8OZMIB&%Qn(QCk zCsKk899C{-x$uFh+B0!ASN+LV=AFU>u8fd_$%2{A2R~e5UZZL{c0qN{_2p_W9K(rW zYSo3s#&q^6J&o_UmBVZH=q-198oM=Q%@y{S%ja2YFg?+3J9s@==gXbuqhIZ%TD(eB zHaT2d)p>2h0-8IM4HJZQw3D0xMgtn&`@e~4t*9)~&c75iKia{iQQ!enQ8~}?j=GP6 zVRzaNKVL2XLM$gmBTIk28FABhk>~VlLWYjt>3%SJIp%|9Xr_K0vvg$OZWbZ!7XN|f zeG3oBhHo{huS#|pQ&sIl9xl2-A^o2C4hSzmHzHur1XU`a2p^VDWOXt=wmAcw{D zvCN$I!g247D$C@Zh(pQupWK=BjO!(?2`&HT(z90K+`)+X_c-RK=ZA{5Wh|T97PKOl z?y6YMrSpfaQka9>_axG?nBcTsCZjD`R*Acsd4J8&h|gS5cDa)CX5yyaf4st)H))X;>)OXdyq(w7_B=euqU<0;yzty8p-Uw^TO(HP4TRBtMpp;KE8a9 zW#=K^BlL=^e?C1V`{@Zs&vKtNO*)Zcb0-=K`QFM4oLhdk?A#K!+U#`NnmG|tn`=H= z$8(T#bnSmpe(`|d;kd(}G*;|={#?+$uCT{q_=%Ze z*x56pM_u-ce!kkDy?|7itkW6*f6*{cF_pGS1)hN z0e$beZJ8%N3@uPzmHI;d!{NumsRK<~RtpZDXVsiAI8}iw<`+6Wcx&l7m(zQ8sB);U zuM})9x%cUCr@`K@Ct`0o#|r;QS3KYRZoSaLll5G+i4(~I+;-yiO9S7$aaK@2X)Kf7 zq-Jm`#JO_!Kc zwMj~;b#>IH{g#yS?4I?FmdC|fDR=K#$;HWLSL)dNoLFu{jEIYQxtHb&%j(NZj0~Rp zHm|R~pvy?Rbke>^z2*C9-qnoa4Yc?62<&yO^0g~)+~v?&mf*B(CqwSY)37Lgy~d^E zQmp}B1bwnU)9A`4a~j;0Q?T*)H`I_a2{Lr*CVoBE85f+-bX~bmRSJ zS3XK8C^s)js%6eFG8&uv=_|4LdD;?_*sh$Sn}Qov9vG!*8WwHMDH<<#eRex|v*PB8 ztAY)MZ1*O*W7lk~HI}dESu&5Y%&8GC@0o<3nb7%F#=>x!HHU z?_aTc4;OoasNM?Wy7T$hONv{nHYa|5rE0%L__BR_pJHUDwf{h#$+mrE2c8;~80Dqb zzw3>%J$!!C-k+a7v)FC&JO3o>fZ6(xn@6l!3cH;Ij(udQ*tz9mL?EkgT&3@Y(5CvO z2b{jVb@XIBzUHp?L-&J6YP@z2guXt@y6#AYLCnQ$ftW)6?)bURT*5~$$7JUH*#B}U z-ot8xURU_qi{q;nm|tjFsIcVJv0DeVw|glvDR_y7_1GI+>r6V3(bfG!A!en)^(PYU zEG#UnB|Zg8#j;u{ON6Dmo4V5YvKT|#>7O<&ks%(#b7xCzwEb55QMgr(^>B1uW=Dr@ zBA;Pdmqy@lg_d}vg1h3;l0KF5J^sesit6JdXV!*9R#asiZ=5fcuuzS+#-o(Z-*|-= zS5qNfp_kiDk-0{VQmRHT&vKp7SGe|ln+fB1)Ir@>_n(Q}VLrE6Gw(s1LQU9dvwV-+ z?*o&zwdqjv9}&|iv7&_`{T>Adv~^&CD*Ic z_m6Kj`K%sU`Y>OuW{&)=Ev5?3wCWS@M{SYPZ5WZ79mKcZZBQR}rx$(t|_yrP1ey%l4&<=t){^+oS9 z*4=FqTi9$scY%q<>A=?wUfZQN{wyv|xl`(!qOJ9Ct83&{f1_%i&Ea!WKV$A*S zqv1J6AE+5F+NJ#-cZ*Z?%`#OH?=?GUMB;5aZinETWoj?wG`BaM;ZO`3+_cGoRUu^0 zWYU~NpWVBUecDvd%VgGk#GCE&ekC(I_ZP;GKYZ}dQc9t9J@GNbY{iD>qZM}-=mhGo z%TPHea{i#M7QLToRp&jmPoA<$W2(gOMS8L;)9Lj*$C;{a?RA8ns8~j)Eoag**BPm^ z*)Jw7b5OG6tusf4LAX7;=f>xcpno;LhjmJJy9rJBgm# zQL}1io*R~^c#wqF)* zRrJcs^=`NQ@yN9Ki=uTK*Tn$ZTUSR77Zlgr=aG$$?jdd!afiGOuM$2K`G~At_=4)58+#S6{mEwTHdQUkB&yxUR%QOS!ZAV z**vun!qwe@pBjfYMZ3S=yIWwXx{~6ra$m%Yk{>2s!#Rc8Rvp*^f8}016kZ1p6ZKtHp&l5Z~J1^OqUs4&~>2mPs_l#St zDJCLkX$=#Ow&HH^za6vZe5KiZYEUh~)YF{7waCY=ad9FGvyh1RCdDOUZD$yx#+@@u zGerhYd8%q`(vV!59V4X49xjr0;6|;JW8A%!9(8)%9t(6PJ9v`}o3eyQ<-e`TIgy|5 zmVYscOIske{qaSK#XYT;qci=3Y#wtyB^U%w_>UML5D_@Krf}s6#VfdHHaC`l8B2 zx(GQxx15KYxe93eHVp;LDUtUXHeyR#xaf9(@D>htCGAqb>h7HB^-M;?YllHxi^4&G<1Kk zS@m{&(|pSq#^_2_Wmi+zeW~`*c_}pKf^UhqsI2P!5~ADhPGn~C<8tz3-+AP~A}9A6 z7WvL(gUwH>V<(~vx^r^8_=FFwrwyzAL3?O!$Ho2U_R=hgMf=eBo6{d<`3-`^D{7a17alWY$S%IV{%kR8IXlgjgac1FmCP&x zoMXqlba?ZnZrqS@*E=n-_Bm&W$^0~QQMw}iEVaR&F^DDarlgGkmb{t~sIGR+MT`$$Wo9EZSZp?Vf z_xx~5-~r#%?L4|xtTkd^wS9%uMGJP_do`~(y&zP-MP!%ud5fr;v@BJ}TQXjm5uEvV zZad#Q8$utkzBO{STvPA$IeM;R!RO+ueHQyR>jv3WSu|cd(pMNkGqBR$XX%BIocJYd zxaf;NmVYg1m-pOO!n>R;b72F{+QZgTp`NkhdXX-FjnP{I!SUT83l~+Qu8-=&~afuOho- z^)d%Bo*ZW}CRbj=dpo`^V&=Qg*+=Mc~^rw|dW4 zyxXB2=ZfSD?lWFmDpp)}Wnsif&3TcBH5%I`*l-gpw;Jp9#+*ClR^}<_dc7(V>5^j@ z=}x#}*efLYcxCpBtmLHoJbHUqn!TWN+gm@x;N&AjZ!xgAf>7Ho<a$-t_lT6(uWk1-9m>iqtbO=>ZcM?-*!rI} z%?o@qmAJq9tUUguIjE>lV>Rze>2mWU?K;-6M@GKCbmJ8u=ty=xbXj(V%N1zRIPm(u zGbsu8lXe|QZ2DFw6Vlh4_SueUP4K7u)CTU3rN>1%3Wys1Kgwk-XnI>}t}89e=ih&& znr?G~j8V)vvGhxBHL-f--!t|(R@p`gK9r`Pys_gfj$U9eb%FO$&&9*5T?!KEVrxFv zz3Dn~^WeDcl6TjN)V$6KS042KaaY{6{yAUMmNvyl>r(?wJGpO2z2L1MbnjDs(C{GP zo35Sx+Sjp5y|0NsB%b!~+4Y#ENpW7YwlBCHP-py4?V#0x8JvJQg*4BO}gq?PmT%s#5-%YsWko`-e zp6=(mZ&`ItTrm*1x|D6>nG<*UyP->=9zkLh%fKF%Imwa4D98N zd#>f43x3U3ls4z}tJqlgig?|_S1xQxD3y}n8SrLO61u(F=7(jNQ%9M8hu)7}_4yN@ zM8l7EI7noss&4+k(<$COet~iSorBw}y)+Meb5Ld2i4WY}m(gbK+!l3}skNEwK= zt*0M9xSY<@P#v57=v(9NG1X(=xlYn(DUWW}bB~PQ6qdEu)7I-jhf2d;`zL~mS$uEU z@y3L=zKIQzhKd$D*-otGr}GHfbNn`2l)Bs3K#|eVilUUhmgL6bjRQ(&9$%{~BDg%r z|6G@X|0x8;$QgO3=c?8?nG;E3=LXP~z$6cp$`e{M9amZVyAjv!D zU2XW~T$zhKsiCeKh3Ybe64B=)qbz$@E;$z06B+$&cK zzT!W7cDu;J%0ri&jtbSdca2_(u?tClpSFbSBCdl+YV|;{;G>2uXD8-%)Z0#!r?_wo zA1;%N?6dFOrzGrnaZ!sNb7pto^NSA|G6I$_-Seed;_a6sMSW}gyiFS3vn~9&T$SZz zft&_v-S?xQqND*dMp)%aFqFY6c z2bzP%d{kUZN|{*(wbxWipZv1bo1pHb-BWH~nkO1F*Lbu(O8W^hcivlk?@@=KCpSmz zPY?s#yZno*cY1nCIzJFKS$3Xv;m^#R{raoDt=8zZH*7t9AtE}a>+v-m!qObIPuY{xX8E&lS;eNL6IAIAz7$B1&Z@ z>m?jl8b7%{m-#uXpw2==I#I3i8fN)#ol6y^OKRy@!@P<=wI`ku6cR0Bq-nYA)x&Bo zd0U{gN2TNKoVLZ6?N`YZPpq>@Kgh#w&#hMHq|+%A(Vt~iyJY_0XFPqSVOUn-z0=1} zZ_pFuCZ=rM_A%qZdhXYOF~ynX9#XP!5GxbpClm>0$( zIXPi_aV&37eo5ZJ$aS(m%VqvW|8uC-}D$?=GH8A~K>;81eN;odC8 znCi4sC*Owa)V*?LO*PV88xs*-y5C!)ajDfZtGU(poc1Ts=<-WfFL!WGFf*H2e>^Zj zEF_`FJH^*-Re7mT)i;BVww2K?QAhM;w&A3fYJ?iUP2E;3eRwhRHK+MV`QMbQ^Tb|rP6sCt(fy{?mu{<3QQgMC&SK9`=VvV3?{WK|N(MrCb znE{z>7fwv<{W|&R=Bthjedoc1qfbrQhV*`LnKR)$&n6l5^zT|>aA{e={pD3^X%RvX|KAtV&&ZXw}8kxIq`c=k}g=BA+Dh4v6UJOX&{~v2mnb z$JHB9_{zF|zQQ4{a~f6KI5nd`J*^B1PD;6*TYCJt$DDW-L2uQQ?om%gx3?N6uiwmU z`1LSvf@D!!DVU~%nV)Z_ZnZUN`{tepZT2ke@@sc2-e8or zyVvnx&r0#Q$dI7JZ9R*gA9d_Kze7vevdLVwVPqhIB{BBss@{YvjaRQ+T=TJN+u}s} z7Neww+_Ns$5}H1j*IXLQO?`DTkTLzxD9^ZR;g(K8y(^*@o{I1!KKabowKR>+R{UFw zpGD{6$N}U2EpbYtD(O8n!5>cra~4Rv5IGuWH@W^yKcjT+O^tw;G`m#0_%d^1@^)1hir|}pa z*)hQW{j=3$n;apro{n=%7Z{vh=5k<<_}aDoE8;u_>qT8T`rqp{YcfAIKiDIGP2cbH zid^oKOK-;BT&T6?>LGKmZO^dS{Z=bb0_-L7T ztTiM)@xD~5u?8o;+)A(Cdj`>B+Wq3Fw9#+h0%+&pb zwL`0=YZddUm3MDHJY(*6*4-&s*6zSq^i1+judlMRXg>;|j$3vaI%9 z(e*46-MuK?PRXvhmTBvg$1B)%vJ5&mJp!%E!}{L|+^m_9xmPf7`ct>bV7{Z3 zmXy<$f<)s;qM~C%iZh=nX!||0*4%cSc=9^q)=$ht-^ybO>4!s>cX5k{pDy2Pv)LlQ zNp10)tI4S)W1$;YUioh4$dh>3?weJ`wrK7l{zAV^3a77Sep9_iC%uzv@#^7heZ}1a z)pwpIys?`bmF=}ReqP~z2j%d@m#m5nAwK0_o{P;}NVhEF-VNdz1@)WqB}?UK56H_{ zh8Wfq`}|rWd8VZJw^2=&@LBcZWe*R`x@v+zaiasb9p-G^DNKndwP?!wj4D zMJ+PqE{l}rjBl&&bKcowT}0IH-@D7{lch!B80$#Q#I5F}iib=Kzxy9I?d))EE)qM< zG7@0%V3h)!|L)a_7CQTUN^a};@Cd!=UeO|LrE@)Vi?-`)#*mKVPe#)gtgBMHbBo1L z{k7l^?cBjvgw0hQMf-Ck*l$L3$JWj_3)HecTBC6zc7u$p*tU(mS}BQs1sfg}?H!YU zzS8DVkM_cMMi>0=a=I;9ET?__)@8oTRoOK9j~DRQTM>FHpH4{f%};TS+}rIi=b)EN zb;!-C9mBq_p5#ZQthmYVCve0>ChBC?^Hq4$t@ZY{(g}~1-rn^VG zf9|VHX5z0ZxSw~|pFMSX;?irJHwrfx@GTwPRJvYtgX2$s1=d5iyFv@PFFA5Di@3ah z*>^JV%9cByW%djaRKIOqn(E&+y!}pvvM_^QjP#pDj-5>ReMHpCbhC5cc(>u$4oNMG zPm7UE+o!Ix<@$sDn~WG2pH2Tcoch{@aY4)6&orTPO;6o??a3Y<@5D$JL%IBzH|8d5*CnPq3qJ2K-Jh}R62G#sS~Z*VoPB&VyQ<%mo__?_$>5@7779V(Wz^hJy&4K`)_Mi)pW?%uP*@YyrcEjZ6HB8)$+-T?w z(M_=UV(9t^*`U2ZwKW0+ew8Dga@&Aq&~7m5Zg4r7m33~s;JslA`X+Q3*cV)^OXlO$ z`mE@>K0>Uuu;Hk>?1~^F<#8lFZBgi+;$eO$8a+Ld{iP%O$`7vLc$eF01=H+TWm)~@ zCto%o5;~N%yk1U-)fx9ww=qEL;+zRe6Ujg`=FPxmiB-lCb8LA&!>?ZSt#v^SwK(5> zdydy`VlJ**s8{F%e75TAR9Z5*VauryRJTDII*aU-?#S-3@6^G+y?b@6rLpQjFF;za zib)9lh=M1osEeF4aybVi8A4yk9X^d4+9|CIRglb@tgT+Gh>^h8j3wz;EY@qrWjz;@ zJdgs37`f7ZhDRBDs5U&VQhj;E;98^ z(TLkk@u{=6WKB%#^oh6P7a+5|8$5P;%@r z9de5Y-XudGN?odu+Bx$@_^Y5A;EgZ5h}z$@b9ti|RDxh(STZOUx8}=aZ)BBRdDw;^ z5>}Kx98_pz4a`X3azMemhc?hM$DU3?oW_s3FgUttDqOa^;N%tE#u9m)&^1FnN25uV z-IxU}acM@$%hEg}R3-`lB0t5V*3QdEsll;;w=Y;IX$nG$*!^Az;{Qiwrbw2SB2q}wvH&Tmm=A7O)ESc4QBU@$* z?5K@oAp7Khh6XtK$5#7w>>Ve-xZ?=;N=Q}c;+(9|izf;l&^Zt;`XA%msw_1ZPmnOR1i0;bDOW@H@I4_8UI_{i-Bggd| z@ENG_4`o3qMtx7#moyODOV9ETO&Vh1R?QL5!UjEkC4toAbfiHJg#qkdUXql>{{FoJ z-$xG$-3nvs0zX@dI>Jn7Uv0F5)_{$zYOJRyNFc0{dcwt2TfA4b(z=5(1E|PUWBtPE zFa0Wz^pywb-}AQ}MAfLmC^mW61==IURm|phACO;u#HjS#nw%0H6baG2M&_Kv-uP@t zzVll;l`%C$MDOd`P=ZOQ+k-$Gn&%jiv6MHucI64lKk&nxPB}@~10GEaBD#IS*T$;k zAie_1a?*K7b_uKa;cX^{kQ^A_1h|?VbtD?}0VslMVP=XZn_*NgWj)}Kw4MIqjW z)(De@74-q4bpTjtl|nEBtq_=N$Ek3}GlslJ^KXNgG<(W(V;rdpw!AhmmNq>nhg+OlB;Qn(R=2s+~uM zET%sS6rxc1C2XSAa>-9aAc2KspjO-r(NGOcDPJ_=wkts`0eg@$$`K56aK69&f8YN2 zc=+>A=fGLsZn=Ywsy6{(1i_oNR#2gtM~u>-6z0USZR~vSwBNx(v(md3G$HrSTF_A> zEPIpXPL=_rUNsS$aUt{waj7Y|bo)OroZapJG6v+1;-~ZPjaF}ef-%VWW3e$Y+Bl>_ zcMirS(vW-E8*rsl<_#{|#vClByEO48SoW zBR?E$7L-Miz`vi%{_xu;p9FVzR!<6SQC3rl!;hQA&#}u@`SoXe$)|s(dsX@S=X=R# zf9tp_(>UQVJZZ6-U*M*$OSJY*vIQTvaz-N=mW7;!$ThO9nX&4=M`9k1Y7=5;wk4NWB!7*%AwIR40`-BzO;(SQX>q0wBDDQrbfAvsp2}l`X$uqUWSpDS#Y1lKe^(+zk-LW-5^vea8B;F&zbZ&iqPzk;(r8oeyvG25%yTZ`*1#9V zCCo;6sIydoPW>(IYBonsa}Zv+ z(sD4WfZh_;^#P^-nO`1Z4jBINcq^d5Imy3aAHGfs+WDSddoy@bKOCHY|EB(a@B3$O zA8z6Iy=VC2=;7AZKj4oyTRU#fker)v-jLc5I%hZ-Eu_#AgY$HBvnvs4Dj=Re>ZtPS z!8Tg16<$neck5uA@#r)_|B$`!q9BCKwJIb+&wts3p;jK`7CqEtF@t(YsDLhT#%WzGSYA?ISHL>`{6)CdR;^tWRZd{Ji z-z(!v1y~SQ0+UH2bdQebr`c4U@;y6}o5~V3=R!^Q#&@aA(!GMEQp*g1cGl9v}A_eeIBD=^ll7`1Rp6At7K5(86 zo!jG#4kFp^o3dKeQFuy&g)|(LP}i`23gyE~gP8RqRaSl^(l|!pj9jY$;MH%D?Pgt} zrlBd|Vnh)z0qr6T#q%0QNxW_QfwF*QzMMdaI==Z1+&6Kn8s+^Gtow!+Lfei#gP7Gl zO0`k7Psm9w99=ApbpqA|JQfi2h$B9XAZA)anXARQkEQB^O} zz9ps;4A8GP(*b|1n2qNJCS>gEIu2I#j#*j0Coi$sZj`jfv2bumLfbxu!5`!Bs~R|NX+ zK9qw8@^f`dAk~FZD^dK84`O3s!`D(pf+yXO#jY64pl3lH5V0xd*E$>!{@J3?^b~`o zSt23EmW}p~Ku*o2B#yh>u3?p$+oan$5iGmyISDXYM-;&@bw3?dsAvl>y{ZdX)^b(3 zQ0f4YI8rX-j|tifUl;$``@7cb=~JR7ES5!l8(jPb=^vGig+X;4TmOF;hhsQDA%nP&QKN;2 z-ABm0yN<5#ku_ngx5GNNY~qB2$l8bW@$1!?9d)yu@MTw*MZX&9DlZ{c!Yf>S-9)jw zQeCJhj|CwTrlL-pR`EAJ1R6$f2En<)eXJ32V}!`aW3!S~>Ca#X^o$bH@uDfbU|a5e z{uTE4kfYx?Ym)j8u!RwJLzR6f7N^F7tW+(7b)=4c{w}`_Z1FhW@%^puD6p)1Tkd0+ z&i&ae@J1JdFq$CRzEE?$G^RyNu)!9bUR}jD+&p4#3|6Xfy{ha;3Bf(b0d!xt5{GXj z5=DS}G;GbdN4TedFv8^}N9y%2{t2OPHz&H4m$tAIf5sK*ke`zM2woT((7KI9`GSNb zG!kJI=P3rPzRxL4w{o7*GnM!d<@0bjAn69L2KIt5 zJjNsMXd3bogs)Ix?;@^HJg%Fu6BY;GUZ3u`o25;$(7-xwH5a;C`UNf#UK#NPUJj|g zrLpD__aDr(Y)UmAMTya=xIKur_Ups_6DcXnI`R{_+BUeAD6dORBs-yv*+?4|jx<&Y zz?xEHh&v9cbWLp_20l8|F=YoDAfa*byYA%)icOr14?{UHC^;P&;6|womy(?YEK|L% z9HqXzYZ(JGa^I6y-=-BhTGu!_W6~y7@@Z|pUhIAxka1gAV50gkfpXPgK@nWz&(l%* z59li$ZM<1*z{18R+AUimV2t)K7;T(?P?cJ|#v<=D+8#Ro2lV_b4HO5aBA@WySZ2kW zR6UeXIxN-kz~nHgeRcfm%l+fi^VChbKX~=>#nD&e=lf^->06P`?G5*-Cou);-*<^d zB-4{y(U5%f4ZpqO{5npwF3~q6FxzL1*fIU4t2>gfADpnO{65E8_mS3qir$gsdy@M) z7AJ`=C|V+cgQDG&X?bJRm!c&$TTSH6a782U zgyZB)S>mb?S7hR)0H85}Fl9H#dR5{Yxk?n+!`?1(SQ)C?Zl`Ei)v()*Z(*yIEo;G= zV-OWm>=V)bfalU+Bl(A>$~c%>-}`Rdb_jm~*{AX%Hlrn*A@|HBfR}?VpRQGGNi$gn zFJK%o-cNtA>5FevHQY6~>Es%3+1vW{cWJD?iMvS|!8`5HU`_5Nr>nNpAAY!Feg7R& zQCDDxiLAGPVx`24!!pSqFlq9^{{vObO$x#=5QgD>PB9B13NEy3+b((mu?GkP`2~{+ zla$iiYe^Tn`8E&V`xvv&0#4tZNSiqYYYk77Y;e#6GUEnk0U))pxV)<>6_ZBR68Zt; zbAEO5x;vXpT$Lq`SR0llM&zw|@wBQHIfdj(^V^SPCdZ~6a{p_tL05l3x1TOz9K;9h zSX*z~HWYsMuQ(_ISS}pd>vd@BENRkp0h%UA0&GJO7?ecYT4_=fskmOz|GvYUEKzpT zbbA`6K2+xAJGbv#lvh6$i=sDr_^<~L;d((KA(BGMh?FoBB@o8o;+Ko*vB>BZ&u24Q zLMGB`Nx32_7aZo4(~>Ar$`~;;44#KuT1vh9)U6$+MA5k@*Pyq}N0cMv} zYJu|cd0WysTrFt15+Z|FbLn0W<)2mlSInt82yUE_GKI7Bl&f_~;ni}P=H@lLk&0qn z=JSPuN8|Cc{YT>;p1_qp0vBox?^FiS(d+l{{5gz&d;-s&kKx&PJTO;To>DHg@(ZO3 z`C>Gh=W0IB}|-wvLC1oLQkL@y{Q zV+@s6e&jqCqT|g`?_ZAP$&P&>=-Eor43vPPME?d*BoUQ@6h(p5vZO}KaUG;0JR@Zm z|4)tYp@z>afJ@3KM)*bTuc_NR{D&N}lnHjGNQJj`{HOJ6?{lxGg&5xH$8wL8B?U19 zh409MoX_jP!-^XEI5z1m>xbS;Vmig9`bAMmPY1(WZW&X2KJ^k=mh%xmmO7( zka1;6)>;+IL)3^UuL8@Lxlur?>GVNP8+DWjwK>)1Hl0RswI{Fl(Bul3e?A5Nn zE8bWlyk|Vrt|ugdmuX#&GOfXIpTOQF^Uk;*O1g<{G-$`7N-$etR`Jx-z3DXd4v%UN z4V|t|{fUc~Mf%+HitK52?H@EbT|>O=p7O4kcw9&SFQXCVSxb{amlu~5!$@zbG$B*D zVs-os8q7+uG(S(y&)%Cl?r6J%7XH{CdeKnAFIX~}l&I0;uLb2)K}m~}O6(?9y$7x4 z@&FW>yPSgG&fa|utM=tAXSAbvNmW(y?KvhCYOPb*hjvcYwRTg~v^0#NL)2UQ2YBO1 zA$C$BZ~Df^{XsiQHRzooYG&B?l+yd!dgWw9yG#t&+Oewv&@s)G8fRL2bTGAZXHh&= zeW^80NW#{z%CXbx3z~F|@dQhbz;0OP7$#G*mlQ{U45ZKk*B)#^ZgsihsuavzfQ49j zm26E%QCXED>)~AK@d5=7%?aE{sg$OadOR;>Au5(ZLcJ0h(jR^(Z$64{8=vhOHJLEUOp8}H$tF*9@zaRF^a&g?{3&{6wi?!&CbQOpt7Yz2!)QCzDN~J8^eXpEa@+hIsrVv_zGqINA8xnSgiYY_76=m$}mF~mM zJ!+jJe3&UXG^f&0I2fUtG`8nzHbt(@4?Cr@d8Z!X{B5m{S!*R;CtK@@Z%b-gNS%{r zl-CIXlLIH~STA*Q)HP{q<0YLjYMgU!mZRp)Ac5?#p!K&9#sICP?pI-w=QD^*@S`>{ z1~8dSU`Cjvp=KttM)2#Ff!&R3kkV2SWU;eblXR#ny=BfeH2rN#Fq102B3zTfUX43v z_i(mR(!5T9ekvG7KI%{V!-i`E8#i9Des>rj#y4>v|G8g}>@Qg*NYltIKE4^kcnJGX zw?Jyw<$P+xzQG^Dy*#NO-F|Xj(XNayz4osl(hUZpS*Z6E$23M#8g-CPPA}gaU!Pz8 zKD~N#addfvuW{efx*u=Z9DW-DHji(;Z(Y<{?ofBPK~`7&wTz+e`|=QfS~4B_=EY`` z)^U4{0sfog~^Wvh_dYqq#4>^KJ4|} zx~W;czX9!8UvJwu5`Xun7`S_tQ^b~&ZIZpz@iqUt4UjfPV=VTefI&;NrHw3VNjizU zm+yWvlw?b?B-`uW%i(Ask;s|haOO9|A=Ud=nkbg|Q#-4$2@gUp{_;M=ll79VLD59j5t2$T`rk z>4}*0z$P3_&+t;X{66%@V=m1on`sYK!1k-;6S()dd=kQi-b5vj@713(|9dCox?kY< z#H0hCoSRV3C5PU0>iFid$l-`+F8zt8;jr61ZXb3J-oibRz!yD-TkS&Y{Ngj5oIv-N zw{U#Yh2w5_&#(r*!$U>Nds;{8)V3$S_GY7wBc`^QCSW6F7glDE0x`0uOlf>JA{^e) z&l)c7ui!R*PsE20U>b=>=@DnLgRUaw?Zk3L>Bwm}8vYnsPQa8J@@HRZ)v^j?!zDadQ^V_Lherg6mUT&Ut`Jnr1)Nk+pdNmxfPrQsWDsN1hw5RUM#VV_i;Ntc%|T=;l7|y;=6ImUKAryu z$KMH#G`9eJNFh3_v0tqm+oOmy@03)3;%9+VtS9hPT67y!~PpR7dKrnYHyM!d;nzMulS9Tq6 z>Q@)@0h@egQ{J+2wANm`?`uA7b&Dd?m1lgFpC-fb(kQjq2O)IP2}veG9npoT;4n>1 z*=6GpLU-t32!%Ozj@fDeHkIlL8Mx^P%2+_FnHE3-UR4rUkALuoEIbC4>1oX z@2Y3V6wS&xpl3Feehv<48wqz_Kyhvu6W2u2=Gk^cAmk~$`e53-N|rG?v#tE^m?{t6 zM$c;q$872c^HVsNJ`48YBM%B2t~Yrj^rWu$*n)LCvyLxyPn$ zwARD!+Oq|I58Jq-pF*w765m`OU!Pq6Qq2-Em(a6L+mVn6e)M1T z3`zvP3$HFr+s?v=8(6s8JwLksc{4N}Z*1XE$SDgpv++@-DJs^5rG?AUXx*UZc$q2`2BQ&@2)g_)kd@i?J&Ohn5 zn~okXHZaxyR{PM^6MSKcEJZ0!QbFWPv)UuiE=k;6A zx}aLSG`3MruiK4_Jv}=vPil%JyS7R~0;*zat0?cFwuHjrO#PItLi5F7O(D8^G#{Hw z1zvfi8sOOA?vgGC{+KC^M|YTo2DDg>20r$nw2=@G=;H@v?hB}DS3vs#@|M=Q7*uQu zOiDH{9+1w%q#wmbOnXKo3Hlw2=7n+S&O+^6K9`)W3YGMtIQ0(ugVc7HiS5uMhc*6& z-YfufZa!;j;WV?P|HB73+K(5n+4IMMMygM9S<68$@cTUmp5)`R<}0hCv>Zwv1) zu*I!avtQ_d*w2}s)6?Iszuw>6eePIF~6PnO9bduETWaaYx<}p>c&dc2i@Q9vdK#*rhsz3j?Q9g8mkaWmd5al+5hS?_ z-ioBnOmzz*5+8qXAuQHhDHq~{6sil5rS#p)lY;q+XkA`vYUxk2PWX)lv#i-Nq?Be< z#2q~GIv$g%m5ybT7VZz{K_H%hPbpfdm<#5eGI2TFzYg>}K7BpW?QG)yE>@=M>GQa!SFSW6lAp zM<4SEN`$QBIVRtTzxgd}8XS&fe>={23wRxlRP=63&LnKCo{I3Sm6TPLw-L>46-$E( zA83Lc`;uRAj3T$%rw1GOG?uZ(sRva~&2z8!YD~YGgrZ-!;VpW0E8f53+wCSO@$N#v zYW)&l2bAm4tUKBwtE?+%h`?QB=F&S`O4ZBE(X+K%`E_V>ff?M^N;FHbYu2#y8tHwp z#NAexii#Jv^SW@H++KUuDBCz_n@nhorj7pq?OAJY+cp&a?q6|d1dx=*l2fEf+dS61 z&;`f~O|T8<3WJttORFqtB-O-g^WS$#J*=ngG-=jhC6I(B?>+aDJUpbCou4B&>R79* z9ax2Za6%i#G@y)#kb!WCfG`$OEI0^yD|$o1sUxl82@M1hUKp6@DV;BWxr9%YacqJY zY1x3d#YOXu)}D|ys<0bdB4Bed){B)fGcSNmtqR1 z!U28%;2gHLp#O3MHn;k)+3y?5)%R=~aGAU-M8scP*4PtnJT&caVyQ4b8FH&KGHd9E zLu*2~z`BC4sVQy+99$j2Y4SOR4?cn_5+2bbN|=cYB$Kz&nX96sr`73rBhYQ1a6X{7 z9v58KDrSSD(0-e(EFa`mZ4CsAsR6sYyD%a?$Li;f%t5#;yn%q;R99+nd~4H4uDz}u z%9u5SmRJyk0!CpRIGVBDx$8U%?=F-bcpMzcy>WncB7`9Y$K#Ptruf+lfFKT=cmeT& z1dg=6VI+zY{Wg39?-yT>yV* z;4IC{&gV`?QC{&;7L+p<+7zP+mzH^l1ZGGl?ge9?0++~U>XiB7xEYzi(Z$(028R{N z?rX%!8p7e9)D{Xz!j~|hshkL4G-8xv5=lzkQchhEWGrbeyM8}AorlE*ZUDj@7=X^*4%#xcD%N16xf(luVDBSiLwJ`k81nhr6F$|I z)pjShz-gewc0qOY_H5Vl9SO&Qa99bjW)$#bkz%JhdVBKsIhjx;Us^Uct?E(B1Q~MR zhxW$=2h%B9-T_4&Y!74OrvdI7TxO4l!NO>gf`_^JoVcA?O;ztK3wd0gY@>;*Ud9U{ zrx*y%=>L?bEEJeC>Ux2yIrZifRZSh1-E8s3v`pFDG|#PQdX+ZnMRHTy4V4TXUz~22 zTe)BZoGnU(uJ!O3*0I5-f!>|LA6^`toWF&u>;3bi{dY&N(hQ(fDklRaDyZ54khgM|)OgU8GT&t%kF z#eKpUnd)V{Npy+^*r{oS_M4D7sS~}8e9T?fpb37a@QI7mby;iD^^{?GP&2jM+l5!J znuK_G#|&n0aVZN?M+*r)O; z!w;s{WGt_Py1EK#MX?-tjEkh6Y5NSVx98z9>V2a{>XoxP0cG4qKTKm^Anq_07+#&V zT1m=h7^h0q+Z6peyY8q=n}t2^F6;X&#AB$u0xHP-#*1ZSzT_o!uGvj7`Dt~&vH)ri zS5uxNR>gIxu1r>1q`y8Vo8MCUpKhQnr@{OL?h(2r)%%w) zi$t@gnuRDoWV2Rki|{Zx`L2cYDTmr3oeNU9Pw@YccrHEayH?h<_UTzZy^uW)$jn{Ia7sS|DgS4#xUwomFFeMSJ!pu6WScRV2>sR#=X=A>Sh zQr+jOxjYYMap~nbs&8yU4>I*G*&2q?fTuxAoO03)fwl^P%EqmcG_&^DJCm#h8$-U- zEY0eCzb{AXhw=Hzsr*nDf8PY&x+j6ZmcK9W%il+%@0^#WrdJsG=9Jo~|M7PI0qs{? zZ`(E$e)q392m&|`63Yp;q-g3~8+Qe=Hi*;hVG9gOqAa2ksgYEitjK@gITU5fvXeI0 zk4Na#Z7NKC zOyotzb1tm`n{v2kTBy4G1~eSYeU(WE(3~3i&2m8ljD|u_`r&4D(9O zz*Liy)@_VQ+Zwz*6R}PGnHiwj8 zW?1}5)3^_p514RRe~Eh$E3stGc>8+9WY^Xu0h8$}YKH|&HcADT#9?gB)9Z?9O+i#fg zz`~3y=z^j2fqS7cMmcCGL`z5K)>6V5YEUDakM$S6s_+nO*$GiI}2#|;C%2#i- zvtConGgLW&Ypt|#eQm~E-!iVfau%hP_VfPwOy@CHQ=+0mc!kIBsgvP2!`y4NZP(;n z8zeVZc94(oJy&DCJXWoPxOCE~OX_l^2i09<)AdfeW@vg#GmvE-a!s#PSJ@g5iPwN$ zRt{VR^`1?zmA?-0_c{)3#72N#i#e*&ZBad@U@YRL&Vv4_SFdR84JR!O`;0Mpc@d8RF8RQTo;u7*|&OntT6u z{sHY*ZExE)5dQ98aSMXl2@=aKx;9JWq-kq+0n#*!({(^m1e8QuL?u!ssW@KI|Gqnl zvSr!Mn(fno@ryz8E`8IcT0MZDFi5T>g4_^IFAx zB*l2lbr&T`7?^SdIq%ZR&o}7VG|C}#BsZNc{U<6E;?J(+w$zAJKGR~7Sa{Ow{j&e0 z_xLG{emg&dqv>?oT}EG$edc8e4leBs&TR~x(^nVp{5kXvp2D-|J$TmZ?Kss`L|hv3 zG_f`}he0qAHYq{^51dIU3r)}nLlCAa3^HacemjVWckP{pSEDy@Ud}zd`~q$eJfi2E z=`LoE91VP!o9L(+wEj=;e;~b8tO2etOw91Zd2nz1-phZ49V1Oq(WreC%|>(K*-6*5{sfIn^>VzNITiE z2z{K6RG~3tcoo$YOgTAeXk$*A-k|nW#5VDhckE7N1$v&QYKj&hjX5}hl@R%)dyD*X z;C}NW#7hL@iY60JI&!z9W~bE%=iYqbZ^E?@th?PGV;1Xs&gT9>&#mmhx5W-Iun&?? z;g5IcAGN?M|6*x(|5)W*zT+8|(9TYC&v1JtW4v`8s|$|X^L-?5$9was&9zqAv_C_? z--jMNdIa;WDRWewZ`Q4&5d?6dY(h-1s=P_vB>^9K=kmh5@2#e#7BBdqED@bH@vFV! z&6NBrtx6{dg=lSmR1h4aP6r zkHTeK1%8d(_tyH^_aH#Uiu28zz8;fDiSh#Dv@l7heuaGvp&I5_{Sj+w_0DP=aY1X%9LK4gHQN>UxVz_n zinqRWhYr;$t1#~$tByikxYMaS(8bEzTfLs!u4f=ML(^-Tfh@9+Yf$6T?OGTf0_w}y zDrotfVC)L{FvO4ku~|W^UZH=0ITUv+q{gL*iB98s=G(Fe`;?Fxn>!wF>SLB#7xekU2FUf4}TwAjn3X*blY1Sv1-9wIVD&eQ`cWt z>|BZSYwrJ7>o4tA-*4MC5PtVxaR`Fi2|URwx}7!+Gwfjr0!pGSq7tc* zR2;9!|Gwjil5N?}n(bu|<3mD`ci;W`c;}PFg%?qV1Oq7O;pDu1s zRl>(oOeS0hDB`5>81A?>LP_|+pB=}{@~P5uaMyHFu=op`a)34t-LlfAXad&<7HPpV z4r3;*kOGdTrrI5wKQa--Du2^f(R>QylX0u=weMR=b%Q`r?uyYvM1bQd$KEvT53|_u~gTnzF3F0uzz(z-!ka z=cSCTi{GTG%o0SfrIv7Y`Rf^o2?&e&LR!>DOk->rIrgY%gzA0=55GCICdKpVGBG5RAUOv3YqjSMjT>Ql21aC##B4IR#}#rc7Rw+ z&2nH`vpKZZuFn^(3;bZtSAXbC1}&6!an7BqyU2mq&=%mT4j|$##tO@2PqwilrI2s3 z8>>=d$?y%T8JOzhZA%+#(vAkTXCkqw|MPG556`xNU@%` z`FodZt+eUhz;HN(0X%yK&DD$%;hM{347b7%J}aBLdRbNRJy;R&`60(%H#ZNRW{VGw zvp8LHC℘{lM8|26id=!#CCDj9hJdvA|f!kZ!E9GMA){+s(?W0F4;wQ)V_PP<9Zxd53+P&F(y&23$4Ud44H%)%FL)m%3X-802ITGt$ zt?q8O>sD`ubZdp`sC%zzK;yzfihr{Mc2;j`ofssQ?pr~TUgPT-!|+0UbOYY&~xUrWsO)V8`rX4C0I7;@~U z8y@=J_8EjsgSh#9)3mx))51c!M}|B`p7P|qYwEa8sNd5>m?4ELC*1_oDz7mg zU+eBeQj&EyFm$=rj_ZcHOJl^T8TWbRzCf0F#5Jf1^>(u~Q=bCr-{d-I)w}Qkm-1bF;>Y9wxsClyv=rIz;g`C>o#D3K}oblR3kadtk7v2qhH4lv3R_D?v)So?y}6wAnJ4i=s=$>mmp~=q=u!CF#UD9_(fzi=6FD5 zh&o0M#qg0z#RP|+oa`zkny!T0f;qO5lB6HViURmJ_LNjQM;EwmC0#+BQ@If$gLfGPU@7IwgpzArs<%0q^_TR5PeBkE=eFHub>NnADzSAypd?Z=QnUwvfMR@AP$;EHsZun9 zB`av?tQ(MF#ZzqxpmI?a86xOPa+uG49{|I^G}<$+(Hb$8781WQq6v^hR2pM# zG%1vyAa+xdH4rJu7QA)j>SfmyH^jv1gvMp)q4>=inoy5$2vTJ~0p?8t2{k#^Sf+a1 z$4Z32f#Y68nByiEmBg0e#S$A(_2$yE#-8}up!J4jI(M7j$UR$En0Zl%4MuEQ%N?AW@v>ks0|XgD0q7VihMo4a^4{|heQbz9jikt`_B7OBbd_~hqDXEeNFp z4{XYQw5}`m>}j8w;f^O=Hf=KOvgfxpL$@zq`aYuwCPL?CbhW6jet1|=2REf%_`#(A zjIz5{DvhkyPOcS&1+|Ipj$P3)HZl$NH(aFn76&H9Gka9#7Q&*hf+EH`e5ayb|-mtx&uetqp{2U%sk z8|swR9x*l4a%2hBm?^WJn;r0Kolps4Y4cRA*X0nR{^7~8pY5nBy9 z6m!V#Nn%*t$Hb&jzIJa`iX@&G*1zAi+b8))ybjM|_D5v?96I0gsYRShO5GDPQgzn# z2-MG0^S0w%S621XA6Iv2J_^>n$6tRJTCc%wv|D7pn<-yd&x9{+`nnHcdvo9u@(86a zPS5bc-qTX^$1a1X3B%HaliC0Bg8u;RR!ei+HW0q^SM0$P$)1K(GpU{0R&1xS)6A%; zYq`@y$KwG>NW_E$SO5&IX8hl~3xX0wNom|(dMGc#WB1$Fhh3eXm01}?2L}Nhz-7S_ z1DcmgTbL;g*FRq0|DaMnm0~vIIz%Co!(;fwwGm3fcmC`=VV2L8UI1OYlaeJL*_;FP zaojDdY=$QAd&goec+O$Uq!m)Y>D)A{bMr?o!bBCX`zo5xVVZGWE0vPGU!p=K{tP9z zjYgu%g%HXdwBT~+(+<;UUH^GEF1+I`84;@Q8Nnuuk3%jvTd#bZZJ*E@Z)82@BQ8RzobBt zGh_O7y1#K$F!v2HL{a9v;L`3A3_b@zK-L|f=sSRSTyl-n00t$~R|Ic_stsnztcSLHsr-!d7?$)M5(EiZkh5j5#E#ay|*^ zH0GM@T4h;o`T=4&H7kH=%@)x6_I$qFca0lHzWPHl8TL^6#knF^_mBmNaZ7;PHh`E@ zj13lLPxi55rI2y5=MlzOPgSL{WcUhI4W`+g^|Y}j{b*3T7OBnr<|pHKDS@HgpN33kIC&#;Q!JLmKG z)ySRf!{_As*p|_m)n)s z0hVG;-(_Z-g3GRV6vkd~>H6UAWUGeDdY7h@Q>!b!%fyfi%@1=# z+^jc^_JaovcmRXQ^FZ>AkP4PU!qtyg z*XLrvr-8d%a%m%tCc|a;!e!`+0G^n&R}NErCFCvWZCcqd=QCSzfHDs4vPi8_1U_%r zT)N!jFlB*q0~emJ!uah~_?ze2j__ZUStMVhOwdg%Ji;rbho`#ey)=o)`C8VxO+vPnM=;0+JB#LNH&8zz;@3i-t#bb}Q}ej|m$ z!;mjv>3ZBY+zH4a3LK>!5Uxe!Ef7IPGJx6ST_4;fxC;5*Kp{6`hDu0$TQJ3d%|)a@ ztvSIaa4cBBpf{Q(%GOkfT~P;rq7y3xoix9R^Tn&a_-Ws)WCV?iNk`~{&u*IW$1$9AS{d;XB?VHXTIq#=`P}++mH}~REy!*C%aLsj zhNJ!|SZ4)`LnV>1Nq{YQ-UTBN9>Nc;vT1}zq&dBTqaAgGmTlXX9Y%AM5eqmj%X?T9 z*Q#|#-iov0DxzJZ2RKtr>!EdQJlC>Q>LR%{xO_LhK*cI?wk_ySCYO_vcdGgD4Tk(t ztzWFERjYmhCzm`gs;Lv>K(DA{#)DdZ=uO7M@td5eeKKmbt=Bl#dYAiAsllLsK10!{ z8Wqe;ppOj!+Z76Ip@yU3xLy_kY zPx3r3RY}c=9gL0|7+-ei7>wWjq&xfir0En2@eawW?sRYkQ>d8GeN8eY zhJ5``N_AcxU9unLa~D&QGiMETSq?0OBRW;x7x4>83d;s(7#R)mI>L+mfVlCsp1BB+ zk`X`IUdIqyZhX=;gsJMfht_dW2=iAe-T#%0_%0CzF%-xq)^#H+zKZFh-m>cD<>H)w z>dx9qpgJPHzb>VSb3lJ+kJ|P2Cjb=m;*rUMule(*r+`3~ybV`~pv%=(VhOy{5yyKd z^0~O1F1gVZGP9OCpQ-uB^fbJkl+U(-Y}sVFO@}xQnLhY?lcPXK>0!m!ihUV!K;hnD z2kb~7{d_$nwG7^$y8!QB#Hy$t_b8cnUIu%g~lh0U#o}N@5?)E{IrXEpTE;% zWLIuADSNxkgGEy38u!>LEgyJKN~rH2@7R6>IDb8W^WGQ+!(U+bV?Te9O#$#&z3okY z>R-TgJRA(*{qSS%tC=}a@_!Z@$y*J-Od zIJweymym8d+_WC#P0lgh)u=hqPquV?vSYA-R#8bla*%~DF7%)RpI&fVp32Y+gKGa4 zTU~5}z8Xs5Cz$)6s&%l4WZY3W$fz=6NQMMQG#b%tq5hodujJm0U1v!f*_`MQP}94s zpvJRHyxts!_#ufy88H{2Loo+&9#^$QqjB9g(@cQ&cTSGs%boZTfThj3OJ6r{09nxCFM(d6s$ zqEFSbKe--`XZ=YJe~rKI6CIgVR-%6Ni#|I&rSMLoVCMR~Ssl8R${!UyvqsbB#$WAL zZExa65dO}u7)3}n3D_J;lU@?8c_X<Zh&*EW0z$Jo9Rw{g(Ji$=%;C!9LsuY7nvrL14m#f)N+c`P}JW@ger&U^GJEken8! zV|YO!10KUK+1a_r6pp!=gT6K=3G<%W7y*hn=9W#APbO$xVhlYD2Xiq?e^`G-` z#DdWAc=Rd7=gC|IV_!j|UjJBY)IS_T@AvyVIGawVj{Fe@J7kYC*&mbO59p{l+^Zqj z7ncukd<^wp58>#z4oCHR#i)jXhq2V8eWen4;=1EN`ICVLccsP%*+9AlkK94X2X4fq zqP>Ce&`~o5m%VGaPyc7|@iUmE;R!uKCLBtG6Qgpoh!xRE(=Gjx2I|twDwU6Il z58rC(rm@-(rr91mRS0`c)tD$8t=KQmiNtbGQL_UnQQ0}kZ}smLXf~T^WGlH~=#^!` z+^yVsTVa-yELb>8LMmuG^?x0|z`^5_m^c{C3Y|!R(7;9g*dJlIuH?3~}ORIa? z?%h3pg-=i~W)(f3(@;UBv{y7-vKR#Mh?|F<{$I3E zTA>L~^5Un3US3#ht_p7{T!k$z6%f+a?hgY!*fKC@iyB3fo~BkxSBc36+gxB$fzyra zfk5`We*CsAJDSr1YKJw?Ut^qe>J3m2`fU}|>UP`R6S(4&a0oG1VAK(`XFzyV>iR9n za&&dJ+V_j!b;>vkl-;OouPb`hh?oh1r9sm=t<{EPrYU{>z}>T)WlcHOUamsQK50^o z=;^`}jO_&)4H04G44U|4!aJ*Hhs!uaZ$dt68X3H1@eY>-n`Xm+h|}aj7WJv?`(An| z7gTfVBQN9^#aB~TQyQYbtPcgoq6V&SNrtWG)OD%?rsHk;WOoa#zPVTrzztSMvO!EQ@4M` zhP0Q2qY>o}3MyGVhG)t}$P)P3oSpkb(lO&RP}lk-CH@l`Q-Cs#z9pFq&;+hanm~_6 zgBhF-Xc7}C)SvTlOv1?VS$vk`vvkJ8aUfy8+5FJhZ~k-uz2EL`;dC;YIO0bXZjn7S zvOlu$59rDn+{q!>7nk>NbOg;`4&d;p35U&QO{+$sPZOa?2U4cu*mcLD46=a&cZI@; z$UwLykK94T25wA*#Jz^_sUxQnE_>H-m;X2L$rI?M;1NBgggclAC!x|c5i6skrd#ud4Nt5Arxi2}HE0##k zqRLC9qPXZ{QEL|-0t$&jVk3~aH)S)SFd>PAFwv(hlW8W6&Rq5UnQ#!2hsoF+x%xNd zOj2LcAyjj;dxhTu>vP+?`rW&|xU)_wYed>p$%!wuIa5?4&SD^tdy0{yPMJYUIEf7h zs45Xm6MjhscqP^qIF%VsAP%QU&*&*jB*J0|M-av-6CxZ$8iP}xJ?n@+{H7iVf&ueP)It=ahS{bm2{cy042^4$UMocZ>+hIUp^w7JsJ(v!t` zkq}1E4uzo7E=YcBey>5R)ykt>D+ER@lM#KljLF*)vznT~(P&<973Fbbm(!-FSm(OkyT84;X?y)IZSS(vyM6cyXV5ICkoo}w3j-jPSBu$VA`vDd zrXPNmGr;+*xD;49mg6{JZO*)s>XvHm`qpb-J#@UU{a(9!;a%XizKmqCnMYU`L%nU4 z%c~kOe7x%C22R6*^+}*IVbeI3Gkaf&aJhUb+!<$!v>d12zfX6 zhoPEl2F%%@hS3bhR?b%PY>jLoF1f(T+Vy}_^0a#VwkbJ^(j01wH9uG(T=3})s2cN| z%Bbym9q$;fSQZT-VG^`D1#}D$4$ED=6IqU`(01o;{=3SUPD5$$*EUxbzIen$N5DeN zyhs}vG=|W4h8@dU6q94^6iTBSpb{2`dNQz-CiWZ%hXuC^wsd5S@Yb@~;w+s~KSOU7 z4Fj)Oyu({gCT12OaU499#C>e~zMmh8In{#t$d8zyg^Tx&hU?CK+gj&dq^Z+T?DL(+ zWT#%FUm$1-3kTPRNpGOmM)%5CR0G^x>DRl;pY2#%a~d}ke&<)5$&doB&5}$SXYAnE zaUf;Ju^FK4gPUQ*B4C?ciAY*wH{<`_qszjgT^zgVWA$QmIiJq`)B5eZkP&C_i(5MliK25Z?m%ywl_d$k zkU0hLam+4B)dH`;@lnt@3>Q?aIG@7XxpY5I<<~U&yUD0Ju{ZGLorvZO1ut8z*9R|K zFJ8e=AA!EQg9|l<`q}$SI6Q>bn^*Aqum!JMt%ebeqmVMGRaq#tlt)1@kJKWaG((;Q z=9-vHWZ>x;OkzF>5+W7;HV`3gs#^u`hacd=&K*4a0%mAC_LYdliuJWx?(RZ6@ z>#+x;!EYUiW}p_4%p%Vyol2lWV0aQLC8{JLV(0}j1wMnnQmH_3MPk`>I2qjO4G}Qm z9G$@2T44Sz(+N5ds)B}GOgkD|LK|j?L5~Ysok2*#1=W`&REa2*5b`*tp`ufmrXpf< z)R=-uS*Zp@2y(Z5zld%yL7_UffaeCkZBN!4sDiJD%s+jB_K&@TO(R{H5|5A#o(9S=BTN@_rBiW2(buWbDPl%qF7&-S z0*<~RiFG4*qw4%+Mjt0c>*^Nul}!)D&)Tk5wTjgdO7jz7lo>Fg+D40|y~lhkmxP{1 zXyaA_V?c|*&jWO}9LFrXARSP%yL~f%bMa$!uuTTT5YzpQ;!9_0U50u3$ zOOv@vI&H44*?Pru=l*)(JMP*X%$wadC70VXI=A1n%t`~kZFaKKYv(`@PUcj7vKzW= zvcp&t6iW)~Ybhc#1ZbZ?RmVGzt_LP@J;K^i^{Vba2PgUBymr!`8_;gMPT>O>H6IYo z7kFOgzOpslD6h4=uHBG0rLy+f*kC5cgqUL~VU%R48tdKc(s9b7uPLqPv73KR*CoDWBa30mYW&;PH2%fcKSg#Rvc&S&Sw$R zb4^!X5$QD7EFyT4VLm*HHtnEBzo}JCE7xLDPe*zNEKMdS)1a%&q zVVs|a_=od%0Wk~2zrgH9w`8LE#K%OVaXoQt86tg5G~e9P=`MQNVib53r)<&4V~C`1 zr{cpa9%iH*4{cIAMAJvJZ!?e5chNmL^MeSJq)|L)FlJKMex7;uM$YtqRYApG=`{RF`_7O$R7t9?7x;hQ@kGh8>|`-EU@y~yO&;%l zcf3y?pB9rMNOpGv*o8}@BxqhJZDFJ|T>o@^|Dzi6z7(So*D>-qHYCGWu8lzMA3W_W zWtNYXo`E|iO2N|4Y|H_=ICRQNJ3$rrUGmXL^BG(SGvOMJ|G>S;)Cjj{7 z=Wjm1!2$GMy@dUP9_;seJ0zNkluP66pIBR%!z39CJ1GawoP^Y5Y+#bk<&r_B21(A0 z#Wg{sJhtB~yy?G%t7`Az3aYEh5~HvDcT}0GM;m3AL9!if*^3pDM#G53-7t)8siNN3Z|`K zSvzYO7$L_QheE5A8^eb%5*d%ZbPaM*%G5dsn29R0AtKmPOZa&6+dB{=5EkWyv?z_3 z#wv}gA+rqFK$RBkgcEEH$K(($&ae8luoz1csrh1bvr~Ykc^z^nT+$k3VGBG5RAUPC z3aRua4mhN$B%6dJiLrKit+FgL-3wwgHOql%&9Ew9%e#oaYuqqro+mmjaYt~V6y}A5 zEz~~kt5TygG3C`1Otm@f2%xu!ur(D!JE;`GFYKGhOEe?P)D#tBHgO<^6?=UIyk1XE z=)Wijn9DG#V>b2~aDg7H@?<;k3hRsREeNd(oQ%*@ymdyVoV@B0Wd|M>CoUS2jm!1I%K!}<$3DAw`w6Pb> zeKHri+^yJbgxboEe+#meIcp%-V>aQ8F`f@~)WgFN6Qc_fN8w)dh;2(aVbwgAP%6?! zARI@Ouro^18pYEnN1q2{XT`E5jvXWiLMlZYA@*4B$Z`FJlmZaT{LS4%41ZxHo4M-pEJN$bXwI< zHRrMd_}NrORuLO;XLbFwvI-2bo_4d#C-GM$>gUkYFM-zlUu0ry&M#7+ORPfJrPg8C z@ENfLQ+eUU72?YCqN?17uzI_>LEW0mExT4m@{)C~yM&a#h!7pE?Hw(5tm_`(d>*cE z6Vx0$jh^zsU+q|1Z`(E$e)q39GXluYMRtm=4bnK5u6CCqO@cUG2NXp>NwiH=B0Z9_ z;}!kyJESOEmTV{PfIUqw7RhtIb0zu7Cuif)xYpX;t-&sQ_{5n8NykEJ7zhcszu!Lm zCL-GBY%rkGM_&}VNgx^aP?vJRP3K7A{P`TH0^;gRN_Bqv=MkvNJ$%Z2hFWT)_ z2QS)(FQIQl;8xGzN=MMRczX@6Uqk!oCA@mwhF9%&)2hZSq+A)lM_P~7ajP|CdXxr! zD3X>n6O%x-N=jZ1x zYc*rsHivn3;Q~UDat&etnkv-PBcfqMCKLinIgF{qwn=E@JB?iNd_p8JuHCq0f5(zd zuxViDAp`3``%SH4^F8HM8ZiQ6A~hp%u|o+c#)mOQFcDIvXaoZm)3W_u%0q3Eu0|q_ zBSg@t<|h-d;N5UIv6sfEqq2#=t5an;Y2*^pb6T+YYR z8UyH>v%w=~Hi*kuE@yypOokb-CY_4`&6168cyinO!fcrdvfSMRHER#K6#tH=PXu?Y#VT{whNF|mG zH?x?6$_8g8ZLCQ-8q}V$NRQm$BY9*=ijl{$n4$-`X((8MN{U?3okz>9mB z>vW1Xyb93Nn7+_jvLMy8;c=2sZ+{Vp>0mqewP@t0^1afYbqx(37Cc)oJs>PjB{d4| zqCcAg5Api&o`t?K_NqGNQEsUDRQKeL!%sEN)9ITV*fxzt#U)L=IjCV9t11jc!Hzve zI;Yu7*M?Fq`7+Kz&gzFEP7`hs@O3@FGRR!iV%Q9>Q`)vEp3Ym|AlB>`FFTOEuf7L( zVR`H#dVNPw?SYF%UyV;!fyuEqX?O$K^dfmH+ z?lq1suiwKjxHY|04-SsJO?fLiv&cIscEHSBl}0ildJVV3?P9nVo+x-) z(CD4viuhdcS(zAH8fl5<6c3UtCSzHOB*)zRRHKC`wbl&}m1%|LZoR#Gr9LaUTF7 zGUC8c=*PvkQkgL?kz{xlOe*U4P1t=?eR&H0f zi6(;OA2*vxc7a+iTD!oE7d=&;%zC0co7c4pVQaG`A74VrlG8EgLxra=^PpnS?v)%X zA4cBE*<%vtf2nlphkm;bl!qch=}!IAeed9?es=2l=5FfVTvgQP99V(5nmhHKuUolq%YrBXgcXzK{q)nPM+w2{Xra_&({ct!Kv_xA(B+(~QaeRyZ z_nRRpS)$~;>=yUwgvC~-$eH2HGtUf}ckkE9dJw*RIe?dNCAC;?CyM7W6nrfU4NF9NtCMNU$*@r#aUJSDY1562$z(6YxvHS1?O>v5_){cPr&yPu0Im z@t*(}+ZB;qZws+XG<-jO_5B3@_hUzSXX5m=oj4;|aILp+sbd(OeYk=*Z(#b2#ybW$#YNM@n2CuIv2dL9WEsa%8^QySlmh=>RJUc-mk z&v0pfJMsA~n1{rp^ffvqz(~?AL+5c{I<5={e=O9qa!pfs43W&2VpSGQQ`pz6U>Qei z)e%jbKyJj6)cKm}ge;uEMVY2xeroAvSjAB)P+*p^Jnk&lBIB~uIC$gUL=KrqQ=vE- z5v$G$mB@{}C51D5gBSAl5EyD+ik!cIj4OpsQ81c@ug3p}>;Dq26-xko;VEZ|AJu-I zyKkp|64z16l=4G1|6-7>=2taJKxFHbXFS*YW)FTJ49EhLDD=2w5s}5b?uTRGCRb}t z?^uCz5ME@V84Jz7>q2TCQ7#=+qK@H*>2&(GqxZTmXKcRos#CfU`D&jwlYz%DY)Bh+ zbv~3ky-F8SVodXWS}7|(-=bb!l)S6%9}XIFiOy0Qb>gDte)&C*O3fB2{{vgDfOiZz za!^MP0TF^3HXLN0ZmTu;gIggO zC&)RDU<}u2r>?}1t{j;&G%<0?X-R+y4I7zjNZ1_;h$3`7EvE^Ud?OoySBqmy%s?}x zD05t?V8MA#P(iHg?k@IwPTV0O!oi#zac&xv}( zyjtPN<^8xaVvh^Ws$Cvp+~?SDq%7j2mi#6y!SJyC&HGK9Flt6IfFVpKPRnpyPaeCJ z{~CrQwvD_Fnt$OrF9`pP8XGLHX|pwApfF!B7m!~lD_tV`xph&&9KBMe)LiMZ$l>P8 zuOG?JLR%&vnxGt%1-?v#VR*Tc7*Z8C_vMkjy$GHg^i9* z*iIgp9?QxUSo@4hXW{~>MV7`Uq%>NwDoC%E$j4pMH%%X~qF`I_o&)DE^IYQ(Mz*@a zCNor0{1R-)<^T(Rq|7TIHEa)9(KB5=-RSzyR)ZBzEgdv7(y#NQ3B z-iX+CvG{yq_aZAZs*7@i7GSf2Tul=?E^#$7> zZrjI8jAHYfvHAF?sTpbJc^Fdpi7|zAyKW(RwwP}D>JSzPQY?5ImJ_(J6xwoW@za## zpkzRVjFK&|L}8_C7BL0<4(pUfHkGYh0xt?#RG@>JL3%2Z^UgnqB#Nr(@LxL)auH}W z9gYKf{QUqGC`$VhJ1#sTpz+o?law1~l1>?J;4Dh4BWiNklQy>M;oas z*cIwLyF?s4PvUP?9DIq506kacg}A4Nvuh=88pkuotr3#Vg4pSP7jB=7TKoe~VxSi3 zJcV{TI<=fd1$BVt`Ma{awh*v1TGb#-aAl^x-$P+{Qp8W!@h4VP`!KR5YX0o_CE*fwV z-rey9&rHQ0RwU?ubJqE`jPotn#!oI+3_iBJhObw@US1L`s&W`Q=~lRRx~fmRos@h& zYQ58#MP|c`1k5RX_nq$zGw!1mdw?rxx`w)s2wD@I7wpm8L!QB@%|$wSb}h0%Ie}N5 zg9@z*aGC2CU>G!31Vf9YVL-jq$Iq8s`h{fmYui=j#M`U6uUI=8oLO+qy@2~RK)$OKC{?EChD{uIo^rY-^5dVY{MGXjAU+-9`I?aF*Q*6v?K6XC_Joh|9l{tb>`c|!tC>j!7$qU z<1q}lirAW~1YOCB)d(GtSv$v14UpU1gLevfeHTFCTF?&rE_SOxpzrO~XZPN-T|H)G zcfEQeuyv##t-sDZp=5YI-xH#St8k=w2h$&=N&N?wnBN6=EERaH;k|K~BvfaQbir~Z zIKI8=pQbTl)zw(@#;jc=++EO|?m$_=N9~KKLl{njH^C1>d^tHDj`wz44ZRG^IeYjZ zP2zN)CVj^a2JVyjlf~e_?OI!N+Da0B=U4QeqK?29z>X6qaY#Zi%EfuvhgDS)F_*73Tj)T@P;lxOr&06FzjT>6CjF97O}M8Gdk2Sgr#vb=yai`F!SjPe9$WWy#F%Y{mhS zII@?m{5gui=QA677PmPJnd4iI1@C4;y?qpa*;d7L7w?l(JU)ZroO^56ozQswiW64W ze<}|5)eO^JK6%z`?!$Sl_U81wc6I^7e|0Lv@K>G# zqrq(ptSMMNDdy0s5L5WBN9$ug12%S7zFZ^025`)oK)cZ$29vFsBc}x8Drj&LK>R2f z&cvdPCU6Mb;1N)OX(72%q*igvk?WPz$#Ue3nMZPc*Jrj!(T&`&g`yD>Pf_zFpBwza zNLSrRA}a}$q?5Es)grp1Dda1_C|JOl(;5{PvF9YQ#;%L5?<6$BHLjI&3JeGCTKkyz zkeH1&Nv;NGudRtc*FV0nM{BXdmD{$vMh$Q)agYO26ltStjpA;(8skQWY2YR^?R2zU zwM9yW1f3^g!w$MO1Eb5XPtl6eKB;s4bxpRE;qR~qU96;K-WlBUTu&JHP_Nga2EYFf zVb_{ThYLHS81z)D&~yE{+_SFo_eyMl=0_@a754lrgs-^aIPTYoIt$!#7@9~X6Ht`o z*Was`mQ*#V#Rg+DM$W~+vRXKDHoj(0jst|lB?DyeFZZb%bo zmV&nXXXBQ$3H}KjS$igFcY4kD$HzJ7sn&SQ&n)lO?(cgm^nTg;vs&dCaWjHJIi06& zXhR7ZsI{|U>cpr7T>B^@1zR*HdJA7>RNMfx+{ra%1AH3JQ!@3*L?Khj8hu}BPN~mx z7Xjw>C%vYee4dQNMVWtSnxLN}`UTEvG3FjEcq%(K$@maZy_wUXn!za={V>F@n(q{1 zV2Ed6w$+wMYl(}-_JvOICg!{`CCNuV$;*kcGzfbo!dULxC;O#j`tH#5IM*4uqdZo- zmCEKpDTG-<$e|yS?y9%S57!FHm+fgZk~}xA9m#zgpGr0=pGdX_c1=S_+Z>p2VcPvUHD@MeCMY0fNxO=y zE7cn$o(GT9QH19pgb>`EyRy=0^}7{=PLj?3bqj{QPP^S2z@MFdw=wGUdob+Z4w~3; z`{hex@Xe^`IahHc40R|Ok2!wHI5kc*wdM3^S^Y%!NgjoAU~GrJPuD=9e9D(vRihGB z22dGoTR4TYm*sNBX!dV=ql}eEOXMXoC1wv1XFEj{whDXB!bgqXbz^W1&}@uapZkMv z(Q(qI+f=@|_*GVZQGV?J$_fWM-e%M2;wN-Gs6}=Zh5%Xbe^v3g4lgbfPP@w_35er5 zTD!?gW-7moqBt-E8HHc)6#D{q}p23Rl`Y z{BddH8M$OsXwzxn9J1t`yP9$04B=X99T?`JvZy09CE8vFSRX%z4g zC{{)jzTTk@sSjc`#<`n`Cs0GKGw@Cc?+8xMvboN2xnO=eR-V-&W(>uYqZvKaH@pF^ z2Zh3dedle@!o!dK)ME=?3VF*hSs*EZB7)BH8Hz{@7z&ya3~c~UCE&pn1psM^&Z88C za(zm-qqU`4}~l)I;U93GYx{+7Dr#hd+<*%_U8 zOM1EIvSYv0b%r&KlM&5cDzEF?m2_#P5p+dzXk`@}Z8TuiA2qtrZ=;`;VmAQCiDMoX zd#Whh95W)Zn+&;QK1HLXX>}zU0ZNvN27GM|TF}Ni^BOumR8ta@c~T+`RjD6WEPn?4 z14F=JTJ7bsv4h&)HVJ3`hF#51Z7j@t(C+*jMt`(Yl`tOc{@J?L3m!t_cGUlZR%tf6 z-ET<^LyHZGLTU2yZ~2_>sdz@YuF27t8$o=f8*+I+kB3!#R(ed zr zEhr*K+oRXQ(e}tmVMR+QC3~YmR)_J}koZTlRMMa{sQcu9S}FV&?N{G(+Bgt?=dakC z$<&ZbY|`sBy)?8TiD{W3kh4j9otsWZ*aF;Qi<9J%T&Ms0tz;RDAZgNjxrft3VoST< z{?xbT`1O1`uX($>HQ0qPPgBBgfzvtT62^?f<=e~aGZxb@OU7f$T@+K2xD8(@7YWPY zSF?8#5lJTu_0_T7nUm-5N1u{hPSFIeH)O;UI-?MhOeR?Z#}iRJoru3?i5s!> zm94_*1i~rh3&vt4Zyr%0PyTi@DhrK>&2M=!nM!!tZ2q?Yw0ZCh!ryycI9@Ck?mGIK z>~kZl;NVi;LQlp}Z=d$z@DQ3Wp273OCOmI88(MXiL^KmB(y5elapZZEL{9UO0{65_ zGcppMl?HD#V3l|0n#sFFYhPkCp8h}2N0>v{;WT1A_7%2(7K{;tzN~Gy^@e7YW6J`8IpH!PvufiL5J@({mYj1I zp@TGraWbQ}Go3t(q^gXVvV0aJg3Nig3^|dgpJWoX5mQLU@hK*f02#3yBb-tVTf&hn zhEBT|mdeQ_(<-H$i}hCq&^2QtixYM41d5Oqo&qW{6RedsXkbKuv@y{D`(p0){CazX~5Uz3AR{Wn;4w?VZYny z_`&r%KR6wP-QfplwOY_z%BuC`N$KLBj=s6V`S=~N1<}2_DOmMGEzg5KLxRAXOIF+& zcTK?L*j(mv_gl@16YqOUZtBI$9vn6sE8!j8SSYb{PiigG9RTO0rD9jqI=8{zrx)FX;l4Rx3g*qOG34x zKj>8|VQMaUPR;H&&!b3HTW(R~Zh{wz%+375(Ng%RskZb*Gd?BJwBVj4q^oWNE9(CFlIG(f5AfLuYV>w!8hMd3`<5wyx(k z!v!Zl-f9)0pte_=-x_P3`{2^8Y~#_{X$Q{QeGK4_N>JJ&hJ|$L8-iLb<_dxHqw5rK~;YD?;)%90joc4EYw?FiQ_Svxe&ew99QtVu9 z{{@RZadf1qHORAJlG1u(BNppBM1OslJ^een_7Ck;+in{-5PjEI3=9FgQrunDNbS~_ z)Uhq61`NrS0s}>y3e;*=OJtYakkrMw{CkF6N?A!ZS|BfdC?BjfIdkUBIYXZQUS?$@ zZnqoIhT&X{b5I{f1c!pBDXNI#Y$$ER9F^u$z%PF9JYfc>Qayq_ zb~`0YKCmeQY~#37HZvKOp!J506~`Q5$b{j7!|7C4U+4N`&Z9&YueMVZPGOj#T1Yvu z@&1z%X8cnm&{P?TEFTr0W(E#Ao!@>s==}T=hJW7P!0BSKh&ItTVh??+g@Zfu2)AYe z;p>YY934UD*Ozd3)PciJr{z*}o}kdS)6AGsAII^On`}0=;IX5Wv$2l1WQfPP9LELI zhQ1v{f{|GoxENl+ZS}v07azba3s2}JG8K_`w$a$jyp2woapQk;|MTXqv<4WEOibhP zTHKL8JO9BcNOGq2wojvh8wEXD&jv0HipleV_Z6Etuag(ybX4%p_SDe0k9A@ZH}J`u&U6gMP94{1WU}?d{jW2xARG+(WK4ny?n|?%;h3 z&d$!N{#rFkc6lw_*>^TyzhnA!*EC!*@7I~eo_$8afU`2>VC^t@m)GZhUFZ&^fE zt8V{x^?S03wd5u|Xg%GfVhisE5hv@B6(h1~lvJB~MYWcmCb`sDJNQxCuKK-hu*DPH|To=7_Pc~-I-WGr4-uT8h?OJVf+DH=q&add(@~yye z1onE9y(A>T1aGLq-~*h!l*{EBU;tHw#A-&yzODTC>**O;@3NiE-F;boaHL_n`{|y3 zmGb7@cD=1N_xEeC51)7-9N&Yv@5#V-A>dm-kT7F{!`x*;z|s%k{Nwp`*I)37=PZ{z zu#r*`<1*YB20xp%_j4xs$`9^9{Y)!cHvhs_93abwer2ItqX@iCxCayN&hFsNjC&g< zg?f0u+Aznp=l56M}>Rof_&SvZK4fkXjMeUDT zO~E0jQP)09*Bm^y;ovVp;=OU49fuwBBsd5_O3P8E(vMto%Kc~j+v{_e`grmfH{Ic1%~j$VE)~4Xs&r2Ss=f1 zj|Yl`!IlNmVfQIU0A(L7!&^8itqI)1 zVt$HI#M43Jl1Kw_hUwD}36lwhRiNZbUouzZ%#F5T8*N6&TqYFs!#O@Mh1D!7k#>el zHiSNm_XEqoQce#8$@Zh3}={YVHvr}$~c`;S0}J~Eo07u z`-KP06>m(c-Cp7;CVwN$?O$57(ttnWUnmU-43a&$cEt0yD=tsel1jdqa_a`rrKL_p zWmM}b3TSm?Mi4diLyfnkIJp*saOkv4Vvgj~pIvi~T*#;C>s?b9GzlQWXc8 zgBV@pxyh7R6)pFYOj&MJy#r$=!Pd1sv2ELToSE3RZQJ(5b~3ST+qP}ncJk$%?|JnL zs&{wwuBx?nT?8)>;P}HZ=Fjh#vpY%57Yj zM!_hVcx*{LYh?v#!P=YNd$I~F2O`^0Y*4YcS}IccDSFwvS5&F@d#dlO0;X1OC9W?V zEVN4&;k}Y%-4`vlf3=ABR}Lx?(8c~dZ!_tz@5RNPx4+>LDDuU9-%^E|#teSEB%(3y z@__GDho*IW$@fu?lu~{!N}awcG5sE0z5txuV88C}Ye|C zE9sT84WZw|`?QR9VC3$+=N8y5=L5>51(){%(m-y`a`H`r@v)I8k6bBb%8P@udbWkQ z%Bwr}$P%=gAhz>I1>>L|*_35>g3_@l$^oY#Zm^!vii+CzQc?bh`?g1N4!HUA zZ{S(QQ?%)&w-nJ;&R;0|IE{R!c;R%p#y6ok3G>5=q`HzP1a`G{cxR_1Jxh6wTKzO#%xiGZvtR2wS;fhq#^*1>sys7yBP7|pQv zb7PpAX5N~P|2e3hmtt(xCP6c;v*B)rhustLdCqUwGq7}~D2EqS0epCZoRLgSQAh22yE-vup#Sx40}g_-LbgI1%8veK#f;d3InWO9 z7$~vM=cjrwdcr;F!Iv){Z!hYk9ZnbmO}2EC2m!*gaGUoLV~Ywx%|H+YxMjxnpqD7f z`zE%SfZ7qjYgP^c;d0L$zq}<*Uk9l>kN*KaU%Lu7Ck|mj?yxS8J1vCE3C-5Wq*AQO zh8Fc|Bs$KgpW(KjJl}s?CzhpXABdw-5_MkHij&>CT7BXW;tt9ewHcxT2WNx?;iCqXDe|J|9o#qLfYn} z+~Pa%Yw?B#_u__)Na(ujxomGN=QouPb$W7^inNq{z^U09R?mqNRs4w33b7mrQ1)9s zzv&tQTxIx@SZ5VCpz0B&yv84k=4%P(xke}}^Rak-3xe%6l40a2NE*SPX^}0eFk=rV z_H-@<7klf7Mz8GHqhZo;^+oad0JSZXDC6l{m|H`D_$&;9>2oFhp{|%g9vw4t*Snb+ z)2oW%iewgzl->}C*`Bms<>^wwm+dl&bJP4=vHBxP=2q4CB1N||FV`5?L(#PVJSu}O z)xFzn?0WM|b}NigcXGaG0z(bDcC1(1G}!Mg0FUd7^bXX-X|1G{Ax|+rvF!oRzWy=D zF0r04=I^vJZDh*{)%n-H*GDENqrI{25}KF9?`x(84YKT|`EcRw#J^n@L=1Vfige$- z&p;!m26Pfzcd zabz|n&n7$Rx@r3d&~OGg;s~BUOp^WVi82F@Z}yBKbeuRir&y4Xl7oryG&vc6Xt~HP z89|`z**S;I_M5zRx#zG%dnED$}l1bFCGs+0ML{ zu;_Tst*`d?xHGK-oL!W;K`_Bog6H|O&i6QYD6)xEqfGO171{)CV~`jHlx%Cm`2zMf zb`*H#rAOEjUB`aBr4_6mgZ>(H(}E6cWGo5bL+A%4-fxH*9@yOJ3^X@wWJKk|tfG!g z;y>9Cn0}7HjVOqSei_tY_TScXS;l%;wGt*6mkB&8pdVcB=lngtK0stH71hIff(h?$ z)qilgCGBu!HDLHaXeq$;d(jVc!MMap?Ad`%=p@p|KXfF6G9UxS-;zH#aT7W9bsk+C z?OhlW-Oku(D^!oPkDC>#M}SrrCB68hbv;i8!PPB~0bWc{2a zMS6G13E{t&3b5fcWQDDUzYhI3BUt)J5`?5@K`wORWpe)!>pES>VL)8D#s|51>Zvu1 zjK-Z)9B?-Zy!%WT$Ic7E0g4IJIk^^dwL)Y^O0T zkKIq!xik5ub;{> z=z9~HG8bZ|zpvzLLac{VM+H{ajB9bU&T(_ccGwPZA8SsT;7j`QMQX zh!NN0yge7k7zI~k;8AxA^K+2y8e#)iS;OaU8_3Q91jM$IUYDYnnwL`L;6G^H`Vr;? z(adJPDL$CD=#PH3#RQA?H%X^rA^z5G*-wc;+u1d;uBMaHGKTB0vW5~%yuL*f!GA4* z@f5|9_qjv(n|kK>nH&4x^xvY@?T-zctH2+&B?b>A?T@=f-M%%>4jWeUuC>o!AIggx zajQYzRcd=3AtAmGRS>4v^y`zAjSPicOYo2zP{#Ahj#JXC^p3u)IKCj6@zS#W46wo1 zpJ+uCEfuax)XM3xF1sxDspLk;G42wX@iF3%x7+6Fg$$(dv66coP20or7S_raV!+@{ zzx2b2-m9fAL=HsPxnt5h$@Uc|ugz56d{=cP2S; z(zsWMvQ*gSPC{Db;k}|CHpjc?6)Z3OeqLHytiiY*9L`8FN1io%h`82}S!HkhNQ0?T zPYg>t1e0Uu4Ao}w^AxNx75qAqHTxEpIgY@nD37R~Ma@o%)0OOJKpotEriupBU4PZE z%$>mKZHCt!icK+k5J*ehT%RQJah-RekwIiZ82#*Lf88u#;D4@s%nS4niDi3_tvGv2 z?I1k_wnqbu;WV-yKbX{eR4gr;Oi&-^q}Gy{Vr>L&VL4H&6x6yYN_m{Ln?ck9GNS7) zpRE3UGA#G5sN${3T!sZ?mpL8-zvSVj;_my2MZBSkxgtTfTpH*BtN*=gvkP`2$Z=}~3B80;(dOF)G4F`*sKfJXujcyV7iM^JS;72>qL zjapxTqv9BUJ}_d?^H;d&Q5jNXtVsBn!oX5ES@?{8yIqo@C=W&6cUEkJd_bTQLesTX z_wy$EyiQ}IeH^i8$jEG(b6u^@n%>PAU0Un`%mYb+n2h4g@lDkR7sh)YZeE`TZYhbp zUwSBrCP^&)wnkL2&<%edw4=TdiM&bxpK_-0Jnx?|%lj&?O*y?=n+X{Tj6K%63Iaxe z+p50nndBQdj0U4ek`{M*3nw(2Tg>mVcQSk?#bfm~*~NLMSApO0pV(jf-Oih0H3$R$ zHYq#~(t6;XHZh_7WLWnBwue~H^?!^{FD&l|5u)OHW&S&pJ)!3z)MT{?%awY8Ts8-c z(_)ibCMccDI4XB8p(a%@=SUswF9yE9*%|3pa>>Fl*&&6Zvs4B>?gx+~EP%|hqA1}# zT_tQ?5MmyiwxrcBxjXhlEj+J?SuVu+WAty}Ih2Axs5M9Y5ykWAiibYGNL9b$ntNx< z;jBZrEn~GZWv2q^PgZ~UR`DEGJoAtQJd$K zOKhuYmZq6Z?l0r?KAGPSChx#08A9`egK$X&hXRVv#ZacZ?eD(!{G{A(!xr~o3gh`D z`}q)qu3yorb0Ioe+$zlpl?L&-u!Jaun^wcLrCdlkEB#-#H?7k2z&cxsGgG~7dGOOM z=$_%!8tOEbwkcf9^G7{Jg)`#L7Mly zD{IL@J%}O{8bPZ}b{|a~AH;mz{#Bfo9vmq*4%J?^?;GWK$~De99#DD;bYR_{gF+{{ z+nS;KqC}^N`zNMdEYVj$$!Hj7k21#waR;Z^)QB$$Hx5s%#bm!iR<~u5WfBqyVuf`J|JP*x2wyG% z0Ys@q;80mWa5xhhlu{e*!8D3pjCG-t4)_k+r-c&Fg2{GqcDrV01=TIqlJ& zqn(?hjwrNl_mjN`-G!Wt2S|q6?gvjcFlmbldYSzhz3?h2z8y*#}o7ic?Nvu;{4pi^I!WQ zy0C=I%4DfVt>Fp-JfLXrn~WX2qG!wVaEph4U0o$q&)WRD-sLRfMO;2&;d2oKIaO|; z>l7JDVU7N~fHC>{MKe18}2AZ~y8=Xrc>1N~L~i8)9ex z{VKIG=+@gH4v8!3bt;gv?)?FCG2+;^ok7h3UTrLwg;2e02itR_ZS8(VSTmV`{seLyNPl>P2>Is&sqXMx~1+Ry?oC?C4J=r}^@^J+&CC zR5~IcZCgrH;5NtDDt6zXJ{UJUAb!eB%Mn4L-gXeW)`ox4@ft7%BA_0)IG^k3OagX? zh6$P!IKT|4kkSZtrLB7L5G%U-ZiD<`(W-DTQND`DsUEPCiSRp1Lq&C&QoTVc6(l7= z7!kX!t1*+gDgRw*@AnzdXLTsi7ml!`x`4E!j0z&``Ld>4_csx`F~r8EPI$!-31DG? z8^q|~fLD9VA{@d%h(bU48B28M5BhPbtNsBSAj=R{Fd+0@OnF`eDjV7%1w%8uj*p{!-A@8_+8d1=#k;p%hP9uspH+363N=`^sy=ZKc zEEBm%WokfqtjlOLp;_goZoC4_ItRg&xY&=U@6kA`h09=q!bu0&;ph$vhI5c#MO;UE z)G@4LE`Aa}h4GTNPD|-MC5JbH{Nag~y5HR{{8oQ-;!W=;ndVVY{P-0V$88JD2pjzT zj&>E6tIby1v`d-;0|Qe6BcPmyi9}_p8rJXsa@|SKLn9PCGG*EAoHNutpc%LOn<(5Z1h{bdG(tvlv8F)ARLmHA1AWE z$)W!AJ%W?BAH5q+wVR`5WZ?%#i*lI!G}YDL;0%ga)7rBHL{Ue`2|AxYfHKC=eaE5L zPTK(wn&08qSH@M6x3%8Zs{?`Ae?npzxG&r?bS+{wg8z5Qd^?w}CHq^T{qW}3Bi1?I z4s#h@m%Fm^#)nVpCs0(pwB>(O`zxBpiGDlFMO&-i+~thpI9(y^vUI5}BgviEso7!d}6E@S8^F0c?88K+}+U79Ur*uxEJyUSIp>nQ^Q3 zRhyZx4scQ}&4S3;Us&Zy;2;~s2EH&3kprZ>@P@h_F3t!(h*;p=fD896@yq7`{-^Po z*g;ppMRADXgZB$1tkZ3$(+d^VPRhpcK&^cMl@A$s>3>UKAtuztdG* zmQH`cxOgaZ=kMcMif#12^flj2^4=v8lLvQBLy~Qc6x0sY!T%XFqfQYhqcgMqdU`I; zEW0?9Js4$;QjoL+{+ZT{lPjQgSmGv)!XMYtPeJH! zBj!ixH{9f-q=&|S|G+HkdeY#g;>pxYN$g(rCMh=J13dF8WskTaDeeJ34s?Gm2QA#| z-83r7=yd+vGSwi%N?agP)|_Z~a9R*eZkTrJ;@rY=+**HB9UQ^(=&2 zs@Rt>>a;1K*seGrz5QKmK$G!gWZ973@R}7gdxwo)V?N>kB=<(xv|Pc5i88@CfKu+0 zkrC@0M$${zZ?Lt@5McfX${0F#bjKo1fEz1{+6yuy9LP~P7WeJ##UP=<^}=jj$+^z# z1>)P)<=GOLn!Um^KhqS_QDrT&>NAGYIg}^=xZzy$9t}57!lM8fq~4nV_8TRyYI=)2 zJ>#>>{TilHq1WQ)wRK*rO8w*p|0gX~et)$>*P*`a@`R+S7$Bnqy$KR#hSZqaDvAUl&si zaXz*qrLD^S`>I2egfgjP7(l7Z8GMASHk8e+nt|#HO!y`^ z$Gg)SE9&BqSS62JO5yxb|L<&!Ujyq4wtiV{ucE8R8Ll-imFXnjM7&r0kpv^Ak(Grc zrK7_yQWBKdTB>-Pz-xWsmR*L4X;K;UL^at6$ZSY{$qkx6ThGIXVpH`ct27l4Hp7IL zP`4Hv@ZjDrVn3$z2uKao7al3yay(N!vI3&d+Q73b1Uv+0uAAnPf!Knvi5p*-j$%jt zWk{e)#G#fO`t`{yHR9JtZJXQC2ER72`_@L(=nEJ31VPTJNFr9nY!AonKeLo1eXP8cE_< zjLGGw^3vjLYQED2a3(D4583xq)&|F7-XuvSSc__KrZ(sRZurnm?>IMu4j%AEDmi`K?;>sxoaH@WHYnIIdu#Z0 z#EqjecmqarKHIA?()2IjNEv*e`ga}$EQ_t}AKB?g%TDq3-@`Iu{G3?0e#ww8t|4RF`_v=da42_yhP5JAYEsoS>&!rzVXU zZ%)XZATJ$JqO+?4#!~7|RW8v%x2ty4EFVIUheHOd?Utuuky_L5coZ3Czxk;h>kpgR zoW`5F-lAEFc?_=na%9#Xa7XA1-UHRtE-4+1Eew_=%&3TN>9s0*0YvNXuC_Fu9P{^PXBQ_=(X`@=<7BvSl9;&7!aK6?V)QM3HjTaKC!p@NM|f zbB#t)&Sw1mCLQQd6tLSsXQ!h@7?3&0>~Rvu2AC9QO>A0G2})r{dn}IjxO@uP`I&Zh z1;fnjc8T?Jty>z`cJCR4p*&IJuxs!Wp0yZ~5T!RGj{fc!-@M7#UqA#gY|@5YewiCP z-IcER$4}oT6~5V7Z5Q)Stgn0RuMNx{d`Tw#CG&g9R2v{w;83Df;s^Ox%3utTvauMv3KsmPM;VVG96$N8bDg-OVsb4B$IfhX{>=IvzyX^7oA4Wu+ zFq&G!K(dG2#-L!f+rR*(o3wn(6}6RlM4a2$SI@jt=c6I-<-;jPVvgh;;_sUy^?WeI zgK|HZ#8Ir{d!E!|!G(_j>-*>O@~z7F|2aZ>Ln{(pE^Xz~r16D{+oiWip+HNwsY&dY z*@q0x@BgvX58WIY{mT6KvMQWWdW^cQz#Ii3;jEWh-pXaYX>fO!83#Q;^-EeVn=gK_ z@cgb>t7tNO3Y`MgE61cprg@lIQ!%h6R6ENAzq^7|!JBXu{wOM=h!#GKi8Z*eX|*^1 z^JnE!#`<0tGhkLzSh}18_8^}_wa8v4Nzfalyw;Vr=El#8WImE)W<>q1-yo~DB|&r4 zSsGMQt)tw=K0Rd&Ia1+|ST?aV0>zpbSBmbA#(V#^QU3`NWXbX0yFd$dyAAwu@0MQ{ zX-sk?n#b^;_!Xy8aS<=NBm*y2`@%j?L1PCn%F(sZeLtV!-D}Vz2|bN~4TS#^V3<_E zwh;x$@T_YF`t*!JL@ZACV`avl_x6cbV~_zJLO(sJ0)S%h{}XkQ1{3DdM1&15-+U-` zTyOl`v+29`ZjvP>>{UB~<%iOdKq*D;TY}sBONIj$$l{07K-%8l7qh>n@vY+Z=~`LZ z_45Gm{yz`k*=2A5GB5`$9{Pto(IwEJRdaXGUNZW3T=%npSmb;s)s~d`UV3L3h$XqetREnsFjff^*B1U8{_nic*9>*mT7q& z8)D<`JuiPOs(ATmn2tao*{~CJMIe%Y2~mK@DNgN}b+P5k`N3-m^^eW!I{JF?QCYf4 z=}8)K!05!ZBIPJxRJ>97Zj@e@Rze0KBQ0+?J|R9SIU!A}Qn#=03pjl*exM_9AP<#N zm2qu#ka2(!dm`XmQ7ph*Q4AoVOesMNm;^}tNYv%wQ9);mqAAAtF?)!dbiXp=q%Hm{ z+;9voK$JWSJC7px0VLWWHv{ERE&ajnBI6DOs5(83$L;s{2!(LWMLe#(;|q@JD&zd2 zgQ5JP&~@wKhyWFL_&hVcV`>x7K=xt;sOE6a_3wW+FCD~)xpTOyKR~cx`0zp({ z?Q+o_ca^2sM74DBdV_#_wJ_aVR(#%EvJSdO@PV{0lp#;c0P~B#ehHGUP6)u-565Gh z2x&_RqKU5u!!Wl9h4H=NKRGe@+C6-g=Wi!{?Oq!sz7WEmuu$D(BKTZtd{JNB%T&G&aQVkx^V4QX|UKCo@apm`lpAey^V&=^wFiJm!tJoRsl(LUNwl$~Cj z0G{La*IkuM2`5PD(aOahqwZap{%Ac9&Zr=wgENYoR8e_JIkd+vx!ht|F<&rlU6P}prR|%S$e^s2J}&q z%>{G}7!PTLDA)4&s6^MWtvMdhFFdaU`iO*-WqqzqVn$k#s zu_yVy;}k9h$>AI^1rCFmDbb0Z*+wRIXU!VjPP+XmcR+f7qWY5oxhn-;tmyzyr9k!B zVRHI4Z&CfJbSrR*@c|T@V~~6-A{$LPS&=<>K|r8iW1bqW@o_F+KO%ykzc|0$-^0|u zH=#v24x&Xmh6W`F-JmuivBavs3B&aE7ZQ32$!Z3@fLib2{^F`4#WhLsD2dW`j%yRT zqoI+noz$Eq3)$FOdIaFLl`1+Vw|P__8u*)JsfKawT!4)sRiR+eLVD z4!s+7V~ItQsoufu%7WwU6um3oo}weY#&%qj;@I6OG^SuIudLIwxY{tM=l2C-`bxOX zrOYaHNLZVxq!cBuMr?P<-DM7xGKzBvkCyKS`G_Wc0x~Ll)wzeqe6tmqO}o_qNcScu z84jwgRjKk3U4lSZ!^R#805G^EH0fd|HCjv5Jn8N5^Frfog`oCo{&1?z9?XBRp~9Lp zLKuMvxqqcw;j}yQ1lRGZzI#XMoAqD2Y+j5iW4@}z+Cd(2>UA9z%YF%6^m)Y%9U@uS z64hS@`Es_!fIRyT<@YX4Th6`yM{4~^O|X2|pU|`yHQE|3n{#|8bey&q3S)BC#>^`! zH4Fc~KD8*|&U54lB8@d=ryZw%I*&ordjuF$_x4!rWTBE0CM2g!nB&pEM}ld+vEaGMDR4tJ zPY*6$!?spU&0u^C0#NLTVx3D4VrmMb>k}3IxZm(5%XwQ)p`P)W0lWMx#G{F~dTon~a^G@q#Z> zEsd-k8jW8E(mlm6Hr5EFgapoCCV$!bttr*_@Z1Zfeh?~Yg}H_V5=jp@r_qZP4pSYn ztSHLx-DO>X+*NKc%_V#sx)bUm&EnZX`9s9=0pcJIQY%hW-xo{Wj?>Y1pGn4sE%T{H zFBmJ*-)$fMnkq^CQZajey6XLGwM7RNACq=-TaaRS?w;cdGk19)>(Sz>6G4iilh!oA zH!5EKr}%+5ynRnKMZAZpeY@xq#IE~9&g6w9ICn4xY+glL$~1UwGha0bhdU|QB6;Qe z`WHZ_2pC2!} zG@jSVTm^K%-|beOAV9G3Pl1S#Oqd7sgah4@`p6rsZw4wx(&f3CGWcQK00f4Y8=8C&^ zfcf#d|2o$D6(~{GwBl308jepdGQI-(nBX7D;UW;-Y0Qdm!8%3)RW(v9Tm~V}!yTv> zNESbX_-Ez?DpYT;CnTmXd`vP#~Nnicsm6f?CWN}u+>@6hQJoN}l^h4{Q)HVK zW1tDXTs^9)T3RIk*#$6K1`bgg^YnBR6_giqR42|w_Po*unS-Cp*$xdYXZ7-jV8ADm z;=*zW@h(sK0Q;4m$CC{mCui|&6^e#wBYT5`u52Z^cU0zo4cTh7*4SDM>v|eF00OT+UP+=3>qus&~-;} zRm_r(*BzMF;e>gf!5@LHgLD$i4l;fw!+!}a`x3x5j388*r+xqz#{W;1@tvwlIK{u= zB;P6E6mcNL5B8_d2>7uNKb4kNC=T7;Wclp>vk|b8%+mV2@i9e|I@3`ai|eR>!gh)( zvu_+lTKbo>pUt1t%`7w|7|dZ%%B<-Y0Q_yd#E3i*>f_ner8}W|@4ONvP)iZ0MN{ay zBN6xl1vi>!l*l7FEE%S^S={&I7)*a0;Ip2qW=7@RTL;ZAE}-`Z_n>8WBcSYP@{zfO5{)amX3!}vZY_OmZ}bYWzm&W1#DOs z1KFVUb)R7L%WamPl+8oDB{!*?{gjlwH`t{Eh+>Kq9dm`rO;Vu`lwdq*Sl6&Uh`s1$ zUxuD%!7~X*AHuV3Tgl)%v-YzuqS-%ut~vDw5apO&cz*^&p=+^E3TF#_z zaIL7qWg+!Sr+%L8$yVw5hS4P#;`enGQUc|v|DH!cXR@j>OQX#6UE>j>l4|QnP-&Wh z;vMN*H5ooS`51;Si&j_-E2`gr7=tc4IhhJ-~@-iO{8oW%_%e23BgEbjA&7Ab@#Tot}wdF zmgY}5`gPr>?sq`{cjX>qr*2EWR0)o#rH2$T**r~ZuL>zl@esrh@jKI}B8Z8Nk1ou* z^XXn=v=D6;5dwCM2^5Vbvltlel<6T|{{jxU; zHP_3U2rZF^|8#JYGq|8De~CEzPSq{2je2+AnT7L3?~V)<1F8j$sWxIkR7@IS9qDn9 zGiX%4L?_^FHhmJG@*SMAqM)*-h`+ew@IT_*GD1lbR{(O^Y{MSNo$#A5H&!+(d#b=1 z=lU$o)}cC1b_Tia=z9S+6~r9;4n~%x&sW$8Gf$&UjrIsZY||I7RKI6a8&|q_D)H;D zpEvNI;!p7PJIxR`mDn?#eQpEfRz$Lbgj5kr?4+0pap*&Lx(V-wN(W2v#B%yEULGKI zK_8Je8aNasX8JK4SW-%aQeXye$r|jH5*@E1+6D5usr=EQe&e6npZ*?EiLE})fA%o% zomk^Bh+=#Mpd=$my>62ol*sLygd1AiMk59)Cp=D0Qn}MINpWw|o~GG)j_8?Kb{`l9 z^3yEjIACBpp=H+!+y#1L8mKOpRvN$AyL>6Ry^l*dq&@N@wnnjT2)34QUL~d6wE?<5 zYGV9dO>vl)a0l$(IQG8XY8@7IJW`sUzmgRGyD0t0jFGKExoPdvAVdl`@wfmT38?d{ zL^@JVeN#i!pF|r&-k{KXW!|;b@thKcI$9*KA2@H+W3IY4COcY#GQ>|#ZN&SO<0-GJ z&{t;YQ7@exFI|VnltKvWl~bfdIHuyo)S-`&^enBNpX6^3ROtd?7AY_u4`5;g9@0?T zMbxMZCkRez-;AUD5C(|r6P2D3rj14}wlcfBp%tpcaI;Swe2rcJba!=dI^c*a_MEdY z%(FVJ;;m4Ew29RCYAB$u{$)`}_QG1`H6V0U>nC4$_X`6mL@wsuv&<!s;5i!cagd+KADc7F%3U&#h11%A&V#t1OoJ@~ zrf~6>%}8V8?ew1AjGWaq(crc-v5FNWs?X7-RBLxzO7aQcp&D|3fXCh|?vLKfKTDkN zSatk3gXF@|2JY4_$Z-+9dW=;rz@+L}suS=_&~Xy4st|qws>*R&eSW-t)4{afv>M9$ zQqG=u{&)V=aZOO&DxmxH}{CxmM6(F+n4h2RbrW z{1;RN-rHQH!0O6B?F*eIFgl)s5rl<# zq-5Mg71ZT6v={^2CE0d58i`~)b6+;8m1@j@KMmc0nOjfOF7WbIF|2(@&kxW?pv;cD?{A?g$JE0AL?h(dwWlX? z15#Mx?^i3xI)I2RNL(nc)GqMBEu$P*!}a2{G_P%}$P0%$7%GdjM>eBBucMI>Pv&$q zn(hIX89pdvDbhaj_~>NQcEnLm-Z7ER$e7Dvl5Af=1oh9Kpd;tT<0l_^%w&Y#lsWF6s5sW?^8e1BS)QLG}e($ zvSlNA^I0v{_+74B&65w(Eu^^68+;;G z^;%a>=a8gdYFw7ZSL67}*ZuhA$hqw9NcVgZBQt*c|3Ch`t7Z&B1nF-#(k8OYQ!+K& z8^f|Ez=D`7+!+dHe79@Yxt!Y(j{k5ETiT~t#U;?}eyoXROJ+7dACZ@uNw9IMM@!Kum}%kd-={$RSd3hDa?H!T+zpb#60HUF|O1>~sh zC;K6Q3sk0(o2^7;cdA|dAr}P|l7Es>+RQl;8I8T9$xLQN&DgpMxq2Rg!0W{63M?N- zvlywnSm`$b2~fB`#P0emk;B^>(0-V&KCJ-d)Eq;Zk##_;(Vou;`IJknPUx=9HZ^vK zZudx){))oe>qRLT-4Q&Tr7w)*hUw#j4R-Yv2EcQyTzSx<;-L!T4ituFbcPO|3tv@* ze{ZePSMCs+j4h{gkxI#B6qW#*p{Q!Yl1?}!+j65@`PFtlMKmxePWWsl)T%(2^Pt;j zjj(O{NLhCYIF39En8>wEr8nhX;Dz--1e?o=r6hZP_O_T;_DZxIPtij*$x>pi_XF?Pz@c*YDrsEh*GO*0S{0fnnn$O=6DOrJtbxTe%nzfGA5Bk>ij|{ea zfkQ7v%w=jO7W=YN({BzHs}UfaCb!J0NMY5yV9)E(kOnb66?`@J$`1V9)wd^`*9I-o z28;9|L&%}dC;$TxE+eJoDc&P7&$^X}!;@qMX;d}YV$>aZERIZZdO)qIaa0%T;opt( zW_~Fq{*Wyt&z;P8_nENZH4V@Y20sw1T4H)^pY8U9V*!xo8kEJN)9to!@$ z6XI#mek*XKUQ;9eRuVA+xw+1k2kO_f26(KHjLuIKb9`;q11uOt1ExrB34PzS_OPNa zQ?nI<#w=4&f;_Pr|48L7I+NhYu?$A^%+|<2^Cgls2+t$QT&X^< z9|r^G#MR;HWaKhPQ4tBx88mNV*WnRRUs zDcJyye~_;{^ucuEP0t=bSWS^$8i8{;zpF7y)ETg|I=YM!XMN$Ib7{7~jOpbQGe(K{ zJ^=;g2ocUYLua1UP~E`Uvt1m)c73Z6pBGazZ@=He)TtX>XP^W2ur%fm79a$IC}Z(| zFK02^LN1BUQPN|%!LuEYgt+6M`MPh6pS(%6w7zU}B8t9`@t#?yC-T#)<3M%)-@g~E z_BsuHObIm{_VP!(m?H1zOH2G%K|KDpNv>GsKpo&Z^whn&a%@E`!(L`GpLHPXb)Zqp zlDYo5DKV#(xKtnv{7IxKEI*&gl`3m9)|TO^+|5i_L0jPxY4my6H%U-XM z*D1e9Mlk*Eg;Nmr9oKV@tMQ{3PADr5rg}_$+1(Vo*PBA`qs}J_jQaAZsugo2^3bZn z7w{*cDv)N$<97{0))yvc)egi(OHa36$h#RBDUNpu@hf;z-2ZHSKhdf^)rD95cZ8dR z3h^HJ z_Eqwa$xQl|DDAUVr9@9;G8bx?XD<(Cy<8SIe&6dHwgoPXk+aoMWB5 z!JtQEPQFA`qKV3?s92(SBTvol8c%=d`MYA6#WL0W{;1q7Uq;u?*jlQ^sZKAT=2?aN zFw*3Ak5{m4#MF9aRqGFycqCZu00nd{>j(HVX1#18X84`=U->XwMmFqrD#ZBpQIKc6e zEpL3l1p0&s)ly-DG{-=DEePmSsQw)Oi7j76yCL;x1>NZ+5vXG&>pFO*7XWyrkInKS z%spLk+<$q3IjZKk5ol%G#cs#P0$}*hr{&I*H?1Ljf2f%y+4Yjp# z(Q<$bWL2;@c3v-4Q#rX+L(9uA~Q-8aKiVdyMT$GD;{bSm-XHR{5*u=r@c8>R7KjT6N z{EW*zH~=yLgUKIHE}ga#Hpt^jhA^?dbJgxE1RGy!f_bD^AN@)@I+{=J_MlF8C^#$M z!+kqVl@3f};VALnVRdb-m!Hx-e9TY-I$5S82}j5y#W4o*%?^(QU^916FFJ%n^yw?2 z{o3B%mr!*Z<7NLN1r1(*qE6RAfUOGO5U$YzJXY)fD+MXS7Ko2Zc_4MSf7VyFhhy|+ zY#Hh3_@F4HRun+c1?z&$lLbnqxD1X?C$UD5WEViE$eb{t3SL__jDa!tp~0 z(sL|Ch5rj6a6O)4nW=YJ+VCkX7ZZ~LN7jR|Daq~`|Dd$VT2x`vg{;-u;if5}6RnZ~ zXrR>&Eowh8W~cXvDo#JZ>@78u987lee?d7dP{?Xk$oNR7dIKN+A2QB4so@Bc6ldpC z5mo0*VngP*Jh@2`f_bpKl^-`_yllLnW9HX&GYuAlUdTpu@jQ%(hVRj1`RFQ!ZV)6*LFVP%Mfu9&wRT13*ktN$~lnLPmsL5L~S!B|z@#$W?y z*mKYnaX^c z-8SUrj?Br|2cBNXWmmX)y{@`Qd?bim)xePHbL`nPEbKmAhVr;;liZkfZToJ%Tl_GJ z*A)BomR4wl^QhdfxtFuW?ixWcE6+5e6yC%y;~56OY4%pS`&PH;)HgG}kO!z# zntlFbk@`)%*5wVs@fi6&3#KaG&Or6yAdcp^qN2#VuUE?u8~yjtBlBWE$;5GMpTP; zwrK4zgFQ-h4kLkz-hY%MP#2LP)^gz_0f*w0sS9C+qHQurM-sUu8O@R%qVQIPO{+8D zv2oy5itKiA%f?qS>Y3)5m3KsYGZRawih6>$ht*5!^Lu<7SLyMXL>D;$aqVB}BbmM@4nF%vWca>Y<{6qObV> zQ9HNnl^1RaIQeiMQ<*EtyWl$kYN|-XRXsZ(V&AvvCB=+>m%qUe3O+pm!c z-XA?iAQ(m{ZB^#(B%4 zNG`ib87p$GYhP`HdJea;rh;NaS2VVml|Gly_D~I@eC&rtxLBNy#;;gt0&aHbCy~Is z_INffpZTq;^pT}XHt;CZiQJ2KJ&sXr_A~7gCW^Pty1YD)s^)a5~Un%*Xck7wDp@wJo;jf4u2a5S0FcXdyS283kBU*y|KD)WRw#siSLL zf!hq$dai0qnV)@crEYSvMYBOo7H0uoZCs90pI7y7G_#JPP7VryC>Uf4gHk6DPkiYj zLAXJZi8~gcbg1L30eGRLv(P4MJ&)_>Py|tl8Iv;)Pyza(u+L@{q)oceYr+8Bsm9e` z1fCLfdqF8Ae0amz;YpI>VBEH_Q~HT{>Xw;3dNvWuFz@DM-&ZtF$G^k2gEaKPmziXk zSs2v9wR8a7waE|$yuE~I=U#>fT+TNir}Mg=)7d=lt>oJw;{cFp!`>WW#~AT#7*i$@ zZ!BL0xteo(vAb~rUrb+tSP<1%Vshg8$AiMPaIkJf^Zu*i6F z?Y0M~>f9bBigW=8vi0EuCPb(|OJif8aON0Ih)D&*L4qnjfJ9V^Kp6@RBtOv1*fFLJ zjwE>6R~hueK1hclIjFJ&0%Sd$)t$L?{)&hOjb^8t)a_q+p;pTuUp3qo3DH7zvrYGq z+l17!FP2Jg6Ghve#YH&K3xB-&2w{tkm5%H=LW_>Iza$=>(3m5>`VHT0+1Ila?8>hx zAq!qA>{c5q@;K{vUBL_fG6dx%xzm0U*tUP0qa+1D?0_?)qRTeZ$%fZQ5L`6PXxPf- z#@!BNuZTMf$yBuzG?OuxJ*&d8@Uif)Vp~Po8vDqM(4ULmu*}~AXXwNxD>?Ql!%QcW zH2+Pe5*}XYgV_iKlIbX|p^{^zrZ7bojKC=X8cVu}>&1xSO|g*9RU}*L98rP%{{Wsq zVZT;vEG>P_Y3TLsde5fdFe^lvMM&6&LryP-hsiDJYTupBr6_rDmLByuf4}d>aPl zcHsWXGoHM>9KU=^Z^Lt#3F@uxcgVc@5Z*|}nbmiRT)iJ%{RfeEua6RW{o&?V!${=n zk|J<~2pe^zmeI#|KFmjmjBoxtR?Ek?@7`Y>A<{W(9Q4W!&Z%4Ya^MPnq*vC$UvC;R z=JiX=LCG3)E2BUvcYC*AwW}#j9+<6^zwM}fg2r~oAAjCjT_E^Uo=_9oc9U)Bo$nPp zJHgx!QG_(TD`*G4T^k*vwZ3i17rGE#m)eya&v!7E0~FN)!swVQ!kV9mI=kM|TLL%ee03{$dGv3ggkJM$iPCNvfP<;cz_Pri&=@rmn~ID5T)&N$OHa8_9PW_-aL z;?Vc{4u$v2_F18JF!ZQrtepvUyLT?vvlc>rdKxs1ix`)&W~{s07H@W~yRQZ2z*x_9 zcEB^GU2U;Xe)v)}+2AVPFt}e=OL>2TMR)A3Yt!FjYAUfrc&yqk?Z_GG+V-}vy6~*C zZ(=jt-$Q8mO$C0km8HJ?&CsgJB*F>UUeVSWr&oDS6U*Dvsj2V|e_`z1mNio3;L%Wc zofQY^XXh1L-44cA+OZ3*KeVI$Qm@JCZm_gw&I9lQ{%sW>!y@wyB?Z@Gy6Oc`jQDcU z@Psc&ewA$e3)NQNZyGree&?^42UH*pERF7TQWA1$lctT7G^lXO1478`4y=`By|uj| zT$TU*W^5BSkmgRx)A@lP0Ru zBfvI}+ZClvDFm%A8s{)bQ7@HB;CODr&r|cGlz(?}v?p69u0>vA27MW)8EQCQh(ew& zoUvVaV<$m>Dptix%XwVu3wYE5n zqUCbgQ3cslsblOYJ&%HqiKZrLhd&)^I>4vFIb3-|K+EsIt$&fp9*t5%mCjpLz2beQ^}LCclt&JdjWjG9JP!mZpTcj*UscZ=_}ICAXR0S ze8O91%o*4hSZlbzoI0@u@4;$6Yqc6D<|c*L9u+f}#!~)H;a1&I!Cu6c=fF7NrC>~& zmyCVgz1IlXY<7}Z`9unrNMty&OpSOGz3EmqCp&WN(7)6*T z)ss7Q^tFo75R*P{i-r`wOetBFBVXatRp82_eavH3=7iJZR!lYa-ESyT<#EOZuD2 z1)woEe0!0t?koQlY4=JduX0xS?l%9WDf^q!w#f|{K(FH7KAEE(I(w6-e(nnF>JN>c zP{%Ecb;7244RU9V4EIk)F4*KBSju2z6ww`#x3aedN322 z!B!>XjU+dzJ#NC+b9}Irilr1GR98hQG?CZF7RSjfvS{LH&?~zw-AXM*1>JtADrAy@SWV-c?UZt>{`VU@4)5E$)qXmEfOtH9JTK3T-Tots zvr2GqP=Ny&#azLZCkXVPF{wdJLB|N6MTFgyB@0ChEQ&-5Qz2pSWiU2N!<0{_D1E{( zFeHW-l!}wuZ%%d|GL17K7hsmHBxB(dn<2n9j$LKBj_C**R}yD1j8V>oh@d@F?(U^rknT_bbwF8 z3%Dr+4lR8GI~-buOd3_=W8lIS>;@~SlnJ~*jUib{$!R7+WQwxKG~{F=gK3_I+TAsz06#~!HD0w)xD{8#nuf{zgZ-|y(xsFG~x}M|CXJVsO2mYKT_>3vV zV(Wwgukx)@sTkXAm6>rs{>-@2w$HT)-kmOg3{7u(-XQd*z-;Vd*(XvD3hVGpCbyFy<#TF(;29crRfT+ zM4@oN&hV5bA`CPYgh9!K;x;nwk_vMvDT#%(CEkA=t}EFC=;l+V;gQTMJpW$OUIdTc z%~@7NxAreVX{=n^POh_nI@C(Nc{W2mvhtegXB(hEF^r_g+}S zBjdBS?Dv-{d#N~!}qY)yfO?X{bqBYewYYV=&v>`d11QxN^X07%bnluSm2g1!w9w=@J!oYkEBt0 ze5e}nx^-o=oIb^4G#*~wUVpy3x$AF(nnCB4_HCl9g=h)7^rQ{P`@lkxYEFH93ki@? zvW0NAA7LVqJ$-+>_39Vv)t}w_>+YwUOZe~s*5$*|{dNE92dvxlli1kflwq5dlnlk^ zOfQNWZWtrDHhqVIVTLL3WI;x=5MhoGvlsiu*u>j-Z}^*OrK9k5tC*%F?9=f(Ra%tT z>8WRJDrOCeinaBS0@{EyPm%^`nPa`RCxInL~R^YGop9WO>LeuL& z%rUCgcY*dXW>x3Kg+rybaRHTW(A+;xWUuYYKh;-lZ`(Ey{_bCK1H9TwVml2s45;HQ z=}X!U=^8Y}_8|xiMmpPUWKkojxLMKvzB`hVC0Xr?_0xzT5s!Drdwq^M{xx6ay~*BQ z5BA{wN*Y+m6oLNcLR(M^uq%XTD#5c%qz{G;M3Sfs7D~hAtIIhbU1f5yKs_cMtcJ*N zkJ?CL`#I1~V_|Wr^aJp*qvRsK6H5eW>v5-|uq(QP)=P~`xLTp!D3!qR(uB`b^H(AN z9%pDzS`u$WR$vO3GG3*q;dm`_dAfGQQSOQ31ie(O@&_%KD+@=5hrf)D4j=#2k{`oa znu6mopwXbd$7Jk;QyF7s*oBp~`IE_Hv)PPQPBc~M7{^L4CxORIZcQ=@n=u6)o?bnN z3%?J_vO91qD9cf3=42NqAzG8&SWS9m{+^@7n2eNJtZ|K*CFegB>s!*iB%;e%s#I>A z^;O1o;WK_K3?@KHrm(go+|Tlb;oMUFs0=}5i6a`Z z#)hcOtfEs;1@D-RHZse65wNXecyW(Jvuq);W0oK*{=i#Vaq!i5M0|7F#aTTcL;jk5PGC@$urA4f_&ia5x3}dkl}=$Nqj)XKTo8 z-E?q*VMfB z$c?2mq`|kARd?hneG2Ov!8IUk1nZ=JN}1Pn`#2~l^_*(7h2{>k*EfMU>2? zUMSJ9f(D_rco@E)pTB(bXh zeZX3BWu%Kt7>RMAH6_toTk8A9B|XHt3uw+7hFzldz2{#_+P#v=S96y8=nnrSCi*dwo4jW0>QdqcE$-}r} zlM5J1ih~_`ZPx=saDsD20Mvt<2xhYxEJSKBs@c0O$gN?Y8<(HUEZI&RMIFSz?8l88 zFI$H^k^Q0C9GxskvevvNSY{4_!%>Hqd9@T zkrhPFqn#}J2y3m_(7^?ld#&_f_@jxoFDPyV|I~5$987mrCG_;FY#n}3G8+yKfPTCY zQHMyaZRwr4rqUg76eWAg2C)wXens= znG)*iZ@%&$3*jn^EVAz83kdIh=R7S@&raMns(|W@w?347IhUKChICI8O`H0R)fAW6 z$y$EIB-*0cvw-Slmo?$NjmTch^$k5fjCYA_Sa4h$4p-4AZ3*zL6+f4`r%MFiscL5} zRJC2-wz0dypzL0xGT8|%bfGN8gg92n50-Dn+7QF26RtYIsOyriLQ-9z1DN`?;F_vE z>a)qR3YGA;7w5LXZVp#^tKYjxqThsn9z2<@2aad@0h8=xalq!dVU9eS1;bY ze)jg_?eATX!H8NJ+-gKXN`qHdbBdK7!J|h|zvGXycdyT$UcBf;rFzJyV7t8F|E+A> zksTzcl|e&k^AWgH$cz}_%sriZ{{YoiUvJws5P$clxB*6Or?He39R?(JmaK`p04-qD zF7^-v1}&XrBC@EFR6MW9ckdlV*|Oqx1Nt;R*y7#scmIzZ{Z_1sPIz+CffJaoq=7_c z2=reFZ9yeqR|xM^jMurywuTrYj#Unc(lGsFx?t8Umq~&;APj~fGCZL+lEi-Tw5v#1 zOqJdOvmK=n(W6KappE0WqO>bgLF>K76lN>b8>M0xrN)0=nZHW;PmrU%Y@PTh@)9$c z%4n6LhS6FS@@nmf!=fSvF;=G{Rcy6PR~Fu!o&7p|bN2Jw*7*RgvkaV!0gVRr6UKo% zoXH4t!!E3>EzZMmv)KfyAet(5gn`m&=w(c}H1W`H0t!0(KD&Vr)!u{UkKmRED^O^b zWEVppt?*^6!cLvP8?+dak!2pKJeHOcATp525JVmWW(MioSjxm2b8DOryS(eN%KK6n zjDb?eiJyMFsTh<#k*PEwS%l9A_;(4+YD`8mY#GGfmYq7-oiPM0EC`LHCfkBR3s%uL z*7ZiBbgqJX5?P4`M$1d9OB{vEOQ0;%HWB0y?|q4lBIT1BWx^PkD8-vE{KKm#mlS?T zC^~EfNhyQ2#XJdofOh7bfnllok5+=u%ag|%Hj*a!d5s;&nCz$eU* zYU_OG@xt@2ez5$jbicyV;0SkwKyo)yJT0cP8Q_4$f}NLXP^S>eCc#LF5lc{ zyiUlOR2ob6yLz?i5$m$H+)PyuYy@LcX=g0!W@g|4YMd*Lw$wSu+}=NUV%RxWuG(wl zimi&#FOML!7Tf-gTCe%yZgP5rdi!B^dxSH%s9b#xL!_C}Q2HVSQ>`L2R0EaE7L7fH z&5Hc=oh+U6E;7VN%0ZbEmMgQvAkbYS)-QrT;hU&S6%ZNs$)m^JPD_+|3MLYHz6YyO zD3Wb&0lG9!qQ|MFMq-pg8CMLuc~ff5Bg$D@<#g{_yDq#1Fm8wsFH^L0NAFXr4@H4Rt3&rY)CXS>F8LwM9%aFGJj|3T zU?XWbl@^vN-Ud4{9-floVEYx?eUCCj;aws3A`cSOy@vse$766qe9*9(R~4hZdCz+j zx;g%B$%wm59*aSI6x~(T(#?yeo|QE9FAg}*?kV8( zRR;b<5c9?S)8|`w^$MD_$u*6MW5_SU#3r=V9Lt|m+B*BKGU%e#6zwteuDM;{ZnA$( zG~N&*+lZ}k2Jp+kLG=zzX*K{oU;h+3rwP)p6f|1s6nYaHQgLtaqWJtktlN_3p(nZP zr}GunR^M+THxPd3ub4_mKn`|ur&g5`xF)@byGlugN~%6Y5i+|2SXu0??G2@O`QJNZ zdtrgQ{?I+u53tOPKhJ#gd6wZ1<*IC@XJ;)qgZq`Vu#g1;eV4*G&Cz?3yaMSfEJ=gJH-F&uFZqu z0>2_yiNbIsmzYMj(o?R|R^7iFbeK_+ zl~S0YwSwqgNa`D`buJf@dIC~enIktgc(OuR%C7F6mw>5)1m?nG4%9`~z~t^GIH;4N z(948k5q@nPHTHma@hC>KoFwEiEk>y<)}lJhtdW>#rUsi8wSmFpL1A^m!%W9kHaCs6 zX46Oh;8j+0qCSQ!DwR1F=UkX>uMXM8zVL(p7^XG&S4#N*DaiT`1N?#ok`^v@70;sY z>MNBSy7e9v8kx$2fu-3;`tHp`=8^Y_1idjnQ z_%5&toqnQ%=}|cPAdLmhZUkdG4F$*gahF7Z8t2NOtBfMyx`)STOj}L0)jBirL>606 zT3iu97$dgb``NqO>*=(288UuJQ&f3#?@1*SqnR4CA#;b;_36G)x?1_0Bz+COK=Px? zbfpN(tL3m3n)YIS!r_?T1#N0%X8q&6zqa%+N2!)zGeOEP2%N08b)+2D`~mdZvOKiN)((|_scp|%=6~C@GO*kI2U7a`(vI63 zGk{SeeDHRO?%vzG)at`f;Lxz?VTbw{1>u{Y!t_a&EXM))UDWV|3Yy_`zqXtEjO3v2Au7 z)l7popTzhRLIWEY7j0aZZX15}p}SYi0ABa{psJ$igEJNOKFec7jZuFY(HAM~vhml#KZHU~3 za#h{Sh&>$nt(SZR8;+CnRn{eOz`mr>mrDv68AB(HpmXp(=kVqWI$Auroy${{M#Je( z;%~wzniAar-Va6ep);l-ly`cE`(KVJjpMJrggpJC$sgbP3$0bh z*p`$|FS&_dYDHEO&pDDS$<1^$9t})F7S0sO14z4WoB!Tj0DPxxx#{tXZD8?WU!Gko z;G-YIb=c^=dewkeFkcG=E8%g#pCOYG1S^Qv9EO3*2R`#26;3eM4SZMy5-vYoE@^7! zi`9zDE@BW24#Pc{N}$-k?AWQpB7PglN1$mv5;EtG-Ex33j-F+4w8ky)`zZM>%+_2! z1c3`jx61x{s{R*?-?~1JPD(32Ge71YTncCHaS2Bo7K+o29y|!mVAthll@o-IQrxa1 z_`ctNbMSrt^$##3V7QDP;UaROJ$OHcw{M~U?;qgJ+djPM_d9y2Cmil8GGHA=;k#b% z;o+ehgg6$&(&61e-uA4F>fI>!!2Z!im&5zn8C;mZEtr1?`m~7k2A&Jr9N8Pxzle<2F(HZ$bBw_v(z(cnJ-_Z%+v zgVp%G(P)rfI_Kzng|N$=bd9)*;DHfl6o4mG#C7@XT7U%S zRB9jtVh4NrXBgk0TeDojz!QpWcl7k{Mi{?5LVLdaa5Wyz&nM%~p;7v4ug85izr141 zr3@Tyv&ibc4-acj8NkUhq0P|N;XL;-87Z?gUyA1F(ou2a2RdGw7)nR!U*}Xw=$9KV z{98~C^Zg7gLBZ^W%GXp8GT}19Y#@{{P{QP@IkcQuO3Ht&ZGyMsXG@&k0BfMKWv^*0 z-xj(1K)6o^E;Qb4KjW1B%(QZZtp;$M6F)e)< zLb#DyJk{0Zm`hSuzrMrgT%&g4|%Zo--RWi!)~p?UI8&>jIzVyJ}}X2Bs`xSp~b# z!u(vcd|ceRz9ye0tLydi`L7X5?d{dODHkQmNR&J{C`vkBpp0ZDy24y@hj=Iwt*z5? zNcYSWuHgZso++49_~y$`qv_~uGAs@spJX%pPpuwLzEl>Q)n?|&#iQ|Ab$h)yH}fn) zMTHb$2NljHSMM)I%b%_$^U>LIHlLo4KN^6#ne9-WEg{%Dt`t8r^X^?!_e18dT!5*O zX&+kh935+J91@3Uph8WP-nr~1sT{Mkkb}EtC1BB_zYCeZMv;`<7V0tyow)23WUc@IaM2vhAO3iG{>t*s(Ce zcLnup`qa)^L(>FyE5KS0?Mm8zzMOxWPQKJ>Kwr6RZLuv?*d8ALUyY}u`PFp1P32~^ z2}?%`w#V)m3AIzi_i-~#+C6yP*#|%NynPe-svA=6^qxsN_=P=fU)Rfc2gnV*8ck)K811hQovZ>6#Y%&#W#L zJKz+DvOZ^%i;Kau4qxZkJSqEi%$YC0d^(?xW|xEE=p{*6$bxj2G9@OLqw#WhHNE&{ z`F=VW{%17bT2TIyre?v582y~e=J0-s!gyxOj4!QbtGfl&MzLO-M57XcGVEullmALI z%42NbyqY)lqhEKUV6_3NAYpr-Uo)EzrfK82o3Lrp3bI>{bsYuq8{NnxUK8yb58f5i zHzM?sp#DWw%MPyp%J)Ic?pyCntw#=x8m3mOra5?VZGUlH zf3|v8IwL!RjLwX!zeJI;WR!ltOO)!s3G~Y*R$vo` z6Q*Fq5(@a85~)FqKu;*NMNC_qBr}B*B#s4#k&w{;*bmLrfV0tv$_DB%YH%3tsZgOB9YD{8&5QR*xvqi>%;cW&!zPZXe9|) z83mFmD(`9Bu!|EGQLfAuCR(Sv&E~_yLqnuECNde(hLGc?mr>1I6>s@J4GcOQ4UXa5 z{rAfF9oWY!ODT~?(rmHmqt#rERkJeB-!auRLMJoMX+)JG7;b@?kSvZVhbhGX#R@Y@ zG$=MrlNm$=_l7BE(j=U6Jx`*=g3KHiZi%8XU^)#L`WMG;0#iy7F>atNg)2o9GzmRt zkMS{FSbIj9GR{Km-7`uuj2eQg;F93$9D*nz3gZ_jFKrY)Fg>w)6q!=s=7aDUh#Y5A zT%)W{XkxA(H31hI(}$RmE`3JNek42)tQ9yB;)qE2Y(@am>=qLSql`z|fH@2!!IhR- zq-#}DhwAOdTok;wySr2q=bxJ1w(wssdg4*lHW8%x5a z^OSNbSrpnC73OIy^nhLB)xp(@f+-GakyK8A(^dIgsZ@+#w(`ugiF+9{rO|y0OfBwk zzYf^i)RL=#2V!(;0f~{dG}`bA=6Vh#)tThLxW2yegH8Kg#-sEWYa4d@vlGV0YamjR zS#21eTy@*SvtAd0Xhj~IO^Vf$TfVZHz7&Q*sB+G0s&pM5Cg`!?wsM)>hTS91Qyz(o zqb`e=;&!kw$aE!)C#KC*F_n?BKMjZ2)^ke@cc_RUi7k}PwO~wO<*6!-Na$;<2%{wx zirMh^<`req@`&|zuJ45pbChQdV1+9~gE&@oJAW#3_kzV=OK0uuwBC3?*yJ~1aL3Z6lZInOrr}n^v&KSZNVN=u4YbN8?>X^D7%ZrdaEe zm}N$wwhYUa-38+G7WlGI%q*YOQvj`4evuy|c`oG)`q zfiGX4z?%=)aqsHryc4#2=e?C|f48uimhco+{j0G9{4dZu=~?X?Vu?*0k?X>la&d{Z7{x@W;;JZ19Q@R;>?<9x|MzR4sbY3WJrOVfaVu@~nk* zP=A5!dH3q#sB`%e(RQyp7`D2@u+wd~`h(7KI2c}@bx)sNn-6w1*MQwK-&hdjPc1n- zw9VNP#ddPj_Pm+5aR7E`&Zosr4K?4y7R}9T_ugPe>t=PTUhir&{&s6 z&vRex`cFq^d!09>LxNMd_~q_gh{e@2+z(;5!X{oxU4zcW**CP%_Jra!N#b2`e)qB` z&BoU&@r}pKylkGx37*PaFZ9W7tmO84!?7Hl5(3t9pl82uO43@OC7TBI{CtTL%d7Cp zY;N$y1%=$NDGRd+KfJhiY}k6wTQCQJ+;k}`ImnVY{*y?K*Y;Y_7fLa6rp)~NK!3dw z%h!VLH6V?H-1W8&!3jDP=R3e-;bq1A%52_M_#yj_r}7WwTWxdOxDo#DUxCc%PO>da zzO+p`mpF~%IKFfo#}j+n4{pW-k&wiOB6$R8JD23YcXt7jAPG{GoohQSC$S|0SS7RKHu$>wnw#%2KIB{yd#70=3L$6E9v(X`7JGhFep^oh}hPeh=SjMbEcMoWRghAEJ@;2$%$EzuX}mJQ^wPje>Qif z^gGFBATu^F%Y=VfQa#Y~M|wf`H3a^L<6blWdeLj*_Oq?V;XeqKrIBPj(ySF?Fd|R_ zM03kgo+>6mi3r`GA&is=waa6kMV>-q0jozU>1dmVzZ8ty6h@cVuiqbCAH9F~?)dET z`u+Lw+4be&37!C_ew$83`ObBx*T61a~efu{`UNOV#d2b+$w2xtkv zakPY|eAO_gH$f=a0BqQk^zm{j*c?C11Q;fh9*?4uSWYE~R8uhnslWx!6~F>gNn#n0 zs8AR1-OJJxELwA$)9ZN!5s{z`SOUHze7rZ%CvVf@O&s{0N=&qLM{9&KE{|5%w&B2h zJFph*y;ulEP9sO4@M3|d{rngdUtcf}BL7U>shZgwoxZ;~M!OlaQ7PkH_S3e5?uFv1 zLb{rfDRV!w-&G z+xGSn;)!Y#h-R*F{;@62F;i(KERh6roUh3q9I!bLrP#J~hu3t<&SK`p;4@&F9R7vj zq%vb5(i9@y0UH8HGqWA}8nQHeR-J4y&wc+GmyR?A%ZSEocub48tE;uymiNAu;sHLj zXQlvT5QjwJRfZurXBPVGpBaqL1PuX?yx#{-&(YNv=jh!u$loi z!ciVVGRGkUL6#)iDoPRqNYxZdbq|tM+&En79Bv13CM~zJP-#y)Rw-eZTjhp=JCru` z2qZjmBafMZ#M^D@(0$Z7#55ldY!2&}j`$!Wvaw@$0r?w5JTjy2WkNHE?9tJZM++f^ z8ab>76+9XQ#4(8S8H3NyZO-t{?yhUUx-O6mf?|tHJG9Y86|Y$;_@^encv*(J=KQHh zLhcEQg1{a~xh~ljdJbBk`&LQzaH0a9d?CFwNYKpI03%|jG3t6a`|$Scq}`0)1yWM- zM6t)(5ObCe#X2S6ign$96~lJ6(;f3 zHM+DQm(cc9jF*;|C&uWZeS=QJ1PnkP^aMyJ4aP}s?E~)ZTTJ=edJ{rnK-6DcuekD-qv6+oBwtRmZ(pl75L!JZ*60J}u%y>2mMLCG#@3UAPX;QZHS*IL?F~q|4gd*rEM1F zDxB(9M^L5R-GLRadk5DJx*G;rO{s%!Ct5Z<*?@jKauSP9^dwAq0C?69-vm(OQK#_B z4WCtEm_BhZufi8WXQSMv2B6jIQ+y$ZMhGsS)Kvk_%Db$MJ_24HP&%O8{E{ymZAUjZ zpcN}=p)Lhpy*d@eW*hY>@>OjRUF~DI;CW+crosy4naj2dl{Z7={517K<`Sj*AE;wS zT8B0e=PZ7QVy2|Y*wf1Ql-~GMsPJ6G8>_+(#(s)Y!$(IHtZ^DagQsLL>z*$ z(uv_=@ZAytn} zM{6q#8WPx;lU{JpyH&1u&r~lrt=-*wWKXs2iX@5TG}MMaY^&NwHPb!N#_Qzr#~)dq zoaC-@m2+-V5v>;I>aSl}ZL>#fHfzq#cWds@D%m2wpCd62d7TDPV-FuESQZJ`y-U8dFck4ODNru)7Ekh|ff-kxZ`m-KmHcAb?7E zFnaQRNa>_Awp6#$0c}kf$PZU+2)Rj!iA@U}v{m*ci5J!ZTFuQqV!5`Lan~N*-0(0H z6D(8c6I%%$NlXEZq*x?`U%aGZ^8hCe+M7?#NM=mPYCpBf!w`RzqZuJlndaeOOGc}D zB(sGX=;=+h>F8>n_;o3-GcFXOroOdKux`Pi@Bvd;sc86|yi_N5`n|$Br5R*@+-iz* z-QC`!^|;CiRn}gy2zgOIl0{#kIoCq$AOe-)hhEAwZ_DI_ciA7dyL3wWqzxW*r3`Bm zCf8eE#EP?@ILQ%y|wv( zw)xf^RL5Y-y7Mi1;0-XWqq)`%z0m2!X)3Ur_Kb-;DADom4_K{(JxYo$`ck|+_d7vi#qDi28qQlN z`M$=#HkSrJcsn=ANB{@32g}s2 zq^zp~*On`J&0%wf9rC;?Jd4#E+^OyHD!Bx9eqH54v!hgj+)cVkc<+p_1ZyO+Esxky z6M;mOEP1@jsdPM%pv|n5a4qNEeVOWGTAsI(%kBpumtm_HaP{p8Jgg;v8-eam^cFqa z0`6y!wTUiuFs+M*i5VBo-;~EcQ82gYZ(6qg1?^Q)Z`(Eye)q4q6&@scj^q|yGB|PT zv}?Kz>0s0WHq7x1TB0q&5~-0?Qa8>s&%3IQM6<_E$0ZIM>fEW%vIE27|k;=k8+|kep`r` zhWdksSK}Yy+WlAXd86zY)n5khv%|T>bp}yEhO! za~1wC~xJG^0e({x)y3YH#?JddC@2>L|5=5Mpr9e|m%{?*s)WRl;a##p?kPK;o zKA(?8$zyHm1Y5igr;mZeX8GYSN-b#&mEJ;D55;6V;(RZNfA?}XkF7T z+^5JxaBBE6OU`me11xM&as;Ev0m*_$Y}jUmS1hB@#zKyj{k%yjEX>E8Vs(Ow3FkYo z4GQD>P@=Zd*astxGs2)0LNS{(qYD1VrIeTg7wrb`$cJ$YVGn=;8;T}ot?ih9PR~2R zk}t|xxb*t}l9cX_T2uEb0&I?*`N@kVt(5kIN^5Hy3zP;kFxa?Fwz$)YSM7S!^PNXd zbez&%?*+R(wgA7t+L>7!-;4a0{oBh=lRs~ZhwI1bcfrC87JvKihn?Wl?H@r@GOxRh zrMo>NfNur^=mj-$wiqLLjgwJg(J|~NoOBfXEdeERYHuM-W1M19#M%rAE;JT2&Sk7X zAi4=ZXod(C4*B86so%APDKM28VI=kQx;=;5n>~I!H-Cg3E zs8uu4glJM@CzrnNrDOEKJA)3LHZ`G5A$zy9jloHJJnjv{O-GtpSS{HLwDmXbRc&wEHW2>qUvVouNb(%XExKfI z>egwCb|})-s0|dD;~BJcwg_9KN>a((H2-}^N`8~q&e*i3TvIT-$A;1J33M#kD3X@7joA6fQ0){E7J1G-*w$RmQUw`kr{On2R@lzOD6Bw8^T$=>^tCzpQ#RYVJc?#zj9XRiF0_VEoF$!%%NsY;MH;NYA zq{S?ZWfr+(R&1uDTAa~rC1+8_w4rYY5o2inH1Klx8m`O#3SKP1Jrkkl@#yb383g~a@65u1QkZJ60v!7Ob{r{+0ykc6P zq8RWjU!l{c&U@+BxNkIU1g;3|(}F8lacw}(!N?^F{)J)&lX4B(LFyvUrE+3BhmBwV zmMLILv30c)xp!X7h%IPVZkUXAsJ+tOFCD)Bcoe_aKFRXk@Fc_FvT>CBM>K^iZc&D| zrJ9nMNxj>w(qxrR|s|49DTamZB|WJ z{$G}vJVX(SWFPY=!-0}9YK{Avw&5$&>HOnV0nX|3FH6ms(x-DgtVbo%z}G1y)M?L8Y~` zjU`D#4D>c`<1OxF>{Ywo%CyN$LHYZR6A2=<9m_+qI+}ob^OOoet-Qi z`6)0oSN!d-AGU(8H@^o_!M*l2l=k+B0DkE8pcCxn=4vs5S2PzD)f}gGqB)1uZV70a zp}R?l#We{QLK>=Pn#xpwz)T&=YG_NIDuPiRoFx)6;@@61)Sww#qBFUpE6WyN zCKZy*)UgyKzs2wXuW8mfZhm^;RU`EcH9+EB)=Y_u_ti-~Fp6jXCh_s(NpOPo-dY>H zv+j7}2O)TMS5&IJ8V_P3PUdbfOUm0_!iMQ(J;;O^w#%m!eE;0qS+)QULbU>VUR}X` zs%U>i2mc*Kd(nqv29JK!k7_0ljl+2N3Z5m&r&2V(1lenuc6ofeOmHuWhl4S==|wvQ zt0i}HHvR(bSZ!|_M-cwbub4_!02_l7rAZaP)DFf8EjE^+wW`QM%iRDgAG_DxJ!2>F zfA8$xaU92CoF@I&lP%7>GtbWJvx5(Q4JTo#vAtb_ZTNr!754@`!AB!KXi8y}40=XI zo{1FdL0be|V1C_+*9pL4TzY)?g=6SVP|c+D;b5$j*JJ&6#6Q;snxmY?Ia3~-du?GJ6vDxD>T&m)*YITc zp!j%V;MLyVo84D?FJD8?iom6LfR6E@a`OHH-oAysUtYtTw|nqrZ?Ec91MZ>F*7%7r zp?=qBjJcUa!@4J@4R=hyhPsjStT7DaurX!Y(7S{1ux{=RyziYtC;mHu7q{RZ3s2}F zGF7KMS>qc?<>vpKUmSfNKMC z1V-MX;GfAEDk-i(J4hXcp;SiK6NS0n@f}lCTZ%m-D-HJrOGiDQNq{|cv7)iBagmOUZ6Ecc~ zXKVpe?^+a9sk-eiY2>m9t10Ra+Gnd#?hjg>UaM&Rtb5fuX?`r)y8hVi6zZIIi&lHr z?S3&3ow2e!&+=oVfx^#vyAu0LB|X#{Goh}*Y(fE+#H5r6?xOCJLHk4nG7^M^{z~*i zrr30)<<5A3utlx!Y4_TnAdKwG5UGwpdrXK0*c^qJG4Co+KN(_VYRvhjDH z?Xx;uW0^Q938xcjpHZHafq-uCITIu?D0JVW@Rx6#*KxyE;l&F`MHk+|4!o-7720Rj ze4L(e#u~BF2FCz-Pzpoe_91my;9CwJDLEzDJ?%ow7}T5Gn}9D-i?V?UyF<&HHm$au zhKkYMy_`?FQH{-)?TzI!qKx^M3h%g#bj4ZJZ}l!unsiJi9=q_eS_2UUK`kzr<)kh- zn>j1*Z?n_wwFb>Ut~!4W-d~+Ge{c2k-aB)h3)avg%>5PlOwl{dd7;w~=sS9Ns@Bs( zQ|au%>+lM!NCT0I<-9-bt~F`ul{iMpPvbvkSJD7og>@ydwb=jxC7{u#e#!vI@WwNh^92l)BGmk#hO2;>a? za)vUAYA&QXNj5Uo`3M-$(DDstT*uSRCPREqH4!PAVe^KZW_GHD-0;Kb^#OG`&;GG< z&meY^L$!M}q{%=uCrpgdc2GfQufI=-eW?&8sJR|^fz(gmD$amdEZbrm@Rsc<%x4aG z4w%y{ZHffdK*BMV1dT!rUtlT3PFLfUdoqZrB1fhdcyEYEd#&?!v)k!jSRPGm+aVUs z#dk}Pc>KB+YMGNWSdOAoQ{t6`o%1)!iRXqkJ2E>qnA#4e`Oe*=c0f!9C|g;}cZb!e zY>`OEcEe%D`F%*250-2f(KH@S77{x7{7j9)KQ{HW#ro9 z27WqRR9OypF0%r86Tidp6x2v{o+qTVB+qUgh+qP}n?c3{q_WlR+!%TAK$jFH2 zKNBQ|^YoF=*%ND>mG&8bS(!#yji_(#lvhSwY8c>ulseJ$*lNb>oPv_tR8Z6vlMKdV5c80P|iCE+6*V|UY&HQ<7sMq?} z7JP=Fcx9)$k!z{(KrJ-FHu^##%mN{SBUug862&>fEQ+XI!w5?<69_wE9qX4TKFps@ zWb^GKG-FOR?hLHe^B1>&T3LG^#I_}CZRn$eZl;E8%f8X2d@)C>a%m+1uW&@YIqmGXd;1Ww4=+Hvo4+5E zGpl4=AqLoT_(cTg;ynL|y^|L3AZ`Aa*MiB~zd^qQ0vXTf=Eu6%S0e-91cP{iL*1Q^ zYWn%dXgx5^;%mMLP;MRr8AWu(D7TWWn*}Q+q!P4)Z4bb(hO!x%znFp%@XTD2nK`eN zDN^Vo?I`S@nmKLK0R~BOu%<$e!~12EsWc>A0c+P6SBbwn`c1c2$y!<A!OM-NgO?qD<$2|esH^Bco|GR0XdaIE71KzJqev}}f2(Dv%ofQ) zH*M&mJwTf(H>-#5L|LSbN(Xmg72tYXRhGlDUd_%DH2y7L+!P5vL7vY(CX;MJuQ7vI za&jg2XnQp+k(^%c_U1a?50eVBZ@tI%zy~P^B!XPT2?#}jLk%Mz zPbvZ3 zjnCG)-W&c*j-)UP%eq5DGZQh>R@I?Q?g zut2?Bi7PfJ)0}4NaMzOqp`D143=j=~l)C)K3!T7RA&J~#-N>Pi|MI$ZryC&mOY>-n zfRhue7txzPAcFi(`*ulkB(<%o@zs#GXTQI#F|Mg<|MCE4`M4c9A=N&hd%Hm^&g_gZF}a z{F3S&4g2l>;~V|V>C6QAWwvD>GRpeDndtIIk_aZ-dryl#qA#2TKgq$FLwuUTMc)?+PLz#c}ysl_}H#k*_656(gz^y5nb1B{KzB}=?nZ+2zL!s^#X=}xo5-Xw>AuQ-#SxQ zoPn+K_A(*b0r74WuWE+UtVdW)L5nUb5+=^4u$mnYtV+E}hFX3|?K>5^iZ%MDQw%zn z@}<$f3`DM!=?8`Cq0b6X9$qOjJedMNK@rB{*>^|Jr>bwky!W z>sgi39JF@zF9&z9Of>QG2|NGt&20Nbpxg1OFROkch)~Seya_NclOiu-aqWFZic^)S zd&p0|u-GvaO-nRw(0#)6laW`+ezQprNG=n>di`~EhhLV*w(L*OH)#5sytru+&aQM_ z6dj3ng+!yopdzCignxKwj4spDB9vJnS0#Ktn%&pPj)~QQNCLSo$mQd= zF_ktpR&?UdMA!jMsmk49912QYi>p>-yU`i4M-B0uU!sKIq7cQk>DtxG?0u?8sWkBq z7&%5Cr9c)#=GW+|PZ^C{bk!mDB@JXbhl$uqX(^QL&~hrmwl0Nq#bM!9*Wt3PMm_(o zv`sM^w%(;DRvlN5`rmU9A$jt`3V)B;_OLGw{)-N*lF@Dz;%2|*2w$t+fTf1e_@h>(uOF4?@R5fL0Y{uzhfGTCVFWczXWrz zd!5-mz@k&i@;vC7Y!{aS7i16lPhn4$7x|j12^q_k)eYdZ+wWtdW9RzpG?jZyt8ZEs z+I1HPlnO5o%O2(JgXd#}HZI5(`Zq1^&2qzIztN>WwS>^K-|HUhk}6e=p5$zwmB$=fB_qq0{eI zAUL=V``IhkEUR%Llyyb9s4*9M2t(Th!~HNOXq@UK8Rywi>a-$9Bx7mpb*{e%KFsX5 zmhMpKM>kNqn*sm5Fr19X$w{pn1XNndI6c6sZ<5a|5U_a9gQve@vBVh?38XzDzJL0C zdh91^z}xy!(ucPzG!M?NU-_tTN~ABypFnetC`~D%Y$KH4n|NC_**Y)KJ6v}`6l-8d zDKR|40{w{k7vZ#nT;u+YI+aH~Q->Ar-0}RE2qMo(?0+5%1&af(#$gNRu$uMOy{=jZ zTu)Ax!IG(2LXg&33yFbE;|ss0q_dH1D2$ZF$Az1=@_sV`>%VTFsI4Z1{Q3xmN=NG2 z6^E5vDI-l(!7(=$Up|fwoLJduS}U(F1Q3dXe;=Yuz@$QpSXO7Bk|0I#lCJY< z?+`35Uh3YPyO<)8nq^jdv%xdEP5Ndo=hVxiS%3&)r4f_~dMmwkCXIL%G<94QuxJ@? zsD37xi2HQ8u6kh>{yq@cw;S}bx`+xKd!>O6=l*V7#BW$pmT>c$gnHPRaZit}$BaW2 zPA&&ceYrbvTLzUX3~Cm zX|!fmS8JN4$Bdz#V0fa1LeWDfqKC4f+~pKMX|AKR;iVpEV7lTM6+&4v4;@)p-$?zSJ)+!mdQtTdq*)y&lTHuR;8(V zvBMu@DO9N6`Q}xY0nMOwhF|Yi;C@h@p0UHPRI=evNAb~@l;6J@0#&$8ne8Ag)-lhW zIuk&l!IemF!M2B=s;R`=KVsQ%YvXj(n_SlGQniuW5dWV>nB1WuC=gd3zCy4q30Tr4 zKor)yqQcxJ_CO^|XXiR2PW9`Cy~9=ae6}CA^Z{J`=9-)NVUqbE>r>ZQgnDz!rjM>u zC?I0wAb!`PVkDJYjE7eX<1-IQc|}@gOM>6+>S=EY;s4@W_2$XQ)Sl=!zUwzA)wxZO zL0Xx=g~(3j<=d51Go-0FgWaIW8OG(Oilujr3ocCbepK%11NfaZJ>rH0?<7oj^EP-k zxlXTp0^_@Ygc|(=Bzpb4T!F>JW_`Y(;9~#%o-=OAwwN|TSr1LXR61oh;MgOhE+j~4 zoNXV|C>jvWGDw=B$YQiHzalV%nG6bOocjY)@q(o*{Xbj`ZA?WFXme{YC4`(!GqBuK z)vGn@t$GNtek~{|OlHo&rY*gDInWH2$Oz2b;;&Anf(E9pAP+UUS};|d0Y*>187Eb^ zD_4>hikx0DDDD>uX@>Q{LUF(FlQ;XZRWS?a=FHd@tbo{y9v1-f9Xn6w0(Xn(R5ZC= z^@_P-_JwW%@Q#Jp-6)JW`IdyvcEn#HVZI|+8Cu`uh%qA$FU#vN-Q-*2-Ya1m+J9PM|s*nQN)y{?h?PONY|E}0C%1#6~sja8c&W~DcomT7O==T z1p0*zY5cm2fPx0a8nO>^cD>oyIY`_2{eP*%lic|ylBuAgPnN{&6Rh7fZ~aBhH;Y*dyemf}cK{dOG5TTzYe?me$kj-xB2%dIb|p zE2G0CPJhmv1^gnbAJy@BheGt?QryA!js z1GBxO9aU>v3(jWmbt*brWqJR?7b(LBuQ%|6Y^FhgNUIcqwiLq#X_Prq0N3TVKX zx;PMQ&RS}%1zSJtonhJ5Ba^Vm6)``#>=$oa)saG>n|2Uzt;=J>TO9vM60{`eQUmsk zl`0mWQ)vpW3-&%XBFqA&C@U{tX!Fmedcaq?(Y-$`9ipc4{2~`Wt5UL3{R5*@(_(hQ zJrmA~P7&P=I#>3{sncqg4y!uM4eBSePTz&+yn(%Hg^FAI+}*4?!RcXn?o#Acip>zqw74s~M?G!K^iHpk45^Mc&wJRimFC{&FcnO7{!MIlG>J29^EiL-( zW1}3?ztaG{m*?}@Wn*gU;bN`lh2Y@8uQan_B23|%y;zD$o6F}>Pa*<+;B(F2x^TN~ zyUQiX?)~_8k$m34AYV~2n|VN$*-=7#pzobc8PZ*rhD~%hd|Z!J7zMYD9&wdE{z^@D z)9!m+eN@rr`|uXep+P}8g#>-MSkGg7)+p>#X@p$Yj5usWaGPIA+<;`o{Iu}Yj%dqb z<39Qpa!o7m84u7Vq7muTvpMBFvJ?7@RrI*Q?rN~Ab+felzai94EY|fZ!-wxCD75Vo zkskCZm7_X|_3be+?xGLU(}k!Dq20K`Q9KX&yH|(oZL~kX9RmD+9l}g}IUc3;n3!&u zk@I~N)(;CPaXxeimUKiN0XBcUxw?{kFMkpoLaB6p+UU!-91=_`D)cQRvoV(5bwTc1 z<6h6CX%=I(+%)N}O3ofs$lS<&YIpQabZGIO6+(K+1MkbOnxvJ**Jk~phrDS!e1-XWcGQ92p}}YC1WMHQ;Q?CkiXH@RF?3O1^p>p z-`&KzA`qpGu?KTo)}9_l8XE_{Gv(##e=C8Q)R=|K>N3vY%ajT!i$^F}ZVqj?qyAL7 z|Ba=}hY}Zr)t4%!RLNM%`;D%6OE=1y#OPA;jK~J@tRwqF%FPOY5yR-}>}(xH`{L%A z5i0`U5dH(##vlMLCpa`e?>EeYB8(xp0$>U>)lZPo-MyL z`=5TfAc3{wYN&^x$bVa3SFv8JWaF0+cnMnLEB=FOm=Qr&;r;3rhrn1^lY23O;6QwF z0hky*op9!2qj^+Te~vG z%u=!$R+dL3=D0wdJT#~NNemUe2eYvQV&)38~hxInsTF0G$Xpeunna50#)5&xF(VCNI?T=17* zN%MiE*`5<4>q!=zoL+xlTHkub-pUB#*Q%oL?GKEvAE4O@Fb6iw`ZntUBGf@y(K6Ko z6AZHLg7Fp8QhlU6Hd#p<|lj$U18P#p^xP5qkhR_@I&G3up0OH-(zUr?GkJI{7R4*N@gjFk*JpV`KElW7a^eptwIgFF$GN^y=q*CNl zYpalkPder|YH`fgeE*ADM4OrrK(YvumcV2~4H87PNlLroR1{E}qMET1p4o+QT1P~U z6*U$DI1z9gzb_xD&Ikl)Gr#EC8`Fge?2&aHzR>*4tq3pL^!gM;te_=9H-ls(6A35T za);b7xmcL86B9ZJm;+7Ti0xpL>J4o>!9-7PCSR_tPI{+9B0ywDLRWok6gulJEEyvU z;o+1V*sy}4Jzab?fOq^OO{D>JYe)lNk3&ZUUI2;=)+k8843T5GvqTN!`F7llr>J+53P;_imOo6-EEP;<=AYPmn(h#g8G#$MGift@zr^RuF&zz50K=GNWZA*-MMId!PUoWS{y%Oakk(}Gb zO+O^7hj2CJDy};B+i6Zj0a;gdseOR%TX}iibgH>|OQjj(?peCe1O2a(>a!toM?79; zl$M#f5gh^9mA(kIZsi9(U%tA+#QulXc$2-p{4t}7HG^O~vZFwu(TLl!*VO*U@e63! z!3LA-!^je*(V z*|tuszA;E=KK#Br3G|qbtr9624}U=|s&K}1-lwm$Op;tTp!UZtR?18(zpzq1xuZ=z zCY#d@0gzQjIj|bC9ewpr`n@5b&4%0H96}{r#g&8?DO}e%%7vG0;vfD~?R>CAf-0nR zB4KBoHrHYC_?nHnf_r}P2&bS741&1TO~61A5VB=zq;=HZ5a33J>>ppj9!p#Qn>3;Y z_jk>&s;H-*xmN-c&7LvW-3gi@Qm8_=5c>O0vzZ4P@D(Z7=D)3D$+L${48^Nh#vr0} z;w+9CoFN(gy%8GH#DqsA;r`+kvXJt7kIBGP{Npk^U#4$aB*7Hu0ri^kXJ{g<8FZi8 zI3>-|vuV?K!$EVuHFANQTD<2MyW4a5)TY%Z09rz8Om0m|pYVavoOc)g;&Q|2pJV#1LCli zhfoRQDcGYw3DtrlO0lxFj@oKECVuVPlqEAe=FUOn!qm58!`_GnrTgUAoL(!IHS9Ps zQ;7gKfxB=G+k9B4AFJ|ZoFa%DV6@v90k$jiZ74bkC57zu_On1WxvI!vpRYVp^uJFx zR!+9o)@(W^j(vb$sVO)u{2z=m)usVA!VDD*1IdU3lO*R4J%q)Wd24F1CCVM#3Mb+J z_HvVJpwV*NpIhaP%%&a<&|)RStCZE?~jC z5I;+Qnh7%=8!q+B?pI?`EynVt&czkqvroye+FkjUAUh06BYY)4C}a_g4IJ)4ZI4tE zqTg%o!^|2or(0kN{7R>_gTGAG_QAGvreEgXh9cgp_AcCN7Ff-lDZX#Lz+;-KiOv{; z!;2P`!{f%{@rE(81}eSAlGO(3+naE^eWZ-?^@EYiiP;@9Uwo+vPbi}W$LC62Gc({& zqMIfcN}m?`Nf(y3ZcEYNkeHX?KwqBg3X9`#R)f>c`GO=LxKE4mJV*-P=L40A>|Oey5v*~F*@-o9bk0lxod_FD}uUE$EEAyukNmA z(5|9Uhqrj3k&12{m^avSyH&wJibGsEN}TNqEH!;nt&WOxKykksB@k!1iR3L`S*@L6EfpilT($Bm9{V~??%tB_FPE}VtV98 zE_Nq+240Uo!U;K)TgCD^+E`YGYEHB2!U71R~q0eIwJ zLt(i}k~Hm9nZC4E^z#VYlg^S-Vd0GGaJ`B=1E?DbF?o0e(4*arhUGLoPgHq=l6NTTKqDB1RF3P%4*gS1?0Q zYU_5PJiXM0(W-ctpO$X=f|qEZC%IjkUdpZ)Og61+t8UPl-)z3k*H#aa!N~H)o*M}@ z-t3oif`(W0YVST3HOtCm1*ggXkP<;++s_3QKG$ChUUyK6$)50&o%|1MV*tU(Sve99 z$dc_S9i*bEjLxJ-lFp!UY`aSHR4!1DSu|uCHGwTM$J#P(Ai- zLpF-8wDhgIM$luY^C~f{2m^WYc0Oh~tzNgjK5TGjD&(8obXeUnQp{dXy4A*&Nzk-Z zJ`TWHyekx*4F4o5KQ#d^pdsq9EJp5)fpcMAggjVzFM5l@kjUMQ-Hj$k4 zNg^!q<0J(?XBO*;Ve!`f-O$&rWOqTw(p~UvdW9)t3gXnCAh+YZ>KS(`%BZQDu5Ni? z%WU^m)yYbGEz{(^|Iv2&2E0x~MWTu>n{+=uVMW#x4V%Um&urc5Xdc%)Ztl*HQoQ3@d&j2GYMwGtP`g&YJn8{hgsS7By=ivLLQGyC-3O9L{ zNy{e5Bglz?xfGgKw!{C~?JeU4STP6WgcG{^JtIE95OTUhdwn2Yip+%~%lt7B)H)IS z?ZI_0$Tp)Q1j5E?oJ|#(W({Z??Bm7-(hzNK*UIy%jPPKxw!WcwetMMYulr~#@tRMf z%HWmYfq;vtu#3R`};pW*HWGLDLX}2%&6%5gEUg9IFhZlXi*vfQ7vD zfj}Op>zC~jG(?<*QSvdel;Sz1WOFDxLfL&Gty4h(7pHV~?^!)Z`P>j7+L(G(m`{ARmAoRy}5HtUiQr?#i=m*`(){SdNQ zNHzJOGkY7kO)!x~SEP=PGUt$giwa2fghYt9MWgllmKao;r)(2(v*QH|XKxd7- zUTtlLy`dbf3W=tg^-}HedtLvdPSdfxT`JaD2gy7irGLjO603wNx4jC=48ZXa z$5s9^$%^-0C0Q$=SYyjEcXKy9%X)^m61~kCpq_(on^z*O-RTCn>hY0+2quu#*1!wm z)vJksC}J{lwX3>1Is&%iwg6I6D|h+zMD7A*EH3SCnJ3L@pyEbsfp&d$k*TwBM}7fQ>?CXJKpK$$Y5@#L;~k7sL7iWr*aDj3B24ZJp zT6=_H^Aw?FAtLx5~HCt>} zo`u8f%CyVtys0g+%-TG!R;z_H19rVxy|C^M>Xg!!M5u+5yxPNE5LJm9Q4eVtfzNkJ zt24YuGgXQ$T?g-Lg@ITQ)Vd@(*owpKh5GkAfJ6(16 z9^bYGagrGNs^VVkswVBKNmP$E`%sOj5Jw9SEa%4H8D3Cdf}XR=ljcuBz41$Gl6$#Y z&a`!P>ErAq9vsvRq;`hDMLQ|32Vs@qWp!MX~`C3@_cSE+tWDB*e{Ehp31Ac3+}O?x)ta=@Kg!~ zXx^@PLtgd;==g$k-EvUNX&6ykI*m|YFMhCT)Bh1n?0k~Ws%6nEji_YZz>R0>KL@Qe zqPNrw%&5sIi@vF-Yzi4{d&;6xZHpn=bu58Kq6=*q(fd*1&b=zGin;~&#b^$OdvASv zeY{_tt1K_2ihT;du+7lMHm08ejg8VY204R1e@~+#@8lbvJAPnMbSyyy%R-0JgHM^~@L(tohUo@?Hy=%>Ye3qd!X-jJy%B1aUt3 zGw4Td>t7uJuR#P!{~Xn_MKk;R1j}s_=7U%=Jkf;Gq`YP$t(yh@Cb+<^_Z_Bdq1g9^ zpp;~JQI%y22rGD{tpxXYXCD6V#gR$I>Okc<7NlcIcq;xWObd7_!X?AgpW~sZqF@ig zc9#r`C|nV@f4(2x+|q>-r_v?(BPS~hV`nBWDrb*E7zI%o$6S3;&HLsss@>S=&iH7M z?NucIW`kn~!o`{p zu0915zd0MOU|O@3SCnh5_`(44bV{@$V`% zg(nIT^|jR+O*;ygW7<9%r6qOW=3d+0XDu>OaK1jxzE2SS_deUL`W%=eym+08Wc{(U zYknvxhCi$5cg})Y`P}3fZf;Y)4!a7hFA0AAgX$A*3XEUHJAkk~qB!SAQ<~y>Rpn_g z?OV6y!&V`WwpL_~HnVGA3BOd^*PL%T)_S?ib(AFYUo`w4?na%EHoX@xY=zNYFDU}i zgbOhhzrh^R-N>Lwh(9dJU-qth;?~`M-(vl{2onfj z6GjyY5rM11s;2gNlwj&~>pjs_#{pp=^r#XIo=jt_VG)eVCli-&s+J71_7HaRQgY&V zj}E`h8zgQ~i_M|-=8!*;1yLKF+MKe+-Kn2p`clZa#;CL*nxa;wG(29yQTaYiw+7#c zwv`^ysnoXvd*QkS3xtqZl1&OaPlVaBq5_4lEF3PwPn zmf{khw?7MQ7WDph6mgi`A1W6GF*4tCQIa?4?0mN_g!a+%8A8>S1AR&eAasa!4cNev z+bNn@`bcTZQBkse6{wVA$B9d5(IK!-(v|%7^CE&3&g#He)52czpylYqKYB@0^N90` z!^@B*j7}(97azAu&FP|t?Z3=@zJkjOygJ+CxIChe@?o zx)qThMBX+{0a?n$Bp763LnzXXPw{_cEl%T{>hEG-{=8p@kvgUagr_HQsSEAR_s^YT zNDa@>GA z_55YpOm;oB6WcF*(t$o$4xcj_H@QzX?22)+b#8a^fauCrtlevp`sk zRUlqNf~*+ocO%&{R=sj&^t3Cic{7*e@aX8oCL(g=hPOANfjoIvOwJCr6zg~~uM zDV}J~C&;QWhDk*kn$u4f^d!0lY)Tiq!f*_e8~O+mp) zenLN)Mtx?8VcxrUJa;hsXhzu~$y|4@tZ=7#V##5anmhpLbJ)eh^=|us$gT8&tu;kR z2_t_5O8+&r01lz6(XcC2GR0x7$UPc0L(`tdF(*xZBgV$@5JzqV=hb4@!{^}qEV5BFRR`}CV?FNd#BcgB^32FMVL=05JG7hBF z8)abZ4kbGy&SMGGu#xXlr;oQ_5f|8`5NF9;28fjv56O=z?t>AwQ;?OA5|d`+&l@^aFOUTSu-RakL;!XcVmb#haOi9Pk(f=9OIxZtDxS-Qkd zZwu!qxh+H=RnYOIWn3dvW*9i;67+1&7lCuc{@y;pC;=#;PzFn3E>_itg_1$ItV(fN z1TYdK-c^9I5kVN`;`h?U64F&&LJ|ai3!4xMhR(~AE$~2v(nNj8^?1n>xtF?#kldcO z6F#dgv+>$gd_C3uhaPIB;YD69KgK%5MSHWoJvM&E>#SX1b#BjtC6t>**ktGX>R_aJE>esN-O>`v_OMc6BH?&F$BAn07paB6t|xg05`75z zq&}}p{pL}akFDavw<2cnUU+k)Dr2|7fzb7#HreNYWo_6l!miOI!)9~d1bA<-2=*+G z0!A85Lc~;_pp0V||I;lb*wnv=dv!9w*rn9?Wyrmf`HvmJYh;nTa(zF5m^?SVamvo}sJ#oC`CRk9f zKwY(9PpIF`8G^7i_9YbhPgF%SAwz^J(=Yamb&-{&D23dyFYX_-{U+XSgaVGMRs~F{ zhYkjNC+1FHPmfNAsM9o&)6!72GZEfzws-o+AftReKu5@lIq;&vY%Rute-)Go7>Q>q zIp|J_hu;iw&@(oPOnP3ld^~)~-L3lTv#mi8_U3r7ow>gL7yJJkxBR!lgUQ57GG6_l zJ0^skt?HTWM?-Fu?-YU+2MT#Q4%Pj`p?(5DB;j7_U5ll-K`94XzA;5}fB{+A-HXxZAM%T?O!tJss*LL>J<*N_T{S; z+kyrJD(*p{mUUn}!MZ9gE*;KOijAQEeAkGv3B97TtrS*_B{F+YOW@wf+#DjbKlM)#32uuuG=DCG4)S+4P z*#2yW3mea8;OtmWu^~04ggnej-f9F`8*!egSY@MD!<0Gx6~TVAmWA9#ch>sTT-fo0 z1!#R~RV=r`8IHDbJ?_l-Rf{?dXe33ayRO&P`qO%geO-8=; zmv7#xQK62Z^DveK17}0#eMmQYT9{X6tk3E~uhJOT3(Z+?tSOyPOIgf}7gu_p$bd++ z^1ILV+?9q%%+A3Am?mQ}MrF!6CHs=x(!qxE>-o%*Ek|}+C+daLa^xARF$wf^-L3~v z_OZ#r!r~G<&sp-OI6q&FpX%+W1ewoflc2(BQkP(y(Cz8`6Yxs&7vpfC`Oehp1KzCK zX0OtkZip-xXOx_=L^eTY(7ZEH{O;x(*%(U@D>`roeZTOW#3fLKD<-vcd@%LHU`ZXe z`<{rNEzyrrt)=t&b`Ib*>WPrd_h#ye_Bm3X-0V9~{hDK4yoJ#y3m`>E4JE5b{%*1L zxdi*ouJf!$gV1g3)oI0#6U40UOm(f`S+~b5&<>0^lkaWA_Mk;wPsSSQA)v<3E9I1{ zWc3R@TT#`l9Z42tay+k9T3LL1)B4Q>@;wvf!?A{Otd;aVN!FV+u03p-HJ0)4#T;e*E#)r81Q!N zMB0uv=Jp%iCp}Qi&~uE-g71M zopGnYtVtdfw6`<4BHbqmx(z5U2{`=ZCnMZpnr7pU=BF<))c3{qSAyElsL&qLIBgV> zIHmtvzv9u!_$(0|D0SB`>ua0S^({-|Nyu@(5kDHp%1r{Y)RiB8_1WGSL8?mXfz&CF=PZAc^oScYN`4fB^}Tlj-!*njJHr_kVl zWsoRFs1%oF4Y(yZ4OIrRhTwSllTO{tYIwz=q*1ir2Orp(FvWq2f?=WxC?|k#uUjuw z_yiq18^uu+0GnbzKF+l+nS~93qU{ekDRUfGqc6QxH0^-7-p)DA(X}9Y5*_Tj}35PC8+~KTpb5TvZ8VXRfe69zs~BSOK~9C1zle-7%2v z=K5(;lZQ;PMiIw$4zbts#TNC4-<#=^;P)mqCJ56TzTDmQcRXKBz@e8mUM+hh15HSz zRUCqYBa9XG%{K1%TMkr!*8HakHQqHmRc}4>Bic;QZL_C4g$$9*_7QP-_L}g? zRwN#;9d`?2D_-UT(u=bO%ps<@$FS|{{bta9D*Y!@9&Z&f%S|557)*l77FK!J<98D0 zi<)RA5X{3E(17VRTNSZ~ZWXDbnE6-~kq8o1e)cCVUjU{tOTuQTSRMTN`TmRvz}`>J zLKrBfU!5k11f+f_5`&gxvU*Zig&XMCZ8eGB{k|yYPZf;tB{cR0tiA!fGo~-&SlBzi z+H*jX&mbCM*c_k^kp3fZR*UhUEDavCNgDr4)DeW|NOz|Q7538cDaz&WbzMx09)p~-{DwajIQ-`YxnvmmcD*Xzrj^YR2zr16)M)>= ztg%mk4mZ%aj$+roe#5N4NtGCx&J^@A6w9@6rN=93WB~R&Aha$`n_Cj?PZsn!`e}yG zB@!?ll(|6AH~vD&Z9xgtMiJ_`C3SS&s1~gz*Yy!v*T*^wL?9DnrwVNZwBsqrC$j&#U=%HKJ=+skdGeo5xdbbR4r3+- z@AS!c2}yOgGV5HxJpGUBuQ@4vJ{au0s5bwJ(+XqQQSrdBnXP+zoCK0po_v%9fQ?=R zSCr_q)*<+S;KWp+uu*=6;~uTXqt=7uE4q)WtHgLw9T>Ec&OMD8T!HivYJnhSk-MiX zk>xB@v8F!GJaS-$RtB z(t2TXE~gEP?t8+EHbKIfAJkaxz@&yvS-dS}t#Cprers2!Q&exV}R?(%Wp$A(H`#}8>l zfF}+i8d4NkH4Dzz2xrH5NW|e2t@{jsz@zqNZ*ck)!}DGgWn7v&g$R+oVA=NKj9wy| z2~YQN^A8bBF30m6&GOnTGb64QDy;P+Ks?F7S493}X4}uFSq;~C*tApC0>gPq{3E`h z+X&VklD7O(j(rh2!AJ==L8Zu%psaSIRL4!B+#~0C`3@cWas#Mz!4o2;DVSEJ_ZRp$ z*QFRl>K2W;83qxRE$mH0_78>|)0EgD9_$%=6#JF$6sT)^YZv7rLbbe);RoPi?Vm0d zp{+9)wGP#U%8}~Rn8D+I!Au3))<}k`^dMI@KbW&=9@NctAtLq|+W8+ys25nWICj2> z=%)w>s>%X(YWLmvG)H9*^exHCs*mS(WYrgcs*V}d8`cUi&-0@$vuR$Vd@hRnN?aZa z7j(tPhnzBsRh3&*fT}?qAekP1IORx54?M|oB(<_gp`Zj$vjHbR&!S3JF-@RnTJj8s zgP36lp7s_o3ybMxZv~H^6)aQ0PqRjyYcoy*^`DU5<7CNVJdP9SS$+_^h4%`cf zi-(Ve%EXDt!UN<~Sm3ex zQI*Ba`b^cELET*XRS-;{0hDrHEi0`MbsLgIO&z1m@Ff2Ec8Ig$7gB|PaS8(gop-K` zzw^HXHqP97rk)rFe1Z2a8?0*a&0}5i&ijzBx(v*?b@)o7&BSb{~55AQx83kLxRd~g|$jC zm$^FfRjeCt7HWj!Dtvv!S_s-YKj}3nSngMyF1bPFFtTMh)M!WHF|& zB-U$bqMlOTSZ`65d%PBwOkrW_%#XbnRRK;R;{9|k?t@;0CcK*U*c~-3k^{IoXgT;+ zNs+12SejqEHG;0OF(7;zEdLQGW4RR-A}9#kB(AWicL-t14%oJk^{wgvQpfb@eoLJ&YEm4FPk7LuU;!HBd;s zx)yLfLc6+s*6-T7aW97ai}cmJt!+#_1sIUorb}^a=6g#eRu@4~P5W3B76^(%=Qf4x zFIT~##R_Na6+TmM@6kT(|C3BD;3f>C;wNQS7A%bAJ&Rs}%^zaHs#`JzG7z9*punFVV)|e5O9@73plk_|vBmFt2)DuM}-^xfg=F_eZ^Hf%}U$f+!^|E2~fwSjIMM zP9-1U9*bsDtZGXEO9L%rObLh-bBzid;zb&#dL1)V2MWu(kqAq=N&16M2R!qGinn9D z+NH>qXCfRWXsxh0MhVSLrR@091X?6PEX|K}XXw^mXK8(2qOs%z0+_Txy+&-yQ^ySN zLS?eH#fAqZoVG#9O+FO+%&Q+I)G>IAFc@VN*H&;LLJDTH91Y8jFbW=$DUsy&+LIk2 zSqBKFgsBzU(r6f(pJi|)Nn`F|AEV^^a^HSXcVf^H!Ri0ur-A>{ph!F?-^ zvXS=aizg$l+58rgnn{~0j!i&k^&s_jat$b*8&xE)LjUGz4C}F{PIRsbwEJGv)8Lc1$u|db6Nuq{a{jUJ=?8A@lN0EJZ)4jGoLMvL$g+u-Mf) zuh}oEPyJsoWYxp;)zZMJ1mb}<@0c`CC6~y!moo-w#Jp>lgFG`W$i7UCXnNyGG|71( zl1n>r?9~?Q{67HFKrO#&guSxl!cY4VTvbagvfRSfc)a~!YrOdoX6^_~?GoPD1j2*o zZ((N##*ZJu_Rbi#$K#<7Ed)ntT=BWJmD!D=OxV1RM_iSWPgAhiM7_?UxKMFa5@9s= z5FAJL!ou^}3wYCfxA5`|{BZDuULn&X62=uDwaoR=DKZNFNVy|vYK;agQH&rAFfbHS zAQ%?}%tZmGFtF;32pIjB_jlx7-41|vSRgaFd(GFP-P`{|AMk=1^J^{uQC0<(D6Q#h z)&K;TK@hlNyvN*Frv_}TB{@X`)0!lz(sv_a+mVFW$d;JwKXF4-Supon$^CYE9431O^AqLr6H*Um7TD`ix0FRTS!+ z7>bv@2Xye{HdZPw=;wCrEJ=>V1&a$ja+$&=VTXbZ7`#>f`VNM-@qB|0b3#p6U1Ps^ zpR|*U&Z71y4;8sq+OV4i`uJBt@GT^bTCYQx72z$j`A_;}uGC4*^S^2qja5N#{(gl$R=#eUo|f&aySn@C z(QTLfe^&4XpZEykmWz%;SatjNk*Nlc;Ps+nPz5wQW zW|u1RD4^Xa&upwT4zjC6X~89XuDOgLVNd@e(^M~l)!AanMbZn^@;ASUO4nK}V#^*s zeE93}|*kaUHk71yu4$s5j>)&z;zGl?Mblx&AIF7xU%2+F8mLq$ut;dV{X}s-`_SmrIwi8%Tf~IN6?dwi!G7MmL8E z`rzxF%)~NHUp79}*c7)FGW zDkB`V`n}gk}-U zg>)pF9=pN?@QzcoofJo0uJbVM^?GHX2gS$(l1{E<7GxM&$aSo;Bw~gv4j|+iCNN=X zCgo&ahT3k17Ayf1X~YgGHy;)ow(~h7JSef16Z)hyMaan0hF_;X;$}KG(V0J!w*4<7hyJ&0XAF#exI;#1VEF5cC36+_uO(o;2 zTX%}6IA)K!)j^phNwvr73>qyHbAq`e)6-LQ@TIQpw}{SYXn^y9K=N8J}Z%a&sDFL#ipG zmcxbIJOR2B zEIRSDLUge&Y5?Xb3Ip2FnO{!)`@ck>UmnOS)W=LK+c~)+AoZcpFvLk)mDB=~a_N;7z9dR_45N zMr7SX&PwDH>lGxt7;ND^pDI(8cD7q|s|%c@%8Q7zDvvepsD(;eAv36Am1MNxPcq8#%k?bhrGwYc+r!&7*9-jBtr6pxxB#r+;ImUMwJ(oTYIRlZCT428 z0ZXkCwA9LhyJb4}Z0TI}BwN0V8mRvwR)1`!^_!^udU`#@<$aq8-cNEP(M@D;n0f;& z<}12kumTE`i~H^gbq{Ajf48~Ke8hIEqZm3L3 z-E^ORn$Ua|yaM-7afu_spceDBf4EXDdmOBfioG>P}dmJ zc=h3f63ageyDJSAj%f6!rP-JR@IhI6%$)3-aC!X-2`=46duLvcUcbB;-0Y5TPB?Vs ztpPXR)V!ww88`Hr+_#+ad?4(-Aje_C#w*E%`7S5UrfrJb8OG|GXNlcw=RU)l+}gZ( z8?<&8;Q_s%k1al-_b9^uH3XFx3p^V{2Tz&-OX1CM?O0oH+c*|}_pjg-Uc}Bg zc3RA~gQV%!@i?uqiQ|dg87zvxpe5QOB8wW5O5*ACzt1_OWL9p$d+$)q7DBEFPMZ=-pZovBX2v(C&Hv(Az#4ev&T!`k{$lk@Q}Z=H z!_H3ayP??gm~*Fy_NXQftc6!WmJDL-DnbL7%oCA>LX;JVU@mcll+4los{Mc9zXkZD zZV0(yKBJ1Atm8F}=iWavLmZzf_3imV_%ievj;bPlR#@#ztyV+BOeW%U2+rt8Vx|O; zERwE>m_s_$aX9sk@H>}K~_jS*fIaZXa;dzCnbU0 zK`FA)G}B+~VtBF=8k6aGax)lyXr5Y=zjitdQaiJ`93jgxkH~?pD}B8{Ni^ zptMrgiulGBkh9G4qjw9YCuY2nKy6^{kntT4(^LemLo&nQ1at`)L!?rk1ClYt!&Fwn z1Ju8b9hbyqa~_x=t2ViS4eXI(y_{rsti4^Xl4@(W+u0Q_(wP^SMM<8LSp;`zyYTaWBNek(UySAZ}CV@su4l>~@OF3En}6Pt|w zG{!%e7+;V2!|AAd(;rSg_Q!*#guCweLb1dzbgWumCT3H!MIPK{vJ|lzGvr?lNSx)O zm0_7Wh6<+bk(0C0JdiHeS6AIu)y!|*n?d*dvR^sbySyHMx~ZNs(HVcdzL`wBH#gn? zl^11+5Rwh}wb3ZMRE4;42qDd{wwUH(+iV)J=G0fLh))jZoTPF!89$2x@JSdPl}3`O zc4TuxelmU&dX(+866P#bz_4!|u=8q;z_{K(|dJIO*HG@7uM zsM|I_2it7;S~*i5Eo9-^{0%t%m`kG{_DrJ`$f2+w6JjiF+w&wSp9kYm7$Cc-cPoxh z!mt8Au&4)R56sgj89_EFt$@cKK-H?(jU|)=@F|k$gU{ijYHuty(kt}Hm(6M9Yb3RZ?W(^g*OGB3 zJ%4N?(f=cY;OueHAc?O1JZ6FCt6o?kI1^^~NfNkAN&=*yKB3YAJ* zU3%gJLXopONmkw1i|r-tA^!W#*qeP#LRI*9t18{tp2y>vXI`9xzmj><8tm@2U>Dw@ zL>&d=k&LEOGyZ^fu0k`uN>D~}=D(h35#WglU&rx6NVl?2vMhf6{u;ibHj$F>M>cjG z2#YhN?}4Y?NFst;F+*@8<5Lx)LqY9kMM}G9nuK>6XE2(hUMdyB!OUc@$L32K{o9vl zk7^Phgbv_Ca4zk=MmSh3g2=trB?6V)>u5H&@N77IvG;8F^f`=p30&KIxUeB~UY}gT z%a<_x^EteDIfNI(Vb_VqQGn90@^fnw^J*}dMRuM}`hi*u+%~b8m_hAigGsC=gM~1b z-W^1MeS2r&Wb_6u{PzrA-hz7=p3oB%x=$`*gXgnXl?M}StVsW2JBo|`an=#5+*DHY6=3T845%O=#y8G>Ih;=C*-e;lP?M}h=msX-v6H$kKx5C ztN{MT7=^)CxxL2O-0@Emh+JgM&(H^=MH1rzr8RXAdbrlNR;$ITIjZurOUIc-e0t+J zWYsNMam761mT|yK!I)MN$7rpDsnY!nV1;w6(WY9$R~3cX*uecy(g_*1;G)hp>~!7q zH@}#k3_xft?mIW*vwtp6Z_ckSyZc_}?}Gu#uq@s<%e7Vk8iU5`Zqe8tEa#-Kk}hr{ zcM5kznkVO~R1y}3jngC)E{ld0&!QM%hnyK0_j*GnoAS#9IX+Dwq%6QzD8zMWJUhk` z7p^VE2csm)M9w^|l=h{ysP~R0ln3SMT*w)6kkn9} zP$WZU+hI*ylHS_bD`!ngv>)G}-@F}Nzdn6iQ+^Gm(>BBXZBxu`(VC2Qswm}3dxBI% zuv4>EP8q)kktOiUDaf1Jl!AHto|m{}x31fBo#C1o6vZ2DUDKj0tuatKq`sXhdMA%4 zBE?yrEGl$NV*2D1(WW(q7~|Pk+i*)xTNe;V@bppP(CjJ8nP#7wfRu9E@071%K|K#I z?U-&obV6YThmJ4n4dwPox$duywh^^iG)6{r+dn4ah$zf-mx>;k5#b4)WuL+h4ytPL z*pnxlqQt3_(>_m+PP-xtZj!DuuEP0?66d2eL|;9wsH~q}6Ji^-)acmjN;z#uzNquo z<849TLToB$ACdAiwK7x%MPO4A$M?Y5%vWDdX^=$dFGyL|@HD29$~Ntl!GvMMyE*z3 zuyA*4Skj$g)gext<)~+bj&Fr}+)`O;iO>e!N}<&tB;z@8dPT~Lg?x`Sl&~!HCmikD z1J_`bu>!vPaYRnFTJRE0w5E`oyATwz*&UW@Iv;c7un&tatgz>D&aGM&g!#H!ak$p_ zHBzbRtQzs6K6HCfmgU&(flTALmlcBU=AytfH&#=hTd+NcD(CrLMI%%(C0@M+n4dKS z{=S(-K5-S*p3b0_FjE}#OQC6srfbZSO74;Q=t@DkrQ)!yKB(FD67TGKyB1^Q3hqqzN3p`mJHO9vw2GT+?2ZPMhJXW}H6q-gR*H^0DuzolqEdGh+cBT z?L)2wl|#o6)647Q_KLV6Dd*?vZCc>qH_SE;V zmDT;8e^|+e+)q-i{{Zb*+j84B5PjEIY%}gqa&1x0q;@C1)R)+ar@m++b^4HaG!VEV zF`@tl0He5>{CgK5B~g?edt9ea#RCN|v1e~*7xdomS&}uv_4Nj&%} zESKC0CC%VELn&lD6C7*C@ekBe#0it{h2@Druhb?Ohtz%7h0mxB9fn^^*&$~ZW2JAw zz4nrf@iB`Lyku~qq5=iAf6H>4C`~Wnt;QI73F@g*5$wgL+#Z@wx%j&+(H_(^E}7mz~b`=F863E9ki+(6zU4VIycB9bduD4s?Ed1=~9v z*zR;%UNsdQrE$(D)@J5)7{!^ZQM^CUq&HeeHG>4BgM02n$=P$OV4D#1V) zpr<=!*aU&X@bNI?W%FYZ@|0=j_U-=(@)Uy1`U~JarpOGwp66>&zB~MvOrjDQ^9(!! zG09S#ptPo5$O5(Twb5ue4?T6=TBoRD;gV1g$Eq&6a=twKz|8G22J6+MPoN$nvlav`UVm{3Lhf9ry8qV5*9`)(PY#$la(xJ%@AFq8qTC#fXz^d^02bjj3r8REwzb5$&?X3J>;b;1kbgmLKfZ*`isir z(W*dJ6J60;C_2d-&n7o_NwrzQ+FbUvPLjIv0d(plSVOJpKH7)idg)3viOSQ6^1X7G z&MwkQYJ=Tn%nE~96rDN?&BD;eGPO1!@W0pc3a2iDpmjf#My_;piI%Q{=DY?3aW<#d zQV3Z}Pe-bN&Pbek@9PG>*95+v&c89*dz#>`^6xI!pwwzE!~FtVEz;*SEP@;OiF&j@ z`0L$y|FqXVIyqgbQi?LR2|3ZJxC%&J{U{?e$tevteipp=XkXlqAAGdIii!IU8>?ym zSnI7jvt01BKy+!?x}Tw^UozyDCiWJX%vG3;=!ODk)K$Gwi(R^gbDAzcn>sZkW|?ci z;wmi-e}{Cd{H?}F#OgUuj+`TY& zu2b(_^xz(~p*8p=UpwW@;#lb^xNW~OVf>Db5&X)aqe8ruVl+bScUfv9GEU>8#xdMR zs2`LH;dpHF>8bfM6@N7)+LMyTHPalf`K7c|jc}YKT=;2OgR99@i*aP(b*uIE;C1WO z8@P2M(4!!)YzXzU_cw5O2(4e=z}v$Xylu4_UNsgRrE$(j)=td3AQ%f9rNbtn6!>Fe zHZ(ygvS1jiVURFmY3@yMY}!W)?{7cARrZ~mmv`WYGf&nh$aIrZo$oEcvl6X93#=u9ENGurm9W%JjI5FtV zsnnTs!Ha-!p9$sKl#`X&sQjo@oI9S@ZtTKYkx&s~OF&x6B>fWx?pd57@hpz%TdN1+ z+5^*)=+(>(%u+lyMcO7CS{> zUOQjP&U{9jYH8dtOlvj;H3F;dh*Ft9REd^ga41^^u^_@oSNJRLXm2Pp@|;ieG9>yt zE4tqB+dnd48bu5B{^0z}O{ahP>86n*_!I;v!=n01Fg>j}8iNJj_u(NTkCj9hnebuw z=xCov?)nEcjBq8K3DYcDA=bHw5voLLZv50WyOEm=k!S*jQ}Hj1&8$$CU}aQ|rJCqj z>Iu%uL>b}XarnE=mula~ytgxZFC0R86aD~dgakoRw*M7S|=lMLPZ7EtyV zp_MaSb!j;`$z$_+?Sf{W=u9%pQgQp>WQ?}&*XxafY!JZZSSq@(iS|}AZrzO%sc;sm zgJcACK|t7gZu#5X$?xB4hI%ay=#N@Z?Rx{-?KX_)wxT<3;rxQ4NAtC(B`-eEbwG!c zVQs0PLU4Tb`6RNJ;~%lljm+Kl^gk-zd{L>vt};*ttBP=QYuIjHx3bA&cm)IXQv+fDHV;X>u95JLTFLqC< z5EAw%k~DFZx?^g~&Q?Qa8Ehzpa*K?)wx79QF!cmTU2Q$ud_BtfQ|Mpdykm}NPZ|-@OGo2~8nn{RRPlBGJnmbOe-ZYu z8s1vb&A5NfK&a2qSjN7u)CD~%pTm9W2{XG$-3umP@^9eE-@R5{Q`NPy@kE~F6?!?Z5JBz0EM>6kBv$7d*2^%GtP#cKqkI>Ow5MbuQBt7u^jpd(}uH7!lqFyC#X6h)@^#Ju?sfs=QdrHxNw#X&;Jig%8CZ~f-y3U?`J9vinZfc zdKbh@YdAxJiU$L?q6b%K=uQu=a~ChIiEasalE#>zFuHD19^3fYXxKDdMc8W-KGcfA zkbCrxYq)1|hA`o=om6rH3?@to+S)0CON`@trhpDqaqqj|G#iq5&=i#{;Sk;(yeb6& zsFYN{lmU4xb3kTsI04W_P4DDPq zXTHw4d&$EmjZ1TNy=O$(o>QwkTx3ACIN!c=G(vOh=DpHtXR8kvBO&SSMdfT13rwYF zmqa7*IMFj+f&6Xu=w6mx4-X+?vBq{KrFr2U%;p{!viL-eogPlW z%FrO5#3RqHz4MI}!;f!dl# z*aJ_pq}G6l4HMJ6*2?NBna%0g*QVFxgzgp0wqUn?05sKeY1`q}R$bj@T;wz(#EFTU ztnx1XTx8NK!t0=`IOjVT5g*r>`jw7HHq6Uv`2(RigEMofZD1UA)~a1gdS|6~1!G#> zt=9Q6=OYTI+S)l<)yJ3Ab*~4?p>fY z&5#*pYcTJ{OUkcMVSC-C^;Fh`v}?IkIt2^E&z7#2v#xZSZD?JwhtG~9hOOXJ)@t3KRsMzA!zyZPH$ScW*IWRv zRAN#4TPe@!^K_N&3oq~T6=L7r#gzNvYy1oCSl?6IMi74YU$JFKWi!ThGilNxfj|tT z%ml(vQqj9n;b2SMDR|dAh7a-oiTdCM%%jzl_7It9QJA#x?Zk6s?IhW*)x06p z9iK^Q}?zI^H>`8 z9c2ORADHBCJ}Ts5CR1I=p?g}%KPw4I#gyk*)rCf=(u1lC$#sN0ITx!e6a{MtNgpv> zRcOj?FiNB<3n@;)rF2*+xO5|1#|c+~k>m3KSG|)L-0~Y-@lI=CkGj$0DI4%$w~)3# zP7q4BlqnTPVBm6UBM8*rsD4p@z;a^u$0&76njj1XpTw1byOB@LN=6RpkkI>hblLSi zDo$&Zh1jrTW5=h=jLH=v??%a4n0ICRRE0W;Q_KgSkVGz_xq#@L;(&}Q7S}|2snr9{{i4x^WW%;Th#2|4v5Jf;Th&cz z3eoKiXM@GlQ%{3!XLP9EFgw0xp$&=V2WoFGzbAHU-|l`m>h+q?x6dy6Cs(IO-4p#! z|LW+h-)KU*>-5t_w}1BWqR}k){(HMke6n=*f&(rEcaYeIG;vYX0x7V%$9O>;Da|z( zd`?EQ$pTY7^{69l6I*tqd8HNvL;W&99qlkV%59bO&^WP(XbK(C?Mp=?h}IKw=^0i$+jVY3Jxw3f?_V5~v~(z%BROdlD)GNaC8l zzR(}W`R362BOY$fz0}OvT83ECt2J0D6XxQ(2UM_+kwzE6QZ&~yjfA6Afu8*fN@$1= zBHwT14l%fD!`Ud%EPyDO8IoIt_1GhGz29qd8_fV!(Zu;p=eo902riD9Vp(09>ugzj zdsZuVg)~W0t7VKRRv4CA;I**T1X>6M4!t`HnW0}>w!H;!3+|x}BYVP>Gp<|T{y#Z9SJX?Qc4RaqsV<{a6m=QtQ7`ZFCOmKCZkrx!28H^zHh%XYKdF75 ztG>>Cby?^rKmQCx9m{E56?Nsy&7(q>v(D#VOJM7n+|php&dq$!eGNSDXN$8c$T5$6 zm&!-U|4Znv^?LE_9EzCho@h(zu|b8zNlYtWSqCt~RLS)@;68$D0vFxu1!P5-i}=e9 zHDwC5tDDhKb z-dl`Hb#ZUclUZ*rW{rVq+!!gIF~(z3u;g3hk}DfaKU=24+cHGQ8+zzk*G4%0r1=o) zpA|k6X292+hZ?M-ZPuJeQcn_8J(i)^)g`UUSQR-#Pe`@Qa_hSB5Sg6g{B!5}fsKs~ zlFZcW3$C&_>HKn+q!u7WWaUz_ibt!OT(-7iHOT81NTtLjg9&l}I>ZXN zRZ_o@PRl&B*`YI<*%}K8n=r`x$VpW;$s;8_7ylb{a#QyAF?QCf^lyRk4RaI92Bfd3 z<_FNeC9Exf<|8~U-I_5qwVbRKyV+8%RycJ%ww6~>nXhHz^gR@7S%1mZ!c_d9Bv#cc zXlmV$;Z~0`fnr3~;sTGkx?_0*uPvp$N{Cj4)jq6Nk#Poy8f?}!1#Z>Xxk ztIbmFd5z0Se2B~G(yhYB zdj0tQ$NGmO=viF2GfU{00LteVT{t;``X5Jdd{T$wdcER~Mj=O`ZTw?nrux+LMxhzc z1{U0Nu|;g4y-X}=Z`WB9L~}HIF2(LQi8I1 zEw*mOiL|&*2^;WExM?4E$v4Y*Wo|6|>XvzpFan!k`G=rqjZ&Lc!_N z>CHZekb-McErLO9U`{N?|KtPl3!z=2)F&_c4>dWzbRe(nt23yU_DI&|bxv?hb@qF&+c`Gmqj zI0sY^;w7+a#h8KpqO<;;yx^Q-3oTn#A_=ZCt2ni_*gdDannjCUGC5@6hYhd zWDM5RaHk|}%G+r950X8?r`&r+PA#D82AOFcNYtWaV9Xwo$Qj6BS*6zffN{s8j!rF( zB@?2y5n4#Cz?2hezNcmU@xA1(vCku^QI&q|_=wtva$@Kzxz;yC*241ms;|bz{Z%GD z89&Xn)YfM7l|n)<7XwLS30pGCc*|9-OQSTMK9{#&FFI|%b=z@6CgZKT9eO37x2tTD z%nskb!-oo`#;H%0emM5}ey@Lj)4kq6vCq4Aun!P*TwxNdyrecT^O44-*wq`T54brW zqwUixc1`nVdxmrTQr~zc-Aos0k^5{X$tf(alIC-eTl!2sBc2;J_LCwpac#Ho5A9f4 zbK5o$e%G(qX4FWsWl728==ex2%dG9zI>u6_51EVxA|VN53Sa@yM-%_|ElMY(2ztLf(;pt464 z#Yv?J*SLk+-7P$CAV#MnxS~?wc6cAp9lAu*g^;&kmhDVH+)J{cU}vU1;YBD^+Eo(j zrI5G?Cz38;yrlA42oLrbDtPJFg9CYq;KI|drhUb@Hhk-}*fD+k4 zGa2FAF>`rzJlU?ipdB5qLP-_qCDGu6GbB)J7K z2Q4mK}6-yobJvoH_2Ycv4#9)lw5 z4ZHj;+KeNOP@hc4lZ&&#NnO8J0_76UH(+ZNbag0 zgAxeEEIEdKe0M`B(T>Z=?Mg83L9+!ByY(NC(%h() zw{I+gc|1s+*!i@edSaLAXzgUT&1A;8&F<*vmjwIkmm034FY4OY*h8#0wBc+Xn?IsX z8QlpijhThp1h(J;a}d+5zEMv&L96XrIGzz)1=SpGa(`)bclrpLq2N9WG8H#{E>5{T#P^_drlPMOt69dDZU zyJv%G-| z^r|IQX1hrqOeecG(cofH-6&?Xtyc}gkwlWIMwd+yzKw+ML1ukF697D1MFEiAwY{BZ z!ZNsyh1AZCIe)U|{PXl|;*3Y#o|8u~VP_9aPOB%x0=_E72EUF)U$Vw?%<|O)2p_$7o)U2uO7l&6tX$ z^%Xj4hml>YSPuMNLq5ZZmXW*>a|SHbtf+rw^K5#($MH?n)I5rrkv^#!Ze@1b;9X%) zkFG-CRfPBIz9MEmN)wRk)-&0w3GncfBLQ@IXtzbKC7I*bSeEWvTtb#&1K(I>3o5r`M81^`%UX< zMRR@XhlMlmWREVGkE@lXmU_t=d6)SeXZ>q}`57mkvJGbCALUd{Q`;~Qz57?}fth>^ zSZSxd08IlF=%G_GC3lZ3uWe0i$(3Yi%JAR2k{uEf`Z4XXI@s2(_G$OMU7x;h$|hpt zaRg(yMukR->j;liOg$6OmE(@ld)s$#*5a4e=kA4?v%Lt~{@@V2+j z1b0|yvjXo9mWGQZFA#zyxzHH~6g0uhTUTmBPB>H93a(A7?s=8LDW`4G?`B2KWfcou zPrFNWvof+M9lV~rnjF#N&GYbZs*(bg^%s}UHTIaXLb|d|Jr1*9Tlu}>sbxD^v9!`D ztGOixSbz{1yKfH8Z$H4NZr{VJC4}YS3B5sXV&XPd=vZI%E;>cBXife_iDGHNmE6$- zL3ca{VjV9)+F;J5u?~b*4wVC`fRm}h`2VAP-E9D0utIL}_^H;U_s#xM8&Pp<|7t8i z)=h;qX=Hb4?{K1rD2jYeL4Lo+REKMgvcO4IWB3Ym4o)wLM3Ua?k0kv)_n1yYC5a*h zbbs6ftZ`;00Cga}k%f2DrbH>^trE_2XRz=nW;hD&hwd<~ZG_<>xtU*nP8Mg^qmwS_ zN5)WP+u?h~%#9XkE%v!vU-Ti|mz1(r=u4BKj!+&QAYFA!U2QPitEVBh>pdQ?sPEx` zbQCsxF2Z=wM~Z%Mtl&y*z}6^|#%6CFSVwIzcQgndrO{Rfe!Kv*7p*aV+(Nd5u!j7@ z{N=EwG+tNdru-D#QqQn{w1claAp4mYLkN-T32Zt9-GWVGcBq@XeMYj_8P z#S8zVx}|1J@#UYA>!lc+JV$)W>uAce?9$^8yKA-*J%qs(wL&%+ZK5Ba_1(I7-*&wz zjB4})jmBAiUqz@(& z+@i5UNqFDcrkpt}mAMD+4i?S$ij@e#lFn3)0R>I)vc^@)kP{XT3nmqOQyW&V5YDo? z!Mx$CX}P|OCA#xAfztOzl$C?G$8V00=<#m%Xo#x?M`?Z9$~kRMlB5)_YO- zay_e%uPnHVIZzs9;M1|v0y7Aj34=LosAk};1i=~qZ$xh=4B$J~$Sj^bb((g*=|3vM zYi8~1W*@{_*SJRM>@Lgg!RR51B40#M*{?Ab?iwRWS4q+ub`Pomr&h!osW0e(*1?8( zOsAk0#EFDLnYaVk;!I5dYC$?<65hJWh(jnE$(<+5VChlJ=peWs+F)9JgwZm+nO|I| z%a30UPTQg%lLTenKfc$@+$fILVpqHMO&`LhqLP(F-uzMi`KA+=lJ4LMZ$uL;n|8&ZK+>+oA~RU~dhqBi-kY=H8=dk~8q*1)y)<7(-IF z)e^!M@|DX&gaq`r5+gYwz@Y8?chcP|k^fOS-O@Yy3n_=st?f!Y@Ye;>z`~?=;OM*% zGQY+4&&8g+D#|1?5%WZ`(Eye)nH-4;kzPj^!0yGPH4)q-nYUX<*bV_D~c8MV%}zGO3c3 zQ?JYaz9aS1ax%2Y`zfgW%v`00;06C2GOLg%n9*!ujv>@Dg*4 zoLP*o3dyZd()is8op&L02G*zzZNM+p+L=4QRC)t$+ppw|-?1fvUkTr+7(EJVzsm}n zDova4PU8|5De8NrVmMiv>h;WgDa79siT1P?@t$c8@Ag*sVG=6W9i*PaGcn$7A_W-a8v%S;N>0o$H5bNj!aLeEslIp zRj!Xtk-^{@eY+Hft3ng90h=Nel%Glk$_a)7-CEJm=eqke`Jwm`_;j~|If9u$es80lAV&k ztODA9J=m$s8#-Wh!L8DL3Lj17@DG?|Sh7E#UxQV!M6z{L(Z{Sm+2&V7B)hfB^}~)Q5a()B*tO0?h~nxQ@+S}3Zpje(~x}U8j=k^12Zk+EnDG!=c=vi z=r)P>on-3*j<(}pZ-tWpMk}NV5Qk;w+tXth3e&23xDT`03=)=^9TM(|D37~s@Q1<9 zT@Cu-X%~D{f>T8w#on{2Fo&nR+W54U+hNwK9!(w1R{iN7UWp80kH!o){?!>WaW4@%Ov7oEw_d7INDcjh zP)UrXDK)n=xgAQbjPNQTJv+X;Q=$g_&WApB4#%oH!tnm<)2e*kqt(dK(~{Jcrzw3O zB7J3@8=y+G`sIdB)dYkUvpn7Dfks=<$+Z&k6Vs+4%i{R0>+q;;&bTe{7&@k?`OMle z)-iv~EQ4lZHDMjs?UhoR!LU{_{6r%GQgV8PRGoGl4LebGlcNJ3UUs*eeebQ(B^CY? zc4`wmJZ-b~G20ot3&&+b9rh1^LW#+FoQR$1L{S z0XaAyGJ?CnASuNSbp*N5GHzw2F7!BH9)d}3{8_QNn1Hp!;}SM$&xld`D^ zYng@9R87MExZ}MgO9~`2`{g}4+l@^88RJEU0m>C$y^)Es2f*K$A~U$Z=4(>!9sQ;f zc*>0VDII{AXDQB6T2n7s;orJxwOTF~FETfFD1Mu3NurRX3(c0GW?oH~IWwd^$OPdwS8Z>K+uy--aR5ov4J-AZ4f(M`N(UK@S!QWv(PT zhJ>fXvqbwO3zbX4^7rXJEg92n-YCa=ks@r947l;rae^>&lPL-rgW*idJFpcB-I99d z0NciriiVbMmP5&u5uRpONBZWu)})9c+7;dp4k0~+KL9e4BSvm*yU6@81$tZcuuxuSYX z+rEUu!$W8fUbVZG^F1zVP3?>}{Y6~&SXV!4v%b3?0A6RvE%CNBaPRUKOmj=uCno`J zJuzGDgZr2fv&>~x+<^ze>DC-7*|R7*b|H0&$SU;pp#9z*+3po5Yyi>7m5$EPQq$>F z0bF|iL0LZ}K0|_RFVVCskhg#-b>5r*^bD!)9r1YCA}nk6P)}&oP~x@y#B@~~l|W}g zM(1SFP->yF{rzp6XLeb9_24cS_yeAGdm!^P?Sa)fb}tVe5)W*a4=m`-0_2Hm2+6O) z69YjI)I_yfeOOy}>S}b+Ix7{~HCyi5xT(<%#y^4lt4cp6Vjffb?Y$RZ)rZ^zP%imL zxAiaWSX*=AHWYs6SDen!fusc3o$YRCv!r1O*`<>J6WHb#c z*~Sp?<+w(x-Fz&PDq0YcLB6wd3Og9K$E-Q^B0kz-N<*9Q8l+{oSPC|s zDR^D4zddtpOyn6@rU*5pmcXfDMuOFGE9&@NKweT~g0{OmH zn=&;E$5n^VYi1jdjAbpOS#9j`acxed!gmAV(5iY;@NsYfSN4Ad?>~TfG(4gQl!z*N zMGIexESE*cm9@gl-FCsG!$X0<64Z=Bi0bhP5RVZFlXwXZ5d{S8`alB(%s1|ypy5&T zfG9R*9#cyVxIl{l_gpGsI>;)th!0}}?tfh%2Ph@y67h@3oh<udN(d`ZcpUkPOm`pJ-6b6s; zhcMXi*oGMow_8{5k=SmFh@A;25z@N7+)xz?Gy@7??5F*x_yaXLAA?6xr2m5G2*$*%LsMIiiwz-!0kR<51W71? z*3~GYY(4xfAzrNpZA?^4?o*gy^_dYDm3C$XGn}a!Y#L&2<{=8C%h48Zrm@g)OCz~n ziwt!h^oj~dj^Vt31-cxSj>wCcx*BQystHI@Tj1nuH{nJPbScYuQ)Ns?{a_A?C$7_@ zVcm0-GKPK-jiPvvi*5x$Qx%yG<)V(ZEXZC(?uzUll_}LqRRd5h)mZ6t4dZ)Z^_IM* z9bO)e2E&_9_fxFy_ganmZraxy%87ks9);XQxbbxMf zFCc=hSDNJ40+(AA>```NY9=p1 z!`{uF*_U6stzpOF?#FKRx`Scr%kJ5I6uZ+pc=k=__vWyD@a*0Y)ofoJG`l%i|FU~_ zw|)DJ*&Q@VyLr*OJPdm<8npXO>ze)8*Zr&Zb-Ozp?8RQA71rNJL$?eIC(L*IIL3G= zG56el?hM<5ezS$GTzM6%C-Ca10=fyS*!-G;#sY!GHwhPqVA;hi<1&E-+*@M&P=~r0 zi{m90p*3xp!UVvgikNhc7ITWtI`M4VgPk-r^TNzAT-K~_q zzr(i9rKNjQA=Yi4P4h1^)oRfeTczO-6ELa)TPhHmrpwL2Q75~sm8u)_ZJIlv3TeR@ zCQVh2a?srlG4GFZYi%STu}nb65_`m5ok@2{my)OG(dhYbtRGUMuw#+u_tbI;rt;9lBYi*SJws6}XK3OW<&^dpkCL&{7 z;lYs28NTWhfeUl)vI(Q2nrB%Vj?w?+_)7(Kf|J)NSAPeJC!dUnhR*)T_6jQl?KZ7t zwK+%~u5$8b`%yMYaoBD~T(_-{Nad|fQ3cZCMOtQ>+_=@+(&L(|5~8BJHG34(hdg_b zGsj}n{L1J`&aC>+w6&WDtY?Gi;G>7|op=>!^|>Py4b9cm)TkH|&c%#_v( zNJRK(X&6o@h@&u5O!m0J~c!WorH^2Q_RB*=&fC zB$Ze&A1&|reiy^s!w-2IS@pE!w@l5Nt1HH=irTMt`mBAxcDdF$HSV@9_VH{@b{Xj) zkEfcH6@|^3b^2;OD^`nr2|j~)YxCW6P}eeSB9>0E(KmA!UHBXAR&8_IMiBnauh?ej zfIS$IOlo%$J2A#`;uJ7r;Ym9g4|7NhXb^Ym-N`RW{NKBGl6VmzHf}#wUnJe#KD+zu z?(H7Fk0)`-+1)L{E_^_aGV})?4@V<4=zZ)B+Ts>viz#dgt~BG??$znE5ug)rgHnZp z!*AKzvClM)g}eu|ZC7IEPuUp3t_)ftK#PLX?y^KrgrrUQAaM-d1m&#|0UVB1_Ia%S zPQtHsj{03eqQj&Q9siu`dx>y3oB5&rEK2wyzL(*6qTyAevA_4K@$xlz<_PrkJ+yTI z)#gbT4i2F4`)k-gXuy7>v13J}&_}L}@e{3M^~Q0=p`Ikex-VvqRTHtHatfX~!$=IB z8B?0RErgGCeW&5XJB4=opTYAf*vG&VdW=lgDJaHxCu6RNPLfXP*->jv(4Q*M6Q+Sh z5hMx~h!JR+U=2nrB5xTFfG4!ch}X!#`2<)0KgQ3Aab6+-mlz@O_-4-6Alp0sm&xEq zOsS`*0)(?T!WnX{it$Q?OW#T*V~5Q#^Xx(sqEKm@C}N5{{7RNn5`_wsg;Yr#3#nB- z6UgO`Za z6Ui0TMQYldhKvG@M9nQTd}?8dLJlJ#*T|3-Xfq$9g!|eg3)P81k<}f${cUdeGQv7T z{Xzfo%3XJ}KR9c)y&rCLuiEXkbwh%AKR6E3U9e=$8aF*Dd{pKVS!6>EZYRWm;Aof% zEiINUIzV+H5>8+ktkDxQ$!2RQc@{SPyQQ ziol=tG+iwQB^D~Qbenk6zn@4+Rgqdt2xc*ded1#kKuqor?$4XO*`_u%DD&32cX?Kz}A#|=kxFtzqeuH*Vk#V5Bb z*Kl-nMCp2Q^2u${tLI)e`xloxOOBc+rF8-Mu)(+V#$0vlDe7D8rsu6_{Qeyt6LSCT zyWP{R#m+muw%c*L{jDXt?&obqS{GffKNs4L)|Mqxq-mn4QEec#kOga2djrqyHEmqC zHUG+Uw06GN=q&52v^OKiWQeD_=U`!ixw?hIcXfTz|_5$fr~=cn57#+qEE*< zsA)`DuvW8O9QXwiaKmaMhR0GbK)ztl4e?=V=?Q(E~gqm;s2coo}V!M0O7 zC!78WvxEkK;nJ-97UnT{@vC|P!$i|Sknr@kvZ|{bFwNkxxn~}lO;b!Bh7J46_q;tm z3hxRxI17Ta@Qw{5bd9^!)a#|*LTsHGFNij4bb&ORBo>wu#9r=?1d7h0H1Ucfx;1P= zT8`Hu8;il2fBh&Oo}UUfe#@!wurdeb&De}V*^+G}rGEhJS8a2fMiBn4U$M=&W7*?K zY9@6$Nt_xXWHZ5_0*c+qWHbn!B*qBn-4WZ(Q7}sc2%4Ngnlppr+TmH zvun^x(Ib1oBHqCaE9bj)9(LJrXSemEB`}vPz7`;tk%TBsbxE!(JpmDCkgDA=?(Y0w zAUIujD}c{ZhFN*NiGEUJr~k5&aT*En-F1XyRitdiGAVYGU+ryuX|-C)58WVY9is2D zr<$Zvp##@Hbl z2OcH0%yU}q(6KAIJtUEfQAk$AatBX%jOfrK%U>auLFXFL20z?EaA`MG2*Jy9n=ZHY z!Ei|Vl}#qpx(byo3L4rj&7}c{OjAP^o=CxP?3$tNxfFKhczxQ1GcP17PG{4;7&+F3 z<%VROwre`$0h!Gjns~0+fCr(0m`9sM)G`K5U}*V6qk%UFEV5jVO@C>QcV^=$FfrW0 zQ!rhfHF`zEu5n=nqXti1>yi?We2lLF_+W%2)yVfk%M2|tg3-9|*d~Se)*oY={w!;# zv3$N2j(xK8u&g0%uKBYJ&wYKXDsz0WWvkwMYH~Ne?cvD@sU%OqF z&9*PTN7wL(=P?t4)wixt*Yy$HEb+3?0GB$g36BiMWR*xot zVUjY~!>J<{`Y~KGn5%~=OR@!sILfknvNcPR$=zrH_JqWtWh8NsQ!GU;5`D9)(E;D% zl5-qFDsPcN3D>mWxwHW&aQb00#jsaJ-ZXT4&Xd`bGe=RSxBZQz9NmYuJDk)W0Gw>; zKYzDiGSomDi@njUr)H&FZTq<4{q%7^&arTr-2ZgHBbh^6NG@|dVz<`>2k_I$3EaPZ zdC*~M)4eHF)C^@&Y%}a`(*A7)z*&rH7fj-W+1_}01p8alKd701A7z?*e=Ab8z5+{e z%Ki_{tdd(cdt|2d;B}92j=v;M9xw=4l{l_Ww|=U;0d`xkSYjVN`&m4LX(@4hEwk!% z|Dlb&StKJ>;)WTtT2!GP9|{j!p#fi?5F7P*a=X)E(QGzMZlh_+EERFP3Vf?mF=0a$ z5N1yMzmqrJC7KpHMDmh-t0PdCaaFM*jbf&|d%I#(^p8rld7^sbhxk?TwzQ1F_BN|(oIBr_@9w_y$;UD;qxkSJf8m*GkiB?(WrsFT;>5ZAF0=2~S z%35O`yXb5y**(p|Opm@HjJe6})UHg`A5SLNH7}nG_iUEjvZ!b7KMET&F9z zutv`F$~q4xA_*^}mB@`bQd$nAS)6f9p(JWYfVuajJC5U-@_Chn1F`#2sh@>NT)gwO zI4MjLFNE{7X9S4@|KQpc)M{`nbtu7n}m)=)FZ8G!?tc ztyww{8ZbD4eoJAs(lc1*sL8PcN#BCfVx}H2g(c-1&I?zf6*>jwfY42)DLG7A;FA!= zB?FZ~cck=GSSwcD4nO+P(THh*y&j)=;HFFM^y7jCgY z;qZ8!!L)IW{!J0G5YD|>51saeIpJeOpny#r3hJh1BIftXvmD+V__Mn26>4|R%z)&zbwuIitYB;{a7ESwT;ld zo1Ra`SGVUkmn306@)XBN!?G2=m&}-yh|b{__kKNvMq|iKaT=W6-q1ZyrxaE!_8NIj zeTNQ-M>^i#Y z{k`Y?XD?u8T_7;`aBdRtj*cgAZ~*;RFJS+m5BvRo$8F7cj6z!~OJj2V+V@j#mc_gm z%a!kr$=F=`8$A7aCg=W&X+v`d5o6DMF>pM459j571ut&E4GT}`IWpBFX)Srb(qR*w zcKWTq)_yE>p-_WaBGg_GOQ8)D2DpYoV*;H1ktHA(KrAB7avlk`La)>NpD!5J#S3tO z88VHpAEJ+{wc$S|HqMyVPp1|5D$j6*!st!a%T29styaqtaD`&WE|E5c5*nBQrWCuk zX*TkP6r-}B5-_L@+%b!3BxIcQ5U`M{R{_*GL*;-%*C+y&ucqjk!l zECgX;vK36u6kBbHc)~M;9m-g&-87`WS=h-Oxky3BOo%mDjl!vyw#E+iSbP&0Y66Rr zOU<1)R(<-93#BNJC0jzMA^&h#2zLPFR5`APVW*7zS9!aYJo#861L91$KY#Jw5(7 z9?>TlUmS(gizmEKE+?b#ti*j9do-QQ!iMEH-jBk}72dk=H&j`0kp#5HWud7TK7BX~ z$FtyQH12}8uAM!2*6D&MvaIWlBj_5LFTmrJd*fA7URCm6t=fI-Z%%w7S^J=t|x^d32vwX`Pjy%Fg{Aq}WBm64geqc(mZRmbEwQCAAn zzTOC@0YPNjj~=7;Chr|oik=wqyQI7S7cboUWwX)Q9^QE2+HW3%HZsJLWNeS{%99#( z--Y%`#q@-3n55m=Qlz@g>YlQfS!Hr}ed`D9R&8_II1v8Muh{Ew1IZ9fJH6zlP1+FR zw7CPq#AJFmoeU#n0Um70mEXz+P3x{6~aJ4CUL;7Sv&?OYRA8v|ScH%zKPaQGz~JElalsgMgW z({>~#bWWxW?8vAid}dLYw6i49Ga+#jK1ntOZ^q=U5I!7ERn|RL-;&_3CTIFX$)ZOj zg&sZUdLbDcMiC8cw`@U0ypX|krr}MiwZHeK_4+M%W(f@R0=n9Vdi$gg2M5sl^)2il zv|zv0+Oei#Kp9si_?gzRdgnOPK+lqKlZwc(ZbC9vPAM~I9E!0M5v8$jAt-C=I}In^ zDRk5C44%)yHUp37F(a~xMKQrU8FOWHv~(&ju3Bft=v;xG5e*~^AyG_$n85Jz%5A_| zyX(0?xDWlSZWjphnix2WaLxZ~{E`~yTLj>eg$#Lox8!S-%^m+sG0>1G^?WHn5XB*j z7}u&?uhh8my;7-|K&;42+r{8@BDq3speiI;7|m!gN9IsV0sb(h;g%RoEg%e#7Y-94 zn;Afkb1W@T3X%;v_CHR>$RkV=PPHKnwPH|YeaB9JPZwh=BGi|oc^i(blph$k;(lnt zXnkXR=Y7h-z2h+44~1wpxEV-6nKB#6QlSio4Y-{l1A;TdRA6bbY~cdbhDbPqF@J-e zm`D8(FON@JB;Sut4za8y{n z_hHKP(2m#hTHCrhaGn*CK*XXklW;>Ma1ybPE5ul`8$;qc-Rt*O&c&!kvWd>M?@0I`3PZZoSf5T5@?X$|H6z0IIJ@{6P5_|xR3-87Eu&lwW zpVccECmJ6F2~R(3>%OW!(ZtmEkz2h~)y-QxTacCEk@?~|Z{ zCf$0Pb>VJ7w$4lzNSh71M4A$Os2xj4(-Lvnbz z6m0#9Qn+7x2j!Qsc?M-e_9ChL4eeLoZ{j!*e&?^42ed$s5?bxGr&9Wh>vnspdZ@7K zLscP@48$VXIom16?)HDbu@eF%(Cc>Z@uFQd*q(33-+VK6j!)w-E_pjUCD?&06sWjA z=m|a==|RsZF2;KBMF{j!Yo_MuP)7=%8MmrIcGk4}xeHIIG?xN?&Bo4X5ssyrgPnFG zG4m&EjNnEF9T}iQLFHyyVnV5C60Q`Ep%Ng2TLSZA+i`mcn4Z3r|csRtR)6(5HN z_M6Rv-Tmg?N9frl&^2?oF#%N1FK*%R5SqVzgoDE-95kCXXBu%Ig|?xD#>D!_^TynS z$*|$esps58Y^c4pIK5#chu)NFL+=j4$A2>o;L|w5DGH<4^N_-nzLiQg zA}2HZ?7%rhTpN%h62k-q|4Mrx^>7W^LFy!qr82sa87%D1o|qz0DK^hWJoh(FhQuC} zGcyeOOVoC{zM2}m{!}RbO8reM|LDDGVXalz`!#J^C0GY00F@$%&Uh5T5QzXKXQBnt zR>zE!oEXfQ62$jLB8E~%8+k}!+s+RKupYr3nnVe01905rdB}2Ls3ys=O{kGBQz&30 zRUruFfVL-OlnCEg-BJNs6jiOc>2Eo6s|dvu^#{HF-SzF&p!4T#=e%Deyg%sPeCZX& z7py;f9*SVqdx49tl2+KbD!)3+LfWzIMZ^quG&pu>0hOdo1c6~tpd)6AO$#;fiAM-! zDnVbn*M5jFvM)olZBF})iYo_Opm1S|YAS0(72Gw{)htRZHFxyd{LybeQHshijdp?e z#)k_B;T%9rt$-Rejg`}#Z_E6X)n0M2dqSs<>kGO{`pEY^f@-$>A&=qlq2g1pl}Bi|+v_TH8zM`F^@Ip+y?u?@rMuaE^xb@ zSHU;Ru@D+{EMY2-56x84Mfl}{P1>O%yg({3gjse>El)2Rwmpx|vnZnR#nq2ajv;OW zq8rhW3)@~?*P6pjCQ$$(dqOxS*Z@w!C6N%2QN6q4kidMF=#7Z!p+(o0iR}bhPSNlw zb##Sv@lt6cv)>C@XpI8KPgIrDwxzifGJE9eWJqqdXP^$d`*l)vYcrDFc!sn+M|+Q3 ztaEDH%a|HD=4KuIG?IjOj6dO2}S6Q^5gu+OF@vv{5hqbt>y?_qIwsiYUp z?9;&})_zFjDJ4l@i#{6c9m#$cUPckoAF>O!mQWGo)F0D~Djd10} zszc=y-3fxqhNNz6;#=VF)2rSOI@s3F)2k03y|@W2j$?Zf%7)y%zw{67Sle>jHV}Q+ zS8OwGB&D*XWYVOKmI}Nx4FHxe7yz^5T1%Ww#i`qm=K3CFe6`!A`qgnQ4s8xd6 zMrhp3F4?mA@RuRvGvNFD+kq!6j+LGR54$gk@Frr6;J%zcS3Wuv)NWLyHdLAh;a8dm z&&b@sS_3z$?(?8Sb0}SmPj;s%@ zr_ToP@FDbnxDO8=_TfRl-*%>P=?gf@{-49k3Al&h2|YofyOi#(MBB@=u#Qfay~bDK;|z^8U_)W) z9|TWnjh=<29V81w5E{Xt?f%bOksN>%j8PbTw21vYA3OL$g1uN6^SSgwG)-chq9k(H zz%!`E$3}y_aw_77q(J=F^X}wfLY2loj0y=jqr&z#oP!ETAX>~JGEPgUZwCd)9E9}U z$C-#z%x4tFcqvG7*$B^B80AZbVunDv8N4|)dBEE%gH zj%X7|2$Zg5OFN*tgry_eG!UfHvn(NvV@A=fwj2JqaJh`oIy-+oJRF>#J$=bu^YB%# zhoqO1c_kRqyNAYL$@dOigyb>R5RNQzVYujMoHnjXC1KT&p9n3cm0j|46eIB-CZ2Jx zygLGZ8DS*HU_2q^60AUpq^**%V=V3Sp{2^lD2XzWOOFb&nwwJ1B|GPBfp^0vk`BTx z00|Wg5-WY%$s*sx+)PFOR^pN@yRB=I(piSK&T#Gl?Uv>A-6vzTXYPBepxV*egJUtF zC{m3Xop}WbB2ALymVtI3MJg!o3N8?Q+B&xIa#;^DEF-2lRrZ2Pc6aGhqH*?`kj@Bb z)v+Lw{*Xo^m70yr93RvzO=k*lw1-v%-<`i z;+Fvh(<-gHT8VZzTW;>M{v!S zTr92pUE%QZ+Y*E-4GJ$LUsoZ7fgLKOT>ExhDPQ-S~MMbr3CbFT{H3oGCz2Ml|- z?Et7GV$0-qjUy!;3g18E=vrBjr7hnnhuiFA?$@BPgd&;Z>PSg5{9H?7l?i@s#$rVP z+ethoNUrh!Duea${7pRO5q}L5EA+X#$n~aeOl3U+Krcsi!dSv_-aYFfRt+g+;#6XNdTW@ z>rG67Sh@{lr+wbxZ#%!%n?7STZ}jXGcD)(DQ1_cRO7$Kqd6SkH4s58^MfLu5ch80{q9^Ytg-Vbu@bo1d(Y1x;qUt|^?UR}$u-on*fddh8^Gco|>!PT*M?`h1B zwB#lxTcg|Tb?H*mV{FrFc1Lt~UK!@mUAi?*nxBZa%TOB;`D?T6d_eaBf5>#_XG>it zl10cJh{LLBJea9-yrg?dk;TP{Q(K|R%kreXMs-d|mu2Fg{9-aQSlXz%S+mVu$t?^v zHJ}URMSXPTz-fi`&q3^EdUG-&anuX5rbhDPgborfHfudEJv9+rRWm>(fx>A8sDdK6 z_Vv+G|9XPLr?SEAVvKT3S&k!#T{w0>BGK+R9K7g|yDA-r-TD-bQg+<26HQwIrNS(H zXxFfnulzhjx`B~$Ts`8VnBVR~VKyw~s4JG+XHo_)nwx^-XGF4`)H6_%#N4p~F{3#x z?nj(yO1h>?s-i4qOK(Vn>$o9c%Od;^UC>5UF$2RZRuMJVAwjnI+7Dq2m6FaXD$%U0!kartO!4)8F(Jg*25Z1JnhrS^> zoAtd-X4z6-D70#ex}OJ8Q_He`$kneZTHwXXU}?P?(5aPi}WQaVSr|Love@7k++ zKE6}FjF-E*)fRz!yL`a?GTrzK?N)758#fUC?q9LZc;?RF_)I2+PJk3bD4|1BPwY-U zP{t#l);)aXDDsHR$pvswa>1eeY>Ndi>zoQJ39^7feVzVMLO(D zF&>-Y$4pr47c9l$TVYt9tC`(j`fuT?+6Q=f3w}9xLNAc%4sq?APXZ5{ z=%kr6zCRd)Oskmz)LLl+VhqMzG{7`MX^_L1SQcK7S&CTa|A4{CB6|ToV2;e-tL5v5 zL3Z+;kxg@E%zub0h-s1Il(uFw3>8Y_OQYc&@|ok-4xB&-4VanJ{2H zq$!I+X=^$`VWD?&$2291X7g~8_}`)&5qZ!IYRCsG)Z^-YTq!)hBJw|KKk4SL{U=^L z>p$&g>#$Ly=>ytQODYXnJz_~%Aj=|=IAe}^t30JBUHQ~#(;nzy=EkK=U9ABXibK(H z%ZtA(9bZR?2gBcc=kJGu(+lUd6Mst*lzd&i_L!blROSZPd~d@nBaf9t_cGz1;a^8` zN_|yI!a`nqPQf&r){^ZPks~xI)l=jDp5{53!Ug7-;5aoFf5uf>x|Ho~UtuHMTQ{Wd@UB8Z-g099ZrgmYkbqI8NbPqt5(+a@Jc6VEA z7Tuz05C_ZGO>uJ_r7AC{GP;2uj*npvzJ7%bF~=Yr3_rfR9Gv%ir)TGzux_PFS|Lk3 zyeIkAxVKFbxTK&`r}pD$ghEc7Cbd}VDz3VXYcue&$i?Fgc6UK4SC#P|r1iV@s30Z_LNg_xUriBEClBpA&@#HhTbvXqZ*Od;Qf z9PYM(`6lDzK+_avG^||}O3pNQ-GK%(RU{2>KiE2TI{fzwkr54??P*D!coAqylj{40 zTCzk+^|db?=OC;6iw^6kYo)?CKX*3b$`sYAXhYsO&?N;AY+c*$@&tI|E$&4MKap-W+DbRybO1XhH zL(=I3$7B?HlW1@xpCl8~mjC@$vhvF@9KF7tUTjO+Z&%-b+V#O7*(j?;8yhv)fHM@R zc--pXWbN7?+i-_Ub1C3=KX()}gF~sN zV3*wtA>Fbef}81`$OIh728@$KQoEx2Lf2|Yumnv@$GeB_xcqmyM+`_<%iM@mjKpi)w4-~%vp4q(J%t}%fD zG0dG6GnC)v|LOfN>7CsUfGbRqX?!#1tLN8_eo+T;%C!Dz6#yS+DURt=m(x~Y)V|kh zHXNriJ2v1LQmze1l8U@V!N1V~z>K&C?I3lYWl|a4^aeA#qdTTZSc*;kOyr(f-Y4py z?#(diE>I7P{b6D7^av>aVCz{s|Li<-<4NavI~)78HJYx_=z1(Oj)ECt$=ad!-NI$9^;%Ulo^CTqvZm}28Kv3=kvLY;&jYxjDb zrsN7|m;-`Ks1UiiM8>(5Y_o((Rbf3fb#3U@v<+2~F4<;Mb4QlV27Sl5QUq1_A%q#^ zGlzw64j`lJhc3i=5%Xhtypue6GL2cmb@(q7Z7q&g&bN<%uFqoo%eO-`?rQ0f5w8$|v^88XwF%peeW2Nc6#$Ws3jn*ex!G9qXb1I<(0jhF^PB4+mT5i~!43R&cnI6@ z;|G+M6ZDJS-q(-k-P2C{_~f(lhaKTcCO$sPO>50oR`}3HH}f2mGEMt9oWh@`2y8eu}5oXIQwVYr(f5pf;z! zkjtP^fwlyqFqSI0L_=LObe0zsnU6A{Pa9z{tCVZ3*tnj`q8%irE6h@2qd4w_{w(HF z%(Yc16Ej{&Ups!W`54+~QlKiDt%jJnq9{m+RLNrFjEbyb9rc^ zda8&vv^gdQ>?UHOS~wN-mMJEVP+6uOs;eN5=_SV%C=XT2u2NzEL8TCXCdmciWvwhi z@Ewwhz?OMha`d=b?ACS`p*S_qBm6fz8wJU9SR{m`l_EYZPuJ#Y@99?tU zxbZ!|0=;q1axBYE=RP`@IK9MCE}n7hOzfLHq^X9YAPF@^s03wMy}SS3-Ngq%5}@Sx z9?OTs5`o2HvERGUi+?QV%O}TApFUwv*)Kfjg-A!&xtLDX=+j)3TrHE7kFHa> z=Ow)yz;K-L;oS#z#|tH7&b~L_{hTHxpUGmw@HKq{Fm96>XY|eJOinmK;RU@-R^?n4 z@RI#f@EN^Ss;?oV{2qQbB(>o{4h48V^#rIHqN?WUP)GJ3Ag{a(uioBtxGYdrgfoRB)qs)`8LCKNsRFUg8SO_6{?B4x!(vuK8T-gHo+$p4qu0p1`}vW)m}ZGm zK~B65av~FpWyTlqQ8f=t&wldTlP8D>@i;zDfuT6dSBo+5gq#|V0EU|Yv(Duzo3Jr= zj5sip?A)L45@fE@d_JcCm#Z<5jqT}4?38`?ytU{X$x%=&WR`Q_@>1ej{60ZWXLRVz z1<$AK=Hsu!zCTYjCfbD!bK{)1uP&~KeG4Qo7bF&suxw0bz3~cU86*Y9EM&nCf)p4_ znFUEeC;jRKTu$Z!*hUlpIOGMtlS8E6B| zC~OQoIbpz|CF%@#3p*4*ATi5fE63_qESZuEZowEdriEOf`4Ll*>gCv5SReL+%!Q-} zhUUP_3s7&Mm0*OjAYdHuH3P29kJC(o@Ri9-5e2zQlO@;CK|65Ldh_It8`US*xrI`! zGN3&NnyqnUkmgBIB%3hb(e}hWh-aaVFvpX|Oj!I^HBReJo#p93Hd(|2!UZ9z@8oP#NX?eB&`RS)UQZZLr!#r{wjBd2Bid;fxer_bhYp_tAz=?!dlNB@L_uUp#)D7-It|Qf{w=sWV!-(8RpSC z7T%7JaEzYbvLy%=iH9X_jC1a!m~=AEQq#J(g+%>oYcUQx^@bn4obgh#m(y5u$j9sx zoL~;d9@!tcAL0jDOd8tD8IeB8tw9n8Ed~x41Qk8YgAThdpZ8JZ_kk&Wu08M&CZwGc z7y*G=0)QN`X9v$~GjUbESe6@@2;6z}vZ)ykU}fW3)h6Qe?YGs+Fen1y^U0Um%qH^q zkV+V-xtNwwMCyqDL5@ol)GDt7tJ|Nx#k&dgN$sQNx@w5`dY993I^@qit`N!V+XIU4 zO62;)$I-ZPV2>v<$k+K)YfYiFS4ciFgzporiF$$$P>u>Rw7IOgmj~LS`r!0peX!yV zEJ|bo0l`|&tqY_8#Z(3li3X4KLi=AlDQQyvF-(M9G=!L{#Xvc~FB>Xq3dFvIuY0Z2 ziW*81eEq54n$@ec{~_>UdqBR*vi7&&Jk=G2uQ1IifYPL-${b>oOnYQEqw}}gkf0ez z;7~Ao0$v-%TSj9J+OlA&hXiR-?)+^?3YzDk&!qaxXP37^r;ONC6v`Mn7wI7@Rv7Kk z5F#cXjHO+*4*GB)yS0}fA?)QTJHbDWj+)p40v{`LqER3R(8Gf_(6EHjjJwOpe|9t! zj(}bK9N4Vr6mXQ{a$i-Bt@R%e^S*Yj_wS51&*Z8wTg3>MQ0q8$;j2qT`B@0valw<@ z9ZuZ$9C2S;#r}C?>KSUl?y00CX{yg?ud5t_r`~LQ41N~T#v~X3a-U5&xQGkXhA_nk zWvm0uT-#7bPqhx4Nq_3>hsVM;EIPO5$!K;LJPm6D>@oCxerWhdZzyQ;Jf4~;33Pr* zw^L*XF&7}Da{v@zVcx=rHX$}f+-j*-%43j9H$j=4VhBR9AAIe+!=#vz^Q(NAD3^;> zR*ECCEp9OC9yMUESDIcTUvWIy$X+Fd)m&GE4)0>-tNB!uX_ z5Xl%UgEZM5BH2CCOUWicFMCw*|Exq|Qj|3oS>>5MH2reHDHRJVHQ{02pOb803bd|! zT&5ANT);EiX3Nd71y!mAZDfuD1`8d4%>D(+gkxBd zyAsLsDv9z}W%9Uvqr?BI_Mf+5PLeWVF453>Up>91B038CAO3{yJ#U%c^iT-fskm=A zSjlAaR@@_B4v{)NO(ZXr?6duIOQ8L}-ta-25Oi(?-ke(K1T@94)^Hl4NB4#Ui@Jpg z=1X=GTa*^Axs~_4pv|9YZTFgk#^gP3~rngkv zb6R4WB{QquWZnfAGxwP`TY#~0K8^-T-fkx4Ex0%IYMFt&&^Ee&`Wf+!Ek5d!#SFD^ zg0&*DP(TG53?B82x72O}Y(1@t${bUT;{s4Z6{}rurHdO>8X+PL9>OkTJ`?#FVS|2X zgcBl@)oKh3MXc5H`Ao|(JF)x~2db5ErANEHS^x38^lD-9(_dgjk~>Gd||!nj7yDomSLsSOcx;IZDL(07+LDRE);7tm4@n_YSF23%y#9 zcxaRWx>cTX2Qo6R42d4!5 zs!2yqAm*?HvSlKYChPQhgdaVNuCO^oS{tqC;Yi@A#9BQO4 zmq`(}$7tXyYYBjnp-kWb%t;nm*TW~Kb!Z_eS+iJBbzq(>msnI-i*g=Y;Oy1)5c4CY zX)K`t9<>ZkV&CW-#y33k+$%lO1X@ICe%m{O2g;?OFL1fP075d$Pu>olxA~j zpHT8~r(7e65+xON5>azRhtuk3`5N)CHlWwT_vdF<7gv{^ZY}YagAp+fZKKfTueM}* zf-N_w@JZVz%ohMu{vzd#v~=^ZFjuxL&xQJtB*G$vs8;heug44_44Xdb7n9} zQF#fWgiObAXn{7hGzVjgaf@R;ynGYg?$#~i8!%m_(aJ$T~NKCTcRZoExzwF4h7Ct3wj-Q$4NqqD2`?}wNEoXE~VK-YoIkpqAo zNLV0BjOr(gt+NFoP?eav{3kj9sz6o03M)mOJmKsqB{T?d2%??a=o<}@oCTb4H>g$3 zX%8`tMyFdcPl2gOM6JMFPfDvI)?JYe#UW#-o9>j!o3-ofc{3_@% zaSqERJ^>-dFcV@gk!0ZWD^8Szc<{*fn}zAsSy3>>(#wnU%i#!{(xQ5&ECfVtHW7Hi z^BH)irH?a-<@FG?`%!5&49sW^- zc!#YHj|k2fAm~&axcZ#yG$my&b5Ks$NnMhM5Beonx}LSnwE75S?zCc4(kP-ua?2T2 zbV!BiLM?(*sD=oJ$qLeShERGD3u&aiw011~D%TRc*<~RhvcX#zUb{5*BUf56BI;YB zR>HGc$qumj4zcIgF4xLYK4j7AI4W~u&XNveB6PjQ1hQVnfChEJq_f55!hfTksDlmh ziK)eRfz&albxd_~xKic-J)R}rCZ_FgLQHn!yk%w8plb#~M9z*>xyd*)`6Y$%vPj!O zxAu6;1T0R?eb%`no}}|YV+B4ts#D`&L{+KHRv~ljpf%%4b6N1&XpxlZytn`RzmEU; z^mnYkn3)IU@^os?pknc=BaW0vb>oz%WT9E63u+SR_%NWTLz)W5eHZKyXLZ5TcNl;{ zWl=y}Jf=#D&F?wLoh5-9t^WD+c&|>Yt(L}M^2z32EK2p}@>Zl|%pN^x6F_)5lH+Ma~SIRDM_Ojf7y644WDGPGdG;0b~d0STQQJ-~|uibcRGO(%! zgHg-z3Jt!=Qk(2x#;2W{)i`xYrB5~7Ze?m2;-zcz-Eva92u|?Z9m;iKSHXsx&ZliP zAG*tlx;BTTqg{pI%?b`GzVd-t!9nK>SJR_J0WZ-s-SNuAG3-2Qcb`!4M%VPc)-d>M z9iY2UZ))Na_2w=A`S#mD?b|g686Yp*q3xb^!nhZ8Rn_D&MEHSL9~%Ck7NQ7{udCym zr3bLKyKov=z}r}DXOZEtV6s|pw_Yfkr2C`x8q;))0Se1CvK=v+zMIbAiv+mL@{VTy{R~TJ2faGL9C1N;;>8 zTh7;KE+jFS4tDbzwzqx+jsv!jEl{SDq{ciIDqBGBMD<TDW5^TfZp{A_Egmr&w zz5&jy-8;1R-2&GR&uma)+g@8&UXxmTee1fX7t3HPIfl_*3OCTsTuSnmp0Nc_s=MmW z$*IjV_gAYVQHlL~kqeKy2e`WXdE;&lRyR>~xP=9OIOg!}#_B>#=r*It;Y&8-ws*Me z5^L+{7~J)9zk@v3HecIL*HuK9+PJ38HZM)n7?FQSup@rXl~8R5xcd@Q&K00FT2>JJ z9*r7Hf?Hwl2|ff){o-JtIjN3)JqWE|#u?)B{^bZw$6ny(_CdY9Dvo#st*bf3R0?aT zc9<=UBns^KpewB&QM6zfx6qaNG295|Q~jF=te1&fUiID|m`mw41!1nGNBlzF)^4K) z_p=b#Q;TX#jKC{&Bby2#o*MgELSZ~5kUwV=p?g^vf7hOcmt5m9K zWfB8E=)3Y5UXQYu@SA{4Ux!W`Q-Vsv>W32>^+KA%aBG`kjO}-?FIOqs+O-ICpZEb{ zcBX|vnJ#G*sf;gl%Y*H-)K~58)u0fR_&p*2Hj?={2kMfb9>Iu|QL`sc=ea<+-FP#q z1vb2yScm{Kzb+xCQ|w;@Ssk!zi6Bd!O!~~A7M$E_^2Yj(Ny=gkM*l`epk$muyyW?U zV$$}3{B}s-aN7!v_X@&S8EePySLQJcw>OjA_Y?PGYvvkTeJ5V|fCwWJNX9dsqG)Iu|ETWz9U%dlz!)<1$Lq7~c;yBsmB6dv6d$=Kn4MA_l@#;FhOSZ#0G zND%(cub5V}KuUmCz2=lQy%0j$NNI`+y?%%yw6Pah#dv+Y>rk%Bf4|vT8;os8qSJjl ze@N_onVos&nV03mAJHtTwD zY|4Q~#y#otVJIdOuEt-MLm4ZN(=rz0aSB(#C&i~QoN={~(uWUIoxC3Fzhd!sE9B;* zJ4!}NC8je2Z#tcK`)@k0-@?!?fq_}Vh4G=@J-LK~1L*wz7Tz6n;9aNFpsi>h54F{4 zW=y0H+wG|^v-qav$$6WO3D}Kp=M-+=1oEamXWHO9iST&K{4{VfJcSGQorn)_fgUR! zrAM5p7COZ$-%bF@OUIq<%75>*|2<^Ir@RID#skhYKU~2uPUepPr7H<{ND&;N~K~IBC6PD4~;Of3N?}h$)VU1 zoiMxCx6H>MKKT?Gj`J*@g?y zqcRRr821atL`<=H0mL&AaHygOJx#Bp8Hb5|x#1$5g7&O~R>D##A~aBVsu+;o?Z9AA zSSgXzg21upMY;pw>v5Poo zSR<=`d_Eubhl6gf--P- z8H`eh5gm=ijE}uQYOb;n;R)yqfxGH?KU%-M2b}w`mTtday~^W7>`V_8YaTu$9-e;v zesa+t_r6|yz0B|2wcD}y?E7VJbY8wQL9)j@1cdNP6NLyZbj-fDO1D+*Qb(+oBd@L9l9~VRoExx;=KA*B&zBxRsl4rh1UrYp6Zg<+gJ8jEx8w|W!L6=&TjRiyz z`K64+QjHaBV=bwiU0h<{eNhLyT!b;-T%21-329q8*qRB&t`umW4XUh;$lBln+lEZ7 zpm{!FZre=pxVgQIeUAeo^~#fSqu7-c3qWifk&mB0yWh^c7=L9J>`eEoSfY$njH0KR zpG`|eeOH-#V>78&yR&H!8NU(W2#s980xL6jmk0|b_Ezqm!MOzpzl6>UbR9(#I|*@z zHwnP>hfRgy9$MXkbJ~RjP}rp{uw%C^DV~ji=}ClX!SnJw+p}sNqlI){D!5g2S8DdJ z&OQ02HZByNC*ZoOF*aweYD{Uy$ULdEaSh0+EsFG(mgCaPV0t@xJ0yCWuZ)Nl;GpwwF32bXjy^vnhEmsb^ z>+1%2k9x2zL6z>tJBvxk8D{ zrsX~Iu4b@NK^vEV`jEyrd~i9D+L+V$mfjpTlNB* z-lFXNH5np^EB^rPR^M;iHV}UIUvV%zSV~>X4Z37V>o%#Ab_FuWh`om)%>-JaEFu!A zl2lx;?fQ67}(hxitBG0=HBuCOG_B?i~k2(}j>LFvoT$Bf$+>P_R4xNQ89C zSrk#}|FN2iTn5yNkzB_@q7;0PbOF&C7I4AGMaCiuV-(JGO;Q$T>1J_d5mJOvm}W zABfbmY7#P6-j>1MJP~s*B}k6+EJQ&2`iq8l(^EJvewXn42JABMh@Md*`^dL3-YW^& zM#r08>q!CmpL_$qPDy}Enoy$XQALAao*h3iNL`s#Fws~T1|<`US&mE) z@OO|)iQz1)MT9lvBbR}&3LwL5q9Gzcr||r~@ZAa){%7>Ef?nqVQhK#(+hOh)uEr## zFl=0S{$@e7`QUisV7x2wl;|MFaH4pT8jV91fs4kpAq?Dxr8cuX7-Ks$@v3hrvFzPD=Y#gdO~ zEe|VASNqou_sUF!T{dR+#98NlA-&4(;x1x59Mdlv%Vu;jp3Y9jGyiNnI+;w*PW|cZ z^5ghJ51cyNp25D`1D+>I4jN4>Cz{U#Qat;+??ZVLp@tyKCL?bsel_oX}GHWg= zxp{TB0#hLRhw=Med(ZstK3><7g^Qn3R$P2oTSz04C;I5IS!&9tp?vCDteg5{75SFsHDu(TaM|#bUms_yWLoZ~A~icXv1`$IQCd-7#fODNc-(aXV%x zRNNJF+w`!);|06L&TTXQsnZ2Vn55-Uw)0>~kTINHJENu;tF2~{cjpa_ILh@xyV-_ zA>dTKrn2iaj)PlE4z>choD})cdKqBkWtZETHKC3F_j~Wn%} zgiqKtpGNRq&H0*MB$7|MfDmzB{&LA~c`QW~vcH+Nm%gX?EQ;3*U(?Fc^KZNvXS6at zi6(p)is_Wc<2UPJl*B%#ZC;}0Q4G7-&oQ5|;he{-D4MVzXVQFpDgTv-U%Me!FZ5B- zavh7=T(NKW_rHJo?f$dx*buj{OSNX_YQkE_uLkV-bGHA(ckKJ;`|SJu{WgIH!snqx zn&wI^;TzoG{ls(`~Va)<{yPrvehg~ZKyz1UObWG<7=s6&sRf` zgnr%ZFcl}f&5n+a*whOoeEh9}gzWJ+2Js%T<_Tgi>0%RB7DkFqqa>U(4+)u?$I*&~ zd{siz|LF6j0*h$r1KWp@5$tC;34thOv3~@-r=yjFMRij_H*g zpUk~5=-OUDi%!{kznm-5`|3#HVF2i zA~2EET)GC(!oR%rVlbQ7Tesje5zgA?O^^Ov#^M%Ci0zHVEJQOqGMn|Til-@gFl|=9 zJ90dI^EYONoyeX|1;-9ejREiP0W?aNzFI@nw&Y&7owW7HqK9=1*1Kh&Ju^?DF_3+I-Yyo@8C zn}EtQYE^Utsfw*2KZ%fDQQR$sRiNBkl!E)I2q2b%{rZwVju16|SV2<794@3jfvr5L zi;8Xmr3fLT^Ej`iJ&2qB&8326M7fNlAZjgI{xGb5633)Q!iwKO8%)v){0RYo@Rqob zxk}=Y-9}WmSDEXFtglL2+mT<0WGy1)7mqdJaTY7 zeF0uYl*pE~7BY(-d(ENBScp(dGlal{IXBh6&bs(jXRwq%7Y8W!nnQ|Zz83@_gUAYw zC`B{_z)R;B$eN09avAem5hXI8dPn2;znqQw!^`87e%^^&nNd7t&)WHyVG;!S74(pF zp~yT{6Gl^pVHAO6F<(N>3RZ!I=$b(>A-wAVYgMVO+4n+V+C>HnAjXdn%fONZ6>aHj ztnZCtJ`^N!^`Ys56*RA?dLNDde*E_A7`)xpDL&ft4%4-}Mum(~yc>=Ib|6w-9p>l~ zScwC5z}3?irX2bJ@k2#HwBm6qL)5;~ErxD3b|=r)XeXwUv$dA1jXew(h6VTVyba?A zR8Xtk&W_q!c*>sxUKg>;A*gaTrcJHpr=Dp+dadr`cCYo}pS`Om?Vmg{YS{%+_dY>C zm6Fp*(YM)OfcO0(;oB=PC(@H6VsqdH)WzuuiiyQC;Fv*+$hAArQ;H>!DJMcV zd}(k3+dVly9u6JhYa-JFDx7}+?E)mYvp1LL{Wtx=XxK3acbG9e_Jlp#Zx@h~KRJm1 zQfz!{C^$)ZswHJOdV4nbx#L0=4zI#lVY${13p-s$tU!#M$pnj{R@E6D_Vl@S!lp5` zW);ho*0B-oK4H$RriksXQT^>M7f^qWnB-IdLpFf+-CDJ75UJ5OE63FTW5RHX4k2A+ zHq~?(AVRkwQ0jOgMWL&bn@QtmF6b&s0-PY=SRwY}wceN+IFbf}0B&1OF#wjT0&j&Zd}o^k5C* zzKN|t6y2n|!3c7wsP1V^J10$o)ZB#~z~m|DybQXOBffr^_41q{tZ(^z30ofq~`)#XjNF?pnAoT0fQ#^VCc4?S+Tr`g=WZBsPU%(`lXXh%^UqfXR4=G_j_P$N=& zpdbr40HsH4^wu0zJF3-U-arICxyHMwTdgpX_eO1{v=yB)rD8J?_|#+z_bEiq(&_ip zSGs#Ah22%YDX$i?o1QqDAkru-i)kYtu=3(VlfbA}s;wac#fnPvG$y%#sfp`J9jKA& z_B;;lB94Dlqp0?hEI(^nY?20~)d`x8{IZEI725V>N2lMjHK?sps#Rxdi%mswX-ZT{ zZ+0O))bqrA>;tn1qwr~Z2dpOm0AS`7kNzqj9j2oavxw~@vsaP_2e~2|QfpRM8+5ea z)Y9W9^m(&jJa`L|4U-(s3i})<^d^%&a%L{TJI>ISH3v~<3&1Cim+%M&-Cb^iUpG45 zIL-I$C_J0s>w&hJ;Nk=x(h}xZyjkTT=2sPcsR92kllTg=t(osz2Jo#u!eZO;*>vOZ zxzqd$-34i#Y@6a|EEey8?lY**rLkOv=1h+5tx&mpIE579%=9rdR1Nz!P3a5y*BQcB zG~&)cnx1=3rOm*h#KvdeRTw-K_Z93_Vt-t){W_qCukLnWkJJ)v&b1hSh&DF|V!^c}s1SsbGwaWkP^@YB<_@mum z6oKD!b`wS`7ibEl5`ABKYQF1@$Fr+)v2&l<^cR`7ZJO|G9w^%pj~x%-sKACV3M(rS z1gL?K-}0D&EtP^=2r2-n2|FReycrs|-!td&SA#KLLQt$RTMJVxH_%X8mrRaaZ<0I;J?D}Z$13JIH=C-2w zb9`Wv(0;!S^M68oHH~w@1!~*qT+dd~N2jfY%x;=9c~a=4vScQ1d06w~u&?&hI1*_| zh^BpHx^>ojAYT)1{q9S&;O3MReR^5Ab1S}#Fcw1857q^_)-~k%2ix0P^7^Eh+QZI2 zvD56?1e%rRRyMTa#;)a9ustv@_tZS2Q$$n$9{d$l!jW$H=!&Y<0C z*5-u1T}JeuL&_rhyp+CCK%bx0D}>|ZapH*5c%_(hjxL(39t0g6*xWs`G}Yzc4Gk`} zgO|`yeFfpUs4Z=Ft^O{}1=BLO3zhP9x8r|Hpg!6GX=3Nw+^!T0QJ%g!0960ve^y-| zZZMsgO%&D|{|4bc!#U*YYq!91w64h|}C09~m=#Wk2YGoV-6@P%#w z)0!JFs{l`!bior7d{7*ObiB~zE=>5;$IoWYS9B0+?luw7Vh%nG;EpRTdp>jBhvCzzYg;MZd@fi%~TrGXyg|{;u zKOXBpL-AKra`P^_$`4jb%;pB3x7#ldpSPdAfT0zEfmy+YaiMl{+J{%Kp#94Wc=@Ug zFWc=pz3K^vOKo+U8x!c)t=3GKc{pi0{-QVIMu{ zXnGvYIZW-tgbO(X?N|q`!4ec94Q#A^Z7=`^29v^~1ilu;kx%&tPN)>RGtw3j63A~{ z7J@E-z-Bq7wS@i1@@?+B^M$+9dqG5R?GaKMscA(w#~Q#jr+Ncq=y?q=D&!f1*G6aI zQLQQSu*_P0WBxJ%#GT8lH}C^Wjxd?~!_i59H1760Cxc=4Y&;xY_xkUPCd9tK46*o3 zY)`U@#o&%9!6u&VNq7TuZJsdD0e8d{gEYDqBwpMsgZqRT#bnh0b1<{8i+L+>D70Z<>d>oa8WL{GFuy1RdDgqy|zxU2I zO}JorYS2n=8XRL8fw8z;Q*OY<(x%>a?PDUl)TC_(qgiEq%U8P8pj0;3I*MHI zMPOF7401g!tlJn^>$27&@Piyi`F$Jw+c(lOeMDutcfRXdx>{tDDaN2k7(1S?xyt5K zDFC_Y@Nl=3t(roHe7n>`>B;79p>EqXQJmcts(UnFifLtc7U!B;c2M28-ZfnbINUx~ zblhwWv-j?wEM8{*1k%b4DT$w$pxCb^+|YMA zYXUWm?c-TA7B#31+0IkKP>L0OE@iuL;kS^U!v4otPZOhrcuebF`t^7V@5xus*nbTK zy&81;Z$S0j52ageM5u)ySdwq~_V<-|i=v?NH`P{cPuoZk{_bBfC*|q{g*YGz zCti9`8YmJkQ4^^j5Q;YTB(X?#-Q6{itNPz>X6?j@6DX*<)18Hgz213t=9y<^eE4TF zO1xlW!-EZI3vJMVkP$qfjt4P4*bzdcLI~Alg3=loC=G*DhBj8xG|0?Zer~ggp*47) zuN{ZN;!x=+@N2h{i11zv5!_1eR7Kd4@nC@3y%nh)5jb7v8i&vsp?*{^}J4*Wvq9$<1j78rBrO1N*SoMR6 zFqZBeM2HRhWZ`4y6I^D`IlR0FcQHJnCn$7-vct{?Idf%nvJ5;g9zZo53uAit6dP-* zz6+`6HW}LQQWwi%?<`MTzT`Ieb+9_c8XO%R!9a`+-G2AjkqT-}^d5nK%INSGRFKM& zR#F-H2M)}Rw0Z=IkLBF=T2CP+Y+ua|tQ~kiykFO3M@$ezwmVC)u>>P@REK_QK}3-O zlO~DM)*+m1*5Pr45|l(x1BgjjR^1cHK<|kd5;L)eQ6q<# zArUWHOjcxl7LO4sL_}!ZZI^U7;F~^@pI|~EWdSxrp|%ApSA~=t-nT7ji%}9~Vh)kL zWOawB))Z>y?F{dgS1cWbI{*?&2u8eC$s%6~RijO{ga;Kz`C8z9leAB2ninA?8N1b= zkWw!~t2vyk@i;`mG41cqkk%U=cyoi?WolQ&*3Az?v|YDetsN9w2Ql>%psi*9vc3EJ zl?hTUM{SLR_z6wP^!AQSyS=ZUFS@Nx`{cB>=tka^T6Ds)D{M)C53x!q9Db@pwMgwI zY}M)@)A2ZO$i<=D;Pdcq7x3?H{g8b3@8Gv1_UF^hY47yr>Z*0!?VVoUbXvXc$$4#o zQ@*kc7T7;lUGG>yE%6ARJJLP$RDu$@n5sp?vapx@{ za}%bZsCQTBwj96`8T8&6Qe{d@Hax@pW0Ayu*=%lFILVu{(YLyluONW0=szG28X6^` zR)#0hY*2t0Q$W#_+eS=rO;AYl9MB`uAAOqeShTJaXk#5pUV#icrs>^Si%^VWZU7vh zvz?>_;=If7a;*7#2INIiRAx@Hf3W_X1-;UMZ1Ji2SgyNl)WIkAu9ZFG1O3`6%z~ii zs0*As#t&Ba5JwamGlUp%=cPVLe)q?M<_irO?whQjr2tpSsw7llFBP89T1>0U#nS11 zxwt;Bmr96>hbxqcyj4vWD+C$nwMl*r}?W**seXNxurx?v@XNM1P`T`x%emY z+@bkR!)kq+m!1Hr)*T-v?Hj9~EzvqO>+rr-RO;s1QhkkN{vWyCdULL&dM?$!o402= z5>{|G&d7K!Eo%aPgH9+-GpW?G6MwFlAfWF!V%00HznhN087bxnf78F&%5!ZSZ>C76V54}eM8mgGdN#z zAK%{J?N(85+cpq>_pi7CMrC`kdlqLcx7TYy5B^?zB9{Tqyp%_gnq7F_>|BbKLg{4~ z@Q4SVUMHyR{(v9`HTi1-cPJGXDg0KhodrzeT*x(;ZM%}OV8P}Hc4c-ULbNO>?Jmo8 zEF^8hpAzTb#VA)ogz#yu%ITTjA&tnZAhQp)&hvEA}@Qeve^ct>p z2%XR8|G;Pj!;gn>G#bLuaM-obga?=^<4UY`rjA{A&UKvogFq}@drZQ7=`mSpgbGr-7*hNc0#(XpA+ITRk=jaG1K4| z)_ql)gR=I($RHIOa)sgGf3e`Ks$77tm>^Slyor8R?w$RlszJh(`aw;BFS7)fm}=FO zpde^Hv|7d)TQO$z;4>s#X%G=;vA~qyllxQ+T!FHbD$g<@wHlOw3U_wLBo&5a>vF}l zzgg~6;-Fo^Fr02#$Ax{zp(vd0$uq7r3NS|0^N z6?HCCWi_=m4|<)UDq3K@5RCHF2~Zi4c)F*nv_!_}=Ju&e5ans0O`D*8$4yV^bnW)T z#`lt;PGo%;~9sVg53!o zKC4$&M&zUo|Kf(&W7XwoS9Rz<`Hyih+oEIh*&~R^W8i0#V33n+du5Wm`ohg z*qm-Hxtg>*_a4KHiX`5>8pFYtAZ#Jjg7QUFP-}J+dHIr4&Xo z=lq4gT=u2I(Af>G?m7#@OT*SFNNYt&@?Qz*^DxBJCbeD*k2_tas(906$|d^;r1c%` zR9#QoFcf{yuec9PO<8F=#9(5;3Z;xmU8&YiJRnp#$!%(p*qQB6I>dk9wUa_=$3C>z z`5|$f>*I6Jxz`6D@@eh`o0}eN!X;Be0}Ewgz)TSejUXowV^|~*$rzgyWdjH21Gq({ zxfJlWT5CtlU?SBV>~FV{v*?B;2ySKEA%LOalL@Nv=lM_;Dnb{=3Nw|8qTr*#1cp;o zGbv*@NOU!A>u&}B-V|t#%A;gHS3H>-*lx9Ux3*hvc3@~jU|{CZGcowbCwpP(3aEGm|X7%LBh?n2%C}20(VTxLLICS4#HH1LB_P9xr2zXY3>Z1 z3{Rm~epm3~2Hddlgq|Z)P14ws4=O=c(P?Mk{j~}I1-I~vG6eX7DKd@wk1~v_f9-#C zCQ6ysuuyR9e(CY4HKcq#ZUCO;DP|~)UUR^`y?f8|EC*+{9h=146wY!1Oer?EZX0<+ zqLKfc9;gk>n8h>_QcjWxm`K&E02VlH<$y|%YB6x{ya-7`m=q#1Rx2{yqA0)ae&3hD zG?o$k(fIV@>q)OW?p*XP`t|oE@rNKl5idimB{WbnLanjluWjNDm`#bc6t0-L%f+Qg z0pz7D1c70^mQ&6Y%ht3!<0--hc^7Fn9Z{c5>?A}k63`J7;t6bl!i9mgv7rrFKQPn| z7A2ROJB_Rf^c@vSk)0)5LRdil;jj?y0LZC^FeU`pC^LV_zFW!TU%Ho<^7_9KrSX*7 zs?8MxI9v+fI!e%t+`7N;+Qqu+@3Rb7!Y5qB1BJI-7Mg11^8C}NI~*K$x()E3MBRcn z^#+I{O&efTfdsuk<`eL>QAVb6Muk+7x_UbB`l=R5staLi*L65NJcOFN1#9)CTpY&? z=|YQtLa>i_=4EoPUnb{ZQ7L;((zzX$rndXaTlmom*ZuqZuShb;3To33sWUQpi*aoQ zD`tj)#VVWYG24>*vs71hE~UicxNAB2CAB4s8&Er=CW>o~@~9<{hi8qus2y|LMTw*^DH z1^Q+V7bb+-apw|tcA))X3$}OKu-$Ig-O+>xD757i8)%CkSRqH z&e@iDe>k{s5bgpJ^ z`p~s9)$S1!sA;2&OyrERT^zk$VBcID=h@-ftYBRW>j4E7vQ67_93hlplf^108^?+GEFElREE?^p=d!i%culP z?4QD2Qr&ybV(G~&411PSEvL2=vL;l!1^g+AGqgRTM0k8w2xU5K9TXM@*_pjK?WJprdI51qx0OcBbIU25{q0S8t43m-VwWF&e`6Rg|F#LB`vXeLoJ-C6# z(_|*Hw7dHD`&Mf|`z@d6o_}!Q!2t|~E);4obFP7YLKZR7D<7>e*ft3VgJD+2&@TA z%n~k44DG>-F&rO5|M4R@I_|?!zu$4L8IMqCi)n65uAlgR%FVn8dy!oD?wE{)+TQ`} zhnWoh1=EJ+E<}Vq^TEK2;CHwvpR4fV8r-nqDSD1f^@w;2-meJRjZU7v_j8o_Uj-X} zRhs};m?6{nWKF}Y+B^M0xuT3jffa)@x20#7;ole;JsUW|rX-=;0KUjGT%a&|PXzbx zeeyhu!qtEs2QYw)YXdSN(XUbPkA%A{3hhGbBG08Vx>q@@{7!9IFs0bCTJha~UWCLL zG%GiZr<$C5pi0iIDgUR4**oF2+vHS3# z(*;pvSr?2dkZ`ZLPsp%L^PLO+{#`2~vRd!qmy;8i&Vu3V(b?t2<+xKL<}Od_U)J-4 zJl9(*6zlEXKz5XxKHXaX>}_Useu6c%i-InCh+FTYlH3|&xx$;TFgBrOE(?7(Ylq*- znmu5bwc(q;1{b@D?k2gN*1*0%ISZ*c1!C-a*U!$)+5bph!Srf0e)-=LdrRGc*_M_q zt8CUcfIc7GXG6rYj8bgaPlsB5Uxz~-P?!o)%X+ln-aYt+-OL&80&k*H^pQdPf8z31 zs(6KL4R}WZwh?IyGfY#4|n2EpVSm=gn+&}y>{ z$aUzlaLKlwy8_ANF2XTU97YiPJC+E1a=7m=xN|GID2GIi-;UWAh=msh?0fU>wSy8@ zVZ3AXS-pvH4qpLNZ{~y0g=yd|mk`h2@1|iAJD`T~1a*jU6#F@b6`QUh-iD~utCcXf zuf=~7@3(FM@<+W?80}(jwU+GZ+1c~QPtTq_V^bQ!#&XB5rOR3uZ$|9J3wHLyGxq$& z8GC+q)>cz}&w)UYPHQP6@v_%jd2*dBx=y(1sbze=5WR}Ry@ekxdK)ez-YXFfbmdpc z-b{aD*ZSFr4{n*dNIXi9fX7|j1ya6e0I5pHnZ1+$!8ZMWOGtd`sEkd(2QJ`c2E*KZ zd;J&p&hfbrEJbjxK8g9w;@{v%F(0U1{HQi=hWj=!`=o|3Zxi{jfk2AdmZ<+Hzn`3t zPRc##ddM!A?+HoXAj4Y-yx-6Y^cPPsp+t%#io#fuAE*iGyw_iN%y=C0oq5w!|D$Aq z__2nW2JS4E+SlV-&3Dsg`~0M)$^>K*2ZHfH56qM@3Q0gkx16k#p;8+HwhZH%YOxZu zU%O=zIFhyz{gI@^t+x97yB>^JQ9^4rzj^a+IGB;n^zmD-2Z39hTr*`HhYkn<1$@91A)5}+(_YsN%8=9}7fUV1*T2KtjD)a?u-d`UM8@PZW+4iAD{ zSSrN}B&%HwA<==x5<`@vM4|8$ID|g&MiR&9QCizn-jSCVC=qG_7NK8*OYa)m@_qaE zCG^~b+ZJhbTX%rc$xW;7uh9TqG9Uiu~NEs-pQj9d68LqFW2qvVp>9rpOiS(`oR_gPcZFtKp6UC=T2!(8sST&-S@ zO_5WaHH84$8`N!4H&#~&83Rvr57U$^LUj|o+0w0QUT-o zG%XoU3(kk*_Ip4PXRB^VTDZm4E#3F{RU zFV;|Oli;ic)DdZ(mlrGG!CiMqOSiNJ9fcYC|0St#5wAv}9Arw{iQr*L_;ncGDoQYH zijE^qO|ZpM$WU^Ma+f%N$0%Kd(o89dtdcAPOPNI31qvbwV!t>8NlDl;^oj5lJiN9KWFyIyuMpolv1TLc0|G2Rz`e}rkD@34PR`P5coe9LWzHEsyy`3Bp!-LUs?mb9@C!hM z@ka}y5qgCT711q&OL19Ig2Iv1sEW?Udy3>M(`=)UF|l~nc{aVimEL?~fH0Ox#mmXO zUn29Gtna=dCzaL1jIhn!bqHgHzOWRGn#L@cCRohkb6)fsOHw`@core*!vu%#Pi27dafXT z{lfhOns(1R%6h~X7H+%eGF`&nme3CcXM+pKQCrClS2S$5l`E8n3{J_ z{YQQE@o+RBUrdIh+1ugtYI-NkX!{K|jo3P1wp{bTfpd-LMjer0%Cq8PlcSqM(}*FU z99uzE7`1 zByLmv9R>0xVzopA&eV^75cQ?5$;ttG)0o``|K8WM@gxR!NT~9 zrQsRlYcEVh%ZhOI7(<^yynNY!O(b{vsqTz)wKBb_Z?lh4os#uSt?;1BW>zW9kcsw8 zv(L?NH)n?bDV6fVK@KtzF;c0A`0MdruZYRiN}AG#c;2!+y;5zbGwV5~y2K&EQUKJt z%Cwm>{SI|Lst2<8_&wTaN;=Q>HOM6k4mQf9Q$4-WRV)OpQ^|<>)Z+@W3PgFPI@o;G zApBGHS*`D$k|EYAt^8E2R7T;JDw$Nddv}8eDx3RwU6~mzWl1q-*jtB+ZMsnm(Ct{i zDE^%3mwC@fkM*|E;4{7TB1{0D1QBruGjd2NgFIT9uS6N2Vtgqf&UXJ$RdEc9e#$(T z7Rgxbh*WvsdPCVrpc1_iNrTX}!*KKy6%Pw=I3-D4@e(bZ0PC7 zp-Vyyy4k1P>$3rW3&;yB6>pDe&oMY26cyTgmTNnb*yBGB3SIo&M-c$VKsmqV7W&{} z+mRgTEenA_l2o%(_#W5}U@a_vcLzQSbq`)8_MFsBWq`ht5==4{WNO`MJC2Ip5){s;Gi^b2ETV z=n7pc)L;r`V8-(a8VyV#2x(x-M9s=_4w*t`Fz?U}d#V4X4_{GfE(N@3&Q3D&m`F7T zYj!6U%Wl~O!JUlGWsU>E$758Z_w#|QRff)u)uxb&yx>yd1O^4FnUpykPIR+9(O+u* zts~GJ`%to)D?TX<>?FzV)=skh90t|}`eqLAOb*fMSr7L1AbI&5cJ~t4O_G+oTJj8q zwmB8XRC+&-C)^Zu+R5ZJc411E>Ub^TI4xxwPnkBfcMutN%$ zLa&gi4)JZ1j~hbP(dlL!JW7!N4oJMd{$;uHl5xvqu#4Za6KV6$;8VAm#9U}_~uc|qbUHU~Kd zBX5a5>I_a_sHr`e#WWI1PUHv}OVw!r7C0x$0eO(-Fm}IHof4Tau0>`nYb3u#QBlj8 zzk6p|s|e9>)azcg4t%~p;uuA~dhpiWr9fL0cNMt8$WB_yS`e1& z?faEfOtI+$24C|MVS}{GwA&5~gt6VE$i)P7#)MdcEl{{H@L+9dL(=yRJqL?YNzENI zmU{Z1)k=|wKHCM}KQ1mDgbM%_^$_OvY{OUnJJG&Mp8rv^%Cj5&g_QQPv~_Wt4B%+R zee0N7cj(Teh1Aa1b$^ddam{_qMc%_ZL)~%p=IyXM=%1c<+Yl`YeFodDHi)_`+hA0U z1pAAcF**7yJ}o2Mdc`CfK7ILZbR9m`*J0~`+Kb*K%fq#RIWr6v0sWg^ zDQ7*s6_HtUqp31Y$(A{U50SQa(x4lr?<+04wMT;l(J-LnfUpoz)d06foTp>SqRi5#`h4c zg7&9YtAYpw()rMVDc43Q3BPA!Cjqm3r1T7E+Kt34xMd>_ZlqsVA@52t9CF=1pLJED z1MZfw#EzB5Rq$T(5p>5~-zgQs(a2=4C+15c{;o)F-=?NiJkw${w(zoA-QRs#-FpRH zS^^zAgO&}!tG#Q(!2wiXzk>aPD(qLQCAT#a0hfk+8e1EiH@-g-cAN|<7_0BhL~LOE zHHZB{qz3+k8H?`@BH$H!Z{c0{6k6$b1}|^HJp_;FF=x7h{FC#3M#wrk?(_@)sX$j4 z6MX(F;V8#m<#id+I1KohO$G7}Y6$Ezy9dp`AiOmYjF}uEj8UmwnMBdtIN}rJ(g$YT z{4ofLe6Wz<+yMQl{GSfFbeIK3`fgc0}$ z(+KVuVPYyq0-2F8RJxJ@%yCY%14==%LErt4lL0ab!$by_C`0WDMSCST{WV>TPaeVR z_0K-F>%HbhyL6a3{owmthWYIq!F03=xG_BQ-B8eFxErI(N^%NKxHw#RxB%r;i9|3S zZp4GkvdIRIXCmUTh4KZ)z4oyDhV(MvLXN-$Ov)wL97RYA8_$-psD8&{MG#7?jBxyr z0QemwTBDSyw}>!@eC9(C&H%)iMp)cJ!d4pjQ_@Y92*0aboYL$4fRyqwv~`Iy58ybr zeE02$+nyWu=2|;leK=>g7zK7s)Q$AQB&~It3x_Ij#o<<}yHxJM%tallfZ8Y3L1k$; z8);w$!J7G@kYPu2>YxVm?)0MGuV0*>H`={^y>-!T^n11U`IrtjP`j3C`+U@kPNSWI zdU?NgVXyQEc>47OV>Q#Y8Z*yZab*K|Wj1d_48b#2WAZI_l%Yt?Iu^we93LOUkVS@< zaw5``rpyxOp|B#{83qpwj~WtW%CyO4A)YdK+#PgEMl-4ntUqJZ$zajaOdc;g1*!26 zB=&U^^FRzSI}u&5LBvf?>>*Zlcu8iDvv!i_RmEH`NKF&+dZF&kb&(EUNmhjE(^{^J zH+fki<<6DoYc|eNeh4^nltI(S&dxgFB-Fy1Kr;arVDZK&)azf? zJ~nIbT8;Hxt884a0U-0z7H<#)tWNmh%GQUxws|l3B(^heiJE2!0X!o~7EYOY$vncK z!E>KKMm?Wb?~|LpPk3rH&p0Cf9N)jK@V!Cyw{O^|47c8oSx4C0hBU zeA3Kfyqle<&F?LCp{ozgUZdNo)f;6;3Q`;q?_(@=~&SBGpsDEtVc!t>erp;T00$!myi8WsIA=bCkbBB z=tskVFMl_LLi504f6ZFwAtczf(%LP}FZjh(C-N+@Fl>+yUg}CY$0r^TXO!H<9531B z42x~$vNpdl&|NJXa@X3zKkZj-Z`(Ey{_bCKD+1U~T{|thc1W5oFLl-cX=2ny`=JO7 zS~^=?WKtukxL(o!zB^KKWXnlb6#F(JKxn=^yu0VQBlYI@EXf+Z-Q5Q4LSNb3paqu* z2Y4&eRvV-Rr5)rJV{jTGgTf)`$)6ZG+ofH+aqxZsw`i=?3Vtodjv`t((`E@g?ME^Z z-G~{29~qzO7>7zur)b6>mP4JJ2>mjVyF?pW1%DWv!7xFy&^m@UGh1|z>|eS3yQ|Q> z4M*v0Y2++%@M3T8)w36S&tJljm%zX+;ljnxIzG9C*RNskx0mqh^&Y(1+iUx+sf|cx&hx9 zp3pNCrb{tr<9kIwHqmKkukq8Q{7(SGm$C%-h$#w-`>QaFi@BqpWGYI9wNOTI?5FIQ zSN4gnE6>WAh#XPj=RnT06z8a%t?}UhH@-C*4YtHffZHxv?{cFo2nE6zu>?IO>Tf7? zqzux7L+fB67?Tu{N(zjEsW#mLpu{;c9w>kmgFXL0%O?~_nC2>S95JGvQB14tr@w{8 z)T#)r(YXKV_@aFf4F2Bhp^B?pYmN+zj?h{x?6&N12NnsLs}-_a()-|DqXopI&J}@S zT=OLpM$Bt5Jd-KH4lx&5-yJ0gQ|?Sqsu|cwD0K%`qDbYS)^@BT;s=hBfl)GTrH>5< zpMFQVF+^jqmJmwFf7uwq9{?FCh;msf*a@EBN87EI@q?^oA-t_eg3`HjZIj-@0ywNJ zfA)5UZsf;XCD(!1RhQdm1cjj{O(p3-q$xRQDC$N1T1Xn1AUn#=b2(cBpp7vS*K<6Mbz;anBudxaV6!gqt0UcB4f>bk!STob z<>-BXcs}ev>yGZH@Vrfqt{|gSTP!gT%NTvB9(DbtNlGF)Bxt1_`yHlvU5VCC8H>Xr zd8#Me3S+rbnOjX#9+PpB=2~mcv6Tlv6K~cn`J(C0XBL_C_dJpMXFCY=Ol%RT!KxarXNy}?^ai??qnhC|3>-4&keQsB!PZbO( z&E-smowQ=!VaJ79ZWl7qjv`7ZGF}|QdS_Xlhi`rNQp{^SEE3N2R%<6Sc)LaY0~(e( zx2?OdcESk^{ET(qhF>V`Q$fURi+HaGAH)s0NAHqQ#AUdbymNf7mG!XsRZ_B3~S{y}nnS{BP_0%IzPo_bZOJ zkiY#`!Ddkmw^hfIA})}jziBiPdOoexWUuV-u%M@ibR8~1#a9)Pt{2s}MFBuEjJ0Yy zm}mkr5G5GhFjnzS@z0Y2lb)?nqMPw1#snil50`Kw(5hUe@&?l--v^1v=xXosIaEpW zd8mc7dJ}|->*^R*OZe_1N9grJnI-rg*saN)9H+lBSRH866}EupBei}9jnSOe&3C%| z<}ANLYhRuaFR4Pvh$6T=@GA{YQw$GNHV;MItjnRAF(QsX3!})wRyexyP$iqsxDGVi zkKE{mV#=p5e}oi6{!^{-5A9b`bJ{o%e&<*0&7=i#1k+Bhxk*YdBqeF)a+G4)Jfs;$ z*b8W4Bv+D?a-IJ7Tgf&U1DAGskEaJP^6qN&eV=y4t3TpdT=DkzE3gk;p%aA~%#0bB zq8Z@l1hsj?46D_FYe+PPU?i|0K&?S1F)Elwa?B##qzE=h|7{=cQE4s({Fcp~1kB)6 zss-5BZYE~I9h)M!nbDaH(HDF&K{fho;mbq?=*(DRW>S$ATqvA^KST8(WeBgPI(t0P zpA-IfQ=oaBE+ylI;?tRd=dISugXgVhFTl4Z&^HUXG9lDDr#(14gx2pb;N@WpUbb3w z=Nj<VAFgtaO%H-tMqpk zUfh8jHata-k*Ox(Zd{^ofo!lL`eX8KB6(PEanwwrFi!;Dgv0`1ng+lSj884#5+ z5flu=js3(-vH1p$=R88#BkBU}9)~l8iG3I&7gNvy6JixCkHUq4jj^W4P~961 zy6-=9{b6-!WXIE|P`111K5o;0_Z@-GFR!}(%Bo)2y&WmmtDL{BHtcy$2vS4~h$9xD zC6UV4S_uYH7>O+_&%|rU6$XY}xGqK_x~&8@D*PO&0EfBAd?cB1s-v#ZG*{Sjapp=- z8z!_UuJWa$k1UuG(Azl)orrby7MP|m(0)zqEn+O=;JC^|aOWE$d9?|};pptD2X;30I>M++5)sAi=%En`pg82&JeRn6Y~VLA;U#TpC!QuQa3zZ&=kdDPpy4;E6u2tN# zh=_Q#1>f6$(VjEOLzmG*9)rHvr#@W zcX=cVtHo9!V-%-~>JV*Xr`E3DUJko{zjM}Ykj$6e_g8pUZ-7XmsNwWpFEx~0c!f2} zhu~em+Z*}sKXeA&(dnRb_GfokmK4U`S=mJhU{@3EXx}J8y;fU; zCEaFiJ&%KR=nlxHzO^^G8t!oStuRssJ6R8^7Dz&+=zdRjwv|0u|Nj8FB7`x{8a~Lu->suZp=|%EaYhxyHP4#D@K`D*c!9pKe!^fydUEnsW77MNyX*tN#B)TeOWYNWerr0bS0&iU=l z-kY;2*ElNw0PR)pZ`(Ey{jR^_1_ZF2xt3eBNzpZ3(#&lFbe>^(>xZH+DCsN_p-GLT zlDb9y_Z=yzmgQzY(61wcSR#+_?!9*uU;bPcWe^=72XGAUnU)6b3Y4&}WNNvRaLYu6 z2AD?BXe%u-gN$oTt=NufliN4Hn!_z>ow}tuiIEvIz=DGDqAQ`QSeq{4sn6{PN@uD=B9Z(H-A?A^H`#NRi{$rR`a~D@MJPM zdGuuR_$kCL1m<=N?`#I)#p@ZIp2Fn$Q#d)Dz{zAX^jif_Q5siMVQpz%L{ZLdQ6=M4 zZ6cpWu*5{Yf}=#JB-$`z>Dfc1IJTcGypDf?clCP%FK@sP2T$lFGCd~AUGY&PNFSYc zM#1-b^1uELzU@kY1qx&aUwoBe)vTR=r%|b3#z3p!$}gFfi(Ghb-ZZZL;Y{oPLmq3Cevm%r4(G`a}kaB{nhny8qY5-r=xx$T^dd0U2Li%Z1nul=K1(x zkdiTjkDkSH_1kpu@FE46M7s?q7+zHZXDq-FE>2U#5s7hpXMuE-(&)uy?pE5?*o#rg@rUGPq#Iw9lK_Jl5+2$gX8cD@cDpCXFS{>ZL2OlE zWY%zPG6)A3H*k6i-EUvP$!Ql(y4{vD&3TGKTTTmO3Vjwub8Z&pw3EtZgu@$XdT|0-Dc zO>Y8>F-NBHY@3Fp+B^S;mBGgD{E;c&8T*X1F*EpauMpG(5Z796rmQ+Q^AQ4?L8=aAkHVT+YbwEuypwF|Ll_E8^ za@2wrMTIT5{n0Da+D8Z{Njw?4mGT@W(}EB(7I;Qd{YO3J1%!99G{??YfGWYF64 zvFoGWR`#@mZ59e2YXoLoWFr!DSsq5`shyoQaaowP|7sJpZTXJjMXL>>%=0!FRbs36 z=@_hI$3Mf0{3N-(xEfy4V>BEOCb#4NA`XZ1_hRU~7%s1G<6#p2^6OwcOfJTQ%b$jm zdLT_%pr8}bhdR_$Q5w-CULm;eJ+s?)9&SJ^*?Jrjhpiag!jbqj;{YWAQ=inui|gcn4ntB~vj& zNL1P<(q+GCwV1uH*ez) zm6E}3!Y~j-@A-;tj;L|kdkCtiDpe}#0e&F0mty3s!`cqeudkf~tq_OwX6?Qmk2F)w z4y}P6*=bAD{82pQvpTCd7|GjDUGyM)Kwe!J&e+O){PZ@rv=*A= z4L%;+6$QM~FdyRDZ>%|oc1biIV&~x{kW2~8ZJT1bkFb^-*dy3jB-T-)D3XiRB4Auk z^Fb)p=VI+ttzjWfO0gQ^N<1%5769)7bq=* zopvd^lrj`s*$lQ-Y;{n|-hH0kgk@01d@%kcq5qSt4C|ApASjjth!sZX)=$x4*c|m8*Jv=Y5Dud=2NlRf_ zwLconQ&sdw=0=h4FRIIT^EnqzY?bfZ_6EgM__)E5&`--qc?2(cwYQi2A<{`)8?b{(hg zmd5+QFrO@mBH!baXgbMMx+zFnv_eU+!shgLFwM~zn5x39n87##eiCC*W~j6M@Wsva z{p4zL<41l68DI+#(vn_a%EMw~EUa)#fFPB8MMY_Mz%d~W&PM=OD+04p+CoMq)uQxB z{LVRn1LX`TRqQ$!lBX7a>cPVd)79~2A6BvbJV&{%%!7+LEtDpY78i^*z~GsOu+_e% zy$fq`X_#UYg5m8GxZIL9K8d)j{jlL@$_Wi!K#A!ZmvmRzvC9JO$mj3&cAwR_mE}}r zbjNW@)WRqkX6uzouxrdkcEKPTsdfGXN~g_e(AZi_mryZ|hrmX&)|A?+-#dw{XH_+fj%(dbz8Sslzoc@LRtKL}qS4@3;5B{R)CWT=6O=@9gs zIsr-y4y775ASZN0hS&g77`x1dwMbEDCkQJVIhzv`WNf|jag1VtAzk#V=gQa}Ds9(p zN132uX$j^EoqjU$5aN$b$NWe|CqN1ZAb zog-xfX6N_>y16OSsyUNpR3><9kinu&!^cu~95IA5DZQYC&%NKCBhRgZmj^VV zOO!2$ET_t3jH8b;(_$1<9 zs$@x({9TZD74eOfL5Fit__JUt957r9!o61iMRtPTVv79ClBUvrovU(!7=_V|mr0jtd)gY>vsQUZ^XI*7kg$FY{JVMGbE#}n zV%&#n!ISDZ?o!*nxYM=5Agx5tE#)`bgH|T^mfC-};D+UVatX4Xp1%gv^^q?`z4ZSY zjFZcor;_8~t`RhSqT8V@czM>J#5KCBv$(!$f7QQ8p4+CwM7XxwUNx-TQ5TlW^GAMj zn}p+|x(Zebso5eY|3&U!%G%xV=Gw{*p|>D^Tg}?9HtoIN?O5G!(=ZT!?_Y6DNWcW^ zJ1W)6=p-bB5KQA?n$R`5HWrCpY^Pg=_}@7@A5GG)ElbB9*wbR)`Fb8Au_!~-VgC5+>g>blVsz!7iX;O`YAi&!AV82x zzM*7pm%x=E$ksanxQGZ$q_l;QOrXWw*YlYZ0tdwfP@rT8v5-78^+T%_#u!BF$-b=O z_(_cNXAzz)F`=o_42qY;sU@Ak;E`3?BCi_n%37Qm5V8uvtfiw11I__**mA^k)R+*L zD;LmW7Fkd_Bn>yhMwP(@YJroOKyr@BX0a|?t)M2GYU%3oJ*dhojkf66iit&EyOyoJC= zxyUGdRyF9(L1#%(Wiy9%AhQ40#J!*7>zc9JdtR809C8nw9b0_J1>a~!=RS;Fqgsty zUc$BgVlSxz{UbB%#N_cU1~y(cHzm|6Ws55`%uX4$zh8BQJ}Ei7L)gK4VBBZ`Q!sWN z&^hZi5*$L0Lv~E#7;CB9)9#T+=lEos;KE%1jK2XyXf~bw?X_v}gj1Upb7Gt;H7*Jj z!gTLEpVSRHFcS-s`I%i%?~tS8mh*fltxo*?THg3zuF32>+IN%n6+79tQ z)%}aR#^={^)b3uTH3bh5|I~jOfU#QemgB5=&aAuzz;Dy)!(mJC1a%ht9(5yl_kL6> z^}4>;!=3)F-40sf@sjcNnv8s5AwkPuMkN{}W)c}Hbta?ZbtmOc92H& z-;op+4H+;0x8%N-^pbTe(+=kM()92$ZD_(lzxFfGu=f|0kueX#AP|N3{))4mExW-c zO6$}*s=K*5qLEwco)V#eAsT@h1f?A?DfI(+IZOLK4j>-`2hH)~ zy;o+0)hgUBofPiOq~JTKfe;A5h%56q#}ba>SP?>r-@GSD7hwt$0!^GR*jC*WxcHS@ z{EZFg)gw@{`lBj)0j-lwPs1<_hVT6qX5s*s?T*T%XGeq*3}j%s9>2O*ihi(V9FF67cdX5(xGw)bGsoGEk771AYbZ( zBBPvX-J9j~X|k9sYp;v<{a)eSjp~%t8SxcaqjEzWs z2(XZSE|Dy4VC`aHn{6#|4mBDS`~5JnWZj=pp)P^4$XRU`mT*|3u2yXWqmza-8+_5c z6)@|Wn$>=%Q|eh2);vhVPB=ncJyISt)^{=-9OUTbvRR7Tv6Pqp-EGEvzxQ{^M<3B~ zHmnih4AG2U8>SiQKT@4Q{g|n-zle98q-7x&8Yi^7yQ4`shYt-lMDAS;{!dz7#*q;O z1%z+Sgk6S9eg*f9sOjkF^^TKIy_C;S!Y~xa@B1sBgb+ChcQZ*4J#f$y@j{3x>zixR z^^vxNgYkd&t%EtHD4=nt{&+vW-%s1cl9D1vrurt?r}udcK*2-6fMWTYy$ zU1t;lf3fqzNMYr6dNH5ejc4O|m^E@$3Q3&{E~7$ASn|4&+z}-Z2WecR2CfGvk_-L#FhDD`!jl~U%rXSz#FemIFGHuAUD%EQgPTxt5VS28TgAhcgM=hL zCzNv~<;Ya4_0A5ceaF zR%h*`Rbge<10tqoUCDT)rUEEj01C|EgL?4pj!<`ovTFQ^+G#9rTc--b2M2sU)&r$s z5)SZt4`Df22u}Wn@F8*KojY1uQ&tH3Z^ZYl7qb5@e#W}H6{U}UMfZ1D+ky;v$Z5^j z*V9?jPE_^<)p)q~9~?#Rjg(Dq+b|4<@BI~AE@^=*xo=*8pc}AWiU2EiDT+do=vsqJ zrutawe?Ll2+@wvK`C`iwUp{->#N?I~4-d*5L$FK&Y^tdwfpT z<0F&CY9=qH?=}BN5iV=?fG?_DXZc#`$i9OXW5Xs~y(a9#4-)>cQSt%TAa^;ovCaWf zNRm4?D(>xC%#2^IKVh`qQh!Y50$}vpi2!s+F88+;NQLQ*d zXzfd`Nn%_0ETxs$A<;$w^pRSwr`0Eh0 zwt z;s?YkkirO(Gy%(WVzJ(B^vHQD=LX{6=MW)ex;Mp}DXp0I#6d}&1gKNbm%MR-(Qp`a z%&QD3<)RcUMZ4pnz253a-EMSOxCN1oOi5+gLIp4889s>?kb>qp%EwKl>{pymFe61W z%5j00FyJW>J!>jp#B#EcrQUg`>v0?Dx_!F%T`7yd`&IS@wUbRx!!Qhn@B0;|+LiSV zU8M>xNN_`3rU_+`2$lEx#m0!NTtHZbXJM6a>Ttc-+}u`=)n>S*L=zLmm~q6(2Olaj9~F7$toCXX{$mVR3OPYlx*Hs!*kp10U|$vlBDoiQo9#Ud$P$o zdX8;A38U53q(z`TI>F>XaDrgrg0(&+T4j@xqXNsCD7}wuxi0ds!*VCw^%#2uPSBC% z8?-yy&%$8<30O(Cd7=r;5b-;rbpE8_|CJqQNnx-Cdo(j*M)X7zdpL`jmUv|Pf#gpV zUkF&_AAVc8cn5`&QES3L49DO76q)#-AoG3Jf;a|yAA1oQ@h+|h*NbbeI`-)o+n%lt zu@51+B>(&pnprk=Ng-l%93Z;rX)%1MgK6RwdN0F#0QzMTF<7i@7e1_4&&#*vx`_Z% zkAM_hdkb3vqwQqj=wbnZLH1}!G!c(PI;VmBW3$m_)9pFC+S{J5n3aA+~mT6a1# z`b1O<**gpwmAUGx9bepkT$j}3;@)R%{oWn3S?_1e2fwXUO=}x55WV|XOid06q&B^_ zj=`}hl#m|U&`StGmd25&Rx*;-?l$zlcO>m98`}YgWDkopA8+29nca!7yspp$7L+v* zRM2=a{8}5H?hE9ax#aW1=>X`N_`r-{PPEq#xAVp9W_FuyHxeC!m$uddmI(NV@t_;{ z1b)pp0$T-i5G2B?EAbnft#twjw1klv8JFOdpvx*H)E>Lo5x`tqUpw?&t>}$WSLlp- zkj#vKsKBK{xO5TGhel(nVJXZJvU$+>Q7iLAWe@D~=VCn5x?(2hQ{C%Y2lYG+M6XF5 zgk+nHu_jN2QMFb+cu+=Aw~=@dgvJeO*s35?EGJRKE9Ov)M6Y~o1p|ZIT+(W7x0JkW z$eJ~Doh4}z!>-XpjAfGD_O7EkN<+H4YezTU86~#@@42n0zVg;&Yw>i;@r!9CKEvEP zhdiY6u^@A{CJv=5kx*}Del+aim8CgZSqm2>Yl793c+vax?CDG}J;%wCxt{ZJ@b60j z?xbaTk@X8AzL`yy@!h_^f}Vgr{~h|rv(M+f$-Hh}X>(s(Tv{zxu@Dz??P!ObZVt;W z$t3%9kj9W0(jh84-!uJ9mNR%vhPMr?J+vPYD^qI8$05?jANY)p)v}|bXh;&WfOtG! z%Yo5N#?St_)4_k8l1)p*Fc60C{S{-`gTm6@C0i&K!Mk`_77598H;_)2WV#;2|8AOo ztg9$$PWgQ1eUb?6RNo=7Wa9|fu*FT@U@Lpe@FZ=I0Sv)?Pb%$bP+95I?vPg*#3lku z($ec`c(uK2>c@JUMz!B3et;Ll2hbDwG?MoYBm*B1kTke9b>(yftO;Bs%5FEY%TKkG z)A+1hca+`)N8{|WGW$diqi@gPuTh2=Qv`iB%s=oJt9HH$<%m%6^-2d?gTSs@9npsv zdZ@91R@#7~jPp0yYXTKTk-aU*S!xs;@_rNlflj{?hRU`Q2X+JT{IVkd+uH!*FbG^y;gjJIFfQW!hYQ{BX$ zzx?S!d(~9r0tVw91QRU1OjZ^}V2c&WWSKyG781~DWPK^0_N&))m+t$j-%bKj`o?O= z2@2Da15KjX)FBq&I@k=-)*B6t7*_!1Ia6!;$pWX6n4tC|Cbu*jphMdTMtj1uM1El$ zoJ=SI9W-@KtWXFng+M%mT}kk{PQO6)h|&-vtMUv+B0@Yc9WALq8X_me-Re5)83+xMqyVBBLC zcCh#(F&!kPk4X&gclj*lcR%Pd`2~$r&1xG#48Hp*)H&G@oELBd!D&xTC~csH5R5#M zy+dY4%SdY{efrMMdW+qY_cZ$Xek8Fg65qF+3@u0k3l{ma``Ra8V@w2(Y>f~+Vaw|7 zW>CJBTB%^BQ~2p+{c!($|5Bp~tQFl>w1PI$M}jRwDntamhO`H37@S&9@dG?|>Ok!y zGR!fmK;|9iT$)V)72LLOyP;3nfn;#LFvStKSf1&gv_kPu6zU)i9=NJ?=-+TZx)?|i zx*`+aZ>q>a0*xgvF$S%4Tec%}nxMLb=Ry=xVa5oN%{YVXDt*PyaW|x@TqR#XP>6Em zJea?!i(&N51hxjPOpe(GLy3>zj*`g@urgjSjNuQ{vhMfw^|bZd|E}PLc;lt*Fb9=1 zX8%>D+kSb+wu`KT<3r&k*iF|?XD7bAtCy76+k7$Gvpt|;d2Ra;>8G^(D^SUn% zSB%B;_O7+CD1sO9AYPWGq{+wzl1xd`Dv1Bx*`^=vvJ0y@&C9$@-g`-@NOl%o6j76d zsH4HV{7rZ*8iVjGEQY+wfL9r!a7uVJ!mG{w!}@i-8PJQ@y@&`FZG#^AX@J`gfUu*^ zC}nWm)%sV~FQCto8ZnvYF;z*q&g|#Hx z^7%k6?arOWsL|?%)l(BT@D>bdzqlF40!0<_yb%(QWF_h7x6h z$E=j%z^O;HP`+m&lkH@E@92!dC)X#7OU?nhz&iM~&xRd_x8RT$>ZojH{5_WXf?VoL zg84@-sXq7*WpVKJtLz7rl08quFc60K{E8#$01Fi>q>)Nkx>qb!g)Z@>wd9;DpOXdg z-*N0DP$Y!#WS{Tjd0)Fww&^=!k6v2_uf3s7UKuNzPw?!pA=t5+6Y?^HunO_W3Z0sc zH;3wFyWbw-X)dnEVgWhZ-YBREbnHV4(1Sk{2zCU91~PyWBQ>2g^H^-#l+xG>-N&}a z<1}pjV|Zf~y*0MGpwnVGMVFgd(kmLR9-*=W={JnZ;SQShbgm9osz+70x=MV@B0)}@t{x?uk9*`y?CzlB2v<1WCJmg z%*3`7-@UUNcdNyMG!U5N&t$%TlF|g7cIa8L4IbFC!)fnXhdsj5n^x$}3Xo9}D{oXZ zr{&#x@ibq}*Uf6~KY^M=nI0nnerVh?Y(oTkx2!9We8##Q0aYP618)ense=Y4;P8NM z1hA?s$-Z{UAc1y@2h%{R4hyI}zp1G;v1b3n%F-XQnX|V9X{`?oiKONK@p0Y5751CCbA0hK z<@n-f&WdlXlfiDnFbsz8JcWmLfWtt$Ze1nBE}XbbyC5{Bjaf6Lah0SX_VjZTTERNd z(AGk^F@UXcN>yvC>DGW)>X!?HpvJXu&6*`^HB0q~bNFN_pc9*#Gw z`Sa{$whE_tA(TN06wA<|jDuZ)23%!PaIogc7A=&u_NvkdnlCwU1=U(YhTsc?jk3=3 zPMLRT_==bY+`LIq0gPK^d$Q;nAmEag)eQ(RxC=m&;Zdc|jN1)SY>Q=jmnKtQGGRyKzW6yBKXw&b`Zz%Yc7}6d zwiii}ZDP*Ww)2!nEFmLM_QhXO#(mG^zggeCbWYZCMDH(H-hfAvFhR7uC;qeLhWz!E zJ;Lkgey}>3p8V43;0x_nZExE)5dQ98aRWTqPMz2-x^`%qEQyn@0g}#$4fI1%7?gCf zg~*~tQc1j`|9!`kWXY23r0x1`0@}zV?}g9v+>v_wN4$tzgT1{L?7=7$TEjWIp-{pE zGJ+{;b3jvecKm(}cc`=-|1BFkafQLTR4cI4JQ54{R?HE2WHyo>PNKl~QSq!u%t9)f zgg+I|VX{DVFQo@>=Q?{m(SIkwKL-(-+bIwo|6Y7pFHf9@aDF9kahB`gt0HWgOxXBcrQ)rS`2at(MJ$MP#2nn35o(Wa*%? z^3aqGT48tydLfh00|z09Jo1U&L1vWOp4 zu85+-S?-0{#yP6ZZMC%_5swWGTQ9NH!A8GHsLhZRI9u{y2XnVid^iBaR{Ngy&`x*0 zO%8W5@OG*pPSNc?0!qKwT2(e#2KM!+WU+rdM>FNAF0s8{jY>&%E{vensnoPlMuzg9 z=+At8S_k|5spCpQIx?Nly<9Z*34G`V1cGU_(bOz)M*kvIWC%w`N8pQ4W3QBWkq)KO z8B47Lhc-?0Qmf?gH}I>5C55p%u-^EuqH{y?kfW$cbPhK?mJkr0_faTo)lCDHVC+NZ zI`w?UUiu|ydYdj&E{n0R1q^MHRJdXf4F988l$fB#X+|ly73O?uS!0EFflPFFI{Wzk za(Xct+X9DfIpRJ%?`>?!s07PobKAZOB7}|XN|7l+Iu&puF^08nRRnG@vU(^PTEdIy zHP%aerE^~@?;4E?+-{kj^kR{-&aNR2>3@5y5M3QDmI$0jg|9+Xe{EP(7Z9wdgnBxi zCXyQfy8z)+%gXL41V6WpsHNjA_Xej89_XOk3Qr}6TEzoW^ZF?&j_`gh;<^rsiaNHX zzb@xz1ZSfzzC-%H45|CuwRVUWm2T>XG@H-`fky4xuI_aju=eb6vOZ55#geVub-vVZ zFaLpI8N&T?Lu5g2H+)1=q{b)J`$r|Cd0z2ez1Zzj6`Os&7Sc;^Xo0_Z_BPh>v%HQo zVBnXd&2EJHyaqdiJ<8p@y3ABzUEqji*Ue*)g$ z);HTR9qFY5f2YTc!G^7GczGJX96kG@I)Y(k%T2wFEu2t9w-akdRyuL$qPP*hPq$%3 zckIewQ$kJUlqCc#8uApHJgJ=>GR& zc#qwa9*Nj+g=+p)IXtqT`8TKi*w2ReTx|Ud?O1JZ+cpsX?q6{Wvf9oZD=oTqNS!Qc z>b3!z#E6XsLlGFXMB7AUQ6;IQUeW))yOU%ovYoi=`fWsk$|UdMy*zh3rt@b!jceY{ zP7QXTCybRAL=?cSG-|Byhnq?Wv=6?X&1B>(jI{wj6c%^3QHbT<_ej7h9l`I}+>tMw zoMe!3asvISGWq)Zgt$ zy2FaZnJ_+_`KOVa8ws7+%vbzbmGE^uH)=9<@N94I#qP7cr_Z5JTcGFW@WBPpIDUN& zFJHpmAJ5^%%RP9px7TFRQ28>lr2N#m*zSAYM7e1)YNKO3J|+|+>s2iCMxh>gGhrQm zGlVbO?u&!h{WtI-{hh%_H^7775j~c|v@tfMyq9^dijI*?bI!Cm)Xc{nm| zXS6S=+!c1W;BJc6YAgrn6~!)K&)_<;LMND8n2t-Xh=mceY65XIU>jNBTmBqSy3)r; zVz9vaB8m#I90il4YB0dIbx5L~!^9$#SX-4B5Gn$GVhojF);7o6aHzE8@c|H1{SRnv zJGFdW)Ni#49t?V%dbjb2Q(A>-Rd#GsSauIH+gR?PB$)*|-I+!SM|sEY;Y7LtFEx-C z#qN15)6WAm+c+KSJETa4@@b*a^{0APP3zZXd1;I`Z-f&lpK_NWn*eq|iN9ry##rY0 zfU5neKKuLIGl_*V=ovXyU!;9?U-Z*8iVlWX?@tHaeh-OW#?CI>E}n4TT#`hV4mMuzi$quZnWJXp`qC32zXu|+&skH|lUWR^6DO?mTJm~+gv z>9`<0rDQ3CA4tklxVK}(c^JN^6|GF2O>&)Zt6se5bgl6tfv-m6#X zlVpMWEPu}Yns{NeyF73IiWaB3t4?@Y> z843leX0r$7#+{ha4wD1hxN0-@F}3mWo-9?8wOa1VQsp*iv`~MJb|WJ1ZBrf{oQYO z0q`yAVdXC8GpC)1Ah6tB?EZEa0Ns2&9*)-udW6S<*4LGBg&Y|Dq zm!8w_^MIaOlW+)x;d&SF0lOUX;MVthtT_i=%uAxn!&}Zh zBI5eqfW%uJwFC{K99n~{bO$Nx2BKojZB$t=)A4Y~?axHo4|*WC-=~`bl5tPR>w#J= zdO!5%mOaD)h5Z8#Mi%fMG3pb~mP_O%>p%`>cLcL2-|Pf1ZC(iUV{*-goZBY{UD!dj z1u*u3yWA3dC(>6(J==e%C)=(i1iLso_|Tzt0bR)P9B@Y-Z8v=+w$!w3RyhssjXd;;!*IrQLR-><9gder`n1)YMxx>GF;`ga`o zArOH<8)SvMvX3b{_hxi2AfR2qPz^vM3?{s~013-={oBrH;)V`r&p;A= z%M}aIs7&o@XoD~mbB|9zG3iD!u1LTIx%<`&ZeK8PVS!QFQz^10qzE zQBJym-mE|IY$}PM%s?uES)s>YBW9Bn%vR_8;^?f?I(Ua%_edlk~t&>Ne9oN4DcsVOu>xh#2H(GHOi&nn69%8Nc(L;KU-Lz;g2qd zY@P|*^1PUsrUF$_elj*h2szh92$d948T-P~6(d%C_5_l77)RV{dUIZmEQaX?Yz);0 zl>m^?ljPH84!A6xx3N^NIYTGaShDN{D+ZvZh`ZPJ20Uz0yQycIX0^e7byNlHaVXt9 zVBvP?z??#^%B5cFF=@4!aT!`cn0Y}T=$ruwu&Gb)k6TBV7YBz&Rc6LBu*IHLs?3|X zZk6yd!^i=;BXKH%M~>~gRHIIp>+j4j@GsD>NS1 zuF!N8>Mqf(Rx31x`6v72{PKt(Kl2VSrcWFK17Nu4-XT%}W(!)`=u4<~gmONx3FeP+ zInWx^Q$!TZnaPRuCL@VG8ExD%4x&ETOr>r>?Z!X-2^&p-w+WD4hmf@nC~^nDnOelP zWH3=}M#gOud|SQV5t26L8>-1!0DJ!w_}<_W=^I(!PY{7r#}9g^JPaH=whI_eh(5GL za+TPC_B$@J^p;g>+S#;irAYtv7n`B`A0%>~A8P$aIYUG!HzP$#G)}?tF@BTw(?X{e zt2(Y!tDe6CrB0Xfp|hOE^mvsU7tlY-q7`#2#~$Jm{>1G;E`-^J@JA3AF>-f#ALBsm zpDEYWb9)5Aez#=C>9%9LzTkn;j``c@Lk`!Izm*xq57DX24Tpd)2f?oxJZUBwz?QA8 zqF@v8<>Uf)!u$%L3$Jd#t#E&!NP(wD6d$7k3;vfWV z1MEWYdL-jvifmzUluF*EF!X9J0jEX+MXEfWAZ8}FXgoiR_h`z2@skyJ;G;1##`7C{ z@JFqLazl^yZW1{xgqzx)N``Ui-7L&~tLcOylToVF2wegLS#j<-4-6zLBb}g^7Dgmd zwCe4KX4d*+Mc2mk+^q@Ysb)zcWTIpOhQNp>zZ`(n&WoYdi7&cTD4GG!E|; zF$=t=xoq@HMskHj1qq20pFg2`SVbVc^{*pmB42?fP}p`M%tf%Eu?$z6@!z+|enA?X z#|51C88{^&ND{q@*T~zYU_!h{Hlqu)Iqif7&uuHzTYASF=7Lwj%o34OvnfhL6ZV6V zWS044kOi+P7FARg5{n}q4t)%+hDt4rx|nq3LK>>zS;1>@0_C`lJS!$mr>d!yhXuUA zepLz@rPN5(Vu~FI5Iqh679~qrDIt7xCJ^j9m>HRJN;6DU)45RAMvJsrqT7VE$M}uT zG|SoxYoR>SW{4^<&1VyM#eUF|zK;$NCCT6kap8?%Af4nv@M#ikOkbx|^w45f39R#^ zT~c3FmUoK$a{OB}Dp6kmLm%iBAN)x*sV&+|H9_S31Naf~vw``sZ z-c=qO(v=@o3Dc`T87cJnz~#%m`D#76o0yf5f(>0{$}$(nDFEI?O8*ZjmkyPXvr8t) zC9$={Zk6tu2&su+TDFcvJ;A}ASIU+%W$spFDqz58esmOcxzb=m4Nuf68MdZYEE&D- z>^R~#54=x6BErug6EZb%xym%PWbpXyVZ;SQp-#ZZu4Qx6V7M09F{%-pMR0;i*Bji_ zMO5Qo#xC$=%26@pqJe}RFp@=Z*bzgguktt~S@=4Bi^4G)6#F*3CPG}%QumoZB+GG8jE>}A%0iI|tgv%Pr= zgkz6hpmjGjFh##+;(G*ZGcaDC_w#L=(2ep4$wLd%U2EMp7kSrB_7LPpXs6*R4lkph0c{Hi7+xL~Iiqnl)%H@N= zV!>$6K$HwZN&dPS*1FTUk|vS9OY0yNj+E~|C>kvmi581O^F*MzqEE>-^NgsYR8$aj zW``LKtuvxb{MEpt4m6jMm`}0h|320{0e+gp{}ABEKKO+B(=k8R(o(RW0J<5-uf70< zmz$y@zcHpmc=D8IwEaD_^7#8$qQU{G;3*<}gNU%<`nKgVa{TKaN#*E(AnUj_!> zg7@1)Fa;aGNJks-L%jyB4uS^EwM4R)qrVe}SJc3aGP22cpE|vsOI!GKTQ}<0w?;l} zQRy(ULVE~>!|&$R@6GmRhqmJzNfw$mlg}%g`&U}b_EimD1<#{~>-v@Y z_4Rr6<$YyuqmhhH6b`rN+iz8eY4&69l_yfW(Jmr>Y0lQ)Is)S19V47<;-(8??mquw z;it*?;q~5n(bCTRKqZ|gca}7FWGszO%H?LQZ%5yn7kc_*!Jk7d<`V>c3kV{w=7pz( zw3u1%->&_m{q@Ct#Wd?*pTR#-L*+Fy>sytS<5r_r$o26;7fzf)3|xncu!djrgU8-M zgZ#=ruNImCMf>XK_KZZXuy?I|#W@0&12()HpV6qH@8ZVpvLOco7R0TPPnC6{CHM$;XT%}>hf5yw(#VOF@hJrT7eY`j z`MehGEzCa6`etQHsL2O0Is##)W6{s$>EwRGva`3n^s%nfvxd;G;bb!ACuzZynbD4eeWPbK5o&{_bCaW|W9Z6v;_* z?M-UCaUG}4Oze0pT{}0fPeW0V#R)~S1Q}ax^WSfG0gxd0BHGS0{ZM|f2w)fchTR7s zy!U;)ig(73AMdco?95FB7t9S8>?2S7r4KLZinB%JF)v!Ld6){ej1soYLNE2BP>g_# zD1SOb5&>=OU#jhu=cfEBN;V9;sU>#35AGFb)G|AY7JL%=%Oy{!*Ui!uFo);IgkQ1A ziYM1mv|xKzLj8Ote#`vdM)>wBgKMg3=^{05_#Rt(p8Cca_ zb5taRzk($^PPjl@KvtASw)LR+T8wbl9PB*l5j6&QL^AkCqj6M186P}K4b#I zgA~@H%{lm)(=1Cr5h*EGxFdjYWU-#Z=9cg@OF+a;%v=1u&IHcGBD5=6xn$ybwAj$B zEAB3+M{8o)=rG)XOi6T&#+O`I?nelo5GMDy^o<7+8-#mf8J+*6nOmnBouwH&=K*&G zf0^5BrutspGar$&*xB*n`HY$cj3C$h;nnPo$~~%y1~4DPT86pBP;%J$V`pavMWIZG z&tniDqZHE}ERDq7uxQEB=mXde!U>i_${~`jUF4ZY5Sw6`5VPM%G0=Qosce)i67vw3=VXM5sb@#%DS^zQxScs4!!F=v9$ zqerX*AH^f592iz66%D1_#o{VqfFM|3^aKF z8R`M7#!bM>0MacSQSXFb5VFE=GBJmJeH@Hv}Oi~vR?SA6|qL*0|^AK2F7OW8Ex!$U3 zH)3dzBCrJuL3s7xr){K?<)NPlp}v6jGK%`I1P51IWcZB70E#|9&dwCxL=@+Xun&8M zb)0TS6$)@%f@`^&z)ty1>XcK>WP1Mg^v5AdU9ztgR=F0MIS9RUaXJ3^Co@6@JIeuO z=`DNeG%ZKdk+ct6>&yhrXe6nBxGjvjg%c^=KSn!FcsUOg!Bqcd1{q?Crw6JEO5Ehs zmc3y)AkC^);xR?MF7C&Jwm6-6m_SOG^JW}HfvC`d-nkMy0qkTu=8gc0vCo8|*yo2) ztSgdgm$8(aN-~zXUsGO{8(L{4}kK^*Okl7|5 z{1~(fA#Y?}iiHotZ^8BJ$jIZk=Q)M_H0FkWTY@&q7I0pWL3L`z1`LY*1NoaeYm;@} ztBd@*!^wnlo!#^Hbb5UL25@9uPAkc6ndCKx&csDlIKa`;)g+-38?a6q1<^I^bOOk? zYp3XiWH##$EC%&COJZbVNzZoia_nwo9A8Xg?)h$TLhKmg2ZJ+}w%IKAaGxw#9iUxq zCg2(gtC|;Ma@7k4YB}r^F8>lWT?$ZJ)`?mPh*c6r++GylhrxzD%NM$Y0?ZB2CX|0_ zfaBfk;_EDiZJwL*bEQW;D;sg@$B4G7OK^$~VM=DI1X+$fa7$!_3BiqgG1NM&gUNf! zjRsuI>7KCX1JlvK?XU`Pw#bj?$2^&O=a zZsHdIAISMPhMa0|^F<(Mk3tB?%CqFbUyBO9B2*w{s6_=h)DJUmFCy#2CI4(=LmSh_ zjMa9V0y-$6Re<(yQGj}DH}zJ$)}H!_6Mi+LaZZ2iT>S4>artE6eE;%S@x&QD9t^%8 z_lK-OAZ52g2xmx2}4iJjWQ284BPX_-RXK;10^kp(Q z*+#IslmpB21~Dk~?Uq}Ab`w@^y-T_WOVi20-O@e@evhnAIe?z>2}s^Kp-T!SEvfIL zo3KVg=#+Fdgk~YJ3BPn1={=HV#KBV1`}5JDs4NbYmVvA-x2`T#+0e4@c*xZGL%>7F zs4{g0$#j%DrPw-N`_9Sddz#ONE%upCqi8g^;pkqEKgd@~W6dj8lBVjkzrSmVRUx{i z!s?-@L!mJ=G#pHj(rWyH&I3&{Xtgm_?CWXj`F>(m%^S3T(LsBymW}~C%D%3Pnw&6S zq=xZcT-HRgeqdXQSAyiH8o@HiJpmPpkl&;PDCV5*Zl#gjVU^GE+x700Okp8nDt*G9 z4LX{KH0AQ6{H>>GHeTaV#2x0Xqt2Q3XIYoN5tu2OzBY63|f>shUndt2(sG z-zGcWf4s+Wttm8~f7TwwRgSJ&C2o@z>%txP8K$IlhlbW!QNfz9A6?*)Kmi(?L$42$ z_4SLwZNs+VD2X{7-rL4Q$}X{o_qO3WGWBrvzD=ST-97E+5>b`dB9^AnVr`)@uTIo# z?eOWrdvKORZwsf(bNT#Et*HN2w2ZQFp?DZbuLhDUjBjFYYN|!u)N?`JP~Tnd0kRDl zDa=aTt)dEr^k~IluN7wNIV=d+Ba+?C%P#1#a^dW$G4!QOp{xSysp%*bp*CXus=?jH zDCKH()k5;#cB&A|ZQVmrmbbjLzr%hqN8KV{xT#z0!CKP45~(F%S)Dp9<7-j+(!a67 z5^~QQ|HhpM+)6=uHb@Sa)+M4MAq}O9O-P!i+kS2&KO-4oB>mcu;`R6uLBLtUWA3I7 zRNZ0j*zJ^7z}|YIf?T`e7L)1}*EDhII?@eK@Wx&oz$~=Ucbt-MXrngF=jm`Y$6lS~ zdsFgI1#2uLP)q+CQ2pqlfNYWPE-(je!KpM{f91DHFZxv2>o7TD@i@ke>#k!+ob)de zkrHxAM?_e3=Np#rB~R$md3{7yCq?4fd^5`_ReEfVSwoNhBY=DQz4Pv`;6MqFF;7+Cq3sLgvkb4*_3(%H?Oy%3h)#V=|&ok`n;({q5`y#PE#M`G_ew?Gt z8f(xIO=;YAuU=eG;DEJLS~$*8SpvYg6ELA*p;&A%I7s)3Y$0eHGKO8dfqDgV{B>pP|Y%542& zZfp*5&z8S7+`v-3w}&Vut;AF&PAPS?Z}W1!*7{nBoEP}- zcFI^Yd?~847?$>zwU#7uv|-5kf-h>V*ac`jcqkrdG3`%2?PunmQeebWh0<^RhBxPbS@v*TnwjohgQKmgi zsB)d##3Hpb+gaBk{`;<-6haGZ8k_bqKM?oY_xPT3uFdYtJk1+XyWM~`^xpRd2P($C z6r&O9f&ZF8@9@)*6tQVyfxB`BI4Qp+x&)E~Cpdhb}*ocB&C}$73%1 zbUuTte5yr~T6o&&Y_2`+tZzWyZGoPh!m*8^`RervY;8g3`37umbzrm8Y5CMlaFoUs zpIV!n?I=owO^ad3)j0CUWNc`nIcCu?Q^RP?jHS7U;27F(7GC$?z;XGzf|nQIhl3~d z9GMQuBv*V?DL0Q!nNj19xp!G~`5@Z_wuQ`USHMJVHX_5zolRveANTIs7WNvU8Z(Ge4# zg(pYrWTh%3Vfj07n@!F%8!xE%R?r1nA?vvD)3X#| z9Msx9Gql*d=i!se0?RTrA-musy%I}N1l45_3i*EwjUVk) zQE$^Q5Pr|ExCf-R(@4rRHngqKZA>s}gKCv{L8x+_OJXgxgMC?Brv7)%ZaSa^$^?)2 zrS5m1zdQTB%gL*%sG?+NCxRXLfL3J+9Z(?%q|sze362Ee1T{GiWyVf`3{y~922!PS zPtmEcsf$_0D-GTb;0~=*M#J+4>r2+jjh%xJ2c#16R^$i)8J(LHhgxMB+7J~r6~=N9 z-dN0GSfHI6lfp^vnr+{GuGN=VBfVTZaV@NbYk8?@ZV^r<6RE;>{e(2t+^W1F*z0x= zp6+#@?ZePhU_f)Yq7>SvXYb(f5V|k+;oz_f2iMl?baG?G+Z@obUJoqg`|NXu1E($YZu7Y*nwWJ2bm}xZ|@^t3KiB& zLF072VWW$g#EQ7z?bf+Zy+QbWO3;QNGqp}zo#SW`{d-IPx8I}ex0+sn8!S;cJbHMq zQ4{O`rBCJ3Cl{wTqX0W*g#HfMeUfU6-w>5+;gO|Ta7L)p$9gQfkAjJVwfx$F%Pcs3 zmt8Yi`e~}l62=Ie&{#}?XNi3^2f=*|{sg5x;(dm3qqCCh-w6w2WB9>zgC*g&s>l4; z@MNiazDm{$*^i@*x^9p!t6fM`Ew9jw02PXN=!h$2A3AURJ3l1zjbdyN;YqMO5FbDN zSdcY@lK6sIt)-t^$Z_>ruH6Zw<;?rlNC|7jy#0W#Rx34dfARh*j^hPP3soYtdEYr^ zthKvI|Be#Q{fxsyy@lbwa@!~6L+H1{- zq6Q8l6MY5kT3K%!ITC*Nuc!dpksRxA2H9j0#aSOKPmJ~0hNVTY7z6^w z>>cF4Zxz}1CFKC-W&6SDX0z+Aud1lL|NDBmJ{Y`wc>pirZgh4(9fx8**V79b8YP3V zQ5(-}6xY*VH-Qn?BINkW7e>g?Ztdfj_T!It@W_?Mb@*$vcIq+17g9X~y|ycB<~^_l z2fKn?d~T_5W#6)mSxSX3;TOdhFkW)CmC}dz3mx5_>i=xSfBPXf9~=j{epX_!H1PBB z@tfYy$FE+)n6|*3d4_A_L+9-L2Hw7fgIhG-j>e4F(Hg zmYZ4MldFMc6R?>c6yzMt0y!J3m^OHCNqD?(o(!Ci{{h$TIU*lEfW3%3QeShX`e<$v zeh}HANFBc%9Q+V}j6#juU`4xnC<}+HOYq{Y8W_Ix`5a&PxU3ZSOz_u>Wfh}AmaD;^qM^n{~z@W;Uc$z+3wu9q-batJr88CM|Z zpiwfe(dj-1y_B24hZzSE`bd-e{ph3k+tWv;@TG~K2ln6fW`-7omiq`!;PvpJ#Pyz| zA{1#M2Ag8f#M{URbRC$bz&~6Y*fLVYNC*TvCWN_EB?*)zG2et9*#|K6h>GeQ z+Sh-$&3I)gbduHhnoO@QyA`XW>+z`K&Ee3g`eiWSp`T@1GQpjaXll(f8h2s4L_H-Y zB-%q*<*iNdJ%*s%pc7Pu8`ey*RmtO*BH+-%kn^;?B~Q=kX2wOh0PV3bOo_!*(49qX z0b1H%#NHXqVxqE^+6JBV8a{g)#0dP(N*mML^Ae#YVHv<0Lmx2**IG{VI)6V(;WxT_ z?X26`VU%vFS}`sn2{3@u?Y$2RZYFlU6T8~FbpW3*jX27V;kuRT0p!NOQf^^xQ^e(u z)l|$$S!2^QO90)?1N6G?f<_u>RZNZ&DI^~yR*KjCROW>8Rh)gt!{jaI4|G}r7dxp# zd+_RTh}jAsXfNLMdWRV+SQpLl180rjTH^C>Z7Lb<&+y{p1d{cbVDh?1#mXm+j)tYx znd0mrzx?GOy-RMb98OU9=_kmEM2LkVouEjQ>8FoZlhOF@>|#_DqQXGhsDOu^0yT73 zXi$k^l_2P?5%ZQ{OXrN6E$1$ZF@^B6CD)j+W%z{G5x!;#F@y;eN+H}~p&~$(Yp$4) zstcPiz!E@jVlDNsBQ>l22R{cI7+6gkKc$R#{i=rfM_ zUhT(>HdETpRr_;lkCqom&0`X~DcJ3K3Rvk3RWbXNp^%X+38(5X&T4TKNAml;Y(pD% zUlr7`U{x_(_u)x48?yWxGs4;-s@d$o%E1Z^Xp)+^ zj@2I%2YE9@)vaaRu2$Bvnu{lZf(4oHUy3I-3;2ix={R}1d3$u7bn)X2-;&$gHHJ-$ zOZ>>+)(H(JwZi4R`oxtL4LOlg=NzM%ck(`}XP&{Jvbmqu*r#(p0k%#F?2a%%vDfH* zaEMgH=nL=wfn)DLafQz|YFV(u$24&GBM+MBF&%dSPT;1nD(YEOvqr1ZYNMV%#+()Y za;<{5WZ?phL^0qBzHI{2n!yOeu_vT@5m$T*E@jJ<04b`4FLu0k#Tcr*_xr)>LEmg~3*2Pa7Rm#c>uk zoi-4Qyg_#2ZZ_1A@$t8T?}dxU7<@%HmaqwWccEepJJdEn(spRrm({)iR+BorTJ=A@ zIT1MJnbK(H=Bjt^S~DpF&cfTM4@QY&$w`(3;80|WfjL9JG)7+n32DHc5?$lqeD|prP#MN zys)K?9KM5q>+7FvskKr^4gC`}^yGQEFE{dg%978+C$xK$o#|?5w&?nZta?umI>l60g! zfeIWh9CB3Csq5$5*~WNse|7Uq<>AWyNKI*eWYfG6uXB>*us0Is_HJ}Dy*s-f-Aq1? z##iII@WrNgLjA3v*|Bh3fxWMO5bJneAd9$Z;JJ>}l09rIIUHaz&$Ym(B?3ml|)$y$2e` z>;#3)1>Hv{vjpPwNT*Dmo7uAT?D(epa5Z=HN3IO|5?eOvmN(eJUhKC`EFB)KIkD*>2s5+a#k-dF-S!b2lupEqjJJ8Ok0_m(L#Za>o+qXK`ZVh6mXAfa3TyEpvlme*f z5Na4reuY*qYXS0BuVjLZ)O{2?balC+V{~>PIBMrkgR-{B?ysFdGTf5cwfJqps{2oc z6>-vaqE`=ydv&NqE7s0&J35rYQC?-I(tLQaqfxBXzJ^aTlxM3vqS+ZP{Z6qgLU&G2 z1rH$?%i)S67GsQJoeZBbvMDBP@Ywizr@6Rs&IhuUc=NGrvw>QZbC4Bj_;GmFCh0G~Tb)*-D$&IW;xH7axArk*) zNk0}xOZGnl9Q+UMSY2=1HWYpLueb|5*v=fwExL9{nlvAE*8r{SB`Nk$1O_c#+eBni zBdH`_(f__nQnF=5PTUmD)BKP~Bz1Us&f&e3UcX7ENiEpkuE918dPir&bHT@BJ$%Pw z)WcH|#%aXG#NN7|4h?i;-w)s#mF7~w?^)Yn$P7-TnuG0jEeQ*+*aX3~3{Pa_QBb*F zmYS(l)CqqooWS`M)s2)9yq@Un@=*Vi@_#!5%|Ypjk4%N|F+3G!t`J_&W+8W%A6-!Hj7`*A61Yj=42(eEt?b`1=fAT!H&pctTH* zsSfF3gAX$1%INfDPr#)ujrlp^AWWMwgEZc=8i zbsLz7EQ~^0w<k{FHA;fHRDdY201#HO%@Bf6#bg%(ULfcED#zj58FZd6crVHVR!h&fRrU@TQ91ITd>l>_o1S!3Y-C+UbN zgmEfD>ua*}#GfAZn;+ura~|D@Nh=s)ZI_4)Md!TzeQ z4Ej!2YtIw*EeKFV#nA5%IZ!f0t+Bvc8)%0LkOD2M+)?P5rGByyZArp%dvBG>gef+= zBcat9>SUQvyUUB!ovcG9#1bq=p&eCTE zjXCUwKQ{p+WL=-)>VDr7DO$_YWnN~Y#@;G!#0&$%_4{%WXudKRCmC6o#$~JY=$PLElqh6T^p4-M zQH(tsaMQW^^1WY@i_UhaX!rG@_NsWksGBt%5bF`G#t;Pcu+p zu!u&Pi7n4b9XK7kqfSHnghiFtUI@5B5J)M9=FL(D;uJe88<%U#broZRDgZ{q!h$Sw>wHQj6ZS}J65oH-*ya+X-! zks(HucjilJIhANFSJ14b3g_{q*!4u=HJ53*g4mKU$hyA2EbQE07QAw6Q9V<37hPo9 z<{Ib0E~>~q+S0P^DPYR3bMEa1DpOBFdAi&|rjnuu4N}ZJE>gQH%V%Z6v0<00#0DBHceGby-43MlW(B=OdwWr-*~<5g4fbB~HSoKX zt`25Ht&2haG{LjO?vw7m;=+Dx_hrI7xh6kbj;EI5yY`>|Fu}(w-zoC9W&4>TYjU5F zYX1T4R@-jdI1qjJSIh!l*iLNAEwV{bH`yeuvkj0IZk)wF6oo-aBb$g!sw9=m7Wwxb zQj#T0PSfn=ZS`WBn?|cogaRStCA zcIfsD$;4T`pTZ3)P4ndOt3B917{UH%)N`gW4^U_u%F>ubzxKQZH_Ox?26E-OV`AoOuNJ50$I|y!OdA?I z7Xc2n14uP!!NkN z6Rr6|tWcN@Ce9;Z0@!*H77{f`A_vT^1d0oFA1L)yA($lseoa{nb~|tlT!dtV;qZSF z;kZyVz$M1WG`?PEKhM{W{~_CSowR-~*T7dvjP|dtbC7vyeQULBG)_wP+kq>hTBIwV zbRZ+p6cfoJAVbhgnZ_abSS8;X6}HDWOwppr|9kE?Nqxc&+L;j?!rr*mIQ0@us)Tlu zREpi(vyHqa(nxzGH-p;1EwhOjD^8+BKqOTo0_7ZKPPT;+XN_T2KfY%_gT z58bQzZPHAj-Ov&i*@2Iw1<(N#qI6bxAy%OAwY4G1O$}W`>m`wzJ8UfY^gl?I zvXr@K3x7ZOap7FJ10W&oVrb{uS>}(?b|ZQCUDlEe-R={h^vl%h^yU$e4$JL>qXn8P zH{UI&cC>mhDXSg<+c8%DHZi)6#xhKZ%Pdt}F^A`u&2oZ}l_9|)R;hwUvQqzYU%NfR{$A{LY z^9-2J?vO8^J2s!r7x;-zTQ3!Xu9xc}v{5Ol>W9#AHECdXRRYqmN(r|myJ_^497TcUY!IAY%gTbJl?gnnWc6o{z>P9X=zPmea%=!x1_2%@$lXTf*ZJ*A$s*0;| zOShn=jfzp!-BD)}hUk5gNfsD;l`|gytvgVy#cjMxFrY`rI^u3Kja_1wy6)g8i=z^D zJEAsQ*g7556VBzZEoX;w)q&%6GoWWyLJ-od-%<3wqD~u__ME6@1~GunLgGdv+uZJc_v@Y+Nh4__ zWJ9j@A$mwK8g=*d-(UBLH~-wMHb>oO&yL75ax*v|O~<~wScKE}k?#mM@Y7Fy>Um># z=~EGLCRcUfA^F^g8*;~Z2#d(y^>^e>*-CZ*xyvQSOi{=h7Ej&d8hf+HvK_{1Z;F z*>ZQe66EL8)0ZbdpZ@fMjByFM5nJ+6%t`b7;+njAMNa?mg1mfnN?x9xw&bIp>o7k= z;a5Uz!q?sI(iN*{)^UP$SF-WwEbQiX)}495th=V6fX|YI!#d(Ykc;szg*^t2LLW4o`NE_BGyjLp{n+v7Zw%VjiO*d!6WOs_(tq)1r7e zB<_0Su{HBWm^YgubM*Vs5sD-I1+QmhvSP%K)-%RQupl7_#X{o1gCtx9kvAtZMqGam zG}*kPABvxScSkwg6#DP3{C^Y8KzZa?Jw$rs#aV&r<$_E`p9XERjy&Ol%!Kk~qy%@U zk38pW;reV&HXs=25rrUBtv``}JFtDLK(iq5tP;Tk!Tpuyc%Crq5y2x?6!JrGPuA4m z#!AupSOiFh2+&)wVZQ4x$&7<3nRt|XI0HZAY(AF6&lliyLm&szoYod)!s?2xnPTcvp&#cTAI8#BL*(#hXgD|Ij39n91+|?%z-E_{KG;)?kOr)1YkXgC?E93 z3qo;8ND;9~w$QFlAj=>X-fYR+zpKS?nG~9n>3A}_y#BSNHTY+@%lx_daA7MqJb*2S z%#gfI?pGjh06qr$a^)uE-rzpufFOcU;Fe(6P)^r{xO?w{cOOH{JE8oD@wUJZGlu30 z!QK6oSWE>hMGDt(D8RNi0@5f_*?_^Na!~u|0TJgIaZ=itUd;=F3rR=@WCOVeA`iYh zRy!}V+g;$!E6ui1+HLMoN;}zX6-t*cr>zSgt3s|YP^2KES^-BZmLE|g=q1Pjm>F{Q7 zJ-s;}4X!622II?d%P^PT;&mV(Sto8_q-uRB2TE1=XI2as98i=A0}%plzG9&pPBH5- z-uT)gJ&pE&l$~b$@a>ytb(JQZzzSx3X-@v;++IQ2Vj8 ztl|FkeIe)4Iq#QFY*Mjos=s2+EoNs-0k6sN9rYqi4D0PQ-p!Y1Uz?pyr=Z#Oh7RAn!@z!PRAd__63pY1G#Vn=dgFi)aZ; zofM>qIc_#vQLGgSjCz`>cALu-H#V89QhnowX)-OdD0I}XfpU2EbR3hcqbaAU$C(O2>rOFit(D1#$o zG*by9l>yQgr3jwt;Y4yEqKn_b+L*kI8rP9ni;9@p>`(!H z*)1c{=FtKQZQdt?>wLJ@2iawgpU2+&)ZoMp<){*4M5D@Ng~>8ml20jGL#l0$zcf;# zzAxcmwiV3l?0YDG59Pl=DBFwH!2&uL(R{C1&a|Zvy3LpGQ3 zN#UN!J%jc%z)W%L({OzgfcdEZJE0(q%+p_F*#kShvW15y7K?o5Dao95FDrs+POs3=8 zSsyj>QGNHcaVR)vo^sJI^9im%wbUbxMFrWa{87&sa`XREhpgv}yCf|0ufl#y7Pj`u zg$DU@7qqr+xdK~>{&Gi6-@)J0!QXfER|oxl<8BU8?`J%70QHH0+y@*K5DBsh?x9iQ z$r-QOjuy>)SfUwMgv?t&8`UNu5MlDPwm?e+=7ahm80jXbyhdh^d0ocm#YSF-IENhS z;+af#ntev#+qbwDKAfD`rilr{bxT^!m|$s}DaCW2KQ9){8E5piM!A!6xCpyU6e}gF zTb2sy$rU9{Y7!lUq6b0>j{bZLxS zeOR~;gyg2xP$=HJ4|L|S@_Nx%q^r<#q9Ei^IWW#l${!e)B4`fwLYfIo`--BjJ7D1{ zXB$REvq2g-f6qC=^SC~%&}y{`r0Za@gN%3NnNh;0;#{ioNZ~ODRB1H#9z8fp-L`L^ z^Ve|O0N+EA_h(z35BKuc+=+k*Yp@s`-c=QRDskA1G=DXZg<>+G&Pr>aiF?LW$}p{1 zd~J#N8Y>%B2NMsfx7_cQ2N|Bu9;hP`P%k%mRCfjdGkem9?e#04c4Y~Blhyc{tT)zb z<|=oOS=rlGDPdl`oDvg?W%V&ujg^H>Z?2)O!V`E#y!5d{S>anVfuqer(K|YYpOd&>jP?<(3CHE^=Fd3Z*PDF{@WCnP0;qp-7avOs%0*kl;z^LEA z7Y$|}^>5?c;Lr$~0GB{$zij}h^8oM0u-8#1rixSKdjPvJfp9AWJWzE+1j&C3vagwX zEfT1x=k4}>3doBud1Q`mQukcm)raxc6Z%{sEfq9o`iL};p`)|T4lhmin9eff3pCO< zpfOGSP-wgZ*$|I)&Z33$yQ*Z`RXLO(j zQKU7LPYv}$3T3Ewpdmix`=_|7R-hXGFSeUFUK^9?@Zz^YU%u})I-d+jje`^u$vV{~ zMw%JBWjs)q#)MBb^78ds6X@XHalAnxS$XV^d1bU{nCbH^?`FjpgtrfZyDCIXq_)hGxva)0wf|(b45Nc@v4=rhPeICvf@Yn_ zqkV!(GL7@+=1 zn-VXx(W>J$x!lmfjcMUza@L*80?&?ttz#z%?aF?O7ypW*`n&`o%DGK12$KPxQL>^jI8KfkBsKGp zp@^?4Uy6@^V`jGC30i8I?RajcThfRpoq(*ca@VCL*)prkOuzNJ_UhIX>hsW--Bx-+ zC$X>2%tRhN2*eXNuI3pk=qsf4^M-q(BmU zDDtJbxneR2MFP8vePJKS%YUwy>x2H|#|Q8jE{7+h$=Gw|^KkMe@@($--uCG`X1i8k z(W98t!zE(X+e^4*L5T0+@9N!a+v05D2lqgq#hbNd-&hL<;>~2>&zOM10`b*~_|gyX zBYYpQ1&o(0*!cboUM@oQ_&WS|?``%wdgx9e~1B{r< ztdM=1?0%xYz1~yWD2FiIQP$wB)-GEykB3c(QPk;~zV2!GeJ_p}5 z1?-_RS!i0>hX4Z_tk>&EAhS+i&|`A4lOnRm)4e9PvB|$ z!!J$SN4a^t`2miP)6kgj4whEX*3e3JOKUuarpGqqsGCR0gpa^nbZ|v0LLRuxt3yp& zgPGZig7yf>eVQYV1p&Hqq-}V&#*+c%^;EhKu;!?r5Zevhu=|Z4%#Pr1A)0XH&9q$z zNHdFDfRLmKDy;3yq`7kkkdcBlo4s-Ftf|X}L`+N4qzSVF%`rhcA&O$J+3ZM^84O~_ zgoUKTgNS8!EXdHX<6IVWUj=OKA_}1ntqh+LKQuFVKAPCw@5B2DT^>4HGJDC#DMODZ z&uYoi>+vw=COJc}U7rs1*gS|nf6ctp07+n6a7)QQAqyps29APXvd{@9G@S*_4_gu& z1eC=fsv(H!DG0h1=&R^ZQOciq&YV_7sME(8HhZ&kcE?*+6Wo6XVW%jRY&PKwF@9jl z4o%V~WTf143r)!+?zBPE^u&6^ULJ|P{PgzhYB;_;8RWK;Yzu91!I!wR!=u~;WyvMD zbieV{ul%cOG|gXmvk+6&;+*d=5z{t+KQJ>;0XDjk1bdY`(RBYvx)JmzhCK>k8IK|f zFi4XS}j5=L1=M}od1p{NU0UX8(RE>_90?s6>rBg z^ynd(k`*fvt%569VR}k@r2IsWz$h*YeG1t$>O~%dJKR|Jy%fZKqM~GdWx%3nKa&X= zF@thEqLj8x&syvj=WPTPDdM7XPy~{SL5S7I_*7ZtQQ=>xtNfDLOT_HL%>PmB~ zO8!dl{sT}R&@oBB708iMR6Y{XtRBD$m246@g zAHSfJjs3_1&si)jZ{%=$>BwDRTqMo>xa#YuGmh?S;2|pPjdj3o z6JF#Ks7w6p_)(Z{XX^Y+cPuj{bx|-#P4FVuO~0W7EqPJY12gB^X(cO|YHCsx>R}2e z@n)aYUobeSe-$YRdPS@128CIR3`MftYF_#-I?x4 zW8u;KD{XmadNoKjvP7W*Uqpi4mZ-KQg^7+lA*C#INV-@yTPN=N{te)PH4pq1Mm-yn zf)naM^p!e5br`3x_sk0Zzun$a6&N)hst{A?-%4vSc`(As)pc(1D0Xu3sC0Jm$UD7w zq?}(o+J-&+8P3p%`yrfSJa%`Eq%5D}7ZZ&8_{Zyz)p3z2w$*J92;v^VWya&bTZSK6 z_EOenr;KkHlL><^xcrqbc&6@z72GlSq$>uP#0ojkkBooFDxx{m)hT!qN4qc6qCXO$ z=}v)fOjlw3-AS8HMZjhh<{y95i+GKTzy2CpLW~00U{a2$mJ5(yW5!0aK01Bmu~z1iSWIbMRW(9OFq`ua;Y?*K(DK zrMH6W%tsI-rrT-izS}h7JGQh-4~U#{nS%;5i!0`uf({9S zPOy6CrGtm0MD~!K^VC(uNx;_3;;kkSiZnMW&thHQ9;^lLbijPkP#+J{gs+LJ_Q{_Q zl#}CB^X`t}1QqM^kpYeJI?Tyvbn-KuB*jxijxc_EF;cTlLPB3SzH!#lWQP&V6u~zq%dn|DM@u@y<*qRYuwL7FUzyS%pX+#0rn9Ui z-%{?V{OMAS6NZc%^Vv*(S!ndCibfN?Bm@u69$IAEw_8i=pm#r#lV5`_zb_Y)O3JX7HCcb821ul4n}=Ev<(5 z-yz4TYgZR4Ag3&@yqXrUB>hY7i^Mm}wn>R8tEA$Peyc?)TAe~%d_&D}m}f6|b*t{g z^^CXi^ZcRUpqa`7bslBcRK%tU<|Ifl!7y;Xei&e`JJD8(gM!)t!A{rcDz3C<()+?| zZIy?2_3b$WM@sP35r}Me)jE>VHJ;$>f03~`9@v(=f_4ux9}|cb!wdqA0M*^Qk1u7C zbqK5I^$I+vslb;bvb=_7VoPq4xptPTn`Oh-#ItVemXz}*#}j?ZW<27!A6$>#{X97x zoeX{)UR74~{|p~wD*LC+G82~5UQyr9eWRN#{!b-oZA!P!jqOwFoU3W#%EQ5b0PR*y zbK5o$z3W$OXFQSQDx#7}?T&1xmJ_-0jH9ZylS{^2ZwgG~XuZx?SLo^F$FddJsX4fK%V?8@BMQAc9^z1#$v*eugTcYm z=YwZ2;M#`3)U4prM9>+XP2lhl2EV?5gTnzF3D4~_*gwiZXkY@EQfx(1k#|TQDkj4}TpL(2i-{7=Go(gXDfT@; zg>$M1$btC9fc_Wd9I4!B59MM}RHsYZpIk6Lb%f5%?EKy2)y>5plkSmg`g0IiDc90> z4l`9U$(i*s&Dco-Ctd(CKg=$0~(q&z-k6u@Lb5b91Qw$JNv}PWC&dcjO0BP$J&g}Or|KsVvt08! zSAu^uBkbX1L)(UnWoif1>C~fY^y9ZnG{GIba_>i17o)SwaSt}ZKf|+bui~@Yg`ZA* z{cdfr73FW3_O^sYG|%JVaJIGF+0u!x(LLG%%3|AW18r0F$rJ2un-JVIs^r~fOVk!| ziS4wpQt8~$PGLO&8jOZTiAFbn=v$NdJeqL(XtzR*Ocq6BTd(8FZqC?)_C%VIK@!{D zT?}^zx7RZq;S%hU$BdH`_lK;LVCE2pbDrj%V0X6z zyKs4WautpRPZAwokU1CAkrcN~7%qhle*sjgm+^`8a*%NNYN zZ_W5Z6ooJJOqhjYa5SG&?q1t7sLU6NPg4VL27~>*H-p!2VQf?2(k$TI#LzwYZ~+Gg zF!<>$>>mtZe=z8|sTrqCXj^=0Os?Mr!IYb{hI^V6{snCUD8mJuwB4R-Dm`Vs` zATU{jHbfb?!~FsQN^)*U1{pJ^l+I2mkeU!Q%ZVaJD((MogMVX#x{Cm=SjLEE@0NUp z)!6ZO`lXclAG-zkJkQu1Gjv2z#C&X4xl#Z8z(32Q1KN|6P~1dN;^gJ4pQ zf0#yJ5sPUgWE}YskVxfM05#6BazG_W6%5?}yoiubND4u1>42WGD5~3Y!w+RLK23z~ zGFm^AaCCk$9{0BloLx*#uRfiOPB#X7hvkN!f`DNQG?v~V;!;VII1nL<}{CysBdfTjOD) zw6_khgN;vTmj;{5;^k6vN3vD1f$!?B@m~0F;UL@skP};yjqQ{iJg5JyRHl?vABiD2wKR1>6RxybVbm+GK{V?R0z5Kjr~;n< zP7Vi9o$S_!%hTRp&fy7kbF_LmCx)h7@9~f8lfB<>9=(3KogNH_Lm2cLl&2% zyH#Lb;8GFxjM#p&c!%o%4SGo&pIW$XiP|8y58l{bR=*+QsD!hHEy-#y__W5uC}n6w zlM(}r&=dr_gFC6>^6t~^5(!3Fmh~Yj48&4+rU^zXu$oW{)VFiEv8=jb^gD^o&U@v_VE%F?m%Xe;c-oB3) zacA`Wd51hFmnX+x+^Z;<&7^xlmq9e2@aUFBD&UcH|4GBZKTRSJzrr%pJBL81Y5#Fa zZkdpYYV#PK8I#y|YN&3r5~9mtLSh+7up-??o_QDDrYVe*NO*_@`Io z3b&9;bx%GkpY)DDUXV9$$oOxs$m=&_@_Ib(Ytk_ASR_&Sg;KFR7>(wES|rn<$Co30 zOh~74WN9{Mxi)hF`Vd{5a&H$*?k9=OMhiXr$1g&(Dsv$+H1 zsM85%r00cHN|)UQQpuiUZF8>_jeIJ6=^js|64X;yUyx9SBQm3*gpc1l zD2Q4Jz9JD@+3s>r?mQMF5_--A53X(4bRdbiA~T*uzSBSKJanD{fG3em1e0XR01-Zk zU|kXlQ1G}A%u~c?F^hcQNdTg&1#Dvi6lC{$SDZ}2H^>O!6pP>%pgSO-0&JlmYDjdzLN;`NBd*B|FIN<)&*N9vK*(f#x2tBJ559Tz12C=X*zojfOKm z&&e?fAs`8#5gLX%OD^d=@KTt{VY)Bd{^6DifS927>6?-MKNeg8)Bto{O@3~u$&uOH zGn>~xjt81TjC;x<opXD^|i9FELNx$qwBo$SG=d>r9GnF0Go=EOP6v%?C zHBl1nK_o-Q;$4YW^oAuVRcj)}!MP9$J2@9La?ww07Z`aVkJzp{1<@_PVLR%y2lk-; zv<=z32J9KMr+E#@!q$Ow&O=W99Q7!UEzcy2T_`^LmdLVLy3*y^5ZBFwBXfcLU8ekDw@ZB!E@*w95}<03R#e3QcHsV=&5}!jJWCVf@T1{x>nRD21c*)n)_fJrio{^{m z?^L!=n&+@p)zN9w z`DSEI2STS$-W#Zr16|Ha{Pg}pfg{q$&L+5unHS6guwNsAE3irXS=FDvqu!dFXK zkIZOuOtucm^xO;HE*@>(FxqqB1C~VK^&0qQ`c$P)%4azdcN$Kyv90k<7^14dj!!Jo zJ(IRf4{O3bgBV`ctcMw{J_2eOMdZgH>)}vdtD^3x8FdBXevoUxhO+JixUP>Sd)t_u zc(XuAsB~I~{<@K)fZo^fw>6tA*R%(_wrCaUejVhS^ZVJX=&G@EC3*JA+?hEaK9^r) zpf$2l|7m_sIqE*pRlx1(hyc_H`xfmM6;mMJs%Di$paEM@3;jS>aVF*hDrBn_) zNw6iqWm>x8#4&vm>+8nGws{v5wiVfy_Hm7GdO@&m_H27uz!N0{pZ#y#7Cd&i|HT+<*Xh1C(a%a3 zP>-1Dt8D&+slH(-FQ2((49~XagScv*#jD*<<0xJ^b-!V}%%b%;p5I9BH;`xK|D7Xw zCf%PllvmW3*fgM0cs04=cyp@cq0T$mZ-ClL(4mxh=pMPur_@HIblT@w!<>>ix?YxQ zQ%F=63kzOyY49Q->)0s4Zo-N=i*g+hYR6YNmkicao@$CUV|YBU6tR0_TZU#fwoZSA zUZ@<|sUv=406%Cu!HsySF@?fGTt}{%V`^#~kr1Y`Wv~3wHgLmq1(TB=;Zuafnrca* zv&B?qPR6!`giJvlO2-OyEP1$PSc>U_8%%%5t$&xC3} z-Zu{3o$WS4bLy0v#4!`K_5MD_vvXf1NlXEJK4&r=Sm%&a(ru~lQ#?F{`7Zdx@Z8UO z4R*}IjVfSBnd^aaw`qW$-!5nzRq<@1sS@I*Fx7Fr&D8k`hiM9q@$Ux^zaC%4V9DCl zzpD+;OeAcw;HExA6YDM~eU9wQ#fYsgt)y8F`0CDyotrCGtTr_#w@lm@6{vJ^Sa+A? zW?E1GA_ntP)n}V0$%+*DAgO<&-8w@ynMiN69M_-Y~FrOW*W-_ct`uuroTR({WqDFD@or0mf@Y1Ee< zwr4?Yp$!VBatM?3sunO^#8CfSV#B-M*mY33u-lFxu z-^5^K73oSO6{CLhB`zwOXXl0;U%#cMsJ5_rednSIEJ{Vey0}??#Zj5S@s1}GO8ugD0&%?wXP;!#k# zRZ{4&kY*9yOB}&qjB+MK0Cri|)@aVPH+5 zudm^wPM~@6_8bllp!@4f*gxpPez)6lt{J1qm8CM)I#-8LG-7&O#2qRok=rICv5MAs zMsX(MXhM`W-wuLeN6$699lV2&{(lM2ufPopZ_sljvSXrc$wy@z*3pe;6a*}VCe4Ua zL!2|ERWn>O8xAz#36Y5!p2SK^LiHjs&LV7smIbz;*Xuz_GG#t*0?Va=Qkn?&AUw4j ztY_gNVBkVSDhi&2M-ESqrI-Q7*#^?toMLX3)AW0`j)L3ZM=0%djPy#Goe{Wm1(Cu8 zCoxKxmQJekzXaiUaUTIbV}?ZGVRiapxpusxR;gFfBhm>t*T|E9EWzL=2%PkslC6D>Fq2=a_WXP#D*+F&avn zsP(l`l10gdVm267s#dtPkkW()w75dP!26qnaR=cxfZQAx6Fb*%Ser+cs0+zqDp*p^ zMeaA3LL=42IW0JKUzPcC{U=*kfk)DNC8j@m7bSTC7{w$~TJOLkdiX3J8?k$}812(=aKNhB28U z5Dumlm`Xy0L=aw>sWegPtfZz6N7azv*|X(P-*j)`CmV}lxSp%JW%XCMRM#7xJXKFT ztJqvMi7A_#BhO4JU1b;^tpX=R6B|n+C8?BS*|gRSmlR2o z>Ce$>-(j|Nlsilwopl$}$EN%?icA~ati7%K+8h^hLb4y%;AZA+gGM$?`IZDTqWn8= zr*5}^#k){<=u(SE!46F-+FMD`p9qQIp$19}YZ8k>-xX+2a7+FwR`;f_g0qb~5rw@c z-wI)mXG{|K4-7TJPO9lh^72*1DX_cdpXA-{!%*)!W@| z!7dEXPp(Hdk(f;M=yM$e#N+gnO>EkP-ai z=8ipP_*AM#pk+IQ#O~OXgPj?jNuOIPT-j9?n?NdDgx?jP!cD-{gOonJn`-xYtpAC{ zzukzNqlAN;KPoW|47}?1U+=%_zdV2&+5$uK2$#l(_Q~ldc=HDOzaGHrH+^{B@9)^7 zq40R5NtD2txqjR0O@#^Kao3Zxo@EoVvF?@R?2SV??#-As_-#peylWN)PH*1BW%ApR zkM6(@B9GMPoT)A%O~Usa4rS_ive)`qQ=A3dyVGC-W<)IV;zjfF5IHEqj)yv3gjep2M-T|4rCnqFwXp?>kg%7kMEhn zMdN<=?EiT@M(|)OIRpbZIBZq8UUL(x2)z*m%k;OapWnqZ%0?Bf1ID;zv21y$?etk&S4_^ zk6w>Qex6E2r=gOFo#r_eI`9yn;4Ivx+R)uEvSqwZO|8o2IG_5VJ@|>m`R%zz>Ae4Q(8VL zy$y#G$1;F9IyJWf2B3&3D)g35Op%u%4T;GpnqoD_m8IB+}ineYItkp z9{kDfP>a~6M`7)^Oq1mtOZqYJ0wz)fXWfh~hK%JA zoSk=|otbAJUhZ@-T*I&fM#UV3Tmn78jT!O5046NN9Qgfvs_K{J^4Blh6ye)n;Ti6` z9sPB3eQ|PndA^gwCku^?$B#9TIIYpd9t*>q(h*;n8ihaMbi2T@5`Ue-at?|;f}*f! zVJXa51lDaL9G4S$t6M}9$x}4T03iyWq-oT9J%;Z&CV&|p#gvOdhF+AU&5Q;nJrqMA zdO7ow9~@$eg`)xV>0^JtESi-*HM~HJQ~7oluXBiGxlDz|me|`ntjvxTXLrTvA9YG@ zDUJmfliWpG5BepiO|*a)FQ6c=^U#6y&@3Lx5?1MJqe33FOT;kKMg|qEwM3c79$|z| zy?>OL`X?!tqe~U+*=-8D{z6wI$BL(WjkOON-Qm9 zoOwZAuC^tP;RU=~RgfmoPw2rQ-iiK{eA)cA^xKfzu2C#iqN`8?v*$aYe zTf)af;EOqa;oNhb-Xq7cao3XPdb?hH%gbkm0rE;NVU7E8CyI)6HaU_5V}t$qPOwT! zEK2Px^ZgHEL5cpHaBC;1soHNtj z24Yn*cr(+Cao*`rfc`q}R)Rujzu?Lua+XBEDaR(3w;dEt*fpZ84UQF@5r7a`*pk@J zC6bMKH?G#NRA=35ftXZ%h*}FwhYZmjCk$}$hU3w2ZP+M7HYbo-tgZ6Qq;CVtqz!aZJSfG`F9fk6ZP@sLCkEjSak`pZ zlH3hG@TAzQ@x3v}{{Ia7z$vHNzrxd!i`~Lr?3OmdyW9faEp1Fc_x9F?|C$ikTA=Pt z3e#vPAq}(<nMm~fpi`Dl88Z{3O z&6^7k5H#|4)I>+ynHL@+(+4nmhjdf+&A9a+?O1JZ+cpsXo?meT+}cj%mlj<+#7&mO zb=P2N7sMI*p$H6GqHQ5EsgYD1ukC-|9Z6d+w$rr5zEvL*MdTgto_p>&DX)G{XX##N ze}515;bL%dIU0(1GSQ88i5U zL+Ccbn09KA6VPO@fg!FeiKl``5K5(ZXp&|7XRW`d)~i+lxa0|Enjft38u_*3A0$PX zFs(N!F}#No5YN+u&$%$VS~KTk@6+BM#bWtJ*FIb!Wkfa~b7iTLTGE7Q2zn;7B!V%A zSVZWPM{RGkvOT_K3Kxz4yJLT+*%*<7nlpk!c;4IFIQ5d7ObO(qKw2ucq_d5@!IB|| zWBkFjfd!*PjD#e{f(V#MwGn}`j+~QiVN5a+8mbhMl)R`$(=LBSb0gxiSxec-AV%}BTTNy|9mNs=*H@*Th0%sBO4INGHG`Er*%`Es3H#muCP> zuiXl1fPvr(XWL$Hk0A93CFRge96c3(4lB@2#JG z$@6oB9~!2pd3T@U(y3qfDwYG}9o%cVif;?3++*doAaS`Cb((7=qp?9TN~D-tQLs=I zku5qSh^;%fM3CwkQ#2Q;@w|JS2q39YzH8d>0WCzbEV?2UqVqh<)-#p_6URXS8Vh_A zr!FAu?sBnm7(6&R3@gIaui+OgRL;(a7YpOVkOjv^!Vp<#GL|Gun4tLDKqs+6Ax&c* zTG7EH4K=S6E?OdPP;@rtAe)hiW)ca_%}T0L5GdXH0AgR9=f3<+@^Z zBNw?AJZa1s>qV0{KTj%53eZAHOrm8OtQHsDp0uy zv|1G(`x3q59U5#~BUkJAdm${IMKJJfvG4n86OIeTZ)2J1Z-!*8rL7G_3JU!|U`j$% z2pI98Y*2t`Qf!kdw_GJ;jVpznatQT)38{IeNuvoaW^sb?k_4A0lX{uEwMl#jPyviZ z(VO^=jT1f~{|$FckPnss>gNQRn*v)XCj zAjpnO)Ni}_L}x~jrKJzCGBob;iclD`*2mfE<$CLUS#i7~Zsl>5Pi1=B_Y}Aq^-qR_ zQnH^vZyn_&qt}BsCx4$`<=m^_kEonp4o?2GL&ATcY<^yVSbcx2^u6kYf}@Gz&&%Dl zEA+fe5mX)(U@A((6U+#wTkFVwqm*Gl6OD7JBVhj&aOK^OKzv{8L6*yX=EnLOgF z4`up)g@0uK%e40&?Nn_~+dvHdo?qb)NPQ7YGQ{WvbSrcSkYK6^5+9@M#Z6A6ciEjo zn<4)DoNGW^w@DlOx=2xcetGP(ALsaERa8MV90o9i+1bfWnrO9Hxb&`2gsu`2(?psI zFLj2RyfI{7?|w0Z2eeKZ4evVLL<+*(*alj&*D%Jt$Pv6Iotg|i3R-U!H5JCP5zZ~< zkQ8WF#$<4uyH1?AFSYs_YNQWa5!b>>xR#fi8jEneTuSA|?Fg>Fu_`YJ_Tu>9&0hR= zAClGuX4JqHWzau4{S2cK#P9dvU=+ha91nbGsU&LG7GDrm?l6jSMMXUirCCNkO)2Is z+PYaZFU>q!3P&t^2#F!B2~LwwaJ4yi@cJJ7)50@)g~EnBlD7D$>)bXvM@B)Q7SNZa za4yBQa^(8GbJS>+{9%I0FDKaB1+p~`U_2hfLX?ih$Dl1^2d(Aij-fYgvEk1#K^uaF zsdd&n@=#P*vjUB)?YXCCYl#&xZTg#ZgQMUncqIv^1+8d4{K3U+3bSQ8AqYAK8#^oH040~9N+tf|GE7dZa@DT0B*2E;qdUKUukEX{NoaM z{{PIF-w+hnJm&0gI2}9&p30t@?K6ZE-GFP|fM3SxsOJh(mzm!IDQa%2&>fS)F7g>* z@*phJ(u$_f6CHHw$bTzqh$+Y9+tEgE3Q;=uWjS8TP1tRk++E&IFL-T&rzqk(fp0|c z4W(4UZrd;nz2_@9pBE=P6zIW85xCtJAlrg9!7jTfHf;-#DNmG=_U}hIfw8Vl7GO6@ zdZgYXpOoD_wFdU+SX-JUAJS=ZHy>p#7-aN7s>NBdepq}@<|D{T|b;`ug)aUD?CSgiGLi%|gx|9vkcYw+?Be&T{+FXpfOU4rv>;TT+SV@5pT%Rg0$d z-WI1-1fROU(u53!BG@6^-ayeP$6zeg?_n2Y&L|cDZtMZjIV)#p+pfhKX{@(Gs(llE z0a@p)w9jkgxE$8cCj*%X*RA#m?3D?!b9>WEc@0%NwkCL7y-JxLGqTBx%d$!2I0)S` z!j|-tC_0#4^uL8XP&6=Kr39_XrFR3VpL7kYO`{oFWL7nTgk-&t`4zOo5)=c+X)`D% zPb1D-b}Q>7)-}aR{@)`=H`aa$Mbmp~QF*bg7(^ZQa-6*O&+}_$aLA)_f&U z488YPaJ~#E5PR)u2RB8UwrjDj3z`fAb{PbjPK3&mC(3oRUq8zB+yCR_%&b+Cg2nKd6h zD>S)Q(nGEMstvarW&Wp9f8&XBVomMm!U_3^eqIX6>4_kD4{(W63nxNq4p>iZQK0ec zE}m*j{N2EGhwno#w3Uy8tuL+YRuiq3W*F$IDE)dWyj%^Ab8ECRIN1Eon&s4*Of}Nm zWDEw+Ecv+?9>d1lsGlq4G1L&*f$`4jxp$THmBY6yy8*nejNG6Z8lycK4m}j>3mSAv zZi-vj%ti;zwk1%X_U-*c_-pG5zK%^_C=y!R`dg*FDmC``qygYY+$86FJr(2+0q#Z7 zRMk8MY1UBSPYp-w`0yZ2o<8v>HtkX#;mbsF|vMK7(%#&f>jqNzSZAT6Ec5MCjLWxrl`FT+;x zCmkt@;7RC;k8`1^6$xpw^JRby5y%{7EuCJ}$!V)-&$c1en{kJ}D?RDn+3`QElTA;PH>12j6GIVk%Ee}Fs`j0joKOWd7PZ?kZ>dDk(DCl1%2kZyqU7bl;Hm%ClJT>?JJxW?R+}E#?iMXqv(T}6HUMq6BWC^wTMN>gmZnu5JF)S0 zu1xd4D#Lga#tOR51^tRGA%sCxobvq(*gG;+mL5sWnG|;+k0drfiX`93&-`jai+Bgu ze;}Uh{uIU#fQ(5aoez@~)Rd%afpk3;LfQ%mv$V)V@g#5DFS0E1#cwK;U*%QbZ`(Ey ze)nH-12V`;9ZTujq-dKgspD<|64$Vey%d2#ODBtnOll;Z)GPYG??_3uEaw-ty^SxH zdA#rLzWaFm_-mf#tzdt@1^dv;nAUKCQN|QATnd<=HeE7V>+ts>+@aET|82Q<7BPc! zsa9akZYO8aEt?~_ooP?TI2JrfP&q4Gnp7$>!fy)aFiuh3OBut*xh_A?^q))qS684p zEh5N#rT9EG@Hz~S4qk_cZ(wYXz|gGV%EZt<|1^N(V+h~9furLPj>6D)t{IO|Xq!rE zOs?Mt!JM0PIqODp5x6iJo9UpDXE4j;ELbpY=-WX=*frk_d>UWCRq?-s7q{S+g(vhJ znd%asHu<3Bp@~kOLF;9N_fm{*HJB73t{sty+lrho*APjiFj{;4uUk^-6JUfHGL7%o z)lW;?*}v>v!TWGLI-I&~J#}5g^0(GZX9m8=GhCoBy2*aw-}>HawQM3z6L#%W@@A=o z1}1F$3sRZts#WWH!PP_<6r0SLc70#J*Km|y-8MxnkIU^n+S&GPs ziaKvmRNHsv@5NzSb%geMw_1~F@9KO!?mS?)98CJ7&*#1VL&nMI{Bp8m@IMqx{0IUR zaXqIUhK5Q;Xj$J7(t-PwXpjOeUEFcwC?h)wL@otkVZ6gpPVHLk^yV|q5cWtAk#?UG zx^jvAm?0N)&=C`216HAMiZMsEUDlp9q^F^wZHtmi&9^S{lJ2iCMYe=cLB4QVh{Dx{ zc}xO#lE+UfATJngKSM-kQ%+MVdnMnrPHG+pr*kwDXKGW2*QZe_sVQtDF*3w)P#$8K(=-PUP*OJnw1p&4m=oA)2PE~ zlu3=syMb45=+{c%33+Y8|8#N!3ClG4HBvUEQhHvWMJfEOVX>qOJVWX>uu@hlD_P7E z@58olts)l3eT&pC06VqXJK$X}Gs9`tl;g;!%5DJK=p1)gzOW zqHU4{=?Ur8z%uZs?@?M}IWF{4yZlx7}a5q36Tt z34}Wx5Nv^(#yUPHlEL|Pe>^O;@w8&X2CGgEm59~>op56$^;mt>0yJ}cfl@YA(ClCa z>=S3)#LMswGiWm!1^Geo=Z*P2G&po;yJuwLB$;>N^C{9|m3 z6E*mT$Q~8ie-y1Dx?4~7sI+yQU zqzJu=!%Oy=wb6^OWZrMqF}zv2i&6ug$grDLbc`s2jOQySKzFv*m3T`>y?aNujIc& z_Mc8b)f>A5-|hultrh&(>%DmPWAFJ-;OHqZQF|CE51ReAV|e)zdVl)~UcBtVi(ao~ zmio-4fz+a`mDmtJP{+0>d%=JVB{dC<09pAVQEm z@FggIhb9BHX7~@43U)+eDh@tFg9NbTq7wncI9I{|S&-;s*ZjW?7id6OhJmZJrO@RX zMKoJx_%}NlpEN>qHou(=$MaeL=hlT4`b)P5O7l8fQyX>*%7PV0mjpoq7Nf90LE))O zg-)L+3@bq)YHt(h3>yUR=HwNm(pDFe{@I(k#6;k(ueliTV2Q?8&9q&6?W}4+xUrx{fp)xg93=;9*lj*FYz=69 zHkt;Z@52v2z+u!T_S9(J40S35=ITpm^exflnuoquT4tIiQ&B7vF@5mW#ebE~A8nw@ z?X;3&bfgwB74H*OrQ;PTnyU+w$8BwjB2zQUilX8;hj`vcA_B})P3u)d zuEsT{K<^_O*0FAEw5@hWkOXzP@ZM7;n43ftV!bo0Ajb8^v}s?#hCNUZ;TwA@8!7lN zKrsOG#QTc-1w6A|rk=zJuB4neCNQy@V7-f3~FpJn6Xs#5t~>IAPTnx7B zc8^|5N^nVmII9{9)i&lyYDBIw*W<)}G>y&XgHhjc%=_h=_-A?gnayv;v*Gl*KN#A% zho4pRXVd=8EWtKEtL9#R7!PJQx8rDT{Ihg=x*pcC26<8Noygc)r6Kph6opcKVDxNI_USOPxEyi zyR@5Cz_Ft5)(mq79!RJy)qG=)6rId;-C{7T^+hV$=H%6@I^As5eioInxSTPpUoOtZ zLe_#y>^YPOOIt5=nPNdm^UYU<(E0`fo5m6;OSU!}CtYD-@85ri>Q#f$turhv`wA+c zk(q9&$i`YfYMqP|bhm_#RJ6hs)#8r(?}yF=1F%fOdO#mku4&b+^B6xj<8zoZe19{z z9bufsHXD4Hj{Y@&JM9ntIh?iHhG|cAH+@mq!3bw}Io4=rgh6%|fubHEqpV&~>eQ@& zr}oRiEd(Zis^+fGB^8a&C9>3tmNc=Z5sK3*cu=BH!FwN^;Un33J9cI#nOT=~!(8rT zaj9^A#_gy4o1h&%O(k|ZEI7-ykBp8n>I3QpctHgjfZc@az`>q}NFoPu&N?S1d16(YQZTr7Dh*@slfQb@qtp zs+Rbx#+);o-i(Vy0WBw$P{`UH75U|X!n_+`KP|z|_sf$6sz{HhyDQ>r$9wwZ6`j^}SC3;7FpsVD|Jds10V8Hedzs+xfh1== z)XnVG0f&RfgN6cg8>w-SqzD+DD)XS`@P~jdk+d>DBrWeB$XqF$V$kUex+F~;&Gsnl zMDPV!Xw3uoK8n8Y+aNjo8e((9OwR5++K@0 z&@IPvb@qe)q2!ol@CBADdXH5~MMhx-S; zx9?zLj=)$yz_pIRJO40(qa*13@(vD|@{wJw+zF#IgzAFL-F8lcn!C z@f^G`VM+yfA1kdq_akzYaabmW*pK;QAov|}O^jF4bD8nbENv3xc0kJv+i-Gn0&|uq zdj0B{xb#wrHE>)va}f;hLre{d=MGF9u!Dc#Lc?5SJaXH|&ZD!7$c9{H5*4iMHgMWk zz$8M1^O$1#I@Nr-(R#N8K1F}@4_fV5CUaK*S;M@OcHX}-5UbuuH2uonEZBOJiWY3ZUx$gI?XPA`i z!J7ty>+{K^1JmGYG#%bto)3oRV|sIbHEnmGJazeHG?-p}9<_^FJ%c*~5qwOt(_YJ{X8+Uz6$Smr z7WU74$e9wV1^w+C)Xj6t3qeJWUwA}4Fr>JDfYhYwJ5;nZDqSQi(K24uFXsks<8}>| z^!u^e^eJzH*2(90-XuEZFn==FH&LLJ`3$2l+)vw?32%Nvk+L5VKQxBCDp-L;lezMPgHT;AstJ4qB=(!+@8sYCRn0?f9z54-UOF2@rd1r_ ze`7f8+RH!ZWWBbTmks>6ywzY$;)*l2BAkB!eN;_T+b|Hl=T~fVf*Gtp+e4?#$CLo& z(2z`>^sdNjtih37Ne0qi-(4vQrhMe!*xJ?ZdvBjKoIGx7xJT!;HKYESIPFiyy`gJs z^ccX%4UYPY{MT83+=F3(UOC+a${jB&1P*|*g*La~gEWP7g%}RHX+7HZAYBQWPRRfbT1m0s^jQGmBkfEw9#Yg+- zH_#zfxS2myvGi~phkNO?WRPCO<`8Lv!*bOBfd-vcf{=&{?PXothn&028#Dx0TvD?u z+nR!ffuTpzP>1dKbT~M?Q^f(7><}gyrj>M31p;wtcG|s5-I{s}tL0Vp1s-&$Y#ZQw zK6@K-lv$i_1I}H6ZYJGbf6#&ONkFct!DU&Z3eR-^4kc}d{Cd9nc>x8gS~>)S58$_( zwXHoI(USM*PoQj#isGFRUc=K5^ol`=V<0Dhk__J1o#38ZVrqH9bEDbp`rsp~Ht>9J zwTc}7%U-vKT%KfMVNFH%3NUb0p}NBYv`H=-FvA_e+~~6GvLpd+$k)D+3M14hb4qL7 zyhD;tgc9>Kn9{N%_yA<5f(*dFWu-lAP#O;?Rh2dXtr04jlwEI$x5v6Xi6!?jbAV$@ zkO69xKG5Jv6Y^61l~RIjviL!V)fA*3?|DOlX+k=P{}*wJ(dRFeNW^3JL~D)vsmDTj zXp4F~mCY+BB>&Uuzhc)){Fb#Y;s>kN@!Myy>oR>Z$->zNUC?YJmSKiu>*AUApZRJy zY!32x9 zlciP6aF3N$J_UHPC_tV$2j#T#dT(C5Ebs4DcQ46WZO|j|hB~XEM8Ho~1-pYQ;8s;A zuJC~W_?B*q2wwe-dZbrhU929Z@7Xp3HiZ7>o} zYEm@(I;cSq8jN!nu~q~Ug>gE|m+_>4 zlCvbeJI;#Z8cjpx45@1ZqpfG@y4UOd5?r1vMMWB4D{5Nh4U@~>A=2;Ild?wNz>>U2 z*@L(uu?OX;lj=wJJDZF&hL!7AXpYT7Amp8r4(0<<@l|{esXcIpjx4{RJ-Tg%yUv@- z&~duff1#bS{S7XEAB}T?zY`l21>%jy{y;fuD|==U1Khje2c;`LsEbtlj2?PS;-8QDPe+1%9KCT zy-@`Ai?v~bGsSE3YJNW%zl`VJ3XXzpQG?#dJmnyyffYiga82*XVMk^IOh7I;DxFA$ zU?h;>lrV!(kfs%-WXb`+EEr8R8!6W|ign>0&qemvlD*QxZcu^Q*!Xq@1yk^b|-DGp0yOQSFA4M${QgiQmAz zR0c_Ypt(c03_J13F1=ohL;&j)apm`KU z#WOyrLsg?7@NYHg4!Z0@TCIP`*-hkD*U0r=>ZZi!<>1ikJUl)0Z6242J==HVsU|*C zU1)+3(&Xy@ZHp`Y^9P?jD%4T04Tw|fKri0hPh$k!h8 zlD>|I2e0oa`Uahnu};G<5Qg_W#SwLYr70`8k*cyVw}PRnkg+e=QsRs3OBTet<2Y>~ zMKIvO@}2*?|2xY4Uh`cWJp80u;bM)n9R2(ed8%8Jngwdi7FXr+%72E%aU^q1@vD~bTBrf{KK zCcESD1W{Z-Dbo0&sEHLekQ=kp&3V)(SzCPw+C*24~~{$p|w@_&4Qv zp1q?eW}l|aJ^`hY!A`?442JK03R6u2F00@OS*3{~!EF+V%QT^^b|E5-rz9Ohh<7JV zy0TT`w4ChtxBc0PK(5+`jF(=q0k6EKS$?k_sTvkkX=!7`f&U487-9aKV6Xhb9=XQ=+PKY0 zALP?}Bu!>2DXU5}UU)?Yyz&~q4}Y$e&kDH0ObZ)t+;BDk{!N`1MhYwI?T6d>)y2)l zZQRX;Ltq0R03Eo3DlK7wpp4`bl<*bYN@VCDw^V{J*gQS8#Lb$l906SW#!+ZT!8<3d zY0ch?4TuE5c5~89i=i6`xy81DFysTm%3_8xA*>7Ku>rZXD3*~jKEt^riyh)wBQ|<6 z)=hzIR#q-PDIlXV-0*{FAQxIIbI+cZs{10rkf~vm@f1M~KKN0L<=tH!;qgwyGm`k5 zu~)(>M<$)NH%$hA39aPhF(Z-Wqo#~3hs5j6Xt)K?CbN#{r;j<&XZSmqVmV7>co7+& zErdOrw62Q~$8Upw?Lk97c?D(%h+dmNd#Q%Zb;{;=wtJZ#%`&Y!Q9dd5+g1FfuHvKQ zgxjDbCL!v2m*Drp_awUgWFfVQpoqIbt{ysF;6R_~O^omTzoUiMV|r0s2qC~ta5(k|B%n%N<`FQeMir<4X-DeN-LGM-wz<#8)? zoNwp#aC@DwXw90&V-8oUt*G(sKdB$o&g!?5)`NmQNt}+K{C}Gb{sXf~$xklLP0cGw zEXmBzQz*$S$w{?Ua?MLoaLdd|Rq#tK&&kY7RkGt!00NuhlEl1}#G(`^S25bz#WBP& z8q5pu2mtFTRw&NMFU?6&NCg^Fo>`KikXn(LT#{3%ke`>TkOwhP53D6N7HW__!eASH z6c^cX0RXjB!D_=W487+ow4OF7?R{j0(lXd#x3Wtq#j%w|%&~**v@4_kKF3b7W?P|@ zEtf=*EWM{EITf1MB`U`pX$6j)#D~!{xWL_({=QPNfP(4(8i!ISN5GE^*R}y9O@hDaa#+I zS|=aDTN&Cl9m;FPgH|b)vy7Q^>fg6_Atpv1lVhK+gB_tah|U0fQo9IoKF}uW2DSCl zozdxf^xLc9$L}9)zfKIVI~uP8=)4oA9ano9xrR%esjAMTpVm0Ef!e?8HC&LWR2l)@a#D^JB1Nv*lhoixM4ns#y_8K)!axv)@BI}cX9IVsBp{l2 z5HIKji5a_t-MHOtcDE*K{O?Y;P)Y%n_|ZeNvmZ0hy!*DXFiDY-_UNV2;H6h|+L>TR zF2{smOo>7p7F}l$0Y98B2t6V>V;nf zx-P=$R(mpz7M?8llwct(Pp_ha}UC$ey$*{3gu<48mc;Av9V3IpCzVjQ1ToHmbk~^*Fe>HORB>JylLKy zYnq^CfZgzGe^he*ik_2}=}0V*IQb{{8LDm({fml2a8f_21HOT8+p@GqFhs;sI0qwq zjoza7pU7+e0P`@o9iqp*jlba_`T*@5?QYvR^1q*gExc>HaqJ}6YY$1CYm&OV!L@D> z8|VQ=VaPUZ3y~$SB-ion=G|{*NJ*4LN^+X^4tFOMh((dZ;e5}K?CZa+m+M;h#futy z!LA%D2-sUbbu8ZsZO>&R9)unEgkNudyJ26sA7J}mWZRpm74n7W?-+ijmbEp#vlg6D z%lOKh@u6$a=iH~S)+StfK73@q`h3BLOYUzyZ^m9P0{Qbz@cYL8XUFB?xtPIQ?|gf) z4B5%i(aXb=qvK!L5WBFOaL3+9RYxqO@D;kbW43>@4 zA{AupmOI=E_-VZQvHbSt8^u%b;%0bzQcZmLeaPL}9s*bUqgEq9Bf-H3%!}_$ISv7F z0G5X!Ic>IGa*z<0qm-argx(#{7DWQ+0Rjue;?oc zwzXhkmg5kTWC8*<_q`RpqW~c0?#%LMZMJqc0SmkpvCrH1%-g!17#`3Uh;(`yVWvmo zEbd=Nxi~zR-9N6myXTNA#|yY|3=Mkdc0rP3Vzr9J6xIb;knr$nBmkB)Wr~gauM*Jj zE1$&H$IGb10(@Z7{qTIj!x6PNBR)%cCYJ=#Y%kmu(nFHxj_vz|Ki}x)N6k&Lj zn**Ppe~!^Zf*t2N>F6cIYPaUm3#}^j9B<407~2?Gm1!FC5VSP+HPCcxFM%myzX-!d z|9%Z72~_i#(Tc%_gj){I^d}Ky!5=B*!5O}&(O(Ys%nGe!^@9A`o<%EdR~vzpuGm$u zvQlTA)DeuieV;KF)@=69zPBb0?;}ZNoU7QJHfxY1U-G%<^S=u!LR3yyPP08ql zhym?+E#Hz3h8qwDyBrvgL4)niln{bqz^;u6${a;P&3J(b%z+HnPoj!C^}iM%dh95{ z5j!{QHZ*1ybHJeGx|K zNE%F`(-=E)Uk%{ILI&1~OYkWnc4q@fry;rlGkZPwRgxdT!&W|C~J&q zq9*3y1URB|x~Oo~lxCG)z6X+1EQ)(4$(C0Q3Ds;4#z@65)dYGj-in?U9zU&VM7iCLNt_nFbYZhG8aF!RGdAlr`V18)&?2YcDW9h^DbdW&vKte* zo_Y5q)%e-o;R&rd)*&o*H9G22I*r&rtTsUieuH_kf`xpiSlklDJgI5LS#YFdIYlxh z<|wIIH*Zu3iE5i|rgPg5!ZcSpjrT~0@0)5)_`-ItD3S|!*fh+7k2W+th(goX@oMn( z;GhVN7;jC)s)~dX{HSt{16(l#~X3)$Jr&d^wsEStyHmjib+=0L=m#3o?K;GnWE@5Rig*FLV&(i zwnzuA2@1%sr{jUH5(^}<9CX;VshbKmTCFV{7mN>?l+(z&p?z#KJ7glRqin-(NfB;5!fW!u|wbU7-@J~#q&uY?jOr;=lJs9&ISyxOw0I&>xJ{;Yz(hp1my>*5OXPwbK)6ke8=%G~sZ>UBn>?XU>!OHUV51 z&lqTe(^km0>$u*6%rGuA#Pg}FMLLKRLPp8KUr6$FmX9r|dK(&f z1v1154u?L;1ZIIqaQyrQ(TK;K=EL%V({T*q0v@i89Y# zgo4~rJBSX;iG9q%;u4`jb(sj zqGW#ZJ@9bEf|5F4<$P6l#N$UgxKjUC4K-nRuRebGaG|9K;8ht);R5l&_@Q)>3P!EG zqbjXcn~Ffse+r(Tv7;(Svf^5gK4>ek1^ZNhWRUBvR#voEGVqjIP|2Q6%;s+>Oy>%t z8l3hy2vua!_Yp}|n2MJq!nmwJJ=Wc7!5tgdua|)!Vd3Mw3Q9;{j&Q~ZjsFeFh zk4D3flAuqV-9a6vmC>sHW3@fELu5WIV#sw<&v&*4q+_l?Kr zNL^JbWe+Er{A&t$c1>pn>y&9pZ3U(86ww8j(tAZy#|!>{ujmQy6^XlFKlox1ZDOhH zq{~ET?SReVcByg-4)9_VZ?;RF3I?o25xMY?DfLSqGR@pDs$P|dXB1@#cjGv@Jr4c- zqtY|5DdkaIuL{asyNeJ@7w=-2xl(`XP*9o!cydLa_@P5V3oqI>r41u-C@AI(GNt$! z={`3S_S<+*mfgl{-O&r3leEfDRt`euOzblu!P`@|2Dz`LKboA0(lwRq)-+t$OlwCpXHHPFgPg+MHm;{}$ z!$yGDcIA13$%ZcfdRr9&N(4r5a+m)Ok~c9EIjrZ3Jrl0gWRw)o-5-oH*65(b8mYUj z8kU=GNE%I28jk*yan2%{jgh#_^yq6$>VNGZm;|Ov@JTty$O6Wg^NGgSqNyZ&IV~?Hxc@B4|G?xN?E$2Q&%-}$(G1z4{ zldzvld}jzIIi@F26X z;)9`qjc#{yZKJ#X7J7CIoSQM6m>8OS`)9DV1>N7?!sb>NHoM)HJDTtag|?v#jmh-3 z?+>^c=3yt2sqfq*EY$v7oPLj3Y$HoED}Z3}vaiI}Na2YaD5ibdv%DbB*A*x|Los2p3c zySod0mS`G&YuH%KP{|Pp9L?h&9NkBl8A@N%JFvbVZTNvt5Yj+j<|6i5JB^3N3;Fb_ zxicvwfD25JY22=EACzk!UP!X2$Z_vtBXH9?a9KwkoEIq?AG+KyONk=EcyCa||Ckt! zZ;giIo+E_)kyRw(?ZhlDvsxKfXmTas zPV%^%^W8sHgCW)v|0@Wx0+~}xLsW!g^9Q$VPs3|Dn?;?wxJx*9Yune}571n?`6iWV zwbx2cx&OK{cysMVQc%*3cXPddxtdwv4NKy4ITGK#X2N z*l8&9ye+D7VPc|w=SLw`V2~R|2j6QlYt@Cg%mg?c-17( zCs05JQ(NEv60Xy-QkUVCmUMrLlg})ex;D>3*Q~jjwrJnK*Fc?YAYkd0x4`~HI~NIF zvD{jY^i`#%1>9k+@hYC20%$AP|C!z{&q&XK#)(>E2&V1+geaFMcU(+ycxO;mI*n`pd z=HPyuL_r|$Z^KC8IAtE*4|t*kkH<wchctTH+ zi7pje2k+)}u+izH+xQOM7=-9ONKheD;AQq8ivtou_K38Jv?m053S@=>Oz=hG!&Fds zsATv5M#4$KYJeMzkxBfp%>F*#JNb_t_hKgHO26$US69kyhiIP0ILAauyB!%|<6EQA z(2*Hx>1Piv_!G=o@?x4#q>v$B#6AQ(j%i1;gQu8iR^)W(<|hk)lSd{XN>u*0YksGT zDHRi%0;%uz52@d+uJKi;vl(>n0&eWL8?-R=z23+8P@Gy_Y4(A4`z=;Hw zkRSwm0Um(j4@5EwC88fF6+AIrZN(vuh(Za~O;mys1}Fomi!4|qp3>YRk!Td*w9WRn z%$S}sg0oyLp2_{?d8cOe_TuttShsP0eKR~AT&&ruTOQwDPU;VQzOGvxUX5!#>-G9z zCpUlAEe}rX{I+xQyt*#Zpeog^(#4VB)NP5Srgh*cq*n0+bxR}DKhsv)C%x0`BP{eQ zeN35P^NO<0qZpw{`u3!Goe)g}{W3+(ROzuKc>^m@h@^J108Ocg)+0qDQ=_EBb;Aoy zJWc)ujcGb(qAl=te4@la7zdEjoIzi&HM7juQTCBX{zk^8S#_N)Md`eyW>dSV+p_;@ z-Jk#xr$fbRZ!tXH47jTH4S*%XGGxY&ekrB>Pcu{#v+fjhG=&Zbp31A7{M46a>UUpS z)O_k-h%%D*daj~q-L;|L??b?1iS1Hh^pmyWEs)nYKTQL5Z7{%;X;**87KTZ7M-0!{ zu3(s9ZB6!aF$zd$CE}mpU7N5y;!Nw#6u``@$#6V69SrR{RGrW@CdR}ON<{N*E=bOa zYTb2Kx`#X-giN&CYpVNZNuM7s{NIsWdCsyh9cX2Y0j9&M-mlDe6H3Kvb?iKB-q>mW z(C=@deWg$+1l_p$&>B9cbfqJe|0s*^X%?vUIX~70fxhpxj#r_4rkLi$ny=0VwJpP| zPW0M-t}$y{0R_=BfF(la`{&U!o5ncQnLAklI#8uT-Y`mi>GzCEfVwR@Rm+>{hxVws zNjx(ex)N?u za}oIJjd-n`4c<*RQw-1C|rVa)T}@nmBWsI%|M5Flujo zC<=p;P7)EBR7t8yR^-3$NXfP$CvDJfZzEt!I+EYr_ucV${CklVUa+&{!46DkANChB z!IMNU&ZIC(<};(p$dn58Vv=jTNZw+UGsO&-!mS+8Mz{Cf6uzR;WQX5s+c;tdQ>pI2 zPCHA%qHC5SI14$6(V?Jnv#d0kR5S^HC`@6Np}LVWhT~M%uVekC;lbYi@Wo4**(ESFcW`N9@K4`d!QmkcU%iBb!yz0DhdsA7=Mf5RL&=OO^y?r< zxyj0K5XoiW+~h3OK`YK6%w-rXnKtz9AR-)?TLW)qZ{f1~uHnTsxMAT5y+Ec0q_zz{ zsC8(g)6T&AH`4JJDxPrEU@~Ut4;2EVpOApG5qJXHPKCY1y$u zJP1-~V1g<`u{)3n7`AS{fxWGE;j%PslOd5+Mb^hesg&NGC>zJ$m{3OZs! zY`|71T$nanfDWD5=z41CL|K$VYVKsUd86;BREjE~ik1+paRvL#;T%9gW#~>nbSmag zW&Eq;@pltmROFL>|51Sxh7hd%GAj&-N12qL~_z?&Q{$~}n{Ep$;kWd7C=`q1bAHRh96vH8=p6Z# z%SItlbXU@x=DEDVxZ5m~wOAI}O5=oVNz;~x)}q=w38|Hcvy6!pH5$Lg`-x2oi=0L1 zD)xc2j~9&{)MhC_PPALeKLWBIkE-&qAG^Dch5oEaIEC<-^Ly_(tf;d-Da3ud;_FVl z>Ib$F*Cu!AdH(?ISzB)#w-SEWub32WB_*z za!Yb8tBwErnIU&qd($Op9?rvAAhEP0hcn-NGaQb7{ViHVjo#Cz4R{K7qYuv~BN5DI zdNP#4C>f57iair6t|y~)V7$c}?uAS-6G&lac5$Iy`|b|zxzhL^{*}DD@R;FqsWw2v z_D#gRC7W}wZ*UWzTPa-GQ5KtpR5%E~D?W$Of~&QZKKwe@$;S)*XB_<172KS=9b~jo z!F*xhdB6Yi^m+g17cinJaA!7fZG325zP^E1ub}_$7x3~`A71wRZM!rKJT5e;vM?sn zzw~JW7u^ zQ(Z)xlD7lKt3CN3;VcA^@8HyWgpB@jJNVZ7iV;?#OjQGCgw9-5Joh#TIh-JKJZ(Rc$7b|l$^$V6?J*&?!cr;d7N|TY7~|gZ&R{T- zlt}8pfG_==uX2G$&wLaxczm@W~j4NX!8 zN$sPXQ;*;i%%Bw@BBqrn^C{Ez^QWf9Y{w_~PjJ=z+=jtm05cY9o~@_n%NIB#!V9I| zC8C`}gdT_gS@!O63&Kfq9wg5IsylAioe2J5hRh~hH#wb@o8#g5Wf;uG%4LLBvc;#S zC&PFpnxEkr?t>pF_Y}j&yCISz5j;KSR5J}vqt9}x?T`ZTCJ^`gLI<_ z9&i3l^179$Qf~G$__^JIOx+UBZFrIbUB;JOp5c~?`%DJ=9L*&MjVEue-d_IadR$)X zSi6aM_H6)7-x=9Ft4=L|FaSIycyZPva8z;UE-0Nat`nVM|Lj>wWaCJ4G1Uo!786q1 zC?i9;#zeYza=R80{t#guf@$R|1l5?tm2$;MA|{R^D+ZBhcbl-}o3&IvtYSQY@a(g@ z5DaIKDe%LO`UjZC1}yUSYaMt#Gc0kRJ6$SM>J981n77a3{cH2NE)zEk9!klP`TpDB zflWhxMPRiYW}R)YcN}xN%^PX137}@jnOg(6rH0*O;J8`mT&qY<1Dwy*>AB)jhy{tw z)UEvPDO5H4Js#$%CH)|!eMQ1gKW)ie$_3j9eqtl|$MFq&{!E@;LkCUX-Gt9qI{L(&r}@(>7cRvk_iT46b5qKBdw6?&dsAmser+pN;k3Y;L5Vjz z!O7e`w)I8oXCa+e@iW%L+|_NE3vIo|pxLcUYFY78!-ap$2mab>G9)Exwy*JA2Gubv zvHBfI4F#-Gtvb5U^LU6vI}gg#8+*~!&PzgCPo)>=n1YdN>u>{8Mfa<^h%5rX8}W}y ziutW$Zr7=>_hfc!ZN;)T7}BC`ZQ*H?g|D6$pahhzefoyamU* zf|e^{F=C|g#^j-m{GM(fv+eDpD8p$=cPYJKiZUKIYmQ4+SpNig0R~FzIj?j8T}MLe zq*44NwUu4ht-8jit2I@v#X7cBvLg5DkxFaaU8&NFr(>XhL@wZJ6$rfX)5R|}Fv|_; zJ)OWMyEH>+L$o{urtKShbWEkc`F@GOnu)}GtvFl0w;JpUzpskC$md-j%E9*_j#+sG;L2?vJ zM{N~LbqzBmS7479dwz6lVxMZICt0mj=Lf1~0#Uhh)TJS6D-B90xl35JHqIZC)vC6( z?k^te?($X*=Nt_xgG9<=C3be`qJuV-t3n%PSVbP3xaR_h4jWTHshG=P!89brV;A1L zwhc*l^Ds$dxeU{)u9KRt8v40B;-6C;C2QXADZ zLT%5r+{eWGFNG4rqK|7jd0nT7yPr_7Qjq^seO{~!T#GW4a!Ep&IZhtI>Yl1R8P$j@ zH+o6z7o?L6i|t+&+#}}Oes3`q9N+crSRKEi_nS`5I)xc@I}WP!hXNu`XPd+6WAfWU zRjoaZLd>3{We}zOsdSsqTxXf+w7@hQ;v8xD7$}hI+9SK#A1>TI6D{j*IeFU;wwbH( zdsHPbr8=>;@tja4*Fnxlb&(kq+sT0ay{z$H?N-}v;z$sE=PPPQtS|{+63r&7Nyug< zOD_wnif0(oiWgYh&}l z_ou?nl5s0g3*V)Q*x2}`I{k5^#{PmCi}wy9;4S-L;nUzxxK4j(@Ny3BB6viPInym< zn2Pr^9?Iyr)33Z$g03`)<_7GH!vtf1%h13*HU$i1x&eY2(=5Q^TmOp$r%T5IeBlvi zhJVPrA7#%@e^SjLV#Yv!@MZspLV{St5npg=O_}+0Z{>TXQlTQ8L+IMU!fm3Z0VaWI z%^pEbz^Xa2hDH$hhZ_s`j4-W&NFXN?CW`cT085-x?SN8{Y|(fB<7A8+!X%M_C9+U; zLeXB`J^r2s<5fiPhNI8@Zf`XFcu_w}i+=KbbYyY+vu65Q1>6{()o!Ti2HelEWQFF% z)`aWBwTA&Hq)H@$@$gwcF&cgGj7Q=eswiAw-0g6ASjJq)DVTssxdL0F2x;NjRW%lM z?^`?zgc2(w96uxg{tgnYQOdMhL|8&@c@cz505KYfhll{xwDXswyHg^3Rk=8&*ZTn} zja6%9iNyrGRbcaEB4pU(4;JOV>Rn&;x}(eC&2~=Ivtp>$nbgrtzeop zRGBP>sm8SVD35=t7a zN@}{2iiKP<9X10Ml7U89P8^SlzyXl7&(^?b9Bx7T>m$m(M)zIzNTA=W#NL#yYKyxpZEkxaFT1?>ZE zy=qGA{rDWbNV3^`g<9v5LBU>*TPCK^G|zOx*cdal4op9?LX&h5tPMZ@*d$(F zAn2Bn(8(OK-TFk+m3lvi;`ai)lX7oK}v^nZti7!m|4@XX~lF>kfaGC zac<2Xv-_+vXneb+8|==hTgz_?^KvmN;u59W-igI9DoSr_x8JZ!{SAy|D7aa_oPSH) zwoOL@#orm8H%QkQzAE^>t$CkjXbCTqlCsBv_XS*sNXKY^6`VHkSh(ik5G7Mtmo#BS z0L6jsx4Lpqi$C4X$+`aA`f^n5M@+o_1j3t0e_n0VfL7GrtrpQ(Fpr~?%N3WP&9{yQ zy678jr@yQ@2!H&<;{4@|H;-P+Am8_=6f+H~ z%0u|Ecdq;Qh6N9E;I(YXVP@Teg|?}djUBwzUMqBDVic>BSoFyxHzq!5c)S(M#(iKf zh8-c045q!>@3Q$IVjgw{VXo|k{cre-wNfsmTd=zu&W492#diM_I$>#%~%);*wd|t;qVKkqs>%p2oaI>sn zWfY@uq4Nn$z@#C}WxBgq&Z>gK$Q?lHZ~d<4At|T6!#ds4c7qs#ypgCJp%S-jAiig*DZkE#3OPukAc3n{yCYc7d3~E*;lNBhj zFVmnhp6%8zMM+HIf!Kq6IY6fR3S@^HzL!w0dHuo@D1NK^3c9z<;ZAiZhhA3xwyuAY zRO}=1Z|io(=s^vGwu+!7X_Y12aRy;KJ$(9rKbemWZ2z8#p88fBJawhxAKZdfMxK=G zFNUg*kQ4rSWae-E@a`Gr-1QQaJ#rIO@BhQ! zybc)$3ivC&j=|IrEj4MFpiskMf-~s&0WaL&2UKj2n!RwJ{Q5!J&EkD=(`?R%SfmS~ zxd#`#&#D}%&W`1iR=9IR6<-lWy$9>NV?FJR8=>VO3fQBx#hB`Raa%q|)eiVmzN9~| z;&?pobh7~W5Isffa@^K#|0-T~nYQRt@MpTfbxLo8sqUYHwg2HwCim^6PJH&>et}n$CrSqQ zK6!)FR|e95zBg`|zhyWZyS!TXXD6m>R%}DmT&iZZ;~j9V^YYDQ9B#1* zeTqw|U!u6=eEZ7e%1$o0G13j-@9*zS=!s<;v+%eP(5gK^ko%L5dGbX<0o$!*T%m>ENcNhzAHw*;@cK1qUS*%ZrgoVKxdUKh z6fG}mn+PqMhW(`^7|BO4IZ++06yM_a7580=2l33VR-;#uWRzw2iiJuJXFv_Rr+owG zXW)20coisAxiTmgO!i{N_2Z6PG)eJcmeFBKPah|FgsGj5W5$A;`_Ao$Eq%NMc>1_b z5#w|=5?~bsauCJK`}5l)USiyKP8F}%Eo?I3)h-H`D>4tOk>q^jbOXVW$x`U{){i|8 zmzNC5?UyILQN*EimXs9kFaHQ{WP>;2K*x!P^A8B0xax1P|53!z>~3ozc7ubLiwVsc z=Q*%+(e%NoN~ap_HBo)XYz1QbRp^hR7S)~BE1XOP-R^Xvfm>%RVgvkHRB+!iLmGXb zSUpLQ>rb`imU!<*J;!6y*5r4YF6)k9Zn>K8<}BY}-!(Zi3SW1gPVt9^i}pGs0d$qM z5JY%Nk3wmQ27H9>eBe}eY|@!>IdUjRU@cX>exTRE*4b&T*O(FDgqruOe6)IA^`Kkh z6x&1rw^}K65V6vZe}G;!s*Q1C;T7C!(etU;4}vEm`Oopbsj#RD7kv7XJTD><8B(id zu_p&7Dr)t|oV{NM{BJJk;<-)s=c+s(Bd~;WS8bVpt=3VcZcsblR4H(W(^90h35Bml z=%Dz`7X^=o^zBg5+S8MhGD?0{MVXihT0DQ#GhhFjEt0wes=N9m z!s*dx@gF71gZ0H!ukQWwUbnL*MGHH&y`ftC58@c!g6BaSXw&$hUk)C6{GWiVr5neE z-nh`EObG<59lx0qo^e-{)#WyN8LqP~1~;180o7v!%$Z`ZW_J|xVfvI--w~CKkn)Q9 zlxBb5tQ$wF6d-Hkk{zijkO_49Q$L0Bth_sXTtZaV3H{M*s@vkYj0l2lJD2bGplCpw zL|a{$2DPXl0~1(Vs=HeC?;vB)W=Q`L$0s&Nxw3_o|Rj@Qdp{1no~@yJj8Y1Nne`diE&9>xFQ>HZ60 z+I~WqAO`HL4ws~|%YbR7Ga&E(LYNs0F&L;i$sJD-L$MpDlJh3Xmp3@gj>^CLb6L|2*=;*Q@;6; zEVs>&O`Ftwu(3O^5Ey3}!j2sb&Ep4_Z2!%N%=PwW5Bx=k^Y;Z!*AVHzL-3wqKLUoa zQ;Cd`deE8GaYiluB1)j04UNpK@72!BBb3?s8Rwp?34w7j;ext1Ki_2Z{s8B(H=Axk z@`zMGjn^rz5BZknCl+l!YtRsd%VF3fauJzAk-GM=go#pz21Ygpzj+2bEVTn>u}BwR z+%!JXJM#;gdk`X^#lCXE!DRSnrr_;1l4X?Ppk)tTerynq#r zijXE2!BR3(Yc(jruN$mFIUI;}egQEk*!NvhOqn@g)FLoi#SSLNhV^wtSXubkP%){J zqc}oZpk7F7c>LE+Tj;`ok3lnHT_DMdbjyg&05|nl=2Lw##QtjCq{fX;OyxH-tKX6L zaE7Yfeoyw1M-yw^p-XN`$wKXbQ``2EGqf4+6~X0fez3$k7O-x2ul4GXmS{#OQrOQ@ zK)>JVoTc$GZHzeS>RL2b_a#r1ULaanG+O<$o4$^BeV_1?ZeGQOSKeaQoxc%Gh;H%) zUq1c5w$!PxGs$L_EyDoDQprbJoc6dhPmPyQG$J& zFFJ;92rA3s$>;0obGhx4q|CNMSr?*s=_>8HZTJ%kj#@>Vl62c_flzQ%zY6s*k>1St zgN5F@q|K=(=x~=o;&Q`$Ypk?VacqIe(40j5E?^sz+@%x{? zvy)t0u4d;jlr>l&6uv*z$9P6Ym07avVkhfvirm(;=Yl^QLuj-^e)r*O@oq(rZRTd_ z@y>OFo2Xm2y+YrxX5&n$Vv4K;-NaKABGWG~+=S@4j&hXzM#g-DAvk<(-9C8LXzu8~ zlwjrT{ASVqiFP#gT-LeJe2+CYbB!P+p%diWx2UB!QWosYQHH>H-seu4#?l%gNIl89 zQ+|xO*Qpx zGry$n@>cuE>BP8M@9}*$dv2XT5Je^N!gux>X*ZNjCq^+ITCjz3Qd`Lk#g9a;kb;Fn zGFycYodT0@%86t$yhLre+;@Gb_cv%?-6g+InTi;S(LEZ_T~Db!*3NqceAjrr!Bsw? zWS21PQ$PWO-ON3npuIZ=gXf(59$V+F)71j4(8=p)3YCI=mu~5*p8twW?tib)?d!m< z(XX!Qz4*-Q=_vo}4Q!B-@Kw99e?!24b zF=NA!{9AMdvn=mTGK2<+^UUEgbRmwY{jfVO7j{hTpdH}9jU=DgaDBe_xH|hK9oZxE ziZ2YJ2PvS1T4tK~1y%4=t6ps-6BB=O4pysCXh_8_(i++deigJwTY``xaf_G;!;vn&zqLU3n)hmt+NXz`f;E&NDDCEvACTx34 z?2X@IFp~cQ^!mzzNobQzWNwB1tk*eS8< zY}s1bTMz(i?9f4($t1LmYC@zHD3%#sSILAnDWHV~i9>gkgkj6^f3=CgvH8quMngd# zB<k!3qX^1qaGtFBRu%L_Q5vx+pdi8MnWJQD55Hh&ffl0=m+U9-JBY3EpNNlbnR+ z;qOwH z!0TX8e8+bm1puHf<+m@F_ zS)W!1G&6vOPV`$X5_v{&XrB=F3l7+k7I@U|bH21l^N^c%3dP5X#6~SW zySP>=j}|N0I)6`V_T@kbw#99IlrRnIpt_lgpW|RzxmaGu--yz>GZLv zYe0C%K|=Sq0naz2cXhVcBVf7n8EpYtbTU34U1XKWN`5BF$8_;{juyUeHA-J8s5tp^ zsQqT3K6WbfwD0@*pGM^INdot$F}x$4nUz`5n;D(;=Z(k!ymkp9$fafPaY|H-?58Sq z?%3*QR8U#mgt&|8k9sV>k|3~vmoUC#U^&1D+*pPr(mIXk4E7y^Efa@PX0s8I%aNe7 zsn7qm$eQ#t5A|0`CZ;vSB>po}R-ZJ8UwDM};ZkyGR?*(*$S2rU^GKBkGNC}l9}~5- z=q~=VD>i>ASmlLxc>bU*gx|#`Ap(J>W)P4Ks47wpscO>qk^2_c8Vm2xZvhu(fF1o$ zA3w~O+)u3*)31*h0B`b=P?3+lfCl~=ELyZup$c`aqyh(sd-A-80QP45SaW>w>0?XJ z8_wziif*GwZfQzGMN%jPTRZb?lE@6+J}*EwOu;)Zd(gGYJ8$iC*K66UDzmPQIghhE zdaIt<+rE&LHIFsF&iWf<>qn2S(~10(;v0UZ0JWj<-U_((BH)eM$E?RSDxqSsZ1*CrqzxI7|icF_m_r_2c0^8{qfwU*}df z8D?RVoFsiZJN|lmJlO4#m?@LBh^mLX;3u5L4kV0|m!v4yosQs8m95NrnuR#+BbfU< zJc-D8nApiMjKVlLq0-`~xUM+D#^zxloh9FLrEe66GA1h93K})V7i#@~U7rVo`-6e}L%&i7_5QstU^PMhu(%{e_=D{Ht z*u4wN*K}kqPc=`3KPLx6gMr}<6kD>EV+PAXuFF*o2So4JVPdn%gTgnfB2!r2EKH(s z_mqRh<8nt4^M{-hLi13Xfj>nSMx=89pp1qKw$`%x3%HtdWzLCUaV>3JAGM{pZhwx2 zvj8aq{Az|49FIJ@Z zGei73wpx>6k{f(}Tm|Bz7`AKXa2fWJfIY|Y&tBT?y*u>H#KZ6^qlWqZMN53h43=gP zU~pemkbt?SB#b_j3Cz?UJtoZ~9p-MrklbgMogSvMj~;ed0~{Be!;3b3M-V)Jh$c)o zX;$%8OU(lqy1kp}Ya6M$Rv_fiDs%(GQW7#rBT$ONS{d z=$Hk7aZ#r3icIABvU|CGdb+ds;rhD#95;GtW920r#FgbOLyhNYJ)wT(-KZ(evbHH; zHl5s!!pMTZnl!E+G>+E{=`9o&K7?G}J&ifT&l_9t4So-60Km!`u0jK?ij0oS+p-PD z@RM5OGnCz7dCjQ+Oiukr80UwrD4~YmB?Jh}JjCnH&!?)DY^wAEx|g z{(bZ4USG5}O;A2r*gSf?6_W8{;ax5t4z`N@=)rdyGJj`!`cT!u;n!92lmoD{8@}W9-Gf>gYzae}S==+5nd*D|z7MLb~xv z2V&u9aWOXFNHiT4(3hrZTuW5v3*X8Sn6)3|LUYN+XxBBMSl$BscNOI`mKK~yio^o9 z*Ts^5)(~z4X`e{?&@##^y)ra4J|*z8o40CLQz=yCZPB9c6>JQz;=~R)AXDS-;nF`u z)zJ$nUWx+{OA1iTj3$vOOR1`523#FkupqaHUe1P21>Qu8Vno7UTRn()g{}u5xYY`8 zUqE#DVCb%_%*w*{sW`omYEXMgaH>%1LtiYTf=WM5`Wos*2A{kYc4G| zVJm$mb+h9O(z(0Y#Bwspt38#CY_q<)+&!~8a$TxlUj_=hIZRwf_$flm6evk|oz;0`s>4$%2 zxAXD$ytOHsve0&vw3&KmZIa(RBsqLIw%M3RQd?<5!4(&_RH;VxI7U^X%b;B_4CM;am4d1PHxpfUebfX3s6*QXhL4TII@iZ;4FTAKlt zAZr0jYctz~gqd4R?W#&|k-L%uCJ=2}xeeJ%Sl&Ts+u5kwe(;aVgn)q%Ng{rDIa0Ef z!aOm>$wF_L<5M&hZ0wd5UujD;iH+*5XB^FDyEav0Um7Z(a+3*x*z7XY>VElMD}CDo;!c4Es|CNj ztPDm&Sx@+GN3zq)RolMQkHRdc9k=CC#46WS(cpG%`_0d63pzNL){)s(n20G57$k@S z7n1~MmW^xXg;M;Bw`5nh&UZLgOG~oTu@w%%oP6$eq1_NXU&bn2Dvs%&M9i=Et`g=% zaGmaTSTUfgJJ&ON%qmtjjfo%km^M-In-@!e&Ym64EFv^58?6611&lj^y#g0Wcr+qI zi_y}VNu*J@cncHfzL7vmmdANmSfd+MxmEY(?|*YQm*jssX50bzmFPKwD3AV# z0Gwkp9U)c?@PbESkD;f*0H{-^n#Q#w!vj)Qjiwxco(RXw3$arc7^w2Q@%W7$6?$`d zqlEgm-q;tkgF|Uudqc-^$Np(YQN(Z-XMVG1ZSZPoEv;pL_s)iIZR79icZp3KzHWuK zJYpwp--4(`slgAV7yjTwKNi98w%0}Jy1>^&)XMmjUnfl48IHK?ACckPOTkV+S85XW z&;5!yC71<)yqMJ^Ezppkcm9ux`qk13+?hHE_IL}^InQ74xk+;WIVt{QmzW?wwe{N2 zsrFu&G17Wbi7l8~2Vcrggg1R}``OunBTo}go8Ha5%SO!A2uB~3a?0+;I@~bK)TCN; zv@7=(hpSMg7PfQ678ne9N@;8JmutKZn>?i)nmj3!29CneFBAZCyE;1_0o5JNSrR?X zfg|R(-k!WIuNv$L;`qc4;4c)=S~#>R8joU(S6Q#tR=v+RQ<*0nKxP`p)<`VO_^1*rtM@B`8Kx8tMp!l>Ff({CbhbDK%9%(Q0;ZLr z#zBKP#sC2k!jQzFiMPk8#o6!)*Sisi#nQVuE-j{#EV} z@*wJHY@ULBq$>2W%how^FBq|x6d`C_^t8zaUdY~~k=a@HoNRoL@OcurMl6?{fAF=t zi0Zg9bI}Ws8N`;|Lg}#a5(@|Fd)J#7wEt4tDK6X6$|~Z8X?odyc@bo`1c7Kmk;f zc4-N5W4Zv8$~ye^6X$fhT6aAgL}5#h2#}rWz2t&^3D#t{H$~?izsA%=wmZu_Fd19q z59tHFzdyNNR%eTZaLu@`PW?0p6f(GOk;Vp@>arMX^EO`VtdPp_Y^_TMq+V{>A1EX& z-LuQQwm#Q)EGy^hz1}%`7ZHU_Rw#;5g8db*%Y}ErztTE0Y&*_wpnWvv>iucU1h3XM z7^}I-D`-jbBi??vqy{v)DhWyG)672kZ#LcPJA3RWsK>^tf6?T|cuZtlBIG<`l#0#V z$7DH0no}aVbnyMBBr|?Cn~u;zu|~R1l*K*4 z`+8#MPIdEn_H|p|5><0qdWuoKEe8HoN7p{%pYyw04&a|jS&#J_eiuNOFMfny zg>f=|g~u>{futq@{)6I$Tzf{5A6N7iBUOUYs5#bjsG_g0t0&ml(*BXB!&Ca)XgN8<5A3y{08sT^S6;PN3T$)T;o*Bo8{JapOvRfpC54>GPQnN{3Ru=ar5hvK@i94-1` zYBPniyzGSe-mId)=Dl&XF4NoU5B8`{%Y@EdUQ7paC+RD=t%*Fcok@yDg^*#jPlEn_ zveTo*(j#8$N2J#~;gaTT9f!fpmr9}!P_L@q54;i0cc;GN4lFXzJ%bE_oOlpZ$N-92 z&zmw<=X${niT%U9J1((M5`y`vlCbD76DVN;xOr0 zg_4skJgB3AC7nu;RpW*}y|{b({YK~xKm)4G<0I@EcL8KN>P}QJBmozVD7Enqm?GS= zkY}BqB`lxOSb#CL{)#?Xix42wDLk&ROVQM5bUBXF1TPkJtOQvSG`eeAD%yp!?n6tIr~SFgaQ~+oM`fIr1vYrN`^^emH8CN#)1E zy|h{g{h3c@rJf3(0jvi<>r`sC6CW9*;Gcb{M8ch6jKe+Bx#veiTDF0YNM*FK%l5Vp zbV-fay$FeSVQj}pHJ-vHV{PJ{_fI&M^>Xwh{64C>@s>0e=?UR0Wq9}J)cOAyo<4sJ zPZe`s5@to~47^U69kQq}kyfPI-qy-5?;ZImcHrU&N*5!3`8`S~!(9xCJ$Gr)J&)kq z;Wo<+drcD}+N&{HY8`Nb;(I+L#WaiI8r^?+w#vFW){mejJ!@*bT@0boB7jc%(x*BZ z;3~=v=_PT0Mm}5z21prXJXEnLFNmVn@-g(?D5;%d)onY^aJR_G=E1WhUW&@2OJ?J_ z|I!qOjIN0AJyQ!>Y%MYVm00!|Zz)d(1ZM}^YO~rWgc~B2wnO)*J1Wce#V$c zeO%tt1uL{B4cZU==e_cTS%g)Td+7U(9&t5bR&I?MQby+_Q^Fx`1tYS!?Q6B@#?-Qv zrgE|ReXSr*C&h+tJylBrufB#t7@PuDQ)zvla0#Dl{l^2D3~n>hW~%i-{OO-*x4g!h z^@dnB9@jxEhW^a6voC}XriW$nW3J3T_8C8WX$WVC5m-t=i;cmPT^eSzyleY;Z4u#e z5Lq8g6~bmkR?BQ0BPaltF}0^ZCA3Vu6N=$XB7zDII|Ruj6%Jlu_+((J34a^z6sJ7`x=I93IjE{m)lnh zW3e?HNhZD}H=6b9dI1FYg%lzcvg4ey_ubEn9Am_toMy^a2*%ckoZ=t5l__61xe_?+ zL6TK{HWPe-pRq|Mifl9ozs@XX^IzM`X0PVBZbcbs6HXPrit!HsZCAy|rV%wA}qP*@7{Bl%;j_Lfsu6b}rOhyw_y zdk}M(ZsP1@U*0d}+?#5D>+Jyc-jRtZ@p=52pAz;E?;^|CN?IKY%5+4GKNP1Le)N|O7iMBQ9ZlKX+^CF*)kNM7k-5;b2@oVKk zbRnx%`hBp<8nl%0MwXcVgytJ`ZRk(q{>Qd@L8I9MzTjGXY|Tlsl}d|Ch^)gV(+gjt zBkeiVm9;c%t5%wx-zCcb5=)ggjjLjbuY}1f^BSAUx^jDSv;#l(G@#A)OOAh~qmVv? z-?#(`G3|B4>F?9$2>KNJnqu`zpxX!LB>RAJXw-viTd~d2@YB-!3ysd!ywKVjwU6*u zAAtMP+xf0b97~5diL* zl{l1$0B0%BQwpc&0S5DwwAGT^1&VfIJ1L0L0rYv0gm1T!oK{zx0!iZ^-(rv!bJ*=_iD~BNWX6>vOh-YhFksSh@$W-NC9TZw{>-G-Wj$pSI`S`+#$l)}&==%vX>s`N% z^Am!+P0X8;X}_{acj0zLCj8tzU0Jui;I%_1iF`M zi%63|ayajxr*ha2v6i=AN)84&vSyh1d6d6$lVtvT-s9J=X#06+($970|2=MHMjggd z$t>BmU3-dyd6GSM&UeXHVZ;RQ!3EDGxA^$nB&g0%}FJFyCcMA>$X!hHPVdrfsG8%_r^&u*;RJwk&P4k zic_P2!scCFTs!4oiYGzwZ1o=^xzN5!io!0j7>`kx7?WVbSk{=4ejES~Osoe0kptx3Og zWHR}=mb$wj6b3>CG41Zr#;FE%V(pdWO~*V#kC5M`RdbrypXgY#Y0?^C#YlpW4^tk3P`84qWomTL;ku=VYd4DZ`=K^SBDe(IYPyI)jCRrPlO8KUq?>(XP2#lqm0ffw*aC1N9%@l3)Z1o)G^(!}!=@O5)76y{#*CmUknihT{65 zYH{Qc6L+4?hYrFvxGQuUaU1eQ*9XS}pG{ViI7$&U`zCW(rSO-ZzohIQa(+ojm&cb; zXLNwHQ?&nrVNCG%jqB}}sjS;`s;4t>ZL-XNGl=o)Pc#z+ueBhLg)T+( zALAMZKV5Xm#1h1Y)Wk49ouB*S!{D-6A?*_qOS0$3Q9cEFR5#893oUwJYTMAp%RDmT zlT0w#Dd-j3K9oagizQBfY&!A_BYRq+q4vYk+S?bgj@h|ktu)x*<747}MVzR<7GM<` z4d_3)Hzp!k>V$>#UEWUFlt3jo-s9Y*9Sd z9xT%@lQh(IGj;5Al_VO)8BTa%SLLg!Bd$uEiwj||7{jBP42!3fxt>L` z9Ij}U%AxG(pO42j;q!4JuXf0cTfy-&u%eEJ;BjOrP&^7hreICBr6ct=zRkr-e&UBa zb8Ipp(>9SNCN8MD9x@&&oMwRl7=Og58!MA81M1onW~JMNWOtiNUeLZ%m+cXpd=>FM zm*Ed{??NRAHxe8?u)}_Nj4b;jd096tiHZ+qPEnK9tk zOZ+2EwsZFz@sIB!_5Xe0Do(2iI@d@fa*qFo5M&)Qer&U05UozB9myWv!p-WqP|(g1 ze!O=-UWF#xx3r!Dt|uaSoG$8>cXt+$^EeO~NRNv-u5a}-kOd{BIUTqsEPY#tYxV5E zZV?>pz{k!6Qx>rN;hHWxnm2Tc`+-28kRu1#s=M1dj!k%YZr#NWkG1heGK^sx2*J@8 zE^c1fYxxaMPcQ^r-Q)B6enIq8sPR@&QyS)Cwd!hJ7+y)Sy``Hs3|W zJ?nB63D}>E3Z$k!ej()`4H_gg3Fu^2%?RjX=I8!@qS&b`J?p{~u{8e6|5ULQDyXuo zg_&;1KV2Zl#u?2|*FxqXyzRqSqDa;afe*`Z5CE^!Gtr*JH-uvlzeKa@MI7rrGX=Lt z1p-?xS}lKP?C-5{S@l`rhBIh`$arcUz=Smg{&F=DXJg|v*b#7o49+Yq4lbl(fo?fZ znjiwzNFG#ytz#GqaCZHLC(p03gGEN|ld|M7pC!nkcAQN8H@HDuPXwH}tWhO7tESYX z1}@h8#_Vg*G2T7J0k>TrAE+(EOo1(B82T~@D8kN*cVAYQoDC!)U$g7 zkMp<>SB#*itW0&6Dgc8%=vsGf82(z76fBnGl01ECgX*0rt>lJgLcNG1Pd6tnoA^j7 zMf_**fy{IZ`71SOxvW=h3WW;V%Vp5uy&~>-i-_)LXu|IemIv^o zRml5UzINH;K>C`gU+t8Fl#BqFIZIJGz)v{Ym3M}OJ*ZF&LwN%$#2iRFgY-`LUrYN9 zVhxi6d~3{sboBYxechfLxn9Y$MA_ZFyCF8_zIhS8upc~`a4Ll)q&XD)8OZJll%7eC zzANGr%;nrWuX_*+P9g9T8Bjui5 zGC#M!8KdV1_f{qyV2BgSC03`#Z3ZoTsZ*=Y+PBKWYLfl2(s-askV6yVC=??YEkP1r zMODD4ij$W)xCAm3Q1OomWkCv*)P@B9{(VaZ;%}lQ3Jr+8PFU0qQLoEi0_CF5xXz1J+F5%QPjksOSm`?z;C>JL zMg6f_%!EaiM3tmS6Ip`mQzDQu?NxE4+pGnf5@4aMF4_+zvGv2zZ9uX8RU+U;um++v zsGOo4KRQNMPhFKulDAu^H6)z;W`Ru`t-KhWY@^DT4qT}8ZBr+%wxJi z?QUY3bD_~t-dswWC!)%>gjK9;?%~O`Y$F|&EuHr2NaA}to`~ROxq;Y>Z{LK-;+Q2i zb$K%EcDvtKfGXO@j!rscH}wq31KXoPVE~JS?Pf`t?h0YfnXp2BnxMo}hloimo~x>X z%vr5?pW4K+Pv4r);uw{g^E7v;*O1wsbk^%3=qmHUp#O`MZ-7yaii?X5qtLr7t7O4S z54nbvp08LMm$rlA%pz3=aEbg?GM0+qKz3K zelES_)ufumn$m57Qk>A%&}oRzdPV^F7&_G8^S)*jn5ujt&5->pLNV=6i1?t zbkZUS8P;0R@$CwwKH7YOW?3T7C%$-?iC93LL8qfd>`PX>eO zp8|55f{wvymB*5MrnzX#lm?6FqOY7eq?4tx0Jk>GhkNurc;gfBQ_)n|5^FC=1w;j$ zzxs^wJ<`UlhQ4Tae1Ap3_$8aW!~I&!7GrzE+Hw?ksGD72?w8)12(frzr-`=88kBhQ z$L=@MP|2fTbe+!IKDe8`zBibB`9?(5=X3GuiE2XjX77@W;?*2meDy(F%(stM>gt%< z%eERMz$f(gzBzgMXRwOSVdN0S`_zQhJa~F9^R(rD@#5fbwBzSK-N!GmU0T=d0j4=L zp%87H_)CDND>B-On-8z_o)pI%1OA@W!c1aVi-#{u!V}mZH3In;ojvT+#~I|4@`p~4 zf&hyb5}%;K4Ha()U}%C+YPxf-@OXZC%>CYitKCh=*zg}R*2f%Vx0Fq-_g<0;X)?C_aPWKh-Q&- z#vo7PS%6lYk{G~Kl+A(N(-wz9jj+T3)klF~`%MK*#kFGrCJB_t7=Q8|?F{8%n#_Xz zPZfI(MtB0E`{8w`h?$QfB+#!q&wZubVJGj)X6OFjWA^>jc{QOyKYZ(&FUj)f#yqmZ z*b$udi$`)PY2L9e!!L=R%jQEg^;`C}@2aEzw5*3ec~f9bl3k-nNEG4f={FyN zcS#^=H|TW4j7=ouNPt-PEipITJyCci1`JyGdF*@+FC_d3X&j8k)1i;pTkJotv4~vp z4o0ZHp!R?D?e6J70d9LkcbAu_V-A=;sz8*!a-#R_xM>6LL=w9I&es**N8$A8F&7X$^D!*ueV zt6v_I4>*A^&%-chxQ`W89DFU1C9AYEKsg<8%(ail=r73{f%nPbc$B%2RRB5%qtIW_ zQVQy+K{_EZRXT3U--Xm_MliM#Uh(I`zs;r>B>JiscF^SyTtVI*DVZJRa?T#>CH+L0 zAd;G`QZ{dLFhLPJ|AAs4!XY=~80Ry2yf2YK_%yd;W(gT$aG;JfI1~Qc-$xbz&M-V< ztD7<+{bXbmsjY^(_PDD1V?+dAjv9`o%Q3yHppVs4h)FWt>!Dm|tFz#Mx)Haa#jQX` z0h;R@_JlPLoXqlUPX}&W@B3qawEMoAv)tnNouius|5T$x z^)?8qQyU(+lK>1#uif1W-rQRs;FRAYLnkW~N!RcksOLUM1{Mw7;ZN9a?gJ@MU!}f-jz^h$%1DHyU4x#v6^)QW@MvEY(nFQ|m z1(`(Ksv(&8E0_?4d~$*`l=Yw(>L8ei-?c0WEr&sog3Nzli;VCjA$P_ct7TW9K?I>I zizwJZdB*Ie7{(2%BFF;K257`qm;G8R!i+%Y413f2P-GR}aO%MVFeOYyI{%`VjJ@*f?85l zbPfi;n~z{vGBuwg3g}s|c+Ol_pp<{gE^8dyYd~;lJnn>`^qyN5iqNcs=b#DsPQuhL z22;9ikSAas78zUvmSuJCAr2b33Pxzu)J1|HtK|rU)}qCLS5wmR-+i zFPxLogUZXU@O<%Dtx;ac4bqh7BFO7VdWGYR3(jL%|Fp&jVylGZL`{W|K?x>thh3$K zZFw`-I3@=o-B4{GQwp(^ZJ-jyZj0ohDv}HpB2k=DW9jBFiDZak-CQ zM&l%TC`8WK^2{JK&NRR*NpSO-I@CG3kEB=D(XfNF)zb`D}q#dr0T zZP47V&d$d1x0fM~cph)Kd2z6i_567ZA}4RxI>a3->m#>sPiu(IZozEe30O9}5l=hY zxlgT~v%L*OZLjRqZ6W@g`x`GJXY)_s=6k1Rc|Vh|^E*uZ z#Kq=VPN5bTtGHTA#L&o;l{$YMSiY#`r+kQ@Dz3(_gPHnx{C_(=y&ay*L=BwH^(o>? zac5u3By*z?xRw{%+A_NNeYQp+uHsiqE@)7GHMG3wg5oX_&qN-uK-}(*#53842^=KI zj3a4s$=T+!m4K?p^`M-j1HH1)%ZJ|MkTm}u^=QYkEnuZPN@7F?H@CG`!q_w+L``$;1QkRiACzBki2-(jk&08+%a{WC?599mF;OW(g>hw=ftOZ(O8I#d8UG8f zKv2I72U_MA#dtoGW-<*hHJ4SiQCom6Xoy*R-E4&EHTN>aX!Is3>uQJ*pj9ZXgB3=w zSF*&+<#n^hs7GIm44)>ejDYsA%oMHlr+R#PQ$9_v)h?@Ov5gDx@pD4>OM_Rd*W?hV z9TPlRMXusgr}`dIn`XxC6m%juigUz-D(*QJ+>_TsKr})>Cq@AO;Tn=(AFHbXl%1ddwvlQ)ab&iSl5gFqNUy>zmQC^5Kob9I!!bjdTMlGGTI>3^PHBLzBILx0P0uG9W3Ww+VIV07f zBF%z72Yhod)6pk!DWwx-u4DMu(yr>61_G-pD@pi=W*U@Ik(7 zWYd1*CJj{*xm_IV#W#pjvF30CSGe{OsD3&{r#2v z$oMECE%d$q5kc#*cMMYA1}Pt-al*W*HQV#(R+>g4Eyq+iFQ6}G4R{W%$-U1w`Sx^8 z1aH8M(uJXVM8-~q6kkGY_0`Vb(eLYdJeJhc?Ofm8JnXJ*>Yx6^+96PG%xYcfe#mNF z-3v+<6d&*Tvw_?Mba}7mJSnm}lMH%cw&C)NB$$_=Hu7?q^IuA|Hzpi=Yb}UYl1HKJ2#V_PXOz;#~IuI)z?^ztV4I zCJI+vnl-Aku2%33G5eM7+L;fq##=s5KXJ3loE5aXY3JS>=Rq;8CBe5l7!;7-$zW*riB&biXov(ZW+pbGTX4^Ks=hVWekqmP-r+I z&cr4DROkpK{h(^#x1(7(78(A~lt=V8zy-S!@fk?em#G)6!A1A#zPNY)`0+N~wGsc? zXLYQJq>6@oewqHPjRfeSaLt>V9NV?JhviF=*S8&UHh_n&ksUR_=r@@iM|Xs+`4 z^U5}9gJ>85`z%lK0tP{*crzEYkyGeRCY;j>!WIucL+Jc*HA!XSCu}jTL_*#>A66fk zyKabp26{1kAI7}yj|n>j#0bP75FF2=xx;5=rWvD*n9h!pA8a>=$qb4FV|`|rsm&?S zI_jtH<`rH%OVW+lRvWggtSHI*9g1}A(4`(dsK+PPrkErIpYN_Ew&qHB!Ec3^QtA>i zW{A!2xbs_mzq#v4jw@7~j&kgw^v&mPL+SZhV+6C|%puyWSkaiSSIIH@28k5_Yuvrs z;Q|3_r3?bG^Fe=B^YS3l)A8D{Z2c8!PV=iG12&YC-B+`g*Qv!?s8)jqx#F|7PxB(1 z;nkUpaytz-$L5c& zHwhhF3hklggq)9`sdV7Yg5havs|ZtYhxCE-#=4DW6(yLL#Vj^%`pIBPRe#2~3uqi9 zi?_m<(dQ5PGm;Bga|5-^a7@VoW$RDlY*R*=EO-yQ#{u+>$~h<^SXP90#<|i=g1|7< zH7yGj0jV8nqFKx(QFXCm-J?nYfXt16s<&u3K)DKz6a+*>#~&)n>q5Bt>Z@tU28C|p z7ST3U8|GYnw|WLBKo_>EvWf|bWX%eW&sAcnc_$UO%LSxUkcE-UE=*DuQ9nvmHWHQH zZB|yyD|bA3-#vE*d4f9Ib7dA<7T`Orm2zO@Kht#T>Cg3TT_NkBJ>Pj_^(I1B(EB9W zHh3r9t5I~j3+#bcLxnm_CPX}QOZprf{P&`wXU4e$p-Z0A1FHu`!gDU;%c#Th%Ds@9 zYn)q5`3?ohXWS>LHVz;c)1CJ+8krkbz}b)!+UI zE-E&k2KCD5ZPJbOr#_8Qy&UO-y7Iy>pGkWRBmfzyl#0a7Kq;~)2Jv>Yf&4K&i?DLi zXSMdI-gEgjDc4fOjjNbxRd}%m%_*Re@n6a~3sg_&QZb>Q8gP(62MO(!6V|ChWaiP= zN8kTE)%C26@e~4c~1n#4C)5d}=j5R|Ikkf0u&p=L$$ij>7SNlHg`{Id}O4?z*N#=1mEa z)-e5#kvgPEIyn4{CrI}8fb1dvr8R@ne0rZEbEXzp36JK}={z(rE$2XN z!xL*br|`b@UMvoO31slMo2$>M#vI9bO0JMnC^Bno>uPg$-ER31VdlnZUY0HsQB^#m zECxHnSri<%AVl_Edbd5PECEj1FL|wWS4~#fbG*QUMM9@wZ$ZPcE_+Uk9AZWeh}I~V zHRq_gok$|9hJkIhNV7s79ANJZ)7c~>@~=T3Mp!9aHU+tD0g}Q?9EGD?Me$!vp1qz> zE&BLY9dXiugatyDvJ{9%HYOcG8uk&EXIf&)kk#V_7Wll4u#)~`x884)WR&4!hUZN? zk36nKO{%$tr3n7}l|Z{T{)NolmGwW}L|+yginK^m@J2FGB@}yEkO*<$tE5bnYOE+E zsT4L=4Mp0*q#`OwC>a7qTJp@+=dwB>(9xI;v8Ftdm#`70>5_kvrAWb6fNhfG#g;1a zgJQ^FEz|$nPRjW|#jSRa^HepH??l|AeyzbiJ=msI$hJ(KG*tcf%;31wl~7}KHGu80 zKbvhuP#t+fv<=_?ce2ATbjK4qSg$_&t!Ns^mwYXA3+cN)3u*9G@zLh9jO!<^NKwG6 z=!gJc8BD&z{Mwo+I$Uk^QGDOYZS0=(?QD}pA}v*;QH0fY#fZ*-rcL?p+K(Wo*_RAWRp;L( z^LC)682$dQ--`~`*$qwPUb$3eF4efSvMSqo)UZGg*g$2Gn5#F^N6@-$bx+CFX+dBLAmLT46`+d&FpxLJlcjYBjH{D6;@XKNSV*B0YQU{^bNg}n1 zqm9d=?osqC@S@m~w2m`VHbLHRAY1oJc z+^Z*?GJ#J(hOO~SJTzN#-$TDLgHL0AV28PipKmiptK#~<{_5N^q83g)VvW`CFT2_? zJ7Q<#WKSNI2-QJZA3YMmNci`nN;wxd^22xY zI`Xoy=A@jfH3D56bXzxAfC`3Lu3Oi^Xh zMD~&T4LV&mRVFKOpEAP7$iBxt*FUdgDjKuFYN=Ggl9?vpF4yxL@3^0JFPnL9B{Nqq zm-&V2{`bAkezsbP%ykb1J=fUJx|GN4Zr3?)REo`(@lO5X`|j4(mV5;YA*NZwB+yK+y$Pk)geKR_C21xw(+`~vBWxKwF_upf0j`t(eyf!+!Z^HK za$h?27mQw3t7o5mR`R<)l3`M+zj#rC7toHFQt**`5tB@ZB8Dzk`T)C3@Aao^xZ_fp z_TSRB4<6HeAmj{8H?<_pyJZ6o)Y5AUpLgOg2)LwPHr7KSu@nB3d;pyxmlGj;csEe# z>j(AsIQ-`z=K6hZ#wC*;TzcoRo=FbxMk6nz*Zd4mBr_Qfh8hkVjW_#;jaRRsV}`)B zp23Cop>lk31#jO%yVtrN5 z?X2F9M87^_O5;13@c4nAYB=e9gbVvWH6PysJ;pp*PdJkY7y;vaJw+~W9cR`{r7(bs zXX4Z2(@<$uDPMPP4tq34^(b;Y{dEFJ-Q^l+Ip$SpwOSCcNa5@ElJR1XONrRFpln0G zwMmGDhCqyCzuY8CdML#NVm`@7y>~kGcw#12>}u6!>Atib+-72)r!FPs;fSL#m zV6hLORuIO>pHMS|8bSr0kdk|urJp?AiKp{42e{!8XNn(Xc=gi05050YjUH`xJI3*; z=CQv6M@!#JCE_M=%{-`KQh3}{vCTSk>VRhY7=tu_z)ZNi`G%QjF-oA%O8b_L=l+kVInzN{lFcVk|*S z;)Bc{;)@_19nC!}cA{CzCZrIcCN75VzaMbjrS^(D7M&%DLbsTi8z|20)?6o z8VUu>D3itAFk<23UX0wfO1Qjg5XSx$_EngaY*y*^+84*2P7S)f^Q-RZ&DnALv|5A8 zf+#QHRkhm844aza82=?N|I45c*&RnY73iR>A)@$hvA3I&OSqEXS@rmAwretIu~Y1@ z`^U)`NineuW3=~jbJ>uyXXg8-#%x+GY7ROzC|`~v9VQV^6Tj?i_TI+jzFtR}$e38Q zt?P6EeNA{w*~z_mhOyLpr|$ev3h@65z-I*X5h9RFTC(<}iA#xL$A5LwXCKq&+t;#( zPM5#YX{p=$^69*L+POBVmdl#GMDn|~K*nPXTCmO@jVXUyW<5FK+A#U)`p!kv9x|C< zm)7n_EWYg|CevD=#(kybk}*tREs-#}#v=38=BjyREGv3%8B39gz+z1o%Z->GI+*@K zm>!>Wx;Mw|?urfbJbzvc<*J#p^Q+^F6&poxW&Wl6GV>b`4I}{cEaBv(05r zxuGopF|(D)q3h@)695h>%xQMa{H-m zGtfG=#n2)SWLAQ3noC5~^|Nrw`Vr5``y5SFcjDFwLGqV{1FtT$*){M|TxmTFs=ent z99ME~slraV+mN~NTT7OO*D>=%<*dl!4_MGvsI_gq z*n~gck>@ol3+rN3HehWz+FU~B$=^3do90W5F}t~xtUY=!+(Z?;;*$$BY4y3C^*khw z_rUS0@uZvDy)>o)Tvwg92f!&$&i2<=sEvgne}6Gg{$7~_0&i-HZd=4(pg6MtFJ2Jp z{H=14&+G1$3so?e%l7BX%hRhaT`e6tzocRqkE1C4o>+9zbTYs2s!5{^jlfkoXKI!Y zxho>=oF=YMqXJ2CrkWg_dr&At&IeH!aVn)qztLD}Bq!1^z0&q)*kJ}nZa4}EnkVLt zhsj;?R9xBQKQ^4$$ka4Xvk($cCVnn(FY)+Yh?h?_(R?_BmTO?&jhGR_f-PCB>3J;R zO)CsI<6-F2g|<60uZ_>f)3F1~rm>HVwT-meGSm;9HqGORPF`<9BR426Wo16D5#TlG zkG1`<<5~#JXCE;dAxsL#-Ew$lSE6I+v)$AwQ=%P(s9069=sk2Sac`c5ie%+uhZ6qS zTjZ)5VMf@H%=1E+Pij;FFfl@{cogJ6uKjo6*@1`)?seFRvc7 z{srw-!EW0)5WVXwW(yaV16T4E-DJ@u-K1&S21pDe_N`kO6h&D?BvMOKb=;!=zC%*7 z6}j0h+G}~RB@XA2@68+PbI(p(DoqnSIS#ITiA8?a$FQxSScRt((C@|K7lhJ8;9oBYMS%im)X1@NuJDA00E};0J5AVA^Of zIWhRdAj35va1juZx*7K(Gxtm_3{WWy;ew^GM(SK_6D?jz49%lo#s87wx4i>!%L+y` zd%4wX*~HF%(j~rv-{}$HWmT|}33Nyg%qIt5f*`QRaNe`y0FQ2JB{cd6h*D(Zyd&>W zH}na|A2b}SiN!P$3XZA>$fSxIfEMRWIUo1{=wuR8n&%ZQJ*?Qs@GIT103ezjIg!w*gevYAGVXz%zfW>YpS}|Fh_oS2z40 zQN}xJeRmA9x+rGERGS1V@hgPR{=;dhBmlVGB*6Kzzu#Tvt8j9isM z3A?kyXxN3|8H62}(^D7@N1d}dE5$ICuAuG;M#2e6iVc*EpkwBXH&;{KO2QiJL&VTP zD!tQa&gfnA0L!bo+y85@W7Aj=$@IuCTp;W+PZ@29ch_cIq*Hcp!o_mFxV@Ub>#BYn zJY?;+`_Mvt{4liN6Li<`Bm9O!Y-Q=|F&dM@q8gm!vKFbp(PasF>U5gUm4ZQ` zEtSNWOur3+IX6i@Ylm_XxNA~2)4>+cV3x{RuwdHIw}S|=ZT>ZIKDvOb;_nh(+=5#c zp3pO7s!d6@V@;%A|Ut}pRP#C?P{{o=#rO~iVT+!Hd2xpLTZ9v9g zVxCZSYb)IEX87sPTsQgavm;$C0Tb4V4`<>-8A_fPg8%Ec^;2guKW^Tv^A$)_ax;rD z7tu9s`x{(a;Fp>F8D2G8EU*P@J?Ly2_8sjfslvkV-4mAnw3IZ72@(cuZ z8kLru{f*&jXqAh{1Y2ofu_*r`6^%E6F5R;)_U&snBHentkoF~}j@!nng5lIgl-zZt+^oPRO&60+X z**Oc(p6h4t$OiAY%yn8?*>npU$28cUYj2mSyDMUb!8cUtW=fu@)WWdJ*WMIR0xc_V z@)eloBb;lM%%Z4ov*i~_YZXP%0`G%Oj@K#z+ynH`*f01FS*yOq+^U-5sp0V^%=a~$ zGv3>4CA@37jkm3utM+Ltx7>dtjsF1cRc&wEHW2>qUvVo^*bW@aExKfA;w+A9ufZJ8 zh`nJzQ5Y0;wuH!}MpAX$qW^tIN^%rg*;~JkA8hJg9^O6AQM&js36q9*eB6LznE#PR zpOzH~lsS-39f`&t} z9mo|Jc~1m_2_yPJZD7kRrjZawM2~=#RNWk)z`0TmC2~%uyFgfEWMmVCW<=Sl*A;QXTe2l~zG-pCQf)yxq zsjJNb9BD&CKQr_quqcVtk(&rRa`enorD%AwY6+o${D;dzxC0=uS0x|>ILbPIZdgCb zDEP}+O)_>{e?v;=v9;<@=M_M|6n=8KMze7CRw1>E<&vZ!2Kq(Xhdu7c56#@${CK|4 zh*r?rXMNZ269LLd_lDow+wD?0?if^xUdDZBzTAHrV3X24_e)=gbHIlLxgjE7ywoqi zPYvDsRAi6M^QVvjGYkmwnai6kS6rGT<>C%6MJcw@$aAqpz%%|b#V&jmJyi5yK`@RU zm>=WFa?{EvD#_Y`=GZp>tF7MB)9hqTx1SQ>1abHzhEXY2$#(^mPNrB?CzlG7m~nJN z(JGx{8I~O1RKAX%M?t=#n zcmRV>iTHash(r*m;YrAp;_3faBIG?b<@BzDYt8chn?8KzQi(W%U(;vLJ*N3MmbYMD z(~}wVKC&?fdNMqTeJh1addm_$i6y>-*OHH6FyZnhj(s>BtMu}@GHP`quAh~5Trlau zg?AR|Tgl;YI`srymUnpZ>{g2LM8l)~{U>{m_8&gBwnAUu!nyXrIeyWDr%z%3x5x10 z={`K!-*3^@PGj-s)W1%O>sN=;`myQY9NVz4;+))^h+$mEUuStZ*J9@6+ z#o#5J+xt{}^bzQ1#G~{XXR?DKG0MBC=gQJ?r`u?V036T6X2|D4Y2`Fa%Z3BZBA-cL z4Ub1kOXleTdcwYLwn58;x8UgL2m%%=y!_HIitKPH(Y;5|q{x?pwpJ=cv4$W{BEQ)s zVR|Ct8;JN#Ma=2k<1>xWaqNMuZsV?z0r8rnL7;dTz?4r%T!Q4d$+%5r==+mP5eTmE z45s10JUUE53OF2w;+fffZ~#I?n2xE_hpfuCMtEjPd zci}9up>WutYjymeE8onOEY$#9@sKmc4;KC!rthBrAgPE?^=Z(6=7K3vtM(9NdlE^dkg5l81Bs(oyVR=q# z8A{Oy2gNl^N_Oj94^PgI2ZL4{vip~pZ(p3B4o@!6FMBOyD+#%CT{OOQM#Z$gjFGsC zxXN?Qbo>$V0yhW}5z#C1e`Zd$8-py_wBlb=l3)j;>QQxqYa`lR+#nY?ibFQi32?)d zO-h}TNMrz1emlr`?_*yhYmCTQtORMBiRIrX)k~x#0FYF3hn@#TPw+3oQ)=RDv z8NugR_{(vYvF4sO$trW`%=-D-$azOzr4yYEu50Huw+o7v!LpOa>!`4G@7b7ZI!`$n zCak$E47pFpHGKnaa&pJ+!NXQ}vDOr_RQCJwz7Ox49xC4aKy~VRI5<6j)hg(e?MLkC zIE-(&TrVm@uIlE87W{(Zwp+P;7#X*ykQa&4CgsCDTLJEEE*xD88n|~~;reE`D&1$A z0ZO;T+e*nADTNR*-#;}Pr5|;^S55@eA_I^sR8Nq{#xv2)ZP6hG?CHrcX7^^(OUzx!F<$>8^Lg%pC9M}K zUIsQREhV5l>ufK+gADxZuV$x|j!N!vR?1G%x_uNXnQ!Z()|s(gA}Uj^3dFL~25~FS ztb-o1!#4beBZhE>eac)jd!12)h|tD*D7=YTXL^3r8A! z5dtWk73&>f&n=!e=W_4ah>t~dGGWn}E3Tb2n~mq49YHMu>A!1|4B(T)yfHENySwXb zU!jNOvk;RG^(c4>dc3(tm%I8PY$ZF#WYdCb-9a_du#w*AuNC^$Rb{(;>CQImB4|{f z)OKSfFqDhgyEkXor-T0S$!R$*JGRHcGNNT@e6vPieGijU^>jY7ZSFo$`B0cg5HcM6 z7$+S}OW5~CUAV87K0GYsl)5QeQ$FhlDLgQ0y&$Cuol`YIZ({K#gjKj%fpVb}+ZfT^ ze>klp1UWFLVgD6QL`1k0kja&owS4M$K+~*&qaA#EW)-5IZzm%miDZh zCzg=&^($;C!j}HU<_hr_cD?_w)T&m6)^@6;g?oG5x*S#TUh23Zb^=@~?5P*83a(5; zET*#%ZE>20r^R(evTTa*2GZo%E7B(pkQD~dKmFG##hJuL-Li1Ozb$|D#{Y}lt4xL4 zf2*oxpjEc;vom71W>osn?c+3|%fip9gbr2<yHO(OIYDcU%RrIzh z?N(iH8aWhw=T}@+i5Rkkp;b3oC83*y(l%0pP(a&9=n%5OVKU1 zXtUiv_%wifRGLcxzZY}o5i>ZGY6*7P&15XPV>1LdGw#aRqo8uDEH`thXc0atoWXF8 zY9VC|XER+4&$acdCD6R9oVZ~sf}7|{n59BEOVfzEVf92Lv!&v*xq&zB_R-;+_UpGk zSQwZkT$>nzi_1P7A4B_(w{UdahNE`7;f^LeLZPkmb7L}n5{5Hw=J})*$ux9k5;oCc zC9-gm$Vr$oZD{NuB5av&1}=y1;o83!@Zt{KW8n!sL#A3(6YG3fWUh)%C&Sv$7Of|A zu24hdw*sTgaRCwSOXxe(O<*DhGe?+mr41x#C<@@(u5v@j8sq<~{WH~Gi3Q*m6J#1s z*7+J2Yv;d63s=?`lLB~}C77Zxx>_!Oy7s+Rt64uB+w5~dzMEVLVvZp4D7FMS1tae$ zal{&;i9uq`f>}%>f#_mTz*MSM0kFb3R}RR76qBL*&GHGQ5vI9_jLjEO#iFR7;g-Mq z&GeKJg7xg`8I8Nw7sFxmk%g=NsCWC}qTAb9Y@GUlAHonx2PM-xi5Msup%c+M?j|he z6s;6!v%*~pTxMvUXdrVzSQzi5B4diBJ0NI zkDo1n5nu3w^fWi2Re4f)0G-nI!*??@BR3zcif$i1g@BXmCMZsQS;Kz)QrFa7a7-V8 zs{XYBolXa)EYa8~nR6ylDe7Ats1Kypd_t~LQK+}L`4iaJkdhf&Ka1vm6?J9lrY4F- zSU=rHjG19Th@S3`c^66ImoVg5$aJD z*d#9u;XM+?Q%(x7bQ08R*3@#niK66I1yeH6g1$6%BcqN%8<-H%l)!_nqc{Bxd}$)*r)*a zs4cuPHO7 zJm1@!iF~LC{N#k|u07VJQ{JG@$m-h*?{rJLE3hYZX_gtA&e{E$V$wGe~Eg_z}6MMx<2d;UQD^uwSNKSR9$b{Fcf{yuecAB zpr|8R)zPUd9sQuC5?WD%)W^sqH?fsqXSM@mRsZ{JCu|ZAQ`0@pLSXJa=YF2#;#)~e z&mRmt7{HP;1&XsYg}5L}L4q1%tpL}hu0d&{agAIL4cOurvjuEWDkeC5Zf%p;fHEO# zux@85Nt}}m!C9gkkzi9bN;X1s9dGo&w&vS6chBwhmBywmbY>W5X zIUGheOyBcZ3Vk>92zN|r)$iRSN6F&I!IWcMaZ=QZsc32!67Kim5WQp2vce-6kH?Ub zLYeD}XKT?^iY;*59?n0S?qV#pSzo_*;}+gACvc%56%|ip1Pz6Io6i#u#_kYEHTMg%FsqZkZAgnm^6`LOId-=u@b_}lka0~NKqju zQY%;!nFHZ~QW_PRPh)^Bk(}}Du!_lsNFY*@y0!T3x0J%F+GPF^Q;c&=mQ8Qt2HbDZ ze>uzO_OZE*FWu97{07Q&9!}pudARFDxqE!-T9~0suWn{tD7L7MS;FUsrAg9-@;rN( zPdj8W?=tVz_l^9U*O&JT?OJVf+qe<_?q9LJagUOsh;n*OI(|taEAquNwyd#qmk*As zfhb7gm?C)~7~4(!-@5=v3Vap)(rKr2oJ>rSzyjEP_Ss#4hadcvzhkyqJJ5phAEEuP z>DaXwi(uOK)@$l=+g(nN9nZRne#^HVY%MyBK9ArVWr6Lv@b~E1M~iT}^w>R!*Yb%^ ztQ)eVAfKS%Ih9f2Xe&1?SeO z%kLS5!}Z#-2}|~e$(CiMXeS_{2tEu92&jjA-sDB-GBT7Z{Ky{ zZMWN$T^-w^ZXhPV;@l7RO>=4URXFQd-rAJIIAj)>nU$F{$D5gJ5^%hiA}reBcN~t# zpWsaWj>Nk+ATJ>vrTdhy4jM&F-i$Ptm5x2lohMuEcgpOAO#|R7!eJ(wfu-67Kv0ii zK<7YwpLssB(VEVE=TGB4#kjF=09;asl7Q|f`kF@XK0Xr#mP3M|J_f*E`wms6&WKap zcfRlJ?1+g-bcw5lljk9G5gRVTgOPji7Qnq5)Eq*{#{X!*;g$%Q+ylo(y|}ROSSJz? z%lXKpASEPvXv)8SI72DP@zNzUlBe-Cnf5Qv&j-UvyWrKQ zi+=oidNCRdr<2~VxpvJ1wfYCsr0!gwM@}mv=2e z@In`5(RofUK4D~?v&V_;P}oHfSb@BqtSDF^V`w~BhzB!@Hip0=uDcN$OG97D>HuIj z;E1IWNB2lU6K|GAb*1Y5Z;3FuJLr}u5(m)v$zIpb%5(&Q2a$}2f z+MA_iArs92jzw2g$RC?1Uu1@E=L^VoJX^Z2_nS zu_(+vD^2BX2ySd2*V562eW8-!J=eJh*%?u*3>7UlCnrd+w|Jp*YFxt+F0a_lvJ2jI z>77!4#wrWjoe%L{&fLmY`}@0e?elx}tBtcs@cat)nr(1H$7us+A#EO{N3@r&#{|*i zh$ZZ?xsXTBdgHOYKYB0aC*>LA~aa%iigvzVwsdhW*Lu#js}c(Qn6R zr~TT}N0+C+_a=kdlQ|vs&g##7ba^ou^e2N)^_q_-y~!iy-a8(nF8h<3&HER_ab3M< z03@()BdPI51f{FQ6A~~du5jIy&LDA^fxfu1{w^-f=f$<_Gy1K}Lq_<{_QE_VZuOGa z)n1Zv@MH#A4=?lTx=W*sVS*CD16Gb%y|6Qp#DsTc-aBjd>n`%V}zr4=%t zpV)U~=Fou<-cVy`L7@%C7v{Okv5;*PEnA4KGFsXQca*(;Pp_ev!-^q~aDZ_xoJ z7e`P`rcxbK%kcurjOz*up%6XHsQA({bMd8?)=^lja};rq7w{;(qqJD%19zU)Ms1}( zR`Fu-`Jo=FOpyz|D)X}!n`XO_vd%C-2Acq~$v8H>B^g8sx6)SJNNaZfooZ`ydrju(qW0c%f zyKLHOx&?}6m?144L08wJv(~A&ZDi?A=|Gyb3+5b)nP49r4*@WZ+@_)1l6p>mMTGAd z?aa{4Jo+MG_r+Nu;%2CsXmIfkZrBhFE(RjphyjwbdsVE?ad8q&} z!}8EY^|?zbGJ^u@c?@|KQI|wroCioxo%){NNa3lV8y4TVA{+Z;Qse{7gyHZ=lPjLQ zdi7-TwM!S+!4vVX!#!pBo z9O3*^Q{z!Ap~#B?R82}O;Atqe63RAku0}_9!cKwbKMS+5@F$yYHzKiwRH~v{o?cYn zxUPnue}?SCe6?MY2}!f6Y)B@cSR-S-?b2I`kC(FU&>Pa*moP47=gWl93tiVR|JnE& zw7!~OTVGornx;`)>=?UyMiDML29)%u-s>prvX^`MJg$5`?u3o|o)fNJNs@(25^pir zcm;pU>=B)l8!S^oMqyzy1dQYcJ8%uLole}F^p;5)*r`ll?>dF=nn6+yr%@D;1hb16 z&d&mDW{!y4&m@pzKOMT;jGG@bUqdB#KrwC1j3N@<6-9@}>=Xr&cw=*8qIBAqFonFd zEUUso#hIGSZ%~30=S8x0b_dGAAc5RI_QiG`Vh%GhM=e}6$DDTaD3RMNQg%v|%z`&? zE-wD=d}@iB8d7Zwd@yO*iE@X;OH?fV00snNTm$yw+n}gioD)uB)o$HzOATGMhm+If zmd3i{ZU&0o>15-*8_$V6%U-&u1no8Jq?X@!NGMI7 z)KX%t60oK!`5@vv1gDRAy?iOwvmrbz2xRxPU4R7WO$EhsDOtrFDLSP?SHfOSI^N}4 zW*H3^sr-=O>P1;1*BFSDUM+^vG+hde|TjVDJBm6dk=K&vf6n|NWZP%rl{(aQg75l~&l3Sexd z)9oU*vTX9}|B++QNI|_2*9yf{TZ3Vr1o5_-%~qz>h^Q>Fl*A)*t{D|HB~vZ3z|2>D zd6F!Y(d_<44BTVYvEr<$-JI;d))POx$t)M?0NwtN`i z=ilX5ZExE)5dQ98aVxUg2^`A}x@1U`ERO571M*@_#)2UT3|gXWA~LCwR9;r}zweHc zEJcnTx5GY7KoE(%dwBQUb0mHAOEOCu-p)<~c3{Y~;Rcut;ht*|3H-1#4nfR}flvhy zsQH{r+d*sR@OemKjZpAsSu8)CVxFOf2HE@j^y?vTR|mHT1;ma_PX8u-M#L+_u!KW4DAz~+Ynm4 zvr9NQfbP%lVgH~D``zxgbB#s7rJ+z})+XlA^QOYi(n$w1^V~8qn;5Sar#Fe!#G5l? z@!dfLykj3NocSN&Jp0b!An*}jXVosl?&VJ_J_|j-JC=l0N^z2~pHr0|k3`MFL$~*$A?vOduCQ8F{gHmFI zX%z|td69t1@8kdl&Z%}l8Av|px&KKzK^{?}G9WDhR-RCFYuinK$&B%-BD6;1{&~;$ zw?AYNfAu_)d&PGtlc81tH-=XNZ^Oe3!==u}w1msSrABQn1C>g|;^9&*3Da!8#Nn?Z z=CFl@3ygck_JN3ACLHSlCSX#QUNIY^=bG^Am*U|X;^KYYpKkW4fxr&@YzR?bFh3BD= zCj#CJm712rX+x{5)GoZ+ZiB>~whdONyb`a7&@fByrhW}+Z z7Z-y|QumcV7>|0N79jMzeG41lRS7mcUBoP#wrNCGF@+`nxkA@i+;KeBzazF+t9`t>+DoO% z&g$dUi0)%dX>pC%q{2!OfX8^mt-xFVrcS3t z(&0-uM$w)+VUr~hc9zWllZK|J-qcy8U#R(pn$Kmm*@pC|N@1QNPbo_H4W8t0@YH%L zc`$U(sJCG)w`+~pVxPReVZU0P3|)ZpZML*1mMiC-i0V0V$_mxk%&yfgv&p8{{^p0* z3CmV!S5Gixz{eXTR<}pE%@qxsJNU)Eu+dhtzDZwXs=7{LSOcx=V7ddTi)YtssuWpo?LuEvX4 z5Xpsrw^;PK-Cj$^HPaH)E$MIvWOKx(m&*3CK&ZKBtz|Ou`*(2*r0aJ+Ar{Mqg6?&txQc7^+D>UMx^(E@qQ{6f64w2K|Uh zrg}B8yJwYZt%8+rs zn=w~Kr#HKehe=_7j{cPbJxAzvQ3T+59{6sf0?I4BtrV&b5VI&l=A!~e`@&TC22^?f zC;mqgpVtk*2aJ#@d|B`{$<|JOQXw{VKd2AjizGs)f(o|7YJ6)n8pbOtLv!s@Bs!JC z=mVIP>=xn>bbLiLlE66qL8alE8B85R#EB#UVJy82Ajdh87RZ5Q54-k%l1_=#LVQ5N zF(|Utw#(n#X1dAS5ZjVI@S4f^AY_k+%wwf?))(P-Vm#bA8);rz6JR$FZM92s}6 zh)QnNNE*tRYKTf|$w>#U=fp%T&@jd=J(e|EC&9$2DLo8oG$oX{MJ+w&JVMwbf%wYa zj;Xdob2CNCHz=P8u>{LesD7#e1MDeH`WkAgIfIgrVl3?@uk_nbr6h$oZwbLX%wc!D ztN}<&j|mLIo{QYuB#Eyv54I{IarCzCVWqQ-tty?&1voBkKX^4mJ+{wVd9KaHLuh6D zKNWzVKQ(=_-24p3$HyhDwM#~%P43?_21I=9I&2}AT2Rilw^apH#^-?R%K(k?` z(pC_%)EXXKqi=dSs@H6_OX1xC5|z942RmQu$*#Ba?8>pH6yr?tLi8d(=t(s6_G;MJ7Q!Jy6yDl&^?=rnT-MF~aCYlyrs5k8Sf+?O;>;eKe&TVbW`U zm;})NMO_&?1#P(N6r%OY`!S9vL)B5Y1(_zt)|B3@4&ilE$|CQo=naZB4<1^ttEAPe z-Ypy9juck7Xl!r7>!E{k+^I(top3P+y=-P;;@y)81v7)v zeQKmoVOB|^rd;46d=zv7!zmTtIQQXXBD2R+sjX{8RDCF&xF*7bYwt2rb3x%`HuIQy zET8arJQr*-Rq&?We)sxK`|xe*G7Qulu9Oc}_pA@^-$VP)xA5+L8{W0s4RbVP9*v|n zeyUU~k8FFw)HE5lJU+9Hnvjg8UGmHxhkR_$h*bD&M0m8N9u=Go&*3V4&%{UfV1^ct z(ql?Q3z5;r+gaqw(($BS+Xme^_p-Nc$R^PmcrKMnf|?SAKNO@QLIR6`fX_Yf(xX81 zS$q?MdMcc^{zv&oP|k}4;FgAzNP4u0*C<;%{mFFjLL%jhlL6Q)4yk^XW!O?FwePiB zP1|F#O^p)BgJxfT;aW@{n6U?GJ) zgwvDe(Z#|G^uw4UN+3NFMN4716wG#58+%x=-u*yfg=i@;m&}ApV}b8pf)$JBjJ3JE zT?ev2MhV_M#F$sq*K>QR>ziPF;LLv(#W)SGwIwRerEg`pGYg`G9X})-^aBz z&r-9Fj`pbTqv=}{tR;2_aM)-6+9Gd6O z2P3DsaqDH@?cH8O?5kN9yN>a0 zaYezNNgGAE1ZkdxVc}Yn>oB(&WPsv*CJ(rv*gKKR9Udk#9ra}-^6;5J=v54buG~Vg zVr$77ta0SC$I6fu8zYv= z?HX>cUcqjsovWK+PouvgqAC?UuJ0ZREhob^v$Fte)g@4>wCqtKFnArP_a0-!6w&=% zrio<927(@F5;a#eChw2+Vt`%SuOF|A@`)l_*;Ws$oGqrVo;^_MsX6k2!Y=ecCui4A6Lq)ue5ix4i7nTmz zmlz3(w^U`-q28>HOogt6zRI|00}eN7Pc0}i;v*F%2o7c(7D(!>rM=HB-C)5JP~_;B z=|OKpjHqEoOV@15soONI%|5-bES{<6Us8SAl>>OwKxLXy^9n2)kdxU=wf*1}t6c|8h^Vg(^%PzDm3w6#0D0G!<^8`&tts(jACDl+;(Qe7ha zOE`5q)1+SuI|07Da;2ZW$cQVS!TGnC{tC{f%%@Q8KkZcCPunmMe(zs#4@hlUX$oR6 z0cC}*8%ThvwbC9Cs$A#NSR{64J3xo{-*sX_PaVWac^v93IWm;8)#(2^{8TZechegIuL4Y!>`mR+n)QY1qSV_DE z_c5ibB)YPMufdl_=cJ~}C1GK>R!hb-OV>F3EE0qbQjZ(IJxLM@g$vAx;6f16+d{>2 zr$l=NlUg0t)`qdv3PVfJV@$r8GQucoPQ@oxBR<3Uy&(My&y|EC!;D=@bjx5uTyzavH`WgJ@y6&$` z=ue`q-yFX9MnW6gSEMvixEw7KGQ7eEOU?G}?0h^J4Nv-m7Bs5y-obXW^-4sZDB~iw z!0H^US&N8}mZNvO5V6EyvqFSV61Aq`*oFF_nB}hZooLoS=VE~Sxy=@n+r377$Pz|s z-p6y_DEPoJ^ZHPKOXXZ-m|$2xT#i0vA-Mz=dhi<;{=~;0 zYQ|yW2OPY}1vi?{d8j%_tm(hMCPL{)A$*;#ow!W#X(S$jKI@g3x%X_!L9dL?B99M3 ze=^}he`Sf9MFKyzj}ve$ck@Ur*f6%2?3uGJ&_s61$%etQXT-azl0SMd5x4_^0rEzKJE zE)OLsKT|4}Z@b;8uV%@(gIIL+HUS&UZpE_hIEcpGIg<+CwFsAY)I!0xgAeed`JIXn z??FE#9;L^ei4OXNl<%g^0zr&qx9R!U(I|sU{V@;NBViPRCMqI(|tzoX_DFBnl$iD${Kf<@A=qQO($)XR z$rv$%y_Ai6!$Rtjp>G<7^^b%4JMFC~e;8~<*m~DkGX93EM1)jQjcPdzDFlimG!KmM zRFMV>6MPbhB`|~*v>J~|61qC8F;7T}Xtwm{Pr2f@gywK`b=|)l4NpIk*7W(Q+r`pk zvo9HQEh3jo$t~U6@GwJ-sV1OhzBWT!M+GBvqXf%~;NFrsR43<4Aw=N@dl>@aE-w0)!R*38m`d0t1h8%W~RfGuz<&B(QrAh|#gYpeJ=|)80Nz<_0-!a6$hBJU}(HrDYt^ zunD7YfBXR(K=?v~@Zst#1ENUatq{5JrKB9H4rGoMP-t;V_Lt0UEQL)U3(L_O3-!;D z8$^-|=gx|bZWk^;b0pji9WhJ-_AqXiqK37tUJbOTc+2uKVJCb6Kf z=~8TjY|hhntK=Z17NJi&RANdzzPu^W#|p?*Gxx`>mUw3yLXQq=n-3$IV1Tc_LNAYu zd78Ct8Q#k2s(NcZ^0>YV(=h&0>Iz3k!61kp%%s8A1+o_8F~uN9S*y{iAzK^sxGx6# zha|=^1&?h`CvhjfkSZ0|anK;@9<*0Q_){6H!v5PkatiTp0jF+_bvTh5{V?I{H|Qz;-ke{4%#60uy<(VFGZS3fz0JpRg{wrN`LaF$&eC)FJZsyyoW(-;KXiY8 z9;?S)T)(w{G?Y473CO(s)WK3}AUVK!GHZ;T@{#=z$7wHdm9$R#wX(~w_ZKnNW{kgQ zo5ejdGo-n1K(uNcp@mQU1yqM@g!?;x!NvivMg2TXyToYR0<lurvT4vqzn1Lkr)4`vC{F1B2u|I^ZHdBq-_tw<@F&#GXF@f16nGv&^jPWPAQ zZSUY;cb{H8wVDU{>w9RHLHN1mmgnbIYp+XzzB>3!MepqrS_^y*=$|dFnM{xsS5zK% z13dK7iSfS?Z)XLxe@Dn^7x3D4UwtYrtM^&!eP@4@L)!VaYjz_u(mtOO-@Zs)xw7lj zS%zF_9F{?jXUzi7UA)Kk)`J1$e%PSE9pd68i&n=v_Hu&tT8fp zcB7Jw#@S_!H67y;!qcl87xTe6od{_l-Kz^t?eu&!Go8LNnXPnwk;mCV`m?(+4XwL2 z=J%VsdPQhD11-<$WnhOUA_&p^whlp-vnUBX zI^I!;7}PhTye4~_I+*l%bq$q{kJaCIAE&lC)EKVr!}$2~xqd#Ly#Hmh+|)XU zhc!5aKe!C%Ay=T6Oap@tdMU*n{$vZ__o31X=0f7cJdOe#ipUBkQv5#P8}nAR9WV}2 zyq6etRqR^2=y|awga*5&^9YJRUOB&&U7WFoi$S$ zp9v!1ZGErdNl$zL7Y1AFD z$w*_onVhM~$y8~{0zE=c*y(x;w2XNZj*pLF&Q=N^|E?KD4!D%)-eaiu47wY%y{Hfg zjVT*Pv-%N%+4PF|-40AYO{s?6uz6H_sQpI@K`=`dPMJ|$U{yc(O(kJ-YeG{4t8nmw-$YJb;il>d~^W*kBf^ASrf zz}#go(xjarb?E<1JVl@81u&Te=?0A^N!W5GStb$e-MgX;lag&4#h}@O z^ws$D<;7JK3z7gHIvup%!QZiNC`G`PO3ETHOIts8m@Z*NQxu8Rlyo(QTe9_zi$8@c z4hI5A8tcbEZiEU++Z2|+3^jkNRA*7LY7Ik zfUVe?TfBCLcd(KCHWaaQ|^Yi{--15!+deKYgC%vCr2Fs?k-y5ooJfVz$Xsh<(JlKnL|)bf@1(-$973A}E1|foU)yfb_Jw7a zxH~)nY_GL!wes{&)g_$`k}mw2(n zeY_|$VT`$n46&CYTs-*;!`x-ucLx!6T@+pqvkY(!IsWSN>9{`{p7i>yLV&&_o{!?y zD!Jes?SPl4BHJiuieq9541+I@q@CF;yT4Rv=v_+Tsv!Mz;NGLjs6RZpJQ-hHdI&lf z9E~qe2R`agMzeY<_1Gg4X{J|;QOZ|OQz$BDO^Cdc#e=3evbxRvzqjr(V~{al9x^i? z3!52F4xJT#EPQ6{385LTGbsP}u6SZt%`nl~FR?$mDModERz%qhigY<@PYJXc#pB`2 zwR>D;fK>7k-tKhqv~tITJ>Q?Zqpt@%Q6nvp#hswFTtieyL0ORPHqC$Hdl3Mk$3dI6vvsvGuC0}A& z#hYC#+rV}A&Yi~cP%>$qsa*p1+)7mjvFi|B~-sPQ8?0M)57f z&-7;HO+R>-oY9-{VKn2T(4WtFOkce$T>x-+evbJi8!dQz9Yr(t;xdtczD)j;`Tw^Q z@^s(o@y3g%?9KEzOmAb(UM!bWpZ>IaOrzCp>|ZWY_GEYWhwUf3kDsy;HeqM!EjvkP ztatFQQ}*MJZ1=yPvLAljWk2lh_Ni;&PkERi@{2TGCC`S#OFvy?lO15qkcJ7oNiwu3 z8%}~~GF*B|3V#!bDc?zNQueRWD|RA&OYq?bMh}7q=qv8UJ1{$l{7`bvh7LW4Tlb&7 z-}2^O%AVn?7g<0YV=n@K|3LL;{Kikx6yR=9HmU>H$RD|$v!eYLPd4h}p z!2?@f;u()yb%Yu$v}Du3OYFJRy_a4(T}X-XrfKE{?8=LMZxZk!b)=E((FKQzy)?XF z&V7Gwh>cn0AuGo;9kO?X?~66x0m;{c0v}3+%dgR zpb5>pA6|}MOVcJ_Q3K|q<_Jx)APNXue{OAUAueP{@p%aNqZFbwm3kD-SsHx+=7I2m zsHYs{?%G3`X#@%YtO-%;b|e4==cN>90wP}y>EBg00aj{b403;oP~u*nKL05i!(&3| zU5sD2kd$Q7)PMEK$%Zu5Owe!rZdVy zfW>Dea!74UY<%qpoONLOrV0IdL7E?+&4pQE$5oeNZU&Tfc*i6pfO+_L3!28T}A$^cH&loyS)ac406)!8I~BZ zJ)`;d{v}T@=zR~SS~s18`GSACEK6};?tI=7^=l%^(tgi3gL)VM(@4p;h9F5Kn z4v(Z1Q3Gi}k6?r%D%cYMUind$^a##?_41k8W{>*=7G^;(U}>Cj17Cj*4F!4c4EXQg zb*F%P_dWZ^9^&)r?cwGzM zv!ghU;$HWSpCl-!dP)tKscX#JfT^ZkgG79UtmN-LZMEmXo{4!og#RbX#LAa}E&mQQ z{X3BA+khASJTE86P0a5xxIrWAxDk5L4UjXDw@}07-%(mhWO5`7q^>L6HzIDrSr{2E zMq>C7CCZ*RvrP;#Fy$PWFoM+vX7m6-n{4=0R*X^Vf#Qlm zi!$E`pwSgQP~ec4z!2W0&7=b7;X8E%I}OweDeAsVI83G04WHo4rVx_52zyayG7l06d{KyQE z!H-3Ovgj6HT$C22=}_>8EtQ7DYh;q3KWq}CcH%@tcaM;dBhC|BmxM66f0;stYxDNL zTup@k(Q_^zgQ7s1t3v_C1$xQJ{a{cu(i(>8kf>#`+8-f7l&h=?Flm_wAH<%RJ31na zZO9j4n|DW8TaTn3$AWDt;8=iuO?Fkpo`Tg0_Hej(m3~hgr4T1!bZNOhQdrwNK(^$p z?+@v=VA)0={1s3Yg5AibX(XaN2=3+29m9@e@Nf!oC)$Q?oq;x%Er2{DhAPvHFHk7< z_Ql`y(P^ypSGCBW9E?U}>+CPbrx!=(ufZR4*|Y-Q7E4}n_!v_(iw$}TJBJY}fC28L zQ4n22#1MeJUH0;?V9dtdz6HQ-vxKinAn9pFPy4`z#qpETicftncthYA`VR(VTH3~A zJ;Pn%V7Y;sa?=1iFf3D^x6!2M0HiwXk$?Lo)^ve@b6Ka}5`C98Xt$F@j#*E^=@Y^jU75a88DvFJB|Nld**G_{Zw05x z6qXJ7O#);dREe=MCFyjb7{|$S69B8g;ex|5XJ!w3u+(D^vCM+hU*Q6ja9l}o37g!q z?#FJw?DrDd*!`3;zVz%dezOXIwLR!F&{JC>$(x+6Fej3REMO4Gn9)czN<#*lk2;pn%jNRB@00J);`-s07x=RZ-6;Y( zx>*U|i#kuT6yzog;mSKr%vBBnMNxC(vhC#U=+|?nukGZ9g}i%&b$Fs4oNGVKYV4kRDrEL9)Sn++{Ca-c zmiP%QPaoRgcMt3hr%EuH?5&c7HkjtRs|_J2ZWyIf6Mfn|zD*bK$AJAiOVTzV`Hi1a zhjbw}j>XP0=r=^ZlYlSXYHU88gfIOm#2aCCDlN~(4=g@Bs?My}@=~j;8r=2`M@Mgt z58s}=Z7l{3Ynrx_v^3@3VVHV;n3T+6&B|05^bWTFH?o-b7ud=#BE99$-Ajw`QcKQ5 zcj@2odP^=u*kUS5uwbl^zL4`7Z8=VG$J=IW9qc4pa*+hGmLgI05z7rvY(`pAE!v-Z z$zf~*tB!56-I^y%VKFnM%})IQC7adS4HncksZ&1l1(jNOiOauep-}57(`i&6udAmv zEGrEEwHd;_&t(WJX3kHHwFtj6)W!{3LgJKd4o{=>vs*;BC9JfQ?k|;slrvoI)2^S4 zXh>AmXYiE4u`?AmPs?;UX#!h(sudVXKnJ-^`Wm0s=_k!JE6pcdqW@%mEX%~IM_!wc z+J-#A z#}zqu>DH=dPg?k|nx6*vCl2s-2|$_a2Bxhn`;l%>o(EO>N?Z!5dnw!-TP-i7 zQdljCEJQ()J*{Xu{L2WSdW~B2on2+(L1DpoI8 z6K=&&wRQzWAFT?y!EI!cixR%IL9e;((sG>Yh|Q4~66r#pHi3n<|Fi!bw?jm35dW-B z1{Tb#e>bb8iBpoh19Hi_I~Lr^y*oiy3rewc0XdbhYd>9J0lT;IQ!iivPg7Z}4ixLp zbI_h7jaH6gEh@7=TzIHM3hzI6Ke>$@ZGdO16_0y)$G*t98NZvh3Qe`tb_eVB$R}{q zbeDa?+~^OmJP^kO&+<^fbr)Ne8H8sJB!7}@0vynWX~4E0SCy&hUbHgrRHkoQFaaxiN0M28bgB*j##6j#0!L>F2n-aOs&f6msSMTbi8l#z zIf&p)-N@bB-QwHdKp~57|9U5#5Wk0yP9B?jip6O9J60xh@qO3&eC5Tgt~-3!y&c{2 z5WwACem|k2>k8-nO9u*_2O?1DVX)Bo_@JN14m}7S`XYK*JANqRhEs7uX=$n*3wYQw z;s{sBkxwqVX;fj>*j`N6o-6~w@wWA7_{Ofst3-_&SFC5M{l3<&$`viwKGmz$LVMRB zN(yvC45gZ$P)=V_3@_?xIAr^MWjktpK51U|)G!t99dqwzI;elzatoxWvMyQsr%QHp z_kv0n82Pkjr=+0iRFBiT9z;LNxOQbhtnjMVfe*c2r=HIn0IFw$fuMR?ZTQ?fFw~<}&&j<4MfGelVARA5Q7o^!O$Z=0csi;MjeLu& z^@f#3M=ueM;pAG_YMZE;14V0ehXC3I?LJ0IJw;>XL})Fuqv4t+tmEGeM!|%MA9n%N zv}0SNY|gh$3SZu!D}{h{m542JbrLRxDl$V@x1m`jFontQRzaxQxUA2GRdWGvkGMw( zy-7ZntUAN|`);b{*jAK|u8XOwklWhr%Ry5dXiOEntQO)f4A#wm$|$ZzRk}n{u|s_k zYZp8SYY2E#*Fnpc?$GQCbxlDn_)qkviK20WK8`XvI*Mo@EAQ3PRWc97I+8{Bbl`Vz zrh|Da@)svA^u;EL`xForG)ovp9Owx0W!Auq;^~#WBIZSbsx*VnR8TDyyIw>A*H@P~ zPQlX3OmN=``H=^5?jH5)Qwlh~NDC2SS6-0u;^4+%0Q>Yo0VPYnstyy>9V6J>@c|uU z=I3Y%u$$ATjb-kQR*K-QRorf!Z)j?*=xbSKyLseNi&LSt?S{wO`+!ye2v7#J*DK7cOyxJ6DRS&5;)IHI`1g zM-?Ed(lnY!RTxaYAVAH#9}*f$BOdvwDs4x~_O>I>V&V{O&sRASYoo*!;heapp#+n% z-(5U1DU%oZ!v78zb%%;!wwyq;6U`a;H3}$8gX~uX3iKvLB>mn>E z63snZgmaq--8Y1*in~B)ShgbNm76l4*C0$(^5X@%x`%GNbH`p*7R;uOvOU=S zG+R<)4F7IAKc060vD>XR>3H{uo2?26a98eQyl;Tlw1_qzj;`5?>V*9ISZ#b&Fw2Sa zBW*>u*G^zGh)pfEEpQZjOyUN``W3pQK$;u;BuK6~XZo#aCWG0#JM{A2a!N%rYuhI}=S@R6+7ua0N7&vKVDd}}#1rax1C zkk3w@Iu7vJY;v6BYki8Zks&S5@7w`O(aA{GnR~&!v!+7AZ$-jpZTVG_>**_Uqu*ol{vA;dk_YM` zqr44TLFPL#a#`xIvvYF1+WISI-w7gDRKhWF|tVLzEOdC!x`@19m{%b?7mr)U3kv{*!MfC&-AhFnk`9 z9`RfuNw6R?xMRNiC$J921BN3MNfCu%z?GG#4avTjUnnP(bGnH~I_hs2%>gu0i?=by zN~vDy^$oqD`l$o|_0~Zv-%bx&*t|H&34hCE#C`A)U$eG_A%;LQfaabeo-$BCf!{0w zo&$p`LgjcYBHxy1E#N3fg*TdN`rDRqlR_RLYt|pXdp8(ac}cC=t8qV>o{cAi(ah?- z$*n{2@$W;Y!+gi&BZta_2R0Le86dRC{R%`6e1;IY3J(Pn%!5Y+kq@+(lfxyXoUU`W z_}cXtseuRBLjAN>j4bfSoMC_xHue3KSV9E?L|&^kA;Ezr5`qd+2?OCOoKcbRZbzJh zJ7{i!0uCl*4}8=CBm_@n4pOLT$;(XOOW-<{77%K58+$-$rJ`j`CFTJ9DP8{L#ga+o zYod{;TB)@|h6}An%mrIEIx4nwT-4iw+Kf1XO(67vsBvCs5pm~+pzF3t>;nT61taji z4N;rHI5aM<3P*W50&T~&SGdolFqikStU@%J&!5-WI+PpzmUq8KYJq3umu7x}A9-GWRPu=J z44O()0=P>*0HpT?O^6IPz3H?x0$Q`-$QsRwWy~>nTXvuadSu9!;y}$JcKM zl>|VL$>7%dqiji5*=Y8zKhv7t+W*#sw+_%s%%Z7W0gWhY`1t5hbg?u3K$r)`P=2v; zIm1D=Wq`E_nK}kDY|%0J#32FwIOFz6IE^Cl4q6EYG#tG-XsI?83{$r~YkXU>XK%2IskT5>=~@+U zbbQgKP)vO%rsi!b4yuWVmnj;bBD+eShurAHNp7eXa`vT6&vJey=%HUmXwskqk2$X*^8P%ns?LqPEFHM3_K0}>1=TIP~ zkyzO_I%;2|R^`gp?8EOvYcQQ)`H}O);@Fk*BjYU46`E;m+C{3=(^=*1p}FIs{hRT0 zFzdg+z4>Ey4VA**2iCz!cGpP(!D+~BmwLpeU=PqalDAXU>WKF7{6Xp4%dzwQJ2{lV zbntH2AK#2ey9H>0j5V~9Bh;L=kP2-VB48YQq;|?Qq_tH1W@xXLc*YgslDq5bsF7*7 z#@HMw7mRx%`USXJ>^1sPjxA;J9vi z03HSEG869$7FY)+%92prToCpZd=8sZ48K2#Q!nxQ4Hy>*kHK~+ngF2=THS38=L=YwM_M;dX-wt(13STbB4{5V7f1Im}Gnn z@Wu^Of~>|F60;p}4r?K#*few{^<2T6mPwR?+925ryoJGz%fsp<2qD!&CE$7*UF)w&7d%V?J)(_-}_MHWfcz-jK}f8oWLwi?G-pyRufc! zKGp9LT{D!oCN}GN;1xQ(rr%aYaogAjDydh;#Dp{5Rj4;GKhny2Sf*yuE03*GhW;0* z8=Qgf^jDNuSC5eXU%Ng8jZI6}3<$ffS#l)=eyD>8GiOBI!lByrrzWMWotuR8rXj$( zLsQ*gk-@x0$p@g)=Kt~sTK}4k7qNlm%puMgnGz-LmP~;CXdPcB7bcJ#^X~3l#on@{ zq=_v{OpjDzO55)L;=Qf@Qcxz$i=#y;s2K7bEz0fZnAo6n#dN0(X%S$K zQ(qVSOzU!N+KUVO-U8D~-c#bs#pGiyenpRm)Q8oRe*^7VZEqX75&rI9F=wbJDYYdh zxF$s$r?GW%yOuP&$Yo-@TYj}L%=LwDE$O9?M5ON+_41*H-g8_xRb)Qn`LXeR2nDY zubMAlwB-6hsTsUmnE2-hL+bV|ku9yzsD!7pLNppC&S_Q)WEbj>Hesct`kB+)-YbXLP4Jp60HZpJf{e`g0 z^|TkLRo@*GvZ?8pEbC80HSMpMvH07G2zbvvS~wg12$%jn7BBC>JtQ8bN1W*%x{8$V z$HnKv%nqIsi+4td|X<%Bj zr+B3A{zmI5LI|yR8=s9csV9DY$8XsFv{C=|L8Fy_8#P+kJ>IZ=yyT!FF1^Xj!UIPY zIUq4P#t~|dKkE(e;JR+ndM)lTq`+8a357`_y|L-z$>__)c<^zzMdQiEd6QM=pKls2 z8=f{h_shqN%VCp+4K4NogqvIhRr(n{Tyn6oJRoAUFv$6(SP6^HeRYJ|mDRi9n2n_YCcX317>nb} zBE#T;QLtL&qL52KWj7SjPEdWY&DS!ZjDXfHNQ&-wR{oM=nwQW)z%M_KhLgcRZZ3bC zoZXxb{yrQh@P6y}xt!%CZP<0KRltqmIWrF6VTsBs$;n9JEOLh8Jf=^zb^$fpuqBp3lzf8cS%!DOU&{dnPX<;M=ch?px5J`#9;|?iu1-=Js ztaJ3H0@X_+lQe81q< zrDD@bTuqOdLr0+MwiECAnu@*s+BR5=`6NgxPW!eCCnqN`XQAQU+=-4LefXrn?SOPg z4=yZmfMxbk)bWJl1$rK*W8X3bNgZv|qDMw0iZ)UB_P8YJOtXNy_a>5j`YwvW@W_M| z#H8DE03$44d{I#{d@5EJFlxnfIm`5levuO&uq6z>wrNZI_5chI=WpMpRc4EKwjfML z)tunuQJtx9_Ql+XKY171P8Ond3^T{@ax?_2OknOrgsA|SaiKOP%*sL@L>N+%4wgK) zLrkVmZmq)pPe>M`oFY+L9BnHRdoJYcTJw9M)~4f%(|9<#J{=4Xpc$#*5MFi$L&~d;F+FO z1uFddD>PfVNzoiY17a6d)`XnUc@-C^F40qAt7<&FUKVs-`uT3JQf6}tYP*{6zlT!Z z&C7{7>QZGP>sHFEGyUIlWwxP#FPkFrU7Sd^c6sRS-wcyoxX|NDmQ4c<{f-n7u3;0B z+Ph@Dngz)-)tuecL-Vb2rj!Sgr=lJ=!eE=JXeRbPbgeP6ZDFCPi9)VVDaSlLxG8+a zy9;$fn10iQ5_iViBu{z3FelMIcLGRNS>p3gRbJeIi?;ztF;__FTr8fxw2+tDCY!82 zIm=Ne)k&oYZnb(@^{=k`8|JvITjQJ>;>0bum=_BNw%F7HK9?S)z|Dj|qXEEsTtx?f zqxs5}R47-=0Xu#XI`7bN*luHk0E1J!+2;2Amy{x>_Lllm&rG-Te~FsE3ng>iK4sk> z-Gzs~x}hbV)U2;Y(byCT>jE&_k!z`Y^O|7JgxnX;^%tA-t5@_$q|Ja%zzE3|< zRFSvEwN}Kq_7DL|^rJ2*RPL)ta^;eWhSzd-3@Nbte=z&)O@6dy%rZ#7cBPJ}2)))^ zJVF_0Hk+M`M>Y-lkd*6q9SbP8uaIq6!P*D@v^>-WR7ifxwi=o{s{S5{CDp%gv zj_StwAW^Ffgtwf?zDv+?4T2XkP+Ft(9l*hK9jAi^IM#4BwWIEup!aD-LmL2&7sfFrCn--aF`ZdBXf_Y` z51KDtW?93)E}>^5sJ2fp;OGdNuU^98Q4hu(ihT@(MKxanVA7Lp+vx};7sHHYX3;JSIq)&g)uUNuh)Ey z^0kwnlm(BOG0ztTh(!`-wcV~;22=V{D!F*P>fEyjZHR@jpeCfDIZE-FG9dj31I9y| zG)a{9V(|tmyOSHHNnx5T^O?Z^Ch3^CgK}<$(Qt#>%Jx??gU6o=#b2pEY3KX!NgHc# zN;}D4p-r`<&X8GXYZ`J2ED|-h%<)Mb=7>TG6Qy^^&>rafd`wcwtrHFPi$l@XnqU61 z4!np^9gaGe{eJgi=z?~u-+};TRJ7j7WuO&DW3X7gI^51EVkOaKCVUz`JK8{cR;eT~ zjCRsVm}ZL|37v@;p-lSa#t(-xgozuBkz@&mGbuM$)-C~sK6yo!Nr6a+iB+3X+ zkK>>I^Hgh6aTYBhxXBgl6CdvY66zz296~wE{CkzVQ6hS@a7jjQ^Sh!)hTYLybhw^XdQ=7vKaLU_BB z{XIIpYIpwZ4xiyA2p~+53l;;Xd%>L)@ILfCvJ&2NVxc3Teb4pRukaMZu-iZHT=p(6 z*2dd8{AeMIW)IY|=;A+Q{2|se<{zj*8MP+bsU142_nrkE>{3}^iMxPzUV|zHfltI8 z{oH4SMbVkKW8)aR4!W9oC^UKM_Ro?o$a3Q0g?wmjOS{^aXCJM!_eVGjYtGJ24R+v^2uURn z=D`&e{=~-@HKTAvgipo+1&_Pn^7))H)kXm$^XI9aEPc-4H~a0KOB9`Qu>?JAzJ$cR zBvT6J%c#daI$-`}LWLP6k(zOVgYZevDGX**EI9XIZz}EMJNY&8|86s?-WDW|h;ZS^ zJz#1nDD2JWu5TWT5-tyy!k^9*yy$dZJ$uo4{t^ay3Y@AX94ZeQ-S@}v`ZaWZe+jQ% zci>g0(=?)i?@}hU@iV1Dx$8JnU(KR%8)M;^WdbsmPQf#09PqI-CsN_FQQ^|Ix>oRh z@Bt3vcdMRVg86Cns6C`av@tK*c*jPrs2wGpTFsw8!wra(BYN#iB^&j^w9!CeI*IV) zs5_QQ5LcbsY?>MM7AO(XChYI;!-ND9AHUVKEovtC0vKHsGdAj9yEIgo@J79-*Dg)C zV@+UO!GuT5t2f`&ZfXyK-+4NbDA?7X_M*UK9QFeLZMRYy;%K$^FfZxc0U}C)N2M!# z;~!AwNmyX6fxsjR0+5P_1*st-l!A|T!#E(ANlYgNGQq4H>t#{vM)G5-7L+ohA#0Hi zj{c^|v}k^BM%_y@$c0Bm3w-9GuVf|Xa;CKNd;*lXGp!?4vFF5L`&Ga9uHS_I0M2MY ziKM%$c#Z7XyN4FKDe~Cgkr|LU$6(oK(@|1h_ETJC^jaDG-m^Mu-)c2O0H!MSZwGoL z2q*%NLnydQ(URDnIh~IY=2&8~ZRaK;7y&`%rNuw`Sc%){vMbFaq8}#uVNB5xkS<}2 zdhLQ1L_M|4`Lk4>X6W@h7jY>Iu`&j>wx zJEdx9MjJ@4D*;P=W&{O@5MK&d8`lDg@(|QTC zr({qcnJI7o1c~cZ&?}!uvXQep8<5mBy$R;D6}Ph0l9@$_=kY0UGkVw=sHt1grgY?@?EpK9+vM(7^FTT`WOn?2t*t`n)W_JI@BbY~0L4?${h1I%+ zfL)^DR=>nOR^YBu^sCyZ&w{h*K+E6h7Ep}s-7Y;cE>$Ar|4vNoLEZ+(!L8^Li$20_ z$PkF_6&4g`WKkT=3(hs|X zfqpnR9`?^Zc6$HVPBT6iI6wFO$nN2t&CRPKp{wp#MQ~P7_l6R!XV&_c=K6b$mL9|O?bRq z%lM4R{1An>L1D9ZuAM3CsVtPLBxrpV;&~`k@J4lLC8d?2EtO~-C056Vejci2yNr5l za5TQxlw+Qr2E((1<4;L&GGMHTjPW8-p6oa9{di3VAZ#*15kyv1$RFa z!7zqJhlgZ(%vCowO;es;ub}P5aj>Dr)Yl4MEa{~Dgh16TX||HhxhyGh+)@O^US7}? zvU%RvU&9+|P!sA-7uhtPw*w%BeaiL~^l(eFvpw;JR2b0;YOki@FP)1wYXXrFC_H(R zDoYl~amS;zw44Slmle}IjbkP;8j~ z5hpch^qP!;NIEVk#07;)XA)aeZX_*C8SXDR=9!+=6jr zZ{OnA9}IJzkJp^|@&>Lu7bZTf8E@Vr!G%O%nh%&QnDcm%3U0RYaVuUD;O>%ezS%IamT^~*I`t2@Iw{PFuTmD~M$zau_=E+KamF8Xuacn*v-iAOu~bqr>F&!EfvXu57w=P&>#HBQPN_)zO4~+xPtt9@(FK%?j`g>6XY>mW zKOGJSY+#iCyRcYk)$p)W%w=fpALUtFa~d}ke&<)5W}ENLxwxlFNVZk+chY(E`4;58WAtMVC+K`sql#{yCaNmB!{~1vcS#BIt+` z32Ndg@Htb0hai=w$doW8b<>E8DJYIZ2o=~6P&U>>Sm233?jVdt>b~p31rd^R20zAa z2R`DAxwr=1ZCWDFKljE2Ov|9n1JYx3G$O+EdNVcQ0z2UsLB`OV5OK+Q0I$a~em#(X z&*+yOM${X-0*|f*9ZwWIYc^kOKWpwjhn^k+U3Cq|Du7z+@FTo@3C*9L!;6Kq^VLj{MGGA>Pq&zXK&Md{yEBJukt$y+6)lp93H@wB3qmRt@DV!x zoG|(YmB0X?5~P8Yvnb+1Y44i}$-ILLPk<+ccOADh%y%>!qWNGWo<@TH0(IYxuh|L9 zpDM~<-CAqpuf4Sf*7qs}V;Y*aV88X)Zl&PfQDKD8c}@#|HazwJVq$7P=C-r{Z!PlKWMl5?RTz@wSu?=R1@LzuA?_Wk z@G-2IikGNDHIJ;POC`|j>!569>_vFko_L~euty$BlSj|UUS;GGcN$XN%Z!QjSTYgi z3kh3CzIqONVXR8lAr@N8y<4y~5dtd!l(%yg5g)e&*v+{9u}nO_r{4`!PN$8)Qy#3^ zL{KlqaqmG6Npzd5meHzg%dl#c^rmCj4yISRfcJvnh+cWakaV=pHLH3mZ?>S?)0(%m z;vcNi)h(-D&eqnfdI>Zt?)}bKNZDQwYr4i5SyMtHCJ{!~wlzpCEgnYnUIC&sq)M;_ zi9*!UB!4XzUZrcSjx;xO_#rYZax_vhDl;LH%AHJbQshbHjEK~ffrcRhgJW*+j6hGG zKsk=Ynw1Rj!%7eeIbm1R5xuTlxrDHbl>uZ0%1w>)pp2|r5=%`qC^{~d(z>mdthqfG ze;YgUX<i-GtT)5#YLTXzJd zNkCXP%dJ&1Io{Sy-Gv4v$v!vSs)S!y*m^*ZO*sbLQ8LMBvz!Iy;yd$GKTCO_WQ8G? zbqwvz#zd!239^2$wnkkj>_aB<_5j;nClRlIJ$<@N%Mv*Grj>`YVhIS= zz$?x4eSO-rMKv9{=rb-H;zZMi)rmF~XrFbdvyAczOc%%IEqIEND_vgi=ZwXIkJwR5 zmvS67#kmZayn%fvUhK(LF*o4 zb5+>tD=;S~-rEIO3G>|O`s*Hf_5m)x*5lTPx%$dDecjtHCzIaKNp)Gx_itWEEk8uv z@j5EY-?zDpig`S_H`jky#7*Y^yUIW9RBcb&FcAKpUvVEQ^+k|$h`|Ju6$WfbfU1@4 zYvnkX#%gM3wnOO<|9xjCU9(nu5!=UEO5)u4o_l-FCvS_a2%=sufF6v$l;Z1TEJd1{ z$vY*jR{7ZKlG{?FnOx=uuhR?UIn&GvCH={eES>S_!w4Qw8dF0*XEH=?bW>K80IGQtKY40I8hW63I`S=2Es{a~Z&cH7R zPv`|Q9a4i_@KIg4O?0x1f`8J%&!|Nz(16XDr592e89h>2K(Z7m7)uSEqqHW3`wYDp zm`vPhaQaM@dE&rg1cQZhg9*e-U|=W#4F5CZCCpe27Qjc$kr_PtUav{58~!DQh!e)V zj6fjfMPAWjvv(C#@Dv1r3(C{ftsW&pkkSx)h-8{AL8V~TjH*av67)i2VZj`xRgep+ zk%Uy~um)J+47CTUKx$#+zeO2SO(88MccB9D#-Zp=*Q=kZ!?cAs(W08 z{2WC{1aBB`r83frqcPZsdAHPwOTa7d^WN)7!IXSM)=~m>eD|jwWdB+(Gr3au3-Og zc?VDsn`rV0p;cx6v%Wnjk^Hi4MOEF-Z;GfKX~MNW6B3*bB5mS7|G?f=4IO!Fk)QYA z8|_+MQ`{w|CtdhPxxjJwEgt*e5J^Xj--3FrM?&IUlMw|y zf|^{arBJTllBpasjxXU)PDjuiQ$AzNh4&*7-+mCv(%pc{gVc)8ggfxr`4q@oPT~Dz z;&}Qty~1JPE%!!a39p*XH#@JId#@w+p(}6URJu@WAD+S6x6u6kHN1J-gg4D*T`%=L zhXz6!KbA5S?;4GfC&$yluEQn`t;Qz<(MWmL82D_^m=GcHUW;((uDp?O*!u{l(Q_<5 zxCVVG@hCl{gzsXOl<|!?a%t(fvQb%G8vmx;8+ufL921E@D8|wgKtP~=3Ii%eoq$oM|KL689pY2XDT7;vG`1#f&IQGY2gt7g21Wfa$fA|Y9p z4X1&lsfx5xQh2SdUw@A#<7G;yUG|U9FFNg`lX@J&yGDZsuDROsrOO%mEU01nHq6Fo zFbk-1%+p?I=kPtEo=pRkMP19A5Ft0Q@OA9@6gCm%j?lN4n5?0?8Bmok;gBG>7nVrD zRDpGE3W>?>N-P{oN{AUx3Ymt$lyii5WGzZigNfLZmsS8FvW>b*!e-=oUgEwn&t00g zFp6%iASm1SuB8*asnW7@kVh9lh}JMz^@54}%LOiCeu+S1qA4=MN6T<&=U_zTr5>*( zaMW|-qH!4UG__{v1@0NWkqG7UZs)AuZC`ZGE>AkWPdzh6hU%F2hPcR>uPH@WU#o~L zgvXc)PxRF?%Bxp~W!?~K1<`J`upq#T7jq@Gv^y_hua2r5%ysoj&%f+{Ir((i>2=#j zow|`&Z9U~2+h7Z-S`*fYDbkfFed*$=KpwMOckAl@qNJgBqrqTCleq4&cS8m~?I=C9 zNSzVL?O5^L!)kp|td5Bitvtb2L(?8;-3tl4pG3MWC$g)Rs|({c_wY8bH!=ssrr;>KxBkPRkZ3T0%97c+jE<9Oo(av zAa!LbLy=l*^e(TCMEf6aSfa`=v_QMgr~1s!3hMkoYfSH4*IMWeC)ZT!Gvf55Qg5au zx7b@-cFVEV(SLel9Yz-kLUrJC1agEV3P=~JOA*}R>zIS-n4M&h(czbHe!(`%l8+XPO?Z5 z8F3()&t`ZgPsZzZ(@6N5J%2x|#ef2RwcUejdOKs>g~?P%q&eut4#8s^%;j!87aK5` z%D5k?$8@)e$PQ)rKDT!XRTJa$rxc>tJIa_f@%_<*`Nkj2UHH+n?TVlumh0+U+uF1Pd*IEQP6xlvgN~ zUDgI7GZ)G3LFZ#H*ZjD*XKYKBO3f~`NnI(->yj;lmJ?T!q>jW^=4p+f@c5&fiG}&sQLHTn>+ZnEk_>zcXxLs@El)L98j3qBR4(pi|# zUyGy$27VexUp|?m^Siu{4M|>;UFXAkYl*%}L@rfV)KkT(z82Vx^nTN3<-qz%VDDZm z@>oGGrsEPS=1R*bh$R}OPE_&Px&;4L)gZ-c4!A{(GvipY5NGY2v-$L}?pNIT)<~zQ z;;n&AYva)a+FA)7m1t)rTG=l|qa>j}lts&WRsoCRCYAhMTKz*nJf#1}r1Br_T3b)s zNECkOSDZ?0ldyq=s@twg!*Xd@SkVv>w0)>hIk)ed@606q_(w1aHd3rNJR5VQv5KqxC~JVBvNVaEJZZQbfE}TDrl-0TpP--$9U%3TAfHuloeiY z=+{5uz>^m0SHqKw%SHs&W2=R}lbo5#qt6*(Eie&w6YeGyEb~z%OLqY+LBtD~vskc>)`WI%?m@IW^i2NdyzZ9T5h^ zHcDAP{{TLVrJSA;f`^qwzp_B5x(U(Uo5T+)I(p1pqo(ZF$F~w zX05SkC#2NVv&TfuB2iD&EUfrfBlYXAwM5`UH4S;~I#GUIuVPB6^0ndh>)1)Ez`w$7 zgIw7}=-Ra&e>MDadUn+v^be1_`Bm4RsGKv>Bun`-JEvO7s?ur)W|n#E-fOlS^*(X$ zEdsKud}J0~IVBfyerDZuMU-)s2W=oytT92RvB*{V0*}(s6t8ENh@6|w9-rU^B!*VO zV;|b7lIs3%Y!*^Utp>hqe?oGP@-Fv5y~3BZ>r@@m;Tk?(bvh-QmKkYGw(fm^Htizd z7ct*1WpZv$4bYr47^lrSmb9SC_M;@p63a5tPs!D@Wk0lJ zvi4_)f2LZjQ~U`vF602GuFX8==bx_z-Op#o7v~qfrgL`K{H0;|bCs`EKG$ z48KmbxE6c;ZEAEDUpO~IOsIv>Uge$B76r|i^$bBPYE9ZYh}e97Yl^D7f@OE2e7qD7AC7VxN z2Ge?OD~V^slryIm_mj+8tVYPxmAhn$T2`1r<({SOt)y=awBtO6teBr!IOTLOb!G80 zlL=|d3bOFHvAFFi$3Dx_5)H8&{Tz8KVn9(p)5cfP)7Hy`WOFl0yre`GZQwIIT`r>4 zTAfZPzulEu&rVERU8*b1^UHGirlD~$_xJ@FY5!?X`fLeOmNebi%__dn4B6RZR}+^z zC0#XHt;(E@qg`6Xa()*uuQZk8H)Us19oNeQv3aKEM}0H4ggG z$N8_z>Sz7vk^avy8~+0BSY2-#ITU^8SKO7d0#X8`>b9#U>E@%fMM?-Nk@lggkeM+s zo57yio}_Hm|Gvle3=9JyP18KgVS<7t`vypCZq+eykNJnkBJUxU8NB zt9+?cDmE-{MUn_Jr$c?}+6rU-xFE4pPC(@2UVuq0?KRWk#~agLP( z@*vq@%l%K%5m=>hDgqlS!8sO1)#~o?7e5(S5utW9?Do#Pz0UCJU8h$+@Ns`_wK&XN zKv+9ZU&(-L&9m^eJ$Hj{r-)h#Zci7vqqq}d0@RhM02mL~j+B7i*&3B^qL|YT)C{z{ zy+Y27?aheWw9^3-VhNU`!0fbk?I0(E>%KvPSd>KS$Wdf9z~>-U3TpajfnW!7*l)bt z29&^6JhTWq{^WP5cO#>4t9Xg0w{{OHjpfnGDrXVUQDOSts|hz(ZoHOj?R0I?n+Sqi zGGxMq<#(ij%T3NvM|7@1^uya1>G(gazbUdN`ddWLGi$FTq{0_vt&JH>k-LuQ{%U*-7 zhG&--7bkU#?}92}eBs%!KU~r&Div#afxHOJYvb~-RV%R)y zu9~Eff{O^SshwH$X~v}Eq%prBAIG<<&~z|`lLgU+yj^1jo<+r*$dc&zq{noaU(yUZ}mn{2Dek{q%VLqH=7t422>@e9u6ZUb&js zv7cE@HtY5;)RTwv{P23RiDrkgo#pK3g#0_L{WT#Qa=*h={sHY(U2oeq6n)pPxGPfF z4jjuXx@2hLENS920o>JyT@*u67&LWl5s^uar0Tdu|NAZ}$x#%!8@fG?4>ol_4lnOH zBu{=z<1`5O_XF66$)B0{GMh-TSeV&`l2)r^Vs*xCrqRqsYK@vRgO|t?rkNE=`rsZV zyZrI>7(SymWQSi0+ZksTmr8HIxxFQ2{EjUVyoJ_@(4(OCUY6NdX>!6FjZ2ussMktG zaI!ST^vt+AdlKzwE#ocI9NzL9X*U|-WVPbLPwN?6r5i1lv4t1?{^7xk{?9M-&BNGk zU}Pg`pTGVcj*g)J>q|I1>ce5b-|?x5;3$nNKDIVBuflLCY@E$|T&+UCOv2_StnDnE zCu$z9n6WhX5FC5<-ooq2C5-a#0$$#M9}b?-Q)IeF9J%7dqH}e0$_#`5io~HbE)ZCf z0MFCGl=*Ono3+vrx#=S*v3mcL{UcNDu`oaepnMAR%wDO zl-AVg%h7_bK@hmQy!hPMr@auWB!x&4iDny63$W^r8VNQQ^n=F2nmJ6XAQ99i2@9or z1we^&rae#&QW!)3pJsDvD=ad}U8z9QaVWao@$RpAFpVlgduuJnbar#qZLkhUli@CV zbH>%X+u`}e^$u5)`SM+pb@Jh6+6?pI`exKv)b#d`CiBI46Hwn)bd(CupQn}lq-m8&!ouhYk10uN^+Z2cB0<jlCUX>W z35GK%AHYf!I^y-s0_+(}M__E}T5u?-GQ#V^36H*crZq`8ua*!>$bUE-gkJzsI!hQ4 z0_^2G-zC}4N<`mPY?^ns{WneNK5VTn?V(lWzLoA@Z&H8CDa4&#W{=VPZJDo~7ei_u7uI2%>o}2QafK^7PeO`Ghjsfpe zlYd@u=jQ691mRg1gAA?8dRvqSqdp zy4S>YuenQ;Aa>CMdPN}1v@JxYydo9HyPN<0W=QHyJ?x|(?jfLvERn;R-#j^D-~M&A zSnc(mJ=-JC$mrM5{q1JN+}VuZ416X6-y4Y_bVL|XeluFT!dZNvj%Nq9aD666c3~z? zzWQ`U?r6Z_Ir+1G_TI4to%_Lt;A{D0WjnX_oD%s27MW5>g$DAi9g2k?z)SMCfX>Ni zL4&pLPs!Uk*SGIEGTCKRyvxn_YzGec?3^*N2`G8HTsp42&ChWB)h2M~3qf8S9lbhy zarFG9lAK(L4LKK6(mFZ4Ag^DOqrbc)uU;RKS4T%}In{F=$~ZE=5MssO^m=nwEW%0G z@s~ZhjAu`HFDF@V;`x)_(&hs0B?*Ui#l0Y>qYva<{nq5!Es+n>YHsP@(PmYPs~S-`*5 zX*BZhqecVU#|7EP;Dan&PQXDxehyjzhj9Qj!WVw%P0553mrVgrIyK4<=4+H*O#*>m z!lL{X6WrO$NMt%rj z1_n4GoY~8Q)qZq6O7_8R94>EBV>7&&P>hG%u^CH2G;jB>G%6&W_z4w9QuzxNF52s^LZJGb_x-^ z6#mEYvxfwPeVr)v)hERjlX?4$-iv`PvyB=Y4N8r{#C{T|=00iZCB9jX?}bZdeJ2O7 z3b@bVI~6wCx!D8s8NI?$>fH>UPe0I^9eM)aNug5;T`$m1TCIf5tQpK;xeIvJirjy2 zG8%Ts_~yg#<-*2jqFXLt-&<__xVVkpl9#gN2Q5-4$UFCcr}q#&xU= z35%cw*pUZge5MK>;;&gZLk#UIR!+p*cSLnc0aLVsnEf0dS>2^{oFbEz>bNl9ft2jB zkY?YcEU7V%8f_z!VzZ+0uRgJ~wyh#RS!?JMC>8R&5ehmfT?MEkcP7%Y5gr`uC@#c& zCO~2|4K4!Vd;S_SO6B0T5fOU7f}$8KV+%qCk!TR8l2ns{YDJO(B-&kz+|tb&N^Y_Y zAr(UrAXh;cj!DeG&wt`SlSwFuL|*&{u=FQb^KXB+(- zKqNb>>P#+bnM_~{6~TH~eM!l0Kt0qJEsI!~C9>)65K@IfJB^fpY&m~8^CmCPAemWZuM^`66YQ$9qB_vqnG=NT1ALizDHCOe9P@$QDTNY|m*+M#z7>5vxM7Vy*4$ zcVBHIDhs-3r*T}G5LywL!wk^1H7YKPe&;GIafj37GZRBxhiZnrix=P=%?f{d~(nuL*h?-a#cB776N7-hBy$UV~D)(F# zsoZQ}dVsXiM!tXQ+3c3!H1#2n`2xQbs*`gRm3&xUn3=U9 zIXedd@_9OoiJ7PzC?}_9*EW3XsB*e=RjF0d{T$znhM&&{m*R`s z8?lkB>z2L@*Z;D(L4iL+FS`4`t9nX;ItpQm>3Z+gETr#{57LoVZy?iQHYW4G8%}dJ z9V@ENq_;8Wn%2bQDi1^3th^s##z-GhaAzeA?Pfdw>K@!KS&J@LVnbvvG8MIR7?;N^ zAT-8rp)$-b>^s=R`b(H@pUdKkcSlPFPYAm*>w^X!>%9ck5td=bZo{ki4 z6}#*>Kusxk0(XM7(0Wl>xaT`@7~9mLFL%!Tpo*9Om{78F9b%I5zreEw+DZcYYv^J> z7gdwBO~-sjB|~p3--?dZZ0}xi<E4GPJfKu$2*2fP7Xi~aO5_a8wq2of_iThdk+cc#C61s!MmbHA z5Y9#_f4xv9%9cR=#(7B6ndGCfhF9(O(ZQ?s;cJ%&^z;m_bqMv#s~b2zhW78T;pn&x zN9}gQ9*uc`LYYv;TBqv7^F~~cGrtui6VJMdnXkN3oSq*izBge?)4PQTu%#b0T=n0= zwfmjJi+iw-fhY77nQT$LP4He`hcY^y^eR86Azh&|iJ+-)2wVXJV;m#+F{8*RJOma| z7RCeuhXuX?gCrvJz<7gj>8|yESK(qoae!NlktsY`W{J`Se#RHSTq-3*v z#k2p@%%=iEH9v;oV1;__?CUj3sMa{GY{YVlI+H?KO4?{Z&r&qMnJ&geFI-TskQx@! z>qczS0vV%EciX~?G7*?E0x^=CuGbrO`>QjiCr5Ar4~CuVzxv%_=kMF=e}`AMmz_Vm z1CxNUoO>RMu!yvgS5GDZDusp2UXWDEB%5sX^&O{6T_t7(%DxWBLu6j2_Uf-nIb{l> zBokq)gh*at;|up|-SD^+l7dtw0(H>y~sM!y8&Aiv088#v+mBW`lMQ3t22RGgyuq7gS@5UBn*&O5J2(_>Mm^KgOQ5| z2F*2-0!0lI*EhEfT2rEX)Wal2fwFeDJW!l5rJ4J^@=;AGon2X$Mb#RdpQXY!vWa-s@HWkB2B@#gsWeAM^A_23IkvrrQDwv_(AV%f@M1-M0%)vL< zsJu_-s`G#Ppug2Jz%_=*6dpZBKTY@gKbdDs`M=IG@O2#G8Y8WWNpL8&@3oq7$EwJT zJvgPzD{a!O#R?<-jRK(ba|Oymsw9qu)F$)RU~AXEW0Djk*+aVG+5d4eBkG`@nqe@> zPka6K7|m~{^FGmpN0cR`R0T9G`6expIdpSd<=#Ar zd_y3R7P-lHvt_rxyTde61n2N%`gt_GnhyTFzWi%?c6~bdV>mJXn}a_*52GLtR0?Y( zg^#9!vcUdBOfi#eT}tZ(4-x7lDPP&?gl?Fd$;Os=#^i=6n2RI|It4_!6-uM7G^ul> zsbURcER+=-9k!5m*Ilti`-kHhhl<&|6Fhh}d9mZQ`2r{HESh4L>uEB2x#RmM3)EJ% zs<}cWML>al)>%e z+&vEM^Sn_G$Gf-H^bd##H}uj3K|s*RfzB9ntGv+*dtH%5?;|n z(nl5vW#`egeE^s@SGr`msr?P@S6ffxMihR}uQ)5Eih&S^)fOrsTOgb5Rz)Eqsj3R0 zXks5H7LM)COn~f)|K2k*PJB(cl*jr3?3pv)`Oam&nVkL_&*GZByIX@@82+>HzmJEZ z?|EX}9S+CcfC=#hJwNoNAB9&jhJHA`;LO2cto|s|7A;k)2j2#8k6e%;{G5!PIZWa- z;!9A|dW6>9u_=Nc8FwSspdi4J5B(TAfWX#esF4v*S!*lzFWrGf8YC=`{Ml(9HW zy;F3gT^qIAv2AtCj&0kvZQHi(j&0kvtxCs9CFvNQWas__` z16DFv#7Ip?owT{5HAFSQ@dBlg<*vBUlK0p`L+D7bg0|^U4(qK>&D5wCLii8)a2T&TM zX<_w59$gxq9D1??UGP!8m{=K+%G~zDz?V}82p(typ9sUNFCid*GWThck%`({D>3kU z9AvICx=0f?MD1Ovnp(LFZM7NhR8^0d_)bvV1N<#-s9;LP0tSH^(+OWmq$L@m+RfrQ z7VJ+hT?&fMR{|EAG|@_m*;%~uN_=BGF1n)0X^HxwbDZ;_NFkm=Ge~Ewk{?Ufu_yyS z+b;>4OqqIedtET<;+$<7?>!P%Roo!%B@MN9_lE~06Iq2|L+FGtjqgDDosavsyPLnG zk6zCSdy;=O!WG)$T0)owOB*10ofV;Hz@Nf1jmI{7RM+bH?LN5K(n%jKBY8b9j)mYv zvnQb_24XM^w`quyHK_R9ltE7IiLCZ%MmSNsfT__`l6*G0H4FMLw#2G6dwxgVIx$!| zJ=*g}C0XJsHO_q0;*=(RUtZD59<>eXV(JMuL1`QNnpXZ#0K?O#GC< z<@QbSo}=R)5NMif6*0jTWdw!WJC04Db`jF!e5#hyW~S7vP+)hr#yKhC^GW(K9WkW) zT>Ujc0rHe;GW{}dS^^X2kA4{DUdL{RsT@&b$b+7K1V&ED2sPon;_os~{aMfE4@3@yH{Ks%*ZW0_ZS8qKQMnxTy#uK=g zB19&Xog}+eYEr(n8OhBep+M9W<2j)0u zLBr#93#^{vsy4;+szH?FyS{c^kyF~NI zZGekgO~R1HLMfKFKPn}!yRDF~n)?OucmswcsK=>WUr||a_#}m6 za+O;lJ&X`RWe#dzKl!dVrABCT)ops@k~|YQzwPP?O&tUWLqnlYiy*sNBKb!DKM zRpb5Fnf+9=aHA~E{s!)8wAcRaOod}<3YLtMn*VC{QyT<#EJv%>Q>AT7a*o|lUT;FL zYJmavbg2D@k;m8&HEik{%Ma27&h1vgf+ z!l>L44q<)GAtX9?ph0SH`Bc`OrFWSFAzkjrd%>kLl+oNhW# z@peNH;(8>hM{r--a! zR>tW?lIO?>6qtwF9EiQ3JloVya+{ zyKe^coLN3t2Y6%O6(4;S;fV_+!wOquma_4I0*P3u2>)*v>pSebKS}q0y4aEC-&X7-O$FHw!;THHTTYjkY@h}< z_-fLceT8!+jOUAmAbc{5z82mXXl@-udWj=2l{!Ndc0|o*7v5++RA@o$MM>`+N*#L* z%K|&b)?VOHo{U%iy)WKYL^+*M^CH|xzkFoU9?Vb+lslBCS*9ejOqY|Be|yF%lJA30 zxkIHAGw1R6L}wiBGC?RMM>VKLN@^9ZR7s~myl2OkMrBe&>qK`n5Cdyum=fB|d_WbI z8n#0t6fV-Z^)CegC7m^8RJLqb#m!B=&z`YcxN57XB-^c(Biln$kuePl!@QGIjJmPI z!!+_Ld@lRhiU!Kva6bRHZ%wt!kCkXy2O8LiVB&XI?L6bZPU7prenj(*Iw zSaoi1=^bE8oOlvsLA4X_36(6U&8%(hjej5yj+jyyNYo0W;3XJRA*CMUt+D%YRF3V4 zDI%Cbd`<`Gv4EGB*O&)YJaCwl8Na)GKD`&3zxnMhbEK*yEv;Y(^<*i_(seHWa#oM8 z)jOjFwB$1%xj8r4MW=-q`0K+S-DttQrgw;e#a`%c?y`z|39!whD5)IfE>aA+2ULAs zD_#GTku|9r(5}&E)~wAu0bp_ZcL$mDKOgVx2AOsGj9rp%Wed9^$}Q7J7@3B`@MDdWXK6Qz+%VvIj5b^f01cmJSDF3R1I z^EoT*fgYgW>)ZAF@o@6YJIOP6Z4c#cbXR&{P@WPy-k6;)PqD0$6fN90o@t@$lBAWQ zP&elD?-bi!iAFm@<9Lh86!%n^elQa#JvW5MF46ES6uVGN$f~wxAu7={RDf*GD7l~q zjU<@EMGaA6s^N}hg_1saA|rVo4FT%obMaH?>$s2<(WEz&g+S;T*zNK?CHr)UaCF^? zDE9BSXfNX(k;S2jTI=*C0C%ZNF+PbfM%iGb&Z#UIWyvfx#-z<$Vr@eve*1n|x+i@& zUG7o&yFuP@JcZ|zq<&x6OhB0tY@M~Roc+@T<2S8Jgf4tk8nDF2QHTw+P(0$A`bbpz zMyCo248%&;j0!P!l$=nU3(y3W+~6xGT(~j zAA+)6sKZSIfxNEV;h|~qukHZ45?w1~CQGLfoG?Gk7vFD8BURIc1F^E|#+!R8 z1wlMpo?M6|)Gp2R4jkl?wq7LL7EAvPvbD#R`t4aa!nB@Vx5A2P{ao4ZW?mD{aQOS@ zBz~(})rE4(FAWblT#fegD&gL~J7J;T=@t*Ys-f$FcYKlMSz-)XYa@phdzh8L6Q&vs zKslgcZ^K5>Em9d)WH2}TVox94)!bs+qrI~WN-^n0Y_Mjb?uhj-WX=N0GJKUur;!aR z)#6j%@qwh@@Q#h@xcB(KJ~baqF~V2AVu|CB$<|9{`xZx}9+yIa9PnN~iSG8SXu5K- zGHq)u!|qsiS5k`CB^eJACIzj?w#QxZo-TqMC-ppURfLcqbE5>IFiRlB6i<_~Ghnz) zGp-$;btQ2tqO@*CQhS92o=jfn`aygj;`HS5bE7(Jd!v;MoRKkcy%>~Is* zw-2k2uRg9`-6Z=F57r$+#!KLCE4-@(u-cSUk-N=!*=Sz6LBlE8;O7&WcuP%R)<<}? z%0CQLTwWV$8MN-}(qx_-Bu^QR)%O2W{rb-vI3cAiFuHVoI7=#QJaQR$;gHS--`nd8Mc3kae>kq`Iy_nu3b+7aS<4LdroQ1i2@2&ofuX z+NXmwcce&^1yYZe9ZMa2T6q1&g>Ger|FaEY-F;jCu9~>d`LNcpQ!tsGUBCX?vRt57(|Lm{SP=9Fs%*nTW1odP2*^c*LoqXLElF)Y)ivl*k`#5wP8<7d>a~zSh{O3GNc?A zM@}Cjq!ZfXS-l9c%M;-oa4L~ZA&&j^EwWij07>|uu|yWkG#b%@Md?*uafR6Dc9*u? zG1qwY1HaNJoZ;t~o%)?q?Q30uu0%AHry;;qoSR?3-}kip7fB-tm0v3*bo4Lz?*{*9 zf}C>wl5JY>9q_NEx!iqCG3QY&R-I_2*KB6`-RN61Rr*b~c)CfJl0IW%M~Hu=TXT1_ znX~nN%u}S#2R`4>le(SDmiT{uha2W+M7FV#6s}9GJ=8 z9z*Wm0Tb7?;LtGLQunR6^O`%?{O@g(`}Jqj$Me~XiwJA*iC*8qb#YnSa- zU<(`xj%L1&^7Gz~uHOv6{jZG+WM_*{fJ0L@3_Q}FRuoZU_Ad)0d3ELQ3-lvw%;WNUJPUXP zWhF25%AYJmfA|9n8&|J{Xtd&+1h-|PC4Rpeqy|^Ui!3uN;(qWh#)g-X z+N^E-o%P^9d_60(`l5MPa9x1^BIJz=M~XyGO5wkOM^c6R%S2{b;545d`ONH%zU9`H z)ENg{WGaTVf*PK(>HY$JYot?&md?>kqOF`t%|hQ_ufhTni)qO>24&207q?F{ia0qA zG5cy9oV?uk!FL?owJLXYGL}MmU1{Sj_X9CewFw`HFb;;i9OP&Sb`GnJz2erm2N-WV z#J@(PgYM*^r_U1|OM1`qIo17R798cf0`%bsj_j$!ewgopE9i@NpJ7TRJ_o*iYAFqg#mcFuu1VIMo#1>Yeipl@lDq-P6vu+I@* zDn0&|(AJT~&(E;+z{j-*#nYI+(skO-YWamy6B!?J~ihYn+z8bu(HiV(4u4# zwv%{&q4H7%!dAg{P>O7A(iUIo*ZWZ-@or$VkDNJg_5n1YFTpoyr{y03Az++Kx7l01 z``uRYd(wvC$PQXh)`Fv!%nEtwWT3-rUn!5HNl8j-GS`#_LvNRW3aV{-t^yq<*wp#+ zD#E~IQnoP6+Uh)y7Rp*OWAs z!r9gGxG}j&3z0}ExCQ7QQ_c=2K!N)-+r1ln^`m4ON0$d&Z3ilp)YgZs&YB5eHj&e} z-XQ_il>S@c_W(n&m|5LUN2J&dg{(*RL{P9n>GEhvnktf1ncF7<_LGw7 z#GJeB{qpo_Q#|(lp8X^)b{V{qc|I4Dz$6&Inh$;ldyW0kgjjy%?V!3#jgbAL>!8vz z@V{bv6FEUycI~Pi=X)vLg6L4y8YQI-*9p;Vr{Rpb*UT2I2UA8O922~B-6TvYyhQPj z#tGpb{J0nyrAMdw!mS9Nhe70{uZHNZ_UKY{xO(yIWwd&6dfg0+aapHh4dr2e&f(w) zTwI_({7(uBeu6kyjx?W98GM@PrEc%z2iv+-7d7(|foM`Y(;!O}>rs0W|M;S?`i&;u{U_mPP7ikG}axt6%`%2$@L>9F*B1@fIc3 z0nS+{`vxTOcL}}sl|N|8G4P{3lSJjkecw+JDA%{F`|GK{1@nbM!6_t5-40F~{jYIUA2CgLA#6S+pKAu@om2ce@0xIptm6ung%@-jn&f0E^-nE)}EFOSi zuU=`pQtcyea!rx2j+4ud8yZ3@ZBr$LR+jsj!qnBk+YN_>xJ**(+J4@`>$Hxnw+L}a zl`8f6u4Qg2u`d5~r9#kEWSTYkesuhDn)tz{+CMlWq>zriLdjE>n0(0-o=FA+5f@f9 zPY!6eY#BI)!qK_sJx?NIVSQV!ou9vY5dKz&MsOtpazL zYPN}Ao?QA6f8~K|!rusQrR5g0EzFcLTLqHkyN4)Azq!T@_P%_tkaLe!sGNY@c_!NB z3O|Mtrucr~edop3uk~5L3CZQidT?zhD%s9Y^ZiPN{2l;}<*V^$OO!;qreqc#I(| zmFb4F*JMV67&*ipX#JETu2dDdX{F}$7&w6HA)MIL3i}dxfMMCaoraFNT+j*QG*L?F z;dcp;P`h@$Hoo>GFa9&!90m+c`0?xo{^_aU(F@A`S-WA|dR5nQ1`K^mISVi4tnGBR zBddJboCqsl2CcdBY0cAnSyR3jVmbT?kz}B(lg*KrKS=25_i)TF$LXQ}Ope(q$J2W< zo{b3dNP3sv#m?aJXuw%4AVDvo04c?g;uORP1z}d7>(E`*K@iwRv9c!bmEHpFZeL0> zvf=GAFuqA69fC#=-tWyXOMaE6Q60pM)rbfIKBDZWZWt`m^ zFm;#bu$?Z5xS?spHUQxMhOfz))sUcNY;X zSh&0%BV3ZK=!VYl@A}y!t+lWdAGfO-lPPIS4u^|J(qdM*W?`>GpSY!Nuk{E}eMqil zP#thC^`|r2Ep56JJ1_Ws4FDgPqpe4t^jjBVZ%e$_we%7zKglRW1aiSXV>cx0gRS6g zXC0|Q&n8gvPX~y2X-76?x2I@6y+QeMP~_-CG#_uxhCb)=u^4%QZ<@?0%U_?6`)}2o zC|p_>sv@IqR3%1}vgP`pnC(X8DgF3= z6TNn&`~RO;)SiJ;3Qen7DfR!nqNH&o;c1kuvXQHHj+V4b+|79eyq?Kj==eV=s5qG2rNraziDsugjnbo9W9?}RSy&bQxFNHVqD7m-O z(J?~^GG~Y(N~t_7ZVY-fcX4s+?QBbmipb9zs)Q-*3UGwf(OLM{1Cpa7w_(d}Gxy&p z*{(D;PU@lUG_C`ud{~@_G9M1Dx$p_o)q7YIu@~n1xW|(Wgm9Ea z$tVAVsJ->8F-vHsJ&_& zF&Z{0gPdU%%9}M6`fd^nK8e_m@rQ0Q@ zMZZb6iZrDe8UrO23oBJy3m0#+IP=yX6Sd~h1b0uJ%MQzI`~Y~1EEo^llOgS2X(X?< zzU5@E{BG8=wdHaUul`}Mi&y9rQdPZj#HD(WN4FwFwcBwU3%|N)>np&2?(wnbU#=7J zS>WRD?XO-f^4OVAXcUJiiaYMcNHe;Lzd1@O+{Ia|4o8By9P;?Wsp54mtC5iw=v=GI z1&?6zyd4F1kDIKI7xPbWqSLC()V>Y__K;bu^i0oQXw<;-6`0t?(cg5xRIG@C8LoF} zFlz}rS}$@u@zkwcaj_gD!)jB}EApD;^CCoTKV7UTruoq)0ZW@+3lvuS%v z@e(nF@(Qto2MWlxPDoN{q(+^(|2-2VC)eZa|M!hpQkEDR#gRx%6UBEX=*)fvX?4KhXJ}H+YZtO$SOmgrahZ z-s9f+n@4bSUqA2|n0;x4{#tN>rPh~{6^ep@Fk62VDh1$221imPUSXj3 zV|JO7zXDerR!$^EdDm*yElh9ctu}!}GjcveZ~_`lIXSX)s+v|1R^P3wAMGj`l0()( z^iz8SaytkUyGRANYUJc=NYMw@mj+u8u`lm?2@eKcSO?;efXz;J_co9chH>+6DGlDgBGguLxMZrigzBg+(mPScBP!vr9gWWn44*lOhnKNyVW zABZH$iRD5RJhBpqEnRciN%2cu^i7w(4`pzjb$m|F&BM(}1iecA zOYStDU0zM8J2f={d>$VBRCzWeVWn6-%LsS$hV={P6ly)RS+`K&zxu8#+?#{fy@l(a z-u(CRG(Vp69(Dd|w^`jdGxz0FmDUQ|YTTd>zpVVh>;VP`)3iR||{+I1(P4IS#N#I)g>EPPv?y zPd^!@1N>Ue2Y9wkENj-0syGkdrbLK`@mKfU zygbq&JGNVR_7iFJ@JQ3gD{u!(SrpkV(40pY)UTwl%|z^Vx}Cm z1Yn0drg3#*x0v_Br1_G53HT9`yA#`2#trU>qQq?mTP<6m$sUG9-rB^S6lJIA;(af~ zy?Zkf9{$QRdg?mg@+s0XvPGZ3#wz6cnyzgcFM|0f=~TM++x|T{ij?Ciy=|jRqVl$} zR;*{Ed{ac8rq@90;GNZe01_Ol9%9wLOS^~7r7CJr*mXC4a=*<>Y1g7{sw^rFz(+2N zTmrbuuSCiRCnqESm_{!`@^=p&6KCr&y_@k5GT*CcV)Je4nZ;mMA#eGCoq2wUX?)8V zEJ4L$&Yn^+m~T>grk4VAYa0DqRvT68WwNt?TV(0pX`Hi9bBa<$+OzX>_=m1WzBfU+ z^g?|`u#Zy7IJ=7=gl8@p?g)x~6nubIv)1+BwbD_y@TD8?K>F3u#sl=BfEsrH_4D5$W=>!|TJpBj)J^V|7qn5AZG%fI zku2!n4SkbqThvslxU$p^`+rDglbKZGvOVEAL;B>OUf$=OB;Q9L-UOTLJ$-~H!v~L{ zzF3J|xpLT1Rl>uQs+KkID?1yFko$?VbWH zc0)uiS>RVu=~aJx=aP~4c!KQiBLZGy=y`A4bIfffe2<1M*P{q+a08(Q6;$aB{ZuJMY54iMKU#fgx@aC3}C4AxvuF%@Ro}5F)6?vZB zEe{ic17;K|p(-;;fqX$jada?FaH%#$_s@BlTvKp}jv-{eC5vm-SxsoV5IGUf-!eGKg(M3FpgT@SXJV}vz)m)_Q z=4cH~6c#|YjI;i4Y%;VV*t-iM# z=m&)jta{gQN0sZCJ;{57X^Z6}tQtv2JPsXrK|0gLSN;^35Mc>nC7CM(qyC*BwwU(W zvRoS8a_Bp^nqaI&wwnAhZ9wY~t1<#+>E+)Dz=5-`-y3_##h_af)GM&mFr0*Bf$U`H zHAvD}!7~OmWUm3aP~P>i^mXMt`yzpdMr#J(aVnK54r4%0y)3C-$a8`Xrt6IP-6o-nM48^1ItbECo`$Bt*}Y z)+*Zj`)uyBcLTL4y>C@>jsk*Sb{yW>qqig9b%5uWzoVDlPD#Y&&}AeC`io16?nO@t zhLo8+-v(=qyj2dN(;eSnaa>x&mItR9O~u#g>Zrk==IZ57!Vu}NyC2s#gsWAcXL##u zmOJTjc9S6TI2^vU&;|CK8WWt8P#K=}xyc#5eh3ORa%Io=a|nq!)P?l>kXy}kwuPhASL2G3B*>JwU- zw4ShULTQ_n7#yp+5-y-;G2ou6-W~-g)( zzgCC7^du}+xUD_n@M@IUTb?cOv!#UN$0mcrjW5&@bA}C%zb3h+#-ywGQQv7#%kyfF zziC)WeX2{A;EWemP`4X0rggUXp>sdpXYN@t05^O#ryD$l(5ob05cYc)485xh3*2F& zmjlMBV3uo*CTv!_5&);SiIJ-*R=#Q-PLssDWf}JoH+=L{?48rBf~$wX)OsT+1X z*?#xmatU4wN0g!#->(L@j>~6~KmKIkc8D1giIqXW&AcZaHn(x)R1Ni!c#j7!{@zm2 zlhDhPL;zag;HfYQPz#c)B<>@;whqA(u_s%%MfISqZOfnAX3!;&}lX1b=-S_WH zvm4r$>(;qAlw*aqyaU_cYsm-$BF&TjTwifEfQ9rMf4Z?E`!XvPKN&J!gdp5WHC`DQ@Xu zUTRTUq47)Q4jG2u5ySg&=2y9TSHX9O3;HFCLKlY}EoX(d&z=l^ZlC0MNP#Xa!<|_Z zT3eiIIC?_Q?(Yo_8lfR(&vv;XbVLZ_(0r$_Jnp%b>&_oK4a1$*A)qxhI=k@hIw8mJ za;apWU=9t3`>#0izd-LE1;8>~4pgR86hEE%KTn_a1gw1)v#|b)1EgFQ z-8Kt`wRkf>C{oXmJux^(XPVvz*I?z&*@WRvskn2OK%=pE6^MjoN%J#8q%dOolSW7? z6*AIDt2jKd=4pgrhfTR>b;7`x?8*t#E`9=DKni=jpNXFXsPt1;TH8t~d@gP8Xf%|W zD%jSa-YHd9+U(TgROiw~vz1#5+UV!$dnUIs)dN>32K%%&_x4oBlglb3^pR;&S9Lb_ zT~CL8+Bjo5A(s%CkA>RLX@}wEr;nj*4mnLjvfl6RdQ;GC2hhV`dxDc#RmA<;Wj`F! z2kyZ~C0TL)-gglwlQ3M|_;HvbOP`y3Td^YAyJ{_TJ~)9Qg~~G1O!O*^kKx;+Xi0Cp zv*YEgFKEyBZwZ)suZ6*VDkq_M#+#P`0sQB+*>|mPU+)k8NkmETaka;tK!F&!AU zgW{bFVWlnBX3N3QC7~9$`k@LTm4)v<{o?WSVpNK`6x2P zzdX7t7FZ==iMeK(HGH&8-%4FEcE~ZZiq`45kdWsZhY6V3&6{~;L0HU z!nrH&Pw^ePg1^LiDqxt*2`uJR0(pE`HgGU!5R3VQC8d)vKrwt{@2=NZMcN!_=P@wRK1-|MyO z<04K07t$PIog(;c)QnJGq447gAvd=TP_k>!xtyZQv1`NqM&nhxasxb<{)#&o?!WPth2aq&>}QxV#b@XLo##&Bv-|I2 zs0^eUUtW zfkWj&v6JbfhBA$_zdlR(K4QvF%-ynXwYFnN4i z^nAIxapHi`4*?QQg``SjQ(zjYZBo||prkT{u9I&0F=54DO;)7X4a_8&xjG4ggmKC9 zHN-V%#!#vb{C*-@s!DNpI<}=Zw|6mAJN%>~ zro)=Tn2xKqxC}Anv!q2ovBnO45CTq&5DG`89Ezp*3NY`I`cMx{nCU~6n>O=^Lb1qd zls4Ik?UW-C*}8!Ti23=lLRl2SJmxvZ1JsJor6(T~=O@U(J`0zFaAMflontqSU-!BE zw$*gpqMaD>?c!Yoe(l7^7HKs4+QigraOt5p@q%&l-E`;zKVLdBlVp5E!1tF9q&KFD z&Qcric~DtoXDW>^(=Km+de=3~l`-8Oj{3_fwAl*ikB};{7TzP9MAr)xCoCVD_D{8LQd#g`E(%|8N&r?B-Df)$1as7wwnZ`~SSp1=8 zlN#jgyg~U%t#zftN1jl->ON!S@c9yiB9JIAMMK;xONJqH;mM4P6mTBEJ)%$CNy8ut z(h}_Xv)9ALZ#e*$S49KIhr{aAMBMe-Z-*VJ_M^>A;@Tj2>N~J<_rJOz;Iw`N${Zdi z*s45Zhm~Ans&#hOm6PH&-3Z%=p&%+rS1Nod;lBtwTl@*m^WDqWQGKg`?*5O3shdy9 zbt_U{9-9Fi**?>M+rA_(&XuRblcxN}c(D=8Nm)zwoif(yF1|eBbTqT2f&2fqh>RgM zl!1fx-D#=cz*E?P`iTfmadYq#uxX~Iv`Fry#1SHettu~-sYl1^i)$fWNu!{1j&H)X z{>9qvz^&fH>9gzkLQWoc%pB>r9DHrgGigUp=-!RP!C?~=R#uYeuQBR zj!WCcxFZTzd(^fC0Lr{$(u7!t(bhsc3yRUYFWasE9i{J_nZq~o`F#yD%RSAV&mVzG8i!k-YTL@Ud4h z0om3Edhq)jW`GW@@I;u!kLV~2Z)yDsiIS|M;d7MlKUA@L@Q6lX-fpvK*&KU8SQjXe zTFT~=-`{kzahRn$7yfJ*Crjc{n1pkSEDs+d$d--z*V2swVg9=)Evpidh6fEC!KNh2 zF5zQRN@Ffjt?M_R+eSuKWNhA%E4dTTla5{cM=#kG-I0kQ_ix#oPh7vIT;Rz(qbQ2T zAZ1}}TCAc?4fs97p=6eEPRi?N5+$@;mmCR@zx>F^O2FN<*qGdhr_6|&1;rzQHhFzH zn$@a79LYo^qqQ|tdR8y~pQc-PXUxzR+;3drag1&0pX->kv-exx6qI=)tmA2RZ^jS5 zE>72fv0lF|)fP=W0c0$_KHk@e1x|0P__~ou?g(cJ_HTw={e4(E{Z_68{0HC)yjvwi)(qkzH#08aTLc35fLZFKY0ckb)7zTsl-kabh?Uk zS=`AhxkKR1Pc^^_+%y1FEd`C(mxmv;_-f3~2QPi8_ARHlli3%sQJeu!fqD!ga^N0( zTdX~s5A@lO2F?y|+fL=5nB#;sztyknl=l$93E?=N6#h^_eO6%FnJ82lI0tCQ1^kC= z{oiRz)7Bim)cKa__q2tncXUpxvUkz)H97)9id9O zL9@enAyCw|`zfC1xt;^nib0=I;X?gCLV2E9wN6MT_bd!98C)tOQeWdgLYZApuf7=T zlw?Jm!J5~8#Euns*SjsN5Oe_j4AuMTU_l_VS;P0jA6;?Poh+qM_RS}k>gFejkCEln zP`&0aZ*CW*!=(8ERYEsQGHrYJB#k0Y8-Mz_E`j&V&7>lCY1L zeH|U0jwdapfl+HfYmkzXYkrD+uAq>_&HF<<#i-rC0ai&lTTE&E2Rpv~bgKy51tA3B zZUTP1>1NoZ_lML3n-(=48oHRX9A_xu@BH!1T@tiNS6jty%!=$PnFcb|ZP??a??5%PZTijpL^4t8t{bc<*QhCJai~OI)06OSKhVDf5S^EVregO8()5L^n6rGKzib?A?9eRT-Y zhE<1tez1jAR0+Q;UE@p7pkfx~dBl-CmFfOuhZB{TN4mk07@uf-sO%I^IXEx+rxN`D z-#R}s^LWu;4kbr%qoDE%DHMJFWRPoi{U>U?RZZsg(%OGHC!u=Cv_H`1`yu)NVOTh} z7LCXM!>~?RUDiOgtW_by|M!qciJB^tSB}`{eC?5vkHhYoi9K`oWu7GM@A~cUoy0D&`xp5}u zj49R#Ygh7T#|YENJCpxpDb5tXx8K#W|G^$eVK|~(RXo&ao_XiyJZtP#L4q#IK8eTL ze`z^xeK~or1PJ+kl%Nn*n#18z1fL&f$?*vWZ`ZLLJy}DC0S%}5n7rbJc2u2ArT!S< zI2>NB*dxw3+#C=(XA3bby6Da*^jZI*(oBdmQv*3?9vu~59Jhy%|Mdy_Br0Hs>yU)( zyf0@D%<%rQfl&)-!h)Em1+!g(l8nc}c-4|~tc(i}eK$V>qrf{r>V(iRDUfAK8QDj@ zZ~HwN_f)@kezb{JzK@9?J&kc+#Zyj$EuZpnK@8KN8C0=PmG%3Oze5Hf0W{-vew<;! zHek#Uqz;O=3h3;aJ2clsZffbuIDD2rZTI3FvOvqwbvP&s-|4C$P#}F~S!B(1R+Rku zw+q3!d;b_xrXyL>kk|Os6oWL=FMe8-5&TC^+a-b*y`l3oezy$_dU^rBdRkB$e|c63 z+N)hZ<-WT3WvPcKLh+DcG(WWzGUwu2%f)C)>&=7HUb2m8xB#H{ALL!PH+%Fod7s3OZEFiHOC$puCXb4 z{3!Q@xK1B`<}zp$3;L4nCV2L|#wT2v^N8CLC+z5hJow*cJH?Orn0fWscg>_C-EW3&^%VFKL=Y*6HI@$e*Td! zFNJTGg!|6xta3Laiu&@|=L@ADkSN=)`b+%ex%ckn;q`388fQIsZI9qy_^fakK=1?_ zzJgR;O>05yC>gS%6vEaA&}K*k^#*P^M`!GiVYRzIb4>i zA_-u1W`&Mht(6Ro9++}VU50ihXT^&og0v^s;l+2NT&gZOnv{+#KE3f<76QLzyFLdB z_@SX~(}6C-iS~1Y@@5_|i)Z=u4_3e5YWUKJ>yjkf;1yRx|aO zYV2Enl%74Zf~SSO=NQ_P*@IfoU0#f1 z$X3&YX?J?k-@q{d%d+ltcjqaQ?Q&kzQ%V{Mn!%}(`7y#Q?Lwsi{c;F30f|mMIJ_?ah??yy_3+~AL-%SmRmz=<01LlB=Y^w_IugwiCj5w{_XBe` zXcaO>nf(q99#_3rbd>naQx%*B15azpXQ+$_f$EzH4o;A&D4vIx82ez7i(sM-)#bTX-S(ztD;&~ta1;P7bSL$VJ^>R%QEABiLCt4?2dQxOQVOOq` z5;ipqr9y$?7c_1jjquzPoT39JR5qiM&M9(ATm{a35c^ewhxugX=-8@CysK3;53n0; zZc=}I{&L;zU7nnFOI_*!+e?rz*3dqw%39+RLwKrd*-CH&HU(8avcc$edwYjQ(|4-7 znooOs8@=){>6W!d>^d)1;ZTc>(JdiV3R9nq{qcqZt+1M!HHFt6;E!U1Tq(8(>l}fM z_ddj)lrob1qD379RhID(e4!c{L+bLD*>SB^K`L9IjaxdTd?(L1jOE>?j`n0mTN`<^AmXs>n$3J$*jMJ;4SgZM zf6GZiQ~9dC^2BDCTGBN3SlwdPJ%(fVmej#19(fy;T{>N$lp%h=Do&SW|e~{Ln zNa;_d^Rh=CPUCllFEP>!wfqjl45{xpYySf6R#9);HV}UIuQ&t&EN71723azAO_#Pw zyA?rV*v9tI1p+OdWi}G2k(86P&41sKqH0ynx}bZVUQF@sK7M!K@#N>fl&i8A?d|no z4`zQ={9`;5e7V%|87`_Ue#h2qmMC7D3oeW^h2(0zC%;Z$jY@MV;77lAnlOWzRQF)b zZl`3)4a*SRPW)P?=ul8OE33>(Dl)=bg&E9NsBWc9;d!S0@>E+^p+NJZK0%iEif1bW z2cyx^{=w+kVNDz+<{mCg3c<@)mvDRxqn{4p=y(K2qtU>H<~%{6EtQoqr5;C7#?7i) zgo!L7cTCO}I_mI@7P(wR1=EJs4kE$O+!=T^JA;e*-NTC;aF2y2^b(m0slJwci{H%Ss^TWj^Y2Jz-iN=08`A7X&isaKK8cL|EOM)Gp(Pf9q^*e zu|Q#TxAb*v?^Ca5Nw|)%&mO#loNH2c2}a(a;2()LiOe-<2dS&Fl*;JP2Q+b~Yo>rH z#qRx1+%#i_eU!r|yrcH?!lrbtK zeNtL(QBw}cI=#PsjNP&liLts-19B^JFmUEiwKF{)q2@b}uO{c0@%-gm%i5YBq6kIW z4&O>JJC@2vF^4cZf*ZxHHgww65oretMZ*Wh1jGTda-)ppmG>XH>m z4Y>)}f03cF3qh8k5!(5G(D{U!6}fi~9givIwG>O9oiW3LK6%C^x!U$_!ub*cu47T< zdC))&;N;{4jH+YJ?eOZ~ZGW$!Z3TnkTzWD9(JdVe4d_J9CP2(8$eSyIq(^QJi>2Emg7CIv$ zc!x<~Nl~q9SXvPOHOt%Oiz4`)Db5yFAH3tn7SMLS?Ft%hh6a#8JAgcjt(cI2O3`OR zCP}6AkiI-^z}m)*g%MSOiYFn=DL*4&#Y9R+(Rkvr(%zLyk-BEqK;||SrMu=tsM5Hs za__Ft4lgQW_?3)4J15=&eEtmWjl-^#Uif;3_}u85a`=j$|AA(QC-q80xuWPD%ElIsg^saXXUo~g9 z&7YVp^&hfi1&t>VK6M+3B(g^}p_8iF#x@7a}&S{f%E3(vx z4eTKa3|cx%Y$Q@8sU&Wj|9wYFwl&#k_TzPYF-6{e_uY4Q^sArqByR=1UJH6K{Z#PJ z^Qqv=rJkSRqKN13rx#opcjS|awVM1ofqPV%O99_kXXB6=jHOzEy>=%#3-4Hr;7;am zWrPj|mAhqyNu;7nc&9LiX@crO$_QS?y4sGlW#bDpugeHBUnw3Z295@U|%VeL1*X9}27Y*n2E?l&(M zBowqOH;iUm)KO{gb>2@q-Je=JRIbnzN@&+wjtrPpj`o|GIwjgr#;B0$647>tnsPwa z==ydayJaClW9vnY$8B-FuDkwH8q=x}O1`uChspWne0KWIvbNVxL4YEvyYD13Q8GlW zv6jxi$RuZqWjnR}h2{?0)HR`Y+gUY>@IaG;HT@o#hNUb-yvZp#pBw7|Mj)ht1%fKX zH!Gi)oH-c`wb-y@!m2e>^%p^b_jkv=hxxJNQ z$>TF-nAdT}^PH^hsBAFGY#qq+7^U$J2w#F%BQqL}Kon^TU%&npzdG;Ma^8-{7VfE* zVwgq5>!5~yb5O&)Ik4Yr-EIyJYMEs^CRcpK(6cZkyev#!7}`+8dzRL^jCq71(6FlnPmxz}gb135kV>xQLs!B^PGGgeDhY^Jdlb+n9+W`@OOpQA1%ocaB~s zurD&us8iwy-u2+{$J_6^esAdcy>2_`^f%%An_znaxI)!~P=14bgzXBYFkBS43sWo5 zhPor>(({OFcf;cP#qFL%Gny3pM?Qk8r$Don9zw@Aif7)&`RI0^OtslyQS=8>f)f8A zNF(&t(EXB9A3Eoc^d1V9&ZJB`4Y;Rf(^c>AdYJ7qTphW;%hsRmRoiacI1qjJSIh=k zNKPHeExJk3B;B}Krwx#Jjo5ERVbBz15s^tPNp0#a^6#CYWLuSc3EDm`A8d-3!!zg1 zkf(nZS<#6P4mxlElYdJ2-)y2}n%dc=%tiG({NRMLQY$|b;YwOOemjPLg`siyqaHiw z%!!3IE1+pVQZRnU76Sap>_R8PqX^??S?Mxua1!1av4BY?%)QnLoGxtLJ-0+EQo_Az z?YLov!wtVuZe;|VE|*;TZhHsU#mdM<=HOYse{}e)|MYnkDU96;u3ZA*;PnWOkD>qK zIUF7L;i%v5`mMR-7&(#8oGa|hI9^DXmGg+}W$cg1+1$ph$l`gf=kbzRhkXyhMdUs> zcs=c8~~MU2SPF%i z(1NPAc0P7G9U|c~jM@PbccoF3EtnyOtw5*X^c})tHc9-!#DaT9m`+13Q4XiH&?mf8Akg-;RB9lH0A05u4kGiA^5y?(C1v6~9BO{3p`{*0DzB|o? zuOFBTsTN>4Q)&ygM!~d(owjcs+CFwz3WQQ_Y;deCYZ6j+NToa(~S!2iHtA%h=KNX_co7E)jh%LnzR$tar zpRE_`YQXijoLgtY4Mq>uFa||#4h2!rZ2~AnxbXG%`GKia$q47db!uK*4G1Y)a51Eh>FwZZ+HJ;PXD&6FLfAOqx3e=yS#CwQp^qogIM)cSO>!fgkv!a>B5yDG zHe4*n>ejFB@}Sqyq7mPQMnfp15zsvpw0TsD8iUZdM1 z#rGO~q{0GaNpP}@m@vo4&q~RXr_xv#)`{_ME71FQ0oPcX$_4Mc-7f$&WMWA&B%)!( zw_yNE<9zvm7_Jsd<5N%fo1u55zUzo%)P4rSCJ9w8s|y02z|+=)u)de*J*bDg z6rE4)8*6jhHuAfF1v;aN&40gL z0DOZK6(={Hn{ql6iv;$)i+!N4|G8eScluAC?vSTs{5j&kPscu=&&Bj42v<}}?k}d7 zYZg+;1OF(b&L<|-iXQC1O;@K^oW9v6}Xb0ULJ%;&!Y@nAq)5TQVdXuS?XDSBo@yzlKT4Z)H^`e5Gl)xYa# z24W*EvyHiv6zUtjzN0tPKW(7D-EFk;{kYM>-GiMH^Vdv9A$o+bNlV0FL?FSP$Q?y_ z%0LN<`D7l1C1HdLP_;bfk?)}M5pWfR5_Wdg=RXp{4TPfFl=#G}SFOP4TO4REzV!Rd zceC(H++Br%!-QZNX1e5V2`mIYLsq%sOR)>z!M20Q2Usd7SgV;gakXjk`Nvc$~q8S$qN+%znv%y!K^j400Cdd zU>iOP0a=4jF&81UH0M>SybZWptI4&NZfAo~x+!Z#l^Y7cFVf|EhYKdP(mT6G)%fr^ z>10e2`*@s&xV%&kJ9jD1-`f$2_kHQ3UXspb-Rc966vv*y2497tWn< z#lZ$S+928<%>yQYiMp;bfnE{pI3T}8;Fo;i2XK0DnO~vxcaXgMk_r(vkF-5K(MUrE z8pD|0#kW3^>jr*X`#ie5vt(d2$hbK$MK7Nde9R^nc5UAFXCARNn|33!Kh8wxyiTM;BJBJXQ(-$buuIM)g`H7$R2sV+XYrVudDTQ zkVBZ`5|I}BrO2WH`PW91n9uKih(6jiN~Q z*~N$Rqv19A^G~v2#8PJ;+5VX|9&G}8o>er2K0ART^=sK+67C67kR45&>gkAoE)yIeq+ek@8S0ac4s z=^`&+6Vj9sWu#DepCz>-2xcD@^|;WHJc&iAGVl;dN$%Cb`N&jIOe4OkpwcKvA=AQN z#tR_=)j^}~Zxkv8S&b4!)QNq1FOwlC(|umYH9jpCh5-hH_5}n+s390ud%+!WFk|wL z!AX{h-blPg)wU}v0h{qmIDLnRq@!_VvY0Muj{zlw-@zQt@pDAft}q3B3Xv@P*aBa= zt^Q5=%VffQo+4^N=_E~ML`*C=$Q?)=(m-iFmV8K)nLAzMVF@}HT(obhPvur-U0mQy z!Ka|!VU59C!x|(VjKcZc$)SK$t2K)mI|NJcUBhQ(+*QuHP2i2;H;B6m0R{^UXt|)G zuqILEplk$5$X46+5i%N&hm$JnkNrLAWT59ms>5MB#UH5AUC1|)-dQBcl8P!oeh_Cx zx(;ds*t?1tF#|n(Dzk2}Ya2`B$@S>s7Zu@(Up|f|$EP*iel%{4y|@SPWi0NqeH@5Z zm|4&A-5fit6Nne=o+5}YaTxbHEzA`AptQSS*S@V42bIQ!`(*l`!S!fxbT-^vkteA| zlcn#PFVzBXvNB`!4OUN1N8={zE|1<1kKv!I;q_p0*@$FVdodmV`@`URI6b-^9RF)L zX|nD3>=G)A?f0EuzWV?*;Krr97O%wz%b`x3U>EYV1Cx0lCSl6F+1sl-)l^8fCMTK1 zB(}%uXk2`tnv`%pv9CIvHfHo%{#PLVi^=J5JSx>M#V09B3Q#ivehU8W!%2NpLo#7- zoNYi=5wuda?Qg3SIz>8WC$V1Zn61HHfkWGr55-L0rk-h=QXgJtk2~}7*|Y7<3itg* z%qmBUF)I}fwy`QBwIa~0RXJWD{)$$mNLN->pU5;Iz>+YQ6T>X>)G*?Mxu*6J4mjqe z@=dYXP-;^ZWj`5A)QnHEi8aTLRv6s%;ufK4 zIajK~$6g^5*id7>@-MY5?v{4RB0!O+jDwj(Mt6IXC+A5_a$t||Rsn{7}qW7d(}nrcJH0 zJjU9#6Yy0SwV63B5XP~Wp7tEfkVA>U1_#VmK~Yny@_@H&VJ+_8QjhCd+*WfqNOCUE z&j(HBYq<36@}k+&qTg<@YukKRQ8pMi$nmWSZ*^vxC_bA@oJW#`=KO>-yT+P^=XtcY*py1g8(30P8aq2!;Z#jD zEU@jIlo#5I)y@1Up1xI3%Kxf&&5AB=ZcelPG_N?D$u+X|;jW}vandJwONNZR1_~b! z^M+aM7C%m~UvgJJ;tL3tn;!$$Rc-${zc*71g)NQ7s;U3?EsxE&JgQXnh+7}Y@Md61 z-pC5CHe_46nW0S!^+^hT02H3^dmOn}4{Qo7v`aTj5O9*K=w@}+)9zWgcgTE1;#TK0 zH8&Ktx$4ra?YybgyrI3kp`~2kM&8^yu4@-JY!Pqh)0$z4^fx* zL8G}q>R)AO&E^5$mfQxJZVkoew0bPH1y4!)OPSLlrNWkDH@((npjhrlStF+|`kDn! ziq|5nQw;s(b&hgBT4}1{@8yZc|8pc&EPwAnnn&_|;%H+WUmZppWBB?gT14?b38GdL zXwukEJgo$(+34$AlG-4AR#F=W&qq?)BzPt?JoZ|w24uM*lntN9)Yn5NU59d0ccM&Z zfn3IIaMduprQE~%LIovQ58Ny|>$*@Zf z0Z}2$T-vtOH8Zy0{_&Ff3#M)m9n>uj+1jHHQ-X+35h$=a?VjzF^(B~L`(_)EO0Zp9 zfHc5*?cH`gKu~**oov&fs-DFrf?1;ezoVW10_|JtbK5o&|L(s6?YNbcIFgd-B{y}P zi{m&KcO1uOId>m284pE462}zD0-zt)$^YKPf)9`c_>h#xb&k_%WD?k2EOvkUAo%kWq zOqP`0hT)7nU-0DTOD?4y22{K#&3NZ9m%MXN0&&kMdA?eKi1KH7h8srr%v&r4c`_b9 zee`7f_!p%DaxU)4shE-e;j1(9>=_yV{TK4|*_b>Xj|Vu__gorqDg081i2phoEj+P| zr$aYfjgXD+O!=s^veDEJr=yj_1^h-5E**+HL0(N>lT-C~LO!@AcuDd=J)#a9!cIxy zM~UXj)M4gmXS-W@w50AeCt~Rc;w0lZ@d7eW=#W`Xh{F&{IFO+;;)aY-SNQkC|69O1 z7LYm+As5uA4yV6n`npPiA=l4bA#o-L`c{s15Up$5aHQ|M=R)9do;&4;t2%aiwKdxmF6r|%~pE{-dY z2FV6|9*rp2nZ~=KiE|c$#yHg$zDI7Cu-q`9QY{|p096Ce!EM2Gffk)rbP<93tSZj& z#`7uJ1vhm${=9^(p35IoDtDW^P7vh8QYx^~<>eBx%LSOmxd7yoR3fk!)UDh+X+Ypt z;GarbiQRBBCEM~s1|$Nw0AvRWyK3dOZNCY1qgS0~0e;Sd>hz#Ta(68=uYPu1t!!5i5K;BmT~ zHbb4hu@$t_P@okIpeGn`pxJjcBCFUJ-l-Q*#ntA4kbz1Emp+q?(D`RWbhOwFz)j9^ z&kqV~*Z8AJaK&6D0@@O9mr{fMevy#b7yo^DadPR@1ZeVmD^wln(A z+mp-V$@$@tkyXFAE$XIVF*U)E#;p#Fri?n*WgMu=Elp3igN%9x(EB@P8PrS!@8f@c zI6O58F&e2#k>HL|h>TDd&K)oxOl-m5hgGQKTG&(hXnBZ~L07~h&1weZ1*p#;i-|TD z%%?$SzvZ1l9U$~oB7#AmnRW_Hl=WA$4XcP0svQQh^-hAMR!(&V2q|tU4YG=x{P+|9 z5t8zmUKZ^WdKbYgK&#%+#Cg~w(^x=yE^Dfvc(1xJlw;-yCwDO87;Us}Kd3-mchy|H zW?LEt5B95CM;deQuH=8tZ1%>xbEZB$mOAY#)$VByyGMGMWGT+asHNVXTDxJx<%K(p zykKL|M=cwPLPa2hsyD&Zt{8n3my2mia|M`rid0RN=S4A7uPmsrkFdpTw9q zhM#W^JP*Gd@R;uwZbNSL1`RcftP4(WSXzW~a6TsD>l#WX3&zvM`3#(DJq z-Mho)yw;LnD&n=(uFUOl6#8*BkE;Ty8vbZKAkA>NGpl;H zDqu;V%zB{tbU$>Rw5b5arJ!hb!>Z$GYxMX<%CAs~%C!w@HMX0xz|vZu`=s31u_0m| zk;j$pP-P`_6^Z+PQf3e8>rAO%*$IdLf>0oa%{|8R*Meyu#q?&-Q2oKQay?pcGK1k4 znvD7C*8rM@6IC;{GRZtiGZF!%Bw6~cd|AW7TlwlFak`Z>M;Sq@^PNE zQDb+Ef*Pc4O9faPBpJJExP7d`Z5C}aec)9&v5>sLaa} zqa0~+5dWbih!-@{Y|4riI%Q_m%8tja%oy1eO&R^QLAf|>ZL2y9wS=vMS!J5;YFa36 zeL;tcY-3mQvfCCuZBy-`NXCF&u^)R|rF?Zm%1n$+%&a9`X1vyd&1^OXv96Qa<7j%d zP&HEC6j#^s0C}zL1t@l7MWd%m?L0zW^$+axM=Xm|_sRoe;GHEyj% zvfZY{ZgQ-KG&Cek$DJB`6W#j~)56(_+Rntbx)Svr3ERuMuAPW2b|Kd9Ky1`~XrD@a zg|0*Q$lNw6w~WX&k?E^;7&?dH?r+xWMb+qV? z>1Kf{1!#pyeF<9EzAQ1*Uh-QGA9wUJaGcV+w9=Oj>sGC6xLfVIS~+6d`nIIj@4IaFbsXy zSMV)P(Ai$mB}1ERY17?+b_kXaFcg`-Ac^Ej^qQ>bzfY2#r0|BJU0=r+(wn_M;F^5Hg`cA17#<^+Tsd4Rv66swBam%%U zTk%EGP9uyr8&P_NI|R*31lZ+QAK_5L{k;h0zG&w`VXM#W0NH zzK5<$fzr6<3!=)LM^Ro~A?tezfgx=Pt`^sD)BLye zas}QTy=AYE>(H*oH6OJ%*JZcJh_Nz*!0yGE1h=Ij6ZAS|$%42{xlT=TxiqA?pgAYo zQM1L~36QR_50l9RGQKv}y=Sf!Dzv%-iFe(FB_Fl|E2o2?H*-h-R`B;DK`Mew)iUk% zFW3Wnq5ftCij}eLB4lkTq{mt)4G5(*3JU+L^Iz1tf7}4yaE;vH`Qg5jHaC5tjJ<-N zD*(VPp-i7EKX%WU7r2+5vwG5V63tf2&XZd!bei_$UVVSdxi$x z1|$Eiv?2?@^r+4p_YIk#?~9rj=j<_0aER`$ci`Yl5rkpbzv!Jjq3TaXyuBNE3a5Rj zKJ*Yp_R2dGFxH0s8rd)HRb6k>Fcf{yued@(ZMV`C1RG*2?2EyqZB(@IGEJ51+$Ppi zJJ`-fnfBkgc9J%0H@+Y7L+jYS$LF4VZ123uk}L?<*8^CG!IxZo8x5qGOw8ygm)r^^ z7rnzgO9f{Z_jH_3QQASqxR9|A=n#Oz=)dp76>3B4;YB&N>w;pXXW*v&2t{797{QN> z4pf951+|}LxlNR&NqDC*hCzb*TB!(jVpDc^jpN#pXkRZyoHEVflpjkw(+E4$DN%IY zGMJW=-U~b*a(_?`)9DV1>Kj=VRNeso84~9hmr~?jU%5} zo0(T(7z>-^;|^ET&~KBnu?d$l3&*J%hf`)O^*sc~j{Rz3e{cvV#dirWFTpnlPv{vk z-Jv=;@?ojmGCDof5IR zmSh`A&e3cJY64bWl8R(8K|g3LTr-Dh6{LbRB2OvZDFG^+UG0Gika95e|5-jJvI`%Q zZybtlw*2%>v6xyNp*b8KeL6cB9)CD%Z5O0(!w_Xu4_`^9uN6mQu*SU&*9kFJ5?yA( zr{S}sd8(_*C1GK-l1@fPWx68ckw_8NsE*wD?l3`^xXu{qoPyy@$^}@3LNKqxrb-rUE4*K9bm|?1-vBc5Q*jfl6`4O&xho~29~Lev)NTGm zl=dREG}XLAc>|udwt*&g?hcb&V`F22Apxt_PJ2L8C zMPg^RGw2Zieb-JxOUlMRUgrmJ{BiE_Imhna>mn_JXl*TkH5h&^#rN@0is{shk4nj{ zP|}Q#Gc{pZ^X;d5wA}3&ydS_f)P~04MLl-FnZ-ou8MtXbQZRnW5(GaoK2$M!6x4o} zl{QtHCgE6P0>c#bl~OV6C8q8k7{{z9(Y|W!IAfZ_89$MBrV;k?oD1J=@8GJKX_2HB zHv0XoXB++Jo7Hh)U}tb@V+h~8J%{aW=)c^At?fQ+_4{4FH4_}AapY5L3$qhNiLhxo z>2Z}uzD&j@CTg85nviNy&WxqLhv3+=*B0Im-@$41UBk;u@Xf&!dVx&$$Q4IEs+DV_ z)6OXPd)r26tbr*>IBk}LDy%)m@#O2{|)^cL!0{m@DVd)26yiC8rO3N|LD9o z=ns4ckrx@}D9QB}UbR2C34*{e@sV;v-MygD)7#Ky=f<%n{&6^-3 z{>t|rq4tERb>=vohbXS1)>Mra9+HCed!Wf|Yh8q^B6HJMo|+XG9_Hd?DGvTs>g+CK z#>_Gx%?BY`ckKDEz!DX^g(KIyhveVh# zeA#)il~oP{vw%|*K;!V}9Cmh~^Lh)mcRH}$=`>wv9B~xdCLbD;=v~j7MkY+hZ7ye? zyC!C1?NuuC#<3iGGo}sg9R$a=xifGydXwF4zNYKO+AicgmqFC*KX^F2ot**VX5DLiOTo%Gz012rZ144lHtn#OH zbStCar!q=1b{oGSrS-kEs^0Pppj$e=`DTj7clJinYIl}PY7H^aEy6x8aj!qub8r26 zZy6Cyps|d4*6k7j%1HMDFYV1{DIIqWDn*ZF7wXTKPdCg`8o_bt_1*)#OOP8Pa_zZZ zgK=tTBvX-n*7tsd447d+kWb82wp?;)l9ZEsJQbz0l|r66TO4@8->l?X>H`acz9plP zaZ>7I3+l(V+AEu`<)hxpsw|;B{4k}3R_u`GCil+Pz5(r6+iu%95PkPo%mM~vw~pm4 zy6qyayGc`LTOb!BcF~8TFlcFP36VuDNj3Hs`S%@CcUif(P2W~PQC-O4;hDoT{$z*!StWl|93tO{pC{5Pvg*0J`d&mJPwq9=7*TQdXG-P1k<->aGxgY`I8S5 z_=ZB#d-x-LcjPdID=xO6KbtoZbFSG6!MvHDa2HJ!6y__7mB$5rguex@VCtc`;oOBc zE1BLNNsY4~qI#RGz@x43SDu0wgTbqV7lYqlCR>4t+QOM~p>zE10$#s{!JjYT)$0Mg z8VtH-YT!Ew;X)gl4u-8l~x;G&l?5mA}chmQ9 zmOQ87!)q{?4o}e|WTH=uYw&i;Lp?gpv|BBI2_0ft$~kU)sbt5RjE}E&lXF*2tR5&4 zV;4rF5iD6C>Gpd|LusQBMDPf#6CEG+iwhxFu;g**T0;{~d4k_Sh&T0Y&c_=EBR#Q` zEZH5lZd*^KwQ(q8fgt^G6(F$Cg|(h~K$Iga)5+i#vn4PZ@8XgMxZrRh&{4s*|G!S* zC_A(OR~R6Zc$n{go_;&}NkJPe|8Uj;Hwr^{U$M5nw^~M|Ms)fjlM>uPDN&XMQ`Sj8 z9hpraCInmWsQc6>-L+}!jx@J3k94PR7D$=|>9CN5)~`kJLj^lmTPk91qDW0TO2nma z)XSH2x)7Y0v`X_7zs4|&_sGi+O$f69M3e&3KD}$3Sh9|e3Bk5I=#sJec9w_I(3026 zV+z*n8X=DM1gBEUb{H3^ViCeO?z`zb+x#EJ3zBhhyrU$SxqM3b?>vyNUcq`V+hW%& zlDMS4Y#Tn4HaH+1g01p&UNvSSOXouxWx5xch`o&5X^icY8u1BM=z7C53v1y095v#8x#|5<8(l%qVx=|@v2XD!>-3u~-&TRf^ zI_@j~!K&A&f_z{fI(QvvkusgE z#C!x1W{wV0>z|lhsoS;sMge`R-1pJ|nnaA3CCF=DMf; zhAjddYlP`9!CpdduOhX+b*gbsH0)_onXK;aGKN5-Ork6KiMz{(!BffH28BU$fj4?* zm7F!Ka@%Ttx~=GT%p5NvYJutoYmSqtSQi^cKARVsJTrxa+gjr%e7$BwpcYR7X-SFg zw0#&g2yF=T;Z5}*>UYnd*I6O7(`!G0}>DsmPTn(K}bm`Nfn_8g``(xyaQ{o z*jwAnN22`qj=c+MNu&~`$NGZT<9Rdl{AM`&n#O4m9vlR40K=b|cpMF-m`u#*md%Bn zc9mS9v_eTU`oR(rU1gHHPcoywStn2DJor9<1!_Y!_*|TIII}oadJWF(Pg2HbY>MDd zMqL%;T%|jn1VPg~S za94YP9Bv!TD28C?^(`6n*Qr@-iG{eIs0|X zCZ>!3N2Bzl$ut_czkBG_;Oe43>;aPz+&=XCz%)YU(&pqwS!&-`&YZZn*`D4E>;HQU zI-7w5aEA#JIn8bLqr%qtU^9B*zWcEOR~BXTjxGzHg22ns%gZgAsakO~hQwlHVZgY1 zHCV%KtO{8H|FEBPxM2lwgR|>xp2||f@;Kpz7W73z~jFCzN z!g)6ExcMKs)f%6mZarSQe}iA$7N~hn`c@RU3s<}ygiqY9>NEJl->g)cUH

    JKQfe=yRXt8VfP7*!*0>z%xFRto z0TuvtN#cL+0wi^zCsSAHWAPwCxSTz^dv>9V7e!hG;mJt=Coub~6knp56pMw4Zdfj4 zGFEbl(h4O_^asmC{JNCf{iJR5CkJ%XU7o(3!VT~^vuY1)K08WWhMs8>qGaFLjLdSx8RfkgYfb>jom96s=O(rz@uMV@ov zr|lbD6&o#*)WXx@@bt;k;V;iB&tYme@ZQGIefjDJ&dy-?+cP*l8^Y;u*z;F2!BHAV zKDD+m=V6!#o0jtdS9$2oWNdE2mS^ESQ}Zxq#?stFa2(jRg;%o)ysv)O@bVV?aPWj) zAkza%kRu<~k!z#V%`gbW0=hh7#zeRl#+q(tdj0a_zs+T*4_24hgUicHSg_2{^lRV< z*;K0)NL;nk7G1A777nG`89M@SjA4+-fwqk$YrA~8tXH^4|6 zTxpHmLW~8H3)nqd1bpnEmJFw#*ivW zbYRsj#THa)jfl}N8A=rn>f_BViil?Uy*hj?GK9wz0&e{D6Ww39$sC=+i`rH^XyK4X z;NEy_EX8nYNmmZ1P)0a!T#;x;O_+)!9l-lZqc6SNZ~)o9in=fJs%E#f}y+Sco-cbVaQL7{rPiEdr^6Dx5kfc1DMm_maWl_}cO4 zR&@4K+K0}>1AX4%^!EbV8$C1$E=nyaou3OcCU3JbE6ia^`qevGJ)HgK(Y*J5J~WK( z9Tb#CXN*1zO0CkAu47|zqwJRW_u^6eeiw$+-M(L5J!)X}8Q(;MzX9!8ZFAc;68^4V zfp*-X?2{#>(@XB$q>ZdFv3j#!0R_b>Wn!Gr`+^4Iv?Tbn92}!nNoo~ zYc!^=nuX)K&F2lhjYr3_kvmyq?D279PNjn1T7}K(>QRyN;X85}{X16g-xK|yde9y) zD(Vm*G`E#^La8N;8c`x- z$K=hMH)KLR2|u4IXp5Q&{y=>8kdK&UKH4lmY*dXl?p+Yru_y7lA`>3^j&b~BnMhyOzryu7a9w3PAp_0qXh{zEqKZ5)VpE??TmTg%?|L84 zFHNi6yX91-XP;0xn%d16qlx z002S%zHf&@06rpXK?A;AsonF@8;}41$Q;yg6rH?qRKZjze6rxKlZ!1^%vP{?68g3_ zE{Ghw!drERe`@I|kG0CDB$}}?1OSuDpZ+vuDgtX2;+x0<_Ao6#)>FcrSL4MuiT1l2 z!{!i4Um15bVjLkIr^`YAfJr7646{t`#wb39H8cm;=D^qt(n#!sIoc`H?+teg4a|Rj zH207jn!{nI*WD>+cCUBJw0pgObj+P%?>m>~aF^7F%iekGa;F$ls3n*TfclshQt`!h-iwVKSTu!&kW}(t(kPfnh0dwgfA!5lYt$R$4**`% zO$!zn$r!4I!a|`Mgc50yCY=hI2tJ1vhQMY(E%h}u=(__CnRU;Wa~94DJLS(f91S|% z5BZ~MyT(vs@0mK#HayJ^n+kTtJEgXL6ZyYycCCJE0QK;~9Cn6fR<7W3op5F0v@t2h#kQWjG9xZa8Pd5s(>btgC?5QH@FM> zQrD+m#%HMqi=kSDONQ8YRWq_R(yT$KHIxj?*c6{)jLKBKC_xE6pUUHg7Uk;j*_kWb zpv!C1K&~s-lTif5+GUwjaBt0-+m{*jnJa7zgS=!3;iVQ3x5U@;WMYo zC_jzX=}<*UQjhcT*x(1fGLwkZaZI$W8ktzrL;_tvm#f4HFdgd6HoCU(rqO`r8=PC& z{x*G+Eh5iLq$Fdqs-BfRYgv-jc6h>+CCMV6A=#{0?3EHbDqCN$h08;^v$~xg!1`M% zTz2#+%YrDTsgFE&0aL~UOrzjMO7xgl(;f%s3kEreQ>FuQ_pD4A&L?N&YN@Xs&d!dk zmF5*&I@~u@j237(Ai_ZjiygUsba4@N7VBsKL>T0BSwTxzW&J**5~fl|k0GgtYh)FI z_GN20tbwyS-H|zXkMkS+V>D=WM#nj~=cr0YA=z|88>B5;6qs?bi5AnG&Fr?D3>VL0 z!Y{>shcVuEmP;eFi|S$r#axvi;*Pfs($NJ*$%T^^{5md^J;voL?LF}K7nql~jLXG& z8J~k@=0rmjaDYKjvgK9skqPB8nUY0rwqWx>0mw7THcvq~MDWmakoI5?;L;^TVZsR= z^H4<>Iw?s$%v^hxUq59&u)F6i0k0IVcogQR>qn`H^_5HMj^R5{9S(Rfma)7Non3X( zg6;KBWO>g6!~(4cTwr|1%LsE&bdj#}8sbZ}xKz8jDQDZX7k2_WYHM!0F?0cl2LdDR z6V@W8jeUpgl90tO8?8ue~JF4quv5P6`7IU1r zWtI=^i7TWkcir)}TY%JkH_f{(f+hXq-Xz`EZoi=NV|v=nZD}4S_+(06S#94ExNr6e zTtB|d-5k9`Be%C}qMf^Z-8D&24)@RJv;=X29MTnBmAUNT=3rlUMZ4vTewnvQD}P## zwwC_2p+NsHSK9D8JjA!Zha3qJ5C>TJziSHCj6Ap-C_U2i@5(#=P^vh?HM*dk=)ITI|990(#n*N<_F)|XOI3_clWCY zkLddO2^^o2Tf6_(kh*%l^i^GcXkBc*p4+>MMSQsDE#3MJU7^sIkG2WtVx5ac^gvtr z58YPZbJ|7_e&?^)c9;>k7?DhBcak_Y#-wrU07Z2Aka{$Sw1TU}opN^qlZ^lO?w!PM zyS1l%s$L|m_P*P1_uE^&{V|(n760g{0!PplI#;N{Oql^W{u3huT*P=sHl`33iW`H1 zY!FKWLKIyaV^sZ`_z0V=};Tr$Bmyw$P2pX<*#|I!p_-WA)(Y^nHUYT#w7b#nZ&_2Lx- z)&&M;3D+iuTKl30r>D^R;T4>mw&0}Is=K8rk5FhE&(xSqzxMqJH`9FFjO5IB+oWu) z{k>rQaVp3DjA=v94kE&)xifGPT*7tnUc!r8aF>NA^bDD5Qr2zoewmDYbXw_G{-d%y zrv(42%&)WvFvJv@#@B1+VfpR+UzR9Jnbrl}(Ajm^cLmbnCD$xX<)U~GjN)Q)Wvk}= zfX}iNXDEz5Xajeze63V$L{0>4eD9pU-Nzry!xBUK`28sxe_ElQ8=!HDg!b|fi9S3 zXQT_8^qEL?5Sns8k4Kl}BC=uzg%gXSYIXPdYvD}SHbQL__6OZw82tKMd)N&xhV9NT z-H|0=J@0)VMZAr4z-ypngj(YkjRq{H6ucB@Npi=?5vA`WHJJ;-!uWt$#uS?!)b>43 z5vnAuNV~_;6d|z>VPbf!oIc##l+clK};R8LNYrMAW*Iku9F$l4BVZnknq?A}fZ8GD37Li_#0)u3*8&$%5QV?}}E z`p~e%U80`IyGYVgNn7Lt&e#2*yWg?T;@h^z?0O=)DLG|xw8K!BY-iM85zA@TET}V> z@Qj<9xDDgn4rk~pE0Lr|7d9~@l-Watbl<(326*58;eof81kx9^Xl;c9bkd{pp0|^0EXrPDw{l9#Xh_(jYDYgd zsgyKwq*k)?Mz9%fWiL}We?U_MGIN>h$NTB{iPEwgY@~JOr1fy~R8cAVy`g;ccmJhk zxpo8|`JeLM?80nOVR78GptSP3)}glx0Tq-{;r~Z5lM)cIS2d z0QR|j=kguLC%f9L$md@A^IspnUVzc4i0|AEkk3B#G;QaFn)d040M zr!hRB(jHMsRotylF&%k4PAG|7ZHYFulDf0254*X*_!D*Syr7{p3i5332$g zfdHOn38pA$2x^c8MB{6t(Xh$5akFcW3W&L_SA$t0jmtevh}mRl&&<#d*PtExniI9! zPE=w&$V_%ilr7kqLX#^&BdFM>6#DKz%NNv8Smq+M`GP9LdTpovS{T!+B6zd;D7a}K z7fFBfeH2mEbElZGk|F9!DZ5qBrbwTQ7?x7)l#nsS(w+W&ZCSHGWr$s{nHrD%*nki#m<%`iCkk;s7TP?A)`Fb(GCqswZnOyNT+Ix=G0q=>heR$XIfXI`i14iZeLJj?L zoFDbOYc>!5ygnapkNs1J*?H09^6L6xNF_}sS2wTon0>OQZ;3GpX4jL^TRaA%;b0U{ zs9^Lqk6<_rUgJ@1G+%b9J?TgUL-Z7ZblY2Dqmq2KSrk|i43mHD)*iAvG? z)Q8px*N=~Bnrj1#A3dn8J1MOAcZ`(Eye)nH-0}NOW9Lp`bWJu~PiRW(XoY{!IhoJ}zS~^QyBvK=(IBwDZ zeMeIMsWmIm*YQOZ$@}i^`;N!AKNe}x2v1HLa01i6Oa5^_6@0nW^YP*@jLhcytI&oC z!i=#tzAdVU?SBT?6zAeSoFve1h+CD$QT_8D!0o@lS)OK z@Uy}MrYWkGlrg+bbTz%!Hn^@pbLBnAVy$?R8hG97ot?h!y?W#0hlyFk$ixub-2M*d z=g|A%4V<0#;H=kcJJXCuD6|bFHKx!PVVH1}mWysA^U%4;*g}U#afXXbF2bB?Lvsfa zVb?qxxSjq4BmZB)i$`$7!V`LdOm&H78+=&taEwltVdI;07z$k~)FAzNUjThVO=hfczHwqkOq{vJ1-eJB#HIRAE z+&=KU$S_Aif*t{SfX1gr!$#sN$Bq-YfsAVda!IN`qTnAXb}%W|pdF+xi$W@+yOqJl z?waa@sz$MOwGz5-Q7(uzXjWzz&vvMNe?DlvpSIeUjan%8m~hLx^^ZOrFzW*CKQsG5 ztvD5owsmTQx5s2HK82=K;>#f}OA*;?0jhEvwB7b6f0)KTLNJ>TM&s#lKKSE)^ymEc z{$}voaAvcxCqIWFig+KXmfS?i2=!iS^{i;()8Qh4rBt<)3Z__IQ}!LFOWLG@inN=~ z$itHRi%Yk9$K{G?f-ObdJwoKdKy5VX!bgu2L-*Ap7E*IZ7Z(oF?Rpm*w67d51avIk zljQM>+7+JF;6FI&?6Nr)xmk(P-#dPKm7sBjtAmZiPR zg<=#81gn%ssq3g!cWv(@Fe((k4lypdaI9{w7Y)9IfNPB=s6zX&js4+6OH)V0c_c;b z>{<_P==b|zREh1qtXyW>Q#QG;!MZ%Kw}EWUwx`H0BBEOl@E!S`&BwRzhlAO%Z#%q( zhnSxmyV*{HLgCYq07OhYp=B=1y1HJPi;E`ag<1Q*4h6fd*i(4b?tmz>tmCPlr7d-TwD|o*BPk8;5MK`{8sWCD=3byuZ%);-CJ;uXUe3t-(_m zfZ_7h3Zw_jU3r1UKyDa>f`PY!(VO99KDru=LGFB<@mXL>FA#t~8y4VJ(}m%`KH`RC zt%GO@^Y!~{xMP9fo(sQ3bFVB@vb7iNfR@#aZ(6tJnt_^GTzNKA46#71nxWiy0WQM3 zfUUtmqW7L>!^K)ekFUhTrv>f|%b(>5H>&cg^J{ zTy`vP+f`&7b1Awx$+}C&TXwgmkoc@nSga#IOL%R(fw6v%(7U&w2BAmnJ~M+3T926T zMw-iGN62pN$D4PaqUrbhAcK$r7cmtZJhVOVt&j3?sh5RB>u;GWMVm0-Mqr;!+``Tx zq!$*-p{&AJ(5#zE%U|gqjZTM%!#B0F8*imIvGGF3hUGy-36IBO97!-8k!Ve1)ke5h zxXQGUPm0RChn`)?S;poJLgpTB{L9D&lBR)Hz&8auw;_GM9fr8PI_+JcL3iLf`iSN$#Qm zVz^g#W&maon7e4EtA71(iQ0pD1jg)ninXuzH#I=@XdwTM_E9^3HICZYIK)<440yjQL=4HJrYEczdN2a96uQT3hZhb5J(rXmSTL zgNw$!V--Hp#B>JzOLT*PyX#i9i$wGu=Oj^R5Rv0S_S9u)-Ktl_(!dgNT%_f&kmG4g zgyqR!!SZ@K9S;W+LY43WZwF&z_()u>qf-U^4`}WvY01^|zCL4XP8CkK2rA*Lc8cCj znN9om9E-W2UW}rHws{4w510%C_izzdg{~#3Rt6E-rVfa&3HMnHMRTC8NlOd+6VKG(3q5rMhWv-p&si3Coz{55wqoksK@IfmE!<@Rqf^x8snA<`Xe#;#O zb!-AGp&qF-UD3lmwoWW#m3vbl+R(K-IgFHG3ZsrW#k#$g*kch!-xFLZp1TUATFsM) z@g6w}4CUS6&f|8a7x-GM%?EVSPNm7aOFc3Mj(!H>^m5Il>N7+Wt-QaRT94fBWPXmW zA9)20)qZOdpAsH!J~gPeYB^3>Vjf88!#+hsMarGfbn~MVCQu z<}Nm@3`TF$qYu~~rU2KIurcrO#Dra?<+-+Utuj2z0QqLv^R)p_BliqkhKDOmA?uK$ zN&6oju#iC7P-X@lvYK^{Dr_oMlKAI<6PJDH(ZlI!nFIw@@Vw28;fK-HbUZCsEGK{= zJs%X8=)2F$!YFJ1lyjLvPbK$i7_Rwhk73Kf-Ml*#5EU!$$j1hoS)wS0bQ}u*>mPe;)4ky+5IWlTd+?4))_Qnd2$pZT>E)vJfq100G)NG|h ziUcy{>|rV@`@#|6v2|1Ml)`ieDr zJ~=5=Uv)2-;W>?;V%g;GLN}cXs;xWF#Vy;3reMwrjh#82eM&otn^v_W*I5vF)NeH6 z+Zp&tQ0KGZOOBQCT;0q4MCBHnN7HT;9ldUw(u8A9ggHrF>_%ndrs`}^E!!uhj4A}J z5_U5oWZL$S+ebLr;942;obc-IZ9>VDGTSjcQVdsTlnJ!@K4O=gu!Xoq~Jmv?887!|FN>NGd zU+&3MRUT59{vOPMrsSYrMl0&>h;wXCbytKr3#U|{OAW6gq*SMGq1|x1B=wY+OGH_A zb=W2ZF5%sVB5I;Hrj5jsj}3>=sc#S(kvhk*PW+W2&Kz;i7OUY9ru;Vr)tfs^HUwa} z5-%!ND-4xQ-{k&@6)H`YB*M|&ca>C6#k8p0fA(=$ksK5Bm02gQR_&Df9Emqd@=k*A zP{{7OuabQCO3AJMpkr<=44rC$?4oQ84X235=Rul13^3L%YVNGKvEz` zQLfYJr*Jwc1p{g=l9&6)UJ==^h2zA~$%hF%5EgkffFF{!caF`;in1Mu&$1=7oed5J*)s1_S6LxU zezjx1rVKyAPmHW!x+d(AQWxH=qU7~mBwTC-gugXL+}O;48)q2s9V75&yLCMIYL0Md zxMSXG&EaLI^Q!r>bMd`eH%#~rM%;yZ?|KZcUqk1g-@~id9eCC0G~`gdu^%V~Uj5w(q#wHH2Jw6}J|@m-p5NQ-~ra6NqwBlSBmA8bHA!aQ0J ziOpIV9^rgDLC&;}Biko`LHuSU;t}w*&G8=s=jTAv@n9pMaYS5rT$2Do8b#j1CtwFI z1eA->`>!5{t-T?UwBn$j_)oBmBQIFBzR}`2v`DiG;Ewpjj>u((*F5?5?koA@_;wUM zhdtnJLtnNXt4p}3tuzEv&{!MkpN4HSVTGMAX zAN=ROH?m4TOh)(9!(VTP0A~?LI!-vIsIY>P;>kb>CJ5b#8ADDfZ&Q0ue7r!KkP|?NyhdfhwllTzLmYab zo?A(wP@!8t0*bX?n#r}q1L$hqn{QWy&t!W&4Ygdv66#6+UowNAf2j#Ut$l`Wx2tFb zzyA(L`ysCynjgv+q)78^vM9`O%iNmt79ueVGJYLh1&3Fwu`L9WM3pjDyD+0EK(Pep2+XoRelZ)UfXpCV#d0fSmU+@ zwK3&A-=~kntu?Nm3e#E0$U{jGC)n)KxVV#)2eO_prwRXPRE1N`_Ka|121$h#W@Oir00}F<6BRoBi zq?E|5h6G>9hif%SR6DkzB~tp=ZEIpZ-*&Sp4%mK3Wz#gT}Q<&U? zn_>TUbUU_ivi|6HI+#y-cZ2cl!(cj`?i;6gQo0+=ukU*Oe-CE+_Wu3d=)Y-mBVR}A zkPIaanXDG{8m)}Un5p&H4zC^w+lQpTM*%a7|%*nD-=YT5fG#hCZ!4KSwOvr z%*t3$SoUaqe{(&!vowUoyB=+Ig0#}JqIkKT48}S<4a=-CtUUS|IgE{6bM(9CZ3u`b zLLubF_8GC=9mpyg&btDyX4le@LUK_?^x;W9D@TP>cCMaN@}miv$=KpSM$uIss0(|9 z*n`S5O$J4eK{cMn-kw!S!uUZT%fM8CmO%TYV_o$sv!|j0l>@>=W!(zg11w8;!u5mVopkyt7K#%WfwlcWfCm0fUJs>6ShD!=cuig4M)npp0EJQ93umdD zI%Vl5)hR6%1xJ>Y#xU2#k0>Bfyx>?saa{l;6k{pQ@^=MWGk}xsRb7?bms2`N=gihq zl)aJiIvG_e&WhC)3@@%jvuPx!who=xrnczIEv0kS&ThbvbMC5K!}ddR6c$2OyQrCy zKVSZ&e>9Z4+OZhrHrB>51uDvj^fH^PN}j}n%ulb%;n5aUUsB@^!vf#ikjq2Eg$m)C zF3>&kT68GsH(--bC`#GwhG`BH9M4+^Vx5?^ zpkoy_A;ZmlDdM`atlR5{_!*EDp5-0{+J1~s3*b{vOj|;ns5dPj@aYAEhr_vMz8-jIgY`jTj ztJpwD)2LkMnpjKiU^|S$`0t#Zq|LIeynV$VQukh-+&%Z$*?yKKSu5PwXu$>?f6m3X z@v#)ssTm(-sF_vTj6bkcL_-w|&eDa|NA)PnC5~Q?;0tOal!Qm6ZI?5PvC?yJZg0sL zKW8z5w~Y5ygdPR8_p;n3N|O^_X^i1GL4BcA1lzGGx4Xs_*pp~?8X0ey=J1xkk#?>T zwr4Xg{I;3FRW{cmPAoj=_c!l7=-+=>bPXdrhoOz2z4!bOwzi=E_#td=^Tb zzZ^WFXUKGqhU1D4OXiyBlo_`Ed3yT^@^b@L0X3Kte>P#39tdfX2CB+~fXOHTdO)Bw zZ75nQ3%S9_!NGfjK68ED2VGv)a)l%oSk(J3kiQW~b-n=JVT#P)lLcSn(zpAMO5!Oq z=FfEmVwR;iLupNOZUs#1d#lxQ1$m{qwLwkTTuVbLArWad2Q?)Ho)d$lA3+Z^7A}~> zBw?n4_>nMGx>o{JIJ?>d6(FTC^uJj?AwFT6OKu%;q#1{z+a2%zUIf#sBeWORYMqRS zN3Y)O?+wR$hX>si?xT0BydQ6Hcb*os{0Kv&!%{2o8eJo;I2waBcDitp5GP8a<4$;@ zJb&aT)u>z&mOqwP3CoyfvulHTDN=+rQVBPHdqRhp=UUTLVd@MM6fy?GnUqV=3XKj^ zvvq(qV@YfyO9#-QWy%OY2sh~(y04lLoUwxa&E;PJ8L1W{hp<*KaGOTHC=socNLH}i z{slSRWou0>l@-9C7JhFhMtkDz?P}ycR%4bjUY?x6Z30}Z;_e;nK(M|ZT-Vw%&fUyD z?(%YF+*cRq;y$eiyHas=nNzjKYO7LpL3%BlK3%YKb{cR+@{=|=qx>peOrb4kRCV;Lcrh#~lcoY$7JYV)WE~tV(yR?T8j>rIT^*47QNHCpOQVNvwLHPbG7swu4t!J)EysiQm!x<#pt8>G^& zyFf~lztdYk0qt39Z`(K){hnWO7we86acn1w79Mq=XKlQ{)5GRdV-VP;99 z7F^&Yd=_*LqXiX9&V6`0m-g#>skQ1vRGpP}Tod8JwRah*m7wr83_WJPmUnnOUI{i| zC^+i%ULPFw4u4Kfg`rx(mGYr+{^17Ryn)_-eumd?dhoi}YnrVA^JpZs@(ZP6dD899 znOY>%j>p5UIVK=e*)3Vtod$f`4T)6v-H7mLNByDT!{{SirN6EC=pM{Ri%01(C8C27 z(aLwN=gQJ?XLs+%LiUY_2*{Kt3cPF`q`!RH`F{+5B!*cD0DPqZC6b=x{+igi_d5pL z3y74@3^lMY4yYcN4wKYb=1G!e%8vtX!NX=&C?Cz zFK0lqY5+7jEjfTg&R6G6g_)c(W*3N84!>fOc@ zPHC@AD+kzWfT_4%esDIY%9O5bWT7@;?PlS`2y#3jD;`8l?;i6Nkp#i94U&VrXE6|6 zCV0sx6B8k=?>f0eHiO36>u1n|pMJ_zy2~fN-_>;m*1to)-_NI=jR$bp%ojBs>((iJ znveZcFz9j~>9V($7#p;js+hl#s()`ouMMx8M(KK5DfJg9 zSF?gJH1+yv(Pd7ka^N1XVw#?%(X)JzEA6eOeo(JG6=4MBGo25aO{ajr-xl&CO2RZh z^xXb_`7op7_9*_#iDHdy4V?Z=1ts^Vg<(fo6T{ZVrmuR69`&QbGGA3v(Vp;h4DJDh*G!}-UV16r*eG&tTt zgFFPgDDcA}ILMA~?UDgKBWU+5*u@1;WI+yLoqkbZ$Au=!gTaCb2i#KVMPRGM*0c`o zZ@2Px1zOay4)4yYVHR(m-x35AB$YF|Twgy4wku&0D27xXe1dJ1YyN< z%5$Y40h}SBac?j**0wFMpu|V=-KjD>M%p$JG!78b8ujkoLBI8VzgurZ{Q&=}@(3RH zfqF#ih_FfU+KjluD-5ss6_Oh4c#v?VTv;P-?l3?Oh9iP64I_}cqi}`dMN5U?ruD%4 z*WfXPRMX#Rg|so68%n{_s~SazjzK)|FVf9@WK?W|)TL23;7i;t7@n~$#c&)9l% zdvj4W^VHUYe{-IL-ZhO$qmUPc;wbWvZxrq$O!(!36!`Cwrv*yv56dO6lS~31dzONb z#&lh7amu4Z{gtWoHZ-0JRvoxR>OOs7Jds$+ zy7X+nhJSEFLD&Ncn4i5H*^f(hu%JJ!xxSV_f+bl=;{_g5(?RPeL~MaKI)Sxs?|MbT zIG)@NFK#B|^Up6M_*Z0$Dqg^)qe>f+DA28qk_DWO zER)8jh((h5)MeJCSU!Do7Hq)2FLi4fXj9LeoVZwb_m~Hd)*h@3!b@5(lxyGG5ICTB zT9_GTZN$cm*5CXvGZnp6FYBqE(MZ{B+it$oLRo_~z*W&OT@IXMryj8Tinvvny}w_g zWI)lEsb0|}y>PZ_)84o>^I+oH2trKq$Rg>65?CiYoq*ES0xOw$RVQrm&Y~9L)0wj2)A#YdOAUHR^e^3^Mc zH=OD*m$f+m7xk`QOvai|6oH)Fmd-D#yuNXW?|)0*>Kmz6&I>3uIG=Q`X;!U;H#b6J zJI3sBRljQ6A@lz+d;bINRZCCXKoGwBSIi+&9)dVU6sm;KKq>73m8ju{P_(hf@fK&- z-C2{Si2vT%wF4mmO2xH%NcJ)N&ExxaeDE<(^B`=s0%*bLXCZ%&M@l9MjfY={;}c0D z%k=zM>kNe&Sz&R8%6gMFUvanC5N^lhBER80ruqH8O(houLdFN~a~7Ir$Fz3rXOyWKJY7}^D# z*%%r}$KPOoA37g)VQ;?!d!0_xU(IBMid-nEwK;Xea4KzDOxls2h2BjjCKRs48BQ`i z31@;V&pkwhZTri@@#qB3%5?>=uE7rn&*(V{)8;z6;KQm8>*#zl4Bke>XGMiU0-Fj8 zlhP7&jz(B*2!uh#f>fKK|IdpF7ZZ{~MNUG%^g9&OX!_&Z(wIku zupat_kEYwLRq{Pws<&4ra~FoF;#JsXON*2U2BTX874Cjat0 zFT9QlW0>JG+9lpAhg2TIJAj-8=HEQj%FLf*^hV40MMCqkx{bdSW$Pieb>^!Gpub|i zeKSDFUzt( zlU}9!bo(Lf+B1)5o@Z=NPJfMOamm};E5RNNKPBw%(U7yrM2-5_{n0z7NEC^OwpheO zG9`FRDK_N`%C$9XpqueTW4NbMF~Q;IbnGG^nofm$0yAw#ViL^Bl!6@@wM9rR3YB)2 zBzh(!PQrUhr!bsR`5;6Hr&E=_UMLe`gHwI(RuJ)%WYd|3H_hhZ!JFpmw=N0j>nFI? zAyiwJT{t>|<}YvI@Tdug&1TKIMl7IQnNVh0$LiSgrcBS0aU&25&n^>@vGNLWdgDlp zy#-Mk-z`Ky8~RbhWWh&KKg5iXV$4KSb)C5j$r*^kn>iyu@w zh>-t(p*65Y98vSBiZVEy(&tjCWFoTVWS%|DLMM_dARLI4Ed7 z7)&gNh#^57CPFq+fF;g_v_K9d9rWyPoQ#oBm?S*VhB+(&gCeUnJN?-iP%tB>1gVqV6S@hPZ)aJ~XtqA;#u<0&hR1<=>HDGW+16tmnI^6@)Jq(m8A zv`f4fK8#xky8y&kNw|%1tn4!1CELAV;Wt%_9lOT%D|=el4xu zwn%3svpTtxWxGgjZd0Kyebm*p<@`}=FlhZ%UmMJ6wr@0Bo3xUxjW{izF)|uw1NpMF zG`fIyN?jysD>Yfg1bC$9*(pLb*bbTAponPZu%|(c#~7PX z+dr98!PpuN;urI19I)t+!2&-gxOL3QmQU4;?e7;eH1sjN74^nd=I){6mt`uYFa=fdcQ)IL1Sv7?_L%PIxGN`{z`4pHVc0RtRNZR1ySEON zR*JZ47b~?*xUr;UUOd&mm#?u9*b4JrOeN7mKF8Na5MRE)7LRm4U-o*pomO|$?fGkt z-^F?wAqX2H`_IU~#C2axdqIG-^}&le*o=NQE%EX5Pr|ExCbOCqJ&jl zJ9S-0yTZ!UGE{g+#<>uS#P)0lMyvhz*-j`F+74~6^Gh7x-RJM_JKy*VmL_3pUH83twvwjFI{*45!Q_`J_oj7W!*aGST5yX5l0ilQ1LN*u96K*fc*4Tn(?` zw)ijM`3(GW@D^PnQB5n2BOjKP+eWvMVX&`uJ#O#7Ui?hCp%GF8^CswZK^v=DhTLd~ zmB?U%76NjOQS-m9f1~T_SpeK)ibUhtQ@zHet^JP;KvSaibNQXyi@F2LWLgTmg;m4` zk3rx__@;8J4wsNJZ9v3e#0)umu(ZJ>OoR52I+s!?qnl;GDy}^z3W!o^7HX#$$^*S#k2vSlxK6Q;#G$C#fj2)s5#L0pjmEwHZLi-Mk8V1BN8EY*3Pa@4 zCc;iW10^VGjT`hEut+RvVJCo1j`>V{g4S;PSmfMd`2p}eBS{p=cDks`QiO`_TdMtb zlpw@zQ;ZT#3Fm9D6^eb{lSOrFe<(_0o!Yj@Yp25t5=9-QgsN40FAZp7MvP&h5dY3!vGsTg_V92rY0~klCN^&9V4wy! zA2Jz6hy$(`cgo$#lqUJ#yL);diHA*`$){>OSh~CYX&=Ac+tcZ9{?sqj4i5`(2)$1M z|98+6d_2~J?z`^bifhO75|T*t79 zR12VKJK{U;y)$88M+TR2#4HL^cGd~ZR4SZ=-xZrcZ_3nM$`PDSbaZ>6Nx`aM<~%2H z<0uzy+@>%K#o%-{bGg0EOSsZsC_b4QczJa6y7Kbq#jDV2=$Zwz%m_;Lw{3Xy29ADx z1+U*6!Rw==11surmkCYEPmS^QajiDtW*Q8uuAJ5EYdmMDYdOnmLr)HCGe;Y|w-7F? zntu$u?Oj1De2(D7J=lxj5#48ws$y_R`C8<;JUU9&3eS#SL+C&;4QA>X{9))pu0aZK zfjmZEeWq7f!gLL+s+QOZG%jlsx! z^dK;_6vYFlj)fd*sPCtmgi;3JXPh!FNe%QuDXLGsbosQICHOOH6EyfiHz-be#D zOD(UQPnhZ3@lqUW8`c^$CqiP07_qT~d|xShnv6=c!&O{Z7seLS3zO;WD{<+ltJnjV zfiA^tyS{5*_M4q{8Ty0ER;PD&+c+pgX&I;ryubkwcwQOCj;C4tU{t_R_xP=Rj8e&) ze>yu0S0AK2VU?3U6HJk6pPm7WHdkdAAJaVP*{xenRhcJWzp0yW4SQ!8OK*>Jj@C;1UYB z-Pk4)hN#WlQ6nr@p2U<(wlZjrVIc#U;>PEQ3>uY`GBu~h&mr?@jjPG|76k$x48a7?lQW&sw-AxrJHLW&BT`M6hwIh@*eGibOghUrZS zYi#kh#t4bpnyHd=>j|ZjiVHSHlY1=17)aE_W)adMN7)ltPM)8^QR=x;$%hrwu16k< zT$0MAm@*vei76$Ni=j49_5jY1|CAt>S5K58KE_Md5if1+Q!!6gP+Tbt7Xix?cn6as zH?1-EThz{@JwxSn@Gcf@^et)FAM_eG&C5=!(_W`2vfw={J}}I1$DOi~rKe!n3nd)I zOp-8X>qJLtDvUUk zMhfc?);_FLdnC07%Aw;0ofrh{5yW0KYhUF1l%Z5o@)5Y|+@b#mYx$I|OevU`2j6V+ zz8wBtIp5V}lKO5Yci#TdxWs?m#%;adx&0wl?`-h%ti{$?n8@JbesQCTmC7cQq7H7x zW9)oQHGqZTe`5YaOWG=u-n9x(RjvWH*&wgxB+Uo0C3nhSX(^V@MzIz) zA+TW+q6Q_s^;qq#0QC;Ju7l_4ZQBhV_ZfV(!N@p<@4hQ#wj`>_(Sd1=rJJ0ZbL`_< zHQTLbyD{j$YwWHU7vxYN*&m@}qt)B84{q0yWWR%sk0hP#iTjZmtL8-Mw)VtCSDKC) z@jP$iYv+A^S+|x+g$<=4Z(Vn8!IRR*g^w|?7bBQbl;9yRB= zE|=%~==mcZ?!H}-56c>eHOJ6c!mh|GOHTjt1-37;PI%TK)he=N7ox_ca>Y`68beEq zsSj{#j(|f?y7xpI(scQiwwOD|r*=JOG-?obDSSohTS^&<*VM%pSNn&E#PRnT`Y;v^ z+0TfD{{Zb&-%r~x5Pr{JaSupI5i}jzU;@fIev}~rt7!LxP~Pui+o9_a|NG8P z0-+V#G+yV2);ZsOzPs-`AATyb!V5PyJ=lct_mcmN#)7A*j)qdri7{MEqf@R)p3BA8 z_)H|jywsWV>0*ox8+{qUJyV)X0Uv7HfD*%|QZ2zAJ4-?6j7%9gOLQU==1`b&r=&EQ zRCoyIicMjhF}08~fy1e;w*zg{>k4L$RwAy5qHskogjp&Ehx0k*Zo3*mWwBIzni<&X z^>(*+dhgy>HN(g(;nE}!d_KO0y*=oCd=I;OJ=pE_IxaNllnHH<&x|Sbei%-<$;!A( zkkyZ?Fq7oM9j0k~l~ zBbx0$^((5+25%Gu&5718q@{KfGdpUU5+RzjMaD|6%W{8mrcv^X00L ziUq|S0lVVrfC{wv=L%(SyIP)%nLO$*#FsCDxA&X^nxd6?-%ZoC(@V1*k)%^el8XP2 zEDv21$sLynAEaepG@3O0Wuv7oV|!T-^1~pJWXA6Z5(b;R-&_ep_RHO1--yY{uNn$~ z*aZw4M|Tr(jjY{LxBiv-|F0L^nUMPr2pTVtZD?PzR4xif!Z{U2#B5@1Y5y;+OD4m2 z;4b`)C6A1RNgvFQX09}{L3fdm-dr^75Gl3D`xzgN2RgMUQ{h#&Xh&++50^>Q7JpX{ zJD;ED)JV(ZTyBB9L!H&{5OXd!f#_z=?Zr2@GFbDwG54DA&}-P-8HB;J`>GnF`-EYU z(7@n&e=2B>o0mH@8}Ib%4Y|eLvu^vMIoomw1a+f>nS*?#*8A_sG;g{KNc-(JJ5r`a z??I_R_|cF)qwVRoAm|!fE-WtGZlC76Kp+Ok9zH<9$;7-&R#W}pJ0gshP5U)cOK}(m z1!oo$r{L`bodMfIE@KS2xCP(l7e-4IM|@;g_VIUTj}U{Yk4#J=tDCxjz}y+4H*Js5 zNb5($)1To05`!|Tri5tN(%X`?N?7jq^SYmKSR1<&Ghn zSQl3Q_O>dx6R`W~7sa4sS!-0-Bv=J&TG1{4POf39U>=1wm>oxWtFhyfB- zQ$#(ndnr6Yzyb34%`>!w8(r3Go14j?Jse%;SHG zcT-i0WrEA8F!s58nXBjjto=B6dONx~?hrvt%GeG(xP|`-HJz-U=orSP>^f$iSM5UE zX;A~}1rl?4djquX$kg$j3ZnD|bQ9#dqq6pzT9Sb_^YlRAuDEeOI@&dly~)(OGK%(3 z?;k(uc)i5ngbVYNmo&pdHvB!Bm(HJ5!D2mOv*}h>ug-Vq2fF%Z)`2ITwCjCz8@1oB z&IdcJ5mH^XO%}MtVRavJ4R%N9Z*(z;#cXx;L3L_KbwiimWd^uP2?R z!>c2ndrga^lbSYmGF~rMWK|+2l4!*yXS;T<#IyeqDZN(ax;-bMCs@?)Vn~3=gkt3u zFHFbMp_5sVP12fY$(}MAEwRwH=&He*Mbz36o-+3ju?NnImbL1@(87MO z&!}P3XNPrx>_F+V3)Ln9t0Oi{!sW74lc?m;tmXoCpjvZn#(YxPzQL|k{y*tAf`nxy z{WxM06eZ2Ba0Q}P>&cj;9WsKk`SiT+8ZPaZK%Od+AHg#o&wVHt3xJ zV&5+_eYmfb8BRLsE{NSPbh+zt+F;4?4L zu^@ox@>5v~R3fA+n$Ck$#}pSnEyd}BrYsZ*|L(*(Kx$zF?3=tH35=$#FaC-7)>PO9VYIJ=^^O+X~b*$c^+3W-GV@?9}^qbGME$zBU4k zwy-%IwLhaai5zQoVPlYZtt7wZ!xR(?q)PwO$r)-{T~Z+%n}Thw6A1`5y3e^Hc9+wr`L5( zXQBJ67i*-|c6T@SI!R$K#%Jz@;ur;r2cNe<7yi`f)JwWRmgu`BgxbE)A8|WP+IGnC z+VMsXd{rCj1G4_rcS(_M9Bxw)f%a>dTuUn275g)xX%Se4@y;~aaf^`y9wKii&gAh` z4rH|RAQ?Oix2(lAl9L_HvJ@tg(1-TXr_}>^d6CI9dGiR~nSJA z`3#CujH6|mg^w#RkGBeOy=PClZZ^O>n2cHgU) zVY;3vSGm=Vywwojrg7qa5AH9i(`f7@jO2u;(F@ib*218{!5?xE@jv{Xu;y z+(PDr#?E^ZMC{xzo#JVgMxqYN7mEd7F8t8~^WT6H72<-)v2rRjApx}nND?yC_#*Cb z(-XQQtOT~LATYnou-)4{L>#0M!~!1aQuMLv*f#WaEf_uXj;)=86c0yrm_q>&S3}AT zfqZ($!fYnh67~u`m$VKNq=f$3Z`5pJJ0Y(?32t-5ct2V;6$)Z>VAvMO;JsZY=E7E3 zjtW?B9*&^stgt$~=Bu^{k- zX4=pr!(96hHD@x+T%QTK*Uxf)c2@pG3PNVDZ2Y8d`W)ratTln2o?@UE|ASc!|AV%r zgLpHps1&Cle<&Q%++dzaS0!G!rUcj@8ZMy@#0o6cpluMQ)6=v<%f4W4ZZ(i^bGyLE zH@Y?^`RgacJ7c9D{Nc+M-n)?7kjUVsb0Hijl7|O=j}__?J@RVm2S0+EIynbn0u+4V zYGGu-f-{@UqV}Y^eCPm12V6~V+5IzY&-yS^klG@rl{I%Fi3a4SS3H^{OwXX|=*rMM zCH>#=L4T@MUJpMSEBh_}ED$v5F6RK#+M27krQsZHiVVZ3u}*T?MeEvoNPuiM!E*)j z2SWfA(bV~zLd0Q?sVaOMx4@*GJc3(I0&ge|DX~C4l4`p8Qy-W^2p_z1lPKtC+Kh?a z^HV3ZI%<;n)T+N5>mAtem0uOK73CP*C^V{UvT?gU{et zV%UF_ub6%6$?VSr8EakTW-7;cq7H4zVO)V{WgH(6lE)A*j7xFobiw!4amOW4mt&A* z)6|0Y+0n6#Dr(+o7fUBv@%72hlK&Y&`qasUyYopL9#m&=|Eo7;0s2u1m5yU^Kq{f? zyq`tyP)f(f~)?5fO%d!&Nw(tS`vvSOaHVIixUlHN7qr%|HIeB`prv{E@xS)!^ z$j}Hc!+bZtIj?9gW9P2dc;<7gy3P6TPyd#t<(AxKILey)Ke=i8%(6z*PTkI;ttQ`v zS8x04CT+A(K8QY`WRk1*yYv1)dOd5+sSoF&#PMfB7;WI5Sk=+83kDt0Ig!8y5&OXvol%ityU?#3ARETy#e zR}e~vnt6Vamow_DmAtAO>2HO1X75o&vL|W1l!=HqM|q`)mUPvz)mrNgEP-QgoY|Y8K+?ZZLCG@^vy?6$aye^KMa}NU%^)at8XlgnQXf72BQ!g75*txy6RTO*zwx;hC*huhc4k&h=ETg5q^$U2A(|?Pv%%7 z>SBAH{EWH-6H@=(EI`Sp9x3+Rj%}EU`YhzK(xu}#S+jBqTFDq6YEl@Jr7y00_zM_=}EI3 zD{%Y^>C`Hq3CcEg=&c&V81Xb~JX~}Qrj1GBo?lAy

    Na?Qtn3{>gs3w=9MLeYVTJ zg#BL%`P83+w$6l2GUxD2e9dUvMrxD}POus|LQY`v%EzB;#Se_Dq}~5$h0)yy^)2Dz zX4TXn%O(q)LL3}{B6wAoKI3EV)gdb*h)qo@lph{*ift+K5zyM#;%D9K!_JQ!ultIr z3BvOikki3SYqFkMb0ykTGkzbAZ2g_OEdpVuPKGf^j^#z_SY z;1lrrRomx@r)hDA?i_vyecd!tA(T7)!)5cl+`fUtNW%1S2OLlb8DqToSup^)nsM`$ zlz)^FN`{SANKUFE-x*nSGD{V-T1Qq$X#a_*K}Y9&8y)yN{Um+tZk@nu3KDgg+l!QJoi`?w2jk{=i8y`g%T?-Ly=5{B+keypj;7OVcu z4R8>PpT;R{y;gfkNVjU{#Zh6-6m^B#Qn8NS8n{N0WtXOy?J7!{2H8hn@MU`xvz2R@ zO9#>2hfflHf+;NY83=)%E+zlSHRF&ah>Ox(T)X|uCH4DQ+Pd7&K#SUwh%Fn4{-If@nV)z&WVl~zwacGq7zH{VrKU6X36 zMCyPsda+$IbuCm;>3KdpQ}8f1)jeX~^X3zh=IJp}_%CN4kT45eZTt|fc4AP2K#WKC zrVUHc@1hUlk{yU+ zS)=I&R-T$w47qNIWcgaG6p*_v+*WtGE_!?f+G(@qF=MDgXRc3_HS|NTM_=k%c7mJj z+_~D+qzc^l-xA8)a4fkMRM@{nGA>wy%0+gIojIgGlFv$42asw5gNB0aAo=w#2k(yl z($v-xdh6vZTcfh?XS^OQJ|F*EUT29WR{brmHqZ`hpG2}6j-Xhm>f{eSQu({3-}Lm! zQz2~P?wk~QXEWU^0tyoOh}T-V9qz`_1+oPYsV?$}h0!jIGDzAG9ES>rcJ zT#AS}2SXX40;K^#CRf8mLPVJ%GzwTL2n86i5NkCUB_CBPY_EQ#Rb-ju!t8)cafeQW#cmbIbrkqj@LAf@`V|C7)ZOVO8Li4=B`yx>D?H(3ZNutH1xtNwrBv>TVK}OG?qw`sYdUcE)ctDj+jHjmI5+t5@t6WP23Frkh$|J_|L(&7Sh4H{wKc1 z)6bM)$Q|bQJmN=y{y){!t%8+nU&I)8kP7gJ59xBWWDOr%yqs>nM|vW>l#6_Tea)D7yYl~O3##0{&S@J zTG?8;4Kkv;Wkhf4Obh*$85kkgsi4JGUL3$;NqNQ(Fy7qJ=EU|5();f9OKsgt4WxKP zO}9(Ljq%oSvBSz{9^8O=#MVm2u2T-0;uKsO`q7N^8NuHA$946i)FU!+PyQ>*IACh; z`o=dJdUs#IY6it@${7`cNg5?9zsXFqoVWg2p>i1)OhDAGIjm*6iM5ZEv3h-AHngKS zXFd(`UC7vQ2Dd~t4)Q!KD16}xIB$q+37-;zDk}d+wvovdkv#oqr8%NxDF0M!v6JB5 zKua}fWcak`<*97b`uaHOZwS#uSw@%A1RxwXVi5esJyklSE-CObfU$2)B4Am@EUAH6 zjhe_jZAK&eNs1iAZ8;LXt2f7&(Kd}49M$hYeoUefE<^%HQ)x#l$zSIJhbvVPbvsRE zM={$(j_2GGv=>Eo$&xDYODO{{3Rj4)_LFM+Iw|a%Qai)F^)9ufN+6}B%D(>>JoP@# zjZqWE&JJbqb3O9S71<&^r+jAxxol9>JL)`T=y8LW?*`vF9!KTL?j_&BHq*8_3n{Ph zlZ0^wV@z}&ewFa=-21LdKbj0E%fL)CGMwgTh7};t-Kj+TvP|j@Y-1!*%9qpb;y6$K zk-^G~z2tUyyA=r-Yy)&KwAV0AaD4vSQWNcBh4LKH`FfJ2F%MO#5~KGCw?vU?CMQ#_ zqhcBr=rcP7!+Uv|D~v0ZaX`uxvHOAs+#iU+fwWa3k=Rk$+*+3~5~=faKCir9RD@hL zA>t7H>jj>QiYbYFyXJVfkm!x`VF%}B*IW`^BwOwm9_HWa;np*ah_@{n@xghQFl^&t zAMzrUYsBMy^kyWfflOwOy{QACGqyI{+;PlaLm1H9^qewGK4`1nNvBLo+00wTL*Nmp zb3iQb5u*eaVgwCEswuP?2SdiWZ7;V-*E;CiX*?L=f}?F>MT-_0rq-)_`)ajYokuj3 zvB8?Nm8mHvhQZJt!PDN|z`Yitvs-UdUlvT^nVaT1Mr9 zHlx@Ioi4o|6_CNm?{0M9rKX2+5cfuF}ylCr&??(@(j5SLBQ(X0m33m>zu6)U0<3;0Q zW#V-s1buDKr%kVq!s9nzgu+OsD(}8Y5gJ@jKOA&Nom814**p>{FHR2W1_e%;j#lXq ziW+mt`h7Syfk?z0;d=YsKB-_@r$LAiec%5sL$Hvt;tf`wA#J;viDd$=R7un=Ef3aN z=80A!QG^v#KN-#1uFf~m*qARSPmtLBn=^QuDzUHPPnALI6O2+vZ1r;V!td&{+Cw~6 z0i0TKB^jV}PVjOydRA-8b-bpQ_pfiY&2iFXu#^(3;5(orm-s!?DHj=k@(nn|k~r1^ z$ieYpu3-~IbPfc30^c&bkGSExbecj{l}1H7jEvL?d^CAB>z>LE_ZAvu-=;tUz$h57 z&iB9mBSNxY1Twen)ly1yOCgQYW_^ECsHMY=_PQKa<@>Jt6)3jSmGI`p=dYRW z=ezC`+>ayI6cfR=PMkjasNR1EA1<`R-gYI0lk+Z=Wap7OPBclZ{PX$2c67!2@Xh(4 zU6jT?|2@WQ`-*)?jsJU$^E30Q0~YxJVc!1^wB(;krVz&f&vF$|ih8P2pF^v2iKbdB zo|^Q34%49vHLL^UM*YFLEA9@-)lFe2FtZ)of!*fYUnio4j14qx4M?o=vvzy8h#d^M zgZ+jW@EzMJyBW|i3vCA|)-2AbA@zU*ec{jy`Nc$)nO?V|$tk@|tHWq)c}>LWcF6%_ ze#qgV>Ye)kS{FG)i+BrzXap%!%k!4zn4i%GAeK(i;5GxaQ>)Sjl6X*>Pyj_eu_S=+ zEql=40INUdf1#ZMu`pNXh95(qyH6DoQIE#=gTHLNWN!9A z^Oklux40w7X|=q6fCxpr7(DW0;K)D%mrNxgng~?8#F-pa-N>0Wf{I^K|J;xHTNLFM zC&CyxyeNk@zmGm`iK3{5TnPq&{S3vRJ4f|l!D%R?2$pKAfTdZ{e}PpcFPs!8)hg1C znIQW?cX5vd#p8s!uAkP;@ienY3Rb-^RKrk{!x4E3sDUk6GfETK5S9c}kQOl_^})n? zW7=~51{ak79p6XJ@Bba&1kvW8y#VVq0o?CjV`Kc7TtV3d54lwCr6P~g`waox|Li3! z1zOb9+p2zfCLep%8a1I1*w+-h2~Xu~>LxQf*O(khTG`222oF=vT|D)j<7y|fe6^>K zbZ(S86BQx_2T#DYUo9RxFk{Bb%|h7z2@2%{Yyk`Yv)rJMi*5Dui5FGQ{UXxm=ipRa zd_AyEmw~tu$kAJ#ysLpT#FQ4j!Iw||ThAlEf;wQ6`-*7e9-_5qyb&0}g4BJqb9`-E z#`|RA+ELE}cn{!=vYFvy87i_mSWE*q6&T}Sb4=uvlxrC+l{wtjxw5T-J90F_zOB-{ z0@5(H@+2IH-#PkBe2Rc+X(o?uKDQop(6PiY84}dNAXIhMw&X!WeQOJbko6(CqW@Ztq<;G5)}cf!oC)XnRcqCxv|WZIpsmQPra|yv$%ze1QN_eW-fEly zJDAJaNl2H`k2aoV)t0XQ{|wHCFaQQud)gN9i14$9Y{)4m15#Y+tN2o^h}+6(h^MTQor)oY$priGLKwd=k(?DF>15yY%85*mVlV{xTPn3i$>J@!`gxE|Hq`*1eO3`c@8ttmAmOd-V#sZ9Mi z3bMRMRGnZwOmpV*D5NkC7NB1^M}%SopHiq`1-LNzaKSy+r`#GzB39R9^_Pq8Y1E>Q zQ&nU^xcA9}LY!c63h;&^kah7MJ@j_13F5OMbmME)UB9JluQ!~$&C&aO4L?@;A!T=~ z)$bKL>pWFR?Z#lJtu#5$VyCO?$!hq;(Iwnnkle>amr6`0iYgn`c5hr`GkoEwo&Wvy ze_6&3V~w#kP>CoKfH)G~Nb|qG8H^jot^|`eLvJb8v`@stYIR-2_ z+ciY_GxJK`Wm_jztr$4W&2s)+_O$Ooq@C(l*Hy8+q6mZJ3q6y2>Dh~)ydw0TDY?;U z3v2`>&K%#h6R`4}&^(-0zhj&uanxXkC*M?h-c2dh2T2s5n{v|+a7NE5OI&3mrnk9g zi>&^Zj!;J;S$-y5I4)Abng0kH4j#pQ!tJAKt%ffpA|GKtIg!cJD}za9Nm>F9rpe*z ze#>@4<*|J8ykkE(2PxH5cS<^ccY0H@aptkPTNJ}O(<^g6GVOv>iNH_%P_X0w*~l(> z^ut2c>*^Fy5yA*s^L}acg$P`7N{P5^?CLBdHwpnNAD`F{u;Ew3($Q|@*sT-Ovk3sa zgXL2vSR)IR`Aq{ceI^CT3Jd1`SYuJ8N+x*d)R_9JVE8z9@%%a1TD~NU$^H)hW)y99 z&0`ENzizM5rJ~fuY7tFFn7qs7ySN_>_F0}z(NU!P0s;I~bH?UE2K-dZ-#kFiGPo^y zPN3nL88*BN(Sqpwm3l*+TrfoV``D0`VdBDkxdCeH)=oHO^7(Jiu*^b;`gEm4Eljqnpv)Bkzv3W zoyW_{q1cpalNqP1z0ft^ZM(sv*_NWRASH2uCVpmcgh9d=b~qOfy-1Ui)r8)x>;0=5 ziEQ=nG>%|AfKyKDv#Kb5ZgtHfa!vQ?#7CcYa{NCgbEnpfYp5Ot$s&LRKw%hLAD_m0(kj z?9xd<`^1Jupjlz*5r{H~R*C+8oS7m40*pv9uE60L1!jzeaAo64pdnC)&EK^=y9GSu zXH4vfJ$qVNwy$h*|8~9w$sW9Gp7N$kzZCiDu17B(e3gskKD4Hh?Qph54|ky*k=84=!#4t~}3?L^AJc?_kJ8R|*u z*I}Q=mYz9+stF8+hR5}1S>BTOqtl84Jy7o?*JE=6-|VmWNfJu|82xO}w*=0JIZ4E3 zzc?X$PQ(Cs1ESOVG+^M$^-T4%S#z>do@I)rE!#^&DQBfL=I;|vB#eH zh>W2Pvu;gd@ktOkR7iQ5eRi5#atls@veQs<3ACe&T0u5%he8v2N_$4%_~64lKF@rk zztDi906rxuFF>e7+2hc($5O{|`x0&Ja-d9wJz7n7{}7dD3FbJ(!BJ=k-qzNry052ayD<2pU z#ZMSmiHxztq0t%Kez#8f)5}Szh}m6GvrG5n-E0kSR}a49YyRW9j)T^Y!hbKH3ziVy zLK~9q3G47`49mX~>7xKF5q6f=rTB8vb|{nbS#mC&ENtcLT8@+GkW zq7>5oq1rt;@a;WWwN})h-_{lU3rZ@rkaIbXxGNe>bV-Yl@HJJo2B8+G@b2qlr;Mko z`_jeP?5S&`O6qYBNK`9i8=-q<`bjoCiy~3P`X$a8QE~;J+dc5&uOMyD<>v}sd)Q#S zW2VI(rldC{9by(a(o0bDl`Z~-7$YV#6iGPTW|3<}5d67WA~UG92F6rn+}sJUOr8S- zsq&tq<7`B&_6!|cGjQWHw%Y&#+kBi16GuRj_R=;el8%_>tBa?7Kh7Cdy5G8qYbN@0G8XBnYv@Q(p@sYUordSf zpQCTpI<<=*9d_&BxQ-PoarG1oIxsy0WtCR-@~^(9Oqr~ zztt9ABrgcvkus5sY(#nZl9Uyx7ksf(Hjj1q(q(ECxo#YEuA4`%SHW8Kv=U`87X_h3 zWL{w?2cm>EY8#%gnKQ(|dTFg2nDSArsH+;mp9;U7_euh~s*rX7l1q{w}9u`Y#)-81$#!0A)K3(uJ!%g#GhLx{Rhr9+=Sm z#Z}z;I~PED1wQYav0qPYNhGqF2Yi1f?VhHBZ%1yggvSEaSUNLwGI z*$Wf9Y1?n4=Mhxb*~0G$%<{I-xM!2HS4K4?lCx?J*Q>silju@gL--}rBiYF;8h*to z7gQU-rCRO{lQawzS0vXgYDJ#%iEuG5q!p)9+@4|Ws-YLh_F|RR^=Jh}L+=(sBPNQ- zr_)7*Of7^WZIuy-0eqel9K%gwm`?U(EZWmBy2!1%p4_plg6pc}xNyYR4M{+7_5pzgDg~JTvD=BVK4&h z$z}s$`tR=f<_Jy9QnGE21s{XG3Ww}z(a5~4XM)x>g?%^>!||Q{TBUfN;B1Dz$*GaM z!`K-o;?`u$tj)LR4W-72)F+kY2@k!6rX3q)PY}oo?6iTE^+MRk0C7tS<$fa#A=hL( z^nSly_BZ)78+4@8#4utsOZLbmW^L=aE;=@;b1V6#QNJssXhOQRNCy-hyuNX$UbIObSj zt~(Yg+&87m0EtBZBK#$Tlk0Es^g%YwY+(3`C@+)whPxxd5JPr& zpkE3w#Zv6FMp=gH93cN_(5%kQ^QMdyehyN9t)XF+-fgC@PI)xC^jsoKI6zTn(CQ45 z5rtCmaD7TI%Nn-E=ePajegF6uUE4ycqeM>cK^T5}3%R>3 zW(#fda`7fLRwm?VUt*&YE1EbNLe_0FopwIUNvVIoCtm@{i#)iz+JA2al{38pje#dK zuoFNi@r>S#cF^7NyhV8d{~Qh<)|dSC&=hWAV6>+^z}lw+KAYzlZhDLV{5u7zEGvgK ztMZGNchT~wC?Nu8aS!ji^U;Ia_Pleg`-0{0*x|K_uKT-;r>*1C<;AJz)1x7c)i<#U z{yG(Ji{#_br~YOIhNtc4iO);V>s@CVp6V_8TO0ISKfdSaf1%$^PQZ*)9Tu8_ z6r%nZ-L@g@(B{1x>|C^tegm*u&C1piCQ&4%6t3y7%N#!Uk2>WRQ{*@xKU zhnD_DwL}_%fB?en6JIi-pYxMV2g_kHCLHw++4wzShX|_7j3oDv1tVbVrSMKehh82`5!kPIGro7HoYqF?V5ok( zLypMz_YMP>U~uoH)WL<15 zhSr-dM(HwXa#N3QQySB4Ut>)Mja3^+_yNmgZicMb{aL0VCHlark+RKN0Yj#pMvJSh zxG>USu>+}k6faRwN}6evO5}#_m|I{7$$LLeovB+Zt!R7pQ*l_lmaiEr)+Y!{rm8%D zx5`^H&xV%mxSx+n*lH2eculzt6|3`&!L_ zLuarOrR_4TaxzXN0+6T@GS)3*i?oI1FvDJdav1f7khq!^M=T=h6jyZZNlc8n5k7Rq z>DU?%O%(p)s>-%h(R?kwTT)CCB9N?Gm(HdG8nu=*_ajP)o zsLC%Qj7QEl3vI@y{hNa{&yk*rPJweMrL!#4>3!efkKXG%gtqUyemPkIB2uZ4M?IE_ zjA<3iUU8S?J&yBLlc&LZHU|-kVcKkdfz%1S#2ko($y%K`cc%lcS9|o9@fozXorB!H zJsQCH>3^G(HTsT}yc*Cp0K&n-IxFgjlW*E^QONKQ2f8NZw+@=D2KWU@VBGGS(Uenqwk^0enQK8fK8v z=^8A>JVz#9V!bhY;XUoBx5n*mSS*3gZDs z*Nz{$FIQfe+9;UmY+LD|pOpy0oLv6b@;CdhMKGh=c6&O?_=R)qZ^2CI*TMT)nWFqx zLrz#7j8vKDb#4s~855RmCL42Gfd&c0#4GF4D-NNh+wKfkPkGi=1tBGPeX1`{>Gz@wwE1srxkx13*?!nLFf~ zW3p6*DeaiJr67bdf`(VX0ev{wp+zR2v3sWmPC26bOLD2V6FXL$G2AXR@j{+M{p%tR zZ28~x&EWUZbF1O+0(T1rLkaU*FdoiziE+$kw^iU)D(p82Vt+KMK$zC!2)*pedvY^0 zZTzH{kWxsv0_GJv?)o{mh5{Hr&{0<;AT=2b_h#il()Gc93k%@}Oso!SbY?(<$c9Ga z)4t5HCh2e{e}kbQ&j#X=LIJG}qEy|&iEK~u-Xzz73~mHG(N?grU#l7ek|pW#Sc=r`LNBzO5d&sMG$mf4}=%t z(wb;aNxz(soGH=POt6X?kJ1S=&0A7o*$(=PDaU97j4)6)TZUrpBTm*zYr7!M4tVMB zN{qSY-YYjgj8tdEq7U%DZT3np{r^C+`pue!Hf>gzF4L$@VoSXy8T=m0+99*(6S(r4 z_VQM(IYr?rUXFbka?@}#5DeB$TMpr5l$gpWpB_Yt#b#< z0I6WYaDJ~HFob}(r`p_Ez0S1tFAl%3*x9{O(^lRDG{9bJIX4YQ*ku8jtzjscE^shC zOB^%lB|l@7czm)(Ac+TA`){7l7run6A;&h`7uP3bQSQ|nZ}CyD-V@7f(acPIn}O4t z0Dx*KK)#e4UopM$k4f0ROO}&Q`FK=&C;f!h-Gji)KFU5iAq-5%Z$I+IFNkO5S**s}tqJ>;je>aPu=IRy}C#Fxx;{9J!y)8fO6<)1b zEJa<~a5(;oIBRY3>9L1bRNxGxYGb$2=6U~Jur|?@PStSmWjj)tdO(42x1Giit08FjpL%{KG zNSo^}h)!J;(zF}KpW)^0@4qH(Brn!)K$kO&@t-_$o&vnHjysO?^rUI1lxhlv^(dH_ zC2;qnMaKdjfqB5K;u@x?@o|O^OomwN)ixs691P@;gfcLKwzI!+7dKoGxx*WFvuG7% z(zdrtU=<^_AP!$|T^O;0@ydP(^x+XkDfB~$TH;x55k=EHCcm}xPNbAdnxnD&ojul{ z`^JhLbcbw5RDH4Q=GH35fK!$%ms9Fy0N|e=|39oiI9l3eJ07tvi+md+#%2hVkzrU? zG9lXNm6f=kx)%1j?6c|i{+#+1r}Fkd1GTRBr00FiI&L5!a_ZrTh7*WML}f>RjQ9;Jki`EF*O)xv+rAo*lFJzoMCTQvtZRS zXv0h|neqA^?$|xoY>G3M`*#Li5QgBB^>C$uW>IS$nx1-5)1+Kk@I;(lr!Qn)S|xpXMPPR9*Ve`_ZKO$d^w;pc@|(e>SH28%zNrAQ~}!TW@}YrSqF zr&jd^kNPi~b#}PUAoWiMxFizDPWsi0xg0wBbmpuxvM@uO-jHmX+>5p>hpimE^{T8V|@YU?@XEqo8A4O0SLjdgi*rDEyuWIHSRp=nN={4sj03$ zbC&@>6@VmHwoLb3?G3M_#P^=Az*VV|n)9|EF2F#w#s51g(j;uq=&t9RtBn&2Hw%9s zWpl|B=H~9m6q1L`8}Bx|fgmJiU*70EVgvG;YrWLL0~9AT_M@QR`)d+IAR2pDq#A+v z@3uOMKmw__8a-vVE4Hd2Y|I5h*Rlder<2Ov*~F3Od2pk06|$r531A8g_&`{c_z$gM zl0b8ON6w6}mTwA9Sr8)Ih?FS$@T;(}jm4{cu36Vj{D=7SWwz>e&=!PT@!^(|VB=<< zlkV}))aSD#4Lzo{`>KyUswe48AQ4IaP(xNstAtlE(Yar^B%UQ3nx9%jqEpS}H?^4c zt0APmA~ko2zKNma^J^K2 z!|cvZ-#*dn-=3gAVFGyXUVGI>R*{;h2jyy*r-_FI75Pa6#E7j%GiG$kT9kAQ6XIK^ z64q)ukuVUS+Wo6jJnyRS)!R?_OXEGL?%(7PNmz$n>MX0G6tc4(TIV(Ec+?7H^CjVC zpkf5{zvF4~K+DX-wz34*Mt~LbOfpX0ApnL(W&<%P)fCA@UoCD-xbNDi-SViC`d|Ep zAu{`wVET#gmyh9OsAe+da4?Vy|25NUR5>isLLR0aaSx-bfUvWaE&ZwEJQo{#MX?am5mR}aOr^k#6^b@n zM|Y_WJpm`>KWSx0hlc>y&&9t_n=OF~-k)oau|oEdz_1V{g*_+Ak$4lwvqtJ6oI{a=4r$h%Em9lH@d{S=1{>(w%sHh{~53bWxx|&+1BIl)hX+#4c3cfg*FSK(78P|DN39nMGR;?eS7zZyzK%;O<>{z zuso&zIBvj({<GRwt)Iig-23zatlSVIxg~&11>g#HSZ$vD5b!y-N(?-xQdZC;A z5jV}%b#Qs$-&KS z+dg{Op3+N#zkTa}sy_Wwq5ws9+66@!fl{GGh6tH5Hh0GkO~<=^V7qb^8HZOA0v_0~ z5)`5ngDE#sqJB7fFrI@K(X@O8%WBf)_&AH8mjpQjL`5zX;-Iha34Mg*yQ;}@UuDg^ z__1I7;H7{o9sG61YVh3LL5w)A(;!*2?@{~G@X+;gDT+?7bIO%*1qpQ-5iRP2}Yw)){E1>iqp0Q>rdYe{sf$g-^CK?F=5~XCviq$MzHJL zbuegc(`GP`a+yd}P^+w$-?_)T<4%gCzfxICMCMmvdOo+@UI~s7heXOD!hqIT!_ShO zsw*Ka@ z^ZK}w&?!O2A^1K71l2Wv9VS6+Foqa0Q7+hOKE&EE^P7UYGimV(_x_xDGxBm1yi=Tf z6-M@t*9&0k<>d6*uTJrOKOSGLhyT1ymhS)asP2x6@d7yMXn9)17K2fNR3lO}EC*?Y z=s{aeM`#68IGPG&L?V{SY<;SclMy9Ltf4$d>m=M2(ES@~2g3%|x}qq}a8-VD>Ia}v zYOpP@0Rf6Ws=5|ctbqxT!?btgjjwn`N(Exf_Ap)g-k7b3ZXgm0IjpS4Jeo(Dtd2Aq zZK}wUBQ+l=N*j}N6&vGxet`>*Gnr7!!aUdL&^d-hhDd3$$T4q+YxL!qL7jLB7J zVzG!BWsRq~HO9$Zl>N8CFmVDi?R}eXuiq!27-3Ja;o;$-cWbsxjks^Cn$wo3hYfS0 zn!AVBz80Rc)8jbW{;ohc7=-t9aE%N#J9mSw_nQ?onx-H(HfShj3_ElkohUy#TV{)r z6HEd`4p|qhDkN1Q^K^7(Pv7pt);osd8*k*0yi%7l%OnWKT3_#CdLwE zPQGi4QQt(ft#hO`ixdOzRr&pN8FHK!Gtk5#iw-zJ*(Y(lVn%w>)f+gusP-bO-auYR+TXkz+E+5f9&*R2iHOWl=( z;fe9o%^WUuXDpFEmN3DsF$AZb?NS4I-&pUK+~EUkI8sb89> znridh*R`ExZRBUiV}*r4v)&>p-j%VlmMcSLC82QcVyLDhDrJD-_>v|u38>rr#+&U- z8kK{qRZ{fMnB4(X?jKko@7SHG;LU|{F7##QcUUTv)%Iwxi;l9^_DcKVJSsbHMtG6s z$U2`;MYY?i9+7yHl>O|8HGNXDY3&iWeOZ|z=UdaUYuc;Rsu1h0<_NaWx+Pkg&I*vz ztUwi4k?M`WsBC#jtWnxeeW)N}SXCx0Ol4Z9Qx)&eBF9!%o1*)b-z3G&*!(2PhwRV7 z#=q@WU2oeq6n*!vxGMr!&TPvqx@5?bEQzN!0rFwg2KG=C1|?lvL}XGUsW@Jd|GrB~ ziY294gKQ6b7$0nkA4m6|b9kx4U$Z3Z_`ACu*oEmIIsbD$6@0PK^Qlo>EcHBy5{Ys7 zzPv<+)0&>XjRTrm~FRdgZDMj;%oRuOmI_Krwq8^xE2fp??P-r(Kn z?fW8En3xS*ni#y(vuoJjhtbdPVQ+r~d!td$ZB2QELfhaIV={f<`%7+;JRC-H<-6CU zEYyB0Ge1ma=&zVI)OQdO4$ZxRv*~YeSv;5U;uc)9@PwWrQ$v!(2Je^5wb5y(-+85G zSL_xw=$!a62{XXN26VBm9H5yu==Q&H4?-HCcvGn{1}-2}6crk6(Ncbkz+jP!$XFLd zEKP_1JK;4>s16dqCrpuPJb2`5Ue2BTL(4=d)B2@`0lvyoT%jqP(7){#q=iR!8t=^I&{_)BB|e_`&y4#PzLD5}7C&q1IT7yASJxqLl(| zR@|lFGNXA?QRafMFn*Fs#uQsUq3{Dw5q3zmNW1PVL0H&Mh$I2%hzYR;t5C?)@TBc% zL!wU%9R!P#NzENKmV0`Ra-~ScB3gTZX|RHQVRJ8ljNDU{fSn@q=Ty6sJpNnJvVvXj zJEZitskPNDBY>mY^1<;E&CHE^mDFzSf-7ytlJp@OnmZO;#MgLlyvirPpI^*^>Ev`A z^!ng!sr?b&(tya*v=2t*NH3`HeIG6gs@;pIV2Z&y;p7=Qj9BrmT_L4|Au|+KVp5di zNl zE)&HWKRDQ-qokOTN;f=WS+6|OgCioc=(ngN&rrEkmEiP8*ZB$!6{<(vqFi!4Y?6*j z(PzgIbc04#pc9#=v2#y|)rS(s-6pkkc<<@2X(JZLANV~BQw%J)SG=Q)RZ)K&;lqMs5)Hs1bhWb*e6m};jO!tk;t0U3wH6l)!=5WG4OFPpDyVEJ9=%&pG zu8Nr!lgz?;x4XHv-hH)Ek%hjU!Ldyte)s+hY;8gJ%?504bz!sHZTrw%aFoU+pIKX& z?If89o0X#uSJT8Fle3XY8qAVWu13j}>PB-9!LehnEW96lfa7W%;N>~^;ou3qK&CsS ziAz2Sm209?WD-4Bv_ol1Di$X*7)xSJQCb73k}V5dNy~(UONV0|PUpX_&(U>$Edah^ zj?CcpZM}xUw*QX}z;kBIljR37E%Kms1FedVuA?Y&dHB9^V})|JrIrSm1g15cff|EV z=TtbbnV>(UCc0z}(<;aXl|{l>=}rKcRDp!e#D9x&L}i3=DYMzI&ORO zb>&PWAT(1y_1SE1FS~xO7CRMubf)7_6~brPe17N}}T`JTcFg>?E!# zC1GKDk6^(xo8HUrNaP61Bqle0dYU1O-DHHM3mDF%T!76{sMq1%Sf;zm&-<3{heIip z5x!tf5nA(7YtpvLmJre46{Zehxnlm1mKRE-f0eSRsvAF2l+^{brsg37 z=+)fU_9hsFj@v>A_T7rh`b(ZEONR!aSK|j z(4yZQv;BC?(s#QQg61Ce?8F%2+YDdydNr>a-|7IZ=@INf>!9&MPfJ=$^`}RA2X50^ zdTEwmR9d=*rL2~%ox3Nb%raLde;eaFwt5}`arGgGK<5E_oxOJ-i>ro^EKQHZ6&vMv z=s3p}^;$nrK@TdfX7RGQ5<3R%yR3YL{TWnUt4nMa)+bRroqSQR?F9jSN5!?1>oV3M zZlcAk{?5$1-90m5%RkW3Z|z!JZ`(K)e)q570NJtATMT5K`gWnhY z%gsRW$wb|JnsLnrF%8&FFA`ct;Xunppcm4Naxpa%_dyV4uRmOqJ0=y61o=4~dlyj6 zrjdLg_}GkqDfhnx}N3XOV=5(LcdB085_6$?&>k}?_aQzAzMXo`)((>G#(yJ#y%`H`711-QNs!DZ zY9*k^jNUPL$l#fjEYL(HItZ1~LX62s0zRhI{{LhDl-RFIhmemfWK^-YYk%FO&)z*V zNrI3n^`sObd>)5v&V*KW=n_qhKN<~$WYQ3?7oz{ci6=$s^zJ;M3XAFYx}#H`+fRcvr@8KiJ{N z|M-S`UEjJGF8uqo-DW^rIlnnkyp~bGlw!G{?ULmTLKO*yA>}51CamxrY8jXibg{7$ z$CyewcWUR9hm34N?FP!+4uM`Lcr#+itSX>FWXe`rfZA+h2^5Bg(!bU~ho~iv6gPQ+ ziHD@U0MZ6IgLb8_=Ea3kVHO}Ua0naY*j8eBS<2o;d|a8aapK+9BTm`POtVuvMF91m zP2W47GHtj)wN{}vModVH19aU=rG8th{rp=K91Gr=F~!wQ6f?nO^Yb=2Iyxdihip5y zrdiiazcTZ1@tO(`JW6_Dq-rS%%tTuWTD6jF6=3akw~Uz(l^CZk{VwNBc;IpCQuykiG{sY=r3Bk;6u?TzXjFC2c96)NNf9>}lD$JxH3C2?cxX z=qG(ywr(zcwv3X>h9+6YZDkVC$~LBmFxQiT!%WRcrE&L({pk@5{8oBtRedbn@|8#2+GQ88th@;+|o z{xoqWE@!xv$Q;azp05thQ|Wt)m(Xt1-i1D>#cRX4s-x)+!aPB_7RbUwNI&|iUMHsrHm~_SN#+Rb2B*>w! zEKsWrGl;yYZ3@Ta1SvYs4Ol{ixwOt%dw}_VT<|Uq?d_E%Xu+yn${&(SL(0^7Y~lXo z#>+#FtLtm6ysxA-d^6S{Hlt`Ga?9+qwuHt>4!5n{{KS6magH;BB?;l3T$k&7X zsal82LTPW~dRG@0{mY>pz;>GqV5`MxNZ5VAVsqYxB!j|uf+<&@a^`rbPv|IGXj=mX zkKvgs0lDPt6%RR=l50Gy9x=USOr&b;uSNUCH-i9A;t^jhC*x(G2__xh+qYY69_xqX z*JG~=HwgYfIKi+3;sj-7jvWp3lB4?1KS?dYv(v|S;+~vcsoZcsQ8&R5S!Exc>+=hO zXQw_3Agv&cmR!$FO6@xn>`jVg%+ri8A2SLnb7v)`7QDa8%G0f{_g9G-Mt9MUijCGr zwS9gy=-&*xzj#*fYEyXW`_P=u2a?AcYn9DMY&>RTQ|ucdvo@J7zH}!SiLv>(kUt|Y zb#DzV=^LszvC8>f5rNH~qqwFjoF!T2Z$(RMgIfb!`GI?)&JNq@zb|{kv#ZOJ^v91g zShEH@)-ZlpniY@0%(o@F{!-#oqaq?AIR}Ezz5p&lJfn=`@WF8R5|mOw_*CGz1lM(o zt=wMMTlL#y-#*sFq@v;TAGbcc*~{UB-sKz?{9kPK{99VQ>b81i;rg4~J>L!&ulntt zv(rsCoF%?{cE6bMVR8^ykEMU`zw@iP&ylrW`_Tt&~Btn!Ak1=xJs5oRYhY z+@j0tu2pZ@p1H8M#!@ZfR@*$I9PSOGz3rW2@j7i4- zy}PFugv48jKjcGi23y?S?(IIi`|OG1Kf_U2YVPfoU=O z#{SjBx3wGiZ7)!+KfI7MX;#eE28put?VDS;N2zEd{2tGp*+SzmkTc+AGedHBVu)a7 z`t87pw4gMrVxmWZq(yiwaR}WJ%4rZda6DA;lu$ zHII1-I|yge9gZ|SYqee+JZl|3k6edaJ%bzVK=u5h1211f>yPK~;$;h7v|2SI>bW-h zij5y>9jaH&=FruniPf-!anl^*2}?C|o;58mu$p6`G(8&?Ha7HwhKufBa1(ux)%$l~ z2CFCSAqv@`2(j_a7`eQ5l5CcqCWP$~+II@{NNDL7utB4dWfHQ&I;LpLC&9a3>T}j0-7r<$4HZN@81?#~yLa zfFCSmno+j!{kgJ43)Ofr7-glY25vR+0&58=n+-gSKQq@vO3LEM+C<-$!}W~{a{z=? zOz7}jIr4l}{Q#NNAwgI+(qfK)yElO{D8PU1N7cy2)lFjZW-b>&<-FLT#}i^33-cPDJ6?O9RW6mjrzRo zs$|4t<)~=KzxtrA=?Y$Y^t?%>_PD{T+;%YG1;a ziS`AS$ofFI*wocxhUoRXy${!&*9(ziPE14>jLgek{`2wtW;fCH`~&IEL1G8f@oZviwEODeKXrpv9?q zO?z5Ki*x(JV8RCBQ?nY`(ZMNO9vzbH&zmbAknSc~R8Kdddig+2ondT&;D=~*Uuis*cQ&&l3xcI_@y zMLjt)y?-p|YDpiuVLGHz6ice$YEsB<%E-|rE2ZCcNAs{Gio4~W@>tQnc>J7gF?zvs z2lGxCmCd(R)Wke@xD2Ju^kpoLcAP+KnQ7b9=3%Bb^QD>6pA{w3PgIakSBeXawlox} z?YkB&k1Yzf@V>OUd{>yYeI@Yt!79t{!N4Ol#eok-d= zPt4JM5@qSjSC?>uQqe*9E!jJ=g~nMZSHO?W4#{1M8G_lFoQ6(}g3>${3+;xI9>Sjz zXE1hAF2m4)gPBS`9x2vxKR|t0k$5Yl4R7t&fnG_3gZbR{%*U#P9Y!nZ&0Gyn27_n4 zCxgdNW7FYMui%Y#pnZID0neYq;PU%Z@ij{Y@j?{~Of97d-VeQ-D zyl<}Yg{Arx%leidTK&0Dnm!u{8~63ChLiD2coTn5;Dc*0i{S}9LLv7lLacm0@mv+1 zB>RmY6T(v$?P~?v6`KAadC^l4gn;viJVV+ch$$Jt4o(MO^1Mdq(b^6cn4^ThUrQV+}$@aB<^a}2bq1~0~Hd}%aTDU*x5_TZSZMrqCt z9bOaYXEKAbhtf(JNVSNfP-?ZG2&8gHH$sAtQmm4lzWE<5EOH<;6ESqIa@0|Lz8wo} zUoFzV)!pgjU*nw)c7}~L5j3V0|^Y}}qcoCs}H97zL;`HkEy9?HuAK&%+7&t}oHDfMiXroeC(7g*wmoyFo zQ~sVY!&pbpDXGInKv?LknG*>q=4&Z*?)eB!N@81?k5|MoQ~qEf(~Po35aeJf3f1^} zFq%qJ4P0vC1xATNbjjseav7#eQYUWNSrXeqilWZ zz-Tmrsqhtc3fGzJ=yO(B!tz&~;~s~5%FSSoM9OKXN*OrJ_U>|ZntYcb8~QSW`*q4u zngQPG(~xeac$Q6{dVzC6Pbu9$yn20gHoiPQJ?lcdaN8qz-04EF@ck}mxxlKA%IKqQ zs@Z<1Vt18^QIWF)XWLxpyN$YsRoNTOLI?ScwTg{`4@hDhR8oaK$6s#R{d@Evf) z4Yg;md_m2Dd-WQEg?fn?l)5(qloU|Ahs~US!&5=QGnseEHLS&2w2VMeqTu9$OfEDf zB5_Edos0L1m-i@&!*bkWkwX|%!_h=3X+Ci{n>q*#3NBO0e3N=7^Ru~a2)`;Y z(5+z^)e%}i)`8;dJC!q2?>0{FLXHZ@Irnaqt_ z;IYwk0Vk=+Q);japcz}&aFhY&&6lPF^KfqLE%Ht2;;L3j<0w09OIe!pl?!W_E7L7w zuy>^&U`ZFSh}x48MNrV=-)yQJ;cHwiLs=!U+^au=s4k2H>PjoK`98kN6nY46rK_I5 zdMSS$<^vUf@AbARl4)KfF`K3}BC%h{km8_m9}cfAe3q^ayq2y9^V<&i^?a8w{fQxt zb}9U@?V@j_z+AuWJ9mIInC@6roNV7$SAyoar75Z(UOXko{#SLAH>|Y)ZVW)}c6BV= za=f139)CB#RbEFqX#4bwkO^)W4{1ED<)d9&bvDJUJiV^JDb9NKS?HW&d0f* zJh^fGA9?Z{%WMPCZWQ@#6&k4N>}@f?p6NTjrHw<6rGsS#R4&5`NdO zs0FkmDb|%>CK<%XCeheC27F=cMIHh}pvaa)m?E{^Ez6#n{P(G<=FKK8C&6M73?CAa z-CeBXtCK$X*Lt~bjb6NH!3((l@5cXqdL8=nxtg9ta^-04hl}aSCUmtQh1YAx#e3c` z!~=BZ>enl{7gFIe{1iWX=Q>&}BKZik%un#-owE?YPo|T|6HG-&UUfEl8A)7(e@n4| z>!py}DDvQ7q2izK6!A6;g+3~sICrEA=k95!AEkhU)e2dppXC#7w0@NSVyWTPc>H?s zYW(s?BQRX)M>x|Sbl-otfH!Yo{PU0S`pp<#kH!cpRFs;_Ch_U3R-8&4V_l+t;mckAd5Eru}m@gJcyY#kCrN5~J_0~v{Ag$2ok3=tb23G;v$ zB`UJpRhN2C*pYST;koT@Cwmb0y0d2&LtN16`Y)(IBf>f+rCk!)U2^F*qRIawt z2)QebZb($tk@8tRq<_43H&P;e47Ulr9WM+p9D?Wtutw|(kDj%Sx;P-SGOV6e z*z3#@3A{Ivc$ltJUP!e&M6jL{dl#rd<9vmJX!rTdz=;idl zoQ~jpgT6Hr zM?F42{(5?Ie0}wPa@>a!ZPsO<#q5KY8&Og$aaDXtlM2!8KBC8AvEyiVDat8v%%w;^ zw4L}R3OgEH4kk$`s)h@6W!KptMkqMh$f#ws2|V(6kMhy%kv#wS^28*n>YIy(D95~l z9c#gvBe6%&%;PRr82SrE!_F-Xpaz%8j$SQ%Yz#b4*WWJMB1uTwu_Ak+8L`eQRO~y!vd8k zv^_^VKq=akW7bdv<^0^Q-Igh>ZclH&#Pr;MD8&oM^G^H+XBLQK5~yqB>L=-=51scU zU8ir@x5Wu2iW=oOQWwm*uHQ9Q#YvKaR87RsBj(@pk!^`fnRcJotTZvkq;YL`dG-@xNMELVo^V96fx9Cr20xc$XXi(d0DeiY_yOMT} z&3=TXKK?%#{9iU%WtrN3)h@d>IE6l@K)6?19AH4Y5cgC%QD9~(&`CeqD7IA}woBh# zV*Bodm7)}POH&AsOM|@zld{;kRA21HQl(_ARc_VZ&lk6stDCD>oXUL1#ILt++hVoW zkLIplvPh{vD=XlG5p+wk%4kb9d0e}>u?Jv>ur(?QBW-qZ^&f966Xc|TJD0g)c1YcZ z$1Ma6ENNb83SZhBMg`4t8nKuuGiusxIB4$D>C|q%;>n_;koh1e&t%L9k91TsLorR2 z#i)D+0P-DM&U*QdtvqKyPtGnnpUxRAdmG_}fDQyzxH&nv<4HNB>MXx{1TXm+2NRpu zTLvJ0HcN^^k7uBr+j>7tS?4p8j1 zjFl(GwF{j4&t*1aH1?rv{@BcK9j}%IUWb3b2KaQbRE2YSywyo#iTgD?6-!i~T_SU) zgCfs`-osBS*?8|!VQ+(;Z}=+;XDyBvhz%k^lL=od5zL2hN*^X@bxU8BlquRN81Y8> zP(gv$ZjfdiWUXpr>6V3ox*FMnLyN`za_t&dKpaV$%A)UJuoCBl?`*P?BoD0JO%DH> z;R#*b7|AeFU7wuNxQ{qSve&?^~ z+j5KGA;GOZy;{X{mt{|?5IMl|!Lq0!G$du1$<0heZp;7udM1g65IxJ?$D0S8bWeZ% z>+2bg|A_pk;_mKNU>8Pz$H7075fA2bHM#NwjiZQpIO#FIh}i<$f-5a!PaAQ-7xrX> zERFHtYyfvCRUkP0mdZ{&rg0(U8jRXX$nut;z)B`vFx82*=AMg=n@#3r|FA87zDaADYdBy${X(k4fe* z&}-=F891N6^x^Ojn!kU9gTp2qG@CVR8U`M6WrFv$j?^dDT?E>XrwvamUF#-fQ{@&i zbEl!0x=W@s?Jb0d4SlcS%jhfglJ69r--2BRp3oy?vOx_p!MkbYis)qNR(?tcJ6y#Q z6|gXbFf{-#vryoyC|MC}m`Vx-wW=AdW&sCg>=glq2+DYbDe4s>2kqlhVR&b7`OJI< z(wZUHjsI!#7Mf&J1~9}BnZi$x^_rx*(;wuM7c!;Z#wG}sQHV=wuPXK~fvSA3R4OJY z%UQE_DG?n@ZYTmwO11_u2Q6-?io}?J{-DyZVg^$S2m`7Shq;iA6d=Pnl@=%gNrkTc zAH`FuDa>Q;X;VDnjX{x4&8ojAhiT;zoJVQ4#*mp5Qt~gt*8c5-xQkd&Z9acW| zLvS>G3v82Y??_Lq6){b_#MxG}A|}~#izMFyxd;H@`0woHz<)%fo;BF7kzuNl*H2{T0+PmU%3o~bpR1f3(g1uc9P7W+Q zW-rn*N~-JpM^WlesTKK~MgXnc@x7A;>amqOS*y(o=HR5~ubro2{R;cFo9n7a{;N08 zYPE_#^;nebx!0cmWQB?UQpls&vDs;jf^xHB4jZg+}d z?PL)ps|7D1+LP6rqf&$(@`d&Zfzk+(JDI$;dE7?5Y4QujxL*v+LZg&as1{UvCGYGq zrpsZ668ra6`dIWeMp{Gf=pS`!SDSk}D`(9O#wmr_6W~L0uy|x)>t>pYX zxKGNKBN3a;z6JMe8e+%9?<8sDxLAj3m*$JygoS9somntPAw{c^!K9UcJk;$9xtVRA^3V5grHo z`Z3!)bsLm(;}sO&eh^**{&wI(AAX!x&k*WWWGW#N`EDmEIC*zl1j^ARc_M@P#*3NV z+vdScMfNvTBFT(8SRabOprs>=h)ilE z<-{%W-*-sKjw9Kb<7CAi#urN@&v$MgKg#>Rrg2*H*Vk*X4qd^cNcXybW&B(3OUw;+ zQx;(Fj}#R%QrR~y25wu646IG(LkC8vG?xP27ITLIGdPfH40hSgkmWTSAh?;{i44)9 zpmM7$GqF^(2)`>FKsQEpBV`Et16@2GY8zBbpm|raIA8~e!@?7KicGbr zFE)6;s9YJHEdAPZ8uuqE9&yxQVrD=VJ2k{?gfLLCLw}^X`QFrD@ZXzhch|g0ZZnw0{AdZaEQX_a_4fO+V@(` zM&uZ0$2uHA!ZlGR0wb?c@Nbj@@q=s74pL`nDwWZ#!eC-|IARKzQfyqz`0h8&`cyqw zE6gywyhlCA_j|d)f1d_kAe7tY%BOdC*ZNWt-NdBrdM{7r&i7G- zv#^yUJ4yzqHO{uR2{$pNA_dx%xy#R`O&f^nq!R>&VI|L$DK@MG`JN{TYeelpyT{8I zAt1RSB0^**`e;=rh%van2c4ji0#v)TrVX8tjv>{sXsOiP)z3C)2HizH!CP{0;UJs? zNa?6yXy?}Q3M^{vNb>N}&Zc>py?-c9^FFmQ1&RphoZN5Ud^bRolfY{fJ$L=};l!5H zrb0?eZL__!T5qdO6h)WhfhsL{Xsi)7umSI_9wT(0P)p)HHxSXw$)=>!-f=5Gmrf^z$%f7KZQn zE$b(EYW;Y*yP3*0p?)Eq93DG&^~OU~m!w5LphS$yu$+K%J>!w~qH>N;BvD_O9M_xm z2xTvK)3-aogsz-Yky3@DQf3hsVTY!<%(ORK;U<)t(FBntNi&arPIg5Lr$*E~x^Zmt zY|hhV8^d&|Qi4~n=oqL3#iNvP1*u;(94)pUfXuC{>oX<(1n9jg$_fMb&i*%_?dI4!cm23LOz@(coouAS!&1KBHk`1C@iAe z;AwiY@ltw{`~FdKa%8=|yqY{uM+DM$XjMlpXnL`RY`mO?SpO?($i}~?ArS={jU z_ZzSeUr_N0M-67i35CW+b1}3`ik&(5#{CEj>G>Jh4)jinHZiK9F*%ZNzjE6GBk>HaFD)*HoW+oMVgufI{VKhUvkTQhhsm@;C>Te1E zrzg;ylq^0o6~O1cKAjnO+3&yZzU&{of{~p9m*yTmnGjm1 z?=IlY8|eS>3SPhI!|Q&(?Mx#cpwJfl%$Qgodft?qS>pEsIrrQ$5%aZI+L`A^()Z>} z8+vyx0_>Tkfp??#@G1SBxfi$K9_yaG$H-KVxUt~9EOKS`yMHsVH!1P=rqwQ{#K1;q>Z6WFM+YN(QL4Qxd`?5rI`J z7}6&vYYK*9^DP`7c!aP=yAQN`y|S+D%Yrn6MEWA`W;Y-v< zW#j7`GQJvr{dj(LHo80=o^AS%72cJQOt`Sl?zl{JEA!ETRvzvy9JD(ik|@e*V7{a+ ztDFR6w&Jr!OSw2lk!|)m3&ynra&z4b$fS95la|%Az~+&2YW3h$>tvoXoH+v@BPpg< zM{YPResD)wS2iBbFt~M-becpR@DpPP1n65H12;vRJ*S;dT%e__wFbNj2Z5%1C(sm^ z@^0224mM)6iqod!6X=&W>efc3sCo{ddA5vGMfSmu7?qdE*|7-~t&Q!j0&)buWuk8$ zZF>!wVOCL0DR#e!qg^qXMCIhSDG?TiANbOik~0gimE!EAa_T_y)WRC3P^eM51uJ}~ zQ6T?yWal#7l;;vv_r%937sDA7Q?zoc@NS<8MUOP>h;veZVX2_Zfa5`)p?2WKi@L?v zNLS?YoLLLJUJ<)I+Q(POZmWUY=b=&isUjc>A%4p6On(l-ewE3=j@mAae+tN=%Vu2JP}<*K`oQC$G5dvk(Rk!H$vUl&M+#k4rPjm257 zbvx|P@r4I7D(Ot4tJdnHcu6uQgCZd2xTyZ zo?38F+gLMTd70gr=;c;xnK>xalAZ*Qs#vb*!Bu4<4}4|s{h^-wv|hU^b5!ZiMRvEV zXts|w*{T3lpGF>U5P1gta6XD@g4l~N1My#Qx-hyUqrTG2_L5u_UPU9I$?PWjo- zt!qnr*QJk6`g0ap4ZCaNuXw>*U6G%0zw`DB6n#YqrD)RG!4_`jOS)~;1Udy+!QUFy zPWsmFD4eurLa*>Gk#?KZqv_Q0D-(JyMlJ^bO=8#REWz0n_dk}#zwK6SZ`(Ey{;pqf z0|MC2i{%DgGBk0Qm$_?;W-(#|{ZIr3O`U8mGO3YN6SwGp-;t7RS&r8_*}jcmL?7>- zyL;|<^y#nZG!4St-2irB@K+|jj0RG~u^D}w3X6l3aU5Nb|3q%DQ`F2V?PNkuyjq*g zoMr!QA3mctLP_|!kezX6aia7b+_9ICwXV2^fo-kvc z&(;g@XDTJZ_rrDSXg*cPkI_9Wp9ExtX{PEXZnN}5{IUHSIyzgDo zr{B9dA70^5VhVu0aH$|YEdLah#KYsXk>g}$Zh;ZRa#glEZ>fqwH$ zYbt0SZHf1TOGppl9Y9Jwg^`o(V+;MfNn+o;PnLU z(94@t>O~GQGz;}l%_Ua{@S=75slmy8;}(AEc40XB`1akfH|U>V_F5HR-d{2Oy3ko7 ze*;WtOsr~dba&|7(UmUUl}Zbp#c|#FY5)z1_g?R0Md{ICRxLNPkf5B{Y2&sAxy&^9 z9-VvJ(aB=EEKg^1@40N2{Xu$231V& z#(r7gO3QDBn`iV0tUoAc=Asxy7>@JKT3JzR=In;RSNYkA#RGj-?=y>{ zH{yYf6YM$QW{zJO3zWu%M{l%F*89dmb}3G)GkmlQDy~QuwPPzyC~`kVnzegE&gyP9 z-;kWuEm(TI4F3{I=MMb8=4kH+IVzst@)2;aZz1x3TY|p2mdpIb(gSMgR)t=EDu#BNxnd z;D_+pThov@cKIWy*ZK)T-Wg*A{bbN|E!0?$>$iq4CoZR#@Gp*I=uMD6xUL1S$0EFa zD-=^T2j!a>#FfEKxH8+0eB=nPr&D54-NqqI*L&n_JdyC?`1s|~i{q2;K}!lZ@)0hj z1(n7{2VT8`<9~h+FJB$Q%j4sH4QewJ9ifk`mI5 zq$I7dd9GmEYgJf8uxqXf!whA?OQFyNz#~1QMHpZ=&_Gr|-Mh@njVCWqb7h5csteH) zffw4~JaYW#%@{*3uSC79UWeWt^T5K9;oDM`R-Y_Pa?BaBkn%S96W!0GqKl275)%3} z=j8LJvPmqLKg0R?Ik|l6=iA2RlGFbAC#;0JYIkmX3lEJ*HY3bP*)o;9L-`G@0eJ+O zb%KJ4^5=bxS8^ZYxU{w+XJ@fKxWh+L9RFDo>5vl$1`atx>bYJeN-YI0MYs?X(T;!) z+y@8wD$z72b32|xF`P-R684_qj9c#gZKv69Uw1N#SJeDjNSc?|z1wap6-Sno>IwoZ zo%^qer^`v#6rN3gz>?GMLm))mFH1Ws$26;bcEz+XVA_dyoYcWACEf z|Jd%e293_UB`j%*OjBU0VrJqAYJMqqB6kexvW0I>z!0afvpaHK)-fEVj2Q*J02f-{13uGMUkjV!|GsvvNNcwcN2F!3Z8#x{eJw=?zeh3jb{p@O zarNkQp~*F-UOA(rXaXxMMT9t=N3MBjy41osG9Xcj5{EQuFTRa8autqaG`<4b}VW6aD@>k?Hsvon=U4F=b`47btSgKnZsWi$JLcbTjA_ zj+wYM!non+*`yEMZ&zZ*&Wap$t!z_*DUFSaXGCK}^?99yc(}=g7;y2e@?k?!+iE)8 zb|MV)wZS}i_;=5Phuh7A359Mm4W@bf-zW>t!{fh`1P`~91QX44@>rp!T5lgx+UX#} zPMPD2*{6pp41Ebx;||qF2vj|_8mG$=e)R=4-Fo##=i;c05RG28069^>yV`A0;$F_q zyB^2;n5{?5v2N%wbA3^XX5}g*ijCvjb~P~HS!UYTMB<9*w)(f-PMXn4grAgv3$_h# zaBN5xe4L?i4{%(AO1SenI@zx!kQC_j7c=teQ=$cU^CeqbE+QBEs1$yeq&Q^iD`W6WHCf>z zSx?<@9He`VL4TW}QG1G#nW4im*NMeFbM$A<{%n_9=u1<7(7e97YQ&zNztNgp^-ZZi zxV~w11~-jvtJD9`>a}}M2k!lROW=cxZln3{R=+s#yX)JF%hsUL?OuO;GTY7T%j-_; zX<^{VqGxSjwd#2~aI+DCdJ=GSgRid0GI7amHWgjI$VwX1$M@kHR|i=Yj$RawvH4xH zQqS``q&KQ&(1xo%F}1p{z1W#|bvs$Z?JqlX=6>0kPcb{o!fj@w6Yr1;b!5+8N3hd9cqZ%gLc;e0K^nOl`0TUDU>>j;H{3&`h9Xsf2P%*kx+?bIe6C3WB_GKv-0 zMtvuCa_6tu?3I&x=aHY6p979_PNaP=+{j`pXP|q|+GCw$+7eo?Nw24+cpq>*RQw%0jy+>}haT+E$ThpYh5Krg?n;rQ(s?oeqi1-z_e{fHTyOSJ-f>?CA) z%jO79GP{&9IuumylockGiVop-g>#sssP3hV;q_cs+rG8|b_AO9(u2%biqBI6&%51| zyxc?k_Lk%3*oovK zaBead>Yx#45N0wA7EBx3JBSE7W@+GJ@*9lG{}sHr1-C3bq36g{hp4u}2Ne%Zbg~S* zAFjnv=t7|elQKg;2$9UFEL;GCyfOyjIkNx|W5NYDws0xaq@oEgb4h6H4_HFE0yn@! z3_@1Y5EH48#GU`E4gI?H0d6ourt#Hd_Ot4&|ATE2WlZaT-W0$Wd4>xVMmMWa!g!xO z&&K1r&aNXEK*qHJnShbEDEKGJfEtNw&<;`;c`lXFoywrL>)$a2OewaiB!T;+X>|cO`!y}r6?62gQ@~DNP*rno1Kv^Y!pD9xf7alKu<@P z6e4n$fO^rQDF4tMe=e12Z6f%O(t1s2FRfeLM?kH?1YwnfRMF2{>4ot;L7Qq+!Rv^CzIi)NUGa1J1+ z3xTnf9h8|rRrEW_<8RhHFWL3KLrQy{TC+K-2&kXe>c{7EG_KdRUzghHmh*U9m4#H{SYaV}wXNQ{zJfYJP<)>b6M{^@C=MR;lLED2Cm4jyXqM$ny;?698 z;;9JgcY-F6VwSJg**1Q{m-N}rhsE(5zGPvBL+jlygV!Q$6Y_AB!mz3nJI z+rfDN%;@Fc+W~QNSypa8_-}VrHQVb6V@G=>au2%qH|ab7(DMj9XxsFLxzdjz&jH`aDMRt zUc7+8ug~E5ivc_z4BE~#;UNlbonIQ0>eGII!Ob$8_d>bqyKNFS*ZsZ7`twB2`zxjm zy*r2yd*;r-#q>42^S^U=aSQIT@PwWsQ$5Ozb-tf7w~tPi{l<@_ZoI_sR)bkGLw^uL zzYykjr3M*;w)Pqr5z7+35EwxymBP>@o8JG){+?uSYX#s>Ops|jE%=({b7w!OiZEeX zAJD|~0Zjm3r3tQ37`>k~kJ0$jXf&)hPIC4+p$JT-1nEPNL=@Xt$ryP{^pT!8{XuPD z%`B#okZ>YLKrB@+2iW4ADF@_1^1;6QpJsC+6XHyS#syHUHl51ffYu4YhkcPZC#(Ic7|75pdzgA{k~jLA^apssN}xO>Iaa6GK&VO|~he z+Yx9pWJ^7xDkeL(Prktx_A4K^0i+}~bS^f%&&P86S@P(?)TW;6;6Etp>_XeuK<)vI zO3S;i7HGT*f_9#Gm*hTN#XhUt3788iI3h-h$TJmi>{(i<&(I1XeKQ2|0#--^38?Xaq4!G`35@?nFN< z#_lWeeMH)tazmxZLX)v1*+9%mPgVdiS5%uR$I$7R!Zub9Qh4Vr7o9Q~Ma4^e!3wD* zN3f>WxE1RhskDhK1A)(N$7;k-j?skeG8px8%XsX~=@lusoxSH4);s?RNBJ|#aZ|<$ z?IC7QtysyG&sPT&voH2!6Lq=o($KVFP963Lf?dgU;YoYPDtSed#nNHf>=g{kzq{T2 z6xmE`qp1FNsV(S+x^tpzG zv;nS}qA8l*3Z!i7wIZbGu8XV1gH)Cyv49`&&IGQx2iLQYZ?CQ|r<3#XB^6PLSNNG& zC!ew;Apxii%jMd13K+{ITM4_tVJhux>twShut%REUjF&w~o41S0c*waUebQLa3y=B;kOKQ_H@8f=ZWh1$1;}Ilc#0mV20U#Od&x_3bxmb$lS-rSHgI@<+88%Yp3S7TC^| zPP#+54*Ov3RBAFPMMKBoOd);En4kqNCcZ%0Ow%$>;a&|-_tm)c-z|**oOY+jQ=(4 z3m!#!co%bn{geeb><2Q%k2sx371|LlMs87yKo-}#=)n^z&82`}i?Ne{85~J91v~9V z2>HlH2ySF}E<Ju}w(+$Dn&T4UnyCP;gG*ti z3gK`(rVwqnjG#QGijQIgZ`q5jSz>w*oo#+%^gGwO7i_^AqWNW2O!D9YugG^K9U({~oUL?}A=D zf@_wZ*i&SxMYXZPdxdgkc0ziUA1z*2=!`@&Br*cmz(CWI1VLLku!uqjZAsuUXVI>>$_T)$>q<%TcXq)KfA*t#L_`CQM=yLJG8kai@+GjpoTIG84pw;hIV*Q*6AJ z+XqeuwMxziwCfIHgvfS$q~g-CWkM{-W-N4YV69cPA!GFniD+3;sku|#mX*GPOer!* z9_@_pI~x~{!fgO4ITS-XR?RctWQZrp!@u=InyXv?2T_`f)YgnsXn(Y{eCK$CCihIe zQIy)PO%*=5@zU~$i?By?TxPmH7~Wl64!Zr`>3O#a^@XTAu-j;Y$daT9MrGJo@}IzG zvx)hJ<~Fnbvd%iEh@*@{^bkI(R0bl=$r0cV~%PpRm3*WgDZMitX~Y(+b0#s%uT@7sMRb+I~}p-aG@mi}(k4p!Mh zW|+Ox-Q%#q&9k&h(1wK`3ZJynDso`r3<17wM)8$>8cA%t(os%B6h~H zLsTTa!J$lE>+T^66qeI2rc#)Rx!K2-E{)3^1pX>ZHzG?m%F~6 zU)W#s%{Sl7>~j2jI!hbD-d+RtVDxv!zl}$N$FUy&HRA?HDGPBt!Z{CRB88oDF?A=p zWMPele-7aRmF7~wuf^JF$P7-UT7unnD`a`krU-6jd@dt&D5%^n%gjtF+Jrw8PGK}d z^(bWo$5UMlPqii26=+Us7S~LLa2;L>vs4Jj^Epwp!@5N%)1~6mnSuRY@1V2ad;2br z7=~sES0;ki+569McnH1U-oe3P4-R@g-JDnK7w83W6y&vux50D&LetU2R3D*W>3`X9g;NOTnl@FDUc91$tQ>l#Z76vQ3 z(+8%2DaDq>O5lFeY(lz0voOQxW{odV)LyU z`p6T6CKYd}-SB3H5Zl27sRTiXOo%nu3Wa)mI~z@HsP>13?gNXGO3j@z7tMh8CxQ%@)ht#nDj{=c!rdv)j_i zoezV-0AiMC^ec?lg}L_eR3Rzy`v+?w#au)~g61;Y*6TSYZP(iEoao1$`)sf;N#gMMEN;);9S@Fh~FMJJm!mZ@&%hDcwwV!C@m{QME&E&)OYVW<6k5G+jK1We6FXTmfWy$NIfm_)>8W9 zaG~ADHySnE6U-c!c3e{BkxTDfm@fkI z=~2nD(JYX&(TZvVpREXw?U{Q+-j3gqi}ihDXM=ott0=%U1Q-hmxr#Kvd@=`|&jJdew;5M<+uLj^ zPSB;)EG7?3WeN!@MevY2r`GW^DFJ(;*7bZLq+<4<3wzEHnbSZsu&QjiN(rUrHiE7gd680Bc&xTqS70y^+wrjnkPx^I@&+Vq z$CfvN>rQgN63MK+ z?=v|%I?ADTCwE8;iVEOtA7SYOgel9&HgXjva1S;w`R`VroYpCwPaZ->z5#VCr>O@k=2HdO}Fq>a1H$E}s%(LiE zni($YzdEhQWE{rCJH6ZT9gsrtPW-?!D226-}?L$&vjk_r`|mn&EU(i`I(itUx$V9mE@ zw@^Y2lgyxF5vNNk7ECkKuW@dcB{m(%VWtp%-`#B_pXzCfg#p-V3o6JQV0=2IYApx) zje2LHa&7Iqq$e2DYyx-pS-&iiDfZ{XcWFeGye;=ng>L z?5XyVwytE7K)tRxjZ>qs>+RI^HVU^B&un~)!k^LoI{s<~eVVev;XxIc&XJ+ycvp?v zxHSo+yv1~MXB1v&=9mRNRwohPsn|7$WaKAQ5`%$*DOskWY46u-`2K&;se{%hK>(&x zqQP>oO|Z4i$*P~NJM3I5%Qjp(hOL*5T06e|mehO0<*iM`JPR`!Kyg(SVSj=v4Yten zQ}s%7<2vc)Yt3-;wZVrH8mgK4b|Uo^C~5B z8ndhe4Sj0n9_!Z%_h2CFGBZ_q69=W*ZQ_9J+&ZK8Hv2t`a{EZlm9eh+CZ)3+hSt?P zPlEc<^Pv890$-`3ZQ<`6`p#j;LkEv=^yXr{)t%{AQDAr&ILg!6@98xC0pf8N{w39b z+_>cDp*@+t|M}{4a(;ca)9Si*a5~r=b_GrHG-2^&0~VW3?%X!o%LBJRcTti1UxoB0 zWxveW+}_M_CH_RQp7 zx9hnuZ*D*X_v39EK|Cmn!muT@Eo2-^J%(7dF)>3*fU|q=lm8Y0Z)p?%((QhyF1jzD z5K68O9Ebcv=cjx1irFK5YA8wnMVd^@g0&X^0&|pQkX1r?6?r!_4hWA`8nm~}R;%oI= zOA4UPCZ9g;K2TJz+h}&}YacCL58c<~him+o0XJm-1!(KPjaE%_+At8k=T~f*c6te) z(?bu03vgArKj`QogvK@y2CcZG1y}Nqv?bC|k`BNlegT@N2 z&RYFWuXR2;8Ja|*MF)ySc-ET#OT=?)bOJ+;HZUS~6g*n25%Mn(XfD(WtYeBZ!#l(7 zcH9Z&eQ3AgS_LxU2v$e*6JsDk5r9=93@xZ3Spfk}?gvwF*&O&qD z>b@H`)j_$c4_3}-Id>)rTw>66u9XxDci-3LUuqLES8OIMlTxQY66r)NaqgHyzqf6W zJdas`A@=sN5e}g=WA`;ZH#KcYH9iSnNABl-!V(I;dQap zPGUm%mBIk6WhN_L5f4IFm-e_84)YFG$QEpQt@sgRZRN}Z9pmBXyNmJt0T1RDniV$W z!pn6q@lwd#u>LF&3BNoX_v*8%^4MCjQiqO4ky1JBCzFCtF=UiU&&mE4^ZP*wvp5NEeP{#box3#)p-&!=twlFa=A5{-6iJni&gH ztJNti6B<-VGYsrnr+~(2Q$JA(Fuvdn)yl2?T!Ue3s9(kjw0>EwvvLA@YBLcD*Mg1L zgC^ymm($pfWlO7N;&8T?Q)UdiZ+07YJ;;jcgGG2y;)y8biZ)?FJ@6iHLM0!E4D%STFM?Xo)7$pJ&7oZfW|&BnX=3l9bop|ChWL#dvuQFi%FZ%Aq;l~oUPW> zbS4K?h0)Q&Ce$AhxK^JXq%`zkW&coD9Jsa7sTZMS8fruDd>0@^Qo|tQ8R><=-&z$) z%hS1_2|#_Mo1j?>{g(cu*cP}f_MS6_Wv@OP^y|z?(rSapa(li0X|Lb!o%RM_jvKZi zrOw3@{nD9UXe}@D7UV@EKa5v6`ZV}xhuxRep8U5;W}p>mT3&fTNWh;A5DFsio_4+p z%kf2HLdt#X?TonX%XChvu>8hvqW+r;|K%RGm4G3W_8ngp5A^?Pbn+jql1)p*Fc60C z{S{;JpeS4LsIgGigWmSAcyL){Y-VYooh_0{_WnDlR!a8J$Mo!_`X8F*pn@x&VkE>i{JMDW3d$bl@ zM=(aaHYzyTEmFaDJK0pfY-8?gtA{-rWi{v1SvgQXW3S{bq-DN*QU1uD@phiu)Zk9* zi}N=$*AV9MviMBNhMYGHf`&SZaFtY1h4`-cn*9#EnK`2TLH5M&nQh&XAy76n4xYUw z2{TG)4hM4KF;0Vg^Kag~KYCzM9esql_y(nsJ!``-5I}eTimT}y)3sF`OiF2&k|A^n zp$Oe27RYzTI{WumwH?z0N{4E>4;@cWl0k8OL#$T4FsRo+>wFs|dOpMMbq9NUj(M3u zS|+Mxv>ndn-C_G&?W@CBz4$;8Vl90@U{R>;K;ULlTeqNzv>IoR$C*&v5S<`>I%!(l z`6xVfmz|5=hYcPd;awJdLW5P%nt&KVPGfpXN~`<_WDz!-B$V9`wu3c1JS`I!u}SXx z%wH7Vc$g%r+be>P;Ms*93IF9}s3|w4DN^{;Z_2M;&JcD0<>`oL~`ro_R#AvOymF5sK+4*?peUnUCSruqlFj)gk ztZ~$P5spNz5oV%5-y0_ouFSJAN;uVqH;d`RWIkEMsH-q_1^A7vw1ON#hFDL9M+H0L z4e$oxm7HhL$czrO-Jz2qVF2*#Xe$^Y%z@HbM#-VBz#?pv_%=(d25=t-N``#P3j&dP*j@fc4wXH0HE>#A}$v0p3HjCJ8IME zl3_9KGkTs?^#WNMVi>{Qu*=;;HlX$V3ph_^`zz2v03QV;LrkJZEQv$)TeSEG)OkQ% zUCr7&e^c~Yoy*qx6SEtW{TY|fFCw+@9v-bt-s9=MZNJ`d71zpz8zvwB^57DzvO#-e z`QoQ}CG;Or&sdP9Uw-Uy@(Jx%ZExE)5dQ98aR`E1Zfwa3x^_#GEN#=5VMS{+#s)0S z3|czLoF!5tsW|S-f8UX!ZAJFFuKPNDNF?(3@b0j%?un3hYtrw!@~z~X-!~cmhjpn5IlMM1|B_v;r9>V;iDlu91eSK zY0hI5+WI~-rqst#lyNhwrq-RvZIiR9j#`05(_BuYf@wqV4kE_T+!}a#c>%BMZx1i# z;2sN4=p`~0QZ}sfkteQ=PAj9%H>B%bB{Y~Bx;0?UU}XnEs$@}5T$(E3vImq@Yn<{N z!~c`}4ar@V2EaSak!d_$(>3vP=l@X!an7{<8Vvw1${Y(6Mz<4Huk3v6bUM}rrz`uA zV9->`YsSbqk|35P+HYp)57(e;YzS3X~GXh+Vzn6a{^HTVZg`kP?dsol3sy1 zh9pqK`VDAhxS=^N5}S}FGhr9H;W}mXWzoBj@31g-s^@j3k!m%c@|;sQraemAu=WN6 zp5Pvk_?Q4$IwjGhwO?%(-bEy|g{*R0Qg7i%dn0zI>I{%C0u_L<)>5K<9rvo}RFxMem zO6wXhTdIouL&)lp%@%b84bJhF8+SIJ0^VXA*d+8ivArBq)22`IV($Bm;1i+?BdMV zPs$Z(%PgeRm$m|1H!~09JJT)%EeoWRmuSiP9Ni&&yvy!v*LC$UJPMC?Th}%g_aya4 z$5|MLyNszk^_-WsPN+TXup#0#iKC=@#e^D6JPY=s-@}9Vfh(xsYB>1e`k?o|cN~NV zz5QsfzoyLa)#Wp{ybr zKOy|%FBU=5F{=4-eIq-7!`7v4b;GcCIzQyDy`8@R?Nw24+cpq>*RQyT0G2bya*Hk* z+Bl2rIgJ6wF=hh;RulqFon<02sghJ2FUWu2k&+r)LAqhvnB(f6mu= z5FH-}a16hrOyao|tCfkbM203FX37YeE?8>(dY8Ttj z@UgTzjc~r%aN(!T6I|sxEz-4xx4qu!$=lwWcQAJ*FtaY3?C7cI|_OkMmz( zQhrzP@(%oP@PwWt(_K=-1s_$+HPPv06ud6iL`WRTgcLiJYq&;!XTYwRr3b=_tRYco zKq?Ca16xWB81PbWuq^HVFY7;%wZ0VqzhZ{W;QMcU#ns;Bzto>+%$V<9R=*5llV`X= zX-!k7@?7v31c3{{*OME^6tpe0G{7VD;zx`Mm)7VD{7xC?EG>sR7Pwfw7&`(k1 z3U}}Li)3b6aWn?2*o{lN1KTx)tR%YBgwMmLM+PLKDkOnn@*5IFs@jtVW@lh8N?=SkioE=^i+goV4`(I05LJ7h02)WweA)L;lU-AiM*} zsdz9U1UM=)e@(i3C6ezdmzVU0e?dy;Ikl$5RRqxAGe5aV(JuUYSZnQVsp@URawTLk z(|9jbVZypl#?#4oI*P9sH?Q<2=`CRVpIBo6L>?LvdFRySY06b zt=)_hnSxy32j))(ma`-DH7+|Eb7F!vJk0i)K`)%wsH?DthyXs+w#s5in| zlA>zLu9`_~=6|lPh*}>G@mAu2UWW{@B)Jj~Y?J@bFt@5Qa;8pC_Va zbbHmJogJEe2Ty<*HSov((uGt99-hOGA{eJq(cj2vq+R=~Zlsf_+w4}a6xa_`V26FH zzC5mNRZG6F2Y&+XS^sm|Mi&2_zv8vyj=;r+bb861lk|d#64SGR0&!+)`!tKRfNGG` z-4(W*`hUN-yFwB|Ah5~I{Sb}E#;dn)-}m>~$D4l#lb}>PJS@Q>^#2UqzpTFJjz-*S zlbP#{o4z-vo^XASTbE?&I+ujGWH_bxnkvd;+$lGA&$=+Dj3X)hBU*cB6G6v5djR=b ztpvorC1VO|#cKMF=0cfzOF}X68NP&%jEyFbZ#GGuu@kvpZ}*cwp{$BH*Wb{pHb5^%p;D&7mtE;9NLRZk)E^)hnp~^JjSZ zstzyf^@`d$b#3Z#Df~o;fS=TAV^>VV;j!({YU-FN8S+|2v)XX#4{I~R1%6g6Ya44F{n20=MlPlcg^u74<3<<#PxF{}#;%!UuQk z`RFX}V|Wn(cNA>m!N|p!BJjTR>Ga&Rnw|4b`#9RWVDS!P4G3f8AzG=azX5aS7;Z!3CsnQv3hsZ1Uhe^D-~a5teI z_#Ty6$IKUho$qz#+^OU18y@c6< z3#P@Y{0CfM*mMP^lH?Nj+?CNFrIeX(hm2u-XlapyTwJi-@=*ssfbmBi$>Bh2zM?9l zB4i%Seb>qO))&+kxOo(Mwh}JT242KlxxhZvM9Yd|`6c#dBn)7{B=kqWjH%GUT1NlI zv>1CbEs%C9m^&*+o3CQ-H&=%3qbEIK+*H9hkkvTZj{JL+Q#PkE%Xo2&%Ez$!X7AGM z8S8^olYKM?g*4qxznG|J{`Se-g064&`>js9kj`vh7Sc33o&U7VLb4C7bF*JW_3^xO z+Bh#HlNHorlm}S)s5PO)p{!`n*^8QDvOYLnRx4E~C*|cwc!3LEIGsiS>GhK6aW18fQt9MS<3`Cm zusWx|noa!EHG7Rgr|qAQ-1)v-V5wb~!EszvIVh&m8&DMchG!)7A?i|e9Ihs6^NAv_HFM+v+xY*k8}geyg9S^&k z2oaeL8yf}zc3RJeJMy6H5-J>W>med{b*qz_Ax#ht5vxhVMxY`;YmqJ58RKh0<}?Lq z2q1!UWVj(3N9<hWZ*0pj0%avPIXB633pb7Z?2mZZ|79sJ;&vTJ3?^`yg-9_|Kr%XbmbEvuBFD@{Ow$X|kgSYB>W?Mfh!g16#~*E|m4q-uoEf=qTELh@)d7qMT-VWvJ2~H6lY(E)9}Y@r*dEtDU>|UnN&u)Vi8|Ccbs9&k#bW zA{QlnF8IiSeA!YrUkmWIE^}JUGr~V52d@Wq*$Iby9sA*`AT*gJd zgYy)R9q_|SaY-5fd4}IGh0=m=np4GASWojThibsv_V?k?=b(Tn!FB-x7kU1AE*{8F zlCA9-m)Nfl2y)fm8!p(&4x8~nY>OuXgQQ(;LEvE0%kJ2piBrsxyE4l4c#vw=ZcR3&WCHX_4s^>*dvdudlCf zt`Evr0B8GjzA6DZf1qn<6o*heU_ClW?# zx~msAKzLHM^T!uEf5Vhk{8`^LEgq?&>t&}D^2wPAf31uB;@S5gczd*~sJCtCx*8TY z^w^S5YwWRHUu*WeZHHfDpv|2=Hq!P(-{paC)cB*!S~uIxpBuy-OQM8`L`@4y{{xLw zO>f&U487-9a6T_ix>FBMiZp4v0>M@+?FJ0HFfttrlPQmqns&c_Qofd@$=Zud(R}24 z1gYZUsWI?K;F2-jR6!JVr^d&v<4MHx0?hcT_98qvKwL&t@7)@Dy4NhYaH<- zS%ikz&stQGa@Knd{JABLfm_F=#G03`92wIfpMu|gyvrxr#d>x*tF8Ey7@E=-OJ+r$nzg$R zZLw$UtSnMqRlH)0q^^0Hv#Kt${H9__K4IyUr?(ZWr%4U}<18&E_`m$RDCh9HpqH}Z z2*445@6x2^H%0lt@H4$xBuFKK zNA_dMZ`k>im-j_6VJ~kg`SZK#pUdp`QO@gQr^e4onX;eL*LnR=a`tjQPc!=I)<}!R zLz&%7YxdQ_!Pk3V9env$c8*2ZS^dD?)DyPz>if6sn{U{`-~YZ#RcBes z^9nmZt?NbgVt@Z8tEbEHC@tpu)XXdySNqP$_Q$hgygyGWn67;Sk@8Xfv1Z?&|AV~| ze@pQBEu#m)1M~$?$`Py@c79*ZoC_Ul?r&{n*K8-9B~^9BKW0^3?F^h^SLZdXY*J3D ztJis2lqFB=GqHlFA5*@lVciBpR+me@%Z`qY*mW|i;O8G(*q?1)mN3glY;b~&xNFx3 zILnKgT^GxIGB_ld^|UPRSxEb1?Rf&v;Vt7ka*~Rk3H+fM4 z?f}&SK0dGnR*gu5Ww}P%k%XhbeRr3XY+MvDJ-K|hPya5KW0+dDEufyL#v}ASU7i3&BQMv8<~MsJpnf zSwj`>+76J`u6|u{&VXDqMDX+FLgGkLLZ=#KWOM!^?l3F6lpIN9tY<})A-Aj)_Ea^H z0q`UaXhjUPV$sy9u&!Lzn_3$r3NhE_-rGN?j5%%*r|W0D}CD9a_R=KMt%+8s6?hu`}-W2k3B8B z?d5$ZVN`@If%arc0diTLBWEvBEgf`hh|zhR`PlY`U4R3`^yHk66zDdx&$E+ zDa(_YK_}Jzj*B?a^?=Ptr3Yar7YQkROBI?C# z6lpyJ0sRU(FuVUQ`o1?a zb?LDf?57)mk2vu8wB=)y5kO)M?WMAKrr>gtj0|MS2B-s9%RKw%lJAH==DfTCQn7Gk z7-P4)4nMW{f`^%6qZTV=HE{`Txl{|DX4jcfn#ce_9Ss>N48mn+0wR>BzGG=gvcgt* zp_wTn#f{tL=wOI6eSk2D2PmE(R1AF8s6pdt0Q5Wn zP_ledOC0_(GSwAIK+pH>t~;uN7`0k@kJ5=^;2K#QHj|`avdF&o=&o3s>#~@Kga|eN z5=6-m<%#NJQ;jnEhhgy-3Uw>Pl3gjH(c3FTT4F&+1=Q6H?Y{;K*dZDX?yIHK_g5Jgq5F%TcEBvqqzO~2ofo2P9w8@~|f z@~B5p3+N-7aA;zl0+C~pTwDgq-Egw3yaSk*YU)}PD%BG@L zaq;`8HGM+hym$eP|CHT;O@suZPdsR~@SX}q<_9uhaMMG^}>lR;3U+g);gY%ivZw4$F#TTU6_Y0(06 zMVuCMNrKYYwyHNs&8=sfoB(Ha$qc0%I+w;9m07VXM&^rkMQy|=FzntixtzCxVp zuE-{?Y37()aobGUaUDxGG!xdM`fK6ZGKI-R!ykDv=e8&oWJ7F0`^3=XClD_E04@H? zg<~e2Cix9$Dp(9u%&K51xjmK($7Yf&$LEdll+%4+vI_zKf%X+NM<{qq!vrPKpI?ba zWySY;=D^4zqvJBJB@;^#fd;P^#Oo{bFI8Ybh=|IR^YyRA5s4aaJ3h0^(Oq)_VOhijZi;XBS<{-_g>;^3=m1>Jmy5=7%0F>Sb zB`g*t$KbN)vxqjW0kY{F>8Xyg$5%)Yq-wmU`nl`q@nv74dtS4wBnl_WEkjkKd0B9yJZ z>yR*g69FwJsA+o-{pz$E84GEUHux5IRaUoj>)K_9K?{3Zh8U&t>esl6GP^m~4A?BF zH7V1iB91G2V#nt7SR2!C#SSjnF*|6DRW-7=ci0k}7 zy^tVPP~LB6mwmm2fx5z_N0l3^9)MubAf(H$1d8TOpl8TF$YF-+!R1I4^9y%;996}B zKsEX$S1ClonVJiaxvTj?L=`9Eqf9PS3p=!sb9f}w{(FY0_zly#!bCK)`bk~x>&(ilik7w)oR=>gM>lb}(Q z)e?ik5k7%JP2(s{a%t!YA2h&NWIQEAZQD5ZvyHuTWzy4+T3RW|Gs*U548HW4Sf&5Z+k)kA2D$b~cJGi>d z77GfMp|>9h-{w-al#ql#U^w89c@)zM8FxfJD^kZIxFkK*#0o+>&a3L2z{C+tF4S`n zY;kPZF{8z-D8SDbh6twTuDi#>o82BfvbNVH~Dg`hdp!_(i zQie#jD6u5~`DbIB=5HPG(NlEv5F2rk5hSn>C!hru!%|`bMS&eA2hM;6E-^;c$Mb}b z_D+|=ghhERW>&Ie;N9f097mOjWu+XQ_hkXUntlY&(=Ay7xFA)%HfBr2iek3nq=P>O zQT4kUr8T6T4oLn{nEIp9Xb|Vv7F)mx#&K%jLje67ysnKK0nXQtgOQjFPO}+UGEO~I z-m8tA-_Np~$F07o*&bXtkXwRe`dQ=e!)9TZq>Lf}T0o`0B0wu^+3U5{+ z6OousLBKi21+FQti%FK)1+*$GpO7%;#~cGXC_U!MEf`|Ul3O;thCBpG-vu30u?52= z_#!qb;1!671;2V!69)toGZT&NNp!yg@1lIQO zMj>u!d}*!V^p`hrg(=)xU!{z(ja{$(rrX$pVV-6HX{|kOIzQ>70O14l__HEtu@$92 zmoTM~e5t5<0}q=My>Jx;p$v!^Nq8cSbL&ZC{EjEXBjN3Z>nYcJ(?|fn+RCce*f&}J zTkV1-9An2K#dFjQ<5;1aSyI)nCKEofLOeLX?Ks*Sm9dH7Qo!QcyV1r3Xu|Os3eCK< zA>*6p&tqBKtHftEkIk$ep0gkAd&Kw!)u&CU62wpm%BD|UCL+b1kJ8zmC}1Q{LG+?` z2jprzrt$dZM;BrElXC2*(}RoRo}3Tu!4HMmkKaWi6U{uZ{%5M6frm(&9s$M1v-kt<}k%ru4{hIXt>W@Q8i2p3&OO zf#9vVq+Ri-Alr}g>Mn0-yI$WYUx#jX;ZZ4s>VSU}*9WD57{Agi(18&HsZ1f8q28-7 zF<1xeSyE$iN>xAWQcx@iC8xb_lej)n)#ak7b{hCR45gg(N^05Ip6Nv$4OY2!mdt0c zy<)w8}?p|0jhngTUBwBx|D zb=LE27S3!-gwQcAZdEtB*VN~KIXiuOb@IRO-u&Oy_wQbv{Lkq{l!(LgF2J3<`Q`ky z2`{eQXrHPJR-^)ez?{(L;K3?cCtaY}u}8#)LnHmIl!T2-N@bKAP*`z~yPym0O21Yo z#B@0kBw#7%#7=-YPw;%DnoSB`$^AjILhO)A@(0b4x_}nT(l9I$V<5;jN0NKckR2^O z+h*)%;|#E#SbFyA-RawlpH9zTpFaYQTF}H+qdvGf+V7ycJd-DfQw z`mu8uSIJ)#)YGylecAfu(dS z?-%`T9UokKiZ;vY?&pF=RQ9-`Ng)J;A@P;WdKx9TmrV9vQVID@!AdbL#z1*HLfa|9 z)}lk##>dA7$714ey>#MO~Ss&sckIi4%a@W85En)(>qRQ zALYJvvd~G+FwVE!Nf?7FV}cd!Lw2_`iqoJTWE$Tb?e7>Ye#grPn0hEK{r0fnMQ+Tk zc=WO1j+RpL&k+Rd5z{4hyt*?f?nu(gOee$iJCMSDy@=)UXLJoU62Bv(>dXdcq$kmu zJ&&X%wchw+zZ)fa$C9*{`E3r0S~#(CJ%502iG<1A!#l94h2LR-)2TkV!%QEVX8eK3 zf9|=;K8`^FzVq+PKGrlmlBv6az4_fZ+~wc;cO|?B6|V8DNN<0kHv4#zKBqUxpXA;m zBs==Jjzg$dBK)5X72}BbnA<{3d%J7z1Tio^t-J-qPJ+k&ZjuDw#+`t0*hCD3Gvzy? z@lVK=aendc_1hnV@}N`E@yz5V@i4FY63FtW@+-!G$R7IBnxFKM$JRKue+w(0 zo+EYiqV&c<-Bc_LCQdJt#|>SJ6Qf(}p+Ynz9wI5XzvHnZF)4`;?E&;GKqPa$2f@YI zUk_WiSG>ZV025sTeok{>($b>l*LwaI*@1PuE}O>)W4eUFD9cS2MR!t|oQ$qD<(i2{ zngb5h;Z%6SS9YDHI=)n?L&IX=l&_J_P*dj$qtCPlOLE7!dUDWz-UfOa>PyYVdN|B~ zH4a^1EJePj?o8>EcGVx1d!@%~WK^pg#zg|UvJLw=G=b6DiB&ytrf(uu2r;%NcpJ-+ z56%keimvTd4I>JR-|lNGlU6Rde%IbN;5~>)9geFH1mvjD%QM$#g-rSha(MRyPcF}n zvs2P9JtxO`j>8pIn@8X}Cs%pTaHAgLHCl4(kUE*VbrSuF?{*?_@R!i4o7(6Fowr^u z@mN+Xq~g2l$OU5`PlaIk$AvhOOJ{HRx*{h+0=dw8q2@3H$&D@_Ip(Wtv8bk5aeHeE zw0Z^gXGzL;o_;7lIO0$kYexO$B_7!b6Cr#siAf;Gc!vU3pmt`CZ^ic4 zxwa>M&sK}zV>fvH;i6abL|x~q4;O+&PQ9v)!!mV1zOoJz?sbB&f%Zrzk{23a&qv*# zMgjs9wUOJSo~M#$!4n|Y?vrPdTBnJ7juZFdO!r}s&1xE1HaPszBe(r%WlL{7Y_u{| zWn?TRe#j$L!TdDe`Jzo)Ug_)JHbDoQM$ggo-M-Se@lQ|wRa)|-=IA^$x{1FGsjqIK z(6tWEC0DMz)-2wCfaQ$mH$a4pNzpgsx%Wl~R7$B^tm$9crlb1A7y6*Tn4NzIYJ;C> z%)hyBn{=;aW^VEFc%rwn>J4-Ry-Bjm)WQ+|D@TGVva4Yhv&j#po8pLg^{3}9sA`D< zOiu&I@NCHbBK!;F;tn|SUe^PiJ8oqZ@x~jK#qCc5rW^*50xg|LjRfGQcrVXW!%PzC zIix~9V0sr^;c*zYW?Y>B-NsZi7iy!h#}2WP#H`MqJ=?xo76zGG&tbwnWi$QxE1$t7 zjLF8ZWT4?muh6FHitjiM=g4Z~`i&wCI;Oo>g|((%P^WMmUBnrYVevP z*Dmuv+tB@v3=iH}`^+&_)M8v6N6ni&EqOf}HYk~aK!~9{5B0t%K@k-PqT)46bKj0% zae8UL)@2WHN1$nq?gDc=LYpLQwl>6uK+E$xQcR|y1*0jygRwKTk=kh1VCmr_q&6R; zSX4dC5Ii}0HB35$MgYR|Wt%`E2j>~wj)o*;qi;b|lUG@Ix-29IhLC^fWnuiZAfs-I zuJcpTZ!GVb1+!)1ILCI&XKj%mTPGU_F}Rw3_r86)zAJ?$}6awE8nc@ z2uA&v&y%d&RSKSSX_+u#Jht8mA$v=yUfq@x_r41|E#!fvC1Ao_7raxc;^wAOd#P#K zdt8;-=m;94A=A)n_L)Lzmc;vzIT+L3X^1Tgkp|_{J}G<9c3I{ex<5HH={k-rD87G> zo0IgN3D$RE5ejTQ5}i4er^l(2`RR}L>HO7wR@?V}%9Ht8Nw{eOOkl7xc;V+6p8m(A zEX|BcRPv@N^^3){n)PuVPdO&B1tw`DoAsXUCCyd* z_Zxfd&AviVPt{3R3!=^1^FH&;I0wJSi@4?O?6hD9jw3jpN+pP|Mm~?}m`VjC4EajJ zj0;fsU4mK=1@x<;Q2;Z+m-vE7@IxYTk83_5len9b@Gmryuwr;90s=7+iup-M1V}An zfaf*I_4zg2Q6U+R;8*+Z$R~=2e+2O@m<;9o>)Ehro;mp(I(WeQY!E!cda;N|Y_ z>lZI~e|ZHXeFU!68s4h_y2o!X;msS^{p}UJezOa&cXxY+G-N*dLMy*eDwcbmH%GT5 z(}B;Io)Ht0sq{*gdDDXiQlmf_y7%8ccl#k{LONxOCGU2!ZJPOy2v5`*Yo@RC6qj@G+sZJ;Q zb7N1cxhyBpWTZ$G5D~~p!3SnrGyA4L^oo-yh5=?tMI&-P4X+L#Z%)Q^2=*K6B0Zo4E)3d7v_7l(7IPAP5*qUGuX-L{_yVZ?3J z)rhL>Y`bcaY}YR|s$T4|ZFJ4`lcPb`29ZGmE%*J_3O0H38Y0RJPJVc+9g z)+&V#W6``pD0`j!GmE^^T?^l6D3(-EO^*cQ_eA!q6V!}gRU&I zA&y!}uU0d2)&-mWlJj-OdsvSkr$X6ZOS zyqa>+DPo-q?V=wqFeo~X`4kF6?8}nl2Ng!O?KDVxAEuQp*wupSrkvIk(@j3Xrf#!g zJC>O>eVDGn$7w;c-&&)5^Rfn;B(UA0k_VD%yeuQe09(^%60%^FE9%_zz7L zna!SV)OKN2ca2WnJntS1heMMt`Ll*86#_fk5ISQQF=wL|hmngSu3$=2OFR1oYU4js zs*Nt}rV@G^!uwX8w(3cW{x}ueEV?VEPzJ3NriU1bb63IHeHXeM!^54-mjc5 zBD!<@EM##p!K;)-*dDr|*lu|5dHSMK9MWrhxSdZ8*y{@oLYctF17D zV_QGHg3GHhTzx+K`0?WO494ddBlvJOKEFC0z$ck@txQb}DW4VZR+%P_qq$)rQ9vaV zInY9b>wCDMDiH|vk-E7pV`|PtTx8f;ggO?Ha07Tw9ea3_(N;_`LdAgOXe-gUPMd<6 z@XAftxt&StXx(nm4-FH;BbOi(_?dpdRw!JLHSKUkY(FfwX>=Y`R$D5ZldqLX2ZxwT zW?ba@z242q*seKdt3ji3SnoIs%292)9c~j}OS{EQ(pg_l1UFMvE|O_AXEUogYivsq zESnwOCPtVNe*vz4++-qeZ#tN_fpNF&+yXi&1q>J-;$0TiE@Q36Xol&9XkG=M8$)v2 z+@Dgj3|*6NYhBZ~YL(EtYPl9#JagaFQX9b5Y7Wnz7g;wppQ<_eS*+fkD*W5Zc3Jaa zVY{Kzp=~;OmM7$D(HBA1jGEQ!)Bm9KAJ!=QRi;*>!f2~K{6v+^^)}chN?WdnfxHTC z?%wHs3d??mc=R{1EM*^qv<)g{^}BhMxi_84Yi_td6a5GDxN;iQM!x`L-x2=o0#*Zc zRY4m2>=`q>wf+I^S#5LEI1v7xU$HmSAqk{OU^uvIDJ6send#d#0cH*uk76r{2geGM z(o#zP`|ZlI<5$`OcQbc~KeVnTt@h>FXIJW@{pEaF>)gIwgWJ#pH(*ME7BKZg55~^x z-s!OS^k9IWKJZYraTZNHd3ge7Tq<9L@T>jy#ATY#guDP6HeZ&^{lI1%%onFGJU$Bj z>6A+|%2s+VBo4w0$!9Q{b9pX=2ajgTzCKYOSN`XA$o1pgibEz{ICO`hzK|RqEf%hC zUh^wlvAmG}Y_8#6xBFoGUia>O7||3s(HC%_J!tfv9>K$h(EaT`Jb2iJ2in@2Emyn=dwY8@Wr4!i%Ni-N#ic~|?m@k8U~m(u5DE=bu?oHVt`Vl^Qk+A`&kJG( zpIpAw2%Sc>VRN^(uH6`dNe!GfZQ7N8xdpup%x zUr3;yGYyh2C09JuR`h}|CW!Mk45z>{-vGDAV4}qsY3`v@=eQ;PAYn@>T&~oinfjVZ zT!j01w8&*az&%icCIkPZdFY|$DO>Df@HOol>1H)00mjSZpb1BvDvY%HSW&2f&n5xK zdrq5U&)za?>F-UB%00cVQuB>r;j*pu(faAwoXV&dvNjN==nVuY!iX42NA zAw85~2v37F0-l%}6uK)ZDLtmE(4`!X(&ikIh~f0Zwp|>{cyfl=#|YcMJLdON`ez6^ z*m6+(^H|UxY~S52DslR106ryOvLoeCq(yK6sDJsU6Cp4PUaS~?cKiwloj+b3j|b13(fD+D z^rB+w%fad3*>V3Wt(S~~x3iOWuytrFHp$jtyK3F(P@-icQV94-1TYLssvMY-18T`# zf9fN4%3xN&BWlPNrBh)G`N>u0mC#>``g3G?!afy~Na8i0Nau5AYgjv{5b{KE&6d*0 zlqVXi2Pw1^$~W+hmEc!NHP9(Yr4%#lmq~IHCBrFbtC3sqo#c8YLpT$@SCPKhw_rg| z^33wWn54bILga^L-wl|rh(jxtmDUxhPl+AoQ!|yr)Fp0FkhUME`Q#Vu`ZmJT3yi$t z0)X^_-LmNwbXqnu&G?q`<0ynRU@5l#?AyJkIQzdu<{DE*SS3+ zo!%yUy?Lksrjy?AP-d%Jw<>mvo9|@yHI*dZNLg=YM$IMi!?MI>hshw9+UIKH ztY%J5r$cQnrBu4s#?43zglT$_au^X0_DNIb@>X7i={ptIQG1KDCUP>dbM_R|F!?wY1Mumc6a}%88Y+PA6v+*!asANMeYt6rRe;L(cJZ zcsasGtPxeNu`?PR4*SOk$4AW;q$7|Pu?CKaDA9p@;Uo3yQWP52a>$)r*58*L>o(-Y^+rnC)S&+W7d1 z2(~!3u3aZI6oxBZl=J!~ywgxKz)k`FMo`g87np!`vslV)T- zU@Rz$<`ft>OAdM=9Urqav1A&PmRwZ-(%66W%R79Ujr|?^eR*%)y!~$La{n#c{@mOC zv%CGf^Zw3y|4S~&tLB$b`+SJEqYP#uONV^$+o2dmR2 zi;O&g3Orsx$I-3GWs!ugid@`bUf;ZHnw7kj@dD!E4IMvFMLL0C9?y`Or(hc(-HMCl9f4S(>3D;;;NlX?QhJ~Z_HAg zmp^O7zoABK-l`}l1N#yV>PI)X=-c>)Hgh4I!sAcY$+Aw;Os423M?9Mv^4)|}c3D;k zoxL~z8M_}4yM!?Rnb2)2LiDc?8js{dI`M48R!TB8)*q141LCB*mknV+HeaGyY4mnWe#pw6 zTkB&I*Pa@bE%_&FYb={EhO6+<>tDGczL+TPq*u68H--S?YS$FWdX&EO) zG5>H z$8@p^V)8Okb+!^a8DibVV4*1IJ>#nUireS?Xm9Q@tYjbE9Z8?Zwx-LAv2s)Qs1(^N z_WiBL|JCDvUj+C`9mzoF$9iqX-0FqHpgI}CwDg;jrKzQ_!{){)>pdx6Kaa$>SCZe}sr22G{H_F(2gX88VZ%lWclw%ZM8!_a%+ zuKggaXjk*EN`*kt_ZsL0ey4*!!GfJt)Uhq@24u=yh-L83 zG-tM$hm$TY&6LwPY!a9`J55~v#9XjI;I&j?@vitqz{kNET&R1k-hBW$NIhy_a^`o@ zt7N>X{gBs=l4fHYxBp+eILbGG8}4ux@OSa*$NJsLSH{9}SP}a&%)aMwS0GJER_t^@(dk`cUz|)+&FtZ==Z{RJsM303NbhT`xVj!3=0+_5I z3~YC%#K$u(#>{b=EtrG?lY`~}#}hOG|3&x=mcD24fJ7oq!UG#a;S2nC@A(TR$a8Gs zp$0MMIJ+xQR@#WSa-zI7=v<#IAP_#;vZwz83{gPe;50%zr&}S$J?C`Jd?nVux&RCB zn1#V6=@8Qe?So+H*g}wik_+ z=OXlVnDj$a{$GX@%s{vgT}$eX7B`SaHMI{q@v1tBK`p7^H>D1TeGg5UNLOe5!R7h) z-}i6EfA8OXyc(Pj{{hGFvX%On2Dj!Oytos0qTR++7=E}J!s*pdKlLw%FueM)e|i4% z`Q<0TmoK`c7=3vdEBMlgFZXoP0UW6nHe1Pedv3TO!vlPYi*dLcEeb!1zcSky%gze* z2xT!-;R)f5A9rM8iq+D#Fi%%9xfuGNx!DEETqQ{b2n^2(E##C0Q<(*^-;C0<_~Fx9J(vJlJw~}AV*`t1(8q$!0)sT^JYFN1PGPxv zsuM>EL{ol_9_{a^WVVLvo_4wd)7a-rhgrO7fYCuD_g=rgecd~Jx%l6I<#liIq7z4@ zbyxv@)kdPcR~6`8MMz|rwGH(}A%|$HXG^S_s%%=0hh-R@jok@s)nZ(OS_f8XY=B$= zow=)w5-hr2=*N~~*X5~B)Rh%l)#4}HabUuMO{a)-Y8rE%Q6<9x{|d2sPdI`aXXK!( zv@PneZ=>&&Bj4 zg@qiNOYnSpaW&}I06K@`G9KxQ`6 znpu#Vs4PWG8%ZK^SP?s84*Cn&a-yO--T&tMpQq)5TH7 z9GUy0a*=g4TB)or$N97H%#xBhF z{RCSZhAz`!YbKD3w&Wr!Aw{FKra%=Fa+KbdhEyN8SXLEo`xh=dIP57rFR~onhYM&on zSqyys;e6O1Tz@$2?+&?fDa2FyC?X^rlC8t?Sfv(U-cw;p&bt!Td(zB^OY3dM-@-0I& zb_U^gX-|uwwUr$KM58vvFmEosCt}yM@x~daE8^qn;>au!G6$mKpqWuIk5JXX1K$gA zua5d=Uh?{jX>xi>gsE^akt=x-D=ygt7n_*;*f%Pg*q^e0i|nl~72Ab0=F*#Q=DzZ1 zsegI4)4`J7kLmDe5a>|n4$4}^Cw9hk55a{hUvPa z$Y(o=^yw;d5UEccljBkKRcc#Yp^cmfYqil=MO_=5Yx?#hWn$bZ*6v88-5qIH{$w*c zU`!n^CL1jiP8Dy83&;|8{fV)#CDTgVkwy9%k`+~vDqa=GZ!->%gP$D)TqMm}>Ke6V z$G&Gy!1LDRu~VTor%*9~lL7;f-Ji!E4wn$R!gf+;;7_qHi6Y1&el`P_EpkPCZ^48$ z=Rw(7u}U018_RE+hIw-P&%0o>ZyFs)0;CnFow+o-gb-_Y>2Gg)+Ev023!YN3W3x-N zRr1F~sGJz*gQ#W8HYKT)*o4+(*i58%4TY#-GV9M!>-fw1gVQqBqB2F65qXTK&f(;b zP)UlE@WZc%Xf!t556M~AKsK>%E9gcePmJO#)xzxiOc}dQQ6irQ6-09Sl0T~p1$}cIX|E}L>+(F4~E*xF@vG%rINN=RO+_Xpexh5g7gt;j_V z6BEEKestcR^W|9Dvy!xD<7oe(YPg1|ZCZKrBrU4ohLJ>B{bVAg4kOpRSA|C3uKC4O z(-QgH2xNaUNxj0I#*5t!@wC<5qrBc4#-!Fs78Q7s_BDCA=BM&HoU05^J41PQ z45zz&2C_NC7W0R2tKZ7gqQ>v#9BXsiHuAfF1?px>$qz|RdQH!c)7Y|{xOF6trCcVL zq#B5VB-9kClAvX^&F{MJ_seb<04Y8|O0tvoW{SDF$^@`j?0XkLp8YVJ%(m(~J6mLj z^t>D9^50lMn%yq3y&5yO28hZ;h*@x0uaCKy zgoB#xP3v+QhYo^z2G9Dy@douN4Fvp_AZ%6>cY>UD&&Z|vTZ4CRh-?TRpwAffYd}jx zzOLzzg$^_8TU&fYDz-y|pwI4jAcBgO8P<>Z;0Jx^vi6AZLslin$H!zuodACRzJ*JR ziSNyc%jTqYXS10A?o_NMg3i)E1CqF&AR{kyhgS7y>(kb10r*=pJCb}tu9?GVzz*Zx z_jTWk2TFy#ifhOab|;uST*ch2-?z4;cu1yV+aXP#0sjI*T|#}IE{HcG0%rweK4C5y z^IQ1;z?-rp=jGf8#G3%-iwTpqKtwCTFEaE9bsX6zd~V+?$lUX9GSh)zKAn;PMz~}0 zNdK4gV3Pg~kRq_Pf?3RSniJ~FS*^|`vEdJD3x!4q0x$xR3uX=%0>`UqL3SrEd?rF) zQ$l~N%m2>80muOvg|3at6ywvCfGQg6y%>>W>w{}m)a{0SF5(oXwbD3Bm#VB{A!C_ef)pJgF+1V!gd+TUn%1(9!;+fq&Xs z{)&Ir>*Qi2<-qn_5LE%9!2;J3WI}Hl3SY!Dg2aV!AkKS)4u|kJ$bpxHgx%f@q>{Qr zVmlsiSI{xYE0Ytb&j<)dz@XFfeP#=1QH$pzgHDD+=**Eul10%X<|oq0VQwYjYZatq z{{YDI6_987F-@UZhHJ|)8SW&oNRu!@vGifi9zGl$x&Vm(9045r`u893JLqW<@L z{mxaZ-S3^e{26-m#Ol#1P(M7+!D(K0x~&pG+BO^`iGh!YhZ#*!=n<=?=hoCBF{zFc z`x|kWIz0st+Og8RN^-fxkoS#`@sONACYpsd%8~$|lOZ*=P~KRSHyV)MPIU4Ayan)E`Dhn}FwZ7B~}TEQk%pW56OPpi$ffli%xid+#n= zSy)SxvS1_e#V*N*mehpI*04ej^wZ`ivI$^Q3(C&ECw@4L?ShsKj9@1Hb|4yGSIxblz2bbGy( zOBS$*m4f}>|0F=`DW<(_(f?Bknwp;TE`mgCrQG^Q!ZC;1x-oY?v779W|G^|z#F6IJ8D(I-qVlRg-H+W1Q z7mt(1-P~QOyD4;PCO4CyX#xCoH0)kB5nH619|UOMIcCU&O$ST{ahUj^;2e@|Ginr7Q~HU*XraFej^0csh+M!eh*NcG4-!35EEck@KYmAIQr9qV

    #qqGGQE=3M~hK57Dt9#!ld19B&TlJ6OQCX6Lfg#;6kPC&ZK{ za8oq0j0POS&zbhnfmk?<3>kxC6EV^+B)16hkH=7Ku_1y&+|9!X78fYF3`>%Bwb9FYg{j`tU>za zV*Z#(4LQcbgz6maZ>?i_<@(F)^_p_f?7V*6YWGZOMybJgtgDdqoz)2i$kS`Ah3q?! z)&st>8d4+I%=Ub6DPn2aqi9(s{U$hivMMTuuyF@xj+r1H#MM|IM{)FAW)MR|J;qcb zeK6e&3q@x@rs0+K=v>cdB&o87p7eX;lbZ0gE^(JJW|?Eic1#>l;i(A|>+8B@vQe5J zO1X`)zD6}tuTxTvjGD4cWW@bI$n46Y@FS`m=`;)L&-G>PIWGy)=JbOJABjqO2Zk-G z!831`A8M|A(Y z_Tt(Cs@)0@X9`5M5C)owG>n5R4CRhCE<>bQSj+M7V0E&NZ6h7QR*>!$iG$;LH-X|Q zjW~?V(?X92tHlx?1@wEeQmoD}l?@Oc_yX`9#q6K?Y}}txVNWVn{pa^5r_Hn0d1L>d zA9o+sIhvm&{gm-N*qDt`eF;yZto_YvNgGpNljg1G-$+j=b$>38c46`mJmZMafhW)N zhQw!6tdGb8SfB0V$s8}R2-qG)P>#!Eg7`o#SF$DhBj*;t*~XYD$@xEqYz_c>@T5#4!X~%psPivlQB!?m+_!}X~QMb@Bx=JHPg#WexJD5NeT?;S7T8Sl+ zVB|Fpmj!ssVmbGQiA4VUh`U`x<&2G%)LZs0@3zF3S`y?-nAhClZ{va2R#IFly1Nq0 zxsdiaC9qkbHU)R8PrI9Mt}oy9Pp?m!Kec*?d67zyBVP)_W>9#&f;uVQXbFS7map;p zqWz|uhl;8LIv$XKk9FO{8-WtyWlFqb142MCa-!nh%Zdv{GE<3OW&1o!Ww}<6u$RwsS~oG z$j+u|nz(tm!am2CC`N6nx4QmSUaVA?`@o=ic*9Q`9`J$?y4|ABbJ>^*jvh(Y`V7V- zOOi5{7V=_K;WEKkB?tdE%q-4jN}LoPWf~nw$Au7q17&;_Ge887RX8l6Vd)5ciV9fd zjr=pt+Czw`su5u?=D-Wo2La>>pQ40X_H_>IoQ0g#4i%?LWUvk z*D*iDoMq=5=iF6y<6L$ZSAorD!N~jFi1(TB@~-$AVTAmjC`DN66b#e`<->X*lqFc6AbE3I= zKdLU)k}u4{AMwy7 zdOQ|!FgkgO(q8OC0j=UA0l}t)>Yj-f3+}lp{_~jskCFd8%YVL_|7im92N4k4N(QeL zCfBlAFkkPO&J?}yqVRR)5nZf}OBPBaQ{Bb_1u%W+g#(9?Uqer@!t*&H?+(p52#AMK z2ACy$D5kP~nPAH69*O5C@;PD=IO;CM1j7&}pUdJIxjP11D8MR$ldK`~>L?k{4yFE@ ztH)SuVX`c#-#^NilM1aV^T)=^OV~02=3Nw7CVe!R-2%xinw{{~Fu5SmloFee6M3Lm z=x589ixQ+-CPP{a)IFkH3F01+E;d8dv{C#Eu`3N7VGMoSo|30v#%xXeFzw%*(4#De-UcM?y{5v@3x%VO31>-a0? zV;~%$jLNb)sIopfLhYs_yhb&p+|7$__IRoy`7f6hDiTaOR* zH}f-hjm=5C`$~j=;trjhxnx~^C&k6L;F)ik?<;2yR&NR+oHqn>Xj4Qu_R@3eiuj)q zi2h-P%yUpbg!mwoq(Es%up$Ddy!4#PfQ*GLBzHEGcy(wAwm7Cp4N3XZlYG~{@0TqK z7ZM-=61q4^`1W@BWS>^veK^g9)yaxA5Wk z?J>H-VdMrr`Vao@r?C^`iy*v3@R`1uJL5~|0weln)FcQ7zI%R-L;BTO#M2-oAJNYt zzCeR14zGh?f?i!j{NJCVe=XeK>pqTOXCU4=;TXLexBd7w#OT#*Hg@U1S%`5kzYX1s zX^ei@-~Y?*5Btymj0R8y9mlt*6HidJ@urLZ`d767pMOSw`RhLV%l`g01@+u9_9JNg zG>+%di@m)IH=Zue>f>OxN2~FivuH2Vv%NDfINO^!QB3})D8{%R-^A$6;1G4#Z;sx- zMDzjl1p6F2VVw*{_UqVCt&P3 zQIs9Xk(iD!8vQbO^zTQH05zQ|cy>?&d2SS=;2gzJGD7jxiIGFd*YUjI8c)c36wI-Y z92Al9h3TY_0>N+Z2GXP`qA)3-| zGK8!GQVc4)o(9N`X`wUB%1s2uYeE)v)bJ6$ab|N5LtmVvH>88Kc$C45V31I=F=**W z@uw>%WTVL6?9spT#TlV0v_)Zhv?CEZU>2TES^ad?mWttC5*2ajX0_e^O$>JrU zDK)GL4b)SSd%9HHO9~H1!~O^M@57vDdzQ?394_wDls6m0=39gwraa%X`#R;V4iO^= zJxqDNXZMz~ANBg|--kKR_U!)7`AN4qZ1=hkbDrzjy`A&-Z`&Qp+#lvV+p~K+=Z8K1 z@57vDdv;${xWW52Q`;Y=JlnJTI_1>)gU|-2yxHq8<$(XY?!+zwtvo|A*{#N}92x($ zRAVye`mNzfzbnwOU+ds&_PWD%_oO8Ti~U*$Xye;x)i`e~$W zMNy1(f*qrY6FY!=vY2}=Z1qmi6o;_iCU8W~75VATNZCc``WI;Kgc1DZwVu1)vioAB zp#x~okd1@Y&KT0`sYV61Y$_$TB|X+0tZ;s#IUc)?2V3cUsvS1VZiwRBIgV_{D-2>X z#bi#lD4yROZ-K4Ht8%{ZDSa@(QAs^hm9oL9K+OR(wZcJ<`@Lar_~E!!4jYHJ75+bi z9rizzLlN2=Pb(4>-61K53vs*%{YnbQ1cpU3r(tj{S4jDIIow%@ol6;xl1n*UL>MUV zA%kPg%3@>!KX&~EPNq?auyRoMT+9RqZ6B2bVPb++WFXkMCpi+5xbq-XY3!)iFNY$lOojTbVF5LEGUEXf%VIq6xwG)%N&?1pK$``$P%9kvZ6=%A z&hl6uHLNDiUwEEUUH7EZu~|QEq_*;Hdtd=Zm`ZRiEdyXGJqxm|CgjBdsf*;e(QkE! zZ(9SKy0^0^nA}(j$G^4BP()8Tk}vv(EQ#f#wkd=EIwAeB$8xG~%d%+xo<-B{cG}$* zp^BCTGp^^l^5&OTllG|J7}~7uXITu#ofC`c+|7c$Bb?O&ZYKvvmUjENV(<@FAI6t{;hpzvBdu;H#oibEsH^|oC?qwEk(0bRVW@T3-a(GGhokF#BQ z)9ZCwjqa%1vslHSKWEw?plz1m)29aDM)%O7>RiLy!}o2%iL9zN0b5o5STpiuxU7f# zAc0rF$TGIx_LAL#tRUc?tZVj4m^%5=K&DKmAr)}lWve3Y-ZGm@kRiAWhVfV7I zgoWC|{wY^)@6fu#&$1KMZCVWSZnm{83#h%l3>0u}GO-qrJF7$PsMK`WYuZEatk`0+ z6%Kwf{{l_0=g!<1hbx%e48?Lj3RL-2VJ0*ATk1`!JmEIolhU&0p32T7>L;eo2Ji)q zgV_xG@d{n%kW2QRQy%FMm=xu{G)8XFe=`48#dj*!#bLm*Bi1CQdkjI|K6k36zPRft z_R)oV1ySk24AVm?{1^m<6(|NU!Vx;VMGNW#qu`?p9FH8&t8SySMT{l^4J7vh>I}j+ zap=I{j&TGa0#h6y*N-rnuYAZo_|?GdC$PfJMk~tA<&$68rl9{$X4ySQReDIGci0+q+eb%4Df+F|f72VZhab>u^n6Zb-+lv{8EA3a-;XIPpF<6)ao~A25D~`Ear0@ zR-?rk`9&Mn8`RK#4gI*ijfiALmG|v#CEF$iJ6QQD@-L6l|B`>VX3h;=haK!+#8U#e zpF)wD!OnP!s#{=<@4lA3gigf0hOlI|uIS5bgLrp5>{nUYZ8DUZ8nvCsHA=-|(=Wd8 zl1FeE33$u(2b`ounMy_a%qWKvFaHdTM}coLPNs)HTfku(xe3bWdB|z>4J()VJod2T zze!Of1e5LK$I}uPS^-WYTq4|zA2xnA@VE-|%Ob_bshQbtux3nu0K#jHt-9uU^L@JSg8 zxvi`wvXWf7#0c%6S1Azue)cT86etE#oMHO7<(^6ngJ)^3C4dB%IADB2SBy1)O)dYa z4jvmaV5T+J!pyQvkg#RYa6m(ORPKKb;={_IIf zvy0GHP({J|fB!2ZWq_*>hq1ZF0V+jY*kA=vH~fzbL?qbfV~|K%aRiSLl~0zzEEwx1 zQH#>YjDb*A0}BxZn3(M<8;lp(Q85VfFME5S3cKg|g_#Zy71$N@^r9Z|&WkS5de0v#e}G9k)i!ewiOOoEV|p_GuFyI~a9 zwUa~oG-J$dn>QIc!QOHL<()IK6-&7#KN%VJ{%w2M8XPy8HhcS7iIxIem<6hQ%P-bc zhKSym4vonK z^PmWYD9KEWiy22rJ%T5wI$;4&jzzc;@`HF~1|h*|d4(AC0!EQ#fZC4gn4+nm%z11| z3U2gRU-k~!(_q*qM&Jspi2**ar3bcT=+z2riP6-Zvn1u0UM(WrMd)6tn}WI48!@*qM`QF>p*e#H>uDdST>;*^oD+09cZ{Wa$yp@dmwSHs#IkZs}6ww&cwz zV~d|Y8PzoL(1@g!NK*9Y*|Vi6jkYrx3ew7b^!c;&>QCqgHsSk4O{dccv4$@7$YSul z5_|iMkT63;1zTihiv&RwAfUO-6xJXOh#LS~K%~Fv=|VrVbTn3wEAV7wOS9J<3>)3y zsMT#Yjt8wnducGUYT=8OGb*^}s?>hU4C{P2VPULy+3nM$7zHij8^If52WpHcdd$Q#kispxuPs&{= zwle$hg5VN5M7Oe7-*|?nGA8mRKcd>PwsJJ3?ilVmCcj}_8+=M9z6Yupm2lh>FYV5e zmx;Vf#T%Nq6Oe^Ee9*u%d@f8xNi+iL8rYQMDVkvi@_@zQ$3Jt9(AmhBQNe5uvV zNI`lEHWb9Ov4z3psvs^-9EzAFdbHzuHu6@pRMaJ+_C-upJz+0dTjV`PlK{vJmM`Ci zW+yB7=Ar9H?nF?2MpId-%Fev_!F3h`jjEvTltmbVxTJFh z3a2mma~5f)_q-I5v1cLDRb5SsFiEX;*R z`haf;NQHS{cm0x1`B{|>xPe9 ztIhkAGz*G$ne_-}3s&kKx}N&2pHDiC{;2ie$Nkn|(C*nBZp<15c_d4_q*#wXChtz~ zm;Wi-yKm!(TA~#Nm3#xARGz@r_fNUfkAq}v;3V>Cu`uTlMrkWYVrav5#A8;Xms08= zKw^r=Oe9?rvB86yBIa{)FMO(EF&V`qY?7Z9+!Ri%W71serb5bdFEN4)V(j#w8`a5= znG@$3w&H%1f`C5KSS3gZ8z$a%$rqO!1)`W%iCDN8&EPa%wetC+v-^8v_xJtXzl}~m zCvgPKx08eZ{8{(`Qw8rCD0mEj&WjGHyv7`^{cQ!2Ax4Q{#1kr$;DwPgwm`jTOtCXb z!kMbs2&dg7!if)~QIKSjy*7Knm!OK ztM|8UOo8QtHxGy|Lu{3F6lsfViRH(}CO125fXX#nvwD&@WpzbUzwmSF5Po%#YYV*3 z#~5V?O|!zbZj>cp`)&@8@`^T zfSvVxcGkj88oQFsCi$T@X5|WVAq|n=q#Dv6!Sz6DGdZH?nGzymY;vno$bY&=McP$I zt(!5P$CL>?hr14LnIU`bj?1u8qwkuUr;Z5dXNtkz&dwf{3XvS-jhxbkCZ{VXmj-=A zIjv#dAAx5p@Fqhdmr~oWOx-Baczt|rhfkhi3x9voPOxIr10|*F3Vd@(n;5Kol*I~O z<%>*j5$1Fu0vnFDHYXKN)<4P@F{9pzN)$DrIxn;D0#Dv2q|D`Sb*BS#Pl+gJbsN7J_Y9=3gk=@jN_q`g?Mj(iQaZJC zNiCsO!&5lTgyl``{F!>KkDjG~|JLMzYde$3nv7xxLfL7PY|VCP4 z9>SHfkHIy>sef%}km|G1vpa)RCf(7rRt?LPLZTLR1JLwfV~t*T!+Lwo+%k(fJMKp} z4(OJI4g)A-O6;YwNkFu%TP9)7@YsQKbp+Scxyrjl2r9;?97G1&ohWDjDCA4IH>r1F6F!6`Omb!o z+%JRNE?)aiwAqa~T0|@ENML+BQSrSBiEnAs7p4kGqc`(K)@KsQa)9oLA zB`)uc4jfiu#I}h(k)Kt!j_cx3438N$#OCI7(_Qp~EW$JU8}ut1qoVj-&xv9YhrwCv zXdcXYx|qm7%oHqjaHLqIfGR!YS}cvPhEho)wXR5<-w|VzYyT$v&8`6j_`eF9>*HB) zwQ)vA`>xG9Q$8xRNH>>^CP8TcOAXI`W_YTI%7aIe8pKj+ii3vcF~68-!R&d1$hNK7)D-!ve`vK0jte6#ax%W@i4lil0GQD?^{U|)en z{o_fhIT#K#OUll-IFH5SUWInEu>)Dk!ME~sMYNzsar>A;Gfk)Hd;m?I#%dx>ij-JP ze#pig4@n4j9!P2=I~n%a#wn=Gp(##!NlLOFkR*@C=G(VHPr6pGU+$RH`jlFlPD{!< zrC3v?9*{rYR@_5Ql-%>PopQ zH_8|aQa`Shv#lu6@UlsG*)2HsS$LE3n@hvHqZH`|*K8AvhYdj-5@yND&zwkX1i8P9 zFeSb_ui%&k6ZiZ!%_mOx;{O@AJn4BHTwwAoq?_r~p~2oeur043qIq}lE!&Xe0aH_! zHC;rahcpj*%1n0lq&YcveaFkBmsgVY;_E@|j4zMlP|dXj8F_~yb9CZ7$+;1kw+c=hw0+N_etoK zY2Ill|L4z0`(29R*2*g>*2^fcC|=1A8<+ZE;f6;Ut=^1~@oJFJyWvE)<$yE^d!e!~ zHA2{JMkzoPZef1O^`)XjGQ{*Nw|H;6L90)%=;T>8m>)lHFfx%`givJd;2YjahJ++z zce;kN*9T~xJbg>^n+6vaE04;+6&9_QjrFtSxTSctZA4h)W6RR+hWoMqopduzF3LJc z=#;FTNexAp?mV4;xD%jg=SV_FleYUrA>!DrLO}U&RViCT$qi3*b2bMun)J zO%M%y7nIM@P?U*A+#ymmE2QcbH7S0+MG%3pISTwlco`hkS;Yf}%rv(vTKgJ3uFd0AS??gJdm>{=|J^te!%^e% zmJ$h-&5L;s8;IpGy@v=nbSxQKc9jN)tFz2UtXfE76jvg+Xv4+%!&pRtccL*4!Mx`O zMR6DgVT6J)nHLyU2kHIJ-5|!yq~Ig_{8VJkq`xak&&rikMbgPhWpoOZRuiR=9XhNB zke$dQgd*9kIn0_x3R*qGkhKlyTb%^e-}ym{>+k$X>%!OBV1$GXQFxZVO9#um1(bJI z(>6o6cBxZRMQ`E7hNtwzzxHjJFH$=KAR76cEho29WYn-eO+Td;2m4}{&qGBtX%Mh4 z1_XtiSztF;Uc`|ztj9F6#Z8Fy^%vD$kiSM;@Iw>sMm569#@=GW?#vszGqOxIVNp8S z&pfrcW|<7q%*DP6T&aa>Fi-<;B6$lERmW&jDhX%)=i~nF-#*n(pKZ}}Ge!CmV`0XF zr&<-!TJ@qBinLJE=27mrmN>(%ysev~vt+8PDy|orp3x|9&CG2KD|Iw+FCZi)1+a?* zw`mU$R3XbdNaIA{D&X$PyEm_^G1m+U+en7R`;;{=0Isc_)UoNaC6OrH!WkIZ0B#P6oycw&DaRt z0q3vFvx{Z#Vr=UZJ&J%*3R6SflTHU-vF73&mdrJgB1Mmz7cyyJoOT0IbV6M z$s|p!>DI|ex~r0yJ#!Do>A_hgVLP!FlAAWkkW5S%#YJ!p>2^=)vN}sF+%3!6#qFBx zWuYt@fEzzbR{1-=T=Ob$c@i+g-I{75PIfQ=r8jJ{bec)(%v3k0$kG+C#S+109Q0;x z#P6$?Umd)rjK07@#&0e>ZuDE-;oH`rJ+K1mw}vPE?vgd7*O;#W)FA8M9w@oBe3_ck z+sf^Mz~R!6U)ce5dh*~|0S!MKw|Ym*04X;#I_HGmZE2}et60`i*|skE(z+zFE?KuN znec$Jl9@X=k6fRn6M!&C!npliY4e^R$EEv$P6T&CN$CMuNHyXH`JxvuwrC`SvL8hL0=7g2Dsz=;Y+LO%u;h)E zncE7ra$c+^^!}nuojATBGN^0CaSdEM$-a#gh~Y~9memy(P9jNS#E9KotyK(46dLQh zQ)!&zfk+_zj1dZbsotduukx-H`T83uk>t!W9FqBE5y=<)XfA>&y!}j^VxjG`OGFR* zEL`flpt3->XD`rRy3UZCl!?PoFl>EKA>oPy<_n z+a-x067>UmQ_F98f)*6nwCJ6_~K3iz7<%9Gqb^ z!9=Mizo=K0Ux-ZaPB7ugTu@Y=e|@>xFmXC{89ml7qm?3^QvSlO-=YSEn+C^Pa+ge- z;VI**I_C|`7W@x2Q!rgLJXx^TVZ)PKFv6I)As)xTqtB^Yt_H+0n`Z3zSpQ|H&N`$j!5|fljY4s&iBO?-$Sy@jcP+CS>E~rxl?g6{H3;w`0AxSg;s0?$F z{<9|A5GpBMZ5l$G1eB*x#b_LausAoxL8Rd}Dr7W13$C&$jM0+fA!UzrdPt9*Ulti+ z#FEjU(o2w~$ytp+00*3kSXqYGRa*o5; z#ZiqcyfeZlDC-W+{z)hH%8I zVLBK#`a{$>JZul!y>6p}ei@+Sey<4^Nf;fd@Q4sziF5y)jZ#ULnH>rDF)iJ4!7?Pjm@$f4Yzk<>OXwwWYg6Bx(23|~8d)br>p?=&s$bM==)FT| zZNhd@>xYE!-~}wVI$5)E0Q}O7Wffw8$26>uZH84m5TRkjQ9QiXXo@0jvX52Xh#OO| zsr;;$lD_Ef8FpW5M#DLS+)g+iv9G4M8j7G$da*JD`OR_|c(qBH1JO_mG_0VuHI@y@ zU|<4@wZ?o4uY%!53yfC6u-0J6OeP^-OE@`fg#lLX{9f|a6$}N9v{M6VI$2a6Y+S(M z+~gQEF$+b{tS_F}cq@qvM0BFLA_Q8=Hgk8frCH^(z0EeXM5pYsP-@?rZ?!H>`C-&} z*+I=xl{b5IV=0{%9$A7GBFU-bbe=6PxZ~5HBvg|o)^I`Hx74Y1S~VvgAek)-4SV_d zhKL8l4r2S9C&hCV%BHFE;EaNQLESly4)(Bh)Hvx35ovd`F=)a5YK-++b~Gn}3dpI* z8ZS7%p|w5UX?I7HEZaWOyXcNs`>3e>YZ)SDHL~69w7ad*@NG*wKjP6&Z3^D%3|f{l zTb2_N^dC}KxOrj0Vtc5pkcM{MEWm=~sy`T-s9S|F*Facgv|p)nz}~KW=*^WlU+NBN3jau4j6BKJ_ zBg{(5Ya*=*`@~1t2697+7(c@g1~*_9Qf3bV)WjRs&xE!fPss5DMuvq7r0CPC7hk2P zjD0NjDbr2!WK}s3Hw#zM6VuEb7(wMxvhL(NAQIlqTVlNEXx8k?w6DM&m!sv$KWBO&` zOfH=Zm(efd762Fq-uby3(Nkxc%)$sBvL7P%f(>VGbQOkE_Vgka|2~g@U3&l858UJ# z?;%{=MBc?LVShV3{O-};4!{088{#YMB)MVTWXg7$FM90z@7dwM|DApJ{UQ7A@Nk!! z`rgD1Vnk(@B#Zd*!NG->%$8^SlW=}O-T2N~d{Dsi;LH!t4(3jr!2bkd;_fHc341X- zW?gB_GR6k3?>e#jI34|1JbQl2 z6`1%=92X~YEY~B7$2jZ1-MfddX|eEn$ePUe;)I3gEWuY}mdu=lIg!g8-w&_cDg4gD zg&Q!3#W2CRp43tT7|pyG-jAFcXc337=0W0k0LTl@!)Wd#IBw@GTqf)aL0@{oH0=(0 zb2(TE4!d$Awv2&<(w?Ek#1CP4(%1KxcTRU4Oq@jCB=K)p+60;-z;tqe)aE->Dm+Jk|Gn-brs}Uzolr(Mw zqJUZdq}?00P6yqe$1euW){pHG!q)x1ciXO7{cgXP|BR>a87p} z5X6~o1p?U_lH|rHQmo>}7w%77s}(Iqwf zqSYL=UZwY2s#r0`&x9&oc6!ZjSMrN3Rje4}XF?Tu-Dj(;%WJEwuiM#OD(hQyS6r!; zO*6Y88|V{PcJqeRmQ~4X%c|DxZ0lDrU0X&gF2QIw$!0f219xE~^aslQmc`0z%VO8< z3^-|?s945g;lY+m-J!wXAGDjPBWSys<+a_+>vqQXtU^>Qx0&(5c0=FYhVJx6?ZL}t ziz}5|58jF~ekLBgm#4kfs3V!&mMT_^@iU={R<}7EruSQ_STV-WgepdZW@nV%Z>eI% z7(WxL=rv!rhbLRT!g7qCi@N#dRi~TzFSquiytek^x}AZUm?tWh*^l&KYdzlGc0TT_ z_ggN%VvL`O>>s}AD9K`5s#r0`&x9)Iyg+(=N}@lL$D0zvxCz>?I~*_pO>h4K^8Ll2 z-TYBN6nD3tu0eZrI_OE5{B8q^R&Uhlownt=^1EAu9laX#-!O?Q-Q8Y|`43@4bKM2* z{#3o?_N-`42pbQzAGcpNPrHI=i<{dMmf&Tau9_RjypS@JGYh);r5 z4qgZ7mV?*1{+b+IFx!pu+E1C)4oA(wX#A=@Xdm}m8#bXzunRwJ$Z%@+j`N);Km6&m z{mB|iyH6}nwZn{OC&(+#vBN*VETOr>mVx){(q)s-_uUDdWDof%asox5W&86eoYSLm z?yxpN+z03`n>vYuu&2v~?_o8BDVw;a+99b3Pvx?gqxp@IYp*<50YytC6K67`6Z}&um*578Jjs8vaN|7| zxpC-!fQ9mcB;->Un-^ebH~lSkfy@#om^#tai}~!QkHrc_-UlE8d@aG18jH^8-4-Dx zR||13BHxN!XdPpP15ULWv0u$#1Q*^1EQ}BWF)5`ua+nX1(Z%fShAoN8sQLK9O~#Jz z@9eU(Wx}Q*)iUry+D-0t5;=f*IB{caA|b)#ctPw&iKglU5-t{nfVPs3siV?70X<--{;NB zOB%V!G78Mw>UTAA-C)VmmY`yK-vZrcK{J(X{KtO=1>DAc$gDPRQG@->aBP+NedN zvQeR*BTgH-w>eh8Xpw%15CUiJN|X-Y?>^Bsp-u$dt$;384|oqS_9NWwz+@M`GjVtB zzYFf~G2ESdOr3<HT+y-+c4-o5Lqx&)>ZZ=;m;Ke*?JZ z07nYo6{9KrS~))4r$pR{gX^C^ek`Qj(8D4+Tt2Q^c}^^N9c2LDHt^TRdqWdBbZjEQ zmtXyOPfyDknGsVkQn7x58?2F=-~as|tLfDsBL%<-m%KtrNw@lAxsRTuaPJqm@xcMA ztloJZ_QAtaSHJ?VTq*#?l>(rN0NEX~$4s1pZiIsTT}1Vg-UZYEl?~Kh;}TGkxGemD za`;L}@pzx>+yUwfz7Gn_WU@q!`5eWy;JNV98yC8l^_P?j1p3^KE~qFJmWBej8G7&( zqzb6lfD~8$!)3&13@{HU^AY0`OqjeF3TewUG*fxUk-tdT(ZX?8`5i5Uc4% z-D8iw=3*5$poxvD>^Xj`$c?Xn^}gRtd(hG&^yrUb5*>nYD19LS?KJ%iaD^fM$g9ES%uDu-Z<_`Hyt83gg4L3< zYEtqWQ2Wvz{IwQyHhgt08YTkLD)Apza_ti*f*G2I6L#i@lgpT|A2H+^nNG+8MLj#$ zi9KMq9`H$WLLghd4TDSND*cKXE-e`N>(}kxNNY2w>NINgCH?x*v!Yp*@lI)2?d4Q| z&FTUFcEN}S#Pj_Do#%crax2C3c&qmHzKF6x^H7?6^_7*B$GzwUWkbqBWGA?%sm9uTWOD?y?Et;IO8)bN-18=Lch%ZImKMfJea+SLzNi8;s>Dfn5rLUJ~TFW z7Tnu#26ETc%T#RQiAs-z%|06vyFjU)lj5nfPRefS8B;F6rGvHsg){v@LG9MVbMW*nEnL2kulX^ExyQ&K@aV>JUas0&np^(UfBvvI|Sx7 zT44}+Cf!)JEg6OKfyOS(O=$^$jXjo|N6-Y+-pqnB*Pj%2jo%uTA{o~puf^ynhxVhfkK$U2ty=ZIJ6|L>xgk{RyesskH|RZFiWovj49XR?Y|*=~ z;k#xn=nRC@rM1ezl?>n+PMWncg zDj$}}4awgt1OuOx`O;53tc*)t30u#=PrGPc0qXAc!VjnJjw0SwlGo54a!B5~=-#7W zwJoF%f@yt;^5VSt7vZ7%MQ~$+iuV=FIP*yewYu>>^*d1ew-0_XY**S9zYu-yWJ7xd z5@DselLyZ?#>y>TL4bIz%cpcRfb2>vtBK-QPv_JHNa@AZ%+nX$_V}Nt{Sol;;b_q5 z{a{wba=s!JP(u&NV2V_0g|eTGX@q?9l2W*bn(LL@h;Yk_EzH$EHJYMa25qvABPi1< zF;EHC#Re5g)EWiU7)R7dv?FkUO#!L;X%K5q07SI>c^D_alu8B+Ucj!e917?$-=)AR zX`l`;LiAbTEQtPdkzD0+e4OZH7A`Mln>3K}sRNqr1k2u>P8Ec6h%#ZB6Df)SbD7y0 z2~|s*(kokvS#sQUY!Yd6=1wkoVRb<$lVnN0JckA06=IB2jd3@p7-H4IgMrOlf58Wi zQ5Bus5P-E2t^8V`qv{*s7HJs0BIcP&`A)WIz5W|mv%0(?RSi?)h zDvI1?wE?5)d*fz_YFZQ=l3#R_N}bPa^LlH>61S@AR#h$k`iH8jG&sq#ZMJGjwM9- zj^g7$oAZ5kOwJq4=-|aze8ma4=kz8`RGX4U4mgp?g<&E$LbY6(vI%PSWkg@#7o2c@ z^?zkMRE-ByD^lPQpbR6SK=*FP;#k%Qo3tJ*~4w zWBsXO%f_8vx6^BnN3Ysx-Moftt__fEvg_1a) zfT4`O(knVr;zm&z#XO^qq0Yd8mYVj$#O0DYOU}Y^%2<4sAatt?xFlMHu`Y{amza?; zx6;n=)+fJi#^_$P$#V>Xpcj*vSMrG*!%ExPG|RYVV%S}&s54?i+pvt{x;XN>U zhj@nGt-S}{U&woKw?QSVajE&)!P57u-0G#6{c5d>+r642PH$6!w^XXiiR9H#HNh;}nz*VHw;+3e^{zr~y|4 zCZw?1;=s%y#@wpq9BN{$IJdUB2;@Lh+G#v!`c)pK(fN4cPCUm)U2W>oxkME0qj7UE zX#OmHNz2&feozf4Iz2M;0y-3#9&U7^izRt;7$t|}GjRk~4X$6hZdu1gn3z27V8D0g z#(*Z~icWmj;Q<-nMU6IbF68kIj-*qL!sAH!NXD-^y-_{dqjshh2gn0=;`o!LkIFbG zBWG@uoukzU^)jU?HAHF#M^l`$KpNL&c5bcA6oo<|6#7$h&}qKtwkBVg2cJjLF5+KeR}Oa zi)Z1|pJJMQYHtHyNnD3Q#-bp2JsPGaR$iX6`|EuHmPmCXMriN$(UL>Gj4P4(U`Vaf zx&PNximMdj%;GQnk_!*r>Ueg$cWie!TN$!AZLW@3SZe}3>AV-mA$H5v08ZS92e+Lm zmjFQ6*)e?)Gnk`;K)}kfQwtR^wCyP*5bGTMnR3C83r?1iFOSU2Qvr15p3Vz|vML6; zK>RR<|Myu3+WUA+4<;ez6$_NlDX6(w5BaecUWDRw(B@fWuy1b&gCI=Oq6?W6o4PQs zG^VUC32y2p?gRz_yB5>J$gJTzoukP0C>$i<%Hm&_*bR>A(oMt}o791mRuM=CGzp`K zgU2x~W9Pz^c_X6e1D^-vFPHAkRTxdnr3iR^1CAQ|QXZhk`Ub_a4}gqVvOlIe!iUfk zr!o!25d=2Pl%#ef{)z{PTK=|~&BtpaG>?xvNIK0f?ZlHozttWNt#+bPG@x8EK)$3V zNoDUpl37yEggd1iZAdfb=xk|l!2$kr-CFdoiaJLp*5?+C4B1hn->d$>GAPWMaUegQ$&EEkv|3XrZ?X#ylWX zIiGpgz~4;u3Ghlen2g_e=&~nB59FzPHH@Q(#%vB&L~#r*9F-Ey)SM$x&DJJC4kN6j zSvj|by~AljvcAT9N(;54O}xypo)sg#sRs$gBne zffd>zfV<384=6u1cE8#mRn^;{noU3a=P7LavSY)$(a3asa<4Pz% zr6LB#79RFhLUiR|2>P)S8QS7G_2lppN)&f)kf!KPWi>2(lk`HJ)Ws{$$Jfa=_|)0= z0}z+t6-H<>o}8LOx7fU4$c1>orAbkSimjf>n(E&9Yh`7j zU1J0(jH2$)E{sD5<aUa z@rZjMKTQg?xCdQZqSgbn=+M4Q0C#E!N{xE*i8NH&nOviK#k}KC% z<2A07Te-$MB3he(Y7ADx6h&1!{t7XcVv(>-BZN&i~0 zIrhRWDm-0);kI;Q1?Uu$EHF^2B?N%*^f;J*Hw@jTULgGIe&J+}Dq7X~uIXs|V2u4Z21#tWQXZNjCz3_|&17131-VkCOQ78w>Jr0H={0FbZj zK6~L(IRIH`@*+g)I0Fs;%88~3Ey5%BY02|FPC0>lU9J&;KJ^?jyf6Si^m6W9BX!0h zKZAl@QnIcfFrYPk;Q@^50&U%h3f2IIf@r}FRW#6@Nq4WxoAX+;IZG|gJ6VJ|Ib3}{ z-g+V@^rxeO(@9}3E8I^Mc`dX~v0T-b1QcVply^IlXbXamFF;QI<@n}~9QiH^L}kr( zZk8Nx+| zDfWwoVG4z*z%Z}%jM9F*D}}_m!lmB0?@&;bSz#}{Lj3`l300F;t6ZYagdFEG&0r}u z<{7EfD9=7qWhb8igN2f?koGdcb|$S@;Sxd{Rt9g@hqHpJrmz{+Rt3$P4zj=$w%}Qn zA4|SNl1pP1R(f4TTahwR*dQuaW+x1#UsQ!6VJyZ1m~s#si2mWVMg&k!L0nNfSzg)V z<>!r8!xguyu+4Y6pZ{t@24%mow*s4rm~3%iQ4)Fc6zh180r09Nq4r4NwI`;Ms_V^B z+W#HSkupXxNAee|Iod$@I1lDs0=r&GV#>4EbVVgY#T%;-^;-VvQl4kwiCA@=lS|Ez zzmx3HHPh1sF6Ep$O*ZJrxumZ)acKxmrpt+3il@k1d4cWhQ%_G1=vOj{#p|&wtMrh~ zF}l7CJj^h)_;%CpJf_Y!6lv!Cza*3im6hLHq84dZrF=D)VJNaE(?mnlc^PVx&n+x| z_Qvd?+2rXpF~0f-)|9U(=?A55!vAg$&>w6zbQSsXmmnb3E7&}^dz%<3O3lL_GZ ztaj~}wCd4vj{Ypayi@4Rj*#LjFX2V^#rzasAYWpGkZe4znmRQI^RlTw7o`ya96qkI zJ^0b!v=(%vK6~iB({8s8bX+8R=)-pRWgY1JM3y~#o)%-*!_+-@mVRQ7yXiQH26i!! zqB)X+AMXJ{knEJYD=I@a`&xg>M9cM#R&YJ_faj_-Dp3u9a)HXu!HT>fQHg-pDJi$C zC=jq)8r~+*x2a^1;jC)ODKDx-*>*uw!D?90a%j_@f0y~Ts;X(e|5^Tur#xX26E~K= z0sgsB#y_PgKHehBSCSfqFJBkV#-w`Q*-i0No~18;=6a*BjpCG$XK6gCk&)s@u7;d0 zDWR?CtZ)b=Qw!BGucsa6QFIb3ZP6(Iiuz)i@Kw4?MICRewBwxiw*r$jFhR{$&2zp2 zGvvTO+5y*OUD`l@TLblc8kP<8_jPcu4}PZx@=DUD4d~rEnAe2;*b+9L+_ZtWZwHUd zU;x`|HLa%iA9iq+L;p5VpIBlmE7sY-JhFq?1_~=GXj*s=?clvW?T$Jp-C|~_7UY2) z$m7mWo#Ud4ss;F!9l(?BsTEN^vK(@!X9w@!EaCN!Pc1S0FUtY<-?Rrd@V>Nz_o6d; z(}7Li>>b-c{k53Ip{VLASOzuRv1#=X83 zE84SVnXg|rZQwn(gV!9MvQ+rIaI?LGZ-8@I8)>#smG znv!fNN^+WyI+7d3mRrr}*&azrUPsn&jwC2ve7s{1N6~7N|NZSQJ`TX)J}9}bd41)y zvB(1!i^XEGU)VeT(`vEWIr#nWci8XQDVrvd5Uj}9D$k}I{+wpZWt7fX5~rL&)2U!$ zn#Zd`jGza0diR%i?4IW$&QkWJ`t7@ERPehje_;5SepyA+578ZG^vn2VHse=mJfHKN zo<{3pk>&7^{W<4%>}tXDO_t5r@tshAekcC6j{iPNdGSJykgXo__-;|KXNQMh?LRv_ z`UAVdChT4Dz%Ggz>z{uAhJF1tJN)Jk?5nR2*;j{$1L~T@Q=SS$Wl@%-T6E-n`9 z$p|KUK*J=_L>zc{9!!#KaehYmdtc6NB4XZbkit1K_#^saw4KE1eLzp%6M)%E51%j?0nJ3H~5^`GeDYkg!1jq zuZ$-^w*ZJ9OefS~=Si&f|C){To?`5hCp;4TxtaY~J^Sv7{3e&gdoq4`alZ499a>{r zJp8}{rYy?y=z(Q(79|P0kCHWq6)Lz4JMHeR^?qHpEuzB~J_3%!{aiubf76 zAZ4op_){PzD5wrV#J~#UPF_XDLTI2HL=T7(-=$d&>yQ2UM?PI+Z~1hZr63B|VP2{w z*DU65(;ws(^(OV;EZT&^&_a`Baeo!rg|F?SjkuAD(_P zPy3CkqLfz5YItzK-omkz$1~1Ew&X^b+Co(DqM!qj4vi(LT$7wfAE@a({>a6s92&&r zk6IN_c--;gr382Z@Z?ixPNvUI?~bQDkKnxN-NKU-*6W4a@sDs8$0@a9<;+4&;}jIO z2zdUUL-WR_Vv%jGvULvIzpbfM^GbLA%qSj(P2YP!jN``RroG$xtx-Y?^$YUr9_WwR=3P`w7v^AYMkCGkSJ>P}g#GdhsRM*hM-5qfc-Q|dj&i|p)jA1 zT*5fB^mxD%S%!!wxG3y*zjJ%nPvr-~33m`8a6m)?y)R3IhYUVOHUm^(BTYB6K8h_V zx%YAR%|_V7Vu*Ui(oEH(9_-{r34Y-A$GPE(jN!ZzAYRILwUffnIz^kNUkCNqW_b!^ z0STByAWfxcfmv^0wX=00Rbe8M5>9~y-++QmRLxja_J+SxzF~5qMjfamKZaI7XCf8u z@IgJ5)r#o-gWF2}9o|U|dPfP>-u#c}wwARF9^;CrZ!$nlQnW%mgH(%NWPv+{GbPQm zxhE-Z>?!ZFhnkYKmi$LS=COuR*nrM2w|NkCdyHp+FO`?*l?OART_gq#j9 z*iqA@%y>P~s|WjQn0%%)D$-|fFX{nkjyrlJhp%!_Bgc7X;$4yz#%Iqp2keeI7A zT_J78cwVJW+d*u4Hc|jMj#Lj+q9z=z06Y2sK&8gk4_X>+ zcrL95PaXwUC@??bFWE9^gA*scq0=gw0Oro1=pE}-*FjC)1^p}xTG`&Plad)Z&+s^o zl&ek+Ry$57!;d%(OntEZxGjyyaX|QKVdAP2qHVPTz z7hLiucozZ|s^?_@-gt?Pv`<6FqDIbQs~^Xp^{oK0KH~c0+2z&wThQfuUyhDO&y@MU zUy(C%$<8h>-(EiVNv???+%Ooz!*lr#3|uf9M}cKDi}9@9lfge0JSDu7ESjMkrN}<; z6qJO#$$8QZVWgJ<$IMX5P0dqe{MojcD`pBUTZO6q%nMMe6Hq3RduDtdt&>8>70@EX z4YA6Eh;a*sJ+hDIEU{9Uql#PMKCYgwf2g|}Z47PL~7P6)9i6~pUo{+ZINj8lVZ;JJ;U4KYBCW;dc4O_^E zjP207xxI=tI5TZ(@49GOmdEwd$i|MR#)m69%&eQl*ost#?xswL)EB#YPxAXDz5@0oM~N^#X8#u3GA8RrcsAQ(YkLSa8Saj+mt>{OGWym#G=E-QAUFSgq>o;XRfUxt%pE54fau{1?2~!vHSow(S-99EsUYvLTAbd(xYb@%skJQ)mZDN zF^>Y#R?kjqjPReo8DF1WU0*eX)opD04Q8;6^2zXqq(_7Gs~6L59u^??)d+LB(6*)= z$&8)7@zvSok7t)RJ^10?4sOy6#$plAi$1ju#L-2FqPlT2@*X#a7N)|MSG=e)Mwl1B zTSa-aREbb>vUXlnO)gZK$yvu`_gOq^WU>a51URjh4T525yIJiLhqyvEv=X%lAd1k2c{8(IsqYYuS1E@RbA2p(nA2%|3k)?O1 z3Z=eSPr!5`KtuLyFocx}c;%Y|M`9DBJ6lLIXe?GqEZL#PzYmPTqv--qINdW68cb7^ zL!OG%tZmBrQ%_PexB8%nOSh{9=wpU(3Xd9sNx;p&)DqPlwoE-z1JhDfMh(OwJ+&INk9Z>|+rr$g14J)U1pZ4$P z>}YW7XZzH*^qj@`vGU_FHcz3CZhQLy;NK3+)lEzWhpv% zID&9DkAPdvwD3SHtM7S*?sW;UjcyzVA(W4|N`>sW0#5KwUZY^Uy%9nf^>)cfBuvW4 zTzyJFtC*z${ZJmE=bxfd;yVXv@XTmANE6V#;2hoOAEV_e`FB4~9ZmDmrzuZXPd+}? z5hml)9yF7Z;KYe_EL*af4~Oh)sZppn`bp5D+>;M&rDq6Aj|1xKLEvz)OkD|q3|;)Q z&TuVJ94o&HH6MZ?0@OYWKLXRQ8&?Bo``qD*=?(Q6Y_FGA~m^h_r#m7H z7fM^jh(p1a(F18Tlu}N&Kh+6K`V}mTD0mdeIJUI2Fm_EUTKm-e33T>H#bP{*^Cr}q z)pz_faIgdEUJya4cgL%Ao}9Y9yR%7-$fLovS~m}f`8${n9!cO3SCa{5j)Ac zYt$P}-~@lf(laLTSCpP&e+-puZp12&-5)0CaEEsT+C|nKXnhbm}_sPLn5K-f7l)qr;%xK}_49 zPcO2aX&9Q+i0V%B>O?Ub?o)|t`?HISbm9Cl zB(9t^CYf9q4%i2#=43NDW_JlOs2p~j_0f@8N+|^P3z3M->U)Wet?;z8fmF znZ4f9)Vju-0td~5b+@;_)O1Dw`%ju+Sh4!DJDHEPmZT=U9Xj>-x-LTgzVD#v$;^;2 z79fqTNGZTGPNk5jSU{#KScxItRm9v)tmbfpx3s=sB8dd1Vf5b* z@rU>C-wy{>Nw=rVRGqL@&hJ#BM{qCq4*GvOK7s##2C&`_-mA}G_>1{%c+eXL`+6d@ z(x%bPW-4h3wg<;q!Sl3M-l*qVoSF6wnyKm1B*^g7oOe=_bK*yq^-Y}{Judl8qlw6p zb-@D{eY*?4L&bOI!cM0RU|;X?-9&y8K?h-{FG_Ti1vS?#noprFG$^9U7N%a{Zc8UZ z)EHooh_Mn<{BQ3vv87$5`gF3ZI>vEZCusocV1sAwNSs>C9SV6ezcZ|%?B3KfJP-Qb z*?-V9w@(?bwh(@jd(8P3)+N1YNo$nb3FS5ix$BE727}wDLcs5WZoBG^WtMG}%L+Dv zyyNpMnem+5kd&AI?-D4l$?*%s%Bdl8T(lj&ew`Zn&x6{ zmRSbtY~mqpJEmI}fOAPZcqzpd@9OsQ4T%Z-Vs#H~41eju6$dL-W?2S0q{Z3VWf8Zf zr>l%^J3(FjG~=KmEb%geycY5D;vAW_Ha#5~9#1!jP5 z(sIiPj&*;VZb`Iod|yrEL|uMpNO*5ebq^%DH&)6Evw?ylKk6#-c**lSaqK z6^qqiRu)od8G?nC<|bGPx+qk6z9lI^s%l{A5W>?v)>u~!PUpbD<)FL;)f*2C4>Mdt zJU&X0egYOP;Z_OKhLIXl1Z#G*mBU*jx}LTprBeI)b@d z%}H6KMpn>~=_}B_pqwU|;MT*chUCJobq7%KKkJwWfuqKz`E$HT+QRpL&DOGr zI!Py>UBR#%KI);0YH((k^~J4gY5!XpvKHfPdqT+sJo~?P@eg(6U?Nx&%TqY;I8NiD zN#YKxM~)4}*B+cphaMW&%JwgZDZK$<#Ltx1!jcNcj}h*1Ufw4tJ2{sO25#+Pyy-}M zPxdvd}F^~iUw8p}HtFE^ zQSOnrq=oMaue+nKP6hAn4OB~i{OauW=?@pzV-hXntFs@w*+xFFI;7f_+<*tYc^=jG zKDaaa>GbkV_lZ=Y)nisW8IN&H2(HyavBPz}In23tYhz&NwlvrjZsnv(e^FO-TJf$r z9B>#>Il?VbsjgpDYUer!Uz45U4At*Z-DnKn*#PQw^HSbnWj-)&GgM4f@iq$mr%|Fa z0`O#w3vwUGR#;Qf2DhYr3hHMh)q1pmQ)xG&&N$)I2#Z*6xKvXCR!op&wMKw9v!Q`% z8@cZd@Y&qE6V`nF|1d}d_a;0Y&{P~&#_Rh5f)87GuI9OOEv^xUWX;AV>MS%(ydsO{ zoe&`hqD(N<1t3kfhpM~*T;Mx0-ed)r<@Bj?hjB4rRxJ>pDr?Fddr+W~B3_v&zIg#l zBu9kB~q9_w3Bg;9WV)nBBSDll_KSh;7BtO@(LZj;jn*5BW7Al3H!~?f!fL%Ui zwM^fcDSboMGO2mfms3-8Q2$CwV_fx#VoerjwJm00*Oxz>A=|5kf=5`*6I-Yil(jm< zHZ$s@`L;&A7&lp>ceoh%m?;;pKS8Rq3KP_&3rR16*(KSX##60hk<~bWeUP#S&|lDc zMTLl}z)W+jQKG4*WHzcrp=5~?Ni?~F2m@A;f={61 zNT@c5I3)u@7BElZ4;*7||NUPVIzQu7?RPn7??|{ZkWM}#17T9c4>6Um^O%v^N}XG!Lq?KwqD8Pnvw=umy^uy zt3;kG59mfO(NfIy+dIf@RQgb%d!`(<=12b^BJUfjI#h>`SjH>vi$@XOFl-J!m7`u; z#n4E9(7x}-m)xp)&&xbN>fjzWc0OW_Ahq1uGXR7s7j@skH6WQk($-P!47ukmzos+5Ji%l0un zO?ZS6$Z$1ZJB74Qj|bL|u3O9Y7?%qs)4hdc7D`rAE$Dizb(OIkG_LsgYnG-t7+_uH zEaMjqE_y2`t%?A4Bs{Mg9Q>5DWYv{*gE{sS7gTM|khSh^mvDxOmm^XxxBJayf5iYd zH8ltW7Ov{yip7dBs5coS%L3Wx*FmZ4w#u#|KfAT>Tk=K>oop%BMaZ@0d(;POJPFt6 zNe?)VwPmgLoRuW)>_2^txs2u(1k`<#oM|S5;2-#d&=;7kW&%&E@@MmVHW|}v_uLwS zNhFMy-U}(wvzK_;8NYeY2)=%3YRy%UQNP^i`s%&$c-*tbx8H9v+QoG(SK0ibxJ5Xl zO2F2ON17+v{l@nmFkRu?DIa4Bc|kA0#@BcCd+*<4WNS=0?*t-rK)95x4Mq7YAcwy> z^fS2wHj8da{yqmz{bl(JbTOPDjhuj6AiM-kV8@S14D|hATV?H>;bjSql7Ha4;*6Ri z8U~yqGmnaXZ(ou<;i*eZ3-ACl6#c|bAGeyPB|QRj>$obWskKcG1K@0yw0{p~Vlf7^ z)8mbLBlGQ<{HBvF<&R(7QpV-}mxG#gEQ6k1{;MoPhr7brJJm&3jeQ|mFZ%T>?bhfz zA;SZmb0}!F+fZK#YktjZhdjM9KpN0RJG|zVUfCEhdhk6sEk!(OaQVudN{qHC+F|-# zRl8Mf5Iwuc(VB*N8hLF@JsL}XrDxBXJQ;8H(@i2GzPgWZ;meG{DRpx~*39i~VE1d5 zXV7?G-K#y8|Gu~_f0N}Pj!Q3%^H6v28jMDv_rwH7RB7hNmajp=FVpak&7bl~nVf#C zW6dvG=VxxU9P7U%Fz*VE_q1{+#(Lg5zp^e3u7orz32IrODEvUy`oU*TbI|45r>QTj z9qYg3L{ur4WBIR|y1r|0tp94Clyx)gxcpnfQx|rQb<7!lJx1Pn(aH_g4~B#l0hKGE zj|rAG?FOtB=6-6!e3g;OE1fgC_CLVIYGqRy$6$daKMb9m-Z&e39Fh)fk`;?`6nc%l zbnNwEcTXO)QQ85x6K}Y{Af%PtlBM{rH1e*2V5eGMtpJ4$@Cu_7Wg#3vW<%cdDihXK|8*)m@LD^V`8xcV&!XKZ&oy3}+5p<)pbG2?B@12+LE-Z3HIUjS@J(?l*YG-r|96 zBEQ)(hV2`A&73#nJ|#Rdn;H~!q@PvnrUMjRRnDO){bC)ct#Fi}QJ=RdrGPCn`>Mo& zl@u29^2S6vY$G1=8yZUHwK|G>lD(;v71h&M^zFbM=5WPt_1t0dz5rvD3KqOs(LSKk@8mbRLDh@WDg7A3mAgZ> z`*BJC&`d<}kZ}4Y?svB&*6zmoq^jfcS#rRh653xgIwF3{I*KX*iWF1a3?;c;$>#@ zn2Hr$AxqtvBKh5O4*d(>Uq^xJ}@yMUaE`T@@bwp-1SgW8s)MWiJF9;=igB>l@^l$ZZa^$Dncl^Qgre|y$p(2~PfB>xlbxYq#w zH*CeNY=HkUYW@w4n*IGW+ouM|Ag^B;5RUtxnhRgpvn6aOa_Nj&0ydrG8IXXH0&mjD-)Mu@74Yl;!d z%1R_iW!G&NLJ2u!94+NAm(Qd|(~U`h4p{IGYw%A|f=lhQNek|BGCoZc4(0543h}2( z0K&J|l@R2|BqUVFsN9@!x?{-i(2w`Yg?p1#Xyjd#4y<`N4(J7!WjeO5-aLi5ouDY*b96fbr0J=PnB7CKb<&H*wyft`Xo zt>UxOo?_>J0PT~(PQx$|MDO{EIYK4k zfS^TH1*L!hsYMn2fXZ=~Bx-60dqW!#|Be$v54j=44WH~C&$GQFk1mU}2t=g%T1+_YAq82x+gZOEIBpSi@39tV3CsD8nePEaqV>MUdrq( z)WjDZ$4pvq8HdVjL~~3oV<$Q<6LD^0v60SqQ8WleA@3NI z#SNxk>lUxqXhx0q^n#=feRlQbMccV9-8)6_*WvyL`J*7e{{iqsIY~#ueZQ8iHvVPe zDwoc6Tfe;Bhfg~uy>i%Bg7+Z!5W*MHc!N*veQS3UNs{PyenmCMcVvT*O*5~BHZ#VE zY2P)r*A~s)100>QRJLo8sx(z4jCXo|*M8q$b~7UK{iug5({v9tXBtbYjEs!Tj8{fP z{_vN@)#Bdvg9rDb2hm=1^5e;PKc6ONS$c7i6ysOvEQ#{-|4JrRR3wWcDU+-!qZnR{ z%6wT&lIQ~7iL+@`T_sVKe@wCxfW>8*Ptv$brqOj;T}5d%U|+*8(DqYOlxdztf8gK! zb;91f%!``{e#UPW@#JHCnM9F|75*A8tE;?VKSqBmlFR7qDk-k>d>Z|5S@J*sTK;{R z{`VkDs^?aV*Ksk4UQZ6P>ZVAdALjE(ihtTICi&u~NH4Fd==+_WKR)_?=kf2OGk7IB zscxdfY8q|sy*P^g^rvX&&%clU_@|xdk2^bC*mRao7##rltEyU*Pq()(84;G}gGoN$ z#%^ZudAV(kZ2NqcpKs6OvSNQDh)FW2K3CC;vzO5!edge^j}blqo5v(NK{t+#0@DDlJj^AQf>AY%lWBl67Dtam>!laH zz6TnAO|$~w8V0;g14q(F9(IvgQ1ot&!`iB-7xeWi-oy ztxOf#v*kSN322YMx1rGs5hp&vWRHl@_#Rid>%cP)SD%r zl37m<>U*OpbUaNKY!k(59Qul2Oo{C!_Mc3fjcJOzp$G72;sv~z4Wq20{DN9W^5qW0 zS>z?b2k@{u7%i^iD%AFSoT{BZwgp7l|E4t);d_4>H)`f_P$oX4ANs z@_}5W$!uEo6?UcAyT;b7asW3?7?+>xYb;3%K1=7xCG2-(U5tk{?{922mi^*Fc=G4I zxwFJP!fK%9&R;j7;FJ|&bN~Kv2ntRkE^&Q&EsSP)sbKwSrxq3)std_CQzISuzG^|M zt&kFmFL}fvN`S+P>44P-khE#h81+e9Furw_lx&GQ%K$m`LVJUTvN;+bpA3)2Cwr&E zqtTDUvx76lV>I4BJU$!h-)}`%F`HZfRwPW|fLP}%imd<`1Be)C45-83T6g^@&tQST z*Tnt%LK=~%ls_>@NZ(}8xO_DDa{6Hf{l4#eLrf~Hj-8qfb(YVCmVlDKOnCg!15?% z$MLMpS=&#EpprXQBsKis9VA;IQ>J$@1dsBH!J6ss5LOH_8y8b%`l#86LFlM1OSZ1z z$GBjeoGAwBMAKoQYXEhz%!q?cSU)8W!(C^bdt$eYq}a0@9_wSqm>-*e)XJ8h(^(ob zof;=w4&@811`EbD@e_dYq-MRiI*@Ozh#3XC86yJ_y)0qM^K`7e-(&nWWq?zy0Wm;m zFiS2f13E*Jbbfb>OF8Hxp|@u#j+^A{V-%W?|Iql}V|?%T4etfS+wgNmJl0`qmI};P zF}z6H8BH!#QKs zNg@<44vBCCqXvMW=^^O;&06eaEec~hicXVR5|_zSNv|>g?XR~qDHHXf#ISHR(_E1^!2d1)Dws3?+MI^Yllpuc{KnZ{HV$nfy1ZTxppq@Ngo zXk&~JccWhKnHP)U@nJN%ii>zsfsqM4VGG8v%hsJO&l&NfjU=D#Gf*|X*_(_T+n|#a zjB%4)$xtYknYVL?@E$DKWK9?oV>Z!j=Evey`dRhO2+zA`1OE&dpq1+%ygR+016W*O zA9YyZ?oa<)>MK%2%1Q8|KxljWR1oi=-F_r~(Tl=EpTrZ@*_% zUNGFqHprtAWISjFfc1o_KGo({#4O3;2F(XA)@kM^6~lwLD?@juhE64SK+NNX4WFq) zi7@06dpIOyr?kr1m!xBhT`v4a1ZYv@)8zz3i0y9}a5=@`B@7Icz3l57)q-3^1jcHL zI&mgM7kjtN3EQ;lmCO_zvaXR49v}UYySJd=}`J#yJ#oR~5^|?RgJWHKE;t@2V80;AMuK zgl#a3L@j7zqr!n5BK(GFs`4tHX-v;p@a-6uxp4P^?bY!tv%fY}5BJDhckGkKxGlRz zro(kykcwTgU~S^_SyF?=o@UgPxa3jMCMN>2TrOZ38Iq7V---wJS4+;LOBBqoJfaEoOFXk;ORwc zBu1l1EDr$a3?ZqOMJ8RkY*uI=MauHP9-0w*;R8;{g>sc&M|gh2Mgjso|9A_$M(Mns%jifI z%UQyG?LbBRm{fz$^I2fd80kL6vn6u=5*-aLhg63OTwzY7%_{)H8P}Ylz~(8LFRGh9 zxg+9=7Bbh6I6BcZXGp@d=1g@f(rF@~#F=nQMAPIVUd}4M5Lhb!RU^nODl*M%0xHjj z=u;=4O~L&RN3WjGJdWCG&>Z-`E zU2nkf^CVfIgY$sad68Vg3>J!4!tQ8~0Bj?{SvlDU=3XFsM>{hgGp4$q&*w}gfUZdIY-*!S zFQUzqiH&Mg!Fbmznfy4zSc9_nVJq6*C2d!>g6DU?i-Jv}@9Y-(6d=ZyGJO%x%H)~x z3KRKwSY%*UB#XSLpo_Q!An*x%u^aiaS}ZHO8{QSXwU3&QA`gAbHXWllQ&;lhW|P0U z^~`|*WMW)tkrdU?+j!D+ES1l*g#@qm=ZhI5Cz zjZpca7fN|zzDOqN1sfEp*ET8Mg1Y4#Mr7#k0#2Co2oKFeMF5$;!_;GP#tEMNAWE6S zmVIL1(Oe5}50^H&9TJ#ie_)a1#yHzL3F7ILkF>oQ!$$%^()m>*W+iT!+k;3DDUTgS z@RU4!g+shf%PaUUUkN4FZsqmLsDZvRxsDph*%vaF2Ij2h3FoBX=EJ`?WmAoHD)udo zfJ+Y1=3<%*vSsc&YVkqir(PBxYNspRdIO8YwZPyV4SQuwM0;I}uyL}m<9xuGJ`Wo> zP3Fv!F*pG#yh=Bh`mfrl{=L8AmMahg+0Czi-<4IqSi|Ncx|kCf(pjC2Xe+&%&wlIc z-jQI`q?xUSSle!ywcBzb<-$i>@8&pPrn9M97v!21YCT)Lj2KH5`&EJa13V0~BrZH2 zo%U0IQ6%M+fuHbdJIVpqN*DQJ3DLE7qdL2UKf4wvwipl!IpFI+XpSfC$W9X3KMD_- zfh?t?f7BoA3Cq#-pjgxt!*MCdL5NY&;x-4NH+Gd!iVszhzC0{Co>2%}GMkm!dLdtw zIug5p0H_A-l*izfB4&<0fU6@e$^^rwkKP;}_C-J-1?&>2&;tQ6F~&Oz){Zu9dBYHO zPtjT{w?K?diSRBgh>$+ZPZGrPb0n>JPrBh7-qTJOBJ#2aAZdPh`;CC79-gYWv8_;Q zq+$jzjQc6Xgib0jn1|UEkIHnfL0?U$&Y7Y~Tmf?p`&%{~PRYS)0qYwHZrs;QKaMXG zI6;L8VCLlkXx>>o8@#lU>sh)D&9uWa;o06Mrw>~?X{o|y(~OzUeF**m&L87CLbK@_ zgZ=LJZhswgj}EM#zT72pj44GrzLToE=KH#$TNVRf#&i15Q-~DK(A3gpPNwc1V za?h*dvGsD2OE(UKx5!H!q`9m-?t~3V;Yj+QT+AN-sn3SYJ9`9JZuwxzaT7KU7zyGb zpvwB)wD9vnH7KnRZcthErpVeheS1ZBbUk{G90z>dgqQBuf*Hg8bo_F7c69LS)$nxu z)A01g@!7%XKcnZ-_xAK8ldC+s|Gs+gfU)(_-svbB9sm3AC^|Vk-XETw9UT2FVn5v< z0MOy_p?8yPAVY^O?E0lP_8AS1SQWfY?^J<2ypZ%+ZOLcLijmO*rXRi^2ca-(= z0e9GlP37y?!=n*;zG++PQ5s55emi+4rM<1E$Yhrkk-pX76l$gc8y;0MbWfgVus zP9TqYKOa7{Ax7t6!-j7&ZZRNn9({e4&q&khNB^~C0s~Cms$$=P+FU=#CVj=%rb%}R z_T$xKYI^YKG`_c8{l@pUtpkW>wHaelBD+k^=mfOYVnv=VKkjzf6;@{fYKVm`JK$o^ z?SSL*FnY2R0=7W?UtybkUd$Lz+U!NWzU(U082y$f0)p0f0F4p!yPXfA)`H{9(+LHR zwHowz_|&*J(0_RhznEWr&%VNUd$sF_3#5_@q!WIov1uYA5r6za{`tLc4BWg*FYfuj zb!CFXH0!)*D{-Y(u7}Q=1)&A8r4gChgbZd=eh6!2wD!kEvY5q_#L~Rj>VKcXDzR5> z-~@_6s`BN6&6v;@VF<@(sKh?mqK(;m%M{|^#`L3w3;q84ohMJ;J=uBoc>cftgMaVL z?<-@+H~aUTuY>~jzB&;xo#+aXs>M@IMbI!fWRE%)m@!LZ_zpFOgQLTPqv80+(d$F+ zr0MFMyJ9+ff<^CZ@qjtXSg<$L&&01U<0=kmM}F*ui|3sIgF%PwE(ha1bc6@&tBw%a zCX$oxz^sw>Xi-wk4VadKT`)6L&sOyddOyuQbmx7&jz1<5cm2s;OSZ#u;SiEx<-X?E z2|9q(dF4`z>C+zRpY@aKnTwk?k!BN#4{P_1Pl*xw-n1-NArlW2k=A=O2UiE=Ka;JV zFNG}tKZBowNs#hmx-bk64dB}=j6uSndZ0T|oO1Ih`yFC9DZ>-t`G9Q7=qA<-YZ9cN z*pS(zO!KT)!Qt@|Bh>}?w2HJCeeF@Z&?GjEiN_jnOoE)1{|>Q^|6rn-e;oAwnFb^> z#S|o$W2EM$Xwf%pZ<@`=phlBBF+$(+ZnSAlQ1nQfzrb{bQa z3o~pZc_`K$`omp~TAn@PkQ39TH#gOHTm9(wwX6Q+@zIc?DkPXPfxP=Npg08v7mPyb zSsR6`@0=^%3w*7+p6K}5n`%+xCvub@BddY*os2X^`lb1pk}!CO4KL;JSS-Kjyje)x zcIGT_#@vbD+RUEe9a8frL9A^C?MVoF`U7mB`@A@Axqy4kam9Jwa}K%6D^U5MZbDSW zmvmB_GwuF-St(_fQYR+h&}Qrj(v5W}7Kpy)e-vgkriYwER6MdOut9YQzzMS)YA9UF zS9x!P=q$$*Nle#Z|CtGwZCobSsh4KK25E`Nj$)+FCM2@EsW&^Q( zYS@L=yf(avs&6rwag<|4GOSVs$AlMD21LuG#gX}@A)^`|`87{B#UsRw=@g7WOz&r4 z2V?~z6rR*U1;1=?Fq?pe%;!M3lt=1O|9t1IFd+Ao^(Y5=zk)&8^zt5h-Rh)jc=WRE zIhEa%4!N*Lz47Vr<2cZH#vxHdr4WXTxpRnHWeIy_KR^m!le@oekh*_iJ6NOX`)VO`D`Bnrv_ z6QhVeW~icyl;osj>!qYjZ3y1s3U8V*8>&#{mLhMw9fm+-okFlK;>pL7P52e)TJjf6 zuS%|QFi>U5!jOU;lPRy&!UzpZ85;6NCAI<;9a3u8uApka*^Sty$`pkG`~wvH8T0S;{9%}(R?fj|$M*N%XZPiCZKrkxwkrbd z^hgY~#$k*#VHU~?lj7N3u+K&WOm8bXW$hK)4{k*7(DrAOaBUSM>f(zJU1d<_~m z7A3R`6xb<1U!AUQls{>gY)`|Upg`ayMX;`?q?Tc#K^lr~sd<9Zt!VTP#(+oDH#Kyf zH`|lztCyzWyybqbB*i+o?-~DiU%b!YkoJA%28pKS7z_)DY2zvQZ9Py!swU6t^g`2T zG;zv2rc7<<8p_B|b0j;7p$QL8fx0bIIq4ps5zeeP4_{6$XOy;|D9DDmyN`_$uov^# zD}2#zIDeu+qldeeIBMm^%PN0F3(Algfs^W$Nq}UiW1Slq^nZxQJkbSIfDwbW-9%X5 zR{PNsh$@4F2LejK{pitSpT|=+VMGP#?p`;py)?8OFvofY2BtbyEz zU30&Yo?1MzX!~7FClK@kQL~)?FjZEta7|lN;pmwsT7rQ%De`l+V{e#PV0!2yTtc*n z%N#0)F6Rl`?4UBIplv`Dh7SyQZ6Q))j*$<*uFG_qh)~}m5za25hiCZpYD1(arpT4! za7?e8D`LEEN;umo)m0o=5(@*d&8h<80tau}pIN?$^Q|aS6&a&Br9jz=K+1!DRj$HF z=IzNk_Og_}xN>BIFAdi*4JTCS^yRLy@6};+&68R=hI0 zvr&Y@rG(A?1`kD#qWw72MkY$^(b*2C*_|esZX{<)hu*(Z1wk+f^l8wrr(JCCh}IBghxQr}5abwD=7t#t+^-uRvJ# zitIgLqNpxv8uFW1bpMviDMZwWm;_-IB5HlnQJ)CjCo1<9Rr`{bTPCwnclOlq7EW#8}tDW;n2~htY`9-36-=&JV>4cyHg>&6j02(hDW%zYdloF9uspu|fK@ zW;xx}8ZiM8udf2})fvAz!{RhSMzdBvvj$yeWmV=D93=Rx4DvRL%W(!eb&dLh>-tu_ z#Nin&#rNZyT|}-1ztrYK`a-h1yXbD(NCIGk(EgHpsh!Bag~a|X>?h8@ogL-M=r6LT zf--7_ePs@_NKrhWIN zx7{mRa9_p@clOZ5E8X~aE~mfJ&Hv>LXD zGUc;PAB>Wj{_U}ngZ(z9s070O0uev2#}9GU(W3q4pZ~i2^G;Oq8l1xjS#2o@B*=@8 z5!|j$i-o545<Idg7~7pmIO&V@SY#6+@F`R)DzCp_nH8jPvy953S=T1d!e`gILPUSNFyaG%%(I zKX_sSkfUG`6@TGB1!Tb90ou3=q4xOItvSIL8&y4kNIp85$0T12D8A37+kJDL8==|! zx`}rR!4IM|P0j5MjcsY;@cw(Uy=VWN#CUrjToDS1D!HL3QOrhRu7(<0x*HGKa`u@P zNT^?hfnd)B>+}W|LKqa*jyR`Fyr(%T+L>`HR$R((Up9$YgX}V=>u+pejMZMH)2Y(Q z`Sle5@>*V#Vp7B^?)J~X;^DPNkZIwS$0}LKCmmX^8qvB}7soHV*sWbf3YLG4%G$}$ zdpY^>WdCgZa`x>?p9S98ZS^VD<8Nq-uJu%GFs^)(&!vC(R7_NZ0P$&=;eOASuG@BTbJioL92uIJhz15|!zl4GF3uFyg6axIh;V`;?6z(|IGf?a;h#Fe z=u#B=aX`@xIC7k~ZRQ!&d;glBkC}o$#$;u?XoW}_A3jw(Ntf(_+g1ok=8eTDp?BGrBAPXzfbkfY;+pl4Y&Fxs!ewchcLv)1$85 zBzpyX^Cx}tC)soJEAuDml?K0dkCL}yWTQ{XuF2Tet7NtN75J4z7hl}7#5-Qax1^+X z7w=O0l@MM9-8@WI`z}7FP}7!Prcm=${Y>leG_A|mv?g!UTKrAFW{=a`FXwS;5wNs^ zB{;5?~{bYes=hJpn7tK>=2?}g_-P>G8sDCC0SP^3Sm5lkz0h;xH1z<7;dH}&8) z>Z#9>@zwk=c^19T7zh2)hF955y0e%bB3I&OUWq#ijEKk*iYme1l{3)OzL{$fHYp}H z)!qprFm8>1wbfOc0m%soT}cr3ceL&UC5wdLLYWM*3u7ra+#Z}Q=jY5|1~Y;*!y-<7 zMTK~0sVwmmyg7I%&q|wa4_2qD&JDr_kd_0G#{I2_@K#gLn+Bn)^3E_UKrIJSF0o=x z;&Ry)#&Sl$T8*XD-gU-e0ctrGBYmdaUf&$O(yX7Rap{(lGcF5I?YP8^=Du4NoI$j@ zXZt|AhoNa0`kf8VFf2f|!!Wiwd3`lMne75uZD3?*wqgP9U}WRkVOWdljt0W_aN|$} zHX$a^I2lfc+wgs{}P^I(Y<~seT~dLw}im0?&TVMkC7c+auxE+n@96$*4INYK>>J%`L2< zkM;B8XqF=a6k?I-Eq{A+25%Rw6{qx`rGecsR=i z+%`)VOo25pyDogYuAg1$mf%`-ZaH?lP=M4e)h1)4#bTDEVmax5x_cV9RsthQ-A z+Ium6d+>7fqpwORl?NVkY(@+jek-J18rUrgtf{F23hpi}%lSH9v<76fK8fM-zpJE7 z%cG=(rLi)ovq`>4+O+mJKZFCCPR-$#LXHSA-Lvhw*Q2qG+_vID48=?qK`a!$g*E%h7?&9X{;X>Z( zeuK9FD}rnF2KhGN3zh(Rf+jQ~KE!&}NCmz3wyp#?+kk4ZwDhJ%4Os^C(v%_|R1o9c z2+zB4rTLvi_kZ4eUv2$--|xCH3Fm#~(PRJjC#S=|jn7UF4@Tpc!^4BuaQ zfDybL8lLdguxxyUL}RPR zV_a~)Ks7iKWo=~7!VN_2OR6+UJw69S3Z@=m9Ut)gosD(bIH^AECicZe){g-L<2%cy=}F24K0Wi~UOY zdY9mg>>nPV4V$I}vQbhr%OMRY<u#r{O}ooWb(9{y%uo-qU<4;E(N#O>1;+XMMJUpqqQO0PgQT zk6vN)2z4qP1`*%zF*E7YKx{HRuKIS)?BwQyV; z6bR3s=yIhwY@CHw^VkTb&0I<#YCf@9*Xe}Eqmg%*WD<8x`%BASF^SY-W__Z_1k!>V za=P4tp9%=8^HK+gw%t1rEKd9{u*~0AA;v|tpp}ja6erggSoJM<8(;LsVAYxrIXZ$I zQ7oN07@anff!McwA3tUM} z0>3bdpKG_FhXb2ns_F3@nRGw22x!SZL$SsS4#|xv`5c>|7;SwFPLpkHtZmddy~_-X zT8y=xi3c-KK9i%Z)!;K$oBa&X>$^sZeDJn~r-qyYi4KmX&cj+|ngx``Y1T9am}b9M z>5Huc56OPvm1%r(VjzNt`Zav2R)U}sD31Ddu>q@;e*Gpart-To!OUQ&Yq2a!70|ua zMV!c1UpykWlC|z$#xZ7D*uvr2x$F8P?=_vc-$1y*)Vc zSHu#~&1xFv+SdaU+6c!L&g{3NeaKaS6#;X~ugbwYXtIjmvr|%HO$@hu(^eQb)XyG>!Fp zvJ#QQ()sO4Ly5DKFT zw$PZp$e$=7BRw`!YZYU`_I)70Rs2b1RZvzw43J>?OUZ?FPcggT>jx~M?2G)arrewK z>U#>qXbVee-P+~#57{Pase=>ZBahZ9mYuV6IxEJVl;REw@w%1a`iR9Zq6Dv30ru#o z{xb(+;2sFXdryQ$fg6mit9SQnqQ+W;j1gFR`KdVM@xToD2!$Z_WUiY%a3LgEN4p-V z>4&FLTQeXO6SE!tloU5~acn%JGe+32OmP9x&5NqCg$_j}I5W*4^?90HU{LRM3c71$ zL)ExdIf#aX%RwK>!ZzRIXVK&6FYHhDpU2Tt*pE-`uu)>0q(DhLShtj-4h5kzs%Z`J zYc!uwy&`ieC4WqAuJdBrM;6N86!q}aY?3oGeo`^@C@xDj0i>K_2YSb@HNUAOB8A?u z*MI&wvcDZ3o(;FqD=JteUvyL(FcimkHhg`se|&g+bhmcDCXVaO|Bl;HEl+i9p3Kup zKFeX@KsJ^s_VC0{;6iq7p9$o2hIid{F=|B#0Xv%2l@B%(a6qy72?qzYISPl>(CF-O zG$`nTaq48s*8++bA95W;I@|Xk(4`O!Iq*Y^P2*&0*=md26Od4o^nh1@#3lKS@#+W> zg9ioAQK`Wi^;AV#FS_Hx$}cW3S`}2a^kahA1hb^-m0V?u(m*c39UQFJ?g!bd_kdZu zSz2B}I)td|tr=+1gI?32cfdu01Ag?#-zuEU?Tagxu?lXuw=v7!uFMtkU1){49-aCn zqg3SBiXJE_{h0?5;3~q(9Ohe4UO$=5{L6uC558uoVgf;9!hkLsK*0zl&L>v@ia0wg zJo<}qfAViILYL_@VH-HqQ7mBR7bG^YdQ)17OV+deF4pX-ydR$1tap$B2V$LPdG=_s zoE5^W!3p8v|J@@$>eS*jP>!C}=(j=R^w}?WO?obVb!u;d?^t29wG#QgU(1pdRx#4P z(0YJbnP37*xHD!qec^Vgg9}`j^GtHg2*4?`7z8Z(sV1W@l>kaW zwZFa-)0+~W4WZ@L%~~L;AxP>5Plq+~HyNlM){?}VDL^D(&&q*})<(Qw`v78Vy&+s z%f5n3YLt|MZl#T-Dq;B{GyK4Jhkm25bQ78DSeyt&P+HqD0)uCYhp z4Xazp;q@3WdSrW7R(cC&gdGG2{FsIlgsVAx(VMwp>)da;nYP>Dt6^A@sEacSUUU(K zSuHErJ+K3_UKIjlyHe4r5SQ^lsiEfyv1JeiTyy5SU9Ii<4TR94sD{Iu*Olg z5&Ql6ENUS#HED_B5oTybdzyRr#T?ZpO~6x^IME_*5}sOaklL1m3A)qR+BpLZPo`Rk zL7TrNu{^%eF0O#LiD2K+O;UMyHL!VcICi0ngb+l7z0r-J`Z*l3VWtf%OIghf?VqS~W{|G)2*in7GzSKU!9`23yO@VBH)$yE2r6`mUB zVx`@Nv9#Bag!9(xLTjDJKAXA+)WNr9{D{AbWzEn!hm>KXy09{Qp&_(P0SSkf;XAb< zW`uwEw@n_K1E-GJt|G1|D=t$LD(0~XqJBap=2A|*FAUs%j6;{t_Ib-sd#49` zFAm-M!}cRj8hucXU;N+UJ}&apz0vV$EwDD_M{gyE^=Czy?0^8xWtD?8{b?wa3J+(R zjU`w8oX~zeX{mlFHNQe=bBFHrlib>>zNBT7?ks{PFtAodbdVcBu69oIuhbfc(cFqGFOGg*qDI9n%=$X*dF) zYf>(gitd^K|45(Y$aNyZ!DA!U+P7adfUy-h&S)mi64HyU0qjYLyuxeY!MkDK3U7fE zZgJST8Wwd2G3~NRYtKa%Q;7Li(XKp_9!r~|uRgBmyqgheqNP>U9x7af1_RQ1P6q;v zGEeBfvnalfZ}76MCi2MeuD(JCFX`$|I~na<%k_7ygTxv-`y!<6=hmY579v=h#=_60 zPfHuo>zWq+ZvzHL6K^#1dEHj1i~1zV$2TwBq*Yx}an`s}chXbXwId(g#lfHrKgaXM z3?k3@{bJx7GU8H7%3jfR$TCW*i5J{kal)4yu_|(7nJ8wm-YVki1E_L|wC9)bt#{Vo zye@UGhNdr-CdXr!xVjEObW&Ux=TDZ31$N^FWHoU<=6V?znCqm6*Sl2K8C1%6*fN_z z{Ij^cE3L%!Or;N!vQ{_KjQc$?`1cz8{1qVbF-aEDEYIPduC0g{4}s7S%{g>axMGMvDmA?UH1ol=>+RQ7Y8 zhQQNP9!5{x083*rbTXQSb#5yy-RdRP2ZtCwlOml|En`7$Eiia2)M|P;0w58+>z|oN znjmc>e{LbVK+!+L-N+ZXPscZzJnc?C0{m}-4FFF-%r$vH)-+SAPt-c-dpF0(NWZXB z)O^f90P4T-2#vZ(aVOyQ#p!VG-`j~7rrn^I+~6atglV@w_N^^R(lU1i9@|qOZ|ak! zro^!t2mm+hG|>Amt<&BvKpURAD|6}twHrBuPV-nxQKlHEQp*&?FfY2$HFRFd0dkdA zt`j`AOex(4E-;2@F8x#xFXVM?W6IV=V*Mr$?X?SWDV`Ic_%V=F9;Cdo!#F zZ~6PbK>q$FU#bv7(>{xz@eZ6>n%{S`PqU{4$CoItSG|_2e+zB0ra7MS+p2a+x|Gj) ze&VTnceVY+Z{MYlO{LL9PlH_=Ij47o(-8V(4rdTz0Y+ia)kj zjUs%i`W2n9H|%et@tvQucOb17fOOfT@5(yvK^2mcjVLHz7`7o$;#^qVj?N1XQI#Py zZ)F|PnOlF^wk}{pSi+noeCs`p_8WW>*K=R6iA3uXA zWlGt)g7meF&Zvp1;K799LU}oSwfE+5ucS zB-58AC4X^DHN(k4m(~nN7e91Bw?6jYddoNz@;#izD{R{{_1~s4!X1m2-cclTW{dMF z)E#?xV6!Hz1m{8ql$gdv6Dy&?HVO5$OxarYiioA4M$-h`6>wP9HY>*;H-*2n$&Cr+ z-_RgJNj!IuW8B3lCdrj%ZOIjKf9d;OI`&$Y?p_;3eqk4*-0N0QA34Rq`O^0Xr0l$Mr-w~fC-Id#pNKLRw=nQ+V-)r7jV5;yBi%t z&g?IvWcceY(!Hhvv)0jD@H7z7FjuWBcGW59SD-nxr=cvj)Enrwo<2}!?lq}xt#yss zpWUo~Q5sKV{%diP%bF}P4s4iGB&BiegHcX!q(tS%vyUac@FSEtkewTBF|`9;!GbsR6>roa~mF=}n$?9j4}Omp!)$kano1dwG2JL6^o~((?>6~p;Uy2qTohHZ?SmR z={442uEBdO!L8^;7SCF}$>Le-9-vXK!MiMht>9%A&)U7sE>dgol!~Y2=5cYjoflfd zTfrMGp1br)yZHTrG+&dqT8DRgueEsADl{a(b$GGcV%XY8Y+`taUhTWb{LZ}G;%VpY zw%)F*q|ps<%W^&cdfwN1a&!#wtZiQx@)^XhWql;z`>w<57I`iDxlK16_h8<=pAcGKmv~Up*B3emi<{WDaCq9iVMiHWO$3*kx=dlrKbFhPD(%u zMl29&1J8>Ud++GY;h_l0lld!j?+mj}mipDJ)m4#Smyul{VEB2GEU=ll`VnqdyGRp} z9-Ed}#sH9&C3OR2G9EQ!eKDk`)G`ApBkxlF2;YO0PwT&&Mr}50r}*+fqKXK-<_G(zC3+h+}GeOAfd3&C%)Jfx2tR-kmsqcxiiZ3O9RX z+oNi6zc;9%1X&P+-hDB@p6N1oA!?8RXlHC#b> zI)j)S#rfR(3T<4sx1%#z@rol-q?cEfh;~n%<;x$wO01koBasm#vy)ZXcq{Oi;3fh$ zUkZ3zPJ<{AoEqvL<)oot=>{(a&Ad?iV($8N>YMFn9t@uoumH~wVqng(&NO|yu0c(O zRhCa9Lg}@tBn3z({i)gYeE2wGcvfM36lWmTZA)W$dR6OII@|67iLO|;ArahH8Ll=fgsYZ|~qpH#>#B`95 zeE#uA0oYzewK50qtipn6l-px0&yZ}y5#K^Gs=-L<*j_NA&`@J+)cs%M##8ee7LPuz z>PW?PNIx}xad9VC51OT*R!etPzR2%EY!AXy1{JtLsgK*2Y!4YLKgEUij+JrGx4;=z zP4&Hi%W)ry00;;>#;;}h;^tJa4_DZtYxKudw2rtR-7Ac9l4}FAlDAE#b!7B8aGkZqt6R{%uzET7F1j=Eqs*>z1kd1s=*ush`-Q`rnNu&>P|0c%lwV>=&ndr^ zJcT}crK*W!ml)P0Y#?7brQ`Jm{F)La`C4fSg%*E3^ie>^xEJ@x&( zzjt^T=uz%#|CDN`ZhLGVirS#szSC6C5Ar9Ek{fRIjx6a99vQ{)_BdsoAsXwWDM;Rj zgs?(C1UIh4j~PqkblNMam`?ZtGwe;rEnEcx9;y~-GzgbtXjg8@H&)l{fYi5?pLUa{ zTo3yE%N^*MFSc4wp@IN6_2DAKSYARNpXbZUtXc<^Q9f5{BY5O}lYt~(Y&3=Bn++zB z22l{hmpByW9Vps7Dx1mZa7FmlW1j<(yl$i$-?P5;mWTxMJLepZC!oP)_bDyY^K_P0 zH*^m<+-d+u7o9|~iCiQ_mC{8AvB{~7N|NN06Yd%AE-HnO&T-B;emRPz)qQf{kRw+| zuMg{vyFEl5LdH)Sb`@4rb>NJp9|nDLUqn!ni$^CHdSSx*~i5GKCa43LU4_F4esV%T;ok{KRK>nx!aHKG}$$n zgGHc|H!ltk_URK_l;R7YWM;pe9{jX78fq`o7ooS0N5lQm@TGd2f8l@sY_vBrP@ymU zFTXlC+B=N2m+=e#yL&H~nZCC_lJANy{I9?L@nAGOJAtSJdR=|tZvZ+iQ+gFH{0slv zFOT3!-o?xs5#C_ova!J{X`@$JbB z#O}lktpY9rPFA@A9tk%qUFDg&ZVAn)h-?2{*dx}Izv4a8G(N8Eb)zljQFmHQulcS% z&0T$SeDAhHgLH&D!h>^#mY8rAMdsuMN;|DPMBMh zLk2Q2OJja6F6w=tPU89X7~!xiO=s+GrmSeKtZ1niGj~g!{jRiaaU$}Y)V9sR^;LmP z8*F=^v9WyRx^1D!!~5&j&0?SvqtV!K5YLP^+cI zi%>6lM(=|L$AnmJ_BzjS0hI~F)Rz2?i!>|KX`%;?i7K?{NcTaE@s32JW^;*Bg^r`i z%`W{g1ho|L2pCG{gDTIplaelsWn(?Z8o(73T4)zg^VlA?-)G+#!I>o`lLce#JiS+Y znIJrDk@B)6tHAXxprDIADT*A9x_c*i$%OX|V-eWA;P+4UWdWzdz<1MZGFwg)jqjC# zoJfv-Je|Ic3&;T9r0)7kF!iI}0d&C>p1}!pJcJhp2cp{_!crp^Vfu9DN0WHJ^Fim9}(F=k##R2I%N(wzX_KcmCIVCz|@_kR&J_fn?A z30S!D%q(D|<#}3Nr)3zY))~J>IJ-X=&Y!0nN|Ke4QS0H@8g_xC!kWZT1pXp{N*(Gr z6>i)*;TJ2J%hP866r%U^=?1zy=##nbEdFEuh%uR_q%rd1wQcGRWmd@B-n39`1XE$e z2{EURZk13gVzDM*Xeku(lCJmyQdq%rDm#Olk9+3GqTwfCc^5V~@;NR<+;zrT z4qoF9420j?o|F~jan5GZ6|)p(iIck2o>(ip7Hwi|oHL>F5z?(9Eu5k)TvOy>Vd57A z&pZMUomjrL@OU&xcGA{$i=3?ue9JSQuHA$#uEn1N9LJ*tqEp!02!h++ocizb3$?*a zC8tHmM{I0f!TDr%vR2Ka#cmdlccF@>rNb8US=wX{by*zZ)=#eKV!qMNtul>B#43}Z zG2Q4(Wg4kG81MNKd&6ezZ_a|)cbU*ol`g%48}Z~l@RF(%nhJi2arT-| zM?h1mJ2`mVDipIMyR5Dnba%){Ff?~agT}8B8SX>UIvV%@QCA3v{|N)5K|u;~5#x;s z+5p9{>g%H+MCzPVtZa1cSg9{G$iBeQDWy~5HM@FQ){TTNc;w`HD4UvR@c7zur_hU| zCJ;2I9*l2knZ>D!O4O2JApFVeh<*DUGEadi2EZ|GEebX)W!vV%WEjgr-7L54i9P_I zE)~*%LJD-n^N3BYkRD80v^$W8?i^0Z*bF_%Ow#$Umn*PSF<#1r}2uE-Nsk`j! z7Nll_lN&0Zr&Wd9iB=%iu8Ff7ZCf-0^z0iCZD;ueeW{YRyvux9$>0}$>8-jrySZ~* z8nAR27I@P%Ln1mD4(J123&Gwft9;Q6j8m6*Q!-B^*v6d{W8wRu8OhIMF!_myZj=fE&heA z*d_dyU|)(V7iT-|7{YJ#2$>Rs2eNZ z4PPJZA0N6dNO)E~G4Lqt#uoji=6q9gzA80`S82KnC5H{Ht&YQMVSH0?zKnvC4w6Ct zt59(?#z?=0)g03`^=ngc(0%kZ81vtBp>Mj-FRBZ1tEQ74bdeUNRAMqFE@o-QSmZpe zNQPggpLm7ne{r3JVih%NNfPB*3rKLl1f*qz!H5H`NM%U*>!c#ArXAds2jpwj4m<)h z`Z>}>Xjn+Tf~h~w4%r-X-rbL+bJ~=Dy4>@Hw?L2+#y=69ns72H4vqKy@hrIAP@vUD z#hIpkO*EX3wZRHztnCMf?;%k6!fH`*Qe3S`a*EB;c&X-X<*b3c|0J=73W^%eH+2^y zuNCQQu$+bwJj5?c_u5Li&u4CUn^k4 zfr4C+QH?cW{dlCcE%UnweVcc;i8y2gkhfc^!}C5zz~;@emb5sGO+Ke(Md6*=I8|gw zi?E~`=H3{hXkGrCXtSzPi#uUs*n@aokw2DMRHdEspDQXR#Jnx?c58f3?*f8(GSdcXV4u%*#{?RRNge!>vf(L!GQsWYv{O)0$3}50jYBD{{!t>UvJyU z5r6lmSQy4h^4XG-^pYZpd~qD-YQRWbJJ;f12LeT|B%Uae$6eZ15BXeu=vzNoXJ(h= za=Dc3I6k07br)C?cV}kj?{8-H`p0yhZVh&Kx7aQ_WOE*+JY#<33BjgG#-`zI7|$5b zvLq9IScL1&{&L2yc_zXnWc9!G?eS6MOz*$es^}J=z+DK92>8GM6$HF9(BJDCha4?on!IoP_l z>a*lJ47ezkPxIK9U^}nCCgJVi^pWL;P5xgycP4}fGv|CoUULQ2g(u2?I*G1 zvF!ifgzQb>&y1b(hQ@Fq@Vu{lV{ z;cjK-u{2A3E(Cr7o6?M@xETEs8Q-#-Ie3>AB@_h(AjUEd#>jZkw?un$?PY9|B%s|` ze>b4NX+8nVu$|(NBR2IS!Cy60@=5zHn{Z@{s&R8^>KGl~WSNE6;OuN??B`hqF@P(8 zahykyn{N~f$&#rGD;;f1Z^0ql%9ttwO4veuLJPqE9uwg*jlyXN$0Uk3^U$BOUvqei zo4qhrW>?Xx>5fgVFM(OFj~ReT#$06;M`IGX?cT!35wA5ifU62$@b|X zI;wQTf;>}s#D`JaR$AF?p6*0Ck}E9eU2RjbWQ!LNC+#~?$XZ&r!|?Zpxj zg0UYomGNJ>FI(bQpR6rpOFCNb>CBF72P&8^=16MLHa0$da$cALQ6$fS5-_<^N?O^QeA6U7#TK}rCvQ!AXNGJA!b&;ah zsb~6Sa@#+cajCZA7MpT2MHMT+w3H{h1#!p-gMbX z03VHYPVIc|vC(M6WR`P#XH%w2#q2Yl#!2i|jldU*)32f0MsTZoM{mCj1{^9^4OpfPGMvp?9VJOB>QMnG1H|d- zN3Yor4XKjJn9O9JMN9iJhH4gb9soBghPA3c2PaplHK-qCrvO8h7C~=E`pa4{Dwk;Z z;m?9k^N28Kz$f`^R%Rm`Xc@0Ja1wC3v5(fbPeXDMEiDJg27qJ?=r;0v-rc^6xA)lg z)$rM~%V)z^PnK6#G5m)ghf8=;p6T9nWu5N7|8*q|vgX!%lJ2lho$^2LPM7=hq`s)W z2K&>R9Ijx<_%!2UP6_iAUi@epoLy)fDr z-V{*pBuBu$f`4LxsRg2EDFD;TxkAsr%)O{VRV5o$2<_@^o)1dy(I$VlH&L#rZG?PL zsl$<(@il=WvuG0gvfgqO`QLwUsgWeGOR6(#;mgQe5uZ}Z4w9xW90KZ6gX{==e0+C& z@!{nC`{VQR-;U4Ue!MvO^b0#+Ph4EdNg;rCb?7(by$+MeqZ!DaDm5rz0zEt1-R>j1 z)zI+E*QTV+JcVvb)R95piI@;@yVJd}#nsmFvmB*QiWc zGLMyRfntlw@YPl$zSNy+V+GR-jJl=GP}SoGO!x`Y3V>k@YRPXU3jn)PhXb*TC?|}) zNcUnu3BN@YTur!$j13Z0GrATd%rxV7z^@4u{F^|(9l=ToAG^K&yOZ;Go5jE+h@KqAoTeOp7Rt~EJ7eZS`=g8o2H5eJ0iJA|9`5IC|MY6RRQT04e71TY zR)0>P^ck z+Du6I=(Rfd-FK|$>~%gb)?bzkjQ+mdYhwZ{5L{G@GV5yUEeb_n@7iuVTTL$xhojLG zFz}O%#>Jk#jZzl{?K8K#j*ljMW+=K5S@#B5I}?e2MyjJ6g~qg4B`5Oo z$>+-sUEbIej~y&cOs^WkD*TL#YOB@)x&q9N4p`++I<4XmL<`a-PQj9CG7Vig%9(k^!4N+MRhupQ>W%@AS1H%;i#syYpD#POpaC6|C~!~oo!og6L3m}2%ZX~%@8DbAB3itwq4T%l-7Gol zkGS^IqS|$5vDeb8cD0wpbxmDM{dG2CtQz1uM(vN6vaaM`U%Fa_BBKY5l-4D;?cvC) zQux(20uT7A(%IGaqvo~Np0uV(dv!4k!V3-inY*Yo?@8~UQSly}To14Fnu$~+`3690 z$Mh!EK9N0q$+p+3@(%b)Q~YDSVGSbFSgVFDHejvhz)D?Ycr3+n1AH9<0<)%ik2X=V zDP@G~)URYR{NWxXN9b;OhI8o!=c#jJ#N!zpfmy#3g3Y*9lzZ99lzsU5^mNbCL_yQ} zswAIg$+D0VNa~4tanyobD1ce|^4Payv`aU${ED-JutpHnu6q1tTb4MfZM&AxKe zI>dk?(sqQ_3k1p7E%+7EnGWg#8+Rg79&v30(h8?*CCLmDQ?ITc%LIW?qk4*J`ZaH0 zL`g?HdNADERlFehpyX|ztKQEi?y6-?w7(A2So$}Fy_5Rs7o<|>r2h&dyyZB8_@hm+ z#sd95$|X;R}B5H zn$3>DKiqg)q3v;37ZgpXpHa`f^&jn3O>f*b5WVYH%)y7mXr*nC+G%Rnc0Qa0a0f?k2#2*cOW*^3r4z+lQ6oSM z=yyf$8f|D3UWnXCY!T){IjJNZ)OP$jw(nY*7JBhl9AdDBd4p!qy5#fWlLC7AU#ifJ z5ryuSM%Imk2ea89zdo4#_7LW8&R)U6FbwG?`o`J4aF*fV+%4hEm2mIm$=|TQ53@%P zVQ+s1d$ZYnAKJFimyw!QO5Z2MRhbS<0*AAY{ zpTXHU5AfC@|*g>cZ2Ud`OanfxR+#?7|CFXoz*vMkkDuq79mWidYh0rK*Y5&gcTI#S$vn zVj7|+kkeijj*GL6?%R?OTyGRyUi|YMWChYuJSSHIVOpmReU-uq5V`IhxCTA!1SeDp zrzdCgDOlFZhfL>EY9U`hsf9aKDOtLfj))Z=15KEct!ES#Nzs%&-w7t%&*-4^D9PR zEr`PPH%_?edDK1Y46_3}g(w;K8e^{krlZvuozQ3+QuWw6UK7#c`t|d)*E3U*SD%w-ASE z=9V6`{uQFrTPF~b&|zV(B`gKX(itedmW8?LbTW#gG+rDl zE6YuLJNLied(VR5W;pL+I-UzhXc*5Kj8E%uNdurTIn%Cuw)p72Y- zlvqloqvWy=>$v6Q{Rz7gDve~qem2iug;XLF%eQciKdxdnhM`cFR* zI)@15@#!+$>B9X@%=&i?h`h`m^?R{c8m+TLeoFQQ{7`i6bbQ`R|neaxOe zXTx8fvS-hS?AdVGCD1quMUtYVbFG)@-e7PU>3KFmu><5_>kdZ!zXAU~1KMC=>=e|* zQ?XYlcWl;P{h+0D`#LM*Q)}g|zqYmzE%^gp57}p_dCZb*F%gQ%8Jk7101ugS%|e-I z9wkgDB~{A6WGk)`K$G?jv_!9#8Vp0J4kn_P?O_vrkZPaqz>^uNwU zLb8Fgyg5S&S*p3xEre#V&;4e~uO{Od_58EDL9mO10UvU#v$n)``+o;L1Eo zAHTGwKBt`*T{aqxm{ytSRWbk z4Y}DTSnk$JX>sP_~LFb5KxVyS?LN@MnP;O?(*JoqL}z6Norz(ouF`mjUb2l zmDhEJ-ptntIg0A=g;Fmd5LmQW#$q87O}TU1Pkb8-yikzCL`_4Lu<&OX^qdOi67rV3 zv{li#&79q4aXAQe#^d;gT|y~SP*&1)6(Fx2u7p^^*bex0n9?nl6ZC)E7^KkoU{j!E zC?EwFZHdK4rO)-ooiL8R@Hhj84id8kObh)x9C)VCgCtN5)n$f?Zx&vooGTek*VYs& z<;ZkyrOqv)^$a5=b8a1~)R|(>d0>naT&xK}TLtD&N%bHhRf+@}AOFqLWWj5zqGa zipC*d^p}qO#|Yv;k13bdvP*ZrUcTgHOl@+fi7d@x?F8-Pmo~bpDk@dktGQTJ{1kL` zCNl+r6I|4na`3OwRL{Y$JO$sf($d#>EP~tCS8XeY>B<2HG(jqZ6DCHYs}NX*3vfPX@o7Mr_F;W9~ zmM;X&^Q=*f+b7*qCuyb-^%`6`Vz`~+L`p0qY^PEe85#zfA^P#_dIHqWSps>BDhqyH zV%Q*E3T0ub(puOBzh*0Z(AIex;I+*s^)Rx!X{nQ4lnq6SJdVhV;DZ zt9NXW?%W)i&ZAIvTXn6@E-L$7-<4;f!m~rsEmoJSO<1GuQkJmC;bLmAz8f+!(Rgo^ z=b2h>(>8r*PsDYMLEyFvYcXtG@LL6a?ssYXhZ}O>dO^L=uY7|sF{jLOY|3?iv+<$s|cy@gB?%m<(_{-tx>rZD#pa0EX zvY{`2L^ziXM%Frqr#C5OZT2U9Wa;qJhw4BmcjfxX_Ce(!bH~J%CHM}~8*CNcP1Wjn zx|By=KkC*eOx056=?zYlcx=W$G=;D)qOT$ubF76aogAQj@V`j;9p7zCZp<*Fc<+R@ zThq*(&`pasQ;5jCe8jh&I8~^ess65cmfHh(-uyH=0C#Y53onh=9(E#P-XHl|?7*5n zputIj3-b~AB~8}5Juj^3Na3~#OAhizW{GZtE}BvgwDF|1@U}1YQ8)Q&E&KxP1CEi? zH*eT{J6jS|*^pCs4QY;Gm&%4aU-ZoL!0l)FZY~YsT=Bp&W3$-&vo>Mhc-P-W8sr~^ zx)j#SF{qqZ`m8!p^B4~DC(YDol8WlZn|#F;C2vH=IUBWoYfpw7&1*^?OT5HaDC2CA z5NB}fXN=U8h}B_3Q|_+HaM2!(2eOfFn3OJ^geVYy|2tW!qWZUM6nN z$)PUJjU&;El)|9id4Lz=x0HspHJsf>&({EL3q4yueZg1M)?34`+b5wpmzyS727ov-NP= zV8B=dSm$A$fnginA~oDT?QYL0#0Z?Hp%}M2WYvM&_1i+kyWc1Ix`Fokq-c5bsk8R$ z{u5;ltT}l)FMBv*RygU~?W5|461Thd98Jz}f&^%wMVrz`g7|6`46nr-Fv}(K7Olxakq#%eSv#)hc~ zai_xXQ92#7_a7GRAgA49yDpp&fhhF@hJT!a5phZAANYFy5=(!?wtI#X{BQe~$zN6c zCqC&7Z$>67ejy34i)1S7`oBx6p`l*@x~RcbP9O`hC~3kEscvWlvlRT>IK!|sHXg9f zli}`Dvg_{Cu3_opq=J`*DcflNy_}7GIKm*tJ)*O1XCd~lZ@^Ia-qx0VF@ck{t^Wb- zR?%+THWYpLSKNmHb^_P(iY^(lEKBNUYk;OT<^X#L0)wKiEiMwNkyKo5*uU?RqGVfk zYINJ<_z=+~@8KoSxre#oQaIrL@du4tv#UCSy_OcUk$25mKek*OI5iata3*YTVa8*=VEK>`w$K%si zugBlKftgzZQ(M6Yo50}u?MFB}gYkE7;Ph+^r{nRl56uKeXv7R8y0qnsH_eGkELWItPYJ9`Ho>fZrgK7nrzp3nB9(t4CZ7F$WsVO1$T zq-`O6P}ousw0x$~1Slyem@$|*Bq0etXVwXf#j3P!4`SMd)`_i{p%hAr60%0LbZ0}4 zLqGSWvk)1&)vHwSbRX2{e<}YHDK}04B*_e!!SnXM=3(yYUus@B6)hOY?)A_8xA$kS z*K@eOG+cA#(a5=Fx{+Z@x~m1aVy=9)L_G=s4bHU${LJ!#w4>3MTEa8SO7ykG0*r^< zgXN@V(a_1Tfphv~vZ89tb6>kFRb~mqc;4Cfg6b77n_twz?o4Y|4K~J`c0d31{q6nD zY1n~61}S0Oth>fx~+G>9J9U%n$c%tZcM zlrhN)7Nz9A&>I69&}KVyPFR+aO*pFoB@xtOqk?Of>XJ*HnhIxo#6|-p*5$r+hWo}v zrdAWlTCms~Mk1Uam|#JhcJqRX1mT1DVE-Ido+Ql#nIv^k>$O^9H<@MbYFU!pxT(Q0s2ZW`M(*-J#lIo9Lofw$ zv8a4x2Q)`x+;b9MD=3r^UKByriqNEguKno`lej@$o8>l7A%p%9+M7IB)CJQl-+##U zj=pa8zP0U}y~k|6)LyEnkPqo%H>N!l_ zMDj(mEVSYzqQL=jw%P9W{)!^>|1*X6wD&jdU0HM6I1+yMufW4p#hJ?ZcFxIcXo;`@9?e5 z|K3~T{I?3nWt>gW<)pvNA2N)7T`VRE`?Jb1NmmaUtv)(BIC%Zb(ZS&f3TYNJB(?PN zDcW_;2I$Qjbnx~By?%3mULPF1WUTXKLi9w1pXK>#{eFM{F3D&2H+z$GvCoQ`$2aT! zO3n6f=IPD;B3|d@Zw4{Jd-;zXorPWG@n-?Q{EFC*!V~lrjI#g4kx17y7P^=HvJ!{7np~nt zQH-ve%aIrLhu$@(=_={=Kli($EL|rip^@whW?dUj5IEQ4UVp%w0nQOI?(9fc$3@^eksFXUbGW*Wbgg)9 z7%D_vEoZ*(xz2#}6@gu`7uP%I>AG&X{c(z}oUT7Q^W5=2Mt2;Fm}HT1EPt(u&LvdD)i6| zB5pdzx{f^O%;olWtZTwqKPmdCn&dQRBm>AF71P{Wc>bZvyuwa2S_ zqU*v5iM-O9PL3*V;E@`0imnW*JfFAdNqt-y1)`{mjgSE=>UVzUwCaH31azdml1+A^ zD?+8{if{*AjjF4IkE}gE5Z2G~oSFvdS|(jj7sO*T)z{Ac zJ_^$XW;6Ne-mzE}yh0gXky(q(K{>gf~WnZvP2UXa>grmh;=DdE z;`9e$9hb{2Y=A5B9dFFX2e~5S$;OQ3RC~l$ga4JS4=rqtNg;$8 zO=dC8L|9@pBSop4G?6f8H%XqwWLLxrf5q5nR=x?MPlb?s|KCY9*-6QbC_(|AW74+o z3w@0R?NiGw7qP~8E{v-}A9Ksw`E!SLUuKf@$1R05x?+ZVf++KR`W9!zMzZ)}m#7_m z{EZk~{!&o)+5fBi8&Z3;&f}c?_mg7M9|b4R{@9OpGA9fxsiZWzEqrCePgdq`a83q> zhWu=vXiPr#Fz z*pTkIl~f}6sioTdpq2{acAZYIA$R}0o@&ocH}LJatL58scl~;*J$Dpbx8UwLQAOhr z?(nK#V;9_3>|`@tO(pC{r&fjYEw_<-dwtAb;VjP6Y)xk8DH%Y?OtipcWZhnmQyd{h zDyha>D;<<>k}{Pu+i*+wkeW)H&(3O@|42`@W~MHtYN|Ce^FuXe=Dwl*EZJ(5 zpl&)Nw*@mXj~akAGk0(5{E&ujUNUQ|3Ol5&T9iEUnlt-By|qBbU1hgs{$eQF-o&K$ zvND+16)l-7gUMFMQ}>VinC_dlH-7eOx&~C4Fc18u9fL5F5pWRoJI$DB$r=EJIlOc{ z&kagTg)mDGIgpudqUrz7zH9lqOusKZyu8b2kbMgqC(p>f-|19057u+)rm0%O2nI2^-%TWdKBS}0gkjsZ9jCs~ml!A381+T7#IUZ5 zVTauaW85)fytBse2S$Z}+SwR8CZ`U~I)-gs zx~`#J;TWD17+RNLys^eOcgQxO9Y(+I7Jy^aSD_NaS|5guHXMT3|K45r%Ht<+929A~CF$YH&z2z^M6RB!=x^W^x8K zkfY|-X&^_)q zEDvp0b~M(SG_KpNk^sgY5PkMrI%EV!yLC+9Mx&s<;sz;%tc0SrN;PjTVHi=b>P9Is zY>mtmZ`25*r8m|T%poysJO60Vepxr#;M9T0@!4s=zcf1z5U4Ju6IF>}+h164ZA&@o z7p+PR+eylB4GWB6xTDoj4g&~O4&~lfK?2KR0D)lCT&Qpi?HXA_4CSU-V>y)TXpJ%G zoi!r~ukEe!H7@!=*wK)TZtv<{vDHw(+(h7=U3b=w|nBuOW7^d(mFoq!t z3yNV1#)4v)g72DQn6{_380Ce=I)-h3QLjBVm7};CStUXAQQn|zjA4oll^C{t-xMDz zF>KeC>{8|iIc)1f?_nBAkcb0AK)J-Qb?3-iizW=%+M&E)*aV|?OA(4;3Pa*ob@Ex9 z(;HeDUgKqs;`KVYTQ10-PsAiW8jMt;h*BT{NxaI{_%e}Vr7(`5g(NYAA_ah=1z9i@ zH3a~qoyIeuA_ah=`N9~Ak^;f;tI8=-ASkLwjHAdD0E*@|VJKw^07l!iFqk3*(oAZg z0dFQH#TLlAzhM#Fi6-e{6=%u1yqeOa<4L$i-EL!GXi2cF|Hdd$od7{Ig^lV2sBG0Z z(mDZxXbLVh5+IGcc6^tMIma&-3&j$U3UH_EhwsRtu^Eu5lMC_OZnb3te^;%EUg2UG2*v=op z$Fz){J%VFZ7;Eupd!SJSslq$C>b?W_Z#9w=V%h51Ih$sfVT zy}(gSy@ybAVE`xBF|_lmG1Q=8Qw^L3kC^H`7O_MDM;D0hV>i#K7v5mQoAq*&jYepZ zPLtaNx7u7Vq)Q0|b{dt@Mto<%AFbUSWuOsfXOH&WMTn6oTs&^YAu@@{vMa;4$qy7G zviq8)Q?!g1xVfr1$dF;;|0z`?^`0?bHHt@T{xW(>>{IBYHFtT3gbyF|aVu6rw)eMb zwh;ULq@4q|a2D9xhJL&Z*`Vu(+W^0SemW1_)$7OdpdGz_3J%-N>!;tmvNXYlQ$6$M zJIpcx!cV6@jo)JOv$VdOG@avkxg9GMU_RU!%PK3E=!;FcNC3EQ)O++A3}CmVhtzYo zXPM9drVyq~Xn;cF>NS)v_ApNv1>5gT(kU+9SjjUrF$D_HY|~?k-s29I8lgoTUWup^ zT7=YQjH)t5Rv^hFOshgtrEmZIiuMDDeobz z0Vy;v7<(=21~5j0BP#l?2 zGH=oK`I6Yx{e&zMs+Q$1=MU0$Ch>f}Ru6jjbVJLMZ!uYk+}+obrQ zz+e0Om`sv7y(WHu^ZRVMF263Z&c*vX*%7mh*r-Y@>PW>ba^F1g?_!{MwaU^T$%4t5 z;Xm&2a>723K?pd`V)1zl>L!qQzc2yV=P?9FK4)+bf{CxIFk@1`g;Dzu2FE*3GlYM{ zi`5(>c}y)n;vw+9;p~BcDy0=)?07|27ZNF_efc&e6`jT3u>4#{t;DK6*{4}ha?AOd zqLyj(vm)`5sfAWyy}}cEP$iUJpEk&1CtfJS5Bf>er+n|K2(3xc9nOsnD#14YCc}S=D5%q$Nwaev$>!-$(Sz;fES2qN0m$ z;(RFI7c9PeK}X>=p5MNIuY3qY$wpf^p3Km$RBOBzvb1^i&^WhMf8SX5hj-zj^!k6yU16hA*=}zvQ6)JJ|0~hc~D~ z4_9Q);r140fBywvZ)fmzHoMNqeh;Z_0&gbcUrc|KWzzI^3f?{(f^{RbV-JVPfE{6S z2j7`=^I*r;zroJ=Vanmvh9_`7eY-=*2G`r2?b-;CL+cGZ8$Z|(Ob^fAz1SWP;i(Py z#~{dl?_TZr2%Q^y8=I!oG??&D2Ke~{K8l*a?apdC*JI^j3g{uUs4_yf5AG#ConlEK z0HX`GGdWh+3HFE=VJ<=jJ_h^Bm%M()Xy2D_` z(4NQj87JZJ-NVoZ<88a2-cwJbiolmP&gQtWsV}~d?O>v&k9#yae?c8<(kv{l5Q;wn zIzJ)v8$6h}IB3Ix8GF1naYsaiPZJYE4tJk?9pvpu|FNh@^n$T8cYX(h}xd&?^dssJD_WR~lBLDydXJc!{@M zOEzz`z>7~rVdtm#kP*HGdS6Sb6bK1yT~`dj5M2_k8C5wjUQ|uV_%a6s04_9CY|S*5 zX^|(=Q(N}l24VqgDvK5VOXjR%dYgnSnC6jdfn)?~A~h?Tib$v%Sqnu0ZDl1>MMc<} zmN&?bj6m-w*PvFUs(x@OHk`^R{e#6hMU7-$(IXMxBBrE;j&9yh1qO%mD*Q32X~E)w z-c$5KKnaa)!o2NknTL3BVSd@J##?dQwT9Xu6u{y1h9T=4@?}+HXzn)m9 SSZ=TJ0p_p*0000-LQO)))S{ID literal 0 HcmV?d00001 diff --git a/build/tools/phpunit.phar b/build/tools/phpunit.phar new file mode 100644 index 0000000..9c91bd4 --- /dev/null +++ b/build/tools/phpunit.phar @@ -0,0 +1,72403 @@ +#!/usr/bin/env php + '/doctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php', + 'doctrine\\instantiator\\exception\\invalidargumentexception' => '/doctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.php', + 'doctrine\\instantiator\\exception\\unexpectedvalueexception' => '/doctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.php', + 'doctrine\\instantiator\\instantiator' => '/doctrine-instantiator/Doctrine/Instantiator/Instantiator.php', + 'doctrine\\instantiator\\instantiatorinterface' => '/doctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php', + 'file_iterator' => '/php-file-iterator/Iterator.php', + 'file_iterator_facade' => '/php-file-iterator/Iterator/Facade.php', + 'file_iterator_factory' => '/php-file-iterator/Iterator/Factory.php', + 'php_codecoverage' => '/php-code-coverage/CodeCoverage.php', + 'php_codecoverage_driver' => '/php-code-coverage/CodeCoverage/Driver.php', + 'php_codecoverage_driver_hhvm' => '/php-code-coverage/CodeCoverage/Driver/HHVM.php', + 'php_codecoverage_driver_xdebug' => '/php-code-coverage/CodeCoverage/Driver/Xdebug.php', + 'php_codecoverage_exception' => '/php-code-coverage/CodeCoverage/Exception.php', + 'php_codecoverage_exception_unintentionallycoveredcode' => '/php-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php', + 'php_codecoverage_filter' => '/php-code-coverage/CodeCoverage/Filter.php', + 'php_codecoverage_report_clover' => '/php-code-coverage/CodeCoverage/Report/Clover.php', + 'php_codecoverage_report_crap4j' => '/php-code-coverage/CodeCoverage/Report/Crap4j.php', + 'php_codecoverage_report_factory' => '/php-code-coverage/CodeCoverage/Report/Factory.php', + 'php_codecoverage_report_html' => '/php-code-coverage/CodeCoverage/Report/HTML.php', + 'php_codecoverage_report_html_renderer' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer.php', + 'php_codecoverage_report_html_renderer_dashboard' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php', + 'php_codecoverage_report_html_renderer_directory' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.php', + 'php_codecoverage_report_html_renderer_file' => '/php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php', + 'php_codecoverage_report_node' => '/php-code-coverage/CodeCoverage/Report/Node.php', + 'php_codecoverage_report_node_directory' => '/php-code-coverage/CodeCoverage/Report/Node/Directory.php', + 'php_codecoverage_report_node_file' => '/php-code-coverage/CodeCoverage/Report/Node/File.php', + 'php_codecoverage_report_node_iterator' => '/php-code-coverage/CodeCoverage/Report/Node/Iterator.php', + 'php_codecoverage_report_php' => '/php-code-coverage/CodeCoverage/Report/PHP.php', + 'php_codecoverage_report_text' => '/php-code-coverage/CodeCoverage/Report/Text.php', + 'php_codecoverage_report_xml' => '/php-code-coverage/CodeCoverage/Report/XML.php', + 'php_codecoverage_report_xml_directory' => '/php-code-coverage/CodeCoverage/Report/XML/Directory.php', + 'php_codecoverage_report_xml_file' => '/php-code-coverage/CodeCoverage/Report/XML/File.php', + 'php_codecoverage_report_xml_file_coverage' => '/php-code-coverage/CodeCoverage/Report/XML/File/Coverage.php', + 'php_codecoverage_report_xml_file_method' => '/php-code-coverage/CodeCoverage/Report/XML/File/Method.php', + 'php_codecoverage_report_xml_file_report' => '/php-code-coverage/CodeCoverage/Report/XML/File/Report.php', + 'php_codecoverage_report_xml_file_unit' => '/php-code-coverage/CodeCoverage/Report/XML/File/Unit.php', + 'php_codecoverage_report_xml_node' => '/php-code-coverage/CodeCoverage/Report/XML/Node.php', + 'php_codecoverage_report_xml_project' => '/php-code-coverage/CodeCoverage/Report/XML/Project.php', + 'php_codecoverage_report_xml_tests' => '/php-code-coverage/CodeCoverage/Report/XML/Tests.php', + 'php_codecoverage_report_xml_totals' => '/php-code-coverage/CodeCoverage/Report/XML/Totals.php', + 'php_codecoverage_util' => '/php-code-coverage/CodeCoverage/Util.php', + 'php_codecoverage_util_invalidargumenthelper' => '/php-code-coverage/CodeCoverage/Util/InvalidArgumentHelper.php', + 'php_invoker' => '/php-invoker/Invoker.php', + 'php_invoker_timeoutexception' => '/php-invoker/Invoker/TimeoutException.php', + 'php_timer' => '/php-timer/Timer.php', + 'php_token' => '/php-token-stream/Token.php', + 'php_token_abstract' => '/php-token-stream/Token.php', + 'php_token_ampersand' => '/php-token-stream/Token.php', + 'php_token_and_equal' => '/php-token-stream/Token.php', + 'php_token_array' => '/php-token-stream/Token.php', + 'php_token_array_cast' => '/php-token-stream/Token.php', + 'php_token_as' => '/php-token-stream/Token.php', + 'php_token_at' => '/php-token-stream/Token.php', + 'php_token_backtick' => '/php-token-stream/Token.php', + 'php_token_bad_character' => '/php-token-stream/Token.php', + 'php_token_bool_cast' => '/php-token-stream/Token.php', + 'php_token_boolean_and' => '/php-token-stream/Token.php', + 'php_token_boolean_or' => '/php-token-stream/Token.php', + 'php_token_break' => '/php-token-stream/Token.php', + 'php_token_callable' => '/php-token-stream/Token.php', + 'php_token_caret' => '/php-token-stream/Token.php', + 'php_token_case' => '/php-token-stream/Token.php', + 'php_token_catch' => '/php-token-stream/Token.php', + 'php_token_character' => '/php-token-stream/Token.php', + 'php_token_class' => '/php-token-stream/Token.php', + 'php_token_class_c' => '/php-token-stream/Token.php', + 'php_token_class_name_constant' => '/php-token-stream/Token.php', + 'php_token_clone' => '/php-token-stream/Token.php', + 'php_token_close_bracket' => '/php-token-stream/Token.php', + 'php_token_close_curly' => '/php-token-stream/Token.php', + 'php_token_close_square' => '/php-token-stream/Token.php', + 'php_token_close_tag' => '/php-token-stream/Token.php', + 'php_token_colon' => '/php-token-stream/Token.php', + 'php_token_comma' => '/php-token-stream/Token.php', + 'php_token_comment' => '/php-token-stream/Token.php', + 'php_token_concat_equal' => '/php-token-stream/Token.php', + 'php_token_const' => '/php-token-stream/Token.php', + 'php_token_constant_encapsed_string' => '/php-token-stream/Token.php', + 'php_token_continue' => '/php-token-stream/Token.php', + 'php_token_curly_open' => '/php-token-stream/Token.php', + 'php_token_dec' => '/php-token-stream/Token.php', + 'php_token_declare' => '/php-token-stream/Token.php', + 'php_token_default' => '/php-token-stream/Token.php', + 'php_token_dir' => '/php-token-stream/Token.php', + 'php_token_div' => '/php-token-stream/Token.php', + 'php_token_div_equal' => '/php-token-stream/Token.php', + 'php_token_dnumber' => '/php-token-stream/Token.php', + 'php_token_do' => '/php-token-stream/Token.php', + 'php_token_doc_comment' => '/php-token-stream/Token.php', + 'php_token_dollar' => '/php-token-stream/Token.php', + 'php_token_dollar_open_curly_braces' => '/php-token-stream/Token.php', + 'php_token_dot' => '/php-token-stream/Token.php', + 'php_token_double_arrow' => '/php-token-stream/Token.php', + 'php_token_double_cast' => '/php-token-stream/Token.php', + 'php_token_double_colon' => '/php-token-stream/Token.php', + 'php_token_double_quotes' => '/php-token-stream/Token.php', + 'php_token_echo' => '/php-token-stream/Token.php', + 'php_token_ellipsis' => '/php-token-stream/Token.php', + 'php_token_else' => '/php-token-stream/Token.php', + 'php_token_elseif' => '/php-token-stream/Token.php', + 'php_token_empty' => '/php-token-stream/Token.php', + 'php_token_encapsed_and_whitespace' => '/php-token-stream/Token.php', + 'php_token_end_heredoc' => '/php-token-stream/Token.php', + 'php_token_enddeclare' => '/php-token-stream/Token.php', + 'php_token_endfor' => '/php-token-stream/Token.php', + 'php_token_endforeach' => '/php-token-stream/Token.php', + 'php_token_endif' => '/php-token-stream/Token.php', + 'php_token_endswitch' => '/php-token-stream/Token.php', + 'php_token_endwhile' => '/php-token-stream/Token.php', + 'php_token_equal' => '/php-token-stream/Token.php', + 'php_token_eval' => '/php-token-stream/Token.php', + 'php_token_exclamation_mark' => '/php-token-stream/Token.php', + 'php_token_exit' => '/php-token-stream/Token.php', + 'php_token_extends' => '/php-token-stream/Token.php', + 'php_token_file' => '/php-token-stream/Token.php', + 'php_token_final' => '/php-token-stream/Token.php', + 'php_token_finally' => '/php-token-stream/Token.php', + 'php_token_for' => '/php-token-stream/Token.php', + 'php_token_foreach' => '/php-token-stream/Token.php', + 'php_token_func_c' => '/php-token-stream/Token.php', + 'php_token_function' => '/php-token-stream/Token.php', + 'php_token_global' => '/php-token-stream/Token.php', + 'php_token_goto' => '/php-token-stream/Token.php', + 'php_token_gt' => '/php-token-stream/Token.php', + 'php_token_halt_compiler' => '/php-token-stream/Token.php', + 'php_token_if' => '/php-token-stream/Token.php', + 'php_token_implements' => '/php-token-stream/Token.php', + 'php_token_inc' => '/php-token-stream/Token.php', + 'php_token_include' => '/php-token-stream/Token.php', + 'php_token_include_once' => '/php-token-stream/Token.php', + 'php_token_includes' => '/php-token-stream/Token.php', + 'php_token_inline_html' => '/php-token-stream/Token.php', + 'php_token_instanceof' => '/php-token-stream/Token.php', + 'php_token_insteadof' => '/php-token-stream/Token.php', + 'php_token_int_cast' => '/php-token-stream/Token.php', + 'php_token_interface' => '/php-token-stream/Token.php', + 'php_token_is_equal' => '/php-token-stream/Token.php', + 'php_token_is_greater_or_equal' => '/php-token-stream/Token.php', + 'php_token_is_identical' => '/php-token-stream/Token.php', + 'php_token_is_not_equal' => '/php-token-stream/Token.php', + 'php_token_is_not_identical' => '/php-token-stream/Token.php', + 'php_token_is_smaller_or_equal' => '/php-token-stream/Token.php', + 'php_token_isset' => '/php-token-stream/Token.php', + 'php_token_lambda_arrow' => '/php-token-stream/Token.php', + 'php_token_lambda_cp' => '/php-token-stream/Token.php', + 'php_token_lambda_op' => '/php-token-stream/Token.php', + 'php_token_line' => '/php-token-stream/Token.php', + 'php_token_list' => '/php-token-stream/Token.php', + 'php_token_lnumber' => '/php-token-stream/Token.php', + 'php_token_logical_and' => '/php-token-stream/Token.php', + 'php_token_logical_or' => '/php-token-stream/Token.php', + 'php_token_logical_xor' => '/php-token-stream/Token.php', + 'php_token_lt' => '/php-token-stream/Token.php', + 'php_token_method_c' => '/php-token-stream/Token.php', + 'php_token_minus' => '/php-token-stream/Token.php', + 'php_token_minus_equal' => '/php-token-stream/Token.php', + 'php_token_mod_equal' => '/php-token-stream/Token.php', + 'php_token_mul_equal' => '/php-token-stream/Token.php', + 'php_token_mult' => '/php-token-stream/Token.php', + 'php_token_namespace' => '/php-token-stream/Token.php', + 'php_token_new' => '/php-token-stream/Token.php', + 'php_token_ns_c' => '/php-token-stream/Token.php', + 'php_token_ns_separator' => '/php-token-stream/Token.php', + 'php_token_num_string' => '/php-token-stream/Token.php', + 'php_token_object_cast' => '/php-token-stream/Token.php', + 'php_token_object_operator' => '/php-token-stream/Token.php', + 'php_token_open_bracket' => '/php-token-stream/Token.php', + 'php_token_open_curly' => '/php-token-stream/Token.php', + 'php_token_open_square' => '/php-token-stream/Token.php', + 'php_token_open_tag' => '/php-token-stream/Token.php', + 'php_token_open_tag_with_echo' => '/php-token-stream/Token.php', + 'php_token_or_equal' => '/php-token-stream/Token.php', + 'php_token_paamayim_nekudotayim' => '/php-token-stream/Token.php', + 'php_token_percent' => '/php-token-stream/Token.php', + 'php_token_pipe' => '/php-token-stream/Token.php', + 'php_token_plus' => '/php-token-stream/Token.php', + 'php_token_plus_equal' => '/php-token-stream/Token.php', + 'php_token_pow' => '/php-token-stream/Token.php', + 'php_token_pow_equal' => '/php-token-stream/Token.php', + 'php_token_print' => '/php-token-stream/Token.php', + 'php_token_private' => '/php-token-stream/Token.php', + 'php_token_protected' => '/php-token-stream/Token.php', + 'php_token_public' => '/php-token-stream/Token.php', + 'php_token_question_mark' => '/php-token-stream/Token.php', + 'php_token_require' => '/php-token-stream/Token.php', + 'php_token_require_once' => '/php-token-stream/Token.php', + 'php_token_return' => '/php-token-stream/Token.php', + 'php_token_semicolon' => '/php-token-stream/Token.php', + 'php_token_shape' => '/php-token-stream/Token.php', + 'php_token_sl' => '/php-token-stream/Token.php', + 'php_token_sl_equal' => '/php-token-stream/Token.php', + 'php_token_sr' => '/php-token-stream/Token.php', + 'php_token_sr_equal' => '/php-token-stream/Token.php', + 'php_token_start_heredoc' => '/php-token-stream/Token.php', + 'php_token_static' => '/php-token-stream/Token.php', + 'php_token_stream' => '/php-token-stream/Token/Stream.php', + 'php_token_stream_cachingfactory' => '/php-token-stream/Token/Stream/CachingFactory.php', + 'php_token_string' => '/php-token-stream/Token.php', + 'php_token_string_cast' => '/php-token-stream/Token.php', + 'php_token_string_varname' => '/php-token-stream/Token.php', + 'php_token_switch' => '/php-token-stream/Token.php', + 'php_token_throw' => '/php-token-stream/Token.php', + 'php_token_tilde' => '/php-token-stream/Token.php', + 'php_token_trait' => '/php-token-stream/Token.php', + 'php_token_trait_c' => '/php-token-stream/Token.php', + 'php_token_try' => '/php-token-stream/Token.php', + 'php_token_type' => '/php-token-stream/Token.php', + 'php_token_typelist_gt' => '/php-token-stream/Token.php', + 'php_token_typelist_lt' => '/php-token-stream/Token.php', + 'php_token_unset' => '/php-token-stream/Token.php', + 'php_token_unset_cast' => '/php-token-stream/Token.php', + 'php_token_use' => '/php-token-stream/Token.php', + 'php_token_var' => '/php-token-stream/Token.php', + 'php_token_variable' => '/php-token-stream/Token.php', + 'php_token_while' => '/php-token-stream/Token.php', + 'php_token_whitespace' => '/php-token-stream/Token.php', + 'php_token_xor_equal' => '/php-token-stream/Token.php', + 'php_token_yield' => '/php-token-stream/Token.php', + 'php_tokenwithscope' => '/php-token-stream/Token.php', + 'php_tokenwithscopeandvisibility' => '/php-token-stream/Token.php', + 'phpunit_exception' => '/phpunit/Exception.php', + 'phpunit_extensions_database_abstracttester' => '/dbunit/Extensions/Database/AbstractTester.php', + 'phpunit_extensions_database_constraint_datasetisequal' => '/dbunit/Extensions/Database/Constraint/DataSetIsEqual.php', + 'phpunit_extensions_database_constraint_tableisequal' => '/dbunit/Extensions/Database/Constraint/TableIsEqual.php', + 'phpunit_extensions_database_constraint_tablerowcount' => '/dbunit/Extensions/Database/Constraint/TableRowCount.php', + 'phpunit_extensions_database_dataset_abstractdataset' => '/dbunit/Extensions/Database/DataSet/AbstractDataSet.php', + 'phpunit_extensions_database_dataset_abstracttable' => '/dbunit/Extensions/Database/DataSet/AbstractTable.php', + 'phpunit_extensions_database_dataset_abstracttablemetadata' => '/dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php', + 'phpunit_extensions_database_dataset_abstractxmldataset' => '/dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.php', + 'phpunit_extensions_database_dataset_compositedataset' => '/dbunit/Extensions/Database/DataSet/CompositeDataSet.php', + 'phpunit_extensions_database_dataset_csvdataset' => '/dbunit/Extensions/Database/DataSet/CsvDataSet.php', + 'phpunit_extensions_database_dataset_datasetfilter' => '/dbunit/Extensions/Database/DataSet/DataSetFilter.php', + 'phpunit_extensions_database_dataset_defaultdataset' => '/dbunit/Extensions/Database/DataSet/DefaultDataSet.php', + 'phpunit_extensions_database_dataset_defaulttable' => '/dbunit/Extensions/Database/DataSet/DefaultTable.php', + 'phpunit_extensions_database_dataset_defaulttableiterator' => '/dbunit/Extensions/Database/DataSet/DefaultTableIterator.php', + 'phpunit_extensions_database_dataset_defaulttablemetadata' => '/dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php', + 'phpunit_extensions_database_dataset_flatxmldataset' => '/dbunit/Extensions/Database/DataSet/FlatXmlDataSet.php', + 'phpunit_extensions_database_dataset_idataset' => '/dbunit/Extensions/Database/DataSet/IDataSet.php', + 'phpunit_extensions_database_dataset_ipersistable' => '/dbunit/Extensions/Database/DataSet/IPersistable.php', + 'phpunit_extensions_database_dataset_ispec' => '/dbunit/Extensions/Database/DataSet/ISpec.php', + 'phpunit_extensions_database_dataset_itable' => '/dbunit/Extensions/Database/DataSet/ITable.php', + 'phpunit_extensions_database_dataset_itableiterator' => '/dbunit/Extensions/Database/DataSet/ITableIterator.php', + 'phpunit_extensions_database_dataset_itablemetadata' => '/dbunit/Extensions/Database/DataSet/ITableMetaData.php', + 'phpunit_extensions_database_dataset_iyamlparser' => '/dbunit/Extensions/Database/DataSet/IYamlParser.php', + 'phpunit_extensions_database_dataset_mysqlxmldataset' => '/dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php', + 'phpunit_extensions_database_dataset_persistors_abstract' => '/dbunit/Extensions/Database/DataSet/Persistors/Abstract.php', + 'phpunit_extensions_database_dataset_persistors_factory' => '/dbunit/Extensions/Database/DataSet/Persistors/Factory.php', + 'phpunit_extensions_database_dataset_persistors_flatxml' => '/dbunit/Extensions/Database/DataSet/Persistors/FlatXml.php', + 'phpunit_extensions_database_dataset_persistors_mysqlxml' => '/dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.php', + 'phpunit_extensions_database_dataset_persistors_xml' => '/dbunit/Extensions/Database/DataSet/Persistors/Xml.php', + 'phpunit_extensions_database_dataset_persistors_yaml' => '/dbunit/Extensions/Database/DataSet/Persistors/Yaml.php', + 'phpunit_extensions_database_dataset_querydataset' => '/dbunit/Extensions/Database/DataSet/QueryDataSet.php', + 'phpunit_extensions_database_dataset_querytable' => '/dbunit/Extensions/Database/DataSet/QueryTable.php', + 'phpunit_extensions_database_dataset_replacementdataset' => '/dbunit/Extensions/Database/DataSet/ReplacementDataSet.php', + 'phpunit_extensions_database_dataset_replacementtable' => '/dbunit/Extensions/Database/DataSet/ReplacementTable.php', + 'phpunit_extensions_database_dataset_replacementtableiterator' => '/dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php', + 'phpunit_extensions_database_dataset_specs_csv' => '/dbunit/Extensions/Database/DataSet/Specs/Csv.php', + 'phpunit_extensions_database_dataset_specs_dbquery' => '/dbunit/Extensions/Database/DataSet/Specs/DbQuery.php', + 'phpunit_extensions_database_dataset_specs_dbtable' => '/dbunit/Extensions/Database/DataSet/Specs/DbTable.php', + 'phpunit_extensions_database_dataset_specs_factory' => '/dbunit/Extensions/Database/DataSet/Specs/Factory.php', + 'phpunit_extensions_database_dataset_specs_flatxml' => '/dbunit/Extensions/Database/DataSet/Specs/FlatXml.php', + 'phpunit_extensions_database_dataset_specs_ifactory' => '/dbunit/Extensions/Database/DataSet/Specs/IFactory.php', + 'phpunit_extensions_database_dataset_specs_xml' => '/dbunit/Extensions/Database/DataSet/Specs/Xml.php', + 'phpunit_extensions_database_dataset_specs_yaml' => '/dbunit/Extensions/Database/DataSet/Specs/Yaml.php', + 'phpunit_extensions_database_dataset_symfonyyamlparser' => '/dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php', + 'phpunit_extensions_database_dataset_tablefilter' => '/dbunit/Extensions/Database/DataSet/TableFilter.php', + 'phpunit_extensions_database_dataset_tablemetadatafilter' => '/dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php', + 'phpunit_extensions_database_dataset_xmldataset' => '/dbunit/Extensions/Database/DataSet/XmlDataSet.php', + 'phpunit_extensions_database_dataset_yamldataset' => '/dbunit/Extensions/Database/DataSet/YamlDataSet.php', + 'phpunit_extensions_database_db_dataset' => '/dbunit/Extensions/Database/DB/DataSet.php', + 'phpunit_extensions_database_db_defaultdatabaseconnection' => '/dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php', + 'phpunit_extensions_database_db_filtereddataset' => '/dbunit/Extensions/Database/DB/FilteredDataSet.php', + 'phpunit_extensions_database_db_idatabaseconnection' => '/dbunit/Extensions/Database/DB/IDatabaseConnection.php', + 'phpunit_extensions_database_db_imetadata' => '/dbunit/Extensions/Database/DB/IMetaData.php', + 'phpunit_extensions_database_db_metadata' => '/dbunit/Extensions/Database/DB/MetaData.php', + 'phpunit_extensions_database_db_metadata_dblib' => '/dbunit/Extensions/Database/DB/MetaData/Dblib.php', + 'phpunit_extensions_database_db_metadata_firebird' => '/dbunit/Extensions/Database/DB/MetaData/Firebird.php', + 'phpunit_extensions_database_db_metadata_informationschema' => '/dbunit/Extensions/Database/DB/MetaData/InformationSchema.php', + 'phpunit_extensions_database_db_metadata_mysql' => '/dbunit/Extensions/Database/DB/MetaData/MySQL.php', + 'phpunit_extensions_database_db_metadata_oci' => '/dbunit/Extensions/Database/DB/MetaData/Oci.php', + 'phpunit_extensions_database_db_metadata_pgsql' => '/dbunit/Extensions/Database/DB/MetaData/PgSQL.php', + 'phpunit_extensions_database_db_metadata_sqlite' => '/dbunit/Extensions/Database/DB/MetaData/Sqlite.php', + 'phpunit_extensions_database_db_metadata_sqlsrv' => '/dbunit/Extensions/Database/DB/MetaData/SqlSrv.php', + 'phpunit_extensions_database_db_resultsettable' => '/dbunit/Extensions/Database/DB/ResultSetTable.php', + 'phpunit_extensions_database_db_table' => '/dbunit/Extensions/Database/DB/Table.php', + 'phpunit_extensions_database_db_tableiterator' => '/dbunit/Extensions/Database/DB/TableIterator.php', + 'phpunit_extensions_database_db_tablemetadata' => '/dbunit/Extensions/Database/DB/TableMetaData.php', + 'phpunit_extensions_database_defaulttester' => '/dbunit/Extensions/Database/DefaultTester.php', + 'phpunit_extensions_database_exception' => '/dbunit/Extensions/Database/Exception.php', + 'phpunit_extensions_database_idatabaselistconsumer' => '/dbunit/Extensions/Database/IDatabaseListConsumer.php', + 'phpunit_extensions_database_itester' => '/dbunit/Extensions/Database/ITester.php', + 'phpunit_extensions_database_operation_composite' => '/dbunit/Extensions/Database/Operation/Composite.php', + 'phpunit_extensions_database_operation_delete' => '/dbunit/Extensions/Database/Operation/Delete.php', + 'phpunit_extensions_database_operation_deleteall' => '/dbunit/Extensions/Database/Operation/DeleteAll.php', + 'phpunit_extensions_database_operation_exception' => '/dbunit/Extensions/Database/Operation/Exception.php', + 'phpunit_extensions_database_operation_factory' => '/dbunit/Extensions/Database/Operation/Factory.php', + 'phpunit_extensions_database_operation_idatabaseoperation' => '/dbunit/Extensions/Database/Operation/IDatabaseOperation.php', + 'phpunit_extensions_database_operation_insert' => '/dbunit/Extensions/Database/Operation/Insert.php', + 'phpunit_extensions_database_operation_null' => '/dbunit/Extensions/Database/Operation/Null.php', + 'phpunit_extensions_database_operation_replace' => '/dbunit/Extensions/Database/Operation/Replace.php', + 'phpunit_extensions_database_operation_rowbased' => '/dbunit/Extensions/Database/Operation/RowBased.php', + 'phpunit_extensions_database_operation_truncate' => '/dbunit/Extensions/Database/Operation/Truncate.php', + 'phpunit_extensions_database_operation_update' => '/dbunit/Extensions/Database/Operation/Update.php', + 'phpunit_extensions_database_testcase' => '/dbunit/Extensions/Database/TestCase.php', + 'phpunit_extensions_database_ui_command' => '/dbunit/Extensions/Database/UI/Command.php', + 'phpunit_extensions_database_ui_context' => '/dbunit/Extensions/Database/UI/Context.php', + 'phpunit_extensions_database_ui_imedium' => '/dbunit/Extensions/Database/UI/IMedium.php', + 'phpunit_extensions_database_ui_imediumprinter' => '/dbunit/Extensions/Database/UI/IMediumPrinter.php', + 'phpunit_extensions_database_ui_imode' => '/dbunit/Extensions/Database/UI/IMode.php', + 'phpunit_extensions_database_ui_imodefactory' => '/dbunit/Extensions/Database/UI/IModeFactory.php', + 'phpunit_extensions_database_ui_invalidmodeexception' => '/dbunit/Extensions/Database/UI/InvalidModeException.php', + 'phpunit_extensions_database_ui_mediums_text' => '/dbunit/Extensions/Database/UI/Mediums/Text.php', + 'phpunit_extensions_database_ui_modefactory' => '/dbunit/Extensions/Database/UI/ModeFactory.php', + 'phpunit_extensions_database_ui_modes_exportdataset' => '/dbunit/Extensions/Database/UI/Modes/ExportDataSet.php', + 'phpunit_extensions_database_ui_modes_exportdataset_arguments' => '/dbunit/Extensions/Database/UI/Modes/ExportDataSet/Arguments.php', + 'phpunit_extensions_grouptestsuite' => '/phpunit/Extensions/GroupTestSuite.php', + 'phpunit_extensions_phpttestcase' => '/phpunit/Extensions/PhptTestCase.php', + 'phpunit_extensions_phpttestsuite' => '/phpunit/Extensions/PhptTestSuite.php', + 'phpunit_extensions_repeatedtest' => '/phpunit/Extensions/RepeatedTest.php', + 'phpunit_extensions_selenium2testcase' => '/phpunit-selenium/Extensions/Selenium2TestCase.php', + 'phpunit_extensions_selenium2testcase_command' => '/phpunit-selenium/Extensions/Selenium2TestCase/Command.php', + 'phpunit_extensions_selenium2testcase_commandsholder' => '/phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.php', + 'phpunit_extensions_selenium2testcase_driver' => '/phpunit-selenium/Extensions/Selenium2TestCase/Driver.php', + 'phpunit_extensions_selenium2testcase_element' => '/phpunit-selenium/Extensions/Selenium2TestCase/Element.php', + 'phpunit_extensions_selenium2testcase_element_accessor' => '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php', + 'phpunit_extensions_selenium2testcase_element_select' => '/phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php', + 'phpunit_extensions_selenium2testcase_elementcommand_attribute' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.php', + 'phpunit_extensions_selenium2testcase_elementcommand_click' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php', + 'phpunit_extensions_selenium2testcase_elementcommand_css' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.php', + 'phpunit_extensions_selenium2testcase_elementcommand_equals' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php', + 'phpunit_extensions_selenium2testcase_elementcommand_genericaccessor' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.php', + 'phpunit_extensions_selenium2testcase_elementcommand_genericpost' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.php', + 'phpunit_extensions_selenium2testcase_elementcommand_value' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.php', + 'phpunit_extensions_selenium2testcase_elementcriteria' => '/phpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.php', + 'phpunit_extensions_selenium2testcase_exception' => '/phpunit-selenium/Extensions/Selenium2TestCase/Exception.php', + 'phpunit_extensions_selenium2testcase_keys' => '/phpunit-selenium/Extensions/Selenium2TestCase/Keys.php', + 'phpunit_extensions_selenium2testcase_keysholder' => '/phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php', + 'phpunit_extensions_selenium2testcase_noseleniumexception' => '/phpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.php', + 'phpunit_extensions_selenium2testcase_response' => '/phpunit-selenium/Extensions/Selenium2TestCase/Response.php', + 'phpunit_extensions_selenium2testcase_screenshotlistener' => '/phpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.php', + 'phpunit_extensions_selenium2testcase_session' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session.php', + 'phpunit_extensions_selenium2testcase_session_cookie' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.php', + 'phpunit_extensions_selenium2testcase_session_cookie_builder' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php', + 'phpunit_extensions_selenium2testcase_session_storage' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php', + 'phpunit_extensions_selenium2testcase_session_timeouts' => '/phpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_acceptalert' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_active' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Active.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_alerttext' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_click' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_dismissalert' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_file' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_frame' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_genericaccessor' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_genericattribute' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_keys' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_location' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_log' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_moveto' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_orientation' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_url' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php', + 'phpunit_extensions_selenium2testcase_sessioncommand_window' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.php', + 'phpunit_extensions_selenium2testcase_sessionstrategy' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php', + 'phpunit_extensions_selenium2testcase_sessionstrategy_isolated' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php', + 'phpunit_extensions_selenium2testcase_sessionstrategy_shared' => '/phpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.php', + 'phpunit_extensions_selenium2testcase_statecommand' => '/phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.php', + 'phpunit_extensions_selenium2testcase_url' => '/phpunit-selenium/Extensions/Selenium2TestCase/URL.php', + 'phpunit_extensions_selenium2testcase_waituntil' => '/phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php', + 'phpunit_extensions_selenium2testcase_webdriverexception' => '/phpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.php', + 'phpunit_extensions_selenium2testcase_window' => '/phpunit-selenium/Extensions/Selenium2TestCase/Window.php', + 'phpunit_extensions_seleniumbrowsersuite' => '/phpunit-selenium/Extensions/SeleniumBrowserSuite.php', + 'phpunit_extensions_seleniumcommon_exithandler' => '/phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php', + 'phpunit_extensions_seleniumcommon_remotecoverage' => '/phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.php', + 'phpunit_extensions_seleniumtestcase' => '/phpunit-selenium/Extensions/SeleniumTestCase.php', + 'phpunit_extensions_seleniumtestcase_driver' => '/phpunit-selenium/Extensions/SeleniumTestCase/Driver.php', + 'phpunit_extensions_seleniumtestsuite' => '/phpunit-selenium/Extensions/SeleniumTestSuite.php', + 'phpunit_extensions_testdecorator' => '/phpunit/Extensions/TestDecorator.php', + 'phpunit_extensions_ticketlistener' => '/phpunit/Extensions/TicketListener.php', + 'phpunit_framework_assert' => '/phpunit/Framework/Assert.php', + 'phpunit_framework_assertionfailederror' => '/phpunit/Framework/AssertionFailedError.php', + 'phpunit_framework_basetestlistener' => '/phpunit/Framework/BaseTestListener.php', + 'phpunit_framework_codecoverageexception' => '/phpunit/Framework/CodeCoverageException.php', + 'phpunit_framework_constraint' => '/phpunit/Framework/Constraint.php', + 'phpunit_framework_constraint_and' => '/phpunit/Framework/Constraint/And.php', + 'phpunit_framework_constraint_arrayhaskey' => '/phpunit/Framework/Constraint/ArrayHasKey.php', + 'phpunit_framework_constraint_arraysubset' => '/phpunit/Framework/Constraint/ArraySubset.php', + 'phpunit_framework_constraint_attribute' => '/phpunit/Framework/Constraint/Attribute.php', + 'phpunit_framework_constraint_callback' => '/phpunit/Framework/Constraint/Callback.php', + 'phpunit_framework_constraint_classhasattribute' => '/phpunit/Framework/Constraint/ClassHasAttribute.php', + 'phpunit_framework_constraint_classhasstaticattribute' => '/phpunit/Framework/Constraint/ClassHasStaticAttribute.php', + 'phpunit_framework_constraint_composite' => '/phpunit/Framework/Constraint/Composite.php', + 'phpunit_framework_constraint_count' => '/phpunit/Framework/Constraint/Count.php', + 'phpunit_framework_constraint_exception' => '/phpunit/Framework/Constraint/Exception.php', + 'phpunit_framework_constraint_exceptioncode' => '/phpunit/Framework/Constraint/ExceptionCode.php', + 'phpunit_framework_constraint_exceptionmessage' => '/phpunit/Framework/Constraint/ExceptionMessage.php', + 'phpunit_framework_constraint_exceptionmessageregexp' => '/phpunit/Framework/Constraint/ExceptionMessageRegExp.php', + 'phpunit_framework_constraint_fileexists' => '/phpunit/Framework/Constraint/FileExists.php', + 'phpunit_framework_constraint_greaterthan' => '/phpunit/Framework/Constraint/GreaterThan.php', + 'phpunit_framework_constraint_isanything' => '/phpunit/Framework/Constraint/IsAnything.php', + 'phpunit_framework_constraint_isempty' => '/phpunit/Framework/Constraint/IsEmpty.php', + 'phpunit_framework_constraint_isequal' => '/phpunit/Framework/Constraint/IsEqual.php', + 'phpunit_framework_constraint_isfalse' => '/phpunit/Framework/Constraint/IsFalse.php', + 'phpunit_framework_constraint_isidentical' => '/phpunit/Framework/Constraint/IsIdentical.php', + 'phpunit_framework_constraint_isinstanceof' => '/phpunit/Framework/Constraint/IsInstanceOf.php', + 'phpunit_framework_constraint_isjson' => '/phpunit/Framework/Constraint/IsJson.php', + 'phpunit_framework_constraint_isnull' => '/phpunit/Framework/Constraint/IsNull.php', + 'phpunit_framework_constraint_istrue' => '/phpunit/Framework/Constraint/IsTrue.php', + 'phpunit_framework_constraint_istype' => '/phpunit/Framework/Constraint/IsType.php', + 'phpunit_framework_constraint_jsonmatches' => '/phpunit/Framework/Constraint/JsonMatches.php', + 'phpunit_framework_constraint_jsonmatches_errormessageprovider' => '/phpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.php', + 'phpunit_framework_constraint_lessthan' => '/phpunit/Framework/Constraint/LessThan.php', + 'phpunit_framework_constraint_not' => '/phpunit/Framework/Constraint/Not.php', + 'phpunit_framework_constraint_objecthasattribute' => '/phpunit/Framework/Constraint/ObjectHasAttribute.php', + 'phpunit_framework_constraint_or' => '/phpunit/Framework/Constraint/Or.php', + 'phpunit_framework_constraint_pcrematch' => '/phpunit/Framework/Constraint/PCREMatch.php', + 'phpunit_framework_constraint_samesize' => '/phpunit/Framework/Constraint/SameSize.php', + 'phpunit_framework_constraint_stringcontains' => '/phpunit/Framework/Constraint/StringContains.php', + 'phpunit_framework_constraint_stringendswith' => '/phpunit/Framework/Constraint/StringEndsWith.php', + 'phpunit_framework_constraint_stringmatches' => '/phpunit/Framework/Constraint/StringMatches.php', + 'phpunit_framework_constraint_stringstartswith' => '/phpunit/Framework/Constraint/StringStartsWith.php', + 'phpunit_framework_constraint_traversablecontains' => '/phpunit/Framework/Constraint/TraversableContains.php', + 'phpunit_framework_constraint_traversablecontainsonly' => '/phpunit/Framework/Constraint/TraversableContainsOnly.php', + 'phpunit_framework_constraint_xor' => '/phpunit/Framework/Constraint/Xor.php', + 'phpunit_framework_error' => '/phpunit/Framework/Error.php', + 'phpunit_framework_error_deprecated' => '/phpunit/Framework/Error/Deprecated.php', + 'phpunit_framework_error_notice' => '/phpunit/Framework/Error/Notice.php', + 'phpunit_framework_error_warning' => '/phpunit/Framework/Error/Warning.php', + 'phpunit_framework_exception' => '/phpunit/Framework/Exception.php', + 'phpunit_framework_exceptionwrapper' => '/phpunit/Framework/ExceptionWrapper.php', + 'phpunit_framework_expectationfailedexception' => '/phpunit/Framework/ExpectationFailedException.php', + 'phpunit_framework_incompletetest' => '/phpunit/Framework/IncompleteTest.php', + 'phpunit_framework_incompletetestcase' => '/phpunit/Framework/IncompleteTestCase.php', + 'phpunit_framework_incompletetesterror' => '/phpunit/Framework/IncompleteTestError.php', + 'phpunit_framework_invalidcoverstargeterror' => '/phpunit/Framework/InvalidCoversTargetError.php', + 'phpunit_framework_invalidcoverstargetexception' => '/phpunit/Framework/InvalidCoversTargetException.php', + 'phpunit_framework_mockobject_badmethodcallexception' => '/phpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.php', + 'phpunit_framework_mockobject_builder_identity' => '/phpunit-mock-objects/Framework/MockObject/Builder/Identity.php', + 'phpunit_framework_mockobject_builder_invocationmocker' => '/phpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.php', + 'phpunit_framework_mockobject_builder_match' => '/phpunit-mock-objects/Framework/MockObject/Builder/Match.php', + 'phpunit_framework_mockobject_builder_methodnamematch' => '/phpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.php', + 'phpunit_framework_mockobject_builder_namespace' => '/phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php', + 'phpunit_framework_mockobject_builder_parametersmatch' => '/phpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.php', + 'phpunit_framework_mockobject_builder_stub' => '/phpunit-mock-objects/Framework/MockObject/Builder/Stub.php', + 'phpunit_framework_mockobject_exception' => '/phpunit-mock-objects/Framework/MockObject/Exception/Exception.php', + 'phpunit_framework_mockobject_generator' => '/phpunit-mock-objects/Framework/MockObject/Generator.php', + 'phpunit_framework_mockobject_invocation' => '/phpunit-mock-objects/Framework/MockObject/Invocation.php', + 'phpunit_framework_mockobject_invocation_object' => '/phpunit-mock-objects/Framework/MockObject/Invocation/Object.php', + 'phpunit_framework_mockobject_invocation_static' => '/phpunit-mock-objects/Framework/MockObject/Invocation/Static.php', + 'phpunit_framework_mockobject_invocationmocker' => '/phpunit-mock-objects/Framework/MockObject/InvocationMocker.php', + 'phpunit_framework_mockobject_invokable' => '/phpunit-mock-objects/Framework/MockObject/Invokable.php', + 'phpunit_framework_mockobject_matcher' => '/phpunit-mock-objects/Framework/MockObject/Matcher.php', + 'phpunit_framework_mockobject_matcher_anyinvokedcount' => '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.php', + 'phpunit_framework_mockobject_matcher_anyparameters' => '/phpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php', + 'phpunit_framework_mockobject_matcher_consecutiveparameters' => '/phpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.php', + 'phpunit_framework_mockobject_matcher_invocation' => '/phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.php', + 'phpunit_framework_mockobject_matcher_invokedatindex' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.php', + 'phpunit_framework_mockobject_matcher_invokedatleastcount' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.php', + 'phpunit_framework_mockobject_matcher_invokedatleastonce' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php', + 'phpunit_framework_mockobject_matcher_invokedatmostcount' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.php', + 'phpunit_framework_mockobject_matcher_invokedcount' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.php', + 'phpunit_framework_mockobject_matcher_invokedrecorder' => '/phpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.php', + 'phpunit_framework_mockobject_matcher_methodname' => '/phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.php', + 'phpunit_framework_mockobject_matcher_parameters' => '/phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.php', + 'phpunit_framework_mockobject_matcher_statelessinvocation' => '/phpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php', + 'phpunit_framework_mockobject_mockbuilder' => '/phpunit-mock-objects/Framework/MockObject/MockBuilder.php', + 'phpunit_framework_mockobject_mockobject' => '/phpunit-mock-objects/Framework/MockObject/MockObject.php', + 'phpunit_framework_mockobject_runtimeexception' => '/phpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.php', + 'phpunit_framework_mockobject_stub' => '/phpunit-mock-objects/Framework/MockObject/Stub.php', + 'phpunit_framework_mockobject_stub_consecutivecalls' => '/phpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'phpunit_framework_mockobject_stub_exception' => '/phpunit-mock-objects/Framework/MockObject/Stub/Exception.php', + 'phpunit_framework_mockobject_stub_matchercollection' => '/phpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php', + 'phpunit_framework_mockobject_stub_return' => '/phpunit-mock-objects/Framework/MockObject/Stub/Return.php', + 'phpunit_framework_mockobject_stub_returnargument' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.php', + 'phpunit_framework_mockobject_stub_returncallback' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.php', + 'phpunit_framework_mockobject_stub_returnself' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php', + 'phpunit_framework_mockobject_stub_returnvaluemap' => '/phpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.php', + 'phpunit_framework_mockobject_verifiable' => '/phpunit-mock-objects/Framework/MockObject/Verifiable.php', + 'phpunit_framework_outputerror' => '/phpunit/Framework/OutputError.php', + 'phpunit_framework_riskytest' => '/phpunit/Framework/RiskyTest.php', + 'phpunit_framework_riskytesterror' => '/phpunit/Framework/RiskyTestError.php', + 'phpunit_framework_selfdescribing' => '/phpunit/Framework/SelfDescribing.php', + 'phpunit_framework_skippedtest' => '/phpunit/Framework/SkippedTest.php', + 'phpunit_framework_skippedtestcase' => '/phpunit/Framework/SkippedTestCase.php', + 'phpunit_framework_skippedtesterror' => '/phpunit/Framework/SkippedTestError.php', + 'phpunit_framework_skippedtestsuiteerror' => '/phpunit/Framework/SkippedTestSuiteError.php', + 'phpunit_framework_syntheticerror' => '/phpunit/Framework/SyntheticError.php', + 'phpunit_framework_test' => '/phpunit/Framework/Test.php', + 'phpunit_framework_testcase' => '/phpunit/Framework/TestCase.php', + 'phpunit_framework_testfailure' => '/phpunit/Framework/TestFailure.php', + 'phpunit_framework_testlistener' => '/phpunit/Framework/TestListener.php', + 'phpunit_framework_testresult' => '/phpunit/Framework/TestResult.php', + 'phpunit_framework_testsuite' => '/phpunit/Framework/TestSuite.php', + 'phpunit_framework_testsuite_dataprovider' => '/phpunit/Framework/TestSuite/DataProvider.php', + 'phpunit_framework_unintentionallycoveredcodeerror' => '/phpunit/Framework/UnintentionallyCoveredCodeError.php', + 'phpunit_framework_warning' => '/phpunit/Framework/Warning.php', + 'phpunit_runner_basetestrunner' => '/phpunit/Runner/BaseTestRunner.php', + 'phpunit_runner_exception' => '/phpunit/Runner/Exception.php', + 'phpunit_runner_filter_factory' => '/phpunit/Runner/Filter/Factory.php', + 'phpunit_runner_filter_group_exclude' => '/phpunit/Runner/Filter/Group/Exclude.php', + 'phpunit_runner_filter_group_include' => '/phpunit/Runner/Filter/Group/Include.php', + 'phpunit_runner_filter_groupfilteriterator' => '/phpunit/Runner/Filter/Group.php', + 'phpunit_runner_filter_test' => '/phpunit/Runner/Filter/Test.php', + 'phpunit_runner_standardtestsuiteloader' => '/phpunit/Runner/StandardTestSuiteLoader.php', + 'phpunit_runner_testsuiteloader' => '/phpunit/Runner/TestSuiteLoader.php', + 'phpunit_runner_version' => '/phpunit/Runner/Version.php', + 'phpunit_textui_command' => '/phpunit/TextUI/Command.php', + 'phpunit_textui_resultprinter' => '/phpunit/TextUI/ResultPrinter.php', + 'phpunit_textui_testrunner' => '/phpunit/TextUI/TestRunner.php', + 'phpunit_util_blacklist' => '/phpunit/Util/Blacklist.php', + 'phpunit_util_configuration' => '/phpunit/Util/Configuration.php', + 'phpunit_util_errorhandler' => '/phpunit/Util/ErrorHandler.php', + 'phpunit_util_fileloader' => '/phpunit/Util/Fileloader.php', + 'phpunit_util_filesystem' => '/phpunit/Util/Filesystem.php', + 'phpunit_util_filter' => '/phpunit/Util/Filter.php', + 'phpunit_util_getopt' => '/phpunit/Util/Getopt.php', + 'phpunit_util_globalstate' => '/phpunit/Util/GlobalState.php', + 'phpunit_util_invalidargumenthelper' => '/phpunit/Util/InvalidArgumentHelper.php', + 'phpunit_util_log_json' => '/phpunit/Util/Log/JSON.php', + 'phpunit_util_log_junit' => '/phpunit/Util/Log/JUnit.php', + 'phpunit_util_log_tap' => '/phpunit/Util/Log/TAP.php', + 'phpunit_util_php' => '/phpunit/Util/PHP.php', + 'phpunit_util_php_default' => '/phpunit/Util/PHP/Default.php', + 'phpunit_util_php_windows' => '/phpunit/Util/PHP/Windows.php', + 'phpunit_util_printer' => '/phpunit/Util/Printer.php', + 'phpunit_util_regex' => '/phpunit/Util/Regex.php', + 'phpunit_util_string' => '/phpunit/Util/String.php', + 'phpunit_util_test' => '/phpunit/Util/Test.php', + 'phpunit_util_testdox_nameprettifier' => '/phpunit/Util/TestDox/NamePrettifier.php', + 'phpunit_util_testdox_resultprinter' => '/phpunit/Util/TestDox/ResultPrinter.php', + 'phpunit_util_testdox_resultprinter_html' => '/phpunit/Util/TestDox/ResultPrinter/HTML.php', + 'phpunit_util_testdox_resultprinter_text' => '/phpunit/Util/TestDox/ResultPrinter/Text.php', + 'phpunit_util_testsuiteiterator' => '/phpunit/Util/TestSuiteIterator.php', + 'phpunit_util_type' => '/phpunit/Util/Type.php', + 'phpunit_util_xml' => '/phpunit/Util/XML.php', + 'sebastianbergmann\\comparator\\arraycomparator' => '/sebastian-comparator/ArrayComparator.php', + 'sebastianbergmann\\comparator\\comparator' => '/sebastian-comparator/Comparator.php', + 'sebastianbergmann\\comparator\\comparisonfailure' => '/sebastian-comparator/ComparisonFailure.php', + 'sebastianbergmann\\comparator\\datetimecomparator' => '/sebastian-comparator/DateTimeComparator.php', + 'sebastianbergmann\\comparator\\domnodecomparator' => '/sebastian-comparator/DOMNodeComparator.php', + 'sebastianbergmann\\comparator\\doublecomparator' => '/sebastian-comparator/DoubleComparator.php', + 'sebastianbergmann\\comparator\\exceptioncomparator' => '/sebastian-comparator/ExceptionComparator.php', + 'sebastianbergmann\\comparator\\factory' => '/sebastian-comparator/Factory.php', + 'sebastianbergmann\\comparator\\mockobjectcomparator' => '/sebastian-comparator/MockObjectComparator.php', + 'sebastianbergmann\\comparator\\numericcomparator' => '/sebastian-comparator/NumericComparator.php', + 'sebastianbergmann\\comparator\\objectcomparator' => '/sebastian-comparator/ObjectComparator.php', + 'sebastianbergmann\\comparator\\resourcecomparator' => '/sebastian-comparator/ResourceComparator.php', + 'sebastianbergmann\\comparator\\scalarcomparator' => '/sebastian-comparator/ScalarComparator.php', + 'sebastianbergmann\\comparator\\splobjectstoragecomparator' => '/sebastian-comparator/SplObjectStorageComparator.php', + 'sebastianbergmann\\comparator\\typecomparator' => '/sebastian-comparator/TypeComparator.php', + 'sebastianbergmann\\diff\\chunk' => '/sebastian-diff/Chunk.php', + 'sebastianbergmann\\diff\\diff' => '/sebastian-diff/Diff.php', + 'sebastianbergmann\\diff\\differ' => '/sebastian-diff/Differ.php', + 'sebastianbergmann\\diff\\lcs\\longestcommonsubsequence' => '/sebastian-diff/LCS/LongestCommonSubsequence.php', + 'sebastianbergmann\\diff\\lcs\\memoryefficientimplementation' => '/sebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php', + 'sebastianbergmann\\diff\\lcs\\timeefficientimplementation' => '/sebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.php', + 'sebastianbergmann\\diff\\line' => '/sebastian-diff/Line.php', + 'sebastianbergmann\\diff\\parser' => '/sebastian-diff/Parser.php', + 'sebastianbergmann\\environment\\console' => '/sebastian-environment/Console.php', + 'sebastianbergmann\\environment\\runtime' => '/sebastian-environment/Runtime.php', + 'sebastianbergmann\\exporter\\exporter' => '/sebastian-exporter/Exporter.php', + 'sebastianbergmann\\globalstate\\blacklist' => '/sebastian-global-state/Blacklist.php', + 'sebastianbergmann\\globalstate\\exception' => '/sebastian-global-state/Exception.php', + 'sebastianbergmann\\globalstate\\restorer' => '/sebastian-global-state/Restorer.php', + 'sebastianbergmann\\globalstate\\runtimeexception' => '/sebastian-global-state/RuntimeException.php', + 'sebastianbergmann\\globalstate\\snapshot' => '/sebastian-global-state/Snapshot.php', + 'sebastianbergmann\\recursioncontext\\context' => '/sebastian-recursion-context/Context.php', + 'sebastianbergmann\\recursioncontext\\exception' => '/sebastian-recursion-context/Exception.php', + 'sebastianbergmann\\recursioncontext\\invalidargumentexception' => '/sebastian-recursion-context/InvalidArgumentException.php', + 'sebastianbergmann\\version' => '/sebastian-version/Version.php', + 'symfony\\component\\yaml\\dumper' => '/symfony/yaml/Symfony/Component/Yaml/Dumper.php', + 'symfony\\component\\yaml\\escaper' => '/symfony/yaml/Symfony/Component/Yaml/Escaper.php', + 'symfony\\component\\yaml\\exception\\dumpexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.php', + 'symfony\\component\\yaml\\exception\\exceptioninterface' => '/symfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.php', + 'symfony\\component\\yaml\\exception\\parseexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php', + 'symfony\\component\\yaml\\exception\\runtimeexception' => '/symfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.php', + 'symfony\\component\\yaml\\inline' => '/symfony/yaml/Symfony/Component/Yaml/Inline.php', + 'symfony\\component\\yaml\\parser' => '/symfony/yaml/Symfony/Component/Yaml/Parser.php', + 'symfony\\component\\yaml\\unescaper' => '/symfony/yaml/Symfony/Component/Yaml/Unescaper.php', + 'symfony\\component\\yaml\\yaml' => '/symfony/yaml/Symfony/Component/Yaml/Yaml.php', + 'text_template' => '/php-text-template/Template.php' + ); + } + + $class = strtolower($class); + + if (isset($classes[$class])) { + require __PHPUNIT_PHAR_ROOT__ . $classes[$class]; + } + } +); + +Phar::mapPhar('phpunit-4.4.5.phar'); + +if ($execute) { + if (isset($_SERVER['argv'][1]) && $_SERVER['argv'][1] == '--manifest') { + print file_get_contents(__PHPUNIT_PHAR_ROOT__ . '/manifest.txt'); + exit; + } + + PHPUnit_TextUI_Command::main(); +} + +__HALT_COMPILER(); ?> +ìŒÍphpunit-4.4.5.pharphp-invoker/Invoker.php&‰·ÇT&Š-é¡¶(php-invoker/Invoker/TimeoutException.phpÕ ‰·ÇTÕ •nжphp-file-iterator/Iterator.phpc‰·ÇTc~ÃÔƒ¶&php-file-iterator/Iterator/Factory.phph‰·ÇThö¸ÑÚ¶%php-file-iterator/Iterator/Facade.php¥‰·ÇT¥l¶php-file-iterator/LICENSE ‰·ÇT ðµ|ò¶!php-token-stream/Token/Stream.php¼=‰·ÇT¼=è/⪶0php-token-stream/Token/Stream/CachingFactory.php?‰·ÇT?ì'· ¶php-token-stream/Token.phpðW‰·ÇTðWâQ«¶php-token-stream/LICENSE‰·ÇTƒ-& ¶sebastian-exporter/Exporter.php„‰·ÇT„™ > ¶sebastian-exporter/LICENSE‰·ÇTAªe)¶Jsebastian-diff/LCS/TimeEfficientLongestCommonSubsequenceImplementation.phpö‰·ÇTöPvÅ+¶Lsebastian-diff/LCS/MemoryEfficientLongestCommonSubsequenceImplementation.php剷ÇTå•¶/sebastian-diff/LCS/LongestCommonSubsequence.php« +‰·ÇT« +PÏzâ¶sebastian-diff/Diff.phpò ‰·ÇTò ŒöU¶sebastian-diff/Parser.php*‰·ÇT*>“pG¶sebastian-diff/Chunk.php‰·ÇTä‡L%¶sebastian-diff/Line.phpÚ ‰·ÇTÚ ùn¬¶sebastian-diff/Differ.phpF"‰·ÇTF"›%»V¶sebastian-diff/LICENSE‰·ÇT—Ðô×¶*phpunit/Runner/StandardTestSuiteLoader.php‰·ÇTîP¶phpunit/Runner/Version.php¼‰·ÇT¼~Oç¶phpunit/Runner/Exception.php—‰·ÇT—Íl £¶phpunit/Runner/Filter/Test.php ‰·ÇT \ïÁ¶!phpunit/Runner/Filter/Factory.phpõ‰·ÇTõ©‰¢ß¶'phpunit/Runner/Filter/Group/Include.php‰·ÇT‹p»t¶'phpunit/Runner/Filter/Group/Exclude.php‰·ÇTøÎY¾¶phpunit/Runner/Filter/Group.php‰·ÇT¼!^i¶!phpunit/Runner/BaseTestRunner.php¬‰·ÇT¬a?g:¶"phpunit/Runner/TestSuiteLoader.php ‰·ÇT 5 b¶ phpunit/TextUI/ResultPrinter.phpÅ@‰·ÇTÅ@h:ùh¶phpunit/TextUI/TestRunner.php[”‰·ÇT[”s*‡ï¶phpunit/TextUI/Command.php¼y‰·ÇT¼yÌ÷ͽ¶phpunit/Exception.php”‰·ÇT”ü†¶$phpunit/Extensions/PhptTestSuite.phpL‰·ÇTLXgPp¶%phpunit/Extensions/TicketListener.php—‰·ÇT—Š“Bó¶$phpunit/Extensions/TestDecorator.phph +‰·ÇTh +Ϻ‰W¶#phpunit/Extensions/RepeatedTest.phpÎ +‰·ÇTÎ +Î2Uk¶%phpunit/Extensions/GroupTestSuite.php—‰·ÇT—òêͶ#phpunit/Extensions/PhptTestCase.phpD‰·ÇTD_ïR¶&phpunit/Framework/ExceptionWrapper.phpˆ ‰·ÇTˆ žøÂ¶¶!phpunit/Framework/TestFailure.php,‰·ÇT,ÅD0S¶phpunit/Framework/Test.php¯‰·ÇT¯òiKF¶phpunit/Framework/Error.phpJ‰·ÇTJðÛPá¶*phpunit/Framework/AssertionFailedError.php¡‰·ÇT¡zì&ÿ¶0phpunit/Framework/ExpectationFailedException.php¿‰·ÇT¿⊙Ÿ¶$phpunit/Framework/RiskyTestError.php)‰·ÇT)<˜D»¶.phpunit/Framework/InvalidCoversTargetError.phph‰·ÇTh6R›ª¶$phpunit/Framework/SelfDescribing.php<‰·ÇT<Äb“ݶphpunit/Framework/Assert.php‡‰·ÇT‡‡=Ž^¶(phpunit/Framework/IncompleteTestCase.php!‰·ÇT!ÉÆ†D¶&phpunit/Framework/Error/Deprecated.phpr‰·ÇTr%Ç»¶"phpunit/Framework/Error/Notice.php\‰·ÇT\”ä¶#phpunit/Framework/Error/Warning.php_‰·ÇT_ ‰÷'¶phpunit/Framework/Exception.phpF +‰·ÇTF +±Ò¬¶phpunit/Framework/RiskyTest.phpω·ÇTÏÊ,yd¶%phpunit/Framework/SkippedTestCase.php‰·ÇTŒÂW¶!phpunit/Framework/OutputError.php ‰·ÇT Ž'þg¶ phpunit/Framework/TestResult.phpo‰·ÇTow(Ý¿¶phpunit/Framework/TestSuite.php©r‰·ÇT©rNìgi¶+phpunit/Framework/CodeCoverageException.php—‰·ÇT—3Ͷ$phpunit/Framework/SyntheticError.phpA‰·ÇTA@]öæ¶+phpunit/Framework/SkippedTestSuiteError.php:‰·ÇT:“4i®¶&phpunit/Framework/BaseTestListener.php“‰·ÇT“.ØŠ¶)phpunit/Framework/IncompleteTestError.php9‰·ÇT9˜eõ¶&phpunit/Framework/SkippedTestError.php/‰·ÇT/¨§—þ¶(phpunit/Framework/Constraint/IsEqual.php€‰·ÇT€ÿ6¶1phpunit/Framework/Constraint/ExceptionMessage.phpv‰·ÇTvzÞ§¶,phpunit/Framework/Constraint/GreaterThan.php/‰·ÇT/“,Ðß¶'phpunit/Framework/Constraint/IsType.php/‰·ÇT/U×'·¶/phpunit/Framework/Constraint/StringContains.phpŸ‰·ÇTŸžÞ=Ŷ-phpunit/Framework/Constraint/IsInstanceOf.php! +‰·ÇT! +Y?›¤¶8phpunit/Framework/Constraint/ClassHasStaticAttribute.php剷ÇTåóæ‰B¶+phpunit/Framework/Constraint/IsAnything.phpB‰·ÇTBáë¼E¶Aphpunit/Framework/Constraint/JsonMatches/ErrorMessageProvider.phpȉ·ÇTÈ|q"ž¶$phpunit/Framework/Constraint/And.phpÿ ‰·ÇTÿ ƒ\)¶*phpunit/Framework/Constraint/Composite.php ‰·ÇT k°Ù¶1phpunit/Framework/Constraint/StringStartsWith.php.‰·ÇT.ÆV—'¶'phpunit/Framework/Constraint/IsNull.phpÙ‰·ÇTÙ˜ÿ_=¶3phpunit/Framework/Constraint/ObjectHasAttribute.php‰·ÇTp½´Ç¶+phpunit/Framework/Constraint/FileExists.php‰·ÇT€Áf¶,phpunit/Framework/Constraint/ArrayHasKey.php# ‰·ÇT# q{E¶2phpunit/Framework/Constraint/ClassHasAttribute.php& ‰·ÇT& ‡H¾‘¶#phpunit/Framework/Constraint/Or.php5 ‰·ÇT5 ÅΧ¼¶.phpunit/Framework/Constraint/ExceptionCode.php’‰·ÇT’HK}¶*phpunit/Framework/Constraint/Exception.php ‰·ÇT à¼í€¶,phpunit/Framework/Constraint/ArraySubset.phpm ‰·ÇTm ¼çÇ…¶&phpunit/Framework/Constraint/Count.phpX ‰·ÇTX 'm¯ý¶.phpunit/Framework/Constraint/StringMatches.php‡ +‰·ÇT‡ +6¯2¶/phpunit/Framework/Constraint/StringEndsWith.php?‰·ÇT?l6¼¶)phpunit/Framework/Constraint/SameSize.phpω·ÇTÏýonp¶'phpunit/Framework/Constraint/IsJson.php½‰·ÇT½â+¹¶7phpunit/Framework/Constraint/ExceptionMessageRegExp.phpމ·ÇTŽ?ïÙ6¶,phpunit/Framework/Constraint/JsonMatches.php>‰·ÇT>t r¶(phpunit/Framework/Constraint/IsEmpty.php‰‰·ÇT‰O–ñѶ*phpunit/Framework/Constraint/Attribute.phpj ‰·ÇTj A=qĶ8phpunit/Framework/Constraint/TraversableContainsOnly.php„ ‰·ÇT„ â¼gt¶(phpunit/Framework/Constraint/IsFalse.php݉·ÇTÝÓ¢i‘¶*phpunit/Framework/Constraint/PCREMatch.php%‰·ÇT%1ü휶$phpunit/Framework/Constraint/Not.phpÖ‰·ÇTÖÃO|Ѷ)phpunit/Framework/Constraint/Callback.php•‰·ÇT• +ø'“¶,phpunit/Framework/Constraint/IsIdentical.php¥‰·ÇT¥Ú&¶)phpunit/Framework/Constraint/LessThan.php&‰·ÇT&> ÀJ¶$phpunit/Framework/Constraint/Xor.php¨ ‰·ÇT¨ ²½B¶4phpunit/Framework/Constraint/TraversableContains.phpR‰·ÇTRáDì¶'phpunit/Framework/Constraint/IsTrue.phpÙ‰·ÇTÙD¿˜¶5phpunit/Framework/UnintentionallyCoveredCodeError.php-‰·ÇT-ó‹Ù±¶2phpunit/Framework/InvalidCoversTargetException.phpª‰·ÇTªú}Äζ&phpunit/Framework/Assert/Functions.phpŒû‰·ÇTŒû',Œ¶$phpunit/Framework/IncompleteTest.php‰·ÇT±Êûp¶ phpunit/Framework/Constraint.php…‰·ÇT…âñc¶,phpunit/Framework/TestSuite/DataProvider.php¹‰·ÇT¹ +Š2¶"phpunit/Framework/TestListener.phps ‰·ÇTs ý@S¶!phpunit/Framework/SkippedTest.php´‰·ÇT´!÷BŸ¶phpunit/Framework/Warning.php剷ÇTå7£þ¶phpunit/Framework/TestCase.php“뉷ÇT“ëh-q ¶phpunit/Util/PHP/Default.php艷ÇTèZµoþ¶phpunit/Util/PHP/Windows.php™ ‰·ÇT™ ^¤ñ¶1phpunit/Util/PHP/Template/TestCaseMethod.tpl.dist6‰·ÇT6+}ÕV¶phpunit/Util/Test.phps{‰·ÇTs{W¢PU¶&phpunit/Util/TestDox/ResultPrinter.php‚!‰·ÇT‚!Gõ™Ø¶'phpunit/Util/TestDox/NamePrettifier.phpw ‰·ÇTw ¸$™|¶+phpunit/Util/TestDox/ResultPrinter/Text.php¢‰·ÇT¢IVz¶+phpunit/Util/TestDox/ResultPrinter/HTML.php鉷ÇTé+ =¶phpunit/Util/String.php˜‰·ÇT˜µl"ß¶&phpunit/Util/InvalidArgumentHelper.php¯‰·ÇT¯µ©¶phpunit/Util/Fileloader.phpò‰·ÇTòTS¶phpunit/Util/PHP.php•‰·ÇT•¢ê:’¶"phpunit/Util/TestSuiteIterator.phpX ‰·ÇTX ÷8¤Ä¶phpunit/Util/Type.php)‰·ÇT)_ûž¶phpunit/Util/Filesystem.phpª‰·ÇTª£•a¶phpunit/Util/Regex.phpó‰·ÇTó=g¾¥¶phpunit/Util/Blacklist.phpB ‰·ÇTB l_Kضphpunit/Util/XML.php w‰·ÇT w»x1¶phpunit/Util/Printer.phpl‰·ÇTl%ͪ¶phpunit/Util/Getopt.php¯‰·ÇT¯‡Ê´1¶phpunit/Util/ErrorHandler.php¨‰·ÇT¨ê¼¶/¶phpunit/Util/Filter.phpâ ‰·ÇTâ …c³0¶phpunit/Util/Log/JUnit.phpd5‰·ÇTd5çA1Ú¶phpunit/Util/Log/TAP.phpþ‰·ÇTþ©ËÞ¶phpunit/Util/Log/JSON.phpÇTïf'ª—¶phpunit/Util/GlobalState.phpE‰·ÇTE€qÙжphpunit/Util/Configuration.phpM„‰·ÇTM„?œ¯ñ¶7phpunit-mock-objects/Framework/MockObject/Invokable.php ‰·ÇT ©]î¶Nphpunit-mock-objects/Framework/MockObject/Exception/BadMethodCallException.phpø ‰·ÇTø ƒv­ë¶Aphpunit-mock-objects/Framework/MockObject/Exception/Exception.phpÝ ‰·ÇTÝ 1þIš¶Hphpunit-mock-objects/Framework/MockObject/Exception/RuntimeException.phpì ‰·ÇTì ’úþa¶2phpunit-mock-objects/Framework/MockObject/Stub.php½ ‰·ÇT½ YÎþ¦¶>phpunit-mock-objects/Framework/MockObject/InvocationMocker.php{‰·ÇT{hò÷…¶?phpunit-mock-objects/Framework/MockObject/Invocation/Object.php ‰·ÇT a»|¶?phpunit-mock-objects/Framework/MockObject/Invocation/Static.phpt‰·ÇTtüñ>g¶9phpunit-mock-objects/Framework/MockObject/MockBuilder.php%‰·ÇT% +£d¶Ephpunit-mock-objects/Framework/MockObject/Builder/MethodNameMatch.phpŠ ‰·ÇTŠ ‚Ãß¶:phpunit-mock-objects/Framework/MockObject/Builder/Stub.phpÐ ‰·ÇTÐ t ¤¶Fphpunit-mock-objects/Framework/MockObject/Builder/InvocationMocker.phpÁ$‰·ÇTÁ$p +žO¶;phpunit-mock-objects/Framework/MockObject/Builder/Match.php¸ ‰·ÇT¸ „Ú‚‚¶Ephpunit-mock-objects/Framework/MockObject/Builder/ParametersMatch.phpa‰·ÇTa#$ ¶?phpunit-mock-objects/Framework/MockObject/Builder/Namespace.php‰·ÇTäca¶>phpunit-mock-objects/Framework/MockObject/Builder/Identity.phpõ ‰·ÇTõ N¹ts¶Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnValueMap.phpâ ‰·ÇTâ #j{5¶Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnCallback.phpó ‰·ÇTó åÝ'Þ¶<phpunit-mock-objects/Framework/MockObject/Stub/Exception.phpX ‰·ÇTX È>n¶9phpunit-mock-objects/Framework/MockObject/Stub/Return.php½ ‰·ÇT½ šº¥¶=phpunit-mock-objects/Framework/MockObject/Stub/ReturnSelf.php ‰·ÇT ¿Ã¶Aphpunit-mock-objects/Framework/MockObject/Stub/ReturnArgument.phpe ‰·ÇTe žMà#¶Cphpunit-mock-objects/Framework/MockObject/Stub/ConsecutiveCalls.php ‰·ÇT ƒ#Õ|¶Dphpunit-mock-objects/Framework/MockObject/Stub/MatcherCollection.php› ‰·ÇT› † ¶Ephpunit-mock-objects/Framework/MockObject/Matcher/InvokedRecorder.phpˉ·ÇTË; =P¶@phpunit-mock-objects/Framework/MockObject/Matcher/MethodName.phpB‰·ÇTB‰`5h¶Dphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtIndex.phpu‰·ÇTuÀa ¬¶Iphpunit-mock-objects/Framework/MockObject/Matcher/StatelessInvocation.php̉·ÇTÌ”7g¶Hphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtMostCount.phpZ‰·ÇTZ]èýǶBphpunit-mock-objects/Framework/MockObject/Matcher/InvokedCount.phpò‰·ÇTò9ûš2¶@phpunit-mock-objects/Framework/MockObject/Matcher/Invocation.phpe‰·ÇTe̸•ì¶Iphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastCount.phpe‰·ÇTeìFkr¶Ephpunit-mock-objects/Framework/MockObject/Matcher/AnyInvokedCount.phpA ‰·ÇTA tÀM8¶Cphpunit-mock-objects/Framework/MockObject/Matcher/AnyParameters.php§ ‰·ÇT§ aéh¶Hphpunit-mock-objects/Framework/MockObject/Matcher/InvokedAtLeastOnce.php/ ‰·ÇT/ mrÙŽ¶Kphpunit-mock-objects/Framework/MockObject/Matcher/ConsecutiveParameters.phpõ‰·ÇTõNÇ[Õ¶@phpunit-mock-objects/Framework/MockObject/Matcher/Parameters.phpÙ‰·ÇTÙê1 Ë¶5phpunit-mock-objects/Framework/MockObject/Matcher.php·(‰·ÇT·(äL†õ¶7phpunit-mock-objects/Framework/MockObject/Generator.phpö—‰·ÇTö—­ÿ~`¶8phpunit-mock-objects/Framework/MockObject/Invocation.phpî ‰·ÇTî ‰a?¶Pphpunit-mock-objects/Framework/MockObject/Generator/mocked_class_method.tpl.dist퉷ÇTíÚ4Þ¶Hphpunit-mock-objects/Framework/MockObject/Generator/wsdl_method.tpl.dist<‰·ÇT<¾Ði‰¶Hphpunit-mock-objects/Framework/MockObject/Generator/trait_class.tpl.dist7‰·ÇT7²[$~¶Jphpunit-mock-objects/Framework/MockObject/Generator/mocked_method.tpl.dist„‰·ÇT„ãbVæ¶Kphpunit-mock-objects/Framework/MockObject/Generator/unmocked_clone.tpl.distŸ‰·ÇTŸ8W}ضIphpunit-mock-objects/Framework/MockObject/Generator/mocked_class.tpl.dist ‰·ÇT ¨ÑFZ¶Qphpunit-mock-objects/Framework/MockObject/Generator/mocked_static_method.tpl.dist—‰·ÇT—+F°ƒ¶Gphpunit-mock-objects/Framework/MockObject/Generator/wsdl_class.tpl.dist³‰·ÇT³w&S¶Kphpunit-mock-objects/Framework/MockObject/Generator/proxied_method.tpl.dist̉·ÇTÌ?a§¶Iphpunit-mock-objects/Framework/MockObject/Generator/mocked_clone.tpl.dist„‰·ÇT„œaT¶8phpunit-mock-objects/Framework/MockObject/MockObject.phpE‰·ÇTE‚jQq¶8phpunit-mock-objects/Framework/MockObject/Verifiable.php ‰·ÇT &n¶phpunit-mock-objects/LICENSE‰·ÇT¢«‘½¶7phpunit-selenium/Extensions/SeleniumTestCase/Driver.phpM°‰·ÇTM°0âR¶:phpunit-selenium/Extensions/SeleniumCommon/ExitHandler.php*‰·ÇT*¢èÏ϶6phpunit-selenium/Extensions/SeleniumCommon/prepend.php? ‰·ÇT? °·³¶?phpunit-selenium/Extensions/SeleniumCommon/phpunit_coverage.php`‰·ÇT`½ùOm¶5phpunit-selenium/Extensions/SeleniumCommon/append.php ‰·ÇT ›·ú÷¶=phpunit-selenium/Extensions/SeleniumCommon/RemoteCoverage.phpI‰·ÇTIÝ\´.¶Aphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy.php¡ ‰·ÇT¡ ̳ãr¶Fphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Click.php» ‰·ÇT» ^ÿaé¶Ephpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/File.php艷ÇTè0“ß—¶Dphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Url.php ‰·ÇT K¸Ž¶Mphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/DismissAlert.php6 +‰·ÇT6 +Ñv’l¶Ephpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Keys.php$‰·ÇT$wîͶIphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Location.phpÏ ‰·ÇTÏ ô¡Ë ¶Qphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAttribute.phpŸ +‰·ÇTŸ +›Bí¶Gphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/MoveTo.phpΉ·ÇTΣ- +¶Gphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Active.php + ‰·ÇT + ×6¸¶Pphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/GenericAccessor.phpT +‰·ÇTT +X·ì¶Gphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Window.phpÜ +‰·ÇTÜ +•ˆ’¶Lphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AcceptAlert.php1 +‰·ÇT1 +BHǶFphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Frame.php¶ ‰·ÇT¶ çz"¶Lphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Orientation.phpÞ ‰·ÇTÞ @\WI¶Jphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/AlertText.phpC ‰·ÇTC lXim¶Dphpunit-selenium/Extensions/Selenium2TestCase/SessionCommand/Log.php ‰·ÇT œð"=¶9phpunit-selenium/Extensions/Selenium2TestCase/Command.phpL ‰·ÇTL ÎcyƶAphpunit-selenium/Extensions/Selenium2TestCase/ElementCriteria.phpN ‰·ÇTN ʶHphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Shared.phpH‰·ÇTHÚVm’¶Jphpunit-selenium/Extensions/Selenium2TestCase/SessionStrategy/Isolated.php’ ‰·ÇT’ ìͶFphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Click.php+ +‰·ÇT+ +¡Ä»¶Dphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Css.phpi ‰·ÇTi ó¶Pphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericAccessor.phpi +‰·ÇTi +•Pe¶Jphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Attribute.phpt ‰·ÇTt  ˈ¶Gphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Equals.php` ‰·ÇT` Én±Õ¶Fphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/Value.phpG ‰·ÇTG +Uç¶Lphpunit-selenium/Extensions/Selenium2TestCase/ElementCommand/GenericPost.phpW +‰·ÇTW +ëLq¶Dphpunit-selenium/Extensions/Selenium2TestCase/WebDriverException.phpf ‰·ÇTf ÍK1ï¶@phpunit-selenium/Extensions/Selenium2TestCase/CommandsHolder.phpˉ·ÇTËZew¶6phpunit-selenium/Extensions/Selenium2TestCase/Keys.phpI‰·ÇTIî†Í¶Bphpunit-selenium/Extensions/Selenium2TestCase/Element/Accessor.php¯‰·ÇT¯û\w€¶@phpunit-selenium/Extensions/Selenium2TestCase/Element/Select.php­‰·ÇT­ëL@"¶8phpunit-selenium/Extensions/Selenium2TestCase/Driver.phpщ·ÇTÑeÅ5v¶;phpunit-selenium/Extensions/Selenium2TestCase/Exception.phpã ‰·ÇTã H"Ç[¶;phpunit-selenium/Extensions/Selenium2TestCase/WaitUntil.php”‰·ÇT”z“¶Dphpunit-selenium/Extensions/Selenium2TestCase/ScreenshotListener.php؉·ÇTØh­7ǶEphpunit-selenium/Extensions/Selenium2TestCase/NoSeleniumException.phpÅ ‰·ÇTÅ Ûök¶Aphpunit-selenium/Extensions/Selenium2TestCase/Session/Storage.php8 ‰·ÇT8 ›‚º¶Bphpunit-selenium/Extensions/Selenium2TestCase/Session/Timeouts.php]‰·ÇT]œ/X¶@phpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie.phpý‰·ÇTý$!¸–¶Hphpunit-selenium/Extensions/Selenium2TestCase/Session/Cookie/Builder.php‰·ÇTÓ¸q¶<phpunit-selenium/Extensions/Selenium2TestCase/KeysHolder.php‰·ÇTÑ|ÚH¶8phpunit-selenium/Extensions/Selenium2TestCase/Window.phpO ‰·ÇTO S§ßô¶9phpunit-selenium/Extensions/Selenium2TestCase/Element.php ‰·ÇT &éø¶9phpunit-selenium/Extensions/Selenium2TestCase/Session.php!1‰·ÇT!1š ™¶:phpunit-selenium/Extensions/Selenium2TestCase/Response.php‰·ÇTTZ¶>phpunit-selenium/Extensions/Selenium2TestCase/StateCommand.phpw +‰·ÇTw + e3Z¶5phpunit-selenium/Extensions/Selenium2TestCase/URL.php™‰·ÇT™HFž¶0phpunit-selenium/Extensions/SeleniumTestCase.phpÀ—‰·ÇTÀ—ÃvK¶1phpunit-selenium/Extensions/Selenium2TestCase.php!E‰·ÇT!Eï[‘ñ¶1phpunit-selenium/Extensions/SeleniumTestSuite.php‰·ÇT®šä¶4phpunit-selenium/Extensions/SeleniumBrowserSuite.phpò‰·ÇTòD³¥¶Rdoctrine-instantiator/Doctrine/Instantiator/Exception/UnexpectedValueException.phpÎ +‰·ÇTÎ +"Ÿè ¶Rdoctrine-instantiator/Doctrine/Instantiator/Exception/InvalidArgumentException.phpô‰·ÇTôhÅ7I¶Ldoctrine-instantiator/Doctrine/Instantiator/Exception/ExceptionInterface.php¥‰·ÇT¥ó.ðö<doctrine-instantiator/Doctrine/Instantiator/Instantiator.phpʉ·ÇTÊX˜¢¶Edoctrine-instantiator/Doctrine/Instantiator/InstantiatorInterface.php~‰·ÇT~¶ÿÌ:¶doctrine-instantiator/LICENSE$‰·ÇT$ +Í‚å¶'php-code-coverage/CodeCoverage/Util.php‰·ÇT¥§ŠÌ¶Gphp-code-coverage/CodeCoverage/Exception/UnintentionallyCoveredCode.php‰·ÇT¥Kë¶.php-code-coverage/CodeCoverage/Report/Text.phpq"‰·ÇTq".}Ôi¶.php-code-coverage/CodeCoverage/Report/HTML.php‰·ÇTˆ¹j¶7php-code-coverage/CodeCoverage/Report/HTML/Renderer.phpÛ‰·ÇTÛ»méC¶<php-code-coverage/CodeCoverage/Report/HTML/Renderer/File.php\I‰·ÇT\I#p“ɶAphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Dashboard.php (‰·ÇT (ýßý¶Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file_item.html.distg‰·ÇTgV³ P¶Nphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/respond.min.js‰·ÇTí{¶Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/html5shiv.min.jsL +‰·ÇTL +F¨¶Lphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/nv.d3.min.js‘߉·ÇT‘ßKˆ¹&¶Iphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/d3.min.js`<‰·ÇT`<užå¶Iphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/holder.jsࣉ·ÇTà£Y{š0¶Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/bootstrap.min.js|Љ·ÇT|Š„w¶Mphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/js/jquery.min.js»v‰·ÇT»voY‚¶Uphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory_item.html.dist5‰·ÇT5ñZˆ]¶Kphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/file.html.distú +‰·ÇTú +Oé¶Rphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/method_item.html.distx‰·ÇTx*öŒ¶Pphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/dashboard.html.distc‰·ÇTcõ˜ܶPphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/directory.html.dista‰·ÇTazd›E¶cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.ttf\±‰·ÇT\±š<œ¶cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.eotŸN‰·ÇTŸNXDZœ¶cphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.svg¨‰·ÇT¨|îÆÉ¶ephp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff2lF‰·ÇTlFvèÃa¶dphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/fonts/glyphicons-halflings-regular.woff€[‰·ÇT€[ê{õ¶Sphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/coverage_bar.html.dist1‰·ÇT1itLì¶Jphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/nv.d3.css#2‰·ÇT#2 b¶Jphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/style.css ‰·ÇT MR#€¶Rphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Template/css/bootstrap.min.cssžÉ‰·ÇTžÉ†& «¶Aphp-code-coverage/CodeCoverage/Report/HTML/Renderer/Directory.phpÀ‰·ÇTÀÒi‚¶3php-code-coverage/CodeCoverage/Report/XML/Tests.php´‰·ÇT´:Ž=7¶2php-code-coverage/CodeCoverage/Report/XML/File.php)‰·ÇT)òŠ£t¶4php-code-coverage/CodeCoverage/Report/XML/Totals.php‡‰·ÇT‡†3çÁ¶2php-code-coverage/CodeCoverage/Report/XML/Node.phpo ‰·ÇTo ~,ŠÔ¶9php-code-coverage/CodeCoverage/Report/XML/File/Method.php²‰·ÇT²6Þ¶7php-code-coverage/CodeCoverage/Report/XML/File/Unit.php/ ‰·ÇT/ ]…#¶9php-code-coverage/CodeCoverage/Report/XML/File/Report.phpT‰·ÇTT±~½¶;php-code-coverage/CodeCoverage/Report/XML/File/Coverage.phpr‰·ÇTrT(Ë=¶5php-code-coverage/CodeCoverage/Report/XML/Project.phpj‰·ÇTjmH= +¶7php-code-coverage/CodeCoverage/Report/XML/Directory.phpƉ·ÇTÆÎOo¾¶1php-code-coverage/CodeCoverage/Report/Factory.phpS‰·ÇTS‡§ÆÄ¶0php-code-coverage/CodeCoverage/Report/Crap4j.php‰·ÇT‘`¹¶0php-code-coverage/CodeCoverage/Report/Clover.php)‰·ÇT)†ÿAŶ-php-code-coverage/CodeCoverage/Report/PHP.phpm‰·ÇTmLé^z¶.php-code-coverage/CodeCoverage/Report/Node.php[‰·ÇT[¹Z•¶7php-code-coverage/CodeCoverage/Report/Node/Iterator.php +‰·ÇT +ŒªIµ¶3php-code-coverage/CodeCoverage/Report/Node/File.phpDI‰·ÇTDI7¤û¶8php-code-coverage/CodeCoverage/Report/Node/Directory.php¥)‰·ÇT¥)y‡¶-php-code-coverage/CodeCoverage/Report/XML.phpu‰·ÇTu‹f”¶.php-code-coverage/CodeCoverage/Driver/HHVM.phpp‰·ÇTpþض manifest.txt‰·ÇT˜Dx\¶sebastian-version/Version.php ‰·ÇT O>¶sebastian-version/LICENSE‰·ÇTåûœ ¶!sebastian-environment/Console.php†‰·ÇT†šXç¶sebastian-environment/LICENSE‰·ÇTiV”¶!sebastian-environment/Runtime.php‰·ÇT´j°¶ca.pemÈ +‰·ÇTÈ +sÓñ޶'sebastian-recursion-context/Context.php°‰·ÇT°ø¿Nê¶)sebastian-recursion-context/Exception.phpˆ‰·ÇTˆ>å™3¶8sebastian-recursion-context/InvalidArgumentException.phpЉ·ÇTÐÊ ¨ú¶#sebastian-recursion-context/LICENSE‰·ÇTÉðζ.symfony/yaml/Symfony/Component/Yaml/Inline.phpL‰·ÇTL2Õ1ý¶@symfony/yaml/Symfony/Component/Yaml/Exception/ParseException.php‰·ÇTÎ79‹¶?symfony/yaml/Symfony/Component/Yaml/Exception/DumpException.phpÒ‰·ÇTÒؙ՚¶Dsymfony/yaml/Symfony/Component/Yaml/Exception/ExceptionInterface.phpƉ·ÇTÆî+­l¶Bsymfony/yaml/Symfony/Component/Yaml/Exception/RuntimeException.phpð‰·ÇTðÏ|-¶.symfony/yaml/Symfony/Component/Yaml/Dumper.php ‰·ÇT l£D¶,symfony/yaml/Symfony/Component/Yaml/Yaml.php ‰·ÇT .|m9¶1symfony/yaml/Symfony/Component/Yaml/Unescaper.php—‰·ÇT—‰ 6ä¶.symfony/yaml/Symfony/Component/Yaml/Parser.phph‰·ÇThÞ±¶/symfony/yaml/Symfony/Component/Yaml/Escaper.phpv ‰·ÇTv 5Ùñd¶symfony/LICENSE)‰·ÇT)ë&•¶#sebastian-global-state/Snapshot.php',‰·ÇT',5+å ¶$sebastian-global-state/Exception.phpþ‰·ÇTþ ª„´¶$sebastian-global-state/Blacklist.php#‰·ÇT#Òf1“¶sebastian-global-state/LICENSE +‰·ÇT +êâ¶#sebastian-global-state/Restorer.phpž‰·ÇTž­}FÔ¶+sebastian-global-state/RuntimeException.php0 ‰·ÇT0 Èyv¶4dbunit/Extensions/Database/IDatabaseListConsumer.phpA +‰·ÇTA +SÀžÓ¶1dbunit/Extensions/Database/DataSet/XmlDataSet.phpþ‰·ÇTþLNȶ5dbunit/Extensions/Database/DataSet/FlatXmlDataSet.phpV‰·ÇTV¾N@Ô¶:dbunit/Extensions/Database/DataSet/TableMetaDataFilter.php*‰·ÇT* +ƒæÛ¶1dbunit/Extensions/Database/DataSet/QueryTable.php‰·ÇTŸ!û¶7dbunit/Extensions/Database/DataSet/CompositeDataSet.php£‰·ÇT£N±=¶1dbunit/Extensions/Database/DataSet/CsvDataSet.php؉·ÇTØ/Í0(¶4dbunit/Extensions/Database/DataSet/DataSetFilter.php‰·ÇT_Æ´¶;dbunit/Extensions/Database/DataSet/DefaultTableIterator.php¤‰·ÇT¤êç“r¶;dbunit/Extensions/Database/DataSet/DefaultTableMetaData.php¢ ‰·ÇT¢ ޱ â¶1dbunit/Extensions/Database/DataSet/Specs/Yaml.php³ ‰·ÇT³ SD\¶0dbunit/Extensions/Database/DataSet/Specs/Csv.phpa‰·ÇTaš=Kj¶4dbunit/Extensions/Database/DataSet/Specs/Factory.php¿ ‰·ÇT¿ Ÿ>3¶4dbunit/Extensions/Database/DataSet/Specs/FlatXml.phpÇ ‰·ÇTÇ .°ý¶4dbunit/Extensions/Database/DataSet/Specs/DbTable.php„‰·ÇT„¹®J¶4dbunit/Extensions/Database/DataSet/Specs/DbQuery.php߉·ÇTß5vƒ¶0dbunit/Extensions/Database/DataSet/Specs/Xml.php­ ‰·ÇT­ Å)5T¶5dbunit/Extensions/Database/DataSet/Specs/IFactory.phpQ +‰·ÇTQ +fý‡¶7dbunit/Extensions/Database/DataSet/ReplacementTable.php3‰·ÇT3`½è—¶9dbunit/Extensions/Database/DataSet/ReplacementDataSet.php`‰·ÇT`Ö„¢¶2dbunit/Extensions/Database/DataSet/IYamlParser.php× ‰·ÇT× Cp¶¶6dbunit/Extensions/Database/DataSet/MysqlXmlDataSet.php/‰·ÇT/¢8o¶,dbunit/Extensions/Database/DataSet/ISpec.php‰ +‰·ÇT‰ +ÀfC¶5dbunit/Extensions/Database/DataSet/DefaultDataSet.php— ‰·ÇT— äkr­¶<dbunit/Extensions/Database/DataSet/AbstractTableMetaData.php艷ÇTèáõáè¶5dbunit/Extensions/Database/DataSet/ITableMetaData.php8 ‰·ÇT8 ÌqjY¶/dbunit/Extensions/Database/DataSet/IDataSet.phpÐ ‰·ÇTÐ -»oB¶6dbunit/Extensions/Database/DataSet/AbstractDataSet.php©‰·ÇT©À[9é¶4dbunit/Extensions/Database/DataSet/AbstractTable.phpW!‰·ÇTW!ê|ì¶9dbunit/Extensions/Database/DataSet/AbstractXmlDataSet.phpt‰·ÇTt3Ì!¶3dbunit/Extensions/Database/DataSet/QueryDataSet.phpo‰·ÇTo1ËГ¶3dbunit/Extensions/Database/DataSet/DefaultTable.php„‰·ÇT„2éÏF¶5dbunit/Extensions/Database/DataSet/ITableIterator.php + ‰·ÇT + "éh¶¶:dbunit/Extensions/Database/DataSet/Persistors/MysqlXml.phpĉ·ÇTÄfø]-¶6dbunit/Extensions/Database/DataSet/Persistors/Yaml.php퉷ÇTín›¶:dbunit/Extensions/Database/DataSet/Persistors/Abstract.phpó‰·ÇTóÂ7‰¶9dbunit/Extensions/Database/DataSet/Persistors/Factory.phpµ‰·ÇTµ[Ñ̶9dbunit/Extensions/Database/DataSet/Persistors/FlatXml.phpj‰·ÇTj_©µ¿¶5dbunit/Extensions/Database/DataSet/Persistors/Xml.php‰·ÇTw:—à¶-dbunit/Extensions/Database/DataSet/ITable.php ‰·ÇT 9ж3dbunit/Extensions/Database/DataSet/IPersistable.php” +‰·ÇT” +—ò¶2dbunit/Extensions/Database/DataSet/YamlDataSet.php‰·ÇT¸L«¶?dbunit/Extensions/Database/DataSet/ReplacementTableIterator.php‰·ÇTB! ¶8dbunit/Extensions/Database/DataSet/SymfonyYamlParser.php +‰·ÇT +n| ¶2dbunit/Extensions/Database/DataSet/TableFilter.php㉷ÇTãš*E¶(dbunit/Extensions/Database/Exception.php +‰·ÇT +x +¦!¶8dbunit/Extensions/Database/Constraint/DataSetIsEqual.phpr‰·ÇTr‡T(¶7dbunit/Extensions/Database/Constraint/TableRowCount.phpc ‰·ÇTc À+/¶6dbunit/Extensions/Database/Constraint/TableIsEqual.phpd‰·ÇTdNjÊǶ/dbunit/Extensions/Database/Operation/Update.php§‰·ÇT§û„°¶2dbunit/Extensions/Database/Operation/Composite.php‰·ÇT9$ –¶/dbunit/Extensions/Database/Operation/Insert.phpÙ‰·ÇTÙÿ»¼—¶0dbunit/Extensions/Database/Operation/Factory.php¸‰·ÇT¸®t¶1dbunit/Extensions/Database/Operation/Truncate.php¾ ‰·ÇT¾ ÿèp¶2dbunit/Extensions/Database/Operation/Exception.phpʉ·ÇTÊüû¶0dbunit/Extensions/Database/Operation/Replace.phpf‰·ÇTf8w@¶-dbunit/Extensions/Database/Operation/Null.php” +‰·ÇT” + I9¶1dbunit/Extensions/Database/Operation/RowBased.php*‰·ÇT*+*Ò¶/dbunit/Extensions/Database/Operation/Delete.php‰·ÇTµ2_Ͷ;dbunit/Extensions/Database/Operation/IDatabaseOperation.phpÓ ‰·ÇTÓ ÈÛÇf¶2dbunit/Extensions/Database/Operation/DeleteAll.php¢ ‰·ÇT¢ lÇØ+¶-dbunit/Extensions/Database/AbstractTester.php$‰·ÇT$éQ…²¶'dbunit/Extensions/Database/UI/IMode.php½ +‰·ÇT½ +Öû¶¶-dbunit/Extensions/Database/UI/ModeFactory.php)‰·ÇT)X›ªõ¶)dbunit/Extensions/Database/UI/Command.phpR ‰·ÇTR ûˆ!B¶6dbunit/Extensions/Database/UI/InvalidModeException.phpÌ ‰·ÇTÌ –Œ× ¶0dbunit/Extensions/Database/UI/IMediumPrinter.php¯ +‰·ÇT¯ +¨à²¶.dbunit/Extensions/Database/UI/IModeFactory.phpô +‰·ÇTô +ƒF¶$¶*dbunit/Extensions/Database/DB/MetaData.phpL ‰·ÇTL ÿ!‰!¶+dbunit/Extensions/Database/DB/IMetaData.php6‰·ÇT6”v÷i¶)dbunit/Extensions/Database/DB/DataSet.php݉·ÇTÝ`­Wk¶0dbunit/Extensions/Database/DB/MetaData/MySQL.phpÖ‰·ÇTÖŠƒ±0¶1dbunit/Extensions/Database/DB/MetaData/SqlSrv.php–‰·ÇT–Ó0 û¶<dbunit/Extensions/Database/DB/MetaData/InformationSchema.phpt‰·ÇTtŽÈö1dbunit/Extensions/Database/DB/MetaData/Sqlite.php>‰·ÇT>=^Ù¶0dbunit/Extensions/Database/DB/MetaData/Dblib.php ‰·ÇT {Ú§¶0dbunit/Extensions/Database/DB/MetaData/PgSQL.php¿‰·ÇT¿•¸gĶ.dbunit/Extensions/Database/DB/MetaData/Oci.phpV‰·ÇTV¥+ E¶3dbunit/Extensions/Database/DB/MetaData/Firebird.php㉷ÇTãBùËp¶/dbunit/Extensions/Database/DB/TableIterator.phpЉ·ÇTŠÁl€­¶1dbunit/Extensions/Database/DB/FilteredDataSet.phpM ‰·ÇTM ¾ç¶;dbunit/Extensions/Database/DB/DefaultDatabaseConnection.php ‰·ÇT ʉ1¶5dbunit/Extensions/Database/DB/IDatabaseConnection.php”‰·ÇT”ò‹Dà¶/dbunit/Extensions/Database/DB/TableMetaData.php ‰·ÇT —K«¶'dbunit/Extensions/Database/DB/Table.php© ‰·ÇT© ûŒs5¶0dbunit/Extensions/Database/DB/ResultSetTable.phpé ‰·ÇTé È[×¶&dbunit/Extensions/Database/ITester.phpª‰·ÇTªÒÌøo¶,dbunit/Extensions/Database/DefaultTester.php¯ ‰·ÇT¯ ‰°: ¶'dbunit/Extensions/Database/TestCase.php(%‰·ÇT(%s¦Èë¶*sebastian-comparator/NumericComparator.phpA‰·ÇTAÏËÒÛ¶(sebastian-comparator/ArrayComparator.phpB‰·ÇTB§j¼‚¶ sebastian-comparator/Factory.phpU‰·ÇTU6‚Gȶ)sebastian-comparator/DoubleComparator.phpœ‰·ÇTœ¸O¯¶*sebastian-comparator/DOMNodeComparator.phpø‰·ÇTø*¸¶,sebastian-comparator/ExceptionComparator.phpÒ ‰·ÇTÒ €‡¶'sebastian-comparator/TypeComparator.php ‰·ÇT œãõž¶-sebastian-comparator/MockObjectComparator.phpµ ‰·ÇTµ *í)+¶+sebastian-comparator/ResourceComparator.phpV‰·ÇTVõ ”û¶*sebastian-comparator/ComparisonFailure.phpʉ·ÇTÊ "Ò¶#sebastian-comparator/Comparator.phpΉ·ÇTÎç6¶)sebastian-comparator/ObjectComparator.phpú‰·ÇTú‚t¥¶+sebastian-comparator/DateTimeComparator.phpZ‰·ÇTZ@Cp®¶3sebastian-comparator/SplObjectStorageComparator.php‰·ÇTɲ϶)sebastian-comparator/ScalarComparator.php›‰·ÇT›_Éë¶¶sebastian-comparator/LICENSE ‰·ÇT u‰¸¶php-text-template/Template.phpð‰·ÇTðí;$¶php-text-template/LICENSE ‰·ÇT ²d¸è¶. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHP + * @subpackage Invoker + * @author Sebastian Bergmann + * @copyright 2011-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/php-invoker + * @since File available since Release 1.0.0 + */ + +/** + * Utility class for invoking callables with a timeout. + * + * @package PHP + * @subpackage Invoker + * @author Sebastian Bergmann + * @copyright 2011-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-invoker + * @since Class available since Release 1.0.0 + */ +class PHP_Invoker +{ + /** + * @var integer + */ + protected $timeout; + + /** + * Invokes a callable and raises an exception when the execution does not + * finish before the specified timeout. + * + * @param callable $callable + * @param array $arguments + * @param integer $timeout in seconds + * @return mixed + * @throws InvalidArgumentException + */ + public function invoke($callable, array $arguments, $timeout) + { + if (!is_callable($callable)) { + throw new InvalidArgumentException; + } + + if (!is_integer($timeout)) { + throw new InvalidArgumentException; + } + + pcntl_signal(SIGALRM, array($this, 'callback'), TRUE); + pcntl_alarm($timeout); + + $this->timeout = $timeout; + + try { + $result = call_user_func_array($callable, $arguments); + } + + catch (Exception $e) { + pcntl_alarm(0); + throw $e; + } + + pcntl_alarm(0); + + return $result; + } + + /** + * Invoked by pcntl_signal() when a SIGALRM occurs. + */ + public function callback() + { + throw new PHP_Invoker_TimeoutException( + sprintf( + 'Execution aborted after %s', + PHP_Timer::secondsToTimeString($this->timeout) + ) + ); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHP + * @subpackage Invoker + * @author Sebastian Bergmann + * @copyright 2011-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/php-invoker + * @since File available since Release 1.0.0 + */ + +/** + * @package PHP + * @subpackage Invoker + * @author Sebastian Bergmann + * @copyright 2011-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-invoker + * @since Class available since Release 1.0.0 + */ +class PHP_Invoker_TimeoutException extends RuntimeException +{ +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package File + * @author Sebastian Bergmann + * @copyright 2009-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @since File available since Release 1.0.0 + */ + +/** + * FilterIterator implementation that filters files based on prefix(es) and/or + * suffix(es). Hidden files and files from hidden directories are also filtered. + * + * @author Sebastian Bergmann + * @copyright 2009-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-file-iterator/tree + * @since Class available since Release 1.0.0 + */ +class File_Iterator extends FilterIterator +{ + const PREFIX = 0; + const SUFFIX = 1; + + /** + * @var array + */ + protected $suffixes = array(); + + /** + * @var array + */ + protected $prefixes = array(); + + /** + * @var array + */ + protected $exclude = array(); + + /** + * @var string + */ + protected $basepath; + + /** + * @param Iterator $iterator + * @param array $suffixes + * @param array $prefixes + * @param array $exclude + * @param string $basepath + */ + public function __construct(Iterator $iterator, array $suffixes = array(), array $prefixes = array(), array $exclude = array(), $basepath = NULL) + { + $exclude = array_filter(array_map('realpath', $exclude)); + + if ($basepath !== NULL) { + $basepath = realpath($basepath); + } + + if ($basepath === FALSE) { + $basepath = NULL; + } else { + foreach ($exclude as &$_exclude) { + $_exclude = str_replace($basepath, '', $_exclude); + } + } + + $this->prefixes = $prefixes; + $this->suffixes = $suffixes; + $this->exclude = $exclude; + $this->basepath = $basepath; + + parent::__construct($iterator); + } + + /** + * @return boolean + */ + public function accept() + { + $current = $this->getInnerIterator()->current(); + $filename = $current->getFilename(); + $realpath = $current->getRealPath(); + + if ($this->basepath !== NULL) { + $realpath = str_replace($this->basepath, '', $realpath); + } + + // Filter files in hidden directories. + if (preg_match('=/\.[^/]*/=', $realpath)) { + return FALSE; + } + + return $this->acceptPath($realpath) && + $this->acceptPrefix($filename) && + $this->acceptSuffix($filename); + } + + /** + * @param string $path + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptPath($path) + { + foreach ($this->exclude as $exclude) { + if (strpos($path, $exclude) === 0) { + return FALSE; + } + } + + return TRUE; + } + + /** + * @param string $filename + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptPrefix($filename) + { + return $this->acceptSubString($filename, $this->prefixes, self::PREFIX); + } + + /** + * @param string $filename + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptSuffix($filename) + { + return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX); + } + + /** + * @param string $filename + * @param array $subString + * @param integer $type + * @return boolean + * @since Method available since Release 1.1.0 + */ + protected function acceptSubString($filename, array $subStrings, $type) + { + if (empty($subStrings)) { + return TRUE; + } + + $matched = FALSE; + + foreach ($subStrings as $string) { + if (($type == self::PREFIX && strpos($filename, $string) === 0) || + ($type == self::SUFFIX && + substr($filename, -1 * strlen($string)) == $string)) { + $matched = TRUE; + break; + } + } + + return $matched; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package File + * @author Sebastian Bergmann + * @copyright 2009-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @since File available since Release 1.1.0 + */ + +/** + * Factory Method implementation that creates a File_Iterator that operates on + * an AppendIterator that contains an RecursiveDirectoryIterator for each given + * path. + * + * @author Sebastian Bergmann + * @copyright 2009-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-file-iterator/tree + * @since Class available since Release 1.1.0 + */ +class File_Iterator_Factory +{ + /** + * @param array|string $paths + * @param array|string $suffixes + * @param array|string $prefixes + * @param array $exclude + * @return AppendIterator + */ + public function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = array()) + { + if (is_string($paths)) { + $paths = array($paths); + } + + $_paths = array(); + + foreach ($paths as $path) { + if ($locals = glob($path, GLOB_ONLYDIR)) { + $_paths = array_merge($_paths, $locals); + } else { + $_paths[] = $path; + } + } + + $paths = $_paths; + unset($_paths); + + if (is_string($prefixes)) { + if ($prefixes != '') { + $prefixes = array($prefixes); + } else { + $prefixes = array(); + } + } + + if (is_string($suffixes)) { + if ($suffixes != '') { + $suffixes = array($suffixes); + } else { + $suffixes = array(); + } + } + + $iterator = new AppendIterator; + + foreach ($paths as $path) { + if (is_dir($path)) { + $iterator->append( + new File_Iterator( + new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::FOLLOW_SYMLINKS) + ), + $suffixes, + $prefixes, + $exclude, + $path + ) + ); + } + } + + return $iterator; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package File + * @author Sebastian Bergmann + * @copyright 2009-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @since File available since Release 1.3.0 + */ + +/** + * Façade implementation that uses File_Iterator_Factory to create a + * File_Iterator that operates on an AppendIterator that contains an + * RecursiveDirectoryIterator for each given path. The list of unique + * files is returned as an array. + * + * @author Sebastian Bergmann + * @copyright 2009-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-file-iterator/tree + * @since Class available since Release 1.3.0 + */ +class File_Iterator_Facade +{ + /** + * @param array|string $paths + * @param array|string $suffixes + * @param array|string $prefixes + * @param array $exclude + * @param boolean $commonPath + * @return array + */ + public function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = array(), $commonPath = FALSE) + { + if (is_string($paths)) { + $paths = array($paths); + } + + $factory = new File_Iterator_Factory; + $iterator = $factory->getFileIterator( + $paths, $suffixes, $prefixes, $exclude + ); + + $files = array(); + + foreach ($iterator as $file) { + $file = $file->getRealPath(); + + if ($file) { + $files[] = $file; + } + } + + foreach ($paths as $path) { + if (is_file($path)) { + $files[] = realpath($path); + } + } + + $files = array_unique($files); + sort($files); + + if ($commonPath) { + return array( + 'commonPath' => $this->getCommonPath($files), + 'files' => $files + ); + } else { + return $files; + } + } + + /** + * Returns the common path of a set of files. + * + * @param array $files + * @return string + */ + protected function getCommonPath(array $files) + { + $count = count($files); + + if ($count == 0) { + return ''; + } + + if ($count == 1) { + return dirname($files[0]) . DIRECTORY_SEPARATOR; + } + + $_files = array(); + + foreach ($files as $file) { + $_files[] = $_fileParts = explode(DIRECTORY_SEPARATOR, $file); + + if (empty($_fileParts[0])) { + $_fileParts[0] = DIRECTORY_SEPARATOR; + } + } + + $common = ''; + $done = FALSE; + $j = 0; + $count--; + + while (!$done) { + for ($i = 0; $i < $count; $i++) { + if ($_files[$i][$j] != $_files[$i+1][$j]) { + $done = TRUE; + break; + } + } + + if (!$done) { + $common .= $_files[0][$j]; + + if ($j > 0) { + $common .= DIRECTORY_SEPARATOR; + } + } + + $j++; + } + + return DIRECTORY_SEPARATOR . $common; + } +} +File_Iterator + +Copyright (c) 2009-2013, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A stream of PHP tokens. + * + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-token-stream/tree + * @since Class available since Release 1.0.0 + */ +class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator +{ + /** + * @var array + */ + protected static $customTokens = array( + '(' => 'PHP_Token_OPEN_BRACKET', + ')' => 'PHP_Token_CLOSE_BRACKET', + '[' => 'PHP_Token_OPEN_SQUARE', + ']' => 'PHP_Token_CLOSE_SQUARE', + '{' => 'PHP_Token_OPEN_CURLY', + '}' => 'PHP_Token_CLOSE_CURLY', + ';' => 'PHP_Token_SEMICOLON', + '.' => 'PHP_Token_DOT', + ',' => 'PHP_Token_COMMA', + '=' => 'PHP_Token_EQUAL', + '<' => 'PHP_Token_LT', + '>' => 'PHP_Token_GT', + '+' => 'PHP_Token_PLUS', + '-' => 'PHP_Token_MINUS', + '*' => 'PHP_Token_MULT', + '/' => 'PHP_Token_DIV', + '?' => 'PHP_Token_QUESTION_MARK', + '!' => 'PHP_Token_EXCLAMATION_MARK', + ':' => 'PHP_Token_COLON', + '"' => 'PHP_Token_DOUBLE_QUOTES', + '@' => 'PHP_Token_AT', + '&' => 'PHP_Token_AMPERSAND', + '%' => 'PHP_Token_PERCENT', + '|' => 'PHP_Token_PIPE', + '$' => 'PHP_Token_DOLLAR', + '^' => 'PHP_Token_CARET', + '~' => 'PHP_Token_TILDE', + '`' => 'PHP_Token_BACKTICK' + ); + + /** + * @var string + */ + protected $filename; + + /** + * @var array + */ + protected $tokens = array(); + + /** + * @var integer + */ + protected $position = 0; + + /** + * @var array + */ + protected $linesOfCode = array('loc' => 0, 'cloc' => 0, 'ncloc' => 0); + + /** + * @var array + */ + protected $classes; + + /** + * @var array + */ + protected $functions; + + /** + * @var array + */ + protected $includes; + + /** + * @var array + */ + protected $interfaces; + + /** + * @var array + */ + protected $traits; + + /** + * @var array + */ + protected $lineToFunctionMap = array(); + + /** + * Constructor. + * + * @param string $sourceCode + */ + public function __construct($sourceCode) + { + if (is_file($sourceCode)) { + $this->filename = $sourceCode; + $sourceCode = file_get_contents($sourceCode); + } + + $this->scan($sourceCode); + } + + /** + * Destructor. + */ + public function __destruct() + { + $this->tokens = array(); + } + + /** + * @return string + */ + public function __toString() + { + $buffer = ''; + + foreach ($this as $token) { + $buffer .= $token; + } + + return $buffer; + } + + /** + * @return string + * @since Method available since Release 1.1.0 + */ + public function getFilename() + { + return $this->filename; + } + + /** + * Scans the source for sequences of characters and converts them into a + * stream of tokens. + * + * @param string $sourceCode + */ + protected function scan($sourceCode) + { + $line = 1; + $tokens = token_get_all($sourceCode); + $numTokens = count($tokens); + + $lastNonWhitespaceTokenWasDoubleColon = FALSE; + + for ($i = 0; $i < $numTokens; ++$i) { + $token = $tokens[$i]; + unset($tokens[$i]); + + if (is_array($token)) { + $name = substr(token_name($token[0]), 2); + $text = $token[1]; + + if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') { + $name = 'CLASS_NAME_CONSTANT'; + } + + $tokenClass = 'PHP_Token_' . $name; + } else { + $text = $token; + $tokenClass = self::$customTokens[$token]; + } + + $this->tokens[] = new $tokenClass($text, $line, $this, $i); + $lines = substr_count($text, "\n"); + $line += $lines; + + if ($tokenClass == 'PHP_Token_HALT_COMPILER') { + break; + } + + else if ($tokenClass == 'PHP_Token_COMMENT' || + $tokenClass == 'PHP_Token_DOC_COMMENT') { + $this->linesOfCode['cloc'] += $lines + 1; + } + + if ($name == 'DOUBLE_COLON') { + $lastNonWhitespaceTokenWasDoubleColon = TRUE; + } + + else if ($name != 'WHITESPACE') { + $lastNonWhitespaceTokenWasDoubleColon = FALSE; + } + } + + $this->linesOfCode['loc'] = substr_count($sourceCode, "\n"); + $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] - + $this->linesOfCode['cloc']; + } + + /** + * @return integer + */ + public function count() + { + return count($this->tokens); + } + + /** + * @return PHP_Token[] + */ + public function tokens() + { + return $this->tokens; + } + + /** + * @return array + */ + public function getClasses() + { + if ($this->classes !== NULL) { + return $this->classes; + } + + $this->parse(); + + return $this->classes; + } + + /** + * @return array + */ + public function getFunctions() + { + if ($this->functions !== NULL) { + return $this->functions; + } + + $this->parse(); + + return $this->functions; + } + + /** + * @return array + */ + public function getInterfaces() + { + if ($this->interfaces !== NULL) { + return $this->interfaces; + } + + $this->parse(); + + return $this->interfaces; + } + + /** + * @return array + * @since Method available since Release 1.1.0 + */ + public function getTraits() + { + if ($this->traits !== NULL) { + return $this->traits; + } + + $this->parse(); + + return $this->traits; + } + + /** + * Gets the names of all files that have been included + * using include(), include_once(), require() or require_once(). + * + * Parameter $categorize set to TRUE causing this function to return a + * multi-dimensional array with categories in the keys of the first dimension + * and constants and their values in the second dimension. + * + * Parameter $category allow to filter following specific inclusion type + * + * @param bool $categorize OPTIONAL + * @param string $category OPTIONAL Either 'require_once', 'require', + * 'include_once', 'include'. + * @return array + * @since Method available since Release 1.1.0 + */ + public function getIncludes($categorize = FALSE, $category = NULL) + { + if ($this->includes === NULL) { + $this->includes = array( + 'require_once' => array(), + 'require' => array(), + 'include_once' => array(), + 'include' => array() + ); + + foreach ($this->tokens as $token) { + switch (get_class($token)) { + case 'PHP_Token_REQUIRE_ONCE': + case 'PHP_Token_REQUIRE': + case 'PHP_Token_INCLUDE_ONCE': + case 'PHP_Token_INCLUDE': { + $this->includes[$token->getType()][] = $token->getName(); + } + break; + } + } + } + + if (isset($this->includes[$category])) { + $includes = $this->includes[$category]; + } + + else if ($categorize === FALSE) { + $includes = array_merge( + $this->includes['require_once'], + $this->includes['require'], + $this->includes['include_once'], + $this->includes['include'] + ); + } else { + $includes = $this->includes; + } + + return $includes; + } + + /** + * Returns the name of the function or method a line belongs to. + * + * @return string or null if the line is not in a function or method + * @since Method available since Release 1.2.0 + */ + public function getFunctionForLine($line) + { + $this->parse(); + + if (isset($this->lineToFunctionMap[$line])) { + return $this->lineToFunctionMap[$line]; + } + } + + protected function parse() + { + $this->interfaces = array(); + $this->classes = array(); + $this->traits = array(); + $this->functions = array(); + $class = FALSE; + $classEndLine = FALSE; + $trait = FALSE; + $traitEndLine = FALSE; + $interface = FALSE; + $interfaceEndLine = FALSE; + + foreach ($this->tokens as $token) { + switch (get_class($token)) { + case 'PHP_Token_HALT_COMPILER': { + return; + } + break; + + case 'PHP_Token_INTERFACE': { + $interface = $token->getName(); + $interfaceEndLine = $token->getEndLine(); + + $this->interfaces[$interface] = array( + 'methods' => array(), + 'parent' => $token->getParent(), + 'keywords' => $token->getKeywords(), + 'docblock' => $token->getDocblock(), + 'startLine' => $token->getLine(), + 'endLine' => $interfaceEndLine, + 'package' => $token->getPackage(), + 'file' => $this->filename + ); + } + break; + + case 'PHP_Token_CLASS': + case 'PHP_Token_TRAIT': { + $tmp = array( + 'methods' => array(), + 'parent' => $token->getParent(), + 'interfaces'=> $token->getInterfaces(), + 'keywords' => $token->getKeywords(), + 'docblock' => $token->getDocblock(), + 'startLine' => $token->getLine(), + 'endLine' => $token->getEndLine(), + 'package' => $token->getPackage(), + 'file' => $this->filename + ); + + if ($token instanceof PHP_Token_CLASS) { + $class = $token->getName(); + $classEndLine = $token->getEndLine(); + $this->classes[$class] = $tmp; + } else { + $trait = $token->getName(); + $traitEndLine = $token->getEndLine(); + $this->traits[$trait] = $tmp; + } + } + break; + + case 'PHP_Token_FUNCTION': { + $name = $token->getName(); + $tmp = array( + 'docblock' => $token->getDocblock(), + 'keywords' => $token->getKeywords(), + 'visibility'=> $token->getVisibility(), + 'signature' => $token->getSignature(), + 'startLine' => $token->getLine(), + 'endLine' => $token->getEndLine(), + 'ccn' => $token->getCCN(), + 'file' => $this->filename + ); + + if ($class === FALSE && + $trait === FALSE && + $interface === FALSE) { + $this->functions[$name] = $tmp; + + $this->addFunctionToMap( + $name, $tmp['startLine'], $tmp['endLine'] + ); + } + + else if ($class !== FALSE) { + $this->classes[$class]['methods'][$name] = $tmp; + + $this->addFunctionToMap( + $class . '::' . $name, + $tmp['startLine'], + $tmp['endLine'] + ); + } + + else if ($trait !== FALSE) { + $this->traits[$trait]['methods'][$name] = $tmp; + + $this->addFunctionToMap( + $trait . '::' . $name, + $tmp['startLine'], + $tmp['endLine'] + ); + } + + else { + $this->interfaces[$interface]['methods'][$name] = $tmp; + } + } + break; + + case 'PHP_Token_CLOSE_CURLY': { + if ($classEndLine !== FALSE && + $classEndLine == $token->getLine()) { + $class = FALSE; + $classEndLine = FALSE; + } + + else if ($traitEndLine !== FALSE && + $traitEndLine == $token->getLine()) { + $trait = FALSE; + $traitEndLine = FALSE; + } + + else if ($interfaceEndLine !== FALSE && + $interfaceEndLine == $token->getLine()) { + $interface = FALSE; + $interfaceEndLine = FALSE; + } + } + break; + } + } + } + + /** + * @return array + */ + public function getLinesOfCode() + { + return $this->linesOfCode; + } + + /** + */ + public function rewind() + { + $this->position = 0; + } + + /** + * @return boolean + */ + public function valid() + { + return isset($this->tokens[$this->position]); + } + + /** + * @return integer + */ + public function key() + { + return $this->position; + } + + /** + * @return PHP_Token + */ + public function current() + { + return $this->tokens[$this->position]; + } + + /** + */ + public function next() + { + $this->position++; + } + + /** + * @param mixed $offset + */ + public function offsetExists($offset) + { + return isset($this->tokens[$offset]); + } + + /** + * @param mixed $offset + * @return mixed + */ + public function offsetGet($offset) + { + return $this->tokens[$offset]; + } + + /** + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + $this->tokens[$offset] = $value; + } + + /** + * @param mixed $offset + */ + public function offsetUnset($offset) + { + unset($this->tokens[$offset]); + } + + /** + * Seek to an absolute position. + * + * @param integer $position + * @throws OutOfBoundsException + */ + public function seek($position) + { + $this->position = $position; + + if (!$this->valid()) { + throw new OutOfBoundsException('Invalid seek position'); + } + } + + private function addFunctionToMap($name, $startLine, $endLine) + { + for ($line = $startLine; $line <= $endLine; $line++) { + $this->lineToFunctionMap[$line] = $name; + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A caching factory for token stream objects. + * + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-token-stream/tree + * @since Class available since Release 1.0.0 + */ +class PHP_Token_Stream_CachingFactory +{ + /** + * @var array + */ + protected static $cache = array(); + + /** + * @param string $filename + * @return PHP_Token_Stream + */ + public static function get($filename) + { + if (!isset(self::$cache[$filename])) { + self::$cache[$filename] = new PHP_Token_Stream($filename); + } + + return self::$cache[$filename]; + } + + /** + * @param string $filename + */ + public static function clear($filename = NULL) + { + if (is_string($filename)) { + unset(self::$cache[$filename]); + } else { + self::$cache = array(); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A PHP token. + * + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/php-token-stream/tree + * @since Class available since Release 1.0.0 + */ +abstract class PHP_Token +{ + /** + * @var string + */ + protected $text; + + /** + * @var integer + */ + protected $line; + + /** + * @var PHP_Token_Stream + */ + protected $tokenStream; + + /** + * @var integer + */ + protected $id; + + /** + * Constructor. + * + * @param string $text + * @param integer $line + * @param PHP_Token_Stream $tokenStream + * @param integer $id + */ + public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id) + { + $this->text = $text; + $this->line = $line; + $this->tokenStream = $tokenStream; + $this->id = $id; + } + + /** + * @return string + */ + public function __toString() + { + return $this->text; + } + + /** + * @return integer + */ + public function getLine() + { + return $this->line; + } +} + +abstract class PHP_TokenWithScope extends PHP_Token +{ + protected $endTokenId; + + /** + * Get the docblock for this token + * + * This method will fetch the docblock belonging to the current token. The + * docblock must be placed on the line directly above the token to be + * recognized. + * + * @return string|null Returns the docblock as a string if found + */ + public function getDocblock() + { + $tokens = $this->tokenStream->tokens(); + $currentLineNumber = $tokens[$this->id]->getLine(); + $prevLineNumber = $currentLineNumber - 1; + + for ($i = $this->id - 1; $i; $i--) { + if (!isset($tokens[$i])) { + return; + } + + if ($tokens[$i] instanceof PHP_Token_FUNCTION || + $tokens[$i] instanceof PHP_Token_CLASS || + $tokens[$i] instanceof PHP_Token_TRAIT) { + // Some other trait, class or function, no docblock can be + // used for the current token + break; + } + + $line = $tokens[$i]->getLine(); + + if ($line == $currentLineNumber || + ($line == $prevLineNumber && + $tokens[$i] instanceof PHP_Token_WHITESPACE)) { + continue; + } + + if ($line < $currentLineNumber && + !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) { + break; + } + + return (string)$tokens[$i]; + } + } + + public function getEndTokenId() + { + $block = 0; + $i = $this->id; + $tokens = $this->tokenStream->tokens(); + + while ($this->endTokenId === NULL && isset($tokens[$i])) { + if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY || + $tokens[$i] instanceof PHP_Token_CURLY_OPEN) { + $block++; + } + + else if ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) { + $block--; + + if ($block === 0) { + $this->endTokenId = $i; + } + } + + else if (($this instanceof PHP_Token_FUNCTION || + $this instanceof PHP_Token_NAMESPACE) && + $tokens[$i] instanceof PHP_Token_SEMICOLON) { + if ($block === 0) { + $this->endTokenId = $i; + } + } + + $i++; + } + + if ($this->endTokenId === NULL) { + $this->endTokenId = $this->id; + } + + return $this->endTokenId; + } + + public function getEndLine() + { + return $this->tokenStream[$this->getEndTokenId()]->getLine(); + } + +} + +abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope { + + public function getVisibility() + { + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) { + if (isset($tokens[$i]) && + ($tokens[$i] instanceof PHP_Token_PRIVATE || + $tokens[$i] instanceof PHP_Token_PROTECTED || + $tokens[$i] instanceof PHP_Token_PUBLIC)) { + return strtolower( + str_replace('PHP_Token_', '', get_class($tokens[$i])) + ); + } + if (isset($tokens[$i]) && + !($tokens[$i] instanceof PHP_Token_STATIC || + $tokens[$i] instanceof PHP_Token_FINAL || + $tokens[$i] instanceof PHP_Token_ABSTRACT)) { + // no keywords; stop visibility search + break; + } + } + } + + public function getKeywords() + { + $keywords = array(); + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) { + if (isset($tokens[$i]) && + ($tokens[$i] instanceof PHP_Token_PRIVATE || + $tokens[$i] instanceof PHP_Token_PROTECTED || + $tokens[$i] instanceof PHP_Token_PUBLIC)) { + continue; + } + + if (isset($tokens[$i]) && + ($tokens[$i] instanceof PHP_Token_STATIC || + $tokens[$i] instanceof PHP_Token_FINAL || + $tokens[$i] instanceof PHP_Token_ABSTRACT)) { + $keywords[] = strtolower( + str_replace('PHP_Token_', '', get_class($tokens[$i])) + ); + } + } + + return implode(',', $keywords); + } + +} + +abstract class PHP_Token_Includes extends PHP_Token +{ + protected $name; + protected $type; + + public function getName() + { + if ($this->name !== NULL) { + return $this->name; + } + + $tokens = $this->tokenStream->tokens(); + + if ($tokens[$this->id+2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) { + $this->name = trim($tokens[$this->id+2], "'\""); + $this->type = strtolower( + str_replace('PHP_Token_', '', get_class($tokens[$this->id])) + ); + } + + return $this->name; + } + + public function getType() + { + $this->getName(); + return $this->type; + } +} + + +class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility +{ + protected $arguments; + protected $ccn; + protected $name; + protected $signature; + + public function getArguments() + { + if ($this->arguments !== NULL) { + return $this->arguments; + } + + $this->arguments = array(); + $tokens = $this->tokenStream->tokens(); + $typeHint = NULL; + + // Search for first token inside brackets + $i = $this->id + 2; + while (!$tokens[$i-1] instanceof PHP_Token_OPEN_BRACKET) { + $i++; + } + + while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) { + if ($tokens[$i] instanceof PHP_Token_STRING) { + $typeHint = (string)$tokens[$i]; + } + + else if ($tokens[$i] instanceof PHP_Token_VARIABLE) { + $this->arguments[(string)$tokens[$i]] = $typeHint; + $typeHint = NULL; + } + + $i++; + } + + return $this->arguments; + } + + public function getName() + { + if ($this->name !== NULL) { + return $this->name; + } + + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id + 1; $i < count($tokens); $i++) { + if ($tokens[$i] instanceof PHP_Token_STRING) { + $this->name = (string)$tokens[$i]; + break; + } + + else if ($tokens[$i] instanceof PHP_Token_AMPERSAND && + $tokens[$i+1] instanceof PHP_Token_STRING) { + $this->name = (string)$tokens[$i+1]; + break; + } + + else if ($tokens[$i] instanceof PHP_Token_OPEN_BRACKET) { + $this->name = 'anonymous function'; + break; + } + } + + if ($this->name != 'anonymous function') { + for ($i = $this->id; $i; --$i) { + if ($tokens[$i] instanceof PHP_Token_NAMESPACE) { + $this->name = $tokens[$i]->getName() . '\\' . $this->name; + break; + } + + if ($tokens[$i] instanceof PHP_Token_INTERFACE) { + break; + } + } + } + + return $this->name; + } + + public function getCCN() + { + if ($this->ccn !== NULL) { + return $this->ccn; + } + + $this->ccn = 1; + $end = $this->getEndTokenId(); + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id; $i <= $end; $i++) { + switch (get_class($tokens[$i])) { + case 'PHP_Token_IF': + case 'PHP_Token_ELSEIF': + case 'PHP_Token_FOR': + case 'PHP_Token_FOREACH': + case 'PHP_Token_WHILE': + case 'PHP_Token_CASE': + case 'PHP_Token_CATCH': + case 'PHP_Token_BOOLEAN_AND': + case 'PHP_Token_LOGICAL_AND': + case 'PHP_Token_BOOLEAN_OR': + case 'PHP_Token_LOGICAL_OR': + case 'PHP_Token_QUESTION_MARK': { + $this->ccn++; + } + break; + } + } + + return $this->ccn; + } + + public function getSignature() + { + if ($this->signature !== NULL) { + return $this->signature; + } + + if ($this->getName() == 'anonymous function') { + $this->signature = 'anonymous function'; + $i = $this->id + 1; + } else { + $this->signature = ''; + $i = $this->id + 2; + } + + $tokens = $this->tokenStream->tokens(); + + while (isset($tokens[$i]) && + !$tokens[$i] instanceof PHP_Token_OPEN_CURLY && + !$tokens[$i] instanceof PHP_Token_SEMICOLON) { + $this->signature .= $tokens[$i++]; + } + + $this->signature = trim($this->signature); + + return $this->signature; + } +} + +class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility +{ + protected $interfaces; + + public function getName() + { + return (string)$this->tokenStream[$this->id + 2]; + } + + public function hasParent() + { + return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS; + } + + public function getPackage() + { + $className = $this->getName(); + $docComment = $this->getDocblock(); + + $result = array( + 'namespace' => '', + 'fullPackage' => '', + 'category' => '', + 'package' => '', + 'subpackage' => '' + ); + + for ($i = $this->id; $i; --$i) { + if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) { + $result['namespace'] = $this->tokenStream[$i]->getName(); + break; + } + } + + if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['category'] = $matches[1]; + } + + if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['package'] = $matches[1]; + $result['fullPackage'] = $matches[1]; + } + + if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['subpackage'] = $matches[1]; + $result['fullPackage'] .= '.' . $matches[1]; + } + + if (empty($result['fullPackage'])) { + $result['fullPackage'] = $this->arrayToName( + explode('_', str_replace('\\', '_', $className)), '.' + ); + } + + return $result; + } + + protected function arrayToName(array $parts, $join = '\\') + { + $result = ''; + + if (count($parts) > 1) { + array_pop($parts); + + $result = join($join, $parts); + } + + return $result; + } + + public function getParent() + { + if (!$this->hasParent()) { + return FALSE; + } + + $i = $this->id + 6; + $tokens = $this->tokenStream->tokens(); + $className = (string)$tokens[$i]; + + while (isset($tokens[$i+1]) && + !$tokens[$i+1] instanceof PHP_Token_WHITESPACE) { + $className .= (string)$tokens[++$i]; + } + + return $className; + } + + public function hasInterfaces() + { + return (isset($this->tokenStream[$this->id + 4]) && + $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) || + (isset($this->tokenStream[$this->id + 8]) && + $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS); + } + + public function getInterfaces() + { + if ($this->interfaces !== NULL) { + return $this->interfaces; + } + + if (!$this->hasInterfaces()) { + return ($this->interfaces = FALSE); + } + + if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) { + $i = $this->id + 3; + } else { + $i = $this->id + 7; + } + + $tokens = $this->tokenStream->tokens(); + + while (!$tokens[$i+1] instanceof PHP_Token_OPEN_CURLY) { + $i++; + + if ($tokens[$i] instanceof PHP_Token_STRING) { + $this->interfaces[] = (string)$tokens[$i]; + } + } + + return $this->interfaces; + } +} + +class PHP_Token_ABSTRACT extends PHP_Token {} +class PHP_Token_AMPERSAND extends PHP_Token {} +class PHP_Token_AND_EQUAL extends PHP_Token {} +class PHP_Token_ARRAY extends PHP_Token {} +class PHP_Token_ARRAY_CAST extends PHP_Token {} +class PHP_Token_AS extends PHP_Token {} +class PHP_Token_AT extends PHP_Token {} +class PHP_Token_BACKTICK extends PHP_Token {} +class PHP_Token_BAD_CHARACTER extends PHP_Token {} +class PHP_Token_BOOLEAN_AND extends PHP_Token {} +class PHP_Token_BOOLEAN_OR extends PHP_Token {} +class PHP_Token_BOOL_CAST extends PHP_Token {} +class PHP_Token_BREAK extends PHP_Token {} +class PHP_Token_CARET extends PHP_Token {} +class PHP_Token_CASE extends PHP_Token {} +class PHP_Token_CATCH extends PHP_Token {} +class PHP_Token_CHARACTER extends PHP_Token {} +class PHP_Token_CLASS extends PHP_Token_INTERFACE {} +class PHP_Token_CLASS_C extends PHP_Token {} +class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token {} +class PHP_Token_CLONE extends PHP_Token {} +class PHP_Token_CLOSE_BRACKET extends PHP_Token {} +class PHP_Token_CLOSE_CURLY extends PHP_Token {} +class PHP_Token_CLOSE_SQUARE extends PHP_Token {} +class PHP_Token_CLOSE_TAG extends PHP_Token {} +class PHP_Token_COLON extends PHP_Token {} +class PHP_Token_COMMA extends PHP_Token {} +class PHP_Token_COMMENT extends PHP_Token {} +class PHP_Token_CONCAT_EQUAL extends PHP_Token {} +class PHP_Token_CONST extends PHP_Token {} +class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token {} +class PHP_Token_CONTINUE extends PHP_Token {} +class PHP_Token_CURLY_OPEN extends PHP_Token {} +class PHP_Token_DEC extends PHP_Token {} +class PHP_Token_DECLARE extends PHP_Token {} +class PHP_Token_DEFAULT extends PHP_Token {} +class PHP_Token_DIV extends PHP_Token {} +class PHP_Token_DIV_EQUAL extends PHP_Token {} +class PHP_Token_DNUMBER extends PHP_Token {} +class PHP_Token_DO extends PHP_Token {} +class PHP_Token_DOC_COMMENT extends PHP_Token {} +class PHP_Token_DOLLAR extends PHP_Token {} +class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token {} +class PHP_Token_DOT extends PHP_Token {} +class PHP_Token_DOUBLE_ARROW extends PHP_Token {} +class PHP_Token_DOUBLE_CAST extends PHP_Token {} +class PHP_Token_DOUBLE_COLON extends PHP_Token {} +class PHP_Token_DOUBLE_QUOTES extends PHP_Token {} +class PHP_Token_ECHO extends PHP_Token {} +class PHP_Token_ELSE extends PHP_Token {} +class PHP_Token_ELSEIF extends PHP_Token {} +class PHP_Token_EMPTY extends PHP_Token {} +class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token {} +class PHP_Token_ENDDECLARE extends PHP_Token {} +class PHP_Token_ENDFOR extends PHP_Token {} +class PHP_Token_ENDFOREACH extends PHP_Token {} +class PHP_Token_ENDIF extends PHP_Token {} +class PHP_Token_ENDSWITCH extends PHP_Token {} +class PHP_Token_ENDWHILE extends PHP_Token {} +class PHP_Token_END_HEREDOC extends PHP_Token {} +class PHP_Token_EQUAL extends PHP_Token {} +class PHP_Token_EVAL extends PHP_Token {} +class PHP_Token_EXCLAMATION_MARK extends PHP_Token {} +class PHP_Token_EXIT extends PHP_Token {} +class PHP_Token_EXTENDS extends PHP_Token {} +class PHP_Token_FILE extends PHP_Token {} +class PHP_Token_FINAL extends PHP_Token {} +class PHP_Token_FOR extends PHP_Token {} +class PHP_Token_FOREACH extends PHP_Token {} +class PHP_Token_FUNC_C extends PHP_Token {} +class PHP_Token_GLOBAL extends PHP_Token {} +class PHP_Token_GT extends PHP_Token {} +class PHP_Token_IF extends PHP_Token {} +class PHP_Token_IMPLEMENTS extends PHP_Token {} +class PHP_Token_INC extends PHP_Token {} +class PHP_Token_INCLUDE extends PHP_Token_Includes {} +class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes {} +class PHP_Token_INLINE_HTML extends PHP_Token {} +class PHP_Token_INSTANCEOF extends PHP_Token {} +class PHP_Token_INT_CAST extends PHP_Token {} +class PHP_Token_ISSET extends PHP_Token {} +class PHP_Token_IS_EQUAL extends PHP_Token {} +class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token {} +class PHP_Token_IS_IDENTICAL extends PHP_Token {} +class PHP_Token_IS_NOT_EQUAL extends PHP_Token {} +class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token {} +class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token {} +class PHP_Token_LINE extends PHP_Token {} +class PHP_Token_LIST extends PHP_Token {} +class PHP_Token_LNUMBER extends PHP_Token {} +class PHP_Token_LOGICAL_AND extends PHP_Token {} +class PHP_Token_LOGICAL_OR extends PHP_Token {} +class PHP_Token_LOGICAL_XOR extends PHP_Token {} +class PHP_Token_LT extends PHP_Token {} +class PHP_Token_METHOD_C extends PHP_Token {} +class PHP_Token_MINUS extends PHP_Token {} +class PHP_Token_MINUS_EQUAL extends PHP_Token {} +class PHP_Token_MOD_EQUAL extends PHP_Token {} +class PHP_Token_MULT extends PHP_Token {} +class PHP_Token_MUL_EQUAL extends PHP_Token {} +class PHP_Token_NEW extends PHP_Token {} +class PHP_Token_NUM_STRING extends PHP_Token {} +class PHP_Token_OBJECT_CAST extends PHP_Token {} +class PHP_Token_OBJECT_OPERATOR extends PHP_Token {} +class PHP_Token_OPEN_BRACKET extends PHP_Token {} +class PHP_Token_OPEN_CURLY extends PHP_Token {} +class PHP_Token_OPEN_SQUARE extends PHP_Token {} +class PHP_Token_OPEN_TAG extends PHP_Token {} +class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token {} +class PHP_Token_OR_EQUAL extends PHP_Token {} +class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token {} +class PHP_Token_PERCENT extends PHP_Token {} +class PHP_Token_PIPE extends PHP_Token {} +class PHP_Token_PLUS extends PHP_Token {} +class PHP_Token_PLUS_EQUAL extends PHP_Token {} +class PHP_Token_PRINT extends PHP_Token {} +class PHP_Token_PRIVATE extends PHP_Token {} +class PHP_Token_PROTECTED extends PHP_Token {} +class PHP_Token_PUBLIC extends PHP_Token {} +class PHP_Token_QUESTION_MARK extends PHP_Token {} +class PHP_Token_REQUIRE extends PHP_Token_Includes {} +class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes {} +class PHP_Token_RETURN extends PHP_Token {} +class PHP_Token_SEMICOLON extends PHP_Token {} +class PHP_Token_SL extends PHP_Token {} +class PHP_Token_SL_EQUAL extends PHP_Token {} +class PHP_Token_SR extends PHP_Token {} +class PHP_Token_SR_EQUAL extends PHP_Token {} +class PHP_Token_START_HEREDOC extends PHP_Token {} +class PHP_Token_STATIC extends PHP_Token {} +class PHP_Token_STRING extends PHP_Token {} +class PHP_Token_STRING_CAST extends PHP_Token {} +class PHP_Token_STRING_VARNAME extends PHP_Token {} +class PHP_Token_SWITCH extends PHP_Token {} +class PHP_Token_THROW extends PHP_Token {} +class PHP_Token_TILDE extends PHP_Token {} +class PHP_Token_TRY extends PHP_Token {} +class PHP_Token_UNSET extends PHP_Token {} +class PHP_Token_UNSET_CAST extends PHP_Token {} +class PHP_Token_USE extends PHP_Token {} +class PHP_Token_VAR extends PHP_Token {} +class PHP_Token_VARIABLE extends PHP_Token {} +class PHP_Token_WHILE extends PHP_Token {} +class PHP_Token_WHITESPACE extends PHP_Token {} +class PHP_Token_XOR_EQUAL extends PHP_Token {} + +// Tokens introduced in PHP 5.1 +class PHP_Token_HALT_COMPILER extends PHP_Token {} + +// Tokens introduced in PHP 5.3 +class PHP_Token_DIR extends PHP_Token {} +class PHP_Token_GOTO extends PHP_Token {} + +class PHP_Token_NAMESPACE extends PHP_TokenWithScope +{ + public function getName() + { + $tokens = $this->tokenStream->tokens(); + $namespace = (string)$tokens[$this->id+2]; + + for ($i = $this->id + 3; ; $i += 2) { + if (isset($tokens[$i]) && + $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) { + $namespace .= '\\' . $tokens[$i+1]; + } else { + break; + } + } + + return $namespace; + } +} + +class PHP_Token_NS_C extends PHP_Token {} +class PHP_Token_NS_SEPARATOR extends PHP_Token {} + +// Tokens introduced in PHP 5.4 +class PHP_Token_CALLABLE extends PHP_Token {} +class PHP_Token_INSTEADOF extends PHP_Token {} +class PHP_Token_TRAIT extends PHP_Token_INTERFACE {} +class PHP_Token_TRAIT_C extends PHP_Token {} + +// Tokens introduced in PHP 5.5 +class PHP_Token_FINALLY extends PHP_Token {} +class PHP_Token_YIELD extends PHP_Token {} + +// Tokens introduced in PHP 5.6 +class PHP_Token_ELLIPSIS extends PHP_Token {} +class PHP_Token_POW extends PHP_Token {} +class PHP_Token_POW_EQUAL extends PHP_Token {} + + +// Tokens introduced in HackLang +class PHP_Token_TYPELIST_LT extends PHP_Token {} +class PHP_Token_TYPELIST_GT extends PHP_Token {} +class PHP_Token_TYPE extends PHP_Token {} +class PHP_Token_SHAPE extends PHP_Token {} +class PHP_Token_LAMBDA_OP extends PHP_Token {} +class PHP_Token_LAMBDA_CP extends PHP_Token {} +class PHP_Token_LAMBDA_ARROW extends PHP_Token {} +PHP_TokenStream + +Copyright (c) 2009-2015, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\Exporter; + +use SebastianBergmann\RecursionContext\Context; + +/** + * A nifty utility for visualizing PHP variables. + * + * + * export(new Exception); + * + * + * @package Exporter + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link https://github.com/sebastianbergmann/exporter + */ +class Exporter +{ + /** + * Exports a value as a string + * + * The output of this method is similar to the output of print_r(), but + * improved in various aspects: + * + * - NULL is rendered as "null" (instead of "") + * - TRUE is rendered as "true" (instead of "1") + * - FALSE is rendered as "false" (instead of "") + * - Strings are always quoted with single quotes + * - Carriage returns and newlines are normalized to \n + * - Recursion and repeated rendering is treated properly + * + * @param mixed $value + * @param integer $indentation The indentation level of the 2nd+ line + * @return string + */ + public function export($value, $indentation = 0) + { + return $this->recursiveExport($value, $indentation); + } + + /** + * Recursive implementation of export + * + * @param mixed $value The value to export + * @param integer $indentation The indentation level of the 2nd+ line + * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects + * @return string + * @see SebastianBergmann\Exporter\Exporter::export + */ + protected function recursiveExport(&$value, $indentation, $processed = null) + { + if ($value === null) { + return 'null'; + } + + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + if (is_float($value) && floatval(intval($value)) === $value) { + return "$value.0"; + } + + if (is_resource($value)) { + return sprintf( + 'resource(%d) of type (%s)', + $value, + get_resource_type($value) + ); + } + + if (is_string($value)) { + // Match for most non printable chars somewhat taking multibyte chars into account + if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) { + return 'Binary String: 0x' . bin2hex($value); + } + + return "'" . + str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . + "'"; + } + + $whitespace = str_repeat(' ', 4 * $indentation); + + if (!$processed) { + $processed = new Context; + } + + if (is_array($value)) { + if (($key = $processed->contains($value)) !== false) { + return 'Array &' . $key; + } + + $key = $processed->add($value); + $values = ''; + + if (count($value) > 0) { + foreach ($value as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + $this->recursiveExport($k, $indentation), + $this->recursiveExport($value[$k], $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('Array &%s (%s)', $key, $values); + } + + if (is_object($value)) { + $class = get_class($value); + + if ($hash = $processed->contains($value)) { + return sprintf('%s Object &%s', $class, $hash); + } + + $hash = $processed->add($value); + $values = ''; + $array = $this->toArray($value); + + if (count($array) > 0) { + foreach ($array as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + $this->recursiveExport($k, $indentation), + $this->recursiveExport($v, $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('%s Object &%s (%s)', $class, $hash, $values); + } + + return var_export($value, true); + } + + /** + * Exports a value into a single-line string + * + * The output of this method is similar to the output of + * SebastianBergmann\Exporter\Exporter::export. This method guarantees + * thought that the result contains now newlines. + * + * Newlines are replaced by the visible string '\n'. Contents of arrays + * and objects (if any) are replaced by '...'. + * + * @param mixed $value + * @return string + * @see SebastianBergmann\Exporter\Exporter::export + */ + public function shortenedExport($value) + { + if (is_string($value)) { + $string = $this->export($value); + + if (strlen($string) > 40) { + $string = substr($string, 0, 30) . '...' . substr($string, -7); + } + + return str_replace("\n", '\n', $string); + } + + if (is_object($value)) { + return sprintf( + '%s Object (%s)', + get_class($value), + count($this->toArray($value)) > 0 ? '...' : '' + ); + } + + if (is_array($value)) { + return sprintf( + 'Array (%s)', + count($value) > 0 ? '...' : '' + ); + } + + return $this->export($value); + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param mixed $value + * @return array + */ + public function toArray($value) + { + if (!is_object($value)) { + return (array)$value; + } + + $array = array(); + + foreach ((array)$value as $key => $val) { + // properties are transformed to keys in the following way: + // private $property => "\0Classname\0property" + // protected $property => "\0*\0property" + // public $property => "property" + if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) { + $key = $matches[1]; + } + + // See https://github.com/php/php-src/commit/5721132 + if ($key === "\0gcdata") { + continue; + } + + $array[$key] = $val; + } + + // Some internal classes like SplObjectStorage don't work with the + // above (fast) mechanism nor with reflection in Zend. + // Format the output similarly to print_r() in this case + if ($value instanceof \SplObjectStorage) { + // However, the fast method does work in HHVM, and exposes the + // internal implementation. Hide it again. + if (property_exists('\SplObjectStorage', '__storage')) { + unset($array['__storage']); + } elseif (property_exists('\SplObjectStorage', 'storage')) { + unset($array['storage']); + } + + if (property_exists('\SplObjectStorage', '__key')) { + unset($array['__key']); + } + + foreach ($value as $key => $val) { + $array[spl_object_hash($val)] = array( + 'obj' => $val, + 'inf' => $value->getInfo(), + ); + } + } + + return $array; + } +} +Exporter + +Copyright (c) 2002-2015, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff\LCS; + +/** + * Time-efficient implementation of longest common subsequence calculation. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class TimeEfficientImplementation implements LongestCommonSubsequence +{ + /** + * Calculates the longest common subsequence of two arrays. + * + * @param array $from + * @param array $to + * @return array + */ + public function calculate(array $from, array $to) + { + $common = array(); + $matrix = array(); + $fromLength = count($from); + $toLength = count($to); + + for ($i = 0; $i <= $fromLength; ++$i) { + $matrix[$i][0] = 0; + } + + for ($j = 0; $j <= $toLength; ++$j) { + $matrix[0][$j] = 0; + } + + for ($i = 1; $i <= $fromLength; ++$i) { + for ($j = 1; $j <= $toLength; ++$j) { + $matrix[$i][$j] = max( + $matrix[$i-1][$j], + $matrix[$i][$j-1], + $from[$i-1] === $to[$j-1] ? $matrix[$i-1][$j-1] + 1 : 0 + ); + } + } + + $i = $fromLength; + $j = $toLength; + + while ($i > 0 && $j > 0) { + if ($from[$i-1] === $to[$j-1]) { + array_unshift($common, $from[$i-1]); + --$i; + --$j; + } elseif ($matrix[$i][$j-1] > $matrix[$i-1][$j]) { + --$j; + } else { + --$i; + } + } + + return $common; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff\LCS; + +/** + * Memory-efficient implementation of longest common subsequence calculation. + * + * @package Diff + * @author Sebastian Bergmann + * @author Denes Lados + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class MemoryEfficientImplementation implements LongestCommonSubsequence +{ + /** + * Calculates the longest common subsequence of two arrays. + * + * @param array $from + * @param array $to + * @return array + */ + public function calculate(array $from, array $to) + { + $cFrom = count($from); + $cTo = count($to); + + if ($cFrom == 0) { + return array(); + } elseif ($cFrom == 1) { + if (in_array($from[0], $to)) { + return array($from[0]); + } else { + return array(); + } + } else { + $i = intval($cFrom / 2); + $fromStart = array_slice($from, 0, $i); + $fromEnd = array_slice($from, $i); + $llB = $this->length($fromStart, $to); + $llE = $this->length(array_reverse($fromEnd), array_reverse($to)); + $jMax = 0; + $max = 0; + + for ($j = 0; $j <= $cTo; $j++) { + $m = $llB[$j] + $llE[$cTo - $j]; + + if ($m >= $max) { + $max = $m; + $jMax = $j; + } + } + + $toStart = array_slice($to, 0, $jMax); + $toEnd = array_slice($to, $jMax); + + return array_merge( + $this->calculate($fromStart, $toStart), + $this->calculate($fromEnd, $toEnd) + ); + } + } + + /** + * @param array $from + * @param array $to + * @return array + */ + private function length(array $from, array $to) + { + $current = array_fill(0, count($to) + 1, 0); + $cFrom = count($from); + $cTo = count($to); + + for ($i = 0; $i < $cFrom; $i++) { + $prev = $current; + + for ($j = 0; $j < $cTo; $j++) { + if ($from[$i] == $to[$j]) { + $current[$j + 1] = $prev[$j] + 1; + } else { + $current[$j + 1] = max($current[$j], $prev[$j + 1]); + } + } + } + + return $current; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff\LCS; + +/** + * Interface for implementations of longest common subsequence calculation. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +interface LongestCommonSubsequence +{ + /** + * Calculates the longest common subsequence of two arrays. + * + * @param array $from + * @param array $to + * @return array + */ + public function calculate(array $from, array $to); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff; + +/** + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class Diff +{ + /** + * @var string + */ + private $from; + + /** + * @var string + */ + private $to; + + /** + * @var Chunk[] + */ + private $chunks; + + /** + * @param string $from + * @param string $to + * @param Chunk[] $chunks + */ + public function __construct($from, $to, array $chunks = array()) + { + $this->from = $from; + $this->to = $to; + $this->chunks = $chunks; + } + + /** + * @return string + */ + public function getFrom() + { + return $this->from; + } + + /** + * @return string + */ + public function getTo() + { + return $this->to; + } + + /** + * @return Chunk[] + */ + public function getChunks() + { + return $this->chunks; + } + + /** + * @param Chunk[] $chunks + */ + public function setChunks(array $chunks) + { + $this->chunks = $chunks; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff; + +/** + * Unified diff parser. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class Parser +{ + /** + * @param string $string + * @return Diff[] + */ + public function parse($string) + { + $lines = preg_split('(\r\n|\r|\n)', $string); + $lineCount = count($lines); + $diffs = array(); + $diff = null; + $collected = array(); + + for ($i = 0; $i < $lineCount; ++$i) { + if (preg_match('(^---\\s+(?P\\S+))', $lines[$i], $fromMatch) && + preg_match('(^\\+\\+\\+\\s+(?P\\S+))', $lines[$i + 1], $toMatch)) { + if ($diff !== null) { + $this->parseFileDiff($diff, $collected); + $diffs[] = $diff; + $collected = array(); + } + + $diff = new Diff($fromMatch['file'], $toMatch['file']); + ++$i; + } else { + $collected[] = $lines[$i]; + } + } + + if (count($collected) && ($diff !== null)) { + $this->parseFileDiff($diff, $collected); + $diffs[] = $diff; + } + + return $diffs; + } + + /** + * @param Diff $diff + * @param array $lines + */ + private function parseFileDiff(Diff $diff, array $lines) + { + $chunks = array(); + + while (count($lines)) { + while (!preg_match('(^@@\\s+-(?P\\d+)(?:,\\s*(?P\\d+))?\\s+\\+(?P\\d+)(?:,\\s*(?P\\d+))?\\s+@@)', $last = array_shift($lines), $match)) { + if ($last === null) { + break 2; + } + } + + $chunk = new Chunk( + $match['start'], + isset($match['startrange']) ? max(1, $match['startrange']) : 1, + $match['end'], + isset($match['endrange']) ? max(1, $match['endrange']) : 1 + ); + + $diffLines = array(); + $last = null; + + while (count($lines) && + (preg_match('(^(?P[+ -])?(?P.*))', $last = array_shift($lines), $match) || + (strpos($last, '\\ No newline at end of file') === 0))) { + if (count($match)) { + $type = Line::UNCHANGED; + + if ($match['type'] == '+') { + $type = Line::ADDED; + } elseif ($match['type'] == '-') { + $type = Line::REMOVED; + } + + $diffLines[] = new Line($type, $match['line']); + } + } + + $chunk->setLines($diffLines); + + $chunks[] = $chunk; + + if ($last !== null) { + array_unshift($lines, $last); + } + } + + $diff->setChunks($chunks); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff; + +/** + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class Chunk +{ + /** + * @var int + */ + private $start; + + /** + * @var int + */ + private $startRange; + + /** + * @var int + */ + private $end; + /** + * @var int + */ + private $endRange; + + /** + * @var array + */ + private $lines; + + /** + * @param int $start + * @param int $startRange + * @param int $end + * @param int $endRange + * @param array $lines + */ + public function __construct($start = 0, $startRange = 1, $end = 0, $endRange = 1, array $lines = array()) + { + $this->start = (int) $start; + $this->startRange = (int) $startRange; + $this->end = (int) $end; + $this->endRange = (int) $endRange; + $this->lines = $lines; + } + + /** + * @return int + */ + public function getStart() + { + return $this->start; + } + + /** + * @return int + */ + public function getStartRange() + { + return $this->startRange; + } + + /** + * @return int + */ + public function getEnd() + { + return $this->end; + } + + /** + * @return int + */ + public function getEndRange() + { + return $this->endRange; + } + + /** + * @return array + */ + public function getLines() + { + return $this->lines; + } + + /** + * @param array $lines + */ + public function setLines(array $lines) + { + $this->lines = $lines; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff; + +/** + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class Line +{ + const ADDED = 1; + const REMOVED = 2; + const UNCHANGED = 3; + + /** + * @var int + */ + private $type; + + /** + * @var string + */ + private $content; + + /** + * @param int $type + * @param string $content + */ + public function __construct($type = self::UNCHANGED, $content = '') + { + $this->type = $type; + $this->content = $content; + } + + /** + * @return string + */ + public function getContent() + { + return $this->content; + } + + /** + * @return int + */ + public function getType() + { + return $this->type; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ + +namespace SebastianBergmann\Diff; + +use SebastianBergmann\Diff\LCS\LongestCommonSubsequence; +use SebastianBergmann\Diff\LCS\TimeEfficientImplementation; +use SebastianBergmann\Diff\LCS\MemoryEfficientImplementation; + +/** + * Diff implementation. + * + * @package Diff + * @author Sebastian Bergmann + * @author Kore Nordmann + * @copyright 2001-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.github.com/sebastianbergmann/diff + */ +class Differ +{ + /** + * @var string + */ + private $header; + + /** + * @param string $header + */ + public function __construct($header = "--- Original\n+++ New\n") + { + $this->header = $header; + } + + /** + * Returns the diff between two arrays or strings as string. + * + * @param array|string $from + * @param array|string $to + * @param LongestCommonSubsequence $lcs + * @return string + */ + public function diff($from, $to, LongestCommonSubsequence $lcs = null) + { + $buffer = $this->header; + $diff = $this->diffToArray($from, $to, $lcs); + + $inOld = false; + $i = 0; + $old = array(); + + foreach ($diff as $line) { + if ($line[1] === 0 /* OLD */) { + if ($inOld === false) { + $inOld = $i; + } + } elseif ($inOld !== false) { + if (($i - $inOld) > 5) { + $old[$inOld] = $i - 1; + } + + $inOld = false; + } + + ++$i; + } + + $start = isset($old[0]) ? $old[0] : 0; + $end = count($diff); + + if ($tmp = array_search($end, $old)) { + $end = $tmp; + } + + $newChunk = true; + + for ($i = $start; $i < $end; $i++) { + if (isset($old[$i])) { + $buffer .= "\n"; + $newChunk = true; + $i = $old[$i]; + } + + if ($newChunk) { + $buffer .= "@@ @@\n"; + $newChunk = false; + } + + if ($diff[$i][1] === 1 /* ADDED */) { + $buffer .= '+' . $diff[$i][0] . "\n"; + } elseif ($diff[$i][1] === 2 /* REMOVED */) { + $buffer .= '-' . $diff[$i][0] . "\n"; + } else { + $buffer .= ' ' . $diff[$i][0] . "\n"; + } + } + + return $buffer; + } + + /** + * Returns the diff between two arrays or strings as array. + * + * Each array element contains two elements: + * - [0] => string $token + * - [1] => 2|1|0 + * + * - 2: REMOVED: $token was removed from $from + * - 1: ADDED: $token was added to $from + * - 0: OLD: $token is not changed in $to + * + * @param array|string $from + * @param array|string $to + * @param LongestCommonSubsequence $lcs + * @return array + */ + public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null) + { + preg_match_all('(\r\n|\r|\n)', $from, $fromMatches); + preg_match_all('(\r\n|\r|\n)', $to, $toMatches); + + if (is_string($from)) { + $from = preg_split('(\r\n|\r|\n)', $from); + } + + if (is_string($to)) { + $to = preg_split('(\r\n|\r|\n)', $to); + } + + $start = array(); + $end = array(); + $fromLength = count($from); + $toLength = count($to); + $length = min($fromLength, $toLength); + + for ($i = 0; $i < $length; ++$i) { + if ($from[$i] === $to[$i]) { + $start[] = $from[$i]; + unset($from[$i], $to[$i]); + } else { + break; + } + } + + $length -= $i; + + for ($i = 1; $i < $length; ++$i) { + if ($from[$fromLength - $i] === $to[$toLength - $i]) { + array_unshift($end, $from[$fromLength - $i]); + unset($from[$fromLength - $i], $to[$toLength - $i]); + } else { + break; + } + } + + if ($lcs === null) { + $lcs = $this->selectLcsImplementation($from, $to); + } + + $common = $lcs->calculate(array_values($from), array_values($to)); + $diff = array(); + + if (isset($fromMatches[0]) && $toMatches[0] && + count($fromMatches[0]) === count($toMatches[0]) && + $fromMatches[0] !== $toMatches[0]) { + $diff[] = array( + '#Warning: Strings contain different line endings!', 0 + ); + } + + foreach ($start as $token) { + $diff[] = array($token, 0 /* OLD */); + } + + reset($from); + reset($to); + + foreach ($common as $token) { + while ((($fromToken = reset($from)) !== $token)) { + $diff[] = array(array_shift($from), 2 /* REMOVED */); + } + + while ((($toToken = reset($to)) !== $token)) { + $diff[] = array(array_shift($to), 1 /* ADDED */); + } + + $diff[] = array($token, 0 /* OLD */); + + array_shift($from); + array_shift($to); + } + + while (($token = array_shift($from)) !== null) { + $diff[] = array($token, 2 /* REMOVED */); + } + + while (($token = array_shift($to)) !== null) { + $diff[] = array($token, 1 /* ADDED */); + } + + foreach ($end as $token) { + $diff[] = array($token, 0 /* OLD */); + } + + return $diff; + } + + /** + * @param array $from + * @param array $to + * @return LongestCommonSubsequence + */ + private function selectLcsImplementation(array $from, array $to) + { + // We do not want to use the time-efficient implementation if its memory + // footprint will probably exceed this value. Note that the footprint + // calculation is only an estimation for the matrix and the LCS method + // will typically allocate a bit more memory than this. + $memoryLimit = 100 * 1024 * 1024; + + if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) { + return new MemoryEfficientImplementation; + } + + return new TimeEfficientImplementation; + } + + /** + * Calculates the estimated memory footprint for the DP-based method. + * + * @param array $from + * @param array $to + * @return integer + */ + private function calculateEstimatedFootprint(array $from, array $to) + { + $itemSize = PHP_INT_SIZE == 4 ? 76 : 144; + + return $itemSize * pow(min(count($from), count($to)), 2); + } +} +Diff + +Copyright (c) 2002-2014, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * The standard test suite loader. + * + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Runner_StandardTestSuiteLoader implements PHPUnit_Runner_TestSuiteLoader +{ + /** + * @param string $suiteClassName + * @param string $suiteClassFile + * @return ReflectionClass + * @throws PHPUnit_Framework_Exception + */ + public function load($suiteClassName, $suiteClassFile = '') + { + $suiteClassName = str_replace('.php', '', $suiteClassName); + + if (empty($suiteClassFile)) { + $suiteClassFile = PHPUnit_Util_Filesystem::classNameToFilename( + $suiteClassName + ); + } + + if (!class_exists($suiteClassName, false)) { + $loadedClasses = get_declared_classes(); + + $filename = PHPUnit_Util_Fileloader::checkAndLoad($suiteClassFile); + + $loadedClasses = array_values( + array_diff(get_declared_classes(), $loadedClasses) + ); + } + + if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) { + $offset = 0 - strlen($suiteClassName); + + foreach ($loadedClasses as $loadedClass) { + $class = new ReflectionClass($loadedClass); + if (substr($loadedClass, $offset) === $suiteClassName && + $class->getFileName() == $filename) { + $suiteClassName = $loadedClass; + break; + } + } + } + + if (!class_exists($suiteClassName, false) && !empty($loadedClasses)) { + $testCaseClass = 'PHPUnit_Framework_TestCase'; + + foreach ($loadedClasses as $loadedClass) { + $class = new ReflectionClass($loadedClass); + $classFile = $class->getFileName(); + + if ($class->isSubclassOf($testCaseClass) && + !$class->isAbstract()) { + $suiteClassName = $loadedClass; + $testCaseClass = $loadedClass; + + if ($classFile == realpath($suiteClassFile)) { + break; + } + } + + if ($class->hasMethod('suite')) { + $method = $class->getMethod('suite'); + + if (!$method->isAbstract() && + $method->isPublic() && + $method->isStatic()) { + $suiteClassName = $loadedClass; + + if ($classFile == realpath($suiteClassFile)) { + break; + } + } + } + } + } + + if (class_exists($suiteClassName, false)) { + $class = new ReflectionClass($suiteClassName); + + if ($class->getFileName() == realpath($suiteClassFile)) { + return $class; + } + } + + throw new PHPUnit_Framework_Exception( + sprintf( + "Class '%s' could not be found in '%s'.", + $suiteClassName, + $suiteClassFile + ) + ); + } + + /** + * @param ReflectionClass $aClass + * @return ReflectionClass + */ + public function reload(ReflectionClass $aClass) + { + return $aClass; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * This class defines the current version of PHPUnit. + * + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Runner_Version +{ + private static $pharVersion = "4.4.5"; + private static $version; + + /** + * Returns the current version of PHPUnit. + * + * @return string + */ + public static function id() + { + if (self::$pharVersion !== null) { + return self::$pharVersion; + } + + if (self::$version === null) { + $version = new SebastianBergmann\Version('4.4.5', dirname(dirname(__DIR__))); + self::$version = $version->getVersion(); + } + + return self::$version; + } + + /** + * @return string + */ + public static function getVersionString() + { + return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann.'; + } + + /** + * @return string + * @since Method available since Release 4.0.0 + */ + public static function getReleaseChannel() + { + if (strpos(self::$pharVersion, 'alpha') !== false) { + return '-alpha'; + } + + if (strpos(self::$pharVersion, 'beta') !== false) { + return '-beta'; + } + + return ''; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Runner_Exception extends RuntimeException implements PHPUnit_Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Runner_Filter_Test extends RecursiveFilterIterator +{ + /** + * @var string + */ + protected $filter = null; + + /** + * @var integer + */ + protected $filterMin; + /** + * @var integer + */ + protected $filterMax; + + /** + * @param RecursiveIterator $iterator + * @param string $filter + */ + public function __construct(RecursiveIterator $iterator, $filter) + { + parent::__construct($iterator); + $this->setFilter($filter); + } + + /** + * @param string $filter + */ + protected function setFilter($filter) + { + if (PHPUnit_Util_Regex::pregMatchSafe($filter, '') === false) { + // Handles: + // * testAssertEqualsSucceeds#4 + // * testAssertEqualsSucceeds#4-8 + if (preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) { + if (isset($matches[3]) && $matches[2] < $matches[3]) { + $filter = sprintf( + '%s.*with data set #(\d+)$', + $matches[1] + ); + + $this->filterMin = $matches[2]; + $this->filterMax = $matches[3]; + } else { + $filter = sprintf( + '%s.*with data set #%s$', + $matches[1], + $matches[2] + ); + } + } // Handles: + // * testDetermineJsonError@JSON_ERROR_NONE + // * testDetermineJsonError@JSON.* + elseif (preg_match('/^(.*?)@(.+)$/', $filter, $matches)) { + $filter = sprintf( + '%s.*with data set "%s"$', + $matches[1], + $matches[2] + ); + } + + // Escape delimiters in regular expression. Do NOT use preg_quote, + // to keep magic characters. + $filter = sprintf('/%s/', str_replace( + '/', '\\/', $filter + )); + } + + $this->filter = $filter; + } + + /** + * @return boolean + */ + public function accept() + { + $test = $this->getInnerIterator()->current(); + + if ($test instanceof PHPUnit_Framework_TestSuite) { + return true; + } + + $tmp = PHPUnit_Util_Test::describe($test, false); + + if ($tmp[0] != '') { + $name = join('::', $tmp); + } else { + $name = $tmp[1]; + } + + $accepted = preg_match($this->filter, $name, $matches); + + if ($accepted && isset($this->filterMax)) { + $set = end($matches); + $accepted = $set >= $this->filterMin && $set <= $this->filterMax; + } + + return $accepted; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Runner_Filter_Factory +{ + /** + * @var array + */ + private $filters = array(); + + /** + * @param ReflectionClass $filter + * @param mixed $args + */ + public function addFilter(ReflectionClass $filter, $args) + { + if (!$filter->isSubclassOf('RecursiveFilterIterator')) { + throw new InvalidArgumentException( + sprintf( + 'Class "%s" does not extend RecursiveFilterIterator', + $filter->name + ) + ); + } + + $this->filters[] = array($filter, $args); + } + + /** + * @return FilterIterator + */ + public function factory(Iterator $iterator, PHPUnit_Framework_TestSuite $suite) + { + foreach ($this->filters as $filter) { + list($class, $args) = $filter; + $iterator = $class->newInstance($iterator, $args, $suite); + } + + return $iterator; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Runner_Filter_Group_Include extends PHPUnit_Runner_Filter_GroupFilterIterator +{ + protected function doAccept($hash) + { + return in_array($hash, $this->groupTests); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Runner_Filter_Group_Exclude extends PHPUnit_Runner_Filter_GroupFilterIterator +{ + protected function doAccept($hash) + { + return !in_array($hash, $this->groupTests); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +abstract class PHPUnit_Runner_Filter_GroupFilterIterator extends RecursiveFilterIterator +{ + /** + * @var array + */ + protected $groupTests = array(); + + /** + * @param RecursiveIterator $iterator + * @param array $groups + * @param PHPUnit_Framework_TestSuite $suite + */ + public function __construct(RecursiveIterator $iterator, array $groups, PHPUnit_Framework_TestSuite $suite) + { + parent::__construct($iterator); + + foreach ($suite->getGroupDetails() as $group => $tests) { + if (in_array($group, $groups)) { + $testHashes = array_map( + function ($test) { return spl_object_hash($test); + }, + $tests + ); + + $this->groupTests = array_merge($this->groupTests, $testHashes); + } + } + } + + /** + * @return boolean + */ + public function accept() + { + $test = $this->getInnerIterator()->current(); + + if ($test instanceof PHPUnit_Framework_TestSuite) { + return true; + } + + return $this->doAccept(spl_object_hash($test)); + } + + abstract protected function doAccept($hash); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Base class for all test runners. + * + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +abstract class PHPUnit_Runner_BaseTestRunner +{ + const STATUS_PASSED = 0; + const STATUS_SKIPPED = 1; + const STATUS_INCOMPLETE = 2; + const STATUS_FAILURE = 3; + const STATUS_ERROR = 4; + const STATUS_RISKY = 5; + const SUITE_METHODNAME = 'suite'; + + /** + * Returns the loader to be used. + * + * @return PHPUnit_Runner_TestSuiteLoader + */ + public function getLoader() + { + return new PHPUnit_Runner_StandardTestSuiteLoader; + } + + /** + * Returns the Test corresponding to the given suite. + * This is a template method, subclasses override + * the runFailed() and clearStatus() methods. + * + * @param string $suiteClassName + * @param string $suiteClassFile + * @param mixed $suffixes + * @return PHPUnit_Framework_Test + */ + public function getTest($suiteClassName, $suiteClassFile = '', $suffixes = '') + { + if (is_dir($suiteClassName) && + !is_file($suiteClassName . '.php') && empty($suiteClassFile)) { + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray( + $suiteClassName, $suffixes + ); + + $suite = new PHPUnit_Framework_TestSuite($suiteClassName); + $suite->addTestFiles($files); + + return $suite; + } + + try { + $testClass = $this->loadSuiteClass( + $suiteClassName, $suiteClassFile + ); + } catch (PHPUnit_Framework_Exception $e) { + $this->runFailed($e->getMessage()); + + return null; + } + + try { + $suiteMethod = $testClass->getMethod(self::SUITE_METHODNAME); + + if (!$suiteMethod->isStatic()) { + $this->runFailed( + 'suite() method must be static.' + ); + + return null; + } + + try { + $test = $suiteMethod->invoke(null, $testClass->getName()); + } catch (ReflectionException $e) { + $this->runFailed( + sprintf( + "Failed to invoke suite() method.\n%s", + $e->getMessage() + ) + ); + + return null; + } + } catch (ReflectionException $e) { + try { + $test = new PHPUnit_Framework_TestSuite($testClass); + } catch (PHPUnit_Framework_Exception $e) { + $test = new PHPUnit_Framework_TestSuite; + $test->setName($suiteClassName); + } + } + + $this->clearStatus(); + + return $test; + } + + /** + * Returns the loaded ReflectionClass for a suite name. + * + * @param string $suiteClassName + * @param string $suiteClassFile + * @return ReflectionClass + */ + protected function loadSuiteClass($suiteClassName, $suiteClassFile = '') + { + $loader = $this->getLoader(); + + return $loader->load($suiteClassName, $suiteClassFile); + } + + /** + * Clears the status message. + * + */ + protected function clearStatus() + { + } + + /** + * Override to define how to handle a failed loading of + * a test suite. + * + * @param string $message + */ + abstract protected function runFailed($message); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * An interface to define how a test suite should be loaded. + * + * @package PHPUnit + * @subpackage Runner + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Runner_TestSuiteLoader +{ + /** + * @param string $suiteClassName + * @param string $suiteClassFile + * @return ReflectionClass + */ + public function load($suiteClassName, $suiteClassFile = ''); + + /** + * @param ReflectionClass $aClass + * @return ReflectionClass + */ + public function reload(ReflectionClass $aClass); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Environment\Console; + +/** + * Prints the result of a TextUI TestRunner run. + * + * @package PHPUnit + * @subpackage TextUI + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_TextUI_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + const EVENT_TEST_START = 0; + const EVENT_TEST_END = 1; + const EVENT_TESTSUITE_START = 2; + const EVENT_TESTSUITE_END = 3; + + /** + * @var array + */ + private static $ansiCodes = array( + 'bold' => 1, + 'fg-black' => 30, + 'fg-red' => 31, + 'fg-yellow' => 33, + 'fg-cyan' => 36, + 'fg-white' => 37, + 'bg-red' => 41, + 'bg-green' => 42, + 'bg-yellow' => 43 + ); + + /** + * @var integer + */ + protected $column = 0; + + /** + * @var integer + */ + protected $maxColumn; + + /** + * @var boolean + */ + protected $lastTestFailed = false; + + /** + * @var integer + */ + protected $numAssertions = 0; + + /** + * @var integer + */ + protected $numTests = -1; + + /** + * @var integer + */ + protected $numTestsRun = 0; + + /** + * @var integer + */ + protected $numTestsWidth; + + /** + * @var boolean + */ + protected $colors = false; + + /** + * @var boolean + */ + protected $debug = false; + + /** + * @var boolean + */ + protected $verbose = false; + + /** + * Constructor. + * + * @param mixed $out + * @param boolean $verbose + * @param boolean $colors + * @param boolean $debug + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.0.0 + */ + public function __construct($out = null, $verbose = false, $colors = false, $debug = false) + { + parent::__construct($out); + + if (is_bool($verbose)) { + $this->verbose = $verbose; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean'); + } + + if (is_bool($colors)) { + $console = new Console; + + $this->colors = $colors && $console->hasColorSupport(); + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean'); + } + + if (is_bool($debug)) { + $this->debug = $debug; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean'); + } + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + public function printResult(PHPUnit_Framework_TestResult $result) + { + $this->printHeader(); + + $this->printErrors($result); + $printSeparator = $result->errorCount() > 0; + + if ($printSeparator && $result->failureCount() > 0) { + $this->write("\n--\n\n"); + } + + $printSeparator = $printSeparator || $result->failureCount() > 0; + $this->printFailures($result); + + if ($this->verbose) { + if ($printSeparator && $result->riskyCount() > 0) { + $this->write("\n--\n\n"); + } + + $printSeparator = $printSeparator || + $result->riskyCount() > 0; + + $this->printRisky($result); + + if ($printSeparator && $result->notImplementedCount() > 0) { + $this->write("\n--\n\n"); + } + + $printSeparator = $printSeparator || + $result->notImplementedCount() > 0; + + $this->printIncompletes($result); + + if ($printSeparator && $result->skippedCount() > 0) { + $this->write("\n--\n\n"); + } + + $this->printSkipped($result); + } + + $this->printFooter($result); + } + + /** + * @param array $defects + * @param string $type + */ + protected function printDefects(array $defects, $type) + { + $count = count($defects); + + if ($count == 0) { + return; + } + + $this->write( + sprintf( + "There %s %d %s%s:\n", + ($count == 1) ? 'was' : 'were', + $count, + $type, + ($count == 1) ? '' : 's' + ) + ); + + $i = 1; + + foreach ($defects as $defect) { + $this->printDefect($defect, $i++); + } + } + + /** + * @param PHPUnit_Framework_TestFailure $defect + * @param integer $count + */ + protected function printDefect(PHPUnit_Framework_TestFailure $defect, $count) + { + $this->printDefectHeader($defect, $count); + $this->printDefectTrace($defect); + } + + /** + * @param PHPUnit_Framework_TestFailure $defect + * @param integer $count + */ + protected function printDefectHeader(PHPUnit_Framework_TestFailure $defect, $count) + { + $this->write( + sprintf( + "\n%d) %s\n", + $count, + $defect->getTestName() + ) + ); + } + + /** + * @param PHPUnit_Framework_TestFailure $defect + */ + protected function printDefectTrace(PHPUnit_Framework_TestFailure $defect) + { + $e = $defect->thrownException(); + $this->write((string) $e); + + while ($e = $e->getPrevious()) { + $this->write("\nCaused by\n" . $e); + } + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printErrors(PHPUnit_Framework_TestResult $result) + { + $this->printDefects($result->errors(), 'error'); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printFailures(PHPUnit_Framework_TestResult $result) + { + $this->printDefects($result->failures(), 'failure'); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printIncompletes(PHPUnit_Framework_TestResult $result) + { + $this->printDefects($result->notImplemented(), 'incomplete test'); + } + + /** + * @param PHPUnit_Framework_TestResult $result + * @since Method available since Release 4.0.0 + */ + protected function printRisky(PHPUnit_Framework_TestResult $result) + { + $this->printDefects($result->risky(), 'risky test'); + } + + /** + * @param PHPUnit_Framework_TestResult $result + * @since Method available since Release 3.0.0 + */ + protected function printSkipped(PHPUnit_Framework_TestResult $result) + { + $this->printDefects($result->skipped(), 'skipped test'); + } + + protected function printHeader() + { + $this->write("\n\n" . PHP_Timer::resourceUsage() . "\n\n"); + } + + /** + * @param PHPUnit_Framework_TestResult $result + */ + protected function printFooter(PHPUnit_Framework_TestResult $result) + { + if (count($result) === 0) { + $this->writeWithColor( + 'fg-black, bg-yellow', + 'No tests executed!' + ); + } elseif ($result->wasSuccessful() && + $result->allHarmless() && + $result->allCompletelyImplemented() && + $result->noneSkipped()) { + $this->writeWithColor( + 'fg-black, bg-green', + sprintf( + 'OK (%d test%s, %d assertion%s)', + count($result), + (count($result) == 1) ? '' : 's', + $this->numAssertions, + ($this->numAssertions == 1) ? '' : 's' + ) + ); + } elseif ((!$result->allCompletelyImplemented() || + !$result->allHarmless() || + !$result->noneSkipped()) && + $result->wasSuccessful()) { + $this->writeWithColor( + 'fg-black, bg-yellow', + sprintf( + "%sOK, but incomplete, skipped, or risky tests!\n" . + 'Tests: %d, Assertions: %d%s%s%s.', + $this->verbose ? "\n" : '', + count($result), + $this->numAssertions, + $this->getCountString( + $result->notImplementedCount(), 'Incomplete' + ), + $this->getCountString( + $result->skippedCount(), 'Skipped' + ), + $this->getCountString( + $result->riskyCount(), 'Risky' + ) + ) + ); + } else { + $this->writeWithColor( + 'fg-white, bg-red', + sprintf( + "\nFAILURES!\n" . + 'Tests: %d, Assertions: %s%s%s%s%s.', + count($result), + $this->numAssertions, + $this->getCountString($result->failureCount(), 'Failures'), + $this->getCountString($result->errorCount(), 'Errors'), + $this->getCountString( + $result->notImplementedCount(), 'Incomplete' + ), + $this->getCountString($result->skippedCount(), 'Skipped') + ) + ); + } + } + + /** + * @param integer $count + * @param string $name + * @return string + * @since Method available since Release 3.0.0 + */ + protected function getCountString($count, $name) + { + $string = ''; + + if ($count > 0) { + $string = sprintf( + ', %s: %d', + $name, + $count + ); + } + + return $string; + } + + /** + */ + public function printWaitPrompt() + { + $this->write("\n to continue\n"); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgressWithColor('fg-red, bold', 'E'); + $this->lastTestFailed = true; + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->writeProgressWithColor('bg-red, fg-white', 'F'); + $this->lastTestFailed = true; + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgressWithColor('fg-yellow, bold', 'I'); + $this->lastTestFailed = true; + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgressWithColor('fg-yellow, bold', 'R'); + $this->lastTestFailed = true; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeProgressWithColor('fg-cyan, bold', 'S'); + $this->lastTestFailed = true; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + if ($this->numTests == -1) { + $this->numTests = count($suite); + $this->numTestsWidth = strlen((string) $this->numTests); + $this->maxColumn = 69 - (2 * $this->numTestsWidth); + } + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if ($this->debug) { + $this->write( + sprintf( + "\nStarting test '%s'.\n", PHPUnit_Util_Test::describe($test) + ) + ); + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if (!$this->lastTestFailed) { + $this->writeProgress('.'); + } + + if ($test instanceof PHPUnit_Framework_TestCase) { + $this->numAssertions += $test->getNumAssertions(); + } elseif ($test instanceof PHPUnit_Extensions_PhptTestCase) { + $this->numAssertions++; + } + + $this->lastTestFailed = false; + + if ($test instanceof PHPUnit_Framework_TestCase) { + if (!$test->hasExpectationOnOutput()) { + $this->write($test->getActualOutput()); + } + } + } + + /** + * @param string $progress + */ + protected function writeProgress($progress) + { + $this->write($progress); + $this->column++; + $this->numTestsRun++; + + if ($this->column == $this->maxColumn) { + $this->write( + sprintf( + ' %' . $this->numTestsWidth . 'd / %' . + $this->numTestsWidth . 'd (%3s%%)', + $this->numTestsRun, + $this->numTests, + floor(($this->numTestsRun / $this->numTests) * 100) + ) + ); + + $this->writeNewLine(); + } + } + + protected function writeNewLine() + { + $this->column = 0; + $this->write("\n"); + } + + /** + * Formats a buffer with a specified ANSI color sequence if colors are + * enabled. + * + * @param string $color + * @param string $buffer + * @return string + * @since Method available since Release 4.0.0 + */ + protected function formatWithColor($color, $buffer) + { + if (!$this->colors) { + return $buffer; + } + + $codes = array_map('trim', explode(',', $color)); + $lines = explode("\n", $buffer); + $padding = max(array_map('strlen', $lines)); + + $styles = array(); + foreach ($codes as $code) { + $styles[] = self::$ansiCodes[$code]; + } + $style = sprintf("\x1b[%sm", implode(';', $styles)); + + $styledLines = array(); + foreach ($lines as $line) { + $styledLines[] = $style . str_pad($line, $padding) . "\x1b[0m"; + } + + return implode("\n", $styledLines); + } + + /** + * Writes a buffer out with a color sequence if colors are enabled. + * + * @param string $color + * @param string $buffer + * @since Method available since Release 4.0.0 + */ + protected function writeWithColor($color, $buffer) + { + $buffer = $this->formatWithColor($color, $buffer); + $this->write($buffer . "\n"); + } + + /** + * Writes progress with a color sequence if colors are enabled. + * + * @param string $color + * @param string $buffer + * @since Method available since Release 4.0.0 + */ + protected function writeProgressWithColor($color, $buffer) + { + $buffer = $this->formatWithColor($color, $buffer); + $this->writeProgress($buffer); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Environment\Runtime; + +/** + * A TestRunner for the Command Line Interface (CLI) + * PHP SAPI Module. + * + * @package PHPUnit + * @subpackage TextUI + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_TextUI_TestRunner extends PHPUnit_Runner_BaseTestRunner +{ + const SUCCESS_EXIT = 0; + const FAILURE_EXIT = 1; + const EXCEPTION_EXIT = 2; + + /** + * @var PHP_CodeCoverage_Filter + */ + protected $codeCoverageFilter; + + /** + * @var PHPUnit_Runner_TestSuiteLoader + */ + protected $loader = null; + + /** + * @var PHPUnit_TextUI_ResultPrinter + */ + protected $printer = null; + + /** + * @var boolean + */ + protected static $versionStringPrinted = false; + + /** + * @var array + */ + private $missingExtensions = array(); + + /** + * @var boolean + */ + private $canCollectCodeCoverage; + + /** + * @param PHPUnit_Runner_TestSuiteLoader $loader + * @param PHP_CodeCoverage_Filter $filter + * @since Method available since Release 3.4.0 + */ + public function __construct(PHPUnit_Runner_TestSuiteLoader $loader = null, PHP_CodeCoverage_Filter $filter = null) + { + if ($filter === null) { + $filter = new PHP_CodeCoverage_Filter; + } + + $this->codeCoverageFilter = $filter; + $this->loader = $loader; + + $runtime = new Runtime; + $this->canCollectCodeCoverage = $runtime->canCollectCodeCoverage(); + } + + /** + * @param PHPUnit_Framework_Test|ReflectionClass $test + * @param array $arguments + * @return PHPUnit_Framework_TestResult + * @throws PHPUnit_Framework_Exception + */ + public static function run($test, array $arguments = array()) + { + if ($test instanceof ReflectionClass) { + $test = new PHPUnit_Framework_TestSuite($test); + } + + if ($test instanceof PHPUnit_Framework_Test) { + $aTestRunner = new PHPUnit_TextUI_TestRunner; + + return $aTestRunner->doRun( + $test, + $arguments + ); + } else { + throw new PHPUnit_Framework_Exception( + 'No test case or test suite found.' + ); + } + } + + /** + * @return PHPUnit_Framework_TestResult + */ + protected function createTestResult() + { + return new PHPUnit_Framework_TestResult; + } + + private function processSuiteFilters(PHPUnit_Framework_TestSuite $suite, array $arguments) + { + if (!$arguments['filter'] && + empty($arguments['groups']) && + empty($arguments['excludeGroups'])) { + return; + } + + $filterFactory = new PHPUnit_Runner_Filter_Factory(); + + if (!empty($arguments['excludeGroups'])) { + $filterFactory->addFilter( + new ReflectionClass('PHPUnit_Runner_Filter_Group_Exclude'), + $arguments['excludeGroups'] + ); + } + + if (!empty($arguments['groups'])) { + $filterFactory->addFilter( + new ReflectionClass('PHPUnit_Runner_Filter_Group_Include'), + $arguments['groups'] + ); + } + + if ($arguments['filter']) { + $filterFactory->addFilter( + new ReflectionClass('PHPUnit_Runner_Filter_Test'), + $arguments['filter'] + ); + } + $suite->injectFilter($filterFactory); + } + + /** + * @param PHPUnit_Framework_Test $suite + * @param array $arguments + * @return PHPUnit_Framework_TestResult + */ + public function doRun(PHPUnit_Framework_Test $suite, array $arguments = array()) + { + $this->handleConfiguration($arguments); + + $this->processSuiteFilters($suite, $arguments); + + if (isset($arguments['bootstrap'])) { + $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap']; + } + + if ($arguments['backupGlobals'] === false) { + $suite->setBackupGlobals(false); + } + + if ($arguments['backupStaticAttributes'] === true) { + $suite->setBackupStaticAttributes(true); + } + + if (is_integer($arguments['repeat'])) { + $test = new PHPUnit_Extensions_RepeatedTest( + $suite, + $arguments['repeat'], + $arguments['processIsolation'] + ); + + $suite = new PHPUnit_Framework_TestSuite(); + $suite->addTest($test); + } + + $result = $this->createTestResult(); + + if (!$arguments['convertErrorsToExceptions']) { + $result->convertErrorsToExceptions(false); + } + + if (!$arguments['convertNoticesToExceptions']) { + PHPUnit_Framework_Error_Notice::$enabled = false; + } + + if (!$arguments['convertWarningsToExceptions']) { + PHPUnit_Framework_Error_Warning::$enabled = false; + } + + if ($arguments['stopOnError']) { + $result->stopOnError(true); + } + + if ($arguments['stopOnFailure']) { + $result->stopOnFailure(true); + } + + if ($arguments['stopOnIncomplete']) { + $result->stopOnIncomplete(true); + } + + if ($arguments['stopOnRisky']) { + $result->stopOnRisky(true); + } + + if ($arguments['stopOnSkipped']) { + $result->stopOnSkipped(true); + } + + if ($this->printer === null) { + if (isset($arguments['printer']) && + $arguments['printer'] instanceof PHPUnit_Util_Printer) { + $this->printer = $arguments['printer']; + } else { + $printerClass = 'PHPUnit_TextUI_ResultPrinter'; + if (isset($arguments['printer']) && + is_string($arguments['printer']) && + class_exists($arguments['printer'], false)) { + $class = new ReflectionClass($arguments['printer']); + + if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) { + $printerClass = $arguments['printer']; + } + } + + $this->printer = new $printerClass( + isset($arguments['stderr']) ? 'php://stderr' : null, + $arguments['verbose'], + $arguments['colors'], + $arguments['debug'] + ); + } + } + + if (!$this->printer instanceof PHPUnit_Util_Log_TAP) { + $this->printer->write( + PHPUnit_Runner_Version::getVersionString() . "\n\n" + ); + + self::$versionStringPrinted = true; + + if (isset($arguments['configuration'])) { + $this->printer->write( + sprintf( + "Configuration read from %s\n\n", + $arguments['configuration']->getFilename() + ) + ); + } + } + + foreach ($arguments['listeners'] as $listener) { + $result->addListener($listener); + } + + $result->addListener($this->printer); + + if (isset($arguments['testdoxHTMLFile'])) { + $result->addListener( + new PHPUnit_Util_TestDox_ResultPrinter_HTML( + $arguments['testdoxHTMLFile'] + ) + ); + } + + if (isset($arguments['testdoxTextFile'])) { + $result->addListener( + new PHPUnit_Util_TestDox_ResultPrinter_Text( + $arguments['testdoxTextFile'] + ) + ); + } + + $codeCoverageReports = 0; + + if (isset($arguments['coverageClover'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageCrap4J'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageHtml'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coveragePHP'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageText'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageXml'])) { + $codeCoverageReports++; + } + + if ($codeCoverageReports > 0 && (!extension_loaded('tokenizer') || !$this->canCollectCodeCoverage)) { + if (!extension_loaded('tokenizer')) { + $this->showExtensionNotLoadedMessage( + 'tokenizer', 'No code coverage will be generated.' + ); + } elseif (!extension_loaded('Xdebug')) { + $this->showExtensionNotLoadedMessage( + 'Xdebug', 'No code coverage will be generated.' + ); + } + + $codeCoverageReports = 0; + } + + if ($codeCoverageReports > 0) { + $codeCoverage = new PHP_CodeCoverage( + null, $this->codeCoverageFilter + ); + + $codeCoverage->setAddUncoveredFilesFromWhitelist( + $arguments['addUncoveredFilesFromWhitelist'] + ); + + $codeCoverage->setCheckForUnintentionallyCoveredCode( + $arguments['strictCoverage'] + ); + + $codeCoverage->setProcessUncoveredFilesFromWhitelist( + $arguments['processUncoveredFilesFromWhitelist'] + ); + + if (isset($arguments['forceCoversAnnotation'])) { + $codeCoverage->setForceCoversAnnotation( + $arguments['forceCoversAnnotation'] + ); + } + + if (isset($arguments['mapTestClassNameToCoveredClassName'])) { + $codeCoverage->setMapTestClassNameToCoveredClassName( + $arguments['mapTestClassNameToCoveredClassName'] + ); + } + + $result->setCodeCoverage($codeCoverage); + } + + if ($codeCoverageReports > 1) { + if (isset($arguments['cacheTokens'])) { + $codeCoverage->setCacheTokens($arguments['cacheTokens']); + } + } + + if (isset($arguments['jsonLogfile'])) { + $result->addListener( + new PHPUnit_Util_Log_JSON($arguments['jsonLogfile']) + ); + } + + if (isset($arguments['tapLogfile'])) { + $result->addListener( + new PHPUnit_Util_Log_TAP($arguments['tapLogfile']) + ); + } + + if (isset($arguments['junitLogfile'])) { + $result->addListener( + new PHPUnit_Util_Log_JUnit( + $arguments['junitLogfile'], $arguments['logIncompleteSkipped'] + ) + ); + } + + $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']); + $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']); + $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']); + $result->beStrictAboutTestSize($arguments['enforceTimeLimit']); + $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']); + $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']); + $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']); + + if ($suite instanceof PHPUnit_Framework_TestSuite) { + $suite->setRunTestInSeparateProcess($arguments['processIsolation']); + } + + $suite->run($result); + + unset($suite); + $result->flushListeners(); + + if ($this->printer instanceof PHPUnit_TextUI_ResultPrinter) { + $this->printer->printResult($result); + } + + if (isset($codeCoverage)) { + if (isset($arguments['coverageClover'])) { + $this->printer->write( + "\nGenerating code coverage report in Clover XML format ..." + ); + + $writer = new PHP_CodeCoverage_Report_Clover; + $writer->process($codeCoverage, $arguments['coverageClover']); + + $this->printer->write(" done\n"); + unset($writer); + } + + if (isset($arguments['coverageCrap4J'])) { + $this->printer->write( + "\nGenerating Crap4J report XML file ..." + ); + + $writer = new PHP_CodeCoverage_Report_Crap4j; + $writer->process($codeCoverage, $arguments['coverageCrap4J']); + + $this->printer->write(" done\n"); + unset($writer); + } + + if (isset($arguments['coverageHtml'])) { + $this->printer->write( + "\nGenerating code coverage report in HTML format ..." + ); + + $writer = new PHP_CodeCoverage_Report_HTML( + $arguments['reportLowUpperBound'], + $arguments['reportHighLowerBound'], + sprintf( + ' and PHPUnit %s', + PHPUnit_Runner_Version::id() + ) + ); + + $writer->process($codeCoverage, $arguments['coverageHtml']); + + $this->printer->write(" done\n"); + unset($writer); + } + + if (isset($arguments['coveragePHP'])) { + $this->printer->write( + "\nGenerating code coverage report in PHP format ..." + ); + + $writer = new PHP_CodeCoverage_Report_PHP; + $writer->process($codeCoverage, $arguments['coveragePHP']); + + $this->printer->write(" done\n"); + unset($writer); + } + + if (isset($arguments['coverageText'])) { + if ($arguments['coverageText'] == 'php://stdout') { + $outputStream = $this->printer; + $colors = (bool) $arguments['colors']; + } else { + $outputStream = new PHPUnit_Util_Printer($arguments['coverageText']); + $colors = false; + } + + $processor = new PHP_CodeCoverage_Report_Text( + $arguments['reportLowUpperBound'], + $arguments['reportHighLowerBound'], + $arguments['coverageTextShowUncoveredFiles'], + $arguments['coverageTextShowOnlySummary'] + ); + + $outputStream->write( + $processor->process($codeCoverage, $colors) + ); + } + + if (isset($arguments['coverageXml'])) { + $this->printer->write( + "\nGenerating code coverage report in PHPUnit XML format ..." + ); + + $writer = new PHP_CodeCoverage_Report_XML; + $writer->process($codeCoverage, $arguments['coverageXml']); + + $this->printer->write(" done\n"); + unset($writer); + } + } + + return $result; + } + + /** + * @param PHPUnit_TextUI_ResultPrinter $resultPrinter + */ + public function setPrinter(PHPUnit_TextUI_ResultPrinter $resultPrinter) + { + $this->printer = $resultPrinter; + } + + /** + * Override to define how to handle a failed loading of + * a test suite. + * + * @param string $message + */ + protected function runFailed($message) + { + $this->write($message . PHP_EOL); + exit(self::FAILURE_EXIT); + } + + /** + * @param string $buffer + * @since Method available since Release 3.1.0 + */ + protected function write($buffer) + { + if (PHP_SAPI != 'cli') { + $buffer = htmlspecialchars($buffer); + } + + if ($this->printer !== null) { + $this->printer->write($buffer); + } else { + print $buffer; + } + } + + /** + * Returns the loader to be used. + * + * @return PHPUnit_Runner_TestSuiteLoader + * @since Method available since Release 2.2.0 + */ + public function getLoader() + { + if ($this->loader === null) { + $this->loader = new PHPUnit_Runner_StandardTestSuiteLoader; + } + + return $this->loader; + } + + /** + * @param array $arguments + * @since Method available since Release 3.2.1 + */ + protected function handleConfiguration(array &$arguments) + { + if (isset($arguments['configuration']) && + !$arguments['configuration'] instanceof PHPUnit_Util_Configuration) { + $arguments['configuration'] = PHPUnit_Util_Configuration::getInstance( + $arguments['configuration'] + ); + } + + $arguments['debug'] = isset($arguments['debug']) ? $arguments['debug'] : false; + $arguments['filter'] = isset($arguments['filter']) ? $arguments['filter'] : false; + $arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : array(); + + if (isset($arguments['configuration'])) { + $arguments['configuration']->handlePHPConfiguration(); + + $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration(); + + if (isset($phpunitConfiguration['backupGlobals']) && + !isset($arguments['backupGlobals'])) { + $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals']; + } + + if (isset($phpunitConfiguration['backupStaticAttributes']) && + !isset($arguments['backupStaticAttributes'])) { + $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes']; + } + + if (isset($phpunitConfiguration['bootstrap']) && + !isset($arguments['bootstrap'])) { + $arguments['bootstrap'] = $phpunitConfiguration['bootstrap']; + } + + if (isset($phpunitConfiguration['cacheTokens']) && + !isset($arguments['cacheTokens'])) { + $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens']; + } + + if (isset($phpunitConfiguration['colors']) && + !isset($arguments['colors'])) { + $arguments['colors'] = $phpunitConfiguration['colors']; + } + + if (isset($phpunitConfiguration['convertErrorsToExceptions']) && + !isset($arguments['convertErrorsToExceptions'])) { + $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions']; + } + + if (isset($phpunitConfiguration['convertNoticesToExceptions']) && + !isset($arguments['convertNoticesToExceptions'])) { + $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions']; + } + + if (isset($phpunitConfiguration['convertWarningsToExceptions']) && + !isset($arguments['convertWarningsToExceptions'])) { + $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions']; + } + + if (isset($phpunitConfiguration['processIsolation']) && + !isset($arguments['processIsolation'])) { + $arguments['processIsolation'] = $phpunitConfiguration['processIsolation']; + } + + if (isset($phpunitConfiguration['stopOnFailure']) && + !isset($arguments['stopOnFailure'])) { + $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure']; + } + + if (isset($phpunitConfiguration['timeoutForSmallTests']) && + !isset($arguments['timeoutForSmallTests'])) { + $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests']; + } + + if (isset($phpunitConfiguration['timeoutForMediumTests']) && + !isset($arguments['timeoutForMediumTests'])) { + $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests']; + } + + if (isset($phpunitConfiguration['timeoutForLargeTests']) && + !isset($arguments['timeoutForLargeTests'])) { + $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests']; + } + + if (isset($phpunitConfiguration['reportUselessTests']) && + !isset($arguments['reportUselessTests'])) { + $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests']; + } + + if (isset($phpunitConfiguration['strictCoverage']) && + !isset($arguments['strictCoverage'])) { + $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage']; + } + + if (isset($phpunitConfiguration['disallowTestOutput']) && + !isset($arguments['disallowTestOutput'])) { + $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput']; + } + + if (isset($phpunitConfiguration['enforceTimeLimit']) && + !isset($arguments['enforceTimeLimit'])) { + $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit']; + } + + if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) && + !isset($arguments['disallowTodoAnnotatedTests'])) { + $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests']; + } + + if (isset($phpunitConfiguration['verbose']) && + !isset($arguments['verbose'])) { + $arguments['verbose'] = $phpunitConfiguration['verbose']; + } + + if (isset($phpunitConfiguration['forceCoversAnnotation']) && + !isset($arguments['forceCoversAnnotation'])) { + $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation']; + } + + if (isset($phpunitConfiguration['mapTestClassNameToCoveredClassName']) && + !isset($arguments['mapTestClassNameToCoveredClassName'])) { + $arguments['mapTestClassNameToCoveredClassName'] = $phpunitConfiguration['mapTestClassNameToCoveredClassName']; + } + + $groupCliArgs = array(); + if (!empty($arguments['groups'])) { + $groupCliArgs = $arguments['groups']; + } + + $groupConfiguration = $arguments['configuration']->getGroupConfiguration(); + + if (!empty($groupConfiguration['include']) && + !isset($arguments['groups'])) { + $arguments['groups'] = $groupConfiguration['include']; + } + + if (!empty($groupConfiguration['exclude']) && + !isset($arguments['excludeGroups'])) { + $arguments['excludeGroups'] = array_diff($groupConfiguration['exclude'], $groupCliArgs); + } + + foreach ($arguments['configuration']->getListenerConfiguration() as $listener) { + if (!class_exists($listener['class'], false) && + $listener['file'] !== '') { + require_once $listener['file']; + } + + if (class_exists($listener['class'])) { + if (count($listener['arguments']) == 0) { + $listener = new $listener['class']; + } else { + $listenerClass = new ReflectionClass( + $listener['class'] + ); + $listener = $listenerClass->newInstanceArgs( + $listener['arguments'] + ); + } + + if ($listener instanceof PHPUnit_Framework_TestListener) { + $arguments['listeners'][] = $listener; + } + } + } + + $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration(); + + if (isset($loggingConfiguration['coverage-clover']) && + !isset($arguments['coverageClover'])) { + $arguments['coverageClover'] = $loggingConfiguration['coverage-clover']; + } + + if (isset($loggingConfiguration['coverage-crap4j']) && + !isset($arguments['coverageCrap4J'])) { + $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j']; + } + + if (isset($loggingConfiguration['coverage-html']) && + !isset($arguments['coverageHtml'])) { + if (isset($loggingConfiguration['lowUpperBound']) && + !isset($arguments['reportLowUpperBound'])) { + $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound']; + } + + if (isset($loggingConfiguration['highLowerBound']) && + !isset($arguments['reportHighLowerBound'])) { + $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound']; + } + + $arguments['coverageHtml'] = $loggingConfiguration['coverage-html']; + } + + if (isset($loggingConfiguration['coverage-php']) && + !isset($arguments['coveragePHP'])) { + $arguments['coveragePHP'] = $loggingConfiguration['coverage-php']; + } + + if (isset($loggingConfiguration['coverage-text']) && + !isset($arguments['coverageText'])) { + $arguments['coverageText'] = $loggingConfiguration['coverage-text']; + if (isset($loggingConfiguration['coverageTextShowUncoveredFiles'])) { + $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles']; + } else { + $arguments['coverageTextShowUncoveredFiles'] = false; + } + if (isset($loggingConfiguration['coverageTextShowOnlySummary'])) { + $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary']; + } else { + $arguments['coverageTextShowOnlySummary'] = false; + } + } + + if (isset($loggingConfiguration['coverage-xml']) && + !isset($arguments['coverageXml'])) { + $arguments['coverageXml'] = $loggingConfiguration['coverage-xml']; + } + + if (isset($loggingConfiguration['json']) && + !isset($arguments['jsonLogfile'])) { + $arguments['jsonLogfile'] = $loggingConfiguration['json']; + } + + if (isset($loggingConfiguration['plain'])) { + $arguments['listeners'][] = new PHPUnit_TextUI_ResultPrinter( + $loggingConfiguration['plain'], true + ); + } + + if (isset($loggingConfiguration['tap']) && + !isset($arguments['tapLogfile'])) { + $arguments['tapLogfile'] = $loggingConfiguration['tap']; + } + + if (isset($loggingConfiguration['junit']) && + !isset($arguments['junitLogfile'])) { + $arguments['junitLogfile'] = $loggingConfiguration['junit']; + + if (isset($loggingConfiguration['logIncompleteSkipped']) && + !isset($arguments['logIncompleteSkipped'])) { + $arguments['logIncompleteSkipped'] = $loggingConfiguration['logIncompleteSkipped']; + } + } + + if (isset($loggingConfiguration['testdox-html']) && + !isset($arguments['testdoxHTMLFile'])) { + $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html']; + } + + if (isset($loggingConfiguration['testdox-text']) && + !isset($arguments['testdoxTextFile'])) { + $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text']; + } + + if ((isset($arguments['coverageClover']) || + isset($arguments['coverageCrap4J']) || + isset($arguments['coverageHtml']) || + isset($arguments['coveragePHP']) || + isset($arguments['coverageText']) || + isset($arguments['coverageXml'])) && + $this->canCollectCodeCoverage) { + $filterConfiguration = $arguments['configuration']->getFilterConfiguration(); + $arguments['addUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist']; + $arguments['processUncoveredFilesFromWhitelist'] = $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist']; + + if (empty($filterConfiguration['whitelist']['include']['directory']) && + empty($filterConfiguration['whitelist']['include']['file'])) { + if (defined('__PHPUNIT_PHAR__')) { + $this->codeCoverageFilter->addFileToBlacklist(__PHPUNIT_PHAR__); + } + + $blacklist = new PHPUnit_Util_Blacklist; + + foreach ($blacklist->getBlacklistedDirectories() as $directory) { + $this->codeCoverageFilter->addDirectoryToBlacklist($directory); + } + + foreach ($filterConfiguration['blacklist']['include']['directory'] as $dir) { + $this->codeCoverageFilter->addDirectoryToBlacklist( + $dir['path'], $dir['suffix'], $dir['prefix'], $dir['group'] + ); + } + + foreach ($filterConfiguration['blacklist']['include']['file'] as $file) { + $this->codeCoverageFilter->addFileToBlacklist($file); + } + + foreach ($filterConfiguration['blacklist']['exclude']['directory'] as $dir) { + $this->codeCoverageFilter->removeDirectoryFromBlacklist( + $dir['path'], $dir['suffix'], $dir['prefix'], $dir['group'] + ); + } + + foreach ($filterConfiguration['blacklist']['exclude']['file'] as $file) { + $this->codeCoverageFilter->removeFileFromBlacklist($file); + } + } + + foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) { + $this->codeCoverageFilter->addDirectoryToWhitelist( + $dir['path'], $dir['suffix'], $dir['prefix'] + ); + } + + foreach ($filterConfiguration['whitelist']['include']['file'] as $file) { + $this->codeCoverageFilter->addFileToWhitelist($file); + } + + foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) { + $this->codeCoverageFilter->removeDirectoryFromWhitelist( + $dir['path'], $dir['suffix'], $dir['prefix'] + ); + } + + foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) { + $this->codeCoverageFilter->removeFileFromWhitelist($file); + } + } + } + + $arguments['addUncoveredFilesFromWhitelist'] = isset($arguments['addUncoveredFilesFromWhitelist']) ? $arguments['addUncoveredFilesFromWhitelist'] : true; + $arguments['processUncoveredFilesFromWhitelist'] = isset($arguments['processUncoveredFilesFromWhitelist']) ? $arguments['processUncoveredFilesFromWhitelist'] : false; + $arguments['backupGlobals'] = isset($arguments['backupGlobals']) ? $arguments['backupGlobals'] : null; + $arguments['backupStaticAttributes'] = isset($arguments['backupStaticAttributes']) ? $arguments['backupStaticAttributes'] : null; + $arguments['cacheTokens'] = isset($arguments['cacheTokens']) ? $arguments['cacheTokens'] : false; + $arguments['colors'] = isset($arguments['colors']) ? $arguments['colors'] : false; + $arguments['convertErrorsToExceptions'] = isset($arguments['convertErrorsToExceptions']) ? $arguments['convertErrorsToExceptions'] : true; + $arguments['convertNoticesToExceptions'] = isset($arguments['convertNoticesToExceptions']) ? $arguments['convertNoticesToExceptions'] : true; + $arguments['convertWarningsToExceptions'] = isset($arguments['convertWarningsToExceptions']) ? $arguments['convertWarningsToExceptions'] : true; + $arguments['excludeGroups'] = isset($arguments['excludeGroups']) ? $arguments['excludeGroups'] : array(); + $arguments['groups'] = isset($arguments['groups']) ? $arguments['groups'] : array(); + $arguments['logIncompleteSkipped'] = isset($arguments['logIncompleteSkipped']) ? $arguments['logIncompleteSkipped'] : false; + $arguments['processIsolation'] = isset($arguments['processIsolation']) ? $arguments['processIsolation'] : false; + $arguments['repeat'] = isset($arguments['repeat']) ? $arguments['repeat'] : false; + $arguments['reportHighLowerBound'] = isset($arguments['reportHighLowerBound']) ? $arguments['reportHighLowerBound'] : 90; + $arguments['reportLowUpperBound'] = isset($arguments['reportLowUpperBound']) ? $arguments['reportLowUpperBound'] : 50; + $arguments['stopOnError'] = isset($arguments['stopOnError']) ? $arguments['stopOnError'] : false; + $arguments['stopOnFailure'] = isset($arguments['stopOnFailure']) ? $arguments['stopOnFailure'] : false; + $arguments['stopOnIncomplete'] = isset($arguments['stopOnIncomplete']) ? $arguments['stopOnIncomplete'] : false; + $arguments['stopOnRisky'] = isset($arguments['stopOnRisky']) ? $arguments['stopOnRisky'] : false; + $arguments['stopOnSkipped'] = isset($arguments['stopOnSkipped']) ? $arguments['stopOnSkipped'] : false; + $arguments['timeoutForSmallTests'] = isset($arguments['timeoutForSmallTests']) ? $arguments['timeoutForSmallTests'] : 1; + $arguments['timeoutForMediumTests'] = isset($arguments['timeoutForMediumTests']) ? $arguments['timeoutForMediumTests'] : 10; + $arguments['timeoutForLargeTests'] = isset($arguments['timeoutForLargeTests']) ? $arguments['timeoutForLargeTests'] : 60; + $arguments['reportUselessTests'] = isset($arguments['reportUselessTests']) ? $arguments['reportUselessTests'] : false; + $arguments['strictCoverage'] = isset($arguments['strictCoverage']) ? $arguments['strictCoverage'] : false; + $arguments['disallowTestOutput'] = isset($arguments['disallowTestOutput']) ? $arguments['disallowTestOutput'] : false; + $arguments['enforceTimeLimit'] = isset($arguments['enforceTimeLimit']) ? $arguments['enforceTimeLimit'] : false; + $arguments['disallowTodoAnnotatedTests'] = isset($arguments['disallowTodoAnnotatedTests']) ? $arguments['disallowTodoAnnotatedTests'] : false; + $arguments['verbose'] = isset($arguments['verbose']) ? $arguments['verbose'] : false; + } + + /** + * @param $extension + * @param string $message + * @since Method available since Release 4.0.0 + */ + private function showExtensionNotLoadedMessage($extension, $message = '') + { + if (isset($this->missingExtensions[$extension])) { + return; + } + + if (!empty($message)) { + $message = ' ' . $message; + } + + $this->showMessage( + 'The ' . $extension . ' extension is not loaded.' . $message . "\n" + ); + + $this->missingExtensions[$extension] = true; + } + + /** + * Shows a message. + * + * @param string $message + * @param boolean $exit + * @since Method available since Release 4.0.0 + */ + private function showMessage($message, $exit = false) + { + $this->write($message . "\n"); + + if ($exit) { + exit(self::EXCEPTION_EXIT); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A TestRunner for the Command Line Interface (CLI) + * PHP SAPI Module. + * + * @package PHPUnit + * @subpackage TextUI + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_TextUI_Command +{ + /** + * @var array + */ + protected $arguments = array( + 'listGroups' => false, + 'loader' => null, + 'useDefaultConfiguration' => true + ); + + /** + * @var array + */ + protected $options = array(); + + /** + * @var array + */ + protected $longOptions = array( + 'colors' => null, + 'bootstrap=' => null, + 'configuration=' => null, + 'coverage-clover=' => null, + 'coverage-crap4j=' => null, + 'coverage-html=' => null, + 'coverage-php=' => null, + 'coverage-text==' => null, + 'coverage-xml=' => null, + 'debug' => null, + 'exclude-group=' => null, + 'filter=' => null, + 'testsuite=' => null, + 'group=' => null, + 'help' => null, + 'include-path=' => null, + 'list-groups' => null, + 'loader=' => null, + 'log-json=' => null, + 'log-junit=' => null, + 'log-tap=' => null, + 'process-isolation' => null, + 'repeat=' => null, + 'stderr' => null, + 'stop-on-error' => null, + 'stop-on-failure' => null, + 'stop-on-incomplete' => null, + 'stop-on-risky' => null, + 'stop-on-skipped' => null, + 'report-useless-tests' => null, + 'strict-coverage' => null, + 'disallow-test-output' => null, + 'enforce-time-limit' => null, + 'disallow-todo-tests' => null, + 'strict' => null, + 'tap' => null, + 'testdox' => null, + 'testdox-html=' => null, + 'testdox-text=' => null, + 'test-suffix=' => null, + 'no-configuration' => null, + 'no-globals-backup' => null, + 'printer=' => null, + 'static-backup' => null, + 'verbose' => null, + 'version' => null + ); + + /** + * @var boolean + */ + private $versionStringPrinted = false; + + /** + * @param boolean $exit + */ + public static function main($exit = true) + { + $command = new static; + + return $command->run($_SERVER['argv'], $exit); + } + + /** + * @param array $argv + * @param boolean $exit + * @return integer + */ + public function run(array $argv, $exit = true) + { + $this->handleArguments($argv); + + $runner = $this->createRunner(); + + if (is_object($this->arguments['test']) && + $this->arguments['test'] instanceof PHPUnit_Framework_Test) { + $suite = $this->arguments['test']; + } else { + $suite = $runner->getTest( + $this->arguments['test'], + $this->arguments['testFile'], + $this->arguments['testSuffixes'] + ); + } + + if ($this->arguments['listGroups']) { + $this->printVersionString(); + + print "Available test group(s):\n"; + + $groups = $suite->getGroups(); + sort($groups); + + foreach ($groups as $group) { + print " - $group\n"; + } + + if ($exit) { + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } else { + return PHPUnit_TextUI_TestRunner::SUCCESS_EXIT; + } + } + + unset($this->arguments['test']); + unset($this->arguments['testFile']); + + try { + $result = $runner->doRun($suite, $this->arguments); + } catch (PHPUnit_Framework_Exception $e) { + print $e->getMessage() . "\n"; + } + + $ret = PHPUnit_TextUI_TestRunner::FAILURE_EXIT; + + if (isset($result) && $result->wasSuccessful()) { + $ret = PHPUnit_TextUI_TestRunner::SUCCESS_EXIT; + } elseif (!isset($result) || $result->errorCount() > 0) { + $ret = PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT; + } + + if ($exit) { + exit($ret); + } else { + return $ret; + } + } + + /** + * Create a TestRunner, override in subclasses. + * + * @return PHPUnit_TextUI_TestRunner + * @since Method available since Release 3.6.0 + */ + protected function createRunner() + { + return new PHPUnit_TextUI_TestRunner($this->arguments['loader']); + } + + /** + * Handles the command-line arguments. + * + * A child class of PHPUnit_TextUI_Command can hook into the argument + * parsing by adding the switch(es) to the $longOptions array and point to a + * callback method that handles the switch(es) in the child class like this + * + * + * longOptions['my-switch'] = 'myHandler'; + * // my-secondswitch will accept a value - note the equals sign + * $this->longOptions['my-secondswitch='] = 'myOtherHandler'; + * } + * + * // --my-switch -> myHandler() + * protected function myHandler() + * { + * } + * + * // --my-secondswitch foo -> myOtherHandler('foo') + * protected function myOtherHandler ($value) + * { + * } + * + * // You will also need this - the static keyword in the + * // PHPUnit_TextUI_Command will mean that it'll be + * // PHPUnit_TextUI_Command that gets instantiated, + * // not MyCommand + * public static function main($exit = true) + * { + * $command = new static; + * + * return $command->run($_SERVER['argv'], $exit); + * } + * + * } + * + * + * @param array $argv + */ + protected function handleArguments(array $argv) + { + if (defined('__PHPUNIT_PHAR__')) { + $this->longOptions['selfupdate'] = null; + $this->longOptions['self-update'] = null; + } + + try { + $this->options = PHPUnit_Util_Getopt::getopt( + $argv, + 'd:c:hv', + array_keys($this->longOptions) + ); + } catch (PHPUnit_Framework_Exception $e) { + $this->showError($e->getMessage()); + } + + foreach ($this->options[0] as $option) { + switch ($option[0]) { + case '--colors': { + $this->arguments['colors'] = true; + } + break; + + case '--bootstrap': { + $this->arguments['bootstrap'] = $option[1]; + } + break; + + case 'c': + case '--configuration': { + $this->arguments['configuration'] = $option[1]; + } + break; + + case '--coverage-clover': { + $this->arguments['coverageClover'] = $option[1]; + } + break; + + case '--coverage-crap4j': { + $this->arguments['coverageCrap4J'] = $option[1]; + } + break; + + case '--coverage-html': { + $this->arguments['coverageHtml'] = $option[1]; + } + break; + + case '--coverage-php': { + $this->arguments['coveragePHP'] = $option[1]; + } + break; + + case '--coverage-text': { + if ($option[1] === null) { + $option[1] = 'php://stdout'; + } + + $this->arguments['coverageText'] = $option[1]; + $this->arguments['coverageTextShowUncoveredFiles'] = false; + $this->arguments['coverageTextShowOnlySummary'] = false; + } + break; + + case '--coverage-xml': { + $this->arguments['coverageXml'] = $option[1]; + } + break; + + case 'd': { + $ini = explode('=', $option[1]); + + if (isset($ini[0])) { + if (isset($ini[1])) { + ini_set($ini[0], $ini[1]); + } else { + ini_set($ini[0], true); + } + } + } + break; + + case '--debug': { + $this->arguments['debug'] = true; + } + break; + + case 'h': + case '--help': { + $this->showHelp(); + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } + break; + + case '--filter': { + $this->arguments['filter'] = $option[1]; + } + break; + + case '--testsuite': { + $this->arguments['testsuite'] = $option[1]; + } + break; + + case '--group': { + $this->arguments['groups'] = explode(',', $option[1]); + } + break; + + case '--exclude-group': { + $this->arguments['excludeGroups'] = explode( + ',', $option[1] + ); + } + break; + + case '--test-suffix': { + $this->arguments['testSuffixes'] = explode( + ',', $option[1] + ); + } + break; + + case '--include-path': { + $includePath = $option[1]; + } + break; + + case '--list-groups': { + $this->arguments['listGroups'] = true; + } + break; + + case '--printer': { + $this->arguments['printer'] = $option[1]; + } + break; + + case '--loader': { + $this->arguments['loader'] = $option[1]; + } + break; + + case '--log-json': { + $this->arguments['jsonLogfile'] = $option[1]; + } + break; + + case '--log-junit': { + $this->arguments['junitLogfile'] = $option[1]; + } + break; + + case '--log-tap': { + $this->arguments['tapLogfile'] = $option[1]; + } + break; + + case '--process-isolation': { + $this->arguments['processIsolation'] = true; + } + break; + + case '--repeat': { + $this->arguments['repeat'] = (int) $option[1]; + } + break; + + case '--stderr': { + $this->arguments['stderr'] = true; + } + break; + + case '--stop-on-error': { + $this->arguments['stopOnError'] = true; + } + break; + + case '--stop-on-failure': { + $this->arguments['stopOnFailure'] = true; + } + break; + + case '--stop-on-incomplete': { + $this->arguments['stopOnIncomplete'] = true; + } + break; + + case '--stop-on-risky': { + $this->arguments['stopOnRisky'] = true; + } + break; + + case '--stop-on-skipped': { + $this->arguments['stopOnSkipped'] = true; + } + break; + + case '--tap': { + $this->arguments['printer'] = 'PHPUnit_Util_Log_TAP'; + } + break; + + case '--testdox': { + $this->arguments['printer'] = 'PHPUnit_Util_TestDox_ResultPrinter_Text'; + } + break; + + case '--testdox-html': { + $this->arguments['testdoxHTMLFile'] = $option[1]; + } + break; + + case '--testdox-text': { + $this->arguments['testdoxTextFile'] = $option[1]; + } + break; + + case '--no-configuration': { + $this->arguments['useDefaultConfiguration'] = false; + } + break; + + case '--no-globals-backup': { + $this->arguments['backupGlobals'] = false; + } + break; + + case '--static-backup': { + $this->arguments['backupStaticAttributes'] = true; + } + break; + + case 'v': + case '--verbose': { + $this->arguments['verbose'] = true; + } + break; + + case '--version': { + $this->printVersionString(); + exit(PHPUnit_TextUI_TestRunner::SUCCESS_EXIT); + } + break; + + case '--report-useless-tests': { + $this->arguments['reportUselessTests'] = true; + } + break; + + case '--strict-coverage': { + $this->arguments['strictCoverage'] = true; + } + break; + + case '--disallow-test-output': { + $this->arguments['disallowTestOutput'] = true; + } + break; + + case '--enforce-time-limit': { + $this->arguments['enforceTimeLimit'] = true; + } + break; + + case '--disallow-todo-tests': { + $this->arguments['disallowTodoAnnotatedTests'] = true; + } + break; + + case '--strict': { + $this->arguments['reportUselessTests'] = true; + $this->arguments['strictCoverage'] = true; + $this->arguments['disallowTestOutput'] = true; + $this->arguments['enforceTimeLimit'] = true; + $this->arguments['disallowTodoAnnotatedTests'] = true; + } + break; + + case '--selfupdate': + case '--self-update': { + $this->handleSelfUpdate(); + } + break; + + default: { + $optionName = str_replace('--', '', $option[0]); + + if (isset($this->longOptions[$optionName])) { + $handler = $this->longOptions[$optionName]; + } elseif (isset($this->longOptions[$optionName . '='])) { + $handler = $this->longOptions[$optionName . '=']; + } + + if (isset($handler) && is_callable(array($this, $handler))) { + $this->$handler($option[1]); + } + } + } + } + + $this->handleCustomTestSuite(); + + if (!isset($this->arguments['test'])) { + if (isset($this->options[1][0])) { + $this->arguments['test'] = $this->options[1][0]; + } + + if (isset($this->options[1][1])) { + $this->arguments['testFile'] = realpath($this->options[1][1]); + } else { + $this->arguments['testFile'] = ''; + } + + if (isset($this->arguments['test']) && + is_file($this->arguments['test']) && + substr($this->arguments['test'], -5, 5) != '.phpt') { + $this->arguments['testFile'] = realpath($this->arguments['test']); + $this->arguments['test'] = substr($this->arguments['test'], 0, strrpos($this->arguments['test'], '.')); + } + } + + if (!isset($this->arguments['testSuffixes'])) { + $this->arguments['testSuffixes'] = array('Test.php', '.phpt'); + } + + if (isset($includePath)) { + ini_set( + 'include_path', + $includePath . PATH_SEPARATOR . ini_get('include_path') + ); + } + + if ($this->arguments['loader'] !== null) { + $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']); + } + + if (isset($this->arguments['configuration']) && + is_dir($this->arguments['configuration'])) { + $configurationFile = $this->arguments['configuration'] . + '/phpunit.xml'; + + if (file_exists($configurationFile)) { + $this->arguments['configuration'] = realpath( + $configurationFile + ); + } elseif (file_exists($configurationFile . '.dist')) { + $this->arguments['configuration'] = realpath( + $configurationFile . '.dist' + ); + } + } elseif (!isset($this->arguments['configuration']) && + $this->arguments['useDefaultConfiguration']) { + if (file_exists('phpunit.xml')) { + $this->arguments['configuration'] = realpath('phpunit.xml'); + } elseif (file_exists('phpunit.xml.dist')) { + $this->arguments['configuration'] = realpath( + 'phpunit.xml.dist' + ); + } + } + + if (isset($this->arguments['configuration'])) { + try { + $configuration = PHPUnit_Util_Configuration::getInstance( + $this->arguments['configuration'] + ); + } catch (Exception $e) { + print $e->getMessage() . "\n"; + exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); + } + + $phpunit = $configuration->getPHPUnitConfiguration(); + + $configuration->handlePHPConfiguration(); + + /** + * Issue #1216 + */ + if (isset($this->arguments['bootstrap'])) { + $this->handleBootstrap($this->arguments['bootstrap']); + } elseif (isset($phpunit['bootstrap'])) { + $this->handleBootstrap($phpunit['bootstrap']); + } + + /** + * Issue #657 + */ + if (isset($phpunit['stderr']) && ! isset($this->arguments['stderr'])) { + $this->arguments['stderr'] = $phpunit['stderr']; + } + + if (isset($phpunit['printerClass'])) { + if (isset($phpunit['printerFile'])) { + $file = $phpunit['printerFile']; + } else { + $file = ''; + } + + $this->arguments['printer'] = $this->handlePrinter( + $phpunit['printerClass'], $file + ); + } + + if (isset($phpunit['testSuiteLoaderClass'])) { + if (isset($phpunit['testSuiteLoaderFile'])) { + $file = $phpunit['testSuiteLoaderFile']; + } else { + $file = ''; + } + + $this->arguments['loader'] = $this->handleLoader( + $phpunit['testSuiteLoaderClass'], $file + ); + } + + $browsers = $configuration->getSeleniumBrowserConfiguration(); + + if (!empty($browsers) && + class_exists('PHPUnit_Extensions_SeleniumTestCase')) { + PHPUnit_Extensions_SeleniumTestCase::$browsers = $browsers; + } + + if (!isset($this->arguments['test'])) { + $testSuite = $configuration->getTestSuiteConfiguration(isset($this->arguments['testsuite']) ? $this->arguments['testsuite'] : null); + + if ($testSuite !== null) { + $this->arguments['test'] = $testSuite; + } + } + } elseif (isset($this->arguments['bootstrap'])) { + $this->handleBootstrap($this->arguments['bootstrap']); + } + + if (isset($this->arguments['printer']) && + is_string($this->arguments['printer'])) { + $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']); + } + + if (isset($this->arguments['test']) && is_string($this->arguments['test']) && substr($this->arguments['test'], -5, 5) == '.phpt') { + $test = new PHPUnit_Extensions_PhptTestCase($this->arguments['test']); + + $this->arguments['test'] = new PHPUnit_Framework_TestSuite; + $this->arguments['test']->addTest($test); + } + + if (!isset($this->arguments['test']) || + (isset($this->arguments['testDatabaseLogRevision']) && !isset($this->arguments['testDatabaseDSN']))) { + $this->showHelp(); + exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); + } + } + + /** + * Handles the loading of the PHPUnit_Runner_TestSuiteLoader implementation. + * + * @param string $loaderClass + * @param string $loaderFile + * @return PHPUnit_Runner_TestSuiteLoader + */ + protected function handleLoader($loaderClass, $loaderFile = '') + { + if (!class_exists($loaderClass, false)) { + if ($loaderFile == '') { + $loaderFile = PHPUnit_Util_Filesystem::classNameToFilename( + $loaderClass + ); + } + + $loaderFile = stream_resolve_include_path($loaderFile); + + if ($loaderFile) { + require $loaderFile; + } + } + + if (class_exists($loaderClass, false)) { + $class = new ReflectionClass($loaderClass); + + if ($class->implementsInterface('PHPUnit_Runner_TestSuiteLoader') && + $class->isInstantiable()) { + return $class->newInstance(); + } + } + + if ($loaderClass == 'PHPUnit_Runner_StandardTestSuiteLoader') { + return; + } + + $this->showError( + sprintf( + 'Could not use "%s" as loader.', + $loaderClass + ) + ); + } + + /** + * Handles the loading of the PHPUnit_Util_Printer implementation. + * + * @param string $printerClass + * @param string $printerFile + * @return PHPUnit_Util_Printer + */ + protected function handlePrinter($printerClass, $printerFile = '') + { + if (!class_exists($printerClass, false)) { + if ($printerFile == '') { + $printerFile = PHPUnit_Util_Filesystem::classNameToFilename( + $printerClass + ); + } + + $printerFile = stream_resolve_include_path($printerFile); + + if ($printerFile) { + require $printerFile; + } + } + + if (class_exists($printerClass)) { + $class = new ReflectionClass($printerClass); + + if ($class->implementsInterface('PHPUnit_Framework_TestListener') && + $class->isSubclassOf('PHPUnit_Util_Printer') && + $class->isInstantiable()) { + if ($class->isSubclassOf('PHPUnit_TextUI_ResultPrinter')) { + return $printerClass; + } + + $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null; + + return $class->newInstance($outputStream); + } + } + + $this->showError( + sprintf( + 'Could not use "%s" as printer.', + $printerClass + ) + ); + } + + /** + * Loads a bootstrap file. + * + * @param string $filename + */ + protected function handleBootstrap($filename) + { + try { + PHPUnit_Util_Fileloader::checkAndLoad($filename); + } catch (PHPUnit_Framework_Exception $e) { + $this->showError($e->getMessage()); + } + } + + /** + * @since Method available since Release 4.0.0 + */ + protected function handleSelfUpdate() + { + $this->printVersionString(); + + if (!extension_loaded('openssl')) { + print "The OpenSSL extension is not loaded.\n"; + exit(PHPUnit_TextUI_TestRunner::EXCEPTION_EXIT); + } + + $remoteFilename = sprintf( + 'https://phar.phpunit.de/phpunit%s.phar', + PHPUnit_Runner_Version::getReleaseChannel() + ); + + $localFilename = realpath($_SERVER['argv'][0]); + $tempFilename = basename($localFilename, '.phar') . '-temp.phar'; + + // Workaround for https://bugs.php.net/bug.php?id=65538 + $caFile = dirname($tempFilename) . '/ca.pem'; + copy(__PHPUNIT_PHAR_ROOT__ . '/ca.pem', $caFile); + + print 'Updating the PHPUnit PHAR ... '; + + $options = array( + 'ssl' => array( + 'allow_self_signed' => false, + 'cafile' => $caFile, + 'verify_peer' => true + ) + ); + + if (PHP_VERSION_ID < 50600) { + $options['ssl']['CN_match'] = 'phar.phpunit.de'; + $options['ssl']['SNI_server_name'] = 'phar.phpunit.de'; + } + + file_put_contents( + $tempFilename, + file_get_contents( + $remoteFilename, + false, + stream_context_create($options) + ) + ); + + chmod($tempFilename, 0777 & ~umask()); + + try { + $phar = new Phar($tempFilename); + unset($phar); + rename($tempFilename, $localFilename); + unlink($caFile); + } catch (Exception $e) { + unlink($caFile); + unlink($tempFilename); + print " done\n\n" . $e->getMessage() . "\n"; + exit(2); + } + + print " done\n"; + exit(0); + } + + /** + * Show the help message. + */ + protected function showHelp() + { + $this->printVersionString(); + + print << + +Code Coverage Options: + + --coverage-clover Generate code coverage report in Clover XML format. + --coverage-crap4j Generate code coverage report in Crap4J XML format. + --coverage-html

    Generate code coverage report in HTML format. + --coverage-php Export PHP_CodeCoverage object to file. + --coverage-text= Generate code coverage report in text format. + Default: Standard output. + --coverage-xml Generate code coverage report in PHPUnit XML format. + +Logging Options: + + --log-junit Log test execution in JUnit XML format to file. + --log-tap Log test execution in TAP format to file. + --log-json Log test execution in JSON format. + --testdox-html Write agile documentation in HTML format to file. + --testdox-text Write agile documentation in Text format to file. + +Test Selection Options: + + --filter Filter which tests to run. + --testsuite Filter which testsuite to run. + --group ... Only runs tests from the specified group(s). + --exclude-group ... Exclude tests from the specified group(s). + --list-groups List available test groups. + --test-suffix ... Only search for test in files with specified + suffix(es). Default: Test.php,.phpt + +Test Execution Options: + + --report-useless-tests Be strict about tests that do not test anything. + --strict-coverage Be strict about unintentionally covered code. + --disallow-test-output Be strict about output during tests. + --enforce-time-limit Enforce time limit based on test size. + --disallow-todo-tests Disallow @todo-annotated tests. + --strict Run tests in strict mode (enables all of the above). + + --process-isolation Run each test in a separate PHP process. + --no-globals-backup Do not backup and restore \$GLOBALS for each test. + --static-backup Backup and restore static attributes for each test. + + --colors Use colors in output. + --stderr Write to STDERR instead of STDOUT. + --stop-on-error Stop execution upon first error. + --stop-on-failure Stop execution upon first error or failure. + --stop-on-risky Stop execution upon first risky test. + --stop-on-skipped Stop execution upon first skipped test. + --stop-on-incomplete Stop execution upon first incomplete test. + -v|--verbose Output more verbose information. + --debug Display debugging information during test execution. + + --loader TestSuiteLoader implementation to use. + --repeat Runs the test(s) repeatedly. + --tap Report test execution progress in TAP format. + --testdox Report test execution progress in TestDox format. + --printer TestListener implementation to use. + +Configuration Options: + + --bootstrap A "bootstrap" PHP file that is run before the tests. + -c|--configuration Read configuration from XML file. + --no-configuration Ignore default configuration file (phpunit.xml). + --include-path Prepend PHP's include_path with given path(s). + -d key[=value] Sets a php.ini value. + +Miscellaneous Options: + + -h|--help Prints this usage information. + --version Prints the version and exits. + +EOT; + + if (defined('__PHPUNIT_PHAR__')) { + print "\n --self-update Update PHPUnit to the latest version.\n"; + } + } + + /** + * Custom callback for test suite discovery. + */ + protected function handleCustomTestSuite() + { + } + + private function printVersionString() + { + if ($this->versionStringPrinted) { + return; + } + + print PHPUnit_Runner_Version::getVersionString() . "\n\n"; + + $this->versionStringPrinted = true; + } + + /** + */ + private function showError($message) + { + $this->printVersionString(); + + print $message . "\n"; + + exit(PHPUnit_TextUI_TestRunner::FAILURE_EXIT); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Marker interface for PHPUnit exceptions. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 4.0.0 + */ +interface PHPUnit_Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Suite for .phpt test cases. + * + * @package PHPUnit + * @subpackage Extensions_PhptTestCase + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Extensions_PhptTestSuite extends PHPUnit_Framework_TestSuite +{ + /** + * Constructs a new TestSuite for .phpt test cases. + * + * @param string $directory + * @param array $options Array with ini settings for the php instance run, + * key being the name if the setting, value the ini value. + * @throws PHPUnit_Framework_Exception + */ + public function __construct($directory, array $options = array()) + { + if (is_string($directory) && is_dir($directory)) { + $this->setName($directory); + + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray($directory, '.phpt'); + + foreach ($files as $file) { + $this->addTestFile($file, $options); + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'directory name'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Base class for test listeners that interact with an issue tracker. + * + * @package PHPUnit + * @subpackage Extensions_TicketListener + * @author Sean Coates + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +abstract class PHPUnit_Extensions_TicketListener implements PHPUnit_Framework_TestListener +{ + /** + * @var array + */ + protected $ticketCounts = array(); + + /** + * @var boolean + */ + protected $ran = false; + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($this->ran) { + return; + } + + $name = $test->getName(false); + $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name); + + foreach ($tickets as $ticket) { + $this->ticketCounts[$ticket][$name] = 1; + } + + $this->ran = true; + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $ifStatus = array('assigned', 'new', 'reopened'); + $newStatus = 'closed'; + $message = 'Automatically closed by PHPUnit (test passed).'; + $resolution = 'fixed'; + $cumulative = true; + } elseif ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE) { + $ifStatus = array('closed'); + $newStatus = 'reopened'; + $message = 'Automatically reopened by PHPUnit (test failed).'; + $resolution = ''; + $cumulative = false; + } else { + return; + } + + $name = $test->getName(false); + $tickets = PHPUnit_Util_Test::getTickets(get_class($test), $name); + + foreach ($tickets as $ticket) { + // Remove this test from the totals (if it passed). + if ($test->getStatus() == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + unset($this->ticketCounts[$ticket][$name]); + } + + // Only close tickets if ALL referenced cases pass + // but reopen tickets if a single test fails. + if ($cumulative) { + // Determine number of to-pass tests: + if (count($this->ticketCounts[$ticket]) > 0) { + // There exist remaining test cases with this reference. + $adjustTicket = false; + } else { + // No remaining tickets, go ahead and adjust. + $adjustTicket = true; + } + } else { + $adjustTicket = true; + } + + $ticketInfo = $this->getTicketInfo($ticket); + + if ($adjustTicket && in_array($ticketInfo['status'], $ifStatus)) { + $this->updateTicket($ticket, $newStatus, $message, $resolution); + } + } + } + } + + abstract protected function getTicketInfo($ticketId = null); + abstract protected function updateTicket($ticketId, $newStatus, $message, $resolution); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A Decorator for Tests. + * + * Use TestDecorator as the base class for defining new + * test decorators. Test decorator subclasses can be introduced + * to add behaviour before or after a test is run. + * + * @package PHPUnit + * @subpackage Extensions + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Extensions_TestDecorator extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * The Test to be decorated. + * + * @var object + */ + protected $test = null; + + /** + * Constructor. + * + * @param PHPUnit_Framework_Test $test + */ + public function __construct(PHPUnit_Framework_Test $test) + { + $this->test = $test; + } + + /** + * Returns a string representation of the test. + * + * @return string + */ + public function toString() + { + return $this->test->toString(); + } + + /** + * Runs the test and collects the + * result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + */ + public function basicRun(PHPUnit_Framework_TestResult $result) + { + $this->test->run($result); + } + + /** + * Counts the number of test cases that + * will be run by this test. + * + * @return integer + */ + public function count() + { + return count($this->test); + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * Returns the test to be run. + * + * @return PHPUnit_Framework_Test + */ + public function getTest() + { + return $this->test; + } + + /** + * Runs the decorated test and collects the + * result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = null) + { + if ($result === null) { + $result = $this->createResult(); + } + + $this->basicRun($result); + + return $result; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A Decorator that runs a test repeatedly. + * + * @package PHPUnit + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Extensions_RepeatedTest extends PHPUnit_Extensions_TestDecorator +{ + /** + * @var mixed + */ + protected $filter = false; + + /** + * @var array + */ + protected $groups = array(); + + /** + * @var array + */ + protected $excludeGroups = array(); + + /** + * @var boolean + */ + protected $processIsolation = false; + + /** + * @var integer + */ + protected $timesRepeat = 1; + + /** + * @param PHPUnit_Framework_Test $test + * @param integer $timesRepeat + * @param boolean $processIsolation + * @throws PHPUnit_Framework_Exception + */ + public function __construct(PHPUnit_Framework_Test $test, $timesRepeat = 1, $processIsolation = false) + { + parent::__construct($test); + + if (is_integer($timesRepeat) && + $timesRepeat >= 0) { + $this->timesRepeat = $timesRepeat; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'positive integer' + ); + } + + $this->processIsolation = $processIsolation; + } + + /** + * Counts the number of test cases that + * will be run by this test. + * + * @return integer + */ + public function count() + { + return $this->timesRepeat * count($this->test); + } + + /** + * Runs the decorated test and collects the + * result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws PHPUnit_Framework_Exception + */ + public function run(PHPUnit_Framework_TestResult $result = null) + { + if ($result === null) { + $result = $this->createResult(); + } + + //@codingStandardsIgnoreStart + for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) { + //@codingStandardsIgnoreEnd + if ($this->test instanceof PHPUnit_Framework_TestSuite) { + $this->test->setRunTestInSeparateProcess($this->processIsolation); + } + $this->test->run($result); + } + + return $result; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * We have a TestSuite object A. + * In TestSuite object A we have Tests tagged with @group. + * We want a TestSuite object B that contains TestSuite objects C, D, ... + * for the Tests tagged with @group C, @group D, ... + * Running the Tests from TestSuite object B results in Tests tagged with both + * @group C and @group D in TestSuite object A to be run twice . + * + * + * $suite = new PHPUnit_Extensions_GroupTestSuite($A, array('C', 'D')); + * + * + * @package PHPUnit + * @subpackage Extensions + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Extensions_GroupTestSuite extends PHPUnit_Framework_TestSuite +{ + public function __construct(PHPUnit_Framework_TestSuite $suite, array $groups) + { + $groupSuites = array(); + $name = $suite->getName(); + + foreach ($groups as $group) { + $groupSuites[$group] = new PHPUnit_Framework_TestSuite($name . ' - ' . $group); + $this->addTest($groupSuites[$group]); + } + + $tests = new RecursiveIteratorIterator( + new PHPUnit_Util_TestSuiteIterator($suite), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($tests as $test) { + if ($test instanceof PHPUnit_Framework_TestCase) { + $testGroups = PHPUnit_Util_Test::getGroups( + get_class($test), $test->getName(false) + ); + + foreach ($groups as $group) { + foreach ($testGroups as $testGroup) { + if ($group == $testGroup) { + $groupSuites[$group]->addTest($test); + } + } + } + } + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Runner for PHPT test cases. + * + * @package PHPUnit + * @subpackage Extensions_PhptTestCase + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Extensions_PhptTestCase implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * @var string + */ + private $filename; + + /** + * @var array + */ + private $settings = array( + 'allow_url_fopen=1', + 'auto_append_file=', + 'auto_prepend_file=', + 'disable_functions=', + 'display_errors=1', + 'docref_root=', + 'docref_ext=.html', + 'error_append_string=', + 'error_prepend_string=', + 'error_reporting=-1', + 'html_errors=0', + 'log_errors=0', + 'magic_quotes_runtime=0', + 'output_handler=', + 'open_basedir=', + 'output_buffering=Off', + 'report_memleaks=0', + 'report_zend_debug=0', + 'safe_mode=0', + 'track_errors=1', + 'xdebug.default_enable=0' + ); + + /** + * Constructs a test case with the given filename. + * + * @param string $filename + * @throws PHPUnit_Framework_Exception + */ + public function __construct($filename) + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_file($filename)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'File "%s" does not exist.', + $filename + ) + ); + } + + $this->filename = $filename; + } + + /** + * Counts the number of test cases executed by run(TestResult result). + * + * @return integer + */ + public function count() + { + return 1; + } + + /** + * Runs a test and collects its result in a TestResult instance. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = null) + { + $sections = $this->parse(); + $code = $this->render($sections['FILE']); + + if ($result === null) { + $result = new PHPUnit_Framework_TestResult; + } + + $php = PHPUnit_Util_PHP::factory(); + $skip = false; + $time = 0; + + $result->startTest($this); + + if (isset($sections['SKIPIF'])) { + $jobResult = $php->runJob($sections['SKIPIF'], $this->settings); + + if (!strncasecmp('skip', ltrim($jobResult['stdout']), 4)) { + if (preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $message)) { + $message = substr($message[1], 2); + } else { + $message = ''; + } + + $result->addFailure($this, new PHPUnit_Framework_SkippedTestError($message), 0); + + $skip = true; + } + } + + if (!$skip) { + PHP_Timer::start(); + $jobResult = $php->runJob($code, $this->settings); + $time = PHP_Timer::stop(); + + if (isset($sections['EXPECT'])) { + $assertion = 'assertEquals'; + $expected = $sections['EXPECT']; + } else { + $assertion = 'assertStringMatchesFormat'; + $expected = $sections['EXPECTF']; + } + + $output = preg_replace('/\r\n/', "\n", trim($jobResult['stdout'])); + $expected = preg_replace('/\r\n/', "\n", trim($expected)); + + try { + PHPUnit_Framework_Assert::$assertion($expected, $output); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + $result->addFailure($this, $e, $time); + } catch (Exception $e) { + $result->addError($this, $e, $time); + } + } + + $result->endTest($this, $time); + + return $result; + } + + /** + * Returns the name of the test case. + * + * @return string + */ + public function getName() + { + return $this->toString(); + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + return $this->filename; + } + + /** + * @return array + * @throws PHPUnit_Framework_Exception + */ + private function parse() + { + $sections = array(); + $section = ''; + + foreach (file($this->filename) as $line) { + if (preg_match('/^--([_A-Z]+)--/', $line, $result)) { + $section = $result[1]; + $sections[$section] = ''; + continue; + } elseif (empty($section)) { + throw new PHPUnit_Framework_Exception('Invalid PHPT file'); + } + + $sections[$section] .= $line; + } + + if (!isset($sections['FILE']) || + (!isset($sections['EXPECT']) && !isset($sections['EXPECTF']))) { + throw new PHPUnit_Framework_Exception('Invalid PHPT file'); + } + + return $sections; + } + + /** + * @param string $code + * @return string + */ + private function render($code) + { + return str_replace( + array( + '__DIR__', + '__FILE__' + ), + array( + "'" . dirname($this->filename) . "'", + "'" . $this->filename . "'" + ), + $code + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Wraps Exceptions thrown by code under test. + * + * Re-instantiates Exceptions thrown by user-space code to retain their original + * class names, properties, and stack traces (but without arguments). + * + * Unlike PHPUnit_Framework_Exception, the complete stack of previous Exceptions + * is processed. + * + * @package PHPUnit + * @subpackage Framework + * @author Daniel F. Kudwien + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.3.0 + */ +class PHPUnit_Framework_ExceptionWrapper extends PHPUnit_Framework_Exception +{ + /** + * @var string + */ + protected $classname; + + /** + * @var PHPUnit_Framework_ExceptionWrapper|null + */ + protected $previous; + + public function __construct(Exception $e) + { + // PDOException::getCode() is a string. + // @see http://php.net/manual/en/class.pdoexception.php#95812 + parent::__construct($e->getMessage(), (int) $e->getCode()); + + $this->classname = get_class($e); + $this->file = $e->getFile(); + $this->line = $e->getLine(); + + $this->serializableTrace = $e->getTrace(); + foreach ($this->serializableTrace as $i => $call) { + unset($this->serializableTrace[$i]['args']); + } + + if ($e->getPrevious()) { + $this->previous = new self($e->getPrevious()); + } + } + + /** + * @return string + */ + public function getClassname() + { + return $this->classname; + } + + /** + * @return PHPUnit_Framework_ExceptionWrapper + */ + public function getPreviousWrapped() + { + return $this->previous; + } + + /** + * @return string + */ + public function __toString() + { + $string = PHPUnit_Framework_TestFailure::exceptionToString($this); + + if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) { + $string .= "\n" . $trace; + } + + if ($this->previous) { + $string .= "\nCaused by\n" . $this->previous; + } + + return $string; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A TestFailure collects a failed test together with the caught exception. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_TestFailure +{ + /** + * @var string + */ + private $testName; + + /** + * @var PHPUnit_Framework_Test|null + */ + protected $failedTest; + + /** + * @var Exception + */ + protected $thrownException; + + /** + * Constructs a TestFailure with the given test and exception. + * + * @param PHPUnit_Framework_Test $failedTest + * @param Exception $thrownException + */ + public function __construct(PHPUnit_Framework_Test $failedTest, Exception $thrownException) + { + if ($failedTest instanceof PHPUnit_Framework_SelfDescribing) { + $this->testName = $failedTest->toString(); + } else { + $this->testName = get_class($failedTest); + } + if (!$failedTest instanceof PHPUnit_Framework_TestCase || !$failedTest->isInIsolation()) { + $this->failedTest = $failedTest; + } + $this->thrownException = $thrownException; + } + + /** + * Returns a short description of the failure. + * + * @return string + */ + public function toString() + { + return sprintf( + '%s: %s', + $this->testName, + $this->thrownException->getMessage() + ); + } + + /** + * Returns a description for the thrown exception. + * + * @return string + * @since Method available since Release 3.4.0 + */ + public function getExceptionAsString() + { + return self::exceptionToString($this->thrownException); + } + + /** + * Returns a description for an exception. + * + * @param Exception $e + * @return string + * @since Method available since Release 3.2.0 + */ + public static function exceptionToString(Exception $e) + { + if ($e instanceof PHPUnit_Framework_SelfDescribing) { + $buffer = $e->toString(); + + if ($e instanceof PHPUnit_Framework_ExpectationFailedException && $e->getComparisonFailure()) { + $buffer = $buffer . $e->getComparisonFailure()->getDiff(); + } + + if (!empty($buffer)) { + $buffer = trim($buffer) . "\n"; + } + } elseif ($e instanceof PHPUnit_Framework_Error) { + $buffer = $e->getMessage() . "\n"; + } elseif ($e instanceof PHPUnit_Framework_ExceptionWrapper) { + $buffer = $e->getClassname() . ': ' . $e->getMessage() . "\n"; + } else { + $buffer = get_class($e) . ': ' . $e->getMessage() . "\n"; + } + + return $buffer; + } + + /** + * Returns the name of the failing test (including data set, if any). + * + * @return string + * @since Method available since Release 4.3.0 + */ + public function getTestName() + { + return $this->testName; + } + + /** + * Returns the failing test. + * + * Note: The test object is not set when the test is executed in process + * isolation. + * + * @see PHPUnit_Framework_Exception + * + * @return PHPUnit_Framework_Test|null + */ + public function failedTest() + { + return $this->failedTest; + } + + /** + * Gets the thrown exception. + * + * @return Exception + */ + public function thrownException() + { + return $this->thrownException; + } + + /** + * Returns the exception's message. + * + * @return string + */ + public function exceptionMessage() + { + return $this->thrownException()->getMessage(); + } + + /** + * Returns true if the thrown exception + * is of type AssertionFailedError. + * + * @return boolean + */ + public function isFailure() + { + return ($this->thrownException() instanceof PHPUnit_Framework_AssertionFailedError); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A Test can be run and collect its results. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Framework_Test extends Countable +{ + /** + * Runs a test and collects its result in a TestResult instance. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = null); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Wrapper for PHP errors. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.2.0 + */ +class PHPUnit_Framework_Error extends PHPUnit_Framework_Exception +{ + /** + * Constructor. + * + * @param string $message + * @param integer $code + * @param string $file + * @param integer $line + * @param Exception $previous + */ + public function __construct($message, $code, $file, $line, Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->file = $file; + $this->line = $line; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Thrown when an assertion failed. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_AssertionFailedError extends PHPUnit_Framework_Exception implements PHPUnit_Framework_SelfDescribing +{ + /** + * Wrapper for getMessage() which is declared as final. + * + * @return string + */ + public function toString() + { + return $this->getMessage(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Exception for expectations which failed their check. + * + * The exception contains the error message and optionally a + * SebastianBergmann\Comparator\ComparisonFailure which is used to + * generate diff output of the failed expectations. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_ExpectationFailedException extends PHPUnit_Framework_AssertionFailedError +{ + /** + * @var SebastianBergmann\Comparator\ComparisonFailure + */ + protected $comparisonFailure; + + public function __construct($message, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null, Exception $previous = null) + { + $this->comparisonFailure = $comparisonFailure; + + parent::__construct($message, 0, $previous); + } + + /** + * @return SebastianBergmann\Comparator\ComparisonFailure + */ + public function getComparisonFailure() + { + return $this->comparisonFailure; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a risky test. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Framework_RiskyTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_RiskyTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a test that is skipped because of an invalid @covers annotation. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Framework_InvalidCoversTargetError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Interface for classes that can return a description of itself. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_SelfDescribing +{ + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString(); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A set of assert methods. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +abstract class PHPUnit_Framework_Assert +{ + /** + * @var integer + */ + private static $count = 0; + + /** + * Asserts that an array has a specified key. + * + * @param mixed $key + * @param array|ArrayAccess $array + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertArrayHasKey($key, $array, $message = '') + { + if (!(is_integer($key) || is_string($key))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'integer or string' + ); + } + + if (!(is_array($array) || $array instanceof ArrayAccess)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array or ArrayAccess' + ); + } + + $constraint = new PHPUnit_Framework_Constraint_ArrayHasKey($key); + + self::assertThat($array, $constraint, $message); + } + + /** + * Asserts that an array has a specified subset. + * + * @param array|ArrayAccess $subset + * @param array|ArrayAccess $array + * @param boolean $strict Check for object identity + * @param string $message + * @since Method available since Release 4.4.0 + */ + public static function assertArraySubset($subset, $array, $strict = false, $message = '') + { + if (!is_array($subset)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, 'array or ArrayAccess' + ); + } + + if (!is_array($array)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, 'array or ArrayAccess' + ); + } + + $constraint = new PHPUnit_Framework_Constraint_ArraySubset($subset, $strict); + + self::assertThat($array, $constraint, $message); + } + + /** + * Asserts that an array does not have a specified key. + * + * @param mixed $key + * @param array|ArrayAccess $array + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertArrayNotHasKey($key, $array, $message = '') + { + if (!(is_integer($key) || is_string($key))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'integer or string' + ); + } + + if (!(is_array($array) || $array instanceof ArrayAccess)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array or ArrayAccess' + ); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ArrayHasKey($key) + ); + + self::assertThat($array, $constraint, $message); + } + + /** + * Asserts that a haystack contains a needle. + * + * @param mixed $needle + * @param mixed $haystack + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 2.1.0 + */ + public static function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) + { + if (is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable) { + $constraint = new PHPUnit_Framework_Constraint_TraversableContains( + $needle, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ); + } elseif (is_string($haystack)) { + $constraint = new PHPUnit_Framework_Constraint_StringContains( + $needle, + $ignoreCase + ); + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array, traversable or string' + ); + } + + self::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains a needle. + * + * @param mixed $needle + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 3.0.0 + */ + public static function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) + { + self::assertContains( + $needle, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message, + $ignoreCase, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ); + } + + /** + * Asserts that a haystack does not contain a needle. + * + * @param mixed $needle + * @param mixed $haystack + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 2.1.0 + */ + public static function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) + { + if (is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable) { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_TraversableContains( + $needle, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ) + ); + } elseif (is_string($haystack)) { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringContains( + $needle, + $ignoreCase + ) + ); + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array, traversable or string' + ); + } + + self::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain a needle. + * + * @param mixed $needle + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 3.0.0 + */ + public static function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) + { + self::assertNotContains( + $needle, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message, + $ignoreCase, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ); + } + + /** + * Asserts that a haystack contains only values of a given type. + * + * @param string $type + * @param mixed $haystack + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '') + { + if (!(is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array or traversable' + ); + } + + if ($isNativeType == null) { + $isNativeType = PHPUnit_Util_Type::isType($type); + } + + self::assertThat( + $haystack, + new PHPUnit_Framework_Constraint_TraversableContainsOnly( + $type, + $isNativeType + ), + $message + ); + } + + /** + * Asserts that a haystack contains only instances of a given classname + * + * @param string $classname + * @param array|Traversable $haystack + * @param string $message + */ + public static function assertContainsOnlyInstancesOf($classname, $haystack, $message = '') + { + if (!(is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array or traversable' + ); + } + + self::assertThat( + $haystack, + new PHPUnit_Framework_Constraint_TraversableContainsOnly( + $classname, + false + ), + $message + ); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains only values of a given type. + * + * @param string $type + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '') + { + self::assertContainsOnly( + $type, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $isNativeType, + $message + ); + } + + /** + * Asserts that a haystack does not contain only values of a given type. + * + * @param string $type + * @param mixed $haystack + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '') + { + if (!(is_array($haystack) || + is_object($haystack) && $haystack instanceof Traversable)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 2, + 'array or traversable' + ); + } + + if ($isNativeType == null) { + $isNativeType = PHPUnit_Util_Type::isType($type); + } + + self::assertThat( + $haystack, + new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_TraversableContainsOnly( + $type, + $isNativeType + ) + ), + $message + ); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain only values of a given + * type. + * + * @param string $type + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ + public static function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '') + { + self::assertNotContainsOnly( + $type, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $isNativeType, + $message + ); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param integer $expectedCount + * @param mixed $haystack + * @param string $message + */ + public static function assertCount($expectedCount, $haystack, $message = '') + { + if (!is_int($expectedCount)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + if (!$haystack instanceof Countable && + !$haystack instanceof Traversable && + !is_array($haystack)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable'); + } + + self::assertThat( + $haystack, + new PHPUnit_Framework_Constraint_Count($expectedCount), + $message + ); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param integer $expectedCount + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.6.0 + */ + public static function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '') + { + self::assertCount( + $expectedCount, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param integer $expectedCount + * @param mixed $haystack + * @param string $message + */ + public static function assertNotCount($expectedCount, $haystack, $message = '') + { + if (!is_int($expectedCount)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + if (!$haystack instanceof Countable && + !$haystack instanceof Traversable && + !is_array($haystack)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_Count($expectedCount) + ); + + self::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param integer $expectedCount + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.6.0 + */ + public static function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '') + { + self::assertNotCount( + $expectedCount, + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts that two variables are equal. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + */ + public static function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $expected, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a variable is equal to an attribute of an object. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + */ + public static function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + self::assertEquals( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that two variables are not equal. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 2.3.0 + */ + public static function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsEqual( + $expected, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ) + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a variable is not equal to an attribute of an object. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + */ + public static function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + self::assertNotEquals( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that a variable is empty. + * + * @param mixed $actual + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertEmpty($actual, $message = '') + { + self::assertThat($actual, self::isEmpty(), $message); + } + + /** + * Asserts that a static attribute of a class or an attribute of an object + * is empty. + * + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '') + { + self::assertEmpty( + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts that a variable is not empty. + * + * @param mixed $actual + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertNotEmpty($actual, $message = '') + { + self::assertThat($actual, self::logicalNot(self::isEmpty()), $message); + } + + /** + * Asserts that a static attribute of a class or an attribute of an object + * is not empty. + * + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '') + { + self::assertNotEmpty( + self::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts that a value is greater than another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertGreaterThan($expected, $actual, $message = '') + { + self::assertThat($actual, self::greaterThan($expected), $message); + } + + /** + * Asserts that an attribute is greater than another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertGreaterThan( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is greater than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertGreaterThanOrEqual($expected, $actual, $message = '') + { + self::assertThat( + $actual, + self::greaterThanOrEqual($expected), + $message + ); + } + + /** + * Asserts that an attribute is greater than or equal to another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertGreaterThanOrEqual( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is smaller than another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertLessThan($expected, $actual, $message = '') + { + self::assertThat($actual, self::lessThan($expected), $message); + } + + /** + * Asserts that an attribute is smaller than another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertLessThan( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is smaller than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertLessThanOrEqual($expected, $actual, $message = '') + { + self::assertThat($actual, self::lessThanOrEqual($expected), $message); + } + + /** + * Asserts that an attribute is smaller than or equal to another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertLessThanOrEqual( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that the contents of one file is equal to the contents of another + * file. + * + * @param string $expected + * @param string $actual + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.2.14 + */ + public static function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false) + { + self::assertFileExists($expected, $message); + self::assertFileExists($actual, $message); + + self::assertEquals( + file_get_contents($expected), + file_get_contents($actual), + $message, + 0, + 10, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that the contents of one file is not equal to the contents of + * another file. + * + * @param string $expected + * @param string $actual + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.2.14 + */ + public static function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false) + { + self::assertFileExists($expected, $message); + self::assertFileExists($actual, $message); + + self::assertNotEquals( + file_get_contents($expected), + file_get_contents($actual), + $message, + 0, + 10, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that the contents of a string is equal + * to the contents of a file. + * + * @param string $expectedFile + * @param string $actualString + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.3.0 + */ + public static function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false) + { + self::assertFileExists($expectedFile, $message); + + self::assertEquals( + file_get_contents($expectedFile), + $actualString, + $message, + 0, + 10, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that the contents of a string is not equal + * to the contents of a file. + * + * @param string $expectedFile + * @param string $actualString + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.3.0 + */ + public static function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false) + { + self::assertFileExists($expectedFile, $message); + + self::assertNotEquals( + file_get_contents($expectedFile), + $actualString, + $message, + 0, + 10, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that a file exists. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertFileExists($filename, $message = '') + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_FileExists; + + self::assertThat($filename, $constraint, $message); + } + + /** + * Asserts that a file does not exist. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertFileNotExists($filename, $message = '') + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_FileExists + ); + + self::assertThat($filename, $constraint, $message); + } + + /** + * Asserts that a condition is true. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertTrue($condition, $message = '') + { + self::assertThat($condition, self::isTrue(), $message); + } + + /** + * Asserts that a condition is not true. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertNotTrue($condition, $message = '') + { + self::assertThat($condition, self::logicalNot(self::isTrue()), $message); + } + + /** + * Asserts that a condition is false. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertFalse($condition, $message = '') + { + self::assertThat($condition, self::isFalse(), $message); + } + + /** + * Asserts that a condition is not false. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function assertNotFalse($condition, $message = '') + { + self::assertThat($condition, self::logicalNot(self::isFalse()), $message); + } + + /** + * Asserts that a variable is not null. + * + * @param mixed $actual + * @param string $message + */ + public static function assertNotNull($actual, $message = '') + { + self::assertThat($actual, self::logicalNot(self::isNull()), $message); + } + + /** + * Asserts that a variable is null. + * + * @param mixed $actual + * @param string $message + */ + public static function assertNull($actual, $message = '') + { + self::assertThat($actual, self::isNull(), $message); + } + + /** + * Asserts that a class has a specified attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassHasAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name'); + } + + if (!is_string($className) || !class_exists($className, false)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_ClassHasAttribute( + $attributeName + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that a class does not have a specified attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassNotHasAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name'); + } + + if (!is_string($className) || !class_exists($className, false)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ClassHasAttribute($attributeName) + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that a class has a specified static attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassHasStaticAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name'); + } + + if (!is_string($className) || !class_exists($className, false)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( + $attributeName + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that a class does not have a specified static attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertClassNotHasStaticAttribute($attributeName, $className, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name'); + } + + if (!is_string($className) || !class_exists($className, false)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'class name'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( + $attributeName + ) + ); + + self::assertThat($className, $constraint, $message); + } + + /** + * Asserts that an object has a specified attribute. + * + * @param string $attributeName + * @param object $object + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertObjectHasAttribute($attributeName, $object, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name'); + } + + if (!is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object'); + } + + $constraint = new PHPUnit_Framework_Constraint_ObjectHasAttribute( + $attributeName + ); + + self::assertThat($object, $constraint, $message); + } + + /** + * Asserts that an object does not have a specified attribute. + * + * @param string $attributeName + * @param object $object + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertObjectNotHasAttribute($attributeName, $object, $message = '') + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'valid attribute name'); + } + + if (!is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_ObjectHasAttribute($attributeName) + ); + + self::assertThat($object, $constraint, $message); + } + + /** + * Asserts that two variables have the same type and value. + * Used on objects, it asserts that two variables reference + * the same object. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ + public static function assertSame($expected, $actual, $message = '') + { + if (is_bool($expected) && is_bool($actual)) { + self::assertEquals($expected, $actual, $message); + } else { + $constraint = new PHPUnit_Framework_Constraint_IsIdentical( + $expected + ); + + self::assertThat($actual, $constraint, $message); + } + } + + /** + * Asserts that a variable and an attribute of an object have the same type + * and value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param object $actualClassOrObject + * @param string $message + */ + public static function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertSame( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that two variables do not have the same type and value. + * Used on objects, it asserts that two variables do not reference + * the same object. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ + public static function assertNotSame($expected, $actual, $message = '') + { + if (is_bool($expected) && is_bool($actual)) { + self::assertNotEquals($expected, $actual, $message); + } else { + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsIdentical($expected) + ); + + self::assertThat($actual, $constraint, $message); + } + } + + /** + * Asserts that a variable and an attribute of an object do not have the + * same type and value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param object $actualClassOrObject + * @param string $message + */ + public static function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '') + { + self::assertNotSame( + $expected, + self::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a variable is of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertInstanceOf($expected, $actual, $message = '') + { + if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name'); + } + + $constraint = new PHPUnit_Framework_Constraint_IsInstanceOf( + $expected + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '') + { + self::assertInstanceOf( + $expected, + self::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is not of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertNotInstanceOf($expected, $actual, $message = '') + { + if (!(is_string($expected) && (class_exists($expected) || interface_exists($expected)))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class or interface name'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsInstanceOf($expected) + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '') + { + self::assertNotInstanceOf( + $expected, + self::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertInternalType($expected, $actual, $message = '') + { + if (!is_string($expected)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_IsType( + $expected + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '') + { + self::assertInternalType( + $expected, + self::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is not of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertNotInternalType($expected, $actual, $message = '') + { + if (!is_string($expected)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_IsType($expected) + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '') + { + self::assertNotInternalType( + $expected, + self::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a string matches a given regular expression. + * + * @param string $pattern + * @param string $string + * @param string $message + */ + public static function assertRegExp($pattern, $string, $message = '') + { + if (!is_string($pattern)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_PCREMatch($pattern); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string does not match a given regular expression. + * + * @param string $pattern + * @param string $string + * @param string $message + * @since Method available since Release 2.1.0 + */ + public static function assertNotRegExp($pattern, $string, $message = '') + { + if (!is_string($pattern)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_PCREMatch($pattern) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is the same. + * + * @param array|Countable|Traversable $expected + * @param array|Countable|Traversable $actual + * @param string $message + */ + public static function assertSameSize($expected, $actual, $message = '') + { + if (!$expected instanceof Countable && + !$expected instanceof Traversable && + !is_array($expected)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable'); + } + + if (!$actual instanceof Countable && + !$actual instanceof Traversable && + !is_array($actual)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable'); + } + + self::assertThat( + $actual, + new PHPUnit_Framework_Constraint_SameSize($expected), + $message + ); + } + + /** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is not the same. + * + * @param array|Countable|Traversable $expected + * @param array|Countable|Traversable $actual + * @param string $message + */ + public static function assertNotSameSize($expected, $actual, $message = '') + { + if (!$expected instanceof Countable && + !$expected instanceof Traversable && + !is_array($expected)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'countable or traversable'); + } + + if (!$actual instanceof Countable && + !$actual instanceof Traversable && + !is_array($actual)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'countable or traversable'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_SameSize($expected) + ); + + self::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a string matches a given format string. + * + * @param string $format + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertStringMatchesFormat($format, $string, $message = '') + { + if (!is_string($format)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_StringMatches($format); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string does not match a given format string. + * + * @param string $format + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertStringNotMatchesFormat($format, $string, $message = '') + { + if (!is_string($format)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringMatches($format) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string matches a given format file. + * + * @param string $formatFile + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertStringMatchesFormatFile($formatFile, $string, $message = '') + { + self::assertFileExists($formatFile, $message); + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_StringMatches( + file_get_contents($formatFile) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string does not match a given format string. + * + * @param string $formatFile + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ + public static function assertStringNotMatchesFormatFile($formatFile, $string, $message = '') + { + self::assertFileExists($formatFile, $message); + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringMatches( + file_get_contents($formatFile) + ) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string starts with a given prefix. + * + * @param string $prefix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringStartsWith($prefix, $string, $message = '') + { + if (!is_string($prefix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_StringStartsWith( + $prefix + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string starts not with a given prefix. + * + * @param string $prefix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringStartsNotWith($prefix, $string, $message = '') + { + if (!is_string($prefix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringStartsWith($prefix) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string ends with a given suffix. + * + * @param string $suffix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringEndsWith($suffix, $string, $message = '') + { + if (!is_string($suffix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_StringEndsWith($suffix); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that a string ends not with a given suffix. + * + * @param string $suffix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ + public static function assertStringEndsNotWith($suffix, $string, $message = '') + { + if (!is_string($suffix)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($string)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_Not( + new PHPUnit_Framework_Constraint_StringEndsWith($suffix) + ); + + self::assertThat($string, $constraint, $message); + } + + /** + * Asserts that two XML files are equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '') + { + self::assertFileExists($expectedFile); + self::assertFileExists($actualFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = false; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = false; + $actual->load($actualFile); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML files are not equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '') + { + self::assertFileExists($expectedFile); + self::assertFileExists($actualFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = false; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = false; + $actual->load($actualFile); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are equal. + * + * @param string $expectedFile + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.3.0 + */ + public static function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '') + { + self::assertFileExists($expectedFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = false; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = false; + $actual->loadXML($actualXml); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param string $expectedFile + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.3.0 + */ + public static function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '') + { + self::assertFileExists($expectedFile); + + $expected = new DOMDocument; + $expected->preserveWhiteSpace = false; + $expected->load($expectedFile); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = false; + $actual->loadXML($actualXml); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are equal. + * + * @param string $expectedXml + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '') + { + $expected = new DOMDocument; + $expected->preserveWhiteSpace = false; + $expected->loadXML($expectedXml); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = false; + $actual->loadXML($actualXml); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param string $expectedXml + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.1.0 + */ + public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '') + { + $expected = new DOMDocument; + $expected->preserveWhiteSpace = false; + $expected->loadXML($expectedXml); + + $actual = new DOMDocument; + $actual->preserveWhiteSpace = false; + $actual->loadXML($actualXml); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that a hierarchy of DOMElements matches. + * + * @param DOMElement $expectedElement + * @param DOMElement $actualElement + * @param boolean $checkAttributes + * @param string $message + * @author Mattis Stordalen Flister + * @since Method available since Release 3.3.0 + */ + public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '') + { + $expectedElement = clone $expectedElement; + $actualElement = clone $actualElement; + + self::assertEquals( + $expectedElement->tagName, + $actualElement->tagName, + $message + ); + + if ($checkAttributes) { + self::assertEquals( + $expectedElement->attributes->length, + $actualElement->attributes->length, + sprintf( + '%s%sNumber of attributes on node "%s" does not match', + $message, + !empty($message) ? "\n" : '', + $expectedElement->tagName + ) + ); + + for ($i = 0; $i < $expectedElement->attributes->length; $i++) { + $expectedAttribute = $expectedElement->attributes->item($i); + $actualAttribute = $actualElement->attributes->getNamedItem( + $expectedAttribute->name + ); + + if (!$actualAttribute) { + self::fail( + sprintf( + '%s%sCould not find attribute "%s" on node "%s"', + $message, + !empty($message) ? "\n" : '', + $expectedAttribute->name, + $expectedElement->tagName + ) + ); + } + } + } + + PHPUnit_Util_XML::removeCharacterDataNodes($expectedElement); + PHPUnit_Util_XML::removeCharacterDataNodes($actualElement); + + self::assertEquals( + $expectedElement->childNodes->length, + $actualElement->childNodes->length, + sprintf( + '%s%sNumber of child nodes of "%s" differs', + $message, + !empty($message) ? "\n" : '', + $expectedElement->tagName + ) + ); + + for ($i = 0; $i < $expectedElement->childNodes->length; $i++) { + self::assertEqualXMLStructure( + $expectedElement->childNodes->item($i), + $actualElement->childNodes->item($i), + $checkAttributes, + $message + ); + } + } + + /** + * Assert the presence, absence, or count of elements in a document matching + * the CSS $selector, regardless of the contents of those elements. + * + * The first argument, $selector, is the CSS selector used to match + * the elements in the $actual document. + * + * The second argument, $count, can be either boolean or numeric. + * When boolean, it asserts for presence of elements matching the selector + * (true) or absence of elements (false). + * When numeric, it asserts the count of elements. + * + * assertSelectCount("#binder", true, $xml); // any? + * assertSelectCount(".binder", 3, $xml); // exactly 3? + * + * @param array $selector + * @param integer|boolean|array $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @deprecated + */ + public static function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + + self::assertSelectEquals( + $selector, + true, + $count, + $actual, + $message, + $isHtml + ); + } + + /** + * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any? + * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml); // 3? + * + * @param array $selector + * @param string $pattern + * @param integer|boolean|array $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @deprecated + */ + public static function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + + self::assertSelectEquals( + $selector, + "regexp:$pattern", + $count, + $actual, + $message, + $isHtml + ); + } + + /** + * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any? + * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none? + * + * @param array $selector + * @param string $content + * @param integer|boolean|array $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @deprecated + */ + public static function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + + $tags = PHPUnit_Util_XML::cssSelect( + $selector, + $content, + $actual, + $isHtml + ); + + // assert specific number of elements + if (is_numeric($count)) { + $counted = $tags ? count($tags) : 0; + self::assertEquals($count, $counted, $message); + } // assert any elements exist if true, assert no elements exist if false + elseif (is_bool($count)) { + $any = count($tags) > 0 && $tags[0] instanceof DOMNode; + + if ($count) { + self::assertTrue($any, $message); + } else { + self::assertFalse($any, $message); + } + } // check for range number of elements + elseif (is_array($count) && + (isset($count['>']) || isset($count['<']) || + isset($count['>=']) || isset($count['<=']))) { + $counted = $tags ? count($tags) : 0; + + if (isset($count['>'])) { + self::assertTrue($counted > $count['>'], $message); + } + + if (isset($count['>='])) { + self::assertTrue($counted >= $count['>='], $message); + } + + if (isset($count['<'])) { + self::assertTrue($counted < $count['<'], $message); + } + + if (isset($count['<='])) { + self::assertTrue($counted <= $count['<='], $message); + } + } else { + throw new PHPUnit_Framework_Exception; + } + } + + /** + * Evaluate an HTML or XML string and assert its structure and/or contents. + * + * The first argument ($matcher) is an associative array that specifies the + * match criteria for the assertion: + * + * - `id` : the node with the given id attribute must match the + * corresponding value. + * - `tag` : the node type must match the corresponding value. + * - `attributes` : a hash. The node's attributes must match the + * corresponding values in the hash. + * - `content` : The text content must match the given value. + * - `parent` : a hash. The node's parent must match the + * corresponding hash. + * - `child` : a hash. At least one of the node's immediate children + * must meet the criteria described by the hash. + * - `ancestor` : a hash. At least one of the node's ancestors must + * meet the criteria described by the hash. + * - `descendant` : a hash. At least one of the node's descendants must + * meet the criteria described by the hash. + * - `children` : a hash, for counting children of a node. + * Accepts the keys: + * - `count` : a number which must equal the number of children + * that match + * - `less_than` : the number of matching children must be greater + * than this number + * - `greater_than` : the number of matching children must be less than + * this number + * - `only` : another hash consisting of the keys to use to match + * on the children, and only matching children will be + * counted + * + * + * // Matcher that asserts that there is an element with an id="my_id". + * $matcher = array('id' => 'my_id'); + * + * // Matcher that asserts that there is a "span" tag. + * $matcher = array('tag' => 'span'); + * + * // Matcher that asserts that there is a "span" tag with the content + * // "Hello World". + * $matcher = array('tag' => 'span', 'content' => 'Hello World'); + * + * // Matcher that asserts that there is a "span" tag with content matching + * // the regular expression pattern. + * $matcher = array('tag' => 'span', 'content' => 'regexp:/Try P(HP|ython)/'); + * + * // Matcher that asserts that there is a "span" with an "list" class + * // attribute. + * $matcher = array( + * 'tag' => 'span', + * 'attributes' => array('class' => 'list') + * ); + * + * // Matcher that asserts that there is a "span" inside of a "div". + * $matcher = array( + * 'tag' => 'span', + * 'parent' => array('tag' => 'div') + * ); + * + * // Matcher that asserts that there is a "span" somewhere inside a + * // "table". + * $matcher = array( + * 'tag' => 'span', + * 'ancestor' => array('tag' => 'table') + * ); + * + * // Matcher that asserts that there is a "span" with at least one "em" + * // child. + * $matcher = array( + * 'tag' => 'span', + * 'child' => array('tag' => 'em') + * ); + * + * // Matcher that asserts that there is a "span" containing a (possibly + * // nested) "strong" tag. + * $matcher = array( + * 'tag' => 'span', + * 'descendant' => array('tag' => 'strong') + * ); + * + * // Matcher that asserts that there is a "span" containing 5-10 "em" tags + * // as immediate children. + * $matcher = array( + * 'tag' => 'span', + * 'children' => array( + * 'less_than' => 11, + * 'greater_than' => 4, + * 'only' => array('tag' => 'em') + * ) + * ); + * + * // Matcher that asserts that there is a "div", with an "ul" ancestor and + * // a "li" parent (with class="enum"), and containing a "span" descendant + * // that contains an element with id="my_test" and the text "Hello World". + * $matcher = array( + * 'tag' => 'div', + * 'ancestor' => array('tag' => 'ul'), + * 'parent' => array( + * 'tag' => 'li', + * 'attributes' => array('class' => 'enum') + * ), + * 'descendant' => array( + * 'tag' => 'span', + * 'child' => array( + * 'id' => 'my_test', + * 'content' => 'Hello World' + * ) + * ) + * ); + * + * // Use assertTag() to apply a $matcher to a piece of $html. + * $this->assertTag($matcher, $html); + * + * // Use assertTag() to apply a $matcher to a piece of $xml. + * $this->assertTag($matcher, $xml, '', false); + * + * + * The second argument ($actual) is a string containing either HTML or + * XML text to be tested. + * + * The third argument ($message) is an optional message that will be + * used if the assertion fails. + * + * The fourth argument ($html) is an optional flag specifying whether + * to load the $actual string into a DOMDocument using the HTML or + * XML load strategy. It is true by default, which assumes the HTML + * load strategy. In many cases, this will be acceptable for XML as well. + * + * @param array $matcher + * @param string $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @deprecated + */ + public static function assertTag($matcher, $actual, $message = '', $isHtml = true) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + + $dom = PHPUnit_Util_XML::load($actual, $isHtml); + $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml); + $matched = count($tags) > 0 && $tags[0] instanceof DOMNode; + + self::assertTrue($matched, $message); + } + + /** + * This assertion is the exact opposite of assertTag(). + * + * Rather than asserting that $matcher results in a match, it asserts that + * $matcher does not match. + * + * @param array $matcher + * @param string $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @deprecated + */ + public static function assertNotTag($matcher, $actual, $message = '', $isHtml = true) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + + $dom = PHPUnit_Util_XML::load($actual, $isHtml); + $tags = PHPUnit_Util_XML::findNodes($dom, $matcher, $isHtml); + $matched = count($tags) > 0 && $tags[0] instanceof DOMNode; + + self::assertFalse($matched, $message); + } + + /** + * Evaluates a PHPUnit_Framework_Constraint matcher object. + * + * @param mixed $value + * @param PHPUnit_Framework_Constraint $constraint + * @param string $message + * @since Method available since Release 3.0.0 + */ + public static function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '') + { + self::$count += count($constraint); + + $constraint->evaluate($value, $message); + } + + /** + * Asserts that a string is a valid JSON string. + * + * @param string $actualJson + * @param string $message + * @since Method available since Release 3.7.20 + */ + public static function assertJson($actualJson, $message = '') + { + if (!is_string($actualJson)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + self::assertThat($actualJson, self::isJson(), $message); + } + + /** + * Asserts that two given JSON encoded objects or arrays are equal. + * + * @param string $expectedJson + * @param string $actualJson + * @param string $message + */ + public static function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '') + { + self::assertJson($expectedJson, $message); + self::assertJson($actualJson, $message); + + $expected = json_decode($expectedJson); + $actual = json_decode($actualJson); + + self::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two given JSON encoded objects or arrays are not equal. + * + * @param string $expectedJson + * @param string $actualJson + * @param string $message + */ + public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '') + { + self::assertJson($expectedJson, $message); + self::assertJson($actualJson, $message); + + $expected = json_decode($expectedJson); + $actual = json_decode($actualJson); + + self::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that the generated JSON encoded object and the content of the given file are equal. + * + * @param string $expectedFile + * @param string $actualJson + * @param string $message + */ + public static function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '') + { + self::assertFileExists($expectedFile, $message); + $expectedJson = file_get_contents($expectedFile); + + self::assertJson($expectedJson, $message); + self::assertJson($actualJson, $message); + + // call constraint + $constraint = new PHPUnit_Framework_Constraint_JsonMatches( + $expectedJson + ); + + self::assertThat($actualJson, $constraint, $message); + } + + /** + * Asserts that the generated JSON encoded object and the content of the given file are not equal. + * + * @param string $expectedFile + * @param string $actualJson + * @param string $message + */ + public static function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '') + { + self::assertFileExists($expectedFile, $message); + $expectedJson = file_get_contents($expectedFile); + + self::assertJson($expectedJson, $message); + self::assertJson($actualJson, $message); + + // call constraint + $constraint = new PHPUnit_Framework_Constraint_JsonMatches( + $expectedJson + ); + + self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraint), $message); + } + + /** + * Asserts that two JSON files are not equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + */ + public static function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '') + { + self::assertFileExists($expectedFile, $message); + self::assertFileExists($actualFile, $message); + + $actualJson = file_get_contents($actualFile); + $expectedJson = file_get_contents($expectedFile); + + self::assertJson($expectedJson, $message); + self::assertJson($actualJson, $message); + + // call constraint + $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches( + $expectedJson + ); + + $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson); + + self::assertThat($expectedJson, new PHPUnit_Framework_Constraint_Not($constraintActual), $message); + self::assertThat($actualJson, new PHPUnit_Framework_Constraint_Not($constraintExpected), $message); + } + + /** + * Asserts that two JSON files are equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + */ + public static function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '') + { + self::assertFileExists($expectedFile, $message); + self::assertFileExists($actualFile, $message); + + $actualJson = file_get_contents($actualFile); + $expectedJson = file_get_contents($expectedFile); + + self::assertJson($expectedJson, $message); + self::assertJson($actualJson, $message); + + // call constraint + $constraintExpected = new PHPUnit_Framework_Constraint_JsonMatches( + $expectedJson + ); + + $constraintActual = new PHPUnit_Framework_Constraint_JsonMatches($actualJson); + + self::assertThat($expectedJson, $constraintActual, $message); + self::assertThat($actualJson, $constraintExpected, $message); + } + + /** + * Returns a PHPUnit_Framework_Constraint_And matcher object. + * + * @return PHPUnit_Framework_Constraint_And + * @since Method available since Release 3.0.0 + */ + public static function logicalAnd() + { + $constraints = func_get_args(); + + $constraint = new PHPUnit_Framework_Constraint_And; + $constraint->setConstraints($constraints); + + return $constraint; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Or matcher object. + * + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.0.0 + */ + public static function logicalOr() + { + $constraints = func_get_args(); + + $constraint = new PHPUnit_Framework_Constraint_Or; + $constraint->setConstraints($constraints); + + return $constraint; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Not matcher object. + * + * @param PHPUnit_Framework_Constraint $constraint + * @return PHPUnit_Framework_Constraint_Not + * @since Method available since Release 3.0.0 + */ + public static function logicalNot(PHPUnit_Framework_Constraint $constraint) + { + return new PHPUnit_Framework_Constraint_Not($constraint); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Xor matcher object. + * + * @return PHPUnit_Framework_Constraint_Xor + * @since Method available since Release 3.0.0 + */ + public static function logicalXor() + { + $constraints = func_get_args(); + + $constraint = new PHPUnit_Framework_Constraint_Xor; + $constraint->setConstraints($constraints); + + return $constraint; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object. + * + * @return PHPUnit_Framework_Constraint_IsAnything + * @since Method available since Release 3.0.0 + */ + public static function anything() + { + return new PHPUnit_Framework_Constraint_IsAnything; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object. + * + * @return PHPUnit_Framework_Constraint_IsTrue + * @since Method available since Release 3.3.0 + */ + public static function isTrue() + { + return new PHPUnit_Framework_Constraint_IsTrue; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Callback matcher object. + * + * @param callable $callback + * @return PHPUnit_Framework_Constraint_Callback + */ + public static function callback($callback) + { + return new PHPUnit_Framework_Constraint_Callback($callback); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object. + * + * @return PHPUnit_Framework_Constraint_IsFalse + * @since Method available since Release 3.3.0 + */ + public static function isFalse() + { + return new PHPUnit_Framework_Constraint_IsFalse; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsJson matcher object. + * + * @return PHPUnit_Framework_Constraint_IsJson + * @since Method available since Release 3.7.20 + */ + public static function isJson() + { + return new PHPUnit_Framework_Constraint_IsJson; + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsNull matcher object. + * + * @return PHPUnit_Framework_Constraint_IsNull + * @since Method available since Release 3.3.0 + */ + public static function isNull() + { + return new PHPUnit_Framework_Constraint_IsNull; + } + + /** + * Returns a PHPUnit_Framework_Constraint_Attribute matcher object. + * + * @param PHPUnit_Framework_Constraint $constraint + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_Attribute + * @since Method available since Release 3.1.0 + */ + public static function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName) + { + return new PHPUnit_Framework_Constraint_Attribute( + $constraint, + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher + * object. + * + * @param mixed $value + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @return PHPUnit_Framework_Constraint_TraversableContains + * @since Method available since Release 3.0.0 + */ + public static function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) + { + return new PHPUnit_Framework_Constraint_TraversableContains($value, $checkForObjectIdentity, $checkForNonObjectIdentity); + } + + /** + * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher + * object. + * + * @param string $type + * @return PHPUnit_Framework_Constraint_TraversableContainsOnly + * @since Method available since Release 3.1.4 + */ + public static function containsOnly($type) + { + return new PHPUnit_Framework_Constraint_TraversableContainsOnly($type); + } + + /** + * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher + * object. + * + * @param string $classname + * @return PHPUnit_Framework_Constraint_TraversableContainsOnly + */ + public static function containsOnlyInstancesOf($classname) + { + return new PHPUnit_Framework_Constraint_TraversableContainsOnly($classname, false); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object. + * + * @param mixed $key + * @return PHPUnit_Framework_Constraint_ArrayHasKey + * @since Method available since Release 3.0.0 + */ + public static function arrayHasKey($key) + { + return new PHPUnit_Framework_Constraint_ArrayHasKey($key); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object. + * + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @return PHPUnit_Framework_Constraint_IsEqual + * @since Method available since Release 3.0.0 + */ + public static function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + return new PHPUnit_Framework_Constraint_IsEqual( + $value, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object + * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher + * object. + * + * @param string $attributeName + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @return PHPUnit_Framework_Constraint_Attribute + * @since Method available since Release 3.1.0 + */ + public static function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + return self::attribute( + self::equalTo( + $value, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ), + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object. + * + * @return PHPUnit_Framework_Constraint_IsEmpty + * @since Method available since Release 3.5.0 + */ + public static function isEmpty() + { + return new PHPUnit_Framework_Constraint_IsEmpty; + } + + /** + * Returns a PHPUnit_Framework_Constraint_FileExists matcher object. + * + * @return PHPUnit_Framework_Constraint_FileExists + * @since Method available since Release 3.0.0 + */ + public static function fileExists() + { + return new PHPUnit_Framework_Constraint_FileExists; + } + + /** + * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_GreaterThan + * @since Method available since Release 3.0.0 + */ + public static function greaterThan($value) + { + return new PHPUnit_Framework_Constraint_GreaterThan($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps + * a PHPUnit_Framework_Constraint_IsEqual and a + * PHPUnit_Framework_Constraint_GreaterThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.1.0 + */ + public static function greaterThanOrEqual($value) + { + return self::logicalOr( + new PHPUnit_Framework_Constraint_IsEqual($value), + new PHPUnit_Framework_Constraint_GreaterThan($value) + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ClassHasAttribute + * @since Method available since Release 3.1.0 + */ + public static function classHasAttribute($attributeName) + { + return new PHPUnit_Framework_Constraint_ClassHasAttribute( + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher + * object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @since Method available since Release 3.1.0 + */ + public static function classHasStaticAttribute($attributeName) + { + return new PHPUnit_Framework_Constraint_ClassHasStaticAttribute( + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ObjectHasAttribute + * @since Method available since Release 3.0.0 + */ + public static function objectHasAttribute($attributeName) + { + return new PHPUnit_Framework_Constraint_ObjectHasAttribute( + $attributeName + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_IsIdentical + * @since Method available since Release 3.0.0 + */ + public static function identicalTo($value) + { + return new PHPUnit_Framework_Constraint_IsIdentical($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object. + * + * @param string $className + * @return PHPUnit_Framework_Constraint_IsInstanceOf + * @since Method available since Release 3.0.0 + */ + public static function isInstanceOf($className) + { + return new PHPUnit_Framework_Constraint_IsInstanceOf($className); + } + + /** + * Returns a PHPUnit_Framework_Constraint_IsType matcher object. + * + * @param string $type + * @return PHPUnit_Framework_Constraint_IsType + * @since Method available since Release 3.0.0 + */ + public static function isType($type) + { + return new PHPUnit_Framework_Constraint_IsType($type); + } + + /** + * Returns a PHPUnit_Framework_Constraint_LessThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_LessThan + * @since Method available since Release 3.0.0 + */ + public static function lessThan($value) + { + return new PHPUnit_Framework_Constraint_LessThan($value); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps + * a PHPUnit_Framework_Constraint_IsEqual and a + * PHPUnit_Framework_Constraint_LessThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.1.0 + */ + public static function lessThanOrEqual($value) + { + return self::logicalOr( + new PHPUnit_Framework_Constraint_IsEqual($value), + new PHPUnit_Framework_Constraint_LessThan($value) + ); + } + + /** + * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object. + * + * @param string $pattern + * @return PHPUnit_Framework_Constraint_PCREMatch + * @since Method available since Release 3.0.0 + */ + public static function matchesRegularExpression($pattern) + { + return new PHPUnit_Framework_Constraint_PCREMatch($pattern); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object. + * + * @param string $string + * @return PHPUnit_Framework_Constraint_StringMatches + * @since Method available since Release 3.5.0 + */ + public static function matches($string) + { + return new PHPUnit_Framework_Constraint_StringMatches($string); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object. + * + * @param mixed $prefix + * @return PHPUnit_Framework_Constraint_StringStartsWith + * @since Method available since Release 3.4.0 + */ + public static function stringStartsWith($prefix) + { + return new PHPUnit_Framework_Constraint_StringStartsWith($prefix); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringContains matcher object. + * + * @param string $string + * @param boolean $case + * @return PHPUnit_Framework_Constraint_StringContains + * @since Method available since Release 3.0.0 + */ + public static function stringContains($string, $case = true) + { + return new PHPUnit_Framework_Constraint_StringContains($string, $case); + } + + /** + * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object. + * + * @param mixed $suffix + * @return PHPUnit_Framework_Constraint_StringEndsWith + * @since Method available since Release 3.4.0 + */ + public static function stringEndsWith($suffix) + { + return new PHPUnit_Framework_Constraint_StringEndsWith($suffix); + } + + /** + * Returns a PHPUnit_Framework_Constraint_Count matcher object. + * + * @param int $count + * @return PHPUnit_Framework_Constraint_Count + */ + public static function countOf($count) + { + return new PHPUnit_Framework_Constraint_Count($count); + } + /** + * Fails a test with the given message. + * + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ + public static function fail($message = '') + { + throw new PHPUnit_Framework_AssertionFailedError($message); + } + + /** + * Returns the value of an attribute of a class or an object. + * This also works for attributes that are declared protected or private. + * + * @param mixed $classOrObject + * @param string $attributeName + * @return mixed + * @throws PHPUnit_Framework_Exception + */ + public static function readAttribute($classOrObject, $attributeName) + { + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name'); + } + + if (is_string($classOrObject)) { + if (!class_exists($classOrObject)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'class name' + ); + } + + return self::getStaticAttribute( + $classOrObject, + $attributeName + ); + } elseif (is_object($classOrObject)) { + return self::getObjectAttribute( + $classOrObject, + $attributeName + ); + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'class name or object' + ); + } + } + + /** + * Returns the value of a static attribute. + * This also works for attributes that are declared protected or private. + * + * @param string $className + * @param string $attributeName + * @return mixed + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.0.0 + */ + public static function getStaticAttribute($className, $attributeName) + { + if (!is_string($className)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!class_exists($className)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'class name'); + } + + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name'); + } + + $class = new ReflectionClass($className); + + while ($class) { + $attributes = $class->getStaticProperties(); + + if (array_key_exists($attributeName, $attributes)) { + return $attributes[$attributeName]; + } + + $class = $class->getParentClass(); + } + + throw new PHPUnit_Framework_Exception( + sprintf( + 'Attribute "%s" not found in class.', + $attributeName + ) + ); + } + + /** + * Returns the value of an object's attribute. + * This also works for attributes that are declared protected or private. + * + * @param object $object + * @param string $attributeName + * @return mixed + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.0.0 + */ + public static function getObjectAttribute($object, $attributeName) + { + if (!is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'object'); + } + + if (!is_string($attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'string'); + } + + if (!preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'valid attribute name'); + } + + try { + $attribute = new ReflectionProperty($object, $attributeName); + } catch (ReflectionException $e) { + $reflector = new ReflectionObject($object); + + while ($reflector = $reflector->getParentClass()) { + try { + $attribute = $reflector->getProperty($attributeName); + break; + } catch (ReflectionException $e) { + } + } + } + + if (isset($attribute)) { + if (!$attribute || $attribute->isPublic()) { + return $object->$attributeName; + } + + $attribute->setAccessible(true); + $value = $attribute->getValue($object); + $attribute->setAccessible(false); + + return $value; + } + + throw new PHPUnit_Framework_Exception( + sprintf( + 'Attribute "%s" not found in object.', + $attributeName + ) + ); + } + + /** + * Mark the test as incomplete. + * + * @param string $message + * @throws PHPUnit_Framework_IncompleteTestError + * @since Method available since Release 3.0.0 + */ + public static function markTestIncomplete($message = '') + { + throw new PHPUnit_Framework_IncompleteTestError($message); + } + + /** + * Mark the test as skipped. + * + * @param string $message + * @throws PHPUnit_Framework_SkippedTestError + * @since Method available since Release 3.0.0 + */ + public static function markTestSkipped($message = '') + { + throw new PHPUnit_Framework_SkippedTestError($message); + } + + /** + * Return the current assertion count. + * + * @return integer + * @since Method available since Release 3.3.3 + */ + public static function getCount() + { + return self::$count; + } + + /** + * Reset the assertion counter. + * + * @since Method available since Release 3.3.3 + */ + public static function resetCount() + { + self::$count = 0; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * An incomplete test case + * + * @package PHPUnit + * @subpackage Framework + * @author Davey Shafik + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.3.0 + */ +class PHPUnit_Framework_IncompleteTestCase extends PHPUnit_Framework_TestCase +{ + /** + * @var string + */ + protected $message = ''; + + /** + * @var boolean + */ + protected $backupGlobals = false; + + /** + * @var boolean + */ + protected $backupStaticAttributes = false; + + /** + * @var boolean + */ + protected $runTestInSeparateProcess = false; + + /** + * @var boolean + */ + protected $useErrorHandler = false; + + /** + * @var boolean + */ + protected $useOutputBuffering = false; + + /** + * @param string $message + */ + public function __construct($className, $methodName, $message = '') + { + $this->message = $message; + parent::__construct($className . '::' . $methodName); + } + + /** + * @throws PHPUnit_Framework_Exception + */ + protected function runTest() + { + $this->markTestIncomplete($this->message); + } + + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + return $this->getName(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Wrapper for PHP deprecated errors. + * You can disable deprecated-to-exception conversion by setting + * + * + * PHPUnit_Framework_Error_Deprecated::$enabled = false; + * + * + * @package PHPUnit + * @subpackage Framework_Error + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Error_Deprecated extends PHPUnit_Framework_Error +{ + public static $enabled = true; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Wrapper for PHP notices. + * You can disable notice-to-exception conversion by setting + * + * + * PHPUnit_Framework_Error_Notice::$enabled = false; + * + * + * @package PHPUnit + * @subpackage Framework_Error + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Error_Notice extends PHPUnit_Framework_Error +{ + public static $enabled = true; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Wrapper for PHP warnings. + * You can disable notice-to-exception conversion by setting + * + * + * PHPUnit_Framework_Error_Warning::$enabled = false; + * + * + * @package PHPUnit + * @subpackage Framework_Error + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Error_Warning extends PHPUnit_Framework_Error +{ + public static $enabled = true; +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Base class for all PHPUnit Framework exceptions. + * + * Ensures that exceptions thrown during a test run do not leave stray + * references behind. + * + * Every Exception contains a stack trace. Each stack frame contains the 'args' + * of the called function. The function arguments can contain references to + * instantiated objects. The references prevent the objects from being + * destructed (until test results are eventually printed), so memory cannot be + * freed up. + * + * With enabled process isolation, test results are serialized in the child + * process and unserialized in the parent process. The stack trace of Exceptions + * may contain objects that cannot be serialized or unserialized (e.g., PDO + * connections). Unserializing user-space objects from the child process into + * the parent would break the intended encapsulation of process isolation. + * + * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_Exception extends RuntimeException implements PHPUnit_Exception +{ + /** + * @var array + */ + protected $serializableTrace; + + public function __construct($message = '', $code = 0, Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->serializableTrace = $this->getTrace(); + foreach ($this->serializableTrace as $i => $call) { + unset($this->serializableTrace[$i]['args']); + } + } + + /** + * Returns the serializable trace (without 'args'). + * + * @return array + */ + public function getSerializableTrace() + { + return $this->serializableTrace; + } + + /** + * @return string + */ + public function __toString() + { + $string = PHPUnit_Framework_TestFailure::exceptionToString($this); + + if ($trace = PHPUnit_Util_Filter::getFilteredStacktrace($this)) { + $string .= "\n" . $trace; + } + + return $string; + } + + public function __sleep() + { + return array_keys(get_object_vars($this)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A marker interface for marking any exception/error as result of an unit + * test as risky. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 4.0.0 + */ +interface PHPUnit_Framework_RiskyTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A skipped test case + * + * @package PHPUnit + * @subpackage Framework + * @author Davey Shafik + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.3.0 + */ +class PHPUnit_Framework_SkippedTestCase extends PHPUnit_Framework_TestCase +{ + /** + * @var string + */ + protected $message = ''; + + /** + * @var boolean + */ + protected $backupGlobals = false; + + /** + * @var boolean + */ + protected $backupStaticAttributes = false; + + /** + * @var boolean + */ + protected $runTestInSeparateProcess = false; + + /** + * @var boolean + */ + protected $useErrorHandler = false; + + /** + * @var boolean + */ + protected $useOutputBuffering = false; + + /** + * @param string $message + */ + public function __construct($className, $methodName, $message = '') + { + $this->message = $message; + parent::__construct($className . '::' . $methodName); + } + + /** + * @throws PHPUnit_Framework_Exception + */ + protected function runTest() + { + $this->markTestSkipped($this->message); + } + + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + return $this->getName(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a test that printed output. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.0 + */ +class PHPUnit_Framework_OutputError extends PHPUnit_Framework_AssertionFailedError +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A TestResult collects the results of executing a test case. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_TestResult implements Countable +{ + /** + * @var array + */ + protected $passed = array(); + + /** + * @var array + */ + protected $errors = array(); + + /** + * @var array + */ + protected $failures = array(); + + /** + * @var array + */ + protected $notImplemented = array(); + + /** + * @var array + */ + protected $risky = array(); + + /** + * @var array + */ + protected $skipped = array(); + + /** + * @var array + */ + protected $listeners = array(); + + /** + * @var integer + */ + protected $runTests = 0; + + /** + * @var float + */ + protected $time = 0; + + /** + * @var PHPUnit_Framework_TestSuite + */ + protected $topTestSuite = null; + + /** + * Code Coverage information. + * + * @var PHP_CodeCoverage + */ + protected $codeCoverage; + + /** + * @var boolean + */ + protected $convertErrorsToExceptions = true; + + /** + * @var boolean + */ + protected $stop = false; + + /** + * @var boolean + */ + protected $stopOnError = false; + + /** + * @var boolean + */ + protected $stopOnFailure = false; + + /** + * @var boolean + */ + protected $beStrictAboutTestsThatDoNotTestAnything = false; + + /** + * @var boolean + */ + protected $beStrictAboutOutputDuringTests = false; + + /** + * @var boolean + */ + protected $beStrictAboutTestSize = false; + + /** + * @var boolean + */ + protected $beStrictAboutTodoAnnotatedTests = false; + + /** + * @var boolean + */ + protected $stopOnRisky = false; + + /** + * @var boolean + */ + protected $stopOnIncomplete = false; + + /** + * @var boolean + */ + protected $stopOnSkipped = false; + + /** + * @var boolean + */ + protected $lastTestFailed = false; + + /** + * @var integer + */ + protected $timeoutForSmallTests = 1; + + /** + * @var integer + */ + protected $timeoutForMediumTests = 10; + + /** + * @var integer + */ + protected $timeoutForLargeTests = 60; + + /** + * Registers a TestListener. + * + * @param PHPUnit_Framework_TestListener + */ + public function addListener(PHPUnit_Framework_TestListener $listener) + { + $this->listeners[] = $listener; + } + + /** + * Unregisters a TestListener. + * + * @param PHPUnit_Framework_TestListener $listener + */ + public function removeListener(PHPUnit_Framework_TestListener $listener) + { + foreach ($this->listeners as $key => $_listener) { + if ($listener === $_listener) { + unset($this->listeners[$key]); + } + } + } + + /** + * Flushes all flushable TestListeners. + * + * @since Method available since Release 3.0.0 + */ + public function flushListeners() + { + foreach ($this->listeners as $listener) { + if ($listener instanceof PHPUnit_Util_Printer) { + $listener->flush(); + } + } + } + + /** + * Adds an error to the list of errors. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($e instanceof PHPUnit_Framework_RiskyTest) { + $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addRiskyTest'; + + if ($this->stopOnRisky) { + $this->stop(); + } + } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) { + $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addIncompleteTest'; + + if ($this->stopOnIncomplete) { + $this->stop(); + } + } elseif ($e instanceof PHPUnit_Framework_SkippedTest) { + $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addSkippedTest'; + + if ($this->stopOnSkipped) { + $this->stop(); + } + } else { + $this->errors[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addError'; + + if ($this->stopOnError || $this->stopOnFailure) { + $this->stop(); + } + } + + foreach ($this->listeners as $listener) { + $listener->$notifyMethod($test, $e, $time); + } + + $this->lastTestFailed = true; + $this->time += $time; + } + + /** + * Adds a failure to the list of failures. + * The passed in exception caused the failure. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + if ($e instanceof PHPUnit_Framework_RiskyTest || + $e instanceof PHPUnit_Framework_OutputError) { + $this->risky[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addRiskyTest'; + + if ($this->stopOnRisky) { + $this->stop(); + } + } elseif ($e instanceof PHPUnit_Framework_IncompleteTest) { + $this->notImplemented[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addIncompleteTest'; + + if ($this->stopOnIncomplete) { + $this->stop(); + } + } elseif ($e instanceof PHPUnit_Framework_SkippedTest) { + $this->skipped[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addSkippedTest'; + + if ($this->stopOnSkipped) { + $this->stop(); + } + } else { + $this->failures[] = new PHPUnit_Framework_TestFailure($test, $e); + $notifyMethod = 'addFailure'; + + if ($this->stopOnFailure) { + $this->stop(); + } + } + + foreach ($this->listeners as $listener) { + $listener->$notifyMethod($test, $e, $time); + } + + $this->lastTestFailed = true; + $this->time += $time; + } + + /** + * Informs the result that a testsuite will be started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + if ($this->topTestSuite === null) { + $this->topTestSuite = $suite; + } + + foreach ($this->listeners as $listener) { + $listener->startTestSuite($suite); + } + } + + /** + * Informs the result that a testsuite was completed. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + foreach ($this->listeners as $listener) { + $listener->endTestSuite($suite); + } + } + + /** + * Informs the result that a test will be started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->lastTestFailed = false; + $this->runTests += count($test); + + foreach ($this->listeners as $listener) { + $listener->startTest($test); + } + } + + /** + * Informs the result that a test was completed. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + foreach ($this->listeners as $listener) { + $listener->endTest($test, $time); + } + + if (!$this->lastTestFailed && $test instanceof PHPUnit_Framework_TestCase) { + $class = get_class($test); + $key = $class . '::' . $test->getName(); + + $this->passed[$key] = array( + 'result' => $test->getResult(), + 'size' => PHPUnit_Util_Test::getSize( + $class, + $test->getName(false) + ) + ); + + $this->time += $time; + } + } + + /** + * Returns true if no risky test occurred. + * + * @return boolean + * @since Method available since Release 4.0.0 + */ + public function allHarmless() + { + return $this->riskyCount() == 0; + } + + /** + * Gets the number of risky tests. + * + * @return integer + * @since Method available since Release 4.0.0 + */ + public function riskyCount() + { + return count($this->risky); + } + + /** + * Returns true if no incomplete test occurred. + * + * @return boolean + */ + public function allCompletelyImplemented() + { + return $this->notImplementedCount() == 0; + } + + /** + * Gets the number of incomplete tests. + * + * @return integer + */ + public function notImplementedCount() + { + return count($this->notImplemented); + } + + /** + * Returns an Enumeration for the risky tests. + * + * @return array + * @since Method available since Release 4.0.0 + */ + public function risky() + { + return $this->risky; + } + + /** + * Returns an Enumeration for the incomplete tests. + * + * @return array + */ + public function notImplemented() + { + return $this->notImplemented; + } + + /** + * Returns true if no test has been skipped. + * + * @return boolean + * @since Method available since Release 3.0.0 + */ + public function noneSkipped() + { + return $this->skippedCount() == 0; + } + + /** + * Gets the number of skipped tests. + * + * @return integer + * @since Method available since Release 3.0.0 + */ + public function skippedCount() + { + return count($this->skipped); + } + + /** + * Returns an Enumeration for the skipped tests. + * + * @return array + * @since Method available since Release 3.0.0 + */ + public function skipped() + { + return $this->skipped; + } + + /** + * Gets the number of detected errors. + * + * @return integer + */ + public function errorCount() + { + return count($this->errors); + } + + /** + * Returns an Enumeration for the errors. + * + * @return array + */ + public function errors() + { + return $this->errors; + } + + /** + * Gets the number of detected failures. + * + * @return integer + */ + public function failureCount() + { + return count($this->failures); + } + + /** + * Returns an Enumeration for the failures. + * + * @return array + */ + public function failures() + { + return $this->failures; + } + + /** + * Returns the names of the tests that have passed. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function passed() + { + return $this->passed; + } + + /** + * Returns the (top) test suite. + * + * @return PHPUnit_Framework_TestSuite + * @since Method available since Release 3.0.0 + */ + public function topTestSuite() + { + return $this->topTestSuite; + } + + /** + * Returns whether code coverage information should be collected. + * + * @return boolean If code coverage should be collected + * @since Method available since Release 3.2.0 + */ + public function getCollectCodeCoverageInformation() + { + return $this->codeCoverage !== null; + } + + /** + * Runs a TestCase. + * + * @param PHPUnit_Framework_Test $test + */ + public function run(PHPUnit_Framework_Test $test) + { + PHPUnit_Framework_Assert::resetCount(); + + $error = false; + $failure = false; + $incomplete = false; + $risky = false; + $skipped = false; + + $this->startTest($test); + + $errorHandlerSet = false; + + if ($this->convertErrorsToExceptions) { + $oldErrorHandler = set_error_handler( + array('PHPUnit_Util_ErrorHandler', 'handleError'), + E_ALL | E_STRICT + ); + + if ($oldErrorHandler === null) { + $errorHandlerSet = true; + } else { + restore_error_handler(); + } + } + + $collectCodeCoverage = $this->codeCoverage !== null && + !$test instanceof PHPUnit_Extensions_SeleniumTestCase && + !$test instanceof PHPUnit_Framework_Warning; + + if ($collectCodeCoverage) { + // We need to blacklist test source files when no whitelist is used. + if (!$this->codeCoverage->filter()->hasWhitelist()) { + $classes = $this->getHierarchy(get_class($test), true); + + foreach ($classes as $class) { + $this->codeCoverage->filter()->addFileToBlacklist( + $class->getFileName() + ); + } + } + + $this->codeCoverage->start($test); + } + + PHP_Timer::start(); + + try { + if (!$test instanceof PHPUnit_Framework_Warning && + $this->beStrictAboutTestSize && + extension_loaded('pcntl') && class_exists('PHP_Invoker')) { + switch ($test->getSize()) { + case PHPUnit_Util_Test::SMALL: { + $_timeout = $this->timeoutForSmallTests; + } + break; + + case PHPUnit_Util_Test::MEDIUM: { + $_timeout = $this->timeoutForMediumTests; + } + break; + + case PHPUnit_Util_Test::LARGE: { + $_timeout = $this->timeoutForLargeTests; + } + break; + } + + $invoker = new PHP_Invoker; + $invoker->invoke(array($test, 'runBare'), array(), $_timeout); + } else { + $test->runBare(); + } + } catch (PHPUnit_Framework_AssertionFailedError $e) { + $failure = true; + + if ($e instanceof PHPUnit_Framework_RiskyTestError) { + $risky = true; + } elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) { + $incomplete = true; + } elseif ($e instanceof PHPUnit_Framework_SkippedTestError) { + $skipped = true; + } + } catch (PHPUnit_Framework_Exception $e) { + $error = true; + } catch (Exception $e) { + $e = new PHPUnit_Framework_ExceptionWrapper($e); + $error = true; + } + + $time = PHP_Timer::stop(); + $test->addToAssertionCount(PHPUnit_Framework_Assert::getCount()); + + if ($this->beStrictAboutTestsThatDoNotTestAnything && + $test->getNumAssertions() == 0) { + $risky = true; + } + + if ($collectCodeCoverage) { + $append = !$risky && !$incomplete && !$skipped; + $linesToBeCovered = array(); + $linesToBeUsed = array(); + + if ($append && $test instanceof PHPUnit_Framework_TestCase) { + $linesToBeCovered = PHPUnit_Util_Test::getLinesToBeCovered( + get_class($test), + $test->getName(false) + ); + + $linesToBeUsed = PHPUnit_Util_Test::getLinesToBeUsed( + get_class($test), + $test->getName(false) + ); + } + + try { + $this->codeCoverage->stop( + $append, + $linesToBeCovered, + $linesToBeUsed + ); + } catch (PHP_CodeCoverage_Exception_UnintentionallyCoveredCode $cce) { + $this->addFailure( + $test, + new PHPUnit_Framework_UnintentionallyCoveredCodeError( + 'This test executed code that is not listed as code to be covered or used:' . + PHP_EOL . $cce->getMessage() + ), + $time + ); + } catch (PHPUnit_Framework_InvalidCoversTargetException $cce) { + $this->addFailure( + $test, + new PHPUnit_Framework_InvalidCoversTargetError( + $cce->getMessage() + ), + $time + ); + } catch (PHP_CodeCoverage_Exception $cce) { + $error = true; + + if (!isset($e)) { + $e = $cce; + } + } + } + + if ($errorHandlerSet === true) { + restore_error_handler(); + } + + if ($error === true) { + $this->addError($test, $e, $time); + } elseif ($failure === true) { + $this->addFailure($test, $e, $time); + } elseif ($this->beStrictAboutTestsThatDoNotTestAnything && + $test->getNumAssertions() == 0) { + $this->addFailure( + $test, + new PHPUnit_Framework_RiskyTestError( + 'This test did not perform any assertions' + ), + $time + ); + } elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) { + $this->addFailure( + $test, + new PHPUnit_Framework_OutputError( + sprintf( + 'This test printed output: %s', + $test->getActualOutput() + ) + ), + $time + ); + } elseif ($this->beStrictAboutTodoAnnotatedTests && $test instanceof PHPUnit_Framework_TestCase) { + $annotations = $test->getAnnotations(); + + if (isset($annotations['method']['todo'])) { + $this->addFailure( + $test, + new PHPUnit_Framework_RiskyTestError( + 'Test method is annotated with @todo' + ), + $time + ); + } + } + + $this->endTest($test, $time); + } + + /** + * Gets the number of run tests. + * + * @return integer + */ + public function count() + { + return $this->runTests; + } + + /** + * Checks whether the test run should stop. + * + * @return boolean + */ + public function shouldStop() + { + return $this->stop; + } + + /** + * Marks that the test run should stop. + * + */ + public function stop() + { + $this->stop = true; + } + + /** + * Returns the PHP_CodeCoverage object. + * + * @return PHP_CodeCoverage + * @since Method available since Release 3.5.0 + */ + public function getCodeCoverage() + { + return $this->codeCoverage; + } + + /** + * Sets the PHP_CodeCoverage object. + * + * @param PHP_CodeCoverage $codeCoverage + * @since Method available since Release 3.6.0 + */ + public function setCodeCoverage(PHP_CodeCoverage $codeCoverage) + { + $this->codeCoverage = $codeCoverage; + } + + /** + * Enables or disables the error-to-exception conversion. + * + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.2.14 + */ + public function convertErrorsToExceptions($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->convertErrorsToExceptions = $flag; + } + + /** + * Returns the error-to-exception conversion setting. + * + * @return boolean + * @since Method available since Release 3.4.0 + */ + public function getConvertErrorsToExceptions() + { + return $this->convertErrorsToExceptions; + } + + /** + * Enables or disables the stopping when an error occurs. + * + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.5.0 + */ + public function stopOnError($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->stopOnError = $flag; + } + + /** + * Enables or disables the stopping when a failure occurs. + * + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.1.0 + */ + public function stopOnFailure($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->stopOnFailure = $flag; + } + + /** + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.0.0 + */ + public function beStrictAboutTestsThatDoNotTestAnything($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->beStrictAboutTestsThatDoNotTestAnything = $flag; + } + + /** + * @return boolean + * @since Method available since Release 4.0.0 + */ + public function isStrictAboutTestsThatDoNotTestAnything() + { + return $this->beStrictAboutTestsThatDoNotTestAnything; + } + + /** + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.0.0 + */ + public function beStrictAboutOutputDuringTests($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->beStrictAboutOutputDuringTests = $flag; + } + + /** + * @return boolean + * @since Method available since Release 4.0.0 + */ + public function isStrictAboutOutputDuringTests() + { + return $this->beStrictAboutOutputDuringTests; + } + + /** + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.0.0 + */ + public function beStrictAboutTestSize($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->beStrictAboutTestSize = $flag; + } + + /** + * @return boolean + * @since Method available since Release 4.0.0 + */ + public function isStrictAboutTestSize() + { + return $this->beStrictAboutTestSize; + } + + /** + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.2.0 + */ + public function beStrictAboutTodoAnnotatedTests($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->beStrictAboutTodoAnnotatedTests = $flag; + } + + /** + * @return boolean + * @since Method available since Release 4.2.0 + */ + public function isStrictAboutTodoAnnotatedTests() + { + return $this->beStrictAboutTodoAnnotatedTests; + } + + /** + * Enables or disables the stopping for risky tests. + * + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 4.0.0 + */ + public function stopOnRisky($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->stopOnRisky = $flag; + } + + /** + * Enables or disables the stopping for incomplete tests. + * + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.5.0 + */ + public function stopOnIncomplete($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->stopOnIncomplete = $flag; + } + + /** + * Enables or disables the stopping for skipped tests. + * + * @param boolean $flag + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.1.0 + */ + public function stopOnSkipped($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->stopOnSkipped = $flag; + } + + /** + * Returns the time spent running the tests. + * + * @return float + */ + public function time() + { + return $this->time; + } + + /** + * Returns whether the entire test was successful or not. + * + * @return boolean + */ + public function wasSuccessful() + { + return empty($this->errors) && empty($this->failures); + } + + /** + * Sets the timeout for small tests. + * + * @param integer $timeout + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.6.0 + */ + public function setTimeoutForSmallTests($timeout) + { + if (!is_integer($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->timeoutForSmallTests = $timeout; + } + + /** + * Sets the timeout for medium tests. + * + * @param integer $timeout + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.6.0 + */ + public function setTimeoutForMediumTests($timeout) + { + if (!is_integer($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->timeoutForMediumTests = $timeout; + } + + /** + * Sets the timeout for large tests. + * + * @param integer $timeout + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.6.0 + */ + public function setTimeoutForLargeTests($timeout) + { + if (!is_integer($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->timeoutForLargeTests = $timeout; + } + + /** + * Returns the class hierarchy for a given class. + * + * @param string $className + * @param boolean $asReflectionObjects + * @return array + */ + protected function getHierarchy($className, $asReflectionObjects = false) + { + if ($asReflectionObjects) { + $classes = array(new ReflectionClass($className)); + } else { + $classes = array($className); + } + + $done = false; + + while (!$done) { + if ($asReflectionObjects) { + $class = new ReflectionClass( + $classes[count($classes)-1]->getName() + ); + } else { + $class = new ReflectionClass($classes[count($classes)-1]); + } + + $parent = $class->getParentClass(); + + if ($parent !== false) { + if ($asReflectionObjects) { + $classes[] = $parent; + } else { + $classes[] = $parent->getName(); + } + } else { + $done = true; + } + } + + return $classes; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A TestSuite is a composite of Tests. It runs a collection of test cases. + * + * Here is an example using the dynamic test definition. + * + * + * addTest(new MathTest('testPass')); + * ?> + * + * + * Alternatively, a TestSuite can extract the tests to be run automatically. + * To do so you pass a ReflectionClass instance for your + * PHPUnit_Framework_TestCase class to the PHPUnit_Framework_TestSuite + * constructor. + * + * + * + * + * + * This constructor creates a suite with all the methods starting with + * "test" that take no arguments. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_TestSuite implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing, IteratorAggregate +{ + /** + * Enable or disable the backup and restoration of the $GLOBALS array. + * + * @var boolean + */ + protected $backupGlobals = null; + + /** + * Enable or disable the backup and restoration of static attributes. + * + * @var boolean + */ + protected $backupStaticAttributes = null; + + /** + * @var boolean + */ + protected $runTestInSeparateProcess = false; + + /** + * The name of the test suite. + * + * @var string + */ + protected $name = ''; + + /** + * The test groups of the test suite. + * + * @var array + */ + protected $groups = array(); + + /** + * The tests in the test suite. + * + * @var array + */ + protected $tests = array(); + + /** + * The number of tests in the test suite. + * + * @var integer + */ + protected $numTests = -1; + + /** + * @var boolean + */ + protected $testCase = false; + + /** + * @var array + */ + protected $foundClasses = array(); + + /** + * @var PHPUnit_Runner_Filter_Factory + */ + private $iteratorFilter = null; + + /** + * Constructs a new TestSuite: + * + * - PHPUnit_Framework_TestSuite() constructs an empty TestSuite. + * + * - PHPUnit_Framework_TestSuite(ReflectionClass) constructs a + * TestSuite from the given class. + * + * - PHPUnit_Framework_TestSuite(ReflectionClass, String) + * constructs a TestSuite from the given class with the given + * name. + * + * - PHPUnit_Framework_TestSuite(String) either constructs a + * TestSuite from the given class (if the passed string is the + * name of an existing class) or constructs an empty TestSuite + * with the given name. + * + * @param mixed $theClass + * @param string $name + * @throws PHPUnit_Framework_Exception + */ + public function __construct($theClass = '', $name = '') + { + $argumentsValid = false; + + if (is_object($theClass) && + $theClass instanceof ReflectionClass) { + $argumentsValid = true; + } elseif (is_string($theClass) && + $theClass !== '' && + class_exists($theClass, false)) { + $argumentsValid = true; + + if ($name == '') { + $name = $theClass; + } + + $theClass = new ReflectionClass($theClass); + } elseif (is_string($theClass)) { + $this->setName($theClass); + + return; + } + + if (!$argumentsValid) { + throw new PHPUnit_Framework_Exception; + } + + if (!$theClass->isSubclassOf('PHPUnit_Framework_TestCase')) { + throw new PHPUnit_Framework_Exception( + 'Class "' . $theClass->name . '" does not extend PHPUnit_Framework_TestCase.' + ); + } + + if ($name != '') { + $this->setName($name); + } else { + $this->setName($theClass->getName()); + } + + $constructor = $theClass->getConstructor(); + + if ($constructor !== null && + !$constructor->isPublic()) { + $this->addTest( + self::warning( + sprintf( + 'Class "%s" has no public constructor.', + $theClass->getName() + ) + ) + ); + + return; + } + + foreach ($theClass->getMethods() as $method) { + $this->addTestMethod($theClass, $method); + } + + if (empty($this->tests)) { + $this->addTest( + self::warning( + sprintf( + 'No tests found in class "%s".', + $theClass->getName() + ) + ) + ); + } + + $this->testCase = true; + } + + /** + * Returns a string representation of the test suite. + * + * @return string + */ + public function toString() + { + return $this->getName(); + } + + /** + * Adds a test to the suite. + * + * @param PHPUnit_Framework_Test $test + * @param array $groups + */ + public function addTest(PHPUnit_Framework_Test $test, $groups = array()) + { + $class = new ReflectionClass($test); + + if (!$class->isAbstract()) { + $this->tests[] = $test; + $this->numTests = -1; + + if ($test instanceof PHPUnit_Framework_TestSuite && + empty($groups)) { + $groups = $test->getGroups(); + } + + if (empty($groups)) { + $groups = array('__nogroup__'); + } + + foreach ($groups as $group) { + if (!isset($this->groups[$group])) { + $this->groups[$group] = array($test); + } else { + $this->groups[$group][] = $test; + } + } + } + } + + /** + * Adds the tests from the given class to the suite. + * + * @param mixed $testClass + * @throws PHPUnit_Framework_Exception + */ + public function addTestSuite($testClass) + { + if (is_string($testClass) && class_exists($testClass)) { + $testClass = new ReflectionClass($testClass); + } + + if (!is_object($testClass)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'class name or object' + ); + } + + if ($testClass instanceof PHPUnit_Framework_TestSuite) { + $this->addTest($testClass); + } elseif ($testClass instanceof ReflectionClass) { + $suiteMethod = false; + + if (!$testClass->isAbstract()) { + if ($testClass->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { + $method = $testClass->getMethod( + PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME + ); + + if ($method->isStatic()) { + $this->addTest( + $method->invoke(null, $testClass->getName()) + ); + + $suiteMethod = true; + } + } + } + + if (!$suiteMethod && !$testClass->isAbstract()) { + $this->addTest(new PHPUnit_Framework_TestSuite($testClass)); + } + } else { + throw new PHPUnit_Framework_Exception; + } + } + + /** + * Wraps both addTest() and addTestSuite + * as well as the separate import statements for the user's convenience. + * + * If the named file cannot be read or there are no new tests that can be + * added, a PHPUnit_Framework_Warning will be created instead, + * leaving the current test run untouched. + * + * @param string $filename + * @param array $phptOptions Array with ini settings for the php instance + * run, key being the name if the setting, + * value the ini value. + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 2.3.0 + * @author Stefano F. Rausch + */ + public function addTestFile($filename, $phptOptions = array()) + { + if (!is_string($filename)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (file_exists($filename) && substr($filename, -5) == '.phpt') { + $this->addTest( + new PHPUnit_Extensions_PhptTestCase($filename, $phptOptions) + ); + return; + } + + // The given file may contain further stub classes in addition to the + // test class itself. Figure out the actual test class. + $classes = get_declared_classes(); + $filename = PHPUnit_Util_Fileloader::checkAndLoad($filename); + $newClasses = array_diff(get_declared_classes(), $classes); + + // The diff is empty in case a parent class (with test methods) is added + // AFTER a child class that inherited from it. To account for that case, + // cumulate all discovered classes, so the parent class may be found in + // a later invocation. + if ($newClasses) { + // On the assumption that test classes are defined first in files, + // process discovered classes in approximate LIFO order, so as to + // avoid unnecessary reflection. + $this->foundClasses = array_merge($newClasses, $this->foundClasses); + } + + // The test class's name must match the filename, either in full, or as + // a PEAR/PSR-0 prefixed shortname ('NameSpace_ShortName'), or as a + // PSR-1 local shortname ('NameSpace\ShortName'). The comparison must be + // anchored to prevent false-positive matches (e.g., 'OtherShortName'). + $shortname = basename($filename, '.php'); + $shortnameRegEx = '/(?:^|_|\\\\)' . preg_quote($shortname, '/') . '$/'; + + foreach ($this->foundClasses as $i => $className) { + if (preg_match($shortnameRegEx, $className)) { + $class = new ReflectionClass($className); + + if ($class->getFileName() == $filename) { + $newClasses = array($className); + unset($this->foundClasses[$i]); + break; + } + } + } + + foreach ($newClasses as $className) { + $class = new ReflectionClass($className); + + if (!$class->isAbstract()) { + if ($class->hasMethod(PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME)) { + $method = $class->getMethod( + PHPUnit_Runner_BaseTestRunner::SUITE_METHODNAME + ); + + if ($method->isStatic()) { + $this->addTest($method->invoke(null, $className)); + } + } elseif ($class->implementsInterface('PHPUnit_Framework_Test')) { + $this->addTestSuite($class); + } + } + } + + $this->numTests = -1; + } + + /** + * Wrapper for addTestFile() that adds multiple test files. + * + * @param array|Iterator $filenames + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 2.3.0 + */ + public function addTestFiles($filenames) + { + if (!(is_array($filenames) || + (is_object($filenames) && $filenames instanceof Iterator))) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'array or iterator' + ); + } + + foreach ($filenames as $filename) { + $this->addTestFile((string) $filename); + } + } + + /** + * Counts the number of test cases that will be run by this test. + * + * @return integer + */ + public function count() + { + $numTests = 0; + + foreach ($this as $test) { + $numTests += count($test); + } + + return $numTests; + } + + /** + * @param ReflectionClass $theClass + * @param string $name + * @return PHPUnit_Framework_Test + * @throws PHPUnit_Framework_Exception + */ + public static function createTest(ReflectionClass $theClass, $name) + { + $className = $theClass->getName(); + + if (!$theClass->isInstantiable()) { + return self::warning( + sprintf('Cannot instantiate class "%s".', $className) + ); + } + + $backupSettings = PHPUnit_Util_Test::getBackupSettings( + $className, + $name + ); + + $preserveGlobalState = PHPUnit_Util_Test::getPreserveGlobalStateSettings( + $className, + $name + ); + + $runTestInSeparateProcess = PHPUnit_Util_Test::getProcessIsolationSettings( + $className, + $name + ); + + $constructor = $theClass->getConstructor(); + + if ($constructor !== null) { + $parameters = $constructor->getParameters(); + + // TestCase() or TestCase($name) + if (count($parameters) < 2) { + $test = new $className; + } // TestCase($name, $data) + else { + try { + $data = PHPUnit_Util_Test::getProvidedData( + $className, + $name + ); + } catch (Exception $e) { + if (!($e instanceof PHPUnit_Framework_SkippedTestError || $e instanceof PHPUnit_Framework_IncompleteTestError)) { + $message = sprintf( + 'The data provider specified for %s::%s is invalid.', + $className, + $name + ); + + $_message = $e->getMessage(); + + if (!empty($_message)) { + $message .= "\n" . $_message; + } + + $data = self::warning($message); + } elseif ($e instanceof PHPUnit_Framework_SkippedTestError) { + $message = sprintf( + 'Test for %s::%s skipped by data provider', + $className, + $name + ); + + $_message = $e->getMessage(); + + if (!empty($_message)) { + $message .= "\n" . $_message; + } + + $data = self::skipTest($className, $name, $message); + } elseif ($e instanceof PHPUnit_Framework_IncompleteTestError) { + $message = sprintf( + 'Test for %s::%s marked incomplete by data provider', + $className, + $name + ); + + $_message = $e->getMessage(); + + if (!empty($_message)) { + $message .= "\n" . $_message; + } + + $data = self::incompleteTest($className, $name, $message); + } + } + + // Test method with @dataProvider. + if (isset($data)) { + $test = new PHPUnit_Framework_TestSuite_DataProvider( + $className . '::' . $name + ); + + if (empty($data)) { + $data = self::warning( + sprintf( + 'No tests found in suite "%s".', + $test->getName() + ) + ); + } + + $groups = PHPUnit_Util_Test::getGroups($className, $name); + + if ($data instanceof PHPUnit_Framework_Warning || + $data instanceof PHPUnit_Framework_SkippedTestCase || + $data instanceof PHPUnit_Framework_IncompleteTestCase) { + $test->addTest($data, $groups); + } else { + foreach ($data as $_dataName => $_data) { + $_test = new $className($name, $_data, $_dataName); + + if ($runTestInSeparateProcess) { + $_test->setRunTestInSeparateProcess(true); + + if ($preserveGlobalState !== null) { + $_test->setPreserveGlobalState($preserveGlobalState); + } + } + + if ($backupSettings['backupGlobals'] !== null) { + $_test->setBackupGlobals( + $backupSettings['backupGlobals'] + ); + } + + if ($backupSettings['backupStaticAttributes'] !== null) { + $_test->setBackupStaticAttributes( + $backupSettings['backupStaticAttributes'] + ); + } + + $test->addTest($_test, $groups); + } + } + } else { + $test = new $className; + } + } + } + + if (!isset($test)) { + throw new PHPUnit_Framework_Exception('No valid test provided.'); + } + + if ($test instanceof PHPUnit_Framework_TestCase) { + $test->setName($name); + + if ($runTestInSeparateProcess) { + $test->setRunTestInSeparateProcess(true); + + if ($preserveGlobalState !== null) { + $test->setPreserveGlobalState($preserveGlobalState); + } + } + + if ($backupSettings['backupGlobals'] !== null) { + $test->setBackupGlobals($backupSettings['backupGlobals']); + } + + if ($backupSettings['backupStaticAttributes'] !== null) { + $test->setBackupStaticAttributes( + $backupSettings['backupStaticAttributes'] + ); + } + } + + return $test; + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * Returns the name of the suite. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Returns the test groups of the suite. + * + * @return array + * @since Method available since Release 3.2.0 + */ + public function getGroups() + { + return array_keys($this->groups); + } + + public function getGroupDetails() + { + return $this->groups; + } + + /** + * Set tests groups of the test case + * + * @param array $groups + * @since Method available since Release 4.0.0 + */ + public function setGroupDetails(array $groups) + { + $this->groups = $groups; + } + + /** + * Runs the tests and collects their result in a TestResult. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + */ + public function run(PHPUnit_Framework_TestResult $result = null) + { + if ($result === null) { + $result = $this->createResult(); + } + + if (count($this) == 0) { + return $result; + } + + $hookMethods = PHPUnit_Util_Test::getHookMethods($this->name); + + $result->startTestSuite($this); + + try { + $this->setUp(); + + foreach ($hookMethods['beforeClass'] as $beforeClassMethod) { + if ($this->testCase === true && + class_exists($this->name, false) && + method_exists($this->name, $beforeClassMethod)) { + if ($missingRequirements = PHPUnit_Util_Test::getMissingRequirements($this->name, $beforeClassMethod)) { + $this->markTestSuiteSkipped(implode(PHP_EOL, $missingRequirements)); + } + + call_user_func(array($this->name, $beforeClassMethod)); + } + } + } catch (PHPUnit_Framework_SkippedTestSuiteError $e) { + $numTests = count($this); + + for ($i = 0; $i < $numTests; $i++) { + $result->startTest($this); + $result->addFailure($this, $e, 0); + $result->endTest($this, 0); + } + + $this->tearDown(); + $result->endTestSuite($this); + + return $result; + } catch (Exception $e) { + $numTests = count($this); + + for ($i = 0; $i < $numTests; $i++) { + $result->startTest($this); + $result->addError($this, $e, 0); + $result->endTest($this, 0); + } + + $this->tearDown(); + $result->endTestSuite($this); + + return $result; + } + + foreach ($this as $test) { + if ($result->shouldStop()) { + break; + } + + if ($test instanceof PHPUnit_Framework_TestCase || + $test instanceof PHPUnit_Framework_TestSuite) { + $test->setBackupGlobals($this->backupGlobals); + $test->setBackupStaticAttributes($this->backupStaticAttributes); + $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess); + } + + $test->run($result); + } + + foreach ($hookMethods['afterClass'] as $afterClassMethod) { + if ($this->testCase === true && class_exists($this->name, false) && method_exists($this->name, $afterClassMethod)) { + call_user_func(array($this->name, $afterClassMethod)); + } + } + + $this->tearDown(); + + $result->endTestSuite($this); + + return $result; + } + + /** + * @param boolean $runTestInSeparateProcess + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.7.0 + */ + public function setRunTestInSeparateProcess($runTestInSeparateProcess) + { + if (is_bool($runTestInSeparateProcess)) { + $this->runTestInSeparateProcess = $runTestInSeparateProcess; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * Runs a test. + * + * @deprecated + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_TestResult $result + */ + public function runTest(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result) + { + $test->run($result); + } + + /** + * Sets the name of the suite. + * + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Returns the test at the given index. + * + * @param integer + * @return PHPUnit_Framework_Test + */ + public function testAt($index) + { + if (isset($this->tests[$index])) { + return $this->tests[$index]; + } else { + return false; + } + } + + /** + * Returns the tests as an enumeration. + * + * @return array + */ + public function tests() + { + return $this->tests; + } + + /** + * Set tests of the test suite + * + * @param array $tests + * @since Method available since Release 4.0.0 + */ + public function setTests(array $tests) + { + $this->tests = $tests; + } + + /** + * Mark the test suite as skipped. + * + * @param string $message + * @throws PHPUnit_Framework_SkippedTestSuiteError + * @since Method available since Release 3.0.0 + */ + public function markTestSuiteSkipped($message = '') + { + throw new PHPUnit_Framework_SkippedTestSuiteError($message); + } + + /** + * @param ReflectionClass $class + * @param ReflectionMethod $method + */ + protected function addTestMethod(ReflectionClass $class, ReflectionMethod $method) + { + if (!$this->isTestMethod($method)) { + return; + } + + $name = $method->getName(); + + if (!$method->isPublic()) { + $this->addTest( + self::warning( + sprintf( + 'Test method "%s" in test class "%s" is not public.', + $name, + $class->getName() + ) + ) + ); + + return; + } + + $test = self::createTest($class, $name); + + if ($test instanceof PHPUnit_Framework_TestCase || + $test instanceof PHPUnit_Framework_TestSuite_DataProvider) { + $test->setDependencies( + PHPUnit_Util_Test::getDependencies($class->getName(), $name) + ); + } + + $this->addTest( + $test, + PHPUnit_Util_Test::getGroups($class->getName(), $name) + ); + } + + /** + * @param ReflectionMethod $method + * @return boolean + */ + public static function isTestMethod(ReflectionMethod $method) + { + if (strpos($method->name, 'test') === 0) { + return true; + } + + // @scenario on TestCase::testMethod() + // @test on TestCase::testMethod() + $doc_comment = $method->getDocComment(); + + return strpos($doc_comment, '@test') !== false || + strpos($doc_comment, '@scenario') !== false; + } + + /** + * @param string $message + * @return PHPUnit_Framework_Warning + */ + protected static function warning($message) + { + return new PHPUnit_Framework_Warning($message); + } + + /** + * @param string $class + * @param string $methodName + * @param string $message + * @return PHPUnit_Framework_SkippedTestCase + * @since Method available since Release 4.3.0 + */ + protected static function skipTest($class, $methodName, $message) + { + return new PHPUnit_Framework_SkippedTestCase($class, $methodName, $message); + } + + /** + * @param string $class + * @param string $methodName + * @param string $message + * @return PHPUnit_Framework_IncompleteTestCase + * @since Method available since Release 4.3.0 + */ + protected static function incompleteTest($class, $methodName, $message) + { + return new PHPUnit_Framework_IncompleteTestCase($class, $methodName, $message); + } + + /** + * @param boolean $backupGlobals + * @since Method available since Release 3.3.0 + */ + public function setBackupGlobals($backupGlobals) + { + if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * @param boolean $backupStaticAttributes + * @since Method available since Release 3.4.0 + */ + public function setBackupStaticAttributes($backupStaticAttributes) + { + if (is_null($this->backupStaticAttributes) && + is_bool($backupStaticAttributes)) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * Returns an iterator for this test suite. + * + * @return RecursiveIteratorIterator + * @since Method available since Release 3.1.0 + */ + public function getIterator() + { + $iterator = new PHPUnit_Util_TestSuiteIterator($this); + + if ($this->iteratorFilter !== null) { + $iterator = $this->iteratorFilter->factory($iterator, $this); + } + + return $iterator; + } + + public function injectFilter(PHPUnit_Runner_Filter_Factory $filter) + { + $this->iteratorFilter = $filter; + foreach ($this as $test) { + if ($test instanceof PHPUnit_Framework_TestSuite) { + $test->injectFilter($filter); + } + } + } + + /** + * Template Method that is called before the tests + * of this test suite are run. + * + * @since Method available since Release 3.1.0 + */ + protected function setUp() + { + } + + /** + * Template Method that is called after the tests + * of this test suite have finished running. + * + * @since Method available since Release 3.1.0 + */ + protected function tearDown() + { + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Framework_CodeCoverageException extends PHPUnit_Framework_Exception +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Creates a synthetic failed assertion. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.5.0 + */ +class PHPUnit_Framework_SyntheticError extends PHPUnit_Framework_AssertionFailedError +{ + /** + * The synthetic file. + * + * @var string + */ + protected $syntheticFile = ''; + + /** + * The synthetic line number. + * + * @var integer + */ + protected $syntheticLine = 0; + + /** + * The synthetic trace. + * + * @var array + */ + protected $syntheticTrace = array(); + + /** + * Constructor. + * + * @param string $message + * @param integer $code + * @param string $file + * @param integer $line + * @param array $trace + */ + public function __construct($message, $code, $file, $line, $trace) + { + parent::__construct($message, $code); + + $this->syntheticFile = $file; + $this->syntheticLine = $line; + $this->syntheticTrace = $trace; + } + + /** + * @return string + */ + public function getSyntheticFile() + { + return $this->syntheticFile; + } + + /** + * @return integer + */ + public function getSyntheticLine() + { + return $this->syntheticLine; + } + + /** + * @return array + */ + public function getSyntheticTrace() + { + return $this->syntheticTrace; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a skipped test suite. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_SkippedTestSuiteError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * An empty Listener that can be extended to implement TestListener + * with just a few lines of code. + * @see PHPUnit_Framework_TestListener for documentation on the API methods. + * + * @package PHPUnit + * @subpackage Framework + * @author Giorgio Sironi + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +abstract class PHPUnit_Framework_BaseTestListener implements PHPUnit_Framework_TestListener +{ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + } + + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + } + + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + public function startTest(PHPUnit_Framework_Test $test) + { + } + + public function endTest(PHPUnit_Framework_Test $test, $time) + { + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of an incomplete test. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_IncompleteTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_IncompleteTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a skipped test. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_SkippedTestError extends PHPUnit_Framework_AssertionFailedError implements PHPUnit_Framework_SkippedTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that checks if one value is equal to another. + * + * Equality is checked with PHP's == operator, the operator is explained in + * detail at {@url http://www.php.net/manual/en/types.comparisons.php}. + * Two values are equal if they have the same value disregarding type. + * + * The expected value is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Kore Nordmann + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsEqual extends PHPUnit_Framework_Constraint +{ + /** + * @var mixed + */ + protected $value; + + /** + * @var float + */ + protected $delta = 0.0; + + /** + * @var integer + */ + protected $maxDepth = 10; + + /** + * @var boolean + */ + protected $canonicalize = false; + + /** + * @var boolean + */ + protected $ignoreCase = false; + + /** + * @var SebastianBergmann\Comparator\ComparisonFailure + */ + protected $lastFailure; + + /** + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @throws PHPUnit_Framework_Exception + */ + public function __construct($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) + { + parent::__construct(); + + if (!is_numeric($delta)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'numeric'); + } + + if (!is_int($maxDepth)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'integer'); + } + + if (!is_bool($canonicalize)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'boolean'); + } + + if (!is_bool($ignoreCase)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(5, 'boolean'); + } + + $this->value = $value; + $this->delta = $delta; + $this->maxDepth = $maxDepth; + $this->canonicalize = $canonicalize; + $this->ignoreCase = $ignoreCase; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $comparatorFactory = new SebastianBergmann\Comparator\Factory; + + try { + $comparator = $comparatorFactory->getComparatorFor( + $this->value, + $other + ); + + $comparator->assertEquals( + $this->value, + $other, + $this->delta, + $this->canonicalize, + $this->ignoreCase + ); + } catch (SebastianBergmann\Comparator\ComparisonFailure $f) { + if ($returnResult) { + return false; + } + + throw new PHPUnit_Framework_ExpectationFailedException( + trim($description . "\n" . $f->getMessage()), + $f + ); + } + + return true; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $delta = ''; + + if (is_string($this->value)) { + if (strpos($this->value, "\n") !== false) { + return 'is equal to '; + } else { + return sprintf( + 'is equal to ', + $this->value + ); + } + } else { + if ($this->delta != 0) { + $delta = sprintf( + ' with delta <%F>', + $this->delta + ); + } + + return sprintf( + 'is equal to %s%s', + $this->exporter->export($this->value), + $delta + ); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.6 + */ +class PHPUnit_Framework_Constraint_ExceptionMessage extends PHPUnit_Framework_Constraint +{ + /** + * @var integer + */ + protected $expectedMessage; + + /** + * @param string $expected + */ + public function __construct($expected) + { + parent::__construct(); + $this->expectedMessage = $expected; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param Exception $other + * @return boolean + */ + protected function matches($other) + { + return strpos($other->getMessage(), $this->expectedMessage) !== false; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + "exception message '%s' contains '%s'", + $other->getMessage(), + $this->expectedMessage + ); + } + + /** + * @return string + */ + public function toString() + { + return 'exception message contains '; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the value it is evaluated for is greater + * than a given value. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_GreaterThan extends PHPUnit_Framework_Constraint +{ + /** + * @var numeric + */ + protected $value; + + /** + * @param numeric $value + */ + public function __construct($value) + { + parent::__construct(); + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return $this->value < $other; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is greater than ' . $this->exporter->export($this->value); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the value it is evaluated for is of a + * specified type. + * + * The expected value is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsType extends PHPUnit_Framework_Constraint +{ + const TYPE_ARRAY = 'array'; + const TYPE_BOOL = 'bool'; + const TYPE_FLOAT = 'float'; + const TYPE_INT = 'int'; + const TYPE_NULL = 'null'; + const TYPE_NUMERIC = 'numeric'; + const TYPE_OBJECT = 'object'; + const TYPE_RESOURCE = 'resource'; + const TYPE_STRING = 'string'; + const TYPE_SCALAR = 'scalar'; + const TYPE_CALLABLE = 'callable'; + + /** + * @var array + */ + protected $types = array( + 'array' => true, + 'boolean' => true, + 'bool' => true, + 'double' => true, + 'float' => true, + 'integer' => true, + 'int' => true, + 'null' => true, + 'numeric' => true, + 'object' => true, + 'resource' => true, + 'string' => true, + 'scalar' => true, + 'callable' => true + ); + + /** + * @var string + */ + protected $type; + + /** + * @param string $type + * @throws PHPUnit_Framework_Exception + */ + public function __construct($type) + { + parent::__construct(); + + if (!isset($this->types[$type])) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Type specified for PHPUnit_Framework_Constraint_IsType <%s> ' . + 'is not a valid type.', + $type + ) + ); + } + + $this->type = $type; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + switch ($this->type) { + case 'numeric': { + return is_numeric($other); + } + + case 'integer': + case 'int': { + return is_integer($other); + } + + case 'double': + case 'float': { + return is_float($other); + } + + case 'string': { + return is_string($other); + } + + case 'boolean': + case 'bool': { + return is_bool($other); + } + + case 'null': { + return is_null($other); + } + + case 'array': { + return is_array($other); + } + + case 'object': { + return is_object($other); + } + + case 'resource': { + return is_resource($other); + } + + case 'scalar': { + return is_scalar($other); + } + + case 'callable': { + return is_callable($other); + } + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'is of type "%s"', + $this->type + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the string it is evaluated for contains + * a given string. + * + * Uses strpos() to find the position of the string in the input, if not found + * the evaluation fails. + * + * The sub-string is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_StringContains extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $string; + + /** + * @var boolean + */ + protected $ignoreCase; + + /** + * @param string $string + * @param boolean $ignoreCase + */ + public function __construct($string, $ignoreCase = false) + { + parent::__construct(); + + $this->string = $string; + $this->ignoreCase = $ignoreCase; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + if ($this->ignoreCase) { + return stripos($other, $this->string) !== false; + } else { + return strpos($other, $this->string) !== false; + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + if ($this->ignoreCase) { + $string = strtolower($this->string); + } else { + $string = $this->string; + } + + return sprintf( + 'contains "%s"', + $string + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the object it is evaluated for is an instance + * of a given class. + * + * The expected class name is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsInstanceOf extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $className; + + /** + * @param string $className + */ + public function __construct($className) + { + parent::__construct(); + $this->className = $className; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return ($other instanceof $this->className); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + '%s is an instance of %s "%s"', + $this->exporter->shortenedExport($other), + $this->getType(), + $this->className + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'is instance of %s "%s"', + $this->getType(), + $this->className + ); + } + + private function getType() + { + try { + $reflection = new ReflectionClass($this->className); + if ($reflection->isInterface()) { + return 'interface'; + } + } catch (ReflectionException $e) { + } + + return 'class'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the class it is evaluated for has a given + * static attribute. + * + * The attribute name is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_Constraint_ClassHasStaticAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + $class = new ReflectionClass($other); + + if ($class->hasProperty($this->attributeName)) { + $attribute = $class->getProperty($this->attributeName); + + return $attribute->isStatic(); + } else { + return false; + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + * @since Method available since Release 3.3.0 + */ + public function toString() + { + return sprintf( + 'has static attribute "%s"', + $this->attributeName + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that accepts any input value. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsAnything extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + return $returnResult ? true : null; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is anything'; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.5.0 + */ + public function count() + { + return 0; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Provides human readable messages for each JSON error. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Bastian Feder + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause + * @link http://www.phpunit.de/ + * @since Class available since Release 3.7.0 + */ +class PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider +{ + /** + * Translates JSON error to a human readable string. + * + * @param string $error + * @param string $prefix + * @return string + */ + public static function determineJsonError($error, $prefix = '') + { + switch ($error) { + case JSON_ERROR_NONE: + return; + case JSON_ERROR_DEPTH: + return $prefix . 'Maximum stack depth exceeded'; + case JSON_ERROR_STATE_MISMATCH: + return $prefix . 'Underflow or the modes mismatch'; + case JSON_ERROR_CTRL_CHAR: + return $prefix . 'Unexpected control character found'; + case JSON_ERROR_SYNTAX: + return $prefix . 'Syntax error, malformed JSON'; + case JSON_ERROR_UTF8: + return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded'; + default: + return $prefix . 'Unknown error'; + } + } + + /** + * Translates a given type to a human readable message prefix. + * + * @param string $type + * @return string + */ + public static function translateTypeToPrefix($type) + { + switch (strtolower($type)) { + case 'expected': + $prefix = 'Expected value JSON decode error - '; + break; + case 'actual': + $prefix = 'Actual value JSON decode error - '; + break; + default: + $prefix = ''; + break; + } + + return $prefix; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Logical AND. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_And extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint[] + */ + protected $constraints = array(); + + /** + * @var PHPUnit_Framework_Constraint + */ + protected $lastConstraint = null; + + /** + * @param PHPUnit_Framework_Constraint[] $constraints + * @throws PHPUnit_Framework_Exception + */ + public function setConstraints(array $constraints) + { + $this->constraints = array(); + + foreach ($constraints as $constraint) { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + throw new PHPUnit_Framework_Exception( + 'All parameters to ' . __CLASS__ . + ' must be a constraint object.' + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $success = true; + $constraint = null; + + foreach ($this->constraints as $constraint) { + if (!$constraint->evaluate($other, $description, true)) { + $success = false; + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $text = ''; + + foreach ($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' and '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + $count = 0; + + foreach ($this->constraints as $constraint) { + $count += count($constraint); + } + + return $count; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +abstract class PHPUnit_Framework_Constraint_Composite extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $innerConstraint; + + /** + * @param PHPUnit_Framework_Constraint $innerConstraint + */ + public function __construct(PHPUnit_Framework_Constraint $innerConstraint) + { + parent::__construct(); + $this->innerConstraint = $innerConstraint; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + try { + return $this->innerConstraint->evaluate( + $other, + $description, + $returnResult + ); + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + $this->fail($other, $description); + } + } + + /** + * Counts the number of constraint elements. + * + * @return integer + */ + public function count() + { + return count($this->innerConstraint); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the string it is evaluated for begins with a + * given prefix. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_Constraint_StringStartsWith extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $prefix; + + /** + * @param string $prefix + */ + public function __construct($prefix) + { + parent::__construct(); + $this->prefix = $prefix; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return strpos($other, $this->prefix) === 0; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'starts with "' . $this->prefix . '"'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that accepts null. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Constraint_IsNull extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return $other === null; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is null'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the object it is evaluated for has a given + * attribute. + * + * The attribute name is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_ObjectHasAttribute extends PHPUnit_Framework_Constraint_ClassHasAttribute +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + $object = new ReflectionObject($other); + + return $object->hasProperty($this->attributeName); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that checks if the file(name) that it is evaluated for exists. + * + * The file path to check is passed as $other in evaluate(). + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_FileExists extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return file_exists($other); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + 'file "%s" exists', + $other + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'file exists'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the array it is evaluated for has a given key. + * + * Uses array_key_exists() to check if the key is found in the input array, if + * not found the evaluation fails. + * + * The array key is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_ArrayHasKey extends PHPUnit_Framework_Constraint +{ + /** + * @var integer|string + */ + protected $key; + + /** + * @param integer|string $key + */ + public function __construct($key) + { + parent::__construct(); + $this->key = $key; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + if (is_array($other)) { + return array_key_exists($this->key, $other); + } + + if ($other instanceof ArrayAccess) { + return $other->offsetExists($this->key); + } + + return false; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'has the key ' . $this->exporter->export($this->key); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return 'an array ' . $this->toString(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the class it is evaluated for has a given + * attribute. + * + * The attribute name is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_Constraint_ClassHasAttribute extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $attributeName; + + /** + * @param string $attributeName + */ + public function __construct($attributeName) + { + parent::__construct(); + $this->attributeName = $attributeName; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + $class = new ReflectionClass($other); + + return $class->hasProperty($this->attributeName); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'has attribute "%s"', + $this->attributeName + ); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + '%sclass "%s" %s', + is_object($other) ? 'object of ' : '', + is_object($other) ? get_class($other) : $other, + $this->toString() + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Logical OR. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_Or extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint[] + */ + protected $constraints = array(); + + /** + * @param PHPUnit_Framework_Constraint[] $constraints + */ + public function setConstraints(array $constraints) + { + $this->constraints = array(); + + foreach ($constraints as $constraint) { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $constraint + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $success = false; + $constraint = null; + + foreach ($this->constraints as $constraint) { + if ($constraint->evaluate($other, $description, true)) { + $success = true; + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $text = ''; + + foreach ($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' or '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + $count = 0; + + foreach ($this->constraints as $constraint) { + $count += count($constraint); + } + + return $count; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.6 + */ +class PHPUnit_Framework_Constraint_ExceptionCode extends PHPUnit_Framework_Constraint +{ + /** + * @var integer + */ + protected $expectedCode; + + /** + * @param integer $expected + */ + public function __construct($expected) + { + parent::__construct(); + $this->expectedCode = $expected; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param Exception $other + * @return boolean + */ + protected function matches($other) + { + return (string) $other->getCode() == (string) $this->expectedCode; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + '%s is equal to expected exception code %s', + $this->exporter->export($other->getCode()), + $this->exporter->export($this->expectedCode) + ); + } + + /** + * @return string + */ + public function toString() + { + return 'exception code is '; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.6 + */ +class PHPUnit_Framework_Constraint_Exception extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $className; + + /** + * @param string $className + */ + public function __construct($className) + { + parent::__construct(); + $this->className = $className; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return $other instanceof $this->className; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + if ($other !== null) { + $message = ''; + if ($other instanceof Exception) { + $message = '. Message was: "' . $other->getMessage() . '" at' + . "\n" . $other->getTraceAsString(); + } + + return sprintf( + 'exception of type "%s" matches expected exception "%s"%s', + get_class($other), + $this->className, + $message + ); + } + + return sprintf( + 'exception of type "%s" is thrown', + $this->className + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'exception of type "%s"', + $this->className + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the array it is evaluated for has a specified subset. + * + * Uses array_replace_recursive() to check if a key value subset is part of the + * subject array. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Márcio Almada + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.4.0 + */ +class PHPUnit_Framework_Constraint_ArraySubset extends PHPUnit_Framework_Constraint +{ + /** + * @var array|ArrayAccess + */ + protected $subset; + + /** + * @var boolean + */ + protected $strict; + + /** + * @param array|ArrayAccess $subset + * @param boolean $strict Check for object identity + */ + public function __construct($subset, $strict = false) + { + parent::__construct(); + $this->strict = $strict; + $this->subset = $subset; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param array|ArrayAccess $other Array or ArrayAcess object to evaluate. + * @return bool + */ + protected function matches($other) + { + $patched = array_replace_recursive($other, $this->subset); + + if ($this->strict) { + return $other === $patched; + } else { + return $other == $patched; + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'has the subset ' . $this->exporter->export($this->subset); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return 'an array ' . $this->toString(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.0 + */ +class PHPUnit_Framework_Constraint_Count extends PHPUnit_Framework_Constraint +{ + /** + * @var integer + */ + protected $expectedCount = 0; + + /** + * @param integer $expected + */ + public function __construct($expected) + { + parent::__construct(); + $this->expectedCount = $expected; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other + * @return boolean + */ + protected function matches($other) + { + return $this->expectedCount === $this->getCountOf($other); + } + + /** + * @param mixed $other + * @return boolean + */ + protected function getCountOf($other) + { + if ($other instanceof Countable || is_array($other)) { + return count($other); + } elseif ($other instanceof Traversable) { + if ($other instanceof IteratorAggregate) { + $iterator = $other->getIterator(); + } else { + $iterator = $other; + } + + $key = $iterator->key(); + $count = iterator_count($iterator); + + // manually rewind $iterator to previous key, since iterator_count + // moves pointer + if ($key !== null) { + $iterator->rewind(); + while ($iterator->valid() && $key !== $iterator->key()) { + $iterator->next(); + } + } + + return $count; + } + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + 'actual size %d matches expected size %d', + $this->getCountOf($other), + $this->expectedCount + ); + } + + /** + * @return string + */ + public function toString() + { + return sprintf( + 'count matches %d', + $this->expectedCount + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Diff\Differ; + +/** + * ... + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.5.0 + */ +class PHPUnit_Framework_Constraint_StringMatches extends PHPUnit_Framework_Constraint_PCREMatch +{ + /** + * @var string + */ + protected $string; + + /** + * @param string $string + */ + public function __construct($string) + { + parent::__construct($string); + + $this->pattern = $this->createPatternFromFormat( + preg_replace('/\r\n/', "\n", $string) + ); + + $this->string = $string; + } + + protected function failureDescription($other) + { + return "format description matches text"; + } + + protected function additionalFailureDescription($other) + { + $from = preg_split('(\r\n|\r|\n)', $this->string); + $to = preg_split('(\r\n|\r|\n)', $other); + + foreach ($from as $index => $line) { + if (isset($to[$index]) && $line !== $to[$index]) { + $line = $this->createPatternFromFormat($line); + + if (preg_match($line, $to[$index]) > 0) { + $from[$index] = $to[$index]; + } + } + } + + $this->string = join("\n", $from); + $other = join("\n", $to); + + $differ = new Differ("--- Expected\n+++ Actual\n"); + + return $differ->diff($this->string, $other); + } + + protected function createPatternFromFormat($string) + { + $string = str_replace( + array( + '%e', + '%s', + '%S', + '%a', + '%A', + '%w', + '%i', + '%d', + '%x', + '%f', + '%c' + ), + array( + '\\' . DIRECTORY_SEPARATOR, + '[^\r\n]+', + '[^\r\n]*', + '.+', + '.*', + '\s*', + '[+-]?\d+', + '\d+', + '[0-9a-fA-F]+', + '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', + '.' + ), + preg_quote($string, '/') + ); + + return '/^' . $string . '$/s'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the string it is evaluated for ends with a given + * suffix. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_Constraint_StringEndsWith extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $suffix; + + /** + * @param string $suffix + */ + public function __construct($suffix) + { + parent::__construct(); + $this->suffix = $suffix; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return substr($other, 0 - strlen($this->suffix)) == $this->suffix; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'ends with "' . $this->suffix . '"'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.0 + */ +class PHPUnit_Framework_Constraint_SameSize extends PHPUnit_Framework_Constraint_Count +{ + /** + * @var integer + */ + protected $expectedCount; + + /** + * @param integer $expected + */ + public function __construct($expected) + { + parent::__construct($this->getCountOf($expected)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that a string is valid JSON. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.7.20 + */ +class PHPUnit_Framework_Constraint_IsJson extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + json_decode($other); + if (json_last_error()) { + return false; + } + + return true; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + json_decode($other); + $error = PHPUnit_Framework_Constraint_JsonMatches_ErrorMessageProvider::determineJsonError( + json_last_error() + ); + + return sprintf( + '%s is valid JSON (%s)', + $this->exporter->shortenedExport($other), + $error + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is valid JSON'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Márcio Almada + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.3.0 + */ +class PHPUnit_Framework_Constraint_ExceptionMessageRegExp extends PHPUnit_Framework_Constraint +{ + /** + * @var integer + */ + protected $expectedMessageRegExp; + + /** + * @param string $expected + */ + public function __construct($expected) + { + parent::__construct(); + $this->expectedMessageRegExp = $expected; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param Exception $other + * @return boolean + */ + protected function matches($other) + { + $match = PHPUnit_Util_Regex::pregMatchSafe($this->expectedMessageRegExp, $other->getMessage()); + + if (false === $match) { + throw new PHPUnit_Framework_Exception ( + "Invalid expected exception message regex given: '{$this->expectedMessageRegExp}'" + ); + } + + return 1 === $match; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + "exception message '%s' matches '%s'", + $other->getMessage(), + $this->expectedMessageRegExp + ); + } + + /** + * @return string + */ + public function toString() + { + return "exception message matches "; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Asserts whether or not two JSON objects are equal. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Bastian Feder + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause + * @link http://www.phpunit.de/ + * @since Class available since Release 3.7.0 + */ +class PHPUnit_Framework_Constraint_JsonMatches extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $value; + + /** + * Creates a new constraint. + * + * @param string $value + */ + public function __construct($value) + { + parent::__construct(); + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * This method can be overridden to implement the evaluation algorithm. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + $decodedOther = json_decode($other); + if (json_last_error()) { + return false; + } + + $decodedValue = json_decode($this->value); + if (json_last_error()) { + return false; + } + + return $decodedOther == $decodedValue; + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return sprintf( + 'matches JSON string "%s"', + $this->value + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that checks whether a variable is empty(). + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.5.0 + */ +class PHPUnit_Framework_Constraint_IsEmpty extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + if ($other instanceof Countable) { + return count($other) === 0; + } + + return empty($other); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is empty'; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + $type = gettype($other); + + return sprintf( + '%s %s %s', + $type[0] == 'a' || $type[0] == 'o' ? 'an' : 'a', + $type, + $this->toString() + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Framework_Constraint_Attribute extends PHPUnit_Framework_Constraint_Composite +{ + /** + * @var string + */ + protected $attributeName; + + /** + * @param PHPUnit_Framework_Constraint $constraint + * @param string $attributeName + */ + public function __construct(PHPUnit_Framework_Constraint $constraint, $attributeName) + { + parent::__construct($constraint); + + $this->attributeName = $attributeName; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + return parent::evaluate( + PHPUnit_Framework_Assert::readAttribute( + $other, + $this->attributeName + ), + $description, + $returnResult + ); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'attribute "' . $this->attributeName . '" ' . + $this->innerConstraint->toString(); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return $this->toString(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the Traversable it is applied to contains + * only values of a given type. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.4 + */ +class PHPUnit_Framework_Constraint_TraversableContainsOnly extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @var string + */ + protected $type; + + /** + * @param string $type + * @param boolean $isNativeType + */ + public function __construct($type, $isNativeType = true) + { + parent::__construct(); + + if ($isNativeType) { + $this->constraint = new PHPUnit_Framework_Constraint_IsType($type); + } else { + $this->constraint = new PHPUnit_Framework_Constraint_IsInstanceOf( + $type + ); + } + + $this->type = $type; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $success = true; + + foreach ($other as $item) { + if (!$this->constraint->evaluate($item, '', true)) { + $success = false; + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'contains only values of type "' . $this->type . '"'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that accepts false. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Constraint_IsFalse extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return $other === false; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is false'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the string it is evaluated for matches + * a regular expression. + * + * Checks a given value using the Perl Compatible Regular Expression extension + * in PHP. The pattern is matched by executing preg_match(). + * + * The pattern string passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_PCREMatch extends PHPUnit_Framework_Constraint +{ + /** + * @var string + */ + protected $pattern; + + /** + * @param string $pattern + */ + public function __construct($pattern) + { + parent::__construct(); + $this->pattern = $pattern; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return preg_match($this->pattern, $other) > 0; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return sprintf( + 'matches PCRE pattern "%s"', + $this->pattern + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Logical NOT. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_Not extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @param PHPUnit_Framework_Constraint $constraint + */ + public function __construct($constraint) + { + parent::__construct(); + + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + $constraint = new PHPUnit_Framework_Constraint_IsEqual($constraint); + } + + $this->constraint = $constraint; + } + + /** + * @param string $string + * @return string + */ + public static function negate($string) + { + return str_replace( + array( + 'contains ', + 'exists', + 'has ', + 'is ', + 'are ', + 'matches ', + 'starts with ', + 'ends with ', + 'reference ', + 'not not ' + ), + array( + 'does not contain ', + 'does not exist', + 'does not have ', + 'is not ', + 'are not ', + 'does not match ', + 'starts not with ', + 'ends not with ', + 'don\'t reference ', + 'not ' + ), + $string + ); + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $success = !$this->constraint->evaluate($other, $description, true); + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + switch (get_class($this->constraint)) { + case 'PHPUnit_Framework_Constraint_And': + case 'PHPUnit_Framework_Constraint_Not': + case 'PHPUnit_Framework_Constraint_Or': { + return 'not( ' . $this->constraint->failureDescription($other) . ' )'; + } + break; + + default: { + return self::negate( + $this->constraint->failureDescription($other) + ); + } + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + switch (get_class($this->constraint)) { + case 'PHPUnit_Framework_Constraint_And': + case 'PHPUnit_Framework_Constraint_Not': + case 'PHPUnit_Framework_Constraint_Or': { + return 'not( ' . $this->constraint->toString() . ' )'; + } + break; + + default: { + return self::negate( + $this->constraint->toString() + ); + } + } + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + return count($this->constraint); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that evaluates against a specified closure. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Timon Rapp + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + */ +class PHPUnit_Framework_Constraint_Callback extends PHPUnit_Framework_Constraint +{ + private $callback; + + /** + * @param callable $callback + * @throws PHPUnit_Framework_Exception + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory( + 1, + 'callable' + ); + } + + parent::__construct(); + + $this->callback = $callback; + } + + /** + * Evaluates the constraint for parameter $value. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return call_user_func($this->callback, $other); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is accepted by specified callback'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that one value is identical to another. + * + * Identical check is performed with PHP's === operator, the operator is + * explained in detail at + * {@url http://www.php.net/manual/en/types.comparisons.php}. + * Two values are identical if they have the same value and are of the same + * type. + * + * The expected value is passed in the constructor. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_IsIdentical extends PHPUnit_Framework_Constraint +{ + /** + * @var float + */ + const EPSILON = 0.0000000001; + + /** + * @var mixed + */ + protected $value; + + /** + * @param mixed $value + */ + public function __construct($value) + { + parent::__construct(); + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + if (is_double($this->value) && is_double($other) && + !is_infinite($this->value) && !is_infinite($other) && + !is_nan($this->value) && !is_nan($other)) { + $success = abs($this->value - $other) < self::EPSILON; + } else { + $success = $this->value === $other; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $f = null; + + // if both values are strings, make sure a diff is generated + if (is_string($this->value) && is_string($other)) { + $f = new SebastianBergmann\Comparator\ComparisonFailure( + $this->value, + $other, + $this->value, + $other + ); + } + + $this->fail($other, $description, $f); + } + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + if (is_object($this->value) && is_object($other)) { + return 'two variables reference the same object'; + } + + if (is_string($this->value) && is_string($other)) { + return 'two strings are identical'; + } + + return parent::failureDescription($other); + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + if (is_object($this->value)) { + return 'is identical to an object of class "' . + get_class($this->value) . '"'; + } else { + return 'is identical to ' . + $this->exporter->export($this->value); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the value it is evaluated for is less than + * a given value. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_LessThan extends PHPUnit_Framework_Constraint +{ + /** + * @var numeric + */ + protected $value; + + /** + * @param numeric $value + */ + public function __construct($value) + { + parent::__construct(); + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return $this->value > $other; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is less than ' . $this->exporter->export($this->value); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Logical XOR. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_Xor extends PHPUnit_Framework_Constraint +{ + /** + * @var PHPUnit_Framework_Constraint[] + */ + protected $constraints = array(); + + /** + * @param PHPUnit_Framework_Constraint[] $constraints + */ + public function setConstraints(array $constraints) + { + $this->constraints = array(); + + foreach ($constraints as $constraint) { + if (!($constraint instanceof PHPUnit_Framework_Constraint)) { + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $constraint + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $success = true; + $lastResult = null; + $constraint = null; + + foreach ($this->constraints as $constraint) { + $result = $constraint->evaluate($other, $description, true); + + if ($result === $lastResult) { + $success = false; + break; + } + + $lastResult = $result; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + $text = ''; + + foreach ($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' xor '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + $count = 0; + + foreach ($this->constraints as $constraint) { + $count += count($constraint); + } + + return $count; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that asserts that the Traversable it is applied to contains + * a given value. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Framework_Constraint_TraversableContains extends PHPUnit_Framework_Constraint +{ + /** + * @var boolean + */ + protected $checkForObjectIdentity; + + /** + * @var boolean + */ + protected $checkForNonObjectIdentity; + + /** + * @var mixed + */ + protected $value; + + /** + * @param mixed $value + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @throws PHPUnit_Framework_Exception + */ + public function __construct($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) + { + parent::__construct(); + + if (!is_bool($checkForObjectIdentity)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'boolean'); + } + + if (!is_bool($checkForNonObjectIdentity)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'boolean'); + } + + $this->checkForObjectIdentity = $checkForObjectIdentity; + $this->checkForNonObjectIdentity = $checkForNonObjectIdentity; + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + if ($other instanceof SplObjectStorage) { + return $other->contains($this->value); + } + + if (is_object($this->value)) { + foreach ($other as $element) { + if (($this->checkForObjectIdentity && + $element === $this->value) || + (!$this->checkForObjectIdentity && + $element == $this->value)) { + return true; + } + } + } else { + foreach ($other as $element) { + if (($this->checkForNonObjectIdentity && + $element === $this->value) || + (!$this->checkForNonObjectIdentity && + $element == $this->value)) { + return true; + } + } + } + + return false; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + if (is_string($this->value) && strpos($this->value, "\n") !== false) { + return 'contains "' . $this->value . '"'; + } else { + return 'contains ' . $this->exporter->export($this->value); + } + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return sprintf( + '%s %s', + is_array($other) ? 'an array' : 'a traversable', + $this->toString() + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Constraint that accepts true. + * + * @package PHPUnit + * @subpackage Framework_Constraint + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Framework_Constraint_IsTrue extends PHPUnit_Framework_Constraint +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return $other === true; + } + + /** + * Returns a string representation of the constraint. + * + * @return string + */ + public function toString() + { + return 'is true'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Extension to PHPUnit_Framework_AssertionFailedError to mark the special + * case of a test test that unintentionally covers code. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Framework_UnintentionallyCoveredCodeError extends PHPUnit_Framework_RiskyTestError +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Framework_InvalidCoversTargetException extends PHPUnit_Framework_CodeCoverageException +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Returns a matcher that matches when the method it is evaluated for + * is executed zero or more times. + * + * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount + * @since Method available since Release 3.0.0 + */ +function any() +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::any', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsAnything matcher object. + * + * @return PHPUnit_Framework_Constraint_IsAnything + * @since Method available since Release 3.0.0 + */ +function anything() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::anything', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_ArrayHasKey matcher object. + * + * @param mixed $key + * @return PHPUnit_Framework_Constraint_ArrayHasKey + * @since Method available since Release 3.0.0 + */ +function arrayHasKey($key) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::arrayHasKey', + func_get_args() + ); +} + +/** + * Asserts that an array has a specified key. + * + * @param mixed $key + * @param array|ArrayAccess $array + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertArrayHasKey($key, $array, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertArrayHasKey', + func_get_args() + ); +} + +/** + * Asserts that an array has a specified subset. + * + * @param array|ArrayAccess $subset + * @param array|ArrayAccess $array + * @param boolean $strict Check for object identity + * @param string $message + * @since Method available since Release 4.4.0 + */ +function assertArraySubset($subset, $array, $strict = false, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertArraySubset', + func_get_args() + ); +} + +/** + * Asserts that an array does not have a specified key. + * + * @param mixed $key + * @param array|ArrayAccess $array + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertArrayNotHasKey($key, $array, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertArrayNotHasKey', + func_get_args() + ); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains a needle. + * + * @param mixed $needle + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 3.0.0 + */ +function assertAttributeContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeContains', + func_get_args() + ); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains only values of a given type. + * + * @param string $type + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ +function assertAttributeContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeContainsOnly', + func_get_args() + ); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param integer $expectedCount + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.6.0 + */ +function assertAttributeCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeCount', + func_get_args() + ); +} + +/** + * Asserts that a static attribute of a class or an attribute of an object + * is empty. + * + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertAttributeEmpty($haystackAttributeName, $haystackClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeEmpty', + func_get_args() + ); +} + +/** + * Asserts that a variable is equal to an attribute of an object. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + */ +function assertAttributeEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeEquals', + func_get_args() + ); +} + +/** + * Asserts that an attribute is greater than another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertAttributeGreaterThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeGreaterThan', + func_get_args() + ); +} + +/** + * Asserts that an attribute is greater than or equal to another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertAttributeGreaterThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeGreaterThanOrEqual', + func_get_args() + ); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertAttributeInstanceOf($expected, $attributeName, $classOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeInstanceOf', + func_get_args() + ); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertAttributeInternalType($expected, $attributeName, $classOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeInternalType', + func_get_args() + ); +} + +/** + * Asserts that an attribute is smaller than another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertAttributeLessThan($expected, $actualAttributeName, $actualClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeLessThan', + func_get_args() + ); +} + +/** + * Asserts that an attribute is smaller than or equal to another value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertAttributeLessThanOrEqual($expected, $actualAttributeName, $actualClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeLessThanOrEqual', + func_get_args() + ); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain a needle. + * + * @param mixed $needle + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 3.0.0 + */ +function assertAttributeNotContains($needle, $haystackAttributeName, $haystackClassOrObject, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotContains', + func_get_args() + ); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain only values of a given + * type. + * + * @param string $type + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ +function assertAttributeNotContainsOnly($type, $haystackAttributeName, $haystackClassOrObject, $isNativeType = null, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotContainsOnly', + func_get_args() + ); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param integer $expectedCount + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.6.0 + */ +function assertAttributeNotCount($expectedCount, $haystackAttributeName, $haystackClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotCount', + func_get_args() + ); +} + +/** + * Asserts that a static attribute of a class or an attribute of an object + * is not empty. + * + * @param string $haystackAttributeName + * @param mixed $haystackClassOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertAttributeNotEmpty($haystackAttributeName, $haystackClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotEmpty', + func_get_args() + ); +} + +/** + * Asserts that a variable is not equal to an attribute of an object. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param string $actualClassOrObject + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + */ +function assertAttributeNotEquals($expected, $actualAttributeName, $actualClassOrObject, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotEquals', + func_get_args() + ); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertAttributeNotInstanceOf($expected, $attributeName, $classOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotInstanceOf', + func_get_args() + ); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param string $expected + * @param string $attributeName + * @param mixed $classOrObject + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertAttributeNotInternalType($expected, $attributeName, $classOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotInternalType', + func_get_args() + ); +} + +/** + * Asserts that a variable and an attribute of an object do not have the + * same type and value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param object $actualClassOrObject + * @param string $message + */ +function assertAttributeNotSame($expected, $actualAttributeName, $actualClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeNotSame', + func_get_args() + ); +} + +/** + * Asserts that a variable and an attribute of an object have the same type + * and value. + * + * @param mixed $expected + * @param string $actualAttributeName + * @param object $actualClassOrObject + * @param string $message + */ +function assertAttributeSame($expected, $actualAttributeName, $actualClassOrObject, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertAttributeSame', + func_get_args() + ); +} + +/** + * Asserts that a class has a specified attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertClassHasAttribute($attributeName, $className, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertClassHasAttribute', + func_get_args() + ); +} + +/** + * Asserts that a class has a specified static attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertClassHasStaticAttribute($attributeName, $className, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertClassHasStaticAttribute', + func_get_args() + ); +} + +/** + * Asserts that a class does not have a specified attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertClassNotHasAttribute($attributeName, $className, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertClassNotHasAttribute', + func_get_args() + ); +} + +/** + * Asserts that a class does not have a specified static attribute. + * + * @param string $attributeName + * @param string $className + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertClassNotHasStaticAttribute($attributeName, $className, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertClassNotHasStaticAttribute', + func_get_args() + ); +} + +/** + * Asserts that a haystack contains a needle. + * + * @param mixed $needle + * @param mixed $haystack + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 2.1.0 + */ +function assertContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertContains', + func_get_args() + ); +} + +/** + * Asserts that a haystack contains only values of a given type. + * + * @param string $type + * @param mixed $haystack + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ +function assertContainsOnly($type, $haystack, $isNativeType = null, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertContainsOnly', + func_get_args() + ); +} + +/** + * Asserts that a haystack contains only instances of a given classname + * + * @param string $classname + * @param array|Traversable $haystack + * @param string $message + */ +function assertContainsOnlyInstancesOf($classname, $haystack, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertContainsOnlyInstancesOf', + func_get_args() + ); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param integer $expectedCount + * @param mixed $haystack + * @param string $message + */ +function assertCount($expectedCount, $haystack, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertCount', + func_get_args() + ); +} + +/** + * Asserts that a variable is empty. + * + * @param mixed $actual + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ +function assertEmpty($actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertEmpty', + func_get_args() + ); +} + +/** + * Asserts that a hierarchy of DOMElements matches. + * + * @param DOMElement $expectedElement + * @param DOMElement $actualElement + * @param boolean $checkAttributes + * @param string $message + * @author Mattis Stordalen Flister + * @since Method available since Release 3.3.0 + */ +function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, $checkAttributes = false, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertEqualXMLStructure', + func_get_args() + ); +} + +/** + * Asserts that two variables are equal. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + */ +function assertEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertEquals', + func_get_args() + ); +} + +/** + * Asserts that a condition is not true. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ +function assertNotTrue($condition, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotTrue', + func_get_args() + ); +} + +/** + * Asserts that a condition is false. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ +function assertFalse($condition, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertFalse', + func_get_args() + ); +} + +/** + * Asserts that the contents of one file is equal to the contents of another + * file. + * + * @param string $expected + * @param string $actual + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.2.14 + */ +function assertFileEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertFileEquals', + func_get_args() + ); +} + +/** + * Asserts that a file exists. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertFileExists($filename, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertFileExists', + func_get_args() + ); +} + +/** + * Asserts that the contents of one file is not equal to the contents of + * another file. + * + * @param string $expected + * @param string $actual + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.2.14 + */ +function assertFileNotEquals($expected, $actual, $message = '', $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertFileNotEquals', + func_get_args() + ); +} + +/** + * Asserts that a file does not exist. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertFileNotExists($filename, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertFileNotExists', + func_get_args() + ); +} + +/** + * Asserts that a value is greater than another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertGreaterThan($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertGreaterThan', + func_get_args() + ); +} + +/** + * Asserts that a value is greater than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertGreaterThanOrEqual($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertGreaterThanOrEqual', + func_get_args() + ); +} + +/** + * Asserts that a variable is of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertInstanceOf($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertInstanceOf', + func_get_args() + ); +} + +/** + * Asserts that a variable is of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertInternalType($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertInternalType', + func_get_args() + ); +} + +/** + * Asserts that a string is a valid JSON string. + * + * @param string $filename + * @param string $message + * @since Method available since Release 3.7.20 + */ +function assertJson($expectedJson, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJson', + func_get_args() + ); +} + +/** + * Asserts that two JSON files are equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + */ +function assertJsonFileEqualsJsonFile($expectedFile, $actualFile, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJsonFileEqualsJsonFile', + func_get_args() + ); +} + +/** + * Asserts that two JSON files are not equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + */ +function assertJsonFileNotEqualsJsonFile($expectedFile, $actualFile, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJsonFileNotEqualsJsonFile', + func_get_args() + ); +} + +/** + * Asserts that the generated JSON encoded object and the content of the given file are equal. + * + * @param string $expectedFile + * @param string $actualJson + * @param string $message + */ +function assertJsonStringEqualsJsonFile($expectedFile, $actualJson, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonFile', + func_get_args() + ); +} + +/** + * Asserts that two given JSON encoded objects or arrays are equal. + * + * @param string $expectedJson + * @param string $actualJson + * @param string $message + */ +function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJsonStringEqualsJsonString', + func_get_args() + ); +} + +/** + * Asserts that the generated JSON encoded object and the content of the given file are not equal. + * + * @param string $expectedFile + * @param string $actualJson + * @param string $message + */ +function assertJsonStringNotEqualsJsonFile($expectedFile, $actualJson, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonFile', + func_get_args() + ); +} + +/** + * Asserts that two given JSON encoded objects or arrays are not equal. + * + * @param string $expectedJson + * @param string $actualJson + * @param string $message + */ +function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertJsonStringNotEqualsJsonString', + func_get_args() + ); +} + +/** + * Asserts that a value is smaller than another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertLessThan($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertLessThan', + func_get_args() + ); +} + +/** + * Asserts that a value is smaller than or equal to another value. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertLessThanOrEqual($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertLessThanOrEqual', + func_get_args() + ); +} + +/** + * Asserts that a haystack does not contain a needle. + * + * @param mixed $needle + * @param mixed $haystack + * @param string $message + * @param boolean $ignoreCase + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @since Method available since Release 2.1.0 + */ +function assertNotContains($needle, $haystack, $message = '', $ignoreCase = false, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotContains', + func_get_args() + ); +} + +/** + * Asserts that a haystack does not contain only values of a given type. + * + * @param string $type + * @param mixed $haystack + * @param boolean $isNativeType + * @param string $message + * @since Method available since Release 3.1.4 + */ +function assertNotContainsOnly($type, $haystack, $isNativeType = null, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotContainsOnly', + func_get_args() + ); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param integer $expectedCount + * @param mixed $haystack + * @param string $message + */ +function assertNotCount($expectedCount, $haystack, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotCount', + func_get_args() + ); +} + +/** + * Asserts that a variable is not empty. + * + * @param mixed $actual + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ +function assertNotEmpty($actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotEmpty', + func_get_args() + ); +} + +/** + * Asserts that two variables are not equal. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 2.3.0 + */ +function assertNotEquals($expected, $actual, $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotEquals', + func_get_args() + ); +} + +/** + * Asserts that a variable is not of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertNotInstanceOf($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotInstanceOf', + func_get_args() + ); +} + +/** + * Asserts that a variable is not of a given type. + * + * @param string $expected + * @param mixed $actual + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertNotInternalType($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotInternalType', + func_get_args() + ); +} + +/** + * Asserts that a condition is not false. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ +function assertNotFalse($condition, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotFalse', + func_get_args() + ); +} + +/** + * Asserts that a variable is not null. + * + * @param mixed $actual + * @param string $message + */ +function assertNotNull($actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotNull', + func_get_args() + ); +} + +/** + * Asserts that a string does not match a given regular expression. + * + * @param string $pattern + * @param string $string + * @param string $message + * @since Method available since Release 2.1.0 + */ +function assertNotRegExp($pattern, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotRegExp', + func_get_args() + ); +} + +/** + * Asserts that two variables do not have the same type and value. + * Used on objects, it asserts that two variables do not reference + * the same object. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ +function assertNotSame($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotSame', + func_get_args() + ); +} + +/** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is not the same. + * + * @param array|Countable|Traversable $expected + * @param array|Countable|Traversable $actual + * @param string $message + */ +function assertNotSameSize($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotSameSize', + func_get_args() + ); +} + +/** + * This assertion is the exact opposite of assertTag(). + * + * Rather than asserting that $matcher results in a match, it asserts that + * $matcher does not match. + * + * @param array $matcher + * @param string $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ +function assertNotTag($matcher, $actual, $message = '', $isHtml = true) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNotTag', + func_get_args() + ); +} + +/** + * Asserts that a variable is null. + * + * @param mixed $actual + * @param string $message + */ +function assertNull($actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertNull', + func_get_args() + ); +} + +/** + * Asserts that an object has a specified attribute. + * + * @param string $attributeName + * @param object $object + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertObjectHasAttribute($attributeName, $object, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertObjectHasAttribute', + func_get_args() + ); +} + +/** + * Asserts that an object does not have a specified attribute. + * + * @param string $attributeName + * @param object $object + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertObjectNotHasAttribute($attributeName, $object, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertObjectNotHasAttribute', + func_get_args() + ); +} + +/** + * Asserts that a string matches a given regular expression. + * + * @param string $pattern + * @param string $string + * @param string $message + */ +function assertRegExp($pattern, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertRegExp', + func_get_args() + ); +} + +/** + * Asserts that two variables have the same type and value. + * Used on objects, it asserts that two variables reference + * the same object. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + */ +function assertSame($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertSame', + func_get_args() + ); +} + +/** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is the same. + * + * @param array|Countable|Traversable $expected + * @param array|Countable|Traversable $actual + * @param string $message + */ +function assertSameSize($expected, $actual, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertSameSize', + func_get_args() + ); +} + +/** + * Assert the presence, absence, or count of elements in a document matching + * the CSS $selector, regardless of the contents of those elements. + * + * The first argument, $selector, is the CSS selector used to match + * the elements in the $actual document. + * + * The second argument, $count, can be either boolean or numeric. + * When boolean, it asserts for presence of elements matching the selector + * (true) or absence of elements (false). + * When numeric, it asserts the count of elements. + * + * assertSelectCount("#binder", true, $xml); // any? + * assertSelectCount(".binder", 3, $xml); // exactly 3? + * + * @param array $selector + * @param integer $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ +function assertSelectCount($selector, $count, $actual, $message = '', $isHtml = true) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertSelectCount', + func_get_args() + ); +} + +/** + * assertSelectEquals("#binder .name", "Chuck", true, $xml); // any? + * assertSelectEquals("#binder .name", "Chuck", false, $xml); // none? + * + * @param array $selector + * @param string $content + * @param integer $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ +function assertSelectEquals($selector, $content, $count, $actual, $message = '', $isHtml = true) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertSelectEquals', + func_get_args() + ); +} + +/** + * assertSelectRegExp("#binder .name", "/Mike|Derek/", true, $xml); // any? + * assertSelectRegExp("#binder .name", "/Mike|Derek/", 3, $xml);// 3? + * + * @param array $selector + * @param string $pattern + * @param integer $count + * @param mixed $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ +function assertSelectRegExp($selector, $pattern, $count, $actual, $message = '', $isHtml = true) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertSelectRegExp', + func_get_args() + ); +} + +/** + * Asserts that a string ends not with a given prefix. + * + * @param string $suffix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ +function assertStringEndsNotWith($suffix, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringEndsNotWith', + func_get_args() + ); +} + +/** + * Asserts that a string ends with a given prefix. + * + * @param string $suffix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ +function assertStringEndsWith($suffix, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringEndsWith', + func_get_args() + ); +} + +/** + * Asserts that the contents of a string is equal + * to the contents of a file. + * + * @param string $expectedFile + * @param string $actualString + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.3.0 + */ +function assertStringEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringEqualsFile', + func_get_args() + ); +} + +/** + * Asserts that a string matches a given format string. + * + * @param string $format + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertStringMatchesFormat($format, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringMatchesFormat', + func_get_args() + ); +} + +/** + * Asserts that a string matches a given format file. + * + * @param string $formatFile + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertStringMatchesFormatFile($formatFile, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringMatchesFormatFile', + func_get_args() + ); +} + +/** + * Asserts that the contents of a string is not equal + * to the contents of a file. + * + * @param string $expectedFile + * @param string $actualString + * @param string $message + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @since Method available since Release 3.3.0 + */ +function assertStringNotEqualsFile($expectedFile, $actualString, $message = '', $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringNotEqualsFile', + func_get_args() + ); +} + +/** + * Asserts that a string does not match a given format string. + * + * @param string $format + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertStringNotMatchesFormat($format, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringNotMatchesFormat', + func_get_args() + ); +} + +/** + * Asserts that a string does not match a given format string. + * + * @param string $formatFile + * @param string $string + * @param string $message + * @since Method available since Release 3.5.0 + */ +function assertStringNotMatchesFormatFile($formatFile, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringNotMatchesFormatFile', + func_get_args() + ); +} + +/** + * Asserts that a string starts not with a given prefix. + * + * @param string $prefix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ +function assertStringStartsNotWith($prefix, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringStartsNotWith', + func_get_args() + ); +} + +/** + * Asserts that a string starts with a given prefix. + * + * @param string $prefix + * @param string $string + * @param string $message + * @since Method available since Release 3.4.0 + */ +function assertStringStartsWith($prefix, $string, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertStringStartsWith', + func_get_args() + ); +} + +/** + * Evaluate an HTML or XML string and assert its structure and/or contents. + * + * The first argument ($matcher) is an associative array that specifies the + * match criteria for the assertion: + * + * - `id` : the node with the given id attribute must match the + * corresponding value. + * - `tag` : the node type must match the corresponding value. + * - `attributes` : a hash. The node's attributes must match the + * corresponding values in the hash. + * - `content` : The text content must match the given value. + * - `parent` : a hash. The node's parent must match the + * corresponding hash. + * - `child`: a hash. At least one of the node's immediate children + * must meet the criteria described by the hash. + * - `ancestor` : a hash. At least one of the node's ancestors must + * meet the criteria described by the hash. + * - `descendant` : a hash. At least one of the node's descendants must + * meet the criteria described by the hash. + * - `children` : a hash, for counting children of a node. + * Accepts the keys: + *- `count`: a number which must equal the number of children + * that match + *- `less_than`: the number of matching children must be greater + * than this number + *- `greater_than` : the number of matching children must be less than + * this number + *- `only` : another hash consisting of the keys to use to match + * on the children, and only matching children will be + * counted + * + * + * // Matcher that asserts that there is an element with an id="my_id". + * $matcher = array('id' => 'my_id'); + * + * // Matcher that asserts that there is a "span" tag. + * $matcher = array('tag' => 'span'); + * + * // Matcher that asserts that there is a "span" tag with the content + * // "Hello World". + * $matcher = array('tag' => 'span', 'content' => 'Hello World'); + * + * // Matcher that asserts that there is a "span" tag with content matching + * // the regular expression pattern. + * $matcher = array('tag' => 'span', 'content' => 'regexp:/Try P(HP|ython)/'); + * + * // Matcher that asserts that there is a "span" with an "list" class + * // attribute. + * $matcher = array( + * 'tag'=> 'span', + * 'attributes' => array('class' => 'list') + * ); + * + * // Matcher that asserts that there is a "span" inside of a "div". + * $matcher = array( + * 'tag'=> 'span', + * 'parent' => array('tag' => 'div') + * ); + * + * // Matcher that asserts that there is a "span" somewhere inside a + * // "table". + * $matcher = array( + * 'tag' => 'span', + * 'ancestor' => array('tag' => 'table') + * ); + * + * // Matcher that asserts that there is a "span" with at least one "em" + * // child. + * $matcher = array( + * 'tag' => 'span', + * 'child' => array('tag' => 'em') + * ); + * + * // Matcher that asserts that there is a "span" containing a (possibly + * // nested) "strong" tag. + * $matcher = array( + * 'tag'=> 'span', + * 'descendant' => array('tag' => 'strong') + * ); + * + * // Matcher that asserts that there is a "span" containing 5-10 "em" tags + * // as immediate children. + * $matcher = array( + * 'tag' => 'span', + * 'children' => array( + * 'less_than'=> 11, + * 'greater_than' => 4, + * 'only' => array('tag' => 'em') + * ) + * ); + * + * // Matcher that asserts that there is a "div", with an "ul" ancestor and + * // a "li" parent (with class="enum"), and containing a "span" descendant + * // that contains an element with id="my_test" and the text "Hello World". + * $matcher = array( + * 'tag'=> 'div', + * 'ancestor' => array('tag' => 'ul'), + * 'parent' => array( + * 'tag'=> 'li', + * 'attributes' => array('class' => 'enum') + * ), + * 'descendant' => array( + * 'tag' => 'span', + * 'child' => array( + * 'id' => 'my_test', + * 'content' => 'Hello World' + * ) + * ) + * ); + * + * // Use assertTag() to apply a $matcher to a piece of $html. + * $this->assertTag($matcher, $html); + * + * // Use assertTag() to apply a $matcher to a piece of $xml. + * $this->assertTag($matcher, $xml, '', false); + * + * + * The second argument ($actual) is a string containing either HTML or + * XML text to be tested. + * + * The third argument ($message) is an optional message that will be + * used if the assertion fails. + * + * The fourth argument ($html) is an optional flag specifying whether + * to load the $actual string into a DOMDocument using the HTML or + * XML load strategy. It is true by default, which assumes the HTML + * load strategy. In many cases, this will be acceptable for XML as well. + * + * @param array $matcher + * @param string $actual + * @param string $message + * @param boolean $isHtml + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ +function assertTag($matcher, $actual, $message = '', $isHtml = true) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertTag', + func_get_args() + ); +} + +/** + * Evaluates a PHPUnit_Framework_Constraint matcher object. + * + * @param mixed$value + * @param PHPUnit_Framework_Constraint $constraint + * @param string $message + * @since Method available since Release 3.0.0 + */ +function assertThat($value, PHPUnit_Framework_Constraint $constraint, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertThat', + func_get_args() + ); +} + +/** + * Asserts that a condition is true. + * + * @param boolean $condition + * @param string $message + * @throws PHPUnit_Framework_AssertionFailedError + */ +function assertTrue($condition, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertTrue', + func_get_args() + ); +} + +/** + * Asserts that two XML files are equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertXmlFileEqualsXmlFile($expectedFile, $actualFile, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertXmlFileEqualsXmlFile', + func_get_args() + ); +} + +/** + * Asserts that two XML files are not equal. + * + * @param string $expectedFile + * @param string $actualFile + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertXmlFileNotEqualsXmlFile($expectedFile, $actualFile, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertXmlFileNotEqualsXmlFile', + func_get_args() + ); +} + +/** + * Asserts that two XML documents are equal. + * + * @param string $expectedFile + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.3.0 + */ +function assertXmlStringEqualsXmlFile($expectedFile, $actualXml, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlFile', + func_get_args() + ); +} + +/** + * Asserts that two XML documents are equal. + * + * @param string $expectedXml + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertXmlStringEqualsXmlString', + func_get_args() + ); +} + +/** + * Asserts that two XML documents are not equal. + * + * @param string $expectedFile + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.3.0 + */ +function assertXmlStringNotEqualsXmlFile($expectedFile, $actualXml, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlFile', + func_get_args() + ); +} + +/** + * Asserts that two XML documents are not equal. + * + * @param string $expectedXml + * @param string $actualXml + * @param string $message + * @since Method available since Release 3.1.0 + */ +function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, $message = '') +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::assertXmlStringNotEqualsXmlString', + func_get_args() + ); +} + +/** + * Returns a matcher that matches when the method it is evaluated for + * is invoked at the given $index. + * + * @param integer $index + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex + * @since Method available since Release 3.0.0 + */ +function at($index) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::at', + func_get_args() + ); +} + +/** + * Returns a matcher that matches when the method it is evaluated for + * is executed at least once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce + * @since Method available since Release 3.0.0 + */ +function atLeastOnce() +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::atLeastOnce', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Attribute matcher object. + * + * @param PHPUnit_Framework_Constraint $constraint + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_Attribute + * @since Method available since Release 3.1.0 + */ +function attribute(PHPUnit_Framework_Constraint $constraint, $attributeName) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::attribute', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object + * that is wrapped in a PHPUnit_Framework_Constraint_Attribute matcher + * object. + * + * @param string $attributeName + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @return PHPUnit_Framework_Constraint_Attribute + * @since Method available since Release 3.1.0 + */ +function attributeEqualTo($attributeName, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::attributeEqualTo', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Callback matcher object. + * + * @param callable $callback + * @return PHPUnit_Framework_Constraint_Callback + */ +function callback($callback) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::callback', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_ClassHasAttribute matcher object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ClassHasAttribute + * @since Method available since Release 3.1.0 + */ +function classHasAttribute($attributeName) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::classHasAttribute', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_ClassHasStaticAttribute matcher + * object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ClassHasStaticAttribute + * @since Method available since Release 3.1.0 + */ +function classHasStaticAttribute($attributeName) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::classHasStaticAttribute', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_TraversableContains matcher + * object. + * + * @param mixed $value + * @param boolean $checkForObjectIdentity + * @param boolean $checkForNonObjectIdentity + * @return PHPUnit_Framework_Constraint_TraversableContains + * @since Method available since Release 3.0.0 + */ +function contains($value, $checkForObjectIdentity = true, $checkForNonObjectIdentity = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::contains', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher + * object. + * + * @param string $type + * @return PHPUnit_Framework_Constraint_TraversableContainsOnly + * @since Method available since Release 3.1.4 + */ +function containsOnly($type) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::containsOnly', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_TraversableContainsOnly matcher + * object. + * + * @param string $classname + * @return PHPUnit_Framework_Constraint_TraversableContainsOnly + */ +function containsOnlyInstancesOf($classname) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::containsOnlyInstancesOf', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsEqual matcher object. + * + * @param mixed $value + * @param float $delta + * @param integer $maxDepth + * @param boolean $canonicalize + * @param boolean $ignoreCase + * @return PHPUnit_Framework_Constraint_IsEqual + * @since Method available since Release 3.0.0 + */ +function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::equalTo', + func_get_args() + ); +} + +/** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly $count times. + * + * @param integer $count + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ +function exactly($count) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::exactly', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_FileExists matcher object. + * + * @return PHPUnit_Framework_Constraint_FileExists + * @since Method available since Release 3.0.0 + */ +function fileExists() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::fileExists', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_GreaterThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_GreaterThan + * @since Method available since Release 3.0.0 + */ +function greaterThan($value) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::greaterThan', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps + * a PHPUnit_Framework_Constraint_IsEqual and a + * PHPUnit_Framework_Constraint_GreaterThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.1.0 + */ +function greaterThanOrEqual($value) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::greaterThanOrEqual', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsIdentical matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_IsIdentical + * @since Method available since Release 3.0.0 + */ +function identicalTo($value) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::identicalTo', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsEmpty matcher object. + * + * @return PHPUnit_Framework_Constraint_IsEmpty + * @since Method available since Release 3.5.0 + */ +function isEmpty() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isEmpty', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsFalse matcher object. + * + * @return PHPUnit_Framework_Constraint_IsFalse + * @since Method available since Release 3.3.0 + */ +function isFalse() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isFalse', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsInstanceOf matcher object. + * + * @param string $className + * @return PHPUnit_Framework_Constraint_IsInstanceOf + * @since Method available since Release 3.0.0 + */ +function isInstanceOf($className) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isInstanceOf', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsJson matcher object. + * + * @return PHPUnit_Framework_Constraint_IsJson + * @since Method available since Release 3.7.20 + */ +function isJson() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isJson', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsNull matcher object. + * + * @return PHPUnit_Framework_Constraint_IsNull + * @since Method available since Release 3.3.0 + */ +function isNull() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isNull', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsTrue matcher object. + * + * @return PHPUnit_Framework_Constraint_IsTrue + * @since Method available since Release 3.3.0 + */ +function isTrue() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isTrue', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_IsType matcher object. + * + * @param string $type + * @return PHPUnit_Framework_Constraint_IsType + * @since Method available since Release 3.0.0 + */ +function isType($type) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::isType', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_LessThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_LessThan + * @since Method available since Release 3.0.0 + */ +function lessThan($value) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::lessThan', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Or matcher object that wraps + * a PHPUnit_Framework_Constraint_IsEqual and a + * PHPUnit_Framework_Constraint_LessThan matcher object. + * + * @param mixed $value + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.1.0 + */ +function lessThanOrEqual($value) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::lessThanOrEqual', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_And matcher object. + * + * @return PHPUnit_Framework_Constraint_And + * @since Method available since Release 3.0.0 + */ +function logicalAnd() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::logicalAnd', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Not matcher object. + * + * @param PHPUnit_Framework_Constraint $constraint + * @return PHPUnit_Framework_Constraint_Not + * @since Method available since Release 3.0.0 + */ +function logicalNot(PHPUnit_Framework_Constraint $constraint) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::logicalNot', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Or matcher object. + * + * @return PHPUnit_Framework_Constraint_Or + * @since Method available since Release 3.0.0 + */ +function logicalOr() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::logicalOr', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_Xor matcher object. + * + * @return PHPUnit_Framework_Constraint_Xor + * @since Method available since Release 3.0.0 + */ +function logicalXor() +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::logicalXor', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_StringMatches matcher object. + * + * @param string $string + * @return PHPUnit_Framework_Constraint_StringMatches + * @since Method available since Release 3.5.0 + */ +function matches($string) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::matches', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_PCREMatch matcher object. + * + * @param string $pattern + * @return PHPUnit_Framework_Constraint_PCREMatch + * @since Method available since Release 3.0.0 + */ +function matchesRegularExpression($pattern) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::matchesRegularExpression', + func_get_args() + ); +} + +/** + * Returns a matcher that matches when the method it is evaluated for + * is never executed. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ +function never() +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::never', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_ObjectHasAttribute matcher object. + * + * @param string $attributeName + * @return PHPUnit_Framework_Constraint_ObjectHasAttribute + * @since Method available since Release 3.0.0 + */ +function objectHasAttribute($attributeName) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::objectHasAttribute', + func_get_args() + ); +} + +/** + * @param mixed $value, ... + * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls + * @since Method available since Release 3.0.0 + */ +function onConsecutiveCalls() +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::onConsecutiveCalls', + func_get_args() + ); +} + +/** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ +function once() +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::once', + func_get_args() + ); +} + +/** + * + * + * @param integer $argumentIndex + * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument + * @since Method available since Release 3.3.0 + */ +function returnArgument($argumentIndex) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::returnArgument', + func_get_args() + ); +} + +/** + * + * + * @param mixed $callback + * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback + * @since Method available since Release 3.3.0 + */ +function returnCallback($callback) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::returnCallback', + func_get_args() + ); +} + +/** + * Returns the current object. + * + * This method is useful when mocking a fluent interface. + * + * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf + * @since Method available since Release 3.6.0 + */ +function returnSelf() +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::returnSelf', + func_get_args() + ); +} + +/** + * + * + * @param mixed $value + * @return PHPUnit_Framework_MockObject_Stub_Return + * @since Method available since Release 3.0.0 + */ +function returnValue($value) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::returnValue', + func_get_args() + ); +} + +/** + * + * + * @param array $valueMap + * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap + * @since Method available since Release 3.6.0 + */ +function returnValueMap(array $valueMap) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::returnValueMap', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_StringContains matcher object. + * + * @param string $string + * @param boolean $case + * @return PHPUnit_Framework_Constraint_StringContains + * @since Method available since Release 3.0.0 + */ +function stringContains($string, $case = true) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::stringContains', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_StringEndsWith matcher object. + * + * @param mixed $suffix + * @return PHPUnit_Framework_Constraint_StringEndsWith + * @since Method available since Release 3.4.0 + */ +function stringEndsWith($suffix) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::stringEndsWith', + func_get_args() + ); +} + +/** + * Returns a PHPUnit_Framework_Constraint_StringStartsWith matcher object. + * + * @param mixed $prefix + * @return PHPUnit_Framework_Constraint_StringStartsWith + * @since Method available since Release 3.4.0 + */ +function stringStartsWith($prefix) +{ + return call_user_func_array( + 'PHPUnit_Framework_Assert::stringStartsWith', + func_get_args() + ); +} + +/** + * + * + * @param Exception $exception + * @return PHPUnit_Framework_MockObject_Stub_Exception + * @since Method available since Release 3.1.0 + */ +function throwException(Exception $exception) +{ + return call_user_func_array( + 'PHPUnit_Framework_TestCase::throwException', + func_get_args() + ); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A marker interface for marking any exception/error as result of an unit + * test as incomplete implementation or currently not implemented. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Framework_IncompleteTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Exporter\Exporter; + +/** + * Abstract base class for constraints. which are placed upon any value. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @author Bernhard Schussek + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +abstract class PHPUnit_Framework_Constraint implements Countable, PHPUnit_Framework_SelfDescribing +{ + protected $exporter; + + public function __construct() + { + $this->exporter = new Exporter; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @param mixed $other Value or object to evaluate. + * @param string $description Additional information about the test + * @param bool $returnResult Whether to return a result or throw an exception + * @return mixed + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function evaluate($other, $description = '', $returnResult = false) + { + $success = false; + + if ($this->matches($other)) { + $success = true; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * This method can be overridden to implement the evaluation algorithm. + * + * @param mixed $other Value or object to evaluate. + * @return bool + */ + protected function matches($other) + { + return false; + } + + /** + * Counts the number of constraint elements. + * + * @return integer + * @since Method available since Release 3.4.0 + */ + public function count() + { + return 1; + } + + /** + * Throws an exception for the given compared value and test description + * + * @param mixed $other Evaluated value or object. + * @param string $description Additional information about the test + * @param SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure + * @throws PHPUnit_Framework_ExpectationFailedException + */ + protected function fail($other, $description, SebastianBergmann\Comparator\ComparisonFailure $comparisonFailure = null) + { + $failureDescription = sprintf( + 'Failed asserting that %s.', + $this->failureDescription($other) + ); + + $additionalFailureDescription = $this->additionalFailureDescription($other); + + if ($additionalFailureDescription) { + $failureDescription .= "\n" . $additionalFailureDescription; + } + + if (!empty($description)) { + $failureDescription = $description . "\n" . $failureDescription; + } + + throw new PHPUnit_Framework_ExpectationFailedException( + $failureDescription, + $comparisonFailure + ); + } + + /** + * Return additional failure description where needed + * + * The function can be overridden to provide additional failure + * information like a diff + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function additionalFailureDescription($other) + { + return ''; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * To provide additional failure information additionalFailureDescription + * can be used. + * + * @param mixed $other Evaluated value or object. + * @return string + */ + protected function failureDescription($other) + { + return $this->exporter->export($other) . ' ' . $this->toString(); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Framework_TestSuite + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Framework_TestSuite_DataProvider extends PHPUnit_Framework_TestSuite +{ + /** + * Sets the dependencies of a TestCase. + * + * @param array $dependencies + */ + public function setDependencies(array $dependencies) + { + foreach ($this->tests as $test) { + $test->setDependencies($dependencies); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A Listener for test progress. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 2.0.0 + */ +interface PHPUnit_Framework_TestListener +{ + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time); + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time); + + /** + * A test suite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite); + + /** + * A test suite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite); + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test); + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time); +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A marker interface for marking a unit test as being skipped. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Interface available since Release 3.0.0 + */ +interface PHPUnit_Framework_SkippedTest +{ +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A warning. + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Framework_Warning extends PHPUnit_Framework_TestCase +{ + /** + * @var string + */ + protected $message = ''; + + /** + * @var boolean + */ + protected $backupGlobals = false; + + /** + * @var boolean + */ + protected $backupStaticAttributes = false; + + /** + * @var boolean + */ + protected $runTestInSeparateProcess = false; + + /** + * @var boolean + */ + protected $useErrorHandler = false; + + /** + * @param string $message + */ + public function __construct($message = '') + { + $this->message = $message; + parent::__construct('Warning'); + } + + /** + * @throws PHPUnit_Framework_Exception + */ + protected function runTest() + { + $this->fail($this->message); + } + + /** + * @return string + * @since Method available since Release 3.0.0 + */ + public function getMessage() + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + * + * @return string + * @since Method available since Release 3.4.0 + */ + public function toString() + { + return 'Warning'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\GlobalState\Snapshot; +use SebastianBergmann\GlobalState\Restorer; +use SebastianBergmann\GlobalState\Blacklist; +use SebastianBergmann\RecursionContext\Context; +use SebastianBergmann\Exporter\Exporter; + +/** + * A TestCase defines the fixture to run multiple tests. + * + * To define a TestCase + * + * 1) Implement a subclass of PHPUnit_Framework_TestCase. + * 2) Define instance variables that store the state of the fixture. + * 3) Initialize the fixture state by overriding setUp(). + * 4) Clean-up after a test by overriding tearDown(). + * + * Each test runs in its own fixture so there can be no side effects + * among test runs. + * + * Here is an example: + * + * + * value1 = 2; + * $this->value2 = 3; + * } + * } + * ?> + * + * + * For each test implement a method which interacts with the fixture. + * Verify the expected results with assertions specified by calling + * assert with a boolean. + * + * + * assertTrue($this->value1 + $this->value2 == 5); + * } + * ?> + * + * + * @package PHPUnit + * @subpackage Framework + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +abstract class PHPUnit_Framework_TestCase extends PHPUnit_Framework_Assert implements PHPUnit_Framework_Test, PHPUnit_Framework_SelfDescribing +{ + /** + * Enable or disable the backup and restoration of the $GLOBALS array. + * Overwrite this attribute in a child class of TestCase. + * Setting this attribute in setUp() has no effect! + * + * @var boolean + */ + protected $backupGlobals = null; + + /** + * @var array + */ + protected $backupGlobalsBlacklist = array(); + + /** + * Enable or disable the backup and restoration of static attributes. + * Overwrite this attribute in a child class of TestCase. + * Setting this attribute in setUp() has no effect! + * + * @var boolean + */ + protected $backupStaticAttributes = null; + + /** + * @var array + */ + protected $backupStaticAttributesBlacklist = array(); + + /** + * Whether or not this test is to be run in a separate PHP process. + * + * @var boolean + */ + protected $runTestInSeparateProcess = null; + + /** + * Whether or not this test should preserve the global state when + * running in a separate PHP process. + * + * @var boolean + */ + protected $preserveGlobalState = true; + + /** + * Whether or not this test is running in a separate PHP process. + * + * @var boolean + */ + private $inIsolation = false; + + /** + * @var array + */ + private $data = array(); + + /** + * @var string + */ + private $dataName = ''; + + /** + * @var boolean + */ + private $useErrorHandler = null; + + /** + * The name of the expected Exception. + * + * @var mixed + */ + private $expectedException = null; + + /** + * The message of the expected Exception. + * + * @var string + */ + private $expectedExceptionMessage = ''; + + /** + * The regex pattern to validate the expected Exception message. + * + * @var string + */ + private $expectedExceptionMessageRegExp = ''; + + /** + * The code of the expected Exception. + * + * @var integer + */ + private $expectedExceptionCode; + + /** + * The name of the test case. + * + * @var string + */ + private $name = null; + + /** + * @var array + */ + private $dependencies = array(); + + /** + * @var array + */ + private $dependencyInput = array(); + + /** + * @var array + */ + private $iniSettings = array(); + + /** + * @var array + */ + private $locale = array(); + + /** + * @var array + */ + private $mockObjects = array(); + + /** + * @var array + */ + private $mockObjectGenerator = null; + + /** + * @var integer + */ + private $status; + + /** + * @var string + */ + private $statusMessage = ''; + + /** + * @var integer + */ + private $numAssertions = 0; + + /** + * @var PHPUnit_Framework_TestResult + */ + private $result; + + /** + * @var mixed + */ + private $testResult; + + /** + * @var string + */ + private $output = ''; + + /** + * @var string + */ + private $outputExpectedRegex = null; + + /** + * @var string + */ + private $outputExpectedString = null; + + /** + * @var mixed + */ + private $outputCallback = false; + + /** + * @var boolean + */ + private $outputBufferingActive = false; + + /** + * @var integer + */ + private $outputBufferingLevel; + + /** + * @var SebastianBergmann\GlobalState\Snapshot + */ + private $snapshot; + + /** + * Constructs a test case with the given name. + * + * @param string $name + * @param array $data + * @param string $dataName + */ + public function __construct($name = null, array $data = array(), $dataName = '') + { + if ($name !== null) { + $this->setName($name); + } + + $this->data = $data; + $this->dataName = $dataName; + } + + /** + * Returns a string representation of the test case. + * + * @return string + */ + public function toString() + { + $class = new ReflectionClass($this); + + $buffer = sprintf( + '%s::%s', + $class->name, + $this->getName(false) + ); + + return $buffer . $this->getDataSetAsString(); + } + + /** + * Counts the number of test cases executed by run(TestResult result). + * + * @return integer + */ + public function count() + { + return 1; + } + + /** + * Returns the annotations for this test. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function getAnnotations() + { + return PHPUnit_Util_Test::parseTestMethodAnnotations( + get_class($this), + $this->name + ); + } + + /** + * Gets the name of a TestCase. + * + * @param boolean $withDataSet + * @return string + */ + public function getName($withDataSet = true) + { + if ($withDataSet) { + return $this->name . $this->getDataSetAsString(false); + } else { + return $this->name; + } + } + + /** + * Returns the size of the test. + * + * @return integer + * @since Method available since Release 3.6.0 + */ + public function getSize() + { + return PHPUnit_Util_Test::getSize( + get_class($this), + $this->getName(false) + ); + } + + /** + * @return string + * @since Method available since Release 3.6.0 + */ + public function getActualOutput() + { + if (!$this->outputBufferingActive) { + return $this->output; + } else { + return ob_get_contents(); + } + } + + /** + * @return boolean + * @since Method available since Release 3.6.0 + */ + public function hasOutput() + { + if (strlen($this->output) === 0) { + return false; + } + + if ($this->hasExpectationOnOutput()) { + return false; + } + + return true; + } + + /** + * @param string $expectedRegex + * @since Method available since Release 3.6.0 + * @throws PHPUnit_Framework_Exception + */ + public function expectOutputRegex($expectedRegex) + { + if ($this->outputExpectedString !== null) { + throw new PHPUnit_Framework_Exception; + } + + if (is_string($expectedRegex) || is_null($expectedRegex)) { + $this->outputExpectedRegex = $expectedRegex; + } + } + + /** + * @param string $expectedString + * @since Method available since Release 3.6.0 + */ + public function expectOutputString($expectedString) + { + if ($this->outputExpectedRegex !== null) { + throw new PHPUnit_Framework_Exception; + } + + if (is_string($expectedString) || is_null($expectedString)) { + $this->outputExpectedString = $expectedString; + } + } + + /** + * @return bool + * @since Method available since Release 3.6.5 + * @deprecated + */ + public function hasPerformedExpectationsOnOutput() + { + return $this->hasExpectationOnOutput(); + } + + /** + * @return bool + * @since Method available since Release 4.3.3 + */ + public function hasExpectationOnOutput() + { + return is_string($this->outputExpectedString) || is_string($this->outputExpectedRegex); + } + + /** + * @return string + * @since Method available since Release 3.2.0 + */ + public function getExpectedException() + { + return $this->expectedException; + } + + /** + * @param mixed $exceptionName + * @param string $exceptionMessage + * @param integer $exceptionCode + * @since Method available since Release 3.2.0 + */ + public function setExpectedException($exceptionName, $exceptionMessage = '', $exceptionCode = null) + { + $this->expectedException = $exceptionName; + $this->expectedExceptionMessage = $exceptionMessage; + $this->expectedExceptionCode = $exceptionCode; + } + + /** + * @param mixed $exceptionName + * @param string $exceptionMessageRegExp + * @param integer $exceptionCode + * @since Method available since Release 4.3.0 + */ + public function setExpectedExceptionRegExp($exceptionName, $exceptionMessageRegExp = '', $exceptionCode = null) + { + $this->expectedException = $exceptionName; + $this->expectedExceptionMessageRegExp = $exceptionMessageRegExp; + $this->expectedExceptionCode = $exceptionCode; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setExpectedExceptionFromAnnotation() + { + try { + $expectedException = PHPUnit_Util_Test::getExpectedException( + get_class($this), + $this->name + ); + + if ($expectedException !== false) { + $this->setExpectedException( + $expectedException['class'], + $expectedException['message'], + $expectedException['code'] + ); + + if (!empty($expectedException['message_regex'])) { + $this->setExpectedExceptionRegExp( + $expectedException['class'], + $expectedException['message_regex'], + $expectedException['code'] + ); + } + } + } catch (ReflectionException $e) { + } + } + + /** + * @param boolean $useErrorHandler + * @since Method available since Release 3.4.0 + */ + public function setUseErrorHandler($useErrorHandler) + { + $this->useErrorHandler = $useErrorHandler; + } + + /** + * @since Method available since Release 3.4.0 + */ + protected function setUseErrorHandlerFromAnnotation() + { + try { + $useErrorHandler = PHPUnit_Util_Test::getErrorHandlerSettings( + get_class($this), + $this->name + ); + + if ($useErrorHandler !== null) { + $this->setUseErrorHandler($useErrorHandler); + } + } catch (ReflectionException $e) { + } + } + + /** + * @since Method available since Release 3.6.0 + */ + protected function checkRequirements() + { + if (!$this->name || !method_exists($this, $this->name)) { + return; + } + + $missingRequirements = PHPUnit_Util_Test::getMissingRequirements( + get_class($this), + $this->name + ); + + if ($missingRequirements) { + $this->markTestSkipped(implode(PHP_EOL, $missingRequirements)); + } + } + + /** + * Returns the status of this test. + * + * @return integer + * @since Method available since Release 3.1.0 + */ + public function getStatus() + { + return $this->status; + } + + /** + * Returns the status message of this test. + * + * @return string + * @since Method available since Release 3.3.0 + */ + public function getStatusMessage() + { + return $this->statusMessage; + } + + /** + * Returns whether or not this test has failed. + * + * @return boolean + * @since Method available since Release 3.0.0 + */ + public function hasFailed() + { + $status = $this->getStatus(); + + return $status == PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE || + $status == PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + } + + /** + * Runs the test case and collects the results in a TestResult object. + * If no TestResult object is passed a new one will be created. + * + * @param PHPUnit_Framework_TestResult $result + * @return PHPUnit_Framework_TestResult + * @throws PHPUnit_Framework_Exception + */ + public function run(PHPUnit_Framework_TestResult $result = null) + { + if ($result === null) { + $result = $this->createResult(); + } + + if (!$this instanceof PHPUnit_Framework_Warning) { + $this->setTestResultObject($result); + $this->setUseErrorHandlerFromAnnotation(); + } + + if ($this->useErrorHandler !== null) { + $oldErrorHandlerSetting = $result->getConvertErrorsToExceptions(); + $result->convertErrorsToExceptions($this->useErrorHandler); + } + + if (!$this instanceof PHPUnit_Framework_Warning && !$this->handleDependencies()) { + return; + } + + if ($this->runTestInSeparateProcess === true && + $this->inIsolation !== true && + !$this instanceof PHPUnit_Extensions_SeleniumTestCase && + !$this instanceof PHPUnit_Extensions_PhptTestCase) { + $class = new ReflectionClass($this); + + $template = new Text_Template( + __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl' + ); + + if ($this->preserveGlobalState) { + $constants = PHPUnit_Util_GlobalState::getConstantsAsString(); + $globals = PHPUnit_Util_GlobalState::getGlobalsAsString(); + $includedFiles = PHPUnit_Util_GlobalState::getIncludedFilesAsString(); + $iniSettings = PHPUnit_Util_GlobalState::getIniSettingsAsString(); + } else { + $constants = ''; + if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n"; + } else { + $globals = ''; + } + $includedFiles = ''; + $iniSettings = ''; + } + + $coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false'; + $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false'; + $isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false'; + $isStrictAboutTestSize = $result->isStrictAboutTestSize() ? 'true' : 'false'; + $isStrictAboutTodoAnnotatedTests = $result->isStrictAboutTodoAnnotatedTests() ? 'true' : 'false'; + + if (defined('PHPUNIT_COMPOSER_INSTALL')) { + $composerAutoload = var_export(PHPUNIT_COMPOSER_INSTALL, true); + } else { + $composerAutoload = '\'\''; + } + + if (defined('__PHPUNIT_PHAR__')) { + $phar = var_export(__PHPUNIT_PHAR__, true); + } else { + $phar = '\'\''; + } + + $data = var_export(serialize($this->data), true); + $dataName = var_export($this->dataName, true); + $dependencyInput = var_export(serialize($this->dependencyInput), true); + $includePath = var_export(get_include_path(), true); + // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC + // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences + $data = "'." . $data . ".'"; + $dataName = "'.(" . $dataName . ").'"; + $dependencyInput = "'." . $dependencyInput . ".'"; + $includePath = "'." . $includePath . ".'"; + + $template->setVar( + array( + 'composerAutoload' => $composerAutoload, + 'phar' => $phar, + 'filename' => $class->getFileName(), + 'className' => $class->getName(), + 'methodName' => $this->name, + 'collectCodeCoverageInformation' => $coverage, + 'data' => $data, + 'dataName' => $dataName, + 'dependencyInput' => $dependencyInput, + 'constants' => $constants, + 'globals' => $globals, + 'include_path' => $includePath, + 'included_files' => $includedFiles, + 'iniSettings' => $iniSettings, + 'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything, + 'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests, + 'isStrictAboutTestSize' => $isStrictAboutTestSize, + 'isStrictAboutTodoAnnotatedTests' => $isStrictAboutTodoAnnotatedTests + ) + ); + + $this->prepareTemplate($template); + + $php = PHPUnit_Util_PHP::factory(); + $php->runTestJob($template->render(), $this, $result); + } else { + $result->run($this); + } + + if ($this->useErrorHandler !== null) { + $result->convertErrorsToExceptions($oldErrorHandlerSetting); + } + + $this->result = null; + + return $result; + } + + /** + * Runs the bare test sequence. + */ + public function runBare() + { + $this->numAssertions = 0; + + $this->snapshotGlobalState(); + $this->startOutputBuffering(); + clearstatcache(); + $currentWorkingDirectory = getcwd(); + + $hookMethods = PHPUnit_Util_Test::getHookMethods(get_class($this)); + + try { + $hasMetRequirements = false; + $this->checkRequirements(); + $hasMetRequirements = true; + + if ($this->inIsolation) { + foreach ($hookMethods['beforeClass'] as $method) { + $this->$method(); + } + } + + $this->setExpectedExceptionFromAnnotation(); + + foreach ($hookMethods['before'] as $method) { + $this->$method(); + } + + $this->assertPreConditions(); + $this->testResult = $this->runTest(); + $this->verifyMockObjects(); + $this->assertPostConditions(); + + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED; + } catch (PHPUnit_Framework_IncompleteTest $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE; + $this->statusMessage = $e->getMessage(); + } catch (PHPUnit_Framework_SkippedTest $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED; + $this->statusMessage = $e->getMessage(); + } catch (PHPUnit_Framework_AssertionFailedError $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE; + $this->statusMessage = $e->getMessage(); + } catch (Exception $e) { + $this->status = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + $this->statusMessage = $e->getMessage(); + } + + // Clean up the mock objects. + $this->mockObjects = array(); + + // Tear down the fixture. An exception raised in tearDown() will be + // caught and passed on when no exception was raised before. + try { + if ($hasMetRequirements) { + foreach ($hookMethods['after'] as $method) { + $this->$method(); + } + + if ($this->inIsolation) { + foreach ($hookMethods['afterClass'] as $method) { + $this->$method(); + } + } + } + } catch (Exception $_e) { + if (!isset($e)) { + $e = $_e; + } + } + + try { + $this->stopOutputBuffering(); + } catch (PHPUnit_Framework_RiskyTestError $_e) { + if (!isset($e)) { + $e = $_e; + } + } + + clearstatcache(); + + if ($currentWorkingDirectory != getcwd()) { + chdir($currentWorkingDirectory); + } + + $this->restoreGlobalState(); + + // Clean up INI settings. + foreach ($this->iniSettings as $varName => $oldValue) { + ini_set($varName, $oldValue); + } + + $this->iniSettings = array(); + + // Clean up locale settings. + foreach ($this->locale as $category => $locale) { + setlocale($category, $locale); + } + + // Perform assertion on output. + if (!isset($e)) { + try { + if ($this->outputExpectedRegex !== null) { + $this->assertRegExp($this->outputExpectedRegex, $this->output); + } elseif ($this->outputExpectedString !== null) { + $this->assertEquals($this->outputExpectedString, $this->output); + } + } catch (Exception $_e) { + $e = $_e; + } + } + + // Workaround for missing "finally". + if (isset($e)) { + $this->onNotSuccessfulTest($e); + } + } + + /** + * Override to run the test and assert its state. + * + * @return mixed + * @throws Exception|PHPUnit_Framework_Exception + * @throws PHPUnit_Framework_Exception + */ + protected function runTest() + { + if ($this->name === null) { + throw new PHPUnit_Framework_Exception( + 'PHPUnit_Framework_TestCase::$name must not be null.' + ); + } + + try { + $class = new ReflectionClass($this); + $method = $class->getMethod($this->name); + } catch (ReflectionException $e) { + $this->fail($e->getMessage()); + } + + try { + $testResult = $method->invokeArgs( + $this, + array_merge($this->data, $this->dependencyInput) + ); + } catch (Exception $e) { + $checkException = false; + + if (is_string($this->expectedException)) { + $checkException = true; + + if ($e instanceof PHPUnit_Framework_Exception) { + $checkException = false; + } + + $reflector = new ReflectionClass($this->expectedException); + + if ($this->expectedException == 'PHPUnit_Framework_Exception' || + $reflector->isSubclassOf('PHPUnit_Framework_Exception')) { + $checkException = true; + } + } + + if ($checkException) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_Exception( + $this->expectedException + ) + ); + + if (is_string($this->expectedExceptionMessage) && + !empty($this->expectedExceptionMessage)) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_ExceptionMessage( + $this->expectedExceptionMessage + ) + ); + } + + if (is_string($this->expectedExceptionMessageRegExp) && + !empty($this->expectedExceptionMessageRegExp)) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_ExceptionMessageRegExp( + $this->expectedExceptionMessageRegExp + ) + ); + } + + if ($this->expectedExceptionCode !== null) { + $this->assertThat( + $e, + new PHPUnit_Framework_Constraint_ExceptionCode( + $this->expectedExceptionCode + ) + ); + } + + return; + } else { + throw $e; + } + } + + if ($this->expectedException !== null) { + $this->assertThat( + null, + new PHPUnit_Framework_Constraint_Exception( + $this->expectedException + ) + ); + } + + return $testResult; + } + + /** + * Verifies the mock object expectations. + * + * @since Method available since Release 3.5.0 + */ + protected function verifyMockObjects() + { + foreach ($this->mockObjects as $mockObject) { + if ($mockObject->__phpunit_hasMatchers()) { + $this->numAssertions++; + } + + $mockObject->__phpunit_verify(); + } + } + + /** + * Sets the name of a TestCase. + * + * @param string + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Sets the dependencies of a TestCase. + * + * @param array $dependencies + * @since Method available since Release 3.4.0 + */ + public function setDependencies(array $dependencies) + { + $this->dependencies = $dependencies; + } + + /** + * Returns true if the tests has dependencies + * + * @return boolean + * @since Method available since Release 4.0.0 + */ + public function hasDependencies() + { + return count($this->dependencies) > 0; + } + + /** + * Sets + * + * @param array $dependencyInput + * @since Method available since Release 3.4.0 + */ + public function setDependencyInput(array $dependencyInput) + { + $this->dependencyInput = $dependencyInput; + } + + /** + * Calling this method in setUp() has no effect! + * + * @param boolean $backupGlobals + * @since Method available since Release 3.3.0 + */ + public function setBackupGlobals($backupGlobals) + { + if (is_null($this->backupGlobals) && is_bool($backupGlobals)) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * Calling this method in setUp() has no effect! + * + * @param boolean $backupStaticAttributes + * @since Method available since Release 3.4.0 + */ + public function setBackupStaticAttributes($backupStaticAttributes) + { + if (is_null($this->backupStaticAttributes) && + is_bool($backupStaticAttributes)) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * @param boolean $runTestInSeparateProcess + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.4.0 + */ + public function setRunTestInSeparateProcess($runTestInSeparateProcess) + { + if (is_bool($runTestInSeparateProcess)) { + if ($this->runTestInSeparateProcess === null) { + $this->runTestInSeparateProcess = $runTestInSeparateProcess; + } + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @param boolean $preserveGlobalState + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.4.0 + */ + public function setPreserveGlobalState($preserveGlobalState) + { + if (is_bool($preserveGlobalState)) { + $this->preserveGlobalState = $preserveGlobalState; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @param boolean $inIsolation + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.4.0 + */ + public function setInIsolation($inIsolation) + { + if (is_bool($inIsolation)) { + $this->inIsolation = $inIsolation; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } + + /** + * @return boolean + * @since Method available since Release 4.3.0 + */ + public function isInIsolation() + { + return $this->inIsolation; + } + + /** + * @return mixed + * @since Method available since Release 3.4.0 + */ + public function getResult() + { + return $this->testResult; + } + + /** + * @param mixed $result + * @since Method available since Release 3.4.0 + */ + public function setResult($result) + { + $this->testResult = $result; + } + + /** + * @param callable $callback + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.6.0 + */ + public function setOutputCallback($callback) + { + if (!is_callable($callback)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'callback'); + } + + $this->outputCallback = $callback; + } + + /** + * @return PHPUnit_Framework_TestResult + * @since Method available since Release 3.5.7 + */ + public function getTestResultObject() + { + return $this->result; + } + + /** + * @param PHPUnit_Framework_TestResult $result + * @since Method available since Release 3.6.0 + */ + public function setTestResultObject(PHPUnit_Framework_TestResult $result) + { + $this->result = $result; + } + + /** + * This method is a wrapper for the ini_set() function that automatically + * resets the modified php.ini setting to its original value after the + * test is run. + * + * @param string $varName + * @param string $newValue + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.0.0 + */ + protected function iniSet($varName, $newValue) + { + if (!is_string($varName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $currentValue = ini_set($varName, $newValue); + + if ($currentValue !== false) { + $this->iniSettings[$varName] = $currentValue; + } else { + throw new PHPUnit_Framework_Exception( + sprintf( + 'INI setting "%s" could not be set to "%s".', + $varName, + $newValue + ) + ); + } + } + + /** + * This method is a wrapper for the setlocale() function that automatically + * resets the locale to its original value after the test is run. + * + * @param integer $category + * @param string $locale + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.1.0 + */ + protected function setLocale() + { + $args = func_get_args(); + + if (count($args) < 2) { + throw new PHPUnit_Framework_Exception; + } + + $category = $args[0]; + $locale = $args[1]; + + $categories = array( + LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME + ); + + if (defined('LC_MESSAGES')) { + $categories[] = LC_MESSAGES; + } + + if (!in_array($category, $categories)) { + throw new PHPUnit_Framework_Exception; + } + + if (!is_array($locale) && !is_string($locale)) { + throw new PHPUnit_Framework_Exception; + } + + $this->locale[$category] = setlocale($category, null); + + $result = call_user_func_array( 'setlocale', $args ); + + if ($result === false) { + throw new PHPUnit_Framework_Exception( + 'The locale functionality is not implemented on your platform, ' . + 'the specified locale does not exist or the category name is ' . + 'invalid.' + ); + } + } + + /** + * Returns a mock object for the specified class. + * + * @param string $originalClassName Name of the class to mock. + * @param array|null $methods When provided, only methods whose names are in the array + * are replaced with a configurable test double. The behavior + * of the other methods is not changed. + * Providing null means that no methods will be replaced. + * @param array $arguments Parameters to pass to the original class' constructor. + * @param string $mockClassName Class name for the generated test double class. + * @param boolean $callOriginalConstructor Can be used to disable the call to the original class' constructor. + * @param boolean $callOriginalClone Can be used to disable the call to the original class' clone constructor. + * @param boolean $callAutoload Can be used to disable __autoload() during the generation of the test double class. + * @param boolean $cloneArguments + * @param boolean $callOriginalMethods + * @return PHPUnit_Framework_MockObject_MockObject + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.0.0 + */ + public function getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false, $callOriginalMethods = false) + { + $mockObject = $this->getMockObjectGenerator()->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments, + $callOriginalMethods + ); + + $this->mockObjects[] = $mockObject; + + return $mockObject; + } + + /** + * Returns a builder object to create mock objects using a fluent interface. + * + * @param string $className + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 3.5.0 + */ + public function getMockBuilder($className) + { + return new PHPUnit_Framework_MockObject_MockBuilder($this, $className); + } + + /** + * Mocks the specified class and returns the name of the mocked class. + * + * @param string $originalClassName + * @param array $methods + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @return string + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.5.0 + */ + protected function getMockClass($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = false, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false) + { + $mock = $this->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + + return get_class($mock); + } + + /** + * Returns a mock object for the specified abstract class with all abstract + * methods of the class mocked. Concrete methods are not mocked by default. + * To mock concrete methods, use the 7th parameter ($mockedMethods). + * + * @param string $originalClassName + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param array $mockedMethods + * @param boolean $cloneArguments + * @return PHPUnit_Framework_MockObject_MockObject + * @since Method available since Release 3.4.0 + * @throws PHPUnit_Framework_Exception + */ + public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false) + { + $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass( + $originalClassName, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $mockedMethods, + $cloneArguments + ); + + $this->mockObjects[] = $mockObject; + + return $mockObject; + } + + /** + * Returns a mock object based on the given WSDL file. + * + * @param string $wsdlFile + * @param string $originalClassName + * @param string $mockClassName + * @param array $methods + * @param boolean $callOriginalConstructor + * @param array $options An array of options passed to SOAPClient::_construct + * @return PHPUnit_Framework_MockObject_MockObject + * @since Method available since Release 3.4.0 + */ + protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = array(), $callOriginalConstructor = true, array $options = array()) + { + if ($originalClassName === '') { + $originalClassName = str_replace('.wsdl', '', basename($wsdlFile)); + } + + if (!class_exists($originalClassName)) { + eval( + $this->getMockObjectGenerator()->generateClassFromWsdl( + $wsdlFile, + $originalClassName, + $methods, + $options + ) + ); + } + + return $this->getMock( + $originalClassName, + $methods, + array('', $options), + $mockClassName, + $callOriginalConstructor, + false, + false + ); + } + + /** + * Returns a mock object for the specified trait with all abstract methods + * of the trait mocked. Concrete methods to mock can be specified with the + * `$mockedMethods` parameter. + * + * @param string $traitName + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param array $mockedMethods + * @param boolean $cloneArguments + * @return PHPUnit_Framework_MockObject_MockObject + * @since Method available since Release 4.0.0 + * @throws PHPUnit_Framework_Exception + */ + public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = array(), $cloneArguments = false) + { + $mockObject = $this->getMockObjectGenerator()->getMockForTrait( + $traitName, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $mockedMethods, + $cloneArguments + ); + + $this->mockObjects[] = $mockObject; + + return $mockObject; + } + + /** + * Returns an object for the specified trait. + * + * @param string $traitName + * @param array $arguments + * @param string $traitClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @return object + * @since Method available since Release 3.6.0 + * @throws PHPUnit_Framework_Exception + */ + protected function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false) + { + return $this->getMockObjectGenerator()->getObjectForTrait( + $traitName, + $arguments, + $traitClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + } + + /** + * Adds a value to the assertion counter. + * + * @param integer $count + * @since Method available since Release 3.3.3 + */ + public function addToAssertionCount($count) + { + $this->numAssertions += $count; + } + + /** + * Returns the number of assertions performed by this test. + * + * @return integer + * @since Method available since Release 3.3.0 + */ + public function getNumAssertions() + { + return $this->numAssertions; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed zero or more times. + * + * @return PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount + * @since Method available since Release 3.0.0 + */ + public static function any() + { + return new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is never executed. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + public static function never() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(0); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed at least N times. + * + * @param integer $requiredInvocations + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount + * @since Method available since Release 4.2.0 + */ + public static function atLeast($requiredInvocations) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount( + $requiredInvocations + ); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed at least once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce + * @since Method available since Release 3.0.0 + */ + public static function atLeastOnce() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce; + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly once. + * + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + public static function once() + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount(1); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed exactly $count times. + * + * @param integer $count + * @return PHPUnit_Framework_MockObject_Matcher_InvokedCount + * @since Method available since Release 3.0.0 + */ + public static function exactly($count) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedCount($count); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is executed at most N times. + * + * @param integer $allowedInvocations + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount + * @since Method available since Release 4.2.0 + */ + public static function atMost($allowedInvocations) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount( + $allowedInvocations + ); + } + + /** + * Returns a matcher that matches when the method it is evaluated for + * is invoked at the given $index. + * + * @param integer $index + * @return PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex + * @since Method available since Release 3.0.0 + */ + public static function at($index) + { + return new PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex($index); + } + + /** + * + * + * @param mixed $value + * @return PHPUnit_Framework_MockObject_Stub_Return + * @since Method available since Release 3.0.0 + */ + public static function returnValue($value) + { + return new PHPUnit_Framework_MockObject_Stub_Return($value); + } + + /** + * + * + * @param array $valueMap + * @return PHPUnit_Framework_MockObject_Stub_ReturnValueMap + * @since Method available since Release 3.6.0 + */ + public static function returnValueMap(array $valueMap) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnValueMap($valueMap); + } + + /** + * + * + * @param integer $argumentIndex + * @return PHPUnit_Framework_MockObject_Stub_ReturnArgument + * @since Method available since Release 3.3.0 + */ + public static function returnArgument($argumentIndex) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnArgument( + $argumentIndex + ); + } + + /** + * + * + * @param mixed $callback + * @return PHPUnit_Framework_MockObject_Stub_ReturnCallback + * @since Method available since Release 3.3.0 + */ + public static function returnCallback($callback) + { + return new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callback); + } + + /** + * Returns the current object. + * + * This method is useful when mocking a fluent interface. + * + * @return PHPUnit_Framework_MockObject_Stub_ReturnSelf + * @since Method available since Release 3.6.0 + */ + public static function returnSelf() + { + return new PHPUnit_Framework_MockObject_Stub_ReturnSelf(); + } + + /** + * + * + * @param Exception $exception + * @return PHPUnit_Framework_MockObject_Stub_Exception + * @since Method available since Release 3.1.0 + */ + public static function throwException(Exception $exception) + { + return new PHPUnit_Framework_MockObject_Stub_Exception($exception); + } + + /** + * @param mixed $value, ... + * @return PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls + * @since Method available since Release 3.0.0 + */ + public static function onConsecutiveCalls() + { + $args = func_get_args(); + + return new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args); + } + + /** + * @param mixed $data The data to export as a string + * @param SebastianBergmann\RecursionContext\Context $processed Contains all objects and arrays that have previously been processed + * @return string + * @since Method available since Release 3.2.1 + */ + protected function dataToString(&$data, $processed = null) + { + $result = array(); + $exporter = new Exporter(); + + if (!$processed) { + $processed = new Context; + } + + $processed->add($data); + + foreach ($data as $key => $value) { + if (is_array($value)) { + if ($processed->contains($data[$key]) !== false) { + $result[] = '*RECURSION*'; + } + + else { + $result[] = sprintf( + 'array(%s)', + $this->dataToString($data[$key], $processed) + ); + } + } + + else { + $result[] = $exporter->shortenedExport($value); + } + } + + return join(', ', $result); + } + + /** + * Gets the data set description of a TestCase. + * + * @param boolean $includeData + * @return string + * @since Method available since Release 3.3.0 + */ + protected function getDataSetAsString($includeData = true) + { + $buffer = ''; + + if (!empty($this->data)) { + if (is_int($this->dataName)) { + $buffer .= sprintf(' with data set #%d', $this->dataName); + } else { + $buffer .= sprintf(' with data set "%s"', $this->dataName); + } + + if ($includeData) { + $buffer .= sprintf(' (%s)', $this->dataToString($this->data)); + } + } + + return $buffer; + } + + /** + * Creates a default TestResult object. + * + * @return PHPUnit_Framework_TestResult + */ + protected function createResult() + { + return new PHPUnit_Framework_TestResult; + } + + /** + * @since Method available since Release 3.5.4 + */ + protected function handleDependencies() + { + if (!empty($this->dependencies) && !$this->inIsolation) { + $className = get_class($this); + $passed = $this->result->passed(); + $passedKeys = array_keys($passed); + $numKeys = count($passedKeys); + + for ($i = 0; $i < $numKeys; $i++) { + $pos = strpos($passedKeys[$i], ' with data set'); + + if ($pos !== false) { + $passedKeys[$i] = substr($passedKeys[$i], 0, $pos); + } + } + + $passedKeys = array_flip(array_unique($passedKeys)); + + foreach ($this->dependencies as $dependency) { + if (strpos($dependency, '::') === false) { + $dependency = $className . '::' . $dependency; + } + + if (!isset($passedKeys[$dependency])) { + $this->result->addError( + $this, + new PHPUnit_Framework_SkippedTestError( + sprintf( + 'This test depends on "%s" to pass.', + $dependency + ) + ), + 0 + ); + + return false; + } + + if (isset($passed[$dependency])) { + if ($passed[$dependency]['size'] > $this->getSize()) { + $this->result->addError( + $this, + new PHPUnit_Framework_SkippedTestError( + 'This test depends on a test that is larger than itself.' + ), + 0 + ); + + return false; + } + + $this->dependencyInput[$dependency] = $passed[$dependency]['result']; + } else { + $this->dependencyInput[$dependency] = null; + } + } + } + + return true; + } + + /** + * This method is called before the first test of this test class is run. + * + * @since Method available since Release 3.4.0 + */ + public static function setUpBeforeClass() + { + } + + /** + * Sets up the fixture, for example, open a network connection. + * This method is called before a test is executed. + * + */ + protected function setUp() + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called before the execution of a test starts + * and after setUp() is called. + * + * @since Method available since Release 3.2.8 + */ + protected function assertPreConditions() + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called before the execution of a test ends + * and before tearDown() is called. + * + * @since Method available since Release 3.2.8 + */ + protected function assertPostConditions() + { + } + + /** + * Tears down the fixture, for example, close a network connection. + * This method is called after a test is executed. + */ + protected function tearDown() + { + } + + /** + * This method is called after the last test of this test class is run. + * + * @since Method available since Release 3.4.0 + */ + public static function tearDownAfterClass() + { + } + + /** + * This method is called when a test method did not execute successfully. + * + * @param Exception $e + * @since Method available since Release 3.4.0 + * @throws Exception + */ + protected function onNotSuccessfulTest(Exception $e) + { + throw $e; + } + + /** + * Performs custom preparations on the process isolation template. + * + * @param Text_Template $template + * @since Method available since Release 3.4.0 + */ + protected function prepareTemplate(Text_Template $template) + { + } + + /** + * Get the mock object generator, creating it if it doesn't exist. + * + * @return PHPUnit_Framework_MockObject_Generator + */ + protected function getMockObjectGenerator() + { + if (null === $this->mockObjectGenerator) { + $this->mockObjectGenerator = new PHPUnit_Framework_MockObject_Generator; + } + + return $this->mockObjectGenerator; + } + + /** + * @since Method available since Release 4.2.0 + */ + private function startOutputBuffering() + { + while (!defined('PHPUNIT_TESTSUITE') && ob_get_level() > 0) { + ob_end_clean(); + } + + ob_start(); + + $this->outputBufferingActive = true; + $this->outputBufferingLevel = ob_get_level(); + } + + /** + * @since Method available since Release 4.2.0 + */ + private function stopOutputBuffering() + { + if (ob_get_level() != $this->outputBufferingLevel) { + while (ob_get_level() > 0) { + ob_end_clean(); + } + + throw new PHPUnit_Framework_RiskyTestError( + 'Test code or tested code did not (only) close its own output buffers' + ); + } + + $output = ob_get_contents(); + + if ($this->outputCallback === false) { + $this->output = $output; + } else { + $this->output = call_user_func_array( + $this->outputCallback, + array($output) + ); + } + + ob_end_clean(); + + $this->outputBufferingActive = false; + $this->outputBufferingLevel = ob_get_level(); + } + + private function snapshotGlobalState() + { + if ($this->runTestInSeparateProcess || $this->inIsolation) { + return; + } + + $backupGlobals = $this->backupGlobals === null || $this->backupGlobals === true; + + if ($backupGlobals || $this->backupStaticAttributes) { + $blacklist = new Blacklist; + + if ($backupGlobals) { + foreach ($this->backupGlobalsBlacklist as $globalVariable) { + $blacklist->addGlobalVariable($globalVariable); + } + } + + if ($this->backupStaticAttributes && !defined('PHPUNIT_TESTSUITE')) { + $blacklist->addClassNamePrefix('PHPUnit'); + $blacklist->addClassNamePrefix('File_Iterator'); + $blacklist->addClassNamePrefix('PHP_CodeCoverage'); + $blacklist->addClassNamePrefix('PHP_Invoker'); + $blacklist->addClassNamePrefix('PHP_Timer'); + $blacklist->addClassNamePrefix('PHP_Token'); + $blacklist->addClassNamePrefix('Symfony'); + $blacklist->addClassNamePrefix('Text_Template'); + $blacklist->addClassNamePrefix('Doctrine\Instantiator'); + + foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) { + foreach ($attributes as $attribute) { + $blacklist->addStaticAttribute($class, $attribute); + } + } + } + + $this->snapshot = new Snapshot( + $blacklist, + $backupGlobals, + $this->backupStaticAttributes, + false, + false, + false, + false, + false, + false, + false + ); + } + } + + private function restoreGlobalState() + { + if (!$this->snapshot instanceof Snapshot) { + return; + } + + $restorer = new Restorer; + + if ($this->backupGlobals === null || $this->backupGlobals === true) { + $restorer->restoreGlobalVariables($this->snapshot); + } + + if ($this->backupStaticAttributes) { + $restorer->restoreStaticAttributes($this->snapshot); + } + + $this->snapshot = null; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Environment\Runtime; + +/** + * Default utility for PHP sub-processes. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.5.12 + */ +class PHPUnit_Util_PHP_Default extends PHPUnit_Util_PHP +{ + /** + * Runs a single job (PHP code) using a separate PHP process. + * + * @param string $job + * @param array $settings + * @return array + * @throws PHPUnit_Framework_Exception + */ + public function runJob($job, array $settings = array()) + { + $runtime = new Runtime; + + $process = proc_open( + $runtime->getBinary() . $this->settingsToParameters($settings), + array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ), + $pipes + ); + + if (!is_resource($process)) { + throw new PHPUnit_Framework_Exception( + 'Unable to spawn worker process' + ); + } + + $this->process($pipes[0], $job); + fclose($pipes[0]); + + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + proc_close($process); + $this->cleanup(); + + return array('stdout' => $stdout, 'stderr' => $stderr); + } + + /** + * @param resource $pipe + * @param string $job + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.5.12 + */ + protected function process($pipe, $job) + { + fwrite($pipe, $job); + } + + /** + * @since Method available since Release 3.5.12 + */ + protected function cleanup() + { + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use SebastianBergmann\Environment\Runtime; + +/** + * Windows utility for PHP sub-processes. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.5.12 + */ +class PHPUnit_Util_PHP_Windows extends PHPUnit_Util_PHP_Default +{ + /** + * @var string + */ + private $tempFile; + + /** + * {@inheritdoc} + * + * Reading from STDOUT or STDERR hangs forever on Windows if the output is + * too large. + * + * @see https://bugs.php.net/bug.php?id=51800 + */ + public function runJob($job, array $settings = array()) + { + $runtime = new Runtime; + + if (false === $stdout_handle = tmpfile()) { + throw new PHPUnit_Framework_Exception( + 'A temporary file could not be created; verify that your TEMP environment variable is writable' + ); + } + + $process = proc_open( + $runtime->getBinary() . $this->settingsToParameters($settings), + array( + 0 => array('pipe', 'r'), + 1 => $stdout_handle, + 2 => array('pipe', 'w') + ), + $pipes + ); + + if (!is_resource($process)) { + throw new PHPUnit_Framework_Exception( + 'Unable to spawn worker process' + ); + } + + $this->process($pipes[0], $job); + fclose($pipes[0]); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + proc_close($process); + + rewind($stdout_handle); + $stdout = stream_get_contents($stdout_handle); + fclose($stdout_handle); + + $this->cleanup(); + + return array('stdout' => $stdout, 'stderr' => $stderr); + } + + /** + * @param resource $pipe + * @param string $job + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.5.12 + */ + protected function process($pipe, $job) + { + if (!($this->tempFile = tempnam(sys_get_temp_dir(), 'PHPUnit')) || + file_put_contents($this->tempFile, $job) === false) { + throw new PHPUnit_Framework_Exception( + 'Unable to write temporary file' + ); + } + + fwrite( + $pipe, + "tempFile, true) . "; ?>" + ); + } + + /** + * @since Method available since Release 3.5.12 + */ + protected function cleanup() + { + unlink($this->tempFile); + } +} +setCodeCoverage(new PHP_CodeCoverage); + } + + $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything}); + $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests}); + $result->beStrictAboutTestSize({isStrictAboutTestSize}); + $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests}); + + $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}'); + $test->setDependencyInput(unserialize('{dependencyInput}')); + $test->setInIsolation(TRUE); + + ob_end_clean(); + $test->run($result); + $output = ''; + if (!$test->hasExpectationOnOutput()) { + $output = $test->getActualOutput(); + } + + rewind(STDOUT); + if ($stdout = stream_get_contents(STDOUT)) { + $output = $stdout . $output; + } + + print serialize( + array( + 'testResult' => $test->getResult(), + 'numAssertions' => $test->getNumAssertions(), + 'result' => $result, + 'output' => $output + ) + ); +} + +{constants} +{included_files} +{globals} + +if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + require_once $GLOBALS['__PHPUNIT_BOOTSTRAP']; + unset($GLOBALS['__PHPUNIT_BOOTSTRAP']); +} + +__phpunit_run_isolated_test(); + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (!function_exists('trait_exists')) { + function trait_exists($traitname, $autoload = true) + { + return false; + } +} + +/** + * Test helpers. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Test +{ + const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/'; + const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m'; + const REGEX_REQUIRES_VERSION = '/@requires\s+(?PPHP(?:Unit)?)\s+(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; + const REGEX_REQUIRES_OS = '/@requires\s+OS\s+(?P.+?)[ \t]*\r?$/m'; + const REGEX_REQUIRES = '/@requires\s+(?Pfunction|extension)\s+(?P([^ ]+?))[ \t]*\r?$/m'; + + const SMALL = 0; + const MEDIUM = 1; + const LARGE = 2; + + private static $annotationCache = array(); + + private static $templateMethods = array( + 'setUp', 'assertPreConditions', 'assertPostConditions', 'tearDown' + ); + + private static $hookMethods = array(); + + /** + * @param PHPUnit_Framework_Test $test + * @param boolean $asString + * @return mixed + */ + public static function describe(PHPUnit_Framework_Test $test, $asString = true) + { + if ($asString) { + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + return $test->toString(); + } else { + return get_class($test); + } + } else { + if ($test instanceof PHPUnit_Framework_TestCase) { + return array( + get_class($test), $test->getName() + ); + } elseif ($test instanceof PHPUnit_Framework_SelfDescribing) { + return array('', $test->toString()); + } else { + return array('', get_class($test)); + } + } + } + + /** + * @param string $className + * @param string $methodName + * @return array|bool + * @throws PHPUnit_Framework_CodeCoverageException + * @since Method available since Release 4.0.0 + */ + public static function getLinesToBeCovered($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + if (isset($annotations['class']['coversNothing']) || isset($annotations['method']['coversNothing'])) { + return false; + } + + return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers'); + } + + /** + * Returns lines of code specified with the @uses annotation. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 4.0.0 + */ + public static function getLinesToBeUsed($className, $methodName) + { + return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses'); + } + + /** + * @param string $className + * @param string $methodName + * @param string $mode + * @return array + * @throws PHPUnit_Framework_CodeCoverageException + * @since Method available since Release 4.2.0 + */ + private static function getLinesToBeCoveredOrUsed($className, $methodName, $mode) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $classShortcut = null; + + if (!empty($annotations['class'][$mode . 'DefaultClass'])) { + if (count($annotations['class'][$mode . 'DefaultClass']) > 1) { + throw new PHPUnit_Framework_CodeCoverageException( + sprintf( + 'More than one @%sClass annotation in class or interface "%s".', + $mode, + $className + ) + ); + } + + $classShortcut = $annotations['class'][$mode . 'DefaultClass'][0]; + } + + $list = array(); + + if (isset($annotations['class'][$mode])) { + $list = $annotations['class'][$mode]; + } + + if (isset($annotations['method'][$mode])) { + $list = array_merge($list, $annotations['method'][$mode]); + } + + $codeList = array(); + + foreach (array_unique($list) as $element) { + if ($classShortcut && strncmp($element, '::', 2) === 0) { + $element = $classShortcut . $element; + } + + $element = preg_replace('/[\s()]+$/', '', $element); + + $codeList = array_merge( + $codeList, + self::resolveElementToReflectionObjects($element) + ); + } + + return self::resolveReflectionObjectsToLines($codeList); + } + + /** + * Returns the requirements for a test. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.6.0 + */ + public static function getRequirements($className, $methodName) + { + $reflector = new ReflectionClass($className); + $docComment = $reflector->getDocComment(); + $reflector = new ReflectionMethod($className, $methodName); + $docComment .= "\n" . $reflector->getDocComment(); + $requires = array(); + + if ($count = preg_match_all(self::REGEX_REQUIRES_OS, $docComment, $matches)) { + $requires['OS'] = sprintf( + '/%s/i', + addcslashes($matches['value'][$count - 1], '/') + ); + } + if ($count = preg_match_all(self::REGEX_REQUIRES_VERSION, $docComment, $matches)) { + for ($i = 0; $i < $count; $i++) { + $requires[$matches['name'][$i]] = $matches['value'][$i]; + } + } + + // https://bugs.php.net/bug.php?id=63055 + $matches = array(); + + if ($count = preg_match_all(self::REGEX_REQUIRES, $docComment, $matches)) { + for ($i = 0; $i < $count; $i++) { + $name = $matches['name'][$i] . 's'; + if (!isset($requires[$name])) { + $requires[$name] = array(); + } + $requires[$name][] = $matches['value'][$i]; + } + } + + return $requires; + } + + /** + * Returns the missing requirements for a test. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 4.3.0 + */ + public static function getMissingRequirements($className, $methodName) + { + $required = static::getRequirements($className, $methodName); + $missing = array(); + + if (!empty($required['PHP']) && version_compare(PHP_VERSION, $required['PHP'], '<')) { + $missing[] = sprintf('PHP %s (or later) is required.', $required['PHP']); + } + + if (!empty($required['PHPUnit'])) { + $phpunitVersion = PHPUnit_Runner_Version::id(); + if (version_compare($phpunitVersion, $required['PHPUnit'], '<')) { + $missing[] = sprintf('PHPUnit %s (or later) is required.', $required['PHPUnit']); + } + } + + if (!empty($required['OS']) && !preg_match($required['OS'], PHP_OS)) { + $missing[] = sprintf('Operating system matching %s is required.', $required['OS']); + } + + if (!empty($required['functions'])) { + foreach ($required['functions'] as $function) { + $pieces = explode('::', $function); + if (2 === count($pieces) && method_exists($pieces[0], $pieces[1])) { + continue; + } + if (function_exists($function)) { + continue; + } + $missing[] = sprintf('Function %s is required.', $function); + } + } + + if (!empty($required['extensions'])) { + foreach ($required['extensions'] as $extension) { + if (!extension_loaded($extension)) { + $missing[] = sprintf('Extension %s is required.', $extension); + } + } + } + + return $missing; + } + + /** + * Returns the expected exception for a test. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.3.6 + */ + public static function getExpectedException($className, $methodName) + { + $reflector = new ReflectionMethod($className, $methodName); + $docComment = $reflector->getDocComment(); + $docComment = substr($docComment, 3, -2); + + if (preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $class = $matches[1]; + $code = null; + $message = ''; + $messageRegExp = ''; + + if (isset($matches[2])) { + $message = trim($matches[2]); + } elseif (isset($annotations['method']['expectedExceptionMessage'])) { + $message = self::parseAnnotationContent( + $annotations['method']['expectedExceptionMessage'][0] + ); + } + + if (isset($annotations['method']['expectedExceptionMessageRegExp'])) { + $messageRegExp = self::parseAnnotationContent( + $annotations['method']['expectedExceptionMessageRegExp'][0] + ); + } + + if (isset($matches[3])) { + $code = $matches[3]; + } elseif (isset($annotations['method']['expectedExceptionCode'])) { + $code = self::parseAnnotationContent( + $annotations['method']['expectedExceptionCode'][0] + ); + } + + if (is_numeric($code)) { + $code = (int) $code; + } elseif (is_string($code) && defined($code)) { + $code = (int) constant($code); + } + + return array( + 'class' => $class, 'code' => $code, 'message' => $message, 'message_regex' => $messageRegExp + ); + } + + return false; + } + + /** + * Parse annotation content to use constant/class constant values + * + * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME + * + * If the constant is not found the string is used as is to ensure maximum BC. + * + * @param string $message + * @return string + */ + private static function parseAnnotationContent($message) + { + if (strpos($message, '::') !== false && count(explode('::', $message) == 2)) { + if (defined($message)) { + $message = constant($message); + } + } + + return $message; + } + + /** + * Returns the provided data for a method. + * + * @param string $className + * @param string $methodName + * @return array|Iterator when a data provider is specified and exists + * false when a data provider is specified but does not exist + * null when no data provider is specified + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.2.0 + */ + public static function getProvidedData($className, $methodName) + { + $reflector = new ReflectionMethod($className, $methodName); + $docComment = $reflector->getDocComment(); + $data = null; + + if (preg_match(self::REGEX_DATA_PROVIDER, $docComment, $matches)) { + $dataProviderMethodNameNamespace = explode('\\', $matches[1]); + $leaf = explode('::', array_pop($dataProviderMethodNameNamespace)); + $dataProviderMethodName = array_pop($leaf); + + if (!empty($dataProviderMethodNameNamespace)) { + $dataProviderMethodNameNamespace = join('\\', $dataProviderMethodNameNamespace) . '\\'; + } else { + $dataProviderMethodNameNamespace = ''; + } + + if (!empty($leaf)) { + $dataProviderClassName = $dataProviderMethodNameNamespace . array_pop($leaf); + } else { + $dataProviderClassName = $className; + } + + $dataProviderClass = new ReflectionClass($dataProviderClassName); + $dataProviderMethod = $dataProviderClass->getMethod( + $dataProviderMethodName + ); + + if ($dataProviderMethod->isStatic()) { + $object = null; + } else { + $object = $dataProviderClass->newInstance(); + } + + if ($dataProviderMethod->getNumberOfParameters() == 0) { + $data = $dataProviderMethod->invoke($object); + } else { + $data = $dataProviderMethod->invoke($object, $methodName); + } + } + + if ($data !== null) { + if (is_object($data)) { + $data = iterator_to_array($data); + } + + foreach ($data as $key => $value) { + if (!is_array($value)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Data set %s is invalid.', + is_int($key) ? '#' . $key : '"' . $key . '"' + ) + ); + } + } + } + + return $data; + } + + /** + * @param string $className + * @param string $methodName + * @return array + * @throws ReflectionException + * @since Method available since Release 3.4.0 + */ + public static function parseTestMethodAnnotations($className, $methodName = '') + { + if (!isset(self::$annotationCache[$className])) { + $class = new ReflectionClass($className); + self::$annotationCache[$className] = self::parseAnnotations($class->getDocComment()); + } + + if (!empty($methodName) && !isset(self::$annotationCache[$className . '::' . $methodName])) { + try { + $method = new ReflectionMethod($className, $methodName); + $annotations = self::parseAnnotations($method->getDocComment()); + } catch (ReflectionException $e) { + $annotations = array(); + } + self::$annotationCache[$className . '::' . $methodName] = $annotations; + } + + return array( + 'class' => self::$annotationCache[$className], + 'method' => !empty($methodName) ? self::$annotationCache[$className . '::' . $methodName] : array() + ); + } + + /** + * @param string $docblock + * @return array + * @since Method available since Release 3.4.0 + */ + private static function parseAnnotations($docblock) + { + $annotations = array(); + // Strip away the docblock header and footer to ease parsing of one line annotations + $docblock = substr($docblock, 3, -2); + + if (preg_match_all('/@(?P[A-Za-z_-]+)(?:[ \t]+(?P.*?))?[ \t]*\r?$/m', $docblock, $matches)) { + $numMatches = count($matches[0]); + + for ($i = 0; $i < $numMatches; ++$i) { + $annotations[$matches['name'][$i]][] = $matches['value'][$i]; + } + } + + return $annotations; + } + + /** + * Returns the backup settings for a test. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.4.0 + */ + public static function getBackupSettings($className, $methodName) + { + return array( + 'backupGlobals' => self::getBooleanAnnotationSetting( + $className, + $methodName, + 'backupGlobals' + ), + 'backupStaticAttributes' => self::getBooleanAnnotationSetting( + $className, + $methodName, + 'backupStaticAttributes' + ) + ); + } + + /** + * Returns the dependencies for a test class or method. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.4.0 + */ + public static function getDependencies($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $dependencies = array(); + + if (isset($annotations['class']['depends'])) { + $dependencies = $annotations['class']['depends']; + } + + if (isset($annotations['method']['depends'])) { + $dependencies = array_merge( + $dependencies, + $annotations['method']['depends'] + ); + } + + return array_unique($dependencies); + } + + /** + * Returns the error handler settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.0 + */ + public static function getErrorHandlerSettings($className, $methodName) + { + return self::getBooleanAnnotationSetting( + $className, + $methodName, + 'errorHandler' + ); + } + + /** + * Returns the groups for a test class or method. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.2.0 + */ + public static function getGroups($className, $methodName = '') + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $groups = array(); + + if (isset($annotations['method']['author'])) { + $groups = $annotations['method']['author']; + } elseif (isset($annotations['class']['author'])) { + $groups = $annotations['class']['author']; + } + + if (isset($annotations['class']['group'])) { + $groups = array_merge($groups, $annotations['class']['group']); + } + + if (isset($annotations['method']['group'])) { + $groups = array_merge($groups, $annotations['method']['group']); + } + + if (isset($annotations['class']['ticket'])) { + $groups = array_merge($groups, $annotations['class']['ticket']); + } + + if (isset($annotations['method']['ticket'])) { + $groups = array_merge($groups, $annotations['method']['ticket']); + } + + foreach (array('small', 'medium', 'large') as $size) { + if (isset($annotations['method'][$size])) { + $groups[] = $size; + } elseif (isset($annotations['class'][$size])) { + $groups[] = $size; + } + } + + return array_unique($groups); + } + + /** + * Returns the size of the test. + * + * @param string $className + * @param string $methodName + * @return integer + * @since Method available since Release 3.6.0 + */ + public static function getSize($className, $methodName) + { + $groups = array_flip(self::getGroups($className, $methodName)); + $size = self::SMALL; + $class = new ReflectionClass($className); + + if ((class_exists('PHPUnit_Extensions_Database_TestCase', false) && + $class->isSubclassOf('PHPUnit_Extensions_Database_TestCase')) || + (class_exists('PHPUnit_Extensions_SeleniumTestCase', false) && + $class->isSubclassOf('PHPUnit_Extensions_SeleniumTestCase'))) { + $size = self::LARGE; + } elseif (isset($groups['medium'])) { + $size = self::MEDIUM; + } elseif (isset($groups['large'])) { + $size = self::LARGE; + } + + return $size; + } + + /** + * Returns the tickets for a test class or method. + * + * @param string $className + * @param string $methodName + * @return array + * @since Method available since Release 3.4.0 + */ + public static function getTickets($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $tickets = array(); + + if (isset($annotations['class']['ticket'])) { + $tickets = $annotations['class']['ticket']; + } + + if (isset($annotations['method']['ticket'])) { + $tickets = array_merge($tickets, $annotations['method']['ticket']); + } + + return array_unique($tickets); + } + + /** + * Returns the process isolation settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.1 + */ + public static function getProcessIsolationSettings($className, $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + if (isset($annotations['class']['runTestsInSeparateProcesses']) || + isset($annotations['method']['runInSeparateProcess'])) { + return true; + } else { + return false; + } + } + + /** + * Returns the preserve global state settings for a test. + * + * @param string $className + * @param string $methodName + * @return boolean + * @since Method available since Release 3.4.0 + */ + public static function getPreserveGlobalStateSettings($className, $methodName) + { + return self::getBooleanAnnotationSetting( + $className, + $methodName, + 'preserveGlobalState' + ); + } + + /** + * @param string $className + * @return array + * @since Method available since Release 4.0.8 + */ + public static function getHookMethods($className) + { + if (!class_exists($className, false)) { + return self::emptyHookMethodsArray(); + } + + if (!isset(self::$hookMethods[$className])) { + self::$hookMethods[$className] = self::emptyHookMethodsArray(); + + try { + $class = new ReflectionClass($className); + + foreach ($class->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() != $className) { + continue; + } + + if (self::isBeforeClassMethod($method)) { + self::$hookMethods[$className]['beforeClass'][] = $method->getName(); + } + + if (self::isBeforeMethod($method)) { + self::$hookMethods[$className]['before'][] = $method->getName(); + } + + if (self::isAfterMethod($method)) { + self::$hookMethods[$className]['after'][] = $method->getName(); + } + + if (self::isAfterClassMethod($method)) { + self::$hookMethods[$className]['afterClass'][] = $method->getName(); + } + } + } catch (ReflectionException $e) { + } + } + + return self::$hookMethods[$className]; + } + + /** + * @return array + * @since Method available since Release 4.0.9 + */ + private static function emptyHookMethodsArray() + { + return array( + 'beforeClass' => array('setUpBeforeClass'), + 'before' => array('setUp'), + 'after' => array('tearDown'), + 'afterClass' => array('tearDownAfterClass') + ); + } + + /** + * @param string $className + * @param string $methodName + * @param string $settingName + * @return boolean + * @since Method available since Release 3.4.0 + */ + private static function getBooleanAnnotationSetting($className, $methodName, $settingName) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $result = null; + + if (isset($annotations['class'][$settingName])) { + if ($annotations['class'][$settingName][0] == 'enabled') { + $result = true; + } elseif ($annotations['class'][$settingName][0] == 'disabled') { + $result = false; + } + } + + if (isset($annotations['method'][$settingName])) { + if ($annotations['method'][$settingName][0] == 'enabled') { + $result = true; + } elseif ($annotations['method'][$settingName][0] == 'disabled') { + $result = false; + } + } + + return $result; + } + + /** + * @param string $element + * @return array + * @throws PHPUnit_Framework_InvalidCoversTargetException + * @since Method available since Release 4.0.0 + */ + private static function resolveElementToReflectionObjects($element) + { + $codeToCoverList = array(); + + if (strpos($element, '::') !== false) { + list($className, $methodName) = explode('::', $element); + + if (isset($methodName[0]) && $methodName[0] == '<') { + $classes = array($className); + + foreach ($classes as $className) { + if (!class_exists($className) && + !interface_exists($className)) { + throw new PHPUnit_Framework_InvalidCoversTargetException( + sprintf( + 'Trying to @cover or @use not existing class or ' . + 'interface "%s".', + $className + ) + ); + } + + $class = new ReflectionClass($className); + $methods = $class->getMethods(); + $inverse = isset($methodName[1]) && $methodName[1] == '!'; + + if (strpos($methodName, 'protected')) { + $visibility = 'isProtected'; + } elseif (strpos($methodName, 'private')) { + $visibility = 'isPrivate'; + } elseif (strpos($methodName, 'public')) { + $visibility = 'isPublic'; + } + + foreach ($methods as $method) { + if ($inverse && !$method->$visibility()) { + $codeToCoverList[] = $method; + } elseif (!$inverse && $method->$visibility()) { + $codeToCoverList[] = $method; + } + } + } + } else { + $classes = array($className); + + foreach ($classes as $className) { + if ($className == '' && function_exists($methodName)) { + $codeToCoverList[] = new ReflectionFunction( + $methodName + ); + } else { + if (!((class_exists($className) || + interface_exists($className) || + trait_exists($className)) && + method_exists($className, $methodName))) { + throw new PHPUnit_Framework_InvalidCoversTargetException( + sprintf( + 'Trying to @cover or @use not existing method "%s::%s".', + $className, + $methodName + ) + ); + } + + $codeToCoverList[] = new ReflectionMethod( + $className, + $methodName + ); + } + } + } + } else { + $extended = false; + + if (strpos($element, '') !== false) { + $element = str_replace('', '', $element); + $extended = true; + } + + $classes = array($element); + + if ($extended) { + $classes = array_merge( + $classes, + class_implements($element), + class_parents($element) + ); + } + + foreach ($classes as $className) { + if (!class_exists($className) && + !interface_exists($className) && + !trait_exists($className)) { + throw new PHPUnit_Framework_InvalidCoversTargetException( + sprintf( + 'Trying to @cover or @use not existing class or ' . + 'interface "%s".', + $className + ) + ); + } + + $codeToCoverList[] = new ReflectionClass($className); + } + } + + return $codeToCoverList; + } + + /** + * @param array $reflectors + * @return array + */ + private static function resolveReflectionObjectsToLines(array $reflectors) + { + $result = array(); + + foreach ($reflectors as $reflector) { + $filename = $reflector->getFileName(); + + if (!isset($result[$filename])) { + $result[$filename] = array(); + } + + $result[$filename] = array_unique( + array_merge( + $result[$filename], + range($reflector->getStartLine(), $reflector->getEndLine()) + ) + ); + } + + return $result; + } + + /** + * @param ReflectionMethod $method + * @return boolean + * @since Method available since Release 4.0.8 + */ + private static function isBeforeClassMethod(ReflectionMethod $method) + { + return $method->isStatic() && strpos($method->getDocComment(), '@beforeClass') !== false; + } + + /** + * @param ReflectionMethod $method + * @return boolean + * @since Method available since Release 4.0.8 + */ + private static function isBeforeMethod(ReflectionMethod $method) + { + return preg_match('/@before\b/', $method->getDocComment()); + } + + /** + * @param ReflectionMethod $method + * @return boolean + * @since Method available since Release 4.0.8 + */ + private static function isAfterClassMethod(ReflectionMethod $method) + { + return $method->isStatic() && strpos($method->getDocComment(), '@afterClass') !== false; + } + + /** + * @param ReflectionMethod $method + * @return boolean + * @since Method available since Release 4.0.8 + */ + private static function isAfterMethod(ReflectionMethod $method) + { + return preg_match('/@after\b/', $method->getDocComment()); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Base class for printers of TestDox documentation. + * + * @package PHPUnit + * @subpackage Util_TestDox + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +abstract class PHPUnit_Util_TestDox_ResultPrinter extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var PHPUnit_Util_TestDox_NamePrettifier + */ + protected $prettifier; + + /** + * @var string + */ + protected $testClass = ''; + + /** + * @var integer + */ + protected $testStatus = false; + + /** + * @var array + */ + protected $tests = array(); + + /** + * @var integer + */ + protected $successful = 0; + + /** + * @var integer + */ + protected $failed = 0; + + /** + * @var integer + */ + protected $risky = 0; + + /** + * @var integer + */ + protected $skipped = 0; + + /** + * @var integer + */ + protected $incomplete = 0; + + /** + * @var string + */ + protected $testTypeOfInterest = 'PHPUnit_Framework_TestCase'; + + /** + * @var string + */ + protected $currentTestClassPrettified; + + /** + * @var string + */ + protected $currentTestMethodPrettified; + + /** + * Constructor. + * + * @param resource $out + */ + public function __construct($out = null) + { + parent::__construct($out); + + $this->prettifier = new PHPUnit_Util_TestDox_NamePrettifier; + $this->startRun(); + } + + /** + * Flush buffer and close output. + * + */ + public function flush() + { + $this->doEndClass(); + $this->endRun(); + + parent::flush(); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_ERROR; + $this->failed++; + } + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE; + $this->failed++; + } + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE; + $this->incomplete++; + } + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_RISKY; + $this->risky++; + } + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED; + $this->skipped++; + } + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if ($test instanceof $this->testTypeOfInterest) { + $class = get_class($test); + + if ($this->testClass != $class) { + if ($this->testClass != '') { + $this->doEndClass(); + } + + $this->currentTestClassPrettified = $this->prettifier->prettifyTestClass($class); + $this->startClass($class); + + $this->testClass = $class; + $this->tests = array(); + } + + $prettified = false; + + if ($test instanceof PHPUnit_Framework_TestCase && + !$test instanceof PHPUnit_Framework_Warning) { + $annotations = $test->getAnnotations(); + + if (isset($annotations['method']['testdox'][0])) { + $this->currentTestMethodPrettified = $annotations['method']['testdox'][0]; + $prettified = true; + } + } + + if (!$prettified) { + $this->currentTestMethodPrettified = $this->prettifier->prettifyTestMethod($test->getName(false)); + } + + $this->testStatus = PHPUnit_Runner_BaseTestRunner::STATUS_PASSED; + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($test instanceof $this->testTypeOfInterest) { + if (!isset($this->tests[$this->currentTestMethodPrettified])) { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $this->tests[$this->currentTestMethodPrettified]['success'] = 1; + $this->tests[$this->currentTestMethodPrettified]['failure'] = 0; + } else { + $this->tests[$this->currentTestMethodPrettified]['success'] = 0; + $this->tests[$this->currentTestMethodPrettified]['failure'] = 1; + } + } else { + if ($this->testStatus == PHPUnit_Runner_BaseTestRunner::STATUS_PASSED) { + $this->tests[$this->currentTestMethodPrettified]['success']++; + } else { + $this->tests[$this->currentTestMethodPrettified]['failure']++; + } + } + + $this->currentTestClassPrettified = null; + $this->currentTestMethodPrettified = null; + } + } + + /** + * @since Method available since Release 2.3.0 + */ + protected function doEndClass() + { + foreach ($this->tests as $name => $data) { + $this->onTest($name, $data['failure'] == 0); + } + + $this->endClass($this->testClass); + } + + /** + * Handler for 'start run' event. + * + */ + protected function startRun() + { + } + + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + */ + protected function onTest($name, $success = true) + { + } + + /** + * Handler for 'end class' event. + * + * @param string $name + */ + protected function endClass($name) + { + } + + /** + * Handler for 'end run' event. + * + */ + protected function endRun() + { + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Prettifies class and method names for use in TestDox documentation. + * + * @package PHPUnit + * @subpackage Util_TestDox + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_TestDox_NamePrettifier +{ + /** + * @var string + */ + protected $prefix = 'Test'; + + /** + * @var string + */ + protected $suffix = 'Test'; + + /** + * @var array + */ + protected $strings = array(); + + /** + * Prettifies the name of a test class. + * + * @param string $name + * @return string + */ + public function prettifyTestClass($name) + { + $title = $name; + + if ($this->suffix !== null && + $this->suffix == substr($name, -1 * strlen($this->suffix))) { + $title = substr($title, 0, strripos($title, $this->suffix)); + } + + if ($this->prefix !== null && + $this->prefix == substr($name, 0, strlen($this->prefix))) { + $title = substr($title, strlen($this->prefix)); + } + + if (substr($title, 0, 1) == '\\') { + $title = substr($title, 1); + } + + return $title; + } + + /** + * Prettifies the name of a test method. + * + * @param string $name + * @return string + */ + public function prettifyTestMethod($name) + { + $buffer = ''; + + if (!is_string($name) || strlen($name) == 0) { + return $buffer; + } + + $string = preg_replace('#\d+$#', '', $name, -1, $count); + + if (in_array($string, $this->strings)) { + $name = $string; + } elseif ($count == 0) { + $this->strings[] = $string; + } + + if (strpos($name, '_') !== false) { + return str_replace('_', ' ', $name); + } + + $max = strlen($name); + + if (substr($name, 0, 4) == 'test') { + $offset = 4; + } else { + $offset = 0; + $name[0] = strtoupper($name[0]); + } + + $wasNumeric = false; + + for ($i = $offset; $i < $max; $i++) { + if ($i > $offset && + ord($name[$i]) >= 65 && + ord($name[$i]) <= 90) { + $buffer .= ' ' . strtolower($name[$i]); + } else { + $isNumeric = is_numeric($name[$i]); + + if (!$wasNumeric && $isNumeric) { + $buffer .= ' '; + $wasNumeric = true; + } + + if ($wasNumeric && !$isNumeric) { + $wasNumeric = false; + } + + $buffer .= $name[$i]; + } + } + + return $buffer; + } + + /** + * Sets the prefix of test names. + * + * @param string $prefix + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Sets the suffix of test names. + * + * @param string $suffix + */ + public function setSuffix($suffix) + { + $this->suffix = $suffix; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Prints TestDox documentation in text format. + * + * @package PHPUnit + * @subpackage Util_TestDox + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_TestDox_ResultPrinter_Text extends PHPUnit_Util_TestDox_ResultPrinter +{ + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + $this->write($this->currentTestClassPrettified . "\n"); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + */ + protected function onTest($name, $success = true) + { + if ($success) { + $this->write(' [x] '); + } else { + $this->write(' [ ] '); + } + + $this->write($name . "\n"); + } + + /** + * Handler for 'end class' event. + * + * @param string $name + */ + protected function endClass($name) + { + $this->write("\n"); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Prints TestDox documentation in HTML format. + * + * @package PHPUnit + * @subpackage Util_TestDox + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_TestDox_ResultPrinter_HTML extends PHPUnit_Util_TestDox_ResultPrinter +{ + /** + * @var boolean + */ + protected $printsHTML = true; + + /** + * Handler for 'start run' event. + * + */ + protected function startRun() + { + $this->write(''); + } + + /** + * Handler for 'start class' event. + * + * @param string $name + */ + protected function startClass($name) + { + $this->write( + '

    ' . $this->currentTestClassPrettified . + '

      ' + ); + } + + /** + * Handler for 'on test' event. + * + * @param string $name + * @param boolean $success + */ + protected function onTest($name, $success = true) + { + if (!$success) { + $strikeOpen = ''; + $strikeClose = ''; + } else { + $strikeOpen = ''; + $strikeClose = ''; + } + + $this->write('
    • ' . $strikeOpen . $name . $strikeClose . '
    • '); + } + + /** + * Handler for 'end class' event. + * + * @param string $name + */ + protected function endClass($name) + { + $this->write('
    '); + } + + /** + * Handler for 'end run' event. + * + */ + protected function endRun() + { + $this->write(''); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * String helpers. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.6.0 + */ +class PHPUnit_Util_String +{ + /** + * Converts a string to UTF-8 encoding. + * + * @param string $string + * @return string + */ + public static function convertToUtf8($string) + { + if (!self::isUtf8($string)) { + if (function_exists('mb_convert_encoding')) { + $string = mb_convert_encoding($string, 'UTF-8'); + } else { + $string = utf8_encode($string); + } + } + + return $string; + } + + /** + * Checks a string for UTF-8 encoding. + * + * @param string $string + * @return boolean + */ + protected static function isUtf8($string) + { + $length = strlen($string); + + for ($i = 0; $i < $length; $i++) { + if (ord($string[$i]) < 0x80) { + $n = 0; + } elseif ((ord($string[$i]) & 0xE0) == 0xC0) { + $n = 1; + } elseif ((ord($string[$i]) & 0xF0) == 0xE0) { + $n = 2; + } elseif ((ord($string[$i]) & 0xF0) == 0xF0) { + $n = 3; + } else { + return false; + } + + for ($j = 0; $j < $n; $j++) { + if ((++$i == $length) || ((ord($string[$i]) & 0xC0) != 0x80)) { + return false; + } + } + } + + return true; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Factory for PHPUnit_Framework_Exception objects that are used to describe + * invalid arguments passed to a function or method. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_InvalidArgumentHelper +{ + /** + * @param integer $argument + * @param string $type + * @param mixed $value + * @return PHPUnit_Framework_Exception + */ + public static function factory($argument, $type, $value = null) + { + $stack = debug_backtrace(false); + + return new PHPUnit_Framework_Exception( + sprintf( + 'Argument #%d%sof %s::%s() must be a %s', + $argument, + $value !== null ? ' (' . gettype($value) . '#' . $value . ')' : ' (No Value) ', + $stack[1]['class'], + $stack[1]['function'], + $type + ) + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Utility methods to load PHP sourcefiles. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.3.0 + */ +class PHPUnit_Util_Fileloader +{ + /** + * Checks if a PHP sourcefile is readable. + * The sourcefile is loaded through the load() method. + * + * @param string $filename + * @return string + * @throws PHPUnit_Framework_Exception + */ + public static function checkAndLoad($filename) + { + $includePathFilename = stream_resolve_include_path($filename); + + if (!$includePathFilename || !is_readable($includePathFilename)) { + throw new PHPUnit_Framework_Exception( + sprintf('Cannot open file "%s".' . "\n", $filename) + ); + } + + self::load($includePathFilename); + + return $includePathFilename; + } + + /** + * Loads a PHP sourcefile. + * + * @param string $filename + * @return mixed + * @since Method available since Release 3.0.0 + */ + public static function load($filename) + { + $oldVariableNames = array_keys(get_defined_vars()); + + include_once $filename; + + $newVariables = get_defined_vars(); + $newVariableNames = array_diff( + array_keys($newVariables), $oldVariableNames + ); + + foreach ($newVariableNames as $variableName) { + if ($variableName != 'oldVariableNames') { + $GLOBALS[$variableName] = $newVariables[$variableName]; + } + } + + return $filename; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Utility methods for PHP sub-processes. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +abstract class PHPUnit_Util_PHP +{ + /** + * @return PHPUnit_Util_PHP + * @since Method available since Release 3.5.12 + */ + public static function factory() + { + if (DIRECTORY_SEPARATOR == '\\') { + return new PHPUnit_Util_PHP_Windows; + } + + return new PHPUnit_Util_PHP_Default; + } + + /** + * Runs a single test in a separate PHP process. + * + * @param string $job + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_TestResult $result + * @throws PHPUnit_Framework_Exception + */ + public function runTestJob($job, PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result) + { + $result->startTest($test); + + $_result = $this->runJob($job); + + $this->processChildResult( + $test, $result, $_result['stdout'], $_result['stderr'] + ); + } + + /** + * Runs a single job (PHP code) using a separate PHP process. + * + * @param string $job + * @param array $settings + * @return array + * @throws PHPUnit_Framework_Exception + */ + abstract public function runJob($job, array $settings = array()); + + /** + * @param array $settings + * @return string + * @since Method available since Release 4.0.0 + */ + protected function settingsToParameters(array $settings) + { + $buffer = ''; + + foreach ($settings as $setting) { + $buffer .= ' -d ' . $setting; + } + + return $buffer; + } + + /** + * Processes the TestResult object from an isolated process. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_TestResult $result + * @param string $stdout + * @param string $stderr + * @since Method available since Release 3.5.0 + */ + private function processChildResult(PHPUnit_Framework_Test $test, PHPUnit_Framework_TestResult $result, $stdout, $stderr) + { + $time = 0; + + if (!empty($stderr)) { + $result->addError( + $test, + new PHPUnit_Framework_Exception(trim($stderr)), $time + ); + } else { + set_error_handler(function ($errno, $errstr, $errfile, $errline) { + throw new ErrorException($errstr, $errno, $errno, $errfile, $errline); + }); + try { + if (strpos($stdout, "#!/usr/bin/env php\n") === 0) { + $stdout = substr($stdout, 19); + } + + $childResult = unserialize(str_replace("#!/usr/bin/env php\n", '', $stdout)); + restore_error_handler(); + } catch (ErrorException $e) { + restore_error_handler(); + $childResult = false; + + $result->addError( + $test, new PHPUnit_Framework_Exception(trim($stdout), 0, $e), $time + ); + } + + if ($childResult !== false) { + if (!empty($childResult['output'])) { + $output = $childResult['output']; + } + + $test->setResult($childResult['testResult']); + $test->addToAssertionCount($childResult['numAssertions']); + + $childResult = $childResult['result']; + + if ($result->getCollectCodeCoverageInformation()) { + $result->getCodeCoverage()->merge( + $childResult->getCodeCoverage() + ); + } + + $time = $childResult->time(); + $notImplemented = $childResult->notImplemented(); + $risky = $childResult->risky(); + $skipped = $childResult->skipped(); + $errors = $childResult->errors(); + $failures = $childResult->failures(); + + if (!empty($notImplemented)) { + $result->addError( + $test, $this->getException($notImplemented[0]), $time + ); + } elseif (!empty($risky)) { + $result->addError( + $test, $this->getException($risky[0]), $time + ); + } elseif (!empty($skipped)) { + $result->addError( + $test, $this->getException($skipped[0]), $time + ); + } elseif (!empty($errors)) { + $result->addError( + $test, $this->getException($errors[0]), $time + ); + } elseif (!empty($failures)) { + $result->addFailure( + $test, $this->getException($failures[0]), $time + ); + } + } + } + + $result->endTest($test, $time); + + if (!empty($output)) { + print $output; + } + } + + /** + * Gets the thrown exception from a PHPUnit_Framework_TestFailure. + * + * @param PHPUnit_Framework_TestFailure $error + * @return Exception + * @since Method available since Release 3.6.0 + * @see https://github.com/sebastianbergmann/phpunit/issues/74 + */ + private function getException(PHPUnit_Framework_TestFailure $error) + { + $exception = $error->thrownException(); + + if ($exception instanceof __PHP_Incomplete_Class) { + $exceptionArray = array(); + foreach ((array) $exception as $key => $value) { + $key = substr($key, strrpos($key, "\0") + 1); + $exceptionArray[$key] = $value; + } + + $exception = new PHPUnit_Framework_SyntheticError( + sprintf( + '%s: %s', + $exceptionArray['_PHP_Incomplete_Class_Name'], + $exceptionArray['message'] + ), + $exceptionArray['code'], + $exceptionArray['file'], + $exceptionArray['line'], + $exceptionArray['trace'] + ); + } + + return $exception; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Iterator for test suites. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.1.0 + */ +class PHPUnit_Util_TestSuiteIterator implements RecursiveIterator +{ + /** + * @var integer + */ + protected $position; + + /** + * @var PHPUnit_Framework_Test[] + */ + protected $tests; + + /** + * @param PHPUnit_Framework_TestSuite $testSuite + */ + public function __construct(PHPUnit_Framework_TestSuite $testSuite) + { + $this->tests = $testSuite->tests(); + } + + /** + * Rewinds the Iterator to the first element. + * + */ + public function rewind() + { + $this->position = 0; + } + + /** + * Checks if there is a current element after calls to rewind() or next(). + * + * @return boolean + */ + public function valid() + { + return $this->position < count($this->tests); + } + + /** + * Returns the key of the current element. + * + * @return integer + */ + public function key() + { + return $this->position; + } + + /** + * Returns the current element. + * + * @return PHPUnit_Framework_Test + */ + public function current() + { + return $this->valid() ? $this->tests[$this->position] : null; + } + + /** + * Moves forward to next element. + * + */ + public function next() + { + $this->position++; + } + + /** + * Returns the sub iterator for the current element. + * + * @return PHPUnit_Util_TestSuiteIterator + */ + public function getChildren() + { + return new PHPUnit_Util_TestSuiteIterator( + $this->tests[$this->position] + ); + } + + /** + * Checks whether the current element has children. + * + * @return boolean + */ + public function hasChildren() + { + return $this->tests[$this->position] instanceof PHPUnit_Framework_TestSuite; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Utility class for textual type (and value) representation. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Type +{ + public static function isType($type) + { + return in_array( + $type, + array( + 'numeric', + 'integer', + 'int', + 'float', + 'string', + 'boolean', + 'bool', + 'null', + 'array', + 'object', + 'resource', + 'scalar' + ) + ); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Filesystem helpers. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Filesystem +{ + /** + * @var array + */ + protected static $buffer = array(); + + /** + * Maps class names to source file names: + * - PEAR CS: Foo_Bar_Baz -> Foo/Bar/Baz.php + * - Namespace: Foo\Bar\Baz -> Foo/Bar/Baz.php + * + * @param string $className + * @return string + * @since Method available since Release 3.4.0 + */ + public static function classNameToFilename($className) + { + return str_replace( + array('_', '\\'), + DIRECTORY_SEPARATOR, + $className + ) . '.php'; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Error handler that converts PHP errors and warnings to exceptions. + * + * @package PHPUnit + * @subpackage Util + * @author Márcio Almada + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.2.0 + */ +class PHPUnit_Util_Regex +{ + public static function pregMatchSafe($pattern, $subject, $matches = null, $flags = 0, $offset = 0) + { + $handler_terminator = PHPUnit_Util_ErrorHandler::handleErrorOnce(E_WARNING); + $match = preg_match($pattern, $subject, $matches, $flags, $offset); + $handler_terminator(); // cleaning + + return $match; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Utility class for blacklisting PHPUnit's own source code files. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 4.0.0 + */ +class PHPUnit_Util_Blacklist +{ + /** + * @var array + */ + public static $blacklistedClassNames = array( + 'File_Iterator' => 1, + 'PHP_CodeCoverage' => 1, + 'PHP_Invoker' => 1, + 'PHP_Timer' => 1, + 'PHP_Token' => 1, + 'PHPUnit_Framework_TestCase' => 2, + 'PHPUnit_Extensions_Database_TestCase' => 2, + 'PHPUnit_Framework_MockObject_Generator' => 2, + 'PHPUnit_Extensions_SeleniumTestCase' => 2, + 'PHPUnit_Extensions_Story_TestCase' => 2, + 'Text_Template' => 1, + 'Symfony\Component\Yaml\Yaml' => 1, + 'SebastianBergmann\Diff\Diff' => 1, + 'SebastianBergmann\Environment\Runtime' => 1, + 'SebastianBergmann\Comparator\Comparator' => 1, + 'SebastianBergmann\Exporter\Exporter' => 1, + 'SebastianBergmann\RecursionContext\Context' => 1, + 'SebastianBergmann\Version' => 1, + 'Composer\Autoload\ClassLoader' => 1, + 'Doctrine\Instantiator\Instantiator' => 1 + ); + + /** + * @var array + */ + private static $directories; + + /** + * @return array + * @since Method available since Release 4.1.0 + */ + public function getBlacklistedDirectories() + { + $this->initialize(); + + return self::$directories; + } + + /** + * @param string $file + * @return boolean + */ + public function isBlacklisted($file) + { + if (defined('PHPUNIT_TESTSUITE')) { + return false; + } + + $this->initialize(); + + foreach (self::$directories as $directory) { + if (strpos($file, $directory) === 0) { + return true; + } + } + + return false; + } + + private function initialize() + { + if (self::$directories === null) { + self::$directories = array(); + + foreach (self::$blacklistedClassNames as $className => $parent) { + if (!class_exists($className)) { + continue; + } + + $reflector = new ReflectionClass($className); + $directory = $reflector->getFileName(); + + for ($i = 0; $i < $parent; $i++) { + $directory = dirname($directory); + } + + self::$directories[] = $directory; + } + + // Hide process isolation workaround on Windows. + // @see PHPUnit_Util_PHP::factory() + // @see PHPUnit_Util_PHP_Windows::process() + if (DIRECTORY_SEPARATOR === '\\') { + // tempnam() prefix is limited to first 3 chars. + // @see http://php.net/manual/en/function.tempnam.php + self::$directories[] = sys_get_temp_dir() . '\\PHP'; + } + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * XML helpers. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_XML +{ + /** + * Escapes a string for the use in XML documents + * Any Unicode character is allowed, excluding the surrogate blocks, FFFE, + * and FFFF (not even as character reference). + * See http://www.w3.org/TR/xml/#charsets + * + * @param string $string + * @return string + * @author Kore Nordmann + * @since Method available since Release 3.4.6 + */ + public static function prepareString($string) + { + return preg_replace( + '/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]/', + '', + htmlspecialchars( + PHPUnit_Util_String::convertToUtf8($string), ENT_QUOTES, 'UTF-8' + ) + ); + } + + /** + * Loads an XML (or HTML) file into a DOMDocument object. + * + * @param string $filename + * @param boolean $isHtml + * @param boolean $xinclude + * @param boolean $strict + * @return DOMDocument + * @since Method available since Release 3.3.0 + */ + public static function loadFile($filename, $isHtml = false, $xinclude = false, $strict = false) + { + $reporting = error_reporting(0); + $contents = file_get_contents($filename); + error_reporting($reporting); + + if ($contents === false) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not read "%s".', + $filename + ) + ); + } + + return self::load($contents, $isHtml, $filename, $xinclude, $strict); + } + + /** + * Load an $actual document into a DOMDocument. This is called + * from the selector assertions. + * + * If $actual is already a DOMDocument, it is returned with + * no changes. Otherwise, $actual is loaded into a new DOMDocument + * as either HTML or XML, depending on the value of $isHtml. If $isHtml is + * false and $xinclude is true, xinclude is performed on the loaded + * DOMDocument. + * + * Note: prior to PHPUnit 3.3.0, this method loaded a file and + * not a string as it currently does. To load a file into a + * DOMDocument, use loadFile() instead. + * + * @param string|DOMDocument $actual + * @param boolean $isHtml + * @param string $filename + * @param boolean $xinclude + * @param boolean $strict + * @return DOMDocument + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @author Tobias Schlitt + */ + public static function load($actual, $isHtml = false, $filename = '', $xinclude = false, $strict = false) + { + if ($actual instanceof DOMDocument) { + return $actual; + } + + // Required for XInclude on Windows. + if ($xinclude) { + $cwd = getcwd(); + chdir(dirname($filename)); + } + + $document = new DOMDocument; + + $internal = libxml_use_internal_errors(true); + $message = ''; + $reporting = error_reporting(0); + + if ('' !== $filename) { + // Necessary for xinclude + $document->documentURI = $filename; + } + + if ($isHtml) { + $loaded = $document->loadHTML($actual); + } else { + $loaded = $document->loadXML($actual); + } + + if (!$isHtml && $xinclude) { + $document->xinclude(); + } + + foreach (libxml_get_errors() as $error) { + $message .= "\n" . $error->message; + } + + libxml_use_internal_errors($internal); + error_reporting($reporting); + + if ($xinclude) { + chdir($cwd); + } + + if ($loaded === false || ($strict && $message !== '')) { + if ($filename !== '') { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not load "%s".%s', + $filename, + $message != '' ? "\n" . $message : '' + ) + ); + } else { + throw new PHPUnit_Framework_Exception($message); + } + } + + return $document; + } + + /** + * + * + * @param DOMNode $node + * @return string + * @since Method available since Release 3.4.0 + */ + public static function nodeToText(DOMNode $node) + { + if ($node->childNodes->length == 1) { + return $node->nodeValue; + } + + $result = ''; + + foreach ($node->childNodes as $childNode) { + $result .= $node->ownerDocument->saveXML($childNode); + } + + return $result; + } + + /** + * + * + * @param DOMNode $node + * @since Method available since Release 3.3.0 + * @author Mattis Stordalen Flister + */ + public static function removeCharacterDataNodes(DOMNode $node) + { + if ($node->hasChildNodes()) { + for ($i = $node->childNodes->length - 1; $i >= 0; $i--) { + if (($child = $node->childNodes->item($i)) instanceof DOMCharacterData) { + $node->removeChild($child); + } + } + } + } + + /** + * "Convert" a DOMElement object into a PHP variable. + * + * @param DOMElement $element + * @return mixed + * @since Method available since Release 3.4.0 + */ + public static function xmlToVariable(DOMElement $element) + { + $variable = null; + + switch ($element->tagName) { + case 'array': { + $variable = array(); + + foreach ($element->getElementsByTagName('element') as $element) { + $value = self::xmlToVariable($element->childNodes->item(1)); + + if ($element->hasAttribute('key')) { + $variable[(string) $element->getAttribute('key')] = $value; + } else { + $variable[] = $value; + } + } + } + break; + + case 'object': { + $className = $element->getAttribute('class'); + + if ($element->hasChildNodes()) { + $arguments = $element->childNodes->item(1)->childNodes; + $constructorArgs = array(); + + foreach ($arguments as $argument) { + if ($argument instanceof DOMElement) { + $constructorArgs[] = self::xmlToVariable($argument); + } + } + + $class = new ReflectionClass($className); + $variable = $class->newInstanceArgs($constructorArgs); + } else { + $variable = new $className; + } + } + break; + + case 'boolean': { + $variable = $element->nodeValue == 'true' ? true : false; + } + break; + + case 'integer': + case 'double': + case 'string': { + $variable = $element->nodeValue; + + settype($variable, $element->tagName); + } + break; + } + + return $variable; + } + + /** + * Validate list of keys in the associative array. + * + * @param array $hash + * @param array $validKeys + * @return array + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function assertValidKeys(array $hash, array $validKeys) + { + $valids = array(); + + // Normalize validation keys so that we can use both indexed and + // associative arrays. + foreach ($validKeys as $key => $val) { + is_int($key) ? $valids[$val] = null : $valids[$key] = $val; + } + + $validKeys = array_keys($valids); + + // Check for invalid keys. + foreach ($hash as $key => $value) { + if (!in_array($key, $validKeys)) { + $unknown[] = $key; + } + } + + if (!empty($unknown)) { + throw new PHPUnit_Framework_Exception( + 'Unknown key(s): ' . implode(', ', $unknown) + ); + } + + // Add default values for any valid keys that are empty. + foreach ($valids as $key => $value) { + if (!isset($hash[$key])) { + $hash[$key] = $value; + } + } + + return $hash; + } + + /** + * Parse a CSS selector into an associative array suitable for + * use with findNodes(). + * + * @param string $selector + * @param mixed $content + * @return array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + public static function convertSelectToTag($selector, $content = true) + { + $selector = trim(preg_replace("/\s+/", " ", $selector)); + + // substitute spaces within attribute value + while (preg_match('/\[[^\]]+"[^"]+\s[^"]+"\]/', $selector)) { + $selector = preg_replace( + '/(\[[^\]]+"[^"]+)\s([^"]+"\])/', "$1__SPACE__$2", $selector + ); + } + + if (strstr($selector, ' ')) { + $elements = explode(' ', $selector); + } else { + $elements = array($selector); + } + + $previousTag = array(); + + foreach (array_reverse($elements) as $element) { + $element = str_replace('__SPACE__', ' ', $element); + + // child selector + if ($element == '>') { + $previousTag = array('child' => $previousTag['descendant']); + continue; + } + + // adjacent-sibling selector + if ($element == '+') { + $previousTag = array('adjacent-sibling' => $previousTag['descendant']); + continue; + } + + $tag = array(); + + // match element tag + preg_match("/^([^\.#\[]*)/", $element, $eltMatches); + + if (!empty($eltMatches[1])) { + $tag['tag'] = $eltMatches[1]; + } + + // match attributes (\[[^\]]*\]*), ids (#[^\.#\[]*), + // and classes (\.[^\.#\[]*)) + preg_match_all( + "/(\[[^\]]*\]*|#[^\.#\[]*|\.[^\.#\[]*)/", $element, $matches + ); + + if (!empty($matches[1])) { + $classes = array(); + $attrs = array(); + + foreach ($matches[1] as $match) { + // id matched + if (substr($match, 0, 1) == '#') { + $tag['id'] = substr($match, 1); + } // class matched + elseif (substr($match, 0, 1) == '.') { + $classes[] = substr($match, 1); + } // attribute matched + elseif (substr($match, 0, 1) == '[' && + substr($match, -1, 1) == ']') { + $attribute = substr($match, 1, strlen($match) - 2); + $attribute = str_replace('"', '', $attribute); + + // match single word + if (strstr($attribute, '~=')) { + list($key, $value) = explode('~=', $attribute); + $value = "regexp:/.*\b$value\b.*/"; + } // match substring + elseif (strstr($attribute, '*=')) { + list($key, $value) = explode('*=', $attribute); + $value = "regexp:/.*$value.*/"; + } // exact match + else { + list($key, $value) = explode('=', $attribute); + } + + $attrs[$key] = $value; + } + } + + if ($classes) { + $tag['class'] = join(' ', $classes); + } + + if ($attrs) { + $tag['attributes'] = $attrs; + } + } + + // tag content + if (is_string($content)) { + $tag['content'] = $content; + } + + // determine previous child/descendants + if (!empty($previousTag['descendant'])) { + $tag['descendant'] = $previousTag['descendant']; + } elseif (!empty($previousTag['child'])) { + $tag['child'] = $previousTag['child']; + } elseif (!empty($previousTag['adjacent-sibling'])) { + $tag['adjacent-sibling'] = $previousTag['adjacent-sibling']; + unset($tag['content']); + } + + $previousTag = array('descendant' => $tag); + } + + return $tag; + } + + /** + * Parse an $actual document and return an array of DOMNodes + * matching the CSS $selector. If an error occurs, it will + * return false. + * + * To only return nodes containing a certain content, give + * the $content to match as a string. Otherwise, setting + * $content to true will return all nodes matching $selector. + * + * The $actual document may be a DOMDocument or a string + * containing XML or HTML, identified by $isHtml. + * + * @param array $selector + * @param string $content + * @param mixed $actual + * @param boolean $isHtml + * @return boolean|array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @author Tobias Schlitt + */ + public static function cssSelect($selector, $content, $actual, $isHtml = true) + { + $matcher = self::convertSelectToTag($selector, $content); + $dom = self::load($actual, $isHtml); + $tags = self::findNodes($dom, $matcher, $isHtml); + + return $tags; + } + + /** + * Parse out the options from the tag using DOM object tree. + * + * @param DOMDocument $dom + * @param array $options + * @param boolean $isHtml + * @return array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + * @author Tobias Schlitt + */ + public static function findNodes(DOMDocument $dom, array $options, $isHtml = true) + { + $valid = array( + 'id', 'class', 'tag', 'content', 'attributes', 'parent', + 'child', 'ancestor', 'descendant', 'children', 'adjacent-sibling' + ); + + $filtered = array(); + $options = self::assertValidKeys($options, $valid); + + // find the element by id + if ($options['id']) { + $options['attributes']['id'] = $options['id']; + } + + if ($options['class']) { + $options['attributes']['class'] = $options['class']; + } + + // find the element by a tag type + if ($options['tag']) { + if ($isHtml) { + $elements = self::getElementsByCaseInsensitiveTagName( + $dom, $options['tag'] + ); + } else { + $elements = $dom->getElementsByTagName($options['tag']); + } + + foreach ($elements as $element) { + $nodes[] = $element; + } + + if (empty($nodes)) { + return false; + } + } // no tag selected, get them all + else { + $tags = array( + 'a', 'abbr', 'acronym', 'address', 'area', 'b', 'base', 'bdo', + 'big', 'blockquote', 'body', 'br', 'button', 'caption', 'cite', + 'code', 'col', 'colgroup', 'dd', 'del', 'div', 'dfn', 'dl', + 'dt', 'em', 'fieldset', 'form', 'frame', 'frameset', 'h1', 'h2', + 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'i', 'iframe', + 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'link', + 'map', 'meta', 'noframes', 'noscript', 'object', 'ol', 'optgroup', + 'option', 'p', 'param', 'pre', 'q', 'samp', 'script', 'select', + 'small', 'span', 'strong', 'style', 'sub', 'sup', 'table', + 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', + 'tr', 'tt', 'ul', 'var', + // HTML5 + 'article', 'aside', 'audio', 'bdi', 'canvas', 'command', + 'datalist', 'details', 'dialog', 'embed', 'figure', 'figcaption', + 'footer', 'header', 'hgroup', 'keygen', 'mark', 'meter', 'nav', + 'output', 'progress', 'ruby', 'rt', 'rp', 'track', 'section', + 'source', 'summary', 'time', 'video', 'wbr' + ); + + foreach ($tags as $tag) { + if ($isHtml) { + $elements = self::getElementsByCaseInsensitiveTagName( + $dom, $tag + ); + } else { + $elements = $dom->getElementsByTagName($tag); + } + + foreach ($elements as $element) { + $nodes[] = $element; + } + } + + if (empty($nodes)) { + return false; + } + } + + // filter by attributes + if ($options['attributes']) { + foreach ($nodes as $node) { + $invalid = false; + + foreach ($options['attributes'] as $name => $value) { + // match by regexp if like "regexp:/foo/i" + if (preg_match('/^regexp\s*:\s*(.*)/i', $value, $matches)) { + if (!preg_match($matches[1], $node->getAttribute($name))) { + $invalid = true; + } + } // class can match only a part + elseif ($name == 'class') { + // split to individual classes + $findClasses = explode( + ' ', preg_replace("/\s+/", " ", $value) + ); + + $allClasses = explode( + ' ', + preg_replace("/\s+/", " ", $node->getAttribute($name)) + ); + + // make sure each class given is in the actual node + foreach ($findClasses as $findClass) { + if (!in_array($findClass, $allClasses)) { + $invalid = true; + } + } + } // match by exact string + else { + if ($node->getAttribute($name) != $value) { + $invalid = true; + } + } + } + + // if every attribute given matched + if (!$invalid) { + $filtered[] = $node; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by content + if ($options['content'] !== null) { + foreach ($nodes as $node) { + $invalid = false; + + // match by regexp if like "regexp:/foo/i" + if (preg_match('/^regexp\s*:\s*(.*)/i', $options['content'], $matches)) { + if (!preg_match($matches[1], self::getNodeText($node))) { + $invalid = true; + } + } // match empty string + elseif ($options['content'] === '') { + if (self::getNodeText($node) !== '') { + $invalid = true; + } + } // match by exact string + elseif (strstr(self::getNodeText($node), $options['content']) === false) { + $invalid = true; + } + + if (!$invalid) { + $filtered[] = $node; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by parent node + if ($options['parent']) { + $parentNodes = self::findNodes($dom, $options['parent'], $isHtml); + $parentNode = isset($parentNodes[0]) ? $parentNodes[0] : null; + + foreach ($nodes as $node) { + if ($parentNode !== $node->parentNode) { + continue; + } + + $filtered[] = $node; + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by child node + if ($options['child']) { + $childNodes = self::findNodes($dom, $options['child'], $isHtml); + $childNodes = !empty($childNodes) ? $childNodes : array(); + + foreach ($nodes as $node) { + foreach ($node->childNodes as $child) { + foreach ($childNodes as $childNode) { + if ($childNode === $child) { + $filtered[] = $node; + } + } + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by adjacent-sibling + if ($options['adjacent-sibling']) { + $adjacentSiblingNodes = self::findNodes($dom, $options['adjacent-sibling'], $isHtml); + $adjacentSiblingNodes = !empty($adjacentSiblingNodes) ? $adjacentSiblingNodes : array(); + + foreach ($nodes as $node) { + $sibling = $node; + + while ($sibling = $sibling->nextSibling) { + if ($sibling->nodeType !== XML_ELEMENT_NODE) { + continue; + } + + foreach ($adjacentSiblingNodes as $adjacentSiblingNode) { + if ($sibling === $adjacentSiblingNode) { + $filtered[] = $node; + break; + } + } + + break; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by ancestor + if ($options['ancestor']) { + $ancestorNodes = self::findNodes($dom, $options['ancestor'], $isHtml); + $ancestorNode = isset($ancestorNodes[0]) ? $ancestorNodes[0] : null; + + foreach ($nodes as $node) { + $parent = $node->parentNode; + + while ($parent && $parent->nodeType != XML_HTML_DOCUMENT_NODE) { + if ($parent === $ancestorNode) { + $filtered[] = $node; + } + + $parent = $parent->parentNode; + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by descendant + if ($options['descendant']) { + $descendantNodes = self::findNodes($dom, $options['descendant'], $isHtml); + $descendantNodes = !empty($descendantNodes) ? $descendantNodes : array(); + + foreach ($nodes as $node) { + foreach (self::getDescendants($node) as $descendant) { + foreach ($descendantNodes as $descendantNode) { + if ($descendantNode === $descendant) { + $filtered[] = $node; + } + } + } + } + + $nodes = $filtered; + $filtered = array(); + + if (empty($nodes)) { + return false; + } + } + + // filter by children + if ($options['children']) { + $validChild = array('count', 'greater_than', 'less_than', 'only'); + $childOptions = self::assertValidKeys( + $options['children'], $validChild + ); + + foreach ($nodes as $node) { + $childNodes = $node->childNodes; + + foreach ($childNodes as $childNode) { + if ($childNode->nodeType !== XML_CDATA_SECTION_NODE && + $childNode->nodeType !== XML_TEXT_NODE) { + $children[] = $childNode; + } + } + + // we must have children to pass this filter + if (!empty($children)) { + // exact count of children + if ($childOptions['count'] !== null) { + if (count($children) !== $childOptions['count']) { + break; + } + } // range count of children + elseif ($childOptions['less_than'] !== null && + $childOptions['greater_than'] !== null) { + if (count($children) >= $childOptions['less_than'] || + count($children) <= $childOptions['greater_than']) { + break; + } + } // less than a given count + elseif ($childOptions['less_than'] !== null) { + if (count($children) >= $childOptions['less_than']) { + break; + } + } // more than a given count + elseif ($childOptions['greater_than'] !== null) { + if (count($children) <= $childOptions['greater_than']) { + break; + } + } + + // match each child against a specific tag + if ($childOptions['only']) { + $onlyNodes = self::findNodes( + $dom, $childOptions['only'], $isHtml + ); + + // try to match each child to one of the 'only' nodes + foreach ($children as $child) { + $matched = false; + + foreach ($onlyNodes as $onlyNode) { + if ($onlyNode === $child) { + $matched = true; + } + } + + if (!$matched) { + break 2; + } + } + } + + $filtered[] = $node; + } + } + + $nodes = $filtered; + + if (empty($nodes)) { + return; + } + } + + // return the first node that matches all criteria + return !empty($nodes) ? $nodes : array(); + } + + /** + * Recursively get flat array of all descendants of this node. + * + * @param DOMNode $node + * @return array + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + protected static function getDescendants(DOMNode $node) + { + $allChildren = array(); + $childNodes = $node->childNodes ? $node->childNodes : array(); + + foreach ($childNodes as $child) { + if ($child->nodeType === XML_CDATA_SECTION_NODE || + $child->nodeType === XML_TEXT_NODE) { + continue; + } + + $children = self::getDescendants($child); + $allChildren = array_merge($allChildren, $children, array($child)); + } + + return isset($allChildren) ? $allChildren : array(); + } + + /** + * Gets elements by case insensitive tagname. + * + * @param DOMDocument $dom + * @param string $tag + * @return DOMNodeList + * @since Method available since Release 3.4.0 + */ + protected static function getElementsByCaseInsensitiveTagName(DOMDocument $dom, $tag) + { + $elements = $dom->getElementsByTagName(strtolower($tag)); + + if ($elements->length == 0) { + $elements = $dom->getElementsByTagName(strtoupper($tag)); + } + + return $elements; + } + + /** + * Get the text value of this node's child text node. + * + * @param DOMNode $node + * @return string + * @since Method available since Release 3.3.0 + * @author Mike Naberezny + * @author Derek DeVries + */ + protected static function getNodeText(DOMNode $node) + { + if (!$node->childNodes instanceof DOMNodeList) { + return ''; + } + + $result = ''; + + foreach ($node->childNodes as $childNode) { + if ($childNode->nodeType === XML_TEXT_NODE || + $childNode->nodeType === XML_CDATA_SECTION_NODE) { + $result .= trim($childNode->data) . ' '; + } else { + $result .= self::getNodeText($childNode); + } + } + + return str_replace(' ', ' ', $result); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Utility class that can print to STDOUT or write to a file. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Util_Printer +{ + /** + * If true, flush output after every write. + * + * @var boolean + */ + protected $autoFlush = false; + + /** + * @var resource + */ + protected $out; + + /** + * @var string + */ + protected $outTarget; + + /** + * @var boolean + */ + protected $printsHTML = false; + + /** + * Constructor. + * + * @param mixed $out + * @throws PHPUnit_Framework_Exception + */ + public function __construct($out = null) + { + if ($out !== null) { + if (is_string($out)) { + if (strpos($out, 'socket://') === 0) { + $out = explode(':', str_replace('socket://', '', $out)); + + if (sizeof($out) != 2) { + throw new PHPUnit_Framework_Exception; + } + + $this->out = fsockopen($out[0], $out[1]); + } else { + if (strpos($out, 'php://') === false && + !is_dir(dirname($out))) { + mkdir(dirname($out), 0777, true); + } + + $this->out = fopen($out, 'wt'); + } + + $this->outTarget = $out; + } else { + $this->out = $out; + } + } + } + + /** + * Flush buffer, optionally tidy up HTML, and close output if it's not to a php stream + */ + public function flush() + { + if ($this->out && strncmp($this->outTarget, 'php://', 6) !== 0) { + fclose($this->out); + } + + if ($this->printsHTML === true && + $this->outTarget !== null && + strpos($this->outTarget, 'php://') !== 0 && + strpos($this->outTarget, 'socket://') !== 0 && + extension_loaded('tidy')) { + file_put_contents( + $this->outTarget, + tidy_repair_file( + $this->outTarget, array('indent' => true, 'wrap' => 0), 'utf8' + ) + ); + } + } + + /** + * Performs a safe, incremental flush. + * + * Do not confuse this function with the flush() function of this class, + * since the flush() function may close the file being written to, rendering + * the current object no longer usable. + * + * @since Method available since Release 3.3.0 + */ + public function incrementalFlush() + { + if ($this->out) { + fflush($this->out); + } else { + flush(); + } + } + + /** + * @param string $buffer + */ + public function write($buffer) + { + if ($this->out) { + fwrite($this->out, $buffer); + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } else { + if (PHP_SAPI != 'cli') { + $buffer = htmlspecialchars($buffer); + } + + print $buffer; + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } + } + + /** + * Check auto-flush mode. + * + * @return boolean + * @since Method available since Release 3.3.0 + */ + public function getAutoFlush() + { + return $this->autoFlush; + } + + /** + * Set auto-flushing mode. + * + * If set, *incremental* flushes will be done after each write. This should + * not be confused with the different effects of this class' flush() method. + * + * @param boolean $autoFlush + * @since Method available since Release 3.3.0 + */ + public function setAutoFlush($autoFlush) + { + if (is_bool($autoFlush)) { + $this->autoFlush = $autoFlush; + } else { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Command-line options parsing class. + * + * @package PHPUnit + * @subpackage Util + * @author Andrei Zmievski + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Getopt +{ + public static function getopt(array $args, $short_options, $long_options = null) + { + if (empty($args)) { + return array(array(), array()); + } + + $opts = array(); + $non_opts = array(); + + if ($long_options) { + sort($long_options); + } + + if (isset($args[0][0]) && $args[0][0] != '-') { + array_shift($args); + } + + reset($args); + array_map('trim', $args); + + while (list($i, $arg) = each($args)) { + if ($arg == '') { + continue; + } + + if ($arg == '--') { + $non_opts = array_merge($non_opts, array_slice($args, $i + 1)); + break; + } + + if ($arg[0] != '-' || + (strlen($arg) > 1 && $arg[1] == '-' && !$long_options)) { + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; + } elseif (strlen($arg) > 1 && $arg[1] == '-') { + self::parseLongOption( + substr($arg, 2), $long_options, $opts, $args + ); + } else { + self::parseShortOption( + substr($arg, 1), $short_options, $opts, $args + ); + } + } + + return array($opts, $non_opts); + } + + protected static function parseShortOption($arg, $short_options, &$opts, &$args) + { + $argLen = strlen($arg); + + for ($i = 0; $i < $argLen; $i++) { + $opt = $arg[$i]; + $opt_arg = null; + + if (($spec = strstr($short_options, $opt)) === false || + $arg[$i] == ':') { + throw new PHPUnit_Framework_Exception( + "unrecognized option -- $opt" + ); + } + + if (strlen($spec) > 1 && $spec[1] == ':') { + if (strlen($spec) > 2 && $spec[2] == ':') { + if ($i + 1 < $argLen) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } + } else { + if ($i + 1 < $argLen) { + $opts[] = array($opt, substr($arg, $i + 1)); + break; + } elseif (list(, $opt_arg) = each($args)) { + } else { + throw new PHPUnit_Framework_Exception( + "option requires an argument -- $opt" + ); + } + } + } + + $opts[] = array($opt, $opt_arg); + } + } + + protected static function parseLongOption($arg, $long_options, &$opts, &$args) + { + $count = count($long_options); + $list = explode('=', $arg); + $opt = $list[0]; + $opt_arg = null; + + if (count($list) > 1) { + $opt_arg = $list[1]; + } + + $opt_len = strlen($opt); + + for ($i = 0; $i < $count; $i++) { + $long_opt = $long_options[$i]; + $opt_start = substr($long_opt, 0, $opt_len); + + if ($opt_start != $opt) { + continue; + } + + $opt_rest = substr($long_opt, $opt_len); + + if ($opt_rest != '' && $opt[0] != '=' && $i + 1 < $count && + $opt == substr($long_options[$i+1], 0, $opt_len)) { + throw new PHPUnit_Framework_Exception( + "option --$opt is ambiguous" + ); + } + + if (substr($long_opt, -1) == '=') { + if (substr($long_opt, -2) != '==') { + if (!strlen($opt_arg) && + !(list(, $opt_arg) = each($args))) { + throw new PHPUnit_Framework_Exception( + "option --$opt requires an argument" + ); + } + } + } elseif ($opt_arg) { + throw new PHPUnit_Framework_Exception( + "option --$opt doesn't allow an argument" + ); + } + + $full_option = '--' . preg_replace('/={1,2}$/', '', $long_opt); + $opts[] = array($full_option, $opt_arg); + + return; + } + + throw new PHPUnit_Framework_Exception("unrecognized option --$opt"); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +// Workaround for http://bugs.php.net/bug.php?id=47987, +// see https://github.com/sebastianbergmann/phpunit/issues#issue/125 for details +require_once __DIR__ . '/../Framework/Error.php'; +require_once __DIR__ . '/../Framework/Error/Notice.php'; +require_once __DIR__ . '/../Framework/Error/Warning.php'; +require_once __DIR__ . '/../Framework/Error/Deprecated.php'; + +/** + * Error handler that converts PHP errors and warnings to exceptions. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.3.0 + */ +class PHPUnit_Util_ErrorHandler +{ + protected static $errorStack = array(); + + /** + * Returns the error stack. + * + * @return array + */ + public static function getErrorStack() + { + return self::$errorStack; + } + + /** + * @param integer $errno + * @param string $errstr + * @param string $errfile + * @param integer $errline + * @throws PHPUnit_Framework_Error + */ + public static function handleError($errno, $errstr, $errfile, $errline) + { + if (!($errno & error_reporting())) { + return false; + } + + self::$errorStack[] = array($errno, $errstr, $errfile, $errline); + + $trace = debug_backtrace(false); + array_shift($trace); + + foreach ($trace as $frame) { + if ($frame['function'] == '__toString') { + return false; + } + } + + if ($errno == E_NOTICE || $errno == E_USER_NOTICE || $errno == E_STRICT) { + if (PHPUnit_Framework_Error_Notice::$enabled !== true) { + return false; + } + + $exception = 'PHPUnit_Framework_Error_Notice'; + } elseif ($errno == E_WARNING || $errno == E_USER_WARNING) { + if (PHPUnit_Framework_Error_Warning::$enabled !== true) { + return false; + } + + $exception = 'PHPUnit_Framework_Error_Warning'; + } elseif ($errno == E_DEPRECATED || $errno == E_USER_DEPRECATED) { + if (PHPUnit_Framework_Error_Deprecated::$enabled !== true) { + return false; + } + + $exception = 'PHPUnit_Framework_Error_Deprecated'; + } else { + $exception = 'PHPUnit_Framework_Error'; + } + + throw new $exception($errstr, $errno, $errfile, $errline); + } + + /** + * Registers an error handler and returns a function that will restore + * the previous handler when invoked + * @param integer $severity PHP predefined error constant + * @link http://www.php.net/manual/en/errorfunc.constants.php + * @throws Exception if event of specified severity is emitted + */ + public static function handleErrorOnce($severity = E_WARNING) + { + $terminator = function () { + static $expired = false; + if (!$expired) { + $expired = true; + // cleans temporary error handler + return restore_error_handler(); + } + }; + + set_error_handler(function ($errno, $errstr) use ($severity) { + if ($errno === $severity) { + return; + } + + return false; + }); + + return $terminator; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Utility class for code filtering. + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.0.0 + */ +class PHPUnit_Util_Filter +{ + /** + * Filters stack frames from PHPUnit classes. + * + * @param Exception $e + * @param boolean $asString + * @return string + */ + public static function getFilteredStacktrace(Exception $e, $asString = true) + { + $prefix = false; + $script = realpath($GLOBALS['_SERVER']['SCRIPT_NAME']); + + if (defined('__PHPUNIT_PHAR_ROOT__')) { + $prefix = __PHPUNIT_PHAR_ROOT__; + } + + if ($asString === true) { + $filteredStacktrace = ''; + } else { + $filteredStacktrace = array(); + } + + if ($e instanceof PHPUnit_Framework_SyntheticError) { + $eTrace = $e->getSyntheticTrace(); + $eFile = $e->getSyntheticFile(); + $eLine = $e->getSyntheticLine(); + } elseif ($e instanceof PHPUnit_Framework_Exception) { + $eTrace = $e->getSerializableTrace(); + $eFile = $e->getFile(); + $eLine = $e->getLine(); + } else { + if ($e->getPrevious()) { + $e = $e->getPrevious(); + } + $eTrace = $e->getTrace(); + $eFile = $e->getFile(); + $eLine = $e->getLine(); + } + + if (!self::frameExists($eTrace, $eFile, $eLine)) { + array_unshift( + $eTrace, array('file' => $eFile, 'line' => $eLine) + ); + } + + $blacklist = new PHPUnit_Util_Blacklist; + + foreach ($eTrace as $frame) { + if (isset($frame['file']) && is_file($frame['file']) && + !$blacklist->isBlacklisted($frame['file']) && + ($prefix === false || strpos($frame['file'], $prefix) !== 0) && + $frame['file'] !== $script) { + if ($asString === true) { + $filteredStacktrace .= sprintf( + "%s:%s\n", + $frame['file'], + isset($frame['line']) ? $frame['line'] : '?' + ); + } else { + $filteredStacktrace[] = $frame; + } + } + } + + return $filteredStacktrace; + } + + /** + * @param array $trace + * @param string $file + * @param int $line + * @return boolean + * @since Method available since Release 3.3.2 + */ + private static function frameExists(array $trace, $file, $line) + { + foreach ($trace as $frame) { + if (isset($frame['file']) && $frame['file'] == $file && + isset($frame['line']) && $frame['line'] == $line) { + return true; + } + } + + return false; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A TestListener that generates a logfile of the test execution in XML markup. + * + * The XML markup used is the same as the one that is used by the JUnit Ant task. + * + * @package PHPUnit + * @subpackage Util_Log + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 2.1.0 + */ +class PHPUnit_Util_Log_JUnit extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var DOMDocument + */ + protected $document; + + /** + * @var DOMElement + */ + protected $root; + + /** + * @var boolean + */ + protected $logIncompleteSkipped = false; + + /** + * @var boolean + */ + protected $writeDocument = true; + + /** + * @var DOMElement[] + */ + protected $testSuites = array(); + + /** + * @var integer[] + */ + protected $testSuiteTests = array(0); + + /** + * @var integer[] + */ + protected $testSuiteAssertions = array(0); + + /** + * @var integer[] + */ + protected $testSuiteErrors = array(0); + + /** + * @var integer[] + */ + protected $testSuiteFailures = array(0); + + /** + * @var integer[] + */ + protected $testSuiteTimes = array(0); + + /** + * @var integer + */ + protected $testSuiteLevel = 0; + + /** + * @var DOMElement + */ + protected $currentTestCase = null; + + /** + * @var boolean + */ + protected $attachCurrentTestCase = true; + + /** + * Constructor. + * + * @param mixed $out + * @param boolean $logIncompleteSkipped + */ + public function __construct($out = null, $logIncompleteSkipped = false) + { + $this->document = new DOMDocument('1.0', 'UTF-8'); + $this->document->formatOutput = true; + + $this->root = $this->document->createElement('testsuites'); + $this->document->appendChild($this->root); + + parent::__construct($out); + + $this->logIncompleteSkipped = $logIncompleteSkipped; + } + + /** + * Flush buffer and close output. + * + */ + public function flush() + { + if ($this->writeDocument === true) { + $this->write($this->getXML()); + } + + parent::flush(); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->currentTestCase !== null) { + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + $buffer = $test->toString() . "\n"; + } else { + $buffer = ''; + } + + $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . + "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e); + + $error = $this->document->createElement( + 'error', PHPUnit_Util_XML::prepareString($buffer) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + if ($this->currentTestCase !== null) { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($test instanceof PHPUnit_Framework_SelfDescribing) { + $buffer = $test->toString() . "\n"; + } else { + $buffer = ''; + } + + $buffer .= PHPUnit_Framework_TestFailure::exceptionToString($e) . + "\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e); + + $failure = $this->document->createElement( + 'failure', PHPUnit_Util_XML::prepareString($buffer) + ); + + $failure->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($failure); + + $this->testSuiteFailures[$this->testSuiteLevel]++; + } + } + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->logIncompleteSkipped && $this->currentTestCase !== null) { + $error = $this->document->createElement( + 'error', + PHPUnit_Util_XML::prepareString( + "Incomplete Test\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e) + ) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } else { + $this->attachCurrentTestCase = false; + } + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->logIncompleteSkipped && $this->currentTestCase !== null) { + $error = $this->document->createElement( + 'error', + PHPUnit_Util_XML::prepareString( + "Risky Test\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e) + ) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } else { + $this->attachCurrentTestCase = false; + } + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + if ($this->logIncompleteSkipped && $this->currentTestCase !== null) { + $error = $this->document->createElement( + 'error', + PHPUnit_Util_XML::prepareString( + "Skipped Test\n" . + PHPUnit_Util_Filter::getFilteredStacktrace($e) + ) + ); + + $error->setAttribute('type', get_class($e)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } else { + $this->attachCurrentTestCase = false; + } + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $testSuite = $this->document->createElement('testsuite'); + $testSuite->setAttribute('name', $suite->getName()); + + if (class_exists($suite->getName(), false)) { + try { + $class = new ReflectionClass($suite->getName()); + + $testSuite->setAttribute('file', $class->getFileName()); + } catch (ReflectionException $e) { + } + } + + if ($this->testSuiteLevel > 0) { + $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite); + } else { + $this->root->appendChild($testSuite); + } + + $this->testSuiteLevel++; + $this->testSuites[$this->testSuiteLevel] = $testSuite; + $this->testSuiteTests[$this->testSuiteLevel] = 0; + $this->testSuiteAssertions[$this->testSuiteLevel] = 0; + $this->testSuiteErrors[$this->testSuiteLevel] = 0; + $this->testSuiteFailures[$this->testSuiteLevel] = 0; + $this->testSuiteTimes[$this->testSuiteLevel] = 0; + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + * @since Method available since Release 2.2.0 + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'tests', $this->testSuiteTests[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'assertions', $this->testSuiteAssertions[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'failures', $this->testSuiteFailures[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'errors', $this->testSuiteErrors[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'time', sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel]) + ); + + if ($this->testSuiteLevel > 1) { + $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel]; + $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel]; + $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel]; + $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel]; + $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel]; + } + + $this->testSuiteLevel--; + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + $testCase = $this->document->createElement('testcase'); + $testCase->setAttribute('name', $test->getName()); + + if ($test instanceof PHPUnit_Framework_TestCase) { + $class = new ReflectionClass($test); + $methodName = $test->getName(); + + if ($class->hasMethod($methodName)) { + $method = $class->getMethod($test->getName()); + + $testCase->setAttribute('class', $class->getName()); + $testCase->setAttribute('file', $class->getFileName()); + $testCase->setAttribute('line', $method->getStartLine()); + } + } + + $this->currentTestCase = $testCase; + } + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if (!$test instanceof PHPUnit_Framework_Warning) { + if ($this->attachCurrentTestCase) { + if ($test instanceof PHPUnit_Framework_TestCase) { + $numAssertions = $test->getNumAssertions(); + $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions; + + $this->currentTestCase->setAttribute( + 'assertions', $numAssertions + ); + } + + $this->currentTestCase->setAttribute( + 'time', sprintf('%F', $time) + ); + + $this->testSuites[$this->testSuiteLevel]->appendChild( + $this->currentTestCase + ); + + $this->testSuiteTests[$this->testSuiteLevel]++; + $this->testSuiteTimes[$this->testSuiteLevel] += $time; + + if (method_exists($test, 'hasOutput') && $test->hasOutput()) { + $systemOut = $this->document->createElement('system-out'); + $systemOut->appendChild( + $this->document->createTextNode($test->getActualOutput()) + ); + $this->currentTestCase->appendChild($systemOut); + } + } + } + + $this->attachCurrentTestCase = true; + $this->currentTestCase = null; + } + + /** + * Returns the XML as a string. + * + * @return string + * @since Method available since Release 2.2.0 + */ + public function getXML() + { + return $this->document->saveXML(); + } + + /** + * Enables or disables the writing of the document + * in flush(). + * + * This is a "hack" needed for the integration of + * PHPUnit with Phing. + * + * @return string + * @since Method available since Release 2.2.0 + */ + public function setWriteDocument($flag) + { + if (is_bool($flag)) { + $this->writeDocument = $flag; + } + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A TestListener that generates a logfile of the + * test execution using the Test Anything Protocol (TAP). + * + * @package PHPUnit + * @subpackage Util_Log + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Log_TAP extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var integer + */ + protected $testNumber = 0; + + /** + * @var integer + */ + protected $testSuiteLevel = 0; + + /** + * @var boolean + */ + protected $testSuccessful = true; + + /** + * Constructor. + * + * @param mixed $out + * @throws PHPUnit_Framework_Exception + * @since Method available since Release 3.3.4 + */ + public function __construct($out = null) + { + parent::__construct($out); + $this->write("TAP version 13\n"); + } + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeNotOk($test, 'Error'); + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->writeNotOk($test, 'Failure'); + + $message = explode( + "\n", PHPUnit_Framework_TestFailure::exceptionToString($e) + ); + + $diagnostic = array( + 'message' => $message[0], + 'severity' => 'fail' + ); + + if ($e instanceof PHPUnit_Framework_ExpectationFailedException) { + $cf = $e->getComparisonFailure(); + + if ($cf !== null) { + $diagnostic['data'] = array( + 'got' => $cf->getActual(), + 'expected' => $cf->getExpected() + ); + } + } + + $yaml = new Symfony\Component\Yaml\Dumper; + + $this->write( + sprintf( + " ---\n%s ...\n", + $yaml->dump($diagnostic, 2, 2) + ) + ); + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeNotOk($test, '', 'TODO Incomplete Test'); + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->write( + sprintf( + "ok %d - # RISKY%s\n", + $this->testNumber, + $e->getMessage() != '' ? ' ' . $e->getMessage() : '' + ) + ); + + $this->testSuccessful = false; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 3.0.0 + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->write( + sprintf( + "ok %d - # SKIP%s\n", + $this->testNumber, + $e->getMessage() != '' ? ' ' . $e->getMessage() : '' + ) + ); + + $this->testSuccessful = false; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->testSuiteLevel++; + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->testSuiteLevel--; + + if ($this->testSuiteLevel == 0) { + $this->write(sprintf("1..%d\n", $this->testNumber)); + } + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->testNumber++; + $this->testSuccessful = true; + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($this->testSuccessful === true) { + $this->write( + sprintf( + "ok %d - %s\n", + $this->testNumber, + PHPUnit_Util_Test::describe($test) + ) + ); + } + } + + /** + * @param PHPUnit_Framework_Test $test + * @param string $prefix + * @param string $directive + */ + protected function writeNotOk(PHPUnit_Framework_Test $test, $prefix = '', $directive = '') + { + $this->write( + sprintf( + "not ok %d - %s%s%s\n", + $this->testNumber, + $prefix != '' ? $prefix . ': ' : '', + PHPUnit_Util_Test::describe($test), + $directive != '' ? ' # ' . $directive : '' + ) + ); + + $this->testSuccessful = false; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (!defined('JSON_PRETTY_PRINT')) { + define('JSON_PRETTY_PRINT', 128); +} + +/** + * A TestListener that generates JSON messages. + * + * @package PHPUnit + * @subpackage Util_Log + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.0.0 + */ +class PHPUnit_Util_Log_JSON extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener +{ + /** + * @var string + */ + protected $currentTestSuiteName = ''; + + /** + * @var string + */ + protected $currentTestName = ''; + + /** + * @var boolean + * @access private + */ + protected $currentTestPass = true; + + /** + * An error occurred. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase( + 'error', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace($e, false), + $e->getMessage(), + $test + ); + + $this->currentTestPass = false; + } + + /** + * A failure occurred. + * + * @param PHPUnit_Framework_Test $test + * @param PHPUnit_Framework_AssertionFailedError $e + * @param float $time + */ + public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) + { + $this->writeCase( + 'fail', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace($e, false), + $e->getMessage(), + $test + ); + + $this->currentTestPass = false; + } + + /** + * Incomplete test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase( + 'error', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace($e, false), + 'Incomplete Test: ' . $e->getMessage(), + $test + ); + + $this->currentTestPass = false; + } + + /** + * Risky test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + * @since Method available since Release 4.0.0 + */ + public function addRiskyTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase( + 'error', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace($e, false), + 'Risky Test: ' . $e->getMessage(), + $test + ); + + $this->currentTestPass = false; + } + + /** + * Skipped test. + * + * @param PHPUnit_Framework_Test $test + * @param Exception $e + * @param float $time + */ + public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) + { + $this->writeCase( + 'error', + $time, + PHPUnit_Util_Filter::getFilteredStacktrace($e, false), + 'Skipped Test: ' . $e->getMessage(), + $test + ); + + $this->currentTestPass = false; + } + + /** + * A testsuite started. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function startTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->currentTestSuiteName = $suite->getName(); + $this->currentTestName = ''; + + $this->write( + array( + 'event' => 'suiteStart', + 'suite' => $this->currentTestSuiteName, + 'tests' => count($suite) + ) + ); + } + + /** + * A testsuite ended. + * + * @param PHPUnit_Framework_TestSuite $suite + */ + public function endTestSuite(PHPUnit_Framework_TestSuite $suite) + { + $this->currentTestSuiteName = ''; + $this->currentTestName = ''; + } + + /** + * A test started. + * + * @param PHPUnit_Framework_Test $test + */ + public function startTest(PHPUnit_Framework_Test $test) + { + $this->currentTestName = PHPUnit_Util_Test::describe($test); + $this->currentTestPass = true; + + $this->write( + array( + 'event' => 'testStart', + 'suite' => $this->currentTestSuiteName, + 'test' => $this->currentTestName + ) + ); + } + + /** + * A test ended. + * + * @param PHPUnit_Framework_Test $test + * @param float $time + */ + public function endTest(PHPUnit_Framework_Test $test, $time) + { + if ($this->currentTestPass) { + $this->writeCase('pass', $time, array(), '', $test); + } + } + + /** + * @param string $status + * @param float $time + * @param array $trace + * @param string $message + * @param PHPUnit_Framework_TestCase|null $test + */ + protected function writeCase($status, $time, array $trace = array(), $message = '', $test = null) + { + $output = ''; + // take care of TestSuite producing error (e.g. by running into exception) as TestSuite doesn't have hasOutput + if ($test !== null && method_exists($test, 'hasOutput') && $test->hasOutput()) { + $output = $test->getActualOutput(); + } + $this->write( + array( + 'event' => 'test', + 'suite' => $this->currentTestSuiteName, + 'test' => $this->currentTestName, + 'status' => $status, + 'time' => $time, + 'trace' => $trace, + 'message' => PHPUnit_Util_String::convertToUtf8($message), + 'output' => $output, + ) + ); + } + + /** + * @param string $buffer + */ + public function write($buffer) + { + array_walk_recursive($buffer, function (&$input) { + if (is_string($input)) { + $input = PHPUnit_Util_String::convertToUtf8($input); + } + }); + + parent::write(json_encode($buffer, JSON_PRETTY_PRINT)); + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.4.0 + */ +class PHPUnit_Util_GlobalState +{ + /** + * @var array + */ + protected static $superGlobalArrays = array( + '_ENV', + '_POST', + '_GET', + '_COOKIE', + '_SERVER', + '_FILES', + '_REQUEST' + ); + + /** + * @var array + */ + protected static $superGlobalArraysLong = array( + 'HTTP_ENV_VARS', + 'HTTP_POST_VARS', + 'HTTP_GET_VARS', + 'HTTP_COOKIE_VARS', + 'HTTP_SERVER_VARS', + 'HTTP_POST_FILES' + ); + + public static function getIncludedFilesAsString() + { + return static::processIncludedFilesAsString(get_included_files()); + } + + public static function processIncludedFilesAsString(array $files) + { + $blacklist = new PHPUnit_Util_Blacklist; + $prefix = false; + $result = ''; + + if (defined('__PHPUNIT_PHAR__')) { + $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/'; + } + + for ($i = count($files) - 1; $i > 0; $i--) { + $file = $files[$i]; + + if ($prefix !== false && strpos($file, $prefix) === 0) { + continue; + } + + // Skip virtual file system protocols + if (preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) { + continue; + } + + if (!$blacklist->isBlacklisted($file) && is_file($file)) { + $result = 'require_once \'' . $file . "';\n" . $result; + } + } + + return $result; + } + + public static function getIniSettingsAsString() + { + $result = ''; + $iniSettings = ini_get_all(null, false); + + foreach ($iniSettings as $key => $value) { + $result .= sprintf( + '@ini_set(%s, %s);' . "\n", + self::exportVariable($key), + self::exportVariable($value) + ); + } + + return $result; + } + + public static function getConstantsAsString() + { + $constants = get_defined_constants(true); + $result = ''; + + if (isset($constants['user'])) { + foreach ($constants['user'] as $name => $value) { + $result .= sprintf( + 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", + $name, + $name, + self::exportVariable($value) + ); + } + } + + return $result; + } + + public static function getGlobalsAsString() + { + $result = ''; + $superGlobalArrays = self::getSuperGlobalArrays(); + + foreach ($superGlobalArrays as $superGlobalArray) { + if (isset($GLOBALS[$superGlobalArray]) && + is_array($GLOBALS[$superGlobalArray])) { + foreach (array_keys($GLOBALS[$superGlobalArray]) as $key) { + if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) { + continue; + } + + $result .= sprintf( + '$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n", + $superGlobalArray, + $key, + self::exportVariable($GLOBALS[$superGlobalArray][$key]) + ); + } + } + } + + $blacklist = $superGlobalArrays; + $blacklist[] = 'GLOBALS'; + + foreach (array_keys($GLOBALS) as $key) { + if (!in_array($key, $blacklist) && !$GLOBALS[$key] instanceof Closure) { + $result .= sprintf( + '$GLOBALS[\'%s\'] = %s;' . "\n", + $key, + self::exportVariable($GLOBALS[$key]) + ); + } + } + + return $result; + } + + protected static function getSuperGlobalArrays() + { + if (ini_get('register_long_arrays') == '1') { + return array_merge( + self::$superGlobalArrays, self::$superGlobalArraysLong + ); + } else { + return self::$superGlobalArrays; + } + } + + protected static function exportVariable($variable) + { + if (is_scalar($variable) || is_null($variable) || + (is_array($variable) && self::arrayOnlyContainsScalars($variable))) { + return var_export($variable, true); + } + return 'unserialize(' . + var_export(serialize($variable), true) . + ')'; + } + + protected static function arrayOnlyContainsScalars(array $array) + { + $result = true; + + foreach ($array as $element) { + if (is_array($element)) { + $result = self::arrayOnlyContainsScalars($element); + } elseif (!is_scalar($element) && !is_null($element)) { + $result = false; + } + + if ($result === false) { + break; + } + } + + return $result; + } +} + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * Wrapper for the PHPUnit XML configuration file. + * + * Example XML configuration file: + * + * + * + * + * + * + * /path/to/files + * /path/to/MyTest.php + * /path/to/files/exclude + * + * + * + * + * + * name + * + * + * name + * + * + * + * + * + * /path/to/files + * /path/to/file + * + * /path/to/files + * /path/to/file + * + * + * + * /path/to/files + * /path/to/file + * + * /path/to/files + * /path/to/file + * + * + * + * + * + * + * + * + * + * Sebastian + * + * + * 22 + * April + * 19.78 + * + * + * MyRelativeFile.php + * MyRelativeDir + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * . + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * @package PHPUnit + * @subpackage Util + * @author Sebastian Bergmann + * @copyright Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since Class available since Release 3.2.0 + */ +class PHPUnit_Util_Configuration +{ + private static $instances = array(); + + protected $document; + protected $xpath; + protected $filename; + + /** + * Loads a PHPUnit configuration file. + * + * @param string $filename + */ + protected function __construct($filename) + { + $this->filename = $filename; + $this->document = PHPUnit_Util_XML::loadFile($filename, false, true, true); + $this->xpath = new DOMXPath($this->document); + } + + /** + * @since Method available since Release 3.4.0 + */ + final private function __clone() + { + } + + /** + * Returns a PHPUnit configuration object. + * + * @param string $filename + * @return PHPUnit_Util_Configuration + * @since Method available since Release 3.4.0 + */ + public static function getInstance($filename) + { + $realpath = realpath($filename); + + if ($realpath === false) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Could not read "%s".', + $filename + ) + ); + } + + if (!isset(self::$instances[$realpath])) { + self::$instances[$realpath] = new PHPUnit_Util_Configuration($realpath); + } + + return self::$instances[$realpath]; + } + + /** + * Returns the realpath to the configuration file. + * + * @return string + * @since Method available since Release 3.6.0 + */ + public function getFilename() + { + return $this->filename; + } + + /** + * Returns the configuration for SUT filtering. + * + * @return array + * @since Method available since Release 3.2.1 + */ + public function getFilterConfiguration() + { + $addUncoveredFilesFromWhitelist = true; + $processUncoveredFilesFromWhitelist = false; + + $tmp = $this->xpath->query('filter/whitelist'); + + if ($tmp->length == 1) { + if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) { + $addUncoveredFilesFromWhitelist = $this->getBoolean( + (string) $tmp->item(0)->getAttribute( + 'addUncoveredFilesFromWhitelist' + ), + true + ); + } + + if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) { + $processUncoveredFilesFromWhitelist = $this->getBoolean( + (string) $tmp->item(0)->getAttribute( + 'processUncoveredFilesFromWhitelist' + ), + false + ); + } + } + + return array( + 'blacklist' => array( + 'include' => array( + 'directory' => $this->readFilterDirectories( + 'filter/blacklist/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/blacklist/file' + ) + ), + 'exclude' => array( + 'directory' => $this->readFilterDirectories( + 'filter/blacklist/exclude/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/blacklist/exclude/file' + ) + ) + ), + 'whitelist' => array( + 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist, + 'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist, + 'include' => array( + 'directory' => $this->readFilterDirectories( + 'filter/whitelist/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/whitelist/file' + ) + ), + 'exclude' => array( + 'directory' => $this->readFilterDirectories( + 'filter/whitelist/exclude/directory' + ), + 'file' => $this->readFilterFiles( + 'filter/whitelist/exclude/file' + ) + ) + ) + ); + } + + /** + * Returns the configuration for groups. + * + * @return array + * @since Method available since Release 3.2.1 + */ + public function getGroupConfiguration() + { + $groups = array( + 'include' => array(), + 'exclude' => array() + ); + + foreach ($this->xpath->query('groups/include/group') as $group) { + $groups['include'][] = (string) $group->nodeValue; + } + + foreach ($this->xpath->query('groups/exclude/group') as $group) { + $groups['exclude'][] = (string) $group->nodeValue; + } + + return $groups; + } + + /** + * Returns the configuration for listeners. + * + * @return array + * @since Method available since Release 3.4.0 + */ + public function getListenerConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('listeners/listener') as $listener) { + $class = (string) $listener->getAttribute('class'); + $file = ''; + $arguments = array(); + + if ($listener->getAttribute('file')) { + $file = $this->toAbsolutePath( + (string) $listener->getAttribute('file'), true + ); + } + + foreach ($listener->childNodes as $node) { + if ($node instanceof DOMElement && $node->tagName == 'arguments') { + foreach ($node->childNodes as $argument) { + if ($argument instanceof DOMElement) { + if ($argument->tagName == 'file' || + $argument->tagName == 'directory') { + $arguments[] = $this->toAbsolutePath((string) $argument->nodeValue); + } else { + $arguments[] = PHPUnit_Util_XML::xmlToVariable($argument); + } + } + } + } + } + + $result[] = array( + 'class' => $class, + 'file' => $file, + 'arguments' => $arguments + ); + } + + return $result; + } + + /** + * Returns the logging configuration. + * + * @return array + */ + public function getLoggingConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('logging/log') as $log) { + $type = (string) $log->getAttribute('type'); + $target = (string) $log->getAttribute('target'); + + if (!$target) { + continue; + } + + $target = $this->toAbsolutePath($target); + + if ($type == 'coverage-html') { + if ($log->hasAttribute('lowUpperBound')) { + $result['lowUpperBound'] = (string) $log->getAttribute('lowUpperBound'); + } + + if ($log->hasAttribute('highLowerBound')) { + $result['highLowerBound'] = (string) $log->getAttribute('highLowerBound'); + } + } elseif ($type == 'junit') { + if ($log->hasAttribute('logIncompleteSkipped')) { + $result['logIncompleteSkipped'] = $this->getBoolean( + (string) $log->getAttribute('logIncompleteSkipped'), + false + ); + } + } elseif ($type == 'coverage-text') { + if ($log->hasAttribute('showUncoveredFiles')) { + $result['coverageTextShowUncoveredFiles'] = $this->getBoolean( + (string) $log->getAttribute('showUncoveredFiles'), + false + ); + } + if ($log->hasAttribute('showOnlySummary')) { + $result['coverageTextShowOnlySummary'] = $this->getBoolean( + (string) $log->getAttribute('showOnlySummary'), + false + ); + } + } + + $result[$type] = $target; + } + + return $result; + } + + /** + * Returns the PHP configuration. + * + * @return array + * @since Method available since Release 3.2.1 + */ + public function getPHPConfiguration() + { + $result = array( + 'include_path' => array(), + 'ini' => array(), + 'const' => array(), + 'var' => array(), + 'env' => array(), + 'post' => array(), + 'get' => array(), + 'cookie' => array(), + 'server' => array(), + 'files' => array(), + 'request' => array() + ); + + foreach ($this->xpath->query('php/includePath') as $includePath) { + $path = (string) $includePath->nodeValue; + if ($path) { + $result['include_path'][] = $this->toAbsolutePath($path); + } + } + + foreach ($this->xpath->query('php/ini') as $ini) { + $name = (string) $ini->getAttribute('name'); + $value = (string) $ini->getAttribute('value'); + + $result['ini'][$name] = $value; + } + + foreach ($this->xpath->query('php/const') as $const) { + $name = (string) $const->getAttribute('name'); + $value = (string) $const->getAttribute('value'); + + $result['const'][$name] = $this->getBoolean($value, $value); + } + + foreach (array('var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) { + foreach ($this->xpath->query('php/' . $array) as $var) { + $name = (string) $var->getAttribute('name'); + $value = (string) $var->getAttribute('value'); + + $result[$array][$name] = $this->getBoolean($value, $value); + } + } + + return $result; + } + + /** + * Handles the PHP configuration. + * + * @since Method available since Release 3.2.20 + */ + public function handlePHPConfiguration() + { + $configuration = $this->getPHPConfiguration(); + + if (! empty($configuration['include_path'])) { + ini_set( + 'include_path', + implode(PATH_SEPARATOR, $configuration['include_path']) . + PATH_SEPARATOR . + ini_get('include_path') + ); + } + + foreach ($configuration['ini'] as $name => $value) { + if (defined($value)) { + $value = constant($value); + } + + ini_set($name, $value); + } + + foreach ($configuration['const'] as $name => $value) { + if (!defined($name)) { + define($name, $value); + } + } + + foreach (array('var', 'post', 'get', 'cookie', 'server', 'files', 'request') as $array) { + // See https://github.com/sebastianbergmann/phpunit/issues/277 + switch ($array) { + case 'var': + $target = &$GLOBALS; + break; + + case 'server': + $target = &$_SERVER; + break; + + default: + $target = &$GLOBALS['_' . strtoupper($array)]; + break; + } + + foreach ($configuration[$array] as $name => $value) { + $target[$name] = $value; + } + } + + foreach ($configuration['env'] as $name => $value) { + if (false === getenv($name)) { + putenv("{$name}={$value}"); + } + if (!isset($_ENV[$name])) { + $_ENV[$name] = $value; + } + } + } + + /** + * Returns the PHPUnit configuration. + * + * @return array + * @since Method available since Release 3.2.14 + */ + public function getPHPUnitConfiguration() + { + $result = array(); + $root = $this->document->documentElement; + + if ($root->hasAttribute('cacheTokens')) { + $result['cacheTokens'] = $this->getBoolean( + (string) $root->getAttribute('cacheTokens'), false + ); + } + + if ($root->hasAttribute('colors')) { + $result['colors'] = $this->getBoolean( + (string) $root->getAttribute('colors'), false + ); + } + + /** + * Issue #657 + */ + if ($root->hasAttribute('stderr')) { + $result['stderr'] = $this->getBoolean( + (string)$root->getAttribute('stderr'), false + ); + } + + if ($root->hasAttribute('backupGlobals')) { + $result['backupGlobals'] = $this->getBoolean( + (string) $root->getAttribute('backupGlobals'), true + ); + } + + if ($root->hasAttribute('backupStaticAttributes')) { + $result['backupStaticAttributes'] = $this->getBoolean( + (string) $root->getAttribute('backupStaticAttributes'), false + ); + } + + if ($root->getAttribute('bootstrap')) { + $result['bootstrap'] = $this->toAbsolutePath( + (string) $root->getAttribute('bootstrap') + ); + } + + if ($root->hasAttribute('convertErrorsToExceptions')) { + $result['convertErrorsToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertErrorsToExceptions'), true + ); + } + + if ($root->hasAttribute('convertNoticesToExceptions')) { + $result['convertNoticesToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertNoticesToExceptions'), true + ); + } + + if ($root->hasAttribute('convertWarningsToExceptions')) { + $result['convertWarningsToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertWarningsToExceptions'), true + ); + } + + if ($root->hasAttribute('forceCoversAnnotation')) { + $result['forceCoversAnnotation'] = $this->getBoolean( + (string) $root->getAttribute('forceCoversAnnotation'), false + ); + } + + if ($root->hasAttribute('mapTestClassNameToCoveredClassName')) { + $result['mapTestClassNameToCoveredClassName'] = $this->getBoolean( + (string) $root->getAttribute('mapTestClassNameToCoveredClassName'), + false + ); + } + + if ($root->hasAttribute('processIsolation')) { + $result['processIsolation'] = $this->getBoolean( + (string) $root->getAttribute('processIsolation'), false + ); + } + + if ($root->hasAttribute('stopOnError')) { + $result['stopOnError'] = $this->getBoolean( + (string) $root->getAttribute('stopOnError'), false + ); + } + + if ($root->hasAttribute('stopOnFailure')) { + $result['stopOnFailure'] = $this->getBoolean( + (string) $root->getAttribute('stopOnFailure'), false + ); + } + + if ($root->hasAttribute('stopOnIncomplete')) { + $result['stopOnIncomplete'] = $this->getBoolean( + (string) $root->getAttribute('stopOnIncomplete'), false + ); + } + + if ($root->hasAttribute('stopOnRisky')) { + $result['stopOnRisky'] = $this->getBoolean( + (string) $root->getAttribute('stopOnRisky'), false + ); + } + + if ($root->hasAttribute('stopOnSkipped')) { + $result['stopOnSkipped'] = $this->getBoolean( + (string) $root->getAttribute('stopOnSkipped'), false + ); + } + + if ($root->hasAttribute('testSuiteLoaderClass')) { + $result['testSuiteLoaderClass'] = (string) $root->getAttribute( + 'testSuiteLoaderClass' + ); + } + + if ($root->getAttribute('testSuiteLoaderFile')) { + $result['testSuiteLoaderFile'] = $this->toAbsolutePath( + (string) $root->getAttribute('testSuiteLoaderFile') + ); + } + + if ($root->hasAttribute('printerClass')) { + $result['printerClass'] = (string) $root->getAttribute( + 'printerClass' + ); + } + + if ($root->getAttribute('printerFile')) { + $result['printerFile'] = $this->toAbsolutePath( + (string) $root->getAttribute('printerFile') + ); + } + + if ($root->hasAttribute('timeoutForSmallTests')) { + $result['timeoutForSmallTests'] = $this->getInteger( + (string) $root->getAttribute('timeoutForSmallTests'), 1 + ); + } + + if ($root->hasAttribute('timeoutForMediumTests')) { + $result['timeoutForMediumTests'] = $this->getInteger( + (string) $root->getAttribute('timeoutForMediumTests'), 10 + ); + } + + if ($root->hasAttribute('timeoutForLargeTests')) { + $result['timeoutForLargeTests'] = $this->getInteger( + (string) $root->getAttribute('timeoutForLargeTests'), 60 + ); + } + + if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) { + $result['reportUselessTests'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'), false + ); + } + + if ($root->hasAttribute('checkForUnintentionallyCoveredCode')) { + $result['strictCoverage'] = $this->getBoolean( + (string) $root->getAttribute('checkForUnintentionallyCoveredCode'), false + ); + } + + if ($root->hasAttribute('beStrictAboutOutputDuringTests')) { + $result['disallowTestOutput'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutOutputDuringTests'), false + ); + } + + if ($root->hasAttribute('beStrictAboutTestSize')) { + $result['enforceTimeLimit'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutTestSize'), false + ); + } + + if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) { + $result['disallowTodoAnnotatedTests'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'), false + ); + } + + if ($root->hasAttribute('strict')) { + $flag = $this->getBoolean( + (string) $root->getAttribute('strict'), false + ); + + $result['reportUselessTests'] = $flag; + $result['strictCoverage'] = $flag; + $result['disallowTestOutput'] = $flag; + $result['enforceTimeLimit'] = $flag; + $result['disallowTodoAnnotatedTests'] = $flag; + } + + if ($root->hasAttribute('verbose')) { + $result['verbose'] = $this->getBoolean( + (string) $root->getAttribute('verbose'), false + ); + } + + return $result; + } + + /** + * Returns the SeleniumTestCase browser configuration. + * + * @return array + * @since Method available since Release 3.2.9 + */ + public function getSeleniumBrowserConfiguration() + { + $result = array(); + + foreach ($this->xpath->query('selenium/browser') as $config) { + $name = (string) $config->getAttribute('name'); + $browser = (string) $config->getAttribute('browser'); + + if ($config->hasAttribute('host')) { + $host = (string) $config->getAttribute('host'); + } else { + $host = 'localhost'; + } + + if ($config->hasAttribute('port')) { + $port = $this->getInteger( + (string) $config->getAttribute('port'), 4444 + ); + } else { + $port = 4444; + } + + if ($config->hasAttribute('timeout')) { + $timeout = $this->getInteger( + (string) $config->getAttribute('timeout'), 30000 + ); + } else { + $timeout = 30000; + } + + $result[] = array( + 'name' => $name, + 'browser' => $browser, + 'host' => $host, + 'port' => $port, + 'timeout' => $timeout + ); + } + + return $result; + } + + /** + * Returns the test suite configuration. + * + * @return PHPUnit_Framework_TestSuite + * @since Method available since Release 3.2.1 + */ + public function getTestSuiteConfiguration($testSuiteFilter = null) + { + $testSuiteNodes = $this->xpath->query('testsuites/testsuite'); + + if ($testSuiteNodes->length == 0) { + $testSuiteNodes = $this->xpath->query('testsuite'); + } + + if ($testSuiteNodes->length == 1) { + return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter); + } + + if ($testSuiteNodes->length > 1) { + $suite = new PHPUnit_Framework_TestSuite; + + foreach ($testSuiteNodes as $testSuiteNode) { + $suite->addTestSuite( + $this->getTestSuite($testSuiteNode, $testSuiteFilter) + ); + } + + return $suite; + } + } + + /** + * @param DOMElement $testSuiteNode + * @return PHPUnit_Framework_TestSuite + * @since Method available since Release 3.4.0 + */ + protected function getTestSuite(DOMElement $testSuiteNode, $testSuiteFilter = null) + { + if ($testSuiteNode->hasAttribute('name')) { + $suite = new PHPUnit_Framework_TestSuite( + (string) $testSuiteNode->getAttribute('name') + ); + } else { + $suite = new PHPUnit_Framework_TestSuite; + } + + $exclude = array(); + + foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) { + $excludeFile = (string) $excludeNode->nodeValue; + if ($excludeFile) { + $exclude[] = $this->toAbsolutePath($excludeFile); + } + } + + $fileIteratorFacade = new File_Iterator_Facade; + + foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) { + if ($testSuiteFilter && $directoryNode->parentNode->getAttribute('name') != $testSuiteFilter) { + continue; + } + + $directory = (string) $directoryNode->nodeValue; + + if (empty($directory)) { + continue; + } + + if ($directoryNode->hasAttribute('phpVersion')) { + $phpVersion = (string) $directoryNode->getAttribute('phpVersion'); + } else { + $phpVersion = PHP_VERSION; + } + + if ($directoryNode->hasAttribute('phpVersionOperator')) { + $phpVersionOperator = (string) $directoryNode->getAttribute('phpVersionOperator'); + } else { + $phpVersionOperator = '>='; + } + + if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) { + continue; + } + + if ($directoryNode->hasAttribute('prefix')) { + $prefix = (string) $directoryNode->getAttribute('prefix'); + } else { + $prefix = ''; + } + + if ($directoryNode->hasAttribute('suffix')) { + $suffix = (string) $directoryNode->getAttribute('suffix'); + } else { + $suffix = 'Test.php'; + } + + $files = $fileIteratorFacade->getFilesAsArray( + $this->toAbsolutePath($directory), + $suffix, + $prefix, + $exclude + ); + $suite->addTestFiles($files); + } + + foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) { + if ($testSuiteFilter && $fileNode->parentNode->getAttribute('name') != $testSuiteFilter) { + continue; + } + + $file = (string) $fileNode->nodeValue; + + if (empty($file)) { + continue; + } + + // Get the absolute path to the file + $file = $fileIteratorFacade->getFilesAsArray( + $this->toAbsolutePath($file) + ); + + if (!isset($file[0])) { + continue; + } + + $file = $file[0]; + + if ($fileNode->hasAttribute('phpVersion')) { + $phpVersion = (string) $fileNode->getAttribute('phpVersion'); + } else { + $phpVersion = PHP_VERSION; + } + + if ($fileNode->hasAttribute('phpVersionOperator')) { + $phpVersionOperator = (string) $fileNode->getAttribute('phpVersionOperator'); + } else { + $phpVersionOperator = '>='; + } + + if (!version_compare(PHP_VERSION, $phpVersion, $phpVersionOperator)) { + continue; + } + + $suite->addTestFile($file); + } + + return $suite; + } + + /** + * @param string $value + * @param boolean $default + * @return boolean + * @since Method available since Release 3.2.3 + */ + protected function getBoolean($value, $default) + { + if (strtolower($value) == 'false') { + return false; + } elseif (strtolower($value) == 'true') { + return true; + } + + return $default; + } + + /** + * @param string $value + * @param boolean $default + * @return boolean + * @since Method available since Release 3.6.0 + */ + protected function getInteger($value, $default) + { + if (is_numeric($value)) { + return (int) $value; + } + + return $default; + } + + /** + * @param string $query + * @return array + * @since Method available since Release 3.2.3 + */ + protected function readFilterDirectories($query) + { + $directories = array(); + + foreach ($this->xpath->query($query) as $directory) { + $directoryPath = (string) $directory->nodeValue; + + if (!$directoryPath) { + continue; + } + + if ($directory->hasAttribute('prefix')) { + $prefix = (string) $directory->getAttribute('prefix'); + } else { + $prefix = ''; + } + + if ($directory->hasAttribute('suffix')) { + $suffix = (string) $directory->getAttribute('suffix'); + } else { + $suffix = '.php'; + } + + if ($directory->hasAttribute('group')) { + $group = (string) $directory->getAttribute('group'); + } else { + $group = 'DEFAULT'; + } + + $directories[] = array( + 'path' => $this->toAbsolutePath($directoryPath), + 'prefix' => $prefix, + 'suffix' => $suffix, + 'group' => $group + ); + } + + return $directories; + } + + /** + * @param string $query + * @return array + * @since Method available since Release 3.2.3 + */ + protected function readFilterFiles($query) + { + $files = array(); + + foreach ($this->xpath->query($query) as $file) { + $filePath = (string) $file->nodeValue; + if ($filePath) { + $files[] = $this->toAbsolutePath($filePath); + } + } + + return $files; + } + + /** + * @param string $path + * @param boolean $useIncludePath + * @return string + * @since Method available since Release 3.5.0 + */ + protected function toAbsolutePath($path, $useIncludePath = false) + { + if ($path[0] === '/') { + return $path; + } + + // Matches the following on Windows: + // - \\NetworkComputer\Path + // - \\.\D: + // - \\.\c: + // - C:\Windows + // - C:\windows + // - C:/windows + // - c:/windows + if (defined('PHP_WINDOWS_VERSION_BUILD') && + ($path[0] === '\\' || + (strlen($path) >= 3 && preg_match('#^[A-Z]\:[/\\\]#i', substr($path, 0, 3))))) { + return $path; + } + + // Stream + if (strpos($path, '://') !== false) { + return $path; + } + + $file = dirname($this->filename) . DIRECTORY_SEPARATOR . $path; + + if ($useIncludePath && !file_exists($file)) { + $includePathFile = stream_resolve_include_path($path); + + if ($includePathFile) { + $file = $includePathFile; + } + } + + return $file; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Interface for classes which can be invoked. + * + * The invocation will be taken from a mock object and passed to an object + * of this class. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Invokable extends PHPUnit_Framework_MockObject_Verifiable +{ + /** + * Invokes the invocation object $invocation so that it can be checked for + * expectations or matched against stubs. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * The invocation object passed from mock object. + * @return object + */ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation); + + /** + * Checks if the invocation matches. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * The invocation object passed from mock object. + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 2.0.6 + */ + +/** + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 2.0.6 + */ +class PHPUnit_Framework_MockObject_BadMethodCallException extends BadMethodCallException implements PHPUnit_Framework_MockObject_Exception +{ +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 2.0.0 + */ + +/** + * Interface for exceptions used by PHPUnit_MockObject. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 2.0.6 + */ +interface PHPUnit_Framework_MockObject_Exception +{ +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 2.0.6 + */ + +/** + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 2.0.6 + */ +class PHPUnit_Framework_MockObject_RuntimeException extends RuntimeException implements PHPUnit_Framework_MockObject_Exception +{ +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * An object that stubs the process of a normal method for a mock object. + * + * The stub object will replace the code for the stubbed method and return a + * specific value instead of the original value. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Stub extends PHPUnit_Framework_SelfDescribing +{ + /** + * Fakes the processing of the invocation $invocation by returning a + * specific value. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * The invocation which was mocked and matched by the current method + * and argument matchers. + * @return mixed + */ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Mocker for invocations which are sent from + * PHPUnit_Framework_MockObject_MockObject objects. + * + * Keeps track of all expectations and stubs as well as registering + * identifications for builders. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_InvocationMocker implements PHPUnit_Framework_MockObject_Stub_MatcherCollection, PHPUnit_Framework_MockObject_Invokable, PHPUnit_Framework_MockObject_Builder_Namespace +{ + /** + * @var PHPUnit_Framework_MockObject_Matcher_Invocation[] + */ + protected $matchers = array(); + + /** + * @var PHPUnit_Framework_MockObject_Builder_Match[] + */ + protected $builderMap = array(); + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + */ + public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) + { + $this->matchers[] = $matcher; + } + + /** + * @since Method available since Release 1.1.0 + */ + public function hasMatchers() + { + foreach ($this->matchers as $matcher) { + if ($matcher->hasMatchers()) { + return TRUE; + } + } + + return FALSE; + } + + /** + * @param mixed $id + * @return boolean|null + */ + public function lookupId($id) + { + if (isset($this->builderMap[$id])) { + return $this->builderMap[$id]; + } + + return NULL; + } + + /** + * @param mixed $id + * @param PHPUnit_Framework_MockObject_Builder_Match $builder + * @throws PHPUnit_Framework_Exception + */ + public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder) + { + if (isset($this->builderMap[$id])) { + throw new PHPUnit_Framework_Exception( + 'Match builder with id <' . $id . '> is already registered.' + ); + } + + $this->builderMap[$id] = $builder; + } + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) + { + return new PHPUnit_Framework_MockObject_Builder_InvocationMocker( + $this, $matcher + ); + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return mixed + */ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $exception = NULL; + $hasReturnValue = FALSE; + + if (strtolower($invocation->methodName) == '__tostring') { + $returnValue = ''; + } else { + $returnValue = NULL; + } + + foreach ($this->matchers as $match) { + try { + if ($match->matches($invocation)) { + $value = $match->invoked($invocation); + + if (!$hasReturnValue) { + $returnValue = $value; + $hasReturnValue = TRUE; + } + } + } catch (Exception $e) { + $exception = $e; + } + } + + if ($exception !== NULL) { + throw $exception; + } + + return $returnValue; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + foreach ($this->matchers as $matcher) { + if (!$matcher->matches($invocation)) { + return FALSE; + } + } + + return TRUE; + } + + /** + * @return boolean + */ + public function verify() + { + foreach ($this->matchers as $matcher) { + $matcher->verify(); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Represents a non-static invocation. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Invocation_Object extends PHPUnit_Framework_MockObject_Invocation_Static +{ + /** + * @var object + */ + public $object; + + /** + * @param string $className + * @param string $methodname + * @param array $parameters + * @param object $object + * @param object $cloneObjects + */ + public function __construct($className, $methodName, array $parameters, $object, $cloneObjects = FALSE) + { + parent::__construct($className, $methodName, $parameters, $cloneObjects); + $this->object = $object; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +use SebastianBergmann\Exporter\Exporter; + +/** + * Represents a static invocation. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Invocation_Static implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing +{ + /** + * @var array + */ + protected static $uncloneableExtensions = array( + 'mysqli' => TRUE, + 'SQLite' => TRUE, + 'sqlite3' => TRUE, + 'tidy' => TRUE, + 'xmlwriter' => TRUE, + 'xsl' => TRUE + ); + + /** + * @var array + */ + protected static $uncloneableClasses = array( + 'Closure', + 'COMPersistHelper', + 'IteratorIterator', + 'RecursiveIteratorIterator', + 'SplFileObject', + 'PDORow', + 'ZipArchive' + ); + + /** + * @var string + */ + public $className; + + /** + * @var string + */ + public $methodName; + + /** + * @var array + */ + public $parameters; + + /** + * @param string $className + * @param string $methodname + * @param array $parameters + * @param boolean $cloneObjects + */ + public function __construct($className, $methodName, array $parameters, $cloneObjects = FALSE) + { + $this->className = $className; + $this->methodName = $methodName; + $this->parameters = $parameters; + + if (!$cloneObjects) { + return; + } + + foreach ($this->parameters as $key => $value) { + if (is_object($value)) { + $this->parameters[$key] = $this->cloneObject($value); + } + } + } + + /** + * @return string + */ + public function toString() + { + $exporter = new Exporter; + + return sprintf( + "%s::%s(%s)", + + $this->className, + $this->methodName, + join( + ', ', + array_map( + array($exporter, 'shortenedExport'), + $this->parameters + ) + ) + ); + } + + /** + * @param object $original + * @return object + */ + protected function cloneObject($original) + { + $cloneable = NULL; + $object = new ReflectionObject($original); + + // Check the blacklist before asking PHP reflection to work around + // https://bugs.php.net/bug.php?id=53967 + if ($object->isInternal() && + isset(self::$uncloneableExtensions[$object->getExtensionName()])) { + $cloneable = FALSE; + } + + if ($cloneable === NULL) { + foreach (self::$uncloneableClasses as $class) { + if ($original instanceof $class) { + $cloneable = FALSE; + break; + } + } + } + + if ($cloneable === NULL && method_exists($object, 'isCloneable')) { + $cloneable = $object->isCloneable(); + } + + if ($cloneable === NULL && $object->hasMethod('__clone')) { + $method = $object->getMethod('__clone'); + $cloneable = $method->isPublic(); + } + + if ($cloneable === NULL) { + $cloneable = TRUE; + } + + if ($cloneable) { + try { + return clone $original; + } catch (Exception $e) { + return $original; + } + } else { + return $original; + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Giorgio Sironi + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Implementation of the Builder pattern for Mock objects. + * + * @package PHPUnit_MockObject + * @author Giorgio Sironi + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_MockBuilder +{ + /** + * @var PHPUnit_Framework_TestCase + */ + private $testCase; + + /** + * @var string + */ + private $type; + + /** + * @var array + */ + private $methods = array(); + + /** + * @var string + */ + private $mockClassName = ''; + + /** + * @var array + */ + private $constructorArgs = array(); + + /** + * @var boolean + */ + private $originalConstructor = TRUE; + + /** + * @var boolean + */ + private $originalClone = TRUE; + + /** + * @var boolean + */ + private $autoload = TRUE; + + /** + * @var boolean + */ + private $cloneArguments = FALSE; + + /** + * @var boolean + */ + private $callOriginalMethods = FALSE; + + /** + * @var object + */ + private $proxyTarget = NULL; + + /** + * @param PHPUnit_Framework_TestCase $testCase + * @param array|string $type + */ + public function __construct(PHPUnit_Framework_TestCase $testCase, $type) + { + $this->testCase = $testCase; + $this->type = $type; + } + + /** + * Creates a mock object using a fluent interface. + * + * @return PHPUnit_Framework_MockObject_MockObject + */ + public function getMock() + { + return $this->testCase->getMock( + $this->type, + $this->methods, + $this->constructorArgs, + $this->mockClassName, + $this->originalConstructor, + $this->originalClone, + $this->autoload, + $this->cloneArguments, + $this->callOriginalMethods, + $this->proxyTarget + ); + } + + /** + * Creates a mock object for an abstract class using a fluent interface. + * + * @return PHPUnit_Framework_MockObject_MockObject + */ + public function getMockForAbstractClass() + { + return $this->testCase->getMockForAbstractClass( + $this->type, + $this->constructorArgs, + $this->mockClassName, + $this->originalConstructor, + $this->originalClone, + $this->autoload, + $this->methods, + $this->cloneArguments + ); + } + + /** + * Creates a mock object for a trait using a fluent interface. + * + * @return PHPUnit_Framework_MockObject_MockObject + */ + public function getMockForTrait() + { + return $this->testCase->getMockForTrait( + $this->type, + $this->constructorArgs, + $this->mockClassName, + $this->originalConstructor, + $this->originalClone, + $this->autoload, + $this->methods, + $this->cloneArguments + ); + } + + /** + * Specifies the subset of methods to mock. Default is to mock all of them. + * + * @param array|null $methods + * @return PHPUnit_Framework_MockObject_MockBuilder + */ + public function setMethods($methods) + { + $this->methods = $methods; + + return $this; + } + + /** + * Specifies the arguments for the constructor. + * + * @param array $args + * @return PHPUnit_Framework_MockObject_MockBuilder + */ + public function setConstructorArgs(array $args) + { + $this->constructorArgs = $args; + + return $this; + } + + /** + * Specifies the name for the mock class. + * + * @param string $name + * @return PHPUnit_Framework_MockObject_MockBuilder + */ + public function setMockClassName($name) + { + $this->mockClassName = $name; + + return $this; + } + + /** + * Disables the invocation of the original constructor. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + */ + public function disableOriginalConstructor() + { + $this->originalConstructor = FALSE; + + return $this; + } + + /** + * Enables the invocation of the original constructor. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 1.2.0 + */ + public function enableOriginalConstructor() + { + $this->originalConstructor = TRUE; + + return $this; + } + + /** + * Disables the invocation of the original clone constructor. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + */ + public function disableOriginalClone() + { + $this->originalClone = FALSE; + + return $this; + } + + /** + * Enables the invocation of the original clone constructor. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 1.2.0 + */ + public function enableOriginalClone() + { + $this->originalClone = TRUE; + + return $this; + } + + /** + * Disables the use of class autoloading while creating the mock object. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + */ + public function disableAutoload() + { + $this->autoload = FALSE; + + return $this; + } + + /** + * Enables the use of class autoloading while creating the mock object. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 1.2.0 + */ + public function enableAutoload() + { + $this->autoload = TRUE; + + return $this; + } + + /** + * Disables the cloning of arguments passed to mocked methods. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 1.2.0 + */ + public function disableArgumentCloning() + { + $this->cloneArguments = FALSE; + + return $this; + } + + /** + * Enables the cloning of arguments passed to mocked methods. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 1.2.0 + */ + public function enableArgumentCloning() + { + $this->cloneArguments = TRUE; + + return $this; + } + + /** + * Enables the invocation of the original methods. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 2.0.0 + */ + public function enableProxyingToOriginalMethods() + { + $this->callOriginalMethods = TRUE; + + return $this; + } + + /** + * Disables the invocation of the original methods. + * + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 2.0.0 + */ + public function disableProxyingToOriginalMethods() + { + $this->callOriginalMethods = FALSE; + $this->proxyTarget = NULL; + + return $this; + } + + /** + * Sets the proxy target. + * + * @param object $object + * @return PHPUnit_Framework_MockObject_MockBuilder + * @since Method available since Release 2.0.0 + */ + public function setProxyTarget($object) + { + $this->proxyTarget = $object; + + return $this; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Builder interface for matcher of method names. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_MethodNameMatch extends PHPUnit_Framework_MockObject_Builder_ParametersMatch +{ + /** + * Adds a new method name match and returns the parameter match object for + * further matching possibilities. + * + * @param PHPUnit_Framework_Constraint $name + * Constraint for matching method, if a string is passed it will use + * the PHPUnit_Framework_Constraint_IsEqual. + * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch + */ + public function method($name); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Builder interface for stubs which are actions replacing an invocation. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Stub extends PHPUnit_Framework_MockObject_Builder_Identity +{ + /** + * Stubs the matching method with the stub object $stub. Any invocations of + * the matched method will now be handled by the stub instead. + * + * @param PHPUnit_Framework_MockObject_Stub $stub The stub object. + * @return PHPUnit_Framework_MockObject_Builder_Identity + */ + public function will(PHPUnit_Framework_MockObject_Stub $stub); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Builder for mocked or stubbed invocations. + * + * Provides methods for building expectations without having to resort to + * instantiating the various matchers manually. These methods also form a + * more natural way of reading the expectation. This class should be together + * with the test case PHPUnit_Framework_MockObject_TestCase. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Builder_InvocationMocker implements PHPUnit_Framework_MockObject_Builder_MethodNameMatch +{ + /** + * @var PHPUnit_Framework_MockObject_Stub_MatcherCollection + */ + protected $collection; + + /** + * @var PHPUnit_Framework_MockObject_Matcher + */ + protected $matcher; + + /** + * @param PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher + */ + public function __construct(PHPUnit_Framework_MockObject_Stub_MatcherCollection $collection, PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher) + { + $this->collection = $collection; + $this->matcher = new PHPUnit_Framework_MockObject_Matcher( + $invocationMatcher + ); + + $this->collection->addMatcher($this->matcher); + } + + /** + * @return PHPUnit_Framework_MockObject_Matcher + */ + public function getMatcher() + { + return $this->matcher; + } + + /** + * @param mixed $id + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function id($id) + { + $this->collection->registerId($id, $this); + + return $this; + } + + /** + * @param PHPUnit_Framework_MockObject_Stub $stub + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function will(PHPUnit_Framework_MockObject_Stub $stub) + { + $this->matcher->stub = $stub; + + return $this; + } + + /** + * @param mixed $value + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willReturn($value) + { + $stub = new PHPUnit_Framework_MockObject_Stub_Return( + $value + ); + + return $this->will($stub); + } + + /** + * @param array $valueMap + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willReturnMap(array $valueMap) + { + $stub = new PHPUnit_Framework_MockObject_Stub_ReturnValueMap( + $valueMap + ); + + return $this->will($stub); + } + + /** + * @param mixed $argumentIndex + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willReturnArgument($argumentIndex) + { + $stub = new PHPUnit_Framework_MockObject_Stub_ReturnArgument( + $argumentIndex + ); + + return $this->will($stub); + } + + /** + * @param callable $callback + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willReturnCallback($callback) + { + $stub = new PHPUnit_Framework_MockObject_Stub_ReturnCallback( + $callback + ); + + return $this->will($stub); + } + + /** + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willReturnSelf() + { + $stub = new PHPUnit_Framework_MockObject_Stub_ReturnSelf(); + + return $this->will($stub); + } + + /** + * @param mixed $value, ... + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willReturnOnConsecutiveCalls() + { + $args = func_get_args(); + + $stub = new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls($args); + + return $this->will($stub); + } + + /** + * @param Exception $exception + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function willThrowException(Exception $exception) + { + $stub = new PHPUnit_Framework_MockObject_Stub_Exception($exception); + + return $this->will($stub); + } + + /** + * @param mixed $id + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function after($id) + { + $this->matcher->afterMatchBuilderId = $id; + + return $this; + } + + /** + * Validate that a parameters matcher can be defined, throw exceptions otherwise. + * + * @throws PHPUnit_Framework_Exception + */ + private function canDefineParameters() + { + if ($this->matcher->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'Method name matcher is not defined, cannot define parameter ' . + ' matcher without one' + ); + } + + if ($this->matcher->parametersMatcher !== NULL) { + throw new PHPUnit_Framework_Exception( + 'Parameter matcher is already defined, cannot redefine' + ); + } + } + + /** + * @param mixed $argument, ... + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function with() + { + $args = func_get_args(); + + $this->canDefineParameters(); + + $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_Parameters($args); + + return $this; + } + + /** + * @param mixed ...$argument + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function withConsecutive() { + + $args = func_get_args(); + + $this->canDefineParameters(); + + $this->matcher->parametersMatcher = + new PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters($args); + + return $this; + } + + /** + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function withAnyParameters() + { + $this->canDefineParameters(); + + $this->matcher->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters; + + return $this; + } + + /** + * @param PHPUnit_Framework_Constraint|string $constraint + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function method($constraint) + { + if ($this->matcher->methodNameMatcher !== NULL) { + throw new PHPUnit_Framework_Exception( + 'Method name matcher is already defined, cannot redefine' + ); + } + + $this->matcher->methodNameMatcher = new PHPUnit_Framework_MockObject_Matcher_MethodName($constraint); + + return $this; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Builder interface for invocation order matches. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Match extends PHPUnit_Framework_MockObject_Builder_Stub +{ + /** + * Defines the expectation which must occur before the current is valid. + * + * @param string $id The identification of the expectation that should + * occur before this one. + * @return PHPUnit_Framework_MockObject_Builder_Stub + */ + public function after($id); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Builder interface for parameter matchers. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_ParametersMatch extends PHPUnit_Framework_MockObject_Builder_Match +{ + /** + * Sets the parameters to match for, each parameter to this funtion will + * be part of match. To perform specific matches or constraints create a + * new PHPUnit_Framework_Constraint and use it for the parameter. + * If the parameter value is not a constraint it will use the + * PHPUnit_Framework_Constraint_IsEqual for the value. + * + * Some examples: + * + * // match first parameter with value 2 + * $b->with(2); + * // match first parameter with value 'smock' and second identical to 42 + * $b->with('smock', new PHPUnit_Framework_Constraint_IsEqual(42)); + * + * + * @return PHPUnit_Framework_MockObject_Builder_ParametersMatch + */ + public function with(); + + /** + * Sets a matcher which allows any kind of parameters. + * + * Some examples: + * + * // match any number of parameters + * $b->withAnyParamers(); + * + * + * @return PHPUnit_Framework_MockObject_Matcher_AnyParameters + */ + public function withAnyParameters(); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Interface for builders which can register builders with a given identification. + * + * This interface relates to PHPUnit_Framework_MockObject_Builder_Identity. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Namespace +{ + /** + * Looks up the match builder with identification $id and returns it. + * + * @param string $id The identifiction of the match builder. + * @return PHPUnit_Framework_MockObject_Builder_Match + */ + public function lookupId($id); + + /** + * Registers the match builder $builder with the identification $id. The + * builder can later be looked up using lookupId() to figure out if it + * has been invoked. + * + * @param string $id + * The identification of the match builder. + * @param PHPUnit_Framework_MockObject_Builder_Match $builder + * The builder which is being registered. + */ + public function registerId($id, PHPUnit_Framework_MockObject_Builder_Match $builder); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Builder interface for unique identifiers. + * + * Defines the interface for recording unique identifiers. The identifiers + * can be used to define the invocation order of expectations. The expectation + * is recorded using id() and then defined in order using + * PHPUnit_Framework_MockObject_Builder_Match::after(). + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Builder_Identity +{ + /** + * Sets the identification of the expectation to $id. + * + * @note The identifier is unique per mock object. + * @param string $id Unique identifiation of expectation. + */ + public function id($id); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.1.0 + */ + +/** + * Stubs a method by returning a value from a map. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.1.0 + */ +class PHPUnit_Framework_MockObject_Stub_ReturnValueMap implements PHPUnit_Framework_MockObject_Stub +{ + protected $valueMap; + + public function __construct(array $valueMap) + { + $this->valueMap = $valueMap; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $parameterCount = count($invocation->parameters); + + foreach ($this->valueMap as $map) { + if (!is_array($map) || $parameterCount != count($map) - 1) { + continue; + } + + $return = array_pop($map); + if ($invocation->parameters === $map) { + return $return; + } + } + + return NULL; + } + + public function toString() + { + return 'return value from a map'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_ReturnCallback implements PHPUnit_Framework_MockObject_Stub +{ + protected $callback; + + public function __construct($callback) + { + $this->callback = $callback; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return call_user_func_array($this->callback, $invocation->parameters); + } + + public function toString() + { + if (is_array($this->callback)) { + if (is_object($this->callback[0])) { + $class = get_class($this->callback[0]); + $type = '->'; + } else { + $class = $this->callback[0]; + $type = '::'; + } + + return sprintf( + 'return result of user defined callback %s%s%s() with the ' . + 'passed arguments', + + $class, + $type, + $this->callback[1] + ); + } else { + return 'return result of user defined callback ' . $this->callback . + ' with the passed arguments'; + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Oliver Schlicht + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Stubs a method by raising a user-defined exception. + * + * @package PHPUnit_MockObject + * @author Oliver Schlicht + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_Exception implements PHPUnit_Framework_MockObject_Stub +{ + protected $exception; + + public function __construct(Exception $exception) + { + $this->exception = $exception; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + throw $this->exception; + } + + public function toString() + { + return sprintf( + 'raise user-specified exception %s', + + PHPUnit_Util_Type::export($this->exception) + ); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Stubs a method by returning a user-defined value. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_Return implements PHPUnit_Framework_MockObject_Stub +{ + protected $value; + + public function __construct($value) + { + $this->value = $value; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return $this->value; + } + + public function toString() + { + return sprintf( + 'return user-specified value %s', + + PHPUnit_Util_Type::export($this->value) + ); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @author Kris Wallsmith + * @copyright 2010 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.1.0 + */ + +/** + * Stubs a method by returning the current object. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @author Kris Wallsmith + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.1.0 + */ +class PHPUnit_Framework_MockObject_Stub_ReturnSelf implements PHPUnit_Framework_MockObject_Stub +{ + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if (!$invocation instanceof PHPUnit_Framework_MockObject_Invocation_Object) { + throw new PHPUnit_Framework_Exception( + 'The current object can only be returned when mocking an ' . + 'object, not a static class.' + ); + } + + return $invocation->object; + } + + public function toString() + { + return 'return the current object'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Stubs a method by returning an argument that was passed to the mocked method. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_ReturnArgument extends PHPUnit_Framework_MockObject_Stub_Return +{ + protected $argumentIndex; + + public function __construct($argumentIndex) + { + $this->argumentIndex = $argumentIndex; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if (isset($invocation->parameters[$this->argumentIndex])) { + return $invocation->parameters[$this->argumentIndex]; + } else { + return NULL; + } + } + + public function toString() + { + return sprintf('return argument #%d', $this->argumentIndex); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Patrick Müller + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Stubs a method by returning a user-defined stack of values. + * + * @package PHPUnit_MockObject + * @author Patrick Müller + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls implements PHPUnit_Framework_MockObject_Stub +{ + protected $stack; + protected $value; + + public function __construct($stack) + { + $this->stack = $stack; + } + + public function invoke(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->value = array_shift($this->stack); + + if ($this->value instanceof PHPUnit_Framework_MockObject_Stub) { + $this->value = $this->value->invoke($invocation); + } + + return $this->value; + } + + public function toString() + { + return sprintf( + 'return user-specified value %s', + + PHPUnit_Util_Type::export($this->value) + ); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Stubs a method by returning a user-defined value. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Stub_MatcherCollection +{ + /** + * Adds a new matcher to the collection which can be used as an expectation + * or a stub. + * + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + * Matcher for invocations to mock objects. + */ + public function addMatcher(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Records invocations and provides convenience methods for checking them later + * on. + * This abstract class can be implemented by matchers which needs to check the + * number of times an invocation has occured. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + * @abstract + */ +abstract class PHPUnit_Framework_MockObject_Matcher_InvokedRecorder implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * @var PHPUnit_Framework_MockObject_Invocation[] + */ + protected $invocations = array(); + + /** + * @return integer + */ + public function getInvocationCount() + { + return count($this->invocations); + } + + /** + * @return PHPUnit_Framework_MockObject_Invocation[] + */ + public function getInvocations() + { + return $this->invocations; + } + + /** + * @return boolean + */ + public function hasBeenInvoked() + { + return count($this->invocations) > 0; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->invocations[] = $invocation; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return TRUE; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which looks for a specific method name in the invocations. + * + * Checks the method name all incoming invocations, the name is checked against + * the defined constraint $constraint. If the constraint is met it will return + * true in matches(). + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_MethodName extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + /** + * @var PHPUnit_Framework_Constraint + */ + protected $constraint; + + /** + * @param PHPUnit_Framework_Constraint|string + * @throws PHPUnit_Framework_Constraint + */ + public function __construct($constraint) + { + if (!$constraint instanceof PHPUnit_Framework_Constraint) { + if (!is_string($constraint)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $constraint = new PHPUnit_Framework_Constraint_IsEqual( + $constraint, 0, 10, FALSE, TRUE + ); + } + + $this->constraint = $constraint; + } + + /** + * @return string + */ + public function toString() + { + return 'method name ' . $this->constraint->toString(); + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return $this->constraint->evaluate($invocation->methodName, '', TRUE); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which checks if a method was invoked at a certain index. + * + * If the expected index number does not match the current invocation index it + * will not match which means it skips all method and parameter matching. Only + * once the index is reached will the method and parameter start matching and + * verifying. + * + * If the index is never reached it will throw an exception in index. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * @var integer + */ + protected $sequenceIndex; + + /** + * @var integer + */ + protected $currentIndex = -1; + + /** + * @param integer $sequenceIndex + */ + public function __construct($sequenceIndex) + { + $this->sequenceIndex = $sequenceIndex; + } + + /** + * @return string + */ + public function toString() + { + return 'invoked at sequence index ' . $this->sequenceIndex; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->currentIndex++; + + return $this->currentIndex == $this->sequenceIndex; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + if ($this->currentIndex < $this->sequenceIndex) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + 'The expected invocation at index %s was never reached.', + + $this->sequenceIndex + ) + ); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which does not care about previous state from earlier + * invocations. + * + * This abstract class can be implemented by matchers which does not care about + * state but only the current run-time value of the invocation itself. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + * @abstract + */ +abstract class PHPUnit_Framework_MockObject_Matcher_StatelessInvocation implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * Registers the invocation $invocation in the object as being invoked. + * This will only occur after matches() returns true which means the + * current invocation is the correct one. + * + * The matcher can store information from the invocation which can later + * be checked in verify(), or it can check the values directly and throw + * and exception if an expectation is not met. + * + * If the matcher is a stub it will also have a return value. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return mixed + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + } + + /** + * Checks if the invocation $invocation matches the current rules. If it does + * the matcher will get the invoked() method called which should check if an + * expectation is met. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return bool + */ + public function verify() + { + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 2.2.0 + */ + +/** + * Invocation matcher which checks if a method has been invoked at least + * N times. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 2.2.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedAtMostCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @var integer + */ + private $allowedInvocations; + + /** + * @param integer $allowedInvocations + */ + public function __construct($allowedInvocations) + { + $this->allowedInvocations = $allowedInvocations; + } + + /** + * @return string + */ + public function toString() + { + return 'invoked at most ' . $this->allowedInvocations . ' times'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + $count = $this->getInvocationCount(); + + if ($count > $this->allowedInvocations) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Expected invocation at most ' . $this->allowedInvocations . + ' times but it occured ' . $count . ' time(s).' + ); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which checks if a method has been invoked a certain amount + * of times. + * If the number of invocations exceeds the value it will immediately throw an + * exception, + * If the number is less it will later be checked in verify() and also throw an + * exception. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @var integer + */ + protected $expectedCount; + + /** + * @param integer $expectedCount + */ + public function __construct($expectedCount) + { + $this->expectedCount = $expectedCount; + } + + /** + * @return boolean + */ + public function isNever() + { + return $this->expectedCount == 0; + } + + /** + * @return string + */ + public function toString() + { + return 'invoked ' . $this->expectedCount . ' time(s)'; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + parent::invoked($invocation); + + $count = $this->getInvocationCount(); + + if ($count > $this->expectedCount) { + $message = $invocation->toString() . ' '; + + switch ($this->expectedCount) { + case 0: { + $message .= 'was not expected to be called.'; + } + break; + + case 1: { + $message .= 'was not expected to be called more than once.'; + } + break; + + default: { + $message .= sprintf( + 'was not expected to be called more than %d times.', + + $this->expectedCount + ); + } + } + + throw new PHPUnit_Framework_ExpectationFailedException($message); + } + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + $count = $this->getInvocationCount(); + + if ($count !== $this->expectedCount) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + 'Method was expected to be called %d times, ' . + 'actually called %d times.', + + $this->expectedCount, + $count + ) + ); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Interface for classes which matches an invocation based on its + * method name, argument, order or call count. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Matcher_Invocation extends PHPUnit_Framework_SelfDescribing, PHPUnit_Framework_MockObject_Verifiable +{ + /** + * Registers the invocation $invocation in the object as being invoked. + * This will only occur after matches() returns true which means the + * current invocation is the correct one. + * + * The matcher can store information from the invocation which can later + * be checked in verify(), or it can check the values directly and throw + * and exception if an expectation is not met. + * + * If the matcher is a stub it will also have a return value. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return mixed + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation); + + /** + * Checks if the invocation $invocation matches the current rules. If it does + * the matcher will get the invoked() method called which should check if an + * expectation is met. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return bool + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 2.2.0 + */ + +/** + * Invocation matcher which checks if a method has been invoked at least + * N times. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 2.2.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @var integer + */ + private $requiredInvocations; + + /** + * @param integer $requiredInvocations + */ + public function __construct($requiredInvocations) + { + $this->requiredInvocations = $requiredInvocations; + } + + /** + * @return string + */ + public function toString() + { + return 'invoked at least ' . $this->requiredInvocations . ' times'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + $count = $this->getInvocationCount(); + + if ($count < $this->requiredInvocations) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Expected invocation at least ' . $this->requiredInvocations . + ' times but it occured ' . $count . ' time(s).' + ); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which checks if a method has been invoked zero or more + * times. This matcher will always match. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @return string + */ + public function toString() + { + return 'invoked zero or more times'; + } + + /** + */ + public function verify() + { + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which allows any parameters to a method. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_AnyParameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + /** + * @return string + */ + public function toString() + { + return 'with any parameters'; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + return TRUE; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which checks if a method has been invoked at least one + * time. + * + * If the number of invocations is 0 it will throw an exception in verify. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce extends PHPUnit_Framework_MockObject_Matcher_InvokedRecorder +{ + /** + * @return string + */ + public function toString() + { + return 'invoked at least once'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + $count = $this->getInvocationCount(); + + if ($count < 1) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Expected invocation at least once but it never occured.' + ); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + */ + +/** + * Invocation matcher which looks for sets of specific parameters in the invocations. + * + * Checks the parameters of the incoming invocations, the parameter list is + * checked against the defined constraints in $parameters. If the constraint + * is met it will return true in matches(). + * + * It takes a list of match groups and and increases a call index after each invocation. + * So the first invocation uses the first group of constraints, the second the next and so on. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + */ +class PHPUnit_Framework_MockObject_Matcher_ConsecutiveParameters + extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + + /** + * @var array + */ + private $_parameterGroups = array(); + + /** + * @var array + */ + private $_invocations = array(); + + /** + * @param array $parameterGroups + */ + public function __construct(array $parameterGroups) + { + foreach ($parameterGroups as $index => $parameters) { + foreach ($parameters as $parameter) { + if (!($parameter instanceof \PHPUnit_Framework_Constraint)) + { + $parameter = new \PHPUnit_Framework_Constraint_IsEqual($parameter); + } + $this->_parameterGroups[$index][] = $parameter; + } + } + } + + /** + * @return string + */ + public function toString() + { + $text = 'with consecutive parameters'; + + return $text; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return bool + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->_invocations[] = $invocation; + $callIndex = count($this->_invocations) - 1; + $this->verifyInvocation($invocation, $callIndex); + return FALSE; + } + + public function verify() + { + foreach ($this->_invocations as $callIndex => $invocation) { + $this->verifyInvocation($invocation, $callIndex); + } + } + + /** + * Verify a single invocation + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @param int $callIndex + * @throws PHPUnit_Framework_ExpectationFailedException + */ + private function verifyInvocation(PHPUnit_Framework_MockObject_Invocation $invocation, $callIndex) + { + + if (isset($this->_parameterGroups[$callIndex])) { + $parameters = $this->_parameterGroups[$callIndex]; + } else { + // no parameter assertion for this call index + return; + } + + if ($invocation === NULL) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Mocked method does not exist.' + ); + } + + if (count($invocation->parameters) < count($parameters)) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + 'Parameter count for invocation %s is too low.', + $invocation->toString() + ) + ); + } + + foreach ($parameters as $i => $parameter) { + $parameter->evaluate( + $invocation->parameters[$i], + sprintf( + 'Parameter %s for invocation #%d %s does not match expected ' . + 'value.', + $i, + $callIndex, + $invocation->toString() + ) + ); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Invocation matcher which looks for specific parameters in the invocations. + * + * Checks the parameters of all incoming invocations, the parameter list is + * checked against the defined constraints in $parameters. If the constraint + * is met it will return true in matches(). + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher_Parameters extends PHPUnit_Framework_MockObject_Matcher_StatelessInvocation +{ + /** + * @var array + */ + protected $parameters = array(); + + /** + * @var PHPUnit_Framework_MockObject_Invocation + */ + protected $invocation; + + /** + * @param array $parameters + */ + public function __construct(array $parameters) + { + foreach ($parameters as $parameter) { + if (!($parameter instanceof PHPUnit_Framework_Constraint)) { + $parameter = new PHPUnit_Framework_Constraint_IsEqual( + $parameter + ); + } + + $this->parameters[] = $parameter; + } + } + + /** + * @return string + */ + public function toString() + { + $text = 'with parameter'; + + foreach ($this->parameters as $index => $parameter) { + if ($index > 0) { + $text .= ' and'; + } + + $text .= ' ' . $index . ' ' . $parameter->toString(); + } + + return $text; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + $this->invocation = $invocation; + return $this->verify(); + } + + /** + * Checks if the invocation $invocation matches the current rules. If it + * does the matcher will get the invoked() method called which should check + * if an expectation is met. + * + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * Object containing information on a mocked or stubbed method which + * was invoked. + * @return bool + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + if ($this->invocation === NULL) { + throw new PHPUnit_Framework_ExpectationFailedException( + 'Mocked method does not exist.' + ); + } + + if (count($this->invocation->parameters) < count($this->parameters)) { + $message = 'Parameter count for invocation %s is too low.'; + + // The user called `->with($this->anything())`, but may have meant + // `->withAnyParameters()`. + // + // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199 + if (count($this->parameters) === 1 && + get_class($this->parameters[0]) === 'PHPUnit_Framework_Constraint_IsAnything') { + $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead."; + } + + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf($message, $this->invocation->toString()) + ); + } + + foreach ($this->parameters as $i => $parameter) { + $parameter->evaluate( + $this->invocation->parameters[$i], + sprintf( + 'Parameter %s for invocation %s does not match expected ' . + 'value.', + + $i, + $this->invocation->toString() + ) + ); + } + + return true; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Main matcher which defines a full expectation using method, parameter and + * invocation matchers. + * This matcher encapsulates all the other matchers and allows the builder to + * set the specific matchers when the appropriate methods are called (once(), + * where() etc.). + * + * All properties are public so that they can easily be accessed by the builder. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Matcher implements PHPUnit_Framework_MockObject_Matcher_Invocation +{ + /** + * @var PHPUnit_Framework_MockObject_Matcher_Invocation + */ + public $invocationMatcher; + + /** + * @var mixed + */ + public $afterMatchBuilderId = NULL; + + /** + * @var boolean + */ + public $afterMatchBuilderIsInvoked = FALSE; + + /** + * @var PHPUnit_Framework_MockObject_Matcher_MethodName + */ + public $methodNameMatcher = NULL; + + /** + * @var PHPUnit_Framework_MockObject_Matcher_Parameters + */ + public $parametersMatcher = NULL; + + /** + * @var PHPUnit_Framework_MockObject_Stub + */ + public $stub = NULL; + + /** + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher + */ + public function __construct(PHPUnit_Framework_MockObject_Matcher_Invocation $invocationMatcher) + { + $this->invocationMatcher = $invocationMatcher; + } + + /** + * @return string + */ + public function toString() + { + $list = array(); + + if ($this->invocationMatcher !== NULL) { + $list[] = $this->invocationMatcher->toString(); + } + + if ($this->methodNameMatcher !== NULL) { + $list[] = 'where ' . $this->methodNameMatcher->toString(); + } + + if ($this->parametersMatcher !== NULL) { + $list[] = 'and ' . $this->parametersMatcher->toString(); + } + + if ($this->afterMatchBuilderId !== NULL) { + $list[] = 'after ' . $this->afterMatchBuilderId; + } + + if ($this->stub !== NULL) { + $list[] = 'will ' . $this->stub->toString(); + } + + return join(' ', $list); + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return mixed + */ + public function invoked(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if ($this->invocationMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'No invocation matcher is set' + ); + } + + if ($this->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception('No method matcher is set'); + } + + if ($this->afterMatchBuilderId !== NULL) { + $builder = $invocation->object + ->__phpunit_getInvocationMocker() + ->lookupId($this->afterMatchBuilderId); + + if (!$builder) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'No builder found for match builder identification <%s>', + + $this->afterMatchBuilderId + ) + ); + } + + $matcher = $builder->getMatcher(); + + if ($matcher && $matcher->invocationMatcher->hasBeenInvoked()) { + $this->afterMatchBuilderIsInvoked = TRUE; + } + } + + $this->invocationMatcher->invoked($invocation); + + try { + if ( $this->parametersMatcher !== NULL && + !$this->parametersMatcher->matches($invocation)) { + $this->parametersMatcher->verify(); + } + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + "Expectation failed for %s when %s\n%s", + + $this->methodNameMatcher->toString(), + $this->invocationMatcher->toString(), + $e->getMessage() + ), + $e->getComparisonFailure() + ); + } + + if ($this->stub) { + return $this->stub->invoke($invocation); + } + + return NULL; + } + + /** + * @param PHPUnit_Framework_MockObject_Invocation $invocation + * @return boolean + */ + public function matches(PHPUnit_Framework_MockObject_Invocation $invocation) + { + if ($this->afterMatchBuilderId !== NULL) { + $builder = $invocation->object + ->__phpunit_getInvocationMocker() + ->lookupId($this->afterMatchBuilderId); + + if (!$builder) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'No builder found for match builder identification <%s>', + + $this->afterMatchBuilderId + ) + ); + } + + $matcher = $builder->getMatcher(); + + if (!$matcher) { + return FALSE; + } + + if (!$matcher->invocationMatcher->hasBeenInvoked()) { + return FALSE; + } + } + + if ($this->invocationMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'No invocation matcher is set' + ); + } + + if ($this->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception('No method matcher is set'); + } + + if (!$this->invocationMatcher->matches($invocation)) { + return FALSE; + } + + try { + if (!$this->methodNameMatcher->matches($invocation)) { + return FALSE; + } + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + "Expectation failed for %s when %s\n%s", + + $this->methodNameMatcher->toString(), + $this->invocationMatcher->toString(), + $e->getMessage() + ), + $e->getComparisonFailure() + ); + } + + return TRUE; + } + + /** + * @throws PHPUnit_Framework_Exception + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify() + { + if ($this->invocationMatcher === NULL) { + throw new PHPUnit_Framework_Exception( + 'No invocation matcher is set' + ); + } + + if ($this->methodNameMatcher === NULL) { + throw new PHPUnit_Framework_Exception('No method matcher is set'); + } + + try { + $this->invocationMatcher->verify(); + + if ($this->parametersMatcher === NULL) { + $this->parametersMatcher = new PHPUnit_Framework_MockObject_Matcher_AnyParameters; + } + + $invocationIsAny = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount'; + $invocationIsNever = get_class($this->invocationMatcher) === 'PHPUnit_Framework_MockObject_Matcher_InvokedCount' && $this->invocationMatcher->isNever(); + if (!$invocationIsAny && !$invocationIsNever) { + $this->parametersMatcher->verify(); + } + } catch (PHPUnit_Framework_ExpectationFailedException $e) { + throw new PHPUnit_Framework_ExpectationFailedException( + sprintf( + "Expectation failed for %s when %s.\n%s", + + $this->methodNameMatcher->toString(), + $this->invocationMatcher->toString(), + PHPUnit_Framework_TestFailure::exceptionToString($e) + ) + ); + } + } + + /** + * @since Method available since Release 1.2.4 + */ + public function hasMatchers() + { + if ($this->invocationMatcher !== NULL && + !$this->invocationMatcher instanceof PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount) { + return TRUE; + } + + return FALSE; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +use Doctrine\Instantiator\Instantiator; +use Doctrine\Instantiator\Exception\InvalidArgumentException as InstantiatorInvalidArgumentException; +use Doctrine\Instantiator\Exception\UnexpectedValueException as InstantiatorUnexpectedValueException; + +if (!function_exists('trait_exists')) { + function trait_exists($traitname, $autoload = true) + { + return false; + } +} + +/** + * Mock Object Code Generator + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Framework_MockObject_Generator +{ + /** + * @var array + */ + private static $cache = array(); + + /** + * @var array + */ + protected $blacklistedMethodNames = array( + '__CLASS__' => TRUE, + '__DIR__' => TRUE, + '__FILE__' => TRUE, + '__FUNCTION__' => TRUE, + '__LINE__' => TRUE, + '__METHOD__' => TRUE, + '__NAMESPACE__' => TRUE, + '__TRAIT__' => TRUE, + '__clone' => TRUE, + '__halt_compiler' => TRUE, + 'abstract' => TRUE, + 'and' => TRUE, + 'array' => TRUE, + 'as' => TRUE, + 'break' => TRUE, + 'callable' => TRUE, + 'case' => TRUE, + 'catch' => TRUE, + 'class' => TRUE, + 'clone' => TRUE, + 'const' => TRUE, + 'continue' => TRUE, + 'declare' => TRUE, + 'default' => TRUE, + 'die' => TRUE, + 'do' => TRUE, + 'echo' => TRUE, + 'else' => TRUE, + 'elseif' => TRUE, + 'empty' => TRUE, + 'enddeclare' => TRUE, + 'endfor' => TRUE, + 'endforeach' => TRUE, + 'endif' => TRUE, + 'endswitch' => TRUE, + 'endwhile' => TRUE, + 'eval' => TRUE, + 'exit' => TRUE, + 'expects' => TRUE, + 'extends' => TRUE, + 'final' => TRUE, + 'for' => TRUE, + 'foreach' => TRUE, + 'function' => TRUE, + 'global' => TRUE, + 'goto' => TRUE, + 'if' => TRUE, + 'implements' => TRUE, + 'include' => TRUE, + 'include_once' => TRUE, + 'instanceof' => TRUE, + 'insteadof' => TRUE, + 'interface' => TRUE, + 'isset' => TRUE, + 'list' => TRUE, + 'namespace' => TRUE, + 'new' => TRUE, + 'or' => TRUE, + 'print' => TRUE, + 'private' => TRUE, + 'protected' => TRUE, + 'public' => TRUE, + 'require' => TRUE, + 'require_once' => TRUE, + 'return' => TRUE, + 'static' => TRUE, + 'switch' => TRUE, + 'throw' => TRUE, + 'trait' => TRUE, + 'try' => TRUE, + 'unset' => TRUE, + 'use' => TRUE, + 'var' => TRUE, + 'while' => TRUE, + 'xor' => TRUE + ); + + /** + * @var boolean + */ + protected $soapLoaded = NULL; + + /** + * Returns a mock object for the specified class. + * + * @param array|string $type + * @param array $methods + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @param boolean $callOriginalMethods + * @param object $proxyTarget + * @return object + * @throws InvalidArgumentException + * @throws PHPUnit_Framework_Exception + * @throws PHPUnit_Framework_MockObject_RuntimeException + * @since Method available since Release 1.0.0 + */ + public function getMock($type, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = TRUE, $callOriginalMethods = FALSE, $proxyTarget = NULL) + { + if (!is_array($type) && !is_string($type)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'array or string'); + } + + if (!is_string($mockClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(4, 'string'); + } + + if (!is_array($methods) && !is_null($methods)) { + throw new InvalidArgumentException; + } + + if ($type === 'Traversable' || $type === '\\Traversable') { + $type = 'Iterator'; + } + + if (is_array($type)) { + $type = array_unique(array_map( + function ($type) { + if ($type === 'Traversable' || + $type === '\\Traversable' || + $type === '\\Iterator') { + return 'Iterator'; + } + + return $type; + }, + $type + )); + } + + if (NULL !== $methods) { + foreach ($methods as $method) { + if (!preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', $method)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Cannot stub or mock method with invalid name "%s"', + $method + ) + ); + } + } + + if ($methods != array_unique($methods)) { + throw new PHPUnit_Framework_MockObject_RuntimeException( + sprintf( + 'Cannot stub or mock using a method list that contains duplicates: "%s"', + implode(', ', $methods) + ) + ); + } + } + + if ($mockClassName != '' && class_exists($mockClassName, FALSE)) { + $reflect = new ReflectionClass($mockClassName); + + if (!$reflect->implementsInterface("PHPUnit_Framework_MockObject_MockObject")) { + throw new PHPUnit_Framework_MockObject_RuntimeException( + sprintf( + 'Class "%s" already exists.', + $mockClassName + ) + ); + } + } + + $mock = $this->generate( + $type, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload, + $cloneArguments, + $callOriginalMethods + ); + + return $this->getObject( + $mock['code'], + $mock['mockClassName'], + $type, + $callOriginalConstructor, + $callAutoload, + $arguments, + $callOriginalMethods, + $proxyTarget + ); + } + + /** + * @param string $code + * @param string $className + * @param array|string $type + * @param boolean $callOriginalConstructor + * @param boolean $callAutoload + * @param array $arguments + * @param boolean $callOriginalMethods + * @param object $proxyTarget + * @return object + */ + protected function getObject($code, $className, $type = '', $callOriginalConstructor = FALSE, $callAutoload = FALSE, array $arguments = array(), $callOriginalMethods = FALSE, $proxyTarget = NULL) + { + $this->evalClass($code, $className); + + if ($callOriginalConstructor && + is_string($type) && + !interface_exists($type, $callAutoload)) { + if (count($arguments) == 0) { + $object = new $className; + } else { + $class = new ReflectionClass($className); + $object = $class->newInstanceArgs($arguments); + } + } else { + try { + $instantiator = new Instantiator; + $object = $instantiator->instantiate($className); + } catch (InstantiatorUnexpectedValueException $exception) { + if($exception->getPrevious()) { + $exception = $exception->getPrevious(); + } + + throw new PHPUnit_Framework_MockObject_RuntimeException( + $exception->getMessage() + ); + } catch (InstantiatorInvalidArgumentException $exception) { + throw new PHPUnit_Framework_MockObject_RuntimeException( + $exception->getMessage() + ); + } + } + + if ($callOriginalMethods) { + if (!is_object($proxyTarget)) { + if (count($arguments) == 0) { + $proxyTarget = new $type; + } else { + $class = new ReflectionClass($type); + $proxyTarget = $class->newInstanceArgs($arguments); + } + } + + $object->__phpunit_setOriginalObject($proxyTarget); + } + + return $object; + } + + /** + * @param string $code + * @param string $className + */ + protected function evalClass($code, $className) + { + if (!class_exists($className, FALSE)) { + eval($code); + } + } + + /** + * Returns a mock object for the specified abstract class with all abstract + * methods of the class mocked. Concrete methods to mock can be specified with + * the last parameter + * + * @param string $originalClassName + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param array $mockedMethods + * @param boolean $cloneArguments + * @return object + * @since Method available since Release 1.0.0 + * @throws PHPUnit_Framework_MockObject_RuntimeException + * @throws PHPUnit_Framework_Exception + */ + public function getMockForAbstractClass($originalClassName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $mockedMethods = array(), $cloneArguments = TRUE) + { + if (!is_string($originalClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($mockClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string'); + } + + if (class_exists($originalClassName, $callAutoload) || + interface_exists($originalClassName, $callAutoload)) { + $reflector = new ReflectionClass($originalClassName); + $methods = $mockedMethods; + + foreach ($reflector->getMethods() as $method) { + if ($method->isAbstract() && !in_array($method->getName(), $methods)) { + $methods[] = $method->getName(); + } + } + + if (empty($methods)) { + $methods = NULL; + } + + return $this->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + } else { + throw new PHPUnit_Framework_MockObject_RuntimeException( + sprintf('Class "%s" does not exist.', $originalClassName) + ); + } + } + + /** + * Returns a mock object for the specified trait with all abstract methods + * of the trait mocked. Concrete methods to mock can be specified with the + * `$mockedMethods` parameter. + * + * @param string $traitName + * @param array $arguments + * @param string $mockClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param array $mockedMethods + * @param boolean $cloneArguments + * @return object + * @since Method available since Release 1.2.3 + * @throws PHPUnit_Framework_MockObject_RuntimeException + * @throws PHPUnit_Framework_Exception + */ + public function getMockForTrait($traitName, array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE, $mockedMethods = array(), $cloneArguments = TRUE) + { + if (!is_string($traitName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($mockClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string'); + } + + if (!trait_exists($traitName, $callAutoload)) { + throw new PHPUnit_Framework_MockObject_RuntimeException( + sprintf( + 'Trait "%s" does not exist.', + $traitName + ) + ); + } + + $className = $this->generateClassName( + $traitName, '', 'Trait_' + ); + + $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . + DIRECTORY_SEPARATOR; + $classTemplate = new Text_Template( + $templateDir . 'trait_class.tpl' + ); + + $classTemplate->setVar( + array( + 'prologue' => 'abstract ', + 'class_name' => $className['className'], + 'trait_name' => $traitName + ) + ); + + $this->evalClass( + $classTemplate->render(), + $className['className'] + ); + + return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); + } + + /** + * Returns an object for the specified trait. + * + * @param string $traitName + * @param array $arguments + * @param string $traitClassName + * @param boolean $callOriginalConstructor + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @return object + * @since Method available since Release 1.1.0 + * @throws PHPUnit_Framework_MockObject_RuntimeException + * @throws PHPUnit_Framework_Exception + */ + public function getObjectForTrait($traitName, array $arguments = array(), $traitClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) + { + if (!is_string($traitName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + if (!is_string($traitClassName)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'string'); + } + + if (!trait_exists($traitName, $callAutoload)) { + throw new PHPUnit_Framework_MockObject_RuntimeException( + sprintf( + 'Trait "%s" does not exist.', + $traitName + ) + ); + } + + $className = $this->generateClassName( + $traitName, $traitClassName, 'Trait_' + ); + + $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . + DIRECTORY_SEPARATOR; + $classTemplate = new Text_Template( + $templateDir . 'trait_class.tpl' + ); + + $classTemplate->setVar( + array( + 'prologue' => '', + 'class_name' => $className['className'], + 'trait_name' => $traitName + ) + ); + + return $this->getObject( + $classTemplate->render(), + $className['className'] + ); + } + + /** + * @param array|string $type + * @param array $methods + * @param string $mockClassName + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @param boolean $callOriginalMethods + * @return array + */ + public function generate($type, array $methods = NULL, $mockClassName = '', $callOriginalClone = TRUE, $callAutoload = TRUE, $cloneArguments = TRUE, $callOriginalMethods = FALSE) + { + if (is_array($type)) { + sort($type); + } + + if ($mockClassName == '') { + $key = md5( + is_array($type) ? join('_', $type) : $type . + serialize($methods) . + serialize($callOriginalClone) . + serialize($cloneArguments) . + serialize($callOriginalMethods) + ); + + if (isset(self::$cache[$key])) { + return self::$cache[$key]; + } + } + + $mock = $this->generateMock( + $type, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload, + $cloneArguments, + $callOriginalMethods + ); + + if (isset($key)) { + self::$cache[$key] = $mock; + } + + return $mock; + } + + /** + * @param string $wsdlFile + * @param string $className + * @param array $methods + * @param array $options + * @return string + * @throws PHPUnit_Framework_MockObject_RuntimeException + */ + public function generateClassFromWsdl($wsdlFile, $className, array $methods = array(), array $options = array()) + { + if ($this->soapLoaded === NULL) { + $this->soapLoaded = extension_loaded('soap'); + } + + if ($this->soapLoaded) { + $options = array_merge($options, array('cache_wsdl'=>FALSE)); + $client = new SoapClient($wsdlFile, $options); + $_methods = array_unique($client->__getFunctions()); + unset($client); + + sort($_methods); + + $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . + 'Generator' . DIRECTORY_SEPARATOR; + $methodTemplate = new Text_Template( + $templateDir . 'wsdl_method.tpl' + ); + $methodsBuffer = ''; + + foreach ($_methods as $method) { + $nameStart = strpos($method, ' ') + 1; + $nameEnd = strpos($method, '('); + $name = substr($method, $nameStart, $nameEnd - $nameStart); + + if (empty($methods) || in_array($name, $methods)) { + $args = explode( + ',', + substr( + $method, + $nameEnd + 1, + strpos($method, ')') - $nameEnd - 1 + ) + ); + $numArgs = count($args); + + for ($i = 0; $i < $numArgs; $i++) { + $args[$i] = substr($args[$i], strpos($args[$i], '$')); + } + + $methodTemplate->setVar( + array( + 'method_name' => $name, + 'arguments' => join(', ', $args) + ) + ); + + $methodsBuffer .= $methodTemplate->render(); + } + } + + $optionsBuffer = 'array('; + + foreach ($options as $key => $value) { + $optionsBuffer .= $key . ' => ' . $value; + } + + $optionsBuffer .= ')'; + + $classTemplate = new Text_Template( + $templateDir . 'wsdl_class.tpl' + ); + + $namespace = ''; + + if (strpos($className, '\\') !== FALSE) { + $parts = explode('\\', $className); + $className = array_pop($parts); + $namespace = 'namespace ' . join('\\', $parts) . ';' . "\n\n"; + } + + $classTemplate->setVar( + array( + 'namespace' => $namespace, + 'class_name' => $className, + 'wsdl' => $wsdlFile, + 'options' => $optionsBuffer, + 'methods' => $methodsBuffer + ) + ); + + return $classTemplate->render(); + } else { + throw new PHPUnit_Framework_MockObject_RuntimeException( + 'The SOAP extension is required to generate a mock object ' . + 'from WSDL.' + ); + } + } + + /** + * @param array|string $type + * @param array|null $methods + * @param string $mockClassName + * @param boolean $callOriginalClone + * @param boolean $callAutoload + * @param boolean $cloneArguments + * @param boolean $callOriginalMethods + * @return array + * @throws PHPUnit_Framework_Exception + */ + protected function generateMock($type, $methods, $mockClassName, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods) + { + $templateDir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Generator' . + DIRECTORY_SEPARATOR; + $classTemplate = new Text_Template( + $templateDir . 'mocked_class.tpl' + ); + + $additionalInterfaces = array(); + $cloneTemplate = ''; + $isClass = FALSE; + $isInterface = FALSE; + + $mockClassName = $this->generateClassName( + $type, $mockClassName, 'Mock_' + ); + + if (is_array($type)) { + foreach ($type as $_type) { + if (!interface_exists($_type, $callAutoload)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Interface "%s" does not exist.', $_type + ) + ); + } + + $additionalInterfaces[] = $_type; + + foreach (get_class_methods($_type) as $method) { + if (in_array($method, $methods)) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Duplicate method "%s" not allowed.', $method + ) + ); + } + + $methods[] = $method; + } + } + } + + if (class_exists($mockClassName['fullClassName'], $callAutoload)) { + $isClass = TRUE; + } else { + if (interface_exists($mockClassName['fullClassName'], $callAutoload)) { + $isInterface = TRUE; + } + } + + if (!class_exists($mockClassName['fullClassName'], $callAutoload) && + !interface_exists($mockClassName['fullClassName'], $callAutoload)) { + $prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n"; + + if (!empty($mockClassName['namespaceName'])) { + $prologue = 'namespace ' . $mockClassName['namespaceName'] . + " {\n\n" . $prologue . "}\n\n" . + "namespace {\n\n"; + + $epilogue = "\n\n}"; + } + + $cloneTemplate = new Text_Template( + $templateDir . 'mocked_clone.tpl' + ); + } else { + $class = new ReflectionClass($mockClassName['fullClassName']); + + if ($class->isFinal()) { + throw new PHPUnit_Framework_Exception( + sprintf( + 'Class "%s" is declared "final" and cannot be mocked.', + $mockClassName['fullClassName'] + ) + ); + } + + if ($class->hasMethod('__clone')) { + $cloneMethod = $class->getMethod('__clone'); + + if (!$cloneMethod->isFinal()) { + if ($callOriginalClone && !$isInterface) { + $cloneTemplate = new Text_Template( + $templateDir . 'unmocked_clone.tpl' + ); + } else { + $cloneTemplate = new Text_Template( + $templateDir . 'mocked_clone.tpl' + ); + } + } + } else { + $cloneTemplate = new Text_Template( + $templateDir . 'mocked_clone.tpl' + ); + } + } + + if (is_object($cloneTemplate)) { + $cloneTemplate = $cloneTemplate->render(); + } + + if (is_array($methods) && empty($methods) && + ($isClass || $isInterface)) { + $methods = get_class_methods($mockClassName['fullClassName']); + } + + if (!is_array($methods)) { + $methods = array(); + } + + $mockedMethods = ''; + + if (isset($class)) { + // https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103 + if ($isInterface && $class->implementsInterface('Traversable') && + !$class->implementsInterface('Iterator') && + !$class->implementsInterface('IteratorAggregate')) { + $additionalInterfaces[] = 'Iterator'; + $methods = array_merge($methods, get_class_methods('Iterator')); + } + + foreach ($methods as $methodName) { + try { + $method = $class->getMethod($methodName); + + if ($this->canMockMethod($method)) { + $mockedMethods .= $this->generateMockedMethodDefinitionFromExisting( + $templateDir, + $method, + $cloneArguments, + $callOriginalMethods + ); + } + } catch (ReflectionException $e) { + $mockedMethods .= $this->generateMockedMethodDefinition( + $templateDir, $mockClassName['fullClassName'], $methodName, $cloneArguments + ); + } + } + } else { + foreach ($methods as $methodName) { + $mockedMethods .= $this->generateMockedMethodDefinition( + $templateDir, $mockClassName['fullClassName'], $methodName, $cloneArguments + ); + } + } + + $method = ''; + + if (!in_array('method', $methods)) { + $methodTemplate = new Text_Template( + $templateDir . 'mocked_class_method.tpl' + ); + + $method = $methodTemplate->render(); + } + + $classTemplate->setVar( + array( + 'prologue' => isset($prologue) ? $prologue : '', + 'epilogue' => isset($epilogue) ? $epilogue : '', + 'class_declaration' => $this->generateMockClassDeclaration( + $mockClassName, + $isInterface, + $additionalInterfaces + ), + 'clone' => $cloneTemplate, + 'mock_class_name' => $mockClassName['className'], + 'mocked_methods' => $mockedMethods, + 'method' => $method + ) + ); + + return array( + 'code' => $classTemplate->render(), + 'mockClassName' => $mockClassName['className'] + ); + } + + /** + * @param array|string $type + * @param string $className + * @param string $prefix + * @return array + */ + protected function generateClassName($type, $className, $prefix) + { + if (is_array($type)) { + $type = join('_', $type); + } + + if ($type[0] == '\\') { + $type = substr($type, 1); + } + + $classNameParts = explode('\\', $type); + + if (count($classNameParts) > 1) { + $type = array_pop($classNameParts); + $namespaceName = join('\\', $classNameParts); + $fullClassName = $namespaceName . '\\' . $type; + } else { + $namespaceName = ''; + $fullClassName = $type; + } + + if ($className == '') { + do { + $className = $prefix . $type . '_' . + substr(md5(microtime()), 0, 8); + } while (class_exists($className, FALSE)); + } + + return array( + 'className' => $className, + 'originalClassName' => $type, + 'fullClassName' => $fullClassName, + 'namespaceName' => $namespaceName + ); + } + + /** + * @param array $mockClassName + * @param boolean $isInterface + * @param array $additionalInterfaces + * @return array + */ + protected function generateMockClassDeclaration(array $mockClassName, $isInterface, array $additionalInterfaces = array()) + { + $buffer = 'class '; + + $additionalInterfaces[] = 'PHPUnit_Framework_MockObject_MockObject'; + $interfaces = implode(', ', $additionalInterfaces); + + if ($isInterface) { + $buffer .= sprintf( + "%s implements %s", + $mockClassName['className'], + $interfaces + ); + + if (!in_array($mockClassName['originalClassName'], $additionalInterfaces)) { + $buffer .= ', '; + + if (!empty($mockClassName['namespaceName'])) { + $buffer .= $mockClassName['namespaceName'] . '\\'; + } + + $buffer .= $mockClassName['originalClassName']; + } + } else { + $buffer .= sprintf( + "%s extends %s%s implements %s", + $mockClassName['className'], + !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '', + $mockClassName['originalClassName'], + $interfaces + ); + } + + return $buffer; + } + + /** + * @param string $templateDir + * @param ReflectionMethod $method + * @param boolean $cloneArguments + * @param boolean $callOriginalMethods + * @return string + */ + protected function generateMockedMethodDefinitionFromExisting($templateDir, ReflectionMethod $method, $cloneArguments, $callOriginalMethods) + { + if ($method->isPrivate()) { + $modifier = 'private'; + } elseif ($method->isProtected()) { + $modifier = 'protected'; + } else { + $modifier = 'public'; + } + + if ($method->isStatic()) { + $modifier .= ' static'; + } + + if ($method->returnsReference()) { + $reference = '&'; + } else { + $reference = ''; + } + + return $this->generateMockedMethodDefinition( + $templateDir, + $method->getDeclaringClass()->getName(), + $method->getName(), + $cloneArguments, + $modifier, + $this->getMethodParameters($method), + $this->getMethodParameters($method, TRUE), + $reference, + $callOriginalMethods, + $method->isStatic() + ); + } + + /** + * @param string $templateDir + * @param string $className + * @param string $methodName + * @param boolean $cloneArguments + * @param string $modifier + * @param string $arguments_decl + * @param string $arguments_call + * @param string $reference + * @param boolean $callOriginalMethods + * @param boolean $static + * @return string + */ + protected function generateMockedMethodDefinition($templateDir, $className, $methodName, $cloneArguments = TRUE, $modifier = 'public', $arguments_decl = '', $arguments_call = '', $reference = '', $callOriginalMethods = FALSE, $static = FALSE) + { + if ($static) { + $templateFile = 'mocked_static_method.tpl'; + } else { + $templateFile = sprintf( + '%s_method.tpl', + $callOriginalMethods ? 'proxied' : 'mocked' + ); + } + + $template = new Text_Template($templateDir . $templateFile); + + $template->setVar( + array( + 'arguments_decl' => $arguments_decl, + 'arguments_call' => $arguments_call, + 'arguments_count' => !empty($arguments_call) ? count(explode(',', $arguments_call)) : 0, + 'class_name' => $className, + 'method_name' => $methodName, + 'modifier' => $modifier, + 'reference' => $reference, + 'clone_arguments' => $cloneArguments ? 'TRUE' : 'FALSE' + ) + ); + + return $template->render(); + } + + /** + * @param ReflectionMethod $method + * @return boolean + */ + protected function canMockMethod(ReflectionMethod $method) + { + if ($method->isConstructor() || + $method->isFinal() || + isset($this->blacklistedMethodNames[$method->getName()])) { + return FALSE; + } + + return TRUE; + } + + /** + * Returns the parameters of a function or method. + * + * @param ReflectionMethod $method + * @param boolean $forCall + * @return string + * @throws PHPUnit_Framework_MockObject_RuntimeException + * @since Method available since Release 2.0.0 + */ + protected function getMethodParameters(ReflectionMethod $method, $forCall = FALSE) + { + $parameters = array(); + + foreach ($method->getParameters() as $i => $parameter) { + $name = '$' . $parameter->getName(); + + /* Note: PHP extensions may use empty names for reference arguments + * or "..." for methods taking a variable number of arguments. + */ + if ($name === '$' || $name === '$...') { + $name = '$arg' . $i; + } + + if ($this->isVariadic($parameter)) { + if ($forCall) { + continue; + } else { + $name = '...' . $name; + } + } + + $default = ''; + $reference = ''; + $typeHint = ''; + + if (!$forCall) { + if ($parameter->isArray()) { + $typeHint = 'array '; + } elseif ((defined('HHVM_VERSION') || version_compare(PHP_VERSION, '5.4.0', '>=')) + && $parameter->isCallable()) { + $typeHint = 'callable '; + } else { + try { + $class = $parameter->getClass(); + } catch (ReflectionException $e) { + throw new PHPUnit_Framework_MockObject_RuntimeException( + sprintf( + 'Cannot mock %s::%s() because a class or ' . + 'interface used in the signature is not loaded', + $method->getDeclaringClass()->getName(), + $method->getName() + ), + 0, + $e + ); + } + + if ($class !== NULL) { + $typeHint = $class->getName() . ' '; + } + } + + if (!$this->isVariadic($parameter)) { + if ($parameter->isDefaultValueAvailable()) { + $value = $parameter->getDefaultValue(); + $default = ' = ' . var_export($value, TRUE); + } elseif ($parameter->isOptional()) { + $default = ' = null'; + } + } + } + + if ($parameter->isPassedByReference()) { + $reference = '&'; + } + + $parameters[] = $typeHint . $reference . $name . $default; + } + + return join(', ', $parameters); + } + + /** + * @param ReflectionParameter $parameter + * @return boolean + * @since Method available since Release 2.2.1 + */ + private function isVariadic(ReflectionParameter $parameter) + { + return method_exists('ReflectionParameter', 'isVariadic') && $parameter->isVariadic(); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Interface for invocations. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Invocation +{ +} + + public function method() + { + $any = new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount; + $expects = $this->expects($any); + return call_user_func_array(array($expects, 'method'), func_get_args()); + } + + public function {method_name}({arguments}) + { + } +{prologue}class {class_name} +{ + use {trait_name}; +} + + {modifier} function {reference}{method_name}({arguments_decl}) + { + $arguments = array({arguments_call}); + $count = func_num_args(); + + if ($count > {arguments_count}) { + $_arguments = func_get_args(); + + for ($i = {arguments_count}; $i < $count; $i++) { + $arguments[] = $_arguments[$i]; + } + } + + $result = $this->__phpunit_getInvocationMocker()->invoke( + new PHPUnit_Framework_MockObject_Invocation_Object( + '{class_name}', '{method_name}', $arguments, $this, {clone_arguments} + ) + ); + + return $result; + } + public function __clone() + { + $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker(); + parent::__clone(); + } +{prologue}{class_declaration} +{ + private $__phpunit_invocationMocker; + private $__phpunit_originalObject; + +{clone}{mocked_methods} + public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher) + { + return $this->__phpunit_getInvocationMocker()->expects($matcher); + } +{method} + public function __phpunit_setOriginalObject($originalObject) + { + $this->__phpunit_originalObject = $originalObject; + } + + public function __phpunit_getInvocationMocker() + { + if ($this->__phpunit_invocationMocker === NULL) { + $this->__phpunit_invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker; + } + + return $this->__phpunit_invocationMocker; + } + + public function __phpunit_hasMatchers() + { + return $this->__phpunit_getInvocationMocker()->hasMatchers(); + } + + public function __phpunit_verify() + { + $this->__phpunit_getInvocationMocker()->verify(); + $this->__phpunit_invocationMocker = NULL; + } +}{epilogue} + + {modifier} function {reference}{method_name}({arguments_decl}) + { + throw new PHPUnit_Framework_MockObject_BadMethodCallException; + } +{namespace}class {class_name} extends \SoapClient +{ + public function __construct($wsdl, array $options) + { + parent::__construct('{wsdl}', $options); + } +{methods}} + + {modifier} function {reference}{method_name}({arguments_decl}) + { + $arguments = array({arguments_call}); + $count = func_num_args(); + + if ($count > {arguments_count}) { + $_arguments = func_get_args(); + + for ($i = {arguments_count}; $i < $count; $i++) { + $arguments[] = $_arguments[$i]; + } + } + + $this->__phpunit_getInvocationMocker()->invoke( + new PHPUnit_Framework_MockObject_Invocation_Object( + '{class_name}', '{method_name}', $arguments, $this, {clone_arguments} + ) + ); + + return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $arguments); + } + public function __clone() + { + $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationMocker(); + } +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Interface for all mock objects which are generated by + * PHPUnit_Framework_MockObject_MockBuilder. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_MockObject /*extends PHPUnit_Framework_MockObject_Verifiable*/ +{ + /** + * Registers a new expectation in the mock object and returns the match + * object which can be infused with further details. + * + * @param PHPUnit_Framework_MockObject_Matcher_Invocation $matcher + * @return PHPUnit_Framework_MockObject_Builder_InvocationMocker + */ + public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation $matcher); + + /** + * @return PHPUnit_Framework_MockObject_InvocationMocker + * @since Method available since Release 2.0.0 + */ + public function __phpunit_setOriginalObject($originalObject); + + /** + * @return PHPUnit_Framework_MockObject_InvocationMocker + */ + public function __phpunit_getInvocationMocker(); + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function __phpunit_verify(); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since File available since Release 1.0.0 + */ + +/** + * Interface for classes which must verify a given expectation. + * + * @package PHPUnit_MockObject + * @author Sebastian Bergmann + * @copyright 2010-2014 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://github.com/sebastianbergmann/phpunit-mock-objects + * @since Interface available since Release 1.0.0 + */ +interface PHPUnit_Framework_MockObject_Verifiable +{ + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws PHPUnit_Framework_ExpectationFailedException + */ + public function verify(); +} +PHPUnit_MockObject + +Copyright (c) 2002-2014, Sebastian Bergmann . +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of Sebastian Bergmann nor the names of his + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Sebastian Bergmann + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.0.0 + */ + +/** + * Implementation of the Selenium RC client/server protocol. + * + * @package PHPUnit_Selenium + * @author Sebastian Bergmann + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.0.0 + */ +class PHPUnit_Extensions_SeleniumTestCase_Driver +{ + /** + * @var PHPUnit_Extensions_SeleniumTestCase + */ + protected $testCase; + + /** + * @var string + */ + protected $testId; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $browser; + + /** + * @var string + */ + protected $browserUrl; + + /** + * @var boolean + */ + protected $collectCodeCoverageInformation = FALSE; + + /** + * @var string + */ + protected $host = 'localhost'; + + /** + * @var integer + */ + protected $port = 4444; + + /** + * @var integer + */ + protected $httpTimeout = 45; + + /** + * @var integer + */ + protected $seleniumTimeout = 30; + + /** + * @var string + */ + protected $sessionId; + + /** + * @var integer + */ + protected $sleep = 0; + + /** + * @var boolean + */ + protected $useWaitForPageToLoad = TRUE; + + /** + * @var boolean + */ + protected $wait = 5; + + /** + * @var array + */ + protected static $autoGeneratedCommands = array(); + + /** + * @var array + */ + protected $commands = array(); + + /** + * @var array $userCommands A numerical array which holds custom user commands. + */ + protected $userCommands = array(); + + /** + * @var array + */ + protected $verificationErrors = array(); + + /** + * @var array + */ + private $webDriverCapabilities; + + public function __construct() + { + if (empty(self::$autoGeneratedCommands)) { + self::autoGenerateCommands(); + } + } + + /** + * Only browserName is supported. + */ + public function setWebDriverCapabilities(array $capabilities) + { + $this->webDriverCapabilities = $capabilities; + } + + /** + * @return string + */ + public function start() + { + if ($this->browserUrl == NULL) { + throw new PHPUnit_Framework_Exception( + 'setBrowserUrl() needs to be called before start().' + ); + } + + if ($this->webDriverCapabilities !== NULL) { + $seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($this->host, $this->port); + $driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl); + $session = $driver->startSession($this->webDriverCapabilities, new PHPUnit_Extensions_Selenium2TestCase_URL($this->browserUrl)); + $webDriverSessionId = $session->id(); + $this->sessionId = $this->getString( + 'getNewBrowserSession', + array($this->browser, $this->browserUrl, '', + "webdriver.remote.sessionid=$webDriverSessionId") + ); + + $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000)); + } + + if (!isset($this->sessionId)) { + $this->sessionId = $this->getString( + 'getNewBrowserSession', + array($this->browser, $this->browserUrl) + ); + + $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000)); + } + + return $this->sessionId; + } + + /** + * @return string + * @since Method available since Release 1.1.0 + */ + public function getSessionId() + { + return $this->sessionId; + } + + /** + * @param string + * @since Method available since Release 1.2.0 + */ + public function setSessionId($sessionId) + { + $this->sessionId = $sessionId; + } + + /** + */ + public function stop() + { + if (!isset($this->sessionId)) { + return; + } + + $this->doCommand('testComplete'); + + $this->sessionId = NULL; + } + + /** + * @param boolean $flag + * @throws InvalidArgumentException + */ + public function setCollectCodeCoverageInformation($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->collectCodeCoverageInformation = $flag; + } + + /** + * @param PHPUnit_Extensions_SeleniumTestCase $testCase + */ + public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase) + { + $this->testCase = $testCase; + } + + /** + * @param integer $testId + */ + public function setTestId($testId) + { + $this->testId = $testId; + } + + /** + * @return integer $testId + */ + public function getTestId() + { + return $this->testId; + } + + /** + * @param string $name + * @throws InvalidArgumentException + */ + public function setName($name) + { + if (!is_string($name)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->name = $name; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @param string $browser + * @throws InvalidArgumentException + */ + public function setBrowser($browser) + { + if (!is_string($browser)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->browser = $browser; + } + + /** + * @return string + */ + public function getBrowser() + { + return $this->browser; + } + + /** + * @param string $browserUrl + * @throws InvalidArgumentException + */ + public function setBrowserUrl($browserUrl) + { + if (!is_string($browserUrl)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->browserUrl = $browserUrl; + } + + /** + * @param string $host + * @throws InvalidArgumentException + */ + public function setHost($host) + { + if (!is_string($host)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->host = $host; + } + + /** + * @return string + * @since Method available since Release 1.1.0 + */ + public function getHost() + { + return $this->host; + } + + /** + * @param integer $port + * @throws InvalidArgumentException + */ + public function setPort($port) + { + if (!is_int($port)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->port = $port; + } + + /** + * @return integer + * @since Method available since Release 1.1.0 + */ + public function getPort() + { + return $this->port; + } + + /** + * @param integer $timeout for Selenium RC in seconds + * @throws InvalidArgumentException + */ + public function setTimeout($timeout) + { + if (!is_int($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->seleniumTimeout = $timeout; + } + + /** + * @param integer $timeout for HTTP connection to Selenium RC in seconds + * @throws InvalidArgumentException + */ + public function setHttpTimeout($timeout) + { + if (!is_int($timeout)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->httpTimeout = $timeout; + } + + /** + * @param integer $seconds + * @throws InvalidArgumentException + */ + public function setSleep($seconds) + { + if (!is_int($seconds)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->sleep = $seconds; + } + + /** + * Sets the number of seconds to sleep() after *AndWait commands + * when setWaitForPageToLoad(FALSE) is used. + * + * @param integer $seconds + * @throws InvalidArgumentException + */ + public function setWait($seconds) + { + if (!is_int($seconds)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer'); + } + + $this->wait = $seconds; + } + + /** + * Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE) + * is used after *AndWait commands. + * + * @param boolean $flag + * @throws InvalidArgumentException + */ + public function setWaitForPageToLoad($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->useWaitForPageToLoad = $flag; + } + /** + * Sets whether captureScreenshotOnFailure (TRUE) or (FALSE) + * if true, the takeScreenshot() is triggered in onNotSuccessfulTest(). + * + * @param boolean $flag + * @throws InvalidArgumentException + */ + public function setCaptureScreenshotOnFailure($flag) + { + if (!is_bool($flag)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); + } + + $this->captureScreenshotOnFailure = $flag; + } + + /** + * @param string $screenshotUrl + * @throws InvalidArgumentException + */ + public function setScreenshotUrl($screenshotUrl) + { + if (!is_string($screenshotUrl)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->screenshotUrl = $screenshotUrl; + } + /** + * @param string $screenshotPath + * @throws InvalidArgumentException + */ + public function setScreenshotPath($screenshotPath) + { + if (!is_string($screenshotPath)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + + $this->screenshotPath = $screenshotPath; + } + + /** + * Adds allowed user commands into {@link self::$userCommands}. See + * {@link self::__call()} (switch/case -> default) for usage. + * + * @param string $command A command. + * + * @return $this + * @see self::__call() + */ + + + public function addUserCommand($command) + { + if (!is_string($command)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string'); + } + $this->userCommands[] = $command; + return $this; + } + + /** + * This method implements the Selenium RC protocol. + * + * @param string $command + * @param array $arguments + * @return mixed + * @method unknown addLocationStrategy() + * @method unknown addLocationStrategyAndWait() + * @method unknown addScript() + * @method unknown addScriptAndWait() + * @method unknown addSelection() + * @method unknown addSelectionAndWait() + * @method unknown allowNativeXpath() + * @method unknown allowNativeXpathAndWait() + * @method unknown altKeyDown() + * @method unknown altKeyDownAndWait() + * @method unknown altKeyUp() + * @method unknown altKeyUpAndWait() + * @method unknown answerOnNextPrompt() + * @method unknown assignId() + * @method unknown assignIdAndWait() + * @method unknown attachFile() + * @method unknown break() + * @method unknown captureEntirePageScreenshot() + * @method unknown captureEntirePageScreenshotAndWait() + * @method unknown captureEntirePageScreenshotToStringAndWait() + * @method unknown captureScreenshotAndWait() + * @method unknown captureScreenshotToStringAndWait() + * @method unknown check() + * @method unknown checkAndWait() + * @method unknown chooseCancelOnNextConfirmation() + * @method unknown chooseCancelOnNextConfirmationAndWait() + * @method unknown chooseOkOnNextConfirmation() + * @method unknown chooseOkOnNextConfirmationAndWait() + * @method unknown click() + * @method unknown clickAndWait() + * @method unknown clickAt() + * @method unknown clickAtAndWait() + * @method unknown close() + * @method unknown contextMenu() + * @method unknown contextMenuAndWait() + * @method unknown contextMenuAt() + * @method unknown contextMenuAtAndWait() + * @method unknown controlKeyDown() + * @method unknown controlKeyDownAndWait() + * @method unknown controlKeyUp() + * @method unknown controlKeyUpAndWait() + * @method unknown createCookie() + * @method unknown createCookieAndWait() + * @method unknown deleteAllVisibleCookies() + * @method unknown deleteAllVisibleCookiesAndWait() + * @method unknown deleteCookie() + * @method unknown deleteCookieAndWait() + * @method unknown deselectPopUp() + * @method unknown deselectPopUpAndWait() + * @method unknown doubleClick() + * @method unknown doubleClickAndWait() + * @method unknown doubleClickAt() + * @method unknown doubleClickAtAndWait() + * @method unknown dragAndDrop() + * @method unknown dragAndDropAndWait() + * @method unknown dragAndDropToObject() + * @method unknown dragAndDropToObjectAndWait() + * @method unknown dragDrop() + * @method unknown dragDropAndWait() + * @method unknown echo() + * @method unknown fireEvent() + * @method unknown fireEventAndWait() + * @method unknown focus() + * @method unknown focusAndWait() + * @method string getAlert() + * @method array getAllButtons() + * @method array getAllFields() + * @method array getAllLinks() + * @method array getAllWindowIds() + * @method array getAllWindowNames() + * @method array getAllWindowTitles() + * @method string getAttribute(string $attributeLocator) + * @method array getAttributeFromAllWindows(string $attributeName) + * @method string getBodyText() + * @method string getConfirmation() + * @method string getCookie() + * @method string getCookieByName(string $name) + * @method integer getCssCount(string $locator) + * @method integer getCursorPosition(string $locator) + * @method integer getElementHeight(string $locator) + * @method integer getElementIndex(string $locator) + * @method integer getElementPositionLeft(string $locator) + * @method integer getElementPositionTop(string $locator) + * @method integer getElementWidth(string $locator) + * @method string getEval(string $script) + * @method string getExpression(string $expression) + * @method string getHtmlSource() + * @method string getLocation() + * @method string getLogMessages() + * @method integer getMouseSpeed() + * @method string getPrompt() + * @method array getSelectOptions(string $selectLocator) + * @method string getSelectedId(string $selectLocator) + * @method array getSelectedIds(string $selectLocator) + * @method string getSelectedIndex(string $selectLocator) + * @method array getSelectedIndexes(string $selectLocator) + * @method string getSelectedLabel(string $selectLocator) + * @method array getSelectedLabels(string $selectLocator) + * @method string getSelectedValue(string $selectLocator) + * @method array getSelectedValues(string $selectLocator) + * @method unknown getSpeed() + * @method unknown getSpeedAndWait() + * @method string getTable(string $tableCellAddress) + * @method string getText(string $locator) + * @method string getTitle() + * @method string getValue(string $locator) + * @method boolean getWhetherThisFrameMatchFrameExpression(string $currentFrameString, string $target) + * @method boolean getWhetherThisWindowMatchWindowExpression(string $currentWindowString, string $target) + * @method integer getXpathCount(string $xpath) + * @method unknown goBack() + * @method unknown goBackAndWait() + * @method unknown highlight(string $locator) + * @method unknown highlightAndWait(string $locator) + * @method unknown ignoreAttributesWithoutValue(string $ignore) + * @method unknown ignoreAttributesWithoutValueAndWait(string $ignore) + * @method boolean isAlertPresent() + * @method boolean isChecked(locator) + * @method boolean isConfirmationPresent() + * @method boolean isCookiePresent(string $name) + * @method boolean isEditable(string $locator) + * @method boolean isElementPresent(string $locator) + * @method boolean isOrdered(string $locator1, string $locator2) + * @method boolean isPromptPresent() + * @method boolean isSomethingSelected(string $selectLocator) + * @method boolean isTextPresent(pattern) + * @method boolean isVisible(locator) + * @method unknown keyDown() + * @method unknown keyDownAndWait() + * @method unknown keyDownNative() + * @method unknown keyDownNativeAndWait() + * @method unknown keyPress() + * @method unknown keyPressAndWait() + * @method unknown keyPressNative() + * @method unknown keyPressNativeAndWait() + * @method unknown keyUp() + * @method unknown keyUpAndWait() + * @method unknown keyUpNative() + * @method unknown keyUpNativeAndWait() + * @method unknown metaKeyDown() + * @method unknown metaKeyDownAndWait() + * @method unknown metaKeyUp() + * @method unknown metaKeyUpAndWait() + * @method unknown mouseDown() + * @method unknown mouseDownAndWait() + * @method unknown mouseDownAt() + * @method unknown mouseDownAtAndWait() + * @method unknown mouseMove() + * @method unknown mouseMoveAndWait() + * @method unknown mouseMoveAt() + * @method unknown mouseMoveAtAndWait() + * @method unknown mouseOut() + * @method unknown mouseOutAndWait() + * @method unknown mouseOver() + * @method unknown mouseOverAndWait() + * @method unknown mouseUp() + * @method unknown mouseUpAndWait() + * @method unknown mouseUpAt() + * @method unknown mouseUpAtAndWait() + * @method unknown mouseUpRight() + * @method unknown mouseUpRightAndWait() + * @method unknown mouseUpRightAt() + * @method unknown mouseUpRightAtAndWait() + * @method unknown open() + * @method unknown openWindow() + * @method unknown openWindowAndWait() + * @method unknown pause() + * @method unknown refresh() + * @method unknown refreshAndWait() + * @method unknown removeAllSelections() + * @method unknown removeAllSelectionsAndWait() + * @method unknown removeScript() + * @method unknown removeScriptAndWait() + * @method unknown removeSelection() + * @method unknown removeSelectionAndWait() + * @method unknown retrieveLastRemoteControlLogs() + * @method unknown rollup() + * @method unknown rollupAndWait() + * @method unknown runScript() + * @method unknown runScriptAndWait() + * @method unknown select() + * @method unknown selectAndWait() + * @method unknown selectFrame() + * @method unknown selectPopUp() + * @method unknown selectPopUpAndWait() + * @method unknown selectWindow() + * @method unknown setBrowserLogLevel() + * @method unknown setBrowserLogLevelAndWait() + * @method unknown setContext() + * @method unknown setCursorPosition() + * @method unknown setCursorPositionAndWait() + * @method unknown setMouseSpeed() + * @method unknown setMouseSpeedAndWait() + * @method unknown setSpeed() + * @method unknown setSpeedAndWait() + * @method unknown shiftKeyDown() + * @method unknown shiftKeyDownAndWait() + * @method unknown shiftKeyUp() + * @method unknown shiftKeyUpAndWait() + * @method unknown shutDownSeleniumServer() + * @method unknown store() + * @method unknown submit() + * @method unknown submitAndWait() + * @method unknown type() + * @method unknown typeAndWait() + * @method unknown typeKeys() + * @method unknown typeKeysAndWait() + * @method unknown uncheck() + * @method unknown uncheckAndWait() + * @method unknown useXpathLibrary() + * @method unknown useXpathLibraryAndWait() + * @method unknown waitForCondition() + * @method unknown waitForElementPresent() + * @method unknown waitForElementNotPresent() + * @method unknown waitForPageToLoad() + * @method unknown waitForPopUp() + * @method unknown windowFocus() + * @method unknown windowMaximize() + */ + public function __call($command, $arguments) + { + $arguments = $this->preprocessParameters($arguments); + + $wait = FALSE; + + if (substr($command, -7, 7) == 'AndWait') { + $command = substr($command, 0, -7); + $wait = TRUE; + } + + switch ($command) { + case 'addLocationStrategy': + case 'addScript': + case 'addSelection': + case 'allowNativeXpath': + case 'altKeyDown': + case 'altKeyUp': + case 'answerOnNextPrompt': + case 'assignId': + case 'attachFile': + case 'break': + case 'captureEntirePageScreenshot': + case 'captureScreenshot': + case 'check': + case 'chooseCancelOnNextConfirmation': + case 'chooseOkOnNextConfirmation': + case 'click': + case 'clickAt': + case 'close': + case 'contextMenu': + case 'contextMenuAt': + case 'controlKeyDown': + case 'controlKeyUp': + case 'createCookie': + case 'deleteAllVisibleCookies': + case 'deleteCookie': + case 'deselectPopUp': + case 'doubleClick': + case 'doubleClickAt': + case 'dragAndDrop': + case 'dragAndDropToObject': + case 'dragDrop': + case 'echo': + case 'fireEvent': + case 'focus': + case 'goBack': + case 'highlight': + case 'ignoreAttributesWithoutValue': + case 'keyDown': + case 'keyDownNative': + case 'keyPress': + case 'keyPressNative': + case 'keyUp': + case 'keyUpNative': + case 'metaKeyDown': + case 'metaKeyUp': + case 'mouseDown': + case 'mouseDownAt': + case 'mouseMove': + case 'mouseMoveAt': + case 'mouseOut': + case 'mouseOver': + case 'mouseUp': + case 'mouseUpAt': + case 'mouseUpRight': + case 'mouseUpRightAt': + case 'open': + case 'openWindow': + case 'pause': + case 'refresh': + case 'removeAllSelections': + case 'removeScript': + case 'removeSelection': + case 'retrieveLastRemoteControlLogs': + case 'rollup': + case 'runScript': + case 'select': + case 'selectFrame': + case 'selectPopUp': + case 'selectWindow': + case 'setBrowserLogLevel': + case 'setContext': + case 'setCursorPosition': + case 'setMouseSpeed': + case 'setSpeed': + case 'shiftKeyDown': + case 'shiftKeyUp': + case 'shutDownSeleniumServer': + case 'store': + case 'submit': + case 'type': + case 'typeKeys': + case 'uncheck': + case 'useXpathLibrary': + case 'windowFocus': + case 'windowMaximize': + case isset(self::$autoGeneratedCommands[$command]): { + // Pre-Command Actions + switch ($command) { + case 'open': + case 'openWindow': { + if ($this->collectCodeCoverageInformation) { + $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/'); + + $this->createCookie( + 'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId, + 'path=/' + ); + } + } + break; + case 'store': + // store is a synonym of storeExpression + // and RC only understands storeExpression + $command = 'storeExpression'; + break; + } + + if (isset(self::$autoGeneratedCommands[$command]) && self::$autoGeneratedCommands[$command]['functionHelper']) { + $helperArguments = array($command, $arguments, self::$autoGeneratedCommands[$command]); + call_user_func_array(array($this, self::$autoGeneratedCommands[$command]['functionHelper']), $helperArguments); + } else { + $this->doCommand($command, $arguments); + } + + // Post-Command Actions + switch ($command) { + case 'addLocationStrategy': + case 'allowNativeXpath': + case 'assignId': + case 'captureEntirePageScreenshot': + case 'captureScreenshot': { + // intentionally empty + } + break; + + default: { + if ($wait) { + if ($this->useWaitForPageToLoad) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } else { + sleep($this->wait); + } + } + + if ($this->sleep > 0) { + sleep($this->sleep); + } + + $this->testCase->runDefaultAssertions($command); + } + } + } + break; + + case 'getWhetherThisFrameMatchFrameExpression': + case 'getWhetherThisWindowMatchWindowExpression': + case 'isAlertPresent': + case 'isChecked': + case 'isConfirmationPresent': + case 'isCookiePresent': + case 'isEditable': + case 'isElementPresent': + case 'isOrdered': + case 'isPromptPresent': + case 'isSomethingSelected': + case 'isTextPresent': + case 'isVisible': { + return $this->getBoolean($command, $arguments); + } + break; + + case 'getCssCount': + case 'getCursorPosition': + case 'getElementHeight': + case 'getElementIndex': + case 'getElementPositionLeft': + case 'getElementPositionTop': + case 'getElementWidth': + case 'getMouseSpeed': + case 'getSpeed': + case 'getXpathCount': { + $result = $this->getNumber($command, $arguments); + + if ($wait) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } + + return $result; + } + break; + + case 'getAlert': + case 'getAttribute': + case 'getBodyText': + case 'getConfirmation': + case 'getCookie': + case 'getCookieByName': + case 'getEval': + case 'getExpression': + case 'getHtmlSource': + case 'getLocation': + case 'getLogMessages': + case 'getPrompt': + case 'getSelectedId': + case 'getSelectedIndex': + case 'getSelectedLabel': + case 'getSelectedValue': + case 'getTable': + case 'getText': + case 'getTitle': + case 'captureEntirePageScreenshotToString': + case 'captureScreenshotToString': + case 'getValue': { + $result = $this->getString($command, $arguments); + + if ($wait) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } + + return $result; + } + break; + + case 'getAllButtons': + case 'getAllFields': + case 'getAllLinks': + case 'getAllWindowIds': + case 'getAllWindowNames': + case 'getAllWindowTitles': + case 'getAttributeFromAllWindows': + case 'getSelectedIds': + case 'getSelectedIndexes': + case 'getSelectedLabels': + case 'getSelectedValues': + case 'getSelectOptions': { + $result = $this->getStringArray($command, $arguments); + + if ($wait) { + $this->waitForPageToLoad($this->seleniumTimeout * 1000); + } + + return $result; + } + break; + + case 'waitForCondition': + case 'waitForElementPresent': + case 'waitForElementNotPresent': + case 'waitForFrameToLoad': + case 'waitForPopUp': { + if (count($arguments) == 1) { + $arguments[] = $this->seleniumTimeout * 1000; + } + + $this->doCommand($command, $arguments); + $this->testCase->runDefaultAssertions($command); + } + break; + + case 'waitForPageToLoad': { + if (empty($arguments)) { + $arguments[] = $this->seleniumTimeout * 1000; + } + + $this->doCommand($command, $arguments); + $this->testCase->runDefaultAssertions($command); + } + break; + + default: { + if (!in_array($command, $this->userCommands)) { + throw new BadMethodCallException( + "Method $command not defined." + ); + } + $this->doCommand($command, $arguments); + } + } + } + + /** + * Send a command to the Selenium RC server. + * + * @param string $command + * @param array $arguments + * @param array $namedArguments + * @return string + * @author Seth Casana + */ + protected function doCommand($command, array $arguments = array(), array $namedArguments = array()) + { + $url = sprintf( + 'http://%s:%s/selenium-server/driver/', + $this->host, + $this->port + ); + + $numArguments = count($arguments); + $postData = sprintf('cmd=%s', urlencode($command)); + for ($i = 0; $i < $numArguments; $i++) { + $argNum = strval($i + 1); + + if ($arguments[$i] == ' ') { + $postData .= sprintf('&%s=%s', $argNum, urlencode($arguments[$i])); + } else { + $postData .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i]))); + } + } + foreach ($namedArguments as $key => $value) { + $postData .= sprintf('&%s=%s', $key, urlencode($value)); + } + + if (isset($this->sessionId)) { + $postData .= sprintf('&%s=%s', 'sessionId', $this->sessionId); + } + + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HEADER, 0); + curl_setopt($curl, CURLOPT_POST, TRUE); + curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); + curl_setopt($curl, CURLOPT_HTTPHEADER, array( + 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' + )); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60); + + $response = curl_exec($curl); + $info = curl_getinfo($curl); + + if (!$response) { + throw new RuntimeException("CURL error while accessing the Selenium Server at '$url': " . curl_error($curl)); + } + + curl_close($curl); + + if (!preg_match('/^OK/', $response)) { + throw new RuntimeException("Invalid response while accessing the Selenium Server at '$url': " . $response); + } + + if ($info['http_code'] != 200) { + throw new RuntimeException( + 'The response from the Selenium RC server is invalid: ' . + $response + ); + } + + return $response; + } + + protected function preprocessParameters($params) + { + foreach ($params as $key => $param ) { + if (is_string($param) && (strlen($param) > 0)) { + $params[$key] = $this->getString('getExpression', array($param)); + } + } + return $params; + } + + /** + * Send a command to the Selenium RC server and treat the result + * as a boolean. + * + * @param string $command + * @param array $arguments + * @return boolean + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getBoolean($command, array $arguments) + { + $result = $this->getString($command, $arguments); + + switch ($result) { + case 'true': return TRUE; + + case 'false': return FALSE; + + default: { + throw new PHPUnit_Framework_Exception( + 'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::export($result) + ); + } + } + } + + /** + * Send a command to the Selenium RC server and treat the result + * as a number. + * + * @param string $command + * @param array $arguments + * @return numeric + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getNumber($command, array $arguments) + { + $result = $this->getString($command, $arguments); + + if (!is_numeric($result)) { + throw new PHPUnit_Framework_Exception( + 'Result is not numeric: ' . PHPUnit_Util_Type::export($result) + ); + } + + return $result; + } + + /** + * Send a command to the Selenium RC server and treat the result + * as a string. + * + * @param string $command + * @param array $arguments + * @return string + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getString($command, array $arguments) + { + try { + $result = $this->doCommand($command, $arguments); + } + + catch (RuntimeException $e) { + throw $e; + } + + return (strlen($result) > 3) ? substr($result, 3) : ''; + } + + /** + * Send a command to the Selenium RC server and treat the result + * as an array of strings. + * + * @param string $command + * @param array $arguments + * @return array + * @author Shin Ohno + * @author Bjoern Schotte + */ + protected function getStringArray($command, array $arguments) + { + $csv = $this->getString($command, $arguments); + $token = ''; + $tokens = array(); + $letters = preg_split('//', $csv, -1, PREG_SPLIT_NO_EMPTY); + $count = count($letters); + + for ($i = 0; $i < $count; $i++) { + $letter = $letters[$i]; + + switch($letter) { + case '\\': { + $letter = $letters[++$i]; + $token .= $letter; + } + break; + + case ',': { + $tokens[] = $token; + $token = ''; + } + break; + + default: { + $token .= $letter; + } + } + } + + $tokens[] = $token; + + return $tokens; + } + + public function getVerificationErrors() + { + return $this->verificationErrors; + } + + public function clearVerificationErrors() + { + $this->verificationErrors = array(); + } + + protected function assertCommand($command, $arguments, $info) + { + $method = $info['originalMethod']; + $requiresTarget = $info['requiresTarget']; + $result = $this->__call($method, $arguments); + $message = "Failed command: " . $command . "('" + . (array_key_exists(0, $arguments) ? $arguments[0] . "'" : '') + . (array_key_exists(1, $arguments) ? ", '" . $arguments[1] . "'" : '') + . ")"; + + if ($info['isBoolean']) { + if (!isset($info['negative']) || !$info['negative']) { + PHPUnit_Framework_Assert::assertTrue($result, $message); + } else { + PHPUnit_Framework_Assert::assertFalse($result, $message); + } + } else { + if ($requiresTarget === TRUE) { + $expected = $arguments[1]; + } else { + $expected = $arguments[0]; + } + + if (strpos($expected, 'exact:') === 0) { + $expected = substr($expected, strlen('exact:')); + + if (!isset($info['negative']) || !$info['negative']) { + PHPUnit_Framework_Assert::assertEquals($expected, $result, $message); + } else { + PHPUnit_Framework_Assert::assertNotEquals($expected, $result, $message); + } + } else { + $caseInsensitive = FALSE; + + if (strpos($expected, 'regexp:') === 0) { + $expected = substr($expected, strlen('regexp:')); + } + + else if (strpos($expected, 'regexpi:') === 0) { + $expected = substr($expected, strlen('regexpi:')); + $caseInsensitive = TRUE; + } + + else { + if (strpos($expected, 'glob:') === 0) { + $expected = substr($expected, strlen('glob:')); + } + + $expected = '^' . str_replace( + array('*', '?'), array('.*', '.?'), $expected + ) . '$'; + } + + $expected = '/' . str_replace('/', '\/', $expected) . '/'; + + if ($caseInsensitive) { + $expected .= 'i'; + } + + if (!isset($info['negative']) || !$info['negative']) { + PHPUnit_Framework_Assert::assertRegExp( + $expected, $result, $message + ); + } else { + PHPUnit_Framework_Assert::assertNotRegExp( + $expected, $result, $message + ); + } + } + } + } + + protected function verifyCommand($command, $arguments, $info) + { + try { + $this->assertCommand($command, $arguments, $info); + } + + catch (PHPUnit_Framework_AssertionFailedError $e) { + array_push($this->verificationErrors, $e->toString()); + } + } + + protected function waitForCommand($command, $arguments, $info) + { + $lastExceptionMessage = ''; + for ($second = 0; ; $second++) { + if ($second > $this->httpTimeout) { + PHPUnit_Framework_Assert::fail( + "WaitFor timeout. \n" + . "Last exception message: \n" . $lastExceptionMessage + ); + } + + try { + $this->assertCommand($command, $arguments, $info); + return; + } + + catch (Exception $e) { + $lastExceptionMessage = $e->getMessage(); + } + + sleep(1); + } + } + + /** + * Parses the docblock of PHPUnit_Extensions_SeleniumTestCase_Driver::__call + * for get*(), is*(), assert*(), verify*(), assertNot*(), verifyNot*(), + * store*(), waitFor*(), and waitForNot*() methods. + */ + protected static function autoGenerateCommands() + { + $method = new ReflectionMethod(__CLASS__, '__call'); + $docComment = $method->getDocComment(); + + if (preg_match_all('(@method\s+(\w+)\s+([\w]+)\((.*)\))', $docComment, $matches)) { + foreach ($matches[2] as $methodKey => $method) { + if (preg_match('/^(get|is)([A-Z].+)$/', $method, $methodMatches)) { + $baseName = $methodMatches[2]; + $isBoolean = $methodMatches[1] == 'is'; + $requiresTarget = (strlen($matches[3][$methodKey]) > 0); + + if (preg_match('/^(.*)Present$/', $baseName, $methodMatches)) { + $notBaseName = $methodMatches[1] . 'NotPresent'; + } else { + $notBaseName = 'Not' . $baseName; + } + + self::$autoGeneratedCommands['store' . $baseName] = array( + 'functionHelper' => FALSE + ); + + self::$autoGeneratedCommands['assert' . $baseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'functionHelper' => 'assertCommand', + 'requiresTarget' => $requiresTarget + ); + + self::$autoGeneratedCommands['assert' . $notBaseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'negative' => TRUE, + 'functionHelper' => 'assertCommand', + 'requiresTarget' => $requiresTarget + ); + + self::$autoGeneratedCommands['verify' . $baseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'functionHelper' => 'verifyCommand', + 'requiresTarget' => $requiresTarget + ); + + self::$autoGeneratedCommands['verify' . $notBaseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'negative' => TRUE, + 'functionHelper' => 'verifyCommand', + 'requiresTarget' => $requiresTarget + ); + + self::$autoGeneratedCommands['waitFor' . $baseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'functionHelper' => 'waitForCommand', + 'requiresTarget' => $requiresTarget + ); + + self::$autoGeneratedCommands['waitFor' . $notBaseName] = array( + 'originalMethod' => $method, + 'isBoolean' => $isBoolean, + 'negative' => TRUE, + 'functionHelper' => 'waitForCommand', + 'requiresTarget' => $requiresTarget + ); + } + } + } + } +} + + * + */ +class PHPUnit_Extensions_SeleniumCommon_ExitHandler +{ + /** + * Register handler. + * If project have own shutdown hanldler user have to add function to handler + * + */ + public static function init() + { + register_shutdown_function( array( 'PHPUnit_Extensions_SeleniumCommon_ExitHandler', 'handle' ) ); + } + + /** + * Manual include apendable files + */ + public static function handle() + { + $execFile = ini_get('auto_append_file'); + if ($execFile!=='') { + include_once ($execFile); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Sebastian Bergmann + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.0.0 + */ + +// By default the code coverage files are written to the same directory +// that contains the covered sourcecode files. Use this setting to change +// the default behaviour and set a specific directory to write the files to. +// If you change the default setting, please make sure to also configure +// the same directory in phpunit_coverage.php. Also note that the webserver +// needs write access to the directory. +if (!isset($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) { + $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = FALSE; +} + +if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && + !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) && + extension_loaded('xdebug')) { + $GLOBALS['PHPUNIT_FILTERED_FILES'] = array(__FILE__); + + xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); +} + +include ('ExitHandler.php'); +PHPUnit_Extensions_SeleniumCommon_ExitHandler::init(); +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Sebastian Bergmann + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.0.0 + */ + +$directory = realpath(__DIR__); +while ($directory != '/') { + $autoloadCandidate = $directory . '/vendor/autoload.php'; + if (file_exists($autoloadCandidate)) { + require_once $autoloadCandidate; + break; + } + $directory = realpath($directory . '/..'); +} + +// Set this to the directory that contains the code coverage files. +// It defaults to getcwd(). If you have configured a different directory +// in prepend.php, you need to configure the same directory here. +$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = getcwd(); + +if (isset($_GET['PHPUNIT_SELENIUM_TEST_ID'])) { + $facade = new File_Iterator_Facade; + $files = $facade->getFilesAsArray( + $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'], + $_GET['PHPUNIT_SELENIUM_TEST_ID'] + ); + + $coverage = array(); + + foreach ($files as $file) { + $data = unserialize(file_get_contents($file)); + unlink($file); + unset($file); + $filter = new PHP_CodeCoverage_Filter(); + + foreach ($data as $file => $lines) { + if ($filter->isFile($file)) { + if (!isset($coverage[$file])) { + $coverage[$file] = array( + 'md5' => md5_file($file), 'coverage' => $lines + ); + } else { + foreach ($lines as $line => $flag) { + if (!isset($coverage[$file]['coverage'][$line]) || + $flag > $coverage[$file]['coverage'][$line]) { + $coverage[$file]['coverage'][$line] = $flag; + } + } + } + } + } + } + + print serialize($coverage); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Sebastian Bergmann + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.0.0 + */ + +if ( isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && + !isset($_GET['PHPUNIT_SELENIUM_TEST_ID']) && + extension_loaded('xdebug')) { + $GLOBALS['PHPUNIT_FILTERED_FILES'][] = __FILE__; + + $data = xdebug_get_code_coverage(); + xdebug_stop_code_coverage(); + + foreach ($GLOBALS['PHPUNIT_FILTERED_FILES'] as $file) { + unset($data[$file]); + } + + if (is_string($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']) && + is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) { + $file = $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] . + DIRECTORY_SEPARATOR . md5($_SERVER['SCRIPT_FILENAME']); + } else { + $file = $_SERVER['SCRIPT_FILENAME']; + } + + file_put_contents( + $name = $file . '.' . md5(uniqid(rand(), TRUE)) . '.' . $_COOKIE['PHPUNIT_SELENIUM_TEST_ID'], + serialize($data) + ); +} +coverageScriptUrl = $coverageScriptUrl; + $this->testId = $testId; + } + + public function get() + { + if (!empty($this->coverageScriptUrl)) { + $url = sprintf( + '%s?PHPUNIT_SELENIUM_TEST_ID=%s', + $this->coverageScriptUrl, + urlencode($this->testId) + ); + + $buffer = @file_get_contents($url); + + if ($buffer !== FALSE) { + $coverageData = unserialize($buffer); + if (is_array($coverageData)) { + return $this->matchLocalAndRemotePaths($coverageData); + } else { + throw new Exception('Empty or invalid code coverage data received from url "' . $url . '"'); + } + } + } + + return array(); + } + + /** + * @param array $coverage + * @return array + * @author Mattis Stordalen Flister + */ + protected function matchLocalAndRemotePaths(array $coverage) + { + $coverageWithLocalPaths = array(); + + foreach ($coverage as $originalRemotePath => $data) { + $remotePath = $originalRemotePath; + $separator = $this->findDirectorySeparator($remotePath); + + while (!($localpath = stream_resolve_include_path($remotePath)) && + strpos($remotePath, $separator) !== FALSE) { + $remotePath = substr($remotePath, strpos($remotePath, $separator) + 1); + } + + if ($localpath && md5_file($localpath) == $data['md5']) { + $coverageWithLocalPaths[$localpath] = $data['coverage']; + } + } + + return $coverageWithLocalPaths; + } + + /** + * @param string $path + * @return string + * @author Mattis Stordalen Flister + */ + protected function findDirectorySeparator($path) + { + if (strpos($path, '/') !== FALSE) { + return '/'; + } + + return '\\'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.6 + */ + +/** + * Specifies how to create Session objects for running tests. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.6 + */ +interface PHPUnit_Extensions_Selenium2TestCase_SessionStrategy +{ + /** + * @param array $parameters 'host' => Selenium Server machine + 'port' => Selenium Server port + 'browser' => a browser name + * 'browserUrl' => base URL to use during the test + */ + public function session(array $parameters); + + public function notSuccessfulTest(); + + public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL); +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.13 + */ + +/** + * Sends session click command for emulating LEFT, MIDDLE or RIGHT mouse buttons + * + * @package PHPUnit_Selenium + * @author Ivan Kurnosov + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.13 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Click + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + const LEFT = 0; + const MIDDLE = 1; + const RIGHT = 2; + + public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + if (is_null($argument)) { + $jsonParameters = NULL; + } elseif (!is_scalar($argument) || !in_array($argument, array( + self::LEFT, self::RIGHT, self::MIDDLE + ))) { + throw new BadMethodCallException('Wrong parameter for click(): expecting 0, 1 or 2.'); + } else { + $jsonParameters = array('button' => $argument); + } + + parent::__construct($jsonParameters, $url); + } + + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.3.2 + */ + +/** + * Sends a file to a RC + * Returns the FQ path to the transfered file + * + * @package PHPUnit_Selenium + * @author Kevin Ran + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.3.2 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_File + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + + /** + * @var + */ + private static $_zipArchive; + + public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + if (!is_file($argument)) { + throw new BadMethodCallException("No such file: {$argument}"); + } + + $zipfile_path = $this->_zipArchiveFile($argument); + $contents = file_get_contents($zipfile_path); + + if ($contents === false) { + throw new Exception("Unable to read generated zip file: {$zipfile_path}"); + } + + $file = base64_encode($contents); + + parent::__construct(array('file' => $file), $url); + + unlink($zipfile_path); + } + + public function httpMethod() + { + return 'POST'; + } + + /** + * Creates a zip archive with the given file + * + * @param string $file_path FQ path to file + * @return string Generated zip file + */ + protected function _zipArchiveFile( $file_path ) + { + + // file MUST be readable + if( !is_readable( $file_path ) ) { + + throw new Exception( "Unable to read {$file_path}" ); + + } // if !file_data + + $filename_hash = sha1( time() . $file_path ); + $tmp_dir = $this->_getTmpDir(); + $zip_filename = "{$tmp_dir}{$filename_hash}.zip"; + $zip = $this->_getZipArchiver(); + + if ($zip->open($zip_filename, ZIPARCHIVE::CREATE) === FALSE) { + throw new Exception( "Unable to create zip archive: {$zip_filename}" ); + } + + $zip->addFile($file_path, basename($file_path)); + $zip->close(); + + return $zip_filename; + } + + /** + * Returns a runtime instance of a ZipArchive + * + * @return ZipArchive + */ + protected function _getZipArchiver() + { + // create ZipArchive if necessary + if (!static::$_zipArchive) { + static::$_zipArchive = new ZipArchive(); + } + + return static::$_zipArchive; + } + + /** + * Calls sys_get_temp_dir and ensures that it has a trailing slash + * ( behavior varies across systems ) + * + * @return string + */ + protected function _getTmpDir() + { + return rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Gets or sets the current URL of the window. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Url + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($url, $commandUrl, PHPUnit_Extensions_Selenium2TestCase_URL $baseUrl) + { + if ($url !== NULL) { + $absoluteLocation = $baseUrl->jump($url)->getValue(); + $jsonParameters = array('url' => $absoluteLocation); + } else { + $jsonParameters = NULL; + } + parent::__construct($jsonParameters, $commandUrl); + } + + public function httpMethod() + { + if ($this->jsonParameters) { + return 'POST'; + } + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Clicks Cancel on an alert popup. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_DismissAlert + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Christian Soronellas + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Gets or sets the current URL of the window. + * + * @package PHPUnit_Selenium + * @author Christian Soronellas + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($jsonParameters, + PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + if ($jsonParameters === NULL) { + parent::__construct(NULL, $url); + } else { + $jsonParameters = $this->keysForText($jsonParameters); + parent::__construct($jsonParameters, $url); + } + } + + /** + * @return string + */ + public function httpMethod() + { + return 'POST'; + } + + /** + * Given a string returns an array of the characters that compose the string + * + * @param string $text + * @throws InvalidArgumentException + * @return array + */ + public function keysForText($text) + { + if (is_scalar($text)) { + return array('value' => preg_split('//u', (string) $text, -1, PREG_SPLIT_NO_EMPTY)); + } + if (is_array($text)) { + return $text; + } + throw new InvalidArgumentException('The "text" argument should be a string or an array of special characters!'); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Jonathan Lipps + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Gets or posts an attribute from/to the session (title, alert text, etc.) + * + * @package PHPUnit_Selenium + * @author Jonathan Lipps + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.9 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Location + extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute +{ + + public function __construct($location, $commandUrl) + { + if ($location !== NULL) { + $jsonParameters = array('location' => $location); + } else { + $jsonParameters = NULL; + } + parent::__construct($jsonParameters, $commandUrl); + } + + public function httpMethod() + { + if ($this->jsonParameters) { + return 'POST'; + } + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Jonathan Lipps + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Gets or posts an attribute from/to the session (title, alert text, etc.) + * + * @package PHPUnit_Selenium + * @author Jonathan Lipps + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.9 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + if ($this->jsonParameters) { + return 'POST'; + } + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.8 + */ + +/** + * Moves the mouse pointer. + * + * @author Giorgio Sironi + * @package PHPUnit_Selenium + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.8 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_MoveTo + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($element, + PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + if (!is_array($element)) { + $element = array( + 'element' => $element, + ); + } + + $validKeys = array( + 'element' => NULL, + 'xoffset' => NULL, + 'yoffset' => NULL, + ); + + $jsonParameters = array_intersect_key($element, $validKeys); + + if (isset($jsonParameters['element'])) { + if (!($jsonParameters['element'] instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) { + throw new PHPUnit_Extensions_Selenium2TestCase_Exception('Only moving over an element is supported. Please pass a PHPUnit_Extensions_Selenium2TestCase_Element instance.'); + } + + $jsonParameters['element'] = $jsonParameters['element']->getId(); + } + + if (isset($jsonParameters['xoffset']) || isset($jsonParameters['yoffset'])) { + // @see https://github.com/sebastianbergmann/phpunit-selenium/pull/250#issuecomment-21308153 + // @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/moveto + error_log('Even though this method is a part of the WebDriver Wire protocol it might be not supported by your browser yet'); + } + + parent::__construct($jsonParameters, $url); + } + + /** + * @return string + */ + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release + */ + +/** + * Gets the active element from the session + * + * @package PHPUnit_Selenium + * @author Marcel Erz + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Active + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + + public function __construct($jsonParameters, PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + $url = $url->addCommand('element')->addCommand('active'); + parent::__construct($jsonParameters, $url); + } + + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Gets an attribute from the session (title, alert text, etc.) + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAccessor + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Changes the focus to a window. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Window + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($name, $commandUrl) + { + $jsonParameters = array('name' => $name); + parent::__construct($jsonParameters, $commandUrl); + } + + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Clicks Ok on an alert popup. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AcceptAlert + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Changes the focus to a frame. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Frame + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($id, $commandUrl) + { + $jsonParameters = array( + 'id' => $this->extractId($id) + ); + + parent::__construct($jsonParameters, $commandUrl); + } + + /** + * @param $id + * @return array + */ + private function extractId($id) + { + if ($this->isElement($id)) { //selenium-element + return $id->toWebDriverObject(); + } + + //html-id or null + return $id; + } + + /** + * @param $id + * @return bool + */ + private function isElement($id) + { + return $id instanceof PHPUnit_Extensions_Selenium2TestCase_Element; + } + + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Jonathan Lipps + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Gets or posts an attribute from/to the session (title, alert text, etc.) + * + * @package PHPUnit_Selenium + * @author Jonathan Lipps + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.9 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Orientation + extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_GenericAttribute +{ + + public function __construct($orientation, $commandUrl) + { + if ($orientation !== NULL) { + $jsonParameters = array('orientation' => $orientation); + } else { + $jsonParameters = NULL; + } + parent::__construct($jsonParameters, $commandUrl); + } + + public function httpMethod() + { + if ($this->jsonParameters) { + return 'POST'; + } + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Obtains the text of an alert, or types into a prompt. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_AlertText + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($argument, PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + if (is_string($argument)) { + $jsonParameters =array('text' => $argument); + } else if ($argument == NULL) { + $jsonParameters = NULL; + } else { + throw new BadMethodCallException('Wrong parameters for alertText().'); + } + parent::__construct($jsonParameters, $url); + } + + public function httpMethod() + { + if ($this->jsonParameters) { + return 'POST'; + } + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Andrew Krasichkov + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.3.2 + */ + +/** + * Get the log for a given log type. Log buffer is reset after each request. + * + * @package PHPUnit_Selenium + * @author Andrew Krasichkov + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.3.2 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Log + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function __construct($type, $commandUrl) + { + $jsonParameters = array('type' => $type); + parent::__construct($jsonParameters, $commandUrl); + } + + public function httpMethod() + { + return 'POST'; + } +}. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Base class for implementing commands with special semantics. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +abstract class PHPUnit_Extensions_Selenium2TestCase_Command +{ + protected $jsonParameters; + private $commandName; + + /** + * @param array $jsonParameters null in case of no parameters + */ + public function __construct($jsonParameters, + PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + if (!is_array($jsonParameters) && $jsonParameters !== NULL) { + throw new InvalidArgumentException("The JSON parameters must be an array, or a NULL value in case they are not required."); + } + $this->jsonParameters = $jsonParameters; + $this->url = $url; + } + + public function url() + { + return $this->url; + } + + /** + * @return string + */ + abstract public function httpMethod(); + + /** + * @param array $jsonParameters null in case of no parameters + */ + public function jsonParameters() + { + return $this->jsonParameters; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Conditions for selecting a DOM element. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCriteria extends ArrayObject +{ + public function __construct($strategy) + { + $this['using'] = $strategy; + } + + /** + * @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria + */ + public function value($searchTarget) + { + $this['value'] = $searchTarget; + return $this; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.6 + */ + +/** + * Keeps a Session object shared between test runs to save time. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.6 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared + implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy +{ + private $original; + private $session; + private $mainWindow; + private $lastTestWasNotSuccessful = FALSE; + + public function __construct(PHPUnit_Extensions_Selenium2TestCase_SessionStrategy $originalStrategy) + { + $this->original = $originalStrategy; + } + + public function session(array $parameters) + { + if ($this->lastTestWasNotSuccessful) { + if ($this->session !== NULL) { + $this->session->stop(); + $this->session = NULL; + } + $this->lastTestWasNotSuccessful = FALSE; + } + if ($this->session === NULL) { + $this->session = $this->original->session($parameters); + $this->mainWindow = $this->session->windowHandle(); + } else { + $this->session->window($this->mainWindow); + } + return $this->session; + } + + public function notSuccessfulTest() + { + $this->lastTestWasNotSuccessful = TRUE; + } + + public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL) + { + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.6 + */ + +/** + * Produces a new Session object shared for each test. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.6 + */ +class PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated + implements PHPUnit_Extensions_Selenium2TestCase_SessionStrategy +{ + public function session(array $parameters) + { + $seleniumServerUrl = PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']); + $driver = new PHPUnit_Extensions_Selenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']); + $capabilities = array_merge($parameters['desiredCapabilities'], + array( + 'browserName' => $parameters['browserName'] + )); + $session = $driver->startSession($capabilities, $parameters['browserUrl']); + return $session; + } + + public function notSuccessfulTest() + { + } + + public function endOfTest(PHPUnit_Extensions_Selenium2TestCase_Session $session = NULL) + { + if ($session !== NULL) { + $session->stop(); + } + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Clicks ok on an alert popup. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Click + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Retrieves the value of a CSS property. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Css + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + /** + * @param array $propertyName + */ + public function __construct($propertyName, + PHPUnit_Extensions_Selenium2TestCase_URL $cssResourceBaseUrl) + { + $this->jsonParameters = array(); + $this->url = $cssResourceBaseUrl->descend($propertyName); + } + + public function httpMethod() + { + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Class for implementing commands that just return a value + * (obtained with GET). + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericAccessor + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Retrieves an attribute of a DOM element. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Attribute + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + /** + * @param array $parameter + */ + public function __construct($parameter, + PHPUnit_Extensions_Selenium2TestCase_URL $attributeResourceBaseUrl) + { + $this->jsonParameters = array(); + $this->url = $attributeResourceBaseUrl->descend($parameter); + } + + public function httpMethod() + { + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Checks equality (same element on the page) with another DOM element. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Equals + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + /** + * @param array $parameter + */ + public function __construct($parameter, + PHPUnit_Extensions_Selenium2TestCase_URL $equalsResourceBaseUrl) + { + $this->jsonParameters = array(); + if (!($parameter instanceof PHPUnit_Extensions_Selenium2TestCase_Element)) { + throw new InvalidArgumentException("Elements can only test equality with other Element instances."); + } + $this->url = $equalsResourceBaseUrl->descend($parameter->getId()); + } + + public function httpMethod() + { + return 'GET'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.0 + */ + +/** + * Get and set the element's value attribute. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.0 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_Value + extends PHPUnit_Extensions_Selenium2TestCase_SessionCommand_Keys +{ + public function httpMethod() + { + if ($this->jsonParameters) { + return 'POST'; + } + throw new BadMethodCallException("JSON Wire Protocol only supports POST to /value now. To get the value of an element GET /attribute/:naem should be used and this object should never be involved."); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2012 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Class for implementing commands that just accomplishes an action (via POST). + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2012 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +class PHPUnit_Extensions_Selenium2TestCase_ElementCommand_GenericPost + extends PHPUnit_Extensions_Selenium2TestCase_Command +{ + public function httpMethod() + { + return 'POST'; + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Christian Becker + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since + */ + +/** + * Indicates an exception as a result of a non-sucessful WebDriver response status code. + * + * @package PHPUnit_Selenium + * @author Christian Becker + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since + */ +class PHPUnit_Extensions_Selenium2TestCase_WebDriverException extends PHPUnit_Extensions_Selenium2TestCase_Exception +{ + /* @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Response_Status_Codes */ + const Success = 0; + const NoSuchDriver = 6; + const NoSuchElement = 7; + const NoSuchFrame = 8; + const UnknownCommand = 9; + const StaleElementReference = 10; + const ElementNotVisible = 11; + const InvalidElementState = 12; + const UnknownError = 13; + const ElementIsNotSelectable = 15; + const JavaScriptError = 17; + const XPathLookupError = 19; + const Timeout = 21; + const NoSuchWindow = 23; + const InvalidCookieDomain = 24; + const UnableToSetCookie = 25; + const UnexpectedAlertOpen = 26; + const NoAlertOpenError = 27; + const ScriptTimeout = 28; + const InvalidElementCoordinates = 29; + const IMENotAvailable = 30; + const IMEEngineActivationFailed = 31; + const InvalidSelector = 32; + const SessionNotCreatedException = 33; + const MoveTargetOutOfBounds = 34; +}. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.4 + */ + +/** + * Object representing elements, or everything that may have subcommands. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.2.4 + */ +abstract class PHPUnit_Extensions_Selenium2TestCase_CommandsHolder +{ + /** + * @var PHPUnit_Extensions_Selenium2TestCase_Driver + */ + protected $driver; + + /** + * @var string the API URL for this element, + */ + protected $url; + + /** + * @var array instances of + * PHPUnit_Extensions_Selenium2TestCase_ElementCommand + */ + protected $commands; + + public function __construct($driver, + PHPUnit_Extensions_Selenium2TestCase_URL $url) + { + $this->driver = $driver; + $this->url = $url; + $this->commands = array(); + foreach ($this->initCommands() as $commandName => $handler) { + if (is_string($handler)) { + $this->commands[$commandName] = $this->factoryMethod($handler); + } else if (is_callable($handler)) { + $this->commands[$commandName] = $handler; + } else { + throw new InvalidArgumentException("Command $commandName is not configured correctly."); + } + } + } + + /** + * @return array class names, or + * callables of the form function($parameter, $commandUrl) + */ + protected abstract function initCommands(); + + public function __call($commandName, $arguments) + { + $jsonParameters = $this->extractJsonParameters($arguments); + $response = $this->driver->execute($this->newCommand($commandName, $jsonParameters)); + return $response->getValue(); + } + + protected function postCommand($name, PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) + { + $response = $this->driver->curl('POST', + $this->url->addCommand($name), + $criteria->getArrayCopy()); + return $response->getValue(); + } + + /** + * @params string $commandClass a class name, descending from + PHPUnit_Extensions_Selenium2TestCase_Command + * @return callable + */ + private function factoryMethod($commandClass) + { + return function($jsonParameters, $url) use ($commandClass) { + return new $commandClass($jsonParameters, $url); + }; + } + + private function extractJsonParameters($arguments) + { + $this->checkArguments($arguments); + + if (count($arguments) == 0) { + return NULL; + } + return $arguments[0]; + } + + private function checkArguments($arguments) + { + if (count($arguments) > 1) { + throw new Exception('You cannot call a command with multiple method arguments.'); + } + } + + /** + * @param string $commandName The called method name + * defined as a key in initCommands() + * @param array $jsonParameters + * @return PHPUnit_Extensions_Selenium2TestCase_Command + */ + protected function newCommand($commandName, $jsonParameters) + { + if (isset($this->commands[$commandName])) { + $factoryMethod = $this->commands[$commandName]; + $url = $this->url->addCommand($commandName); + $command = $factoryMethod($jsonParameters, $url); + return $command; + } + throw new BadMethodCallException("The command '$commandName' is not existent or not supported yet."); + } +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Ivan Kurnosov + * @copyright 2010-2011 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.12 + */ + +/** + * Class to hold the special keys Unicode entities + * + * @package PHPUnit_Selenium + * @author Ivan Kurnosov + * @copyright 2010-2011 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + * @since Class available since Release 1.3.0 + * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/value + */ +class PHPUnit_Extensions_Selenium2TestCase_Keys +{ + const NULL = "\xEE\x80\x80"; + const CANCEL = "\xEE\x80\x81"; + const HELP = "\xEE\x80\x82"; + const BACKSPACE = "\xEE\x80\x83"; + const TAB = "\xEE\x80\x84"; + const CLEAR = "\xEE\x80\x85"; + const RETURN_ = "\xEE\x80\x86"; + const ENTER = "\xEE\x80\x87"; + const SHIFT = "\xEE\x80\x88"; + const CONTROL = "\xEE\x80\x89"; + const ALT = "\xEE\x80\x8A"; + const PAUSE = "\xEE\x80\x8B"; + const ESCAPE = "\xEE\x80\x8C"; + const SPACE = "\xEE\x80\x8D"; + const PAGEUP = "\xEE\x80\x8E"; + const PAGEDOWN = "\xEE\x80\x8F"; + const END = "\xEE\x80\x90"; + const HOME = "\xEE\x80\x91"; + const LEFT = "\xEE\x80\x92"; + const UP = "\xEE\x80\x93"; + const RIGHT = "\xEE\x80\x94"; + const DOWN = "\xEE\x80\x95"; + const INSERT = "\xEE\x80\x96"; + const DELETE = "\xEE\x80\x97"; + const SEMICOLON = "\xEE\x80\x98"; + const EQUALS = "\xEE\x80\x99"; + const NUMPAD0 = "\xEE\x80\x9A"; + const NUMPAD1 = "\xEE\x80\x9B"; + const NUMPAD2 = "\xEE\x80\x9C"; + const NUMPAD3 = "\xEE\x80\x9D"; + const NUMPAD4 = "\xEE\x80\x9E"; + const NUMPAD5 = "\xEE\x80\x9F"; + const NUMPAD6 = "\xEE\x80\xA0"; + const NUMPAD7 = "\xEE\x80\xA1"; + const NUMPAD8 = "\xEE\x80\xA2"; + const NUMPAD9 = "\xEE\x80\xA3"; + const MULTIPLY = "\xEE\x80\xA4"; + const ADD = "\xEE\x80\xA5"; + const SEPARATOR = "\xEE\x80\xA6"; + const SUBTRACT = "\xEE\x80\xA7"; + const DECIMAL = "\xEE\x80\xA8"; + const DIVIDE = "\xEE\x80\xA9"; + const F1 = "\xEE\x80\xB1"; + const F2 = "\xEE\x80\xB2"; + const F3 = "\xEE\x80\xB3"; + const F4 = "\xEE\x80\xB4"; + const F5 = "\xEE\x80\xB5"; + const F6 = "\xEE\x80\xB6"; + const F7 = "\xEE\x80\xB7"; + const F8 = "\xEE\x80\xB8"; + const F9 = "\xEE\x80\xB9"; + const F10 = "\xEE\x80\xBA"; + const F11 = "\xEE\x80\xBB"; + const F12 = "\xEE\x80\xBC"; + const COMMAND = "\xEE\x80\xBD"; +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + */ + + +/** + * Provides access to /element and /elements commands + * + * @package PHPUnit_Selenium + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @version Release: @package_version@ + * @link http://www.phpunit.de/ + */ +abstract class PHPUnit_Extensions_Selenium2TestCase_Element_Accessor + extends PHPUnit_Extensions_Selenium2TestCase_CommandsHolder +{ + + /** + * @param string $value e.g. 'container' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byClassName($value) + { + return $this->by('class name', $value); + } + + /** + * @param string $value e.g. 'div.container' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byCssSelector($value) + { + return $this->by('css selector', $value); + } + + /** + * @param string $value e.g. 'uniqueId' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byId($value) + { + return $this->by('id', $value); + } + + /** + * @param string $value e.g. 'Link text' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byLinkText($value) + { + return $this->by('link text', $value); + } + + /** + * @param string $value e.g. 'Link te' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byPartialLinkText($value) + { + return $this->by('partial link text', $value); + } + + /** + * @param string $value e.g. 'email_address' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byName($value) + { + return $this->by('name', $value); + } + + /** + * @param string $value e.g. 'body' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byTag($value) + { + return $this->by('tag name', $value); + } + + /** + * @param string $value e.g. '/div[@attribute="value"]' + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function byXPath($value) + { + return $this->by('xpath', $value); + } + + /** + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function element(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) + { + $value = $this->postCommand('element', $criteria); + return PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue( + $value, $this->getSessionUrl()->descend('element'), $this->driver); + } + + /** + * @return array instances of PHPUnit_Extensions_Selenium2TestCase_Element + */ + public function elements(PHPUnit_Extensions_Selenium2TestCase_ElementCriteria $criteria) + { + $values = $this->postCommand('elements', $criteria); + $elements = array(); + foreach ($values as $value) { + $elements[] = + PHPUnit_Extensions_Selenium2TestCase_Element::fromResponseValue( + $value, $this->getSessionUrl()->descend('element'), $this->driver); + } + return $elements; + } + + /** + * @param string $strategy + * @return PHPUnit_Extensions_Selenium2TestCase_ElementCriteria + */ + public function using($strategy) + { + return new PHPUnit_Extensions_Selenium2TestCase_ElementCriteria($strategy); + } + + /** + * @return PHPUnit_Extensions_Selenium2TestCase_URL + */ + protected abstract function getSessionUrl(); + + /** + * @param string $strategy supported by JsonWireProtocol element/ command + * @param string $value + * @return PHPUnit_Extensions_Selenium2TestCase_Element + */ + private function by($strategy, $value) + { + return $this->element($this->using($strategy)->value($value)); + } + +} +. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Sebastian Bergmann nor the names of his + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * @package PHPUnit_Selenium + * @author Giorgio Sironi + * @copyright 2010-2013 Sebastian Bergmann + * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License + * @link http://www.phpunit.de/ + * @since File available since Release 1.2.2 + */ + +/** + * Object representing a ",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
    a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:k.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("