Ë
    ãß²jÄ?  ã                   óê  — 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ZddlmZ ddl	m
Z
mZ  ej                  d«      Z ej                  «       Zi Zeed<    ej                  «       Zi Zeed<   dZd	Zd
Zd
Zd
Zd	ZdZdedefd„Zdededefd„Zdede ddfd„Z!deddfd„Z"dedededz  fd„Z#dedededdfd„Z$dededededz  fd„Z%dededededdf
d„Z&dede'defd„Z(d3defd„Z)d4defd „Z*dededdfd!„Z+dededdfd"„Z,d#ede'dz  fd$„Z-d#ede'dz  fd%„Z.d3d#eded&edz  ddfd'„Z/d#edede0fd(„Z1d)Z2ded#ed*e'd+ed,ed-e0de'e0e0f   fd.„Z3dedede0fd/„Z4dedededz  fd0„Z5	 d3dede e   d1edz  ddfd2„Z6y)5uZ  Per-task read/search bookkeeping for the file tools.

Process-lifetime state behind read_file/search_files/write_file/patch.
Per task_id ``_read_tracker``
stores: ``last_key``/``consecutive`` (loop detection; reset by any OTHER tool
call), ``read_history`` (diagnostics), ``dedup`` (key -> file metadata; survives context
compression), ``dedup_generation_reads`` (keys whose full content was served since
the last compaction boundary; cleared on compression so one recovery read returns
full content), ``dedup_hits`` (stub-loop breaker), ``read_timestamps``
(staleness warnings), ``read_coverage`` (per resolved path: the line ranges the
task has paged through at one file version â€” contiguous pages that reach the last line
count as a whole-file read), ``full_write_baselines`` (resolved paths whose
whole-file content this task saw via unredacted read_file page(s) or wrote via
write_file; required before write_file may overwrite an existing file â€” patch
never qualifies) and ``not_found`` (short-TTL negative cache). Every
container is hard-capped (``_cap_read_tracker_data``) so long sessions stay small.
é    N)Ú_evict_oldest)Ú_authoritative_workspace_rootÚ_resolve_path_for_taskztools.file_toolsÚ_read_trackerÚ_patch_failure_trackeré@   iô  iè  g      N@Útask_idÚreturnc                 ó°   — t         j                  | ddt        «       dœ«      }dD ]  }|j                  |i «       Œ |j                  dt        «       «       |S )z“Get-or-create the tracker entry for *task_id*, back-filling missing containers
    (search_tool / tests create partial entries). Lock must be held.Nr   )Úlast_keyÚconsecutiveÚread_history)ÚdedupÚ
dedup_hitsÚread_timestampsÚread_coverageÚfull_write_baselinesÚdedup_generation_reads)r   Ú
setdefaultÚset©r	   Ú	task_dataÚkeys      úC/home/ubuntu/.hermes/hermes-agent/tools/file_tools_read_tracking.pyÚ
_task_datar   2   s^   € ô ×(Ñ(¨Ø¨¼C»Eñ3Có D€Iàbò &ˆØ×Ñ˜S "Õ%ð&à×ÑÐ1´3³5Ô9ØÐó    Úresolved_pathc                 óÎ   — t         5  t        j                  | i «      }||vrt        |t        dz
  «       |j                  |d«      dz   ||<   ||   cddd«       S # 1 sw Y   yxY w)zAIncrement and return the consecutive-failure count for this path.é   r   N)Ú_patch_failure_lockr   r   r   Ú_PATCH_FAILURE_PATHS_CAPÚget)r	   r   Útask_failuress      r   Ú_record_patch_failurer$   =   sh   € ä	ñ ,Ü.×9Ñ9¸'À2ÓFˆà Ñ-Ü˜-Ô)AÀAÑ)EÔFØ'4×'8Ñ'8¸ÈÓ'JÈQÑ'Nˆ�mÑ$Ø˜]Ñ+÷,÷ ,ò ,ús   ‡A
AÁA$Úresolved_pathsc                 ó¦   — |syt         5  t        j                  | «      }|r|ndD ]  }|j                  |d«       Œ 	 ddd«       y# 1 sw Y   yxY w)z5Clear consecutive-failure counts for the given paths.N© )r    r   r"   Úpop)r	   r%   r#   Úrps       r   Ú_reset_patch_failuresr*   H   sS   € áØÜ	ñ (Ü.×2Ñ2°7Ó;ˆÙ$1‘.°rò 	(ˆBØ×Ñ˜b $Õ'ñ	(÷(÷ (ñ (ús   Š3AÁAr   c           	      óæ   — dt         fdt        fdt        fdt        fdt        fdt        fdt        fdt        ffD ]4  \  }}| j                  |«      }|€Œt        |«      |kD  sŒ)t        ||«       Œ6 y	)
zXEnforce size caps on the per-task sub-containers. Call with ``_read_tracker_lock`` held.r   r   r   r   r   r   r   Ú	not_foundN)Ú_READ_HISTORY_CAPÚ
_DEDUP_CAPÚ_READ_TIMESTAMPS_CAPÚ_FULL_WRITE_BASELINES_CAPÚ_NOT_FOUND_CAPr"   Úlenr   )r   r   ÚcapÚ	containers       r   Ú_cap_read_tracker_datar5   R   sˆ   € ð 
Ô*Ð+Ø	”*ÐØ	”zÐ"Ø	!¤:Ð.Ø	Ô0Ð1Ø	Ô.Ð/Ø	Ô!:Ð;Ø	”nÐ%ð'ò *‰ˆˆSð —M‘M #Ó&ˆ	ØÑ ¤S¨£^°cÓ%9Ü˜) SÕ)ñ*r   Úfilepathc                 óX   — 	 t        t        | |«      «      S # t        t        f$ r Y y w xY w©N)Ústrr   ÚOSErrorÚ
ValueError©r6   r	   s     r   Ú_resolved_or_noner=   c   s1   € ðÜÔ)¨(°GÓ<Ó=Ð=øÜ”ZÐ ò Ùðús   ‚ —)¨)ÚopÚresolved_strc                 ó†   — t         j                  |«      }|r|j                  d«      nd}|r|j                  | |fd«       yy)zJDrop the negative-cache entry for *(op, resolved_str)*. Lock must be held.r,   N)r   r"   r(   )r>   r?   r	   r   Únfs        r   Ú_pop_not_foundrB   j   s?   € ä×!Ñ! 'Ó*€IÙ'0ˆ�‰�{Ô	#°d€BÙ	Ø
�‰��LÐ! 4Õ(ð 
r   c                 óØ  — t         5  t        j                  |«      }|r&|j                  d«      xs i j                  | |f«      nd}|€
	 ddd«       y|\  }}t        j                  «       |z
  t
        kD  rt        | ||«       	 ddd«       y	 ddd«       t        j                  j                  |«      rt         5  t        | ||«       ddd«       yS # 1 sw Y   ŒGxY w# 1 sw Y   yxY w)zÙReturn cached not-found JSON for *(op, resolved_str)* if still fresh.

    *op* is "read" or "search" (different error JSON shapes). Evicted by TTL,
    by write_file/patch on the path, or by any other tool call.
    r,   N)
Ú_read_tracker_lockr   r"   ÚtimeÚ	monotonicÚ_NOT_FOUND_TTL_SECONDSrB   ÚosÚpathÚexists)r>   r?   r	   r   ÚentryÚtsÚcached_jsons          r   Ú_check_not_found_cacherN   r   sá   € ô 
ñ Ü!×%Ñ% gÓ.ˆ	ÙNW�—‘˜{Ó+Ò1¨r×6Ñ6¸¸LÐ7IÔJÐ]aˆØˆ=Ø÷	ð ð
  ‰ˆˆKÜ�>‰>Ó˜bÑ Ô#9Ò9Ü˜2˜|¨WÔ5Ø÷ð ð :÷ô 
‡w�w‡~�~�lÔ#Üñ 	6Ü˜2˜|¨WÔ5÷	6àØÐ÷!ð ú÷	6àús   ‡ACÁ1CÂ;C ÃCÃ C)Ú
error_jsonc                 ó¼   — t         5  t        |«      }t        j                  «       |f|j	                  di «      | |f<   t        |«       ddd«       y# 1 sw Y   yxY w)zKCache a not-found error so the next *op* call for *resolved_str* skips I/O.r,   N)rD   r   rE   rF   r   r5   )r>   r?   r	   rO   r   s        r   Ú_record_not_foundrQ   ‹   sU   € ä	ñ *Ü˜wÓ'ˆ	ÜEIÇ^Á^ÓEUÐWaÐDbˆ	×Ñ˜[¨"Ó-¨r°<Ð.@ÑAÜ˜yÔ)÷*÷ *ñ *ús   ‡AAÁAr   c                 óT   — | d   |k(  r| dxx   dz  cc<   | d   S || d<   d| d<   | d   S )zRUpdate last_key/consecutive for *key* and return the new count. Lock must be held.r   r   r   r'   )r   r   s     r   Ú_bump_consecutiverS   “   sM   € à�Ñ Ò#Ø�-Ó  AÑ%Ó ð �]Ñ#Ð#ð !$ˆ	�*ÑØ#$ˆ	�-Ñ Ø�]Ñ#Ð#r   c                 óÚ  — t         5  | r"t        j                  | «      r
t        |    gng }nt        t        j	                  «       «      }|D ]A  }d|v r|d   j                  «        |j                  dt        «       «      j                  «        ŒC |D �cg c]  }|t        |j                  di «      «      f‘Œ! }}ddd«       D ]ƒ  \  }}|j                  «       D ��ch c]  \  }}t        |«      |dd k7  sŒ|’Œ }}}|sŒ=t         5  |D ]2  }|d   j                  |«      ||   k(  sŒ|d   j                  |d«       Œ4 	 ddd«       Œ… yc c}w # 1 sw Y   Œ—xY wc c}}w # 1 sw Y   Œ§xY w)u  Advance the read-dedup generation after context compression (one task, or all
    when ``task_id`` is None). The per-key ``dedup`` metadata map is PRESERVED so unchanged
    files keep returning stubs instead of re-bloating the reclaimed context; the
    generation-read set is cleared so the FIRST unchanged read of each key after
    compaction returns full content the summary may have dropped. Stub-hit counters
    are cleared so the hard block restarts fresh. write_file baselines survive
    exactly like the dedup map does â€” while the file metadata still matches the
    stamp this task recorded; byte identity is checked before overwriting. A baseline
    whose file changed underneath is dropped
    (the stat runs outside the lock so a hung mount cannot stall other tasks).r   r   r   Néÿÿÿÿ)rD   r   r"   ÚlistÚvaluesÚclearr   r   ÚdictÚitemsÚ_file_metadatar(   )r	   Útargetsr   Ú
candidatesÚ	baselinesÚpÚversionÚchangeds           r   Úreset_file_deduprb   �   s‰  € ô 
ñ 
0ÙÜ2?×2CÑ2CÀGÔ2L”} WÑ-Ñ.ÐRT‰Gäœ=×/Ñ/Ó1Ó2ˆGØ ò 	JˆIØ˜yÑ(Ø˜,Ñ'×-Ñ-Ô/Ø× Ñ Ð!9¼3»5ÓA×GÑGÕIð	Jð
 (/ö0Ø#ð !¤$ y§}¡}Ð5KÈRÓ'PÓ"QÒRð 0ˆ
ð 0÷
0ð !+ò GÑˆ	�9Ø'0§¡Ó'8×^™˜˜G¼NÈ1Ó<MÐQXÐY\ÐZ\ÐQ]Ó<]’1Ð^ˆÑ^ÚÜ#ñ GØ ò G�AØ Ð!7Ñ8×<Ñ<¸QÓ?À9ÈQÁ<ÓOØ!Ð"8Ñ9×=Ñ=¸aÀÕFñG÷Gð GñGùò0÷
0ð 
0üó _÷Gð Gús<   ‡BEÂ$E
Â7EÃEÃ6EÄ E!Ä'E!Å
EÅEÅ!E*	c                 óÔ   — t         5  t        j                  | «      }|r6d|d<   d|d<   dD ]'  }|j                  |«      sŒ||   j                  «        Œ) ddd«       y# 1 sw Y   yxY w)a!  Reset the consecutive read/search counter for a task.

    Called by the dispatcher for every tool OTHER than read_file/search_files.
    Also clears stub-hit counters and the not-found cache: any other tool may
    have created a previously-missing path (or flipped its permissions).
    Nr   r   r   )r   r,   )rD   r   r"   rX   r   s      r   Únotify_other_tool_callrd   ¼   sn   € ô 
ñ +Ü!×%Ñ% gÓ.ˆ	ÙØ$(ˆI�jÑ!Ø'(ˆI�mÑ$Ø2ò +�Ø—=‘= Õ%Ø˜c‘N×(Ñ(Õ*ð+÷+÷ +ñ +ús   ‡8AÁ AÁA'c                 ó@  — t        | |«      }|€yt        5  t        j                  |«      }|€
	 ddd«       y|j                  d«      }|r!|D �cg c]  }|d   |k(  sŒ|‘Œ c}D ]  }||= Œ t	        d||«       t	        d||«       ddd«       yc c}w # 1 sw Y   yxY w)z©Evict every dedup entry (all offset/limit ranges) and not-found entry for *filepath*
    after a write, so the next read returns fresh content. Acquires the lock itself.Nr   r   ÚreadÚsearch)r=   rD   r   r"   rB   )r6   r	   Úresolvedr   r   Úks         r   Ú_invalidate_dedup_for_pathrj   Í   sµ   € ô ! ¨7Ó3€HØÐØÜ	ñ 	4Ü!×%Ñ% gÓ.ˆ	ØÐØ÷	4ð 	4ð —‘˜gÓ&ˆÙØ!&Ö;˜A¨!¨A©$°(Ó*:’aÒ;ò �Ø˜!‘Hðä�v˜x¨Ô1Ü�x ¨7Ô3÷	4ð 	4ùò <÷	4ð 	4ús(   –B¸BÁBÁBÁ!%BÂBÂBc                 ó<  — t        | |«       t        | |«      }|€y	 t        j                  j	                  |«      }t        5  t        j                  |«      }|� ||j                  di «      |<   t        |«       ddd«       y# t
        $ r Y yw xY w# 1 sw Y   yxY w)a  After a successful write: invalidate dedup and refresh the stored mtime so
    consecutive edits by the same task don't trigger false staleness warnings.

    Also invalidates the dedup cache for the written path so that subsequent reads return fresh content
    (fixes #13144).
    Nr   )rj   r=   rH   rI   Úgetmtimer:   rD   r   r"   r   r5   )r6   r	   rh   Úcurrent_mtimer   s        r   Ú_update_read_timestamprn   ß   s¥   € ô ˜x¨Ô1Ü  ¨7Ó3€HØÐØðÜŸ™×(Ñ(¨Ó2ˆô 
ñ .Ü!×%Ñ% gÓ.ˆ	ØÐ ØDQˆI× Ñ Ð!2°BÓ7¸ÑAÜ" 9Ô-÷	.ð .øô ò Ùðú÷.ð .ús   �B Á8BÂ	BÂBÂBrh   c                 ó¾   — 	 t        j                  | «      }|j                  |j                  |j                  |j
                  |j                  fS # t        $ r Y y w xY wr8   )rH   ÚstatÚst_devÚst_inoÚst_sizeÚst_mtime_nsÚst_ctime_nsr:   )rh   Ústs     r   r[   r[   õ   sL   € ðÜ�W‰W�XÓˆØ�y‰y˜"Ÿ)™) R§Z¡Z°·±ÀÇÁÐOÐOøÜò Ùðús   ‚AA Á	AÁAc           	      óæ  ‡‡— 	 t        j                  t        j                   | «      j                  «      syt        j                  | t        j
                  t        t        dd«      z  t        t        dd«      z  «      }t        j                  |d«      5 }t        j                  |j                  «       «      Št        j                  ‰j                  «      s
	 ddd«       yt        j                  |d«      j                  «       }t        j                   | «      Šddd«       d}t        ˆfd„|D «       «      }|t        ˆfd	„|D «       «      k(  rg |¢‘­S y# 1 sw Y   Œ>xY w# t        $ r Y yw xY w)
zGA byte snapshot, not just mtime (editors/copy tools can preserve that).NÚ
O_NONBLOCKr   ÚO_BINARYÚrbÚsha256)rq   rr   rs   rt   ru   c              3   ó6   •K  — | ]  }t        ‰|«      –— Œ y ­wr8   ©Úgetattr)Ú.0ÚnameÚbefores     €r   ú	<genexpr>z _file_version.<locals>.<genexpr>
  s   øè ø€ ÒA°$œ ¨×-ÑAùó   ƒc              3   ó6   •K  — | ]  }t        ‰|«      –— Œ y ­wr8   r}   )r   r€   Úafters     €r   r‚   z _file_version.<locals>.<genexpr>  s   øè ø€ ÒD°TœG E¨4×0ÑDùrƒ   )rp   ÚS_ISREGrH   Úst_modeÚopenÚO_RDONLYr~   ÚfdopenÚfstatÚfilenoÚhashlibÚfile_digestÚdigestÚtupler:   )rh   ÚfdÚstreamr�   Úfieldsr`   r…   r�   s         @@r   Ú_file_versionr”   ý   s+  ù€ ðÜ�|‰|œBŸG™G HÓ-×5Ñ5Ô6ØÜ�W‰W�XœrŸ{™{¬W´R¸ÀqÓ-IÑIÌGÔTVÐXbÐdeÓLfÑfÓgˆÜ�Y‰Y�r˜4Ó ð 	& FÜ—X‘X˜fŸm™m›oÓ.ˆFÜ—<‘< §¡Ô/Ø÷	&ð 	&ô ×(Ñ(¨°Ó:×AÑAÓCˆFÜ—G‘G˜HÓ%ˆE÷	&ð OˆÜÓA¸&ÔAÓAˆØ”eÓD¸VÔDÓDÒDØ%�WÐ%˜fÑ%Ð%Ø÷	&ð 	&ûô ò Ùðús<   „2E$ ·AE$ ÂAEÃE$ Ã"9EÄ;E$ ÅE!ÅE$ Å$	E0Å/E0Úexpected_sha256c                 óÔ   — t        | «      }|�|�|d   j                  «       |k7  ryt        5  t        |«      }||d   t	        | «      <   t        |«       ddd«       y# 1 sw Y   yxY w)zÎRecord that *task_id* saw the whole current content of *resolved* (full
    unredacted read_file, or its own successful write_file), so a later
    write_file may replace the file. Acquires the lock itself.NrU   r   )r”   ÚhexrD   r   r9   r5   )rh   r	   r•   r`   r   s        r   Ú_mark_full_write_baseliner˜     sl   € ô ˜HÓ%€GØ€˜?Ð6¸7À2¹;¿?¹?Ó;LÐP_Ò;_ØÜ	ñ *Ü˜wÓ'ˆ	Ø;Bˆ	Ð(Ñ)¬#¨h«-Ñ8Ü˜yÔ)÷*÷ *ñ *ús   ­(AÁA'c                 óæ   — t         5  t        j                  |«      xs i }|j                  di «      j                  t        | «      «      }d d d «       d uxr t	        | «      |k(  S # 1 sw Y   ŒxY w)Nr   )rD   r   r"   r9   r”   )rh   r	   r   Úbaselines       r   Ú_has_full_write_baseliner›     so   € Ü	ñ PÜ!×%Ñ% gÓ.Ò4°"ˆ	Ø—=‘=Ð!7¸Ó<×@Ñ@ÄÀXÃÓOˆ÷Pð ˜4ÐÒG¤M°(Ó$;¸xÑ$GÐG÷Pð Pús   ‡AA'Á'A0é   r`   ÚstartÚendÚredactedc                 óì  — | j                  di «      }|j                  |«      }|�|d   |k7  st        |d   «      t        kD  r|g ddœx}||<   |d   xs ||d<   g }	t	        |d   ||fgz   «      D ]F  \  }
}|	r,|
|	d   d   dz   k  r|	d   d	   t        |	d   d   |«      f|	d<   Œ4|	j                  |
|f«       ŒH |	|d<   t        |t        «      xr |d	kD  xr |	d	   d	   dk  xr |	d	   d   |k\  }||d   fS )
a  Merge the page ``start..end`` into this task's coverage of *resolved* and return
    ``(complete, redacted_any)``: whether pages taken at this same *version* now reach from
    line 1 to *total_lines*, and whether any of them came back redacted. A file too large
    for one read_file page (>2000 lines / the char budget) can only ever be seen this
    way, so paging through it must count as a whole-file read. A new version restarts the
    coverage (the earlier pages describe a file that no longer exists). Lock must be held.r   r`   ÚrangesF)r`   r¡   rŸ   rŸ   rU   r   r   )	r   r"   r2   Ú_READ_COVERAGE_RANGES_CAPÚsortedÚmaxÚappendÚ
isinstanceÚint)r   rh   r`   r�   rž   Útotal_linesrŸ   ÚcoveragerK   ÚmergedÚsÚeÚcompletes                r   Ú_note_read_coverager®   )  sK  € ð ×#Ñ# O°RÓ8€HØ�L‰L˜Ó"€EØ€}˜˜iÑ(¨GÒ3´s¸5À¹?Ó7KÔNgÒ7gØ18ÀBÐTYÑ%ZÐZˆ�˜Ñ"Ø˜jÑ)Ò5¨X€Eˆ*ÑØ$&€FÜ�u˜X‘¨5°#¨,¨Ñ7Ó8ò "‰ˆˆ1Ù�a˜6 "™: a™=¨1Ñ,Ò,Ø  ™* Q™-¬¨V°B©Z¸©]¸AÓ)>Ð?ˆF�2ŠJà�M‰M˜1˜a˜&Õ!ð	"ð
 €Eˆ(�OÜ˜;¬Ó,ò F°¸q±ò FØ˜1‘I˜a‘L AÑ%òFØ*0°©)°A©,¸+Ñ*Eð à�U˜:Ñ&Ð&Ð&r   c                 ó4  — t        | |«      }|€yt        5  t        j                  |«      }|r!|j                  di «      j                  |«      nd}ddd«       €y	 t        j
                  j                  |«      |k7  S # 1 sw Y   Œ/xY w# t        $ r Y yw xY w)zšTrue when the file's mtime changed since this task last read it. False when
    never read, fresh, or unstattable (a deleted file is the write's problem).NFr   )r=   rD   r   r"   rH   rI   rl   r:   )r6   r	   rh   r   Ú
read_mtimes        r   Ú_read_mtime_driftedr±   B  s£   € ô ! ¨7Ó3€HØÐØÜ	ñ _Ü!×%Ñ% gÓ.ˆ	ÙKT�Y—]‘]Ð#4°bÓ9×=Ñ=¸hÔGÐZ^ˆ
÷_ð ÐØðÜ�w‰w×Ñ Ó)¨ZÑ7Ð7÷_ð _ûô ò Ùðús   –;A?Á!B Á?BÂ	BÂBc                 ó(   — t        | |«      rd| › d�S y)zNWarn (don't block) when the file's mtime changed since this task last read it.z	Warning: z£ was modified since you last read it (external edit or concurrent agent). The content you read may be stale. Consider re-reading the file to verify before writing.N)r±   r<   s     r   Ú_check_file_stalenessr³   S  s*   € ä˜8 WÔ-à˜�zð "Lð Lð	Mð r   Ú
session_idc                 óv  ‡	— ddl m} |D �cg c]  }|sŒ|‘Œ	 }}|sy	 ddlmŠ	 ddlm} |D �cg c]  }t         ||«      j                  «      ‘Œ }}t        ˆ	fd„|D «       d«      xs t        | «      xs |d   } ||xs | ||¬«       yc c}w c c}w # t        $ r t        j                  dd	¬
«       Y yw xY w)z¯Best-effort note that successful edits made prior verification stale. cwd: the
    first edited path's recognised project root, else the workspace root, else the first parent.r   )ÚPathN)Úproject_facts_for)Úmark_workspace_editedc              3   ó4   •K  — | ]  } ‰|«      sŒ|–— Œ y ­wr8   r'   )r   Úcr·   s     €r   r‚   z+_mark_verification_stale.<locals>.<genexpr>k  s   øè ø€ Ò@˜1Ñ+<¸QÕ+?”QÑ@ùs   ƒ‘)r´   ÚcwdÚpathsz verification stale marker failedT)Úexc_info)Úpathlibr¶   Úagent.coding_contextr·   Úagent.verification_evidencer¸   r9   ÚparentÚnextr   Ú	ExceptionÚloggerÚdebug)
r	   r%   r´   r¶   r_   r¼   r¸   Úparentsr»   r·   s
            @r   Ú_mark_verification_stalerÇ   ]  s¾   ø€ õ à&Ö,�1ª!ŠQÐ,€EÐ,ÙØð	HÝ:ÝEà05Ö6¨1”3‘t˜A“w—~‘~Õ&Ð6ˆÐ6ÜÓ@ Ô@À$ÓGò GÜ/°Ó8òGØ<CÀA¹Jð 	á¨Ò)>°wÀCÈuÖUùò -ùò 7øô ò HÜ�‰Ð7À$ˆÖGðHús,   ŒB”BžB ®"BÁ:B ÂB Â B8Â7B8r8   )Údefault)7Ú__doc__r�   ÚloggingrH   rp   Ú	threadingrE   Útools.file_stater   Útools.file_tools_pathsr   r   Ú	getLoggerrÄ   ÚLockrD   r   rY   Ú__annotations__r    r   r!   r-   r.   r/   r0   r1   rG   r9   r   r§   r$   rV   r*   r5   r=   rB   rN   rQ   r�   rS   rb   rd   rj   rn   r[   r”   r˜   Úboolr›   r¢   r®   r±   r³   rÇ   r'   r   r   ú<module>rÒ      s  ðòó$ Û Û 	Û Û Û å *ß Xà	ˆ×	Ñ	Ð-Ó	.€à#�Y—^‘^Ó%Ð Ø€ˆtÓ ð %�i—n‘nÓ&Ð Ø!Ð ˜Ó !ØÐ ð Ð Ø€
ØÐ Ø Ð Ø€ØÐ ð˜ð  ó ð, 3ð ,°sð ,¸só ,ð( 3ð (¸ð (Àó (ð* dð *¨tó *ð" ð ¨cð °c¸D±jó ð)�sð )¨#ð )¸ð )Àó )ð˜sð °#ð Àð ÈÈdÉ
ó ð2*˜#ð *¨Sð *¸3ð *ÈCð *ÐTXó *ð$ ð $¨Eð $°có $ñG˜có Gñ>+ Có +ð"4¨ð 4°sð 4¸tó 4ð$. Sð .°3ð .¸4ó .ð,˜Sð  U¨T¡\ó ð˜Cð  E¨D¡Ló ñ*
*¨ð 
*°cð 
*ÈCÐRVÉJð 
*Ðbfó 
*ðH sð H°Sð H¸Tó Hð  Ð ð' 4ð '°3ð 'Àð 'Èsð 'ÐY\ð 'Ø/3ð'Ø8=¸dÀD¸jÑ8Ió'ð2 #ð °ð ¸ó ð" Cð °#ð ¸#À¹*ó ð 7;ñH cð H¸4À¹9ð HØ),¨t©ðHØ?CôHr   