
    hgA`                        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 d dlmZmZ d dlmZ d dlmZ ej        Z eedd          Z G d	 d
          Z G d de          Z G d de          Zd Zd Z G d d          Z G d d          Z G d de          Zd Z G d de          Z  G d d          Z! G d d          Z"dS )    N)Optional)SSL)certs
exceptions)
basethread)tlsIPPROTO_IPV6)   c                   H    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZdS )	_FileLikei   c                 0    || _         d | _        d | _        d S N)o_logfirst_byte_timestampselfr   s     b/var/www/fb-scrape/myenv/lib/python3.11/site-packages/seleniumwire/thirdparty/mitmproxy/net/tcp.py__init__z_FileLike.__init__   s    	$(!!!    c                     || _         d S r   )r   r   s     r   set_descriptorz_FileLike.set_descriptor    s    r   c                 ,    t          | j        |          S r   )getattrr   )r   attrs     r   __getattr__z_FileLike.__getattr__#   s    tvt$$$r   c                     g | _         dS )zg
            Starts or resets the log.

            This will store all bytes read or written.
        Nr   r   s    r   	start_logz_FileLike.start_log&   s     			r   c                     d| _         dS )z$
            Stops the log.
        Nr   r   s    r   stop_logz_FileLike.stop_log.   s     			r   c                     | j         d uS r   r   r   s    r   
is_loggingz_FileLike.is_logging4   s    y$$r   c                 |    |                                  st          d          d                    | j                  S )z2
            Returns the log as a string.
        zNot logging!r   )r$   
ValueErrorjoinr   r   s    r   get_logz_FileLike.get_log7   s8        	-^,,,xx	"""r   c                 f    |                                  r| j                            |           d S d S r   )r$   r   appendr   vs     r   add_logz_FileLike.add_log?   s:    ?? 	 IQ	  	 r   c                     d | _         d S r   )r   r   s    r   reset_timestampsz_FileLike.reset_timestampsC   s    $(!!!r   N)__name__
__module____qualname__	BLOCKSIZEr   r   r   r    r"   r$   r(   r-   r/    r   r   r   r      s        I) ) )
  % % %    % % %# # #     ) ) ) ) )r   r   c                       e Zd Zd Zd ZdS )Writerc                     t          | j        d          r[	 | j                                         dS # t          j        t
          f$ r&}t          j        t          |                    d}~ww xY wdS )8
            May raise exceptions.TcpDisconnect
        flushN)	hasattrr   r9   socketerrorIOErrorr   TcpDisconnectstrr+   s     r   r9   zWriter.flushI   sw     467## 	77L'* 7 7 7 .s1vv6667	7 	7s   2 A.!A))A.c                    |r| j         pt          j                    | _         	 t          | j        d          r/|                     |           | j                            |          S | j                            |          }|                     |d|                    |S # t          j        t          j
        f$ r&}t          j        t          |                    d}~ww xY wdS )r8   sendallN)r   timer:   r   r-   rA   writer   Errorr;   r<   r   r>   r?   )r   r,   res       r   rC   zWriter.writeS   s      	7(,(A(PTY[[D%	7469-- LLOOO6>>!,,,QALL2A2'''HIv|, 7 7 7 .s1vv6667	7 	7s   AB  '8B   C!;!CC!N)r0   r1   r2   r9   rC   r4   r   r   r6   r6   G   s2        7 7 77 7 7 7 7r   r6   c                   (    e Zd Zd ZddZd Zd ZdS )Readerc                 .   d}t          j                     }|dk    s|dk    r|dk    s|| j        k    r| j        }n|}	 | j                            |          }nX# t          j        $ r Y nt          j        t          j        f$ r_ | j                                        pd}t          j                     |z
  |k     rt          j	        d           Y t          j                    t          j        $ r t          j                    t          j        $ r&}t          j        t!          |                    d}~wt          j        $ r6}|j        dk    rY d}~nt          j        t!          |                    d}~wt          j        $ r&}t          j        t!          |                    d}~ww xY w| j        pt          j                     | _        |sn+||z  }|dk    r|t-          |          z  }|dk    |dk    |                     |           |S )zG
            If length is -1, we read until connection closes.
        r   r   i,  皙?N)rJ   zUnexpected EOF)rB   r3   r   readr   ZeroReturnErrorWantWriteErrorWantReadError
gettimeoutsleepr   
TcpTimeoutr;   timeoutr<   r>   r?   SysCallErrorargsTlsExceptionrD   r   lenr-   )r   lengthresultstartrlendatarS   rF   s           r   rL   zReader.readg   s.    	llfqjj||v66~6v{{4((&   &(9: 2 2 2 &++--4IKK%'722JsOOOH$/111> . . . +---< 7 7 7 .s1vv666# 6 6 66333EEEE -c!ff5559 6 6 6 -c!ff5556(,(A(PTY[[D% dNF||#d))#M llfqjjN 	VsC   A F0-A#F0AF0!D55F0E8!E88F0
!F++F0Nc                 v    d}d}	 |||k    rn*|                      d          }|dz  }|sn||z  }|dk    rn3|S )Nr   r   T      
)rL   )r   sizerY   
bytes_readchs        r   readlinezReader.readline   sh    

	J$$6$61B!OJ ";;
	 r   c                     |                      |          }|dk    rOt          |          |k    r<|st          j                    t          j        d|dt          |                    |S )zu
            Like .read, but is guaranteed to either return length bytes, or
            raise an exception.
        rJ   z	Expected z bytes, got )rL   rW   r   r>   TcpReadIncomplete)r   rX   rY   s      r   	safe_readzReader.safe_read   sx    
 6""R<<CKK611  .000 2239663v;;;G   r   c                    t          | j        t                    rc	 | j        j                            |t
          j                  S # t
          j        $ r&}t          j	        t          |                    d}~ww xY wt          | j        t          j                  r^	 | j                            |t
          j                  S # t          j        $ r&}t          j        t          |                    d}~ww xY wt!          d          )a  
        Tries to peek into the underlying file object.

        Returns:
            Up to the next N bytes if peeking is successful.

        Raises:
            exceptions.TcpException if there was an error with the socket
            TlsException if there was an error with pyOpenSSL.
            NotImplementedError if the underlying file object is not a [pyOpenSSL] socket
        Nz&Can only peek into (pyOpenSSL) sockets)
isinstancer   socket_fileobject_sockrecvr;   MSG_PEEKr<   r   TcpExceptionreprr   
ConnectionrD   rV   r?   NotImplementedError)r   rX   rF   s      r   peekzReader.peek   s     df/00 	P7v|((AAA< 7 7 7 -d1gg6667// 	P6v{{66?;;;9 6 6 6 -c!ff5556 &&NOOOs/   )A A;!A66A;$C C8!C33C8r   )r0   r1   r2   rL   rc   rf   rq   r4   r   r   rH   rH   e   s[        . . .`      P P P P Pr   rH   c                 T    d | D             pt          j         | dd|          d         S )a  
    This is a wrapper around select.select() which also works for SSL.Connections
    by taking ssl_connection.pending() into account.

    Caveats:
        If .pending() > 0 for any of the connections in rlist, we avoid the select syscall
        and **will not include any other connections which may or may not be ready**.

    Args:
        rlist: wait until ready for reading

    Returns:
        subset of rlist which is ready for reading.
    c                 v    g | ]6}t          |t          j                  r|                                d k    4|7S )r   )rh   r   ro   pending).0conns     r   
<listcomp>z#ssl_read_select.<locals>.<listcomp>   sI       dCN++040B0B 	0B0B0Br   r4   r   )select)rlistrS   s     r   ssl_read_selectrz      sB        2 
ub"g	.	.q	12r   c                    	 |                      t          j                   t          j        dk    rR|                     |                                 pd           t          d          D ]}|                     d          s n|                      t          j	                   n# t          j
        $ r Y nw xY w|                                  dS )z@
    Does a hard close of a socket, without emitting a RST.
    nt   i   i   N)shutdownr;   SHUT_WRosname
settimeoutrP   rangerk   SHUT_RDr<   close)sock_s     r   close_socketr      s    $ 	fn%%% 7d?? OODOO--3444 ,--  yy E 	fn%%%%<    	JJLLLLLs   B B# #B54B5c                   .    e Zd ZdZdZd Zd Zd Zd ZdS )_ConnectionrJ   c                     t          t          j        | j        d                    | _        t          t          j        | j        d                    | _        dS )zF
        Set up .rfile and .wfile attributes from .connection
        rbwbN)rH   r;   SocketIO
connectionrfiler6   wfiler   s    r   	_makefilez_Connection._makefile  sB     FODOTBBCC
FODOTBBCC


r   c                     |r5|| _         |                                | _        |                                  nd | _         d | _        d | _        d | _        d| _        d| _        d S NF)r   getpeername
ip_addressr   r   r   tls_establishedfinished)r   r   s     r   r   z_Connection.__init__#  sf     	(DO(4466DONN"DO"DODJDJ$r   c                     | j         sd S | j                                        }| j                                        }| j                                        }|||fS r   )r   r   get_cipher_nameget_cipher_bitsget_cipher_version)r   r   bitsversions       r   get_current_cipherz_Connection.get_current_cipher1  sX    # 	4..00..00/4466T7""r   c                    d| _         t          | j        t          j                  szt          | j        dd          sI	 | j                                         | j                                         n# t          j
        $ r Y nw xY w| j                                         d S 	 | j                                         d S # t          j        $ r Y d S w xY w)NTclosedF)r   rh   r   r   ro   r   r   r9   r   r   r>   r   r~   rD   r   s    r   finishz_Connection.finish:  s    
 $/3>:: 	4:x77 J$$&&&J$$&&&&!/   D J((*****9   s#   2A1 1BB"B= =CCN)	r0   r1   r2   rbufsizewbufsizer   r   r   r   r4   r   r   r   r     s]        HH
D 
D 
D  # # #    r   r   c                   &    e Zd Zd Zd Zd Zd ZdS )ConnectionCloserc                 "    || _         d| _        d S r   )rv   	_canceled)r   rv   s     r   r   zConnectionCloser.__init__Q  s    	r   c                 8    d| _         t          | j                  S )zH
            Cancel the current closer, and return a fresh one.
        T)r   r   rv   r   s    r   popzConnectionCloser.popU  s     	***r   c                     | S r   r4   r   s    r   	__enter__zConnectionCloser.__enter__\  s    r   c                 J    | j         s| j                                         d S d S r   )r   rv   r   r   rU   s     r   __exit__zConnectionCloser.__exit___  s.    ~ 	IOO	 	r   N)r0   r1   r2   r   r   r   r   r4   r   r   r   r   P  sP          + + +      r   r   c                        e Zd Zd fd	Zedeej                 fd            Zd Z	ddZ
d Zd Zdd	Zd
 Zd Zd Zd Z xZS )	TCPClientNc                     t                                          d            || _        || _        d | _        g | _        d | _        || _        d S r   )superr   addresssource_addresscertserver_certssnispoof_source_address)r   r   r   r   	__class__s       r   r   zTCPClient.__init__f  sN    ,	$8!!!r   returnc                 .    t          | j        dd           S )N
cert_error)r   r   r   s    r   ssl_verification_errorz TCPClient.ssl_verification_erroro  s    td;;;r   c                     | j         rPt          | j         t          j                  rt	          | j         j                   d S t	          | j                    d S d S r   )r   rh   r   ro   r   _socketr   s    r   r   zTCPClient.closes  s]     ? 	.$/3>:: .T_455555T_-----		. 	.r   c                    t          j        d||d|}| j        }t          j        || j                  | _        |r4|| _        | j                            |                    d                     | j                                         t          || j                   t          j        | j                                                  | _        | j                                        D ].}| j                            t          j        |                     /d| _        | j                            | j                   | j                            | j                   d S )N)alpn_protosr   idnaTr4   )r   create_client_contextr   r   ro   r   set_tlsext_host_nameencodeset_connect_statedo_ssl_handshaker   Certget_peer_certificater   get_peer_cert_chainr   r*   r   r   r   r   )r   r   r   sslctx_kwargscontextr   is          r   convert_to_tlszTCPClient.convert_to_tls}  sB   + 
#
 
 
 

 .$/BB 	EDHO00F1C1CDDD))+++t///JtCCEEFF	 4466 	4 	4A$$UZ]]3333#
!!$/222
!!$/22222r   c                 .    t          j         |||          S r   )r;   )r   familytypeprotos       r   
makesocketzTCPClient.makesocket  s    }VT5111r   c                 $    t          j        |i |S r   )r;   getaddrinfo)r   rU   kwargss      r   r   zTCPClient.getaddrinfo  s    !426222r   c                 P   d }|                      | j        d         | j        d         dt          j                  D ]S}|\  }}}}}d }		 |                     |||          }	|r|	                    |           | j        r|	                    | j                   | j        r	 |		                    t          j
        t          j                  s+|	                    t          j
        t          j        d           nL# t          $ r?}
|	|	                                 t          j        dt#          |
          z             d }
~
ww xY w|	                    |           |	c S # t          j        $ r#}|}|	|	                                 Y d }~Md }~ww xY w||t          j        d          )Nr   r^   z$Failed to spoof the source address: z!getaddrinfo returns an empty list)r   r   r;   SOCK_STREAMr   r   r   bindr   
getsockoptSOL_IPIP_TRANSPARENT
setsockopt	Exceptionr   r   rm   r?   connectr<   )r   rS   errresafsocktyper   	canonnamesar   rF   r   s               r   create_connectionzTCPClient.create_connection  s    ##DLOT\!_aI[\\ 	! 	!C14.B%BD!r8U;; -OOG,,,& 3IId1222, 
	#v}f>STT U OOFM6;PRSTTT$   + JJLLL(5BSVVK  	 R   < ! ! !#JJLLL!
 ?I,BCCCs>   	AE AC65E6
D? :D::D??EF*FFc                 l   	 |                                  }nC# t          j        t          f$ r*}t	          j        d| j        d         d|          d }~ww xY w|| _        |                                | _	        |
                                | _        |                                  t          |           S )NzError connecting to "r   z": )r   r;   r<   r=   r   rm   r   r   getsocknamer   r   r   r   r   )r   r   r   s      r   r   zTCPClient.connect  s    	//11JJg& 	 	 	))a##'  	
 %(4466$0022%%%s    A%AAc                 :    | j                             |           d S r   r   r   r   ns     r   r   zTCPClient.settimeout      ""1%%%%%r   c                 4    | j                                         S r   )r   rP   r   s    r   rP   zTCPClient.gettimeout  s    ))+++r   c                 F    | j         r| j                                        S dS Nr   r   r   get_alpn_proto_negotiatedr   s    r   r   z#TCPClient.get_alpn_proto_negotiated  &     	?<<>>>3r   )NNr   )r0   r1   r2   r   propertyr   r   InvalidCertificateExceptionr   r   r   r   r   r   r   r   rP   r   __classcell__r   s   @r   r   r   d  s       9 9 9 9 9 9 <1W(X < < < X<. . .3 3 3 302 2 23 3 3$D $D $D $DL& & && & &, , ,      r   r   c                 |   	 	 |                                  n# t          j        $ rG t          j        | gg g |                                           \  }}}|st          j        d          Y lt          j        $ r>}t          |dd          }|r|t          j	        dt          |          z            d}~ww xY wdS )a  Peform the SSL handshake.

    If a timeout has been set on the socket externally, it causes OpenSSL
    to raise EWOULDBLOCK which breaks the handshake. This function will
    catch that condition and will retry the operation until it succeeds or
    some other error occurs.

    See https://github.com/pyca/pyopenssl/issues/168 for more information.

    Args:
        sock: The underlying socket.
        ssl_connection: The OpenSSL Connection object.
    TzSelect timed outr   NSSL handshake error: %s)do_handshaker   rO   rx   rP   r   rR   rD   r   rV   rn   )r   ssl_connectionrdr   rF   verification_errors         r   r   r     s    	S''))))  	 	 	}dVRT__5F5FGGHB1 @ +,>???Hy 	S 	S 	S!(t!L!L! S(( -.G$q''.QRRR	S 	s    AB9-B9;9B44B9c                   :     e Zd ZdZ fdZd Zd Zd Zd Z xZ	S )BaseHandlerzU
        The instantiator is expected to call the handle() and finish() methods.
    c                 t    t                                          |           || _        || _        d | _        d S r   )r   r   r   server
clientcert)r   r   r   r  r   s       r   r   zBaseHandler.__init__  s4    $$$r   c                 B   t          j        d||d|}| j        }t          j        || j                  | _        | j                                         	 t          || j                   n;# t          j        $ r)}t          j	        dt          |          z            d}~ww xY wd| _        | j                                        }|rt          j        |          | _        | j                            | j                   | j                            | j                   dS )zq
        Convert connection to SSL.
        For a list of parameters, see tls.create_server_context(...)
        )r   keyr   NTr4   )r   create_server_contextr   r   ro   set_accept_stater   rD   r   rV   rn   r   r   r   r   r  r   r   r   )r   r   r  r   r   r   r,   s          r   r   zBaseHandler.convert_to_tls  s)    +     .$/BB((***	OT4?3333y 	O 	O 	O)*Cd1gg*MNNN	O#3355 	/#j..DO
!!$/222
!!$/22222s   A+ +B#:$BB#c                     t           r   rp   r   s    r   handlezBaseHandler.handle   s    !!r   c                 :    | j                             |           d S r   r   r   s     r   r   zBaseHandler.settimeout#  r   r   c                 F    | j         r| j                                        S dS r   r   r   s    r   r   z%BaseHandler.get_alpn_proto_negotiated&  r   r   )
r0   r1   r2   __doc__r   r   r
  r   r   r   r   s   @r   r   r     s~             3 3 30" " "& & &      r   r   c                   6    e Zd Zd Zed             Zd Zd ZdS )Counterc                 D    d| _         t          j                    | _        d S )Nr   )_count	threadingLock_lockr   s    r   r   zCounter.__init__.  s    ^%%


r   c                 R    | j         5  | j        cd d d            S # 1 swxY w Y   d S r   r  r  r   s    r   countzCounter.count2  ss    Z 	 	;	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s     c                 f    | j         5  | xj        dz  c_        d d d            d S # 1 swxY w Y   d S Nr^   r  r   s    r   r   zCounter.__enter__7  ~    Z 	 	KK1KK	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	   &**c                 f    | j         5  | xj        dz  c_        d d d            d S # 1 swxY w Y   d S r  r  r   s     r   r   zCounter.__exit__;  r  r  N)r0   r1   r2   r   r   r  r   r   r4   r   r   r  r  -  s\        & & &   X      r   r  c                   P    e Zd Zd Zd ZddZd Zej        fdZ	d Z
d Zdd
ZdS )	TCPServerc                 8   || _         t          j                    | _        | j                                         d| _        | j         d         dk    rt          j        d          d | _        	 t          j        t          j        t          j	                  | _        | j        
                    t          j        t          j        d           | j        
                    t          j        t          j        d           | j        
                    t          t          j        d           | j                            | j                    nP# t          j        $ r>}| j        r| j                                         d | _        |j        dk    r|Y d }~nd }~ww xY w| j        s	 t          j        t          j        t          j	                  | _        | j        
                    t          j        t          j        d           | j        
                    t          j        t          j        d           | j                            | j                    nP# t          j        $ r>}| j        r| j                                         d | _        |j        dk    r|Y d }~nd }~ww xY w| j        st          j        t          j        t          j	                  | _        | j        
                    t          j        t          j        d           | j        
                    t          j        t          j        d           | j                            | j                    | j                                        | _         | j                                         t-                      | _        d S )NFr   	localhostzOBinding to 'localhost' is prohibited. Please use '::1' or '127.0.0.1' directly.r^   b   )r   r  Event_TCPServer__is_shut_downset_TCPServer__shutdown_requestr;   r<   AF_INET6r   r   
SOL_SOCKETSO_REUSEADDRSO_KEEPALIVEr	   IPV6_V6ONLYr   r   errnoAF_INETr   listenr  handler_counter)r   r   rF   s      r   r   zTCPServer.__init__B  s   'o//!!!"'<?k)),pqqq	 !-9KLLDKK""6#4f6I1MMMK""6#4f6I1MMMK""<1CQGGGKT\****| 	 	 	{ $!!###DKw"}} }}}}		 { 	$mFNF<NOO&&v'8&:MqQQQ&&v'8&:MqQQQ  ....<   ; (K%%'''"7b==G !====	 { 	+ -9KLLDKK""6#4f6I1MMMK""6#4f6I1MMMKT\***{..00&yys2   -CE F4FFB-I J4JJc                 J   | j         5  	 |                     ||           nE# t          $ r }|j        t          j        k    s Y d }~n d }~w |                     ||           Y nxY wt          |           n# t          |           w xY w	 d d d            d S # 1 swxY w Y   d S r   )r.  handle_client_connectionOSErrorr+  EINVALhandle_errorr   )r   r   client_addressrF   s       r   connection_threadzTCPServer.connection_threadv  s   ! 	) 	))--j.IIII   
 w%,.. /....>!!*n=====Z((((Z(((((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)sH   B!A6
A#AA6A#!A6&B6BBBBrK   c                    | j                                          	 | j        st          j        | j        gg g |          \  }}}| j        |v r| j                                        \  }}t          j        d| j        j	        d|d         d|d         d| j
        d         d| j
        d         d| j        ||f          }d	|_        	 |                                 n?# t          j        $ r- |                     ||           |                                 Y nw xY w| j        d
| _        | j                                          d S # d
| _        | j                                          w xY w)NzTCPConnectionHandler (z: r   :r^   z -> ))targetrU   TF)r#  clearr%  rx   r;   acceptr   
BaseThreadr   r0   r   r5  daemonrZ   r  ThreadErrorr3  r   r$  )r   poll_intervalrE   w_e_r   r4  ts           r   serve_foreverzTCPServer.serve_forever  s   !!###	&- +"M4;-ROO	2r;!##151C1C1E1E.J"-- N333*1---*1--- LOOO LOOO  $5(.9
 
 
A  $AH+				$0 + + +))*nEEE"((*****+% - +, ',D###%%%%% ',D###%%%%s0   B/E	 C  E	  9DE	 DE	 	"E+c                     d| _         | j                                         | j                                         |                                  d S )NT)r%  r#  waitr;   r   handle_shutdownr   s    r   r~   zTCPServer.shutdown  sK    "&  """r   c                     t           rvt          t          j                              }t          d|           t          dt	          |          z  |           t          ||           t          d|           dS dS )zO
            Called when handle_client_connection raises an exception.
        z(----------------------------------------)filez&Error in processing of request from %sN)	tracebackr?   
format_excprintrn   )r   connection_r4  fpexcs        r   r3  zTCPServer.handle_error  s      	&i*,,--C)"%%%%9D<P<PPWY[ [ [ [#B)"%%%%%%	& 	&r   c                     t           )z5
            Called after client connection.
        r	  )r   rv   r4  s      r   r0  z"TCPServer.handle_client_connection  s
     "!r   c                     dS )z3
            Called after server shutdown.
        Nr4   r   s    r   rF  zTCPServer.handle_shutdown  s      r      c                     t          j                     }	 t          j                     |z
  |k    r!t          j        d| j        j        z            | j        j        dk    rd S N)Nr^   z%s service threads still aliver   )rB   r   Timeoutr.  r  )r   rS   rZ   s      r   wait_for_silencezTCPServer.wait_for_silence  sk    		y{{U"g-- (4(./   #)Q..	r   N)rK   )rQ  )r0   r1   r2   r   r5  rC  r~   sysstderrr3  r0  rF  rT  r4   r   r   r  r  @  s        2) 2) 2)h) ) ) & & & &8   <?: & & & &" " "  
	 	 	 	 	 	r   r  )#r+  r   rx   r;   rU  r  rB   rI  typingr   OpenSSLr   !seleniumwire.thirdparty.mitmproxyr   r   +seleniumwire.thirdparty.mitmproxy.coretypesr   %seleniumwire.thirdparty.mitmproxy.netr   r   ri   r   r	   r   r6   rH   rz   r   r   r   r   r   r   r  r  r4   r   r   <module>r\     s    				   



                      ? ? ? ? ? ? ? ? B B B B B B 5 5 5 5 5 5O  wv~r22,) ,) ,) ,) ,) ,) ,) ,)^7 7 7 7 7Y 7 7 7<hP hP hP hP hPY hP hP hPV2 2 2** * *Z; ; ; ; ; ; ; ;|       (v v v v v v v vr  >. . . . .+ . . .b       &J J J J J J J J J Jr   