o
    j                     @   s  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 zd dlmZ W n ey;   eZY nw ejdkZerGeZ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Z$dZ%ej&ej' ej( d Z)dZ*G dd de+Z,G dd de,Z-G dd de,Z.G dd de,Z/G d d! d!e,Z0d"d# Z1G d$d% d%e2Z3G d&d' d'e2Z4G d(d) d)e4Z5G d*d+ d+e2Z6G d,d- d-e2Z7G d.d/ d/e2Z8G d0d1 d1e2Z9G d2d3 d3e9Z:G d4d5 d5e9Z;G d6d7 d7e2Z<G d8d9 d9e2Z=G d:d; d;e9Z>G d<d= d=e:Z?G d>d? d?e:Z@G d@dA dAe:ZAG dBdC dCe:ZBG dDdE dEe:ZCG dFdG dGe2ZDG dHdI dIe:ZEG dJdK dKe:ZFG dLdM dMe:ZGdNdO ZdPdQ ZHG dRdS dSe2ZIdYdUdVZJdZdWdXZKdS )[    N)BytesIO)OrderedDict)bytes)   Fz[1;31mz[1;32mz[1;33mz[1;34mz[1;35mz[1;36mz[1;37mz[1;0mz[1;41m[1;37mz[1;42m[1;37mz[1;43m[1;37mz[1;44m[1;37mz[1;45m[1;37mz[1;46m[1;37mz[1;47m[1;30m ak  
class {name}(Structure):
    def __init__(self, cstruct, structure, source=None):
        self.structure = structure
        self.source = source
        super({name}, self).__init__(cstruct, structure.name, structure.fields)

    def _read(self, stream):
        r = OrderedDict()
        sizes = {{}}
        bitreader = BitBuffer(stream, self.cstruct.endian)

{read_code}

        return Instance(self, r, sizes)

    def add_fields(self, name, type_, offset=None):
        raise NotImplementedError("Can't add fields to a compiled structure")

    def __repr__(self):
        return '<Structure {name} +compiled>'
c                   @      e Zd ZdS )ErrorN__name__
__module____qualname__ r   r   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/msldap/external/bloodhoundpy/lib/cstruct.pyr   [       r   c                   @   r   )ParserErrorNr	   r   r   r   r   r   _   r   r   c                   @   r   )CompilerErrorNr	   r   r   r   r   r   c   r   r   c                   @   r   )ResolveErrorNr	   r   r   r   r   r   g   r   r   c                   @   r   )NullPointerDereferenceNr	   r   r   r   r   r   k   r   r   c                 O   s&   t sd S t| j|i |tjd d S )N)file)DEBUGprintformatsysstderr)lineargskwargsr   r   r   logo   s   r   c                   @   sT   e Zd ZdZdZdddZddd	ZdddZdddZdd Z	dd Z
dd Zd
S )cstructzMain class of cstruct. All types are registered in here.

    Args:
        endian: The endianness to use when parsing.
        pointer: The pointer type to use for Pointers.
       <uint64c                 C   s  || _ i | _i | _i dddddddddd	d
ddddddddd	dddddd	ddddddddi dddt| ddddt| ddddt| dddd	t| d	dd dt| dd!d"dt| dd!d#dt| dd$d%dt| dd$d&d't| d'd!d(d)t| d)d$d*d+t| d,t| d-t| d-d.d/d0t| d0d.d1d2t| d2d3d/d4t| d4d3d1d5t i| _| 	|| _
d S )6Nbyteint8ubyteuint8ucharshortint16ushortuint16longint32ulonguint32ulong64r!   u1u2u4u8worddwordlonglongint64	ulonglongintzunsigned intr   bB   hH   iI   qQfloatfdoubledcharwcharint24r   Tuint24Fint48   uint48void)endianconstslookups
PackedTypeCharType	WcharTypeBytesIntegerVoidTypetypedefsresolvepointer)selfrQ   r[   r   r   r   __init__   s   
 !"#%&'(*-zcstruct.__init__Fc                 C   s4   |  }|s|  | jv rtd| || j|< dS )a"  Add a type or type reference.

        Args:
            name: Name of the type to be added.
            t: The type to be added. Can be a str reference to another type
                or a compatible type class.

        Raises:
            ValueError: If the type already exists.
        zDuplicate type: %sN)lowerrY   
ValueError)r\   nametreplacer   r   r   addtype   s   zcstruct.addtypeNc                 K   s2   |pt j}|t jkrt| fi |}|| dS )a  Parse structures from the given definitions using the given definition type.

        Definitions can be parsed using different parsers. Currently, there's
        only one supported parser - DEF_CSTYLE. Parsers can add types and
        modify this cstruct instance. Arguments can be passed to parsers
        using kwargs.

        Args:
            s: The definition to parse.
            deftype: The definition type to parse the definitions with.
            **kwargs: Keyword arguments for parsers.
        N)r   
DEF_CSTYLECStyleParserparse)r\   sdeftyper   parserr   r   r   load   s   

zcstruct.loadc                 K   sH   t |d}| j| |fi | W d   dS 1 sw   Y  dS )a:  Load structure definitions from a file.

        The given path will be read and parsed using the .load() function.

        Args:
            s: The path to load definitions from.
            deftype: The definition type to parse the definitions with.
            **kwargs: Keyword arguments for parsers.
        rN)openrj   read)r\   rg   rh   r   fhr   r   r   loadfile   s   
"zcstruct.loadfilec                 C   s   |  ||S )zParse data using a given type.

        Args:
            name: Type name to read.
            s: File-like object or byte string to parse.

        Returns:
            The parsed data.
        )rZ   rm   )r\   r`   rg   r   r   r   rm      s   
zcstruct.readc                 C   sf   |}t |ts	|S tdD ]}| | jvrtd| | j|  }t |ts,|  S qtd| )a~  Resolve a type name to get the actual type object.

        Types can be referenced using different names. When we want
        the actual type object, we need to resolve these references.

        Args:
            name: Type name to resolve.

        Returns:
            The resolved type object.

        Raises:
            ResolveError: If the type can't be resolved.
        
   zUnknown type %sz0Recursion limit exceeded while resolving type %s)
isinstancestrxranger^   rY   r   )r\   r`   ra   r@   r   r   r   rZ      s   

zcstruct.resolvec                 C   s<   |  | jv r| j|   S || jv r| j| S td| )NzInvalid Attribute: %s)r^   rY   rR   AttributeErrorr\   attrr   r   r   __getattr__  s
   

zcstruct.__getattr__)r    r!   )FN)r
   r   r   __doc__rd   r]   rc   rj   ro   rm   rZ   rw   r   r   r   r   r   v   s    

4

r   c                   @   s    e Zd ZdZdd Zdd ZdS )Parserz[Base class for definition parsers.

    Args:
        cstruct: An instance of cstruct.
    c                 C   
   || _ d S rx   r   r\   r   r   r   r   r]   !     
zParser.__init__c                 C      t  )zThis function should parse definitions to cstruct types.

        Args:
            data: Data to parse definitions from, usually a string.
        NotImplementedErrorr\   datar   r   r   rf   $  s   zParser.parseN)r
   r   r   ry   r]   rf   r   r   r   r   rz     s    rz   c                       sR   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
  ZS )re   zDefinition parser for C-like structure syntax.

    Args:
        cstruct: An instance of cstruct
        compiled: Whether structs should be compiled or not.
    Tc                    s   || _ tt| | d S rx   )compiledsuperre   r]   )r\   r   r   	__class__r   r   r]   5     zCStyleParser.__init__c                 C   s2   |  | | | | | | || jj d S rx   )
_constants_enums_structs_lookupsr   rR   r   r   r   r   rf   :  s   


zCStyleParser.parsec              
   C   sj   t d|}|D ]*}| }|d dd }zt|}W n ttfy)   Y nw || jj	|d < qd S )Nz5#define\s+(?P<name>[^\s]+)\s+(?P<value>[^\r\n]+)\s*\nvalue//r   r`   )
refinditer	groupdictrsplitastliteral_evalr_   SyntaxErrorr   rR   )r\   r   rk   ra   rH   vr   r   r   r   @  s   zCStyleParser._constantsc                 C   s   t d|}|D ]m}| }d}i }|d dD ];}|d\}}}	|dD ]+}
|
d\}}}| }| }|s=q(|sB|}n	t| j|i }|d }|||< q(q|d	 s]d
|d	< t	| j|d | j
|d	 |}| j|j| qd S )NzOenum\s+(?P<name>[^\s:{]+)\s*(:\s*(?P<type>[^\s]+)\s*)?\{(?P<values>[^}]+)\}\s*;r   values
r   ,=r   typer.   r`   )r   r   r   split	partitionstrip
Expressionr   evaluateEnumrZ   rc   r`   )r\   r   rk   ra   rH   nextvalr   r   sepcommentr   keyvalenumr   r   r   r   M  s:   
zCStyleParser._enumsc           	      C   s$  t | j}td|}|D ]}| }|d r|d }n|d r.|d  dd  }ntd|d dkr[| |d	 d
d  }t	| j||}|d dksU| j
rZ||}n|d dkrf|d }nq|d rt| j|d | |d r|d  dD ]}| }| j|| qqd S )Nz(#(?P<flags>(?:compile))\s+)?((?P<typedef>typedef)\s+)?(?P<type>[^\s]+)\s+(?P<name>[^\s]+)?(?P<fields>\s*\{[^}]+\}(?P<defs>\s+[^;\n]+)?)?\s*;r`   defsr   r   zNo name for structr   structfieldsr   flagscompiletypedef)Compilerr   r   r   r   r   r   r   _parse_fields	Structurer   r   rc   )	r\   r   compilerrk   ra   rH   r`   sttdr   r   r   r   p  s:   



zCStyleParser._structsc           	   	   C   s  t d|}g }|D ]}| }|d drq
| j|d }|d dddd|d< |d d ur\|d dkr=d }nt| j|d }z| }W n	 t	yT   Y nw t
| j||}|d d	rs|d d
d  |d< t| j|}t|d ||d rt|d nd }|| q
|S )NzW(?P<type>[^\s]+)\s+(?P<name>[^\s\[:]+)(\s*:\s*(?P<bits>\d+))?(\[(?P<count>[^;\n]*)\])?;r   r   r`   ( )count*r   bits)r   r   r   
startswithr   rZ   rb   r   r   	ExceptionArrayPointerFieldr9   append)	r\   rg   r   rk   rF   rH   type_r   fieldr   r   r   r     s6   $zCStyleParser._parse_fieldsc                    sR   t d|}|D ]}t|d}t fdd| D  jj|d< qd S )Nz#\$(?P<name>[^\s]+) = ({[^}]+})\w*\nr<   c                    s    g | ]\}} j j| |fqS r   )r   rR   .0kr   r\   r   r   
<listcomp>       z)CStyleParser._lookups.<locals>.<listcomp>r   )	r   r   r   r   groupdictitemsr   rS   )r\   r   rR   rk   ra   rH   r   r   r   r     s   zCStyleParser._lookups)T)r
   r   r   ry   r]   rf   r   r   r   r   r   __classcell__r   r   r   r   re   -  s    #"&re   c                   @   sb   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )InstancezHolds parsed structure data.Nc                 C   s.   t | d| t | d| t | d| d S )N_type_values_sizes)object__setattr__)r\   r   r   sizesr   r   r   r]     s   zInstance.__init__c                 C   s   | j d || S )zWrite this structure to a writable file-like object.

        Args:
            fh: File-like objects that supports writing.

        Returns:
            The amount of bytes written.
        r   )__dict__write)r\   rn   r   r   r   r     s   	zInstance.writec                 C   s   t  }| | | S )zmDump this structure to a byte string.

        Returns:
            The raw bytes of this structure.
        )r   r   getvalue)r\   rg   r   r   r   dumps  s   
zInstance.dumpsc                 C   s*   || j d jvrtd| | j d | S Nr   zInvalid attribute: %rr   r   lookuprt   ru   r   r   r   rw     s   zInstance.__getattr__c                 C   s.   || j d jvrtd| || j d |< d S r   r   )r\   rv   r   r   r   r   r     s   zInstance.__setattr__c                 C      | j d | S Nr   r   )r\   itemr   r   r   __getitem__     zInstance.__getitem__c                 C   s   || j d v S r   r   ru   r   r   r   __contains__  r   zInstance.__contains__c                 C   s.   d| j d jddd | j d  D f S )Nz<%s %s>r   z, c                 S   s6   g | ]\}}d |t |ttfrt|nt|f qS )z%s=%s)rq   r9   r+   hexreprr   r   r   r   r     s    $z%Instance.__repr__.<locals>.<listcomp>r   )r   r`   joinr   r   r   r   r   __repr__  s   
zInstance.__repr__c                 C      t |  S rx   )lenr   r   r   r   r   __len__     zInstance.__len__c                 C   r   )Nr   r   )r\   r   r   r   r   _size  r   zInstance._sizerx   )r
   r   r   ry   r]   r   r   rw   r   r   r   r   r   r   r   r   r   r   r     s    

r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )PointerInstancezDLike the Instance class, but for structures referenced by a pointer.c                 C   s"   || _ || _|| _|| _d | _d S rx   )_streamr   _addr_ctx_value)r\   ra   streamaddrctxr   r   r   r]     s
   
zPointerInstance.__init__c                 C   s   t d| j| j | jdkrt | jd u rA| j }| j| j t| jt	r1| j
| j| j}n| j
| j}| j| || _| jS )Nz)Dereferencing pointer -> 0x{:016x} [{!r}]r   )r   r   r   r   r   tellseekrq   r   r   _readr   )r\   posrk   r   r   r   _get  s   


zPointerInstance._getc                 C   s   t |  |S rx   )getattrr   ru   r   r   r   rw     r   zPointerInstance.__getattr__c                 C   r   rx   )rr   r   r   r   r   r   __str__!  r   zPointerInstance.__str__c                 C   s
   | j dkS Nr   )r   r   r   r   r   __nonzero__$  r~   zPointerInstance.__nonzero__c                 C      d | j| jS )Nz<Pointer {!r} @ 0x{:x}>)r   r   r   r   r   r   r   r   '     zPointerInstance.__repr__N)
r
   r   r   ry   r]   r   rw   r   r   r   r   r   r   r   r     s    r   c                
   @   s   e Zd ZdZddd fddd fddd fd	d
d fddd fddd fddd fddd fgZdd ZdddZdd Zdd ZdS )r   z9Expression parser for simple calculations in definitions.+c                 C   s   | | S rx   r   ar:   r   r   r   <lambda>/      zExpression.<lambda>-c                 C   s   | | S rx   r   r   r   r   r   r  0  r  r   c                 C   s   | | S rx   r   r   r   r   r   r  1  r  /c                 C   s   | | S rx   r   r   r   r   r   r  2  r  &c                 C   s   | |@ S rx   r   r   r   r   r   r  3  r  |c                 C   s   | |B S rx   r   r   r   r   r   r  4  r  z>>c                 C   s   | |? S rx   r   r   r   r   r   r  5  r  z<<c                 C   s   | |> S rx   r   r   r   r   r   r  6  r  c                 C      || _ || _d S rx   )r   expr)r\   r   r  r   r   r   r]   9     
zExpression.__init__Nc                 C   s   |r|ni }d}g }d}t t| jD ]8}| j| dkr(|d7 }|| d}q| j| dkrD|d8 }| ||}| }|t|7 }q|| j| 7 }q| ||S )Nr   r   r   r   r   )rs   r   r  r   evaluate_partpoprr   )r\   contextlevellevelsbufr@   r   r   r   r   r   =  s$   
zExpression.evaluatec                 C   s   |  }| jD ]#}|d |v r*||d d\}}|d | ||| ||  S q||v r3|| S |dr=t|dS || jjv rI| jj| S t|S )Nr   r   0x   )r   	operatorsr   r
  r   r9   r   rR   )r\   er   or   r:   r   r   r   r
  U  s   
"

zExpression.evaluate_partc                 C      | j S rx   r  r   r   r   r   r   h     zExpression.__repr__rx   )	r
   r   r   ry   r  r]   r   r
  r   r   r   r   r   r   +  s    








r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd S )!BaseTypez$Base class for cstruct type classes.c                 C   r{   rx   r|   r}   r   r   r   r]   o  r~   zBaseType.__init__c                 C   s   t |}| |S )zParse the given data according to the type that implements this class.

        Args:
            data: Byte string to parse.

        Returns:
            The parsed value of this type.
        )r   r   r   r   r   r   readsr  s   	
zBaseType.readsc                 C   s   t  }| || | S )zDump the given data according to the type that implements this class.

        Args:
            data: Data to dump.

        Returns:
            The resulting bytes.
        )r   _writer   )r\   r   outr   r   r   r   ~  s   	zBaseType.dumpsc                 O   s$   t |tttfr| |S | |S )zParse the given data according to the type that implements this class.

        Args:
            obj: Data to parse. Can be a (byte) string or a file-like object.

        Returns:
            The parsed value of this type.
        )rq   rr   r   newbytesr  r   )r\   objr   r   r   r   r   rm     s   	

zBaseType.readc                 C      |  ||S )a  Write the given data to a writable file-like object according to the
        type that implements this class.

        Args:
            stream: Writable file-like object to write to.
            data: Data to write.

        Returns:
            The amount of bytes written.
        r  r\   r   r   r   r   r   r     s   zBaseType.writec                 C   r   rx   r   r\   r   r   r   r   r     r  zBaseType._readc                    s    fddt |D S )Nc                    s   g | ]}  qS r   )r   r   r@   r!  r   r   r         z(BaseType._read_array.<locals>.<listcomp>)rs   r\   r   r   r   r!  r   _read_array     zBaseType._read_arrayc                 C   r   rx   r   r!  r   r   r   _read_0  r  zBaseType._read_0c                 C   r   rx   r   r   r   r   r   r    r  zBaseType._writec                 C   s"   d}|D ]
}||  ||7 }q|S r   r  )r\   r   r   numr@   r   r   r   _write_array  s   zBaseType._write_arrayc                 C   r   rx   r   r   r   r   r   _write_0  r  zBaseType._write_0c                 C   r   )z$Return a default value of this type.r   r   r   r   r   default     zBaseType.defaultc                 C   r   )z$Return a default array of this type.r   r   r   r   r   default_array  r,  zBaseType.default_arrayc                 C   s   t | j| |S rx   )r   r   r\   r   r   r   r   r     r   zBaseType.__getitem__c                 O   sJ   t |dkr| j|i |S |  }|r#| D ]
\}}t||| q|S r   )r   rm   r+  r   setattr)r\   r   r   rk   r   r   r   r   r   __call__  s   zBaseType.__call__N)r
   r   r   ry   r]   r  r   rm   r   r   r%  r'  r  r)  r*  r+  r-  r   r0  r   r   r   r   r  l  s"    r  c                       s2   e Zd ZdZd
 fdd	Zdd Zdd	 Z  ZS )RawTypez3Base class for raw types that have a name and size.Nr   c                    s    || _ || _tt| | d S rx   )r`   sizer   r1  r]   )r\   r   r`   r2  r   r   r   r]        zRawType.__init__c                 C   r  rx   r2  r   r   r   r   r     r  zRawType.__len__c                 C   s   | j r| j S t| S rx   )r`   r  r   r   r   r   r   r     s   
zRawType.__repr__r   )r
   r   r   ry   r]   r   r   r   r   r   r   r   r1    s
    r1  c                       sn   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Zdd ZdddZ	dd Z
dd Zdd ZdddZ  ZS )r   zType class for structures.Nc                    sV   || _ d | _t | _|r|ng | _| jD ]}|| j|j < q|   tt| | d S rx   )	r`   r2  r   r   r   _calc_offsetsr   r   r]   )r\   r   r`   r   rF   r   r   r   r]     s   
zStructure.__init__c              	   C   s   d}d }d}| j D ]H}|jr5|dks|j|kr,|j}|jd }|d ur+||_||j7 }nd |_||j8 }q	||_|d urQz	|t|j7 }W q	 tyP   d }Y q	w q	d S Nr   rB   )r   r   r   r2  offsetr   	TypeError)r\   r7  bitstypebitsremainingr   r   r   r   r5    s0   



zStructure._calc_offsetsc                 C   s   d}d }d}| j D ]7}|jr*|dks|j|kr$|j}|jd }||j7 }||j8 }q	t|j}||7 }|jd ur@t||j| }q	|S r6  )r   r   r   r2  r   r7  max)r\   r2  r9  r:  r   fieldlenr   r   r   
_calc_size  s"   





zStructure._calc_sizec                 O   s  t d| j| j t|| jj}| }t }i }| jD ]b}| }	| j	|j
}
|jrJ|	||j krJt d||j|j |||j  ||j }	|jrX||
|j||j< q|  t|
ttfrj|
||}n|
|}| |	 ||j< |||j< qt| ||S )Nz[Structure::read] {} {}z!+ seeking to 0x{:x}+0x{:x} for {})r   r`   r2  	BitBufferr   rQ   r   r   r   rZ   r   r7  r   r   r   rm   resetrq   r   r   r   r   )r\   r   r   r   	bitbufferstruct_startrk   r   r   startftr   r   r   r   r   $  s6   



zStructure._readc                 C   sz   t || jj}d}| jD ]'}|jr||jt||j|j q|j	r&|
  ||j|t||j7 }q|j	r;|
  |S r   )r>  r   rQ   r   r   r   r   r   r`   r   flushr  )r\   r   r   r@  r(  r   r   r   r   r  J  s   
zStructure._writec                 C   s:   t |||d}| j| || j|< d| _t| || dS )zAdd a field to this structure.

        Args:
            name: The field name.
            type_: The field type.
            offset: The field offset.
        r7  N)r   r   r   r   r2  r/  )r\   r`   r   r7  r   r   r   r   	add_field^  s
   
zStructure.add_fieldc                 C   s,   t  }| jD ]
}|j ||j< qt| |S )zCreate and return an empty Instance from this structure.

        Returns:
            An empty Instance from this structure.
        )r   r   r   r+  r`   r   )r\   rk   r   r   r   r   r+  l  s   

zStructure.defaultc                 C   s   | j d u r
|  | _ | j S rx   )r2  r=  r   r   r   r   r   x  s   

zStructure.__len__c                 C      d | jS )Nz<Structure {}>)r   r`   r   r   r   r   r   ~  r   zStructure.__repr__r   c                 C   s|   |dkrt d| j | jD ],}|jdu rd}nd|j}t dd| ||j|j t|jtr;|j|d  qdS )	zPretty print this structure.r   	struct {}Nz0x??z0x{:02x}z{}+{} {} {}r   r   )	r   r   r`   r   r7  r   rq   r   show)r\   indentr   r7  r   r   r   rI    s   

zStructure.showrx   )r   )r
   r   r   ry   r]   r5  r=  r   r  rF  r+  r   r   rI  r   r   r   r   r   r     s    &
r   c                   @   8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )r>  z;Implements a bit buffer that can read and write bit fields.c                 C   s"   || _ || _d | _d| _d| _d S r   )r   rQ   r   _buffer
_remaining)r\   r   rQ   r   r   r   r]     s
   
zBitBuffer.__init__c                 C   s   | j dk s
| j|kr|| _|jd | _ || j| _| jdkr8| jd|> d @ }|  j|L  _|  j |8  _ |S | jd| j | > d d| j > d A @ }|| j | L }|  j |8  _ |S )Nr   rB   >)rM  r   r2  r   r   rL  rQ   )r\   
field_typer   r   r   r   r   rm     s   
zBitBuffer.readc                 C   sr   | j dkr|jd | _ || _| jdkr$|  j|| jjd | j  > O  _n|  j|| j | > O  _|  j |8  _ d S )Nr   rB   rN  )rM  r2  r   rQ   rL  )r\   rO  r   r   r   r   r   r     s   

"zBitBuffer.writec                 C   s(   | j | j| j d | _ d| _d| _d S r   )r   r  r   rL  rM  r   r   r   r   rD    s   
zBitBuffer.flushc                 C   s   d | _ d| _d| _d S r   )r   rL  rM  r   r   r   r   r?    s   
zBitBuffer.resetN)	r
   r   r   ry   r]   rm   r   rD  r?  r   r   r   r   r>    s    r>  c                   @   s"   e Zd ZdZdddZdd ZdS )r   zHolds a structure field.Nc                 C   s   || _ || _|| _|| _d S rx   )r`   r   r   r7  )r\   r`   r   r   r7  r   r   r   r]     s   
zField.__init__c                 C   r   )Nz<Field {} {}>)r   r`   r   r   r   r   r   r     r   zField.__repr__)NN)r
   r   r   ry   r]   r   r   r   r   r   r     s    
r   c                       sJ   e Zd ZdZ fddZdddZdd Zd	d
 Zdd Zdd Z	  Z
S )r   a  Implements a fixed or dynamically sized array type.

    Example:
        When using the default C-style parser, the following syntax is supported:

            x[3] -> 3 -> static length.
            x[] -> None -> null-terminated.
            x[expr] -> expr -> dynamic length.
    c                    s8   || _ || _t| jtp| jd u | _tt| | d S rx   )r   r   rq   r   dynamicr   r   r]   )r\   r   r   r   r   r   r   r]     s   zArray.__init__Nc                 C   sD   | j d u r| j|S | jr| j |}n| j }| j|td|S r   )r   r   r'  rP  r   r%  r;  )r\   r   r  r   r   r   r   r     s   
zArray._readc                 C   s&   | j d u r| j||S | j||S rx   )r   r   r*  r)  )r\   rF   r   r   r   r   r    s   
zArray._writec                    s,    j s jd u r
g S  fddt jD S )Nc                    s   g | ]} j  qS r   )r   r+  r"  r   r   r   r     r#  z!Array.default.<locals>.<listcomp>)rP  r   rs   r   r   r   r   r+    s   zArray.defaultc                 C   s&   | j d u rd| jS d| j| j S )Nz{0!r}[]z
{0!r}[{1}])r   r   r   r   r   r   r   r     s   
zArray.__repr__c                 C   s   | j rtdt| j| j S )NzDynamic size)rP  r8  r   r   r   r   r   r   r   r     s   zArray.__len__rx   )r
   r   r   ry   r]   r   r  r+  r   r   r   r   r   r   r   r     s    

r   c                       `   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Z  ZS )rT   zDImplements a packed type that uses Python struct packing characters.c                       || _ tt| ||| d S rx   )packcharr   rT   r]   )r\   r   r`   r2  rS  r   r   r   r]        zPackedType.__init__c                 C   s   |  |dd S Nr   r   )r%  r!  r   r   r   r     r   zPackedType._readc                 C   sZ   | j | }||}| jjt| | j }t||kr%tdt||f tt	
||S )NzRead %d bytes, but expected %d)r2  rm   r   rQ   rr   rS  r   EOFErrorlistr   unpack)r\   r   r   lengthr   fmtr   r   r   r%    s   

zPackedType._read_arrayc                 C   sF   g }	 | | j}t| jj| j |d }|dkr	 |S || qNTr   )rm   r2  r   rX  r   rQ   rS  r   )r\   r   rk   rH   r   r   r   r   r'    s   
zPackedType._read_0c                 C   s   |  ||gS rx   r)  r   r   r   r   r  +  r   zPackedType._writec                 C   s2   | j jtt| | j }|tj|g|R  S rx   )r   rQ   rr   r   rS  r   r   pack)r\   r   r   rZ  r   r   r   r)  .  s   zPackedType._write_arrayc                 C      |  ||dg S r   r\  r   r   r   r   r*  2     zPackedType._write_0c                 C      dS r   r   r   r   r   r   r+  5     zPackedType.defaultc                 C   
   dg| S r   r   r.  r   r   r   r-  8  r~   zPackedType.default_arrayr
   r   r   ry   r]   r   r%  r'  r  r)  r*  r+  r-  r   r   r   r   r   rT     s    	rT   c                       rQ  )rU   z=Implements a character type that can properly handle strings.c                       t t| |dd d S )NrI   r   )r   rU   r]   r}   r   r   r   r]   ?  r&  zCharType.__init__c                 C   s
   | dS )Nr   rm   r!  r   r   r   r   B  r~   zCharType._readc                 C   s   |dkrdS | |S )Nr       re  r$  r   r   r   r%  E  s   
zCharType._read_arrayc                 C   s>   g }	 | d}|dkrt |dkrn|| qd|S )NTr   rf      )rm   rV  r   r   r\   r   rk   cr   r   r   r'  K  s   



zCharType._read_0c                 C   s4   t |tr	t|}trt |tr|d}||S )Nzlatin-1)rq   r9   chrPY3rr   encoder   r   r   r   r   r  Y  s
   


zCharType._writec                 C   r  rx   r  r   r   r   r   r)  b  r   zCharType._write_arrayc                 C      |  ||d S Nrg  r  r   r   r   r   r*  e  r   zCharType._write_0c                 C   r`  rn  r   r   r   r   r   r+  h  ra  zCharType.defaultc                 C      d| S rn  r   r.  r   r   r   r-  k     zCharType.default_arrayrc  r   r   r   r   rU   <  s    	rU   c                       sl   e Zd ZdZ fddZedd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Z  ZS )rV   z!Implements a wide-character type.c                    rd  )NrJ   r<   )r   rV   r]   r}   r   r   r   r]   r  r&  zWcharType.__init__c                 C   s$   | j jdkrdS | j jdkrdS d S )Nr    z	utf-16-lerN  z	utf-16-be)r   rQ   r   r   r   r   encodingu  s
   zWcharType.encodingc                 C   s   | d| jS )Nr<   rm   decoderq  r!  r   r   r   r   |  r_  zWcharType._readc                 C   s&   |dkrdS | d| }|| jS )Nr   r   r<   rr  )r\   r   r   r   r   r   r   r%    s   zWcharType._read_arrayc                 C   sB   d}	 | d}t|dkrt |dkrn||7 }q|| jS )Nrf  Tr<   s     )rm   r   rV  rs  rq  rh  r   r   r   r'    s   
zWcharType._read_0c                 C   s   | || jS rx   )r   rl  rq  r   r   r   r   r    r_  zWcharType._writec                 C   r  rx   r  r   r   r   r   r)    r   zWcharType._write_arrayc                 C   rm  N r  r   r   r   r   r*    r   zWcharType._write_0c                 C   r`  rt  r   r   r   r   r   r+    ra  zWcharType.defaultc                 C   ro  rt  r   r.  r   r   r   r-    rp  zWcharType.default_array)r
   r   r   ry   r]   propertyrq  r   r%  r'  r  r)  r*  r+  r-  r   r   r   r   r   rV   o  s    
rV   c                       sx   e Zd ZdZ fddZedd Zedd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Zdd Z  ZS )rW   zFImplements an integer type that can span an arbitrary amount of bytes.c                    rR  rx   )signedr   rW   r]   )r\   r   r`   r2  rw  r   r   r   r]     rT  zBytesInteger.__init__c                    s   g }t |D ][}d}| || |d |   |dkr,d fddtt t D  tr2t ntt }|D ]}	|d> |	B }q9|r\|d|d d > @ r\d|d d > }
||
d 8 }|| q|S )	Nr   r   r    rf  c                 3   s     | ]} ||d   V  qdS )r   Nr   r"  r   r   r   	<genexpr>  s    z%BytesInteger.parse.<locals>.<genexpr>rB   r<   )	rs   r   reversedr   rk  rW  mapordr   )r  r2  r   rw  rQ   numsri  r(  intsr@   biasr   rx  r   rf     s   $zBytesInteger.parsec                    s   g }| D ]]}t |}|dk r|d|d > 7 }dg|  |d }|dkr@|d@ }tr.t|fnt| |< |dL }|d8 }|dks#|dkrWd fdd	ttt D  nd  |  qd|S )
Nr   r   rB   rg     r    rf  c                 3   s$    | ]} ||d   d V  qdS )r   r   Nr   r"  rH   r   r   ry    s   " z$BytesInteger.pack.<locals>.<genexpr>)	r9   rk  r   rj  r   rz  rs   r   r   )r   r2  rQ   r  r@   r(  r:   r   r  r   r]    s$   
&

zBytesInteger.packc                 C   s*   |  || jd | jd| j| jjd S rU  rf   rm   r2  rw  r   rQ   r!  r   r   r   r     s   *zBytesInteger._readc                 C   s&   |  || j| | j|| j| jjS rx   r  r$  r   r   r   r%    s   &zBytesInteger._read_arrayc                 C   s*   g }	 |  |}|dkr	 |S || qr[  )r   r   )r\   r   rk   r   r   r   r   r'    s   

zBytesInteger._read_0c                 C   s   | | |g| j| jjS rx   r   r]  r2  r   rQ   r   r   r   r   r    s   zBytesInteger._writec                 C   s   | | || j| jjS rx   r  r   r   r   r   r)    s   zBytesInteger._write_arrayc                 C   r^  r   r\  r   r   r   r   r*    r_  zBytesInteger._write_0c                 C   r`  r   r   r   r   r   r   r+    ra  zBytesInteger.defaultc                 C   rb  r   r   r.  r   r   r   r-    r~   zBytesInteger.default_array)r
   r   r   ry   r]   staticmethodrf   r]  r   r%  r'  r  r)  r*  r+  r-  r   r   r   r   r   rW     s    


rW   c                       sx   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Z  ZS )r   a  Implements an Enum type.

    Enums can be made using any type. The API for accessing enums and their
    values is very similar to Python 3 native enums.

    Example:
        When using the default C-style parser, the following syntax is supported:

            enum <name> [: <type>] {
                <values>
            };

        For example, an enum that has A=1, B=5 and C=6 could be written like so:

            enum Test : uint16 {
                A, B=5, C
            };
    c                    sL   || _ || _i | _| D ]	\}}|| j|< qtt| ||t| j  d S rx   )r   r   reverser   r   r   r]   r   )r\   r   r`   r   r   r   r   r   r   r   r]     s   zEnum.__init__c                 C   s
   t | |S rx   )EnumInstancer\   r   r   r   r   r0    r~   zEnum.__call__c                 C   s   | j |}| |S rx   )r   r   )r\   r   r   r   r   r   r     s   z
Enum._readc                 C   s   t t| | j||S rx   )rW  r{  r   r%  r$  r   r   r   r%  !  r&  zEnum._read_arrayc                 C   s   t t| | j|S rx   )rW  r{  r   r'  r!  r   r   r   r'  $     zEnum._read_0c                 C   s"   t |tr|jn|}| j||S rx   )rq   r  r   r   r  r   r   r   r   r  '  s   zEnum._writec                 C      dd |D }| j ||S )Nc                 S       g | ]}t |tr|jn|qS r   rq   r  r   r   rH   r   r   r   r   ,  r   z%Enum._write_array.<locals>.<listcomp>)r   r)  r   r   r   r   r)  +     zEnum._write_arrayc                 C   r  )Nc                 S   r  r   r  r  r   r   r   r   0  r   z!Enum._write_0.<locals>.<listcomp>)r   r*  r   r   r   r   r*  /  r  zEnum._write_0c                 C   s   | dS r   r   r   r   r   r   r+  3  rp  zEnum.defaultc                 C       || j v r| | j | S t|rx   )r   KeyErrorru   r   r   r   r   6     
zEnum.__getitem__c                 C   r  rx   )r   rt   ru   r   r   r   rw   <  r  zEnum.__getattr__c                 C   s
   || j v S rx   )r   ru   r   r   r   r   B  r~   zEnum.__contains__)r
   r   r   ry   r]   r0  r   r%  r'  r  r)  r*  r+  r   rw   r   r   r   r   r   r   r     s    
r   c                   @   sL   e Zd ZdZdd Zedd Zdd Zdd	 Zd
d Z	dd Z
dd ZdS )r  z&Implements a value instance of an Enumc                 C   r  rx   )r   r   )r\   r   r   r   r   r   r]   I  r	  zEnumInstance.__init__c                 C   s.   | j | jjvrd| jj| j S | jj| j  S )Nz{}_{})r   r   r  r   r`   r   r   r   r   r`   M  s   zEnumInstance.namec                 C   s4   t |tr|j| jurdS t|dr|j}| j|kS )NFr   )rq   r  r   hasattrr   r  r   r   r   __eq__S  s
   

zEnumInstance.__eq__c                 C   s   |  |du S )NF)r  r  r   r   r   __ne__\  r   zEnumInstance.__ne__c                 C   s   t | j| jfS rx   )hashr   r   r   r   r   r   __hash___  r   zEnumInstance.__hash__c                 C   s   d | jj| jS )Nz{}.{})r   r   r`   r   r   r   r   r   b  r_  zEnumInstance.__str__c                 C   s   d | jj| j| jS )Nz<{}.{}: {}>)r   r   r`   r   r   r   r   r   r   e  r  zEnumInstance.__repr__N)r
   r   r   ry   r]   rv  r`   r  r  r  r   r   r   r   r   r   r  F  s    
	r  c                       s$   e Zd Z fddZdd Z  ZS )Unionc                    s   || _ tt| | d S rx   )r   r   r  r]   r}   r   r   r   r]   j  r   zUnion.__init__c                 C   r   rx   r   r!  r   r   r   r   n  r  zUnion._read)r
   r   r   r]   r   r   r   r   r   r   r  i  s    r  c                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
r   z(Implements a pointer to some other type.c                    s    || _ || _tt| | d S rx   )r   r   r   r   r]   )r\   r   targetr   r   r   r]   u  r3  zPointer.__init__c                 C   s   | j |}t| j|||S rx   )r   r[   r   r   )r\   r   r   r   r   r   r   r   z  s   zPointer._readc                 C   s   t | jjS rx   )r   r   r[   r   r   r   r   r   ~  r   zPointer.__len__c                 C   rG  )Nz<Pointer {!r}>)r   r   r   r   r   r   r     r   zPointer.__repr__)	r
   r   r   ry   r]   r   r   r   r   r   r   r   r   r   r  s    r   c                       s(   e Zd ZdZ fddZdd Z  ZS )rX   zImplements a void type.c                    s   t t| d dd d S )NrP   r   )r   rX   r]   r   r   r   r   r]     r&  zVoidType.__init__c                 C   s   d S rx   r   r!  r   r   r   r     ra  zVoidType._read)r
   r   r   ry   r]   r   r   r   r   r   r   rX     s    rX   c                 C   sD   g }| j D ]}t|j}||j|f qt| jtjfd|i}|S )z1Create ctypes structures from cstruct structures._fields_)r   ctypes_typer   r   r`   _ctypesr   )	structurer   r   ra   ttr   r   r   ctypes  s   

r  c                 C   s   t jt jt jd}t| tr|| j S t| trt jS t| t	r*t
| j}|| j S t| tr9t
| j}t|S td| jj )N)rA   r@   r:   zType not implemented: %s)r  c_ulongc_longc_int8rq   rT   rS  rU   c_charr   r  r   r   r   _targetr  POINTERr   r   r
   )ra   mappingsubtyper   r   r   r    s   








r  c                   @   rK  )r   zICompiler for cstruct structures. Creates somewhat optimized parsing code.c                 C   r{   rx   r|   r}   r   r   r   r]     r~   zCompiler.__init__c                 C   sR   |  |}t|dd}tttttttt	t
td
}t|| ||j | j||}|S )Nz
<compiled>exec)
r   r   r   r   r  r   rW   r>  r   rs   )gen_struct_classr   r   r   r   r   r  r   rW   r>  r   rs   r  r`   r   )r\   r  sourceri  envscr   r   r   r     s    

zCompiler.compilec                 C   s&  g }g }g }d}d}|j D ]}| j|j}t|ttttt	t
ttfs*td|t|ts:t|trt|jtr|rE|| || d}	t|tri|j}
t|
tr[dj|
jd}
|	dj|j|
|jjd7 }	n|	d	j|j|jd
7 }	|	dj|jd7 }	||	 d}g }q|jr|r|| || |dj|j|jj|jd d}g }d}q|r|d d}zt|}||7 }|| W q ty   |r|| || || | d}g }Y qw t|r|| || d|}ddd |dD }|tj|j|d d|S )Nr   Fz!Unsupported type for compiler: {}zs = stream.tell()
z6max(0, Expression(self.cstruct, "{expr}").evaluate(r))r  zjr["{name}"] = []
for _ in xrange({num}):
    r["{name}"].append(self.cstruct.{struct_name}._read(stream))
)r`   r(  struct_namez7r["{name}"] = self.cstruct.{struct_name}._read(stream)
)r`   r  z#sizes["{name}"] = stream.tell() - s)r`   z>r["{name}"] = bitreader.read(self.cstruct.{type_name}, {bits}))r`   	type_namer   Tzbitreader.reset()z

r   c                 S   s   g | ]}d | qS )z        r   )r   r   r   r   r   r   *  s    z-Compiler.gen_struct_class.<locals>.<listcomp>)r`   	read_code)r   r   rZ   r   rq   r   r   r   r   rT   rU   rV   rW   r   r   r   gen_read_blockr   r   r  r`   r   r   r   gen_dynamic_blockr   r   COMPILE_TEMPL)r\   r  blocksclasses	cur_block	read_sizeprev_was_bitsr   rC  struct_readr(  r   r  r   r   r   r    s   








zCompiler.gen_struct_classc                 C   sP  dj |d}g }g }d }d}d}d}	|D ]z}
| j|
j}|}d}d}d}t|tr/|j}n	t|tr8| jj}t|trt|j	}|}|j}t|trN|j}n	t|trW| jj}t|t
ttfrkd ||||j  }n(d |	|	| }nt|t
r~t|}nt|ttfrd |||j }nt|	}|st|tr|j}nd}t|tt
tttfr|}t|t
ttfrd}d}||j9 }n|j}||kr|d || d}||7 }|}d}t|trd	j ||j||j|dkrd
ndd}nt|t
tfrd |}t|tr|d7 }nd |}t|trdj |j|d}nOt|tr3t|jtr3dj |jj|d}n8t|trCdj |jj|d}n(t|trZt|jtrZdj |jj|d}nt|trkt|trkd |}|dj |
j|d |dj |
j||j d |	|7 }	|||j 7 }q|r|d || | d|d|S )Nz~buf = stream.read({size})
if len(buf) != {size}: raise EOFError()
data = struct.unpack(self.cstruct.endian + "{{}}", buf)
{{}}r4  r   r   r   z{}:{}xz{}{}z\BytesInteger.parse(buf[{slice}], {size}, {count}, {signed}, self.cstruct.endian){data_slice}z[0])slicer2  r   rw  
data_slicezbuf[{}]C.decode('utf-16-le' if self.cstruct.endian == '<' else 'utf-16-be')zdata[{}]z0EnumInstance(self.cstruct.{type_name}, {getter}))r  getterz=[EnumInstance(self.cstruct.{type_name}, d) for d in {getter}]z>PointerInstance(self.cstruct.{type_name}, stream, {getter}, r)zK[PointerInstance(self.cstruct.{type_name}, stream, d, r) for d in {getter}]zlist({})zr["{name}"] = {getter})r`   r  zsizes["{name}"] = {size})r`   r2  r   )r   r   rZ   r   rq   r   r   r[   r   r   rU   rV   rW   r2  rr   rT   rS  r   rw  r`   r   )r\   r2  blocktemplreadcoderZ  curtypecurcount
buf_offsetdata_offsetr   rC  ra   r   
data_count
read_slice	charcountrS  r  r   r   r   r  /  s   












zCompiler.gen_read_blockc                 C   s>  t |jtstd|j|jj}d }|jjsYt |tr'dj|j|jd}n*t |t	t
frCdj|jd|j d}t |t
rB|d7 }nt |trQdj|j|jd	}d
j||jdS |jjj}dj||j|jd}t |trwdj|j|jd}n!t |t	t
frd}t |t
r|d7 }nt |trdj|j|jd	}|j|d dS )Nz#Only Array can be dynamic, got {!r}zt = []
while True:
    d = stream.read({size})
    if len(d) != {size}: raise EOFError()
    v = struct.unpack(self.cstruct.endian + "{packchar}", d)[0]
    if v == 0: break
    t.append(v))r2  rS  zt = []
while True:
    c = stream.read({size})
    if len(c) != {size}: raise EOFError()
    if c == b"{null}": break
    t.append(c)
t = b"".join(t)z\x00)r2  nullr  zt = []
while True:
    d = stream.read({size})
    if len(d) != {size}: raise EOFError()
    v = BytesInteger.parse(d, {size}, 1, {signed}, self.cstruct.endian)
    if v == 0: break
    t.append(v))r2  rw  z1{reader}
r["{name}"] = t
sizes["{name}"] = len(t))readerr`   zdynsize = max(0, Expression(self.cstruct, "{expr}").evaluate(r))
buf = stream.read(dynsize * {type_size})
if len(buf) != dynsize * {type_size}: raise EOFError()
r["{name}"] = {{reader}}
sizes["{name}"] = dynsize * {type_size})r  r`   	type_sizezRlist(struct.unpack(self.cstruct.endian + "{{:d}}{packchar}".format(dynsize), buf)))rS  r  r  zGBytesInteger.parse(buf, {size}, dynsize, {signed}, self.cstruct.endian))r  r2  )rq   r   r   r   r   r   rT   r2  rS  rU   rV   rW   rw  r`   r  )r\   r   ra   r  r  	expr_readr   r   r   r    sb   


	









zCompiler.gen_dynamic_blockN)	r
   r   r   ry   r]   r   r  r  r  r   r   r   r   r     s    a|r   r   c                 C   s~  |r	|ddd }d}d}t dt| dD ]}d}g }t dD ]}	|s0|r0| \}}||7 }n
|r:|	dkr:||7 }||	 t| krG|d7 }nW| ||	  }
trSt|
n|
}
|
tv r[|
nd}|rr|dt|
7 }||| t	  n|dt|
7 }|| |d	8 }|dkrd}|dur|t	7 }|	d
kr|dur|t	7 }|d7 }|	dkr|d7 }qd
|}td||| || qdS )zHexdump some data.

    Args:
        s: Bytes to hexdump.
        palette: Colorize the hexdump using this color pattern.
        offset: Byte offset of the hexdump.
        prefix: Optional prefix.
    Nr   r   r  r   z  .z{:02x}r      r      z{}{:08x}  {:48s}  {})rs   r   r  rk  rj  	PRINTABLEr   r|  r   COLOR_NORMALr   r   )rg   paletter7  prefix	remainingactiver@   valscharsjri  pr   r   r   hexdump  sL   	



r  c              	   C   sp  t tfttfttfttftt	ft
tfttfg}t| tr&| }| j} | }nt| tr2|r2| |}ntdg }d}d| jd }|jjD ]^}||t|  \}	}
|||j|
f |d7 }t||j}t|trqt|}n(t|tr{t|}nt|trt !|}d|v r|"dddt|jd	  }|d
|	|jt#|7 }qFt$  t%|||d t$  t$| dS )a  Dump a structure or parsed structure instance.

    Prints a colorized hexdump and parsed structure output.

    Args:
        t: Structure or Instance to dump.
        data: Bytes to parse the Structure on, if t is not a parsed Instance.
        offset: Byte offset of the hexdump.
    zInvalid argumentsr   rH  z:
r   r   z
{}r   r?   z- {}{}{}: {}
rE  N)&	COLOR_REDCOLOR_BG_REDCOLOR_GREENCOLOR_BG_GREENCOLOR_YELLOWCOLOR_BG_YELLOW
COLOR_BLUECOLOR_BG_BLUECOLOR_PURPLECOLOR_BG_PURPLE
COLOR_CYANCOLOR_BG_CYANCOLOR_WHITECOLOR_BG_WHITErq   r   r   r   r   r_   r   r`   r   r   r   r   r   rr   r   r9   r   rW  pprintpformatrb   r  r   r  )ra   r   r7  colorsgr  cir  r   fgbgr   r   r   r   
dumpstruct2  sH   









 r  )Nr   r   r   )Lr   r   r   r  stringr   r  r  ior   collectionsr   builtinsr   r  ImportErrorversion_infork  r9   r+   rangers   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  digitsascii_letterspunctuationr  r  r   r   r   r   r   r   r   r   r   rz   re   r   r   r   r  r1  r   r>  r   r   rT   rU   rV   rW   r   r  r  r   rX   r  r   r  r  r   r   r   r   <module>   s   
 % A(Af /66136WJ#	
  
G;