
    Cj=                       S r SSKJr  SSKJr  SSKJr  SSKJr  SSK	J
r
Jr  SSKrSSKJr  SS	KJr  SS
KJr   " S S5      r\R*                  R,                   " S S5      5       r\S:X  a  \" 5       r\R5                  SS5        gg)zm
Fuzzy matcher.

This class is used by the [command palette](/guide/command_palette) to match search terms.

    )annotations)	lru_cache)
itemgetter)finditer)IterableSequenceN)LRUCache)Content)Stylec                      \ rS rSrSr SSS.     SS jjjrSS jr\\" SS9SS	 j5       5       r	SS
 jr
      SS jrSrg)FuzzySearch   zYPerforms a fuzzy search.

Unlike a regex solution, this will finds all possible matches.
i   )
cache_sizec               0    Xl         [        U5      U l        g)z}Initialize fuzzy search.

Args:
    case_sensitive: Is the match case sensitive?
    cache_size: Number of queries to cache.
N)case_sensitiver	   cache)selfr   r   s      _/home/rurouni/.local/share/pipx/venvs/strix-agent/lib/python3.13/site-packages/textual/fuzzy.py__init__FuzzySearch.__init__   s     -MUN

    c                    X4nX0R                   ;   a  U R                   U   $ S/ 4n[        U R                  X5      [        S5      US9nXPR                   U'   U$ )zMatch against a query.

Args:
    query: The fuzzy query.
    candidate: A candidate to check,.

Returns:
    A pair of (score, tuple of offsets). `(0, ())` for no result.
        r   )keydefault)r   max_matchr   )r   query	candidate	cache_keyr   results         r   matchFuzzySearch.match+   sZ     &	

"::i((03RyT[[2
1wW &

9r   i   )maxsizec                r    [        [        SU5       Vs1 s H  o"R                  5       iM     sn5      $ s  snf )Nz\w+)	frozensetr   start)clsr   r"   s      r   get_first_lettersFuzzySearch.get_first_letters>   s.     Xfi5PQ5PE++-5PQRRQs   4c                    U R                  U5      n[        U5      nU[        UR                  U5      5      -   nSnUtpxU H  n	XS-   :w  a  US-  nU	nM     XFS-
  -
  U-  n
USX-  -   -  nU$ )zGScore a search.

Args:
    search: Search object.

Returns:
    Score.
   )r)   lenintersection)r   r   	positionsfirst_lettersoffset_countscoregroupslast_offsetoffsetsoffsetnormalized_groupss              r   r2   FuzzySearch.scoreC   s     ..y9 9~#c-*D*DY*O&PP )Fq(! K  *aZ8LH';<<r   c           	   #    ^^^^#    / mSnU R                   (       d   UR                  5       nUR                  5       nU R                  nX;   aH  UR                  U5      n[	        [        XU[        U5      -   5      5      nU" X&5      X!:X  a  SOS-  U4v   g [        U5       H  u  px[        U5      U-
  n	/ n
TR                  U
5        UnUR                  X5      =nS:w  a5  U
R                  U5        US-   nX:  a  OUR                  X5      =nS:w  a  M5  U
(       d  Sv     g U
S   S-   nM     / m[        U5      mSUUUU4S jjmT" / S5        T H  nU" X&5      U4v   M     g 7f)	Nr   g       @g      ?r,   )r    c                   > TU    HG  nU (       a
  X S   :  d  M  / U QUPn[        U5      T:X  a  TR                  U5        M<  T" X1S-   5        MI     g)zoRecursively match offsets.

Args:
    offsets: A list of offsets.
    positions_index: Index of query letter.

r:   r,   N)r-   append)r5   positions_indexr6   new_offsetsget_offsetsletter_positionspossible_offsetsquery_lengths       r   r@   'FuzzySearch._match.<locals>.get_offsets   sW     +?;&2;"6"4G"4V"4K;'<7(//<#K11DE <r   )r5   z	list[int]r>   intreturnNone)	r   lowerr2   findlistranger-   	enumerater=   )r   r   r   positionr2   query_locationr5   r6   letter
last_indexr/   indexlocationr@   rA   rB   rC   s                @@@@r   r   FuzzySearch._match^   sq     -/""!)IKKME

&^^E2N5#e*1LMNGi)I4FSCP  '.NFY&0J#%I##I.E(~~f<<8C  * 1&	  )~~f<<8C
  |a'H / -/5z	F 	F  	B'G	+W44 (s   DE$AE$)r   r   N)F)r   boolr   rE   rF   rG   )r   strr   rU   rF   ztuple[float, Sequence[int]])r   rU   rF   zfrozenset[int])r   rU   r/   zSequence[int]rF   float)r   rU   r   rU   rF   z%Iterable[tuple[float, Sequence[int]]])__name__
__module____qualname____firstlineno____doc__r   r"   classmethodr   r)   r2   r   __static_attributes__r;   r   r   r   r      s{     &+
AI
"
;>
	
& tS  S69595%(95	.95r   r   c                      \ rS rSrSrSSS.       SS jjr\SS j5       r\SS j5       r\SS	 j5       r	SS
 jr
SS jrSrg)Matcher   zA fuzzy matcher.NF)match_styler   c               `    Xl         Uc	  [        SS9OUU l        X0l        [	        5       U l        g)zInitialise the fuzzy matching object.

Args:
    query: A query as typed in by the user.
    match_style: The style to use to highlight matched portions of a string.
    case_sensitive: Should matching be case sensitive?
NT)reverse)_queryr   _match_style_case_sensitiver   fuzzy_search)r   r   ra   r   s       r   r   Matcher.__init__   s-     3>3FE$/K-'Mr   c                    U R                   $ )zThe query string to look for.)rd   r   s    r   r   Matcher.query   s     {{r   c                    U R                   $ )zBThe style that will be used to highlight hits in the matched text.)re   rj   s    r   ra   Matcher.match_style   s        r   c                    U R                   $ )zIs this matcher case sensitive?)rf   rj   s    r   r   Matcher.case_sensitive   s     ###r   c                T    U R                   R                  U R                  U5      S   $ )zMatch the candidate against the query.

Args:
    candidate: Candidate string to match against the query.

Returns:
    Strength of the match from 0 to 1.
r   )rg   r"   r   )r   r   s     r   r"   Matcher.match   s&       &&tzz9=a@@r   c                   [         R                  " U5      nU R                  R                  U R                  U5      u  p4U(       d  U$ U H;  nX   R                  5       (       a  M  UR                  U R                  XUS-   5      nM=     U$ )zHighlight the candidate with the fuzzy match.

Args:
    candidate: The candidate string to match against the query.

Returns:
    A [`Text`][rich.text.Text] object with highlighted matches.
r,   )r
   from_markuprg   r"   r   isspacestylizere   )r   r   contentr2   r5   r6   s         r   	highlightMatcher.highlight   sw     %%i0**00YGNF$,,..!//$*;*;VaZP  r   )rf   re   rd   rg   )r   rU   ra   zStyle | Noner   rT   rF   rG   )rF   rU   )rF   r   )rF   rT   )r   rU   rF   rV   )r   rU   rF   r
   )rW   rX   rY   rZ   r[   r   propertyr   ra   r   r"   rw   r]   r;   r   r   r_   r_      s     %)$** "	*
 * 
*&   ! ! $ $	Ar   r_   __main__zfoo.barzfoo/egg.bar)r[   
__future__r   	functoolsr   operatorr   rer   typingr   r   	rich.reprrichtextual.cacher	   textual.contentr
   textual.visualr   r   reprautor_   rW   rg   r"   r;   r   r   <module>r      s    #    %  " #  A5 A5H @ @ @F z=Ly-0 r   