+
    iHàjîC  ã            	      óò  € R t ^ RIHt ^ RIt^ RIt^ RIHtHtHtH	t	H
t
 ^ RIHt ^ RIHtHtHtHtHt ^ RIHtHt ^ RIHtHt ^ RIHt ]! R	R
RRR]R04      t];QJ d    . R ] 4       F  NK  	  5M! R ] 4       4      t]! 0 R%m4      t];QJ d    . R ] 4       F  NK  	  5M! R ] 4       4      t R&t!R'],           t"Rt#Rt$R R lt%R R lt&R R lt'R R lt(R R lt)R R lt*R R  lt+R! R" lt,R# R$ lt-R# )(zúTranscript repair for SessionDB batch appends: reconcile in-memory rows with committed SQLite rows
(in-place sanitizer rewrites, assistant blank-row repair, concurrent-winner adoption, watermark-compaction
clone lookup) and sync markers after commit.)ÚannotationsN)ÚAnyÚCallableÚDictÚListÚMapping)Ú_DB_PERSISTED_MARKER)ÚCANONICAL_ROWÚDB_ROW_SNAPSHOTÚMESSAGE_UIDÚcopy_identity_fieldsÚmessage_uid_or_none)Ú
_id_chunksÚ_placeholders)Ú_fill_missing_tool_call_uidsÚ_restore_row_identity)Ú_MESSAGE_WRITE_COLUMNSÚ
session_idÚroleÚ	timestampÚactiveÚdisplay_identityÚtool_call_uidc              #  ó>   "  € T F  q\         9  g   K  Vx € K  	  R # 5i©N)Ú_NON_PAYLOAD_COLUMNS©Ú.0Úcs   & Ú</home/ubuntu/.hermes/hermes-agent/agent/transcript_repair.pyÚ	<genexpr>r       s   é € Ð[Ñ#9˜aÔFZÑ=ZŸšÓ#9ùó   ‚“
c              #  ó>   "  € T F  q\         9  g   K  Vx € K  	  R # 5ir   )Ú_METADATA_COLUMNSr   s   & r   r    r    "   s   é € ÐP¡/˜QÔ>OÑ5O—q’q£/ùr!   Ú_metadata_onlyÚ_content_onlyc               ó    € V ^8„  d   QhRRRR/# )é   ÚrowúMapping[str, Any]ÚreturnÚstr© )Úformats   "r   Ú__annotate__r.   -   s   € ÷ ñ Ð!2ð °sñ ó    c                ó.  € \         P                  ! ^R7      p\         Få  pW,          pVf   VP                  R4       K"  \	        V\
        \        \        34      '       d   R\        V4      rTM]\	        V\        4      '       d   RVP                  RR4      rTM3\	        V\        4      '       d   RMR\        V4      P                  R	4      rTVP                  V\        V4      P                  ^R
4      ,           V,           4       Kç  	  VP                  4       # )aø  Fixed-size digest of the owned (non-metadata) columns (the CAS version) of a ``SELECT *`` messages row.

Callers pass rows read back from SQLite, never Python bind values: column affinity rewrites values on
storage (int ``platform_message_id`` -> TEXT, float ``token_count`` -> INTEGER), so hashing bind values
would never match the stored version. A digest rather than a row copy: the value rides on live message
dicts, so a full copy would double transcript memory and anything that prices dict bytes.
)Údigest_sizeó   Nó   Bó   Szutf-8Úsurrogatepassó   Fó   IÚasciiÚbig)ÚhashlibÚblake2bÚ_OWNED_COLUMNSÚupdateÚ
isinstanceÚbytesÚ	bytearrayÚ
memoryviewr+   ÚencodeÚfloatÚreprÚlenÚto_bytesÚ	hexdigest)r(   ÚdigestÚcolumnÚvalueÚtagÚdatas   &     r   Útranscript_row_snapshotrM   -   sÒ   € ô �_Š_¨Ô,€Fß ˆØ•ˆØŠ=Ø�M‰M˜$ÔÙÜ�eœe¤Y´
Ð;×<Ò<Øœe E›l‘Ü˜œs×#Ò#Ø˜eŸl™l¨7°OÓD‘ä!+¨E´5×!9Ò!9™¸tÄdÈ5Ãk×FXÑFXÐY`ÓFa�Ø�‰�cœC ›I×.Ñ.¨q°%Ó8Õ8¸4Õ?Ö@ñ !ð ×ÑÓÐr/   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r'   Úconnúsqlite3.Connectionr   r+   Úmessagesúlist[dict[str, Any]]r*   ÚNoner,   )r-   s   "r   r.   r.   E   s1   € ÷ Rñ RÐ'9ð RÀsð RÐVjð RÐosñ Rr/   c                óv  € V Uu/ uF4  p\        VP                  R4      \        4      '       g   K*  VR,          VbK6  	  pp\        V4       Fd  pV P	                  R\        V4       R2V.VO54      P                  4        F,  p\        V4      V\        VR,          4      ,          \        &   K.  	  Kf  	  R# u upi )ztStamp the stored-row digest on freshly inserted dicts (every ``_insert_message_rows`` caller; one SELECT
per batch).Ú_row_idz7SELECT * FROM messages WHERE session_id = ? AND id IN (Ú)ÚidN)	r>   ÚgetÚintr   Úexecuter   ÚfetchallrM   r
   )rO   r   rQ   ÚmsgÚby_idÚchunkr(   s   &&&    r   Ústamp_inserted_row_snapshotsr_   E   sª   € ñ -5Ó\©H S¼
À3Ç7Á7È9ÓCUÔWZ×8[Ô ˆS��^˜SÒ ©H€EÐ\Ü˜EÖ"ˆØ—<‘<ØEÄmÐTYÓFZÐE[Ð[\Ð]Ð`jÐ_sÐmrÑ_só
ç
‰(‹*òˆCô 6MÈSÓ5QˆE”#�c˜$•i“.Õ!¤/Ó2óó #ùò ]s
   …'B6±B6c               ó    € V ^8„  d   QhRRRR/# )r'   Úcontentr   r*   Úboolr,   )r-   s   "r   r.   r.   P   s   € ÷ ñ ˜cð  dñ r/   c                óê   € V f   R# \        V \        4      '       d   V P                  4       '       * # \        V \        4      '       d,   RP	                  R V  4       4      P                  4       '       * # R# )zYTrue when decoded message content is None, whitespace-only, or has no visible text parts.TÚ c              3  ó¦   "  € T FG  p\        V\        4      '       g   K  VP                  R 4      R8X  g   K3  VP                  RR4      x € KI  	  R# 5i)ÚtypeÚtextrd   N)r>   ÚdictrX   )r   Úps   & r   r    Ú#is_content_blank.<locals>.<genexpr>W   sB   é € Ðq±g°ÄÈAÌt×ATÔ,ÐYZ×Y^ÑY^Ð_eÓYfÐjpÑYpÔ,˜1Ÿ5™5 ¨×,Ð,³gùs   ‚AŸA·AF)r>   r+   ÚstripÚlistÚjoin)ra   s   &r   Úis_content_blankrn   P   sW   € à‚ÙÜ�'œ3×ÒØ—=‘=“?Ô"Ð"Ü�'œ4× Ò Ø—7‘7Ñq±gÓqÓq×wÑwÓyÔyÐyÙr/   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r'   rO   rP   r   r+   r   Úmessage_uidz
str | Noner*   zMapping[str, Any] | Noner,   )r-   s   "r   r.   r.   [   s4   € ÷ ñ Ø
ðØ*-ðØ58ðØGQðàñr/   c                óR   € Vf   R# V P                  RWV34      P                  4       # )aŒ  Newest active physical row for one durable logical message.

A ``message_uid`` names a logical message, not a physical row: compaction/copy paths deliberately
keep it while re-issuing row ids. The later active row is the current version. Callers use this only
when the live dict also carries a stored-row snapshot, so a fresh message that merely resembles an
older one can never be adopted here.
NztSELECT * FROM messages WHERE session_id = ? AND active = 1 AND role = ? AND message_uid = ? ORDER BY id DESC LIMIT 1)rZ   Úfetchone)rO   r   r   rp   s   &&&&r   Ú_active_logical_message_rowrs   [   s4   € ð ÒÙØ�<‰<ð	#à	˜;Ð'ó÷ �hƒjð	r/   c               ó8   € V ^8„  d   QhRRRRRRRRR	RR
RRRRR/# )r'   rO   rP   r   r+   rQ   rR   Úencode_content_fnzCallable[[Any], Any]Údecode_content_fnÚserialize_message_fnz4Callable[[dict[str, Any], float], Mapping[str, Any]]Údecode_row_fnz-Callable[[Mapping[str, Any]], dict[str, Any]]r*   r,   )r-   s   "r   r.   r.   n   sd   € ÷ Yñ YØ
ðYàðYð #ðYð ,ð	Yð
 ,ðYð OðYð AðYð ñYr/   c           	     ób  aa€ . pV EF™  p\        V\        4      '       d   VP                  R4      MRp	\        V\        4      '       d   VP                  RR4      MRp
\        V\        4      '       d   VP                  \        4      MRpRo\        V	\        4      '       d   \        WWš4      oM,\        V\        4      '       d   \        WV
\        V4      4      oSf   VP                  V4       Kì  \	        SR,          4      pWÈR&   \        SV4       RpR;rï\        V\        4      '       Ed`   \        S4      V8g  pV'       EgH   V! V\        SR,          4      4      oSR,          f   / SCRSR,          /Co\        ;QJ d$    VV3R	 l\         4       F  '       g   K   R
M	  RM! VV3R	 l\         4       4      '       d   \        WSS4       R
p\          Uu/ uF"  pVP                  V4      e   K  VSV,          bK$  	  pp\        ;QJ d*    R VP#                  4        4       F  '       g   K   R
M	  RM! R VP#                  4        4       4      '       d4   V! S4      pV Uu/ uF  pVV9   g   K  VVV,          bK  	  ppR
V\$        &   M‚V
R8X  d^   \'        V! SR,          4      4      '       d@   V P)                  RV! VP                  R4      4      WÁSR,          34      P*                  ^ 8„  pMV
R8X  d   RV! SR,          4      \,        R
/pV'       d"   V P)                  RWÁ34      P/                  4       MSpVR,          VR&   \1        VV4       \        V4      V\        &   V'       d	   V! V4      pV'       d   WØ\2        &   EKƒ  VP5                  \2        R4       EKœ  	  V# u upi u upi )a:  Resolve row-addressed rewrites without appending duplicates or replacing concurrent winners.

A durable row snapshot is a compare-and-swap version for sanitizer rewrites. When a live replay loses
its physical ``_row_id``, the pair (logical ``message_uid``, stored-row snapshot) recovers the newest
active generation without matching mutable payload. Watermark-compaction clones are matched by their
copied payload identity, not timestamp alone. Legacy blank assistant rows retain the narrow interrupted-
stream content repair. Returns only rows that need fresh inserts.
rU   Nr   ÚunknownrW   Fr   Útoken_countc              3  óJ   <"  € T F  pSV,          SV,          8g  x € K  	  R # 5ir   r,   )r   rI   Ú
serializedÚ
target_rows   & €€r   r    Ú6resolve_and_repair_transcript_batch.<locals>.<genexpr>¢   s    øé € Ð]ÉnÀF�z &Õ)¨Z¸Õ-?Ö?Ënùs   ƒ #Tc              3  ó(   "  € T F  qR Jx € K
  	  R # 5ir   r,   )r   rJ   s   & r   r    r   ¦   s   é € ÐGÑ6F¨U DÕ(Ó6Fùs   ‚Ú	assistantra   zPUPDATE messages SET content = ? WHERE id = ? AND session_id = ? AND content IS ?ú6SELECT * FROM messages WHERE id = ? AND session_id = ?)r>   rh   rX   r
   rY   Ú_active_message_rowr+   rs   r   Úappendr   rM   rC   Úanyr<   Ú_rewrite_rowÚ_LIVE_MISSING_METADATAÚvaluesÚ_METADATA_ONLYrn   rZ   ÚrowcountÚ_CONTENT_ONLYrr   r   r	   Úpop)rO   r   rQ   ru   rv   rw   rx   Úinserted_rowsr\   Úexisting_row_idr   ÚexpectedÚ	target_idÚ	canonicalÚadoptÚwroter   ÚmissingÚdecodedÚ	final_rowr}   r~   s   &&&&&&&             @@r   Ú#resolve_and_repair_transcript_batchr—   n   s)  ù€ ð" +-€MÜˆÜ0:¸3Ä×0EÒ0E˜#Ÿ'™' )Ô,È4ˆÜ-7¸¼T×-BÒ-Bˆs�w‰w�v˜yÔ)È	ˆÜ/9¸#¼t×/DÒ/D�3—7‘7œ?Ô+È$ˆØˆ
Ü�o¤s×+Ò+Ü,¨T¸ÓU‰JÜ˜¤#×&Ò&ô 5°TÀtÔM`ÐadÓMeÓfˆJØÒØ× Ñ  Ô%Ùä˜
 4Õ(Ó)ˆ	Ø"ˆI‰Ü$ Z°Ô5Øˆ	ØÐˆÜ�h¤×$Ó$ô ,¨JÓ7¸8ÑCˆEß�5Ù1°#´u¸ZÈÕ=TÓ7UÓV�
Ø˜mÕ,Ò4ð "Z JÐ!Y°¸zÈ-Õ?XÑ!Y�Jß“3Õ]ÍnÓ]—3—3’3Õ]ÍnÓ]×]Ò]Ü  °:¸zÔJØ �EÝ5KÓbÑ5K°ÈsÏwÉwÐWXËzÔ+˜1˜j¨�mÒ+Ñ5K�Ðbß“3ÑG°g·n±nÔ6FÓG—3—3’3ÑG°g·n±nÔ6FÓG×GÒGÙ+¨JÓ7�GÙ8?Ó P¹°1À1ÈÁ<¤  G¨A¥J¢¹�IÐ PØ04�IœnÑ-øØ�[Ô Ô%5Ñ6GÈ
ÐS\ÕH]Ó6^×%_Ò%_ð —L‘LØbÙ" 3§7¡7¨9Ó#5Ó6¸	ÈzÐZcÕOdÐeó÷ ‰h˜ñ‰Eð �{Ô"Ø&Ñ(9¸*ÀYÕ:OÓ(PÔR_ÐaeÐf�	÷ ð —L‘LØDÀyÐF]ó
ç
‰(Œ* :ð 	ð % [Õ1ˆˆKÑô 	˜i¨Ô-Ü6°yÓAˆŒOÑßÙ% iÓ0ˆIßØ!*”Ôà�G‰G”M 4×(ñM ðN ÐùòE cùò !Qs   ÇN'Ç6N'É(	N,É6N,c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r'   rO   rP   r   r+   r~   r)   r}   r*   rS   r,   )r-   s   "r   r.   r.   Ê   sA   € ÷ añ aØ
ðaàðað "ðað "ð	að
 
ñar/   c                óŠ  a€ VR,          pVeJ   V P                  RWR,          V34      P                  4        Uu. uF  p\        VR,          4      NK  	  upM. pRP                  R \         4       4      pV P                  RV R2. V3R	 l\         4       O\        VR,          4      NVN4       \        WVSWF4       R# u upi )
zXRewrite one durable payload whose digest matched the live dict's last committed version.r   NztSELECT id FROM messages WHERE session_id = ? AND id != ? AND (active = 1 OR compacted = 1) AND display_identity IS ?rW   z, c              3  ó*   "  € T F	  q R 2x € K  	  R# 5i)z = ?Nr,   ©r   rI   s   & r   r    Ú_rewrite_row.<locals>.<genexpr>Ü   s   é € ÐI¹.°˜h d�O».ùó   ‚zUPDATE messages SET z  WHERE id = ? AND session_id = ?c              3  ó6   <"  € T F  pSV,          x € K  	  R # 5ir   r,   )r   rI   r}   s   & €r   r    rœ   ß   s   øé € Ð
;©N &ˆ:�f×Ò«Nùó   ƒ)rZ   r[   rY   rm   r<   Ú_restore_display_index)rO   r   r~   r}   Úold_identityr(   Úold_peer_idsÚassignmentss   &&&f    r   r†   r†   Ê   sÜ   ø€ ð Ð0Õ1€Lð 
Ò	!ð —<‘<ðJà DÕ)¨<Ð8ó
÷ ‰(‹*ð	óñˆCô 	ˆC��IŽñòð (*ð ð —)‘)ÑI½.ÓIÓI€KØ‡L�LØ
˜{˜mÐ+KÐLØ_Ô
;­NÓ
;Ð_¼SÀÈDÕAQÓ=RÐ_ÐT^Ð_ôô ˜4¨Z¸À\Ö`ùòs   ºC c               ó4   € V ^8„  d   QhRRRRRRRRRR	R
RRR/# )r'   rO   rP   r   r+   r~   r)   r}   r¡   r   r¢   z	list[int]r*   rS   r,   )r-   s   "r   r.   r.   ä   sN   € ÷ -
ñ -
Ø
ð-
àð-
ð "ð-
ð "ð	-
ð
 ð-
ð ð-
ð 
ñ-
r/   c                óº  € V'       d2   \        V4      p\        V4      pV P                  RV R2WGV.VO54       \        VR,          4      pVR,          p	\	        VR,          ;'       g
    VR,          4      p
V
'       g   V P                  RW˜W�34       R# V P                  R	WV	34      P                  4       p\        V.V Uu. uF)  p\        VR
,          e
   VR
,          MVR,          4      NK+  	  up,           4      pV P                  RW�W�34       V'       d7   T P                  RV Uu. uF  qÍ\        VR,          4      V3NK  	  up4       R# R# u upi u upi )zLRestore display identities/orders invalidated by the payload-update trigger.z\UPDATE messages SET display_identity = ?, display_order = ? WHERE session_id = ? AND id IN (rV   rW   r   r   Ú	compactedz[UPDATE messages SET display_identity = ?, display_order = ? WHERE id = ? AND session_id = ?NzƒSELECT id, display_order FROM messages WHERE session_id = ? AND id != ? AND (active = 1 OR compacted = 1) AND display_identity IS ?Údisplay_orderzEUPDATE messages SET display_order = ? WHERE id = ? AND session_id = ?)r   ÚminrZ   rY   rb   r[   Úexecutemany)rO   r   r~   r}   r¡   r¢   ÚplaceholdersÚ	old_orderr�   Únew_identityÚvisibleÚpeersÚpeerÚ	new_orders   &&&&&&        r   r    r    ä   sj  € ÷ Ü$ \Ó2ˆÜ˜Ó%ˆ	Ø�‰ð/Ø/;¨n¸Að?à jÐ@°<Ñ@ô	
ô �J˜tÕ$Ó%€IØÐ0Õ1€LÜ�:˜hÕ'×BÐB¨:°kÕ+BÓC€GßØ�‰ØiØ iÐ<ô	
ñ 	à�L‰Lð	Fà	 Ð-ó÷ �hƒjð	 
ô
 Ø	ˆÙglÓ
mÑglÐ_cŒ3¨¨_Õ(=Ò(Iˆt�OÖ$ÈtÐTXÍzÖZÑglÑ
mõ	nó€Ið 	‡L�LØeØ	 )Ð8ô÷ Ø×ÑØSÙBGÓHÁ%¸$œ˜T $�Z›¨*Ó5Á%ÑHö	
ñ ùò nùò Is   Ã/E
Ä+E
c               ó(   € V ^8„  d   QhRRRRRRRR/# )r'   rO   rP   r   r+   Úrow_idrY   r   r,   )r-   s   "r   r.   r.     s*   € ÷ 2ñ 2Ð0ð 2¸cð 2È3ð 2ÐVYñ 2r/   c           	     óÚ  a€ V P                  RW!34      P                  4       oSe   SR,          V8w  d   R# \        SR,          ;'       g    ^ 4      ^8X  d   S# SR,          f   S# RP                  R \         4       4      pV P                  RV R	2VVSR,          SR
,          SR,          .V3R l\         4       O54      P                  4       p\        V4      ^8X  d
   V^ ,          # S# )z^The same-role active clone for ``row_id``, or the addressed inactive row when no clone exists.r‚   Nr   r   r   z AND c              3  ó*   "  € T F	  q R 2x € K  	  R# 5i)z IS ?Nr,   r›   s   & r   r    Ú&_active_message_row.<locals>.<genexpr>"  s   é € Ð%UÁ_¸6¨°Õ&6Ã_ùr�   z…SELECT * FROM messages WHERE session_id = ? AND active = 1 AND role = ? AND display_identity IS ? AND timestamp IS ? AND id != ? AND z ORDER BY id DESC LIMIT 2r   rW   c              3  ó6   <"  € T F  pSV,          x € K  	  R # 5ir   r,   )r   rI   r(   s   & €r   r    rµ   -  s   øé € Ð8©˜fˆc�&�kŠk«ùrŸ   )rZ   rr   rY   rm   Ú_REPAIR_COLUMNSr[   rE   )rO   r   r²   r   Úpayload_predicatesÚclonesr(   s   &&&&  @r   rƒ   rƒ     sü   ø€ à
�,‰,Ø@À6ÐBVóç�hƒjð ð ‚{�c˜&•k TÔ)ÙÜ
ˆ3ˆx�=×Ð˜AÓ !Ô#Øˆ
ð ÐÕÒ&Øˆ
Ø Ÿ™Ñ%UÅ_Ó%UÓUÐØ�\‰\ð	HàÐ
Ð7ð	9ð ØØÐ"Õ#Ø�ÕØ��Ið	
ô 9­Ó8ñ	
ó	÷ �hƒjð ô ˜F› qÔ(ˆ6�!�9Ð1¨cÐ1r/   c               ó$   € V ^8„  d   QhRRRRRR/# )r'   Ú
batch_msgsrR   Ú
batch_rowsr*   rS   r,   )r-   s   "r   r.   r.   3  s$   € ÷ +ñ +Ð-Að +ÐOcð +Ðhlñ +r/   c                óò  € \        W4       EFæ  w  r#RV\        &   \        VP                  R4      \        4      '       d   VR,          VR&   \        W24       \        VP                  R4      \        \        34      '       d   VR,          VR&   \        VP                  \        4      \        4      '       d   V\        ,          V\        &   VP                  \        4      p\        V\        4      '       d`   VP                  \        4      '       dE   \         F7  pVP                  V4      f   K  VP                  V4      e   K-  WE,          W%&   K9  	  EKI  \        V\        4      '       d+   VP                  \        4      '       d   VR,          VR&   EK‰  \        V\        4      '       g   EK¢  \         F:  pWT9   d   WE,          e   WE,          W%&   K  VR9  g   K(  VP                  VR4       K<  	  EKé  	  R# )zYStamp persistence markers and sync canonical durable fields onto live dicts after commit.TrU   r   Nra   )r   ra   )Úzipr   r>   rX   rY   r   rC   r
   r+   r	   rh   r‰   r‡   r‹   Ú_SYNC_FIELDSrŒ   )r»   r¼   Úwrittenr(   r‘   Úkeys   &&    r   Úsync_flushed_message_markersrÂ   3  sa  € ä˜J×3‰ˆØ(,ˆÔ$Ñ%Ü�c—g‘g˜iÓ(¬#×.Ò.Ø!$ Y¥ˆG�IÑÜ˜SÔ*Ü�c—g‘g˜kÓ*¬S´%¨L×9Ò9Ø#& {Õ#3ˆG�KÑ Ü�c—g‘gœoÓ.´×4Ò4Ø'*¬?Õ';ˆG”OÑ$Ø—G‘GœMÓ*ˆ	Ü�i¤×&Ò&¨9¯=©=¼×+HÒ+Hç-�Ø—=‘= Ó%Ô1°g·k±kÀ#Ó6FÔ6NØ#,¥>�G“Lô .ô ˜	¤4×(Ò(¨Y¯]©]¼=×-IÒ-IØ!*¨9Õ!5ˆG�IÔÜ˜	¤4×(Õ(ß#�ØÔ#¨	­Ò(BØ#,¥>�G“LØÐ 3Ö3Ø—K‘K  TÖ*ô	 $ó% 4r/   >   Úapi_contentÚdisplay_kindÚdisplay_metadataÚplatform_message_idÚcodex_reasoning_items)rÄ   rÅ   )r   ).Ú__doc__Ú
__future__r   r:   Úsqlite3Útypingr   r   r   r   r   Úagent.context_compressorr   Úagent.message_metadatar	   r
   r   r   r   Úhermes_state_commonr   r   Úhermes_state_identityr   r   Úhermes_state_messagesr   Ú	frozensetr   Útupler·   r#   r<   r‡   r¿   r‰   r‹   rM   r_   rn   rs   r—   r†   r    rƒ   rÂ   r,   r/   r   Ú<module>rÓ      só   ðñ0õ #ã Û ß 5Õ 5å 9÷\õ \ç 9ß UÝ 8ñ !Ø�6˜;¨Ð2DÀkÐSbÐcóeÐ ç�%Ñ[Ñ#9Ó[—%‘%Ñ[Ñ#9Ó[Ó[€ñ ÚgóÐ ÷ �ÑP¡/ÓP—‘ÑP¡/ÓPÓP€à=Ð à˜?Õ*€ð "€Ø€õõ0Rõõõ&Yõxaõ4-
õ`2÷>+r/   