Ë
    øÇ:j¸²  ã                   ó<  — 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
 ddl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 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.m/Z/ ddlm0Z0m1Z1m2Z2m3Z3 ddl4m5Z5 g d¢Z6 e7«       Z8	 ddlm9Z9m:Z: dZ;d„ Z=dbd„Z>d„ Z?dcd„Z@dcd„ZAdcd„ZBeCfd„ZDd„ ZEeEZFd„ ZGd„ ZH	 ddl#mIZJ d„ ZKdcd„ZLd„ Zddd „ZMd!„ ZNd"„ ZOd#„ ZPdcd$„ZQdcd%„ZRded&„ZSdcd'„ZTdfd(„ZUd)d*œd+„ZVdcd,„ZWd-„ ZXd.„ ZYd/„ ZZd0„ Z[d1„ Z\d2„ Z]d3„ Z^d4„ Z_d5„ Z`d6„ Zad7„ Zbd8„ Zcdgd9„Zdd:„ Zedd;œd<„Zfe5d=k\  rdd>lmgZh dd;œd?„Zgefj                   eg_         nefZgd@„ ZiejekffdA„ZldB„ ZmdC„ ZndD„ ZodE„ Zp eq eedF«      «      ZrdG„ ZsdH„ ZtdI„ ZudJ„ ZvdK„ Zwg dL¢ZxedM„ «       ZydN„ Zz ejö                  «       j`                  Z|dO„ Z}dP„ Z~dQ„ ZdR„ Z€dS„ Z�dT„ Z‚ddUœdV„ZƒdW„ Z„ddUœdX„Z…dY„ Z†ddUœdZ„Z‡d[„ ZˆddUœd\„Z‰ e
dd¬]«       G d^„ d_«      «       ZŠddUœd`„Z‹da„ ZŒy# e<$ r dZ;Y �Œsw xY w# e<$ r eHZJY �ŒTw xY w)ha  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)Ú	dataclass)Ú	lru_cacheÚreduce)ÚheappushÚheappushpop)Ú
accumulateÚchainÚcombinationsÚcompressÚcountÚcycleÚfilterfalseÚgroupbyÚisliceÚpairwiseÚproductÚrepeatÚstarmapÚ	takewhileÚteeÚzip_longest)ÚprodÚcombÚisqrtÚgcd)ÚmulÚgetitemÚindexÚis_Ú
itemgetterÚtruediv)Ú	randrangeÚsampleÚchoiceÚshuffle)Ú
hexversion)8ÚStatsÚ	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_noner   Ú	partitionÚpolynomial_evalÚpolynomial_from_rootsÚpolynomial_derivativeÚpowersetÚprependÚquantifyÚreshapeÚ#random_combination_with_replacementÚrandom_combinationÚrandom_derangementÚrandom_permutationÚrandom_productÚ
repeatfuncÚ
roundrobinÚrunning_maxÚrunning_meanÚrunning_medianÚrunning_minÚrunning_statisticsÚsieveÚsliding_windowÚ	subslicesÚsum_of_squaresÚtabulateÚtailÚtakeÚtotientÚ	transposeÚ
triplewiseÚuniqueÚunique_everseenÚunique_justseen)Úheappush_maxÚheappushpop_maxTFc                 ó,   — t        t        || «      «      S )zóReturn 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     úk/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/more_itertools/recipes.pyr\   r\   q   s   € ô ”�x Ó#Ó$Ð$ó    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     ri   rZ   rZ   �   s   € ô ˆxœ˜u›Ó&Ð&rj   c                 ó˜   — 	 t        |«      }t        |t        d|| z
  «      d«      S # t        $ r t	        t        || ¬«      «      cY S w xY w)zƒReturn 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   )rg   rh   Úsizes      ri   r[   r[   “   sO   € ð8Ü�8‹}ˆô �h¤ A t¨a¡xÓ 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   rp   )r   Únextr   )Úiteratorrg   s     ri   r0   r0   £   s)   € ð@ 	€yäˆh˜qÖ!ô 	ŒV�H˜a Ó# TÕ*rj   c                 ó0   — t        t        | |d«      |«      S )z…Returns the nth item or a default value.

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

    N)rx   r   )rh   rg   Údefaults      ri   r>   r>   Ë   s   € ô ”�x  DÓ)¨7Ó3Ð3rj   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   )rh   Úkeyry   ÚfirstÚseconds        ri   r-   r-   Ø   s9   € ô$ �x Ó%€HØò ˆØò 	ˆFÚð	áðð rj   c                 ó,   — t        t        || «      «      S )zcReturn the how many times the predicate is true.

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

    )Úsumrl   )rh   Úpreds     ri   rH   rH   ò   s   € ô Œs�4˜Ó"Ó#Ð#rj   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   ©rh   s    ri   rA   rA   ü   s   € ô �œ6 $›<Ó(Ð(rj   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©rh   rg   s     ri   r=   r=     s    € ô ×Ñœv¤e¨H£o°qÓ9Ó:Ð:rj   c                 ó6   — t        t        t        | |«      «      S )zãReturns 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�   rl   r!   )Úvec1Úvec2s     ri   r2   r2     s   € ô Œs”3˜˜dÓ#Ó$Ð$rj   )Úsumprodc                 ó,   — t        j                  | «      S )zÜReturn 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†   )Úlist_of_listss    ri   r5   r5   +  s   € ô ×Ñ˜}Ó-Ð-rj   c                 ó\   — |€t        | t        |«      «      S t        | t        ||«      «      S )aK  Call *function* 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   )rm   ÚtimesÚargss      ri   rO   rO   7  s.   € ð, €}Ü�x¤¨£Ó.Ð.Ü�8œV D¨%Ó0Ó1Ð1rj   c                 ó   — t        | «      S )z²
    Wrapper for :func:`itertools.pairwise`.

    .. warning::

       This function is deprecated as of version 11.0.0. It will be removed in a future
       major release.
    )Úitertools_pairwiser„   s    ri   r   r   R  s   € ô ˜hÓ'Ð'rj   c                 ó–   — t        | «      g|z  }|xdk(  r t        |d|iŽS xdk(  r t        |ddiŽ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 `ValueError` will be raised.

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

    ÚfillÚ	fillvalueÚstrictTÚignorez Expected fill, strict, or ignore)ru   r   ÚzipÚ
ValueError)rh   rg   Ú
incompleter–   Ú	iteratorss        ri   r6   r6   ^  sZ   € ô: �h“Ð  1Ñ$€IØ
ÝÜ 	Ð?°YÑ?Ð?ÝÜ˜	Ð/¨$Ñ/Ð/ÛÜ˜	�?Ð"ØÜÐ?Ó@Ð@rj   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)rl   ru   Úrangerr   r   r   rx   )Ú	iterablesrœ   Ú
num_actives      ri   rP   rP   ‡  sT   è ø€ ô ”D˜)Ó$€IÜœC 	›N¨A¨rÓ2ò (ˆ
Üœ& ¨JÓ7Ó8ˆ	Ü”t˜YÓ'×'Ñ'ñ(à'ús   ‚AAÁAÁAc                 óˆ   ‡ ‡‡‡— ‰ €t         Š t        |«      Št        «       Št        «       Šˆˆˆ ˆfd„} |‰«       |‰«      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, ' '])

    c              3   ó†   •K  — 	 | r| j                  «       –— | rŒ‰D ]  } ‰|«      r‰n‰j                  |«        n y Œ<­w©N)ÚpopleftÚappend)ÚqueueÚvalueÚfalse_queuery   r‚   Ú
true_queues     €€€€ri   Úgenzpartition.<locals>.gen´  sP   øè ø€ ØÙØ—m‘m“oÒ%ò à!ò �Ù# Eœ{‘°×CÑCÀEÔJÙðð ð ùs
   ƒAœ%A)Úboolru   r   )r‚   rh   r«   r©   ry   rª   s   `  @@@ri   rB   rB   ™  sA   û€ ð( €|ÜˆÜ�H‹~€Hä“'€KÜ“€J÷ñ ˆ{Ó™S ›_Ð,Ð,rj   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     €ri   ú	<genexpr>zpowerset.<locals>.<genexpr>Ó  s   øè ø€ ÒM°aœ|¨A¨q×1ÑMùó   ƒé   )rf   r   r†   rŸ   rr   )rh   r±   s    @ri   rF   rF   Á  s2   ø€ ô" 	ˆX‹€AÜ×ÑÓM¼5ÄÀQÃÈ!ÁÓ;LÔMÓMÐMrj   c              #   óØ   K  — t        «       }|€1t        |j                  | «      D ]  }|j                  |«       |–— Œ y| D ]$  } ||«      }||vsŒ|j                  |«       |–— Œ& y­w)a  Yield unique elements, preserving order. Remember all elements ever seen.

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

    Raises ``TypeError`` for unhashable items.

    Some unhashable objects can be converted to hashable objects
    using the *key* parameter:

    * For ``list`` objects, try ``key=tuple``.
    * For ``set`` objects, try ``key=frozenset``.
    * For ``dict`` objects, try ``key=lambda x: frozenset(x.items())``
      or in Python 3.15 and later, set ``key=frozendict``.

    Alternatively, consider the ``unique()`` itertool recipe.  It sorts
    the data and then uses equality to eliminate duplicates.  Hashability
    is not required.

    N)Úsetr   Ú__contains__Úadd)rh   r}   ÚseenÚelementÚks        ri   ra   ra   Ö  sr   è ø€ ô. ‹5€DØ
€{Ü" 4×#4Ñ#4°hÓ?ò 	ˆGØ�H‰H�WÔØ‹Mñ	ð  ò 	ˆGÙ�G“ˆAØ˜Š}Ø—‘˜”Ø“ñ		ùs   ‚AA*ÁA*c           
      óœ   — |€t        t        d«      t        | «      «      S t        t        t        t        d«      t        | |«      «      «      S )záYields 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´   )rl   r%   r   rx   )rh   r}   s     ri   rb   rb   ú  s>   € ð €{Ü”:˜a“=¤'¨(Ó"3Ó4Ð4äŒt”Sœ A›¬°¸#Ó(>Ó?Ó@Ð@rj   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}   )Úsortedrb   )rh   r}   r¾   Ú	sequenceds       ri   r`   r`   	  s   € ô  �x S°'Ô:€IÜ˜9¨#Ô.Ð.rj   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(function, 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   )rm   Ú	exceptionr~   s      ri   r8   r8     s<   è ø€ ô, 
�)Ó	ñ ØÐÙ“'ŠMØÙ“*Òð ÷ð ü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'

    )rx   Úfilter)rh   r{   r‚   s      ri   r3   r3   :  s   € ô" ”�t˜XÓ&¨Ó0Ð0rj   r´   ©r   c                 ól   — t        t        t         |«      «      | z  }t        t        t        |«      «      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)``.

    )r‡   rl   r)   )r   r    Úpoolss      ri   rN   rN   N  s,   € ô  ”#”e˜YÓ'Ó(¨6Ñ1€EÜ””V˜UÓ#Ó$Ð$rj   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‡   rr   r(   )rh   r°   Úpools      ri   rM   rM   b  s-   € ô �‹?€DØ�YŒˆDŒ	 A€AÜ”˜˜a“Ó!Ð!rj   c                 ó¬   — t        | «      }t        |«      }t        t        t	        |«      |«      «      }t        |D �cg c]  }||   ‘Œ	 c}«      S c c}w )zÿReturn 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)``.

    )r‡   rr   r¿   r(   rŸ   )rh   r°   rÉ   rg   ÚindicesÚis         ri   rK   rK   t  sH   € ô �‹?€DÜˆD‹	€AÜ”VœE !›H aÓ(Ó)€GÜ 7Ö+˜a�$�q“'Ò+Ó,Ð,ùÒ+ó   ¾Ac                 ó¬   ‡— t        | «      }t        |«      Št        ˆfd„t        |«      D «       «      }t        |D �cg c]  }||   ‘Œ	 c}«      S c c}w )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Ì   rg   s     €ri   r²   z6random_combination_with_replacement.<locals>.<genexpr>‘  s   øè ø€ Ò4 a”Y˜q—\Ñ4ùs   ƒ)r‡   rr   r¿   rŸ   )rh   r°   rÉ   rË   rÌ   rg   s        @ri   rJ   rJ   „  sH   ø€ ô �‹?€DÜˆD‹	€AÜÓ4¬5°«8Ô4Ó4€GÜ 7Ö+˜a�$�q“'Ò+Ó,Ð,ùÒ+rÍ   c                 ó@  — t        | «      }t        |«      }t        ||«      }|dk  r||z  }d|cxk  r
|k  st        ‚ 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.
    ``IndexError`` will be raised if the given *index* is invalid.
    r   r´   rž   )r‡   rr   r   Ú
IndexErrorr¦   )rh   r°   r#   rÉ   rg   ÚcÚresults          ri   r?   r?   •  sÌ   € ô �‹?€DÜˆD‹	€AÜˆQ�‹
€Aàˆq‚yØ�‰
ˆØ�Œ>˜Š>ÜÐð ÜÐà€FÙ
Ø�a‘%˜1‘*˜a !™e Q¨¡Uˆaˆ1ˆØ�qŠjØ�Q‰JˆEØ˜˜A™‘; !Ñ# Q¨¡UˆqˆAð �q‹jð 	�‰�d˜2 ™6‘lÔ#ò ô �‹=Ðrj   c                 ó   — t        | g|«      S )a  Yield *value*, followed by the elements in *iterable*.

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

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

    )r   )r¨   rh   s     ri   rG   rG   ·  s   € ô �%�˜(Ó#Ð#rj   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   rp   r´   )r‡   rr   r   r   r   r¦   Ú_sumprod)ÚsignalÚkernelrg   ÚwindowÚxs        ri   r1   r1   Æ  sq   è ø€ ôF �6‹]™4˜R˜4Ñ €FÜˆF‹€AÜ�A�3˜qÔ! AÑ%€FÜ�6œ6 ! Q¨¡UÓ+Ó,ò 'ˆØ�‰�aÔÜ�v˜vÓ&Ó&ñ'ù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™   )Ú	predicateÚitÚtruesÚafters       ri   r/   r/   ñ  s2   € ô �r“7�L€Eˆ5Ü”Y˜y¨%Ó0´#°e³*Ó=€EØ�%ˆ<Ðrj   c                 ó„   — t        | d«      \  }}}t        |d«       t        |d«       t        |d«       t        |||«      S )z�Return overlapping triplets from *iterable*.

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

    é   N)r   rx   r™   )rh   Út1Út2Út3s       ri   r_   r_     s?   € ô �X˜qÓ!�J€BˆˆBÜˆˆT„NÜˆˆT„NÜˆˆT„NÜˆr�2�r‹?Ðrj   c                 ó~   — t        | |«      }t        |«      D ]  \  }}t        t        |||«      d «       Œ t	        |Ž S r¤   )r   Ú	enumeraterx   r   r™   )rh   rg   rœ   rÌ   ry   s        ri   Ú_sliding_window_islicerè     sC   € ä�H˜aÓ €IÜ  Ó+ò +‰ˆˆ8ÜŒV�H˜a Ó# TÕ*ð+ä�	ˆ?Ðrj   c              #   ó    K  — t        | «      }t        t        ||dz
  «      |¬«      }|D ]   }|j                  |«       t	        |«      –— Œ" y ­w)Nr´   rp   )ru   r   r   r¦   r‡   )rh   rg   ry   rÚ   rÛ   s        ri   Ú_sliding_window_dequerê     sK   è ø€ ä�H‹~€HÜ”6˜( A¨¡EÓ*°1Ô5€FØò ˆØ�‰�aÔÜ�F‹mÓñù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     ri   rW   rW   %  sb   € ð 	ˆ2‚vÜ$ X¨qÓ1Ð1Ø	
ˆQŠÜ% h°Ó2Ð2Ø	
ˆaŠÜ˜Ó!Ð!Ø	
ˆaŠÜ�8‹}ÐäÐ9¸!¸Ð=Ó>Ð>rj   c           
      óª   — t        | «      }t        t        t        t	        t        |«      dz   «      d«      «      }t        t        t        |«      |«      S )zþReturn 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í   )	rf   r   Úslicer   rŸ   rr   rl   r"   r   )rh   ÚseqÚslicess      ri   rX   rX   >  s@   € ô ˆx‹.€CÜ”UœL¬¬s°3«x¸!©|Ó)<¸aÓ@ÓA€FÜŒwœ˜s› VÓ,Ð,rj   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´   )rf   r1   )ÚrootsÚpolyÚroots      ri   rD   rD   L  s6   € ð  ˆ3€DØò 0ˆÜ”H˜T A¨ u :Ó.Ó/‰ð0à€Krj   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ç   rr   r   rš   )rh   r¨   rn   ÚstopÚ	seq_indexry   rÌ   rº   s           ri   r9   r9   b  s©   è ø€ ô2 ˜ '¨4Ó0€IØÐä˜( E¨4Ó0ˆÜ# H¨eÓ4ò 	‰JˆAˆwØ˜%Ñ 7¨eÓ#3Ø“ñ	ð
 !% Œs�8Œ}°$ˆØ�A‰IˆÜ”jÓ!ñ 	;ØÙ% e¨Q°©U°DÓ9Ð9�qÒ:ð ÷	;ð 	;ü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)Ú	bytearrayr9   r   Úbytesrr   rŸ   )rg   rn   ÚdataÚps       ri   rV   rV   ‹  sÂ   è ø€ ð 	ˆ1‚uØŠØ€EÜ�VÓ  Q¡Ñ'€DÜ˜˜a ¬U°1«X¸©\Ô:ò ˆÜ˜d A u¨a°!©eÓ4×4Ð4Ü"'¬¬E°!°a±%¸¸AÀ¹EÓ,BÓ(CÓ"DˆˆQ�‰U�Q˜˜Q™ÐÑØ�A‘‰ðô ˜$  5Ó)×)Ñ)ð 	5øð *ús%   ‚AB(ÁB$ÁAB(ÂB&ÂB(Â&B(©r—   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š   ru   r‡   r   rr   )rh   rg   r—   ry   Úbatchs        ri   Ú_batchedr     sr   è ø€ ð 	ˆ1‚uÜÐ1Ó2Ð2Ü�H‹~€HÜœ ¨!Ó,Ó-Ð
-ˆ%Ð
-Ù”c˜%“j A’oÜÐ:Ó;Ð;ØŠô œ ¨!Ó,Ó-Ð
-ˆ%Ó
-ùs   ‚A)A.Á,A.i¢ )r.   c                ó   — t        | ||¬«      S )Nrÿ   )Úitertools_batched)rh   rg   r—   s      ri   r.   r.   ·  s   € Ü  ¨1°VÔ<Ð<rj   c                 ó   — t        | ddiŽ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.
    r—   T)r™   )Úmatrixs    ri   r^   r^   ¿  s   € ô �Ð$˜tÑ$Ð$rj   c                 óP   — 	 t        | «       t        | |«      S # t        $ r Y yw xY w)z.Scalars are bytes, strings, and non-iterables.T)ru   rt   Ú
isinstance)r¨   Ú
stringlikes     ri   Ú
_is_scalarr
  Ë  s1   € ðÜˆUŒô �e˜ZÓ(Ð(øô ò Ùðú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.)ru   rx   ÚStopIterationr   r
  r†   )Útensorry   r¨   s      ri   Ú_flatten_tensorr  Ô  sd   € ä�F‹|€HØ
ð	Ü˜“NˆEô ˜%˜ 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   )r  ÚshapeÚ	first_dimÚdimsÚscalar_streamÚreshapeds         ri   rI   rI   â  sZ   € ôB �%œÔÜ”u×*Ñ*¨6Ó2°EÓ:Ð:ØÐ€I�Ü# FÓ+€MÜ”gœx¨›~¨}Ó=€HÜ�(˜IÓ&Ð&rj   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   )rr   r.   r   r×   r   r^   )Úm1Úm2rg   s      ri   r;   r;     s0   € ô 	ˆBˆq‰E‹
€AÜ”7œ8¤W¨R´¸2³Ó%?Ó@À!ÓDÐDrj   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š   )rg   ÚbrÛ   ÚyÚds        ri   Ú_factor_pollardr    s•   € ô �1�a‹[ò 	ˆØˆ	ˆˆAØˆØ�1ŠfØ�Q‘˜‘˜a‘ˆAØ�Q‘˜‘˜a‘ˆAØ�Q‘˜‘˜a‘ˆAÜ�A˜‘E˜1“ˆAð	 �1‹fð
 �‹6ØŠHð	ô Ð'Ó
(Ð(rj   éÓ   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_211r7   r¦   r  r¿   )rg   ÚprimeÚprimesÚtodoÚfacts        ri   r4   r4   -  s«   è ø€ ð 	ˆ1‚uØô #ò ˆØ�e“)ØŠKØ�%‰KˆAð �e”)ðð €FØ�a’%ˆA‰3˜R€DØò &ˆØˆvŠ:œ !œØ�M‰M˜!Õä" 1Ó%ˆDØ�T˜1 ™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   )rr   Útyperl   Úpowr   r  rŸ   r×   )ÚcoefficientsrÛ   rg   Úpowerss       ri   rC   rC   N  sM   € ô  	ˆLÓ€AØˆA‚vØŒt�A‹w�q‹zÐÜ””f˜Q“i¤¬%°«(Ó!3Ó4€FÜ�L &Ó)Ð)rj   c                 ó$   — t        t        | «      Ž S )z¯Return 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    ri   rY   rY   e  s   € ô ”S˜“]Ð#Ð#rj   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´   )rr   r  rŸ   rf   rl   r!   )r)  rg   r*  s      ri   rE   rE   p  s2   € ô 	ˆLÓ€AÜ”e˜A˜q“kÓ"€FÜ””C˜ vÓ.Ó/Ð/rj   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¶   r4   )rg   r"  s     ri   r]   r]   ƒ  s-   € ô& ”V˜A“Y“ò ˆØ	ˆQ�%‰Z‰‰ðà€Hrj   ))iÿ  )rí   )i�Š )é   éI   )l   ÅtT7 )rí   é   é=   )l   Áay)rí   é   é   iS_ )l   ;n>Ô)rí   râ   é   r0  é   )l   ßp¤)rí   râ   r4  r0  r5  r2  )l            )rí   iE  iŸ$  in  i×à i=• iþ‘k)l   ý%!HÈn•fW )rí   râ   r4  r0  r5  r2  é   é   r3  é   r.  é%   é)   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)rg   r±   r  s      ri   Ú_shift_to_oddr=  «  sS   € ð ˆa‰%�1‰× Ñ Ó" QÑ&€AØ	ˆQ‰€AØ�‰F�a‰<˜1Ò  Q¢¨1°ª6Ð1Ð1Øˆaˆ4€Krj   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)r=  r(  rŸ   )rg   Úbaser±   r  rÛ   Ú_s         ri   Ú_strong_probable_primerA  ´  s‘   € Ø�ŠE˜˜Aš A¨¤M°¢MÐ2Ð2 MÐ2Ð2ä˜˜Q™Ó�D€A€qäˆD�!�Q‹€AØˆA‚v��a˜!‘e’Øä�1�q‘5‹\ò ˆØ�‰E�A‰IˆØ��A‘‹:Ùðð
 rj   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.
    r6  >   rí   râ   r4  r0  r5  r2  r´   râ   r4  r0  r5  r2  Fc              3   ó<   •K  — | ]  }t        d ‰dz
  «      –— Œ y­w)rí   r´   N)Ú_private_randrangerÐ   s     €ri   r²   zis_prime.<locals>.<genexpr>õ  s   øè ø€ ÒA°!Ô# A q¨1¡u×-ÑAùs   ƒé@   c              3   ó6   •K  — | ]  }t        ‰|«      –— Œ y ­wr¤   )rA  )r¯   r?  rg   s     €ri   r²   zis_prime.<locals>.<genexpr>÷  s   øè ø€ ÒA°4Ô% a¨×.ÑAùr³   )Ú_perfect_testsrŸ   Úall)rg   ÚlimitÚbasess   `  ri   r7   r7   Ê  s‚   ø€ ðB 	ˆ2‚vØÐ(Ð(Ð(à�ŠE�a˜!’e  A¢¨!¨aª%°A¸²F¸qÀ2ºvØä&ò B‰ˆˆuØˆu‹9ÙðBó B´u¸R³yÔAˆäÓA¸5ÔAÓAÐArj   c                 ó   — t        d| «      S )zÂReturns 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Å   )rg   s    ri   r:   r:   ú  s   € ô �$˜‹?Ðrj   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   rl   r   r   )Úcountss    ri   r<   r<     s   € ôT ””Dœ* VÓ,¨fÓ5Ó6Ð6rj   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  rc   r   r   rd   ©ry   ÚreadÚloÚhis       ri   Ú#_running_median_minheap_and_maxheaprT  5  s‚   è ø€ ð ×Ñ€DØ	€BØ	€Bä	”-Ó	 ñ &ØÜ˜œ[¨©T«VÓ4Ô5Ø�Q‘%ŠKä�Rœ¨©T«VÓ4Ô5Ø�a‘5˜2˜a™5‘= 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)rO  r   r  r   r   rP  s       ri   Ú_running_median_minheap_onlyrV  E  sŒ   è ø€ ð ×Ñ€DØ	€BØ	€Bä	”-Ó	 ñ &ØÜ�Rœ+ b©$«&Ó1Ð1Ô2Ø�a‘5�&ŠLä�Rœ+ b©4«6¨'Ó2Ð2Ô3Ø�a‘5˜2˜a™5‘= 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   rr   r   r¥   )ry   rq   rÚ   ÚorderedrÛ   rÌ   rg   Úms           ri   Ú_running_median_windowedrZ  U  s›   è ø€ ô ‹W€FØ€Gàò 
IˆØ�‰�aÔÜˆw˜Ôäˆw‹<˜&Ò Ü˜G V§^¡^Ó%5Ó6ˆAØ˜�
ä�‹LˆØ�‰FˆØ šEˆg�aŠj¨°°A±©¸À¹Ñ(CÀqÑ'HÓHñ
Iùs   ‚B
Brp   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   úWindow size should be positive)ru   Ú_indexrš   rZ  Ú_max_heap_availablerV  rT  ©rh   rq   ry   s      ri   rS   rS   h  sU   € ô. �H‹~€HàÐÜ˜“ˆØ�QŠ;ÜÐ=Ó>Ð>Ü'¨°&Ó9Ð9åÜ+¨HÓ5Ð5ä.¨xÓ8Ð8rj   c              #   óÀ   K  — t        «       }d}| D ]I  }|j                  |«       ||z  }t        |«      |kD  r||j                  «       z  }|t        |«      z  –— ŒK y ­w)Nr   )r   r¦   rr   r¥   )ry   rg   rÚ   Úrunning_sumr¨   s        ri   Ú_windowed_running_meanrb  �  sb   è ø€ Ü‹W€FØ€KØò (ˆØ�‰�eÔØ�uÑˆÜˆv‹;˜Š?Ø˜6Ÿ>™>Ó+Ñ+ˆKØœC ›KÑ'Ó'ñ(ùs   ‚AAc                óš   — t        | «      }|€#t        t        t        |«      t	        d«      «      S |dk  rt        d«      ‚t        ||«      S )a³  Cumulative mean 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_mean([40, 30, 50, 46, 39, 44]))
        [40.0, 35.0, 40.0, 41.5, 41.0, 41.5]

        >>> list(running_mean([40, 30, 50, 46, 39, 44], maxlen=3))
        [40.0, 35.0, 40.0, 42.0, 45.0, 43.0]

    Supports numeric types such as int, float, complex, Decimal, and Fraction.

    No extra effort is made to reduce round-off errors for float inputs.
    So the results may be slightly different from `statistics.mean`.

    r´   r   r\  )ru   rl   r&   r   r   rš   rb  r_  s      ri   rR   rR   ˜  sJ   € ô, �H‹~€Hà€~Ü”7œJ xÓ0´%¸³(Ó;Ð;à�‚{ÜÐ9Ó:Ð:ä! (¨FÓ3Ð3rj   c              #   ó  K  — t        «       }t        | «      D ]m  \  }}|r|d   d   ||z
  k(  r|j                  «        |r)|d   d   |k  s|j                  «        |r|d   d   |k  sŒ|j	                  ||f«       |d   d   –— Œo y ­w©Nr   rž   r´   ©r   rç   r¥   Úpopr¦   )ry   rq   Úsisr#   r¨   s        ri   Ú_windowed_running_minri  ¹  ó�   è ø€ Ü
‹'€CÜ! (Ó+ò ‰ˆˆuÙ�3�q‘6˜!‘9 ¨¡Ò.Ø�K‰KŒMÙ˜#˜b™' !™* uÒ,Ø�G‰GŒIñ ˜#˜b™' !™* uÓ,à�
‰
�E˜5�>Ô"Ø�!‰f�Q‰i‹ñùó   ‚A&B	Á) B	c                óv   — t        | «      }|€t        |t        ¬«      S |dk  rt        d«      ‚t	        ||«      S )aD  Smallest 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_min([4, 3, 7, 0, 8, 1, 6, 2, 9, 5]))
        [4, 3, 3, 0, 0, 0, 0, 0, 0, 0]

        >>> list(running_min([4, 3, 7, 0, 8, 1, 6, 2, 9, 5], maxlen=3))
        [4, 3, 3, 0, 0, 0, 1, 1, 2, 2]

    Supports numeric types such as int, float, Decimal, and Fraction,
    but not complex numbers which are unorderable.
    ©Úfuncr   r\  )ru   r   Úminrš   ri  r_  s      ri   rT   rT   Ä  ó?   € ô& �H‹~€Hà€~Ü˜(¬Ô-Ð-à�‚{ÜÐ9Ó:Ð:ä  ¨6Ó2Ð2rj   c              #   ó  K  — t        «       }t        | «      D ]m  \  }}|r|d   d   ||z
  k(  r|j                  «        |r)|d   d   |kD  s|j                  «        |r|d   d   |kD  sŒ|j	                  ||f«       |d   d   –— Œo y ­wre  rf  )ry   rq   Úsdsr#   r¨   s        ri   Ú_windowed_running_maxrs  â  rj  rk  c                óv   — t        | «      }|€t        |t        ¬«      S |dk  rt        d«      ‚t	        ||«      S )aC  Largest 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_max([4, 3, 7, 0, 8, 1, 6, 2, 9, 5]))
        [4, 4, 7, 7, 8, 8, 8, 8, 9, 9]

        >>> list(running_max([4, 3, 7, 0, 8, 1, 6, 2, 9, 5], maxlen=3))
        [4, 4, 7, 7, 8, 8, 8, 6, 9, 9]

    Supports numeric types such as int, float, Decimal, and Fraction,
    but not complex numbers which are unorderable.
    rm  r   r\  )ru   r   rs   rš   rs  r_  s      ri   rQ   rQ   í  rp  rj   )ÚfrozenÚslotsc                   ó@   — e Zd ZU eed<   eed<   eed<   eed<   eed<   y)r,   rv   ÚminimumÚmedianÚmaximumÚmeanN)Ú__name__Ú
__module__Ú__qualname__r  Ú__annotations__Úfloat© rj   ri   r,   r,     s   … à
ƒIØƒNØƒMØƒNØ
„Krj   r,   c                óø   — t        | d«      \  }}}}t        t        |€t        d«      nt	        t        d|«      t        |«      «      t        ||¬«      t        ||¬«      t        ||¬«      t        ||¬«      «      S )a  Statistics for 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.

    Yields instances of a ``Stats`` dataclass with fields for the dataset *size*,
    *minimum* value, *median* value, *maximum* value, and the arithmetic *mean*.

    Supports numeric types such as int, float, Decimal, and Fraction,
    but not complex numbers which are unorderable.
    é   r´   rp   )r   rl   r,   r   r   rŸ   r   rT   rS   rQ   rR   )rh   rq   Út0rã   rä   rå   s         ri   rU   rU     so   € ô ˜ 1Ó%�N€BˆˆB�ÜÜØ�NŒˆaŒ¬¬e°A°vÓ.>ÄÀvÃÓ(OÜ�B˜vÔ&Ü�r &Ô)Ü�B˜vÔ&Ü�R Ô'óð rj   c                 ó"  — t        | «      }t        |«      dk  rt        |«      dk(  ryt        d«      ‚t        t	        t        |«      «      «      }t        |«      }	 t        |«       t        t        t        ||«      «      s t        |Ž |«      S Œ4)z�Return a random derangement of elements in the iterable.

    Equivalent to but much faster than ``choice(list(derangements(iterable)))``.

    rí   r   r�  zNo derangments to choose from)
r‡   rr   rÒ   rf   rŸ   r*   Úanyrl   r$   r%   )rh   rð   Úpermrn   s       ri   rL   rL   /  s   € ô �‹/€CÜ
ˆ3ƒx�!‚|Üˆs‹8�qŠ=ØÜÐ8Ó9Ð9Ü””c˜#“h“Ó €DÜ�$‹K€EØ
Ü�ŒÜ”3”s˜E 4Ó(Ô)Ø$”:˜tÐ$ SÓ)Ð)ð rj   )r   r¤   )r•   N)NF)NN)r   N)�Ú__doc__ÚrandomÚbisectr   r   Úcollectionsr   Ú
contextlibr   Údataclassesr   Ú	functoolsr	   r
   Úheapqr   r   Ú	itertoolsr   r   r   r   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'   r(   r)   r*   Úsysr+   Ú__all__ÚobjectÚ_markerrc   rd   r^  ÚImportErrorr\   rZ   r[   r0   r>   r-   r¬   rH   rA   r@   r=   r2   rŒ   r×   r5   rO   r6   rP   rB   rF   ra   rb   r`   r8   r3   rN   rM   rK   rJ   r?   rG   r1   r/   r_   rè   rê   rW   rX   rD   r9   rV   r  r.   r  r^   Ústrrü   r
  r  rI   r;   r  r‡   r!  r4   rC   rY   rE   r]   rG  r=  rA  ÚRandomrD  r7   r:   r<   rT  rV  rZ  rS   rb  rR   ri  rT   rs  rQ   r,   rU   rL   r�  rj   ri   ú<module>rš     sÈ  ðñó ç &Ý Ý Ý !ß 'ß '÷÷ ÷ ÷ ó ÷$ (Ó 'ß L× Lß 5Ó 5Ý ò9€ñv ‹(€ðß3ð Ðò%ó 'ò$8ó %+óP
4óð4 !ó $ò)ð €ò;ò
%ðÝ(ò
	.ó2ò6	(ó&AòR(ò$%-òPNó*!óHAó/ó(ó:1ð( '(ô %ó("ò$-ò -ò"òD$ò('òVò&ò òò?ò2-òó,&;òR*ð* %*ô ð( �ÒÝ6à',ô =ð ×&Ñ&€G…Oà€Gò	%ð #& u ó )ò1ò&'òREò)ñ  ™% ›*Ó%Ð òòB*ò.$ò0ò&ò2€ð ñó ðòð& #�V—]‘]“_×.Ñ.Ð ò-Bò`ò*7òZ&ò &ò Ið& (,ô "9òJ(ð &*ô 4òBð %)ô 3ò<ð %)ô 3ñ< �$˜dÔ#÷ð ó $ðð ,0ô ó6*øðI. ò  ØÓð ûðx ò ØƒHðús$   ÂH Ã H ÈHÈHÈHÈH