M/ef zdZddlmZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z dd lm Z dd lm Z dd lmZdd lmZddlZddlmZddlmZddlmZddlmZddlmZdZiddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd? Ziej5Dcic] \}}e|z| c}}Zd@edAefdBZGdCdDej>eZ GdEdFe Z!e!d(Z"e!dGZ#GdHdIejHZ%GdJdKejHejLZ&GdLdMe Z'e'dNZ(e'dOZ)e'dPZ*e'dQZ+e'dRZ,e'dSZ-e'dTZ.e'dUZ/GdVdWej>Z0GdXdYejHZ1GdZd[e1Z2Gd\d]ejHZ3Gd^d_Z4ed`dabZ5Gdcdae3Z6Gdddee6Z7Gdfdge6Z8Gdhdie2Z9Gdjdke3Z:Gdldme1Z;Gdndoe3Z<Gdpdqe<Z=Gdrdse<Z>Gdtdue2Z?GdvdwejHZ@Gdxdye2ZAGdzd{ejHZBGd|d}e3ZCGd~de2ZDGddeCZEycc}}w)zACME protocol messages.)HashableN)Any)Dict)Iterator)List)Mapping)MutableMapping)Optional)Tuple)Type)TypeVar) challenges)errors)fields)jws)utilzurn:ietf:params:acme:error:accountDoesNotExistz4The request specified an account that does not existalreadyRevokedzOThe request specified a certificate to be revoked that has already been revokedbadCSRz2The CSR is unacceptable (e.g., due to a short key)badNoncez1The client sent an unacceptable anti-replay nonce badPublicKeyz>The JWS was signed by a public key the server does not supportbadRevocationReasonz;The revocation reason provided is not allowed by the serverbadSignatureAlgorithmz@The JWS was signed with an algorithm the server does not supportcaaz\Certification Authority Authorization (CAA) records forbid the CA from issuing a certificatecompoundzBSpecific error conditions are indicated in the "subproblems" array connectionz?The server could not connect to the client to verify the domaindnszAThere was a problem with a DNS query during identifier validationdnssecz4The server could not validate a DNSSEC signed domainincorrectResponsez;Response received didn't match the challenge's requirements invalidEmailz1The provided email for a registration was invalidinvalidContactz$The provided contact URI was invalid malformedz!The request message was malformedrejectedIdentifierz9The server will not issue certificates for the identifierzLThe request attempted to finalize an order that is not ready to be finalizedz,There were too many requests of a given typez(The server experienced an internal errorz=The server experienced a TLS error during domain verificationz)The client lacks sufficient authorizationz@A contact URL for an account used an unsupported protocol schemez*The server could not resolve a domain namez'An identifier is of an unsupported typez,The server requires external account binding) orderNotReady rateLimitedserverInternaltls unauthorizedunsupportedContact unknownHostunsupportedIdentifierexternalAccountRequirederrreturnc`t|tr|jt|jvSy)z#Check if argument is an ACME error.F) isinstanceErrortyp ERROR_PREFIX)r-s //usr/lib/python3/dist-packages/acme/messages.py is_acme_errorr5@s'#u377#6sww&& ceZdZUdZdZeZeedfe d<deddffd Z defdZ e d eddfd Z defd Zd edefd ZdefdZxZS) _ConstantzACME constant.namePOSSIBLE_NAMESr:r.NcNt|||j|<||_yN)super__init__r;r:selfr: __class__s r4r?z_Constant.__init__Ls% $(D! r6c|jSr=r9rAs r4to_partial_jsonz_Constant.to_partial_jsonQs yyr6jobjc||jvr"tj|jd|j|S)Nz not recognized)r;joseDeserializationError__name__clsrFs r4 from_jsonz_Constant.from_jsonTs= s)) )++s||nO,LM M!!$''r6cN|jjd|jdS)N())rBrJr:rDs r4__repr__z_Constant.__repr__Zs$..))*!DII;a88r6othercbt|t|xr|j|jk(Sr=)r0typer:)rArRs r4__eq__z_Constant.__eq__]s%%d,Htyy1HHr6cDt|j|jfSr=)hashrBr:rDs r4__hash__z_Constant.__hash__`sT^^TYY/00r6)rJ __module__ __qualname____doc__ __slots__NotImplementedr;rstr__annotations__r?rE classmethodrMrQrboolrUintrX __classcell__rBs@r4r8r8GsI-;NDk)*;ST (S([(( 9#9ICIDI1#1r6r8c*eZdZUdZiZeeefed<y)IdentifierTypezACME identifier type.r;N rJrYrZr[r;rr^r8r_r6r4rfrfds+-NDi(-r6rfipceZdZUdZej dejZee d<ej dZ e e d<y) IdentifierzJACME identifier. :ivar IdentifierType typ: :ivar str value: rTdecoderr2valueN) rJrYrZr[rHfieldrfrMr2r_rnr^rhr6r4rkrkms; %$**V^5M5MNCNG$E3$r6rkceZdZUdZej dddZeed<ej ddZ eed<ej d dZ eed <ej d e jd Z ed ed <ej d dZeeded <ej"deeeefdedfdZedededdfdZedeefdZedeefdZdededdfdZdefdZy)r1aACME error. https://datatracker.ietf.org/doc/html/rfc7807 Note: Although Error inherits from JSONObjectWithFields, which is immutable, we add mutability for Error to comply with the Python exception API. :ivar str typ: :ivar str title: :ivar str detail: :ivar Identifier identifier: :ivar tuple subproblems: An array of ACME Errors which may be present when the CA returns multiple errors related to the same request, `tuple` of `Error`. rTTz about:blank omitemptydefaultr2titlerrdetail identifierrmrrrk subproblems)r1.rnr.c&td|DS)Nc3FK|]}tj|ywr=)r1rM).0 subproblems r4 z$Error.subproblems..sIZU__Z0I!tuplerns r4ryzError.subproblemssI5IIIr6codekwargsc T|tvrtd|zt|z}|dd|i|S)zCreate an Error instance with an ACME Error code. :str code: An ACME error code, like 'dnssec'. :kwargs: kwargs to pass to Error. z4The supplied code: %s is not a known ACME error coder2rh) ERROR_CODES ValueErrorr3)rLrrr2s r4 with_codezError.with_codesE { "%'+,- -T!%s%f%%r6c@tj|jS)zHardcoded error description based on its type. :returns: Description if standard ACME error or ``None``. :rtype: str )ERROR_TYPE_DESCRIPTIONSgetr2rDs r4 descriptionzError.descriptions'**48844r6cjt|jjddd}|tvr|Sy)zACME error code. Basically self.typ without the ERROR_PREFIX. :returns: error code if standard ACME code or ``None``. :rtype: str :)maxsplitN)r^r2rsplitr)rArs r4rz Error.codes6488}##C!#4R8 ; Kr6r:Nc0tj|||Sr=)object __setattr__)rAr:rns r4rzError.__setattr__s!!$e44r6cvdjd|j|j|j|jfDj }|j rd|j jd|z}|jr1t|jdkDr|jD] }|d|z } |S)Ns :: c3DK|]}||jddyw)Nasciibackslashreplaceencode)r|parts r4r~z Error.__str__..s*!9= KK!3 4!s z Problem for z: r ) joinr2rrvrtdecoderwrnrylen)rAresultr}s r4__str__z Error.__str__s! XXt''djj A!!"(  ??#DOO$9$9#:"=FF   D$4$4 5 9".. , Bzl++ , r6)rJrYrZr[rHror2r^r_rtrvrkrMrwr ryr rmrrrr`rpropertyrrrrrhr6r4r1r1xshtzz&D-HCHGt4E34$**X6FC6)3j22d*DJ&D1;MUY1ZK% -.ZJ4S#X/JE,4GJJ &S &C &G & &5Xc]55 hsm  55C5D5  r6r1c*eZdZUdZiZeeefed<y)StatuszACME "status" field.r;Nrgrhr6r4rrs+-NDi(-r6runknownpending processingvalidinvalidrevokedready deactivatedceZdZdZGddej Zdeee fddfdZ dede fd Z dede fd Z de ee ffd Zedeee fddfd Zy) DirectoryzmDirectory. Directory resources must be accessed by the exact field name in RFC8555 (section 9.7.5). c8eZdZUdZej ddZeed<ej ddZ eed<ej ddZ e eed<ej d dZ e ed <d ed d ffd Zed efdZd eeffd Zded efdZxZS)Directory.MetazDirectory Meta.termsOfServiceTru_terms_of_servicewebsite caaIdentitiescaa_identitiesr,external_account_requiredrr.Nc |jDcic]\}}|j||}}}t| di|ycc}}wNrhitems_internal_namer>r?rArkvrBs r4r?zDirectory.Meta.__init__sF__iter__r@s r4rzDirectory.Meta.__iter__s8(* H"&*="=d12h4G Hs#&r:c|dk(rd|zS|S)Nr_rhrAr:s r4rzDirectory.Meta._internal_names!%);!;3: E Er6)rJrYrZr[rHrorr^r_rrrrrarr?rrrrrrcrds@r4Metars!+,<!M3M!tzz)t<<$.DJJ$$OS O*4$**5NZ^*_!4_ 'S 'T '  *c *  * Hhsm H  Fs Fs Fr6rrFr.Nc||_yr=)_jobjrArFs r4r?zDirectory.__init__s  r6r:cX ||S#t$r}tt|d}~wwxYwr=)KeyErrorAttributeErrorr^)rAr:errors r4 __getattr__zDirectory.__getattr__s0 -:  - U, , -s )$)cZ |j|S#t$rtd|dwxYw)NzDirectory field "z " not found)rrrs r4 __getitem__zDirectory.__getitem__s= B::d# # B.tfK@A A Bs*cDtj|jdS)Nc|Sr=rh)rs r4z+Directory.to_partial_json.. s1r6)rmap_keysrrDs r4rEzDirectory.to_partial_json s}}TZZ55r6cn|jj|jdi|d<||S)Nmeta)rrMpoprKs r4rMzDirectory.from_jsons/xx))$((62*>?V 4yr6)rJrYrZr[rHJSONObjectWithFieldsrrr^rr?rrrrEr`r rMrhr6r4rrs Ft((F2WS#X.4--- BBB 6c3h6^CH5+r6rc@eZdZUdZej dZded<y)ResourcezOACME Resource. :ivar acme.messages.ResourceBody body: Resource body. body ResourceBodyN)rJrYrZr[rHrorr_rhr6r4rrs &4::f-D.-r6rc@eZdZUdZej dZeed<y)ResourceWithURIzKACME Resource with URI. :ivar str uri: Location of the resource. uriN) rJrYrZr[rHrorr^r_rhr6r4rrs tzz% C r6rceZdZdZy)rzACME Resource Body.NrJrYrZr[rhr6r4rr'sr6rc TeZdZdZedej dededede ee ff dZ y) ExternalAccountBindingzACME External Account Bindingaccount_public_keykidhmac_key directoryr.ctj|jj}tj j |}|d}tjj|tjj|tjjd||}|jS)zLCreate External Account Binding Resource from contact details, kid and hmac. newAccount)keyN)jsondumpsrErrHb64 b64decoderJWSsignjwkJWKOctjwaHS256) rLrrrrkey_jsondecoded_hmac_keyurleabs r4 from_dataz ExternalAccountBinding.from_data.s ::0@@BCJJL88--h7 %ggll8TXX__9I_%J88>>4%""$$r6N) rJrYrZr[r`rHJWKr^rrrrrhr6r4rr+sH' %488 %# % %& %+/S> % %r6rGenericRegistration Registration)boundceZdZUdZej ddej jZej e d<ej dddZ e e dfe d<ej d d Z e e d <ej d d Zee d <ej d d Zee d <ej dd Zee d<ej dd Zee efe d<dZdZe d$deedee dee deee efdedef dZdeddffd Zde de e dffdZdee efdee effdZdee efffd Z dee efffd! Z!e"de e dffd"Z#e"de e dffd#Z$xZ%S)%rzRegistration Resource Body. :ivar jose.JWK key: Public key. :ivar tuple contact: Contact information following ACME spec, `tuple` of `str`. :ivar str agreement: rTrrrmcontactrhrq. agreementrustatustermsOfServiceAgreedterms_of_service_agreedonlyReturnExistingonly_return_existingexternalAccountBindingexternal_account_bindingztel:zmailto:NrLphoneemailrr.c Fd|v}t|jdd}||j|j|z|;|j |j dDcgc]}|j |zc}|s|rt||d<|r||d<|di|Scc}w)a Create registration resource from contact details. The `contact` keyword being passed to a Registration object is meaningful, so this function represents empty iterables in its kwargs by passing on an empty `tuple`. rrh,r )listrappend phone_prefixextendsplit email_prefixr)rLr r r rcontact_provideddetailsmails r4rzRegistration.from_data[s%.vzz)R01   NN3++e3 4   NN C@PQC,,t3Q R & %gF9  #1IF- .}V}Rs Bc dd|vr|dtj|ddt| di|y)z;Note if the user provides a value for the `contact` member.rN _add_contactTrh)rrr>r?)rArrBs r4r?zRegistration.__init__|s7  6)#4#@   t^T : "6"r6prefixc@tfd|jDS)Nc3\K|]#}|jr|td%ywr=) startswithr)r|rvrs r4r~z/Registration._filter_contact..s2*%+  ( 3v;< *s),)rr)rArs `r4_filter_contactzRegistration._filter_contacts!*/3||** *r6rFcHt|ddr|jd|d<|S)a The `contact` member of Registration objects should not be required when de-serializing (as it would be if the Fields' `omitempty` flag were `False`), but it should be included in serializations if it was provided. :param jobj: Dictionary containing this Registrations' data :type jobj: dict :returns: Dictionary containing Registrations data to transmit to the server :rtype: dict rFr)getattrrrs r4_add_contact_if_appropriatez(Registration._add_contact_if_appropriates' 4 /"kk)4DO r6cBt|}|j|S)z2Modify josepy.JSONDeserializable.to_partial_json())r>rEr"rArFrBs r4rEzRegistration.to_partial_jsons!w&(//55r6cBt|}|j|S)z;Modify josepy.JSONObjectWithFields.fields_to_partial_json())r>fields_to_partial_jsonr"r$s r4r&z#Registration.fields_to_partial_jsons!w-///55r6c8|j|jS)z*All phones found in the ``contact`` field.)rrrDs r4phoneszRegistration.phones##D$5$566r6c8|j|jS)z*All emails found in the ``contact`` field.)rrrDs r4emailszRegistration.emailsr)r6)NNN)&rJrYrZr[rHrorrMrr_rr r^rrrrrar r rrrrr`r rr rr?rr"rEr&rr(r+rcrds@r4rrAsDJJudhh>P>PQCQ *tzz)tRPGU38_PTZZ t"6c3h6 6S#X6 7c3h777c3h77r6ceZdZdZy)NewRegistrationzNew registration.Nrrhr6r4r-r-sr6r-ceZdZdZy)UpdateRegistrationzUpdate registration.Nrrhr6r4r/r/sr6r/ceZdZUdZej dejZee d<ej ddZ e e d<ej ddZ e e d<y) RegistrationResourcezRegistration Resource. :ivar acme.messages.Registration body: :ivar str new_authzr_uri: Deprecated. Do not use. :ivar str terms_of_service: URL for the CA TOS. rrlnew_authzr_uriTrurN) rJrYrZr[rHrorrMrr_r2r^rrhr6r4r1r1sW$FL4J4JKD,K$$**%5FNCF&DJJ'9TJcJr6r1ceZdZUdZdZej dddZee d<ej de jde Z e e d<ejd d Zej"e d <ej d ejdd Zee d <d eddffd Zdedeffd Zdeeefffd Zedeeefdeeefffd ZedefdZdedefdZdeeffd Z dedefdZ!xZ"S) ChallengeBodya>Challenge Resource Body. .. todo:: Confusingly, this has a similar name to `.challenges.Challenge`, as well as `.achallenges.AnnotatedChallenge`. Please use names such as ``challb`` to distinguish instances of this class from ``achall``. :ivar acme.challenges.Challenge: Wrapped challenge. Conveniently, all challenge fields are proxied, i.e. you can call ``challb.x`` to get ``challb.chall.x`` contents. :ivar acme.messages.Status status: :ivar datetime.datetime validated: :ivar messages.Error error: )challrTNrq_urlr)rmrrrs validatedrurrr.c |jDcic]\}}|j||}}}t| di|ycc}}wrrrs r4r?zChallengeBody.__init__sF8> G1$%%a(!+GG "6"Hrr:c@t||j|Sr=)r>rrr@s r4rzChallengeBody.encodesw~d11$788r6cvt|}|j|jj|Sr=)r>rEupdater5r$s r4rEzChallengeBody.to_partial_jsons.w&( DJJ..01 r6rFcjt||}tjj ||d<|S)Nr5)r>fields_from_jsonr ChallengerM)rLrF jobj_fieldsrBs r4r=zChallengeBody.fields_from_jsons3g.t4 )33==dC Gr6c|jS)zThe URL of this challenge.)r6rDs r4rzChallengeBody.urisyyr6c.t|j|Sr=)r!r5rs r4rzChallengeBody.__getattr__stzz4((r6c#JKt|D] }|dk(rdn|yw)Nr6rrr@s r4rzChallengeBody.__iter__s.G$& 4D6>%t 3 4s #c|dk(rdS|S)Nrr6rhrs r4rzChallengeBody._internal_namesv0D0r6)#rJrYrZr[r\rHror6r^r_rrMSTATUS_PENDINGrrrfc3339r7datetimer1rrr?rrrEr`rr=rrrrrrrcrds@r4r4r4sQ I  5D$?D#?TZZ&2B2B"&@FF@#16>>+#NIx  N4::gu!%t5E55###93939c3h GCH$5$sCx. S)))4(3-4 13131r6r4ceZdZUdZej dejZee d<ej dZ e e d<e de fdZ y)ChallengeResourcezChallenge Resource. :ivar acme.messages.ChallengeBody body: :ivar str authzr_uri: URI found in the 'up' ``Link`` header. rrl authzr_urir.c.|jjS)zThe URL of the challenge body.)rrrDs r4rzChallengeResource.urisyy}}r6N)rJrYrZr[rHror4rMrr_rIr^rrrhr6r4rHrHsT %$**V]5L5LMD-M djj.J. Sr6rHceZdZUdZej dejdZee d<ej ddZ e e e d<ej dde jZe e d<ej d dZej$e d <ej d dZee d <e j*d e eeefd ee d ffdZ y) AuthorizationzAuthorization Resource Body. :ivar acme.messages.Identifier identifier: :ivar list challenges: `list` of `.ChallengeBody` :ivar acme.messages.Status status: :ivar datetime.datetime expires: rwTrxrrurrexpireswildcardrnr..c&td|DS)Nc3FK|]}tj|ywr=)r4rM)r|r5s r4r~z+Authorization.challenges..,sG],,U3Grrrs r4rzAuthorization.challenges*sGGGGr6N)rJrYrZr[rHrorkrMrwr_rrr4rrrrErMrFrNrarmrr^rr rhr6r4rLrLs(TZZ j>R>R^bcJ c&0djj&NJ]#NTZZD&BRBRSFFS "0 T!JGX  JTZZ d;Hd;H$tCH~.H59K3LHHr6rLceZdZdZy)NewAuthorizationzNew authorization.Nrrhr6r4rRrR/sr6rRceZdZdZy)UpdateAuthorizationzUpdate authorization.Nrrhr6r4rTrT3sr6rTceZdZUdZej dejZee d<ej ddZ e e d<y)AuthorizationResourcez~Authorization Resource. :ivar acme.messages.Authorization body: :ivar str new_cert_uri: Deprecated. Do not use. rrl new_cert_uriTruN) rJrYrZr[rHrorLrMrr_rWr^rhr6r4rVrV7s= %$**V]5L5LMD-M" >TBL#Br6rVceZdZUdZej dej ejZeje d<y)CertificateRequestz~ACME newOrder request. :ivar jose.ComparableX509 csr: `OpenSSL.crypto.X509Req` wrapped in `.ComparableX509` csrrmencoderN) rJrYrZr[rHro decode_csr encode_csrrZComparableX509r_rhr6r4rYrYBs3 *tzz%RVRaRabC  br6rYcxeZdZUdZej dZeed<ej dZ e e dfed<y)CertificateResourceaCertificate Resource. :ivar josepy.util.ComparableX509 body: `OpenSSL.crypto.X509` wrapped in `.ComparableX509` :ivar str cert_chain_uri: URI found in the 'up' ``Link`` header :ivar tuple authzrs: `tuple` of `AuthorizationResource`. cert_chain_uriauthzrs.N) rJrYrZr[rHrorbr^r_rcr rVrhr6r4raraLs?%$**%56NC61;I1FGU(#- .Fr6raceZdZUdZej dej ejZeje d<ej dZ e e d<y) RevocationzRevocation message. :ivar jose.ComparableX509 certificate: `OpenSSL.crypto.X509` wrapped in `jose.ComparableX509` certificater[reasonN) rJrYrZr[rHro decode_cert encode_certrfr_r_rgrbrhr6r4rereYsP (2tzzt//9I9I(KK$$K$**X&FC&r6receZdZUdZej ddZeee d<ej de jdZ e e d<ej ddZ eee d<ej ddZee d<ej d dZee d <ej$d dZej(e d <ej d dej Zee d <ej.d eeeefdeedffdZy)Ordera_Order Resource Body. :ivar identifiers: List of identifiers for the certificate. :vartype identifiers: `list` of `.Identifier` :ivar acme.messages.Status status: :ivar authorizations: URLs of authorizations. :vartype authorizations: `list` of `str` :ivar str certificate: URL to download certificate as a fullchain PEM. :ivar str finalize: URL to POST to to request issuance once all authorizations have "valid" status. :ivar datetime.datetime expires: When the order expires. :ivar ~.Error error: Any error that occurred during finalization, if applicable. identifiersTrurrxauthorizationsrffinalizerMrrrnr..c&td|DS)Nc3FK|]}tj|ywr=)rkrM)r|rws r4r~z$Order.identifiers..sN*Z))*5Nrrrs r4rlzOrder.identifiers}sNNNNr6N)rJrYrZr[rHrorlrrkr_rrMrrmr^rfrnrrErMrFr1rrmrrr rhr6r4rkrkes  %/DJJ}$MKj!MTZZ&2B2BdSFFS * +;t LNDIL!tzz-4@K@DJJzT:Hc:!/ T!JGX  J4::guOE5OO4S#X/OE*c/4JOOr6rkcxeZdZUdZej dejZee d<ej ddddZ e e d<ej d Z e ee d <ej d d Zee d <ej d d Ze ee d <e j$d e eeefdeedffdZ y) OrderResourceaOrder Resource. :ivar acme.messages.Order body: :ivar bytes csr_pem: The CSR this Order will be finalized with. :ivar authorizations: Fully-fetched AuthorizationResource objects. :vartype authorizations: `list` of `acme.messages.AuthorizationResource` :ivar str fullchain_pem: The fetched contents of the certificate URL produced once the order was finalized, if it's present. :ivar alternative_fullchains_pem: The fetched contents of alternative certificate chain URLs produced once the order was finalized, if present and requested during finalization. :vartype alternative_fullchains_pem: `list` of `str` rrlcsr_pemTc$|jdSNzutf-8r)ss r4rzOrderResource.!((72Cr6c$|jdSru)r)bs r4rzOrderResource.rwr6)rrrmr\rm fullchain_pemrualternative_fullchains_pemrnr..c&td|DS)Nc3FK|]}tj|ywr=)rVrM)r|authzs r4r~z/OrderResource.authorizations..sO*44U;Orrrs r4rmzOrderResource.authorizationssOOOOr6N)rJrYrZr[rHrorkrMrr_rsbytesrmrrVrzr^r{rmrrr rhr6r4rrrrs $**VU__=D%=TZZ T)D(C EGU E3=$**=M2NND./N#OtDM3D,6DJJ7SAE-GS G Pd4S>2Pu=RTW=W7XPPr6rrceZdZdZy)NewOrderz New order.Nrrhr6r4rrsr6r)Fr[collections.abcrrFrtypingrrrrrr r r r r josepyrHacmerrrrrr3rrr BaseExceptionrar5JSONDeSerializabler8rfIDENTIFIER_FQDN IDENTIFIER_IPrrkr1rSTATUS_UNKNOWNrDSTATUS_PROCESSING STATUS_VALIDSTATUS_INVALIDSTATUS_REVOKED STATUS_READYSTATUS_DEACTIVATEDrrrrrrrr-r/r1r4rHrLrRrTrVrYrarerkrrr)r:descs00r4rs$ !, Q B  C  T X_  T N D X!$G%&<'(4)*U+,dA@ J?\?FM= B0;0A0A0C",$L4 }1''1:.Y. !'t$ %**%TD % %v||Tn.Y.  " "<(g  " "g M*4''4n.t((.!h!4,,%%&3>Jj7<j7Zl K? K>1L>1B   HLH6} - COCc22c G/ G '** 'OLO:#PO#PLu[sJ7