
    kh_                     >   d dl Z d dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
 d dlZd dlmZ d dlmc mZ d dl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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e	e*e*f   fdZ+dejX                  de	e*e*f   de	e*e*f   fdZ-de*de*de	e*e*f   de	e*e*e*e*f   fdZ. G d dej^                        Z0 G d dej^                        Z1 G d dej^                        Z2 G d dej^                        Z3d1dZ4 e( e4d       e4d       e4d       e4d       e4d       e4d       e4dd d!d"#       e4dd d!d"#       e4d$d d%&      d'	      Z5d2d(Z6d3d)e7d*e8de3fd+Z9e)d3d,       Z:e)d3d-       Z;e)d3d.       Z<e)d3d/       Z=e)d3d0       Z>y)4    N)deepcopy)partial)DictListOptionalTupleUnionIMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STD)
PatchEmbedMlpDropPathClNormMlpClassifierHead
LayerScaleget_norm_layerget_act_layerinit_weight_jaxinit_weight_vit	to_2tupleuse_fused_attn   )build_model_with_cfg)feature_take_indices)named_apply
checkpoint)generate_default_cfgsregister_modelwindow_sizec                     | j                   \  }}}}| j                  |||d   z  |d   ||d   z  |d   |      } | j                  dddddd      j                         j                  d|d   |d   |      }|S )aT  
    Partition into non-overlapping windows with padding if needed.
    Args:
        x (tensor): input tokens with [B, H, W, C].
        window_size (int): window size.
    Returns:
        windows: windows after partition with [B * num_windows, window_size, window_size, C].
        (Hp, Wp): padded height and width before partition
    r   r               shapeviewpermute
contiguous)xr   BHWCwindowss          U/var/www/teggl/fontify/venv/lib/python3.12/site-packages/timm/models/hieradet_sam2.pywindow_partitionr2      s     JAq!Q	q!{1~%{1~qKN7JKXYN\]^Aii1aAq)446;;BAP[\]P^`abGN    r0   hwc                    |\  }}| j                   d   ||z  |d   z  |d   z  z  }| j                  |||d   z  ||d   z  |d   |d   d      }|j                  dddddd      j                         j                  |||d      }|S )aZ  
    Window unpartition into original sequences and removing padding.
    Args:
        x (tensor): input tokens with [B * num_windows, window_size, window_size, C].
        window_size (int): window size.
        hw (Tuple): original height and width (H, W) before padding.
    Returns:
        x: unpartitioned sequences with [B, H, W, C].
    r   r   r%   r!   r"   r#   r$   r&   )r0   r   r4   r-   r.   r,   r+   s          r1   window_unpartitionr6   $   s     DAqaQUk!n4AFGAQ[^+Q+a.-@+a.R]^_R`bdeA			!Q1a#..055aArBAHr3   r-   r.   returnc                 r    |d   | |d   z  z
  |d   z  }|d   ||d   z  z
  |d   z  }| |z   ||z   }}||||fS )Nr   r    )r-   r.   r   pad_hpad_wHpWps          r1   	_calc_padr>   5   sb    ^a+a.00KNBE^a+a.00KNBEYE	Br5%r3   c            	            e Zd ZU ej                  j
                  e   ed<   	 d
dededede	j                  f fdZdej                  dej                  fd	Z xZS )MultiScaleAttention
fused_attndimdim_out	num_headsq_poolc                    t         |           || _        || _        || _        ||z  }|dz  | _        t               | _        || _        t        j                  ||dz        | _        t        j                  ||      | _        y )Ng      r!   )super__init__rB   rC   rD   scaler   rA   rE   nnLinearqkvproj)selfrB   rC   rD   rE   head_dim	__class__s         r1   rH   zMultiScaleAttention.__init__?   st     	"i'%
(*99S'A+.IIgw/	r3   r+   r7   c                 b   |j                   \  }}}}| j                  |      j                  |||z  d| j                  d      }t	        j
                  |d      \  }}}	| j                  ||j                  |||d      j                  dddd      }| j                  |      j                  dddd      }|j                   dd \  }}|j                  |||z  | j                  d      }|j                  dd      }|j                  dd      }|	j                  dd      }	| j                  rt        j                  |||	      }n;|| j                  z  }||j                  dd      z  }
|
j                  d      }
|
|	z  }|j                  dd      j                  |||d      }| j                  |      }|S )Nr!   r%   r"   r   r   )rB   )r'   rL   reshaperD   torchunbindrE   r)   	transposerA   Fscaled_dot_product_attentionrI   softmaxrM   )rN   r+   r,   r-   r.   _rL   qkvattns              r1   forwardzMultiScaleAttention.forwardR   s   WW
1a hhqk!!!QUAt~~rB ,,sA&1a ;;"		!Q2&..q!Q:AA&&q!Q2A771Q<DAq		!QUDNNB7A KK1KK1KK1??..q!Q7ADJJAq{{2r**D<<B<'DqA KK1%%aAr2IIaLr3   N)__name__
__module____qualname__rT   jitFinalbool__annotations__intrJ   ModulerH   Tensorr_   __classcell__rP   s   @r1   r@   r@   <   se    		%% !00 0 	0
 		0&   %,,  r3   r@   c                        e Zd Z	 	 	 	 	 	 	 ddededededeeeef      deej                  e
f   deej                  e
f   ded	ee   d
ef fdZdej                  dej                  fdZ xZS )MultiScaleBlockrB   rC   rD   	mlp_ratioq_stride
norm_layer	act_layerr   init_values	drop_pathc                    t         |           t        |      }t        |      }t	        |      | _        t        | j
                        | _        || _        || _	        || _
        ||k7  rt        j                  ||      | _        nt        j                         | _        d | _        | j                  rt        j                   ||d      | _         ||      | _        t%        |||t'        | j                              | _        |	t+        ||	      nt        j                         | _        |
dkD  rt/        |
      nt        j                         | _         ||      | _        t5        |t7        ||z        |      | _        |	t+        ||	      nt        j                         | _        |
dkD  rt/        |
      | _        y t        j                         | _        y )NF)kernel_sizestride	ceil_mode)rD   rE           )rr   )rG   rH   r   r   r   r   anyis_windowedrB   rC   rp   rJ   rK   rM   Identitypool	MaxPool2dnorm1r@   r   r^   r   ls1r   
drop_path1norm2r   rh   mlpls2
drop_path2)rN   rB   rC   rD   ro   rp   rq   rr   r   rs   rt   rP   s              r1   rH   zMultiScaleBlock.__init__v   s{    	#J/
!),	$[1t//0 '>		#w/DIDI	==$DI  _
'DII&	
	 8C7N:g{3TVT_T_Ta1:S(9-bkkm(
)#$

 8C7N:g{3TVT_T_Ta1:S(9-bkkmr3   r+   r7   c           
         |}| j                  |      }| j                  | j                  k7  rT| j                  |      }| j                  7|j                  dddd      }| j	                  |      j                  dddd      }| j                  }|j                  dd \  }}||}}| j                  r:t        |||      \  }}}}	t        j                  |ddd|	d|f      }t        ||      }| j                  |      }| j                  b| j                  d   | j                  d   z  | j                  d   | j                  d   z  f}|j                  dd \  }}t        |||      \  }}}}	| j                  r.t        ||||f      }|d d d |d |d d f   j!                         }|| j#                  | j%                  |            z   }|| j'                  | j)                  | j+                  | j-                  |                        z   }|S )Nr   r!   r   r"   )r   rB   rC   rM   r}   r)   r   r'   r{   r>   rW   padr2   r^   rp   r6   r*   r   r   r   r   r   r   )
rN   r+   shortcutr   r-   r.   r<   r=   r:   r;   s
             r1   r_   zMultiScaleBlock.forward   s   JJqM 88t||#yy|Hyy$#++Aq!Q799X.66q!QB &&wwq|1AB#,Q;#? BE5a!Q5!U34A K0A IIaL==$++A.$--2BBDDTDTUVDW[_[h[hij[kDklK>>!A&DAq#,Q;#? BE5 "1kB8<A!RaR!Q,**,Attxx{33$**Q-)@ ABBr3   )g      @N	LayerNormGELUr   Nry   )ra   rb   rc   rh   floatr   r   r	   rJ   ri   strrH   rT   rj   r_   rk   rl   s   @r1   rn   rn   u   s     .2,7+1'+4T4T 4T 	4T
 4T 5c?+4T "))S.)4T C(4T 4T e_4T 4Tl# #%,, #r3   rn   c                        e Zd ZdZ	 	 	 	 	 ddeedf   deedf   deedf   dedef
 fdZd	ej                  d
ej                  fdZ	 xZ
S )HieraPatchEmbedz#
    Image to Patch Embedding.
    rv   .rw   paddingin_chans	embed_dimc                 `    t         |           t        j                  |||||      | _        y)ab  
        Args:
            kernel_size (Tuple): kernel size of the projection layer.
            stride (Tuple): stride of the projection layer.
            padding (Tuple): padding size of the projection layer.
            in_chans (int): Number of input image channels.
            embed_dim (int):  embed_dim (int): Patch embedding dimension.
        )rv   rw   r   N)rG   rH   rJ   Conv2drM   )rN   rv   rw   r   r   r   rP   s         r1   rH   zHieraPatchEmbed.__init__   s,      	IIi[QX
	r3   r+   r7   c                 P    | j                  |      }|j                  dddd      }|S )Nr   r"   r!   r   )rM   r)   rN   r+   s     r1   r_   zHieraPatchEmbed.forward   s(    IIaLIIaAq!r3   )   r   r#   r#   r!   r!   r!   i   )ra   rb   rc   __doc__r   rh   rH   rT   rj   r_   rk   rl   s   @r1   r   r      s     (."(#)
38_
 c3h
 sCx	

 
 
* %,, r3   r   c            5       4    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d7dedededededeed	f   d
eed	f   deed	f   deeed	f      dedeeef   deed	f   dededeeef   deed	f   deed	f   dee   dede	dededede
ej                  ef   de
ej                  ef   f2 fdZdej                  dej                  fd Zd! Zej$                  j&                  d"        Zej$                  j&                  d8d#e	defd$       Zej$                  j&                  d9d%e	ddfd&       Zej$                  j&                  d'        Zd:dedee   d(e	fd)Z	 	 	 	 	 	 d;dej                  d*ee
eee   f      d+e	d,e	d-ed.e	d#e	de
eej                     eej                  eej                     f   f   fd/Z	 	 	 	 d<d*e
eee   f   d0e	d1e	d#e	fd2Zdej                  dej                  fd3Zd8d4e	dej                  fd5Zdej                  dej                  fd6Z xZ S )=HieraDetz5
    Reference: https://arxiv.org/abs/2306.00989
    Nr   num_classesglobal_poolr   rD   patch_kernel.patch_stridepatch_padding
patch_sizerE   rp   stagesdim_mulhead_mulglobal_pos_sizewindow_specglobal_att_blocksrs   weight_initfix_inithead_init_scale	drop_ratedrop_path_raterq   rr   c                 V	   t         #|           t        |      }t        |      }t	        |      t	        |      k(  sJ d| _        || _        || _        d| _        t        |      }|| _
        t        dt	        |      dz         D cg c]  }t        |d |       dz
   c}| _        d|
cxk  rt	        | j                  d d       k  sJ  J | j                  d d D cg c]  }|dz   	 c}d |
 | _        |	t        d |	||dd      | _        nt!        |||||      | _        || _        || _        t'        j(                  t+        j,                  d|g| j$                         | _        t'        j(                  t+        j,                  d|| j                  d   | j                  d               | _        t+        j2                  d||      D cg c]  }|j5                          }}d}t'        j6                         | _        g | _        t        |      D ]  }|}| j                  |   } | j"                  || j"                  v rdn| } |dz
  | j                  v r!t=        ||z        }t=        ||z        }|dz  }t?        |||||   || j                  v r| j                  nd | ||	      }!|}| j8                  jA                  |!       || j                  v s| xj:                  tC        |d
|d
z   z  d| j                  |          gz  c_         |x| _"        | _#        tI        |||||      | _%        | j.                  +t&        jL                  jO                  | j.                  d       | j0                  +t&        jL                  jO                  | j0                  d       |dk7  r*|dk(  rtP        ntR        }"tU        |"d      }"tW        |"|        |r| jY                          t[        | jJ                  tH              rt[        | jJ                  j\                  t&        j^                        rs| jJ                  j\                  j`                  jb                  je                  |       | jJ                  j\                  jf                  jb                  je                  |       y y y c c}w c c}w c c}w )NFNHWCr   r   r%   T)img_sizer   r   r   
output_fmtdynamic_img_pad)rv   rw   r   r   r   )rB   rC   rD   rt   rp   r   rq   rr   r"   zblocks.)num_chs	reductionmodule)	pool_typer   rq   g{Gz?)stdskipjaxhead.fc)classifier_name)4rG   rH   r   r   lengrad_checkpointingr   r   r   sumrp   range
stage_endsq_pool_blocksr   patch_embedr   r   r   rJ   	ParameterrT   zeros	pos_embedpos_embed_windowlinspaceitem
Sequentialblocksfeature_inforh   rn   appenddictnum_featureshead_hidden_sizer   headinittrunc_normal_r   r   r   r   fix_init_weight
isinstancefcrK   weightdatamul_bias)$rN   r   r   r   r   rD   r   r   r   r   rE   rp   r   r   r   r   r   r   rs   r   r   r   r   r   rq   rr   depthir+   dpr	cur_stagerC   r   blockinit_fnrP   s$                                      r1   rH   zHieraDet.__init__   sC   N 	#J/
!),	6{c+...."'&& F 8=aVq8QR13vbqz?Q.RF7c$//#2"6777777-1__Sb-ABa!eB7FK!)%!#! $ D  /(#%!# D "3  /ekk!Y&VAUAU&VW "U[[ItGWGWXYGZ\`\l\lmn\o-p q!&>5!IJAqvvxJJ	mmou 	vAG **95K%%1#$(>(>#>aK1u'i'12	H 45	Q	##a&*+t/A/A*At'%#	E  IKKu%DOO#!!A	!4DwW[WfWfgpWqVrMst&v v!;	v@ 5>=D1+!!
	 >>%GG!!$..d!;  ,GG!!$"7"7T!B& )4)=o?GgyAG&  "dii!89jWYW`W`>aIILL$$))/:IILL""''8 ?b9u SB8 Ks   RR!R&r+   r7   c                 `   |j                   dd \  }}| j                  }t        j                  | j                  ||fd      }|j                   d   |j                   d   z  }|j                   d   |j                   d   z  }||j                  ||f      z   }|j                  dddd      }||z   S )	Nr   r!   bicubic)sizemoderR   r%   r   r"   )r'   r   rW   interpolater   tiler)   )rN   r+   hwwindow_embedr   tile_htile_ws           r1   
_pos_embedzHieraDet._pos_embed  s    wwq|1,,MM$..1vIN	$(:(:2(>>$(:(:2(>> 1 1662B CC	%%aAq1	9}r3   c                    d }t        | j                        D ]m  \  }} ||j                  j                  j                  j
                  |dz           ||j                  j                  j                  j
                  |dz          o y )Nc                 R    | j                  t        j                  d|z               y )N       @)div_mathsqrt)param	_layer_ids     r1   rescalez)HieraDet.fix_init_weight.<locals>.rescale  s    JJtyyy12r3   r   )	enumerater   r^   rM   r   r   r   fc2)rN   r   layer_idlayers       r1   r   zHieraDet.fix_init_weight  si    	3  )5 	=OHeEJJOO**//A>EIIMM((--x!|<	=r3   c                 
    ddgS )Nr   r   r9   rN   s    r1   no_weight_decayzHieraDet.no_weight_decay  s    /00r3   coarsec                     t        ddg      S )Nz'^pos_embed|pos_embed_window|patch_embed)z^blocks\.(\d+)N)stemr   )r   )rN   r   s     r1   group_matcherzHieraDet.group_matcher  s    ;-.
 	
r3   enablec                     || _         y r`   )r   )rN   r   s     r1   set_grad_checkpointingzHieraDet.set_grad_checkpointing  s
    "(r3   c                 .    | j                   j                  S r`   )r   r   r   s    r1   get_classifierzHieraDet.get_classifier  s    yy||r3   reset_otherc                 N    || _         | j                  j                  |||       y )N)r   r  )r   r   reset)rN   r   r   r  s       r1   reset_classifierzHieraDet.reset_classifier  s     &		{Tr3   indicesnorm
stop_earlyr   intermediates_onlyc                    |rJ d       |dv sJ d       |rNt        t        | j                        |      \  }}	|D 
cg c]  }
| j                  |
    }}
| j                  |	   }	n"t        t        | j                        |      \  }}	| j	                  |      }| j                  |      }g }t        j                  j                         s|s| j                  }n| j                  d|	dz    }t        |      D ]u  \  }
}| j                  r+t        j                  j                         st        ||      }n ||      }|
|v sJ|dk(  r|j                  dddd	      n|}|j                  |       w |r|S ||fS c c}
w )
aE   Forward features that returns intermediates.

        Args:
            x: Input image tensor
            indices: Take last n blocks if int, all if None, select matching indices if sequence
            norm: Apply norm layer to all intermediates
            stop_early: Stop iterating over blocks when last desired intermediate hit
            output_fmt: Shape of intermediate feature outputs
            intermediates_only: Only return intermediate features
            coarse: Take coarse features (stage ends) if true, otherwise all block featrures
        Returns:

        z'normalization of features not supported)NCHWr   z(Output format must be one of NCHW, NHWC.Nr   r  r   r!   r"   )r   r   r   r   r   r   rT   rd   is_scriptingr   r   r   r)   r   )rN   r+   r	  r
  r  r   r  r   take_indices	max_indexr   intermediatesr   blkx_outs                  r1   forward_intermediateszHieraDet.forward_intermediates  so   . BBBx--Y/YY-&:3t;OQX&Y#L)8DE1DOOA.ELE	2I&:3t{{;KW&U#L)QOOA99!!#:[[F[[)a-0F' 	,FAs&&uyy/E/E/GsA&FL 1;v1E		!Q1-1$$U+	,   -3 Fs   E5
prune_norm
prune_headc                    |r2t        t        | j                        |      \  }}| j                  |   }n"t        t        | j                        |      \  }}| j                  d|dz    | _        |r| j                  j                  d|       |S )z@ Prune layers not required for specified intermediates.
        Nr   r   )r  )r   r   r   r   r   r  )rN   r	  r  r  r   r  r  s          r1   prune_intermediate_layersz"HieraDet.prune_intermediate_layers  s}     &:3t;OQX&Y#L)	2I&:3t{{;KW&U#L)kk.9q=1IIOOA:O6r3   c                     | j                  |      }| j                  |      }| j                  D ]A  }| j                  r+t        j
                  j                         st        ||      }: ||      }C |S r`   )r   r   r   r   rT   rd   r  r   )rN   r+   r  s      r1   forward_featureszHieraDet.forward_features  sg    QOOA;; 	C&&uyy/E/E/GsA&F		
 r3   
pre_logitsc                 V    |r| j                  ||      }|S | j                  |      }|S )N)r  )r   )rN   r+   r  s      r1   forward_headzHieraDet.forward_head  s1    3=DIIaJI/ DH99Q<r3   c                 J    | j                  |      }| j                  |      }|S r`   )r  r  r   s     r1   r_   zHieraDet.forward  s'    !!!$a r3   )r!     avg`   r   r   r   r   Nr!   )r"   r"   )r"   r!      r!   r   r   r   )   r#      r   )   r#     N TgMbP?ry   ry   r   r   F)T)NF)NFTr  FT)r   FTT)!ra   rb   rc   r   rh   r   r   r   r   rf   r	   rJ   ri   rH   rT   rj   r   r   rd   ignorer   r   r   r  r  r  r   r  r  r  r  r_   rk   rl   s   @r1   r   r      s    #$,2,2-348(.&3 !/5,2
 ,0!!%*"$'0;/5KN9N9 N9 	N9
 N9 N9  S/N9  S/N9 !c?N9 !sCx1N9 N9 CHoN9 #s(ON9 N9 N9  #38_!N9$ sCx%N92  %S#X3N9< "%=N9> ?N9@ AN9B #CN9D EN9F "GN9H biin-IN9J RYY^,KN9`ELL U\\ = YY1 1 YY
D 
T 
 
 YY)T )T ) ) YY UC Uhsm Uae U 8<#$',4 ||4  eCcN344  	4 
 4  4  !%4  4  
tELL!5tELL7I)I#JJ	K4 p ./$#3S	>*  	
 &%,, 5<< $ 5<<  %,, r3   r   c                 2    | ddddddt         t        ddd	|S )
Nr   )r!     r,  )   r-  g      ?r   )r!      r.  zpatch_embed.projr   )urlr   
input_size	pool_sizecrop_pctinterpolationmin_input_sizemeanr   
first_conv
classifierr
   )r/  kwargss     r1   _cfgr9    s2    H)}%.B(	  r3   ztimm/)	hf_hub_id)r!      r;  )r!      r<  )    r=  )r:  r4  r0  r1  r   )r$  r$  )r   r0  r1  )	zsam2_hiera_tiny.fb_r896zsam2_hiera_tiny.fb_r896_2pt1zsam2_hiera_small.fb_r896zsam2_hiera_small.fb_r896_2pt1zsam2_hiera_base_plus.fb_r896z!sam2_hiera_base_plus.fb_r896_2pt1zsam2_hiera_large.fb_r1024zsam2_hiera_large.fb_r1024_2pt1zhieradet_small.untrainedc                     | j                  d|       } i }| j                         D ]S  \  }}|j                  |      r|j                  |d      }n+|j                  dd      }|j                  dd      }|||<   U |S )Nmodelr(  zmlp.layers.0zmlp.fc1zmlp.layers.1zmlp.fc2)getitems
startswithreplace)
state_dictr?  prefixoutputr\   r]   s         r1   checkpoint_filter_fnrG  N  s    4JF  " 1<<		&"%AIIni0IIni0q	 Mr3   variant
pretrainedc                     |j                  dd      }d}t        t        | |ft        t        |      t        |d      d|S )Nout_indicesr#   r(  )rE  getter)rK  feature_cls)pretrained_filter_fnfeature_cfg)popr   r   r   rG  r   )rH  rI  r8  rK  checkpoint_prefixs        r1   _create_hiera_detrR  ]  sW    **]A.K   %%9BST[hG  r3   c           	      J    t        dd      }t        dd| it        |fi |S )N)r   r"   r   r"   )r$   r   	   r   r   rI  )sam2_hiera_tinyr   rR  rI  r8  
model_argss      r1   rV  rV  o  s,    \YGJd:djIc\bIcddr3   c           	      J    t        dd      }t        dd| it        |fi |S )Nr   r"      r"   r   
      rU  rI  )sam2_hiera_smallrW  rX  s      r1   r`  r`  u  s,    ]kJJeJe$zJd]cJdeer3   c           	      L    t        ddd      }t        dd| it        |fi |S )Np   r"   )r%  r%  )r   rD   r   rI  )sam2_hiera_base_plusrW  rX  s      r1   rc  rc  {  s/    q(KJi
idS]NhagNhiir3   c           	      P    t        ddddd      }t        dd| it        |fi |S )	N   r"   )r"      $   r#   )   !   +   r$  r#   r#  r$  )r   rD   r   r   r   rI  )sam2_hiera_largerW  rX  s      r1   rl  rl    s;    &!J eJe$zJd]cJdeer3   c           	      N    t        dddd      }t        dd| it        |fi |S )Nr[  r]  rk  gh㈵>)r   r   r   rs   rI  )hieradet_smallrW  rX  s      r1   rn  rn    s2    ]kWdrvwJc*cZHb[aHbccr3   )r(  )Nr(  r)  )?r   copyr   	functoolsr   typingr   r   r   r   r	   rT   torch.nnrJ   torch.nn.functional
functionalrW   	timm.datar   r   timm.layersr   r   r   r   r   r   r   r   r   r   r   _builderr   	_featuresr   _manipulater   r   	_registryr   r   rh   r2   rj   r6   r>   ri   r@   rn   r   r   r9  default_cfgsrG  r   rf   rR  rV  r`  rc  rl  rn  r9   r3   r1   <module>r|     sM      5 5     A_ _ _ _ + + 0 <U38_   5c? PUVY[^V^P_ "     5c?  uS#sTWEW?X  6")) 6rZbii Zzbii BXryy Xx %#  
 %) %
 !% !
 &* &
 %) %
 *. *
 "& $"h" '+ $"h' !% F![1& 1hs  8 $ e e
 f f
 j j
 f f d dr3   