§
    …ßj5  ã                   ób  — d Z ddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZ  G d„ de¦  «        Z G d„ d	e¦  «        Z G d
„ de¦  «        Z G d„ d¦  «        Z G d„ d¦  «        Z ej        ¦   «         Zdad„ Zd„ Zd„ Zd„ Zdd„Zd„ Zdd„Z d„ Z!d„ Z"d„ Z#dd„Z$d„ Z%d„ Z&d„ Z'dS )aL  
Stash - Global Shared State for Dirty Workers

Provides simple key-value tables stored in the arbiter process.
All workers can read and write to the same tables.

Usage::

    from gunicorn.dirty import stash

    # Basic operations - table is auto-created on first access
    stash.put("sessions", "user:1", {"name": "Alice", "role": "admin"})
    user = stash.get("sessions", "user:1")
    stash.delete("sessions", "user:1")

    # Dict-like interface
    sessions = stash.table("sessions")
    sessions["user:1"] = {"name": "Alice"}
    user = sessions["user:1"]
    del sessions["user:1"]

    # Query operations
    keys = stash.keys("sessions")
    keys = stash.keys("sessions", pattern="user:*")

    # Table management
    stash.ensure("cache")           # Explicit creation (idempotent)
    stash.clear("sessions")         # Delete all entries
    stash.delete_table("sessions")  # Delete the table itself
    tables = stash.tables()         # List all tables

Declarative usage in DirtyApp::

    class MyApp(DirtyApp):
        stashes = ["sessions", "cache"]  # Auto-created on arbiter start

        def __call__(self, action, *args, **kwargs):
            # Tables are ready to use
            stash.put("sessions", "key", "value")

Note: Tables are stored in the arbiter process and are ephemeral.
If the arbiter restarts, all data is lost.
é    Né   )Ú
DirtyError)ÚDirtyProtocolÚSTASH_OP_PUTÚSTASH_OP_GETÚSTASH_OP_DELETEÚSTASH_OP_KEYSÚSTASH_OP_CLEARÚSTASH_OP_INFOÚSTASH_OP_ENSUREÚSTASH_OP_DELETE_TABLEÚSTASH_OP_TABLESÚSTASH_OP_EXISTSÚmake_stash_messagec                   ó   — e Zd ZdZdS )Ú
StashErrorz$Base exception for stash operations.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    úG/var/www/html/venv/lib/python3.11/site-packages/gunicorn/dirty/stash.pyr   r   E   s   € € € € € Ø.Ð.Ð.Ð.r   r   c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )ÚStashTableNotFoundErrorz#Raised when a table does not exist.c                 ó^   •— || _         t          ¦   «                              d|› �¦  «         d S )NzStash table not found: )Ú
table_nameÚsuperÚ__init__)Úselfr   Ú	__class__s     €r   r   z StashTableNotFoundError.__init__L   s1   ø€ Ø$ˆŒÝ‰Œ×ÒÐ?°:Ð?Ð?Ñ@Ô@Ð@Ð@Ð@r   ©r   r   r   r   r   Ú__classcell__©r!   s   @r   r   r   I   sG   ø€ € € € € Ø-Ð-ðAð Að Að Að Að Að Að Að Ar   r   c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )ÚStashKeyNotFoundErrorz,Raised when a key does not exist in a table.c                 ór   •— || _         || _        t          ¦   «                              d|› d|› �¦  «         d S )NzKey not found in z: )r   Úkeyr   r   )r    r   r(   r!   s      €r   r   zStashKeyNotFoundError.__init__T   s@   ø€ Ø$ˆŒØˆŒÝ‰Œ×ÒÐ@¨ZÐ@Ð@¸3Ð@Ð@ÑAÔAÐAÐAÐAr   r"   r$   s   @r   r&   r&   Q   sG   ø€ € € € € Ø6Ð6ðBð Bð Bð Bð Bð Bð Bð Bð Br   r&   c                   óŽ   — e Zd ZdZdd„Zd„ Zd„ Zd„ Zdd„Zd	„ Z	dd
„Z
d„ Zdd„Zd„ Zd„ Zd„ Zdd„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ ZdS )ÚStashClientzl
    Client for stash operations.

    Communicates with the arbiter which stores all tables in memory.
    ç      >@c                 ó`   — || _         || _        d| _        t          j        ¦   «         | _        dS )z½
        Initialize the stash client.

        Args:
            socket_path: Path to the dirty arbiter's Unix socket
            timeout: Default timeout for operations in seconds
        N)Úsocket_pathÚtimeoutÚ_sockÚ	threadingÚLockÚ_lock)r    r-   r.   s      r   r   zStashClient.__init__a   s-   € ð 'ˆÔØˆŒØˆŒ
Ý”^Ñ%Ô%ˆŒ
ˆ
ˆ
r   c                 óB   — t          t          j        ¦   «         ¦  «        S )zGenerate a unique request ID.)ÚstrÚuuidÚuuid4©r    s    r   Ú_get_request_idzStashClient._get_request_idn   s   € å•4”:‘<”<Ñ Ô Ð r   c                 óN  — ddl }| j        �dS 	 |                      |j        |j        ¦  «        | _        | j                             | j        ¦  «         | j                             | j        ¦  «         dS # |j        t          f$ r}d| _        t          d|› �¦  «        |‚d}~ww xY w)z Establish connection to arbiter.r   NzFailed to connect to arbiter: )Úsocketr/   ÚAF_UNIXÚSOCK_STREAMÚ
settimeoutr.   Úconnectr-   ÚerrorÚOSErrorr   )r    r:   Úes      r   Ú_connectzStashClient._connectr   s¹   € àˆˆˆØŒ:Ð!ØˆFð	JØŸš v¤~°vÔ7IÑJÔJˆDŒJØŒJ×!Ò! $¤,Ñ/Ô/Ð/ØŒJ×Ò˜tÔ/Ñ0Ô0Ð0Ð0Ð0øØ”�gÐ&ð 	Jð 	Jð 	JØˆDŒJÝÐA¸aÐAÐAÑBÔBÈÐIøøøøð	Jøøøs   �A#A4 Á4B$ÂBÂB$c                 ó|   — | j         �4	 | j                              ¦   «          n# t          $ r Y nw xY wd| _         dS dS )zClose the connection.N)r/   ÚcloseÚ	Exceptionr7   s    r   Ú_closezStashClient._close€   sY   € àŒ:Ð!ðØ”
× Ò Ñ"Ô"Ð"Ð"øÝð ð ð Ø�ðøøøàˆDŒJˆJˆJð "Ð!s   ‰# £
0¯0Nc           	      ó‚  — | j         5  | j        €|                      ¦   «          |                      ¦   «         }t	          ||||||¬¦  «        }	 t          j        | j        |¦  «         t          j        | j        ¦  «        }|                     d¦  «        }	|	t
          j	        k    r!|                     d¦  «        cddd¦  «         S |	t
          j
        k    r||                     di ¦  «        }
|
                     dd¦  «        }|
                     dd	¦  «        }|d
k    rt          |¦  «        ‚|dk    rt          ||¦  «        ‚t          |¦  «        ‚t          d|	› �¦  «        ‚# t          $ rB}|                      ¦   «          t!          |t          ¦  «        r‚ t          d|› �¦  «        |‚d}~ww xY w# 1 swxY w Y   dS )a6  
        Execute a stash operation.

        Args:
            op: Operation code (STASH_OP_*)
            table: Table name
            key: Optional key
            value: Optional value
            pattern: Optional pattern for keys operation

        Returns:
            Result from the operation
        N)r(   ÚvalueÚpatternÚtypeÚresultr?   Ú
error_typer   ÚmessagezUnknown errorr   r&   zUnexpected response type: zStash operation failed: )r2   r/   rB   r8   r   r   Úwrite_messageÚread_messageÚgetÚMSG_TYPE_RESPONSEÚMSG_TYPE_ERRORr   r&   r   rE   rF   Ú
isinstance)r    ÚopÚtabler(   rH   rI   Ú
request_idrM   ÚresponseÚmsg_typeÚ
error_inforL   Ú	error_msgrA   s                 r   Ú_executezStashClient._execute‰   s)  € ð ŒZð "	Hð "	HØŒzÐ!Ø—’‘”�à×-Ò-Ñ/Ô/ˆJÝ(Ø˜B Ø˜u¨gðñ ô ˆGð
HÝÔ+¨D¬J¸Ñ@Ô@Ð@Ý(Ô5°d´jÑAÔA�à#Ÿ<š<¨Ñ/Ô/�Ø�}Ô>Ò>Ð>Ø#Ÿ<š<¨Ñ1Ô1ð!"	Hð "	Hð "	Hð "	Hñ "	Hô "	Hð "	Hð "	Hð" ¥Ô!=Ò=Ð=Ø!)§¢¨g°rÑ!:Ô!:�JØ!+§¢°¸lÑ!KÔ!K�JØ *§¢¨y¸/Ñ JÔ J�Ià!Ð%>Ò>Ð>Ý5°eÑ<Ô<Ð<Ø!Ð%<Ò<Ð<Ý3°E¸3Ñ?Ô?Ð?Ý$ YÑ/Ô/Ð/å$Ð%LÀ(Ð%LÐ%LÑMÔMÐMøåð Hð Hð HØ—’‘”�Ý˜a¥Ñ,Ô,ð ØÝ Ð!?¸AÐ!?Ð!?Ñ@Ô@ÀaÐGøøøøð	Høøøð="	Hð "	Hð "	Hð "	Høøøð "	Hð "	Hð "	Hð "	Hð "	Hð "	Hs8   ˆAF4ÁA,E%ÃBE%Å%
F1Å/=F,Æ,F1Æ1F4Æ4F8Æ;F8c                 óB   — |                       t          |||¬¦  «         dS )zö
        Store a value in a table.

        The table is automatically created if it doesn't exist.

        Args:
            table: Table name
            key: Key to store under
            value: Value to store (must be serializable)
        )r(   rH   N)r[   r   )r    rU   r(   rH   s       r   ÚputzStashClient.put¿   s$   € ð 	�Š•l E¨s¸%ˆÑ@Ô@Ð@Ð@Ð@r   c                 ób   — 	 |                       t          ||¬¦  «        S # t          $ r |cY S w xY w)zú
        Retrieve a value from a table.

        Args:
            table: Table name
            key: Key to retrieve
            default: Default value if key not found

        Returns:
            The stored value, or default if not found
        ©r(   )r[   r   r&   )r    rU   r(   Údefaults       r   rP   zStashClient.getÌ   sC   € ð	Ø—=’=¥¨u¸#�=Ñ>Ô>Ð>øÝ$ð 	ð 	ð 	ØˆNˆNˆNð	øøøs   ‚ Ÿ.­.c                 ó<   — |                       t          ||¬¦  «        S )zÈ
        Delete a key from a table.

        Args:
            table: Table name
            key: Key to delete

        Returns:
            True if key was deleted, False if it didn't exist
        r_   )r[   r   ©r    rU   r(   s      r   ÚdeletezStashClient.deleteÝ   ó   € ð �}Š}�_¨e¸ˆ}Ñ=Ô=Ð=r   c                 ó<   — |                       t          ||¬¦  «        S )zÞ
        Get all keys in a table, optionally filtered by pattern.

        Args:
            table: Table name
            pattern: Optional glob pattern (e.g., "user:*")

        Returns:
            List of keys
        ©rI   )r[   r	   )r    rU   rI   s      r   ÚkeyszStashClient.keysê   s   € ð �}Š}�]¨E¸7ˆ}ÑCÔCÐCr   c                 ó<   — |                       t          |¦  «         dS )z]
        Delete all entries in a table.

        Args:
            table: Table name
        N)r[   r
   ©r    rU   s     r   ÚclearzStashClient.clear÷   s   € ð 	�Š•n eÑ,Ô,Ð,Ð,Ð,r   c                 ó8   — |                       t          |¦  «        S )z�
        Get information about a table.

        Args:
            table: Table name

        Returns:
            Dict with table info (size, etc.)
        )r[   r   ri   s     r   ÚinfozStashClient.info   s   € ð �}Š}�]¨EÑ2Ô2Ð2r   c                 ó<   — |                       t          |¦  «         dS )z­
        Ensure a table exists (create if not exists).

        This is idempotent - calling it multiple times is safe.

        Args:
            table: Table name
        N)r[   r   ri   s     r   ÚensurezStashClient.ensure  s   € ð 	�Š•o uÑ-Ô-Ð-Ð-Ð-r   c                 ó<   — |                       t          ||¬¦  «        S )zÔ
        Check if a table or key exists.

        Args:
            table: Table name
            key: Optional key to check within the table

        Returns:
            True if exists, False otherwise
        r_   )r[   r   rb   s      r   ÚexistszStashClient.exists  rd   r   c                 ó<   — |                       t          |¦  «         dS )zV
        Delete an entire table.

        Args:
            table: Table name
        N)r[   r   ri   s     r   Údelete_tablezStashClient.delete_table$  s   € ð 	�ŠÕ+¨UÑ3Ô3Ð3Ð3Ð3r   c                 ó8   — |                       t          d¦  «        S )zT
        List all tables.

        Returns:
            List of table names
        Ú )r[   r   r7   s    r   ÚtableszStashClient.tables-  s   € ð �}Š}�_¨bÑ1Ô1Ð1r   c                 ó"   — t          | |¦  «        S )z•
        Get a dict-like interface to a table.

        Args:
            name: Table name

        Returns:
            StashTable instance
        )Ú
StashTable)r    Únames     r   rU   zStashClient.table6  s   € õ ˜$ Ñ%Ô%Ð%r   c                 ón   — | j         5  |                      ¦   «          ddd¦  «         dS # 1 swxY w Y   dS )zClose the client connection.N)r2   rF   r7   s    r   rD   zStashClient.closeB  s{   € àŒZð 	ð 	Ø�KŠK‰MŒMˆMð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s   ˆ*ª.±.c                 ó   — | S ©Nr   r7   s    r   Ú	__enter__zStashClient.__enter__G  s   € Øˆr   c                 ó.   — |                       ¦   «          d S r{   )rD   )r    Úexc_typeÚexc_valÚexc_tbs       r   Ú__exit__zStashClient.__exit__J  s   € Ø�
Š
‰Œˆˆˆr   )r+   )NNNr{   )r   r   r   r   r   r8   rB   rF   r[   r]   rP   rc   rg   rj   rl   rn   rp   rr   ru   rU   rD   r|   r�   r   r   r   r*   r*   Z   sc  € € € € € ðð ð&ð &ð &ð &ð!ð !ð !ðJð Jð Jðð ð ð0Hð 0Hð 0Hð 0HðlAð Að Aðð ð ð ð">ð >ð >ðDð Dð Dð Dð-ð -ð -ð
3ð 
3ð 
3ð	.ð 	.ð 	.ð>ð >ð >ð >ð4ð 4ð 4ð2ð 2ð 2ð
&ð 
&ð 
&ðð ð ð
ð ð ðð ð ð ð r   r*   c                   ót   — e Zd ZdZd„ Zed„ ¦   «         Zd„ Zd„ Zd„ Z	d„ Z
d„ Zd	„ Zdd„Zdd„Zd„ Zd„ Zd„ Zd
S )rw   a2  
    Dict-like interface to a stash table.

    Example::

        sessions = stash.table("sessions")
        sessions["user:1"] = {"name": "Alice"}
        user = sessions["user:1"]
        del sessions["user:1"]

        # Iteration
        for key in sessions:
            print(key, sessions[key])
    c                 ó"   — || _         || _        d S r{   )Ú_clientÚ_name)r    Úclientrx   s      r   r   zStashTable.__init__^  s   € ØˆŒØˆŒ
ˆ
ˆ
r   c                 ó   — | j         S )zTable name.)r…   r7   s    r   rx   zStashTable.nameb  s   € ð ŒzÐr   c                 ó¨   — | j                              | j        |¦  «        }|€/| j                              | j        |¦  «        st	          |¦  «        ‚|S r{   )r„   rP   r…   rp   ÚKeyError)r    r(   rK   s      r   Ú__getitem__zStashTable.__getitem__g  sM   € Ø”×!Ò! $¤*¨cÑ2Ô2ˆØˆ>à”<×&Ò& t¤z°3Ñ7Ô7ð $Ý˜s‘m”mÐ#Øˆr   c                 óH   — | j                              | j        ||¦  «         d S r{   )r„   r]   r…   )r    r(   rH   s      r   Ú__setitem__zStashTable.__setitem__o  s$   € ØŒ×Ò˜œ S¨%Ñ0Ô0Ð0Ð0Ð0r   c                 ód   — | j                              | j        |¦  «        st          |¦  «        ‚d S r{   )r„   rc   r…   r‰   ©r    r(   s     r   Ú__delitem__zStashTable.__delitem__r  s4   € ØŒ|×"Ò" 4¤:¨sÑ3Ô3ð 	 Ý˜3‘-”-Ðð	 ð 	 r   c                 óB   — | j                              | j        |¦  «        S r{   )r„   rp   r…   rŽ   s     r   Ú__contains__zStashTable.__contains__v  s   € ØŒ|×"Ò" 4¤:¨sÑ3Ô3Ð3r   c                 óZ   — t          | j                             | j        ¦  «        ¦  «        S r{   )Úiterr„   rg   r…   r7   s    r   Ú__iter__zStashTable.__iter__y  s"   € Ý�D”L×%Ò% d¤jÑ1Ô1Ñ2Ô2Ð2r   c                 ól   — | j                              | j        ¦  «        }|                     dd¦  «        S )NÚsizer   )r„   rl   r…   rP   )r    rl   s     r   Ú__len__zStashTable.__len__|  s-   € ØŒ|× Ò  ¤Ñ,Ô,ˆØ�xŠx˜ Ñ"Ô"Ð"r   Nc                 óD   — | j                              | j        ||¦  «        S )zGet value with default.)r„   rP   r…   )r    r(   r`   s      r   rP   zStashTable.get€  s   € àŒ|×Ò ¤
¨C°Ñ9Ô9Ð9r   c                 óD   — | j                              | j        |¬¦  «        S )z-Get all keys, optionally filtered by pattern.rf   )r„   rg   r…   )r    rI   s     r   rg   zStashTable.keys„  s   € àŒ|× Ò  ¤°WÐ Ñ=Ô=Ð=r   c                 óD   — | j                              | j        ¦  «         dS )zDelete all entries.N)r„   rj   r…   r7   s    r   rj   zStashTable.clearˆ  s    € àŒ×Ò˜4œ:Ñ&Ô&Ð&Ð&Ð&r   c              #   ó–   K  — | j                              | j        ¦  «        D ]&}|| j                              | j        |¦  «        fV — Œ'dS )z Iterate over (key, value) pairs.N©r„   rg   r…   rP   rŽ   s     r   ÚitemszStashTable.itemsŒ  sY   è è € à”<×$Ò$ T¤ZÑ0Ô0ð 	9ð 	9ˆCØ�t”|×'Ò'¨¬
°CÑ8Ô8Ð8Ð8Ð8Ð8Ð8ð	9ð 	9r   c              #   ó’   K  — | j                              | j        ¦  «        D ]$}| j                              | j        |¦  «        V — Œ%dS )zIterate over values.Nrœ   rŽ   s     r   ÚvalueszStashTable.values‘  sT   è è € à”<×$Ò$ T¤ZÑ0Ô0ð 	4ð 	4ˆCØ”,×"Ò" 4¤:¨sÑ3Ô3Ð3Ð3Ð3Ð3ð	4ð 	4r   r{   )r   r   r   r   r   Úpropertyrx   rŠ   rŒ   r�   r‘   r”   r—   rP   rg   rj   r�   rŸ   r   r   r   rw   rw   N  s÷   € € € € € ðð ðð ð ð ðð ñ „Xððð ð ð1ð 1ð 1ð ð  ð  ð4ð 4ð 4ð3ð 3ð 3ð#ð #ð #ð:ð :ð :ð :ð>ð >ð >ð >ð'ð 'ð 'ð9ð 9ð 9ð
4ð 4ð 4ð 4ð 4r   rw   c                 ó
   — | a dS )z@Set the global stash socket path (called during initialization).N)Ú_stash_socket_path)Úpaths    r   Úset_stash_socket_pathr¤   ¢  s   € ð ÐÐÐr   c                  ó€   — ddl } t          €-| j                             d¦  «        }|r|S t	          d¦  «        ‚t          S )zGet the stash socket path.r   NÚGUNICORN_DIRTY_SOCKETz\Stash socket path not configured. Make sure dirty_workers > 0 and dirty_apps are configured.)Úosr¢   ÚenvironrP   r   )r§   r£   s     r   Úget_stash_socket_pathr©   ¨  sR   € à€I€I€IÝÐ!àŒz�~Š~Ð5Ñ6Ô6ˆØð 	ØˆKÝðIñ
ô 
ð 	
õ Ðr   c                  óˆ   — t          t          dd¦  «        } | €)t          ¦   «         }t          |¦  «        } | t          _        | S )z*Get or create a thread-local stash client.Ústash_clientN)ÚgetattrÚ_thread_localr©   r*   r«   )r†   r-   s     r   Ú_get_clientr®   ·  s=   € å•] N°DÑ9Ô9€FØ€~Ý+Ñ-Ô-ˆÝ˜[Ñ)Ô)ˆØ%+�Ô"Ø€Mr   c                 óL   — t          ¦   «                              | ||¦  «         dS )zStore a value in a table.N)r®   r]   )rU   r(   rH   s      r   r]   r]   Ã  s$   € å�M„M×Ò�e˜S %Ñ(Ô(Ð(Ð(Ð(r   c                 óH   — t          ¦   «                              | ||¦  «        S )zRetrieve a value from a table.)r®   rP   )rU   r(   r`   s      r   rP   rP   È  s   € å‰=Œ=×Ò˜U C¨Ñ1Ô1Ð1r   c                 óF   — t          ¦   «                              | |¦  «        S )zDelete a key from a table.)r®   rc   ©rU   r(   s     r   rc   rc   Í  ó   € å‰=Œ=×Ò  sÑ+Ô+Ð+r   c                 óF   — t          ¦   «                              | |¦  «        S )zGet all keys in a table.)r®   rg   )rU   rI   s     r   rg   rg   Ò  s   € å‰=Œ=×Ò˜e WÑ-Ô-Ð-r   c                 óH   — t          ¦   «                              | ¦  «         dS )zDelete all entries in a table.N)r®   rj   ©rU   s    r   rj   rj   ×  s    € å�M„M×Ò˜ÑÔÐÐÐr   c                 óD   — t          ¦   «                              | ¦  «        S )zGet information about a table.)r®   rl   r¶   s    r   rl   rl   Ü  s   € å‰=Œ=×Ò˜eÑ$Ô$Ð$r   c                 óH   — t          ¦   «                              | ¦  «         dS )zEnsure a table exists.N)r®   rn   r¶   s    r   rn   rn   á  s    € å�M„M×Ò˜ÑÔÐÐÐr   c                 óF   — t          ¦   «                              | |¦  «        S )zCheck if a table or key exists.)r®   rp   r²   s     r   rp   rp   æ  r³   r   c                 óH   — t          ¦   «                              | ¦  «         dS )zDelete an entire table.N)r®   rr   r¶   s    r   rr   rr   ë  s    € å�M„M×Ò˜uÑ%Ô%Ð%Ð%Ð%r   c                  óB   — t          ¦   «                              ¦   «         S )zList all tables.)r®   ru   r   r   r   ru   ru   ð  s   € å‰=Œ=×ÒÑ!Ô!Ð!r   c                 óD   — t          ¦   «                              | ¦  «        S )z%Get a dict-like interface to a table.)r®   rU   )rx   s    r   rU   rU   õ  s   € å‰=Œ=×Ò˜tÑ$Ô$Ð$r   r{   )(r   r0   r5   Úerrorsr   Úprotocolr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r&   r*   rw   Úlocalr­   r¢   r¤   r©   r®   r]   rP   rc   rg   rj   rl   rn   rp   rr   ru   rU   r   r   r   ú<module>rÀ      s¹  ðð
*ð *ðX Ð Ð Ð Ø €€€à Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð /ð /ð /ð /ð /�ñ /ô /ð /ðAð Að Að Að A˜jñ Aô Að AðBð Bð Bð Bð B˜Jñ Bô Bð Bðqð qð qð qð qñ qô qð qðhF4ð F4ð F4ð F4ð F4ñ F4ô F4ð F4ð\  �	”Ñ!Ô!€ð Ð ðð ð ðð ð ðð ð ð)ð )ð )ð
2ð 2ð 2ð 2ð
,ð ,ð ,ð
.ð .ð .ð .ð
ð ð ð
%ð %ð %ð
 ð  ð  ð
,ð ,ð ,ð ,ð
&ð &ð &ð
"ð "ð "ð
%ð %ð %ð %ð %r   