Ë
    tPêjýé  ã            (       ó	  — U d dl Z d dlmZmZmZmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZ d dlmZmZmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z# d dl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- erd dl.m/Z0 d dl.m1Z2 dddddddœZ3eee4e4f      e5d<    G d„ de«      Z6 G d„ ded¬ «      Z7e4e8e4e9f   z  Z: G d!„ d"e«      Z; G d#„ d$e«      Z< G d%„ d&e<«      Z=d'e6e<z  d(e>fd)„Z?d*e-d'e6d(e-fd+„Z@d,e4dz  d(eAfd-„ZBd.ee6   d(e-fd/„ZCd0ee4e8e4e9f   f   dz  d1e4d(e8e4e9f   fd2„ZD	 	 dyd3e%d'e6d4ee4e8e4e9f   f   d5ee4e8e4e9f   f   d6ee4e7f   d7e4dz  d0ee4e8e4e9f   f   dz  d(e%fd8„ZEd9ed:ee4   d(e8e4e7f   fd;„ZF	 	 dzd<e4d=e4d>eGdz  d?eAd@edz  d(eHe4e4f   fdA„ZIddddBœd7e4d1e4eJe4   z  dz  d<e4d=e4dCe4dz  dDe4eJe4   z  dz  dEeJe4   dz  d>eGdz  d?eAd(e8e4dFf   fdG„ZKd7e4d1e4eJe4   z  dz  dHe4dIe4dCe4dz  dDe4eJe4   z  dz  dEeJe4   dz  d(eHe4eJe4   f   fdJ„ZLdKe4d(e4fdL„ZMddddBœdKe4d7e4d1e4eJe4   z  dz  d<e4d=e4dCe4dz  dDe4eJe4   z  dz  dEeJe4   dz  d>eGdz  d?eAd(eHe4eJe4   f   fdM„ZNddddBœdKe4d7e4d1e4eJe4   z  dz  d<e4d=e4dCe4dz  dDe4eJe4   z  dz  dEeJe4   dz  d>eGdz  d?eAd(eHe4eJe4   f   fdN„ZOd.ee6   d6ee4e7f   d7e4dz  d0ee4e8e4e9f   f   dz  d(e;f
dO„ZPd9ed.ee6   d7e4dz  d0ee4e8e4e9f   f   dz  d(e;f
dP„ZQdQZRee5dR<   dSZSee5dT<   dUZTee5dV<   dWZUee5dX<   dYZVee5dZ<   d[ZWee5d\<   d]ZXee5d^<   d_ZYee5d`<   daZZee5db<   dcZ[ee5dd<   deZ\ee5df<   dgZ]ee5dh<   diZ^ee5dj<   d'e<d(e-fdk„Z_d6ee4e7f   dDe4d(e)fdl„Z`d.ee<   d6ee4e7f   d(e;fdm„Zad9ed.ee<   d(e;fdn„Zb	 	 	 	 	 d{d9edz  dKe4d7e4d1e4eJe4   z  dz  d0ee4e8e4e9f   f   dz  d<e4dz  d=e4dz  dCe4dz  dDe4eJe4   z  dz  doeGdpeGdEeJe4   dz  dqeee6   ge-f   dz  d>eGdz  d?eAdreee6   gee8e4e8e4e9f   f      f   dz  d(e,f"ds„Zcdtee&   duee=   d6ee4e7f   d0ee4e8e4e9f   f   dz  d(df
dv„Zd	 	 	 	 d|d9edz  dKe4d7e4d1e4eJe4   z  dz  d0ee4e8e4e9f   f   dz  d<e4dz  d=e4dz  dCe4dz  dDe4eJe4   z  dz  dEeJe4   dz  d>eGdz  dweAd?eAd(e,fdx„Zey)}é    N)Ú	AwaitableÚCallableÚMappingÚSequence)ÚSet)ÚdatetimeÚ	timedeltaÚtimezone)ÚSimpleNamespace)ÚTYPE_CHECKINGÚFinalÚProtocol)ÚHTTPExceptionÚstatus)Ú	TypedDict)Úverbose_proxy_logger)ÚPTU_SENTINEL_API_KEY)ÚCommonProxyErrors)Úis_ptu_cost_attribution_enabled)ÚPrismaClient)Ú"DeletedVerificationTokenRepository)ÚVerificationTokenRepository)	ÚBreakdownMetricsÚDailySpendDataÚDailySpendMetadataÚGroupedDataÚKeyMetadataÚKeyMetricWithMetadataÚMetricWithMetadataÚSpendAnalyticsPaginatedResponseÚSpendMetrics)Ú LiteLLM_DeletedVerificationToken)ÚLiteLLM_VerificationTokenÚLiteLLM_DailyUserSpendÚLiteLLM_DailyTeamSpendÚLiteLLM_DailyOrganizationSpendÚLiteLLM_DailyEndUserSpendÚLiteLLM_DailyAgentSpendÚLiteLLM_DailyTagSpend)Úlitellm_dailyuserspendÚlitellm_dailyteamspendÚlitellm_dailyorganizationspendÚlitellm_dailyenduserspendÚlitellm_dailyagentspendÚlitellm_dailytagspendÚ_PRISMA_TO_PG_TABLEc                   óâ  — e Zd Zedefd„«       Zedefd„«       Zededz  fd„«       Zededz  fd„«       Zededz  fd„«       Z	ededz  fd„«       Z
ededz  fd	„«       Zedefd
„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zedefd„«       Zy)ÚDailySpendRecordÚreturnc                  ó   — y ©N© ©Úselfs    ú}/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/proxy/management_endpoints/common_daily_activity.pyÚdatezDailySpendRecord.date4   s   € Øó    c                  ó   — y r5   r6   r7   s    r9   Úapi_keyzDailySpendRecord.api_key7   ó   € Ø!r;   Nc                  ó   — y r5   r6   r7   s    r9   ÚmodelzDailySpendRecord.model:   ó   € Ø#&r;   c                  ó   — y r5   r6   r7   s    r9   Úmodel_groupzDailySpendRecord.model_group=   s   € Ø),r;   c                  ó   — y r5   r6   r7   s    r9   Úcustom_llm_providerz$DailySpendRecord.custom_llm_provider@   ó   € Ø14r;   c                  ó   — y r5   r6   r7   s    r9   Úmcp_namespaced_tool_namez)DailySpendRecord.mcp_namespaced_tool_nameC   s   € Ø69r;   c                  ó   — y r5   r6   r7   s    r9   ÚendpointzDailySpendRecord.endpointF   ó   € Ø&)r;   c                  ó   — y r5   r6   r7   s    r9   Úprompt_tokenszDailySpendRecord.prompt_tokensI   s   € Ø$'r;   c                  ó   — y r5   r6   r7   s    r9   Úcompletion_tokensz"DailySpendRecord.completion_tokensL   s   € Ø(+r;   c                  ó   — y r5   r6   r7   s    r9   ÚspendzDailySpendRecord.spendO   r>   r;   c                  ó   — y r5   r6   r7   s    r9   Úcache_read_input_tokensz(DailySpendRecord.cache_read_input_tokensR   s   € Ø.1r;   c                  ó   — y r5   r6   r7   s    r9   Úcache_creation_input_tokensz,DailySpendRecord.cache_creation_input_tokensU   ó   € Ø25r;   c                  ó   — y r5   r6   r7   s    r9   Úcompression_saved_tokensz)DailySpendRecord.compression_saved_tokensX   s   € Ø/2r;   c                  ó   — y r5   r6   r7   s    r9   Úcompression_savings_spendz*DailySpendRecord.compression_savings_spend[   rV   r;   c                  ó   — y r5   r6   r7   s    r9   Úprompt_caching_savings_spendz-DailySpendRecord.prompt_caching_savings_spend^   s   € Ø58r;   c                  ó   — y r5   r6   r7   s    r9   Ú&gateway_injected_caching_savings_spendz7DailySpendRecord.gateway_injected_caching_savings_spenda   s   € Ø?Br;   c                  ó   — y r5   r6   r7   s    r9   Úautorouter_savings_spendz)DailySpendRecord.autorouter_savings_spendd   rF   r;   c                  ó   — y r5   r6   r7   s    r9   Úapi_requestszDailySpendRecord.api_requestsg   rA   r;   c                  ó   — y r5   r6   r7   s    r9   Úsuccessful_requestsz$DailySpendRecord.successful_requestsj   s   € Ø*-r;   c                  ó   — y r5   r6   r7   s    r9   Úfailed_requestsz DailySpendRecord.failed_requestsm   rK   r;   )Ú__name__Ú
__module__Ú__qualname__ÚpropertyÚstrr:   r=   r@   rC   rE   rH   rJ   ÚintrM   rO   ÚfloatrQ   rS   rU   rX   rZ   r\   r^   r`   rb   rd   rf   r6   r;   r9   r2   r2   3   s’  „ ØØ�cÒó ØàØ!˜Ò!ó Ø!àØ&�s˜T‘zÒ&ó Ø&àØ,˜S 4™ZÒ,ó Ø,àØ4 S¨4¡ZÒ4ó Ø4àØ9¨#°©*Ò9ó Ø9àØ)˜# ™*Ò)ó Ø)àØ'˜sÒ'ó Ø'àØ+ 3Ò+ó Ø+àØ!�uÒ!ó Ø!àØ1¨Ò1ó Ø1àØ5¨SÒ5ó Ø5àØ2¨#Ò2ó Ø2àØ5¨5Ò5ó Ø5àØ8¨eÒ8ó Ø8àØB¸ÒBó ØBàØ4¨%Ò4ó Ø4àØ&˜cÒ&ó Ø&àØ- SÒ-ó Ø-àØ) Ò)ó Ù)r;   r2   c                   ó.   — e Zd ZU edz  ed<   edz  ed<   y)Ú_KeyMetadataDictNÚ	key_aliasÚteam_id)rg   rh   ri   rk   Ú__annotations__r6   r;   r9   ro   ro   q   s   … Ø�T‰zÓØ�4‰ZÔr;   ro   F)Útotalc                   ó(   — e Zd ZU ee   ed<   eed<   y)Ú_AggregatedSpendDataÚresultsÚtotalsN)rg   rh   ri   Úlistr   rr   r!   r6   r;   r9   ru   ru   y   s   … Ø�.Ñ!Ó!ØÔr;   ru   c                   óR  — e Zd ZU eed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   eed	<   edz  ed
<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   edz  ed<   y)Ú_GroupingSetsRowr:   Nr=   r@   rC   rE   rH   rJ   Úgroup_levelrQ   rM   rO   rS   rU   rX   rZ   r\   r^   r`   rb   rd   rf   )rg   rh   ri   rk   rr   rl   rm   r6   r;   r9   rz   rz   ~   sË   … Ø
ƒIØ�4‰ZÓØ�‰:ÓØ�t‘ÓØ˜t™Ó#Ø! D™jÓ(Ø�D‰jÓØÓØ�4‰<ÓØ˜‘:ÓØ˜T‘zÓ!Ø  4™ZÓ'Ø!$ t¡Ó+Ø! D™jÓ(Ø$ t™|Ó+Ø"'¨$¡,Ó.Ø,1°D©LÓ8Ø# d™lÓ*Ø˜‘*ÓØ˜t™Ó#Ø˜4‘ZÔr;   rz   c                   ó(   — e Zd ZU edz  ed<   eed<   y)Ú_EntityRollupRowNÚ	entity_idÚapi_key_rolled)rg   rh   ri   rk   rr   rl   r6   r;   r9   r}   r}   –   s   … Ø�T‰zÓØÔr;   r}   Úrecordr3   c                 óD   — t        | dd«      xs d}|syt        «       sy|S )a2  Flat cost a daily row reports, which is zero unless PTU cost attribution is enabled.

    Both read paths funnel through here: the paginated path reads the ``ptu_flat_cost``
    column straight off the row, and the aggregated path reads the SUM() alias. Rows an
    operator accrued during an earlier opt-in stay in the table, so the gate lives on the
    read rather than on the query that produced the rows.

    The row is checked before the flag because this runs once per metric accumulation, and
    a record fans out across roughly a dozen breakdowns. The flag reads through the secret
    manager, uncached, so consulting it for every accumulation put thousands of lookups on
    a shared endpoint that made none before. Only a row actually carrying flat cost, which
    is a sentinel row, reaches it now.
    Úptu_flat_costNç        )Úgetattrr   )r€   Úraws     r9   Ú_reported_flat_costr†   ›   s+   € ô ˜ °$Ó7Ò>¸3€CÙØÜ*Ô,ØØ€Jr;   Úexisting_metricsc                 ó  — |j                   xs d}|j                  xs d}| xj                  |j                  xs dz  c_        | xj                  t	        |«      z  c_        | xj                   |z  c_         | xj                  |z  c_        | xj
                  ||z   z  c_        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_	        | xj                  |j                  xs dz  c_
        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_        | xj                  |j                  xs dz  c_        | S )a  Update metrics with new record data.

    Rollup rows can carry None for numeric fields when SUM() spans zero rows
    (e.g. a key with no spend), so coalesce to 0 before accumulating to avoid
    a TypeError. Mirrors the handling in ``_record_to_spend_metrics``.
    r   rƒ   )rM   rO   rQ   Ú	flat_costr†   Útotal_tokensrS   rU   rX   rZ   r\   r^   r`   rb   rd   rf   )r‡   r€   rM   rO   s       r9   Úupdate_metricsr‹   ±   s¹  € ð "×/Ñ/Ò4°1€MØ%×7Ñ7Ò<¸1ÐØ×Ò˜fŸl™lÒ1¨cÑ1ÕØ×ÒÔ"5°fÓ"=Ñ=ÕØ×"Ò" mÑ3Õ"Ø×&Ò&Ð*;Ñ;Õ&Ø×!Ò! ]Ð5FÑ%FÑFÕ!Ø×,Ò,°×0NÑ0NÒ0SÐRSÑSÕ,Ø×0Ò0°F×4VÑ4VÒ4[ÐZ[Ñ[Õ0Ø×-Ò-°×1PÑ1PÒ1UÐTUÑUÕ-Ø×.Ò.°&×2RÑ2RÒ2WÐVWÑWÕ.Ø×1Ò1°V×5XÑ5XÒ5]Ð\]Ñ]Õ1Ø×;Ò;Ø×5Ñ5Ò:¸ñÕ;ð ×-Ò-°×1PÑ1PÒ1UÐTUÑUÕ-Ø×!Ò! V×%8Ñ%8Ò%=¸AÑ=Õ!Ø×(Ò(¨F×,FÑ,FÒ,KÈ!ÑKÕ(Ø×$Ò$¨×(>Ñ(>Ò(CÀ!ÑCÕ$ØÐr;   Útagc                 óŒ   — | sy| j                  «       j                  «       }|j                  d«      xs |j                  d«      S )z>Determine whether a tag should be treated as a User-Agent tag.Fzuser-agent:zuser agent:)ÚstripÚlowerÚ
startswith)rŒ   Únormalized_tags     r9   Ú_is_user_agent_tagr’   Î   s>   € áØØŸI™I›K×-Ñ-Ó/€NØ×$Ñ$ ]Ó3Ò_°~×7PÑ7PÐQ^Ó7_Ð_r;   Úrecordsc                 ó$  — i }| D ]]  }t        |dd«      }|sŒt        |dd«      }t        |«      rŒ,|j                  |«      }|�|j                  |j                  kD  sŒY|||<   Œ_ t	        «       }|j                  «       D ]  }t        ||«       Œ |S )zÂ
    Deduplicate spend metrics for tags using request_id, ignoring User-Agent prefixed tags.

    Each unique request_id contributes at most one record (the tag with max spend) to metadata.
    Ú
request_idNrŒ   )r„   r’   ÚgetrQ   r!   Úvaluesr‹   )r“   Údeduped_recordsr€   r•   Ú	tag_valueÚcurrent_bestÚmetadata_metricss          r9   Úcompute_tag_metadata_totalsrœ   Ö   s©   € ð ;=€OØò 1ˆÜ!(¨°¸tÓ!Dˆ
ÙØä˜F E¨4Ó0ˆ	Ü˜iÔ(Øà&×*Ñ*¨:Ó6ˆØÐ 6§<¡<°,×2DÑ2DÓ#DØ*0ˆO˜JÒ'ð1ô +›nÐØ!×(Ñ(Ó*ò 1ˆÜÐ'¨Õ0ð1àÐr;   Úentity_metadata_fieldr~   c                 ó8   — | r| j                  |«      nd}|�|S i S )zXThe metadata payload for one entity breakdown bucket, empty when the caller passed none.N)r–   )r�   r~   Ústoreds      r9   Ú_entity_metadatar    ð   s+   € ñ
 =RÐ)×-Ñ-¨iÔ8ÐW[€FØÐ'ˆ6Ð/¨RÐ/r;   Ú	breakdownÚmodel_metadataÚprovider_metadataÚapi_key_metadataÚentity_id_fieldc           
      ó(  — |j                   t        k(  }|r|j                  xs |j                  n|j                  }|r@|| j                  vr2t        t        «       |j                  |i «      ¬«      | j                  |<   |�rXt        | j                  |   j                  |«      | j                  |   _	        |�s |j                   | j                  |   j                  vr˜t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j                  |   j                  |j                   <   t        | j                  |   j                  |j                      j                  |«      | j                  |   j                  |j                      _	        |j                  xs |j                  }	|	r@|	| j                  vr2t        t        «       |j                  |	i «      ¬«      | j                  |	<   |	�rXt        | j                  |	   j                  |«      | j                  |	   _	        |�s |j                   | j                  |	   j                  vr˜t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j                  |	   j                  |j                   <   t        | j                  |	   j                  |j                      j                  |«      | j                  |	   j                  |j                      _	        |j                  �rÕ|j                  | j                  vr,t        t        «       i ¬«      | j                  |j                  <   t        | j                  |j                     j                  |«      | j                  |j                     _	        |j                   | j                  |j                     j                  vr¢t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j                  |j                     j                  |j                   <   t        | j                  |j                     j                  |j                      j                  |«      | j                  |j                     j                  |j                      _	        |�s¥|j                   xs d}
|
| j"                  vr2t        t        «       |j                  |
i «      ¬«      | j"                  |
<   t        | j"                  |
   j                  |«      | j"                  |
   _	        |j                   | j"                  |
   j                  vr˜t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j"                  |
   j                  |j                   <   t        | j"                  |
   j                  |j                      j                  |«      | j"                  |
   j                  |j                      _	        |j$                  �rÕ|j$                  | j&                  vr,t        t        «       i ¬«      | j&                  |j$                  <   t        | j&                  |j$                     j                  |«      | j&                  |j$                     _	        |j                   | j&                  |j$                     j                  vr¢t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j&                  |j$                     j                  |j                   <   t        | j&                  |j$                     j                  |j                      j                  |«      | j&                  |j$                     j                  |j                      _	        |sì|j                   | j(                  vr‹t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j(                  |j                   <   t        | j(                  |j                      j                  |«      | j(                  |j                      _	        |�r¥t+        ||d«      }|r|nd}|| j,                  vr,t        t        «       t/        ||«      ¬«      | j,                  |<   t        | j,                  |   j                  |«      | j,                  |   _	        |�s |j                   | j,                  |   j                  vr˜t        t        «       t        |j                  |j                   i «      j                  dd«      |j                  |j                   i «      j                  dd«      ¬«      ¬«      | j,                  |   j                  |j                   <   t        | j,                  |   j                  |j                      j                  |«      | j,                  |   j                  |j                      _	        | S )a!  Updates breakdown metrics for a single record using the existing update_metrics function.

    PTU sentinel rows (api_key == PTU_SENTINEL_API_KEY) add their flat cost to every
    parent bucket but never appear as an api_key row, and are kept out of the
    per-request provider breakdown.©ÚmetricsÚmetadatarp   Nrq   ©rp   rq   ÚunknownÚ
Unassigned)r=   r   rC   r@   Úmodelsr   r!   r–   r‹   r¨   Úapi_key_breakdownr   r   Úmodel_groupsrH   Úmcp_serversrE   Ú	providersrJ   Ú	endpointsÚapi_keysr„   Úentitiesr    )r¡   r€   r¢   r£   r¤   r¥   r�   Úis_ptu_sentinelÚ	model_keyÚmodel_group_keyÚproviderÚentity_values               r9   Úupdate_breakdown_metricsrº   ù   s}	  € ð $Ÿ^™^Ô/CÑC€Oñ @O˜×*Ñ*Ò:¨f¯lªlÐTZ×T`ÑT`€Iñ �Y i×&6Ñ&6Ñ6Ü&8Ü “NØ#×'Ñ'¨	°2Ó6ô'
ˆ	×Ñ˜Ñ#ò Ü.<¸Y×=MÑ=MÈiÑ=X×=`Ñ=`ÐbhÓ.iˆ	×Ñ˜Ñ#Ô+âà�~‰~ Y×%5Ñ%5°iÑ%@×%RÑ%RÑRÜPeÜ(›NÜ(Ø"2×"6Ñ"6°v·~±~ÀrÓ"J×"NÑ"NÈ{Ð\`Ó"aØ 0× 4Ñ 4°V·^±^ÀRÓ H× LÑ LÈYÐX\Ó ]ôôQ�	× Ñ  Ñ+×=Ñ=¸f¿n¹nÑMô UcØ× Ñ  Ñ+×=Ñ=¸f¿n¹nÑM×UÑUØóUˆI×Ñ˜YÑ'×9Ñ9¸&¿.¹.ÑIÔQð $×/Ñ/Ò?°6·<±<€OÙ˜?°)×2HÑ2HÑHÜ2DÜ “NØ#×'Ñ'¨¸Ó<ô3
ˆ	×Ñ˜Ñ/ò Ü:HØ×"Ñ" ?Ñ3×;Ñ;¸Vó;
ˆ	×Ñ˜Ñ/Ô7ò à�~‰~ Y×%;Ñ%;¸OÑ%L×%^Ñ%^Ñ^Ü\qÜ(›NÜ(Ø"2×"6Ñ"6°v·~±~ÀrÓ"J×"NÑ"NÈ{Ð\`Ó"aØ 0× 4Ñ 4°V·^±^ÀRÓ H× LÑ LÈYÐX\Ó ]ôô]�	×&Ñ& Ñ7×IÑIÈ&Ï.É.ÑYô aoØ×&Ñ& Ñ7×IÑIÈ&Ï.É.ÑY×aÑaØóaˆI×"Ñ" ?Ñ3×EÑEÀfÇnÁnÑUÔ]ð
 ×&Ó&Ø×*Ñ*°)×2GÑ2GÑGÜEWÜ$›ØôFˆI×!Ñ! &×"AÑ"AÑBô JXØ×!Ñ! &×"AÑ"AÑB×JÑJÈFóJ
ˆ	×Ñ˜f×=Ñ=Ñ>ÔFð
 �>‰> ×!6Ñ!6°v×7VÑ7VÑ!W×!iÑ!iÑiä%Ü(›NÜ(Ø"2×"6Ñ"6°v·~±~ÀrÓ"J×"NÑ"NÈ{Ð\`Ó"aØ 0× 4Ñ 4°V·^±^ÀRÓ H× LÑ LÈYÐX\Ó ]ôôð ×!Ñ! &×"AÑ"AÑB×TÑTÐU[×UcÑUcÑdô #Ø×!Ñ! &×"AÑ"AÑB×TÑTÐU[×UcÑUcÑd×lÑlØó
ð 	×Ñ˜f×=Ñ=Ñ>×PÑPØ�N‰Nñ	
ä
ò
 à ×4Ñ4ÒA¸	ˆØ˜9×.Ñ.Ñ.Ü,>Ü$›Ø*×.Ñ.¨x¸Ó<ô-ˆI×Ñ Ñ)ô 1?¸y×?RÑ?RÐS[Ñ?\×?dÑ?dÐflÓ0mˆ	×Ñ˜HÑ%Ô-ð �>‰> ×!4Ñ!4°XÑ!>×!PÑ!PÑPÜNcÜ$›Ü$Ø.×2Ñ2°6·>±>À2ÓF×JÑJÈ;ÐX\Ó]Ø,×0Ñ0°·±ÀÓD×HÑHÈÐTXÓYôôOˆI×Ñ Ñ)×;Ñ;¸F¿N¹NÑKô SaØ×Ñ Ñ)×;Ñ;¸F¿N¹NÑK×SÑSØóS
ˆ	×Ñ˜HÑ%×7Ñ7¸¿¹ÑGÔOð ‡ƒØ�?‰? )×"5Ñ"5Ñ5Ü3EÜ$›Øô4ˆI×Ñ §¡Ñ0ô 8FØ×Ñ §¡Ñ0×8Ñ8¸&ó8
ˆ	×Ñ˜FŸO™OÑ,Ô4ð
 �>‰> ×!4Ñ!4°V·_±_Ñ!E×!WÑ!WÑWÜUjÜ$›Ü$Ø.×2Ñ2°6·>±>À2ÓF×JÑJÈ;ÐX\Ó]Ø,×0Ñ0°·±ÀÓD×HÑHÈÐTXÓYôôVˆI×Ñ §¡Ñ0×BÑBÀ6Ç>Á>ÑRô ZhØ×Ñ §¡Ñ0×BÑBÀ6Ç>Á>ÑR×ZÑZØóZ
ˆ	×Ñ˜FŸO™OÑ,×>Ñ>¸v¿~¹~ÑNÔVñ
 à�>‰> ×!3Ñ!3Ñ3Ü1FÜ$›Ü$Ø.×2Ñ2°6·>±>À2ÓF×JÑJÈ;ÐX\Ó]Ø,×0Ñ0°·±ÀÓD×HÑHÈÐTXÓYôô2ˆI×Ñ˜vŸ~™~Ñ.ô 6DÀI×DVÑDVÐW]×WeÑWeÑDf×DnÑDnÐpvÓ5wˆ	×Ñ˜6Ÿ>™>Ñ*Ô2ò Ü˜v ¸Ó=ˆÙ'3‘|¸ˆØ˜y×1Ñ1Ñ1Ü/AÜ$›Ü)Ð*?ÀÓNô0ˆI×Ñ˜|Ñ,ô 4BÀ)×BTÑBTÐUaÑBb×BjÑBjÐlrÓ3sˆ	×Ñ˜<Ñ(Ô0âà�~‰~ Y×%7Ñ%7¸Ñ%E×%WÑ%WÑWÜUjÜ(›NÜ(Ø"2×"6Ñ"6°v·~±~ÀrÓ"J×"NÑ"NÈ{Ð\`Ó"aØ 0× 4Ñ 4°V·^±^ÀRÓ H× LÑ LÈYÐX\Ó ]ôôV�	×"Ñ" <Ñ0×BÑBÀ6Ç>Á>ÑRô ZhØ×"Ñ" <Ñ0×BÑBÀ6Ç>Á>ÑR×ZÑZØóZˆI×Ñ˜|Ñ,×>Ñ>¸v¿~¹~ÑNÔVð
 Ðr;   Úprisma_clientr³   c              ƒ   óš  K  — t        | «      j                  j                  ddt        |«      ii¬«      ƒ d{  –—† }|D �ci c]&  }|j                  |j
                  |j                  dœ“Œ( }}|t        |j                  «       «      z
  }|r}	 t        | «      j                  j                  ddt        |«      iiddi¬«      ƒ d{  –—† }|D ]7  }|j                  |vsŒ|j
                  |j                  dœ||j                  <   Œ9 	 |S |S 7 ŒÒc c}w 7 ŒL# t        $ r+}t        j                  d	t        |«      |«       Y d}~|S d}~ww xY w­w)
zèGet api key metadata, falling back to deleted keys table for keys not found in active table.

    This ensures that key_alias and team_id are preserved in historical activity logs
    even after a key is deleted or regenerated.
    ÚtokenÚin©ÚwhereNrª   Ú
deleted_atÚdesc)rÀ   Úorderz<Failed to fetch deleted key metadata for %d missing keys: %s)r   ÚtableÚ	find_manyrx   r½   rp   rq   ÚsetÚkeysr   Ú	Exceptionr   ÚwarningÚlen)r»   r³   Úkey_recordsÚkÚresultÚmissing_keysÚdeleted_key_recordsÚes           r9   Úget_api_key_metadatarÑ   º  sf  è ø€ ô <WÐWdÓ;e×;kÑ;k×;uÑ;uØ˜œt H›~Ð.Ð/ð <vó <÷ 6€Kð LWö2ØFGˆ�‰˜qŸ{™{°q·y±yÑAÑAð2€Fð 2ð
 #¤S¨¯©«Ó%7Ñ7€LÙð	ô 9¸ÓG×MÑM×WÑWØ ¤t¨LÓ'9Ð :Ð;Ø# VÐ,ð Xó ÷ ð  ð )ò �Ø—7‘7 &Ò(à%&§[¡[Ø#$§9¡9ñ'�F˜1Ÿ7™7’Oñð €Mˆ6€Mð?6úò2ðùô ò 	Ü ×(Ñ(ØNÜ�LÓ!Ø÷ð ð €Mûð	üsc   ‚6E¸D¹EÁ+DÁ, EÂ8D ÃDÃD Ã(D ÄEÄEÄD Ä	EÄ EÄ=EÅEÅEÚ
start_dateÚend_dateÚtimezone_offset_minutesÚinclude_current_utc_dayÚutc_nowc                 ó  — |r|€| |fS |�|n"t        j                  t        j                  «      }|t	        |¬«      z
  j                  «       j                  «       }||k  r| |fS | t        ||j                  «       j                  «       «      fS )a9  
    Map a caller-local date range onto UTC bucket keys, extending only the live end.

    The aggregation table (e.g. LiteLLM_DailyUserSpend) stores spend in whole-UTC-day
    buckets keyed on date as YYYY-MM-DD. Any conversion of an interior local-day
    boundary using only date arithmetic must round to whole UTC days, allowing up to
    24h of slop at each boundary. A previous implementation expanded the SQL range by
    an extra full UTC day on whichever side the offset pointed, which pulled in 24h of
    unrelated bucket data per boundary and produced approximately 100% over-counting on
    single-day queries (e.g. IST May 29 returning UTC May 28 + UTC May 29 in full).
    Sums of single-day queries then exceeded the equivalent multi-day aggregate, which
    is mathematically impossible. Historical dates therefore stay a pass-through: the
    local date is the UTC bucket key, trading boundary slop for monotonic, additive
    results. Hour-level buckets or pro-rata weighting would fix that properly; both
    require data the current schema does not store.

    The end boundary is different when the range reaches the caller's current day. A
    caller west of UTC asking for a range ending "today" is asking for data up to now,
    but once UTC has rolled past their local midnight, everything they sent since then
    sits in the next UTC bucket, which the pass-through excludes: a PT dashboard goes
    stale every evening from 5pm until local midnight, showing $0 for anything that
    only started accruing that evening. Extending such a range to today's UTC bucket
    cannot over-count, because the only part of that bucket outside the caller's range
    is the future, and the future is empty. ``timezone_offset_minutes`` follows the
    JS ``Date.getTimezoneOffset`` convention: UTC minus local, positive west of UTC.

    The extension is strictly opt-in via ``include_current_utc_day`` so a consumer
    whose axis or reconciliation expects the range to stop at the requested end date
    keeps today's byte-for-byte behaviour; the cost optimization dashboard opts in.
    )Úminutes)r   Únowr
   Úutcr	   r:   Ú	isoformatÚmax)rÒ   rÓ   rÔ   rÕ   rÖ   rÙ   Úcaller_local_todays          r9   Ú_adjust_dates_for_timezonerÞ   å  sŠ   € ñJ #Ð&=Ð&EØ˜8Ð#Ð#Ø#Ð/‘´X·\±\Ä(Ç,Á,Ó5O€CØ!$¤yÐ9PÔ'QÑ!Q× WÑ WÓ Y× cÑ cÓ eÐØÐ$Ò$Ø˜8Ð#Ð#Ø”s˜8 S§X¡X£Z×%9Ñ%9Ó%;Ó<Ð<Ð<r;   )Úexclude_entity_idsrÔ   rÕ   r@   r=   rß   Ú_WhereValuec        	         ó,  — t        ||||«      \  }	}
d|	|
dœi}|r||d<   |rt        |t        «      rd|i|d<   n||d<   |�t        |t        «      rd|i|| <   nd|i|| <   |r2|j                  | i «      }t        |t        «      rd|i}d|i|d<   ||| <   |S )z5Build prisma where clause for daily activity queries.r:   )ÚgteÚlter@   r¾   r=   ÚequalsÚnot)rÞ   Ú
isinstancerx   r–   rk   )r¥   r~   rÒ   rÓ   r@   r=   rß   rÔ   rÕ   Úadjusted_startÚadjusted_endÚwhere_conditionsÚcurrents                r9   Ú_build_where_conditionsrë     sæ   € ô $>Ø�HÐ5Ð7Nó$Ñ €N�Lð
 	Ø!Øñ
ð7Ðñ Ø$)Ð˜Ñ!ÙÜ�gœtÔ$Ø+/°¨/Ð˜YÒ'à*1Ð˜YÑ'àÐÜ�i¤Ô&Ø15°yÐ0AÐ˜_Ò-à19¸9Ð0EÐ˜_Ñ-áØ/×3Ñ3°OÀRÓHˆÜ�gœsÔ#Ø Ð)ˆGØÐ 2Ð3ˆ�‰Ø,3Ð˜Ñ)àÐr;   rç   rè   c                 óÐ  ‡
— g }g }dŠ
|j                  d‰
› �«       |j                  |«       ‰
dz  Š
|j                  d‰
› �«       |j                  |«       ‰
dz  Š
|�µt        |t        «      rx|rddj                  ˆ
fd„t	        t        |«      «      D «       «      }	|j                  d| › d|	› d�«       |j                  |«       ‰
t        |«      z  Š
n?|j                  d	«       n-|j                  d| › d
‰
› �«       |j                  |«       ‰
dz  Š
|rcdj                  ˆ
fd„t	        t        |«      «      D «       «      }	|j                  d| › d|	› d�«       |j                  |«       ‰
t        |«      z  Š
|r*|j                  d‰
› �«       |j                  |«       ‰
dz  Š
t        |t        «      ru|radj                  ˆ
fd„t	        t        |«      «      D «       «      }	|j                  d|	› d�«       |j                  |«       ‰
t        |«      z  Š
n>|j                  d	«       n,|r*|j                  d‰
› �«       |j                  |«       ‰
dz  Š
dj                  |«      |fS )zFBuild the WHERE clause and $N params shared by the aggregated queries.é   z	date >= $z	date <= $z, c              3   ó.   •K  — | ]  }d ‰|z   › �–— Œ y­w©ú$Nr6   ©Ú.0ÚiÚps     €r9   ú	<genexpr>z1_build_aggregated_where_clause.<locals>.<genexpr>`  s   øè ø€ Ò(T¸¨1¨Q°©U¨G¬Ñ(Tùó   ƒú"z" IN (ú)ÚFALSEz" = $c              3   ó.   •K  — | ]  }d ‰|z   › �–— Œ y­wrï   r6   rñ   s     €r9   rõ   z1_build_aggregated_where_clause.<locals>.<genexpr>m  s   øè ø€ Ò U° 1 Q¨¡U G¤Ñ Uùrö   z
" NOT IN (z	model = $c              3   ó.   •K  — | ]  }d ‰|z   › �–— Œ y­wrï   r6   rñ   s     €r9   rõ   z1_build_aggregated_where_clause.<locals>.<genexpr>{  s   øè ø€ Ò$N°Q q¨¨Q©¨¤[Ñ$Nùrö   zapi_key IN (zapi_key = $z AND )Úappendræ   rx   ÚjoinÚrangerÊ   Úextend)r¥   r~   rç   rè   r@   r=   rß   Úsql_conditionsÚ
sql_paramsÚplaceholdersrô   s             @r9   Ú_build_aggregated_where_clauser  D  sZ  ø€ ð (*€NØ#%€JØ	€Að ×Ñ˜I a S˜/Ô*Ø×Ñ�nÔ%Øˆ�F€Aà×Ñ˜I a S˜/Ô*Ø×Ñ�lÔ#Øˆ�F€Að ÐÜ�i¤Ô&ÙØ#Ÿy™yÓ(T¼eÄCÈ	ÃNÓ>SÔ(TÓT�Ø×%Ñ%¨¨/Ð):¸&ÀÀÈaÐ&PÔQØ×!Ñ! )Ô,Ø”S˜“^Ñ#‘à×%Ñ% gÕ.à×!Ñ! A oÐ%6°e¸A¸3Ð"?Ô@Ø×Ñ˜iÔ(Ø�‰FˆAñ Ø—y‘yÓ U´e¼CÐ@RÓ<SÓ6TÔ UÓUˆØ×Ñ  /Ð!2°*¸\¸NÈ!ÐLÔMØ×ÑÐ,Ô-Ø	ŒSÐ#Ó$Ñ$ˆñ Ø×Ñ 	¨!¨˜oÔ.Ø×Ñ˜%Ô Ø	ˆQ‰ˆô �'œ4Ô ÙØŸ9™9Ó$N¼%ÄÀGÃÓ:MÔ$NÓNˆLØ×!Ñ! L°°¸aÐ"@ÔAØ×Ñ˜gÔ&Ø”�W“Ñ‰Aà×!Ñ! 'Õ*Ù	Ø×Ñ ¨A¨3Ð/Ô0Ø×Ñ˜'Ô"Ø	ˆQ‰ˆà�<‰<˜Ó'¨Ð3Ð3r;   Ú
table_namec                 ó   — | dk(  ryy)zšOnly LiteLLM_DailyTeamSpend carries ptu_flat_cost; other daily tables emit a
    constant zero so the SpendMetrics.flat_cost response shape stays uniform.r+   z*SUM(ptu_flat_cost)::float AS ptu_flat_costz0::float AS ptu_flat_costr6   )r  s    r9   Ú_ptu_flat_cost_selectr  ‰  s   € ð Ð-Ò-Ø;Ø&r;   c        
   	      óÊ   — t         j                  | «      }
|
€t        d| › �«      ‚t        ||||	«      \  }}t	        |||||||¬«      \  }}dt        | «      › d|
› d|› d�}||fS )uÚ  Build a parameterized SQL GROUP BY query for aggregated daily activity.

    Groups by (date, api_key, model, model_group, custom_llm_provider,
    mcp_namespaced_tool_name, endpoint) with SUMs on all metric columns.
    The entity_id column is intentionally omitted from GROUP BY to collapse
    rows across entities â€” this is where the biggest row reduction comes from.

    Returns:
        Tuple of (sql_query, params_list) ready for prisma_client.db.query_raw().
    úUnknown table name: ©r¥   r~   rç   rè   r@   r=   rß   aè  
        SELECT
            date,
            api_key,
            model,
            COALESCE(NULLIF(model_group, ''), model) AS model_group,
            custom_llm_provider,
            mcp_namespaced_tool_name,
            endpoint,
            GROUPING(date, api_key, model, COALESCE(NULLIF(model_group, ''), model),
                     custom_llm_provider, mcp_namespaced_tool_name,
                     endpoint) AS group_level,
            SUM(spend)::float AS spend,
            á‘  ,
            SUM(prompt_tokens)::bigint AS prompt_tokens,
            SUM(completion_tokens)::bigint AS completion_tokens,
            SUM(cache_read_input_tokens)::bigint AS cache_read_input_tokens,
            SUM(cache_creation_input_tokens)::bigint AS cache_creation_input_tokens,
            SUM(compression_saved_tokens)::bigint AS compression_saved_tokens,
            SUM(compression_savings_spend)::float AS compression_savings_spend,
            SUM(prompt_caching_savings_spend)::float AS prompt_caching_savings_spend,
            SUM(gateway_injected_caching_savings_spend)::float AS gateway_injected_caching_savings_spend,
            SUM(autorouter_savings_spend)::float AS autorouter_savings_spend,
            SUM(api_requests)::bigint AS api_requests,
            SUM(successful_requests)::bigint AS successful_requests,
            SUM(failed_requests)::bigint AS failed_requests
        FROM "ú"
        WHERE a9  
        GROUP BY GROUPING SETS (
            (date),
            (date, api_key),
            (date, model),
            (date, model, api_key),
            (date, COALESCE(NULLIF(model_group, ''), model)),
            (date, COALESCE(NULLIF(model_group, ''), model), api_key),
            (date, custom_llm_provider),
            (date, custom_llm_provider, api_key),
            (date, mcp_namespaced_tool_name),
            (date, mcp_namespaced_tool_name, api_key),
            (date, endpoint),
            (date, endpoint, api_key),
            ()
        )
    ©r0   r–   Ú
ValueErrorrÞ   r  r  ©r  r¥   r~   rÒ   rÓ   r@   r=   rß   rÔ   rÕ   Úpg_tablerç   rè   Úwhere_clauser  Ú	sql_querys                   r9   Ú_build_aggregated_sql_queryr  ‘  s¯   € ô. *×-Ñ-¨jÓ9€HØÐÜÐ/°
¨|Ð<Ó=Ð=ä#=Ø�HÐ5Ð7Nó$Ñ €N�Lô  >Ø'ØØ%Ø!ØØØ-ô Ñ€L�*ð,ô # :Ó.Ð/ð 0ð ˆjð Øˆnð ð7+€IðZ �jÐ Ð r;   c        
         óÜ   — t         j                  | «      }
|
€t        d| › �«      ‚t        ||||	«      \  }}t	        |||||||¬«      \  }}d|› dt        | «      › d|
› d|› d|› d|› d	�}||fS )
u  Per-entity companion to _build_aggregated_sql_query.

    Two rollup levels over the same WHERE clause â€” (date, entity) and
    (date, entity, api_key) â€” told apart by GROUPING(api_key): 1 when the
    api_key column is rolled up, 0 when it is part of the key.
    r  r	  z
        SELECT
            "zœ" AS entity_id,
            date,
            api_key,
            GROUPING(api_key) AS api_key_rolled,
            SUM(spend)::float AS spend,
            r
  r  z6
        GROUP BY GROUPING SETS (
            (date, "z"),
            (date, "z", api_key)
        )
    r  r  s                   r9   Ú_build_entity_rollup_sql_queryr  ö  sÏ   € ô& *×-Ñ-¨jÓ9€HØÐÜÐ/°
¨|Ð<Ó=Ð=ä#=Ø�HÐ5Ð7Nó$Ñ €N�Lô  >Ø'ØØ%Ø!ØØØ-ô Ñ€L�*ðàÐð ô
 # :Ó.Ð/ð 0ð ˆjð Øˆnð à$Ð%ð &Ø$Ð%ð &ð1€Ið8 �jÐ Ð r;   c           
      óô  — i }i }g }t        «       }i }| D ]l  }	|	j                  }
|
|vrt        «       t        «       dœ||
<   t        ||
   d   |	«      ||
   d<   t	        ||
   d   |	|||||¬«      ||
   d<   t        ||	«      }Œn |j                  «       D ]J  \  }
}|j                  t        t        j                  |
d«      j                  «       |d   |d   ¬«      «       ŒL |j                  d„ d¬	«       ||d
œS )N©r¨   r¡   r¨   r¡   )r¥   r�   ú%Y-%m-%d©r:   r¨   r¡   c                 ó   — | j                   S r5   ©r:   ©Úxs    r9   ú<lambda>z/_aggregate_spend_records_sync.<locals>.<lambda>g  ó
   € ˜qŸv™v€ r;   T©ÚkeyÚreverse©rv   rw   )r!   r:   r   r‹   rº   Úitemsrü   r   r   ÚstrptimeÚsort)r“   r¤   r¥   r�   r¢   r£   rv   Útotal_metricsÚgrouped_datar€   Údate_strÚdatas               r9   Ú_aggregate_spend_records_syncr*  :  s4  € ð ;=€NØ=?Ðà+-€GÜ “N€MØ24€Làò >ˆØ—;‘;ˆØ˜<Ñ'ä'›>Ü-Ó/ñ&ˆL˜Ñ"ô
 -;¸<ÈÑ;QÐR[Ñ;\Ð^dÓ,eˆ�XÑ˜yÑ)ä.FØ˜Ñ" ;Ñ/ØØØØØ+Ø"7ô/
ˆ�XÑ˜{Ñ+ô ' }°fÓ=‰ð)>ð, '×,Ñ,Ó.ò 
‰ˆ�$Ø�‰ÜÜ×&Ñ& x°Ó<×AÑAÓCØ˜Y™Ø˜{Ñ+ôõ	
ð
ð ‡L�LÑ%¨t€LÔ4à¨-Ñ8Ð8r;   c              ƒ   ó  K  — |D �ch c]/  }|j                   sŒ|j                   t        k7  sŒ$|j                   ’Œ1 }}i }|rt        | |«      ƒ d{  –—† }t        j                  t
        ||||¬«      ƒ d{  –—† S c c}w 7 Œ/7 Œ­w)zÁAggregate rows into DailySpendData list and total metrics.

    The per-row loop is offloaded to a worker thread via asyncio.to_thread so
    a large result set doesn't peg the event loop.
    N)r“   r¤   r¥   r�   )r=   r   rÑ   ÚasyncioÚ	to_threadr*  )r»   r“   r¥   r�   r€   r³   r¤   s          r9   Ú_aggregate_spend_recordsr.  l  s‹   è ø€ ð &-ö!Ø!°·³À6Ç>Á>ÔUiÓCiˆ�‹ð!€Hð !ð 57ÐÙÜ!5°mÀXÓ!N×NÐä×"Ñ"Ü%ØØ)Ø'Ø3ô÷ ð ùò!ð Oøðús7   ‚B‡A;™A;­A;»BÁB Á%BÁ6BÁ7
BÂBé   Ú_GROUP_GRAND_TOTALé?   Ú_GROUP_DATEé   Ú_GROUP_DATE_API_KEYé/   Ú_GROUP_DATE_MODELé   Ú_GROUP_DATE_MODEL_API_KEYé7   Ú_GROUP_DATE_MODEL_GROUPé   Ú_GROUP_DATE_MODEL_GROUP_API_KEYé;   Ú_GROUP_DATE_PROVIDERé   Ú_GROUP_DATE_PROVIDER_API_KEYé=   Ú_GROUP_DATE_MCPé   Ú_GROUP_DATE_MCP_API_KEYé>   Ú_GROUP_DATE_ENDPOINTé   Ú_GROUP_DATE_ENDPOINT_API_KEYc                 óÂ  — | j                   xs d}| j                  xs d}t        | j                  xs dt	        | «      ||||z   | j
                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d| j                  xs d¬«      S )zæBuild a SpendMetrics directly from one already-aggregated rollup row.

    SUM() over zero rows is SQL NULL, so rollup rows (notably the grand-total
    row, which Postgres emits even on an empty match) can carry None values.
    r   rƒ   )rQ   r‰   rM   rO   rŠ   rS   rU   rX   rZ   r\   r^   r`   rb   rd   rf   )rM   rO   r!   rQ   r†   rS   rU   rX   rZ   r\   r^   r`   rb   rd   rf   )r€   rM   rO   s      r9   Ú_record_to_spend_metricsrJ  Ÿ  sâ   € ð "×/Ñ/Ò4°1€MØ%×7Ñ7Ò<¸1ÐÜØ�l‰lÒ!˜cÜ% fÓ-Ø#Ø+Ø"Ð%6Ñ6Ø &× >Ñ >Ò CÀ!Ø$*×$FÑ$FÒ$KÈ!Ø!'×!@Ñ!@Ò!EÀAØ"(×"BÑ"BÒ"GÀaØ%+×%HÑ%HÒ%MÈAØ/5×/\Ñ/\Ò/aÐ`aØ!'×!@Ñ!@Ò!EÀAØ×(Ñ(Ò-¨AØ"×6Ñ6Ò;¸!Ø×.Ñ.Ò3°!ôð r;   c                 ó|   — | j                  |i «      }t        |j                  d«      |j                  d«      ¬«      S )Nrp   rq   rª   )r–   r   )r¤   r=   Úmetas      r9   Ú_key_metadatarM  º  s3   € Ø"×&Ñ& w°Ó3€DÜ §¡¨+Ó!6ÀÇÁÈÓ@SÔTÐTr;   c           
      ó¼  ‡‡— t        «       }i Šdt        dt        fˆfd„}dt        t        t        f   dt        dt         ddfd„}dt        t        t        f   d	t        d
t        dt         ddf
ˆfd„}| D �]p  }|j
                  }t        |«      }|j                  t        k(  }	|t        k(  r|}Œ:|t        k(  r| ||j                  «      d<   ŒY ||j                  «      d   }
|t        k(  rI|j                  sŒ„|	rŒ‡t        |t        ‰|j                  «      ¬«      |
j                  |j                  <   ŒÀ|t         k(  r,|j"                  sŒÖ ||
j$                  |j"                  |«       Œõ|t&        k(  rK|j"                  s�Œ|j                  s�Œ|	r�Œ ||
j$                  |j"                  |j                  |«       �ŒI|t(        k(  r.|j*                  s�Œ` ||
j,                  |j*                  |«       �Œ€|t.        k(  rK|j*                  s�Œ—|j                  s�Œ¥|	r�Œ© ||
j,                  |j*                  |j                  |«       �ŒÔ|t0        k(  r:|j3                  ddi¬«      }|j4                  xs d} ||
j6                  ||«       �Œ|t8        k(  rC|j                  s�Œ.|	r�Œ2|j4                  xs d} ||
j6                  ||j                  |«       �Œc|t:        k(  r.|j<                  s�Œz ||
j>                  |j<                  |«       �Œš|t@        k(  rG|j<                  s�Œ±|j                  s�Œ¿ ||
j>                  |j<                  |j                  |«       �Œê|tB        k(  r.|jD                  s�Œ ||
jF                  |jD                  |«       �Œ!|tH        k(  s�Œ,|jD                  s�Œ:|j                  s�ŒH ||
jF                  |jD                  |j                  |«       �Œs ‰jK                  «       D ��cg c];  \  }}tM        tO        jP                  |d«      j                  «       |d   |d   ¬«      ‘Œ= }}}|jS                  d„ d¬«       ||dœS c c}}w )uh  Build the response from rollup rows produced by the GROUPING SETS query.

    Each row carries a `group_level` bitmask (from Postgres GROUPING()) that
    identifies which rollup level it belongs to. We dispatch the row's
    pre-aggregated metrics straight into the matching bucket â€” no per-row
    summing in Python and no nested update_metrics calls.
    r(  r3   c                 ób   •— ‰j                  | «      }|€t        «       t        «       dœ}|‰| <   |S )Nr  )r–   r!   r   )r(  Úbucketr'  s     €r9   Úensure_datez:_aggregate_grouping_sets_records_sync.<locals>.ensure_dateÎ  s7   ø€ Ø%1×%5Ñ%5°hÓ%?ˆØˆ>Ü!-£Ô>NÓ>PÑQˆFØ%+ˆL˜Ñ"Øˆr;   Útargetr   r¨   Nc                 óZ   — | j                  |«      }|€t        |i ¬«      | |<   y ||_        y ©Nr§   )r–   r   r¨   )rR  r   r¨   Úexistings       r9   Úassign_metric_with_metadatazJ_aggregate_grouping_sets_records_sync.<locals>.assign_metric_with_metadataÕ  s-   € Ø Ÿ*™* S›/ˆØÐÜ,°WÀrÔJˆF�3ŠKà&ˆHÕr;   Ú
parent_keyr=   c                 ó¨   •— | j                  |«      }|€t        t        «       i ¬«      }|| |<   t        |t	        ‰|«      ¬«      |j
                  |<   y rT  )r–   r   r!   r   rM  r®   )rR  rW  r=   r¨   Úparentr¤   s        €r9   Úassign_api_key_breakdownzG_aggregate_grouping_sets_records_sync.<locals>.assign_api_key_breakdownÜ  sR   ø€ ð —‘˜JÓ'ˆØˆ>Ü'´³ÈÔLˆFØ!'ˆF�:ÑÜ,AØ¤mÐ4DÀgÓ&Nô-
ˆ× Ñ  Ò)r;   r¡   r§   r‰   rƒ   )Úupdater«   r  r  c                 ó   — | j                   S r5   r  r  s    r9   r  z7_aggregate_grouping_sets_records_sync.<locals>.<lambda>8  r  r;   Tr  r"  )*r!   rk   r   Údictr   r{   rJ  r=   r   r0  r2  r:   r4  r   rM  r³   r6  r@   r­   r8  r:  rC   r¯   r<  r>  Ú
model_copyrE   r±   r@  rB  rH   r°   rD  rF  rJ   r²   rH  r#  r   r   r$  r%  )r“   r¤   r&  rQ  rV  rZ  r€   Úlevelr¨   rµ   r¡   Úprovider_metricsr¸   r(  r)  rv   r'  s    `              @r9   Ú%_aggregate_grouping_sets_records_syncra  ¿  sÕ  ù€ ô !“N€MØ24€Lðœcð ¤kõ ð'¬D´Ô6HÐ1HÑ,Ið 'ÔPSð 'Ô^jð 'Ðosó 'ð
Ü”SÔ,Ð,Ñ-ð
äð
ô ð
ô ð	
ð
 
õ
ð ó DhˆØ×"Ñ"ˆÜ*¨6Ó2ˆØ Ÿ.™.Ô,@Ñ@ˆàÔ&Ò&Ø#ˆMØà”KÒØ29‰K˜Ÿ™Ó$ YÑ/Øá §¡Ó,¨[Ñ9ˆ	àÔ'Ò'Ø�~‹~¢oÜ5JØ#Ü*Ð+;¸V¿^¹^ÓLô6�	×"Ñ" 6§>¡>Ò2ð Ô'Ò'Ø�|‹|Ù+¨I×,<Ñ,<¸f¿l¹lÈGÕTØÔ/Ò/Ø�|Œ| §¤³Ù(¨×)9Ñ)9¸6¿<¹<ÈÏÉÐY`ÖaØÔ-Ò-Ø×!Ô!Ù+¨I×,BÑ,BÀF×DVÑDVÐX_Ö`ØÔ5Ò5Ø×!Ô! f§n¤n»_Ù(Ø×*Ñ*Ø×&Ñ&Ø—N‘NØö	ð Ô*Ò*ð  '×1Ñ1¸+ÀsÐ9KÐ1ÓLÐØ×1Ñ1Ò>°YˆHÙ'¨	×(;Ñ(;¸XÐGWÖXØÔ2Ò2Ø�~Œ~£oØ!×5Ñ5ÒB¸�Ù(¨×)<Ñ)<¸hÈÏÉÐX_Ö`Ø”oÒ%Ø×.Ô.Ù+¨I×,AÑ,AÀ6×CbÑCbÐdkÖlØÔ-Ò-Ø×.Ô.°6·>´>Ù(Ø×)Ñ)Ø×3Ñ3Ø—N‘NØö	ð Ô*Ò*Ø�ŒÙ+¨I×,?Ñ,?ÀÇÁÐRYÖZØÔ2Ô2Ø�Œ 6§>¤>Ù(¨×)<Ñ)<¸f¿o¹oÈvÏ~É~Ð_fÖgðIDhðX +×0Ñ0Ó2÷ñ ˆH�dô 	Ü×"Ñ" 8¨ZÓ8×=Ñ=Ó?Ø˜‘OØ˜;Ñ'ö	
ð€Gñ ð ‡L�LÑ%¨t€LÔ4à¨-Ñ8Ð8ùós   Ï<A Qc              ƒ   ó  K  — |D �ch c]/  }|j                   sŒ|j                   t        k7  sŒ$|j                   ’Œ1 }}i }|rt        | |«      ƒ d{  –—† }t        j                  t
        ||¬«      ƒ d{  –—† S c c}w 7 Œ-7 Œ­w)zHAsync wrapper: fetch api_key_metadata, then dispatch on a worker thread.N)r“   r¤   )r=   r   rÑ   r,  r-  ra  )r»   r“   Úrr³   r¤   s        r9   Ú _aggregate_grouping_sets_recordsrd  =  s}   è ø€ ð 5<Ö o¨q¸q¿y»yÈQÏYÉYÔZnÓMn §£Ð o€HÐ oà46ÐÙÜ!5°mÀXÓ!N×NÐä×"Ñ"Ü-ØØ)ô÷ ð ùò !pð Oøðús7   ‚B‡A9™A9­A9»BÁA>Á#BÁ4B Á5
BÂ BÚpageÚ	page_sizeÚmetadata_metrics_funcÚresolve_entity_metadatac              ƒ   ó¤  K  — | €'t        ddt        j                  j                  i¬«      ‚|�|€t        t        j
                  ddi¬«      ‚	 t        |||||||||¬«	      }t        | j                  |«      j                  |¬«      ƒ d{  –—† }t        | j                  |«      j                  |dd	id
dig|	dz
  |
z  |
¬«      ƒ d{  –—† }|}|�i |xs i ¥ ||«      ƒ d{  –—† ¥}t        | |||¬«      ƒ d{  –—† }|d   }|r ||«      }t        |d   t        d&i d|j                  “d|j                  “d|j                   “d|j"                  “d|j$                  “d|j&                  “d|j(                  “d|j*                  “d|j,                  “d|j.                  “d|j0                  “d|j2                  “d|j4                  “d|j6                  “d|j8                  “d |	“d!| |
z   “d"|	|
z  |k  “Ž¬#«      S 7 �Œr7 �Œ87 �Œ 7 �Œ# t:        $ r;}t=        j>                  d$|«       t        t        j@                  dd%|› �i¬«      ‚d}~ww xY w­w)'a6  Common function to get daily activity for any entity type.

    ``resolve_entity_metadata`` lets a caller resolve entity metadata from the
    rows actually on the page (e.g. user_id -> user_email) instead of fetching
    the whole entity table upfront, which matters when the entity set is
    unbounded.
    Néô  Úerror©Ústatus_codeÚdetailú&Please provide start_date and end_date)	r¥   r~   rÒ   rÓ   r@   r=   rß   rÔ   rÕ   r¿   r:   rÂ   ÚidÚascrí   )rÀ   rÃ   ÚskipÚtake)r»   r“   r¥   r�   rw   rv   Útotal_spendÚtotal_flat_costÚtotal_prompt_tokensÚtotal_completion_tokensrŠ   Útotal_api_requestsÚtotal_successful_requestsÚtotal_failed_requestsÚtotal_cache_read_input_tokensÚ!total_cache_creation_input_tokensÚtotal_compression_saved_tokensÚtotal_compression_savings_spendÚ"total_prompt_caching_savings_spendÚ,total_gateway_injected_caching_savings_spendÚtotal_autorouter_savings_spendre  Útotal_pagesÚhas_more©rv   r©   z!Error fetching daily activity: %súFailed to fetch analytics: r6   )!r   r   Údb_not_connected_errorÚvaluer   ÚHTTP_400_BAD_REQUESTrë   r„   ÚdbÚcountrÅ   r.  r    r   rQ   r‰   rM   rO   rŠ   rb   rd   rf   rS   rU   rX   rZ   r\   r^   r`   rÈ   r   Ú	exceptionÚHTTP_500_INTERNAL_SERVER_ERROR)r»   r  r¥   r~   r�   rÒ   rÓ   r@   r=   re  rf  rß   rg  rÔ   rÕ   rh  ré   Útotal_countÚdaily_spend_dataÚresolved_entity_metadataÚ
aggregatedr›   rÐ   s                          r9   Úget_daily_activityr‘  P  s  è ø€ ð6 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 Ð˜XÐ-ÜÜ×3Ñ3ØÐEÐFô
ð 	
ð
S
Ü"9Ø+ØØ!ØØØØ1Ø$;Ø$;ô
#
Ðô )0°×0@Ñ0@À*Ó(M×(SÑ(SÐZjÐ(SÓ(k×"kˆô ELÈM×L\ÑL\Ð^hÓDi×DsÑDsØ"à˜Ð Ø�u�ðð ˜‘(˜iÑ'Øð Etó E
÷ ?
Ðð $9Ð Ø"Ð.ð(Ø(Ò.¨Bð(á0Ð1AÓB×Bð(Ð$ô
 #;Ø'Ø$Ø+Ø":ô	#
÷ 
ˆ
ð & hÑ/ÐÙ Ù4Ð5EÓFÐä.Ø˜yÑ)Ü'ò Ø,×2Ò2ðà 0× :Ò :ðð %5×$BÒ$Bðð )9×(JÒ(Jð	ð
 .×:Ò:ðð $4×#@Ò#@ðð +;×*NÒ*Nðð '7×&FÒ&Fðð /?×.VÒ.Vðð 3C×2^Ò2^ðð 0@×/XÒ/Xðð 1A×0ZÒ0Zðð 4D×3`Ò3`ðð >N×=tÒ=tðð 0@×/XÒ/Xðñ  ð!ð"  +˜l¨iÑ7Ñ8ð#ð$  Ñ*¨kÒ9ð%ô
ð 	
ðQ #lùð?
ùð Cùð
úôF ò 
Ü×&Ñ&Ð'JÈAÔNÜÜ×=Ñ=ØÐ:¸1¸#Ð>Ð?ô
ð 	
ûð
üss   ‚AIÁ=H	 ÂG=Â<H	 ÃH Ã	H	 Ã#HÃ$H	 Ã;HÃ<D H	 Ç<IÇ=H	 È H	 ÈH	 ÈH	 È		IÈ6IÉIÉIrv   Úentity_rowsc                 óT  — | D �ci c]  }|j                   j                  d«      |“Œ  }}|D ]õ  }|j                  |j                   «      }|€Œ!|j                  j                  }|j
                  xs d}|j                  |«      }	|	€$t        t        «       t        ||«      ¬«      }	|	||<   t        |«      }
|j                  r|
|	_        Œ�|j                  sŒª|j                  t        k7  sŒ¾t        |
t        ||j                  «      ¬«      |	j                   |j                  <   Œ÷ yc c}w )z@Write breakdown.entities onto the already-built per-day results.r  Nr¬   r§   )r:   Ústrftimer–   r¡   r´   r~   r   r!   r    rJ  r   r¨   r=   r   r   rM  r®   )rv   r’  r¤   r�   ÚdayÚby_dateÚrowr´   r~   rP  r¨   s              r9   Ú_fold_entity_rollups_syncr˜  Í  s	  € ð ELÖL¸S�c—h‘h×'Ñ'¨
Ó3°SÑ8ÐL€GÐLàò ˆØ�k‰k˜#Ÿ(™(Ó#ˆØˆ;Øà—=‘=×)Ñ)ˆØ—M‘MÒ1 \ˆ	Ø—‘˜iÓ(ˆØˆ>Ü'Ü$›Ü)Ð*?ÀÓKôˆFð #)ˆH�YÑä*¨3Ó/ˆØ×ÒØ$ˆF�NØ�[‹[˜SŸ[™[Ô,@Ó@Ü4IØ¬-Ð8HÈ#Ï+É+Ó*Vô5ˆF×$Ñ$ S§[¡[Ò1ñ'ùò Ms   …#D%Úinclude_entity_breakdownc              ƒ   ó  K  — | €'t        ddt        j                  j                  i¬«      ‚|�|€t        t        j
                  ddi¬«      ‚	 t        ||||||||	|
|¬«
      \  }}|rt        ||||||||	|
|¬«
      nd}|�Zt        j                   | j                  j                  |g|¢­Ž  | j                  j                  |d   g|d   ¢­Ž «      ƒ d{  –—† n& | j                  j                  |g|¢­Ž ƒ d{  –—† df\  }}|xs g D �cg c]  }t        d%i |¤Ž‘Œ }}t        | |¬	«      ƒ d{  –—† }|ret        d
„ |D «       «      }t        d„ |D «       «      }|rt!        | |«      ƒ d{  –—† ni }t        j"                  t$        |d   |||¬«      ƒ d{  –—†  t'        |d   t)        d%i d|d   j*                  “d|d   j,                  “d|d   j.                  “d|d   j0                  “d|d   j2                  “d|d   j4                  “d|d   j6                  “d|d   j8                  “d|d   j:                  “d|d   j<                  “d|d   j>                  “d|d   j@                  “d|d   jB                  “d|d   jD                  “d|d   jF                  “dd“dd“d d!“Ž¬"«      S 7 �Œ×7 �Œµc c}w 7 �Œ‡7 �ŒN7 �Œ&# tH        $ r;}tK        jL                  d#|«       t        t        jN                  dd$|› �i¬«      ‚d}~ww xY w­w)&a(  Aggregated variant that returns the full result set (no pagination).

    Uses SQL GROUP BY to aggregate rows in the database rather than fetching
    all individual rows into Python. This collapses rows across entities
    (users/teams/orgs), reducing ~150k rows to ~2-3k grouped rows.

    include_entity_breakdown runs a small companion rollup query and folds
    `breakdown.entities` onto the response, as entity-scoped views like Team Usage need.

    Matches the response model of the paginated endpoint so the UI does not need to transform.
    Nrj  rk  rl  ro  )
r  r¥   r~   rÒ   rÓ   r@   r=   rß   rÔ   rÕ   r   rí   )r»   r“   c              3   ó2   K  — | ]  }t        di |¤Ž–— Œ y ­w)Nr6   )r}   )rò   r—  s     r9   rõ   z0get_daily_activity_aggregated.<locals>.<genexpr>I  s   è ø€ Ò)]ÀcÔ*:Ñ*A¸SÕ*AÑ)]ùs   ‚c              3   óv   K  — | ]1  }|j                   sŒ|j                   t        k7  sŒ$|j                   –— Œ3 y ­wr5   )r=   r   )rò   rc  s     r9   rõ   z0get_daily_activity_aggregated.<locals>.<genexpr>J  s+   è ø€ ò /Ø°Q·Y³YÀ1Ç9Á9ÔPdÓCd�—	•	ñ/ùs   ‚9”9¨9rv   )rv   r’  r¤   r�   rt  rw   ru  rv  rw  rŠ   rx  ry  rz  r{  r|  r}  r~  r  r€  r�  re  r‚  rƒ  Fr„  z,Error fetching aggregated daily activity: %sr…  r6   )(r   r   r†  r‡  r   rˆ  r  r  r,  Úgatherr‰  Ú	query_rawrz   rd  ÚtupleÚ	frozensetrÑ   r-  r˜  r    r   rQ   r‰   rM   rO   rŠ   rb   rd   rf   rS   rU   rX   rZ   r\   r^   r`   rÈ   r   r‹  rŒ  )r»   r  r¥   r~   r�   rÒ   rÓ   r@   r=   rß   rÔ   r™  rÕ   r  r  Úentity_queryÚraw_rowsÚraw_entity_rowsr—  r“   r�  Úentity_recordsÚentity_api_keysÚentity_key_metadatarÐ   s                            r9   Úget_daily_activity_aggregatedr§  ï  sð  è ø€ ð4 ÐÜØØÔ.×EÑE×KÑKÐLô
ð 	
ð
 Ð˜XÐ-ÜÜ×3Ñ3ØÐEÐFô
ð 	
ð
d
Ü ;Ø!Ø+ØØ!ØØØØ1Ø$;Ø$;ô!
Ñˆ	�:ñ4 (ô +Ø%Ø /Ø#Ø%Ø!ØØØ#5Ø(?Ø(?õð ð 	ð0 Ð'ô	 —.‘.Ø*�× Ñ ×*Ñ*¨9ÐB°zÒBØ*�× Ñ ×*Ñ*¨<¸©?ÐM¸\È!¹_ÒMó÷ ð ð
 3˜×(Ñ(×2Ñ2°9ÐJ¸zÒJ×JÈDÐQñ 	"ˆ�/ð ?GºnÈ"ÖN°cÔ*Ñ1¨SÓ1ÐNˆÐNô #CØ'Øô#
÷ 
ˆ
ñ
 Ü$)Ñ)]È_Ô)]Ó$]ˆNÜ%.ñ /Ø#1ô/ó &ˆOñ
 #ô +¨=¸/ÓJ×JÐJàð  ô
 ×#Ñ#Ü)Ø" 9Ñ-Ø*Ø!4Ø&;ô÷ ð ô /Ø˜yÑ)Ü'ò Ø& xÑ0×6Ò6ðà *¨8Ñ 4× >Ò >ðð %/¨xÑ$8×$FÒ$Fðð )3°8Ñ(<×(NÒ(Nð	ð
 (¨Ñ1×>Ò>ðð $.¨hÑ#7×#DÒ#Dðð +5°XÑ*>×*RÒ*Rðð '1°Ñ&:×&JÒ&Jðð /9¸Ñ.B×.ZÒ.Zðð 3=¸XÑ2F×2bÒ2bðð 0:¸(Ñ/C×/\Ò/\ðð 1;¸8Ñ0D×0^Ò0^ðð 4>¸hÑ3G×3dÒ3dðð >HØñ>ç8Ò8ð!ð" 0:¸(Ñ/C×/\Ò/\ð#ñ$ ð%ñ& ð'ñ( ð)ô
ð 	
ðGùð
 Kûò Oð
ùð KùðúôD ò 
Ü×&Ñ&Ð'UÐWXÔYÜÜ×=Ñ=ØÐ:¸1¸#Ð>Ð?ô
ð 	
ûð
üs’   ‚ALÁBK ÃJ-Ã$K Ã;J0Ã<K ÄJ3ÄK Ä1J8Ä2;K Å-J;Å.*K ÆJ>ÆDK Ê,LÊ-K Ê0K Ê3K Ê;K Ê>K Ë	LË
6L Ì LÌL)NN)FN)NNNFN)NNFF)fr,  Úcollections.abcr   r   r   r   r   ÚAbstractSetr   r	   r
   Útypesr   Útypingr   r   r   Úfastapir   r   Útyping_extensionsr   Úlitellm._loggingr   Úlitellm.constantsr   Úlitellm.proxy._typesr   Ú-litellm.proxy.spend_tracking.ptu_feature_flagr   Úlitellm.proxy.utilsr   Ú'litellm.repositories.table_repositoriesr   Ú2litellm.repositories.verification_token_repositoryr   Ú>litellm.types.proxy.management_endpoints.common_daily_activityr   r   r   r   r   r   r   r    r!   Úprisma.modelsr"   ÚPrismaDeletedVerificationTokenr#   ÚPrismaVerificationTokenr0   rk   rr   r2   ro   r]  Úobjectrà   ru   rz   r}   rm   r†   r‹   Úboolr’   rœ   r    rº   rÑ   rl   rŸ  rÞ   rx   rë   r  r  r  r  r*  r.  r0  r2  r4  r6  r8  r:  r<  r>  r@  rB  rD  rF  rH  rJ  rM  ra  rd  r‘  r˜  r§  r6   r;   r9   ú<module>r»     sB
  ðÜ ß BÓ BÝ .ß 2Ñ 2Ý !ß 1Ñ 1ç )Ý 'å 1Ý 2Ý 2Ý YÝ ,Ý Võ÷
÷ 
õ 
ñ õõð 7Ø6Ø&FØ!<Ø8Ø4ñ1Ð �U˜7 3¨ 8Ñ,Ñ-ó ô;*�xô ;*ô|�y¨õ ð
 �D˜˜f˜Ñ%Ñ%€ô˜9ô ô
 �ô  ô0Ð'ô ð
Ð 0Ð3CÑ Cð Èó ð, \ð Ð;Kð ÐP\ó ð:`˜C $™Jð `¨4ó `ð¨Ð2BÑ)Cð Èó ð40Ø" 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAð0àð0ð 
ˆ#ˆvˆ+Ñó0ð #'ØDHñ~Øð~àð~ð ˜C  c¨6 kÑ!2Ð2Ñ3ð~ð ˜s D¨¨f¨Ñ$5Ð5Ñ6ð	~ð
 ˜cÐ#3Ð3Ñ4ð~ð ˜4‘Zð~ð # 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAð~ð ó~ðB(Øð(à˜#Ñð(ð 
ˆ#ÐÐ
Ñ ó(ð^ %*Ø#ñ+=Øð+=àð+=ð ! 4™Zð+=ð "ð	+=ð
 ˜‰_ð+=ð ˆ3�ˆ8�_ó+=ðl ,0Ø*.Ø$)ò.àð.ð �T˜#‘Y‰ Ñ%ð.ð ð	.ð
 ð.ð �‰:ð.ð �4˜‘9‰_˜tÑ#ð.ð ˜S™	 DÑ(ð.ð ! 4™Zð.ð "ð.ð 
ˆ#ˆ}Ð
Ñó.ðbB4àðB4ð �T˜#‘Y‰ Ñ%ðB4ð ð	B4ð
 ðB4ð �‰:ðB4ð �4˜‘9‰_˜tÑ#ðB4ð ˜S™	 DÑ(ðB4ð ˆ3��S‘	ˆ>ÑóB4ðJ' cð '¨có 'ð" ,0Ø*.Ø$)òb!àðb!ð ðb!ð �T˜#‘Y‰ Ñ%ð	b!ð
 ðb!ð ðb!ð �‰:ðb!ð �4˜‘9‰_˜tÑ#ðb!ð ˜S™	 DÑ(ðb!ð ! 4™Zðb!ð "ðb!ð ˆ3��S‘	ˆ>Ñób!ð\ ,0Ø*.Ø$)òA!àðA!ð ðA!ð �T˜#‘Y‰ Ñ%ð	A!ð
 ðA!ð ðA!ð �‰:ðA!ð �4˜‘9‰_˜tÑ#ðA!ð ˜S™	 DÑ(ðA!ð ! 4™ZðA!ð "ðA!ð ˆ3��S‘	ˆ>ÑóA!ðH/9àÐ&Ñ'ð/9ð ˜cÐ#3Ð3Ñ4ð/9ð ˜4‘Zð	/9ð
 # 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAð/9ð ó/9ðdàðð Ð&Ñ'ðð ˜4‘Zð	ð
 # 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAðð óðH  Ð �EÓ Ø€ˆUÓ ØÐ �UÓ ØÐ �5Ó Ø#%Ð ˜5Ó %Ø!#Ð ˜Ó #Ø)+Ð  Ó +Ø Ð �eÓ  Ø&(Ð ˜eÓ (Ø€�Ó Ø!#Ð ˜Ó #Ø Ð �eÓ  Ø&(Ð ˜eÓ (ðÐ%5ð ¸,ó ð6U G¨CÐ1AÐ,AÑ$Bð UÈSð UÐU`ó Uð
{9àÐ&Ñ'ð{9ð ˜cÐ#3Ð3Ñ4ð{9ð ó	{9ð|àðð Ð&Ñ'ðð ó	ð> ,0ØY]Ø*.Ø$)àñ#z
Ø $Ñ&ðz
àðz
ð ðz
ð �T˜#‘Y‰ Ñ%ð	z
ð
 # 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAðz
ð �d‘
ðz
ð �D‰jðz
ð �‰:ðz
ð �4˜‘9‰_˜tÑ#ðz
ð ðz
ð ðz
ð ˜S™	 DÑ(ðz
ð $ XÐ.>Ñ%?Ð$@À,Ð$NÑOÐRVÑVðz
ð ! 4™Zðz
ð "ðz
ð  & xÐ0@Ñ'AÐ&BÀIÈdÐSVÐX\Ð]`ÐbhÐ]hÑXiÐSiÑNjÑDkÐ&kÑlØ
ñð!z
ð$ %ó%z
ðzà�nÑ%ðð Ð*Ñ+ðð ˜cÐ#3Ð3Ñ4ð	ð
 # 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAðð 
óðX ,0Ø*.Ø%*Ø$)ñJ
Ø $Ñ&ðJ
àðJ
ð ðJ
ð �T˜#‘Y‰ Ñ%ð	J
ð
 # 3¨¨S°&¨[Ñ(9Ð#9Ñ:¸TÑAðJ
ð �d‘
ðJ
ð �D‰jðJ
ð �‰:ðJ
ð �4˜‘9‰_˜tÑ#ðJ
ð ˜S™	 DÑ(ðJ
ð ! 4™ZðJ
ð #ðJ
ð "ðJ
ð %ôJ
r;   