summaryrefslogtreecommitdiffstats
path: root/ipsilon/admin/providers.py
blob: ba5e1e740e240c37abc2eba8828e7dc8c0d58d72 (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
#!/usr/bin/python
#
# Copyright (C) 2014  Simo Sorce <simo@redhat.com>
#
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import cherrypy
from ipsilon.util.page import Page
from ipsilon.providers.common import FACILITY
from ipsilon.admin.common import AdminPluginPage


class ProviderPlugins(Page):
    def __init__(self, site, parent):
        super(ProviderPlugins, self).__init__(site)
        self._master = parent
        self.title = 'Identity Providers'
        self.url = '%s/providers' % parent.url
        self.facility = FACILITY
        parent.add_subtree('providers', self)

        for plugin in self._site[FACILITY]['available']:
            cherrypy.log.error('Admin provider plugin: %s' % plugin)
            obj = self._site[FACILITY]['available'][plugin]
            page = AdminPluginPage(obj, self._site, self)
            if hasattr(obj, 'admin'):
                obj.admin.mount(page)
            self.add_subtree(plugin, page)

    def root_with_msg(self, message=None, message_type=None):
        plugins = self._site[FACILITY]
        enabled_plugins = []
        for item in plugins['available']:
            plugin = plugins['available'][item]
            if plugin.is_enabled:
                enabled_plugins.append(item)
        return self._template('admin/providers.html', title=self.title,
                              baseurl=self.url,
                              message=message,
                              message_type=message_type,
                              available=plugins['available'],
                              enabled=enabled_plugins,
                              menu=self._master.menu)

    def root(self, *args, **kwargs):
        return self.root_with_msg()

    def enable(self, plugin):
        msg = None
        plugins = self._site[FACILITY]
        if plugin not in plugins['available']:
            msg = "Unknown plugin %s" % plugin
            return self.root_with_msg(msg, "error")
        obj = plugins['available'][plugin]
        if not obj.is_enabled:
            obj.enable(self._site)
            msg = "Plugin %s enabled" % obj.name
        return self.root_with_msg(msg, "success")
    enable.exposed = True

    def disable(self, plugin):
        msg = None
        plugins = self._site[FACILITY]
        if plugin not in plugins['available']:
            msg = "Unknown plugin %s" % plugin
            return self.root_with_msg(msg, "error")
        obj = plugins['available'][plugin]
        if obj.is_enabled:
            obj.disable(self._site)
            msg = "Plugin %s disabled" % obj.name
        return self.root_with_msg(msg, "success")
    disable.exposed = True
|nmCS:h: jZ8:uYLa eʬDL^pX>s! ]hxc~IB, u\Nt1y7Wb@82vli?I,,QQ9fm7UyqU^-40G[ F ;1dVeNkJR^E݆KHF_?"ja=PI|;KaR9bIxfg:J %{ ik2d|l(^ ru%\lmF)L$w.vYL#Bb{۴b=oG==:t;)7αHę0+©]_pA;3e\5^^u|15{vH,q"α!p*S$PE0T_Ubg'cxDQYxQ eC?pk"]WDD1ăbbk?%TREN'lbHT!N;Y[V TA.7/5qH8xqw|@v}s/exЭ yă.mofF>VE}M}uU;8 U睸YR{sk=͇6:!YuW﷖]սb%>[˖]b8 j''w#=.d*-pd^ MI嶧fNJԀ"eRϞI#6b1GM\w+^5j"\BZ|,F~QtUc2+[K[!@>|KKTsb~AlK3H%+ ?!/ @<JSTkRIEw%ILϣDȠCc]LYJqdhEpJG kn@Hrm*\Uu>K.pӚy][ULR-r$W5 z\a܎Sߑe_ a$'T,V: QF[`J[ieskPCTyvEs)j m`YUOTbh#{~iQ5;8\$ w_wͼ@q&һ5W㚿% ώXBae& &fM!f;uwӐ`QZҨCڴ:"\93 3woԜ1;nU ƁJ0ߔXoO*Ƿ`,@k2/I#&-cV2)[4ɔ4x= }+EjGUFzW(-r ns̞an!R{JtP\y_Ƴu[EF]Dm=~ /OH\IPq̌:$5],]*Ma/daдbyBfe!Zw|Ps-.vr S2Qnsۄ%vAEw@{ҊS(fu wzY9DW#}a?2q0rpee~ҁջaTyrWE&Rf|-KYow2 g^YNm5%SCX#EΝBcam,KSM$旽z/tYOB:!+\\qV qEu]I#U{k]J1&:)RP/Bu)){ˀ/ÚHXv! g4Ӳ,C Tv\' f`J5ߓ>y"-49#ߗb&çwdX>,[\)Qowd{Fûz F zܸ6nzZݤ>7:uv\qcJlDA5,& 戝3ޫg:8lUZ8׮j2jn}{)x,ށʏ ,"YYP DVТCkez/jz!.ft 4%ce0(ˇsX$WvΎ5K<Ģ$!:Ua 06? ?R7@xZ ]>hi>ȅC?4j\vu'vYbDl*hFm _q-iϡqL skW4\}]\HY>{(@TcCL=,.6Mt?+UD]7df9wȵI~]>Q?o-9ASR\cSk0:><0Nܺ[&5hLËi Ml6##cf XVo-]  a {\$U}˄x)\fy|^TA=9姎wM*ñ,CSSqJ%}T::l9$`;*->swrܿG6nwL3; lѣ6k.1 E$ D(=p3`]5,E@pYm^zkqjOf3Д&ĆG;@'䐰d|ӑeWc/7BCBŶns}L 2:Tݾ" +diA`6s8=fRTuՂFnlbL2rpbf$XVi!1oH C3-@w! !4Yq[eNenY_oX^R)w+r:ᶞ~SZ5_f&bqϏ*¼^QBJY fAu42)#>,i|"WzHN} sxSm^cH뱥wfFPRGʢ&%!{P㭊J2xpfpJ3T8Ѩňln~J0'@Kŧ]X,emV **VZI3l|Fk+ $%Qcͬ=rs x0?2UOasM꛶GEaf+ l_9xFmacH0P_~D^Kv7lw1s]DK"ٲ 0d4 ==nܰ:;m *(m|m?LO+̗>fR1F 8R0%t]nb>sHI1mɔWFkAn Z@ }0N8黭T\~.nS^)M]_X pS嶹LG3+4BTW2UM<$54˲H6`n{!r]u[aE7U lJ;^c^~RK}g]vFkѧۏۥɷ#LH' WɺPO8}k$BqWwT\e]pv,n#J,Q3_=HBWHs 70ǯk?JXK #̎ 'QnJLh$sI׶ʥzVT6VW0,U ~44bD3^DBPbzi#z4=ZA+O*@;/+rcA_{-D'N/2tr~-D)^YQn} ݳQcoi5Vi]zwXJCffկy9T x yakWq9ZA^1 L-#=F 4XAR87O] aIJL2]_죷"dn`a֙1T 8. tԽ$U$xx>>rm@~p`?OrrՊb0:uPW#bon 7PTt%#~]Z7{os%p/&m*j 6= ÅWSW˕;z)#;Ń24Ʒpbڟnu;0u3on2m6k0V$r{JU4#O__D:YȘu'Ci<B .r% "w=u&&yb,[I ڣk |n[ sh mƙǯ +]Y ?X}uN82'B4!B_^umF{’$0Cn ̓l{DwdL!ZLsjf6_UM](Bp'n`e;}F`Fv|/LVlV V_>N{<@.R/41a|$ cIWP).V\o9]3ݬ{*x]b?y|!w8aLi6StFU3hbvJ2 I:E C˗NIӕiC]{Rիdm?Ædͪ 2SQ& }l8 ?trXN6E:]ݔ:J5DᩓH/+8#;|)T)J JJgTgLM '4.j:i&@@y ܨΨuJ/(iZ-4 p"z"=^wɀ` 4<ɚ๥%|%#rM_^m Q_aފhOo"M I({3{u<8r㎯*|0UjW`$Q-֑H["]HGdH{^ R#9j24UlI +Ii&S<ϿXt\9C7:x$wY{Y2sU8tOVd_|A;FK8l_`sVa_R ڳ?O8.^L KZBYSf6 qj!eJ8Gn$4̭Wx`?\^Fq)H8!Q-FոKU.sBr WۚDAXr=pR*L|m nPn;:^]e .,ݚva3v~ڸ&;`C-H޵ck{rU΅'0\ޤhPGp[݈Sj QjQ- 4!kM(tړI ^JSs)FOV^ݟ&fs|q/iKyy'/t(MN{,0jK "v&H%N0)YjQ|$^B4JP:RZ z %Gtk1 xiWm2qt=Ie ` xCӊAwÅu0R\G:O(V.ŧo@lA P%Dvl1IGbȱvp?jŰpȠ 7 RRHC<;.[S5{dK,VhG$U ^698qP/`"#bL G>w"~i:Nu~cZI8?"@䅿sʘ`o4hE3.(š &5^~Y | &N_YDLcv….ҩ{t/hM!z;3{m&Q Q4f1Nɖ@ӖW(mPrc}Z V|fr& EOgP7I+ ,ϓJ*A~<0Ǐ|}pm aɇbv)9 ?"G7l 5GP")9A6tp(bin\l# GÕT/kxzO/\/ Kgs4'N.q#MGEL797_E?HUMS72)pbdJTI+ m߁ }>_SckvPכ%-9L|k{yδNck:|3qއ {]y ^!VQJUv$UtefcqeI>6Wne= 74]lV}?$^1sBp%7X5iaa5Cdڂ$gB^4>.dwT162 3X@M7X rqv.gJ 2p_K*N >ǁT^D+=^ΔRHF)!8r1 c-BYȂ%V;@// G(rK]L$S.oɨE'>wdIa}<;I7? c٦Mc$;HnrX*(,,)bӀڸ%|hf~Ɏ?1Dl̎OjOpUC-H`c1&,W8S씃[t\ ؊8=m@)>VlRUƮ~m9=nw)#0q[C)d38 -*ɇ 9?y+Jwd{0ypyvFkXby9~ y O!?%,4k?iiM =TɁv@$?`ck"mFx1aC65yua61FU+9qڒ%^$DB.q&1mD;S3C%L:~ڿ DVO(W{;eFM2SzAң9O86w-^.0 F" : >oykӒ2_Vm ">;҈ x=5F3@WJSWlem=Eˉ'=CR%Rl?$&D|g$Q[z[ cP"ԙHDo_"{.Q@SmTRFO%@w±G4@"==M:?|>hPАnGc_/ xg#}T @M̠)(  .L kvGΣoJ@F۶sv]墋VsX [Ϣ_BSAΏB%φW$~XZ[~(sQ;xm,ހI3Hjd5g@'pT(ǮX@\( 9 s B$)'<:gc$@q eװ@Hc?SV^K§I'' OL܉TPtr~C1"(@1Kʅ*!j/p=U=d|VJMkFc |K.l/3$Y0В`; lS[%eSzp-R$?D(Uiln.H,M6L+1):7%J-* :>ƒz0ֳIrXf RAdW+0E`8 3n2 me鴎WBM/fg`8,VT~>|V4I{ HbQ9,ܟ?pC\O\!K u% s{_.2=RfsFpBƍMi߿ ޾ijBAP/͂u@qbl;a{tDhKǶ3#)}"JW6 ́tCYMǫ/X5Qf0OxgR~SNb 4{C^ּ1.Yœ,UoZkORGR#D9u(_249ȼܚP\2 ~RzE40.5ZOur >(~< <=RՁgz>rwuxC \ؾUh:XM#.,y^o1a$Sg?Kaq "+oh205 }b&)[k<ֳ#T*؋$ E)=Ȕ.*:җeރfK(4aYʙHR0awT_iq?:=!f8K\U(ˏcRMj4F1(Kv=}@xjxy# >oaσiAVC7kصGra|:l ЙiOM^%܉`z9Gu:ѽ*Ce/*>i?3^{f.Fup* ̰R@Tz/$>L}=/26eSwW0ljaXYVqk+澥`lF};&MQV[lɿ.d,)!aXu&ȨZ25DKX'/Ȱ+xKɗ/f\Zgc9C2bL&5p0SCvӕ:X$-Ay,HںSŬZNoopԙ; !z΃s=eTIL-~}Fo3yF%T>5r-TAq%JR ;/V9VS,U+)=V)Mwdd8:ZjLrg%Rژѽ au üS+yFEฎ+(,ī4%w yb6qj+Ρ_FuI7φ n ?blo_ )Ѽ:0f{AQiݨU hKa>%{!=g5 1=cSIu0f#T1[ VQD~[6i)Ϝ%ɏwFm;]62A,L?Ý&<l͊?%eWx[L;{_ࠒ_'ReMF(/֎-F<5lo~}hG%={\uS8U@W{WБ12{zZzكF`ppksNotnACĻv0jr͞J d='^FJ9xl[;qa^73Q[Kkm!EH`;|ecɨfߩM}Cx0xxqlҽ# |q)}\e{;Td՞ vbHI%P8#XOaID}Q؎CkF߰} 0UMa7<' D{ s,MRwDUyA4><5iX'<]u i p8D{JiWb mh5"zbcaJb2ŀ2ce(o&GG0ǔwݥ_{5 bdVE쟡٭~u{Qn4Ҹ/𶑁] r%~V5!Yj>HS(|0}bzd̹XI1Ck )_$1E^3 ]#gb`m0̓;-RLÛQVkΎת!֎of`Ry2MMpՍoVô]=*_{F9*~pNSt!oN4` p] ۆu  Y`/ T\ RM\Xh~4[3WlɚlڡaT4{Z/֎!5E" πBWBICkRk& 1L@f`QܧGy 8@V$'OLY մ?x*B_Yͣޡr4 X+D|uB^XߥQ=PfHOxl !L\Iasj6 /0myj~vO/o(Xa%jÕП.wLzf- ?EHNQ1pM0Ii;q8!QD&Gn 6⸝qFr-@{ۻQ3 e͉zWD@&l0{>s;Gޗ_ l/ōp|{1ZU& 6Q^LEƯQ934Sr.Gro` CN-1Jw\<Q #kn.=(w3Y nju(glNk"3z \.Ku߶86vX_Xv3mM 3kKw-yNٶC,N Rgk;3VBr*8*g>ho6c@-x@꬏PKDB^].ܗڵ&v}mj (PO(^fԐl~{s@AyqeA}[ئ0Z׸ȟ䔬15Z2)-.-*h-y!A6my!\]TlHݼsb[OBJ}ZGe\_ e=fX,Je" /DjRfQ*Oj*r+A%VREc5Ia2Wς\+$-2[AqWM.q;* 1=#r{FD`iWuoiX{~SdZ8eӝ#ĜXxuouzR+^WkkL_#XOhnQ &D;|y@L)~9+s*P?ӈہB*NGAbjǥߗ&* Xl]A+(Hosz8`g?8 %|p{* ȋ_MX—(Rj!QXkOmw[ ݍ;!;Ж5q*kp,\^wTMX<SÝcW?z"|n*ab:T=BO^!]΅+j\$Tˇm>2cIx<|RK~\SBq)/ hՙx)_/ z3NV>woL5L1!vuɭƕ\/&@IĻ1#~GIBNE|@ˆ!)hէՐC! C1vnOPnr-Z]ZcˤE,A|AEo*-ԅyY6p_͉Stl,Խfj@rspc@ɀk$M\+hW2A;]is={F"P{boHa5{s^&+AaR j!aH&dg,# @x_|wl7^g4{Ӆd%WryA8uځzdu`0dcΎHؑiN:ـm}n0ֆӒ2Ϛ5+/HF8ȸ,J!:<.mNrV\. nEfq+M*AF+ t7%ח&:s$OvDV*Cwưk9&-G6k ~2!'g&\$P10. Fǒ#,0T-mZ5İk*<ھ#6`q6O玷 j [k ޻0$;'FWc ofA^c@=m|A֬zy=zdNɷmcŽi*f:Pw]5$;_~ЮN) =S^?W>{p=MoH{+b67ed)H\`6YA;jȟo[{HTcBn j{/}ǭLw/+B%p+3ruHk4}qKG5"`# _oE;7ʶzoVneu2GEc44Teԩ4l&: )A4llfyBh2> zz&n5۸Vp\DD1;4\uC֖‘heAP+lUԬ"%  'E@_0?r3Z\ѥ_ "r86^m;8r{m#Ղ|rgBWi,H"?3 ktH@>Z|n-G /%=w/]B1|0FkKBK4'L&^bD~ݷB<ݶ crÏr՗NK@Djg+OY9GA3Ug /˶kZЉ¶a:tW CI.N*!(;8v{1*FzVbNtPR;gSu '"MJ#g~2f'3УLCjjr"I>Uk[ܽ,#"I|+fC^Xf _G=XAh;iGs ݰ7L(?z:NX9}vzC3e)QxQGG <$I f:U쿝zz:^O'Wj|& u$ fBOv)2'4d9N%)P [rb.;K;BBԢpݕ&,ݖ sՌNX!%~fP,ҚqoD9A%x=&9\v;~ilP&;[ d5x =8py+ "_G ITFIDo!) Ob+$|f Eq ݌7x[Dٴs 8O8xgiB)X5S5E܀BtX8֒N}nufV(:)2"5;]&j;8 e˵[[Z2QReUri\QLƩNsfP)R)5X ¶i!eeb}D0u;&KY],uhX0۵{-ineλ@Wal8J'S}U;ˠwh*lV_y#sT׈lr;kyņG1(o{ DmPjlWVІS7}dL < ڃ0d@U2Ců\qȏ])G}mKL#YH,QHF{~7XdGM=Q0B.C2mT@v*.#)YJ! xZh;4ͯPDaRfL[JW\d#*$py@ Q*ckf38g{ $]x}uƍ)3h}:wcVYa`ziv"|X&0)/I^m`g5u_yuG2_j̊}= $vwk#?Izmhkܣ.ӌ2icɌVLGy+$B_2ӃxUB8UfgWbkmf BkD8ER nfpo ]vBӥ:6%Okx=O`Gjgo w @*&f.O58}e϶fdd$Tn'ړԽ5CLf|qœ )zP]`n*X=B[V@wQ8t$N*#3Q}2,)^UCZ}HXJvjv طk"ó"(< ,%sڽtBQEAIZ ?Zt.|#Q ^zOe@ėÄ M=Pk~ 43{G?:Az.K5nl,EݚI< L0PhBȂRN]tlڟ+yy}Wd x QU!\7s8.ЄLQ=٫p}v?K4MP ̣,Bcw܁G}V)ujPHzڰv@.$CGnę-ǎ%c;s&jcS2XIO0J |-S Dt]` xl)C0ʍFV e,KX[#?EAg;f-?i~SӴ@7ܧъWO=5E` 2Ho^ S@)DdO$ιHM/q5 SBD(͔QR֤EocйT٤Rg;ƣG/a#/s|Dˆ6̹3},x3xߒA{79D ^ᔄJg8s\VI{#&n͒e{SG揆DuYr%9z@;{ +PywɈ5:gCxr<?{蠍.D% % 5^J('Ąh @S!*9P08֖(m-njEx H?`/܌TKS8gn gfH b*rG<Ghc2v3XiQɑ'#0T^2)QgNL?VV(;niS>0CM_WYONIx3:1y]nQti6Ea|/{Ru;[Af=6ւ?N?^-H4 zu@X{ɶ/]Jt!tRDe.@8dxWMa/XMs2Fhfe{; +sj6xw1 ?٫?z:Q+}<vEE[-j{bX* ?&XGeL z|wMjՂ.Գf*[?e55z'Nnvdiq47Kjj=e?j_A+46 S;0!Ճ"iwIjl %`B 6u;Lf90-K3.- jA3oO8\)R;mK0x<d R"=ĦrT #bӕ>T#oe8`- lL(_Qn]ЃJD kP}oHj٩:)mw5èl f$A}Gw2 C_J~#y؎Kx$Ϊ]ʭ7%͸63iokJ@*%8Έk=ivXg~QރsIEǶ!Bޑ$S^\$Btdf%E3[Ai>%`GC o[9CL `c:/Q{hA]oB毦 9*Zfxϛڇٗ-o`jz=q&q! 2 I;qMgUK=Q1 l@|i>@yBr !Ǹ @Ha+~=jNjO}(YD` 2j: zqwtQA,; ŌwjbrQNJBmK3Φg8aDb{9Nߏ?W7CGK(Is-ء&1sR;D=x=D)l1b$EL]@w*2[珗-!RB_\zIGE1~{!h3UbG)$p{]H.Fm`+_E]R*y"\$1:. Z0䈟7~:n'dJ_/IBD*us5qJ3%-lra{Be{`Es^ۉ@o#$7ũ56 =ڪd+jPm(~z] Q贑l=i+I(OMN,G"ޛVLvNSO' uobQ6QY73Ro*R7؍Bv32n,SZUʱ%،ךcO"FґR-x_/˅3Ϳx+l۽H{4_TusYqE"uҫ(1444O猂*A(}>'-(Ԉ`Z9PdijzyҲ=.O`:Td.;@[Qh*^~i lamEŊ^b_ލ,b`uj5dImdDZ8_ZTF0߼dz~kIV59ct !q\ɿòzt9ά?l]N!'c$bٮ2@ #{*:O\*z8Yڨ`i_!:s.WQ(%g98@JK%׭!<j:2/K|B |0JF%&#KΎ+2f[{`(ۨb?(.sY?@V7NУ06v,dfxh㛉Ǟw!4=Lo ;^a{4 )!S'3vOog< w`lVUyb G{,eyfJYxJL0R@H/R`<5AB3zWs#ꉚL~6ml/x7~!yD\o6r<"%!24g7)D( fa'[fBl$2Kgˢx-U3S[w^=Η<'iIҍ!7b7S(|<̩9BpBH~C*?!̜ȢNc1<$1 _F%V+Hp3a]K|Xto5ME8ih$RO0V^)w(Nv ^I[q0iQIUHai\{y MJ~$}{˅j@u]]uߠ(ji!w@<ȓn.JJ⻵jh=yvTFƪJG"_)h?͑V1>c9f_ n[&)Z{;)uU 5+g^Nu*yF9rAR]1ٱ~Eg C:&P / ;0:AޞYT$=t#S3\4|~=) x#G+( :@اow _p}" g7X Rr]HR8`TģXɏ[`Ū@21ӮG@VO$_]€G_BՂGp/ Tm)& ARklNe G՞^dA%3U i!RzWĞ\muYp[u{4+Ti1=LϿKGJm3,'_ 7mFlL>[Ɣ?O~cÒzNGcuC .t!ކBı&N!jI-kShnհ gVc 4pʡ^Q7 R{ϝcAj¢[!)8e_iZhtn6&lKp"SԬ(2яy[õ 3T hׯWL,| lNJR-!(R\y9vj$L<Fd [z9Kv<]Ro[8R ߬I=b]{-hAULFT}4~/36zUhIOAѢy+lqܦ0b[G"Np4u4vj|e0Hᅳ{Q`XXfN'7E|s aae3d$dktᣯr0kX%?$Z+чgM`q k@`]Հ)~ר*cϭ2'sKHm7;Ɩ1@,1]p¾ђa{T"W "?PaB#2YdRcBmr:u@JqKz^0-|jq97 Z1{ ~ѣ$Y3"o&0cG^7ұeR !u#nVW; 3oy!*=(ϨC&_q= vsD7qٓKY*Q@̙ nӻ㶶r`3ews&g8 'jq&c~\P>MZLh`R1U9m DZJ4'p}^.cE{#|hժT(V |-@M<@b^8z{#[>ImAȐ˼dH7 rex;-7rօ֢fV j-= tnWEєR8rf H(9^SQMc7YkDݓ)Kgr֎$2k|G #:"j]bFN7$B拵0 BHX.bMu,Q谕mg3/`Bc^+P֬$7k8@r!m!ᒜ%}ỺRLmА4[pPܑVڊJTNŒ}8#J؋\&> pV%Bpw Gtأy[wѡ S{,Q"8~%߆]_<+odz5#qЂ ̏HbNN&\5"tcD+;nɲHV~7W@634F"4'bpR%M!k-7~KZ!CHxIWq#<D3WrH"Å_"-U˱&.vBo=s3G!؉L=鑺71(čxmM`zc)54# r/}?PXӏȯn.M#R! mfUtMlld6e4sp7ʤ#RʡWNE]ިš*T.}?ۊ \dz)BBP8m.}wBא2 p-&o]9w`j#WooybJFS 2B 3Z>GW AJ<?Թp cho}D\v ۡe?"}[Pko|3Y{/o79I-&R@13gq)<!Ǻ.0#(ni ^o:"Tg Fk=.v}#_8\c$1,C XyiM|bBV+?l>%ZN0yзeДS5V,S3y> ۅ4:j^$1:xV5E #V.xS3jNiFkZ]{GQU:*vfer5΍bVIpk#K^᧦S" Cdb:Wu`;q0Jm:I.ۗ u)zNP ;ZJwS r҆SfF(sz1o=r9|U鵹G2q ;Sify|Da?ڌ֑KBmVVv,=#ݦ\ A&D]<>+R?;ڂv"–b~g#$X*;8np99jH_YEϱs_*|(DsM 됑%ΜSQnTE6+2VM4 ]95dbZ/ TW6 #R(^"b 6;ZϽuؚ7Ys@VƻWAr/v:6Nh3S3<d{H=eFւ5 *f> v7=Hֶd *NwH@lΦNs ^2˦VBF|l'Gm8{#i<ؘN KƪRj,>6O7mD.*D+|+_GGk^OH#Jx'{m3*)N0{r;nBVα r!i1*[i~cJpoe,씝_iɖfM~P1_"X_ŽYR'Y /1kds@ CPqB8zD2&{Pey[cVyuɨC8nP+9=Ԁ#D5:op5Z =y& O/ ~l;s  HiKe8ey []PqHSWd݋=Jܶg`Nɖh x 6<(c/E`$чDj +᳐}.6ފ[O?$xvcIe {&|Ù3lޮ+js0&18m/GZD %7E JeehoC;%1gOȊ1bS-A //ZoTowߋɄR〃^/s7B6wҎNG |dLsh]3(8GeQg4|йpߢcTbE0 )6a9ym0V譬J8̂2kEd?J6_Z?ٰELp*ǁ xe[6°zWi995R5GP뒄qQF$]v ܩȁ>N3~'?]KPXR8#!}؈K[Xc!|`Fh{[)9oا[eRjjRWNa\}oť(@HTX$q;s?aimAި,D|T%|T ԋo}2` QO_{D>UAB榦Wpk;tGY V브]DX.7YqِS:O~I0yAa{V'/Bt82b-!pwMkǕi]T&z`*R$/ i>`tXS;]^<]v ݌@2b緂] Ng('a W}~+` ZQNJ(p*.M\3Z~߉W"}G`= 5BZMxD@~Ǹ."6uzޏ U?rjQ9T Z^Hۭש+NI,ߺB߁ b>u 74#:jEqaD9NlGF6cR$>b$5/2Rc$c_9v}Ґk8OZ=S2\d`x$3I yFCgIfr e.1)3dϟUb*ll9)a^hG7` K& , *y"75µ@#PvXeo &gN?~s~Yڻ/=̉& ]@&rwǢy[ɺH_QnQTg#ѵDU L CbbLJ@Bc"Fĵ PA3_n2`h7{ӫcuK-gJbGw(\1,Z/w%!gCjtSG `XsJog~`*16R8<# }[yEyQpHL\k;L!_lC=KQ*^L3R*Rx[ĚiJݯvFLkU0I]~{FND{‰(ٳa3 <=zF҈]ѦH;BO9l=IR1 ژz 7C5F3aBYSgӿJoF]c~߸^G|hua~p[U ǓSQݓݻMd{%Aaj=vKT@ vdyƼ]-]k$.GK~-l[2;tA1I'w>;3ig|<k䵰U5½p'Hf/B?w! a|8MDR!`QL wVR1q&cy3u]h??Ȩf/Q(lep- 4nυ(œTڟuɓsxd<.[C$R(eAH0r2ܦY7hwcO85YvdD?U0g͂ʃȤǐdܹ/b"y7%*[" )zqy ?w+{bXKC$~1!݈V ^:>Ƅ\m Ty,lȣLaljifL^@ЎU"W܁^k{y5Vy-ގ[meML-mޯ8}4٧P/Rيr2K',QsGlikeazj Cod1 ~X_ƌϱM7Z` Ve!Ogmjڭmximc4,&IxvE.w$\{01Y}NFߢ'[JԿ,iq·Q`=)4A%  ߘA饯>X_>h+ lX)!qe K˩>JCs'x @~ Cd򹟱L^kmY@+iR}[ݨA%!y%K>ekcPgJeBD:F_swWMB">7‚jl@XdFܽ*B65A{Ӌ)Թ^j1b%&hJ@;J\dv<4#rͺbB/|Ain #m$^J*{%3uc~+jivE)QŘv|Uu*EVzC Bz^kg-\@Y2^TXܺă2T Lsx?ѵƶ/Ow}AnC4+)OPzuxl-@nCoʊCZ-UۮE%J*SĦQ ve_h.`ġTkK>x cOlf0W U"D΄{yl&Rld􋐫g LcZMIujfcgz[/PByV" r Z?ED bDl }8Y;rtXOs`񂬌c}ŒK|109S$7וxJ\Jk泊fA: ks_A@/14Qڊ rg"၇ Qn6n{R[|7llc|ci$hZ&(w$SExRS%OCl_frC I1JD5O-uT5wYha;-EmSNσM'^?5!uH؝Ҭj_shz>36VȘ@!n]+zuBەT<$vM#|& L-==G_K@%L$t7^ b'DKLSmkgi Qh2.;\ ;OEКdPzmMIr 7* ,r!%@9i-;>%p lU}=ˎ7Seح;'tRaMn ]Wtd6da>hDMQ:H? hn*gZ[YļPzabӏ_CnRYu%d5( @0EӼ<5s_ԋ@To Ƌz#鍋^-Ose:d]x1/dR`=/aWTt,&) a;`D(:PIoO:Y'sea|/Ug@%q 7@!TO9Q^˚`X9wKWDqP!>LEFO :.oY~E6SFfMa%PGC.vb$c5N6 S| eF3tAC sb#mLC)(4n*|_ !*~,lcm(fϬ::TXpU p/u΀p>r ѻe5gb#/\CqMOga 5͑ӎ[7L~"!`WV',&/`Fte-S(C%CwW!Ρ%%FA%)2X9/7tM<UKALAѯ]d#MC #od\Z4uQ#h6,MWkb[wؚ^m?:[fB5t$?HR6*[raMwnъzIN^h2\w޴{8Cpܔ~ iʰKkhH\ť"UC8^9ld9 $S/nj{i"PX_HDj}=D%ôͭ㯄zmi*`BJlrH SP LaOP4RAQ5wFl:)|t87]uD+VtY83֍Iɜ5go>ilvF qp2W4Y[84dö uMs%DU[hSԬ(cmm;ϵaภ9k̙;R+ΒV md<Cp߳o. ۗ^pU%ܠc=o#=rеc-3|kdo$`3SBrƘEW1졢W;g Ǡ' xTѫ=2OB4BȃC>.2Y,ts/ 52ol!yN׶m pnNH+Akv_.g} pFi}f]0oBDPI-x遵lR1+CqR|Bv{C"><,.e_W _p}N5%0"?w͈nKf."J|&wߜף#b85,C v|ZTu,d/vgԒsuɬ@Fhj)^kӛ1^K6Ӏr}]Q13Ac.@/d\P\eKЅI2F=-a3C^V9 3`\m΂$ ?湿xlû0ܔ1Jfȕ,լvD$PW0ޟ0r2@J~0.EUCiwWfn3/JJ⪝8.=.]fL]v:_P*%.W fؠQV]6%{}h֑u>+1IUXgӼ=~N8zr.S-*(5yQW`s[m,ReMͦNoH_oyf5I(!sR RSqJAK]Z8`lXHN% βAfMW:^[RvWoجHLV/Utpl/NЦ@z+c Dh,i^WrO6k*k6>cY4ࣂeVa_o5L&wI]bg 8s/Mr,LԞ:XYl@Dɴԫ8JB|5Ǔ*'*,GQ݁W׵%x)8>6~4.I'wNFws