+
    lHàjá†  ã                   ó<  a € R| t:0 t R t^ RIt^ RIt^ RIHt ^ RIHtHtH	t	 ]
]]3,          tRt/ RRbRRbRR	bR
R	bRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRbRRRRRRRRR RR!R/C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R0 R1 ltR2 R3 ltR4 R5 ltR6 R7 ltR8 R9 ltR: R; ltR< R= ltR> R? ltR@ RA ltRB RC ltRD RE lt RF RG lt!RH]3RI]3RJ]3RK]3RL]3RM]3RN]3RO] 3RP]!3.	t"] ^ k ]#! RORP04      t$R}RQ RR llt%RS RT lt&RU RV lt'R~RW RX llt(RRYR/RZ R[ lllt)R€R\ R] llt*R^ R_ lt+R` Ra lt,Rb Rc lt-Rd Re lt.Rf Rg lt/Rh Ri lt0Rj Rk lt1Rl Rm lt2Rn Ro lt3Rp Rq lt4Rr Rs lt5R�Rt Ru llt6Rv Rw lt7R‚Rx Ry llt8Rz R{ lt9R# )ƒar  Fuzzy find-and-replace for LLM-generated edits.

An ordered chain of increasingly permissive strategies (``STRATEGIES``) lets
whitespace, indentation, escaping and Unicode drift in tool-call arguments
still land on the intended region::

    new_content, match_count, strategy, error = fuzzy_find_and_replace(
        content, old_string, new_string, replace_all=False)
N)ÚSequenceMatcher)ÚCallableÚIterableÚOptionalz§No edit was applied because old_string and new_string are identical. Provide the existing text to replace in old_string and the changed replacement text in new_string.u   â€œÚ"u   â€�u   â€˜Ú'u   â€™u   â€”z--u   â€“Ú-u   â€¦ú...ô   Â Ú u   âˆ’u   â€€u   â€�u   â€‚u   â€ƒu   â€„u   â€…u   â€†u   â€‡u   â€ˆu   â€‰u   â€Šu   â€¯u   â�Ÿu   ã€€c                ó0   € V ^8„  d   QhR\         R\         /# ©é   ÚtextÚreturn©Ústr)Úformats   "Ú6/home/ubuntu/.hermes/hermes-agent/tools/fuzzy_match.pyÚ__annotate__r   %   s   € ÷ ñ œSð ¤Sñ ó    c                ób   € \         P                  4        F  w  rV P                  W4      p K  	  V # )z6Map typographic Unicode variants to ASCII equivalents.)ÚUNICODE_MAPÚitemsÚreplace)r   ÚcharÚrepls   &  r   Ú_unicode_normalizer   %   s*   € ä!×'Ñ'Ö)‰
ˆØ�|‰|˜DÓ'Šñ *à€Kr   c          
      ój   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        /# )r   Úcontent_linesÚ
start_lineÚend_lineÚcontent_lengthr   )Úlistr   ÚintÚSpan)r   s   "r   r   r   .   s6   € ÷ 3ñ 3¬T´#­Yð 3ÄCð 3Ü(+ð3Ü=@ð3ÜEIñ3r   c                ó~   € \        R V RV  4       4      p\        R V RV  4       4      ^,
          pV\        W54      3# )zOCharacter span covering ``content_lines[start_line:end_line]`` (end exclusive).c              3   óF   "  € T F  p\        V4      ^,           x € K  	  R# 5i©é   N©Úlen©Ú.0Úlines   & r   Ú	<genexpr>Ú,_calculate_line_positions.<locals>.<genexpr>1   s   é € ÐIÑ.H d”C˜“I —M’MÓ.Hùó   ‚!Nc              3   óF   "  € T F  p\        V4      ^,           x € K  	  R# 5ir(   r*   r,   s   & r   r/   r0   2   s   é € ÐEÑ,D D”#�d“)˜a—-’-Ó,Dùr1   )ÚsumÚmin)r   r    r!   r"   Ú	start_posÚend_poss   &&&&  r   Ú_calculate_line_positionsr7   .   sG   € ô ÑI¨m¸K¸ZÑ.HÓIÓI€IÜÑE¨M¸)¸8Ñ,DÓEÓEÈÕI€GØ”c˜.Ó2Ð2Ð2r   c                ó¤   € V ^8„  d   QhR\         R\        \         ,          R\        R\        \        .\        3,          R\        \
        ,          /# )r   Úcontentr   ÚnÚacceptr   )r   r#   r$   r   Úboolr%   )r   s   "r   r   r   6   sK   € ÷ Añ Aœ3ð A¬t´C­yð A¼Sð AÜ"¤C 5¬$ ;Õ/ðAÜ48¼µJñAr   c                óÂ   € \        \        V4      V,
          ^,           4       Uu. uF.  qC! V4      '       g   K  \        WWB,           \        V 4      4      NK0  	  up# u upi )zKSpans of every ``n``-line window starting at ``i`` for which ``accept(i)``.)Úranger+   r7   )r9   r   r:   r;   Úis   &&&& r   Ú_window_spansr@   6   sZ   € ô
 ”s˜=Ó)¨AÕ-°Õ1Ô2óAá2ˆA°f¸Q·iô 	IÔ! -°AµE¼3¸w»<ÖHÙ2ñAð Aùò As
   ¥A¹ Ac          	      ó®   € V ^8„  d   QhR\         R\         R\        \        \         ,          .\        \         ,          3,          R\        \        ,          /# )r   r9   ÚpatternÚ	transformr   )r   r   r#   r%   )r   s   "r   r   r   >   sI   € ÷ Vñ V¤cð V´Cð VÜ(0´$´sµ)°¼dÄ3½iÐ1GÕ(HðVÜMQÔRVÍZñVr   c           	     óš   aaaa€ V P                  R4      oS! VP                  R4      4      o\        S4      o\        V SSVVVV3R l4      # )zVMatch ``pattern`` against ``content`` after applying ``transform`` to each line block.Ú
c                 ó,   <€ S! SW S,            4      S8H  # ©N© )r?   r   r:   Úpattern_normrC   s   &€€€€r   Ú<lambda>Ú*_match_transformed_lines.<locals>.<lambda>E   s   ø€ ¡9¨]¸1À½UÐ-CÓ#DÈÒ#Tr   )Úsplitr+   r@   )r9   rB   rC   r   r:   rI   s   &&f@@@r   Ú_match_transformed_linesrM   >   sH   û€ ð —M‘M $Ó'€MÙ˜WŸ]™]¨4Ó0Ó1€LÜˆLÓ€AÜ˜ -°ßTóVð Vr   c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# )r   Úlinesr   )r#   r   )r   s   "r   r   r   H   s"   € ÷ ñ œ4¤�9ð ¬¬c­ñ r   c                ó¤   € \        V 4      p V ^ ,          P                  4       V ^ &   \        V 4      ^8”  d   V R,          P                  4       V R&   V # )z2Strip whitespace on the first and last lines only.éÿÿÿÿ)r#   Ústripr+   )rO   s   &r   Ú_strip_boundaryrS   H   sC   € ä�‹K€EØ�Q�x�~‰~Ó€Eˆ!�HÜ
ˆ5ƒz�A„~Ø˜"•I—O‘OÓ%ˆˆb‰	Ø€Lr   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   Úoriginalr   ©r   r#   r$   )r   s   "r   r   r   Q   s   € ÷ ñ ¤cð ¬d´3­iñ r   c                ó¼   € . p^ pV  F@  pVP                  V4       \        P                  V4      pY$e   \        V4      M^,          pKB  	  VP                  V4       V# )zÐMap each original index to its index in ``_unicode_normalize(original)``
(replacements can expand one char into several). Length ``len(original)+1``;
the last entry is a sentinel one past the final character.)Úappendr   Úgetr+   )rU   ÚresultÚnorm_posr   r   s   &    r   Ú_build_orig_to_norm_mapr\   Q   sX   € ð €FØ€HÛˆØ�‰�hÔÜ�‰˜tÓ$ˆØÒ!1”C˜”I°qÕ8Šñ ð ‡M�M�(ÔØ€Mr   c                óh   € V ^8„  d   QhR\         \        ,          R\        \        \        3,          /# )r   Úorig_to_normr   )r#   r$   Údict)r   s   "r   r   r   _   s&   € ÷ ñ ¤4¬¥9ð ´´c¼3°hµñ r   c                óZ   € / p\        V RR 4       F  w  r#VP                  W24       K  	  V# )z2norm_pos -> first original position mapping to it.NrQ   )Ú	enumerateÚ
setdefault)r^   ÚinvertedÚorig_posr[   s   &   r   Ú_invert_norm_mapre   _   s3   € à!€HÜ'¨°S°bÐ(9Ö:ÑˆØ×Ñ˜HÖ/ñ ;à€Or   c                ó^   € V ^8„  d   QhR\         \        ,          R\        R\        R\        /# )r   r^   Ú
orig_startÚnorm_endr   )r#   r$   )r   s   "r   r   r   g   s-   € ÷ ñ ¤D¬¥Ið ¼3ð Ì#ð ÔRUñ r   c                ój   € \        V 4      ^,
          pTpWC8  d   W,          V8  d   V^,          pK  V# )zHWalk from ``orig_start`` until the mapped position reaches ``norm_end``.r*   )r^   rg   rh   Úorig_lenÚorig_ends   &&&  r   Ú_norm_end_to_origrl   g   s4   € ä�<Ó  1Õ$€HØ€HØ
Ô
 ,Õ"8¸8Ô"CØ�A�ŠØ€Or   c                ó~   € V ^8„  d   QhR\         \        ,          R\         \        ,          R\         \        ,          /# )r   r^   Únorm_matchesr   )r#   r$   r%   )r   s   "r   r   r   p   s0   € ÷ ñ ¬d´3­ið ÄtÌDÅzð ÔVZÔ[_ÕV`ñ r   c           	     ó�   € \        V 4      p. pV F2  w  rEWB9   g   K  W$,          pVP                  V\        WV4      34       K4  	  V# )z@Convert spans in the normalised string to original-string spans.)re   rX   rl   )r^   rn   Únorm_to_orig_startÚresultsÚ
norm_startrh   rg   s   &&     r   Ú_map_positions_norm_to_origrs   p   sN   € ä)¨,Ó7ÐØ€GÛ ,Ñˆ
ØÖ+Ø+Õ7ˆJØ�N‰N˜JÔ(9¸,ÐT\Ó(]Ð^Ö_ñ !-ð €Nr   c          	      ót   € V ^8„  d   QhR\         R\         R\        \        ,          R\        \        ,          /# )r   rU   Ú
normalizedÚnormalized_matchesr   ©r   r#   r%   )r   s   "r   r   r   {   s2   € ÷ .ñ .¬ð .¼ð .Ü26´tµ*ð.ÜAEÄdÅñ.r   c           
     ó>  a€ . p^ ;rEV\        V 4      8  dÅ   V\        V4      8  dµ   W,          W,          8X  d&   VP                  V4       V^,          pV^,          pKX  W,          R9   dT   W,          R8X  dG   VP                  V4       V^,          pV\        V 4      8  d   W,          R9  d   V^,          pK´  K¶  K¸  VP                  V4       V^,          pKÔ  VP                  \        V4      .\        V 4      V,
          ,          4       / p/ p\        V4       F  w  r‰VP	                  W˜4       W‡V	&   K  	  . p
V FÛ  w  opSV9   d   VS,          pM\        V3R l\        V4       4       4      pV^,
          V9   d   W{^,
          ,          ^,           pMWËS,
          ,           pV\        V4      8  d=   W^,
          ,          R8X  d)   V\        V 4      8  d   W,          R9   d   V^,          pK(  V
P                  V\        V\        V 4      4      34       KÝ  	  V
# )zIBest-effort span mapping for ``[ \t]+`` -> ``' '`` whitespace collapsing.ú 	r   c              3   ó>   <"  € T F  w  rVS8¼  g   K  Vx € K  	  R # 5irG   rH   )r-   r?   r:   rr   s   &  €r   r/   Ú,_map_normalized_positions.<locals>.<genexpr>�   s   øé € ÐVÑ+B¡4 1ÀaÈ:ÁoŸQšQÓ+Bùs   ƒ“
)r+   rX   Úextendra   rb   r4   )rU   ru   rv   r^   Úorig_idxÚnorm_idxrp   Únorm_to_orig_endrd   r[   Úoriginal_matchesrh   rg   rk   rr   s   &&&           @r   Ú_map_normalized_positionsr�   {   sæ  ø€ ð €LØÐ€HØ
”S˜“]Ô
" x´#°j³/Ô'AØÕ Õ!5Ô5Ø×Ñ Ô)Ø˜�MˆHØ˜�MŠHØÕ 5Ô(¨ZÕ-AÀSÔ-Hà×Ñ Ô)Ø˜�MˆHØœ#˜h›-Ô'¨HÕ,>ÀeÔ,KØ˜A•’ñ -LÑ'ð
 ×Ñ Ô)Ø˜�MŠHØ×Ñœ˜Z›Ð)¬S°«]¸XÕ-EÕFÔGàÐØÐÜ'¨Ö5ÑˆØ×%Ñ% hÔ9Ø%-˜Ó"ñ 6ð ÐÛ 2Ñˆ
�HØÐ+Ô+Ø+¨JÕ7‰JäÔV¬9°\Ô+BÓVÓVˆJØ�a�<Ð+Ô+Ø'°1­Õ5¸Õ9‰Hà!°
Õ%:Õ;ˆHð ”c˜*“oÔ%¨*Àµ\Õ*BÀcÔ*IØœS ›]Ô*¨xÕ/AÀUÔ/JØ˜A•’Ø×Ñ ¬S°¼3¸x»=Ó-IÐ JÖKñ !3ð  Ðr   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# ©r   r9   rB   r   rw   )r   s   "r   r   r   °   s*   € ÷ Hñ HœSð H¬3ð H´4¼µ:ñ Hr   c                óœ   € \         P                  ! \         P                  ! V4      V 4       Uu. uF  q"P                  4       NK  	  up# u upi )u†   Strategy 1: exact, non-overlapping occurrences (str.replace semantics â€”
overlapping spans would corrupt the file under replace_all).)ÚreÚfinditerÚescapeÚspan)r9   rB   Úms   && r   Ú_strategy_exactrŠ   °   s6   € ô !Ÿkšk¬"¯)ª)°GÓ*<¸gÔFÓGÑF˜�F‰FŽHÑFÑGÐGùÒGs   ®A	c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   ¶   s*   € ÷ Zñ Z¤Cð Z´#ð Z¼$¼t½*ñ Zr   c                ó   € \        WR 4      # )z-Strategy 2: strip each line before comparing.c                 óJ   € V  Uu. uF  qP                  4       NK  	  up# u upi rG   ©rR   ©ÚlsÚls   & r   rJ   Ú(_strategy_line_trimmed.<locals>.<lambda>¸   s   € ÑUWÓAXÑUWÐPQÇ'Á'Æ)ÑUWÒAXùÒAXó   … ©rM   ©r9   rB   s   &&r   Ú_strategy_line_trimmedr–   ¶   s   € ä# GÑ6XÓYÐYr   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   »   s*   € ÷ 	Yñ 	Y¬Sð 	Y¼3ð 	YÄ4ÌÅ:ñ 	Yr   c                óf   € R pV! V 4      p\        W2! V4      4      pV'       g   . # \        WV4      # )z;Strategy 3: collapse runs of spaces/tabs to a single space.c                 ó2   € \         P                  ! R RV 4      # )z[ \t]+r   )r…   Úsub)Úss   &r   Ú	normalizeÚ2_strategy_whitespace_normalized.<locals>.normalize½   s   € Ü�vŠv�i  aÓ(Ð(r   )rŠ   r�   )r9   rB   rœ   Úcontent_normalizedÚmatches_in_normalizeds   &&   r   Ú_strategy_whitespace_normalizedr    »   s=   € ò)ñ # 7Ó+ÐÜ+Ð,>À	È'Ó@RÓSÐß Øˆ	Ü$ WÐBWÓXÐXr   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   Ç   s*   € ÷ [ñ [¬Cð [¼#ð [Ä$ÄtÅ*ñ [r   c                ó   € \        WR 4      # )z0Strategy 4: ignore leading indentation entirely.c                 óJ   € V  Uu. uF  qP                  4       NK  	  up# u upi rG   )Úlstripr�   s   & r   rJ   Ú0_strategy_indentation_flexible.<locals>.<lambda>É   s   € ÑVXÓAYÑVXÐQRÇ(Á(Æ*ÑVXÒAYùÒAYr“   r”   r•   s   &&r   Ú_strategy_indentation_flexibler¦   Ç   s   € ä# GÑ6YÓZÐZr   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   Ì   s%   € ÷ 7ñ 7¬ð 7´sð 7¼tÄD½zñ 7r   c                óŒ   € VP                  RR4      P                  RR4      P                  RR4      pW!8X  d   . # \        W4      # )zOStrategy 5: treat literal ``\n``/``\t``/``\r`` in the pattern as control chars.ú\nrE   ú\tÚ	ú\rÚ)r   rŠ   )r9   rB   Úpattern_unescapeds   && r   Ú_strategy_escape_normalizedr¯   Ì   sE   € àŸ™¨¨tÓ4×<Ñ<¸UÀDÓI×QÑQÐRWÐY]Ó^ÐØÔ#Øˆ	Ü˜7Ó6Ð6r   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   Ô   s*   € ÷ Gñ G¬ð G´cð G¼dÄ4½jñ Gr   c                ó"   € \        W\        4      # )z>Strategy 6: strip whitespace on the first and last lines only.)rM   rS   r•   s   &&r   Ú_strategy_trimmed_boundaryr²   Ô   s   € ä# G´oÓFÐFr   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   Ù   s*   € ÷ 
Wñ 
W¬#ð 
W¼ð 
WÄÄTÅ
ñ 
Wr   c                óÄ   € \        V4      p\        V 4      pW08X  d	   W!8X  d   . # \        W24      ;'       g    \        W24      pV'       g   . # \        \	        V 4      V4      # )zVStrategy 7: exact/line-trimmed match after Unicode->ASCII normalisation of both sides.)r   rŠ   r–   rs   r\   )r9   rB   Únorm_patternÚnorm_contentrn   s   &&   r   Ú_strategy_unicode_normalizedr·   Ù   sb   € ä% gÓ.€LÜ% gÓ.€LØÔ <Ô#:Øˆ	Ü# LÓ?÷ Jð JÜ-¨lÓIð çØˆ	Ü&Ô'>¸wÓ'GÈÓVÐVr   c                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r   æ   s*   € ÷ Cñ C¤Cð C´#ð C¼$¼t½*ñ Cr   c                ó®  aaa	a
a€ \        V4      P                  R4      p\        V4      ^8  d   . # V^ ,          P                  4       pVR,          P                  4       p\        V4      o\        V 4      P                  R4      o\	        \        S4      S,
          ^,           4       Uu0 uFO  pSV,          P                  4       V8X  g   K!  SVS,           ^,
          ,          P                  4       V8X  g   KM  VkKQ  	  upo
\        S
4      ^8X  d   RMRoRP                  V^R 4      o	R VVV	V
V3R llp\        W P                  R4      SV4      # u upi )zDStrategy 8: anchor on first+last lines, similarity-score the middle.rE   g      à?gffffffæ?c                ó0   € V ^8„  d   QhR\         R\        /# ©r   r?   r   ©r$   r<   )r   s   "r   r   Ú,_strategy_block_anchor.<locals>.__annotate__ú   s   € ÷ Zñ Z”3ð Zœ4ñ Zr   c                 ó¶   <€ V S9  d   R # S^8:  d   R# RP                  SV ^,           V S,           ^,
           4      p\        RVS4      P                  4       S8¬  # )FTrE   N)Újoinr   Úratio)r?   Úcontent_middler:   Únorm_content_linesÚpattern_middleÚpotential_matchesÚ	thresholds   & €€€€€r   ÚsimilarÚ'_strategy_block_anchor.<locals>.similarú   sY   ø€ ØÐ%Ô%ÙØ�Œ6ÙØŸ™Ð#5°a¸!µe¸AÀ½EÀA½IÐ#FÓGˆÜ˜t ^°^ÓD×JÑJÓLÐPYÑYÐYr   rQ   )r   rL   r+   rR   r>   r¿   r@   )r9   rB   Úpattern_linesÚ
first_lineÚ	last_liner?   rÆ   r:   rÂ   rÃ   rÄ   rÅ   s   &&     @@@@@r   Ú_strategy_block_anchorrË   æ   s9  ü€ ä& wÓ/×5Ñ5°dÓ;€MÜ
ˆ=Ó˜AÔØˆ	Ø˜qÕ!×'Ñ'Ó)€JØ˜bÕ!×'Ñ'Ó)€IÜˆMÓ€Aô ,¨GÓ4×:Ñ:¸4Ó@ÐäœÐ/Ó0°1Õ4°qÕ8Ô9ó@Ù9ˆaØ˜aÕ ×&Ñ&Ó(¨JÑ6ô 	
à˜q 1�u q�yÕ)×/Ñ/Ó1°YÑ>÷ 	
ˆÑ9ñ@Ðô
 Ð-Ó.°!Ô3‘¸€IØ—Y‘Y˜}¨Q¨rÐ2Ó3€N÷Zô Zô ˜§-¡-°Ó"5°q¸'ÓBÐBùò!@s   Â)EÃ'EÃ8Ec                óR   € V ^8„  d   QhR\         R\         R\        \        ,          /# rƒ   rw   )r   s   "r   r   r     s%   € ÷ <ñ <¤Sð <´3ð <¼4Ä½:ñ <r   c                ó,  aaaaaa€ VP                  R4      oV P                  R4      o\        S4      oS\        S4      8”  d   . # S^ ,          P                  4       oSR,          P                  4       oR R loR VVVVVV3R llp\        V SSV4      # )z«Strategy 9 (last resort): anchored per-line similarity, every non-blank line >= 0.80.
The anchor pre-filter bounds the scan; the all-lines rule stops coincidental matches.rE   c                ó<   € V ^8„  d   QhR\         R\         R\        /# )r   ÚaÚbr   )r   Úfloat)r   s   "r   r   Ú-_strategy_context_aware.<locals>.__annotate__  s&   € ÷ Fñ F”ð Fœð F¤ñ Fr   c                 óF   € W8X  d   R # \        RW4      P                  4       # )g      ð?N)r   rÀ   )rÏ   rÐ   s   &&r   Ú_simÚ%_strategy_context_aware.<locals>._sim  s!   € Ø”fˆsÐE¤/°$¸Ó"=×"CÑ"CÓ"EÐEr   c                ó0   € V ^8„  d   QhR\         R\        /# r»   r¼   )r   s   "r   r   rÒ     s   € ÷ Cñ C”#ð Cœ$ñ Cr   c                 óJ  <€ SW S,            pS! SV^ ,          P                  4       4      R8  d   R# S! SVR,          P                  4       4      R8  d   R# \        ;QJ d)    V3R l\        SV4       4       F  '       d   K   R# 	  R# ! V3R l\        SV4       4       4      # )é    çš™™™™™é?Fc              3   ó²   <"  € T FL  w  rVP                  4       '       * ;'       g)    S! VP                  4       VP                  4       4      R 8¬  x € KN  	  R# 5i)rÙ   NrŽ   )r-   Úp_lineÚc_linerÔ   s   &  €r   r/   Ú:_strategy_context_aware.<locals>.accept.<locals>.<genexpr>  sG   øé € ð Cá"A‘�ð —‘“Ô×NÐN¡$ v§|¡|£~°v·|±|³~Ó"FÈ$Ñ"NÔNÛ"Aùs
   ƒ"A¦1ATrQ   )rR   ÚallÚzip)r?   Úblock_linesrÔ   r   Ú	first_patÚlast_patr:   rÈ   s   & €€€€€€r   r;   Ú'_strategy_context_aware.<locals>.accept  s    ø€ Ø# A¨!¥eÐ,ˆÙ�	˜; q�>×/Ñ/Ó1Ó2°TÔ9ÙÙ�˜+ b�/×/Ñ/Ó1Ó2°TÔ9Ùß‹sô Cä"% m°[Ô"AóC�sŒsð 	CŠsð 	Cˆsô Cä"% m°[Ô"AóCó Cð 	Cr   rQ   )rL   r+   rR   r@   )	r9   rB   r;   rÔ   r   rá   râ   r:   rÈ   s	   && @@@@@@r   Ú_strategy_context_awarerä     sˆ   ý€ ð —M‘M $Ó'€MØ—M‘M $Ó'€MÜˆMÓ€AØŒ3ˆ}ÓÔØˆ	Ø˜aÕ ×&Ñ&Ó(€IØ˜RÕ ×&Ñ&Ó(€HõF÷Cõ Cô ˜ -°°FÓ;Ð;r   ÚexactÚline_trimmedÚwhitespace_normalizedÚindentation_flexibleÚescape_normalizedÚtrimmed_boundaryÚunicode_normalizedÚblock_anchorÚcontext_awarec          	      óŠ   € V ^8„  d   QhR\         \        \        ,          ,          R\        R\        R\        \        ,          /# )r   Ú
strategiesÚtargetÚwherer   )r   r   r   )r   s   "r   r   r   1  s7   € ÷ ñ œh¤x´¥}Õ5ð ¼sð ÜðÜ&.¬s¥mñr   c                ó–   € \        \        P                  R V  4       4      4      pV'       g   R# RRP                  V4       RV RV R2# )a.  The note for an edit whose span was found by a similarity strategy, else None.

Those strategies accept a window whose lines only resemble the search text, so the spliced span
can land a line off (observed: a duplicated closing delimiter just outside the intended region).
The normalizing strategies still match every line, so their boundaries are exact; they fire on
routine edits (e.g. missing base indentation), where a note would teach the model to ignore it.
Post-write verification cannot catch a shifted span: it only confirms the new content landed.
c              3   ó>   "  € T F  q\         9   g   K  Vx € K  	  R # 5irG   )ÚSIMILARITY_STRATEGIES)r-   r›   s   & r   r/   Ú boundary_note.<locals>.<genexpr>;  s   é € ÐR© AÔ<QÑ7QŸaša«ùs   ‚“
NzNon-exact match (strategy: z, Ú)z:. The edit span was located approximately, not matched to u³    literal boundaries â€” review the diff below to confirm the change landed exactly where intended (a shifted boundary can duplicate or drop a line just outside the edited region).)r#   r_   Úfromkeysr¿   )rï   rð   rñ   Úuseds   &&& r   Úboundary_noterù   1  sR   € ô ”—‘ÑR©ÓRÓRÓS€DßÙà
% d§i¡i°£oÐ%6°a¸°wð ?)Ø)/¨ð 17ð	7ðr   c                óH   € V ^8„  d   QhR\         R\         R\         R\        /# )r   r9   Ú
old_stringÚ
new_stringr   ©r   r<   )r   s   "r   r   r   H  s.   € ÷ Añ A¤ð A´ð AÄ#ð AÌ$ñ Ar   c                ó~   € V'       d%   \        VP                  4       4      ^8  g   W 9  d   R# W8H  ;'       g    W9  # )z¥True when the edit is already present (re-sent edit -> success-shaped no-op).
Conservative: new_string non-trivial (>= 8 chars) and present EXACTLY; old_string gone.F)r+   rR   )r9   rû   rü   s   &&&r   Úis_already_appliedrÿ   H  s8   € ÷ œ˜Z×-Ñ-Ó/Ó0°1Ô4¸
Ô8QÙØÑ#×@Ð@ zÑ'@Ð@r   c                óR   € V ^8„  d   QhR\         R\        \        ,          R\         /# )r   r9   Úmatchesr   rw   )r   s   "r   r   r   P  s*   € ÷ Añ Aœcð A¬D´­Jð A¼3ñ Ar   c                 ó:   a € R P                  V 3R lV 4       4      # )Ú c              3   ó0   <"  € T F  w  rSW x € K  	  R # 5irG   rH   )r-   ÚstartÚendr9   s   &  €r   r/   Ú#_matched_regions.<locals>.<genexpr>Q  s   øé € Ð@¹©*¨%�7˜5Õ%»ùs   ƒ)r¿   )r9   r  s   f&r   Ú_matched_regionsr  P  s   ø€ Ø�7‰7Ô@¹Ó@Ó@Ð@r   c                ó^   € V ^8„  d   QhR\         R\        \        ,          R\        R\         /# )r   r9   r  Úcapr   )r   r#   r%   r$   )r   s   "r   r   r   T  s-   € ÷ ñ ¤Sð ´4¼µ:ð ÄCð ÔPSñ r   c                óâ  € . pVRV  F¦  w  rEV P                  R^ V4      ^,           pV P                  R^ V4      ^,           pV P                  RV4      pVR	8X  d   \        V 4      pWV P	                  4       p	\        V	4      ^P8”  d   V	R,          R,           p	VP                  RV RV	 24       K¨  	  \        V4      V,
          p
V
^ 8”  d   VP                  RV
 R24       RP                  V4      # )
zBRender up to ``cap`` match positions as 'L<line>: <snippet>' rows.NrE   :NéM   Nr	   z  Lz: z
  ... and z morerQ   )ÚcountÚrfindÚfindr+   rR   rX   r¿   )r9   r  r
  Úrowsr  Ú_endÚline_noÚ
line_startÚline_endÚsnippetÚextras   &&&        r   Ú_format_match_locationsr  T  sç   € à€DØ˜t “}‰ˆØ—-‘-  a¨Ó/°!Õ3ˆØ—]‘] 4¨¨EÓ2°QÕ6ˆ
Ø—<‘<  jÓ1ˆØ�rŒ>Ü˜7“|ˆHØ XÐ.×4Ñ4Ó6ˆÜˆw‹<˜"ÔØ˜c•l UÕ*ˆGØ�‰�c˜'˜ " W IÐ.Ö/ñ %ô �‹L˜3Õ€EØˆq„yØ�‰�j   uÐ-Ô.Ø�9‰9�T‹?Ðr   Úcorrection_notesc                óî   € V ^8„  d   QhR\         R\         R\         R\        R\        \        \         ,          ,          R\        \         \
        \        \         ,          \        \         ,          3,          /# )r   r9   rû   rü   Úreplace_allr  r   )r   r<   r   r#   Útupler$   )r   s   "r   r   r   g  sp   € ÷ JQñ JQ¤Cð JQ´Sð JQÄcð JQÜ(,ðJQä-5´d¼3µiÕ-@ðJQäLQÔRUÔWZÔ\dÔehÕ\iÔksÔtwÕkxÐRxÕLyñJQr   c               óˆ  € V'       g   V ^ RR3# VP                  4       '       g   V ^ RR3# ^ RIHpHp  V! WV 4      w  rpY8X  d   T ^ R\
        3# \         EF4  w  ršT
! Y4      pT'       g   K  \        T4      ^8”  d7   T'       g/   \        RR4       \        Y4      pT ^ RR\        T4       RT 23u # T'       d@   \        T4      ^8”  d0   T	\        9   d%   \        RR4       T ^ RR\        T4       RT	 R	23u # T	R
8w  d   \        YY4      pT'       d	   T ^ RT3u # \        Y T4      p\        YTT	R
8w  d   TMRT	R8X  d   \        Y4      MRR7      p\        T	4       T'       d   Te   TP                  T4       T\        T4      T	R3u # 	  \        RR4       T ^ RR3#   T d   pT ^ R\	        T4      3u Rp?# Rp?ii ; i)a  Find and replace via the strategy chain.

Returns ``(new_content, match_count, strategy_name, error)``; on failure
``(content, 0, None, error)``. Successful escape corrections append their
explanation to ``correction_notes`` when supplied by a tool caller.
Nuú   old_string is empty â€” nothing to match. Set old_string to the exact existing text the replacement should replace (read the file first if unsure). To create a new file or fully rewrite one, use write_file instead. Do not re-send this call unchanged.uÈ   old_string is only whitespace â€” provide non-blank text to match. Set it to the exact existing text the replacement should replace (read the file first if unsure). Do not re-send this call unchanged.)ÚAmbiguousEscapeDriftErrorÚmaybe_correct_escape_driftÚ	ambiguouszFound zc matches for old_string. Provide more context to make it unique, or use replace_all=True. Matches:
z approximate matches via the 'z‘' strategy; replace_all only applies to exact matches. Provide the precise text (whitespace included) so an exact/line-trimmed match can be made.rå   rë   )rû   Úunicode_planÚno_matchz1Could not find a match for old_string in the file)rR   Útools.escape_drift_autocorrectr  r  r   ÚIDENTICAL_STRINGS_ERRORÚ
STRATEGIESr+   Ú_note_edit_matchr  rô   Ú_detect_escape_driftÚ_maybe_unescape_new_stringÚ_apply_replacementsÚ_unicode_edit_planrX   )r9   rû   rü   r  r  r  r  Úcorrection_noteÚexcÚstrategy_nameÚstrategy_fnr  Ú	locationsÚ	drift_errÚeffective_newÚnew_contents   &&&&$           r   Úfuzzy_find_and_replacer2  g  s  € ÷ ð ˜˜4ð;ð<ð 	<ð
 ×Ñ×Òð ˜˜4ðDðEð 	E÷ eð*Ù2LÈZÐelÓ2mÑ/ˆ
 ð ÔØ˜˜4Ô!8Ð8Ð8ç&0 jÑ"ˆÙ˜gÓ2ˆßÙäˆw‹<˜!Ô§KÜ˜T ;Ô/Ü/°ÓAˆIØ˜A˜tØœ˜W›˜ð 'à&˜Kð)ð*ò *÷ œ3˜w›<¨!Ô+°ÔAVÔ0VÜ˜T ;Ô/Ø˜A˜tØœ˜W›˜ð 'Ø!�?ð #8ð9ð:ò :ð ˜GÔ#Ü,¨W¸zÓVˆIßØ  4¨Ð2Ò2ä2°:ÈÓPˆÜ)Ø˜mØ%2°gÔ%=‘zÀ4à*Ð.BÔBô -¨ZÔGØHLô	Oˆô
 	˜Ô'ßÐ/Ò;Ø×#Ñ# OÔ4ØœC ›L¨-¸Ð=Ò=ñI '1ôL �T˜:Ô&Ø�A�tÐPÐPÐPøðY %ô *Ø˜˜4¤ S£Ð)Õ)ûð*ús   ´F! Æ!GÆ(F<Æ6GÆ<Gc                ó`   € V ^8„  d   QhR\         \        ,          R\         \        ,          RR/# )r   ÚstrategyÚmissr   N)r   r   )r   s   "r   r   r   ´  s)   € ÷ $ñ $œx¬�}ð $´H¼SµMð $ÈTñ $r   c                óH   €  ^ RI Hp T! Y4       R#   \         d     R# i ; i)zzReport to shared metrics which strategy landed (or why none did); a no-op unless a
metered patch tool call is in progress.)Únote_edit_matchN)Ú/hermes_cli.observability.shared_metrics_harnessr7  Ú	Exception)r4  r5  r7  s   && r   r%  r%  ´  s(   € ðÝSñ �HÖ#øô ô Úðús   ‚ ’! !c                ó€   € V ^8„  d   QhR\         R\        \        ,          R\         R\         R\        \         ,          /# ©r   r9   r  rû   rü   r   ©r   r#   r%   r   )r   s   "r   r   r   À  s;   € ÷ ñ ¬3ð ¼¼d½ð Ü.1ðÜ?BðÜGOÔPSÅ}ñr   c                óœ   € RV9  d   R# VP                  R4      pV F+  w  rVWV pRV9   g   K  WGP                  R4      8”  g   K)    R# 	  R# )ak  Error string when a literal two-character ``\n`` in the arguments stands in
for a real line break in the file (arguments JSON-escaped one extra time), else None.

Fires when some matched region contains a real newline and old_string holds MORE
literal ``\n`` than that region. old_string is copied from the file, so a genuine
edit has equal counts even when the code legitimately contains ``"\n"``; only the
surplus is drift. Regions are compared one by one because joining them would
multiply the file-side count under replace_all. new_string must carry a literal
``\n`` too: that is what gets written in place of a line break, since
_maybe_unescape_new_string deliberately never rewrites ``\n``. ``\r`` needs no
guard here -- that helper converts it whenever the region has a real CR. Drift in
new_string alone is indistinguishable from an edit that adds a ``\n`` literal.
r©   NrE   aÆ  Escape-drift detected: old_string contains more literal '\\n' sequences than the matched region of the file, which has real line breaks there instead. This is almost always a tool-call serialization artifact where a line break got escaped one extra time; new_string would write it as backslash + n. Re-read the file with read_file and pass old_string/new_string with actual line breaks, keeping only the '\\n' sequences that appear literally in the file.)r  )r9   r  rû   rü   Úold_literalsr  r  Úregions   &&&&    r   Ú_detect_newline_literal_driftr@  À  sY   € ð �JÔÙØ×#Ñ# EÓ*€LÛ‰
ˆØ˜sÐ#ˆØ�6Ž>˜l¯\©\¸%Ó-@Ö@ð5ò6ñ ñ r   c                ó€   € V ^8„  d   QhR\         R\        \        ,          R\         R\         R\        \         ,          /# r;  r<  )r   s   "r   r   r   á  sA   € ÷ Oñ O¤#ð O´´Tµ
ð OÜ%(ðOÜ69ðOÜ>FÄs½mñOr   c                ó  € RV9   ;'       g    RV9   pV'       g
   RV9  d   R# \        W4      pV'       d6   R F/  pWc9   g   K  Wb9   g   K  We9  g   K  V^,          pRV: RV: R2u # 	  \        WW#4      pV'       d   V# \        WRV4      # )	zÔError string when new_string carries tool-call escape artifacts, else None:
``\'``/``\"`` in both strings but not the matched region, doubled backslash
runs, or a literal ``\n`` standing in for a real line break.ú\'ú\"Ú\NzNEscape-drift detected: old_string and new_string contain the literal sequence a   but the matched region of the file does not. This is almost always a tool-call serialization artifact where an apostrophe or quote got prefixed with a spurious backslash. Re-read the file with read_file and pass old_string/new_string without backslash-escaping z characters.)rC  rD  )r  r@  Ú_detect_backslash_doubling)	r9   r  rû   rü   Úhas_quote_suspectsÚmatched_regionsÚsuspectÚplainÚnewline_drifts	   &&&&     r   r&  r&  á  s¡   € ð
  *Ñ,×CÐC°¸Ñ0CÐß $¨jÔ"8Ùä& wÓ8€OßÛ%ˆGØÖ$¨Ö)>À7ÖCaØ �
�ð,Ø,3©;ð 7*ð
 +0©°,ð@òAñ &ô 2°'ÀJÓ[€MßØÐÜ% oÀ:ÓNÐNr   c                óF   € V ^8„  d   QhR\         R\        \        ,          /# )r   r›   r   rV   )r   s   "r   r   r   ý  s   € ÷ 7ñ 7”sð 7œt¤C�yñ 7r   c                ól   € \         P                  ! RV 4       Uu. uF  p\        V4      NK  	  up# u upi )z5Lengths of maximal backslash runs in ``s``, in order.z\\+)r…   Úfindallr+   )r›   Úruns   & r   Ú_backslash_runsrP  ý  s+   € ä "§
¢
¨6°1Ô 5Ó6Ñ 5˜ŒC�ŽHÑ 5Ñ6Ð6ùÒ6s   š1c          	      ó^   € V ^8„  d   QhR\         R\         R\         R\        \         ,          /# )r   rH  rû   rü   r   ©r   r   )r   s   "r   r   r     s.   € ÷ 'ñ '´ð 'Äð 'Ü+.ð'Ü3;¼Cµ=ñ'r   c                óâ  € \        V4      p\        V 4      pV'       dÎ   V'       dÆ   \        V4      \        V4      8w  g­   W48X  g§   \        ;QJ d%    R \        W44       4       F  '       g   K   RM	  RM! R \        W44       4       4      '       g[   \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       g   \        V4      ^8¼  d   \        V4      V8X  d   R#  R# )zïDetect old_string whose every backslash run is exactly 2x the file's (arguments
JSON-escaped one extra time). Requires the same run count, a non-trivial signal
(a run >= 2 or 2+ runs), and new_string not already matching the file's counts.c              3   ó<   "  € T F  w  rW^,          8g  x € K  	  R# 5i©r   NrH   )r-   ÚoÚfs   &  r   r/   Ú-_detect_backslash_doubling.<locals>.<genexpr>  s   é € ÐCÑ*B¡$ !�1˜A�–:Ó*Bùs   ‚TFc              3   ó*   "  € T F	  q^8¬  x € K  	  R# 5irU  rH   )r-   rW  s   & r   r/   rX    s   é € Ð2©	 1˜Qž«	ùs   ‚Na¬  Escape-drift detected: every backslash run in old_string is exactly twice as long as in the matched region of the file (e.g. the file has `\\` where old_string has `\\\\`). The tool-call arguments were JSON-escaped one extra time; applying new_string verbatim would double every backslash in the file. Re-read the file with read_file and resend old_string/new_string with the backslash counts exactly as they appear in the file.)rP  r+   Úanyrß   )rH  rû   rü   Úold_runsÚ	file_runss   &&&  r   rF  rF    s£   € ô
 ˜zÓ*€HÜ Ó0€IßŸI¬¨X«¼#¸i».Ô)HØÔ$ß‹sÑC¬#¨hÔ*BÓC�s�sŠsÑC¬#¨hÔ*BÓC×CÒCß“CÑ2©	Ó2—C—C’CÑ2©	Ó2×2Ò2´c¸)³nÈÔ6IÜ˜zÓ*¨iÔ7Ùð	&ñ'r   c                ó^   € V ^8„  d   QhR\         R\         R\        \        ,          R\         /# )r   rü   r9   r  r   rw   )r   s   "r   r   r     s-   € ÷ 
ñ 
¬3ð 
¼ð 
ÄtÌDÅzð 
ÔVYñ 
r   c                ó”   € RV 9  d
   RV 9  d   V # \        W4      pR F&  w  rEW@9   g   K  WS9   g   K  V P                  WE4      p K(  	  V # )zÿConvert literal ``\t``/``\r`` in new_string to control chars, per sequence, only
when the matched region already contains the real control char (so ``sep = "\t"`` files
are left alone). ``\n`` is excluded: rewriting it would mangle source escape literals.rª   r¬   ))rª   r«   )r¬   r­   )r  r   )rü   r9   r  rH  ÚliteralÚcontrols   &&&   r   r'  r'    sS   € ð �JÔ 5°
Ô#:ØÐÜ& wÓ8€OÛ:ÑˆØÖ  WÖ%?Ø#×+Ñ+¨GÓ=ŠJñ ;ð Ðr   c                ó0   € V ^8„  d   QhR\         R\         /# ©r   r.   r   r   )r   s   "r   r   r   (  s   € ÷ 6ñ 6œcð 6¤cñ 6r   c                 ó\   € V R \        V 4      \        V P                  R4      4      ,
           # )Nry   )r+   r¤   )r.   s   &r   Ú_leading_whitespacerd  (  s'   € ØÐ4”�T“œS §¡¨UÓ!3Ó4Õ4Ð5Ð5r   c                óF   € V ^8„  d   QhR\         R\        \         ,          /# r   rR  )r   s   "r   r   r   ,  s"   € ÷ Kñ K¤ð K¬´#­ñ Kr   c                 óF   € \        R  V P                  R4       4       R4      # )c              3   óT   "  € T F  qP                  4       '       g   K  Vx € K   	  R # 5irG   rŽ   r,   s   & r   r/   Ú)_first_meaningful_line.<locals>.<genexpr>-  s   é € ÐCÑ"2˜$·j±j·l—’Ó"2ùs   ‚(ž
(rE   N)ÚnextrL   )r   s   &r   Ú_first_meaningful_linerj  ,  s   € ÜÑC $§*¡*¨TÔ"2ÓCÀTÓJÐJr   c                óH   € V ^8„  d   QhR\         R\        R\        R\        /# )r   r9   r  r  r   )r   r$   r<   )r   s   "r   r   r   0  s(   € ÷ ñ ¤Cð ´ð ¼#ð Ä$ñ r   c                ó  € TpWV P                  R4       Fj  pVP                  4       '       d9   V P                  R^ V4      ^,           p\        WV P                  R4      4      u # V\	        V4      ^,           ,          pKl  	  R# )zÛWhether text outside the match precedes its first non-blank line.

Leading newlines and blank lines do not make an anchor partial-line: the first
code line can still be captured in full and need indentation adjustment.
rE   z 	F)rL   rR   r  r<   r+   )r9   r  r  Úfirst_line_startr.   r  s   &&&   r   Ú_match_starts_mid_linern  0  s{   € ð ÐØ˜cÐ"×(Ñ(¨Ö.ˆØ�:‰:�<Š<Ø Ÿ™ t¨QÐ0@ÓAÀAÕEˆJÜ˜Ð+;Ð<×BÑBÀ7ÓKÓLÒLØœC ›I¨�MÕ)Òñ	 /ñ
 r   c          
      óT   € V ^8„  d   QhR\         R\         R\         R\        R\         /# )r   Úfile_regionrû   rü   Úmatch_starts_mid_liner   rý   )r   s   "r   r   r   ?  s1   € ÷  ñ  ¤sð  ¼ð  Ìð  Ü15ð Ü:=ñ r   c               ó   € V'       d	   V'       d   V# \        V4      p\        V 4      pVe   Vf   V# \        V4      p\        V4      pWg8X  d   V# . pVP                  R4       F—  p	V	P                  4       '       g   VP	                  V	4       K,  \        V	4      P                  V4      '       d&   VP	                  Wy\        V4      R ,           4       Kq  VP	                  WyP                  R4      ,           4       K™  	  RP                  V4      # )aÛ  Re-anchor ``new_string``'s indentation onto the file's actual base indent after a
non-exact match: swap the LLM base prefix (first non-blank old_string line) for the
file's, preserving relative nesting; shallower lines anchor to the file base.

Preserve the supplied indentation when non-whitespace text precedes the match's
first non-blank line: a partial-line expression has no reliable base indent.
Leading line breaks and blank lines still allow whole-line re-anchoring.
NrE   ry   )	rj  rd  rL   rR   rX   Ú
startswithr+   r¤   r¿   )
rp  rû   rü   rq  Ú	old_firstÚ
file_firstÚ
old_indentÚfile_indentÚ	out_linesr.   s
   &&&$      r   Ú_reindent_replacementry  ?  sæ   € ÷ ×.ØÐÜ& zÓ2€IÜ'¨Ó4€JØÒ˜JÒ.ØÐÜ$ YÓ/€JÜ% jÓ1€KØÔ ØÐà€IØ× Ñ  Ö&ˆØ�z‰z�|Š|Ø×Ñ˜TÖ"Ü  Ó&×1Ñ1°*×=Ò=Ø×Ñ˜[´°J³Ð0@Ð+AÕAÖBà×Ñ˜[¯;©;°uÓ+=Õ=Ö>ñ 'ð �9‰9�YÓÐr   c                ó^   € V ^8„  d   QhR\         R\         R\        \         \        3,          /# )r   rû   rü   r   ©r   r  r#   )r   s   "r   r   r   _  s/   € ÷ Oñ O¤3ð O´Cð O¼EÄ#ÄtÀ)Õ<Lñ Or   c                óP   € \        V 4      pV\        RW!4      P                  4       3# )zz``(normalized old, old->new opcodes)``: independent of the file region, so
a replace_all computes it once for every match.N)r   r   Úget_opcodes)rû   rü   Únorm_olds   && r   r)  r)  _  s)   € ô " *Ó-€HØ”_ T¨8Ó@×LÑLÓNÐNÐNr   c                ój   € V ^8„  d   QhR\         R\         R\        \         \        3,          R\         /# )r   rp  rü   Úplanr   r{  )r   s   "r   r   r   f  s3   € ÷ !ñ !´#ð !Ä3ð !Ü+0´´d°Õ+;ð!Ü@Cñ!r   c                óF  € Vw  r4V\        V 4      8w  d   V# \        V 4      p. pV Fh  w  rxršpVR8X  d?   \        P                  ! WX4      ^,
          p\	        W\V	4      pVP                  WV 4       KL  VR8w  g   KU  VP                  WV 4       Kj  	  RP                  V4      # )zÚApply only the old->new edits onto ``file_region``'s original (Unicode) text,
so a unicode_normalized match doesn't flatten the file's em-dashes/smart quotes.
``plan`` is ``_unicode_edit_plan(old_string, new_string)``.ÚequalÚdeleter  )r   r\   ÚbisectÚbisect_rightrl   rX   r¿   )rp  rü   r€  r~  ÚopcodesÚfile_orig_to_normÚresult_partsÚtagÚi1Úi2Új1Új2rg   rk   s   &&&           r   Ú _preserve_unicode_in_replacementrŽ  f  s©   € ð
 Ñ€HØÔ% kÓ2Ô2ØÐä/°Ó<Ðà €LÛ&Ñˆ�˜Ø�'Œ>ä×,Ò,Ð->ÓCÀaÕGˆJÜ(Ð):ÈÓKˆHØ×Ñ °xÐ @ÖAØ�HŽ_Ø×Ñ 
¨bÐ 1Ö2ñ  'ð �7‰7�<Ó Ð r   c                óÄ   € V ^8„  d   QhR\         R\        \        ,          R\         R\        \         ,          R\        \        \         \        3,          ,          R\         /# )r   r9   r  rü   rû   r   r   )r   r#   r%   r   r  )r   s   "r   r   r   }  sP   € ÷ ñ ¤ð ¬t´D­zð Ü$'ðÜ5=¼cµ]ðä&.¬u´S¼$°YÕ/?Õ&@ðäLOñr   c                óÈ   € T p\        VR RR7       FL  w  rgTpVe-   WV p	Ve   \        W˜V4      p\        W“V\        WV4      R7      pVRV V,           WWR ,           pKN  	  V# )zÞSplice ``new_string`` over each span (end-to-start so offsets stay valid);
``old_string`` non-None (non-exact match) re-indents it per region, and
``unicode_plan`` (unicode_normalized match) keeps each region's typography.c                 ó   € V ^ ,          # ©rØ   rH   ©Úxs   &r   rJ   Ú%_apply_replacements.<locals>.<lambda>„  s   € °A°a¶Dr   T)ÚkeyÚreverseN)rq  )ÚsortedrŽ  ry  rn  )
r9   r  rü   rû   r   rZ   r  r  Úadjustedr?  s
   &&&&&     r   r(  r(  }  sƒ   € ð €FÜ˜W©.À$×G‰
ˆØˆØÒ!Ø 3Ð'ˆFØÒ'ô <¸FÈlÓ[�Ü,Ø HÜ&<¸WÈSÓ&QôˆHð ˜˜� (Õ*¨V°D¨\Õ9Šñ Hð €Mr   c                ó0   € V ^8„  d   QhR\         R\         /# rb  r   )r   s   "r   r   r   –  s   € ÷ Eñ E¤ð E¬ñ Er   c                ó²   € V P                  R4      pV R\        V 4      \        V4      ,
           pVP                  RR4      P                  RR4      V,           # )uB   Render the leading whitespace run visibly (â†’ = tab, Â· = space).ry   Nr«   u   â†’r   ô   Â·)r¤   r+   r   )r.   ÚstrippedÚprefixs   &  r   Ú_visualize_whitespacerŸ  –  sM   € à�{‰{˜5Ó!€HØÐ,”3�t“9œs 8›}Õ,Ð-€FØ�>‰>˜$ Ó&×.Ñ.¨s°DÓ9¸HÕDÐDr   c          
      óT   € V ^8„  d   QhR\         R\         R\        R\        R\         /# )r   rû   r9   Úcontext_linesÚmax_resultsr   )r   r$   )r   s   "r   r   r   �  s1   € ÷ (ñ (¤3ð (´ð (ÄSð (Ô[^ð (Ôgjñ (r   c           
     óö  aaa€ V '       d	   V'       g   R# V P                  4       pVP                  4       oV'       d	   S'       g   R# V^ ,          P                  4       ;'       g    \        R V 4       R4      oS'       g   R# \        V3R l\	        S4       4       R R7      pV Uu. uF  qf^ ,          R8”  g   K  VNK  	  upRV pV'       g   R# . p\        4       p	V Fœ  w  r«\        ^ W²,
          4      o\        \        S4      V\        V4      ,           V,           4      pSV3V	9   d   KN  V	P                  SV34       VP                  RP                  VV3R	 l\        VS,
          4       4       4      4       Kž  	  R
P                  V4      pSV^ ,          ^,          ,          pVP                  4       S8X  d7   Wä^ ,          8w  d*   VR\        V4       R\        V^ ,          4       R2,          pV# u upi )zONumbered snippets of the lines most similar to old_string's anchor line, or ''.r  c              3   óp   "  € T F,  qP                  4       '       g   K  VP                  4       x € K.  	  R # 5irG   rŽ   )r-   r‘   s   & r   r/   Ú%find_closest_lines.<locals>.<genexpr>¦  s    é € Ð*U¹i¸Ï7É7Ï9¬9¨1¯7©7¯9¨9»iùs   ‚6ž6c              3   ó®   <"  € T FJ  w  rVP                  4       '       g   K  \        R SVP                  4       4      P                  4       V3x € KL  	  R # 5irG   )rR   r   rÀ   )r-   r?   r.   Úanchors   &  €r   r/   r¥  ª  sC   øé € ð NÙ$<™˜ÀÇ
Á
Çô N”o d¨F°D·J±J³LÓA×GÑGÓIÈ1ÕMÛ$<ùs
   ƒA¢3Ac                 ó   € V ^ ,          ) # r’  rH   r“  s   &r   rJ   Ú$find_closest_lines.<locals>.<lambda>«  s   € Ð^_Ð`aÕ^bÑ]br   )r–  g333333Ó?NrE   c              3   ól   <"  € T F)  pSV,           ^,           R RSSV,           ,           2x € K+  	  R# 5i)r)   Ú4dz| NrH   )r-   Újr   r  s   & €€r   r/   r¥  ¸  s6   øé € ð [ÙGYÀ!ˆu�q�y˜1�}˜RÐ   =°¸µÕ#;Ð"<Õ=ÓGYùs   ƒ14z
---
uF   

Whitespace difference detected (â†’ = tab, Â· = space):
  file has: z
  you sent: z.
Use the exact whitespace shown in 'file has'.)Ú
splitlinesrR   ri  r˜  ra   ÚsetÚmaxr4   r+   ÚaddrX   r¿   r>   rŸ  )rû   r9   r¡  r¢  Ú	old_linesÚscoredr›   ÚtopÚpartsÚseen_rangesÚ_Úline_idxr  rZ   Ú	best_liner§  r   r  s   &&&&           @@@r   Úfind_closest_linesr¹  �  sÂ  ú€ çŸWÙØ×%Ñ%Ó'€IØ×&Ñ&Ó(€MßŸMÙà�q�\×ÑÓ!×ZÐZ¤TÑ*U¹iÓ*UÐWYÓ%Z€FßÙäô NÜ$-¨mÔ$<óNÙSbôd€FáÓ
+‘f� !¥ s¡
�1ˆ1‘fÑ
+¨L¨[Ð
9€CßÙà€EÜ“%€KÛ‰ˆÜ�A�xÕ/Ó0ˆÜ”#�mÓ$ h´°Y³Õ&?À-Õ&OÓPˆØ�3ˆ<˜;Ô&ÙØ�‰˜ ˜Ô%Ø�‰�T—Y‘Yõ [ÜGLÈSÐSXÍ[ÔGYó[ó [ö 	\ñ ð �^‰^˜EÓ"€Fð ˜c !�f Q�iÕ(€IØ‡�Ó˜FÔ" y¸aµLÔ'@ØðÜ0°Ó;Ð<ð =Ü0°¸1µÓ>Ð?ð @<ð<õ	=ˆð
 €Mùò3 ,s   Â)G6Â=G6c          
      ój   € V ^8„  d   QhR\         \        ,          R\        R\        R\        R\        /# )r   ÚerrorÚmatch_countrû   r9   r   )r   r   r$   )r   s   "r   r   r   È  s=   € ÷ Nñ N¤¬¥ð N¼Cð NÜ%(ðNÜ36ðNÜ;>ñNr   c                óŽ   € V^ 8w  g    V '       d   V P                  R4      '       g   R# \        W#4      pV'       d
   RV,           # R# )z¬'\n\nDid you mean...' snippet for plain no-match errors only, else '' (ambiguous /
escape-drift / identical errors also have ``match_count == 0`` but a hint would mislead).zCould not findr  z&

Did you mean one of these sections?
)rs  r¹  )r»  r¼  rû   r9   Úhints   &&&& r   Úformat_no_match_hintr¿  È  s?   € ð �aÔŸu¨E×,<Ñ,<Ð=M×,NÒ,NÙÜ˜jÓ2€DßAEÐ6¸Õ=ÐMÈ2ÐMr   c                ó¼   € V ^8„  d   Qh/ ^ \         9   dH   \        \        \        \        \        \        .\        \
        ,          3,          3,          ,          ;R&   # )r   r$  )Ú__conditional_annotations__r#   r  r   r   r%   )r   s   "r   r   r      sE   € ÷ ñ ÷~	0ò 	0ŒD””sœH¤c¬3 Z´´dµÐ%;Õ<Ð<Õ=Õ>ñ 	0òr   )zold_string'sr  )é   )FrG   )NN)r   é   );rÁ  Ú__doc__r„  r…   Údifflibr   Útypingr   r   r   r  r$   r%   r#  r   r   r7   r@   rM   rS   r\   re   rl   rs   r�   rŠ   r–   r    r¦   r¯   r²   r·   rË   rä   r$  Ú	frozensetrô   rù   rÿ   r  r  r2  r%  r@  r&  rP  rF  r'  rd  rj  rn  ry  r)  rŽ  r(  rŸ  r¹  r¿  r   )rÁ  s   @r   Ú<module>rÈ     s€  øðöó Û 	Ý #ß /Ñ /àˆS�#ˆX…€ð&ð ð

"Øˆcð
"Ø˜Sð
"àˆcð
"à˜Sð
"ð ˆdð
"ð ˜cð
"ð ˆeð	
"ð ˜sð	
"ð
 ˆcð
"ð ˆcð
"ð ˜Sð
"ð #+¨Cð
"ð 2:¸3ð
"ð ˆcð
"ð ˜Sð
"ð #+¨Cð
"ð 2:¸3ð
"ð ˆc�8˜S (¨C°¸3Øˆc�8˜Sñ
"€õõ3õAõVõõõõõõ.õjHõZõ
	Yõ[õ
7õGõ

WõCõ><ð: ˆoÐØÐ+Ð,ØÐ=Ð>ØÐ;Ð<ØÐ5Ð6ØÐ3Ð4ØÐ7Ð8ØÐ+Ð,ØÐ-Ð.ð	B0€
ó 	0ñ " >°?Ð"CÓDÐ ÷õ.AõA÷ñ&JQàCG÷JQð JQ÷Z$õõBOõ87õ
'õ.
õ6õKõõ õ@Oõ!÷.õ2E÷(÷VNr   