§
    íÂj²=  ã                  ó”   — d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
 ddlmZmZmZmZmZmZmZmZmZ ddlmZ  G d„ d¦  «        ZdS )	am  
FreeExile Character Stat Aggregator Service.
Combines Base Attributes, Equipped Item Affixes, and Meridian Passives.
Evaluates Path of Exile modifier math (Flat, Inc/Red, More/Less), tag filters,
and conditional triggers. Constructs calculation ASTs and persists them to SQLite.
Strict typing and modular methods (<= 50 lines each) following Elite Standards 2026.
é    )ÚannotationsN)ÚDictÚListÚOptionalÚAnyÚTuple)	ÚModifierTypeÚStatModifierÚEvaluationContextÚAggregatedCharacterStatsÚConstantNodeÚSumNodeÚScaleFactorNodeÚProductNodeÚModifierContributionNode)ÚFormulaPersistenceServicec                  óœ   — e Zd ZdZ	 	 	 d>d?d
„Z	 	 	 	 	 	 d@dAd„Z	 	 	 	 	 dBdCd„ZdDd!„ZdEd"„ZdFd&„Z	dGd)„Z
dHd.„ZdId0„ZdJd2„ZdKd6„ZdLd:„ZdMd=„ZdS )NÚCharacterStatAggregatorzRAuthoritative service aggregating character stats under Path of Exile mathematics.NÚpersistence_serviceú#Optional[FormulaPersistenceService]Úinventory_serviceúOptional[Any]Úmeridian_serviceÚreturnÚNonec                óN   — |pt          d¦  «        | _        || _        || _        d S )Nz:memory:)r   Úpersistencer   r   )Úselfr   r   r   s       ú5C:\Projects\FreeExile\server\stats\stat_aggregator.pyÚ__init__z CharacterStatAggregator.__init__   s0   € ð /ÐWÕ2KÈJÑ2WÔ2WˆÔØ!2ˆÔØ 0ˆÔÐÐó    Úcharacter_loadoutÚ	inventoryÚmeridian_bonusÚcontextúOptional[EvaluationContext]Ú	player_idúOptional[str]Úcustom_modifiersúOptional[List[StatModifier]]r   c           	     ó\  — |pt          ¦   «         }|pd}g }	|                      ||	¦  «         |                      ||	¦  «         |                      |||	¦  «         |r|	                     |¦  «         |                      |	|¦  «        \  }
}|                      |
¦  «        }d|› dt          t          j        ¦   «         dz  ¦  «        › dt          j
        ¦   «         j        dd…         › �}| j                             ||||                     ¦   «         t          |j        ¦  «        ¬¦  «         |S )zTExecutes full stat aggregation pipeline from all sources, AST build, and DB persist.Úanon_playerÚcalc_Ú_iè  Né   )r'   Úcalculation_idÚformula_astÚfinal_statsÚcontext_tags)r   Ú_collect_attribute_modifiersÚ_collect_inventory_modifiersÚ_collect_meridian_modifiersÚextendÚ_evaluate_all_statsÚ_build_aggregated_statsÚintÚtimeÚuuidÚuuid4Úhexr   Úsave_calculationÚto_dictÚlistÚactive_tags)r   r"   r#   r$   r%   r'   r)   ÚctxÚpidÚmodsÚ
stats_dictÚast_treer2   Úcalc_ids                 r   Úcalculate_statsz'CharacterStatAggregator.calculate_stats(   s@  € ð Ð,Õ*Ñ,Ô,ˆØÐ(˜=ˆØ#%ˆà×)Ò)Ð*;¸TÑBÔBÐBØ×)Ò)¨)°TÑ:Ô:Ð:Ø×(Ò(¨¸¸dÑCÔCÐCØð 	*Ø�KŠKÐ(Ñ)Ô)Ð)à#×7Ò7¸¸cÑBÔBÑˆ
�HØ×2Ò2°:Ñ>Ô>ˆàP˜#ÐPÐP¥¥D¤I¡K¤K°$Ñ$6Ñ 7Ô 7ÐPÐP½$¼*¹,¼,Ô:JÈ2ÈAÈ2Ô:NÐPÐPˆØÔ×)Ò)ØØ"Ø Ø#×+Ò+Ñ-Ô-Ý˜cœoÑ.Ô.ð 	*ñ 	
ô 	
ð 	
ð Ðr!   ÚMAP_JOINÚstrÚ
account_idÚcharacter_idrB   Ú
conditionsÚtrigger_reasonc                óê  — d}| j         r1|r/|r-	 | j                              ||¦  «        }n# t          $ r Y nw xY wd}| j        r.|r,	 | j                             |¦  «        }n# t          $ r Y nw xY w|rt          |¦  «        nt          ¦   «         }	t          t          |t          ¦  «        r|                     ¦   «         n|pd¦  «        }
t          |	|
¬¦  «        }|  
                    ||||¬¦  «        S )z:High-level facade querying upstream services by player_id.N© )rB   rN   )r#   r$   r%   r'   )r   Úget_character_inventoryÚ	Exceptionr   Úcompute_total_statsÚ	frozensetÚ
isinstanceÚdictÚkeysr   rI   )r   r'   rL   rM   rB   rN   rO   ÚinvÚmeridianÚtagsÚcondsrC   s               r   Úaggregate_player_statsz.CharacterStatAggregator.aggregate_player_statsI   s6  € ð ˆØÔ!ð 	 jð 	°\ð 	ðØÔ,×DÒDÀZÐQ]Ñ^Ô^��øÝð ð ð Ø�ðøøøàˆØÔ ð 	 Yð 	ðØÔ0×DÒDÀYÑOÔO��øÝð ð ð Ø�ðøøøð *5ÐE�y˜Ñ%Ô%Ð%½)¹+¼+ˆÝ­z¸*ÅdÑ/KÔ/KÐc˜*Ÿ/š/Ñ+Ô+Ð+ÐR\ÐRbÐ`bÑdÔdˆÝ¨D¸UÐCÑCÔCˆØ×#Ò#¨cÀ(ÐTWÐclÐ#ÑmÔmÐms   �+ «
8·8ÁA" Á"
A/Á.A/ÚloadoutrE   úList[StatModifier]c                óÜ  — |rt          |dd¦  «        nd}|rt          |dd¦  «        nd}|rt          |dd¦  «        nd}|                     t          dt          j        t          |¦  «        d¬¦  «        ¦  «         |                     t          dt          j        |d	z  t          h d
£¦  «        d¬¦  «        ¦  «         |                     t          dt          j        |dz  d¬¦  «        ¦  «         |                     t          dt          j        |dz  dz  d¬¦  «        ¦  «         |                     t          dt          j        |d	z  t          ddh¦  «        d¬¦  «        ¦  «         dS )z0Extracts base attribute scaling (STR, DEX, INT).Ú	cuong_theé2   Ú	than_phapÚ	than_niemÚmax_hpzattr:STR©ÚsourceÚattack_damagegš™™™™™É?>   ÚmeleeÚattackÚphysical)r[   rg   Úattack_speedg333333Ã?zattr:DEXÚcrit_chancegš™™™™™¹?ç      Y@ÚspellÚ	elementalzattr:INTN)ÚgetattrÚappendr
   r	   ÚFLATÚfloatÚ	INCREASEDrU   )r   r^   rE   Ústr_valÚdex_valÚint_vals         r   r4   z4CharacterStatAggregator._collect_attribute_modifierse   s{  € à7>ÐF•'˜' ;°Ñ3Ô3Ð3ÀBˆØ7>ÐF•'˜' ;°Ñ3Ô3Ð3ÀBˆØ7>ÐF•'˜' ;°Ñ3Ô3Ð3ÀBˆð 	�Š•L ­<Ô+<½eÀG¹n¼nÐU_Ð`Ñ`Ô`ÑaÔaÐaØ�Š•LØ�\Ô3°W¸s±]ÝÐ:Ð:Ð:Ñ;Ô;ÀJð
ñ 
ô 
ñ 	ô 	ð 	ð
 	�Š•L µÔ1GÈÐSWÉÐ`jÐkÑkÔkÑlÔlÐlØ�Š•L µÔ0AÀGÈcÁMÐUZÑCZÐcmÐnÑnÔnÑoÔoÐoà�Š•LØ�\Ô3°W¸s±]Ý˜G [Ð1Ñ2Ô2¸:ð
ñ 
ô 
ñ 	ô 	ð 	ð 	ð 	r!   c                óP  — |sdS t          |d|¦  «        }t          |t          ¦  «        r!t          |                     ¦   «         ¦  «        nt          |¦  «        }|                      |¦  «        \  }}}|r1|                     t          dt          j	        dd¬¦  «        ¦  «         nd|rb|r`|                     t          dt          j	        dd	¬¦  «        ¦  «         |                     t          d
t          j
        dd	¬¦  «        ¦  «         |D ]}|                      ||¦  «         ŒdS )z4Ingests equipment affixes and weapon grip mechanics.NÚ	equipmentrh   ç      I@zgrip:TWO_HANDEDrf   rl   g      $@zgrip:DUAL_WIELDÚblock_chanceg      .@)rq   rV   rW   rA   ÚvaluesÚ_inspect_weapon_gripsrr   r
   r	   ÚMORErs   Ú_parse_item_affixes)	r   r#   rE   Ú
items_dictÚitemsÚhas_main_2hÚhas_main_1hÚ
has_off_1hÚits	            r   r5   z4CharacterStatAggregator._collect_inventory_modifiersz   s4  € àð 	ØˆFÝ˜Y¨°YÑ?Ô?ˆ
Ý-7¸
ÅDÑ-IÔ-IÐ_•�Z×&Ò&Ñ(Ô(Ñ)Ô)Ð)ÍtÐT^ÑO_ÔO_ˆà/3×/IÒ/IÈ%Ñ/PÔ/PÑ,ˆ�[ *Øð 	iØ�KŠK� _µlÔ6GÈÐVgÐhÑhÔhÑiÔiÐiÐiØð 	i˜Zð 	iØ�KŠK� ^µ\Ô5FÈÐUfÐgÑgÔgÑhÔhÐhØ�KŠK� ^µ\Ô5FÈÐUfÐgÑgÔgÑhÔhÐhàð 	/ð 	/ˆBØ×$Ò$ R¨Ñ.Ô.Ð.Ð.ð	/ð 	/r!   r‚   ú	List[Any]úTuple[bool, bool, bool]c                óÜ  — d}d}d}|D �]^}t          t          |dd¦  «        ¦  «                             ¦   «         }t          t          |dd¦  «        ¦  «                             ¦   «         }t          t          |dd¦  «        ¦  «                             ¦   «         }t          |di ¦  «        pi }	d|v p3d|v p/|	                     d¦  «        d	k    p|	                     d
¦  «        du }
t          t          |dd¦  «        ¦  «                             ¦   «         }d|v pd|v pd|v p	d|v pd|v p|
}|r8|
rd}�Œ,d|                     ¦   «         v sd|                     ¦   «         v rd}�Œ\d}�Œ`|||fS )z(Detects 2H or Dual-Wield configurations.FÚnameÚ Úitem_idÚslotÚmetadataÚ2hÚgripÚ
TWO_HANDEDÚis_two_handedTÚ	item_typeÚweaponÚswordÚbladeu   kiáº¿mu   Ä‘aoÚoff_handÚoffhand)rK   rq   ÚlowerÚupperÚget)r   r‚   Úmain_2hÚmain_1hÚoff_1hr†   rŠ   rŒ   r�   ÚmetaÚis_2hÚitem_type_strÚis_wpns                r   r~   z-CharacterStatAggregator._inspect_weapon_grips‹   s¼  € àˆØˆØˆØð 	#ñ 	#ˆBÝ•w˜r 6¨2Ñ.Ô.Ñ/Ô/×5Ò5Ñ7Ô7ˆDÝ�' " i°Ñ4Ô4Ñ5Ô5×;Ò;Ñ=Ô=ˆGÝ•w˜r 6¨2Ñ.Ô.Ñ/Ô/×5Ò5Ñ7Ô7ˆDÝ˜2˜z¨2Ñ.Ô.Ð4°"ˆDà˜�ð 5Ø˜7�?ð5à—8’8˜FÑ#Ô# |Ò3ð5ð —8’8˜OÑ,Ô,°Ð4ð	 õ  ¥¨¨K¸Ñ <Ô <Ñ=Ô=×CÒCÑEÔEˆMà˜MÐ)ð Ø˜d�?ðà˜d�?ðð ˜tÐ#ðð ˜T�>ð	ð
 ð ð ð #Øð #Ø"�G‘GØ 4§:¢:¡<¤<Ð/Ð/°9ÀÇ
Â
ÁÄÐ3LÐ3LØ!�F‘Fà"�GùØ˜ Ð'Ð'r!   Úitemr   c                ó€  — t          |dg ¦  «        }dt          |dd¦  «        › �}|D ]•}t          |dd¦  «        }|r7t          t          |dd¦  «        ¦  «        }|                      ||||¦  «         ŒLt          |d	d¦  «        }|r6t          t          |d
d¦  «        ¦  «        }|                      ||||¦  «         Œ–dS )z?Parses legacy Affix and 15-tier AffixMod from an equipped item.Úaffixeszitem:rŠ   ÚgearÚstat_keyNÚcurrent_valr   Úmod_idÚvalue)rq   rt   Ú_map_legacy_affixÚ_map_affix_mod)	r   r£   rE   r¥   ÚsrcÚaffÚs_keyÚvalÚm_ids	            r   r€   z+CharacterStatAggregator._parse_item_affixes­   sá   € å˜$ 	¨2Ñ.Ô.ˆØ5•g˜d F¨FÑ3Ô3Ð5Ð5ˆØð 	:ð 	:ˆCå˜C ¨TÑ2Ô2ˆEØð Ý�G C¨¸Ñ:Ô:Ñ;Ô;�Ø×&Ò& u¨c°3¸Ñ=Ô=Ð=Øå˜3 ¨$Ñ/Ô/ˆDØð :Ý�G C¨°!Ñ4Ô4Ñ5Ô5�Ø×#Ò# D¨#¨s°DÑ9Ô9Ð9øð	:ð 	:r!   Úkeyr°   rt   r­   c           
     ó  — |dk    r2|                      t          dt          j        ||¬¦  «        ¦  «         dS |dk    rA|                      t          dt          j        |t	          dh¦  «        |¬¦  «        ¦  «         dS |dk    r2|                      t          dt          j        ||¬¦  «        ¦  «         dS |dk    r2|                      t          dt          j        ||¬¦  «        ¦  «         dS |d	k    r=|                      t          d
t          j        |dk    r|dz  n||¬¦  «        ¦  «         dS |dv rN|dk    rdnd|v rdnd|v rdnd}|D ]7}|                      t          d|› �t          j        ||¬¦  «        ¦  «         Œ6dS dS )z+Maps legacy stone affixes to StatModifiers.Úphys_dmgrh   rf   Úfire_dmgÚfirere   Ú	atk_speedrl   Ú	crit_raterm   ç      ð?rn   )Úall_resÚfire_resÚcold_resÚ	chaos_resrº   ©ÚhoaÚthuyÚkimÚmocÚtho)r¿   Úcold)rÀ   )rÂ   Úres_N)rr   r
   r	   rs   rU   ru   )r   r²   r°   r­   rE   ÚelemsÚes          r   r«   z)CharacterStatAggregator._map_legacy_affix¾   sÐ  € à�*ÒÐØ�KŠK� _µlÔ6GÈÐUXÐYÑYÔYÑZÔZÐZÐZÐZØ�JÒÐØ�KŠK� _µlÔ6GÈÍiÐY_ÐX`ÑNaÔNaÐjmÐnÑnÔnÑoÔoÐoÐoÐoØ�HŠ_ˆ_Ø�KŠK� X­|Ô/@À#ÈcÐRÑRÔRÑSÔSÐSÐSÐSØ�KÒÐØ�KŠK� ^µ\Ô5KÈSÐY\Ð]Ñ]Ô]Ñ^Ô^Ð^Ð^Ð^Ø�KÒÐØ�KŠK� ]µLÔ4EÐVYÐ\_ÒV_ÐV_ÀsÈUÁ{À{ÐehÐqtÐuÑuÔuÑvÔvÐvÐvÐvØÐDÐDÐDØ<?À9Ò<LÐ<LÐ8Ð8Ø" c˜M˜M��¸VÀs¸]¸]°	°	ÐPXð ð ð Zð Z�Ø—’�L¨°¨¨µ\Ô5FÈÐTWÐXÑXÔXÑYÔYÐYÐYð EÐDðZð Zr!   r©   c           
     ó|  — d|v sd|v rDd|v rt           j        nt           j        }|                     t	          d|||¬¦  «        ¦  «         dS d|v rA|                     t	          dt           j        |t          dh¦  «        |¬¦  «        ¦  «         dS d|v r2|                     t	          d	t           j        ||¬¦  «        ¦  «         dS d
|v r2|                     t	          dt           j        ||¬¦  «        ¦  «         dS d|v r2|                     t	          dt           j        ||¬¦  «        ¦  «         dS d|v r=|                     t	          dt           j        |dk    r|dz  n||¬¦  «        ¦  «         dS d|v rCd|v rdnd|v rdnd}|                     t	          d|› �t           j        ||¬¦  «        ¦  «         dS dS )z1Maps 15-tier AffixMod instances to StatModifiers.Úpref_flat_physÚpref_phys_pctÚpctrh   rf   Úpref_fire_flatr¶   Ú	pref_lifere   Úsuff_move_spdÚ
move_speedÚsuff_atk_spdrl   Úsuff_crit_multiÚcrit_multiplierr¹   rn   Úresr¿   rÄ   rÀ   rÂ   rÅ   N)r	   ru   rs   rr   r
   rU   )r   r©   r°   r­   rE   Úm_typeÚelems          r   r¬   z&CharacterStatAggregator._map_affix_modÑ   sù  € à˜vÐ%Ð%¨¸FÐ)BÐ)BØ/4¸¨¨•\Ô+Ð+ÅLÔDUˆFØ�KŠK� _°f¸cÈ#ÐNÑNÔNÑOÔOÐOÐOÐOØ Ð'Ð'Ø�KŠK� _µlÔ6GÈÍiÐY_ÐX`ÑNaÔNaÐjmÐnÑnÔnÑoÔoÐoÐoÐoØ˜FÐ"Ð"Ø�KŠK� X­|Ô/@À#ÈcÐRÑRÔRÑSÔSÐSÐSÐSØ Ð&Ð&Ø�KŠK� \µ<Ô3IÈ3ÐWZÐ[Ñ[Ô[Ñ\Ô\Ð\Ð\Ð\Ø˜vÐ%Ð%Ø�KŠK� ^µ\Ô5KÈSÐY\Ð]Ñ]Ô]Ñ^Ô^Ð^Ð^Ð^Ø &Ð(Ð(Ø�KŠK�Ð%6½Ô8IÐZ]Ð`cÒZcÐZcÈ3ÐQVÉ;È;ÐilÐuxÐyÑyÔyÑzÔzÐzÐzÐzØ�fˆ_ˆ_Ø" fÐ,Ð,�5�5¸VÀvÐ=MÐ=M°6°6ÐSXˆDØ�KŠK� ]¨D ] ]µLÔ4EÀsÐSVÐWÑWÔWÑXÔXÐXÐXÐXð ˆ_r!   rZ   c           
     óÌ  — |}|€;| j         r4|dk    r.	 | j                              |¦  «        }n# t          $ r d}Y nw xY w|sdS d}t          |dd¦  «        dk    rB|                     t          dt          j        t          |j	        ¦  «        |¬¦  «        ¦  «         t          |dd¦  «        dk    rB|                     t          d	t          j        t          |j
        ¦  «        |¬¦  «        ¦  «         t          |d
d¦  «        dk    rL|j        dk    r
|j        dz  n|j        }|                     t          d	t          j        ||¬¦  «        ¦  «         t          |dd¦  «        dk    rB|                     t          dt          j        t          |j        ¦  «        |¬¦  «        ¦  «         t          |dd¦  «        dk    rB|                     t          dt          j        t          |j        ¦  «        |¬¦  «        ¦  «         t          |dd¦  «        dk    rJdD ]I}|                     t          d|› �t          j        t          |j        ¦  «        |¬¦  «        ¦  «         ŒHdS dS )z-Ingests Meridian passive constellation stats.Nr,   rZ   Úhpr   re   rf   Údpsrh   Údps_multç        g       @rn   r¸   rm   Úcrit_dmgrÒ   Úresistr¾   rÅ   )r   rT   rS   rq   rr   r
   r	   rs   rt   r×   rØ   rÙ   ru   r¸   rÛ   rÜ   )r   rZ   r'   rE   Úbr­   Úd_pctrÇ   s           r   r6   z3CharacterStatAggregator._collect_meridian_modifiersä   s`  € àˆØˆ9˜Ô.ˆ9°9ÀÒ3MÐ3MðØÔ)×=Ò=¸iÑHÔH��øÝð ð ð Ø���ðøøøàð 	ØˆFØˆÝ�1�d˜AÑÔ Ò"Ð"Ø�KŠK� X­|Ô/@Å%ÈÌÁ+Ä+ÐVYÐZÑZÔZÑ[Ô[Ð[Ý�1�e˜QÑÔ !Ò#Ð#Ø�KŠK� _µlÔ6GÍÈqÌuÉÌÐ^aÐbÑbÔbÑcÔcÐcÝ�1�j #Ñ&Ô&¨Ò,Ð,Ø*+¬*¸Ò*;Ð*;�A”J Ñ&Ð&ÀÄˆEØ�KŠK� _µlÔ6LÈeÐ\_Ð`Ñ`Ô`ÑaÔaÐaÝ�1�k 3Ñ'Ô'¨#Ò-Ð-Ø�KŠK� ]µLÔ4EÅuÈQÌ[ÑGYÔGYÐbeÐfÑfÔfÑgÔgÐgÝ�1�j #Ñ&Ô&¨Ò,Ð,Ø�KŠK�Ð%6½Ô8IÍ5ÐQRÔQ[ÑK\ÔK\ÐehÐiÑiÔiÑjÔjÐjÝ�1�h Ñ$Ô$ sÒ*Ð*Ø9ð fð f�Ø—’�L¨°¨¨µ\Ô5FÍÈaÌhÉÌÐ`cÐdÑdÔdÑeÔeÐeÐeð +Ð*ðfð fs   “. ®=¼=rC   r   ú'Tuple[Dict[str, float], Dict[str, Any]]c                ó  — ddddddddddddœ}t          |                     ¦   «         ¦  «        d	„ |D ¦   «         z  }i i }}|D ];}|                      ||                     |d¦  «        ||¦  «        \  }}	|||<   |	||<   Œ<||fS )
z0Evaluates mathematical resolution for each stat.r{   g     @�@gš™™™™™©?g      ø?g      @r¹   rÚ   )rh   re   rm   rÒ   rÏ   rl   Úres_hoaÚres_thuyÚres_kimÚres_mocÚres_thoc                ó   — h | ]	}|j         ’Œ
S rQ   )r§   )Ú.0Úms     r   ú	<setcomp>z>CharacterStatAggregator._evaluate_all_stats.<locals>.<setcomp>  s   € Ð0JÐ0JÐ0JÀ°´Ð0JÐ0JÐ0Jr!   )ÚsetrX   Ú_compute_statr›   )
r   rE   rC   Ú	base_valsÚall_stat_keysÚ	res_statsrG   r¯   Ú	final_valÚstat_asts
             r   r8   z+CharacterStatAggregator._evaluate_all_statsþ   s¾   € ð
 "¨VÀDØ#°3ÈØ¨¸ÈÐX[ð
ð 
ˆ	õ
 ˜IŸNšNÑ,Ô,Ñ-Ô-Ð0JÐ0JÀTÐ0JÑ0JÔ0JÑJˆØ  "�8ˆ	Ø"ð 	'ð 	'ˆEØ"&×"4Ò"4°U¸I¿MºMÈ%ÐQTÑ<UÔ<UÐW[Ð]`Ñ"aÔ"aÑˆI�xØ(ˆI�eÑØ&ˆH�U‰OˆOØ˜(Ð"Ð"r!   r¯   Úbase_valúTuple[float, Dict[str, Any]]c           
     ó$  — d\  }}}}g g g }}
}	|D �]¯}|j         |k    rŒ|                     |j        ¦  «        o|                     |j        ¦  «        }t          |j        |j        j        |j        t          |j        ¦  «        |j        |¬¦  «         
                    ¦   «         }|sŒ˜|j        t          j        k    r ||j        z  }|	                     |¦  «         ŒÍ|j        t          j        k    r!||j        z  }|
                     |¦  «         �Œ|j        t          j        k    r!||j        z  }|
                     |¦  «         �Œ9|j        t          j        k    r'|d|j        dz  z   z  }|                     |¦  «         �Œu|j        t          j        k    r%|d|j        dz  z
  z  }|                     |¦  «         �Œ±t%          dd||z
  dz  z   ¦  «        }||z   |z  |z  }d|v rdnd}t'          ||¦  «        }||t)          d	|d
¦  «         
                    ¦   «         t+          d||	¦  «         
                    ¦   «         t-          d||z
  ||
¦  «         
                    ¦   «         t/          d||¦  «         
                    ¦   «         dœ}||fS )zHResolves PoE formula: (Base + Flat) * (1 + (Inc - Red)/100) * More/Less.)rÚ   rÚ   rÚ   r¹   )rg   Úmodifier_typerª   r[   Ú	conditionÚcondition_metr¹   rn   rÚ   Úcrité   é   ÚbaseÚ
base_rulesÚflat_sumÚinc_red_factorÚmore_less_factor)Ú	stat_nameÚfinal_valuerú   ÚflatÚscaleÚmore)r§   Úmatches_tagsr[   Úis_condition_metrõ   r   rg   Úmod_typerª   rA   r@   r	   rs   rr   ru   ÚREDUCEDr   ÚLESSÚmaxÚroundr   r   r   r   )r   r¯   rñ   rE   rC   Ú
flat_totalÚ	inc_totalÚ	red_totalÚmore_factorÚ
flat_nodesÚ	inc_nodesÚ
more_nodesrè   ÚactiveÚc_nodeÚscale_factorrï   Ú	precisionÚfinal_roundedrð   s                       r   rë   z%CharacterStatAggregator._compute_stat  s°  € ð 9KÑ5ˆ
�I˜y¨+Ø,.°°B˜z�Iˆ
àð 	*ñ 	*ˆAØŒz˜UÒ"Ð"ØØ×%Ò% a¤fÑ-Ô-ÐS°#×2FÒ2FÀqÄ{Ñ2SÔ2SˆFÝ-Ø”x¨q¬zÔ/?ÀqÄwÝ˜!œ&‘\”\¨Q¬[Èðñ ô ÷ Šg‰iŒið ð ð ØØŒz�\Ô.Ò.Ð.Ø˜aœgÑ%�
Ø×!Ò! &Ñ)Ô)Ð)Ð)Ø”�|Ô5Ò5Ð5Ø˜QœWÑ$�	Ø× Ò  Ñ(Ô(Ð(Ñ(Ø”�|Ô3Ò3Ð3Ø˜QœWÑ$�	Ø× Ò  Ñ(Ô(Ð(Ñ(Ø”�|Ô0Ò0Ð0Ø  a¤g°¡oÑ 5Ñ6�Ø×!Ò! &Ñ)Ô)Ð)Ñ)Ø”�|Ô0Ò0Ð0Ø  a¤g°¡oÑ 5Ñ6�Ø×!Ò! &Ñ)Ô)Ð)ùå˜3  y°9Ñ'<ÀÑ&EÑ EÑFÔFˆØ 
Ñ*¨lÑ:¸[ÑHˆ	Ø 5˜˜�A�A¨aˆ	Ý˜i¨Ñ3Ô3ˆð ¨}Ý  ¨°<Ñ@Ô@×HÒHÑJÔJÝ˜J¨
°JÑ?Ô?×GÒGÑIÔIÝ$Ð%5°yÀ9Ñ7LÈlÐ\eÑfÔf×nÒnÑpÔpÝÐ 2°KÀÑLÔL×TÒTÑVÔVð
ð 
ˆð ˜hÐ&Ð&r!   Ús_dictúDict[str, float]c                ó  ‡— ˆfd„dD ¦   «         }t          ‰d         ‰d         t          dt          d‰d         ¦  «        ¦  «        t          d‰d         ¦  «        t          d‰d	         ¦  «        |t          ‰¦  «        ¬
¦  «        S )z=Assembles AggregatedCharacterStats from evaluated dictionary.c                óD   •— i | ]}|‰                      d |› �d¦  «        “ŒS )rÅ   rÚ   )r›   )rç   rÇ   r  s     €r   ú
<dictcomp>zCCharacterStatAggregator._build_aggregated_stats.<locals>.<dictcomp>@  s/   ø€ ÐdÐdÐd¸!�q˜&Ÿ*š* Z¨A Z Z°Ñ5Ô5ÐdÐdÐdr!   r¾   rh   re   r¹   rÚ   rm   rÒ   rÏ   )rh   re   rm   rÒ   rÏ   ÚresistancesÚ	all_stats)r   Úminr	  rW   )r   r  r  s    ` r   r9   z/CharacterStatAggregator._build_aggregated_stats>  s‘   ø€ àdÐdÐdÐdÐ?cÐdÑdÔdˆÝ'Ø  Ô1Ø˜(Ô#Ý˜C¥ S¨&°Ô*?Ñ!@Ô!@ÑAÔAÝ  VÐ,=Ô%>Ñ?Ô?Ý˜3  |Ô 4Ñ5Ô5Ø#Ý˜6‘l”lð
ñ 
ô 
ð 	
r!   )NNN)r   r   r   r   r   r   r   r   )NNNNNN)r"   r   r#   r   r$   r   r%   r&   r'   r(   r)   r*   r   r   )NNNNrJ   )r'   rK   rL   r(   rM   r(   rB   r   rN   r   rO   rK   r   r   )r^   r   rE   r_   r   r   )r#   r   rE   r_   r   r   )r‚   r‡   r   rˆ   )r£   r   rE   r‡   r   r   )
r²   rK   r°   rt   r­   rK   rE   r_   r   r   )
r©   rK   r°   rt   r­   rK   rE   r_   r   r   )rZ   r   r'   rK   rE   r_   r   r   )rE   r_   rC   r   r   rß   )
r¯   rK   rñ   rt   rE   r_   rC   r   r   rò   )r  r  r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    rI   r]   r4   r5   r~   r€   r«   r¬   r6   r8   rë   r9   rQ   r!   r   r   r      ss  € € € € € Ø\Ð\ð DHØ+/Ø*.ð	1ð 1ð 1ð 1ð 1ð ,0Ø#'Ø(,Ø/3Ø#'Ø9=ðð ð ð ð ðH %)Ø&*Ø%)Ø$(Ø(ðnð nð nð nð nð8ð ð ð ð*/ð /ð /ð /ð" (ð  (ð  (ð  (ðD:ð :ð :ð :ð"Zð Zð Zð Zð&Yð Yð Yð Yð&fð fð fð fð4#ð #ð #ð #ð"-'ð -'ð -'ð -'ð^
ð 
ð 
ð 
ð 
ð 
r!   r   )r"  Ú
__future__r   r<   r;   Útypingr   r   r   r   r   Úserver.stats.stat_typesr	   r
   r   r   r   r   r   r   r   Ú server.stats.formula_persistencer   r   rQ   r!   r   ú<module>r'     s  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø €€€Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð GÐ FÐ FÐ FÐ FÐ Fðn
ð n
ð n
ð n
ð n
ñ n
ô n
ð n
ð n
ð n
r!   