o
    ﯪgu                     @   s*  U d Z ddgZddlZddlZddlZddlmZ ddlZddl	m
Z
mZ ddlZddlZddlmZ ddlZddl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mZm Z m!Z!m"Z"m#Z#m$Z$ dd
l%m&Z&m'Z'm(Z(m)Z)m*Z* e rddl	m+Z+ ddl,m-Z- e"dddZ.e"de/e0e1e2e3Z4ej5dd dk rddl6m7Z7 e7Z8nddlm7Z7 e7e/ee4 f Z8e9e:Z;dZ<e'e=d< 	 e>dZ?	 G dd dej@ZAdede*f dede*f fddZBdede*f dede*f fddZCG d d dee. ZDG d!d" d"e8ZEd#e&de/fd$d%ZFG d&d dejGeAd'ZHdS )(z3Parser for reading and writing configuration files.GitConfigParserSectionConstraint    N)wraps)BufferedReaderIOBase)defenc
force_text)LockFile)AnyCallableGenericIOListDictSequenceTYPE_CHECKINGTupleTypeVarUnioncast)Lit_config_levelsConfigLevels_TupPathLikeassert_never_T)BytesIO)RepoT_ConfigParser)boundT_OMD_value   )r          )OrderedDict)systemuserglobal
repositoryCONFIG_LEVELSz2(?<=includeIf )\"(gitdir|gitdir/i|onbranch):(.+)\"c                       s:   e Zd ZdZdededeeef dd f fddZ  Z	S )MetaParserBuilderz_Utility class wrapping base-class methods into decorators that assure read-only
    properties.namebasesclsdictreturnc                    s   d}||v r7|| }|D ]*}dd t |t jD }|D ]\}}||v r%qt|}	||v r1t|	}	|	||< qqt | |||}
|
S )zEquip all base-class methods with a needs_values decorator, and all non-const
        methods with a :func:`set_dirty_and_flush_changes` decorator in addition to
        that.
        _mutating_methods_c                 s   s"    | ]}|d   ds|V  qdS )r   _N
startswith).0t r4   F/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/git/config.py	<genexpr>Y   s     z,MetaParserBuilder.__new__.<locals>.<genexpr>)inspect
getmembers	isroutineneeds_valuesset_dirty_and_flush_changessuper__new__)clsr*   r+   r,   kmmmutating_methodsbasemethodsmethodmethod_with_valuesnew_type	__class__r4   r5   r=   P   s   
zMetaParserBuilder.__new__)
__name__
__module____qualname____doc__strr   r   r
   r=   __classcell__r4   r4   rF   r5   r)   L   s    .r)   func.r-   c              	      s*   t  dddtdtdtf fdd}|S )zYReturn a method for ensuring we read values (on demand) before we try to access
    them.selfr   argskwargsr-   c                    s   |     | g|R i |S N)read)rO   rP   rQ   rN   r4   r5   assure_data_presento   s   z)needs_values.<locals>.assure_data_present)r   r
   r   )rN   rU   r4   rT   r5   r:   k   s    r:   non_const_funcc                    s*   dddt dt dtf fdd} j|_|S )zReturn a method that checks whether given non constant function may be called.

    If so, the instance will be set dirty. Additionally, we flush the changes right to
    disk.
    rO   r   rP   rQ   r-   c                    s(    | g|R i |}d| _ |   |S )NT)_dirtywrite)rO   rP   rQ   rvalrV   r4   r5   flush_changes   s   z2set_dirty_and_flush_changes.<locals>.flush_changes)r
   r   rH   )rV   r[   r4   rZ   r5   r;   x   s   r;   c                       s   e Zd ZdZdZdZdededdfdd	Zd d
dZ	dede
f fddZdede
de
de
fddZedefddZd ddZd!ddZdedededdfddZ  ZS )"r   a'  Constrains a ConfigParser to only option commands which are constrained to
    always use the section we have been initialized with.

    It supports all ConfigParser methods that operate on an option.

    :note:
        If used as a context manager, will release the wrapped ConfigParser.
    _config_section_name)	get_value	set_valuegetsetgetintgetfloat
getboolean
has_optionremove_sectionremove_optionoptionsconfigsectionr-   Nc                 C   s   || _ || _d S rR   r\   )rO   rj   rk   r4   r4   r5   __init__   s   
zSectionConstraint.__init__c                 C   s   | j   d S rR   r]   releaserO   r4   r4   r5   __del__   s   zSectionConstraint.__del__attrc                    s$    j v r fddS t  S )Nc                     s   j  g| R i |S rR   )_call_config)rP   rQ   rq   rO   r4   r5   <lambda>       z/SectionConstraint.__getattr__.<locals>.<lambda>)_valid_attrs_r<   __getattribute__)rO   rq   rF   rs   r5   __getattr__   s   
zSectionConstraint.__getattr__rC   rP   rQ   c                 O   s    t | j|| jg|R i |S )zdCall the configuration at the given method which must take a section name as
        first argument.)getattrr]   r^   )rO   rC   rP   rQ   r4   r4   r5   rr      s    zSectionConstraint._call_configc                 C      | j S )z*return: ConfigParser instance we constrain)r]   ro   r4   r4   r5   rj         zSectionConstraint.configc                 C   s
   | j  S )ziEquivalent to :meth:`GitConfigParser.release`, which is called on our
        underlying parser instance.rm   ro   r4   r4   r5   rn      s   
zSectionConstraint.release!SectionConstraint[T_ConfigParser]c                 C   s   | j   | S rR   )r]   	__enter__ro   r4   r4   r5   r}      s   
zSectionConstraint.__enter__exception_typeexception_value	tracebackc                 C   s   | j ||| d S rR   )r]   __exit__)rO   r~   r   r   r4   r4   r5   r         zSectionConstraint.__exit__r-   N)r-   r|   )rH   rI   rJ   rK   	__slots__rv   r   rL   rl   rp   r
   rx   rr   propertyrj   rn   r}   r   rM   r4   r4   rF   r5   r      s    	


"c                	       s*  e Zd ZdZdededdf fddZdededdf fdd	Zded
e	e ddf fddZ
dedef fddZdedef fddZdededdf fddZddedeedf deedf f fddZdede	e f fddZde	eeef  fddZde	eee	e f  fddZ  ZS )_OMDzOrdered multi-dict.keyvaluer-   Nc                    s   t  ||g d S rR   r<   __setitem__rO   r   r   rF   r4   r5   r      r   z_OMD.__setitem__c                    s2   || vrt  ||g d S t  || d S rR   )r<   r   __getitem__appendr   rF   r4   r5   add   s   z_OMD.addvaluesc                    s   t  || d S rR   r   )rO   r   r   rF   r4   r5   setall      z_OMD.setallc                       t  |d S Nr<   r   rO   r   rF   r4   r5   r         z_OMD.__getitem__c                    r   r   r   r   rF   r4   r5   getlast   r   z_OMD.getlastc                    s4   || vrt  ||g d S t  |}||d< d S r   )r<   r   r   )rO   r   r   priorrF   r4   r5   setlast   s
   z_OMD.setlastdefaultc                    s   t  ||gd S r   )r<   ra   )rO   r   r   rF   r4   r5   ra      r   z_OMD.getc                       t  |S rR   r   r   rF   r4   r5   getall      z_OMD.getallc                        fdd D S )z"List of (key, last value for key).c                    s   g | ]}| | fqS r4   r4   r2   kro   r4   r5   
<listcomp>   ru   z_OMD.items.<locals>.<listcomp>r4   ro   r4   ro   r5   items      z
_OMD.itemsc                    r   )z&List of (key, list of values for key).c                    s   g | ]	}|  |fqS r4   )r   r   ro   r4   r5   r      s    z"_OMD.items_all.<locals>.<listcomp>r4   ro   r4   ro   r5   	items_all   r   z_OMD.items_allrR   )rH   rI   rJ   rK   rL   r   r   r
   r   r   r   r   r   r   r   ra   r   r   r   r   rM   r4   r4   rF   r5   r      s    ,&r   config_levelc              	   C   s   t jdkr| dkrd} | dkrdS | dkr3tjdp%ttjddd	}ttt|d
dS | dkr?ttdS | dkrGt	dt
| t	d|  d S )Nwin32r$   r&   z/etc/gitconfigr%   XDG_CONFIG_HOMEHOME~z.configgitrj   z~/.gitconfigr'   zGNo repo to get repository configuration from. Use Repo._get_config_pathzInvalid configuration level: )sysplatformosenvironra   ospjoinnormpath
expanduser
ValueErrorr   )r   config_homer4   r4   r5   get_config_path   s   "r   c                       s  e Zd ZdZeZ	 edZdZ	ee	Z
ee	d d Z[	dZ	 					dOd	eded
eeed
f  f dededeedf ded ddfddZdPddZdPddZdQddZdeddfddZdPddZdedefdd Zd!eeee f d"eddfd#d$Zdeeef fd%d&Z de!e"eef  fd'd(Z#dPd)d*Z$d!eddfd+d,Z%d-ede!e"eef  f fd.d/Z&d-ede!e"ee!e f  fd0d1Z'e(dPd2d3Z)d4eddfd5d6Z*d7eddf fd8d9Z+e,defd:d;Z-	dRd7ed<ed=eee.eedf deee.eef fd>d?Z/	dRd7ed<ed=eee.eedf de!eee.eef  fd@dAZ0dBedeee.eef fdCdDZ1dEeeeee.ef defdFdGZ2e(e3d7ed<edEeeeee.ef dd fdHdIZ4e(e3d7ed<edEeeeee.ef dd fdJdKZ5d7edLedd f fdMdNZ6  Z7S )Sr   a  Implements specifics required to read git style configuration files.

    This variation behaves much like the :manpage:`git-config(1)` command, such that the
    configuration will be read on demand based on the filepath given during
    initialization.

    The changes will automatically be written once the instance goes out of scope, but
    can be triggered manually as well.

    The configuration file will be locked if you intend to change values preventing
    other instances to write concurrently.

    :note:
        The config is case-sensitive even when queried, hence section and option names
        must match perfectly.

    :note:
        If used as a context manager, this will release the locked file.
    z^\s*[#;]z\s*(?P<option>[^:=\s][^:=]*)z\s*(?P<vi>[:=])\s*z(?P<value>.*)$)add_sectionrg   rh   rb   NTfile_or_filesr   	read_onlymerge_includesr   repo)r   Nr-   c                 C   s   t jj| td |  |  |  t| ds|  | _|dur || _n|du r3|r/dd tD | _n
t	dt
|g| _|| _d| _d| _|| _|| _d| _|   dS )a  Initialize a configuration reader to read the given `file_or_files` and to
        possibly allow changes to it by setting `read_only` False.

        :param file_or_files:
            A file path or file object, or a sequence of possibly more than one of them.

        :param read_only:
            If ``True``, the ConfigParser may only read the data, but not change it.
            If ``False``, only a single file path or file object may be given. We will
            write back the changes when they happen, or when the ConfigParser is
            released. This will not happen if other configuration files have been
            included.

        :param merge_includes:
            If ``True``, we will read files mentioned in ``[include]`` sections and
            merge their contents into ours. This makes it impossible to write back an
            individual configuration file. Thus, if you want to modify a single
            configuration file, turn this off to leave the original dataset unaltered
            when reading it.

        :param repo:
            Reference to repository to use if ``[includeIf]`` sections are found in
            configuration files.
        )	dict_type_proxiesNc                 S   s"   g | ]}|d krt tt|qS )r'   )r   r   r   )r2   fr4   r4   r5   r   j  s    z,GitConfigParser.__init__.<locals>.<listcomp>z7No configuration level or configuration files specifiedF)cpRawConfigParserrl   r   hasattr_dictr   _file_or_filesr(   r   r   
_read_onlyrW   _is_initialized_merge_includes_repo_lock_acquire_lock)rO   r   r   r   r   r   r4   r4   r5   rl   ;  s,    


zGitConfigParser.__init__c                 C   sf   | j s1| js*t| jttjfr| j}nt| jttt	fr t
d| jj}| || _| j  d S d S )NzVWrite-ConfigParsers can operate on a single file only, multiple files have been passed)r   r   
isinstancer   rL   r   r   tuplelistr   r   r*   t_lock_obtain_lock)rO   r   r4   r4   r5   r   z  s   zGitConfigParser._acquire_lockc                 C   s   |    dS )z4Write pending changes if required and release locks.Nrn   ro   r4   r4   r5   rp     s   zGitConfigParser.__del__c                 C   s   |    | S rR   )r   ro   r4   r4   r5   r}     s   zGitConfigParser.__enter__rP   c                 G   s   |    d S rR   r   )rO   rP   r4   r4   r5   r     r   zGitConfigParser.__exit__c                 C   s   | j s| jr| j sdS z.z|   W n ty$   tjddd Y n	 ty,   Y nw W | jdur:| j  dS dS | jdurG| j  w w )a  Flush changes and release the configuration write lock. This instance must
        not be used anymore afterwards.

        In Python 3, it's required to explicitly release locks and flush changes, as
        ``__del__`` is not called deterministically anymore.
        Nz/Exception during destruction of GitConfigParserT)exc_info)	r   r   	_has_lockrX   IOError_loggererrorReferenceError_release_lockro   r4   r4   r5   rn     s   	
zGitConfigParser.release	optionstrc                 C   s   |S )z1Do not transform options in any way when writing.r4   )rO   r   r4   r4   r5   optionxform  s   zGitConfigParser.optionxformfpfpnamec                 C   st  d}d}d}d}d}dt dt fdd}	 | t}	|	sn|d	 }|	 d
ks/| j|	r0q|	dd	d  dkrC|	d dv rCq| j	|	 }
|s|
r|

d }|| jv ra| j| }n|tjkrj| j}n| d|ff}|| j|< d| j|< d}n|du rt|||	|s| j|	}
|
r|

ddd\}}}|dv rd|v r| ds|d}|dkr||d	   r|d| }| }|dkrd
}| | }t|d	kr|d dkr|d dkrd}||d	d }||| n9| j|	s|st|}||t|	 q|	 }	|	dr#d}|	dd }	||}| ||||	  q|r8|dS )a  Originally a direct copy of the Python 2.4 version of
        :meth:`RawConfigParser._read <configparser.RawConfigParser._read>`, to ensure it
        uses ordered dicts.

        The ordering bug was fixed in Python 2.4, and dict itself keeps ordering since
        Python 3.7. This has some other changes, especially that it ignores initial
        whitespace, since git uses tabs. (Big comments are removed to be more compact.)
        Nr   Fvr-   c                 S   s*   | r|  dr| d d } | tdS )N\r   unicode_escape)endswithencoder   decode)r   r4   r4   r5   string_decode  s   z,GitConfigParser._read.<locals>.string_decodeT    remrRheaderrH   optionvir   )=:;"r   z"")!rL   readliner   r   strip
re_commentmatchsplitlowerSECTCREgroup	_sectionsr   DEFAULTSECT	_defaultsr   r   MissingSectionHeaderErrorOPTCREr1   findisspacer   rstriplenr   OPTVALUEONLYParsingErrorr   reprr   r   r   )rO   r   r   cursectoptnamelinenois_multi_lineer   linemosectnamer   optvalposr4   r4   r5   _read  sv   		$




$

FzGitConfigParser._readc                 C   s   | j ot|  S rR   )r   r   _included_pathsro   r4   r4   r5   _has_includes  r   zGitConfigParser._has_includesc              	      s0  g }|   D ]}|dkr|| |7 }t|}|du s!| jdu r"q|d}|d  |dv rst  t	 fdddD sFd	    
d
rO d7  |
dr]tddd   | jjrrtt| jj rr|| |7 }q|dkrz| jjj}W n	 ty   Y qw t| r|| |7 }q|S )zList all paths that must be included to configuration.

        :return:
            The list of paths, where each path is a tuple of (option, value).
        includeNr   r"   )gitdirzgitdir/ic                 3   s    | ]}  |V  qd S rR   r0   )r2   sr   r4   r5   r6   1  s    z2GitConfigParser._included_paths.<locals>.<genexpr>)z.//z**/r  z**z/iz[a-zA-Z]c                 S   s   d |   |   S )Nz[{}{}])formatr   r   upper)mr4   r4   r5   rt   :  s    z1GitConfigParser._included_paths.<locals>.<lambda>onbranch)sectionsr   CONDITIONAL_INCLUDE_REGEXPsearchr   r   r   r   r   anyr   resubgit_dirfnmatchfnmatchcaserL   active_branchr*   	TypeError)rO   pathsrk   r   keywordbranch_namer4   r  r5   r    sF   




zGitConfigParser._included_pathsc           	      C   s  | j rdS d| _ dg}t| jttjfr| jg}nt| jtttfs'| jg}nt| j}t	|}d}|r|
d}d}t|drOttt |}| ||j n/tt|}z t|d}d}| ||j W d   n1 snw   Y  W n	 ty}   Y q2w |  r|  D ]M\}}|drt|}t|s|sqtt|}t|sJ d	tt||}t|}||v st|tjsq|| |d| |d
7 }q|s4|dkrd| _ dS dS )zRead the data stored in the files we have been initialized with.

        This will ignore files that cannot be read, possibly leaving an empty
        configuration.

        :raise IOError:
            If a file cannot be handled.
        NTr   r   Fseekrbr   z9Need absolute paths to be sure our cycle checks will workr   )!r   r   r   rL   r   r   r   r   r   rb   popr   r   r   bytesr  r*   openr   r  r  r1   r   r   isabsr   dirnamer   accessR_OKr   insertr   )	rO   files_to_readseennum_read_include_files	file_pathfile_okr   r/   include_pathr4   r4   r5   rS   M  s^   	












.
zGitConfigParser.readc                    sR   dt dtddf fdd}jr|tjj j D ]	\}}||| qdS )z`Write an .ini-format representation of the configuration state in
        git compatible format.r*   section_dictr-   Nc              
      sd     d|  t | D ]!\}}|dkrq|D ]}  d||ddf t qqd S )Nz[%s]
rH   z		%s = %s

z
	)rX   r   r   r   _value_to_stringreplace)r*   r5  r   r   r   r   rO   r4   r5   write_section  s   (z-GitConfigParser._write.<locals>.write_section)rL   r   r   r   r   r   r   )rO   r   r:  r*   r   r4   r9  r5   _write  s   zGitConfigParser._writesection_namec                    s   dd t  |D S )zK:return: list((option, value), ...) pairs of all items in the given sectionc                 S   s    g | ]\}}|d kr||fqS )rH   r4   )r2   r   r   r4   r4   r5   r     s     z)GitConfigParser.items.<locals>.<listcomp>)r<   r   )rO   r<  rF   r4   r5   r     s   zGitConfigParser.itemsc                 C   sb   t | j}| j|  D ] \}}|dkrq||v r!|||kr!q|D ]}||| q#q| S )zQ:return: list((option, [values...]), ...) pairs of all items in the given sectionrH   )r   r   r   r   r   r   )rO   r<  rvr   vsr   r4   r4   r5   r     s   
zGitConfigParser.items_allc                 C   s   |  d | js
dS t| jttfrtdt| j |  r&t	
d dS | j}t|ttjtf}|r>| jdur>| j  t|dsett|}t|d}| | W d   dS 1 s^w   Y  dS td|}|d t|d	rx|  | | dS )
zWrite changes to our file, if there are changes at all.

        :raise IOError:
            If this is a read-only writer instance or if we could not obtain a file
            lock.
        rX   NzRCannot write back if there is not exactly a single file to write to, have %i fileszsSkipping write-back of configuration file as include files were merged in.Set merge_includes=False to prevent this.r%  wbr   r   truncate)_assure_writablerW   r   r   r   r   AssertionErrorr   r  r   debugrL   r   r   r   r   r   r   r   r)  r;  r%  r@  )rO   r   is_file_lockfp_openr4   r4   r5   rX     s8   



"


zGitConfigParser.writemethod_namec                 C   s   | j rtd| |f d S )Nz(Cannot execute non-constant method %s.%s)r   r   )rO   rF  r4   r4   r5   rA    s   z GitConfigParser._assure_writablerk   c                    r   )z)Assures added options will stay in order.)r<   r   )rO   rk   rF   r4   r5   r     s   zGitConfigParser.add_sectionc                 C   rz   )zD:return: ``True`` if this instance may change the configuration file)r   ro   r4   r4   r5   r     r{   zGitConfigParser.read_onlyr   r   c                 C   s<   z|  ||}W n ty   |dur| Y S  w | |S )a  Get an option's value.

        If multiple values are specified for this option in the section, the last one
        specified is returned.

        :param default:
            If not ``None``, the given default value will be returned in case the option
            did not exist.

        :return:
            A properly typed value, either int, float or string

        :raise TypeError:
            In case the value could not be understood.
            Otherwise the exceptions known to the ConfigParser will be raised.
        N)ra   	Exception_string_to_value)rO   rk   r   r   valuestrr4   r4   r5   r_     s   
zGitConfigParser.get_valuec                    sR   z     j| |}W n ty   |dur|g Y S  w  fdd|D S )a  Get an option's values.

        If multiple values are specified for this option in the section, all are
        returned.

        :param default:
            If not ``None``, a list containing the given default value will be returned
            in case the option did not exist.

        :return:
            A list of properly typed values, either int, float or string

        :raise TypeError:
            In case the value could not be understood.
            Otherwise the exceptions known to the ConfigParser will be raised.
        Nc                    s   g | ]}  |qS r4   )rH  )r2   rI  ro   r4   r5   r   ?  s    z.GitConfigParser.get_values.<locals>.<listcomp>)r  r   r   rG  )rO   rk   r   r   lstr4   ro   r5   
get_values!  s   
zGitConfigParser.get_valuesrI  c              
   C   s   t tf}|D ]}z||}|t|krW q|W   S  ttfy$   Y qw | }|dkr/dS |dkr5dS t|ts?td||S )NfalseFtrueTz=Invalid value type: only int, long, float and str are allowed)intfloatr   r!  r   r   rL   )rO   rI  typesnumtypevalvlr4   r4   r5   rH  A  s*   

z GitConfigParser._string_to_valuer   c                 C   s    t |tttfrt|S t|S rR   )r   rN  rO  boolrL   r   )rO   r   r4   r4   r5   r7  ]  s   z GitConfigParser._value_to_stringc                 C   s,   |  |s
| | | ||| | | S )a  Set the given option in section to the given value.

        This will create the section if required, and will not throw as opposed to the
        default ConfigParser ``set`` method.

        :param section:
            Name of the section in which the option resides or should reside.

        :param option:
            Name of the options whose value to set.

        :param value:
            Value to set the option to. It must be a string or convertible to a string.

        :return:
            This instance
        )has_sectionr   rb   r7  rO   rk   r   r   r4   r4   r5   r`   b  s   

zGitConfigParser.set_valuec                 C   s0   |  |s
| | | j| || | | S )a  Add a value for the given option in section.

        This will create the section if required, and will not throw as opposed to the
        default ConfigParser ``set`` method. The value becomes the new value of the
        option as returned by :meth:`get_value`, and appends to the list of values
        returned by :meth:`get_values`.

        :param section:
            Name of the section in which the option resides or should reside.

        :param option:
            Name of the option.

        :param value:
            Value to add to option. It must be a string or convertible to a string.

        :return:
            This instance
        )rU  r   r   r   r7  rV  r4   r4   r5   	add_value{  s   

zGitConfigParser.add_valuenew_namec                    sp   |  |std| |  |rtd| t | | j| }| |D ]
\}}||| q&| | | S )zRename the given section to `new_name`.

        :raise ValueError:
            If:

            * `section` doesn't exist.
            * A section with `new_name` does already exist.

        :return:
            This instance
        z!Source section '%s' doesn't existz'Destination section '%s' already exists)rU  r   r<   r   r   r   r   rg   )rO   rk   rX  new_sectionr   r>  rF   r4   r5   rename_section  s   



zGitConfigParser.rename_section)NTTNNr   )r-   r   rR   )8rH   rI   rJ   rK   r	   r   r  compiler   optvalueonly_sourcer   r   r.   r   r   r   rT  r   rl   r   rp   r}   r
   r   rn   rL   r   r   r   r(  r  rN  r  r   r   r  rS   r;  r   r   r:   rX   rA  r   r   r   rO  r_   rK  rH  r7  r;   r`   rW  rZ  rM   r4   r4   rF   r5   r     s    




?


"a
2K""-	
#
  ,,")	metaclass)IrK   __all__abcconfigparserr   r  	functoolsr   r7   ior   r   loggingr   os.pathpathr   r  r   
git.compatr   r   git.utilr	   typingr
   r   r   r   r   r   r   r   r   r   r   r   	git.typesr   r   r   r   r   r   git.repo.baser   r   rL   r(  rN  rO  rT  r   version_infocollectionsr#   OrderedDict_OMD	getLoggerrH   r   r(   __annotations__r[  r  ABCMetar)   r:   r;   r   r   r   r   r   r4   r4   r4   r5   <module>   sN   8

""@-