
    Æe\                        U d Z ddlZddlZddlmZ ddlZddlZddlZddlZddl	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 ddlmZ dd	lmZ dd
lmZmZmZmZmZmZmZ ddlm Z m!Z!m"Z"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.m/Z/m0Z0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9m:Z: ddl;m<Z< dee/   de=de#j|                  deeddf   fdZ?dee/   de=dee@   dee/   fdZA eB       ZCe=eDd<    G d d      ZEy)zAutoImport module for rope.    N)sha256)OrderedDict)FutureProcessPoolExecutoras_completed)datetime)chain)Path)local)	GeneratorIterableIteratorListOptionalSetTuple)
exceptionslibutilsresourceobserver
taskhandle
versioning)Project)Resource)models)
ModuleFileNameNameTypePackagePackageTypeSearchResultSource)	get_names)	get_filesget_modname_from_pathget_package_tuplesort_and_deduplicatesort_and_deduplicate_tuple)importutilspackages
underlinedjob_setreturnc              #     K   t               5 }| D ]W  }t        ||      D ]F  }|j                  |j                         |j	                          |j                  t        ||       H Y 	 ddd       y# 1 sw Y   yxY ww)zGet all names as futures.N)r   r#   started_jobmodname	incrementsubmitr"   )r)   r*   r+   executorpackagemodules         @/usr/lib/python3/dist-packages/rope/contrib/autoimport/sqlite.pyget_future_namesr6   +   s      
	 B( 	BG#GZ8 B##FNN3!!#ooiAAB	BB B Bs   B AA4+	B 4A=9B existingc                 j    |rdt         dt        ffd}ndt         dt        ffd}t        ||       S )z!Filter list of packages to parse.r3   r,   c                      | j                   vS Nnamer3   r7   s    r5   filter_packagez'filter_packages.<locals>.filter_package=   s    <<x//    c                 \    | j                   vxr | j                   j                  d       S )N_)r<   
startswithr=   s    r5   r>   z'filter_packages.<locals>.filter_packageB   s*    <<x/T8O8OPS8T4TTr?   )r   boolfilter)r)   r*   r7   r>   s     ` r5   filter_packagesrE   7   s@     	0G 	0 	0
	UG 	U 	U .(++r?   _deprecated_defaultc                   6   e Zd ZU dZej
                  ed<   eed<   eed<   e	ed<   eed<   dde
fded	ededefd
Zeddddee   dedej
                  fd       Zed        Zej"                  dej
                  fd       Zd ZdefdZdFdededeeeef      fdZ	 	 dGdededeee      deeddf   fdZ	 dFdededeeddf   fdZ	 dFdededeeddf   fdZdee   fdZdee   fdZdeee    ee	   f   fdZ!dde"jF                  fdeee$      ded e"jJ                  fd!Z&de"jF                  ddfd"eee      d e"jJ                  d#edee   fd$Z'd"ee   de(e	   fd%Z)d&efd'Z*d( Z+d) Z,d* Z-d+ Z.	 dHd,e$ded-efd.Z/d/ Z0d,e$d0e$fd1Z1dId-efd2Z2dee3   fd3Z4d4e3fd5Z5dee	   fd6Z6d7ee	   fd8Z7dee   fd9Z8d: Z9d;e:fd<Z;e<de de=fd=       Z>d;e?e    fd>Z@de fd?ZAd@edee	   fdAZB	 dFd,e$dedeCfdBZDdCeEj                  fdDZGdCeEj                  fdEZHy)J
AutoImportzA class for finding the module that provides a name.

    This class maintains a cache of global names in python modules.
    Note that this cache is not accurate and might be out of date.

    
connectionmemoryprojectproject_packager*   TFobservec                    || _         t        |j                  j                  |      }|J |j                  J || _        || _        || _        |t        u r!d| _        t        j                  dt               t               | _        | j                  ||      | _        | j!                          |rHt#        j$                  | j&                  | j(                  | j*                        }|j-                  |       yy)a  Construct an AutoImport object.

        Parameters
        ___________
        project : rope.base.project.Project
            the project to use for project imports
        observe : bool
            if true, listen for project changes and update the cache.
        underlined : bool
            If `underlined` is `True`, underlined names are cached, too.
        memory:
            If true, don't persist to disk

            DEPRECATION NOTICE: The default value will change to use an on-disk
            database by default in the future. If you want to use an in-memory
            database, you need to pass `memory=True` explicitly:

                autoimport = AutoImport(..., memory=True)
        NTzThe default value for `AutoImport(memory)` argument will change to use an on-disk database by default in the future. If you want to use an in-memory database, you need to pass `AutoImport(memory=True)` explicitly.rK   rJ   )changedmovedremoved)rK   r%   rootpathlibpathrL   r*   rJ   rF   warningswarnDeprecationWarningr   thread_localcreate_database_connectionrI   	_setup_dbr   ResourceObserver_changed_moved_removedadd_observer)selfrK   rM   r*   rJ   rL   observers          r5   __init__zAutoImport.__init__Y   s    4 +GLL,@,@'J***##///.$((DKMM8 # "G99 : 
 	'88T[[$--H   *	 r?   NrO   r,   c                   dt         dt         fd}|s|t        d      |s||j                  m|t        j                         }n;|j                   ||j
                        }n ||j                  j                        }t        j                  d| dd      S t        j                  |j                  j                  d	z        S )
z
        Create an sqlite3 connection

        project : rope.base.project.Project
            the project to use for project imports
        memory : bool
            if true, don't persist to disk
        datar,   c                 P    t        | j                               j                         S r:   )r   encode	hexdigest)re   s    r5   calculate_project_hashzEAutoImport.create_database_connection.<locals>.calculate_project_hash   s    $++-(2244r?   z)if memory=False, project must be providedz
file:rope-z:?mode=memory&cache=sharedT)urizautoimport.db)
str	Exception
ropefoldersecrets	token_hexaddress	real_pathsqlite3connectrT   )clsrK   rJ   ri   project_hashs        r5   rZ   z%AutoImport.create_database_connection   s     	5 	5 	5 '/GHHW_(:(:(B &002##+5gooF5g6H6H6R6RS??\N*DE4  ??7#5#5#=#=#OPPr?   c                     t        | j                  d      s6| j                  | j                  | j                        | j                  _        | j                  j
                  S )z
        Creates a new connection if called from a new thread.

        This makes sure AutoImport can be shared across threads.
        rI   rO   )hasattrrY   rZ   rK   rJ   rI   ra   s    r5   rI   zAutoImport.connection   sU     t((,7+/+J+J{{ ,K ,D(   +++r?   valuec                 &    || j                   _        y r:   )rY   rI   )ra   ry   s     r5   rI   zAutoImport.connection   s    ',$r?   c                 R   t         j                  j                  | j                         t	        | j                  t         j                  j                  j                  d                  }t        j                  | j                        }|r|d   d   |k7  r| j                          y y )Nversion_hashr   )r   Metadatacreate_tablerI   list_executeobjectsselectr   calculate_version_hashrK   clear_cache)ra   r|   current_version_hashs      r5   r[   zAutoImport._setup_db   s    $$T__5MM&//1188HI
  *@@N|Aq15II  Jr?   startingc                     | j                  t        j                  j                  j	                  ddd      |f      j                         }t        |      S )aa  
        Find modules that have a global name that starts with `starting`.

        For a more complete list, use the search or search_full methods.

        Parameters
        __________
        starting : str
            what all the names should start with
        Return
        __________
        Return a list of ``(name, module)`` tuples
        r<   r4   source)r   r   r   import_assistr   fetchallr'   )ra   r   resultss      r5   r   zAutoImport.import_assist   sN     --KK%%,,VXxH8+

(* 	 *
 	
r?   r<   exact_matchc           
          | j                  ||      D cg c]  \  }}}}|||f }}}}}t        |      S c c}}}}w )z
        Search both modules and names for an import string.

        This is a simple wrapper around search_full with basic sorting based on Source.

        Returns a sorted list of import statement, modname pairs
        )search_fullr'   )ra   r<   r   	statementimport_namer   typer   s           r5   searchzAutoImport.search   sW     9=8H8Hk9/
 /
4	; V,/
 /
 *'22/
s   9
ignored_namesc              #      K   |
t               }t        | j                  ||            }|j                  | j                  ||            }|D ]  }|j                  |vs|  yw)a  
        Search both modules and names for an import string.

        Parameters
        __________
        name: str
            Name to search for
        exact_match: bool
            If using exact_match, only search for that name.
            Otherwise, search for any name starting with that name.
        ignored_names : Set[str]
            Will ignore any names in this set

        Return
        __________
        Unsorted Generator of SearchResults. Each is guaranteed to be unique.
        N)set_search_nameunion_search_moduler<   )ra   r<   r   r   r   results         r5   r   zAutoImport.search_full   sg     .  EMd''k:;-- 3 3D+ FG 	F{{-/	s   AA&A&c              #      K   |s|dz   }| j                  t        j                  j                  j	                  dddd      |f      D ]  \  }}}}t        d| d| |||        yw)	z
        Search both names for available imports.

        Returns the import statement, import name, source, and type.
        %r<   r4   r   r   from  import N)r   r   r   search_by_name_liker   r    )ra   r<   r   r   r4   r   	name_types          r5   r   zAutoImport._search_name  s      #:D6:mmKK++2268XvVG7
 	2K
 F88K=9			s   A&A(c              #   @  K   |s|dz   }| j                  t        j                  j                  j	                  dd      |f      D ]b  \  }}|j                  d      }|d   }|d   }|dd D ]  }|dz  }||z  } t        d| d	| ||t        j                  j                         d | j                  t        j                  j                  j	                  dd      |f      D ]5  \  }}d|v rt        d
| ||t        j                  j                         7 yw)z
        Search both modules for available imports.

        Returns the import statement, import name, source, and type.
        r   r4   r   .r      r   r   zimport N)r   r   r   search_submodule_liker   splitr    r   Modulery   search_module_like)	ra   r<   r   r4   r   partsr   	remainingparts	            r5   r   zAutoImport._search_module*  s:     #:D"mmKK--44XxH4'
 	NFF LL%E)KaIa "S 	T!	" I;h{m<OO))		" #mmKK**11(HEw
 	NFF f}&"FFHOO4I4I 	s   DDc                     | j                  t        j                  j                  j	                  dd      |f      j                         }t        |      S )z0Get the list of modules that have global `name`.r4   r   )r   r   r   search_by_namer   r   r&   )ra   r<   r   s      r5   get_moduleszAutoImport.get_modulesN  sE    --KK&&--hAD7

(* 	 $G,,r?   c                     | j                  t        j                  j                  j	                  d            j                         S )z(Get the list of all cached global names.r<   )r   r   r   r   r   r   rx   s    r5   get_all_nameszAutoImport.get_all_namesU  s/    }}V[[0077?@IIKKr?   c                    | j                  t        j                  j                  j	                               j                         }| j                  t        j                  j                  j	                               j                         }||fS )zDump the entire database.)r   r   r   r   select_starr   r   )ra   name_resultspackage_resultss      r5   	_dump_allzAutoImport._dump_allY  sa    }}V[[%8%8%D%D%FGPPR--(>(>(J(J(LMVVX_,,r?   	resourcestask_handlec           	         || j                   j                         }|j                  dt        |            }| j	                  t
        j                  j                  | j                  j                  f       g }t               5 }|D ]b  }|j                  d|j                          | j                  ||      }|j                  |j                  t         || j                               d 	 ddd       t#        |      D ]1  }	| j%                  |	j'                                |j)                          3 | j*                  j-                          y# 1 sw Y   cxY w)zGenerate global name cache for project files.

        If `resources` is a list of `rope.base.resource.File`, only
        those files are searched; otherwise all python modules in the
        project are cached.
        NGenerating autoimport cachezWorking on )rK   get_python_filescreate_jobsetlenr   r   r   delete_by_package_namerL   r<   r   r.   rU   _resource_to_moduleappendr1   r"   r   
_add_namesr   finished_jobrI   commit)
ra   r   r*   r   r+   futuresr2   filer4   futures
             r5   generate_cachezAutoImport.generate_cache_  s*    557I++)3y>
 	NN11D4H4H4M4M3O	
  " 	Yh! Y##k$))$=>11$
Cxy&$BVBVWXY	Y
 #7+ 	#FOOFMMO,  "	# 	 	Y 	Ys   A(EEmodulessingle_threadc                    || j                   n|}|| j                         nt        | j                  |            }| j	                         }t        t        |||            }|sy| j                  |       |j                  dd      }|rf|D ]`  }t        ||      D ]O  }	|j                  |	j                         t        |	|      D ]#  }
| j                  |
       |j                          % Q b nJt        t        |||            D ]1  }| j!                  |j#                                |j                          3 | j$                  j'                          y)a}  
        Generate global name cache for external modules listed in `modules`.

        If no modules are provided, it will generate a cache for every module available.
        This method searches in your sys.path and configured python folders.
        Do not use this for generating your own project's internal names,
        use generate_resource_cache for that instead.
        Nr   r   )r*   _get_available_packagesr   _get_packages_from_modules_get_packages_from_cacherE   _add_packagesr   r#   r.   r/   r"   	_add_namer   r   r6   r   r   rI   r   )ra   r   r   r   r*   r)   r7   r+   r3   r4   r<   future_names               r5   generate_modules_cachez!AutoImport.generate_modules_cache~  sJ    )3(:T__

  ((*d55g>? 	 002*hGH8$++,I1M# /'< /F''7 )&' : /t,,,.///  , :w?  '  2 2 45$$&	' 	 r?   c              #   J   K   |D ]  }| j                  |      }||  y wr:   )_find_package_path)ra   r   r/   r3   s       r5   r   z%AutoImport._get_packages_from_modules  s2      	G--g6GM		s   !#r4   c                 J    | j                  |       | j                  |g       y)z<Update a module in the cache, or add it if it doesn't exist.N)_del_if_existr   )ra   r4   s     r5   update_modulezAutoImport.update_module  s     6"##VH-r?   c                 l    | j                   j                          | j                   j                          y)zClose the autoimport database.N)rI   r   closerx   s    r5   r   zAutoImport.close  s"     r?   c                    g }| j                  t        j                  j                  j	                  d      |f      j                         }|D ]  }t        j                  t        j                        5  |d   }|j                  | j                  j                   d      r dj                  |j                  d            }| j                  j!                  |      }||v rO||   }|j#                         \  }}|5|j!                         j%                         }	|	||j'                  |	|f       ddd        |S # 1 sw Y   xY w)z/Return a list of ``(resource, lineno)`` tuples.r4   r   r   N)r   r   r   r   r   r   
contextlibsuppressr   ModuleNotFoundErrorrB   rL   r<   joinr   rK   
get_moduleget_definition_locationget_resourcer   )
ra   r<   r   r   r4   module_namepymodulepynamelinenoresources
             r5   get_name_locationszAutoImport.get_name_locations  s5   --KK++228<tg

(* 	  	>F$$Z%C%CD >$Qi))T-A-A-F-F,Gq*IJ"%((;+<+<S+A"BK<<22;?8#%d^F%+%C%C%ENFF)#)#4#4#6#C#C#E#/F4F"MM8V*<=> >	> > >s   3B<D;;E	c                 P   | j                   5  | j                  t        j                  j                  j                                | j                  t        j                  j                  j                                | j                  t        j                  j                  j                                t        j                  j                  | j                          t        j                  j                  | j                          t        j                  j                  | j                          t        j                  | j                        t        j                  t        j                  | j                              t        j                          j#                         f}t        j                  j$                  g dk(  sJ | j                  t        j                  j                  j'                         |       | j                   j)                          ddd       y# 1 sw Y   yxY w)zClear all entries in global-name cache.

        It might be a good idea to use this function before
        regenerating global names.

        )r|   	hash_data
created_atN)rI   r   r   r   r   
drop_tabler   r}   r~   r   r   rK   jsondumpsget_version_hash_datar   utcnow	isoformatcolumnsinsert_intor   )ra   re   s     r5   r   zAutoImport.clear_cache  s\    __ 	%MM&++--88:;MM&..00;;=>MM&//11<<>?KK$$T__5NN''8OO((911$,,?

:;;DLLIJ!++-D
 ??** /   
 MM&//11==?FOO""$'	% 	% 	%s   HHH%c                    t        j                  d|      }||d|j                          }	 t        j                  | j
                  |      }d}t        j                  |dff      }t        j                  | j
                  |      }|j                  |       |j                         }|j                  |      }|j                  dd|      dz   }|S # t        j                  $ r Y yw xY w)z5Guess at what line the new import should be inserted.z^(def|class)\s+Nr   __rope_testmodule_rope
r   )rer   startr   get_string_modulerK   r   ModuleSyntaxErrorr(   NormalImportget_module_imports
add_importget_changed_sourceindexcount)	ra   codematchr   testmodname
importinfomodule_importsoffsetr   s	            r5   find_insertion_linezAutoImport.find_insertion_line  s    		,d3%++-(D	11$,,EH / --T/B.DE
$77hO!!*-002K(D!V,q0 ++ 		s    C C'&C'r   r   c                    |r|n| j                   }| j                  ||      }| j                  |j                  d       t	        || j
                        D ]  }| j                  |        |r| j                  j                          yy)z0Update the cache for global names in `resource`.F)r   r   N)	r*   r   r   r/   r"   rL   r   rI   r   )ra   r   r*   r   r4   r<   s         r5   update_resourcezAutoImport.update_resource  sz     $.Z4??
))(J?v~~eDfd&:&:; 	!DNN4 	!OO""$ r?   c                 H    |j                         s| j                  |       y y r:   )	is_folderr  )ra   r   s     r5   r]   zAutoImport._changed  s!    !!#  * $r?   newresourcec                     |j                         s>| j                  |      j                  }| j                  |       | j	                  |       y y r:   )r  r   r/   r   r  )ra   r   r  r/   s       r5   r^   zAutoImport._moved  sE    !!#..x8@@Gw'  - $r?   c                     | j                  t        j                  j                  |f       |r| j                  j                          y y r:   )r   r   r   delete_by_module_namerI   r   )ra   r   r   s      r5   r   zAutoImport._del_if_exist  s4    fkk77+HOO""$ r?   c                     dt         dt        fd}| j                  j                         }t	        |t        t         |            }t        t        j                  |            S )Nfolderr,   c                 L    | j                         xr | j                         dk7  S )Nz/usr/bin)is_diras_posix)r  s    r5   filter_foldersz6AutoImport._get_python_folders.<locals>.filter_folders  s    ==?Fv'8J'FFr?   )	r
   rC   rK   get_python_path_foldersrD   mapr   r   fromkeys)ra   r  foldersfolder_pathss       r5   _get_python_folderszAutoImport._get_python_folders  sU    	G4 	GD 	G ,,668nc$.@AK((677r?   r  c              #   |   K   |j                         }	 	 t        |       # t        $ r Y t        $ r Y y w xY wwr:   )iterdirnextPermissionErrorStopIteration)ra   r  dirss      r5   _safe_iterdirzAutoImport._safe_iterdir"  sG     ~~4j   #   s$   <# <	9<9<9<c           	      D   t         j                  D cg c],  }t        |t        j                  d t
        j                        . }}| j                         D ]B  }| j                  |      D ],  }t        || j                        }||j                  |       . D |S c c}w r:   )sysbuiltin_module_namesr   r!   BUILTINr   r  r  r%   rK   r   )ra   r4   r)   r  r3   package_tuples         r5   r   z"AutoImport._get_available_packages,  s     22#
 FFNND+2E2EF#
 #
 ..0 	/F--f5 / 1'4<< H (.	/	/ #
s   1Br)   c                     |D cg c]#  }|j                   t        |j                        f% }}| j                  t        j
                  j                  j                         |       y c c}w r:   )r<   rk   rU   _executemanyr   r   r   r   )ra   r)   pre   s       r5   r   zAutoImport._add_packages9  sN    /78!QVV%88&..00<<>E 9s   (A(c                     t        t        | j                  t        j                  j
                  j                               j                                }|j                  | j                  j                         |S r:   )r   r	   r   r   r   r   r   r   r   rL   r<   )ra   r7   s     r5   r   z#AutoImport._get_packages_from_cache=  sX    "4==!7!7!C!C!EFOOQR
 	,,112r?   c                 ~    |j                         s-| j                  |      j                  }| j                  |       y y r:   )r  r   r/   r   )ra   r   r/   s      r5   r_   zAutoImport._removedD  s7    !!#..x8@@Gw' $r?   namesc                 B    | j                  |j                                y r:   )r   r   )ra   r)  s     r5   _add_future_nameszAutoImport._add_future_namesI  s    'r?   c                     | j                   | j                  | j                  | j                  j                  | j
                  j                  fS r:   )r<   r/   r3   r   ry   r   r;   s    r5   _convert_namezAutoImport._convert_nameL  s=     IILLLLKKNN  
 	
r?   c           	          |V| j                  t        j                  j                  j	                         |D cg c]  }| j                  |       c}       y y c c}w r:   )r%  r   r   r   r   r-  )ra   r)  r<   s      r5   r   zAutoImport._add_namesV  sO    ##//16;<d##D)<  =s   A
c                     | j                  t        j                  j                  j	                         | j                  |             y r:   )r   r   r   r   r   r-  )ra   r<   s     r5   r   zAutoImport._add_name]  s.    fkk))5579K9KD9QRr?   target_namec                 (   |t         j                  v r*t        |t        j                  d t
        j                        S | j                         D ]C  }| j                  |      D ]-  }t        || j                        }||\  }}}}||k(  s)|c c S  E y r:   )
r   r!  r   r!   r"  r   r  r  r%   rK   )	ra   r0  r  r3   r#  r<   r   package_pathpackage_types	            r5   r   zAutoImport._find_package_path`  s    #222;k>Q>QRR..0 	)F--f5 ) 1'4<< H (;H8flL;&(()	) r?   c                     | j                   j                  sJ |r|n| j                  }|j                  }t	        || j                   j                  d      }t        ||||j                  dk(        S )NF)add_package_namez__init__.py)rL   rU   r*   rT   r$   r   r<   )ra   r   r*   resource_pathresource_modnames        r5   r   zAutoImport._resource_to_modulen  sw     ##((((#-Z4??
&.. !64//44u!
 -/	
 	
r?   queryc                     t        |t        j                        sJ  | j                  j                  |j
                  g|i |S r:   )
isinstancer   
FinalQueryrI   execute_queryra   r8  argskwargss       r5   r   zAutoImport._execute  s=    %!2!2333&t&&u||EdEfEEr?   c                     t        |t        j                        sJ  | j                  j                  |j
                  g|i |S r:   )r:  r   r;  rI   executemanyr=  r>  s       r5   r%  zAutoImport._executemany  s=    %!2!2333*t**5<<I$I&IIr?   )F)FN)FT)T)I__name__
__module____qualname____doc__rr   
Connection__annotations__rC   r   r   rF   rc   classmethodr   rZ   propertyrI   setterr[   rk   r   r   r   r   r   r   r    r   r   r   r   r   r   r   r   DEFAULT_TASK_HANDLEr   BaseTaskHandler   r   r   r   r   r   r   r   r  r  r]   r^   r   r
   r  r  r   r   r   r_   r   r+  staticmethodtupler-  r   r   r   r   r   r   r   r;  r   r%   r?   r5   rH   rH   K   s!    """L
  *4+4+ 4+ 	4+
 4+l  &*	"Q '""Q 	"Q
 
		"Q "QH , , - 2 2 - -
c 
*33 3T 3d5c?>S 3& ",0	   C)	
 
<t+	,@ .3&*	<t+	,0 .3""&*"	<t+	,"H-49 -LtCy L-5dT']!:; - /3 1;1O1O	!DN+! !  ..	!B (,1;1O1O#%)+!$s)$+!  ..+! 	+!
 TN+!Z$s) @Q .C .
 
*%8& LP
% 
%.2
%DH
%+.x .h .% %
8T$Z 8D g Fd7m F$s) (
(v ( 
D 
U 
 
 Sd Sc hw6G  6;
 
.2
	
&Ff// FJ&"3"3 Jr?   rH   )FrF  r   r   hashlibr   rn   r   rr   r   rV   collectionsr   concurrent.futuresr   r   r   r   	itertoolsr	   rT   r
   	threadingr   typingr   r   r   r   r   r   r   	rope.baser   r   r   r   r   rope.base.projectr   rope.base.resourcesr   rope.contrib.autoimportr   rope.contrib.autoimport.defsr   r   r   r   r   r    r!   rope.contrib.autoimport.parser"   rope.contrib.autoimport.utilsr#   r$   r%   r&   r'   rope.refactorr(   rC   
BaseJobSetr6   rk   rE   objectrF   rH  rH   rP  r?   r5   <module>ra     s    !     	  
  # H H     L L L T T % ( *   4  &	B7m	B)-	B8B8M8M	BvtT!"	B,w,-1,=A#Y,g," #H T $|J |Jr?   