ó
    á“,jŠ  ã                   ó²   • S r SSK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  SSKJr  SSKJr  SSKJr  SSKJrJrJr  \
(       a
  SS	KJr  SSKr " S
 S5      rg)aW  
########
Timeline
########

.. plot:: pyplots/timeline.py

:class:`pyannote.core.Timeline` instances are ordered sets of non-empty
segments:

  - ordered, because segments are sorted by start time (and end time in case of tie)
  - set, because one cannot add twice the same segment
  - non-empty, because one cannot add empty segments (*i.e.* start >= end)

There are two ways to define the timeline depicted above:

.. code-block:: ipython

  In [25]: from pyannote.core import Timeline, Segment

  In [26]: timeline = Timeline()
     ....: timeline.add(Segment(1, 5))
     ....: timeline.add(Segment(6, 8))
     ....: timeline.add(Segment(12, 18))
     ....: timeline.add(Segment(7, 20))
     ....:

  In [27]: segments = [Segment(1, 5), Segment(6, 8), Segment(12, 18), Segment(7, 20)]
     ....: timeline = Timeline(segments=segments, uri='my_audio_file')  # faster
     ....:

  In [9]: for segment in timeline:
     ...:     print(segment)
     ...:
  [ 00:00:01.000 -->  00:00:05.000]
  [ 00:00:06.000 -->  00:00:08.000]
  [ 00:00:07.000 -->  00:00:20.000]
  [ 00:00:12.000 -->  00:00:18.000]


.. note::

  The optional *uri*  keyword argument can be used to remember which document it describes.

Several convenient methods are available. Here are a few examples:

.. code-block:: ipython

  In [3]: timeline.extent()    # extent
  Out[3]: <Segment(1, 20)>

  In [5]: timeline.support()  # support
  Out[5]: <Timeline(uri=my_audio_file, segments=[<Segment(1, 5)>, <Segment(6, 20)>])>

  In [6]: timeline.duration()  # support duration
  Out[6]: 18


See :class:`pyannote.core.Timeline` for the complete reference.
é    N)ÚOptionalÚIterableÚListÚUnionÚCallableÚTextIOÚTupleÚTYPE_CHECKINGÚIteratorÚDictÚText)Ú
SortedListé   )ÚPYANNOTE_SEGMENT)ÚSegment)ÚSupportÚLabelÚCropMode©Ú
Annotationc                   óŒ  • \ rS rSrSr\SDSSS\\   SS 4S jj5       r  SES	\\	\
      S\4S
 jjrS rS rS rS\\
   4S jrS\S\
4S jrSFS jrSFS jrS\
S\4S jrS\
SS 4S jrS\
SS 4S jrS\
SS 4S jrSGS jrS\
SS 4S jrSGS jrSGS jrSS S\\\
\
4      4S jr  SHS\S \ S!\!S\\"\\
\
4   \
4      4S" jjr#  SHS\S \ S!\!S\"S \S \$\
\
4   4   4   4S# jjr%S$\&S\'\
   4S% jr(S$\&S\\
   4S& jr)SIS' jr* SJS(\S \ SS 4S) jjr+S* r,S+ r-S,\"\
S 4   4S- jr.SIS. jr/SS S\!4S/ jr0SDS0\\1\
/\
4      SS 4S1 jjr2S\
4S2 jr3SKS3\&S\\
   4S4 jjr4SKS3\&SS 4S5 jjr5S\&4S6 jr6SDS\\   S\\
   4S7 jjr7SDS\\   SS 4S8 jjr8SIS9 jr9  SLS:\"\\	\:   SS4   S;\\   SS<4S= jjr;S\\<   4S> jr=S\<4S? jr>S@\?4SA jr@SB rASCrBg)MÚTimelineés   a•  
Ordered set of segments.

A timeline can be seen as an ordered set of non-empty segments (Segment).
Segments can overlap -- though adding an already exisiting segment to a
timeline does nothing.

Parameters
----------
segments : Segment iterator, optional
    initial set of (non-empty) segments
uri : string, optional
    name of segmented resource

Returns
-------
timeline : Timeline
    New timeline
NÚdfzpd.DataFrameÚuriÚreturnc                 ó6   • [        U[           5      nU " X2S9nU$ )N©Úsegmentsr   )Úlistr   )Úclsr   r   r   Útimelines        Ú¤C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\pyannote/core/timeline.pyÚfrom_dfÚTimeline.from_dfˆ   s!   € ä˜Ô+Ñ,Ó-ˆÙ Ñ2ˆØˆó    r   c                 óÊ   • Uc  Sn[        U Vs/ s H  o3(       d  M  UPM     sn5      nX@l        [        U5      U l        S U 5       n[        U5      U l        X l        g s  snf )N© c              3   ó6   #   • U  H  o  H  o"v •  M     M     g 7f©Nr(   ©Ú.0ÚsegmentÚboundarys      r#   Ú	<genexpr>Ú$Timeline.__init__.<locals>.<genexpr>ž   ó   é € ÐSªl 7Ë7¸x”hÉ7‘hªlùó   ‚)ÚsetÚsegments_set_r   Úsegments_list_Úsegments_boundaries_r   )Úselfr   r   r-   Úsegments_setÚ
boundariess         r#   Ú__init__ÚTimeline.__init__Ž   sh   € ð ÑØˆHô ±8ÓG²8¨»wŸG±8ÑGÓHˆà)Ôô )¨Ó6ˆÔñ T©lÓSˆ
Ü$.¨zÓ$:ˆÔ!ð �ùò Hs
   �
A �A c                 ó,   • [        U R                  5      $ )zLNumber of segments

>>> len(timeline)  # timeline contains three segments
3
©Úlenr4   ©r7   s    r#   Ú__len__ÚTimeline.__len__¤   s   € ô �4×%Ñ%Ó&Ð&r&   c                 ó"   • U R                  5       $ r*   )Ú__bool__r?   s    r#   Ú__nonzero__ÚTimeline.__nonzero__¬   s   € Ø�}‰}‹Ðr&   c                 ó2   • [        U R                  5      S:„  $ )z`Emptiness

>>> if timeline:
...    # timeline is not empty
... else:
...    # timeline is empty
r   r=   r?   s    r#   rC   ÚTimeline.__bool__¯   s   € ô �4×%Ñ%Ó&¨Ñ*Ð*r&   c                 ó,   • [        U R                  5      $ )zÊIterate over segments (in chronological order)

>>> for segment in timeline:
...     # do something with the segment

See also
--------
:class:`pyannote.core.Segment` describes how segments are sorted.
)Úiterr5   r?   s    r#   Ú__iter__ÚTimeline.__iter__¹   s   € ô �D×'Ñ'Ó(Ð(r&   Úkc                 ó    • U R                   U   $ )zvGet segment by index (in chronological order)

>>> first_segment = timeline[0]
>>> penultimate_segment = timeline[-2]
)r5   )r7   rL   s     r#   Ú__getitem__ÚTimeline.__getitem__Å   s   € ð ×"Ñ" 1Ñ%Ð%r&   Úotherc                 ó4   • U R                   UR                   :H  $ )a)  Equality

Two timelines are equal if and only if their segments are equal.

>>> timeline1 = Timeline([Segment(0, 1), Segment(2, 3)])
>>> timeline2 = Timeline([Segment(2, 3), Segment(0, 1)])
>>> timeline3 = Timeline([Segment(2, 3)])
>>> timeline1 == timeline2
True
>>> timeline1 == timeline3
False
©r4   ©r7   rP   s     r#   Ú__eq__ÚTimeline.__eq__Í   s   € ð ×!Ñ! U×%8Ñ%8Ñ8Ð8r&   c                 ó4   • U R                   UR                   :g  $ )Ú
InequalityrR   rS   s     r#   Ú__ne__ÚTimeline.__ne__Ü   s   € à×!Ñ! U×%8Ñ%8Ñ8Ð8r&   r-   c                 ó8   • U R                   R                  U5      $ )zéGet index of (existing) segment

Parameters
----------
segment : Segment
    Segment that is being looked for.

Returns
-------
position : int
    Index of `segment` in timeline

Raises
------
ValueError if `segment` is not present.
)r5   Úindex©r7   r-   s     r#   r[   ÚTimeline.indexà   s   € ð" ×"Ñ"×(Ñ(¨Ó1Ð1r&   c                 ó  • U R                   nX;   d  U(       d  U $ UR                  U5        U R                  R                  U5        U R                  nUR                  UR                  5        UR                  UR
                  5        U $ )a—  Add a segment (in place)

Parameters
----------
segment : Segment
    Segment that is being added

Returns
-------
self : Timeline
    Updated timeline.

Note
----
If the timeline already contains this segment, it will not be added
again, as a timeline is meant to be a **set** of segments (not a list).

If the segment is empty, it will not be added either, as a timeline
only contains non-empty segments.
)r4   Úaddr5   r6   ÚstartÚend©r7   r-   r4   r6   s       r#   r_   ÚTimeline.addó   ss   € ð, ×*Ñ*ˆØÓ#®7ØˆKà×Ñ˜'Ô"à×Ñ×Ñ Ô(à#×8Ñ8ÐØ× Ñ  §¡Ô/Ø× Ñ  §¡Ô-àˆr&   c                 ó  • U R                   nX;  a  U $ UR                  U5        U R                  R                  U5        U R                  nUR                  UR                  5        UR                  UR
                  5        U $ )zêRemove a segment (in place)

Parameters
----------
segment : Segment
    Segment that is being removed

Returns
-------
self : Timeline
    Updated timeline.

Note
----
If the timeline does not contain this segment, this does nothing
)r4   Úremover5   r6   r`   ra   rb   s       r#   re   ÚTimeline.remove  sq   € ð$ ×*Ñ*ˆØÓ'ØˆKà×Ñ˜WÔ%à×Ñ×"Ñ" 7Ô+à#×8Ñ8ÐØ×#Ñ# G§M¡MÔ2Ø×#Ñ# G§K¡KÔ0àˆr&   c                 ó$   • U R                  U5      $ )zJSame as `remove`

See also
--------
:func:`pyannote.core.Timeline.remove`
)re   r\   s     r#   ÚdiscardÚTimeline.discard7  s   € ð �{‰{˜7Ó#Ð#r&   r"   c                 ó$   • U R                  U5      $ r*   )Úupdate©r7   r"   s     r#   Ú__ior__ÚTimeline.__ior__@  s   € Ø�{‰{˜8Ó$Ð$r&   c                 óŒ   • U R                   nX!R                   -  n[        U5      U l        S U 5       n[        U5      U l        U $ )aG  Add every segments of an existing timeline (in place)

Parameters
----------
timeline : Timeline
    Timeline whose segments are being added

Returns
-------
self : Timeline
    Updated timeline

Note
----
Only segments that do not already exist will be added, as a timeline is
meant to be a **set** of segments (not a list).

c              3   ó6   #   • U  H  o  H  o"v •  M     M     g 7fr*   r(   r+   s      r#   r/   Ú"Timeline.update.<locals>.<genexpr>_  r1   r2   )r4   r   r5   r6   )r7   r"   r8   r9   s       r#   rk   ÚTimeline.updateC  sK   € ð( ×)Ñ)ˆà×.Ñ.Ñ.ˆô )¨Ó6ˆÔñ T©lÓSˆ
Ü$.¨zÓ$:ˆÔ!àˆr&   c                 ó$   • U R                  U5      $ r*   )Úunionrl   s     r#   Ú__or__ÚTimeline.__or__d  s   € Ø�z‰z˜(Ó#Ð#r&   c                 óZ   • U R                   UR                   -  n[        X R                  S9$ )a^  Create new timeline made of union of segments

Parameters
----------
timeline : Timeline
    Timeline whose segments are being added

Returns
-------
union : Timeline
    New timeline containing the union of both timelines.

Note
----
This does the same as timeline.update(...) except it returns a new
timeline, and the original one is not modified.
r   )r4   r   r   )r7   r"   r   s      r#   rt   ÚTimeline.uniong  s)   € ð$ ×%Ñ%¨×(>Ñ(>Ñ>ˆÜ ¯x©xÑ8Ð8r&   c              #   óè   #   • U R                    H^  n[        UR                  UR                  S9nUR                   R                  US9 H   nUR	                  U5      (       d  M  X$4v •  M"     M`     g7f)a+  Iterate over pairs of intersecting segments

>>> timeline1 = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 4)])
>>> timeline2 = Timeline([Segment(1, 3), Segment(3, 5)])
>>> for segment1, segment2 in timeline1.co_iter(timeline2):
...     print(segment1, segment2)
(<Segment(0, 2)>, <Segment(1, 3)>)
(<Segment(1, 2)>, <Segment(1, 3)>)
(<Segment(3, 4)>, <Segment(3, 5)>)

Parameters
----------
other : Timeline
    Second timeline

Returns
-------
iterable : (Segment, Segment) iterable
    Yields pairs of intersecting segments in chronological order.
©r`   ra   ©ÚmaximumN)r5   r   ra   ÚirangeÚ
intersects)r7   rP   r-   ÚtempÚother_segments        r#   Úco_iterÚTimeline.co_iter|  sf   é € ð, ×*Ô*ˆGô  §¡°'·+±+Ñ>ˆDØ!&×!5Ñ!5×!<Ñ!<ÀTÐ!<Ó!J�Ø×%Ñ% m×4Ó4Ø!Ð0Ô0ó "Kò	 +ùs   ‚AA2Á$A2ÚsupportÚmodeÚreturns_mappingc              #   óP  #   • US;  a  [        S5      e[        U[        [        45      (       d  [	        S5      e[        U[        5      (       a<  U(       a  U/nO/ n[        X@R
                  S9nU R                  XUS9 H  nUv •  M	     gUR                  5       nUS:X  a  U R                  U5       H	  u  pgUv •  M     gUS:X  a&  U R                  U5       H  u  phXh;   d  M  Uv •  M     gU R                  U5       H$  u  phXh-  n	U	(       d  M  U(       a  Xi4v •  M   U	v •  M&     g7f)	zjLike `crop` but returns a segment iterator instead

See also
--------
:func:`pyannote.core.Timeline.crop`
>   ÚlooseÚstrictÚintersectionz9Mode must be one of 'loose', 'strict', or 'intersection'.z(Support must be a Segment or a Timeline.r   ©r„   r…   Nr‡   rˆ   )	Ú
ValueErrorÚ
isinstancer   r   Ú	TypeErrorr   Ú	crop_iterrƒ   r�   )
r7   rƒ   r„   r…   r   Úyieldedr-   Ú_r€   Ú	mapped_tos
             r#   rŽ   ÚTimeline.crop_iterš  s1  é € ð Ð:Ó:Üð /ó 0ð 0ô ˜'¤G¬XÐ#6×7Ñ7ÜÐFÓGÐGä�gœw×'Ñ'æØ#˜9‘à�ä¨·h±hÑ?ˆGØŸ>™>¨'Ø:Ið *ó K�à”ñKð ð —/‘/Ó#ˆð �7‹?Ø"Ÿl™l¨7Ö3‘
�Ø”ñ 4àð �8ÓØ*.¯,©,°wÖ*?Ñ&�ØÕ+Ø!”Mñ +@ð ð '+§l¡l°7Ö&;Ñ"ˆGØÑ/ˆIÞÙÞØÐ(Ô(à”ò '<ùs   ‚CD&Ã#AD&c                 ó$  • US:X  aj  U(       ac  / 0 pTU R                  USSS9 H6  u  pgUR                  U5        UR                  U[        5       5      U/-   XW'   M8     [	        X@R
                  S9U4$ [	        U R                  XS9U R
                  S9$ )a¬  Crop timeline to new support

Parameters
----------
support : Segment or Timeline
    If `support` is a `Timeline`, its support is used.
mode : {'strict', 'loose', 'intersection'}, optional
    Controls how segments that are not fully included in `support` are
    handled. 'strict' mode only keeps fully included segments. 'loose'
    mode keeps any intersecting segment. 'intersection' mode keeps any
    intersecting segment but replace them by their actual intersection.
returns_mapping : bool, optional
    In 'intersection' mode, return a dictionary whose keys are segments
    of the cropped timeline, and values are list of the original
    segments that were cropped. Defaults to False.

Returns
-------
cropped : Timeline
    Cropped timeline
mapping : dict
    When 'returns_mapping' is True, dictionary whose keys are segments
    of 'cropped', and values are lists of corresponding original
    segments.

Examples
--------

>>> timeline = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 4)])
>>> timeline.crop(Segment(1, 3))
<Timeline(uri=None, segments=[<Segment(1, 2)>])>

>>> timeline.crop(Segment(1, 3), mode='loose')
<Timeline(uri=None, segments=[<Segment(0, 2)>, <Segment(1, 2)>])>

>>> timeline.crop(Segment(1, 3), mode='strict')
<Timeline(uri=None, segments=[<Segment(1, 2)>])>

>>> cropped, mapping = timeline.crop(Segment(1, 3), returns_mapping=True)
>>> print(mapping)
{<Segment(1, 2)>: [<Segment(0, 2)>, <Segment(1, 2)>]}

r‰   TrŠ   r   ©r„   )rŽ   ÚappendÚgetr    r   r   )r7   rƒ   r„   r…   r   Úmappingr-   r‘   s           r#   ÚcropÚTimeline.cropÔ  sœ   € ðb �>Ó!¦oØ " B�gØ&*§n¡n°WØ:HØEIð '5ó 'KÑ"�ð —‘ 	Ô*Ø%,§[¡[°¼D»FÓ%CÀwÀiÑ%O�Ó"ñ	'Kô
  X·8±8Ñ<¸gÐEÐEä §¡° Ð!CØ ŸH™Hñ&ð 	&r&   Útc                 ó6   • [        U R                  U5      5      $ )z¹Get list of segments overlapping `t`

Parameters
----------
t : float
    Timestamp, in seconds.

Returns
-------
segments : list
    List of all segments of timeline containing time t
)r    Úoverlapping_iter)r7   rš   s     r#   ÚoverlappingÚTimeline.overlapping  s   € ô �D×)Ñ)¨!Ó,Ó-Ð-r&   c              #   ó–   #   • [        XS9nU R                  R                  US9 H  nUR                  U5      (       d  M  Uv •  M!     g7f)zxLike `overlapping` but returns a segment iterator instead

See also
--------
:func:`pyannote.core.Timeline.overlapping`
rz   r{   N)r   r5   r}   Úoverlaps)r7   rš   r-   s      r#   rœ   ÚTimeline.overlapping_iter   sF   é € ô  Ñ)ˆØ×*Ñ*×1Ñ1¸'Ð1ÓBˆGØ×Ñ ×"Ó"Ø”ò Cùs   ‚:A	Á 	A	c                 ó°   • [        U R                  S9nU R                  U 5       H  u  p#X#:X  a  M  UR                  X#-  5        M!     UR	                  5       $ )aB  Get overlapping parts of the timeline.

A simple illustration:

.. code-block:: text

    timeline
    |------|    |------|      |----|
      |--|    |-----|      |----------|

    timeline.get_overlap()
      |--|      |---|         |----|

Returns
-------
overlap : `pyannote.core.Timeline`
   Timeline of the overlaps.
©r   )r   r   r�   r_   rƒ   )r7   Úoverlaps_tlÚs1Ús2s       r#   Úget_overlapÚTimeline.get_overlap,  sN   € ô&  4§8¡8Ñ,ˆØ—l‘l 4Ö(‰FˆBØ‹xÙØ�O‰O˜B™GÖ$ñ )ð ×"Ñ"Ó$Ð$r&   Úremovedc                 óè   • [        U[        5      (       a  [        U/5      n[        U R                  5       /U R                  S9nUR                  US9nUS:X  a  SnOUS:X  a  SnU R                  XBS9$ )aµ  Remove segments that overlap `removed` support.

Parameters
----------
removed : Segment or Timeline
    If `support` is a `Timeline`, its support is used.
mode : {'strict', 'loose', 'intersection'}, optional
    Controls how segments that are not fully included in `removed` are
    handled. 'strict' mode only removes fully included segments. 'loose'
    mode removes any intersecting segment. 'intersection' mode removes
    the overlapping part of any intersecting segment.

Returns
-------
extruded : Timeline
    Extruded timeline

Examples
--------

>>> timeline = Timeline([Segment(0, 2), Segment(1, 2), Segment(3, 5)])
>>> timeline.extrude(Segment(1, 2))
<Timeline(uri=None, segments=[<Segment(0, 1)>, <Segment(3, 5)>])>

>>> timeline.extrude(Segment(1, 3), mode='loose')
<Timeline(uri=None, segments=[<Segment(3, 5)>])>

>>> timeline.extrude(Segment(1, 3), mode='strict')
<Timeline(uri=None, segments=[<Segment(0, 2)>, <Segment(3, 5)>])>

r£   ©rƒ   r‡   rˆ   r”   )rŒ   r   r   Úextentr   Úgapsr˜   )r7   r©   r„   Ú	extent_tlÚtruncating_supports        r#   ÚextrudeÚTimeline.extrudeF  sr   € ôD �gœw×'Ñ'Ü ˜yÓ)ˆGä˜dŸk™k›m˜_°$·(±(Ñ;ˆ	Ø$Ÿ\™\°)˜\Ð<Ðà�7‹?Ø‰DØ�XÓØˆDØ�y‰yÐ+ˆyÐ7Ð7r&   c                 ó´   • [        U R                  5      nSn[        U R                  5       H"  u  p4U[        U5      -  nX#S-   U:  a  SOS-  nM$     US-  nU$ )zÁHuman-readable representation

>>> timeline = Timeline(segments=[Segment(0, 10), Segment(1, 13.37)])
>>> print(timeline)
[[ 00:00:00.000 -->  00:00:10.000]
 [ 00:00:01.000 -->  00:00:13.370]]

Ú[r   z
 Ú Ú])r>   r5   Ú	enumerateÚstr)r7   ÚnÚstringÚir-   s        r#   Ú__str__ÚTimeline.__str__t  sb   € ô �×#Ñ#Ó$ˆØˆÜ# D×$7Ñ$7Ö8‰JˆAØ”c˜'“lÑ"ˆFØ 1™u q›y‘e¨bÑ0ŠFñ 9ð 	�#‰ˆØˆr&   c                 óR   • SU R                   < S[        U R                  5      < S3$ )z¥Computer-readable representation

>>> Timeline(segments=[Segment(0, 10), Segment(1, 13.37)])
<Timeline(uri=None, segments=[<Segment(0, 10)>, <Segment(1, 13.37)>])>

z<Timeline(uri=z, segments=z)>)r   r    r5   r?   s    r#   Ú__repr__ÚTimeline.__repr__†  s%   � ð 59·H´HÜ48¸×9LÑ9LÖ4MðOð 	Or&   Úincludedc                 óÒ   • [        U[        5      (       a  XR                  ;   $ [        U[        5      (       a%  U R                  R	                  UR                  5      $ [        S5      e)a  Inclusion

Check whether every segment of `included` does exist in timeline.

Parameters
----------
included : Segment or Timeline
    Segment or timeline being checked for inclusion

Returns
-------
contains : bool
    True if every segment in `included` exists in timeline,
    False otherwise

Examples
--------
>>> timeline1 = Timeline(segments=[Segment(0, 10), Segment(1, 13.37)])
>>> timeline2 = Timeline(segments=[Segment(0, 10)])
>>> timeline1 in timeline2
False
>>> timeline2 in timeline1
>>> Segment(1, 13.37) in timeline1
True

zCChecking for inclusion only supports Segment and Timeline instances)rŒ   r   r4   r   Ú
issupersetr�   )r7   rÀ   s     r#   Ú__contains__ÚTimeline.__contains__‘  s^   € ô8 �h¤×(Ñ(Ø×1Ñ1Ñ1Ð1ä˜¤(×+Ñ+Ø×%Ñ%×0Ñ0°×1GÑ1GÓHÐHô ð%ó&ð &r&   c                 ó(   • [        U R                  S9$ )zkReturn an empty copy

Returns
-------
empty : Timeline
    Empty timeline using the same 'uri' attribute.

r£   )r   r   r?   s    r#   ÚemptyÚTimeline.empty¸  s   € ô ˜DŸH™HÑ%Ð%r&   c                 ón   • U R                  UR                  5       S9nUR                  U5       H  n  g   g)a  Check whether other timeline is fully covered by the timeline

Parameter
---------
other : Timeline
    Second timeline

Returns
-------
covers : bool
    True if timeline covers "other" timeline entirely. False if at least
    one segment of "other" is not fully covered by timeline
r«   FT)r­   r¬   r�   )r7   rP   r­   r�   s       r#   ÚcoversÚTimeline.coversÃ  s7   € ð" �y‰y §¡£ˆyÐ0ˆð —‘˜eÖ$ˆAÙñ %ð
 r&   Úsegment_funcc                 ó¶   • Uc  [        U R                  U R                  S9$ [        U R                   Vs/ s H
  o!" U5      PM     snU R                  S9$ s  snf )a_  Get a copy of the timeline

If `segment_func` is provided, it is applied to each segment first.

Parameters
----------
segment_func : callable, optional
    Callable that takes a segment as input, and returns a segment.
    Defaults to identity function (segment_func(segment) = segment)

Returns
-------
timeline : Timeline
    Copy of the timeline

r   )r   r5   r   )r7   rË   Úss      r#   ÚcopyÚTimeline.copyß  sW   € ð* ÑÜ T×%8Ñ%8¸d¿h¹hÑGÐGô ¸4×;NÒ;NÓ!OÒ;N°a ,¨q¦/Ñ;NÑ!OØ ŸH™Hñ&ð 	&ùÒ!Os   µAc                 óv   • U R                   (       a  U R                  nUS   nUS   n[        X#S9$ [        SSS9$ )a5  Extent

The extent of a timeline is the segment of minimum duration that
contains every segments of the timeline. It is unique, by definition.
The extent of an empty timeline is an empty segment.

A picture is worth a thousand words::

    timeline
    |------|    |------|     |----|
      |--|    |-----|     |----------|

    timeline.extent()
    |--------------------------------|

Returns
-------
extent : Segment
    Timeline extent

Examples
--------
>>> timeline = Timeline(segments=[Segment(0, 1), Segment(9, 10)])
>>> timeline.extent()
<Segment(0, 10)>

r   éÿÿÿÿrz   ç        )r4   r6   r   )r7   r6   r`   ra   s       r#   r¬   ÚTimeline.extentü  sE   € ð8 ××Ø#'×#<Ñ#<Ð Ø(¨Ñ+ˆEØ& rÑ*ˆCÜ Ñ0Ð0ä˜S cÑ*Ð*r&   Úcollarc              #   ó¢   #   • U (       d  gU R                   S   nU  H*  nX2-  nU(       a  UR                  U:  a  X#-  nM$  Uv •  UnM,     Uv •  g7f)zqLike `support` but returns a segment generator instead

See also
--------
:func:`pyannote.core.Timeline.support`
Nr   )r5   Úduration)r7   rÔ   Únew_segmentr-   Úpossible_gaps        r#   Úsupport_iterÚTimeline.support_iter   sb   é € ö Øð ×)Ñ)¨!Ñ,ˆãˆGð #Ñ0ˆLÞ <×#8Ñ#8¸6Ó#AàÑ&’ð
 "Ò!ð &’ñ! ð& Óùs   ‚AAc                 óH   • [        U R                  U5      U R                  S9$ )a
  Timeline support

The support of a timeline is the timeline with the minimum number of
segments with exactly the same time span as the original timeline. It
is (by definition) unique and does not contain any overlapping
segments.

A picture is worth a thousand words::

    collar
    |---|

    timeline
    |------|    |------|      |----|
      |--|    |-----|      |----------|

    timeline.support()
    |------|  |--------|   |----------|

    timeline.support(collar)
    |------------------|   |----------|

Parameters
----------
collar : float, optional
    Merge separated by less than `collar` seconds. This is why there
    are only two segments in the final timeline in the above figure.
    Defaults to 0.

Returns
-------
support : Timeline
    Timeline support
r   )r   rÙ   r   )r7   rÔ   s     r#   rƒ   ÚTimeline.supportM  s!   € ôF  ×!2Ñ!2°6Ó!:ÀÇÁÑIÐIr&   c                 óB   • [        S U R                  5        5       5      $ )z¾Timeline duration

The timeline duration is the sum of the durations of the segments
in the timeline support.

Returns
-------
duration : float
    Duration of timeline support, in seconds.
c              3   ó8   #   • U  H  oR                   v •  M     g 7fr*   )rÖ   )r,   rÍ   s     r#   r/   Ú$Timeline.duration.<locals>.<genexpr>€  s   é € Ð;Ò': !—:–:Ò':ùs   ‚)ÚsumrÙ   r?   s    r#   rÖ   ÚTimeline.durationr  s   € ô Ñ; t×'8Ñ'8Ô':Ó;Ó;Ð;r&   c              #   óX  #   • Uc  U R                  5       n[        U[        [        45      (       d!  [	        S[        U5      R                  -  5      e[        U[        5      (       a{  UR                  nU R                  USS9R                  5        H-  n[        X#R                  S9nU(       a  Uv •  UR                  nM/     [        X!R                  S9nU(       a  Uv •  gg[        U[        5      (       a2  UR                  5        H  nU R                  US9 H  nUv •  M	     M     gg7f)zlLike `gaps` but returns a segment generator instead

See also
--------
:func:`pyannote.core.Timeline.gaps`

Nz3unsupported operand type(s) for -':%s and Timeline.r‰   r”   rz   r«   )r¬   rŒ   r   r   r�   ÚtypeÚ__name__r`   r˜   rƒ   ra   Ú	gaps_iter)r7   rƒ   ra   r-   Úgaps        r#   rå   ÚTimeline.gaps_iter‚  s  é € ð ‰?Ø—k‘k“mˆGä˜'¤G¬XÐ#6×7Ñ7Üð /Ü15°g³×1GÑ1GñHó Ið Iô �gœw×'Ñ'ð —-‘-ˆCð  Ÿ9™9 W°>˜9ÐB×JÑJÖL�ô  C¯]©]Ñ;�ÞØ’Ið —k‘k’ñ Mô  ¯©Ñ5ˆCÞØ“	ð ô ˜¤×*Ñ*ð #Ÿ?™?Ö,�ØŸ>™>°'˜>Ó:�CØ”Ió ;ò -ð +ùs   ‚D(D*c                 óD   • [        U R                  US9U R                  S9$ )aî  Gaps

A picture is worth a thousand words::

    timeline
    |------|    |------|     |----|
      |--|    |-----|     |----------|

    timeline.gaps()
           |--|        |--|

Parameters
----------
support : None, Segment or Timeline
    Support in which gaps are looked for. Defaults to timeline extent

Returns
-------
gaps : Timeline
    Timeline made of all gaps from original timeline, and delimited
    by provided support

See also
--------
:func:`pyannote.core.Timeline.extent`

r«   r   )r   rå   r   )r7   rƒ   s     r#   r­   ÚTimeline.gaps²  s%   € ô:  §¡¸ Ð!@Ø ŸH™Hñ&ð 	&r&   c                 óä  • U R                  5       n[        / 5      nU  H'  u  p4UR                  U5        UR                  U5        M)     [        U5      n[	        U R
                  S9n[        U5      S:X  a  [	        U R
                  S9$ / nUS   nUSS  HF  n[        X4S9nU(       a1  UR                  UR                  5      (       a  UR                  U5        UnMH     [	        X`R
                  S9$ )a  Segmentation

Create the unique timeline with same support and same set of segment
boundaries as original timeline, but with no overlapping segments.

A picture is worth a thousand words::

    timeline
    |------|    |------|     |----|
      |--|    |-----|     |----------|

    timeline.segmentation()
    |-|--|-|  |-|---|--|  |--|----|--|

Returns
-------
timeline : Timeline
    (unique) timeline with same support and same set of segment
    boundaries as original timeline, but with no overlapping segments.
r£   r   r   Nrz   r   )rƒ   r3   r_   Úsortedr   r   r>   r   r�   Úmiddler•   )r7   rƒ   Ú
timestampsr`   ra   r"   r   r-   s           r#   ÚsegmentationÚTimeline.segmentationÒ  sÖ   € ð, —,‘,“.ˆô ˜“Wˆ
Û ‰LˆUØ�N‰N˜5Ô!Ø�N‰N˜3Öñ !ô ˜JÓ'ˆ
ô  §¡Ñ)ˆäˆz‹?˜aÓÜ §¡Ñ)Ð)àˆØ˜1‘ˆØ˜a˜b“>ˆCä EÑ3ˆGÞ˜7×.Ñ.¨w¯~©~×>Ñ>Ø—‘ Ô(àŠEñ "ô  ¯x©xÑ8Ð8r&   Ú	generatorÚmodalityr   c                 ó®   • SSK Jn  U" U R                  US9nUS:X  a  SSKJn  U" 5       nOUS:X  a  SSKJn  U" 5       nU  H  n[        U5      XG'   M     U$ )ai  Turn timeline into an annotation

Each segment is labeled by a unique label.

Parameters
----------
generator : 'string', 'int', or iterable, optional
    If 'string' (default) generate string labels. If 'int', generate
    integer labels. If iterable, use it to generate labels.
modality : str, optional

Returns
-------
annotation : Annotation
    Annotation
r   r   )r   rñ   r¹   )Ústring_generatorÚint)Úint_generator)Ú
annotationr   r   Úutils.generatorsró   rõ   Únext)r7   rð   rñ   r   rö   ró   rõ   r-   s           r#   Úto_annotationÚTimeline.to_annotation  sZ   € õ* 	+Ù D§H¡H°xÑ@ˆ
Ø˜Ó Ý:Ù(Ó*‰IØ˜%ÓÝ7Ù%›ˆIãˆGÜ"& y£/ˆJÓñ ð Ðr&   c              #   óú   #   • U R                   (       a  U R                   OSn[        U[        5      (       a  SU;   a  SU S3n[        U5      eU  H&  nU SUR                  S SUR
                  S S3v •  M(     g7f)	z}Generate lines for a UEM file for this timeline

Returns
-------
iterator: Iterator[str]
    An iterator over UEM text lines
z<NA>Ú zRSpace-separated UEM file format does not allow file URIs containing spaces (got: "z").z 1 z.3fÚ
N)r   rŒ   r   r‹   r`   ra   )r7   r   Úmsgr-   s       r#   Ú	_iter_uemÚTimeline._iter_uem0  sy   é € ð Ÿ(Ÿ(ˆd�hŠh¨ˆÜ�cœ4× Ñ  S¨C£Zð/Ø/2¨e°3ð8ˆCä˜S“/Ð!ÛˆGØ�E˜˜WŸ]™]¨3Ð/¨q°·±¸SÐ0AÀÐDÔDò ùs   ‚A9A;c                 ój   • SR                  U R                  5        Vs/ s H  oPM     sn5      $ s  snf )z`Serialize timeline as a string using UEM format

Returns
-------
serialized: str
    UEM string
r´   )Újoinrÿ   )r7   Úlines     r#   Úto_uemÚTimeline.to_uem@  s.   € ð �w‰w¨¯©Ô)9Ó:Ò)9 šÑ)9Ñ:Ó;Ð;ùÒ:s   ž0Úfilec                 óT   • U R                  5        H  nUR                  U5        M     g)z¦Dump timeline to file using UEM format

Parameters
----------
file : file object

Usage
-----
>>> with open('file.uem', 'w') as file:
...    timeline.write_uem(file)
N)rÿ   Úwrite)r7   r  r  s      r#   Ú	write_uemÚTimeline.write_uemJ  s!   € ð —N‘NÖ$ˆDØ�J‰J�tÖò %r&   c                 ó¬   • SSK JnJn  U(       d8  [        R                  " UR                  U R                  R                  S95        gSSK Jn  U" U 5      $ )zJIPython notebook support

See also
--------
:mod:`pyannote.core.notebook`
r   )ÚMATPLOTLIB_IS_AVAILABLEÚMATPLOTLIB_WARNING)ÚklassN)Úrepr_timeline)	Únotebookr  r  ÚwarningsÚwarnÚformatÚ	__class__rä   r  )r7   r  r  r  s       r#   Ú
_repr_png_ÚTimeline._repr_png_Y  sA   € ÷ 	JÞ&Ü�MŠMÐ,×3Ñ3¸$¿.¹.×:QÑ:QÐ3ÐRÔSØå+Ù˜TÓ"Ð"r&   )r6   r5   r4   r   r*   )NN)rP   r   )r"   r   r   r   )r‰   F)r   r   )r‰   )rÒ   )r¹   N)Crä   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Úclassmethodr   r·   r$   r   r   r:   r@   rD   rC   r   rJ   rô   rN   rT   rX   r[   r_   re   rh   rm   rk   ru   rt   r	   r�   r   r   Úboolr   rŽ   r   r˜   Úfloatr   r�   rœ   r§   r°   r»   r¾   rÃ   rÆ   rÉ   r   rÎ   r¬   rÙ   rƒ   rÖ   rå   r­   rî   r   rù   r   rÿ   r  r   r	  r  Ú__static_attributes__r(   r&   r#   r   r   s   ss  † ñð( ñ˜ð ¨h°s©mð Àzô ó ðð :>Ø ñØ# H¨WÑ$5Ñ6ðàõò,'òò+ð
)˜( 7Ñ+ô 
)ð&˜Sð & Wô &ô9ô9ð2˜Wð 2¨ô 2ð&"˜7ð " zô "ðH˜gð ¨*ô ð@$˜wð $¨:ô $ô%ð˜wð ¨:ô ôB$ô9ð*1˜Zð 1¨H°U¸7ÀGÐ;KÑ5LÑ,Mô 1ð@ $2Ø*/ñ8 Ø"ð8 à ð8 ð $(ð8 ð ˜˜e G¨WÐ$4Ñ5°wÐ>Ñ?Ñ@õ	8 ðx -Ø%*ñ;&Øð;&àð;&ð #ð;&ð �Z  z°4¸ÀÐ8HÑ3IÐ'IÑ!JÐJÑKõ	;&ðz.˜Uð . t¨G¡}ô .ð
 %ð 
¨H°WÑ,=ô 
ô%ð8 "0ñ,8Ø ð,8àð,8à4>õ,8ò\ò$	Oð%& U¨7°JÐ+>Ñ%?ô %&ôN	&ð˜Jð ¨4ô ñ8& ¨(°G°9¸gÐ3EÑ*FÑ!Gð &Øõ&ð:"+˜ô "+ñH+ 5ð +°8¸GÑ3Dõ +ñZ#J˜eð #J¨Zõ #JðJ<˜%ô <ñ . ¨'Ñ!2ð .¸hÀwÑ>Oõ .ñ`&˜H WÑ-ð &Øõ&ô@99ðx LTØ04ñ!Ø!& s¨H°U©O¸TÀ4Ð'GÑ!Hð!à (¨¡ð!ð õ!ðFE˜8 D™>ô Eð <˜ô <ð˜fô õ#r&   r   )r  r  Útypingr   r   r   r   r   r   r	   r
   r   r   r   Úsortedcontainersr   r´   r   r-   r   Úutils.typesr   r   r   rö   r   ÚpandasÚpdr   r(   r&   r#   Ú<module>r$     sP   ðñ>;óx ÷H÷ H÷ Hñ Hõ (å Ý ß 1Ñ 1ö Ý&Û÷s#ò s#r&   