§
    @L¾j%-  ã                   óŠ  — d Z ddlZddlZddlZddlZddlmZ  ee¦  «                             ¦   «         j	        j	        j	        Z
e
dz  Z ee¦  «        ej        vr$ej                             d ee¦  «        ¦  «          ee
¦  «        ej        vr$ej                             d ee
¦  «        ¦  «         ddlmZ ddlmZ e
dz  dz  Zed	z  d
z  dz  Zed	z  dz  dz  Zed	z  dz  dz  Zedz  dz  Z G d„ dej        ¦  «        Z G d„ dej        ¦  «        Z G d„ dej        ¦  «        Zedk    r ej        ¦   «          dS dS )aœ  
Unit and Integration Test Suite for FreeExile Milestone 2 (R2: Waypoint Safe Radius & Healing):
- Waypoint dataclass safe_radius field default 8.0
- Server ZoneEngine.is_in_waypoint_safe_radius() logic
- Server ZoneEngine.validate_monster_spawn() coordinate-aware safe radius rejection
- Client wilderness_zone_packs.js ZONE_WAYPOINTS registry and isInWaypointSafeRadius()
- Client monster_system.js safe zone leashing, 2% maxHp/sec healing, and attack suppression
- Client initial monster placement outside safe radius
- Client world_renderer.js safe zone indicator
- Line count constraints: monster_system.js <= 490, world_renderer.js <= 500, zone_engine.py <= 500
é    N)ÚPathÚserver)ÚWaypoint)Ú
ZoneEngineÚclientÚwebappÚjsÚdatazwilderness_zone_packs.jsÚenginezmonster_system.jszworld_renderer.jsÚworldzzone_engine.pyc                   óD   — e Zd Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
S )ÚTestWaypointSafeRadiusServerc                 ó,   — t          ¦   «         | _        d S )N)r   r   ©Úselfs    ú=C:\Projects\FreeExile\tests\unit\test_waypoint_safe_radius.pyÚsetUpz"TestWaypointSafeRadiusServer.setUp%   s   € Ý ‘l”lˆŒˆˆó    c                 ód   — t          ddddd¬¦  «        }|                      |j        d¦  «         dS )	z:Verifies Waypoint dataclass has safe_radius default = 8.0.Úwp_testzTest WaypointÚ	zone_testç      $@ç      4@)Úwaypoint_idÚnameÚzone_idÚxÚyç       @N©r   ÚassertEqualÚsafe_radius©r   Úwps     r   Ú+test_waypoint_dataclass_safe_radius_defaultzHTestWaypointSafeRadiusServer.test_waypoint_dataclass_safe_radius_default(   sE   € åØ!Ø ØØØð
ñ 
ô 
ˆð 	×Ò˜œ¨Ñ-Ô-Ð-Ð-Ð-r   c                 óf   — t          dddddd¬¦  «        }|                      |j        d¦  «         dS )	z7Verifies Waypoint dataclass accepts custom safe_radius.Ú	wp_customzCustom Waypointr   r   r   g      .@)r   r   r   r   r   r"   Nr    r#   s     r   Ú*test_waypoint_dataclass_custom_safe_radiuszGTestWaypointSafeRadiusServer.test_waypoint_dataclass_custom_safe_radius3   sH   € åØ#Ø"ØØØØð
ñ 
ô 
ˆð 	×Ò˜œ¨Ñ.Ô.Ð.Ð.Ð.r   c                 óþ   — | j                              d¦  «        }|                      t          |j        ¦  «        dk    ¦  «         |j                             ¦   «         D ]}|                      |j        d¦  «         ŒdS )zFVerifies all registered canonical waypoints in zones have safe_radius.Úzone_tang_kiem_nhair   r   N)r   Úget_zoneÚ
assertTrueÚlenÚ	waypointsÚvaluesr!   r"   )r   Úzoner$   s      r   Ú)test_canonical_waypoints_have_safe_radiuszFTestWaypointSafeRadiusServer.test_canonical_waypoints_have_safe_radius?   s{   € àŒ{×#Ò#Ð$9Ñ:Ô:ˆØ�Š�˜DœNÑ+Ô+¨aÒ/Ñ0Ô0Ð0Ø”.×'Ò'Ñ)Ô)ð 	2ð 	2ˆBØ×Ò˜Rœ^¨SÑ1Ô1Ð1Ð1ð	2ð 	2r   c                 óX  — d}| j                              |¦  «        }t          |j                             ¦   «         ¦  «        d         }|                      | j                              ||j        |j        ¦  «        ¦  «         |                      | j                              ||j        dz   |j        dz   ¦  «        ¦  «         |                      | j                              ||j        dz   |j        ¦  «        ¦  «         |  	                    | j                              ||j        dz   |j        dz   ¦  «        ¦  «         |  	                    | j                              ||j        dz   |j        dz   ¦  «        ¦  «         |  	                    | j                              dd	d	¦  «        ¦  «         d
S )zKVerifies is_in_waypoint_safe_radius detects coordinates inside and outside.r*   r   g      @g      @r   g      @g      9@Úzone_non_existentg        N)
r   r+   Úlistr.   r/   r,   Úis_in_waypoint_safe_radiusr   r   ÚassertFalse)r   r   r0   r$   s       r   Ú)test_is_in_waypoint_safe_radius_detectionzFTestWaypointSafeRadiusServer.test_is_in_waypoint_safe_radius_detectionF   s{  € à'ˆØŒ{×#Ò# GÑ,Ô,ˆÝ�$”.×'Ò'Ñ)Ô)Ñ*Ô*¨1Ô-ˆð 	�Š˜œ×>Ò>¸wÈÌÈbÌdÑSÔSÑTÔTÐTð 	�Š˜œ×>Ò>¸wÈÌÈsÉ
ÐTVÔTXÐ[^ÑT^Ñ_Ô_Ñ`Ô`Ð`ð 	�Š˜œ×>Ò>¸wÈÌÈsÉ
ÐTVÔTXÑYÔYÑZÔZÐZð 	×Ò˜œ×?Ò?ÀÈÌÐPSÉÐUWÔUYÐ\_ÑU_Ñ`Ô`ÑaÔaÐað 	×Ò˜œ×?Ò?ÀÈÌÐPTÉÐVXÔVZÐ]aÑVaÑbÔbÑcÔcÐcð 	×Ò˜œ×?Ò?Ð@SÐUXÐZ]Ñ^Ô^Ñ_Ô_Ð_Ð_Ð_r   c                 ó0  — d}| j                              |¦  «        }t          |j                             ¦   «         ¦  «        d         }| j                              |d|j        |j        ¬¦  «        \  }}|                      |¦  «         |  	                    d|¦  «         |  	                    |j
        |¦  «         | j                              |d|j        dz   |j        dz   ¬¦  «        \  }}|                      |¦  «         |  	                    d|¦  «         dS )zVVerifies validate_monster_spawn rejects hostile mob spawn inside waypoint safe radius.r*   r   F©Úis_dummyr   r   u   an toÃ ng       @N)r   r+   r4   r.   r/   Úvalidate_monster_spawnr   r   r6   ÚassertInr   ©r   r   r0   r$   ÚallowedÚreasons         r   Ú6test_validate_monster_spawn_rejects_inside_safe_radiuszSTestWaypointSafeRadiusServer.test_validate_monster_spawn_rejects_inside_safe_radius^   s  € à'ˆØŒ{×#Ò# GÑ,Ô,ˆÝ�$”.×'Ò'Ñ)Ô)Ñ*Ô*¨1Ô-ˆð œ+×<Ò<¸WÈuÐXZÔX\Ð`bÔ`dÐ<ÑeÔe‰ˆ�Ø×Ò˜Ñ!Ô!Ð!Ø�Š�j &Ñ)Ô)Ð)Ø�Š�b”g˜vÑ&Ô&Ð&ð œ+×<Ò<¸WÈuÐXZÔX\Ð_bÑXbÐfhÔfjÐmpÑfpÐ<ÑqÔq‰ˆ�Ø×Ò˜Ñ!Ô!Ð!Ø�Š�j &Ñ)Ô)Ð)Ð)Ð)r   c                 óN  — d}| j                              |¦  «        }t          |j                             ¦   «         ¦  «        d         }| j                              |d|j        dz   |j        dz   ¬¦  «        \  }}|                      |¦  «         |  	                    d|¦  «         dS )zVVerifies validate_monster_spawn allows hostile mob spawn outside waypoint safe radius.r*   r   Fr   r9   u
   há»£p lá»‡N©
r   r+   r4   r.   r/   r;   r   r   r,   r<   r=   s         r   Ú6test_validate_monster_spawn_allows_outside_safe_radiuszSTestWaypointSafeRadiusServer.test_validate_monster_spawn_allows_outside_safe_radiuso   s    € à'ˆØŒ{×#Ò# GÑ,Ô,ˆÝ�$”.×'Ò'Ñ)Ô)Ñ*Ô*¨1Ô-ˆð œ+×<Ò<¸WÈuÐXZÔX\Ð_cÑXcÐgiÔgkÐnrÑgrÐ<ÑsÔs‰ˆ�Ø�Š˜Ñ Ô Ð Ø�Š�l FÑ+Ô+Ð+Ð+Ð+r   c                 óB  — d}| j                              |¦  «        }t          |j                             ¦   «         ¦  «        d         }| j                              |d|j        |j        ¬¦  «        \  }}|                      |¦  «         |  	                    d|¦  «         dS )zGVerifies Target Dummy is allowed to spawn even at waypoint coordinates.r*   r   Tr9   zTarget DummyNrB   r=   s         r   ÚBtest_validate_monster_spawn_allows_target_dummy_inside_safe_radiusz_TestWaypointSafeRadiusServer.test_validate_monster_spawn_allows_target_dummy_inside_safe_radiusz   s’   € à'ˆØŒ{×#Ò# GÑ,Ô,ˆÝ�$”.×'Ò'Ñ)Ô)Ñ*Ô*¨1Ô-ˆàœ+×<Ò<¸WÈtÐWYÔW[Ð_aÔ_cÐ<ÑdÔd‰ˆ�Ø�Š˜Ñ Ô Ð Ø�Š�n fÑ-Ô-Ð-Ð-Ð-r   c                 óÎ   — | j                              d¦  «        \  }}|                      |¦  «         | j                              d¦  «        \  }}|                      |¦  «         dS )zSVerifies callers passing only (zone_id, is_dummy) continue to function identically.r*   Úzone_boundless_sanctuaryN)r   r;   r,   r6   )r   r>   Ú_Úallowed_sanctuarys       r   Ú2test_validate_monster_spawn_backward_compatibilityzOTestWaypointSafeRadiusServer.test_validate_monster_spawn_backward_compatibility„   se   € à”[×7Ò7Ð8MÑNÔN‰
ˆ�Ø�Š˜Ñ Ô Ð à#œ{×AÒAÐB\Ñ]Ô]ÑÐ˜1Ø×ÒÐ*Ñ+Ô+Ð+Ð+Ð+r   N)Ú__name__Ú
__module__Ú__qualname__r   r%   r(   r1   r7   r@   rC   rE   rJ   © r   r   r   r   $   sž   € € € € € ð#ð #ð #ð	.ð 	.ð 	.ð
/ð 
/ð 
/ð2ð 2ð 2ð`ð `ð `ð0*ð *ð *ð"	,ð 	,ð 	,ð.ð .ð .ð,ð ,ð ,ð ,ð ,r   r   c                   óH   — e Zd Zed„ ¦   «         Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
dS )	ÚTestWaypointSafeRadiusClientc                 óÆ   — t                                d¬¦  «        | _        t                               d¬¦  «        | _        t
                               d¬¦  «        | _        d S )Núutf-8©Úencoding)ÚWILDERNESS_PACKS_JSÚ	read_textÚpacks_js_contentÚMONSTER_SYSTEM_JSÚmonster_js_contentÚWORLD_RENDERER_JSÚrenderer_js_content)Úclss    r   Ú
setUpClassz'TestWaypointSafeRadiusClient.setUpClassŽ   sS   € å2×<Ò<ÀgÐ<ÑNÔNˆÔÝ!2×!<Ò!<ÀgÐ!<Ñ!NÔ!NˆÔÝ"3×"=Ò"=ÀwÐ"=Ñ"OÔ"OˆÔÐÐr   c                 óÞ   — |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         dS )zTVerifies wilderness_zone_packs.js exports ZONE_WAYPOINTS and isInWaypointSafeRadius.zexport const ZONE_WAYPOINTSz&export function isInWaypointSafeRadiusz&window.ZONE_WAYPOINTS = ZONE_WAYPOINTSz6window.isInWaypointSafeRadius = isInWaypointSafeRadiusN)r<   rW   r   s    r   Ú1test_wilderness_packs_exports_registry_and_helperzNTestWaypointSafeRadiusClient.test_wilderness_packs_exports_registry_and_helper”   si   € à�ŠÐ3°TÔ5JÑKÔKÐKØ�ŠÐ>ÀÔ@UÑVÔVÐVØ�ŠÐ>ÀÔ@UÑVÔVÐVØ�ŠÐNÐPTÔPeÑfÔfÐfÐfÐfr   c                 ó`  — d}t          j        ddd|gddt          t          ¦  «        d¬¦  «        }d„ |j                             ¦   «         D ¦   «         }|d         }d	d
l}|                     |¦  «        }|                      |d         d¦  «         |  	                    |d         d¦  «         d
S )zPVerifies isInWaypointSafeRadius(0, 0) is true and (20, 20) is false via Node.js.zêimport { isInWaypointSafeRadius } from './client/webapp/js/data/wilderness_zone_packs.js';const atOrigin = isInWaypointSafeRadius(0, 0);const farAway = isInWaypointSafeRadius(20, 20);console.log(JSON.stringify({ atOrigin, farAway }));Únodez--input-type=modulez-eT)Úcapture_outputÚtextÚcwdÚcheckc                 ó^   — g | ]*}|                      ¦   «         ¯|                      ¦   «         ‘Œ+S rN   )Ústrip)Ú.0Úlns     r   ú
<listcomp>z`TestWaypointSafeRadiusClient.test_client_is_in_waypoint_safe_radius_via_node.<locals>.<listcomp>«   s-   € ÐTÐTÐT rÈÏÊÉÌÐT˜Ÿš™
œ
ÐTÐTÐTr   éÿÿÿÿr   NÚatOriginz9isInWaypointSafeRadius(0, 0) must be true for spawn pointÚfarAwayz;isInWaypointSafeRadius(20, 20) must be false outside radius)
Ú
subprocessÚrunÚstrÚPROJECT_ROOTÚstdoutÚ
splitlinesÚjsonÚloadsr,   r6   )r   ÚscriptÚprocÚoutput_linesÚ	last_linert   r
   s          r   Ú/test_client_is_in_waypoint_safe_radius_via_nodezLTestWaypointSafeRadiusClient.test_client_is_in_waypoint_safe_radius_via_node›   sÉ   € ðBð 	õ Œ~ØÐ*¨D°&Ð9ØØÝ•LÑ!Ô!Øð
ñ 
ô 
ˆð UÐT¨T¬[×-CÒ-CÑ-EÔ-EÐTÑTÔTˆØ  Ô$ˆ	ØˆˆˆØ�zŠz˜)Ñ$Ô$ˆØ�Š˜˜ZÔ(Ð*eÑfÔfÐfØ×Ò˜˜iœÐ*gÑhÔhÐhÐhÐhr   c                 óÎ  — ddl }|                     d| j        |j        ¦  «        }|                      |¦  «         t          |                     d¦  «        ¦  «        }t          |                     d¦  «        ¦  «        }t          j        ||¦  «        }|  	                    |dd|› d|› d	|› d
�¦  «         |                     d| j        |j        ¦  «        }|                      |¦  «         t          |                     d¦  «        ¦  «        }t          |                     d¦  «        ¦  «        }t          j        ||¦  «        }	|  	                    |	dd|› d|› d	|	› d
�¦  «         dS )zZVerifies initial pack coordinates in zone_tang_kiem_nhai are outside 8.0 unit safe radius.r   NzVpackId:\s*'pack_tang_kiem_alpha'.*?leader:\s*\{[^}]+wx:\s*([-\d.]+),\s*wy:\s*([-\d.]+)é   é   r   zpack_tang_kiem_alpha at (z, z) dist z must be > 8.0zUpackId:\s*'pack_tang_kiem_beta'.*?leader:\s*\{[^}]+wx:\s*([-\d.]+),\s*wy:\s*([-\d.]+)zpack_tang_kiem_beta at ()
ÚreÚsearchrW   ÚDOTALLÚassertIsNotNoneÚfloatÚgroupÚmathÚhypotÚassertGreater)
r   r~   Úpack_alpha_matchÚwx_alphaÚwy_alphaÚ
dist_alphaÚpack_beta_matchÚwx_betaÚwy_betaÚ	dist_betas
             r   Ú3test_wilderness_packs_tang_kiem_outside_safe_radiuszPTestWaypointSafeRadiusClient.test_wilderness_packs_tang_kiem_outside_safe_radius²   s¨  € àˆ	ˆ	ˆ	ØŸ9š9Ð%~ð  AEô  AVð  XZô  Xañ  bô  bÐØ×ÒÐ-Ñ.Ô.Ð.ÝÐ)×/Ò/°Ñ2Ô2Ñ3Ô3ˆÝÐ)×/Ò/°Ñ2Ô2Ñ3Ô3ˆÝ”Z ¨(Ñ3Ô3ˆ
Ø×Ò˜: sÐ,ÈÐ,Ð,ÐT\Ð,Ð,ÐeoÐ,Ð,Ð,ñ  	Aô  	Að  	AàŸ)š)Ð$|ð  Cô  Tð  VXô  V_ñ  `ô  `ˆØ×Ò˜_Ñ-Ô-Ð-Ý˜×-Ò-¨aÑ0Ô0Ñ1Ô1ˆÝ˜×-Ò-¨aÑ0Ô0Ñ1Ô1ˆÝ”J˜w¨Ñ0Ô0ˆ	Ø×Ò˜9 cÐ+zÀgÐ+zÐ+zÐQXÐ+zÐ+zÐajÐ+zÐ+zÐ+zÑ{Ô{Ð{Ð{Ð{r   c                 óÞ   — |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         dS )z\Verifies monster_system.js implements 2% maxHp/sec healing and force-leashing on safe entry.ÚplayerInSafeZonez	0.02 * dtÚisInWaypointSafeRadiuszm.isLeashing = trueN©r<   rY   r   s    r   Ú2test_monster_system_safe_zone_healing_and_leashingzOTestWaypointSafeRadiusClient.test_monster_system_safe_zone_healing_and_leashingÃ   sg   € à�ŠÐ(¨$Ô*AÑBÔBÐBØ�Š�k 4Ô#:Ñ;Ô;Ð;Ø�ŠÐ.°Ô0GÑHÔHÐHØ�ŠÐ+¨TÔ-DÑEÔEÐEÐEÐEr   c                 ór   — |                       d| j        ¦  «         |                       d| j        ¦  «         dS )zQVerifies executeMonsterAttackOnPlayer guards against hitting player in safe zone.r’   zŠif (player.godMode || isSafeHavenZone() || (window.isInWaypointSafeRadius && window.isInWaypointSafeRadius(player.wx, player.wy))) return;Nr“   r   s    r   Ú)test_monster_system_attack_guard_immunityzFTestWaypointSafeRadiusClient.test_monster_system_attack_guard_immunityÊ   sS   € à�ŠÐ.°Ô0GÑHÔHÐHØ�Šð  cð  eiô  e|ñ  	}ô  	}ð  	}ð  	}ð  	}r   c                 óÞ   — |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         |                       d| j        ¦  «         dS )zeVerifies world_renderer.js renders waypoint and gentle visual safe zone indicator with distance fade.ÚZONE_WAYPOINTSz362, 181z14.0ÚsetLineDashN)r<   r[   r   s    r   Ú'test_world_renderer_safe_zone_indicatorzDTestWaypointSafeRadiusClient.test_world_renderer_safe_zone_indicatorÏ   se   € à�ŠÐ&¨Ô(@ÑAÔAÐAØ�Š�j $Ô":Ñ;Ô;Ð;Ø�Š�f˜dÔ6Ñ7Ô7Ð7Ø�Š�m TÔ%=Ñ>Ô>Ð>Ð>Ð>r   N)rK   rL   rM   Úclassmethodr]   r_   rz   r�   r”   r–   rš   rN   r   r   rP   rP   �   s™   € € € € € ØðPð Pñ „[ðPð
gð gð gðið ið ið.|ð |ð |ð"Fð Fð Fð}ð }ð }ð
?ð ?ð ?ð ?ð ?r   rP   c                   ó    — e Zd Zd„ Zd„ Zd„ ZdS )ÚTestCodeHygieneAndLineLimitsc                 ó4  — t                                d¬¦  «                             ¦   «         }|                      t	          |¦  «        ddt	          |¦  «        › d�¦  «         |                      t	          |¦  «        ddt	          |¦  «        › d�¦  «         dS )	z;Verifies monster_system.js is <= 490 lines (target <= 485).rR   rS   iê  zmonster_system.js has z lines (exceeds 490 target)éô  ú lines (exceeds 500 hard cap)N)rX   rV   rs   ÚassertLessEqualr-   ©r   Úliness     r   Útest_monster_system_line_limitz;TestCodeHygieneAndLineLimits.test_monster_system_line_limitØ   sŠ   € å!×+Ò+°WÐ+Ñ=Ô=×HÒHÑJÔJˆØ×Ò�S ™ZœZ¨Ð.nÅsÈ5ÁzÄzÐ.nÐ.nÐ.nÑoÔoÐoØ×Ò�S ™ZœZ¨Ð.pÅsÈ5ÁzÄzÐ.pÐ.pÐ.pÑqÔqÐqÐqÐqr   c                 óÊ   — t                                d¬¦  «                             ¦   «         }|                      t	          |¦  «        ddt	          |¦  «        › d�¦  «         dS )z+Verifies world_renderer.js is <= 500 lines.rR   rS   rŸ   zworld_renderer.js has r    N)rZ   rV   rs   r¡   r-   r¢   s     r   Útest_world_renderer_line_limitz;TestCodeHygieneAndLineLimits.test_world_renderer_line_limitÞ   sZ   € å!×+Ò+°WÐ+Ñ=Ô=×HÒHÑJÔJˆØ×Ò�S ™ZœZ¨Ð.pÅsÈ5ÁzÄzÐ.pÐ.pÐ.pÑqÔqÐqÐqÐqr   c                 óÊ   — t                                d¬¦  «                             ¦   «         }|                      t	          |¦  «        ddt	          |¦  «        › d�¦  «         dS )z(Verifies zone_engine.py is <= 500 lines.rR   rS   rŸ   zzone_engine.py has r    N)ÚZONE_ENGINE_PYrV   rs   r¡   r-   r¢   s     r   Útest_zone_engine_line_limitz8TestCodeHygieneAndLineLimits.test_zone_engine_line_limitã   sZ   € å×(Ò(°'Ð(Ñ:Ô:×EÒEÑGÔGˆØ×Ò�S ™ZœZ¨Ð.mÅCÈÁJÄJÐ.mÐ.mÐ.mÑnÔnÐnÐnÐnr   N)rK   rL   rM   r¤   r¦   r©   rN   r   r   r�   r�   ×   sL   € € € € € ðrð rð rðrð rð rð
oð oð oð oð or   r�   Ú__main__)Ú__doc__r„   rn   ÚsysÚunittestÚpathlibr   Ú__file__ÚresolveÚparentrq   Ú
SERVER_DIRrp   ÚpathÚinsertÚworld.zone_typesr   Úworld.zone_enginer   Ú
WEBAPP_DIRrU   rX   rZ   r¨   ÚTestCaser   rP   r�   rK   ÚmainrN   r   r   ú<module>rº      s,  ðð
ð 
ð €€€Ø Ð Ð Ð Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ð Ð àˆt�H‰~Œ~×%Ò%Ñ'Ô'Ô.Ô5Ô<€Ø˜HÑ$€
Ø€3€z�?„?˜#œ(Ð"Ð"Ø„H‡O‚O�A�s�s˜:‘”Ñ'Ô'Ð'Ø€3€|ÑÔ˜CœHÐ$Ð$Ø„H‡O‚O�A�s�s˜<Ñ(Ô(Ñ)Ô)Ð)à %Ð %Ð %Ð %Ð %Ð %Ø (Ð (Ð (Ð (Ð (Ð (à˜HÑ$ xÑ/€
Ø  4Ñ'¨&Ñ0Ð3MÑMÐ Ø Ñ%¨Ñ0Ð3FÑFÐ Ø Ñ%¨Ñ0Ð3FÑFÐ Ø˜gÑ%Ð(8Ñ8€ðf,ð f,ð f,ð f,ð f, 8Ô#4ñ f,ô f,ð f,ðRG?ð G?ð G?ð G?ð G? 8Ô#4ñ G?ô G?ð G?ðToð oð oð oð o 8Ô#4ñ oô oð oð$ ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr   