o
    4@Hh	                  
   @  s  d dl mZ d dlZd dlmZ d dlmZ d dlmZm	Z	 d dl
Z
d dlZd dlmZ zd dlZd dlmZ W n eyN Z z
ee W Y dZ[ndZ[ww d dlZd dlZd dlmZmZ d d	lmZmZ d
dlmZmZmZ eryd dlmZ e  Z!e!"dZ#e$ej%Z&e#'e& e$ej%Z(e!)e( ej*j+ddej,dedgddgdZ-d_ddZ.eddddd`d d!Z/e-dad#d$Z0edbd'd(Z1dcd)d*Z2dcd+d,Z3dcd-d.Z4dcd/d0Z5dcd1d2Z6dcd3d4Z7dcd5d6Z8ddd8d9Z9ddd:d;Z:ddd<d=Z;ddd>d?Z<ddd@dAZ=dcdBdCZ>edcdDdEZ?dddFdGZ@dcdHdIZAe-dedJdKZBej*CdLdcdMdNZDej*CdLdcdOdPZEej*CdLdcdQdRZFej*CdLdcdSdTZGdcdUdVZHdddWdXZIdddYdZZJdcd[d\ZKdcd]d^ZLdS )f    )annotationsN)asynccontextmanager)count)TYPE_CHECKINGNoReturn)skip_if_optional_else_raise)SSL)DTLSChannelDTLSEndpoint)FakeNet	UDPPacket   )
binds_ipv6gc_collect_harderslow)AsyncGeneratorzexample.comipv6FT)marksipv4)idskwargs
int | boolreturnr
   c                  K  sD   |  dd}|rtjjntjj}tjjtjj|d}t|fi | S )Nr   F)typefamily)poptriosocketAF_INET6AF_INET
SOCK_DGRAMr
   )r   r   r   sock r"   U/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/trio/_tests/test_dtls.pyendpoint/   s   r$   )
autocancelmtur   r%   boolr&   
int | None:AsyncGenerator[tuple[DTLSEndpoint, tuple[str, int]], None]c              
    s   t |da}|rdnd}|j|dfI d H  t 4 I d H ,}d fd	d
}||jt|I d H  ||j fV  | rB|j	
  W d   I d H  n1 I d H sRw   Y  W d    d S W d    d S 1 sjw   Y  d S )Nr   z::1	127.0.0.1r   dtls_channelr	   r   Nonec                   s   t d| jj d| j  d ur|   z/t d |  I d H  t d | 2 z3 d H W }t d|d| j | |I d H  q+6 W d S  tj	yW   t d Y d S w )Nzecho handler started: server z client zserver starting do_handshakezserver finished do_handshakezechoing  -> zecho handler channel broken)
printr$   r   getsocknamepeer_addressset_ciphertext_mtudo_handshakesendr   BrokenResourceError)r,   packetr&   r"   r#   echo_handlerB   s*   

z&dtls_echo_server.<locals>.echo_handler)r,   r	   r   r-   )r$   r   bindr   open_nurserystartserve
server_ctxr0   cancel_scopecancel)r%   r&   r   server	localhostnurseryr8   r"   r7   r#   dtls_echo_server6   s   
*"rC   r-   c              
     s  t | d4 I d H \}}t| d}||t}ttj |  W d    n1 s.w   Y  |	 I d H  |
dI d H  | I d H dksMJ |
dI d H  | I d H dks`J tjtdd |
dI d H  W d    n1 szw   Y  |d | }|d | |ksJ |d | |ksJ W d    n1 sw   Y  W d   I d H  d S 1 I d H sw   Y  d S )	Nr*      hellos   goodbyez4^openssl doesn't support sending empty DTLS packets$match    i  i  )rC   r$   connect
client_ctxpytestraisesr   NeedHandshakeErrorget_cleartext_mtur3   r4   receive
ValueErrorr2   )r   _server_endpointaddressclient_endpointclient_channelcleartext_mtu_1234r"   r"   r#   
test_smoke^   s4   



.rU   autojump_clocktrio.testing.MockClockc           
        s  d}t dt     d| _t 4 I d H \}}t 4 I d H d fdd	dfd
d}| _t	|D ]j}t
d t
d t
d t Q}||t}t
d | I d H  t
d t| }	 td}	||I d H  | I d H |ksJ W d    n1 sw   Y  |	jsnqjW d    n1 sw   Y  q<W d   I d H  n1 I d H sw   Y  W d   I d H  d S 1 I d H sw   Y  d S )Nd   r   gMbP?r6   r   r   r-   c                   s   	 j g dg ddd }t| j d| j d|  |dkr#d S |d	kr- |  n/|d
kr>t d I d H  n|dksDJ t| j d| j d| j	    
|  d S q)NT)deliverdropdupedelay)gffffff?皙?r]   r]   )weightsr   r.   z: rZ   r[   r\      rY   z: delivered )choicesr/   sourcedestinationsend_packetr   sleeprandompayloadhexdeliver_packet)r6   op)fnrr"   r#   route_packet   s0   
z:test_handshake_over_terrible_network.<locals>.route_packetc                   s(   z	  |  W d S  ty   Y d S w N)
start_soonRuntimeErrorr6   )rB   rl   r"   r#   route_packet_wrapper   s
   zBtest_handshake_over_terrible_network.<locals>.route_packet_wrapperzP################################################################################zclient starting do_handshakezclient finished do_handshakeT
   r6   r   r   r-   )re   Randomr   enableautojump_thresholdrC   r   r:   rl   ranger/   r$   rH   rI   r3   strencodemove_on_afterr4   rN   cancelled_caught)
rV   
HANDSHAKES_rQ   rq   irR   clientmsgcscoper"   )rj   rB   rk   rl   r#   $test_handshake_over_terrible_networkz   sF   
-*.r   c               	     s   t  4 I d H :\} }t !}||t}|dI d H  | I d H dks(J W d    n1 s2w   Y  W d   I d H  d S 1 I d H sHw   Y  d S )N   xyz)rC   r$   rH   rI   r4   rN   r}   rQ   rR   r   r"   r"   r#   test_implicit_handshake   s   .r   c                    sD  t  } t  x}| jdI d H  t 4 I d H T}d	dd}|| jt|I d H  || j	 t
}t 4 I d H }||jd ||j W d   I d H  n1 I d H sZw   Y  |j  W d   I d H  n1 I d H stw   Y  W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )
Nr+   r   channelr	   r   r-   c              	     s^   t  4 I d H }|| jd || j W d   I d H  d S 1 I d H s(w   Y  d S )Ns   from server)r   r:   rn   r4   rN   )r   rB   r"   r"   r#   handler   s
   .z!test_full_duplex.<locals>.handlers   from clientr   r	   r   r-   )r$   r   r9   r   r:   r;   r<   r=   rH   r0   rI   rn   r4   rN   r>   r?   )server_endpointrR   server_nurseryr   r   rB   r"   r"   r#   test_full_duplex   s$   
((Pr   c               
     s  t  4 I d H x\} }t _}||t}| I d H  |  ttj	 |
dI d H  W d    n1 s9w   Y  ttj	 | I d H  W d    n1 sVw   Y  |  | I d H  W d    n1 spw   Y  W d   I d H  d S 1 I d H sw   Y  d S )N   abc)rC   r$   rH   rI   r3   closerJ   rK   r   ClosedResourceErrorr4   rN   acloser   r"   r"   r#   test_channel_closing   s    .r   c               	     sX   t dd4 I d H \} }|   W d   I d H  n1 I d H s!w   Y  |   d S )NF)r%   )rC   r   )r   _addressr"   r"   r#   !test_serve_exits_cleanly_on_close  s
   
(r   c                    sR  t  4 I d H \} }t  4 I d H \} }t }||t}||t}|dI d H  |dI d H  | I d H dksAJ | I d H dksLJ |  tt	j
 |dI d H  W d    n1 siw   Y  tt	j
 | I d H  W d    n1 sw   Y  tt	j
 ||t W d    n1 sw   Y  d
dd	}t	 4 I d H ,}tt	j
 ||jt|I d H  W d    n1 sw   Y  W d   I d H  n1 I d H sw   Y  W d    n1 sw   Y  W d   I d H  n1 I d H sw   Y  W d   I d H  d S 1 I d H s"w   Y  d S )Nr   r      xxxr}   objectr   r-   c                      d S rm   r"   r}   r"   r"   r#   null_handler$     z+test_client_multiplex.<locals>.null_handlerr}   r   r   r-   )rC   r$   rH   rI   r4   rN   r   rJ   rK   r   r   r:   r;   r<   r=   )r}   address1address2rR   client1client2r   rB   r"   r"   r#   test_client_multiplex  s8   *
(\r   c               	     sx   t j ,} tjtdd t|  W d    n1 sw   Y  W d    d S W d    d S 1 s5w   Y  d S )Nz#^DTLS requires a SOCK_DGRAM socket$rE   )r   r   rJ   rK   rO   r
   )sr"   r"   r#   test_dtls_over_dgram_only,  s   
"r   c               
     sT  ddd} t  }|jdI d H  t 4 I d H <}||jt| I d H  t	tj
 ||jt| I d H  W d    n1 sCw   Y  |j  W d   I d H  n1 I d H s]w   Y  t 4 I d H }||jt| I d H  |j  W d   I d H  n1 I d H sw   Y  W d    d S W d    d S 1 sw   Y  d S )	Nr}   r   r   r-   c                   r   rm   r"   r   r"   r"   r#   r   3  r   z'test_double_serve.<locals>.null_handlerr   r   )r$   r   r9   r   r:   r;   r<   r=   rJ   rK   BusyResourceErrorr>   r?   )r   r   rB   r"   r"   r#   test_double_serve2  s$   
(*	"r   trio.abc.Clockc              
     s   t  }|  t W}t ;}|jdI d H  td}||j t	}|
 I d H  W d    n1 s9w   Y  |jsCJ W d    n1 sMw   Y  W d    d S W d    d S 1 sew   Y  d S )Nr   rX   )r   ru   r$   r   r9   r   rz   rH   r0   rI   r3   r{   )rV   rj   r   r   r   r   r"   r"   r#   test_connect_to_non_serverD  s   Pr   c           	   
     sB  t  }|  dD ]}t 4 I d H \}}t|df}|j|ks#J ||t}t|d D ]}|t	|
 I d H  tdI d H  q/| }|jdksQJ t|D ]}| I d H t	|
 ksfJ qU|dI d H  | I d H dkszJ W d    n1 sw   Y  W d   I d H  n1 I d H sw   Y  q
d S )N)rr      )incoming_packets_buffer      s   buffer clear now)r   ru   rC   r$   r   rH   rI   rw   r4   rx   ry   r   rd   
statistics incoming_packets_dropped_in_triorN   )	rV   rj   buffer_sizer}   rQ   rR   r   r~   statsr"   r"   r#   test_incoming_buffer_overflowP  s*    (r   c                   s  t  }|  ddlm}m}m}m}m}m}m	} |||j
|jd|||jddddtddd}	|	d }
|	d d }|	d d }t|	}d	|d
< |||j
|jd|||jddddtddd}|||j
|jd|||jddddtddd d}|||j
|jddd}|||j
|jdtdd d}t 4 I d H G\}}tjjtjjd(}dd|
|||||||f
D ]}|||I d H  tdI d H  qW d    n1 sw   Y  W d   I d H  d S 1 I d H sw   Y  d S )Nr   )ContentTypeHandshakeFragmentHandshakeTypeProtocolVersionRecordencode_handshake_fragmentencode_recordrr   )msg_typemsg_lenmsg_seqfrag_offsetfrag_lenfrag)content_typeversionepoch_seqnorf                r   rG   #      r   r   r   )r   ru   
trio._dtlsr   r   r   r   r   r   r   	handshakeDTLS10client_hellobytes	bytearrayrC   r   r   r    sendtord   )rV   rj   r   r   r   r   r   r   r   r   client_hello_extendedclient_hello_shortclient_hello_really_shortclient_hello_corrupt_record_lenclient_hello_fragmented$client_hello_trailing_data_in_recordhandshake_empty client_hello_truncated_in_cookier}   rQ   r!   
bad_packetr"   r"   r#   *test_server_socket_doesnt_crash_on_garbagec  s   $

	
	.r   c              
     s   t    ddlm m t Qtdd fdd	}|_t	 4 I d H %\}}	 t
 }||t}| I d H  W d    n1 sMw   Y  q21 I d H sYw   Y  W d    n1 shw   Y  jsrJ d S )Nr   )	BadPacketdecode_client_hello_untrustedr   r6   r   r   r-   c                   s   z
| j \}}}W n	  y   Y n/w t|dkrBt| j }t}|t|kr3t|d }  ||  dN  < tj| |d} |  d S )Nr   r   )rf   )rf   lenr   nextr?   attrsevolverh   )r6   r}   cookierf   offsetr   r   r   rj   offset_to_corruptr"   r#   rl     s   
z2test_invalid_cookie_rejected.<locals>.route_packetTrs   )r   ru   r   r   r   r   CancelScoper   rl   rC   r$   rH   rI   r3   r{   )rV   rl   r}   rQ   r   r   r"   r   r#   test_invalid_cookie_rejected  s$   
!r   c                   s  t  }|  t }t }|jdI d H  t 4 I d H r}dd fdd}||jt	|I d H  t
d	 t  ||j t}| I d H  W d    n1 sZw   Y   jsdJ t
d
 ||j t}| I d H dks|J tdI d H  |j  W d   I d H  n1 I d H sw   Y  W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )Nr   Tr   r	   r   r-   c                   s   r9dt d    tdI d H  t d ttj |  I d H  W d    d S 1 s2w   Y  d S t d | dI d H  d S )NFz'handler: first time, cancelling connectg      ?z"handler: handshake should fail nowz&handler: not first time, sending hellorD   )	r/   r?   r   rd   rJ   rK   r5   r3   r4   r   connect_cscope
first_timer"   r#   r     s   "zAtest_client_cancels_handshake_and_starts_new_one.<locals>.handlerzclient: starting first connectzclient: starting second connectrD   rr   r   )r   ru   r$   r   r9   r   r:   r;   r<   r=   r/   r   rH   r0   rI   r3   r{   rN   rd   r>   r?   )rV   rj   r@   r   rB   r   r   r"   r   r#   0test_client_cancels_handshake_and_starts_new_one  s.   

(Pr   c                    s  t  } t  }| jdI d H  |jdI d H  ddd d fdd	}t 4 I d H }|| jt|I d H  ||jt I d H  || j	 t
}|d
I d H  | I d H d
ksbJ | |j	 t
}| I d H  ttj |dI d H  W d    n1 sw   Y  |dI d H  | I d H dksJ |j  W d   I d H  n1 I d H sw   Y  W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )Nr   r   r	   r   r-   c                   s*   | 2 z3 d H W }|  |I d H  q6 d S rm   )r4   )r   r6   r"   r"   r#   r8   1  s   z-test_swap_client_server.<locals>.echo_handlerc                   sB   t tj  | I d H  W d    d S 1 sw   Y  d S rm   )rJ   rK   r   r5   r   r8   r"   r#   crashing_echo_handler5     "z6test_swap_client_server.<locals>.crashing_echo_handlers   b as clients   association brokens   a as clientr   )r$   r   r9   r   r:   r;   r<   r=   rH   r0   rI   r4   rN   r3   rJ   rK   r5   r>   r?   )abr   rB   b_to_aa_to_br"   r   r#   test_swap_client_server,  s.   
(Pr   c                    s  t    ddfdd} | _t 4 I d H c\} t Jt 4 I d H /}d fdd	}|| td
I d H  d|j	
dj	 I d H  W d   I d H  n1 I d H s`w   Y  W d    n1 sow   Y  W d   I d H  d S 1 I d H sw   Y  d S )NTr6   r   r   r-   c                   s*    r	t d|  d S t d|  |  d S )Nzdropped packetzdelivered packet)r/   rh   rp   
blackholedrj   r"   r#   rl   U  s
   

z@test_openssl_retransmit_doesnt_break_stuff.<locals>.route_packetc                    sJ     t} | jddI d H  | dI d H  |  I d H dks#J d S )Ng      ?initial_retransmit_timeout   hi)rH   rI   r3   r4   rN   )r   )rQ   rR   r"   r#   	connecteri  s
   z=test_openssl_retransmit_doesnt_break_stuff.<locals>.connecterg?Fr   rs   r   r-   )r   ru   rl   rC   r$   r   r:   rn   rd   r   r   r0   )rl   r   rB   r   r"   )rQ   r   rR   rj   r#   *test_openssl_retransmit_doesnt_break_stuffK  s*   
(.r   c           	   
     s   t    d d
 fdd}|_t 4 I d H G\}}dD ]6}t )}t }d ||t}|j	|d	I d H  t }|| |ksHJ W d    n1 sRw   Y  q!W d   I d H  d S 1 I d H siw   Y  d S )NTr6   r   r   r-   c                   s    rd d S  |  d S )NF)rh   rp   r   r"   r#   rl     s   zCtest_initial_retransmit_timeout_configuration.<locals>.route_packet)r   r      r   rs   )
r   ru   rl   rC   r$   r   current_timerH   rI   r3   )	rV   rl   r}   rQ   tr   beforer   afterr"   r   r#   -test_initial_retransmit_timeout_configuration  s&   .r   c               	     s   d t    d
 fdd} | _t d4 I d H F\}}t -}||t}|  | I d H  |	d	I d H  |
 I d H d	ksJJ W d    n1 sTw   Y  W d   I d H  d S 1 I d H sjw   Y  d S )Ni,  r6   r   r   r-   c                   sB   t d|   t dt| j  t| j ksJ |  d S )Ndelivering zpayload size: )r/   r   rf   rh   rp   MTUrj   r"   r#   rl     s   z9test_explicit_tiny_mtu_is_respected.<locals>.route_packetr7   r   rs   )r   ru   rl   rC   r$   rH   rI   r2   r3   r4   rN   )rl   _serverrQ   r   r   r"   r   r#   #test_explicit_tiny_mtu_is_respected  s   
.r  c              	     s   t      | rdndd fdd}| _t| d	4 I d H I\}}t| d	.}||t}|d
 |dI d H  |	 I d H dksIJ |
 dksQJ W d    n1 s[w   Y  W d   I d H  d S 1 I d H sqw   Y  d S )Ni  i$  r6   r   r   r-   c                   s<   t | jkrtd|   d S td|    |  d S )Nz	dropping r   )r   rf   r/   rh   rp   rj   r&   r"   r#   rl     s   z@test_handshake_handles_minimum_network_mtu.<locals>.route_packetr*   i'  r   i(#  rs   )r   ru   rl   rC   r$   rH   rI   r2   r4   rN   rM   )r   rV   rl   r}   rQ   rR   r   r"   r  r#   *test_handshake_handles_minimum_network_mtu  s   
.r  z$always:unclosed DTLS:ResourceWarningc                    s   t j j} ddd}tt | I d H }t j I d H  t	  W d    n1 s-w   Y  t j I d H  t j j}| |k sFJ | |ksLJ d S )Nr   intc               
     s   t  } tjjtjjdI}|dI d H  | | t}t 4 I d H }|	|j
 tj I d H  |j  W d   I d H  n1 I d H sJw   Y  W d    n1 sYw   Y  tj j}|S )Nr   r   )r$   r   r   r    r9   rH   r0   rI   r:   rn   r3   testingwait_all_tasks_blockedr>   r?   lowlevelcurrent_statisticstasks_living)er   crB   during_tasksr"   r"   r#   start_and_forget_endpoint  s   (zDtest_system_task_cleaned_up_on_gc.<locals>.start_and_forget_endpoint)r   r  )
r   r	  r
  r  rJ   warnsResourceWarningr  r  r   )before_tasksr  r  after_tasksr"   r"   r#   !test_system_task_cleaned_up_on_gc  s   
r  c                    sN   t  } tt ~ t  W d    n1 sw   Y  tj I d H  d S rm   )r$   rJ   r  r  r   r   r  r  r  r"   r"   r#   !test_gc_before_system_task_starts  s   r  c                    s   t  } |   t }|jdI d H  |  tj I d H  tjjtjj	d}|
d|j I d H  W d    n1 s@w   Y  tt ~t  W d    d S 1 sZw   Y  d S )Nr   r   r   )r   ru   r$   r   r9   _ensure_receive_loopr   r  r  r    r   r0   rJ   r  r  r   )rj   r  r   r"   r"   r#   test_gc_as_packet_received  s   "r  c                  C  sL   ddd} t | }tt ~t  W d    d S 1 sw   Y  d S )Nr   r
   c                    s   t  } |   t S rm   )r   ru   r$   )rj   r"   r"   r#   main  s   z&test_gc_after_trio_exits.<locals>.main)r   r
   )r   runrJ   r  r  r   )r  r  r"   r"   r#   test_gc_after_trio_exits  s   

	"r  c                    sH   t  } | j  tj I d H  W d    d S 1 sw   Y  d S rm   )r$   r   r   r   r  r  r  r"   r"   r#   'test_already_closed_socket_doesnt_crash-  s
   
"r  c              
     s   t      t 4 I d H N\}d fdd}| _t *}td ||t}|	 I d H  W d    n1 s>w   Y  W d    n1 sMw   Y  W d   I d H  d S 1 I d H scw   Y  d S )	Nr6   r   r   r-   c                   s     |  j  d S rm   )rh   r   r   rp   rj   r@   r"   r#   rl   @  s   
zEtest_socket_closed_while_processing_clienthello.<locals>.route_packetrr   rs   )
r   ru   rC   rl   r$   r   rz   rH   rI   r3   )rV   rQ   rl   rR   r   r"   r  r#   /test_socket_closed_while_processing_clienthello6  s   .r  c                   s  t  }|  d
dd}||_t 4 I d H _\}}t F}||t t 4 I d H %}d fdd}|	| t
d	I d H  ||t W d   I d H  n1 I d H sWw   Y  W d    n1 sfw   Y  W d   I d H  d S 1 I d H s|w   Y  d S )Nr6   r   r   r-   c                 S  s   d S rm   r"   rp   r"   r"   r#   rl   R  s   zGtest_association_replaced_while_handshake_running.<locals>.route_packetc                     sB   t tj   I d H  W d    d S 1 sw   Y  d S rm   )rJ   rK   r   r5   r3   r"   c1r"   r#   doomed_handshake\  r   zKtest_association_replaced_while_handshake_running.<locals>.doomed_handshakerr   rs   r   )r   ru   rl   rC   r$   rH   rI   r   r:   rn   rd   )rV   rj   rl   r}   rQ   rR   rB   r!  r"   r  r#   1test_association_replaced_while_handshake_runningL  s"   

(.r"  c               
     s   t  } |   ddd}|| _t 4 I d H J\}}t 1}||t}||t tt	j
 | I d H  W d    n1 sBw   Y  W d    n1 sQw   Y  W d   I d H  d S 1 I d H sgw   Y  d S )Nr6   r   r   r   c                 S  s   t  rm   )AssertionErrorrp   r"   r"   r#   rl   l  s   zGtest_association_replaced_before_handshake_starts.<locals>.route_packet)r6   r   r   r   )r   ru   rl   rC   r$   rH   rI   rJ   rK   r   r5   r3   )rj   rl   r}   rQ   rR   r   r"   r"   r#   1test_association_replaced_before_handshake_startsg  s   
.r$  c                    s  t  4 I d H s\} }t Z}t 4 I d H ?}tddD ]}|d|ft}||j q||t}|	dI d H  |
 I d H dksGJ |j  W d   I d H  n1 I d H s\w   Y  W d    n1 skw   Y  W d   I d H  d S 1 I d H sw   Y  d S )Nr   rr   r+   r   )rC   r$   r   r:   rw   rH   rI   rn   r3   r4   rN   r>   r?   )r}   rQ   rR   rB   r~   r   r"   r"   r#   test_send_to_closed_local_porty  s   (.r%  )r   r   r   r
   )r%   r'   r&   r(   r   r'   r   r)   )r   r'   r   r-   )rV   rW   r   r-   r   )rV   r   r   r-   )r   r'   rV   r   r   r-   )M
__future__r   re   
contextlibr   	itertoolsr   typingr   r   r   rJ   trio._tests.pytest_pluginr   trustmeOpenSSLr   ImportErrorerrorr   trio.testingr	   r
   trio.testing._fake_netr   r   _core._tests.tutilr   r   r   collections.abcr   CAca
issue_certserver_certContextDTLS_METHODr=   configure_certrI   configure_trustmarkparametrizeparamparametrize_ipv6r$   rC   rU   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  filterwarningsr  r  r  r  r  r  r"  r$  r%  r"   r"   r"   r#   <module>   s    



'
X










r
*
-
4

"
#




	

