U
    -e                     @   s  d Z ddlZddlZddlZddlZddlZddlmZ zddlmZ W n e	k
r`   dZY nX zddl
Z
W n e	k
r   dZ
Y nX dddZG d	d
 d
ZG dd dZG dd dZG dd dZdd Zdd ZG dd dZG dd deZG dd deZG dd deZdS )z1
The classes that actually handle the downloads.
    N   	parse_url)tqdmFc                 C   s^   t ttttd}t| }|d |krHtd|d  d|  d|  d||d  |d}|S )a  
    Choose the appropriate downloader for the given URL based on the protocol.

    Parameters
    ----------
    url : str
        A URL (including protocol).
    progressbar : bool or an arbitrary progress bar object
        If True, will print a progress bar of the download to standard error
        (stderr). Requires `tqdm <https://github.com/tqdm/tqdm>`__ to be
        installed. Alternatively, an arbitrary progress bar object can be
        passed. See :ref:`custom-progressbar` for details.

    Returns
    -------
    downloader
        A downloader class, like :class:`pooch.HTTPDownloader`,
        :class:`pooch.FTPDownloader`, or :class: `pooch.SFTPDownloader`.

    Examples
    --------

    >>> downloader = choose_downloader("http://something.com")
    >>> print(downloader.__class__.__name__)
    HTTPDownloader
    >>> downloader = choose_downloader("https://something.com")
    >>> print(downloader.__class__.__name__)
    HTTPDownloader
    >>> downloader = choose_downloader("ftp://something.com")
    >>> print(downloader.__class__.__name__)
    FTPDownloader
    >>> downloader = choose_downloader("doi:DOI/filename.csv")
    >>> print(downloader.__class__.__name__)
    DOIDownloader

    )ftphttpshttpsftpdoiprotocolzUnrecognized URL protocol 'z' in 'z'. Must be one of .)progressbar)FTPDownloaderHTTPDownloaderSFTPDownloaderDOIDownloaderr   
ValueErrorkeys)urlr   Zknown_downloaders
parsed_url
downloader r   R/var/www/html/Darija-Ai-Train/env/lib/python3.8/site-packages/pooch/downloaders.pychoose_downloader   s    &r   c                   @   s$   e Zd ZdZd	ddZd
ddZdS )r   a  
    Download manager for fetching files over HTTP/HTTPS.

    When called, downloads the given file URL into the specified local file.
    Uses the :mod:`requests` library to manage downloads.

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to customize
    the download of files (for example, to use authentication or print a
    progress bar).

    Parameters
    ----------
    progressbar : bool or an arbitrary progress bar object
        If True, will print a progress bar of the download to standard error
        (stderr). Requires `tqdm <https://github.com/tqdm/tqdm>`__ to be
        installed. Alternatively, an arbitrary progress bar object can be
        passed. See :ref:`custom-progressbar` for details.
    chunk_size : int
        Files are streamed *chunk_size* bytes at a time instead of loading
        everything into memory at one. Usually doesn't need to be changed.
    **kwargs
        All keyword arguments given when creating an instance of this class
        will be passed to :func:`requests.get`.

    Examples
    --------

    Download one of the data files from the Pooch repository:

    >>> import os
    >>> from pooch import __version__, check_version
    >>> url = "https://github.com/fatiando/pooch/raw/{}/data/tiny-data.txt"
    >>> url = url.format(check_version(__version__, fallback="main"))
    >>> downloader = HTTPDownloader()
    >>> # Not using with Pooch.fetch so no need to pass an instance of Pooch
    >>> downloader(url=url, output_file="tiny-data.txt", pooch=None)
    >>> os.path.exists("tiny-data.txt")
    True
    >>> with open("tiny-data.txt") as f:
    ...     print(f.read().strip())
    # A tiny data file for test purposes only
    1  2  3  4  5  6
    >>> os.remove("tiny-data.txt")

    Authentication can be handled by passing a user name and password to
    :func:`requests.get`. All arguments provided when creating an instance of
    the class are forwarded to :func:`requests.get`. We'll use
    ``auth=(username, password)`` to use basic HTTPS authentication. The
    https://httpbin.org website allows us to make a fake a login request using
    whatever username and password we provide to it:

    >>> user = "doggo"
    >>> password = "goodboy"
    >>> # httpbin will ask for the user and password we provide in the URL
    >>> url = f"https://httpbin.org/basic-auth/{user}/{password}"
    >>> # Trying without the login credentials causes an error
    >>> downloader = HTTPDownloader()
    >>> try:
    ...     downloader(url=url, output_file="tiny-data.txt", pooch=None)
    ... except Exception:
    ...     print("There was an error!")
    There was an error!
    >>> # Pass in the credentials to HTTPDownloader
    >>> downloader = HTTPDownloader(auth=(user, password))
    >>> downloader(url=url, output_file="tiny-data.txt", pooch=None)
    >>> with open("tiny-data.txt") as f:
    ...     for line in f:
    ...         print(line.rstrip())
    {
      "authenticated": true,
      "user": "doggo"
    }
    >>> os.remove("tiny-data.txt")

    F   c                 K   s0   || _ || _|| _| jdkr,td kr,tdd S NT2Missing package 'tqdm' required for progress bars.)kwargsr   
chunk_sizer   r   selfr   r   r   r   r   r   __init__   s
    zHTTPDownloader.__init__c                 C   s8  |r$t j|dd}t|jdk}|S | j }|dd t|d }|rTt|d}zt j
|f|}|  |j| jd}	t|j
dd	}
| jdkrttjd
k}t|
d|dddd}n| jr| j}|
|_|	D ],}|r|| |  | jr|| j q| jr |  ||
 |	  W 5 |r2|	  X dS )a  
        Download the given URL over HTTP to the given output file.

        Uses :func:`requests.get`.

        Parameters
        ----------
        url : str
            The URL to the file you want to download.
        output_file : str or file-like object
            Path (and file name) to which the file will be downloaded.
        pooch : :class:`~pooch.Pooch`
            The instance of :class:`~pooch.Pooch` that is calling this method.
        check_only : bool
            If True, will only check if a file exists on the server and
            **without downloading the file**. Will return ``True`` if the file
            exists and ``False`` otherwise.

        Returns
        -------
        availability : bool or None
            If ``check_only==True``, returns a boolean indicating if the file
            is available on the server. Otherwise, returns ``None``.

        T)allow_redirects   streamwritew+b)r   zcontent-lengthr   win32O   BtotalZncolsasciiunitZ
unit_scaleZleaveN)requestsheadboolstatus_coder   copy
setdefaulthasattropenclosegetraise_for_statusiter_contentr   intheadersr   sysplatformr   r+   r%   flushupdatereset)r    r   output_filepooch
check_onlyresponse	availabler   ispathcontentr+   	use_asciiprogresschunkr   r   r   __call__   sP    





zHTTPDownloader.__call__N)Fr   )F__name__
__module____qualname____doc__r!   rK   r   r   r   r   r   U   s   L
r   c                   @   s$   e Zd ZdZddd	Zdd
dZdS )r   a  
    Download manager for fetching files over FTP.

    When called, downloads the given file URL into the specified local file.
    Uses the :mod:`ftplib` module to manage downloads.

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to customize
    the download of files (for example, to use authentication or print a
    progress bar).

    Parameters
    ----------
    port : int
        Port used for the FTP connection.
    username : str
        User name used to login to the server. Only needed if the server
        requires authentication (i.e., no anonymous FTP).
    password : str
        Password used to login to the server. Only needed if the server
        requires authentication (i.e., no anonymous FTP). Use the empty string
        to indicate no password is required.
    account : str
        Some servers also require an "account" name for authentication.
    timeout : int
        Timeout in seconds for ftp socket operations, use None to mean no
        timeout.
    progressbar : bool
        If True, will print a progress bar of the download to standard error
        (stderr). Requires `tqdm <https://github.com/tqdm/tqdm>`__ to be
        installed. **Custom progress bars are not yet supported.**
    chunk_size : int
        Files are streamed *chunk_size* bytes at a time instead of loading
        everything into memory at one. Usually doesn't need to be changed.

       	anonymous NFr   c                 C   sH   || _ || _|| _|| _|| _|| _|| _| jdkrDtd krDtdd S r   )	portusernamepasswordaccounttimeoutr   r   r   r   )r    rT   rU   rV   rW   rX   r   r   r   r   r   r!     s    
zFTPDownloader.__init__c              	      sb  t |}tj| jd}|j|d | jd |rztj|d \}}z(|j
| j| j| jd |||k}	W 5 |	  X |	S t d }
|
rt d z|j
| j| j| jd d|d  }| jr.|d	 ttjd
k}tt||d d|dddd&  fdd}|j||| jd W 5 Q R X n|j| j| jd W 5 |  |
r\ 	  X dS )aZ  
        Download the given URL over FTP to the given output file.

        Parameters
        ----------
        url : str
            The URL to the file you want to download.
        output_file : str or file-like object
            Path (and file name) to which the file will be downloaded.
        pooch : :class:`~pooch.Pooch`
            The instance of :class:`~pooch.Pooch` that is calling this method.
        check_only : bool
            If True, will only check if a file exists on the server and
            **without downloading the file**. Will return ``True`` if the file
            exists and ``False`` otherwise.

        Returns
        -------
        availability : bool or None
            If ``check_only==True``, returns a boolean indicating if the file
            is available on the server. Otherwise, returns ``None``.

        )rX   netloc)hostrT   path)userpasswdZacctr%   r&   zRETR zTYPE Ir'   r(   r)   Tr*   c                    s    t|   |  dS z+Update the progress bar and write to outputN)r?   lenr%   )datarA   rI   r   r   callbackl  s    z(FTPDownloader.__call__.<locals>.callback)	blocksizeN)r   ftplibFTPrX   connectrT   osr[   splitr6   loginrU   rV   rW   Znlstr4   r5   quitr   voidcmdr0   r<   r=   r   r:   sizeZ
retrbinaryr   r%   )r    r   rA   rB   rC   r   r   	directory	file_namerE   rF   commandrH   rb   r   ra   r   rK   2  sF    



zFTPDownloader.__call__)rQ   rR   rS   rS   NFr   )FrL   r   r   r   r   r      s   &       
r   c                   @   s"   e Zd ZdZdddZd	d
 ZdS )r   a  
    Download manager for fetching files over SFTP.

    When called, downloads the given file URL into the specified local file.
    Requires `paramiko <https://github.com/paramiko/paramiko>`__ to be
    installed.

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to customize
    the download of files (for example, to use authentication or print a
    progress bar).

    Parameters
    ----------
    port : int
        Port used for the SFTP connection.
    username : str
        User name used to login to the server. Only needed if the server
        requires authentication (i.e., no anonymous SFTP).
    password : str
        Password used to login to the server. Only needed if the server
        requires authentication (i.e., no anonymous SFTP). Use the empty
        string to indicate no password is required.
    timeout : int
        Timeout in seconds for sftp socket operations, use None to mean no
        timeout.
    progressbar : bool or an arbitrary progress bar object
        If True, will print a progress bar of the download to standard
        error (stderr). Requires `tqdm <https://github.com/tqdm/tqdm>`__ to
        be installed.

       rR   rS   NFc                 C   sh   || _ || _|| _|| _|| _|| _g }| jr@td kr@|d td krR|d |rdt	d
|d S )Nr   z7Missing package 'paramiko' required for SFTP downloads. )rT   rU   rV   rW   rX   r   r   appendparamikor   join)r    rT   rU   rV   rW   rX   r   errorsr   r   r   r!     s    	

zSFTPDownloader.__init__c           
   	      s   t |}tj|d | jfd}d}z|j| j| jd tj	|}| j
| _| jrt||d j}ttjdk}t|d|dd	d	d
 | jr &  fdd}	|j|d ||	d W 5 Q R X n||d | W 5 |  |dk	r|  X dS )aQ  
        Download the given URL over SFTP to the given output file.

        The output file must be given as a string (file name/path) and not an
        open file object! Otherwise, paramiko cannot save to that file.

        Parameters
        ----------
        url : str
            The URL to the file you want to download.
        output_file : str
            Path (and file name) to which the file will be downloaded. **Cannot
            be a file object**.
        pooch : :class:`~pooch.Pooch`
            The instance of :class:`~pooch.Pooch` that is calling this method.
        rY   )sockN)rU   rV   r[   r'   r(   r)   Tr*   c                    s"   t | _ t |  j  dS r^   )r:   r+   r?   n)currentr+   rI   r   r   rb     s    
z)SFTPDownloader.__call__.<locals>.callback)rb   )r   rs   	TransportrT   r6   rf   rU   rV   Z
SFTPClientZfrom_transportrX   Zget_channel
settimeoutr   r:   statst_sizer0   r<   r=   r   r7   )
r    r   rA   rB   r   
connectionr	   rl   rH   rb   r   ry   r   rK     s4     zSFTPDownloader.__call__)rp   rR   rS   rS   NFrL   r   r   r   r   r   {  s   "      
r   c                   @   s"   e Zd ZdZd	ddZdd ZdS )
r   a<  
    Download manager for fetching files from Digital Object Identifiers (DOIs).

    Open-access data repositories often issue Digital Object Identifiers (DOIs)
    for data which provide a stable link and citation point. The trick is
    finding out the download URL for a file given the DOI.

    When called, this downloader uses the repository's public API to find out
    the download URL from the DOI and file name. It then uses
    :class:`pooch.HTTPDownloader` to download the URL into the specified local
    file. Allowing "URL"s  to be specified with the DOI instead of the actual
    HTTP download link. Uses the :mod:`requests` library to manage downloads
    and interact with the APIs.

    The **format of the "URL"** is: ``doi:{DOI}/{file name}``.

    Notice that there are no ``//`` like in HTTP/FTP and you must specify a
    file name after the DOI (separated by a ``/``).

    Use with :meth:`pooch.Pooch.fetch` or :func:`pooch.retrieve` to be able to
    download files given the DOI instead of an HTTP link.

    Supported repositories:

    * `figshare <https://www.figshare.com>`__
    * `Zenodo <https://www.zenodo.org>`__
    * `DataVerse <https://dataverse.org/>`__ instances

    .. attention::

        DOIs from other repositories **will not work** since we need to access
        their particular APIs to find the download links. We welcome
        suggestions and contributions adding new repositories.

    Parameters
    ----------
    progressbar : bool or an arbitrary progress bar object
        If True, will print a progress bar of the download to standard error
        (stderr). Requires `tqdm <https://github.com/tqdm/tqdm>`__ to be
        installed. Alternatively, an arbitrary progress bar object can be
        passed. See :ref:`custom-progressbar` for details.
    chunk_size : int
        Files are streamed *chunk_size* bytes at a time instead of loading
        everything into memory at one. Usually doesn't need to be changed.
    **kwargs
        All keyword arguments given when creating an instance of this class
        will be passed to :func:`requests.get`.

    Examples
    --------

    Download one of the data files from the figshare archive of Pooch test
    data:

    >>> import os
    >>> downloader = DOIDownloader()
    >>> url = "doi:10.6084/m9.figshare.14763051.v1/tiny-data.txt"
    >>> # Not using with Pooch.fetch so no need to pass an instance of Pooch
    >>> downloader(url=url, output_file="tiny-data.txt", pooch=None)
    >>> os.path.exists("tiny-data.txt")
    True
    >>> with open("tiny-data.txt") as f:
    ...     print(f.read().strip())
    # A tiny data file for test purposes only
    1  2  3  4  5  6
    >>> os.remove("tiny-data.txt")

    Same thing but for our Zenodo archive:

    >>> url = "doi:10.5281/zenodo.4924875/tiny-data.txt"
    >>> downloader(url=url, output_file="tiny-data.txt", pooch=None)
    >>> os.path.exists("tiny-data.txt")
    True
    >>> with open("tiny-data.txt") as f:
    ...     print(f.read().strip())
    # A tiny data file for test purposes only
    1  2  3  4  5  6
    >>> os.remove("tiny-data.txt")

    Fr   c                 K   s   || _ || _|| _d S N)r   r   r   r   r   r   r   r!   <  s    zDOIDownloader.__init__c           	      C   sh   t |}t|d }|d }|d dkr4|dd }||}tf | j| jd| j}|||| dS )a7  
        Download the given DOI URL over HTTP to the given output file.

        Uses the repository's API to determine the actual HTTP download URL
        from the given DOI.

        Uses :func:`requests.get`.

        Parameters
        ----------
        url : str
            The URL to the file you want to download.
        output_file : str or file-like object
            Path (and file name) to which the file will be downloaded.
        pooch : :class:`~pooch.Pooch`
            The instance of :class:`~pooch.Pooch` that is calling this method.

        rY   r[   r   /r   N)r   r   )r   doi_to_repositorydownload_urlr   r   r   r   )	r    r   rA   rB   r   data_repositoryrn   r   r   r   r   r   rK   A  s    
 zDOIDownloader.__call__N)Fr   rL   r   r   r   r   r     s   Q
r   c                 C   sJ   t d|  }|j}d|j  kr,dk rFn ntd|  d| d|S )z
    Follow a DOI link to resolve the URL of the archive.

    Parameters
    ----------
    doi : str
        The DOI of the archive.

    Returns
    -------
    url : str
        The URL of the archive in the data repository.

    zhttps://doi.org/  X  zArchive with doi:z not found (see z). Is the DOI correct?)r.   r7   r   r1   r   )r
   rD   r   r   r   r   
doi_to_urlf  s    r   c                 C   sv   | d dkr| dd } t ttg}t| }d}|D ]}|dkr2|j|| d}q2|dkrrt|d }td| d|S )a]  
    Instantiate a data repository instance from a given DOI.

    This function implements the chain of responsibility dispatch
    to the correct data repository class.

    Parameters
    ----------
    doi : str
        The DOI of the archive.

    Returns
    -------
    data_repository : DataRepository
        The data repository object
    r   N)archive_urlr
   rY   zInvalid data repository 'zy'. To request or contribute support for this repository, please open an issue at https://github.com/fatiando/pooch/issues)FigshareRepositoryZenodoRepositoryDataverseRepositoryr   
initializer   r   )r
   Zrepositoriesr   r   repo
repositoryr   r   r   r     s(    
r   c                   @   s(   e Zd Zedd Zdd Zdd ZdS )DataRepositoryc                 C   s   dS )  
        Initialize the data repository if the given URL points to a
        corresponding repository.

        Initializes a data repository object. This is done as part of
        a chain of responsibility. If the class cannot handle the given
        repository URL, it returns `None`. Otherwise a `DataRepository`
        instance is returned.

        Parameters
        ----------
        doi : str
            The DOI that identifies the repository
        archive_url : str
            The resolved URL for the DOI
        Nr   )clsr
   r   r   r   r   r     s    zDataRepository.initializec                 C   s   t dS )n  
        Use the repository API to get the download URL for a file given
        the archive URL.

        Parameters
        ----------
        file_name : str
            The name of the file in the archive that will be downloaded.

        Returns
        -------
        download_url : str
            The HTTP URL that can be used to download the file.
        NNotImplementedError)r    rn   r   r   r   r     s    zDataRepository.download_urlc                 C   s   t dS )
        Populate the registry using the data repository's API

        Parameters
        ----------
        pooch : Pooch
            The pooch instance that the registry will be added to.
        Nr   )r    rB   r   r   r   populate_registry  s    
z DataRepository.populate_registryN)rM   rN   rO   classmethodr   r   r   r   r   r   r   r     s   
r   c                   @   s<   e Zd Zdd Zedd Zedd Zdd Zd	d
 Z	dS )r   c                 C   s   || _ || _d | _d S r   r   r
   _api_responser    r
   r   r   r   r   r!     s    zZenodoRepository.__init__c                 C   s"   t |}|d dkrdS | ||S )r   rY   z
zenodo.orgNr   r   r
   r   Zparsed_archive_urlr   r   r   r     s    zZenodoRepository.initializec                 C   s6   | j dkr0| jdd }td|  | _ | j S )zCached API response from ZenodoNr   r   zhttps://zenodo.org/api/records/)r   r   rh   r.   r7   json)r    
article_idr   r   r   api_response	  s    

zZenodoRepository.api_responsec                 C   sP   dd | j d D }||kr<td| d| j d| j d|| d d	 }|S )
r   c                 S   s   i | ]}|d  |qS )keyr   .0itemr   r   r   
<dictcomp>%  s      z1ZenodoRepository.download_url.<locals>.<dictcomp>filesFile '' not found in data archive  (doi:).linksr    r   r   r   r
   r    rn   r   r   r   r   r   r     s    zZenodoRepository.download_urlc                 C   s&   | j d D ]}|d |j|d < q
dS )r   r   Zchecksumr   Nr   registryr    rB   filedatar   r   r   r   -  s    
z"ZenodoRepository.populate_registryN)
rM   rN   rO   r!   r   r   propertyr   r   r   r   r   r   r   r     s   

r   c                   @   sD   e Zd Zdd Zedd Zdd Zedd Zd	d
 Z	dd Z
dS )r   c                 C   s   || _ || _d | _d S r   r   r   r   r   r   r!   <  s    zFigshareRepository.__init__c                 C   s"   t |}|d dkrdS | ||S )r   rY   zfigshare.comNr   r   r   r   r   r   A  s    zFigshareRepository.initializec                 C   sB   | j d\}}|dd }|d dkr.dS t|dd }|S )zi
        Parse version from the doi

        Return None if version is not available in the doi.
        r   r   r   r   vNr   )r
   rh   r:   )r    _suffixZ	last_partversionr   r   r   _parse_version_from_doi[  s    z*FigshareRepository._parse_version_from_doic                 C   s   | j dkrtd| j  d }|d }|  }|dkr^td| j dt d| }nd| d| }t|}|	  | d	 | _ | j S )
z!Cached API response from FigshareNz)https://api.figshare.com/v2/articles?doi=r   idzThe Figshare DOI 'zv' doesn't specify which version of the repository should be used. Figshare will point to the latest version available.z%https://api.figshare.com/v2/articles/z
/versions/r   )
r   r.   r7   r
   r   r   warningswarnUserWarningr8   )r    Zarticler   r   Zapi_urlrD   r   r   r   r   k  s(    


zFigshareRepository.api_responsec                 C   sH   dd | j D }||kr8td| d| j d| j d|| d }|S )r   c                 S   s   i | ]}|d  |qS )namer   r   r   r   r   r     s      z3FigshareRepository.download_url.<locals>.<dictcomp>r   r   r   r   r   r   r   r   r   r   r     s    zFigshareRepository.download_urlc                 C   s(   | j D ]}d|d  |j|d < qdS )r   md5:Zcomputed_md5r   Nr   r   r   r   r   r     s    

z$FigshareRepository.populate_registryN)rM   rN   rO   r!   r   r   r   r   r   r   r   r   r   r   r   r   ;  s   

'r   c                   @   sV   e Zd Zdd Zedd Zedd Zedd Zej	d	d Zd
d Z
dd ZdS )r   c                 C   s   || _ || _d | _d S r   r   r   r   r   r   r!     s    zDataverseRepository.__init__c                 C   s>   |  ||}d|j  kr"dk r*n ndS | ||}||_|S )r   r   r   N)_get_api_responser1   r   )r   r
   r   rD   r   r   r   r   r     s    
zDataverseRepository.initializec                 C   s.   t |}t|d  d|d  d| }|S )z
        Perform the actual API request

        This has been separated into a separate ``classmethod``, as it can be
        used prior and after the initialization.
        r   ://rY   z-/api/datasets/:persistentId?persistentId=doi:)r   r.   r7   )r   r
   r   parsedrD   r   r   r   r     s
    z%DataverseRepository._get_api_responsec                 C   s"   | j dkr| | j| j| _ | j S )z-Cached API response from a DataVerse instanceN)r   r   r
   r   )r    r   r   r   r     s    
 z DataverseRepository.api_responsec                 C   s
   || _ dS )zUpdate the cached API responseN)r   )r    rD   r   r   r   r     s    c                 C   s   t | j}| j d d d D ]<}||d d kr |d  d|d  d	|d d
    S q td| d| j d| j ddS )r   r`   latestVersionr   dataFilefilenamer   r   rY   z0/api/access/datafile/:persistentId?persistentId=ZpersistentIdr   r   r   r   N)r   r   r   r   r   r
   )r    rn   r   r   r   r   r   r     s    
"z DataverseRepository.download_urlc                 C   s@   | j  d d d D ]$}d|d d  |j|d d < qdS )	r   r`   r   r   r   r   md5r   N)r   r   r   r   r   r   r   r     s
    

z%DataverseRepository.populate_registryN)rM   rN   rO   r!   r   r   r   r   r   setterr   r   r   r   r   r   r     s   




r   )F)rP   rg   r<   rd   r   r.   utilsr   r   ImportErrorrs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s6   


7 % o|55R~