U
    /Wj&—  ã                   @   s  d Z ddlmZmZ ddlmZ ddlmZ ddlmZm	Z
mZ ddlmZmZ ddlmZmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ eejƒG dd„ dƒƒZeejƒG dd„ dƒƒZdZ eej!ƒG dd„ dej"ƒƒZ#G dd„ dej$ƒZ%G dd„ dej&ƒZ'eej!ƒG dd„ dej(ƒƒZ)e *e'e)¡ G dd„ dej&ƒZ+eejƒG dd„ dej(ƒƒZ,e *e+e,¡ G dd„ dej&ƒZ-eej!ƒG dd „ d ej&ƒƒZ.ee.ejej/ƒ G d!d"„ d"ej(ƒZ0e *e.e0¡ eej1ej2ƒG d#d$„ d$ƒƒZ3G d%d&„ d&e3ƒZ4ddd$d&gZ5d'S )(a  
A module that needs a better name.

Implements new cred things for words.

How does this thing work?

  - Network connection on some port expecting to speak some protocol

  - Protocol-specific authentication, resulting in some kind of credentials object

  - twisted.cred.portal login using those credentials for the interface
    IUser and with something implementing IChatClient as the mind

  - successful login results in an IUser avatar the protocol can call
    methods on, and state added to the realm such that the mind will have
    methods called on it as is necessary

  - protocol specific actions lead to calls onto the avatar; remote events
    lead to calls onto the mind

  - protocol specific hangup, realm is notified, user is removed from active
    play, the end.
é    )ÚctimeÚtime)Úimplementer)Ú	copyright)ÚcredentialsÚerrorÚportal)ÚdeferÚprotocol)ÚfailureÚlogÚreflect)ÚregisterAdapter)Úpb)ÚewordsÚiwords)Úircc                   @   sV   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zdd
d„Zdd„ Zdd„ Z	dd„ Z
dd„ Zd	S )ÚGroupc                 C   s   || _ i | _dddœ| _d S )NÚ )ÚtopicÚtopic_author)ÚnameÚusersÚmeta©Úselfr   © r   ú`c:\users\psant\downloads\hotstarbackend\school\venv38\Lib\site-packages\twisted/words/service.pyÚ__init__.   s
    þzGroup.__init__c                 C   s   t  t||ƒ¡S ©N)r   ÚFailureÚ	Exception)r   ÚerrÚpr   r   r   Ú_ebUserCall6   s    zGroup._ebUserCallc                 C   s0   |D ]&\}}|s|j \}}|  || ¡ ¡ qd S r   )ÚvalueÚremoveÚgetErrorMessage)r   ÚresultsÚsuccessÚresultÚuserr"   r   r   r   Ú_cbUserCall9   s    
zGroup._cbUserCallc                 C   s”   t j |¡std |¡ƒ‚|j| jkrŠg }|| j|j< | j ¡ D ]6}||k	r@t 	|j
| |¡}|j| j|d� | |¡ q@t |¡ | j¡ t d ¡S )Nz{!r} is not a chat client©r#   )r   ÚIChatClientÚ
providedByÚAssertionErrorÚformatr   r   Úvaluesr	   ÚmaybeDeferredÚ
userJoinedÚ
addErrbackr$   ÚappendÚDeferredListÚaddCallbackr,   Úsucceed)r   r+   Ú	additionsr#   Údr   r   r   Úadd?   s    ÿz	Group.addNc                 C   sˆ   z| j |j= W n tk
r"   Y n\X g }| j  ¡ D ]8}||k	r2t |j| ||¡}|j| j|d� | 	|¡ q2t 
|¡ | j¡ t d ¡S ©Nr-   )r   r   ÚKeyErrorr2   r	   r3   ÚuserLeftr5   r$   r6   r7   r8   r,   r9   )r   r+   ÚreasonZremovalsr#   r;   r   r   r   r&   N   s    zGroup.removec                 C   s   t  t| jƒ¡S r   )r	   r9   Úlenr   ©r   r   r   r   Úsize]   s    z
Group.sizec                 C   sp   || kst ‚g }| j ¡ D ]8}||k	rt |j|| |¡}|j| j|d� | |¡ qt 	|¡ 
| j¡ t d ¡S r=   )r0   r   r2   r	   r3   Úreceiver5   r$   r6   r7   r8   r,   r9   )r   ÚsenderÚ	recipientÚmessageZreceivesr#   r;   r   r   r   rD   `   s    zGroup.receivec                 C   s`   || _ g }| j ¡ D ].}t |j| |¡}|j| j|d� | |¡ qt 	|¡ 
| j¡ t d ¡S r=   )r   r   r2   r	   r3   ÚgroupMetaUpdater5   r$   r6   r7   r8   r,   r9   )r   r   Zsetsr#   r;   r   r   r   ÚsetMetadatak   s    zGroup.setMetadatac                 C   s   t | j ¡ ƒS r   )Úiterr   r2   rB   r   r   r   Ú	iterusersu   s    zGroup.iterusers)N)Ú__name__Ú
__module__Ú__qualname__r   r$   r,   r<   r&   rC   rD   rI   rK   r   r   r   r   r   ,   s   

r   c                   @   sN   e Zd ZdZdZdd„ Zdd„ Zdd„ Zddd	„Zd
d„ Z	dd„ Z
dd„ ZdS )ÚUserNc                 C   s   || _ g | _tƒ | _d S r   )r   Úgroupsr   ÚlastMessager   r   r   r   r      s    zUser.__init__c                 C   s   || _ || _tƒ | _d S r   )ÚrealmÚmindr   ÚsignOn)r   rR   rS   r   r   r   ÚloggedIn„   s    zUser.loggedInc                    s    ‡ ‡fdd„}ˆ   ˆj¡ |¡S )Nc                    s   ˆj  ˆ ¡ | S r   )rP   r6   ©r*   ©Úgroupr   r   r   ÚcbJoinŠ   s    zUser.join.<locals>.cbJoin)r<   rS   r8   )r   rX   rY   r   rW   r   Újoin‰   s    z	User.joinc                    s"   ‡ ‡fdd„}ˆ   ˆj|¡ |¡S )Nc                    s   ˆj  ˆ ¡ | S r   )rP   r&   rV   rW   r   r   ÚcbLeave‘   s    zUser.leave.<locals>.cbLeave)r&   rS   r8   )r   rX   r@   r[   r   rW   r   Úleave�   s    z
User.leavec                 C   s   t ƒ | _| | j||¡S r   )r   rQ   rD   rS   )r   rF   rG   r   r   r   Úsend—   s    z	User.sendc                 C   s
   t | jƒS r   )rJ   rP   rB   r   r   r   Ú
itergroups›   s    zUser.itergroupsc                 C   s"   | j d d … D ]}|  |¡ qd S r   )rP   r\   )r   Úgr   r   r   Úlogoutž   s    zUser.logout)N)rL   rM   rN   rR   rS   r   rU   rZ   r\   r]   r^   r`   r   r   r   r   rO   z   s   
rO   zNickServ!NickServ@servicesc                   @   s‚  e Zd ZdZdZdZdZdZdZdd„ Z	dd„ Z
dd	„ Zd
d„ ZdPdd„Zdd„ Zdd„ ZdZdZdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZejdfejdfejdfejdfgZejd fejd!fgZd"d#„ Z d$d%„ Z!d&d'„ Z"d(d)„ Z#dQd*d+„Z$dRd,d-„Z%d.d/„ Z&d0d1„ Z'd2d3„ Z(d4d5„ Z)d6d7„ Z*d8d9„ Z+d:d;„ Z,d<d=„ Z-d>d?„ Z.d@dA„ Z/dBdC„ Z0dDdE„ Z1dFdG„ Z2dHdI„ Z3dJdK„ Z4dLdM„ Z5dNdO„ Z6dS )SÚIRCUserzM
    Protocol instance representing an IRC user connected to the server.
    Núutf-8c                 C   s    | j | _| jj| _| jj| _d S r   )Úirc_NICKSERV_PRIVMSGÚirc_PRIVMSGÚfactoryrR   r   ÚhostnamerB   r   r   r   ÚconnectionMade¼   s    
zIRCUser.connectionMadec                 C   s   | j d k	r|   ¡  d | _d S r   )r`   Úavatar©r   r@   r   r   r   ÚconnectionLostÁ   s    
zIRCUser.connectionLostc                 O   s€   d|kr| j |d< d|kr,| j | j¡|d< | ||d gt|ƒ }g }|D ]"}t|tƒrb| d¡}| |¡ qJt	j
j||Ž d S )NÚprefixÚtorb   )rf   r   ÚencodeÚencodingÚlistÚ
isinstanceÚbytesÚdecoder6   r   ÚIRCÚsendMessage)r   ÚcommandZparameter_listÚkwZarglistZarglistUnicodeÚargr   r   r   rt   Ç   s    


zIRCUser.sendMessagec                 C   s,   |   |j› d|j› d| j› �d|j ¡ d S )Nú!ú@ú#)rZ   r   rf   ©r   rX   r+   r   r   r   r4   Ö   s    zIRCUser.userJoinedc                 C   s2   |   |j› d|j› d| j› �d|j |p*d¡ d S )Nrx   ry   rz   Zleaving)Úpartr   rf   ©r   rX   r+   r@   r   r   r   r?   Ù   s
    ýzIRCUser.userLeftc                 C   s`   t j |¡rd|j }n|j}| dd¡}| ¡ D ](}|  |j› d|j› d| j› �||¡ q2d S )Nrz   Útextz<an unrepresentable message>rx   ry   )r   ÚIGroupr/   r   ÚgetÚ
splitlinesÚprivmsgrf   )r   rE   rF   rG   ZrecipientNamer~   ÚLr   r   r   rD   à   s    ýzIRCUser.receivec              
   C   sJ   d|krF|d }|  dd¡}|  | jd|j ||› d|› d| j› �¡ d S )Nr   r   r   rz   rx   ry   )r€   r   r   rf   )r   rX   r   r   Úauthorr   r   r   rH   ñ   s    üzIRCUser.groupMetaUpdatec                 C   s   |d | _ dS )zÃ
        Password message -- Register a password.

        Parameters: <password>

        [REQUIRED]

        Note that IRC requires the client send this *before* NICK
        and USER.
        éÿÿÿÿN)Úpassword©r   rk   Úparamsr   r   r   Úirc_PASS   s    zIRCUser.irc_PASSc                 C   s¼   |d }zt |tƒr | | j¡}W n2 tk
rT   |  tt|ƒd¡ | j 	¡  Y dS X || _
|| _| jD ]\}}|  ||| jj ¡ qh| jdkr |  t|d¡ n| j}d| _|  ||¡ dS )zh
        Nick message -- Set your nickname.

        Parameters: <nickname>

        [REQUIRED]
        r   z;Your nickname cannot be decoded. Please use ASCII or UTF-8.Nz	Password?)rp   rq   rr   rn   ÚUnicodeDecodeErrorr‚   ÚNICKSERVÚreprÚ	transportÚloseConnectionÚnicknamer   Ú_motdMessagesrt   re   Ú_serverInfor†   ÚlogInAs)r   rk   rˆ   r�   Úcoder~   r†   r   r   r   Úirc_NICK  s*    
ý

zIRCUser.irc_NICKc                 C   s   |d | _ dS )zk
        User message -- Set your realname.

        Parameters: <user> <mode> <unused> <realname>
        r…   N)Zrealnamer‡   r   r   r   Úirc_USER/  s    	zIRCUser.irc_USERc                 C   s`   |d }|d }| j dkr&| j ¡  n6| ¡ dkrD|  t| j d¡ n| j }d| _ |  ||¡ dS )ú^
        Send a (private) message.

        Parameters: <msgtarget> <text to be sent>
        r   r…   NZnickservz1Denied.  Please send me (NickServ) your password.)r�   r�   rŽ   Úlowerr‚   r‹   r’   )r   rk   rˆ   Útargetr†   r�   r   r   r   rc   :  s    
ýzIRCUser.irc_NICKSERV_PRIVMSGc                 C   s6   | j j t ||¡| tj¡}|j| j| j	|fd� d S )N)ZerrbackArgs)
re   r   Úloginr   ZUsernamePasswordr   ÚIUserÚaddCallbacksÚ_cbLoginÚ_ebLogin)r   r�   r†   r;   r   r   r   r’   Q  s    
  ÿzIRCUser.logInAsz:connected to Twisted IRCzA:Your host is %(serviceName)s, running version %(serviceVersion)sz,:This server was created on %(creationDate)sz&%(serviceName)s %(serviceVersion)s w nz(:- %(serviceName)s Message of the Day - z:End of /MOTD command.c                 C   sZ   |\}}}|t jks"td|›�ƒ‚| `|| _|| _| jD ]\}}|  ||| jj	 ¡ q8d S )NzRealm is buggy, got )
r   rš   r0   rd   rh   r`   Ú_welcomeMessagesrt   re   r‘   )r   r*   Úifacerh   r`   r“   r~   r   r   r   rœ   n  s    
zIRCUser._cbLoginc                 C   sh   |  tj¡r|  t|d¡ n>|  tj¡r8|  t|d¡ n"t d¡ t 	|¡ |  t|d¡ | j
 ¡  d S )Nz*Already logged in.  No pod people allowed!zLogin failed.  Goodbye.zUnhandled error during login:z"Server error during login.  Sorry.)Úcheckr   ÚAlreadyLoggedInr‚   r‹   ÚecredZUnauthorizedLoginr   Úmsgr"   r�   rŽ   )r   r"   r�   r   r   r   r�   z  s      ÿ

zIRCUser._ebLoginc                 C   s   | j dk	r|  d| j¡ dS )zK
        Ping message

        Parameters: <server1> [ <server2> ]
        NZPONG)rR   rt   rf   r‡   r   r   r   Úirc_PING‰  s    
zIRCUser.irc_PINGc                 C   s   | j  ¡  dS )z>
        Quit

        Parameters: [ <Quit Message> ]
        N)r�   rŽ   r‡   r   r   r   Úirc_QUIT’  s    zIRCUser.irc_QUITc                 G   s.   |r|   tjd¡ n|  | jd|j d¡ d S )Nú:Unknown MODE flag.rz   ú+)rt   r   ÚERR_UNKNOWNMODEZchannelModer   )r   rX   ÚmodesÚargsr   r   r   Ú_channelModeš  s    zIRCUser._channelModec                 C   s@   |r|   tjd¡ n(|| jkr.|   tjd¡ n|   tjd¡ d S )Nr¦   r§   z(:You can't look at someone else's modes.)rt   r   r¨   rh   ZRPL_UMODEISZERR_USERSDONTMATCH)r   r+   r©   r   r   r   Ú	_userMode   s    
 ÿzIRCUser._userModec                    sÔ   z"ˆ d }t |tƒr | ˆj¡}W n* tk
rL   ˆ tjˆ d d¡ Y dS X | d¡rš‡ ‡fdd„}ˆj	 
|dd… ¡}|jˆj|tˆ dd… ƒd� n6‡fd	d
„}ˆj	 |¡}|jˆj|tˆ dd… ƒd� dS )z€
        User mode message

        Parameters: <nickname>
        *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )

        r   z2:No such nickname (could not decode your unicode!)Nrz   c                    s$   |   tj¡ ˆ tjˆ d d¡ d S )Nr   ú:That channel doesn't exist.©Útrapr   ÚNoSuchGrouprt   r   ÚERR_NOSUCHCHANNEL©r"   ©rˆ   r   r   r   ÚebGroupÀ  s      ÿz!IRCUser.irc_MODE.<locals>.ebGroupé   )ZcallbackArgsc                    s   ˆ   tjd¡ d S )Nz:No such nickname.©rt   r   ÚERR_NOSUCHNICKr²   rB   r   r   ÚebUserÊ  s    z IRCUser.irc_MODE.<locals>.ebUser)rp   rq   rr   rn   rŠ   rt   r   r·   Ú
startswithrR   ÚlookupGroupr›   r«   ÚtupleÚ
lookupUserr¬   )r   rk   rˆ   ÚchannelOrUserr´   r;   r¸   r   r³   r   Úirc_MODEª  s$    
ý
 zIRCUser.irc_MODEc                 C   s   dS )zl
        Userhost message

        Parameters: <nickname> *( SPACE <nickname> )

        [Optional]
        Nr   r‡   r   r   r   Úirc_USERHOSTÐ  s    zIRCUser.irc_USERHOSTc                    s¸   z"|d ‰t ˆtƒr ˆ ˆj¡‰W n* tk
rL   ˆ tj|d d¡ Y dS X |d ‰ ˆ d¡rvˆj	 
ˆdd… ¡}nˆj	 ˆ¡ dd„ ¡}‡ ‡fd	d
„}‡‡fdd„}| ||¡ dS )r–   r   z6:No such nick/channel (could not decode your unicode!)Nr…   rz   rµ   c                 S   s   | j S r   )rS   ©r+   r   r   r   Ú<lambda>ñ  ó    z%IRCUser.irc_PRIVMSG.<locals>.<lambda>c                    s   | d k	rˆj  | dˆ i¡S d S )Nr~   )rh   r]   )Ztarg)ÚmessageTextr   r   r   ÚcbTargetô  s    z%IRCUser.irc_PRIVMSG.<locals>.cbTargetc                    s   ˆ   tjˆd¡ d S )Nz:No such nick/channel.r¶   r²   )r   Ú
targetNamer   r   ÚebTargetø  s    z%IRCUser.irc_PRIVMSG.<locals>.ebTarget)rp   rq   rr   rn   rŠ   rt   r   r·   r¹   rR   rº   r¼   r8   r›   )r   rk   rˆ   r˜   rÄ   rÆ   r   )rÃ   r   rÅ   r   rd   Ú  s(    
ý
ÿzIRCUser.irc_PRIVMSGc                    s–   z"|d ‰ t ˆ tƒr ˆ  ˆj¡‰ W n* tk
rL   ˆ tj|d d¡ Y dS X ˆ  d¡rdˆ dd… ‰ ‡fdd„}‡ ‡fdd	„}ˆj	 
ˆ ¡ ||¡ dS )
zm
        Join message

        Parameters: ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] )
        r   ú1:No such channel (could not decode your unicode!)Nrz   rµ   c                    s    ‡ ‡fdd„}ˆj  ˆ ¡ |¡S )Nc                    s>   ˆ  ˆ ˆ¡ ˆ ˆjdˆ j dd„ ˆ  ¡ D ƒ¡ ˆ ˆ ¡ d S )Nrz   c                 S   s   g | ]
}|j ‘qS r   ©r   ©Ú.0r+   r   r   r   Ú
<listcomp>  s     zEIRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoin.<locals>.<listcomp>)r4   Únamesr   rK   Ú
_sendTopic)ZignrW   r   r   rY     s    ýz1IRCUser.irc_JOIN.<locals>.cbGroup.<locals>.cbJoin©rh   rZ   r8   )rX   rY   rB   ©rX   r   ÚcbGroup  s    	z!IRCUser.irc_JOIN.<locals>.cbGroupc                    s   ˆ  tjdˆ  d¡ d S )Nrz   z:No such channel.)rt   r   r±   r²   ©Ú	groupNamer   r   r   r´     s
      ÿz!IRCUser.irc_JOIN.<locals>.ebGroup)rp   rq   rr   rn   rŠ   rt   r   r±   r¹   rR   ÚgetGroupr›   ©r   rk   rˆ   rÐ   r´   r   rÑ   r   Úirc_JOINý  s     
ý
zIRCUser.irc_JOINc                    sÎ   z*|d ‰ t |d tƒr(|d  ˆj¡‰ W n* tk
rT   ˆ tj|d d¡ Y dS X ˆ  d¡rlˆ dd… ‰ t	|ƒdkr–|d ‰t ˆtƒršˆ d¡‰nd‰‡‡fdd„}‡ ‡fd	d
„}ˆj
 ˆ ¡ ||¡ dS )zc
        Part message

        Parameters: <channel> *( "," <channel> ) [ <Part Message> ]
        r   z:Could not decode your unicode!Nrz   rµ   rb   c                    s$   ‡ ‡‡fdd„}ˆj  ˆ ˆ¡ |¡S )Nc                    s   ˆ  ˆ ˆˆ¡ d S r   )r?   rV   )rX   r@   r   r   r   r[   @  s    z2IRCUser.irc_PART.<locals>.cbGroup.<locals>.cbLeave)rh   r\   r8   )rX   r[   )r@   r   rÏ   r   rÐ   ?  s    z!IRCUser.irc_PART.<locals>.cbGroupc                    s,   |   tj¡ ˆ tjdˆ  d|  ¡  ¡ d S )Nrz   ú:)r¯   r   r°   rt   r   ÚERR_NOTONCHANNELr'   r²   rÑ   r   r   r´   E  s      
ÿz!IRCUser.irc_PART.<locals>.ebGroup)rp   rq   rr   rn   rŠ   rt   r   r×   r¹   rA   rR   rº   r›   rÔ   r   )rÒ   r@   r   r   Úirc_PART%  s*      ÿ

zIRCUser.irc_PARTc                    s–   z"|d ‰ t ˆ tƒr ˆ  ˆj¡‰ W n* tk
rL   ˆ tj|d d¡ Y dS X ˆ  d¡rdˆ dd… ‰ ‡fdd„}‡ ‡fdd	„}ˆj	 
ˆ ¡ ||¡ dS )
zb
        Names message

        Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
        r…   rÇ   Nrz   rµ   c                    s(   ˆ   ˆ jd| j dd„ |  ¡ D ƒ¡ d S )Nrz   c                 S   s   g | ]
}|j ‘qS r   rÈ   rÉ   r   r   r   rË   g  s     z6IRCUser.irc_NAMES.<locals>.cbGroup.<locals>.<listcomp>)rÌ   r   rK   rÏ   rB   r   r   rÐ   e  s
      ÿz"IRCUser.irc_NAMES.<locals>.cbGroupc                    s$   |   tj¡ ˆ ˆjdˆ  g ¡ d S )Nrz   )r¯   r   r°   rÌ   r   r²   ©Úchannelr   r   r   r´   j  s    z"IRCUser.irc_NAMES.<locals>.ebGroup)rp   rq   rr   rn   rŠ   rt   r   r±   r¹   rR   rº   r›   rÔ   r   rÙ   r   Ú	irc_NAMESM  s     	
ý
zIRCUser.irc_NAMESc                 C   sŽ   z&|d }t |d tƒr$| | j¡}W n$ tk
rJ   |  tjd¡ Y dS X | d¡rb|dd… }t	|ƒdkr€|  
||d ¡ n
|  |¡ dS )zJ
        Topic message

        Parameters: <channel> [ <topic> ]
        r   z<:That channel doesn't exist (could not decode your unicode!)Nrz   rµ   )rp   rq   rr   rn   rŠ   rt   r   r±   r¹   rA   Ú	_setTopicÚ	_getTopic)r   rk   rˆ   rÚ   r   r   r   Ú	irc_TOPICq  s    þ
zIRCUser.irc_TOPICc                 C   s`   |j  d¡}|r\|j  d¡pd}|j  dd¡}|  | jd|j |¡ |  | jd|j ||¡ dS )zP
        Send the topic of the given group to this user, if it has one.
        r   r   z<noone>Ú
topic_dater   rz   N)r   r€   r   r   ZtopicAuthor)r   rX   r   r„   Údater   r   r   rÍ   Š  s    zIRCUser._sendTopicc                    s(   ‡ ‡fdd„}ˆj  ˆ ¡ ˆj|¡ d S )Nc                    s"   |   tj¡ ˆ tjdˆ d¡ d S ©Nú=r­   r®   r²   rÙ   r   r   r´   ™  s       ÿz"IRCUser._getTopic.<locals>.ebGroup)rR   rº   r›   rÍ   )r   rÚ   r´   r   rÙ   r   rÝ   •  s    zIRCUser._getTopicc                    s4   ‡‡fdd„}‡ ‡fdd„}ˆj  ˆ ¡ ||¡ d S )Nc                    sH   ˆ j  ¡ }ˆ|d< ˆj|d< ttƒ ƒ|d< ‡ ‡fdd„}ˆ  |¡ |¡S )Nr   r   rß   c                    s   ˆ  tjdˆ j d¡ d S )Nrz   z.:You need to be a channel operator to do that.)rt   r   ZERR_CHANOPRIVSNEEDEDr   r²   rW   r   r   ÚebSet«  s
    ýz1IRCUser._setTopic.<locals>.cbGroup.<locals>.ebSet)r   Úcopyr   Úintr   rI   r5   )rX   ZnewMetarã   )r   r   rÏ   r   rÐ   ¥  s    

z"IRCUser._setTopic.<locals>.cbGroupc                    s"   |   tj¡ ˆ tjdˆ d¡ d S rá   r®   r²   rÙ   r   r   r´   ´  s       ÿz"IRCUser._setTopic.<locals>.ebGroup)rR   rº   r›   )r   rÚ   r   rÐ   r´   r   )rÚ   r   r   r   rÜ   ¡  s    zIRCUser._setTopicc                 C   s<   |D ]$\}}}|   tj|t|ƒd| ¡ q|   tjd¡ dS )zõ
        Send a group of LIST response lines

        @type channels: C{list} of C{(str, int, str)}
        @param channels: Information about the channels being sent:
            their name, the number of participants, and their topic.
        rÖ   z:End of /LISTN)rt   r   ZRPL_LISTÚstrZRPL_LISTEND)r   Úchannelsr   rC   r   r   r   r   ro   ¼  s    zIRCUser.listc                    sÔ   |r°z,|d }t |tƒr$| ˆ j¡}| d¡}W n* tk
rZ   ˆ  tj|d d¡ Y dS X g }|D ],}| 	d¡r~|dd… }| 
ˆ j |¡¡ qdtj|dd�}| d	d
„ ¡ n
ˆ j ¡ }‡ fdd„}| |¡ dS )zÎ
        List query

        Return information about the indicated channels, or about all
        channels if none are specified.

        Parameters: [ <channel> *( "," <channel> ) [ <target> ] ]
        r   ú,rÇ   Nrz   rµ   T)ZconsumeErrorsc                 S   s   dd„ | D ƒS )Nc                 S   s   g | ]\}}|r|‘qS r   r   ©rÊ   ÚsÚrr   r   r   rË   ë  s      z6IRCUser.irc_LIST.<locals>.<lambda>.<locals>.<listcomp>r   )Zgsr   r   r   rÁ   ë  rÂ   z"IRCUser.irc_LIST.<locals>.<lambda>c                    s6   dd„ ‰ t  ‡ fdd„| D ƒ¡}| ‡fdd„¡ |S )Nc                 S   s   |j | |j d¡fS )Nr   )r   r   r€   )rC   rX   r   r   r   ÚgotSizeñ  s    z3IRCUser.irc_LIST.<locals>.cbGroups.<locals>.gotSizec                    s   g | ]}|  ¡  ˆ |¡‘qS r   )rC   r8   ©rÊ   rX   ©rì   r   r   rË   õ  s     z6IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<listcomp>c                    s   ˆ   dd„ | D ƒ¡S )Nc                 S   s   g | ]\}}|r|‘qS r   r   ré   r   r   r   rË   ÷  s      zHIRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>.<locals>.<listcomp>)ro   )r(   rB   r   r   rÁ   ÷  rÂ   z4IRCUser.irc_LIST.<locals>.cbGroups.<locals>.<lambda>)r	   r7   r8   )rP   r;   rB   rî   r   ÚcbGroupsð  s    ÿz"IRCUser.irc_LIST.<locals>.cbGroups)rp   rq   rr   rn   ÚsplitrŠ   rt   r   r±   r¹   r6   rR   rº   r	   r7   r8   r^   )r   rk   rˆ   ZallChannelsrç   rP   Úchrï   r   rB   r   Úirc_LISTÈ  s.    
ý


zIRCUser.irc_LISTc                    s,   ˆ   ˆ jd|j ‡ fdd„| ¡ D ƒ¡ d S )Nrz   c              	      s*   g | ]"}|j ˆ jˆ jj |j d d|j f‘qS )ÚHr   )r   rf   rR   )rÊ   ÚmrB   r   r   rË      s   ÿz'IRCUser._channelWho.<locals>.<listcomp>)Zwhor   rK   ©r   rX   r   rB   r   Ú_channelWhoü  s    
þýzIRCUser._channelWhoc                 C   s   |   tjd¡ d S )Nz:User /WHO not implemented)rt   r   ÚRPL_ENDOFWHO©r   r+   r   r   r   Ú_userWho  s    zIRCUser._userWhoc                    sÌ   |sˆ  tjd¡ dS z"|d ‰ tˆ tƒr6ˆ  ˆj¡‰ W n* tk
rb   ˆ  tj|d d¡ Y dS X ˆ  d¡r ‡ ‡fdd„}ˆj	 
ˆ dd… ¡}| ˆj|¡ n(‡ ‡fd	d
„}ˆj	 ˆ ¡}| ˆj|¡ dS )zC
        Who query

        Parameters: [ <mask> [ "o" ] ]
        z:/WHO not supported.Nr   z2:End of /WHO list (could not decode your unicode!)rz   c                    s    |   tj¡ ˆ tjˆ d¡ d S ©Nz:End of /WHO list.)r¯   r   r°   rt   r   r÷   r²   ©r½   r   r   r   r´   *  s    z IRCUser.irc_WHO.<locals>.ebGrouprµ   c                    s    |   tj¡ ˆ tjˆ d¡ d S rú   )r¯   r   Ú
NoSuchUserrt   r   r÷   r²   rû   r   r   r¸   2  s    zIRCUser.irc_WHO.<locals>.ebUser)rt   r   r÷   rp   rq   rr   rn   rŠ   r¹   rR   rº   r›   rö   r¼   rù   )r   rk   rˆ   r´   r;   r¸   r   rû   r   Úirc_WHO	  s*    
ý
zIRCUser.irc_WHOc                    s€   ‡fdd„}‡ ‡fdd„}z"ˆ d }t |tƒr:| ˆj¡}W n* tk
rf   ˆ tjˆ d d¡ Y dS X ˆj 	|¡ 
||¡ dS )zV
        Whois query

        Parameters: [ <target> ] <mask> *( "," <mask> )
        c                    sN   ˆ   ˆ j| j| jˆ jj| jˆ jjddttƒ | j ƒ| jdd„ |  ¡ D ƒ¡ d S )NzHi mom!Fc                 S   s   g | ]}d |j  ‘qS )rz   rÈ   rí   r   r   r   rË   L  s     z5IRCUser.irc_WHOIS.<locals>.cbUser.<locals>.<listcomp>)Zwhoisr   rR   rå   r   rQ   rT   r^   rÀ   rB   r   r   ÚcbUser@  s    õz!IRCUser.irc_WHOIS.<locals>.cbUserc                    s$   |   tj¡ ˆ tjˆ d d¡ d S )Nr   ú:No such nick/channel)r¯   r   rü   rt   r   r·   r²   r³   r   r   r¸   O  s    z!IRCUser.irc_WHOIS.<locals>.ebUserr   rÿ   N)rp   rq   rr   rn   rŠ   rt   r   r·   rR   r¼   r›   )r   rk   rˆ   rþ   r¸   r+   r   r³   r   Ú	irc_WHOIS9  s    
zIRCUser.irc_WHOISc                 C   s   |   tjd¡ dS )zE
        Oper message

        Parameters: <name> <password>
        z:O-lines not applicableN)rt   r   ZERR_NOOPERHOSTr‡   r   r   r   Úirc_OPER^  s    zIRCUser.irc_OPER)N)N)N)7rL   rM   rN   Ú__doc__rP   r`   rh   rR   rn   rg   rj   rt   r4   r?   rD   rH   r�   r†   r‰   r”   r•   rc   r’   r   ZRPL_WELCOMEZRPL_YOURHOSTZRPL_CREATEDZ
RPL_MYINFOrž   ZRPL_MOTDSTARTZRPL_ENDOFMOTDr�   rœ   r�   r¤   r¥   r«   r¬   r¾   r¿   rd   rÕ   rØ   rÛ   rÞ   rÍ   rÝ   rÜ   ro   rò   rö   rù   rý   r   r  r   r   r   r   ra   ¦   sn   
"þüöþ	


&
#(($4
0%ra   c                   @   s   e Zd ZdZeZdd„ ZdS )Ú
IRCFactorya  
    IRC server that creates instances of the L{IRCUser} protocol.

    @ivar _serverInfo: A dictionary mapping:
        "serviceName" to the name of the server,
        "serviceVersion" to the copyright version,
        "creationDate" to the time that the server was started.
    c                 C   s&   || _ || _| j jtjtƒ dœ| _d S )N)ZserviceNameZserviceVersionZcreationDate)rR   r   r   r   Úversionr   r‘   )r   rR   r   r   r   r   r   s  s    ýzIRCFactory.__init__N)rL   rM   rN   r  ra   r
   r   r   r   r   r   r  g  s   	r  c                   @   s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚPBMindc                 C   s   d S r   r   rB   r   r   r   r   ~  s    zPBMind.__init__c                 C   s.   t  t¡}t|tƒr| d¡}||j | ¡fS ©Nrb   )r   Úqualr  rp   ræ   rm   ÚinvokerÚregisterReference©r   Újellierr  r   r   r   ÚjellyFor�  s    


zPBMind.jellyForc                 C   s   d S r   r   )r   r+   rX   r   r   r   Úremote_userJoined‡  s    zPBMind.remote_userJoinedc                 C   s   d S r   r   )r   r+   rX   r@   r   r   r   Úremote_userLeftŠ  s    zPBMind.remote_userLeftc                 C   s   d S r   r   ©r   rE   rF   rG   r   r   r   Úremote_receive�  s    zPBMind.remote_receivec                 C   s   d S r   r   ©r   rX   r   r   r   r   Úremote_groupMetaUpdate�  s    zPBMind.remote_groupMetaUpdateN)	rL   rM   rN   r   r  r  r  r  r  r   r   r   r   r  }  s   r  c                   @   s2   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	d
„ZdS )ÚPBMindReferencer   c                 C   sJ   t j |¡rt| j| j|ƒ}nt| j| j|ƒ}|  dt| j| j|ƒ||¡S )NrD   )r   r   r/   ÚPBGrouprR   rh   ÚPBUserÚ
callRemote)r   rE   rF   rG   Zrecr   r   r   rD   ˜  s       ÿzPBMindReference.receivec                 C   s   |   dt| j| j|ƒ|¡S )NrH   )r  r  rR   rh   r  r   r   r   rH   ¡  s
      ÿzPBMindReference.groupMetaUpdatec                 C   s&   |   dt| j| j|ƒt| j| j|ƒ¡S )Nr4   ©r  r  rR   rh   r  r{   r   r   r   r4   ¦  s
    ýzPBMindReference.userJoinedNc                 C   s(   |   dt| j| j|ƒt| j| j|ƒ|¡S )Nr?   r  r}   r   r   r   r?   ­  s    üzPBMindReference.userLeft)N)rL   rM   rN   r   rD   rH   r4   r?   r   r   r   r   r  ”  s
   	r  c                   @   s6   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ ZdS )r  c                 C   s   || _ || _|| _d S r   )rR   rh   rX   )r   rR   rh   rX   r   r   r   r   º  s    zPBGroup.__init__c                 C   s   t | jj| jj| jjfƒS r   )ÚhashrR   r   rh   rX   rB   r   r   r   ÚprocessUniqueID¿  s    zPBGroup.processUniqueIDc                 C   sN   t  | j¡}t|tƒr | d¡}| jj}t|tƒr<| d¡}|||j 	| ¡fS r  )
r   r  Ú	__class__rp   ræ   rm   rX   r   r  r	  )r   r  r  rX   r   r   r   r  Â  s    



zPBGroup.jellyForNc                 C   s   | j  | j|¡S r   )rh   r\   rX   ri   r   r   r   Úremote_leaveË  s    zPBGroup.remote_leavec                 C   s   | j  | j|¡S r   )rh   r]   rX   ©r   rG   r   r   r   Úremote_sendÎ  s    zPBGroup.remote_send)N)rL   rM   rN   r   r  r  r  r  r   r   r   r   r  ¹  s
   	
r  c                   @   sX   e Zd Zdd„ Zddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zddd„Z	dd„ Z
dd„ ZdS )ÚPBGroupReferencec                 C   s*   |\}}}|  d¡| _tj | |||g¡S r  )rr   r   r   ÚRemoteReferenceÚ
unjellyFor)r   Z	unjellierZunjellyListZclsNamer   Úrefr   r   r   r   Ô  s    
zPBGroupReference.unjellyForNc                 C   s   |   d|¡S )Nr\   ©r  ri   r   r   r   r\   Ù  s    zPBGroupReference.leavec                 C   s   |   d|¡S )Nr]   r"  r  r   r   r   r]   Ü  s    zPBGroupReference.sendc                 C   s   d S r   r   rø   r   r   r   r<   ß  s    zPBGroupReference.addc                 C   s   d S r   r   rB   r   r   r   rK   ã  s    zPBGroupReference.iterusersc                 C   s   d S r   r   r  r   r   r   rD   ç  s    zPBGroupReference.receivec                 C   s   d S r   r   )r   r+   r@   r   r   r   r&   ë  s    zPBGroupReference.removec                 C   s   d S r   r   )r   r   r   r   r   rI   ï  s    zPBGroupReference.setMetadatac                 C   s   d S r   r   rB   r   r   r   rC   ó  s    zPBGroupReference.size)N)N)rL   rM   rN   r   r\   r]   r<   rK   rD   r&   rI   rC   r   r   r   r   r  Ò  s   

r  c                   @   s   e Zd Zdd„ Zdd„ ZdS )r  c                 C   s   || _ || _|| _d S r   )rR   rh   r+   )r   rR   rh   r+   r   r   r   r   ü  s    zPBUser.__init__c                 C   s   t | jj| jj| jjfƒS r   )r  rR   r   rh   r+   rB   r   r   r   r    s    zPBUser.processUniqueIDN)rL   rM   rN   r   r  r   r   r   r   r  û  s   r  c                   @   s`   e Zd Zdd„ Zdd„ Zdd„ Zedd„ ƒZejd	d„ ƒZd
d„ Z	dd„ Z
dd„ Zddd„ZdS )Ú
ChatAvatarc                 C   s
   || _ d S r   )rh   )r   rh   r   r   r   r     s    zChatAvatar.__init__c                 C   s0   t  | j¡}t|tƒr | d¡}||j | ¡fS r  )r   r  r  rp   ræ   rm   r  r	  r
  r   r   r   r  
  s    

zChatAvatar.jellyForc                    s(   ‡ fdd„}ˆ j j |¡}| |¡ |S )Nc                    s(   ‡ ‡fdd„}ˆj  ˆ ¡}| |¡ |S )Nc                    s   t ˆjjˆjˆ ƒS r   )r  rh   rR   )ZignoredrW   r   r   rY     s    z7ChatAvatar.remote_join.<locals>.cbGroup.<locals>.cbJoinrÎ   )rX   rY   r;   rB   rÏ   r   rÐ     s    
z'ChatAvatar.remote_join.<locals>.cbGroup)rh   rR   rÓ   r8   )r   rÒ   rÐ   r;   r   rB   r   Úremote_join  s    
zChatAvatar.remote_joinc                 C   s   d S r   r   rB   r   r   r   r     s    zChatAvatar.namec                 C   s   d S r   r   )r   r%   r   r   r   r   "  s    c                 C   s   d S r   r   r  r   r   r   rH   '  s    zChatAvatar.groupMetaUpdatec                 C   s   d S r   r   r  r   r   r   rD   +  s    zChatAvatar.receivec                 C   s   d S r   r   r{   r   r   r   r4   /  s    zChatAvatar.userJoinedNc                 C   s   d S r   r   r}   r   r   r   r?   3  s    zChatAvatar.userLeft)N)rL   rM   rN   r   r  r$  Úpropertyr   ÚsetterrH   rD   r4   r?   r   r   r   r   r#    s   

r#  c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚAvatarReferencec                 C   s   |   d|¡S )NrZ   r"  )r   rÒ   r   r   r   rZ   <  s    zAvatarReference.joinc                    s,   t  ¡ ‰ | j ‡ fdd„¡ | jj ¡  ˆ S )Nc                      s
   ˆ   d ¡S r   )Úcallbackr   ©r;   r   r   rÁ   A  rÂ   z&AvatarReference.quit.<locals>.<lambda>)r	   ZDeferredZbrokerZnotifyOnDisconnectr�   rŽ   rB   r   r)  r   Úquit?  s    zAvatarReference.quitN)rL   rM   rN   rZ   r*  r   r   r   r   r'  ;  s   r'  c                   @   sˆ   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dZ
dZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd S )!Ú
WordsRealmrb   c                 C   s
   || _ d S r   rÈ   r   r   r   r   r   M  s    zWordsRealm.__init__c                 C   s   t |ƒS r   )rO   r   r   r   r   ÚuserFactoryP  s    zWordsRealm.userFactoryc                 C   s   t |ƒS r   )r   r   r   r   r   ÚgroupFactoryS  s    zWordsRealm.groupFactoryc                    s   ‡ ‡fdd„}|S )Nc                      s"   t ˆddd„ ƒƒ  d  ˆ _ˆ _d S )Nr`   c                   S   s   d S r   r   r   r   r   r   rÁ   Y  rÂ   z:WordsRealm.logoutFactory.<locals>.logout.<locals>.<lambda>)ÚgetattrrR   rS   r   ©rh   Úfacetr   r   r`   W  s    z(WordsRealm.logoutFactory.<locals>.logoutr   )r   rh   r0  r`   r   r/  r   ÚlogoutFactoryV  s    zWordsRealm.logoutFactoryc                    s8   t ˆ tƒrˆ  ˆj¡‰ ‡ ‡‡‡fdd„}ˆ ˆ ¡ |¡S )Nc                    sp   | j d k	rt ¡ ‚ˆD ]J}|| d ƒ}|d k	r|  ˆˆ¡ ˆ ˆ_ˆˆ_ | ˆ_||ˆ | |¡f  S qtˆˆƒ‚d S r   )rR   r   r¡   rU   r   rh   r1  ÚNotImplementedError)rh   rŸ   r0  ©ÚavatarIdÚ
interfacesrS   r   r   r   Ú	gotAvatarb  s    

z+WordsRealm.requestAvatar.<locals>.gotAvatar)rp   rq   rr   Ú	_encodingÚgetUserr8   )r   r4  rS   r5  r6  r   r3  r   ÚrequestAvatar^  s    
zWordsRealm.requestAvatarc                 C   s   d S r   r   rB   r   r   r   r^   q  s    zWordsRealm.itergroupsFTc                 C   s   t ‚d S r   ©r2  r   r   r   r   r¼   y  s    zWordsRealm.lookupUserc                 C   s   t ‚d S r   r:  rõ   r   r   r   rº   |  s    zWordsRealm.lookupGroupc                 C   s   t ‚dS )aÓ  
        Add the given user to this service.

        This is an internal method intended to be overridden by
        L{WordsRealm} subclasses, not called by external code.

        @type user: L{IUser}

        @rtype: L{twisted.internet.defer.Deferred}
        @return: A Deferred which fires with L{None} when the user is
        added, or which fails with
        L{twisted.words.ewords.DuplicateUser} if a user with the
        same name exists already.
        Nr:  rø   r   r   r   ÚaddUser  s    zWordsRealm.addUserc                 C   s   t ‚dS )aY  
        Add the given group to this service.

        @type group: L{IGroup}

        @rtype: L{twisted.internet.defer.Deferred}
        @return: A Deferred which fires with L{None} when the group is
        added, or which fails with
        L{twisted.words.ewords.DuplicateGroup} if a group with the
        same name exists already.
        Nr:  rõ   r   r   r   ÚaddGroup�  s    zWordsRealm.addGroupc                    s.   ˆj r$‡ ‡fdd„}ˆ ˆ ¡ |¡S ˆ ˆ ¡S )Nc                    s   |   tj¡ ˆ ˆ ¡S r   )r¯   r   ÚDuplicateGrouprº   r²   ©r   r   r   r   r´   ¡  s    z$WordsRealm.getGroup.<locals>.ebGroup)ÚcreateGroupOnRequestÚcreateGroupr5   rº   )r   r   r´   r   r>  r   rÓ   ž  s    zWordsRealm.getGroupc                    s.   ˆj r$‡ ‡fdd„}ˆ ˆ ¡ |¡S ˆ ˆ ¡S )Nc                    s   |   tj¡ ˆ ˆ ¡S r   )r¯   r   ÚDuplicateUserr¼   r²   r>  r   r   r¸   «  s    z"WordsRealm.getUser.<locals>.ebUser)ÚcreateUserOnRequestÚ
createUserr5   r¼   )r   r   r¸   r   r>  r   r8  ¨  s    zWordsRealm.getUserc                    sH   ‡ fdd„}‡ ‡fdd„}ˆ   ¡ ‰ ˆ ˆ ¡}| ||¡ | ˆj¡ |S )Nc                    s   t  t ˆ ¡¡S r   )r   r    r   rA  rÀ   rÈ   r   r   ÚcbLookup³  s    z'WordsRealm.createUser.<locals>.cbLookupc                    s   |   tj¡ ˆ ˆ ¡S r   )r¯   r   rü   r,  r²   r>  r   r   ÚebLookup¶  s    z'WordsRealm.createUser.<locals>.ebLookup)r—   r¼   r›   r8   r;  ©r   r   rD  rE  r;   r   r>  r   rC  ²  s    
zWordsRealm.createUserc                    sH   ‡ fdd„}‡ ‡fdd„}ˆ   ¡ ‰ ˆ ˆ ¡}| ||¡ | ˆj¡ |S )Nc                    s   t  t ˆ ¡¡S r   )r   r    r   r=  rÏ   rÈ   r   r   rD  Á  s    z(WordsRealm.createGroup.<locals>.cbLookupc                    s   |   tj¡ ˆ ˆ ¡S r   )r¯   r   r°   r-  r²   r>  r   r   rE  Ä  s    z(WordsRealm.createGroup.<locals>.ebLookup)r—   rº   r›   r8   r<  rF  r   r>  r   r@  À  s    
zWordsRealm.createGroupN)rL   rM   rN   r7  r   r,  r-  r1  r9  r^   r?  rB  r¼   rº   r;  r<  rÓ   r8  rC  r@  r   r   r   r   r+  I  s"   

r+  c                       sD   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z‡  Z	S )ÚInMemoryWordsRealmc                    s   t ƒ j||Ž i | _i | _d S r   )Úsuperr   r   rP   )r   Úarv   ©r  r   r   r   Ð  s    zInMemoryWordsRealm.__init__c                 C   s   t  | j ¡ ¡S r   )r	   r9   rP   r2   rB   r   r   r   r^   Õ  s    zInMemoryWordsRealm.itergroupsc                 C   s6   |j | jkr t t t ¡ ¡¡S || j|j < t |¡S r   )	r   r   r	   Úfailr   r    r   rA  r9   rø   r   r   r   r;  Ø  s    zInMemoryWordsRealm.addUserc                 C   s6   |j | jkr t t t ¡ ¡¡S || j|j < t |¡S r   )	r   rP   r	   rK  r   r    r   r=  r9   rõ   r   r   r   r<  Þ  s    zInMemoryWordsRealm.addGroupc              
   C   sP   |  ¡ }z| j| }W n* tk
r@   t t t |¡¡¡ Y S X t 	|¡S d S r   )
r—   r   r>   r	   rK  r   r    r   rü   r9   )r   r   r+   r   r   r   r¼   ä  s    zInMemoryWordsRealm.lookupUserc              
   C   sP   |  ¡ }z| j| }W n* tk
r@   t t t |¡¡¡ Y S X t 	|¡S d S r   )
r—   rP   r>   r	   rK  r   r    r   r°   r9   )r   r   rX   r   r   r   rº   í  s    zInMemoryWordsRealm.lookupGroup)
rL   rM   rN   r   r^   r;  r<  r¼   rº   Ú__classcell__r   r   rJ  r   rG  Ï  s   	rG  N)6r  r   r   Zzope.interfacer   Ztwistedr   Ztwisted.credr   r   r¢   r   Ztwisted.internetr	   r
   Ztwisted.pythonr   r   r   Ztwisted.python.componentsr   Ztwisted.spreadr   Ztwisted.wordsr   r   Ztwisted.words.protocolsr   r   r   rš   rO   r‹   r.   rs   ra   ZServerFactoryr  ZReferenceabler  r  r  ZsetUnjellyableForClassr  r  r  r#  ZIPerspectiver'  ZIRealmZIChatServicer+  rG  Ú__all__r   r   r   r   Ú<module>   s\   M(     E!%
2 )ü