
    NgU              
       6   d Z ddlZddlmZ ddl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 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" dgZ#ee$e$f         Z%e G d dej&                              Z' G d dej&                  Z( G d dej&                  Z) G d dej&                  Z* G d dej&                  Z+ G d dej&                  Z,d'dZ-d(dZ. e  e.d           e.d           e.d           e.d           e.d           e.d          d          Z/ed'd e,fd!            Z0ed'd e,fd"            Z1ed'd e,fd#            Z2ed'd e,fd$            Z3ed'd e,fd%            Z4ed'd e,fd&            Z5dS ))z Twins
A PyTorch impl of : `Twins: Revisiting the Design of Spatial Attention in Vision Transformers`
    - https://arxiv.org/pdf/2104.13840.pdf

Code/weights from https://github.com/Meituan-AutoML/Twins, original copyright/license info below

    N)partial)ListOptionalTupleUnionIMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STD)MlpDropPath	to_2tupletrunc_normal_use_fused_attn   )build_model_with_cfg)feature_take_indices)register_notrace_module)register_modelgenerate_default_cfgs)	AttentionTwinsc                   \     e Zd ZU dZej        j        e         ed<   d	 fd	Z	de
fdZ xZS )
LocallyGroupedAttnz( LSA: self attention within a group
    
fused_attn           r   c                    |dk    sJ t          t          |                                            ||z  dk    sJ d| d| d            || _        || _        ||z  }|dz  | _        t                      | _        t          j	        ||dz  d	          | _
        t          j        |          | _        t          j	        ||          | _        t          j        |          | _        || _        d S )
Nr   r   dim   should be divided by num_heads .         Tbias)superr   __init__dim	num_headsscaler   r   nnLinearqkvDropout	attn_dropproj	proj_dropws)selfr'   r(   r.   r0   r1   head_dim	__class__s          M/var/www/html/ai-engine/env/lib/python3.11/site-packages/timm/models/twins.pyr&   zLocallyGroupedAttn.__init__)   s    Qwwww $''00222Y!###%]C%]%]QZ%]%]%]###")#%
(**9S#'555I..Ic3''	I..    sizec           	      |   |j         \  }}}|\  }}|                    ||||          }dx}}	| j        || j        z  z
  | j        z  }
| j        || j        z  z
  | j        z  }t          j        |dd||
|	|f          }|j         \  }}}}|| j        z  || j        z  }}|                    ||| j        || j        |                              dd          }|                     |                              |||z  | j        | j        z  d| j        || j        z            	                    dddddd          }|
                    d          \  }}}| j        r,t          j        |||| j        r| j        j        nd          }nS|| j        z  }||                    d	d
          z  }|                    d
          }|                     |          }||z  }|                    dd                              |||| j        | j        |          }|                    dd                              ||| j        z  || j        z  |          }|
dk    s|dk    r&|d d d |d |d d f                                         }|                    |||          }|                     |          }|                     |          }|S )Nr      r"   r         r   	dropout_pr'   )shapeviewr1   Fpadreshape	transposer,   r(   permuteunbindr   scaled_dot_product_attentiontrainingr.   pr)   softmax
contiguousr/   r0   )r2   xr7   BNCHWpad_lpad_tpad_rpad_b_HpWp_h_wr,   qkvattns                         r5   forwardzLocallyGroupedAttn.forward:   s    '1a1FF1aA1tw;&$'11tw;&$'1E!aE5%788w2r1twdgBIIaTWb$'155??1EEhhqkk!!rBw$')1dna4>>QS SSZSZ[\^_abdeghjkSlSl 	**Q--1a? 
	.1a.2mC$.**  AA
 DJAq{{2r***D<<B<''D>>$''DqAKK1%%aR$'1EEKK1%%adgrDG|QGG199		!!!RaR!QQQ,**,,AIIaAIIaLLNN1r6   r   r   r   r   __name__
__module____qualname____doc__torchjitFinalbool__annotations__r&   Size_ra   __classcell__r4   s   @r5   r   r   #   sy          	%%%%     "%u % % % % % % % %r6   r   c                   \     e Zd ZU dZej        j        e         ed<   d	 fd	Z	de
fdZ xZS )
GlobalSubSampleAttnzQ GSA: using a  key to summarize the information for a group to be efficient.
    r   r   r   r   c                    t                                                       ||z  dk    sJ d| d| d            || _        || _        ||z  }|dz  | _        t                      | _        t          j        ||d          | _	        t          j        ||dz  d          | _
        t          j        |          | _        t          j        ||          | _        t          j        |          | _        || _        |d	k    r8t          j        ||||
          | _        t          j        |          | _        d S d | _        d | _        d S )Nr   r   r   r    r!   Tr#   r9   r   kernel_sizestride)r%   r&   r'   r(   r)   r   r   r*   r+   r]   kvr-   r.   r/   r0   sr_ratioConv2dsr	LayerNormnorm)r2   r'   r(   r.   r0   rw   r3   r4   s          r5   r&   zGlobalSubSampleAttn.__init__   s6   Y!###%]C%]%]QZ%]%]%]###")#%
(**3$///)Cqt444I..Ic3''	I.. a<<iShxPPPDGS))DIIIDGDIIIr6   r7   c                 \   |j         \  }}}|                     |                              ||| j        || j        z                                dddd          }| j        x |                    ddd          j        ||g|R  }|                     |                              ||d                              ddd          }|                     |          }|                     |                              |dd| j        || j        z                                ddddd          }|                    d          \  }}	| j	        r<t          j        j                            |||	| j        r| j        j        nd          }nS|| j        z  }||                    d	d          z  }
|
                    d
          }
|                     |
          }
|
|	z  }|                    dd                              |||          }|                     |          }|                     |          }|S )Nr   r9   r   r"   r?   r:   r   r<   r>   r@   )rA   r]   rE   r(   rG   ry   r{   rv   rH   r   rh   r*   
functionalrI   rJ   r.   rK   r)   rF   rL   r/   r0   )r2   rN   r7   rO   rP   rQ   r]   rv   r^   r_   r`   s              r5   ra   zGlobalSubSampleAttn.forward   s   '1aFF1IIaDNA4GHHPPQRTUWXZ[\\7*		!Q""*1a7$777A

""1a,,44Q1==A		!AWWQZZ2q$.!t~:MNNVVWXZ[]^`acdeeyy||1? 
	#@@1a.2mC$.** A  AA
 DJAq{{2r***D<<B<''D>>$''DqAKK1%%aA..IIaLLNN1r6   rb   rc   ro   s   @r5   rq   rq      sy          	%%%%     0u        r6   rq   c                   P     e Zd Zddddej        ej        ddf fd	ZdefdZ xZ	S )Blockg      @r   r   Nc                 2   t                                                        ||          | _        |
t          ||dd ||          | _        n7|
dk    rt          |||||	          | _        nt          |||||
          | _        |dk    rt          |          nt          j	                    | _
         ||          | _        t          |t          ||z            ||          | _        |dk    rt          |          nt          j	                    | _        d S )NFr   r   )in_featureshidden_features	act_layerdrop)r%   r&   norm1r   r`   rq   r   r   r*   Identity
drop_path1norm2r   intmlp
drop_path2)r2   r'   r(   	mlp_ratior0   r.   	drop_pathr   
norm_layerrw   r1   r4   s              r5   r&   zBlock.__init__   s    	Z__
:!#y%y)TTDII1WW+CIyRZ[[DII*3	9iQSTTDI1:R(9---R[]]Z__
i00	
 
 
 2;R(9---R[]]r6   r7   c                     ||                      |                     |                     |          |                    z   }||                     |                     |                     |                              z   }|S N)r   r`   r   r   r   r   )r2   rN   r7   s      r5   ra   zBlock.forward   sa    		$**Q-- > >???A 7 7888r6   )
rd   re   rf   r*   GELUrz   r&   rm   ra   rn   ro   s   @r5   r   r      s}         g|S S S S S S@u        r6   r   c                   2     e Zd Zd fd	ZdefdZd Z xZS )PosConv   r   c                     t          t          |                                            t          j        t          j        ||d|dd|                    | _        || _        d S )Nr"   r   T)r$   groups)r%   r   r&   r*   
Sequentialrx   r/   ru   )r2   in_chans	embed_dimru   r4   s       r5   r&   zPosConv.__init__   s[    gt%%'''MIh	1fad9UUU
 
	 r6   r7   c                     |j         \  }}} |                    dd          j        ||g|R  }|                     |          }| j        dk    r||z  }|                    d                              dd          }|S )Nr   r9   )rA   rF   rB   r/   ru   flatten)r2   rN   r7   rO   rP   rQ   cnn_feat_tokens          r5   ra   zPosConv.forward   s    '1a/Q**/1<t<<<IIn%%;!AIIaLL""1a((r6   c                 4    d t          d          D             S )Nc                     g | ]}d |z  S )zproj.%d.weight ).0is     r5   
<listcomp>z+PosConv.no_weight_decay.<locals>.<listcomp>   s    777 1$777r6   r:   )ranger2   s    r5   no_weight_decayzPosConv.no_weight_decay   s    77eAhh7777r6   )r   r   )rd   re   rf   r&   rm   ra   r   rn   ro   s   @r5   r   r      sg             u    8 8 8 8 8 8 8r6   r   c                   J     e Zd ZdZd	 fd	Zdeej        ef         fdZ	 xZ
S )

PatchEmbedz Image to Patch Embedding
          r"   r   c                    t                                                       t          |          }t          |          }|| _        || _        |d         |d         z  dk    r|d         |d         z  dk    sJ d| d| d            |d         |d         z  |d         |d         z  c| _        | _        | j        | j        z  | _        t          j	        ||||          | _
        t          j        |          | _        d S )Nr   r   z	img_size z! should be divided by patch_size r    rs   )r%   r&   r   img_size
patch_sizerR   rS   num_patchesr*   rx   r/   rz   r{   )r2   r   r   r   r   r4   s        r5   r&   zPatchEmbed.__init__  s    X&&z**
 ${Z]*a//HQK*Q-4OST4T4T4TPPP:PPP 5U4T4T!!
15x{jQRm7S6DF?Ih	zR\]]]	L++			r6   returnc                    |j         \  }}}}|                     |                              d                              dd          }|                     |          }|| j        d         z  || j        d         z  f}||fS )Nr9   r   r   )rA   r/   r   rF   r{   r   )r2   rN   rO   rQ   rR   rS   out_sizes          r5   ra   zPatchEmbed.forward  sy    W
1aIIaLL  ##--a33IIaLL++Q$/!2D-DE({r6   )r   r   r"   r   )rd   re   rf   rg   r&   r   rh   Tensorrm   ra   rn   ro   s   @r5   r   r      sn         , , , , , ,E%,"56        r6   r   c                   R    e Zd ZdZdddddddd	d
ddddddd eej        d          ef fd	Ze	j
        j        d             Ze	j
        j        d,d            Ze	j
        j        d-d            Ze	j
        j        dej        fd            Zd.dedee         fdZd Z	 	 	 	 	 d/de	j        deeeee         f                  ded ed!ed"edeee	j                 ee	j        ee	j                 f         f         fd#Z	 	 	 d0deeee         f         d%ed&efd'Zd( Zd,d)efd*Zd+ Z xZ S )1r   z Twins Vision Transfomer (Revisiting Spatial Attention)

    Adapted from PVT (PyramidVisionTransformer) class at https://github.com/whai362/PVT.git
    r   r:   r"     avg@            )r   r9   r:   r   r:   r:   r:   r:   r"   r:      r"   r   r:   r9   r   Nr   gư>)epsc                   
 t                                                       || _        || _        |	| _        | _        d         x| _        | _        d| _        t          |          }|}t          j                    | _        t          j                    | _        t          t          |	                    D ]}| j                            t#          |||                              | j                            t          j        |                     |         }t'          fd|D                       }dt          j                    | _        g | _        d t-          j        d|t1          |	                    D             dt          t          |	                    D ]t          j        
fdt          |	                   D                       }| j                            |           | xj        t3          d	          ddz   z  
          gz  c_        |	         z  t          j        d D                       | _         | j                  | _        t          j        |          | _        |dk    rt          j        | j        |          nt          j                    | _        |                      | j!                   d S )Nr?   F)rK   c              3   "   K   | ]	}|z  V  
d S r   r   )r   tr   s     r5   	<genexpr>z!Twins.__init__.<locals>.<genexpr>D  s'      ??Q*_??????r6   r9   c                 6    g | ]}|                                 S r   )item)r   rN   s     r5   r   z"Twins.__init__.<locals>.<listcomp>I  s     PPPAqvvxxPPPr6   r   c                     g | ]J}          
                  |z            	         	|dz  dk    rdn         	  	        KS )Nr9   r   )	r'   r(   r   r0   r.   r   r   rw   r1   r   )r   r   attn_drop_rate	block_clscurdpr
embed_dimsr^   
mlp_ratiosr   r(   proj_drop_rate	sr_ratioswsss     r5   r   z"Twins.__init__.<locals>.<listcomp>L  s     	$Z 	$Z 	$Z DE %.IqM#A,$Q-((cAg,%"1q1uzz11s1v	%? 	%? 	%? 	$Z 	$Z 	$Zr6   zblock.)modulenum_chs	reductionc                 .    g | ]}t          ||          S r   )r   )r   r   s     r5   r   z"Twins.__init__.<locals>.<listcomp>[  s"    'b'b'b)	9(E(E'b'b'br6   )"r%   r&   num_classesglobal_pooldepthsr   num_featureshead_hidden_sizegrad_checkpointingr   r*   
ModuleListpatch_embeds	pos_dropsr   lenappendr   r-   tupleblocksfeature_inforh   linspacesumdict	pos_blockr{   	head_dropr+   r   headapply_init_weights)r2   r   r   r   r   r   r   r(   r   r   r   r   	drop_ratepos_drop_rater   r   drop_path_rater   r   prev_chsr   _blockr   r   r^   r4   s     `   ``` ``  `` ``   @@@r5   r&   zTwins.__init__  s   * 	&&$4>rNBD1"'X&&MOOs6{{## 	 	A$$Z*hPZ[\P]%^%^___N!!"*}"="="=>>>!!}H????h?????HJJmooPP>3v;;!O!OPPPs6{{## 	 	A] 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z 	$Z INfUViHXHX	$Z 	$Z 	$Z 
 
F Kv&&&$lqllJqM]^abcdad]e"f"f"f!gg6!9CC'b'bWa'b'b'bccJt011	 I..ALqBId/===VXVaVcVc	 	

4%&&&&&r6   c                 b    t          d | j                                        D                       S )Nc                     g | ]
\  }}d |z   S )z
pos_block.r   )r   nrK   s      r5   r   z)Twins.no_weight_decay.<locals>.<listcomp>h  s!    SSSAL1$SSSr6   )setr   named_parametersr   s    r5   r   zTwins.no_weight_decayf  s-    SS1P1P1R1RSSSTTTr6   Fc                 8    t          d|rddgng d          }|S )Nz^patch_embeds.0)z)^(?:blocks|patch_embeds|pos_block)\.(\d+)Nz^norm)i ))z^blocks\.(\d+)\.(\d+)N)z"^(?:patch_embeds|pos_block)\.(\d+))r   r   )stemr   )r   )r2   coarsematchers      r5   group_matcherzTwins.group_matcherj  sI    # D#   

 

 

 r6   Tc                     |r
J d            d S )Nz$gradient checkpointing not supportedr   )r2   enables     r5   set_grad_checkpointingzTwins.set_grad_checkpointingy  s    AAAAAAAAr6   r   c                     | j         S r   )r   r   s    r5   get_classifierzTwins.get_classifier}  s
    yr6   r   r   c                     || _         ||dv sJ || _        |dk    rt          j        | j        |          nt          j                    | _        d S )N) r   r   )r   r   r*   r+   r   r   r   )r2   r   r   s      r5   reset_classifierzTwins.reset_classifier  sZ    &"+----*DALqBId/===VXVaVcVc			r6   c                    t          |t          j                  rbt          |j        d           t          |t          j                  r.|j        )t          j                            |j        d           d S d S d S t          |t          j                  rLt          j                            |j        d           t          j                            |j        d           d S t          |t          j	                  r|j
        d         |j
        d         z  |j        z  }||j        z  }|j        j                            dt          j        d|z                       |j        "|j        j                                         d S d S d S )Ng{Gz?)stdr   g      ?r   g       @)
isinstancer*   r+   r   weightr$   init	constant_rz   rx   rt   out_channelsr   datanormal_mathsqrtzero_)r2   mfan_outs      r5   r   zTwins._init_weights  sa   a## 	$!(,,,,!RY'' -AF,>!!!&!,,,,,- -,>,>2<(( 	$Gafa(((Gah,,,,,29%% 	$mA&q)99ANJG GHM!!!TYsW}%=%=>>>v!!!#####	$ 	$ "!r6   NCHWrN   indicesr{   
stop_early
output_fmtintermediates_onlyc           	         |dk    s
J d            g }t          t          | j                  |          \  }}	|j        \  }
}}}t	          t          | j        | j        | j        | j                            D ],\  }\  }}}} ||          \  }} ||          }t	          |          D ]#\  }} |||          }|dk    r |||          }$|t          | j	                  dz
  k     rR |j
        |
g|dR                      dddd                                          }||v r|                    |           ||v rd|r|                     |          n|}|                     |j
        |
g|dR                      dddd                                                     .|r|S |                     |          }||fS )a   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
        Returns:

        r  z$Output shape for Twins must be NCHW.r   r   r?   r"   r9   )r   r   r   rA   	enumeratezipr   r   r   r   rE   rG   rM   r   r{   )r2   rN   r  r{   r  r  r  intermediatestake_indices	max_indexrO   rX   heightwidthr   embedr   r   pos_blkr7   jblkx_feats                          r5   forward_intermediateszTwins.forward_intermediates  s   ( V###%K###"6s4;7G7G"Q"Qi
  g1fe1:3!4>4;<P <P 2
 2
 	h 	h-A-tVW eAhhGAtQA#F++ ) )3C4LL664((A3t{##a'''AIa+$++++33Aq!Q??JJLL$$!((+++$$-18TYYq\\\qF!(()ED)E")E)E)E)M)MaQRTUWX)Y)Y)d)d)f)fggg 	!  IIaLL-r6   r   
prune_norm
prune_headc                     t          t          | j                  |          \  }}|rt          j                    | _        |r|                     dd           |S )z@ Prune layers not required for specified intermediates.
        r   r   )r   r   r   r*   r   r{   r   )r2   r  r"  r#  r  r  s         r5   prune_intermediate_layerszTwins.prune_intermediate_layers  s[     #7s4;7G7G"Q"Qi 	&DI 	)!!!R(((r6   c                    |j         d         }t          t          | j        | j        | j        | j                            D ]\  }\  }}}} ||          \  }} ||          }t          |          D ]#\  }	}
 |
||          }|	dk    r |||          }$|t          | j                  dz
  k     r8 |j	        |g|dR  
                    dddd                                          }|                     |          }|S )Nr   r   r?   r"   r9   )rA   r  r  r   r   r   r   r   r   rE   rG   rM   r{   )r2   rN   rO   r   r  r   r   r  r7   r  r  s              r5   forward_featureszTwins.forward_features  s"   GAJ1:D%t~t{DNSS2U 2U 		M 		M-A-tVWeAhhGAtQA#F++ ) )3C4LL664((A3t{##a'''AIa+$++++33Aq!Q??JJLLIIaLLr6   
pre_logitsc                     | j         dk    r|                    d          }|                     |          }|r|n|                     |          S )Nr   r   r@   )r   meanr   r   )r2   rN   r(  s      r5   forward_headzTwins.forward_head  sK    u$$1ANN10qqDIIaLL0r6   c                 Z    |                      |          }|                     |          }|S r   )r'  r+  )r2   rN   s     r5   ra   zTwins.forward  s-    !!!$$a  r6   F)Tr   )NFFr  F)r   FT)!rd   re   rf   rg   r   r*   rz   r   r&   rh   ri   ignorer   r   r   Moduler   r   r   strr   r   r   r   r   rk   r   r!  r%  r'  r+  ra   rn   ro   s   @r5   r   r     s         *"#"wr|666'E' E' E' E' E' E'N YU U U Y    YB B B B Y	    d dC dhsm d d d d$ $ $$ 8<$$',5  5 |5  eCcN345  	5 
 5  5  !%5  
tEL!5tEL7I)I#JJ	K5  5  5  5 r ./$#	 3S	>*  	      1 1$ 1 1 1 1      r6   Fc                 |    |                     dd          }t          t          | |fdt          |d          i|}|S )Nout_indicesr:   feature_cfggetter)r2  feature_cls)popr   r   r   )variant
pretrainedkwargsr2  models        r5   _create_twinsr;    sV    **]A..K w
 [hGGG  E
 Lr6   r   c                 6    | ddd dddt           t          ddd|S )	Nr   )r"   r   r   g?bicubicTzpatch_embeds.0.projr   )urlr   
input_size	pool_sizecrop_pctinterpolationfixed_input_sizer*  r  
first_conv
classifierr   )r>  r9  s     r5   _cfgrF    s7    =t%.B+6   r6   ztimm/)	hf_hub_id)ztwins_pcpvt_small.in1kztwins_pcpvt_base.in1kztwins_pcpvt_large.in1kztwins_svt_small.in1kztwins_svt_base.in1kztwins_svt_large.in1kr   c           	      r    t          dg dg dg dg dg d          }t          d
d	| it          |fi |S )Nr:   r   r   i@  r   r   r9   r;   r   r   r   r:   r:   r   r   r   r   r(   r   r   r   twins_pcpvt_smallr8  )rM  r   r;  r8  r9  
model_argss      r5   rM  rM    sj    !4!4!4YeYeYe|||||5 5 5J bbbtJGaGaZ`GaGabbbr6   c           	      r    t          dg dg dg dg dg d          }t          d
d	| it          |fi |S )Nr:   rI  rJ  rK  )r"   r:      r"   r   rL  twins_pcpvt_baser8  )rS  rN  rO  s      r5   rS  rS     sj    !4!4!4YeYeYe}}6 6 6J aa
ad:F`F`Y_F`F`aaar6   c           	      r    t          dg dg dg dg dg d          }t          d
d	| it          |fi |S )Nr:   rI  rJ  rK  )r"   r      r"   r   rL  twins_pcpvt_larger8  )rV  rN  rO  s      r5   rV  rV  (  sj    !4!4!4YeYeYe}}6 6 6J bbbtJGaGaZ`GaGabbbr6   c           
      x    t          dg dg dg dg dg dg d          }t          dd
| it          |fi |S )Nr:   r   )r9   r:   r   r   r   )r9   r9   
   r:      rZ  rZ  rZ  r   r   r   r(   r   r   r   r   twins_svt_smallr8  )r\  rN  rO  s      r5   r\  r\  0  ss    !4!4!4ZfZfZf}},,,,,,H H HJ ``z`T*E_E_X^E_E_```r6   c           
      x    t          dg dg dg dg dg dg d          }t          dd
| it          |fi |S )Nr:   )`      i  r   )r"   r         r   r9   r9   rR  r9   rY  r   r[  twins_svt_baser8  )rc  rN  rO  s      r5   rc  rc  8  ss    !4!4!4[g[g[g}},,,,,,H H HJ __j_DD^D^W]D^D^___r6   c           
      x    t          dg dg dg dg dg dg d          }t          dd
| it          |fi |S )Nr:   )r   r   r   i   )r:   r   r       r   rb  rY  r   r[  twins_svt_larger8  )rf  rN  rO  s      r5   rf  rf  @  ss    !6!6!6...]i]i]i}},,,,,,H H HJ ``z`T*E_E_X^E_E_```r6   r-  )r   )6rg   r
  	functoolsr   typingr   r   r   r   rh   torch.nnr*   torch.nn.functionalr}   rC   	timm.datar	   r
   timm.layersr   r   r   r   r   _builderr   	_featuresr   _features_fxr   	_registryr   r   vision_transformerr   __all__r   rm   r/  r   rq   r   r   r   r   r;  rF  default_cfgsrM  rS  rV  r\  rc  rf  r   r6   r5   <module>rt     s;           / / / / / / / / / / / /                 A A A A A A A A O O O O O O O O O O O O O O * * * * * * + + + + + + 1 1 1 1 1 1 < < < < < < < < ) ) ) ) ) ))c3h ; ; ; ; ; ; ; ;B8 8 8 8 8") 8 8 8v% % % % %BI % % %P8 8 8 8 8bi 8 8 8,       8\ \ \ \ \BI \ \ \~       %$"dW555!TG444"dW555 D73334'222 D7333& &   c cU c c c c b bE b b b b c cU c c c c a a5 a a a a ` `% ` ` ` ` a a5 a a a a a ar6   