§
    ÷žyj":  ã                  óp  — U d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZmZ ddlZddlmZ  ej        e¦  «        Z ej        d¦  «        Z ej        d¦  «        Zi ad	ed
<   daded<   d7d„Zd8d„Zd9d„Zd:d„Zd;d„Zd<d„Zd<d„Z d=d„Z!d>d!„Z"d?d#„Z#	 	 	 d@dAd+„Z$dBd,„Z%	 	 	 dCdDd4„Z&dBd5„Z'dEd6„Z(dS )FuÑ  Skill bundles â€” aliases that load multiple skills under one slash command.

A skill bundle is a small YAML file that names a set of skills to load
together. Invoking ``/<bundle-name>`` from the CLI or gateway loads every
referenced skill's full content into a single user message, the same way
``/<skill-name>`` does â€” but for N skills at once.

Storage
-------
Bundles live in ``~/.hermes/skill-bundles/*.yaml`` (and the equivalent
profile-aware directory under ``HERMES_HOME``). Each file looks like::

    name: backend-dev
    description: Backend feature work â€” code review, testing, PR workflow.
    skills:
      - github-code-review
      - test-driven-development
      - github-pr-workflow
    instruction: |
      Optional extra guidance to inject above the skill bodies.

The file's stem is treated as a fallback name when ``name:`` is absent, so
dropping a YAML into the directory is enough to register a new bundle.

Conflict resolution
-------------------
If a bundle and a skill share the same slash name, the bundle wins. The
slash command dispatch checks bundles first, then falls back to skills.
This is the intended behavior â€” a user who names a bundle ``research``
explicitly wants ``/research`` to mean their bundle, not whatever skill
happens to share the slug.

Public API
----------
- :func:`get_skill_bundles` â€” return ``{"/slug": bundle_info}``
- :func:`resolve_bundle_command_key` â€” map a user-typed command to its slug
- :func:`build_bundle_invocation_message` â€” produce the full user message
- :func:`reload_bundles` â€” re-scan disk and return a diff
- :func:`list_bundles` â€” return rich info for display (``hermes bundles``)
- :func:`save_bundle` / :func:`delete_bundle` â€” file-level operations
é    )ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚOptionalÚTuple)Úget_hermes_homez
[^a-z0-9-]z-{2,}úDict[str, Dict[str, Any]]Ú_bundles_cachezOptional[float]Ú_bundles_cache_mtimeÚreturnr   c                 ó¨   — t           j                             d¦  «        } | r!t          | ¦  «                             ¦   «         S t          ¦   «         dz  S )zŸReturn the canonical bundles directory under HERMES_HOME.

    Honors ``HERMES_BUNDLES_DIR`` for tests; falls back to
    ``<HERMES_HOME>/skill-bundles``.
    ÚHERMES_BUNDLES_DIRzskill-bundles)ÚosÚenvironÚgetr   Ú
expanduserr
   )Úoverrides    ú9/home/ragecks/.hermes/hermes-agent/agent/skill_bundles.pyÚ_bundles_dirr   B   sI   € õ Œz�~Š~Ð2Ñ3Ô3€HØð +Ý�H‰~Œ~×(Ò(Ñ*Ô*Ð*ÝÑÔ˜Ñ.Ð.ó    ÚnameÚstrc                ó  — |                       ¦   «                              dd¦  «                             dd¦  «        }t                               d|¦  «        }t                               d|¦  «                             d¦  «        }|S )NÚ ú-Ú_Ú )ÚlowerÚreplaceÚ_BUNDLE_INVALID_CHARSÚsubÚ_BUNDLE_MULTI_HYPHENÚstrip)r   Úcmds     r   Ú_slugifyr'   N   sl   € Ø
�*Š*‰,Œ,×
Ò
˜s CÑ
(Ô
(×
0Ò
0°°cÑ
:Ô
:€CÝ
×
#Ò
# B¨Ñ
,Ô
,€CÝ
×
"Ò
" 3¨Ñ
,Ô
,×
2Ò
2°3Ñ
7Ô
7€CØ€Jr   ú
List[Path]c                 óÆ   — t          ¦   «         } |                      ¦   «         sg S g }dD ]7}|                     t          |                      |¦  «        ¦  «        ¦  «         Œ8|S )N)z*.yamlz*.yml)r   ÚexistsÚextendÚsortedÚglob)ÚbaseÚfilesÚexts      r   Ú_iter_bundle_filesr1   U   s`   € Ý‰>Œ>€DØ�;Š;‰=Œ=ð Øˆ	Ø€EØ"ð -ð -ˆØ�Š•V˜DŸIšI c™NœNÑ+Ô+Ñ,Ô,Ð,Ð,Ø€Lr   r/   Úfloatc                óp  — t          ¦   «         }g }|                     ¦   «         r>	 |                     |                     ¦   «         j        ¦  «         n# t
          $ r Y nw xY w| D ]?}	 |                     |                     ¦   «         j        ¦  «         Œ0# t
          $ r Y Œ<w xY w|rt          |¦  «        ndS )zËHighest mtime across the bundle files plus the dir itself.

    Watching the directory mtime catches deletions; watching individual
    files catches edits. Together they're a cheap freshness check.
    g        )r   r*   ÚappendÚstatÚst_mtimeÚOSErrorÚmax)r/   r.   ÚmtimesÚfs       r   Ú
_max_mtimer;   _   sÐ   € õ ‰>Œ>€DØ€FØ‡{‚{�}„}ð ð	Ø�MŠM˜$Ÿ)š)™+œ+Ô.Ñ/Ô/Ð/Ð/øÝð 	ð 	ð 	ØˆDð	øøøàð ð ˆð	Ø�MŠM˜!Ÿ&š&™(œ(Ô+Ñ,Ô,Ð,Ð,øÝð 	ð 	ð 	ØˆHð	øøøà Ð)�3ˆv‰;Œ;ˆ; cÐ)s#   ¦,A Á
A ÁA Á(,BÂ
B"Â!B"ÚpathúOptional[Dict[str, Any]]c                óÂ  — 	 |                       d¬¦  «        }n4# t          $ r'}t                               d| |¦  «         Y d}~dS d}~ww xY w	 t	          j        |¦  «        }n9# t          j        $ r'}t                               d| |¦  «         Y d}~dS d}~ww xY wt          |t          ¦  «        st                               d| ¦  «         dS t          | 
                    d¦  «        p| j        ¦  «                             ¦   «         }|st                               d| ¦  «         dS | 
                    d	¦  «        pg }t          |t          ¦  «        r|st                               d
| ¦  «         dS d„ |D ¦   «         }|st                               d| ¦  «         dS t          | 
                    d¦  «        pd¦  «                             ¦   «         }t          | 
                    d¦  «        pd¦  «                             ¦   «         }t          |¦  «        }|st                               d| ¦  «         dS |||pdt          |¦  «        › d�||t          | ¦  «        dœS )uÁ   Parse a single bundle YAML file. Returns ``None`` on any error.

    Errors are logged at WARNING level. We don't raise â€” a broken bundle
    shouldn't take down slash command discovery.
    úutf-8©ÚencodingzCould not read bundle %s: %sNzInvalid YAML in bundle %s: %sz$Bundle %s is not a mapping; skippingr   zBundle %s has no name; skippingÚskillsz&Bundle %s has no skills list; skippingc                ó’   — g | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ‘ŒES © ©r   r%   ©Ú.0Úss     r   ú
<listcomp>z%_load_bundle_file.<locals>.<listcomp>‘   s9   € Ð?Ð?Ð? µ°A±´·²±´Ð?�c�!‰fŒf�lŠl‰nŒnÐ?Ð?Ð?r   z)Bundle %s has empty skills list; skippingÚdescriptionr   Úinstructionz&Bundle %s yielded empty slug; skippingzLoad z skills as a bundle)r   ÚslugrJ   rB   rK   r<   )Ú	read_textr7   ÚloggerÚwarningÚyamlÚ	safe_loadÚ	YAMLErrorÚ
isinstanceÚdictr   r   Ústemr%   Úlistr'   Úlen)	r<   ÚrawÚexcÚdatar   rB   rJ   rK   rL   s	            r   Ú_load_bundle_filer[   t   su  € ðØ�nŠn gˆnÑ.Ô.ˆˆøÝð ð ð Ý�ŠÐ5°t¸SÑAÔAÐAØˆtˆtˆtˆtˆtøøøøðøøøðÝŒ~˜cÑ"Ô"ˆˆøÝŒ>ð ð ð Ý�ŠÐ6¸¸cÑBÔBÐBØˆtˆtˆtˆtˆtøøøøðøøøõ �d�DÑ!Ô!ð Ý�ŠÐ=¸tÑDÔDÐDØˆtåˆt�xŠx˜ÑÔÐ, 4¤9Ñ-Ô-×3Ò3Ñ5Ô5€DØð Ý�ŠÐ8¸$Ñ?Ô?Ð?Øˆtà�XŠX�hÑÔÐ% 2€FÝ�f�dÑ#Ô#ð ¨6ð Ý�ŠÐ?ÀÑFÔFÐFØˆtØ?Ð? fÐ?Ñ?Ô?€FØð Ý�ŠÐBÀDÑIÔIÐIØˆtå�d—h’h˜}Ñ-Ô-Ð3°Ñ4Ô4×:Ò:Ñ<Ô<€KÝ�d—h’h˜}Ñ-Ô-Ð3°Ñ4Ô4×:Ò:Ñ<Ô<€Kå�D‰>Œ>€DØð Ý�ŠÐ?ÀÑFÔFÐFØˆtð ØØ"ÐNÐ&N­c°&©k¬kÐ&NÐ&NÐ&NØØ"Ý�D‘	”	ðð ð s,   ‚ ™
A
£AÁA
ÁA# Á#BÁ2BÂBc                 óò   — t          ¦   «         } i }| D ]R}t          |¦  «        }|sŒd|d         › �}||v r*t                               d||||         d         ¦  «         ŒM|||<   ŒS|at          | ¦  «        a|S )u   Scan the bundles directory and rebuild the cache.

    Returns the same mapping as :func:`get_skill_bundles` â€” ``"/slug"`` â†’
    bundle info dict. Later bundles with a duplicate slug are skipped with
    a warning (first wins, alphabetical order).
    ú/rL   z,Duplicate bundle slug %s from %s; keeping %sr<   )r1   r[   rN   rO   r   r;   r   )r/   Úoutr:   ÚinfoÚkeys        r   Úscan_bundlesra   ¨   s¦   € õ Ñ Ô €EØ%'€CØð ð ˆÝ  Ñ#Ô#ˆØð 	ØØ �$�v”,Ð Ð ˆØ�#ˆ:ˆ:Ý�NŠNØ>Ø�Q˜˜Cœ Ô(ñô ð ð ØˆˆC‰ˆØ€NÝ% eÑ,Ô,ÐØ€Jr   c                 óŠ   — t          ¦   «         } t          | ¦  «        }t          rt          |k    rt	          ¦   «          t          S )zÎReturn the current bundle mapping, rescanning when disk changed.

    Cheap to call repeatedly: only rescans when the bundles directory or
    any bundle file's mtime is newer than the cached snapshot.
    )r1   r;   r   r   ra   )r/   Úcurrent_mtimes     r   Úget_skill_bundlesrd   Ã   s>   € õ Ñ Ô €EÝ˜uÑ%Ô%€MÝð Õ1°]ÒBÐBÝ‰ŒˆÝÐr   ÚcommandúOptional[str]c                ód   — | sdS d|                       dd¦  «        › �}|t          ¦   «         v r|ndS )zëResolve a user-typed command to its canonical bundle slash key.

    Hyphens and underscores are treated interchangeably to mirror the
    skill-command behavior (Telegram converts hyphens to underscores in
    bot command names).
    Nr]   r   r   )r!   rd   )re   Úcmd_keys     r   Úresolve_bundle_command_keyri   Ð   sG   € ð ð ØˆtØ-�'—/’/ # sÑ+Ô+Ð-Ð-€GØÕ!2Ñ!4Ô!4Ð4Ð4ˆ7ˆ7¸$Ð>r   úDict[str, Any]c                 óÀ  ‡‡— d	d„}  | t           ¦  «        Št          ¦   «         } | |¦  «        Št          t          ‰¦  «        t          ‰¦  «        z
  ¦  «        }t          t          ‰¦  «        t          ‰¦  «        z
  ¦  «        }t          t          ‰¦  «        t          ‰¦  «        z  ¦  «        }ˆfd„|D ¦   «         ˆfd„|D ¦   «         |t	          ‰¦  «        dœS )
zïRe-scan the bundles directory and return a diff.

    Mirrors :func:`agent.skill_commands.reload_skills` so callers can use
    the same display logic. Returns a dict with ``added``, ``removed``,
    ``unchanged``, and ``total`` keys.
    Úcmdsr   r   úDict[str, str]c                ó>   — d„ |                       ¦   «         D ¦   «         S )Nc                ól   — i | ]1\  }}|                      d ¦  «        |pi                      dd¦  «        “Œ2S )r]   rJ   r   )Úlstripr   )rG   ÚkÚvs      r   ú
<dictcomp>z5reload_bundles.<locals>._snapshot.<locals>.<dictcomp>å   s:   € ÐYÐYÐYÁDÀAÀq�—’˜‘”   RŸ}š}¨]¸BÑ?Ô?ÐYÐYÐYr   )Úitems)rl   s    r   Ú	_snapshotz!reload_bundles.<locals>._snapshotä   s   € ØYÐYÈDÏJÊJÉLÌLÐYÑYÔYÐYr   c                ó&   •— g | ]}|‰|         d œ‘ŒS ©)r   rJ   rD   )rG   ÚnÚafters     €r   rI   z"reload_bundles.<locals>.<listcomp>ð   s%   ø€ ÐLÐLÐL¸1˜1¨U°1¬XÐ6Ð6ÐLÐLÐLr   c                ó&   •— g | ]}|‰|         d œ‘ŒS rw   rD   )rG   rx   Úbefores     €r   rI   z"reload_bundles.<locals>.<listcomp>ñ   s%   ø€ ÐQÐQÐQ¸a˜Q¨v°a¬yÐ9Ð9ÐQÐQÐQr   )ÚaddedÚremovedÚ	unchangedÚtotal)rl   r   r   rm   )r   ra   r,   ÚsetrW   )ru   ÚnewÚadded_namesÚremoved_namesr~   ry   r{   s        @@r   Úreload_bundlesr„   Ý   sé   øø€ ðZð Zð Zð Zð ˆY•~Ñ&Ô&€FÝ
‰.Œ.€CØˆI�c‰NŒN€Eå�˜U™œ¥c¨&¡k¤kÑ1Ñ2Ô2€KÝ�3˜v™;œ;­¨U©¬Ñ3Ñ4Ô4€MÝ•s˜5‘z”z¥C¨¡K¤KÑ/Ñ0Ô0€Ið MÐLÐLÐLÀÐLÑLÔLØQÐQÐQÐQÀ=ÐQÑQÔQØÝ�U‘”ð	ð ð r   úList[Dict[str, Any]]c                 óf   — t          ¦   «         } t          |                      ¦   «         d„ ¬¦  «        S )z6Return a sorted list of bundle info dicts for display.c                ó   — | d         S )NrL   rD   )Úbs    r   ú<lambda>zlist_bundles.<locals>.<lambda>ú   s
   € °!°F´)€ r   )r`   )rd   r,   Úvalues)Úbundless    r   Úlist_bundlesrŒ   ÷   s.   € åÑ!Ô!€GÝ�'—.’.Ñ"Ô"Ð(;Ð(;Ð<Ñ<Ô<Ð<r   r   rh   Úuser_instructionÚtask_idú
str | NoneÚplatformú*Optional[Tuple[str, List[str], List[str]]]c           	     óø  — t          ¦   «         }|                     | ¦  «        }|sdS ddlm}m} 	 ddlm}  ||¬¦  «        }	n# t          $ r t          ¦   «         }	Y nw xY wg }
g }g }g }t          ¦   «         }|d         }|d         }|                     d¦  «        pd	}|D ]á}|pd	 	                    ¦   «         }|r||v rŒ| 
                    |¦  «          |||¬
¦  «        }|s|                     |¦  «         ŒY|\  }}}||	v s||	v r|                     |p|¦  «         Œ	 ddlm}  |||¬
¦  «         n# t          $ r Y nw xY wd|› d�}|                      |||||¬¦  «        ¦  «         |
                     |¦  «         Œâ|sdS d|› dt          |
¦  «        › d�d	d|› �dd                     |
¦  «        › �g}|r+|                     dd                     |¦  «        › �¦  «         |r+|                     dd                     |¦  «        › �¦  «         |r|                     d	d|› �g¦  «         |r|                     d	d|› �g¦  «         d                     |¦  «        }d                     |g|¢¦  «        |
|fS )u  Build the user message content for a bundle slash command invocation.

    Returns ``(message, loaded_skill_names, missing_skill_names)`` or
    ``None`` if the bundle wasn't found.

    A bundle that references skills the user doesn't have installed still
    loads â€” the agent gets a note about which ones were skipped. This is
    the same forgiving stance ``build_preloaded_skills_prompt`` uses for
    ``-s`` CLI preloading.

    Disabled skills are also skipped: bundles load members via
    ``_load_skill_payload`` directly, bypassing the scan-time disabled
    filter in ``get_skill_commands()``, so the disabled list must be
    re-applied here.  ``platform`` scopes the check to a specific
    platform's ``skills.platform_disabled`` config (gateway dispatch
    passes it explicitly because the gateway handles multiple platforms
    in one process); when *None*, the platform resolves from session env
    vars and the global disabled list still applies.  Mirrors the
    stacked-skill gate in gateway dispatch (#58888).
    Nr   )Ú_load_skill_payloadÚ_build_skill_message)Úget_disabled_skill_names)r�   r   rB   rK   r   )rŽ   )Úbump_usez[Loaded as part of the "z" skill bundle.])Ú
session_idz&[IMPORTANT: The user has invoked the "z" skill bundle, loading zL skills together. Treat every skill below as active guidance for this turn.]zBundle: zSkills loaded: z, zSkills missing (skipped): z-Skills disabled for this platform (skipped): zBundle instruction: zUser instruction: Ú
z

)rd   r   Úagent.skill_commandsr“   r”   Úagent.skill_utilsr•   Ú	Exceptionr€   r%   Úaddr4   Útools.skill_usager–   rW   Újoinr+   )rh   r�   rŽ   r�   r‹   r_   r“   r”   r•   Údisabled_namesÚloaded_namesÚmissingÚdisabledÚskill_blocksÚseenÚbundle_namerB   Úextra_instructionÚskill_idÚ
identifierÚloadedÚloaded_skillÚ	skill_dirÚ
skill_namer–   Úactivation_noteÚheader_linesÚheaders                               r   Úbuild_bundle_invocation_messager°   ý   s¼  € õ4  Ñ!Ô!€GØ�;Š;�wÑÔ€DØð Øˆtð OÐNÐNÐNÐNÐNÐNÐNðØ>Ð>Ð>Ð>Ð>Ð>Ø1Ð1¸8ÐDÑDÔDˆˆøÝð ð ð Ý™œˆˆˆðøøøð !€LØ€GØ€HØ €LÝ‘U”U€Dà�v”,€KØ�(Œ^€FØŸš Ñ/Ô/Ð5°2Ðàð #(ð #(ˆØ�n "×+Ò+Ñ-Ô-ˆ
Øð 	˜Z¨4Ð/Ð/ØØ�Š�ÑÔÐà$Ð$ Z¸ÐAÑAÔAˆØð 	Ø�NŠN˜:Ñ&Ô&Ð&ØØ.4Ñ+ˆ�i ð ˜Ð'Ð'¨:¸Ð+GÐ+GØ�OŠO˜JÐ4¨*Ñ5Ô5Ð5Øð	Ø2Ð2Ð2Ð2Ð2Ð2ØˆH�Z¨Ð1Ñ1Ô1Ð1Ð1øÝð 	ð 	ð 	ØˆDð	øøøð E {ÐDÐDÐDð 	ð 	×ÒØ Ð ØØØØ"ð	ñ ô ñ	
ô 	
ð 	
ð 	×Ò˜JÑ'Ô'Ð'Ð'àð Øˆtð
	-°ð 	-ð 	-Ý�|Ñ$Ô$ð	-ð 	-ð 	-ð 	Ø �;Ð Ð Ø3˜$Ÿ)š) LÑ1Ô1Ð3Ð3ð€Lð ð OØ×ÒÐM¸¿ºÀ7Ñ9KÔ9KÐMÐMÑNÔNÐNØð 
Ø×ÒØQ¸D¿IºIÀhÑ<OÔ<OÐQÐQñ	
ô 	
ð 	
ð ð NØ×Ò˜RÐ!KÐ8IÐ!KÐ!KÐLÑMÔMÐMØð 
Ø×ÒØÐ8Ð&6Ð8Ð8Ð9ñ	
ô 	
ð 	
ð �YŠY�|Ñ$Ô$€FØ�KŠK˜Ð/ ,Ð/Ñ0Ô0°,ÀÐHÐHs#   ±A ÁAÁAÄ!D5Ä5
EÅEc                ór   — t          | ¦  «        }|st          d| ›d�¦  «        ‚t          ¦   «         |› d�z  S )z7Return the canonical filesystem path for a bundle name.zBundle name z normalizes to an empty slugz.yaml)r'   Ú
ValueErrorr   ©r   rL   s     r   Úbundle_path_forr´   x  sE   € å�D‰>Œ>€DØð NÝÐL¨ÐLÐLÐLÑMÔMÐMÝ‰>Œ>˜t˜N˜N˜NÑ*Ð*r   FrB   ú	List[str]rJ   rK   Ú	overwriteÚboolc                óÎ  — | pd                      ¦   «         } | st          d¦  «        ‚d„ |D ¦   «         }|st          d¦  «        ‚t          | ¦  «        }|                     ¦   «         r|st	          d|› �¦  «        ‚|j                             dd¬¦  «         | |dœ}|r||d	<   |r||d
<   |                     t          j	        |dd¬¦  «        d¬¦  «         t          ¦   «          |S )z¼Write a bundle to disk and invalidate the cache.

    Raises ``FileExistsError`` if the target exists and ``overwrite`` is
    False. Raises ``ValueError`` if the inputs are unusable.
    r   zBundle name is requiredc                ó’   — g | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ‘ŒES rD   rE   rF   s     r   rI   zsave_bundle.<locals>.<listcomp>�  s9   € ÐGÐGÐG¨½¸A¹¼¿º¹¼ÐG•c˜!‘f”f—l’l‘n”nÐGÐGÐGr   z(Bundle must reference at least one skillzBundle already exists at T)ÚparentsÚexist_ok)r   rB   rJ   rK   F)Ú	sort_keysÚallow_unicoder?   r@   )r%   r²   r´   r*   ÚFileExistsErrorÚparentÚmkdirÚ
write_textrP   Ú	safe_dumpra   )r   rB   rJ   rK   r¶   Úcleaned_skillsr<   Úpayloads           r   Úsave_bundlerÅ   €  s&  € ð ˆJ�B×ÒÑÔ€DØð 4ÝÐ2Ñ3Ô3Ð3ØGÐG¨fÐGÑGÔG€NØð EÝÐCÑDÔDÐDå˜4Ñ Ô €DØ‡{‚{�}„}ð B˜Yð BÝÐ@¸$Ð@Ð@ÑAÔAÐAà„K×Ò˜d¨TÐÑ2Ô2Ð2Ø'+°~ÐFÐF€GØð -Ø!,ˆ�ÑØð -Ø!,ˆ�Ñà‡O‚OÝŒ�w¨%¸tÐDÑDÔDØð ñ ô ð õ �N„N€NØ€Kr   c                ó´   — t          | ¦  «        }|                     ¦   «         st          d|› �¦  «        ‚|                     ¦   «          t	          ¦   «          |S )zvDelete a bundle by name. Returns the deleted path.

    Raises ``FileNotFoundError`` if the bundle doesn't exist.
    zNo bundle at )r´   r*   ÚFileNotFoundErrorÚunlinkra   )r   r<   s     r   Údelete_bundlerÉ   ¦  sS   € õ
 ˜4Ñ Ô €DØ�;Š;‰=Œ=ð 8ÝÐ 6°Ð 6Ð 6Ñ7Ô7Ð7Ø‡K‚K�M„M€MÝ�N„N€NØ€Kr   c                óh   — t          | ¦  «        }t          ¦   «                              d|› �¦  «        S )z+Look up a bundle by name (slug-normalized).r]   )r'   rd   r   r³   s     r   Ú
get_bundlerË   ³  s-   € å�D‰>Œ>€DÝÑÔ×"Ò" : t : :Ñ.Ô.Ð.r   )r   r   )r   r   r   r   )r   r(   )r/   r(   r   r2   )r<   r   r   r=   )r   r   )re   r   r   rf   )r   rj   )r   r…   )r   NN)
rh   r   r�   r   rŽ   r�   r�   r�   r   r‘   )r   r   r   r   )r   r   F)r   r   rB   rµ   rJ   r   rK   r   r¶   r·   r   r   )r   r   r   r=   ))Ú__doc__Ú
__future__r   Úloggingr   ÚreÚpathlibr   Útypingr   r   r   r   r	   rP   Úhermes_constantsr
   Ú	getLoggerÚ__name__rN   Úcompiler"   r$   r   Ú__annotations__r   r   r'   r1   r;   r[   ra   rd   ri   r„   rŒ   r°   r´   rÅ   rÉ   rË   rD   r   r   ú<module>r×      sY  ðð(ð (ð (ðT #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø 	€	€	€	Ø Ð Ð Ð Ð Ð Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3à €€€à ,Ð ,Ð ,Ð ,Ð ,Ð ,à	ˆÔ	˜8Ñ	$Ô	$€ð #˜œ
 =Ñ1Ô1Ð Ø!�r”z (Ñ+Ô+Ð à,.€Ð .Ð .Ð .Ñ .Ø(,Ð Ð ,Ð ,Ð ,Ñ ,ð	/ð 	/ð 	/ð 	/ðð ð ð ðð ð ð ð*ð *ð *ð *ð*1ð 1ð 1ð 1ðhð ð ð ð6
ð 
ð 
ð 
ð
?ð 
?ð 
?ð 
?ðð ð ð ð4=ð =ð =ð =ð ØØð	sIð sIð sIð sIð sIðv+ð +ð +ð +ð ØØð#ð #ð #ð #ð #ðL
ð 
ð 
ð 
ð/ð /ð /ð /ð /ð /r   