
    3jIb                        S SK r S SKJrJrJrJrJrJrJrJ	r	J
r
JrJr  S SKJrJrJr  \ R"                  \ R$                  \ R&                  \ R(                  \ R*                  S.r\R/                  5        V Vs0 s H  u  pX_M	     snn r\ R(                  4S\ R2                  S\ R2                  S\ R4                  S\ R2                  4S	 jjr\ R&                  4S\ R2                  S\ R2                  S\ R4                  S\ R2                  4S
 jjrS r\ R(                  4S\ R2                  S\ R2                  S\ R4                  S\ R2                  4S jjr   SCS\ R2                  S\ R2                  S\S\ S\ S\!\ R2                  \ R2                  4   4S jjr"\ RF                  " / SQ5      RI                  S5      r%0 r&\ R&                  S4S\ R2                  S\ R2                  S\ R2                  S\ R4                  S\ S\ R2                  4S jjr'   SDS\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S-  S \ R4                  S-  S!\ R2                  S-  S\ R2                  4S" jjr(S#r) SES\ R2                  S$\ S\!\ R2                  \ R2                  4   4S% jjr*\ R&                  4S\ R2                  S\ R2                  S\ R4                  S\ R2                  4S& jjr+  SFS\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S-  S \ R4                  S-  S\ R2                  4S' jjr,\ RZ                  R]                  S(S)S*9S\ R2                  S\ R2                  S+\/S\ R2                  4S, j5       r0\0Rb                  S- 5       r2\ RZ                  R]                  S.S)S*9S\ R2                  S\ R2                  S+\/S\ R2                  4S/ j5       r3\3Rb                  S0 5       r4\ RZ                  R]                  S1S)S*9S\ R2                  S\ R2                  S\S\ S\ S\!\ R2                  \ R2                  4   4S2 j5       r5\5Rb                  S3 5       r6\ RZ                  R]                  S4S)S*9S\ R2                  S\ R2                  S\ R2                  S+\/S\ S\ R2                  4S5 j5       r7\7Rb                  S6 5       r8\ RZ                  R]                  S7S)S*9S\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S-  S+\/S!\ R2                  S-  S\ R2                  4S8 j5       r9\9Rb                  S9 5       r:\ RZ                  R]                  S:S)S*9S\ R2                  S$\ S\!\ R2                  \ R2                  4   4S; j5       r;\;Rb                  S< 5       r<\ RZ                  R]                  S=S)S*9S\ R2                  S\ R2                  S+\/S\ R2                  4S> j5       r=\=Rb                  S? 5       r>\ RZ                  R]                  S@S)S*9S\ R2                  S\ R2                  S\ R2                  S\ R2                  S\ R2                  S-  S+\/S\ R2                  4SA j5       r?\?Rb                  SB 5       r@gs  snn f )G    N)	E8M0_BIASF4_E2M1_MAXF8_E4M3_MAXF8_E5M2_MAX_f32_to_floatx_unpacked_float8_rounde8m0_to_f32from_blocked
pack_uint4roundup
to_blocked)ScalingTypeSwizzleTypescaled_mm_v2)r               xscaleoutput_typereturnc                    U[         R                  :X  a  [        nO*U[         R                  :X  a  [        nO[        SU S35      eU SU-  R                  U R                  5      -  n[         R                  " XC* X4S9nUR                  U5      $ )NUnsupported output_type: 3. Expected torch.float8_e4m3fn or torch.float8_e5m2      ?)out)	torchfloat8_e4m3fnr   float8_e5m2r   
ValueErrortodtypeclamp)r   r   r   lp_maxtemps        c/home/wildlama/miniconda3/lib/python3.13/site-packages/comfy_kitchen/backends/eager/quantization.pyquantize_per_tensor_fp8r(   )   s     e)))	))	)'}4gh
 	
 e((D;;tWf7D77;    c                 D    U R                  US9UR                  US9-  nU$ Nr#   )r"   )r   r   r   	dq_tensors       r'   dequantize_per_tensor_fp8r.   9   s*     ;'%(((*EEIr)   c                     [         R                  " UU SX-
  -  -  S-
  SU-  -  U SU* S-   U-
  -  -  5      nXeR                  UR                  S9S-  -  nUR	                  5       SU-  -  $ )N       @r   r   r   r,   g      p?)r   wherer"   r#   floor)abs_xexponentnormal_maskMANTISSA_BITSEXPONENT_BIASrngmantissa_scaleds          r'   calc_mantissar:   @   s    kk	#(23	4s	:q-?OP	#=.1,}<=	>O vvO$9$9v:kJJO  "a&677r)   r8   c                    U[         R                  :X  a  Su  p4nO)U[         R                  :X  a  Su  p4nO[        SU S35      eU R	                  5       n [         R
                  " U 5      nU R                  5       n[         R                  " US:H  SU5      n[         R                  " [         R                  " [         R                  " U5      5      U-   SSU-  S-
  5      nUS:H  ) n	[        XxXXQ5      US S & U[         R                  " U	SX-
  -  S	U-   -  SU* S-   -  U-  5      -  n[         R                  " U5      n
[         R                  " XjR                  U
R                  US
9  UR                  U5      $ )N)         )r   r      r   r   r   r   r   r0   r   )minmaxr   )r   r   r    r!   halfsignabsr1   r$   r2   log2r:   finfor@   rA   r"   )r   r8   r   EXPONENT_BITSr6   r7   rC   r3   r4   r5   infos              r'   stochastic_rounding_fp8rI   K   s\   
 e)))6=3m	))	)6>3m'} 5# #
 	

 	
A::a=DEEGE;;uz1d+D{{EJJu%&6		=1H
 M"KUk-]E!HEKK	)	*sU{;	-!#	$- D ;;{#D	KK((d;77;r)   Tper_tensor_scaleepsilonpad_16xhi_firstc                 2   U R                   nU(       an  U R                   u  pg[        US5      n[        US5      n	X:w  d  X:w  a>  [        R                  R                  R                  U SX-
  SX-
  45      n U R                   nSn
U R                  US   SU
5      n [        R                  " [        R                  " U 5      SS9nUR                  [        R                  5      [        -  nX-  n[        R                  " U[        S9n[        U5      nX-  nUS:H  n[        R                  " U[        R                   " U5      U5      nU R#                  5       UR%                  S5      -  n[        R                  " UR%                  S5      [        R&                  " U5      U5      nUn[        R                  " U[        * [        5      nUR)                  U5      n[+        USS5      n[-        UUS9n[/        UR                  [        R0                  5      S	S
9nUU4$ )N   r   dim)rA   r   r   )rM   Fflatten)shaper   r   nn
functionalpadreshapeamaxrD   r"   float32r   r$   r   r   r1   	ones_likefloat	unsqueeze
zeros_likeviewr   r   r   r   )r   rJ   rK   rL   rM   
orig_shaperowscolspadded_rowspadded_cols
block_sizemax_absblock_scalescaled_block_scalesscaled_block_scales_fp8scaled_block_scales_fp32total_scalezero_scale_masktotal_scale_safedata_scaled
out_scalesdata_lpblocked_scaless                          r'   quantize_nvfp4rs   s   s    J WW
dB'dB'+"5##''A{/A1kFX+YZA JJ			*Q-Z0Ajj12.G**U]]+k9K%8#kk*=;O,-DE"=K #a'O{{?EOOK4PR]^'').88<<K++o77;U=M=Mk=Z\ghK(J++kK<EK"":.K%k1a8G84G
e.A.A BERNN""r)   )        g      ?r   g      ?r0   g      @g      @g      @g       g      g      g      g       g      g      g      r   qxblock_scalesc                 ^   [         R                  U R                  U45      nUc5  [        R	                  U R                  U5      nU[         U R                  U4'   U S-  nU S-	  nU(       a6  [
        R                  " Xv/SS9R                  " / U R                  S S QSP76 nO5[
        R                  " Xg/SS9R                  " / U R                  S S QSP76 n[
        R                  R                  R                  UR                  5       U5      R                  S5      nUR                  n	Sn
UR                  U	S   SU
5      nU	S   U
-  n[        UU	S   US9nUR	                  U5      UR	                  U5      -  nXR!                  S5      -  nUR                  U	5      R	                  U5      nU$ )	Nr?   r<   rP   rQ   rO   r   r   num_rowsnum_cols)E2M1_LUT_CACHEgetdeviceE2M1_LUTr"   r   stackr`   rU   rV   rW   	embeddingintsqueezerY   r
   r^   )ru   rJ   rv   r   rM   lutlohir   ra   rf   num_blocks_per_rowblock_scales_unswizzledrl   data_dequantizedresults                   r'   dequantize_nvfp4r      s    

bii5
6C
{kk"))[136		;/0	dB	qBkk2(+00D"((3B-DDkk2(+00D"((3B-DD
((


'
'	3
7
?
?
CC JJ ++jmR
4C
 $A*4 +A# #%%k25L5O5OP[5\\K 22266 "":.11+>FMr)   abtensor_scale_atensor_scale_bblock_scale_ablock_scale_bbias	out_dtypealphac	                    [        U R                  [        R                  5      UR                  [        R                  5      R	                  5       UR                  S5      U/UR                  S5      U/UU[
        R                  [
        R                  /[
        R                  [
        R                  /[        R                  [        R                  /[        R                  [        R                  /S9
n	U	$ )NrP   scale_ascale_br   r   scale_recipe_ascale_recipe_b	swizzle_a	swizzle_b)r   r`   r   float4_e2m1fn_x2tr   BlockWise1x16
TensorWiser   SWIZZLE_32_4_4
NO_SWIZZLE)
r   r   r   r   r   r   r   r   r   r   s
             r'   scaled_mm_nvfp4r      s     	u%%&	u%%&((*##B'8##B'8%33[5K5KL%33[5K5KL //1G1GH //1G1GHF Mr)       pad_32xc                    U R                   nU R                  5       S:X  d   S5       eU(       ao  U R                   u  p4[        US5      n[        US5      nXS:w  d  Xd:w  a>  [        R                  R
                  R                  U SXd-
  SXS-
  45      n U R                   nO(U R                   S   [        -  S:X  d   S[         35       eUu  p4U[        -  nU R                  X7[        5      n[        R                  " [        R                  " U5      SS9n	U	R                  5       [        -  n
[        R                  " U
S	S
9n
[        R                  " U
5      n[        R                  " U5      R!                  [        R"                  5      [$        -   n[        R                  " USS5      nUR!                  [        R&                  5      n[)        U5      nU	S:H  n[        R*                  " U[        R,                  " U5      U5      nUR                  5       UR/                  S5      -  n[        R*                  " UR/                  S5      [        R0                  " U5      U5      n[        R                  " U[        * [        5      nUR                  U5      R!                  [        R2                  5      n[        R*                  " U[        R0                  " U5      U5      n[5        USS9nUUR7                  [        R8                  5      4$ )a  Quantize tensor to MXFP8 format with block-wise E8M0 scaling.

MXFP8 uses block size 32 with power-of-2 (E8M0) block scales.

Args:
    x: Input tensor (2D, shape M x K)
    output_type: FP8 output dtype (float8_e4m3fn)
    pad_32x: If True, pad dimensions to be divisible by 32

Returns:
    Tuple of (quantized_fp8_tensor, block_scales_e8m0)
    - quantized_fp8_tensor: FP8 data of shape (M, K) or padded shape
    - block_scales_e8m0: E8M0 scales of shape (M, K//32) in swizzled layout
r   zInput must be 2Dr   r   r   z!K dimension must be divisible by rP   rQ   g       8)r@      FrS   )rU   rR   r   r   rV   rW   rX   MXFP8_BLOCK_SIZErY   rZ   rD   r]   r   r$   rE   ceilr"   int32r   uint8r	   r1   r\   r^   r_   r   r   r`   float8_e8m0fnu)r   r   ra   rb   rc   rd   re   
num_blocks	x_blockedrg   scale_needed
log2_scale
exp_biasedblock_scales_e8m0block_scales_f32	zero_maskro   data_fp8rr   s                      r'   quantize_mxfp8r     sl   $ J557a<+++< WW
dB'dB'+"5##''A{/A1kFX+YZAJwwqz,,1i5VWgVh3ii1JD))J		$,<=Ijj9-26G==?[0L;;|;L L)JJ'**5;;7)CJZC0J"ekk2"#45 AI{{9eoo>N.OQab //#&6&@&@&DDK++i11"5u7G7G7TVabK ++kK<EK"":.11%2E2EFH Iu/?/?@Q/RTef   15AN^(()=)=>>>r)   c                 j   U R                   nUu  pEU[        -  nUR                  [        R                  5      n[        UUUS9n[        U5      n	U R                  [        R                  5      R                  XF[        5      n
XR                  S5      -  nUR                  U5      R                  U5      $ )zDequantize tensor from MXFP8 format.

Args:
    qx: Quantized FP8 tensor (float8_e4m3fn or float8_e5m2)
    block_scales: E8M0 block scales in swizzled layout (float8_e8m0fnu)
    output_type: Target output dtype

Returns:
    Dequantized tensor
rx   rP   )rU   r   r`   r   r   r
   r	   r"   r[   rY   r^   )ru   rv   r   ra   rb   rc   r   block_scales_uint8r   r   data_f32r   s               r'   dequantize_mxfp8r   G  s     JJD))J &**5;;7* ##:; uuU]]#++D>NOH  "<"<R"@@ ##J/22;??r)   c                     [        U UR                  5       UUUU[        R                  [        R                  [        R
                  [        R
                  S9
nU$ )a  MXFP8 matrix multiplication using block-wise E8M0 scales.

Computes: output = a @ b.T + bias (linear semantics)

Args:
    a: FP8 matrix A of shape (M, K)
    b: FP8 matrix B of shape (N, K) - will be transposed internally
    block_scale_a: E8M0 block scales for A in swizzled format
    block_scale_b: E8M0 block scales for B in swizzled format
    bias: Optional bias vector of shape (N,)
    out_dtype: Output dtype

Scales are expected to be in swizzled (SWIZZLE_32_4_4) format from quantize_mxfp8.
r   )r   r   r   BlockWise1x32r   r   )r   r   r   r   r   r   r   s          r'   scaled_mm_mxfp8r   o  sQ    , 		"00"00,,,,F Mr)   zcomfy_kitchen::quantize_fp8 )mutates_argsoutput_dtype_codec                 Z    SSK Jn  [        U   nXUS.nUR                  SUS9nU" S0 UD6$ )zQuantize tensor to FP8 format with per-tensor scaling.

Args:
    x: Input tensor
    scale: Scale tensor (scalar)
    output_dtype_code: FP8 dtype code (5=float8_e4m3fn, 6=float8_e5m2)

Returns:
    Quantized FP8 tensor
r   registryr   r   r   r(   kwargsr   comfy_kitchen.registryr   DTYPE_CODE_TO_DTYPEget_implementationr   r   r   r   output_dtyper   impls          r'   _op_quantize_fp8r     s>      0&'89L\BF&&'@&PD>&>r)   c                 <    [         U   n[        R                  " XS9$ r+   r   r   
empty_liker   r   r   r   s       r'   _op_quantize_fp8_faker         &'89LA22r)   zcomfy_kitchen::dequantize_fp8c                 Z    SSK Jn  [        U   nXUS.nUR                  SUS9nU" S0 UD6$ )a"  Dequantize tensor from FP8 format with per-tensor scaling.

Args:
    x: Input FP8 tensor (float8_e4m3fn or float8_e5m2)
    scale: Scale tensor (scalar)
    output_dtype_code: Target dtype code (0=float32, 1=float16, 2=bfloat16)

Returns:
    Dequantized tensor in specified output format
r   r   r   r.   r   r   r   r   s          r'   _op_dequantize_fp8r     s>      0&'89L\BF&&'B6&RD>&>r)   c                 <    [         U   n[        R                  " XS9$ r+   r   r   s       r'   _op_dequantize_fp8_faker     r   r)   zcomfy_kitchen::quantize_nvfp4c                 J    SSK Jn  XX#US.nUR                  SUS9nU" S0 UD6$ )a  Quantize tensor to NVFP4 format with block-wise scaling.

Args:
    x: Input tensor (2D)
    per_tensor_scale: Global scale factor
    epsilon: Epsilon for numerical stability
    pad_16x: If True, pad dimensions to be divisible by 16
    hi_first: If True, the even-indexed element is packed into the high nibble (default).
              If False, the even-indexed element goes into the low nibble.

Returns:
    Tuple of (quantized_tensor, block_scales)
r   r   )r   rJ   rK   rL   rM   rs   r   r   r   r   r   )r   rJ   rK   rL   rM   r   r   r   s           r'   _op_quantize_nvfp4r     s6    * 0wpxyF&&'7&GD>&>r)   c                 Z   U R                   u  pVU(       a  [        US5      n[        US5      n[        R                  " XVS-  4[        R                  U R
                  S9n[        US5      n[        US-  S5      n	[        R                  " X4[        R                  U R
                  S9n
Xz4$ )NrO   r   r#   r}      r<   )rU   r   r   emptyr   r}   r   )r   rJ   rK   rL   rM   rb   rc   qdata
scale_rows
scale_colsrv   s              r'   _op_quantize_nvfp4_faker     s    JDtR tR  KKqy)QXXNE s#JQ'J;;
7u?R?R[\[c[cdLr)   zcomfy_kitchen::dequantize_nvfp4c                 \    SSK Jn  [        U   nXX&US.nUR                  SUS9nU" S0 UD6$ )a  Dequantize tensor from NVFP4 format with block-wise scaling.

Args:
    qx: Quantized FP4 tensor (packed as uint8)
    per_tensor_scale: Global scale factor
    block_scales: Block scales in swizzled layout (float8_e4m3fn)
    output_dtype_code: Target dtype code (0=float32, 1=float16, 2=bfloat16)
    hi_first: If True, the high nibble is the even-indexed element (default).
              If False, the low nibble is the even-indexed element.

Returns:
    Dequantized tensor in specified output format
r   r   )ru   rJ   rv   r   rM   r   r   r   r   )	ru   rJ   rv   r   rM   r   r   r   r   s	            r'   _op_dequantize_nvfp4r     sH    * 0&'89Ll  FN  OF&&'9&&ID>&>r)   c                 v    [         U   nU R                  u  pg[        R                  " XgS-  4XPR                  S9$ )Nr   r   r   rU   r   r   r}   )ru   rJ   rv   r   rM   r   rb   cols_packeds           r'   _op_dequantize_nvfp4_faker   #  s5    &'89LD;;Ao.l99UUr)   zcomfy_kitchen::scaled_mm_nvfp4c	           
      `    SSK Jn	  [        U   n
XX#XEXjUS.	nU	R                  SUS9nU" S0 UD6$ )a[  Matrix multiplication with NVFP4 quantized inputs.

Computes: y = (a @ b.T) * (tensor_scale_a * tensor_scale_b) + bias

Args:
    a: Quantized matrix A (M, K//2) in uint8 format
    b: Quantized matrix B (N, K//2) in uint8 format
    tensor_scale_a: Global scale for A
    tensor_scale_b: Global scale for B
    block_scale_a: Block-wise scales for A
    block_scale_b: Block-wise scales for B
    bias: Optional bias vector
    output_dtype_code: Output dtype code (0=float32, 1=float16, 2=bfloat16)
    alpha: Output scale (tensor_scale_a * tensor_scale_b)

Returns:
    Result tensor of shape (M, N)
r   r   )	r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   s                r'   _op_scaled_mm_nvfp4r   +  sK    < 0#$56I(&u	F &&'8&HD>&>r)   c	                     [         U   n	U R                  S   n
UR                  S   n[        R                  " X4XR                  S9$ Nr   r   r   )r   r   r   r   r   r   r   r   r   r   mns               r'   _op_scaled_mm_nvfp4_faker   V  s@    
 $$56I	
A	
A;;vYxx@@r)   zcomfy_kitchen::quantize_mxfp8c                 F    SSK Jn  XS.nUR                  SUS9nU" S0 UD6$ )a&  Quantize tensor to MXFP8 format with block-wise E8M0 scaling.

MXFP8 uses block size 32 with power-of-2 (E8M0) block scales.

Args:
    x: Input tensor (2D, shape M x K)
    pad_32x: If True, pad dimensions to be divisible by 32

Returns:
    Tuple of (quantized_fp8_tensor, block_scales_e8m0)
r   r   )r   r   r   r   r   r   )r   r   r   r   r   s        r'   _op_quantize_mxfp8r   e  s1      0)F&&'7&GD>&>r)   c                 X   U R                   u  p#U(       a  [        US5      n[        US5      n[        R                  " X#4[        R                  U R
                  S9nUS-  n[        US5      n[        US5      n[        R                  " Xg4[        R                  U R
                  S9nXH4$ )Nr   r   r   r<   )rU   r   r   r   r   r}   r   )	r   r   rb   rc   r   r   r   r   rv   s	            r'   _op_quantize_mxfp8_faker   |  s    JDtR tR  KKE,?,?QE Js#JQ'J;;
7u?S?S\]\d\deLr)   zcomfy_kitchen::dequantize_mxfp8c                 Z    SSK Jn  [        U   nXUS.nUR                  SUS9nU" S0 UD6$ )a)  Dequantize tensor from MXFP8 format.

Args:
    qx: Quantized FP8 tensor (float8_e4m3fn)
    block_scales: E8M0 block scales in swizzled layout (float8_e8m0fnu)
    output_dtype_code: Target dtype code (0=float32, 1=float16, 2=bfloat16)

Returns:
    Dequantized tensor in specified output format
r   r   )ru   rv   r   r   r   r   r   )ru   rv   r   r   r   r   r   s          r'   _op_dequantize_mxfp8r     s>      0&'89L\RF&&'9&&ID>&>r)   c                 <    [         U   n[        R                  " XS9$ r+   r   )ru   rv   r   r   s       r'   _op_dequantize_mxfp8_faker     s    &'89LB33r)   zcomfy_kitchen::scaled_mm_mxfp8c                 \    SSK Jn  [        U   nXX#XGS.nUR                  SUS9n	U	" S0 UD6$ )a  Matrix multiplication with MXFP8 quantized inputs.

Computes: y = a @ b.T + bias

Args:
    a: Quantized FP8 matrix A (M, K)
    b: Quantized FP8 matrix B (N, K)
    block_scale_a: E8M0 block scales for A in swizzled layout
    block_scale_b: E8M0 block scales for B in swizzled layout
    bias: Optional bias vector
    output_dtype_code: Output dtype code (0=float32, 1=float16, 2=bfloat16)

Returns:
    Result tensor of shape (M, N)
r   r   )r   r   r   r   r   r   r   r   r   r   )
r   r   r   r   r   r   r   r   r   r   s
             r'   _op_scaled_mm_mxfp8r     sF    0 0#$56I&F
 &&'8&HD>&>r)   c                     [         U   nU R                  S   nUR                  S   n[        R                  " Xx4X`R                  S9$ r   r   )	r   r   r   r   r   r   r   r   r   s	            r'   _op_scaled_mm_mxfp8_faker     s@     $$56I	
A	
A;;vYxx@@r)   )rt   FT)NNN)F)NN)Ar   comfy_kitchen.float_utilsr   r   r   r   r   r   r	   r
   r   r   r   comfy_kitchen.scaled_mm_v2r   r   r   r[   float16bfloat16r   r    r   itemsDTYPE_TO_CODETensorr#   r(   r.   r:   rI   r]   booltuplers   tensorr^   r~   r{   r   r   r   r   r   r   library	custom_opr   r   register_faker   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )kvs   00r'   <module>r     sV       N M }}}}~~  #6";";"=>"=$!"=> FKEXEX || !LL 7<{{ 
\\ " FK^^||!LL7<{{
\\8  %22% ||% 	%  %  \\	% V -#||-#ll-# -# 	-#
 -# 5<<%&-#` <<   9Q< 	
   %~~00ll0 ,,0 	0
 0 \\0t !%$(!%|||| LL LL	
 << << ,,
 {{T! <<$ \\@  
 C?||C?C? 5<<%&C?R  %~~%@%@,,%@ %@ \\	%@Z !%$(#||#||# <<# <<	#
 ,,
# {{T!# \\#X 6RH||<<  \\	 I. 3  3
 8rJ||<<  \\	 K. !!3 "3
 8rJ||ll  	
  5<<%& K6 !! "$ :Lll ,, 	
  \\ M8 ##V $V 9K'||'||' LL' LL	'
 <<' <<' ,,
' ' <<$' \\' L'T ""A #A 8rJ|| 5<<%& K, !! "( :L,,  \\	 M. ##4 $4
 9K || ||  <<  <<	 
 ,,
    \\  L F ""A #A[ ?s   6[