o
    5h                     @   s<  d Z ddlmZ ddlmZmZmZ ddlm	Z	m
Z
 zddlmZ ddlmZ W n ey=   ddlmZ ddlmZ Y nw ddlmZ ddlmZ dd	lZdd	lZdd	lZeeZdd	lZdd	lZdd	lZdd	lZdd	lZerzdd	l Z W n ey   d	Z d
Z!Y nw dd	l Z dd	l"Z"e rdd	l#Z#zdd	l$Z$W n ey   d	Z$Y nw dd	l%Z%dd	l&Z&ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z>m?Z? ddlm@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP g dZQeReeFrejSnejTdd ZUg dZVddgZWddl=mXZX dZYeGdZZeGdZ[eRej\]dpCdZ^G dd de_Z`eFraejajbZcedecejajegZfdd Zgnd d Zg	!	!dd"d#Zhd$d% Zid&d' ZjejZkzdd(llmmZj W n
 ey   Y nw dd*d+Zndd-d.Zoe d	u rdd/d.Zod0d1 ZpeFrd2d3 Zqd4d5 Zrndd6lmsZsmtZt d7d3 Zqd8d5 Zre@eqd9 e@erd: d;d< Zud=d> Zvd?d@ ZwdAZxeGdBZyddCdDZzdEdF Z{dGZ|e|}dHZ~dIdJ ZdKdL ZdMZeGdNZdOdP ZddRdSZddTdUZeFrddVdWZnddXdWZe@edY e8dZd[d\dd]d^Zedd_ Zedd` ZedddagZddcddZdedf ZzddglmZ W n ey^   d	Zd!Zd!Zd!Zd	Zdhdi ZY nWw djZdBZe$rePrdkej  krvdlkrn ne$ ZdjZnddmlmZ e Zd!ZeGdnZeFrdjZzedodp W n ey   d!ZY n   Y dqdi ZndjZdrdi Ze@eds dtdu Ze%jZeZdvdw Zz	edx djZW n ey   d!ZY nw ddydzZere Znee Zd{d| Zd}d~ ZdZe8d[ddddefddZdZdd ZdZdd Zdd Zdd Zd	S )z4passlib.utils -- helpers for writing password hashes    )JYTHON)
b2a_base64
a2b_base64Error)	b64encode	b64decode)Sequence)Iterable)lookup)update_wrapperNznot present under Jython)warn)BASE64_CHARS
AB64_CHARSHASH64_CHARSBCRYPT_CHARSBase64EngineLazyBase64Engineh64h64bigbcrypt64ab64_encodeab64_decodeb64s_encodeb64s_decode)deprecated_functiondeprecated_methodmemoized_propertyclasspropertyhybrid_method)ExpectedStringErrorExpectedTypeError)add_doc
join_bytesjoin_byte_valuesjoin_byte_elemsirangeimapPY3ujoin_unicodeunicodebyte_elem_value
nextgetterunicode_or_strunicode_or_bytes_typesget_method_functionsuppress_causePYPY)r   sys_bitsunix_crypt_schemesrounds_cost_valuesconsteqsaslprep	xor_bytesrender_bytesis_same_codecis_ascii_safeto_bytes
to_unicodeto_native_str	has_crypt
test_crypt
safe_crypttickrnggetrandbytes
getrandstrgenerate_passwordis_crypt_handleris_crypt_contexthas_rounds_infohas_salt_info   g      ?)sha512_cryptsha256_crypt
sha1_cryptbcrypt	md5_crypt
bsdi_crypt	des_cryptlinearlog2)MissingBackendError      PASSLIB_MAX_PASSWORD_SIZEi   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )SequenceMixinz
    helper which lets result object act like a fixed-length sequence.
    subclass just needs to provide :meth:`_as_tuple()`.
    c                 C   s   t d)Nzimplement in subclass)NotImplementedErrorself r]   j/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/passlib/utils/__init__.py	_as_tuple   s   zSequenceMixin._as_tuplec                 C      t |  S N)reprr_   r[   r]   r]   r^   __repr__      zSequenceMixin.__repr__c                 C   s   |   | S ra   r_   )r\   idxr]   r]   r^   __getitem__   rd   zSequenceMixin.__getitem__c                 C   r`   ra   )iterr_   r[   r]   r]   r^   __iter__   rd   zSequenceMixin.__iter__c                 C   r`   ra   )lenr_   r[   r]   r]   r^   __len__   rd   zSequenceMixin.__len__c                 C   s   |   |kS ra   re   r\   otherr]   r]   r^   __eq__   rd   zSequenceMixin.__eq__c                 C   s   |  | S ra   )rn   rl   r]   r]   r^   __ne__   rd   zSequenceMixin.__ne__N)__name__
__module____qualname____doc__r_   rc   rg   ri   rk   rn   ro   r]   r]   r]   r^   rY      s    rY   c                 C   sJ   t t| j}|sdS ||}|r|jtvrdS |t|d  jtkS )*test if function accepts specified keywordFT)	inspect	signaturer/   
parametersgetkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyparamsargr]   r]   r^   accepts_keyword   s   
r   c                 C   s"   t t| }||jv p|jduS )rt   N)rv   
getargspecr/   argskeywords)r~   r   specr]   r]   r^   r      s   Fc                    s2  t |tr|g}t| j}|r,t |tr|g}|D ] |r" |v r"q |v r+|  q|r|D ]] t fdd|D r>q0|r^t|D ]\}}	t |	rO n|rXt|	|rX nqDt|}n)|rtt	|D ]\}
}	t|	|rt||
 }||d  |	ksJ  nqfd}nd}|
|  q0|st|| _dS dS )a  
    helper to update mixin classes installed in target class.

    :param target:
        target class whose bases will be modified.

    :param add:
        class / classes to install into target's base class list.

    :param remove:
        class / classes to remove from target's base class list.

    :param append:
        by default, prepends mixins to front of list.
        if True, appends to end of list instead.

    :param after:
        optionally make sure all mixins are inserted after
        this class / classes.

    :param before:
        optionally make sure all mixins are inserted before
        this class / classes.

    :param dryrun:
        optionally perform all calculations / raise errors,
        but don't actually modify the class.
    c                 3   s    | ]}t | V  qd S ra   )
issubclass).0basemixinr]   r^   	<genexpr>       z'update_mixin_classes.<locals>.<genexpr>   r   N)
isinstancetyper|   	__bases__removeany	enumerater   rj   reversedinserttuple)targetaddr   appendbeforeafterdryrunbasesrf   r   end_idxr]   r   r^   update_mixin_classes   sN   





r   c                 c   s    |dk r	t dt| tr-t| }d}||k r+|| }| || V  |}||k sdS dS t| trWt| }	 t||}zt|}W n
 t	yM   Y dS w t
|f|V  q7td)z8
    split iterable into chunks of <size> elements.
    r   zsize must be positive integerr   Tzsource must be iterableN)
ValueErrorr   r   rj   r	   rh   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinitr	chunk_itrfirstr]   r]   r^   batch  s.   

r   c                 C   s   t | trt |tstdd}nt | tr"t |tstdt}ntdt| t|k}|r4| }d}|s:|}d}|rPt||D ]
\}}|||A O }qA|dkS t||D ]\}}|t|t|A O }qU|dkS )a  Check two strings/bytes for equality.

    This function uses an approach designed to prevent
    timing analysis, making it appropriate for cryptography.
    a and b must both be of the same type: either str (ASCII only),
    or any type that supports the buffer protocol (e.g. bytes).

    Note: If a and b are of different lengths, or if an error occurs,
    a timing attack could theoretically reveal information about the
    types and lengths of a and b--but not their values.
    z)inputs must be both unicode or both bytesFr   r   )r   r*   r   bytesr'   rj   zipord)leftrightis_py3_bytes	same_sizetmpresultlrr]   r]   r^   r5   ;  s.   



r5   )compare_digest,c                 C   s:   |   } | |r| dd } | sg S dd | |D S )zRsplit comma-separated string into list of elements,
    stripping whitespace.
    Nru   c                 S   s   g | ]}|  qS r]   )stripr   elemr]   r]   r^   
<listcomp>  s    zsplitcomma.<locals>.<listcomp>)r   endswithsplit)r   sepr]   r]   r^   
splitcomma  s   
r   valuec                    s  t | tstdt| f tjtj t fdd| D }t	d|}|s*t
S tj}||d rC||d s?td| tj}n|}tj}tj}tj}tj}tj}	tj}
tj}tj}tj}|D ]v} |rlJ d|rtJ d	||r~td
| ||rtd| ||rtd| ||rtd| |	|rtd| |
|rtd| ||rtd| ||rtd| ||rtd| ||rtd| qb|S )a  Normalizes unicode strings using SASLPrep stringprep profile.

    The SASLPrep profile is defined in :rfc:`4013`.
    It provides a uniform scheme for normalizing unicode usernames
    and passwords before performing byte-value sensitive operations
    such as hashing. Among other things, it normalizes diacritic
    representations, removes non-printing characters, and forbids
    invalid characters such as ``\n``. Properly internationalized
    applications should run user passwords through this function
    before hashing.

    :arg source:
        unicode string to normalize & validate

    :param param:
        Optional noun identifying source parameter in error messages
        (Defaults to the string ``"value"``). This is mainly useful to make the caller's error
        messages make more sense contextually.

    :raises ValueError:
        if any characters forbidden by the SASLPrep profile are encountered.

    :raises TypeError:
        if input is not :class:`!unicode`

    :returns:
        normalized unicode string

    .. note::

        This function is not available under Jython,
        as the Jython stdlib is missing the :mod:`!stringprep` module
        (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).

    .. versionadded:: 1.6
    z$input must be unicode string, not %sc                 3   s(    | ]} |s|rt n|V  qd S ra   )_USPACEr   cin_table_b1in_table_c12r]   r^   r     s    
zsaslprep.<locals>.<genexpr>NFKCr   ru   zmalformed bidi sequence in z$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez$unassigned code points forbidden in z control characters forbidden in z$private use characters forbidden in z"non-char code points forbidden in zsurrogate codes forbidden in z!non-plaintext chars forbidden in z!non-canonical chars forbidden in z1display-modifying / deprecated chars forbidden inztagged characters forbidden in zforbidden bidi character in )r   r*   r   r   
stringprepr   r   r)   unicodedata	normalize_UEMPTYin_table_d1r   in_table_d2in_table_a1in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9)r   paramdatais_ral_charis_forbidden_bidi_charr   r   r   r   r   r   r   r   r   r   r]   r   r^   r6     sl   
,r6   c                 C   s   t dt )zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is )rZ   _stringprep_missing_reason)r   r   r]   r]   r^   r6     s   c                 G   s4   t | tr
| d} | tdd |D  }|dS )a  Peform ``%`` formating using bytes in a uniform manner across Python 2/3.

    This function is motivated by the fact that
    :class:`bytes` instances do not support ``%`` or ``{}`` formatting under Python 3.
    This function is an attempt to provide a replacement:
    it converts everything to unicode (decoding bytes instances as ``latin-1``),
    performs the required formatting, then encodes the result to ``latin-1``.

    Calling ``render_bytes(source, *args)`` should function roughly the same as
    ``source % args`` under Python 2.

    .. todo::
        python >= 3.5 added back limited support for bytes %,
        can revisit when 3.3/3.4 is dropped.
    latin-1c                 s   s(    | ]}t |tr|d n|V  qdS )r   N)r   r   decode)r   r   r]   r]   r^   r   ,  s    
zrender_bytes.<locals>.<genexpr>)r   r   r   r   encode)r   r   r   r]   r]   r^   r8     s   




r8   c                 C   s   t | dS Nbig)int
from_bytesr   r]   r]   r^   bytes_to_int2  rd   r   c                 C   s   |  |dS r   )r;   r   countr]   r]   r^   int_to_bytes4  rd   r   )hexlify	unhexlifyc                 C   s   t t| dS )N   )r   r   r   r]   r]   r^   r   9  s   c                 C   s   t d|d>  |  S )Nz%%0%dxr   )r   r   r]   r]   r^   r   ;  s   z/decode byte string as single big-endian integerz/encode integer as single big-endian byte stringc                 C   s   t t| t|A t| S )z;Perform bitwise-xor of two byte strings (must be same size))r   r   rj   r   r   r]   r]   r^   r7   A  s   r7   c                 C   s$   d|d t |   }| | d| S )zE
    repeat or truncate <source> string, so it has length <size>
    r   N)rj   r   r   multr]   r]   r^   repeat_stringE  s   r   c                 C   s"   d|d t |   }t| | |S )zN
    variant of repeat_string() which truncates to nearest UTF8 boundary.
    r   )rj   utf8_truncater   r]   r]   r^   utf8_repeat_stringM  s   r        c                 C   sF   t | }||kr|du rt| trtnt}| |||   S | d| S )z>right-pad or truncate <source> string, so it has length <size>N)rj   r   r*   _UNULL_BNULL)r   r   padcurr]   r]   r^   right_pad_stringX  s   r   c                    s   t tsttdt}|dk rtd|| }||kr S t|d |}||k r>t| d@ dkr6n|d7 }||k s+||ksDJ d|   fdd	}| sVJ  S )
a  
    helper to truncate UTF8 byte string to nearest character boundary ON OR AFTER <index>.
    returned prefix will always have length of at least <index>, and will stop on the
    first byte that's not a UTF8 continuation byte (128 - 191 inclusive).
    since utf8 should never take more than 4 bytes to encode known unicode values,
    we can stop after ``index+3`` is reached.

    :param bytes source:
    :param int index:
    :rtype: bytes
    r   r            r   Nc                     s<   z d} W n
 ty   Y dS w |   dsJ dS )Nutf-8T)r   UnicodeDecodeError
startswith)textr   r   r]   r^   sanity_check  s   z#utf8_truncate.<locals>.sanity_check)r   r   r    rj   maxminr+   )r   indexr   r  r]   r  r^   r   c  s$   

r   s	    
 aA:#!asciic                 C   s   t | tkS )zRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16))_ASCII_TEST_UNICODEr   _ASCII_TEST_BYTES)codecr]   r]   r^   is_ascii_codec  s   r  c                 C   s,   | |krdS | r
|sdS t | jt |jkS )z3Check if two codec names are aliases for same codecTF)_lookup_codecnamer   r]   r]   r^   r9     s
   r9   r      c                    s(   t | trtnt t fdd| D S )z<Check if string (bytes or unicode) contains only 7-bit asciic                 3   s    | ]}| k V  qd S ra   r]   r   r   r]   r^   r         z is_ascii_safe.<locals>.<genexpr>)r   r   _B80_U80all)r   r]   r  r^   r:     s   r:   r  c                 C   sR   |sJ t | tr|rt||s| ||S | S t | tr$| |S t| |)a  Helper to normalize input to bytes.

    :arg source:
        Source bytes/unicode to process.

    :arg encoding:
        Target encoding (defaults to ``"utf-8"``).

    :param param:
        Optional name of variable/noun to reference when raising errors

    :param source_encoding:
        If this is specified, and the source is bytes,
        the source will be transcoded from *source_encoding* to *encoding*
        (via unicode).

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * unicode strings will be encoded using *encoding*, and returned.
        * if *source_encoding* is not specified, byte strings will be
          returned unchanged.
        * if *source_encoding* is specified, byte strings will be transcoded
          to *encoding*.
    )r   r   r9   r   r   r*   r   )r   encodingr   source_encodingr]   r]   r^   r;     s   



r;   c                 C   s4   |sJ t | tr| S t | tr| |S t| |)a  Helper to normalize input to unicode.

    :arg source:
        source bytes/unicode to process.

    :arg encoding:
        encoding to use when decoding bytes instances.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * returns unicode strings unchanged.
        * returns bytes strings decoded using *encoding*
    )r   r*   r   r   r   r   r  r   r]   r]   r^   r<     s   



r<   c                 C   s,   t | tr
| |S t | tr| S t| |ra   )r   r   r   r*   r   r  r]   r]   r^   r=     s
   



r=   c                 C   s,   t | tr| S t | tr| |S t| |ra   )r   r   r*   r   r   r  r]   r]   r^   r=     s
   



a>  Take in unicode or bytes, return native string.

    Python 2: encodes unicode using specified encoding, leaves bytes alone.
    Python 3: leaves unicode alone, decodes bytes using specified encoding.

    :raises TypeError: if source is not unicode or bytes.

    :arg source:
        source unicode or bytes string.

    :arg encoding:
        encoding to use when encoding unicode or decoding bytes.
        this defaults to ``"utf-8"``.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :returns: :class:`str` instance
    z1.6z1.7)
deprecatedremovedc                 C   s   t | |ddS )z'deprecated, use to_native_str() insteadhash)r   )r=   )r   r  r]   r]   r^   to_hash_str$  s   r  z true t yes y on 1 enable enabledz#false f no n off 0 disable disablednonebooleanc                 C   sx   |dv sJ t | tr+|   }|tv rdS |tv rdS |tv r#|S td|| f t | tr2| S | du r8|S t| S )z\
    helper to convert value to boolean.
    recognizes strings such as "true", "false"
    )TFNTFzunrecognized %s value: %rN)	r   r.   lowerr   	_true_set
_false_set	_none_setr   bool)r   r  r   cleanr]   r]   r^   as_bool-  s   

r&  c                 C   s8   t st| ts	dS z| d W dS  ty   Y dS w )z
    UT helper --
    test if value is safe to pass to crypt.crypt();
    under PY3, can't pass non-UTF8 bytes to crypt.crypt.
    Tr  F)crypt_accepts_bytesr   r   r   r  r   r]   r]   r^   is_safe_crypt_inputG  s   
r(  )cryptc                 C   s   d S ra   r]   secretr  r]   r]   r^   r@   ]  s   r@   T)   rJ   r   )r,  r   r   )nullcontextz*:!   xxc                 C   s  t rt| tr| d} t| v rtdt|tr|d}n6t| trC| }z| d} W n
 ty7   Y d S w | d|ksCJ dt	| v rKtdt|trU|d}zt
 t| |}W d    n1 shw   Y  W n
 tyx   Y d S w t|tr|d}|r|d tv rd S |S )Nr  null character in secretr
  z"utf-8 spec says this can't happen!r   )r'  r   r*   r   r   r   r   r   r  _NULL_safe_crypt_lock_cryptOSError_invalid_prefixes)r+  r  origr   r]   r]   r^   r@     sF   








c                 C   s   t | tr
| d} t| v rtdt |tr|d}t t| |}W d    n1 s.w   Y  |s7d S |d}|d tv rDd S |S )Nr  r0  r
  r   )	r   r*   r   r1  r   r2  r3  r   r5  )r+  r  r   r]   r]   r^   r@     s   




a  Wrapper around stdlib's crypt.

    This is a wrapper around stdlib's :func:`!crypt.crypt`, which attempts
    to provide uniform behavior across Python 2 and 3.

    :arg secret:
        password, as bytes or unicode (unicode will be encoded as ``utf-8``).

    :arg hash:
        hash or config string, as ascii bytes or unicode.

    :returns:
        resulting hash as ascii unicode; or ``None`` if the password
        couldn't be hashed due to one of the issues:

        * :func:`crypt()` not available on platform.

        * Under Python 3, if *secret* is specified as bytes,
          it must be use ``utf-8`` or it can't be passed
          to :func:`crypt()`.

        * Some OSes will return ``None`` if they don't recognize
          the algorithm being used (though most will simply fall
          back to des-crypt).

        * Some OSes will return an error string if the input config
          is recognized but malformed; current code converts these to ``None``
          as well.
    c                 C   s4   t |tsJ dt| |sJ dt| ||kS )zcheck if :func:`crypt.crypt` supports specific hash
    :arg secret: password to test
    :arg hash: known hash of password to use as reference
    :returns: True or False
    z#hash must be unicode_or_str, got %szhash must be non-empty)r   r-   r   r@   r*  r]   r]   r^   r?     s
   

r?   c                 C   s2   t d| }|rtdd |ddD S dS )zhelper to parse version stringz(\d+(?:\.\d+)+)c                 s   s    | ]}t |V  qd S ra   )r   r   r]   r]   r^   r     r  z parse_version.<locals>.<genexpr>r   .N)researchr   groupr   )r   mr]   r]   r^   parse_version  s   r<  r   c              	   C   s   ddl m} t| dr%t| dr%z|  } W n ty$   | d} Y nw td| ttdr2t ndt	t
 t t trFtd	d
ndf }t||d dS )z.generate prng seed value from system resourcesr   )sha512getstategetrandbitsi   z%s %s %s %.15f %.15f %sgetpidN    r   r  r   )hashlibr=  hasattrr>  rZ   r?  r(   osr@  idobjecttimerA   has_urandomurandomr   r   r   	hexdigest)r   r=  r  r]   r]   r^   genseed  s    rK  c                    s     st S  fdd}t| S )z]return byte-string containing *count* number of randomly generated bytes, using specified rngc                  3   sF      d> } d}| k r!| d@ V  | dL } |d7 }| k sd S d S )Nr   r      r   )r?  r   r   r   rB   r]   r^   helperM  s   
zgetrandbytes.<locals>.helper)_BEMPTYr#   )rB   r   rO  r]   rN  r^   rC   B  s   	
rC   c                    sh   dk rt dt dkrt ddkr  S  fdd}t tr/t| S t| S )z|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngr   zcount must be >= 0zalphabet must not be emptyr   c                  3   sL     d } d}|k r$ |   V  |  } |d7 }|k sd S d S )Nr   r   )	randrangerM  charsetr   lettersrB   r]   r^   rO  f  s   zgetrandstr.<locals>.helper)r   rj   r   r*   r)   r$   )rB   rS  r   rO  r]   rR  r^   rD   W  s   
	

rD   42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0z/passlib.pwd.genword() / passlib.pwd.genphrase())r  r  replacement
   c                 C   s   t t|| S )aw  generate random password using given length & charset

    :param size:
        size of password.

    :param charset:
        optional string specified set of characters to draw from.

        the default charset contains all normal alphanumeric characters,
        except for the characters ``1IiLl0OoS5``, which were omitted
        due to their visual similarity.

    :returns: :class:`!str` containing randomly generated password.

    .. note::

        Using the default character set, on a OS with :class:`!SystemRandom` support,
        this function should generate passwords with 5.7 bits of entropy per character.
    )rD   rB   )r   rS  r]   r]   r^   rE   v  s   rE   )r  setting_kwdscontext_kwdsverifyr  identifyc                       t  fddtD S )z4check if object follows the :ref:`password-hash-api`c                 3       | ]}t  |V  qd S ra   rC  r   r  objr]   r^   r     r   z#is_crypt_handler.<locals>.<genexpr>)r  _handler_attrsr`  r]   r`  r^   rF        rF   )needs_update	genconfiggenhashrZ  encryptr[  c                    r\  )zOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec                 3   r]  ra   r^  r_  r`  r]   r^   r     r   z#is_crypt_context.<locals>.<genexpr>)r  _context_attrsr`  r]   r`  r^   rG     rc  rG   c                 C      d| j v ot| ddduS )z_check if handler provides the optional :ref:`rounds information <rounds-attributes>` attributesrounds
min_roundsNrX  getattrhandlerr]   r]   r^   rH        
rH   c                 C   ri  )z[check if handler provides the optional :ref:`salt information <salt-attributes>` attributessaltmin_salt_sizeNrl  rn  r]   r]   r^   rI     rp  rI   )NNFNNF)r   r   ra   )r  r   N)r  r   )r
  )Nr  )rs   passlib.utils.compatr   binasciir   r   r   _BinAsciiErrorbase64r   r   collections.abcr   r	   ImportErrorcollectionscodecsr
   r  	functoolsr   r   rv   logging	getLoggerrp   logmathrD  sysrandomr8  r   r   rG  r   	threadingtimeittypeswarningsr   passlib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   passlib.utils.decorr   r   r   r   r   passlib.excr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   __all__r   maxsizemaxintr2   r3   r4   rT   rP  r   r   environry   MAX_PASSWORD_SIZErF  rY   	ParameterVAR_KEYWORDr}   setVAR_POSITIONALr{   r   r   r   r5   str_consteqhmacr   r   r6   r8   r   r   r   r   r7   r   r   r   r   r   r   r  r   r  r  r9   r  r  r:   r;   r<   r=   r  r   r!  r"  r#  r&  r(  r)  r3  r>   r'  crypt_needs_lockr2  r@   r1  pypy_version_infoLockr-  r5  r   r?   default_timertimerrA   r<  rI  rH  rZ   rK  SystemRandomrB   RandomrC   rD   
_52charsetrE   rb  rF   rh  rG   rH   rI   r]   r]   r]   r^   <module>   sV   <L".	

W>

 





F


%


	*
/


!

