§
    HŠtjE¶  ã                   óŠ  — d Z ddlmZ ddlZ ej        e¦  «        ZddlZddlm	Z	 ddl
mZmZ ddlmZ ddlmZ ddlmZ dd	lmZmZmZ dd
lmZ ddlmZmZmZmZ ddgZ e¦   «         Z dZ!dZ"dZ#dZ$dZ% G d„ de¦  «        Z& e'¦   «         Z(d„ Z) e)¦   «         Z*d„ Z+ e+¦   «         Z, G d„ de&¦  «        Z- G d„ de&¦  «        Z.dS )z(passlib.apache - apache password supporté    )Úwith_statementN)Úwarn)ÚexcÚregistry)ÚCryptContext)ÚExpectedStringError)Úhtdigest)Úrender_bytesÚto_bytesÚis_ascii_codec)Údeprecated_method)Ú
join_bytesÚunicodeÚBytesIOÚPY3ÚHtpasswdFileÚHtdigestFileó   :ó   #s   :
	 ÚskippedÚrecordc                   ó   — e Zd ZdZdZdZdZdZdZdZ	dZ
ed„ ¦   «         Zed„ ¦   «         Zdddddefd„Zd	„ Zed
„ ¦   «         Zej        d„ ¦   «         Zed„ ¦   «         Zd„ Zdd„Zd„ Zd„ Zd„ Zd„ Zd„ Zdd„Zd„ Zd„ Zd„ Zd„ Z d„ Z!dd„Z"d„ Z#dS ) Ú_CommonFilez0common framework for HtpasswdFile & HtdigestFileNFc                 óf   — d|v rt          d¦  «        ‚ | di |¤Ž}|                     |¦  «         |S )zöcreate new object from raw string.

        :type data: unicode or bytes
        :arg data:
            database to load, as single string.

        :param \*\*kwds:
            all other keywords are the same as in the class constructor
        Úpathz$'path' not accepted by from_string()© )Ú	TypeErrorÚload_string)ÚclsÚdataÚkwdsÚselfs       úL/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/passlib/apache.pyÚfrom_stringz_CommonFile.from_stringK   sF   € ð �Tˆ>ˆ>ÝÐBÑCÔCÐCØˆsˆ{ˆ{�Tˆ{ˆ{ˆØ×Ò˜ÑÔÐØˆó    c                 ó@   —  | di |¤Ž}|                      |¦  «         |S )zûcreate new object from file, without binding object to file.

        :type path: str
        :arg path:
            local filepath to load from

        :param \*\*kwds:
            all other keywords are the same as in the class constructor
        r   )Úload)r   r   r!   r"   s       r#   Ú	from_pathz_CommonFile.from_path\   s)   € ð ˆsˆ{ˆ{�Tˆ{ˆ{ˆØ�	Š	�$‰ŒˆØˆr%   Túutf-8c                 óJ  — |st          dt          d¬¦  «         d}d}nt          |¦  «        st          d¦  «        ‚|| _        || _        || _        || _        d| _        |st          dt          d¬¦  «         d	}|r|s|  	                    ¦   «          d S i | _
        g | _        d S )
Nz„``encoding=None`` is deprecated as of Passlib 1.6, and will cause a ValueError in Passlib 1.8, use ``return_unicode=False`` instead.é   ©Ú
stacklevelr)   Fz'encoding must be 7-bit ascii compatibler   zp``autoload=False`` is deprecated as of Passlib 1.6, and will be removed in Passlib 1.8, use ``new=True`` insteadT)r   ÚDeprecationWarningr   Ú
ValueErrorÚencodingÚreturn_unicodeÚautosaveÚ_pathÚ_mtimer'   Ú_recordsÚ_source)r"   r   ÚnewÚautoloadr2   r0   r1   s          r#   Ú__init__z_CommonFile.__init__n   së   € ð ð 
	HÝð 9õ $°ð3ñ 3ô 3ð 3ð ˆHØ"ˆNˆNÝ Ñ)Ô)ð 	Hõ ÐFÑGÔGÐGØ ˆŒð -ˆÔØ ˆŒØˆŒ
ØˆŒð ð 	Ýð På#°ð3ñ 3ô 3ð 3ð ˆCØð 	˜ð 	Ø�IŠI‰KŒKˆKˆKˆKàˆDŒMØˆDŒLˆLˆLr%   c                 ó´   — d}| j         r|dz  }| j        r|d| j        z  z  }| j        dk    r|d| j        z  z  }d| j        j        t          | ¦  «        |fz  S )NÚ z autosave=Truez path=%rr)   z encoding=%rz<%s 0x%0x%s>)r2   r3   r0   Ú	__class__Ú__name__Úid)r"   Útails     r#   Ú__repr__z_CommonFile.__repr__‘   sr   € ØˆØŒ=ð 	%ØÐ$Ñ$ˆDØŒ:ð 	,Ø�J ¤Ñ+Ñ+ˆDØŒ=˜GÒ#Ð#Ø�N T¤]Ñ2Ñ2ˆDØ ¤Ô!8½"¸T¹(¼(ÀDÐ IÑIÐIr%   c                 ó   — | j         S ©N)r3   ©r"   s    r#   r   z_CommonFile.path�   s
   € àŒzÐr%   c                 ó8   — || j         k    rd| _        || _         d S )Nr   )r3   r4   ©r"   Úvalues     r#   r   z_CommonFile.path¡   s!   € à�D”JÒÐØˆDŒKØˆŒ
ˆ
ˆ
r%   c                 ó   — | j         S )z7modify time when last loaded (if bound to a local file))r4   rC   s    r#   Úmtimez_CommonFile.mtime§   s   € ð Œ{Ðr%   c                 óÌ   — | j         st          d| z  ¦  «        ‚| j        r/| j        t          j                             | j         ¦  «        k    rdS |                      ¦   «          dS )zBReload from ``self.path`` only if file has changed since last loadz%r is not bound to a local fileFT)r3   ÚRuntimeErrorr4   Úosr   Úgetmtimer'   rC   s    r#   Úload_if_changedz_CommonFile.load_if_changed¯   s`   € àŒzð 	IÝÐ@À4ÑGÑHÔHÐHØŒ;ð 	˜4œ;­"¬'×*:Ò*:¸4¼:Ñ*FÔ*FÒFÐFØ�5Ø�	Š	‰ŒˆØˆtr%   c                 óB  — |�Et          |d¦  «        5 }d| _        |                      |¦  «         ddd¦  «         n# 1 swxY w Y   n×|sFt          dt	          | j        j        ¬¦  «        z  t          d¬¦  «         |                      ¦   «         S | j	        rlt          | j	        d¦  «        5 }t          j                             | j	        ¦  «        | _        |                      |¦  «         ddd¦  «         n# 1 swxY w Y   nt          d| j        j        z  ¦  «        ‚d	S )
aô  Load state from local file.
        If no path is specified, attempts to load from ``self.path``.

        :type path: str
        :arg path: local file to load from

        :type force: bool
        :param force:
            if ``force=False``, only load from ``self.path`` if file
            has changed since last load.

            .. deprecated:: 1.6
                This keyword will be removed in Passlib 1.8;
                Applications should use :meth:`load_if_changed` instead.
        NÚrbr   z†%(name)s.load(force=False) is deprecated as of Passlib 1.6,and will be removed in Passlib 1.8; use %(name)s.load_if_changed() instead.)Únamer+   r,   z2%s().path is not set, an explicit path is requiredT)Úopenr4   Ú_load_linesr   Údictr<   r=   r.   rM   r3   rK   r   rL   rJ   )r"   r   ÚforceÚfhs       r#   r'   z_CommonFile.load¸   s¨  € ð  ÐÝ�d˜DÑ!Ô!ð % RØ�”Ø× Ò  Ñ$Ô$Ð$ð%ð %ð %ñ %ô %ð %ð %ð %ð %ð %ð %øøøð %ð %ð %ð %øð ð 	8Ýð ;õ ˜4œ>Ô2Ð3Ñ3Ô3ñ4õ $°ð	3ñ 3ô 3ð 3ð
 ×'Ò'Ñ)Ô)Ð)ØŒZð 	8Ý�d”j $Ñ'Ô'ð %¨2Ý œg×.Ò.¨t¬zÑ:Ô:�”Ø× Ò  Ñ$Ô$Ð$ð%ð %ð %ñ %ô %ð %ð %ð %ð %ð %ð %øøøð %ð %ð %ð %øõ ÐSØ#œ~Ô6ñ 7ñ 8ô 8ð 8àˆts!   “<¼A ÁA Â,?C7Ã7C;Ã>C;c                 ó„   — t          || j        d¦  «        }d| _        |                      t	          |¦  «        ¦  «         dS )z@Load state from unicode or bytes string, replacing current stater    r   N)r   r0   r4   rR   r   )r"   r    s     r#   r   z_CommonFile.load_stringÜ   s<   € å˜˜dœm¨VÑ4Ô4ˆØˆŒØ×Ò� ™œÑ'Ô'Ð'Ð'Ð'r%   c                 ó&  — | j         }i }g }d}t          |¦  «        D ]µ\  }}|                     ¦   «         }|r|                     t          ¦  «        r||z  }Œ; |||dz   ¦  «        \  }	}
|	|v r#t
                               d|	z  ¦  «         ||z  }Œt|r|                     t          |f¦  «         d}|
||	<   |                     t          |	f¦  «         Œ¶| 
                    ¦   «         r|                     t          |f¦  «         || _        || _        dS )zload from sequence of listsr%   é   z1username occurs multiple times in source file: %rN)Ú_parse_recordÚ	enumerateÚlstripÚ
startswithÚ_BHASHÚlogÚwarningÚappendÚ_SKIPPEDÚ_RECORDÚrstripr5   r6   )r"   ÚlinesÚparseÚrecordsÚsourcer   ÚidxÚlineÚtmpÚkeyrF   s              r#   rR   z_CommonFile._load_linesâ   s>  € àÔ"ˆØˆØˆØˆÝ" 5Ñ)Ô)ð 	*ð 	*‰IˆC�ð —+’+‘-”-ˆCØð ˜#Ÿ.š.­Ñ0Ô0ð Ø˜4‘�Øð ˜˜t S¨¡UÑ+Ô+‰JˆC�ð �gˆ~ˆ~Ý—’ÐOÐRUÑUÑVÔVÐVØ˜4‘�Øð ð Ø—’�x¨Ð1Ñ2Ô2Ð2Ø�ð !ˆG�C‰LØ�MŠM�7 C˜.Ñ)Ô)Ð)Ð)ð �>Š>ÑÔð 	/Ø�MŠM�8 WÐ-Ñ.Ô.Ð.ð  ˆŒØˆŒˆˆr%   c                 ó    — t          d¦  «        ‚)z)parse line of file into (key, value) pairú!should be implemented in subclass©ÚNotImplementedError)r"   r   Úlinenos      r#   rY   z_CommonFile._parse_record  ó   € å!Ð"EÑFÔFÐFr%   c                 ól   — | j         }||v }|||<   |s!| j                             t          |f¦  «         |S )z›
        helper for setting record which takes care of inserting source line if needed;

        :returns:
            bool if key already present
        )r5   r6   r`   rb   )r"   rk   rF   rf   Úexistings        r#   Ú_set_recordz_CommonFile._set_record  sD   € ð ”-ˆØ˜7�NˆØˆ�‰Øð 	0ØŒL×Ò¥¨# Ñ/Ô/Ð/Øˆr%   c                 óR   — | j         r| j        r|                      ¦   «          dS dS dS )z0subclass helper to call save() after any changesN)r2   r3   ÚsaverC   s    r#   Ú	_autosavez_CommonFile._autosave!  s:   € àŒ=ð 	˜TœZð 	Ø�IŠI‰KŒKˆKˆKˆKð	ð 	ð 	ð 	r%   c                 óz  — |�Rt          |d¦  «        5 }|                     |                      ¦   «         ¦  «         ddd¦  «         dS # 1 swxY w Y   dS | j        rE|                      | j        ¦  «         t
          j                             | j        ¦  «        | _        dS t          d| j
        j        z  ¦  «        ‚)zhSave current state to file.
        If no path is specified, attempts to save to ``self.path``.
        NÚwbz%%s().path is not set, cannot autosave)rQ   Ú
writelinesÚ_iter_linesr3   rv   rK   r   rL   r4   rJ   r<   r=   )r"   r   rU   s      r#   rv   z_CommonFile.save&  sö   € ð ÐÝ�d˜DÑ!Ô!ð 2 RØ—’˜d×.Ò.Ñ0Ô0Ñ1Ô1Ð1ð2ð 2ð 2ñ 2ô 2ð 2ð 2ð 2ð 2ð 2ð 2ð 2øøøð 2ð 2ð 2ð 2ð 2ð 2àŒZð 	8Ø�IŠI�d”jÑ!Ô!Ð!Ýœ'×*Ò*¨4¬:Ñ6Ô6ˆDŒKˆKˆKåÐFØ#œ~Ô6ñ 7ñ 8ô 8ð 8s   “(AÁAÁAc                 óD   — t          |                      ¦   «         ¦  «        S )z)Export current state as a string of bytes)r   r{   rC   s    r#   Ú	to_stringz_CommonFile.to_string4  s   € å˜$×*Ò*Ñ,Ô,Ñ-Ô-Ð-r%   c              #   ó  K  — | j         }	 t          |¦  «        }| j        D ][\  }}|t          k    r|V — Œ|t          k    sJ ‚||vrŒ'|                      |||         ¦  «        V — 	 |                     |¦  «         Œ\	 |rJ d|›�¦   «         ‚dS )z#iterator yielding lines of databaseTz%failed to write all records: missing=N)r5   Úsetr6   ra   rb   Ú_render_recordÚremove)r"   rf   ÚpendingÚactionÚcontents        r#   r{   z_CommonFile._iter_lines@  sÏ   è è € ð ”-ˆð	#Ý˜'‘l”lˆGØ#œ|ð 	,ð 	,‰OˆF�GØ�Ò!Ð!à����à¥Ò(Ð(Ð(Ð(à 'Ð)Ð)ð Ø×)Ò)¨'°7¸7Ô3CÑDÔDÐDÐDÐDð,Ø—N’N 7Ñ+Ô+Ð+Ð+ð	Wð ÐVÐVÐVÈWÈWÐ VÑVÔV�;ÐVÐVr%   c                 ó    — t          d¦  «        ‚)z,given key/value pair, encode as line of filerm   rn   )r"   rk   rF   s      r#   r€   z_CommonFile._render_record[  rq   r%   c                 ó.   — |                       |d¦  «        S )z)user-specific wrapper for _encode_field()Úuser©Ú_encode_field©r"   r‡   s     r#   Ú_encode_userz_CommonFile._encode_userb  s   € à×!Ò! $¨Ñ/Ô/Ð/r%   c                 ó.   — |                       |d¦  «        S )z*realm-specific wrapper for _encode_field()Úrealmrˆ   ©r"   r�   s     r#   Ú_encode_realmz_CommonFile._encode_realmf  s   € à×!Ò! %¨Ñ1Ô1Ð1r%   Úfieldc                 óX  — t          |t          ¦  «        r|                     | j        ¦  «        }n%t          |t          ¦  «        st          ||¦  «        ‚t          |¦  «        dk    rt          |›d|›�¦  «        ‚t          d„ |D ¦   «         ¦  «        rt          |›d|›�¦  «        ‚|S )a+  convert field to internal representation.

        internal representation is always bytes. byte strings are left as-is,
        unicode strings encoding using file's default encoding (or ``utf-8``
        if no encoding has been specified).

        :raises UnicodeEncodeError:
            if unicode value cannot be encoded using default encoding.

        :raises ValueError:
            if resulting byte string contains a forbidden character,
            or is too long (>255 bytes).

        :returns:
            encoded identifer as bytes
        éÿ   z! must be at most 255 characters: c              3   ó(   K  — | ]}|t           v V — Œd S rB   )Ú_INVALID_FIELD_CHARS)Ú.0Úcs     r#   ú	<genexpr>z,_CommonFile._encode_field.<locals>.<genexpr>‚  s(   è è € Ð8Ð8¨QˆqÕ(Ð(Ð8Ð8Ð8Ð8Ð8Ð8r%   z contains invalid characters: )	Ú
isinstancer   Úencoder0   Úbytesr   Úlenr/   Úany)r"   rF   Úparams      r#   r‰   z_CommonFile._encode_fieldj  sÆ   € õ" �e�WÑ%Ô%ð 	4Ø—L’L ¤Ñ/Ô/ˆEˆEÝ˜E¥5Ñ)Ô)ð 	4Ý% e¨UÑ3Ô3Ð3Ýˆu‰:Œ:˜ÒÐÝØ#˜e˜e U Uð,ñ -ô -ð -åÐ8Ð8°%Ð8Ñ8Ô8Ñ8Ô8ð 	.ÝØ#˜e˜e U Uð-ñ .ô .ð .àˆr%   c                 ó†   — t          |t          ¦  «        s
J d¦   «         ‚| j        r|                     | j        ¦  «        S |S )aW  decode field from internal representation to format
        returns by users() method, etc.

        :raises UnicodeDecodeError:
            if unicode value cannot be decoded using default encoding.
            (usually indicates wrong encoding set for file).

        :returns:
            field as unicode or bytes, as appropriate.
        zexpected value to be bytes)r˜   rš   r1   Údecoder0   rE   s     r#   Ú_decode_fieldz_CommonFile._decode_field‡  sG   € õ ˜%¥Ñ'Ô'ÐEÐEÐ)EÑEÔEÐ'ØÔð 	Ø—<’< ¤Ñ.Ô.Ð.àˆLr%   )NTrB   )r�   )$r=   Ú
__module__Ú__qualname__Ú__doc__r0   r1   r3   r4   r2   r5   r6   Úclassmethodr$   r(   r   r9   r@   Úpropertyr   ÚsetterrH   rM   r'   r   rR   rY   rt   rw   rv   r}   r{   r€   r‹   r�   r‰   r    r   r%   r#   r   r   ,   s  € € € € € Ø:Ð:ð €Hð €Nð €EØ€Fð €Hð €Hð €Gð
 ðð ñ „[ðð  ðð ñ „[ðð" ! e°dÀUØ!°#ð!ð !ð !ð !ðFJð Jð Jð ðð ñ „Xðð 
„[ðð ñ „[ðð
 ðð ñ „Xððð ð ð"ð "ð "ð "ðH(ð (ð (ð(ð (ð (ðTGð Gð Gðð ð ð"ð ð ð
8ð 8ð 8ð 8ð.ð .ð .ðWð Wð Wð6Gð Gð Gð0ð 0ð 0ð2ð 2ð 2ðð ð ð ð:ð ð ð ð r%   r   c                  óf  — d } dD ]}t          j        |¦  «        r|}  nŒt          j        d¦  «        rdnd }t                               ¦   «          |st                               g d¢¦  «         t          |pdd|p| pd| pd|pdd¬¦  «        }|                     |d         |d         ¬	¦  «         |S )
N)ÚbcryptÚsha256_cryptr¨   )Úportable_apache_24Úhost_apache_24Úlinux_apache_24ÚportableÚhostÚapr_md5_cryptr©   )rª   Úportable_apache_22r«   Úhost_apache_22r¬   Úlinux_apache_22rª   r«   )r­   r®   )r   Úhas_os_crypt_supportÚhas_backendÚ_warn_no_bcryptÚclearÚupdaterS   )Ú	host_bestrP   r¨   Údefaultss       r#   Ú_init_default_schemesrº   ³  s  € ð €IØ*ð ð ˆÝÔ(¨Ñ.Ô.ð 	ØˆIØˆEð	õ "Ô-¨hÑ7Ô7ÐAˆXˆX¸T€FÝ×ÒÑÔÐØð HÝ×Òð  Gð  Gð  Gñ 	Hô 	Hð 	Hõ à!Ð4 _Ø*ð Ð= Ð=¨oØ Ð3 Oð Ð0 .Ø&ðñ ô €Hð" ‡O‚OØÐ.Ô/ØÐ&Ô'ð ñ ô ð ð €Or%   c                  óø   — g d¢} |                       t          j        ¦   «         ¦  «         | d d…         dgz   | z   }t          t	          | ¦  «        |j        ¬¦  «        } t          | t          d         d¬¦  «        S )N)r¨   r©   Úsha512_cryptÚ	des_cryptr¯   Ú	ldap_sha1Ú	plaintexté   r¯   )rk   r°   Ú2y)ÚschemesÚdefaultÚbcrypt__ident)Úextendr   Úget_supported_os_crypt_schemesÚsortedr   Úindexr   Úhtpasswd_defaults)rÂ   Ú	preferreds     r#   Ú_init_htpasswd_contextrË   Þ  s’   € ðð ð €Gð0 ‡N‚N•8Ô:Ñ<Ô<Ñ=Ô=Ð=ð ˜˜˜”˜Ð/Ñ/°'Ñ9€IÝ•S˜‘\”\ y¤Ð7Ñ7Ô7€Gõ Øõ "Ð"6Ô7ð ðñ ô ð r%   c                   óä   ‡ — e Zd ZdZddefˆ fd„	Zd„ Zd„ Zd„ Zd„ Z	 e
dd	d
¬¦  «        d„ ¦   «         Zd„ Zd„ Z e
dd	d¬¦  «        d„ ¦   «         Zd„ Zd„ Z e
dd	d¬¦  «        d„ ¦   «         Zˆ xZS )r   aÇ  class for reading & writing Htpasswd files.

    The class constructor accepts the following arguments:

    :type path: filepath
    :param path:

        Specifies path to htpasswd file, use to implicitly load from and save to.

        This class has two modes of operation:

        1. It can be "bound" to a local file by passing a ``path`` to the class
           constructor. In this case it will load the contents of the file when
           created, and the :meth:`load` and :meth:`save` methods will automatically
           load from and save to that file if they are called without arguments.

        2. Alternately, it can exist as an independant object, in which case
           :meth:`load` and :meth:`save` will require an explicit path to be
           provided whenever they are called. As well, ``autosave`` behavior
           will not be available.

           This feature is new in Passlib 1.6, and is the default if no
           ``path`` value is provided to the constructor.

        This is also exposed as a readonly instance attribute.

    :type new: bool
    :param new:

        Normally, if *path* is specified, :class:`HtpasswdFile` will
        immediately load the contents of the file. However, when creating
        a new htpasswd file, applications can set ``new=True`` so that
        the existing file (if any) will not be loaded.

        .. versionadded:: 1.6
            This feature was previously enabled by setting ``autoload=False``.
            That alias has been deprecated, and will be removed in Passlib 1.8

    :type autosave: bool
    :param autosave:

        Normally, any changes made to an :class:`HtpasswdFile` instance
        will not be saved until :meth:`save` is explicitly called. However,
        if ``autosave=True`` is specified, any changes made will be
        saved to disk immediately (assuming *path* has been set).

        This is also exposed as a writeable instance attribute.

    :type encoding: str
    :param encoding:

        Optionally specify character encoding used to read/write file
        and hash passwords. Defaults to ``utf-8``, though ``latin-1``
        is the only other commonly encountered encoding.

        This is also exposed as a readonly instance attribute.

    :type default_scheme: str
    :param default_scheme:
        Optionally specify default scheme to use when encoding new passwords.

        This can be any of the schemes with builtin Apache support,
        OR natively supported by the host OS's :func:`crypt.crypt` function.

        * Builtin schemes include ``"bcrypt"`` (apache 2.4+), ``"apr_md5_crypt"`,
          and ``"des_crypt"``.

        * Schemes commonly supported by Unix hosts
          include ``"bcrypt"``, ``"sha256_crypt"``, and ``"des_crypt"``.

        In order to not have to sort out what you should use,
        passlib offers a number of aliases, that will resolve
        to the most appropriate scheme based on your needs:

        * ``"portable"``, ``"portable_apache_24"`` -- pick scheme that's portable across hosts
          running apache >= 2.4. **This will be the default as of Passlib 2.0**.

        * ``"portable_apache_22"`` -- pick scheme that's portable across hosts
          running apache >= 2.4. **This is the default up to Passlib 1.9**.

        * ``"host"``, ``"host_apache_24"`` -- pick strongest scheme supported by
           apache >= 2.4 and/or host OS.

        * ``"host_apache_22"`` -- pick strongest scheme supported by
           apache >= 2.2 and/or host OS.

        .. versionadded:: 1.6
            This keyword was previously named ``default``. That alias
            has been deprecated, and will be removed in Passlib 1.8.

        .. versionchanged:: 1.6.3

            Added support for ``"bcrypt"``, ``"sha256_crypt"``, and ``"portable"`` alias.

        .. versionchanged:: 1.7

            Added apache 2.4 semantics, and additional aliases.

    :type context: :class:`~passlib.context.CryptContext`
    :param context:
        :class:`!CryptContext` instance used to create
        and verify the hashes found in the htpasswd file.
        The default value is a pre-built context which supports all
        of the hashes officially allowed in an htpasswd file.

        This is also exposed as a readonly instance attribute.

        .. warning::

            This option may be used to add support for non-standard hash
            formats to an htpasswd file. However, the resulting file
            will probably not be usable by another application,
            and particularly not by Apache.

    :param autoload:
        Set to ``False`` to prevent the constructor from automatically
        loaded the file from disk.

        .. deprecated:: 1.6
            This has been replaced by the *new* keyword.
            Instead of setting ``autoload=False``, you should use
            ``new=True``. Support for this keyword will be removed
            in Passlib 1.8.

    :param default:
        Change the default algorithm used to hash new passwords.

        .. deprecated:: 1.6
            This has been renamed to *default_scheme* for clarity.
            Support for this alias will be removed in Passlib 1.8.

    Loading & Saving
    ================
    .. automethod:: load
    .. automethod:: load_if_changed
    .. automethod:: load_string
    .. automethod:: save
    .. automethod:: to_string

    Inspection
    ================
    .. automethod:: users
    .. automethod:: check_password
    .. automethod:: get_hash

    Modification
    ================
    .. automethod:: set_password
    .. automethod:: delete

    Alternate Constructors
    ======================
    .. automethod:: from_string

    Attributes
    ==========
    .. attribute:: path

        Path to local file that will be used as the default
        for all :meth:`load` and :meth:`save` operations.
        May be written to, initialized by the *path* constructor keyword.

    .. attribute:: autosave

        Writeable flag indicating whether changes will be automatically
        written to *path*.

    Errors
    ======
    :raises ValueError:
        All of the methods in this class will raise a :exc:`ValueError` if
        any user name contains a forbidden character (one of ``:\r\n\t\x00``),
        or is longer than 255 characters.
    Nc                 ój  •— d|v r,t          dt          d¬¦  «         |                     d¦  «        }|rW|t          v rt          d|z  t          j        ¦  «         t                               ||¦  «        }|                     |¬¦  «        }|| _	         t          t          | ¦  «        j        |fi |¤Ž d S )NrÃ   z{``default`` is deprecated as of Passlib 1.6, and will be removed in Passlib 1.8, it has been renamed to ``default_scheem``.r+   r,   zPHtpasswdFile: no bcrypt backends available, using fallback for default scheme %r)rÃ   )r   r.   Úpoprµ   r   ÚPasslibSecurityWarningrÉ   ÚgetÚcopyÚcontextÚsuperr   r9   )r"   r   Údefault_schemerÒ   r!   r<   s        €r#   r9   zHtpasswdFile.__init__Ê  sÙ   ø€ à˜ÐÐÝð *õ $°ð3ñ 3ô 3ð 3ð "ŸXšX iÑ0Ô0ˆNØð 	;Ø¥Ð0Ð0Ýð <Ø>LñMåÔ/ñ1ô 1ð 1õ /×2Ò2°>À>ÑRÔRˆNØ—l’l¨>�lÑ:Ô:ˆGØˆŒØ*��l˜DÑ!Ô!Ô*¨4Ð8Ð8°4Ð8Ð8Ð8Ð8Ð8r%   c                 ó¨   — |                      ¦   «                              t          ¦  «        }t          |¦  «        dk    rt	          d|z  ¦  «        ‚|S )Nr+   z/malformed htpasswd file (error reading line %d)©rc   ÚsplitÚ_BCOLONr›   r/   )r"   r   rp   Úresults       r#   rY   zHtpasswdFile._parse_recordÜ  sP   € à—’‘”×&Ò&¥wÑ/Ô/ˆÝˆv‰;Œ;˜!ÒÐÝÐNØ%ñ&ñ 'ô 'ð 'àˆr%   c                 ó$   — t          d||¦  «        S )Nz%s:%s
©r
   )r"   r‡   Úhashs      r#   r€   zHtpasswdFile._render_recordä  s   € Ý˜I t¨TÑ2Ô2Ð2r%   c                 ó*   ‡ — ˆ fd„‰ j         D ¦   «         S )z6
        Return list of all users in database
        c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS r   ©r    )r•   r‡   r"   s     €r#   ú
<listcomp>z&HtpasswdFile.users.<locals>.<listcomp>ï  s'   ø€ ÐCÐCÐC¨T�×"Ò" 4Ñ(Ô(ÐCÐCÐCr%   )r5   rC   s   `r#   ÚuserszHtpasswdFile.usersë  s"   ø€ ð DÐCÐCÐC°T´]ÐCÑCÔCÐCr%   c                 ób   — | j                              |¦  «        }|                      ||¦  «        S )a£  Set password for user; adds user if needed.

        :returns:
            * ``True`` if existing user was updated.
            * ``False`` if user account was added.

        .. versionchanged:: 1.6
            This method was previously called ``update``, it was renamed
            to prevent ambiguity with the dictionary method.
            The old alias is deprecated, and will be removed in Passlib 1.8.
        )rÒ   rÜ   Úset_hash)r"   r‡   ÚpasswordrÜ   s       r#   Úset_passwordzHtpasswdFile.set_passwordý  s-   € ð Œ|× Ò  Ñ*Ô*ˆØ�}Š}˜T 4Ñ(Ô(Ð(r%   ú1.6ú1.8rå   ©Ú
deprecatedÚremovedÚreplacementc                 ó.   — |                       ||¦  «        S ©zset password for user©rå   ©r"   r‡   rä   s      r#   r·   zHtpasswdFile.update  s   € ð × Ò   xÑ0Ô0Ð0r%   c                 óf   — 	 | j         |                      |¦  «                 S # t          $ r Y dS w xY w)a  Return hash stored for user, or ``None`` if user not found.

        .. versionchanged:: 1.6
            This method was previously named ``find``, it was renamed
            for clarity. The old name is deprecated, and will be removed
            in Passlib 1.8.
        N)r5   r‹   ÚKeyErrorrŠ   s     r#   Úget_hashzHtpasswdFile.get_hash  sD   € ð	Ø”= ×!2Ò!2°4Ñ!8Ô!8Ô9Ð9øÝð 	ð 	ð 	Ø�4�4ð	øøøs   ‚" ¢
0¯0c                 óð   — t           r/t          |t          ¦  «        r|                     | j        ¦  «        }|                      |¦  «        }|                      ||¦  «        }|                      ¦   «          |S )zã
        semi-private helper which allows writing a hash directly;
        adds user if needed.

        .. warning::
            does not (currently) do any validation of the hash string

        .. versionadded:: 1.7
        )r   r˜   Ústrr™   r0   r‹   rt   rw   )r"   r‡   rÜ   rs   s       r#   rã   zHtpasswdFile.set_hash  sm   € õ ð 	.•:˜d¥CÑ(Ô(ð 	.Ø—;’;˜tœ}Ñ-Ô-ˆDØ× Ò  Ñ&Ô&ˆØ×#Ò# D¨$Ñ/Ô/ˆØ�ŠÑÔÐØˆr%   rò   c                 ó,   — |                       |¦  «        S ©zreturn hash for user©rò   rŠ   s     r#   ÚfindzHtpasswdFile.find1  s   € ð �}Š}˜TÑ"Ô"Ð"r%   c                 óŠ   — 	 | j         |                      |¦  «        = n# t          $ r Y dS w xY w|                      ¦   «          dS )zƒDelete user's entry.

        :returns:
            * ``True`` if user deleted.
            * ``False`` if user not found.
        FT)r5   r‹   rñ   rw   rŠ   s     r#   ÚdeletezHtpasswdFile.delete8  sY   € ð	Ø”˜d×/Ò/°Ñ5Ô5Ð6Ð6øÝð 	ð 	ð 	Ø�5�5ð	øøøà�ŠÑÔÐØˆts   ‚ ž
,«,c                 ó`  — |                       |¦  «        }| j                             |¦  «        }|€dS t          |t          ¦  «        r|                     | j        ¦  «        }| j                             ||¦  «        \  }}|r+|�)|| j        v sJ ‚|| j        |<   |  	                    ¦   «          |S )aM  
        Verify password for specified user.
        If algorithm marked as deprecated by CryptContext, will automatically be re-hashed.

        :returns:
            * ``None`` if user not found.
            * ``False`` if user found, but password does not match.
            * ``True`` if user found and password matches.

        .. versionchanged:: 1.6
            This method was previously called ``verify``, it was renamed
            to prevent ambiguity with the :class:`!CryptContext` method.
            The old alias is deprecated, and will be removed in Passlib 1.8.
        N)
r‹   r5   rÐ   r˜   r   r™   r0   rÒ   Úverify_and_updaterw   )r"   r‡   rä   rÜ   ÚokÚnew_hashs         r#   Úcheck_passwordzHtpasswdFile.check_passwordF  s¹   € ð × Ò  Ñ&Ô&ˆØŒ}× Ò  Ñ&Ô&ˆØˆ<Ø�4Ý�h¥Ñ(Ô(ð 	6ð  —’ t¤}Ñ5Ô5ˆHØ”|×5Ò5°hÀÑEÔE‰ˆˆHØð 	�(Ð&à˜4œ=Ð(Ð(Ð(Ð(Ø"*ˆDŒM˜$ÑØ�NŠNÑÔÐØˆ	r%   rÿ   c                 ó.   — |                       ||¦  «        S ©zverify password for user©rÿ   rï   s      r#   ÚverifyzHtpasswdFile.verifye  s   € ð ×"Ò" 4¨Ñ2Ô2Ð2r%   )r=   r¡   r¢   r£   Úhtpasswd_contextr9   rY   r€   rá   rå   r   r·   rò   rã   rø   rú   rÿ   r  Ú__classcell__©r<   s   @r#   r   r     st  ø€ € € € € ðmð mðp !°Ð?Oð 9ð 9ð 9ð 9ð 9ð 9ð$ð ð ð3ð 3ð 3ðDð Dð Dð$)ð )ð )ð Ð %°Ø#1ð3ñ 3ô 3ð1ð 1ñ3ô 3ð1ðð ð ðð ð ð$ Ð %°Ø#-ð/ñ /ô /ð#ð #ñ/ô /ð#ð
ð ð ðð ð ð> Ð %°Ø#3ð5ñ 5ô 5ð3ð 3ñ5ô 5ð3ð 3ð 3ð 3ð 3r%   c                   ó  ‡ — e Zd ZdZdZdˆ fd„	Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zdd
„Zdefd„Z eddd¬¦  «        d„ ¦   «         Zdd„Zdefd„Z eddd¬¦  «        d„ ¦   «         Zdd„Zd„ Zdefd„Z eddd¬¦  «        d„ ¦   «         Zˆ xZS )r   aÎ  class for reading & writing Htdigest files.

    The class constructor accepts the following arguments:

    :type path: filepath
    :param path:

        Specifies path to htdigest file, use to implicitly load from and save to.

        This class has two modes of operation:

        1. It can be "bound" to a local file by passing a ``path`` to the class
           constructor. In this case it will load the contents of the file when
           created, and the :meth:`load` and :meth:`save` methods will automatically
           load from and save to that file if they are called without arguments.

        2. Alternately, it can exist as an independant object, in which case
           :meth:`load` and :meth:`save` will require an explicit path to be
           provided whenever they are called. As well, ``autosave`` behavior
           will not be available.

           This feature is new in Passlib 1.6, and is the default if no
           ``path`` value is provided to the constructor.

        This is also exposed as a readonly instance attribute.

    :type default_realm: str
    :param default_realm:

        If ``default_realm`` is set, all the :class:`HtdigestFile`
        methods that require a realm will use this value if one is not
        provided explicitly. If unset, they will raise an error stating
        that an explicit realm is required.

        This is also exposed as a writeable instance attribute.

        .. versionadded:: 1.6

    :type new: bool
    :param new:

        Normally, if *path* is specified, :class:`HtdigestFile` will
        immediately load the contents of the file. However, when creating
        a new htpasswd file, applications can set ``new=True`` so that
        the existing file (if any) will not be loaded.

        .. versionadded:: 1.6
            This feature was previously enabled by setting ``autoload=False``.
            That alias has been deprecated, and will be removed in Passlib 1.8

    :type autosave: bool
    :param autosave:

        Normally, any changes made to an :class:`HtdigestFile` instance
        will not be saved until :meth:`save` is explicitly called. However,
        if ``autosave=True`` is specified, any changes made will be
        saved to disk immediately (assuming *path* has been set).

        This is also exposed as a writeable instance attribute.

    :type encoding: str
    :param encoding:

        Optionally specify character encoding used to read/write file
        and hash passwords. Defaults to ``utf-8``, though ``latin-1``
        is the only other commonly encountered encoding.

        This is also exposed as a readonly instance attribute.

    :param autoload:
        Set to ``False`` to prevent the constructor from automatically
        loaded the file from disk.

        .. deprecated:: 1.6
            This has been replaced by the *new* keyword.
            Instead of setting ``autoload=False``, you should use
            ``new=True``. Support for this keyword will be removed
            in Passlib 1.8.

    Loading & Saving
    ================
    .. automethod:: load
    .. automethod:: load_if_changed
    .. automethod:: load_string
    .. automethod:: save
    .. automethod:: to_string

    Inspection
    ==========
    .. automethod:: realms
    .. automethod:: users
    .. automethod:: check_password(user[, realm], password)
    .. automethod:: get_hash

    Modification
    ============
    .. automethod:: set_password(user[, realm], password)
    .. automethod:: delete
    .. automethod:: delete_realm

    Alternate Constructors
    ======================
    .. automethod:: from_string

    Attributes
    ==========
    .. attribute:: default_realm

        The default realm that will be used if one is not provided
        to methods that require it. By default this is ``None``,
        in which case an explicit realm must be provided for every
        method call. Can be written to.

    .. attribute:: path

        Path to local file that will be used as the default
        for all :meth:`load` and :meth:`save` operations.
        May be written to, initialized by the *path* constructor keyword.

    .. attribute:: autosave

        Writeable flag indicating whether changes will be automatically
        written to *path*.

    Errors
    ======
    :raises ValueError:
        All of the methods in this class will raise a :exc:`ValueError` if
        any user name or realm contains a forbidden character (one of ``:\r\n\t\x00``),
        or is longer than 255 characters.
    Nc                 óX   •— || _          t          t          | ¦  «        j        |fi |¤Ž d S rB   )Údefault_realmrÓ   r   r9   )r"   r   r	  r!   r<   s       €r#   r9   zHtdigestFile.__init__  s6   ø€ Ø*ˆÔØ*��l˜DÑ!Ô!Ô*¨4Ð8Ð8°4Ð8Ð8Ð8Ð8Ð8r%   c                 ó¼   — |                      ¦   «                              t          ¦  «        }t          |¦  «        dk    rt	          d|z  ¦  «        ‚|\  }}}||f|fS )NrÀ   z/malformed htdigest file (error reading line %d)rÖ   )r"   r   rp   rÙ   r‡   r�   rÜ   s          r#   rY   zHtdigestFile._parse_record  sf   € Ø—’‘”×&Ò&¥wÑ/Ô/ˆÝˆv‰;Œ;˜!ÒÐÝÐNØ%ñ&ñ 'ô 'ð 'à"Ñˆˆe�TØ�eˆ}˜dÐ"Ð"r%   c                 ó0   — |\  }}t          d|||¦  «        S )Nz	%s:%s:%s
rÛ   )r"   rk   rÜ   r‡   r�   s        r#   r€   zHtdigestFile._render_record  s   € Ø‰ˆˆeÝ˜L¨$°°tÑ<Ô<Ð<r%   c                 ó:   — |€| j         }|€t          d¦  «        ‚|S )NzGyou must specify a realm explicitly, or set the default_realm attribute)r	  r   rŽ   s     r#   Ú_require_realmzHtdigestFile._require_realm  s4   € Øˆ=ØÔ&ˆEØˆ}Ýð !Eñ Fô Fð Fàˆr%   c                 óX   — |                       |¦  «        }|                      |d¦  «        S )Nr�   )r  r‰   rŽ   s     r#   r�   zHtdigestFile._encode_realm  s+   € Ø×#Ò# EÑ*Ô*ˆØ×!Ò! %¨Ñ1Ô1Ð1r%   c                 óV   — |                       |¦  «        |                      |¦  «        fS rB   )r‹   r�   ©r"   r‡   r�   s      r#   Ú_encode_keyzHtdigestFile._encode_key#  s)   € Ø× Ò  Ñ&Ô&¨×(:Ò(:¸5Ñ(AÔ(AÐAÐAr%   c                 ó\   ‡ — t          d„ ‰ j        D ¦   «         ¦  «        }ˆ fd„|D ¦   «         S )z%Return list of all realms in databasec              3   ó&   K  — | ]}|d          V — ŒdS )rX   Nr   )r•   rk   s     r#   r—   z&HtdigestFile.realms.<locals>.<genexpr>,  s&   è è € Ð5Ð5 �S˜”VÐ5Ð5Ð5Ð5Ð5Ð5r%   c                 ó:   •— g | ]}‰                      |¦  «        ‘ŒS r   rß   )r•   r�   r"   s     €r#   rà   z'HtdigestFile.realms.<locals>.<listcomp>-  s'   ø€ Ð>Ð>Ð>¨e�×"Ò" 5Ñ)Ô)Ð>Ð>Ð>r%   )r   r5   )r"   Úrealmss   ` r#   r  zHtdigestFile.realms*  s;   ø€ åÐ5Ð5 t¤}Ð5Ñ5Ô5Ñ5Ô5ˆØ>Ð>Ð>Ð>°vÐ>Ñ>Ô>Ð>r%   c                 óX   ‡ ‡— ‰                       ‰¦  «        Šˆˆ fd„‰ j        D ¦   «         S )z®Return list of all users in specified realm.

        * uses ``self.default_realm`` if no realm explicitly provided.
        * returns empty list if realm not found.
        c                 ó^   •— g | ])}|d          ‰k    ¯‰                      |d         ¦  «        ‘Œ*S )rX   r   rß   )r•   rk   r�   r"   s     €€r#   rà   z&HtdigestFile.users.<locals>.<listcomp>6  s?   ø€ ð $ð $ð $¨sØ�q”6˜U’?�?ð ×"Ò" 3 q¤6Ñ*Ô*Ø"�?�?r%   )r�   r5   rŽ   s   ``r#   rá   zHtdigestFile.users/  sJ   øø€ ð ×"Ò" 5Ñ)Ô)ˆð$ð $ð $ð $ð $°d´mð $ñ $ô $ð 	$r%   c                 ó®   — |t           u rd|}}|                      |¦  «        }t          j        |||| j        ¬¦  «        }|                      |||¦  «        S )aŸ  Set password for user; adds user & realm if needed.

        If ``self.default_realm`` has been set, this may be called
        with the syntax ``set_password(user, password)``,
        otherwise it must be called with all three arguments:
        ``set_password(user, realm, password)``.

        :returns:
            * ``True`` if existing user was updated
            * ``False`` if user account added.
        N©r0   )Ú_UNSETr  r	   rÜ   r0   rã   ©r"   r‡   r�   rä   rÜ   s        r#   rå   zHtdigestFile.set_passwordQ  s[   € ð •vÐÐà" E�8ˆEØ×#Ò# EÑ*Ô*ˆÝŒ}˜X t¨U¸T¼]ÐKÑKÔKˆØ�}Š}˜T 5¨$Ñ/Ô/Ð/r%   ræ   rç   rå   rè   c                 ó0   — |                       |||¦  «        S rí   rî   ©r"   r‡   r�   rä   s       r#   r·   zHtdigestFile.updated  s   € ð × Ò   u¨hÑ7Ô7Ð7r%   c                 ó°   — |                       ||¦  «        }| j                             |¦  «        }|€dS t          r|                     | j        ¦  «        }|S )a�  Return :class:`~passlib.hash.htdigest` hash stored for user.

        * uses ``self.default_realm`` if no realm explicitly provided.
        * returns ``None`` if user or realm not found.

        .. versionchanged:: 1.6
            This method was previously named ``find``, it was renamed
            for clarity. The old name is deprecated, and will be removed
            in Passlib 1.8.
        N)r  r5   rÐ   r   rŸ   r0   )r"   r‡   r�   rk   rÜ   s        r#   rò   zHtdigestFile.get_hashj  sX   € ð ×Ò˜t UÑ+Ô+ˆØŒ}× Ò  Ñ%Ô%ˆØˆ<Ø�4Ýð 	.Ø—;’;˜tœ}Ñ-Ô-ˆDØˆr%   c                 ó  — |t           u rd|}}t          r/t          |t          ¦  «        r|                     | j        ¦  «        }|                      ||¦  «        }|                      ||¦  «        }|                      ¦   «          |S )aÈ  
        semi-private helper which allows writing a hash directly;
        adds user & realm if needed.

        If ``self.default_realm`` has been set, this may be called
        with the syntax ``set_hash(user, hash)``,
        otherwise it must be called with all three arguments:
        ``set_hash(user, realm, hash)``.

        .. warning::
            does not (currently) do any validation of the hash string

        .. versionadded:: 1.7
        N)	r  r   r˜   rô   r™   r0   r  rt   rw   )r"   r‡   r�   rÜ   rk   rs   s         r#   rã   zHtdigestFile.set_hash}  s�   € ð •6ˆ>ˆ>à �4ˆEåð 	.•:˜d¥CÑ(Ô(ð 	.Ø—;’;˜tœ}Ñ-Ô-ˆDØ×Ò˜t UÑ+Ô+ˆØ×#Ò# C¨Ñ.Ô.ˆØ�ŠÑÔÐØˆr%   rò   c                 ó.   — |                       ||¦  «        S rö   r÷   r  s      r#   rø   zHtdigestFile.find—  s   € ð �}Š}˜T 5Ñ)Ô)Ð)r%   c                 ó�   — |                       ||¦  «        }	 | j        |= n# t          $ r Y dS w xY w|                      ¦   «          dS )záDelete user's entry for specified realm.

        if realm is not specified, uses ``self.default_realm``.

        :returns:
            * ``True`` if user deleted,
            * ``False`` if user not found in realm.
        FT)r  r5   rñ   rw   )r"   r‡   r�   rk   s       r#   rú   zHtdigestFile.deletež  sb   € ð ×Ò˜t UÑ+Ô+ˆð	Ø”˜cÐ"Ð"øÝð 	ð 	ð 	Ø�5�5ð	øøøà�ŠÑÔÐØˆts   ˜! ¡
/®/c                 ó®   ‡— |                       ‰¦  «        Š| j        }ˆfd„|D ¦   «         }|D ]}||= Œ|                      ¦   «          t          |¦  «        S )z±Delete all users for specified realm.

        if realm is not specified, uses ``self.default_realm``.

        :returns: number of users deleted (0 if realm not found)
        c                 ó,   •— g | ]}|d          ‰k    ¯|‘ŒS )rX   r   )r•   rk   r�   s     €r#   rà   z-HtdigestFile.delete_realm.<locals>.<listcomp>¸  s"   ø€ Ð:Ð:Ð:˜¨#¨a¬&°Eª/¨/�¨/¨/¨/r%   )r�   r5   rw   r›   )r"   r�   rf   Úkeysrk   s    `   r#   Údelete_realmzHtdigestFile.delete_realm¯  sl   ø€ ð ×"Ò" 5Ñ)Ô)ˆØ”-ˆØ:Ð:Ð:Ð:˜wÐ:Ñ:Ô:ˆØð 	ð 	ˆCØ˜��Ø�ŠÑÔÐÝ�4‰yŒyÐr%   c                 óì   — |t           u rd|}}|                      |¦  «        }|                      |¦  «        }| j                             ||f¦  «        }|€dS t          j        ||||| j        ¬¦  «        S )aê  Verify password for specified user + realm.

        If ``self.default_realm`` has been set, this may be called
        with the syntax ``check_password(user, password)``,
        otherwise it must be called with all three arguments:
        ``check_password(user, realm, password)``.

        :returns:
            * ``None`` if user or realm not found.
            * ``False`` if user found, but password does not match.
            * ``True`` if user found and password matches.

        .. versionchanged:: 1.6
            This method was previously called ``verify``, it was renamed
            to prevent ambiguity with the :class:`!CryptContext` method.
            The old alias is deprecated, and will be removed in Passlib 1.8.
        Nr  )r  r‹   r�   r5   rÐ   r	   r  r0   r  s        r#   rÿ   zHtdigestFile.check_password¾  s‡   € ð$ •vÐÐà" E�8ˆEØ× Ò  Ñ&Ô&ˆØ×"Ò" 5Ñ)Ô)ˆØŒ}× Ò  $ u Ñ.Ô.ˆØˆ<Ø�4ÝŒ˜x¨¨t°UØ(,¬ð7ñ 7ô 7ð 	7r%   rÿ   c                 ó0   — |                       |||¦  «        S r  r  r  s       r#   r  zHtdigestFile.verifyÛ  s   € ð ×"Ò" 4¨°Ñ9Ô9Ð9r%   )NNrB   )r=   r¡   r¢   r£   r	  r9   rY   r€   r  r�   r  r  rá   r  rå   r   r·   rò   rã   rø   rú   r%  rÿ   r  r  r  s   @r#   r   r   r  sð  ø€ € € € € ðBð Bð^ €Mð
9ð 9ð 9ð 9ð 9ð 9ð#ð #ð #ð=ð =ð =ðð ð ð2ð 2ð 2ðBð Bð Bð?ð ?ð ?ð
$ð $ð $ð $ðD (,°fð 0ð 0ð 0ð 0ð& Ð %°Ø#1ð3ñ 3ô 3ð8ð 8ñ3ô 3ð8ðð ð ð ð& $(¨fð ð ð ð ð4 Ð %°Ø#-ð/ñ /ô /ð*ð *ñ/ô /ð*ð
ð ð ð ð"ð ð ð *.¸ð 7ð 7ð 7ð 7ð: Ð %°Ø#3ð5ñ 5ô 5ð:ð :ñ5ô 5ð:ð :ð :ð :ð :r%   )/r£   Ú
__future__r   ÚloggingÚ	getLoggerr=   r^   rK   Úwarningsr   Úpasslibr   r   Úpasslib.contextr   Úpasslib.excr   Úpasslib.hashr	   Úpasslib.utilsr
   r   r   Úpasslib.utils.decorr   Úpasslib.utils.compatr   r   r   r   Ú__all__Úobjectr  rØ   r]   r”   ra   rb   r   r   rµ   rº   rÉ   rË   r  r   r   r   r%   r#   ú<module>r5     s&  ðØ .Ð .ð
 &Ð %Ð %Ð %Ð %Ð %à €€€Ð'�gÔ'¨Ñ1Ô1�Ø 	€	€	€	Ø Ð Ð Ð Ð Ð ð "Ð !Ð !Ð !Ð !Ð !Ð !Ð !Ø (Ð (Ð (Ð (Ð (Ð (Ø +Ð +Ð +Ð +Ð +Ð +Ø !Ð !Ð !Ð !Ð !Ð !Ø @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ BÐ Bð Øð€ð 
ˆ‰Œ€à
€Ø	€ð &Ð ð €Ø
€ð
jð jð jð jð j�&ñ jô jð jðJ �#‘%”%€ð&ð &ð &ðR *Ð)Ñ+Ô+Ð ð*ð *ð *ðZ *Ð)Ñ+Ô+Ð ðX3ð X3ð X3ð X3ð X3�;ñ X3ô X3ð X3ðBm:ð m:ð m:ð m:ð m:�;ñ m:ô m:ð m:ð m:ð m:r%   