Ë
    ãß²jeB  ã                  ó  — d Z ddlmZ ddlZddlZddlZddlmZmZ ddlm	Z	 ddl
mZmZ ddlmZ ddlmZ  ej"                  e«      Zd	Zd
ZdZ e	d¬«       G d„ d«      «       Zd)d„Zd„ Zd*d„Zd+d„Zd,d„Zd-d„Zd-d„Zd-d„Zd.d/d„Z d0d„Z!d1d„Z"	 	 d2	 	 	 	 	 	 	 d3d„Z#	 	 d2	 	 	 	 	 	 	 d4d„Z$ddl%m&Z& ddl%m&Z& dZ'	 d5	 	 	 	 	 d6d„Z(	 	 d2	 	 	 	 	 	 	 d7d „Z)d!Z*d"Z+d#Z,d0d$„Z-	 	 d2	 	 	 	 	 	 	 	 	 d8d%„Z.d1d&„Z/d1d'„Z0	 d5	 	 	 	 	 d9d(„Z1y):zIGeneric managed-tool gateway helpers for Nous-hosted vendor passthroughs.é    )ÚannotationsN)ÚdatetimeÚtimezone)Ú	dataclass)ÚCallableÚOptional©Úget_hermes_home)Úmanaged_nous_tools_enabledznousresearch.comÚhttpséx   T)Úfrozenc                  ó6   — e Zd ZU ded<   ded<   ded<   ded<   y)ÚManagedToolGatewayConfigÚstrÚvendorÚgateway_originÚnous_user_tokenÚboolÚmanaged_modeN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__© ó    ú?/home/ubuntu/.hermes/hermes-agent/tools/managed_tool_gateway.pyr   r      s   … àƒKØÓØÓØÔr   r   c                óf   — t        | t        «      r | j                  «       r| j                  «       S dS )z:*value* stripped when it is a non-blank string, else None.N)Ú
isinstancer   Ústrip)Úvalues    r   Ú_cleanr"      s$   € ä& u¬cÔ2°u·{±{´}ˆ5�;‰;‹=ÐNÈ$ÐNr   c                 ó   — t        «       dz  S )zDReturn the Hermes auth store path, respecting HERMES_HOME overrides.z	auth.jsonr	   r   r   r   Úauth_json_pathr$   #   s   € äÓ˜{Ñ*Ð*r   c                 ó”   — 	 ddl m}   | d«      }t        |t        «      syddlm}m}  ||«      r |«       sy|S # t        $ r Y yw xY w)aU  The profile's Nous state, or None. A free-tier identity counts only while the free tier is on:
    with ``nous.guest: false`` it is invisible here, so no cached or refreshed token of it is ever
    attached to a request.

    Resolves through the same profile-then-global-root fallback every other credential reader
    uses: a profile created with ``share_auth`` has no ``auth.json`` of its own and signs in with
    the root identity. Reading only ``HERMES_HOME/auth.json`` made that profile look signed out to
    the connector gate alone, so ``manage_connections`` vanished from its tool list.r   )Úget_provider_auth_stateÚnousN)Úguest_enabledÚis_guest_state)Úhermes_cli.authr&   r   ÚdictÚhermes_cli.anon_authr(   r)   Ú	Exception)r&   Únous_providerr(   r)   s       r   Ú_read_nous_provider_stater/   (   sK   € ðÝ;á/°Ó7ˆÜ˜-¬Ô.ØßFá˜-Ô(±´ØØÐøÜò Ùðús   ‚; ¡; ¹; »	AÁAc                ó0  — t        | «      }|€y 	 t        j                  |j                  d«      r|d d dz   n|«      }|j
                  �|n|j                  t        j                  ¬«      j                  t        j                  «      S # t        $ r Y y w xY w)NÚZéÿÿÿÿz+00:00)Útzinfo)
r"   r   ÚfromisoformatÚendswithÚ
ValueErrorr3   Úreplacer   ÚutcÚ
astimezone)r!   Ú
normalizedÚparseds      r   Ú_parse_timestampr<   @   s�   € Ü˜“€JØÐØðÜ×'Ñ'Àj×FYÑFYÐZ]ÔF^¨
°3°B¨¸(Ò(BÐdnÓoˆð —m‘mÐ/‰F°V·^±^Ì8Ï<É<°^Ó5X×dÑdÔem×eqÑeqÓrÐrøô ò Ùðús   �.B	 Â		BÂBc                ó¸   — t        | «      }|d u xsJ |t        j                  t        j                  «      z
  j                  «       t        dt        |«      «      k  S )Nr   )r<   r   Únowr   r8   Útotal_secondsÚmaxÚint)Ú
expires_atÚskew_secondsÚexpiress      r   Ú_access_token_is_expiringrE   K   sK   € Ü˜zÓ*€GØ�dˆ?Òq˜w¬¯©´h·l±lÓ)CÑC×RÑRÓTÔX[Ð\]Ô_bÐcoÓ_pÓXqÑqÐqr   c                 óØ   — 	 ddl m} m} 	  |d«      }t        |«      S # | $ r t        j                  d«      }Y Œ'w xY w# t
        $ r" t        j                  d«      }Y t        |«      S w xY w)zÙRead the TOOL_GATEWAY_USER_TOKEN override through the secret scope. Scope verdict is authoritative
    when installed (a scoped miss must NOT borrow the process env under multiplex); ``os.environ`` only when unscoped.r   )ÚUnscopedSecretErrorÚ
get_secretÚTOOL_GATEWAY_USER_TOKEN)Úagent.secret_scoperG   rH   ÚosÚgetenvr-   r"   )rG   rH   Úexplicits      r   Ú_read_user_token_overriderN   P   so   € ð8ßFð	<Ù!Ð";Ó<ˆHô
 �(ÓÐøð	 #ò 	<Ü—y‘yÐ!:Ó;ŠHð	<ûäò 8Ü—9‘9Ð6Ó7‰Ü�(ÓÐð8ús#   ‚> ‹ ž;¸> º;»> ¾A)Á(A)c                 óf   — t        «       xs& t        t        «       xs i j                  d«      «      S )uÈ   Cheap token probe: env override or cached auth-store token, no expiry check and no network â€”
    availability scans must stay off the synchronous OAuth refresh path (:func:`read_nous_access_token`).Úaccess_token)rN   r"   r/   Úgetr   r   r   Úpeek_nous_access_tokenrR   _   s-   € ô %Ó&Òi¬&Ô2KÓ2MÒ2SÐQS×1XÑ1XÐYgÓ1hÓ*iÐir   c                 ó°  — t        «       x} r| S t        «       xs i }|syt        «       }|r!t        |j	                  d«      t
        «      s|S 	 ddlm} t         |t
        ¬«      «      x}r|S 	 |S # t        $ r[}ddl
m} t        ||«      r(t        |t        |j                  xs d«      «      cY d}~S t         j#                  d|«       Y d}~|S d}~ww xY w)	aª  Read a Nous Subscriber OAuth access token from auth store or env override.

    A read: with no Nous identity there is no bearer and the answer is None. The free-tier identity
    is created by the boot bootstrap (``hermes_cli.free_tier_bootstrap``), never on a token-read
    path (NS-845 Q1.2). A retired free-tier credential IS replaced here, once: that is the explicit
    dead-credential rule, shared with inference.
    NrB   r   ©Úresolve_nous_access_token©Úrefresh_skew_seconds)ÚAnonCredentialDeadÚanon_credential_deadz$Nous access token refresh failed: %s)rN   r/   rR   rE   rQ   Ú'_NOUS_ACCESS_TOKEN_REFRESH_SKEW_SECONDSr*   rU   r"   r-   r,   rX   r   Ú_replace_dead_guest_tokenr   ÚcodeÚloggerÚdebug)rM   r.   Úcached_tokenrU   Úrefreshed_tokenÚexcrX   s          r   Úread_nous_access_tokenrb   e   sÝ   € ô -Ó.Ð.€xÐ.ØˆÜ-Ó/Ò5°2€MÙØÜ)Ó+€LÙÔ5°m×6GÑ6GÈÓ6UÔW~ÔØÐðBÝ=ä$Ñ%>ÔT{Ô%|Ó}Ð}ˆ?Ð}Ø"Ð"ð ~ð Ðøô ò Bõ 	<ä�cÐ-Ô.Ü,¨]¼CÀÇÁÒ@bÐLbÓ<cÓdÕdÜ�‰Ð;¸S×AÐAØÐûðBús$   ÁA1 Á1	CÁ:4CÂ.CÂ4CÃCc                óú   — ddl m}m}m} ddlm}  ||| j                  d«      ¬«       ||k(  ry 	  |d¬«      €y t         |t        ¬«      «      S # t        $ r }t        j                  d	|«       Y d }~y d }~ww xY w)
Nr   )ÚANON_ACCOUNT_LOCKEDÚclear_dead_guestÚensure_portal_identityrT   Ú
anon_token)Ú
dead_tokenT)rM   rV   z@Nous free tier replacement after a retired credential failed: %s)r,   rd   re   rf   r*   rU   rQ   r"   rZ   r-   r]   r^   )Ú
dead_stater\   rd   re   rf   rU   ra   s          r   r[   r[   …   sr   € ßbÑbÝ9á�T j§n¡n°\Ó&BÕCàÐ"Ò"ØðÙ!¨4Ô0Ð8ØÜÑ/ÔElÔmÓnÐnøÜò Ü�‰ÐWÐY\Ô]Üûðús   ±	A »A Á	A:ÁA5Á5A:c                 ó˜   — t        j                  dd«      j                  «       j                  «       xs t        } | dvrt        d«      ‚| S )z,Return configured shared gateway URL scheme.ÚTOOL_GATEWAY_SCHEMEÚ >   Úhttpr   z-TOOL_GATEWAY_SCHEME must be 'http' or 'https')rK   rL   r    ÚlowerÚ_DEFAULT_TOOL_GATEWAY_SCHEMEr6   )Úschemes    r   Úget_tool_gateway_schemerq   –   sE   € ä�Y‰YÐ,¨bÓ1×7Ñ7Ó9×?Ñ?ÓAÒaÔEa€FØÐ&Ñ&ÜÐHÓIÐIØ€Mr   c                óL  — t        j                  | j                  «       j                  dd«      › d�d«      j	                  «       j                  d«      x}r|S t        j                  dd«      j	                  «       j	                  d«      xs t        }t        «       › d| › d|› �S )	z0Return the gateway origin for a specific vendor.Ú-Ú_Ú_GATEWAY_URLrl   ú/ÚTOOL_GATEWAY_DOMAINú://z	-gateway.)rK   rL   Úupperr7   r    ÚrstripÚ_DEFAULT_TOOL_GATEWAY_DOMAINrq   )r   Úexplicit_vendor_urlÚshared_domains      r   Úbuild_vendor_gateway_urlr~   ž   s–   € ä Ÿi™i¨6¯<©<«>×+AÑ+AÀ#ÀsÓ+KÐ*LÈLÐ(YÐ[]Ó^×dÑdÓf×mÑmÐnqÓrÐrÐÐrØ"Ð"Ü—I‘IÐ3°RÓ8×>Ñ>Ó@×FÑFÀsÓKÒkÔOk€MÜ%Ó'Ð(¨¨F¨8°9¸]¸OÐLÐLr   c                ó~   — t        «       sy |xs t        | «      } |xs t        «       }|r|syt        | ||d¬«      S )z8Resolve shared managed-tool gateway config for a vendor.NT)r   r   r   r   )r   r~   rb   r   )r   Úgateway_builderÚtoken_readerr   r   s        r   Úresolve_managed_tool_gatewayr‚   ¦   sT   € ô &Ô'ØØA�oÒAÔ)AÀ6ÓJ€NØ=�|Ò=Ô'=Ó@€OÙ¡ØÜ#¨6À.Ðbqð  AEô  Fð  Fr   c                ó2   — t        | ||xs t        ¬«      duS )záTrue when a gateway URL and a likely-usable Nous token are present. Defaults to
    :func:`peek_nous_access_token` (no OAuth refresh); callers about to make a real request use
    :func:`resolve_managed_tool_gateway` instead.)r€   r�   N)r‚   rR   )r   r€   r�   s      r   Úis_managed_tool_gateway_readyr„   ³   s5   € ô (¨ÀÐ^jò  _Eô  oEô  Fð  NRð  Rð  Rr   )ÚurlsplitÚtoolc                ód  — t        | t        «      r| j                  «       sy|xs t        }	 t	         |t
        «      «      }t	        | j                  «       «      }t        |j                  «      xr1 |j                  |j                  f|j                  |j                  fk(  S # t        $ r Y yw xY w)u  True when ``url`` is on the Nous tool-gateway origin this client builds.

    Anything granting a URL extra trust â€” our bearer, reading files off disk to
    upload â€” must gate on this rather than on a name, so an arbitrary URL can
    never inherit that trust.
    F)
r   r   r    r~   r…   Ú_MANAGED_GATEWAY_VENDORr6   r   rp   Únetloc)Úurlr€   ÚbuilderÚexpectedÚactuals        r   Úis_managed_nous_gateway_urlrŽ   Å   s•   € ô �cœ3Ô s§y¡y¤{ØàÒ9Ô!9€GðÜ™GÔ$;Ó<Ó=ˆÜ˜#Ÿ)™)›+Ó&ˆô �—‘ÓÒg F§M¡M°6·=±=Ð#AÀhÇoÁoÐW_×WfÑWfÐEgÑ#gÐgøô ò Ùðús   ­.B# Â#	B/Â.B/c                ó  — t        | |«      si S |xs t        }	  |«       }t        |t        «      r|j                  «       si S dd|j                  «       › �iS # t        $ r#}t        j	                  d| |«       i cY d}~S d}~ww xY w)a‰  Live auth headers for a managed gateway URL, or ``{}`` when not managed.

    Read fresh on every call rather than cached: a Nous access token expires
    within the hour, and a long session would otherwise keep presenting a dead
    bearer. Returns ``{}`` rather than raising when no token is available, so a
    caller can report "sign in" instead of sending an unauthenticated request.
    z,Managed gateway token read failed for %s: %sNÚAuthorizationzBearer )rŽ   rb   r-   r]   r^   r   r   r    )rŠ   r€   r�   Úresolved_token_readerÚtokenra   s         r   Úmanaged_gateway_auth_headersr“   Û   s…   € ô ' s¨OÔ<Øˆ	à(ÒBÔ,BÐðÙ%Ó'ˆô �eœSÔ!¨¯©¬Øˆ	à˜w u§{¡{£} oÐ6Ð7Ð7øô ò Ü�‰ÐCÀSÈ#ÔNØ�	ûðús   šA Á	BÁ!A?Á9BÁ?Bg      .@g      N@g     Àr@c                ó  — 	 | j                  «       }|j                  di «      j                  d«      }t        |t        «      r |j	                  «       r|j	                  «       S d| j                  › d�S # t
        $ r Y Œw xY w)a
  A model-actionable reason from a gateway refusal, or a generic one.

    The gateway's 4xx bodies carry deliberate guidance (rate-limit waits, size
    caps, "you could not submit anyway"), so surface `error.message` verbatim
    rather than a bare status code.
    ÚerrorÚmessagez%the gateway refused the upload (HTTP ú))ÚjsonrQ   r   r   r    r-   Ústatus_code)ÚresponseÚpayloadr–   s      r   Ú_describe_media_upload_refusalrœ   û   sw   € ðØ—-‘-“/ˆØ—+‘+˜g rÓ*×.Ñ.¨yÓ9ˆÜ�gœsÔ#¨¯©¬Ø—=‘=“?Ð"ð 3°8×3GÑ3GÐ2HÈÐJÐJøô ò Ùðús   ‚A A3 Á3	A?Á>A?c                ó  ‡ ‡‡‡— t        ‰ ‰«      syt        |t        «      r|j                  d«      syt	        t        ‰ «      j                  «       «      }|j                  › d|j                  › �}|› |› �Šdˆˆˆ ˆfd„}|S )u×  Async ``(data, mime) -> argument value`` uploader for one managed vendor.

    Returns ``None`` when there is no usable upload endpoint (not a managed
    Nous URL, or no ``upload_path``); callers then refuse local paths with a
    clear message instead of silently forwarding them.

    The three steps of the protocol:

    1. POST ``origin + upload_path`` with the declared content type and exact
       byte length, using the same live auth headers as the vendor calls.
       The gateway answers with a presigned single-object PUT URL (short
       expiry; type and length are signed into it) and an upload token.
    2. PUT the bytes to that URL. This goes directly to storage â€” never
       through the gateway â€” which is what removes the request-size ceiling.
    3. Return ``nous-upload:<token>`` for the tool argument. The token is
       bound to this Nous principal and is redeemable only through the
       gateway, so it is inert anywhere else it might end up.
    Nrv   rx   c           	   “  ó(  •K  — dd l }ddlm} t        ‰‰‰«      }|st	        d«      ‚|j                  t        «      }|j                  |¬«      4 ƒd {  –—† }|j                  ‰||t        | «      dœ¬«      ƒ d {  –—† }d d d «      ƒd {  –—†  j                  dk7  rt	        t        |«      «      ‚	 |j                  «       }t        |t        «      r|j!                  d«      nd }	t        |t        «      r|j!                  d	«      nd }
t        |	t"        «      r|	rt        |
t"        «      r|
st	        d
«      ‚|j                  t        t$        t&        ¬«      } ||¬«      4 ƒd {  –—† }|j)                  |	| d|i¬«      ƒ d {  –—† }d d d «      ƒd {  –—†  j                  dk7  rt	        d|j                  › d�«      ‚d|
› �S 7 �Œs7 �ŒN7 �ŒA# 1 ƒd {  –—†7  sw Y   �ŒRxY w# t        $ r d }Y �Œ/w xY w7 Œ�7 Œt7 Œf# 1 ƒd {  –—†7  sw Y   ŒvxY w­w)Nr   )Úcreate_ssrf_safe_async_clientz.no Nous credential is available for the upload)Útimeout)ÚcontentTypeÚcontentLength)Úheadersr˜   éÈ   Ú	uploadUrlr’   z+the gateway's upload response was malformed)ÚreadÚwritezContent-Type)Úcontentr£   z!storage refused the upload (HTTP r—   znous-upload:)ÚhttpxÚtools.url_safetyrŸ   r“   ÚRuntimeErrorÚTimeoutÚ%_MEDIA_UPLOAD_PRESIGN_TIMEOUT_SECONDSÚAsyncClientÚpostÚlenr™   rœ   r˜   r-   r   r+   rQ   r   Ú&_MEDIA_UPLOAD_PUT_READ_TIMEOUT_SECONDSÚ'_MEDIA_UPLOAD_PUT_WRITE_TIMEOUT_SECONDSÚput)ÚdataÚmimer©   rŸ   r£   Úpresign_timeoutÚclientÚpresignr›   Ú
upload_urlr’   Úput_timeoutr³   r€   Úpresign_urlÚ
server_urlr�   s                €€€€r   Úuploadz,build_managed_media_uploader.<locals>.upload,  s
  øè ø€ ÛåBä.¨z¸?ÈLÓYˆÙÜÐOÓPÐPð  Ÿ-™-Ô(MÓNˆØ×$Ñ$¨_Ð$Ó=÷ 	ð 	ÀØ"ŸK™KØØØ%)¼CÀ»IÑFð (ó ÷ ˆG÷	÷ 	ð ×Ñ #Ò%ÜÔ=¸gÓFÓGÐGð	Ø—l‘l“nˆGô 2<¸GÄTÔ1J�W—[‘[ Ô-ÐPTˆ
Ü(2°7¼DÔ(A�—‘˜GÔ$ÀtˆÜ˜:¤sÔ+±
¼zÈ%ÔQTÔ?UÑZ_ÜÐLÓMÐMà—m‘mÜ1Ü7Ü9ð $ó 
ˆñ
 1¸ÔE÷ 	]ð 	]Èð Ÿ
™
 :°tÀnÐVZÐE[˜
Ó\×\ˆC÷	]÷ 	]ð �?‰?˜cÒ!ÜÐ!BÀ3Ç?Á?ÐBSÐSTÐUÓVÐVà˜e˜WÐ%Ð%ð=	ùðùð	ù÷ 	÷ 	ò 	ûô ò 	Ø‹Gð	úð	]øð ]øð	]ø÷ 	]÷ 	]ñ 	]üsÓ   ƒAHÁGÁHÁ$GÁ;G	Á<GÂ HÂGÂ'HÂ4G% ÃB"HÅ&G7Å'HÅ*G=ÆG9ÆG=Æ	HÆG;Æ2HÇ	GÇHÇG"ÇGÇG"ÇHÇ%G4Ç0HÇ3G4Ç4HÇ9G=Ç;HÇ=HÈHÈHÈH)r´   Úbytesrµ   r   Úreturnr   )rŽ   r   r   Ú
startswithr…   r    rp   r‰   )r¼   Úupload_pathr€   r�   ÚpartsÚoriginr½   r»   s   ` ``   @r   Úbuild_managed_media_uploaderrÄ     s{   û€ ô0 ' z°?ÔCØÜ�k¤3Ô'¨{×/EÑ/EÀcÔ/JØä”S˜“_×*Ñ*Ó,Ó-€EØ—‘ˆ~˜S §¡ Ð/€FØ�H˜[˜MÐ*€K÷2&ð 2&ðh €Mr   c                ó   — d| › �S )zABase path for a managed vendor's REST routes on the gateway host.z/api/r   ©r   s    r   Úmanaged_vendor_base_pathrÇ   b  s   € à�6�(ÐÐr   c                ó   — d| › �S )z=Media upload endpoint for a managed vendor, on the same host.z/api/uploads/r   rÆ   s    r   Úmanaged_vendor_upload_pathrÉ   f  s   € à˜6˜(Ð#Ð#r   c                óª   — |xs t         }	  |t        «      j                  d«      }|sy||› t	        | «      › �t        | «      dœS # t        $ r Y yw xY w)uD  Absolute URLs for a managed vendor, or ``None`` when none resolves.

    Address resolution only: entitlement is deliberately not consulted here.
    What an account may spend on a managed vendor is the gateway's own
    decision, stated in its refusals, and re-deciding it on the client can only
    ever disagree with the server. A caller that wants to hide its tools from
    users who could not call them at all does that in its ``check_fn``.

    ``None`` means no origin could be resolved â€” a misconfigured
    ``TOOL_GATEWAY_SCHEME`` â€” so there is nothing to call.
    rv   N)rÃ   Úbase_urlrÁ   )r~   rˆ   rz   r6   rÇ   rÉ   )r   r€   r‹   rÃ   s       r   Úmanaged_vendor_endpointsrÌ   j  sp   € ð Ò9Ô!9€GðÙÔ0Ó1×8Ñ8¸Ó=ˆñ Øð Ø�hÔ7¸Ó?Ð@ÐAÜ1°&Ó9ñð øô ò Ùðús   ŒA Á	AÁA)r!   Úobjectr¿   úOptional[str])r¿   úOptional[dict])r!   rÍ   r¿   zOptional[datetime])rB   rÍ   rC   rA   r¿   r   )r¿   rÎ   )rY   )ri   r+   r\   r   r¿   rÎ   )r¿   r   )r   r   r¿   r   )NN)r   r   r€   úOptional[Callable[[str], str]]r�   ú%Optional[Callable[[], Optional[str]]]r¿   z"Optional[ManagedToolGatewayConfig])r   r   r€   rÐ   r�   rÑ   r¿   r   )N)rŠ   rÍ   r€   rÐ   r¿   r   )rŠ   rÍ   r€   rÐ   r�   rÑ   r¿   r+   )
r¼   rÍ   rÁ   rÍ   r€   rÐ   r�   rÑ   r¿   zOptional[Callable])r   r   r€   rÐ   r¿   rÏ   )2Ú__doc__Ú
__future__r   r˜   ÚloggingrK   r   r   Údataclassesr   Útypingr   r   Úhermes_constantsr
   Útools.tool_backend_helpersr   Ú	getLoggerr   r]   r{   ro   rZ   r   r"   r$   r/   r<   rE   rN   rR   rb   r[   rq   r~   r‚   r„   Úurllib.parser…   rˆ   rŽ   r“   r­   r±   r²   rœ   rÄ   rÇ   rÉ   rÌ   r   r   r   ú<module>rÛ      sû  ðÙ Oå "ã Û Û 	ß 'Ý !ß %å ,Ý Aà	ˆ×	Ñ	˜8Ó	$€à1Ð Ø&Ð Ø*-Ð 'ñ �$Ô÷ð ó ðóOò
+ó
ó0sóró
ójóô@ó"óMð DHØ:>ð
FØð
FØ"@ð
Fà7ð
FàCeó
Fð DHØ:>ðRØðRØ"@ðRà7ðRàCGóRõ "Ý !à Ð ð 7;ðhØ	ðhà3ðhð 
óhð0 7;Ø:>ð8Ø	ð8à3ð8ð 8ð8ð 
ó	8ð4 )-Ð %à)-Ð &à*/Ð 'óKð& 7;Ø:>ð	UØðUàðUð 4ðUð 8ð	Uð
 óUónó$ð 7;ðØðà3ðð ôr   