§
    í¿jÎ(  ã                  óš  — 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 ddl	m
Z
mZ ddlZddlmc mZ ddlmZ  ej        d¦  «        Zdd	d
dddœZg d¢Z ej        d¬¦  «        d%d„¦   «         Z ej        d¬¦  «        d&d„¦   «         Z ej        d¬¦  «        d'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"d+d$„Z#dS ),zõ
Unit Tests for Cross-Language Map Styles Catalog Synchronization.
Verifies 100% parity across server/world/map_style_catalog.py, data/map_styles.db,
and client/webapp/js/data/map_style_catalog.js, including legacy biome backward compatibility.
é    )ÚannotationsN)ÚPath)ÚAnyÚDict©ÚMapStyleServicez^#[0-9a-fA-F]{6}$)ÚBLEACHED_BONE_CANYONÚSTY_11_HEM_NUI_XUONG_TRANG)ÚSAVAGE_MANGROVE_SWAMPÚSTY_06_BAI_THA_MA_NGAP_MAN)ÚCRIMSON_BLOOD_FORESTÚSTY_02_HUYET_SAT_LAM)ÚOUTCAST_MINE_SHAFTSÚSTY_16_MO_QUANG_LUU_DAY)ÚCORRUPTED_FIEND_RUINSÚSTY_21_PHE_TICH_MA_THAN)é   é   é   é   é   )ÚHOANG_DA_DA_NGOAIÚDAM_LAY_DOC_CHUONGÚHEM_NUI_COT_MACÚHAM_MO_TA_QUAIÚTHAN_DIEN_PHE_TICHÚHU_KHONG_DI_BIENÚmodule)ÚscopeÚreturnr   c                 ól   — t          t          ¦  «                             ¦   «         j        j        j        S )N)r   Ú__file__ÚresolveÚparent© ó    ú@C:\Projects\FreeExile\tests\unit\test_map_styles_catalog_sync.pyÚproject_rootr(   (   s#   € å•‰>Œ>×!Ò!Ñ#Ô#Ô*Ô1Ô8Ð8r&   r(   r   c                ó2   — | dz  dz  }t          |¬¦  «        S )NÚdatazmap_styles.db)Údb_pathr   )r(   Údb_files     r'   Ú
db_servicer-   -   s"   € à˜VÑ# oÑ5€GÝ 7Ð+Ñ+Ô+Ð+r&   úDict[str, Any]c                óš  — | dz  dz  dz  dz  dz  }|                      ¦   «         sJ d|› �¦   «         ‚d}t          j        dd	d
|gt          | ¦  «        dddd¬¦  «        }d„ |j        pd                     ¦   «         D ¦   «         }t          |¦  «        dk    sJ d|j        › d|j        › d�¦   «         ‚t          j	        |d         ¦  «        S )zSExecute Node.js to import and serialize client/webapp/js/data/map_style_catalog.js.ÚclientÚwebappÚjsr*   zmap_style_catalog.jszClient catalog file missing: a   
    import catalog from './client/webapp/js/data/map_style_catalog.js';
    const payload = {
        map_styles: catalog.MAP_STYLES,
        code_to_style: catalog.BIOME_CODE_TO_STYLE_ID,
        legacy_map: catalog.LEGACY_BIOME_MAP
    };
    console.log(JSON.stringify(payload));
    Únodez--input-type=modulez-eTzutf-8)ÚcwdÚcapture_outputÚtextÚencodingÚcheckc                ó„   — g | ]=}|                      ¦   «                              d ¦  «        ¯)|                      ¦   «         ‘Œ>S )Ú{)ÚstripÚ
startswith)Ú.0Úlines     r'   ú
<listcomp>z#js_catalog_data.<locals>.<listcomp>K   sA   € ÐnÐnÐn TÐQU×Q[ÒQ[ÑQ]ÔQ]×QhÒQhÐilÑQmÔQmÐn�D—J’J‘L”LÐnÐnÐnr&   Ú r   zNo JSON output from Node: z
 (stderr: ú)éÿÿÿÿ)
Úis_fileÚ
subprocessÚrunÚstrÚstdoutÚ
splitlinesÚlenÚstderrÚjsonÚloads)r(   Újs_fileÚscriptÚprocÚstdout_liness        r'   Újs_catalog_datarQ   3   s  € ð ˜XÑ%¨Ñ0°4Ñ7¸&Ñ@ÐCYÑY€GØ�?Š?ÑÔÐGÐGÐG¸gÐGÐGÑGÔGÐð€Fõ Œ>Ø	Ð&¨¨fÐ5Ý�ÑÔØØØØðñ ô €Dð oÐn¨d¬kÐ.?¸R×-KÒ-KÑ-MÔ-MÐnÑnÔn€LÝˆ|ÑÔ˜qÒ Ð Ð Ð"d¸t¼{Ð"dÐ"dÐVZÔVaÐ"dÐ"dÐ"dÑ Ô Ð ÝŒ:�l 2Ô&Ñ'Ô'Ð'r&   r-   ÚNonec                ó¨   — t          j        ¦   «         }|                      ¦   «         }t          |¦  «        dk    sJ ‚t          |¦  «        dk    sJ ‚dS )zAVerify that Python catalog and DB both contain exactly 30 styles.é   N)Ú
py_catalogÚlist_stylesrI   )r-   Ú	py_stylesÚ	db_styless      r'   Ú-test_python_catalog_and_db_style_count_parityrY   P   sU   € åÔ&Ñ(Ô(€IØ×&Ò&Ñ(Ô(€IÝˆy‰>Œ>˜RÒÐÐÐÝˆy‰>Œ>˜RÒÐÐÐÐÐr&   c                óF  — d„ |                       ¦   «         D ¦   «         }t          j        }t          |                     ¦   «         ¦  «        t          |                     ¦   «         ¦  «        k    sJ ‚|                     ¦   «         D �]š\  }}||         }|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j	        |j	        k    sJ ‚|j
        |j
        k    sJ ‚|j        j        |j        j        k    sJ ‚|j        j        |j        j        k    sJ ‚|j        j        |j        j        k    sJ ‚|j        j        |j        j        k    sJ ‚|j        j        |j        j        k    sJ ‚|j        j        |j        j        k    sJ ‚t'          j        |j        j        ¦  «        |j        j        k    sJ ‚t'          j        |j        j        ¦  «        |j        j        k    sJ ‚|j        j        |j        j        k    sJ ‚|j        |j        k    sJ ‚�ŒœdS )zIVerify 1-to-1 attribute match between Python catalog and SQLite database.c                ó   — i | ]
}|j         |“ŒS r%   )Ústyle_id©r=   Úss     r'   ú
<dictcomp>zFtest_python_catalog_and_db_style_attributes_parity.<locals>.<dictcomp>Z   s   € ÐAÐAÐA 1�”˜QÐAÐAÐAr&   N)rV   rU   ÚMAP_STYLES_BY_IDÚsetÚkeysÚitemsÚ
biome_codeÚname_viÚname_enÚtheme_categoryÚtheme_category_nameÚpaletteÚfloorÚwallÚpathÚliquidÚambientÚlightingÚambient_hexÚpytestÚapproxÚfog_densityÚhazardÚslow_factorÚdpsÚlegacy_alias)r-   rX   rW   Ús_idÚpy_sÚdb_ss         r'   Ú2test_python_catalog_and_db_style_attributes_parityr{   X   s  € àAÐA¨
×(>Ò(>Ñ(@Ô(@ÐAÑAÔA€IÝÔ+€Iåˆy�~Š~ÑÔÑ Ô ¥C¨	¯ªÑ(8Ô(8Ñ$9Ô$9Ò9Ð9Ð9Ð9à—o’oÑ'Ô'ð 6ñ 6‰
ˆˆdØ˜ŒˆØŒ $¤/Ò1Ð1Ð1Ð1ØŒ|˜tœ|Ò+Ð+Ð+Ð+ØŒ|˜tœ|Ò+Ð+Ð+Ð+ØÔ" dÔ&9Ò9Ð9Ð9Ð9ØÔ'¨4Ô+CÒCÐCÐCÐCØŒ|Ô! T¤\Ô%7Ò7Ð7Ð7Ð7ØŒ|Ô  D¤LÔ$5Ò5Ð5Ð5Ð5ØŒ|Ô  D¤LÔ$5Ò5Ð5Ð5Ð5ØŒ|Ô" d¤lÔ&9Ò9Ð9Ð9Ð9ØŒ|Ô# t¤|Ô';Ò;Ð;Ð;Ð;ØŒ}Ô(¨D¬MÔ,EÒEÐEÐEÐEÝŒ}˜Tœ]Ô6Ñ7Ô7¸4¼=Ô;TÒTÐTÐTÐTÝŒ}˜Tœ[Ô4Ñ5Ô5¸¼Ô9PÒPÐPÐPÐPØŒ{Œ $¤+¤/Ò1Ð1Ð1Ð1ØÔ  DÔ$5Ò5Ð5Ð5Ð5Ñ5ð!6ð 6r&   c                ó  — t          j        ¦   «         D �]r}t          j        |¦  «        }|                      |¦  «        }t          |¦  «        dk    sJ ‚t          |¦  «        dk    sJ ‚t	          ||¦  «        D ]M\  }}|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j        |j        k    sJ ‚ŒNt          j	        |¦  «        }|  	                    |¦  «        }t          |¦  «        dk    sJ ‚t          |¦  «        t          |¦  «        k    sJ ‚t	          ||¦  «        D ]M\  }}	|j
        |	j
        k    sJ ‚|j        |	j        k    sJ ‚t          j        |j        ¦  «        |	j        k    sJ ‚ŒN�ŒtdS )zPVerify tile mappings and props count and attributes match between Python and DB.é   r   N)rU   Úlist_available_stylesÚget_tiles_for_stylerI   ÚzipÚ	tile_codeÚtile_type_nameÚtexture_pathÚprocedural_fallback_colorÚget_props_for_styleÚprop_idÚplacement_rulerq   rr   Úspawn_weight)
r-   rx   Úpy_tilesÚdb_tilesÚptÚdtÚpy_propsÚdb_propsÚppÚdps
             r'   Ú1test_python_catalog_and_db_tiles_and_props_parityr‘   r   s½  € åÔ0Ñ2Ô2ð Eñ EˆÝÔ1°$Ñ7Ô7ˆØ×1Ò1°$Ñ7Ô7ˆÝ�8‰}Œ} Ò"Ð"Ð"Ð"Ý�8‰}Œ} Ò"Ð"Ð"Ð"Ý˜( HÑ-Ô-ð 	Pð 	P‰FˆB�Ø”< 2¤<Ò/Ð/Ð/Ð/ØÔ$¨Ô(9Ò9Ð9Ð9Ð9Ø”? b¤oÒ5Ð5Ð5Ð5ØÔ/°2Ô3OÒOÐOÐOÐOÐOåÔ1°$Ñ7Ô7ˆØ×1Ò1°$Ñ7Ô7ˆÝ�8‰}Œ} Ò!Ð!Ð!Ð!Ý�8‰}Œ}¥ H¡¤Ò-Ð-Ð-Ð-Ý˜( HÑ-Ô-ð 	Eð 	E‰FˆB�Ø”: ¤Ò+Ð+Ð+Ð+ØÔ$¨Ô(9Ò9Ð9Ð9Ð9Ý”= ¤Ñ1Ô1°R´_ÒDÐDÐDÐDÐDñ	EðEð Er&   rQ   c                ó  — | d         }| d         }t          |¦  «        dk    sJ ‚t          |¦  «        dk    sJ ‚t          |                     ¦   «         ¦  «        t          t          j                             ¦   «         ¦  «        k    sJ ‚dS )zMVerify that client JS catalog defines exactly 30 styles and 30 code mappings.Ú
map_stylesÚcode_to_stylerT   N)rI   ra   rb   rU   r`   )rQ   Ú	js_stylesÚjs_codess      r'   Ú$test_js_catalog_style_count_and_keysr—   ‰   s„   € à Ô-€IØ˜Ô/€Håˆy‰>Œ>˜RÒÐÐÐÝˆx‰=Œ=˜BÒÐÐÐÝˆy�~Š~ÑÔÑ Ô ¥C­
Ô(C×(HÒ(HÑ(JÔ(JÑ$KÔ$KÒKÐKÐKÐKÐKÐKr&   c                óð  — | d         }t           j                             ¦   «         D �]M\  }}||v sJ d|› d�¦   «         ‚||         }|d         |j        k    sJ ‚|d         |j        k    sJ ‚|d         |j        k    sJ ‚|d         |j        k    sJ ‚|d         |j        k    sJ ‚|d	         }|d
         |j        j	        k    sJ ‚|d         |j        j
        k    sJ ‚|d         |j        j        k    sJ ‚|d         |j        j        k    sJ ‚|d         |j        j        k    sJ ‚t          j        |d         d         ¦  «        |j        j        k    sJ ‚|d         d         |j        j        k    sJ ‚�ŒOdS )zSVerify client JS styles match Python styles on id, biome_code, palettes, and rules.r“   zStyle z missing in JS catalogrd   re   rf   rg   rw   ri   rj   rk   rl   rm   rn   ro   rs   rt   rv   N)rU   r`   rc   rd   re   rf   rg   rw   ri   rj   rk   rl   rm   rn   rq   rr   ro   rs   rt   rv   )rQ   r•   rx   ry   Újs_sÚjs_pals         r'   Ú test_js_catalog_to_python_parityr›   “   s·  € à Ô-€Iå Ô1×7Ò7Ñ9Ô9ð 8ñ 8‰
ˆˆdØ�yÐ Ð Ð Ð"G¨4Ð"GÐ"GÐ"GÑ Ô Ð Ø˜Œˆà�LÔ! T¤_Ò4Ð4Ð4Ð4Ø�IŒ $¤,Ò.Ð.Ð.Ð.Ø�IŒ $¤,Ò.Ð.Ð.Ð.ØÐ$Ô%¨Ô)<Ò<Ð<Ð<Ð<Ø�NÔ# tÔ'8Ò8Ð8Ð8Ð8à�i”ˆØ�gŒ $¤,Ô"4Ò4Ð4Ð4Ð4Ø�fŒ~ ¤Ô!2Ò2Ð2Ð2Ð2Ø�fŒ~ ¤Ô!2Ò2Ð2Ð2Ð2Ø�hÔ 4¤<Ô#6Ò6Ð6Ð6Ð6Ø�iÔ  D¤LÔ$8Ò8Ð8Ð8Ð8åŒ}˜T *Ô-¨mÔ<Ñ=Ô=ÀÄÔAZÒZÐZÐZÐZØ�HŒ~˜eÔ$¨¬¬Ò7Ð7Ð7Ð7Ñ7ð%8ð 8r&   c                óR  — d„ |d                               ¦   «         D ¦   «         }|d         }t                                ¦   «         D ]à\  }\  }}t          j        |¦  «        }|€J ‚|j        |k    sJ ‚|j        |k    sJ ‚t          j        |         |k    sJ ‚t          j        |¦  «        j        |k    sJ ‚|                      |¦  «        }|€J ‚|j        |k    sJ ‚|j        |k    sJ ‚|  	                    |¦  «        j        |k    sJ ‚||         |k    sJ ‚||         |k    sJ ‚ŒádS )zRVerify codes 1-5 map to the 5 canonical biomes across Python, DB, and JS catalogs.c                ó4   — i | ]\  }}t          |¦  «        |“ŒS r%   )Úint)r=   ÚkÚvs      r'   r_   z=test_legacy_biomes_backward_compatibility.<locals>.<dictcomp>°   s$   € ÐOÐOÐO™d˜a •�A‘”˜ÐOÐOÐOr&   r”   Ú
legacy_mapN)
rc   ÚEXPECTED_LEGACY_MAPPINGSrU   Úget_map_style_by_coder\   rw   ÚLEGACY_BIOME_TO_STYLE_IDÚget_map_styleÚget_style_by_codeÚ	get_style)	r-   rQ   r–   Ú	js_legacyÚcodeÚlegacy_nameÚexpected_style_idÚpy_styleÚdb_styles	            r'   Ú)test_legacy_biomes_backward_compatibilityr®   ¬   s�  € ð PÐO o°oÔ&F×&LÒ&LÑ&NÔ&NÐOÑOÔO€HØ Ô-€Iå2J×2PÒ2PÑ2RÔ2Rð ;ð ;Ñ.ˆÑ.ˆ{Ð-åÔ3°DÑ9Ô9ˆØÐ#Ð#Ð#ØÔ Ð$5Ò5Ð5Ð5Ð5ØÔ$¨Ò3Ð3Ð3Ð3ÝÔ2°;Ô?ÐCTÒTÐTÐTÐTÝÔ'¨Ñ4Ô4Ô=ÐARÒRÐRÐRÐRð ×/Ò/°Ñ5Ô5ˆØÐ#Ð#Ð#ØÔ Ð$5Ò5Ð5Ð5Ð5ØÔ$¨Ò3Ð3Ð3Ð3Ø×#Ò# KÑ0Ô0Ô9Ð=NÒNÐNÐNÐNð ˜Œ~Ð!2Ò2Ð2Ð2Ð2Ø˜Ô%Ð):Ò:Ð:Ð:Ð:Ð:ð%;ð ;r&   c                óú  ‡— |d                               ¦   «         }t          D ]×Št          j        ‰¦  «        }t	          |¦  «        dk    sJ d‰› dt	          |¦  «        › d�¦   «         ‚ˆfd„|                      ¦   «         D ¦   «         }t	          |¦  «        dk    sJ d‰› dt	          |¦  «        › d�¦   «         ‚ˆfd„|D ¦   «         }t	          |¦  «        dk    sJ d	‰› dt	          |¦  «        › d�¦   «         ‚ŒØd
S )zHVerify 6 themes have exactly 5 styles each in Python, DB, and Client JS.r“   r   zPython theme z has z styles, expected 5c                ó*   •— g | ]}|j         ‰k    ¯|‘ŒS r%   ©rg   ©r=   r^   Úthemes     €r'   r?   zItest_thematic_categories_distribution_across_catalogs.<locals>.<listcomp>Ò   s&   ø€ ÐUÐUÐU˜!¸1Ô;KÈuÒ;TÐ;T�AÐ;TÐ;TÐ;Tr&   z	DB theme c                ó,   •— g | ]}|d          ‰k    ¯|‘ŒS r±   r%   r²   s     €r'   r?   zItest_thematic_categories_distribution_across_catalogs.<locals>.<listcomp>Õ   s)   ø€ ÐIÐIÐI˜!¨AÐ.>Ô,?À5Ò,HÐ,H�AÐ,HÐ,HÐ,Hr&   z	JS theme N)ÚvaluesÚEXPECTED_THEMESrU   Úlist_styles_by_categoryrI   rV   )r-   rQ   r•   Úpy_groupÚdb_groupÚjs_groupr³   s         @r'   Ú5test_thematic_categories_distribution_across_catalogsr»   È   s4  ø€ ð   Ô-×4Ò4Ñ6Ô6€Iå ð ^ð ^ˆÝÔ5°eÑ<Ô<ˆÝ�8‰}Œ} Ò!Ð!Ð!Ð#a°5Ð#aÐ#a½sÀ8¹}¼}Ð#aÐ#aÐ#aÑ!Ô!Ð!àUÐUÐUÐU˜z×5Ò5Ñ7Ô7ÐUÑUÔUˆÝ�8‰}Œ} Ò!Ð!Ð!Ð#]¨uÐ#]Ð#]½3¸x¹=¼=Ð#]Ð#]Ð#]Ñ!Ô!Ð!àIÐIÐIÐI˜yÐIÑIÔIˆÝ�8‰}Œ} Ò!Ð!Ð!Ð#]¨uÐ#]Ð#]½3¸x¹=¼=Ð#]Ð#]Ð#]Ñ!Ô!Ð!Ð!ð^ð ^r&   c                 óp  — t          j        d¦  «        €J ‚t          j        d¦  «        €J ‚t          j        d¦  «        j        dk    sJ ‚t          j        d¦  «        j        dk    sJ ‚t          j        d¦  «        �J ‚t          j        d¦  «        �J ‚t          j        ¦   «         } t          | ¦  «        dk    sJ ‚t          t          | ¦  «        ¦  «        dk    sJ ‚t          j	        ¦   «         }t          |¦  «        dk    sJ ‚d„ |D ¦   «         t          t          dd¦  «        ¦  «        k    sJ ‚dS )	zFVerify all lookup helper methods in server/world/map_style_catalog.py.ÚSTY_01_HOANG_MANG_CO_LONé   r   é   rT   c                ó   — g | ]	}|j         ‘Œ
S r%   )rd   r]   s     r'   r?   z5test_python_catalog_query_helpers.<locals>.<listcomp>ì   s   € Ð1Ð1Ð1˜QˆAŒLÐ1Ð1Ð1r&   r   )rU   r¥   r§   r£   r\   r¦   r~   rI   ra   rV   ÚlistÚrange)Úall_idsÚordered_styless     r'   Ú!test_python_catalog_query_helpersrÅ   Ù   sF  € õ Ô#Ð$=Ñ>Ô>ÐJÐJÐJÝÔÐ 9Ñ:Ô:ÐFÐFÐFõ Ô+¨AÑ.Ô.Ô7Ð;TÒTÐTÐTÐTÝÔ'¨Ñ*Ô*Ô3Ð7PÒPÐPÐPÐPÝÔ+¨AÑ.Ô.Ð6Ð6Ð6ÝÔ+¨BÑ/Ô/Ð7Ð7Ð7õ Ô.Ñ0Ô0€GÝˆw‰<Œ<˜2ÒÐÐÐÝ�s�7‰|Œ|ÑÔ Ò"Ð"Ð"Ð"åÔ+Ñ-Ô-€NÝˆ~ÑÔ "Ò$Ð$Ð$Ð$Ø1Ð1 .Ð1Ñ1Ô1µT½%ÀÀ2¹,¼,Ñ5GÔ5GÒGÐGÐGÐGÐGÐGr&   c            	     óB  — t          j        ¦   «         D ]Š} d| j        j        fd| j        j        fd| j        j        fd| j        j        fd| j        j        fd| j        j	        ffD ]7\  }}t                               |¦  «        sJ d|› d|› d	| j        › �¦   «         ‚Œ8Œ‹d
S )zOVerify that all color strings across all 30 styles conform strictly to #RRGGBB.rj   rk   rl   rm   rn   rp   zInvalid HEX 'z' in z of N)rU   rV   ri   rj   rk   rl   rm   rn   ro   rp   Ú	HEX_REGEXÚmatchr\   )r^   Ú
color_nameÚhex_vals      r'   Ú,test_hex_colors_validity_across_all_palettesrË   ï   sÓ   € åÔ#Ñ%Ô%ð 	hð 	hˆà�a”i”oÐ&Ø�Q”Y”^Ð$Ø�Q”Y”^Ð$Ø�q”yÔ'Ð(Ø˜œ	Ô)Ð*Ø˜AœJÔ2Ð3ð$
ð 	hð 	hÑˆJ˜õ —?’? 7Ñ+Ô+ÐgÐgÐ-g¸WÐ-gÐ-gÈ:Ð-gÐ-gÐ[\Ô[eÐ-gÐ-gÑgÔgÐ+Ðgð	hð	hð 	hr&   )r    r   )r(   r   r    r   )r(   r   r    r.   )r-   r   r    rR   )rQ   r.   r    rR   )r-   r   rQ   r.   r    rR   )r    rR   )$Ú__doc__Ú
__future__r   rK   ÚreÚsqlite3rD   Úpathlibr   Útypingr   r   rq   Úserver.world.map_style_catalogÚworldÚmap_style_catalogrU   Úserver.world.map_style_servicer   ÚcompilerÇ   r¢   r¶   Úfixturer(   r-   rQ   rY   r{   r‘   r—   r›   r®   r»   rÅ   rË   r%   r&   r'   ú<module>rØ      sO  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø 	€	€	€	Ø €€€Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ð Ð à €€€à 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø :Ð :Ð :Ð :Ð :Ð :àˆBŒJÐ+Ñ,Ô,€	ð >Ø>Ø7Ø9Ø;ðð Ð ðð ð €ð €„�hÐÑÔð9ð 9ð 9ñ  Ôð9ð €„�hÐÑÔð,ð ,ð ,ñ  Ôð,ð
 €„�hÐÑÔð(ð (ð (ñ  Ôð(ð8 ð  ð  ð  ð6ð 6ð 6ð 6ð4Eð Eð Eð Eð.Lð Lð Lð Lð8ð 8ð 8ð 8ð2;ð ;ð ;ð ;ð8^ð ^ð ^ð ^ð"Hð Hð Hð Hð,hð hð hð hð hð hr&   