
    q-PhW                    h   U d dl mZ d dl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 d dlmZ d d	lmZmZmZmZmZ d d
lmZmZ d dlmZ d dlmZ d dl m!Z!m"Z"m#Z# er>d dlm$Z$ d dl
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/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 d dl6m7Z7 dddZ8dZ9dZ:eded ed!iZ;d"e<d#<    G d$ d%          Z=dd-Z>dd0Z?dd4Z@dd>ZAed?d@ddF            ZBeddI            ZBdJd@ddLZBddMZCdNdNdOddUZDddXZEdd[ZF	 	 	 	 	 	 	 	 	 dddoZGddqZHdrdsddxZI	 ddd~ZJddZKddZLdNS )    )annotations)Sequence)BytesIO)PathLike)Path)TYPE_CHECKINGAnyoverload)	functions)qualified_type_name)DateDatetimeFloat64Int64Time)FLOAT_DTYPESINTEGER_DTYPES)json)DuplicateError)_expand_selector_dicts_expand_selectorsnumeric)Iterable)LiteralWorkbookFormat	Worksheet)	DataFrameSchemaSeries)ColumnFormatDictColumnTotalsDefinitionConditionalFormatDictOneOrMoreDataTypesPolarsDataTypeRowTotalsDefinition)Expr   iterableIterable[Any]nintreturnc                6    t          t          |           g|z   S N)zipiter)r,   r.   s     b/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/polars/io/spreadsheet/_write_utils.py_clusterr6   +   s    h 1$%%    z#,##0.000;[Red]-#,##0.000z#,##0;[Red]-#,##0zyyyy-mm-dd hh:mm:sszyyyy-mm-dd;@z
hh:mm:ss;@zdict[PolarsDataType, str]_XL_DEFAULT_DTYPE_FORMATS_c                  :    e Zd ZdZddZedd
            ZddZdS )_XLFormatCachezGCreate/cache only one Format object per distinct set of format options.wbr   r0   Nonec                "    i | _         || _        d S r2   )_cacher;   )selfr;   s     r5   __init__z_XLFormatCache.__init__;   s    )+r7   fmtdict[str, Any]strc                :    t          j        | dt                    S )NT)	sort_keysdefault)r   dumpsrC   )rA   s    r5   _keyz_XLFormatCache._key?   s    z#s;;;;r7   dict[str, Any] | Formatr   c                    t          |t                    s|}nU|                     |          }| j                            |          }|$| j                            |          }|| j        |<   |S r2   )
isinstancedictrH   r>   getr;   
add_format)r?   rA   wbfmtkeys       r5   rM   z_XLFormatCache.getC   sh    #t$$ 	)EE))C..CKOOC((E}**3//#(C r7   N)r;   r   r0   r<   )rA   rB   r0   rC   )rA   rI   r0   r   )__name__
__module____qualname____doc__r@   staticmethodrH   rM    r7   r5   r:   r:   8   sb        QQ    < < < \<	 	 	 	 	 	r7   r:   dfr!   colsIterable[str]min_maxrB   boolc           	     4    t           fd|D                       }|t          t          t          |          t          |          dz                       k    rdS  j        }|d         ||d                  d|d<   |d         ||d                  d|d<   d	S )
z>Indicate if the given columns are all adjacent to one another.c              3  B   K   | ]}                     |          V  d S r2   )get_column_index).0colrW   s     r5   	<genexpr>z!_adjacent_cols.<locals>.<genexpr>Q   s1      ;;s"%%c**;;;;;;r7      Fr   )idxnameminmaxT)sortedrangere   rg   columns)rW   rX   rZ   idxsrj   s   `    r5   _adjacent_colsrl   O   s    ;;;;d;;;;;DveCIIs4yy1}556666u*!%a'$q'2BCC!%b7483DEEtr7   schemar"   c                :    t          fd| D                       S )z4Indicate if the given columns are all integer-typed.c              3  L   K   | ]}|                                          V  d S r2   )
is_integer)r_   r`   rm   s     r5   ra   z$_all_integer_cols.<locals>.<genexpr>]   s3      88Cvc{%%''888888r7   )all)rX   rm   s    `r5   _all_integer_colsrr   [   s&    88884888888r7   d$dict[str | Sequence[str], Any] | Anydict[str, Any] | Anyc                    t          | t                    s| S i }|                                 D ]<\  }}t          |t                    st          |t                    s|f}|D ]}|||<   =|S )zCUnpack multi-col dictionary into equivalent single-col definitions.)rK   rL   itemsrC   r   )rs   unpackedrP   valueks        r5   _unpack_multi_column_dictr{   `   s     a !Hggii    
Uc3 	z#x'@'@ 	&C 	  	 AHQKK	 Or7   wsr    conditional_formatsr&   table_starttuple[int, int]include_headerformat_cacher<   c               "   ddl m} t          | |ddd                                          D ]`\  }}t	          |t
                    s/t          |          dk    rt          t          |                    }t	          |t
          t          f          r|g}|D ]}	t	          |	t                    sd|	i}	t	          |t
                    rt          | |||          }
nKt          | |||          }
d	|
v r4t          t          |                    }|
|	d
<   t          | |||          }
d|	v rK|	d         }t	          ||          r|n-|                    t	          |t
                    rd|in|          |	d<   |                    |
|	           bdS )zJTake all conditional formatting options and apply them to the table/range.r   r   TFexpand_keysexpand_values
tuple_keysrb   typer    multi_rangeformat
num_formatN)xlsxwriter.formatr   r   rw   rK   rC   lennextr4   rL   _xl_column_range_xl_column_multi_rangerM   conditional_format)rW   r|   r}   r~   r   r   r   rX   formatsrA   	col_ranger`   fs                r5   _xl_apply_conditional_formatsr   o   s    )(((((/
TSW  egg#2 #2g $$$ 	$TaT

##DgT{++ 	 iG 	2 	2Cc4(( $sm$$$ ,T.  		 3T.  	 )##tDzz**C)2C& 0K^! ! !I 3M "!V,,AA%))-73-?-?Fq))Q  H !!)S11117	2#2 #2r7   .)as_ranger`   str | tuple[int, int]r   Literal[True]rC   c                   d S r2   rV   rW   r~   r`   r   r   s        r5   r   r      s	     #r7   Literal[False]tuple[int, int, int, int]c                   d S r2   rV   r   s        r5   r   r      s	     !$r7   Ttuple[int, int, int, int] | strc                  |d         t          |          z   |d         t          |t                    r|                     |          n|d         z   f}|d         | j        z   dz
  |d         t          |t                    rdn|d         |d         z
  z   f}|r!d                    t          g ||R            S ||z   S )zKReturn the Excel sheet range of a named column, accounting for all offsets.r   rb    )r/   rK   rC   r^   heightjoin_xl_rowcols_to_range)rW   r~   r`   r   r   	col_start
col_finishs          r5   r   r      s     	A^,,,Ajc6J6JV"--c222PSTUPVWI
 	!ry 1$!ZS11HAQIJ  &ww+DYDDDDEEE:%%r7   c                    i }t           ||          r-t           |d         d         |d         d         f          S d                     fd|D                       S )zNReturn column ranges as an xlsxwriter 'multi_range' string, or spanning range.rZ   re   rc   rg   r   r   c              3  >   K   | ]}t          |           V  dS )r   N)r   )r_   r`   rW   r   r~   s     r5   ra   z)_xl_column_multi_range.<locals>.<genexpr>   sH         	[#nMMM     r7   )rl   r   r   )rW   r~   rX   r   ms   `` ` r5   r   r      s     Ab$*** 
uXe_ahuo.)	
 
 
 	
 88           r7   N)dtypeexprcoldefsr   1dict[str, PolarsDataType] | PolarsDataType | Noner   Expr | Nonec                  t          | j                  | j                                        }i |                                D ]\  }}|v rd|d}t	          |          t          |t                    s|                    |           I|                    d          |<   |                    d          }|                    d          }	|	||                    |           ||	                    |	          dz   n|	                    |          }
|
                    |
|           t          j        d          n|                     fd|D                       } | S )	zHInsert dummy frame columns in order to create empty/named table columns.zcannot create a second z columnreturn_dtypeinsert_beforeinsert_afterNrb   c           
   3  .  K   | ]}|v r|ns                     |          Y                                         |t          t                    r                     |t                    n                    n                    |          V  d S r2   )rM   castrK   rL   r   alias)r_   r`   cast_lookupdf_original_columnsr   r   s     r5   ra   z1_xl_inject_dummy_table_columns.<locals>.<genexpr>  s          ))) C  )__S11= 		OO3=eT3J3JU		#w///PU    eCjj     r7   )setrj   copyrw   r   rK   rL   appendrM   indexinsertFlitselect)rW   r   r   r   df_select_colsr`   
definitionmsgr   r   
insert_idxr   r   s     ``       @@r5   _xl_inject_dummy_table_columnsr      s    bj//Z__&&NK"==?? 7 7Z%%%:C:::C %%%J-- 	7!!#&&&&)~~n==K&NN?;;M%>>.99L#(=%%c**** %, #((66::'--m<< 
 %%j#6666,15;;;DD	        "   
 
B" Ir7   paramsSequence[str] | dict[str, Any]c                  ddl m} i }t          |t                    r|                    d          n|}|sd}	t          |	          t          |||          sd}	t          |	          t          ||||d          \  }
}}}|d	         |d
         d         z   }|d	         |d         d         z   }t          |t                    si }n<d |	                                D             }d|vr|                    d          dv |d<   t          |j                  D ]@} ||
|          } ||
|          }| d| |d<   |                     |
||           |
d	z  }
AdS )z@Inject sparklines into (previously-created) empty table columns.r   xl_rowcol_to_cellrj   z;supplying 'columns' param value is mandatory for sparklinesr   z.sparkline data range/cols must all be adjacentF)r   r   rb   re   rc   rg   c                "    i | ]\  }}|d v	||S ))rj   r   r   rV   )r_   rd   vals      r5   
<dictcomp>z)_xl_inject_sparklines.<locals>.<dictcomp>9  s4     
 
 
cGGG #GGGr7   negative_pointsr   )columnwin_loss:ri   N)xlsxwriter.utilityr   rK   rL   rM   
ValueErrorrl   RuntimeErrorr   rw   ri   r   add_sparkline)r|   rW   r~   r`   r   r   r   r   	data_colsr   spk_rowspk_col_data_start_coldata_end_coloptions
data_startdata_ends                     r5   _xl_inject_sparklinesr     s    544444A)3FD)A)AM

9%%%vI  KooB	1555  >3-
K^e  GWa !^ahuo5Nq>AeHUO3Lfd## 
W
 
#\\^^
 
 

 G++)0V)<)<@V)VG%&29  &&w??
$$Wl;;(55855
'73331 r7   row_col_pairs	list[str]c                 x    ddl m fdt          |           D             }d t          |          D             S )z@Return list of "A1:B2" range refs from pairs of row/col indexes.r   r   c              3  6   K   | ]\  }} ||          V  d S r2   rV   )r_   rowr`   r   s      r5   ra   z'_xl_rowcols_to_range.<locals>.<genexpr>M  s5      UUc""3,,UUUUUUr7   c                "    g | ]\  }}| d | S )r   rV   )r_   
cell_startcell_ends      r5   
<listcomp>z(_xl_rowcols_to_range.<locals>.<listcomp>N  s+    WWW+?:xz&&H&&WWWr7   )r   r   r6   )r   	cell_refsr   s     @r5   r   r   I  sR    444444UUUUXm=T=TUUUIWW8ICVCVWWWWr7      column_totalsColumnTotalsDefinition | Nonecolumn_formatsColumnFormatDict | Nonedtype_formats$dict[OneOrMoreDataTypes, str] | Noneheader_formatdict[str, Any] | None
sparklines0dict[str, Sequence[str] | dict[str, Any]] | Noneformulas&dict[str, str | dict[str, str]] | None
row_totalsRowTotalsDefinition | Nonefloat_precisiontable_styledict[str, Any] | str | NoneHtuple[list[dict[str, Any]], dict[str | tuple[str, ...], str], DataFrame]c           	         !" d%dfd j                                         D             }|r                     |           t          t	           ddd                    |sd	}i !n2 j         "d
 "                                D              t          |t                    st           "          rt          nt          }|du r n4t          |t                    r|hnt          t           |                    }t          d  j        D                       }| j        dz  k    rdnd d}|t!           |d          i!|g}nUt	           |dd          } "fd|                                D             }  fd|                                D             !|du r.t#                      dit                              |pdd          }nVt          |t                    rA|                                }t#                      |it                              |pd|          }t          t          |t                    rt	           |dd          nt           |                    }t          |t(                    rt                              |d          n*t          |t                    r|                                ni d |pi                                 D             t          pi           t          |pi           }t-          |          D ]_}t          |t.          t0          f          rA|                    t                              ||                    |                               `|                                D ]<}t          |t                    s%d|dt9          |          d}t;          |          =|rt=           |           rt=                      |rt=           !|           |                    ddi          }|
t@          }tB          }nBt@          "                    dd          d         }tB          "                    dd          d         }tF          D ]}|tH          |<   d|	z  }|s|n|%                    d d!|           }tH                                          D ]\  }}|&                    ||           tN          D ]}|&                    ||           |                                D ]
\  }}|||<    j                                         D ]X\  }}|(                                }||v r2|                    |||                   }&                    ||           |vr||<   Y                                D ]\  }}t          |t                    r|                    |dd"          |<   6t          |t                    rNd#|vr) j                             |          }||v r||         |d#<   d|vrd|d<   |                    |          |<   |r|                    |          nd	!fd$ j        D             }| fS )&z7Setup and unify all column-related formatting/defaults.sr#   r0   c                p    |                      | j        d |                                 D                       S )Nc                4    g | ]}|d nt          |          S r2   )rC   )r_   vs     r5   r   z=_xl_setup_table_columns.<locals>._map_str.<locals>.<listcomp>c  s&    JJJaiddSVVJJJr7   )	__class__rd   to_list)r   s    r5   _map_strz)_xl_setup_table_columns.<locals>._map_stra  s6    {{FJJaiikkJJJ
 
 	
r7   c                    g | ]g\  }}|                                 s|                                -t          j        |                                                            |          hS rV   )	is_nested	is_objectr   r`   map_batchesr   )r_   r`   tpr  s      r5   r   z+_xl_setup_table_columns.<locals>.<listcomp>f  sq       C<<>>  \\^^	c

x((..s33  r7   TFr   Nc                @    h | ]\  }}|                                 |S rV   )
is_numeric)r_   r`   r	  s      r5   	<setcomp>z*_xl_setup_table_columns.<locals>.<setcomp>{  s)    MMMRR]]__MMMMr7   c              3  R   K   | ]"}|r|d          nd                                 V  #dS )r   r   N)isupperr_   cs     r5   ra   z*_xl_setup_table_columns.<locals>.<genexpr>  s;      LLA1,1Q44"5577LLLLLLr7   r+   Ttotalsum)r   r   c                `    i | ]*\  }}|t          |d u rn|          rt          nt          +S )T)rr   r   r   )r_   nmrX   numeric_colsrm   s      r5   r   z+_xl_setup_table_columns.<locals>.<dictcomp>  sU           B (4QWXX!EE 	     r7   c                F    i | ]\  }}|t          |d u rn|d          S )Tr  )_xl_table_formula)r_   rd   rX   rW   r  s      r5   r   z+_xl_setup_table_columns.<locals>.<dictcomp>  sO        D$ '4%   r7   rV   c                L    i | ]!\  }}|t          |t                    rd |in|"S )formula)rK   rC   )r_   r`   r   s      r5   r   z+_xl_setup_table_columns.<locals>.<dictcomp>  sG       C 	Z%=%=Ji!!7  r7   zinvalid dtype_format value: z (expected format string, got ))r   valignvcenter;rb   r   0z.000.)r   r  r   c                   g | ]{}d  ||                              |                               |          p(                     |i                                d          d                                D             |S )c                    i | ]
\  }}|||S r2   rV   )r_   rz   r  s      r5   r   z6_xl_setup_table_columns.<locals>.<listcomp>.<dictcomp>  s/     	
 	
 	
1 } q }}r7   r  )headerr   r   total_functionr  )rM   rw   )r_   r`   col_header_formatr   column_formulascolumn_total_funcsrow_total_funcss     r5   r   z+_xl_setup_table_columns.<locals>.<listcomp>  s        	
 	
 (-!2"4"8"8"="=#'',, C&**33377	BB	 	 egg	
 	
 	
  r7   )r   r#   r0   r#   ))rm   rw   with_columnsr{   r   rK   rL   rr   r   r   rC   r   r   r  rj   widthr  r   fromkeyslowerr   r   listtuple	frozensetupdatepopvaluesr   	TypeErrorr   rM   _XL_DEFAULT_INTEGER_FORMAT__XL_DEFAULT_FLOAT_FORMAT_splitr   r8   replace
setdefaultr   	base_type)#rW   r   r   r   r   r   r   r   r   r   r   	cast_colsrow_totals_dtypesum_colsn_ucasetotalfnr	  rA   r   fmt_defaultint_base_fmtflt_base_fmtzeros	fmt_floatr`   r:  table_columnsr  r&  r'  r(  r  r)  rm   s#   `  `                        @@@@@@@r5   _xl_setup_table_columnsrG  Q  s    
 
 
 

   y((  I
  (__Y'' /DRV	
 	
 	
 N  (MM6<<>>MMM*d++ "	*<@@Mg 
 %%  "*c22@ZLL.r:>>??  LLLLLLLG&Q66ssSFFFE$&7He&L&LMOJJ/JE  J          !+ 0 0 2 2          #-"2"2"4"4	  O  ETT]]:;KU-S-ST	M3	'	' O  "" BN$--
8Hb"*M*MN-mT**	2r=dRWXXXXr=11 M mX..	OmU+++&0&E&EMm  """2  %^2244  O ..B//N,"--M=!! K Kb5),-- 	K  r=3D3DR3H3H!I!IJJJ##%% ! !#s## 	!sssVijmVnVnsssCC.. 	!
  <+B
;; A+B@@ Y+BGWXXX ""Hi#899K20 388a@@C066sA>>qA 6 6)5"2&&/!E$)X|/C/CFKPUKK/X/XI .3355 * *C  S)))) 0 0  Y//// &&((    Cb 9??$$ . .RLLNN	%%##Bi(@AAC%%c3///n$$"-N3 #((** 8 8Sc3 	8"."2"2"i88# #N3 T"" 	83&&Y]]3''&&(5b(9C%s"" )H"."2"23"7"7N3 <IR((777d        :  M" .",,r7   2tuple[dict[str, Any] | str | None, dict[str, Any]]c                    t          | t                    rJd}| D ]}||vrd|}t          |          |                                 }|                    dd          } ni }| |fS )zESetup table options, distinguishing style name from other formatting.)stylebanded_columnsbanded_rowsfirst_columnlast_columnzinvalid table style key: rJ  N)rK   rL   r   r   r2  )r   valid_optionsrP   r   table_optionss        r5   _xl_setup_table_optionsrQ    s     +t$$ 
  	& 	&C-''9#99 oo% ( $((**#''66%%r7   Freturn_worksheetr;   r   rS  bool | Worksheetc                   t          fd|                                 D                       r|rndS d| j        dj        }t	          |          )Nc              3      K   | ]}|u V  	d S r2   rV   )r_   sheetr|   s     r5   ra   z,_xl_worksheet_in_workbook.<locals>.<genexpr>2  s'      
4
452;
4
4
4
4
4
4r7   Tzthe given workbook object z  is not the parent of worksheet )any
worksheetsfilenamerd   r   )r;   r|   rS  r   s    `  r5   _xl_worksheet_in_workbookr[  /  sh     
4
4
4
4BMMOO
4
4
444 0%/rr4/
ar{
a
aVXV]
a
aC
S//r7   workbook&Workbook | BytesIO | Path | str | None	worksheetstr | Worksheet | None tuple[Workbook, Worksheet, bool]c                <   ddl m} ddlm} t	          | |          r>| d}}t	          ||          rt          ||          r|n|                    |          }nt	          ||          rd| }t          |          ddt          t                   d}t	          | t                    r || |          d	d}}}n| t          d
          }	n't	          | t                    rt          |           }	n| }	t	          |	t                    rD|	j        r|	n|	                    d                                                              d          }	 ||	|          }d\  }}|9t	          ||          rt          ||d          }n|                    |          }|||fS )z2Establish the target Excel workbook and worksheet.r   r   r   F)rd   zEworksheet object requires the parent workbook object; found workbook=T)nan_inf_to_errorsstrings_to_formulasdefault_date_formatNzdataframe.xlsxz.xlsx)strict)NTrR  )
xlsxwriterr   xlsxwriter.worksheetr    rK   r[  get_worksheet_by_namer4  r8   r   r   r   rC   r   suffixwith_suffix
expanduserresolveadd_worksheet)
r\  r^  r   r    r;   	can_closer|   r   workbook_optionsfiles
             r5   _xl_setup_workbookrq  8  s   
 $#####......(H%% $' %I 9i00: .b)<<:II
 ))y)99 	 
Iy	)	) 'bV^bbnn "&#(#=d#C
 

 h(( 	' (3C D DdDIBB,--Hc**  H~~$)) ![GTTd.>.>w.G.GZ\\WEW** 
 $ 011B&MB		zi++ 	2*2y4PPPBB!!y!11Br9r7   funcc                :   i }t          |t                    r|g}t          | ||          r6d|                                 d|d         d          d|d         d          dS d	                    d
 |D                       }d|                                 d| dS )zIReturn a formula using structured references to columns in a named table.r   =z([@[re   rd   z]:[rg   z]]),c              3  "   K   | ]
}d | dV  dS )z[@[z]]NrV   r  s     r5   ra   z$_xl_table_formula.<locals>.<genexpr>v  s*      551;;;;555555r7   (r  )rK   rC   rl   upperr   )rW   rX   rr  r   colrefss        r5   r  r  n  s    A$ vb$*** -O4::<<OOQuXf%5OO!E(6:JOOOO((5555555,4::<<,,',,,,r7   c                    dt                      }|                                 D ](}|                    fd|j        D                        )t	          |          } | }||v r|dz  } | }||v |S )z4Establish a unique (per-workbook) table object name.Framec              3  ^   K   | ]'}|d                                         |d          V  (dS )rd   N)
startswith)r_   tbltable_prefixs     r5   ra   z(_xl_unique_table_name.<locals>.<genexpr>  sR       
 
F0F0F|0T0T
K
 
 
 
 
 
r7   rb   )r   rY  r1  tablesr   )r;   polars_tablesr|   r.   
table_namer  s        @r5   _xl_unique_table_namer  z  s    L!eeMmmoo 
 
 
 
 
 
#%9
 
 
 	
 	
 	
 	
 	MA %!%%J

%
%	Q$)a))
 
%
% r7   )r+   )r,   r-   r.   r/   r0   r-   )rW   r!   rX   rY   rZ   rB   r0   r[   )rX   rY   rm   r"   r0   r[   )rs   rt   r0   ru   )rW   r!   r|   r    r}   r&   r~   r   r   r[   r   r:   r0   r<   )rW   r!   r~   r   r`   r   r   r[   r   r   r0   rC   )rW   r!   r~   r   r`   r   r   r[   r   r   r0   r   )rW   r!   r~   r   r`   r   r   r[   r   r[   r0   r   )
rW   r!   r~   r   rX   rY   r   r[   r0   rC   )
rW   r!   r   rB   r   r   r   r   r0   r!   )r|   r    rW   r!   r~   r   r`   rC   r   r[   r   r   r0   r<   )r   r/   r0   r   )	NNNNNNNr   N)rW   r!   r   r:   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r/   r   r   r0   r   )r   r   r0   rH  )r;   r   r|   r    rS  r[   r0   rT  r2   )r\  r]  r^  r_  r0   r`  )rW   r!   rX   rY   rr  rC   r0   rC   )r;   r   r0   rC   )M
__future__r   collections.abcr   ior   osr   pathlibr   typingr   r	   r
   polarsr   r   polars._utils.variousr   polars.datatypesr   r   r   r   r   polars.datatypes.groupr   r   polars.dependenciesr   polars.exceptionsr   polars.selectorsr   r   r   r   r   rf  r   r   r   rg  r    r!   r"   r#   polars._typingr$   r%   r&   r'   r(   r)   polars.exprr*   r6   r6  r5  r8   __annotations__r:   rl   rr   r{   r   r   r   r   r   r   rG  rQ  r[  rq  r  r  rV   r7   r5   <module>r     s   " " " " " " " $ $ $ $ $ $                   / / / / / / / / / / ! ! ! ! ! ! 5 5 5 5 5 5              @ ? ? ? ? ? ? ? $ $ $ $ $ $ , , , , , , O O O O O O O O O O !((((((######((((((......0000000000                !     & & & & & 8 1 #.,9            .	 	 	 	9 9 9 9
   /2 /2 /2 /2d 
 "     
 
$ $ $ 
$  & & & & & &.   4 @D3 3 3 3 3 3l, , , ,^X X X X 48.2:>+/CG7;-1/3B- B- B- B- B-J& & & &4 >C      )-3 3 3 3 3l	- 	- 	- 	-     r7   