§
    S¿j‰-  ã                  ó,  — U d Z ddlmZ ddlZddlmc mZ ddl	m
Z
 ddlmZmZmZ ddlZddlmZmZ ddlmZ dZd	ed
<   dZded<   dZded<   ddhZded<   dhZded<   dZded<   dZded<   d5d„Zd6d!„Z ej        d"¬#¦  «        d7d$„¦   «         Z  ej        d"¬#¦  «        d8d&„¦   «         Z! ej        d"¬#¦  «        d9d(„¦   «         Z" G d)„ d*¦  «        Z# G d+„ d,¦  «        Z$ G d-„ d.¦  «        Z% G d/„ d0¦  «        Z& G d1„ d2¦  «        Z' G d3„ d4¦  «        Z(dS ):aá  
Unit Test Suite for FreeExile 30 Map Styles Asset Integrity & Quality.
Verifies:
1. Presence of all 30 style folders under client/webapp/assets/map/styles/.
2. Presence of all 9 required textures per style:
   floor.png, wall.png, path.png, liquid.png, props.png,
   floor_normal.png, wall_normal.png, path_normal.png, liquid_normal.png.
3. Valid non-empty PNG magic header (\x89PNG\r\n\x1a\n).
4. Standard dimensions (floor/path/liquid: 64x32 or 128x64 px; wall: 128x128 px).
5. Tangent-space lighting compliance (normal maps Blue channel mean > 128.0).
6. File size efficiency: individual tile files < 60 KB, total asset folder < 10 MB.
7. Adversarial edge cases: corrupt magic, invalid dimensions, inverted normals, oversized files.
é    )ÚannotationsN)ÚPath)ÚListÚSetÚTuple)ÚImageÚ	ImageStat)Úlist_available_styless   ‰PNG

ÚbytesÚ	PNG_MAGIC)	ú	floor.pngúwall.pngúpath.pngú
liquid.pngú	props.pngúfloor_normal.pngúwall_normal.pngúpath_normal.pngúliquid_normal.pngzTuple[str, ...]ÚREQUIRED_ASSET_FILES)r   r   r   r   ÚNORMAL_MAP_FILES©é@   é    )é€   r   zSet[Tuple[int, int]]ÚVALID_TILE_DIMS)r   r   ÚVALID_WALL_DIMSi ð  ÚintÚMAX_TILE_FILE_SIZE_BYTESi    ÚMAX_TOTAL_FOLDER_SIZE_BYTESÚ	file_pathr   ÚreturnÚboolc                óø   — |                       ¦   «         r|                      ¦   «         j        dk     rdS t          | d¦  «        5 }|                     d¦  «        }ddd¦  «         n# 1 swxY w Y   |t
          k    S )zKVerifies that the file exists, is non-empty, and has valid PNG magic bytes.é   FÚrbN)Úis_fileÚstatÚst_sizeÚopenÚreadr   )r!   ÚfÚheaders      úCC:\Projects\FreeExile\tests\unit\test_map_style_assets_integrity.pyÚverify_png_magic_headerr/   5   s®   € à×ÒÑÔð  )§.¢.Ñ"2Ô"2Ô":¸QÒ">Ð">ØˆuÝ	ˆi˜Ñ	Ô	ð  !Ø—’˜‘”ˆðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð à•YÒÐs   ÁA&Á&A*Á-A*Úfloatc                ó  — t          j        | ¦  «        5 }t          j        |¦  «        }t	          |j        ¦  «        dk    r&t          |j        d         ¦  «        cddd¦  «         S 	 ddd¦  «         n# 1 swxY w Y   dS )zAComputes the mean intensity of the Blue channel across the image.é   é   Ng        )r   r*   r	   ÚStatÚlenÚmeanr0   )r!   Úimgr(   s      r.   Úcompute_blue_channel_meanr8   >   sÉ   € å	Œ�IÑ	Ô	ð ' #ÝŒ~˜cÑ"Ô"ˆÝˆtŒy‰>Œ>˜QÒÐÝ˜œ 1œÑ&Ô&ð'ð 'ð 'ð 'ñ 'ô 'ð 'ð 'àð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'ð ˆ3s   •AA5Á5A9Á<A9Úmodule)Úscopec                 ól   — t          t          ¦  «                             ¦   «         j        j        j        S )zReturn repository root path.)r   Ú__file__ÚresolveÚparent© ó    r.   Úproject_rootrA   G   s%   € õ •‰>Œ>×!Ò!Ñ#Ô#Ô*Ô1Ô8Ð8r@   rA   c                ó$   — | dz  dz  dz  dz  dz  S )zBReturn canonical styles directory client/webapp/assets/map/styles.ÚclientÚwebappÚassetsÚmapÚstylesr?   )rA   s    r.   Ústyles_rootrH   M   s#   € ð ˜(Ñ" XÑ-°Ñ8¸5Ñ@À8ÑKÐKr@   ú	List[str]c                 ó�  — t          ¦   «         } t          | ¦  «        }d}||k    }|�st          j        d|fd||f¦  «        dt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt	          j        ¦   «         v st          j        | ¦  «        rt          j        | ¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          j        dt          | ¦  «        › �¦  «        dz   d	|iz  }t          t          j
        |¦  «        ¦  «        ‚d
x}x}}| S )z$Retrieve all 30 canonical style IDs.é   ©ú==)z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr5   rG   )Úpy0Úpy1Úpy3Úpy6zExpected 30 styles, got z
>assert %(py8)sÚpy8N)r
   r5   Ú
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚ_format_assertmsgÚAssertionErrorÚ_format_explanation)rG   Ú@py_assert2Ú@py_assert5Ú@py_assert4Ú@py_format7Ú@py_format9s         r.   Úcanonical_stylesra   S   sO  € õ #Ñ$Ô$€FÝˆv‰;Œ;ÐF˜"ÐFˆ;˜"ÒÐFÐFÑFÕFÔFÐFÐFÐFÐFˆ;˜"ÐFÑFÔFÐFÕFÔFÑFÔFÐFÐFÕFÔF�3ÑFÔFÐFÕFÔF�3ÑFÔFÐFÐFÐFÕFÔFÑFÔFÐFÐFÕFÔFˆvÑFÔFÐFÕFÔFˆvÑFÔFÐFÐFÕFÔFˆ;ÑFÔFÕFÔF˜"ÑFÔFÐFÐFÑFÐFÕFÔFÐF½¸V¹¼ÐFÐFÑFÔFÐFÑFÐFÐFÐFÑFÐFÕFÕFÔFÐFÑFÔFÑFÔFÐFÐFÐFÐFÐFÐFÐFØ€Mr@   c                  ó*   — e Zd ZdZdd„Zdd	„Zdd
„ZdS )ÚTestMapStyleDirectoryStructurez@Validates root styles directory and all 30 style subdirectories.rH   r   r"   ÚNonec                óî  — |j         } |¦   «         }|s£t          j        d|› �¦  «        dz   dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j        |¦  «        ¦  «        ‚dx}}|j	        } |¦   «         }|s£t          j        d|› �¦  «        dz   dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j        |¦  «        ¦  «        ‚dx}}dS )z4Root styles directory must exist and be a directory.zStyles root does not exist: zC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.exists
}()
}rH   ©rN   Úpy2Úpy4Nz Styles root is not a directory: úC
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.is_dir
}()
})
ÚexistsrS   rY   rU   rV   rW   rX   rZ   r[   Úis_dir)ÚselfrH   Ú@py_assert1Ú@py_assert3Ú@py_format5s        r.   Ú!test_styles_root_directory_existsz@TestMapStyleDirectoryStructure.test_styles_root_directory_exists^   s”  € àÔ!ÐQÐ!Ð!Ñ#Ô#ÐQÐ#ÐQÕQÔQÐ%QÀKÐ%QÐ%QÑQÔQÐQÑQÐQÕQÔQÑQÔQÐQÐQÕQÔQˆ{ÑQÔQÐQÕQÔQˆ{ÑQÔQÐQÐQÕQÔQÐ!ÑQÔQÕQÔQÐ#ÑQÔQÐQÐQÑQÐQÕQÕQÔQÐQÑQÔQÑQÔQÐQÐQÐQÐQÐQØÔ!ÐUÐ!Ð!Ñ#Ô#ÐUÐ#ÐUÕUÔUÐ%UÈÐ%UÐ%UÑUÔUÐUÑUÐUÕUÔUÑUÔUÐUÐUÕUÔUˆ{ÑUÔUÐUÕUÔUˆ{ÑUÔUÐUÐUÕUÔUÐ!ÑUÔUÕUÔUÐ#ÑUÔUÐUÐUÑUÐUÕUÕUÔUÐUÑUÔUÑUÔUÐUÐUÐUÐUÐUÐUÐUr@   ra   rI   c                ó,  ‡— ˆfd„|D ¦   «         }| }|s}t          j        d|› �¦  «        dz   ddt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndiz  }t          t          j        |¦  «        ¦  «        ‚d}dS )zAAll 30 canonical styles must have a matching lowercase directory.c                óf   •— g | ]-}‰|                      ¦   «         z                       ¦   «         °+|‘Œ.S r?   )Úlowerrk   )Ú.0Ús_idrH   s     €r.   ú
<listcomp>zYTestMapStyleDirectoryStructure.test_all_30_style_subdirectories_exist.<locals>.<listcomp>g   sH   ø€ ð 
ð 
ð 
ØØ $§*¢*¡,¤,Ñ.×6Ò6Ñ8Ô8ð
Øð
ð 
ð 
r@   zMissing style subdirectories: ú
>assert not %(py0)srN   ÚmissingN)rS   rY   rU   rV   rW   rX   rZ   r[   )rl   rH   ra   rx   rm   Ú@py_format2s    `    r.   Ú&test_all_30_style_subdirectories_existzETestMapStyleDirectoryStructure.test_all_30_style_subdirectories_existc   sÄ   ø€ ð
ð 
ð 
ð 
Ø-ð
ñ 
ô 
ˆð ˆ{ÐFˆ{ÐFÕFÔFÐF¸WÐFÐFÑFÔFÐFÑFÐFÐFÕFÔFÑFÔFÐFÐFÕFÔF�7ÑFÔFÐFÕFÔF�7ÑFÔFÐFÐFÐFÑFÐFÕFÕFÔFÐFÑFÔFÑFÔFÐFÐFÐFÐFÐFr@   c                ól  — d„ |D ¦   «         }d„ |                      ¦   «         D ¦   «         }||z
  }| }|s}t          j        d|› �¦  «        dz   ddt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndiz  }t          t          j        |¦  «        ¦  «        ‚d}dS )z=Only the 30 canonical style subdirectories should be present.c                ó6   — h | ]}|                      ¦   «         ’ŒS r?   )rs   )rt   ru   s     r.   ú	<setcomp>z[TestMapStyleDirectoryStructure.test_no_unrecognized_style_subdirectories.<locals>.<setcomp>q   s    € ÐCÐCÐC¨$˜Ÿš™œÐCÐCÐCr@   c                óD   — h | ]}|                      ¦   «         ¯|j        ’ŒS r?   )rk   Úname)rt   Úps     r.   r}   z[TestMapStyleDirectoryStructure.test_no_unrecognized_style_subdirectories.<locals>.<setcomp>r   s7   € ð 
ð 
ð 
Ø°Q·X²X±Z´Zð
ØŒFð
ð 
ð 
r@   z,Unexpected subdirectories in styles folder: rw   rN   Ú
unexpectedN)	ÚiterdirrS   rY   rU   rV   rW   rX   rZ   r[   )rl   rH   ra   Úexpected_dirsÚactual_dirsr�   rm   ry   s           r.   Ú)test_no_unrecognized_style_subdirectorieszHTestMapStyleDirectoryStructure.test_no_unrecognized_style_subdirectoriesm   sæ   € ð DÐCÐ2BÐCÑCÔCˆð
ð 
Ø'×/Ò/Ñ1Ô1ð
ñ 
ô 
ˆð ! =Ñ0ˆ
Øˆ~ÐZˆ~ÐZÕZÔZÐZÈjÐZÐZÑZÔZÐZÑZÐZÐZÕZÔZÑZÔZÐZÐZÕZÔZ�:ÑZÔZÐZÕZÔZ�:ÑZÔZÐZÐZÐZÑZÐZÕZÕZÔZÐZÑZÔZÑZÔZÐZÐZÐZÐZÐZr@   N©rH   r   r"   rd   )rH   r   ra   rI   r"   rd   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rp   rz   r…   r?   r@   r.   rc   rc   [   sd   € € € € € ØJÐJðVð Vð Vð Vð
Gð Gð Gð Gð	[ð 	[ð 	[ð 	[ð 	[ð 	[r@   rc   c                  ó   — e Zd ZdZej                             d e¦   «         ¦  «        dd„¦   «         Zej                             d e¦   «         ¦  «        dd	„¦   «         Z	ej                             d e¦   «         ¦  «        dd
„¦   «         Z
dS )Ú$TestMapStyleFileCompletenessAndMagiczGValidates presence and PNG magic headers for all required style assets.Ústyle_idrH   r   Ústrr"   rd   c                óÜ  ‡— ||                      ¦   «         z  Š‰j        } |¦   «         }|s£t          j        d‰› �¦  «        dz   dt	          j        ¦   «         v st          j        ‰¦  «        rt          j        ‰¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚dx}}ˆfd„t          D ¦   «         }| }|st          j        |› d|› �¦  «        dz   d	d
t	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nd
iz  }t          t          j	        |¦  «        ¦  «        ‚d}dS )z;Each style folder must contain the 9 mandatory asset files.zStyle folder not found: ri   Ú	style_dirrf   Nc                óB   •— g | ]}‰|z                        ¦   «         °|‘ŒS r?   )r'   )rt   Úfnamer�   s     €r.   rv   zaTestMapStyleFileCompletenessAndMagic.test_style_contains_all_9_required_files.<locals>.<listcomp>ƒ   s@   ø€ ð 
ð 
ð 
ØØ Ñ%×.Ò.Ñ0Ô0ð
Øð
ð 
ð 
r@   z missing required files: rw   rN   Úmissing_files)rs   rk   rS   rY   rU   rV   rW   rX   rZ   r[   r   )	rl   rH   r�   rm   rn   ro   r“   ry   r�   s	           @r.   Ú(test_style_contains_all_9_required_fileszMTestMapStyleFileCompletenessAndMagic.test_style_contains_all_9_required_files|   s§  ø€ ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	ØÔÐIÐÐÑ!Ô!ÐIÐ!ÐIÕIÔIÐ#I¸iÐ#IÐ#IÑIÔIÐIÑIÐIÕIÔIÑIÔIÐIÐIÕIÔIˆyÑIÔIÐIÕIÔIˆyÑIÔIÐIÐIÕIÔIÐÑIÔIÕIÔIÐ!ÑIÔIÐIÐIÑIÐIÕIÕIÔIÐIÑIÔIÑIÔIÐIÐIÐIÐIÐIð
ð 
ð 
ð 
Ý3ð
ñ 
ô 
ˆð !Ð ÐWÐ ÐWÕWÔW XÐ"WÐ"WÈÐ"WÐ"WÑWÔWÐWÑWÐWÐWÕWÔWÑWÔWÐWÐWÕWÔW�=ÑWÔWÐWÕWÔW�=ÑWÔWÐWÐWÐWÑWÐWÕWÕWÔWÐWÑWÔWÑWÔWÐWÐWÐWÐWÐWr@   c           	     óÈ  — ||                      ¦   «         z  }t          D �]Á}||z  }|j        } |¦   «         }|s£t          j        d|› �¦  «        dz   dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          t          j
        |¦  «        ¦  «        ‚dx}}|j        } |¦   «         }|j        }	d}
|	|
k    }|sèt          j        d|fd|	|
f¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        t          j        |	¦  «        t          j        |
¦  «        d	œz  }t          j        d
|› �¦  «        dz   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}x}	x}}
t          |¦  «        }|sØt          j        d|› �¦  «        dz   dt          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        dœz  }t          t          j
        |¦  «        ¦  «        ‚d}�ŒÃdS )zEEvery required file must be non-empty and start with PNG magic bytes.zFile does not exist: zD
>assert %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.is_file
}()
}Úfpathrf   Nr   ©ú>)z_%(py6)s
{%(py6)s = %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.stat
}()
}.st_size
} > %(py9)s)rN   rg   rh   rQ   Úpy9zFile is empty: z
>assert %(py11)sÚpy11zInvalid PNG magic in z.
>assert %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}r/   ©rN   rO   rP   )rs   r   r'   rS   rY   rU   rV   rW   rX   rZ   r[   r(   r)   rT   r/   )rl   rH   r�   r�   r’   r–   rm   rn   ro   r]   Ú@py_assert8Ú@py_assert7Ú@py_format10Ú@py_format12r\   Ú@py_format4s                   r.   Ú3test_style_files_have_valid_png_magic_and_non_emptyzXTestMapStyleFileCompletenessAndMagic.test_style_files_have_valid_png_magic_and_non_empty‰   s  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	Ý)ð 	Sñ 	SˆEØ Ñ%ˆEØ”=ÐC�=�=‘?”?ÐC�?ÐCÕCÔCÐ$C¸EÐ$CÐ$CÑCÔCÐCÑCÐCÕCÔCÑCÔCÐCÐCÕCÔC�5ÑCÔCÐCÕCÔC�5ÑCÔCÐCÐCÕCÔC�=ÑCÔCÕCÔC�?ÑCÔCÐCÐCÑCÐCÕCÕCÔCÐCÑCÔCÑCÔCÐCÐCÐCÐCÐCØ”:ÐF�:�:‘<”<ÐF�<Ô'ÐF¨!ÐFÐ'¨!Ò+ÐFÐFÐFÕFÔFÐFÐFÐFÐFÐ'¨!ÐFÑFÔFÐFÕFÔFÑFÔFÐFÐFÕFÔF�5ÑFÔFÐFÕFÔF�5ÑFÔFÐFÐFÕFÔF�:ÑFÔFÕFÔF�<ÑFÔFÕFÔFÐ'ÑFÔFÕFÔF¨!ÑFÔFÐFÐFÑFÐFÕFÔFÐ-F¸uÐ-FÐ-FÑFÔFÐFÑFÐFÐFÐFÑFÐFÕFÕFÔFÐFÑFÔFÑFÔFÐFÐFÐFÐFÐFÐFÐFÐFÐFÐFÐFÝ*¨5Ñ1Ô1ÐRÐ1ÐRÕRÔRÐ3RÈ5Ð3RÐ3RÑRÔRÐRÑRÐRÕRÔRÑRÔRÐRÐRÕRÔRÕ*ÑRÔRÐRÕRÔRÕ*ÑRÔRÐRÐRÐRÕRÔRÑRÔRÐRÐRÕRÔR¨5ÑRÔRÐRÕRÔR¨5ÑRÔRÐRÐRÕRÔRÐ1ÑRÔRÐRÐRÑRÐRÕRÕRÔRÐRÑRÔRÑRÔRÐRÐRÐRÑRð		Sð 	Sr@   c           	     ó  — ||                      ¦   «         z  }t          D �]ä}||z  }t          j        |¦  «        5 }|j        }d}||k    }	|	sÊt          j        d|	fd||f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        ndt          j
        |¦  «        t          j
        |¦  «        dœz  }
t          j        |› d|j        › d�¦  «        dz   d	|
iz  }t          t          j        |¦  «        ¦  «        ‚d
x}x}	}g }|j        }	d}|	|k    }|}|r|j        }d}||k    }|}|�s–t          j        d|fd|	|f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        ndt          j
        |	¦  «        t          j
        |¦  «        dœz  }dd|iz  }|                     |¦  «         |ržt          j        d|fd||f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        ndt          j
        |¦  «        t          j
        |¦  «        dœz  }dd|iz  }|                     |¦  «         t          j        |d¦  «        i z  }t          j        d|› �¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d
x}x}x}	x}x}x}x}}d
d
d
¦  «         n# 1 swxY w Y   �Œæd
S )z@PIL must successfully decode every required file as a PNG image.ÚPNGrL   )z.%(py2)s
{%(py2)s = %(py0)s.format
} == %(py5)sr7   ©rN   rg   Úpy5z format is z, expected PNGú
>assert %(py7)sÚpy7Nr   r—   )z,%(py4)s
{%(py4)s = %(py2)s.width
} > %(py7)s)rg   rh   r§   z%(py9)sr™   )z1%(py13)s
{%(py13)s = %(py11)s.height
} > %(py16)s)rš   Úpy13Úpy16z%(py18)sÚpy18zInvalid dimensions for z
>assert %(py21)sÚpy21)rs   r   r   r*   ÚformatrS   rT   rU   rV   rW   rX   rY   rZ   r[   ÚwidthÚheightÚappendÚ_format_boolop)rl   rH   r�   r�   r’   r–   r7   rm   r^   rn   Ú@py_format6Ú@py_format8Ú@py_assert6r]   Ú@py_assert0Ú@py_assert12Ú@py_assert15Ú@py_assert14rž   Ú@py_format17Ú@py_format19Ú@py_format20Ú@py_format22s                          r.   Ú%test_style_files_are_decodable_by_pilzJTestMapStyleFileCompletenessAndMagic.test_style_files_are_decodable_by_pil•   sä  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	Ý)ð 	[ñ 	[ˆEØ Ñ%ˆEÝ”˜EÑ"Ô"ð [ cØ”zÐ[ UÐ[�z UÒ*Ð[Ð[Ð[Õ[Ô[Ð[Ð[Ð[Ð[�z UÐ[Ñ[Ô[Ð[Õ[Ô[Ñ[Ô[Ð[Ð[Õ[Ô[�sÑ[Ô[Ð[Õ[Ô[�sÑ[Ô[Ð[Ð[Õ[Ô[�zÑ[Ô[Õ[Ô[ UÑ[Ô[Ð[Ð[Ñ[Ð[Õ[Ô[¨uÐ,[Ð,[ÀÄÐ,[Ð,[Ð,[Ñ[Ô[Ð[Ñ[Ð[Ð[Ð[Ñ[Ð[Õ[Õ[Ô[Ð[Ñ[Ô[Ñ[Ô[Ð[Ð[Ð[Ð[Ð[Ð[Ð[ØZÐZ�s”yÐZ 1ÐZ�y 1’}ÐZÐZÐZÐZÐZ¨¬ÐZ°aÐZ¨°aªÐZÐZÐZÐZÑZÕZÔZÐZÐZÐZÐZ�y 1ÐZÑZÔZÐZÕZÔZÑZÔZÐZÐZÕZÔZ�sÑZÔZÐZÕZÔZ�sÑZÔZÐZÐZÕZÔZ�yÑZÔZÕZÔZ 1ÑZÔZÐZÐZÑZÐZÐZÐZÐZÐZÑZÐZÐZ×ZÒZÐZÑZÔZÐZÐZÐZÕZÔZÐZÐZÐZÐZ¨°aÐZÑZÔZÐZÕZÔZÑZÔZÐZÐZÕZÔZ¨ÑZÔZÐZÕZÔZ¨ÑZÔZÐZÐZÕZÔZ¨ÑZÔZÕZÔZ°aÑZÔZÐZÐZÑZÐZÐZÐZÐZÐZÑZÐZÐZ×ZÒZÐZÑZÔZÐZÕZÔZÐZÐZÑZÔZÐZÑZÐZÕZÔZÐ9ZÐSXÐ9ZÐ9ZÑZÔZÐZÑZÐZÐZÐZÑZÐZÕZÕZÔZÐZÑZÔZÑZÔZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZÐZð[ð [ð [ñ [ô [ð [ð [ð [ð [ð [ð [øøøð [ð [ð [ð [ùð	[ð 	[s   »J1K8Ë8K<	Ë?K<	N©rH   r   r�   rŽ   r"   rd   )r‡   rˆ   r‰   rŠ   ÚpytestÚmarkÚparametrizer
   r”   r¡   r¼   r?   r@   r.   rŒ   rŒ   y   sà   € € € € € ØQÐQà„[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAð
Xð 
Xð 
Xñ BÔAð
Xð „[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAð	Sð 	Sð 	Sñ BÔAð	Sð „[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAð	[ð 	[ð 	[ñ BÔAð	[ð 	[ð 	[r@   rŒ   c                  ó   — e Zd ZdZej                             d e¦   «         ¦  «        dd„¦   «         Zej                             d e¦   «         ¦  «        dd	„¦   «         Z	ej                             d e¦   «         ¦  «        dd
„¦   «         Z
dS )ÚTestMapStyleDimensionszFValidates isometric and wall dimension contracts across all 30 styles.r�   rH   r   rŽ   r"   rd   c                óÊ  — ||                      ¦   «         z  }d}|D �]E}||z  }t          j        |¦  «        5 }|j        |j        f}|t
          v }	|	söt          j        d|	fd|t
          f¦  «        dt          j	        ¦   «         v st          j
        |¦  «        rt          j        |¦  «        nddt          j	        ¦   «         v st          j
        t
          ¦  «        rt          j        t
          ¦  «        nddœz  }
t          j        |› d|› d|› d	t
          › �¦  «        d
z   d|
iz  }t          t          j        |¦  «        ¦  «        ‚d}	ddd¦  «         n# 1 swxY w Y   �ŒGdS )z@Floor, path, and liquid tiles must be either 64x32 or 128x64 px.)r   r   r   r   r   r   ©Úin©z%(py0)s in %(py2)sÚdimsr   ©rN   rg   ú/ú dimensions ú not in ú
>assert %(py4)srh   N)rs   r   r*   r­   r®   r   rS   rT   rU   rV   rW   rX   rY   rZ   r[   )rl   rH   r�   r�   Ú
tile_filesr’   r–   r7   rÇ   rm   Ú@py_format3ro   s               r.   Útest_isometric_tile_dimensionsz5TestMapStyleDimensions.test_isometric_tile_dimensions¥   sU  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	ð
ˆ
ð  ð 	ñ 	ˆEØ Ñ%ˆEÝ”˜EÑ"Ô"ð  cØœ	 3¤:Ð.�Ø�Ð.ð ð ð õ ä ðð ð ð �t�ð ñ ô ð õ äñô ð ð õ ìð ñ ô ð õ äð ñ ô ð ð ð õ äñô ð ð õ ìõ  /ñ ô ð õ äõ  /ñ ô ð ð ð ð ñ ð õ ä ð  ÐTÐT %ÐTÐT°TÐTÐTÅ?ÐTÐTñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ùð	ð 	s   ¸DEÅE	ÅE	c                óÆ  — ||                      ¦   «         z  }dD �]E}||z  }t          j        |¦  «        5 }|j        |j        f}|t
          v }|söt          j        d|fd|t
          f¦  «        dt          j	        ¦   «         v st          j
        |¦  «        rt          j        |¦  «        nddt          j	        ¦   «         v st          j
        t
          ¦  «        rt          j        t
          ¦  «        nddœz  }	t          j        |› d|› d|› d	t
          › �¦  «        d
z   d|	iz  }
t          t          j        |
¦  «        ¦  «        ‚d}ddd¦  «         n# 1 swxY w Y   �ŒGdS )zFWall albedo and normal maps must be 128x128 px for vertical extrusion.)r   r   rÄ   rÆ   rÇ   r   rÈ   rÉ   rÊ   rË   rÌ   rh   N)rs   r   r*   r­   r®   r   rS   rT   rU   rV   rW   rX   rY   rZ   r[   )rl   rH   r�   r�   r’   r–   r7   rÇ   rm   rÎ   ro   s              r.   Útest_wall_tile_dimensionsz0TestMapStyleDimensions.test_wall_tile_dimensions·   sL  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	Ø4ð 	ñ 	ˆEØ Ñ%ˆEÝ”˜EÑ"Ô"ð  cØœ	 3¤:Ð.�Ø�Ð.ð ð ð õ ä ðð ð ð �t�ð ñ ô ð õ äñô ð ð õ ìð ñ ô ð õ äð ñ ô ð ð ð õ äñô ð ð õ ìõ  /ñ ô ð õ äõ  /ñ ô ð ð ð ð ñ ð õ ä ð  ÐTÐT %ÐTÐT°TÐTÐTÅ?ÐTÐTñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ùð	ð 	s   ¶DEÅE	ÅE	c                ó  — ||                      ¦   «         z  }|dz  }t          j        |¦  «        5 }|j        }d}||k    }|sÊt	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        dœz  }	t	          j
        |› d|j        › d�¦  «        d	z   d
|	iz  }
t          t	          j        |
¦  «        ¦  «        ‚dx}x}}|j        }d}||k    }|sÊt	          j        d|fd||f¦  «        dt          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        ndt	          j	        |¦  «        t	          j	        |¦  «        dœz  }	t	          j
        |› d|j        › d�¦  «        d	z   d
|	iz  }
t          t	          j        |
¦  «        ¦  «        ‚dx}x}}ddd¦  «         dS # 1 swxY w Y   dS )z;Props sheet must be a non-empty image with width >= height.r   r   )ú>=)z-%(py2)s
{%(py2)s = %(py0)s.width
} >= %(py5)sr7   r¤   z/props.png width z < 64r¦   r§   Nr   )z.%(py2)s
{%(py2)s = %(py0)s.height
} >= %(py5)sz/props.png height z < 32)rs   r   r*   r­   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r®   )rl   rH   r�   r�   Ú
props_pathr7   rm   r^   rn   r±   r²   s              r.   Útest_props_sheet_dimensionsz2TestMapStyleDimensions.test_props_sheet_dimensionsÅ   s§  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	Ø Ñ,ˆ
ÝŒZ˜
Ñ#Ô#ð 	V sØ”9ÐR ÐR�9 ’?ÐRÐRÐRÕRÔRÐRÐRÐRÐR�9 ÐRÑRÔRÐRÕRÔRÑRÔRÐRÐRÕRÔR�3ÑRÔRÐRÕRÔR�3ÑRÔRÐRÐRÕRÔR�9ÑRÔRÕRÔR ÑRÔRÐRÐRÑRÐRÕRÔR xÐ$RÐ$RÀ#Ä)Ð$RÐ$RÐ$RÑRÔRÐRÑRÐRÐRÐRÑRÐRÕRÕRÔRÐRÑRÔRÑRÔRÐRÐRÐRÐRÐRÐRÐRØ”:ÐU ÐU�: Ò#ÐUÐUÐUÕUÔUÐUÐUÐUÐU�: ÐUÑUÔUÐUÕUÔUÑUÔUÐUÐUÕUÔU�3ÑUÔUÐUÕUÔU�3ÑUÔUÐUÐUÕUÔU�:ÑUÔUÕUÔU ÑUÔUÐUÐUÑUÐUÕUÔU¨Ð%UÐ%UÀCÄJÐ%UÐ%UÐ%UÑUÔUÐUÑUÐUÐUÐUÑUÐUÕUÕUÔUÐUÑUÔUÑUÔUÐUÐUÐUÐUÐUÐUÐUð	Vð 	Vð 	Vñ 	Vô 	Vð 	Vð 	Vð 	Vð 	Vð 	Vð 	Vð 	Vøøøð 	Vð 	Vð 	Vð 	Vð 	Vð 	Vs   ±GHÈHÈHNr½   )r‡   rˆ   r‰   rŠ   r¾   r¿   rÀ   r
   rÏ   rÑ   rÕ   r?   r@   r.   rÂ   rÂ   ¢   sØ   € € € € € ØPÐPà„[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAðð ð ñ BÔAðð" „[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAðð ð ñ BÔAðð „[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAðVð Vð Vñ BÔAðVð Vð Vr@   rÂ   c                  ól   — e Zd ZdZej                             d e¦   «         ¦  «        d
d„¦   «         Zd	S )Ú"TestMapStyleNormalMapsTangentSpacezEValidates tangent-space normal maps Blue channel dominance (> 128.0).r�   rH   r   rŽ   r"   rd   c           	     óø  — ||                      ¦   «         z  }t          D ]Ú}||z  }t          |¦  «        }d}||k    }|s¶t          j        d|fd||f¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        dœz  }	t          j	        |› d|› d|d›d	�¦  «        d
z   d|	iz  }
t          t          j        |
¦  «        ¦  «        ‚dx}}ŒÛdS )zCNormal maps must have Blue channel mean > 128 for lighting shaders.ç      `@r—   )z%(py0)s > %(py3)sÚb_mean©rN   rP   rÉ   z B-channel mean ú.2fz	 <= 128.0z
>assert %(py5)sr¥   N)rs   r   r8   rS   rT   rU   rV   rW   rX   rY   rZ   r[   )rl   rH   r�   r�   r’   r–   rÚ   r\   rm   r    r±   s              r.   Ú'test_normal_maps_blue_channel_dominancezJTestMapStyleNormalMapsTangentSpace.test_normal_maps_blue_channel_dominanceÔ   s³  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	Ý%ð 	ð 	ˆEØ Ñ%ˆEÝ.¨uÑ5Ô5ˆFØ!ð �6˜E’>ð ð ð õ ìðð ð ð �6˜Eð ñ ô ð õ äñô ð ð õ ìð ñ ô ð õ äð ñ ô ð ð õ äð "ñ ô ð ð ñ ð õ ìð ÐJÐJ˜eÐJÐJ°VÐJÐJÐJÐJñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ð ð ð ð	ð 	r@   Nr½   )	r‡   rˆ   r‰   rŠ   r¾   r¿   rÀ   r
   rÝ   r?   r@   r.   r×   r×   Ñ   sV   € € € € € ØOÐOà„[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAð
ð 
ð 
ñ BÔAð
ð 
ð 
r@   r×   c                  ót   — e Zd ZdZej                             d e¦   «         ¦  «        dd„¦   «         Zdd	„Z	d
S )ÚTestMapStyleFileSizeAndBudgetzCValidates file size budgets for mobile efficiency and fast loading.r�   rH   r   rŽ   r"   rd   c           	     óŒ  — ||                      ¦   «         z  }t          D �]#}||z  }|                     ¦   «         j        }|t          k     }|sót          j        d|fd|t          f¦  «        dt          j        ¦   «         v st          j	        |¦  «        rt          j
        |¦  «        nddt          j        ¦   «         v st          j	        t          ¦  «        rt          j
        t          ¦  «        nddœz  }t          j        |› d|› d|dz  d	›d
�¦  «        dz   d|iz  }	t          t          j        |	¦  «        ¦  «        ‚d}�Œ%dS )zBIndividual tile textures and normal maps must be strictly < 60 KB.©ú<©z%(py0)s < %(py2)sÚ
size_bytesr   rÈ   rÉ   z size i   z.1fz KB >= 60 KB budgetrÌ   rh   N)rs   r   r(   r)   r   rS   rT   rU   rV   rW   rX   rY   rZ   r[   )
rl   rH   r�   r�   r’   r–   rä   rm   rÎ   ro   s
             r.   Ú%test_individual_tile_files_under_60kbzCTestMapStyleFileSizeAndBudget.test_individual_tile_files_under_60kbå   só  € ð
   (§.¢.Ñ"2Ô"2Ñ2ˆ	Ý)ð 	ñ 	ˆEØ Ñ%ˆEØŸš™œÔ-ˆJØÕ 8Ò8ð ð ð õ ìðð ð ð �:Õ 8ð ñ ô ð õ äñô ð ð õ ìð ñ ô ð õ äð ñ ô ð ð ð õ äñô ð ð õ ìõ !9ñ ô ð õ äõ !9ñ ô ð ð ð ð ñ ð õ ìð ÐUÐU˜eÐUÐU¨:¸Ñ+<ÐUÐUÐUÐUñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ñ ð	ð 	r@   c                óX  — t          d„ |                     d¦  «        D ¦   «         ¦  «        }|t          k     }|sît          j        d|fd|t          f¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddt          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddœz  }t          j	        d|d	z  d
›d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d}dS )zCTotal size of all assets under map/styles must be strictly < 10 MB.c              3  óp   K  — | ]1}|                      ¦   «         ¯|                     ¦   «         j        V — Œ2d S )N)r'   r(   r)   )rt   r,   s     r.   ú	<genexpr>zYTestMapStyleFileSizeAndBudget.test_total_assets_folder_size_under_10mb.<locals>.<genexpr>ô   sN   è è € ð 
ð 
Ø!"ÀÇ	Â	ÁÄð
Ø�FŠF‰HŒHÔð
ð 
ð 
ð 
ð 
ð 
r@   Ú*rá   rã   Ú
total_sizer    rÈ   zTotal styles size i   rÜ   z MB >= 10 MB budgetrÌ   rh   N)ÚsumÚrglobr    rS   rT   rU   rV   rW   rX   rY   rZ   r[   )rl   rH   rê   rm   rÎ   ro   s         r.   Ú(test_total_assets_folder_size_under_10mbzFTestMapStyleFileSizeAndBudget.test_total_assets_folder_size_under_10mbò   sÝ  € åð 
ð 
Ø&1×&7Ò&7¸Ñ&<Ô&<ð
ñ 
ô 
ñ 
ô 
ˆ
ð Õ7Ò7ð 	
ð 	
ð 	
õ 	
ìð	
ð 	
ð 	
ð 	
ˆzÕ7ð 	
ñ 	
ô 	
ð 	
õ 	
ä	ñ	
ô 	
ð 	
ð 	
õ 	
ìð ñ 	
ô 	
ð 	
õ 	
ä 	ð ñ 	
ô 	
ð 	
ð 	
ð 	
õ 	
ä	ñ	
ô 	
ð 	
ð 	
õ 	
ìõ 8ñ 	
ô 	
ð 	
õ 	
ä 	õ 8ñ 	
ô 	
ð 	
ð 	
ð 	
ð 	
ñ 	
ð 	
õ 	
ìð U ¨{Ñ!;ÐTÐTÐTÐTñ	
ô 	
ð 	
ñ 	
ð 	
ð 	
ð 	
ñ 	
ð 	
õ 	
õ 	
ìð	
ñ 	
ô 	
ñ 	
ô 	
ð 	
ð 	
ð 	
ð 	
ð 	
r@   Nr½   r†   )
r‡   rˆ   r‰   rŠ   r¾   r¿   rÀ   r
   rå   rí   r?   r@   r.   rß   rß   â   sj   € € € € € ØMÐMà„[×Ò˜ZÐ)>Ð)>Ñ)@Ô)@ÑAÔAð
ð 
ð 
ñ BÔAð
ð
ð 
ð 
ð 
ð 
ð 
r@   rß   c                  ó:   — e Zd ZdZdd„Zdd„Zdd„Zdd	„Zdd
„ZdS )Ú(TestMapStyleAssetAdversarialAndEdgeCaseszEAdversarial stress tests for integrity validators and error handling.Útmp_pathr   r"   rd   c                óê  — |dz  }|                      d¦  «         t          |¦  «        }| }|sÀddt          j        ¦   «         v st	          j        t          ¦  «        rt	          j        t          ¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        ndt	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚dx}}dS )z.Corrupted header bytes must fail verification.zcorrupt.pngs   NOT_A_PNG_FILE_HEADERú0assert not %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}r/   Ú	fake_filer›   N©	Úwrite_bytesr/   rU   rV   rS   rW   rX   rZ   r[   ©rl   rð   ró   r\   r^   ro   s         r.   Ú&test_corrupt_png_magic_header_detectedzOTestMapStyleAssetAdversarialAndEdgeCases.test_corrupt_png_magic_header_detectedÿ   sÿ   € à˜}Ñ,ˆ	Ø×ÒÐ6Ñ7Ô7Ð7Ý*¨9Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ð5Õ5Ô5Ñ5Ô5Ð5Ð5Õ5Ô5Õ*Ñ5Ô5Ð5Õ5Ô5Õ*Ñ5Ô5Ð5Ð5Ð5Õ5Ô5Ñ5Ô5Ð5Ð5Õ5Ô5¨9Ñ5Ô5Ð5Õ5Ô5¨9Ñ5Ô5Ð5Ð5Õ5Ô5Ð5Ñ5Ô5Ð5Ð5Ñ5Ð5Õ5Õ5Ô5Ð5Ñ5Ô5Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5Ð5r@   c                óê  — |dz  }|                      d¦  «         t          |¦  «        }| }|sÀddt          j        ¦   «         v st	          j        t          ¦  «        rt	          j        t          ¦  «        nddt          j        ¦   «         v st	          j        |¦  «        rt	          j        |¦  «        ndt	          j        |¦  «        dœz  }t          t	          j        |¦  «        ¦  «        ‚dx}}dS )z5Files with fewer than 8 bytes must fail verification.ztruncated.pngs   ‰PNGrò   r/   ró   r›   Nrô   rö   s         r.   Ú#test_truncated_header_file_detectedzLTestMapStyleAssetAdversarialAndEdgeCases.test_truncated_header_file_detected  sþ   € à˜Ñ.ˆ	Ø×Ò˜jÑ)Ô)Ð)Ý*¨9Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5Ð5Ð5Õ5Ô5Ñ5Ô5Ð5Ð5Õ5Ô5Õ*Ñ5Ô5Ð5Õ5Ô5Õ*Ñ5Ô5Ð5Ð5Ð5Õ5Ô5Ñ5Ô5Ð5Ð5Õ5Ô5¨9Ñ5Ô5Ð5Õ5Ô5¨9Ñ5Ô5Ð5Ð5Õ5Ô5Ð5Ñ5Ô5Ð5Ð5Ñ5Ð5Õ5Õ5Ô5Ð5Ñ5Ô5Ñ5Ô5Ð5Ð5Ð5Ð5Ð5Ð5Ð5r@   c                óÀ  — |dz  }t          |¦  «        }| }|sÀddt          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        nddt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        dœz  }t          t          j        |¦  «        ¦  «        ‚dx}}dS )z7Missing file must safely return False without crashing.z	ghost.pngrò   r/   Úghostr›   N)r/   rU   rV   rS   rW   rX   rZ   r[   )rl   rð   rû   r\   r^   ro   s         r.   Útest_nonexistent_file_detectedzGTestMapStyleAssetAdversarialAndEdgeCases.test_nonexistent_file_detected  sê   € à˜;Ñ&ˆÝ*¨5Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1Õ*Ñ1Ô1Ð1Õ1Ô1Õ*Ñ1Ô1Ð1Ð1Ð1Õ1Ô1Ñ1Ô1Ð1Ð1Õ1Ô1¨5Ñ1Ô1Ð1Õ1Ô1¨5Ñ1Ô1Ð1Ð1Õ1Ô1Ð1Ñ1Ô1Ð1Ð1Ñ1Ð1Õ1Õ1Ô1Ð1Ñ1Ô1Ñ1Ô1Ð1Ð1Ð1Ð1Ð1Ð1Ð1r@   c                óÒ  — |dz  }t          j        ddd¦  «        }|                     |d¬¦  «         t          |¦  «        }d}||k    }|s—t	          j        d|fd	||f¦  «        d
t          j        ¦   «         v st	          j        |¦  «        rt	          j	        |¦  «        nd
t	          j	        |¦  «        dœz  }dd|iz  }t          t	          j        |¦  «        ¦  «        ‚dx}}dS )z9Normal map with Blue channel mean <= 128 must be flagged.zbad_normal.pngÚRGBr   )éÈ   rÿ   rK   r£   )r¬   rÙ   )ú<=)z%(py0)s <= %(py3)srÚ   rÛ   zassert %(py5)sr¥   N)r   ÚnewÚsaver8   rS   rT   rU   rV   rW   rX   rZ   r[   )	rl   rð   Úbad_normr7   rÚ   r\   rm   r    r±   s	            r.   Ú)test_low_blue_channel_normal_map_detectedzRTestMapStyleAssetAdversarialAndEdgeCases.test_low_blue_channel_normal_map_detected  s
  € àÐ.Ñ.ˆÝŒi˜˜x¨Ñ8Ô8ˆØ�Š� %ˆÑ(Ô(Ð(Ý*¨8Ñ4Ô4ˆØÐˆv˜ŠÐÐÐÕÔÐÐÐÐˆv˜ÐÑÔÐÕÔÑÔÐÐÕÔˆvÑÔÐÕÔˆvÑÔÐÐÕÔ˜ÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐÐÐr@   c                ó‚  — d}|t           v}|sÑt          j        d|fd|t           f¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nddt          j        ¦   «         v st          j        t           ¦  «        rt          j        t           ¦  «        nddœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d	}|t          v}|sÑt          j        d|fd|t          f¦  «        dt          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndd
t          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nd
dœz  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚d	}d	S )zJArbitrary dimension (e.g. 100x100) must not match tile or wall dimensions.)éd   r  )únot in)z%(py0)s not in %(py2)sÚdimr   rÈ   zassert %(py4)srh   Nr   )
r   rS   rT   rU   rV   rW   rX   rZ   r[   r   )rl   r  rm   rÎ   ro   s        r.   Ú#test_invalid_tile_dimension_flaggedzLTestMapStyleAssetAdversarialAndEdgeCases.test_invalid_tile_dimension_flagged  sÓ  € àˆØ�/Ð)Ð)Ð)Ð)Õ)Ô)Ð)Ð)Ð)Ð)ˆs�/Ð)Ñ)Ô)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)ˆsÑ)Ô)Ð)Õ)Ô)ˆsÑ)Ô)Ð)Ð)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)�/Ñ)Ô)Ð)Õ)Ô)�/Ñ)Ô)Ð)Ð)Ð)Ð)Ñ)Ð)Ð)Ð)Ð)Ð)Ñ)Ð)Õ)Õ)Ô)Ð)Ñ)Ô)Ñ)Ô)Ð)Ð)Ð)Ø�/Ð)Ð)Ð)Ð)Õ)Ô)Ð)Ð)Ð)Ð)ˆs�/Ð)Ñ)Ô)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)ˆsÑ)Ô)Ð)Õ)Ô)ˆsÑ)Ô)Ð)Ð)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)�/Ñ)Ô)Ð)Õ)Ô)�/Ñ)Ô)Ð)Ð)Ð)Ð)Ñ)Ð)Ð)Ð)Ð)Ð)Ñ)Ð)Õ)Õ)Ô)Ð)Ñ)Ô)Ñ)Ô)Ð)Ð)Ð)Ð)Ð)r@   N)rð   r   r"   rd   )r"   rd   )	r‡   rˆ   r‰   rŠ   r÷   rù   rü   r  r	  r?   r@   r.   rï   rï   ü   s~   € € € € € ØOÐOð6ð 6ð 6ð 6ð6ð 6ð 6ð 6ð2ð 2ð 2ð 2ð
ð ð ð ð*ð *ð *ð *ð *ð *r@   rï   )r!   r   r"   r#   )r!   r   r"   r0   )r"   r   )rA   r   r"   r   )r"   rI   ))rŠ   Ú
__future__r   ÚbuiltinsrU   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterS   Úpathlibr   Útypingr   r   r   r¾   ÚPILr   r	   Úserver.world.map_style_catalogr
   r   Ú__annotations__r   r   r   r   r   r    r/   r8   ÚfixturerA   rH   ra   rc   rŒ   rÂ   r×   rß   rï   r?   r@   r.   ú<module>r     s  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € Ð Ð Ð Ð Ð Ð Ø #Ð #Ð #Ð #Ð #Ð #Ð #Ð #Ð #Ð #à €€€Ø  Ð  Ð  Ð  Ð  Ð  Ð  Ð  à @Ð @Ð @Ð @Ð @Ð @à'€	Ð 'Ð 'Ð 'Ñ 'ð
)Ð ð 
ð 
ð 
ñ 
ð%Ð ð ð ð ñ ð *2°9Ð(=€Ð =Ð =Ð =Ñ =Ø)3¨€Ð 4Ð 4Ð 4Ñ 4à )Ð Ð )Ð )Ð )Ñ )Ø#3Ð Ð 3Ð 3Ð 3Ñ 3ðð ð ð ðð ð ð ð €„�hÐÑÔð9ð 9ð 9ñ  Ôð9ð
 €„�hÐÑÔðLð Lð Lñ  ÔðLð
 €„�hÐÑÔðð ð ñ  Ôðð[ð [ð [ð [ð [ñ [ô [ð [ð<&[ð &[ð &[ð &[ð &[ñ &[ô &[ð &[ðR,Vð ,Vð ,Vð ,Vð ,Vñ ,Vô ,Vð ,Vð^ð ð ð ð ñ ô ð ð"
ð 
ð 
ð 
ð 
ñ 
ô 
ð 
ð4 *ð  *ð  *ð  *ð  *ñ  *ô  *ð  *ð  *ð  *r@   