
    Mi                     z    S SK Jr  SSKJrJrJrJrJrJrJ	r	  S\S\	\\4   4S jr
S\	\\   \S4   S	\\   4S
 jrg)    )log2   )AnyCallableIterableListNDArraySequenceUnion	operationitemsc           
         [        U5      S:X  a  g[        U5      S:X  a  US   $ [        U5      S:X  a  U " US   US   5      $ [        [        S[        [        U5      5      -   5      5       Hn  n/ n[        U5      S-  n[        S[        U5      U-
  S5       H"  nUR	                  U " X   XS-      5      5        M$     US:w  a  UR	                  US   5        UnMp     [        W5      S:X  d   eUS   $ )a  
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         k/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/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NN9UXuU|<= 5
 >NN59% .  w<11:    argsNreturnc                      / nU  Vs/ s HV  nUc  M  [        US5      (       a,  [        U[        [        45      (       d  UR	                  U5      OUR                  U5      PMX       nU$ s  snf )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   sv    V G 	 A		Az"":a#u+F+F 	q^^A	 	 Ns   A(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   