
    N j_                    n   S SK Jr  S SKrS SKJrJrJr  S SKrS SKJ	r	  S SKJ
r
  S SKJr  \(       a
  S SKJrJrJr  SS jr      SS jr        SS	 jr    SS
 jr    SS jr S          S!S jjr        S"S jr S          S#S jjr  S$           S%S jjr    S&S jr    S'S jr " S S\	R8                  5      r " S S\	R8                  5      r S      S(S jjr S      S)S jjr     S*S jr!    S+S jr"  S,       S-S jjr#  S,       S.S jjr$g)/    )annotationsN)AnyNoReturnTYPE_CHECKING)Tensor)NamedMemberAccessor)CallableIterableSequencec                     [        S5      e)Na$  make_functional(module): we don't yet support models that do parameter tying (also sometimes known as weight sharing). Please try to rewrite your model by replacing all instances of the tied parameter with another and/or comment your support in https://github.com/pytorch/functorch/issues/446)RuntimeError     q/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/torch/_functorch/make_functional.pyraise_parameter_tying_errorr      s    
	: r   c                   [        U 5      n[        U5      n[        UR                  5       5      n[        UR                  5       5      nUR                  U5      (       d  [	        SU SU 35      e0 nUR                  5        H  u  pxU/ 4Xh'   M     UR                  5        H/  u  pxX;  a  [	        SU S35      eXh   S   R                  U5        M1     [        UR                  5       5      $ )aC  
named_params is a dictionary of tensors: {'A': A, 'B': B}
tied_named_params is another dictionary of tensors {'A': A, 'B': B, 'B_tied': B}
with potentially tied (or 'duplicated') tensors

This function creates a mapping from the names in named_params to the
names in tied_named_params: {'A': ['A'], 'B': ['B', 'B_tied']}.
ztensors_dict_keys z+ is not a subset of tied_tensors_dict_keys ztensor for key 'z ' not found in tensor_to_mapping   )dictsetkeysissubsetAssertionErroritemsappendvalues)	named_paramstied_named_paramsnamed_params_dicttied_named_params_dicttensors_dict_keystied_tensors_dict_keystensor_to_mappingkeytensors	            r   create_names_mapr%   $   s    \*!"34-2245 !7!<!<!>?%%&<== !2 3 4&&<%=?
 	

 >@(..0%("I! 1-335* "3%'GH  	!!$++C0 6 !((*++r   c                6   [        U" SS95      n[        U" SS95      n[        XC5      n0 n[        U 5      nU H<  u  pX;  a  U" [        R                  " U	SS95      Xi'   Xi   n
UR                  X5        M>     [        U5      S:X  a  Su  pO
[        U6 u  pXU4$ )NF)remove_duplicateTmeta)devicer   r   r   )tupler%   r   torch
empty_like
set_tensorlenzip)modnamed_memberssubclassall_named_membersunique_named_members	names_mapmemoaccessornamepreplacementnamesparamss                r   _extract_membersr>   G   s    
 mUCD !EF !5II D"3'H$=u//&ABDGgD.	 %  A%v12)##r   c                J    [        X R                  [        R                  5      $ )a>  
This function removes all the Parameters from the model and
return them as a tuple as well as their original attribute names.
The weights must be re-loaded with `load_weights` before the model
can be used again.
Note that this function modifies the model in place and after this
call, mod.parameters() will be empty.
)r>   named_parametersnn	Parameterr1   s    r   extract_weightsrD   a   s     C!5!5r||DDr   c                0    [        X R                  S 5      $ )Nc                    U $ Nr   )xs    r   <lambda>!extract_buffers.<locals>.<lambda>r   s    ar   )r>   named_buffersrC   s    r   extract_buffersrL   o   s     C!2!2K@@r   c                    [        U 5      nU(       a&  U Vs/ s H  n[        R                  " U5      PM     nnUR                  X5        gs  snf )z
Reload a set of weights so that `mod` can be used again to perform a forward pass.
Note that the `params` are regular Tensors (that can have history) and so are left
as Tensors. This means that mod.parameters() will still be empty after this call.
N)r   rA   rB   set_tensors)r1   r<   r=   	as_paramsr8   r:   s         r   load_weightsrP   u   s@     #3'H+126a",,q/62' 3s    Ac                   / n[        U 5      n[        UR                  5       U5       HU  u  u  pVn[        U5       H>  u  pUS:X  a"  UR	                  UR                  X5      5        M-  UR                  X5        M@     MW     U$ )Nr   )r   r0   r   	enumerater   swap_tensorr.   )
r1   r6   elemsresultr8   _
attr_nameselemi	attr_names
             r   _swap_stater[      sv     F"3'H!$Y__%6!>%j1LAAvh229CD##I4	 2 "? Mr   c                <    [        U 5      nUR                  X5        g rG   )r   rN   )r1   r<   buffersrO   r8   s        r   load_buffersr^      s     #3'H(r   c                @   [        U5      [        U5      :w  a#  [        S[        U5       S[        U5       35      e[        XU5        [        U5      S:  aG  [        U5      [        U5      :w  a#  [        S[        U5       S[        U5       35      e[        XU5        U $ )zload_state(model, weights, weight_names, buffers=(), buffer_names=()) -> model

load_state takes `weights` and `buffers` and assigns them to the model.
This is the inverse operation of `make_functional_deprecated_v1`.
zlen(weight_names)=z != len(weights)=r   zlen(buffer_names)=z != len(buffers)=)r/   r   rP   r^   )modelweightsweight_namesr]   buffer_namess        r   
load_staterd      s     <CL( \!2 33DS\NS
 	
 g.
7|a|G, $S%6$77HWW  	U'2Lr   c                   ^ ^ [        T R                  5       5      n[        U5      S:  a  [        S5      e[	        T 5      u  nmnSUU 4S jjnX$T4$ )a  make_functional_deprecated_v1(model) -> weights, func, weight_names

Given an nn.Module, make_functional_deprecated_v1 extracts the state (weights)
and returns a functional version of the model, `func`. This makes
it so that it is possible use transforms over the parameters of
`model`.

`func` can be invoked as follows:
```
x = torch.randn(4, 3)
model = nn.Linear(3, 3)
weights, func, _ = make_functional_deprecated_v1(model)
func(weights, (x,))
```

And here is an example of applying the grad transform:
```
x = torch.randn(4, 3)
model = nn.Linear(3, 3)
weights, _, func = make_functional_deprecated_v1(model)
grad_weights = grad(func)(weights, (x,))
```

To put the state back into a model, use `load_state`.
r   zmake_functional_deprecated_v1(model): `model` has buffers. Please use make_functional_with_buffers_deprecated_v1(model) instead.c                T   > [         R                  " T5      n[        UTU 5        U" U6 $ rG   )copydeepcopyrP   )ra   datamutable_modeldescriptorsr`   s      r   fun*make_functional_deprecated_v1.<locals>.fun   s(    e,]K9d##r   )ra   tuple[Tensor, ...]ri   tuple[Any, ...]returnr   )listr]   r/   r   rD   )r`   r]   ra   rV   rl   rk   s   `    @r   make_functional_deprecated_v1rr      s^    8 5==?#G
7|aI
 	
 .e4G[!$ $
 $$r   c                t   ^ ^^ [        T 5      u  nmn[        T 5      u  nmn        SUU U4S jjnXUTT4$ )a  make_functional_with_buffers_deprecated_v1(model) -> weights, buffers, func, weight_names, buffer_names

Given an nn.Module, make_functional_with_buffers_deprecated_v1 extracts the state (weights and buffers)
and returns a functional version of the model, `func`.

`func` can be invoked as follows:
```
x = torch.randn(4, 3)
model = nn.Linear(3, 3)
weights, buffers, func, _, _ = make_functional_with_buffers_deprecated_v1(model)
func(weights, buffers, (x,))
```

And here is an example of applying the grad transform:
```
x = torch.randn(4, 3)
model = nn.Linear(3, 3)
weights, buffers, func, _, _ = make_functional_with_buffers_deprecated_v1(model)
func(weights, buffers, (x,))
grad_weights = grad(func)(weights, buffers, (x,))
```

To put the state back into a model, use `load_state`.
c                n   > [         R                  " T5      n[        UTU 5        [        UTU5        U" U6 $ rG   )rg   rh   rP   r^   )ra   r]   ri   rj   buf_descriptorsr`   weight_descriptorss       r   rl   7make_functional_with_buffers_deprecated_v1.<locals>.fun  s7    
 e,]$6@]OW=d##r   )ra   rn   r]   rn   ri   ro   rp   r   )rD   rL   )r`   ra   rV   r]   rl   ru   rv   s   `    @@r   *make_functional_with_buffers_deprecated_v1rx      si    B &5U%;"G"1%"8G_a$#$#$ $ 
	$ $ S"4oEEr   c                     ^  \ rS rSrSr            SU 4S jjr\ S     S	S jj5       r          S
S jrSr	U =r
$ )FunctionalModuleWithBuffersi  zO
This is the callable object returned by :func:`make_functional_with_buffers`.
c                   > [         TU ]  5         Xl        X l        X0l        [        U5      U l        U R                  R                  U5        g rG   )super__init__stateless_modelparam_namesrc   r   all_names_mapupdate)selfr~   r   rc   param_names_mapbuffer_names_map	__class__s         r   r}   $FunctionalModuleWithBuffers.__init__  sD     	.&(!/2!!"23r   c                    [         R                  " U 5      n[        U5      u  p4n[        U5      u  pgnU(       a  U H  n	U	R	                  S5        M     [        X$XuU5      UU4$ NF)rg   rh   rD   rL   requires_grad_rz   )
r`   disable_autograd_tracking
model_copyr=   r   r   r]   rc   r   params
             r   _create_from(FunctionalModuleWithBuffers._create_from*  sp    
 ]]5)
/>z/J,_2A*2M//$$$U+   (HX 
 	
r   c                "   [        U R                  U R                  [        U5      [        U5      -   5      n U R                  " U0 UD6[        U R                  U R                  U5        $ ! [        U R                  U R                  U5        f = frG   )r[   r~   r   r+   )r   r=   r]   argskwargs	old_states         r   forward#FunctionalModuleWithBuffers.forward=  s|        &ME'N*
	
	M''88 ,,d.@.@)LK,,d.@.@)Ls   A+ +#B)r   rc   r   r~   )r~   	nn.Moduler   tuple[str, ...]rc   r   r   dict[str, list[str]]r   r   rp   NoneFr`   r   r   boolrp   Jtuple[FunctionalModuleWithBuffers, tuple[Tensor, ...], tuple[Tensor, ...]])
r=   Iterable[Tensor]r]   r   r   r   r   r   rp   r   __name__
__module____qualname____firstlineno____doc__r}   staticmethodr   r   __static_attributes____classcell__r   s   @r   rz   rz     s    4"4 %4 &	4
 .4 /4 
4  <A

59
	S
 
$M M "M 	M
 M 
M Mr   rz   c                  n   ^  \ rS rSrSr        SU 4S jjr\ S     S	S jj5       rS
S jrSr	U =r
$ )FunctionalModuleiQ  zB
This is the callable object returned by :func:`make_functional`.
c                F   > [         TU ]  5         Xl        X l        X0l        g rG   )r|   r}   r~   r   r6   )r   r~   r   r6   r   s       r   r}   FunctionalModule.__init__V  s!     	.&"r   c                    [         R                  " U 5      n[        U5      u  p4nU(       a  U H  nUR                  S5        M     [	        X$U5      U4$ r   )rg   rh   rD   r   r   )r`   r   r   r=   r   r6   r   s          r   r   FunctionalModule._create_froma  sN    
 ]]5)
)8)D&Y$$$U+  
CVKKr   c                    [        U R                  U R                  U5      n U R                  " U0 UD6[        U R                  U R                  U5        $ ! [        U R                  U R                  U5        f = frG   )r[   r~   r6   )r   r=   r   r   r   s        r   r   FunctionalModule.forwardm  sb     4 4dnnfM		I''88 ,,dnniHK,,dnniHs   A #A9)r6   r   r~   )r~   r   r   r   r6   r   rp   r   r   r`   r   r   r   rp   z+tuple[FunctionalModule, tuple[Tensor, ...]])r=   r   r   r   r   r   rp   r   r   r   s   @r   r   r   Q  ss    	#"	# %	# (		#
 
	# <A	L	L59	L	4	L 	LI Ir   r   c                    [        U R                  5       5      n[        U5      S:  a  [        S5      e[        R                  XS9$ )a  make_functional(model, disable_autograd_tracking=False) -> func, params

Given a ``torch.nn.Module``, :func:`make_functional` extracts the state
(params) and returns a functional version of the model, ``func``. This
makes it so that it is possible use transforms over the parameters of
``model``.

``func`` can be invoked as follows:

.. code-block:: python

    import torch
    import torch.nn as nn
    from functorch import make_functional

    x = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    func, params = make_functional(model)
    func(params, x)

And here is an example of applying the grad transform over the parameters
of a model.

.. code-block:: python

    import torch
    import torch.nn as nn
    from functorch import make_functional, grad

    x = torch.randn(4, 3)
    t = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    func, params = make_functional(model)


    def compute_loss(params, x, t):
        y = func(params, x)
        return nn.functional.mse_loss(y, t)


    grad_weights = grad(compute_loss)(params, x, t)

If the model has any buffers, please use :func:`make_functional_with_buffers` instead.

Args:
    model (torch.nn.Module): Input model.
    disable_autograd_tracking (bool): Flag to disable gradients tracking for output parameters.
        The returned params are unrelated to the set of params from the original model. If False (default),
        the params will have ``requires_grad=True`` on them (aka they will be trackable with regular
        PyTorch autograd), matching the requires_grad-ness of the params from the original model.
        Otherwise, the returned params will have ``requires_grad=False``. Default, False.
        If you plan on using regular PyTorch autograd (e.g., if you want to call ``.backward()`` or
        ``torch.autograd.grad()``, then set ``disable_autograd_tracking=False``.
        Otherwise, if you're only planning on using functorch's gradient transforms,
        then please set ``disable_autograd_tracking=True`` to avoid unnecessarily tracking
        history with PyTorch autograd.

r   zdmake_functional(model): `model` has buffers. Please use make_functional_with_buffers(model) instead.r   )rq   r]   r/   r   r   r   )r`   r   r]   s      r   make_functionalr   w  sP    z 5==?#G
7|a;
 	
 (( )  r   c                (    [         R                  XS9$ )a$  make_functional_with_buffers(model, disable_autograd_tracking=False) -> func, params, buffers

Given a ``torch.nn.Module``, make_functional_with_buffers extracts the
state (params and buffers) and returns a functional version of the model
``func`` that can be invoked like a function.

``func`` can be invoked as follows:

.. code-block:: python

    import torch
    import torch.nn as nn
    from functorch import make_functional_with_buffers

    x = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    func, params, buffers = make_functional_with_buffers(model)
    func(params, buffers, x)

And here is an example of applying the grad transform over the parameters
of a model:

.. code-block:: python

    import torch
    import torch.nn as nn
    from functorch import make_functional_with_buffers, grad

    x = torch.randn(4, 3)
    t = torch.randn(4, 3)
    model = nn.Linear(3, 3)
    func, params, buffers = make_functional_with_buffers(model)


    def compute_loss(params, buffers, x, t):
        y = func(params, buffers, x)
        return nn.functional.mse_loss(y, t)


    grad_weights = grad(compute_loss)(params, buffers, x, t)

Args:
    model (torch.nn.Module): Input model.
    disable_autograd_tracking (bool): Flag to disable gradients tracking for output parameters.
        The returned params are unrelated to the set of params from the original model. If False (default),
        the params will have ``requires_grad=True`` on them (aka they will be trackable with regular
        PyTorch autograd), matching the requires_grad-ness of the params from the original model.
        Otherwise, the returned params will have ``requires_grad=False``. Default, False.
        If you plan on using regular PyTorch autograd (e.g., if you want to call ``.backward()`` or
        ``torch.autograd.grad()``, then set ``disable_autograd_tracking=False``.
        Otherwise, if you're only planning on using functorch's gradient transforms,
        then please set ``disable_autograd_tracking=True`` to avoid unnecessarily tracking
        history with PyTorch autograd.

r   )rz   r   )r`   r   s     r   make_functional_with_buffersr     s     t '33 4  r   c                L    [        [        U 6 5      n [        S U  5       5      nU$ )Nc              3  j   #    U  H)  n[         R                  " U5      R                  5       v   M+     g 7frG   r,   stackdetach.0shardss     r   	<genexpr>"transpose_stack.<locals>.<genexpr>  s)      3LF""$$3L   13)r+   r0   )tuple_of_tuple_of_tensorsresultss     r   transpose_stackr     s3     !&c+D&E F 3L G Nr   c                  ^ [        U 5      S:X  a  [        S5      e[        S U  5       5      (       d"  [        S U  5       5      (       d  [        S5      e[        U S   5      m[        U4S jU  5       5      (       d  [        S5      e[	        U  Vs/ s H  n[        U5      PM     sn6 u  p#n[        U5      n[        U5      nUS   X44$ s  snf )a  combine_state_for_ensemble(models) -> func, params, buffers

Prepares a list of torch.nn.Modules for ensembling with :func:`vmap`.

Given a list of ``M`` ``nn.Modules`` of the same class, stacks all of their
parameters and buffers together to make ``params`` and ``buffers``.
Each parameter and buffer in the result will have an additional dimension
of size ``M``.

:func:`combine_state_for_ensemble` also returns ``func``, a functional
version of one of the models in :attr:`models`. One cannot directly run
``func(params, buffers, *args, **kwargs)`` directly, you probably want to
use ``vmap(func, ...)(params, buffers, *args, **kwargs)``

Here's an example of how to ensemble over a very simple model:

.. code-block:: python

    num_models = 5
    batch_size = 64
    in_features, out_features = 3, 3
    models = [torch.nn.Linear(in_features, out_features) for i in range(num_models)]
    data = torch.randn(batch_size, 3)

    fmodel, params, buffers = combine_state_for_ensemble(models)
    output = vmap(fmodel, (0, 0, None))(params, buffers, data)

    assert output.shape == (num_models, batch_size, out_features)

.. warning::
    All of the modules being stacked together must be the same (except for
    the values of their parameters/buffers). For example, they should be in the
    same mode (training vs eval).

    This API is subject to change -- we're investigating better ways to
    create ensembles and would love your feedback how to improve this.
r   z?combine_state_for_ensemble: Expected at least one model, got 0.c              3  8   #    U  H  oR                   v   M     g 7frG   trainingr   ms     r   r   -combine_state_for_ensemble.<locals>.<genexpr>4  s     +Fq

Fs   c              3  B   #    U  H  oR                   (       + v   M     g 7frG   r   r   s     r   r   r   4  s     2R6azz>>6s   zTcombine_state_for_ensemble: Expected all models to have the same training/eval mode.c              3  >   >#    U  H  n[        U5      TL v   M     g 7frG   )type)r   r   
model0_typs     r   r   r   :  s     5ftAw*$fs   zHcombine_state_for_ensemble: Expected all models to be of the same class.)r/   r   allr   r0   r   r   )modelsr`   funcsr=   r]   r   s        @r   combine_state_for_ensembler     s    P 6{aM
 	
 +F+++s2R62R/R/R0
 	
 fQiJ5f555V
 	
 !;A	B6%
&u
-6	BE7 V$Fg&G8V$$	 
Cs   C
c                ,   ^ ^^       SUUU 4S jjnU$ )Nc                   >^ ^ [        T
5      S:  a  [        S5      e[        T
5      S:X  a"  T" T 0 TD6R                  T	5      n[        U5      $ T
S   nUS::  a  [        SU S35      e[	        U U	UU4S j[        U5       5       5      n[        T" T 0 TD65      u  pVn[	        S U 5       5      n[	        [        U6 5      n[	        S U 5       5      nXU4$ )	N   ,NYI: ensemble_shape with more than 1 elementr   num_models  should be > 0c              3  R   >#    U  H  nT" T0 TD6R                  T5      v   M     g 7frG   tor   rV   r   r)   r   model_classs     r   r   3functional_init.<locals>.wrapped.<locals>.<genexpr>W  -      
=NK((++F33=N   $'c              3  >   #    U  H  n[        U5      S    v   M     g7f)r   N)rr   r   r`   s     r   r   r   [  s     TVE5e<Q?V   c              3  j   #    U  H)  n[         R                  " U5      R                  5       v   M+     g 7frG   r   r   s     r   r   r   ]  %     K7F+22447r   )r/   
ValueErrorr   rr   r+   ranger0   )r   r   r`   
num_modelsr   rV   fnr<   ra   r)   ensemble_shaper   s   ``       r   wrapped functional_init.<locals>.wrappedK  s     ~!#KLL~!#0033F;E077#A&
?{:,nEFF 
=B:=N
 
 5[$5Q&5QRuTVTTW&K7KKE!!r   )r   r   r   r   rp   >tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]r   r   r   r)   r   s   ``` r   functional_initr   F  s,    
""!"	G" "* Nr   c                ,   ^ ^^       SUUU 4S jjnU$ )Nc                   >^ ^ [        T5      S:  a  [        S5      e[        T5      S:X  a"  T" T 0 TD6R                  T5      n[        U5      $ TS   nUS::  a  [        SU S35      e[	        U UUU4S j[        U5       5       5      n[        T" T 0 TD65      u  nnnnn[        [	        S U 5       5      6 u  p[	        [        U	6 5      n	[	        S U	 5       5      n	[	        [        U
6 5      n
[	        S	 U
 5       5      n
XXgU4$ )
Nr   r   r   r   r   c              3  R   >#    U  H  nT" T0 TD6R                  T5      v   M     g 7frG   r   r   s     r   r   @functional_init_with_buffers.<locals>.wrapped.<locals>.<genexpr>  r   r   c              3  >   #    U  H  n[        U5      S S v   M     g 7f)Nr   )rx   r   s     r   r   r     s#      #E ;5A"1E#r   c              3  j   #    U  H)  n[         R                  " U5      R                  5       v   M+     g 7frG   r   r   s     r   r   r     r   r   c              3  j   #    U  H)  n[         R                  " U5      R                  5       v   M+     g 7frG   r   r   s     r   r   r     r   r   )r/   r   r   rr   r+   r   rx   r0   )r   r   r`   r   r   rV   r   rb   rc   ra   r]   r)   r   r   s   ``         r   r   -functional_init_with_buffers.<locals>.wrappedr  s&    ~!#KLL~!#0033F;E077#A&
?{:,nEFF 
=B:=N
 
 7{D7SF7ST	
 # 
 W&K7KKW&K7KK<??r   )r   r   r   r   rp   ztuple[tuple[Tensor, ...], tuple[Tensor, ...], Callable[..., Any], tuple[str, ...], tuple[str, ...]] | tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]r   r   s   ``` r   functional_init_with_buffersr   c  s5    )@)@!)@	I)@ )@V Nr   )rp   r   )r   0dict[str, Tensor] | Iterable[tuple[str, Tensor]]r   r   rp   r   )r1   r   r2   z+Callable[..., Iterable[tuple[str, Tensor]]]r3   zCallable[[Tensor], Tensor]rp   @tuple[tuple[Tensor, ...], tuple[str, ...], dict[str, list[str]]])r1   r   rp   r   r   )
r1   r   r<   Sequence[str]r=   Sequence[Tensor]rO   r   rp   r   )r1   r   r6   r   rT   r   rp   zlist[Tensor])
r1   r   r<   r   r]   r   rO   r   rp   r   r*   )r`   r   ra   r   rb   r   r]   r   rc   r   rp   r   )r`   r   rp   r   )r`   r   rp   zctuple[tuple[Tensor, ...], tuple[Tensor, ...], Callable[..., Any], tuple[str, ...], tuple[str, ...]]r   r   )r   ztuple[tuple[Tensor, ...], ...]rp   rn   )r   zSequence[nn.Module]rp   r   )r   cpu)r   type[nn.Module]r   tuple[()] | tuple[int, ...]r)   torch.types.Devicerp   zMCallable[..., tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]])r   r   r   r   r)   r   rp   zCallable[..., tuple[tuple[Tensor, ...], tuple[Tensor, ...], Callable[..., Any], tuple[str, ...], tuple[str, ...]] | tuple[tuple[Tensor, ...], Callable[..., Any], tuple[str, ...]]])%
__future__r   rg   typingr   r   r   r,   torch.nnrA   r   %torch.nn.utils._named_member_accessorr   collections.abcr	   r
   r   r   r%   r>   rD   rL   rP   r[   r^   rd   rr   rx   Modulerz   r   r   r   r   r   r   r   r   r   r   <module>r     s   #  / /    E << ,B ,G ,  ,F$	$>$ )$ F	$4E	EEEA	AEA 	(	(( ( 	(
 
("	3<L$ 	)	)) ) 	)
 
) !#"$   	
   4)%)%C)%X.F.F.Fb9M")) 9Mx#Iryy #IN 9>EE15E0ER 9><<15<O<~=;%;%O;%@ 35!& /  S	> 35!&: :/: :
	:r   