Ë
    –\;j^K  ã                   óÊ   — 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mZmZmZ ddlmZmZmZmZmZ ddlmZ d	Zd
Z e	eej4                  d¬«      Z G d„ d«      Zy)é    N)Úquant_layersé   )Ú
get_logger)Ú_get_input_name_indexÚ_get_op_input_var_namesÚ_get_op_output_var_namesÚ_get_output_name_indexé   )Ú
fuse_utilsÚ
ptq_configÚ	ptq_hooksÚptq_quantizerÚutils)ÚPTQRegistryú.pdmodelz
.pdiparamsz&%(asctime)s-%(levelname)s: %(message)s)Úfmtc                   ó”   ‡ — e Zd ZdZej
                  fˆ fd„	Zdd„Zdd„Zd„ Z	d„ Z
d„ Zd„ Zd	„ Zd
„ Zd„ Zed„ «       Zed„ «       Zˆ xZS )ÚImperativePTQz,
    Static post training quantization.
    c                 óh   •— t         ‰| �  «        t        |t        j                  «      sJ ‚|| _        y)aQ  
        Constructor.

        Args:
            quant_config(PTQConfig): the config of post training quantization.
                The config has weight_quantizer and activation_quantizer.
                In default, the weight_quantizer is PerChannelAbsmaxQuantizer
                and the activation_quantizer is KLQuantizer.
        N)ÚsuperÚ__init__Ú
isinstancer   Ú	PTQConfigÚ_quant_config)ÚselfÚquant_configÚ	__class__s     €úkG:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\paddle/quantization/imperative/ptq.pyr   zImperativePTQ.__init__/   s.   ø€ ô 	‰ÑÔä˜,¬
×(<Ñ(<Ô=Ð=Ð=à)ˆÕó    c                 ó¨  — t        |t        j                  j                  «      sJ d«       ‚|st	        j
                  |«      }|r&|j                  «        t        j                  ||«      }|j                  «       D ]Ô  \  }}t        j                  |«      sŒt        j                  |«      sŒ2| j                  |«      rŒDt	        j
                  | j                  «      }t        j                   |«      rd|_        ||_        t$        j&                  }|j)                  |«      }	|	|_        |j,                  j/                  |	j0                  d¬«       ŒÖ |S )aÉ  
        Add quant config and hook to the target layer.

        Args:
            model(paddle.nn.Layer): The model to be quantized.
            inplace(bool): Whether apply quantization to the input model.
                           Default: False.
            fuse(bool): Whether to fuse layers.
                        Default: False.
            fuse_list(list): The layers' names to be fused. For example,
                "fuse_list = [["conv1", "bn1"], ["conv2", "bn2"]]".
                A TypeError would be raised if "fuse" was set as
                True but "fuse_list" was None.
                Default: None.
        Return
            quantized_model(paddle.nn.Layer): The quantized model.
        ú2The model must be the instance of paddle.nn.Layer.TF)Úlast)r   ÚpaddleÚnnÚLayerÚcopyÚdeepcopyÚevalr   Úfuse_layersÚnamed_sublayersr   Úis_supported_layerr   Úis_leaf_layerÚ_is_skip_layerr   Úis_simulated_quant_layerÚenable_in_act_quantizerr   Úquant_forward_post_hookÚregister_forward_post_hookÚquant_hook_handleÚ_forward_post_hooksÚmove_to_endÚ_hook_id)
r   ÚmodelÚinplaceÚfuseÚ	fuse_listÚnameÚlayerr   Úhookr2   s
             r   ÚquantizezImperativePTQ.quantize?   s$  € ô$ Ø”6—9‘9—?‘?ô
ð 	@à?ó	@ð 
ñ Ü—M‘M %Ó(ˆEÙØ�J‰JŒLÜ×*Ñ*¨5°)Ó<ˆEØ ×0Ñ0Ö2‰KˆD�%ä×.Ñ.¨uÕ5Ü×'Ñ'¨Õ.Ø×+Ñ+¨EÕ2ô  $Ÿ}™}¨T×-?Ñ-?Ó@�Ü×7Ñ7¸Ô>Ø;?�LÔ8Ø&2�Ô#ô !×8Ñ8�Ø$)×$DÑ$DÀTÓ$JÐ!Ø1B�Ô.Ø×)Ñ)×5Ñ5Ø%×.Ñ.°Uð 6õ ð! 3ð( ˆr   c                 ó¦  — t        |t        j                  j                  «      sJ d«       ‚| j	                  |«       t        j
                  j                  d|||dœ|¤Ž d}t        j                  «       rd}t        j                  «        t        j                  «       }t        j                  j                  «       }t        j                  j                  |«      }t        j                  j                  |«      }	t        j                  j!                  |«      }
|
t"        z   }|
t$        z   }t        j                  j'                  |	|||¬«      \  }}}| j)                  |«       | j+                  ||«       | j-                  |«       d}|€d}n)|j/                  d«      r|j1                  d	d
«      d   }n|}t        j                  j3                  |	|«      }|D �cg c]!  }|j5                  «       j7                  |«      ‘Œ# }}t        j                  j9                  |||||j;                  «       ¬«       |rt        j<                  «        yyc c}w )aÖ  
        1. Convert the quantized model
        2. Call jit.save to save the inference model
        3. Post process the inference model.

        Args:
            model (Layer): The model to be saved.
            path (str): The path prefix to save model. The format is
                ``dirname/file_prefix`` or ``file_prefix``.
            input_spec (list[InputSpec|Tensor], optional): Describes the input
                of the saved model's forward method, which can be described by
                InputSpec or example Tensor. If None, all input variables of
                the original Layer's forward method would be the inputs of
                the saved model. Default None.
            **config (dict, optional): Other save configuration options for
                compatibility. We do not recommend using these configurations,
                they may be removed in the future. If not necessary, DO NOT use
                them. Default None.
                The following options are currently supported:
                (1) output_spec (list[Tensor]): Selects the output targets of
                the saved model. By default, all return variables of original
                Layer's forward method are kept as the output of the saved model.
                If the provided ``output_spec`` list is not all output variables,
                the saved model will be pruned according to the given
                ``output_spec`` list.

        Returns:
            None
        r!   )r;   ÚpathÚ
input_specFT)Úpath_prefixÚexecutorÚmodel_filenameÚparams_filenameNr6   r   Ú.r
   r   )rB   Úprogram© )r   r#   r$   r%   Ú_convertÚjitÚsaveÚin_dynamic_modeÚenable_staticÚCPUPlaceÚstaticÚglobal_scopeÚExecutorÚosr?   ÚdirnameÚbasenameÚINFER_MODEL_SUFFIXÚINFER_PARAMS_SUFFIXÚload_inference_modelÚ	_clean_upÚ_gather_input_thresholdsÚ_remove_scale_opÚendswithÚrsplitÚjoinÚglobal_blockÚvarÚsave_inference_modelÚcloneÚdisable_static)r   r6   r?   r@   ÚconfigÚis_dynamic_modeÚplaceÚscopeÚexerR   rS   rC   rD   Úinfer_programÚfeed_target_namesÚfetch_targetsÚ
model_namerA   r:   Ú	feed_varss                       r   Úsave_quantized_modelz"ImperativePTQ.save_quantized_modelo   s  € ô> Ø”6—9‘9—?‘?ô
ð 	@à?ó	@ð 
ð
 	�‰�eÔä�
‰
�‰ÐP˜e¨$¸:ÑPÈÒPð  ˆÜ×!Ñ!Ô#Ø"ˆOÜ× Ñ Ô"ä—‘Ó!ˆÜ—‘×*Ñ*Ó,ˆÜ�m‰m×$Ñ$ UÓ+ˆä—'‘'—/‘/ $Ó'ˆÜ—7‘7×#Ñ# DÓ)ˆØ!Ô$6Ñ6ˆØ"Ô%8Ñ8ˆô �M‰M×.Ñ.ØØØ)Ø+ð	 /ó 
ñ		
ØØØð 	�‰�}Ô%Ø×%Ñ% m°UÔ;Ø×Ñ˜mÔ,ð ˆ
ØÐ!Ø ‰JØ×$Ñ$ ZÔ0Ø'×.Ñ.¨s°AÓ6°qÑ9‰Jà'ˆJÜ—g‘g—l‘l 7¨JÓ7ˆá?Pó
Ù?P°tˆM×&Ñ&Ó(×,Ñ,¨TÕ2Ð?Pð 	ð 
ô 	�‰×*Ñ*ØØØØØ!×'Ñ'Ó)ð 	+ô 	
ñ Ü×!Ñ!Õ#ð ùò
s   Ç&Ic                 óp  — |j                  «       D ];  \  }}| j                  |«      sŒ|j                  j                  j	                  «        Œ= | j                  |«       |j                  «       D ]3  \  }}| j                  |«      sŒ| j                  ||j                  «       Œ5 | j                  |«       y)a  
        Convert the quantized model.

        Args:
            model(paddle.nn.Layer): The quantized model.
            inplace(bool): Whether apply conversion to the input model.
                           Default: False.
        Returns:
            None
        N)r*   Ú_is_quant_layerr   r2   ÚremoveÚ_cal_thresholdsÚ_save_output_thresholdsÚ_wrap_simulated_layers)r   r6   r:   Ú	sub_layers       r   rH   zImperativePTQ._convertÍ   sœ   € ð  %×4Ñ4Ö6‰OˆD�)Ø×#Ñ# IÕ.Ø×'Ñ'×9Ñ9×@Ñ@ÕBð  7ð 	×Ñ˜UÔ#à$×4Ñ4Ö6‰OˆD�)Ø×#Ñ# IÕ.Ø×,Ñ,¨Y¸	×8OÑ8OÕPð  7ð 	×#Ñ# EÕ*r   c                 ó°  — t        |t        j                  j                  «      sJ d«       ‚d}d}|j	                  «       D ]  \  }}| j                  |«      sŒ|dz  }Œ |j	                  «       D ]å  \  }}| j                  |«      sŒ|dz  }|dz  dk(  rt        j                  d|› d|› d�«       |j                  }|j                  r|j                  j                  «        |j                  j                  «        t        j                  |«      sŒ£|j                  f}|j                   j#                  ||«       |j                   j                  «        Œç y)	z«
        Calculate the thresholds of inputs and outputs.

        Args:
            model(paddle.nn.Layer): The quantized model.
        Returns:
            None
        ú8The input model must be the instance of paddle.nn.Layer.r   r
   é   zProcess the z / z layerN)r   r#   r$   r%   r*   rn   Ú_loggerÚinfor   r/   Úin_act_quantizerÚcal_thresholdsÚout_act_quantizerr   r.   ÚweightÚwt_quantizerÚsample_data)r   r6   Ú	total_numÚcur_numr:   rs   r   Úweightss           r   rp   zImperativePTQ._cal_thresholdså   s:  € ô Ø”6—9‘9—?‘?ô
ð 	FàEó	Fð 
ð ˆ	ØˆØ$×4Ñ4Ö6‰OˆD�)Ø×#Ñ# IÕ.Ø˜Q‘‘	ð  7ð  %×4Ñ4Ö6‰OˆD�)Ø×#Ñ# IÕ.Ø˜1‘�Ø˜Q‘; !Ò#Ü—L‘L <°¨y¸¸I¸;ÀfÐ!MÔNà(×6Ñ6�à×7Ò7Ø ×1Ñ1×@Ñ@ÔBØ×.Ñ.×=Ñ=Ô?ä×7Ñ7¸	ÕBØ(×/Ñ/Ð1�GØ ×-Ñ-×9Ñ9¸)ÀWÔMØ ×-Ñ-×<Ñ<Õ>ñ  7r   c                 óè  — t        |t        j                  j                  «      sJ d«       ‚t	        j
                  |«      }|j                  }|j                  j                  }t        |«      dk(  sJ ‚t        |«      dk(  rA|d   t        d«      z   dz   }|j                  ||d   i«       |j                  d|d   i«       yt        j                  dj                  |d   t        |«      «      «       y)zí
        Save the output thresholds to the layer.

        Args:
            sub_layer(paddle.nn.Layer): The quantized layer.
            quant_config(PTQConfig): the quant config for the layer.
        Returns:
            None
        ru   r
   r   Ú
_thresholdÚout_thresholdz;output_thresholds shape of {} need to be 1, but received {}N)r   r#   r$   r%   r   Ú
layer_infoÚoutput_namesr{   Ú
thresholdsÚlenÚstrÚ_set_op_attrsrw   ÚwarningÚformat)r   rs   r   r…   r†   Úoutput_thresholdsÚ	save_names          r   rq   z%ImperativePTQ._save_output_thresholds	  sï   € ô Ø”v—y‘y—‘ô
ð 	FàEó	Fð 
ô !×+Ñ+¨IÓ6ˆ
à!×.Ñ.ˆØ(×:Ñ:×EÑEÐÜ�<Ó  AÒ%Ð%Ð%ÜÐ Ó! QÒ&Ø$ Q™¬#¨a«&Ñ0°<Ñ?ˆIØ×#Ñ# YÐ0AÀ!Ñ0DÐ$EÔFØ×#Ñ# _Ð6GÈÑ6JÐ$KÕLä�O‰OØM×TÑTØ  ‘O¤SÐ):Ó%;óõr   c                 ó¦  — t        |t        j                  j                  «      sJ d«       ‚|j	                  «       D �]’  \  }}| j                  |«      sŒt        j                  |«      sŒ/|j                  }|j                  du sJ ‚|j                  }|j                  }d}t        j                  j                  «       D ]  \  }}	t        ||	«      sŒd|z   } n |€J ‚t        |t        j                   «      rd}
nd}
|
d|j"                  |j"                  dœ}t%        j&                  |   |fi |¤Ž}t)        |d	«      sJ ‚t)        |j*                  d
«      sJ ‚t-        |j.                  «      dk(  rXt1        j2                  |j.                  d   gt0        j4                  ¬«      }|j*                  j6                  j9                  |«       t)        |d«      sJ ‚t)        |j:                  d
«      sJ ‚t-        |j.                  «      dk(  sJ ‚|j.                  d   }t        |t<        «      r&t1        j2                  |t0        j4                  ¬«      }n&t1        j2                  |gt0        j4                  ¬«      }|j:                  j6                  j9                  |«       | j?                  ||«       t        j@                  ||«      \  }}tC        |||«       �Œ• y)zç
        Replace conv2d and linear with the quantized layers, and save
        thresholds into the fake layers.
        Args:
            model(paddle.nn.Layer): The model to be quantized.
        Returns:
            None
        ru   TNÚ	QuantizedÚabs_maxÚchannel_wise_abs_maxÚmoving_average_abs_max)Úweight_quantize_typeÚactivation_quantize_typeÚweight_bitsÚactivation_bitsÚ_fake_quant_inputÚ_scaler
   r   )ÚdtypeÚ_fake_quant_weight)"r   r#   r$   r%   r*   rn   r   r.   r   r/   r}   ry   r   Úlayer_name_mapÚitemsr   ÚAbsmaxQuantizerÚ
quant_bitsr   Ú__dict__Úhasattrr˜   rˆ   r‡   ÚnpÚarrayÚfloat32r™   Ú	set_valuer›   Úlistrq   Úfind_parent_layer_and_sub_nameÚsetattr)r   r6   r:   rs   r   r}   ry   Úquant_layer_nameÚkeyÚvaluer”   ÚkwargsÚquant_layerÚinput_thresholdÚweight_thresholdÚparent_layerÚsub_names                    r   rr   z$ImperativePTQ._wrap_simulated_layers'  s´  € ô Ø”6—9‘9—?‘?ô
ð 	FàEó	Fð 
ð  %×4Ñ4×6‰OˆD�)Ø×#Ñ#Øõä×6Ñ6°yÕAØ(×6Ñ6�Ø#×;Ñ;¸tÑCÐCÐCØ+×8Ñ8�Ø#/×#@Ñ#@Ð ð $(Ð Ü"'×"6Ñ"6×"<Ñ"<Ö">‘J�C˜Ü! )¨UÕ3Ø+6¸Ñ+<Ð(Ùð #?ð (Ð3Ð3Ð3ä˜l¬M×,IÑ,IÔJØ+4Ñ(à+AÐ(à,@Ø0HØ#/×#:Ñ#:Ø'7×'BÑ'Bñ	�ô +×3Ñ3Ð4DÑEØñØ!'ñ�ô
 ˜{Ð,?Ô@Ð@Ð@Ü˜{×<Ñ<¸hÔGÐGÐGÜÐ'×2Ñ2Ó3°qÒ8Ü&(§h¡hØ)×4Ñ4°QÑ7Ð8ÄÇ
Á
ô'�Oð  ×1Ñ1×8Ñ8×BÑBØ'ôô ˜{Ð,@ÔAÐAÐAÜ˜{×=Ñ=¸xÔHÐHÐHÜ˜<×2Ñ2Ó3°qÒ8Ð8Ð8Ø#/×#:Ñ#:¸1Ñ#=Ð ÜÐ.´Ô5Ü')§x¡xØ(´·
±
ô(Ñ$ô (*§x¡xØ)Ð*´"·*±*ô(Ð$ð ×.Ñ.×5Ñ5×?Ñ?Ø$ôð
 ×,Ñ,¨[¸,ÔGô */×)MÑ)MØ˜4ó*Ñ&�˜hô ˜ h°Ö<ñE  7r   c                 ó  — t        j                  |«      D �]t  }t        |«      D �]b  }t        j                  |j                  |«      }|€Œ'd|j
                  v s|j
                  dk(  r‚|j                  d«      d   }t        j                  ||«      }t        j                  |«      }t        ||«      \  }}	|j                  |t        |	«      z   dz   |«       |j                  dd«       ŒÆt        |«      D ]�  }
|
|k7  rŒ	t        ||
«      \  }}	|t        |	«      z   dz   }|j                  |«      sŒ;|j                  |«      }t        ||«      \  }}	|t        |	«      z   dz   }|j                  ||«       |j                  dd«       Œ‘ �Œe �Œw y)	zî
        Get and save input thresholds from the front ops.

        Args:
            program(Program): the input infer program.
            scope(Scope): the corresponding scope for the program.
        Returns:
            None
        NÚquantize_dequantizeÚmoving_average_abs_max_scaleÚOutScaler   rƒ   Úwith_quant_attrT)r   Úprogram_all_opsr   Úfind_previous_opÚblockÚtypeÚoutputÚload_variable_dataÚfp_numpy_to_naiver   Ú	_set_attrr‰   r   r	   Úhas_attrÚattr)r   rF   re   ÚopÚin_var_nameÚprevious_opÚ	attr_nameÚin_thresholdÚargnameÚindexÚout_var_nameÚ	thresholds               r   rX   z&ImperativePTQ._gather_input_thresholdsx  s�  € ô ×'Ñ'¨×0ˆBÜ6°r×:�Ü#×4Ñ4°R·X±X¸{ÓK�ØÐ&Øð *¨[×-=Ñ-=Ñ=Ø"×'Ñ'Ð+IÒIà +× 2Ñ 2°:Ó >¸qÑ A�IÜ#(×#;Ñ#;¸EÀ9Ó#M�LÜ#(×#:Ñ#:¸<Ó#H�LÜ%:¸2¸{Ó%K‘N�G˜UØ—L‘LØ¤# e£*Ñ,¨|Ñ;¸\ôð —L‘LÐ!2°DÕ9ä(@ÀÖ(M˜Ø'¨;Ò6Ø$Ü)?Ø'¨ó*™˜ ð %,¬c°%«jÑ$8¸<Ñ$G˜	Ø*×3Ñ3°IÔ>Ø$Ø$/×$4Ñ$4°YÓ$?˜	ä)>¸rÀ;Ó)O™˜ Ø$+¬c°%«jÑ$8¸<Ñ$G˜	ØŸ™ Y°	Ô:ØŸ™Ð%6¸Õ=ò )Nò%  ;ñ 1r   c                 óv  — d„ }t        j                  |«      D �]  }d|j                  v r(|j                  D ]  }d|v sŒ|j	                  |«       Œ Œ:|j                  dv sŒI|j                  dk(  rdnd}|j                  |«      d   }t        j                  |j                  |«      }t        |«      d	kD  s|d   j                  d
k7  rŒ±|d   }t        ||«      \  }	}
|	t        |
«      z   dz   }t        ||j                  d«      d   «      \  }	}
|	t        |
«      z   dz   } |||||«        |||dd«       �Œ  y)z°
        Remove useless thresholds which are added in jit.save.

        Args:
            program(Program): the input infer program.
        Returns:
            None
        c                 óB  — | j                  |«      rŽ|j                  |«      r|| j                  |«      |j                  |«      k(  rX| j                  |«      }| j                  |«       |j                  |«       |j                  ||«       |j                  dd«       y y y y )Nr¶   T)r¿   rÀ   Ú_remove_attrr¾   )rÁ   Únext_opÚold_attr_nameÚnew_attr_namerÉ   s        r   Ú_helperz(ImperativePTQ._clean_up.<locals>._helper¯  s�   € à—‘˜MÔ*Ø×$Ñ$ ]Ô3Ø—G‘G˜MÓ*¨g¯l©l¸=Ó.IÒIàŸG™G MÓ2�	Ø—‘ Ô.Ø×$Ñ$ ]Ô3Ø×!Ñ! -°Ô;Ø×!Ñ!Ð"3°TÕ:ð Jð 4ð +r   r³   rƒ   )Úconv2dÚmatmulrÑ   ÚOutputÚOutr   r
   Úelementwise_addr„   N)r   r·   rº   Ú
attr_namesrÌ   r»   Úfind_next_opsr¹   rˆ   r	   r‰   )r   rF   rÐ   rÁ   rÄ   Úarg_namerÈ   Únext_opsrÍ   rÆ   rÇ   rÎ   rÏ   s                r   rW   zImperativePTQ._clean_up¥  s5  € ò
	;ô ×'Ñ'¨×0ˆBØ$¨¯©Ñ/à!#§¤�IØ# yÒ0ØŸ™¨	Õ2ñ "/ð —‘Ð0Ò0à')§w¡w°(Ò':™8À�Ø!Ÿy™y¨Ó2°1Ñ5�Ü ×.Ñ.¨r¯x©x¸ÓF�Ü�x“= 1Ò$¨°©×(8Ñ(8Ð<MÒ(MØØ" 1™+�ä!7¸¸LÓ!I‘�˜Ø '¬#¨e«*Ñ 4°|Ñ C�ä!7Ø˜WŸ^™^¨EÓ2°1Ñ5ó"‘�˜ð !(¬#¨e«*Ñ 4°|Ñ C�á˜˜G ]°MÔBÙ˜˜G _°oÖFñ1 1r   c                 ó  — t        j                  |«      D ]s  }|j                  dk(  sŒ|j                  d«      d   }|j	                  d«      d   }t        j
                  |j                  |«      }|D ]  }|j                  ||«       Œ Œu y)z=
        Remove the moving_average_abs_max_scale op.
        r´   ÚXr   rÔ   N)r   r·   rº   Úinputr»   r×   r¹   Ú_rename_input)r   rF   rÁ   rÂ   rÈ   rÙ   rÍ   s          r   rY   zImperativePTQ._remove_scale_opÕ  s{   € ô ×'Ñ'¨Ö0ˆBØ�w‰wÐ8Ó8Ø Ÿh™h s›m¨AÑ.�Ø!Ÿy™y¨Ó/°Ñ2�Ü ×.Ñ.¨r¯x©x¸ÓF�Û'�GØ×)Ñ)¨,¸ÕDñ  (ñ 1r   c                 ó:   — t        | d«      xr | j                  du S )NÚ
skip_quantT)r¡   rß   ©r;   s    r   r-   zImperativePTQ._is_skip_layerá  s   € ä�u˜lÓ+ÒH°×0@Ñ0@ÀDÐ0HÐHr   c                 ó   — t        | d«      S )Nr   )r¡   rà   s    r   rn   zImperativePTQ._is_quant_layerå  s   € ä�u˜oÓ.Ð.r   )FFN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Údefault_ptq_configr   r=   rl   rH   rp   rq   rr   rX   rW   rY   Ústaticmethodr-   rn   Ú__classcell__)r   s   @r   r   r   *   sy   ø„ ñð %/×$AÑ$Aõ *ó .ó`\$ò|+ò0"?òHò<O=òb+>òZ.Gò`
Eð ñIó ðIð ñ/ó ô/r   r   )r&   ÚloggingrQ   Únumpyr¢   r#   Úpaddle.nn.quantr   Ústatic.log_helperr   Ústatic.quantization.utilsr   r   r   r	   Ú r   r   r   r   r   Úptq_registryr   rT   rU   râ   ÚINFOrw   r   rG   r   r   Ú<module>rñ      s`   ðó Û Û 	ã ã Ý (å +÷ó ÷ FÕ EÝ %àÐ Ø"Ð á
Øˆg�l‰lÐ Hô€÷
}/ò }/r   