+
    lHàj_0  ã                  ó  € R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
HtHt ]P                  ! R4      tR tR R	 lt ! R
 R4      tR R ltR R lt ! R R]4      tRtRtR R ltRR R llt ! R R]4      t ! R R]4      tR# )uÎ  Wake-word hotword engines (pyopen-wakeword / sherpa-onnx KWS / Porcupine).

All three run fully on-device. Config, platform probes and sensitivity accessors
live in :mod:`tools.wake_word`; engines read them lazily through that module (import cycle).
This module is the SINGLE owner of the engine implementations â€” ``tools.wake_word``
imports these classes and must not shadow them with copies.

Dependency admission: constructing an engine ensures its ``wake-*`` extra. The
``audio-io`` extra (sounddevice + numpy) is ensured only when the resolved
capture mode is ``local`` â€” client capture (desktop/TUI streaming PCM via
``wake.feed``) never needs, and must never trigger installation of, local
audio libraries.
)ÚannotationsN)Úsuppress)ÚPath)ÚAnyÚDictÚOptionalztools.wake_wordc                 ó   € ^ RI Hp  V # )é    ©Ú	wake_word)Útoolsr   r
   s    Ú</home/ubuntu/.hermes/hermes-agent/tools/wake_word_engines.pyÚ_wwr      s   € ÝØÐó    c               ó$   € V ^8„  d   QhRRRRRR/# )é   ÚfeatureÚstrÚcfgúdict[str, Any]ÚreturnÚNone© )Úformats   "r   Ú__annotate__r      s!   € ÷ %ñ %˜ð % >ð %°dñ %r   c                óÄ   € ^ RI pVP                  V 4       \        4       P                  V4      R8X  d-   VP	                  R4      '       g   VP                  R4       R# R# R# )r	   NÚlocalzaudio-io)ÚpmÚensure_importr   Úresolve_capture_modeÚ	available)r   r   r   s   && r   Ú_ensure_depr!      sM   € Ûà×Ñ�WÔä
ƒu×!Ñ! #Ó&¨'Ô1¸"¿,¹,Àz×:RÒ:RØ
×Ñ˜Ö$ñ ;SÑ1r   c                  ó�   € ] tR t^(t$ RtRtR]R&   RtR]R&   RtR]R&   R	t	R
]R&   R R lt
R R ltR R ltR R ltR R ltRtR	# )Ú_Enginez²Minimal hotword-engine contract: feed int16 frames, get a bool. Subclasses set ``feature``
(the pm extra ensured before ``_build``) and their own ``cfg`` sub-section ``section``.Ú r   r   Úsectioné   ÚintÚframe_lengthNzOptional[tuple[str, str]]Ú
last_matchc               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   Ú_Engine.__annotate__4   s   € ÷ 9ñ 9˜Nñ 9r   c                	óŽ   € \        V P                  V4       V P                  V\        WP                  4      \        4       4       R # ©N)r!   r   Ú_buildÚ_subr%   r   )Úselfr   s   &&r   Ú__init__Ú_Engine.__init__4   s+   € Ü�D—L‘L #Ô&Ø�‰�Cœ˜c§<¡<Ó0´#³%Ö8r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úsubr   r   r   )r   s   "r   r   r+   8   s!   € ÷ "ñ "˜.ð "¨~ð "Àdñ "r   c                	ó   € \         hr-   ©ÚNotImplementedError)r0   r   r4   Úwws   &&&&r   r.   Ú_Engine._build8   ó   € Ü!Ð!r   c               ó   € V ^8„  d   QhRR/# ©r   r   Úboolr   )r   s   "r   r   r+   ;   s   € ÷ "ñ " ñ "r   c                	ó   € \         hr-   r6   ©r0   Úframes   &&r   ÚprocessÚ_Engine.process;   r:   r   c               ó   € V ^8„  d   QhRR/# ©r   r   r   r   )r   s   "r   r   r+   >   s   € ÷ Sñ S�tñ Sr   c                ó   € R# )zDClear any internal audio/feature buffer (called on every (re)start).Nr   ©r0   s   &r   ÚresetÚ_Engine.reset>   ó   ‚ r   c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   r+   A   s   € ÷ >ñ >�tñ >r   c                ó   € R# )z/Release engine resources (called once on stop).Nr   rF   s   &r   ÚcloseÚ_Engine.closeA   rI   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Ú__annotations__r%   r(   r)   r1   r.   rA   rG   rL   Ú__static_attributes__r   r   r   r#   r#   (   sT   ‡ ñ_ð €GˆSÓØ€GˆSÓØ€L�#Óð -1€JÐ)Ó0õ9õ"õ"õS÷>ñ >r   r#   c               ó    € V ^8„  d   QhRRRR/# )r   Úvaluer   r   r=   r   )r   s   "r   r   r   E   s   € ÷ dñ d˜Cð d Dñ dr   c                ó¨   € \         P                  V 9   ;'       g9    V P                  R4      ;'       g     \         P                  P	                  V 4      # )ú.onnx)rX   z.tflitez.ppn)ÚosÚsepÚendswithÚpathÚexists)rV   s   &r   Ú_looks_like_pathr^   E   s8   € Ü�6‰6�U‰?×cÐc˜eŸn™nÐ-IÓJ×cÐcÌbÏgÉgÏnÉnÐ]bÓNcÐcr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Úkeyr   r   r   )r   s   "r   r   r   I   s!   € ÷ 0ñ 0ˆnð 0 3ð 0¨>ñ 0r   c                óX   € V P                  V4      p\        V\        4      '       d   V# / # r-   )ÚgetÚ
isinstanceÚdict)r   r`   r4   s   && r   r/   r/   I   s&   € Ø
�'‰'�#‹,€CÜ˜S¤$×'Ò'ˆ3Ð/¨RÐ/r   c                  óT   € ] tR t^NtRtRRuttR R ltR R ltR R	 lt	R
 R lt
RtR# )Ú_OpenWakeWordEngineun  pyopen-wakeword â€” free, local hotword detection (TFLite via a bundled
tensorflowlite_c lib; no runtime download, no framework choice). Scores one
~80 ms frame at a time; ``sensitivity`` IS the raw 0..1 threshold (higher =
stricter). A real utterance holds the score high across frames while a stray
phoneme spikes one, so ``confirmation_frames`` hits are required.zwake-openwakewordÚopenwakewordc               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   Ú _OpenWakeWordEngine.__annotate__W   s   € ÷ (ñ ( dñ (r   c                	óà  € ^ RI HpHp \        VP	                  R4      ;'       g    VP
                  4      P                  4       pVP                  4       VP                  9   d   VP                  4       pVP                  V4      V n        VP                  V4      V n        ^ V n        VP                  4       V n        VP#                  V4      V n        V P$                  P&                  .V n        R# )r	   )ÚOpenWakeWordÚOpenWakeWordFeaturesÚmodelN)Úpyopen_wakewordrk   rl   r   rb   Ú_BUNDLED_MODEL_NAMEÚstripÚlowerÚ_BUNDLED_MODEL_ALIASESÚ_bundled_wakeword_pathÚ_sensitivityÚ
_thresholdÚ_confirmation_framesÚ_confirm_neededÚ_confirm_streakÚfrom_builtinÚ	_featuresÚ
from_modelÚ_modelÚidÚ_labels)r0   r   r4   r8   rk   rl   Ú	model_refs   &&&&   r   r.   Ú_OpenWakeWordEngine._buildW   sµ   € ßFä˜Ÿ™ Ó(×BÐB¨B×,BÑ,BÓC×IÑIÓKˆ	ð
 �?‰?Ó × 9Ñ 9Ô9Ø×1Ñ1Ó3ˆIð
 Ÿ/™/¨#Ó.ˆŒØ!×6Ñ6°sÓ;ˆÔØ ˆÔØ-×:Ñ:Ó<ˆŒØ"×-Ñ-¨iÓ8ˆŒØŸ™Ÿ™Ð'ˆŽr   c               ó   € V ^8„  d   QhRR/# r<   r   )r   s   "r   r   ri   l   s   € ÷ ñ  ñ r   c                	ór  € R pV P                   P                  VP                  4       4       F9  pV P                  P                  V4       F  pW@P                  8¼  g   K  RpK  	  K;  	  V'       d@   V ;P
                  ^,          un        V P
                  V P                  8¼  d
   ^ V n        R# R # ^ V n        R # )FT)rz   Úprocess_streamingÚtobytesr|   ru   rx   rw   )r0   r@   ÚoverÚembÚscores   &&   r   rA   Ú_OpenWakeWordEngine.processl   s”   € ð ˆØ—>‘>×3Ñ3°E·M±M³OÖDˆCØŸ™×6Ñ6°sÖ;�ØŸO™OÖ+Ø’Dó <ñ E÷ Ø× Ò  AÕ%Õ Ø×#Ñ# t×';Ñ';Ô;Ø'(�Ô$ÙÙØ ˆÔÙr   c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   ri   €   s   € ÷  ñ  �tñ  r   c                	óä   € ^ V n         \        \        4      ;_uu_ 4        V P                  P	                  4        V P
                  P	                  4        RRR4       R#   + '       g   i     R# ; i)r	   N)rx   r   Ú	Exceptionrz   rG   r|   rF   s   &r   rG   Ú_OpenWakeWordEngine.reset€   sF   € ð  !ˆÔÜ”i× Õ Ø�N‰N× Ñ Ô"Ø�K‰K×ÑÔ÷ !× × Ò ús   Ÿ5AÁA/	c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   ri   ˆ   s   € ÷  ñ  �tñ  r   c                	óö   € V P                  4        \        \        4      ;_uu_ 4        V P                  P	                  4        V P
                  P	                  4        R R R 4       R #   + '       g   i     R # ; ir-   )rG   r   r‹   rz   rL   r|   rF   s   &r   rL   Ú_OpenWakeWordEngine.closeˆ   sE   € Ø�
‰
ŒÜ”i× Õ Ø�N‰N× Ñ Ô"Ø�K‰K×ÑÔ÷ !× × Ò ús   ¨5A'Á'A8	)rw   rx   rz   r~   r|   ru   N)rN   rO   rP   rQ   rR   r   r%   r.   rA   rG   rL   rT   r   r   r   rf   rf   N   s/   † ñIð +¨NÐ€GˆWõ(õ*õ( ÷ ñ  r   rf   zhttps://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/sherpa-onnx-kws-zipformer-gigaspeech-3.3M-2024-01-01.tar.bz2z4sherpa-onnx-kws-zipformer-gigaspeech-3.3M-2024-01-01c               ó   € V ^8„  d   QhRR/# )r   r   r   r   )r   s   "r   r   r   ˜   s   € ÷ 5ñ 5˜Dñ 5r   c                 ó8   € ^ RI Hp  V ! 4       R,          R,          # )r	   ©Úget_hermes_homeÚcacheÚ	wakewords)Úhermes_constantsr“   r’   s    r   Ú_sherpa_model_rootr—   ˜   s   € Ý0ÙÓ˜wÕ&¨Õ4Ð4r   c               ó    € V ^8„  d   QhRRRR/# )r   ÚrootzOptional[Path]r   r   r   )r   s   "r   r   r   �   s   € ÷ ñ ˜~ð ¸ñ r   c                óR  € T ;'       g    \        4       p V \        ,          pVR,          P                  4       '       d   V# ^ RIp^ RIpV P                  RRR7       V \         R2,          p\        P                  R4       VP                  P                  \        V4       VP                  VR4      ;_uu_ 4       pVP                  V RR	7       RRR4       VP                  RR
7       VR,          P                  4       '       g   \        RV 24      hV#   + '       g   i     LO; i)zBDownload + unpack the sherpa KWS model once; return its directory.ú
tokens.txtNT)ÚparentsÚexist_okz.tar.bz2z:wake word: downloading sherpa KWS model (one-time, ~13 MB)zr:bz2Údata)Úfilter)Ú
missing_okz sherpa KWS model unpack failed: )r—   Ú_SHERPA_KWS_MODEL_DIRr]   ÚtarfileÚurllib.requestÚmkdirÚloggerÚinfoÚrequestÚurlretrieveÚ_SHERPA_KWS_MODEL_URLÚopenÚ
extractallÚunlinkÚRuntimeError)r™   Útargetr¢   ÚurllibÚarchiveÚtfs   &     r   Ú_ensure_sherpa_modelr²   �   sí   € à×'Ð'Ô%Ó'€DØÔ)Õ)€FØ�Õ×%Ñ%×'Ò'ØˆÛÛØ‡J�J�t d€JÔ+ØÔ-Ð.¨hÐ7Õ7€GÜ
‡K�KÐLÔMØ
‡N�N×ÑÔ4°gÔ>Ø	�‰�g˜w×	'Ô	'¨2Ø
�‰�d 6ˆÔ*÷ 
(à‡N�N˜d€NÔ#Ø�\Õ!×)Ñ)×+Ò+ÜÐ=¸f¸XÐFÓGÐGØ€M÷ 
(×	'ús   Â;DÄD&	c                  óX   € ] tR t^±tRtRRuttRtR R ltR R lt	R	 R
 lt
R R ltRtR# )Ú_SherpaKwsEngineuÊ   sherpa-onnx open-vocabulary keyword spotting â€” any typed phrase, zero training. ``wake_word.phrase``
is BPE-tokenized at runtime against the model's vocabulary: DETECTION config, not a cosmetic label.zwake-sherpaÚsherpar&   c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   Ú_SherpaKwsEngine.__annotate__¸   s   € ÷ /5ñ /5 dñ /5r   c           
     	ó¦  a€ ^ RI p^ RIp^ RI Hp \        VP	                  R4      ;'       g    R4      P                  4       pV'       d   \        V4      M	\        4       oSR,          P                  4       '       g   \        RS 24      h\        VP                  VR4      ;'       g    R4      P                  4       pWƒP                  4       /p	\        VP	                  R	R
4      4      '       dH   VP                  4       P                  4        F%  w  r«V	P                  VP                  4       V
4       K'  	  \!        V	4      pT! V Uu. uF  q»P#                  4       NK  	  up\        SR,          4      R\        SR,          4      R7      p/ V n        VP'                  RRRRRR7      p\)        WÍ4       Fe  w  r¿VP#                  4       P+                  RR4      pW›,          V P$                  V&   VP-                  RP/                  V4      RV R2,           4       Kg  	  VP1                  4        VP2                  V n        RRVP7                  V4      ,          ,           pR V3R llpVP9                  \        SR,          4      V! R4      V! R4      V! R4      V P4                  V^R7      V n        V P:                  P=                  4       V n        R# u upi ) r	   N)Ú
text2tokenÚ	model_dirr$   r›   zsherpa KWS model not found at Úphrasez
hey hermesÚprofile_routingTÚbpez	bpe.model)ÚtokensÚtokens_typeÚ	bpe_modelÚwz.txtzhermes-kws-Fzutf-8)ÚmodeÚsuffixÚprefixÚdeleteÚencodingÚ Ú_z @Ú
gš™™™™™©?gš™™™™™Ù?c               ó    € V ^8„  d   QhRRRR/# )r   Úpartr   r   r   )r   s   "r   r   Ú-_SherpaKwsEngine._build.<locals>.__annotate__Ü   s   € ÷ 	 ñ 	 ˜cð 	  cñ 	 r   c                ó–   <€ \        SP                  V  R 24      4      pV'       g   \        RS RV  R 24      h\        V^ ,          4      # )z-*[!8].onnxzsherpa KWS model file missing: Ú/)ÚsortedÚglobr­   r   )rË   ÚhitsÚds   & €r   Ú_model_fileÚ,_SherpaKwsEngine._build.<locals>._model_fileÜ   sI   ø€ Ü˜!Ÿ&™& D 6¨Ð!5Ó6Ó7ˆDßÜ"Ð%DÀQÀCÀqÈÈÈkÐ#ZÓ[Ð[Ü�t˜A•w“<Ðr   ÚencoderÚdecoderÚjoiner)r¾   rÕ   rÖ   r×   Úkeywords_fileÚkeywords_thresholdÚnum_threads) Úsherpa_onnxÚtempfiler¹   r   rb   rp   r   r²   r]   r­   Ú_getÚ_active_profile_namer=   Úenrolled_profile_phrasesÚitemsÚ
setdefaultÚlistÚupperÚ_display_to_profileÚNamedTemporaryFileÚzipÚreplaceÚwriteÚjoinrL   ÚnameÚ_keywords_filert   ÚKeywordSpotterÚ_spotterÚcreate_streamÚ_stream)r0   r   r4   r8   rÛ   rÜ   r¹   rº   r»   Ú
phrase_mapÚprofÚpÚphrasesr¾   ÚkwÚtoksÚdisplayÚ	thresholdrÓ   rÒ   s   &&&&               @r   r.   Ú_SherpaKwsEngine._build¸   s[  ø€ ÛÛÝ*Ü˜Ÿ™ Ó,×2Ð2°Ó3×9Ñ9Ó;ˆ	ß(ŒD�ŒOÔ.BÓ.DˆØ�LÕ ×(Ñ(×*Ò*ÜÐ!?À¸sÐCÓDÐDô �R—W‘W˜S (Ó+×;Ð;¨|Ó<×BÑBÓDˆØ&,×.EÑ.EÓ.GÐ%Hˆ
Ü�—‘Ð)¨4Ó0×1Ò1Ø×6Ñ6Ó8×>Ñ>Ö@‘�Ø×%Ñ% a§g¡g£i°Ö6ñ Aä�zÓ"ˆÙ±Ó8±¨1ŸW™WžY±Ñ8ÄÀQÈÕEUÓAVÐdiÜ&)¨!¨k­/Ó&:ô<ˆð 46ˆÔ Ø×(Ñ(¨c¸&ÈÐ_dØ29ð )ó ;ˆä˜7Ö+‰GˆAØ—g‘g“i×'Ñ'¨¨SÓ1ˆGØ0:µˆD×$Ñ$ WÑ-Ø�H‰H�S—X‘X˜d“^¨¨7¨)°2Ð&6Õ6Ö7ñ ,ð 	�‰Œ
Ø Ÿg™gˆÔð
 ˜3 §¡°Ó!5Õ5Õ5ˆ	÷	 ð 	 ð $×2Ñ2Ü�q˜<Õ'Ó(±+¸iÓ2HÑR]Ð^gÓRhÙ˜xÓ(¸×8KÑ8KÐ`iØð 3ó 
ˆŒð
 —}‘}×2Ñ2Ó4ˆŽùò= 9s   ÅKc               ó   € V ^8„  d   QhRR/# r<   r   )r   s   "r   r   r·   é   s   € ÷ ñ  ñ r   c                	ó–  € ^ RI pV P                  P                  \        4       P                  VP                  WP                  R7      R,          4       RpV P                  P                  V P                  4      '       dÉ   V P                  P                  V P                  4       V P                  P                  V P                  4      pV'       g   K  R\        V4      rSVP                  RR4      P                  4       V P                  P                  VR4      3V n        V P                  P#                  V P                  4       Kó  V# )	r	   N)Údtypeg      à@FTrÈ   rÇ   r$   )Únumpyrï   Úaccept_waveformr   ÚSAMPLE_RATEÚasarrayÚfloat32rí   Úis_readyÚdecode_streamÚ
get_resultr   rç   rq   rä   rb   r)   Úreset_stream)r0   r@   ÚnpÚfiredÚresultrö   s   &&    r   rA   Ú_SherpaKwsEngine.processé   sæ   € ÛØ�‰×$Ñ$¤S£U×%6Ñ%6¸¿
¹
À5×PZÑPZ¸
Ó8[Ð^eÕ8eÔfØˆØ�m‰m×$Ñ$ T§\¡\×2Ò2Ø�M‰M×'Ñ'¨¯©Ô5Ø—]‘]×-Ñ-¨d¯l©lÓ;ˆFß‰vØ!%¤s¨6£{�wØ#*§?¡?°3¸Ó#<×#BÑ#BÓ#DØ#'×#;Ñ#;×#?Ñ#?ÀÈÓ#Lð#N�”à—‘×*Ñ*¨4¯<©<Ö8Øˆr   c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   r·   ÷   s   € ÷ 9ñ 9�tñ 9r   c                	ó¬   € \        \        4      ;_uu_ 4        V P                  P                  4       V n        R R R 4       R #   + '       g   i     R # ; ir-   )r   r‹   rí   rî   rï   rF   s   &r   rG   Ú_SherpaKwsEngine.reset÷   s0   € ä”i× Õ ØŸ=™=×6Ñ6Ó8ˆDŒL÷ !× × Ò ús   ˜ AÁA	c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   r·   ü   s   € ÷ +ñ +�tñ +r   c                	ó®   € \        \        4      ;_uu_ 4        \        P                  ! V P                  4       R R R 4       R #   + '       g   i     R # ; ir-   )r   ÚOSErrorrY   r¬   rë   rF   s   &r   rL   Ú_SherpaKwsEngine.closeü   s.   € Ü”g×ÕÜ�IŠI�d×)Ñ)Ô*÷ ××Òús   ˜!AÁA	)rä   rë   rí   rï   r)   N)rN   rO   rP   rQ   rR   r   r%   r(   r.   rA   rG   rL   rT   r   r   r   r´   r´   ±   s5   † ñkð % hÐ€GˆWØ€Lõ/5õbõ9÷
+ñ +r   r´   c                  óH   € ] tR tRtRtRRuttR R ltR R ltR	 R
 lt	Rt
R# )Ú_PorcupineEnginei  u@   Picovoice Porcupine â€” premium, on-device, needs an access key.zwake-porcupineÚ	porcupinec               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   Ú_PorcupineEngine.__annotate__  s   € ÷ 9ñ 9 dñ 9r   c                	óÄ  € ^ RI p\        P                  ! R4      ;'       g    RP                  4       pV'       g   \	        R4      h\        VP                  R4      ;'       g    R4      P                  4       pRVRR	VP                  V4      ,
          ./pV.T\        V4      '       d   R
MR&   VP                  ! R/ VB V n
        V P                  P                  V n        R# )r	   NÚPORCUPINE_ACCESS_KEYr$   zcPorcupine wake word requires PORCUPINE_ACCESS_KEY (get a free key at https://console.picovoice.ai).ÚkeywordÚjarvisÚ
access_keyÚsensitivitiesg      ð?Úkeyword_pathsÚkeywordsr   )ÚpvporcupinerY   Úgetenvrp   r­   r   rb   rt   r^   ÚcreateÚ
_porcupiner(   )r0   r   r4   r8   r  r  r  Úkwargss   &&&&    r   r.   Ú_PorcupineEngine._build  sÆ   € ÛÜ—i’iÐ 6Ó7×=Ð=¸2×DÑDÓFˆ
ßÜð  Só Tð Tä�c—g‘g˜iÓ(×4Ð4¨HÓ5×;Ñ;Ó=ˆð #/°
¸OÈcÐTV×TcÑTcÐdgÓThÕNhÐMiÐ!jˆØPWÈyˆÔ"2°7×";Ò";‰ÀÑLØ%×,Ò,Ñ6¨vÑ6ˆŒØ ŸO™O×8Ñ8ˆÖr   c               ó   € V ^8„  d   QhRR/# r<   r   )r   s   "r   r   r    s   € ÷ 3ñ 3 ñ 3r   c                	ó>   € V P                   P                  V4      ^ 8¬  # )r	   )r   rA   r?   s   &&r   rA   Ú_PorcupineEngine.process  s   € Ø�‰×&Ñ& uÓ-°Ñ2Ð2r   c               ó   € V ^8„  d   QhRR/# rD   r   )r   s   "r   r   r    s   € ÷ %ñ %�tñ %r   c                	ó¢   € \        \        4      ;_uu_ 4        V P                  P                  4        R R R 4       R #   + '       g   i     R # ; ir-   )r   r‹   r   rÅ   rF   s   &r   rL   Ú_PorcupineEngine.close  s,   € Ü”i× Õ Ø�O‰O×"Ñ"Ô$÷ !× × Ò ús	   ˜=½A	)r   r(   N)rN   rO   rP   rQ   rR   r   r%   r.   rA   rL   rT   r   r   r   r  r    s%   † ÙJà'¨Ð€GˆWõ9õ3÷%ñ %r   r  r-   )rR   Ú
__future__r   ÚloggingrY   Ú
contextlibr   Úpathlibr   Útypingr   r   r   Ú	getLoggerr¥   r   r!   r#   r^   r/   rf   r©   r¡   r—   r²   r´   r  r   r   r   Ú<module>r/     s—   ðñõ #ã Û 	Ý Ý ß &Ñ &à	×	Ò	Ð,Ó	-€òõ
%÷>ñ >õ:dõ0ô
> ˜'ô > ðHCð ð OÐ õ5÷
ô(M+�wô M+ô`%�wö %r   