
    &`i                     	   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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 d dlmZ d dlmZmZmZmZmZmZ d dlZd dlZd dl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%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ d d
l,m-Z-m.Z. d dl/m0Z0m1Z1 d dl2m3Z3m4Z4 d dl5m6Z6 d dl7m8Z8 d dl9m:Z:m;Z;m<Z< d dl=m>Z> d dl?m@Z@mAZAmBZBmCZCmDZDmEZEmFZF d dlGmHZH d dlImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZR d dlSmTZTmUZU d dlVmWZW 	 d dlXmYZY n# eZ$ r	 d dl[mYZY Y nw xY w ej\        e]          Z^g dZ_dZ`eeeaeaf         eeeaeaf                  f         Zbdeecef         ddfdZddeecef         deee         fdZfdeecef         deeddfdZg	 d}d!ehd"eec         decfd#Zi	 	 	 d~d$eea         d%eeee                  d&eeee                  ddfd'Zj	 	 	 	 	 dd)ecd*eea         d+eea         d,ehd-ehd.ehd/eec         d0ehd1eeh         d2ehd3ehdeecef         fd4Zkd5Zl	 ddeecef         d0ehdeecef         fd6Zmd)ecd.ehd7ehd/eec         d8ehddfd9Znd)ecd.ehd:ehd/eec         deec         f
d;Zod<ecd=ead/eec         ddfd>Zp	 dd?eec         d3ehddfd@Zqd defdeecef         dAecd,ehd-ehd.ehd/eec         d3ehdBeeH         dCeddfdDZrdEeec         dFecdGecdHeHdehf
dIZsdeecef         dHeHd,ehdeeecef         ef         fdJZt	 	 	 dd)ecdKehdLehdMehd/eec         d0ehdNehdOeeb         ddfdPZuddQd d d d dd dd d ddRd)ecdSeec         dTecdUehdVehdWehdKehd/eec         d0ehdOeeb         dXehdYehdZeec         decfd[Zv	 	 	 	 	 	 	 	 dd\e>dSeec         dUehdVehdOeeb         dXehdTecd]ehdZeec         decfd^Zwdd d d d(efd)ecd_eec         d`eec         d/eec         daehdbeec         dcehd0ehddehdeehdCeddfdfZx	 dd)ecd/eec         decfdgZy	 dd)ecd/eec         deec         fdhZzdeecef         d/eec         deec         fdiZ{	 	 	 ddeecef         dAecd/eec         djehdBeeH         dYehdecfdkZ|	 	 	 	 	 	 	 	 ddlehdmeec         dnehdoehdpehdqehdrehdseec         deec         fdtZ}	 	 	 	 	 	 	 	 	 	 	 	 	 dd<eec         dueec         dveec         dweec         dxeec         dyeeh         dmeec         dnehdoehdpehdqehdrehdseec         deec         fdzZ~d{ecd.ehdeeh         fd|ZdS )    N)ThreadPoolExecutor)
ModuleType)AnyDictListOptionalTupleUnion)	usage_lib)subprocess_output_util)AutoscalerSummary)cf
cli_logger)ArchiveGetParametersNode_info_from_params)create_archive_for_local_and_remote_nodescreate_archive_for_remote_nodesget_all_local_data)set_rsync_silentset_using_login_shells)#AUTOSCALER_RESOURCE_REQUEST_CHANNELMAX_PARALLEL_SHUTDOWN_WORKERS)CreateClusterEventglobal_event_system)LogTimer)NodeAvailabilitySummary)_NODE_PROVIDERS_PROVIDER_PRETTY_NAMES_get_node_provider)NodeUpdaterThread)LoadMetricsSummaryformat_info_stringhash_launch_confhash_runtime_confprepare_configvalidate_config	with_envs)NodeProvider)	NODE_KIND_HEADNODE_KIND_WORKERSTATUS_UNINITIALIZEDSTATUS_UP_TO_DATETAG_RAY_LAUNCH_CONFIGTAG_RAY_NODE_KINDTAG_RAY_NODE_NAMETAG_RAY_NODE_STATUSTAG_RAY_USER_NODE_TYPE)_internal_kv_putinternal_kv_get_gcs_client)log_once)quote)autohostdocker   configreturnc                 P    | d         d         dk    rddl m}  ||            d S d S )Nprovidertypeawsr   )
log_to_cli)"ray.autoscaler._private.aws.configrB   )r<   rB   s     t/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/autoscaler/_private/commands.pytry_logging_configrE   \   sG    j&!U**AAAAAA
6 +*    provider_configc                 >    | d         dk    rddl m}  |            S d S )Nr@   rA   r   )get_log_state)rC   rI   )rG   rI   s     rD   try_get_log_staterJ   c   s5    v%''DDDDDD}4rF   	log_statec                 H    |sd S | d         dk    rddl m}  ||          S d S )Nr@   rA   r   )reload_log_state)rC   rM   )rG   rK   rM   s      rD   try_reload_log_staterN   k   sJ     v%''GGGGGG	*** ('rF   Fverboseaddressc                    ddl m}  |            r0ddlm} ddl m}  ||          }|                    ||          } n| r|                     d          } t          j        |           }|	                    d          }	|	                    d          }
|	                    d	          }|	                    d
          }|	                    d          }|	rz|
rx|rvt          di |	}|
                    di           }t          j        di |}t          dd|i|
}t          j                            |          }t#          ||||||          } nd} nd} |r| dz  } | |                    d          z  } | S )aZ  
    Return a debug string for the autoscaler.

    Args:
        status: The autoscaler status string for v1
        error: The autoscaler error string for v1
        verbose: Whether to print verbose information.
        address: The address of the cluster (gcs address).

    Returns:
        str: A debug string for the cluster's status.
    r   is_autoscaler_v2)get_cluster_status)ClusterStatusFormatter)rO   utf-8load_metrics_reportautoscaler_reporttimegcs_request_timenon_terminated_nodes_timenode_availability_summary)rY   rZ   r[   rO   zWNo cluster status. It may take a few seconds for the Ray internal services to start up.
 )ray.autoscaler.v2.utilsrS   ray.autoscaler.v2.sdkrT   rU   formatdecodejsonloadsgetr#   popr   from_fieldsr   datetimefromtimestampr$   )statuserrorrO   rP   rS   rT   rU   cluster_statusstatus_dictlm_summary_dictautoscaler_summary_dict	timestamprZ   r[   
lm_summarynode_availability_summary_dictr\   autoscaler_summaryreport_times                      rD   debug_statusru   t   s    988888 ,
<<<<<<BBBBBB++G44'..~w.OO	 &
w''j((%//*?@@"-//2E"F"FOOF++	&??+=>>$/OO4O$P$P! 	6 	9 	+>>o>>J-D-H-H+R. .* )@(K ) )0) )% "3 " "*C")" " #+99)DDK'" !1*C  FF= F9 	
  ($%,,w'''MrF   num_cpusbundlesbundle_label_selectorsc                 <   t          j                    st          d          g }t          | pd          D ]}|                    ddii d           |r,|r t          |          t          |          k    s
J d            |r9t          |          D ])\  }}|r||         ni }|                    ||d           *t          t          t          j
        |          d           dd	lm}  |            r'dd
lm}	 t                      j        }
 |	|
|           dS dS )a  Remotely request some CPU or GPU resources from the autoscaler. Optionally
    specify label selectors for nodes with the requested resources.

    If `bundle_label_selectors` is provided, `bundles` must also be provided.
    Both must be lists of the same length, and `bundle_label_selectors` expects a list
    of string dictionaries.

    This function is to be called e.g. on a node before submitting a bunch of
    ray.remote calls to ensure that resources rapidly become available.

    Args:
        num_cpus: Scale the cluster to ensure this number of CPUs are
            available. This request is persistent until another call to
            request_resources() is made.
        bundles (List[ResourceDict]): Scale the cluster to ensure this set of
            resource shapes can fit. This request is persistent until another
            call to request_resources() is made.
        bundle_label_selectors (List[Dict[str,str]]): Optional label selectors
            that new nodes must satisfy. (e.g. [{"accelerator-type": "A100"}])
            The elements in the bundle_label_selectors should be one-to-one mapping
            to the elements in bundles.
    zRay is not initialized yetr   CPU   )	resourceslabel_selectorz^If bundle_label_selectors is provided, bundles must also be provided and have the same length.T)	overwriterR   )request_cluster_resourcesN)rayis_initializedRuntimeErrorrangeappendlen	enumerater4   r   rc   dumpsr_   rS   r`   r   r5   rP   )rv   rw   rx   
to_request_ibundleselectorrS   r   gcs_addresss              rD   request_resourcesr      s   6  97888J8=q!! K K
bIIJJJJ% hhLLC(>$?$????g @?  Q"7++ 	Q 	QIAv4JR-a00PRHFhOOPPPP+TZ
-C-Ct    988888 ;CCCCCC022:!!+z:::::	; ;rF   Tconfig_fileoverride_min_workersoverride_max_workers
no_restartrestart_onlyyesoverride_cluster_nameno_config_cacheredirect_command_outputuse_login_shellsno_monitor_on_headc           	          t          |	           |	st          j        d           |t          j        d           nt          j        |            fd}	 t	          j        t                                                               n}# t          $ r* t          j
        dt          j                              Y nJt          j        j        $ r} ||            d}~wt          j        j        $ r} ||            d}~ww xY wt#          j        t&          j        di           t+          j        d         d                   }|sgt          j
        dt          j        d	          z   d
z   d         d         t          j        d t+          j                    D                                  dfd} |d|            |d|            |d|           rt          j                     t          j        dd                    t          j                     t7          |          t9                     t;           |||||
           S )zACreates or updates an autoscaling Ray cluster from a config json.FNc                 v   t          j        d           t          j                     t          j        dt          j        d          z              t          j                     t          j        d          5  t          j        |            d d d            n# 1 swxY w Y   t          j                     d S )NzCluster config invalidzFailed to load YAML file {}zPyYAML error:)r   rk   newliner   boldverbatim_error_ctxabort)er   s    rD   handle_yaml_errorz3create_or_update_cluster.<locals>.handle_yaml_error	  s    12224rwt}}DkRRR*?;; 	  	 Q	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 s   :BB"Bz7Provided cluster configuration file ({}) does not existcluster_configr?   r@   zUnknown provider type r   z
Available providers are: {}c                 ,    g | ]}t           |         |S N)r   ).0ks     rD   
<listcomp>z,create_or_update_cluster.<locals>.<listcomp>,  s"    UUUqoa6H6T6T6T6TrF   c           	          |l| v radt          j        dt          j        d          z   t          j        dt          j        d          z   dz             z   | ||                     || <   d S d S )NTz4`{}` override provided on the command line.
  Using r   z [configuration file has ])r   warningr   r   dimmed)keyoverrider<   printed_overridess     rD   handle_cli_overridez5create_or_update_cluster.<locals>.handle_cli_override2  s    f}}$(!"gdmm$ i ;bgdmm Kc QRRS 3K   #F3KKK  rF   min_workersmax_workerscluster_nameClusterr   )r   cmd_output_utilset_allow_interactiveset_output_redirectedyaml	safe_loadopenreadFileNotFoundErrorr   r   r   r   parserParserErrorscannerScannerErrorr   execute_callbackr   
up_startedr   re   render_listkeysr   labeled_value_bootstrap_configrE   get_or_create_head_node)r   r   r   r   r   r   r   r   r   r   r   r   r   importerr   r<   r   s   `              @@rD   create_or_update_clusterr      s   " +,,, 5-e444&-e4444-.EFFF    [ 1 1 6 6 8 899 
 
 
EGK  	
 	
 	
 	
 	
 ;"   !<$   ! (%(8&'A   "6*#5f#=>>H 
$rwt}}4 8* *:v&"UUO022UUU 		
 	
 	
 # # # # # #  ';<<<';<<<(=>>> Y~(>???vGGGFv   Ms*   3B 1DDC  D7DDr{   c                 ^   t          |           } t          j                    }|                    t	          j        | gd                              d                     t          j        	                    t          j                    d                    |                                                    }t          j                            |          r|s}t	          j        t!          |                                                    }|                    dd          t&          k    rt)          |d         d         |                    d	                     t+          d
          rut-          j        dt1          j        d          z   |           t,          j        dk    rt-          j        d           t-          j        dt1          j        d                     |d         }d|v r||d         d<   |S t-          j        dt1          j        d          z   dz   t1          j        d          z   dz   |                    dd          t&                     t9          j        | d         d                   }|s(t;          d                    | d                              || d                   }t-          j        dt?          j        | d         d                              	 |                     |           } ng# tB          $ rZ}t,          j        dk    rtD          #                    d           n%t-          j        dtI          |           d           Y d }~nd }~ww xY w	 tK          |            n+# tL          tN          f$ r t-          j(        d           Y nw xY w|)                    |           }	||	d         d<   |smt!          |d          5 }
t&          tU          |	d                   |	d}|
+                    t	          j        |                     d d d            n# 1 swxY w Y   |	S ) NT)	sort_keysrV   zray-config-{}_versionr<   r?   provider_log_info_printed_cached_config_warningz*Loaded cached provider configuration from r   r   z$Loaded cached provider configurationzUIf you experience issues with the cloud provider, try re-running the command with {}.z--no-config-cache_config_cache_pathz,Found cached cluster config but the version z (expected z]) does not match.
This is normal if cluster launcher was updated.
Config will be re-resolved.noner@   zUnsupported provider {}z Checking {} environment settings   z$Failed to autodetect node resources.z%Failed to autodetect node resources: z5. You can see full stack trace with higher verbosity.zNot all Ray autoscaler dependencies were found. In Ray 1.4+, the Ray CLI, autoscaler, and dashboard will only be usable via `pip install "ray[default]"`. Please update your install command.w)r   r   r<   ),r'   hashlibsha1updaterc   r   encodeospathjointempfile
gettempdirra   	hexdigestexistsrd   r   r   re   CONFIG_CACHE_VERSIONrN   r6   r   verbose_warningr   r   	verbosityr   r   NotImplementedErrorprintr    &fillout_available_node_types_resources	Exceptionlogger	exceptionstrr(   ModuleNotFoundErrorImportErrorr   bootstrap_configrJ   write)r<   r   hasher	cache_keyconfig_cachecached_configr   provider_clsexcresolved_configfs              rD   r   r   ^  s    F##F \^^F
MM$*fX666==gFFGGG55f6F6F6H6HII I 
w~~i   ' 'z$y//"6"6"8"899J++/CCC
 !X&z2  !455  
 899 *@274==P   '1,,&'MNNN"+ G/00	   )2M]**BKj)*>?  #%'WT]]36!wt}}-0..
   V44$   "6*#5f#=>>H X!";"B"B6*CU"V"VWWW8F:.//L*"6*#5f#=>>  	DDVLL   !##CDDDDFC F F F  	

 	- 
 
 
+	
 	
 	
 	
 	

 #33F;;O8AOJ 45 .)S!! 	.Q0%6z7R%S%S) L
 GGDJ|,,---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. s>   %K; ;
MAMM#M3 3%NNAP""P&)P&workers_onlykeep_min_workersc                 0   t          j        t          |                                                     ||d<   t	                    t          j        |dd           s|	 t          | dddddd|dd	
  
         na# t          $ rT}t          j	        d
t          |                     t          j        d           t          j        d           Y d}~nd}~ww xY wt          d         d                   fd}fd} |            }                    di                               d          }	|	rt          j                    }
t          j        d           t          j                    }t          j        d           t'          t(                    5 }|D ]}|                    |||	           	 ddd           n# 1 swxY w Y   t          j        |
           t          j        |           t-          d          5  |r                    |           t          j        dt3          j        t7          |                    t9          d                     t;          j        t>                      |            }t          j        dt3          j        t7          |                    t>                     |t          j         d           tC          d          rs	 t          j        d           "                                 t          j         d           nM# t          $ r@}t          j	        d
t          |                     t          j        d           Y d}~nd}~ww xY wddd           dS # 1 swxY w Y   dS )z?Destroys all nodes of a Ray cluster described by a config json.Nr   zDestroying cluster.T_abortray stopr8   F)	cmdrun_envscreentmuxstopstartr   port_forwardwith_outputr   z^Exception occurred when stopping the cluster Ray runtime (use -v to dump teardown exceptions).zLIgnoring the exception and attempting to shut down the cluster nodes anyway.r?   c                  *                        t          t          i          } r                    dd          }t	          j        dt          j        d          z   t          j        |          t          j        d                     t          j
        | t          |           |z
            } r>t	          j        dt          j        d          z   t          j        d                     | S                      t          t          i          }|| z   S )Nr   r   z.{} random worker nodes will not be shut down. z(due to {})z--keep-min-workersz%The head node will not be shut down. z--workers-only)non_terminated_nodesr0   r,   re   r   r   r   r   r   randomsampler   r+   )workersr   headr<   r   r?   r   s      rD   remaining_nodesz)teardown_cluster.<locals>.remaining_nodes  s   //1BDT0UVV 		I **]A66K@)M**+$$,--	   mGS\\K-GHHG  	7")M:R:RR())  
 N,,.?-PQQg~rF   c                    	 t          | d         d         d         d         g g g ddd                    d                    }t          |d	| dd
           d S # t          $ r t	          j        d|             Y d S w xY w)Nr?   authr   file_mounts Fr:   node_idrG   r?   auth_configr   r  initialization_commandssetup_commandsray_start_commandsruntime_hashfile_mounts_contents_hashis_head_nodedocker_configzdocker stop r9   )r  r   zDocker stop failed on )r"   re   _execr   r   r   )nodecontainer_nameupdaterr<   r?   s      rD   run_docker_stopz)teardown_cluster.<locals>.run_docker_stop
  s    	@' &z 2!"6N#N3"=1(*!#%*,"$jj22  G  /~//!	       	@ 	@ 	@>>>??????	@s   AA" "!BBr:   r  )r   )r  r  zteardown_cluster: done.z Requested {} nodes to shut down.1s)interval)_tagsz&{} nodes remaining after {} second(s).zNo nodes remaining.cleanup_cluster_resourcesz'Cleaning up shared cluster resources...z$Shared cluster resources cleaned up.zFailed to cleanup shared cluster resources (use -v to see details). You may need to manually delete MSI, NSG, and Subnet resources.)#r   r   r   r   r   r   confirmexec_clusterr   verbose_errorr   r   r!   re   r   is_output_redirectedr   does_allow_interactiver   r   r   submitr   terminate_nodesr   r   r   r   dictrY   sleepPOLL_INTERVALsuccesshasattrr!  )r   r   r   r   r   r   r
  r  Ar  output_redirallow_interactiveexecutorr  r<   r?   s     ` `         @@rD   teardown_clusterr2    s    ^D--224455F(!6~v&&Fs1$???? 	&;!!      
	 
	 
	$T3q662228   D       
	 "&"4f^6LMMH       6@ @ @ @ @ @: 	AZZ"--112BCCN A ';==-d333+BDD-e444,IJJJ 	h  #$~      	 	 	 	 	 	 	 	 	 	 	 	 	 	 	
 	-l;;;-.?@@@	+	,	,   	$$Q'''2AD)))    J}%%%!!A8"'#a&&//=    	 	0111 8899 	, 	
 !JKKK22444"#IJJJJ   (s1vv666"V       /                 sh   (B 
C A
CC %GGGC!N4<L10N1
M;;6M61N6M;;NNNhardc                    t          j        t          |                                                     }|||d<   t	          |          }t          j        |d           t          |d         |d                   }|                    t          t          i          }|st          j        d           dS t          j        |          }t          j        dt          j        d          z   |           |r|                    |           nYt#          ||d         ||d         |d         |d	         g g g d
d
d|                    d                    }t'          |ddd           t)          j        t,                     |                    di                               dd          r|                    |          }	n|                    |          }	|	S )zKills a random Raylet worker.Nr   zA random node will be killed.r?   zNo worker nodes detected.z	Shutdown r   r  r  r  Fr:   r  r   use_internal_ips)r   r   r   r   r   r   r"  r!   r  r0   r,   r   r  choicer   r   terminate_noder"   re   r  rY   r*  r+  internal_ipexternal_ip)
r   r   r3  r   r<   r?   nodesr  r  node_ips
             rD   	kill_noder<  Y  s   
 ^D--224455F(!6~v&&Fs;<<<!&"4f^6LMMH))+<>N*OPPE 4555t=D[274==0$777 1%%%%#":.v/}-$&!&( **X..
 
 
  	gz5%000J}zz*b!!%%&8%@@ -&&t,,&&t,,NrF   cluster_config_file	num_linesc                 B    d| d}t          | |ddddd|d	  	         dS )z+Tails the autoscaler logs of a Ray cluster.ztail -n z) -f /tmp/ray/session_latest/logs/monitor*r8   FN)r   r   r   r   r   r  r   r  )r#  )r=  r>  r   r   s       rD   monitor_clusterr@    sQ     JY
I
I
IC3
 
 
 
 
 
rF   start_commandsc           
         t          t          d |                     }t          |          dk    r:t          j        dt          j        d          t          j        d                     t          d |D                       }|sw|swt          j        dt          j        d          t          j        d          t          j        d	          t          j        d          t          j        d                     d S d S d S )
Nc                 
    d| v S )N	ray startr^   )xs    rD   <lambda>z.warn_about_bad_start_command.<locals>.<lambda>  s    +*: rF   r   z<Ray runtime will not be started because `{}` is not in `{}`.rD  head_start_ray_commandsc              3      K   | ]}d |v V  	dS )zautoscaling-configNr^   )r   rE  s     rD   	<genexpr>z/warn_about_bad_start_command.<locals>.<genexpr>  s9       . .&'!. . . . . .rF   zThe head node will not launch any workers because `{}` does not have `{}` set.
Potential fix: add `{}` to the `{}` command under `{}`.z--autoscaling-configz0--autoscaling-config=~/ray_bootstrap_config.yaml)listfilterr   r   r   r   r   any)rA  r   ray_start_cmd#autoscaling_config_in_ray_start_cmds       rD   warn_about_bad_start_commandrO    s$     : :NKKLLM
=QJGK  G-..	
 	
 	
 +. . .+8. . . + +' 0 

3E 

F GK  G*++GFGGGK  G-..		
 		
 		
 		
 		


 

 

 

rF   printable_config_file	_provider_runnerc	                    t          j        t          j                   |pt	          | d         | d                   }	t          j        |           } t          t          i}
|		                    |
          }t          |          dk    r	|d         }nd}|s?t          j        |dd           t          j                     t          j        d           |r|rSt          j        |d	t!          j        d
          d           t          j                     t          j        d           n|r?t          j        dt!          j        d                     t          j        |dd           net          j        d           t          j        |t!          j        d          d           t          j                     t          j        d           t          j                     t          j        |                     di                     }d}d}|                     d          }|r]||
t(          <   | d         |         }|                    |d                    |                    d          }|                    d          }t-          || d                   }t/          ||||	          }|rt          j        d          5  t          j        t          j                   |At          j        |dd           |	                    |           t          j        d|           ||
t6          <   d                    | d                   |
t:          <   t<          |
t>          <   |	                     ||
d           t          j        d           tC          j!                    }d}t          j        d          5  	 tC          j!                    |z
  dk    rt          j"        d           |		                    |
          }t          |          dk    r	|d         }ntC          j#        tH                     y	 ddd           n# 1 swxY w Y   t          j                     ddd           n# 1 swxY w Y   t          j        t          j%                   t          j        d d!tM                      "          5  tO          | d#         d|           \  }}|s(tQ          | |	|          \  } }t          j        d$           |r=|                     d%i                               d&          r	| d'         }ng }| d(         }n|r|s| d'         }g }n| d'         }| d(         }|stS          ||           tU          j+        d)d*          d*k    r\d)tT          j,        vr:t          j        d+t!          j        d)          t!          j        d)                     t[          |d*||d,          }t]          dTi d-|d.| d         d|	d/| d         d| d         d#| d#         d0| d0         d1|d2|d3|d4|d5|d6dd7|d8|d9|                     d:          |                     d;          d<d=|                     d%          d>|}|/                                 |0                                 |		                    |
           |j1        dk    r(t          j"        d?           te          j3        d           ddd           n# 1 swxY w Y   t          j        t          j4        d@|i           dA}|r#dB                    tk          |                    }ndC}t          j                     t          j        dD          5  tT          j6        7                    |          }t          j        dE           t          j        t!          j        dF| |                      t          j                     t          j        dG           t          j        t!          j        dH| |                      t          j                     t          j        dI           t          j        t!          j        dJ| |                      t          j                     t          j        dK           t          j        t!          j        dL                     t          j                     t          j        dM           t          j        t!          j        dN| |                      t          j                     t          j        dO           t          j        t!          j        dP| | dQtk          |                                t          j                     ddd           n# 1 swxY w Y   td          j8        dRk    r?|s?dSts                      v r1	 tU          j:        |j;                   dS # tx          $ r Y dS w xY wdS dS dS )Uz@Create the cluster head node, which in turn creates the workers.r?   r   r   Nz,No head node found. Launching a new cluster.Tr   )clizsUpdating cluster configuration and restarting the cluster Ray runtime. Setup commands will not be run due to `{}`.
z--restart-onlyz6Cluster Ray runtime will not be restarted due to `{}`.z--no-restartz:Updating cluster configuration and running setup commands.z6Updating cluster configuration and running full setup.z&Cluster Ray runtime will be restarted.	head_nodehead_node_typeavailable_node_typesnode_configr|   labelsr  z!Acquiring an up-to-date head nodezRelaunching the head node.zTerminated head node {}zray-{}-headr{   zLaunched a new head nodezFetching the new head node2   z6Head node fetch timed out. Failed to create head node.zSetting up head node)z<>r{   r{   )	_numberedr   r  zPrepared bootstrap configr:   r  head_setup_commandsrG  RAY_UP_enable_autoscaler_v21zAutoscaler v2 is now enabled by default (since Ray 2.50.0). To switch back to v1, set {}=0. This message can be suppressed by setting {} explicitly.)RAY_enable_autoscaler_v2RAY_CLOUD_INSTANCE_IDRAY_NODE_TYPE_NAMEr  rG   r  r  r  r  process_runnerr  r  r  node_resourcesnode_labelsrsync_optionsrsync_excludersync_filterrf  rg  r  r   zFailed to setup head node.head_node_idz4tail -n 100 -f /tmp/ray/session_latest/logs/monitor*z --cluster-name={}r  zUseful commands:zTo terminate the cluster:z  ray down z/To retrieve the IP address of the cluster head:z  ray get-head-ip zATo port-forward the cluster's Ray Dashboard to the local machine:z  ray dashboard z[To submit a job to the cluster, port-forward the Ray Dashboard in another terminal and run:zc  ray job submit --address http://localhost:<dashboard-port> --working-dir . -- python my_script.pyz;To connect to a terminal on the cluster head for debugging:z  ray attach zTo monitor autoscaling:z  ray exec  win32remote_config_filer^   )=r   r   r   cluster_booting_startedr!   copydeepcopyr0   r+   r  r   r   r"  r   r   show_usage_stats_promptr   r   r   re   r3   r   r%   _should_create_new_headgroupacquiring_new_head_noder7  r/   ra   r1   r-   r2   create_noderY   r   r*  r+  head_node_acquiredr)  r&   _set_up_config_for_head_noderO  r   getenvenvironr)   r"   r  r   exitcodesysexitcluster_booting_completedr7   r   abspathplatformlocalsremovenameOSError)r<   rP  r   r   r   r   r   rQ  rR  r?   head_node_tagsr:  rU  head_node_confighead_node_resourceshead_node_labelsrV  head_configlaunch_hashcreating_new_headr  r  r  rl  r  r  r  monitor_str	modifierss                                rD   r   r     sW    ();)STTT .zF>2 H ]6""F>N )).99E
5zzA~~!H			 4?	
 	
 	
 	
 	)d3333 8 	8@ ())       -$77777 	8H''   L     UVVVRWEFFt       -$7777}VZZR%@%@AA ZZ 011N 51?-.34^DM :;;; *ook::&??844"#3VF^DDK/;    !ABB 	! 	!0":   $"3(DTRRRR''	222 !:IFFF4?N010=0D0D~&1 1N,- 3GN./  !1>1EEE7888IKKEI!">?? 
. 
.	.y{{U*R//"(T   %99.IIE5zzQ$)!H	J}---	. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
. 
.    ?	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	!B ();)NOOO		ff	
 
 
 _ _ 5F=!45
 5
10 " 	:)E** *&F& 8999 	C zz(B''++,<== $!'(=!>!#!'(A!B  	C 1 	C#$9:N!##$9:N!'(A!B 	Q();=OPPP
 92C88C??,BJ>> oG9::G9::	   "+"03-6*8 " " $ 
 
 
I
":..
 X
 v	

  //
 }--
 %++D$E$E
 *>
  21
 #7
 &
 '@&?
 
 /.
 )(
" "(O!<!< &

> : :  !
( !**X...)
* &+
. 	 	%%n555q  9:::HQKKK_ _ _ _ _ _ _ _ _ _ _ _ _ _ _B (4I	
   IK (//6K0L0LMM					,	-	- ) ) "0E F F4555!Q/D!Qi!Q!QRRSSSJKKKGK)>K	KKLL	
 	
 	
 	O	
 	
 	
 	!V4I!V9!V!VWWXXX9	
 	
 	
 	G9 	
 	
 	
 	VWWW!S1F!S	!S!STTUUU2333GU3UYUU{ASASUU 	
 	
 	

 	S) ) ) ) ) ) ) ) ) ) ) ) ) ) )\ 	" 	  FHH,,	I(-..... 	 	 	DD	 	 ,,sp   C2Q&4A;P<0Q&<Q 	 Q&Q 	Q&&Q*-Q*2H4[22[69[6.Hfff?g 
g('g(ri  new_launch_hashnew_head_node_typer?   c                    | sdS |                     |           }|                    t                    }|                    t                    }||k    }||k    }|p|}	|	rt	          j        d          5  |r:t	          j        dt          j        |          t          j        |                     |r:t	          j        dt          j        |          t          j        |                     ddd           n# 1 swxY w Y   |	S )a  Decides whether a new head node needs to be created.

    We need a new head if at least one of the following holds:
    (a) There isn't an existing head node
    (b) The user-submitted head node_config differs from the existing head
        node's node_config.
    (c) The user-submitted head node_type key differs from the existing head
        node's node_type.

    Args:
        head_node_id (Optional[str]): head node id if a head exists, else None
        new_launch_hash: hash of current user-submitted head config
        new_head_node_type: current user-submitted head node-type key

    Returns:
        bool: True if a new Ray head node should be launched, False otherwise
    TzECurrently running head node is out-of-date with cluster configurationzCurrent hash is {}, expected {}z)Current head node type is {}, expected {}N)		node_tagsre   r/   r3   r   rr  r   r   r   )
ri  r  r  r?   	head_tagscurrent_launch_hashcurrent_head_typehashes_mismatchtypes_mismatchnew_head_requireds
             rD   rq  rq    sg   .  t ""<00I#--(=>>!&<== &)<<O'+<<N'9>  S
 
 	 	   5G/00GO,,     ?G-..G.//  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	" s   4A9C99C= C=c                    t          j        |           }|d                             dd           |                    dd           d| d         v rd}||d         d<   i }| d         D ]}|||<   ||d<   ||d<   |                    |          }t          j        d	k    }t          j        d
d|           }|                    t          j
        |                     |                                 |r|                                 | d                             d|j        i           d| d         v r)| d                             || d         d         i           | |fS )zPrepares autoscaling config and, if needed, ssh key, to be mounted onto
    the Ray head node for use by the autoscaler.

    Returns the modified config and the temporary config file that will be
    mounted onto the head node.
    r  ssh_proxy_commandNrU  ssh_private_keyz~/ray_bootstrap_key.pemr  r   rk  r   zray-bootstrap-)prefixdeletez~/ray_bootstrap_config.yaml)rn  ro  rf   prepare_for_head_noderz  r~  r   NamedTemporaryFiler   rc   r   flushcloser   r  )	r<   r?   r   remote_configremote_key_path
new_mountsremote_path
is_windowsrl  s	            rD   rv  rv    s    M&))M &14888 k4(((F6N**33Bf/0 Jm, . ."-
;#-M- ",M,22=AAM (J!4$^   TZ66777 #  """
=  	&(:(?@   F6N**}$$0A!B	
 	
 	
 %%%rF   r  
use_screenuse_tmuxnewr  c                     |r|rd}n d}n|r|rd}nd}n|rt          d          d}t          | |dddd||||d	
           dS )a  Attaches to a screen for the specified cluster.

    Arguments:
        config_file: path to the cluster yaml
        start: whether to start the cluster if it isn't up
        use_screen: whether to use screen as multiplexer
        use_tmux: whether to use tmux as multiplexer
        override_cluster_name: set the name of the cluster
        new: whether to force a new screen
        port_forward ( (int,int) or list[(int,int)] ): port(s) to forward
    ztmux newztmux attach || tmux newz	screen -Lzscreen -L -xRRz4--new only makes sense if passing --screen or --tmuxz$SHELLr8   FT)
r   r   r   r   r   r  r   r   r  _allow_uninitialized_stateN)
ValueErrorr#  )	r   r  r  r  r   r   r  r  r   s	            rD   attach_clusterr  Q  s    ,   	,CC+CC	  	#CC"CC 	USTTT3'!#'     rF   r8   )r   r   r   r   r   r  r   r   r  r  r  extra_screen_argsr   r   r   r   r   r  r  r  c                   |r|r
J d            |t           v s"J d                    t                                 t          j        d           t	          j        t          |                                                     }|||d<   t          ||          }t          || |||          }t          |d         |d                   }t          ||d         ||d	         |d         |d
         g g g ddd|                    d          |                    d          d|                    d                    }|r|rd                    |dddg          }t          |||||	|
|d|	  	        }|s|rd| g}|(|                    d                    |                     |r|                    d           n|r|                    d           d                    |          }t!          j        dt%          j        |                     |S )a  Runs a command on the specified cluster.

    Arguments:
        config_file: path to the cluster yaml
        cmd: command to run
        run_env: whether to run the command on the host or in a container.
            Select between "auto", "host" and "docker"
        screen: whether to run in a screen
        extra_screen_args: optional custom additional args to screen command
        tmux: whether to run in a tmux session
        stop: whether to stop the cluster after command run
        start: whether to start the cluster if it isn't up
        override_cluster_name: set the name of the cluster
        port_forward ( (int, int) or list[(int, int)] ): port(s) to forward
        _allow_uninitialized_state: whether to execute on an uninitialized head
            node.
    z+Can specify only one of `screen` or `tmux`.z--run_env must be in {}TNr   r   create_if_neededr  r?   r  r  r  rf  rg  rh  r:   )r  rG   r?   r  r   r  r  r  r  r  r  r  re  r  z; r   z=ray teardown ~/ray_bootstrap_config.yaml --yes --workers-onlyzsudo shutdown -h nowF)r  r  r   shutdown_after_runr  z
ray attachz--cluster-name={}z--tmuxz--screenrj  z!Run `{}` to check command status.)RUN_ENV_TYPESra   r   r   r   r   r   r   r   _get_running_head_noder!   r"   re   r   r  r   r   r   r   r   )r   r   r   r   r   r   r  r   r   r  r  r  r  r<   rU  r?   r  resultattach_command_partsattach_commands                       rD   r#  r#    s   B O4OO"OOO m###%>%E%Em%T%T### )$///^D--224455F(!6~vGGGF&#=  I "&"4f^6LMMHz*6NN+=) ""$#ZZ88"JJ~66
 
 jj**#  G&  
t 
iiO&	
 
 ! +
 
 
F  Wv W ,k: , ''#**+@AA    	4 ''1111 	4 ''
333"677<bgn>U>UVVVMrF   r  r  c	           	      B   |r~|rMg d}	|t          |          dk    r|	|gz  }	|	ddt          |dz             gz  }	d                    |	          }n/|r-ddd	ddt          |dz             g}	d                    |	          }| j                            |d
||||          S )N)r   z-Lz-dmr   bashz-cz; exec bashrj  r   r  z-dT)exit_on_failr  r  r   r  )r   r7   r   
cmd_runnerrun)
r  r   r   r   r  r  r   r  r  wrapped_cmds
             rD   r  r    s      ( 	(  K !,5F1G1G!1K1K 122cM)** K
 ((;''CC 
	( cM)**K ((;''C!!!- "   rF   sourcetargetdown
ip_addressuse_internal_ip	all_nodesshould_bootstrapc                 d  
 t                    t                    k    rt          j        d           t                    t                    k    s
J d            |r|rt          j        d           t          j        t          |                                                     ||d<   |	rt          |          drJrH                    di           	                                D ]}rn
                    |          rd	 n t          d
         d                   
fd}g }t          | |d          }|r                    |          g}n(|g}|r#|                    t          |                     |D ]} ||||k               dS )a\  Rsyncs files.

    Arguments:
        config_file: path to the cluster yaml
        source: source dir
        target: target dir
        override_cluster_name: set the name of the cluster
        down: whether we're syncing remote -> local
        ip_address: Address of node. Raise Exception
            if both ip_address and 'all_nodes' are provided.
        use_internal_ip: Whether the provided ip_address is
            public or private.
        all_nodes: whether to sync worker nodes in addition to the head node
        should_bootstrap: whether to bootstrap cluster config before syncing
    z7Expected either both a source and a target, or neither.z6Must either provide both or neither source and target.z/Cannot provide both ip_address and 'all_nodes'.Nr   r   Fr  Tr?   c           	         t          di d| dd         ddd         dd         dd         dg d	g d
g ddddddd|d                    d                              d          dd                    d          }r|j        }n|j        }	rD
rBt          j        dk    r#t          j        d           t          d            |	
           d S |	                    |           d S )Nr  rG   r?   r  r  r   r  r  r  r  r  r  r  rb  r  r  re  rf  rg  rh  r  r:   r   Fr^   )
r"   re   
rsync_downrsync_upr   r   r   r   r   sync_file_mounts)r  r  r  rsyncrR  r<   r  is_file_mountr?   r  r  r  s       rD   rsync_to_nodezrsync.<locals>.rsync_to_nodeY  s   # 
 
 
G
":..
 X
 v	

  //
 }--
 %'B
 2
  "r
 
 ,O
 #7
 ')b
 &
  "(O!<!< &

> : :  
& !**X...'
*  	%&EE$E 	,f 	,#a''5e<<< '''E&&-00000$$U+++++rF   )r  )r  )r  )boolr   r   r   r   r   r   r   re   r   
startswithr!   r  get_node_idextend_get_worker_nodes)r   r  r  r   r  r  r  r   r  r  rR  remote_mountr  r:  rU  r  r<   r  r?   s    `` ` `   `     @@@rD   r  r  $  sY   8 F||tF||##RSSS<<4    ?    Li LJKKK^D--224455F(!6~ L"6?KKKM & "JJ}b99>>@@ 	 	L*F66|DD  $ "&"4f^6LMMH", ", ", ", ", ", ", ", ", ", ", ",H E&2U  I  K%%j/%RRS 	KLL*63HIIJJJ D DgW	-ACCCCCD DrF   c                    t          j        t          |                                                     }|||d<   t	          |d         |d                   }t          || |          }|                    di           }|                    dd          r,|                    dd          s|                    |          }n|                    |          }|S )z<Returns head node IP for given configuration file if exists.Nr   r?   r5  Fuse_external_head_ip)	r   r   r   r   r!   r  re   r8  r9  )r   r   r<   r?   rU  provider_cfghead_node_ips          rD   get_head_node_ipr    s    
 ^D--224455F(!6~!&"4f^6LMMH&v{<QRRI::j"--L *E22 7<;K;K< < 7  ++I66++I66rF   c                 ~   t          j        t          |                                                     }|||d<   t	          |d         |d                                       t          t          i          }|                    di                               dd          rfd|D             S fd|D             S )z5Returns worker node IPs for given configuration file.Nr   r?   r5  Fc                 :    g | ]}                     |          S r^   )r8  r   r  r?   s     rD   r   z'get_worker_node_ips.<locals>.<listcomp>  '    ===t$$T**===rF   c                 :    g | ]}                     |          S r^   )r9  r  s     rD   r   z'get_worker_node_ips.<locals>.<listcomp>  r  rF   )	r   r   r   r   r!   r  r0   r,   re   )r   r   r<   r:  r?   s       @rD   get_worker_node_ipsr    s    
 ^D--224455F(!6~!&"4f^6LMMH))+<>N*OPPEzz*b!!%%&8%@@ >====u========u====rF   c                     ||| d<   t          | d         | d                   }|                    t          t          i          S )z0Returns worker node ids for given configuration.Nr   r?   )r!   r  r0   r,   )r<   r   r?   s      rD   r  r    sH    
 (!6~!&"4f^6LMMH((*;=M)NOOOrF   r  c                 \   |pt          | d         | d                   }t          t          i}|                    |          }d}	d}
|D ]Z}|                    |                              t                    }|t          k    r|}	=|}
t          j	        d| d| d           [|	|	S |r)t          | |ddd|	           t          | ||dd
          S |r2|
0t          j	        d|
 dt          j        d|                      |
S t          d                    | d                             )a{  Get a valid, running head node.
    Args:
        config (Dict[str, Any]): Cluster Config dictionary
        printable_config_file: Used for printing formatted CLI commands.
        override_cluster_name: Passed to `get_or_create_head_node` to
            override the cluster name present in `config`.
        create_if_needed: Create a head node if one is not present.
        _provider: [For testing], a Node Provider to use.
        _allow_uninitialized_state: Whether to return a head node that
            is not 'UP TO DATE'. This is used to allow `ray attach` and
            `ray exec` to debug a cluster in a bad state.

    r?   r   NzHead node (z) is in state .FT)rP  r   r   r   r   r  zThe head node being returned: zs is not `up-to-date`. If you are not debugging a startup issue it is recommended to restart this head node with: {}z  ray down  z$Head node of cluster ({}) not found!)r!   r0   r+   r  r  re   r2   r.   r   r   r   r  r   r   r   ra   )r<   rP  r   r  rQ  r  r?   r  r:  rU  _backup_head_noder  
node_states                rD   r  r    s   *  .zF>2 H 	>N )).99EI P P''--112EFF
***II $NTNNNNNOOOO	  
"7"7	
 	
 	
 	
 &!!"',
 
 
 	
 & 	%*;*GG1B G G G >'<>>??	   %$299&:PQQ
 
 	
rF   streamoutputlogsdebug_statepip	processesprocesses_verboser   c                    | r|rt          d          t          |||||          }t          |          5 }	t          |	|           d d d            n# 1 swxY w Y   |	j        }
| ret          |
d          5 }t          j        d|                                           d d d            n# 1 swxY w Y   t          j	        |
           d S |pMt          j
                            t          j                    t          j
                            |
                    }t          j        |
|           t!          j        d|            |S )Nz?You can only use either `--output` or `--stream`, but not both.r  r  r  r  r  filerbr{   zCreated local data archive at )r  r   r   r   r  r   r   r   r   r  r   r   getcwdbasenameshutilmover   r   )r  r  r  r  r  r  r  r   
parametersarchivetmpfpr  s                rD   get_local_dump_archiver    s     
& 
M
 
 	
 +  J 
h			 077J///0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ,C #t__ 	#HQ		"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#
	#tGrw||BIKK1A1A#1F1FGGF
KV>f>>???Ms#   AAA9(B--B14B1r9   ssh_userssh_keyr:   localc                 t   d}|r|dz  }|r|dz  }|	r|dz  }|
r|dz  }t          j        d| d           t          | |          \  } }}fd|D             }|st          j        d	           d S | rd
|d         _        |t          |            }t          |||	|
|          }t          |          5 }|rt          |||           nt          |||           d d d            n# 1 swxY w Y   |s}|r&| dt          j
                                        dd}n#dt          j
                                        dd}t          j                            t          j                    |          }nt          j                            |          }t#          j        |j        |           |S )Nr  z^  - The logfiles of your Ray session
    This usually includes Python outputs (stdout/stderr)
zd  - Debug state information on your Ray cluster 
    e.g. number of workers, drivers, objects, etc.
z2  - Your installed Python packages (`pip freeze`)
zW  - Information on your running Ray processes
    This includes command line arguments
z}You are about to create a cluster dump. This will collect data from cluster nodes.

The dump will contain this information:

z
If you are concerned about leaking private information, extract the archive and inspect its contents before sharing it with anyone.c                 6    g | ]}t          |           S ))r9   r  r  docker_container)r   )r   hr:   r  r  s     rD   r   z,get_cluster_dump_archive.<locals>.<listcomp>q  s:        	!h&QQQ  rF   zXNo nodes found. Specify with `--host` or by passing a ray cluster config to `--cluster`.Tr   r  r  )remote_nodesr  r   z%Y-%m-%d_%H-%M-%Sz.tar.gzcollected_logs_)r   r   r   rk   is_headr  r   r   r   r   rh   nowr   r   r   r  
expanduserr  r  r  )r=  r9   r  r  r:   r  r  r  r  r  r  r  r   content_strhostsr   r:  r  r  filenames     ```               rD   get_cluster_dump_archiver  6  s   " K 
I	

  
C	

  MLL 
9	

 	 	 	 	  $ 	-tXwOO       E
  -	
 	
 	
 t  a} ,---+  J 
h			 7 	5e
     ,e
                   , 	XXh&7&;&;&=&=#XXXX H
 Yh&7&;&;&=&=#XXXX  bikk844##F++
Kf%%%Ms   (C55C9<C9msgc                 6    |rd nt          j        | d          S )NT)r   )clickr"  )r  r   s     rD   r"  r"    s     :44EM#T::::rF   )FN)NNN)NFFTF)F)FFN)NFFNFr8   FNr   )FNF)FNTTTTFN)NNNNNNNTTTTFN)rn  rh   r   rc   loggingr   r  r  
subprocessrz  r   rY   concurrent.futuresr   typesr   typingr   r   r   r   r	   r
   r  r   r   ray._common.usager   ray.autoscaler._privater   r   "ray.autoscaler._private.autoscalerr   "ray.autoscaler._private.cli_loggerr   r   $ray.autoscaler._private.cluster_dumpr   r   r   r   r   r   r   &ray.autoscaler._private.command_runnerr   r   !ray.autoscaler._private.constantsr   r   $ray.autoscaler._private.event_systemr   r   !ray.autoscaler._private.log_timerr   :ray.autoscaler._private.node_provider_availability_trackerr   !ray.autoscaler._private.providersr   r    r!   ray.autoscaler._private.updaterr"   ray.autoscaler._private.utilr#   r$   r%   r&   r'   r(   r)   ray.autoscaler.node_providerr*   ray.autoscaler.tagsr+   r,   r-   r.   r/   r0   r1   r2   r3   ray.experimental.internal_kvr4   r5   ray.util.debugr6   shlexr7   r   pipes	getLogger__name__r   r  r+  intPort_forwardr   rE   r)  rJ   rN   r  ru   r   r   r   r   r2  r<  r@  rO  r   rq  rv  r  r#  r  r  r  r  r  r  r  r  r"  r^   rF   rD   <module>r$     s        				       



   1 1 1 1 1 1       : : : : : : : : : : : : : : : :   



 ' ' ' ' ' ' M M M M M M @ @ @ @ @ @ = = = = = = = =                                Y X X X X X X X 6 6 6 6 6 6              
 > = = = = =                  6 5 5 5 5 5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 V U U U U U U U # # # # # #    
	8	$	$***U38_d5c?&;;<tCH~ $    tCH~ (4.    +$sCx. +T +d + + + + DHC C C3;C=CC C C CN #$(372; 2;sm2;d4j!2; %T$Z02; 
	2; 2; 2; 2;x ,0!.3!$i ii"3-i #3-i 	i
 i 
i $C=i i &d^i i i 
#s(^i i i iX   5:b bcNb-1b	#s(^b b b bJSS	S S $C=	S
 S 
S S S Sl///'+/DLSM/c]/ / / /d),EMc]	   & ;@
 
I
37
	
 
 
 
D  %(,$^ ^cN^^ ^ 	^
 
^ $C=^ ^ %^ ^ 
^ ^ ^ ^B	93-99 9 	9
 
9 9 9 9x9&cN9&&29&@D9&
4S>39& 9& 9& 9&D "+/1 111 1 	1
 $C=1 1 
1 <(1 
1 1 1 1n +/!+/','+k k kk 
#k 	k
 k k k k $C=k k <(k k !%k  }k 	k k k k` +/$'+. ..	#. . 	.
 <(. . . .  }. 	. . . .n !%!!!$eD eDeDSMeD SMeD $C=	eD
 eD eD eD eD eD eD eD 
eD eD eD eDR >B -5c]   2 >B> >>-5c]>	#Y> > > >$	PcN	P3;C=	P	#Y	P 	P 	P 	P  #(,',H
 H
cNH
H
 $C=H
 	H

 %H
 !%H
 	H
 H
 H
 H
X  #"& &&SM& & 	&
 
& & & sm& c]& & & &T *."!   #"o o!#o
3-o smo c]	o
 SMo D>o SMo o o 
o o o smo c]o o o od; ;4 ;HTN ; ; ; ; ; ;s   6C= =D
D