
    p#jm                       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dZd[dZddddd\d"Zd]d$Zd^d)Z d_d+Z!d,d	d-d`d1Z"dad5Z#dbd6Z$dcd7Z%ddd9Z&ded<Z'	 dZdfd>Z(dgd@Z)dhdBZ*didEZ+djdGZ,dkdIZ-dddJdldPZ.dmdQZ/dndRZ0dodSZ1dpdTZ2dqdVZ3drdXZ4dodYZ5dS )sz3Normalized 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                  d    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S )NousPortalSubscriptionInfoNOptional[str]planOptional[int]tierOptional[float]monthly_chargecurrent_period_endcredits_remainingrollover_credits)
__name__
__module____qualname__r   __annotations__r   r   r   r   r         </home/ubuntu/.hermes/hermes-agent/hermes_cli/nous_account.pyr   r   $   s{         DD&*N****(,,,,,)-----(,,,,,,,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.   r/   r0   r1   r2   r3   r4   r5   r6   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'   r8   r8   >   sM           G %d ; ; ;H;;;;;;r&   r8   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!<   ed)d#            Zed)d$            Zed)d%            Zd*d(ZdS )+NousPortalAccountInfor9   	logged_inNousAccountInfoSourcesourcefreshNr   user_idorg_id	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rS   selfs    r'   is_paidzNousPortalAccountInfo.is_paidd   s    '4//r&   c                    | j         du S )NFr]   r^   s    r'   is_free_tierz"NousPortalAccountInfo.is_free_tierh   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)rS   rW   r:   r^   s    r'   tool_gateway_entitledz+NousPortalAccountInfo.tool_gateway_entitledl   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)rS   rW   r9   r:   r<   get)r_   re   tas      r'   tool_gateway_entitled_forz/NousPortalAccountInfo.tool_gateway_entitled_foru   sL     #t++4BK2:K"+//(*C*Ct*KLLLr&   )r[   r9   )re   rf   r[   r9   )r!   r"   r#   r$   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rR   rS   rU   rW   rY   rZ   r   propertyr`   rb   rd   rj   r%   r&   r'   r@   r@   K   s        OOO!!!!KKK!G!!!! F    #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&   r@   account_infoOptional[NousPortalAccountInfo]r[   rf   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/z/billing)hermes_cli.authro   	ExceptionrJ   
isinstancerf   striprstrip)rl   ro   bases      r'   nous_portal_billing_urlrx      s    D;;;;;;; D D D"CD D+dC   '

 '&kk#((((s   	 zthis feature)
capabilityinclude_refresh_hintcoverage_categoryry   rz   r9   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 )rx   rj   rd   rA   rL   rS   r   rU   r-   _no_paid_access_messagerD   )	rl   ry   rz   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   )rU   r0   r1   r6   r4   r5   _credit_detail)
rl   ry   r   r   r0   r1   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 $ 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   rA   Naccess_token)r   r   rJ   r   )rA   rC   rD   rJ   staterJ   r   )r   r   rJ   )rr   r   rs   _error_inforh   _portal_base_urlrt   rf   ru   _info_from_oauth_pool_info_from_inference_key_poolr@   _info_from_valid_jwt_fresh_account_info)
r   r   r   r   excr   rJ   pool_oauth_info	pool_infojwt_infos
             r'   get_nous_portal_account_infor   (  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]rJ   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   rA   rJ   r   account_response_errorr   rA   rJ   rZ   r   rJ   r   )rr   r   r   r   
_cache_key_ACCOUNT_INFO_CACHE_LOCKr   time	monotonic_ACCOUNT_INFO_CACHE_TTL_fetch_nous_account_infor   rt   rh   rf   _info_from_account_payloadrs   r9   )r   r   rJ   r   r   r   refreshed_state	cache_key
cached_key	cached_atcached_infopayloadinfor   s                 r'   r   r   `  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   rJ   rK   runtime_base_urlbase_urlTpool:labelunknownportal_oauth_missing)rA   rC   rD   rJ   rK   rL   rM   r   )_select_nous_pool_entrygetattrrt   rf   ru   r@   rs   )rJ   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   rJ   rG   rK   r   r   	agent_keyr   r   r   )r   rG   rK   r   rM   r   Tr   r   r   r   r   r   )r   rs   _pool_entry_is_portal_oauthr   rt   rf   ru   r   r   r   rh   r   )
r   r   rJ   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        rN   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   rt   rf   ru   lower
startswithr9   )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 )
Nrp   rq   z/api/oauth/accountzBearer zapplication/json)AuthorizationAccept)headers   )timeout)rv   urllibrequestRequesturlopenjsonloadsreaddecodert   r>   )r   rJ   rw   urlr   reqrespr   s           r'   r   r     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,   r2   rF   )r+   r,   r.   r2   rA   TrC   r   rD   FrE   subrG   rH   rI   rJ   rK   rL   rM   
auth_storerN   )tzrS   rU   rW   rY   r%   )rr   r   rs   _coerce_floatrh   r   r   r   _coerce_bool_coerce_intr)   _coerce_strr@   r   fromtimestampr   utc_tool_access_from_valuer>   )
r   r   rJ   r   r   claimsr   r,   r2   access_infos
             r'   r   r   )  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          
        t          |                     d          t                    r|                     d          ni }t          |                     d          t                    r|                     d          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|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organisationrR   rS   rA   TrC   r   rD   rF   idrG   rJ   rK   rL   r   r   rM   r   rO   rP   rU   rW   rZ   r%   )rt   rh   r>   _subscription_from_payload!_paid_service_access_from_payloadr+   r,   r@   r  r.   r9   r  )r   r   rJ   r
  r  rR   r   r,   s           r'   r   r   [  sr    #-W[[-@-@$"G"GO7;;vRD gkk.11488	N### 
 .gkk..I.IJJL.w{{;P/Q/QRRF$*4&..Kv1(    $} d <++D1122bQW7av7M7M]a	
 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&   valuerV   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<   )rt   r>   r  rh   itemsrf   r8   )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&   rQ   c                   t          | t                    sd S t          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    )rt   r>   r   r  rh   r  r   r  s    r'   r  r    s    eT"" t%6**++6**++$UYY/?%@%@AA&uyy1E'F'FGG'		2E(F(FGG&uyy1C'D'DEE   r&   rT   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.   r/   r0   r1   r2   r3   r4   r5   r6   )r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   )rt   r>   r  rh   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&   )rJ   rZ   r   objectrA   rZ   rX   c           
     F    t          |dd||t          |                     S )Nr   F)rA   rC   rD   rJ   rZ   r   )r@   rf   r   s       r'   r   r     s3     !'%jj   r&   c                    |                      d          }t          |t                    r|                                sd S |                                                    d          S )NrJ   rq   )rh   rt   rf   ru   rv   )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   rJ   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)rt   rf   ru   endswithr   fromisoformat	timestamprs   )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)rt   rf   r  s    r'   r  r    s%    % % 4r&   r*   c                4    t          | t                    r| nd S r)  )rt   r9   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r)  )rt   r9   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r)  )rt   r9   floatr,  r-  r  s    r'   r   r     s[    % t=4U||z"   ttr.  r)  )rl   rm   r[   rf   )
rl   rm   ry   rf   rz   r9   r{   r   r[   r   )rl   r@   ry   rf   r   rf   r[   rf   )r   r   r   r   r   r   r[   rf   )r[   r   )r   r9   r   r   r[   r@   )r   r   r   r9   rJ   r   r[   r@   )rJ   r   r[   rm   )r   r9   r   r   rJ   r   r[   rm   )r[   r   )r   r   r[   r9   )r   rf   rJ   r   r[   r   )
r   rf   r   r   rJ   r   r   r   r[   rm   )r   r   r   r   rJ   r   r[   r@   )r  r   r[   rV   )r  r   r[   rQ   )r  r   r[   rT   )
r   r  rA   r9   rJ   r   rZ   rX   r[   r@   )r   r   r[   r   )r   rf   rJ   r   r[   rf   )r  r   r[   r   )r  r   r[   r   )r  r   r[   r*   )r  r   r[   r   )6r=   
__future__r   r  r   	threadingr   urllib.requestr   dataclassesr   r   r   r   typingr   r	   r
   rB   TOOL_COVERAGE_CATEGORIESr   r   r$   Lockr   r   r)   r8   r@   rx   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>r8     sR   9 9 9 " " " " " "            ( ( ( ( ( ( ( ( ' ' ' ' ' ' ' ' ) ) ) ) ) ) ) ) ) )   VW    IM  M M M M)9>++  $- - - - - - - - $1 1 1 1 1 1 1 1 $	< 	< 	< 	< 	< 	< 	< 	< $0M 0M 0M 0M 0M 0M 0M 0Mf) ) ) ) )$ %!%'+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&   