Ë
    °L¦j+  ã                  óì   — d dl mZ d dlZd dlmZ d dlZd dl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mZ dd	lmZ dd
lmZ dZdd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	 	 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Z y)é    )ÚannotationsN)ÚPath)ÚAnyé   )ÚSettings)Úbuild_monthly_factor_panel)Úoptimize_weights_walk_forwardÚrun_factor_backtest)Úload_research_context)Úanalyze_text_sourcesz0.1.0c                óF   — t        |«      }|j                  «       r|S | |z  S )N)r   Úis_absolute)ÚrootÚvalueÚpaths      ú1C:\FundamentalWorkbench\src\fundamental_mvp\m2.pyÚ_resolver      s%   € Ü�‹;€DØ×#Ñ#Ô%ˆ4Ð6¨4°$©;Ð6ó    c                ó’   — | j                  |j                  |› d�z  d¬«       | j                  |j                  |› d�z  dd¬«       y )Nú.parquetF©Úindexz.csvz	utf-8-sig)r   Úencoding)Ú
to_parquetÚprocessed_dirÚto_csv)ÚframeÚstemÚsettingss      r   Ú_saver       sJ   € Ø	×Ñ�X×+Ñ+°°°hÐ.?Ñ?ÀuÐÔMØ	‡L�L�×'Ñ'¨T¨F°$¨-Ñ7¸uÈ{€LÕ[r   c           	     óâ  — g d¢}| j                   | d   j                  «          j                  «       }t        j                  |d   d¬«      |d<   |j                   |d   j                  «       |d   j                  |«      z     }|j                  rt        j                  |¬«      S |j                  ddgd¬«      }|j                  dd	¬
«      j                  d«      }|j                  dd	¬«      j                  ddddddd¬«      }|g d¢   j                  g d¢«      j                  d¬«      }|d|d   z  z
  d|d   z  z
  j                  dd«      |d<   t         |d <   |j#                  |¬«      S )!N)
Úsource_codeÚtext_document_countÚlatest_text_dateÚtext_risk_scoreÚtext_catalyst_scoreÚ
moat_scoreÚmanagement_scoreÚmanagement_risk_scoreÚqualitative_scoreÚtext_model_versionr"   Úannouncement_dateÚcoerce©Úerrors©ÚcolumnsÚfirst)Úna_positionF)Ú
group_keysé   )Úas_index)Údocument_idÚsize)r,   Úmax)Ú
risk_scorer9   )Úcatalyst_scoreÚmean)r'   r<   )r(   r<   )r)   r9   )r#   r$   r%   r&   r'   r(   r)   )r'   r(   r&   )çš™™™™™Ù?r=   gš™™™™™É?r   ©Úaxisg      à?r%   g      Ð?r)   r   éd   r*   r+   )ÚlocÚnotnaÚcopyÚpdÚto_datetimeÚisnaÚleÚemptyÚ	DataFrameÚsort_valuesÚgroupbyÚtailÚaggÚmulÚsumÚclipÚM2_MODEL_VERSIONÚreindex)Ú	documentsÚas_ofr1   ÚusableÚresultÚpositives         r   Ú_aggregate_textrX       sŽ  € ò€Gð
 �]‰]˜9 ]Ñ3×9Ñ9Ó;Ñ<×AÑAÓC€FÜ"$§.¡.°Ð8KÑ1LÐU]Ô"^€FÐÑØ�Z‰Z˜Ð2Ñ3×8Ñ8Ó:¸VÐDWÑ=X×=[Ñ=[Ð\aÓ=bÑbÑc€FØ‡|‚|Ü�|‰| GÔ,Ð,Ø×Ñ Ð0CÐ DÐRYÐÓZ€FØ�^‰^˜M°eˆ^Ó<×AÑAÀ"ÓE€FØ�^‰^˜M°Eˆ^Ó:×>Ñ>Ø3Ø5Ø-Ø6Ø)Ø5Ø>ð ?ó €Fð ÒOÑP×TÑTÒUdÓe×iÑiÐopÐiÓq€HØ#+¨c°FÐ;LÑ4MÑ.MÑ#MÐPTÐW]Ð^uÑWvÑPvÑ#v×"|Ñ"|Ð}~ð  ADó  #E€FÐÑÜ#3€FÐÑ Ø�>‰> 'ˆ>Ó*Ð*r   c                óÊ  — | j                  |dd¬«      j                  |dd¬«      }g d¢}t        j                  d|j                  ¬«      }t        j                  d|j                  ¬«      }|D ]y  \  }}t        j                  ||   d¬«      }	|	j                  «       }
|j                  |	j                  d	«      |z  «      }|j                  |
j                  t        «      |z  «      }Œ{ |j                  |j                  d	t        j                  «      «      |d
<   |ddg   j                  «       j                  d¬«      |d<   t        |d<   |j!                  dd
gddg¬«      S )Nr"   Úleft)ÚonÚhow))Úcombined_scoregffffffæ?)r*   ç333333Ã?)Úresearch_context_scorer^   g        r   r-   r.   r   Úm2_composite_scorer*   r_   r   r>   Úm2_research_coverageÚm2_model_versionÚcandidate_eligibleF©Ú	ascending)ÚmergerD   ÚSeriesr   Ú
to_numericrB   ÚaddÚfillnaÚastypeÚfloatÚdivÚreplaceÚnpÚnanr<   rQ   rJ   )Ú
candidatesÚtextÚcontextrV   ÚpartsÚ	numeratorÚdenominatorÚcolumnÚweightÚvaluesÚ	availables              r   Ú_enrich_candidatesr{   <   sF  € Ø×Ñ˜d }¸&ÐÓA×GÑGÈÐTaÐgmÐGÓn€FÚe€EÜ—	‘	˜# V§\¡\Ô2€IÜ—)‘)˜C v§|¡|Ô4€KÛ‰ˆ�Ü—‘˜v f™~°hÔ?ˆØ—L‘L“Nˆ	Ø—M‘M &§-¡-°Ó"2°VÑ";Ó<ˆ	Ø!—o‘o i×&6Ñ&6´uÓ&=ÀÑ&FÓG‰ð	  ð
 $-§=¡=°×1DÑ1DÀQÌÏÉÓ1OÓ#P€FÐÑ Ø%+Ð-@ÐBZÐ,[Ñ%\×%bÑ%bÓ%d×%iÑ%iÐopÐ%iÓ%q€FÐ!Ñ"Ü!1€FÐÑØ×ÑÐ3Ð5IÐJÐW\Ð^cÐVdÐÓeÐer   c                ó*  — | j                   dz  }t        j                  t        |«      «      5 }|j	                  «       D ]=  \  }}|j                  d|«       |j                  d|› d�«       |j                  d«       Œ? 	 d d d «       y # 1 sw Y   y xY w)Nzfundamental_mvp.duckdbÚm2_framezCREATE OR REPLACE TABLE z AS SELECT * FROM m2_frame)Údatabase_dirÚduckdbÚconnectÚstrÚitemsÚregisterÚexecuteÚ
unregister)r   ÚtablesÚdatabaseÚ
connectionÚnamer   s         r   Ú_persist_tablesrŠ   L   s|   € Ø×$Ñ$Ð'?Ñ?€HÜ	�‰œ˜H›Ô	&¨*Ø!Ÿ<™<ž>‰KˆD�%Ø×Ñ 
¨EÔ2Ø×ÑÐ!9¸$¸Ð?YÐZÔ[Ø×!Ñ! *Õ-ñ *÷ 
'×	&Ñ	&ús   ®AB	Â	Bc                óJ   — t        j                  | «      rdS t        | «      d›S )NÚ-ú.2%)rD   rF   rl   )r   s    r   Ú_fmt_pctrŽ   U   s    € Ü—'‘'˜%”.ˆ3Ð;¬¨u«°cÐ(:Ð;r   c                ól  — dj                  d„ |j                  dd¬«      j                  d¬«      D «       «      xs d}dj                  d„ |j                  d¬«      j                  «       D «       «      xs d	}|j                  |j                  d
d«         j                  d«      }dj                  d„ |j                  d¬«      D «       «      xs d}dt        › d|d   › d|d   › d|d   › d|d   › d|d   › d|d   › d|d   › d|› d|› d|d    › d!|› d"�}	| j                  d#z  j                  |	d$¬%«       y )&NÚ
c              3  óÜ   K  — | ]d  }d |j                   › dt        |j                  «      › d|j                  d›dt	        |j
                  «      › dt	        |j                  «      › d�–— Œf y­w)ú| ú | z.4fú |N)ÚfactorÚintÚperiodsÚmean_rank_icrŽ   Úmean_long_short_net_returnÚ cumulative_long_short_net_return©Ú.0Úrows     r   Ú	<genexpr>z _write_report.<locals>.<genexpr>`   sˆ   è ø€ ð áfˆCð ˆS�Z‰ZˆL˜œC §¡Ó,Ð-¨S°×1AÑ1AÀ#Ð0FÀcÌ(ÐSV×SqÑSqÓJrÐIsÐsvÔwð  AD÷  Aeñ  Aeó  xfð  wgð  giô  	jÙfùs   ‚A*A,r˜   Frd   r   z| - | 0 | - | - | - |c              3  ó6   K  — | ]  \  }}d |› d|d›d�–— Œ y­w)r’   r“   r�   r”   N© )rœ   r‰   r   s      r   rž   z _write_report.<locals>.<genexpr>d   s(   è ø€ ÐyÑLx¹[¸TÀ5˜r $  s¨5°¨+°RÔ8ÑLxùs   ‚z	| - | - |rc   r5   c           
   3  óŽ   K  — | ]=  }d |j                   › d|j                  › d|j                  d›d|j                  d›d�	–— Œ? y­w)r’   r“   z.2fz.0%r”   N)Úsecurity_idr‰   r`   ra   r›   s     r   rž   z _write_report.<locals>.<genexpr>f   sP   è ø€ ð á.ˆCð ˆS�_‰_Ð˜S §¡ 
¨#¨c×.DÑ.DÀSÐ-IÈÈS×MeÑMeÐfiÐLjÐjlÔmÙ.ùs   ‚AAz| - | - | - | - |u7   # M2 æ·±åº¦ç ”ç©¶ä¸Žå› å­�å®žéªŒæŠ¥å‘Š

æ¨¡åž‹ç‰ˆæœ¬ï¼šu     
ç ”ç©¶æˆªé�¢ï¼šrT   u     
æ–‡æœ¬æ–‡æ¡£ï¼šÚtext_documentsu    ä»½ï¼Œè¦†ç›– Útext_stocksu6    å�ªè‚¡ç¥¨  
è¡Œä¸š/æ¦‚å¿µ/å‚¬åŒ–å‰‚ä¸Šä¸‹æ–‡è¦†ç›–ï¼šÚcontext_stocksu    å�ª  
å› å­�é�¢æ�¿ï¼šÚfactor_rowsu    è¡Œï¼ŒÚfactor_periodsu+    ä¸ªæœˆåº¦æˆªé�¢  
æ�ƒé‡�æ ·æœ¬å¤–æ£€éªŒï¼šÚoos_periodsu—    ä¸ªæœˆåº¦æˆªé�¢

## 1. å�•å› å­�ç»“æžœ

| å› å­� | æœŸæ•° | å¹³å�‡ RankIC | æœˆå�‡å¤šç©ºå‡€æ”¶ç›Š | ç´¯è®¡å¤šç©ºå‡€æ”¶ç›Š |
|---|---:|---:|---:|---:|
uA   

## 2. æœ€æ–°èµ°æ­¥ä¼˜åŒ–æ�ƒé‡�

| å› å­� | æ�ƒé‡� |
|---|---:|
u   

æ�ƒé‡�ä»…ç”¨è°ƒä»“æ—¥ä¹‹å‰� Útraining_periodsuÄ    ä¸ªæœˆè®­ç»ƒï¼Œé�žè´Ÿä¸”å’Œä¸º 1ï¼›å›žæµ‹å·²è®¡å…¥å�Œè¾¹æ�¢æ‰‹æ‰€å¯¹åº”çš„é…�ç½®äº¤æ˜“æˆ�æœ¬ã€‚

## 3. M2 å€™é€‰æ ·æœ¬

| ä»£ç � | å��ç§° | M2ç»¼å�ˆåˆ† | å¤–éƒ¨ç ”ç©¶è¦†ç›– |
|---|---|---:|---:|
u  

## 4. å�£å¾„ä¸Žé™�åˆ¶

- è´¢åŠ¡å› å­�ä»…åœ¨ `available_trade_date` ä¸�æ™šäºŽè°ƒä»“æˆªé�¢æ—¶ä½¿ç”¨ï¼Œæ ‡ç­¾æ”¶ç›Šä¸�å�‚ä¸Žå½“æœŸå› å­�æž„å»ºã€‚
- è¡Œä¸šæ˜ å°„ç›®å‰�æ˜¯ M1 å½“å‰�æˆªé�¢ï¼ŒåŽ†å�²è¡Œä¸šå�˜æ›´ä»�å­˜åœ¨åˆ†ç±»å��å·®ã€‚
- å…¬å‘Šæ–‡æœ¬å¾—åˆ†æ˜¯å�¯è§£é‡Šå…³é”®è¯�ç ”ç©¶ä¿¡å�·ï¼Œä¸�æ˜¯å¯¹å…¬å�¸è´¨åœ°çš„äº‹å®žè®¤å®šï¼›é«˜é£Žé™©æ–‡æ¡£å¿…é¡»å¤�æ ¸åŽŸæ–‡ã€‚
- å¤–éƒ¨æ–‡æœ¬ã€�è¡Œä¸šé«˜é¢‘ã€�äº§ä¸šé“¾å’Œå‚¬åŒ–å‰‚è¾“å…¥ç¼ºå¤±æ—¶ä¸�å¡«å……ä¼ªåˆ†æ•°ï¼Œä»¥è¦†ç›–çŽ‡æ˜¾å¼�æ ‡è®°ã€‚

æœ¬æŠ¥å‘Šç”¨äºŽç ”ç©¶ç®¡çº¿éªŒè¯�ï¼Œä¸�æž„æˆ�æŠ•èµ„å»ºè®®ã€‚
u!   M2_æ·±åº¦ç ”ç©¶ä¸Žå› å­�å®žéªŒ.mdúutf-8©r   )
ÚjoinrJ   Ú
itertuplesr‚   rA   ÚgetÚheadrQ   Ú
report_dirÚ
write_text)
r   ÚsummaryÚfactor_summaryÚweightsÚenrichedÚfactor_linesÚweight_linesÚtopÚ	top_linesÚreports
             r   Ú_write_reportr»   Y   s»  € ð —9‘9ñ à!×-Ñ-¨nÈÐ-ÓN×YÑYÐ`eÐYÔfóó ò !ð 
!ð ð —9‘9ÑyÈG×L_ÑL_ÐjoÐL_ÓLp×LvÑLvÔLxÓyÓyò  Ið  ~I€LØ
�,‰,�x—|‘|Ð$8¸%Ó@Ñ
A×
FÑ
FÀrÓ
J€CØ—	‘	ñ à—>‘>¨�>Ô.óó ò ð 
ð ðä Ð!ð "Ø˜Ñ Ð!ð "ØÐ(Ñ)Ð*¨.¸ÀÑ9OÐ8Pð Q*Ø*1Ð2BÑ*CÐ)Dð EØ˜Ñ&Ð' w¨wÐ7GÑ/HÐ.Ið JØ  Ñ/Ð0ð 1ð €ð ð €ð à$Ð%7Ñ8Ð9ð :ð €ð 
ð7%€FðL ×ÑÐ>Ñ>×JÑJÈ6Ð\cÐJÕdr   c                ó<  — t        j                  |j                  d¬«      «      }|d   }|d   }| j                  j	                  dd¬«       | j
                  j	                  dd¬«       t        | t        |d   «      «      }t        j                  |j                  «      }|j                  |d   j                  d	d
g«       |d   j                  | j                  «      z  |d   j                  «       z     j!                  «       }t        j"                  |d   j%                  «       «      j'                  «       }t)        t+        | j,                  t        |d   «      «      «      }t/        ||«      }	t        j                  | j                  dz  «      }
|
ddg   j1                  ddi¬«      }t3        |j5                  di «      «      }|j7                  t        | j,                  «      |d   |d   |d   dœ«       t9        ||«      }|j;                  |«      }t<        j>                  |j                  |d   jA                  d«      df<   tC        |d   «      }t3        dtE        |d   «      tG        |d   «      tE        |d   «      ¬ «      }tI        ||fi |¤Ž}tC        |j5                  d!|«      «      }tK        ||ftE        |d"   «      tE        |d#   «      tG        |j5                  d$d%«      «      t        |d&   «      d'œ|¤Ž}t        j                  | j                  d(z  «      }tM        ||	|«      }||	||jN                  |jP                  |d)œ}|jS                  «       D ]  \  }}tU        ||| «       Œ tU        |jV                  d*| «       tU        |jX                  d+| «       tU        |jZ                  d,| «       tU        |j\                  jX                  d-| «       t_        | |«       t`        |jc                  «       je                  «       tg        |«      |	jh                  stE        |	d   jk                  «       «      ndtE        |d   jm                  d«      jo                  «       «      |jp                  |jr                  |jt                  |jP                  jh                  s&tE        |jP                  d   jk                  «       «      ndtE        |d"   «      |jv                  jS                  «       D ��ci c]  \  }}|ty        tG        |«      d.«      “Œ c}}|D �ci c]  }|t        | j                  |› d/�z  «      “Œ  c}d0œ}| j
                  d1z  j{                  t}        j~                  |d2d3¬4«      d¬«       t�        | ||jN                  |jv                  |«       |S c c}}w c c}w )5Nrª   r«   ÚpathsÚbacktestT)ÚparentsÚexist_okÚ
start_dateÚindustry_l1_codeÚX50ÚX51Ú
avg_amountÚavailable_trade_dateÚrebalance_dateÚdisclosure_dirzsecurity_master.parquetr"   Úindustry_l2_codeÚindustry_coder0   Úresearch_contextÚindustry_high_frequencyÚtheme_mappingÚ	catalysts)Úbase_dirÚindustry_data_pathÚtheme_mapping_pathÚcatalyst_pathÚresearch_context_coverager   r_   Úfactor_columnsÚ	quantilesÚtransaction_cost_bpsÚminimum_assets)Úavailable_date_colrÕ   rÖ   Ú
min_assetsÚoptimization_columnsr©   Úweight_candidatesÚmax_factor_weightg      ð?Úoptimization_objective)Útrain_periodsÚcandidate_countÚ
max_weightÚ	objectivezstock_screen_candidates.parquet)Útext_research_documentsÚtext_research_scoresÚresearch_context_scoresÚfactor_backtest_summaryÚfactor_weight_historyÚm2_stock_candidatesÚfactor_group_returnsÚfactor_period_returnsÚ	factor_icÚfactor_oos_period_returnsé   r   )Úmodel_versionrT   r£   r¤   r¥   r¦   Úfactor_stocksr§   r¨   r©   Úlatest_weightsÚoutputszm2_run_summary.jsonFé   )Úensure_asciiÚindent)AÚtomllibÚloadsÚ	read_textr   Úmkdirr°   r   r�   rD   Úread_parquetÚoutput_pathrA   ÚisinÚgeÚmin_avg_amount_20rB   rC   Ú	Timestampr9   Ú	normalizer   r   Úproject_rootrX   ÚrenameÚdictr®   Úupdater   Úscore_stocksro   rp   ÚeqÚlistr–   rl   r
   r	   r{   r²   Úweight_historyr‚   r    Úgroup_returnsÚperiod_returnsÚicÚoos_backtestrŠ   rQ   ÚdateÚ	isoformatÚlenrH   ÚnuniqueÚgtrO   ÚrowsÚstocksr—   r´   Úroundr±   ÚjsonÚdumpsr»   )r   Úconfig_pathÚrawr½   Úbacktest_configÚpanel_resultÚpanelrT   rS   Útext_scoresÚmasterÚuniverseÚcontext_configrË   Úcontext_scoresÚfactorsÚcommonÚfactor_testÚoptimized_factorsÚ	optimizedrq   rµ   r†   r‰   r   rx   r²   s                              r   Úrun_m2r$  “   sG  € Ü
�-‰-˜×-Ñ-°wÐ-Ó?Ó
@€CØ�‰L€EØ˜*‘o€OØ×Ñ× Ñ ¨¸Ð Ô=Ø×Ñ×Ñ d°TÐÔ:ä-¨h¼¸OÈLÑ<YÓ8ZÓ[€LÜ�O‰O˜L×4Ñ4Ó5€EØ�I‰IØ	Ð!Ñ	"×	'Ñ	'¨°¨Ó	7Ð7Ø
�Ñ
×
 Ñ
  ×!;Ñ!;Ó
<ñ	=à
Ð&Ñ
'×
-Ñ
-Ó
/ñ	0ñ÷ �dƒfð	 
ô
 �L‰L˜Ð/Ñ0×4Ñ4Ó6Ó7×AÑAÓC€Eä$¤X¨h×.CÑ.CÄSÈÐO_ÑI`ÓEaÓ%bÓc€IÜ! )¨UÓ3€KÜ�_‰_˜X×3Ñ3Ð6OÑOÓP€FØ�}Ð&8Ð9Ñ:×AÑAÐK]Ð_nÐJoÐAÓp€HÜ˜#Ÿ'™'Ð"4°bÓ9Ó:€NØ×ÑÜ˜×-Ñ-Ó.Ø#Ð$=Ñ>Ø# OÑ4Ø˜{Ñ+ñ	ô ô -¨^¸UÓCÐØ%×2Ñ2°8Ó<€NÜfh×flÑfl€N×Ñ�~Ð&AÑB×EÑEÀaÓHÐJbÐbÑcä�?Ð#3Ñ4Ó5€GÜØ1Ü�o kÑ2Ó3Ü" ?Ð3IÑ#JÓKÜ�Ð'7Ñ8Ó9ô	€Fô & e¨WÑ?¸Ñ?€KÜ˜_×0Ñ0Ð1GÈÓQÓRÐÜ-ØÐ ðä˜/Ð*<Ñ=Ó>Ü˜OÐ,?Ñ@ÓAÜ˜×,Ñ,Ð-@À#ÓFÓGÜ�oÐ&>Ñ?Ó@ñð ñ€Iô —‘ ×!7Ñ!7Ð:[Ñ![Ó\€JÜ! *¨k¸>ÓJ€Hà#,Ø +Ø#1Ø#.×#6Ñ#6Ø!*×!9Ñ!9Ø'ñ€Fð —|‘|–~‰ˆˆeÜˆe�T˜8Õ$ð &ä	ˆ+×
#Ñ
#Ð%;¸XÔFÜ	ˆ+×
$Ñ
$Ð&=¸xÔHÜ	ˆ+�.‰.˜+ xÔ0Ü	ˆ)×
 Ñ
 ×
/Ñ
/Ð1LÈhÔWÜ�H˜fÔ%ô *Ø—‘“×'Ñ'Ó)Ü˜i›.ØHS×HYÒHY”s˜; }Ñ5×=Ñ=Ó?Ô@Ð_`Ü˜nÐ-HÑI×LÑLÈQÓO×SÑSÓUÓVØ#×(Ñ(Ø%×,Ñ,Ø&×.Ñ.ØXa×XpÑXp×XvÒXv”s˜9×3Ñ3Ð4DÑE×MÑMÓOÔPÐ|}Ü Ð0BÑ CÓDØMV×M^ÑM^×MdÑMdÔMfÔgÑMf¹\¸TÀ6˜4¤¤u¨V£}°aÓ!8Ñ8ÐMfÒgÙV\Ó]ÑV\Èd�Dœ#˜h×4Ñ4¸$¸¸xÐ7HÑHÓIÑIÐV\Ñ]ñ€Gð ×ÑÐ0Ñ0×<Ñ<Ü�
‰
�7¨°qÔ9ÀGð =ô ô �(˜G [×%8Ñ%8¸)×:KÑ:KÈXÔVØ€Nùó hùÚ]s   Ó) VÔ#V)r   r   r   r�   Úreturnr   )r   úpd.DataFramer   r�   r   r   r%  ÚNone)rS   r&  rT   zpd.Timestampr%  r&  )rq   r&  rr   r&  rs   r&  r%  r&  )r   r   r†   zdict[str, pd.DataFrame]r%  r'  )r   Úobjectr%  r�   )r   r   r²   údict[str, Any]r³   r&  r´   z	pd.Seriesrµ   r&  r%  r'  )r   r   r  r   r%  r)  )!Ú
__future__r   r  Úpathlibr   rô   Útypingr   r   Únumpyro   ÚpandasrD   Úconfigr   Úfactor_datasetr   Ú
factor_labr	   r
   rË   r   Útext_researchr   rQ   r   r    rX   r{   rŠ   rŽ   r»   r$  r    r   r   Ú<module>r3     sŸ   ðÝ "ã Ý Û Ý ã Û Û å Ý 6ß JÝ 3Ý /ð Ð ó7ó
\ó
+ó8fó .ó<ð7eØð7eàð7eð !ð7eð ð	7eð
 ð7eð 
ó7eôtUr   