
    piS                     h   d Z ddlZddlmZmZ ddlmZ ddlmZ ddl	m
Z
mZmZ ddlmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ dd	lm Z m!Z!m"Z"m#Z# dd
l$m%Z%m&Z&m'Z'm(Z(m)Z) ddlm*Z*m+Z+m,Z, ddl-m.Z. g dZ/ e0       Z1	  e2d        ee2d      Z3	 ddlm5Z6 	 ddlm8Z8m9Z9 dZ:d Z;d]dZ<d Z=d^dZ>d^dZ?d^dZ@eAfdZBd ZCeCZDd ZEd ZFd ZGd^dZHd  ZI	 dd!lmJZK d" ZJeIj                   eJ_          G d# d$eL      ZMd% ZNd& ZOd_d'ZPd( ZQd) ZRd* ZSd^d+ZTd^d,ZUd`d-ZVd^d.ZWdad/ZXd0d1d2ZYd^d3ZZd4 Z[d5 Z\d6 Z]d7 Z^d8 Z_d9 Z`d: Zad; Zbd< Zcd= Zdd> Zed? Zfdbd@ZgdA ZhdddBZie.dCk\  rddDlmjZk dddEZjeij                   ej_         neiZjdF ZlemenffdGZodH ZpdI ZqdJ ZrdK Zs et ehdL            ZudM ZvdN ZwdO ZxdP ZydQ Zzg dRZ{e
dS        Z|dT Z} ej                         jT                  ZdU ZdV ZdW ZdX ZdY ZdZ Zdd[d\Zy# e4$ r e2Z3Y ow xY w# e7$ r d Z6Y ww xY w# e7$ r dZ:Y zw xY w# e7$ r eIZJY =w xY w)ca  Imported from the recipes section of the itertools documentation.

All functions taken from the recipes section of the itertools library docs
[1]_.
Some backward-compatible usability improvements have been made.

.. [1] http://docs.python.org/library/itertools.html#recipes

    N)bisect_leftinsort)dequesuppress)	lru_cachepartialreduce)heappushheappushpop)
accumulatechaincombinationscompresscountcyclegroupbyisliceproductrepeatstarmap	takewhileteezip_longest)prodcombisqrtgcd)mulnot_
itemgettergetitemindex)	randrangesamplechoice)
hexversion)2	all_equalbatchedbefore_and_afterconsumeconvolve
dotproduct
first_truefactorflattengrouperis_primeiter_except
iter_indexloopsmatmulmultinomialncyclesnthnth_combinationpadnonepad_nonepairwise	partitionpolynomial_evalpolynomial_from_rootspolynomial_derivativepowersetprependquantifyreshape#random_combination_with_replacementrandom_combinationrandom_permutationrandom_product
repeatfunc
roundrobinrunning_mediansievesliding_window	subslicessum_of_squarestabulatetailtaketotient	transpose
triplewiseuniqueunique_everseenunique_justseenTstrict)sumprodc                     t        | |      S N)r-   )xys     X/opt/services/ai/voice_agent/venv/lib/python3.12/site-packages/more_itertools/recipes.py<lambda>rb   l   s    Jq!,     )heappush_maxheappushpop_maxFc                 ,    t        t        ||             S )zReturn first *n* items of the *iterable* as a list.

        >>> take(3, range(10))
        [0, 1, 2]

    If there are fewer than *n* items in the iterable, all of them are
    returned.

        >>> take(10, range(3))
        [0, 1, 2]

    )listr   )niterables     ra   rS   rS   x   s     x#$$rc   c                 ,    t        | t        |            S )a  Return an iterator over the results of ``func(start)``,
    ``func(start + 1)``, ``func(start + 2)``...

    *func* should be a function that accepts one integer argument.

    If *start* is not specified it defaults to 0. It will be incremented each
    time the iterator is advanced.

        >>> square = lambda x: x ** 2
        >>> iterator = tabulate(square, -3)
        >>> take(4, iterator)
        [9, 4, 1, 0]

    )mapr   )functionstarts     ra   rQ   rQ      s     xu&&rc   c                     	 t        |      }t        |t        d|| z
        d      S # t        $ r t	        t        ||             cY S w xY w)zReturn an iterator over the last *n* items of *iterable*.

    >>> t = tail(3, 'ABCDEFG')
    >>> list(t)
    ['E', 'F', 'G']

    r   Nmaxlen)lenr   max	TypeErroriterr   )rh   ri   sizes      ra   rR   rR      sO    88} hAtax 0$77  /E(1-../s   ' A	A	c                 R    |t        | d       yt        t        | ||      d       y)aX  Advance *iterable* by *n* steps. If *n* is ``None``, consume it
    entirely.

    Efficiently exhausts an iterator without returning values. Defaults to
    consuming the whole iterator, but an optional second argument may be
    provided to limit consumption.

        >>> i = (x for x in range(10))
        >>> next(i)
        0
        >>> consume(i, 3)
        >>> next(i)
        4
        >>> consume(i)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    If the iterator has fewer items remaining than the provided limit, the
    whole iterator will be consumed.

        >>> i = (x for x in range(3))
        >>> consume(i, 5)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    Nr   ro   )r   nextr   )iteratorrh   s     ra   r+   r+      s)    @ 	yhq! 	VHa#T*rc   c                 0    t        t        | |d      |      S )zReturns the nth item or a default value.

    >>> l = range(10)
    >>> nth(l, 3)
    3
    >>> nth(l, 20, "zebra")
    'zebra'

    N)rw   r   )ri   rh   defaults      ra   r9   r9      s     xD)733rc   c                 >    t        | |      }|D ]  }|D ]  }  y  y y)a  
    Returns ``True`` if all the elements are equal to each other.

        >>> all_equal('aaaa')
        True
        >>> all_equal('aaab')
        False

    A function that accepts a single argument and returns a transformed version
    of each input item can be specified with *key*:

        >>> all_equal('AaaA', key=str.casefold)
        True
        >>> all_equal([1, 2, 3], key=lambda x: x < 10)
        True

    FT)r   )ri   keyrx   firstseconds        ra   r(   r(      s9    $ x%H  	F	 rc   c                 ,    t        t        ||             S )zcReturn the how many times the predicate is true.

    >>> quantify([True, False, True])
    2

    )sumrk   )ri   preds     ra   rD   rD      s     s4"##rc   c                 ,    t        | t        d            S )a   Returns the sequence of elements and then returns ``None`` indefinitely.

        >>> take(5, pad_none(range(3)))
        [0, 1, 2, None, None]

    Useful for emulating the behavior of the built-in :func:`map` function.

    See also :func:`padded`.

    N)r   r   ri   s    ra   r<   r<     s     6$<((rc   c                 R    t        j                  t        t        |       |            S )zvReturns the sequence elements *n* times

    >>> list(ncycles(["a", "b"], 3))
    ['a', 'b', 'a', 'b', 'a', 'b']

    )r   from_iterabler   tupleri   rh   s     ra   r8   r8     s      veHoq9::rc   c                 6    t        t        t        | |            S )zReturns the dot product of the two iterables.

    >>> dotproduct([10, 15, 12], [0.65, 0.80, 1.25])
    33.5
    >>> 10 * 0.65 + 15 * 0.80 + 12 * 1.25
    33.5

    In Python 3.12 and later, use ``math.sumprod()`` instead.
    )r   rk   r   )vec1vec2s     ra   r-   r-     s     s3d#$$rc   c                 ,    t        j                  |       S )zReturn an iterator flattening one level of nesting in a list of lists.

        >>> list(flatten([[0, 1], [2, 3]]))
        [0, 1, 2, 3]

    See also :func:`collapse`, which can flatten multiple levels of nesting.

    )r   r   )listOfListss    ra   r0   r0   +  s     {++rc   c                 \    |t        | t        |            S t        | t        ||            S )aG  Call *func* with *args* repeatedly, returning an iterable over the
    results.

    If *times* is specified, the iterable will terminate after that many
    repetitions:

        >>> from operator import add
        >>> times = 4
        >>> args = 3, 5
        >>> list(repeatfunc(add, times, *args))
        [8, 8, 8, 8]

    If *times* is ``None`` the iterable will not terminate:

        >>> from random import randrange
        >>> times = None
        >>> args = 1, 11
        >>> take(6, repeatfunc(randrange, times, *args))  # doctest:+SKIP
        [2, 4, 8, 1, 8, 4]

    )r   r   )functimesargss      ra   rJ   rJ   7  s.    , }tVD\**4e,--rc   c                 N    t        |       \  }}t        |d       t        ||      S )zReturns an iterator of paired items, overlapping, from the original

    >>> take(4, pairwise(count()))
    [(0, 1), (1, 2), (2, 3), (3, 4)]

    On Python 3.10 and above, this is an alias for :func:`itertools.pairwise`.

    Nr   rw   zip)ri   abs      ra   	_pairwiser   R  s&     x=DAqDMq!9rc   )r=   c                     t        |       S r^   )itertools_pairwiser   s    ra   r=   r=   f  s    !(++rc   c                         e Zd Zd fd	Z xZS )UnequalIterablesErrorc                 P    d}|| dj                   | z  }t        | 	  |       y )Nz Iterables have different lengthsz/: index 0 has length {}; index {} has length {})formatsuper__init__)selfdetailsmsg	__class__s      ra   r   zUnequalIterablesError.__init__m  s;    0MEMM C 	rc   r^   )__name__
__module____qualname__r   __classcell__)r   s   @ra   r   r   l  s     rc   r   c              #   n   K   t        | dt        iD ]  }|D ]  }|t        u st                | ! y w)N	fillvalue)r   _markerr   )	iterablescombovals      ra   _zip_equal_generatorr   w  sE     i;7;  	.Cg~+--	. 	s    55c                      	 t        | d         }t        | dd  d      D ]$  \  }}t        |      }||k7  st        |||f       t        |  S # t        $ r t        |       cY S w xY w)Nr      )r   )rq   	enumerater   r   rs   r   )r   
first_sizeiitru   s        ra   
_zip_equalr     s    /1&
y}a0 	KEArr7Dz!+ZD4IJJ	K
 I  /#I../s   3A A A%$A%c                     t        |       g|z  }|dk(  rt        |d|iS |dk(  rt        | S |dk(  rt        | S t	        d      )a  Group elements from *iterable* into fixed-length groups of length *n*.

    >>> list(grouper('ABCDEF', 3))
    [('A', 'B', 'C'), ('D', 'E', 'F')]

    The keyword arguments *incomplete* and *fillvalue* control what happens for
    iterables whose length is not a multiple of *n*.

    When *incomplete* is `'fill'`, the last group will contain instances of
    *fillvalue*.

    >>> list(grouper('ABCDEFG', 3, incomplete='fill', fillvalue='x'))
    [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]

    When *incomplete* is `'ignore'`, the last group will not be emitted.

    >>> list(grouper('ABCDEFG', 3, incomplete='ignore', fillvalue='x'))
    [('A', 'B', 'C'), ('D', 'E', 'F')]

    When *incomplete* is `'strict'`, a subclass of `ValueError` will be raised.

    >>> iterator = grouper('ABCDEFG', 3, incomplete='strict')
    >>> list(iterator)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
    ...
    UnequalIterablesError

    fillr   r[   ignorez Expected fill, strict, or ignore)rt   r   r   r   
ValueError)ri   rh   
incompleter   	iteratorss        ra   r1   r1     s^    : h 1$IVI;;;X9%%XI;<<rc   c               '      K   t        t        |       }t        t        |       dd      D ]/  }t	        t        ||            }t        t        |      E d{    1 y7 w)aG  Visit input iterables in a cycle until each is exhausted.

        >>> list(roundrobin('ABC', 'D', 'EF'))
        ['A', 'D', 'E', 'B', 'F', 'C']

    This function produces the same output as :func:`interleave_longest`, but
    may perform better for some inputs (in particular when the number of
    iterables is small).

    r   N)rk   rt   rangerq   r   r   rw   )r   r   
num_actives      ra   rK   rK     sT      D)$IC	NAr2 (
&J78	tY'''('s   AAAAc                     | t         } t        |d      \  }}}t        t        | |            \  }}t        |t        t        |            t        ||      fS )a  
    Returns a 2-tuple of iterables derived from the input iterable.
    The first yields the items that have ``pred(item) == False``.
    The second yields the items that have ``pred(item) == True``.

        >>> is_odd = lambda x: x % 2 != 0
        >>> iterable = range(10)
        >>> even_items, odd_items = partition(is_odd, iterable)
        >>> list(even_items), list(odd_items)
        ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])

    If *pred* is None, :func:`bool` is used.

        >>> iterable = [0, 1, False, True, '', ' ']
        >>> false_items, true_items = partition(None, iterable)
        >>> list(false_items), list(true_items)
        ([0, False, ''], [1, True, ' '])

       )boolr   rk   r   r    )r   ri   t1t2pp1p2s          ra   r>   r>     sS    ( |Ha IBAT1FBRT2'"b)9::rc   c                     t        |       t        j                  fdt        t	              dz         D              S )a1  Yields all possible subsets of the iterable.

        >>> list(powerset([1, 2, 3]))
        [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

    :func:`powerset` will operate on iterables that aren't :class:`set`
    instances, so repeated elements in the input will produce repeated elements
    in the output.

        >>> seq = [1, 1, 0]
        >>> list(powerset(seq))
        [(), (1,), (1,), (0,), (1, 1), (1, 0), (1, 0), (1, 1, 0)]

    For a variant that efficiently yields actual :class:`set` instances, see
    :func:`powerset_of_sets`.
    c              3   6   K   | ]  }t        |        y wr^   )r   ).0rss     ra   	<genexpr>zpowerset.<locals>.<genexpr>  s     Ma|Aq1M   r   )rg   r   r   r   rq   )ri   r   s    @ra   rB   rB     s2    " 	XAM5Q!;LMMMrc   c              #      K   t               }|j                  }g }|j                  }|du}| D ]  }|r ||      n|}	 ||vr ||       | ! y# t        $ r ||vr ||       | Y >w xY ww)a  
    Yield unique elements, preserving order.

        >>> list(unique_everseen('AAAABBBCCDAABBB'))
        ['A', 'B', 'C', 'D']
        >>> list(unique_everseen('ABBCcAD', str.lower))
        ['A', 'B', 'C', 'D']

    Sequences with a mix of hashable and unhashable items can be used.
    The function will be slower (i.e., `O(n^2)`) for unhashable items.

    Remember that ``list`` objects are unhashable - you can use the *key*
    parameter to transform the list to a tuple (which is hashable) to
    avoid a slowdown.

        >>> iterable = ([1, 2], [2, 3], [1, 2])
        >>> list(unique_everseen(iterable))  # Slow
        [[1, 2], [2, 3]]
        >>> list(unique_everseen(iterable, key=tuple))  # Faster
        [[1, 2], [2, 3]]

    Similarly, you may want to convert unhashable ``set`` objects with
    ``key=frozenset``. For ``dict`` objects,
    ``key=lambda x: frozenset(x.items())`` can be used.

    N)setaddappendrs   )	ri   r|   seensetseenset_addseenlistseenlist_adduse_keyelementks	            ra   rX   rX     s     6 eG++KH??LoG 	#CL	A	  	 Q	s(   :A/AA/A,)A/+A,,A/c           
          |t        t        d      t        |             S t        t        t        t        d      t        | |                  S )zYields elements in order, ignoring serial duplicates

    >>> list(unique_justseen('AAAABBBCCDAABBB'))
    ['A', 'B', 'C', 'D', 'A', 'B']
    >>> list(unique_justseen('ABBCcAD', str.lower))
    ['A', 'B', 'C', 'A', 'D']

    r   r   )rk   r!   r   rw   )ri   r|   s     ra   rY   rY   '  s>     {:a='("344tSA#(>?@@rc   c                 8    t        | ||      }t        ||      S )a  Yields unique elements in sorted order.

    >>> list(unique([[1, 2], [3, 4], [1, 2]]))
    [[1, 2], [3, 4]]

    *key* and *reverse* are passed to :func:`sorted`.

    >>> list(unique('ABBcCAD', str.casefold))
    ['A', 'B', 'c', 'D']
    >>> list(unique('ABBcCAD', str.casefold, reverse=True))
    ['D', 'c', 'B', 'A']

    The elements in *iterable* need not be hashable, but they must be
    comparable for sorting to work.
    )r|   reverse)r|   )sortedrY   )ri   r|   r   	sequenceds       ra   rW   rW   6  s      xS':I9#..rc   c              #   f   K   t        |      5  |	 |        	  |         
# 1 sw Y   yxY ww)a  Yields results from a function repeatedly until an exception is raised.

    Converts a call-until-exception interface to an iterator interface.
    Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel
    to end the loop.

        >>> l = [0, 1, 2]
        >>> list(iter_except(l.pop, IndexError))
        [2, 1, 0]

    Multiple exceptions can be specified as a stopping condition:

        >>> l = [1, 2, 3, '...', 4, 5, 6]
        >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError)))
        [7, 6, 5]
        >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError)))
        [4, 3, 2]
        >>> list(iter_except(lambda: 1 + l.pop(), (IndexError, TypeError)))
        []

    Nr   )r   	exceptionr}   s      ra   r3   r3   J  s;     , 
)	 'M&L  s   1%.1c                 .    t        t        ||       |      S )a  
    Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item for which
    ``pred(item) == True`` .

        >>> first_true(range(10))
        1
        >>> first_true(range(10), pred=lambda x: x > 5)
        6
        >>> first_true(range(10), default='missing', pred=lambda x: x > 9)
        'missing'

    )rw   filter)ri   rz   r   s      ra   r.   r.   g  s    " tX&00rc   r   r   c                 h    |D cg c]  }t        |       c}| z  }t        d |D              S c c}w )a  Draw an item at random from each of the input iterables.

        >>> random_product('abc', range(4), 'XYZ')  # doctest:+SKIP
        ('c', 3, 'Z')

    If *repeat* is provided as a keyword argument, that many items will be
    drawn from each iterable.

        >>> random_product('abcd', range(4), repeat=2)  # doctest:+SKIP
        ('a', 2, 'd', 3)

    This equivalent to taking a random selection from
    ``itertools.product(*args, repeat=repeat)``.

    c              3   2   K   | ]  }t        |        y wr^   )r&   )r   pools     ra   r   z!random_product.<locals>.<genexpr>  s     0$0s   )r   )r   r   r   poolss       ra   rI   rI   {  s3      &**TU4[*V3E0%000 +s   /c                 `    t        |       }|t        |      n|}t        t        ||            S )ab  Return a random *r* length permutation of the elements in *iterable*.

    If *r* is not specified or is ``None``, then *r* defaults to the length of
    *iterable*.

        >>> random_permutation(range(5))  # doctest:+SKIP
        (3, 4, 0, 1, 2)

    This equivalent to taking a random selection from
    ``itertools.permutations(iterable, r)``.

    )r   rq   r%   )ri   r   r   s      ra   rH   rH     s-     ?DYD	AAa!!rc   c                     t        |       t              }t        t        t	        |      |            }t        fd|D              S )zReturn a random *r* length subsequence of the elements in *iterable*.

        >>> random_combination(range(5), 3)  # doctest:+SKIP
        (2, 3, 4)

    This equivalent to taking a random selection from
    ``itertools.combinations(iterable, r)``.

    c              3   (   K   | ]	  }|     y wr^    r   r   r   s     ra   r   z%random_combination.<locals>.<genexpr>       *Qa*   )r   rq   r   r%   r   )ri   r   rh   indicesr   s       @ra   rG   rG     s=     ?DD	AVE!Ha()G*'***rc   c                     t        |       t              t        fdt        |      D              }t        fd|D              S )aS  Return a random *r* length subsequence of elements in *iterable*,
    allowing individual elements to be repeated.

        >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP
        (0, 0, 1, 2, 2)

    This equivalent to taking a random selection from
    ``itertools.combinations_with_replacement(iterable, r)``.

    c              3   4   K   | ]  }t                y wr^   )r$   r   r   rh   s     ra   r   z6random_combination_with_replacement.<locals>.<genexpr>  s     4aYq\4s   c              3   (   K   | ]	  }|     y wr^   r   r   s     ra   r   z6random_combination_with_replacement.<locals>.<genexpr>  r   r   )r   rq   r   r   )ri   r   r   rh   r   s      @@ra   rF   rF     s<     ?DD	A45844G*'***rc   c                    t        |       }t        |      }|dk  s||kD  rt        d}t        |||z
        }t	        d|dz         D ]  }|||z
  |z   z  |z  } |dk  r||z  }|dk  s||k\  rt
        g }|rL||z  |z  |dz
  |dz
  }}}||k\  r||z  }|||z
  z  |z  |dz
  }}||k\  r|j                  |d|z
            |rLt        |      S )a  Equivalent to ``list(combinations(iterable, r))[index]``.

    The subsequences of *iterable* that are of length *r* can be ordered
    lexicographically. :func:`nth_combination` computes the subsequence at
    sort position *index* directly, without computing the previous
    subsequences.

        >>> nth_combination(range(5), 3, 5)
        (0, 3, 4)

    ``ValueError`` will be raised If *r* is negative or greater than the length
    of *iterable*.
    ``IndexError`` will be raised if the given *index* is invalid.
    r   r   r   )r   rq   r   minr   
IndexErrorr   )	ri   r   r#   r   rh   cr   r   results	            ra   r:   r:     s    ?DD	A	A1q5	AAq1uA1a!e_ !QOq ! qy
	uzF
a%1*a!eQUa1qjQJEA;!#QUqA qj 	d26l#  =rc   c                     t        | g|      S )a  Yield *value*, followed by the elements in *iterator*.

        >>> value = '0'
        >>> iterator = ['1', '2', '3']
        >>> list(prepend(value, iterator))
        ['0', '1', '2', '3']

    To prepend multiple values, see :func:`itertools.chain`
    or :func:`value_chain`.

    )r   )valuerx   s     ra   rC   rC     s     %(##rc   c              #      K   t        |      ddd   }t        |      }t        dg|      |z  }t        | t	        d|dz
              D ]!  }|j                  |       t        ||       # yw)u}  Discrete linear convolution of two iterables.
    Equivalent to polynomial multiplication.

    For example, multiplying ``(x² -x - 20)`` by ``(x - 3)``
    gives ``(x³ -4x² -17x + 60)``.

        >>> list(convolve([1, -1, -20], [1, -3]))
        [1, -4, -17, 60]

    Examples of popular kinds of kernels:

    * The kernel ``[0.25, 0.25, 0.25, 0.25]`` computes a moving average.
      For image data, this blurs the image and reduces noise.
    * The kernel ``[1/2, 0, -1/2]`` estimates the first derivative of
      a function evaluated at evenly spaced inputs.
    * The kernel ``[1, -2, 1]`` estimates the second derivative of a
      function evaluated at evenly spaced inputs.

    Convolutions are mathematically commutative; however, the inputs are
    evaluated differently.  The signal is consumed lazily and can be
    infinite. The kernel is fully consumed before the calculations begin.

    Supports all numeric types: int, float, complex, Decimal, Fraction.

    References:

    * Article:  https://betterexplained.com/articles/intuitive-convolution/
    * Video by 3Blue1Brown:  https://www.youtube.com/watch?v=KuXjwB4LzSA

    Nr   r   ro   r   )r   rq   r   r   r   r   _sumprod)signalkernelrh   windowr_   s        ra   r,   r,     sq     F 6]4R4 FFAA3q!A%F66!QU+, 'avv&&'s   A,A.c                 d    t        |      \  }}t        t        | |      t        |            }||fS )a  A variant of :func:`takewhile` that allows complete access to the
    remainder of the iterator.

         >>> it = iter('ABCdEfGhI')
         >>> all_upper, remainder = before_and_after(str.isupper, it)
         >>> ''.join(all_upper)
         'ABC'
         >>> ''.join(remainder) # takewhile() would lose the 'd'
         'dEfGhI'

    Note that the first iterator must be fully consumed before the second
    iterator can generate valid results.
    )r   r   r   r   )	predicater   truesafters       ra   r*   r*   &  s2     r7LE5Yy%0#e*=E%<rc   c                     t        | d      \  }}}t        |d       t        |d       t        |d       t        |||      S )zReturn overlapping triplets from *iterable*.

    >>> list(triplewise('ABCDE'))
    [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E')]

    r   Nr   )ri   r   r   t3s       ra   rV   rV   9  s?     Xq!JBBTNTNTNr2r?rc   c                 ~    t        | |      }t        |      D ]  \  }}t        t        |||      d         t	        | S r^   )r   r   rw   r   r   )ri   rh   r   r   rx   s        ra   _sliding_window_islicer  I  sC    Ha I + +8VHa#T*+	?rc   c              #      K   t        |       }t        t        ||dz
        |      }|D ]   }|j                  |       t	        |       " y w)Nr   ro   )rt   r   r   r   r   )ri   rh   rx   r   r_   s        ra   _sliding_window_dequer  Q  sK     H~H6(AE*15F aFms   AAc                     |dkD  rt        | |      S |dkD  rt        | |      S |dk(  rt        |       S |dk(  rt        |       S t	        d|       )aY  Return a sliding window of width *n* over *iterable*.

        >>> list(sliding_window(range(6), 4))
        [(0, 1, 2, 3), (1, 2, 3, 4), (2, 3, 4, 5)]

    If *iterable* has fewer than *n* items, then nothing is yielded:

        >>> list(sliding_window(range(3), 4))
        []

    For a variant with more features, see :func:`windowed`.
          r   zn should be at least one, not )r  r  r=   r   r   r   s     ra   rN   rN   Z  sb     	2v$Xq11	
Q%h22	
a!!	
a8}9!=>>rc   c           
          t        |       }t        t        t        t	        t        |      dz         d            }t        t        t        |      |      S )zReturn all contiguous non-empty subslices of *iterable*.

        >>> list(subslices('ABC'))
        [['A'], ['A', 'B'], ['A', 'B', 'C'], ['B'], ['B', 'C'], ['C']]

    This is similar to :func:`substrings`, but emits items in a different
    order.
    r   r  )	rg   r   slicer   r   rq   rk   r"   r   )ri   seqslicess      ra   rO   rO   s  s@     x.CULs3x!|)<a@AFwsV,,rc   c                 J    dg}| D ]  }t        t        |d| f            } |S )uk  Compute a polynomial's coefficients from its roots.

    >>> roots = [5, -4, 3]            # (x - 5) * (x + 4) * (x - 3)
    >>> polynomial_from_roots(roots)  # x³ - 4 x² - 17 x + 60
    [1, -4, -17, 60]

    Note that polynomial coefficients are specified in descending power order.

    Supports all numeric types: int, float, complex, Decimal, Fraction.
    r   )rg   r,   )rootspolyroots      ra   r@   r@     s6      3D 0HTAu:./0Krc   c              #     K   t        | dd      }|0t        | ||      }t        ||      D ]  \  }}||u s||k(  s|  y|t        |       n|}|dz
  }t	        t
              5  	  |||dz   |      x} # 1 sw Y   yxY ww)a  Yield the index of each place in *iterable* that *value* occurs,
    beginning with index *start* and ending before index *stop*.


    >>> list(iter_index('AABCADEAF', 'A'))
    [0, 1, 4, 7]
    >>> list(iter_index('AABCADEAF', 'A', 1))  # start index is inclusive
    [1, 4, 7]
    >>> list(iter_index('AABCADEAF', 'A', 1, 7))  # stop index is not inclusive
    [1, 4]

    The behavior for non-scalar *values* matches the built-in Python types.

    >>> list(iter_index('ABCDABCD', 'AB'))
    [0, 4]
    >>> list(iter_index([0, 1, 2, 3, 0, 1, 2, 3], [0, 1]))
    []
    >>> list(iter_index([[0, 1], [2, 3], [0, 1], [2, 3]], [0, 1]))
    [0, 2]

    See :func:`locate` for a more general means of finding the indexes
    associated with particular values.

    r#   Nr   )getattrr   r   rq   r   r   )ri   r   rm   stop	seq_indexrx   r   r   s           ra   r4   r4     s     2 '40I(E40#He4 	JAw%7e#3	
 !%s8}$AIj! 	;%eQUD99q: 	; 	;s   8B*B%A99B>Bc              #   T  K   | dkD  rd d}t        d      | dz  z  }t        |d|t        |       dz         D ]Q  }t        |d|||z        E d{    t        t	        t        ||z  | ||z                     |||z  | ||z   <   ||z  }S t        |d|      E d{    y7 R7 w)zeYield the primes less than n.

    >>> list(sieve(30))
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

    r  r   )r   r   r   )r  N)	bytearrayr4   r   bytesrq   r   )rh   rm   datar   s       ra   rM   rM     s      	1uEVQ'DaU1X\: dAua!e444"'E!a%AE,B(C"DQUQQA $5))) 	5 *s%   AB(B$AB(B&B(&B(c             #      K   |dk  rt        d      t        |       }t        t        ||            x}r8|rt	        |      |k7  rt        d      | t        t        ||            x}r7yyw)a  Batch data into tuples of length *n*. If the number of items in
    *iterable* is not divisible by *n*:
    * The last batch will be shorter if *strict* is ``False``.
    * :exc:`ValueError` will be raised if *strict* is ``True``.

    >>> list(batched('ABCDEFG', 3))
    [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]

    On Python 3.13 and above, this is an alias for :func:`itertools.batched`.
    r   zn must be at least onezbatched(): incomplete batchN)r   rt   r   r   rq   )ri   rh   r[   rx   batchs        ra   _batchedr    sr      	1u122H~H!,-
-%
-c%jAo:;; !,-
-%
-s   A)A.,A.i )r)   c                    t        | ||      S )NrZ   )itertools_batched)ri   rh   r[   s      ra   r)   r)     s     1V<<rc   c                     t        |  S )a  Swap the rows and columns of the input matrix.

    >>> list(transpose([(1, 2, 3), (11, 22, 33)]))
    [(1, 11), (2, 22), (3, 33)]

    The caller should ensure that the dimensions of the input are compatible.
    If the input is empty, no output will be produced.
    )_zip_strictr   s    ra   rU   rU     s     rc   c                 P    	 t        |        t        | |      S # t        $ r Y yw xY w)z.Scalars are bytes, strings, and non-iterables.T)rt   rs   
isinstance)r   
stringlikes     ra   
_is_scalarr'     s1    U eZ((  s    	%%c                     t        |       }	 	 t        |      }t        |f|      }t	        |      r|S t        j
                  |      }<# t        $ r |cY S w xY w)z.Depth-first iterator over scalars in a tensor.)rt   rw   StopIterationr   r'  r   )tensorrx   r   s      ra   _flatten_tensorr+  	  sd    F|H
	NE %8,eO&&x0   	O	s   A	 	AAc                     t        |t              rt        t        j                  |       |      S |^}}t        |       }t        t        t        |      |      }t        ||      S )a  Change the shape of a *matrix*.

    If *shape* is an integer, the matrix must be two dimensional
    and the shape is interpreted as the desired number of columns:

        >>> matrix = [(0, 1), (2, 3), (4, 5)]
        >>> cols = 3
        >>> list(reshape(matrix, cols))
        [(0, 1, 2), (3, 4, 5)]

    If *shape* is a tuple (or other iterable), the input matrix can have
    any number of dimensions. It will first be flattened and then rebuilt
    to the desired shape which can also be multidimensional:

        >>> matrix = [(0, 1), (2, 3), (4, 5)]    # Start with a 3 x 2 matrix

        >>> list(reshape(matrix, (2, 3)))        # Make a 2 x 3 matrix
        [(0, 1, 2), (3, 4, 5)]

        >>> list(reshape(matrix, (6,)))          # Make a vector of length six
        [0, 1, 2, 3, 4, 5]

        >>> list(reshape(matrix, (2, 1, 3, 1)))  # Make 2 x 1 x 3 x 1 tensor
        [(((0,), (1,), (2,)),), (((3,), (4,), (5,)),)]

    Each dimension is assumed to be uniform, either all arrays or all scalars.
    Flattening stops when the first value in a dimension is a scalar.
    Scalars are bytes, strings, and non-iterables.
    The reshape iterator stops when the requested shape is complete
    or when the input is exhausted, whichever comes first.

    )	r%  intr)   r   r   r+  r
   reversedr   )matrixshape	first_dimdimsscalar_streamreshapeds         ra   rE   rE     sZ    B %u**62E::I#F+Mgx~}=H(I&&rc   c                 x    t        |d         }t        t        t        t	        | t        |                  |      S )a#  Multiply two matrices.

    >>> list(matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]))
    [(49, 80), (41, 60)]

    The caller should ensure that the dimensions of the input matrices are
    compatible with each other.

    Supports all numeric types: int, float, complex, Decimal, Fraction.
    r   )rq   r)   r   r   r   rU   )m1m2rh   s      ra   r6   r6   @  s0     	BqE
A78WR2%?@!DDrc   c                     t        d|       D ]L  }dx}}d}|dk(  r6||z  |z   | z  }||z  |z   | z  }||z  |z   | z  }t        ||z
  |       }|dk(  r6|| k7  sJ|c S  t        d      )Nr   r  zprime or under 5)r   r   r   )rh   r   r_   r`   ds        ra   _factor_pollardr:  O  s     1a[ 		A1fQaAQaAQaAAE1A	 1f
 6H	 '
((rc      c              #     K   | dk  ryt         D ]  }| |z  r	| | |z  } | |z  s g }| dkD  r| gng }|D ]9  } | dk  st        |       r|j                  |        %t        |       }||| |z  fz  }; t	        |      E d{    y7 w)a  Yield the prime factors of n.

    >>> list(factor(360))
    [2, 2, 2, 3, 3, 5]

    Finds small factors with trial division.  Larger factors are
    either verified as prime with ``is_prime`` or split into
    smaller factors with Pollard's rho algorithm.
    r  Nr   i  )_primes_below_211r2   r   r:  r   )rh   primeprimestodofacts        ra   r/   r/   b  s      	1u # e)K%KA e) Fa%A3RD &v:!MM!"1%DT19%%D& f~s   B	B	AB	BB	c           	          t        |       }|dk(  r t        |      d      S t        t        t	        |      t        t        |                  }t        | |      S )a  Evaluate a polynomial at a specific value.

    Computes with better numeric stability than Horner's method.

    Evaluate ``x^3 - 4 * x^2 - 17 * x + 60`` at ``x = 2.5``:

    >>> coefficients = [1, -4, -17, 60]
    >>> x = 2.5
    >>> polynomial_eval(coefficients, x)
    8.125

    Note that polynomial coefficients are specified in descending power order.

    Supports all numeric types: int, float, complex, Decimal, Fraction.
    r   )rq   typerk   powr   r.  r   r   )coefficientsr_   rh   powerss       ra   r?   r?     sM      	LAAvtAwqzfQi%(!34FL&))rc   c                 $    t        t        |        S )zReturn the sum of the squares of the input values.

    >>> sum_of_squares([10, 20, 30])
    1400

    Supports all numeric types: int, float, complex, Decimal, Fraction.
    )r   r   r#  s    ra   rP   rP     s     SWrc   c                 v    t        |       }t        t        d|            }t        t	        t
        | |            S )u  Compute the first derivative of a polynomial.

    Evaluate the derivative of ``x³ - 4 x² - 17 x + 60``:

    >>> coefficients = [1, -4, -17, 60]
    >>> derivative_coefficients = polynomial_derivative(coefficients)
    >>> derivative_coefficients
    [3, -8, -17]

    Note that polynomial coefficients are specified in descending power order.

    Supports all numeric types: int, float, complex, Decimal, Fraction.
    r   )rq   r.  r   rg   rk   r   )rE  rh   rF  s      ra   rA   rA     s2     	LAeAqk"FCv.//rc   c                 H    t        t        |             D ]
  }| | |z  z  }  | S )u  Return the count of natural numbers up to *n* that are coprime with *n*.

    Euler's totient function φ(n) gives the number of totatives.
    Totative are integers k in the range 1 ≤ k ≤ n such that gcd(n, k) = 1.

    >>> n = 9
    >>> totient(n)
    6

    >>> totatives = [x for x in range(1, n) if gcd(n, x) == 1]
    >>> totatives
    [1, 2, 4, 5, 7, 8]
    >>> len(totatives)
    6

    Reference:  https://en.wikipedia.org/wiki/Euler%27s_totient_function

    )r   r/   )rh   r>  s     ra   rT   rT     s-    & VAY 	Q%ZHrc   ))i  )r  )i )   I   )l   tT7 )r     =   )l   ay)r        iS_ )l   ;n>)r  r      rL     )l   p)r  r   rP  rL  rQ  rN  )l            )r  iE  i$  in  i i= ik)l   %!HnfW )r  r   rP  rL  rQ  rN        rO     rJ  %   )   c                 t    | dz
  | z  j                         dz
  }| |z	  }d|z  |z  | k(  r
|dz  r|dk\  sJ ||fS )z#Return s, d such that 2**s * d == nr   r   )
bit_length)rh   r   r9  s      ra   _shift_to_oddrY    sS     a%1  "Q&A	QAFa<1Q1611a4Krc   c                     | dkD  r| dz  rd|cxk  r| k  sJ  J t        | dz
        \  }}t        |||       }|dk(  s|| dz
  k(  ryt        |dz
        D ]  }||z  | z  }|| dz
  k(  s y y)Nr  r   TF)rY  rD  r   )rh   baser   r9  r_   _s         ra   _strong_probable_primer]    s    EAAMM22M22QDAqD!QAAva!e1q5\ EAIA:
 rc   c                       dk  r dv S  dz  r dz  r dz  r dz  r
 dz  r dz  sy	t         D ]  \  }} |k  s n  fd
t        d      D        }t         fd|D              S )a  Return ``True`` if *n* is prime and ``False`` otherwise.

    Basic examples:

        >>> is_prime(37)
        True
        >>> is_prime(3 * 13)
        False
        >>> is_prime(18_446_744_073_709_551_557)
        True

    Find the next prime over one billion:

        >>> next(filter(is_prime, count(10**9)))
        1000000007

    Generate random primes up to 200 bits and up to 60 decimal digits:

        >>> from random import seed, randrange, getrandbits
        >>> seed(18675309)

        >>> next(filter(is_prime, map(getrandbits, repeat(200))))
        893303929355758292373272075469392561129886005037663238028407

        >>> next(filter(is_prime, map(randrange, repeat(10**60))))
        269638077304026462407872868003560484232362454342414618963649

    This function is exact for values of *n* below 10**24.  For larger inputs,
    the probabilistic Miller-Rabin primality test has a less than 1 in 2**128
    chance of a false positive.
    rR  >   r  r   rP  rL  rQ  rN  r   r   rP  rL  rQ  rN  Fc              3   <   K   | ]  }t        d dz
          yw)r  r   N)_private_randranger   s     ra   r   zis_prime.<locals>.<genexpr>*  s     A!#Aq1u-As   @   c              3   6   K   | ]  }t        |        y wr^   )r]  )r   r[  rh   s     ra   r   zis_prime.<locals>.<genexpr>,  s     A4%a.Ar   )_perfect_testsr   all)rh   limitbasess   `  ra   r2   r2     s    B 	2v(((Ea!eA!a%AFq2v& Buu9B BuRyAA5AAArc   c                     t        d|       S )zReturns an iterable with *n* elements for efficient looping.
    Like ``range(n)`` but doesn't create integers.

    >>> i = 0
    >>> for _ in loops(5):
    ...     i += 1
    >>> i
    5

    Nr   )rh   s    ra   r5   r5   /  s     $?rc   c                  H    t        t        t        t        |       |             S )u  Number of distinct arrangements of a multiset.

    The expression ``multinomial(3, 4, 2)`` has several equivalent
    interpretations:

    * In the expansion of ``(a + b + c)⁹``, the coefficient of the
      ``a³b⁴c²`` term is 1260.

    * There are 1260 distinct ways to arrange 9 balls consisting of 3 reds, 4
      greens, and 2 blues.

    * There are 1260 unique ways to place 9 distinct objects into three bins
      with sizes 3, 4, and 2.

    The :func:`multinomial` function computes the length of
    :func:`distinct_permutations`.  For example, there are 83,160 distinct
    anagrams of the word "abracadabra":

        >>> from more_itertools import distinct_permutations, ilen
        >>> ilen(distinct_permutations('abracadabra'))
        83160

    This can be computed directly from the letter counts, 5a 2b 2r 1c 1d:

        >>> from collections import Counter
        >>> list(Counter('abracadabra').values())
        [5, 2, 2, 1, 1]
        >>> multinomial(5, 2, 2, 1, 1)
        83160

    A binomial coefficient is a special case of multinomial where there are
    only two categories.  For example, the number of ways to arrange 12 balls
    with 5 reds and 7 blues is ``multinomial(5, 7)`` or ``math.comb(12, 5)``.

    Likewise, factorial is a special case of multinomial where
    the multiplicities are all just 1 so that
    ``multinomial(1, 1, 1, 1, 1, 1, 1) == math.factorial(7)``.

    Reference:  https://en.wikipedia.org/wiki/Multinomial_theorem

    )r   rk   r   r   )countss    ra   r7   r7   =  s    T D*V,f566rc   c           	   #      K   | j                   }g }g }t        t              5  	 t        |t	        | |                    |d    t        |t        | |                    |d   |d   z   dz   N# 1 sw Y   yxY ww)z.Non-windowed running_median() for Python 3.14+r   r  N)__next__r   r)  rd   r   r   re   rx   readlohis       ra   #_running_median_minheap_and_maxheaprp  j  s      D	B	B	-	  &[TV45Q%KRTV45a52a5=A%% & &s    A>AA22A;7A>c           	   #     K   | j                   }g }g }t        t              5  	 t        |t	        | |                     |d     t        |t	        | |                      |d   |d   z
  dz   R# 1 sw Y   yxY ww)zDBackport of non-windowed running_median() for Python 3.13 and prior.r   r  N)rk  r   r)  r   r   rl  s       ra   _running_median_minheap_onlyrr  z  s      D	B	B	-	  &R+b$&112a5&LR+b46'223a52a5=A%% & &s    BAA66A?;Bc              #     K   t               }g }| D ]w  }|j                  |       t        ||       t        |      |kD  rt	        ||j                               }||= t        |      }|dz  }|dz  r||   n||dz
     ||   z   dz   y yw)z+Yield median of values in a sliding window.r  r   N)r   r   r   rq   r   popleft)rx   rp   r   orderedr_   r   rh   ms           ra   _running_median_windowedrw    s      WFG 
Iaww<& GV^^%56A
LFEgajA(Cq'HH
Is   B
Bro   c                    t        |       }|'t        |      }|dk  rt        d      t        ||      S t        st        |      S t        |      S )aD  Cumulative median of values seen so far or values in a sliding window.

    Set *maxlen* to a positive integer to specify the maximum size
    of the sliding window.  The default of *None* is equivalent to
    an unbounded window.

    For example:

        >>> list(running_median([5.0, 9.0, 4.0, 12.0, 8.0, 9.0]))
        [5.0, 7.0, 5.0, 7.0, 8.0, 8.5]
        >>> list(running_median([5.0, 9.0, 4.0, 12.0, 8.0, 9.0], maxlen=3))
        [5.0, 7.0, 5.0, 9.0, 8.0, 9.0]

    Supports numeric types such as int, float, Decimal, and Fraction,
    but not complex numbers which are unorderable.

    On version Python 3.13 and prior, max-heaps are simulated with
    negative values. The negation causes Decimal inputs to apply context
    rounding, making the results slightly different than that obtained
    by statistics.median().
    r   zWindow size should be positive)rt   r#   r   rw  _max_heap_availablerr  rp  )ri   rp   rx   s      ra   rL   rL     sU    . H~HvQ;=>>'&99+H55.x88rc   )r   r^   )r   N)NF)NN)r   N)__doc__randombisectr   r   collectionsr   
contextlibr   	functoolsr   r	   r
   heapqr   r   	itertoolsr   r   r   r   r   r   r   r   r   r   r   r   r   r   mathr   r   r   r   operatorr   r    r!   r"   r#   r$   r%   r&   sysr'   __all__objectr   r   r"  rs   r\   r   ImportErrorrd   re   ry  rS   rQ   rR   r+   r9   r(   r   rD   r<   r;   r8   r-   r0   rJ   r   r=   r   r   r   r   r   r1   rK   r>   rB   rX   rY   rW   r3   r.   rI   rH   rG   rF   r:   rC   r,   r*   rV   r  r  rN   rO   r@   r4   rM   r  r)   r   rU   strr  r'  r+  rE   r6   r:  r   r=  r/   r?   rP   rA   rT   rc  rY  r]  Randomr`  r2   r5   r7   rp  rr  rw  rL   r   rc   ra   <module>r     s    &   0 0 '     ( ' : : , , 3j (,t #d+K-(3 % '$8 %+P
44 ! $) ;
%	,.6	)8
, !((HJ / %=P($;8N**ZA/(:1( "# 1("$+ +"'T$('V& ?2-,&;R** %* ( 6', = &&GOG	 #&u )1&'RE)  %*% B*.0&2  & #V]]_.. -B`*7Z& & I& (, "9w)  K  -,H-    `  HsH   	G; H	 H H& ;HH	HHH#"H#&H10H1