HEX
Server: Apache
System: Linux server2.voipitup.com.au 4.18.0-553.104.1.lve.el8.x86_64 #1 SMP Tue Feb 10 20:07:30 UTC 2026 x86_64
User: posscale (1027)
PHP: 8.2.29
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/__pycache__/data.cpython-310.pyc
o

�N�g@��@sTdZddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
mZmZddl
ZddlZddlZddlmZddlmZddlmZddlmZzddlZWneyadZYnwdZe�e�ZGd	d
�d
e�Zdidd
�Z didd�Z!didd�Z"ed�djdd��Z#ed�djdd��Z$dkdd�Z%							dldd�Z&							dldd�Z'							dldd�Z(						dmdd �Z)					dnd!d"�Z*ed#�ed$�					dnd%d&���Z+ed'�ed(�					dnd)d*���Z,	dod+d,�Z-ed-�dpd/d0��Z.ed1�d2d3��Z/dqd5d6�Z0defd7d8�Z1ed9�defd:d;��Z2eddfd<d=�Z3ed>�d?d@��Z4dAdB�Z5drdCdD�Z6edE�dFdE��Z7edG�e8ffdHdG��Z9edI�dJdI��Z:dkdKdL�Z;edM�dNdM��Z<dOdP�Z=dQdR�Z>edS�dTdS��Z?dsdVdW�Z@dtdXdY�ZA	dudZd[�ZBdkd\d]�ZCed^�dvd_d^��ZDdwdadb�ZEedc�dkddde��ZFedf�dkdgdh��ZGdS)xzc
Functions for manipulating, inspecting, or otherwise working with data types
and data structures.
�N)�Mapping�MutableMapping�Sequence)�DEFAULT_TARGET_DELIM)�
SaltException)�jinja_filter)�OrderedDict�algorithms_guaranteedc@sbeZdZdZddd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dS)�CaseInsensitiveDictzq
    Inspired by requests' case-insensitive dict implementation, but works with
    non-string keys as well.
    NcKs"t�|_|j|p	ifi|��dS)zy
        Force internal dict to be ordered to ensure a consistent iteration
        order, irrespective of case.
        N)r�_data�update)�self�init�kwargs�r�C/opt/saltstack/salt/lib/python3.10/site-packages/salt/utils/data.py�__init__(szCaseInsensitiveDict.__init__cCs
t|j�S�N)�lenr�r
rrr�__len__0s
zCaseInsensitiveDict.__len__cCs||f|jt|�<dSr�r�to_lowercase)r
�key�valuerrr�__setitem__3szCaseInsensitiveDict.__setitem__cCs|jt|�=dSrr�r
rrrr�__delitem__7�zCaseInsensitiveDict.__delitem__cCs|jt|�dS)N�rrrrr�__getitem__:szCaseInsensitiveDict.__getitem__cC�dd�|j��D�S)Ncss�|]}|dVqdS)rNr��.0�itemrrr�	<genexpr>>��z/CaseInsensitiveDict.__iter__.<locals>.<genexpr>)r�valuesrrrr�__iter__=szCaseInsensitiveDict.__iter__cCs*t|t�sdSt|���tt|����kS)NF)�
isinstancer�dict�items_lowerr
)r
Zrvalrrr�__eq__@s
zCaseInsensitiveDict.__eq__cCstt|����Sr)�reprr*�itemsrrrr�__repr__FrzCaseInsensitiveDict.__repr__cCr!)zp
        Returns a generator iterating over keys and values, with the keys all
        being lowercase.
        css �|]\}}||dfVqdS)rNr�r#r�valrrrr%Ns�z2CaseInsensitiveDict.items_lower.<locals>.<genexpr>)rr.rrrrr+IszCaseInsensitiveDict.items_lowercCst|j���S)z.
        Returns a copy of the object
        )r
rr.rrrr�copyPszCaseInsensitiveDict.copyr)�__name__�
__module__�__qualname__�__doc__rrrrr r(r,r/r+r2rrrrr
"s
r
Fcs|zt|���WStyYnw|j}t|t�r+�r|nt��fdd�|��D��St|t�r<|��fdd�|D��S|S)z�
    Calls data.attr() if data has an attribute/method called attr.
    Processes data recursively if data is a Mapping or Sequence.
    For Mapping, processes both keys and values.
    c3s,�|]\}}t|���t|���fVqdSr��
__change_caser0��attr�preserve_dict_classrrr%es�
�
�
�z __change_case.<locals>.<genexpr>c3s�|]	}t|���VqdSrr7r"r9rrr%ms�
�)�getattr�AttributeError�	__class__r)rr*r.r)�datar:r;Z	data_typerr9rr8Ws�
�
�r8cC�t|d|�S)z>
    Recursively changes everything in data to lowercase.
    �lowerr7�r?r;rrrrs�rcCr@)z>
    Recursively changes everything in data to uppercase.
    �upperr7rBrrr�to_uppercasezrCrE�
compare_dictscCs�i}t|pi��|pi�D]1}||vrd||d�||<q
||vr+d||d�||<q
||||kr>||||d�||<q
|S)z�
    Compare before and after results from various salt functions, returning a
    dict describing the changes that were made.
    ���old�new)rJrI)�set�union)rIrJ�retrrrrrF�s��
compare_listscCsPi}|D]}||vr|�dg��|�q|D]}||vr%|�dg��|�q|S)z�
    Compare before and after results from various salt functions, returning a
    dict describing the changes that were made
    rJrI)�
setdefault�append)rIrJrMr$rrrrN�s��cs��durt��t|��vrt�d|�dS��t|��|}t|t�r/�fdd�|��D�}nt|tt	tt
f�rEt|��fdd�|D��}��t|��|S)a�
    Generic method to remove circular references from objects.
    This has been taken from author Martijn Pieters
    https://stackoverflow.com/questions/44777369/
    remove-circular-references-in-dicts-lists-tuples/44777477#44777477
    :param ob: dict, list, tuple, set, and frozenset
        Standard python object
    :param object _seen:
        Object that has circular reference
    :returns:
        Cleaned Python object
    :rtype:
        type(ob)
    NzZCaught a circular reference in data structure below.Cleaning and continuing execution.
%r
cs"i|]
\}}t|��t|���qSr��_remove_circular_refs)r#�k�v��_seenrr�
<dictcomp>�s��z)_remove_circular_refs.<locals>.<dictcomp>c3s�|]}t|��VqdSrrQ)r#rTrUrrr%�s�z(_remove_circular_refs.<locals>.<genexpr>)
rK�id�log�	exception�addr)r*r.�list�tuple�	frozenset�type�remove)�obrV�resrrUrrR�s$�

�rR�strictc		Cs�t|�}|stjjjntjjj}t|t�r t||||||||�St|t	�r0t
||||||||�St|t�rL|rAt|||||||�St
||||||||�St|t
j
�rV|��Sz
|||||�}W|StyjY|Styv|ss�Y|Sw)ub
    Generic function which will decode whichever type is passed, if necessary.
    Optionally use to_str=True to ensure strings are str types and not unicode
    on Python 2.

    If `strict` is True, and `keep` is False, and we fail to decode, a
    UnicodeDecodeError will be raised. Passing `keep` as True allows for the
    original value to silently be returned in cases where decoding fails. This
    can be useful for cases where the data passed to this function is likely to
    contain binary blobs, such as in the case of cp.recv.

    If `normalize` is True, then unicodedata.normalize() will be used to
    normalize unicode strings down to a single code point per glyph. It is
    recommended not to normalize unless you know what you're doing. For
    instance, if `data` contains a dictionary, it is possible that normalizing
    will lead to data loss because the following two strings will normalize to
    the same value:

    - u'\u044f\u0438\u0306\u0446\u0430.txt'
    - u'\u044f\u0439\u0446\u0430.txt'

    One good use case for normalization is in the test suite. For example, on
    some platforms such as Mac OS, os.listdir() will produce the first of the
    two strings above, in which "й" is represented as two code points (i.e. one
    for the base character, and one for the breve mark). Normalizing allows for
    a more reliable test case.

    )rR�salt�utils�stringutils�
to_unicode�to_strr)r�decode_dictr\�decode_listr]�decode_tuple�datetime�	isoformat�	TypeError�UnicodeDecodeError)	r?�encoding�errors�keep�	normalizer;�preserve_tuplesrhZ_decode_funcrrr�decode�st'��
�

�

�����	����rucCs�t|�}|r
|��ni}|��D]�\}	}
t|	t�r1|r%t|	||||||�n
t|	|||||||�}	n"z
t|	|||||||�}	WntyGYnt	yR|sP�Ynwt|
t
�rdt|
|||||||�}
nYt|
t�r�|rut|
||||||�n
t|
|||||||�}
n<t|
t�r�t|
|||||||�}
n+z
t|
|||||||�}
Wnty�}zWYd}~nd}~wt	y�|s��Ynw|
||	<q|S)��
    Decode all string values to Unicode. Optionally use to_str=True to ensure
    strings are str types and not unicode on Python 2.
    N)
rRr>r.r)r]rkrjrurnror\rri)r?rprqrrrsr;rtrhrMrr�errrri1s�
�������
�

��
��
��
���
ric

Cs�t|�}g}|D]h}	t|	t�rt|	|||||||�}	nPt|	t�r8|r,t|	||||||�n
t|	|||||||�}	n3t|	t�rIt|	|||||||�}	n"z
t|	|||||||�}	Wnt	y_Ynt
yj|sh�Ynw|�|	�q|S)rv)rRr)r\rjr]rkrrirurnrorP)
r?rprqrrrsr;rtrhrMr$rrrrj�sz
�

����
����rjc
Cstt||||||d|��S)rvT)r]rj)r?rprqrrrsr;rhrrrrks

��rkcCs�t|�}t|t�rt||||||�St|t�r t||||||�St|t�r8|r/t|||||�St||||||�Sz
tj	j
�|||�WStyLY|St
yX|sU�Y|Sw)a�
    Generic function which will encode whichever type is passed, if necessary

    If `strict` is True, and `keep` is False, and we fail to encode, a
    UnicodeEncodeError will be raised. Passing `keep` as True allows for the
    original value to silently be returned in cases where encoding fails. This
    can be useful for cases where the data passed to this function is likely to
    contain binary blobs.

    )rRr)r�encode_dictr\�encode_listr]�encode_tuplerdrerf�to_bytesrn�UnicodeEncodeError)r?rprqrrr;rtrrr�encodes8
�
�
�������r}Zjson_decode_dictZjson_encode_dictc		CsVt|�}|r
|��ni}|��D]�\}}t|t�r-|r#t|||||�nt||||||�}n ztjj	�
|||�}WntyAYntyL|sJ�Ynwt|t
�r\t||||||�}nHt|t�ru|rkt|||||�nt||||||�}n/t|t�r�t||||||�}n ztjj	�
|||�}Wnty�Ynty�|s��Ynw|||<q|S�z+
    Encode all string values to bytes
    )rRr>r.r)r]rzryrdrerfr{rnr|r\rrx)	r?rprqrrr;rtrMrrrrrrxLsZ
�����
�
���
���
rxZjson_decode_listZjson_encode_listc	Cs�t|�}g}|D]^}t|t�rt||||||�}nHt|t�r2|r(t|||||�nt||||||�}n/t|t�rAt||||||�}n ztj	j
�|||�}WntyUYnt
y`|s^�Ynw|�|�q|Sr~)rRr)r\ryr]rzrrxrdrerfr{rnr|rP)r?rprqrrr;rtrMr$rrrry�s:
�
���
���rycCstt|||||d��S)z-
    Encode all string values to Unicode
    T)r]ry)r?rprqrrr;rrrrz��rzZexactly_n_truercs,t|��t�fdd�t|�D��ot��S)zb
    Tests that exactly N items in an iterable are "truthy" (neither None,
    False, nor 0).
    c3s�|]}t��VqdSr��any)r#�j��irrr%�r&zexactly_n.<locals>.<genexpr>)�iter�all�ranger�)�iterable�amountrr�r�	exactly_n�s$r�Zexactly_one_truecCst|�S)zI
    Check if only one item is not None, False, or 0 in an iterable.
    )r�)r�rrr�exactly_one�sr��defaultc
Cs,d}t||g�}t|t�r|n|gD]/}|D]$}	t|	t�r|	nt|	�}
t|t�r*|nt|�}t�||
�r:||	}nq|durAnq|durL|�|d�}|rv||vrv||}|dur]|}nt|t�rvt|t�sktd��t	j
j�t
�|�|�}|r�t|t�s�td��|dur�|}|St	j
j�|t
�|��|S)zF
    Common code to filter data structures like grains and pillar
    Nz?filter_by default and look-up values must both be dictionaries.z.filter_by merge argument must be a dictionary.)�traverse_dict_and_listr)r\�str�fnmatch�fnmatchcase�getrrrdreZ
dictupdaterr2�deepcopy)
Zlookup_dict�lookup�traverse�merger��baserMr1�eachrZtest_keyZ	test_eachZbase_valuesrrr�	filter_by�sB��

�
�r�c
Cs@|}z|�|�D]}||}qW|Stttfy|YSw)a
    Traverse a dict using a colon-delimited (or otherwise delimited, using the
    'delimiter' param) target string. The target 'foo:bar:baz' will return
    data['foo']['bar']['baz'] if this value exists, and will otherwise return
    the dict in the default argument.
    )�split�KeyError�
IndexErrorrn)r?rr��	delimiter�ptrr�rrr�
traverse_dict
s
���r�r�c
Cs�|}t|t�r|�|�}t|t�r|g}|D]�}t|t�r�zt|�}Wn/tyRd}dd�|D�D]}z	||}d}Wn	tyGYq3w|sP|YSYqwd}dd�|D�D]}z	||}d}Wn	typYq\w|s�z||}Wqty�|YSwqz||}Wqty�ddl}	z	|	j	j
�|�}
Wnty�|YYSw|
|kr�|YSz||
}Wntt
fy�|YYSwYqt
y�|YSw|S)a	
    Traverse a dict or list using a colon-delimited (or otherwise delimited,
    using the 'delimiter' param) target string. The target 'foo:bar:0' will
    return data['foo']['bar'][0] if this value exists, and will otherwise
    return the dict in the default argument.
    Function will automatically determine the target type.
    The target 'foo:bar:0' will return data['foo']['bar'][0] if data like
    {'foo':{'bar':['baz']}} , if data like {'foo':{'bar':{'0':'baz'}}}
    then return data['foo']['bar']['0']
    Fcs��|]
}t|t�r|VqdSr�r)r*�r#�xrrrr%8��z)traverse_dict_and_list.<locals>.<genexpr>Tcsr�rr�r�rrrr%Fr�rN)r)r�r��intr\�
ValueErrorr�r�Zsalt.utils.argsre�argsZyamlify_arg�	Exceptionrn)r?rr�r�r�r��idxZembed_matchZembeddedrdZ
loaded_keyrrrr�sx



����������r�cs>ddd��d��fdd�	�|�|�}t|�}|dkrdSt|ddd�D]x}|�|d	|��}|d
kr8|}	|}
n|�||d	��}	t||i|d�}
t�d|	||�|
ikrVq$t|
t�rg�|
|	||d
�rfdSq$t|
t	t
f�r�|
D]}t|t�r��||	||d
�r�dS�||	||d
�r�dSqpq$�|
|	||d
�r�dSq$dS)af
    Check for a match in a dictionary using a delimiter character to denote
    levels of subdicts, and also allowing the delimiter character to be
    matched. Thus, 'foo:bar:baz' will match data['foo'] == 'bar:baz' and
    data['foo']['bar'] == 'baz'. The latter would take priority over the
    former, as more deeply-nested matches are tried first.
    FcSs�zt|���}Wntytjj�|���}Ynwzt|���}Wnty5tjj�|���}Ynw|rPzt�||�WSt	yOt
�d|�YdSw|rV||kSt�||�S)NzInvalid regex '%s' in matchF)
r�rArordrerfrg�re�matchr�rY�errorr�)�target�pattern�regex_match�exact_matchrrr�_match|s*���
�
�zsubdict_match.<locals>._matchcs�d}|�d�}|r|dd�}|dkrd}|s||vrd}|s)t||||d�r)d}|so|ro|D]?}t||t�rF�|||||d�rEdSq/t||t�ra||D]}�||||d�r_dSqQq/�|||||d�rndSq/|S)NFz*:��*T�r�r�)�
startswith�
subdict_matchr)r*r\)r�r�r�r�rMZwildcardrr$��_dict_matchr�rrr��sV
��������z"subdict_match.<locals>._dict_matchrr���Nr�)r�z5Attempting to match '%s' in '%s' using delimiter '%s'r�T)FF)r�rr��joinr�rY�debugr)r*r\r])r?�exprr�r�r�ZsplitsZ
num_splitsr�rZmatchstrr��memberrr�rr�qs^

,�
�
����r�Zsubstring_in_listcst�fdd�|D��S)z�
    Return a boolean value that indicates whether or not a given
    string is present in any of the strings which comprise a list
    c3s�|]}�|vVqdSrr)r#�s��string_to_search_forrrr%�r&z!substr_in_list.<locals>.<genexpr>r�)r�Zlist_to_searchrr�r�substr_in_list�rr�cCs>t|t�r|D]}t|t�rt|�dkrdSqdSdSdS)zy
    Returns True if data is a list of one-element dicts (as found in many SLS
    schemas), otherwise returns False
    rFT)r)r\r*r)r?�elementrrr�is_dictlist�s

�r�c
Cs�t|t�r,z	tjj�|�}Wntjjjjy+}z
t�	|�iWYd}~Sd}~ww|dur4dd�}|dur<dd�}tft
ftf}t|t�rs|D]'}t||�rRqJt|t
�rht|�dkrgt�	d|�iSqJt�	d|�iSnt�	d	|�iSi}|D]G}t||�r�d|||�<qtt|��}	||	}
t|
�r�|r�t|
|d
�|||	�<q|r�t�	d�iS||	|
�|||	�<q||	|
�|||	�<q|S)zt
    Takes a list of one-element dicts (as found in many SLS schemas) and
    repacks into a single dictionary.
    NcS�|Srr�r�rrr�key_cb�zrepack_dictlist.<locals>.key_cbcSs|Srr)r��yrrr�val_cb!r�zrepack_dictlist.<locals>.val_cbrzcInvalid input for repack_dictlist: key/value pairs must contain only one element (data passed: %s).zPInvalid input for repack_dictlist: element %s is not a string/dict/numeric valuezAInvalid input for repack_dictlist, data passed is not a list (%s))�recursezUInvalid input for repack_dictlist: nested dictlist found, but recurse is set to False)r)r�rdreZyamlZ	safe_load�parserZParserErrorrYr�r��floatr\r*r�nextr�r��repack_dictlist)r?rcr�r�r��errZvalid_non_dictr�rMrr1rrrr�sh

��


�����
�r��is_listcCs
t|t�S)z(
    Check if a variable is a list.
    )r)r\�rrrrr�Us
�is_itercCs6|r	t||�r	dSzt|�WdStyYdSw)a�
    Test if an object is iterable, but not a string type.

    Test if an object is an iterator or is iterable itself. By default this
    does not return True for string objects.

    The `ignore` argument defaults to a list of string types that are not
    considered iterable. This can be used to also exclude things like
    dictionaries or named tuples.

    Based on https://bitbucket.org/petershinners/yter
    FT)r)r�rn)�thing�ignorerrrr�]s��sorted_ignorecasecCst|dd�d�S)z�
    Sort a list of strings ignoring case.

    >>> L = ['foo', 'Foo', 'bar', 'Bar']
    >>> sorted(L)
    ['Bar', 'Foo', 'bar', 'foo']
    >>> sorted(L, key=lambda x: x.lower())
    ['bar', 'Bar', 'foo', 'Foo']
    >>>
    cSs|��Sr)rAr�rrr�<lambda>�sz#sorted_ignorecase.<locals>.<lambda>�r)�sorted)Zto_sortrrrr�tsc	Cs�zt|�}WnttfyYnwzt|�}Wnttfy#Ynwt|tftf�r0|dkSt|t�r=t|���dkSt|�S)a
    Returns a boolean value representing the "truth" of the value passed. The
    rules for what is a "True" value are:

        1. Integer/float values greater than 0
        2. The string values "True" and "true"
        3. Any object for which bool(obj) returns True
    r�true)r�r�rnr�r)r�rA�boolr�rrr�is_true�s
��
r��
mysql_to_dictcCs�i}dg}|D]O}|sq|�d�rq|�d�}t|�D]
\}}|��||<qt|�dkrTt|�d}i}	t|�D]}
|
dkr?q8tjj�	||
�|	||
<q8|	||	|<q|}q|S)z;
    Convert MySQL-style output to a python dictionary
    rG�+�|r)
r�r��	enumerate�striprr�rdrerfZto_num)r?rrM�headers�line�compsr��comp�index�row�fieldrrrr��s(

cCs|dur|Stfttfttf}tt|�ttg�}t|ttf�rGg}|D] }|dur?t|ttf�r6t|�}n	t||�s?t	|�}|�
|�q$|St|t�r�i}|��D]3\}}|durct||�sct	|�}|durtt|tttf�rtt|�}n
|dur�t||�s�t	|�}|||<qR|S|S)zg
    Convert the data list, dictionary into simple types, i.e., int, float, string,
    bool, etc.
    N)r�r�r�r�r]r\r)r*�simple_types_filterr-rPr.)r?Zsimpletypes_keysZsimpletypes_valuesZsimplearrayrZ
simpledictrrrrr��s4




r�cCs.g}|D]}t|t�st|�}|�|�q|S)zu
    Given an iterable, returns its items as a list, with any non-string items
    converted to unicode strings.
    )r)r�rP)r?rMr$rrr�	stringify�s
r��
json_querycCs*tdurd}t�|�t|��t�||�S)aj
    Query data using JMESPath language (http://jmespath.org).

    Requires the https://github.com/jmespath/jmespath.py library.

    :param data: A complex data structure to query
    :param expr: A JMESPath expression (query)
    :returns: The query result

    .. code-block:: jinja

        {"services": [
            {"name": "http", "host": "1.2.3.4", "port": 80},
            {"name": "smtp", "host": "1.2.3.5", "port": 25},
            {"name": "ssh",  "host": "1.2.3.6", "port": 22},
        ]} | json_query("services[].port") }}

    will be rendered as:

    .. code-block:: text

        [80, 25, 22]
    Nz-json_query requires jmespath module installed)�jmespathrYr��RuntimeError�search)r?r�r�rrrr��s

rcCst|t�pt|�|vp|S)z�
    Helper function for filter_falsey to determine if something is not to be
    considered falsey.

    :param any value: The value to consider
    :param list ignore_types: The types to ignore when considering the value.

    :return bool
    )r)r�r_)r�ignore_typesrrr�_is_not_considered_falseys
r�cs�|rtjt|d�d�ndd��t|t�r-�fdd�|��D�}t|��fdd�|D��St|�rG�fdd	�|D�}t|��fd
d�|D��S|S)a�
    Helper function to remove items from an iterable with falsey value.
    Removes ``None``, ``{}`` and ``[]``, 0, '' (but does not remove ``False``).
    Recurses into sub-iterables if ``recurse`` is set to ``True``.

    :param dict/list data: Source iterable (dict, OrderedDict, list, set, ...) to process.
    :param int recurse_depth: Recurse this many levels into values that are dicts
        or lists to also process those. Default: 0 (do not recurse)
    :param list ignore_types: Contains types that can be falsey but must not
        be filtered. Default: Only booleans are not filtered.

    :return type(data)

    .. versionadded:: 3000
    r)�
recurse_depthr�cSr�rrr�rrrr�.szfilter_falsey.<locals>.<lambda>csg|]
\}}|�|�f�qSrr�r#rr��filter_elementrr�
<listcomp>2s�z!filter_falsey.<locals>.<listcomp>cs$g|]\}}t|�d�r||f�qS��r��r�r�r�rrr�6s
��c3s�|]}�|�VqdSrr�r#rr�rrr%=r&z filter_falsey.<locals>.<genexpr>csg|]
}t|�d�r|�qSr�r�r�r�rrr�?s
��)�	functools�partial�
filter_falseyr)r*r.r_r�)r?r�r�Zprocessed_elementsr)r�r�rr�s.�
��

�
��
��r�c	Cs�|pg}i}t�|�}t�|�}t|t�r�t|t�r�|s�gg}}	t|�t|�krFtt|�t|��}
t|���|
d�}t|���|
d�}	t||�D]D\}}||kr�||vr^||=||=qKt	|||||||d�}|st||=||=qK|d||<|d||<qK||vr�||=||vr�||=qK|D]}
||
||
<q�|	D]}
||
||
<q�|s�|r�||d�}|Si}|St|t
��r+t|t
��r+tt|�t|��D]N}||vr�|�|d�|�|d�q�|r�||vr�||vr�||=q�||v�r||v�rt	|||||||d�}|�s
||=||=q�|d||<|d||<q�|�s |�r'||d�}|Si}|St|t��rPt|t��rP||�sA||�rL||||d�}|Si}|St
|��r�t
|��r�t|�}t|�}|�r�|D]!}|D]}t	|||||d�}|�s�|�|�|�|��qk�qk�qgnBg}tt||��D]&\}\}}t	|||||d�}|�s�|�|��q�|d||<|d||<�q�t|�D]
}|�|�|�|��q�|�s�|�r�t|�|�t|�|�d�}|Si}|S||k�r�in||d�}|S)ax
    Performs a recursive diff on mappings and/or iterables and returns the result
    in a {'old': values, 'new': values}-style.
    Compares dicts and sets unordered (obviously), OrderedDicts and Lists ordered
    (but only if both ``old`` and ``new`` are of the same type),
    all other Mapping types unordered, and all other iterables ordered.

    :param mapping/iterable old: Mapping or Iterable to compare from.
    :param mapping/iterable new: Mapping or Iterable to compare to.
    :param list ignore_keys: List of keys to ignore when comparing Mappings.
    :param bool ignore_order: Compare ordered mapping/iterables as if they were unordered.
    :param bool ignore_missing_keys: Do not return keys only present in ``old``
        but missing in ``new``. Only works for regular dicts.

    :return dict: Returns dict with keys 'old' and 'new' containing the differences.
    N)�ignore_keys�ignore_order�ignore_missing_keysrIrJrH)r2r�r)rr�minr\�keys�zip�recursive_diffrrK�popr�r`r�rP�reversedr_)rIrJr�r�r�rbZret_oldZret_newZ
append_oldZ
append_newZ
min_lengthZkey_oldZkey_newr$rMrZlist_oldZlist_newZitem_oldZitem_newZremove_indicesr�Ziter_oldZiter_newrrrrHs�

���
��H�H���1�1�&/�/��

����
������rcsFd|ig}|r�d|vr|d|�d��n|}d|vr%||�d�dd�nd�|�d�rl|�d�rl|dd��g}|dur?|St|t�rI|��}n	t|t�rRt|�}�fdd	�����fd
d�|D�}dd�|D�}|St|t�r�||��vr|d�igS|�	|�}|dur�t
|���}|Sd|ig}|Sd|dur��igS|igS|S)
a�
    Get the values for a given path.

    :param path:
        keys of the properties in the tree separated by colons.
        One segment in the path can be replaced by an id surrounded by curly braces.
        This will match all items in a list of dictionary.

    :param default:
        default value to return when no value is found

    :return:
        a list of dictionaries, with at least the "value" key providing the actual value.
        If a placeholder was used, the placeholder id will be a key providing the replacement for it.
        Note that a value that wasn't found in the tree will be an empty list.
        This ensures we can make the difference with a None value set by the user.
    r�:Nr�{�}r�cs||�<|Srr)Z
value_dictr)�placeholder_namerr�_append_placeholder�sz&get_value.<locals>._append_placeholdercs,g|]\�}��fdd�t|���D��qS)csg|]}�|���qSrrr")rrrrr��s��z(get_value.<locals>.<listcomp>.<listcomp>)�	get_value)r#r1)rr��	next_pathr�rr��s�
��zget_value.<locals>.<listcomp>cSsg|]	}|D]}|�qqSrr)r#r�r�rrrr�s)�findr��endswithr)r*r.r\r�r�r�r	)�obj�pathr�rbrr.r'rr)rr�r
rrr	�s<
"


�	



��r	�flattenc	Cs�|durt�}t|�|vrtd��|�t|��g}|D];}|s%|dvr%qt|�rR|dur8|�t|||d��q|dkrL|�t|t|�d||d��q|�|�q|�|�q|S)aT
    .. versionadded:: 3005

    Flatten a list.

    :param data: A list to flatten

    :param levels: The number of levels in sub-lists to descend

    :param preserve_nulls: Preserve nulls in a list, by default flatten removes
                           them

    :param _ids: Parameter used internally within the function to detect
                 reference cycles.

    :returns: A flat(ter) list of values

    .. code-block:: jinja

        {{ [3, [4, 2] ] | flatten }}
        # => [3, 4, 2]

    Flatten only the first level of a list:

    .. code-block:: jinja

        {{ [3, [4, [2]] ] | flatten(levels=1) }}
        # => [3, 4, [2]]

    Preserve nulls in a list, by default flatten removes them.

    .. code-block:: jinja

        {{ [3, None, [4, [2]] ] | flatten(levels=1, preserve_nulls=True) }}
        # => [3, None, 4, [2]]
    Nz+Reference cycle detected. Check input list.)N�None�null)�preserve_nulls�_idsr)�levelsrr)	rKrX�RecursionErrorr[r��extendrr�rP)r?rrrrMr�rrrrs0&
��	�sha512cCs~t|t�r
|�t�}ttt�r&|ttt�vr&t�|�}|�	|�|�
�}|Stt|�r;t�|�}|�	|�|�
�}|Std��)z�
    .. versionadded:: 2014.7.0

    Encodes a value with the specified encoder.

    value
        The value to be hashed.

    algorithm : sha512
        The algorithm to use. May be any valid algorithm supported by
        hashlib.
    z#You must specify a valid algorithm.)r)r�r}Z__salt_system_encoding__�hasattr�hashlib�ALGORITHMS_ATTR_NAMEr<rJr�	hexdigestr)r�	algorithmZhasher�outrrr�hashYs

�


�

�rZ
random_samplecCs2|durt�||�}|St�t|���||�}|S)aS
    Return a given sample size from a list. By default, the random number
    generator uses the current system time unless given a seed value.

    .. versionadded:: 3005

    value
        A list to e used as input.

    size
        The sample size to return.

    seed
        Any value which will be hashed as a seed for random.
    N)�random�sample�Randomr)r�size�seedrMrrrr zs
�r Zrandom_shufflecCst|t|�|d�S)a(
    Return a shuffled copy of an input list. By default, the random number
    generator uses the current system time unless given a seed value.

    .. versionadded:: 3005

    value
        A list to be used as input.

    seed
        Any value which will be hashed as a seed for random.
    )r#)r r)rr#rrr�shuffle�sr$)F)NNr)NrcFFFFF)NrcFFFF)NrcFFF)NrcFF)r)Nr�N)FFNN)r)Nr)NFF)NFN)r)Hr6r2rlr�r�r�loggingrr��collections.abcrrrZsalt.utils.dictupdaterdZsalt.utils.stringutilsZsalt.utils.yamlZ
salt.defaultsrZsalt.exceptionsrZsalt.utils.decorators.jinjarZsalt.utils.odictrr��ImportErrorr�	getLoggerr3rYr
r8rrErFrNrRrurirjrkr}rxryrzr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rr	rrr r$rrrr�<module>s�

5


*
�f
�
�V
�
�2�C�1
�		

/S
�

G



%



0
�
?
F!