
    ,j7s                       U d Z ddlmZ ddlZddlZddlZddlZddlZddl	m
Z
mZ ddlmZmZ ddlmZmZmZ ed         ZdZd	Zdad
ed<    ej                    Z e
d           G d d                      Z e
d           G d d                      Z e
d           G d d                      Z e
d           G d d                      Zd[d\dZd[d\dZddddd]d#Zd^d%Z d_d*Z!d`d,Z"d-d	d.dad2Z#dbd6Z$dcd7Z%ddd8Z&ded:Z'dfd=Z(	 d[dgd?Z)dhdAZ*didCZ+djdFZ,dkdHZ-dldJZ.dddKdmdQZ/dndRZ0dodSZ1dpdTZ2dqdUZ3drdWZ4dsdYZ5dpdZZ6dS )tz3Normalized Nous Portal account entitlement helpers.    )annotationsN)	dataclassfield)datetimetimezone)AnyLiteralOptional)jwtaccount_apiinference_keynoneerror)	firecrawlfalz	fal-videozopenai-audiozbrowser-usemodal<   z1tuple[str, float, 'NousPortalAccountInfo'] | None_account_info_cacheT)frozenc                  r    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S )NousPortalSubscriptionInfoNOptional[str]planOptional[int]tierOptional[float]monthly_chargemonthly_creditscurrent_period_endcredits_remainingrollover_credits)__name__
__module____qualname__r   __annotations__r   r   r   r   r    r!        </home/ubuntu/.hermes/hermes-agent/hermes_cli/nous_account.pyr   r   $   s         DD&*N****'+O++++(,,,,,)-----(,,,,,,,r'   r   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S )NousPaidServiceAccessInfoNOptional[bool]allowedpaid_accessr   reasonorganisation_idr   effective_at_mshas_active_subscriptionactive_subscription_is_paidsubscription_tierr   subscription_monthly_chargesubscription_credits_remainingpurchased_credits_remainingtotal_usable_credits)r"   r#   r$   r,   r%   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r&   r'   r(   r*   r*   /   s         "G"""""&K&&&& F    %)O))))%)O)))).22222266666'+++++3777776:"::::377777,0000000r'   r*   c                  D    e Zd ZU dZdZded<    ee          Zded<   dS )	NousToolAccessInfoa/  Free tool-pool entitlement, decoupled from paid/billing access.

    Mirrors the Portal's ``tool_access`` claim/field: ``enabled`` is true when a
    positive tool-pool balance is live and not gated off; ``coverage`` maps each
    tool category to whether the pool funds it (FAL video is excluded).
    Fboolenabled)default_factoryzdict[str, bool]coverageN)	r"   r#   r$   __doc__r;   r%   r   dictr=   r&   r'   r(   r9   r9   ?   sM           G %d ; ; ;H;;;;;;r'   r9   c                     e Zd ZU ded<   ded<   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#<   ed+d%            Zed+d&            Zed+d'            Zd,d*ZdS )-NousPortalAccountInfor:   	logged_inNousAccountInfoSourcesourcefreshNr   user_idorg_idorg_slugorg_name	client_id
product_idnous_clientportal_base_urlinference_base_urlFinference_credential_presentcredential_sourcezOptional[datetime]
expires_atemail	privy_did$Optional[NousPortalSubscriptionInfo]subscriptionr+   paid_service_access#Optional[NousPaidServiceAccessInfo]paid_service_access_infoOptional[NousToolAccessInfo]tool_accessOptional[dict[str, Any]]
raw_claimsraw_accountr   returnc                    | j         du S )NTrV   selfs    r(   is_paidzNousPortalAccountInfo.is_paidg   s    '4//r'   c                    | j         du S )NFr`   ra   s    r(   is_free_tierz"NousPortalAccountInfo.is_free_tierk   s    '500r'   c                B    | j         du rdS | j        duo| j        j        S )zCoarse "entitled to any managed tool" gate: paid access OR a live
        free tool pool. Use :meth:`tool_gateway_entitled_for` to gate a specific
        tool category (the pool does not cover every category).TN)rV   rZ   r;   ra   s    r(   tool_gateway_entitledz+NousPortalAccountInfo.tool_gateway_entitledo   s0    
 #t++4t+H0@0HHr'   categorystrc                    | j         du rdS | j        }t          |o"|j        o|j                            |          du           S )zWhether a specific tool category is entitled. Paid users are entitled
        everywhere; free tool-pool users only where ``coverage[category]`` is
        true (e.g. image but not video).T)rV   rZ   r:   r;   r=   get)rb   rh   tas      r(   tool_gateway_entitled_forz/NousPortalAccountInfo.tool_gateway_entitled_forx   sL     #t++4BK2:K"+//(*C*Ct*KLLLr'   )r^   r:   )rh   ri   r^   r:   )r"   r#   r$   r%   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rU   rV   rX   rZ   r\   r]   r   propertyrc   re   rg   rm   r&   r'   r(   rA   rA   L   s        OOO!!!!KKK!G!!!! F    "H"""""H""""#I#### $J$$$$!%K%%%%%)O))))(,,,,,). ....'+++++%)J))))E#I####9=L====*.....DHHHHH04K4444+/J////,0K0000E0 0 0 X0 1 1 1 X1 I I I XIM M M M M Mr'   rA   account_infoOptional[NousPortalAccountInfo]r^   ri   c                    	 ddl m} n# t          $ r d}Y nw xY wd}| | j        }t	          |t
                    r|                                s|}|                    d           dS )z>Return the billing URL for a normalized Nous account snapshot.r   )DEFAULT_NOUS_PORTAL_URLhttps://portal.nousresearch.comN//billing)hermes_cli.authrr   	ExceptionrM   
isinstanceri   striprstrip)ro   rr   bases      r(   nous_portal_billing_urlr|      s    D;;;;;;; D D D"CD D+dC   '

 '&kk#((((s   	 c                ,   t          |           }|dt          d                    }| t          | dd          nd}t          |t                    r?|                                r+ddlm} | d ||                                d           d	S | d	S )
aN  Return the portal top-up URL that auto-opens the top-up modal.

    Prefers the org-pinned page ``{base}/orgs/{slug}/billing?topup=open`` (skips
    the legacy shim's re-resolution + multi-org disambiguation). Falls back to the
    legacy ``{base}/billing?topup=open`` when the account has no ``org_slug`` (the
    portal's ``slug`` is nullable; the legacy page forwards the param through to
    the org-pinned page). Never builds ``/orgs/None/billing``.

    The ``?topup=open`` query is the NAS enabler that lands the user in the
    top-up flow rather than just on the billing page.
    Nru   rH   r   )quotez/orgs/ )safez/billing?topup=open)r|   lengetattrrx   ri   ry   urllib.parser~   )ro   base_billingr{   slugr~   s        r(   nous_portal_topup_urlr      s     +<88L*3z??**+D6B6N7<T222TXD$ P P&&&&&&OOeeDJJLLr:::OOOO''''r'   zthis feature)
capabilityinclude_refresh_hintcoverage_categoryr   r   r:   r   r   c                  t          |           }| 2|'|                     |          rdS | j        r| d| dS n	| j        rdS | 	d| d| dS | j        s| j        r	d| d| dS d| d	| dS | j        -d
| d}| j        r|d| j         dz  }|r|dz  }|d| dz  }|S | j        }|r|j        nd}|dk    rd| dS |dk    s	| j        du r!t          | ||          }|r| j
        s|dz  }|S d| d| dS )u   Return user-facing guidance for a missing Nous tool-gateway entitlement.

    ``None`` means the account is entitled to use the capability — via paid
    service access OR a live free tool pool that covers it. The message works
    from normalized entitlement fields rather than subscription price alone:
    purchased credits without a subscription still count as paid access, while a
    paid subscription with exhausted usable credits does not.

    ``coverage_category`` scopes the check to a single tool category (e.g.
    ``"fal-video"``). When given, a user who is entitled overall but whose
    access does not fund that category gets a neutral billing nudge instead of a
    message implying their credits are exhausted. The pool-vs-paid distinction is
    never surfaced to the user.
    Nzd isn't included with your current Nous Portal access. Add credits or a subscription to enable it at .z9Hermes could not verify your Nous Portal entitlement, so zO is unavailable. Run `hermes model` to refresh your login, or check billing at zeNous inference credentials are configured, but Hermes cannot verify your Nous Portal paid access for zc. Log in with `hermes model` to enable Portal-managed features. Billing and credits are managed at zLog in to Nous Portal to use z9: run `hermes model`. Billing and credits are managed at z9Hermes could not verify your Nous Portal paid access, so z is unavailable.z Account lookup failed: z, Run `hermes model` to refresh your session.z Check billing at account_missingzOHermes could not find a Nous Portal account or organisation for this login, so zi is unavailable. Run `hermes model` to authenticate again; if the problem persists, contact Nous support.no_usable_creditsFzF If you recently bought credits, run `hermes model` to refresh Hermes.zIYour Nous Portal account does not currently have paid service access, so 2 is unavailable. Add credits or update billing at )r|   rm   rg   rB   rO   rV   r   rX   r.   _no_paid_access_messagerE   )	ro   r   r   r   billing_urldetailaccessr.   messages	            r(   &format_nous_portal_entitlement_messager      sd   * *,77K(556GHH t1 
 " \ \MX\ \ \	 / 	4)
 ) )%) ) )	
 ! 
4 	94>9 9 +69 9 9AJ A A2=A A A	

 '/
    	  	GF1CFFFFF 	EDDF5{55552F$.V]]$F"""R#R R R	
 $$$(HE(Q(Q),
KPP 	`(: 	`__G	[	[ 	[LW	[ 	[ 	[r'   r   c                Z   | j         }|r|j        nd }|r|j        nd }|r|j        nd }|r|j        nd }|r|j        nd }|r|rt          |||          }	d|	 d| d| dS |r|du r	d| d| dS |du rt          |||          }	d|	 d| d	| dS t          |||          }	d
|	 d| d| dS )Nz&Your Nous Portal credits are exhaustedz, so z, is unavailable. Top up or renew credits at r   FzGYour current Nous Portal plan does not include paid service access, so z+ is unavailable. Upgrade or add credits at zEYour Nous Portal account has no active subscription or usable creditsz- is unavailable. Subscribe or add credits at z3Your Nous Portal account has no usable paid creditsr   )rX   r1   r2   r7   r5   r6   _credit_detail)
ro   r   r   r   r1   r2   total_usablesubscription_creditspurchased_creditscredit_details
             r(   r   r     s   
 2F@FPf<<DHN"X&"D"DTX28B6..dLDJT6@@PT>DN::$ 
#> 
&|5IK\]]I] I I I I:EI I I	

  
#>%#G#GXX XITX X X	

 %''&|5IK\]]!! !#-! !! ! !	
 #<1EGXYYM	Xm 	X 	X	X 	XIT	X 	X 	Xr'   r   r   r   r   c                    g }| |                     d| d           ||                     d|d           ||                     d|d           |sdS dd                    |           dS )	Nzusable $z.2fzsubscription $zpurchased $r   z (z, ))appendjoin)r   r   r   partss       r(   r   r   +  s    
 E2222333'@&:@@@AAA$:#4:::;;; r#		%  ####r'   Nonec                 
    da dS )z7Clear the short-lived account-info cache used by tests.N)r   r&   r'   r(   $reset_nous_portal_account_info_cacher   <  s     r'   F)force_freshmin_jwt_ttl_secondsr   r   intc                   	 ddl m}  |d          pi }n(# t          $ r}t          |d          cY d}~S d}~ww xY w|                    d          }t          |          }t          |t                    r|                                s<t          | ||          }||S t          |          }||S t          dd	d|
          S | st          ||||          }	|	|	S t          || |          S )af  Return normalized Nous Portal account entitlement information.

    By default, a valid unexpired OAuth access JWT is used as a low-latency
    local account snapshot. ``force_fresh=True`` always calls
    ``/api/oauth/account`` and bypasses the short-lived cache. JWT claims are
    decoded locally for UX gating only; server APIs remain authoritative.
    r   )get_provider_auth_statenousF)r   rB   Naccess_token)r   r   rM   r   )rB   rD   rE   rM   staterM   r   )r   r   rM   )rv   r   rw   _error_infork   _portal_base_urlrx   ri   ry   _info_from_oauth_pool_info_from_inference_key_poolrA   _info_from_valid_jwt_fresh_account_info)
r   r   r   r   excr   rM   pool_oauth_info	pool_infojwt_infos
             r(   get_nous_portal_account_infor   B  st   7;;;;;;''//52 7 7 76666666667 99^,,L&u--OlC(( 
0B0B0D0D 
/# 3+
 
 

 &""1/BB	 $+	
 
 
 	
  '+ 3	
 
 
 O'   s    
;6;;r   dict[str, Any]rM   c           	     \   	 ddl m}m}  |            } |d          p| }t          |          p|}t	          ||          }t
          5  |sEt          >t          \  }}	}
||k    r-t          j                    |	z
  t          k     r|
cd d d            S d d d            n# 1 swxY w Y   t          ||          }|st          dd|          S t          |                    d          t                    r(t          |                    d          pdd||	          S t          |||
          }t
          5  |t          j                    |fad d d            n# 1 swxY w Y   |S # t           $ r<}t          |t#          |                     d                    |          cY d }~S d }~ww xY w)Nr   )r   resolve_nous_access_tokenr   empty_account_responseTr   rB   rM   r   account_response_errorr   rB   rM   r]   r   rM   r   )rv   r   r   r   
_cache_key_ACCOUNT_INFO_CACHE_LOCKr   time	monotonic_ACCOUNT_INFO_CACHE_TTL_fetch_nous_account_infor   rx   rk   ri   _info_from_account_payloadrw   r:   )r   r   rM   r   r   r   refreshed_state	cache_key
cached_key	cached_atcached_infopayloadinfor   s                 r(   r   r   z  s   *
VVVVVVVV002211&99BU*?;;N|_==	% 	' 	' '#6#B5H2
I{**0@0@90LPg/g/g&		' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' +<II 	. /   
 gkk'**C00 	kk'**F.F /#	    *!+
 
 

 & 	F 	F#,dn.>.>"E	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 
 
 
599^4455+
 
 
 	
 	
 	
 	
 	
 	

sy   AE% 	;BE% E% B!!E% $B!%&E% AE% E% 5EE% EE% E E% %
F+/1F& F+&F+c                   	 t                      }|dS t          |dd          pt          |dd          }t          |t                    r|                                sdS t          dddt          |dd          p| t          |dd          p!t          |d	d          pt          |d
d          ddt          |dd           d          S # t          $ r Y dS w xY w)zEReturn an explicit unknown-entitlement snapshot for opaque Nous keys.Nruntime_api_keyr   r   Fr   rM   rN   runtime_base_urlbase_urlTpool:labelunknownportal_oauth_missing)rB   rD   rE   rM   rN   rO   rP   r   )_select_nous_pool_entryr   rx   ri   ry   rA   rw   )rM   entryruntime_keys      r(   r   r     s   '))=4e%6==cP^`bAcAc+s++ 	;3D3D3F3F 	4$"0$77 #" 3T:: 45"4d;;45*d33)-JgeWi&H&HJJ(
 
 
 	
"    tts   C AC !A*C 
CCc           
     n   	 t                      }n# t          $ r Y d S w xY w|t          |          sd S t          |dd           }t	          |t
                    r|                                sd S t          |dd           p|}|t          |dd           t          |dd           p!t          |dd           pt          |dd           t          |dd           dt          |d	d
           d}| st          ||||          }||S 	 t          ||          }n)# t          $ r}	t          |	d|          cY d }	~	S d }	~	ww xY w|st          dd|          S t	          |
                    d          t
                    r(t          |
                    d          pdd||          S t          |||          S )Nr   rM   rJ   rN   r   r   	agent_keyr   r   r   )r   rJ   rN   r   rP   r   Tr   r   r   r   r   r   )r   rw   _pool_entry_is_portal_oauthr   rx   ri   ry   r   r   r   rk   r   )
r   r   rM   r   r   entry_portal_urlr   r   r   r   s
             r(   r   r     sm   '))   tt}7>>}t5.$77LlC(( 0B0B0D0D t 	($// 	 
 %UK66E/66 0u0$770uj$//UK66IWUGY%G%GII
 
E  ', 3	
 
 
 O
*<9IJJ 
 
 
,
 
 
 	
 	
 	
 	
 	
 	

  
*,
 
 
 	

 '++g&&,, 
++g&&B*B,	
 
 
 	
 &(   s*    
D 
D>"D93D>9D>Optional[Any]c                     ddl m}   | d          }|r|                                sd S t          |                                          }|sd S d
d}t          ||	          S )Nr   )	load_poolr   r   r   r^   tuple[float, float, int]c                    t          t          | dd                     pd}t          t          | dd                     pd}t          t          | dd          pd          }||| fS )Nagent_key_expires_atg        rQ   priorityr   )_parse_iso_timestampr   r   )r   	agent_exp
access_expr   s       r(   _entry_sort_keyz0_select_nous_pool_entry.<locals>._entry_sort_key!  so    (8NPT)U)UVV]Z]	)'%t*L*LMMTQT
wuj!449:::y11r'   )key)r   r   r^   r   )agent.credential_poolr   has_credentialslistentriesmax)r   poolr   r   s       r(   r   r     s    //////9VD t++-- t4<<>>""G t2 2 2 2 wO,,,,r'   r   r   c                l   t          | dd           }t          |t                    r|                                sdS t          t          | dd          pd                                                                          }t          | dd           }|                    d          pt          |          S )Nr   F	auth_typer   refresh_tokenoauth)r   rx   ri   ry   lower
startswithr:   )r   r   r   r   s       r(   r   r   *  s    5.$77LlC(( 0B0B0D0D uGE;339r::@@BBHHJJIE?D99M((?D,?,??r'   r   c                   |pd                     d          }| d}d|  dd}t          j                            ||          }t          j                            |d	          5 }t          j        |                                                                          }d d d            n# 1 swxY w Y   t          |t                    r|ni S )
Nrs   rt   z/api/oauth/accountzBearer zapplication/json)AuthorizationAccept)headers   )timeout)rz   urllibrequestRequesturlopenjsonloadsreaddecoderx   r?   )r   rM   r{   urlr   reqrespr   s           r(   r   r   3  s
    @@HHMMD
%
%
%C1<11$ G .
 
 g
 
6
6C			Q		/	/ 34*TYY[[//11223 3 3 3 3 3 3 3 3 3 3 3 3 3 3 $//777R7s   '9B,,B03B0tokenc          
        	 ddl m} n# t          $ r Y d S w xY w ||           }|sd S t          |                    d                    }|5|t          j                    t          dt          |                    z   k    rd S t          |                    d                    }t          |                    d                    }t          ||t          |                    d                    |          }	t          di dd	d
ddddt          |                    d                    dt          |                    d                    dt          |                    d          p|                    d                    dt          |                    d                    dt          |                    d                    d|dt          |                    d                    dd	dt          |                    d                    pddt          j        |t          j                  d|d|	dt#          |                    d                    dt%          |          S )Nr   )_decode_jwt_claimsexpr-   r3   rG   )r,   r-   r/   r3   rB   TrD   r   rE   FrF   subrJ   rK   rL   rM   rN   rO   rP   
auth_storerQ   )tzrV   rX   rZ   r\   r&   )rv   r  rw   _coerce_floatrk   r   r   r   _coerce_bool_coerce_intr*   _coerce_strrA   r   fromtimestampr   utc_tool_access_from_valuer?   )
r  r   rM   r   r  claimsr  r-   r3   access_infos
             r(   r   r   C  s   6666666   tt  &&F t


5))
*
*C
{cTY[[3q#6I2J2J+K+KKKKtvzz-8899K#FJJ/B$C$CDD+#FJJx$8$899+	  K !   $u e FJJu--...	
 6::h//000 fjj55O;9O9OPPP vzz,77888  

= 9 9::: ( 'uyy1E'F'FGGG &*T &eii0C&D&DEEU )#(,???? (K "-  ,FJJ},E,EFFF!" <<<# s   	 
r   c          
        |                      d          }t          |t                    r|ni }|                      d          }t          |t                    r|ni }t          |                      d                    }t	          |                      d                    }|r|j        nd }	|		||j        }	t          di ddddd	dd
t          |                     d                    p
|r|j	        nd dt          |                     d                    dt          |                     d                    dt          |                     d                    d|dt          |                     d                    dt          |                     d          p|                     d                    dt          |                     d                    pddt          |                     d                    dt          |                     d                    d|d|	d|dt          |                      d                    dt          |           S )NuserorganisationrU   rV   rB   TrD   r   rE   rG   idrH   r   rI   namerJ   rM   rN   rO   r   r   rP   r
  rR   rS   rX   rZ   r]   r&   )rk   rx   r?   _subscription_from_payload!_paid_service_access_from_payloadr,   r-   rA   r  r/   r:   r  )
r   r   rM   raw_userr  raw_orgr  rU   r   r-   s
             r(   r   r   u  s    {{6""H'1(D'A'AI88rDkk.))G.8$.G.G#O77RL-gkk..I.IJJL.w{{;P/Q/QRRF$*4&..Kv1(    $} d <++D1122bQW7av7M7M]a	
 \--f55666 \--f55666 eii44555 ( 'uyy1E'F'FGGG &*%))N*C*C*]uyyQ\G]G]%^%^%^ &eii0C&D&DEEU $((7++,,, dhh{33444 "\ (K  "(!" ,GKK,F,FGGG#$ MMM% r'   valuerY   c                ^   t          | t                    sdS t          |                     d                    du }|                     d          }i }t          |t                    r6|                                D ]!\  }}t          |t
                    r|du ||<   "t          ||          S )zParse a Portal ``tool_access`` object (from the JWT claim or the account
    API) into :class:`NousToolAccessInfo`. Fails closed: a non-object value
    yields ``None``, and only literal ``true`` counts for ``enabled`` and each
    coverage entry.Nr;   Tr=   )r;   r=   )rx   r?   r  rk   itemsri   r9   )r  r;   raw_coverager=   r   vals         r(   r  r    s    
 eT"" t599Y//00D8G99Z((L "H,%% ,$**,, 	, 	,HC#s## , #tgAAAAr'   rT   c                   t          | t                    sd S t          t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                              S )	Nr   r   r   r   r   r    r!   )r   r   r   r   r   r    r!   )rx   r?   r   r  rk   r  r  r  s    r(   r  r    s    eT"" t%6**++6**++$UYY/?%@%@AA%eii0A&B&BCC&uyy1E'F'FGG'		2E(F(FGG&uyy1C'D'DEE   r'   rW   c                n   t          | t                    sd S t          |                     d                    }t          |                     d                    }t	          ||t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d                    t          |                     d	                    t          |                     d
                    t          |                     d                    t          |                     d                              S )Nr,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   )r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   )rx   r?   r  rk   r*   r  r  r  )r  r,   r-   s      r(   r  r    sW   eT"" t599Y//00Guyy7788K$599X..//#EII.?$@$@AA#EII.?$@$@AA ,UYY7P-Q-Q R R$0;X1Y1Y$Z$Z%eii0C&D&DEE$1%))<Y2Z2Z$[$['4UYY?_5`5`'a'a$1%))<Y2Z2Z$[$[*5995K+L+LMM   r'   )rM   r]   r   objectrB   r]   r[   c           
     F    t          |dd||t          |                     S )Nr   F)rB   rD   rE   rM   r]   r   )rA   ri   r   s       r(   r   r     s3     !'%jj   r'   c                    |                      d          }t          |t                    r|                                sd S |                                                    d          S )NrM   rt   )rk   rx   ri   ry   rz   )r   r  s     r(   r   r     sV    II'((EeS!!  t;;==$$$r'   c                    t          j        |                     d                                                    }|pd d| S )Nzutf-8r   :)hashlibsha256encode	hexdigest)r   rM   digests      r(   r   r     sD    ^L//8899CCEEF#..f...r'   c                   t          | t                    r| sd S |                                 }|                    d          r|d d         dz   }	 t	          j        |                                          S # t          $ r Y d S w xY w)NZz+00:00)rx   ri   ry   endswithr   fromisoformat	timestamprw   )r  texts     r(   r   r     s    eS!!  t;;==D}}S $CRCy8#%d++55777   tts   %A7 7
BBc                8    t          | t                    r| r| S d S N)rx   ri   r$  s    r(   r  r    s%    % % 4r'   r+   c                4    t          | t                    r| nd S r8  )rx   r:   r$  s    r(   r  r    s    ud++5555r'   r   c                    t          | t                    rd S 	 | d S t          |           S # t          t          f$ r Y d S w xY wr8  )rx   r:   r   	TypeError
ValueErrorr$  s    r(   r  r    s[    % t=45zzz"   tt   , , A Ac                    t          | t                    rd S 	 | d S t          |           S # t          t          f$ r Y d S w xY wr8  )rx   r:   floatr;  r<  r$  s    r(   r  r    s[    % t=4U||z"   ttr=  r8  )ro   rp   r^   ri   )
ro   rp   r   ri   r   r:   r   r   r^   r   )ro   rA   r   ri   r   ri   r^   ri   )r   r   r   r   r   r   r^   ri   )r^   r   )r   r:   r   r   r^   rA   )r   r   r   r:   rM   r   r^   rA   )rM   r   r^   rp   )r   r:   r   r   rM   r   r^   rp   )r^   r   )r   r   r^   r:   )r   ri   rM   r   r^   r   )
r  ri   r   r   rM   r   r   r   r^   rp   )r   r   r   r   rM   r   r^   rA   )r  r   r^   rY   )r  r   r^   rT   )r  r   r^   rW   )
r   r&  rB   r:   rM   r   r]   r[   r^   rA   )r   r   r^   r   )r   ri   rM   r   r^   ri   )r  r   r^   r   )r  r   r^   r   )r  r   r^   r+   )r  r   r^   r   )7r>   
__future__r   r+  r   	threadingr   urllib.requestr   dataclassesr   r   r   r   typingr   r	   r
   rC   TOOL_COVERAGE_CATEGORIESr   r   r%   Lockr   r   r*   r9   rA   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&   r'   r(   <module>rG     sk   9 9 9 " " " " " "            ( ( ( ( ( ( ( ( ' ' ' ' ' ' ' ' ) ) ) ) ) ) ) ) ) )   VW    IM  M M M M)9>++  $- - - - - - - - $1 1 1 1 1 1 1 1 $	< 	< 	< 	< 	< 	< 	< 	< $2M 2M 2M 2M 2M 2M 2M 2Mj) ) ) ) )( ( ( ( (4 %!%'+X X X X X Xv% % % %P$ $ $ $"    !5 5 5 5 5 5p2
 2
 2
 2
j   BD D D DN- - - -&@ @ @ @ &*8 8 8 8 8 / / / /d# # # #LB B B B"      2 &*,0     "% % % %/ / / /
	 	 	 	   6 6 6 6        r'   