§
    ½º¾jW9  ã                  ó
  — d Z ddlm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
mZmZmZmZ ddlmZmZ ddlmZmZmZmZmZ ddlmZmZmZmZ  G d	„ d
¦  «        Z G d„ d¦  «        Z G d„ d¦  «        Z G d„ d¦  «        Z dS )zZUnit test suite for FreeExile Milestone M1: Procedural Tile Map Pipeline Server to Client.é    )ÚannotationsN)ÚListÚTuple)ÚTileTypeÚTileCellÚMapGridDataÚEncounterZone)ÚWildernessMapGeneratorÚZONE_DEFAULT_SIZES)Úserialize_map_gridÚdeserialize_map_gridÚHEADER_MAGICÚHEADER_SIZEÚBIOME_TO_CODE)ÚProceduralMapEngineÚgenerate_wilderness_mapÚverify_path_connectivityÚcalculate_path_sinuosityc                  ó"   — e Zd ZdZdd„Zdd„ZdS )ÚTestTileTypeEnumExpansionz2Verifies TileType codes 0-19 and behavior methods.ÚreturnÚNonec                ó  — i dd“dd“dd“dd“d	d
“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd “d!d"“d#d$d%d&œ¥}|                      ¦   «         D ]\  }}t          |         j        |k    sJ ‚Œt          t          ¦  «        d'k    sJ ‚d S )(NÚVOIDr   ÚFLOORé   ÚWALLé   ÚDESTRUCTIBLE_BARRICADEé   ÚMUD_POOLé   Ú
SPIKE_TRAPé   ÚCRUMBLED_DEBRISé   Ú	BONE_PILEé   ÚPOISON_VENTé   ÚCHASMé	   Ú	BOSS_GATEé
   Ú
BOSS_ALTARé   ÚRUNIC_FLOORé   ÚPATHé   ÚDENSE_TERRAINé   ÚPOIé   ÚENCOUNTER_LOWé   é   é   é   )ÚENCOUNTER_MEDIUMÚENCOUNTER_HIGHÚWATERé   )Úitemsr   ÚvalueÚlen)ÚselfÚexpectedÚnameÚcodes       úAC:\Projects\FreeExile\tests\unit\test_wilderness_map_generator.pyÚ%test_all_twenty_tile_codes_registeredz?TestTileTypeEnumExpansion.test_all_twenty_tile_codes_registered   s<  € ð
Ø�Að
Ø ð
Ø#)¨1ð
Ø.FÈð
ØKUÐWXð
à˜!ð
à.°ð
à3>Àð
àCPÐRSð
àU\Ð^_ð
ð ˜ð
ð *¨2ð
ð 0=¸bð
ð CIÈ"ð
ð O^Ð_að
ð �2ð	
ð '¨ð	
ð ACÐVXÐceð	
ð 
ð 
ˆð #Ÿ.š.Ñ*Ô*ð 	0ð 	0‰JˆD�$Ý˜D”>Ô'¨4Ò/Ð/Ð/Ð/Ð/Ý•8‰}Œ} Ò"Ð"Ð"Ð"Ð"Ð"ó    c           	     óì  — t           j        t           j        t           j        t           j        t           j        t           j        t           j        t           j        t           j	        g	}|D ]}| 
                    ¦   «         du sJ ‚Œt           j        t           j        t           j        t           j        t           j        t           j        g}|D ]}| 
                    ¦   «         du sJ ‚Œt           j                             ¦   «         dk    sJ ‚t           j                             ¦   «         dk    sJ ‚t           j                             ¦   «         dk    sJ ‚t           j                             ¦   «         dk    sJ ‚d S )NTFgš™™™™™é?gáz®Gáö?g       @g      ð?)r   r   r!   r#   r3   r5   r7   r9   r>   r?   Úis_passabler   r   r   r+   r-   r@   Úmovement_cost)rE   Úpassable_typesÚtÚimpassable_typess       rI   Ú'test_tile_passability_and_movement_costzATestTileTypeEnumExpansion.test_tile_passability_and_movement_cost'   s:  € åŒN�HÔ-­xÔ/BÅHÄMÝÔ"¥H¤Lµ(Ô2HÝÔ%¥xÔ'>ð
ˆð
  ð 	+ð 	+ˆAØ—=’=‘?”? dÐ*Ð*Ð*Ð*Ð*õ ŒM�8œ=­(Ô*IÝŒN�HÔ.µ´ð
Ðð "ð 	,ð 	,ˆAØ—=’=‘?”? eÐ+Ð+Ð+Ð+Ð+åŒ}×*Ò*Ñ,Ô,°Ò3Ð3Ð3Ð3ÝÔ%×3Ò3Ñ5Ô5¸Ò=Ð=Ð=Ð=ÝÔ ×.Ò.Ñ0Ô0°CÒ7Ð7Ð7Ð7ÝŒ~×+Ò+Ñ-Ô-°Ò4Ð4Ð4Ð4Ð4Ð4rK   N©r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rJ   rR   © rK   rI   r   r      sB   € € € € € Ø<Ð<ð	#ð 	#ð 	#ð 	#ð5ð 5ð 5ð 5ð 5ð 5rK   r   c                  óˆ   — e Zd ZdZej                             dg d¢¦  «        dd„¦   «         Zdd„Zdd„Z	dd„Z
dd„Zdd„ZdS )ÚTestWildernessMapGeneratorzGVerifies wilderness map layout, paths, encounter zones, and guarantees.zzone_id,expected_w,expected_h)	)Úzone_tang_kiem_nhaié<   é-   )Úzone_ancient_sword_barrowéD   é4   )Úzone_boundless_sandstorméL   é:   )Úzone_blood_scale_ruinséT   é@   )Úzone_five_elements_altaré\   éF   )Úzone_abyssal_ice_pondéd   rb   )Úzone_infinite_blood_riftél   éR   )Úzone_purgatory_lava_cavernér   éV   )Úzone_boundless_celestial_palaceéx   éZ   Úzone_idÚstrÚ
expected_wÚintÚ
expected_hr   r   c                ó*  — t          j        |¦  «        }|j        |k    r|j        |k    sJ ‚|                     d¬¦  «        }|j        |k    r|j        |k    sJ ‚t          |j        ¦  «        |k    rt          |j        d         ¦  «        |k    sJ ‚d S )Née   ©Úseedr   )r
   Úfor_zoneÚwidthÚheightÚgeneraterD   Útiles)rE   ru   rw   ry   ÚgenÚmap_datas         rI   Ú$test_canonical_wilderness_dimensionsz?TestWildernessMapGenerator.test_canonical_wilderness_dimensions@   sŸ   € õ %Ô-¨gÑ6Ô6ˆØŒy˜JÒ&Ð&¨3¬:¸Ò+CÐ+CÐ+CÐCØ—<’< S�<Ñ)Ô)ˆØŒ~ Ò+Ð+°´À:Ò0MÐ0MÐ0MÐMÝ�8”>Ñ"Ô" jÒ0Ð0µS¸¼ÈÔ9JÑ5KÔ5KÈzÒ5YÐ5YÐ5YÐYÐ5YÐ5YrK   c           
     óÔ  — t          j        d¦  «        }dD ]Ð}|                     |¬¦  «        }|j        \  }}t	          |j        ¦  «        D ]™}t	          |j        ¦  «        D ]‚}t          j        ||z
  ||z
  ¦  «        dk    ra|j	        |         |         }|j
        du sJ d|› d|› d|› �¦   «         ‚|j        t          j        t          j        fv sJ d	|j        › d
�¦   «         ‚ŒƒŒšŒÑd S )Nr[   )r   é*   rk   é	  iŸ† r|   g       @TzBlocked cell (ú,z) inside spawn radius for seed zNon-floor tile z inside spawn radius)r
   r~   r�   Úspawn_pointÚranger€   r   ÚmathÚhypotr‚   ÚwalkableÚ	tile_typer   r   r3   )	rE   rƒ   r}   r„   ÚsxÚsyÚyÚxÚcells	            rI   Ú'test_spawn_safe_area_radius_8_guaranteezBTestWildernessMapGenerator.test_spawn_safe_area_radius_8_guaranteeQ   s;  € Ý$Ô-Ð.CÑDÔDˆØ,ð 	Ið 	IˆDØ—|’|¨�|Ñ.Ô.ˆHØÔ)‰FˆB�Ý˜8œ?Ñ+Ô+ð Ið I�Ý˜xœ~Ñ.Ô.ð Ið I�AÝ”z ! b¡&¨!¨b©&Ñ1Ô1°SÒ8Ð8Ø'œ~¨aÔ0°Ô3˜Ø#œ}°Ð4Ð4Ð4Ð6sÀqÐ6sÐ6sÈ1Ð6sÐ6sÐmqÐ6sÐ6sÑ4Ô4Ð4Ø#œ~µ(´.Å(Ä-Ð1PÐPÐPÐPð  SIÐdhÔdrð  SIð  SIð  SIÑPÔPÐPøð	IðIð	Ið 	IrK   c                ó(  — dD ]Ž}t          j        d¦  «        }|                     |¬¦  «        }t          ||j        |j        d¬¦  «        \  }}|du sJ d|› �¦   «         ‚t          ||j        |j        ¦  «        }|dk    sJ d|› d	|› �¦   «         ‚Œ�d S )
N)r   r   r‡   rk   i90  r[   r|   T)Úallow_sealed_boss_gatez Main path disconnected for seed g      ô?zPath sinuosity z < 1.25 for seed )r
   r~   r�   r   rŠ   Ú	boss_gater   )rE   r}   rƒ   r„   Ú	connectedÚpathÚ	sinuositys          rI   Ú!test_guaranteed_sinuous_main_pathz<TestWildernessMapGenerator.test_guaranteed_sinuous_main_path]   sÙ   € Ø*ð 	[ð 	[ˆDÝ(Ô1Ð2GÑHÔHˆCØ—|’|¨�|Ñ.Ô.ˆHÝ6°xÀÔAUÐW_ÔWið  CGð  Hñ  Hô  H‰OˆI�tØ Ð$Ð$Ð$Ð&OÈÐ&OÐ&OÑ$Ô$Ð$Ý0°°xÔ7KÈXÔM_Ñ`Ô`ˆIØ Ò$Ð$Ð$Ð&Z¸	Ð&ZÐ&ZÐTXÐ&ZÐ&ZÑ$Ô$Ð$Ð$ð	[ð 	[rK   c                ó  — t          j        d¦  «        }|                     d¬¦  «        }dt          |j        ¦  «        cxk    rdk    sn J ‚d„ |j        D ¦   «         }d|v rd|v sJ ‚|j        D ]P}d|j        cxk    r|j        cxk     r|j        k     sn J ‚d|j        cxk    r|j	        cxk     r|j
        k     sn J ‚ŒQdt          |j        ¦  «        cxk    rdk    sn J ‚|j        D ]!\  }}|j        |         |         j        d	u sJ ‚Œ"d S )
Nr[   i+  r|   r   r    c                ó   — g | ]	}|j         ‘Œ
S rX   )Útier)Ú.0Úes     rI   ú
<listcomp>zQTestWildernessMapGenerator.test_encounter_zones_and_dead_ends.<locals>.<listcomp>j   s   € Ð:Ð:Ð:˜A�”Ð:Ð:Ð:rK   r   r   T)r
   r~   r�   rD   Úencounter_zonesÚmin_xÚmax_xr   Úmin_yÚmax_yr€   Údead_end_pointsr‚   rŽ   )rE   rƒ   r„   ÚtiersÚencÚdxÚdys          rI   Ú"test_encounter_zones_and_dead_endsz=TestWildernessMapGenerator.test_encounter_zones_and_dead_endsf   s~  € Ý$Ô-Ð.CÑDÔDˆØ—<’< S�<Ñ)Ô)ˆØ•C˜Ô0Ñ1Ô1Ð6Ð6Ò6Ð6°QÒ6Ð6Ð6Ð6Ð6Ð6Ø:Ð: Ô!9Ð:Ñ:Ô:ˆØ�Eˆzˆz˜a 5˜j˜j˜jÐ(ØÔ+ð 	@ð 	@ˆCØ˜œ	Ð>Ð>Ò>Ð> C¤IÐ>Ð>Ò>Ð>°´Ò>Ð>Ð>Ð>Ð>Ð>Ø˜œ	Ð?Ð?Ò?Ð? C¤IÐ?Ð?Ò?Ð?°´Ò?Ð?Ð?Ð?Ð?Ð?Ð?à•C˜Ô0Ñ1Ô1Ð6Ð6Ò6Ð6°QÒ6Ð6Ð6Ð6Ð6Ð6ØÔ.ð 	;ð 	;‰FˆB�Ø”> "Ô% bÔ)Ô2°dÐ:Ð:Ð:Ð:Ð:ð	;ð 	;rK   c                ój  — t          j        d¦  «        }|                     d¬¦  «        }|j        }|€J ‚d\  }}t	          |j        |j        |j        z   ¦  «        D ]¬}t	          |j        |j        |j        z   ¦  «        D ]‡}||j        k    s7||j        |j        z   dz
  k    s!||j        k    s||j        |j        z   dz
  k    rC|j	        |         |         j
        }|t          j        k    r|dz  }Œr|t          j        k    r|dz  }ŒˆŒ­|dk    sJ ‚||j        dz  |j        dz  z   dz
  dz
  k    sJ ‚d S )Nr[   iç  r|   )r   r   r   r   r"   )r
   r~   r�   Ú	boss_roomr‹   r’   Úhr“   Úwr‚   r�   r   r-   r   )	rE   rƒ   r„   ÚbrÚ
gate_countÚ
wall_countr’   r“   rP   s	            rI   Ú#test_boss_arena_perimeter_isolationz>TestWildernessMapGenerator.test_boss_arena_perimeter_isolationt   sU  € Ý$Ô-Ð.CÑDÔDˆØ—<’< S�<Ñ)Ô)ˆØÔˆØˆ~ˆ~ˆ~Ø!%Ñˆ
�JÝ�r”t˜RœT B¤D™[Ñ)Ô)ð 	(ð 	(ˆAÝ˜2œ4 ¤¨¬¡Ñ-Ô-ð (ð (�Ø˜œ’9�9  R¤T¨B¬D¡[°1¡_Ò 4Ð 4¸¸R¼Tº	¸	ÀQÈ"Ì$ÐQSÔQUÉ+ÐXYÉ/ÒEYÐEYØ œ qÔ)¨!Ô,Ô6�AØ�HÔ.Ò.Ð.Ø" a™˜
˜
Ø�hœmÒ+Ð+Ø" a™˜
øð(ð ˜QŠˆˆˆØ˜bœd Q™h¨¬°©Ñ1°AÑ5¸Ñ:Ò:Ð:Ð:Ð:Ð:Ð:rK   c                óD  — t          j        d¦  «        }|                     d¬¦  «        }dt          |j        ¦  «        cxk    rdk    sn J ‚|j        D ]J\  }}}|j        |         |         j        t          j        k    sJ ‚|j        |         |         j	        du sJ ‚ŒKd S )Nr[   ix  r|   r   r    T)
r
   r~   r�   rD   Ú
poi_pointsr‚   r�   r   r7   rŽ   )rE   rƒ   r„   ÚpxÚpyÚ_s         rI   Útest_poi_placement_countz3TestWildernessMapGenerator.test_poi_placement_count…   s½   € Ý$Ô-Ð.CÑDÔDˆØ—<’< S�<Ñ)Ô)ˆØ•C˜Ô+Ñ,Ô,Ð1Ð1Ò1Ð1°Ò1Ð1Ð1Ð1Ð1Ð1Ø!Ô,ð 	;ð 	;‰IˆB��AØ”> "Ô% bÔ)Ô3µx´|ÒCÐCÐCÐCØ”> "Ô% bÔ)Ô2°dÐ:Ð:Ð:Ð:Ð:ð	;ð 	;rK   N)ru   rv   rw   rx   ry   rx   r   r   rS   )rT   rU   rV   rW   ÚpytestÚmarkÚparametrizer…   r•   rœ   r­   rµ   r»   rX   rK   rI   rZ   rZ   =   sÏ   € € € € € ØQÐQà„[×ÒØ'ð	
ð 	
ð 	
ñ	ô 	ðZð Zð Zñ	ô 	ðZð
Ið 
Ið 
Ið 
Ið[ð [ð [ð [ð;ð ;ð ;ð ;ð;ð ;ð ;ð ;ð";ð ;ð ;ð ;ð ;ð ;rK   rZ   c                  ó:   — e Zd ZdZd
d„Zd
d„Zd
d„Zd
d„Zd
d„Zd	S )ÚTestMapBinarySerializerzVVerifies binary encoding, decoding, truncation detection, and unknown tile resilience.r   r   c                ó  — t          j        d¦  «        }|                     d¬¦  «        }t          |¦  «        }|d d…         t          k    sJ ‚t          |¦  «        t          |j        |j        z  z   k    sJ ‚t          |¦  «        }|j        |j        k    sJ ‚|j        |j        k    sJ ‚|j
        |j
        k    sJ ‚|j        |j        k    sJ ‚t          |j        ¦  «        t          |j        ¦  «        k    sJ ‚t          |j        ¦  «        t          |j        ¦  «        k    sJ ‚t          |j        ¦  «        D ]M}t          |j        ¦  «        D ]6}|j        |         |         j        |j        |         |         j        k    sJ ‚Œ7ŒNd S )Nr[   rˆ   r|   r   )r
   r~   r�   r   r   rD   r   r   r€   r   rŠ   r˜   r£   r·   r‹   r‚   r�   )rE   rƒ   ÚorigÚbinary_dataÚrestoredr’   r“   s          rI   Útest_binary_roundtrip_integrityz7TestMapBinarySerializer.test_binary_roundtrip_integrity‘   s�  € Ý$Ô-Ð.CÑDÔDˆØ�|Š| ˆ|Ñ%Ô%ˆÝ(¨Ñ.Ô.ˆà˜2˜A˜2Œ¥,Ò.Ð.Ð.Ð.Ý�;ÑÔ¥;°´¸d¼kÑ1IÑ#IÒIÐIÐIÐIå'¨Ñ4Ô4ˆØŒ~ ¤Ò+Ð+Ð+Ð+ØŒ $¤+Ò-Ð-Ð-Ð-ØÔ# tÔ'7Ò7Ð7Ð7Ð7ØÔ! T¤^Ò3Ð3Ð3Ð3Ý�8Ô+Ñ,Ô,µ°DÔ4HÑ0IÔ0IÒIÐIÐIÐIÝ�8Ô&Ñ'Ô'­3¨t¬Ñ+?Ô+?Ò?Ð?Ð?Ð?å�t”{Ñ#Ô#ð 	Tð 	TˆAÝ˜4œ:Ñ&Ô&ð Tð T�Ø”~ aÔ(¨Ô+Ô5¸¼ÀA¼ÀqÔ9IÔ9SÒSÐSÐSÐSÐSðTð	Tð 	TrK   c                ó  — t          j        t          d¬¦  «        5  t          d¦  «         d d d ¦  «         n# 1 swxY w Y   d}t          j        t          d¬¦  «        5  t          |¦  «         d d d ¦  «         d S # 1 swxY w Y   d S )NzBuffer too short©Úmatchs   SHORTs   XX                    zInvalid map magic)r¼   ÚraisesÚ
ValueErrorr   )rE   Úcorrupt_magics     rI   Ú!test_binary_header_error_handlingz9TestMapBinarySerializer.test_binary_header_error_handling¥   s
  € ÝŒ]�:Ð-?Ð@Ñ@Ô@ð 	+ð 	+Ý  Ñ*Ô*Ð*ð	+ð 	+ð 	+ñ 	+ô 	+ð 	+ð 	+ð 	+ð 	+ð 	+ð 	+øøøð 	+ð 	+ð 	+ð 	+ð -ˆÝŒ]�:Ð-@ÐAÑAÔAð 	0ð 	0Ý  Ñ/Ô/Ð/ð	0ð 	0ð 	0ñ 	0ô 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0ð 	0øøøð 	0ð 	0ð 	0ð 	0ð 	0ð 	0s   œ8¸<¿<Á A=Á=BÂBc                óF  — t          j        d¦  «        }t          |                     d¬¦  «        ¦  «        }t	          |¦  «        }ddd|dz
  |dz
  fD ]L}t          j        t          d	¬
¦  «        5  t          |d |…         ¦  «         d d d ¦  «         n# 1 swxY w Y   ŒMd S )Nr[   r‡   r|   r:   rA   é   r   é2   zBuffer truncatedrÇ   )	r
   r~   r   r�   rD   r¼   rÉ   rÊ   r   )rE   rƒ   Ú	valid_bufÚ	total_lenÚcuts        rI   Ú*test_binary_truncation_across_all_sectionszBTestMapBinarySerializer.test_binary_truncation_across_all_sections­   sç   € Ý$Ô-Ð.CÑDÔDˆÝ& s§|¢|¸ |Ñ'<Ô'<Ñ=Ô=ˆ	Ý˜	‘N”Nˆ	Ø˜˜B 	¨A¡¨y¸2©~Ð>ð 	6ð 	6ˆCÝ”�zÐ1CÐDÑDÔDð 6ð 6Ý$ Y¨t°¨t¤_Ñ5Ô5Ð5ð6ð 6ð 6ñ 6ô 6ð 6ð 6ð 6ð 6ð 6ð 6øøøð 6ð 6ð 6ð 6øð	6ð 	6s   Á1BÂB	ÂB	c                ó   — t          j        d¦  «        }t          t          |                     d¬¦  «        ¦  «        ¦  «        }d|d<   t          t          |¦  «        ¦  «        }|j        d         d         j        t          j
        k    sJ ‚d S )Nr[   r(   r|   éc   éÿÿÿÿ)r
   r~   Ú	bytearrayr   r�   r   Úbytesr‚   r�   r   r   )rE   rƒ   ÚrawrÄ   s       rI   Ú(test_unknown_tile_value_fallback_to_wallz@TestMapBinarySerializer.test_unknown_tile_value_fallback_to_wallµ   s{   € Ý$Ô-Ð.CÑDÔDˆÝÕ*¨3¯<ª<¸Q¨<Ñ+?Ô+?Ñ@Ô@ÑAÔAˆØˆˆB‰Ý'­¨c©
¬
Ñ3Ô3ˆØŒ~˜bÔ! "Ô%Ô/µ8´=Ò@Ð@Ð@Ð@Ð@Ð@rK   c                óê   — t          dd¬¦  «        }t          |t          ¦  «        sJ ‚|                     ¦   «         }t	          |¦  «        dk    sJ ‚t          |¦  «        }|j        |j        k    sJ ‚d S )Nr[   é{   r|   r   )r   Ú
isinstancer   Ú	to_binaryrD   r   r   )rE   r„   ÚbÚdecodeds       rI   Ú%test_facade_and_to_binary_integrationz=TestMapBinarySerializer.test_facade_and_to_binary_integration¼   sw   € Ý*Ð+@ÀsÐKÑKÔKˆÝ˜(¥KÑ0Ô0Ð0Ð0Ð0Ø×ÒÑ Ô ˆÝ�1‰vŒv˜ŠzˆzˆzˆzÝ& qÑ)Ô)ˆØŒ} ¤Ò.Ð.Ð.Ð.Ð.Ð.rK   NrS   )	rT   rU   rV   rW   rÅ   rÌ   rÓ   rÚ   rá   rX   rK   rI   rÀ   rÀ   Ž   s†   € € € € € Ø`Ð`ðTð Tð Tð Tð(0ð 0ð 0ð 0ð6ð 6ð 6ð 6ðAð Að Að Að/ð /ð /ð /ð /ð /rK   rÀ   c                  óR   — e Zd ZdZedd„¦   «         Zdd„Zdd	„Zdd
„Zdd„Z	dd„Z
dS )Ú'TestClientTileGridLoaderNodeIntegrationzfVerifies client-side JS loader decodes binary stream, handles OOB/NaN queries, and in-place mutations.Úscriptrv   r   ú subprocess.CompletedProcess[str]c                ó8   — t          j        dd| gddd¬¦  «        S )NÚnodez-eTzc:\Projects\FreeExile)Úcapture_outputÚtextÚcwd)Ú
subprocessÚrun)rä   s    rI   Ú	_run_nodez1TestClientTileGridLoaderNodeIntegration._run_nodeÈ   s.   € åŒ~Ø�T˜6Ð"ØØØ(ð	
ñ 
ô 
ð 	
rK   r   c                óÎ  — t          j        d¦  «        st          j        d¦  «         t	          j        d¦  «        }|                     d¬¦  «        }|dz  }|                     t          |¦  «        ¦  «         t          |¦  «         
                    dd¦  «        }d	|› d
|j        › d|j        › d�}|                      |¦  «        }|j        dk    sJ d|j        › �¦   «         ‚d S )Nrç   ú,Node.js runtime not installed in environmentr[   iA  r|   zmap_test.binú\ú/z¥
        const fs = require('fs');
        const { TileGridLoader } = require('./client/webapp/js/engine/tile_grid_loader.js');
        const buf = fs.readFileSync('z‡');
        const meta = TileGridLoader.loadBinaryMap(buf);
        if (!meta) process.exit(1);
        if (window.currentMapWidth !== z;) process.exit(2);
        if (window.currentMapHeight !== zý) process.exit(3);
        const spawnTile = window.getTileAt(meta.spawn.x, meta.spawn.y);
        if (spawnTile !== 1 && spawnTile !== 13) process.exit(4);
        if (window.getTileAt(-10, -10) !== 2) process.exit(5);
        process.exit(0);
        r   zNode decoding failed: )ÚshutilÚwhichr¼   Úskipr
   r~   r�   Úwrite_bytesr   rv   Úreplacer   r€   rí   Ú
returncodeÚstderr)rE   Útmp_pathrƒ   r„   Úbin_pathÚbin_strÚ	js_scriptÚress           rI   Ú$test_node_tile_grid_loader_roundtripzLTestClientTileGridLoaderNodeIntegration.test_node_tile_grid_loader_roundtripÑ   s  € ÝŒ|˜FÑ#Ô#ð 	HÝŒKÐFÑGÔGÐGå$Ô-Ð.CÑDÔDˆØ—<’< S�<Ñ)Ô)ˆØ˜nÑ,ˆØ×ÒÕ/°Ñ9Ô9Ñ:Ô:Ð:Ý�h‘-”-×'Ò'¨¨cÑ2Ô2ˆðð '.ðð ð )1¬ðð ð *2¬ðð ð ˆ	ð �nŠn˜YÑ'Ô'ˆØŒ~ Ò"Ð"Ð"Ð$I¸S¼ZÐ$IÐ$IÑ"Ô"Ð"Ð"Ð"rK   c                ó¾   — t          j        d¦  «        st          j        d¦  «         d}|                      |¦  «        }|j        dk    sJ d|j        › �¦   «         ‚d S )Nrç   rï   z±
        const { TileGridLoader, BIOME_CODES } = require('./client/webapp/js/engine/tile_grid_loader.js');
        if (!TileGridLoader || !BIOME_CODES) process.exit(1);
        r   z3Clean Node require failed (window ReferenceError): ©rò   ró   r¼   rô   rí   r÷   rø   ©rE   rä   rý   s      rI   Ú,test_node_loader_clean_import_without_windowzTTestClientTileGridLoaderNodeIntegration.test_node_loader_clean_import_without_windowë   sn   € ÝŒ|˜FÑ#Ô#ð 	HÝŒKÐFÑGÔGÐGðˆð �nŠn˜VÑ$Ô$ˆØŒ~ Ò"Ð"Ð"Ð$fÐZ]ÔZdÐ$fÐ$fÑ"Ô"Ð"Ð"Ð"rK   c                ó¾   — t          j        d¦  «        st          j        d¦  «         d}|                      |¦  «        }|j        dk    sJ d|j        › �¦   «         ‚d S )Nrç   rï   a²  
        const { TileGridLoader } = require('./client/webapp/js/engine/tile_grid_loader.js');
        TileGridLoader.loadFallbackGrid(60, 45, 1);
        const badCoords = [NaN, undefined, -1, 60, Infinity, -Infinity, "invalid"];
        for (const c of badCoords) {
            if (TileGridLoader.getTileAt(c, 0) !== 2 || TileGridLoader.getTileAt(0, c) !== 2) {
                console.error("Failed for coord:", c, "got:", TileGridLoader.getTileAt(c, 0));
                process.exit(1);
            }
        }
        if (TileGridLoader.getTileAt(NaN, NaN) !== 2) process.exit(2);
        if (TileGridLoader.getTileAt(0.9, 0.9) !== 1) process.exit(3);
        process.exit(0);
        r   z!getTileAt non-finite/OOB failed: r   r  s      rI   Ú(test_node_get_tile_at_non_finite_and_oobzPTestClientTileGridLoaderNodeIntegration.test_node_get_tile_at_non_finite_and_oobõ   sl   € ÝŒ|˜FÑ#Ô#ð 	HÝŒKÐFÑGÔGÐGðˆð �nŠn˜VÑ$Ô$ˆØŒ~ Ò"Ð"Ð"Ð$TÈÌ
Ð$TÐ$TÑ"Ô"Ð"Ð"Ð"rK   c                ó¾   — t          j        d¦  «        st          j        d¦  «         d}|                      |¦  «        }|j        dk    sJ d|j        › �¦   «         ‚d S )Nrç   rï   a  
        const { TileGridLoader } = require('./client/webapp/js/engine/tile_grid_loader.js');
        TileGridLoader.loadFallbackGrid(10, 10, 1);
        if (!TileGridLoader.setTileAt(5, 5, 10) || TileGridLoader.getTileAt(5, 5) !== 10) process.exit(1);
        if (!TileGridLoader.setTileAt(5, 5, 1) || TileGridLoader.getTileAt(5, 5) !== 1) process.exit(2);
        for (const bad of [-1, 10, NaN, Infinity]) {
            if (TileGridLoader.setTileAt(bad, 0, 1) !== false) process.exit(3);
        }
        process.exit(0);
        r   z$setTileAt mutation or guard failed: r   r  s      rI   Ú)test_node_set_tile_at_mutation_and_guardszQTestClientTileGridLoaderNodeIntegration.test_node_set_tile_at_mutation_and_guards	  sl   € ÝŒ|˜FÑ#Ô#ð 	HÝŒKÐFÑGÔGÐGð	ˆð �nŠn˜VÑ$Ô$ˆØŒ~ Ò"Ð"Ð"Ð$WÈ3Ì:Ð$WÐ$WÑ"Ô"Ð"Ð"Ð"rK   c                óª  — t          j        d¦  «        st          j        d¦  «         t	          j        d¦  «        }|dz  }|                     t          |                     d¬¦  «        ¦  «        ¦  «         t          |¦  «         
                    dd¦  «        }d	|› d
�}|                      |¦  «        }|j        dk    sJ d|j        › �¦   «         ‚d S )Nrç   rï   r[   z	valid.binr‡   r|   rð   rñ   a�  
        const fs = require('fs');
        const { TileGridLoader } = require('./client/webapp/js/engine/tile_grid_loader.js');
        if (TileGridLoader.loadBinaryMap(null) !== null) process.exit(1);
        if (TileGridLoader.loadBinaryMap(Buffer.alloc(0)) !== null) process.exit(2);
        if (TileGridLoader.loadBinaryMap(Buffer.alloc(15)) !== null) process.exit(3);

        const valid = fs.readFileSync('a‚  ');
        const corrupt = Buffer.from(valid); corrupt[0] = 88; corrupt[1] = 88;
        if (TileGridLoader.loadBinaryMap(corrupt) !== null) process.exit(4);

        for (const cut of [16, 20, valid.length - 1]) {
            if (TileGridLoader.loadBinaryMap(valid.subarray(0, cut)) !== null) process.exit(5);
        }

        const fake = Buffer.alloc(16);
        fake.write("FE", 0, 2, 'ascii'); fake.writeUInt8(1, 2); fake.writeUInt8(1, 3);
        fake.writeUInt16LE(0, 4); fake.writeUInt16LE(0, 6); fake.writeUInt8(10, 12);
        if (TileGridLoader.loadBinaryMap(fake) !== null) process.exit(6);

        process.exit(0);
        r   zNode buffer rejection failed: )rò   ró   r¼   rô   r
   r~   rõ   r   r�   rv   rö   rí   r÷   rø   )rE   rù   rƒ   rú   rû   rä   rý   s          rI   Ú.test_node_loader_truncated_and_corrupt_bufferszVTestClientTileGridLoaderNodeIntegration.test_node_loader_truncated_and_corrupt_buffers  sá   € ÝŒ|˜FÑ#Ô#ð 	HÝŒKÐFÑGÔGÐGÝ$Ô-Ð.CÑDÔDˆØ˜kÑ)ˆØ×ÒÕ/°·²À"°Ñ0EÔ0EÑFÔFÑGÔGÐGÝ�h‘-”-×'Ò'¨¨cÑ2Ô2ˆðð )0ðð ð ˆð, �nŠn˜VÑ$Ô$ˆØŒ~ Ò"Ð"Ð"Ð$QÀSÄZÐ$QÐ$QÑ"Ô"Ð"Ð"Ð"rK   N)rä   rv   r   rå   rS   )rT   rU   rV   rW   Ústaticmethodrí   rþ   r  r  r  r  rX   rK   rI   rã   rã   Å   s²   € € € € € ØpÐpàð
ð 
ð 
ñ „\ð
ðJð Jð Jð Jð4gð gð gð gðUð Uð Uð Uð(Xð Xð Xð Xð Rð Rð Rð Rð Rð RrK   rã   )!rW   Ú
__future__r   rŒ   rò   rë   Útypingr   r   r¼   Úserver.world.map_data_typesr   r   r   r	   Ú%server.world.wilderness_map_generatorr
   r   Ú"server.world.map_binary_serializerr   r   r   r   r   Ú"server.world.procedural_map_enginer   r   r   r   r   rZ   rÀ   rã   rX   rK   rI   ú<module>r     sé  ðØ `Ð `à "Ð "Ð "Ð "Ð "Ð "Ø Ð Ð Ð Ð Ð Ð Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ð Ð Ø €€€à VÐ VÐ VÐ VÐ VÐ VÐ VÐ VÐ VÐ VÐ VÐ VØ \Ð \Ð \Ð \Ð \Ð \Ð \Ð \ðð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð!5ð !5ð !5ð !5ð !5ñ !5ô !5ð !5ðHN;ð N;ð N;ð N;ð N;ñ N;ô N;ð N;ðb4/ð 4/ð 4/ð 4/ð 4/ñ 4/ô 4/ð 4/ðnsRð sRð sRð sRð sRñ sRô sRð sRð sRð sRrK   