
    Ixhc                        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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Z0ddde+ddfdZ1	 	 d5ddde+dee+         de2ded         f
dZ3d e.d!e)fd"Z4d#ed         de/fd$Z5	 d6d%dd&e-ded'         fd(Z6d)e)d*e)d+e7fd,Z8 G d- d.ee.                   Z9 G d/ d0e9d1                   Z: G d2 d3e9d                   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Set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          M/var/www/html/what/lib/python3.11/site-packages/setuptools/config/setupcfg.pyread_configurationr0   (   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_configurationr4   D   s+     4Kr1    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&   r9   ospathabspathisfiler   getcwdchdirdirnameparse_config_filesparse_configurationcommand_options_finalize_license_files)r,   r#   r6   r+   r9   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}r5   )formatlocals	functoolsr   getattr)rF   rG   getter_nameby_attributegetters        r/   _get_optionrP   j   sP     %+$00vxx00K$Wj#>>LZl;;F688Or1   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_optionsrP   rF   section_prefix)r.   config_dicthandleroptionvalues        r/   r)   r)   v   sk     $D))K @ @) 	@ 	@F 2F;;E:?K./77	@ r1   distributionrC   )ConfigMetadataHandlerConfigOptionsHandlerc           	         t          j        |           5 }t          | |||          }|                                 | j        s|j        | _        t          | j        |||| j        | j                  }|                                 | 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   EnsurePackagesDiscoveredr[   parsepackage_dirrZ   metadatasrc_root_referenced_filesupdate)rY   rC   r+   ensure_discoveredoptionsmetas         r/   rB   rB      s   $ 
	(	6	6 
:K& 	
 
 	' 	;'.':L$$! $!
 
 	

&--%t'=	
 	
 	
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2 =s   BB77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)rg   rh   ri   original_requirements_strreqmsgs         r/   %_warn_accidental_env_marker_misconfigry      s   " zS[[A--		/	0	0 
, 
,$'HHV$4$4!344:!_e _ _;A!9_ _ _  M#{+++
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
, 
,s   ABBBc                   B   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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 )r7   z1Handles metadata supplied in configuration files.rT   aliasesrF   re   rd   c                 @   i }| j         }|                                D ]I\  }}|                    |          s|                    |d                              d          }|||<   J|| _        || _        || _        g | _        || _	        t                      | _        d S )N .)rT   items
startswithreplacestripr+   rF   sectionsrS   rd   setrb   )	selfrF   re   r+   rd   r   rT   section_namesection_optionss	            r/   __init__zConfigHandler.__init__   s     '),-4]]__ 	5 	5)L/**>:: '//CCII#NNL%4H\""$8!$ &(!2+.55	 	r1   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
 
 	
r1   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)tuplerF   r{   getrL   KeyErrorr   	Exceptionr+   setattrrS   append)	r   option_namerX   unknownrF   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
        rk   c                 ^    g | ]*}|                                 |                                 +S r5   r   ).0chunks     r/   
<listcomp>z-ConfigHandler._parse_list.<locals>.<listcomp>A  s-    BBB%EKKMMBBBBr1   )
isinstancelist
splitlinessplit)clsrX   	separators      r/   _parse_listzConfigHandler._parse_list/  s\     eT"" 	L5==$$&&EEKK	**EBB5BBBBr1   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   rX   r   resultlinerG   sepvals           r/   _parse_dictzConfigHandler._parse_dictC  s     	OOE** 	. 	.D NN955MCci*>F   #&))++F399;;r1   c                 2    |                                 }|dv S )zQRepresents value as boolean.

        :param value:
        :rtype: bool
        )1trueyes)lowerr   rX   s     r/   _parse_boolzConfigHandler._parse_boolV  s     ,,,r1   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   
ValueErrorrI   )rX   exclude_directiverG   s     r/   r   z3ConfigHandler._exclude_files_parser.<locals>.parserl  sI     ' 122  --3VC[[   Lr1   r5   )r   rG   r   s    ` r/   _exclude_files_parserz#ConfigHandler._exclude_files_parser`  s#    	 	 	 	 	 r1   root_dirc                 ,   d}t          |t                    s|S |                    |          s|S |t          |          d         }d |                    d          D             }| j                            |           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                 6    g | ]}|                                 S r5   r   )r   r;   s     r/   r   z-ConfigHandler._parse_file.<locals>.<listcomp>  s     >>>dTZZ\\>>>r1   r   )	r   r    r   rn   r   rb   rc   r   
read_files)r   rX   r   include_directivespec	filepathss         r/   _parse_filezConfigHandler._parse_filew  s     $%%% 	L 122 	LS*++--.>>djjoo>>>	%%i000 H555r1   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:r}   )r   r   rc   rd   r_   r   	read_attr)r   rX   r_   r   attr_directive	attr_descs         r/   _parse_attrzConfigHandler._parse_attr  sh     !// 	LMM."55	 	41=>>>	;AAAr1   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 Nr5   )rX   ri   methodparse_methodss      r/   r^   z1ConfigHandler._get_parser_compound.<locals>.parse  s+    F' ( (Mr1   r5   )r   r   r^   s    ` r/   _get_parser_compoundz"ConfigHandler._get_parser_compound  s#    	 	 	 	 	 r1   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_parserrX   rG   _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r1   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   r5   )r   vr   s     r/   <lambda>z6ConfigHandler._parse_section_to_dict.<locals>.<lambda>  s    }}Q// r1   c                     |S r   r5   )r   r   s     r/   r   z6ConfigHandler._parse_section_to_dict.<locals>.<lambda>  s    UV r1   r   )r   r   r   r   s     ` r/   _parse_section_to_dictz$ConfigHandler._parse_section_to_dict  s7     5BW/////22?FKKKr1   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   ro   rp   r   )r   r   namer   rX   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.

        r}   z_%szparse_section%sr~   __Nz*Unsupported distribution option section: [])r   r   rL   r   r   rT   )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 	3r1   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   )rs   rt   )argskwargsfuncrx   warning_classs     r/   config_handlerz@ConfigHandler._deprecated_config_handler.<locals>.config_handler  s*    M#}---4((((r1   r   )r   r   rx   r   r   s    ``` r/   _deprecated_config_handlerz(ConfigHandler._deprecated_config_handler  sB     
t	) 	) 	) 	) 	) 	) 
	) r1   )r   r   )r   
__module____qualname____doc__r    __annotations__r{   r
   r!   AllCommandOptionsr   r]   r   propertyr   r   classmethodr   r   r   r   _Pathr   r   r   r   r   r   r^   r   r5   r1   r/   r7   r7      s        ;;
 !GT#s(^    #
 ":   6 
 
 X
$- $- $-L C C C [C&   [$ - - [-   [,65 6 6 6 64B B B B B(   [&   [ 
L 
L 
L [
L# # #3 3 34    r1   r7   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 )rZ   r`   urldescriptionclassifiers	platforms)	home_pagesummary
classifierplatformFNrF   r   re   r+   rd   r_   r   c                 l    t                                          ||||           || _        || _        d S r   )superr   r_   r   )r   rF   re   r+   rd   r_   r   r   s          r/   r   zConfigMetadataHandler.__init__  s8     	W.BDUVVV& r1   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-,	  (% **&/
 
 	
r1   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}r5   )r   r   r   r   r   r   rI   rJ   r   r  r   r_   )r   rX   r  tmpls       r/   r  z$ConfigMetadataHandler._parse_versionI  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   rT   r{   strict_moder:   curdirr   boolr   r]   r   rR   r   r   r   r   r  __classcell__r   s   @r/   rZ   rZ   	  s        N  #	 G K '+)! !*! #! #	!
 ":! d^! ! ! ! ! ! ! 
 
 X
BX X X X X X Xr1   rZ   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 )r[   re   rF   r   r+   rd   c                 v    t                                          ||||           |j        | _        i | _        d S r   )r   r   ra   r   r_   )r   rF   re   r+   rd   r   s        r/   r   zConfigOptionsHandler.__init__h  s=     	W.BDUVVV"++-r1   c                 0    |                      |d          S )Nrm   )r   )r   r   s     r/   _parse_list_semicolonz*ConfigOptionsHandler._parse_list_semicolons  s    u444r1   c                 :    |                      || j                  S )Nr  )r   r   )r   rX   s     r/   _parse_file_in_rootz(ConfigOptionsHandler._parse_file_in_rootw  s    >>>r1   rg   rX   c                     |                      |                     |                    }t          |||           d |D             S )Nc                 <    g | ]}|                     d           |S )#)r   )r   r   s     r/   r   zAConfigOptionsHandler._parse_requirements_list.<locals>.<listcomp>  s)    DDDts/C/CDDDDr1   )r  r  ry   )r   rg   rX   ri   s       r/   _parse_requirements_listz-ConfigOptionsHandler._parse_requirements_listz  sL    ++D,D,DU,K,KLL-eUFCCC EDDDDDr1   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$+&-
 
 	
r1   c                 v    | j         j        }t          j        |                     |          || j                  S r   )rd   r_   r   r1  r   r   )r   rX   r_   s      r/   r2  z$ConfigOptionsHandler._parse_cmdclass  s1    ,8t//66T]SSSr1   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_dirr5   )
r   r   parse_section_packages__findr   r   rc   r   r_   r   find_packages)r   rX   find_directivestrimmed_valuefind_kwargss        r/   r3  z$ConfigOptionsHandler._parse_packages  s     #$56//##E*** 77Mor22
 
 	%);;]!- 	 	
 	
 	
 #22k222r1   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 r5   r5   )r   kr   
valid_keyss      r/   r   zEConfigOptionsHandler.parse_section_packages__find.<locals>.<listcomp>  s*    NNN1ZAaVr1   r@  Nr   )r   r   rR   r   r   )r   r   section_datar>  r@  rE  s        @r/   r:  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 r1   c                 F    |                      || j                  }|| d<   dS )z`Parses `entry_points` configuration file section.

        :param dict section_options:
        r.  N)r   r   r   r   ri   s      r/   parse_section_entry_pointsz/ConfigOptionsHandler.parse_section_entry_points  s,    
 ,,_d>NOO%^r1   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8r1   c                 6    |                      |          | d<   dS )z`Parses `package_data` configuration file section.

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

        :param dict section_options:
        exclude_package_dataNrO  rP  s     r/   "parse_section_exclude_package_dataz7ConfigOptionsHandler.parse_section_exclude_package_data  s#    
 (,'?'?'P'P#$$$r1   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"  )rD  r   r   s     r/   r   zCConfigOptionsHandler.parse_section_extras_require.<locals>.<lambda>  s#    667M7M7M7MqQQ r1   extras_requireNr   rH  s   `  r/   parse_section_extras_requirez1ConfigOptionsHandler.parse_section_extras_require  s<    
 55QQQQ
 

 "(r1   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   rH  s      r/   parse_section_data_filesz-ConfigOptionsHandler.parse_section_data_files  s;    
 ,,_d>NOO#6vt}MM\r1   )r   r   r   rT   r   r  r   r]   r   r   r  r  r    r"  r   r   r2  r3  r:  rI  rM  rQ  rT  rX  r\  r  r  s   @r/   r[   r[   d  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r1   r[   )FF)r5   F)F)<r   r:   ro   rK   rs   collectionsr   r   r   typingr   r   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   r}   r   r&   r   distutils.distr   r    PathLiker   SingleCommandOptionsr   r!   rR   r0   r4   r  r(   rP   r)   rB   r   ry   r7   rZ   r[   r5   r1   r/   <module>rg     s1   
 
			          # # # # # #            : : : : : : : : : : : : : : : : : : : : : : : : : : : : 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    * + + +&+ :;	+ + + +\, ,# ,t , , , ,Bo o o o oGFO o o od	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r1   