
    lj3                       d Z ddlmZ g dZddlZddlmZmZm	Z	m
Z
mZmZmZ ddlmZmZmZ ddlZ ed          Z ed          Z ed	ej        ej                  Z ed
e
          ZerddlmZ dSdZdTdZdUdZdVdZdWd"Z dXd%Z!dXd&Z"edYd*            Z#edZd+            Z#ed[d,            Z#d\d/Z#d]d4Z$d^d7Z%d_d;Z&d`d>Z'dadBZ(dbdDZ)dadEZ*dadFZ+edcdH            Z,edddJ            Z,ededK            Z,dfdMZ,dgdPZ-dhdRZ.dS )izOperations on iterables.    )annotations)adjacent_n_tuplesadjacent_pairsall_elements_are_instancesconcatenate_listslist_difference_updatelist_updatelistify	make_evenmake_even_by_cyclingremove_list_redundanciesremove_nonesstretch_array_to_lengthtuplifyN)Callable
Collection	GeneratorHashableIterable
ReversibleSequence)TYPE_CHECKINGTypeVaroverloadTUFH)boundobjectsSequence[T]nintreturnzip[tuple[T, ...]]c                N     t           fdt          |          D             ddiS )a  Returns the Sequence objects cyclically split into n length tuples.

    See Also
    --------
    adjacent_pairs : alias with n=2

    Examples
    --------
    .. code-block:: pycon

        >>> list(adjacent_n_tuples([1, 2, 3, 4], 2))
        [(1, 2), (2, 3), (3, 4), (4, 1)]
        >>> list(adjacent_n_tuples([1, 2, 3, 4], 3))
        [(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 2)]
    c              3  D   K   | ]}g |d          d |         V  d S N ).0kr    s     P/home/agentuser/manim-venv/lib/python3.11/site-packages/manim/utils/iterables.py	<genexpr>z$adjacent_n_tuples.<locals>.<genexpr>=   s>      @@!-7122;-!-@@@@@@    strictT)ziprange)r    r"   s   ` r,   r   r   -   s3      @@@@uQxx@@@NNNNr.   c                "    t          | d          S )zAlias for ``adjacent_n_tuples(objects, 2)``.

    See Also
    --------
    adjacent_n_tuples

    Examples
    --------
    .. code-block:: pycon

        >>> list(adjacent_pairs([1, 2, 3, 4]))
        [(1, 2), (2, 3), (3, 4), (4, 1)]
       )r   )r    s    r,   r   r   @   s     Wa(((r.   iterableIterable[object]Classtype[object]boolc                :    t          fd| D                       S )z^Returns ``True`` if all elements of iterable are instances of Class.
    False otherwise.
    c              3  8   K   | ]}t          |          V  d S r(   )
isinstance)r*   er6   s     r,   r-   z-all_elements_are_instances.<locals>.<genexpr>U   s-      66z!U##666666r.   )all)r4   r6   s    `r,   r   r   Q   s(     6666X666666r.   itemsIterable[T]property_funcCallable[[T], U]list[tuple[list[T], U | None]]c                   g }g }d}| D ]X} ||          }||k    r0t          |          dk    r|                    ||f           |}|g}C|                    |           Yt          |          dk    r|                    ||f           |S )a  Takes in a Sequence, and returns a list of tuples, (batch, prop)
    such that all items in a batch have the same output when
    put into the Callable property_func, and such that chaining all these
    batches together would give the original Sequence (i.e. order is
    preserved).

    Examples
    --------
    .. code-block:: pycon

        >>> batch_by_property([(1, 2), (3, 4), (5, 6, 7), (8, 9)], len)
        [([(1, 2), (3, 4)], 2), ([(5, 6, 7)], 3), ([(8, 9)], 2)]
    Nr   )lenappend)r>   r@   batch_prop_pairs
curr_batch	curr_propitemprops          r,   batch_by_propertyrK   X   s      8:JI 
$ 
$}T""9:"" ''Y(?@@@IJJd####
:Y 7888r.   list_of_listslist[T]c                     d | D             S )zCombines the Iterables provided as arguments into one list.

    Examples
    --------
    .. code-block:: pycon

        >>> concatenate_lists([1, 2], [3, 4], [5])
        [1, 2, 3, 4, 5]
    c                    g | ]	}|D ]}|
S r)   r)   )r*   lstrI   s      r,   
<listcomp>z%concatenate_lists.<locals>.<listcomp>   s%    :::Sc::dD::::r.   r)   )rL   s    r,   r   r   {   s     ;:M::::r.   l1l2c                     fd| D             S )zReturns a list containing all the elements of l1 not in l2.

    Examples
    --------
    .. code-block:: pycon

        >>> list_difference_update([1, 2, 3, 4], [2, 4])
        [1, 3]
    c                    g | ]}|v|	S r)   r)   r*   r<   rS   s     r,   rQ   z*list_difference_update.<locals>.<listcomp>       )))!Qb[[A[[[r.   r)   rR   rS   s    `r,   r   r      s     *)))r))))r.   c                @    fd| D             t                    z   S )a9  Used instead of ``set.update()`` to maintain order,
        making sure duplicates are removed from l1, not l2.
        Removes overlap of l1 and l2 and then concatenates l2 unchanged.

    Examples
    --------
    .. code-block:: pycon

        >>> list_update([1, 2, 3], [2, 4, 4])
        [1, 3, 2, 4, 4]
    c                    g | ]}|v|	S r)   r)   rV   s     r,   rQ   zlist_update.<locals>.<listcomp>   rW   r.   )listrX   s    `r,   r	   r	      s*     *)))r)))DHH44r.   objstr	list[str]c                    d S r(   r)   r\   s    r,   r
   r
      s    $'Cr.   c                    d S r(   r)   r`   s    r,   r
   r
      s    *-#r.   c                    d S r(   r)   r`   s    r,   r
   r
      s     #r.   str | Iterable[T] | Tlist[str] | list[T]c                    t          | t                    r| gS t          | t                    rt          |           S | gS )zConverts obj to a list intelligently.

    Examples
    --------
    .. code-block:: pycon

        >>> listify("str")
        ['str']
        >>> listify((1, 2))
        [1, 2]
        >>> listify(len)
        [<built-in function len>]
    )r;   r]   r   r[   r`   s    r,   r
   r
      sB     #s u#x   Cyyur.   
iterable_1
iterable_2Iterable[U]tuple[list[T], list[U]]c                   t          |           t          |          ct                    t                    t                    fdt                    D             fdt                    D             fS )a  Extends the shorter of the two iterables with duplicate values until its
        length is equal to the longer iterable (favours earlier elements).

    See Also
    --------
    make_even_by_cycling : cycles elements instead of favouring earlier ones

    Examples
    --------
    .. code-block:: pycon

        >>> make_even([1, 2], [3, 4, 5, 6])
        ([1, 1, 2, 2], [3, 4, 5, 6])

        >>> make_even([1, 2], [3, 4, 5, 6, 7])
        ([1, 1, 1, 2, 2], [3, 4, 5, 6, 7])
    c                ,    g | ]}|z  z           S r)   r)   )r*   r"   
len_list_1lengthlist_1s     r,   rQ   zmake_even.<locals>.<listcomp>   '    CCCZF*	+CCCr.   c                ,    g | ]}|z  z           S r)   r)   )r*   r"   
len_list_2rm   list_2s     r,   rQ   zmake_even.<locals>.<listcomp>   ro   r.   )r[   rD   maxr1   )rf   rg   rl   rq   rm   rn   rr   s     @@@@@r,   r   r      s    ( *%%tJ'7'7NFFVJVJZ((FCCCCCCU6]]CCCCCCCCCU6]]CCC r.   Collection[T]Collection[U]c                   t          t          |           t          |                    }t          j        |           t          j        |          fdt	          |          D             fdt	          |          D             fS )a  Extends the shorter of the two iterables with duplicate values until its
        length is equal to the longer iterable (cycles over shorter iterable).

    See Also
    --------
    make_even : favours earlier elements instead of cycling them

    Examples
    --------
    .. code-block:: pycon

        >>> make_even_by_cycling([1, 2], [3, 4, 5, 6])
        ([1, 2, 1, 2], [3, 4, 5, 6])

        >>> make_even_by_cycling([1, 2], [3, 4, 5, 6, 7])
        ([1, 2, 1, 2, 1], [3, 4, 5, 6, 7])
    c                .    g | ]}t                    S r)   next)r*   _cycle1s     r,   rQ   z(make_even_by_cycling.<locals>.<listcomp>       ---!f---r.   c                .    g | ]}t                    S r)   rx   )r*   rz   cycle2s     r,   rQ   z(make_even_by_cycling.<locals>.<listcomp>   r|   r.   )rs   rD   itcycler1   )rf   rg   rm   r{   r~   s      @@r,   r   r      s    ( Z#j//22FXj!!FXj!!F----uV}}-------uV}}--- r.   rP   Reversible[H]list[H]c                    g }t                      }t          |           D ]0}||vr*|                    |           |                    |           1|                                 |S )zgUsed instead of ``list(set(l))`` to maintain order.
    Keeps the last occurrence of each element.
    )setreversedrE   addreverse)rP   reversed_resultusedxs       r,   r   r     sl     O55Dc]]  D==""1%%%HHQKKKr.   sequenceIterable[T | None]c                    d | D             S )zRemoves elements where bool(x) evaluates to False.

    Examples
    --------
    .. code-block:: pycon

        >>> remove_nones(["m", "", "l", 0, 42, False, True])
        ['m', 'l', 42, True]
    c                    g | ]}||S r)   r)   )r*   r   s     r,   rQ   z remove_nones.<locals>.<listcomp>  s    %%%!1%A%%%r.   r)   )r   s    r,   r   r     s     &%x%%%%r.   nparraynpt.NDArray[F]rm   c                x    t          |           |k    r| S t          j        | |g| j        dd         R           S )a  Extends/truncates nparray so that ``len(result) == length``.
        The elements of nparray are cycled to achieve the desired length.

    See Also
    --------
    resize_preserving_order : favours earlier elements instead of cycling them
    make_even_by_cycling : similar cycling behaviour for balancing 2 iterables

    Examples
    --------
    .. code-block:: pycon

        >>> points = np.array([[1, 2], [3, 4]])
        >>> resize_array(points, 1)
        array([[1, 2]])
        >>> resize_array(points, 3)
        array([[1, 2],
               [3, 4],
               [1, 2]])
        >>> resize_array(points, 2)
        array([[1, 2],
               [3, 4]])
       N)rD   npresizeshape)r   rm   s     r,   resize_arrayr     sB    0 7||v9Wv:abb(9::;;;r.   npt.NDArray[np.float64]c                    t          |           dk    r%t          j        |g| j        dd         R           S t          |           |k    r| S t          j        |          t          |           z  |z  }| |         S )a"  Extends/truncates nparray so that ``len(result) == length``.
        The elements of nparray are duplicated to achieve the desired length
        (favours earlier elements).

        Constructs a zeroes array of length if nparray is empty.

    See Also
    --------
    resize_array : cycles elements instead of favouring earlier ones
    make_even : similar earlier-favouring behaviour for balancing 2 iterables

    Examples
    --------
    .. code-block:: pycon

        >>> resize_preserving_order(np.array([]), 5)
        array([0., 0., 0., 0., 0.])

        >>> nparray = np.array([[1, 2], [3, 4]])
        >>> resize_preserving_order(nparray, 1)
        array([[1, 2]])

        >>> resize_preserving_order(nparray, 3)
        array([[1, 2],
               [1, 2],
               [3, 4]])
    r   r   N)rD   r   zerosr   arange)r   rm   indicess      r,   resize_preserving_orderr   :  s{    < 7||qx4'-"344555
7||vi#g,,.&8G7r.   c                     t                     |k    r S t          j        dt                     dz
  |          }t          j         fd|D                       S )av  Extends/truncates nparray so that ``len(result) == length``.
        New elements are interpolated to achieve the desired length.

        Note that if nparray's length changes, its dtype may too
        (e.g. int -> float: see Examples)

    See Also
    --------
    resize_array : cycles elements instead of interpolating
    resize_preserving_order : favours earlier elements instead of interpolating

    Examples
    --------
    .. code-block:: pycon

        >>> nparray = np.array([[1, 2], [3, 4]])
        >>> resize_with_interpolation(nparray, 1)
        array([[1., 2.]])
        >>> resize_with_interpolation(nparray, 4)
        array([[1.        , 2.        ],
               [1.66666667, 2.66666667],
               [2.33333333, 3.33333333],
               [3.        , 4.        ]])
        >>> nparray = np.array([[[1, 2], [3, 4]]])
        >>> nparray = np.array([[1, 2], [3, 4], [5, 6]])
        >>> resize_with_interpolation(nparray, 4)
        array([[1.        , 2.        ],
               [2.33333333, 3.33333333],
               [3.66666667, 4.66666667],
               [5.        , 6.        ]])
        >>> nparray = np.array([[1, 2], [3, 4], [1, 2]])
        >>> resize_with_interpolation(nparray, 4)
        array([[1.        , 2.        ],
               [2.33333333, 3.33333333],
               [2.33333333, 3.33333333],
               [1.        , 2.        ]])
    r   r   c                    g | ]Q}t          |          t          t          j        |                    |d z  }}}d |z
  |         z  ||         z  z   RS )r   )r#   r   ceil)r*   cilhrhar   s        r,   rQ   z-resize_with_interpolation.<locals>.<listcomp>  sj     	
 	
 	
"2wwBGBKK(8(8"q&B Ugbk!AO3	
 	
 	
r.   )rD   r   linspacearray)r   rm   cont_indicess   `  r,   resize_with_interpolationr   `  st    L 7||v;q#g,,"2F;;L8	
 	
 	
 	
"	
 	
 	
  r.   c                    t          |           }||k    rt          d          t          j        |          t	          |          z  }||z  }| |                    t                             S )Nz8Trying to stretch array to a length shorter than its own)rD   Warningr   r   floatastyper#   )r   rm   curr_lenr   s       r,   r   r     sb    7||H&PQQQi%--/GxG7>>#&&''r.   
tuple[str]c                    d S r(   r)   r`   s    r,   r   r     s    %(Sr.   tuple[T]c                    d S r(   r)   r`   s    r,   r   r     s    +.3r.   c                    d S r(   r)   r`   s    r,   r   r     s    !$r.   tuple[str] | tuple[T]c                    t          | t                    r| fS t          | t                    rt          |           S | fS )zConverts obj to a tuple intelligently.

    Examples
    --------
    .. code-block:: pycon

        >>> tuplify("str")
        ('str',)
        >>> tuplify([1, 2])
        (1, 2)
        >>> tuplify(len)
        (<built-in function len>,)
    )r;   r]   r   tupler`   s    r,   r   r     sB     #s v#x   Szzvr.   argsGenerator[T, None, None]c               '     K   t                      }t          j        |  D ] }||v r|                    |           |V  !dS )az  Returns a generator that yields all unique elements of the Iterables
        provided via args in the order provided.

    Examples
    --------
    .. code-block:: pycon

        >>> gen = uniq_chain([1, 2], [2, 3], [1, 4, 4])
        >>> from collections.abc import Generator
        >>> isinstance(gen, Generator)
        True
        >>> tuple(gen)
        (1, 2, 3, 4)
    N)r   r   chainr   )r   unique_itemsr   s      r,   
uniq_chainr     s]       55LXt_  	 r.   objectc           	        t          | t                    rEt          t          t	          d |                                 D                                           S t          | t                    r3t          t          t	          d | D                                           S t          | t          t          f          r&t          t          d | D                                 S t          |           S )z7Determines a hash, even of potentially mutable objects.c              3  X   K   | ]%\  }}t          |          t          |          fV  &d S r(   hash_obj)r*   r+   vs      r,   r-   zhash_obj.<locals>.<genexpr>  s7       T T1(1++x{{!; T T T T T Tr.   c              3  4   K   | ]}t          |          V  d S r(   r   r*   r<   s     r,   r-   zhash_obj.<locals>.<genexpr>  s(       : :! : : : : : :r.   c              3  4   K   | ]}t          |          V  d S r(   r   r   s     r,   r-   zhash_obj.<locals>.<genexpr>  s(      33!(1++333333r.   )r;   dicthashr   sortedr>   r   r[   r`   s    r,   r   r     s    #t WE& T T		 T T TTTUUVVV#s =E& : :c : : :::;;<<<#t}%% 5E33s3333344499r.   )r    r!   r"   r#   r$   r%   )r    r!   r$   r%   )r4   r5   r6   r7   r$   r8   )r>   r?   r@   rA   r$   rB   )rL   r?   r$   rM   )rR   r?   rS   r?   r$   rM   )r\   r]   r$   r^   )r\   r?   r$   rM   )r\   r   r$   rM   )r\   rc   r$   rd   )rf   r?   rg   rh   r$   ri   )rf   rt   rg   ru   r$   ri   )rP   r   r$   r   )r   r   r$   rM   )r   r   rm   r#   r$   r   )r   r   rm   r#   r$   r   )r\   r]   r$   r   )r\   r?   r$   r   )r\   r   r$   r   )r\   rc   r$   r   )r   r?   r$   r   )r\   r   r$   r#   )/__doc__
__future__r   __all__	itertoolsr   collections.abcr   r   r   r   r   r   r   typingr   r   r   numpyr   r   r   float64int_r   r   numpy.typingnptr   r   r   rK   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r)   r.   r,   <module>r      s@     " " " " " "                         4 3 3 3 3 3 3 3 3 3    GCLLGCLLGCRW%%GCx     O O O O&) ) ) )"7 7 7 7       F
; 
; 
; 
;
* 
* 
* 
*5 5 5 5 
 ' ' ' 
 ' 
 - - - 
 - 
 # # # 
 #   ,   <   :   & & & &< < < <:# # # #L/ / / /d( ( ( ( 
 ( ( ( 
 ( 
 . . . 
 . 
 $ $ $ 
 $   ,   .     r.   