
    <iS                     t   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          Z3n# e4$ r e2Z3Y nw xY w	 ddlm5Z6 n# e7$ r d Z6Y nw xY w	 ddlm8Z8m9Z9 dZ:n# e7$ r dZ:Y nw xY w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_         n# e7$ r eIZJY nw xY w G d# d$eL          ZMd% ZNd& ZOd`d(ZPd) ZQd* ZRd+ ZSd_d,ZTd_d-ZUdad.ZVd_d/ZWdbd0ZXd1d2d3ZYd_d4ZZd5 Z[d6 Z\d7 Z]d8 Z^d9 Z_d: Z`d; Zad< Zbd= Zcd> Zdd? Zed@ ZfdcdAZgdB ZhdddCZie.dDk    rddElmjZk dddFZjeij         ej_         neiZjdG ZlemenffdHZodI ZpdJ ZqdK ZrdL Zs et ehdM                    ZudN ZvdO ZwdP ZxdQ ZydR Zzg dSZ{e
dT             Z|dU Z} ej~                    j*        ZdV ZdW ZdX ZdY ZdZ Zd[ Zdd\d]ZdS )da  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     /Users/kimhansen/Desktop/03 Workspace/ceo-agents/chl-effectiveness/mcp-servers/whoop/.venv/lib/python3.11/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      sr    88}} hAtax 0 0$777  / / /E(1---...../s   3 (AAc                 n    |t          | d           dS t          t          | ||          d           dS )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+      sG    @ 	yhq!!!!!! 	VHa##T*****rc   c                 @    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33rc   c                 D    t          | |          }|D ]}|D ]}  dS  dS dS )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(      sF    $ x%%H   	 	F555tt4rc   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                 `    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%     veHooq99:::rc   c                 H    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  s9    , }tVD\\***4e,,---rc   c                 f    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DMMMq!99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 )UnequalIterablesErrorNc                 l    d}|| dj         | z  }t                                          |           d S )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  sI    0MEM C 	rc   r^   )__name__
__module____qualname__r   __classcell__)r   s   @ra   r   r   l  s=                 rc   r   c              #   r   K   t          | dt          iD ]"}|D ]}|t          u rt                      |V  #d S )N	fillvalue)r   _markerr   )	iterablescombovals      ra   _zip_equal_generatorr   w  s`      i;7;;   	. 	.Cg~~+--- 	 rc   c                  
   	 t          | d                   }t          | dd          d          D ]-\  }}t          |          }||k    r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0 	K 	KEArr77Dz!!+ZD4IJJJJ " I  / / /#I...../s   A#A& &BBfillc                     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

    r   r   r[   ignorez Expected fill, strict, or ignore)rt   r   r   r   
ValueError)ri   rh   
incompleter   	iteratorss        ra   r1   r1     so    : 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{V  ;dS )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     s~       D)$$IC	NNAr22 ( (
&J7788	tY''''''''''( (rc   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, ' '])

    N   )boolr   rk   r   r    )r   ri   t1t2pp1p2s          ra   r>   r>     sc    ( |Ha  IBAT1FBRT2''"b)9)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   8   K   | ]}t          |          V  d S r^   )r   ).0rss     ra   	<genexpr>zpowerset.<locals>.<genexpr>  s-      MMa|Aq11MMMMMMrc   r   )rg   r   r   r   rq   )ri   r   s    @ra   rB   rB     sH    " 	XAMMMM5Q!;L;LMMMMMMrc   c              #      K   t                      }|j        }g }|j        }|du}| D ]H}|r ||          n|}	 ||vr ||           |V  &# t          $ r ||vr ||           |V  Y Ew xY wdS )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 eeG+KH?LoG 	 	#0CCLLL	A 	 	 	  Q		 	s   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']

    Nr   r   )rk   r!   r   rw   )ri   r|   s     ra   rY   rY   '  sQ     {:a=='("3"3444tSA#(>(>??@@@rc   c                 H    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              #   x   K   t          |          5  | |            V  	  |             V  # 1 swxY w Y   dS )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      , 
)		  %''MMM	$&&LLL	         s   /33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00rc   r   r   c                 R    d |D             | z  }t          d |D                       S )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                 ,    g | ]}t          |          S  r   r   pools     ra   
<listcomp>z"random_product.<locals>.<listcomp>  s    ***TU4[[***rc   c              3   4   K   | ]}t          |          V  d S r^   )r&   r   s     ra   r   z!random_product.<locals>.<genexpr>  s(      00$000000rc   r   )r   r   poolss      ra   rI   rI   {  s9      +*T***V3E00%000000rc   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     s8     ??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   | ]}|         V  d S r^   r   r   r   r   s     ra   r   z%random_combination.<locals>.<genexpr>  '      **Qa******rc   )r   rq   r   r%   r   )ri   r   rh   indicesr   s       @ra   rG   rG     s[     ??DD		AVE!HHa(())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   6   K   | ]}t                    V  d S r^   )r$   r   r   rh   s     ra   r   z6random_combination_with_replacement.<locals>.<genexpr>  s)      44aYq\\444444rc   c              3   (   K   | ]}|         V  d S r^   r   r   s     ra   r   z6random_combination_with_replacement.<locals>.<genexpr>  r   rc   )r   rq   r   r   )ri   r   r   rh   r   s      @@ra   rF   rF     sg     ??DD		A444458844444G****'******rc   c                    t          |           }t          |          }|dk     s||k    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 }|rS||z  |z  |dz
  |dz
  }}}||k    r||z  }|||z
  z  |z  |dz
  }}||k    |                    |d|z
                      |St          |          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:     s8    ??DD		A	A1q55	AAq1uA1a!e__ ! !QOq qyy
		uzzF
 $a%1*a!eQUa1qjjQJEA;!#QUqA qjj 	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 ])}|                    |           t          ||          V  *dS )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,     s      F 6]]44R4 FFAA3q!!!A%F66!QU++,, ' 'avv&&&&&&' 'rc   c                     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*   &  s<     r77LE5Yy%0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  sP     Xq!!JBBTNNNTNNNTNNN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  sU    Ha  I ++ + +8VHa##T****	?rc   c              #      K   t          |           }t          t          ||dz
            |          }|D ](}|                    |           t	          |          V  )d S )Nr   ro   )rt   r   r   r   r   )ri   rh   rx   r   r_   s        ra   _sliding_window_dequer
  Q  sq      H~~H6(AE**1555F  aFmm rc   c                     |dk    rt          | |          S |dk    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  sy     	2vv$Xq111	
Q%h222	
a!!!	
a8}}=!==>>>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  sR     x..CULs3xx!|)<)<a@@AAFwsV,,,rc   c                 V    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@     s>      3D 0 0HTAu:..//Krc   c              #   :  K   t          | dd          }|7t          | ||          }t          ||          D ]\  }}||u s||k    r|V  dS |t          |           n|}|dz
  }t	          t
                    5  	  |||dz   |          x}V  # 1 swxY w Y   dS )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00I(E400#He44 	 	JAw%7e#3#3	 	
 !%s8}}}$AIj!! 	; 	;;%IeQUD999q:::;	; 	; 	; 	; 	; 	; 	; 	; 	; 	;s   9BBBc              #     K   | dk    rdV  d}t          d          | dz  z  }t          |d|t          |           dz             D ]_}t          |d|||z            E d{V  t          t	          t          ||z  | ||z                                 |||z  | ||z   <   ||z  }`t          |d|          E d{V  dS )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       	1uuEVQ'DaU1XX\:::  dAua!e444444444"'E!a%AE,B,B(C(C"D"DQUQQA$5)))))))))))rc   c             #   "  K   |dk     rt          d          t          |           }t          t          ||                    x}rI|r"t	          |          |k    rt          d          |V  t          t          ||                    x}GdS dS )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     s       	1uu1222H~~H!,,--
-%  	<c%jjAoo:;;; !,,--
-%     rc   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                 f    	 t          |            n# t          $ r Y dS w xY wt          | |          S )z.Scalars are bytes, strings, and non-iterables.T)rt   rs   
isinstance)r   
stringlikes     ra   
_is_scalarr)     sF    U   tteZ(((s    
  c                     t          |           }	 	 t          |          }n# t          $ r |cY S w xY wt          |f|          }t	          |          r|S t          j        |          }Z)z.Depth-first iterator over scalars in a tensor.)rt   rw   StopIterationr   r)  r   )tensorrx   r   s      ra   _flatten_tensorr-  	  s    F||H1	NNEE 	 	 	OOO	%8,,e 	O&x001s   " 11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     sp    B % ;u*622E:::I#F++Mgx~~}==H(I&&&rc   c                     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   @  s=     	BqE

A78WR2%?%?@@!DDDrc   c                     t          d|           D ]R}dx}}d}|dk    r:||z  |z   | z  }||z  |z   | z  }||z  |z   | z  }t          ||z
  |           }|dk    :|| k    r|c S St          d          )Nr   r  zprime or under 5)r   r   r   )rh   r   r_   r`   ds        ra   _factor_pollardr<  O  s     1a[[ 	 		A1ffQaAQaAQaAAE1A	 1ff
 66HHH 
'
(
((rc      c              #   *  K   | dk     rdS t           D ]}| |z  s|V  | |z  } | |z  g }| dk    r| gng }|D ]F} | dk     st          |           r|                    |            -t          |           }||| |z  fz  }Gt	          |          E d{V  dS )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       	1uu #  e) 	KKK%KA e) 	
 Fa%%A33RD & &v::!:MM!"1%%DT19%%DDf~~rc   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   r0  r   r   )coefficientsr_   rh   powerss       ra   r?   r?     sc      	LAAvvtAwwqzzfQii%((!3!34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WWrc   c                     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   r0  r   rg   rk   r   )rG  rh   rH  s      ra   rA   rA     s@     	LAeAqkk""FCv..///rc   c                 T    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     s3    & VAYY  	Q%ZHrc   ))i  )r  )i )   I   )l   tT7 )r     =   )l   ay)r        iS_ )l   ;n>)r  r      rN     )l   p)r  r   rR  rN  rS  rP  )l            )r  iE  i$  in  i i= ik)l   %!HnfW )r  r   rR  rN  rS  rP        rQ     rL  %   )   c                     | dz
  | z                                   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   r;  s      ra   _shift_to_oddr[    s\     a%1  ""Q&A	QAFa<1Q16666a4Krc   c                     | dk    r| dz  rd|cxk    r| k     sn J t          | dz
            \  }}t          |||           }|dk    s	|| dz
  k    rdS t          |dz
            D ]}||z  | z  }|| dz
  k    r dS dS )Nr  r   TF)r[  rF  r   )rh   baser   r;  r_   _s         ra   _strong_probable_primer_    s    EEAEAMMMMMMMMMMQDAqD!QAAvva!et1q5\\  EAIA::44  5rc   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d	S t           D ]\  }} |k     r 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.
    rT  >   r  r   rR  rN  rS  rP  r   r   rR  rN  rS  rP  Fc              3   >   K   | ]}t          d dz
            V  dS )r  r   N)_private_randranger   s     ra   r   zis_prime.<locals>.<genexpr>*  s2      AA!#Aq1u--AAAAAArc   @   c              3   8   K   | ]}t          |          V  d S r^   )r_  )r   r]  rh   s     ra   r   zis_prime.<locals>.<genexpr>,  s.      AA4%a..AAAAAArc   )_perfect_testsr   all)rh   limitbasess   `  ra   r2   r2     s    B 	2vv(((E a!e A !a% AF q2v u& B Buu99E  BAAAuRyyAAAAAAA5AAA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                  b    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5666rc   c           	   #   <  K   | j         }g }g }t          t                    5  	 t          |t	          | |                                 |d         V  t          |t          | |                                 |d         |d         z   dz  V  m# 1 swxY w Y   dS )z.Non-windowed running_median() for Python 3.14+Tr   r  N)__next__r   r+  rd   r   r   re   rx   readlohis       ra   #_running_median_minheap_and_maxheaprr  j  s       D	B	B	-	 	  & &	&[TTVV44555Q%KKKRTTVV44555a52a5=A%%%%	&& & & & & & & & & &s   A/BBBc           	   #   D  K   | j         }g }g }t          t                    5  	 t          |t	          | |                                  |d          V  t          |t	          | |                                   |d         |d         z
  dz  V  q# 1 swxY w Y   dS )zDBackport of non-windowed running_median() for Python 3.13 and prior.Tr   r  N)rm  r   r+  r   r   rn  s       ra   _running_median_minheap_onlyrt  z  s       D	B	B	-	 	  & &	&R+b$$&&111222a5&LLLR+b4466'222333a52a5=A%%%%	&& & & & & & & & & &s   A3BBBc              #   b  K   t                      }g }| D ]}|                    |           t          ||           t          |          |k    r%t	          ||                                          }||= t          |          }|dz  }|dz  r||         n||dz
           ||         z   dz  V  dS )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_windowedry    s       WWFG 
I 
Iaww<<&  GV^^%5%566A
LLFEHgajjA(Cq'HHHHH
I 
Irc   ro   c                    t          |           }|4t          |          }|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().
    Nr   zWindow size should be positive)rt   r#   r   ry  _max_heap_availablert  rr  )ri   rp   rx   s      ra   rL   rL     sl    . H~~HvQ;;=>>>'&999 6+H555.x8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   r{  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   re  r[  r_  Randomrb  r2   r5   r7   rr  rt  ry  rL   r   rc   ra   <module>r     s     & & & & & & & &             0 0 0 0 0 0 0 0 0 0 ' ' ' ' ' ' ' '                                 ( ' ' ' ' ' ' ' ' ' ' ' : : : : : : : : : : : : : : , , , , , , , , , ,      3 3 3j &((,Ct '#d+++KK    KKK-((((((( - - -,,HHH-
33333333         % % % ' ' ' '$8 8 8 %+ %+ %+ %+P
4 
4 
4 
4   4 ! $ $ $ $) ) ) ; ; ;
% 
% 
%	, 	, 	,. . . .6  	)888888
, , , !(H    HHH    J     / / / %= %= %= %=P( ( ($; ; ;8N N N** * * *ZA A A A/ / / /(   :1 1 1 1( "# 1 1 1 1 1(" " " "$+ + + + + +"' ' 'T$ $ $(' (' ('V  &       ? ? ?2- - -  ,&; &; &; &;R* * ** %*     ( 666666', = = = = = &GOOG	 	 	 #&u ) ) ) )1 1 1&' &' &'RE E E) ) )  E%%**%%   B* * *.  0 0 0&  2       & #V]__. -B -B -B`  *7 *7 *7Z& & & & & & I I I& (, "9 "9 "9 "9 "9 "9 "9sH   B   B*)B*.B5 5C ?C C CCD# #D-,D-