
    j                     v    d dl mZ ddlmZmZmZmZmZmZm	Z	 dede	eef   fdZ
de	ee   edf   d	ee   fd
Zy)    )log2   )AnyCallableIterableListNDArraySequenceUnion	operationitemsc           
         t        |      dk(  ryt        |      dk(  r|d   S t        |      dk(  r | |d   |d         S t        t        dt        t        |            z               D ]l  }g }t        |      dz  }t        dt        |      |z
  d      D ]#  }|j	                   | ||   ||dz                   % |dk7  r|j	                  |d          |}n t              dk(  sJ |d   S )af  
    Call an operation function in a cascaded pairwise way against a
    flat list of items.

    This should produce the same result as `functools.reduce`
    if `operation` is commutable like addition or multiplication.
    This may be faster for an `operation` that runs with a speed
    proportional to its largest input, which mesh booleans appear to.

    The union of a large number of small meshes appears to be
    "much faster" using this method.

    This only differs from `functools.reduce` for commutative `operation`
    in that it returns `None` on empty inputs rather than `functools.reduce`
    which raises a `TypeError`.

    For example on `a b c d e f g` this function would run and return:
        a b
        c d
        e f
        ab cd
        ef g
        abcd efg
     -> abcdefg

    Where `functools.reduce` would run and return:
        a b
        ab c
        abc d
        abcd e
        abcde f
        abcdef g
     -> abcdefg

    Parameters
    ----------
    operation
      The function to call on pairs of items.
    items
      The flat list of items to apply operation against.
    r   Nr      )lenrangeintr   append)r   r   _results	items_modis         >/DATA/.local/lib/python3.12/site-packages/trimesh/iteration.pyreduce_cascader      s    T 5zQ	UqQx	Uqq58,,3q4E
++,- JN	q#e*y0!4ANN9U1XuQU|<= 5
 >NN59% .  w<11:    argsNreturnc                      g }| D cg c]H  }|Dt        |d      r't        |t        t        f      s|j	                  |      n|j                  |      J c} |S c c}w )a  
    A less principled version of `list(itertools.chain(*args))` that
    accepts non-iterable values, filters `None`, and returns a list
    rather than yielding values.

    If all passed values are iterables this will return identical
    results to `list(itertools.chain(*args))`.


    Examples
    ----------

    In [1]: list(itertools.chain([1,2], [3]))
    Out[1]: [1, 2, 3]

    In [2]: trimesh.util.chain([1,2], [3])
    Out[2]: [1, 2, 3]

    In [3]: trimesh.util.chain([1,2], [3], 4)
    Out[3]: [1, 2, 3, 4]

    In [4]: list(itertools.chain([1,2], [3], 4))
      ----> 1 list(itertools.chain([1,2], [3], 4))
      TypeError: 'int' object is not iterable

    In [5]: trimesh.util.chain([1,2], None, 3, None, [4], [], [], 5, [])
    Out[5]: [1, 2, 3, 4, 5]


    Parameters
    -----------
    args
      Will be individually checked to see if they're iterable
      before either being appended or extended to a flat list.


    Returns
    ----------
    chained
      The values in a flat list.
    __iter__)hasattr
isinstancestrbytesextendr   )r   chainedas      r   chainr'   N   so    V G 	 A= Az":a#u+F 	q^^A	 	 Ns   AA)mathr   typedr   r   r   r   r	   r
   r   r   r'    r   r   <module>r+      sY     J J JEh EuXw5F/G EP4x}c4/0 4T#Y 4r   