a
    4ñ»j¤x  ã                8   @   s`  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZ d dlmZ d dlm Z m!Z! e
j"Z"ej#râe
j$Z"G dd„ de%ƒZ&G dd„ de'ƒZ(de)dddd�fde)dddd�fde)ddd�fde)dedd d!d"�fd#e)d$d%d&d'�fd(e)d$d)d*d'�fd+e)dd,d-d�fd.e)dd/d�fd0e)d1d2d3d4d5�fd6e)d7d8d9�fd:e)dd;d�fd<e)dd=d>d�fd6e)d?d@d9�fdAe)ddBdCd�fdDe)ddEd�fdFe)ddGdHd�fdIe)ddGdJd�fdKe)ddLdMd�fdNe)ddLdOd�fdPe)ddQd�fdRe)ddSdTd�fdUe)ddSdVd�fdWe)ddXdYd�fdZe)ddXd[d�fd\e)dd]d^d�fd_e)dd]d`d�fdae)e&j*dbdc�fdde)dedf�fdge)dhdf�fdie)djdkdl�fdme)ddnd�fdoe)ddpdqd�fdre)ddpdsd�fdte)ddudvdwdx�fd6e)ddydzd�fd{e)dd|d�fd}e)dd~dd�fd€e)dd~d�d�fd‚e)dƒdf�fd„e)dd…d�fd6e)d†d‡dˆd‰�fdŠe)dd‡d‹dŒd��fdŽe)dd�d�d�fd‘e)dd�d’d�fd“e)dd”d�fd•e)dd–d�fd—e)dd˜d�fd™e)dšd›dœ�fd�e)ddžd�fdŸe)dšd dœ�fd¡e)dd¢d�fd£e)dd¤d�fg4Z+e,d¥d¦gƒZ-d§d¨„ Z.d©dª„ Z/d²d¬d­„Z0d®d¯„ Z1G d°d±„ d±e%ƒZ2dS )³é    )Úprint_functionN)Úconfigparser)ÚScenarioOutline)ÚFileLocation)ÚJUnitReporter)ÚSummaryReporter)ÚTagExpression)ÚStreamOpener)Ú	_registry)ÚUserDataÚparse_user_define)ÚUnknown)Úselect_best_encodingÚto_textsc                   @   s:   e Zd Zg d¢Zed	dd„ƒZedd„ ƒZedd„ ƒZdS )
ÚLogLevel)ÚNOTSETÚCRITICALÚFATALÚERRORÚWARNINGÚWARNÚINFOÚDEBUGNc                 C   s   t t|  ¡ |ƒS )a  
        Convert levelname into a numeric log level.

        :param levelname: Logging levelname (as string)
        :param unknown_level: Used if levelname is unknown (optional).
        :return: Numeric log-level or unknown_level, if levelname is unknown.
        )ÚgetattrÚloggingÚupper)Ú	levelnameZunknown_level© r   ú:E:\soccer\ml_env\Lib\site-packages\behave/configuration.pyÚparse(   s    	zLogLevel.parsec                 C   s>   |   |t¡}|tu r:d|d | jdd … ¡f }t |¡‚|S )Nz%s is unknown, use: %sú, é   )r   r   ÚjoinÚnamesÚargparseZArgumentTypeError)Úclsr   ÚlevelÚmessager   r   r   Ú
parse_type3   s    ÿ
zLogLevel.parse_typec                 C   s
   t  | ¡S ©N)r   ÚgetLevelName)r&   r   r   r   Ú	to_string<   s    zLogLevel.to_string)N)	Ú__name__Ú
__module__Ú__qualname__r#   Ústaticmethodr   Úclassmethodr(   r+   r   r   r   r   r   "   s   

r   c                   @   s   e Zd ZdS )ÚConfigErrorN)r,   r-   r.   r   r   r   r   r1   A   s   r1   )z-cz
--no-colorÚstore_falseÚcolorz&Disable the use of ANSI color escapes.)ÚactionÚdestÚhelp)z--colorÚ
store_truez˜Use ANSI color escapes. This is the default
                  behaviour. This switch is used to override a
                  configuration file setting.)z-dz	--dry-runz/Invokes formatters without executing the steps.)r4   r6   )z-Dz--defineÚuserdata_definesÚappendz
NAME=VALUEzŠDefine user-specific data for the config.userdata dictionary.
                  Example: -D foo=bar to store it in config.userdata["foo"].)r5   Útyper4   Úmetavarr6   )z-ez	--excludeZPATTERNÚ
exclude_rezNDon't run feature files matching regular expression
                  PATTERN.)r;   r5   r6   )z-iz	--includeÚ
include_rez;Only run feature files matching regular expression PATTERN.)z
--no-junitÚjunitz&Don't output JUnit-compatible reports.)z--junita  Output JUnit-compatible reports.
                  When junit is enabled, all stdout and stderr
                  will be redirected and dumped to the junit report,
                  regardless of the "--capture" and "--no-capture" options.
                  )z--junit-directoryÚPATHZjunit_directoryZreportsz*Directory in which to store JUnit reports.)r;   r5   Údefaultr6   r   Údefault_formatz,Specify default formatter (default: pretty).)r5   r6   )z-fz--formatz¨Specify a formatter. If none is specified the default
                  formatter is used. Pass "--format help" to get a
                  list of available formatters.)z--steps-catalogÚsteps_catalogz}Show a catalog of all available step definitions.
                  SAME AS: --format=steps.catalog --dry-run --no-summary -qÚ"scenario_outline_annotation_schemazvSpecify name annotation schema for scenario outline
                  (default="{name} -- @{row.id} {examples.name}").)z-kz--no-skippedÚshow_skippedz(Don't print skipped steps (due to tags).)z--show-skippedz•Print skipped steps.
                  This is the default behaviour. This switch is used to
                  override a configuration file setting.)z--no-snippetsÚshow_snippetsz-Don't print snippets for unimplemented steps.)z
--snippetsz¨Print snippets for unimplemented steps.
                  This is the default behaviour. This switch is used to
                  override a configuration file setting.)z-mz--no-multilineZshow_multilinezGDon't print multiline strings and tables under
                  steps.)z--multilinez°Print multiline strings and tables under steps.
                  This is the default behaviour. This switch is used to
                  override a configuration file setting.)z-nz--namezÎOnly execute the feature elements which match part
                  of the given name. If this option is given more
                  than once, it will match against all the given
                  names.)z--no-captureÚstdout_capturezWDon't capture stdout (any stdout output will be
                  printed immediately.))z	--capturezÜCapture stdout (any stdout output will be
                  printed if there is a failure.)
                  This is the default behaviour. This switch is used to
                  override a configuration file setting.)z--no-capture-stderrÚstderr_capturezWDon't capture stderr (any stderr output will be
                  printed immediately.))z--capture-stderrzÜCapture stderr (any stderr output will be
                  printed if there is a failure.)
                  This is the default behaviour. This switch is used to
                  override a configuration file setting.)z--no-logcaptureÚlog_capturezSDon't capture logging. Logging configuration will
                  be left intact.)z--logcapturez÷Capture logging. All logging during a step will be captured
                  and displayed in the event of a failure.
                  This is the default behaviour. This switch is used to
                  override a configuration file setting.)z--logging-levelzdSpecify a level to capture logging at. The default
                  is INFO - capturing everything.)r:   r6   )z--logging-formatzÁSpecify custom format to print statements. Uses the
                  same format as used by standard logging handlers. The
                  default is "%%(levelname)s:%%(name)s:%%(message)s".)r6   )z--logging-datefmtz¥Specify custom date/time format to print
                  statements.
                  Uses the same format as used by standard logging
                  handlers.)z--logging-filteraI  Specify which statements to filter in/out. By default,
                  everything is captured. If the output is too verbose, use
                  this option to filter out needless output.
                  Example: --logging-filter=foo will capture statements issued
                  ONLY to foo or foo.what.ever.sub but not foobar or other
                  logger. Specify multiple loggers with comma:
                  filter=foo,bar,baz.
                  If any logger name is prefixed with a minus, eg filter=-foo,
                  it will be excluded rather than included.aÀ  Specify which statements to filter in/out. By default,
                         everything is captured. If the output is too verbose,
                         use this option to filter out needless output.
                         Example: ``logging_filter = foo`` will capture
                         statements issued ONLY to "foo" or "foo.what.ever.sub"
                         but not "foobar" or other logger. Specify multiple
                         loggers with comma: ``logging_filter = foo,bar,baz``.
                         If any logger name is prefixed with a minus, eg
                         ``logging_filter = -foo``, it will be excluded rather
                         than included.)r6   Úconfig_help)z--logging-clear-handlersz!Clear all other logging handlers.)z--no-summaryÚsummaryz0Don't display the summary at the end of the run.)z	--summaryz*Display the summary at the end of the run.)z-oz	--outfileÚoutfilesÚFILEz*Write to specified file instead of stdout.)r4   r5   r;   r6   Úpathsz;Specify default feature paths, used when none are provided.)z-qz--quietz$Alias for --no-snippets --no-source.)z-sz--no-sourceÚshow_sourcezVDon't print the file and line of the step definition with the
                  steps.)z--show-sourcezÑPrint the file and line of the step
                  definition with the steps. This is the default
                  behaviour. This switch is used to override a
                  configuration file setting.)z--stagezÓDefines the current test stage.
                  The test stage name is used as name prefix for the environment
                  file and the steps directory (instead of default path names).
                  )z--stopz(Stop running tests at the first failure.Údefault_tagsZTAG_EXPRESSIONz]Define default tags when non are provided.
                  See --tags for more information.)r5   r;   r6   )z-tz--tagsz’Only execute features or scenarios with tags
                  matching TAG_EXPRESSION. Pass "--tags-help" for
                  more information.zÁOnly execute certain features or scenarios based
                         on the tag expression given. See below for how to code
                         tag expressions in configuration files.)r4   r;   r6   rI   )z-Tz--no-timingsÚshow_timingsz)Don't print the time taken for each step.)z--show-timingszßPrint the time taken, in seconds, of each step after the
                  step has completed. This is the default behaviour. This
                  switch is used to override a configuration file
                  setting.)ú-vú	--verbosez#Show the files and features loaded.)z-wz--wipz¹Only run scenarios tagged with "wip". Additionally: use the
                  "plain" formatter, do not capture stdout or logging output
                  and stop at the first failure.)z-xz--expandz)Expand scenario outline tables in output.)z--langÚLANGz/Use keywords for a language other than English.)r;   r6   )z--lang-listz(List the languages available for --lang.)z--lang-helpz0List the translations accepted for one language.)z--tags-helpzShow help for tag expressions.)z	--versionzShow version.Úlogging_formatÚlogging_datefmtc                    sH  t ƒ }t|_| | ¡ tj | ¡‰ i }tD �]
\}}d|v rF|d }nF|D ]@}| d¡rn|dd …  	dd¡}qJt
|ƒdks~J ‚|dd … }qJ|d ¡ v ršq*| d|¡s¨q*| d	d
¡}|d
krÚ|tv }|jd||d�||< q*|dv rô| d|¡||< q*|dk�r*|dk�r
q*dd„ | d|¡ ¡ D ƒ||< q*td| ƒ‚q*d|v �rÊ|d }	t
|	ƒ}
| dg ¡}t
|ƒ}||
k �r |	|d … D ]}d| }| |¡ �q|||d< n*t
|ƒ|
k�rÊtd| ƒ |d |
… |d< dD ].}||v �rÎ|| }‡ fdd„|D ƒ||< �qÎdddœ}| ¡ D ]2\}}i ||< | |¡�r||  | |¡¡ �q|S )Nr5   z--é   ú-Ú_r!   z%tags_help lang_list lang_help versionZbehaver4   Ústore)Úraw)r7   r2   r9   r8   c                 S   s   g | ]}|  ¡ ‘qS r   )Ústrip)Ú.0Úsr   r   r   Ú
<listcomp>�  ó    z&read_configuration.<locals>.<listcomp>zaction "%s" not implementedÚformatrK   z	%s.outputz.CONFIG-ERROR: Too many outfiles (%d) provided.)rM   rK   c                    s"   g | ]}t j t j ˆ |¡¡‘qS r   )ÚosÚpathÚnormpathr"   )r\   Úp©Z
config_dirr   r   r^   ª  r_   Úmore_formattersÚuserdata)zbehave.formatterszbehave.userdata)ÚConfigParserÚstrÚoptionxformÚreadra   rb   ÚdirnameÚoptionsÚ
startswithÚreplaceÚlenÚsplitÚ
has_optionÚgetÚraw_value_optionsÚ
getbooleanÚ
splitlinesÚ
ValueErrorr9   ÚprintÚitemsÚhas_sectionÚupdate)rb   ÚconfigÚresultÚfixedÚkeywordsr5   Úoptr4   Zuse_raw_valueÚ
formattersZformatter_sizerK   Zoutfiles_sizeZformatter_nameÚoutfileZ
paths_namerM   Zspecial_config_section_mapÚsection_nameZ	data_namer   re   r   Úread_configurationp  sr    




ÿ


ÿ
ÿ
þr„   c                  c   s|   dt j d¡g} tjdv r<dt jv r<|  t j t jd ¡¡ t| ƒD ]2}tdƒD ]$}t j ||¡}t j 	|¡rP|V  qPqDd S )Nz./ú~)ÚcygwinÚwin32ÚAPPDATA)z
behave.iniz	.behavercz	setup.cfgztox.ini)
ra   rb   Ú
expanduserÚsysÚplatformÚenvironr9   r"   ÚreversedÚisfile)rM   rb   Úfilenamer   r   r   Úconfig_filenamesº  s    ÿr�   Fc                 C   s^   t ƒ D ]"}|rtd| ƒ |  t|ƒ¡ q|rZtdƒ t | ¡D ]\}}td||f ƒ q@d S )Nz!Loading config defaults from "%s"zUsing defaults:z%15s %s)r�   rx   r{   r„   ÚsixÚ	iteritems)ÚdefaultsÚverboser�   ÚkÚvr   r   r   Úload_configurationÇ  s    
r—   c                  C   sh   d} d}d}t j| |d�}tD ]4\}}|s,qd|v rBt|ƒ}|d= |j|i |¤Ž q|jdddd	� |S )
Nz,%(prog)s [options] [ [DIR|FILE|FILE:LINE] ]+z.    Run a number of feature tests with behave.z™
    EXAMPLES:
    behave features/
    behave features/one.feature features/two.feature
    behave features/one.feature:10
    behave @features.txt
    )ÚusageÚdescriptionrI   rM   Ú*z5Feature directory, file or file location (FILE:LINE).)Únargsr6   )r$   ÚArgumentParserrm   ÚdictÚadd_argument)r˜   r™   ÚmoreÚparserr~   r   r   r   r   Úsetup_parserÓ  s    ÿr¡   c                   @   s²   e Zd ZdZeejdkdddddddddejddddi ddd	d
�Z	e
dƒZd"dd„Zd#dd„Zdd„ Zdd„ Zedd„ ƒZdd„ Zd$dd„Zdd„ Zd%dd„Zdd„ Zd d!„ ZdS )&ÚConfigurationz3Configuration object for behave and behave runners.r‡   TFz"%(levelname)s:%(name)s:%(message)sNÚprettyÚ z#{name} -- @{row.id} {examples.name})r3   rE   rD   Údry_runrN   rP   rF   rG   rH   rT   Úlogging_levelrB   rJ   r>   Ústagerg   rA   rO   rC   r8   c                 K   sp  |du rt jdd… }nrt|tjƒrttƒ p,d}tjrLt|tjƒrL| |¡}ntj	rht|tj
ƒrh| |¡}t |¡}nt|ttfƒrŠt|ƒ}|du r¢d|v p d|v }d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _d| _| j ¡ }t  |¡D ]\}}|||< �q|| _g | _!g | _"d| _#g | _$d| _%d| _&d| _'d| _(d| _)d| _*d| _+|�rtt,| j|d� t-ƒ }	|	j.f i | j¤Ž |	 /|¡}
t  |
j0¡D ]2\}}| 1d	¡�rÆ|| j2v�rÆ�q¢t3| ||ƒ �q¢d
d„ | j4D ƒ| _4|  5|
j6¡ | j�r"d| _7dg| _8d| _9d| _:d| _;d| _<| j�rZd| _7dg| j ¡  | _=d| _>d| _?d| _@d| _AtB| j=�pl| j ¡ ƒ| _=| j<�r†d| _Cd| _D| j&�rœtE F| j&¡| _&| j%�r²tE F| j%¡| _%| j�rÈ|  G| j¡| _#| jHdu �rätIjJ Kdd¡| _H|  L| jH¡ |  M¡  |  N¡  | j�r*d| _Ad| _Od| _@| j" PtQ| ƒ¡ | j:�rB| j" PtR| ƒ¡ |  S¡  |  T¡ }|�rl|	 Udd V|¡ ¡ dS )aD  
        Constructs a behave configuration object.
          * loads the configuration defaults (if needed).
          * process the command-line args
          * store the configuration results

        :param command_args: Provide command args (as sys.argv).
            If command_args is None, sys.argv[1:] is used.
        :type command_args: list<str>, str
        :param load_config: Indicate if configfile should be loaded (=true)
        :param verbose: Indicate if diagnostic output is enabled
        :param kwargs:  Used to hand-over/overwrite default values.
        Nr!   zutf-8rQ   rR   Ústepsúenvironment.py)r”   rX   c                 S   s   g | ]}t j |¡‘qS r   )ra   rb   rc   )r\   rb   r   r   r   r^   O  r_   z*Configuration.__init__.<locals>.<listcomp>zsteps.catalogTFÚplainÚwipZBEHAVE_STAGEzformat=%s is unknownr    )WrŠ   ÚargvÚ
isinstancer‘   Ústring_typesr   ÚPY2Ú	text_typeÚencodeÚPY3Úbinary_typeÚdecodeÚshlexrq   ÚlistÚtupler   ÚversionZ	tags_helpZ	lang_listZ	lang_helprO   r>   rT   rU   ÚnameÚscoperB   rg   r«   r“   Úcopyr’   r�   Ú	reportersZname_reÚoutputsr=   r<   rC   Ú	steps_dirÚenvironment_filer8   rf   r—   r¡   Úset_defaultsÚ
parse_argsÚ__dict__rn   Úcmdline_only_optionsÚsetattrrM   Úsetup_outputsrK   rA   r`   r¥   rJ   rD   ÚquietÚtagsr3   ÚstoprH   rF   r   rN   rE   ÚreÚcompileÚbuild_name_rer§   ra   rŒ   rs   Úsetup_stageÚsetup_modelÚsetup_userdatarG   r9   r   r   Úsetup_formatsÚcollect_unknown_formatsÚerrorr"   )ÚselfÚcommand_argsZload_configr”   ÚkwargsÚencodingr“   r¹   Úvaluer    ÚargsÚkeyÚunknown_formatsr   r   r   Ú__init__  s¸    



zConfiguration.__init__c                 C   sp   | j r|rJ dƒ‚d S |s0| j  ttjd�¡ n<|D ]6}|rV|dkrV| j  t|ƒ¡ q4| j  ttjd�¡ q4d S )Nz	ONLY-ONCE)ÚstreamrW   )r½   r9   r	   rŠ   Ústdout)rÒ   Zargs_outfilesr‚   r   r   r   rÅ   �  s    zConfiguration.setup_outputsc                 C   s*   | j r&| j  ¡ D ]\}}t ||¡ qdS )z/Register more, user-defined formatters by name.N)rf   ry   Ú_format_registryZregister_as)rÒ   r¹   Zscoped_class_namer   r   r   rÏ   ž  s    zConfiguration.setup_formatsc                 C   s8   g }| j r4| j D ]"}|dkst |¡r(q| |¡ q|S )Nr6   )r`   rÝ   Zis_formatter_validr9   )rÒ   rÙ   Úformat_namer   r   r   rÐ   ¤  s    
ÿz%Configuration.collect_unknown_formatsc                 C   s"   t | ƒ} d | ¡}tj|tjd�S )a  
        Build regular expression for scenario selection by name
        by using a list of name parts or name regular expressions.

        :param names: List of name parts or regular expressions (as text).
        :return: Compiled regular expression to use.
        ú|)Úflags)r   r"   rÉ   rÊ   ÚUNICODE)r#   Úpatternr   r   r   rË   ®  s    
zConfiguration.build_name_rec                 C   sL   t |tƒrt |¡}| jr.| j |¡d u r.dS | jrH| j |¡d urHdS dS )NTF)r­   r   r‘   r°   r=   Úsearchr<   )rÒ   r�   r   r   r   Úexclude¾  s    

zConfiguration.excludec                 K   sl   |du r| j }|r(ddlm} ||ƒ n2| d| j¡}| d| j¡}tjf ||dœ|¤Ž t ¡  	|¡ dS )aö  
        Support simple setup of logging subsystem.
        Ensures that the logging level is set.
        But note that the logging setup can only occur once.

        SETUP MODES:
          * :func:`logging.config.fileConfig()`, if ``configfile`` is provided.
          * :func:`logging.basicConfig()`, otherwise.

        .. code-block: python
            # -- FILE: features/environment.py
            def before_all(context):
                context.config.setup_logging()

        :param level:       Logging level of root logger.
                            If None, use :attr:`logging_level` value.
        :param configfile:  Configuration filename for fileConfig() setup.
        :param kwargs:      Passed to :func:`logging.basicConfig()`
        Nr   )Ú
fileConfigr`   Údatefmt)r`   ræ   )
r¦   Úlogging.configrå   ÚpoprT   rU   r   ÚbasicConfigÚ	getLoggerÚsetLevel)rÒ   r&   Z
configfilerÔ   rå   Zformat_ræ   r   r   r   Úsetup_loggingÈ  s    
zConfiguration.setup_loggingc                 C   s    | j rt | j ¡}| ¡ t_d S r)   )rC   r‘   r°   r[   r   Zannotation_schema)rÒ   Zname_schemar   r   r   rÍ   ë  s    zConfiguration.setup_modelc                 C   s4   d}d}|r$|d }|| }|| }|| _ || _dS )a†  Setup the test stage that selects a different set of
        steps and environment implementations.

        :param stage:   Name of current test stage (as string or None).

        EXAMPLE::

            # -- SETUP DEFAULT TEST STAGE (unnamed):
            config = Configuration()
            config.setup_stage()
            assert config.steps_dir == "steps"
            assert config.environment_file == "environment.py"

            # -- SETUP PRODUCT TEST STAGE:
            config.setup_stage("product")
            assert config.steps_dir == "product_steps"
            assert config.environment_file == "product_environment.py"
        r¨   r©   rX   N)r¾   r¿   )rÒ   r§   r¾   r¿   Úprefixr   r   r   rÌ   ð  s    zConfiguration.setup_stagec                 C   s0   t | jtƒst| jƒ| _| jr,| j | j¡ d S r)   )r­   rg   r   r8   r{   )rÒ   r   r   r   rÎ     s    zConfiguration.setup_userdatac                 C   s$   | j  |¡ | jr | j  | j¡ dS )z†Update userdata with data and reapply userdata defines (cmdline).
        :param data:  Provides (partial) userdata (as dict)
        N)rg   r{   r8   )rÒ   Údatar   r   r   Úupdate_userdata  s    zConfiguration.update_userdata)NTN)N)NN)N)r,   r-   r.   Ú__doc__r�   rŠ   r‹   r   r   r“   ÚsetrÃ   rÚ   rÅ   rÏ   rÐ   r/   rË   rä   rì   rÍ   rÌ   rÎ   rï   r   r   r   r   r¢   í  sH   ì
 




#
r¢   )F)3Ú
__future__r   r$   r   ra   rÉ   rŠ   rµ   r‘   Z	six.movesr   Zbehave.modelr   Zbehave.model_corer   Zbehave.reporter.junitr   Zbehave.reporter.summaryr   Zbehave.tag_expressionr   Zbehave.formatter.baser	   Zbehave.formatterr
   rÝ   Zbehave.userdatar   r   Zbehave._typesr   Zbehave.textutilr   r   rh   r¯   ÚSafeConfigParserÚobjectr   Ú	Exceptionr1   r�   r(   rm   Ú	frozensetrt   r„   r�   r—   r¡   r¢   r   r   r   r   Ú<module>   sH  ÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ	÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ	ÿÿüÿ	ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿ€ € ä  #þJ
