+
    jHàjr  ã                  ó’  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
HtHtHt ]P                  ! R4      t]],          tR^€R]RR/R	 R
 lltR^ RR/R R lltR]! 4       RRRRRR/R R lltRR/R R lltRR/R R lltR R ltR  R! ltR" R# ltR$^
/R% R& lltR'^/R( R) lltR* R+ ltR, R- ltR. R/ ltR0 R1 lt R# )2aš  Shared leaf helpers for the gateway hosted-room modules.

Each hosted-room module validates identifiers, bounded integers, exact field sets and
canonical JSON with its own error class and pinned error strings; these helpers take the
error class and message templates as parameters so failures stay byte-identical while the
logic lives once. Must stay a leaf: never import a hosted_room* module (import cycle).
)ÚannotationsN)ÚPath)ÚAnyÚCallableÚIteratorÚMappingz^[A-Za-z0-9][A-Za-z0-9._:-]*$Ú	max_charsÚpatternÚinvalidc               ó4   € V ^8„  d   QhRRRRRRRRR	R
RRRR/# )é   Úvaluer   ÚlabelÚstrÚerrorútype[Exception]r   Úintr	   zre.Pattern[str] | Noner
   ú
str | NoneÚreturn© )Úformats   "Ú@/home/ubuntu/.hermes/hermes-agent/gateway/hosted_rooms_common.pyÚ__annotate__r      sD   € ÷ 	ñ 	Øð	Øð	Ø&5ð	ØBEð	à#ð	à>Hð	àTWñ	ó    c               óø   € \        V \        4      '       g   V! V R24      hV P                  4       p V '       d,   \        V 4      V8”  g   Ve-   VP	                  V 4      '       g   T! T;'       g    RV 24      hV # )zLStrip and validate a bounded string; ``pattern=None`` skips the shape check.ú must be a stringzinvalid )Ú
isinstancer   ÚstripÚlenÚ	fullmatch)r   r   r   r   r	   r
   s   &$$$$$r   Ú
identifierr       sr   € ô �eœS×!Ò!Ù�u�gÐ.Ð/Ó0Ð0Ø�K‰K‹M€Eß”C˜“J Ô*¨wÒ/BÈ7×K\ÑK\Ð]b×KcÒKcÙ�G×1Ð1 ¨%¨Ð1Ó2Ð2Ø€Lr   ÚlowÚhighc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r   r   r   r   r   Úmessager   r!   r   r"   z
int | Noner   r   )r   s   "r   r   r   #   s8   € ÷ ñ �sð  oð Àð È#ð ÐYcð Ðorñ r   c               óŽ   € \        V \        4      '       g'   \        V \        4      '       d   W8  g   Ve   W8”  d	   V! V4      hV # )zZReject bools, non-ints and values outside ``[low, high]`` (``message`` is the exact text).)r   Úboolr   )r   r   r$   r!   r"   s   &$$$$r   Úbounded_intr'   #   s:   € ä�%œ×Ò¤j°¼×&<Ò&<ÀÄÐPTÒP`ÐejÔeqÙ�G‹nÐØ€Lr   ÚoptionalÚ
not_objectÚmissing_fmtz#{label} is missing fields: {fields}Úunknown_fmtz${label} has unknown fields: {fields}c               ó<   € V ^8„  d   QhRRRRRRRRRR	R
RRRRRRR/	# )r   r   r   r   r   Úrequiredzfrozenset[str] | set[str]r(   r   r   r)   r   r*   r+   r   zMapping[str, Any]r   )r   s   "r   r   r   *   sZ   € ÷ ñ ØðØðØ)BðØNgðàðà(2ðàHKðð ðð CTñr   c          
     ó„  € \        V \        4      '       g   T! T;'       g    V R24      h\        V 4      pW(,
          p	W‚,
          V,
          p
V	'       d2   V! VP                  VRP	                  \        V	4      4      R7      4      hV
'       d2   V! VP                  VRP	                  \        V
4      4      R7      4      hV # )zZRequire exactly ``required`` (+ any ``optional``) keys; formats name the offenders sorted.z must be an objectz, )r   Úfields)r   r   Ú	frozensetr   ÚjoinÚsorted)r   r   r-   r(   r   r)   r*   r+   ÚkeysÚmissingÚunknowns   &$$$$$$$   r   Úexact_fieldsr6   *   s¤   € ô
 �eœW×%Ò%Ù�J×>Ð> U GÐ+=Ð">Ó?Ð?Ü�UÓ€DØ�o€GØ�o Õ(€GßÙ�K×&Ñ&¨U¸4¿9¹9ÄVÈGÃ_Ó;UÐ&ÓVÓWÐWßÙ�K×&Ñ&¨U¸4¿9¹9ÄVÈGÃ_Ó;UÐ&ÓVÓWÐWØ€Lr   r   Tc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r   r   r   r   r   r   r   Ú	max_bytesr   r   r&   r   r   )r   s   "r   r   r   ;   s8   € ÷ 
ñ 
�ð 
˜ð 
°sð 
Àsð 
ÐSWð 
Ðcfñ 
r   c               ó  € \        V \        4      '       g   V! V R24      hV P                  4       '       g   V! V R24      hV'       d   V P                  4       p \        V P	                  R4      4      V8”  d   V! V R24      hV # )zdNon-blank string bounded by ``max_bytes`` of UTF-8; ``strip=False`` keeps and measures the raw text.r   z must not be emptyúutf-8ú is too large)r   r   r   r   Úencode)r   r   r   r8   r   s   &$$$$r   Útextr=   ;   s{   € ä�eœS×!Ò!Ù�u�gÐ.Ð/Ó0Ð0Ø�;‰;�=Š=Ù�u�gÐ/Ð0Ó1Ð1ßØ—‘“ˆÜ
ˆ5�<‰<˜Ó Ó! IÔ-Ù�u�g˜]Ð+Ó,Ð,Ø€Lr   Úensure_asciic               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   r>   r&   r   r   r   )r   s   "r   r   r   H   s&   € ÷ _ñ _˜ð _¨dð _¸cñ _r   c               ó4   € \         P                  ! WRRR7      # )zDSorted-key, separator-free JSON (the digest/storage canonical form).T)r>   Ú	sort_keysÚ
separators)Ú,Ú:)ÚjsonÚdumps)r   r>   s   &$r   Úcompact_jsonrG   H   s   € ä�:Š:�eÀ$ÐS]Ô^Ð^r   c               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r   r   r   r   r   r   r   r8   r   r>   r&   r   r   )r   s   "r   r   r   M   s9   € ÷ ñ ˜#ð ¨ð Àð ÐQTð Ðdhð Ðmpñ r   c               óÈ   €  \        WR7      p\	        TP                  R4      4      T8”  d   T! T R24      hT#   \        \        \        3 d   pT! T R24      ThRp?ii ; i)zZ``compact_json`` bounded by ``max_bytes`` of UTF-8; unserializable input raises ``error``.)r>   z must be JSON-serializableNr:   r;   )rG   Ú	TypeErrorÚ
ValueErrorÚRecursionErrorr   r<   )r   r   r   r8   r>   ÚencodedÚexcs   &$$$$  r   Úcanonical_jsonrO   M   sq   € ðCÜ˜uÔ@ˆô ˆ7�>‰>˜'Ó"Ó# iÔ/Ù�u�g˜]Ð+Ó,Ð,Ø€Nøô	 ”z¤>Ð2ô CÙ�u�gÐ7Ð8Ó9¸sÐBûðCús   ‚: ºA!ÁAÁA!c               ó    € V ^8„  d   QhRRRR/# )r   Úpartsr   r   r   r   )r   s   "r   r   r   X   s   € ÷ /ñ /�Sð /˜Sñ /r   c                 óT   € \        R P                  V 4      P                  R4      4      # )Ú r:   )r   r1   r<   )rQ   s   *r   Úutf8_lenrT   X   s    € Üˆr�w‰w�u‹~×$Ñ$ WÓ-Ó.Ð.r   c               ó    € V ^8„  d   QhRRRR/# )r   Únowzfloat | Noner   Úfloatr   )r   s   "r   r   r   \   s   € ÷ 6ñ 6ˆ|ð 6 ñ 6r   c                óJ   € V f   \         P                   ! 4       # \        V 4      # )z<``now`` as a float, or the current wall clock when ``None``.)ÚtimerW   )rV   s   &r   ÚclockrZ   \   s   € àš+Œ4�9Š9‹;Ð5¬5°«:Ð5r   Útimeoutc               ó$   € V ^8„  d   QhRRRRRR/# )r   ÚpathÚDbPathr[   rW   r   úsqlite3.Connectionr   )r   s   "r   r   r   a   s"   € ÷ &ñ &�fð &¨%ð &Ð9Kñ &r   c               óH   € ^ RI Hp V! V R\        VR,          4      RRR7      # )z^Row-factory connection with foreign keys on; no journal or schema work (steady-state readers).©Úopen_dbzshared-state.dbiè  FT)Údb_labelÚbusy_timeout_msÚwalÚforeign_keys)Úhermes_cli.sqlite_utilrb   r   )r]   r[   rb   s   &$ r   Úopen_sqliterh   a   s)   € å.á�4Ð"3ÄSÈÐSWÍÓEXÐ^cØ $ô&ð &r   Úlock_retriesc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r   Údb_pathr^   rc   r   Úreadyz$Callable[[sqlite3.Connection], bool]Ú
initializez$Callable[[sqlite3.Connection], None]ri   r   r   r_   r   )r   s   "r   r   r   i   sD   € ÷ Jñ JØðJØ"%ðJØ.RðJà4ðJàDGðJàPbñJr   c          	     ó>   aa€ R VV3R llp^ RI Hp V! WRRWER7      # )a4  Open the shared root store: WAL, foreign keys, then ``initialize`` in one IMMEDIATE txn if not ``ready``.

Multiple profile gateways share this database, so every draft-schema transition
is serialized in SQLite itself: a crash rolls back the whole DDL/data migration and
another process can safely retry it.
c               ó    € V ^8„  d   QhRRRR/# )r   Úconnr_   r   ÚNoner   )r   s   "r   r   Úconnect.<locals>.__annotate__r   s   € ÷ ñ Ð,ð °ñ r   c                ó¼   <€ S! V 4      '       g-    V P                  R 4       S! V 4       V P                  4        R# R#   \         d    T P                  4        h i ; i)zBEGIN IMMEDIATEN)ÚexecuteÚcommitÚ	ExceptionÚrollback)rp   rm   rl   s   &€€r   Ú_initializeÚconnect.<locals>._initializer   sQ   ø€ Ù�T�{Š{ðØ—‘Ð.Ô/Ù˜4Ô Ø—‘–ñ	 øô
 ô Ø—‘”Øðús	   ‘)> ¾Ara   i'  T)rc   rd   rf   Úwal_lock_retriesrm   )rg   rb   )rk   rc   rl   rm   ri   rx   rb   s   &$dd$  r   Úconnectr{   i   s+   ù€ ÷ñ õ /á�7¸vÐTXØ$0ôJð Jr   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   rp   r_   Úsqlr   ÚparamsÚtupler   rv   r   rq   r   )r   s   "r   r   r   ‚   s1   € ÷ ñ Ð*ð °ð ¸eð ÈIð ÐZ^ñ r   c                óJ   € V P                  W4      P                  ^8w  d   VhR# )zURun a compare-and-swap UPDATE; anything but exactly one row means the fence was lost.N)rt   Úrowcount)rp   r}   r~   r   s   &&&&r   Úfenced_updater‚   ‚   s#   € à‡|�|�CÓ ×)Ñ)¨QÔ.Øˆñ /r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rp   r_   Útabler   r   r&   r   )r   s   "r   r   r   ˆ   s"   € ÷ ñ Ð)ð °#ð ¸$ñ r   c                óL   € V P                  R V34      P                  4       pVRJ# )z9SELECT 1 FROM sqlite_master WHERE type='table' AND name=?N)rt   Úfetchone)rp   r„   Úrows   && r   Útable_existsrˆ   ˆ   s*   € Ø
�,‰,ÐRÐUZÐT\Ó
]×
fÑ
fÓ
h€CØ�dˆ?Ðr   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rp   r_   r„   r   r   zfrozenset[str]r   )r   s   "r   r   r   �   s'   € ÷ Tñ TÐ*ð T°3ð T¸>ñ Tr   c                óL   € \        R  V P                  RV R24       4       4      # )c              3  ó2   "  € T F  q^,          x € K  	  R# 5i)é   Nr   )Ú.0r‡   s   & r   Ú	<genexpr>Ú table_columns.<locals>.<genexpr>Ž   s   é € ÐSÑ'R ˜—V’VÓ'Rùs   ‚zPRAGMA table_info(Ú))r0   rt   )rp   r„   s   &&r   Útable_columnsr‘   �   s&   € ÜÑS t§|¡|Ð6HÈÈÈqÐ4QÔ'RÓSÓSÐSr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r{   z&Callable[[DbPath], sqlite3.Connection]rk   r^   Ú	immediater&   r   zIterator[sqlite3.Connection]r   )r   s   "r   r   r   ‘   s,   € ÷ ?ñ ?Ø3ð?Ø>Dð?ØTXð?à!ñ?r   c               ó.   € ^ RI Hp V! V ! V4      VR7      # )zVOpen via ``connect``, optionally ``BEGIN IMMEDIATE``, commit on success, always close.)Útransaction)r“   )rg   r•   )r{   rk   r“   Ú_transactions   &&$ r   r•   r•   ‘   s   € õ Cá™ Ó(°IÔ>Ð>r   )!Ú__doc__Ú
__future__r   rE   ÚreÚsqlite3rY   Úpathlibr   Útypingr   r   r   r   ÚcompileÚIDENTIFIER_REr   r^   r    r'   r0   r6   r=   rG   rO   rT   rZ   rh   r{   r‚   rˆ   r‘   r•   r   r   r   Ú<module>rŸ      sô   ðñõ #ã Û 	Û Û Ý ß 3Ó 3ð —
’
Ð;Ó<€Ø	��€ð	ØHKð	à&3ð	àKO÷	ðÐPQð Ðfj÷ ðÙjsÓjuðà59ðàNsðð >÷ð"
ÐZ^÷ 
ð_°T÷ _õ
õ/õ6ð
&°"÷ &ðJàJK÷Jõ2õõ
T÷?r   