o
    Hb}                     @   s  g d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddl
mZmZ ddlmZ ejZzddlZddlmZmZmZmZ W n eyb   ejdkr^ dZY nw d	Zd
Ze ZdZdgZeedr|dZedg7 ZejdkrdZedg7 ZefddZ dd Z!dd Z"dd Z#dd Z$G dd dZ%erG dd de%Z&G dd de%Z'G dd de(Z)dPd d!Z*ejdkrdQd#d$Z+ndQd%d$Z+G d&d' d'e(Z,d(d) Z-ejdkrG d*d+ d+e(Z.d,d- Z/d.Z0d/Z1d0Z2d1Z3d2d3 Z4d4d5 Z5G d6d7 d7e(Z6d8d9 Z7d:d; Z8G d<d= d=e)Z9d>d? Z:ejdkr3d@dA Z;ej<ej=hZ>dRdBdCZ?nddl@Z@ee@dDrAe@jAZBne@jCZBdRdEdCZ?ejdkrmdFdG ZDdHdI ZEeFe'eD dJdK ZGdLdM ZHeFe&eG dS dNdG ZDdOdI ZEeFe'eD dS )S)ClientListenerPipewait    N   )util)AuthenticationErrorBufferTooShort)	reduction)WAIT_OBJECT_0WAIT_ABANDONED_0WAIT_TIMEOUTINFINITEwin32i    g      4@AF_INETAF_UNIXAF_PIPEc                 C   s   t  |  S Ntime	monotonic)timeout r   1/usr/lib/python3.10/multiprocessing/connection.py_init_timeout;      r   c                 C   s   t  | kS r   r   )tr   r   r   _check_timeout>   r   r   c                 C   sr   | dkrdS | dkr"t jrdt  dtt S tjdt  dS | dkr5tjd	t ttf d
dS t	d)z?
    Return an arbitrary free address for the given family
    r   )Z	localhostr   r   z
 listener--z	listener-)prefixdirr   z\\.\pipe\pyc-%d-%d- zunrecognized family)
r   Zabstract_sockets_supportedosgetpidnext_mmap_countertempfileZmktempZget_temp_dir
ValueErrorfamilyr   r   r   arbitrary_addressE   s   r*   c                 C   sR   t jdkr| dkrtd|  t jdkr#| dkr%tt| s'td|  dS dS dS )zD
    Checks if the family is valid for the current environment.
    r   r   zFamily %s is not recognized.r   N)sysplatformr'   hasattrsocketr(   r   r   r   _validate_familyX   s   
r/   c                 C   sP   t | tkrdS t | tu r| drdS t | tu s t| r"dS td|  )z]
    Return the types of the address

    This can be 'AF_INET', 'AF_UNIX', or 'AF_PIPE'
    r   z\\r   r   zaddress type of %r unrecognized)typetuplestr
startswithr   is_abstract_socket_namespacer'   )addressr   r   r   address_typed   s   r6   c                   @   s   e Zd ZdZd+ddZdd Zdd Zd	d
 Zdd Zdd Z	e
dd Ze
dd Ze
dd Zdd Zdd Zd,ddZdd Zd-ddZd.d d!Zd"d# Zd/d%d&Zd'd( Zd)d* ZdS )0_ConnectionBaseNTc                 C   s>   |  }|dk rtd|s|std|| _|| _|| _d S )Nr   zinvalid handlez6at least one of `readable` and `writable` must be True)	__index__r'   _handle	_readable	_writable)selfhandlereadablewritabler   r   r   __init__z   s   
z_ConnectionBase.__init__c                 C   s   | j d ur|   d S d S r   r9   _closer<   r   r   r   __del__   s   
z_ConnectionBase.__del__c                 C   s   | j d u r	tdd S )Nzhandle is closed)r9   OSErrorrC   r   r   r   _check_closed   s   
z_ConnectionBase._check_closedc                 C      | j stdd S )Nzconnection is write-only)r:   rE   rC   r   r   r   _check_readable      z_ConnectionBase._check_readablec                 C   rG   )Nzconnection is read-only)r;   rE   rC   r   r   r   _check_writable   rI   z_ConnectionBase._check_writablec                 C   s$   | j r
d| _td|   td)NFzbad message length)r;   r:   closerE   rC   r   r   r   _bad_message_length   s
   z#_ConnectionBase._bad_message_lengthc                 C   s
   | j du S )z True if the connection is closedNr9   rC   r   r   r   closed   s   
z_ConnectionBase.closedc                 C      | j S )z"True if the connection is readable)r:   rC   r   r   r   r>         z_ConnectionBase.readablec                 C   rO   )z"True if the connection is writable)r;   rC   r   r   r   r?      rP   z_ConnectionBase.writablec                 C   s   |    | jS )z+File descriptor or handle of the connection)rF   r9   rC   r   r   r   fileno   s   z_ConnectionBase.filenoc                 C   s,   | j durz
|   W d| _ dS d| _ w dS )zClose the connectionNrA   rC   r   r   r   rK      s
   

z_ConnectionBase.closer   c                 C   s   |    |   t|}|jdkrtt|}t|}|dk r#td||k r+td|du r4|| }n|dk r<td|| |krFtd| ||||   dS )z,Send the bytes data from a bytes-like objectr   r   zoffset is negativezbuffer length < offsetNzsize is negativezbuffer length < offset + size)rF   rJ   
memoryviewitemsizebyteslenr'   _send_bytes)r<   bufoffsetsizemnr   r   r   
send_bytes   s"   

z_ConnectionBase.send_bytesc                 C   s$   |    |   | t| dS )zSend a (picklable) objectN)rF   rJ   rV   _ForkingPicklerdumpsr<   objr   r   r   send   s   z_ConnectionBase.sendc                 C   sJ   |    |   |dur|dk rtd| |}|du r!|   | S )z7
        Receive bytes data as a bytes object.
        Nr   znegative maxlength)rF   rH   r'   _recv_bytesrL   getvalue)r<   Z	maxlengthrW   r   r   r   
recv_bytes   s   
z_ConnectionBase.recv_bytesc                 C   s   |    |   t|K}|j}|t| }|dk rtd||kr&td|  }| }||| k r:t|	 |
d |||| || |   |W  d   S 1 sZw   Y  dS )zq
        Receive bytes data into a writeable bytes-like object.
        Return the number of bytes read.
        r   znegative offsetzoffset too largeN)rF   rH   rR   rS   rU   r'   rb   tellr	   rc   seekreadinto)r<   rW   rX   rZ   rS   ZbytesizeresultrY   r   r   r   recv_bytes_into   s&   


$z_ConnectionBase.recv_bytes_intoc                 C   s&   |    |   |  }t| S )zReceive a (picklable) object)rF   rH   rb   r]   loads	getbuffer)r<   rW   r   r   r   recv   s   z_ConnectionBase.recv        c                 C   s   |    |   | |S )z/Whether there is any input available to be read)rF   rH   _pollr<   r   r   r   r   poll  s   
z_ConnectionBase.pollc                 C      | S r   r   rC   r   r   r   	__enter__     z_ConnectionBase.__enter__c                 C      |    d S r   rK   r<   exc_type	exc_valueZexc_tbr   r   r   __exit__  r   z_ConnectionBase.__exit__)TT)r   Nr   )r   )rm   )__name__
__module____qualname__r9   r@   rD   rF   rH   rJ   rL   propertyrN   r>   r?   rQ   rK   r\   ra   rd   ri   rl   rp   rr   ry   r   r   r   r   r7   w   s0    







r7   c                   @   sD   e Zd ZdZdZejfddZdd Zddd	Z	d
d Z
dd ZdS )PipeConnectionz
        Connection class based on a Windows named pipe.
        Overlapped I/O is used, so the handles must have been created
        with FILE_FLAG_OVERLAPPED.
        Fc                 C      || j  d S r   rM   )r<   Z_CloseHandler   r   r   rB        zPipeConnection._closec              	   C   s   t j| j|dd\}}z(z|t jkr!t |jgdt}|tks!J W n   |   W |	d\}}n|	d\}}w |dksBJ |t
|ksJJ d S )NT
overlappedFr   )_winapiZ	WriteFiler9   ERROR_IO_PENDINGWaitForMultipleObjectseventr   r   cancelGetOverlappedResultrU   )r<   rW   overrwaitresZnwrittenr   r   r   rV     s   

 zPipeConnection._send_bytesNc           	   
   C   sh  | j r
d| _ t S |d u rdnt|d}ztj| j|dd\}}zFz|tjkr7t|j	gdt
}|tks7J W n   |   W |d\}}|dkr[t }||  |W S |tjkrg| ||W S n2|d\}}|dkrt }||  |     Y W S |tjkr| ||     Y W S w W td ty } z	|jtjkrt d }~ww )NF   Tr   r   z.shouldn't get here; expected KeyboardInterrupt)_got_empty_messageioBytesIOminr   ReadFiler9   r   r   r   r   r   r   r   writerk   ZERROR_MORE_DATA_get_more_datarE   winerrorERROR_BROKEN_PIPEEOFErrorRuntimeError)	r<   maxsizeZbsizer   r   r   Znreadfer   r   r   rb   +  sT   





zPipeConnection._recv_bytesc                 C   s.   | j st| jd dkrdS tt| g|S )Nr   T)r   r   PeekNamedPiper9   boolr   ro   r   r   r   rn   K  s
   zPipeConnection._pollc                 C   s   |  }t }|| t| jd }|dksJ |d ur+t|| |kr+|   tj	| j|dd\}}|
d\}}|dksCJ ||ksIJ ||   |S )Nr   r   Tr   )rk   r   r   r   r   r   r9   rU   rL   r   r   )r<   r   r   rW   r   leftr   Zrbytesr   r   r   r   Q  s   
zPipeConnection._get_more_datar   )rz   r{   r|   __doc__r   r   CloseHandlerB   rV   rb   rn   r   r   r   r   r   r~     s    
 r~   c                   @   s|   e Zd ZdZerejfddZejZ	ej
ZnejfddZejZ	ejZe	fddZefddZd	d
 ZdddZdd ZdS )
Connectionzo
    Connection class based on an arbitrary file descriptor (Unix only), or
    a socket handle (Windows).
    c                 C   r   r   rM   r<   rB   r   r   r   rB   h  r   zConnection._closec                 C   r   r   rM   r   r   r   r   rB   m  r   c                 C   s8   t |}	 || j|}||8 }|dkrd S ||d  }q)NTr   )rU   r9   )r<   rW   r   	remainingr[   r   r   r   _sendr  s   zConnection._sendc                 C   sf   t  }| j}|}|dkr1|||}t|}|dkr$||kr ttd|| ||8 }|dks|S )Nr   zgot end of file during message)r   r   r9   rU   r   rE   r   )r<   rY   readrW   r=   r   chunkr[   r   r   r   _recv{  s   


zConnection._recvc                 C   s   t |}|dkr%tdd}td|}| | | | | | d S td|}|dkr;| | | | d S | ||  d S )Ni!i!Qi @  )rU   structZpackr   )r<   rW   r[   Z
pre_headerheaderr   r   r   rV     s   


zConnection._send_bytesNc                 C   s^   |  d}td| \}|dkr |  d}td| \}|d ur*||kr*d S |  |S )N   r   r      r   )r   r   unpackrc   )r<   r   rW   rY   r   r   r   rb     s   


zConnection._recv_bytesc                 C   s   t | g|}t|S r   )r   r   )r<   r   rr   r   r   rn     s   zConnection._pollr   )rz   r{   r|   r   r   _multiprocessingZclosesocketrB   ra   Z_writerl   Z_readr"   rK   r   r   r   r   rV   rb   rn   r   r   r   r   r   a  s    	

r   c                   @   sR   e Zd ZdZdddZdd Zdd	 Zed
d Zedd Z	dd Z
dd ZdS )r   z
    Returns a listener object.

    This is a wrapper for a bound socket which is 'listening' for
    connections, or for a Windows named pipe.
    Nr   c                 C   sp   |p	|rt |p	t}|pt|}t| |dkrt||| _nt|||| _|d ur3t|ts3t	d|| _
d S )Nr   authkey should be a byte string)r6   default_familyr*   r/   PipeListener	_listenerSocketListener
isinstancerT   	TypeError_authkey)r<   r5   r)   backlogauthkeyr   r   r   r@     s   
zListener.__init__c                 C   s>   | j du r	td| j  }| jrt|| j t|| j |S )zz
        Accept a connection on the bound socket or named pipe of `self`.

        Returns a `Connection` object.
        Nzlistener is closed)r   rE   acceptr   deliver_challengeanswer_challenge)r<   cr   r   r   r     s   

zListener.acceptc                 C   s$   | j }|durd| _ |  dS dS )zA
        Close the bound socket or named pipe of `self`.
        N)r   rK   )r<   Zlistenerr   r   r   rK     s
   zListener.closec                 C      | j jS r   )r   _addressrC   r   r   r   r5        zListener.addressc                 C   r   r   )r   _last_acceptedrC   r   r   r   last_accepted  r   zListener.last_acceptedc                 C   rq   r   r   rC   r   r   r   rr     rs   zListener.__enter__c                 C   rt   r   ru   rv   r   r   r   ry     r   zListener.__exit__)NNr   N)rz   r{   r|   r   r@   r   rK   r}   r5   r   rr   ry   r   r   r   r   r     s    
	

r   c                 C   sh   |pt | }t| |dkrt| }nt| }|dur$t|ts$td|dur2t|| t|| |S )z=
    Returns a connection to the address of a `Listener`
    r   Nr   )	r6   r/   
PipeClientSocketClientr   rT   r   r   r   )r5   r)   r   r   r   r   r   r     s   


r   Tc                 C   sp   | r"t  \}}|d |d t| }t| }||fS t \}}t|dd}t|dd}||fS )L
        Returns pair of connection objects at either end of a pipe
        TFr?   r>   )r.   Z
socketpairsetblockingr   detachr"   pipe)duplexs1s2c1c2Zfd1Zfd2r   r   r   r   	  s   

r   c              
   C   s   t d}| rtj}tjtjB }tt}}ntj}tj}dt}}t||tjB tj	B tj
tjB tjB d||tjtj}t||dtjtjtjtj}t|tjdd tj|dd}|d\}	}
|
dksgJ t|| d}t|| d}||fS )	r   r   r   r   NTr   r   r   )r*   r   PIPE_ACCESS_DUPLEXGENERIC_READGENERIC_WRITEBUFSIZEZPIPE_ACCESS_INBOUNDCreateNamedPipeFILE_FLAG_OVERLAPPEDFILE_FLAG_FIRST_PIPE_INSTANCEPIPE_TYPE_MESSAGEPIPE_READMODE_MESSAGE	PIPE_WAITNMPWAIT_WAIT_FOREVERNULL
CreateFileOPEN_EXISTINGSetNamedPipeHandleStateConnectNamedPiper   r~   )r   r5   ZopenmodeaccessZobsizeZibsizeZh1Zh2r   _r   r   r   r   r   r   r     s>   



	
c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )r   zO
    Representation of a socket which is bound to an address and listening
    r   c                 C   s   t  tt || _z)tjdkr| jt jt jd | jd | j	| | j
| | j | _W n ty?   | j   w || _d | _|dkr]t|s]tj| tj|fdd| _d S d | _d S )Nposixr   Tr   r   argsZexitpriority)r.   getattr_socketr"   nameZ
setsockoptZ
SOL_SOCKETZSO_REUSEADDRr   ZbindZlistenZgetsocknamer   rE   rK   Z_familyr   r   r4   Finalizeunlink_unlink)r<   r5   r)   r   r   r   r   r@   L  s*   



zSocketListener.__init__c                 C   s&   | j  \}| _|d t| S )NT)r   r   r   r   r   r   r<   sr   r   r   r   e  s   
zSocketListener.acceptc                 C   sN   z| j   W | j}|d urd | _|  d S d S | j}|d ur&d | _|  w w r   )r   rK   r   )r<   r   r   r   r   rK   j  s   
zSocketListener.closeN)r   )rz   r{   r|   r   r@   r   rK   r   r   r   r   r   H  s
    
r   c                 C   s\   t | }ttt|}|d ||  t| W  d   S 1 s'w   Y  dS )zO
    Return a connection object connected to the socket given by `address`
    TN)r6   r.   r   r   Zconnectr   r   )r5   r)   r   r   r   r   r   t  s   


$r   c                   @   s8   e Zd ZdZdddZdddZdd	 Zed
d ZdS )r   z0
        Representation of a named pipe
        Nc                 C   sL   || _ | jddg| _d | _td| j  tj| tj| j| j fdd| _	d S )NT)firstz listener created with address=%rr   r   )
r   _new_handle_handle_queuer   r   	sub_debugr   r   _finalize_pipe_listenerrK   )r<   r5   r   r   r   r   r@     s   zPipeListener.__init__Fc              
   C   sH   t jt jB }|r|t jO }t | j|t jt jB t jB t j	t
t
t jt jS r   )r   r   r   r   r   r   r   r   r   ZPIPE_UNLIMITED_INSTANCESr   r   r   )r<   r   flagsr   r   r   r     s   

zPipeListener._new_handlec              
   C   s   | j |   | j d}z	tj|dd}W n ty3 } z|jtjkr& W Y d }~t|S d }~ww z+zt	|j
gdt}W n   |  t|  W |d\}}|dks\J t|S |d\}}|dksmJ w )Nr   Tr   F)r   appendr   popr   r   rE   r   ZERROR_NO_DATAr   r   r   r   r   r   r~   )r<   r=   r   r   resr   r   r   r   r   r     s2   


zPipeListener.acceptc                 C   s$   t d| | D ]}t| qd S )Nz closing listener with address=%r)r   r   r   r   )queuer5   r=   r   r   r   r     s   z$PipeListener._finalize_pipe_listenerr   )F)	rz   r{   r|   r   r@   r   r   staticmethodr   r   r   r   r   r     s    

r   c              
   C   s   t  }	 zt| d t| tjtjB dtjtjtjtj}W n  t	y? } z|j
tjtjfvs4t|r5 W Y d}~nd}~ww nqt|tjdd t|S )zU
        Return a connection object connected to the pipe given by `address`
        r     r   N)r   r   ZWaitNamedPiper   r   r   r   r   r   rE   r   ZERROR_SEM_TIMEOUTZERROR_PIPE_BUSYr   r   r   r~   )r5   r   hr   r   r   r   r     s2   

r      s   #CHALLENGE#s	   #WELCOME#s	   #FAILURE#c                 C   s   dd l }t|tstdt|tt}| 	t
|  |||d }| d}||kr7| 	t d S | 	t td)Nr    Authkey must be bytes, not {0!s}md5   zdigest received was wrong)hmacr   rT   r'   formatr0   r"   urandomMESSAGE_LENGTHr\   	CHALLENGEnewdigestrd   WELCOMEFAILUREr   Z
connectionr   r   messager  Zresponser   r   r   r     s   



r   c                 C   s   dd l }t|tstdt|| d}|d tt tks'J d| |ttd  }|	||d
 }| | | d}|tkrJtdd S )Nr   r   r   zmessage = %rr   zdigest sent was rejected)r   r   rT   r'   r   r0   rd   rU   r  r  r  r\   r  r   r  r   r   r   r     s   

 

r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )ConnectionWrapperc                 C   s6   || _ || _|| _dD ]}t||}t| || qd S )N)rQ   rK   rp   rd   r\   )_conn_dumps_loadsr   setattr)r<   connr^   rj   attrr`   r   r   r   r@     s   
zConnectionWrapper.__init__c                 C   s   |  |}| j| d S r   )r  r  r\   )r<   r`   r   r   r   r   ra   
  s   
zConnectionWrapper.sendc                 C   s   | j  }| |S r   )r  rd   r  r   r   r   r   rl     s   

zConnectionWrapper.recvN)rz   r{   r|   r@   ra   rl   r   r   r   r   r
    s    r
  c                 C   s   t | fd d d ddS )Nr   utf-8)	xmlrpclibr^   encode)r`   r   r   r   
_xml_dumps  s   r  c                 C   s   t | d\\}}|S )Nr  )r  rj   decode)r   r`   methodr   r   r   
_xml_loads  s   r  c                   @   s   e Zd Zdd ZdS )XmlListenerc                 C   s"   dd l ma t| }t|ttS Nr   )xmlrpc.clientclientr  r   r   r
  r  r  r_   r   r   r   r     s   
zXmlListener.acceptN)rz   r{   r|   r   r   r   r   r   r    s    r  c                  O   s"   dd l ma tt| i |ttS r  )r  r  r  r
  r   r  r  )r   kwdsr   r   r   	XmlClient  s   r  c                 C   s   t | }g }|rZt|d|}|tkr	 |S t|  kr$tt| k r+n n|t8 }nt|  kr9tt| k rCn td|t8 }ntd|||  ||d d  }d}|s|S )NFzShould not get herer   r   )	listr   r   r   r   rU   r   r   r   )Zhandlesr   Lreadyr   r   r   r   _exhaustive_wait*  s$   
 

r!  c           
         s  |du rt }n|dk rd}nt|d d }t| } i g }t  t }z| D ]}zt|d}W n ty?   || < Y q'w zt| dd\}}W n t	yi } zd|j
}}|tvr_ W Y d}~nd}~ww |tjkrz|| ||j< q'|rt dd dkrz	|d	\}	}W n t	y } z	|j
}W Y d}~nd}~ww |st|d
rd|_ | d}q't |}W |D ]}|  q|D ]D}z	|d\}	}W n t	y } z|j
}|tvr W Y d}~nd}~ww |tjkr|j } | |dkrt|d
rd|_qnU|D ]}|  q|D ]G}z	|d\}	}W n t	yC } z|j
}|tvr9 W Y d}~nd}~ww |tjkrb|j } | |dkrbt|d
rbd|_qw  fdd|D   fdd| D S )
        Wait till an object in object_list is ready/readable.

        Returns list of those objects in object_list which are ready/readable.
        Nr   r   g      ?rQ   T   )   r#  Fr   c                 3   s    | ]} | V  qd S r   r   ).0r   )waithandle_to_objr   r   	<genexpr>  s    zwait.<locals>.<genexpr>c                    s   g | ]}| v r|qS r   r   )r%  o)ready_objectsr   r   
<listcomp>  s    wait.<locals>.<listcomp>)r   intr  setr   AttributeErrorr8   r   r   rE   r   _ready_errorsr   r   r   r+   Zgetwindowsversionr   r-   r   addr!  keysr   ZERROR_OPERATION_ABORTEDupdate)
object_listr   Zov_listZready_handlesr(  rQ   r   r   r   r   r   )r)  r&  r   r   @  s   










r   PollSelectorc                 C   s   t  E}| D ]	}||tj q|durt | }	 ||}|r0dd |D W  d   S |durG|t  }|dk rG|W  d   S q1 sKw   Y  dS )r"  NTc                 S   s   g | ]\}}|j qS r   )Zfileobj)r%  keyZeventsr   r   r   r*    s    r+  r   )_WaitSelectorregister	selectorsZ
EVENT_READr   r   Zselect)r3  r   Zselectorr`   Zdeadliner   r   r   r   r     s"   
c                 C   sf   |   }t|tjtj}ddlm} ||}t|| j	| j
ffW  d    S 1 s,w   Y  d S )Nr   )resource_sharer)rQ   r.   Zfromfdr   ZSOCK_STREAMr!   r9  Z	DupSocketrebuild_connectionr>   r?   )r  r=   r   r9  dsr   r   r   reduce_connection  s   
$r<  c                 C   s   |   }t|  ||S r   r   r   )r;  r>   r?   Zsockr   r   r   r:    s   r:  c                 C   sB   | j rtjnd| jrtjndB }t|  |}t|| j | jffS r  )	r>   r   ZFILE_GENERIC_READr?   ZFILE_GENERIC_WRITEr
   Z	DupHandlerQ   rebuild_pipe_connection)r  r   dhr   r   r   reduce_pipe_connection  s
   r@  c                 C      |   }t|||S r   )r   r~   )r?  r>   r?   r=   r   r   r   r>       r>  c                 C   s    t |  }t|| j| jffS r   )r
   ZDupFdrQ   r:  r>   r?   )r  dfr   r   r   r<    s   c                 C   rA  r   r=  )rC  r>   r?   fdr   r   r   r:    rB  )NN)Tr   )I__all__r   r"   r+   r.   r   r   r&   	itertoolsr   r!   r   r   r	   contextr
   ZForkingPicklerr]   r   r   r   r   r   ImportErrorr,   r   ZCONNECTION_TIMEOUTcountr%   r   Zfamiliesr-   r   r   r*   r/   r6   r7   r~   r   objectr   r   r   r   r   r   r   r  r  r  r  r   r   r
  r  r  r  r  r!  r   ZERROR_NETNAME_DELETEDr/  r   r8  r4  r6  ZSelectSelectorr<  r:  r7  r@  r>  r   r   r   r   <module>   s   	
	



 PT
=

,,
8	P
