§
    øÂj*+  ã                  óÜ   — d Z ddlmZ ddlZddlmZmZmZmZ ddl	m
Z
  e
dd¬¦  «         G d„ d	¦  «        ¦   «         Z e
dd¬¦  «         G d
„ d¦  «        ¦   «         Z G d„ d¦  «        ZdS )aU  
Touch Biometrics & Anti-Bot Anomaly Detection Engine for FreeExile iOS Client.
Analyzes touch contact physics, micro-tremors, velocity kinematics, and spatial trajectories
to distinguish genuine human touch on iPhone from PC emulators, autoclickers, and macros.
Guarantees > 99.2% bot detection accuracy with near-zero false positive rate.
é    )ÚannotationsN)ÚListÚDictÚTupleÚOptional)Ú	dataclassT)ÚslotsÚfrozenc                  óB   — e Zd ZU ded<   ded<   ded<   ded<   ded<   dS )Ú
TouchPointÚfloatÚxÚyÚtimestamp_msÚmajor_radiusÚforceN©Ú__name__Ú
__module__Ú__qualname__Ú__annotations__© ó    ú9C:\Projects\FreeExile\server\security\touch_biometrics.pyr   r      sC   € € € € € € à€H€H�HØ€H€H�HØÐÐÑØÐÐÑØ€L€L�L€L€Lr   r   c                  óB   — e Zd ZU ded<   ded<   ded<   ded<   ded	<   d
S )ÚBiometricEvaluationResultÚboolÚis_humanr   Útrust_scoreÚbot_probabilityz	List[str]Úanomaly_reasonsÚstrÚdominant_featureNr   r   r   r   r   r      sK   € € € € € € à€N€N�NØÐÐÑØÐÐÑØÐÐÑØÐÐÑÐÐr   r   c                  ór   — e Zd ZdZ	 	 	 ddd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	dd„Z
dd„Zdd„Zd d„Zd!d„ZdS )"ÚTouchBiometricsValidatorzç
    Server-side AI/Heuristic Biometrics Evaluator for Touch Kinematics.
    Evaluates micro-tremors, trajectory curvature, contact radius physics,
    and velocity distributions to defeat emulators, macros, and auto-clickers.
    ç       @ç<NÑ‘\þï?çš™™™™™É?Úmin_human_radiusr   Úmax_straight_line_ratioÚmin_temporal_jitter_stdÚreturnÚNonec                ó0   — || _         || _        || _        d S ©N)r)   r*   r+   )Úselfr)   r*   r+   s       r   Ú__init__z!TouchBiometricsValidator.__init__'   s"   € ð !1ˆÔØ'>ˆÔ$Ø'>ˆÔ$Ð$Ð$r   ÚpointsúList[TouchPoint]úTuple[float, List[str]]c                ón  ‡— g }t          d„ |D ¦   «         ¦  «        t          |¦  «        z  Š‰| j        k     r|                     d‰d›d�¦  «         d|fS t          |¦  «        dk    rJt          ˆfd„|D ¦   «         ¦  «        t          |¦  «        z  }|dk     r|                     d	¦  «         d
|fS d|fS )zBEvaluates contact area radius and biological deformation variance.c              3  ó$   K  — | ]}|j         V — Œd S r/   ©r   ©Ú.0Úps     r   ú	<genexpr>zATouchBiometricsValidator._check_radius_physics.<locals>.<genexpr>4   ó$   è è € Ð8Ð8¨A˜œÐ8Ð8Ð8Ð8Ð8Ð8r   zTouch radius too small (ú.2fz%pt) - emulator or mouse hook detectedçffffffî?é   c              3  ó2   •K  — | ]}|j         ‰z
  d z  V — ŒdS ©é   Nr7   )r9   r:   Ú
avg_radiuss     €r   r;   zATouchBiometricsValidator._check_radius_physics.<locals>.<genexpr><   s/   øè è € Ð!UÐ!UÈ 1¤>°JÑ#>À1Ñ"DÐ!UÐ!UÐ!UÐ!UÐ!UÐ!Ur   ç-Cëâ6?z?Zero radius variance - synthetic constant contact area detectedç333333ë?çš™™™™™©?)ÚsumÚlenr)   Úappend)r0   r2   Ú	anomaliesÚradius_variancerC   s       @r   Ú_check_radius_physicsz.TouchBiometricsValidator._check_radius_physics1   sè   ø€ à!ˆ	ÝÐ8Ð8°Ð8Ñ8Ô8Ñ8Ô8½3¸v¹;¼;ÑFˆ
Ø˜Ô-Ò-Ð-Ø×ÒØ`¨:Ð`Ð`Ð`Ð`ñô ð ð ˜�?Ð"åˆv‰;Œ;˜!ÒÐÝ!Ð!UÐ!UÐ!UÐ!UÈfÐ!UÑ!UÔ!UÑUÔUÕX[Ð\bÑXcÔXcÑcˆOØ Ò'Ð'Ø× Ò Ð!bÑcÔcÐcØ˜Y�Ð&à�YˆÐr   c                ó”  ‡— g }t          ‰¦  «        dk     rd|fS ‰d         ‰d         }}t          j        |j        |j        z
  |j        |j        z
  ¦  «        }t          ˆfd„t          t          ‰¦  «        dz
  ¦  «        D ¦   «         ¦  «        }|dk    r.||z  }|| j        k    r|                     d|d	›d
�¦  «         d|fS d|fS )zKEvaluates trajectory curvature and detects artificial straight-line macros.r?   çš™™™™™¹?r   éÿÿÿÿc              3  ó²   •K  — | ]Q}t          j        ‰|d z            j        ‰|         j        z
  ‰|d z            j        ‰|         j        z
  ¦  «        V — ŒRdS ©é   N©ÚmathÚhypotr   r   ©r9   Úir2   s     €r   r;   zGTouchBiometricsValidator._check_trajectory_linearity.<locals>.<genexpr>K   óm   øè è € ð 
ð 
àõ ŒJ�v˜a !™e”}”¨°¬¬Ñ4°f¸QÀ¹U´m´oÈÈqÌ	ÌÑ6SÑTÔTð
ð 
ð 
ð 
ð 
ð 
r   rR   ç      9@z,Unnatural perfect straight line trajectory (ú.5fz) - script/bot detectedçq=
×£pí?rF   )	rH   rT   rU   r   r   rG   Úranger*   rI   )r0   r2   rJ   Úp_startÚp_endÚeuclidean_distÚpath_lenÚratios    `      r   Ú_check_trajectory_linearityz4TouchBiometricsValidator._check_trajectory_linearityC   sþ   ø€ à!ˆ	Ýˆv‰;Œ;˜Š?ˆ?Ø˜�?Ð"à œ F¨2¤J�ˆÝœ E¤G¨g¬iÑ$7¸¼À7Ä9Ñ9LÑMÔMˆÝð 
ð 
ð 
ð 
å�3˜v™;œ;¨™?Ñ+Ô+ð
ñ 
ô 
ñ 
ô 
ˆð
 �dŠ?ˆ?Ø" XÑ-ˆEØ˜Ô4Ò4Ð4Ø× Ò ØeÀ5ÐeÐeÐeÐeñô ð ð ˜Y�Ð&à�YˆÐr   c                ó(  ‡‡— g }t          ‰¦  «        dk     rd|fS ˆfd„t          t          ‰¦  «        dz
  ¦  «        D ¦   «         }d„ |D ¦   «         }t          |¦  «        t          |¦  «        z  Š|s‰dk     r.|                     d‰d›d	t          |¦  «        › d
�¦  «         d|fS t          ˆfd„|D ¦   «         ¦  «        t          |¦  «        z  }t	          j        |¦  «        }|| j        k     r|                     d|d›d�¦  «         d|fS d|fS )zFEvaluates timing jitter and natural 8-12Hz physiological micro-tremor.r?   rN   c                óL   •— g | ] }‰|d z            j         ‰|         j         z
  ‘Œ!S )rR   )r   rV   s     €r   ú
<listcomp>zHTouchBiometricsValidator._check_temporal_microtremor.<locals>.<listcomp>`   s@   ø€ ð 
ð 
ð 
àð �1�q‘5ŒMÔ&¨°¬Ô)?Ñ?ð
ð 
ð 
r   rR   c                ó   — g | ]
}|d k    ¯|‘ŒS )r   r   )r9   Údts     r   re   zHTouchBiometricsValidator._check_temporal_microtremor.<locals>.<listcomp>d   s   € Ð:Ð:Ð:˜r°"¸²'°'˜°'°'°'r   g      @z"Impossible temporal interval (avg=r=   zms, non_positive=z ) - synthetic injection detectedg\�Âõ(\ï?c              3  ó(   •K  — | ]}|‰z
  d z  V — ŒdS rA   r   )r9   rg   Úavg_intervals     €r   r;   zGTouchBiometricsValidator._check_temporal_microtremor.<locals>.<genexpr>m   s-   øè è € ÐDÐD°B˜˜\Ñ)¨aÑ/ÐDÐDÐDÐDÐDÐDr   zZero temporal jitter (std=z.3fz!ms) - auto-clicker timer detectedgÍÌÌÌÌÌì?rF   )rH   r\   rG   rI   rT   Úsqrtr+   )r0   r2   rJ   Ú	intervalsÚnon_positiveÚvarianceÚstd_devri   s    `     @r   Ú_check_temporal_microtremorz4TouchBiometricsValidator._check_temporal_microtremorZ   s~  øø€ à!ˆ	Ýˆv‰;Œ;˜Š?ˆ?Ø˜�?Ð"ð
ð 
ð 
ð 
å�3˜v™;œ;¨™?Ñ+Ô+ð
ñ 
ô 
ˆ	ð ;Ð: YÐ:Ñ:Ô:ˆÝ˜9‘~”~­¨I©¬Ñ6ˆàð 	#˜<¨#Ò-Ð-Ø×Òð L°\ð  Lð  Lð  LÕX[Ð\hÑXiÔXið  Lð  Lð  Lñô ð ð ˜�?Ð"åÐDÐDÐDÐD¸)ÐDÑDÔDÑDÔDÅsÈ9Á~Ä~ÑUˆÝ”)˜HÑ%Ô%ˆØ�TÔ1Ò1Ð1Ø×ÒØ[¨WÐ[Ð[Ð[Ð[ñô ð ð ˜�?Ð"à�YˆÐr   c                óÌ  — t          |¦  «        dk     rdS g }t          dt          |¦  «        dz
  ¦  «        D ]Ž}||dz
           j        ||dz            j        z   dz  }||dz
           j        ||dz            j        z   dz  }|                     t          j        ||         j        |z
  ||         j        |z
  ¦  «        ¦  «         Œ�t          |¦  «        t          |¦  «        z  S )zPComputes high-frequency spatial residual energy indicative of biological tremor.é   rN   rR   g       @)rH   r\   r   r   rI   rT   rU   rG   )r0   r2   Ú	residualsrW   Úmid_xÚmid_ys         r   Ú_compute_spatial_tremor_energyz7TouchBiometricsValidator._compute_spatial_tremor_energyw   sÖ   € åˆv‰;Œ;˜Š?ˆ?Ø�3Øˆ	Ý�q�#˜f™+œ+¨™/Ñ*Ô*ð 	Sð 	SˆAØ˜A ™E”]”_ v¨a°!©e¤}¤Ñ6¸#Ñ=ˆEØ˜A ™E”]”_ v¨a°!©e¤}¤Ñ6¸#Ñ=ˆEØ×Ò�TœZ¨¨q¬	¬°eÑ(;¸VÀA¼Y¼[È5Ñ=PÑQÔQÑRÔRÐRÐRÝ�9‰~Œ~¥ I¡¤Ñ.Ð.r   c                ó,  ‡— g }t          ‰¦  «        dk     rd|fS t          ˆfd„t          t          ‰¦  «        dz
  ¦  «        D ¦   «         ¦  «        }|dk    r9|                      ‰¦  «        }|dk     r|                     d|d›d	�¦  «         d
|fS d|fS )zREvaluates 8-12Hz physiological micro-tremor spatial residual energy along gesture.é   rF   c              3  ó²   •K  — | ]Q}t          j        ‰|d z            j        ‰|         j        z
  ‰|d z            j        ‰|         j        z
  ¦  «        V — ŒRdS rQ   rS   rV   s     €r   r;   zFTouchBiometricsValidator._check_spatial_microtremor.<locals>.<genexpr>ˆ   rX   r   rR   g      >@g{®Gázt?z$Sub-biological micro-tremor energy (rZ   z$pt) - mathematically synthetic curverE   )rH   rG   r\   ru   rI   )r0   r2   rJ   r`   Úenergys    `   r   Ú_check_spatial_microtremorz3TouchBiometricsValidator._check_spatial_microtremor‚   sÎ   ø€ à!ˆ	Ýˆv‰;Œ;˜Š?ˆ?Ø˜�?Ð"åð 
ð 
ð 
ð 
å�3˜v™;œ;¨™?Ñ+Ô+ð
ñ 
ô 
ñ 
ô 
ˆð �dŠ?ˆ?Ø×8Ò8¸Ñ@Ô@ˆFØ˜Š~ˆ~Ø× Ò Øk¸6ÐkÐkÐkÐkñô ð ð ˜Y�Ð&à�YˆÐr   c                ó¬  ‡— g }t          |¦  «        dk     rd|fS d„ |D ¦   «         }t          |¦  «        t          |¦  «        z  Š‰dk    s‰dk    r|                     d‰d›d�¦  «         d	|fS t          ˆfd
„|D ¦   «         ¦  «        t          |¦  «        z  }|dk     r1t          |¦  «        dk    r|                     d|d›d�¦  «         d|fS d|fS )zMEvaluates touch pressure dynamics and biological fingertip compression curve.r?   rF   c                ó   — g | ]	}|j         ‘Œ
S r   )r   r8   s     r   re   zDTouchBiometricsValidator._check_pressure_physics.<locals>.<listcomp>œ   s   € Ð*Ð*Ð*˜a�!”'Ð*Ð*Ð*r   ç        g      ø?z$Unnatural touch pressure magnitude (r=   z) - simulated eventr[   c              3  ó(   •K  — | ]}|‰z
  d z  V — ŒdS rA   r   )r9   ÚfÚ	avg_forces     €r   r;   zCTouchBiometricsValidator._check_pressure_physics.<locals>.<genexpr>¢   s,   øè è € ÐBÐB°a˜a )™m°Ñ1ÐBÐBÐBÐBÐBÐBr   g-Cëâ6
?rw   zStatic pressure lock (variance=z.6fz!) - macro constant force detectedg)\�Âõ(ì?)rH   rG   rI   )r0   r2   rJ   ÚforcesÚforce_variancer€   s        @r   Ú_check_pressure_physicsz0TouchBiometricsValidator._check_pressure_physics–   s  ø€ à!ˆ	Ýˆv‰;Œ;˜Š?ˆ?Ø˜�?Ð"à*Ð* 6Ð*Ñ*Ô*ˆÝ˜‘K”K¥# f¡+¤+Ñ-ˆ	Ø˜ÒÐ˜y¨3š˜Ø×ÒÐfÀIÐfÐfÐfÐfÑgÔgÐgØ˜�?Ð"åÐBÐBÐBÐB¸6ÐBÑBÔBÑBÔBÅSÈÁ[Ä[ÑPˆØ˜GÒ#Ð#­¨F©¬°qÒ(8Ð(8Ø×ÒØg°.ÐgÐgÐgÐgñô ð ð ˜�?Ð"à�YˆÐr   c                óÚ  ‡	— g }t          |¦  «        dk     rd|fS g }t          t          |¦  «        dz
  ¦  «        D ]‹}||dz            j        ||         j        z
  }|dk    ret          j        ||dz            j        ||         j        z
  ||dz            j        ||         j        z
  ¦  «        }|                     ||z  ¦  «         ŒŒt          |¦  «        dk    rŽt          |¦  «        t          |¦  «        z  Š	‰	dk    rit          ˆ	fd„|D ¦   «         ¦  «        t          |¦  «        z  }t          j	        |¦  «        }|dk     r$‰	dk    r|                     d	|d
›d�¦  «         d|fS d|fS )zQEvaluates velocity profile: humans exhibit bell-shaped acceleration/deceleration.rq   rF   rR   gü©ñÒMbP?r?   c              3  ó(   •K  — | ]}|‰z
  d z  V — ŒdS rA   r   )r9   ÚsÚ	avg_speeds     €r   r;   zCTouchBiometricsValidator._check_velocity_profile.<locals>.<genexpr>»   s,   øè è € Ð$JÐ$J¸a a¨)¡m¸Ñ%9Ð$JÐ$JÐ$JÐ$JÐ$JÐ$Jr   rD   r(   zConstant velocity profile (std=ú.4fz) - robotic script detectedrE   )
rH   r\   r   rT   rU   r   r   rI   rG   rj   )
r0   r2   rJ   ÚspeedsrW   rg   ÚdistÚspeed_varianceÚ	speed_stdr‡   s
            @r   Ú_check_velocity_profilez0TouchBiometricsValidator._check_velocity_profile«   sƒ  ø€ à!ˆ	Ýˆv‰;Œ;˜Š?ˆ?Ø˜�?Ð"à ˆÝ•s˜6‘{”{ Q‘Ñ'Ô'ð 	)ð 	)ˆAØ˜˜A™”Ô+¨f°Q¬iÔ.DÑDˆBØ�EŠzˆzÝ”z &¨¨Q©¤-¤/°F¸1´I´KÑ"?ÀÈÈAÉÄÄÐSYÐZ[ÔS\ÔS^ÑA^Ñ_Ô_�Ø—’˜d R™iÑ(Ô(Ð(øåˆv‰;Œ;˜!ÒÐÝ˜F™œ¥c¨&¡k¤kÑ1ˆIØ˜4ÒÐÝ!$Ð$JÐ$JÐ$JÐ$JÀ6Ð$JÑ$JÔ$JÑ!JÔ!JÍSÐQWÉ[Ì[Ñ!X�Ý œI nÑ5Ô5�	Ø˜vÒ%Ð%¨)°cª/¨/Ø×$Ò$Ød¸)ÐdÐdÐdÐdñô ð ð   ˜?Ð*à�YˆÐr   c                ód  ‡‡— g }t          |¦  «        dk     rd|fS t          d„ |D ¦   «         ¦  «        t          |¦  «        z  Št          d„ |D ¦   «         ¦  «        t          |¦  «        z  Št          ˆˆfd„|D ¦   «         ¦  «        }|dk     r|                     d|d›d	�¦  «         d
|fS d|fS )zEDetects stationary auto-clicker tapping at the exact same coordinate.r?   rF   c              3  ó$   K  — | ]}|j         V — Œd S r/   )r   r8   s     r   r;   zATouchBiometricsValidator._check_repetitive_tap.<locals>.<genexpr>Ë   ó$   è è € Ð+Ð+˜q�q”sÐ+Ð+Ð+Ð+Ð+Ð+r   c              3  ó$   K  — | ]}|j         V — Œd S r/   )r   r8   s     r   r;   zATouchBiometricsValidator._check_repetitive_tap.<locals>.<genexpr>Ì   r�   r   c              3  ób   •K  — | ])}t          j        |j        ‰z
  |j        ‰z
  ¦  «        V — Œ*d S r/   rS   )r9   r:   Úcenter_xÚcenter_ys     €€r   r;   zATouchBiometricsValidator._check_repetitive_tap.<locals>.<genexpr>Í   s<   øè è € Ð"^Ð"^ÐRS¥4¤:¨a¬c°H©n¸a¼cÀH¹nÑ#MÔ#MÐ"^Ð"^Ð"^Ð"^Ð"^Ð"^r   ç333333Ã?z"Sub-pixel static coordinate lock (rˆ   zpx) - autoclicker detectedr>   )rH   rG   ÚmaxrI   )r0   r2   rJ   Úmax_dist_from_centerr“   r”   s       @@r   Ú_check_repetitive_tapz.TouchBiometricsValidator._check_repetitive_tapÅ   sâ   øø€ à!ˆ	Ýˆv‰;Œ;˜Š?ˆ?Ø˜�?Ð"åÐ+Ð+ FÐ+Ñ+Ô+Ñ+Ô+­c°&©k¬kÑ9ˆÝÐ+Ð+ FÐ+Ñ+Ô+Ñ+Ô+­c°&©k¬kÑ9ˆÝ"Ð"^Ð"^Ð"^Ð"^Ð"^ÐW]Ð"^Ñ"^Ô"^Ñ^Ô^Ðà $Ò&Ð&Ø×ÒØiÐ5IÐiÐiÐiÐiñô ð ð ˜�?Ð"à�YˆÐr   r   c           
     ó   — |st          ddddgd¬¦  «        S d|                      |¦  «        fd|                      |¦  «        fd	|                      |¦  «        fd
|                      |¦  «        fd|                      |¦  «        fd|                      |¦  «        fd|                      |¦  «        fg}g }d}d}|D ]'\  }\  }}|                     |¦  «         ||k    r|}|}Œ(t          d„ |D ¦   «         ¦  «        t          |¦  «        z  }	|dk     }
|
r(t          ddt          |	d¦  «        dz  z   dz   ¦  «        }nt          dd|z
  ¦  «        }t          |
t          |d¦  «        t          |d¦  «        ||¬¦  «        S )zBDetailed multi-vector biometrics evaluation with ensemble scoring.Fr}   g      ð?zEmpty touch streamÚempty_stream)r   r   r    r!   r#   Úradius_physicsÚ	linearityÚtemporal_microtremorÚspatial_microtremorÚpressure_physicsÚvelocityÚrepetitive_tapÚnominalc              3  ó$   K  — | ]}|j         V — Œd S r/   r7   r8   s     r   r;   z=TouchBiometricsValidator.evaluate_detailed.<locals>.<genexpr>ö   r<   r   g      à?gffffffæ?rY   g      Y@r•   g{®Gáz”?r?   )r   rL   rb   ro   rz   rƒ   r�   r˜   ÚextendrG   rH   Úminr–   Úround)r0   r2   ÚchecksÚall_anomaliesÚmax_bot_probÚdominantÚfeature_nameÚprobÚreasonsrC   r   r   s               r   Úevaluate_detailedz*TouchBiometricsValidator.evaluate_detailed×   sÚ  € àð 	Ý,ØØØ #Ø!5Ð 6Ø!/ðñ ô ð ð ˜t×9Ò9¸&ÑAÔAÐBØ˜$×:Ò:¸6ÑBÔBÐCØ# T×%EÒ%EÀfÑ%MÔ%MÐNØ" D×$CÒ$CÀFÑ$KÔ$KÐLØ ×!=Ò!=¸fÑ!EÔ!EÐFØ˜×5Ò5°fÑ=Ô=Ð>Ø˜t×9Ò9¸&ÑAÔAÐBð
ˆð $&ˆØˆØˆà-3ð 	(ð 	(Ñ)ˆL™/˜4 Ø× Ò  Ñ)Ô)Ð)Ø�lÒ"Ð"Ø#�Ø'�øåÐ8Ð8°Ð8Ñ8Ô8Ñ8Ô8½3¸v¹;¼;ÑFˆ
Ø $Ò&ˆØð 	8Ý˜c 4­3¨z¸4Ñ+@Ô+@À5Ñ+HÑ#IÈDÑ#PÑQÔQˆKˆKå˜d C¨,Ñ$6Ñ7Ô7ˆKå(ØÝ˜k¨1Ñ-Ô-Ý! ,°Ñ2Ô2Ø)Ø%ð
ñ 
ô 
ð 	
r   úTuple[bool, float, str]c                ó¨   — |                       |¦  «        }|j        r
d|j        dfS |j        rd                     |j        ¦  «        nd}d|j        |fS )z…
        Legacy compatible evaluation method.
        Returns: (is_human: bool, trust_score: float [0.0 - 1.0], reason: str)
        Tz(Authentic human biometric motion patternz; zBot detectedF)r®   r   r   r!   Újoin)r0   r2   ÚresÚ
reason_strs       r   Úevaluate_touch_samplez.TouchBiometricsValidator.evaluate_touch_sample  sc   € ð
 ×$Ò$ VÑ,Ô,ˆØŒ<ð 	UØ˜œÐ*TÐTÐTØ7:Ô7JÐ^�T—Y’Y˜sÔ2Ñ3Ô3Ð3ÐP^ˆ
Ø�c”o zÐ1Ð1r   N)r&   r'   r(   )r)   r   r*   r   r+   r   r,   r-   )r2   r3   r,   r4   )r2   r3   r,   r   )r2   r3   r,   r   )r2   r3   r,   r¯   )r   r   r   Ú__doc__r1   rL   rb   ro   ru   rz   rƒ   r�   r˜   r®   r´   r   r   r   r%   r%       s  € € € € € ðð ð #&Ø)/Ø),ð	?ð ?ð ?ð ?ð ?ðð ð ð ð$ð ð ð ð.ð ð ð ð:	/ð 	/ð 	/ð 	/ðð ð ð ð(ð ð ð ð*ð ð ð ð4ð ð ð ð$,
ð ,
ð ,
ð ,
ð\	2ð 	2ð 	2ð 	2ð 	2ð 	2r   r%   )rµ   Ú
__future__r   rT   Útypingr   r   r   r   Údataclassesr   r   r   r%   r   r   r   ú<module>r¹      s&  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ð .Ø !Ð !Ð !Ð !Ð !Ð !ð €�˜dÐ#Ñ#Ô#ðð ð ð ð ñ ô ñ $Ô#ðð €�˜dÐ#Ñ#Ô#ðð ð ð ð ñ ô ñ $Ô#ððn2ð n2ð n2ð n2ð n2ñ n2ô n2ð n2ð n2ð n2r   