aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/class_loader.php
blob: cfdcc2af0b1ef3206484e1e76a82061bc2e56e80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/

namespace phpbb;

/**
* The class loader resolves class names to file system paths and loads them if
* necessary.
*
* Classes have to be of the form phpbb_(dir_)*(classpart_)*, so directory names
* must never contain underscores. Example: phpbb_dir_subdir_class_name is a
* valid class name, while phpbb_dir_sub_dir_class_name is not.
*
* If every part of the class name is a directory, the last directory name is
* also used as the filename, e.g. phpbb_dir would resolve to dir/dir.php.
*/
class class_loader
{
	private $namespace;
	private $path;
	private $php_ext;
	private $cache;

	/**
	* A map of looked up class names to paths relative to $this->path.
	* This map is stored in cache and looked up if the cache is available.
	*
	* @var array
	*/
	private $cached_paths = array();

	/**
	* Creates a new \phpbb\class_loader, which loads files with the given
	* file extension from the given path.
	*
	* @param string $namespace Required namespace for files to be loaded
	* @param string $path    Directory to load files from
	* @param string $php_ext The file extension for PHP files
	* @param \phpbb\cache\driver\driver_interface $cache An implementation of the phpBB cache interface.
	*/
	public function __construct($namespace, $path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null)
	{
		if ($namespace[0] !== '\\')
		{
			$namespace = '\\' . $namespace;
		}

		$this->namespace = $namespace;
		$this->path = $path;
		$this->php_ext = $php_ext;

		$this->set_cache($cache);
	}

	/**
	* Provide the class loader with a cache to store paths. If set to null, the
	* the class loader will resolve paths by checking for the existance of every
	* directory in the class name every time.
	*
	* @param \phpbb\cache\driver\driver_interface $cache An implementation of the phpBB cache interface.
	*/
	public function set_cache(\phpbb\cache\driver\driver_interface $cache = null)
	{
		if ($cache)
		{
			$this->cached_paths = $cache->get('class_loader_' . str_replace('\\', '__', $this->namespace));

			if ($this->cached_paths === false)
			{
				$this->cached_paths = array();
			}
		}

		$this->cache = $cache;
	}

	/**
	* Registers the class loader as an autoloader using SPL.
	*/
	public function register()
	{
		spl_autoload_register(array($this, 'load_class'));
	}

	/**
	* Removes the class loader from the SPL autoloader stack.
	*/
	public function unregister()
	{
		spl_autoload_unregister(array($this, 'load_class'));
	}

	/**
	* Resolves a phpBB class name to a relative path which can be included.
	*
	* @param string       $class The class name to resolve, must be in the
	*                            namespace the loader was constructed with.
	*                            Has to begin with \
	* @return string|bool        A relative path to the file containing the
	*                            class or false if looking it up failed.
	*/
	public function resolve_path($class)
	{
		if (isset($this->cached_paths[$class]))
		{
			return $this->path . $this->cached_paths[$class] . '.' . $this->php_ext;
		}

		if (!preg_match('/^' . preg_quote($this->namespace, '/') . '[a-zA-Z0-9_\\\\]+$/', $class))
		{
			return false;
		}

		$relative_path = str_replace('\\', '/', substr($class, strlen($this->namespace)));

		if (!file_exists($this->path . $relative_path . '.' . $this->php_ext))
		{
			return false;
		}

		if ($this->cache)
		{
			$this->cached_paths[$class] = $relative_path;
			$this->cache->put('class_loader_' . str_replace('\\', '__', $this->namespace), $this->cached_paths);
		}

		return $this->path . $relative_path . '.' . $this->php_ext;
	}

	/**
	* Resolves a class name to a path and then includes it.
	*
	* @param string $class The class name which is being loaded.
	*/
	public function load_class($class)
	{
		// In general $class is not supposed to contain a leading backslash,
		// but sometimes it does. See tickets PHP-50731 and HHVM-1840.
		if ($class[0] !== '\\')
		{
			$class = '\\' . $class;
		}

		if (substr($class, 0, strlen($this->namespace)) === $this->namespace)
		{
			$path = $this->resolve_path($class);

			if ($path)
			{
				require $path;
			}
		}
	}
}
l`ۧ^KpR$N\91'O}nH K$5VR%CdLpIP[G4_~LW2Jo}M-ae6@HLm ^Srݯ't.f[.G+oMv!s8,_0W2!T&YmY:* bKV{NfPd =5,7*Xa)n4(WRnX@`V6/Ǧ(D[F@]_ƟH>k`*!;N+fG[ ߴT*p8A'#_Pg O@]BPt:aPD 7sv<|lQ'0P,w^?Ia悟JC%G}WzOqoև5/WV3s}@2rϼ,?$_um4;TeƚV PBuܼ@q?<\@ed3tڦ`} Ik]-O :<535qUΤtօ _6Rzi.>V. {F,-d'$}zx: Hg'pDK>n89Iy%:ov" [iX0NQh _d;!N-j|E?d[:MοEf!g&G*R^D$E$/oX'NbP\RNٶv񆸢UV1 削&"c鯉5n?)"o7gC?n$lA\o쎥KcuBL03xDa#u~ݞz r5[Ddef|M*E:iG]>JP[QmғG{-NgY˚PK%ÊQl9ŏ:#UWZ"JZx(t@޴rgCΉC?LG _}eXd' kKS#6bELXnVrdůu02]١_T_M)SdSDZMV W5W]"ԻM`Hn۽19X:ӕsf?KxZrB"e_:BO{~7J濸QF%'z_KIj5eٳ;a )vf8Ujl4weTwo4R<ɖ>2`N,WMpIƧ*s1ܽy刑Sl!:mIEO0 F"X?<\8hO?!i`!r0Jv}Zm"12ƍ{Ʈ5^Zճ 峖 Wn}NDulqz-S2(1XmCI)_A|n _*H_ӲV|y_tȞ;CF*u+ c H6*&lOtb,sg7ڢ %j+8d̖4\UVM-!i|N[YN{O2_3V6N(W.DnCgq_t^@V!Gͨ1<#?d2UP4CzZpYKڃ(yϔ) ?6w_V#vhGP@|7 ձv􎵅ώC`l|2Ah*wz*Fx,F#cDdݭtK MSSf@|jb&.jCgQ>˚6$>dRت F 掱nO$^kHG*8l2v^]*.g^ 17bwl -w| FB[[sv0|ȜRYALk)Rsv/p6ͬU0CFw0a XC ¯sc$+J[, ==9?fD _AlYv a!J`;'DJ+&!w،6k#, V*>>q"l􌇯[bv`?jo]"2w-/G+q։З/#%[p7&M^ud@-h l#*X":9w60 'ޛ[4]@98,zz|8ZT ЗO>qѫSOu^hԢ`*mWڌ/%g[C|oI.21 2@pԐm&g|o3o5 Q^l(Dp=yJ}t5Y4Xhݾ.ɂi `_ s*@P~8eK0PL&Dk<*|T)zWuUk\3=I"JYq">JcEnMGo,QhMDa6|=,Ej~NT̗Kgj|x'e*yւ?2٣; O"ۜj^YЅ6H ,? 7u2Ro?1u6䥇Al0جl N\ort<]Pݳ^Zr47\6=*נ})ߧn W*6w&}+J{8ͬn.o 49Gq<7 j#YزYz$C=C:,\)C h1 gsɈFd H{s" П]_4$O㝟@E`WLC.d.Oio玡@O~eydT7^8mMC۔ԠeCob ݭz:1 !p Cz_dW;XɴIO c@1s" ^#ݖб+]AAXrY^]@h6g3QCG՚suFٱdWҋϻ[9ɑkn$].ވ ׆J|Io9͒dox!&$ӗ ݔqe2 {Ǚ1R$u(}r:ptۄ}̓)*av:嬧 `]y<+0uE`@/~g=xHNo,դOFf:sXdE;qn> Q(dj#X;L!z(+SH4\ 6릑Q}n=BoI BVo6WtHh5S-,vk=ޓEKYrJ ࡍT@f6*kbL\?bèkj"2pR˗.Հ]܎#!LAG bWZ ~S" ;[=@7o0N{窲*Ar*H~9 9ʬxpum`-Ѝ񺪽̆B/[Odx`\cٶD% ?X/W ͖6{0vw~ bn^OL>ݮ'uf,)2j=n܍nn5_l:Fu+pI˝=T"#P+-2}9+kݫS%5 WKξLM`-Oݙ#qZ?SfVs3L<_)ؐĢؕhzF>-l| ps)ZQN*ZZ:#D/կ#DxwB?S ̚|VKyx}a[Ϭ-9+5pDKF%$uH$w`&d/+MρnI Tz0Sbף!ĩ-w7!{s1ND{f)L: <8nryC4-FQdd7e='TՖ7p~VEML BYxg;ܭG9<~ ^x^n4C1 t-ٳBv1m xfEadBDRR&(+\֊ŐY0(ؔQ"5If4&C+0xVYddt@ +^X˴#:y*iA#U_ !Te3Y3rƷ!0$˩_GAeiYu pz60Z~aLA3+2Cf@kjiW0#`NA'vߪ&NNۇ!! cNS8[Lbp'mH---!lGއ*טq߆O{'l9an79=7rH~tm\94E%'OIuUT.1C`ٵ\μ6碌Wĭ^' .[̵@^C'KteIIo~1*r[#g(̒Pڿ&g}\ {SAu>IJ*3*Yq!G v;J*1O \S#NYp ,RnhŻ0?sYSa[*Y`iš1$4LL\]6%i&wZavh;|I?"r\jZůZ[k)m-nogذ_A؊\с\6IzGǜZ1u3Ұ˄, j1r $+(6oDy6gt羜.mcŠHFcp! {n.&-NOvn]tA7fu1DMm]W!&Pgv?WȒ;^n%]R}qȿu IL4;8l.~Lr?Ǹ$(0U L:ܚd%6GltsK Ao$IS@PQʣ`/oV׃LdOo1lҫT Xp0A5|t pAMDA4uF7bg94Fm-}a;=v7-l¨CD E Gڸ`iش ~Hjطۙ&?t![a卭 {`; Oݜ Ҡ(jUslm"P[>TE3d>lMwG3fgmw<>F$T@,licPMCzij}JB:smCr(>׉jӯ]MԂ`Vf.21e]}_wgKyFVQjgs8KkB9dIFGҨW^INvך cwጱѸi7)L ['/@9Z071ݺ=@'f{QX(8"M1p͂zo`dǍbN=ŭ9'\8ShBn$T*k<Fʳ$@ݩD8{YyEU3o'bό4i R 7sI8: آtwG}m, tu?$rnYf(x} !ʆXēTCG`Y X= \XJ/1tS% XԎ<[lSa[#[YBQy5d.N|k϶O}tx+3W4l+op^`w=;x"xVekc/Hђ) QCB( B:iCg 三X '1n2mhN=s" x|/;*0Faܡ}mK~Ɛ^@GlQ9K:ԚjRΧ6pu]odGOO`r>X_du'lLop#Q@,)qvpx'Ң?[ۏ#27S m&m6+bW<3E! ;SqNӜSƵj>=ULDjKHL {B2U "23bYX 4Oq2B]iԲnΑ|ܛt fG ȒY&Tz+-ě\۞aSSU)#/+[XȤ^!Bg9T`tJ >aV606tj[)om (. A+'$^Qruy;vօnKkms( Fw1[!.znm!a, '%9-/b:^ e8ocn- ͐\)~䙉yI(x@`b= (G_P.]!g2.]Ów7aoHDJYG +v~1tC`f@\"!:> 'k>l{ND2N XeB(1tSLDz%\=07eW%uDQ/5'm_?D"_26`1D6WJ]mR>sz unQ3٬*G|®ýIxXغD\11/E7 P؈WC0~HIY*ڧ+`2M%dʊgj;%41 c_5C#]h>cF]˽G~t Sw~\0ʓBT"j#P43gy'vX|&-CD oY C-I?b.6if[.H6, 'eݑOgͳv U1}NW\E^|q{zq}!qc컒OZ <3 #DkB}|C4SO_768?rCqw-%f9H NC#3vHRj[:P;Ҧqw6PO/୯\Ϛ,)UhA-0H8 -7}PAb#Y:B4*u|zH5 kvߡi<`Z@m]p=+DZ#q}Te|jmd L=U8ެME *Jqf?;U/TX2T9%d$e|?%DSv`Qk =lB` xroֻ$K-/Ζ}}#wC nP/ɶ|ѺiR%IȞx@IeO=z;˜…㾙 @9?CEHG Am!fz)ihk]b1ljg 4 x̻lk/nwe/6uuRX ͛_Z$?U&\5Qƾy-?3H}e\z"P8E< ^ ú-9_] _&)Zw$)Q+fXOH[ LBSr.q'#klaoqkmVZi3ZC=v g[Y q,<8N-̳&\0&Kv_j"iAС6`*kmgf*tQURHSMAN5F2Y6x -fJaI"*R1 Hxlh ֭BtmП@#s}< $9~ PhəVKs?K uhNы9>o~S&ڪ~kh]:5sڳތjhPݼ$;tD1R%hR|WCm>c@BZQb((t!'zy}`0UY[B]r5<^!jߜܷ]=rҙq*m.7-n| uĖ)猄̬6&'ȖU )rP{S_BT zRJ32ymA"Wċo{'ݩ ~QHiKdl,O MGrɦ;WryĢEna2|?d.;w3M̈5[fQ\Dqy5҂u/-Y͑ڻ!H/J}Eˈp%݂&aGs4dxЪX\Ĥt^{</WagdH3uѹs h~V*bv%mR\0h䨆d@0skQc ? )mp߾JT5']! C݃Gg;PM8x611/sTV0-Z}ďr1t~vr}&GD W(P۠t9Lz^JXK_o_q$^41&+b l,nȔOI)f_1H;nvvgED.[ZJ1η1z𻉉$i$VHEw9꺒m:) QD'n=Tn)Md2ݥnI)we00>ۏ!un(j"``pcO{fEԂRTuaD=':8{wqF2kCaX[(~[h;.6h uHߴ$ږM~ }8:<(˲EmtWъg%exO5 RMv1==c+1dAslf\э:N̪'ˣ":[vO͕.a:NA\eBƣ%勂dP> ʓA+~f'0"T৥KT׀T,}lH΃?/'!Hx >ɪy/m<ء-޼i!]NyN18.k3A` _MHe*αU_ݙ!=۟t2ȁgb4iff;Rq/Xe5\[nOC1qpaѝ];Zbm߃N0h*[e[Em(3A4h m@w8jQYG;r[6ޣYgLq{w&A aqՉ&!iɷc?KF~Sw\2lv(i^)#jdo=ۥGbe9ŲZJvI:,0-;Yqd=p"6ޕDNYSj]t?2)@6 Dz-TyؙsJt"QH"AgXfRl:%8ȀZ)K8\5ݹj}[ ׺VHuD BI.p6}A;|tJoWbb0aԝGV4]6ܳ=cOF`XB@kܦs o:Cv5NsT6 r>"Bc}h抻nbl6ґwտސtAd> }CfGagZ^Iǹ!!]+A3y/?Z$\aPD5pуp=a:|BE3 <"ƋK.8D>C۶$Pl՛NbK23Ց}ߎM5naWzj~lNup45dIf]7Pe[B{ͻVX(0~l=(wdͻnr+osw]oC=*itxk#¬W߳߃rUχN:B'P~meD8$s\tt O(SϹ[BloA>>RY6Yxl:9(J)_^MXcsDKh ʼkE8{_kxQͰJN%WHV&OFYn<LzAutQ]ߏdS>Z6ҝȔy\M,D7 @m =2h h_Vo"pxu7uP_'.񨥫D<= L}b׆md ڗ\zt:R7RS,g^S䃓EI҄J3ƚjpDYvE4OvO*049eX ?wrNͽyuk}bIc~u܎2Glqq >}Pk'C/ ֿF~MVo3|SxH~Zd\Yib 2>_%Ϟu8&2qxt.W|.މ/rJ_ԣ8#=%k0s5HUbI5+6 ÖE?ӸipN>\7/VP??pΌͬ-N(W* 0wG:snN;H6uGz~ۯĢ!xZI7ڢ.T, f3p!(Ld?\k}%t"FB]):lj8,>ANHg8rv0#޽?œƄ/V{(|"2kEXq>fpiĶ1;7"!޴rql1ls4XWQh󭿦W+,'PoHV4.8Ougܳ@ŬJSAeKnw7 x nF:S7up,f^,LlVDmdž#x-x?1;%bڔ>x 9լ[! ۰ }b|$LJ[E<^H#t"IKQªY/1\B#4I+(xaB?rD 纵Dm뚄.r:AU1OSO1US܍⻨uE]~]B8TRϞe$Qg@Z$( "'>j\JwJkY^\@9SM\_Kn5VcyL@!(1RE闫'+d"N42.J2tfLovT˸s^WTTM8,a,~绣-E}< k_5ZaXa LۛdBaD`9m:ԩkJ?hT+)(ZO#M̞+Pڥ7-Fk-ðdi[8Vz3.4T}|"#zN#ti6,Bȏ7k"\jn1V7Ǟ,8ě4D'>P2^t=Ń4}0J%v{plbu:w㽎_b^8)B$ոO<lS M˵P퍢{J#ΒEdRD 7pP<8Hbꖁ }siݜAtX@qLM`s /:ZH9#\rٵ_@YMݠj,Ia62fhXy֒{3l ,nDpeG,t*94ضDZjjTQ o0HKUEV{3r7$œ5 VHk&ӉḪ.WoRz%fnt=졧XT Xfo?;6?}!ƀN91SluM0)f{҄QaL(1y hq.!/d۩"@zKifUd)wSHx0,dS 둪zNL/>]vwc J?Xrq"W:>yJ>Ң8zuO]6T`aZ1\F%|~kIѵv^/_# uq˵c_'Ȉx|&A2\?~QCs~0 K, DN ntBBKRTy٬ SmC} 998ZP7x&j+I{aVmt3ф:bPkD[4=9R<4!sZ /fсp԰cBGhO(CN1RE{^{5s%Y_M >`>Ӆk0͆!>12jhNMM )I1 oEh.ؐDa6И2MƞTU1lq O{=d1 0s qk_;esoV&3?agT|&ldTzê̕{( 濁Q!swbh ,.vF$(9vQh[Y%ܕfB2ZEtdW8\i"/^|hE2im_ C3G9 *!}~{txΕT| \_^JdbQX4w kv;iyn/IH,4LC=SJU4ekLa&UDJ${$$2M˭ % Hki0=c΍?m VNLs5p²i0U 8ҾҊ*9[K#Mux1q04U]d3} }aY]8T6 sSE\Җ?T,e3d^МY䭍A1} :JǘO(D?;7=ohd`B{㭙L`s4iQ{%GI)BᶦT5A5WDOzmp)MY'ReBMudU;pU}T5K|em;MQcJ qՌ{ʛp&=^=c5 ı.*F6xbL< oN\Eu!E8#`?q&na=VgwIK6XUDOd]/&BZJ/}R QQGh #>h:ۀ.VPQ T `ӷȅPj dIiG2ja:R&@+7kx>65BV 2ʘVGUkd׭v;\lmV}a>aDCU4"_ 0oP~Mj?z"W=x. zi6Pwo^cё>.& ''y9An_=e=O c4U?+$Bu,qFbUXu&*_cݎfMw2 g}fQ NOL n8xښ3"UM:s+ݹTZ]̭geWpX?RDS<۲]XF>h,Wu!n%|V !Ta:DІ,#av(rd4 h&Cǧ!_/3,OOl` -1,.[˫8W'#v~|D@n`4 W%,_W̔1RͽP?./S8:`tWn!nhu=qD4[yІRkc ~+` Tl7F[51˕4&V%1|^tKR|#5hUQ&N;U 1][<}J6Y]>`EIU#9y=Sl꿲(ϡ+EP\o8 Ep0ANjZ.WIϧt7QXW!(Ì/q_}@vTtBnվ:ntG„/ -ϲJ#Ay0VRhą3Ygcp{ZdnDDZE{$_j C6 \@& 虪yMoNOOh& cbIq \0`*7g zt ټ4t(]I=(2Uts2VH(?hm-M0.wÉёdujm_DV)^jG͝ueoPXj-Vqlcy}փ]DA^ *߮!d ծSzk2T"C 9b?mno^t TUmI>MԊj}Ux W72_C;`QXٴxL;^H>lds28bdE6 }ֹ36oҒ$?s"D}92.m^m3cї.Y$W>jX+C0v0r(Y*d4s'C2,nz'6߇}K5 QpPxE{J>kW,!j.nFӇuV\;a{^:2~[ӎa |!ίЗܾ5fU;'`!<:-R({f *;|@[  :<+dDGcOã$"=Gpagmf0$m/HISm{"`ljH JDf>TĦ_>"nx&SUAw":(l!O5k%FP2n8cט@ ׂ9K".'|c2Q[ d 5dqR^v@(6BoR+}Kv#Vs 'yX3p+e@PZ3'{p4%:14X˫RJMO^ ҐvKL ЅEʈ-$"6!6xFQf?Ob.*̡}6<^w"~o*ԑ7rbpO#Cc4W%SxAk0غ,MmTEͲwATG5A*EIe`F%OR@.qX~=>YMm@y~Fs%3Q*6J+28$ IQNWqx g螨%ΰ*cv|r.B>:# F?h,@d)q5=V s%bvau>3'Ek:"{8 z`pÏv'3Ļ=u+*_u* $;Ьp̂li-TbP!I^_eoY3!Sj,ثw&jel4_1} . ]˗Y>|vwS w#ԩMQ{K?iNU70ŖV/Z: 2ݳ7gw:Vw!'DdPG+wb;SɸWC%S[w%ޜ֐qU }{]Kבx5$cT!wcNGKv{ J8R [*fKL1#m<8[&fEG~`ޱ$lKp[o'GT3l׉0~ [a=tX{ps|gz-.=tMH窹YO 5HыiK>| Ѹ=3;^R&(߲U+@jdY3h nV^eҩ]j E{=QeIF3`Nr|JvI Ęk0f3gVc%L;L:qPt1Ni7?CbP0*C1\(o+߲mRbuE$>~TbnsㇿkVE^.{2@ƒl{pm*Gx{h#~Tj<ޣ*9 ώUMv*vVft k :} Ð"']ïډiqɰZ@c[R;~MeӤqo22R %B_ `q/~%b&ml#!kٶj.Ei~ǽ, ̮`h֦m\eMyIG0~IL 9E%xi \6o鴙4u}3dJvXqੱ]( O>bD|$s7̿Rih ČutBbNd7N; aH5=*L.OIQmɑ(CLg$>1=^j 6wO=Y~l{`g\-#OEb}ԥHq'Ɗ&D/3PJӮ)`!K1(+[(ZZVq j^RbSeGVdS(&]0;1`~tma^dn .yU'987+\Ы4 A05YZBFN_0bE&ڝ E"ZJH/6%2+Չ=+J坄eitmx ddVחv{Kq>8y]m\ el@P LY!-;S3 (QՈPk϶DύvE ۋ`C%eOQT٤Z@^,0k;E<GiӃ_2RQZܜXKd4ڈsÐi-6L1cEOQ.:{˨\7bM"y,xdRXmX%fl!D$ၦXhB4г1@ j9FW7aF\԰ 6m@*tsLoł]H1A \(&4nջ(/H5]( S@z^#'{nD H`V]d\/Թ #FuYлZ4{~^% ĭ~@tI~%֩;=e9Z cϗU=%ה; :cؤQCуСŸ9#k'%^3" Hg&0*Co[ju _pnp^{ϸ>!`6_iY5ŕS|%GwWlh$=;ͰykʉZvO' ,uk͈ `9xh<].FO?vx~&uiїu=7 2L!/*ao~ S7h"zh,ݑ5VyI]pHԱn}?ƿ\p_B|z:p[9zNڡ8/KG5W-+-hK+~ryYĕ4B9iٴ_(An5ۊĖY>t$ Fl.H4f=ݷBL*5m?/%==-NPF\,+hkvq;JxKO3͍n3GkL|Ҧ}Jjc(Ņҹ6P^Rj$bTcL-qMB6 ]EKT-M:of)BQHiK CO+&u6o8'aX^'fߙTOlHS9$mbYW9>iqinG2?C3O;sfA+,%<I6 /o6FJT>8Xͧ(Oq&wncmf,kL n1VHrQ%B_PwyeDm柩iXTa,lw'ҔTC}Q$D$chy 5k^j3#Ι[?1II<.pZ9p>&4CUlplyG}IxyS譬ќ76qwt@#c/>c=`x5325 (| "c\Б q٭=$3ͽ"8?8醖l BKњҳnŃZE=+*ͺv-_lMmܢv9x`K{roԹ)MW+*oEq"}M.Wфi]m?ZXqO2[K_j$Y2QZ>в-[ lkobڌT5Cm$Iލ 4p|9.C hpA[`)Td>psU䜵`j=e ,3$@)/!ߨP^;ɇ:5*g 22MYg{"o C]TrV󉇾"}B4jl6JS>H\I̠p3)&#MסI7q?ɏ'z/2o<^b}:,z otp3du(8OkSj&W))<#lp]}ЇzB0Y{`m.ƈU ꌅD.rY@b. yyVH 3t#%Ar~َy@ã6F׊Hf,s3%.T+p E}*apʊU%Ao hP|rzǫW>Ͻ` oI#|AԔVim4r)8f03G: D],:fI״ Pwiuj.x'nVebFy =̀(<JL(->0:"|~E;w#!+=7 x7jř8WH@f]~90|>5@S>X^O|b0=[ B8?;-jJ>Kc%?HGI׺b2`J:/oDu{3+ *Bⰳ@(_> w6,rH볕*m%H Nh NOa`q3uIk ~!%АfsF-x&F }  2iF;.~YDK 0)浮حpOaU2ȷň & éd@g(oj]"ѝ'3^h1K[_9 >;hT/!F.* V`/o"lj%+:[45? ́Dt_6uZ  Ԣ!cZ!;NQ.GN҂; dh,!/ܧ% ƃle MnD:J(lpqj:?ϫ_"fj+yph,] l~]М@yGRe 9#.v ֖ZNJ6Li7 -&1dgJYkd3f;T\8#axq:uyLsS@ ;)< YxPf/zzd!f준)~q#Cy~oOeϊ7E-ԥ@fs1u~sc) 4Mt4Z^h$Kg *!a:Lc)|AV?/ByoNRW 5 D8(-GmZ#$6CYˁ6@:|Utel?ZEiv{pM A6(kPDU~P$59-.c2fwjxxT ȯ.X{ṳnKx'a73{ђ8hwpj e=߳d)dli /f0xd&P8Y;i{_ 򛭾G Z{9+jkҗ|M7:TϿN{ 8~*VL&JJ\C3}8ӽ&ED3PXG0O=7O 3qOδpڢ~3Lo, ugOxh%YXRzj(g wt=a-$Y""Mn{PK,i{ p'$S* 4(&g/ LEk,X_zw$[ެu_}ЬjJaⶲ6_e;nX{ RY|lIi0uO#T.gҐ,WꬋvyZ&6}wYnrr_8g!jLUSA`gtiyY0YLZʝJ5"¸V2 ZOMB=2TkOh LaRV&%|AD#,ͥuv墻$IZпG1 '—ڼ\[JCPkn| ^bR%2?p剂"Q]I8:^pzD-D{gtU԰*1ڛ@ahꨵȖZ?e+4)J0+!{C  ¸ǎ6ۂC#DR*e,jIY.fJ}=lgu1"#)ϮhT|8,2zhQz|b"t4oR+T1xȡ_bIȡpuC1zV=v1iC 2=)A``͡m "[eVOlj!/hTM-,\75]W7|g[I*8Nci"O92a7AA 3>}_ :f>P߯zG*F`6:>=²m>/*)(K ِdFƨ_j])q&VC#nwZWg;+"1@o/`U| \N+(bttH1rYO ~)X%$Z<]qNJ<% OulN$j ؗ{˥cM@(Hܫ/HdP5roZmEJ'Trv$`{Gv•KVXN=iL?>mp!$vz7JV2Z}ê;@/QPВIL넹!(BDbCi؁]x)<3-0ۯ8?fB5nήwXk0~IcE\IC>kT-r:Cqyh]Y'MfTZS (-f!ۋS*"F(BwK(rύ[sVJӁi7R= G+~- d(+¬jqV2݃+}Y{:qO8 d&g ҩne@0SFQu\KTh,ՌJII萇(JOʙ^[q)WZ2dWTSi+Hle(0䑵4J\YviMOpiʠ`/2r9f2^