summaryrefslogtreecommitdiffstats
path: root/ipsilon/providers/saml2/auth.py
blob: 036ed5e9e9264348abdae3dcae171dba0ba0ee9c (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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#!/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/>.

from ipsilon.providers.common import ProviderPageBase, ProviderException
from ipsilon.providers.saml2.provider import ServiceProvider
from ipsilon.providers.saml2.provider import InvalidProviderId
from ipsilon.providers.saml2.provider import NameIdNotAllowed
from ipsilon.util.user import UserSession
import cherrypy
import datetime
import lasso


class AuthenticationError(ProviderException):

    def __init__(self, message, code):
        super(AuthenticationError, self).__init__(message)
        self.code = code
        self._debug('%s [%s]' % (message, code))


class InvalidRequest(ProviderException):

    def __init__(self, message):
        super(InvalidRequest, self).__init__(message)
        self._debug(message)


class UnknownProvider(ProviderException):

    def __init__(self, message):
        super(UnknownProvider, self).__init__(message)
        self._debug(message)


class AuthenticateRequest(ProviderPageBase):

    def __init__(self, *args, **kwargs):
        super(AuthenticateRequest, self).__init__(*args, **kwargs)
        self.STAGE_INIT = 0
        self.STAGE_AUTH = 1
        self.stage = self.STAGE_INIT

    def auth(self, login):
        try:
            self.saml2checks(login)
        except AuthenticationError, e:
            self.saml2error(login, e.code, e.message)
        return self.reply(login)

    def _parse_request(self, message):

        login = self.cfg.idp.get_login_handler()

        try:
            login.processAuthnRequestMsg(message)
        except (lasso.ProfileInvalidMsgError,
                lasso.ProfileMissingIssuerError), e:

            msg = 'Malformed Request %r [%r]' % (e, message)
            raise InvalidRequest(msg)

        except (lasso.ProfileInvalidProtocolprofileError,
                lasso.DsError), e:

            msg = 'Invalid SAML Request: %r (%r [%r])' % (login.request,
                                                          e, message)
            raise InvalidRequest(msg)

        except (lasso.ServerProviderNotFoundError,
                lasso.ProfileUnknownProviderError), e:

            msg = 'Invalid SP [%s] (%r [%r])' % (login.remoteProviderId,
                                                 e, message)
            raise UnknownProvider(msg)

        self._debug('SP %s requested authentication' % login.remoteProviderId)

        return login

    def saml2login(self, request):

        if not request:
            raise cherrypy.HTTPError(400,
                                     'SAML request token missing or empty')

        try:
            login = self._parse_request(request)
        except InvalidRequest, e:
            self._debug(str(e))
            raise cherrypy.HTTPError(400, 'Invalid SAML request token')
        except UnknownProvider, e:
            self._debug(str(e))
            raise cherrypy.HTTPError(400, 'Unknown Service Provider')
        except Exception, e:  # pylint: disable=broad-except
            self._debug(str(e))
            raise cherrypy.HTTPError(500)

        return login

    def saml2checks(self, login):

        session = UserSession()
        user = session.get_user()
        if user.is_anonymous:
            if self.stage < self.STAGE_AUTH:
                session.save_data('saml2', 'stage', self.STAGE_AUTH)
                session.save_data('saml2', 'Request', login.dump())
                session.save_data('login', 'Return',
                                  '%s/saml2/SSO/Continue' % self.basepath)
                raise cherrypy.HTTPRedirect('%s/login' % self.basepath)
            else:
                raise AuthenticationError(
                    "Unknown user", lasso.SAML2_STATUS_CODE_AUTHN_FAILED)

        self._audit("Logged in user: %s [%s]" % (user.name, user.fullname))

        # TODO: check if this is the first time this user access this SP
        # If required by user prefs, ask user for consent once and then
        # record it
        consent = True

        # TODO: check destination

        try:
            provider = ServiceProvider(self.cfg, login.remoteProviderId)
            nameidfmt = provider.get_valid_nameid(login.request.nameIdPolicy)
        except NameIdNotAllowed, e:
            raise AuthenticationError(
                str(e), lasso.SAML2_STATUS_CODE_INVALID_NAME_ID_POLICY)
        except InvalidProviderId, e:
            raise AuthenticationError(
                str(e), lasso.SAML2_STATUS_CODE_AUTHN_FAILED)

        # TODO: check login.request.forceAuthn

        login.validateRequestMsg(not user.is_anonymous, consent)

        authtime = datetime.datetime.utcnow()
        skew = datetime.timedelta(0, 60)
        authtime_notbefore = authtime - skew
        authtime_notafter = authtime + skew

        us = UserSession()
        user = us.get_user()

        # TODO: get authentication type fnd name format from session
        # need to save which login manager authenticated and map it to a
        # saml2 authentication context
        authn_context = lasso.SAML2_AUTHN_CONTEXT_UNSPECIFIED

        timeformat = '%Y-%m-%dT%H:%M:%SZ'
        login.buildAssertion(authn_context,
                             authtime.strftime(timeformat),
                             None,
                             authtime_notbefore.strftime(timeformat),
                             authtime_notafter.strftime(timeformat))

        nameid = None
        if nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT:
            # TODO map to something else ?
            nameid = provider.normalize_username(user.name)
        elif nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT:
            # TODO map to something else ?
            nameid = provider.normalize_username(user.name)
        elif nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_KERBEROS:
            nameid = us.get_data('user', 'krb_principal_name')
        elif nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_EMAIL:
            nameid = us.get_user().email
            if not nameid:
                nameid = '%s@%s' % (user.name, self.cfg.default_email_domain)

        if nameid:
            login.assertion.subject.nameId.format = nameidfmt
            login.assertion.subject.nameId.content = nameid
        else:
            raise AuthenticationError("Unavailable Name ID type",
                                      lasso.SAML2_STATUS_CODE_AUTHN_FAILED)

        # TODO: add user attributes as policy requires from 'usersession'

    def saml2error(self, login, code, message):
        status = lasso.Samlp2Status()
        status.statusCode = lasso.Samlp2StatusCode()
        status.statusCode.value = lasso.SAML2_STATUS_CODE_RESPONDER
        status.statusCode.statusCode = lasso.Samlp2StatusCode()
        status.statusCode.statusCode.value = code
        login.response.status = status

    def reply(self, login):
        if login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_ART:
            # TODO
            raise cherrypy.HTTPError(501)
        elif login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_POST:
            login.buildAuthnResponseMsg()
            self._debug('POSTing back to SP [%s]' % (login.msgUrl))
            context = {
                "title": 'Redirecting back to the web application',
                "action": login.msgUrl,
                "fields": [
                    [lasso.SAML2_FIELD_RESPONSE, login.msgBody],
                    [lasso.SAML2_FIELD_RELAYSTATE, login.msgRelayState],
                ],
                "submit": 'Return to application',
            }
            # pylint: disable=star-args
            return self._template('saml2/post_response.html', **context)

        else:
            raise cherrypy.HTTPError(500)
щ&c:d=֡S?uR+e.ɿO,&WCш\XE9V-{t'20ELy'd>v.pY~%/4"d;7B0laFGaUߎ_a;e[ ,P},v˾.{Uio bDW.0gJ<88>Z-D|{FN5!-d2W+F)h< fbٝDjIxiCwbf#%t=Z_ɐ"U: 3ݯZĚuH ->{ E# :7KP[~y[T LE㝦Qr>ll< XVL{78D$M/m=n(}H=OКq6zw>*M>pD~V1es8I1fE!Dc0j;1NH/;`7&Bh vG'm\v}-rr+qCG8b/>]=vGI~V S[^'-"{DFgH/ vsYrNl,lf$NBul)TXGx^չ+0__'K幂kMJ/[2< !`^eWdJ`Lهq[-C7͏we- pIG( Y d DY& !@%bsފz/ , K]"lBZ`LFE3 UNSKuplF|pQ#,`HK'$>԰z0˛}{?%ј@da$hM0:vR{cK \^ay/#6cT +a pP{݊ _zSb{ּhL(l(u+.]ާy=Bg/J?kq6 .6Qf&".K& fU";U! `}{@yTL}6 gFW)o2$bga&qO aG|.ciՔпjV=9Yؾx0,ī nwcC1dI ۩ 5?dbmK;OY-6& {/(s}[YV#Ā}dd+сZU,#Sg}{j! %nɾڠ{3"psUXkatw2'j!PL. ٛ+y w|NKY+s^ IXbC"R-$Ur=/*D";v.I6?Ri>y 0@㒔ӘX6 BR3%mhNmE?E^G9BOxxE 8u~$0\"Yxf<56>Q0C/TY{߷DJC o!Tx. o8Jx:t(շ0.tIR $} (9G f ێ;CsףY-w7z;oTG!q7TWiC"䌈~s3 QXZG#_}glRt&Zb+mSnHFAUJ-"K9ʖL+L ("kj\{E]rL3;6(fs1)EOYC>anAt$O(Q1v&`u@k dmwbpKbj&/AI%TN!d)Hb<ǧ5z[4S*T '1 i9!D\)< P"lmƎ# @Ae{E,SkV-" >MMSjVOO ywZA_|썶lvwm?,o-F \XG\_*/!xA@\l=.'ړc-Rh6/L]ҚrGdhJ+=gXeekQ^ڻ^=勧+$#+0[Pg%FKl;"<]xz;RE`w}0C$vLF";~#HVX`AWPbN.LhmwѰԵgwyBH/(V#:01J/JZ&c̵6!ؾOmJѐFR)?$1(QRJ%3, T%RBv;5$l q. NۢtY^ )gf=pXWKԄ.~S[?vOwar7r-YD鐚32ƕ`WWD܋bv͹Vmv0^ũXWqhJ(X"_$KOQca dXM|$ _l bi8x$/ ļ:p IL:cpMsF^m?Q&=՛5?4}PrGŎmQ,380͝~K5,2xsWe05j5>#y%Z@}{fe>d DڶY51{mWۡ|-8f % fo+dl vjY'}[FY";ڦ'i!R<M&p2WG_.yc(mȗf#"b遵E^$f帉h{؊qw2m*巹f,}s_@/׻K5vhLDȡm?372$|d$'wJ%VUN F->Gq M2Xu,((&6&ݖFsE^y'aJ&hżW&j,CPjAБGW/Ō&a]dN-A/185;u֖f^!*0HY)8%L4mAuJ؄Cq,Rӏ{}:-&D&2[.}ߏ5_2r~1Ƒ#ꦈzvuAj;s^rakA;DرUiǽfaN%!MS&J^/@Sp#@/ʍ\3Or3q5C[ jTO Efs,*s]!oq싚]*B$,)98!mz\Ź BAx)A$ɳ%2ϲ0ǰ98'xVKʰ8&T,0^ܑRVF>@P0_' ;4tM$$Bdp9lL"XԌ\"5ۄ NPR\WyV?\Rs iQde%h d騲>X<:q7t{^-p̏ꟸjnͣ7g /vAmͣ0 ٫81~j:w NV v =6f.u9I8zFSw(&Sɔ*O g%=*{ˏaQx;y0Mvup_Q2F#Ѿn)7$ؗe{Qnb^%mŸlјQpX_2/娧Rp.("wf)z""O﹘X憱úa 53x,*ؤ*#k/vc^-Q=vⴗDs4{b9mx Ym G'k"ث뾦or, f omO̱1 #{ñlks8RnyI批3TC=y^ґ#niycf ,)>dU84[c`@,I2mk |)) 'G=ԊqƗDk#s>5 D/et*fr`҈H*,pA"tk*LVNP&fw\7 Rq6W nxM";Q/i&GdrKѳ(XdVɚ(BV[.+@o)F6G&/'ûa܎;+7KMmޮ]._%ذ ;QʮٶXs ||X*uimh1] :v(&5 S }v !G`݁>hYAC+{<.{aշ-mjP8 =Ypx/1/5 eqfT o W~[( %!`nAQN$9E 4g'zEpǬpMv<@> iطeܝ Pk̔M7 p6"u6Fks h^fR$2;dR\fqaܑ|~NȑK.˗.~Vffݭ8uνThʧNiB 8):oN_֧< ~~|䴝?#ׄ`!\T!.Z --۷"p| NŞx?/~ -' kM s 3S̈J|Z*VB@L/>/2 n͌enxQpnM.>oom50 3u%0530rO^ؾ MAȂBȳ-_ R XO fKS^M\$E \w<ɝ $5B+dԟc}ܻ1!ڑ0K_fR$nTL~ZWk$h | EB޶{mŖlb ^Gbo@rsv(2U&ޙd?'$Q\hr2PQew쬳lז/( 1ߟsv-J)"=0.m|a.>XPf;i*KAEF+;-%쩝Wuy"r{-JERRA0Y4er n3-kf;ܫ@=e B':{ /L Sr#mj2$UURJE]?B'q r2Nfĥ?)8PŞ9RY/:]HC/o6nƻ? ?կ[+0Y\ ]ĊшUjc5J>OLvLqXy7Pxk<>d,λmíK~RTC܆— e#!s&?^IJ SUf$ OiYdXSBS5nD B GC\;U_IYE6iE/^  ⟆y%<+ň K]$\Ҷؾ=rwRu( C$ɆLA8ӗ9GvHLYEFYйj07nO(tӧ(@6+ EN5\E;7KtGM* AmOnO %%H1\c=&qo @r|!*n?XgNy>8#rtii0[}֊،>>YO%9-~G>~qT7Qͱrʆ-tiys!q5{v? #,[ͫ g s~ȏ8-IpBesJX5a5K`Ү›azq}?ajtejf!JVdo /$S/+ ' `Ðqݝ:@ v/LdvsFuJuC}zJƄ ioٽG YR&jX9C ^vbC!jŋ:3l2avA'x=jE-p(?a77ήIƯ&aNn B/{^~'V/o8STӥo 9Q*FX#K5uwdoiq;׳ N.{s$Xbg~+O~m"M7K\Z'9kI=4y~Opc*C癋ǫFӰ)4ÞJD:1&kI&l8VI%vMZ Ń1Jz@톱zc(^Ē"oK͇cEofmϨ; ~Ts T"6\sgO݆.* iWvYXF~D4dŗ-U4\Zw/lP>V,hjL8COW\4J~I7Ƽxx r'>%}]yspD D0H|Αc'}8Ej3"$$LK{÷s\Pb/&_qNnbQ#}S}h8%IѼyz91oU">t43Azl9txXۇ7mLMNN!cz?&r!@/:̈˜ܮCLgw +6(|T:0OS먙;gؽg5-4T3f2 䩝C^T<_$Uç_zW7cTgI+T2غ_7W a] k}H RzX^wR?.A. (֭[TNTO_?Ц%G =L 4 rV=d";fL* fJW){{pv|Nb@>2cG e{7R#Wr*I[;GA'Cps'½ FpL,k; m?ܻ#+)t{B[̏,eHUPPRe(cv{qz3'@x\DPq\D־Am&-_a%ݠQ`ɜP۸J3\*0 z97j jQl غwz<\l  H6-9p ,Y\)>Pv^q߅+f\eӅzF-b'g1k ko虃6:U3K46 nZ1|]nDjJY<%@N#5\= \|+d$@Aݔ2$E lgP)araߍHcL7AUֿx6(a a#]/@/7z%ZX_ |HLhj4^ ֢${dDwμ_QwauX /ùʗS{ܠC]CޱrC8OAC|?~_^D}%Y*^LdĶ| ^?ۘr#/mK0;JXk[;?i咮\Ckp}7ѡ1/XӋS) z8d:~7|Ά5nQ}2U--c] lo{=r G$P=G%f P v;ݥ%/w`&`.ᓈj6хm{9!m/-v>HWujcu*t2,1CWӱŔCiNkC"% m|0݃ķzbV/.(Ư5bQ tkt!5 TTxU-xK̒񰱟d@aU#f4t~iͺr!{4Xs]~C|4,&G,ʫB#7B x4ɑGk$zMPtl9;obK>|Jݹ!=d*3\L{Pyp+q&|1-fGod!K%.aIއvEAL㥄{?4lBDufЯ؟ tb vF0%gG]p̍Ģ o1nm|$Y?ro"TVҎ ~gExzؙ YGnA{CZ=KDq(ZبuyO! }HLXϞWƫ-iZ7kӖx0ur`*ҳr?"-.+Vnw\)\׻m5MNP6%jnRЁHjZwV/-56x8@ 1ϒPk@4LrfoBk*!?ޯyïij~HkTw !? ưdcDP#PI;dXV_B\M;>XřLWd@yPc1DlE2".3?؜l_釸bE(-/c>F.O*UnCBH}~wqUM2 hZǘ%qUI=.r|Yhv KV/^ CQ]5t1g8b`1VL6ia4JehN]}}A{"Fي}ճIEe@(wnX%KYLyZ@ rh伦|0X7[ y ms\3|"lic.Φ!HC䟊+˭8-mMSg豆7 =t` #"h`hVQK3U莅BXAiZ^v&sRdҮ%+m  1EYUezKF!6 nB3 괨IDm~91DԴ0죘m  RIZ'6ž(O݌<@Tv\}%J-8'PL"Cʏޠ<ɱS(CF*4_p*$qx?徴S&{mhb<12o6G#% Cw8:F#P?$X¯1LWa]h}i] KT/x35KhP9|F6[8p_cU7bk:s@Yģмrɴj6c_pY+Yi[* d101Pv5V|5q3rb- ^R ҠD]UAe>&\'n>2ӿ1@Ǚ 5 Zzsա{Q8E "FJ{r׈DEɤ5J^F4?9.l{ﷵG"^(",SC[hrɥoedcX%*)Ua5VÝ?:[1{(m$-Ȳ2Wŏˎin˪ ߍƬ,u¹pdi#qdJH$\mn)0ɚEEVZfEQoG[』|u~ӄ[ w2zD`_`R>ʲcP QգL4 l]a\}&CVL(RAهܠSM†*"l}oSDmaNKqxԥ𘏺͏{^`Og6JGm+aK7 1']W3|ߜp0X&^^71} +0!T* M\ZN@/\\Rk֝%F!:< } iX]%q(GkD|eJԧ2qxJa.xۘE&stsEC2XP77!û]co&U2h+$0 U`L#_鑞qZ\OBVc5^lx{b~9 ЧI@>hTdrgsWiQ 5i"[set=^@s:NXm E-`fٴ Q5q2oYWSR|˒2@JȀ]wȎ:6~od/Se%uHC/goXZz7j`-yqh`7GP]l>~Lb4:5uB,kN4<  j[Gٗhs~'@hVt21]OF>^ -gKIkq]zP^QӅ+(P8aI $2GCt-V bt{xЧ^Hϡxc|$&M{=gk I*r}KDBgXOi%aD' EPur+-Qiخy!{T?Eh{ho2D#Y0Մ:ei3Lօ=םl~k~o Mv}"'vRhNy3Qj TPs"tɌN&`6R(|c݌;x4‹0J`7 <L8\f> գ:Ѭ[0ЏjC/3ixy|!\HQ`?j=N}2 \OFo/^c64kVgA P"g\9%M^Q)-@~!GY*6zb?3Y9B3 g۱?,#o8WF/Ԋ~(._I q<`4haW_)]q%!<]+EH0 *)ޒ _YzKR:3E +*)eklhԘMRa?YqeHDi<rߝ2=TF'Gߙ^};D6툛`Y?t$HZDm Q$c#[#TIE  8:z/B转vlWR#~Nahbٵ 8~s<>NCuc!`8h?#ɱ}ە,A/MuX(s]-Nz@ZiF ^aƖmLg+G=n#32Z}0拠y>> M≑%:n 䄥N+Bv(jT*~o)&hW1_0mfTpmVn ʌrG<"~5.ttIE_$Dn ⌈;H49wQMtkds 7RѮ |FҙHfCs+f I1,e9)s䞮C=إ,H!>:7C ~~oaA&_Zh!gB\J Wk;879Y P-\B 0R^g N23 7MSyb^5"4d.dw$t6vNX =YuEt;PqF#UY _Y{` Z <f]]Wh|"5oG v 5n5 jѣl $=0_@/+mYͫ'eU2 %*¥ @jZoEBN?r_vpe0d̆\oM3acf6arxŠF 蝳O]2 ѥ,H?b𐵊S ": "7`]#0}\9a9&$tf-9i)L<}فm#~ WTk~/ 3C!eWߴpE/IsgR>> (Q3ܫ\a:*LCRٲfG ?TTYh]3ROR{WRr-<lqfrC}?ѯh9h++-#ں3<֛u-, DsҦn8.BuaՕ;ŸX1 R'hs!ST|Fʫo3b0h^759r2j!m^ʘK˰SΠٟW)A'IA5+#"=\Q(6/KT)%_iuz8qg1cq!ACz{6!Ie?9!3ʀb?k7KEn[mmVKjj.Ik׃Tz\;.qenYm$&xv l\h37&[oC" rzq~X:*b-F7]S ѹKS sN =?D-3 #)јuE4L,̾(ڬ D:cR9AG&EKFѾ\UE*K UZ9m-AlKkĞjCϬV[Qz(nڱ */[*|)R^-VSDac".QRaqĔɃ6"AyQ4\t"퀢UJC5"WIa">I3cjz\wəI4*⒢ZJ[Qo`nۇjې(δjF=uN@Vf <"a:LP]̓aXi#yb3M-!{nR~gx~}r" 5i h'NCeYSgTև AqvRL\ };4sˢhHu+~G9Pk ϔ|*xn<7qAi֣"X=6< >^\Lr-6MNPD+r`ֹmJn;.ж(pځ%6uZ@JIJ2۔6tW,PguݙNhW2Ns>И &{);pC<Ż>~VrM!$İUz%W? o S!ym}S`,w,ǑIrB25+1 /?8D)c2@$D/^tJn$тs%Z8ߚ.+ԐyXQ )+W+~@l$ <]Э^xyh0F>lE]QTI2t00~?q\ 8ba#`:-G#]Ҽ!K\6IY\rM= vN%KiQ +nDk1|ZapnC.]㹭3hϣ$}IVg~ 泔=PJow0[1:\U&Z7SWl?E~uT% VL8Majq~22mgo22ʘP[+אq]B<-BZtԓ\v~1M\r0)k#_LdK_.Ty\ d{ y^#N>*Y6&Jn}MohKVPO8a* p^912_n)ֶm=C j \˴1)-:GQ%$>%Bb+ 2%vw poѸmo*2fA: q2?U?(?ΏڅЦt]ltfkF+GJڣOd%-&c?/4i^-Skq}.M w6S{̷K55ҳn7-5rKJrtїFGrKcxz^G}C2w.Ӌ a N%eIdן6V@v}D5].,C+iG55|AnR=k*챏蛧,L?M6v3 wM7-5l+\Hǹj0 f>Jb#~.Gkђ*?8v4TV.!{~;quhpM^ϵzMHDgs,!n!&ȸTBd[Ϙ^ c]vȉSFz}Aδ9fcp s% g$}e)J@aOg-d2)479Ln}1b&|JHYWNFN;ۈ:Hj4q:$6 bYy}VmNdJ6 >o0LV2O<T;XdV5ڡeʷL~d.r%:+IŰI~eڕft}d̻Z|y4Tj\ ]FϐW,B $ߛ'4OįgmbO%'$'ruLJO͂LTCs k2 tC!Bbf3QDDmmp^ҏ^FK}gR$ Qro7Hd!2>ux;ı-4uٵe(Ȟ_뀯u-C~e&P6oj}?rHPbF%E$Zm@INs3j{I%%Q}Mq>Zg^]iU]Rflg E#B#c6& 1qyJF |z\78GMHj #Y=ox2Ta_먊LPd؄mFiCG V*{J*K]Ni8&[(B9`!-Rz24un̉bN$ЙnAd (wT9Θ]/}2j$WU0Zз(+&f~-|j0nNJ.pR̀e⫄06f Qyg`:hz: $pBo'@6!bqf7xw:4]͡G/;aX7!zᬻ8 ,4lwc, +dMPg.V%w*dN|u֠> ʱebr siXhBPDѶ&\!ۥuL yN ]& ƈHv^jtg]L۸.<2cu p5#f+ vE[Iu~2o~6qAbFUy0;(Cd뙩d*8 [CGoF6 Yuii <IRG #Do_Q L=0Y#rBY!|D Kgx?!ۊn|˒p@-';ӆHAi%Ou.s2n2d M7ecց4m (:) Qz6ҁЃwea>NȩGC:Z(=1(9.4,VθŒgՕ!_rMOQ;R7㕒Y^H𯇐wM2Px(Ph^05f#tئy>_g @zhWK7WM  (ŐXU]˝F:jXqSrغ2F:n|3Z&$X ^Be9&co>̄ԒJ ug#kN :0"m[hXU/F[T:yHOcD ncb?7q m4TZ뙶1wO!USklEg grHUT4W3a8wqgp,(L{4ZARyB,VLYZmnpB7zՑg1@N*7)YBSPp4iN3]i%&(gZ˘c1[`\4/A7A4?`mRlKf9TAj/v}-pHh7/ )$szaUyLpD^{KZ7X^6lh;edVe`+{9iqNA`mFz\ T٢_.uabCc)cAd4'"֏/)KAƁ[4V .[`]" ]7c1YGR) UYx{8ž -}pWDX0zx.-k١Ͼ) #v1G]uu:^"3%hj{S|E?gt̛  (x^b8a*j≄:rŒJ<0PZ+zčלap7>b;9QdasS#z>a0Ans]bkzjGVf,[9UO#!qdo'΃#+__'P=hVc/G G񕺆V_I${5{#0.&y=y=`b{-NER% z9t Fp#>%E9jZ|_[:7c3"bRhTHYE4hJk:# wkV4%&-Xd쓝GcYw5%>W_6+ޠ8S]=wm~D#č34D᫇?U|uT\MohZ,5<׸fV#ϒd?) VX^|yn{hZU@.[k!y\iJ_< ;T9m(aw꼨PphIe>Sx:佬O[@^z)Aa|P%GƠC<Sk 7}BȲ7$3b86"NB|R ysh #5,PxN^Qݨ8- ko^׶᥺>Y2(8,{n^E xpy3yL1R$eġS\,oSg+Pho]( >ntk aX% bEbq@eKdžRl/o'iP:kwf ɄϨFJ7.BvW|A!eCLw@'9 >Xt+IcO<kDg(E /=r1xoV]S~ԡ}YT3yzs1oN 9Jy 2d?9}V2 j8p6%2ԋLoi}4e-SAڂRٴg n?;A.1$uQFbIUPطq#lQ|wk&u5g ?&g/hedav˳ټߩ|dP4TIHr8,̓ ;g:Hfpf#Nԗ?_ C`0 0Uo'2lEx  O-L1,I[v'EQzKܿ.+ҁ)ԾfE!-U-fr0/nlK_a U128k̟;ӗsgw>ܮEDL|GFqW|dY{ޫ`kߓڪSq?#X>G:nA7{#펽zm~@T̮&^ 3aK$Fh4yP?'I~#-Pb]kKΊ$ Ü9u>۬v~5{^Gd8ۤ $ '=5,Wջܘc@M|D"J pb;)P.4S RK5I){|E-qQ1S7iO  5!Y_ny=TO?86m#"$p{2=E"yQHpe_4pwy(|C- P8 xjRue/k2p '/5,k#+UC /Pͨxfz/O@`ﶬ1'bk"kyK&[#kW6UN:Py N[0)Bc+0u$|ȊZW q{y0H^ݟ4G,+,տKnwZp똌zr.ra-QyİRvJmFRYetpowCifHܴ/}u~V!LL 5m3гە3˹QqvHBd EFܫ@l^ go}8MSAj5nS#+񒘊ᐿ^|bÒꨓЭG̈́6>3=J}B3I[e45"h =CG_ǥ-Ҧ 1K1P_:JE2_G*(gÉ[,HS$Y_Lx$UvM-ZѠfmݹ$Z:{gA4,C5, LTspg6OY^>hY.ZnN\%joPXjiorWcD_RqoPfpwJ;qjMgDuw' h`|\ T9 P@jWu(lSRX*] МIqZ0x9ё=w9M#I[fB1=zd{ irRvrZb}˹%7](Z]s c|~Y=&c `H{);!ϼNH~ao˝orf\Zň' RM+=Tu/{Еg%Mv٥=q(#oN.S :7Lۃd/̣JaU?‹ .]"Bt7f;ja1I9jN: N`;8i8S9Ħ~K(hd ' .RdRi?HtrQ#oy;4L䯣P!}u;bOχZ(N]m 'pRC]l APTGbkJnmU7@%&z]iO˱N&|hFOARHܻN@2ۂd\0A T Rt2X|Vs-r}Rg8H[ @/DZo<<qq`EE=JC<>]?޳|:)зJHN[o]dt'Rf>K&D \M e t$Vgev6:Z͖8C3% t;,'2|ϫߪ<$Në|\8⿥Q7sUinai9h)9wů6xrxOd1Vc1'Jʚ%p,O"'SF&]KϞ6%)w}n:j.`Xp=GSk=V+t3h_ ߁}7z~ӧtY#* kB9ac?udk;uS) g) !!$@t<2{p'_Rr x:}&*X,(}(,1TεФIy1 @*О"ɫ"0Pm%-Sh)ڌW܌EP ?ߗߟE=hXgvSbE%=zmR 5wf#BpE!Z@2EAlKdm1ԮgVTkLDi2Vt}GpNg3D=yFW4 Ox .To +Mmzƅů-. sηBz,} 4T=dr{oCcnyV;|.$R9 H$ Y* ȞAiz4GJyH7[":2Dכ'(uG{L^)Z񋲉3[)GU "ĥshQO"9L@&a)mʥ,gSo3_@FNN[VfϡF;f|,+~y nP\809vZ$o}şk@ϗWy:2\z;B0¿qM!k~n1t;6 y|FDaxqiVhHwըڈ:5IzZҤPl%Jfa\@ :E=sk;fP71f@cw< cN=k;5tmys8ҙ`gERN9G"@h :t@xϗQpU 7*Zgk_O|6?h?9˄CDWmp!hWg7UɹA\s K2ԫUBGagHD `a"BD<7PC5t$7#r ŅUg$I$\n~إ .!)%2b8ӓvdT{˰w d1`&S ˶}_1A-iMA;A9q ySdkd>nXnJ o>HWϣ^E2"0f˶1CsxHٗ!bb=ggϦbwLJCp6!6~ˀSNTjaJBG˥xg|`Y$)55xEN;-锿`&*I/))4T'(,+|$3ԫ--f6-0>P3wi:#ϱGR*3 T)Qx^[HR`0|jyq6OFWCW#+xmir肴Rࠫ~9 ༑JU[2f~3ܓf' CM`cMԦBC; Q[e͇l}uX{5'N.b-Ryć[53t= 0q0@H bv/B-%9[ꤣ%s`\:e[+p<6Zk``jDpeI=_qzQAMkhU;k)XX9Q ϴQ밞h&ŤV Muhax7O#i#+O q[}.j Tsk"'םy1}iH֪mTu 1Bwأt H$6O?:'wZi#Ҥ1vS5ɯҕ0^xEJh@M 1+5ni(hseB22?P.0Ay<}p7HFƟla RxG@Aj$څ+i/Z%(RSvT?#cOȠt nhJ G٨8LyC5jJɹ$nz"W}9q, EЩ_>et]؀wㇸ#WH_Ir+" jޢ5F:J2?*/ZmQj֧dvd0?CX'H|u8]rh.-wf |[mdWǿF֍d#2XDvKM*[x(%L-2]VW"b9Cr)/X[)'(mq~F)M$NRM6k9((_eYr$BjgX)>hD#4$< GQDG)ɐe#7@ ,'Bx-˚O*dH$CG}Y$Gn[ .Uib֭|b{dX;[YՐ̱8c}.1馫jc(iweK&BJ2ߜaUtȤH0r(lkTfϓA~wygw:Vmc,Zۖ ѥB7c7i PlD"m)sYH0Ʈ3d9Yݕxs (Gس3X`7DR7A M(C>3VQ!`C8ZoD>Kw]p|#Ou~yb2^j;@{JiZ2(甞К {1)?|Bs"1 ,m%Հx;SZ{a~ڳ{ۍ >#ح aAkb9sO4\ǣxMZMhPr} .oހ|OMQD:qfLKu$Y ׊8*>t;gRF a\Q(MZJ3r(lU_¬Z{ժO<3DSܰOl "RwxIzHgԟ(UmT6q[miϙe9ml HIڐ2C̽'TrkcO҅ nn1c5+M<0g@xBrH.2f.m5Qzm#gGV)cαX5DȆvoſA޺JhXXb*!^EylB@ݚ nQʧ6#mϥP`F$(v^=FՄ㥚us6yNopL Np=C%;mXVpUF> ٔ$(ϊ $sF|tHwGp AuShQk㍻MG}W$)qp]i~Jpk r{a~{\KoڒceEEVwld6'ZI>gs[B-=%_;ȍÀLTjd::p {MXx}3L{9"3rQN8>imOqS˴Nz.6/dW+ܷ+1dܑՈ߮-ŶR25vsX~K%?HZ*IdVU[&4x>͆P8"dm6-靺]c JDgal_@zL, ׻ 3NnxEr%viB,6B(X]vS+ W [-X[3FtV@;ډg(X(an I\̤Z.o0I !&~~mf ZcLDBm31DEFE$l^ŝL1PS&FU NEZ 8:1Od+s:i U ܞ%w?n%> ;u/%nk+5 G,5ـrkv| 9oUWN/'n_ǕDX8V]6}XR1w$d`K24>'E|нl~P(?CcM}Ț 1y w X<G/yN(˕=0HqRr42e~:bp1}9's *[h'D^3:7Ti%ж֮/#!Re,.A+̶\X ;(VU'2D{Zw3UHД] [YJDZ,[rg =s|= LIr0kc YL )[$ /))#qHQ͔ni47q%2Sl$)qv}X""Vi,Xм[ٛT,luǂt~䓼PRf6.át0̫T%H |%8ON}B\m;˟C;xFŻD=+ ۖ >$2NؔVQrzI2 tEBT@bN30s *T<4Z -nX@{&8HȷlvմZ jG{6 %\S{=Ha*mL/k\]-W[Զ޾ K# ^ ].5jpu3)9B @ı#ẗ́:_\c1e=?jOr7f6bg.j"1FO3DdOoik_xW<`vrq^[dmX8Ӄ0:v7wa0@&dl7M%$gzӢPż'%3$m\ /V/n)'57߾lЂm +&ga7![:xa!L#*2V6'7}j5=5{bEe^Bw@iȌ3*^3̱c6qutPR{Z6+!g+G7Yt—XkG6 _)Ӟ[ >qRrBn>1ڸء",x}\M1?䶔v녶:i6yf-%3\_C‘Tk핆 cxzzFӰ3L7Ҧog?` 7$ ?`L|)#$e}pR R,%OqFRɑָYb_ `5`C̉VHiQ$1t o(/^Dqj_,TMICP7+R֛ަ q@Sxո%TLgI(^'_򪓗9A K}ymo5(]rd=-DG\h0;@jkM|ßZlQɵ~.J:nG,V[*5N}IjxLzz{tL1W:~"=`~!hY{+*8ⱋOIlp~K:r7ږ/:NUifz !Y٢~$jJ̭%F1Ȑ y1n*zW?iM $ӣU)ضE6((7؆,5>vuh&a'vO 8]Usˢ!ÔPhϏ[%u1[T]4 mVRWKw;E7]0;$+ 0{wnQT}-qi*i\ja ݴ~<-)}8e[5HwzyT7.sD%_ 0-r]۟E! ,r*o\eE 3$s,,]lbuZpAܿqipe%20^e[z'"gpG(2AXѯ-P憳ɼ%.%E/+*ŀ7 V UdhYC8́nŁ57 YmH?CtSR H &Jd7@k}o2YU"evWܕ1S6\Hbᩉ7Kh7Po<<+X#6S? SК\#GVҵ'$qD4,Y23+&B ѭPqA"x} tau)iˍ#gWNc)pHmV~6ƬeOl}̒P>o#AsL6O15ĥ8'dӄbg֦ GG<4&}&YYwq;&< ZvMxuX$1x G =. Z@֬oJl@ [%ID d"t)w% gPBDVF9q_پ]ӿe榮KJK#: %;x`YRr+/jɖﶅZ@SaMe/zF3}O7Cll8~'C 2X%RFk9zU2dwxkNފw9}Q0{oU#D3Ca}K [kD+E㗰d>fcк~%)T 5jIRHRr^ DH ͽ}Sn_?8.7XpFW)˂o'U|KtfLv؅N&5tM! Pppks9ɳEH"b+ǽe=T sQziYH"52#ϋ%I]'6|u]7~\WKdwKLΫ6}vuur6׼^5;s-/=7ZヮN 51B{,Ԣdϰ{.۝h+CTC; .A+ΟeX!fw>LmCFNK`nJ*H*ANO ;wMkWb')XUOrLZ֨ f,mQ<4cjD#AUDe"p#V3TbF^`80:̔C5M69dxMGC͋\潙p%q @`hs0 eZBsa3>H`YQRZDDH'r 4ڗ4-=/0HϮek& qH ͊󐲊Pz|lչS\^\xY{͙ߧ=A⣒χg`Џ8bI5}Fׄ6_.773BZ#? (WxZmu#"XAT\יXkcD!jҬg$Шa7Sk$' V-)ĭJyY0ր=NB`Itap8'&Ge[>׺GASܐG k̊K6b[N<%k1\%K"Dao۞RYVa{č玶նnZFz t9{eHD^[oj 'mY{):Xwp$ Ne*OAp,3e7;3hslșl$3BtxU^JZ.ԺeѺMÓLG2[[yŠgdb-<=^ U%XO;1FxQ';oʪ qI!t̩0%Tqŝ/ɕOǁ W6b6NV=w]R!x=2uRQ渧epu w&{/}Z/AWKS[+"fOj`pz sHAܡw,a?'y:Ҥ(DC'!sT3SmHC~/4ݹrZ2}{Q4dFjL#Kw,cn _MѸ,yijX7$IΡOkw )UDF5φٿQ׏!VaMxMakBeN?`7PAI[.XbJ: Ӗ5^;,i/<\Bl 0}8rP a|¬[BFS/FST% ÄͺW9@T>B5s#i tˎX2S^>@#7KFZ""ƒE"E}{si`񴽿1jiߜh uCQ ?MN42IoZPq@|۳*_`.bRtjkWb+΁/E3ssTk7N%QkS;WkސC*U镐S 2 /?Xg4U\:xD1, lzm#شN}ɬ\$!o\|o5[,0N+3f,@6Hv^v.-Fc_lN}~d|Nqh7JkA>Dۘ䭴mBLä`zl账B?wҩ3:SL&U1=n?bZcG@PN8, .=muQI6_ V>U$Kɰ&HCP>ǸG+SzL ө3vTTl/e_ZPGHz(_p]ZO SC ^s8k ix1W HwM2T:b2mJA H (VJs Fq6gWiΓ, \# -f;RR[.pXK6Hӝ7WD  i~uΠj D1]&3w,@1 rǛ_$TV@m-hcI*خH _^6Δ6.-eH7!Borgϟpy}ݔJ+uJB^`C'5Tpݫ\LM ,&l2JplOK1(P+>5ꖬ'cV6˄sRQܹ>f^'/pҕ>+裡'\\k׮U/L aއzIJ)M&crاoR<m1g:Z`G<Z5F"l>+MM|AӈWYCfrC^ P2:P2vN"D8 GФ!puWKdY: 0F鰄qGQaD qpީrzh}АH?jƚ:s$@g3Z4(~}.G?@8X.H'>*:(sWЏd )Y SޱI 3EbchtiYeFާW|(QYMH>zSj$}n$> R$%qx~lh]s׃a!nBAdnD -+ZAGzf6Vx0vjoǙxiy*jؚ &l~M-=YژŸ]}ˬ@9[%}[0v4PUz^G(0{#z0 #ǿ .q|Bˈ9Rd*(NIjzYa["ޤ?fg `#YQQ7^bl4/NHPO4 \&8%$*Ij\*gKQabj]Giޙ4bGU w!NQѹ Pm; աђ0C9b9f D>^<7Xɒs{}HKN*m,}9W`")Qi֠D S)b6pȤPSU\oSz&ɚ%s|7ubXF_S 'wz4 4W]G:,?#tncqQڒ3M@|k}7U /T3{bGyz[PWمSh#m$0"nkhEzDz$)yu}|~ 8lmmJVZYsA$[!-g-j ӆk_A0114d;q}ϲJѾ@l\r Y˅~o;]78aҗ?gO_3kwE`Q4/b(L"B ɣq"h/2m[:ᑝc%.k˃) ZWxy¯)z:qP?_3IE9#@6C-+(v\XZ3މMMjDMP[rr|@Y!-1p/*dUV3ć/V,9j)~tD̨dB)Q + Slʖ5Y VJSoc?GCv)aca< op:RGv\Ip_ 9, =3F6oKX؛+l#Hdib#Е2UH 8?.p ʀ!? >Mof\έQ|IS)W|*qa+͢a!:}<}{*'SJ8)Bq *a C]&n0E 10'"LP[Y%yKx<{DFӳHΡVow1M.o*F`&^T? raM%XL+[9Ez5AEHrhHyU]Yz\/B ?$~ !5"1^ N׋0hX~2В𲕩#H;tǧ7~wj,y G}ҩPz}-"1k~A$ IZÞd&RQ Ԏha]JЖ*/IcdΊI'IN]~i&nv WZW'CAh5Qͦ2`CAַ>ܱD.CfARJ4ze4;(2[,5O9` üά+tf6l6 ]O%9x$.QVPiP*`&*ׅGwo3Xku^{Lʣq3Qr 3 i=5 4͌O@\>bG߈&p_ յ4Tfš#xQ M4KĴ./e\iO6@굲'9" gWkBvS7gVkꬊJ~4;m'5ˈ?]jw@KV *Zxw=C ƻ$d}nb.-/rPz{жhY/5/Ґ+hI<㰛*\!$&J*6S007>{?K Η t \sf`:"S 3{%L'tԄ;x9ܢqw:tD ([WN}g5u ,WZ+Vwx#r !fn4?z@RdT2r_ BIpyN:`͙àz@UM$C/!`EQac7iRCJc|!3AaSaTy_͢EQ}&=_m)zP|#=YA꧱<<}e>DiUҾAjoӽgaR@,O "Xx.RMfn>Q9 ? dK1T}GfP3teF=]dJ[Flޞ\+9fl3%Jb禸HA4*z=(a |KL CQN*B"^s a÷Ŷo t$Mq{3RuBme"b]%I (O5 bzZ8]y.vXϦlV. 8Tɣc=; jg |[t67Aq{qZ#6CΓBkY-i7Gr!w)V8f2Z3_ ! k826l 8; b{2 HSfQFtpMoW#X,A/3BI?&7 )?cqOCEJuPV${uNO#EtJ4`QcS,D]6at1 1Z5_$W%?iz!a3~4oc瑆XVB>\>? :Cg.F v@2xYa=X2`kkW- N2WۖŒM[[vC)H=陂i_[O珂4)ة>Q#֢InY%)6bktn4ト;b?'2sǘaVmxTt B(e9i6ixV0 !I QNT'DsCd.C/hab BY+ԵN8ܵT-8 >F\z dsK'U.=c)sG)AȜbg'k;MׅYt3R?m;7/0UDե:gCw^Sw|(+$H(|ē)_ SZoH|`I[ojV,x›J [h '5oA>~˻@A|CoXq?ܡ%>m\9;yC]^BͼN2qڜoHPbm:Er0({tcW蹻H>GI__=f*dh%(rܜxK Pgnoȩ|xrC!' ypS=J5`9c>@,q>FE]i%:əx 髣NDtoz0h0y)굓,U3+ۄ*L(g3yFsrl)c<;|&uPF dJ)l,r,zf{{ٝ)RMɂZPh7Ш%!]Wڸ$!*TXRpt^rPyO8$酮%mZff b#oO-c ̌QsɍF ;X::;5 0RW0ꠂX$8Sf i`3֒6 um wqA7ݳKuV3BEH?Mc0< >.›cfÛae'bԭgU/wOalQ:XPoOFCFx8{1~C4mC$MZ*=JB6.oongǨvcz\*-:09u#)#N'lyUYY"g6^"ƫHŪ)poҚӒMxӚRēU5ES$t ,`k6p؋K [oO拜Vź 2l/A'nGRDՒ%ma{I},Fw"8!O ox'@7BE2{hDZ*7Fi;R[#d7w+㢿w8~?dAH}?ȵ QӧY`9wot*i[M8qFZ Q}A`33AImL%ц]~H h ֱ?|1Ԛ־p6=||{#A&(-O&ج l^ UG?1fw (Oiu$:+a< ~^J=}M@߫( e*&PPci;"'T98$ =pn؂2D ]Er%XLU֓܅̼PJ:>M 7!劏ؼ+Tl'&6.E8'f4rkdɿ̔ Yn+ulT #@\@_ XQmܦZ2" DuY뜊:ACfmn'ODE#AdBC&9%$WlT % и(У\]4k]cb U%˶N΁Nl+,PӲJ4r_A (nJMwtʿN<]Y,J뾼- ie=5(֮W^Ll<,Őgr[r fR?8L_|.I &{}\3JBgOd"WĀX6C#6 -`t XYqп,]mGK "!ZSFCeKg(Ʋ;&`U؍kϣi!b?7c m- w)v& WG7Ff:-\]kO}k)q?~*f󥍪.ͣrUJ%+#n rfEQ\uc(i^XPeI =UZDX:xwٮߘBy{,2Y EM}Jf1 (ӗ`#+h\F]Y`Esƚ 68 AjHa19ы g$L%cܕjtnTuE _,)h̅v B"=m^,t񴎥Xꃥitw,V Qlx$xI^ 7< `?ܡ6 =i70`SY3rc. ICpP "#N7 7%cSux弌 l*~Q7,cnh@YMz$nS=bJALU*9xI:![yz8q,L3$JxF !MmdN[`fuP/l㞧\Y?o5&9aTV[*$&4"פx"Ųع^ pjLcR>0·n:`iy;>. 0&($c1Ǹ.ﶋc5 .AsWK}9M9B yIQd1))+%oZXJR;@JiOb.K'3?jZ *{J,m%lIh OL:CtO2pG.0EH&RٛY𤣦8ik%eb˘4!Jae<}%HH*o$6g<QǛ^d޽S;!yu ^*9%)!e~~5"3$|^i3üi&XŰ#Ԍ p[eOYv3ר!^Jx6?4*l"bd@.-/p}: VsETGtw#^$FBsJD|z2YZ-pbb(X 67SW- '8¯} CˤX <-Jo @A5ZM 3)w}P;kzj|%Ngoߣs8r4ΥYe-,8MKAqu~XGPy@imK* 'A-^49?p|~H o-ZKq.'wlra0]Lr3 ڙu hnt:l(̨|^Lф\ʩ_'Psg^4螝-7kI&#HR _z[~1`Q-OS@TChJm'VE!Dȝ]VYQ&X4/XcTj70q #C) p=[}+sBD(y'0gZnQ25 f{yn\FF,N+[F}͊Aw.~r{C grmi|>ҟ[uJC/oRMz"d٦8-;rԡoU*̢\$7拣NB2ɔW&j(%Rw/\uι[m2#s+bJxsD7G#=_|Fa—B(ZXoL1 h ?.&6-,p59dMbtAkʧV!Ey_)8F=Rd|ޓ=.s84+{|y=CEXb&F'۵ٳCo$@bN#a;l,d(x4P޺iW.W }DO U <>RQx?ZxUx2.+fWv 혾|ІJY8pv P Cvҋ><]rtQ+C(b1}xu갃VA@tC]p| w9GNT+^AuFWn`^$BCoc/.b+?Qu*P#V_qCU)87Sd'qip c+ E&2/?0}":ef̈R^K.r̛(rxX$JƝ2>mFKtUV@ H X:=;ŸC`*#VI2L2l[YwƼx~.^ i]dEOYŞ;_c$uc`:ZD&F)EOt=Շ{ :KՖ-Ӡ@`VԷHT, mQ"z >ѕ4x䈽XjuoҌF˹7_3g?[>"ZhM vu.{ >}lk"ioAo-!?1ȯ~FSzhgcx#PH3O%栴]EsFmIQ8nќwKBT%l&l,U,]eY6GI'n̕_Uegtӝ9aQ_QFQV@@g,)\e6Fu䗦3j!$rA!; eTFaN >1&ݝD0gҥX^I~_]66`Q8Xc ,{yO㜩-G=q@j{m:sJ3- ګHrzx8;®bu;Җ 3xgpK%BE{?Pm;z97;9bZ s_+8RQ>_"ǻu Kp{b[ݼ(ݺB$ck78(pM eR<5g0T4X= iBeެ+5(>%f21pDF)+ 3a;e= Ȱ qܸ@$" YaXR" ה!r"VPx9tOxL2J$ k O}fIeJf"͛9642DJDD9/`;>qPMm-#L t6@AZ!@?BW  0KC/^0tg=u푴@N*M= |o/Un"G=y[+pprEs ,4n I~w!I)]Gt º 9u&H ]@mg=FfؓRn iI(gZf@k dgIST)*08}rA͐_<%]CFCS`wyPzHu=+fqid_=0wX^ ȫE.t/]yRŞ Cw 0 NTkGuQ3QNGcn,"E37(,jG&Ҝn{ x?βnX.EUL]?`YA(+l0}SōUC2đag>V@3 #ׅLP6ޟ4l=7,4A-ֺAC5CWx;;STNeNh=CGEdx'^#,D#fʝv3l]Ν6Z K[+)j$<4ff0ՃT6nb ]N)̾*FjɻSh-G{Ӷ \S@hRĊ]'ia }aсIq.U2H)0jQ:/E.;eGziP[FIjx"_b ak'DTmgYҧA(I!ʾ:P@t: Sb¶SoxxtjGTFdݷwB32Bjò;L M8b U*Ce8e@a8lx8ӽS5L {iPu/ DMV-Xa<"u &gBb'b8,R*^uM!dæxNgiISRXHqC8:tkn/v~G&"@!|W6BU e2 Nq֢Έ`)WjIGqy 0U"`LK"|euTI?e %F:nﹴpo̯\bγK5@Y AۋjZKg'|XxlA QɐBװ  %cT\{kax˳Z}fO%OT%!_xW'4g৲=}`yOj'JOws#lk# !Tq$m;MY#9_=Q5 |yj>vI茰nlV1nR{Gz6vT@GמJ_Nݩ4&I><7Kv)/Br O⦾ tc!qJ'}'[L>eH0L ­dtf{Sv3Ky'CNLoW 9tvN&xvB88}{9؊3ⶢQ_?Cb@" 8i-Hôyf#gs4݇t+zt|j%˥]2s\+Lu8wJZ 3&ωѝ`DۻV 1͞>OND{sr{ySЃ$ ; ,M"A:'Gjj ~DIgG;T >,oGkcOt{~XWdƁR8s;2adڄ򽊩 v6QR}yë41kuC=Mu|ŧFFYa[jJAmb`z:5b!~~ASAw *v >"J,,pI]B%H DNf}'AzG~"5=nc?kur Z$rۢiXo1p!qpԉ6$(* T(ݱs] 11×* ?bL#$;i' g#D LTO0$6x/V16fI ADvڊ1eVYuXэlscH͏.X`9/2et0%إ:U2ƽ_T.hX\c3ݎqxx;UN? SX-h=}_OK0zA۱ J¤8JPՠJ] >s'?IÆ!2csa@z,~Y`}}-ru台l4TOoQma8H^rvP}tvt]YU9-w$*>=M&7&Eo>T}9 !N>;r;TnsB,~Ű4hXl8h8)pp`RmO;jI8)$qP)H1!G^6q.wMV>-C('+/GMBr9AЬLXW:;cD%dnѬ_o@ʷux j!O>ܸXsJ.+ {G,n~<1=.duڞ)J`= 㬽㕩Agddʖ@6/cv)IbcKސe}ZGF36Imi6A2t<,rKR`S͓;Ai)-wj̓s'~w@@Ρ>:,[]GSA5B3) E?5]wg8C'uKno05ӓ 3,e ''2Ū^ʫ.^~-'mEVZJRofSOe ;dsE_G.Wns6%TI 2F h 'nj‰bǰE7\8󢛝7&V.h6^|]Pa,m5h{PuZKֱu 4G.-fd.bfJo8p|i@}uS a!EU)㯤,.'n^!/A񗬈x|cs%{- _e:SN0́d/"4*?"i;v'>ZcDyLqp}qW`3P.(08g,!;>ԅ2d⥑!g ̠SNxay.5kRw`bzDR~P ^kMD᩸x8"2.bcni~BPNrf9>G)uA$ĕ\08Ĝ˴,%\Gm1Z] H(t2=R[[|^ooTQL>;f&Ն\%A as(d}O/LƼ/LÕO<=yX$)BT1"#ѳ"&hO[#'So+t A"3Rmfs>tv@1z!̘bwPd;UKvZ&u3| =ҋھ4ȝ @.4gגi /*|1&I>R?`±Owr +걙^L>El s`c]++:=^Mk?O9u:# 9&:P0oHW|^xblw4nf]6BZLjP+&G&:|Iumo1NBˣ9/~ T:ܫqQ p4_uJ bkFN8 7h_W1 Ty0a#4T'컉=WOg[SvwcwQ9$>1x,(]wJXsfiiH(ОpE[Bzz#٘k86vDʼn*F㼒8/-5u&UAsP-È-`]ˆ_oS6'6hߒ'!w/qR@{^Sn)u@r6r`jKZ#.ɊJ/wq&]ymdFiX 45!v?+ݮA8z7㼧31y5i:z F7ejXnSIWѷ<+NDvybƵ Kyu1TEK657oc3 SeG2'unt ׉j)wn # 0^?"a1SvLuȵ+ 2+^DX|&?+ڇSJTJ,\u)Mok]-j'~]MS`wH /{b#gj*ԞnQs3 5 /w8~6Z4ɋ}j19651&*:ݪ=?譅<d-:I!sp˛ʟmX+4v{;16i`g( +j_r;n>zTmLOe8Z>WPu@MI.BA5fEp.`lWj8ո&*&'̃<ܛwN; z65W[N>(.:Te[ D"-bu)aOɕD|'2HD֪+Xs"]Ziūk-ǤB?>G|(ÛmYjZX0˸6mkOnPxNϐԿgOw kn$2©hc&ϊGR1&RWv0ښx;;z*mF ׁ SA#5kH.jˁ,.!F@Ez'psݢV35l'9Ǔ8i(k28_d\%vθ [Pp=&c}x! Jse]VnIZ:*GbPS !0)HH+H%LUi\*zxBȩE7-}*7zR;d}QyMl{T|jnH.=,ܴm hM#ﲈE[zX8p-Pj>rr"'lD79 +*oΡm |!$-{F&~lapOCul'@јF evUt)ZT+@8Vυsb D)#H>Ca⾮27UD4/am4LcDh1ۀ`G̙BOݦ֕K)dlepC8W1jq~l:|O*Tu3ɺnR@;{t>{Zc|Wˀc.5jKcn*pp3ycW %҄:ULXk;6RESۃQ$.R3c~T LJfFij='xܥzk15/M+_ m󬵝/WGI @^W*mT9S9,;u߾AA8+|R-LIY,W*܎Xּђ221 U[(tz\H a"w+ |u-Zxӆ' (OPQCWw(:~6aKUX(:Qs !kp{.m-tŅ5qx*Dcʬ *Ss72vFW[Pcu?~8Dyae̸"Q~p`U)ܞL'Ȓ^HL^n{댸t\3Ogql/AF\y8#t &)Erj"ߡa$څ%X($ QV c}x8N+NQMs)3s.R-bχS3FSD#J|Ȼ$,|<zF$wnqq@4=b Lqл A8-F2u7guTWݦa8ZՃ;Z$7y;G)SMNݡz6987v˱"Rh̐h͍,.լddڄK@ ](ӰDL#)qMEa+옶%MhBKppDHqҐ7d98E%;㳒?$;g;o 8)IE Y2Yfpr\&|Pk =qջ:qC|N0Vn;k+IHPh%\ˡQ3*'>vK 3 lޙoA/[ǩ֣Tv^w,n2Q]5S`˗ 75VTYjh_SF,Kvbaa׼7ѫ&>ځG0MJ(+J#zkGSD#7 `;Н_!]׵uۺSmr tUR3e(ფ=˴X‘]*|HV(ح > U>FcB*ܲ,<"v,wLl g׋VKq̢q4Hܸ䥎 9þ DxȽ6ZT'2l7nOڇ)PȺvFS⅚h" oyh[4#QJqY(9J_tLBpDŽun[{0,vkߘj̕ebUXH;-72Έg<xKgmJŮrI˙a$=ƕV!Ϙg"p\=*9pYEQH}=Gm&V5 !wkƳyt–ƥ(BbNJlR rzp4+G!wa&ZCB]u0_#v^"l)5Ɲ㔟7%g( ~^W~i4 ЃZ#޻/wZ5v6]!~;)J}wI)H$ü!YJ=(:i,=~ ~22_W ԤΎG8O51Dqhː9M.M?_Au@~`eI|oJtA@&`b=s4NQ:S)`w&5/#5'l1Į\nd{P3ڴًod8ьA~@Kg~:uɭڏ:,BtTS\%1G.L+D.U<]ʭVbFECm@Af!1N2 н-/[_5Ua0U); T+G`n mn@VAAa-J ;[zG+3AW(6 ߿,sIw=@{Ki-}b4;Q.0A8q ;]B51zH^13h)'T2 YY2!K*&7tH;O Rh ūߩnk>srTůhx'ԽEv5/aEOwam8XBU s A79cC2DA_gqV7gg2 K{8'()uaܢc1 YX15p R3\Q_A#F=i2B{قS){v/ áDp&>eT wjC/Jd" awʵg( 0(/4VɅ:WJeYăڬ¹F|<O T{`v$f _4?6鼜(gA]dYb)Tu:^mh:AZ!7z8=Ldl*w\x|K* 0N;&Df?  O}A?M0R (m$Hu)?|s9,(\ZqV{JP L]3U*M doڲ6v1gKƖ1R?8y6@h: p0uAj㬓{&xgcjН ~?g!>Ǭi{1%8 Ĉ+Dg7擐IAHځXZ_FpTewB`+:mOt|dEXoStXö1L%W-An̈́,F# ΩDѣ}wLpF{dQguuSu߷x9EmMcT 7aXaxu9ߖWv/#q:5Pzͤ!5X9kGè)UK0g<\ "8!=x=&-3ص^PVE= ?CD0i0šWmә#vT"bY>8Cq%0EIJ ,z qI4LɅ0r ά޾Vr,YFn|GIX11#4pgT1oG^ą9Rf56(#- PFJǣ]O,2am,^ڙJWT1>azBy2 Yǝ]zZΪS^rL+{c^}LqtբGC|<ĝUZ]d|]K&^8< !}iR?a\[ʢsKݎ >(ieNbumciN}Ls)~SVTcd~@E&Cy D ]jmxُʽPA3ĥB~FjZӬe mZ0/?9_턆[0:J ,WC:eNIه, ]VG &fxm𻹀Hʅ l(urg\WTtm+K3)x5B !qp:\0,ў7A'# G}E'nbA6có@\3f\CƝJal҈WJnмdʄ\]&JI'a!(beA׎#Xwrmh}ڪ?I/Vwn#T1S&*gl9gu5B#:􃵡>FQ:?YߙR'xŝ|]b/eqpa<.T@%Au^F9B7YFt?6ۗ&`.mZg̺81٭0j "JO\St>bhɗ̫+N}c@ bd'oFR0s >W2Y]1AnfwXw^bm﷼ і{-o*r4;30*%W .|!)a93łU1LЂh*W8ʁ`|A2b33颕 ?oBR)'m|>ekS{Dʴ؀HP/TO/8x<_Op6-8\i#!*l8{Ŏ9G Lf=LTuڠyR7 V磥 Bq1x )vƎҙYŃh6s'K*I3QUDRex_lMm^><>N,9 bIMƧs#{Nch ^ĕzeJ`)rCgr5rl<X\qxEK NH(i^xL.$a lEH9 _jjڅ㎄1[G>MhZd)+ۉ8E5>/w 5+MSv;Ƚ#|==H^/蜸c4悯^[%!+'RN.g_1lCI7d 5nc2ˆتfZ14-$ӃŊv}?w[ڮu=ܞupMvi֯fvf<ÊSAT^ v `˖u^@1X^ǝ'%ƉvX¨ݠ[>ʙiyӤR Xf$di}mI,wť(?0 'nO3I;*7~JB?W%|K^]KBBH7_pJʎ&M]#^ 4gJ2M({QFp#H TY_P0?%in,D˟r5CCi1\ crѩA~{@4b7/a94( ne^WQރmO0GU!Uv=҆p3;:Ρ~>6A&'wSfT{ֹ^0zhÇ"9ay:T΢/aZ)4wG\]ì#N8?`"˨}POmO(^U ]hZ8Va lɹrH1z;)vT 2IeDS2[Q}>flL K0Γ%pu8 2GR!"- ԗ*?4a0UTr !(55! k8_3Ο~$мg=:OIk_>|c"\ݖ+U-QY;94 kW⬠&9˄]g#JF<Ⲑmuq\\J$$<[]6,mքrJ{fӬ R̊8 y%v{2VY^z%Fٮ*r:g 06RYrw]Z9}"; F#A^NXԚ4_S//S-W9'vMw:๝'p|}@kEYC|oB}5(Y#:@Km 89jxJչSV]2Oe2;mFvъjRo"|DXE ,[uz?Pi Ccz 4E脠ŮQ0[ w {ԕ UKXy\nE4'"H xwĪcz^K|MxMUPn+|jژOE<_l%gqcU8 .4=qu/4GGt!7qD}%{q:.l2԰u`+W]yiFj`w)$+xsF7X>>ki9,Eq}ٷ(4uRjSֿ͒j$"A% <΁I ]WAbJ7.Ըsx\똓4FuwqxaUO U;CB&MZ~ѓ u9O pfiYi+)n}E}>-ȋe(p>z#mvw6-V2E;6gafQz8ykyKHg^拋A2zY4|cnOb~5?MW87 *+leop$w֕oQ M,0Zвb-6. %/t@Dj/UO`ppl_ v: SwL`cC^KEm`>9KqyS!YB5lTJwX0W m^wPp&dlQ(Cj WCc/T݃ _ݪ{)DeM[פLA 2ة|,/H9|+yÿs<OMZu[IHJf&GuPQH08=/7!);ձA̤y1{Lm.ڔk*>(^Aw8Ề-J/-ۜIxZinrOXr~4ihh;FE[Us;L;=.$V"A_NeĢ*7HS۾ƽd %BF:-2#|·p pɞJ$av[r7s#aeL{ > Er8Vpw: ~JߏNc8ǮqNT+-9athR#Y9p;yҸ%%EQT'9\qyP= $EkӅ9!! ri*@ !m1A KTǧJb,r &۬S_g)^eA~/*"O_T.yPy'}Y|m `Dى^zkKj,O䟏7 LŘ8m?źoC.[hdtT9 Y+́p?&/Gu[,n|^_̜N]OPpTnȞ_ H*3~5B@$]0 UuBtQ/O]<9( +zrw"-EQgƪ$u\d !DRxif&[|%HV+إw !9}F@Jf#ӊș8 8 V4v\s4bO'i.5XjYʚ@$l3 [#yZ!DdN\87q&hjmXL i 3;O2 R=Qvp佬pF>آ)6;xvi)ڇ$῅8rPhk+]ǚ^9'{M f1qTLJj8I˝#b|.YT%#b` Q;9+5' XQjV`yLMKgS &(jomk߻#UȚ/B%vT vڈŨrJ[q; k64Z9d)sٛ{ߝs_MnGkј |4/=H E{,0%ڕ׉3+gs탾2vS!OqYtҦt؁s+-NM3  YJ2&KuF}'cMc^ZMZY?jMZz]m7ZZK-y4:0?#S4\G UvvQ0 ~[- A ! >Md:~ v![W &i }|m4B<"Ȇ:Rs˳Ga1:fEc_a*1[\C)p-es)bq77Ձ=?x0V -G?!G6!QW:UFa6QRd@3co91;ǂh%jqE@l;P&Yĉ\+juR}a :WMgПbRaN@xjƂ<% ~DO; r0-g!}f:ϸ `#WYu6_F6\{1RېݾOÌ .PvAT%u'gY&1"JfP?(5AB9t Ys%%]s{wa96c! 5WI%Ġbm3`̓<)b mPMU4:f*$;wZ|7\V; nlޭꀬXj(#$Bl)rocFM*l(Ex4p[/[Vjx_5ו  8 ֒%ndh?Jt&7}1`z[6H5/azOpy ck3lj G [7P,[wVmv\|Fy_鲩k<@]$O~(Ms69vYz*aW:`)޺E A}7*vW~|'bS#[VZn?dz7n&6pz> ys /X >*lT@}~ 6x|5@;*,y)z8a5kf, !=ޝTʊI] *'ub*9G> :P]2О0uK6?NK.Q6T\B$ X`RTQCC3=pګJK86~fF~z|d2#B\,LzNWMN̬VGsH,Y`1{:ntt1Y.B),o^`_yL Odېo2> Z([ 2$FeOBw*+Šڨc蛙1Z+.Q,qEp@HO/4?. BH9ukZ!YAq@y8yWi]UaLj}Ώ oO]"РAil(>Whj]g)1EJ!) mRU*jjat=NtwP4̂/-`.&Lo68>"*lew4Ҍk`w oL;JV)}<4&Wަ6?B)0dۑVPIc$z8W<+)`#"?/I=@XO0t=;UFuzBnF+'Ce AC;n ~K7!5uM|#V<JlEm UwQ@8-h̋ *胚![br01K rĭ$IOYQBdIeּqq%jTw4*(<|KIvD({qfmxh#ŕ&ܛ>O$],Lc) *[i/Ɗ(`I3p`Ϫ:ޮ\`BwbSa0e7N$z qwgme3L(U"f+B МL T H|=S}'W-f@r`CشRtBWt4/T,wE`{O9Ցavg* 5j,)dYVz!'7{#ab.t?1O޵ܧk6zp7;lˉy8kٷ1tX%G՗ŜڇOMŴt㈐auw)$ps'^,#Lp _ԋFA_Q#MU יH:gS,9#xlHRp)c^(r_pFPG 9gtΔ=Rv"IRgVyJhs;b?ύYO]Ǐ ġw1(eזhP%toOcJIT@zu1zG*n5]JZr#X{P*2዁ԫt^N)dWBʁXBI(P&-@g`j[ZSg5'H׫bw9Θ5H=(ɂ^xձU骓FyDR(=Rx \6Q:d ȝI9ŀyv`8(6,0C^Qqc7ǿ{4+t!#Nn1,S9dk/ҝb@+NOZ o`y۶(E~e1@y}!/A-&9 YS~H] \Kڛ!iji(Ӣ6A۳Z U<;lj8\5s1%tufV^:x%/>e4P<4㽓qZւGzEZ%52 ! %vH GN!TfalI$f@!-4|j5TdHL -mV2b,a}ޟe)J^zf+ˍ[ptdd*R@8N'\mɇR].^/̪s/tU>?4j n^E%sWF~zRo _98QLGE3y[~kΦ_F ÚZqjh3<{hc!}{޷JD