web/lib/Zend/Service/WindowsAzure/Storage/TableEntityQuery.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/Zend/Service/WindowsAzure/Storage/TableEntityQuery.php	Fri Mar 11 15:05:35 2011 +0100
@@ -0,0 +1,350 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Service_WindowsAzure
+ * @subpackage Storage
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: TableEntityQuery.php 23167 2010-10-19 17:53:31Z mabe $
+ */
+
+/**
+ * @category   Zend
+ * @package    Zend_Service_WindowsAzure
+ * @subpackage Storage
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Service_WindowsAzure_Storage_TableEntityQuery
+{
+    /**
+     * From
+     * 
+     * @var string
+     */
+	protected $_from  = '';
+	
+	/**
+	 * Where
+	 * 
+	 * @var array
+	 */
+	protected $_where = array();
+	
+	/**
+	 * Order by
+	 * 
+	 * @var array
+	 */
+	protected $_orderBy = array();
+	
+	/**
+	 * Top
+	 * 
+	 * @var int
+	 */
+	protected $_top = null;
+	
+	/**
+	 * Partition key
+	 * 
+	 * @var string
+	 */
+	protected $_partitionKey = null;
+
+	/**
+	 * Row key
+	 * 
+	 * @var string
+	 */
+	protected $_rowKey = null;
+	
+	/**
+	 * Select clause
+	 * 
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function select()
+	{
+		return $this;
+	}
+	
+	/**
+	 * From clause
+	 * 
+	 * @param string $name Table name to select entities from
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function from($name)
+	{
+		$this->_from = $name;
+		return $this;
+	}
+	
+	/**
+	 * Specify partition key
+	 * 
+	 * @param string $value Partition key to query for
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function wherePartitionKey($value = null)
+	{
+	    $this->_partitionKey = $value;
+	    return $this;
+	}
+	
+	/**
+	 * Specify row key
+	 * 
+	 * @param string $value Row key to query for
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function whereRowKey($value = null)
+	{
+	    $this->_rowKey = $value;
+	    return $this;
+	}
+	
+	/**
+	 * Add where clause
+	 * 
+	 * @param string       $condition   Condition, can contain question mark(s) (?) for parameter insertion.
+	 * @param string|array $value       Value(s) to insert in question mark (?) parameters.
+	 * @param string       $cond        Condition for the clause (and/or/not)
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function where($condition, $value = null, $cond = '')
+	{
+	    $condition = $this->_replaceOperators($condition);
+	    
+	    if ($value !== null) {
+	        $condition = $this->_quoteInto($condition, $value);
+	    }
+	    
+		if (count($this->_where) == 0) {
+			$cond = '';
+		} else if ($cond !== '') {
+			$cond = ' ' . strtolower(trim($cond)) . ' ';
+		}
+		
+		$this->_where[] = $cond . $condition;
+		return $this;
+	}
+
+	/**
+	 * Add where clause with AND condition
+	 * 
+	 * @param string       $condition   Condition, can contain question mark(s) (?) for parameter insertion.
+	 * @param string|array $value       Value(s) to insert in question mark (?) parameters.
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function andWhere($condition, $value = null)
+	{
+		return $this->where($condition, $value, 'and');
+	}
+	
+	/**
+	 * Add where clause with OR condition
+	 * 
+	 * @param string       $condition   Condition, can contain question mark(s) (?) for parameter insertion.
+	 * @param string|array $value       Value(s) to insert in question mark (?) parameters.
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function orWhere($condition, $value = null)
+	{
+		return $this->where($condition, $value, 'or');
+	}
+	
+	/**
+	 * OrderBy clause
+	 * 
+	 * @param string $column    Column to sort by
+	 * @param string $direction Direction to sort (asc/desc)
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+	public function orderBy($column, $direction = 'asc')
+	{
+		$this->_orderBy[] = $column . ' ' . $direction;
+		return $this;
+	}
+    
+	/**
+	 * Top clause
+	 * 
+	 * @param int $top  Top to fetch
+	 * @return Zend_Service_WindowsAzure_Storage_TableEntityQuery
+	 */
+    public function top($top = null)
+    {
+        $this->_top  = (int)$top;
+        return $this;
+    }
+	
+    /**
+     * Assembles the query string
+     * 
+     * @param boolean $urlEncode Apply URL encoding to the query string
+     * @return string
+     */
+	public function assembleQueryString($urlEncode = false)
+	{
+		$query = array();
+		if (count($this->_where) != 0) {
+		    $filter = implode('', $this->_where);
+			$query[] = '$filter=' . ($urlEncode ? self::encodeQuery($filter) : $filter);
+		}
+		
+		if (count($this->_orderBy) != 0) {
+		    $orderBy = implode(',', $this->_orderBy);
+			$query[] = '$orderby=' . ($urlEncode ? self::encodeQuery($orderBy) : $orderBy);
+		}
+		
+		if ($this->_top !== null) {
+			$query[] = '$top=' . $this->_top;
+		}
+		
+		if (count($query) != 0) {
+			return '?' . implode('&', $query);
+		}
+		
+		return '';
+	}
+	
+	/**
+	 * Assemble from
+	 * 
+	 * @param boolean $includeParentheses Include parentheses? ()
+	 * @return string
+	 */
+	public function assembleFrom($includeParentheses = true)
+	{
+	    $identifier = '';
+	    if ($includeParentheses) {
+	        $identifier .= '(';
+	        
+	        if ($this->_partitionKey !== null) {
+	            $identifier .= 'PartitionKey=\'' . $this->_partitionKey . '\'';
+	        }
+	            
+	        if ($this->_partitionKey !== null && $this->_rowKey !== null) {
+	            $identifier .= ', ';
+	        }
+	            
+	        if ($this->_rowKey !== null) {
+	            $identifier .= 'RowKey=\'' . $this->_rowKey . '\'';
+	        }
+	            
+	        $identifier .= ')';
+	    }
+		return $this->_from . $identifier;
+	}
+	
+	/**
+	 * Assemble full query
+	 * 
+	 * @return string
+	 */
+	public function assembleQuery()
+	{
+		$assembledQuery = $this->assembleFrom();
+		
+		$queryString = $this->assembleQueryString();
+		if ($queryString !== '') {
+			$assembledQuery .= $queryString;
+		}
+		
+		return $assembledQuery;
+	}
+	
+	/**
+	 * Quotes a variable into a condition
+	 * 
+	 * @param string       $text   Condition, can contain question mark(s) (?) for parameter insertion.
+	 * @param string|array $value  Value(s) to insert in question mark (?) parameters.
+	 * @return string
+	 */
+	protected function _quoteInto($text, $value = null)
+	{
+		if (!is_array($value)) {
+	        $text = str_replace('?', '\'' . addslashes($value) . '\'', $text);
+	    } else {
+	        $i = 0;
+	        while(strpos($text, '?') !== false) {
+	            if (is_numeric($value[$i])) {
+	                $text = substr_replace($text, $value[$i++], strpos($text, '?'), 1);
+	            } else {
+	                $text = substr_replace($text, '\'' . addslashes($value[$i++]) . '\'', strpos($text, '?'), 1);
+	            }
+	        }
+	    }
+	    return $text;
+	}
+	
+	/**
+	 * Replace operators
+	 * 
+	 * @param string $text
+	 * @return string
+	 */
+	protected function _replaceOperators($text)
+	{
+	    $text = str_replace('==', 'eq',  $text);
+	    $text = str_replace('>',  'gt',  $text);
+	    $text = str_replace('<',  'lt',  $text);
+	    $text = str_replace('>=', 'ge',  $text);
+	    $text = str_replace('<=', 'le',  $text);
+	    $text = str_replace('!=', 'ne',  $text);
+	    
+	    $text = str_replace('&&', 'and', $text);
+	    $text = str_replace('||', 'or',  $text);
+	    $text = str_replace('!',  'not', $text);
+	    
+	    return $text;
+	}
+	
+	/**
+	 * urlencode a query
+	 * 
+	 * @param string $query Query to encode
+	 * @return string Encoded query
+	 */
+	public static function encodeQuery($query)
+	{
+		$query = str_replace('/', '%2F', $query);
+		$query = str_replace('?', '%3F', $query);
+		$query = str_replace(':', '%3A', $query);
+		$query = str_replace('@', '%40', $query);
+		$query = str_replace('&', '%26', $query);
+		$query = str_replace('=', '%3D', $query);
+		$query = str_replace('+', '%2B', $query);
+		$query = str_replace(',', '%2C', $query);
+		$query = str_replace('$', '%24', $query);
+		
+		
+		$query = str_replace(' ', '%20', $query);
+		
+		return $query;
+	}
+	
+	/**
+	 * __toString overload
+	 * 
+	 * @return string
+	 */
+	public function __toString()
+	{
+		return $this->assembleQuery();
+	}
+}
\ No newline at end of file
\mE00bUY !2C^w Uh`p47  (Ng^ʽ(WdV*W(w 5U 0` 440hzd&U`*T(D|GOx=e^aEy%9*!aP%,{| 0~u_ʬ/ )괐{A]jVK[}R,\E!!(j?>VSj~#h`CCr}FPe 5 0jUUeWSH|zr\yh8R\C(nCp7 ÍfeʫC>r20hhxèh`:1]hr]jfAUqVU֛#!- ; Q4K­W`YTʴچZ~>({Ca, EU~d>*)qY%=x<%_```X0d0d0wh> CъL6U7C!-O*UW#ʆCC`(| U]j*U]aʆCCv qީCsUd7* UlxT>O10hU*Tt*WPH4QC,dDjQU_Q{TK! ,}a!U}e_9c0d0d2*I=a``C` CC!MC=j+W e ;0V`?QXp“>xCCcD$\UpJ6fAU*J=X(",)ECB!jktCCP2 Cj"`[`q uWUEs ֪⪲VzJEUeUwYn/0<)UxC`X2$ʫVC~00ҫWeMOwJua) !_ Ƚa%_*r5D$>0` 0` 0zCCCP 0hh`HuJp*%Xw)-MUdFi )CU:`2(nrR1W nu2O8cUls FUteCPE(`ʇpw*pެ \Kƫ'?|2? %CCd?:&"`%LʲR`y*?U{7s=`_E!?eV C U~pE&ƨeVT2 >0b,%`V(22-CC!P5D U` (lE]aj2 40`2UqU0l`0``MUY CUVj`X0`ʫP:C!2Cd01)AXW ~cE2>h|0Ud)UFb- p8E40d7C!UCJ `Hʹx#d1U`ʬZaeU,C!`|y  eUpPsCb,UCʴeZUD?eT[ ?lhnchll|jUsUt : Á8jhhj",$(YCCd0lU. x 0`r`Z 쪧CPa` CCv꿼V_d#*ʼ 9u *Z@U?JuF 0`jd2ֽY Ed2%1V*Xī  dJL0e  C! j!h%4JF**ȫn%| !k-ׯɐr`kсޯ`h0p>* *qUw  /+t2jC2C2UxUwJWYJ  ZMa`48 ʬjU0p1#!l`t`l{CyFCtV*`2*- `x4&%7  e32H UVAr :nU^5^c`b.FCT61InhsAtǠ<ǐ`x 5^\%S."d<Ne[_!`)z zz{Jp x 0`zR{}X%`UmDCcCD-`V Rlhh!U`PUeU]C!v0`ᱱ 0` 0` 0` 0``eXFU`d02FU`/J!/tĦU{Jb%G~ǵ^>AUT*6Q:y7RVU` YA]!~ ͏ݖzzlq g5X0hi^ET:ׇeW5R-U],h{ UhhhhhhqUR%e$KR4Jl U aT*CCC!hheSP``ڕՄڪn48ʡbWIȺHC֫TrÁU#:ު}O `OW0_Uy :C6667"X40`J CT5"d2,d!UjC%j%.!-uZl À[CPwGh`lvlp9 G60h|A`tF FCp6;"lw(l`p40vG#UeW50: rAViW#;CCc6: ##Cw84<A:!8r6;60lr44; c^Rs 0`UnC!2ꬆ+!ڪU y5Uc*(gVV 668 Un*C`ªd@OUU]  ?}WJ!ʓa`X0+ PKzR|[1WS #C UZjTPd2 E,U  <yjZU?n`JzheVC$C"2CP 0` 0` 0` 0` U0ݐʭH2aVhh!:ÈjPT*FU FGX ڬ /,몿2Pr: G#xGa; 8U9AvÑr0p;íW2%L qP|\2d2/)>0`8sC%p80``/ |Q}_')>Mׁ3?o<0`0<_@e::@9Pv:HH UHR(UQ@P*H @*((PPP UJ ( PU@*BTP!!)Q QSah4h @4d4=Ci z@24hh@@ @8@2& ) <4e6̛B@4=M6SCe 0)HA4M6Si#5F=C@qƸ3U }rV`~n3k1Cnώ98;y+1Xh3(SJQ¨X), _Cv)0bOաɕakU5K2,Uc!aT ΊT;nC!_5 nPhuU~:+cUYɪ(*\H5|^fA)I"ނlȨeaI_-v7ftp"N9vs\2JL2eUs^_=-=~]Qh44e\w(N0J*MMA}->h\|=4񧷍={O/ CjުTbC35"=GF2j'H`PrD${bDǠ6=Cb_^޿巻~qQm+v}(kq=.DLB@DyFtTUri'Zbpr1Io[n<]}66ͮ}c=*VGx;<[_w=h=9VaP9c0 lD%lh~q;|U0{`9_`WQ]G#.X?8y\IeE& ]V/RHc_lV '2['k\J7S$Eܻ_Uy]C4? + CPjü7 0jCGp9?yxp6< CusAr9Qt"9=w6:ctGr8_}5 Cd9jR`Cpȕ X+{ 10PC;CP׹\P`!Xz42);440`d=cE: 7A`T8nÊ ~445!a5hd=!*sccpu07 4648CPԋp90t8#wu,CQvj(r6:ap8j0r0`r69""p2 !=F0`Ϋ``0h` T; aqU,0e(j6<ǐar7 C`=ay;!8*r-ô7Cd:ÈhWHsCyCo1;k-" ( gGe^sa 1k`WY@Ul*7UC5U­6UAj *+6hvU8UvUGSV[*ҮW )ʭ@ [W[U*ViV!¯Rw^=؉ 3w%tDR[U%hp<p:Cj8Ee Cd<F>Ca0qr?wEh`;UU⫚*0uChvX9E>ceYUl9 a0vv ?l6CX:9:pu<!=a`~ @CA|C`ÀaګCC;ǐ:<:GAchv;a`Ghr0~a}x(z ECz {r5 "Cp0l`CtAq+a?>d0{ǰ8Á0{ c>c44; c`0>#r40d8p0hd: q x`tC6?r=QA;8P0y C5 !h` C 1xC:è7Aw=FAp>-GAhuQxGơ :19v:a=x=;1:p:Aw5C0d80p;Fu{`{Glp0p0`5Fc`#U^clvCCxAJ|Gwc<1uPq`;bL;2%M\$8gAH Awc??T>ĤHJ%CZJX,5)6}㈵"2OR^jܤD2EXT0aT$Z):EJ`Y220f UU3d*4Œ%=kUU%*ȪD"y ʕeU`C^zG9YЪ>s*=S.֨OAX $9e:GxGd% PRIhVdx]GhizeffZ?yY;1{#tO+5fyj:k҇Z7֫W\8׏/ Cˏ+C-׍*ΡuPs:(Rf.Y%.^%0kc\cό?~,>+?8߬.XҖhv: Cm240b-1d=F?~a`4>Cqy4:##e]sWCar5 ` W\tpz@0`t 0 6rPA=t4px!=p!yv{C`UzUڝƇ?vX??hAG#}:14;Cqs #>cC7*2X4;FC|Gaq C0h`2c ttZ:h{xhv0yQD^ÁahwA0{Fp;lllz cPFC  Áh|FF"d41#qiqC`6;cF: Gqp0ll}C{ ; C8AccCt=F10yGqhp64< xcP`1`>0mc<â.Áуp2d=Gc9 Ád8CCPÁ;a{"}ǐ{ "|q{66666665Ur90` 0`UZU 0nZ9*G⫁ 輡u!}hwxrpr*V nWjUsUx!< 766㪿p:j Ud660`uV 0` 0` 0u40`|Fƪ65UGql`` 0`h`  |U_TEFBC`]A9\ %SAأjp* 0` 0` 0` 0` 0` 0` 9Ue_````````````{JqUҫccH?Um;EZ UjP7Uwllq u UZ U\U*jU_aeZ ث^8`d?!jeUx*Uف*ʻh8ff`ҫWM\VAVүJWWʬΫqS\*UV*)G__Hb,h`eXWWpeVU~avC}0` 0` >יJ{t^YC 2"`0`K!ކ 0`ψ~#`!``?uPC*~hsp80p?~.ꯕ`0` <ᡡ B): _H}TZJv{^>䧐U%;dV (aV;XaVUh182zeP/zRuEjOTx^Y^ۋE8*1VDj\G0d?'5[p9!Uv$ȷ _bC_~0U`2UX|F 0` Px 0` 0` l:ʬr{ð 0` 0`ۙU`ʬ2~B 2ʧx+t=d+C  +C Ĩo|{JL 9UN)E?bpU?st;sWq!d4*.H``UZCUnR]$_tX3QHE`Y !jyUmN*UPkQ>xE.z|arOQ 0uPaVPQQvՙ~7|.'K9ַk9f#&UÜX]qC#;Br9G5Z0 Dccch*"ju 47Cad5 0K!:H: ;Èn cccc=!;Pb!!8zT:Â^!5"UJ QP:d70` cc Cyřxח9n0t9Ey5 ;UyUp;+*WR;P !2]]Fw0x llpJb/awqvacxF %zpE Ccht.q40ld;6;luE` "àU- 64;C !u5{:F kZ y <{ Cpؼ*ܧp=a6;ү]YWZUlhlp; 60u8#ccp9p0p;1tacx"4=p=PAt ClzQGazhwQ;c:c!lua< E8cyz Nhffec33331Xx7C;^x0t x`V P9U<ҪjUd7 P0`(txդUi)Jx7 C<0z/*`hG29\ȕ8qP z,h`ʭ*YV)WJ YP?Ww{zC>eZR&*%`]j 0` 0`*ᤍQ/j +oYԓ*U}cccUZVǕhqU2Ea22Ub!U,^P!;,UEuEޕuRLUU;{  *u40h,CUUī*?U|ʪ449lwCv06;cc`CQsUc<1<ƇxlhvccChycVH vu*:W΢.r*,@U_"SϓǕZ2U:$t\R`TVC*1!YVR%9E>뛵%E C$]0`1K%U3: LUp>}eU4 Y C*C$_[YUlj*67CCCCC*CuVT5 *< (4֔ބ^UWx 2*~qCC 0`440` 0`CC 0`C*>*AKtDK>>/QA=r0`; *5C!Vy!.zCqK8U0k$`47U %`Tu C *CrmT;_xUp8p8  (s!n%dCR?w95bUh0d64~,\eVCZà0`?E CCW0qQY"ϠKJc] 2VCeϢ.^+VPP= 0y P\è0` ;CI<ʾC%yUWn"^\( R>0|d2`E!C`“PUQ,cZUUWE7d?0{ƐʪUHפZE=?=,`ʬ8 Uyl``):~ 0`(F .F Ch`!J2/h~K03,b,e:!PY`P:U`!ᔓ+w2C(e}wA0d0`҇`ʬU^huY X"02 Z]!P bWfbU¡1) jEYVV !cplpJ0d0p5CC˛*EUXC* WqW W?KW l7Uhp66466=.^:<z(ll` 0`CJ0eE`EEuIW_%}ߗ}>Wܨ1VjSTĦJHj2DS 0`b`zU)ulBJxjiI.QnE As tO*ʬW(~QHm0`Ɔ 441΅L`0e``0zn__ .$:P|.!UC!ƅ(05 puϘ5_uC̦ڬC84:iZ%ڡH`wðre5V`:ÁAxEև#b ! MT?=|;Czq~W B~dKC%zb,yqD?}U=CCY 22;V}-k7W-15QP9d2"eH󆆨tC "#68C>quT;Uv`eCC!eýWt_8!ڪ 8(>rOAW "- *UV 1 Y`f%Q̰nCrP|I ,I>`{CCJI ?7>C`򆡡PhaTU_ PVWAކX2K4>PȨH CHZ80nE^CcP+7p;Q+?T}jR>eH*v SWy)އPiVNCc8d2H d168 ðV"r92HU^l}u ̋]V|H8pz_H;F }IwĆ%2U%;⬤^8WC!ܩnA 0` 0` 0eV ".NVC!% xn &ɒUhuCu\ 0d8*!=Y Pje}c0nT?-い``W E*D/p~] hRXԒSiN*ʰrʩ"X=?_C*x`nwY =F_|'0e0?s+Q&Ĥ`ʆHC"Ljj Jh400CUV ʰUGt=j>,#!jUcP`d0`CUPI5 Ujj>xE 0`j93*C0d0d2Zd02E˵hll`ʫB>h{>0`R,pZ40d>0lqU,E!$?p*jC̫)U +aEXV!VP`& 0e P 2!b/t>|~7UjU"UϭVCC)CPu0}l:C]UTU}"CP`7UV lhnhll}!̺aҫ*: Á81+sU^\aڪE a `,W`]< 0`ʔEu"^ڋ C; T42%hd440`42Jx*ʲ.!d: qÈqUe{̕P; 0`hhvnffUf+,hkW{OvŖ Bj ,D Ce2* %`X20` XbC&hhh`ʬ ``` 0`j [8 UUh0J`X0jCq\ U]"ʬzQևꪻA E 됻P蕺^įk"j X0(}豖`°b_ 0`R/ Z}?/ ;CCc >C!/Uu=R!)¨R-UHu2sUs!lYn欤tJyG"_ C쪫9"U^tUC!C  !+jVC(d,ʬC!eV C!TeO,5 b-PHĦħܔ袺_!`ʉE޾l⻬wqW,V}|!ӇF#劺hd?w~Q!K*C=CTzC):C!2E<Ljt(i 2:M8q9">U08 u U Rlhvhs#w8z1xp8x sCZ!- FĦNd)N 3FY%)*"⬇45%d8c< 2U* `p5YUuT61Il`a9`CZ & %E?0 0`ҽ)0֡7ovs|o? <"seWqgG[AG+1V Y#lllnEV,0j%e d2PT2EiW5biVANʩVozu꭪v @<va:tuqW#! A`tF FClvE:Ph`Ur8+ʹڮ*WPhxul;@]*\F F84wCpW~ = *Vyʑ8%/pφ3%Y`UHCPʆEZCT2+Xުlnʬᱵ'lheuVUd4666lh-R,d4 \"͏aX7Ue0|Ǫqy8aʲ*Hz|* Php0lp5U[k0`CCP"4:{U9\\*߼`7p ΢Wԋ C>t;_8{_ f]}UWګ߽x/Z["`Y E̡Cv{]$_(<%^ .bItzPd240hd- 2R"sa+{zU`T9ll` 0`Zs 0dZ۫龜Uhp9JX9r48P[ %zCq+ 0dJU8`d0n^/TB"{xz%<]aW0xUY HC$_e E$_*G||@R }AB@*`e#y*UV ;*"_N 40UW0`*sz -MPy\C2?Eʅc0`蕖 2`ȕP<U"%`PTxX2 %`ė9EKu*_mP0P"4YU`K X0`_U*wOb0d<j c- sXx:CCU2U{{0` 0` 0` 0` 0`Y]5f 0`{ ڡ̋uXUZ CPYUjXj^+QX2R"VK:c(`sd!apn C649r;Famr;a98asUtU\ P\|u UbP[_9JO0`\ 0b,I}W2*p~w#(+$k>@K 0@ ͽV40( OOУ#GѠJMJz4h4A hj%Oѣ#F4h4@L12d41ODe H1"D$H`lS11<])I%Q\ ^H~~5iQ2ƪm$1--7۷;R>MeUT*J=$g;Njj:UDSdH)'ݕzq\VDq0ڜ^mnԷIâۇ#s\_꺓6) Cz[bۭ$ZHj^ker¦-QVڥfS C?5J[w1m/ꄽy]*ڜmF]ÝBMliuv7tQI hja5ějٜ }CJ֑Xkxi6^L.;>39]f2;[FDp,x 1 9%eɌba<]&Z78M Vfijoqmy9FoH8; sO-bz#[zm췱988J[fI5nVsIGS3U$g\.$x-zăA7Xbec؞ DͽSxG͐8BCADͥTs%= j Xid2dSadJW zq=OL;f+)&e0ͱ;J7G>./{Im{> y~-{Uh@КM4ll&Gؑ h#✌kv`r2"AWVL9^l5/~$12D=Xu#8i 55vI0:y)ԛ&5"L)Q:3$  M$d$.DE̦f$-{ғfx2pW O'S'k Uàh:1JqLq_]BCw|