
    ∋d]                       d dl m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Zd dlmZmZ d dlmZmZ d dlmZ d dlmZmZ d dlmZmZ d dlmZ d d	lmZ d dlZd d
lmZ d dl m!Z!m"Z" d dl#m$Z$m%Z%m&Z&m'Z'm(Z( d dl)m*Z* d dl+m,Z,m-Z-m.Z.m/Z/m0Z0 d dl1m2Z2m3Z3 d dl4m5Z5 d dl6m7Z7m8Z8m9Z9m:Z:m;Z;  ej<        e=          Z>e
j?        dk     rd ej@        ejA                  z  dz  dz
  ZBnd ej@        ejC                  z  dz
  ZBe5dz  ZDd ZEd ZFd ZGd ZH G d de$          ZI G d deI          ZJd ZK G d d           ZLejM        ejN        z  ZOejP        d!d"ZQ G d# d$ejR                  ZS G d% d&e&eL          ZT G d' d(eT          ZU G d) d*eT          ZV G d+ d,e(eL          ZW G d- d.eW          ZX G d/ d0eW          ZY G d1 d2e*          ZZ G d3 d4eZ          Z[ G d5 d6eZ          Z\dS )7    )annotationsN)SSLCertVerificationErrorSSLError)AnyClassVar)sliding_window)gennetutil)IOStreamStreamClosedError)	TCPClient)	TCPServer)parse_timedelta)parse_host_portunparse_host_port)CommCommClosedError	ConnectorFatalCommClosedErrorListener)Backend)ensure_concrete_hostfrom_framesget_tcp_server_address
host_array	to_frames)pack_frames_preludeunpack_frames)MEMORY_LIMIT)	ensure_ipensure_memoryviewget_ipget_ipv6nbytes)   
            c                :   |                                  rdS t          j                            d          }t	          t          |d                    }| j        }d}||dz   k    s
J d            t          d|d	z            }t          d||z
  |z            }|||z  z
  }|d
k    sJ 	 t          j	        
                    d          rFt                              d||           |                    t          j        d|dz  |dz  f           n|                    t          j        t          j        d           	 t          j        }t          j        }t          j        }n)# t*          $ r t          j	        dk    rd}d}d}nd}Y nw xY w|t                              d|||           |                    t          j        ||           |                    t          j        ||           |                    t          j        ||           t          j	        
                    d          rFt                              d|dz             d}	|                    t          j        |	|dz             dS dS # t.          $ r t                              d           Y dS w xY w)z5
    Set kernel-level TCP timeout on the stream.
    Nzdistributed.comm.timeouts.tcpseconds)defaultr&   r)   zTimeout too lowr(      r   winz+Setting TCP keepalive: idle=%d, interval=%di  darwin   i  i  z7Setting TCP keepalive: nprobes=%d, idle=%d, interval=%dlinuxzSetting TCP user timeout: %d ms   z$Could not set timeout on TCP stream.)closeddaskconfiggetintr   socketmaxsysplatform
startswithloggerdebugioctlSIO_KEEPALIVE_VALS
setsockopt
SOL_SOCKETSO_KEEPALIVETCP_KEEPIDLETCP_KEEPINTVLTCP_KEEPCNTAttributeErrorSOL_TCPOSError	exception)
commtimeoutsocknprobesidleintervalrD   rE   rF   TCP_USER_TIMEOUTs
             4lib/python3.11/site-packages/distributed/comm/tcp.pyset_tcp_timeoutrS   ;   s    {{}} koo=>>G/'9===>>G;D Ggk!!!#4!!!q'Q,D1w~'122HX''D!8888"A<""5)) 	ILLFhWWWJJv01dTk8d?2STTTTOOF-v/BAFFF
(%2 & 4$0! ( ( (<8++#'L$)M"'KK#'L( 'M	   WEEEdCCCxHHH<""7++ 	NLL:GdNKKK!OOFN,<gnMMMMM	N 	N  A A A?@@@@@@As8   *BI2 ;$E  I2  #FI2 FC(I2 2$JJc                    |                                  rdS 	 t          | j                                        dd          S # t          $ r Y dS w xY w)z'
    Get a stream's local address.
    z<closed>Nr(   )r3   r   r8   getsocknamerI   )rK   s    rR   get_stream_addressrV   v   sb     {{}} z $+"9"9";";BQB"?@@   zzs   'A   
AAc                (   |j         v|j         }t          |t          j                  r2|j        r+d|j        v r"t          d|  d|j        j         d|           t          d|  d|j        j         d|           |t          d|  d|           |)z8
    Re-raise StreamClosedError as CommClosedError.
    N
UNKNOWN_CAzin z: )	
real_error
isinstancesslr   reasonr   	__class____name__r   )objexcs     rR   convert_stream_closed_errorra      s     ~!nc3<(( 	Yz Ylcj88*+W+W+W8N+W+WRU+W+WXXXJCJJ3=+AJJSJJKKQTT0C0030011s:    c                0     |             }|r	d|_         dS dS )zCallback to close Dask Comm when Tornado Stream closes

    Parameters
    ----------
        ref: weak reference to a Dask comm
    TN_closed)refrK   s     rR   _close_commrg      s,     355D  rb   c                  4    e Zd ZU dZej                            ej                            d                    Z	de
d<   de
d<   	 dd fdZd Zd Zedd            Zedd            Zd dZd!dZej        d             Zd"dZd#dZed             Z xZS )$TCPzO
    An established communication based on an underlying Tornado IOStream.
    zdistributed.comm.shardzClassVar[int]max_shard_sizezIOStream | NonestreamTr   
local_addrstr	peer_addrdeserializeboolc                   d| _         t                                          |           || _        || _        || _        t          j        | |                                           | _	        d| j	        _
        i | _        t          j        |           }|                    t          j        t           |                     |                    d           t%          |           |                                  d S )NF)ro   T)re   super__init___local_addr
_peer_addrrk   weakreffinalize_get_finalizer
_finalizeratexit_extrarf   set_close_callback	functoolspartialrg   set_nodelayrS   _read_extra)selfrk   rl   rn   ro   rf   r]   s         rR   rs   zTCP.__init__   s     [111%#!*41D1D1F1FGG!&k$!!)"3K"E"EFFF4   rb   c                    d S N r   s    rR   r   zTCP._read_extra   s    rb   c                :    t          |           }| j        |fd}|S )Nc                    | G|                                  s5t                              d|            |                                  d S d S d S )NzClosing dangling stream in )r3   r=   warningclose)rk   rs     rR   rw   z$TCP._get_finalizer.<locals>.finalize   sQ     !&--//!@Q@@AAA "!!!rb   )reprrk   )r   r   rw   s      rR   rx   zTCP._get_finalizer   s/    JJ K1 	 	 	 	 rb   returnc                    | j         S r   )rt   r   s    rR   local_addresszTCP.local_address   s    rb   c                    | j         S r   )ru   r   s    rR   peer_addresszTCP.peer_address   s
    rb   Nc                n  K   | j         }|t                      d}t          j        |          }	 |                    |           d {V }t          j        ||          \  }t          |          }t          dt          d|t          z   t                              D ]C\  }}|||         }	|	j
        }
|                    |	           d {V }||
k    sJ ||
f            D	 	 t          |          }t          || j        || j                   d {V }n1# t           $ r$ |                                  t          d          w xY w|S # t$          $ rB}d | _         d| _        t)          j                    st-          | |           Y d }~d S Y d }~d S d }~wt.          $ r |                                   w xY w)NQr(   r   )ro   deserializersallow_offloadz aborted stream on truncated dataT)rk   r   structcalcsize
read_bytesunpackr   r   rangeOPENSSL_MAX_CHUNKSIZEr$   	read_intor   r   ro   r   EOFErrorabortr   re   r:   is_finalizingra   BaseException)r   r   rk   fmtfmt_sizeframes_nbytesframesijchunkchunk_nbytesnmsges                 rR   readzTCP.read   sU     >!###?3''(	"("3"3H"="=======M%}S-@@]..F&a)>>@UVV  < <1 qs$| **511111111L(((1l*;((((<,J&v..' $ 0"/"&"4	          J J J

%&HIIIJ J7 ! 	5 	5 	5DKDL$&& 5+D!4444444445 5 5 5 5 5 	 	 	 JJLLL	s$   B1E
 $2D .E

F41F#F4messagec           	       K   | j         }|t                      t          || j        ||| j        | j        d| j        | j                   d {V }d |D             }t          |          }t          |          }t          j        dt          |          |z             |z   }|g|}t          |          g|}||d         z  }|dk     rd                    |          g}|g}	 t          ||          D ]\  }	}
|	rt          |
          }
t!          dt#          d|	t$          z   t$                              D ]U\  }}|
||         }|j        }|j        t)                      |j                            |           |xj        |z  c_        V|                    d           nf# t(          $ r;}d | _         d	| _        t3          j                    st7          | |           Y d }~n&d }~wt8          $ r |                                   w xY w|S )
N)sender	recipient)r   serializerson_errorcontextframe_split_sizec                ,    g | ]}t          |          S r   )r$   ).0fs     rR   
<listcomp>zTCP.write.<locals>.<listcomp>  s    333q333rb   r   r   i   rb   r(   T)rk   r   r   r   
local_inforemote_infohandshake_optionsrj   sumr   r   packr$   joinzipr!   r   r   r   _write_bufferr   append_total_write_indexwritere   r:   r   ra   r   r   )r   r   r   r   rk   r   r   frames_nbytes_totalheadereach_frame_nbytes
each_framer   r   r   r   r   s                   rR   r   z	TCP.write
  s     >!### ,#/!-  (
 "0
 
 
 
 
 
 
 
 
 43F333!-00$V,,S&..3F"FGG&P"6"8-8}Q//&&hhv&&'F01M(	14]F1K1K B B-!:$ B "3:!>!>J .-0EE1 ! ! B B1 !+1Q3',|!/7"3"5"55,33E:::11\A111 LL  	5 	5 	5DKDL$&& 5+D!444 		 		 		 JJLLL		 #"s   'B>F& &
H	01G&&#H	c              #    K   | j         d c}| _         d| _        ||                                s	 |                                r|                    d          V  |j                            t
          j                   n# t          $ r Y nw xY w| j	        
                                 |                                 d S # | j	        
                                 |                                 w xY wd S d S )NTrb   )rk   re   r3   writingr   r8   shutdown	SHUT_RDWRrI   ry   detachr   r   rk   s     rR   r   z	TCP.closeV  s      
 #k4fmmoo	>>## , ,,s+++++&&v'78888    &&((( &&((( s*   AB  ?B?  
B
B? BB? ?/C.Nonec                    | j         d c}| _         d| _        |C|                                s1| j                                         |                                 d S d S d S )NT)rk   re   r3   ry   r   r   r   s     rR   r   z	TCP.aborti  s_    "k4fmmooO""$$$LLNNNNN rb   c                    | j         S r   rd   r   s    rR   r3   z
TCP.closedp  s
    |rb   c                    | j         S r   )r{   r   s    rR   
extra_infozTCP.extra_infos  s
    {rb   T)rk   r   rl   rm   rn   rm   ro   rp   )r   rm   r   )Nr   )r   r   )r   rp   )r^   
__module____qualname____doc__r4   utilsparse_bytesr5   r6   rj   __annotations__rs   r   rx   propertyr   r   r   r   r	   	coroutiner   r   r3   r   __classcell__)r]   s   @rR   ri   ri      s          %)J$:$:011% %N      !      0  
 
 
       X     X0 0 0 0dJ# J# J# J#X 	]  ]$         X    rb   ri   c                  :    e Zd ZdZ eeej                  Zd ZdS )TLSz(
    A TLS-specific version of TCP.
    c                B   t                               |            | j        j        }|v| j                            |                                |                                           | j        d         \  }}}t          	                    d| j
        |||           d S d S )N)peercertcipherr   z7TLS connection with %r: protocol=%s, cipher=%s, bits=%d)ri   r   rk   r8   r{   updategetpeercertr   r=   r>   ru   )r   rM   r   protobitss        rR   r   zTLS._read_extra  s    {!K(8(8(:(:4;;==QQQ"&+h"7FE4LLI     rb   N)	r^   r   r   r   minr   ri   rj   r   r   rb   rR   r   r   x  sD          S.0BCCN    rb   r   c                    |                      d          }t          |t          j                  st	          d|          |S )Nssl_contextzpTLS expects a `ssl_context` argument of type ssl.SSLContext (perhaps check your TLS configuration?) Instead got )r6   rZ   r[   
SSLContext	TypeError)connection_argsctxs     rR   _expect_tls_contextr     sT    


m
,
,Cc3>** 
$$ $
 
 	

 Jrb   c                      e Zd Zd ZdS )RequireEncryptionMixinc                v    | j         s/|                    d          rt          d| j        |z             d S d S )Nrequire_encryptionzJencryption required by Dask configuration, refusing communication from/to )	encryptedr6   RuntimeErrorprefix)r   addressr   s      rR   _check_encryptionz(RequireEncryptionMixin._check_encryption  s]    ~ 	/"5"56J"K"K 	,7;{W7L7LO  	 	 	 	rb   N)r^   r   r   r   r   rb   rR   r   r     s#            rb   r   )typec                 K   	 t          j        | |||t                    S # t           j        $ r }|j        t           j        k    r Y d }~nd }~ww xY wt          j                                        | ||t           j                   d {V S )N)familyr   flagsr   r   )	r8   getaddrinfo_NUMERIC_ONLYgaierrorerrno
EAI_NONAMEasyncioget_running_loopSOCK_STREAM)hostportr   r   r   s        rR   _getaddrinfor    s      
!
 
 
 	
 ?   7f''' (''''
 )++77d6(: 8         s   " AAAc                  (    e Zd ZdZej        fdd
ZdS )_DefaultLoopResolvera  
    Resolver implementation using `asyncio.loop.getaddrinfo`.
    backport from Tornado 6.2+
    https://github.com/tornadoweb/tornado/blob/3de78b7a15ba7134917a18b0755ea24d7f8fde94/tornado/netutil.py#L416-L432

    With an additional optimization based on
    https://github.com/python-trio/trio/blob/4edfd41bd5519a2e626e87f6c6ca9fb32b90a6f4/trio/_socket.py#L125-L192
    (Copyright Contributors to the Trio project.)

    And proposed to cpython in https://github.com/python/cpython/pull/31497/
    r  rm   r  r7   r   socket.AddressFamilyr   list[tuple[int, Any]]c                `   K   d t          |||t          j                   d {V D             S )Nc                "    g | ]\  }}}}}||fS r   r   )r   fam_r   s       rR   r   z0_DefaultLoopResolver.resolve.<locals>.<listcomp>  s6     
 
 
%Q1g 'N
 
 
rb   r   )r  r8   r  )r   r  r  r   s       rR   resolvez_DefaultLoopResolver.resolve  s`      
 
/;d60B0 0 0 * * * * * *
 
 
 	
rb   N)r  rm   r  r7   r   r  r   r	  )r^   r   r   r   r8   	AF_UNSPECr  r   rb   rR   r  r    sA        
 
 DJCS
 
 
 
 
 
 
rb   r  c                  J    e Zd ZU  e e                      Zded<   ddZdS )BaseTCPConnector)resolverzClassVar[TCPClient]clientTc                  K   |                      ||           t          |          \  }} | j        di |}	 d|v r<| j                            ||t
                     d {V } |j        di | d {V }n! | j        j        ||fdt
          i| d {V }|                                r|j        rt          |j                  n`# t          $ r}t          | |           Y d }~nAd }~wt          $ r}	t          d          |	d }	~	wt          $ r}	t                      |	d }	~	ww xY w| j        t          |          z   }
|                     ||
| j        |z   |          }|S )Nserver_hostname)max_buffer_sizeFr  zzTLS certificate does not match. Check your security settings. More info at https://distributed.dask.org/en/latest/tls.htmlr   )F)r   r   _get_connect_argsr  connectMAX_BUFFER_SIZE	start_tlsr3   errorr   ra   r   r   r   r   rV   
comm_class)r   r   ro   r   ipr  kwargsrk   r   errr   rK   s               rR   r  zBaseTCPConnector.connect  s     w888"7++D''::/::	2 F**#{22o  3            0v/@@@@@@@@@@2t{2   .= AG          }} 66< 6'555  	1 	1 	1'a00000000' 	 	 	&O    	2 	2 	2&((c1	2 &8&@&@@M4;#8+
 
 s0   BC
 

D'C))D'6DD'D""D'Nr   )r^   r   r   r   r  r  r   r  r   rb   rR   r  r    sR         "+)5I5I5K5K"L"L"LFLLLL( ( ( ( ( (rb   r  c                       e Zd ZdZeZdZd ZdS )TCPConnectortcp://Fc                    i S r   r   r   r   s     rR   r  zTCPConnector._get_connect_args      	rb   N)r^   r   r   r   ri   r  r   r  r   rb   rR   r!  r!  	  s2        FJI    rb   r!  c                       e Zd ZdZeZdZd ZdS )TLSConnectortls://Tc                h    dt          |          i}|                    d          r|d         |d<   |S )Nssl_optionsr  )r   r6   )r   r   tls_argss      rR   r  zTLSConnector._get_connect_args  sC    !#6#G#GH011 	M*9:K*LH&'rb   N)r^   r   r   r   r   r  r   r  r   rb   rR   r'  r'    s2        FJI    rb   r'  c                  h    e Zd Z	 	 	 	 ddZd Zd Zd Zd Zd	 Ze	d
             Z
e	d             ZdS )BaseTCPListenerTNr   c                    |                      ||           t          ||          \  | _        | _        || _        || _        || _        || _         | j        di || _	        d | _
        d | _        d S )Nr   )r   r   r  r  default_hostcomm_handlerro   r   _get_server_argsserver_args
tcp_serverbound_address)r   r   r0  ro   r   r/  default_portr   s           rR   rs   zBaseTCPListener.__init__  s     	w888,WlCC((&*040CC?CC!rb   c                  K   t          ddt          i| j        | _        | j        | j        _        t          t          j        	                    d                    }t          d          D ]y}	 t          j        | j        | j        |          }| j                            |            n<# t           $ r-}| j        dk    s|j        t"          j        k    r |}Y d }~rd }~ww xY w||                                  d S )Nr  zdistributed.comm.socket-backlog   )r   backlogr   r   )r   r  r2  r3  _handle_streamhandle_streamr7   r4   r5   r6   r   r
   bind_socketsr  r  add_socketsrI   r   
EADDRINUSEget_host_port)r   r8  r  socketsr   r`   s         rR   startzBaseTCPListener.start3  s     #XXOXtGWXX(,(;%dkoo&GHHIIq 	 	A
 ".Itw   ++G444     9>>QW0@%@%@ Is   /!B,,
C#6#CC#c                T    | j         d c}| _         ||                                 d S d S r   )r3  stop)r   r3  s     rR   rB  zBaseTCPListener.stopM  s6    &*ot#
DO!OO "!rb   c                2    | j         t          d          d S )Nz,invalid operation on non-started TCPListener)r3  
ValueErrorr   s    rR   _check_startedzBaseTCPListener._check_startedR  s!    ?"KLLL #"rb   c                  K   | j         t          |d d          z   }|                     ||           d {V }|d S t                              d|| j                   | j         t          |          z   }|                     |||| j                  }| j	        |_	        	 | 
                    |           d {V  n,# t          $ r t                              d|           Y d S w xY w|                     |           d {V  d S )Nr(   z!Incoming connection from %r to %rz4Connection from %s closed before handshake completed)r   r   _prepare_streamr=   r>   contact_addressrV   r  ro   r   on_connectionr   infor0  )r   rk   r   r   rK   s        rR   r9  zBaseTCPListener._handle_streamV  s9     + 172A2; ??++FG<<<<<<<<>F8'4CWXXX&8&@&@@v}gt?OPP!/	$$T********** 	 	 	KKNPWXXXFF	 %%%%%%%%%%%s   B: :%C#"C#c                    |                                   | j        t          | j                  | _        | j        dd         S )z@
        The listening address as a (host, port) tuple.
        Nr(   )rE  r4  r   r3  r   s    rR   r>  zBaseTCPListener.get_host_porti  sC     	%!7!H!HD!"1"%%rb   c                H    | j         t          |                                  z   S )z4
        The listening address as a string.
        )r   r   r>  r   s    rR   listen_addresszBaseTCPListener.listen_addresst  s#    
 {.0B0B0D0DEEErb   c                    |                                  \  }}t          || j                  }| j        t	          ||          z   S )z2
        The contact address as a string.
        )r/  )r>  r   r/  r   r   )r   r  r  s      rR   rH  zBaseTCPListener.contact_address{  sF    
 ''))
d#Dt7HIII{.tT::::rb   )TTNr   )r^   r   r   rs   r@  rB  rE  r9  r>  r   rM  rH  r   rb   rR   r-  r-    s        
 " " " "(  4  
M M M& & &&	& 	& 	& F F XF ; ; X; ; ;rb   r-  c                  &    e Zd ZdZeZdZd Zd ZdS )TCPListenerr"  Fc                    i S r   r   r$  s     rR   r1  zTCPListener._get_server_args  r%  rb   c                
   K   |S r   r   )r   rk   r   s      rR   rG  zTCPListener._prepare_stream  s      rb   N)	r^   r   r   r   ri   r  r   r1  rG  r   rb   rR   rP  rP    sA        FJI      rb   rP  c                  &    e Zd ZdZeZdZd Zd ZdS )TLSListenerr(  Tc                (    t          |          }d|iS )Nr*  )r   )r   r   r   s      rR   r1  zTLSListener._get_server_args  s    !/22s##rb   c                   K   	 |                                  d {V  |S # t          $ r>}t                              d| j        |t          |dd           p|           Y d }~d S d }~ww xY w)Nz7Listener on %r: TLS handshake failed with remote %r: %srY   )wait_for_handshakerI   r=   r   rM  getattr)r   rk   r   r   s       rR   rG  zTLSListener._prepare_stream  s      	++--------- M  	 	 	NNI#<..3!	        	s     
A(3A##A(N)	r^   r   r   r   r   r  r   r1  rG  r   rb   rR   rT  rT    sA        FJI$ $ $    rb   rT  c                  2    e Zd Zd Zd Zd Zd Zd Zd ZdS )BaseTCPBackendc                *    |                                  S r   )_connector_classr   s    rR   get_connectorzBaseTCPBackend.get_connector  s    $$&&&rb   c                "     | j         |||fi |S r   )_listener_class)r   lochandle_commro   r   s        rR   get_listenerzBaseTCPBackend.get_listener  s!    #t#CkUU_UUUrb   c                ,    t          |          d         S )Nr   r   r   r`  s     rR   get_address_hostzBaseTCPBackend.get_address_host  s    s##A&&rb   c                     t          |          S r   rd  re  s     rR   get_address_host_portz$BaseTCPBackend.get_address_host_port  s    s###rb   c                `    t          |          \  }}t          t          |          |          S r   )r   r   r    )r   r`  r  r  s       rR   resolve_addresszBaseTCPBackend.resolve_address  s)    $S))
d 4$777rb   c                    t          |          \  }}t          |          }d|v rt          |          }nt          |          }t	          |d           S )N:)r   r    r#   r"   r   )r   r`  r  r  
local_hosts        rR   get_local_address_forz$BaseTCPBackend.get_local_address_for  sO    $S))
d$;;!$JJJ T222rb   N)	r^   r   r   r]  rb  rf  rh  rj  rn  r   rb   rR   rZ  rZ    sq        ' ' 'V V V
' ' '$ $ $8 8 83 3 3 3 3rb   rZ  c                      e Zd ZeZeZdS )
TCPBackendN)r^   r   r   r!  r\  rP  r_  r   rb   rR   rp  rp            #!OOOrb   rp  c                      e Zd ZeZeZdS )
TLSBackendN)r^   r   r   r'  r\  rT  r_  r   rb   rR   rs  rs    rq  rb   rs  )]
__future__r   r   ctypesr   r}   loggingr8   r[   r   r:   rv   r   r   typingr   r   tlzr   tornador	   r
   tornado.iostreamr   r   tornado.tcpclientr   tornado.tcpserverr   r4   
dask.utilsr   distributed.comm.addressingr   r   distributed.comm.corer   r   r   r   r   distributed.comm.registryr   distributed.comm.utilsr   r   r   r   r   distributed.protocol.utilsr   r   distributed.systemr   distributed.utilsr    r!   r"   r#   r$   	getLoggerr^   r=   version_infosizeofc_intr   c_size_tr  rS   rV   ra   rg   ri   r   r   r   AI_NUMERICHOSTAI_NUMERICSERVr   r  r  Resolverr  r  r!  r'  r-  rP  rT  rZ  rp  rs  r   rb   rR   <module>r     sn   " " " " " "          



  



  2 2 2 2 2 2 2 2                                       8 8 8 8 8 8 8 8 ' ' ' ' ' ' ' ' ' ' ' '  & & & & & & J J J J J J J J              . - - - - -              J I I I I I I I + + + + + + T T T T T T T T T T T T T T		8	$	$ g=6=#>#>>!CaG=6=#A#AAAE"8A 8A 8Av  ; ; ;	 	 	V V V V V$ V V Vr    #   ,          %(== 4:3E     0
 
 
 
 
7+ 
 
 
:+ + + + +y"8 + + +\    #   	 	 	 	 	# 	 	 	d; d; d; d; d;h 6 d; d; d;N	 	 	 	 	/ 	 	 	    /   03 3 3 3 3W 3 3 3>" " " " " " " "
" " " " " " " " " "rb   