
    qi                        d dl mZ d dlmZ d dlZd dlmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZmZ d	d
lmZmZmZ d	dlmZmZmZmZmZmZmZmZmZmZ dedede dz  fdZ!dededede de de de de de de"de"de dz  defdZ#dede$ee%e e f   f   de$ee%e e f   f   dede defdZ&deded ed!ed"ejN                  e(z  d#ejN                  e"z  d$e defd%Z)ded&edee*e   z  d'ed ed!ed(e ded)e$e e+e   f   dee*e   z  fd*Z,ded'ed ed!edef
d+Z-d,ed'ed-e"de.fd.Z/d/ee*e   z  d0ee*e   z  dz  d,ed'ed ed(e defd1Z0d/ee*e   z  d0ee*e   z  dz  ded'ed ed(e defd2Z1	 d8d3e d'ed4e d ed5e$e e%eef   f   ded6e.d)e$e e+e   f   dz  defd7Z2y)9    )Callable)AnyN)get_node_type_to_io_type_map)get_new_attr_name_with_prefix)_is_activation_post_process)GraphModulemap_arg)GraphNode   )NSNodeTargetTypeNSSingleResultValuesType
NSSubgraph)
 get_arg_indices_of_inputs_to_log$get_node_first_input_and_output_typeget_node_input_qparamsget_normalized_nth_inputget_number_of_non_param_argsget_target_type_strgetattr_from_fqnNodeInputOrOutputTypeop_type_supports_shadowingreturn_first_non_observer_nodenodegmreturnc                 N   d }t        |d      r| }| j                  dk(  rit        | j                  t              s!t        dt        | j                               t        || j                        }t        |      rt        | |d      }|j                  |j                     d   }|S )N_node_name_to_scopecall_moduleExpected str, got r   )hasattrop
isinstancetargetstrAssertionErrortyper   r   r   r   name)r   r   fqnnode_to_use_for_fqnmodules        a/home/ubuntu/crypto_trading_bot/.venv/lib/python3.12/site-packages/torch/ao/ns/fx/graph_passes.py_maybe_get_fqnr-      s    
Cr() #77m#dkk3/$'9$t{{:K9L%MNN%b$++6F*62&>tR&K#$$%8%=%=>qAJ    
logger_clslogger_node_name_suffixref_node_name
model_nameref_nameref_node_target_typeresults_typeindex_within_argindex_of_argr)   c                      t        | j                  |z         |      }t        | |      } ||| j                  ||||||	|
|
      }t        |||       | j                  j                  d|| fi       }|S )z
    Given a starting graph of

    prev_node -> node -> next_node

    This function creates a new logger_cls obj and adds it
    after node, resulting in

    prev_node -> node -> logger_obj -> next_node
    r   )r   r(   r   setattrgraphcreate_node)r   r   r/   r0   r1   r2   r3   r4   r5   r6   r7   r)   logger_node_nametarget_type
logger_objlogger_nodes                   r,   _insert_logger_after_noder@   ,   s    24		++
 &dB/K		J B *-**((8H4'SUVKr.   *node_to_instrument_inputs_to_ref_node_name+node_to_instrument_outputs_to_ref_node_namec                    t               }i fd}| j                  j                  D ]  }|j                  dk(  r'|j	                  t        t        || d      |             :||v s||v rt        ||       }||v r(||   \  }	}
t        |      }|D ]  }t        || |      }t        |      t        u rV|j                     }t        || |d|j                  ||	|
t        j                  j                  d||      |j                  <   xt        |      t         j"                  j$                  j&                  u st)        |      D ]Z  \  }}|j                     }t        || |d|j                  ||	|
t        j                  j                  |||      |j                  <   \  |j+                  ||      |j                  <   ||v s||   \  }	}
t        |j                     | |d|j                  ||	|
t        j,                  j                  dd|      |j                  <   |j+                  ||      |j                  <    t/        | |      }|S )z
    Takes the graph of gm, adds loggers to the output
    of each node in nodes_to_instrument. Returns a GraphModule with the new
    graph.
    c                 "    t        | fd      S )Nc                 "    | j                      S Nr(   )r   envs    r,   <lambda>z8add_loggers_to_model.<locals>.load_arg.<locals>.<lambda>m   s    s499~ r.   r	   )arH   s    r,   load_argz&add_loggers_to_model.<locals>.load_argl   s    q566r.   outputr   _ns_logger_r6   r7   r)   )r
   r:   nodesr"   rM   r	   r   r-   r   r'   r   r(   r@   r   
NODE_INPUTvaluetorchfximmutable_collectionsimmutable_list	enumerate	node_copyNODE_OUTPUTr   )r   rA   rB   r/   r2   	new_graphrL   r   r)   r3   ref_node_typearg_indices_to_lognode_arg_idxnode_arg	prev_nodearg_idxargnew_gmrH   s                     @r,   add_loggers_to_modelrc   \   sk    IC7  TA77hW%=dB%JHUV>>?? r*CAA*T+'- &Fd%K"$6 &L7b,OHH~-$'$6	-F%&) II&$)4??EE-.)5 #.HMM* X%((*H*H*W*WW -6h,? LGS(+CHHI2K ) " * - $		 * ( - 8 C C I I18-9$'3C	//&T '00x@C		NBB*U+'- ";		N!II!,88>>%&!""DII  '00x@C		NiTAl Y'FMr.   prev_node_cnode_agm_bgraph_cscale
zero_pointdtype_cast_namec                 l    t        |j                  dz         |      }t        |||       |j                  d|di |      } t        |j                  dz         |      }	t        ||	|       |j                  d|	di |	      }
|j                  dt        j
                  | ||
t        j                  fi |      S )N_input_scale_get_attr _input_zero_point_call_function)r   r(   r9   r;   rS   quantize_per_tensorquint8)rd   re   rf   rg   rh   ri   rj   scale_node_name
scale_nodezero_point_node_namezero_point_nodes              r,    _insert_quantize_per_tensor_noderw      s     S3FKK/4QRSWXOD/5)$$OR_J8**
 D&
3))("b2FO !!	j/5<<@
 r.   node_cgm_anode_name_prefixnode_type_to_io_type_mapc	           	         d}	d}
d}d}d}d}t        | |||      \  }}t        ||||      \  }}|t        j                  k(  r|t        j                  k(  sL|t        j                  k(  r|t        j                  k(  s&|t        j                  k(  r$|t        j
                  k(  rt        j                  }	n||k(  r.|t        j                  k7  rt        j                  j                  }
n|t        j                  k(  r8|t        j                  k(  r%t        | ||      }|t        j                  }	|\  }}np|t        j                  k(  r&|t        j                  k(  rd}t        j                  }n7t        d| d|j                          d| d| j                          dz         t!        |t"              r t%        |      |      }|	r+||t'        || |||||      S |j)                  d|	|fi |      S |r|j)                  d|||fi |      S |
st        d	       |
       }t+        |||       |j)                  d
||fi |      S t!        |t,              rg }|D ]  } t%        |      |      }|	r(|j)                  d|	|fi |      }|j/                  |       >|
st        d	       |
       }t+        |||       |j)                  d
||fi |      }|j/                  |        |S t        dt1        |       d      )a  
    Given a starting graph C (derived from graph B) of

    ... -> prev_node_c -> node_c -> ...

    And a corresponding related node_a, inserts the correct dtype
    cast node after prev_node_c to cast into the dtype expected
    by node_a, resulting in:

                          dtype_cast
                        /
    ... -> prev_node_c -> node_c -> ...

    For example, if node_c is an int8 op and node_a is an fp32 op, this function
    will insert a dequant.
    Ntozdtype cast from  z to z needs to be implementedrp   call_methodz*Expected dtype_cast_mod_cls to be not Noner   ztype fz is not handled)r   r   FP32INT8FP16FP32_OR_INT8rS   
dequantizeUNKNOWNnnIdentityr   rq   float16r&   format_noder#   r   r   rw   r;   r9   listappendr'   )re   rx   rd   ry   rf   rg   rz   r/   r{   dtype_cast_opdtype_cast_mod_clsdtype_cast_methoddtype_cast_method_dtypedtype_cast_scaledtype_cast_zero_pointnode_input_type_a_node_output_type_anode_input_type_c_node_output_type_cnode_a_input_qparamsnew_dtype_cast_namedtype_cast_modresultsprev_node_c_innernew_dtype_cast_nodes                            r,   _insert_dtype_cast_after_noder      s   6 M" -Qj":.** .Rj":.** !6!;!;;!%:%?%?? !6!;!;;!%:%?%?? !6!;!;;!%:%G%GG ((..!6!>!>>"XX..2777!6!;!;;  6D2 
  +!55M6J332777!6!;!;; "'--0163E3E3G2HM"#1V%7%7%9$::RST
 	

 +t$M;<LMdS+0E0Q7$)'  **#! N'  &&!56#  &$%QRR/1ND-~>&&##  
K	&!, 	4"Q"?@P"QRV"W&-&9&9#!&(''# 23)()UVV!3!51>B&-&9&9!'&(''# 231	42 vd;&7%8HIIr.   c           
         | j                   dk(  r t        | j                  dz         |      }t        || j                        }t        j                  |      r|j                         }t        |||       |j                  | j                   |di |      }|S | j                   dk(  r| j                  dvrt        d| j                   d      | j                  dk(  rct        t        | |d	      |||      } t        | j                  dz         |      }|j                  | j                   | j                  |fi |      }|S t        t        | |d	      |||      } t        | j                  dz         |      }|j                  | j                   | j                  |t        | |d
      fi |      }|S t        d| j                          d| j                    d      )z+
    Simple copy of node_a to graph_c.
    rm   _shadow_copy_rn   r   r   r}   ztarget  is not implementedr   r   r   zhandling of node z	 with op )r"   r   r(   r   r$   rS   	is_tensordetachr9   r;   r&   _copy_node_from_a_to_cr   r   )re   ry   rf   rg   node_a_copy_name
node_a_objnode_a_copyarg_copys           r,   r   r     s    yyJW89VW
 &dFMM:
??:&#**,J&
3))II'R1A
 	m	#== 44 76==/9L!MNN==L(-(q94wH <o-   "--		6==8+r;KK -(q94wH <o-   "--		3FD!DE K   2 2 45YvyykI\]
 	
r.   
subgraph_anum_non_param_args_node_ac                 `   g }| j                   }|| j                  k7  r.|j                  |       t        ||d      }|| j                  k7  r.|j                  |       |j	                          d }|D ]  }||d   u r|nd}|j                  |d      }||\  }	}
n|j                  |j                  }
}	d}|t        |	      k  r3|dk(  rn|dk(  r|dk(  rn ||	|   |      s y|dz  }|t        |	      k  r3|
j                         D ]$  }|dk(  rn|dk(  r|dk(  rn |||      s  y|dz  }&  y)z
    This function returns `False` if the input subgraph cannot be copied by
    `_insert_copy_of_subgraph_a_after_input_node_c`. This usually means
    that there is a corner case logic for which copy is not yet implemented.
    r   c                     t        | t              r:t        | |      }|j                  dk(  r|j                  dv S |j                  dk(  ryyt        | t
        t        f      r| D ]  }t        |t              r y y)Nr   r   rm   TF)r#   r   r   r"   r$   r   tuple)
node_a_argry   arg_aels       r,   _can_insertz3_can_insert_copy_of_subgraph_a.<locals>._can_insert  su    j$'2:tDExx=(||';;;Z'
T5M2  !!"d+ ! r.   r   Tnormalize_to_only_use_kwargs   F)
end_node
start_noder   r   reversenormalized_argumentsargskwargslenvalues)r   ry   r   rP   cur_noder   re   local_num_non_param_args_node_anorm_args_kwargs	norm_argsnorm_kwargscur_idx	kwarg_vals                r,   _can_insert_copy_of_subgraph_ar     sw    E""H
j++
+X+HdA> j++
+ 
LL	MMO"  ")/58);% 	( "66t 7 
 '%5"I{%+[[&--{II&!|A"AQ"F"9W#5t< qLG I& %++- 		I!|A"AQ"F"9d3 qLG		3"H r.   input_node_cinput_node_c_2c           	         t        | t        t        f      st        dt	        |              |j
                  g}|j
                  }||j                  k7  r/t        ||d      }|j                  d|       ||j                  k7  r/|d   }t        | |||||      }	t        dt        |            D ]  }
||
   }|	}t        |d||||      }	 |	S )z*
    TODO(before land): real docblock
    zExpected Node or list, got r   r   N)r#   r   r   r&   r'   r   r   r   insert)_insert_copy_of_node_a_after_input_node_cranger   )r   r   r   ry   rf   rz   
nodes_of_ar   
cur_node_a
cur_node_c	cur_idx_ard   s               r,   -_insert_copy_of_subgraph_a_after_input_node_cr     s     lT4L1:4;M:NOPP %%&J""H
j++
++HdA>!X& j++
+ AJ:nj$>NJ 1c*o. 
		*
 >


 r.   c                 j   t        | t              r| j                  n6t        | t              st	        dt        |              | d   j                  |j                  d      }||\  }}n|j                  |j                  }}g }	i }
fd}d}|t        |      k  rB|dk(  r| }n|dk(  r||}n |||         }|	j                  |       |dz  }|t        |      k  rB|j                         D ]-  \  }|dk(  r| |
|<   n|dk(  r|||
|<   n |      |
|<   |dz  }/ t        |	      }	 t        |            }|j                  dk(  r t        |            }t        |j                  t               s!t	        dt        |j                               t#        |j                        }t%        ||       j'                  |j                  ||	|
|      }|S |j                  d	vrt	        d
|j                         j'                  |j                  |j                  |	|
|      }|S )a  
    Assume that node_a from graph_a has
      args (input, (input2)?, arg1, ...), and
      kwargs {kw0: kwarg0, ...}

    Note: input2 is optional. If it equals to None, we assume that the op
    has a single non-param input.  If it is specified, we assume that the op
    has two non-param inputs.

    Copies the underlying values of arg1..argn and kwarg0..kwargn into gm_b,
    and creates the corresponding nodes in graph_c. Note: observers are ignored,
    so if an arg is an observer we navigate up until we find a non-observer parent.

    If node_a is a call_module, points the module pointed to by node_a to gm_b.

    Creates the copy of node_a in graph_c, with input as the first arg,
    and all other args and kwargs pointing to the copies of the objects
    in gm_b created above.

    An example in pictures:

    graph A:
    ========

    input -------------> node_a
                         / / /
    (input_2)?----------/ / /
                         / /
    weight -> weight_obs  /
                         /
    bias ----------------

    graph C (derived from B):
    =========================

    input_node_c --> node_a_copy
                     / / /
    (input_node_c_2)? / /
                     / /
    weight_copy ----/ /
                     /
    bias_copy ------/
    Expected list, got r   Tr   c                 N   t        | t              rt        |       } t        |       } | S t        | t        t
        t        j                  f      r| S t        t        t        f      r$D ]  }t        |t              st        d       | S t        dt               d      )Nz/handling of Node inside list is not implementedzhandling for kwarg of type r   )r#   r   r   r   intfloatrS   dtyper   r   r&   r'   )ra   r   ry   rf   rg   r   s     r,   	_copy_argz<_insert_copy_of_node_a_after_input_node_c.<locals>._copy_arg  s    c4 0d;C(dD'BCJc5%++67J	D%=1 b$'(I 
 J -d9o->>QR r.   r   r   r    )rp   r   zUnexpected op: )r#   r   r:   r   r&   r'   r   r   r   r   r   itemsr   r   r"   r$   r%   r   r9   r;   )r   r   re   ry   rf   rz   r   r   r   new_args
new_kwargsr   r   new_arg
kwarg_namenode_a_shadows_c_namenew_mod_copy_namemod_anode_a_shadows_crg   r   s      ``              @@r,   r   r   <  s`   f ,%$$,- #6tL7I6J!KLLq/''224 3  #!1	;!'fmm;	HJ( G
C	N
"a<"G\n8$G	' 23G 1 C	N
" "-!2!2!4 
Ia<%1Jz"\n8%3Jz"%.y%9Jz"1 XHK9:JKDQyyM!K9:JKDQ&--- #5d6==6I5J!KLL v}}5'/"..II!
  99<< ?699+!>??"..IIMM!
  r.   name_aname_bmatched_subgraph_pairsshould_log_inputsc                 X  3 |
t               }t               }i 33fd}	i }
i }|j                         D ]\  \  }}|\  }}t        |j                  |      }t        |j                  |      }||||f|
|j
                  <   ||||f||j                  <   ^ |j                  j                  D ]h  }|j                  dk(  r)|j                  t        |j                  d   |	             <||
v }||v }|s|r|r|
|   \  }}}}n|st        d      ||   \  }}}}t        |j
                        xr t        |      }|sUt        dt        ||       dt        |j
                  |       z   dz          |j!                  ||	      3|j"                  <   t%        |j
                  |||      \  }}t%        ||||      \  }}|t&        j(                  k7  xr= |t&        j(                  k7  xr( |t&        j(                  k7  xr |t&        j(                  k7  }|sVt        dt        ||       dt        |j
                  |       z   d	z          |j!                  ||	      3|j"                  <   |t&        j*                  k(  r|t&        j,                  k(  rot/        |j
                  ||      }|sVt        dt        ||       dt        |j
                  |       z   d
z          |j!                  ||	      3|j"                  <   Qt1        |j
                  |      }t3        |||      sVt        dt        ||       dt        |j
                  |       z   dz          |j!                  ||	      3|j"                  <   t5        |j                  |      }t5        j                  |      }|r|rt7        ||d      } t9        | t:              rV3| j"                     }!t=        |!||d|j"                  |||t>        j@                  jB                  dd|      3|!j"                  <   nt9        | tD              rv| D "cg c]  }"3|"j"                      }#}"tG        |#      D ]K  \  }$}!t=        |!||d|j"                  |||t>        j@                  jB                  |$d|      3|!j"                  <   M nt        dtI        |        d      |s|r.|j!                  ||	      3|j"                  <   3|j"                     }%|rt7        %|d      }!|rHt9        |!t:              rt7        |%|d      }!n*t9        |!tD              r|!D "cg c]  }"t7        |"|d       }!}"tK        |j
                  |%|!||||j"                  dz   ||	      }&|rd}'t9        |&t:              r2t=        |&||d|'| ||t>        j@                  jB                  dd|      }&|&}(nt9        |&tD              st        dtI        |&             g })tG        |&      D ]E  \  }*}+t=        |+||d|'| ||t>        j@                  jB                  |*d|      },|)jM                  |,       G |)}&|&}(d}-t1        |j
                  |      }|dk(  rt7        |%|d      }-tO        |&|-||||%j"                  dz         }.|.3|.j"                  <   |r|.}/t7        |/|d      (k7  rt7        |/|d      }/t7        |/|d      |(k7  rt9        |(t:              r(tQ        ||(j"                        }0|/j"                  |0_)        nUt9        |(tD              st        dtI        |(             |(D ])  }1tQ        ||1j"                        }0|/j"                  |0_)        + t=        3|.j"                     ||d|.j"                  | ||t>        jT                  jB                  dd|      3|.j"                  <   |st=        3|j"                     ||d|j"                  |||t>        jT                  jB                  dd|      3|j"                  <   J|j!                  ||	      3|j"                  <   k tW        ||      }2|2S c c}"w c c}"w )a  
    Creates a new GraphModule consisting of the graph of C, with the meaningful
    nodes of A shadowing the corresponding nodes of B.  For example,

    Graph A:
    a0 -> op0_fp32 -> a1 -> op1_fp32 -> a2

    Graph B:
    b0 -> op0_int8 -> b1 -> op1_int8 -> b2

    matched_node_pairs: {'op0': (op0_fp32, op0_int8), 'op1': (op1_fp32, op1_int8)}

    Graph C (A shadows B):

        / dequant0 -> op0_fp32 -> logger_a_0  / dequant_1 -> op1_fp32 -> logger_a_1
       /                                     /
    b0 -------------> op0_int8 -> logger_b_0 --------------> op1_int8 -> logger_b_1

    In a nutshell, this function does the following for each node pair:
    * copies the necessary attributes and modules from gm_a to gm_b,
      keeping names unique
    * adds a dtype cast op (dequant, quant, etc)
    * adds a copy of node_a in gm_b's graph
    * adds loggers to the outputs of node_a and node_b
    Nc                 "    t        | fd      S )Nc                 "    | j                      S rF   rG   )r   env_cs    r,   rI   z6create_a_shadows_b.<locals>.load_arg.<locals>.<lambda>  s    uTYY'7 r.   rJ   )rK   r   s    r,   rL   z$create_a_shadows_b.<locals>.load_arg  s    q788r.   rM   r   z+Expected node_b_is_end_node to be not falsez$skipping shadow loggers for node_b: z, start_node_a: z, unsupportedz, unknown dtype castz, unknown input qparamsz", unhandled logic in subgraph copy_ns_logger_b_inp_rO   ztype z is not handled yet_dtype_cast_ _ns_logger_a_inp_r   r   r   r   _ns_logger_a__ns_logger_b_),r   r
   r   r   base_op_noder   r   r:   rP   r"   rM   r	   r   r&   r   printrX   r(   r   r   r   r   r   r   r   r   r-   r   r#   r   r@   r   rQ   rR   r   rW   r'   r   r   r   getattrr1   rY   r   )4r   ry   r   rf   r   r/   r   r{   rg   rL   +start_node_b_to_matched_subgraph_a_and_name)end_node_b_to_matched_subgraph_a_and_name
match_namematchr   
subgraph_bref_node_type_aref_node_type_bnode_bnode_b_is_start_nodenode_b_is_end_noder3   all_op_types_support_shadowingr   node_output_type_anode_input_type_bnode_output_type_bnode_io_types_known_a_and_br   r   
fqn_base_a
fqn_base_bprev_node_brd   ra   prev_node_c_listr`   rx   dtype_cast_noder1   input_loggernew_loggersdtype_cast_idxdtype_cast_node_innerdtype_cast_loggernode_c_second_non_param_argr   r   input_logger_modinput_logger_innergm_cr   s4                                                      @r,   create_a_shadows_br    s	   H  '#?#A  gGE9 35/02-399; 

E!&
J-j.E.EtL-j.E.EtL	N
3J4I4IJ 	J
1*2E2EF
" **"" rE99 NN76;;q>8<=  &)TT#'PP#5# @G## *()VWW >fE## .H%%. .5,V4 + 2:;NvW[;\:]^()<Z=R=RTX)Y(Z[\%&
 &-%6%6vx%Hfkk" 5%%tZ9Q!" 5j*B!"
 "%:%B%BB H&*?*G*GGH%)>)F)FFH '*?*G*GG	 ( /:;NvW[;\:]^()<Z=R=RTX)Y(Z[\,-
 &-%6%6vx%Hfkk" "%:%?%??%)>)C)CC'=))41I($ ,>?RSY[_?`>ab,-@AVAVX\-],^_`34
 *1):):68)LE&++&(D%%t)% 2D"; :;NvW[;\:]^()<Z=R=RTX)Y(Z[\:;
 &-%6%6vx%Hfkk"'
(?(?FJ'
(?(?FJ#$":64"KK!+t4&+K,<,<&=2K' &/"KK"$+4??EE-.)* *3k../ $K6 HS+SE#((O+S(+S4=>N4O 0G[6O + $ * 3 & & ( / 8 C C I I18-.$.7E+"2"23" -#D$5#66IJ  $'9%,%6%6vx%Hfkk"v{{+ $ 7vtQG$!+t4&>vtQ&O#K6 (3' # 5S$B' ' #@))KK.0,#, %$&M!/48*C+ &/)"$+4??EE-.)* *+ ;J)/4@"0"5d?6K5L M#  ')EN+F BAN,A 1J 5 $ * 3 - & ( / 8 C C I I1?-.$.1- (../@A#B$ +6'6 /3+,H))4-) -12J	3/ $Q#/KK/1$  0@&++, %  0H28T1EU#;HdA#N 38T1EU ",5+249J9J+K(9A(6  *,="0"5d<6H5I J# 
 3? K./6t=O=T=T/U,=E]],:K
 0I*//0#$))#,88>>%&!""0&++,( "%>&++&#KK#,88>>%&!""&fkk"0 ")!2!268!DE&++erEh tW%DKk ,Tl's   +`"+`'rF   )3collections.abcr   typingr   rS   torch.ao.ns.fx.mappingsr   torch.ao.quantization.fx.utilsr   torch.ao.quantization.observerr   torch.fxr   r	   torch.fx.graphr
   r   ns_typesr   r   r   utilsr   r   r   r   r   r   r   r   r   r   r%   r-   r   r@   dictr   rc   Tensorr   rw   r   setr   r   boolr   r   r   r  rn   r.   r,   <module>r     s   $   @ H F ) & L L   ; 3: "-
-- - !	-
 - - - - - - - 
t- 
-`jj04T5c?5J0Kj 26dE#s(O6K1Lj 	j
 j jZ  	
 <<% s"  
B^J^J^J T
"^J 	^J
 ^J ^J ^J ^J #3,<(=#=>^J 
DJ^JD6
6

6
 6
 	6

 
6
rHH
H  #H 
	HV)d#)4:%,) ) 	)
 ) ) 
)XM d#M 4:%,M  M  	M 
 M  M  
M p IMww
w w 	w
 !eJ
,B&C!CDw w w #3,<(=#=>Ew wr.   