ó
    Ð]j]4  ã                  óô  • S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	J
r
  SSKJr  SSKJrJrJrJrJrJrJrJrJrJrJrJrJrJr  \(       a  SS	KJr  S
r " S S\5      r\" SS9SS j5       r \" SS9SS j5       r!\" SS9SS j5       r"\" SS9SS j5       r#\" SS9SS j5       r$ " S S\
5      r%\" SS9SS j5       r&            S S jr'  S!       S"S jjr(S#S jr)S$S jr*  S!       S"S jjr+g)%zú
Grapheme cluster segmentation following Unicode Standard Annex #29.

This module provides pure-Python implementation of the grapheme cluster boundary algorithm as
defined in UAX #29: Unicode Text Segmentation.

https://www.unicode.org/reports/tr29/
é    )Úannotations)ÚIntEnum)Ú	lru_cache)ÚTYPE_CHECKINGÚOptionalÚ
NamedTupleé   )Úbisearch)Ú
GRAPHEME_LÚ
GRAPHEME_TÚ
GRAPHEME_VÚGRAPHEME_LVÚINCB_EXTENDÚINCB_LINKERÚGRAPHEME_LVTÚINCB_CONSONANTÚGRAPHEME_EXTENDÚGRAPHEME_CONTROLÚGRAPHEME_PREPENDÚGRAPHEME_SPACINGMARKÚEXTENDED_PICTOGRAPHICÚGRAPHEME_REGIONAL_INDICATOR)ÚIteratoré    c                  óP   • \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rSrSrSrSrSrSrSrg)ÚGCBé,   z'Grapheme Cluster Break property values.r   r	   é   é   é   é   é   é   é   é	   é
   é   é   é   © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚOTHERÚCRÚLFÚCONTROLÚEXTENDÚZWJÚREGIONAL_INDICATORÚPREPENDÚSPACING_MARKÚLÚVÚTÚLVÚLVTÚ__static_attributes__r*   ó    ÚM/home/mande/repo/quber/.venv/lib/python3.13/site-packages/wcwidth/grapheme.pyr   r   ,   sL   † Ù1à€EØ	
€BØ	
€BØ€GØ€FØ
€CØÐØ€GØ€LØ	€AØ
€AØ
€AØ	€BØ
ƒCr?   r   i   )Úmaxsizec                óŠ  • U S:X  a  [         R                  $ U S:X  a  [         R                  $ U S:X  a  [         R                  $ [	        U [
        5      (       a  [         R                  $ [	        U [        5      (       a  [         R                  $ [	        U [        5      (       a  [         R                  $ [	        U [        5      (       a  [         R                  $ [	        U [        5      (       a  [         R                  $ [	        U [        5      (       a  [         R                   $ [	        U ["        5      (       a  [         R$                  $ [	        U [&        5      (       a  [         R(                  $ [	        U [*        5      (       a  [         R,                  $ [	        U [.        5      (       a  [         R0                  $ [         R2                  $ )z;Return the Grapheme_Cluster_Break property for a codepoint.r)   r&   i   )r   r1   r2   r5   Ú	_bisearchr   r3   r   r4   r   r6   r   r7   r   r8   r   r9   r   r:   r   r;   r   r<   r   r=   r0   ©Úucss    r@   Ú_grapheme_cluster_breakrF   B   s'  € ð
 ˆfƒ}Ü�v‰vˆØ
ˆfƒ}Ü�v‰vˆØ
ˆfƒ}Ü�w‰wˆä�Ô&×'Ñ'Ü�{‰{ÐÜ�”o×&Ñ&Ü�z‰zÐÜ�Ô1×2Ñ2Ü×%Ñ%Ð%Ü�Ô&×'Ñ'Ü�{‰{ÐÜ�Ô*×+Ñ+Ü×ÑÐÜ�”j×!Ñ!Ü�u‰uˆÜ�”j×!Ñ!Ü�u‰uˆÜ�”j×!Ñ!Ü�u‰uˆÜ�”k×"Ñ"Ü�v‰vˆÜ�”l×#Ñ#Ü�w‰wˆÜ�9‰9Ðr?   c                ó4   • [        [        U [        5      5      $ )z6Check if codepoint has Extended_Pictographic property.)ÚboolrC   r   rD   s    r@   Ú_is_extended_pictographicrI   e   s   € ô ”	˜#Ô4Ó5Ó6Ð6r?   c                ó4   • [        [        U [        5      5      $ )z,Check if codepoint has InCB=Linker property.)rH   rC   r   rD   s    r@   Ú_is_incb_linkerrK   k   ó   € ô ”	˜#œ{Ó+Ó,Ð,r?   c                ó4   • [        [        U [        5      5      $ )z/Check if codepoint has InCB=Consonant property.)rH   rC   r   rD   s    r@   Ú_is_incb_consonantrN   q   s   € ô ”	˜#œ~Ó.Ó/Ð/r?   c                ó4   • [        [        U [        5      5      $ )z,Check if codepoint has InCB=Extend property.)rH   rC   r   rD   s    r@   Ú_is_incb_extendrP   w   rL   r?   c                  ó.   • \ rS rSr% SrS\S'   S\S'   Srg)	ÚBreakResulté}   z*Result of grapheme cluster break decision.rH   Úshould_breakÚintÚri_countr*   N)r+   r,   r-   r.   r/   Ú__annotations__r>   r*   r?   r@   rR   rR   }   s   ‡ Ù4àÓØ†Mr?   rR   c                óø  • U [         R                  :X  a  U[         R                  :X  a
  [        SSS9$ U [         R                  [         R                  [         R                  4;   a
  [        SSS9$ U[         R                  [         R                  [         R                  4;   a
  [        SSS9$ U [         R
                  :X  aL  U[         R
                  [         R                  [         R                  [         R                  4;   a
  [        SSS9$ U [         R                  [         R                  4;   a.  U[         R                  [         R                  4;   a
  [        SSS9$ U [         R                  [         R                  4;   a  U[         R                  :X  a
  [        SSS9$ U[         R                  :X  a
  [        SSS9$ U[         R                  :X  a
  [        SSS9$ U [         R                  :X  a
  [        SSS9$ g)zÊ
Check simple GCB-pair-based break rules (cacheable).

Returns BreakResult for rules that can be determined from GCB properties alone, or None if
complex lookback rules (GB9c, GB11) need to be checked.
Fr   ©rT   rV   TN)r   r1   r2   rR   r3   r9   r:   r<   r=   r;   r4   r8   r7   )Úprev_gcbÚcurr_gcbs     r@   Ú_simple_break_checkr\   „   st  € ð ”3—6‘6Ó˜h¬#¯&©&Ó0Ü¨¸Ñ:Ð:ð ”C—K‘K¤§¡¬¯©Ð0Ó0Ü¨°qÑ9Ð9ð ”C—K‘K¤§¡¬¯©Ð0Ó0Ü¨°qÑ9Ð9ð ”3—5‘5Ó˜X¬#¯%©%´·±¼¿¹ÄÇÁÐ)HÓHÜ¨¸Ñ:Ð:ð ”C—F‘FœCŸE™E�?Ó" x´C·E±E¼3¿5¹5°>Ó'AÜ¨¸Ñ:Ð:ð ”C—G‘GœSŸU™UÐ#Ó#¨´C·E±EÓ(9Ü¨¸Ñ:Ð:ð ”3—:‘:ÓÜ¨¸Ñ:Ð:ð ”3×#Ñ#Ó#Ü¨¸Ñ:Ð:ð ”3—;‘;ÓÜ¨¸Ñ:Ð:ð r?   c                óZ  • [        X5      nUb  U$ U[        R                  :X  a
  [        SSS9$ [	        X#   5      n[        U5      (       as  SnUS-
  nUS:¼  af  [	        X(   5      n	[        U	5      (       a  SnUS-  nO9[        U	5      (       a  US-  nO#[        U	5      (       a  U(       a
  [        SSS9$ O	OUS:¼  a  Mf  U [        R                  :X  ap  [        U5      (       a`  US-
  nUS:¼  aU  [	        X(   5      n	[        U	5      n
U
[        R                  :X  a  US-  nO[        U	5      (       a
  [        SSS9$ OUS:¼  a  MU  U [        R                  :X  a4  U[        R                  :X  a   US-  S:X  a  [        SUS-   S9$ [        SSS9$ U[        R                  :X  a  SOSn[        SUS9$ )zƒ
Determine if there should be a grapheme cluster break between prev and curr.

Implements UAX #29 grapheme cluster boundary rules.
Fr   rY   r	   Tr   )r\   r   r5   rR   ÚordrN   rK   rP   rI   rF   r4   r6   )rZ   r[   ÚtextÚcurr_idxrV   ÚresultÚcurr_ucsÚ
has_linkerÚiÚprev_ucsÚ	prev_props              r@   Ú_should_breakrg   µ   s¥  € ô ! Ó4€FØÑØˆð ”3—7‘7ÓÜ¨¸Ñ:Ð:ô
 �4‘>Ó"€HÜ˜(×#Ñ#Øˆ
Ø�q‰LˆØ�1‹fÜ˜4™7“|ˆHÜ˜x×(Ñ(Ø!�
Ø�Q‘‘Ü  ×*Ñ*Ø�Q‘‘Ü# H×-Ñ-ÞÜ&°EÀAÑFÐFØàð �1�fð ”3—7‘7ÓÔ8¸×BÑBØ�q‰LˆØ�1‹fÜ˜4™7“|ˆHÜ/°Ó9ˆIØœCŸJ™JÓ&Ø�Q‘‘Ü*¨8×4Ñ4Ü"°ÀÑBÐBàð �1�fð ”3×)Ñ)Ó)¨h¼#×:PÑ:PÓ.PØ�a‰<˜1ÓÜ¨E¸HÀq¹LÑIÐIÜ¨°qÑ9Ð9ð ¤× 6Ñ 6Ó6‰q¸A€HÜ D°8Ñ<Ð<r?   Nc              #  ó”  #   • U (       d  g[        U 5      nUc  UnX:¼  d  X:¼  a  g[        X#5      nUnSn[        [        X   5      5      nU[        R
                  :X  a  Sn[        US-   U5       HM  n[        [        X   5      5      n[        XhXU5      n	U	R                  nU	R                  (       a  XU v •  UnUnMO     XU v •  g7f)a  
Iterate over grapheme clusters in a Unicode string.

Grapheme clusters are "user-perceived characters" - what a user would
consider a single character, which may consist of multiple Unicode
codepoints (e.g., a base character with combining marks, emoji sequences).

:param unistr: The Unicode string to segment.
:param start: Starting index (default 0).
:param end: Ending index (default len(unistr)).
:yields: Grapheme cluster substrings.

Example::

    >>> list(iter_graphemes('cafe\u0301'))
    ['c', 'a', 'f', 'e\u0301']
    >>> list(iter_graphemes('ok\U0001F468\u200D\U0001F469\u200D\U0001F467'))
    ['o', 'k', '\U0001F468\u200D\U0001F469\u200D\U0001F467']
    >>> list(iter_graphemes('ok\U0001F1FA\U0001F1F8'))
    ['o', 'k', '\U0001F1FA\U0001F1F8']

.. versionadded:: 0.3.0
Nr   r	   )
ÚlenÚminrF   r^   r   r6   Úrangerg   rV   rT   )
ÚunistrÚstartÚendÚlengthÚcluster_startrV   rZ   Úidxr[   ra   s
             r@   Úiter_graphemesrr   ø   sÒ   é € ö8 Øä�‹[€Fà
�{Øˆàƒ|�u“Øä
ˆcÓ
€Cð €MØ€Hô '¤s¨6©=Ó'9Ó:€Hð ”3×)Ñ)Ó)Øˆä�U˜Q‘Y Ö$ˆÜ*¬3¨v©{Ó+;Ó<ˆä˜x°6ÀÓIˆØ—?‘?ˆà××Ø sÐ+Ò+ØˆMàŠñ %ð ˜sÐ
#Ó#ùs   ‚CCc                óú  • [        XS-
     5      nUS:X  a  US:¼  a  XS-
     S:X  a  US-
  $ US:  aR  US:¼  aG  US:¼  aA  [        XS-
     5      nUS:¼  a+  [        U5      [        R                  :X  a  [	        XS-
  5      $ US-
  $ US-
  nUS:”  aa  X-
  [
        :  aU  [        X   5      nSUs=::  a  S:  a  O  OO7[        U5      [        R                  :X  a  OUS-  nUS:”  a  X-
  [
        :  a  MU  Un[        [        X   5      5      nU[        R                  :X  a  SOSn[        US-   U5       HG  n	[        [        X	   5      5      n
[        XzX	U5      nUR                  nUR                  (       a  U	nU
nMI     U$ )ac  
Find the start of the grapheme cluster containing the character before pos.

Scans backwards from pos to find a safe starting point, then iterates forward using standard
break rules to find the actual cluster boundary.

:param text: The Unicode string.
:param pos: Position to search before (exclusive).
:returns: Start position of the grapheme cluster.
r	   r&   r   Úé€   r   r   )r^   rF   r   r7   Ú_find_cluster_startÚMAX_GRAPHEME_SCANr3   r6   rk   rg   rV   rT   )r_   ÚposÚ	target_cpÚprev_cpÚ
safe_startÚcprp   Úleft_gcbrV   rd   Ú	right_gcbra   s               r@   rv   rv   <  s�  € ô �D˜q™‘MÓ"€Ið �DÓ˜S A›X¨$°Q©w©-¸4Ó*?Ø�Q‰wˆð �4Óà�!‹8˜	 TÓ)Ü˜$ Q™w™-Ó(ˆGØ˜$‹Ô#:¸7Ó#CÄsÇ{Á{Ó#RÜ*¨4°q±Ó9Ð9Ø�Q‰wˆð �q‘€JØ
�q‹.˜cÑ.Ô2CÓCÜ�Ñ!Ó"ˆØ�2Õ˜ÖØÜ" 2Ó&¬#¯+©+Ó5ØØ�a‰ˆ
ð �q‹.˜cÑ.Ô2CÕCð €MÜ&¤s¨4Ñ+;Ó'<Ó=€HØ¤× 6Ñ 6Ó6‰q¸A€Hä�: ‘> 3Ö'ˆÜ+¬C°±«LÓ9ˆ	Ü˜x°D¸XÓFˆØ—?‘?ˆØ××ØˆMØŠñ (ð Ðr?   c           	     óN   • US::  a  g[        U [        U[        U 5      5      5      $ )a   
Find the grapheme cluster boundary immediately before a position.

:param unistr: The Unicode string to search.
:param pos: Position in the string (0 < pos <= len(unistr)).
:returns: Start index of the grapheme cluster containing the character at pos-1.

Example::

    >>> grapheme_boundary_before('Hello \U0001F44B\U0001F3FB', 8)
    6
    >>> grapheme_boundary_before('a\r\nb', 3)
    1

.. versionadded:: 0.3.6
r   )rv   rj   ri   )rl   rx   s     r@   Úgrapheme_boundary_beforer€   p  s&   € ð" ˆaƒxØÜ˜v¤s¨3´°F³Ó'<Ó=Ð=r?   c              #  óÐ   #   • U (       d  g[        U 5      nUc  UO
[        X#5      n[        US5      nX:¼  d  X:¼  a  gUnXA:”  a!  [        X5      nXQ:  a  gXU v •  UnXA:”  a  M   gg7f)ay  
Iterate over grapheme clusters in reverse order (last to first).

:param unistr: The Unicode string to segment.
:param start: Starting index (default 0).
:param end: Ending index (default len(unistr)).
:yields: Grapheme cluster substrings in reverse order.

Example::

    >>> list(iter_graphemes_reverse('cafe\u0301'))
    ['e\u0301', 'f', 'a', 'c']

.. versionadded:: 0.3.6
Nr   )ri   rj   Úmaxrv   )rl   rm   rn   ro   rx   rp   s         r@   Úiter_graphemes_reverserƒ   †  sq   é € ö( Øä�‹[€Fà‘K‰&¤S¨Ó%5€CÜ��q‹M€Eàƒ|�u“Øà
€CØ
‹+Ü+¨FÓ8ˆàÓ ØØ 3Ð'Ò'Øˆð �+ùs   ‚A A&Á$A&)rE   rU   Úreturnr   )rE   rU   r„   rH   )rZ   r   r[   r   r„   zOptional[BreakResult])rZ   r   r[   r   r_   Ústrr`   rU   rV   rU   r„   rR   )r   N)rl   r…   rm   rU   rn   zOptional[int]r„   zIterator[str])r_   r…   rx   rU   r„   rU   )rl   r…   rx   rU   r„   rU   ),r/   Ú
__future__r   Úenumr   Ú	functoolsr   Útypingr   r   r   r
   rC   Útable_graphemer   r   r   r   r   r   r   r   r   r   r   r   r   r   Úcollections.abcr   rw   r   rF   rI   rK   rN   rP   rR   r\   rg   rr   rv   r€   rƒ   r*   r?   r@   Ú<module>rŒ      s®  ðñõ #õ Ý ç 6Ñ 6õ ,÷:÷ :÷ :÷ :ö å(ð Ð ôˆ'ô ñ, �4Ñóó ðñD �4Ñó7ó ð7ñ
 �4Ñó-ó ð-ñ
 �4Ñó0ó ð0ñ
 �4Ñó-ó ð-ô
�*ô ñ �4Ñó-ó ð-ð`@=Øð@=àð@=ð ð@=ð ð	@=ð
 ð@=ð ô@=ðJ ØðA$ØðA$àðA$ð 
ðA$ð õ	A$ôH1ôh>ð0 Øð&Øð&àð&ð 
ð&ð ö	&r?   