
    09oenb                        d Z ddlZddlZddlZddlZddlmZ ddlmZ ddlmZ 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 ddlmZmZ ddlmZmZ dd	lmZmZ dd
lmZ ddl m!Z! ddl"m#Z# e
rddl$m%Z% ddl&m'Z' ee(ej)        f         Z*ededef         f         Z+	 ede+f         Z, eded                   Z-	 	 d4de*de.fdZ/ddde*ddfdZ0	 	 d5ddde*dee*         de1ded         f
dZ2d e-d!e(fd"Z3d#ed         de.fd$Z4	 d6d%dd&e,ded'         fd(Z5d)e(d*e(d+e6fd,Z7 G d- d.ee-                   Z8 G d/ d0e8d1                   Z9 G d2 d3e8d                   Z:dS )7ze
Load setuptools configuration from ``setup.cfg`` files.

**API will be made private in the future**
    N)defaultdict)partialwraps)TYPE_CHECKINGCallableAnyDictGenericIterableListOptionalTupleTypeVarUnion)DistutilsOptionErrorDistutilsFileError)RequirementInvalidRequirement)VersionInvalidVersion)SpecifierSet)SetuptoolsDeprecationWarning   )expandDistribution)DistributionMetadatastrTarget)r   r   )boundFfilepathreturnc                     ddl m}  |            }|r|                                ng }t          || ||          }t	          |          S )a,  Read given configuration file and returns options from it as a dict.

    :param str|unicode filepath: Path to configuration file
        to get options from.

    :param bool find_others: Whether to search for other configuration files
        which could be on in various places.

    :param bool ignore_option_errors: Whether to silently ignore
        options, values of which could not be resolved (e.g. due to exceptions
        in directives such as file:, attr:, etc.).
        If False exceptions are propagated as expected.

    :rtype: dict
    r   r   )setuptools.distr   find_config_files_applyconfiguration_to_dict)r"   find_othersignore_option_errorsr   dist	filenameshandlerss          SD:\Python Project\StaffProfile\venv\Lib\site-packages\setuptools/config/setupcfg.pyread_configurationr/   (   s^    ( -,,,,,<>>D,7?&&(((RIdHi1EFFH ***    r+   r   c                 N    t          | |           |                                  | S )z`Apply the configuration from a ``setup.cfg`` file into an existing
    distribution object.
    )r'   _finalize_requires)r+   r"   s     r.   apply_configurationr3   D   s+     4Kr0    other_filesr*   )ConfigHandler.c                 (   ddl m} t          j                            |          }t          j                            |          st          d|z            t          j                    }t          j        t          j        	                    |                     g ||}	 |
                    | |           t          | | j        |          }|                                  t          j        |           n# t          j        |           w xY w|S )zHRead configuration from ``filepath`` and applies to the ``dist`` object.r   )_Distributionz%Configuration file %s does not exist.)r,   )r*   )r%   r8   ospathabspathisfiler   getcwdchdirdirnameparse_config_filesparse_configurationcommand_options_finalize_license_files)r+   r"   r5   r*   r8   current_directoryr,   r-   s           r.   r'   r'   M   s    .-----wx((H7>>(## U !H8!STTT	HRW__X&&'''(+(x(I$(((CCC&$&=Q
 
 
 	$$&&&
"####"####Os   "AC9 9D
target_objkeyc                      dj         di t                      }t          j        t          | |          }t	          | ||          } |            S )z
    Given a target object and option key, get that option from
    the target object, either through a get_{key} method or
    from an attribute directly.
    z	get_{key}r4   )formatlocals	functoolsr   getattr)rE   rF   getter_nameby_attributegetters        r.   _get_optionrO   j   sP     %+$00vxx00K$Wj#>>LZl;;F688Or0   r-   c                     t          t                    }| D ]1}|j        D ]'}t          |j        |          }|||j                 |<   (2|S )zReturns configuration data gathered by given handlers as a dict.

    :param list[ConfigHandler] handlers: Handlers list,
        usually from parse_configuration()

    :rtype: dict
    )r   dictset_optionsrO   rE   section_prefix)r-   config_dicthandleroptionvalues        r.   r(   r(   v   sk     $D))K @ @) 	@ 	@F 2F;;E:?K./77	@ r0   distributionrB   )ConfigMetadataHandlerConfigOptionsHandlerc           	      B   t          j        |           5 }t          | |||          }|                                 | j        s|j        | _        t          | j        |||| j        | j                  }|                                 ddd           n# 1 swxY w Y   ||fS )a  Performs additional parsing of configuration options
    for a distribution.

    Returns a list of used option handlers.

    :param Distribution distribution:
    :param dict command_options:
    :param bool ignore_option_errors: Whether to silently ignore
        options, values of which could not be resolved (e.g. due to exceptions
        in directives such as file:, attr:, etc.).
        If False exceptions are propagated as expected.
    :rtype: list
    N)r   EnsurePackagesDiscoveredrZ   parsepackage_dirrY   metadatasrc_root)rX   rB   r*   ensure_discoveredoptionsmetas         r.   rA   rA      s    $ 
	(	6	6 :K& 	
 
 	' 	;'.':L$$! $!
 
 	

)              , =s   A1BBBlabel
orig_valueparsedc                 D   d|v st          |          dk    rdS t          j        t                    5  d                    |          }t          |          }|j        )d|  d|d          d}t          j        |t                     ddd           dS # 1 swxY w Y   dS )	am  Because users sometimes misinterpret this configuration:

    [options.extras_require]
    foo = bar;python_version<"4"

    It looks like one requirement with an environment marker
    but because there is no newline, it's parsed as two requirements
    with a semicolon as separator.

    Therefore, if:
        * input string does not contain a newline AND
        * parsed result contains two requirements AND
        * parsing of the two parts from the result ("<first>;<second>")
        leads in a valid Requirement with a valid marker
    a UserWarning is shown to inform the user about the possible problem.
    
   N;z#One of the parsed requirements in `z*` looks like a valid environment marker: 'r   z}'
Make sure that the config is correct and check https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#opt-2)
len
contextlibsuppressr   joinr   markerwarningswarnUserWarning)rd   re   rf   original_requirements_strreqmsgs         r.   %_warn_accidental_env_marker_misconfigrv      s   " zS[[A--		/	0	0 
, 
,$'HHV$4$4!344:!_e _ _;A!9_ _ _  M#{+++
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
,s   ABBBc                   R   e Zd ZU dZeed<   	 i Zeeef         ed<   	 dede	de
j        fdZed             Zd	 Zedd            Zed             Zed             Zed             Zedefd            ZdefdZed             Zed             Zedd            Zd Zd Zd ZdS )r6   z1Handles metadata supplied in configuration files.rS   aliasesrE   rb   ra   c                    i }| j         }|                                D ]I\  }}|                    |          s|                    |d                              d          }|||<   J|| _        || _        || _        g | _        || _	        d S )N .)
rS   items
startswithreplacestripr*   rE   sectionsrR   ra   )	selfrE   rb   r*   ra   r   rS   section_namesection_optionss	            r.   __init__zConfigHandler.__init__   s     '),-4]]__ 	5 	5)L/**>:: '//CCII#NNL%4H\""$8!$ &(!2r0   c                 :    t          d| j        j        z            ).Metadata item name to parser function mapping.z!%s must provide .parsers property)NotImplementedError	__class____name__)r   s    r.   parserszConfigHandler.parsers   s#     "/$.2II
 
 	
r0   c                    t                      }| j        }| j                            ||          }t	          |||          }||u rt          |          |rd S d}| j                            |          }|r'	  ||          }n# t          $ r d}| j        s Y nw xY w|rd S t	          |d|z  d           }|t          |||           n ||           | j
                            |           d S )NFTzset_%s)tuplerE   rx   getrK   KeyErrorr   	Exceptionr*   setattrrR   append)	r   option_namerW   unknownrE   current_valueskip_optionparsersetters	            r.   __setitem__zConfigHandler.__setitem__  s9   ''_
 l&&{K@@
KAAG##;''' 	F!!+.. 	u   "0  
  	FX%;TBB>JU3333F5MMM,,,,,s   8B BB,c                     t          |t                    r|S d|v r|                                }n|                    |          }d |D             S )zRepresents value as a list.

        Value is split either by separator (defaults to comma) or by lines.

        :param value:
        :param separator: List items separator character.
        :rtype: list
        rh   c                 ^    g | ]*}|                                 |                                 +S r4   r   ).0chunks     r.   
<listcomp>z-ConfigHandler._parse_list.<locals>.<listcomp>:  s-    BBB%EKKMMBBBBr0   )
isinstancelist
splitlinessplit)clsrW   	separators      r.   _parse_listzConfigHandler._parse_list(  s\     eT"" 	L5==$$&&EEKK	**EBB5BBBBr0   c                     d}i }|                      |          D ]\}|                    |          \  }}}||k    rt          d|z            |                                ||                                <   ]|S )zPRepresents value as a dict.

        :param value:
        :rtype: dict
        =z(Unable to parse option value to dict: %s)r   	partitionr   r   )r   rW   r   resultlinerF   sepvals           r.   _parse_dictzConfigHandler._parse_dict<  s     	OOE** 	. 	.D NN955MCci*>F   #&))++F399;;r0   c                 2    |                                 }|dv S )zQRepresents value as boolean.

        :param value:
        :rtype: bool
        )1trueyes)lowerr   rW   s     r.   _parse_boolzConfigHandler._parse_boolO  s     ,,,r0   c                     fd}|S )zReturns a parser function to make sure field inputs
        are not files.

        Parses a value after getting the key so error messages are
        more informative.

        :param key:
        :rtype: callable
        c                 z    d}|                      |          r"t          d                                        | S )Nfile:zCOnly strings are accepted for the {0} field, files are not accepted)r}   
ValueErrorrH   )rW   exclude_directiverF   s     r.   r   z3ConfigHandler._exclude_files_parser.<locals>.parsere  sI     ' 122  --3VC[[   Lr0   r4   )r   rF   r   s    ` r.   _exclude_files_parserz#ConfigHandler._exclude_files_parserY  s#    	 	 	 	 	 r0   root_dirc                     d}t          |t                    s|S |                    |          s|S |t          |          d         }d |                    d          D             }t          j        ||          S )aO  Represents value as a string, allowing including text
        from nearest files using `file:` directive.

        Directive is sandboxed and won't reach anything outside
        directory with setup.py.

        Examples:
            file: README.rst, CHANGELOG.md, src/file.txt

        :param str value:
        :rtype: str
        r   Nc              3   >   K   | ]}|                                 V  d S Nr   )r   r:   s     r.   	<genexpr>z,ConfigHandler._parse_file.<locals>.<genexpr>  s*      >>dTZZ\\>>>>>>r0   r   )r   r   r}   rk   r   r   
read_files)r   rW   r   include_directivespec	filepathss         r.   _parse_filezConfigHandler._parse_filep  s     $%%% 	L 122 	LS*++--.>>djjoo>>>	 H555r0   c                     d}|                     |          s|S |                    |d          }|                    | j        j                   t          j        |||          S )zRepresents value as a module attribute.

        Examples:
            attr: package.attr
            attr: package.module.attr

        :param str value:
        :rtype: str
        zattr:rz   )r}   r~   updatera   r^   r   	read_attr)r   rW   r^   r   attr_directive	attr_descs         r.   _parse_attrzConfigHandler._parse_attr  sh     !// 	LMM."55	 	41=>>>	;AAAr0   c                     fd}|S )zReturns parser function to represents value as a list.

        Parses a value applying given methods one after another.

        :param parse_methods:
        :rtype: callable
        c                 ,    | }D ]} ||          }|S r   r4   )rW   rf   methodparse_methodss      r.   r]   z1ConfigHandler._get_parser_compound.<locals>.parse  s+    F' ( (Mr0   r4   )r   r   r]   s    ` r.   _get_parser_compoundz"ConfigHandler._get_parser_compound  s#    	 	 	 	 	 r0   c                 b    i }|                                 D ]\  }\  }} |||          ||<   |S )a  Parses section options into a dictionary.

        Applies a given parser to each option in a section.

        :param dict section_options:
        :param callable values_parser: function with 2 args corresponding to key, value
        :rtype: dict
        )r|   )r   r   values_parserrW   rF   _r   s          r.   _parse_section_to_dict_with_keyz-ConfigHandler._parse_section_to_dict_with_key  sH     ,2244 	1 	1MC!S&sC00E#JJr0   Nc                 D    rfdnd }|                      ||          S )a   Parses section options into a dictionary.

        Optionally applies a given parser to each value.

        :param dict section_options:
        :param callable values_parser: function with 1 arg corresponding to option value
        :rtype: dict
        c                      |          S r   r4   )r   vr   s     r.   <lambda>z6ConfigHandler._parse_section_to_dict.<locals>.<lambda>  s    }}Q// r0   c                     |S r   r4   )r   r   s     r.   r   z6ConfigHandler._parse_section_to_dict.<locals>.<lambda>  s    UV r0   r   )r   r   r   r   s     ` r.   _parse_section_to_dictz$ConfigHandler._parse_section_to_dict  s7     5BW/////22?FKKKr0   c                     |                                 D ]>\  }\  }}t          j        t                    5  || |<   ddd           n# 1 swxY w Y   ?dS )zQParses configuration file section.

        :param dict section_options:
        N)r|   rl   rm   r   )r   r   namer   rW   s        r.   parse_sectionzConfigHandler.parse_section  s    
 #2"7"7"9"9 	# 	#T:Au$X.. # #"T
# # # # # # # # # # # # # # #	# 	#s   AA	A	c                     | j                                         D ]^\  }}d}|rd|z  }t          | d|z                      dd          d          }|t	          d| j        d|d           ||           _dS )	zTParses configuration file items from one
        or more related sections.

        rz   z_%szparse_section%sr{   __Nz*Unsupported distribution option section: [])r   r|   rK   r~   r   rS   )r   r   r   method_postfixsection_parser_methods        r.   r]   zConfigHandler.parse  s    
 .2]-@-@-B-B 	3 	3)L/N 6!&!58?"^3<<S$GG	9 9! %,*****LLL:  
 "!/2222'	3 	3r0   c                 D    t                    fd            }|S )zthis function will wrap around parameters that are deprecated

        :param msg: deprecation message
        :param warning_class: class of warning exception to be raised
        :param func: function to be wrapped around
        c                  >    t          j                    | i |S r   )rp   rq   )argskwargsfuncru   warning_classs     r.   config_handlerz@ConfigHandler._deprecated_config_handler.<locals>.config_handler  s*    M#}---4((((r0   r   )r   r   ru   r   r   s    ``` r.   _deprecated_config_handlerz(ConfigHandler._deprecated_config_handler  sB     
t	) 	) 	) 	) 	) 	) 
	) r0   )r   r   )r   
__module____qualname____doc__r   __annotations__rx   r
   r    AllCommandOptionsr   r\   r   propertyr   r   classmethodr   r   r   r   _Pathr   r   r   r   r   r   r]   r   r4   r0   r.   r6   r6      s        ;;
 !GT#s(^   33 #3
 ":3 3 3 3. 
 
 X
$- $- $-L C C C [C&   [$ - - [-   [, 6% 6 6 6 [62B B B B B(   [&   [ 
L 
L 
L [
L# # #3 3 34    r0   r6   c                        e Zd ZdZdddddZdZ	 dej        fd	d
dede	de
j        dee         def fdZed             Zd Z xZS )rY   r_   urldescriptionclassifiers	platforms)	home_pagesummary
classifierplatformFNrE   r   rb   r*   ra   r^   r   c                 l    t                                          ||||           || _        || _        d S r   )superr   r^   r   )r   rE   rb   r*   ra   r^   r   r   s          r.   r   zConfigMetadataHandler.__init__  s8     	W.BDUVVV& r0   c                 @   | j         }t          | j        | j                  }| j        }| j        }||||                     |dt                    ||                     ||           |d          |                      |d          dt                    |||| j	        |dS )r   r   z[The requires parameter is deprecated, please use install_requires for runtime dependencies.licenselicense_filezDThe license_file parameter is deprecated, use license_files instead.)r   keywordsprovidesrequires	obsoletesr   r  r  license_filesr   long_descriptionversionproject_urls)
r   r   r   r   r   r   r   r   r   _parse_version)r   
parse_list
parse_file
parse_dictexclude_files_parsers        r.   r   zConfigMetadataHandler.parsers   s     %
T-FFF
%
#9 $""77=,	  $44ZLL++I66 ;;$$^44-,	  (% **&/
 
 	
r0   c           	      d   |                      || j                  }||k    r]|                                }	 t          |           n6# t          $ r) d}t           |j        di t                                w xY w|S t          j	        | 
                    || j        | j                            S )zSParses `version` option value.

        :param value:
        :rtype: str

        zCVersion loaded from {value} does not comply with PEP 440: {version}r4   )r   r   r   r   r   r   rH   rI   r   r	  r   r^   )r   rW   r	  tmpls       r.   r  z$ConfigMetadataHandler._parse_versionB  s     ""5$-88emmooGD    ! D D D5  +;4;+B+B+B+BCCCD N~d..ud6FVVWWWs   A 3A:)r   r   r   rS   rx   strict_moder9   curdirr   boolr   r\   r   rQ   r   r   r   r   r  __classcell__r   s   @r.   rY   rY     s        N  #	 G K '+)! !*! #! #	!
 ":! d^! ! ! ! ! ! ! 
 
 X
BX X X X X X Xr0   rY   r   c                        e Zd ZdZdddededej        f fdZe	d             Z
d Zd	ed
efdZed             Zd Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )rZ   rb   rE   r   r*   ra   c                 v    t                                          ||||           |j        | _        i | _        d S r   )r   r   r`   r   r^   )r   rE   rb   r*   ra   r   s        r.   r   zConfigOptionsHandler.__init__a  s=     	W.BDUVVV"++-r0   c                 0    |                      |d          S )Nrj   )r   )r   r   s     r.   _parse_list_semicolonz*ConfigOptionsHandler._parse_list_semicolonl  s    u444r0   c                 :    |                      || j                  S )Nr   )r   r   )r   rW   s     r.   _parse_file_in_rootz(ConfigOptionsHandler._parse_file_in_rootp  s    >>>r0   rd   rW   c                     |                      |                     |                    }t          |||           d |D             S )Nc                 <    g | ]}|                     d           |S )#)r}   )r   r   s     r.   r   zAConfigOptionsHandler._parse_requirements_list.<locals>.<listcomp>y  s)    DDDts/C/CDDDDr0   )r  r  rv   )r   rd   rW   rf   s       r.   _parse_requirements_listz-ConfigOptionsHandler._parse_requirements_lists  sL    ++D,D,DU,K,KLL-eUFCCC EDDDDDr0   c                     | j         }| j        }| j        }| j        }|||||||                     |dt
                    t          | j        d          | j        | j        | j	        | j
        |t          |dS )r   zeThe namespace_packages parameter is deprecated, consider using implicit namespaces instead (PEP 420).install_requires)zip_safeinclude_package_datar^   scriptseager_resourcesdependency_linksnamespace_packagesr"  setup_requirestests_requirepackagesentry_points
py_modulespython_requirescmdclass)r   r   r   _parse_cmdclassr   r   r   r   r  _parse_packagesr  r   )r   r  
parse_boolr  parse_cmdclasss        r.   r   zConfigOptionsHandler.parsers{  s     %
%
%
- #$.%!) *"&"A"AH,	# # !(-/A! ! #8!7, 4$+&-
 
 	
r0   c                 v    | j         j        }t          j        |                     |          || j                  S r   )ra   r^   r   r/  r   r   )r   rW   r^   s      r.   r0  z$ConfigOptionsHandler._parse_cmdclass  s1    ,8t//66T]SSSr0   c                 :   ddg}|                                 }||vr|                     |          S |                     | j                            di                     }|                    ||d         k    | j        | j                   t          j	        di |S )zTParses `packages` option value.

        :param value:
        :rtype: list
        zfind:zfind_namespace:zpackages.findr   )
namespacesr   fill_package_dirr4   )
r   r   parse_section_packages__findr   r   r   r   r^   r   find_packages)r   rW   find_directivestrimmed_valuefind_kwargss        r.   r1  z$ConfigOptionsHandler._parse_packages  s     #$56//##E*** 77Mor22
 
 	%);;]!- 	 	
 	
 	
 #22k222r0   c                     |                      || j                  }g dt          fd|                                D                       }|                    d          }||d         |d<   |S )zParses `packages.find` configuration file section.

        To be used in conjunction with _parse_packages().

        :param dict section_options:
        )whereincludeexcludec                 *    g | ]\  }}|v 	|||fS r4   r4   )r   kr   
valid_keyss      r.   r   zEConfigOptionsHandler.parse_section_packages__find.<locals>.<listcomp>  s*    NNN1ZAaVr0   r>  Nr   )r   r   rQ   r|   r   )r   r   section_datar<  r>  rC  s        @r.   r8  z1ConfigOptionsHandler.parse_section_packages__find  s     22?DDTUU444
NNNN 2 2 4 4NNN
 
 ((#(8K r0   c                 F    |                      || j                  }|| d<   dS )z`Parses `entry_points` configuration file section.

        :param dict section_options:
        r,  N)r   r   r   r   rf   s      r.   parse_section_entry_pointsz/ConfigOptionsHandler.parse_section_entry_points  s,    
 ,,_d>NOO%^r0   c                 `    |                      || j                  }t          j        |          S r   )r   r   r   canonic_package_data)r   r   package_datas      r.   _parse_package_dataz(ConfigOptionsHandler._parse_package_data  s+    22?DDTUU*<888r0   c                 6    |                      |          | d<   dS )z`Parses `package_data` configuration file section.

        :param dict section_options:
        rJ  NrK  r   r   s     r.   parse_section_package_dataz/ConfigOptionsHandler.parse_section_package_data  s"    
  $77HH^r0   c                 6    |                      |          | d<   dS )zhParses `exclude_package_data` configuration file section.

        :param dict section_options:
        exclude_package_dataNrM  rN  s     r.   "parse_section_exclude_package_dataz7ConfigOptionsHandler.parse_section_exclude_package_data  s#    
 (,'?'?'P'P#$$$r0   c                 D                           | fd          }| d<   dS )zbParses `extras_require` configuration file section.

        :param dict section_options:
        c                 8                         d|  d|          S )Nzextras_require[r   )r   )rB  r   r   s     r.   r   zCConfigOptionsHandler.parse_section_extras_require.<locals>.<lambda>  s#    667M7M7M7MqQQ r0   extras_requireNr   rF  s   `  r.   parse_section_extras_requirez1ConfigOptionsHandler.parse_section_extras_require  s<    
 55QQQQ
 

 "(r0   c                 v    |                      || j                  }t          j        || j                  | d<   dS )z^Parses `data_files` configuration file section.

        :param dict section_options:
        
data_filesN)r   r   r   canonic_data_filesr   rF  s      r.   parse_section_data_filesz-ConfigOptionsHandler.parse_section_data_files  s;    
 ,,_d>NOO#6vt}MM\r0   )r   r   r   rS   r   r  r   r\   r   r   r  r  r   r   r   r   r0  r1  r8  rG  rK  rO  rR  rV  rZ  r  r  s   @r.   rZ   rZ   ]  sp       N	."	. #	. #		.
 ":	. 	. 	. 	. 	. 	. 5 5 [5? ? ?Ec E# E E E E 
 
 X
@T T T3 3 32  *& & &9 9 9I I IQ Q Q
( 
( 
(N N N N N N Nr0   rZ   )FF)r4   F)F);r   r9   rl   rJ   rp   collectionsr   r   r   typingr   r   r	   r
   r   r   r   r   r   r   r   distutils.errorsr   r   (setuptools.extern.packaging.requirementsr   r   #setuptools.extern.packaging.versionr   r   &setuptools.extern.packaging.specifiersr   setuptools._deprecation_warningr   rz   r   r%   r   distutils.distr   r   PathLiker   SingleCommandOptionsr   r    rQ   r/   r3   r  r'   rO   r(   rA   r   rv   r6   rY   rZ   r4   r0   r.   <module>re     s'   
 
			          # # # # # #            5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 F E E E E E E E T T T T T T T T G G G G G G G G ? ? ? ? ? ? H H H H H H       4,,,,,,333333c2;E5#445 
  445 	'M!N	O	O	O
 + ++ 
	+ + + +8n  .     $&!& 
$)%   	   :	F 	 	 	 	 	E*>$? D    * ( ( (&( :;	( ( ( (V, ,# ,t , , , ,Bk k k k kGFO k k k\	XX XX XX XX XXM*@A XX XX XXv]N ]N ]N ]N ]N=8 ]N ]N ]N ]N ]Nr0   