
    	^c0f                        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m	Z	 ddl
mZmZ ddlmZ ddlmZmZmZmZm
Z
mZ ddlmZmZmZ d	 Zg d
ZdgZ ej        dej                  Zd Zd Z d Z! G d d          Z"d Z#d Z$ G d d          Z%g dZ& G d dej'                  Z(d Z)d Z* G d d          Z+d Z,dS )aR  command server extension for cHg

'S' channel (read/write)
    propagate ui.system() request to client

'attachio' command
    attach client's stdio passed by sendmsg()

'chdir' command
    change current directory

'setenv' command
    replace os.environ completely

'setumask' command (DEPRECATED)
'setumask2' command
    set umask

'validate' command
    reload the config and check if the server is up to date

Config
------

::

  [chgserver]
  # how long (in seconds) should an idle chg server exit
  idletimeout = 3600

  # whether to skip config or env change checks
  skiphash = False
    N   )_)getattrsetattr)hex)commandserverencodingerror
extensionspycompatutil)hashutilprocutil
stringutilc                     t          t          j        t          j        |                                                               S )z return sha1 hexdigest for a list)r   r   sha1r   pprintdigest)itemss    5/usr/lib/python3/dist-packages/mercurial/chgserver.py	_hashlistr   J   s1    x}Z.u5566==??@@@    )s   aliass
   diff-toolss   eols   extdiffs
   extensionss   fastannotates   merge-toolss   schemes)s   commandss   show.aliasprefixs~  \A(?:
                    CHGHG
                    |HG(?:DEMANDIMPORT|EMITWARNINGS|MODULEPOLICY|PROF|RCPATH)?
                    |HG(?:ENCODING|PLAIN).*
                    |LANG(?:UAGE)?
                    |LC_.*
                    |LD_.*
                    |PATH
                    |PYTHON.*
                    |TERM(?:INFO)?
                    |TZ
                    )\Zc                    g }t           D ]*}|                    |                     |                     +t          D ].\  }}|                    |                     ||                     /t          |          }dt          j        v rdhnt                      fdt          j        	                                D             }t          t          |                    }|dd         |dd         z   S )a  return a quick hash for detecting config/env changes

    confighash is the hash of sensitive config items and environment variables.

    for chgserver, it is designed that once confighash changes, the server is
    not qualified to serve its client and should redirect the client to a new
    server. different from mtimehash, confighash change will not mark the
    server outdated and exit since the user can have different configs at the
    same time.
    s   CHGHGs   HGc                 Z    g | ]'\  }}t                               |          r|v#||f(S  )_envrematch).0kvignoreds      r   
<listcomp>z_confighash.<locals>.<listcomp>   sJ       Aq<<??  !// 
A///r   N   )_configsectionsappendconfigitems_configsectionitemsconfigr   r	   environsetr   sorted)uisectionitemssectionitemsectionhashenvitemsenvhashr!   s          @r   _confighashr3   q   s
    L" 5 5BNN7334444, 6 6BIIgt445555L))K8###'%%   $**,,  H
 x(())Grr?WRaR[((r   c                    d t          j         |           D             }	 ddlm} |                    |           n# t          $ r Y nw xY wg }t
          j        r|                    t
          j                   |D ]L}	 |                    t          j        t          j	        |                               =# t          $ r Y Iw xY wt          t          |                    S )zget a list of paths that should be checked to detect change

    The list will include:
    - extensions (will not cover all files for complex extensions)
    - mercurial/__version__.py
    - python binary
    c                     g | ]\  }}|S r   r   )r   nms      r   r"   z"_getmtimepaths.<locals>.<listcomp>   s    777TQq777r   r   )__version__)r    r8   r%   ImportErrorr   sysexecutablefsencodeinspect
getabsfile	TypeErrorr+   r*   )r,   modulesr8   filesr7   s        r   _getmtimepathsrB      s    87Z2266777G!!!!!!{####   E -X+,,,  	LL*7+=a+@+@AABBBB 	 	 	D	#e**s!   < 
A	A	>9B88
CCc                 \    d }t          t          j        ||                     dd         S )aW  return a quick hash for detecting file changes

    mtimehash calls stat on given paths and calculate a hash based on size and
    mtime of each file. mtimehash does not read file content because reading is
    expensive. therefore it's not 100% reliable for detecting content changes.
    it's possible to return different hashes for same file contents.
    it's also possible to return a same hash for different file contents for
    some carefully crafted situation.

    for chgserver, it is designed that once mtimehash changes, the server is
    considered outdated immediately and should no longer provide service.

    mtimehash is not included in confighash because we only know the paths of
    extensions after importing them (there is imp.find_module but that faces
    race conditions). We need to calculate confighash without importing.
    c                     	 t          j        |           }|t          j                 |j        fS # t          $ r Y d S w xY wN)osstatST_MTIMEst_sizeOSError)pathsts     r   trystatz_mtimehash.<locals>.trystat   sJ    	Bt}%rz22 	 	 	DD	s   ,/ 
==N   )r   r   maplist)pathsrM   s     r   
_mtimehashrQ      s7    $   X%gu5566ss;;r   c                   0    e Zd ZdZd Zedd            ZdS )	hashstatezCa structure storing confighash, mtimehash, paths used for mtimehashc                 0    || _         || _        || _        d S rE   )
confighash	mtimehash
mtimepaths)selfrU   rV   rW   s       r   __init__zhashstate.__init__   s    $"$r   Nc                     |t          |           }t          |           }t          |          }|                     dd||           t	          |||          S )Ns	   cmdservers   confighash = %s mtimehash = %s
)rB   r3   rQ   logrS   )r,   rW   rU   rV   s       r   fromuizhashstate.fromui   sc    '++J __
z**	
/		
 	
 	
 Y
;;;r   rE   )__name__
__module____qualname____doc__rY   staticmethodr\   r   r   r   rS   rS      sI        MM% % %
 < < < \< < <r   rS   c                 L     G fdd| j                    |           S )Nc                   8     e Zd Zd fd	Zd Zdfd	Z xZS )_newchgui.<locals>.chguiNc                     t          |                               |           |rt          |d          | _        d S | _        d S )N_csystem)superrY   r   rf   )rX   src	__class__chguicsystems     r   rY   z!_newchgui.<locals>.chgui.__init__   sK    %'',,, ( 'Z A A 'r   c                 r   || j         usZt          j        | j         d          r@| j                                         t          j                                        k    s| j        rt	          j        ||||          S |                                  | 	                    |t	          j
        |          |          S )Ns   fileno)r)   cwdout)foutr   safehasattrfilenor   stdout_finoutredirectedsystemflushrf   shellenviron)rX   cmdr)   rm   rn   s        r   
_runsystemz#_newchgui.<locals>.chgui._runsystem   s     49$$'	9== %9##%%)?)?)A)AAA) B  sG#NNNNJJLLL==h&;G&D&DcJJJr   c                 b    |                      |t          j        |          ddi           dS )N   pager   attachio)typecmdtableT)rf   r   rv   )rX   rw   envattachios      r   	_runpagerz"_newchgui.<locals>.chgui._runpager   sA    MM%c**%x0	     4r   rE   )r]   r^   r_   rY   rx   r   __classcell__)ri   r   rj   rk   s   @r   rj   rd      sx        	( 	( 	( 	( 	( 	( 	( 	(	K 	K 	K 	 	 	 	 	 	 	 	 	 	r   rj   ri   )srcuirk   r   rj   s    ``@r   	_newchguir      sV               B 5<<r   c           	      T   ddl m} | j                                        }dD ]!}t	          ||t          | |                     "t          j        | d          r| j        |_        |	                    ||          }|
                    ||d                    |                                 D ]T\  }}}	|                     ||          }
d|
v s|
dk    s|
                    d          r<|                    |||	|
           U|d	         }|rt          j                            |          pd }|d
         }|                    |||          \  }}t'          j        |           t+          j        ||           ||ur*t'          j        |           t+          j        ||           ||fS )Nr   )dispatch)   fin   fout   ferrs   environs   _csystems   config   :s   --config   $s   cwds
   repository)wd)fp)r9   r   ri   loadr   r   r   rp   rf   _earlyparseopts_parseconfig
walkconfigconfigsource
startswith	setconfigrF   rK   realpath	_getlocalr   
populateuir   setuplogging)r   argscdebugr   newuiaoptionsr.   namevaluesourcerm   rpathrK   newluis                  r   
_loadnewuir     s   O  ""E3 - -q'%++,,,,{++ ( &&ud33G%!3444 !& 0 0 2 2 6 6u##GT226>>V{22f6G6G6M6M2uf5555 &/C

'"'""3''
/4CM"E%%eUs%;;LD&%   u0000Ff%%%"6f55556?r   c                        e Zd ZdZd ZddZdS )channeledsystema  Propagate ui.system() request in the following format:

    payload length (unsigned int),
    type, ' ',
    cmd, ' ',
    cwd, ' ',
    envkey, '=', val, ' ',
    ...
    envkey, '=', val

    if type == 'system', waits for:

    exitcode length (unsigned int),
    exitcode (int)

    if type == 'pager', repetitively waits for a command name ending with '
'
    and executes it defined by cmdtable, or exits the loop if the command name
    is empty.
    c                 0    || _         || _        || _        d S rE   )in_rn   channel)rX   r   rn   r   s       r   rY   zchanneledsystem.__init__<  s    r   N   systemc           	         ||t          j        |pd          g}|                    d |                                D                        d                    |          }| j                            t          j        d| j	        t          |                               | j                            |           | j                                         |dk    r| j                            d          }t          j        d|          \  }|dk    r!t          j        t#          d                    t          j        d	| j                            d                    \  }	|	S |d
k    rb	 | j                                        d d         }|sd S |r||v r ||                      n$t          j        t#          d          |z            at          j        d|z            )N   .c              3   *   K   | ]\  }}d ||fz  V  dS )s   %s=%sNr   )r   r   r    s      r   	<genexpr>z+channeledsystem.__call__.<locals>.<genexpr>C  s/      BB$!QH1v%BBBBBBr          >cIr         >Is   invalid response   >irz   Ts   unexpected command: %ss   invalid S channel type: %s)r   abspathextendr   joinrn   writestructpackr   lenru   r   readunpackr
   Abortr   readlineProgrammingError)
rX   rw   r)   rm   r|   r}   r   datalengthrcs
             r   __call__zchanneledsystem.__call__A  s   c4<t445BB'--//BBBBBBzz$v{64<TCCDDDt9X]]1%%FeV44IV{{k!$7"8"8999M%q)9)9::ERIXJh''))#2#. E Jx!HSMOOOO+a(A&B&BS&HIIIJ ()F)MNNNr   )Nr   N)r]   r^   r_   r`   rY   r   r   r   r   r   r   '  sG         (  
O O O O O Or   r   ))s   cinr   rb)s   coutr   wb)s   cerrr   r   c            	           e Zd Z fdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Z fdZd Zej        j                                        Ze                    ee	eee
ed            ej        ed          rd Zeed<    xZS  xZS )chgcmdserverc	           
      X   t          t          |                               t          |t	          ||d          | j                  ||||           || _        d| _        g | _        || _	        || _
        |4| j                                        | _        t          j        | j        d<   d S d S )N   SFs   validate)rg   r   rY   r   r   r   
clientsock_ioattached_oldiosrS   baseaddresscapabilitiescopyvalidate)
rX   r,   repofinro   sockprereposetupsrS   r   ri   s
            r   rY   zchgcmdserver.__init__f  s     	lD!!**b/#tT::DMJJ	
 	
 	
  "&  $ 1 6 6 8 8D-9-BDk*** ! r   c                     t          t          |                                            | j                                         |                                  d| _        d S NF)rg   r   cleanupr,   ru   
_restoreior   )rX   ri   s    r   r   zchgcmdserver.cleanupy  sN    lD!!))+++ 	 r   c                 x   | j                             t          j        ddd                     | j                             dd          \  }}}}t          |          dk    sJ |d         \  }}}|t          j        k    sJ |t          j        k    sJ t          |          
                    d                                          }| j                            dd|           | j        }	|	                                 |                                  t!          |t"                    D ]\  }
\  }}}|
dk    sJ t%          |	|          }t'          j        |
|                                           t'          j        |
           | j        rd|d	k    r|}n=|                                rt3          j        |          }nt3          j        |          }||urt9          |	||           t9          | ||           d
| _        | j                            t          j        dt          |                               dS )z{Attach to client's stdio passed via unix domain socket; all
        channels except cresult will no longer be used
        r      Ir      r   i	   chgservers   received fds: %r
r   Tr   N)r   sendallr   r   recvmsgr   socket
SOL_SOCKET
SCM_RIGHTS
memoryviewcasttolistr,   r[   ru   _saveiozip_iochannelsr   rF   dup2rq   closer   isattyr   make_line_bufferedunwrap_line_bufferedr   cresultr   )rX   r   ancdata	msg_flagsaddress
cmsg_level	cmsg_type	cmsg_data	clientfdsr,   fdcnfnmoder   newfps                   r   r   zchgcmdserver.attachio  s    	FD! < <===,0O,C,CAs,K,K)gy'7||q    +21:(
IyV.....F----- y))..s33::<<	L"7CCCW



"%i"="= 	% 	%BR6666RBGB		$$$HRLLL 
 W}} 99;; >$7;;EE$9"==EBB&&&D"e$$$$6;uc)nn==>>>>>r   c                    | j         rd S | j        }t          D ]i\  }}}t          | |          }t          ||          }t	          j        |                                          }| j                             |||f           jd S rE   )r   r,   r   r   rF   duprq   r%   )rX   r,   r   r   _modechr   r   s           r   r   zchgcmdserver._saveio  s    < 	FW( 	. 	.MBEr""BRB		$$BLR----		. 	.r   c           	         | j         sd S t          j        t          j        t          j                  }| j        }t          | j         t                    D ]\  \  }}}\  }}}	 d|v r;t          j        ||	                                           |
                                 t          j        ||	                                           t          j        |           nF# t          $ r9}	| j                            ddt          j        |	          |           Y d }	~	nd }	~	ww xY wt!          | ||           t!          |||           t          j        |           | j         d d = d S )Nwr   s   got %s while duplicating %s
)r   rF   opendevnullO_WRONLYr,   r   r   r   rq   ru   r   rJ   r[   r   forcebytestrr   )
rX   nullfdr,   r   r   r   r   r   r   errs
             r   r   zchgcmdserver._restoreio  sl   | 	FR[11W,/k,J,J 	  	 (LRR.2r4$;; GFBIIKK000HHJJJBIIKK(((     4+C00	        D"b!!!BB
LOOOs   "A:C
D '/DD c                 h   |                                  }d}d}	 t          | j        || j                  \  | _        }n# t          j        $ r~}| j                            t          d          t          j        |          z             |j	        r/| j                            t          d          |j	        z             d}Y d}~n[d}~wt          j
        $ rF}|j        |j        }| j                            |                                           d}Y d}~nd}~ww xY w|rW| j                                         d}| j                            dd          r|}| j                            d	|z             dS t"                              || j        j                  }g }|j        | j        j        k    rXt+          | j        | j        j                  }	|                    d
|	z             | j        j        r|                    d           |j        | j        j        k    r2t+          | j        |j                  }	|                    d|	z             | j                            ddt          j        |                     | j                            d                    |          pd           dS )a  Reload the config and check if the server is up to date

        Read a list of ' ' separated arguments.
        Write a non-empty list of ' ' separated instruction strings or ' '
        if the list is empty.
        An instruction string could be either:
            - "unlink $path", the client should unlink the path to stop the
              outdated server.
            - "redirect $path", the client should attempt to connect to $path
              first. If it does not work, start a new server. It implies
              "reconnect".
            - "exit $n", the client should exit directly with code n.
              This may happen if we cannot parse the config.
            - "reconnect", the client should close the connection and
              reconnect.
        If neither "reconnect" nor "redirect" is included in the instruction
        list, the client can continue with this server after completing all
        the instructions.
        F   s
   abort: %s
s   (%s)
TNs   uis   detailed-exit-codes   exit %ds	   unlink %ss	   reconnects   redirect %sr   s   validate: %s
r   )	_readlistr   r,   r   r
   	RepoErrorr   r   r  hintErrordetailed_exit_codeformatru   
configboolr   r   rS   r\   rW   rV   _hashaddressr   rU   r%   r[   r   r   )
rX   r   errorraisedr  luiinst	exit_codenewhashinstsaddrs
             r   r   zchgcmdserver.validate  s   ( ~~ 	%dgtT[AALDGSS 	 	 	 GMM!N++j.Ed.K.KKLLLy 8a	llTY6777KKKKKK{ 	 	 	&2%)%<"GMM$++--(((KKKKKK		  	GMMOOOIw!!%)>?? /.	LzI5666F""3(ABB 888 0$.2KLLDLL,--- ~' +\***!::: 0'2DEEDLL$.///L"3Z5Fu5M5MNNN5::e,,566666s"   #> DA4CD<DDc                     |                                  }|sdS | j                            dd|           t          j        |           dS )zChange current directory

        Note that the behavior of --cwd option is bit different from this.
        It does not affect --config parameter.
        Nr   s   chdir to '%s'
)_readstrr,   r[   rF   chdir)rX   rK   s     r   r  zchgcmdserver.chdir  sH     }} 	FL"4d;;;
r   c                 V    |                      |                     d                     dS )zChange umask (DEPRECATED)r   N)	_setumask_readrX   s    r   setumaskzchgcmdserver.setumask%  s&     	tzz!}}%%%%%r   c                     |                                  }t          |          dk    rt          d          |                     |           dS )zChange umaskr   s(   invalid mask length in setumask2 requestN)r  r   
ValueErrorr  )rX   r   s     r   	setumask2zchgcmdserver.setumask2+  sE    }}t99>>HIIItr   c                     t          j        d|          d         }| j                            dd|           t	          j        |           d S )Nr   r   r   s   setumask %r
)r   r   r,   r[   r   r  )rX   r   masks      r   r  zchgcmdserver._setumask2  sG    }UD))!,L"2D999dr   c                     | j         }g | _         	 t          t          |                                           |                                  || _         S # |                                  || _         w xY wrE   )r   rg   r   
runcommandr   )rX   globaloldiosri   s     r   r&  zchgcmdserver.runcommand7  sp     |	(t,,7799OO'DLL OO'DL''''s   &A A0c                    |                                  }	 t          d |D                       }n# t          $ r t          d          w xY w| j                            ddt          |                                                     t          j        	                                 t          j        
                    |           dS )ztClear and update os.environ

        Note that not all variables can make an effect on the running process.
        c              3   B   K   | ]}|                     d d          V  dS )   =r   N)split)r   ss     r   r   z&chgcmdserver.setenv.<locals>.<genexpr>J  s0      66q!''$**666666r   s"   unexpected value in setenv requestr   s   setenv: %r
N)r	  dictr!  r,   r[   r+   keysr	   r)   clearupdate)rX   lnewenvs      r   setenvzchgcmdserver.setenvC  s    
 NN	D66A66666FF 	D 	D 	DBCCC	DL/6&++--3H3HIII   '''''s	   0 A
)r{   s   chdirs
   runcommands   setenvs   setumasks	   setumask2s   setprocnamec                     |                                  }| j                            dd|           t          j        |           dS )zChange process titler   s   setprocname: %r
N)r  r,   r[   r   setprocname)rX   r   s     r   r5  zchgcmdserver.setprocname`  s?    ==??DGKK&:DAAA &&&&&r   )r]   r^   r_   rY   r   r   r   r   r   r  r  r"  r  r&  r3  r   serverr   r   r0  r   rp   r   r5  r   r   s   @r   r   r   e  s       C C C C C&! ! ! ! !0? 0? 0?d. . .  @:7 :7 :7x
 
 
& & &    

( 
( 
( 
( 
(( ( ( !'499;;L!%!#	
 	
	 	 	 t.11 3	' 	' 	' (3^$$$$$3 3 3 3r   r   c                 2    d| t          j                    fz  S )Ns	   %s.%d.tmp)rF   getpid)r   s    r   _tempaddressr9  i  s    7BIKK000r   c                     t           j                            |           \  }}|                    dd          d         }dt           j                            ||          |fz  S )Nr   r   r   s   %s-%s)rF   rK   r+  r   )r   hashstrdirnamebasenames       r   r  r  m  sT     g..GX~~dA&&q)Hrw||GX66@@@r   c                   X    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 Zd Zd ZdS )chgunixservicehandlerz"Set of operations for chg servicesr   c                     || _         d | _        d | _        d | _        |                    dd          | _        t          j                    | _        d S )Nr   s   idletimeout)r,   
_hashstate_baseaddress_realaddress	configint_idletimeouttime_lastactive)rX   r,   s     r   rY   zchgunixservicehandler.__init__{  sL       LL~FF9;;r   c                     |                      |           |                                  |                     |           |                                  d S rE   )_inithashstate_checkextensions_bind_createsymlink)rX   r   r   s      r   
bindsocketz chgunixservicehandler.bindsocket  sR    G$$$

4r   c                     || _         | j                            dd          rd | _        || _        d S t
                              | j                  | _        t          || j        j                  | _        d S )Nr   s   skiphash)	rB  r,   r  rA  rC  rS   r\   r  rU   rX   r   s     r   rI  z$chgunixservicehandler._inithashstate  sl    #7lK88 	"DO 'DF#**4733($/2LMMr   c                 Z    | j         sd S t          j                    rd| j         _        d S d S )Nr   )rA  r   	notloadedrV   r  s    r   rJ  z&chgunixservicehandler._checkextensions  s>     	F!! 	, ),DO%%%		, 	,r   c                     t          | j                  }t          j        ||           t	          j        |          | _        |                    t          j	                   t          j
        || j                   d S rE   )r9  rC  r   bindunixsocketrF   rG   _socketstatlistenr   	SOMAXCONNrename)rX   r   tempaddresss      r   rK  zchgunixservicehandler._bind  sk     #4#455D+...7;//F$%%% 	K!233333r   c                     | j         | j        k    rd S t          | j                   }t          j        t          j                            | j                  |           t          j        || j                    d S rE   )	rB  rC  r9  rF   symlinkrK   r=  r   rW  )rX   rX  s     r   rL  z$chgunixservicehandler._createsymlink  sh     111F"4#455

27##D$566DDDK!233333r   c                     	 t          j        | j                  }|j        | j        j        k    o*|t          j                 | j        t          j                 k    S # t          $ r Y dS w xY wr   )rF   rG   rC  st_inorT  rH   rJ   )rX   rL   s     r   _issocketownerz$chgunixservicehandler._issocketowner  sq    	*++B	T-44 It}%)9$-)HH  	 	 	55	s   AA 
A)(A)c                 d    |                                  sd S t          j        | j                   d S rE   )r]  r   	tryunlinkrC  rO  s     r   unlinksocketz"chgunixservicehandler.unlinksocket  s6    ""$$ 	F
 	t()))))r   c                     |                                  s#| j                            dd| j                   dS t	          j                    | j        z
  | j        k    r| j                            dd           dS dS )Nr   s   %s is not owned, exiting.
Ts   being idle too long. exiting.
F)r]  r,   r[   rC  rF  rG  rE  r  s    r   
shouldexitz chgunixservicehandler.shouldexit  s}    ""$$ 	GKK<d>O   49;;))D,===GKK&HIII4ur   c                 6    t          j                     | _        d S rE   )rF  rG  r  s    r   newconnectionz#chgunixservicehandler.newconnection  s    9;;r   c           
      L    t          | j        |||||| j        | j                  S rE   )r   r,   rA  rB  )rX   r   connr   ro   r   s         r   createcmdserverz%chgunixservicehandler.createcmdserver  s3    GO	
 	
 		
r   N)r]   r^   r_   r`   pollintervalrY   rM  rI  rJ  rK  rL  r]  r`  rb  rd  rg  r   r   r   r?  r?  v  s        ,,L
' 
' 
'  N N N, , ,	4 	4 	44 4 4  * * *	 	 	' ' '

 

 

 

 

r   r?  c                    dt           j        v rt           j        d= dt           j        v r-t           j        d         t           j        d<   t           j        d= n6dt           j        v r(dt           j        v rt           j        d= t           j        d= |r|                     dddd           t          |           }t	          j        | d ||	          S )
Ns   CHGINTERNALMARKs   CHGORIG_LC_CTYPEs   LC_CTYPEs   CHG_CLEAR_LC_CTYPEs   bundles   mainreporootr   s   repo)r   optshandler)r	   r)   r   r?  r   unixforkingservice)r,   r   rj  hs       r   chgunixservicern    s     X---/0 h...(0(89L(M%011	("2	2	2(*** -23 ?
Yg>>>b!!A+BTaPPPPr   )-r`   r=   rF   rer   rG   r   rF  i18nr   r   r   r   noder   r9   r   r	   r
   r   r   utilsr   r   r   r   r$   r'   compileXr   r3   rB   rQ   rS   r   r   r   r   r6  r   r9  r  r?  rn  r   r   r   <module>ru     s     F  				 				                                               A A A	 	 	 ' 
 
 D
 
") ) )>  4< < <:< < < < < < < <." " "J! ! !H3O 3O 3O 3O 3O 3O 3O 3Ol  A3 A3 A3 A3 A3=' A3 A3 A3H1 1 1A A Ag
 g
 g
 g
 g
 g
 g
 g
TQ Q Q Q Qr   