
    >ie                        d dl mZ 	 d dlmZmZ d dlmZmZ d dl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(dZd)dZd*dZ G d d          Z edd          Z	 	 d+d,dZd-d!Zd.d$Zd/d&ZdS )0    )annotations)defaultdict
namedtuple)MappingMutableMapping)log)Anycast)get_dependenciesget_depsgetcycleistaskreverse_dict)KeyNdskMutableMapping[Key, Any]dependencies$MutableMapping[Key, set[Key]] | Nonereturndict[Key, int]c           	        @ABCDEF  si S t                       fd D             t                    @t          @          \  BFt          @F          At	          A          t	                     k    r?t           d          }t          dd                    d |D                       z            d @                                D             }t	          |          dk    rHt          t          t                                }d+d}|g|R  |<   ||<   t                     }||= |S d @Afd                                D             D             }|j        }d,@ABfd}	d,@ABFfd}
Ft          |          d                  EEFfdA                                D             Ci Dd}t          ||          g}|j        }g }|j        }|j        }|j        }t'          t                    }g }|j        }|j        }t)          |          }|j        }|j        }i }|j        }g }|j        }|j        }t(          j        }d}	 	 t)                      } d}!|r |            }"|"Dv r"B|"         r|"|vr|                    |"            ||"         D          } dt	          |           cxk     rdk     r)n n&|                    t3          | |
d                     n|                    |             ||            |s|rB|d                  rd}#n|D|"<   |dz  }@|"         } d}!| r| D ]}$B|$xx         dz  cc<   d}#n|r |            }|j        }|rd}#n|r|D ]_}%|%Dv r	 @|%         }&|D|%<   |dz  }|&rB|&D ]}$B|$xx         dz  cc<   t	          |&          dk    r|&\  }%B|%         s	@|%         }&R| |&z  } ~&` |              || D          } | sd}!d}#nnm|#rh|re|s|rdnd}! |t)          |          D          }'t3          |'Cfd          D ]}%||%         }(t	           | |@|(         D          |                    dk    r ||%           D	 @|%         }&|D|%<   |dz  }|&r|&D ]}$B|$xx         dz  cc<   |!rV|&|z  })|)rNt	          |&          t	          |)          k    r)t	          |)          dk    r|)\  }%B|%         s	@|%         }&{nQ|&|)z
  }&nt)                      })t	          |&          dk    r#|&\  }%B|%         s|)s	@|%         }& ||%           n| |&z  } ~&	 ~' || D          }  |             | sd}!| |z  })|)rNt	          |           t	          |)          k    r't	          |)          dk    r|)\  }$B|$         s|"||$<   ~$Vd}!| |)z
  } t	          |           dk    rT| \  }$|!r|s|$g}|j        } ||$           C|$         }*B|$         s|"||$<   n||*                             |            ~$~*nDt	          |           dk    r| \  }$}+C|$         }*C|+         },|,|*k     s|*|,k    r  |	|+           |	|$          k     r|+|$}+}$|,|*},}*|rC|d                  }-|,|-k     rH ||            ||+g           |$g}|j        } ||            B|+         s|#r ||+           n|"||+<   n|*|-k     rY ||           |$g}|j        } ||$           B|+         s|#r ||+           nr|"||+<   nl||,                             |+g           nOC|"         }.|*|$f|,|+ffD ]=\  }/}0B|0         s|#r ||0           |"||0<   !||/                             |0g           >~.~-n|rJ |!rp|$g}|j        } ||$           B|+         s|"||+<   nw|*|,k    r*dC|"         z  d |*z  k    r ||+g            ||+           nG||,                             |+g           n*|*|$f|,|+ffD ]!\  }/}0||/                             |0g           "~$~+~*~,n:t'          t(                    }1t'          t(                    }2| D ]J}$C|$         }3B|$         s|#s|2|3                             |$           |1|3                             |$           KC|"         }.|r1C|d                  }-g }4t)                      }5|1                                D ]U\  }*}6|*|-k     r|4                    |*           n2|2|*         }5|5D ]}7|"||7<   |6|5z  }6||*                             |6           ~6~*V~5|4r ||           dt	          |4          k     r|4                    d!           |4D ]Z}*|1|*         }8dt	          |8          cxk     rd"k     rn nt3          |8|	d          }8 |d# |8D                         ||8           ~8[ |            }|j        }~4~-n|!r8t          |1          }9|1                    |9          }:t	          |:          dk    rt          |:          } ||           nd$|.z  d%t	          |:          z  t	          |:          z  |9z  k    rPt	          |:          d"k     rt3          |:|	d          }: |d& |:D                         |            } ||:           nat	          |:          d"k     rt          |:|	          g}n|:                                g}||9                             |:            ||           ~:~9|j        }|1                                D ]9\  }*}6|2|*         }5|5D ]}7|"||7<   |6|5z  }6||*                             |6           ~*~6:		t	                    t	          D          k    rn|rPt3          |d!          D ]*}* |d' t7          ||*                   D                        +|                                 g };|roDfd( |            D             };|;rUdt	          |;          cxk     rd"k     rn n|;                    |	d            |d) |;D                         ||;           n|o~;|r	|st	          |          }<t)          |          } ||D          }t	          |          }=|<|=z
  }>|>|=k    s/|=|=|>z
  t9          |=|>z
            z  z   |=t9          |=          z  k     rt          ||          }"
t	          |          d*k     rt3          ||d          }nt          |          }|j        }?d}|"|v r
 |?            }"|"Dv r |?            }"|"Dv |                    |"           
DS )-a  Order nodes in dask graph

    This produces an ordering over our tasks that we use to break ties when
    executing.  We do this ahead of time to reduce a bit of stress on the
    scheduler and also to assist in static analysis.

    This currently traverses the graph as a single-threaded scheduler would
    traverse it.  It breaks ties in the following ways:

    1.  Begin at a leaf node that is a dependency of a root node that has the
        largest subgraph (start hard things first)
    2.  Prefer tall branches with few dependents (start hard things first and
        try to avoid memory usage)
    3.  Prefer dependents that are dependencies of root nodes that have
        the smallest subgraph (do small goals that can terminate quickly)

    Examples
    --------
    >>> inc = lambda x: x + 1
    >>> add = lambda x, y: x + y
    >>> dsk = {'a': 1, 'b': 2, 'c': (inc, 'a'), 'd': (add, 'b', 'c')}
    >>> order(dsk)
    {'a': 0, 'c': 1, 'b': 2, 'd': 3}
    Nc                2    i | ]}|t          |          S  )r   ).0kr   s     *lib/python3.11/site-packages/dask/order.py
<dictcomp>zorder.<locals>.<dictcomp>{   s&    AAA+C33AAA    z2Cycle detected between the following keys:
  -> %sz
  -> c              3  4   K   | ]}t          |          V  d S N)str)r   xs     r   	<genexpr>zorder.<locals>.<genexpr>   s(      33SVV333333r   c                    h | ]	\  }}||
S r   r   r   r   vs      r   	<setcomp>zorder.<locals>.<setcomp>   s!    <<<1!<!<<<r      argsr	   kwargsr   Nonec                     d S r    r   )r)   r*   s     r   _fzorder.<locals>._f   s    Dr   c           
     Z    i | ](\  }}\  }}}}}|||z
  ||z
  | |t          |          f)S r   )StrComparable)r   keynum_dependentstotal_dependents_min_heightsmax_heightss          r   r   zorder.<locals>.<dictcomp>   sk       
C "
! 	[([(#

  r   c              3  ^   K   | ]'\  }}||t          |                   |         fV  (d S r    len)r   r0   val
dependentsmetricss      r   r#   zorder.<locals>.<genexpr>   sX       
 
S
#jo&&5
 
 
 
 
 
r   r"   r   tuplec                    J t          |                    t          |                    z
  |          z   |          d          t          |           fS )zChoose a path from our starting task to our tactical goal

        This path is connected to a large goal, but focuses on completing
        a small goal and being memory efficient.
        N   r8   r/   )r"   r   r:   r;   
num_neededs    r   dependents_keyzorder.<locals>.dependents_key   s`     ''' 
1\!_!5!55
1E QZ]N!	
 		
r   c           	         J t          |                    }|          \  }}}}}||z   ||z   
|           |t          |                    z
  	|          z   ||t          |           fS )z}Choose which dependency to run as part of a reverse DFS

        This is very similar to both ``initial_stack_key``.
        r?   )r"   r1   r2   r3   r4   r5   r   r:   r;   r@   total_dependenciess         r   dependencies_keyzorder.<locals>.dependencies_key   s    
 '''Z]++ AJ	

 [([(""Sa111JqMA!

 
	
r   r   c                L    i | ] \  }\  }}}}}||         z
  d z   ||z
  z  !S )r(   r   )r   r0   r2   r3   r4   root_total_dependenciesrC   s        r   r   zorder.<locals>.<dictcomp>   sa       

C 
 	$'9#'>>B+-/  r   r0   FTi  )r0   reversec                    |          S r    r   )r"   partition_keyss    r   <lambda>zorder.<locals>.<lambda>  s    PQAR r            )rH   d   c              3     K   | ]}|gV  d S r    r   r   deps     r   r#   zorder.<locals>.<genexpr>  s$      /F/F#/F/F/F/F/F/Fr   
      c              3     K   | ]}|gV  d S r    r   rR   s     r   r#   zorder.<locals>.<genexpr>  s$      /J/J#/J/J/J/J/J/Jr   c              3  4   K   | ]}t          |          V  d S r    )list)r   els     r   r#   zorder.<locals>.<genexpr>  s(      "P"P488"P"P"P"P"P"Pr   c                    g | ]}|v|	S r   r   )r   r"   results     r   
<listcomp>zorder.<locals>.<listcomp>  s    JJJ!6//!///r   c              3     K   | ]}|gV  d S r    r   rR   s     r   r#   zorder.<locals>.<genexpr>  s$      #@#@cSE#@#@#@#@#@#@r   i'  )r)   r	   r*   r	   r   r+   )r"   r   r   r<   )dictr   ndependenciesgraph_metricsr8   r   RuntimeErrorjoinitemsr
   r   objectorder__getitem__rX   minpopappendextendr   setupdateaddclear
differencesortedsortreversedr   )Gr   r   cycle
root_nodesrootr-   o
init_stackinitial_stack_keyrA   rD   iinner_stackinner_stack_popinner_stacksinner_stacks_appendinner_stacks_extendinner_stacks_pop
next_nodesouter_stackouter_stack_extendouter_stack_popseenseen_updateseen_addsinglessingles_clearlater_singleslater_singles_appendlater_singles_clearset_differenceis_init_sorteddepsadd_to_inner_stackitemprocess_singlesrS   singledeps_singlessingles_keysparentalready_seenr0   dep2key2prev_keyitem_keyr   d	dep_poolspossible_singlespkeynow_keyspsinglesvalsspoolmin_keymin_pool
outer_depsprev_lenNminit_stack_popr:   r;   r@   rK   r[   rF   rC   sG   ``                                                              @@@@@@@r   re   re   Y   sj   8  	
s))CAAAASAAAl++J%2<%L%L"J"L*6HIIG
7||s3xxd##Ann33U333334
 
 	
 =<
 0 0 2 2<<<J
: C""	 	 	 	 %*%%D	'T#|$$dG
 &
 
 
 
 
(..00
 
 
'  J6 #.
 
 
 
 
 
 
 
 
&
 
 
 
 
 
 
 
 
 
8 1j1A1A!1DE     ]]__  N  F	A z'8999:K!oO$&L&-&-#' @K4?P?PJ $&K$+!oO z??D+KxHP !GMM!M(/'- ^NNR!Y	&55D!% I&((6>>d#  !:--#**4000-~l4.@&IIs4yy////4/////'.. &t1A4 P P P    (..t444#D)))" !  # !z+b/'B ! &*OO#$F4LFA%d+D)-& !#' 1 1C&sOOOq0OOOO*/  $..00"-/  "&  ,  F'' '1&'9)*vQ' 
1'3 5 5 *31 4"<00A55,8	'1&'9 !-3=f3EL$, L0D(##%%%%~dF33 %*""& G+7 G+ .9%SL%STTe"-~c'llFCC %\7R7R7R7RSSS 9 9F %V_F*N .z&/A6 J J $     -,V444 #'1&'9)*vQ' 1'3 5 5 *31 41 5/;d/B#/ !O (+<'8'8C<M<M'M'M+.|+<+<+A+A8DIV3=f3E -9?I&?Q08(-3?,3NL/2uu"<00A55,8	'1&'9 !*+7 %17A&7I(0$8$8$@$@$@$) L0D( %~dF33 %*"  $;L 	+t99L 1 111<((A--!-)# 0+/GCL%*"l*4yyA~~% k #&%K&1oOHSMMM$S)!# 1 $(GCLLsO**4000Ta !	T$S)%d+3JJd{{&t,,~~c/B/BBB $cC $cC 46-k!n=Hh++K888++TF333'*e*5/#D))))$/ 5. 5 4 4T : : : :04x++K888'*e*5/ )$/ <. 5 4 4T : : : :04&t,33TF;;;;#1$#7&)3Z$$> : :DAq#-a= :#2 !6$8$8$;$;$;$;15GAJJ *1 4 4aS 9 9 9 9$ ****) 6'*e*5/ )$/ <,0GDMM D[[Q1E-ES-P-P//777$HTNNNN&t,33TF;;;;&)3Z$$> 6 6DAq&qM00!5555sDD (,,	#.s#3#3  - -C)#.D%c? 8? 8(.223777dO'',,,,)$/ M&-k!n=H!H"uuH%.__%6%6 	& 	&	T>>$OOC0000'7'<H%- 2 2-1

 H,D&sO224888 ##  :++K888s8}},,$MM$M777#+ % %C#,S>D 3t992222s22222'-dPT'U'U'U///F/F/F/F/FFFF'K--- $&6&6&8&8*5/ (( * #:"%i..#,==#9#9x==A--*.x..K'K4444MBX,>X,NQX,XXX  #8}}s22+1$,.$," ," ," 0//J/J/J/J/JJJJ*:*:*<*<K'K1111  #8}}s22/28/P/P/P.Q/7||~~.>&w/66x@@@'K444$g*5/%.__%6%6 & &	T#3C#8!) . .A)-GAJJ("3..t444s
Y	&v
 |F++ 	j$777 Q Q #""P"Phz#6O6O"P"P"PPPPP
 	JJJJ__%6%6JJJJ s:,,,,,,,,,OOOEEE###@#@Z#@#@#@@@@J'''  	  	  	":HZJ'
F;;JJA1AAvva!es1q5zz11AAJ>>:+<===:&&#J4EtTTT

!*--
'^N!N:!>##Dfnn!>##D fnn4   eR!h Mr   Mapping[Key, set[Key]]r:   rC   Mapping[Key, int])dict[Key, tuple[int, int, int, int, int]]c                   i d |                                 D             }g }|j        }|j        }|                                 D ]G\  }}|s@||         }	d|	|	ddf|<   | |         D ]%}
||
xx         dz  cc<   ||
         s ||
           &H|r |            }||         }t          |          dk    r&|\  }|         \  }}}}}d|z   ||d|z   d|z   f|<   nut	          fd||         D              \  }}}}}dt          |          z   t          |          t          |          dt          |          z   dt          |          z   f|<   | |         D ]%}
||
xx         dz  cc<   ||
         s ||
           &|S )a  Useful measures of a graph used by ``dask.order.order``

    Example DAG (a1 has no dependencies; b2 and c1 are root nodes):

    c1
    |
    b1  b2
     \  /
      a1

    For each key we return:

    1.  **total_dependents**: The number of keys that can only be run
        after this key is run.
        Note that this is only exact for trees. (undirected) cycles will cause
        double counting of nodes. Therefore, this metric is an upper bound
        approximation.

        1
        |
        2   1
         \ /
          4

    2.  **min_dependencies**: The minimum value of the total number of
        dependencies of all final dependents (see module-level comment for more).
        In other words, the minimum of ``ndependencies`` of root
        nodes connected to the current node.

        3
        |
        3   2
         \ /
          2

    3.  **max_dependencies**: The maximum value of the total number of
        dependencies of all final dependents (see module-level comment for more).
        In other words, the maximum of ``ndependencies`` of root
        nodes connected to the current node.

        3
        |
        3   2
         \ /
          3

    4.  **min_height**: The minimum height from a root node

        0
        |
        1   0
         \ /
          1

    5.  **max_height**: The maximum height from a root node

        0
        |
        1   0
         \ /
          2

    Examples
    --------
    >>> inc = lambda x: x + 1
    >>> dsk = {'a1': 1, 'b1': (inc, 'a1'), 'b2': (inc, 'a1'), 'c1': (inc, 'b1')}
    >>> dependencies, dependents = get_deps(dsk)
    >>> _, total_dependencies = ndependencies(dependencies, dependents)
    >>> metrics = graph_metrics(dependencies, dependents, total_dependencies)
    >>> sorted(metrics.items())
    [('a1', (4, 2, 3, 1, 2)), ('b1', (2, 3, 3, 1, 1)), ('b2', (1, 2, 2, 0, 0)), ('c1', (1, 3, 3, 0, 0))]

    Returns
    -------
    metrics: Dict[key, Tuple[int, int, int, int, int]]
    c                8    i | ]\  }}||t          |          S r   r7   r%   s      r   r   z!graph_metrics.<locals>.<dictcomp>O  s)    @@@1a@!SVV@@@r   r(   r   c              3  (   K   | ]}|         V  d S r    r   )r   r   r[   s     r   r#   z graph_metrics.<locals>.<genexpr>v  s'      CCfVnCCCCCCr   )rc   rh   ri   r8   zipsumrg   max)r   r:   rC   r@   currentcurrent_popcurrent_appendr0   r   r9   childparentsr   r2   min_dependenciesmax_dependenciesr4   r5   total_dependents_min_dependencies_max_dependencies_min_heights_max_heights_r[   s                          @r   r`   r`     s>   b F@@
(8(8(:(:@@@JG+K^N%%'' * *	T 	*$S)Cc31-F3K%c* * *5!!!Q&!!!!%( *"N5)))
 %&kmmS/w<<1IV v    $$  KKF3KK CCCC:c?CCCD!!! C)***%&&%&&C%%%C%%%F3K "#& 	& 	&Eu"e$ &u%%%K  %&L Mr   %tuple[dict[Key, int], dict[Key, int]]c                   i }i |                                  D ]\  }}t          |          ||<   |sd|<   |                                }g }|j        }|j        }D ]0}	||	         D ]%}
||
xx         dz  cc<   ||
         s ||
           &1|ra |            }	dt          fd| |	         D                       z   |	<   ||	         D ]%}
||
xx         dz  cc<   ||
         s ||
           &|a|fS )aG  Number of total data elements on which this key depends

    For each key we return the number of tasks that must be run for us to run
    this task.

    Examples
    --------
    >>> inc = lambda x: x + 1
    >>> dsk = {'a': 1, 'b': (inc, 'a'), 'c': (inc, 'b')}
    >>> dependencies, dependents = get_deps(dsk)
    >>> num_dependencies, total_dependencies = ndependencies(dependencies, dependents)
    >>> sorted(total_dependencies.items())
    [('a', 1), ('b', 2), ('c', 3)]

    Returns
    -------
    num_dependencies: Dict[key, int]
    total_dependencies: Dict[key, int]
    r(   c              3  (   K   | ]}|         V  d S r    r   )r   r   r[   s     r   r#   z ndependencies.<locals>.<genexpr>  s'      KKfUmKKKKKKr   )rc   r8   copyrh   ri   r   )r   r:   r@   r   r&   num_dependenciesr   r   r   r0   r   r[   s              @r   r_   r_     s|   , JF""$$  1A
1 	F1I!((G+K^N ' ' o 	' 	'Fv!#f% 'v&&&	'  'kmm#KKKKc9JKKKKKKs o 	' 	'Fv!#f% 'v&&&  ' V##r   c                  2    e Zd ZU dZdZded<   ddZdd	Zd
S )r/   a  Wrap object so that it defaults to string comparison

    When comparing two objects of different types Python fails

    >>> 'a' < 1
    Traceback (most recent call last):
        ...
    TypeError: '<' not supported between instances of 'str' and 'int'

    This class wraps the object so that, when this would occur it instead
    compares the string representation

    >>> StrComparable('a') < StrComparable(1)
    False
    objr	   r   c                    || _         d S r    r   )selfr   s     r   __init__zStrComparable.__init__  s    r   otherr   boolc                    	 | j         |j         k     S # t          $ r- t          | j                   t          |j                   k     cY S w xY wr    )r   	Exceptionr!   )r   r   s     r   __lt__zStrComparable.__lt__  sR    	28ei'' 	2 	2 	2tx==3uy>>1111	2s    4A	A	N)r   r	   )r   r	   r   r   )__name__
__module____qualname____doc__	__slots____annotations__r   r   r   r   r   r/   r/     sX            IHHH   2 2 2 2 2 2r   r/   	OrderInfo)re   agenum_data_when_runnum_data_when_releasednum_dependencies_freedrv   Mapping[Key, int] | None&tuple[dict[Key, OrderInfo], list[int]]c                l   |t          |           \  }}nt          |          }|t          | |          }g }d}i i i i d |                                D             }t	          t          | |j                            D ]\  }}|                    |           ||<   d}	||         D ]6}
||
xx         dz  cc<   ||
         dk    r|||
         z
  |
<   ||
<   |	dz  }	7|	|<   ||         r	||	dz
  z  }vd|<   ||<   ||	z  }fd|                                D             }||fS )a  Simulate runtime metrics as though running tasks one at a time in order.

    These diagnostics can help reveal behaviors of and issues with ``order``.

    Returns a dict of `namedtuple("OrderInfo")` and a list of the number of outputs held over time.

    OrderInfo fields:
    - order : the order in which the node is run.
    - age : how long the output of a node is held.
    - num_data_when_run : the number of outputs held in memory when a node is run.
    - num_data_when_released : the number of outputs held in memory when the output is released.
    - num_dependencies_freed : the number of dependencies freed by running the node.
    N)r   r   c                4    i | ]\  }}|t          |          S r   r7   )r   r0   r9   s      r   r   zdiagnostics.<locals>.<dictcomp>   s$    CCCHC#s3xxCCCr   rG   r(   c                n    i | ]1\  }}|t          ||         |         |         |                   2S r   )r   )r   r0   r9   r   freedreleasepressurerunpressures      r   r   zdiagnostics.<locals>.<dictcomp>  sX     
 
 
 C 	YS;s+_S-A5:
 

 
 
r   )r   r   re   rc   	enumeraterp   rf   ri   )r   rv   r   r:   pressurenum_in_memoryr@   ry   r0   releasedrS   rvr   r   r   r   s               @@@@r   diagnosticsr     s   $ #+C== jj!,//
y#L111HM
CKOECC
0@0@0B0BCCCJF3AM:::;; & &3&&&(C$ 	 	CsOOOq OOO#!##qv:C'4$Ac
c? 	&X\)MMCH#0OC X%MM
 
 
 
 
 
 
 			
 
 
B x<r   r+   c                     d S r    r   r   r   r   r-   r-     s    Cr   taskr	   c                   t          |           rt          | d                   sJ g }| dd          D ]}t          |t          t          f          r|                    |           4t          |t                    rHt          |          r#|                    t          |                     {|                    |           t          |t                    r|                    d |D                        t          g|R S | S )Nr   r(   c                ,    g | ]}t          |          S r   )_convert_task)r   es     r   r\   z!_convert_task.<locals>.<listcomp>-  s      > > >aq!1!1 > > >r   )
r   callable
isinstancer!   intri   r<   r   rX   r-   )r   new_specrY   s      r   r   r      s   d|| Q      qrr( 		@ 		@B"sCj)) @####B&& @":: (OOM"$5$56666OOB''''B%% @ > >2 > > >???Xr   r^   c                    i }|                                  D ]\  }}|}t          |          ||<   t          |          t          |           k    rt          d          |S )zTake a dask graph and replace callables with a dummy function and remove
    payload data like numpy arrays, dataframes, etc.
    z)Sanitization failed to preserve topology.)rc   r   r   ra   )r   newr0   valuesnew_keys        r   sanitize_dskr   3  sg     Cyy{{ - -V$V,,G}}%%FGGGJr   r    )r   r   r   r   r   r   )r   r   r:   r   rC   r   r   r   )r   r   r:   r   r   r   )NN)r   r   rv   r   r   r   r   r   )r   r+   )r   r	   r   r	   )r   r   r   r^   )
__future__r   collectionsr   r   collections.abcr   r   mathr   typingr	   r
   	dask.corer   r   r   r   r   dask.typingr   re   r`   r_   r/   r   r   r-   r   r   r   r   r   <module>r      s   " " " " " "LZ 0 / / / / / / / 3 3 3 3 3 3 3 3               P P P P P P P P P P P P P P      
 :>a
 a
 a
 a
 a
HE E E EP.$ .$ .$ .$b2 2 2 2 2 2 2 2> J	 		 #'9=8 8 8 8 8v      &     r   