
    `i@                        d dl mZmZmZ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e!         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e!         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ej(        e)f         d"eej(        e#f         d#e!defd$Z*ded%edeee+e         f         d&eded ed'e!ded(e%e!e,e         f         deee+e         f         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-Z0d.eee+e         f         d/eeee+e         f                  d+ed&eded'e!defd0Z1d.eee+e         f         d/eeee+e         f                  ded&eded'e!defd1Z2	 d7d2e!d&ed3e!ded4e%e!e&eef         f         ded5e/d(ee%e!e,e         f                  defd6Z3dS )8    )AnyCallableOptionalUnionN)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                    d }t          |d          rv| }| j        dk    rQt          | j        t                    sJ t          || j                  }t          |          rt          | |d          }|j        |j	                 d         }|S )N_node_name_to_scopecall_moduler   )
hasattrop
isinstancetargetstrr   r	   r   r    name)r   r   fqnnode_to_use_for_fqnmodules        o/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/torch/ao/ns/fx/graph_passes.py_maybe_get_fqnr,      s    
Cr()) 
B #7m##dk3/////%b$+66F*622 L&>tR&K&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                            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.   r/   r0   r1   r2   r3   r4   r5   r6   r(   logger_node_nametarget_type
logger_objlogger_nodes                   r+   _insert_logger_after_noder?   *   s    24	++ 
 
 &dB//K	 J B *---*((8H4'SUVVKr-   *node_to_instrument_inputs_to_ref_node_name+node_to_instrument_outputs_to_ref_node_namec                 f   t                      }i fd}| j        j        D ]}|j        dk    r3|                    t          t          || d          |                     A||v s||v rt          ||           }||v r||         \  }	}
t          |          }|D ]}t          || |          }t          |          t          k    rE|j                 }t          || |d|j        ||	|
t          j        j        d||          |j        <   pt          |          t           j        j        j        k    rZt)          |          D ]I\  }}|j                 }t          || |d|j        ||	|
t          j        j        |||          |j        <   J|                    ||          |j        <   ||v rM||         \  }	}
t          |j                 | |d|j        ||	|
t          j        j        dd|          |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>k   s    s49~ r-   r   )arG   s    r+   load_argz&add_loggers_to_model.<locals>.load_argj   s    q5555666r-   outputr   _ns_logger_r5   r6   r(   )r   r9   nodesr#   rL   r   r   r,   r   typer   r'   r?   r   
NODE_INPUTvaluetorchfximmutable_collectionsimmutable_list	enumerate	node_copyNODE_OUTPUTr
   )r   r@   rA   r.   r1   	new_graphrK   r   r(   r2   ref_node_typearg_indices_to_lognode_arg_idxnode_arg	prev_nodearg_idxargnew_gmrG   s                     @r+   add_loggers_to_modelrc   Z   s    IC7 7 7 7 7  VA VA7hW%=dB%J%JHUUVVV>>>??? r**CAAA*T+'- &Fd%K%K"$6 ( (L7b,OOHH~~--$'$6	-F%&) I&$)4?E-.)5 #. . .HM** X%(*H*WWW -6h,?,?  LGS(+CHI2K ) " * - $	 * ( - 8 C I18-9$'3 3 3C	//"  '00x@@C	NBBB*U+'- ";	N!I!,8>%&!"" " "DI  '00x@@C	NNY''FMr-   prev_node_cnode_agm_bgraph_cscale
zero_pointdtype_cast_namec                     t          |j        dz             |          }t          |||           |                    d|di |          } t          |j        dz             |          }	t          ||	|           |                    d|	di |	          }
|                    dt          j        | ||
t          j        fi |          S )N_input_scale_get_attr _input_zero_point_call_function)r   r'   r8   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3FK/4QRRSWXXOD/5)))$$OR_ J8** 
  D&
33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    s@|t          j        k    r|t          j        k    s |t          j        k    r|t          j        k    rt          j        }	n||k    r"|t          j        k    rt          j	        j
        }
n|t          j        k    r5|t          j        k    r%t          | ||          }|t          j        }	|\  }}nr|t          j        k    r|t          j        k    rd}t          j        }nCt          d| d|                                 d| d|                                  dz             t!          |t"                    r t%          |          |          }|	r3||t'          || |||||          S |                    d|	|fi |          S |r|                    d|||fi |          S |
sJ  |
            }t+          |||           |                    d	||fi |          S t!          |t,                    rg }|D ]} t%          |          |          }|	r0|                    d|	|fi |          }|                    |           L|
sJ  |
            }t+          |||           |                    d	||fi |          }|                    |           |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_methodr!   ztype fz is not handled)r   r   FP32INT8FP16FP32_OR_INT8rS   
dequantizeUNKNOWNnnIdentityr   rq   float16AssertionErrorformat_noder$   r   r   rw   r:   r8   listappendrP   )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!>>>"X.2777!6!;;;  6D2 
  
  +!5M6J332777!6!;;; "'-M0MM63E3E3G3GMMM"SSV%7%7%9%9SSST
 
 	

 +t$$ DJM;<LMMdSS %	+0E0Q7$)'   **#! N'    	&&!56#   &%%%//11ND-~>>>&&##   
K	&	& J!, 	4 	4"Q"?@P"Q"QRV"W"W 4&-&9&9#!&('' '# 23333))))!3!3!5!51>BBB&-&9&9!'&('' '# 23333Hd;&7&7HHHIIIr-   c           
         | j         dk    r t          | j        dz             |          }t          || j                  }t          j        |          r|                                }t          |||           |	                    | j         |di |          }|S | j         dk    r| j        dv sJ d| j         d            | j        dk    rgt          t          | |d	          |||          } t          | j        dz             |          }|	                    | j         | j        |fi |          }|S t          t          | |d	          |||          } t          | j        dz             |          }|	                    | j         | j        |t          | |d
          fi |          }|S t          d|                                  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detachr8   r:   _copy_node_from_a_to_cr   r   r   )re   ry   rf   rg   node_a_copy_name
node_a_objnode_a_copyarg_copys           r+   r   r     sN    yJW89VWW
 
 &dFM::
?:&& 	-#**,,J&
333))I'R1A
 
 	m	#	#} !
 
 
 
 8V]777
 
 
 =L((-(q994w H <o-       "--	6=8+r;K K -(q994w H <o-       "--	3FD!DDE  K  ] 2 2 4 4]]vy]]]
 
 	
r-   
subgraph_anum_non_param_args_node_ac                    g }| j         }|| j        k    r1|                    |           t          ||d          }|| j        k    1|                    |           |                                 d }|D ]}||d         u r|nd}|                    |d          }||\  }	}
n|j        |j        }
}	d}|t          |	          k     rA|dk    rn"|dk    r|dk    rn ||	|         |          s dS |dz  }|t          |	          k     A|
	                                D ]+}|dk    rn|dk    r|dk    rn |||          s  dS |dz  },dS )	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                    r3t          | |          }|j        dk    r	|j        dv S |j        dk    rdS dS t          | t
          t          f          r| D ]}t          |t                    s dS dS )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  s    j$'' 	!2:tDDEx=((|';;;Z''tu
T5M22 	!  ! !!"d++ ! 55!tr-   r   Tnormalize_to_only_use_kwargsN   F)
end_node
start_noder   r   reversenormalized_argumentsargskwargslenvalues)r   ry   r   rO   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     s    E"H
j+
+
+X+HdA>> j+
+
+ 
LL	MMOOO  "  " ")/58););%% 	( "66t 7 
 
 '%5"I{{%+[&-{II&&!||A"AQ"F"F"{9W#5t<< ! 55qLG I&& %++-- 		 		I!||A"AQ"F"F"{9d33 ! 555qLGG		 4r-   input_node_cinput_node_c_2c           	         t          | t          t          f          sJ |j        g}|j        }||j        k    r2t          ||d          }|                    d|           ||j        k    2|d         }t          | |||||          }	t          dt          |                    D ] }
||
         }|	}t          |d||||          }	!|	S )z*
    TODO(before land): real docblock
    r   r   N)
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1111 %&J"H
j+
+
++HdA>>!X&&& j+
+
+ AJ:nj$>N J 1c*oo.. 
 
		*
 >
 


 r-   c                    t          | t                    r| j        n$t          | t                    sJ | d         j        |                    d          }||\  }}n|j        |j        }}g }	i }
fd}d}|t          |          k     rR|dk    r| }n|dk    r||}n |||                   }|	                    |           |dz  }|t          |          k     R|	                                D ]2\  }|dk    r| |
|<   n|dk    r|||
|<   n |          |
|<   |dz  }3t          |	          }	 t          |                    }|j        dk    rz t          |                    }t          |j        t                    sJ t          |j                  }t!          ||                               |j        ||	|
|          }|S |j        dv s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 ------/
    r   Tr   Nc                    t          | t                    r$t          |           } t          |           } | S t          | t          t
          t          j        f          r| S t          t          t          f          r&D ]!}t          |t                    r
J 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   rP   )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'BBCJc5%+677 	J	D%=11 		  %b$//  E /  J Rd9ooRRR  r-   r   r!   )rp   r   )r$   r   r9   r   r   r   r   r   r   itemsr   r   r#   r%   r&   r   r8   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 ,%% ($,-----q/'224 3   #!1	;;!'fm;	HJ       & G
C	NN
"
"a<<"GG\\n8$GGi	' 233G   1 C	NN
"
" "-!2!2!4!4  
Ia<<%1Jz""\\n8%3Jz""%.Yy%9%9Jz"1XHK9:JKKDQQyM!!K9:JKKDQQ&------ v}55'///"..I!
 
  y<<<<<"..IM!
 
  r-   name_aname_bmatched_subgraph_pairsshould_log_inputsc                   3 |t                      }t                      }i 33fd}	i }
i }|                                D ]P\  }}|\  }}t          |j        |          }t          |j                  }||||f|
|j        <   ||||f||j        <   Qj        j        D ]}|j	        dk    r/|
                    t          |j        d         |	                     =||
v }||v }|s|r|r|
|         \  }}}}n|sJ ||         \  }}}}t          |j                  ot          |          }|s[t          dt          |           dt          |j        |           z   dz              |                    ||	          3|j        <   t#          |j        |||          \  }}t#          |||          \  }}|t$          j        k    o/|t$          j        k    o|t$          j        k    o|t$          j        k    }|s\t          dt          |           dt          |j        |           z   dz              |                    ||	          3|j        <   |t$          j        k    r|t$          j        k    rtt-          |j        ||          }|s\t          dt          |           dt          |j        |           z   d	z              |                    ||	          3|j        <   Lt/          |j        |          }t1          |||          s\t          dt          |           dt          |j        |           z   d
z              |                    ||	          3|j        <   t3          |j        |          }t3          |j                  }|r|rt5          |d          } t7          | t8                    rE3| j                 }!t;          |!|d|j        |||t<          j        j         dd|          3|!j        <   nt7          | tB                    rc3fd| D             }"tE          |           D ]D\  }#}$|"|#         }!t;          |!|d|j        |||t<          j        j         |#d|          3|!j        <   En tG          dtI          |            d          |s|r+|                    ||	          3|j        <   3|j                 }%|rt5          |%d          }!|rJt7          |!t8                    rt5          |%d          }!n#t7          |!tB                    rfd|!D             }!tK          |j        |%|!|||j        dz   ||	  	        }&|rd}'t7          |&t8                    r-t;          |&|d|'| ||t<          j        j         dd|          }&|&}(nqt7          |&tB                    sJ g })tE          |&          D ]D\  }*}+t;          |+|d|'| ||t<          j        j         |*d|          },|)&                    |,           E|)}&|&}(d}-t/          |j        |          }|dk    rt5          |%d          }-tO          |&|-|||%j        dz             }.|.3|.j        <   |r|.}/t5          |/d          |(k    r&t5          |/d          }/t5          |/d          |(k    &t7          |(t8                    r"tQ          |(j                  }0|/j        |0_)        n=t7          |(tB                    sJ |(D ]#}1tQ          |1j                  }0|/j        |0_)        $t;          3|.j                 |d|.j        | ||t<          j*        j         dd|          3|.j        <   |rBt;          3|j                 |d|j        |||t<          j*        j         dd|          3|j        <   |                    ||	          3|j        <   tW          |          }2|2S )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 rE   rF   )r   env_cs    r+   rH   z6create_a_shadows_b.<locals>.load_arg.<locals>.<lambda>  s    uTY'7 r-   rI   )rJ   r   s    r+   rK   z$create_a_shadows_b.<locals>.load_arg  s    q7777888r-   rL   r   z$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_rN   c                 *    g | ]}|j                  S rn   rF   ).0ra   r   s     r+   
<listcomp>z&create_a_shadows_b.<locals>.<listcomp>  s    +S+S+SE#(O+S+S+Sr-   ztype z is not handled yetc                 2    g | ]}t          |d           S )r   )r   )r   ra   rf   s     r+   r   z&create_a_shadows_b.<locals>.<listcomp>  s5     ' ' ' # 5S$BB' ' 'r-   _dtype_cast_ _ns_logger_a_inp_r   r   r   _ns_logger_a__ns_logger_b_),r   r   r   r   base_op_noder   r   r9   rO   r#   rL   r   r   r   printrX   r'   r   r   r   r   r   r   r   r   r,   r   r$   r   r?   r   rQ   rR   r   rW   r   rP   r   r   r   getattrr0   rY   r
   )4r   ry   r   rf   r   r.   r   r{   rg   rK   +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_noder2   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   prev_node_c_listr`   ra   rx   dtype_cast_noder0   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#A  ggGE9 9 9 9 9 35/02-399;; 
 

E!&
J-j.EtLL-j.EtLL	N
3J4IJ 	J
1*2EFF *" aE aE9  NN76;q>8<<===  &)TT#'PP X	E#5 X	E# F @G##O *))) >fE## .H%. . .5,V44 + 2 ^;NvW[;\;\^^[)<Z=RTX)Y)Y[[\%&  
 &-%6%6vx%H%Hfk" 5%tZ9Q !" 5j*B !"
 "%:%BB H&*?*GGH%)>)FFH '*?*GG	 ( / ^;NvW[;\;\^^[)<Z=RTX)Y)Y[[\,-  
 &-%6%6vx%H%Hfk" "%:%???%)>)CCC'=)41I( ($ , b?RSY[_?`?`bb_-@AVX\-]-]__`34  
 *1):):68)L)LE&+&(D%t) )% 2D";  	 ^;NvW[;\;\^^[)<Z=RTX)Y)Y[[\:;  
 &-%6%6vx%H%Hfk"'
(?FFJ'
(?FFJ# .$ ,":64"K"KK!+t44 *&+K,<&=2K' &/"K"$+4?E-.)* *3 3 3k.// $K66  ,T+S+S+S{+S+S+S(,5k,B,B  LGS*:7*CK6O + $ * 3 & & ( / 8 C I18-.$.7 7 7E+"233$ -JD$5$5JJJ   $ ,'9 ,%,%6%6vx%H%Hfk"v{+ $ U 7vtQGG$ !+t44 &>vtQ&O&O#K66 ' ' ' ''2' ' ' #@)K.0,
# 
#* % )7$&M!/488 &7*C+ &/)"$+4?E-.)* *+ + + AP)/4@@@@@&(EN+F F B BAN,A 1J 5 $ * 3 - & ( / 8 C I1?-.$.1 1 1- (../@AAAA*5'6 /3+,H)4- -) -112Ja3 3/ $Q#/K/1$ $  0@&+, % K  0H28T1EEUU#;HdA#N#N 38T1EEUU!,55 K+249J+K+K(9A(66),=====2> K K./6t=O=T/U/U,=E],:: 0I*/0#$)#,8>%&!""0 0 0&+,( " %>&+&#K#,8>%&!""& & &fk"0 ")!2!268!D!DE&+tW%%DKr-   rE   )4typingr   r   r   r   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   1 1 1 1 1 1 1 1 1 1 1 1  @ @ @ @ @ @ H H H H H H F F F F F F ) ) ) ) ) ) ) ) & & & & & & & & L L L L L L L L L L                        ; 8C=     -
-- - !	-
 - - - - - - - 
#- 
- - - -`ll04T5c?5J0Kl 26dE#s(O6K1Ll 	l
 l l l l l^  	
 u$% elC'(  
   B\J\J\J tT$Z'(\J 	\J
 \J \J \J \J #3,<(=#=>\J 4d\J \J \J \J@8
8

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

 
8
 8
 8
 8
vHH
H  #H 
	H H H HV(d4j()(U4d#345( ( 	(
 ( ( 
( ( ( (VI d4j()I U4d#345I  I  	I 
 I  I  
I  I  I  I h LPf ff
f f 	f
 !eJ
,B&C!CDf f f 'tC5E1F,F'GHf f f f f f fr-   