
    Ӄie                        U d 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 ddlm	Z	 ddl
mZmZmZmZmZ ddlmZ ddlZ ej        e          ZdZdZi aeeef         ed	<   daeed
<   e G d d                      Ze G d d                      Zi dddddddddddddddddddddddddd d!d"d#d#d$d%d%d%d&d'd(d)d*d+d,d-Zeeef         ed.<   da eeeef                  ed/<   d0eeef         fd1Z!d0e	fd2Z"d0eeef         fd3Z#d4eeef         d0dfd5Z$dXd7e%d0eeef         fd8Z&d9ed:ed0ee'         fd;Z(d<eeef         d0ee'         fd=Z)e G d> d?                      Z*d9ed0eeeef                  fd@Z+dAeeef         d:ed0eeeef                  fdBZ,d9ed:ed0ee*         fdCZ-d9ed0ee         fdDZ.ddl/Z/ e/j0        dEe/j1                  Z2e/j3        edF<   d9ed0ee         fdGZ4	 dYdIed9edJe'd0eeeef                  fdKZ5dLedMeeef         dNed0efdOZ6dNedMeeef         d0efdPZ7dNed0ee         fdQZ8d0eeef         fdRZ9dSed0ee         fdTZ:dNedLed0ee         fdUZ;dLed0ee         fdVZ<dNed0ee         fdWZ=dS )Zu]  Models.dev registry integration — primary database for providers and models.

Fetches from https://models.dev/api.json — a community-maintained database
of 4000+ models across 109+ providers.  Provides:

- **Provider metadata**: name, base URL, env vars, documentation link
- **Model metadata**: context window, max output, cost/M tokens, capabilities
  (reasoning, tools, vision, PDF, audio), modalities, knowledge cutoff,
  open-weights flag, family grouping, deprecation status

Data resolution order (like TypeScript OpenCode):
  1. Bundled snapshot (ships with the package — offline-first)
  2. Disk cache (~/.hermes/models_dev_cache.json)
  3. Network fetch (https://models.dev/api.json)
  4. Background refresh every 60 minutes

Other modules should import the dataclasses and query functions from here
rather than parsing the raw JSON themselves.
    N)	dataclass)Path)AnyDictListOptionalTuple)atomic_json_writezhttps://models.dev/api.jsoni  _models_dev_cache_models_dev_cache_timec                      e Zd ZU dZeed<   eed<   eed<   eed<   dZeed<   dZeed<   dZ	eed	<   dZ
eed
<   dZeed<   dZeed<   dZeedf         ed<   dZeedf         ed<   dZeed<   dZeed<   dZee         ed<   dZeed<   dZeed<   dZee         ed<   dZee         ed<   dZeed<   dZeed<   dZeed<   dZeed<   d efd!Zd efd"Z d efd#Z!d efd$Z"d efd%Z#d efd&Z$dS )'	ModelInfoz1Full metadata for a single model from models.dev.idnamefamilyprovider_idF	reasoning	tool_call
attachmenttemperaturestructured_outputopen_weights .input_modalitiesoutput_modalitiesr   context_window
max_outputN	max_inputg        
cost_inputcost_outputcost_cache_readcost_cache_write knowledge_cutoffrelease_datestatusinterleavedreturnc                 .    | j         dk    p
| j        dk    S )Nr   )r   r    selfs    -/home/ubuntu/hermes-agent/agent/models_dev.pyhas_cost_datazModelInfo.has_cost_dataV   s    ":d&6&::    c                 "    | j         pd| j        v S )Nimage)r   r   r*   s    r,   supports_visionzModelInfo.supports_visionY   s    B'T-B"BBr.   c                     d| j         v S )Npdfr   r*   s    r,   supports_pdfzModelInfo.supports_pdf\   s    ---r.   c                     d| j         v S )Naudior4   r*   s    r,   supports_audio_inputzModelInfo.supports_audio_input_   s    $///r.   c                     |                                  sdS d| j        ddd| j        ddg}| j        |                    d| j        dd           d	                    |          S )
z<Human-readable cost string, e.g. '$3.00/M in, $15.00/M out'.unknown$z.2fz/M inz/M outNzcache read $z/M, )r-   r   r    r!   appendjoin)r+   partss     r,   format_costzModelInfo.format_costb   s    !!## 	9/T_////1QT5E1Q1Q1Q1QR+LLD(<DDDDEEEyyr.   c                    g }| j         r|                    d           | j        r|                    d           |                                 r|                    d           |                                 r|                    d           |                                 r|                    d           | j        r|                    d           | j        r|                    d           |rd                    |          nd	S )
zBHuman-readable capabilities, e.g. 'reasoning, tools, vision, PDF'.r   toolsvisionPDFr7   zstructured outputzopen weightsr<   basic)	r   r=   r   r1   r5   r8   r   r   r>   )r+   capss     r,   format_capabilitieszModelInfo.format_capabilitiesk   s   > 	%KK$$$> 	!KK   !! 	"KK!!! 	KK$$&& 	!KK   ! 	-KK+,,, 	(KK'''"&3tyyG3r.   )%__name__
__module____qualname____doc__str__annotations__r   boolr   r   r   r   r   r   r	   r   r   intr   r   r   r   floatr    r!   r"   r$   r%   r&   r'   r   r-   r1   r5   r8   r@   rG   r   r.   r,   r   r   0   sE        ;;GGG
IIIKKK ItItJK#t###L$ )+eCHo***)+uS#X+++ NCJ#Ix}### JK'+OXe_+++(,huo,,, cL#FCK;t ; ; ; ;C C C C C.d . . . .0d 0 0 0 0 S        4S 4 4 4 4 4 4r.   r   c                   t    e Zd ZU dZeed<   eed<   eedf         ed<   eed<   dZeed<   d	Ze	ed
<   de
fdZdS )ProviderInfoz-Full metadata for a provider from models.dev.r   r   .envapir#   docr   model_countr(   c                 *    t          | j                  S )N)rN   rT   r*   s    r,   has_api_urlzProviderInfo.has_api_url   s    DH~~r.   N)rH   rI   rJ   rK   rL   rM   r	   rU   rV   rO   rN   rX   r   r.   r,   rR   rR      s         77GGG
III	sCx	HHHCMMMKT      r.   rR   
openrouter	anthropiczaizkimi-codingzkimi-for-codingminimaxz
minimax-cndeepseekalibabacopilotzgithub-copilotz
ai-gatewayvercelzopencode-zenopencodezopencode-gokilocodekilo	fireworkszfireworks-aihuggingfacegeminigooglexainvidiagroqmistral
togetherai
perplexitycohere)rh   ri   rj   rk   rl   rm   rn   PROVIDER_TO_MODELS_DEV_MODELS_DEV_TO_PROVIDERr(   c                  d    t           #d t                                          D             a t           S )u4   Return models.dev ID → Hermes provider ID mapping.Nc                     i | ]\  }}||	S r   r   ).0kvs      r,   
<dictcomp>z(_get_reverse_mapping.<locals>.<dictcomp>   s    "S"S"SDAq1a"S"S"Sr.   )rp   ro   itemsr   r.   r,   _get_reverse_mappingrx      s1     &"S"S4J4P4P4R4R"S"S"S""r.   c                  (    ddl m}   |             dz  S )zReturn path to disk cache file.r   get_hermes_homezmodels_dev_cache.json)hermes_constantsr{   rz   s    r,   _get_cache_pathr}      s(    000000?666r.   c                  ,   	 t                      } |                                 r=t          | d          5 }t          j        |          cddd           S # 1 swxY w Y   n2# t
          $ r%}t                              d|           Y d}~nd}~ww xY wi S )z%Load models.dev data from disk cache.zutf-8)encodingNz(Failed to load models.dev disk cache: %s)r}   existsopenjsonload	Exceptionloggerdebug)
cache_pathfes      r,   _load_disk_cacher      s    D$&&
 	$j7333 $qy||$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ D D D?CCCCCCCCDIs:   3A" A	A" AA" AA" "
B,BBdatac                     	 t                      }t          || dd           dS # t          $ r&}t                              d|           Y d}~dS d}~ww xY w)z.Save models.dev data to disk cache atomically.N),:)indent
separatorsz(Failed to save models.dev disk cache: %s)r}   r
   r   r   r   )r   r   r   s      r,   _save_disk_cacher      sz    D$&&
*d4JOOOOOO D D D?CCCCCCCCCDs   !% 
AAAFforce_refreshc           	      R   | s2t           r+t          j                    t          z
  t          k     rt           S 	 t	          j        t          d          }|                                 |                                }t          |t                    rz|rx|a t          j                    at          |           t                              dt          |          t          d |                                D                                  |S n2# t"          $ r%}t                              d|           Y d}~nd}~ww xY wt           s`t%                      a t           rKt          j                    t          z
  dz   at                              dt          t                                t           S )	zFetch models.dev registry. In-memory cache (1hr) + disk fallback.

    Returns the full registry dict keyed by provider ID, or empty dict on failure.
       )timeoutz:Fetched models.dev registry: %d providers, %d total modelsc              3      K   | ]<}t          |t                    t          |                    d i                     V  =dS )modelsN)
isinstancedictlenget)rs   ps     r,   	<genexpr>z#fetch_models_dev.<locals>.<genexpr>   sI      [[zRSUYGZGZ[Ch++,,[[[[[[r.   zFailed to fetch models.dev: %sNi,  z0Loaded models.dev from disk cache (%d providers))r   timer   _MODELS_DEV_CACHE_TTLrequestsr   MODELS_DEV_URLraise_for_statusr   r   r   r   r   r   r   sumvaluesr   r   )r   responser   r   s       r,   fetch_models_devr      s    !! Y[[115JJJ  :<;;;!!###}}dD!! 		d 		 $%)Y[["T"""LLLD		[[dkkmm[[[[[  
 K : : :5q99999999:
  e,.. 	e%)Y[[3H%H3%N"LLKSQbMcMcddds   CD	 	
D8D33D8providermodelc                    t                               |           }|sdS t                      }|                    |          }t          |t                    sdS |                    di           }t          |t                    sdS |                    |          }|rt          |          }|r|S |                                }|                                D ]2\  }	}
|	                                |k    rt          |
          }|r|c S 3dS )zLook up context_length for a provider+model combo in models.dev.

    Returns the context window in tokens, or None if not found.
    Handles case-insensitive matching and filters out context=0 entries.
    Nr   )ro   r   r   r   r   _extract_contextlowerrw   )r   r   mdev_provider_idr   provider_datar   entryctxmodel_lowermidmdatas              r,   lookup_models_dev_contextr     s    .11(;; tDHH-..MmT** tx,,Ffd## t JJuE u%% 	J ++--Kllnn  
U99;;+%%"5))C 


4r.   r   c                    t          | t                    sdS |                     d          }t          |t                    sdS |                    d          }t          |t          t          f          r|dk    rt          |          S dS )zExtract context_length from a models.dev model entry.

    Returns None for invalid/zero values (some audio/image models have context=0).
    Nlimitcontextr   )r   r   r   rO   rP   )r   r   r   s      r,   r   r   &  s    
 eT"" tIIgEeT"" t
))I

C#U|$$ q3xx4r.   c                   h    e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   dZeed<   dS )ModelCapabilitiesz;Structured capability metadata for a model from models.dev.Tsupports_toolsFr1   supports_reasoning@ r       max_output_tokensr#   model_familyN)rH   rI   rJ   rK   r   rN   rM   r1   r   r   rO   r   r   rL   r   r.   r,   r   r   ;  sz         EEND!OT!!!$$$$ NC   !s!!!L#r.   r   c                    t                               |           }|sdS t                      }|                    |          }t          |t                    sdS |                    di           }t          |t                    sdS |S )zResolve a Hermes provider ID to its models dict from models.dev.

    Returns the models dict or None if the provider is unknown or has no data.
    Nr   )ro   r   r   r   r   )r   r   r   r   r   s        r,   _get_provider_modelsr   G  s    
 .11(;; tDHH-..MmT** tx,,Ffd## tMr.   r   c                    |                      |          }t          |t                    r|S |                                }|                                 D ]6\  }}|                                |k    rt          |t                    r|c S 7dS )zBFind a model entry by exact match, then case-insensitive fallback.N)r   r   r   r   rw   )r   r   r   r   r   r   s         r,   _find_model_entryr   \  s     JJuE%  ++--Kllnn  
U99;;+%%*UD*A*A%LLL4r.   c                    t          |           }|dS t          ||          }|dS t          |                    dd                    }t          |                    dd                    }t          |                    dd                    }|                    di           }t	          |t
                    si }|                    d          }t	          |t          t          f          r|dk    rt          |          nd	}	|                    d
          }
t	          |
t          t          f          r|
dk    rt          |
          nd}|                    dd          pd}t          ||||	||          S )u  Look up full capability metadata from models.dev cache.

    Uses the existing fetch_models_dev() and PROVIDER_TO_MODELS_DEV mapping.
    Returns None if model not found.

    Extracts from model entry fields:
      - reasoning  (bool)  → supports_reasoning
      - tool_call  (bool)  → supports_tools
      - attachment (bool)  → supports_vision
      - limit.context (int) → context_window
      - limit.output  (int) → max_output_tokens
      - family     (str)   → model_family
    Nr   Fr   r   r   r   r   r   outputr   r   r#   )r   r1   r   r   r   r   )	r   r   rN   r   r   r   rO   rP   r   )r   r   r   r   r   r1   r   r   r   r   outr   r   s                r,   get_model_capabilitiesr   l  sn    "(++F~tfe,,E}t %))K7788N599\599::OeiiU;;<< IIgr""EeT"" 
))I

C!+C#u!>!>V377SXXXPVN
))H

C$.sS%L$A$AWcAggCSW99Xr**0bL%'-%+!   r.   c                 j    t          |           }|g S t          |                                          S )zReturn all model IDs for a provider from models.dev.

    Returns an empty list if the provider is unknown or has no data.
    )r   listkeys)r   r   s     r,   list_provider_modelsr     s1    
 "(++F~	r.   zZ-tts\b|embedding|live-|-(preview|exp)-\d{2,4}[-_]|-image\b|-image-preview\b|-customtools\b_NOISE_PATTERNSc                    t          |           }|g S g }|                                D ]b\  }}t          |t                    s|                    dd          s2t
                              |          rM|                    |           c|S )zReturn model IDs suitable for agentic use from models.dev.

    Filters for tool_call=True and excludes noise (TTS, embedding,
    dated preview snapshots, live/streaming, image-only models).
    Returns an empty list on any failure.
    Nr   F)r   rw   r   r   r   r   searchr=   )r   r   resultr   r   s        r,   list_agentic_modelsr     s     "(++F~	Fllnn  
U%&& 	yye,, 	!!#&& 	cMr.      queryr   c                 ~   t                      }|sg S g }|t                              |          }|sg S |                    |i           }t          |t                    r]|                    di           }t          |t                    r2|                                D ]\  }}	|                    |||	f           nt                                          D ]\  }
}|                    |i           }t          |t                    r]|                    di           }t          |t                    r2|                                D ]\  }}	|                    |
||	f           |sg S d |D             }|                                 }g }|D ]5\  }}}	||                                v r|                    |||	d           6t          j	        |||dz  d          }t                      }g }|D ]W}|d         |d	         f}||vrA|                    |           |                    |           t          |          |k    r|c S X|D ]r}|D ]m\  }}}	|                                |k    rO||f}||vrG|                    |           |                    |||	d           t          |          |k    r|c c S ns|S )
a  Fuzzy search across models.dev catalog. Returns matching model entries.

    Args:
        query: Search string to match against model IDs.
        provider: Optional Hermes provider ID to restrict search scope.
                  If None, searches across all providers in PROVIDER_TO_MODELS_DEV.
        limit: Maximum number of results to return.

    Returns:
        List of dicts, each containing 'provider', 'model_id', and the full
        model 'entry' from models.dev.
    Nr   c                 B    g | ]}|d                                           S )   )r   )rs   cs     r,   
<listcomp>z%search_models_dev.<locals>.<listcomp>  s$    888qtzz||888r.   )r   model_idr      g?)ncutoffr   r   )r   ro   r   r   r   rw   r=   r   difflibget_close_matchessetaddr   )r   r   r   r   
candidatesr   r   r   r   r   hermes_prov	mdev_provmodel_ids_lowerquery_lowersubstring_matchesprov	fuzzy_idsseen_idsresultsmatchkeyfids                         r,   search_models_devr     sN    D 	 !J155h?? 	I!1266mT** 	>"&&x44F&$'' >"(,,.. > >JC%%xe&<==== '=&B&B&D&D 	E 	E"K HHY33M-.. E&**8R88fd++ E&,llnn E E
U"));U*CDDDD 	 98Z888O++--K & Z Zc5#))++%%$$$CRW%X%XYYY )_	#  I EEH$&G #  Z %
"34hLLNN5!!!7||u$$  	' 	' * 	' 	'D#uyy{{c!!Skh&&LL%%%NN#PU#V#VWWW7||u,,&	' Nr.   r   rawr   c                    |                     d          pi }t          |t                    si }|                     d          pi }t          |t                    si }|                     d          pi }t          |t                    si }|                     d          pg }|                     d          pg }|                     d          }t          |t          t          f          r|dk    rt          |          nd}	|                     d          }
t          |
t          t          f          r|
dk    rt          |
          nd}|                     d          }t          |t          t          f          r|dk    rt          |          nd}t          di d	| d
|                     d
d          p| d|                     dd          pdd|dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |                     dd                    dt          |t                    rt          |          nddt          |t                    rt          |          ndd|	d|d|dt	          |                     dd          pd          dt	          |                     dd          pd          dd|v r|d         t	          |d                   nddd |v r|d          t	          |d                    ndd!|                     d"d          pdd#|                     d#d          pdd$|                     d$d          pdd%|                     d%d          S )&zEConvert a raw models.dev model entry dict into a ModelInfo dataclass.r   cost
modalitiesinputr   r   r   Nr   r   r#   r   r   r   Fr   r   r   r   r   r   r   r   r   r   r   r   r    r!   
cache_readr"   cache_writer$   	knowledger%   r&   r'   )	r   r   r   rO   rP   r   rN   r   tuple)r   r   r   r   r   r   
input_modsoutput_modsr   ctx_intr   out_intinpinp_ints                 r,   _parse_model_infor   &  s@   GGG"EeT"" 776?? bDdD!! &&,"Jj$'' 
((.BJ..**0bK
))I

C$S3,77JC!GGc#hhhG
))H

C$S3,77JC!GGc#hhhG
))G

C$S3,77MC!GGc#hhhG   8WWVR  ,H wwx$$*  K	
 sww{E22333 sww{E22333 e44555 66777 sww':EBBCCC #''.%88999 /9T.J.JRz***PR 1;;0M0MU%,,,SU w 7 '  '1--2333!" $((8Q//41555#$ 6BT5I5IdS_N`Nld<0111rv%& 8E7L7LQUVcQdQptM2333vz'( b117R)* WW^R006B+, wwx$$*-. GGM5111/ r.   c                    |                     d          pg }|                     d          pi }t          | |                     dd          p| t          |t                    rt	          |          nd|                     dd          pd|                     dd          pdt          |t
                    rt          |          nd	          S )
zAConvert a raw models.dev provider entry dict into a ProviderInfo.rS   r   r   r#   r   rT   rU   r   )r   r   rS   rT   rU   rV   )r   rR   r   r   r   r   r   )r   r   rS   r   s       r,   _parse_provider_infor   Y  s    
''%..
BCWWX$"FWWVR  /K$S$//7E#JJJRGGE2$"GGE2$"#-fd#;#;BCKKK   r.   c                     t                               | |           }t                      }|                    |          }t          |t                    sdS t          ||          S )zGet full provider metadata from models.dev.

    Accepts either a Hermes provider ID (e.g. "kilocode") or a models.dev
    ID (e.g. "kilo").  Returns None if the provider is not in the catalog.
    N)ro   r   r   r   r   r   )r   mdev_idr   r   s       r,   get_provider_infor  k  s\     %((kBBGD
((7

Cc4   t---r.   c                      t                      } i }|                                 D ]/\  }}t          |t                    rt	          ||          }|||<   0|S )u   Return all providers from models.dev as {provider_id: ProviderInfo}.

    Returns the full catalog — 109+ providers.  For providers that have
    a Hermes alias, both the models.dev ID and the Hermes ID are included.
    )r   rw   r   r   r   )r   r   pidpdatainfos        r,   list_all_providersr  |  s_     D&(Fjjll  
UeT"" 	'U33DF3KMr.   env_varc                    t                      }g }|                                D ]^\  }}t          |t                    rD|                    dg           }t          |t
                    r| |v r|                    |           _|S )zReverse lookup: find all providers that use a given env var.

    Useful for auto-detection: "user has ANTHROPIC_API_KEY set, which
    providers does that enable?"

    Returns list of models.dev provider IDs.
    rS   )r   rw   r   r   r   r   r=   )r  r   matchesr  r  rS   s         r,   get_providers_for_env_varr
    s     DGjjll $ $
UeT"" 	$))E2&&C#t$$ $Cs###Nr.   c                 \   t                               | |           }t                      }|                    |          }t          |t                    sdS |                    di           }t          |t                    sdS |                    |          }t          |t                    rt          |||          S |                                }|                                D ]E\  }}	|                                |k    r(t          |	t                    rt          ||	|          c S FdS )zGet full model metadata from models.dev.

    Accepts Hermes or models.dev provider ID.  Tries exact match then
    case-insensitive fallback.  Returns None if not found.
    Nr   )ro   r   r   r   r   r   r   rw   )
r   r   r   r   r  r   r   r   r   r   s
             r,   get_model_infor    s    %((kBBGDHHWEeT"" tYYx$$Ffd## t **X

C#t 9 3888 ..""Kllnn : :
U99;;+%%*UD*A*A%$S%999994r.   c                    t                      }t                                          D ]
\  }}|                    |          }t	          |t
                    s1|                    di           }t	          |t
                    s]|                    |           }t	          |t
                    rt          | ||          c S |                                 }|                                D ]G\  }}	|                                |k    r*t	          |	t
                    rt          ||	|          c c S H|                                D ]\  }
}|
t                      v rt	          |t
                    s,|                    di           }t	          |t
                    sX|                    |           }t	          |t
                    rt          | ||
          c S dS )zSearch all providers for a model by ID.

    Useful when you have a full slug like "anthropic/claude-sonnet-4.6" or
    a bare name and want to find it anywhere.  Checks Hermes-mapped providers
    first, then falls back to all models.dev providers.
    r   N)	r   ro   rw   r   r   r   r   r   rx   )r   r   	hermes_idr   r  r   r   r   r   r   r  s              r,   get_model_info_any_providerr    s    D 5::<< > >	7!!%&& 	8R((&$'' 	jj""c4   	=$XsG<<<<< nn&& ,,.. 	> 	>JCyy{{k))j.E.E)(eW=======	>
 jjll 9 9
U&((((%&& 	8R((&$'' 	jj""c4   	9$XsC88888	9 4r.   c                    t                               | |           }t                      }|                    |          }t          |t                    sg S |                    di           }t          |t                    sg S g }|                                D ]\\  }}t          |t                    s|                    dd          }|dk    r8|                    t          |||                     ]|S )zjReturn all models for a provider as ModelInfo objects.

    Filters out deprecated models by default.
    r   r&   r#   
deprecated)ro   r   r   r   r   rw   r=   r   )	r   r   r   r  r   r   r   r   r&   s	            r,   list_provider_model_infosr    s    
 %((kBBGDHHWEeT"" 	YYx$$Ffd## 	 Fllnn > >
U%&& 	8R((\!!'UG<<====Mr.   )F)Nr   )>rK   r   r   loggingosr   dataclassesr   pathlibr   typingr   r   r   r   r	   utilsr
   r   	getLoggerrH   r   r   r   r   rL   rM   r   rP   r   rR   ro   rp   rx   r}   r   r   rN   r   rO   r   r   r   r   r   r   r   recompile
IGNORECASEr   Patternr   r   r   r   r  r  r
  r  r  r  r   r.   r,   <module>r     s    (    				  ! ! ! ! ! !       3 3 3 3 3 3 3 3 3 3 3 3 3 3 # # # # # # 		8	$	$.  %' 4S> & & & !  ! ! ! K4 K4 K4 K4 K4 K4 K4 K4\        &*,** 
5* $	*
 y* ,* 
* y* * (* J* =* * * =*  h!*" h#*$ 1* * * S#X   8 59 $sCx.1 8 8 8#d38n # # # #7 7 7 7 7	$sCx. 	 	 	 	D4S> Dd D D D D) )D )T#s(^ ) ) ) )X" "C "HSM " " " "JDcN x}    *        3 8DcN+C    *d38n S Xd3PS8n=U     /S / /BS9T / / / /d3 49     
			(bj0M    # $s)    0 45U UUU-0U	$sCx.U U U Ux0 0$sCx. 0s 0y 0 0 0 0fc S#X <    $.3 .8L+A . . . ."Dl!23    "s tCy    0 #i   B*# *(92E * * * *Z3 4	?      r.   