
    O=d                        d Z ddlZddlmZ ddlZddlZddlZddlm	Z	m
Z
mZmZmZmZmZ ddlmZmZmZ dZd Zd	 Zd
 Zd Zd:dZd Zd:dZd Zd Zd:dZd:dZd:dZ d:dZ!d:dZ"d Z#d Z$d:dZ%d Z&d Z'd:dZ(d:dZ)de	fdZ*d Z+d Z,d  Z-d! Z.d:d"Z/d:d#Z0d$ Z1d:d%Z2d& Z3d' Z4d:d(Z5d;d+Z6d, Z7d- Z8d<d/Z9d=d0Z:d1 Z;d2 Z<d>d3Z=d4 Z>d:d5Z?d6 Z@d7 ZAd?d9ZBdS )@zU
Functions that operate on lists, dicts, and other objects.

.. versionadded:: 1.0.0
    N)partial   )UNSETbase_getbase_setcallitgetargcountiteratoriteriteratee)	PathTokento_pathto_path_tokens),assignassign_with	callablesclone
clone_deepclone_deep_with
clone_withdefaultsdefaults_deepfind_keyfind_last_keyfor_infor_in_rightgethasinvert	invert_byinvokekeysmap_keys
map_valuesmap_values_deepmerge
merge_withomitomit_by	parse_intpickpick_byrename_keysset_set_with
to_booleanto_dict
to_integerto_list	to_numberto_pairs	to_string	transformunsetupdateupdate_withvaluesc                     t          | g|R  S )a  
    Assigns properties of source object(s) to the destination object.

    Args:
        obj (dict): Destination object whose properties will be modified.
        sources (dict): Source objects to assign to `obj`.

    Returns:
        dict: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> obj = {}
        >>> obj2 = assign(obj, {'a': 1}, {'b': 2}, {'c': 3})
        >>> obj == {'a': 1, 'b': 2, 'c': 3}
        True
        >>> obj is obj2
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 2.3.2
        Apply :func:`clone_deep` to each `source` before assigning to `obj`.

    .. versionchanged:: 3.0.0
        Allow iteratees to accept partial arguments.

    .. versionchanged:: 3.4.4
        Shallow copy each `source` instead of deep copying.

    .. versionchanged:: 4.0.0

        - Moved `iteratee` argument to :func:`assign_with`.
        - Removed alias ``extend``.
    )r   objsourcess     8D:\Sites\api_v1\venv\Lib\site-packages\pydash/objects.pyr   r   B   s    N s%W%%%%    c                    t          |          }|                    d          }|)t          |d                   r|                                }|t	          |d          }nd}|D ]d}|                                }|                                D ]9\  }}|r-t          ||                     |          ||| ||          }||}|| |<   :e| S )ab  
    This method is like :func:`assign` except that it accepts customizer which is invoked to produce
    the assigned values. If customizer returns ``None``, assignment is handled by the method
    instead. The customizer is invoked with five arguments: ``(obj_value, src_value, key, obj,
    source)``.

    Args:
        obj (dict): Destination object whose properties will be modified.
        sources (dict): Source objects to assign to `obj`.

    Keyword Args:
        customizer (mixed, optional): Customizer applied per iteration.

    Returns:
        dict: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> customizer = lambda o, s: s if o is None else o
        >>> results = assign({'a': 1}, {'b': 2}, {'a': 3}, customizer)
        >>> results == {'a': 1, 'b': 2}
        True

    .. versionadded:: 4.0.0
    
customizerN   maxargsargcount)listr   callablepopr	   copyitemsr   )	r=   r>   kwargsrB   rH   sourcekeyvaluevals	            r?   r   r   l   s    : 7mmGL))Jhwr{33[[]]
z1555 	 	 ,,.. 	 	JC  Zuc3Yabbb?ECHH	 Jr@   c                 N    t          d t          |           D                       S )a  
    Creates a sorted list of keys of an object that are callable.

    Args:
        obj (list|dict): Object to inspect.

    Returns:
        list: All keys whose values are callable.

    Example:

        >>> callables({'a': 1, 'b': lambda: 2, 'c': lambda: 3})
        ['b', 'c']

    .. versionadded:: 1.0.0

    .. versionchanged:: 2.0.0
        Renamed ``functions`` to ``callables``.

    .. versionchanged:: 4.0.0
        Removed alias ``methods``.
    c              3   >   K   | ]\  }}t          |          |V  d S N)rJ   .0rP   rQ   s      r?   	<genexpr>zcallables.<locals>.<genexpr>   s1      II*#u%I#IIIIIIr@   )sortedr
   r=   s    r?   r   r      s'    . IIIIIIIIr@   c                      t          |           S )a  
    Creates a clone of `value`.

    Args:
        value (list|dict): Object to clone.

    Example:

        >>> x = {'a': 1, 'b': 2, 'c': {'d': 3}}
        >>> y = clone(x)
        >>> y == y
        True
        >>> x is y
        False
        >>> x['c'] is y['c']
        True

    Returns:
        list|dict: Cloned object.

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Moved 'iteratee' parameter to :func:`clone_with`.
    
base_clonerQ   s    r?   r   r      s    4 er@   c                 $    t          | |          S )a  
    This method is like :func:`clone` except that it accepts customizer which is invoked to produce
    the cloned value. If customizer returns ``None``, cloning is handled by the method instead. The
    customizer is invoked with up to three arguments: ``(value, index|key, object)``.

    Args:
        value (list|dict): Object to clone.
        customizer (callable, optional): Function to customize cloning.

    Returns:
        list|dict: Cloned object.

    Example:

        >>> x = {'a': 1, 'b': 2, 'c': {'d': 3}}
        >>> cbk = lambda v, k: v + 2 if isinstance(v, int) and k else None
        >>> y = clone_with(x, cbk)
        >>> y == {'a': 3, 'b': 4, 'c': {'d': 3}}
        True
    rB   r\   rQ   rB   s     r?   r   r      s    * e
3333r@   c                 $    t          | d          S )a%  
    Creates a deep clone of `value`. If a iteratee is provided it will be executed to produce the
    cloned values.

    Args:
        value (list|dict): Object to clone.

    Returns:
        list|dict: Cloned object.

    Example:

        >>> x = {'a': 1, 'b': 2, 'c': {'d': 3}}
        >>> y = clone_deep(x)
        >>> y == y
        True
        >>> x is y
        False
        >>> x['c'] is y['c']
        False

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Moved 'iteratee' parameter to :func:`clone_deep_with`.
    T)is_deepr\   r^   s    r?   r   r      s    6 eT****r@   c                 &    t          | d|          S )a
  
    This method is like :func:`clone_with` except that it recursively clones `value`.

    Args:
        value (list|dict): Object to clone.
        customizer (callable, optional): Function to customize cloning.

    Returns:
        list|dict: Cloned object.
    T)rc   rB   r\   ra   s     r?   r   r     s     eTjAAAAr@   c                 p    |D ]2}|                                 D ]\  }}|                     ||           3| S )aZ  
    Assigns properties of source object(s) to the destination object for all destination properties
    that resolve to undefined.

    Args:
        obj (dict): Destination object whose properties will be modified.
        sources (dict): Source objects to assign to `obj`.

    Returns:
        dict: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> obj = {'a': 1}
        >>> obj2 = defaults(obj, {'b': 2}, {'c': 3}, {'a': 4})
        >>> obj is obj2
        True
        >>> obj == {'a': 1, 'b': 2, 'c': 3}
        True

    .. versionadded:: 1.0.0
    )rM   
setdefault)r=   r>   rO   rP   rQ   s        r?   r   r     sQ    4  ' ' ,,.. 	' 	'JCNN3&&&&	' Jr@   c                 (    d }t          | g|R d|iS )a=  
    This method is like :func:`defaults` except that it recursively assigns default properties.

    Args:
        obj (dict): Destination object whose properties will be modified.
        sources (dict): Source objects to assign to `obj`.

    Returns:
        dict: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> obj = {'a': {'b': 1}}
        >>> obj2 = defaults_deep(obj, {'a': {'b': 2, 'c': 3}})
        >>> obj is obj2
        True
        >>> obj == {'a': {'b': 1, 'c': 3}}
        True

    .. versionadded:: 3.3.0
    c                 V    t          | d          r|                     ||           d S d S )Nrf   )hasattrrf   )r=   rP   rQ   s      r?   setterzdefaults_deep.<locals>.setterX  s8    3%% 	'NN3&&&&&	' 	'r@   _setterr&   )r=   r>   rj   s      r?   r   r   >  s1    4' ' ' c4G444V444r@   c                 B    t          | |          D ]\  }}}}|r|c S dS )a  
    This method is like :func:`pydash.arrays.find_index` except that it returns the key of the first
    element that passes the predicate check, instead of the element itself.

    Args:
        obj (list|dict): Object to search.
        predicate (mixed): Predicate applied per iteration.

    Returns:
        mixed: Found key or ``None``.

    Example:

        >>> find_key({'a': 1, 'b': 2, 'c': 3}, lambda x: x == 1)
        'a'
        >>> find_key([1, 2, 3, 4], lambda x: x == 1)
        0

    .. versionadded:: 1.0.0
    Nr   )r=   	predicateresult_rP   s        r?   r   r   _  sF    * *#y99  3 	JJJ	 r@   c                 z    t          t          t          | |                              }|D ]\  }}}}|r|c S dS )ac  
    This method is like :func:`find_key` except that it iterates over elements of a collection in
    the opposite order.

    Args:
        obj (list|dict): Object to search.
        predicate (mixed): Predicate applied per iteration.

    Returns:
        mixed: Found key or ``None``.

    Example:

        >>> find_last_key({'a': 1, 'b': 2, 'c': 3}, lambda x: x == 1)
        'a'
        >>> find_last_key([1, 2, 3, 1], lambda x: x == 1)
        3

    .. versionchanged:: 4.0.0
        Made into its own function (instead of an alias of ``find_key``) with
        proper reverse find implementation.
    N)reversedrI   r   )r=   ro   reversed_objrp   rq   rP   s         r?   r   r   y  s[    . Dc9!=!=>>??L)  3 	JJJ	 r@   c                 Z    d t          | |          D             }t          |d           | S )ag  
    Iterates over own and inherited enumerable properties of `obj`, executing `iteratee` for each
    property.

    Args:
        obj (list|dict): Object to process.
        iteratee (mixed): Iteratee applied per iteration.

    Returns:
        list|dict: `obj`.

    Example:

        >>> obj = {}
        >>> def cb(v, k): obj[k] = v
        >>> results = for_in({'a': 1, 'b': 2, 'c': 3}, cb)
        >>> results == {'a': 1, 'b': 2, 'c': 3}
        True
        >>> obj == {'a': 1, 'b': 2, 'c': 3}
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``for_own``.
    c              3   ,   K   | ]\  }}}}|d u dV  dS FN rW   retrq   s      r?   rX   zfor_in.<locals>.<genexpr>  s.      QQ\S!QC5LLDLLLLQQr@   Nr   nextr=   iterateewalks      r?   r   r     s7    6 RQ\#x%@%@QQQDtJr@   c                 ^    d t          | |d          D             }t          |d           | S )a1  
    This function is like :func:`for_in` except it iterates over the properties in reverse order.

    Args:
        obj (list|dict): Object to process.
        iteratee (mixed): Iteratee applied per iteration.

    Returns:
        list|dict: `obj`.

    Example:

        >>> data = {'product': 1}
        >>> def cb(v): data['product'] *= v
        >>> for_in_right([1, 2, 3, 4], cb)
        [1, 2, 3, 4]
        >>> data['product'] == 24
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``for_own_right``.
    c              3   ,   K   | ]\  }}}}|d u dV  dS rw   rx   ry   s      r?   rX   zfor_in_right.<locals>.<genexpr>  s6      __\S!QRUY^R^R^DR^R^R^R^__r@   T)reverseNr{   r}   s      r?   r   r     s<    2 `_\#x%N%N%N___DtJr@   c                     |t           u r|}nt                      }t          |          D ]}t          | ||          } | |u r|}  n| S )a?  
    Get the value at any depth of a nested object based on the path described by `path`. If path
    doesn't exist, `default` is returned.

    Args:
        obj (list|dict|Sequence|Mapping): Object to process.
        path (str|list): List or ``.`` delimited string of path describing path.
        default (mixed): Default value to return if path doesn't exist. Defaults to ``None``.

    Returns:
        mixed: Value of `obj` at path.

    Example:

        >>> get({}, 'a.b.c') is None
        True
        >>> get({'a': {'b': {'c': [1, 2, 3, 4]}}}, 'a.b.c[1]')
        2
        >>> get({'a': {'b': {'c': [1, 2, 3, 4]}}}, 'a.b.c.1')
        2
        >>> get({'a': {'b': [0, {'c': [1, 2]}]}}, 'a.b.1.c.1')
        2
        >>> get({'a': {'b': [0, {'c': [1, 2]}]}}, ['a', 'b', 1, 'c', 1])
        2
        >>> get({'a': {'b': [0, {'c': [1, 2]}]}}, 'a.b.1.c.2') is None
        True

    .. versionadded:: 2.0.0

    .. versionchanged:: 2.2.0
        Support escaping "." delimiter in single string path key.

    .. versionchanged:: 3.3.0

        - Added :func:`get` as main definition and :func:`get_path` as alias.
        - Made :func:`deep_get` an alias.

    .. versionchanged:: 3.4.7
        Fixed bug where an iterable default was iterated over instead of being returned when an
        object path wasn't found.

    .. versionchanged:: 4.0.0

        - Support attribute access on `obj` if item access fails.
        - Removed aliases ``get_path`` and ``deep_get``.

    .. versionchanged:: 4.7.6
        Fixed bug where getattr is used on Mappings and Sequence in Python 3.5+
    default)r   objectr   r   )r=   pathr   sentinelrP   s        r?   r   r     sj    d %
 88t}}  sC222(??CE 
 Jr@   c                     	 t          | |t                     d}n%# t          t          t          t
          f$ r d}Y nw xY w|S )a  
    Checks if `path` exists as a key of `obj`.

    Args:
        obj (mixed): Object to test.
        path (mixed): Path to test for. Can be a list of nested keys or a ``.`` delimited string of
            path describing the path.

    Returns:
        bool: Whether `obj` has `path`.

    Example:

        >>> has([1, 2, 3], 1)
        True
        >>> has({'a': 1, 'b': 2}, 'b')
        True
        >>> has({'a': 1, 'b': 2}, 'c')
        False
        >>> has({'a': {'b': [0, {'c': [1, 2]}]}}, 'a.b.1.c.1')
        True
        >>> has({'a': {'b': [0, {'c': [1, 2]}]}}, 'a.b.1.c.2')
        False

    .. versionadded:: 1.0.0

    .. versionchanged:: 3.0.0
        Return ``False`` on ``ValueError`` when checking path.

    .. versionchanged:: 3.3.0

        - Added :func:`deep_has` as alias.
        - Added :func:`has_path` as alias.

    .. versionchanged:: 4.0.0
        Removed aliases ``deep_has`` and ``has_path``.
    r   TF)r   r   KeyError
IndexError	TypeError
ValueError)r=   r   existss      r?   r   r     sX    LCu%%%%j)Z8    Ms    >>c                 4    d t          |           D             S )aE  
    Creates an object composed of the inverted keys and values of the given object.

    Args:
        obj (dict): Dict to invert.

    Returns:
        dict: Inverted dict.

    Example:

        >>> results = invert({'a': 1, 'b': 2, 'c': 3})
        >>> results == {1: 'a', 2: 'b', 3: 'c'}
        True

    Note:
        Assumes `obj` values are hashable as ``dict`` keys.

    .. versionadded:: 1.0.0

    .. versionchanged:: 2.0.0
        Added ``multivalue`` argument.

    .. versionchanged:: 4.0.0
        Moved ``multivalue=True`` functionality to :func:`invert_by`.
    c                     i | ]\  }}||	S rx   rx   rV   s      r?   
<dictcomp>zinvert.<locals>.<dictcomp>d  s    777:3E3777r@   r
   rZ   s    r?   r   r   I  s    6 87#7777r@   c                     t          j        |          }i }t          |           D ]7\  }}|                     ||          g                               |           8|S )a  
    This method is like :func:`invert` except that the inverted object is generated from the results
    of running each element of object thru iteratee. The corresponding inverted value of each
    inverted key is a list of keys responsible for generating the inverted value. The iteratee is
    invoked with one argument: ``(value)``.

    Args:
        obj (dict): Object to invert.
        iteratee (mixed): Iteratee applied per iteration.

    Returns:
        dict: Inverted dict.

    Example:

        >>> obj = {'a': 1, 'b': 2, 'c': 1}
        >>> results = invert_by(obj)  # {1: ['a', 'c'], 2: ['b']}
        >>> set(results[1]) == set(['a', 'c'])
        True
        >>> set(results[2]) == set(['b'])
        True
        >>> results2 = invert_by(obj, lambda value: 'group' + str(value))
        >>> results2['group1'] == results[1]
        True
        >>> results2['group2'] == results[2]
        True

    Note:
        Assumes `obj` values are hashable as ``dict`` keys.

    .. versionadded:: 4.0.0
    )pydr~   r
   rf   append)r=   r~   callbackrp   rP   rQ   s         r?   r   r   g  sf    B |H%%HFsmm ; ;
U((5//2..55c::::Mr@   c                     t          |          }t          j        |          }t          j        |          }	 t	          t          | |          |          } ||i |}n# t          $ r d}Y nw xY w|S )a)  
    Invokes the method at path of object.

    Args:
        obj (dict): The object to query.
        path (list|str): The path of the method to invoke.
        args (optional): Arguments to pass to method call.
        kwargs (optional): Keyword arguments to pass to method call.

    Returns:
        mixed: Result of the invoked method.

    Example:

        >>> obj = {'a': [{'b': {'c': [1, 2, 3, 4]}}]}
        >>> invoke(obj, 'a[0].b.c.pop', 1)
        2
        >>> obj
        {'a': [{'b': {'c': [1, 3, 4]}}]}

    .. versionadded:: 1.0.0
    N)r   r   initiallastgetattrr   AttributeError)	r=   r   argsrN   pathstarget_pathmethod_namemethodrz   s	            r?   r    r      s    . DMME+e$$K(5//K&S+..<< fd%f%%    
 Js   A   A/.A/c                 4    d t          |           D             S )a  
    Creates a list composed of the keys of `obj`.

    Args:
        obj (mixed): Object to extract keys from.

    Returns:
        list: List of keys.

    Example:

        >>> keys([1, 2, 3])
        [0, 1, 2]
        >>> set(keys({'a': 1, 'b': 2, 'c': 3})) == set(['a', 'b', 'c'])
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 1.1.0
        Added ``keys_in`` as alias.

    .. versionchanged:: 4.0.0
        Removed alias ``keys_in``.
    c                     g | ]\  }}|S rx   rx   )rW   rP   rq   s      r?   
<listcomp>zkeys.<locals>.<listcomp>  s    ,,,FCC,,,r@   r   rZ   s    r?   r!   r!     s    2 -,hsmm,,,,r@   c                 6    d t          | |          D             S )a  
    The opposite of :func:`map_values`, this method creates an object with the same values as object
    and keys generated by running each own enumerable string keyed property of object thru iteratee.
    The iteratee is invoked with three arguments: ``(value, key, object)``.

    Args:
        obj (list|dict): Object to map.
        iteratee (mixed): Iteratee applied per iteration.

    Returns:
        list|dict: Results of running `obj` through `iteratee`.

    Example:

        >>> callback = lambda value, key: key * 2
        >>> results = map_keys({'a': 1, 'b': 2, 'c': 3}, callback)
        >>> results == {'aa': 1, 'bb': 2, 'cc': 3}
        True

    .. versionadded:: 3.3.0
    c                     i | ]
\  }}}}||S rx   rx   )rW   rp   rQ   rq   s       r?   r   zmap_keys.<locals>.<dictcomp>  s#    QQQ1feQFEQQQr@   rn   r=   r~   s     r?   r"   r"     s#    , RQ\#x5P5PQQQQr@   c                 6    d t          | |          D             S )a  
    Creates an object with the same keys as object and values generated by running each string keyed
    property of object thru iteratee. The iteratee is invoked with three arguments: ``(value, key,
    object)``.

    Args:
        obj (list|dict): Object to map.
        iteratee (mixed): Iteratee applied per iteration.

    Returns:
        list|dict: Results of running `obj` through `iteratee`.

    Example:

        >>> results = map_values({'a': 1, 'b': 2, 'c': 3}, lambda x: x * 2)
        >>> results == {'a': 2, 'b': 4, 'c': 6}
        True
        >>> results = map_values({'a': 1, 'b': {'d': 4}, 'c': 3}, {'d': 4})
        >>> results == {'a': False, 'b': True, 'c': False}
        True

    .. versionadded:: 1.0.0
    c                     i | ]
\  }}}}||S rx   rx   )rW   rp   rq   rP   s       r?   r   zmap_values.<locals>.<dictcomp>  s#    MMM-FAsACMMMr@   rn   r   s     r?   r#   r#     s#    0 NMc81L1LMMMMr@   c                     t          |          t          j        |           r$fd}t          | t	          | |                    S t          |           S )a  
    Map all non-object values in `obj` with return values from `iteratee`. The iteratee is invoked
    with two arguments: ``(obj_value, property_path)`` where ``property_path`` contains the list of
    path keys corresponding to the path of ``obj_value``.

    Args:
        obj (list|dict): Object to map.
        iteratee (callable): Iteratee applied to each value.
        property_path (mixed, optional): Path key(s) to access.

    Returns:
        mixed: The modified object.

    Warning:
        `obj` is modified in place.

    Example:

        >>> x = {'a': 1, 'b': {'c': 2}}
        >>> y = map_values_deep(x, lambda val: val * 2)
        >>> y == {'a': 2, 'b': {'c': 4}}
        True
        >>> z = map_values_deep(x, lambda val, props: props)
        >>> z == {'a': ['a'], 'b': {'c': ['b', 'c']}}
        True

    .. versionadded: 2.2.0

    .. versionchanged:: 3.0.0
        Allow iteratees to accept partial arguments.

    .. versionchanged:: 4.0.0
        Renamed from ``deep_map_values`` to ``map_values_deep``.
    c                 N    t          | t          j        |g                    S rU   )r$   r   flatten)rQ   rP   r~   
propertiess     r?   deep_iterateez&map_values_deep.<locals>.deep_iteratee-  s$    "5(CKS@Q4R4RSSSr@   )r   r   	is_objectr   r#   r   )r=   r~   property_pathr   r   s    `  @r?   r$   r$     sx    F ''J
}S 1	T 	T 	T 	T 	T 	T c:c=99:::hZ000r@   c                     t          | g|R  S )aT  
    Recursively merges properties of the source object(s) into the destination object. Subsequent
    sources will overwrite property assignments of previous sources.

    Args:
        obj (dict): Destination object to merge source(s) into.
        sources (dict): Source objects to merge from. subsequent sources overwrite previous ones.

    Returns:
        dict: Merged object.

    Warning:
        `obj` is modified in place.

    Example:

        >>> obj = {'a': 2}
        >>> obj2 = merge(obj, {'a': 1}, {'b': 2, 'c': 3}, {'d': 4})
        >>> obj2 == {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        True
        >>> obj is obj2
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 2.3.2
        Apply :func:`clone_deep` to each `source` before assigning to `obj`.

    .. versionchanged:: 2.3.2
        Allow `iteratee` to be passed by reference if it is the last positional argument.

    .. versionchanged:: 4.0.0
        Moved iteratee argument to :func:`merge_with`.

    .. versionchanged:: 4.9.3
        Fixed regression in v4.8.0 that caused exception when `obj` was ``None``.
    rl   r<   s     r?   r%   r%   5  s    L c$G$$$$r@   c                 Z   | dS t          |          }|                    dd          }|+|r)t          |d                   r|                                }d |D             }t          |          r't          t          |t          |d                    }nd}t          | g|R d|i|S )a  
    This method is like :func:`merge` except that it accepts customizer which is invoked to produce
    the merged values of the destination and source properties. If customizer returns ``None``,
    merging is handled by this method instead. The customizer is invoked with five arguments:
    ``(obj_value, src_value, key, obj, source)``.

    Args:
        obj (dict): Destination object to merge source(s) into.
        sources (dict): Source objects to merge from. subsequent sources
            overwrite previous ones.

    Keyword Args:
        iteratee (callable, optional): Iteratee function to handle merging
            (must be passed in as keyword argument).

    Returns:
        dict: Merged object.

    Warning:
        `obj` is modified in place.

    Example:

        >>> cbk = lambda obj_val, src_val: obj_val + src_val
        >>> obj1 = {'a': [1], 'b': [2]}
        >>> obj2 = {'a': [3], 'b': [4]}
        >>> res = merge_with(obj1, obj2, cbk)
        >>> obj1 == {'a': [1, 3], 'b': [2, 4]}
        True

    .. versionadded:: 4.0.0

    .. versionchanged:: 4.9.3
        Fixed regression in v4.8.0 that caused exception when `obj` was ``None``.
    Nr~   rC   c                 6    g | ]}t          j        |          S rx   )rL   deepcopy)rW   rO   s     r?   r   zmerge_with.<locals>.<listcomp>  s"    ;;;t}V$$;;;r@   rD   rE   rG   )rI   rK   rJ   r   r   r	   _merge_with)r=   r>   rN   r~   s       r?   r&   r&   ^  s    H {t7mmGzz*d++HG(=(=;;==;;7;;;G 68k(TU6V6V6VWWWsBWBBBxB6BBBr@   c           	         |                     d          }|                     d          }|t          }|D ]}t          |          D ]\  }}t          | |d           }t	          |t
                    ot	          |t
                    }	t	          |t                    ot	          |t                    }
d }|r ||||| |          }||}n|	s|
rt          ||||          }n|} || ||           | S )Nr~   rk   r   )r~   rk   )r   r   r
   r   
isinstancerI   dictr   )r=   r>   rN   r~   rj   rO   rP   	src_value	obj_valueall_sequencesall_mappings_resultrp   s                r?   r   r     s,   zz*%%HZZ	""F~ % %&v.. 	% 	%NC c4888I&y$77WJyRV<W<WM%i66V:iQU;V;VLG K"(9ic6JJ"  #, #$Y	HV\]]]"F3V$$$$!	%$ Jr@   c                 F    t          | t          j        |                    S )a  
    The opposite of :func:`pick`. This method creates an object composed of the property paths of
    `obj` that are not omitted.

    Args:
        obj (mixed): Object to process.
        *properties (str): Property values to omit.

    Returns:
        dict: Results of omitting properties.

    Example:

        >>> omit({'a': 1, 'b': 2, 'c': 3}, 'b', 'c') == {'a': 1}
        True
        >>> omit({'a': 1, 'b': 2, 'c': 3 }, ['a', 'c']) == {'b': 2}
        True
        >>> omit([1, 2, 3, 4], 0, 3) == {1: 2, 2: 3}
        True
        >>> omit({'a': {'b': {'c': 'd'}}}, 'a.b.c') == {'a': {'b': {}}}
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Moved iteratee argument to :func:`omit_by`.

    .. versionchanged:: 4.2.0
        Support deep paths.
    )r(   r   r   r=   r   s     r?   r'   r'     s    > 3J//000r@   c                 Z   t                    slt          j        t                    }t	          d |D                       rt          |           }nt          |           }d }t          j        |||          }n-t          d          fdt          |           D             }|S )a  
    The opposite of :func:`pick_by`. This method creates an object composed of the string keyed
    properties of object that predicate doesn't return truthy for. The predicate is invoked with two
    arguments: ``(value, key)``.

    Args:
        obj (mixed): Object to process.
        iteratee (mixed, optional): Iteratee used to determine which properties to omit.

    Returns:
        dict: Results of omitting properties.

    Example:

        >>> omit_by({'a': 1, 'b': '2', 'c': 3}, lambda v: isinstance(v, int))
        {'b': '2'}

    .. versionadded:: 4.0.0

    .. versionchanged:: 4.2.0
        Support deep paths for `iteratee`.
    c              3   <   K   | ]}t          |          d k    V  dS )r   N)len)rW   r   s     r?   rX   zomit_by.<locals>.<genexpr>  s,      //s4yy1}//////r@   c                 0    t          j        | |           | S rU   )r   r7   )r=   r   s     r?   _unsetzomit_by.<locals>._unset  s    Ic4   Jr@      rE   c                 B    i | ]\  }}t          ||           ||S )rG   r   )rW   rP   rQ   rH   r~   s      r?   r   zomit_by.<locals>.<dictcomp>  sF     
 
 
U(E3BBB

 
 
r@   )
rJ   r   map_r   anyr   r0   reduce_r	   r
   )r=   r~   r   clonedr   rz   rH   s    `    @r?   r(   r(     s    . H 
7++/////// 	"__FFS\\F	 	 	 k%00x333
 
 
 
 
&smm
 
 
 Jr@   c                     |s8t          j        |           r$	 t          | d           d}n# t          $ r Y nw xY w|sd}	 |dk    r| fnt	          |           |f}t          | }n# t          t
          f$ r d}Y nw xY w|S )a   
    Converts the given `value` into an integer of the specified `radix`. If `radix` is falsey, a
    radix of ``10`` is used unless the `value` is a hexadecimal, in which case a radix of 16 is
    used.

    Args:
        value (mixed): Value to parse.
        radix (int, optional): Base to convert to.

    Returns:
        mixed: Integer if parsable else ``None``.

    Example:

        >>> parse_int('5')
        5
        >>> parse_int('12', 8)
        10
        >>> parse_int('x') is None
        True

    .. versionadded:: 1.0.0
       
   N)r   	is_stringintr   r5   r   )rQ   radixr   parseds       r?   r)   r)     s    0  S]5)) 	rNNN EE  	 	 	D	
   !B;;xxYu-=-=u,Ed	"    Ms   + 
88 #A$ $A:9A:c                 F    t          | t          j        |                    S )a  
    Creates an object composed of the picked object properties.

    Args:
        obj (list|dict): Object to pick from.
        properties (str): Property values to pick.

    Returns:
        dict: Dict containing picked properties.

    Example:

        >>> pick({'a': 1, 'b': 2, 'c': 3}, 'a', 'b') == {'a': 1, 'b': 2}
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Moved iteratee argument to :func:`pick_by`.
    )r+   r   r   r   s     r?   r*   r*   3  s    * 3J//000r@   c                 <    t                      |t          |          r2t                     }|t          j        }d}nt          |d          }n||ng } fd}d}i }|D ]6}t           |          }t          ||||          rt          |||           7|S )a!  
    Creates an object composed of the object properties predicate returns truthy for. The predicate
    is invoked with two arguments: ``(value, key)``.

    Args:
        obj (list|dict): Object to pick from.
        iteratee (mixed, optional): Iteratee used to determine which properties to pick.

    Returns:
        dict: Dict containing picked properties.

    Example:

        >>> obj = {'a': 1, 'b': '2', 'c': 3 }
        >>> pick_by(obj, lambda v: isinstance(v, int)) == {'a': 1, 'c': 3}
        True

    .. versionadded:: 4.0.0
    Nr   r   rE   c                 $    t          |          S rU   )r   )rQ   r   r=   s     r?   r~   zpick_by.<locals>.iterateek  s    sD>>!r@   rG   )	r0   rJ   r!   r   identityr	   r   r   r-   )r=   r~   r   rH   rp   r   rQ   s   `      r?   r+   r+   K  s    ( #,,C8H--S		|HHH"8Q777HH$0b	" 	" 	" 	" 	" F & &C(E4(;;; 	&u%%%Mr@   c                 D    fd|                                  D             S )a  
    Rename the keys of `obj` using `key_map` and return new object.

    Args:
        obj (dict): Object to rename.
        key_map (dict): Renaming map whose keys correspond to existing keys in `obj` and whose
            values are the new key name.

    Returns:
        dict: Renamed `obj`.

    Example:

        >>> obj = rename_keys({'a': 1, 'b': 2, 'c': 3}, {'a': 'A', 'b': 'B'})
        >>> obj == {'A': 1, 'B': 2, 'c': 3}
        True

    .. versionadded:: 2.0.0
    c                 D    i | ]\  }}                     ||          |S rx   )r   )rW   rP   rQ   key_maps      r?   r   zrename_keys.<locals>.<dictcomp>  s-    GGGZS%GKKS!!5GGGr@   )rM   )r=   r   s    `r?   r,   r,   {  s(    ( HGGG399;;GGGGr@   c                 $    t          | ||          S )a  
    Sets the value of an object described by `path`. If any part of the object path doesn't exist,
    it will be created.

    Args:
        obj (list|dict): Object to modify.
        path (str | list): Target path to set value to.
        value (mixed): Value to set.

    Returns:
        mixed: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> set_({}, 'a.b.c', 1)
        {'a': {'b': {'c': 1}}}
        >>> set_({}, 'a.0.c', 1)
        {'a': {'0': {'c': 1}}}
        >>> set_([1, 2], '[2][0]', 1)
        [1, 2, [1]]
        >>> set_({}, 'a.b[0].c', 1)
        {'a': {'b': [{'c': 1}]}}

    .. versionadded:: 2.2.0

    .. versionchanged:: 3.3.0
        Added :func:`set_` as main definition and :func:`deep_set` as alias.

    .. versionchanged:: 4.0.0

        - Modify `obj` in place.
        - Support creating default path values as ``list`` or ``dict`` based on whether key or index
          substrings are used.
        - Remove alias ``deep_set``.
    )r.   )r=   r   rQ   s      r?   r-   r-     s    N Cu%%%r@   c                 L    t          | |t          j        |          |          S )aN  
    This method is like :func:`set_` except that it accepts customizer which is invoked to produce
    the objects of path. If customizer returns undefined path creation is handled by the method
    instead. The customizer is invoked with three arguments: ``(nested_value, key, nested_object)``.

    Args:
        obj (list|dict): Object to modify.
        path (str | list): Target path to set value to.
        value (mixed): Value to set.
        customizer (callable, optional): The function to customize assigned values.

    Returns:
        mixed: Modified `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> set_with({}, '[0][1]', 'a', lambda: {})
        {0: {1: 'a'}}

    .. versionadded:: 4.0.0

    .. versionchanged:: 4.3.1
        Fixed bug where a callable `value` was called when being set.
    r`   )r9   r   constant)r=   r   rQ   rB   s       r?   r.   r.     s%    8 sD#,u"5"5*MMMMr@   true1false0c                     t          j        |           r<|                                 } d }|r || |          rd}n#|r || |          rd}nd}nt          |           }|S )a  
    Convert `obj` to boolean. This is not like the builtin ``bool`` function. By default commonly
    considered strings values are converted to their boolean equivalent, i.e., ``'0'`` and
    ``'false'`` are converted to ``False`` while ``'1'`` and ``'true'`` are converted to ``True``.
    If a string value is provided that isn't recognized as having a common boolean conversion, then
    the returned value is ``None``. Non-string values of `obj` are converted using ``bool``.
    Optionally, `true_values` and `false_values` can be overridden but each value must be a string.

    Args:
        obj (mixed): Object to convert.
        true_values (tuple, optional): Values to consider ``True``. Each value must be a string.
            Comparision is case-insensitive. Defaults to ``('true', '1')``.
        false_values (tuple, optional): Values to consider ``False``. Each value must be a string.
            Comparision is case-insensitive. Defaults to ``('false', '0')``.

    Returns:
        bool: Boolean value of `obj`.

    Example:

        >>> to_boolean('true')
        True
        >>> to_boolean('1')
        True
        >>> to_boolean('false')
        False
        >>> to_boolean('0')
        False
        >>> assert to_boolean('a') is None

    .. versionadded:: 3.0.0
    c                     |                                  d |D             v rdS t          j        d                    |          |           S )Nc                 6    g | ]}|                                 S rx   )lower)rW   rR   s     r?   r   z5to_boolean.<locals>.boolean_match.<locals>.<listcomp>   s     <<<		<<<r@   T|)r   rematchjoin)textvalss     r?   boolean_matchz!to_boolean.<locals>.boolean_match  sE    zz||<<t<<<<<tx555r@   TFN)r   r   stripbool)r=   true_valuesfalse_valuesr   rQ   s        r?   r/   r/     s    B }S iikk	6 	6 	6  	==k:: 	EE 	mmC>> 	EEEES		Lr@   c                 z    	 t          |           S # t          $ r t          t          |                     cY S w xY w)a  
    Convert `obj` to ``dict`` by creating a new ``dict`` using `obj` keys and values.

    Args:
        obj: (mixed): Object to convert.

    Returns:
        dict: Object converted to ``dict``.

    Example:

        >>> obj = {'a': 1, 'b': 2}
        >>> obj2 = to_dict(obj)
        >>> obj2 == obj
        True
        >>> obj2 is not obj
        True

    .. versionadded:: 3.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``to_plain_object``.

    .. versionchanged:: 4.2.0
        Use ``pydash.helpers.iterator`` to generate key/value pairs.

    .. versionchanged:: 4.7.1
        Try to convert to ``dict`` using ``dict()`` first, then fallback to using
        ``pydash.helpers.iterator``.
    )r   	Exceptionr
   rZ   s    r?   r0   r0     sH    >#Cyy # # #HSMM"""""#s    &::c                 t    	 t          t          |                     }n# t          t          f$ r d}Y nw xY w|S )a  
    Converts `obj` to an integer.

    Args:
        obj (str|int|float): Object to convert.

    Returns:
        int: Converted integer or ``0`` if it can't be converted.

    Example:

        >>> to_integer(3.2)
        3
        >>> to_integer('3.2')
        3
        >>> to_integer('3.9')
        3
        >>> to_integer('invalid')
        0

    .. versionadded:: 4.0.0
    r   )r   floatr   r   )r=   nums     r?   r1   r1   6  sL    . %**oo	"    Js    55Tc                 z   t          | t                    r
| dd         S t          | t                    r|                                 S |st          | t          t
          f          r| gS |r.t          | t
                    rt          d | D                       S 	 t          |           S # t          $ r | gcY S w xY w)a  
    Converts a obj, an iterable or a single item to a list.

    Args:
        obj (mixed): Object to convert item or wrap.
        split_strings (bool, optional): Whether to split strings into single chars. Defaults to
            ``True``.

    Returns:
        list: Converted obj or wrapped item.

    Example:

        >>> results = to_list({'a': 1, 'b': 2, 'c': 3})
        >>> assert set(results) == set([1, 2, 3])

        >>> to_list((1, 2, 3, 4))
        [1, 2, 3, 4]

        >>> to_list(1)
        [1]

        >>> to_list([1])
        [1]

        >>> to_list(a for a in [1, 2, 3])
        [1, 2, 3]

        >>> to_list('cat')
        ['c', 'a', 't']

        >>> to_list('cat', split_strings=False)
        ['cat']

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.3.0

        - Wrap non-iterable items in a list.
        - Convert other iterables to list.
        - Byte objects are returned as single character strings in Python 3.
    Nc              3   b   K   | ]*}t          |t                    rt          |          n|V  +d S rU   )r   r   chr)rW   cs     r?   rX   zto_list.<locals>.<genexpr>  s;      EEAjC007CFFFaEEEEEEr@   )r   rI   r   r:   strbytesr   )r=   split_stringss     r?   r2   r2   W  s    V #t 111v	C		 zz|| 	z#U|<< 	u	 :c511 EEEEEEEE	99 	 	 	5LLL	s   B* *B:9B:c                     	 t          d|          }|dk     rt          j        }nt          } |t	          |           |z            |z  }n# t
          $ r d}Y nw xY w|S )a|  
    Convert `obj` to a number. All numbers are retuned as ``float``. If precision is negative, round
    `obj` to the nearest positive integer place. If `obj` can't be converted to a number, ``None``
    is returned.

    Args:
        obj (str|int|float): Object to convert.
        precision (int, optional): Precision to round number to. Defaults to ``0``.

    Returns:
        float: Converted number or ``None`` if can't be converted.

    Example:

        >>> to_number('1234.5678')
        1235.0
        >>> to_number('1234.5678', 4)
        1234.5678
        >>> to_number(1, 2)
        1.0

    .. versionadded:: 3.0.0
    r   r   N)powmathfloorroundr   r   )r=   	precisionfactorrounderr   s        r?   r3   r3     s{    0R##q== jGGGgeCjj6)**V3    Js   AA AAc                 4    d t          |           D             S )a  
    Creates a two dimensional list of an object's key-value pairs, i.e. ``[[key1, value1], [key2,
    value2]]``.

    Args:
        obj (mixed): Object to process.

    Returns:
        list: Two dimensional list of object's key-value pairs.

    Example:

        >>> to_pairs([1, 2, 3, 4])
        [[0, 1], [1, 2], [2, 3], [3, 4]]
        >>> to_pairs({'a': 1})
        [['a', 1]]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Renamed from ``pairs`` to ``to_pairs``.
    c                     g | ]	\  }}||g
S rx   rx   rV   s      r?   r   zto_pairs.<locals>.<listcomp>  s     999ZS%S%L999r@   r   rZ   s    r?   r4   r4     s    . :98C==9999r@   c                 \    t          j        |           r| }n| d}nt          |           }|S )a  
    Converts an object to string.

    Args:
        obj (mixed): Object to convert.

    Returns:
        str: String representation of `obj`.

    Example:

        >>> to_string(1) == '1'
        True
        >>> to_string(None) == ''
        True
        >>> to_string([1, 2, 3]) == '[1, 2, 3]'
        True
        >>> to_string('a') == 'a'
        True

    .. versionadded:: 2.0.0

    .. versionchanged:: 3.0.0
        Convert ``None`` to empty string.
    N )r   r   r   )r=   ress     r?   r5   r5     s9    4 }S 	#hhJr@   c                      t           j        dnt          d          g  fdt                     D             }t	          |d           S )aF  
    An alernative to :func:`pydash.collections.reduce`, this method transforms `obj` to a new
    accumulator object which is the result of running each of its properties through a iteratee,
    with each iteratee execution potentially mutating the accumulator object. The iteratee is
    invoked with four arguments: ``(accumulator, value, key, object)``. Iteratees may exit iteration
    early by explicitly returning ``False``.

    Args:
        obj (list|dict): Object to process.
        iteratee (mixed): Iteratee applied per iteration.
        accumulator (mixed, optional): Accumulated object. Defaults to ``list``.

    Returns:
        mixed: Accumulated object.

    Example:

        >>> transform([1, 2, 3, 4], lambda acc, v, k: acc.append((k, v)))
        [(0, 1), (1, 2), (2, 3), (3, 4)]

    .. versionadded:: 1.0.0
    Nr      rE   c           	   3   P   K   | ] \  }}t          ||           du dV  !dS )rG   FNr   )rW   rP   itemaccumulatorrH   r~   r=   s      r?   rX   ztransform.<locals>.<genexpr>  sS        C(KsC(KKKuTT 	TTTT r@   )r   r   r	   r
   r|   )r=   r~   r  r   rH   s   ``` @r?   r6   r6     s    . <x333      !#  D
 	tr@   c                 $    t          | ||          S )a  
    This method is like :func:`set_` except that accepts updater to produce the value to set. Use
    :func:`update_with` to customize path creation. The updater is invoked with one argument:
    ``(value)``.

    Args:
        obj (list|dict): Object to modify.
        path (str|list): A string or list of keys that describe the object path to modify.
        updater (callable): Function that returns updated value.

    Returns:
        mixed: Updated `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> update({}, ['a', 'b'], lambda value: value)
        {'a': {'b': None}}
        >>> update([], [0, 0], lambda value: 1)
        [[1]]

    .. versionadded:: 4.0.0
    )r9   )r=   r   updaters      r?   r8   r8   "  s    4 sD'***r@   c                 |   t          |          st          j        |          }|-t          |          st          t          t
          |d          }n+|r't          t          |t          |d                    }nd}t          | t                    rt          nt          }t          |          }t          j        |          s|g}t          j        |          }t          |t                    r|j        }| }t          t          j        |                    D ]\  }	}
t          |
t                    r$|
j        }t          j        ||	dz   dg|          }n|
}|}t%          ||d          }d}|r ||||          }|
 |            }t'          |||d	           	 t%          ||d          }# t(          $ rL}	 |t+          |                   }d}n# t,          $ r d
}Y nw xY w|rt)          d|d|           Y d}~d}~ww xY wt%          ||d          }t'          ||t	          ||                     | S )a4  
    This method is like :func:`update` except that it accepts customizer which is invoked to produce
    the objects of path. If customizer returns ``None``, path creation is handled by the method
    instead. The customizer is invoked with three arguments: ``(nested_value, key, nested_object)``.

    Args:
        obj (list|dict): Object to modify.
        path (str|list): A string or list of keys that describe the object path to modify.
        updater (callable): Function that returns updated value.
        customizer (callable, optional): The function to customize assigned values.

    Returns:
        mixed: Updated `obj`.

    Warning:
        `obj` is modified in place.

    Example:

        >>> update_with({}, '[0][1]', lambda: 'a', lambda: {})
        {0: {1: 'a'}}

    .. versionadded:: 4.0.0
    Nr   rG      rE   default_factoryr   F)allow_overrideTz!Unable to update object at index z. )rJ   r   r   r   r   r   r	   r   r   rI   r   is_listr   r   rP   	enumerater   r   r   r   r   r   r   )r=   r   r  rB   call_customizerdefault_typetokenslast_keytargetidxtokenrP   r  obj_valpath_objexc_failedrQ   s                     r?   r9   r9   ?  s   2 G (,w''hz&:&:!&%aHHH	 !&*{:_`?a?a?abbb%c400:44dLD!!F;v xH(I&&  <FF 3 344 T T
UeY'' 	+)C!gfsQw8I.JT`aaaOOC*O63555 	=&wV<<H&((Hhu====
	Tfc4888FF 	T 	T 	TC)     T RC R RS R RSSST T T T T	T VXt444EVXvgu55666Js6   F22
H=GHG$!H#G$$HHc                    t          |          }t          j        |          s|g}t          j        |          }t	          |t
                    r|j        }| }t          j        |          D ]t}t	          |t
                    r|j        }n|}	 	 ||         }n%# t          $ r |t          |                   }Y nw xY wn# t          $ r
 t          }Y nw xY w|t          u r nud}|t          ur_	 	 |                    |           d}n4# t          $ r' |                    t          |                     d}Y nw xY wn# t          $ r Y nw xY w|S )aE  
    Removes the property at `path` of `obj`.

    Note:
        Only ``list``, ``dict``, or objects with a ``pop()`` method can be unset by this function.

    Args:
        obj (mixed): The object to modify.
        path (mixed): The path of the property to unset.

    Returns:
        bool: Whether the property was deleted.

    Warning:
        `obj` is modified in place.

    Example:

        >>> obj = {'a': [{'b': {'c': 7}}]}
        >>> unset(obj, 'a[0].b.c')
        True
        >>> obj
        {'a': [{'b': {}}]}
        >>> unset(obj, 'a[0].b.c')
        False
    FT)r   r   r  r   r   r   rP   r   r   r   r   r   rK   )r=   r   r  r  r  r  rP   	did_unsets           r?   r7   r7     s   6 D!!F;v xH(I&&  <FV$$  eY'' 	)CCC	* * * *C)* 	 	 	FFF	 U??E  IU	!

8$$$ 		 ! ! !

3x==))) 			!  	 	 	D	 s`   BB?B;8B?:B;;B??CC/D D< .D85D< 7D88D< <
E	E	c                 4    d t          |           D             S )a  
    Creates a list composed of the values of `obj`.

    Args:
        obj (mixed): Object to extract values from.

    Returns:
        list: List of values.

    Example:

        >>> results = values({'a': 1, 'b': 2, 'c': 3})
        >>> set(results) == set([1, 2, 3])
        True
        >>> values([2, 4, 6, 8])
        [2, 4, 6, 8]

    .. versionadded:: 1.0.0

    .. versionchanged:: 1.1.0
        Added ``values_in`` as alias.

    .. versionchanged:: 4.0.0
        Removed alias ``values_in``.
    c                     g | ]\  }}|S rx   rx   )rW   rq   rQ   s      r?   r   zvalues.<locals>.<listcomp>  s    000haE000r@   r   rZ   s    r?   r:   r:     s    4 10(3--0000r@   Fc                    |rt           j        nt           j         }d}t          |          r+|s)t          |d          }t	          t
          ||          }n|r|}nd}|r || ||           }||S |s ||           }n| }|rit          j        |           sUt          | t                    s@t          |           D ]0\  }}	|rt          |	|||d          }
n ||	||           }
|
|
||<   1|S )zEBase clone function that supports deep clone and customizer callback.Nr  rE   rG   T)_cloned)rL   r   rJ   r	   r   r   r   r   r   r   r
   r]   )rQ   rc   rB   rP   r'  clone_byrp   rH   cbksubvaluerR   s              r?   r]   r]     s:    '6t}}TYHF
 G z1555fj8<<<	 
 (UC'' %
 "3='' "
5%0H0H "%e__ 	" 	"MC 0 7CdKKKc(C//!sMr@   rU   )r   r   )T)r   )NN)FNNF)C__doc__rL   	functoolsr   r   r   pydashr   helpersr   r   r   r   r	   r
   r   	utilitiesr   r   r   __all__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r8   r9   r7   r:   r]   rx   r@   r?   <module>r1     s            				     [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ 9 9 9 9 9 9 9 9 9 9-`'& '& '&T3 3 3lJ J J4  :4 4 4 40+ + +<B B B B  B5 5 5B   4   :   @   <C C C CL, , ,^8 8 8<' ' ' 'T" " "J- - -8R R R R2N N N N6 #'e ,1 ,1 ,1 ,1^&% &% &%R4C 4C 4Cn  :1 1 1D- - - -`, , , ,^1 1 10- - - -`H H H.'& '& '&TN N N N>3 3 3 3l"# "# "#J  B8 8 8 8v& & & &R: : :4     F' ' ' 'T+ + +:R R R RjE E EP1 1 1D" " " " " "r@   