*/ class phpbb_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff { /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array(T_OPEN_TAG); } /** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return null */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { // We are only interested in the first file comment. if ($stackPtr !== 0) { if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) { return; } } // Fetch next non whitespace token $tokens = $phpcsFile->getTokens(); $start = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); // Skip empty files if ($tokens[$start]['code'] === T_CLOSE_TAG) { return; } // Mark as error if this is not a doc comment else if ($start === false || $tokens[$start]['code'] !== T_DOC_COMMENT) { $phpcsFile->addError('Missing required file doc comment.', $stackPtr); return; } // Find comment end token $end = $phpcsFile->findNext(T_DOC_COMMENT, $start + 1, null, true) - 1; // If there is no end, skip processing here if ($end === false) { return; } // List of found comment tags $tags = array(); // check comment lines without the first(/**) an last(*/) line for ($i = $start + 1, $c = ($end - $start); $i <= $c; ++$i) { $line = $tokens[$i]['content']; // Check that each line starts with a '*' if (substr($line, 0, 1) !== '*') { $message = 'The file doc comment should not be idented.'; $phpcsFile->addWarning($message, $i); } else if (preg_match('/^\*\s+@([\w]+)\s+(.*)$/', $line, $match) !== 0) { $tags[$match[1]] = array($match[2], $i); } } // Check that the first and last line is empty if (trim($tokens[$start + 1]['content']) !== '*') { $message = 'The first file comment line should be empty.'; $phpcsFile->addWarning($message, ($start + 1)); } if (trim($tokens[$end - $start]['content']) !== '*') { $message = 'The last file comment line should be empty.'; $phpcsFile->addWarning($message, ($end - $start)); } $this->processPackage($phpcsFile, $start, $tags); $this->processVersion($phpcsFile, $start, $tags); $this->processCopyright($phpcsFile, $start, $tags); $this->processLicense($phpcsFile, $start, $tags); //print_r($tags); } /** * Checks that the tags array contains a valid package tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processPackage(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { if (!isset($tags['package'])) { $message = 'Missing require @package tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (preg_match('/^([\w]+)$/', $tags['package'][0]) === 0) { $message = 'Invalid content found for @package tag.'; $phpcsFile->addWarning($message, $tags['package'][1]); } } /** * Checks that the tags array contains a valid version tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processVersion(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { if (!isset($tags['version'])) { $message = 'Missing require @version tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (preg_match('/^\$Id:[^\$]+\$$/', $tags['version'][0]) === 0) { $message = 'Invalid content found for @version tag, use "$Id: $".'; $phpcsFile->addError($message, $tags['version'][1]); } } /** * Checks that the tags array contains a valid copyright tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processCopyright(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { if (!isset($tags['copyright'])) { $message = 'Missing require @copyright tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (preg_match('/^\(c\) 2[0-9]{3} phpBB Group\s*$/', $tags['copyright'][0]) === 0) { $message = 'Invalid content found for @copyright tag, use "(c) phpBB Group".'; $phpcsFile->addError($message, $tags['copyright'][1]); } } /** * Checks that the tags array contains a valid license tag * * @param PHP_CodeSniffer_File $phpcsFile The context source file instance. * @param integer The stack pointer for the first comment token. * @param array(string=>array) $tags The found file doc comment tags. * * @return null */ protected function processLicense(PHP_CodeSniffer_File $phpcsFile, $ptr, $tags) { $license = 'http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2'; if (!isset($tags['license'])) { $message = 'Missing require @license tag in file doc comment.'; $phpcsFile->addError($message, $ptr); } else if (trim($tags['license'][0]) !== $license) { $message = 'Invalid content found for @license tag, use ' . '"' . $license . '".'; $phpcsFile->addError($message, $tags['license'][1]); } } } vLZ1Qۧzz2p,{` mI<4c:u.·"ڍNދG@G,6q?ę" R!?-I=rײ03y ,ۙX2Z!7Be]W`Q5+&i>8< TɜQ[2H,=ȁG%]mu#OBbNLJRMtjsi, |-~lnJ=]"x/tvN [<9%(`ڸU^&qcxi">==SR 3wYCCnD +mMͶ~ :5>sk'aWQgKgZ9[*p#̮!m$pb3pn9[jfϑa~p͝TL7Cx0(ISzk-^ZǨӆ`<ʄouYL?Do.C*Ô3-۬wXݼM=* Fr( LI6g:gJ,"Ctp!HrD./7~+ʐt SOtͭ>ne?9?}1XPzq&?l§:ڎR~cH/*f?k*O񄊩j Py븠#6?F=E+U_ĩK% &X%0 ;C~qU9w=(Ԧ:bI]ŐO4ĨDZ-g%k ژfԐuDarH/d n4[Prjm% ݙħ:>@ŊoGBunVһĻ>Dxxg ZN6f jOR0۠Y.a 29y 4.g6@rD#v7S{o9SعT=E (Q^ksIkh>XҎ֕WPMW#%8cE|ܬj,#K")W9-G<A_L0!?1>4Xdf3n጑m,T#"2%D*c/Bؙ/c;e2ˏa)L8 -qAb2frm,hYff@Ic>GeX\ؗߝk/QeMfUy,~J 6&IfyK`3MC Bo Z N_4`xk2^)# !-ء/@0H>G2ޕwxthTDaZI1qu5#_CR|jWJoclR wzeEʢዝmvK=v>/8TDTt=m*AO\6vIvD`̳%PHvo '{k{}zXy'4;AB7%Nc>vDAO Ն6)@ ր `ia:Tq,x:bnMmP:ټ2?0OMJǁLQ9@AEh;d]…bwdzGN ]5D8UūW;Dej6Y}:;Y: ~91u}/aώVCS=kebġk? '))@ؑ7Z+~T1Kg9 VUć9&Lwt';Xu;;L"G87˻E.67:*.%QHkYxĄ d@̱KYGl掔ɞܜ:`'ؗXtp%dIKQW3b+*=eTa7kҜZpjH1.:I3ߤthZ?~0lS+6]$'}Hp̔5+kqmcl>`:Vƞʜd $،&go_Q$`:V%J~|dCbE5cI9 %i)H٭% :zڹQɁx%3 ;C)I;/2 }|h%!ɺ$n_Dd^=TfzR ukF;Ϲ?Ԉob|[A䈉mynBsa#=Qy&Y`w2Iz臓VEiM ^1PfZK5g )BX/p LR\.h<"L*EE}z%,4q62U㧊 [$_0Bʡu-oW3q/6H6SPˤ6f`DcyAf ǽ& FF65>Z_Χ3r=ݮ?S94pWnF6ew8vKbbFqmHAY ۏzZ!?Lm?%`z!Ppre۾D?gR 4sƱ,FN\i!?Sr>{z! Q] T \ft>}K3(fwo[Ȣ"*oWAi&{GvgG{!c]Iۨ/ud1~ƧD2n\F|T;S>#{  ySzI?.rc*Ch&ՓI((FxEAPm4"ͥBƟ4'j\D{=2n xjF5{/&I6vڣ<#"kޞ#f' Wڃ.kJv!j%\^M|H|2lfB8.@L8 u",bD ~~J+9!Y v: l?0vaPʮG>/}eٽxY FtW^ڢcZϙ۽ A"7ob Ct>A2b; E܈P @H?PS,gZwWb'G7#]/[ZHx>Q"pic&P)'㒗zvǠ6TCլ--\+|oϡO}F 7PPxkCͅѸ`..BI;ǿ3vDc(#p7ٷ oJގmLU@nȓaeOt=7YCHs!ez"tkʾB1!C[v673l ~3Ise2ňVT6IMyE{OMW[D`V 8Y{%XErW9'"v |m>gzExRp: aO'&:py6FzT; &]"X]@9tfg'X<>{|5bǻ`ƒ@cz!4e"9 rZT/]nw1!_w4*OxNlw8QpXl!P'Y}bjw^dvcāoP6t>Edvjnfy@Sxm'F R;AB)ǁ5:c-#a^Y_h2gj0V~dawcmԃ>w0Ϩґ};)bL1TWVLJ;5˟[6k0֣+Zk7*!=ֱ^p?󢇿t36B%xn\:-MKjKlzVt<,=L?pa;:jHyC~0q`f}Z)m ~ri?d`s[TSpǢ<֛i *-ۅk2%{ݼ{WwL?{7.Q<u [lxCrL0%Ѵm9A-Ͱ;p)SxM#~= h62I~]i@?]G~EbcWatnYP.Á19E6y%O2Bk%{xQXTD2qP+89{X Xc ΁~b˭-?zqwU7 1Dl y;cGLJ!uZE9lPH#N{!Zh"q$̗tO(B9_{;H!@dǘd__Lꀠ+馇A<ƤeX0 =*tM^_X~VщzO'~j(YȡiӋ&A(T`RMQ:!"o/mLN&pE+jVatk$n2%d5hs 'j#tex*^9ԄG[ZXj䞾PX $[nǀe<ګo2wCc(Ǝ0]{a"p该:#9muJ=ƻ aAmIx]r-#_ɮ^J‰ jPנE{Ѽ1au|.ByQA7 l<(" \W,aSNy njQBz+m=mjUj :OL A2E3kP&}}>!GT%qSފ> -FC>Y pkտ\I*_~V0zCw @`?-: LAY3vK"qm\*9L=fvͭQ'!aBdVAL1Պ)cعHb4tv FB ԣm jHyަ zϳrr%|&MrcD ^`F [>8W"AǢ)]ƹ7,Q < +9@WWimMz@$`oZ P5m|)<)@B,ːQ A-t#B!iA$59L4 ʀu\Ӛ9;:I-yi75ѾLoRe@DC-6J'w+@Xn#'-̢$l}q 0mŹ2p[66o^ Rnz`2f_,9]"Vͷ6"A ?I&zY*`0gMnTIB)۞ϲ+] ~oY鷲\wB (vG>nyڴ~qNs9t;֜Y4i`ڤT7`/yLliZZXjZ9F86b{+";I{pR3N tD1uQe# .Lב41ּ `AYujn_ͣqt%L(|iuԹΦZFY#$;Umk(lL:0a_Z:,_:רNQbv /nc|A p^)OOߠY7kR-7qc$VL}0'o? x(J`2.xa-݅˫exY݊rh~H6~Ro0$J4A[beMMotEM{Xb VEH\& un$D'S)s?8͉oƃ{$D1@^ 4Kگ1k K֞|K,S1ƹ sj(m#N"$;?Dڙ$KiYbUfnRr|ӣHLPlZݕneg8jq* h7#W$IÄ{dlj 9D;Q|( x͊Lclu/c@ݣbpr_^57A>벥BMUOdJ0jR\Fa,=є9]!'śx~eM7Tw.*/dW"mY׫9-x=4 -։1: m2*#z2ٵqIGVڎن*KLE-Rsǐ:=QJieM,޾k<~݃@c,ͧ/<ޝj2ZfWF[GbEAD=wvmDlak3,9WJ|.tQDPe3&m]q2ܮ9tO06-gD4V8vύF~'FZI `XF QL+&7bNjoQR$}E7&t}yT>ZC/J|^3x^p dB{U6YxVaQ:[&ͫi.<6W#A+7r6+f+Ͷ 鼖sLX/'x ?A߈捊IѶpS/T D.Wr Yriۅ"_4l?{pbF݌cZ<1{'4DԂ bvo<8=f/?ekgYG  ҉Pxo5"{4G}'Iu\hU~GReeq P%e\_`5nj5å@}s j.P=`HZ:,]dbXՋY'-n?x{<R´|mVq`eD(˴XmD&mW;) RA lŭMӷnN$K%A**|ojӐN "2*} ^d(=t&UWFN=~j muVϵ\`zGj,u8; bFbTӛKh>6 ]$B(Xn+]dA_o}]y"|֮Єdg4Jłl2B$ֻ1?ywe햣3T?}f:?# Tn5y xnb VG!Y.a-m2V%;"3*O4Yj%.E+!{8f6UvpS@TN]n}A1f? 7ǛϨ(PJг>/|c̊[VrZ[SCh5AJkHu)0o >}S 缈)HgA}UfSfJ`ǜ w}\4z  ko>-p験v|v}B7\2Zn4?_*V+2tEv,B`l#tVGm=W/FDNA$ 舢mRX홐hTN[s߅FSFgBOZeC5xegi}Shh3.ꕦeo|-dZ|6fԑ@bTs.}F_b\M;UqX# c r0D`yv1=L1q/9jh 4V˩w2#Ziizv8SrwWBX]@4|8j*"e{bkGsLQI-=.~j}Fa航5qyշNwWa-fhх}Kjݎ&ώ/Rcޫ)7|h80Ƶ 5oep»4kqo: Ýf,f0֠%ⱀ\}[ ͓G>VL&7Iy~1HLQo9̦'wB%?d !+ÒСNԪ5WdP핤[ FrR@+ 췰r[Яm$P!0/g^0Ref30~"wW! .KɹfD[ᒈۓ ۟Q\* oQMNPpFnf1PV&(b=[d_OJ{poV eAl?L@'5Rkhn$jj0?fm>_mE8+ jQiO?v}J`]R($KW5a+$Blw荰D#Z]_mjNhG9S0M|e_{Y<t]Cɔ;}7*XLn=z㗙\v{'mO# E" ]3+'2h7p1A#DYɱz"94!>%}Z\Уr,O!W64hMQkո#0Zb_oYR ݳ|JAY~0# 9io^PC }EZRJj?~]9m#v$ĴA)K0>u)c42f"w a$@h٨D+GDVsrҫPcO~A?1HID ă('B`=tӡt^Z1G xז9fL}[9l9N AN!lm!BbXp.Z6.͟ч\>RDn6bfzRͧsAݺ"]W4†q4;/"%FΩ4׳ EEot.ل'`5 pƥ&6mj* 8ݣ‚JD3H{mb|]-5雩ɻL#&,\6W`_nUL8.3 7pQʝ(Xa+[Z7v #zW qG( :z Rm6k9D4*ip欱df>1<%4d.ZA J "ǀ CCⅣxI#& Z?%2F@ΛFܝj̝kUԄ)qnuHS/  wS @/n!TN}R~ֱuΎ(lu3g 9Qrl$]~"y!P$2ϰR iu,#l“R{HdΑ9V /}|⡻)hZFuٓ|?e֢1[mqOS'lC@BيamK>Dt `,J]g;>)IJ%Wf'[W iFx>ykZ馾Jd2zf'$!;cΠ9"\&ꡢzrZ s.A9+/V~.2Idhc<@?m[K]~X/S]&[kg:Rr)]  Jdi4`q??, hܲzO*%`´L!ăk~=UZlÛƦoy$p=M_X 0DD٬5Rswy= AN4_@4:IBS+vq-k}r $]PPB3fUaljgZA7NQa#I(Sk.F(&O&dABХAFS%"*0HlIYXM\Ddf ~`Ź샕f7Y%A^,gl9J3E(Wa0;!iZEx>As317{78xԳ:*oNPk]ʱBTYl;oM1dn;GfF3W˶sW9E s_'ױX^k>~qh(n`hm'rKelkP=:FVFi_'⸐V9YOB-W6\i,eFM ̔w,-Ib⚰;ZtSJ,l#5&X?,̅B}=|2a^h'h2ݴV0wv\dBnPf+*#- kh2UY]u];ka]G;Vd둥Jo{Nhpߵؑd+ܐ0k/1D1[4sBN e$|)XZ^#ypLqFOPb!18l%* ƓH7E!ƿ3F2FqP4AySSu_YZ sDr(fr+ @ӄMzrKAfn%&*{IEșmKf4Cs>΢l3' esѱ`!1we)@BcG`HBU1\xM+CYWh=iTwY/| )5׽(!e"/XvOؗ*ư.(צd>?ٳ1[w>쾣Uyɬs`} , Vu-D2ILb{z/j91ylOY-x"-44D2π Tlq\\mEELa;JGAVt Q0!  bkw^ mP@|lF^0F(6&;}&f 6NMRt#ƒmr7BlS?(k3h#8$7{?!>vJP)j+vܭn9Je..Dwϗ"5@RQ:̭> m}Y,ǰ@7}_>#}},/"?MO 7M\ "e k=59@hWBX8绹o/r9̖Uv$M ۦܭ ~"7 4.CN0hF.,0A*0("fT8u^A?,º`ip bI:.h6\l!Iub<<ć?.V'Sb5[fj5/61OcǓ 2hE6Kg޿22nHKBZ.w9&꧱BQ;B`@i&K81qSa)·h=Ž-gtVA+ѨIKa#w k68: + \ep[ l=OBB-Gu]Cw{]$X>5>nOo^!&UoHs/);о Gw0O4aUKf#~[qNl, itFzM_]^y`LPe-Kg<?IgM.J 6_,:+Bz9\7N )GjBڸr|9\U>2 / 2$8YzrD%D.[`@[e)} plWO>}'DL.Nqlcy/xZtlƒU!K xZ6qRPç؃M(0Z~C_7EWm߶$Ƣm,hHϸ?N 鴟L۝hVQ(6RFt4 ntlz|<:%*\ʓ\Mwr5"Ġ&x]6ZP@E(pEcl$tP x5@͗mq,eT]V'INP2/΢eXKe1])01L@O |nsKp7]vU? 2CDTz>5_qF婣/WOF>< cse]: geP^dv'8 IٹϰF,>VR@cWzg̹`9Lo%$*kэ=9nhWQcO)=,$q\pxш vf֮λY1_s (Gu3.4Zr\ߎO g8''Z1}V9\%:I}0W=z)Ș sre_1r5L3ҥTG'!)y^+ pTar_WkX7^yuTβ7_"FDeupeWVg tBXo=WQG)%#qx-G%Yqj?Š vˎ)7QUxrNu3@# !8EpeYmϞ2v#pzᡠ#+2;A˫@S i ^9@Ӈk/*^,D=Ob>Qr^(l{‚c@|"KACxH>W')GKVE&35F :|d@&}ӴN2*58XE >s j'O-3S{%*7p ɜI6CWύL]!..=Ɏ#I͉):xBrf< `7ul`oZ?*a۶ѧ]* 8ZȂJc,x"|(,a Rm[!D+?jܑ=Oָ&ZH폺Ӽ3G*(D%V=fؐmNEGwoժͦ}l6{v[IX3aM #L:2| g'{ BNERjֲ} !''jFH-t,`]w0?΅*P^=4h-MNlBL{t\&bY*MVa-z:* BZ=`>]-0Ke359??XڲG,@eIs D낹u|Y! 8p ~mfxmD}l&d=?[.#R6s뮞η]V>nmœKE#p!THg `Bf kEH2Sջ!gv %;@]^G_vdѷ ػinGP DDУ^ŋK}=Z5.zb#PEVup*([ ̯f}Kz'qA)D>"xl sw膮x7W eހt0~\G9xmcFA~e.viU;1C :M՜1Comn)EWW)f3#r+@fo/}.g<^ HwgTNƗUAՙ7HrC3J1ea G4(nFAWF7(pÜ0u,;|F *UnK}dTvE6X"X OHh(?=Ģc#7~V)4[09k"c%@{O pB.Q^=`sƁ& /. !?ŋdB50A:lAB̮G G湳.&|fG<9 q*!{fniDQK/,?үrw fѼLd$LSs*RG9DZ~ +V@;!t,|Qme_.nnzܡ n(09b7)1BI|tQG6[7l>8} T"Jj$HL,VG#`e[|OR}΅X\D> 2o_Gx-6av"@!' L9+E+Mhq63gCĬ |p '%͒ډ6ilfV1-oW k '#t̲Em#|3 f84(A\wB+g!=lv?H_-}T?Њ(Zk28e+ ;ݦ#gxql*/ypXuG[D Ƣx|\eDB,t3?bEkkE3% 5ŔCM2EC <[Lg G>!:^LSk괂^H;ukF"G/yu|I"`k'O&$Yh*/Sh.V]D֞ hS5HYjzMmNySϬ{u^l#,7=Jp:pClY lx7\W"cY=^*hf$0TL%A4rJgLRS懔V R~QNiv|ltPPdQr!aRJt5Fd:'wLJ!# _hbՀC](yaOAܮ(Ga7n#%ނHlZ+7sZDGiKi=ukA67V He_t#*YE,/,Xq8$, 4UobZښ}<͓ ¯WP@[KW=M.z Nqu-&=4Pf]x]?6;kϠ4.3NBzWO8&ۦ@9p]PXZn4cKY9L5ZaX~P[f=!̴:qq}u>WdḺ\ƽXRjak4CrZpشr(7OU 8պHx}hhnߨs(, edcP4!G)\.)R PޱsS >*EyTYeHѳW(|N r>es#j*2~T'o""C7scG;k7fyHʓ7k| =<6Dq]VE|j 5eBFDq:^엔tR,Z&ﻚnl yVp>>u]xX 3T GdD26VP:޼߯gqF\4/O?Oōij{^S%șe8sB=M8BJ?a"hpC:վ%5X^}X͛Q~6$q=ȓw[+EKޖp8P=9NՑ\Υcs%Ur_c5+͜V DÝ;ڲ9E;{}+[+bOns8" Ojn`wFX4kJ]> >yҴ$'G4YɬuW a|JՑĪOB?tF&^[G_"pзD=bUd~R5*Pm ÙڪP3KSg/M%mŇZh"nѧ6d) j~!<~% ؝[0VQ25,tqf1Rj,42ERWP`e,y8 6G3Ǐ^?)t< xFHmp.Ň 3 82LVKQB(ؾ=F3uz ɨ%Ұ~'xĵRqa*h-`pW!/ΒB}%iOw-WUU;Cmc@aZ<.(v^'!VqTb=) d3{`4{Hj  )\ys1'-ߩQ=AD꙾͗~#g"@Re4JWFݦ+2jQө˄Y )Q)) x/SW) שp۵%_RXo#$]L Y8'9_yv7OD rh |q SP7tSfpy9r_j @$椖eSkՠOS֫P:u|@/9|Sb) ,}eWO|x||"E,D%J5_^ E+XφH3xQBū5foIx$2~ODp rJz4@1RP[4 ΐ|-m` l,8!EgZtQ]ET_RIH;v'pBiPâx%i5蜧 Ec'v y +s,Nq G!mzʚ۾N$R>o ^B`3ˎ-vxqoBDRb֗f h6j>$2P_jYZzȮen&L/fсǁzGnVpÍ (56'VTlYȩܯr&0|^!aS{k58YUx_99Y٤, Y)1N4,hV5k9.  ZJ8 +Q/gʱބ t=#l@ΑXdzL̝v0G+{4F}qaﴗIƇJ7*3jCgY*&}lZj}zfF6GVnnY7х`*!-/k@9+)݅`udڳxvU-}P[8ju7’] vkR}CVB3XfDM+B6KVy~joi=.Ua&LF~ie'XԡL_;b\sß";]~İ=UEd~< -)  @yǗQb% =v#$y/D,")uJGUt%6DB'>'H@TۼHp%PaPQ&y ,Za_hċC cOaG嘮5̹d R87^WmhۆeBiDs2Ś`hudZo\Acr\!H92dYC13UB&[4sh%M<5۩@wXz39.VJy˘?I%MU򤐰roHz-[+~ HKv(k57FMj qCLޕt ~ :ՃF&O~|o T;-XJ }lAzE@^wmXrU_eVͰKSl\) kν+=pnqZ ([N"@b D6:r $82-¡=VVE)=R (q$!HC:B#*4e vx}azWU~ZmnNhJ托z\lu[/\2䔅!nqt_U;V_d^ \=(I靎(`dFgZoe@U3$8)|!l^;srkat D((6J݅o޶Ov*!Ts y*&Qq]Nݩye*E7%x4K,gNH^o Oޯbme1a׮|.:|ѠSgY;\{Pʄ.$_BZ~֩V: KNl_ܩs8P)l .'Am%fͷ]>KcPPzE˯{. ˵g ]KV* ʊ#c `iu@d{aGF)8A;: 0aaw:~.Buprn׆ |UyY9.4ܻթv UϮ4.ė q_YΠA&Y(5 xHzI+XTߐ &Qk]SO' * 3yYB>N&*IJMݽD;_IFNM9aڨ@^.EAGT7DL!/μ9§H 8{KЉtjoQ6~g[8וǃ}J .-J^q%+BiS68Ө8}!j4(]qCgΚs'Ʉk%rIus;ٸ1hr/ouAܶA ; K$?%@j[k~9|3oq#p¸|P 3]n 1 bVS {Yu4a^^ qrwx] (Ot~9Bl'|fy]湰 YmkR3ZMV?b%|pao ԥeYGn)æN?TkmW`;--/1Lb'V*MbnMw$sv$>4 ۠?CO ;%]\42kKȀ\ b\Zuv*Nw&/.yK }gfwTIFS(6p$cQ, [I,(.qo !,}HKm3e݈. +0ұ%ӨUÈ}\n{2ZPfrl%tО5d|N#rEg1؍+]ɽfP =9*+j0Hl(+V`2rޞcth6*[|8ΥwYdH]5C6XmBE͟[a~2@꫖5\g BhyḂ'U*Bٹ&U}*/Nv MGBޗ8PF83Ҕ#oQCmSyvmU n폡'f,[IU5ڇCWQf@4mARJViyDOС2ΏXzA sNe]&=e{ܷ33X^[_E1hgeo"Zk"7{k/9nȖ%i3퀊~!YO:'l#a'y&kg/"4S; 7$ u񕖍+ΫĂ9$#guOz9{iD!s;NHmv:ΆjTki)s\?ށc21=wݑ3J<T5~Dpx\<=,C'Om ϸ]Gh:j ;=!]@8JL40H>+Mq,W=iv飛|?e)~zspR,0!t `JNi.& 'nӱwdcӉ:5ٞO`܃ˀW~eMI 6RsR~=~J֑pxW#.5]#\ܜuuctv$sy @p$Y1i<qag=:;C)܍k/;PZD'4^eZb,B ^BZ)&wT7R( !Tni:28948 )Oy4dZϓNpdTMh2V>΁ar~`iq؁Kci@.>0}l?*ÌP4vq5G.#](Tm҃YZͽ<m̩SM]3@*Vʙ82F:p$]ƥrЫ:_dc@kʪOE/PVtmfi(}0]# G?A림S1]\v?-jDwYFNV,/"{mQ8,&BE2sdнPuK;*Z8c)o_zgfxP f/h!GSwd_&w3Gkj4^L 1C )ʚ;edzN&dZ괛쬮q-((S(Ku?®< ˆ.(+ .\4" +籔]a/}r?iN.jNŃm}2%8wzJ MyM!uT5Pv{KQPbq0h8& M!1Gy; 8ϡ`/ԙʲT*+YfcԉjڈغlhÕ.KR|q¶I1]/ĈCm7vX+As CtDxNB0Za+ChlTm[Vjf=qlHE Rq$aDfڿe$pf^8>ӑ,2/hc\$P< "|1K̦.h(hN3^i^0RC# cz0#H{c ~vǫ7kMJ(kI{Cj] biX\Hx1< Pɑm_.iXg7G!O 7_aʂq*mam]#U]zJ9 Ih!8H e n ,! /ޚ/uB6MpX4|ռ Vt",N.RgT{y&I0(yEV z;#Uy[TB313is^{||vH0}IuwTm;ʿ9c ,wf ^ٯ}{}' |6:jiau.͐ ugVi%,7F \@r`?, ëb,ל~%D2U1zT?7F@tۆ@1~mPɘ4>s2@\Fw1(dmiWHڧ#qj<ʆ˴ SMU"BpNJ+ҫbtrVW>Dx#d򮛉Hvz{ڒx+gx^ʏi3h_Ab=+lۨPkB|L5.v攃J5v#)dS?iv0t$Q7-.:!6]|Xl?#'=M.bmא ӰW|9m_`/Oh ܫrǡgh%qrr+FDޔ-`P<4=tN#Nb0Xa2frxL/,EnHplMRKg[?X q{5y @G63>HGh-j+{x͓H9\ P3Q}37EÐ', =(t؈?=%$[,.DW䂥.0 ?=u#ĢK`4_/ /g1y* EU%LPLYyGNzWB|Trt._~LJw1 :LeQĩf*dQ;1Zohh-\?:ؿXnW+g֠{9dfX?}4H˘/a.'.M ź4=qZu=B]7@ܸM͡~>Q@y>*F N'{LtdsmOw'9cvn(v0sc]YPPiN3wVs^؁nV2rI['EW\Ʈ\:aߒ_K*Y54m1W$p[Q̆E/JxE{ɋ +73G嘷[Jޜo Fg5o'B[Y}~wq*0WU?R)k>2gkcϛg <@=I>vRv>u*D>A8;qEV@uSqhϟHpq n@7#q9xe_.OEƮvV v%I7kҙV2動 C-8Crj7c;X ΀g Az }8os@7ky\6Rv#t6"賵HQ$'4VҊ-c6Veq84d7ZQ$BYpJ$ޱ1[PJy.xU~R6ISl" jS-8^Pkx{hOT޽C7i|0|u#A5΀oKм,u dSk5YZRC l0]%P-H I/@ǟS&쪉H2]5J~ IzʾN#n3cnFýto oU$Hg^sCl;{KR d*кhp,ι5n꿄U+yZ*Fo+Lƃ$ίѣˌ#nHat3Bй Cyk&'}d? ]LW*[bv҆}搪˿3Z1ߌwG(``|uUGK0t571מz,F>kxIyu lLr=/.40Z*È'@}ٶ$36Q O&I{jO 2 !OOJ4Kו^qu5ZXGsB%wz2Oߓfhz&E*.n#8&,#:A U!(2;gl@$ɴ+Qc2ɞ]3h3QG`Jf{n*ܧ懔0˷Asz 0m}ܡxS@1}fŞ`5tKrN3FbLm}ght)9}Uɕ6ҴQG+@!L;/mZ2.8g7VF<L@A(hfi{S)ʍnSmy73|YC8 %ZS(9B\^tcpAUhX8k+Xu[I٨޺.ޛz(YKpкX/ ua%߆>VOog!m5 X_Ц> E8<C*)qOCHN.%{G3':i."9?D-׶l@`;@$Thi5k J¡d_dVnP1" [[zŋʼnmR&0Z_y'jOjMᅵΑ56ԝ'uɅvk֕9Ja9lWvEy>Z[ز^rʊpfP>=LOlvVI `9] O_ !^D۳XYąSд+ws.sTb Fk`ZIo] ]sbndȿ ;2 4U̸%7գ \rGs:pߺ+j 4R$RLB(F$;VSgqb6BGE˞&:z{In Is\íu@7iW? ZnKHL-^@ 60j/y+uN3qy{"w2 Iz Ո PYB8ሔCh+Z{Mp~ %e<=!}G,1+C L]?۬K)a"ޙs ƖQ))AN5X<ȭu> ߾¦@Y c(/e\샫*- r>nse8c"K%QFԝ<`쑆srJ&G rA>n0}B>{J 7qOd'%Ye}Zн? E<&EiۢK+`{M%sh'8s(8&1ZEYbz+ص BX#X5GGN o$-R=~0|`Ͳ 4poYØvEc55\LDa.1z.. I+|XԐtx\c*90[W}*&q )ցS;z: a_i8N@9_%7[b@r_YDAY{Ȣ-['tc'R&yAXWO[lY1x6/$z.;]K/!Ok;~Օ͈ayzV]m, AT yl;\)B!C9pFٞE2a4R"0$9d P:9? 9-jƢx51gM̎Wâao3Q:ɩ TwO¢u6. &=u*O?>'% waIv!f1Y3 c[C@䂷4-k}v5` 14"|`;WfoRS:,ڲ]'kh D ;cn *χ[3]o@‘9s#㱽RRs%`;N{^g5xH{i5ERK짠Ӣxga(M^%^'ۙ.Fo)Cb{m M2][Ѯ:qD}LSf4]3y{MzXGKa Jf [S؃ͷ}8j)>C9wIK~縺]5;J\ZY-b_9kpF3i5,ykJfDiK$ȎfPyaEðWN_\zCE:$i,^tVf U,ÎA!`1VcϠp&#L+WMl }yهp! x:Aq96"{5Fĥ֘N&Bp.}AJT kFw4֨qQ\tǣs#b[T->xWv& mʝCiޫwcUr )0y 'iռD9o9_4Ê"xXȚRrNtkKhq1eʊܖdaV\ŝz<2x `!TW?B&$f:I=O<,c9}ճcU>B!mrQw: ܎j0\eNQ*L , (ʞ{sUR{af`(A8ٽ)yAlt+%3Jr9[`9 1tL͗thq[!Iʽ,!A*טϿTpNEP\m>P!ek8.X{dX)gXp'6MOC1,Cp 9WŤy078P?)2/}? 5rvQSPKǣy=@LZt}77øk \@tcf%|̇y @X-lٙxo6޸Q-OۣQpeg@ 6_a'?:[ X&;,lѢmsʧIMFd2tB1UHpQnL.U3gA]XG,߹ܨ!CtĠa$pr]T)-~Brv' B43Ԏ!Tip=HA ٙS}ìcA9 63wBdlDahy- [9 ZiR}|uvo}$MZj_ v7&DԬ(DW+(]c$4l*bv@'ZcVb#di*'*SJF,$nN!}ot~(;<@Q$~g(=96 &pO-zqAAaV=ea-ܜƢ Ph%^6``0e44n CLZD|Ƀ01܂ա~q]ǁ ~n~7>g2F/7My 28烹 2{j`ҦJ|~@4~B:Ik VJ6+pKWBkMBky aŭk^})(Q;~KlGCa}@"MsiT7&]m\I }6CXzF [':'ӟ]m$}4 L+YeT0k8$rIy+ ZVbF>2 yN#ڣW#G_D 1LV=2x@nw$ 퍔u[4<4A"GΑdZ62rqHT ;o"[6J(RbQ}j_Y^w}RUt~uU> H x۴IEF{ `7e6P,Kw#T(.ErSġ蝯ȿW?SaO|Dz7i9WD8V@*+R֟>)Cdr mTnS{D荅L:N.zRgvJùʓ/0lB&xLС{k_HfKBWeĐ(vcUS=OW8TL.+?m#pi.pf%vB 8VFۑժJf oȩlף*ɗN+ haTgZkp Q? }42:*) 䡔JqWӎ+"Xy;ث`Q X%iY7W1`Ldy6TSUn^{xBHuQ!:L*u7hdɄ[48QϿ ͰpտB}bJ(7,탰u6_b('R}PlU?II; …`'cB3]8V#9|X_/ӕ(2dY K>2agl*E<۰@J=PQ0 ޏ}]4x9ʵ֙2 <T W]k5!${#j`ˌhZ7ZY7D*Pc yrᏮK FhbPi EufJ:FaTb)b4t E[榮i^xq݇YU0U`䯃In8W,%ܵBrRINr$1JᥕqW}J28>AFW۾Q_ӀМrBes A\0a)n ŭu9nr΃ۈw'˔c~ [Ta\]aۘCg =E28 i4U(1 _KG>ʖb˳j$WƲ$Ԙh,)asrI~3yqQ L' 0f*+F~hZ)ޟ^<t٥nbЬ9gC->drvmeM5]"GDLk͸PƯ2bH58/ H6n{e_z_R6(SuHMn 1IX6wc J.dhlgJV ѭRą^dfU" K  8Fzi(jl9kU6#xO/P n&b$OqS$@&Bq"2S$;}c@E$w-ߣӕv?RO9fI; Gҭ6Jbd`": Ē^,KNbW Ne;ёRr/Ǻ~u. tZ#bhl?$>k!/&}l>if >y?7ME=5Ii&ܕӔ%!kY]n )]ֳs}_[QqݤSAS @U>; 6\:1'u\\״8Brsѫ;Yb mi=( 2 Sg8n޵ۼJq:Fw٢8+aӦ5K9zT&(-] bl f:Vj\6 E"b9(b@pCۭ;_sA_zY֨CĖ5SBuTnۚ;h`IlR60|Yӻ7$OmQ,~w> a7_$! =([N<ַ 7?݂ _-]J-7')G9@Y.֬tsWj)' " <9 N*l^8}Q^3PagB+ֻ=N}Ȋ\TzNuH($tVx[jq$+ P]udI o{jРXuA.)_D/B|Ƚ3é+ bpԜL# lZ qf4ڇb' @ږ!јlaEտ yU,'IF=x2Yx e͓l?#wIU6׹8݀#G-$CtۄF{Py!y.&1!9wiR V}-:T-ގX3[8)XI/tty e 4QiQF-=4W&`MCpܞQ"w^k@:>wep|)S$`*mvpÛ sE!=|>mL޿)@a/q׾m8t"^W%}]T8:#x0ïeOdѲМE/Pcbxؕq#h4}!\?B>yN_~/% ?!4'3,&VK1 GjVs" w8=rLK"_?x9MFtd܁#HoP#(t?6wb(\4z[o 8܆ml.艱p>~!,YlG'V'!@b@Fsp3)ğti)~@1"ZP8蜌9iX~t*}L=M.} a- 8󳟓-mz<}Hf*VvNi`Bu[N.=esU*fXM9$uVTD*̖W $r^xBerEӨ\hq+7i:Dx]{螛kLo"w,b"owDy_ VfQ& (Q|ΠH/ĥj3tR0أ-GP|C`<ˎvKb2=7[%TM nF.k=LC}C \h&IJk ~k0M탑jޗنB+¤Qə`Msi$ʋ0C cjLVU2zn1t_8?43U`A fr`]4&#)r/UKN6f#:9ژaAV|A)GQٛ1=.En9D}04wxԆԹNӠG儫&O#-|R M} dWOIfuMU:>ء5Tkͬgvh]Рj[#(?(-Zɼ]JLf)>D`Tb\!A0>j3Etez\snLy\4g5՜4IAd~aGٺҰt 4ߗ4">{>nXsz#ݽt(PP&ϟl;xV┣Gl@c/qEܕa6< >'IjBŁ3E=*E»=|xܿ9QO³-/q߈Ω$.iix1w1;9Md'p8ywK "FڲtQl@z@]T "Vo\nu"J9oJI]g]ÒM=;DמX`ĝy5*̥:9S%'&om8^44{aiϥɶ&41]H_{i\rsMW*fyB'u_r=<^4bQ8T?a%BC"QyD7A]3]1[_fLKИOlSC翁ep/‰Xps?~*|P}1ѫ7Ǻ=߮w`>,C)R$֯m2vŭu**t}ugȫ>υi+J<ް6= b$yN'Aw73+/+)Q7.1Bp&-goȬA@ z?1(@8XHB2oX˟0#'0VHI(]?IVu PD={LH*L`Op[pMc(UǪjoLX,? ~8`k`u|^B-ʕw[d  ey5N'(J|<O~no7WmuT8yta鴅9+::W>=D J"BarQчw\ ɩb=i VݝWr(5v44$8Ӈ>մ3`%vCq PMsnAz|;%i8}4ɜ` x*rP]0zjU^p.IƘM o3K3; J< ‘gYΨImWdP3_joԧӷ ر 1ޫ(ab5ZfsDrJC|N-[C3raʗ)y*J5(K"k hf-!ip]2CFf:SooKߊI%7~_`Zע: Jf3 G6xC0%BҵlpE̢%.oD=XI>Λ^>e5"KlC'!"ݧR?QN+ehtx`5[oi!)D@c.e)NzG-+Lv8-<<} sm\y%efT᷀[YI= _A[؝ ¿+5.iYV`1D"G dbSW,e"Idj2] S]rE}KYmhn8tȸMAozݔDͪmPqت1x`;XdZozZ7PD21 x5\N d8ed+7뼝YwTl+>cp< 7+NoN?UxBfrwO*\ZFaCC"D;V~6˚C朰"L_5Fؾ; T/xtcQ] }i{!]TcRNWoGGVʢ}N^TJ28=!i7 V6PssV &:W+tBEϝc vDL3Uӭ;6ۛ9ab%ݯd7b/}0B1PqGJ5PO } H< qo쑦&` P dsG i@aZ C7;z\\_&Ձ'iW U:8{C Q=v/]E|n{t@l]Qksh^g:oj !q~vRxfe5Ȓ^ qHG4Sd)힎o𣳍aNqB9:7o?7M.Iž >TCuԋAe,ND/Dq o4݊j_4k+0[K$8 emRre[UHD[IbqшTP'XSM+* y "1\bD<{ꙁjkzGiT 1Յi8'>4cOH$)dŜ,ـgV6et|WbJxlJKY#^?FT h#.J@öi%馽ii3ࢷ:EN no~L WՐE:q%'GvuBAD[GfFܦM&XDVnE) jf8CT.''^5%XHbUCɨ97DzX;: ~Ń.L2L3Tw۩@iZ^Ǹb]v(7p AiO`h[Bخ׶@lQZkE G[Ř3;ΩQG>^Y S!2snydq3wf}"ZRyzB]ewQxfЋܜUI2nUF,S@!qɧ6tv8<.9ir44#񀕶:UR}5FtɌ1'M F$~tAw@.HW |*.dj!oZiaT#xw.1ɱ=d:8Z5GVTN;oS,yUtk._SB(|% 4qºjkx=<-Dp™F,ٿKY|%} X-Vaҏ"`]mb2u{!C;uYeк:SgR>/Н8c3?Xll iHh8W3Ћcf3}ŧ-ՀN|Pr*Eg+Ye#}l:S!dKD)up}dܖg/z ԠЛ)v|qSdoهey6P[7B3]}veP! ZF֡]:$ǎ^ޑ`æJO\*[nY2{6XPŵ>\kX'-) ,7oJ T$Wod N0g\)7>oXǜ[C ⥴CQޒK~KV܋J% e1q+h+zdYO^AXcK^?(+y wǹ:1kI i Q:HwTto+$C)