o
    Yih                     @   s  d Z ddlmZ ddlZddlZddlZddlZddlmZm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
 Zdd Zdd Zejddddddddddddfddddddddddddddddddfdd did!dddidddddfd"i dd#diddd#didfd$dd#didi dd#didfd%dddd!d#diidd#didfd&dd#didd!didddfd'd ddd(dd)idd*d+d,d-d.d/ddd*d0dd,d1d.d/fd2d3d4d5id6d7d8g d9id:d;d7d5g d9d<d:d;fd=d d!diid i id d!diifd>d i id d!diid d!diifd?d@dAdBidCdDdEdFdGdHdDdEdFdGdCfgdIedJedKedLefdMdNZejdOdPd did did didQdRfdSd d!diid d!diid d!diidQdRfdTd did dUid dUid:dVfdWd d!diid d5id d5id:dXfdYd d5id d!diid d!diid:dZfd[d did!d\idd\ddQdRfgd]d^ Zejd_d`d@dadbdDdadcdDdadbfddd@dadcdDdadbdDdadcfdedfdgdAdRiiidhdidjdkiiidfdgdAdkiiifdldmddRdngidoddpdqgidmddpdqgifdrdmddRdngidoddpdsgidmddpdsgifdtdudvdigidwdxdiddydzgidudxdiddydzgifd{duddRd|dvdigidwdxdigidudxdigifd}d~diddddddfdd@dddDddddDdddfdi ddddddfdddii i fddd7idddiidddiifddddiiddiddifddddRddgiidddd5ddddgiidddd5ddddgiifgdIededKedefddZG dd dejZG dd dejZe  G dd dejZe  G dd dejZG dd dZ G dd deZ!G dd dejZ"dd Z#dd Z$dd Z%dd Z&dd Z'dd Z(dd Z)dd Z*ddÄ Z+ddń Z,ddǄ Z-ddɄ Z.dd˄ Z/dd̈́ Z0ddτ Z1ddф Z2ddӄ Z3ddՄ Z4ddׄ Z5ddل Z6ddۄ Z7dd݄ Z8dd߄ Z9dd Z:dd Z;dd Z<dd Z=dd Z>dd Z?dS )z"Tests tools in the _common module.    )EnumN)ListOptional   )_common)types)errorsc                  C   sr   t ddd } tjdd}|   |   W d    n1 s w   Y  t|dks-J |d jtjks7J d S )NWarning!c                   S      d S N r   r   r   _/home/kim/smarthome/.venv/lib/python3.10/site-packages/google/genai/tests/common/test_common.pyfunc$      ztest_warn_once.<locals>.funcTrecord   r   )r   experimental_warningwarningscatch_warningslencategoryr   ZExperimentalWarning)r   wr   r   r   test_warn_once#   s   
r   c                  C   sh   t ddd } tjdd}t jd }|   W d    n1 s$w   Y  |d j|ks2J d S )Nr	   c                   S   r
   r   r   r   r   r   r   r   0   r   z$test_warn_at_call_line.<locals>.funcTr   r   r   )r   r   r   r   inspectcurrentframef_linenolineno)r   Zcaptured_warningsZ	call_liner   r   r   test_warn_at_call_line/   s   
r   c                   C   s  t ttttjf  sJ t tjtjttjf  sJ t tttt	f  r+J t ttt	tjf  r9J t tt rBJ t tttjf rNJ t tjtjtt	f  r]J t tjtjt	tjf  rmJ t tjt rwJ t tjttjf rJ d S r   )
r   Z_is_struct_typelistdictstrtypingAnyr   Dictintr   r   r   r   test_is_struct_type;   s     r&   z5test_id, initial_target, update_dict, expected_targetZsimple_updater      ab   )r*   c)r)   r*   r,   Znested_update
      )xy   (   )r0   z)r/   r0   r3   Zadd_new_nested_dictr)   r*   Zempty_targetr/   Zempty_updateZoverwrite_non_dict_with_dictZoverwrite_dict_with_non_dictZdeeper_nesting)r,   d)r*   e   )r4   f   )r*   g   )r)   h)r,   r4   r7   )r*   r5   r9   Zdifferent_value_typesZ
string_val
nested_intd   )key1key2{   nested_list)r   r'   r   T)r>   r?   Zkey3)r<   rA   Zupdate_with_empty_nested_dictZtarget_with_empty_nested_dictZkey_case_alignment_checkZJohnemail_addresszjohn@example.com)
first_namecontact_infoZJanezjane@example.com123)rB   Zphone_number)	firstNamerD   test_idinitial_targetupdate_dictexpected_targetc                 C   s   t || ||ksJ d S r   )r   recursive_dict_update)rG   rH   rI   rJ   r   r   r   test_recursive_dict_updateI   s   TrL   z`test_id, initial_target, update_dict, expected_target, expect_warning, expected_log_message_partZtype_match_intF Ztype_match_dictZtype_mismatch_int_to_strZhelloz^Type mismatch for key 'a'. Existing type: <class 'int'>, new type: <class 'str'>. Overwriting.Ztype_mismatch_dict_to_intz_Type mismatch for key 'a'. Existing type: <class 'dict'>, new type: <class 'int'>. Overwriting.Ztype_mismatch_int_to_dictz_Type mismatch for key 'a'. Existing type: <class 'int'>, new type: <class 'dict'>. Overwriting.Zadd_new_keynewc                 C   s   t || ||ksJ |r-t|jdksJ |jd jdks!J ||jd jv s+J d S |jD ]}|jdkrH||jv rHtd|  d|j  q0d S )Nr   r   WARNINGzUnexpected warning logged for z: )r   rK   r   records	levelnamemessagepytestZfail)rG   rH   rI   rJ   Zexpect_warningZexpected_log_message_partcaplogr   r   r   r   (test_recursive_dict_update_type_warnings   s   /
rU   z8test_id, target_dict, update_dict, expected_aligned_dictZsimple_snake_to_camelZDoe)rC   	last_name)rF   ZlastNameZsimple_camel_to_snakeZnested_dict_alignmentZ	user_infoZcontact_detailsZuserInfoZcontactDetailsZemailAddressztest@example.comZlist_of_dicts_alignmentZ
users_list)user_idZ	user_nameZ	usersListZAlice)ZuserIdZuserNameZ,list_of_dicts_alignment_mixed_case_in_update)rW   ZUserNameZ-list_of_dicts_different_lengths_update_longerZ
items_dataitem_idZ	itemsDataZitemIdZExtra)rX   itemNameZ-list_of_dicts_different_lengths_target_longer)rX   	item_nameZ&no_matching_keys_preserves_update_caseZkey_one)ZKEY_TWOZkeyThreeZmixed_match_and_no_match)rC   	age_years   ZEngineer)rF   Z	AGE_YEARSoccupation_title)rC   r[   r]   Zempty_target_dict	new_valueZanotherValue)Znew_keyZ
anotherKeyZempty_update_dictZexisting_keyvalueZ(target_has_non_dict_value_for_nested_keyconfig_settingsZconfigSettingsZ	themeNameZdarkZ(update_has_non_dict_value_for_nested_keyZ
theme_nameZlightZdark_theme_stringZdeeply_nested_with_listsZ	level_oneZ
list_items)rZ   Z
item_valueZlevelOneZ	listItemsZTest)rY   Z	itemValueZTest2   target_dictexpected_aligned_dictc                 C   s&   t ||}||ksJ d|  d S )NzTest failed for: )r   Zalign_key_case)rG   rb   rI   rc   Zaligned_dictr   r   r   test_align_key_case   s   \rd   c                   @   s:   e Zd ZU eed< eed< dZeed< dZe	e ed< dS )SimpleModelnamer_   T	is_activeN
none_field)
__name__
__module____qualname__r!   __annotations__r%   rg   boolrh   r   r   r   r   r   re   =  s
   
 re   c                   @   s&   e Zd ZU eed< dZed  ed< dS )ChainidNchild)ri   rj   rk   r%   rl   rp   r   r   r   r   r   rn   D  s   
 rn   c                   @   s.   e Zd ZU eed< ejedZe	d  ed< dS )Treero   )default_factorychildrenN)
ri   rj   rk   r%   rl   pydanticFieldr   rs   r   r   r   r   r   rq   L  s   
 rq   c                   @   s,   e Zd ZU eed< ejdddZeed< dS )ReprFalseModelvisiblesecretF)reprhiddenN)ri   rj   rk   r!   rl   rt   ru   rz   r   r   r   r   rv   T  s   
 rv   c                   @   s   e Zd Zdd ZdS )NonPydanticc                 C   s   dS )NzNonPydantic(
  attr='value'
)r   )selfr   r   r   __repr__[  s   zNonPydantic.__repr__N)ri   rj   rk   r}   r   r   r   r   r{   Y  s    r{   c                   @   s   e Zd ZdZdZdS )MyEnumr   r'   N)ri   rj   rk   ZONETWOr   r   r   r   r~   _  s    r~   c                   @   s   e Zd ZdS )
EmptyModelN)ri   rj   rk   r   r   r   r   r   d  s    r   c                  C   s.   t ddd} td }t| |ksJ d S )Nz	Test Namer@   rf   r_   zZ
    SimpleModel(
      is_active=True,
      name='Test Name',
      value=123
    )
    )re   textwrapdedentstripry   objexpectedr   r   r   +test_repr_simple_model_defaults_and_no_noneh  s
   r   c                  C   s   t  } d}t| |ksJ d S )NzEmptyModel())r   ry   r   r   r   r   test_repr_empty_modelt  s   r   c                  C   s4   t dt ddd} td }t| |ksJ d S )Nr   r'   ro   )ro   rp   zJ
    Chain(
      child=Chain(
        id=2
      ),
      id=1
    )
    )rn   r   r   r   ry   r   r   r   r   test_repr_nested_modelz  s
   r   c                  C   sB   t dd} t dd}|| _| |_td }t| |ksJ d S )Nr   r   r'   zv
    Chain(
      child=Chain(
        child=<... Circular reference ...>,
        id=2
      ),
      id=1
    )
    )rn   rp   r   r   r   ry   )Zobj1obj2r   r   r   r   test_repr_circular_model  s   


r   c                  C   s6   ddg} |  |  td }t| |ksJ d S )Nr   r'   zG
    [
      1,
      2,
      <... Circular reference ...>,
    ]
    )appendr   r   r   r   _pretty_repr)Zmy_listr   r   r   r   test_repr_circular_list  s   
r   c                  C   s4   ddi} | | d< t d }t| |ksJ d S )Nr)   r   r|   zJ
    {
      'a': 1,
      'self': <... Circular reference ...>
    }
    r   r   r   r   r   )Zmy_dictr   r   r   r   test_repr_circular_dict  s   r   c                  C   s   t td} dd tdD }ttd}ttd}dtj| ddv s&J dtj|ddv s1J dtj|ddv s<J dtj|ddv sGJ d S )Nr-   c                 S   s   i | ]}||qS r   r   ).0ir   r   r   
<dictcomp>  s    z'test_repr_max_items.<locals>.<dictcomp>z<... 5 more items ...>r6   )Z	max_itemsz<dict len=10>)r   rangesettupler   r   )lstdctstZtplr   r   r   test_repr_max_items  s   r   c                  C   s<   d} t tj| dddksJ t| tj| ddksJ d S )Nsd   aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZ   )max_len]   ra   )r   r   r   ry   )Zb_datar   r   r   test_repr_max_len_bytes  s   r   c                  C   s0   ddddddiii} dt j| ddv sJ d S )Nr)   r*   r(   z {<... 2 items at Max depth ...>}r   depthr   r   nestedr   r   r   test_repr_max_depth_dict  s   r   c                  C   s(   g dggg} dt j| ddv sJ d S )N)r4   r5   r5   pz [<... 4 items at Max depth ...>]r   r   r   r   r   r   r   test_repr_max_depth_list  s   r   c                  C   s@   h dddddg dd} t d }t| |ksJ d S )	N>   r   r'   r   )r+   r6   r8   r'   r   )r*   r)   )r:      	   )r   r   r    r   z
    {
      'dict': {
        'a': 1,
        'b': 2
      },
      'list': [
        7,
        8,
        9,
      ],
      'set': {
        1,
        2,
        3,
      },
      'tuple': (
        4,
        5,
        6,
      )
    }
    r   r   r   r   r   test_repr_collections  s   r   c                  C   s0   dddd} t d }t| |ksJ d S )Nr   )r   )r   r'   )Ztuple0Ztuple1Ztuple2z{
    {
      'tuple0': (),
      'tuple1': (
        1,
      ),
      'tuple2': (
        1,
        2,
      )
    }
    r   r   r   r   r   test_tuple_collections  s   r   c                   C   sr   t g dks	J t i dksJ t t dksJ t t dks&J t dt itd ks7J d S )Nz[]z{}zset()z()Z	empty_setz8
        {
          'empty_set': set()
        }
      )r   r   r   r   r   r   r   r   r   r   r   test_repr_empty_collections  s   r   c                  C   sR   d} d}t | |ksJ d}d}t ||ksJ d}d}t ||ks'J d S )Nzline onez
'line one'z!line one
line two with """ insidez*"""line one
line two with \"\"\" inside"""zA string with """ insidez'A string with """ inside'r   )s1Zexp1s2Zexp2Zs3Zexp3r   r   r   test_repr_strings  s   r   c                  C   sJ   t ddd} t| }d|v sJ d|vsJ td }||ks#J d S )Nshowhide)rw   rz   zvisible='show'rz   z4
    ReprFalseModel(
      visible='show'
    )
    )rv   ry   r   r   r   r   resultr   r   r   r   test_repr_repr_false+  s   r   c                  C   s@   t ddd d} t| }d|vsJ td }||ksJ d S )Nz	Only Namer   )rf   r_   rh   rh   zX
    SimpleModel(
      is_active=True,
      name='Only Name',
      value=0
    )
    )re   ry   r   r   r   r   r   r   r   test_repr_none_fields8  s   r   c                  C   s:   t  } tj}| |d}td }t||ksJ d S )N)npenzh
    {
      'en': <MyEnum.TWO: 2>,
      'np': NonPydantic(
          attr='value'
        )
    }
    )r{   r~   r   r   r   r   r   r   )r   r   r   r   r   r   r   test_repr_other_typesF  s   
r   c                  C   s4   t ddd} td }tj| dd|ksJ d S )NzIndent Testr   r   z`
    SimpleModel(
        is_active=True,
        name='Indent Test',
        value=1
    )
    r+   )Zindent_delta)re   r   r   r   r   r   r   r   r   r   test_repr_indent_deltaU  s
   r   c                  C   sz   t jg t jt jt jddgddt jjddgdt jdd	t jt j	j
d	d
gdddd} td }t| |ks;J d S )NaA  There isn't a single "best" LLM, as the ideal choice highly depends on your specific needs, use case, budget, and priorities. The field is evolving incredibly fast, with new models and improvements being released constantly.

However, we can talk about the **leading contenders** and what they are generally known for:...)textmodel)partsZroler   )contentZfinish_reasonindexz%models/gemini-2.5-flash-preview-05-20i>  r:   )ZmodalityZtoken_counti\  i  )Zcandidates_token_countZprompt_token_countZprompt_tokens_detailsZthoughts_token_countZtotal_token_count)Z"automatic_function_calling_history
candidatesZmodel_versionZusage_metadataa  
      GenerateContentResponse(
        automatic_function_calling_history=[],
        candidates=[
          Candidate(
            content=Content(
              parts=[
                Part(
                  text="""There isn't a single "best" LLM, as the ideal choice highly depends on your specific needs, use case, budget, and priorities. The field is evolving incredibly fast, with new models and improvements being released constantly.

      However, we can talk about the **leading contenders** and what they are generally known for:..."""
                ),
              ],
              role='model'
            ),
            finish_reason=<FinishReason.STOP: 'STOP'>,
            index=0
          ),
        ],
        model_version='models/gemini-2.5-flash-preview-05-20',
        usage_metadata=GenerateContentResponseUsageMetadata(
          candidates_token_count=1086,
          prompt_token_count=7,
          prompt_tokens_details=[
            ModalityTokenCount(
              modality=<MediaModality.TEXT: 'TEXT'>,
              token_count=7
            ),
          ],
          thoughts_token_count=860,
          total_token_count=1953
        )
      )
  )r   ZGenerateContentResponse	CandidateZContentZPartZFinishReasonSTOPZ$GenerateContentResponseUsageMetadataZModalityTokenCountZMediaModalityZTEXTr   r   r   ry   r   r   r   r   test_repr_complex_objecta  s>   
!!"r   c                  C   s   dddddigiiddddddigiidddddd	igiiddgi} d
di}t | | dddddigiddiddddigiddidddd	igiddigi}| |ksZJ dS )z>Test move_value_by_path function with array wildcard notation.requestsr   r   r   1@   )requestoutputDimensionality23zrequests[].*zrequests[].request.*r   )r   r   N)r   Zmove_value_by_path)datapathsr   r   r   r   test_move_value_by_path  s~   			))r   c                    s   G dd dt j G  fdddt j}dddii}| jtjdd	 ||}W d
   n1 s2w   Y  |jjdks?J t| j	dksHJ d
S )z0Test that no warning is logged when types match.c                   @      e Zd ZU eed< dS )zMtest_check_field_type_mismatches_no_warning_for_correct_types.<locals>.ModelAr_   Nri   rj   rk   r%   rl   r   r   r   r   ModelA     
 r   c                          e Zd ZU  ed< dS )zPtest_check_field_type_mismatches_no_warning_for_correct_types.<locals>.TestModelmodel_aNri   rj   rk   rl   r   r   r   r   	TestModel  r   r   r   r_   r@   google_genai._commonloggerNr   )
r   	BaseModelat_levelloggingrO   model_validater   r_   r   rP   rT   r   r   r   r   r   r   =test_check_field_type_mismatches_no_warning_for_correct_types  s   r   c                    s   G dd dt j G dd dt j}G  fdddt j}|dd}d	|i}| jtjd
d || W d   n1 s>w   Y  t| jdksLJ d| jd jv sVJ d| jd jv s`J dS )z?Test that warning is logged when Pydantic model types mismatch.c                   @   r   )zPtest_check_field_type_mismatches_warns_on_pydantic_type_mismatch.<locals>.ModelAr_   Nr   r   r   r   r   r     r   r   c                   @   r   )zPtest_check_field_type_mismatches_warns_on_pydantic_type_mismatch.<locals>.ModelBr_   Nri   rj   rk   r!   rl   r   r   r   r   ModelB  r   r   c                       r   )zStest_check_field_type_mismatches_warns_on_pydantic_type_mismatch.<locals>.TestModelmodel_fieldNr   r   r   r   r   r     r   r   testr_   r   r   r   Nr   z&Type mismatch in TestModel.model_fieldr   expected ModelA, got ModelB	r   r   r   r   rO   Z_check_field_type_mismatchesr   rP   rR   rT   r   r   Zmodel_b_instancer   r   r   r   @test_check_field_type_mismatches_warns_on_pydantic_type_mismatch  s   
r   c                    s   G dd dt j G  fdddt j}ddi}| jtjdd ||}W d   n1 s0w   Y  |jdu s<J t| jd	ksEJ dS )
z/Test that no warning is logged for None values.c                   @   r   )zKtest_check_field_type_mismatches_no_warning_for_none_values.<locals>.ModelAr_   Nr   r   r   r   r   r   2  r   r   c                          e Zd ZU dZe  ed< dS )zNtest_check_field_type_mismatches_no_warning_for_none_values.<locals>.TestModelNr   ri   rj   rk   r   r   rl   r   r   r   r   r   5     
 r   r   Nr   r   r   	r   r   r   r   rO   r   r   r   rP   r   r   r   r   ;test_check_field_type_mismatches_no_warning_for_none_values/  s   r   c                    s   G dd dt j G  fdddt j}i }| jtjdd ||}W d   n1 s.w   Y  |jdu s:J t| jdksCJ dS )	z2Test that no warning is logged for missing fields.c                   @   r   )zNtest_check_field_type_mismatches_no_warning_for_missing_fields.<locals>.ModelAr_   Nr   r   r   r   r   r   D  r   r   c                       r   )zQtest_check_field_type_mismatches_no_warning_for_missing_fields.<locals>.TestModelNr   r   r   r   r   r   r   G  r   r   r   r   Nr   r   r   r   r   r   >test_check_field_type_mismatches_no_warning_for_missing_fieldsA  s   r   c                 C   s   G dd dt j}ddd}| jtjdd ||}W d   n1 s&w   Y  |jd	ks2J |jdks9J t| j	d
ksBJ dS )z=Test that no warning is logged for primitive type mismatches.c                   @   s   e Zd ZU eed< eed< dS )zRtest_check_field_type_mismatches_no_warning_for_primitive_types.<locals>.TestModel	int_field	str_fieldN)ri   rj   rk   r%   rl   r!   r   r   r   r   r   V  s   
 r   rE   r   )r   r   r   r   Nr@   r   )
r   r   r   r   rO   r   r   r   r   rP   r   r   r   r   ?test_check_field_type_mismatches_no_warning_for_primitive_typesS  s   
r   c                    s   G dd dt j G dd dt j}G  fdddt j}|dd}d	|i}| jtjd
d || W d   n1 s>w   Y  t| jdksLJ d| jd jv sVJ dS )z@Test that Optional types are properly unwrapped before checking.c                   @   r   )zLtest_check_field_type_mismatches_handles_optional_unwrapping.<locals>.ModelAr_   Nr   r   r   r   r   r   j  r   r   c                   @   r   )zLtest_check_field_type_mismatches_handles_optional_unwrapping.<locals>.ModelBr_   Nr   r   r   r   r   r   m  r   r   c                       r   )zOtest_check_field_type_mismatches_handles_optional_unwrapping.<locals>.TestModelNr   r   r   r   r   r   r   p  r   r   r   r   r   r   r   Nr   r   r   r   r   r   r   r   <test_check_field_type_mismatches_handles_optional_unwrappingg  s   
r   c                    s   G dd dt j G  fdddt j} dd}d|i}| jtjdd	 ||}W d
   n1 s5w   Y  |jjdksBJ t| j	dksKJ d
S )zJTest that no warning is logged when correct Pydantic instance is provided.c                   @   r   )zYtest_check_field_type_mismatches_no_warning_for_correct_pydantic_instance.<locals>.ModelAr_   Nr   r   r   r   r   r     r   r   c                       r   )z\test_check_field_type_mismatches_no_warning_for_correct_pydantic_instance.<locals>.TestModelr   Nr   r   r   r   r   r     r   r   *   r   r   r   r   Nr   )
r   r   r   r   rO   r   r   r_   r   rP   )rT   r   Zmodel_a_instancer   r   r   r   r   Itest_check_field_type_mismatches_no_warning_for_correct_pydantic_instance~  s   
r   c                    s   G dd dt j G dd dt j}G  fdddt j}|dd}|d	d
d}| jtjdd || W d	   n1 s@w   Y  t| jdksNJ d| jd jv sXJ d| jd jv sbJ d	S )z3Test checking multiple fields with mixed scenarios.c                   @   r   )zEtest_check_field_type_mismatches_with_multiple_fields.<locals>.ModelAr_   Nr   r   r   r   r   r     r   r   c                   @   r   )zEtest_check_field_type_mismatches_with_multiple_fields.<locals>.ModelBr_   Nr   r   r   r   r   r     r   r   c                       s.   e Zd ZU  ed< dZe  ed< eed< dS )zHtest_check_field_type_mismatches_with_multiple_fields.<locals>.TestModelfield_aNfield_bfield_c)ri   rj   rk   rl   r   r   r!   r   r   r   r   r     s   
 r   Zwrongr   Nr   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   5test_check_field_type_mismatches_with_multiple_fields  s   
r   c                 C   sn   G dd dt j}dddgi}| jtjdd || W d   n1 s'w   Y  t| jd	ks5J dS )
zCTest that validation doesn't crash on generic types like list[str].c                   @   s   e Zd ZU ee ed< dS )zItest_check_field_type_mismatches_generic_type_no_error.<locals>.TestModeltagsN)ri   rj   rk   r   r!   rl   r   r   r   r   r     s   
 r   r   r)   r*   r   r   Nr   )r   r   r   r   rO   r   r   rP   )rT   r   r   r   r   r   6test_check_field_type_mismatches_generic_type_no_error  s   r   )@__doc__enumr   r   r   r   r"   r   r   r   rt   rS   rM   r   r   r   r   r   r&   markZparametrizer!   r    rL   rU   rd   r   re   rn   Zmodel_rebuildrq   rv   r{   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s  





Q	


		
	


.




Y!GZ