§
    „Øjèi  ã            	      óž  — d Z ddlmZ ddlmZmZ ddlZddlZddl	Z	ddl
mZ ddlmZ ej        rddlmZ dZd	                     ¦   «         Z G d
„ d edg d¢¦  «        ¦  «        Z G d„ d edg d¢¦  «        ¦  «        Z G d„ de¦  «        Z G d„ d¦  «        Z G d„ de	j        ¦  «        ZegZedk    rddlZ ej        e¦  «         dS dS )z*
Classes for searching for Lyric objects.
é    )Úannotations)Ú
namedtupleÚOrderedDictN)ÚMusic21Exception)Únote)Ú
StreamTypez // zDel start end measure lyric text identifier absoluteStart absoluteEndc            
      óF   — e Zd ZU dZdZddddddd	d
ddœ	Zded<   d„ Zd„ ZdS )ÚIndexedLyriczZ
    A Lyric that has been indexed to its attached element and position in a Stream.

    © z)the element that the lyric is attached toz¯Suppose that the entire lyric for the stream were a single string:
                 this is the index of the position in the string that this
                 lyric starts at.z­Suppose that the entire lyric for the stream were a single string:
                 this is the index of the position in the string that this
                 lyric ends at.zrThe measureNumber of the measure that the element is in
                 in the stream.  Same as .el.measureNumberz.The :class:`~music21.note.Lyric` object itselfz"The text of the lyric as a string.zThe identifier of the lyriczBthe position, not in the current identifier, but in all the lyricsz"the end position in all the lyrics©	ÚelÚstartÚendÚmeasureÚlyricÚtextÚ
identifierÚabsoluteStartÚabsoluteEndúdict[str, str]Ú	_DOC_ATTRc                óx   — d| j         ›d| j        ›d| j        ›d| j        ›d| j        ›d| j        ›d| j        ›d�S )	NzIndexedLyric(el=z, start=z, end=z
, measure=z, lyric=z, text=z, identifier=ú))r   r   r   r   r   r   r   ©Úselfs    úŠ/Users/tedpeters/Documents/Projects/Claude Projects/Misc Tools/notename-sheets/.venv/lib/python3.11/site-packages/music21/search/lyrics.pyÚ__repr__zIndexedLyric.__repr__:   sw   € ð3 4¤7ð 3ð 3°d´jð 3ð 3È$Ì(ð 3ð 3Øœ<ð3ð 3Ø37´:ð3ð 3ØHLÌ	ð3ð 3à"œoð3ð 3ð 3ð 	4ó    c                óB   ‡ ‡— ˆˆ fd„t           D ¦   «         } ‰ j        |Ž S )z;
        see docs for SortTuple for what this does
        c           	     óX   •— g | ]&}‰                      |t          ‰|¦  «        ¦  «        ‘Œ'S r   )ÚgetÚgetattr)Ú.0ÚattrÚkeywordsr   s     €€r   ú
<listcomp>z'IndexedLyric.modify.<locals>.<listcomp>C   s1   ø€ ÐQÐQÐQ¸t�8—<’< ¥g¨d°DÑ&9Ô&9Ñ:Ô:ÐQÐQÐQr   )Ú	_attrListÚ	__class__)r   r%   ÚoutLists   `` r   ÚmodifyzIndexedLyric.modify?   s2   øø€ ð RÐQÐQÐQÐQÅyÐQÑQÔQˆØˆtŒ~˜wÐ'Ð'r   N)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   Ú__annotations__r   r*   r   r   r   r
   r
      s†   € € € € € € ð
ð ð €Ià9ð%ð#ð>àEØ8Ø7ØaØ?ð!ð !€Ið ð ð ñ ð"4ð 4ð 4ð
(ð (ð (ð (ð (r   r
   r   c                  ó:   — e Zd ZU dZdZddddddd	œZd
ed<   d„ ZdS )ÚSearchMatchzL
    A lightweight object representing the match (if any) for a search.
    r   z_
            The measureNumber of the measure that the first matching lyric is in.
            z^
            The measureNumber of the measure that the last matching lyric is in.
            a  
            The text of the lyric that matched the search.  For a
            plaintext search, this will be the same as the search
            term, but for a regular expression
            search this will be the text that matched the regular
            expression.
            zY
            A list of all lyric-containing elements that matched this text.
            zD
            A list of IndexedLyric objects that match.
            zd
            The identifier of (presumably all, but at least the first) lyric to match.
            ©ÚmStartÚmEndÚ	matchTextÚelsÚindicesr   r   r   c                óX   — d| j         ›d| j        ›d| j        ›d| j        ›d| j        ›d�S )NzSearchMatch(mStart=z, mEnd=z, matchText=z, els=z, indices=[...], identifier=r   )r4   r5   r6   r7   r   r   s    r   r   zSearchMatch.__repr__g   sZ   € ð3 d¤kð 3ð 3¸D¼Ið 3ð 3Ø!œ^ð3ð 3Ø59´Xð3ð 3à"œoð3ð 3ð 3ð 	4r   N)r+   r,   r-   r.   r/   r   r0   r   r   r   r   r2   r2   H   st   € € € € € € ðð ð €Iððððððð)!ð !€Ið ð ð ñ ð24ð 4ð 4ð 4ð 4r   r2   r3   c                  ó   — e Zd ZdS )ÚLyricSearcherExceptionN)r+   r,   r-   r   r   r   r;   r;   m   s   € € € € € Ø€Dr   r;   c                  ó€   — e Zd ZdZdddœdd	„Zedd„¦   «         Zedd„¦   «         Zddd„Zddd„Z	dd„Z
ddd„Zdd„ZdS ) ÚLyricSearchera°  
    An object that can find lyrics that match a certain regular expression
    and return relevant information about the match.

    Construct the LyricSearcher by passing in a Stream object (it can be
    a Score or Part or other nested item), and then call ".search()" on it.

    See :ref:`User's Guide, Chapter 28, Lyric Searching <usersGuide_28_lyricSearcher>` for
    full details.

    TODO: Bug that occasionally the previous note will be included; Search luca/gloria for
       "riam tuam." (From Gloriam tuam).  For some reason, the whole "Gloria" is included.
       Does not occur if only "iam tuam." is searched.

    TODO: allow for all intermediate notes during a search to be found.
        includeIntermediateElements.

    TODO: allow for trailing melismas to also be included.

    TODO: Note that because of recursive searching w/ voices, there may be "phantom" lyrics
        found if a work contains multiple voices.
    Nú ©ÚwordSeparatorÚsúStreamType | Noner@   Ústrc               óZ   — || _         d| _        d| _        d | _        g | _        || _        d S )NF)ÚstreamÚincludeIntermediateElementsÚincludeTrailingMelismaÚ
_indexTextÚ_indexTuplesr@   )r   rA   r@   s      r   Ú__init__zLyricSearcher.__init__Š   s6   € Ø'(ˆŒØ+0ˆÔ(Ø&+ˆÔ#à$(ˆŒØ02ˆÔØ*ˆÔÐÐr   Úreturnc                óJ   — | j         €|                      ¦   «          | j         pdS )a  
        Returns the text that has been indexed (a la, :func:`~music21.text.assembleLyrics`):

        >>> p0 = corpus.parse('luca/gloria').parts[0]
        >>> ls = search.lyrics.LyricSearcher(p0)
        >>> ls.indexText[0:25]
        'Et in terra pax hominibus'
        NÚ )rH   Úindexr   s    r   Ú	indexTextzLyricSearcher.indexText“   s&   € ð Œ?Ð"Ø�JŠJ‰LŒLˆLØŒÐ$ "Ð$r   úlist[IndexedLyric]c                óF   — | j         €|                      ¦   «          | j        S ©N)rH   rN   rI   r   s    r   ÚindexTupleszLyricSearcher.indexTuples¡   s    € àŒ?Ð"Ø�JŠJ‰LŒLˆLØÔ Ð r   c                óª  — |€| j         }n|| _         t          ¦   «         }t          ¦   «         }t          ¦   «         }|                     ¦   «         j        D �]}|j        }|sŒ|j        }|D ]ü}|j        sŒ
|j        }	|	|vrd||	<   d||	<   g ||	<   ||	         }
||	         }||	         }t          |
¦  «        }|j        }|dv r|
|z  }
n$|
| j	        |z   z  }
|t          | j	        ¦  «        z  }|
||	<   t          |||t          |¦  «        z   ||||	dd¦	  «	        }|                     |¦  «         |j        s|j        }n't          j        r	|j        €J ‚|j        d         j        }|||	<   Œý�Œg }|                     ¦   «         D ]}|                     |¦  «         Œd}d}d}g }|D ]v}|j        |k    r|}|dk    r|t          t&          ¦  «        z  }|j        }|                     |j        |z   |j        |z   ¬¦  «        }|j        }|                     |¦  «         Œw|| _        t&                               |                     ¦   «         ¦  «        }
|
| _        |S )až  
        A method that indexes the Stream's lyrics and returns the list
        of IndexedLyric objects.

        This does not actually need to be run, since calling .search() will call this if
        it hasn't already been called.

        >>> from pprint import pprint as pp

        >>> p0 = corpus.parse('luca/gloria').parts[0]
        >>> ls = search.lyrics.LyricSearcher(p0)
        >>> pp(ls.index()[0:5])
        [IndexedLyric(el=<music21.note.Note C>, start=0, end=2, measure=1,
             lyric=<music21.note.Lyric number=1 syllabic=single text='Et'>, text='Et',
             identifier=1),
         IndexedLyric(el=<music21.note.Note D>, start=3, end=5, measure=2,
             lyric=<music21.note.Lyric number=1 syllabic=single text='in'>, text='in',
             identifier=1),
         IndexedLyric(el=<music21.note.Note F>, start=6, end=9, measure=2,
             lyric=<music21.note.Lyric number=1 syllabic=begin text='ter'>, text='ter',
             identifier=1),
         IndexedLyric(el=<music21.note.Note F>, start=9, end=11, measure=3,
             lyric=<music21.note.Lyric number=1 syllabic=end text='ra'>, text='ra',
             identifier=1),
         IndexedLyric(el=<music21.note.Note A>, start=12, end=15, measure=3,
             lyric=<music21.note.Lyric number=1 syllabic=single text='pax'>, text='pax',
             identifier=1)]

        * Changed in v6.7: indexed lyrics get an identifier.
        NrM   )ÚbeginÚmiddleNr   éÿÿÿÿ)r   r   )rE   r   ÚrecurseÚnotesÚlyricsÚmeasureNumberr   r   Úlenr@   r
   ÚappendÚisCompositeÚsyllabicÚtÚTYPE_CHECKINGÚ
componentsÚvaluesÚextendÚLINEBREAK_TOKENr*   r   r   r   rI   ÚjoinrH   )r   rA   ÚindexByIdentifierÚiTextByIdentifierÚlastSyllabicByIdentifierÚnÚlsÚmNumÚlyÚlyIdentifierÚiTextÚlastSyllabicrN   ÚposStartÚtxtÚilÚindexPreliminaryÚoneIdentifierIndexÚabsolutePosShiftÚlastIdentifierÚlastEndÚoneIndexÚnewIndexs                          r   rN   zLyricSearcher.index§   sâ  € ð@ ˆ9Ø”ˆAˆAàˆDŒKåFQÁmÄmÐÝ7B±}´}Ðå<G¹M¼Mð 	!ð —’‘”Ô"ð $	Fñ $	FˆAØ#$¤8ˆBØð ØØ”?ˆDØð Fð F�Ø”wð ØØ!œ}�ØÐ'8Ð8Ð8Ø68Ð% lÑ3Ø=AÐ,¨\Ñ:Ø68Ð% lÑ3à)¨,Ô7�Ø7¸ÔE�Ø)¨,Ô7�å˜u™:œ:�Ø”g�ØÐ#<Ð<Ð<Ø˜S‘L�E�Eà˜TÔ/°#Ñ5Ñ5�EØ¥ DÔ$6Ñ 7Ô 7Ñ7�Hà27Ð! ,Ñ/Ý! ! X¨x½#¸c¹(¼(Ñ/BÀDÈ"ÈcØ".°°1ñ6ô 6�à—’˜RÑ Ô Ð Ø”~ð >Ø#%¤;�L�Lå”ð 9Ø!œ}Ð8Ð8Ð8Ø#%¤=°Ô#4Ô#=�LØ9EÐ(¨Ñ6Ð6ñ?FðB ÐØ"3×":Ò":Ñ"<Ô"<ð 	8ð 	8ÐØ×#Ò#Ð$6Ñ7Ô7Ð7Ð7àÐØˆØˆØˆà(ð 		#ð 		#ˆHØÔ" nÒ4Ð4Ø#*Ð Ø˜a’<�<Ø$­­OÑ(<Ô(<Ñ<Ð$Ø%Ô0ˆNØ—’°X´^ÐFVÑ5VØ3;´<ÐBRÑ3Rð 'ñ Tô TˆHàÔ*ˆGØ�LŠL˜Ñ"Ô"Ð"Ð"à!ˆÔÝ×$Ò$Ð%6×%=Ò%=Ñ%?Ô%?Ñ@Ô@ˆØˆŒØˆr   úlist[SearchMatch]c                ó|  — |€| j         }|| j         us| j        s|                      |¦  «         t          |t          ¦  «        rd}n%t          |d¦  «        rd}nt          |› d�¦  «        ‚|du r9|                      t          j	        t          j
        |¦  «        ¦  «        ¦  «        S |                      |¦  «        S )a¿  
        Return a list of SearchMatch objects matching a string or regular expression.

        >>> import re

        >>> p0 = corpus.parse('luca/gloria').parts[0]
        >>> ls = search.lyrics.LyricSearcher(p0)
        >>> ls.search('pax')
        [SearchMatch(mStart=3, mEnd=3, matchText='pax', els=(<music21.note.Note A>,),
                        indices=[...], identifier=1)]

        Search a regular expression that takes into account non-word characters such as commas

        >>> agnus = re.compile(r'agnus dei\W+filius patris', re.IGNORECASE)
        >>> sm = ls.search(agnus)
        >>> sm
        [SearchMatch(mStart=49, mEnd=55, matchText='Agnus Dei, Filius Patris',
                        els=(<music21.note.Note G>,...<music21.note.Note G>), indices=[...],
                        identifier=1)]
        >>> sm[0].mStart, sm[0].mEnd
        (49, 55)

        OMIT_FROM_DOCS

        Make sure that regexp characters are not interpreted as such in plaintext:

        This should only match Amen.

        >>> ls.search('en.')
        [SearchMatch(mStart=125, mEnd=125, matchText='en.', ...)]

        This should match 'ene', 'eni', and 'en.'

        >>> ls.search(re.compile('en.'))
        [SearchMatch(mStart=13, mEnd=13, matchText='ene', ...),
         SearchMatch(mStart=38, mEnd=38, matchText='ens', ...),
         SearchMatch(mStart=42, mEnd=42, matchText='eni', ...),
         SearchMatch(mStart=125, mEnd=125, matchText='en.', ...)]
        NTÚfinditerFz3 is not a string or RE with the finditer() function)rE   rI   rN   Ú
isinstancerC   Úhasattrr;   Ú	_reSearchÚreÚcompileÚescape)r   ÚtextOrRerA   Ú	plainTexts       r   ÚsearchzLyricSearcher.search  sÏ   € ðR ˆ9Ø”ˆAà�D”KÐÐ tÔ'8ÐØ�JŠJ�q‰MŒMˆMå�h¥Ñ$Ô$ð 	RØˆIˆIÝ�X˜zÑ*Ô*ð 	RØˆIˆIå(ØÐPÐPÐPñRô Rð Rð ˜ÐÐØ—>’>¥"¤*­R¬Y°xÑ-@Ô-@Ñ"AÔ"AÑBÔBÐBà—>’> (Ñ+Ô+Ð+r   r
   c                óx   — | j         D ] }|j        |cxk    r|j        k    rn Œ|c S Œ!t          d|› d�¦  «        ‚)zù
        Finds an object in ._indexTuples by search position.

        Raises exception if no IndexedLyric for that position.

        Runs in O(n) time on number of lyrics. Would not be
        hard to do in O(log(n)) for very large lyrics
        úCould not find position ú in text)rI   r   r   r;   )r   ÚposÚis      r   Ú_findObjInIndexByPosz"LyricSearcher._findObjInIndexByPosL  sf   € ð Ô"ð 	ð 	ˆAØŒw˜#Ð&Ð&Ò&Ð& ¤Ò&Ð&Ð&Ð&Ð&Ø���ð 'õ %Ð%MÀÐ%MÐ%MÐ%MÑNÔNÐNr   é?B c                óž   — g }| j         D ]-}|j        |k    r |j        |k    r|                     |¦  «         Œ.|st	          d|› d�¦  «        ‚|S )zY
        Finds a list of objects in ._indexTuples by search position (inclusive)
        rˆ   r‰   )rI   r   r   r]   r;   )r   rq   ÚposEndr8   r‹   s        r   Ú_findObjsInIndexByPosz#LyricSearcher._findObjsInIndexByPos[  so   € ð ˆØÔ"ð 	"ð 	"ˆAØŒ}˜xÒ'Ð'¨A¬O¸vÒ,EÐ,EØ—’˜qÑ!Ô!Ð!øØð 	XÝ(Ð)VÀHÐ)VÐ)VÐ)VÑWÔWÐWØˆr   Úrú
re.Patternc           
     ó¬  — g }| j         €|S |                     | j         ¦  «        D ]­}|                     ¦   «         \  }}|                     d¦  «        }|                      ||dz
  ¦  «        }|d         }|d         }	t          |j        |	j        |t          d„ |D ¦   «         ¦  «        ||d         j        ¬¦  «        }
| 	                    |
¦  «         Œ®|S )Nr   é   rW   c              3  ó$   K  — | ]}|j         V — Œd S rR   )r   )r#   Ú	thisIndexs     r   ú	<genexpr>z*LyricSearcher._reSearch.<locals>.<genexpr>Š  s$   è è € Ð&MÐ&M¸	 y¤|Ð&MÐ&MÐ&MÐ&MÐ&MÐ&Mr   r3   )
rH   r}   ÚspanÚgroupr�   r2   r   Útupler   r]   )r   r‘   Ú	locationsÚmÚabsoluteFoundPosÚabsoluteEndPosr6   r8   Ú
indexStartÚindexEndÚsms              r   r€   zLyricSearcher._reSearch{  sê   € Ø')ˆ	ØŒ?Ð"ØÐØ—’˜DœOÑ,Ô,ð 	!ð 	!ˆAØ/0¯vªv©x¬xÑ,Ð˜nØŸš ™
œ
ˆIà×0Ò0Ð1AÀ>ÐTUÑCUÑVÔVˆGØ  œˆJØ˜r”{ˆHå JÔ$6Ø"*Ô"2Ø'0Ý!&Ð&MÐ&MÀWÐ&MÑ&MÔ&MÑ!MÔ!MØ%,Ø(/°¬
Ô(=ðñ ô ˆBð ×Ò˜RÑ Ô Ð Ð ØÐr   rR   )rA   rB   r@   rC   )rK   rC   )rK   rP   )rK   r{   )rK   r
   )r�   )r‘   r’   rK   r{   )r+   r,   r-   r.   rJ   ÚpropertyrO   rS   rN   r†   rŒ   r�   r€   r   r   r   r=   r=   q   s  € € € € € ðð ð.+È#ð +ð +ð +ð +ð +ð +ð ð%ð %ð %ñ „Xð%ð ð!ð !ð !ñ „Xð!ð
gð gð gð gð gðR:,ð :,ð :,ð :,ð :,ðxOð Oð Oð Oð
ð 
ð 
ð 
ð 
ð@ð ð ð ð ð r   r=   c                  ó"   — e Zd Z	 d„ Zd„ Zd„ ZdS )ÚTestc                ó„  ‡ ‡‡— ddl m} ddl mŠ d}|                     |d¬¦  «        Š‰                     ¦   «         j        d         j        d         }ˆˆˆ fd„} |¦   «          d|j        d         _        d	|j        d
         _         |¦   «          d|j        d         _        d|j        d
         _         |¦   «          dS )zD
        This score uses a non-breaking space as an elision
        r   ©Ú	converter©r†   uñ  
        <score-partwise>
            <part-list>
                <score-part id="P1">
                <part-name>MusicXML Part</part-name>
                </score-part>
            </part-list>
            <part id="P1">
                <measure number="1">
                    <note>
                        <pitch>
                            <step>G</step>
                            <octave>4</octave>
                        </pitch>
                        <duration>1</duration>
                        <voice>1</voice>
                        <type>quarter</type>
                        <lyric number="1">
                            <syllabic>middle</syllabic>
                            <text>la</text>
                            <elision>Â </elision>
                            <syllabic>middle</syllabic>
                            <text>la</text>
                        </lyric>
                    </note>
                </measure>
            </part>
        </score-partwise>
        ÚMusicXML©Úformatc                 ór   •— ‰j                              ‰¦  «        } ‰                     | j        d¦  «         d S )Nu   laÂ la)rZ   r=   ÚassertEqualrO   )rk   rA   r†   r   s    €€€r   Ú	runSearchz0Test.testMultipleLyricsInNote.<locals>.runSearch¿  s6   ø€ Ø”×,Ò,¨QÑ/Ô/ˆBà×Ò˜Rœ\¨8Ñ4Ô4Ð4Ð4Ð4r   rU   r   r”   ÚsingleN)	Úmusic21r§   r†   ÚparseÚflattenrY   rZ   rb   r_   )r   r§   ÚpartXMLrm   r®   rA   r†   s   `    @@r   ÚtestMultipleLyricsInNotezTest.testMultipleLyricsInNote˜  sì   øøø€ ð 	&Ð%Ð%Ð%Ð%Ð%Ø"Ð"Ð"Ð"Ð"Ð"ðˆð: �OŠO˜G¨JˆOÑ7Ô7ˆØ�YŠY‰[Œ[Ô˜qÔ!Ô(¨Ô+ˆð	5ð 	5ð 	5ð 	5ð 	5ð 	5ð 	5ð
 	ˆ	‰ŒˆØ$+ˆŒ�aÔÔ!Ø$)ˆŒ�aÔÔ!Øˆ	‰ŒˆØ$,ˆŒ�aÔÔ!Ø$,ˆŒ�aÔÔ!Øˆ	‰Œˆˆˆr   c                ó
  — ddl m} ddl m} d}|                     |d¬¦  «        }|j                             |¦  «        }|                      |j        d¦  «         |j        }|                      t          |¦  «        d¦  «         t          |                     ¦   «         j        ¦  «        }|                      |d         j        |d         j        d         ¦  «         |                      |d	         j        |d	         j        d         ¦  «         |                      |d
         j        |d         j        d	         ¦  «         |                      |d         j        |d	         j        d	         ¦  «         |                      |d         j        |d
         j        d         ¦  «         |                     d¦  «        }|                      t          |¦  «        d	¦  «         |d         }	|                      |	j        d
¦  «         |                      |	j        d
¦  «         |                      |	j        |d	         |d
         f¦  «         |                      |	j        d
¦  «         |                      t          |	j        ¦  «        d
¦  «         |                      |	j        d         j        |d	         j        d	         ¦  «         |                      |	j        d	         j        |d
         j        d         ¦  «         t)          j        d¦  «        }
|                     |
¦  «        }|                      t          |¦  «        d
¦  «         |d         }	|                      |	j        d
¦  «         |                      |	j        d
¦  «         |                      |	j        d¦  «         |                      |	j        d	¦  «         |                      |	j        |d	         f¦  «         |d	         }|                      |j        d
¦  «         |                      |j        d
¦  «         |                      |j        d¦  «         |                      |j        d
¦  «         |                      |j        |d
         f¦  «         |                     d¦  «        }|                      t          |¦  «        d	¦  «         |                      |d         j        d	¦  «         |                      |d         j        d
¦  «         |                      |d         j        d	¦  «         d S )Nr   r¦   r¨   a
	  
        <score-partwise>
            <part-list>
                <score-part id="P1">
                <part-name>MusicXML Part</part-name>
                </score-part>
            </part-list>
            <part id="P1">
                <measure number="1">
                    <note>
                        <pitch>
                            <step>G</step>
                            <octave>4</octave>
                        </pitch>
                        <duration>2</duration>
                        <voice>1</voice>
                        <type>half</type>
                        <lyric number="1">
                            <syllabic>single</syllabic>
                            <text>hi</text>
                        </lyric>
                        <lyric number="2">
                            <syllabic>single</syllabic>
                            <text>bye</text>
                        </lyric>
                    </note>
                </measure>
                <measure number="2">
                    <note>
                        <pitch>
                            <step>A</step>
                            <octave>4</octave>
                        </pitch>
                        <duration>1</duration>
                        <voice>1</voice>
                        <type>quarter</type>
                        <lyric number="1">
                            <syllabic>begin</syllabic>
                            <text>there!</text>
                        </lyric>
                        <lyric number="2">
                            <syllabic>begin</syllabic>
                            <text>Mi</text>
                        </lyric>
                    </note>
                    <note>
                        <pitch>
                            <step>B</step>
                            <octave>4</octave>
                        </pitch>
                        <duration>1</duration>
                        <voice>1</voice>
                        <type>quarter</type>
                        <lyric number="2">
                            <syllabic>end</syllabic>
                            <text>chael.</text>
                        </lyric>
                    </note>
                </measure>
            </part>
        </score-partwise>
        r©   rª   zhi there! // bye Michael.é   r”   é   é   é   ÚMichaelze[a-z]Úerr   zi t)r°   r§   r†   r±   rZ   r=   r­   rO   rS   r\   Úlistr²   rY   ÚassertIsr   r4   r5   r7   r   r8   r�   r‚   r6   )r   r§   r†   r³   rA   rk   ÚtuplesrY   ÚmatchÚm0Úe_with_letterÚm1s               r   ÚtestMultipleVerseszTest.testMultipleVersesÌ  sJ  € Ø%Ð%Ð%Ð%Ð%Ð%Ø"Ð"Ð"Ð"Ð"Ð"ð=ˆð| �OŠO˜G¨JˆOÑ7Ô7ˆØŒ]×(Ò(¨Ñ+Ô+ˆØ×Ò˜œÐ'BÑCÔCÐCØ”ˆØ×Ò�˜V™œ aÑ(Ô(Ð(Ý�Q—Y’Y‘[”[Ô&Ñ'Ô'ˆØ�Š�f˜Q”i”o u¨Q¤x¤°qÔ'9Ñ:Ô:Ð:Ø�Š�f˜Q”i”o u¨Q¤x¤°qÔ'9Ñ:Ô:Ð:Ø�Š�f˜Q”i”o u¨Q¤x¤°qÔ'9Ñ:Ô:Ð:Ø�Š�f˜Q”i”o u¨Q¤x¤°qÔ'9Ñ:Ô:Ð:Ø�Š�f˜Q”i”o u¨Q¤x¤°qÔ'9Ñ:Ô:Ð:à—	’	˜)Ñ$Ô$ˆØ×Ò�˜U™œ QÑ'Ô'Ð'Ø�1ŒXˆØ×Ò˜œ AÑ&Ô&Ð&Ø×Ò˜œ !Ñ$Ô$Ð$Ø×Ò˜œ %¨¤(¨E°!¬HÐ!5Ñ6Ô6Ð6Ø×Ò˜œ¨Ñ*Ô*Ð*Ø×Ò�˜RœZ™œ¨!Ñ,Ô,Ð,Ø�Š�b”j ”mÔ)¨5°¬8¬?¸1Ô+=Ñ>Ô>Ð>Ø�Š�b”j ”mÔ)¨5°¬8¬?¸1Ô+=Ñ>Ô>Ð>åœ
 9Ñ-Ô-ˆØ—	’	˜-Ñ(Ô(ˆØ×Ò�˜U™œ QÑ'Ô'Ð'Ø�1ŒXˆØ×Ò˜œ AÑ&Ô&Ð&Ø×Ò˜œ !Ñ$Ô$Ð$Ø×Ò˜œ tÑ,Ô,Ð,Ø×Ò˜œ¨Ñ*Ô*Ð*Ø×Ò˜œ %¨¤( Ñ-Ô-Ð-Ø�1ŒXˆØ×Ò˜œ AÑ&Ô&Ð&Ø×Ò˜œ !Ñ$Ô$Ð$Ø×Ò˜œ tÑ,Ô,Ð,Ø×Ò˜œ¨Ñ*Ô*Ð*Ø×Ò˜œ %¨¤( Ñ-Ô-Ð-à—	’	˜%Ñ Ô ˆØ×Ò�˜U™œ QÑ'Ô'Ð'Ø×Ò˜˜qœœ¨!Ñ,Ô,Ð,Ø×Ò˜˜qœœ¨Ñ*Ô*Ð*Ø×Ò˜˜qœÔ,¨aÑ0Ô0Ð0Ð0Ð0r   c                ó®  — ddl m} ddl m} dd l}d}|                     |d¬¦  «        }t          d¦  «        D �]}d|z  }|j                             ||¬	¦  «        }|                     d
¦  «        D ]à}	|	d         |z   |	d         z   }
|                     |
¦  «        }|  	                    t          |¦  «        d¦  «         |  	                    t          |d         j        ¦  «        d¦  «         |  	                    |d         j        d         j        |	d         ¦  «         |  	                    |d         j        d         j        |	d         ¦  «         Œá�Œd S )Nr   r¦   r¨   uq  <score-partwise version="4.0">
  <identification>
    <encoding>
      <software>MuseScore 4.5.2</software>
      <encoding-date>2025-06-22</encoding-date>
      <supports element="accidental" type="yes"/>
      <supports element="beam" type="yes"/>
      <supports element="print" attribute="new-page" type="no"/>
      <supports element="print" attribute="new-system" type="no"/>
      <supports element="stem" type="yes"/>
      </encoding>
    </identification>
  <part-list>
    <score-part id="P1">
      <part-name>é’¢ç�´, Track1</part-name>
      <part-abbreviation>Pno.</part-abbreviation>
      <score-instrument id="P1-I1">
        <instrument-name>é’¢ç�´</instrument-name>
        <instrument-sound>keyboard.piano</instrument-sound>
        </score-instrument>
      <midi-device id="P1-I1" port="1"></midi-device>
      <midi-instrument id="P1-I1">
        <midi-channel>1</midi-channel>
        <midi-program>1</midi-program>
        <volume>78.7402</volume>
        <pan>0</pan>
        </midi-instrument>
      </score-part>
    </part-list>
  <part id="P1">
    <measure number="1">
      <attributes>
        <divisions>2</divisions>
        <key>
          <fifths>0</fifths>
          </key>
        <time>
          <beats>4</beats>
          <beat-type>4</beat-type>
          </time>
        <clef>
          <sign>F</sign>
          <line>4</line>
          </clef>
        </attributes>
      <note dynamics="50">
        <pitch>
          <step>G</step>
          <octave>3</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>down</stem>
        <lyric number="1">
          <syllabic>single</syllabic>
          <text>é•¿</text>
          </lyric>
        </note>
      <note dynamics="50">
        <pitch>
          <step>E</step>
          <octave>3</octave>
          </pitch>
        <duration>1</duration>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <beam number="1">begin</beam>
        <notations>
          <slur type="start" number="1"/>
          </notations>
        <lyric number="1">
          <syllabic>single</syllabic>
          <text>äº­</text>
          </lyric>
        </note>
      <note dynamics="50">
        <pitch>
          <step>G</step>
          <octave>3</octave>
          </pitch>
        <duration>1</duration>
        <voice>1</voice>
        <type>eighth</type>
        <stem>down</stem>
        <beam number="1">end</beam>
        <notations>
          <slur type="stop" number="1"/>
          </notations>
        </note>
      <note dynamics="50">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>down</stem>
        <lyric number="1">
          <syllabic>single</syllabic>
          <text>å¤–</text>
          </lyric>
        </note>
      <note>
        <rest/>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        </note>
      </measure>
    <measure number="2">
      <note dynamics="50">
        <pitch>
          <step>A</step>
          <octave>3</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>down</stem>
        <lyric number="1">
          <syllabic>single</syllabic>
          <text>å�¤</text>
          </lyric>
        </note>
      <note dynamics="50">
        <pitch>
          <step>C</step>
          <octave>4</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>down</stem>
        <lyric number="1">
          <syllabic>single</syllabic>
          <text>é�“</text>
          </lyric>
        </note>
      <note dynamics="50">
        <pitch>
          <step>G</step>
          <octave>3</octave>
          </pitch>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        <stem>down</stem>
        <lyric number="1">
          <syllabic>single</syllabic>
          <text>è¾¹</text>
          </lyric>
        </note>
      <note>
        <rest/>
        <duration>2</duration>
        <voice>1</voice>
        <type>quarter</type>
        </note>
      <barline location="right">
        <bar-style>light-heavy</bar-style>
        </barline>
      </measure>
    </part>
  </score-partwise>r©   rª   r¶   r>   r?   u   é•¿äº­å¤–å�¤é�“è¾¹r”   r·   )r°   r§   r†   Úmore_itertoolsr±   ÚrangerZ   r=   Úpairwiser­   r\   r7   r   )r   r§   r†   rÅ   r³   rA   Ú
lenWordSepÚwordSeprk   ÚpairÚkeywordr¿   s               r   ÚtestCustomSeparatorzTest.testCustomSeparator<  sx  € Ø%Ð%Ð%Ð%Ð%Ð%Ø"Ð"Ð"Ð"Ð"Ð"ØÐÐÐðfˆðN �OŠO˜G¨JˆOÑ7Ô7ˆÝ ™(œ(ð 		Añ 		AˆJØ˜JÑ&ˆGØ”×,Ò,¨Q¸gÐ,ÑFÔFˆBØ&×/Ò/Ð0DÑEÔEð Að A�Ø˜qœ' GÑ+¨d°1¬gÑ5�ØŸ	š	 'Ñ*Ô*�Ø× Ò ¥ U¡¤¨QÑ/Ô/Ð/Ø× Ò ¥ U¨1¤X¤\Ñ!2Ô!2°AÑ6Ô6Ð6Ø× Ò   q¤¤¨a¤Ô!6¸¸Q¼Ñ@Ô@Ð@Ø× Ò   q¤¤¨a¤Ô!6¸¸Q¼Ñ@Ô@Ð@Ð@ñAð		Að 		Ar   N)r+   r,   r-   r´   rÃ   rÌ   r   r   r   r¤   r¤   •  sS   € € € € € Øð2ð 2ð 2ðhn1ð n1ð n1ð`vAð vAð vAð vAð vAr   r¤   Ú__main__)r.   Ú
__future__r   Úcollectionsr   r   r�   Útypingr`   ÚunittestÚmusic21.exceptions21r   r°   r   ra   Úmusic21.common.typesr   re   Úsplitr'   r
   r2   r;   r=   ÚTestCaser¤   Ú
_DOC_ORDERr+   ÚmainTestr   r   r   ú<module>rØ      s  ððð ð #Ð "Ð "Ð "Ð "Ð "à /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ø 	€	€	€	Ø Ð Ð Ð Ø €€€à 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø Ð Ð Ð Ð Ð ð „?ð 0Ø/Ð/Ð/Ð/Ð/Ð/à€àR×XÒXÑZÔZ€	ð%(ð %(ð %(ð %(ð %(�:�:Øð3ð 3ð 3ñô ñ %(ô %(ð %(ðR"4ð "4ð "4ð "4ð "4�*�*˜]Ø\Ð\Ð\ñ^ô ^ñ "4ô "4ð "4ðJ	ð 	ð 	ð 	ð 	Ð-ñ 	ô 	ð 	ð^ð ^ð ^ð ^ð ^ñ ^ô ^ð ^ðH	]Að ]Að ]Að ]Að ]Aˆ8Ôñ ]Aô ]Að ]AðD ˆ_€
ð ˆzÒÐØ€N€N€NØ€GÔ�TÑÔÐÐÐð Ðr   