§
    [¿jœ7  ã                  ó¤  — U d Z ddlmZ ddlZddlmc mZ ddl	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mZ ddlZddlmZmZ ddlmZ de_         ee¦  «                             ¦   «         j        j        j        Zed	z  d
z  dz  dz  dz  Z dZ!de"d<   dd„Z# G d„ d¦  «        Z$ G d„ d¦  «        Z% G d„ d¦  «        Z& G d„ d¦  «        Z'dS )a&  
Adversarial Stress Test Suite for FreeExile 30 Map Styles Assets.
Verifies decompression throughput, SLA latencies, concurrent thread safety,
memory footprint constraints (< 500 KB active biome, < 8 MB all 30 styles),
and resilience against corrupt, zero-byte, truncated, and malicious files.
é    )ÚannotationsN)ÚPath)ÚDictÚListÚTuple)ÚImageÚ	ImageFile)Úlist_available_stylesFÚclientÚwebappÚassetsÚmapÚstyles)	ú	floor.pngúfloor_normal.pngúwall.pngúwall_normal.pngúpath.pngúpath_normal.pngú
liquid.pngúliquid_normal.pngú	props.pngzTuple[str, ...]ÚCORE_ASSET_NAMESÚ	file_pathr   ÚreturnúTuple[int, int, float]c                ó   — t          j        ¦   «         }t          j        | ¦  «        5 }|                     ¦   «          |j        |j        }}ddd¦  «         n# 1 swxY w Y   t          j        ¦   «         |z
  dz  }|||fS )z@Decompresses image file and returns (width, height, elapsed_ms).Nç     @�@)ÚtimeÚperf_counterr   ÚopenÚloadÚwidthÚheight)r   Út0ÚimgÚwÚhÚ
elapsed_mss         úFC:\Projects\FreeExile\tests\unit\test_map_styles_adversarial_stress.pyÚ_load_and_decompressr+   *   s³   € å	Ô	Ñ	Ô	€BÝ	Œ�IÑ	Ô	ð % #Ø�Š‰
Œ
ˆ
ØŒy˜#œ*ˆ1ˆð%ð %ð %ñ %ô %ð %ð %ð %ð %ð %ð %øøøð %ð %ð %ð %õ Ô#Ñ%Ô%¨Ñ*¨fÑ4€JØˆa�ÐÐs   ¨#AÁAÁAc                  ó*   — e Zd ZdZdd„Zdd„Zdd„ZdS )	Ú)TestAssetDecompressionAndThroughputStresszHStress-tests decompression latencies, throughput, and concurrent access.r   ÚNonec                ó¢  — g }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  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}x}}|D ]–}t          |                     ¦   «         z  }	t          D ]-}
t          |	|
z  ¦  «        \  }}}|                     |¦  «         Œ.|	d
z                       d¦  «        D ]*}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  }dd|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}x}}t!          |¦  «        }t#          |¦  «        t          |¦  «        z  }t%          |¦  «        }|t'          t          |¦  «        dz  ¦  «                 }|t'          t          |¦  «        dz  ¦  «                 }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z   d|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}}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z   d|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}}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z   d|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}}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z   d|iz  }t          t          j	        |¦  «        ¦  «        ‚d	x}}d	S )&z;Every single asset must decompress within p99 < 25.0ms SLA.é   ©ú==©z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sÚlenr   ©Úpy0Úpy1Úpy3Úpy6úassert %(py8)sÚpy8NÚpropsú*.pngih  Ú	latenciesgffffffî?g®Gáz®ï?g      9@©ú<©z%(py0)s < %(py3)sÚmax_lat©r6   r8   zMax decompression latency ú.2fz
ms >= 25msú
>assert %(py5)sÚpy5g      @Úp99_latzP99 latency z	ms >= 5msg       @Úp95_latzP95 latency z	ms >= 2msg      ð?Úmean_latzMean latency z	ms >= 1ms)r
   r4   Ú
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanationÚSTYLES_ROOTÚlowerr   r+   ÚappendÚglobÚmaxÚsumÚsortedÚintÚ_format_assertmsg)Úselfr>   r   Ú@py_assert2Ú@py_assert5Ú@py_assert4Ú@py_format7Ú@py_format9Ús_idÚs_dirÚfnameÚ_ÚelapsedÚp_filerB   rI   Ú
sorted_latrH   rG   Ú@py_assert1Ú@py_format4Ú@py_format6s                         r*   Ú%test_all_360_assets_decompression_slazOTestAssetDecompressionAndThroughputStress.test_all_360_assets_decompression_sla7   sê  € à!#ˆ	Ý&Ñ(Ô(ˆÝ�6‰{Œ{Ð ˜bÐ ˆ{˜bÒ Ð Ð Ð Õ Ô Ð Ð Ð Ð ˆ{˜bÐ Ñ Ô Ð Õ Ô Ñ Ô Ð Ð Õ Ô �sÑ Ô Ð Õ Ô �sÑ Ô Ð Ð Ð Õ Ô Ñ Ô Ð Ð Õ Ô �6Ñ Ô Ð Õ Ô �6Ñ Ô Ð Ð Õ Ô ˆ{Ñ Ô Õ Ô ˜bÑ Ô Ð Ð Ñ Ð Ð Ð Ð Ð Ñ Ð Õ Õ Ô Ð Ñ Ô Ñ Ô Ð Ð Ð Ð Ð Ð Ð àð 	*ð 	*ˆDÝ $§*¢*¡,¤,Ñ.ˆEÝ)ð *ð *�Ý 4°U¸U±]Ñ CÔ C‘��1�gØ× Ò  Ñ)Ô)Ð)Ð)Ø  7™?×0Ò0°Ñ9Ô9ð *ð *�Ý 4°VÑ <Ô <‘��1�gØ× Ò  Ñ)Ô)Ð)Ð)ð*õ �9‰~Œ~Ð$ Ð$ˆ~ Ò$Ð$Ð$Ð$Õ$Ô$Ð$Ð$Ð$Ð$ˆ~ Ð$Ñ$Ô$Ð$Õ$Ô$Ñ$Ô$Ð$Ð$Õ$Ô$�sÑ$Ô$Ð$Õ$Ô$�sÑ$Ô$Ð$Ð$Ð$Õ$Ô$Ñ$Ô$Ð$Ð$Õ$Ô$�9Ñ$Ô$Ð$Õ$Ô$�9Ñ$Ô$Ð$Ð$Õ$Ô$ˆ~Ñ$Ô$Õ$Ô$ Ñ$Ô$Ð$Ð$Ñ$Ð$Ð$Ð$Ð$Ð$Ñ$Ð$Õ$Õ$Ô$Ð$Ñ$Ô$Ñ$Ô$Ð$Ð$Ð$Ð$Ð$Ð$Ð$Ý�i‘.”.ˆÝ�y‘>”>¥C¨	¡N¤NÑ2ˆÝ˜IÑ&Ô&ˆ
Ø�S¥ Z¡¤°4Ñ!7Ñ8Ô8Ô9ˆØ�S¥ Z¡¤°4Ñ!7Ñ8Ô8Ô9ˆàÐSˆw˜Š~ÐSÐSÐSÕSÔSÐSÐSÐSÐSˆw˜ÐSÑSÔSÐSÕSÔSÑSÔSÐSÐSÕSÔSˆwÑSÔSÐSÕSÔSˆwÑSÔSÐSÐSÕSÔS˜ÑSÔSÐSÐSÑSÐSÕSÔSÐS¸GÐSÐSÐSÐSÑSÔSÐSÑSÐSÐSÐSÑSÐSÕSÕSÔSÐSÑSÔSÑSÔSÐSÐSÐSÐSÐSØÐCˆw˜Š}ÐCÐCÐCÕCÔCÐCÐCÐCÐCˆw˜ÐCÑCÔCÐCÕCÔCÑCÔCÐCÐCÕCÔCˆwÑCÔCÐCÕCÔCˆwÑCÔCÐCÐCÕCÔC˜ÑCÔCÐCÐCÑCÐCÕCÔCÐC¨WÐ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ˆw˜Š}ÐCÐCÐCÕCÔCÐCÐCÐCÐCˆw˜ÐCÑCÔCÐCÕCÔCÑCÔCÐCÐCÕCÔCˆwÑCÔCÐCÕCÔCˆwÑCÔCÐCÐCÕCÔC˜ÑCÔCÐCÐCÑCÐCÕCÔCÐC¨WÐ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ˆx˜#Š~ÐFÐFÐFÕFÔFÐFÐFÐFÐFˆx˜#ÐFÑFÔFÐFÕFÔFÑFÔFÐFÐFÕFÔFˆxÑFÔFÐFÕFÔFˆxÑFÔFÐFÐFÕFÔF˜#ÑFÔFÐFÐFÑFÐFÕFÔFÐF¨xÐ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ó    c           	     ó"  — t          ¦   «         }g }t          d¦  «        D ]±}|D ]¬}t          |                     ¦   «         z  }t	          j        ¦   «         }t          D ]E}t          j        ||z  ¦  «        5 }| 	                    ¦   «          ddd¦  «         n# 1 swxY w Y   ŒFt	          j        ¦   «         |z
  dz  }	| 
                    |	¦  «         Œ­Œ²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  }d
d|iz  }t%          t          j        |¦  «        ¦  «        ‚dx}
x}}t)          |¦  «        t          |¦  «        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z   d|iz  }t%          t          j        |¦  «        ¦  «        ‚dx}}
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z   d|iz  }t%          t          j        |¦  «        ¦  «        ‚dx}}
dS )z@Simulates rapid player traversal across 30 biomes over 3 cycles.é   Nr   éZ   r1   r3   r4   Útotal_biome_timesr5   r:   r;   g      .@r?   rA   Úavg_switch_timerC   zAverage switch rD   z
ms >= 15msrE   rF   g      I@Úmax_switch_timezMax switch z
ms >= 50ms)r
   ÚrangerR   rS   r   r    r   r   r!   r"   rT   r4   rJ   rK   rL   rM   rN   rO   rP   rQ   rW   rV   rZ   )r[   r   rp   rd   ra   rb   r%   rc   r&   Úbiome_time_msr\   r]   r^   r_   r`   rq   rr   rh   ri   rj   s                       r*   Ú!test_rapid_biome_switching_stresszKTestAssetDecompressionAndThroughputStress.test_rapid_biome_switching_stressR   s'  € å&Ñ(Ô(ˆØ)+Ðå�q‘”ð 	8ð 	8ˆAØð 8ð 8�Ý# d§j¢j¡l¤lÑ2�ÝÔ&Ñ(Ô(�Ý-ð #ð #�EÝœ E¨E¡MÑ2Ô2ð #°cØŸš™
œ
˜
ð#ð #ð #ñ #ô #ð #ð #ð #ð #ð #ð #øøøð #ð #ð #ð #øå!%Ô!2Ñ!4Ô!4°rÑ!9¸VÑ C�Ø!×(Ò(¨Ñ7Ô7Ð7Ð7ð8õ Ð$Ñ%Ô%Ð+¨Ð+Ð%¨Ò+Ð+Ð+Ð+Õ+Ô+Ð+Ð+Ð+Ð+Ð%¨Ð+Ñ+Ô+Ð+Õ+Ô+Ñ+Ô+Ð+Ð+Õ+Ô+�sÑ+Ô+Ð+Õ+Ô+�sÑ+Ô+Ð+Ð+Ð+Õ+Ô+Ñ+Ô+Ð+Ð+Õ+Ô+Ð$Ñ+Ô+Ð+Õ+Ô+Ð$Ñ+Ô+Ð+Ð+Õ+Ô+Ð%Ñ+Ô+Õ+Ô+¨Ñ+Ô+Ð+Ð+Ñ+Ð+Ð+Ð+Ð+Ð+Ñ+Ð+Õ+Õ+Ô+Ð+Ñ+Ô+Ñ+Ô+Ð+Ð+Ð+Ð+Ð+Ð+Ð+ÝÐ/Ñ0Ô0µ3Ð7HÑ3IÔ3IÑIˆÝÐ/Ñ0Ô0ˆØ!%ÐXˆ Ò%ÐXÐXÐXÕXÔXÐXÐXÐXÐXˆ ÐXÑXÔXÐXÕXÔXÑXÔXÐXÐXÕXÔXˆÑXÔXÐXÕXÔXˆÑXÔXÐXÐXÕXÔX ÑXÔXÐXÐXÑXÐXÕXÔXÐ'X¸Ð'XÐ'XÐ'XÐ'XÑXÔXÐXÑXÐXÐXÐXÑXÐXÕXÕXÔXÐXÑXÔXÑXÔXÐXÐXÐXÐXÐXØ!%ÐTˆ Ò%ÐTÐTÐTÕTÔTÐTÐTÐTÐTˆ ÐTÑTÔTÐTÕTÔTÑTÔTÐTÐTÕTÔTˆÑTÔTÐTÕTÔTˆÑTÔTÐTÐTÕTÔT ÑTÔTÐTÐTÑTÐTÕTÔTÐ'T°_Ð'TÐ'TÐ'TÐ'TÑTÔTÐTÑTÐTÐTÐTÑTÐTÕTÕTÔTÐTÑTÔTÑTÔTÐTÐTÐTÐTÐTÐTÐTs   Á5B	ÂBÂBc           	     ó’  ‡‡‡— t          ¦   «         }g }|D ]D}t          |                     ¦   «         z  Š|                     ˆfd„t          D ¦   «         ¦  «         ŒEdd„Št
          j                             d¬¦  «        5 Šˆˆfd	„|D ¦   «         }d
„ t
          j                             |¦  «        D ¦   «         }ddd¦  «         n# 1 swxY w Y   t          |¦  «        }t          |¦  «        }||k    }|�sxt          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        |¦  «        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  }	dd|	iz  }
t!          t          j        |
¦  «        ¦  «        ‚dx}x}}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}dS )z<20 concurrent threads decompressing textures simultaneously.c              3  ó"   •K  — | ]	}‰|z  V — Œ
d S )N© )Ú.0Úfrb   s     €r*   ú	<genexpr>ziTestAssetDecompressionAndThroughputStress.test_concurrent_multi_threaded_decompression.<locals>.<genexpr>m   s'   øè è € Ð=Ð= q˜ ™Ð=Ð=Ð=Ð=Ð=Ð=rl   Úpathr   r   Úboolc                ó²   — t          j        | ¦  «        5 }|                     ¦   «          |j        dk    o
|j        dk    cd d d ¦  «         S # 1 swxY w Y   d S )Nr   )r   r!   r"   r#   r$   )r|   r&   s     r*   ÚworkerzfTestAssetDecompressionAndThroughputStress.test_concurrent_multi_threaded_decompression.<locals>.workero   s”   € Ý”˜DÑ!Ô!ð 8 SØ—’‘
”
�
Ø”y 1’}Ð7¨¬°aªð8ð 8ð 8ð 8ñ 8ô 8ð 8ð 8ð 8ð 8ð 8ð 8øøøð 8ð 8ð 8ð 8ð 8ð 8s   •*AÁAÁAé   )Úmax_workersc                ó<   •— g | ]}‰                      ‰|¦  «        ‘ŒS rx   )Úsubmit)ry   ÚpÚexecutorr   s     €€r*   ú
<listcomp>zjTestAssetDecompressionAndThroughputStress.test_concurrent_multi_threaded_decompression.<locals>.<listcomp>u   s'   ø€ ÐAÐAÐA°a�x—’ v¨qÑ1Ô1ÐAÐAÐArl   c                ó6   — g | ]}|                      ¦   «         ‘ŒS rx   )Úresult)ry   rz   s     r*   r†   zjTestAssetDecompressionAndThroughputStress.test_concurrent_multi_threaded_decompression.<locals>.<listcomp>v   s    € ÐTÐTÐT a�q—x’x‘z”zÐTÐTÐTrl   Nr1   )zN%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py8)s
{%(py8)s = %(py5)s(%(py6)s)
}r4   ÚresultsÚtasks)r6   r7   r8   rF   r9   r;   zassert %(py10)sÚpy10z,assert %(py3)s
{%(py3)s = %(py0)s(%(py1)s)
}Úall)r6   r7   r8   )r|   r   r   r}   )r
   rR   rS   Úextendr   Ú
concurrentÚfuturesÚThreadPoolExecutorÚas_completedr4   rJ   rK   rL   rM   rN   rO   rP   rQ   rŒ   )r[   r   rŠ   ra   r�   r‰   r\   Ú@py_assert7r^   r`   Ú@py_format11ri   r…   rb   r   s               @@@r*   Ú,test_concurrent_multi_threaded_decompressionzVTestAssetDecompressionAndThroughputStress.test_concurrent_multi_threaded_decompressiong   s“  øøø€ å&Ñ(Ô(ˆØˆØð 	>ð 	>ˆDÝ $§*¢*¡,¤,Ñ.ˆEØ�LŠLÐ=Ð=Ð=Ð=Õ,<Ð=Ñ=Ô=Ñ=Ô=Ð=Ð=ð	8ð 	8ð 	8ð 	8õ
 Ô×2Ò2¸rÐ2ÑBÔBð 	UÀhØAÐAÐAÐAÐA¸5ÐAÑAÔAˆGØTÐT­:Ô+=×+JÒ+JÈ7Ñ+SÔ+SÐTÑTÔTˆGð	Uð 	Uð 	Uñ 	Uô 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uøøøð 	Uð 	Uð 	Uð 	Uõ �7‰|Œ|Ð)�s 5™zœzÐ)ˆ|˜zÒ)Ð)Ð)Ñ)Õ)Ô)Ð)Ð)Ð)Ð)ˆ|˜zÐ)Ñ)Ô)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)�sÑ)Ô)Ð)Õ)Ô)�sÑ)Ô)Ð)Ð)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)�7Ñ)Ô)Ð)Õ)Ô)�7Ñ)Ô)Ð)Ð)Õ)Ô)ˆ|Ñ)Ô)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô)�sÑ)Ô)Ð)Õ)Ô)�sÑ)Ô)Ð)Ð)Ð)Õ)Ô)Ñ)Ô)Ð)Ð)Õ)Ô) 5Ñ)Ô)Ð)Õ)Ô) 5Ñ)Ô)Ð)Ð)Õ)Ô)˜zÑ)Ô)Ð)Ð)Ñ)Ð)Ð)Ð)Ð)Ð)Ñ)Ð)Õ)Õ)Ô)Ð)Ñ)Ô)Ñ)Ô)Ð)Ð)Ð)Ð)Ð)Ð)Ð)Ý�7‰|Œ|Ðˆ|ÐÐÐÕÔÑÔÐÐÕÔ�sÑÔÐÕÔ�sÑÔÐÐÐÕÔÑÔÐÐÕÔ�7ÑÔÐÕÔ�7ÑÔÐÐÕÔˆ|ÑÔÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐs   Á?9CÃCÃCN©r   r.   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rk   ru   r”   rx   rl   r*   r-   r-   4   s^   € € € € € ØRÐRðGð Gð Gð Gð6Uð Uð Uð Uð*ð ð ð ð ð rl   r-   c                  ó�   — e Zd ZdZd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 )Ú)TestAdversarialFileCorruptionAndEdgeCaseszQStress-tests behavior under corrupted, zero-byte, truncated, and malicious files.Útmp_pathr   r   r.   c                ó  — |dz  }|                      ¦   «          t          j        t          f¦  «        5  t	          j        |¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z=Zero-byte file must raise UnidentifiedImageError or EOFError.zzero.pngN)ÚtouchÚpytestÚraisesÚ	Exceptionr   r!   r"   )r[   rœ   Ú	zero_filer&   s       r*   Útest_zero_byte_asset_rejectionzHTestAdversarialFileCorruptionAndEdgeCases.test_zero_byte_asset_rejection   s  € à˜zÑ)ˆ	Ø�ŠÑÔÐÝŒ]�I˜<Ñ(Ô(ð 	ð 	Ý”˜IÑ&Ô&ð ¨#Ø—’‘
”
�
ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s5   ´BÁ	A*ÁBÁ*A.	Á.BÁ1A.	Á2BÂBÂ	BÚlength)é   é   é   é   é   rY   c                óz  — t           dz  dz  }|                     ¦   «         }|d|› d�z  }|                     |d|…         ¦  «         t          j        t
          f¦  «        5  t          j        |¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z@Truncated byte streams must be detected and rejected gracefully.Ústy_01_hoang_mang_co_lor   Útrunc_z.pngN)	rR   Ú
read_bytesÚwrite_bytesrŸ   r    r¡   r   r!   r"   )r[   rœ   r¤   Úsample_pathÚraw_dataÚ
trunc_filer&   s          r*   Útest_truncated_stream_rejectionzITestAdversarialFileCorruptionAndEdgeCases.test_truncated_stream_rejection‡   s=  € õ "Ð$=Ñ=ÀÑKˆØ×)Ò)Ñ+Ô+ˆØÐ 5¨Ð 5Ð 5Ð 5Ñ5ˆ
Ø×Ò˜x¨¨¨Ô0Ñ1Ô1Ð1åŒ]�I˜<Ñ(Ô(ð 	ð 	Ý”˜JÑ'Ô'ð ¨3Ø—’‘
”
�
ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s6   Á"B0Á7BÂB0ÂB	ÂB0ÂB	Â B0Â0B4Â7B4c                óR  — t           dz  dz  }t          |                     ¦   «         ¦  «        }|                     d¦  «        }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}x}}t          d¦  «        D ]}
||dz   |
z            dz  ||dz   |
z   <   Œ|dz  }|                     |¦  «         t          j        t           f¦  «        5  t#          j        |¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z?Corrupted IDAT chunk payload must fail without unhandled crash.r«   r   s   IDATr¥   ©ú!=©z%(py0)s != -%(py3)sÚidat_posrC   úassert %(py6)sr9   Nr¨   r§   éÿ   zcorrupt_idat.png)rR   Ú	bytearrayr­   ÚfindrJ   rK   rL   rM   rN   rO   rP   rQ   rs   r®   rŸ   r    r¡   r   r!   r"   )r[   rœ   r¯   Údatar·   r\   r^   rh   Ú@py_format5r_   ÚiÚcorrupt_filer&   s                r*   Útest_corrupted_idat_zlib_streamzITestAdversarialFileCorruptionAndEdgeCases.test_corrupted_idat_zlib_stream“   sN  € å!Ð$=Ñ=ÀÑKˆÝ˜×/Ò/Ñ1Ô1Ñ2Ô2ˆØ—9’9˜WÑ%Ô%ˆØÐ˜A˜2Ðˆx˜2Š~ÐÐÐÕÔÐÐÐÐˆx˜2ÐÑÔÐÕÔÑÔÐÐÕÔˆxÑÔÐÕÔˆxÑÔÐÐÕÔ˜AÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐÐÐå�r‘”ð 	Eð 	EˆAØ&*¨8°a©<¸!Ñ+;Ô&<¸tÑ&CˆD�˜A‘ Ñ!Ñ"Ð"àÐ"4Ñ4ˆØ× Ò  Ñ&Ô&Ð&ÝŒ]�I˜<Ñ(Ô(ð 	ð 	Ý”˜LÑ)Ô)ð ¨SØ—’‘
”
�
ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s6   ÅFÅ#FÅ8FÆF	ÆFÆF	ÆFÆF Æ#F c                ó   — t           dz  dz  }t          |                     ¦   «         ¦  «        }|                     d¦  «        }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}x}}||dz   xx         dz  cc<   |dz  }
|
                     |¦  «         t          j        t          f¦  «        5  t!          j        |
¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )z<Tampered CRC32 checksum in PNG chunk is rejected or flagged.r«   r   ó   IHDRr¥   r´   r¶   Úihdr_posrC   r¸   r9   Né   r¹   zcorrupt_crc.png)rR   rº   r­   r»   rJ   rK   rL   rM   rN   rO   rP   rQ   r®   rŸ   r    r¡   r   r!   Úverify)r[   rœ   r¯   r¼   rÃ   r\   r^   rh   r½   r_   r¿   r&   s               r*   Útest_corrupted_crc32_checksumzGTestAdversarialFileCorruptionAndEdgeCases.test_corrupted_crc32_checksum£   s.  € å!Ð$=Ñ=ÀÑKˆÝ˜×/Ò/Ñ1Ô1Ñ2Ô2ˆØ—9’9˜WÑ%Ô%ˆØÐ˜A˜2Ðˆx˜2Š~ÐÐÐÕÔÐÐÐÐˆx˜2ÐÑÔÐÕÔÑÔÐÐÕÔˆxÑÔÐÕÔˆxÑÔÐÐÕÔ˜AÑÔÐÐÑÐÐÐÐÐÑÐÕÕÔÐÑÔÑÔÐÐÐÐÐÐÐàˆX˜‰]ÐÐÔ˜tÑ#ÐÐÑØÐ"3Ñ3ˆØ× Ò  Ñ&Ô&Ð&ÝŒ]�I˜<Ñ(Ô(ð 	ð 	Ý”˜LÑ)Ô)ð ¨SØ—
’
‘”�ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s6   Ä5FÅ
E+ÅFÅ+E/	Å/FÅ2E/	Å3FÆFÆ
Fc                óÆ  — t           dz  dz  t           dz  dz  dz  dz  t           dz  dz  t          d¦  «        g}|D �]"}|j        } |¦   «         }| }|s‹d	d
t          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nd
t          j        |¦  «        t          j        |¦  «        dœz  }t          t          j	        |¦  «        ¦  «        ‚dx}x}}t          j        t          t          f¦  «        5  t          j        |¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   �Œ$dS )z6Invalid paths and path traversal payloads fail safely.Ústy_non_existentr   z..r   z	ghost.pngr«   zmissing.pngz)C:/Windows/System32/drivers/etc/hosts.pngzFassert not %(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.is_file
}()
}r„   )r6   Úpy2Úpy4N)rR   r   Úis_filerL   rM   rJ   rN   rO   rP   rQ   rŸ   r    ÚFileNotFoundErrorÚOSErrorr   r!   r"   )r[   Útraversal_pathsr„   rh   Ú@py_assert3r]   rj   r&   s           r*   Ú$test_nonexistent_paths_and_traversalzNTestAdversarialFileCorruptionAndEdgeCases.test_nonexistent_paths_and_traversal±   sï  € õ Ð,Ñ,¨{Ñ:Ý˜$Ñ Ñ%¨Ñ0°;Ñ>ÝÐ3Ñ3°mÑCÝÐ<Ñ=Ô=ð	
ˆð !ð 	ñ 	ˆAØ”yÐ"�y�y‘{”{Ð"�{�?Ð"�?Ð"Ð"Ð"Õ"Ô"Ñ"Ô"Ð"Ð"Õ"Ô"�qÑ"Ô"Ð"Õ"Ô"�qÑ"Ô"Ð"Ð"Õ"Ô"�yÑ"Ô"Õ"Ô"�{Ñ"Ô"Ð"Ð"Ñ"Ð"Õ"Õ"Ô"Ð"Ñ"Ô"Ñ"Ô"Ð"Ð"Ð"Ð"Ð"Ð"Ð"Ý”Õ 1µ7Ð;Ñ<Ô<ð ð Ý”Z ‘]”]ð  cØ—H’H‘J”J�Jðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ùð	ð 	s6   ÄEÄD=Ä1EÄ=EÅEÅEÅEÅE	ÅE	c                ó`  — dddddœ}|                      ¦   «         D ]‘\  }}||z  }|                     |¦  «         t          j        t          f¦  «        5  t          j        |¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   Œ’dS )zENon-PNG text, HTML, and JSON payloads disguised as .png are rejected.s'   <html><body>404 Not Found</body></html>s&   {"error": "Unauthorized", "code": 401}s   GIF89a  €  s    ÿª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 ÿª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 ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU ÿªU)zhtml.pngzjson.pngzfake_gif.pngzbinary_junk.pngN)Úitemsr®   rŸ   r    r¡   r   r!   r"   )r[   rœ   ÚpayloadsÚnameÚcontentrz   r&   s          r*   Útest_disguised_non_png_fileszFTestAdversarialFileCorruptionAndEdgeCases.test_disguised_non_png_files¿   s6  € ð CØAØAØ8ð	&
ð &
ˆð &Ÿ^š^Ñ-Ô-ð 	ð 	‰MˆD�'Ø˜4‘ˆAØ�MŠM˜'Ñ"Ô"Ð"Ý”¥	˜|Ñ,Ô,ð ð Ý”Z ‘]”]ð  cØ—H’H‘J”J�Jðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð øð	ð 	s6   ÁB"Á*BÁ?B"ÂBÂB"ÂBÂB"Â"B&	Â)B&	c                ó´  — t          j        ¦   «         }t          j        ddd¦  «                             |d¬¦  «         t          |                     ¦   «         ¦  «        }|                     d¦  «        }t          j	        d||dz   d	d	¦  «         |||d
z   …         }t          j        |¦  «        }t          j	        d||d
z   |¦  «         |dz  }|                     |¦  «         t          j        t          f¦  «        5  t          j        |¦  «        5 }|                     ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )zECrafted huge dimension header is trapped safely by PIL safety limits.ÚRGB)r¥   r¥   )r   r   r   ÚPNG)ÚformatrÂ   z>IIr¦   iÿÿ  rÄ   z>Izbomb.pngN)ÚioÚBytesIOr   ÚnewÚsaverº   Úgetvaluer»   ÚstructÚ	pack_intoÚzlibÚcrc32r®   rŸ   r    r¡   r!   r"   )	r[   rœ   Úbior¼   rÃ   Ú
chunk_dataÚnew_crcÚ	bomb_pathr&   s	            r*   Ú,test_decompression_dimension_overflow_safetyzVTestAdversarialFileCorruptionAndEdgeCases.test_decompression_dimension_overflow_safetyÎ   s¹  € õ Œj‰lŒlˆÝŒ	�%˜ Ñ+Ô+×0Ò0°¸UÐ0ÑCÔCÐCÝ˜Ÿš™œÑ(Ô(ˆØ—9’9˜WÑ%Ô%ˆÝÔ˜  h°¡l°E¸5ÑAÔAÐAà˜( X°¡]Ð2Ô3ˆ
Ý”*˜ZÑ(Ô(ˆÝÔ˜˜t X°¡]°GÑ<Ô<Ð<à˜zÑ)ˆ	Ø×Ò˜dÑ#Ô#Ð#åŒ]�I˜<Ñ(Ô(ð 	ð 	Ý”˜IÑ&Ô&ð ¨#Ø—’‘
”
�
ðð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s6   Ã?EÄD5Ä)EÄ5D9	Ä9EÄ<D9	Ä=EÅEÅEN)rœ   r   r   r.   )rœ   r   r¤   rY   r   r.   r•   )r–   r—   r˜   r™   r£   rŸ   ÚmarkÚparametrizer²   rÀ   rÆ   rÐ   rÖ   rè   rx   rl   r*   r›   r›   |   sÌ   € € € € € Ø[Ð[ðð ð ð ð „[×Ò˜XÐ'8Ð'8Ð'8Ñ9Ô9ð	ð 	ð 	ñ :Ô9ð	ðð ð ð ð ð ð ð ðð ð ð ðð ð ð ðð ð ð ð ð rl   r›   c                  ó*   — e Zd ZdZdd„Zdd„Zdd„ZdS )	Ú!TestMemoryConsumptionVerificationzKVerifies RAM and disk budgets: active biome < 500 KB, all 30 styles < 8 MB.r   r.   c                óN  — t          ¦   «         }d}|D �]µ}t          |                     ¦   «         z  }d}t          D ]F}t	          j        ||z  ¦  «        5 }||j        |j        z  dz  z  }ddd¦  «         n# 1 swxY w Y   ŒG|dz                       d¦  «        D ]C}t	          j        |¦  «        5 }||j        |j        z  dz  z  }ddd¦  «         n# 1 swxY w Y   ŒD||k    r|}d}	d}
|	|
z  }||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|dz  d›d�¦  «        dz   d|iz  }t!          t          j        |¦  «        ¦  «        ‚dx}x}	x}
}�Œ·d}	d}
|	|
z  }||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|› �¦  «        dz   d|iz  }t!          t          j        |¦  «        ¦  «        ‚dx}x}	x}
}dS )z=Every active biome raw RGBA buffer must be strictly < 500 KB.r   r¦   Nr<   r=   iô  i   r?   )z%(py0)s < (%(py3)s * %(py5)s)Ú	biome_ram)r6   r8   rF   z memory rD   z KB exceeds 500 KB limitz
>assert %(py8)sr;   i   r1   )z%(py0)s == (%(py3)s * %(py5)s)Úmax_biome_ramzUnexpected footprint: )r
   rR   rS   r   r   r!   r#   r$   rU   rJ   rK   rL   rM   rN   rO   rZ   rP   rQ   )r[   r   rï   ra   rb   rî   rc   r&   rf   r\   r^   Ú@py_assert6rh   r_   r`   s                  r*   Ú4test_active_biome_uncompressed_footprint_under_500kbzVTestMemoryConsumptionVerification.test_active_biome_uncompressed_footprint_under_500kbæ   s*  € å&Ñ(Ô(ˆØˆàð 	ñ 	ˆDÝ $§*¢*¡,¤,Ñ.ˆEØˆIå)ð <ð <�Ý”Z ¨¡Ñ.Ô.ð <°#Ø ¤¨S¬ZÑ!7¸!Ñ!;Ñ;�Ið<ð <ð <ñ <ô <ð <ð <ð <ð <ð <ð <øøøð <ð <ð <ð <øð ! 7™?×0Ò0°Ñ9Ô9ð <ð <�Ý”Z Ñ'Ô'ð <¨3Ø ¤¨S¬ZÑ!7¸!Ñ!;Ñ;�Ið<ð <ð <ñ <ô <ð <ð <ð <ð <ð <ð <øøøð <ð <ð <ð <øð ˜=Ò(Ð(Ø )�ð  #ð  Tð ˜s T™zð �9˜zÒ)ð ð ð õ ìðð ð ð �9˜zð ñ ô ð õ äñô ð ð õ ìð ñ ô ð õ äð ñ ô ð ð õ äð  #ñ ô õ äð &*ñ ô ð ð ñ ð õ ìð ÐOÐO ¨TÑ!1ÐOÐOÐOÐOñô ð ñ ð ð ð ñ ð õ õ ìðñ ô ñ ô ð ð ð ð ð ð ð ð ð ñ ð
 !$ÐT dÐT  d¡
ÐTˆ} 
Ò*ÐTÐTÐTÕTÔTÐTÐTÐTÐTˆ} 
ÐTÑTÔTÐTÕTÔTÑTÔTÐTÐTÕTÔTˆ}ÑTÔTÐTÕTÔTˆ}ÑTÔTÐTÐTÕTÔT ÑTÔTÕTÔT dÑTÔTÐTÐTÑTÐTÕTÔTÐ,TÀ]Ð,TÐ,TÑTÔTÐTÑTÐTÐTÐTÑTÐTÕTÕTÔTÐTÑTÔTÑTÔTÐTÐTÐTÐTÐTÐTÐTÐTÐTÐTÐTs$   ÁA6Á6A:Á=A:Â0CÃCÃCc                óT  — d}t          ¦   «         D ]R}t          |                     ¦   «         z  }|                     d¦  «        D ]}||                     ¦   «         j        z  }ŒŒS|dz  }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z   d|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}}dS )zHTotal disk size across all 30 style directories must be strictly < 8 MB.r   r=   é   ç       @r?   rA   Útotal_disk_mbrC   zTotal disk size rD   z MB unexpectedly highrE   rF   N)r
   rR   rS   ÚrglobÚstatÚst_sizerJ   rK   rL   rM   rN   rO   rZ   rP   rQ   )
r[   Útotal_disk_bytesra   rb   rz   rõ   r\   rh   ri   rj   s
             r*   Ú0test_all_30_styles_aggregate_disk_size_under_8mbzRTestMemoryConsumptionVerification.test_all_30_styles_aggregate_disk_size_under_8mb  s\  € àÐÝ)Ñ+Ô+ð 	5ð 	5ˆDÝ $§*¢*¡,¤,Ñ.ˆEØ—[’[ Ñ)Ô)ð 5ð 5�Ø  A§F¢F¡H¤HÔ$4Ñ4Ð Ð ð5ð )¨KÑ8ˆà"Ð_ˆ}˜sÒ"Ð_Ð_Ð_Õ_Ô_Ð_Ð_Ð_Ð_ˆ}˜sÐ_Ñ_Ô_Ð_Õ_Ô_Ñ_Ô_Ð_Ð_Õ_Ô_ˆ}Ñ_Ô_Ð_Õ_Ô_ˆ}Ñ_Ô_Ð_Ð_Õ_Ô_˜sÑ_Ô_Ð_Ð_Ñ_Ð_Õ_Ô_Ð$_°}Ð$_Ð$_Ð$_Ð$_Ñ_Ô_Ð_Ñ_Ð_Ð_Ð_Ñ_Ð_Õ_Õ_Ô_Ð_Ñ_Ô_Ñ_Ô_Ð_Ð_Ð_Ð_Ð_Ð_Ð_rl   c                ó  — d}d}t          ¦   «         D ]g}t          |                     ¦   «         z  }|D ]F}t          j        ||z  ¦  «        5 }||j        |j        z  dz  z  }ddd¦  «         n# 1 swxY w Y   ŒGŒh|dz  }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z   d|
iz  }t          t          j        |¦  «        ¦  «        ‚dx}	}d}||z
  }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        |¦  «        t          j        |¦  «        dœz  }t          j        d|d›d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}x}}dS )zCIn-memory core albedo textures across all 30 styles must be < 8 MB.)r   r   r   r   r   r   r¦   Nró   rô   r?   rA   Útotal_albedo_mbrC   zAlbedo buffer rD   z MB exceeds 8.0 MB budgetrE   rF   g\�Âõ(\@gš™™™™™¹?)z;%(py6)s
{%(py6)s = %(py0)s((%(py1)s - %(py3)s))
} < %(py9)sÚabs)r6   r7   r8   r9   Úpy9zExpected ~6.09 MB, got z MBz
>assert %(py11)sÚpy11)r
   rR   rS   r   r!   r#   r$   rJ   rK   rL   rM   rN   rO   rZ   rP   rQ   rý   )r[   Úalbedo_namesÚtotal_albedo_ramra   rb   rc   r&   rü   r\   rh   ri   rj   r^   r]   Ú@py_assert8r’   Ú@py_format10Ú@py_format12s                     r*   Ú*test_all_30_styles_albedo_buffer_under_8mbzLTestMemoryConsumptionVerification.test_all_30_styles_albedo_buffer_under_8mb  sµ  € àWˆØÐå)Ñ+Ô+ð 	Cð 	CˆDÝ $§*¢*¡,¤,Ñ.ˆEØ%ð Cð C�Ý”Z ¨¡Ñ.Ô.ð C°#Ø$¨¬	°C´JÑ(>ÀÑ(BÑBÐ$ðCð Cð Cñ Cô Cð Cð Cð Cð Cð Cð Cøøøð Cð Cð Cð CøðCð +¨kÑ:ˆØ!$ð 	
ˆ Ò$ð 	
ð 	
ð 	
õ 	
ìð	
ð 	
ð 	
ð 	
ˆ ð 	
ñ 	
ô 	
ð 	
õ 	
ä	ñ	
ô 	
ð 	
ð 	
õ 	
ìð ñ 	
ô 	
ð 	
õ 	
ä 	ð ñ 	
ô 	
ð 	
ð 	
õ 	
ä 	ð "%ñ 	
ô 	
ð 	
ð 	
ñ 	
ð 	
õ 	
ìð L˜_ÐKÐKÐKÐKñ	
ô 	
ð 	
ñ 	
ð 	
ð 	
ð 	
ñ 	
ð 	
õ 	
õ 	
ìð	
ñ 	
ô 	
ñ 	
ô 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð &*Ðd�? TÑ)Ðd�sÐ)Ñ*Ô*Ðd¨SÐdÐ*¨SÒ0ÐdÐdÑdÕdÔdÐdÐdÐdÐdÐ*¨SÐdÑdÔdÐdÕdÔdÑdÔdÐdÐdÕdÔd�sÑdÔdÐdÕdÔd�sÑ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ÑdÔdÕdÔdÐ*ÑdÔdÕdÔd¨SÑdÔdÐdÐdÑdÐdÕdÔdÐ2dÈOÐ2dÐ2dÐ2dÐ2dÑ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Ðds   ÁA.Á.A2Á5A2Nr•   )r–   r—   r˜   r™   rñ   rú   r  rx   rl   r*   rì   rì   ã   sd   € € € € € ØUÐUðUð Uð Uð Uð8
`ð 
`ð 
`ð 
`ðeð eð eð eð eð erl   rì   c                  ó*   — e Zd ZdZdd„Zdd„Zdd„ZdS )	Ú)TestTexturePixelIntegrityAndNormalVectorszMVerifies pixel validity, alpha masks, normal vector distributions, and props.r   r.   c           
     óð  — t          ¦   «         }|D �]ã}t          |                     ¦   «         z  }dD �]À}t          j        ||z  ¦  «        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  }	dd|	iz  }
t          t          j        |
¦  «        ¦  «        ‚d	x}x}}|                     ¦   «         d
         }|                     ¦   «         }|d         }d}||k    }|s‡t          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        |› d|› d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d	x}x}}d	d	d	¦  «         n# 1 swxY w Y   �ŒÂ�Œåd	S )zLFloor, wall, path, liquid tiles must contain non-transparent colored pixels.)r   r   r   r   ÚRGBAr1   ©z,%(py2)s
{%(py2)s = %(py0)s.mode
} == %(py5)sr&   ©r6   rÉ   rF   úassert %(py7)sÚpy7Nrn   r¥   r¹   )z%(py1)s == %(py4)s©r7   rÊ   ú/z has no opaque pixelsú
>assert %(py6)sr9   ©r
   rR   rS   r   r!   ÚmoderJ   rK   rL   rM   rN   rO   rP   rQ   ÚsplitÚ
getextremarZ   )r[   r   ra   rb   rc   r&   rh   r^   rÏ   rj   Ú@py_format8Ú
alpha_chanÚextremaÚ@py_assert0r\   r½   r_   s                    r*   Ú+test_albedo_tiles_not_empty_and_valid_alphazUTestTexturePixelIntegrityAndNormalVectors.test_albedo_tiles_not_empty_and_valid_alpha#  s�  € å&Ñ(Ô(ˆØð 	Uñ 	UˆDÝ $§*¢*¡,¤,Ñ.ˆEØLð Uñ U�Ý”Z ¨¡Ñ.Ô.ð U°#Øœ8Ð- vÐ-˜8 vÒ-Ð-Ð-Ð-Õ-Ô-Ð-Ð-Ð-Ð-˜8 vÐ-Ñ-Ô-Ð-Õ-Ô-Ñ-Ô-Ð-Ð-Õ-Ô-˜3Ñ-Ô-Ð-Õ-Ô-˜3Ñ-Ô-Ð-Ð-Õ-Ô-˜8Ñ-Ô-Õ-Ô- vÑ-Ô-Ð-Ð-Ñ-Ð-Ð-Ð-Ð-Ð-Ñ-Ð-Õ-Õ-Ô-Ð-Ñ-Ô-Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ø!$§¢¡¤¨Q¤�JØ(×3Ò3Ñ5Ô5�Gà" 1œ:ÐT¨ÐT˜:¨Ò,ÐTÐTÐTÕTÔTÐTÐTÐTÐT˜:¨ÐTÑTÔTÕTÔT˜:ÑTÔTÕTÔT¨ÑTÔTÐTÐTÑTÐTÕTÔT°Ð.TÐ.T¸Ð.TÐ.TÐ.TÑTÔTÐTÑTÐTÐTÐTÑTÐTÕTÕTÔTÐTÑTÔTÑTÔTÐTÐTÐTÐTÐTÐTÐTðUð Uð Uñ Uô Uð Uð Uð Uð Uð Uð Uøøøð Uð Uð Uð UùñUð	Uð 	Us   ÁFG'Ç'G+Ç.G+c                ó  — t          ¦   «         }d}|D �]ë}t          |                     ¦   «         z  }|D �]È}t          j        ||z  ¦  «        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  }
dd|
iz  }t          t          j        |¦  «        ¦  «        ‚d	x}x}	}|                     ¦   «         \  }}}}|                     ¦   «         }|d
         }d}	||	k    }|s�t          j        d|fd||	f¦  «        t          j        |¦  «        t          j        |	¦  «        dœz  }t          j        |› d|› d|d
         › d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚d	x}x}}	d	d	d	¦  «         n# 1 swxY w Y   �ŒÊ�Œíd	S )zGTangent normal maps must have valid Z orientation across all 30 styles.)r   r   r   r   r	  r1   r
  r&   r  r  r  Nr¥   é€   )ú>=)z%(py1)s >= %(py4)sr  r  z
 max blue z < 128r  r9   r  )r[   r   Únormal_namesra   rb   rc   r&   rh   r^   rÏ   rj   r  ÚrÚgÚbÚaÚ	b_extremar  r\   r½   r_   s                        r*   Ú%test_normal_map_z_vector_distributionzOTestTexturePixelIntegrityAndNormalVectors.test_normal_map_z_vector_distribution0  s¦  € å&Ñ(Ô(ˆð
ˆð ð 	`ñ 	`ˆDÝ $§*¢*¡,¤,Ñ.ˆEØ%ð `ñ `�Ý”Z ¨¡Ñ.Ô.ð `°#Øœ8Ð- vÐ-˜8 vÒ-Ð-Ð-Ð-Õ-Ô-Ð-Ð-Ð-Ð-˜8 vÐ-Ñ-Ô-Ð-Õ-Ô-Ñ-Ô-Ð-Ð-Õ-Ô-˜3Ñ-Ô-Ð-Õ-Ô-˜3Ñ-Ô-Ð-Ð-Õ-Ô-˜8Ñ-Ô-Õ-Ô- vÑ-Ô-Ð-Ð-Ñ-Ð-Ð-Ð-Ð-Ð-Ñ-Ð-Õ-Õ-Ô-Ð-Ñ-Ô-Ñ-Ô-Ð-Ð-Ð-Ð-Ð-Ð-Ð-Ø!$§¢¡¤‘J�A�q˜!˜QØ !§¢¡¤�Ià$ Qœ<Ð_¨3Ð_˜<¨3Ò.Ð_Ð_Ð_Õ_Ô_Ð_Ð_Ð_Ð_˜<¨3Ð_Ñ_Ô_Õ_Ô_˜<Ñ_Ô_Õ_Ô_¨3Ñ_Ô_Ð_Ð_Ñ_Ð_Õ_Ô_°4Ð0_Ð0_¸%Ð0_Ð0_È9ÐUVÌ<Ð0_Ð0_Ð0_Ñ_Ô_Ð_Ñ_Ð_Ð_Ð_Ñ_Ð_Õ_Õ_Ô_Ð_Ñ_Ô_Ñ_Ô_Ð_Ð_Ð_Ð_Ð_Ð_Ð_ð`ð `ð `ñ `ô `ð `ð `ð `ð `ð `ð `øøøð `ð `ð `ð `ùñ`ð	`ð 	`s   ÁFG1Ç1G5Ç8G5c           
     ó0  — t          ¦   «         D �]}t          |                     ¦   «         z  dz  }t          j        |¦  «        5 }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  }dd|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}x}x}x}x}	x}}
t#          d¦  «        D ]ï}|                     |dz  d|dz   dz  df¦  «        }|                     ¦   «         d                              ¦   «         }|d         }d}||k    }|s‡t          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        |› d|› d�¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}}Œð	 ddd¦  «         n# 1 swxY w Y   �ŒdS )zMProps composite sheet (192x64) segments cleanly into 3 non-empty 64x64 cells.r   éÀ   é@   r1   )z-%(py4)s
{%(py4)s = %(py2)s.width
} == %(py7)sÚsheet)rÉ   rÊ   r  z%(py9)srþ   )z2%(py13)s
{%(py13)s = %(py11)s.height
} == %(py16)s)rÿ   Úpy13Úpy16z%(py18)sÚpy18r   zassert %(py21)sÚpy21Nrn   r¥   )ú>)z%(py1)s > %(py4)sr  z/props.png cell z	 is emptyr  r9   )r
   rR   rS   r   r!   r#   r$   rJ   rK   rL   rM   rN   rO   rT   Ú_format_booloprP   rQ   rs   Úcropr  r  rZ   )r[   ra   Ú
sheet_pathr'  rh   rÏ   rð   r]   r  Ú@py_assert12Ú@py_assert15Ú@py_assert14r  r  Ú@py_format17Ú@py_format19Ú@py_format20Ú@py_format22r¾   ÚcellÚalpha_extremar\   r½   r_   s                           r*   Útest_props_sheet_segmentationzGTestTexturePixelIntegrityAndNormalVectors.test_props_sheet_segmentationC  sõ  € å)Ñ+Ô+ð 	Wñ 	WˆDÝ$ t§z¢z¡|¤|Ñ3°kÑAˆJÝ”˜JÑ'Ô'ð W¨5Ø@Ð@�u”{Ð@ cÐ@�{ cÒ)Ð@Ð@Ð@Ð@Ð@¨e¬lÐ@¸bÐ@¨l¸bÒ.@Ð@Ð@Ð@Ð@Ñ@Õ@Ô@Ð@Ð@Ð@Ð@�{ cÐ@Ñ@Ô@Ð@Õ@Ô@Ñ@Ô@Ð@Ð@Õ@Ô@�uÑ@Ô@Ð@Õ@Ô@�uÑ@Ô@Ð@Ð@Õ@Ô@�{Ñ@Ô@Õ@Ô@ cÑ@Ô@Ð@Ð@Ñ@Ð@Ð@Ð@Ð@Ð@Ñ@Ð@Ð@×@Ò@Ð@Ñ@Ô@Ð@Ð@Ð@Õ@Ô@Ð@Ð@Ð@Ð@¨l¸bÐ@Ñ@Ô@Ð@Õ@Ô@Ñ@Ô@Ð@Ð@Õ@Ô@¨eÑ@Ô@Ð@Õ@Ô@¨eÑ@Ô@Ð@Ð@Õ@Ô@¨lÑ@Ô@Õ@Ô@¸bÑ@Ô@Ð@Ð@Ñ@Ð@Ð@Ð@Ð@Ð@Ñ@Ð@Ð@×@Ò@Ð@Ñ@Ô@Ð@Õ@Ô@Ð@Ð@Ñ@Ô@Ð@Ñ@Ð@Ð@Ð@Ð@Ð@Ñ@Ð@Õ@Õ@Ô@Ð@Ñ@Ô@Ñ@Ô@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ð@Ý˜q™œð Wð W�AØ Ÿ:š: q¨2¡v¨q°1°q±5¸B±,ÀÐ&CÑDÔD�DØ$(§J¢J¡L¤L°¤O×$>Ò$>Ñ$@Ô$@�MØ(¨Ô+ÐV¨aÐVÐ+¨aÒ/ÐVÐVÐVÕVÔVÐVÐVÐVÐVÐ+¨aÐVÑVÔVÕVÔVÐ+ÑVÔVÕVÔV¨aÑVÔVÐVÐVÑVÐVÕVÔV°DÐ1VÐ1VÈ!Ð1VÐ1VÐ1VÑVÔVÐVÑVÐVÐVÐVÑVÐVÕVÕVÔVÐVÑVÔVÑVÔVÐVÐVÐVÐVÐVÐVÐVÐVðWðWð Wð Wñ Wô Wð Wð Wð Wð Wð Wð Wøøøð Wð Wð Wð Wùð	Wð 	Ws   ÁJ7L	Ì	L	ÌL	Nr•   )r–   r—   r˜   r™   r  r#  r9  rx   rl   r*   r  r     sd   € € € € € ØWÐWðUð Uð Uð Uð`ð `ð `ð `ð&	Wð 	Wð 	Wð 	Wð 	Wð 	Wrl   r  )r   r   r   r   )(r™   Ú
__future__r   ÚbuiltinsrL   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterJ   Úconcurrent.futuresrŽ   rÛ   rà   r   râ   Úpathlibr   Útypingr   r   r   rŸ   ÚPILr   r	   Úserver.world.map_style_catalogr
   ÚLOAD_TRUNCATED_IMAGESÚ__file__ÚresolveÚparentÚPROJECT_ROOTrR   r   Ú__annotations__r+   r-   r›   rì   r  rx   rl   r*   ú<module>rJ     s  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € Ð Ð Ð Ð Ø 	€	€	€	Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø $Ð $Ð $Ð $Ð $Ð $Ð $Ð $Ð $Ð $à €€€Ø  Ð  Ð  Ð  Ð  Ð  Ð  Ð  à @Ð @Ð @Ð @Ð @Ð @ð #(€	Ô àˆt�H‰~Œ~×%Ò%Ñ'Ô'Ô.Ô5Ô<€Ø˜XÑ%¨Ñ0°8Ñ;¸eÑCÀhÑN€ð
%Ð ð 
ð 
ð 
ñ 
ðð ð ð ðEð Eð Eð Eð Eñ Eô Eð EðPdð dð dð dð dñ dô dð dðN:eð :eð :eð :eð :eñ :eô :eð :eðz,Wð ,Wð ,Wð ,Wð ,Wñ ,Wô ,Wð ,Wð ,Wð ,Wrl   