§
    =Œ¨jMç  ã                  óT  — d dl m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
mZmZmZmZmZ dZdZeeef         Zd1d„Zd2d3d„Ze G d„ d¦  «        ¦   «         Zd4d„Zd5d„Zd4d„Zd6d„Z	 d7d8d„Zd6d„Zd5d„Zd5d „Zd4d!„Z d6d"„Z!d9d$„Z"d:d&„Z#d;d'„Z$d;d(„Z%d<d,„Z&d=d.„Z' G d/„ d0¦  «        Z(dS )>é    )ÚannotationsN)Ú	dataclass)ÚDecimalÚInvalidOperationÚROUND_HALF_UP)ÚAnyÚDictÚListÚOptionalÚTupleé   é   ÚpenniesÚintÚreturnÚstrc                ód   — t          dt          | ¦  «        ¦  «        }|dz  }|dz  }d|d›d|d›�S )z&Format integer pennies as `$1,234.56`.r   éd   ú$ú,ú.Ú02d©Úmaxr   )r   ÚvalueÚdollarsÚcentss       ú²D:\Dyzine Tek Dropbox\Chris Cummings\Dyzine Tek, LLC\Engineering\Digital Signage\Overhead Bank Signage\DyzineFrame\Cursor OHD Project\DyzineFrame\reusable_odometer\core\engine.pyÚformat_dollarsr      sE   € å�•3�w‘<”<Ñ Ô €EØ�s‰l€GØ�C‰K€EØ&ˆwÐ&Ð&Ð&˜5Ð&Ð&Ð&Ð&ó    r   r   Údefaultc           
     óú  — | €t          dt          |¦  «        ¦  «        S t          | t          ¦  «        rt          dt          | ¦  «        ¦  «        S t          | t          ¦  «        rpt	          t          | ¦  «        ¦  «        t	          d¦  «        z  }t          dt          |                     t	          d¦  «        t          ¬¦  «        ¦  «        ¦  «        S t          | ¦  «                             ¦   «         }|st          dt          |¦  «        ¦  «        S | 	                    dd¦  «         	                    dd¦  «        }	 t	          |¦  «        }n4# t          t          f$ r  t          dt          |¦  «        ¦  «        cY S w xY wd	|v rV|t	          d¦  «        z  }t          dt          |                     t	          d¦  «        t          ¬¦  «        ¦  «        ¦  «        S t          dt          |¦  «        ¦  «        S )
z9Parse an int-pennies or dollar-string value into pennies.Nr   Ú100Ú1)Úroundingr   Ú r   r   )r   r   Ú
isinstanceÚfloatr   r   Úquantizer   ÚstripÚreplacer   Ú
ValueError)r   r!   r   ÚtextÚparseds        r   Úparse_display_to_penniesr/      s©  € à€}Ý�1•c˜'‘l”lÑ#Ô#Ð#Ý�%�ÑÔð "Ý�1•c˜%‘j”jÑ!Ô!Ð!Ý�%�ÑÔð QÝ�˜E™
œ
Ñ#Ô#¥g¨e¡n¤nÑ4ˆÝ�1•c˜%Ÿ.š.­°©¬Å˜.ÑNÔNÑOÔOÑPÔPÐPåˆu‰:Œ:×ÒÑÔ€DØð $Ý�1•c˜'‘l”lÑ#Ô#Ð#Ø�<Š<˜˜RÑ Ô ×(Ò(¨¨bÑ1Ô1€Dð$Ý˜‘”ˆˆøÝ�jÐ)ð $ð $ð $Ý�1•c˜'‘l”lÑ#Ô#Ð#Ð#Ð#ð$øøøð ˆd€{€{Ø� ™œÑ'ˆÝ�1•c˜%Ÿ.š.­°©¬Å˜.ÑNÔNÑOÔOÑPÔPÐPÝˆq•#�f‘+”+ÑÔÐs   ÅE Å.FÆFc                  óì  — e Zd ZU dZded<   dZded<   dZded<   dZded<   dZded	<   d
Z	ded<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded <   dZded!<   dZded"<   d#Zded$<   dZded%<   dZded&<   d'Zded(<   d)Zded*<   d+Zded,<   d-Zded.<   d/Zded0<   d1Zded2<   dZded3<   d4Z ded5<   d6Z!ded7<   dZ"ded8<   dZ#ded9<   e$	 dBdCdA„¦   «         Z%d:S )DÚOdometerConfigiè  r   Úmax_lag_penniesiô  Úpenny_max_lag_penniesr   Údime_continuous_lag_penniesÚdime_roll_max_lag_penniesÚpenny_roll_max_lag_penniesg333333Ã?r(   Úmin_rateç      à?Úmax_rateç      @Údime_max_rateg      9@Úidle_catchup_secç      @Úcontribution_idle_secç      @Úpenny_roll_secç        Úpenny_roll_sec_mingffffffÖ?Úcarry_roll_secç      ð?Úcarry_roll_sec_minÚinitial_display_pennies© úTuple[CurvePoint, ...]Ú
rate_curveÚroll_curve_secÚchase_rate_scaleé   Úcatchup_lag_thresholdÚcatchup_lag_bonus_per_centÚsnap_behind_threshold_pennieséÈ   Úsnap_behind_to_lag_penniesgš™™™™™Ù?Úroll_smooth_taugš™™™™™É?Úpenny_roll_sec_floorr   Údime_catchup_enter_pennieséP   Údime_catchup_exit_penniesiX  Údollar_catchup_enter_penniesÚdollar_catchup_exit_penniesi   Údollar_roll_max_lag_penniesgÍÌÌÌÌÌÜ?Údollar_roll_secÚdollar_roll_sec_minÚdollar_roll_smooth_tauNÚdataúOptional[Dict[str, Any]]Úkwargsr   r   ú'OdometerConfig'c                ó�  — i }|r|                      |¦  «         |                      |¦  «          | ¦   «         }dD ])}||v r#t          ||         |j        ¬¦  «        |_         nŒ*i dd“dd“dd“dd“dd“dd“d	d“d
d
“dd
“dd“dd“dd“dd“dd“dd“dd“dd“i dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d“d!d!“d"d"“d#d#“d$d#“¥d%d%d&d&d'd'd(d(d)d*d+d,œ¥}|                     ¦   «         D ] \  }}||v rt	          ||||         ¦  «         Œ!d-}	|	D ]/\  }}}
||v r%t	          ||t          ||         |
¦  «        ¦  «         Œ0|S ).N)Úinitial_displayÚinitial_dollarsÚinitial_pennies)r!   r2   r3   Úpenny_max_lagr6   Úpenny_roll_max_lagr4   Údime_continuous_lagr5   Údime_roll_max_lagr7   r9   r;   r<   r>   Úmax_lagÚpennies_min_rateÚpennies_max_rater@   rB   rC   rE   Údime_roll_secÚdime_roll_sec_minrK   rM   rN   rO   rQ   Ú!progressive_snap_behind_thresholdÚprogressive_snap_behind_lagrR   rS   rT   Údime_catchup_enterrV   rW   rX   rY   rZ   r[   r\   )rV   Údime_catchup_exitrW   Údollar_catchup_enterrX   Údollar_catchup_exitrY   Údollar_roll_max_lagrZ   r[   r\   ))rI   rI   Úrate)Úchase_rate_curverI   ru   )Úpennies_per_second_curverI   ru   )rJ   rJ   Úsec)Úpenny_roll_curve_secrJ   rx   )Úroll_sec_curverJ   rx   )Úupdater/   rF   ÚitemsÚsetattrÚ_parse_curve_points)Úclsr]   r_   ÚmergedÚcfgÚkeyÚkey_mapÚsrcÚdstÚ	curve_mapÚ	value_keys              r   Úfrom_mappingzOdometerConfig.from_mapping_   s  € ð "$ˆØð 	 Ø�MŠM˜$ÑÔÐØ�Š�fÑÔÐØˆc‰eŒeˆàLð 	ð 	ˆCØ�fˆ}ˆ}Ý.FØ˜3”K¨Ô)Dð/ñ /ô /�Ô+ð �ð	 ð.
ØÐ0ð.
à#Ð%<ð.
ð Ð4ð.
ð )Ð*Fð	.
ð
 !Ð">ð.
ð *Ð+Hð.
ð "Ð#@ð.
ð (Ð)Dð.
ð  Ð!<ð.
ð ˜
ð.
ð ˜
ð.
ð ˜_ð.
ð Ð 2ð.
ð $Ð%<ð.
ð Ð(ð.
ð   
ð!.
ð"  
ð#.
ð .
ð$ Ð.ð%.
ð& !Ð"6ð'.
ð( Ð.ð).
ð* !Ð"6ð+.
ð, Ð-ð-.
ð.  Ð!5ð/.
ð0 Ð 2ð1.
ð2 $Ð%<ð3.
ð4 )Ð*Fð5.
ð6 ,Ð-Lð7.
ð8 )Ð*Fð9.
ð: 0Ð1Pð;.
ð< *Ð+Gð=.
ð> Ð0ð?.
ð@ #Ð$:ðA.
ðB )Ð*FðC.
ðD !Ð">ðE.
ð .
ðF *EØ!<Ø,JØ$BØ+HØ#@Ø+HØ#@Ø0Ø#8Ø&>ð[.
ð .
ð .
ˆð^  Ÿš™œð 	/ð 	/‰HˆC�Ø�fˆ}ˆ}Ý˜˜S &¨¤+Ñ.Ô.Ð.øð
ˆ	ð $-ð 	Oð 	OÑˆC��iØ�fˆ}ˆ}Ý˜˜SÕ"5°f¸S´kÀ9Ñ"MÔ"MÑNÔNÐNøØˆ
r    ©N)r]   r^   r_   r   r   r`   )&Ú__name__Ú
__module__Ú__qualname__r2   Ú__annotations__r3   r4   r5   r6   r7   r9   r;   r<   r>   r@   rB   rC   rE   rF   rI   rJ   rK   rM   rN   rO   rQ   rR   rS   rT   rV   rW   rX   rY   rZ   r[   r\   Úclassmethodrˆ   rG   r    r   r1   r1   /   s�  € € € € € € à€OÐÐÐÑØ!$ÐÐ$Ð$Ð$Ñ$Ø'(ÐÐ(Ð(Ð(Ñ(Ø%(ÐÐ(Ð(Ð(Ñ(Ø&'ÐÐ'Ð'Ð'Ñ'Ø€HÐÐÐÑØ€HÐÐÐÑØ€MÐÐÐÑØ"ÐÐ"Ð"Ð"Ñ"Ø#&ÐÐ&Ð&Ð&Ñ&Ø€NÐÐÐÑØ #ÐÐ#Ð#Ð#Ñ#ð !€NÐ Ð Ð Ñ Ø #ÐÐ#Ð#Ð#Ñ#Ø#$ÐÐ$Ð$Ð$Ñ$Ø)+€JÐ+Ð+Ð+Ñ+Ø-/€NÐ/Ð/Ð/Ñ/Ø!ÐÐ!Ð!Ð!Ñ!Ø!#ÐÐ#Ð#Ð#Ñ#Ø(+ÐÐ+Ð+Ð+Ñ+à)-Ð!Ð-Ð-Ð-Ñ-Ø&)ÐÐ)Ð)Ð)Ñ)ð !€OÐ Ð Ð Ñ à"&ÐÐ&Ð&Ð&Ñ&à&)ÐÐ)Ð)Ð)Ñ)Ø%'ÐÐ'Ð'Ð'Ñ'ð ),Ð Ð+Ð+Ð+Ñ+Ø'*ÐÐ*Ð*Ð*Ñ*Ø'*ÐÐ*Ð*Ð*Ñ*ð "€OÐ!Ð!Ð!Ñ!Ø!$ÐÐ$Ð$Ð$Ñ$à$'ÐÐ'Ð'Ð'Ñ'àà.2ðMð Mð Mð Mñ „[ðMð Mð Mr    r1   r�   c                ó~   — | j         rt          d„ | j         D ¦   «         ¦  «        S | j        dk    r| j        S | j        S )Nc              3  ó&   K  — | ]}|d          V — ŒdS )r   NrG   ©Ú.0Úpoints     r   ú	<genexpr>z'_penny_roll_ramp_lag.<locals>.<genexpr>²   ó&   è è € Ð<Ð< �5˜”8Ð<Ð<Ð<Ð<Ð<Ð<r    r   )rJ   r   r6   r3   ©r�   s    r   Ú_penny_roll_ramp_lagr—   °   sM   € Ø
Ôð =ÝÐ<Ð<¨Ô);Ð<Ñ<Ô<Ñ<Ô<Ð<Ø
Ô%¨Ò)Ð)ØÔ-Ð-ØÔ$Ð$r    r(   c                ó¤   — | j         rt          d„ | j         D ¦   «         ¦  «        S t          | j        d¦  «        }| j        dk    r| j        n|dz  S )Nc              3  ó&   K  — | ]}|d          V — ŒdS )é   NrG   r‘   s     r   r”   z#slowest_roll_sec.<locals>.<genexpr>º   r•   r    ç�íµ ÷Æ°>r   r:   )rJ   r   r@   rB   )r�   Úfasts     r   Úslowest_roll_secr�   ¸   s^   € Ø
Ôð =ÝÐ<Ð<¨Ô);Ð<Ñ<Ô<Ñ<Ô<Ð<ÝˆsÔ! 4Ñ(Ô(€DØ%(Ô%;¸aÒ%?Ð%?ˆ3Ô!Ð!ÀTÈCÁZÐOr    c                ó^   — | j         dk    rt          | j         ¦  «        S t          | ¦  «        S )zMLag (cents) at which intermittent/dime roll reaches carry_roll_sec (fastest).r   )r5   r   r—   r–   s    r   Ú_carry_roll_ramp_lagrŸ   ¿   s/   € à
Ô$ qÒ(Ð(Ý�3Ô0Ñ1Ô1Ð1Ý Ñ$Ô$Ð$r    Údeltac                ó:  — t          t          |j        ¦  «        d¦  «        }|j        dk    rt          |j        ¦  «        n|dz  }t          t	          |¦  «        d¦  «        }t          t          dt          | ¦  «        ¦  «        |¦  «        |z  }||||z
  z  z   S )z×Seconds per full digit roll for dimes/dollars+ (independent of penny ramp).

    Uses ``carry_roll_sec`` / ``carry_roll_sec_min`` (aliases ``dime_roll_sec``*)
    and ramps across ``dime_roll_max_lag_pennies``.
    r›   r   r:   rš   )r   r(   rC   rE   rŸ   Úminr   )r    r�   rœ   ÚslowÚcapÚts         r   Ú_carry_roll_sec_at_lagr¦   Æ   sŸ   € õ �u�SÔ'Ñ(Ô(¨$Ñ/Ô/€Dð Ô! AÒ%Ð%õ 	ˆcÔ$Ñ%Ô%Ð%à�C‰Zð 	õ
 Õ" 3Ñ'Ô'¨Ñ
+Ô
+€CÝ�C�•3�u‘:”:ÑÔ Ñ$Ô$ sÑ*€AØ�!�t˜d‘{Ñ#Ñ#Ð#r    éÿÿÿÿÚpowerÚlag_penniesc                óR   — ~ |dk    r|nt          |¦  «        }t          ||¦  «        S ©Nr   )rŸ   r¦   )r¨   r�   r©   Úlags       r   Úcarry_roll_sec_for_powerr­   ×   s3   € ð 	Ø$¨Ò)Ð)ˆ+ˆ+Õ/CÀCÑ/HÔ/H€CÝ! # sÑ+Ô+Ð+r    c                ó‚  — |j         rt          | |j         ¦  «        }nut          |j        d¦  «        }|j        dk    r|j        n|dz  }t          t          |¦  «        d¦  «        }t          t          d| ¦  «        |¦  «        |z  }||||z
  z  z   }t          |j        pd¦  «        }|dk    rt          ||¦  «        }|S )Nr›   r   r:   rš   rA   )	rJ   Ú_curve_value_at_lagr   r@   rB   r—   r¢   r(   rS   )r    r�   rx   rœ   r£   r¤   r¥   Úfloors           r   Ú_penny_roll_sec_at_lagr±   ß   sÉ   € Ø
Ôð 'Ý! %¨Ô);Ñ<Ô<ˆˆå�3Ô% tÑ,Ô,ˆØ),Ô)?À!Ò)CÐ)CˆsÔ%Ð%ÈÐPSÉˆÝÕ& sÑ+Ô+¨QÑ/Ô/ˆÝ•�A�u‘”˜sÑ#Ô# cÑ)ˆØ�Q˜$ ™+Ñ&Ñ&ˆÝ�#Ô*Ð1¨cÑ2Ô2€EØˆs‚{€{Ý�#�u‰oŒoˆØ€Jr    c                ó<   — t          t          | ¦  «        | ¦  «        S )z3Fastest legal penny digit roll (full ramp + floor).)r±   r—   r–   s    r   Ú_penny_maxed_roll_secr³   î   ó   € å!Õ"6°sÑ";Ô";¸SÑAÔAÐAr    c                ó<   — t          t          | ¦  «        | ¦  «        S )z0Fastest legal dime digit roll (full carry ramp).)r¦   rŸ   r–   s    r   Ú_carry_maxed_roll_secr¶   ó   r´   r    c                ó^   — | j         dk    rt          | j         ¦  «        S t          | ¦  «        S )zCLag (cents) at which dollar roll reaches dollar_roll_sec (fastest).r   )rY   r   rŸ   r–   s    r   Ú_dollar_roll_ramp_lagr¸   ø   s/   € à
Ô&¨Ò*Ð*Ý�3Ô2Ñ3Ô3Ð3Ý Ñ$Ô$Ð$r    c                ó˜  — t          t          |j        ¦  «        d¦  «        }|j        dk    rt          |j        ¦  «        n|dz  }t	          |¦  «        }t          ||¦  «        }t          ||¦  «        }t          t          |¦  «        d¦  «        }t          t          dt          | ¦  «        ¦  «        |¦  «        |z  }||||z
  z  z   S )uæ   Seconds per full dollar digit roll (independent of dime/carry ramp).

    Visual floor: never faster than maxed dime roll â€” dollars advance +$1 per
    land so value throughput stays higher even when the glyph spins slower.
    r›   r   r?   rš   )r   r(   rZ   r[   r¶   r¸   r¢   r   )r    r�   rœ   r£   Ú
dime_floorr¤   r¥   s          r   Ú_dollar_roll_sec_at_lagr»   ÿ   sÈ   € õ �u�SÔ(Ñ)Ô)¨4Ñ0Ô0€Dð Ô" QÒ&Ð&õ 	ˆcÔ%Ñ&Ô&Ð&à�C‰Zð 	õ ' sÑ+Ô+€JÝˆt�ZÑ Ô €DÝˆt�T‰?Œ?€DÝ
Õ# CÑ(Ô(¨!Ñ
,Ô
,€CÝ�C�•3�u‘:”:ÑÔ Ñ$Ô$ sÑ*€AØ�!�t˜d‘{Ñ#Ñ#Ð#r    ú	List[int]c                ó~   ‡ — t          dt          ‰ ¦  «        ¦  «        Š ˆ fd„t          t          ¦  «        D ¦   «         S )Nr   c                ó&   •— g | ]}‰d |z  z  d z  ‘ŒS )é
   rG   )r’   Úir   s     €r   ú
<listcomp>z&_pennies_to_digits.<locals>.<listcomp>  s'   ø€ ÐBÐBÐB¨!ˆW˜˜Q™Ñ 2Ñ%ÐBÐBÐBr    )r   r   ÚrangeÚNUM_COLUMNS)r   s   `r   Ú_pennies_to_digitsrÄ     s:   ø€ Ý�!•S˜‘\”\Ñ"Ô"€GØBÐBÐBÐB­uµ[Ñ/AÔ/AÐBÑBÔBÐBr    Údigitsc                óh   — t          t          dz
  dd¦  «        D ]}| |         dk    r|c S Œt          S )Nrš   r§   r   )rÂ   rÃ   ÚMIN_DISPLAY_POWER)rÅ   r¨   s     r   Úleftmost_significant_powerrÈ     sD   € Ý•{ Q‘¨¨BÑ/Ô/ð ð ˆØ�%Œ=˜AÒÐØˆLˆLˆLð åÐr    c                ó  — t          | ¦  «        }t          d| ¦  «        }t          || ¦  «        }t          | ¦  «        }t          d| ¦  «        }t          || ¦  «        }t	          | ¦  «        }t          d| ¦  «        }t          || ¦  «        }	| j        dk    rd| j        › d�nd}
| j        dk    rd| j        › d�nd}| j        s| j	        r¤| j        rdt          | j        ¦  «        › d�n| j        › d	| j        › d
| j        › d�}| j	        rdt          | j	        ¦  «        › d�n	|d›d|d›d�}dt          | j        ¦  «        › d|› d|› d|d›d|d›d|› d|d›d|	d›d|› d|
› d|› d| j        › d�S d                     g d‘t          | j        ¦  «        › ‘d‘| j        › ‘d‘|› ‘d‘|d›‘d‘|d›‘d‘|› ‘d‘|d›‘d‘|d›‘d‘|› ‘d‘|d›‘d‘|	d›‘d‘|
› ‘d‘|› ‘d‘| j        › ‘d	‘| j        › ‘d
‘| j        › ‘d‘| j        › ‘d‘¦  «        S ) Nr   zdime_catchup@Úczdimes=intermittentzdollar_catchup@zdollars=cascadezcurve[ú]z->ú+zc/sz.2fzs->Úszstart=z  chase=z  penny_roll=z  carry_roll=zs@zc  dollar_roll=zc  ú  z  @ r&   z  chase@zc  penny_roll@zc zs  carry_roll@zs  dollar_roll@zs  zc/s @ )r—   r±   rŸ   r¦   r¸   r»   rT   rW   rI   rJ   Úlenr7   r9   r;   r   rF   r2   Újoinr3   )r�   Úroll_capÚ	roll_slowÚ	roll_fastÚ	carry_capÚ
carry_slowÚ
carry_fastÚ
dollar_capÚdollar_slowÚdollar_fastÚ	dime_descÚdollar_descÚ
chase_descÚ	roll_descs                 r   Úformat_odometer_config_summaryrÞ      sp  € Ý# CÑ(Ô(€HÝ& q¨#Ñ.Ô.€IÝ& x°Ñ5Ô5€IÝ$ SÑ)Ô)€IÝ'¨¨3Ñ/Ô/€JÝ'¨	°3Ñ7Ô7€JÝ& sÑ+Ô+€JÝ)¨!¨SÑ1Ô1€KÝ)¨*°cÑ:Ô:€Kð Ô)¨AÒ-Ð-ð 	:˜Ô6Ð9Ð9Ð9Ð9à!ð ð Ô+¨aÒ/Ð/ð 	>˜#Ô:Ð=Ð=Ð=Ð=àð ð
 „~ð 
˜Ô+ð 
ð Œ~ðJÐ+•S˜œÑ(Ô(Ð+Ð+Ð+Ð+à”LÐIÐI C¤LÐIÐI°3Ô3DÐIÐIÐIð 	ð Ô!ð7Ð/•S˜Ô+Ñ,Ô,Ð/Ð/Ð/Ð/àÐ6Ð6Ð6 iÐ6Ð6Ð6Ð6ð 	ðD•^ CÔ$?Ñ@Ô@ð Dð DØðDð DØ.7ðDð Dà$ÐMðDð Dà-7ÐMðDð Dà?HðDð Dð 'ÐQðDð Dð 0;ÐQðDð Dð CMðDð Dð ð	Dð Dð (ð	Dð Dð .1Ô-@ð	Dð Dð Dð	
ð	$÷ 	$ò 	$ð 	$ð 	$ð 	$• Ô ;Ñ<Ô<ð 	$ð 	$ð 	$ð 	$ØÔ*ð	$ð 	$ð 	$ð 	$àð	$ð 	$ð 	$ð 	$à"+ÐFð	$ð 	$ð 	$ð 	$à4=ÐFð	$ð 	$ð 	$ð 	$ð  ð	$ð 	$ð 	$ð 	$ð $.ÐIð	$ð 	$ð 	$ð 	$ð 7AÐIð	$ð 	$ð 	$ð 	$ð "ð		$ð 	$ð 	$ð 	$ð &1ÐMð		$ð 	$ð 	$ð 	$ð :EÐMð		$ð 	$ð 	$ð 	$ð
 ð	$ð 	$ð 	$ð 	$ð
 $ð	$ð 	$ð 	$ð 	$ð Œ<ð	$ð 	$ð 	$ð 	$ð œ<ð	$ð 	$ð 	$ð 	$ð +.Ô*;ð	$ð 	$ð 	$ð 	$ð Ô ð	$ð 	$ð 	$ð 	$ñ 	$ô 	$ð	r    c                ój  — t          | d¬¦  «        }dg}dD ]ˆ}t          t          |dz  ¦  «        ¦  «        }|                     |¦  «        }t	          || ¦  «        }d|z  }t          ||¦  «        }|                     d|d›d	|d
›d	|d›d	|d›d	|d›d	|d›�¦  «         Œ‰d                     |¦  «        S )Nr   )Úinitial_target_penniesz2lag($)  lag(c)  chase  roll_s  roll_cap  EFFECTIVE)g      Ð?r8   rD   g       @r=   g      @g      @g      @gö(\�Âõ@r:   g      @g      @g      @g       @g      !@g{®Gáú!@g      "@ç      $@r   rD   z  $z4.2frÎ   Ú5dz5.2fú
)ÚOdometerEnginer   ÚroundÚ_pennies_per_secondr±   r¢   ÚappendrÐ   )	r�   ÚengineÚlinesr   r¬   ÚchaseÚrollÚrcapÚeffs	            r   Úformat_odometer_lag_maprî   R  s÷   € Ý˜C¸Ð:Ñ:Ô:€FØAÐB€Eðð 
ð 
ˆõ( •%˜ #™Ñ&Ô&Ñ'Ô'ˆØ×*Ò*¨3Ñ/Ô/ˆÝ% c¨3Ñ/Ô/ˆØ�T‰zˆÝ�%˜ÑÔˆØ�ŠØ^�'Ð^Ð^Ð^ #Ð^Ð^Ð^¨EÐ^Ð^Ð^¸$Ð^Ð^Ð^ÀtÐ^Ð^Ð^ÐTWÐ^Ð^Ð^ñ	
ô 	
ð 	
ð 	
ð �9Š9�UÑÔÐr    Úrawr‡   rH   c           
     óŠ  — t          | t          t          f¦  «        sdS i }| D �]r}d }d }t          |t          ¦  «        rÄ|                     d|                     d|                     d¦  «        ¦  «        ¦  «        }|                     ||                     d|                     d¦  «        ¦  «        ¦  «        }|�|€Œ›	 t          dt          |¦  «        ¦  «        }t          |¦  «        }n˜# t          t          f$ r Y ŒÜw xY wt          |t          t          f¦  «        ret          |¦  «        dk    rR	 t          dt          |d         ¦  «        ¦  «        }t          |d	         ¦  «        }n# t          t          f$ r Y �Œ]w xY w|�|�|d
k    r�Œm|||<   �Œtt          t          |                     ¦   «         ¦  «        ¦  «        S )NrG   r©   r¬   Úxr   Úyr   r   rš   rA   )r'   ÚlistÚtupleÚdictÚgetr   r   r(   Ú	TypeErrorr,   rÏ   Úsortedr|   )rï   r‡   ÚpointsÚentryr¬   r   Úlag_rawÚ	value_raws           r   r~   r~   t  s»  € Ý�c�D¥%˜=Ñ)Ô)ð ØˆrØ!€FØð ñ ˆØ!ˆØ!%ˆÝ�e�TÑ"Ô"ð 	Ø—i’i ¨u¯yªy¸ÀÇ	Â	È#ÁÄÑ/OÔ/OÑPÔPˆGØŸ	š	ØØ—	’	˜' 5§9¢9¨S¡>¤>Ñ2Ô2ñô ˆIð ˆ )Ð"3ØðÝ˜!�S ™\œ\Ñ*Ô*�Ý˜iÑ(Ô(��øÝ�zÐ*ð ð ð Ø�ðøøøå˜¥¥e˜}Ñ-Ô-ð 	µ#°e±*´*À²/°/ðÝ˜!�S  q¤™]œ]Ñ+Ô+�Ý˜e Aœh™œ��øÝ�zÐ*ð ð ð Ø‘ðøøøàˆ;˜%˜-¨5°Cª<¨<ÙØˆˆs‰‰Ý•˜Ÿš™œÑ'Ô'Ñ(Ô(Ð(s$   Â?,C,Ã,D Ã?D Ä38E,Å,FÆ FÚcurvec                ó   — |sdS | |d         d         k    r|d         d         S |d         \  }}|dd …         D ]7\  }}| |k    r(t          ||z
  d¦  «        }| |z
  |z  }||||z
  z  z   c S ||}}Œ8|d         d         S )NrA   r   rš   r§   )r   )r    rý   Úprev_lagÚ
prev_valuer¬   r   Úspanr¥   s           r   r¯   r¯   ”  s¸   € Øð ØˆsØ��a”˜”ÒÐØ�QŒx˜Œ{ÐØ  œ8Ñ€HˆjØ˜A˜B˜B”ið *ð *‰
ˆˆUØ�CŠ<ˆ<Ý�s˜X‘~ qÑ)Ô)ˆDØ˜Ñ! TÑ)ˆAØ  U¨ZÑ%7Ñ 8Ñ8Ð8Ð8Ð8Ø" E�*ˆˆØ�Œ9�QŒ<Ðr    c                  óÄ  — e Zd Z	 	 dedfd„Zdgd
„Zdgd„Zdgd„Zdhd„Zdhd„Ze	did„¦   «         Z
djd„Ze	dkd„¦   «         Zdid„Zdjd„Zdjd„Zdjd„Zdldmd„Zdldmd„Zdnd„Zdnd„Zdod"„Zdldpd$„Zdqd%„Zdrd'„Zdrd(„Zdrd)„Zdrd*„Zdjd+„Zdqd,„Zdjd-„Zdjd.„Zdjd/„Z dsd0„Z!dqd1„Z"dtd2„Z#dtd3„Z$dldud5„Z%dldud6„Z&e'dvd9„¦   «         Z(dldwd;„Z)dldwd<„Z*djd=„Z+djd>„Z,dqd?„Z-dqd@„Z.dqdA„Z/dqdB„Z0dtdC„Z1dtdD„Z2dqdE„Z3dqdF„Z4dtdG„Z5dqdH„Z6dtdI„Z7dtdJ„Z8dxdK„Z9dqdL„Z:dqdM„Z;e'dydO„¦   «         Z<djdP„Z=dzdQ„Z>dzdR„Z?d{dS„Z@e'dodT„¦   «         ZAd|dV„ZBdxdW„ZCdsdX„ZDd}d~d[„ZEe'dd\„¦   «         ZFd€d]„ZGd�d_„ZHd{d`„ZIdida„ZJd‚dc„ZKdqdd„ZLdS )ƒrä   NÚconfigúOptional[OdometerConfig]rà   úOptional[int]c                óh  — |pt          ¦   «         | _        |€| j        j        nt          dt	          |¦  «        ¦  «        }|| _        t          |¦  «        | _        t          j	        ¦   «         | _
        dgt          z  | _        dgt          z  | _        d gt          z  | _        dgt          z  | _        d | _        d| _        t%          | j        ¦  «        | _        t)          d| j        ¦  «        | _        t-          d| j        ¦  «        | _        d| _        d| _        d | _        d | _        d| _        d S ©Nr   rA   F)r1   r  rF   r   r   Útarget_penniesr(   Údisplay_floatÚtimeÚperf_counterÚ_last_target_change_timerÃ   Ú_carry_scroll_phaseÚ_carry_finishingÚ_carry_from_digitÚ_carry_was_inÚ_last_maintained_lagÚ_penny_scroll_visualr�   Ú_smoothed_roll_secr¦   Ú_smoothed_carry_roll_secr»   Ú_smoothed_dollar_roll_secÚ_dime_drivenÚ_dollar_drivenÚ_cosmetic_penny_digitÚ_cosmetic_dime_digitÚ_dime_scroll_visual)Úselfr  rà   Ústarts       r   Ú__init__zOdometerEngine.__init__¤  s2  € ð
 Ð0¥Ñ 0Ô 0ˆŒð &Ð-ð ŒKÔ/Ð/å�Q�Ð2Ñ3Ô3Ñ4Ô4ð 	ð
 $)ˆÔÝ$)¨%¡L¤LˆÔÝ/3Ô/@Ñ/BÔ/BˆÔ%Ø14°½Ñ0CˆÔ Ø-2¨GµkÑ,AˆÔØ7;°f½{Ñ6JˆÔØ*/¨µ;Ñ)>ˆÔØ37ˆÔ!Ø+.ˆÔ!Ý)9¸$¼+Ñ)FÔ)FˆÔÝ/EØˆtŒ{ñ0
ô 0
ˆÔ%õ 1HØˆtŒ{ñ1
ô 1
ˆÔ&ð #(ˆÔà$)ˆÔà48ˆÔ"à37ˆÔ!Ø*-ˆÔ Ð Ð r    r  r   ÚNonec                óÈ   — |€d S t          dt          |¦  «        ¦  «        }|| j        k    r5|| _        t          j        ¦   «         | _        |                      ¦   «          d S d S r«   )r   r   r  r
  r  r  Úsnap_if_too_far_behind©r  r  r¥   s      r   Úset_target_penniesz!OdometerEngine.set_target_penniesÉ  sk   € ØÐ!ØˆFÝ�•3�~Ñ&Ô&Ñ'Ô'ˆØ�Ô#Ò#Ð#Ø"#ˆDÔÝ,0Ô,=Ñ,?Ô,?ˆDÔ)Ø×'Ò'Ñ)Ô)Ð)Ð)Ð)ð $Ð#r    c                ó°   — |€dS t          dt          |¦  «        ¦  «        }|| _        t          j        ¦   «         | _        |                      |¦  «         dS )zCSnap target and display immediately to a known starting/live value.Nr   )r   r   r  r
  r  r  Ú_snap_display_to_settled_centsr!  s      r   Údisplay_immediate_penniesz(OdometerEngine.display_immediate_penniesÒ  sW   € àÐ!ØˆFÝ�•3�~Ñ&Ô&Ñ'Ô'ˆØˆÔÝ(,Ô(9Ñ(;Ô(;ˆÔ%Ø×+Ò+¨AÑ.Ô.Ð.Ð.Ð.r    c                ó0   — |                       |¦  «         d S r‰   )r"  )r  r  s     r   Ú
set_targetzOdometerEngine.set_targetÛ  s   € Ø×Ò Ñ/Ô/Ð/Ð/Ð/r    Údelta_penniesr   c                óZ   — |                       | j        t          |¦  «        z   ¦  «         d S r‰   )r"  r  r   ©r  r(  s     r   Úbump_target_penniesz"OdometerEngine.bump_target_penniesÞ  s,   € Ø×Ò Ô 3µc¸-Ñ6HÔ6HÑ HÑIÔIÐIÐIÐIr    c                ó0   — |                       |¦  «         d S r‰   )r+  r*  s     r   Úbump_targetzOdometerEngine.bump_targetá  s   € Ø× Ò  Ñ/Ô/Ð/Ð/Ð/r    c                ó*   — |                       ¦   «         S r‰   )Ú_settled_cents©r  s    r   Údisplay_pennieszOdometerEngine.display_penniesä  s   € à×"Ò"Ñ$Ô$Ð$r    Úboolc                óÞ   — |                       ¦   «         dk    pU| j        pN| j        pG| j        dk    p<| j        dk    p1t          d„ | j        D ¦   «         ¦  «        pt          | j        ¦  «        S )Nr   r›   c              3  ó"   K  — | ]
}|d k    V — ŒdS )r›   NrG   )r’   Úps     r   r”   z.OdometerEngine.is_animating.<locals>.<genexpr>ï  s&   è è € Ð>Ð> �1�t’8Ð>Ð>Ð>Ð>Ð>Ð>r    )r©   r  r  r  r  Úanyr  r  r0  s    r   Úis_animatingzOdometerEngine.is_animatingè  sŽ   € à×ÒÑÔ Ò"ð *ØÔ ð*àÔ"ð*ð Ô(¨4Ò/ð*ð Ô'¨$Ò.ð	*õ
 Ð>Ð> TÔ%=Ð>Ñ>Ô>Ñ>Ô>ð*õ �4Ô(Ñ)Ô)ð	
r    r   c                ó*   — | j         rdS | j        rdndS )zAHUD/debug: who owns catch-up math (`dollar`, `dime`, or `penny`).ÚdollarÚdimeÚpenny)r  r  r0  s    r   Úcatchup_modezOdometerEngine.catchup_modeó  s&   € ð Ôð 	Ø�8ØÔ*Ð7ˆvˆv°Ð7r    c                ó*   — t          | j        ¦  «        S r‰   )r   r	  r0  s    r   r/  zOdometerEngine._settled_centsú  s   € Ý�4Ô%Ñ&Ô&Ð&r    c                ó–   — t          | j        ¦  «        | j        z
  }|| j        j        k    rdS |                      | j        ¦  «         dS )NFT)r   r	  r  r  r2   r$  )r  Ú	overshoots     r   Úsnap_if_wonzOdometerEngine.snap_if_woný  sK   € Ý˜Ô*Ñ+Ô+¨dÔ.AÑAˆ	Ø˜œÔ3Ò3Ð3Ø�5Ø×+Ò+¨DÔ,?Ñ@Ô@Ð@Øˆtr    c                ót  — |                       ¦   «         }t          dt          | j        j        ¦  «        ¦  «        }t          dt          | j        j        ¦  «        ¦  «        }|dk    s||k    rdS t          d| j        |z
  ¦  «        }|                      ¦   «         |k    rdS |                      |¦  «         dS )zDIf lag exceeds threshold, jump display to a fixed lag behind target.r   FT)	r©   r   r   r  rO   rQ   r  r/  r$  )r  r¬   Ú	thresholdÚ
target_lagÚsnap_displays        r   r   z%OdometerEngine.snap_if_too_far_behind  s¯   € à×ÒÑ Ô ˆÝ˜�3˜tœ{ÔHÑIÔIÑJÔJˆ	Ý˜�C ¤Ô FÑGÔGÑHÔHˆ
Ø˜Š>ˆ>˜S IÒ-Ð-Ø�5Ý˜1˜dÔ1°JÑ>Ñ?Ô?ˆØ×ÒÑ Ô  LÒ0Ð0Ø�5Ø×+Ò+¨LÑ9Ô9Ð9Øˆtr    c                óˆ   — |                       ¦   «         dk    rdS t          j        ¦   «         | j        z
  | j        j        k     S )Nr   T)r©   r
  r  r  r  r>   r0  s    r   Ú_contributions_activez$OdometerEngine._contributions_active  sD   € Ø×ÒÑÔ Ò!Ð!Ø�4åÔÑÔ $Ô"?Ñ?ØŒKÔ-ò.ð 	.r    r    r(   c                óX   — |€|                       ¦   «         }|                      |¦  «        S r‰   )r©   ræ   ©r  r    s     r   Úpennies_per_secondz!OdometerEngine.pennies_per_second  s,   € Øˆ=Ø×$Ò$Ñ&Ô&ˆEØ×'Ò'¨Ñ.Ô.Ð.r    c                ó”  — |€|                       ¦   «         }|dk    rdS | j        s-| j        j        dk    r7|t	          | j        j        ¦  «        k    rt          | j        d¦  «        }d|z  S | j        s-| j        j        dk    r7|t	          | j        j        ¦  «        k    rt          | j	        d¦  «        }d|z  S t          |                      |¦  «        |                      |¦  «        ¦  «        }|                      ¦   «         }t          d|t          |                      ¦   «         ¦  «        z
  ¦  «        dz  }t          ||¦  «        S )Nr   rA   r›   g      Y@rá   g      N@)r©   r  r  rW   r   r   r  r  rT   r  r¢   ræ   Ú_chase_animation_capÚ_intermittent_display_ceilingr(   r/  )r  r    rë   rê   ÚceilÚheadrooms         r   Úeffective_pennies_per_secondz+OdometerEngine.effective_pennies_per_second  sA  € Øˆ=Ø×$Ò$Ñ&Ô&ˆEØ�AŠ:ˆ:Ø�3ØÔð 	 ØŒKÔ4°qÒ8Ð8Ø�˜Tœ[ÔEÑFÔFÒFÐFõ �tÔ5°tÑ<Ô<ˆDØ˜4‘<ÐØÔð 	ØŒKÔ2°QÒ6Ð6Ø�˜Tœ[ÔCÑDÔDÒDÐDõ �tÔ4°dÑ;Ô;ˆDØ˜$‘;ÐÝ�D×,Ò,¨UÑ3Ô3°T×5NÒ5NÈuÑ5UÔ5UÑVÔVˆØ×1Ò1Ñ3Ô3ˆÝ�s˜D¥5¨×)<Ò)<Ñ)>Ô)>Ñ#?Ô#?Ñ?Ñ@Ô@À4ÑGˆÝ�5˜(Ñ#Ô#Ð#r    c                ó
  — | j         }|dk    rdS |                      ¦   «         st          |j        ||j        z  ¦  «        S |j        rt          ||j        ¦  «        }n‰t          |j        d¦  «        }||k    r ||z  }|j        ||j        |j        z
  z  z   }nN|j        }t          |j	        |j        z
  d¦  «        }t          ||j        z
  |¦  «        }||z  }|||j        z  z   }t          dt          |j        ¦  «        ¦  «        }	||	z  }t          dt          |j        ¦  «        ¦  «        }
t          dt          |j        ¦  «        ¦  «        }|
dk    r+|dk    r%||
k    r|                      ¦   «         r|||
z
  |z  z  }|S )Nr   rA   rš   gš™™™™™©?)r  rF  r   r7   r<   rI   r¯   r3   r9   r2   r¢   r;   r(   rK   r   rM   rN   )r  r    r�   ru   Ú	penny_capr¥   Ú
penny_rateÚbandÚexcessÚscalerB  Úbonuss               r   ræ   z"OdometerEngine._pennies_per_second5  sœ  € ØŒkˆØ�AŠ:ˆ:Ø�3Ø×)Ò)Ñ+Ô+ð 	CÝ�s”| U¨SÔ-AÑ%AÑBÔBÐBØŒ>ð 	:Ý& u¨c¬nÑ=Ô=ˆDˆDå˜CÔ5°qÑ9Ô9ˆIØ˜	Ò!Ð!Ø˜IÑ%�Ø”| a¨3¬<¸#¼,Ñ+FÑ&GÑG��à œ\�
Ý˜3Ô.°Ô1JÑJÈAÑNÔN�Ý˜U SÔ%>Ñ>ÀÑEÔE�Ø˜T‘M�Ø! A¨Ô(9Ñ$9Ñ9�Ý�D�% Ô 4Ñ5Ô5Ñ6Ô6ˆØ�e‰|ˆÝ˜�3˜sÔ8Ñ9Ô9Ñ:Ô:ˆ	Ý�C�˜sÔ=Ñ>Ô>Ñ?Ô?ˆà˜ŠMˆMØ˜’	�	Ø˜	Ò!Ð!Ø×*Ò*Ñ,Ô,ð "ð �U˜YÑ&¨%Ñ/Ñ/ˆDØˆr    c           	     óŽ   — dt          t          t          d|¦  «        t          | j        ¦  «        ¦  «        | j        ¦  «        z  S )NrD   r   )r±   r¢   r   r—   r  rH  s     r   rK  z#OdometerEngine._chase_animation_capU  s@   € ØÕ+Ý•�A�u‘”Õ3°D´KÑ@Ô@ÑAÔAÀ4Ä;ñ
ô 
ñ 
ð 	
r    r	  r¨   c                ó   — d|z  }||z  |z  S ©Nr¿   rG   )r  r	  r¨   Úunits       r   Ú_column_fractionzOdometerEngine._column_fractionZ  s   € Ø�5‰yˆØ Ñ$¨Ñ,Ð,r    r   c                óª  — |€|                       ¦   «         nt          dt          |¦  «        ¦  «        }t          |¦  «        | _        d| _        d| _        t          | j        ¦  «        | _	        t          d| j        ¦  «        | _        t          d| j        ¦  «        | _        d| _        d| _        d | _        d | _        |                      ¦   «          d S r  )r/  r   r   r(   r	  r  r  r�   r  r  r¦   r  r»   r  r  r  r  r  Ú_clear_all_carry_scroll)r  r   r   s      r   r$  z-OdometerEngine._snap_display_to_settled_cents^  s¼   € Ø).¨�×#Ò#Ñ%Ô%Ð%½CÀÅ3ÀuÁ:Ä:Ñ<NÔ<NˆÝ" 5™\œ\ˆÔØ$'ˆÔ!Ø#&ˆÔ Ý"2°4´;Ñ"?Ô"?ˆÔÝ(>¸qÀ$Ä+Ñ(NÔ(NˆÔ%Ý)@ÀÀDÄKÑ)PÔ)PˆÔ&Ø!ˆÔØ#ˆÔØ%)ˆÔ"Ø$(ˆÔ!Ø×$Ò$Ñ&Ô&Ð&Ð&Ð&r    c                ó<  — |                       ¦   «         }t          | j        |z
  ¦  «        dk    rt          |¦  «        | _        |                      ¦   «         dk    r@d| _        d| _        d| _        d| _        d | _	        d | _
        |                      ¦   «          d S d S )Nç•Ö&è.>r   rA   F)r/  Úabsr	  r(   r©   r  r  r  r  r  r  r]  )r  Úsettleds     r   Ú_discard_sub_cent_slopz%OdometerEngine._discard_sub_cent_slopl  s£   € Ø×%Ò%Ñ'Ô'ˆÝˆtÔ! GÑ+Ñ,Ô,¨tÒ3Ð3Ý!& w¡¤ˆDÔØ×ÒÑÔ Ò"Ð"Ø(+ˆDÔ%Ø'*ˆDÔ$Ø %ˆDÔØ"'ˆDÔØ)-ˆDÔ&Ø(,ˆDÔ%Ø×(Ò(Ñ*Ô*Ð*Ð*Ð*ð #Ð"r    Údtc           	     óÐ  ‡ ‡‡— t          t          d‰                      ¦   «         ¦  «        t          t          ‰ j        ¦  «        d¦  «        ¦  «        }t          t          d‰                      ¦   «         ¦  «        t          t          ‰ j        ¦  «        d¦  «        ¦  «        }t          t          d‰                      ¦   «         ¦  «        t          t          ‰ j        ¦  «        d¦  «        ¦  «        }‰ j        s‰ j        rt          ‰ j        ¦  «        }nt          |‰ j        ¦  «        }‰ j        rt          ‰ j        ¦  «        }nt          |‰ j        ¦  «        }‰ j        rt          |‰ j        ¦  «        }n‰                      ¦   «         }t          ‰ j        j        d¦  «        }dt!          j        | |z  ¦  «        z
  Št          t%          t'          ‰ j        dd¦  «        pd¦  «        |d¦  «        }	dt!          j        | |	z  ¦  «        z
  Šdˆfd
„}
dˆˆ fd„} |
‰ j        |¦  «        ‰ _         |
‰ j        |¦  «        ‰ _         |‰ j        |¦  «        ‰ _        ‰ j        S )a  Smooth penny/carry/dollar roll durations toward lag-derived targets.

        One-sided for catch-up: acceleration (shorter roll = faster) is immediate
        so lag spikes do not ease into fast too late; deceleration eases over
        roll_smooth_tau so landing does not jerk.

        While dollar-driven: pennies+dimes maxed; dollars use dollar_roll_* and
        ease into faster rates (so enter always begins at dollar_roll_sec_min).
        While dime-driven only: pennies maxed; dimes use carry_roll_*.
        rš   r›   rD   r\   rA   Úcurrentr(   Útargetr   c                ó*   •— || k    r|S | || z
  ‰z  z   S r‰   rG   )re  rf  Úalphas     €r   Ú_snap_acceleratez9OdometerEngine._smooth_roll_sec.<locals>._snap_accelerate¢  s(   ø€ à˜Ò Ð Ø�Ø˜f wÑ.°%Ñ7Ñ7Ð7r    c                ó<   •— ‰j         s|S || k    r|S | || z
  ‰z  z   S r‰   )r  )re  rf  Údollar_alphar  s     €€r   Ú_ease_accelerate_dollarz@OdometerEngine._smooth_roll_sec.<locals>._ease_accelerate_dollar¨  s8   ø€ àÔ&ð Ø�Ø˜Ò Ð Ø�Ø˜f wÑ.°,Ñ>Ñ>Ð>r    )re  r(   rf  r(   r   r(   )r¢   r   r©   r—   r  rŸ   r¸   r  r  r³   r±   r¶   r¦   r»   Ú_dollar_roll_sec_slowrR   ÚmathÚexpr(   Úgetattrr  r  r  )r  rc  r¬   Ú	carry_lagÚ
dollar_lagÚpenny_targetÚcarry_targetÚdollar_targetÚtauÚ
dollar_tauri  rl  rh  rk  s   `           @@r   Ú_smooth_roll_seczOdometerEngine._smooth_roll_secy  s  øøø€ õ •#�a˜×)Ò)Ñ+Ô+Ñ,Ô,­cÕ2FÀtÄ{Ñ2SÔ2SÐUVÑ.WÔ.WÑXÔXˆÝÝ��4×#Ò#Ñ%Ô%Ñ&Ô&­Õ,@ÀÄÑ,MÔ,MÈqÑ(QÔ(Qñ
ô 
ˆ	õ Ý��4×#Ò#Ñ%Ô%Ñ&Ô&­Õ,AÀ$Ä+Ñ,NÔ,NÐPQÑ(RÔ(Rñ
ô 
ˆ
ð Ôð 	D $Ô"3ð 	DÝ0°´Ñ=Ô=ˆLˆLå1°#°t´{ÑCÔCˆLØÔð 	JÝ0°´Ñ=Ô=ˆLˆLå1°)¸T¼[ÑIÔIˆLð Ôð 	9Ý3°JÀÄÑLÔLˆMˆMà ×6Ò6Ñ8Ô8ˆMÝ�$”+Ô-¨tÑ4Ô4ˆØ•d”h ˜s S™yÑ)Ô)Ñ)ˆÝÝ•'˜$œ+Ð'?ÀÑEÔEÐLÈÑMÔMØØñ
ô 
ˆ
ð
 �TœX r c¨JÑ&6Ñ7Ô7Ñ7ˆð	8ð 	8ð 	8ð 	8ð 	8ð 	8ð	?ð 	?ð 	?ð 	?ð 	?ð 	?ð 	?ð #3Ð"2°4Ô3JÈLÑ"YÔ"YˆÔØ(8Ð(8ØÔ)¨<ñ)
ô )
ˆÔ%ð *AÐ)@ØÔ*¨Mñ*
ô *
ˆÔ&ð Ô&Ð&r    c                ó2   — |t          | j        d¦  «        z  S ©Nr›   )r   r  ©r  rc  s     r   Ú_penny_roll_stepzOdometerEngine._penny_roll_step¹  s   € Ø•C˜Ô/°Ñ6Ô6Ñ6Ð6r    c                ó2   — |t          | j        d¦  «        z  S rz  )r   r  r{  s     r   Ú_carry_roll_stepzOdometerEngine._carry_roll_step¼  s   € Ø•C˜Ô5°tÑ<Ô<Ñ<Ð<r    c                ó2   — |t          | j        d¦  «        z  S rz  )r   r  r{  s     r   Ú_dollar_roll_stepz OdometerEngine._dollar_roll_step¿  s   € Ø•C˜Ô6¸Ñ=Ô=Ñ=Ð=r    c                ó\   — |                       ¦   «         }| j        |z
  }|dk    o|dz  dk    S )Nr   r¿   é	   )r/  r  )r  ra  Úgaps      r   Ú_chase_needs_penny_carry_chainz-OdometerEngine._chase_needs_penny_carry_chainÂ  s8   € Ø×%Ò%Ñ'Ô'ˆØÔ! GÑ+ˆØ�QŠwÐ.˜G b™L¨QÒ.Ð.r    c                óÒ  — | j         rdS t          dt          | j        j        ¦  «        ¦  «        }|dk    r=| j        r4| j        d         dk    r#d| _        d| _        |                      d¦  «         dS t          dt          | j        j	        ¦  «        ¦  «        }||k    rt          d|dz  ¦  «        }|  
                    ¦   «         }| j        d         dk    }| j        sŒ||k    r„d| _        t          | j        ¦  «        | _        t          t          t          d|¦  «        t          | j        ¦  «        ¦  «        | j        ¦  «        | _        |                      ¦   «         dz  | _        dS |dz   }||k     rn|sn|                      ¦   «         dz  }| j        }|du p t          |¦  «        dz  |k    o
| j        dk    }|sdS d| _        d| _        |                      d¦  «         dS dS dS )	z7Enter/exit lag-gated dime-driven catch-up (hysteresis).Nr   rš   r›   Fr   Tr¿   )r  r   r   r  rT   r  r  r  Ú_clear_carry_scrollrV   r©   r³   r  r¦   r¢   rŸ   r  r/  r  )	r  ÚenterÚexit_lagr¬   Údime_inflightÚhandoffÚsettled_digitÚcosmeticÚaligneds	            r   Ú_update_dime_mode_statez&OdometerEngine._update_dime_mode_stateÇ  s  € ð Ôð 	ØˆFÝ�A•s˜4œ;ÔAÑBÔBÑCÔCˆØ�AŠ:ˆ:ØÔ ð , TÔ%=¸aÔ%@ÀDÒ%HÐ%HØ$)�Ô!Ø-1�Ô*Ø×(Ò(¨Ñ+Ô+Ð+ØˆFÝ�q�#˜dœkÔCÑDÔDÑEÔEˆØ�uÒÐÝ˜1˜e q™jÑ)Ô)ˆHØ×ÒÑ Ô ˆØÔ0°Ô3°dÒ:ˆØÔ ð 
	Ø�eŠ|ˆ|Ø$(�Ô!å*?ÀÄÑ*LÔ*L�Ô'Ý0FÝ�˜A˜s™œÕ%9¸$¼+Ñ%FÔ%FÑGÔGØ”Kñ1ô 1�Ô-ð .2×-@Ò-@Ñ-BÔ-BÀRÑ-G�Ô*ØˆFð ˜R‘-ˆØ�Š=ˆ= ˆ=Ø ×/Ò/Ñ1Ô1°BÑ6ˆMØÔ1ˆHØ $Ð&ð Ý�H‘” Ñ" mÒ3ð 6ØÔ-°Ò5ð ð ð Ø�Ø %ˆDÔØ)-ˆDÔ&Ø×$Ò$ QÑ'Ô'Ð'Ð'Ð'ð ˆ=ˆ=ˆ=r    c                óF   — t          | j        ¦  «        }| j        |dz   k    S )zBTrue when smoothed dime/carry period is at (or past) the fast end.gü©ñÒMbP?)r¶   r  r  )r  Úmaxeds     r   Ú_carry_roll_is_maxedz#OdometerEngine._carry_roll_is_maxedô  s#   € å% d¤kÑ2Ô2ˆØÔ,°¸±Ò<Ð<r    c                óx   — t          dt          ¦  «        D ]#}| j        |         dk    s| j        |         r dS Œ$dS )z<True while a dime roll or its dollar+ cascade is mid-scroll.rš   r›   TF©rÂ   rÃ   r  r  ©r  r¨   s     r   Ú_dime_catchup_columns_busyz)OdometerEngine._dime_catchup_columns_busyù  óL   € å˜1�kÑ*Ô*ð 	ð 	ˆEØÔ'¨Ô.°Ò5Ð5¸Ô9NÈuÔ9UÐ5Ø�t�tð 6àˆur    c                óx   — t          dt          ¦  «        D ]#}| j        |         dk    s| j        |         r dS Œ$dS )z<True while a dollar roll or its tens+ cascade is mid-scroll.r   r›   TFr“  r”  s     r   Ú_dollar_catchup_columns_busyz+OdometerEngine._dollar_catchup_columns_busy   r–  r    c                ó,   — t          d| j        ¦  «        S )zCPinned slow continuous dollar period (always >= maxed-dime visual).r   )r»   r  r0  s    r   rm  z$OdometerEngine._dollar_roll_sec_slow  s   € å& q¨$¬+Ñ6Ô6Ð6r    c                ó6  — t          dt          | j        j        ¦  «        ¦  «        }|dk    rG| j        r>|                      ¦   «         s*d| _        d| _        d| _        |                      d¦  «         dS t          |t          | j        ¦  «        dz   ¦  «        }t          dt          | j        j
        ¦  «        ¦  «        }||k    rt          d|dz  ¦  «        }|                      ¦   «         }| j        sì||k    rä| j        rÝ|                      ¦   «         rÉ|                      ¦   «         sµd| _        d| _        t          | j        ¦  «        | _        t#          | j        ¦  «        | _        |                      ¦   «         | _        |                      ¦   «         }|dz  | _        |dz  dz  | _        d| _        |                      d¦  «         |                      d¦  «         dS |d	z   }||k     �r*|                      ¦   «         �s|                      ¦   «         dz  dz  }| j        }|du p t          |¦  «        dz  |k    o
| j        d
k    }|sdS d| _        d| _        d| _        t/          dt0          ¦  «        D ]}	|                      |	¦  «         Œd| _        t3          t5          t          d|¦  «        t          | j        ¦  «        ¦  «        | j        ¦  «        | _        | j        €|                      ¦   «         dz  | _        |                      d¦  «         dS dS dS )z9Enter/exit lag-gated dollar-driven catch-up (hysteresis).r   FNrA   r   rš   Tr¿   r   r›   )r   r   r  rW   r  r˜  r  r  r†  rŸ   rX   r©   r  r‘  r•  r³   r  r¶   r  rm  r  r/  r  rÂ   rÃ   r¦   r¢   )
r  r‡  rˆ  r¬   ra  rŠ  Úsettled_dimerŒ  r�  r¨   s
             r   Ú_update_dollar_mode_statez(OdometerEngine._update_dollar_mode_state  s1  € å�A•s˜4œ;ÔCÑDÔDÑEÔEˆØ�AŠ:ˆ:ØÔ"ð ,¨4×+LÒ+LÑ+NÔ+Nð ,Ø&+�Ô#Ø,0�Ô)Ø+.�Ô(Ø×(Ò(¨Ñ+Ô+Ð+ØˆFå�EÕ/°´Ñ<Ô<¸qÑ@ÑAÔAˆÝ�q�#˜dœkÔEÑFÔFÑGÔGˆØ�uÒÐÝ˜1˜e q™jÑ)Ô)ˆHØ×ÒÑ Ô ˆØÔ"ð 	à�u’�ØÔ%ð à×-Ò-Ñ/Ô/ð ð ×7Ò7Ñ9Ô9ð ð
 '+�Ô#à$(�Ô!Ý*?ÀÄÑ*LÔ*L�Ô'Ý0EÀdÄkÑ0RÔ0R�Ô-à15×1KÒ1KÑ1MÔ1M�Ô.Ø×-Ò-Ñ/Ô/�Ø-4°r©\�Ô*Ø-4¸©]¸bÑ,@�Ô)Ø+.�Ô(à×(Ò(¨Ñ+Ô+Ð+Ø×(Ò(¨Ñ+Ô+Ð+ØˆFð ˜S‘.ˆØ�Š=‰= ×!BÒ!BÑ!DÔ!D‰=Ø ×/Ò/Ñ1Ô1°RÑ7¸2Ñ=ˆLØÔ0ˆHØ $Ð&ð Ý�H‘” Ñ" lÒ2ð 5ØÔ,°Ò4ð ð ð Ø�Ø"'ˆDÔØ(,ˆDÔ%Ø'*ˆDÔ$å˜q¥+Ñ.Ô.ð 0ð 0�Ø×(Ò(¨Ñ/Ô/Ð/Ð/à $ˆDÔÝ,BÝ•C˜˜3‘K”KÕ!5°d´kÑ!BÔ!BÑCÔCØ”ñ-ô -ˆDÔ)ð Ô)Ð1Ø-1×-@Ò-@Ñ-BÔ-BÀRÑ-G�Ô*à×$Ò$ QÑ'Ô'Ð'Ð'Ð'ð1 ˆ=ˆ=ˆ=r    c                ó6  — | j         €|                      ¦   «         dz  | _         |t          t          | j        ¦  «        d¦  «        z  }t          d| j        |z   ¦  «        | _        | j        dk    r(d| _        t          | j         ¦  «        dz   dz  | _         dS dS )zLFree-spin pennies 0-9 at maxed penny rate (independent of dime/dollar roll).Nr¿   r›   rD   ç¡�vÿÿÿï?rA   rš   )r  r/  r   r³   r  r¢   r  r   ©r  rc  Ústeps      r   Ú_chase_penny_cosmeticz$OdometerEngine._chase_penny_cosmeticM  sŸ   € àÔ%Ð-Ø)-×)<Ò)<Ñ)>Ô)>ÀÑ)CˆDÔ&à•CÕ-¨d¬kÑ:Ô:¸DÑAÔAÑAˆÝ$'¨¨TÔ-FÈÑ-MÑ$NÔ$NˆÔ!ØÔ$¨
Ò2Ð2Ø(+ˆDÔ%Ý*-¨dÔ.HÑ*IÔ*IÈAÑ*MÐQSÑ)SˆDÔ&Ð&Ð&ð 3Ð2r    c                ó<  — | j         €|                      ¦   «         dz  dz  | _         |t          t          | j        ¦  «        d¦  «        z  }t          d| j        |z   ¦  «        | _        | j        dk    r(d| _        t          | j         ¦  «        dz   dz  | _         dS dS )z<Free-spin dimes 0-9 at maxed carry rate while dollars drive.Nr¿   r›   rD   rž  rA   rš   )r  r/  r   r¶   r  r¢   r  r   rŸ  s      r   Ú_chase_dime_cosmeticz#OdometerEngine._chase_dime_cosmeticX  s£   € àÔ$Ð,Ø)-×)<Ò)<Ñ)>Ô)>À"Ñ)DÈÑ(JˆDÔ%Ø•CÕ-¨d¬kÑ:Ô:¸DÑAÔAÑAˆÝ#& s¨DÔ,DÀtÑ,KÑ#LÔ#LˆÔ ØÔ# zÒ1Ð1Ø'*ˆDÔ$Ý),¨TÔ-FÑ)GÔ)GÈ!Ñ)KÈrÑ(QˆDÔ%Ð%Ð%ð 2Ð1r    ra  c                ó~   — |€|                       ¦   «         nt          dt          |¦  «        ¦  «        }|dz  dz  dz   S )Nr   r¿   ©r/  r   r   ©r  ra  r   s      r   Ú_next_dime_boundaryz"OdometerEngine._next_dime_boundaryb  s@   € Ø)0¨�×#Ò#Ñ%Ô%Ð%½cÀ!ÅSÈÁ\Ä\Ñ>RÔ>RˆØ˜‘˜rÑ! BÑ&Ð&r    c                ó~   — |€|                       ¦   «         nt          dt          |¦  «        ¦  «        }|dz  dz  dz   S )Nr   r   r¥  r¦  s      r   Ú_next_dollar_boundaryz$OdometerEngine._next_dollar_boundaryf  s@   € Ø)0¨�×#Ò#Ñ%Ô%Ð%½cÀ!ÅSÈÁ\Ä\Ñ>RÔ>RˆØ˜‘ Ñ# cÑ)Ð)r    ÚbeforeÚafterc                óœ   — d|z  }t          dt          | ¦  «        ¦  «        |z  dz  t          dt          |¦  «        ¦  «        |z  dz  k    S )zLTrue when this decimal column's glyph changes between two whole-cent values.r¿   r   r   )rª  r«  r¨   rZ  s       r   Ú_digit_changes_crossingz&OdometerEngine._digit_changes_crossingj  sM   € ð �5‰yˆÝ�Q�˜F™œÑ$Ô$¨Ñ,°Ñ2½¸QÅÀEÁ
Ä
Ñ9KÔ9KÈtÑ9SÐWYÑ8YÒZÐZr    r¼   c                ó  ‡ ‡‡— |€‰                       ¦   «         nt          dt          |¦  «        ¦  «        Št          ‰                      ‰¦  «        ‰ j        ¦  «        Š‰‰k    rg S ˆˆ ˆfd„t          dt          ¦  «        D ¦   «         S )uG   Dollar+ powers whose digits wrap when the next independent +10Â¢ lands.Nr   c                óB   •— g | ]}‰                      ‰‰|¦  «        ¯|‘ŒS rG   ©r­  ©r’   r¨   Únxtr  r   s     €€€r   rÁ   zCOdometerEngine._powers_scrolling_with_next_dime.<locals>.<listcomp>v  óA   ø€ ð 
ð 
ð 
àØ×+Ò+¨E°3¸Ñ>Ô>ð
Øð
ð 
ð 
r    r   )r/  r   r   r¢   r§  r  rÂ   rÃ   ©r  ra  r²  r   s   ` @@r   Ú _powers_scrolling_with_next_dimez/OdometerEngine._powers_scrolling_with_next_dimep  sœ   øøø€ à)0¨�×#Ò#Ñ%Ô%Ð%½cÀ!ÅSÈÁ\Ä\Ñ>RÔ>RˆÝ�$×*Ò*¨5Ñ1Ô1°4Ô3FÑGÔGˆØ�%Š<ˆ<ØˆIð
ð 
ð 
ð 
ð 
ð 
å˜q¥+Ñ.Ô.ð
ñ 
ô 
ð 	
r    c                ó  ‡ ‡‡— |€‰                       ¦   «         nt          dt          |¦  «        ¦  «        Št          ‰                      ‰¦  «        ‰ j        ¦  «        Š‰‰k    rg S ˆˆ ˆfd„t          dt          ¦  «        D ¦   «         S )zCTens+ powers whose digits wrap when the next independent +$1 lands.Nr   c                óB   •— g | ]}‰                      ‰‰|¦  «        ¯|‘ŒS rG   r°  r±  s     €€€r   rÁ   zEOdometerEngine._powers_scrolling_with_next_dollar.<locals>.<listcomp>‚  r³  r    é   )r/  r   r   r¢   r©  r  rÂ   rÃ   r´  s   ` @@r   Ú"_powers_scrolling_with_next_dollarz1OdometerEngine._powers_scrolling_with_next_dollar|  sœ   øøø€ à)0¨�×#Ò#Ñ%Ô%Ð%½cÀ!ÅSÈÁ\Ä\Ñ>RÔ>RˆÝ�$×,Ò,¨UÑ3Ô3°TÔ5HÑIÔIˆØ�%Š<ˆ<ØˆIð
ð 
ð 
ð 
ð 
ð 
å˜q¥+Ñ.Ô.ð
ñ 
ô 
ð 	
r    c                ó`   — |                       ¦   «         D ]}| j        |         }|dk     r dS ŒdS )zNTrue while a dollar+ cascade for the pending next-dime boundary is unfinished.rž  TF)rµ  r  ©r  r¨   Úphases      r   Ú%_higher_columns_pending_for_next_dimez4OdometerEngine._higher_columns_pending_for_next_dimeˆ  sF   € à×:Ò:Ñ<Ô<ð 	ð 	ˆEØÔ,¨UÔ3ˆEØ�zÒ!Ð!Ø�t�tð "àˆur    c                ó`   — |                       ¦   «         D ]}| j        |         }|dk     r dS ŒdS )zNTrue while a tens+ cascade for the pending next-dollar boundary is unfinished.rž  TF)r¹  r  r»  s      r   Ú'_higher_columns_pending_for_next_dollarz6OdometerEngine._higher_columns_pending_for_next_dollar�  sF   € à×<Ò<Ñ>Ô>ð 	ð 	ˆEØÔ,¨UÔ3ˆEØ�zÒ!Ð!Ø�t�tð "àˆur    c                óÆ   — |                       d¦  «         t          dt          ¦  «        D ]5}| j        |         dk    s| j        |         r|                       |¦  «         Œ6dS )uF   Clear dimes + any dollar+ phases that ride the independent +10Â¢ land.rš   r   r›   N©r†  rÂ   rÃ   r  r  r”  s     r   Ú_clear_dime_cascade_columnsz*OdometerEngine._clear_dime_cascade_columns˜  ón   € à× Ò  Ñ#Ô#Ð#Ý˜1�kÑ*Ô*ð 	0ð 	0ˆEØÔ'¨Ô.°Ò5Ð5¸Ô9NÈuÔ9UÐ5Ø×(Ò(¨Ñ/Ô/Ð/øð	0ð 	0r    c                óÆ   — |                       d¦  «         t          dt          ¦  «        D ]5}| j        |         dk    s| j        |         r|                       |¦  «         Œ6dS )zDClear dollars + any tens+ phases that ride the independent +$1 land.r   r¸  r›   NrÁ  r”  s     r   Ú_clear_dollar_cascade_columnsz,OdometerEngine._clear_dollar_cascade_columnsŸ  rÃ  r    c                óê   — |                       ¦   «         }|                      |¦  «        }|| j        k    r|                      ¦   «          dS t	          |¦  «        | _        |                      ¦   «          dS )zOComplete a decoupled dime roll: next dime boundary only (never snap to target).N)r/  r§  r  rÂ  r(   r	  )r  ra  Ú	next_dimes      r   Ú_land_independent_dimez%OdometerEngine._land_independent_dime¦  ss   € à×%Ò%Ñ'Ô'ˆØ×,Ò,¨WÑ5Ô5ˆ	Ø�tÔ*Ò*Ð*à×,Ò,Ñ.Ô.Ð.ØˆFÝ" 9Ñ-Ô-ˆÔà×(Ò(Ñ*Ô*Ð*Ð*Ð*r    c                óê   — |                       ¦   «         }|                      |¦  «        }|| j        k    r|                      ¦   «          dS t	          |¦  «        | _        |                      ¦   «          dS )zOComplete a decoupled dollar roll: next $1 boundary only (never snap to target).N)r/  r©  r  rÅ  r(   r	  )r  ra  Únext_dollars      r   Ú_land_independent_dollarz'OdometerEngine._land_independent_dollar²  ss   € à×%Ò%Ñ'Ô'ˆØ×0Ò0°Ñ9Ô9ˆØ˜Ô,Ò,Ð,Ø×.Ò.Ñ0Ô0Ð0ØˆFÝ" ;Ñ/Ô/ˆÔà×*Ò*Ñ,Ô,Ð,Ð,Ð,r    c                ó.  — |                       |¦  «         |                      ¦   «         }| j        |z
  }| j        d         }|                      |¦  «        }t          dt          | j        j        ¦  «        ¦  «        }t          d|dz   ¦  «        }|dk    rF||k     rdS |dz  dz  | j	        d<   d| j
        d<   d| j        d<   t          d|¦  «        | j        d<   dS |dk     r|                      ¦   «          dS t          d||z   ¦  «        }|| j        d<   dS )	uñ   Dimes own +10Â¢ on their own schedule; pennies are cosmetic only.

        When the next +10Â¢ changes dollars (and higher), those columns scroll in
        sync via ``_update_intermittent_scroll`` â€” do not land until they finish.
        rš   r   r¿   r›   NTFrD   )r¡  r/  r  r  r~  r   r   r  rV   r  r  r  r¢   rÂ  ©r  rc  ra  rƒ  r¼  r   rˆ  Úmin_gap_to_starts           r   Ú_update_dime_driven_catchupz*OdometerEngine._update_dime_driven_catchup½  s2  € ð 	×"Ò" 2Ñ&Ô&Ð&Ø×%Ò%Ñ'Ô'ˆØÔ! GÑ+ˆØÔ(¨Ô+ˆØ×$Ò$ RÑ(Ô(ˆÝ�q�#˜dœkÔCÑDÔDÑEÔEˆõ ˜r 8¨b¡=Ñ1Ô1ÐØ�DŠ=ˆ=ØÐ%Ò%Ð%Ø�Ø)0°B©¸"Ñ(<ˆDÔ" 1Ñ%Ø$(ˆDÔ˜qÑ!Ø',ˆDÔ! !Ñ$Ý*-¨c°4©.¬.ˆDÔ$ QÑ'ØˆFØ�Š8ˆ8à×,Ò,Ñ.Ô.Ð.ØˆFÝ�C˜ ™Ñ&Ô&ˆØ&+ˆÔ  Ñ#Ð#Ð#r    c                óX  — |                       |¦  «         |                      |¦  «         |                      ¦   «         }| j        |z
  }| j        d         }|                      |¦  «        }t          dt          | j        j	        ¦  «        ¦  «        }t          d|dz   ¦  «        }|dk    rF||k     rdS |dz  dz  | j
        d<   d| j        d<   d| j        d<   t          d	|¦  «        | j        d<   dS |dk     r|                      ¦   «          dS t          d	||z   ¦  «        }|| j        d<   dS )
uò   Dollars own +$1 on their own schedule; pennies+dimes are cosmetic only.

        When the next +$1 changes tens (and higher), those columns scroll in
        sync via ``_update_intermittent_scroll`` â€” do not land until they finish.
        r   r   r   r›   Nr¿   TFrD   )r¡  r£  r/  r  r  r€  r   r   r  rX   r  r  r  r¢   rÅ  rÍ  s           r   Ú_update_dollar_driven_catchupz,OdometerEngine._update_dollar_driven_catchupÜ  sD  € ð 	×"Ò" 2Ñ&Ô&Ð&Ø×!Ò! "Ñ%Ô%Ð%Ø×%Ò%Ñ'Ô'ˆØÔ! GÑ+ˆØÔ(¨Ô+ˆØ×%Ò% bÑ)Ô)ˆÝ�q�#˜dœkÔEÑFÔFÑGÔGˆÝ˜s H¨s¡NÑ3Ô3ÐØ�DŠ=ˆ=ØÐ%Ò%Ð%Ø�Ø)0°C©¸2Ñ(=ˆDÔ" 1Ñ%Ø$(ˆDÔ˜qÑ!Ø',ˆDÔ! !Ñ$Ý*-¨c°4©.¬.ˆDÔ$ QÑ'ØˆFØ�Š9ˆ9Ø×.Ò.Ñ0Ô0Ð0ØˆFÝ�C˜ ™Ñ&Ô&ˆØ&+ˆÔ  Ñ#Ð#Ð#r    c                ó    — | j         r| j        rdS | j        d         dk     rdS |                      ¦   «         rdS |                      ¦   «          dS )uG   Apply +10Â¢ land when dime roll is complete and higher digits finished.Nrš   rž  )r  r  r  r½  rÈ  r0  s    r   Ú_try_land_independent_dimez)OdometerEngine._try_land_independent_dimeø  se   € àÔ ð 	 DÔ$7ð 	ØˆFØÔ# AÔ&¨Ò3Ð3ØˆFØ×5Ò5Ñ7Ô7ð 	ØˆFØ×#Ò#Ñ%Ô%Ð%Ð%Ð%r    c                ó’   — | j         sdS | j        d         dk     rdS |                      ¦   «         rdS |                      ¦   «          dS )zGApply +$1 land when dollar roll is complete and higher digits finished.Nr   rž  )r  r  r¿  rË  r0  s    r   Ú_try_land_independent_dollarz+OdometerEngine._try_land_independent_dollar  s[   € àÔ"ð 	ØˆFØÔ# AÔ&¨Ò3Ð3ØˆFØ×7Ò7Ñ9Ô9ð 	ØˆFØ×%Ò%Ñ'Ô'Ð'Ð'Ð'r    c                óT  — |                       ¦   «         }| j        |k    rd S |                      ¦   «         rd S |                      |¦  «        }t	          d| j        |z   ¦  «        | _        | j        dk    r3d| _        t          t	          |dz   | j        ¦  «        ¦  «        | _        d S d S )NrD   rž  rA   rš   )r/  r  r„  r|  r¢   r  r(   r	  ©r  rc  ra  r   s       r   Ú_chase_cent_upzOdometerEngine._chase_cent_up  s³   € Ø×%Ò%Ñ'Ô'ˆØÔ 'Ò)Ð)ØˆFØ×.Ò.Ñ0Ô0ð 	ð ˆFØ×$Ò$ RÑ(Ô(ˆÝ$'¨¨TÔ-FÈÑ-MÑ$NÔ$NˆÔ!ØÔ$¨
Ò2Ð2Ø(+ˆDÔ%Ý!&¥s¨7°Q©;¸Ô8KÑ'LÔ'LÑ!MÔ!MˆDÔÐÐð 3Ð2r    c                ó¦   — | j         s| j        rdS |                      ¦   «         sdS | j        d         }|dk    rt	          d|¦  «        | _        dS dS )uA   Keep penny 9â†’0 glyph locked to the driving carry cascade phase.Nrš   r›   rD   )r  r  r„  r  r¢   r  )r  r¼  s     r   Ú!_sync_penny_scroll_to_carry_chainz0OdometerEngine._sync_penny_scroll_to_carry_chain  sh   € àÔð 	 Ô 3ð 	ØˆFØ×2Ò2Ñ4Ô4ð 	ØˆFØÔ(¨Ô+ˆØ�4Š<ˆ<Ý(+¨C°©¬ˆDÔ%Ð%Ð%ð ˆ<r    c                ó’  — |                       ¦   «         }|| j        k    rd S |                      |¦  «        }| j        dk    r[t	          d| j        |z
  ¦  «        | _        | j        dk    r1d| _        t          t	          |dz
  | j        ¦  «        ¦  «        | _        d S t          t	          |dz
  | j        ¦  «        ¦  «        | _        d S )Nr›   rA   r_  rš   )r/  r  r|  r  r   r(   r	  r×  s       r   Ú_chase_cent_downzOdometerEngine._chase_cent_down"  sÄ   € Ø×%Ò%Ñ'Ô'ˆØ�dÔ)Ò)Ð)ØˆFØ×$Ò$ RÑ(Ô(ˆØÔ$ tÒ+Ð+Ý(+¨C°Ô1JÈTÑ1QÑ(RÔ(RˆDÔ%ØÔ(¨DÒ0Ð0Ø,/�Ô)Ý%*­3¨w¸©{¸DÔ<OÑ+PÔ+PÑ%QÔ%Q�Ô"ØˆFÝ"¥3 w°¡{°DÔ4GÑ#HÔ#HÑIÔIˆÔÐÐr    c                óü  — |dk    rd S |                       ¦   «          |                      ¦   «          |                      ¦   «          |                      ¦   «          |                      |¦  «         |                      ¦   «         }| j        |k    rÔ| j        rB|                      |¦  «         |  	                    |d¬¦  «         |  
                    ¦   «          d S | j        rB|                      |¦  «         |  	                    |d¬¦  «         |                      ¦   «          d S |                      |¦  «         |  	                    |d¬¦  «         |                      ¦   «          d S | j        |k     red| _        d| _        d | _        d | _        d| _        |                      |¦  «         |                      ¦   «          |  	                    |d¬¦  «         d S |                      ¦   «          |  	                    |d¬¦  «         d S )Nr   r¸  )Ú	min_powerr   rš   FrA   )r@  r   rŽ  rœ  rx  r/  r  r  rÑ  Ú_update_intermittent_scrollrÕ  r  rÏ  rÓ  rØ  rÚ  r  r  r  rÜ  Ú$_sync_intermittent_phases_to_displayrb  )r  rc  ra  s      r   r{   zOdometerEngine.update/  s  € Ø�Š7ˆ7ØˆFØ×ÒÑÔÐØ×#Ò#Ñ%Ô%Ð%Ø×$Ò$Ñ&Ô&Ð&Ø×&Ò&Ñ(Ô(Ð(Ø×Ò˜bÑ!Ô!Ð!Ø×%Ò%Ñ'Ô'ˆØÔ Ò(Ð(ØÔ"ð 9Ø×2Ò2°2Ñ6Ô6Ð6Ø×0Ò0°¸qÐ0ÑAÔAÐAØ×1Ò1Ñ3Ô3Ð3Ð3Ð3ØÔ"ð 	9ð ×0Ò0°Ñ4Ô4Ð4Ø×0Ò0°¸qÐ0ÑAÔAÐAØ×/Ò/Ñ1Ô1Ð1Ð1Ð1à×#Ò# BÑ'Ô'Ð'Ø×0Ò0°¸qÐ0ÑAÔAÐAØ×6Ò6Ñ8Ô8Ð8Ð8Ð8ØÔ  7Ò*Ð*Ø %ˆDÔØ"'ˆDÔØ)-ˆDÔ&Ø(,ˆDÔ%Ø'*ˆDÔ$Ø×!Ò! "Ñ%Ô%Ð%Ø×5Ò5Ñ7Ô7Ð7Ø×,Ò,¨R¸1Ð,Ñ=Ô=Ð=Ð=Ð=à×'Ò'Ñ)Ô)Ð)Ø×,Ò,¨R¸1Ð,Ñ=Ô=Ð=Ð=Ð=r    c                óV   — d| j         |<   d| j        |<   d | j        |<   d| j        |<   d S )NrA   F)r  r  r  r  r”  s     r   r†  z"OdometerEngine._clear_carry_scrollT  s<   € Ø*-ˆÔ  Ñ'Ø',ˆÔ˜eÑ$Ø(,ˆÔ˜uÑ%Ø$)ˆÔ˜5Ñ!Ð!Ð!r    c                ó^   — t          t          ¦  «        D ]}|                      |¦  «         Œd S r‰   )rÂ   rÃ   r†  r”  s     r   r]  z&OdometerEngine._clear_all_carry_scrollZ  s:   € Ý�;Ñ'Ô'ð 	,ð 	,ˆEØ×$Ò$ UÑ+Ô+Ð+Ð+ð	,ð 	,r    c                ó2  — | j         }t          dt          ¦  «        D ]y}| j        |         }|dk    rŒ|                      |¦  «        r|                      |¦  «        }n%| j        |         r|                      ||¦  «        }nŒf||dz   k    r
|| j        |<   Œzd S )Nrš   r›   )r	  rÂ   rÃ   r  Ú_column_cascade_activeÚ_intermittent_scroll_targetr  r[  )r  Údfr¨   r¼  rf  s        r   rà  z3OdometerEngine._sync_intermittent_phases_to_display^  s¸   € ØÔˆÝ˜1�kÑ*Ô*ð 	9ð 	9ˆEØÔ,¨UÔ3ˆEØ˜Š}ˆ}ØØ×*Ò*¨5Ñ1Ô1ð Ø×9Ò9¸%Ñ@Ô@��ØÔ& uÔ-ð Ø×.Ò.¨r°5Ñ9Ô9��àØ�v ‘}Ò$Ð$Ø28�Ô(¨Ñ/øð	9ð 	9r    Úsettled_centsc                ó   — | d|z  z  dz  S rY  rG   )rç  r¨   s     r   Ú_digit_at_powerzOdometerEngine._digit_at_powerm  s   € à " e¡)Ñ,°Ñ2Ð2r    c                ó2   — |                       ¦   «         dk    S r«   )r©   r0  s    r   Ú_display_is_chasingz"OdometerEngine._display_is_chasingq  s   € Ø×ÒÑ!Ô! AÒ%Ð%r    c                óN   — | j         |         }|dk    r|dk     p| j        |         S )Nr›   rž  )r  r  r»  s      r   Ú_carry_roll_in_progressz&OdometerEngine._carry_roll_in_progresst  s0   € ØÔ(¨Ô/ˆØ˜’Ð3 ¨Ò!3ÐT¸Ô8MÈeÔ8TÐTr    c                óz  — |dk    rdS |dk    r	| j         rdS |dk    r| j        s| j         rdS |                      |¦  «        rdS |                      ¦   «         sdS |                      ¦   «         }|dk    r|                      |d¦  «        S | j         rZ| j        d         dk    rdS t          |                      |¦  «        | j	        ¦  «        }||k    rdS |  
                    |||¦  «        S | j        rZ| j        d         dk    rdS t          |                      |¦  «        | j	        ¦  «        }||k    rdS |  
                    |||¦  «        S |                      ||¦  «        sdS |                      ||¦  «        dk    rdS |dz
  }|                      |¦  «        p!| j        |         p|                      |¦  «        S )Nr   Fr   rš   Tr›   r‚  )r  r  rí  rë  r/  Ú_column_in_carryr  r¢   r©  r  r­  r§  ré  r  rä  )r  r¨   ra  r²  Úlowers        r   rä  z%OdometerEngine._column_cascade_activex  sÿ  € Ø�AŠ:ˆ:Ø�5à�AŠ:ˆ:˜$Ô-ˆ:Ø�5à�AŠ:ˆ:˜4Ô,ˆ:°Ô0Cˆ:Ø�5Ø×'Ò'¨Ñ.Ô.ð 	Ø�4Ø×'Ò'Ñ)Ô)ð 	Ø�5Ø×%Ò%Ñ'Ô'ˆØ�AŠ:ˆ:Ø×(Ò(¨°!Ñ4Ô4Ð4ð Ôð 	EØÔ'¨Ô*¨dÒ2Ð2Ø�uÝ�d×0Ò0°Ñ9Ô9¸4Ô;NÑOÔOˆCØ�gŠ~ˆ~Ø�uØ×/Ò/°¸¸eÑDÔDÐDð Ôð 	EØÔ'¨Ô*¨dÒ2Ð2Ø�uÝ�d×.Ò.¨wÑ7Ô7¸Ô9LÑMÔMˆCØ�gŠ~ˆ~Ø�uØ×/Ò/°¸¸eÑDÔDÐDØ×$Ò$ W¨eÑ4Ô4ð 	Ø�5Ø×Ò ¨Ñ/Ô/°1Ò4Ð4Ø�4Ø˜‘	ˆà×(Ò(¨Ñ/Ô/ð 2ØÔ$ UÔ+ð2à×*Ò*¨5Ñ1Ô1ð	
r    c                ó4   — |                       |¦  «        sdS dS )NrA   rD   )rä  r”  s     r   rå  z*OdometerEngine._intermittent_scroll_target¥  s"   € Ø×*Ò*¨5Ñ1Ô1ð 	Ø�3Øˆsr    c                óf   — d|z  }t          | ¦  «        |z  |z  }t          ||z   dz
  ¦  «        dz   S )Nr¿   rš   gé!çýÿï?)r   r(   )r	  r¨   rZ  Útails       r   Ú_carry_window_capz OdometerEngine._carry_window_capª  s=   € à�5‰yˆÝ�MÑ"Ô" dÑ*¨dÑ2ˆÝ�T˜D‘[ 1‘_Ñ%Ô%¨Ñ0Ð0r    úOptional[float]c                óv  — | j         s| j        rd S g }t          dt          ¦  «        D ]}|                      |¦  «        r*|                     |                      ||¦  «        ¦  «         ŒA|                      |¦  «        r)|                     |                      ||¦  «        ¦  «         Œ€|sd S t          |¦  «        S ©Nrš   )	r  r  rÂ   rÃ   rí  rç   rô  rä  r¢   )r  r	  Úcapsr¨   s       r   Ú_carry_display_hold_capz&OdometerEngine._carry_display_hold_cap°  sË   € àÔð 	 Ô 3ð 	Ø�4ØˆÝ˜1�kÑ*Ô*ð 	Jð 	JˆEØ×+Ò+¨EÑ2Ô2ð JØ—’˜D×2Ò2°=À%ÑHÔHÑIÔIÐIÐIØ×,Ò,¨UÑ3Ô3ð JØ—’˜D×2Ò2°=À%ÑHÔHÑIÔIÐIøØð 	Ø�4Ý�4‰yŒyÐr    c                óÚ  — t          |dz   t          ¦  «        D ]'}|                      |¦  «        s| j        |         r d S Œ(|                      ¦   «         }|| j        k    rd S | j        |z
  }|dk    r%|dz  dk    r|                      | j        ¦  «         d S d|z  }||z  |dz
  k     rd S t          ||z  |z  |z   | j        ¦  «        }||k    rt          |¦  «        | _	        d| _
        d S d S )Nrš   r¿   r‚  rA   )rÂ   rÃ   rí  r  r/  r  r$  r¢   r(   r	  r  )r  r¨   Úhigherra  rƒ  rZ  Úbumpeds          r   Ú_bump_display_after_carryz(OdometerEngine._bump_display_after_carry¾  s$  € Ý˜E A™I¥{Ñ3Ô3ð 	ð 	ˆFØ×+Ò+¨FÑ3Ô3ð °tÔ7LÈVÔ7Tð Ø��ðà×%Ò%Ñ'Ô'ˆØ�dÔ)Ò)Ð)ØˆFØÔ! GÑ+ˆØ�!Š8ˆ8˜ 2™¨!Ò+Ð+Ø×/Ò/°Ô0CÑDÔDÐDØˆFØ�5‰yˆØ�d‰N˜d Q™hÒ&Ð&ØˆFÝ�g ‘o¨Ñ-°Ñ4°dÔ6IÑJÔJˆØ�GÒÐÝ!& v¡¤ˆDÔØ(+ˆDÔ%Ð%Ð%ð Ðr    c                ó†   — t          | j        ¦  «        }|                      | j        ¦  «        }|�t	          ||¦  «        }|S r‰   )r(   r  rù  r	  r¢   )r  Úceilingr¤   s      r   rL  z,OdometerEngine._intermittent_display_ceilingÑ  sA   € Ý˜Ô+Ñ,Ô,ˆØ×*Ò*¨4Ô+=Ñ>Ô>ˆØˆ?Ý˜' 3Ñ'Ô'ˆGØˆr    rš   rÞ  c                óÖ  — |dk    rd S t          dt          |¦  «        ¦  «        }| j        r(| j        s!t	          |                      ¦   «         ¦  «        nt	          ¦   «         }| j        r!t	          |                      ¦   «         ¦  «        nt	          ¦   «         }t          |t          ¦  «        D �]9}|  	                    ¦   «         d|z  z  dz  }| j
        |         }| j        r|dk    r|t          | j        d¦  «        z  }	nS| j        s4| j        s-|                      ¦   «         r|t          | j        d¦  «        z  }	n|t          | j        d¦  «        z  }	|dk    rX| j        r||v rd| j
        |<   ŒÂ| j        r||v rd| j
        |<   ŒØ|                      |¦  «         |                      |¦  «         �Œ|                      |¦  «        }
| j        |         }|
rX|s
|| j        |<   d| j        |<   d	| j        |<   |                      |¦  «        }||k    rt-          |||	z   ¦  «        | j
        |<   �Œ€d	| j        |<   |dk    r”| j        |         �‡d| j        |<   t-          d||	z   ¦  «        }|| j
        |<   |dk    rX| j        r||v rd| j
        |<   �Œá| j        r||v rd| j
        |<   �Œø|                      |¦  «         |                      |¦  «         �Œ$|                      |¦  «         �Œ;d S )
Nr   rš   r¿   r¸  r›   rž  rD   TF)r   r   r  r  Úsetrµ  r¹  rÂ   rÃ   r/  r  r  r„  r  r  r†  rý  rä  r  r  r  rå  r¢   )r  rc  rÞ  r  Úpending_dime_powersÚpending_dollar_powersr¨   ra  r¼  r   Ú	cascadingÚwas_inrf  s                r   rß  z*OdometerEngine._update_intermittent_scrollØ  ss  € Ø�Š7ˆ7ØˆFÝ�A•s˜9‘~”~Ñ&Ô&ˆð Ô ðØ)-Ô)<ð�C�×5Ò5Ñ7Ô7Ñ8Ô8Ð8å‘”ð 	ð ?CÔ>QÐ\�C�×7Ò7Ñ9Ô9Ñ:Ô:Ð:ÕWZÑW\ÔW\ð 	õ ˜5¥+Ñ.Ô.ð 5	,ñ 5	,ˆEØ×*Ò*Ñ,Ô,°°U±Ñ;¸rÑAˆGØÔ,¨UÔ3ˆEØÔ"ð E u°¢z zØ�C Ô >ÀÑEÔEÑE��àÔ%ð	EàÔ+ð	Eð ×7Ò7Ñ9Ô9ð	Eð �C Ô 7¸Ñ>Ô>Ñ>��à�C Ô =¸tÑDÔDÑD�Ø˜
Ò"Ð"ð Ô&ð ¨5Ð4IÐ+IÐ+IØ69�DÔ,¨UÑ3ØØÔ$ð ¨Ð2EÐ)EÐ)EØ69�DÔ,¨UÑ3ØØ×(Ò(¨Ñ/Ô/Ð/Ø×.Ò.¨uÑ5Ô5Ð5ÙØ×3Ò3°EÑ:Ô:ˆIØÔ'¨Ô.ˆFØð Øð <Ø4;�DÔ*¨5Ñ1Ø,0�Ô" 5Ñ)Ø/4�Ô% eÑ,Ø×9Ò9¸%Ñ@Ô@�Ø˜E’>�>Ý69¸&À%È$Á,Ñ6OÔ6O�DÔ,¨UÑ3ÙØ(-ˆDÔ˜uÑ%Ø�tŠ|ˆ| Ô 6°uÔ =Ð IØ/3�Ô% eÑ,Ý˜C ¨¡Ñ.Ô.�Ø27�Ô(¨Ñ/Ø˜JÒ&Ð&ØÔ*ð !¨uÐ8MÐ/MÐ/MØ:=˜Ô0°Ñ7Ù ØÔ(ð !¨UÐ6IÐ-IÐ-IØ:=˜Ô0°Ñ7Ù Ø×,Ò,¨UÑ3Ô3Ð3Ø×2Ò2°5Ñ9Ô9Ð9ÙØ×$Ò$ UÑ+Ô+Ð+Ñ+ðk5	,ð 5	,r    c                ó4   — |dk    rdS d|z  }| |z  |dz
  k    S )Nr   Fr¿   rš   rG   )rç  r¨   Úmods      r   rï  zOdometerEngine._column_in_carry  s-   € à�AŠ:ˆ:Ø�5Ø�%‰iˆØ Ñ#¨¨a©Ò/Ð/r    c                óD   — t          t          | j        ¦  «        ¦  «        S r‰   )rÄ   r   r	  r0  s    r   Úget_display_digitsz!OdometerEngine.get_display_digits"  s   € Ý!¥# dÔ&8Ñ"9Ô"9Ñ:Ô:Ð:r    úTuple[int, float]c                óÐ  — |dk     s|t           k    rdS |dk    rC| j        �t          | j        ¦  «        dz  | j        fS |                      ¦   «         dz  | j        fS |dk    r,| j        r%| j        �t          | j        ¦  «        dz  | j        fS d|z  }|                      ¦   «         |z  dz  }| j        |         }|dk    r|dfS | j	        |         }|€|}|t          |d¦  «        fS )Nr   )r   rA   r¿   rš   r›   rA   rD   )rÃ   r  r   r  r/  r  r  r  r  r  r¢   )r  r¨   rZ  ra  r¼  Ú
from_digits         r   Úget_column_drawzOdometerEngine.get_column_draw%  s  € Ø�1Š9ˆ9˜¥Ò,Ð,Ø�6Ø�AŠ:ˆ:ØÔ)Ð5Ý˜4Ô5Ñ6Ô6¸Ñ;¸TÔ=VÐVÐVØ×&Ò&Ñ(Ô(¨2Ñ-¨tÔ/HÐHÐHØ�AŠ:ˆ:˜$Ô-ˆ:°$Ô2KÐ2WÝ�tÔ0Ñ1Ô1°BÑ6¸Ô8PÐPÐPØ�5‰yˆØ×&Ò&Ñ(Ô(¨DÑ0°BÑ6ˆØÔ(¨Ô/ˆØ�DŠ=ˆ=Ø˜C�<ÐØÔ+¨EÔ2ˆ
ØÐØ ˆJØ�3˜u c™?œ?Ð*Ð*r    c                ó8   — |                       |¦  «        d         S r÷  )r  r”  s     r   Úget_column_scrollz OdometerEngine.get_column_scroll8  s   € Ø×#Ò# EÑ*Ô*¨1Ô-Ð-r    c                óV   — t          d| j        |                      ¦   «         z
  ¦  «        S r«   )r   r  r/  r0  s    r   r©   zOdometerEngine.lag_pennies;  s&   € Ý�1�dÔ)¨D×,?Ò,?Ñ,AÔ,AÑAÑBÔBÐBr    r©   c                óV  — t          t          dt          |¦  «        ¦  «        | j        j        ¦  «        }| j        }|�!||k     r|                      ¦   «          d| _        t          d|                      ¦   «         |z   ¦  «        | _	        || _        t          j        ¦   «         | _        d S )Nr   rA   )r¢   r   r   r  r2   r  rà  r  r/  r  r
  r  r  )r  r©   r¬   rÿ   s       r   Úmaintain_lagzOdometerEngine.maintain_lag>  sš   € Ý•#�a�˜[Ñ)Ô)Ñ*Ô*¨D¬KÔ,GÑHÔHˆØÔ,ˆØÐ C¨(¢N NØ×5Ò5Ñ7Ô7Ð7Ø(+ˆDÔ%Ý! ! T×%8Ò%8Ñ%:Ô%:¸SÑ%@ÑAÔAˆÔØ$'ˆÔ!Ý(,Ô(9Ñ(;Ô(;ˆÔ%Ð%Ð%r    c                óH   — |                       | j        ¦  «         d | _        d S r‰   )r$  r  r  r0  s    r   Úreset_display_to_targetz&OdometerEngine.reset_display_to_targetH  s'   € Ø×+Ò+¨DÔ,?Ñ@Ô@Ð@Ø$(ˆÔ!Ð!Ð!r    )NN)r  r  rà   r  )r  r  r   r  )r(  r   r   r  )r   r   )r   r2  )r   r   r‰   )r    r  r   r(   )r    r   r   r(   )r	  r(   r¨   r   r   r(   )r   r  r   r  )r   r  )rc  r(   r   r(   )r   r(   )rc  r(   r   r  )ra  r  r   r   )rª  r   r«  r   r¨   r   r   r2  )ra  r  r   r¼   )r¨   r   r   r  )rç  r   r¨   r   r   r   )r¨   r   r   r2  )r¨   r   r   r(   )r	  r(   r   rõ  )rš   )rc  r(   rÞ  r   r   r  )rç  r   r¨   r   r   r2  )r   r¼   )r¨   r   r   r
  )r©   r   r   r  )MrŠ   r‹   rŒ   r  r"  r%  r'  r+  r-  Úpropertyr1  r7  r<  r/  r@  r   rF  rI  rO  ræ   rK  r[  r$  rb  rx  r|  r~  r€  r„  rŽ  r‘  r•  r˜  rm  rœ  r¡  r£  r§  r©  Ústaticmethodr­  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ý  rL  rß  rï  r	  r  r  r©   r  r  rG   r    r   rä   rä   £  sb  € € € € € ð ,0Ø04ð#.ð #.ð #.ð #.ð #.ðJ*ð *ð *ð *ð/ð /ð /ð /ð0ð 0ð 0ð 0ðJð Jð Jð Jð0ð 0ð 0ð 0ð ð%ð %ð %ñ „Xð%ð	
ð 	
ð 	
ð 	
ð ð8ð 8ð 8ñ „Xð8ð'ð 'ð 'ð 'ðð ð ð ðð ð ð ð.ð .ð .ð .ð/ð /ð /ð /ð /ð
$ð $ð $ð $ð $ð0ð ð ð ð@
ð 
ð 
ð 
ð
-ð -ð -ð -ð'ð 'ð 'ð 'ð 'ð+ð +ð +ð +ð>'ð >'ð >'ð >'ð@7ð 7ð 7ð 7ð=ð =ð =ð =ð>ð >ð >ð >ð/ð /ð /ð /ð
+(ð +(ð +(ð +(ðZ=ð =ð =ð =ð
ð ð ð ðð ð ð ð7ð 7ð 7ð 7ðA(ð A(ð A(ð A(ðD	Tð 	Tð 	Tð 	TðRð Rð Rð Rð'ð 'ð 'ð 'ð 'ð*ð *ð *ð *ð *ð ð[ð [ð [ñ „\ð[ð


ð 

ð 

ð 

ð 

ð

ð 

ð 

ð 

ð 

ðð ð ð ðð ð ð ð0ð 0ð 0ð 0ð0ð 0ð 0ð 0ð
+ð 
+ð 
+ð 
+ð	-ð 	-ð 	-ð 	-ð,ð ,ð ,ð ,ð>,ð ,ð ,ð ,ð8&ð &ð &ð &ð(ð (ð (ð (ðNð Nð Nð Nð8ð 8ð 8ð 8ðJð Jð Jð Jð#>ð #>ð #>ð #>ðJ*ð *ð *ð *ð,ð ,ð ,ð ,ð9ð 9ð 9ð 9ð ð3ð 3ð 3ñ „\ð3ð&ð &ð &ð &ðUð Uð Uð Uð+
ð +
ð +
ð +
ðZð ð ð ð
 ð1ð 1ð 1ñ „\ð1ð
ð ð ð ð,ð ,ð ,ð ,ð&ð ð ð ðA,ð A,ð A,ð A,ð A,ðF ð0ð 0ð 0ñ „\ð0ð;ð ;ð ;ð ;ð+ð +ð +ð +ð&.ð .ð .ð .ðCð Cð Cð Cð<ð <ð <ð <ð)ð )ð )ð )ð )ð )r    rä   )r   r   r   r   )r   )r   r   r!   r   r   r   )r�   r1   r   r   )r�   r1   r   r(   )r    r   r�   r1   r   r(   )r§   )r¨   r   r�   r1   r©   r   r   r(   )r   r   r   r¼   )rÅ   r¼   r   r   )r�   r1   r   r   )rï   r   r‡   r   r   rH   )r    r   rý   rH   r   r(   ))Ú
__future__r   rn  r
  Údataclassesr   Údecimalr   r   r   Útypingr   r	   r
   r   r   rÃ   rÇ   r   r(   Ú
CurvePointr   r/   r1   r—   r�   rŸ   r¦   r­   r±   r³   r¶   r¸   r»   rÄ   rÈ   rÞ   rî   r~   r¯   rä   rG   r    r   ú<module>r     sŸ  ðØ "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø !Ð !Ð !Ð !Ð !Ð !Ø <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3à€ØÐ Ø�3˜�:Ô€
ð'ð 'ð 'ð 'ðð ð ð ð ð2 ð}ð }ð }ð }ð }ñ }ô }ñ „ð}ð@%ð %ð %ð %ðPð Pð Pð Pð%ð %ð %ð %ð$ð $ð $ð $ð$ 9;ð,ð ,ð ,ð ,ð ,ðð ð ð ðBð Bð Bð Bð
Bð Bð Bð Bð
%ð %ð %ð %ð$ð $ð $ð $ð*Cð Cð Cð Cð
ð ð ð ð/ð /ð /ð /ðdð ð ð ðD)ð )ð )ð )ð@ð ð ð ðg)ð g)ð g)ð g)ð g)ñ g)ô g)ð g)ð g)ð g)r    