
    Phl                     F   d dl Z d dlmZmZ d dlmZmZ d dl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dlmZmZ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#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 jT                  e+f   d"e"e jT                  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Z3y)8    N)GraphModulemap_arg)GraphNode)get_new_attr_name_with_prefix   )
$get_node_first_input_and_output_typegetattr_from_fqnNodeInputOrOutputTypereturn_first_non_observer_nodeget_number_of_non_param_argsget_target_type_str get_arg_indices_of_inputs_to_logget_node_input_qparamsop_type_supports_shadowingget_normalized_nth_input)NSSingleResultValuesType
NSSubgraphNSNodeTargetType)get_node_type_to_io_type_map)_is_activation_post_process)DictTupleCallableListAnyUnionOptionalSetnodegmreturnc                    d }t        |d      rw| }| j                  dk(  rJt        | 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        fC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\torch/ao/ns/fx/graph_passes.py_maybe_get_fqnr0      s    
Cr() #77m#dkk3///%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!   r2   r3   r4   r5   r6   r7   r8   r9   r:   r,   logger_node_nametarget_type
logger_objlogger_nodes                   r/   _insert_logger_after_noderC   .   s    4 	K%dii2I&IJ2N %dB/Ktyy*h&c;J
 B *-**(('$"6Kr1   *node_to_instrument_inputs_to_ref_node_name+node_to_instrument_outputs_to_ref_node_namec                    t               }i t        | j                               }fd}| j                  j                  D ]  }|j
                  dk(  r'|j                  t        t        || d      |             :||v s||v rt        ||       }	||v r+||   \  }
}t        |      }|D ]  }t        || |      }t        |      t        k(  rV|j                     }t        || |d|j                  ||
|t        j                   j"                  d||	      |j                  <   yt        |      t$        j&                  j(                  j*                  k(  rjt-        |      D ]Z  \  }}|j                     }t        || |d|j                  ||
|t        j                   j"                  |||	      |j                  <   \  |j/                  ||      |j                  <   ||v s||   \  }
}t        |j                     | |d|j                  ||
|t        j0                  j"                  dd|	      |j                  <   |j/                  ||      |j                  <   " t3        | |      }|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>g   s    s499~r1   r   )arK   s    r/   load_argz&add_loggers_to_model.<locals>.load_argf   s    q566r1   outputr   _ns_logger_r9   r:   r,   )r   dictnamed_modulesr=   nodesr'   rP   r   r   r0   r   typer   r+   rC   r   
NODE_INPUTvaluetorchfximmutable_collectionsimmutable_list	enumerate	node_copyNODE_OUTPUTr   )r!   rD   rE   r2   r5   	new_graphmodulesrO   r    r,   r6   ref_node_typearg_indices_to_lognode_arg_idxnode_arg	prev_nodearg_idxargnew_gmrK   s                      @r/   add_loggers_to_modelrj   U   sU    IC2##%&G7 77hW%=dB%JHUV ??@@ r*CAA*TUY*Z'-
 &Fd%K"$6L7b,OHH~-$'$6	-F%r:}dii&-4??EE-.\ #.%HMM* h588+I+I+X+XX,5h,?LGS(+CHHI2K )2z=$)) *Hm 8 C C I I18|$'3)C	/ -@ - %74 '00x@C		NBB*UVZ*['-!:		NB
M499-,88>>%&QC	"ADII '00x@C		Nq t Y'FMr1   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+   r<   r>   rY   quantize_per_tensorquint8)rk   rl   rm   rn   ro   rp   rq   scale_node_name
scale_nodezero_point_node_namezero_point_nodes              r/    _insert_quantize_per_tensor_noder~      s    	+%KK/)	++/	1  D/5)$$OR_>J	0%KK..	004	6  D&
3))("b2FHO 22	j/5<<@" r1   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J  |
       }t+        |||       |j)                  d	||fi |      S t!        |t,              rg }|D ]|  } t%        |      |      }|	r(|j)                  d|	|fi |      }|j/                  |       >|
sJ  |
       }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 implementedrw   call_methodr%   ztype fz is not handled)r	   r   FP32INT8FP16FP32_OR_INT8rY   
dequantizeUNKNOWNnnIdentityr   rx   float16AssertionErrorformat_noder(   r   r   r~   r>   r<   listappendrV   )rl   r   rk   r   rm   rn   r   r2   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" ,D*&>	@ +* 	-D*&>	@ +*
 
388	8	388	8	388	8	388	8 
388	8	3@@	@((..2:::"XX..27772777  6D2 4+!55M6J3327772777 "'--0163E3E3G2HM !6#5#5#7"88PQRS 	S +t$;)*:;DA 	+0E0Q7w8H)+>@ @ **#][NB') ) &&056<OQ Q &%%/1ND-~>&&2[NB#% % 
K	&!,?-.>?E  &-&9&9#]5F4H"'')# 23)))!3!51>B&-&9&9!#69J8Lb'')# 23! "-" vd;&7%8HIIr1   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 sJ 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.
    rt   _shadow_copy_ru   r   r   r   ztarget  is not implementedr   r   r   zhandling of node z	 with op )r'   r   r+   r
   r)   rY   	is_tensordetachr<   r>   _copy_node_from_a_to_cr   r   r   )rl   r   rm   rn   node_a_copy_name
node_a_objnode_a_copyarg_copys           r/   r   r   A  s    yyJH)&++*GHN 	%dFMM:
??:&#**,J&
3))II'R1AC	m	#}} 44 	9fmm_$78	94==L(-(q9dG%H M-fkkO.KLTR !--		6==8+r;KMK-(q94wPH M-fkkO.KLTR !--		6==3FD!DE$&K   2 2 45YvyykI\]_ 	_r1   
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   rt   TF)r(   r   r   r'   r)   r   tuple)
node_a_argr   arg_aels       r/   _can_insertz3_can_insert_copy_of_subgraph_a.<locals>._can_insert  sp    j$'2:tDExx=(||';;;Z'
T5M2 !"d+  ! r1   r   Tnormalize_to_only_use_kwargs   F)
end_node
start_noder   r   reversenormalized_argumentsargskwargslenvalues)r   r   r   rU   cur_noder   rl   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   o  sq    E""H
j++
+X+HdA> j++
+ 
LL	MMO"  q! +D'( 	( "66t 7 5'%5"I{%+[[&--{II&!|A"AQ"F"9W#5t< qLG I& %++-I!|A"AQ"F"9d3 qLG .1 F r1   input_node_cinput_node_c_2c           	         t        | t              r| j                  }n!t        | t              sJ | d   j                  }|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
    r   r   N)r(   r   r=   r   r   r   r   insert)_insert_copy_of_node_a_after_input_node_cranger   )r   r   r   r   rm   r   rn   
nodes_of_ar   
cur_node_a
cur_node_c	cur_idx_ark   s                r/   -_insert_copy_of_subgraph_a_after_input_node_cr     s     ,%$$,---q/'' %%&J""H
j++
++HdA>!X& j++
+ AJ:J 1c*o.		*
 >
 / r1   c                    t        | t              r| j                  n!t        | t              sJ | 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(  rq t        |            }t        |j                  t              sJ t        |j                        }t!        ||       j#                  |j                  ||	|
|      }|S |j                  dv s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 ------/
    r   Tr   c                 F   t        | t              rt        |       } t        |       } | S t        | t        t
        t        j                  f      r| S t        t        t        f      r D ]  }t        |t              s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floatrY   dtyper   r   r   rV   )rh   r   r   rm   rn   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$/ FEF/   J -d9o->>QRT Tr1   r   r%   )rw   r   )r(   r   r=   r   r   r   r   r   r   itemsr   r   r'   r)   r*   r
   r<   r>   )r   r   rl   r   rm   r   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_crn   r   s      ``              @@r/   r   r     s)   f ,%$$,---q/''224 3 1#!1	;!'fmm;	HJT" 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 "5 XH 	8%&67=  yyM! <)*:;DA 	 &----- v}}5'/"..II((-/  yy<<<<"..IIv}}h-/  r1   name_aname_bmatched_subgraph_pairsshould_log_inputsc                 .  4 |
t               }t               }i 4t        |j                               }	4fd}
i }i }|j	                         D ]\  \  }}|\  }}t        |j                  |      }t        |j                  |      }||||f||j                  <   ||||f||j                  <   ^ |j                  j                  D ]:  }|j                  dk(  r)|j                  t        |j                  d   |
             <||v }||v }|s|r|r||   \  }}}}n|sJ ||   \  }}}}t        |j                        xr t        |      }|sUt!        dt        ||       dt        |j                  |       z   dz          |j#                  ||
      4|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#                  ||
      4|j$                  <   |t(        j,                  k(  r|t(        j.                  k(  rot1        |j                  ||      }|sVt!        dt        ||       dt        |j                  |       z   d	z          |j#                  ||
      4|j$                  <   Ht3        |j                  |      }t5        |||      sVt!        dt        ||       dt        |j                  |       z   d
z          |j#                  ||
      4|j$                  <   t7        |j                  |      }t7        j                  |      } |r|rt9        ||d      }!t;        |!t<              rV4|!j$                     }"t?        |"||d|j$                  |||t@        jB                  jD                  dd|       4|"j$                  <   nt;        |!tF              r{|!D #cg c]  }#4|#j$                      }$}#tI        |!      D ]P  \  }%}#|$|%   }"t?        |"||d|j$                  |||t@        jB                  jD                  |%d|       4|"j$                  <   R ntK        dtM        |!       d      |s|r.|j#                  ||
      4|j$                  <   4|j$                     }&|rt9        &|d      }"|rHt;        |"t<              rt9        |&|d      }"n*t;        |"tF              r|"D #cg c]  }#t9        |#|d       }"}#tO        |j                  |&|"||||j$                  dz   ||	      }'|rd}(t;        |'t<              r2t?        |'||d|(| ||t@        jB                  jD                  dd|      }'|'})nkt;        |'tF              sJ g }*tI        |'      D ]E  \  }+},t?        |,||d|(| ||t@        jB                  jD                  |+d|      }-|*jQ                  |-       G |*}'|'})d}.t3        |j                  |      }|dk(  rt9        |&|d      }.tS        |'|.||||&j$                  dz         }/|/4|/j$                  <   |r|/}0t9        |0|d      )k7  rt9        |0|d      }0t9        |0|d      |)k7  rt;        |)t<              r(tU        ||)j$                        }1|0j$                  |1_+        n@t;        |)tF              sJ |)D ])  }2tU        ||2j$                        }1|0j$                  |1_+        + t?        4|/j$                     ||d|/j$                  | ||t@        jX                  jD                  dd|      4|/j$                  <   |st?        4|j$                     ||d|j$                  |||t@        jX                  jD                  dd|       4|j$                  <   |j#                  ||
      4|j$                  <   = t[        ||      }3|3S 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 rI   rJ   )r    env_cs    r/   rL   z6create_a_shadows_b.<locals>.load_arg.<locals>.<lambda>  s    uTYY'7r1   rM   )rN   r   s    r/   rO   z$create_a_shadows_b.<locals>.load_arg  s    q788r1   rP   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_rR   ztype z is not handled yet_dtype_cast_ _ns_logger_a_inp_r   r   r   _ns_logger_a__ns_logger_b_).r   r   rS   rT   r   r   base_op_noder   r   r=   rU   r'   rP   r   r   r   printr^   r+   r	   r   r   r   r   r   r   r   r0   r   r(   r   rC   r   rW   rX   r   r]   r   rV   r   r   r   getattrr4   r_   r   )5r   r   r   rm   r   r2   r   r   rn   ra   rO   +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_noder6   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_brk   rh   prev_node_c_listrg   r   dtype_cast_noder4   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   s5                                                       @r/   create_a_shadows_br  l  s   H  '#?#A  gGE4%%'(G9 35/02-399;
E!&
J-j.E.EtL-j.E.EtL_oF 	4J4I4IJ _oF 	2*2E2EF < **""99 NN76;;q>8<=  &)TT#'PP $6#?G G
Ho *))=fE G
Ho +:+@+@A 3*62 + 2:;NvW[;\:]^&'::;P;PRV'W&XYZ#$% &-%6%6vx%Hfkk"
 5))4,. 21
 5D*,. 21
 "%:%B%BB D"&;&C&CCD!%:%B%BBD #&;&C&CC	 ( /:;NvW[;\:]^&'::;P;PRV'W&XYZ*+, &-%6%6vx%Hfkk" "%:%?%??!%:%?%??'=))41I(K$+>?RSY[_?`>ab*+>z?T?TVZ+[*\]^123 *1):):68)LE&++& -Z-B-BDI &1*dD]^:;NvW[;\:]^&'::;P;PRV'W&XYZ89: &-%6%6vx%Hfkk"'
(?(?FJ'
(?(?FJ# %":64"KK!+t4&+K,<,<&=2K'z;N"KK?4??EE-.Q *3,k../ $K6 HS+S{E#((O{(+S,5k,BLGS*:7*CK6O +T:?R &VX 8 C C I I18q$.70E+"2"23 -C -uT+5F4GGZ-[\\ $'9%,%6%6vx%Hfkk"v{{+ $
 7vtQG$!+t4&>vtQ&O#K6Yd&eYdRU'?T1'MYd&e"?))6;dGKK.0*,#. %$&M!/48*C+T:?R)68_4??EE-.Q *+, AP)/4@@@&(ENE_AN,A0I 5tZI\ -vx 8 C C I I1?-.$.10- (../@A F` +6'6 /3+,HI^I^`d,e),12J6SWYZ2[/#P#%@dFKK/,I$K  0@&++, %  0H28T1EU#;HdA#N 38T1EU!,5+249J9J+K(9A(6),===2>./6t=O=T=T/U,=E]],: 3?
 0I*//0$
O$))68_,88>>%&Q"0$&++, " &?&++&j/KK?,88>>%&Q"&$fkk"  ")!2!268!DE&++Y #\ tW%DKS ,TZ 'fs   ;` `rI   )4rY   torch.fxr   r   torch.fx.graphr   r   torch.ao.quantization.fx.utilsr   utilsr	   r
   r   r   r   r   r   r   r   r   ns_typesr   r   r   torch.ao.ns.fx.mappingsr   torch.ao.quantization.observerr   typingr   r   r   r   r   r   r   r   r*   r0   r   rC   rj   Tensorr   r~   r   r   boolr   r   r   r  ru   r1   r/   <module>r     s:    ) & H   
 G I I I ; 8C= %
%% % !	%
 % % % % % % % 
#% 
%NOO04T5c?5J0KO 26dE#s(O6K1LO 	O
 O Ob  	
 u$% ellC'(  
:{J{J{J tT$Z'({J 	{J
 {J {J {J {J #3,<(=#=>{J 4d{J|,_,_
,_ ,_ 	,_
 
,_\GG
G  #G 
	GR/d4j()/U4d#345/ / 	/
 / / 
/d@ d4j()@ U4d#345@  @  	@ 
 @  @  
@ T LPJJ
J J 	J
 !eJ
,B&C!CDJ J J 'tC5E1F,F'GHJ Jr1   