
    jV                        U d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
 d dlZd dlmZ d dl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 d d	lmZmZmZ d d
l m!Z!m"Z" d dl#m$Z$ h dZ%i Z&e'e(e'f         e)d<    ej*                    Z+h dZ,de'de'fdZ-de(de'dz  fdZ.d>de(de(de(de/fdZ0de'ddfdZ1de(de/fdZ2de(ddfdZ3d?de4de(de(d e(de'f
d!Z5d"e6e7e(ej        f                  ddfd#Z8d$e(d%e(de7eee4                  e6e(         dz  f         fd&Z9de(de/fd'Z:de(ddfd(Z;de(d"e6e7e(ej        f                  d)e<d*eee4                  d+e4d$e(d,e6e(         dz  d-ej=        d.e'd/e4de4fd0Z>de(d1e(d2e4d)e<d*eee4                  d+e4d$e(d,e6e(         dz  d-ej=        d.e'de4fd3Z?de(d4e(d5e4d2e4d)e<d*eee4                  d+e4d$e(d,e6e(         dz  d-ej=        d.e'de4fd6Z@	 d@de'd7e(de(d)e<d2e4d+e4d%e(d$e(d8e(dz  d5e4dz  ddfd9ZAde'ddfd:ZBd1e(d;e(d)e<d2e4d+e4d%e(d$e(de(de(d8e(de7e(dz  e(f         fd<ZCd4e(d;e(d5e4d)e<d2e4d+e4d%e(d$e(de(de(d8e(de7e(dz  e(f         fd=ZDdS )A    N)OptionalSet)uuid4)Image)
BATCH_SIZECONF_THRESHIMGSZ
OUTPUT_DIRget_upload_model_defaultloggermodel_supports_text_prompt)get_job)save_job)submit_task)add_result_bytescreate_result_storefinalize_result_store)_predict_batch	get_model)job_matches_owner>   .bmp.png.tif.jpeg.tiff.webp.jpgUPLOAD_JOBS>   doneerrorcanceledinterruptedjobreturnc                 >    d |                                  D             S )Nc                 &    i | ]\  }}|d k    ||S )cancel .0keyvalues      O/home/longshao/multi-rider-rag/modules/detection/services/upload_job_service.py
<dictcomp>z$_upload_snapshot.<locals>.<dictcomp>*   s#    HHH:3xC    )itemsr#   s    r-   _upload_snapshotr2   )   s    HHHHHHr/   job_idc                    t           5  t                              |           }|t          |          cd d d            S 	 d d d            n# 1 swxY w Y   t	          |           }||                    d          dk    rd S |S )Njob_typeupload)UPLOAD_JOBS_LOCKr   getr2   get_saved_jobr3   r#   	saved_jobs      r-   get_upload_job_snapshotr<   -   s    	 ) )oof%%?#C(() ) ) ) ) ) ) )) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 f%%IIMM*55AAts   +AAA 	owner_keyowner_ipc                 .   d }t           5  t                              |           }|t          |||          r|d                                          |                    d          t
          vrBd|d<   d|d<   |                    d          pt          t          j                              |d<   t          |          }d d d            n# 1 swxY w Y   |t          |           dS t          |           }|*|                    d          d	k    st          |||          sd
S |                    d          t
          v rdS d|d<   d|d<   |                    d          pt          t          j                              |d<   t          |           dS )Nr'   statusr!   cancel requestedmessageend_tsTr5   r6   F)r7   r   r8   r   setTERMINAL_STATUSESinttimer2   r   r9   )r3   r>   r?   snapshotr#   s        r-   request_upload_cancelrJ   9   s   H	 - -oof%%?0iJJ?Mwwx  (999 *H!3I # 1 1 ES5E5EH',,H- - - - - - - - - - - - - - - t


C
{cggj))X55=NsT]_g=h=h5u
wwx---tCM'C	NGGH%%9TY[[)9)9CMSMMM4s   B5CCCrI   c                     	 t          |            d S # t          $ r4}t          j        d|                     d          |           Y d }~d S d }~ww xY w)Nz#failed to persist upload job %s: %sid)r   	Exceptionr   	exceptionr8   )rI   excs     r-   _save_job_staterP   W   st    Y Y Y Y>T@R@RTWXXXXXXXXXYs    
A)AAc                    t           5  t                              |           }|	 d d d            dS |d                                         rI|                    d          t          vrd|d<   |                    d          pd|d<   	 d d d            dS 	 d d d            n# 1 swxY w Y   t          |           }|2|                    d          d	k    s|                    d          dk    rdS t           5  t                              |           }|	 d d d            dS |d                                          |                    d          t          vrLd|d<   |                    d          pd|d<   |                    d
          r|                    d
          |d
<   d d d            n# 1 swxY w Y   dS )NFr'   rA   r!   rC   rB   Tr5   r6   rD   )r7   r   r8   is_setrF   r9   rE   r:   s      r-   _sync_cancel_staterS   ^   s   	  oof%%;        x=!! 	wwx  (999 *H!$!3!3!I7II       		               f%%IIMM*55AAY]]S[E\E\`jEjEju	 	8 	8oof%%;	8 	8 	8 	8 	8 	8 	8 	8 	H778$555&CM&]]955K9KC	N}}X&& 8 )h 7 7H	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 4s0   B#AB##B'*B':F3%BF33F7:F7c                     t          |            t          5  t                              |           }|	 d d d            d S t	          |          }d d d            n# 1 swxY w Y   t          |           d S N)rS   r7   r   r8   r2   rP   )r3   r#   rI   s      r-   _persist_job_staterV   z   s    v	 ) )oof%%;) ) ) ) ) ) ) ) $C((	) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 Hs   AAA!$A!queuedtotalsource_namesource_typerA   c                    i dddt                      j        d|d|ddddd	d d
|d|d| dddddddt          t          j                              dd dd dg ddt          t
          t          dt                      ddd	S )Nr5   r6   rL   rY   rZ   source_pathr=   temp_dirframe_intervalrA   rC   rX   	processedr   keptfailedstart_tsrD   zip_path	zip_parts)	
result_dirresult_manifest_pathconf_thresh
batch_sizeimgszclasses_raw	model_keyr>   r?   )r   hexrG   rH   r   r   r	   r   )rX   rY   rZ   rA   s       r-   _new_upload_jobrm      s   Heggk 	{ 	{	
 	r 	B 	$ 	& 	6 	 	Q 	 	! 	C	$$ 	$  	D!" 	R#$  "" -//5   r/   batchc                 `    | D ]*\  }}	 |                                  # t          $ r Y 'w xY wd S rU   )closerM   )rn   _nameimgs      r-   _close_batch_imagesrs      sS      
s	IIKKKK 	 	 	D	 s   
++rk   rj   c                    d }d }t          |           r%d |                    d          D             pd }||fS t          |dd           }|r|rt                      }t	          |t
                    rd |                                D             }nd t          |          D             }d |                    d          D             D ]w}|                                r#|	                    t          |                     9|                    |                                          }	|	|	                    |	           x|r|}||fS )Nc                 ^    g | ]*}|                                 |                                 +S r(   strip)r*   tokens     r-   
<listcomp>z*_resolve_model_filters.<locals>.<listcomp>   s-    ]]]Eu{{}}]%++--]]]r/   ,namesc                 r    i | ]4\  }}t          |                                          t          |          5S r(   )strlowerrG   r)   s      r-   r.   z*_resolve_model_filters.<locals>.<dictcomp>   s6    UUUeE

((**CHHUUUr/   c                 X    i | ]'\  }}t          |                                          |(S r(   )r}   r~   )r*   indexr,   s      r-   r.   z*_resolve_model_filters.<locals>.<dictcomp>   s0    WWWleUE

((**EWWWr/   c                 ^    g | ]*}|                                 |                                 +S r(   rv   )r*   r,   s     r-   ry   z*_resolve_model_filters.<locals>.<listcomp>   s-    YYY5;;==YekkmmYYYr/   )r   splitgetattrrE   
isinstancedictr0   	enumerateisdigitaddrG   r8   r~   )
rk   modelrj   allowed_classesprompt_classesr{   indexesname_maprx   mappeds
             r-   _resolve_model_filtersr      sc   *.O'+N!),, /]][5F5Fs5K5K]]]eae..E7D))E &u &EEeT"" 	XUUu{{}}UUUHHWWiPUFVFVWWWHYY1B1B31G1GYYY 	( 	(E}} (CJJ''''!ekkmm44%KK''' 	&%ON**r/   c                      t          |           S rU   )rS   )r3   s    r-   _is_upload_canceledr      s    f%%%r/   c                 2   t           5  t                              |           }|	 d d d            d S |dxx         dz  cc<   |dxx         dz  cc<   |d         |                    d          pdk    r|d         |d<   d d d            d S # 1 swxY w Y   d S )Nr_      ra   rX   r   )r7   r   r8   )r3   r#   s     r-   _mark_upload_failed_itemr      s   	 , ,oof%%;, , , , , , , , 	KAH{swww//4155{+CL, , , , , , , , , , , , , , , , , ,s   BABBBrg   r   ri   r   
result_zipresult_storekept_sequencec           	      .   d |D             }d |D             }	 t          |||||||          }n# t          $ r}t          5  t                              |           }|x|dxx         t          |          z  cc<   |dxx         t          |          z  cc<   t          |          |d<   |d         |                    d          pdk    r|d         |d<   d d d            n# 1 swxY w Y   t          j        d| |           t          d	|           |d }~ww xY wd}	 t          |||          D ]\  }}}|s	|
d
z  }
t          j                    }|                    |dd           |                                }|
ddt          j                            |          d          d}|                    ||           t'          |	||d|i           |d
z  }	 t)          |           n# t)          |           w xY wt          5  t                              |           }|Y|dxx         t          |          z  cc<   |dxx         |z  cc<   |d         |                    d          pdk    r|d         |d<   d d d            n# 1 swxY w Y   |
S )Nc                     g | ]\  }}|S r(   r(   )r*   name_s      r-   ry   z"_process_batch.<locals>.<listcomp>   s    ---GD!4---r/   c                     g | ]\  }}|S r(   r(   )r*   r   rr   s      r-   ry   z"_process_batch.<locals>.<listcomp>   s    ***&!S#***r/   r_   ra   rC   rX   r   z&upload inference failed for job %s: %szinference failed: r   JPEGZ   )formatquality07dr   r   origin_name)extrar`   )r   rM   r7   r   r8   lenr}   r   rN   RuntimeErrorzipioBytesIOsavegetvalueospathsplitextwritestrr   rs   )r3   rn   r   rg   r   ri   rk   r   r   r   r   batch_names
batch_imgshitsrO   r#   
kept_deltar   rr   hitbufpayloadoutput_names                          r-   _process_batchr      sy    .-u---K**E***J@j%ouV_aopp 
@ 
@ 
@ 	4 	4//&))CK   CJJ.   HU+!$SI{#swww'7'7'<1==#&{#3CL	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	A63OOO55566C?
@ J#!+z4@@ 
	 
	ND#s QM*,,CHHSH444llnnG*PPP1A1A$1G1G1JPPPKW555\;W[G\]]]]!OJJ
	 	E""""E""""	 0 0oof%%?E

*KKK:%KKK;3777#3#3#8q99";/G0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 sY   0 
DDBC"D"C&	&D)C&	*,DD!B;G- -G>A6J

JJrc   rh   c                    g }d}t          j        |          5 }|                                D ]Z}t          |           r nG|                                r*t
          j                            |j        	                                          d         }t
          j        
                    |j                  }|t          vs|s	 |                    |          }t          j        t          j        |                                        d          }n # t$          $ r t'          |            Y w xY w|                    ||f           t+          |          |k    r*t-          | ||||||||	|
|          }g }t/          |            \|r8t          |           s)t-          | ||||||||	|
|          }t/          |            nt1          |           d d d            n# 1 swxY w Y   |S )Nr   r   RGB)zipfileZipFileinfolistr   is_dirr   r   r   filenamer~   basename
IMAGE_EXTSreadr   openr   r   convertrM   r   appendr   r   rV   rs   )r3   rc   rh   r   rg   r   ri   rk   r   r   r   rn   r   
source_zipentryext	safe_namer   rr   s                      r-   _run_zip_sourcer     sU    ,.EM		"	" 5'j((** "	+ "	+E"6** ||~~ '""5>#7#7#9#9::1=C((88I*$$I$$//%00jG!4!455==eDD   (000 LL)S)***5zzZ'' .#" !! ! "6*** 	',V44 	'* M v&&&&&&&k5' 5' 5' 5' 5' 5' 5' 5' 5' 5' 5' 5' 5' 5' 5'n s8   B+GADGD1-G0D11B"GG#&G#
video_pathr^   c                 b   t          j        |          }|                                st          d          g }d}d}d}	 	 t	          |           rn|                                \  }}|sn||z  dk    r|dz  }:	 t          j        |t           j                  }t          j	        |          }n$# t          $ r t          |            |dz  }Y w xY w|                    d|dd|f           |dz  }|dz  }t          |          |k    r*t          | |||||||	|
||          }g }t          |            |r8t	          |           s)t          | |||||||	|
||          }t          |            nt!          |           |                                 n# |                                 w xY w|S )Nzcannot open video filer   Tr   frame_06dr   )cv2VideoCaptureisOpenedr   r   r   cvtColorCOLOR_BGR2RGBr   	fromarrayrM   r   r   r   r   rV   rs   release)r3   r   r^   rh   r   rg   r   ri   rk   r   r   r   caprn   r   	frame_idx
sample_idxretframergbrr   s                        r-   _run_video_sourcer   Y  s&    
:
&
&C<<>> 53444+-EMIJ<'	+"6** JC >)Q..Q	l5#*;<<oc**   (000Q	
 LL7:7777=>>>!OJNI5zzZ'' .#" !! ! "6***O'	+R  	',V44 	'* M v&&&&&&&s1   :F <3B0 /F 0CF CB0F F,r\   r]   c
                 6   t          |                     d          pd                                          }
|
st          d          t	          |           }t          j                    |d<   ||d<   ||d<   |p|                    d          pd|d<   |	|	n|                    d          |d<   ||d	<   ||d
<   ||d<   ||d<   |p"|                    d          pt                      |d<   |                    d          pt          t          j	                              |d<   |                    d          pd|d<   t          5  |t          |
<   d d d            n# 1 swxY w Y   d }t          j                            t          d|
 d          }	 t!          |
          rt          5  t          |
         }|                    d          pt          t          j	                              |d<   t#          |          }d d d            n# 1 swxY w Y   t%          |           	 t          5  t                              |
          }|7|                    d          t&          v rt                              |
d            d d d            d S # 1 swxY w Y   d S t          5  t          |
         }d|d<   d|d<   d d d            n# 1 swxY w Y   t+          |
           	 t-          |d                   }n.# t.          $ r!}t1          d|d          d|           |d }~ww xY wt3          |
d||                    dd                    }t5          |d         ||          \  }}t7          j        |dt6          j                  5 }|dk    r t=          |
|||||||d         |||           n=t?          |
|tA          dt          |	pd                    ||||||d         |||           d d d            n# 1 swxY w Y   tC          |
          rt          j        "                    |          r&	 t          j#        |           n# t.          $ r Y nw xY w|rAt          j        $                    |d                   rtK          j&        |d         d           t          5  t                              |
          }|gd |d<   |                    d          pd!|d<   |                    d          pt          t          j	                              |d<   t#          |          }nd }d d d            n# 1 swxY w Y   |t%          |           	 t          5  t                              |
          }|7|                    d          t&          v rt                              |
d            d d d            d S # 1 swxY w Y   d S tO          |          }t          5  t                              |
          }|x||d"<   |t          j        (                    |          d#g|d$<   |d         |d<   ||d%<   d&|d<   d'|d<   t          t          j	                              |d<   t#          |          }nd }d d d            n# 1 swxY w Y   |t%          |           n# t.          $ r}tS          j*        d(|
|           t          j        "                    |          r&	 t          j#        |           n# t.          $ r Y nw xY w|rAt          j        $                    |d                   rtK          j&        |d         d           t!          |
           t          5  t                              |
          }||d         +                                r d |d<   |                    d          pd!|d<   nd)|d<   t          |          |d<   t          t          j	                              |d<   t#          |          }nd }d d d            n# 1 swxY w Y   |t%          |           Y d }~nd }~ww xY wt          5  t                              |
          }|7|                    d          t&          v rt                              |
d            d d d            d S # 1 swxY w Y   d S # t          5  t                              |
          }|7|                    d          t&          v rt                              |
d            d d d            w # 1 swxY w Y   w xY w)*NrL   r=   zmissing job idr'   r\   rZ   r]   r^   rg   rh   ri   rj   rk   rb   rC   rW   upload_z.ziprD   rA   runningu   模型文件加载失败（u#   ），请重新部署模型文件: r6   rY   wr   r   re   Tignore_errorsr!   rB   rc   )r   r   rd   rf   r   	completedzupload job %s failed: %sr    ),r}   r8   rw   
ValueErrorr   	threadingEventr   rG   rH   r7   r   r   r   joinr
   rS   r2   rP   rF   poprV   r   rM   r   r   r   r   r   ZIP_DEFLATEDr   r   maxr   isfileremoveisdirshutilrmtreer   r   r   rN   rR   )r#   r\   rZ   rg   rh   ri   rj   rk   r]   r^   r3   runtime_jobr   rc   currentrI   r   rO   r   r   r   manifest_paths                         r-   _run_upload_jobr     s    $"%%++--F +)***s))K%O--K!,K!,K&K+//**E*EKK
6D6PNNVaVeVefvVwVwK !!,K *K K!,K(fKOOK,H,HfLdLfLfK)ooj99MS=M=MK
(__Y77C8K		 * *)F* * * * * * * * * * * * * * * Lw||J(>&(>(>(>??H|.f%% 	! 5 5%f-$+KK$9$9$MS=M=M!+G445 5 5 5 5 5 5 5 5 5 5 5 5 5 5 H%%%d  	. 	.!oof--G"w{{8'<'<@Q'Q'Q---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.a  	+ 	+!&)G )GH!*GI	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	6"""	k+677EE 	 	 	pk+.Fppknpp 	 +68[+//ZgikJlJlmm*@[AY[`bm*n*n'_XsG,@AA 	Ze###,"     "3~23344#,"   !	 	 	 	 	 	 	 	 	 	 	 	 	 	 	> v&& 	w~~h'' Ih''''    D Nl<.H I I Nl<8MMMM! $ $%//&11&(2GH%)0Y)?)?)UCUGI&(/H(=(=(QTY[[AQAQGH%/88HH#H$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ #)))^  	. 	.!oof--G"w{{8'<'<@Q'Q'Q---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.[ .l;; 	  	 !oof--G"&.
#1927CSCST\C]C](^(^'_$(4\(B%2?./$*!%0	"$'	$4$4!+G44	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  H%%% & & &3VSAAA7>>(## 		(####    	JBGMM,|*DEE 	JM,|4DIIII6""" 	  	 !oof--G"8$++-- 2(2GH%)0Y)?)?)UCUGI&&(/GH%),SGI&$'	$4$4!+G44	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  H%%%3&6  	. 	.!oof--G"w{{8'<'<@Q'Q'Q---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.!oof--G"w{{8'<'<@Q'Q'Q---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.s  EE"EZ (AH	=Z 	HZ HZ +AJJJZ  K8Z KZ KZ K5 4Z 5
L ?LL  A#Z A$O3'Z 3O77Z :O7;2Z .Q Z 
QZ QAZ BT/#Z /T33Z 6T37Z AV44V8;V8Z BY:.Z :Y>>Z Y>Z b$ `,#5`'[.-`'.
[;8`':[;;A`'B#`:`'`
	
`'`
	`'"b$ '`,,b$ 6Abbb$d,Ad dddddc           	          t          |            t          dd| d         i|                     dd          |                     dd          | d                    d S )Nr6   r3   rL   r>   r=   r?   )r>   r?   task_id)r   r   r8   r1   s    r-   _enqueue_upload_jobr   T  sf    SMMM	3t9''+r**R((D	     r/   original_filenamec
                 X   	 t          j        |           5 }
t          d |
                                D                       }d d d            n# 1 swxY w Y   n4# t          $ r'}t          j        |	d           d d| fcY d }~S d }~ww xY w|dk    rt          j        |	d           dS t          ||dd	          }|                    | |	|||||||
	  	         	 t          |           n4# t          $ r'}t          j        |	d           d d| fcY d }~S d }~ww xY w|d         dfS )Nc              3     K   | ]}|                                 skt          j                            |j                                                  d          t          v Yt          j                            |j                  }d V  dS )r   N)r   r   r   r   r   r~   r   r   )r*   r   s     r-   	<genexpr>z start_zip_job.<locals>.<genexpr>m  s        ||~~ G$$U^%9%9%;%;<<Q?:MMG$$U^44 N  NMMM	 r/   Tr   zZIP parse failed: r   )Nz=ZIP contains no supported images (.jpg/.png/.bmp/.tiff/.webp)r   rW   rA   )	r\   r]   rg   rh   ri   rj   rk   r>   r?   start upload job failed: rL   r=   )
r   r   sumr   rM   r   r   rm   updater   )rc   r   rg   rh   ri   rj   rk   r>   r?   r]   r   rX   rO   r#   s                 r-   start_zip_jobr   _  s   0_X&& 	*  '0022    E	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  0 0 0hd3333/#/////////0 zzhd3333TT
%!2E(
K
K
KCJJ  
 
 
7C     7 7 7hd333366666666667 t9b=s^   A ,AA AA AA 
B$B BBC. .
D8DDDc                    t          j        |           }|                                s,|                                 t	          j        |
d           dS t          |                    t           j                  pd          }|                                 |dk    r5t          d|t          d|          z   dz
  t          d|          z            nd}t          ||dd          }|                    | |
t          dt          |                    |||||||		
  
         	 t          |           n4# t          $ r'}t	          j        |
d           d d
| fcY d }~S d }~ww xY w|d         dfS )NTr   )Nz,cannot open video file; expected MP4/AVI/MOVr   r   videorW   r   )
r\   r]   r^   rg   rh   ri   rj   rk   r>   r?   r   rL   r=   )r   r   r   r   r   r   rG   r8   CAP_PROP_FRAME_COUNTr   rm   r   r   rM   )r   r   r^   rg   rh   ri   rj   rk   r>   r?   r]   r   frame_countrX   r#   rO   s                   r-   start_video_jobr    s    
:
&
&C<<>> Dhd3333CCcggc677<1==KKKMMM\gjk\k\kCK#a"8"881<QAWAWWXXXqrE
%!2GH
M
M
MCJJ1c.1122    7C     7 7 7hd333366666666667 t9b=s   "D2 2
E#<EE#E#)r=   r=   )rW   rU   )Er   r   r   r   rH   r   typingr   r   uuidr   r   PILr   shared.config.configr   r   r	   r
   r   r   r   shared.db.sqliter   r9   r   shared.task_queuer   /modules.detection.services.result_store_servicer   r   r   shared.inference.infer_servicer   r   shared.ownership.ownershipr   r   r   r   r}   __annotations__Lockr7   rF   r2   r<   boolrJ   rP   rS   rV   rG   rm   listtuplers   r   r   r   floatr   r   r   r   r   r   r   r  r(   r/   r-   <module>r     s   					 				                              



                        6 5 5 5 5 5 % % % % % % ) ) ) ) ) )         
 E D D D D D D D 8 8 8 8 8 8 IHH
!T#t)_ ! ! !!9>## @@@ I$ I4 I I I I	C 	D4K 	 	 	 	 # # c SW    <Yd Yt Y Y Y Ys t    8s t     3 S s C _c    >tE#u{*:$;<     +c +s +uXVYZ]V^M_aefiajmqaqMqGr + + + +8& & & & & &,S ,T , , , ,66c5;&'(6 	6
 c#h'6 6 6 I$6 6 6 6 	6 6 6 6rGGG G
 G c#h'G G G I$G G G 	G G G GTUUU U 	U U c#h'U U U I$U U U 	U U U UD "&`. `.	`.`. `. 	`.
 `. `. `. `. Dj`. $J`. 
`. `. `. `.FT d    /// / 	/
 / / / / / / 3:s?/ / / /d*** * 	*
 * * * * * * * 3:s?* * * * * *r/   