
                            S r SSKJr  SSKJr  SSKJr  SSKrSSKJr  SSKJ	r
  SSKJr  SS	KJr  SS
KJr  SSKJ	r	  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKrSS0rS/rSr " S S\	R:                  5      r " S S\	R:                  5      r " S S\	R:                  5      r  " S S\	R:                  5      r! " S S\	R:                  5      r" " S S\	R:                  5      r#S  r$S! r%S" r& S`S# jr'S$ r(S% r)S& r*S' r+    SaS( jr,SbS) jr-   ScS* jr.S+ r/S, r0S- r1S. r2S/ r3   SdS0 jr4S1 r5S2 r6S3 r7S4 r8S5 r9SbS6 jr:SbS7 jr;SeS8 jr<      SfS9 jr=S: r>S;S<0r?S=\?S;   -  \?S>'   S?\?S;   -  \?S@'   S?\?S@   -  \?SA'   SB\?SA   -  \?SC'   SD\?SC   -  \?SE'   SF\?SC   -  \?SG'   \R                  " SHSIR                  \?5      -  5      rBSJ rCSK rD\R                  " SL5      rE\R                  " SM5      rF\R                  " SN5      rGSO rH\R                  " SP5      rISQ rJSR rKSS rLST rMSU rNSbSV jrOSW rPSbSX jrQ SeSY jrRSZ rSS[ rTS\ rUS] rVS^ rW SeS_ jrXg)gz0Util methods for Stackdriver Monitoring Surface.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)util)	arg_utils)labels_util)log)
properties)	resources)yaml)timeschannelLabelslabelscriteriaz@Notification channel migrated from Prometheus alert manager filec                       \ rS rSrSrSrg)YamlOrJsonLoadError.   zGException for when a JSON or YAML string could not loaded as a message. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       1lib/googlecloudsdk/command_lib/monitoring/util.pyr   r   .   s    Or   r   c                       \ rS rSrSrSrg)NoUpdateSpecifiedError2   zEException for when user passes no arguments that specifies an update.r   Nr   r   r   r   r!   r!   2       Mr   r!   c                       \ rS rSrSrSrg)ConditionNotFoundError6   z;Indiciates the Condition the user specified does not exist.r   Nr   r   r   r   r%   r%   6   s    Cr   r%   c                       \ rS rSrSrSrg)ConflictingFieldsError:   z@Inidicates that the JSON or YAML string have conflicting fields.r   Nr   r   r   r   r(   r(   :   s    Hr   r(   c                       \ rS rSrSrSrg)MonitoredProjectNameError>   zEInidicates that an invalid Monitored Project name has been specified.r   Nr   r   r   r   r+   r+   >   r#   r   r+   c                       \ rS rSrSrSrg)MissingRequiredFieldErrorB   zHInidicates that supplied policy/alert rule is missing required field(s).r   Nr   r   r   r   r.   r.   B   s    Pr   r.   c                     [        U Vs/ s H  o0R                  U5      PM     sn5      (       d  [        SR                  U5      5      eg s  snf )Nz.Did not specify any flags for updating the {}.)anyIsSpecifiedr!   format)argsupdate_arg_destsresourcedests       r   ValidateUpdateArgsSpecifiedr8   F   sN    	1AB1At$1AB	C	C
 8??IK K 
DBs   Ac                     [         R                  " U5       H>  u  p#X ;   d  M  X0;   a  [        SR                  X#5      5      eU R	                  U5      X'   M@     U $ )NzCannot specify both {} and {}.)six	iteritemsr(   r3   pop)yaml_objfield_remappings
field_nameremapped_names       r   _RemapFieldsrA   L   s\    #&==1A#Bj		"$%E%L%L&' ( 	( (Z 8h $C 
/r   c                 H    U H  nX ;   d  M
  U R                  U5        M     U $ N)r<   )r=   field_deletionsr?   s      r   _DeleteFieldsrE   V   s%    #jll: $ 
/r   c                      [         R                  " U 5      nU(       a  [        XS5      nU(       a  [        XT5      n[        R
                  " X5      nU$ ! [         a  n[        SR                  X'5      5      eS nAff = f)Nz2Could not parse YAML or JSON string for [{0}]: {1})	r   loadrA   rE   r   PyValueToMessage	Exceptionr   r3   )
msg_stringmessage_typedisplay_typer>   rD   msg_as_yamlmsgexcs           r   MessageFromStringrP   ]   sr     ))J'K ?k!+?k

#
#L
>CJ	  
<CC	    s   AA 
A=A88A=c                 >    U [        S5      S R                  SS5      $ )z'Converts a --flag-arg to its dest name.z--N-_)lenreplace)	flag_names    r   _FlagToDestrW   m   s     	3t9:		&	&sC	00r   c                 $    SR                  U 5      $ )Nz{}s)r3   )durations    r   _FormatDurationrZ   r   s    	h	r   c                     U R                  S5      (       d  U R                  S5      (       a-  U R                  =(       d    U R                  n[        X!S5      nU$ U" 5       nU$ )z"Returns the base policy from args.policypolicy_from_fileAlertPolicy)r2   r\   r]   rP   )r4   policy_classpolicy_stringr\   s       r   GetBasePolicyMessageFromArgsra   v   sY    	h4#3#34F#G#GKK84#8#8M}MJF 
- ^F	-r   c                 (   U R                  S5      (       a.  U R                  S5      (       d  [        R                  " SS5      eg/ SQnU HD  nUS:X  a  SnO[        U5      nU R                  U5      (       d  M/  [        R                  " US5      e   g)	a  Checks if condition arguments exist and are specified correctly.

Args:
  args: argparse.Namespace, the parsed arguments.
Returns:
  bool: True, if '--condition-filter' is specified.
Raises:
  RequiredArgumentException:
    if '--if' is not set but '--condition-filter' is specified.
  InvalidArgumentException:
    if flag in should_not_be_set is specified without '--condition-filter'.
condition_filterif_value--ifz;If --condition-filter is set then --if must be set as well.T)z--aggregationz
--durationz--trigger-countz--trigger-percentz--condition-display-namere   z
--combinerzAShould only be specified if --condition-filter is also specified.F)r2   calliope_excRequiredArgumentExceptionrW   InvalidArgumentException)r4   should_not_be_setflagr7   s       r   CheckConditionArgsrk      s     
())J''22

GI I  "	4 			$		33OQ 	Q " r   c	                 f   U(       d  U R                  5       nUb  X!l        Sn	U(       d  U(       a  U R                  XES9n	U	UUS.n
U(       a  X:S'   Ub]  Uu  pU(       d  U R                  " S0 U
D6Ul        U$ U R
                  R                  nU R
                  " S[        X5      US.U
D6Ul        U$ )a!  Populates the fields of a Condition message from args.

Args:
  messages: module, module containing message classes for the stackdriver api
  condition: Condition or None, a base condition to populate the fields of.
  display_name: str, the display name for the condition.
  aggregations: list[Aggregation], list of Aggregation messages for the
    condition.
  trigger_count: int, corresponds to the count field of the condition trigger.
  trigger_percent: float, corresponds to the percent field of the condition
    trigger.
  duration: int, The amount of time that a time series must fail to report new
    data to be considered failing.
  condition_filter: str, A filter that identifies which time series should be
    compared with the threshold.
  if_value: tuple[str, float] or None, a tuple containing a string value
    corresponding to the comparison value enum and a float with the condition
    threshold value. None indicates that this should be an Absence condition.

Returns:
  Condition, a condition with its fields populated from the args
N)countpercent)triggerrY   filteraggregations)
comparisonthresholdValuer   )		ConditiondisplayNameTriggerMetricAbsenceconditionAbsentMetricThresholdComparisonValueValuesEnumgetattrconditionThreshold)messages	conditiondisplay_namerq   trigger_counttrigger_percentrY   rc   rd   ro   kwargs
comparatorthreshold_valuecomparison_enums                 r   BuildConditionr      s    4 
""$I('o  6G  & )>"*J"*"8"8"B6"Bi 
 !00JJo%-%=%= &_9(& &i"
 
r   c                     U=(       d1    [         R                  R                  R                  R	                  SS9n[
        R                  R                  U SU0SS9$ )NTrequired
projectsIdz(monitoring.projects.notificationChannelsparams
collectionr   VALUEScoreprojectGetr   REGISTRYParse)channel_namer   s     r   ParseNotificationChannelr      sW    Hz((--559949H'				!	!L'2; 
" 
= =r   c	                    Uc  / nUb  UR                  S5        X l        Uc  Ub&  U R                  (       d  UR                  5       U l        Ub!  UR                  S5        X@R                  l        Ub!  UR                  S5        XPR                  l        Ub  UR                  S5        X`l        Ub  UR                  S5        Xpl        Ub7  UR                  S5        [        R                  " X0R                  SS9nX0l        gg)	z?Override and/or add fields from other flags to an Alert Policy.Nr   zdocumentation.contentzdocumentation.mime_typeenablednotification_channelscombiner	item_type)appendru   documentationDocumentationcontentmimeTyper   notificationChannelsr	   ChoiceToEnumCombinerValueValuesEnumr   )	base_policyr}   r   r   documentation_contentdocumentation_formatr   channelsfield_maskss	            r   ModifyAlertPolicyr      s    K~&*(,@,L'' ( 6 6 8K&./(=%%01)=&y!! ./'/$z"%%55MH#	 r   c           
          [        U Vs/ s H  nU R                  [        U5      5      PM     sn5      (       d  [        R                  " U5      eg s  snf rC   )r1   r2   rW   rf   MinimumArgumentException)r4   flagsrj   s      r   ValidateAtleastOneSpecifiedr     sU    	!$ {401! 
" 
"

/
/
66
" !s   $Ac                    / SQn[        X5        [        XR                  5      nU R                  S5      (       a  U R                  OSnU R                  S5      (       a  U R
                  OSnU R                  R                  R                  5       =(       d    / nU Vs/ s H  owR                  5       PM     sn=(       d    SnU R                  =(       d    U R                  n	U	(       a  U R                  OSn
[        UUU R                  UU	U
UUS9  [        U 5      (       a  SnU R                   (       a"  [#        U R                   UR$                  S5      /n['        UU R(                  UU R*                  U R,                  [/        U R0                  5      U R2                  U R4                  S9nUR6                  R9                  U5        U$ s  snf )z(Builds an AleryPolicy message from args.)--display-namez--policyz--policy-from-filer   Nr   )r   r   r   r   r   r   Aggregation)r   rq   r   r   rY   rc   rd   )r   ra   r^   r2   r   r   CONCEPTSr   r   RelativeNamer   documentation_from_filer   r   r   rk   aggregationrP   r   r   condition_display_namer   r   rZ   rY   rc   rd   
conditionsr   )r4   r}   policy_base_flagsr\   r   r   channel_refschannelr   r   r   rq   r~   s                r   CreateAlertPolicyFromArgsr     s   Jd6 (.B.BC&"..z::T]]( ,,Y77DLLT'44::<B,4@AL""$LAIT(,,L0L0L#8dd $$1/ L'


H00-A Bl 00!((,, /.. I Y'	-? Bs   Gc                    / SQn[        X5        SnU R                  =(       d    U R                  nU(       a  [        XAR                  S5      nSnU R
                  (       a"  [        U R
                  UR                  S5      /n[        UUU R                  UU R                  U R                  [        U R                  5      U R                  U R                  S9	$ )z%Builds a Condition message from args.)z--condition-filterz--conditionz--condition-from-fileNrt   r   )r~   r   rq   r   r   rY   rc   rd   )r   r~   condition_from_filerP   rt   r   r   r   r   r   r   rZ   rY   rc   rd   )r4   r}   condition_base_flagsr~   condition_stringrq   s         r   GetConditionFromArgsr   G  s    3d9)^^?t'?'?!,,k;I ,	%(..? @L 
..&&**t}}-,,}}	
 	r   c                     UR                    H  nUR                  U :X  d  M  Us  $    [        SR                  U 5      5      eNz,No condition with name [{}] found in policy.)r   namer%   r3   )condition_namer\   r~   s      r   GetConditionFromPolicyr   d  sC    $$i~~' % 	4;;NK	M Mr   c                     [        UR                  5       H4  u  p#UR                  U :X  d  M  UR                  R                  U5        Us  $    [	        SR                  U 5      5      er   )	enumerater   r   r<   r%   r3   )r   r\   ir~   s       r   RemoveConditionFromPolicyr   m  s]     1 12la~~'Am 3
 	4;;NK	M Mr   c                     Uc  / nUb  UR                  S5        Xl        Ub  UR                  S5        X0l        Ub  UR                  S5        X@l        Ub  UR                  S5        X l        U $ )z>Modifies base_channel's properties using the passed arguments.typer   descriptionr   )r   r   ru   r   r   )base_channelchannel_typer   r   r   r   s         r   ModifyNotificationChannelr   w  s}     Kv$~&+}%*y!"	r   c                    / SQn[        X5        U R                  =(       d    U R                  nU(       aY  [        X1R                  S[
        S9nUR                  (       a.  [        UR                  R                  S S9UR                  l        OUR	                  5       nU R                  S5      (       a  U R                  OSn[        UU R                  U R                  U R                  US9$ )	z/Builds a NotificationChannel message from args.)r   z--channel-contentz--channel-content-from-fileNotificationChannel)r>   c                     U R                   $ rC   key)props    r   <lambda>0GetNotificationChannelFromArgs.<locals>.<lambda>  s    r   r   r   N)r   r   r   r   )r   channel_contentchannel_content_from_filerP   r   CHANNELS_FIELD_REMAPPINGSr   sortedadditionalPropertiesr2   r   r   r   r   r   )r4   r}   channels_base_flagschannel_stringr   r   s         r   GetNotificationChannelFromArgsr     s    8d8''I4+I+I.0L0L 51JLG ~~,2
..
-
-3H-Jgnn) **,G ,,Y77DLLT'	"704		040A0A/3/?/?+2	
4 4r   c                 ,    [         R                  " XSS9$ )NT)
sort_items)r   DictToAdditionalPropertyMessage)r   
labels_clss     r   ParseCreateLabelsr     s    		1	1T
+ +r   c           	          [         R                  " [        U SU-   5      [        U SU-   5      [        U SU-   5      S9nUR                  5       (       d  gUR	                  X#5      R                  5       $ )a  Returns the result of applying the diff constructed from args.

This API doesn't conform to the standard patch semantics, and instead does
a replace operation on update. Therefore, if there are no updates to do,
then the original labels must be returned as writing None into the labels
field would replace it.

Args:
  args: argparse.Namespace, the parsed arguments with update_labels,
    remove_labels, and clear_labels
  labels_name: str, the name for the labels flag.
  labels_cls: type, the LabelsValue class for the new labels.
  orig_labels: message, the original LabelsValue value to be updated.

Returns:
  LabelsValue: The updated labels of type labels_cls.

Raises:
  ValueError: if the update does not change the labels.
update_remove_clear_)	additionssubtractionsclearN)r
   Diffr{   MayHaveUpdatesApply	GetOrNone)r4   labels_namer   orig_labelslabels_diffs        r   ProcessUpdateLabelsr     so    *   i+564[!89D([013+ 
	#	#	%	%			:	3	=	=	??r   c                    [         R                  " SU 5      nU(       am  UR                  S5      U :w  a  [        S5      e[        R
                  " UR                  S5      5      n[        R
                  " UR                  S5      5      nX44$ [        R
                  " [        R                  R                  R                  R                  SS95      n[         R                  " SU 5      nU(       a(  [        R
                  " UR                  S5      5      nX44$ U(       a<  [        R                  " S	R                  U S
95        [        R
                  " U 5      nX44$ [        S5      e)a3  Returns the metrics scope and monitored project.

Parse the specified monitored project name and return the metrics scope and
monitored project.

Args:
  monitored_project_name: The name of the monitored project to create/delete.
  project_fallback: When set, allows monitored_project_name to be just a
    project id or number.

Raises:
  MonitoredProjectNameError: If an invalid monitored project name is
  specified.

Returns:
   (metrics_scope_def, monitored_project_def): Project parsed metrics scope
     project id, Project parsed metrics scope project id
zElocations/global/metricsScopes/([a-z0-9:\-]+)/projects/([a-z0-9:\-]+)r   2Invalid monitored project name has been specified.      Tr   zprojects/([a-z0-9:\-]+)Received an incorrectly formatted project name. Expected "projects/{identifier}" received "{identifier}". Assuming given resource is a project.
identifier)rematchgroupr+   projects_utilParseProjectr   r   r   r   r   r   warningr3   )monitored_project_nameproject_fallbackmatchedmetrics_scope_defmonitored_project_def$monitored_resource_container_matcheds         r   ParseMonitoredProjectr    sU   & HHO' }}Q11%
>@ @ &227==3CD)66w}}Q7GH0 
	11- &22&&**D*9;+-88"$:,( ,+88
.
4
4Q
7  
	11 
	kk))// *0 * ,889OP
 
	11 &
> r   c                 8   [         R                  " SU 5      nU(       a"  UR                  S5      UR                  S5      4$ U(       aI  [        R                  " SR                  U S95        S[        R                  " U 5      R                  5       4$ [        S5      e)a0  Returns the monitored resource container identifier.

Parse the specified monitored_resource_container_name and return the
identifier.

Args:
  monitored_resource_container_name: The monitored resource container. Ex -
    projects/12345.
  project_fallback: When set, allows monitored_resource_container_name to be
    just a project id or number.

Raises:
  MonitoredProjectNameError: If an invalid monitored project name is
  specified.

Returns:
   resource_type, monitored_resource_container_identifier: Monitored resource
   container type and identifier
z(projects)/([a-z0-9:\-]+)r   r   r   r   projectsr   )
r   r   r   r   r   r3   r   r   Namer+   )!monitored_resource_container_namer  r  s      r   ParseMonitoredResourceContainerr    s    , HH"$E' ==W]]1---KK	''-v8 (. (
 	""#DEJJL 
 $< r   c                     U=(       d1    [         R                  R                  R                  R	                  SS9n[
        R                  R                  U SU0SS9$ )NTr   r   zmonitoring.projects.snoozesr   r   )snooze_namer   s     r   ParseSnoozer  /  sX    Hz((--559949H'				!	!G$. 
" 
 r   c                     U=(       d1    [         R                  R                  R                  R	                  SS9n[
        R                  R                  U SU0SS9$ )NTr   r   zmonitoring.projects.alertsr   r   )
alert_namer   s     r   
ParseAlertr  8  sX    Hz((--559949H'				!	!G$- 
" 
 r   c                     U R                  S5      (       a5  U R                  nU(       a  [        UUS[        S9nU$ [        UUS5      n U$ U" 5       nU$ )z"Returns the base snooze from args.snooze_from_fileSnooze)rD   )r2   r  rP   SNOOZE_FIELD_DELETIONS)r4   snooze_classupdatesnooze_stringsnoozes        r   GetBaseSnoozeMessageFromArgsr  A  si    	())))M 


0	f 
- !


f 
- ^F	-r   c                    Uc  / nSnSn	Ub  UR                  S5        UnO- [        R                  " U R                  R                  5      nSn	Sn
SnUb  UR                  S5        Un
O- [        R                  " U R                  R                  5      n
Sn Ub,  U	(       d%  [        R                  " U5      U R                  l        U
b,  U(       d%  [        R                  " U
5      U R                  l        Ub  UR                  S5        X l	        UbX  UR                  S5        UR                  5       nX=l        Xl        Ub'  [        U5      S:w  a  [        S	5      eXMl        Xl        ggUb  [!        S
5      eg! [
         a     GN8f = f! [
         a     GNf = f! [
         aO    UR                  5       n[        R                  " U5      Ul        [        R                  " U
5      Ul        Xl         Nf = f)z9Override and/or add fields from other flags to an Snooze.NFzinterval.start_timeTzinterval.end_timer   criteria_policiesr   zCExactly 1 alert policy is required if criteria-filter is specified.z>criteria-policies is required if criteria-filter is specified.)r   r   ParseDateTimeinterval	startTimeAttributeErrorendTimeFormatDateTimeTimeIntervalru   Criteriapoliciesr   rT   
ValueErrorrp   r.   )base_snoozer}   r   r  criteria_filter
start_timeend_timer   start_time_targetstart_time_from_baseend_time_targetend_time_from_baser  r   s                 r   ModifySnoozer0  W  s	    K,-"--k.B.B.L.LM! /*+O++K,@,@,H,HIo	$$-A',';';<M'Nk$"+=%*%9%9/%Jk" ~&*"*+  "H)#"		1	$
 	
 (o% # "
#H  #W  
  
 
 $$$&H--.?@H++O<H#	$s7   ,E9 *,F
 AF 9
FF

FFAG43G4c           
          SS/n[        X5        [        XR                  5      n[        UUU R                  U R
                  U R                  U R                  U R                  S9  U$ )z"Builds a Snooze message from args.r   z--snooze-from-file)r   r  r)  r*  r+  )	r   r  r  r0  r   r  r)  r*  r+  )r4   r}   snooze_base_flagsr  s       r   CreateSnoozeFromArgsr3    sd    ')=>d6 (oo>&$$..**}} 
-r   sr   gMbP?ms<   mh   d   wim  yz^([0-9]+)(%s)|c                    SnU n[         R                  S5      S-   nU (       a  [        R                  U 5      nU(       d  [	        SR                  U5      5      e [        UR                  S5      5      nUR                  S5      n[         R                  U5      nXs:  a  [	        SR                  U5      5      eUnXW-  nX-  nXR                  S5      S n U (       a  M  U$ ! [         a    [	        SR                  U5      5      ef = f)	a7  Forked from datelib.py.

Convert a formatted Prometheus string representing an interval into seconds.

The accepted interval string syntax is:
  interval: (interval_part)*
  interval_part: decimal_integer unit
  unit: "ms"       # Milliseconds
      | "s"        # Seconds
      | "m"        # Minutes
      | "h"        # Hours
      | "d"        # Days
      | "w"        # Weeks (7 days)
      | "y"        # Years (365 days)

No whitespace is allowed.
The empty string is valid (and equivalent to 0 seconds).
|decimal_integer| cannot include a sign.
No endianness ordering is required when using multiple interval_part-s. For
example, "1s1Y" and "1Y1s" are both valid.

Examples:
  "45m" = 45 minutes
  "14d12h" = 14 days + 12 hours
  "5d12h30m" = 5 days + 12 hours + 30 minutes

Args:
  interval: String to interpret as an interval.  See above for a description
    of the syntax.

Raises:
  ValueError: If the provided time_string contains unexpected
  characters.

Returns:
  A non-negative integer representing the number of seconds represented by the
  interval string.
r   r=  r   zE{} is invalid due to missing unit of time or unexpected character(s).zLFound invalid character in {}, which is neither an integer nor unit of time.r   z6Time units not ordered from largest to smallest in {}.N)	_INTERVAL_CONV_DICTget_INTERVAL_PART_REGEXPr   r'  r3   intr   end)r  totaloriginal_intervalprevious_multiplierr   numsuffix
multipliers           r   ConvertIntervalToSecondsrK    s   N % ,//4q8!''1E!6"34 
Ac [[^F$((0J(
B
I
I  %C	LE		!'HE 	F 
,1  f./ s   C" "%Dc                     [        U 5      nUS:  a  [        SR                  U US95      eUS-  S:w  a  [        SR                  X5      5      e[        U5      $ )a  Converts Prometheus time to duration JSON string.

Args:
  time_string: String provided by the alert rule YAML file defining time
    (ex:1h30m)

Raises:
  ValueError: If the provided time_string is not a multiple of 30 seconds or
  is less than 30 seconds.

Returns:
  Duration proto string representing the adjusted seconds (multiple of 30
  seconds) value of the provided time_string
   z>{time_string} converted to {seconds}s is less than 30 seconds.time_stringsecondsr   z4{} converted to {}s is not a multiple of 30 seconds.)rK  r'  r3   rZ   rN  s     r   8ConvertPrometheusTimeStringToEvaluationDurationInSecondsrQ    su     %[1'r\
HOO# 	P 	
  |q
>EE	
 
 
	!!r   z!\{\{ *(humanize )? *\$value *\}\}z"\{\{ *(humanize )? *\$labels *\}\}z<\{\{ *(humanize )? *\$labels\.([a-zA-Z_][a-zA-Z0-9_]*) *\}\}c           
      ~    [         R                  S[        R                  S[        R                  SU 5      5      5      $ )a  Translate Prometheus templating language constructs to document variables.

TranslatePromQLTemplateToDocumentVariables translates common Prometheus
templating language constructs to their equivalent Cloud Alerting document
variables. See:
https://prometheus.io/docs/prometheus/latest/configuration/template_reference/
and https://cloud.google.com/monitoring/alerts/doc-variables.

Only the following constructs will be translated:

"{{ $value }}" will be translated to "${metric.label.value}".
"{{ humanize $value }}" will be translated to "${metric.label.value}".
"{{ $labels.<name> }}" will be translated to
"${metric_or_resource.label.<name>}".
"{{ humanize $labels.<name> }}" will be translated to
"${metric_or_resource.label.<name>}".
"{{ $labels }}" will be translated to
"${metric_or_resource.labels}".
"{{ humanize $labels }}" will be translated to
"${metric_or_resource.labels}".

The number of spaces inside the curly braces is immaterial.

All other Prometheus templating language constructs are not translated.

Notes:
1. A document variable reference that does not match a variable
   will be rendered as "(none)".
2. We do not know whether a {{ $labels.<name> }} construct refers to
   a Cloud Alerting metric or a resource label. Thus we translate it to
   "${metric_or_resource.label.<name>}".
   Note that a reference to a non-existent label will be rendered as "(none)".

Examples:
1. "[{{$labels.a}}] VALUE = {{ $value }}" will be translated to
   "[${metric_or_resource.label.a}] VALUE = ${metric.label.value}".

2. "[{{humanize $labels.a}}] VALUE = {{ humanize $value }}"
   will be translated to
   "[${metric_or_resource.label.a}] VALUE = ${metric.label.value}".

Args:
  template: String contents of the "subject" or "content" fields of an
  AlertPolicy protoco buffer. The contents of these fields is a template
  which may contain Prometheus templating language constructs.

Returns:
  The translated template.
z${metric_or_resource.label.\2}z${metric_or_resource.labels}z${metric.label.value})_LABELS_KEY_REGEXPsub_LABELS_VARIABLE_REGEXP_VALUE_VARIABLE_REGEXP)templates    r   *TranslatePromQLTemplateToDocumentVariablesrX  ;  s?    d 
		'!!
)
 
$
$&23
4 4r   z[A-Za-z_][A-Za-z0-9_]*c                    U R                  5       nU R                  5       Ul        UR                  S5      c  [	        S5      eUR                  S5      c  [	        S5      e[
        R                  UR                  S5      5      c  [        S5      eUR                  S5      c  [	        S5      eUR                  S5      UR                  l        UR                  S5      Ul	        UR                  S5      UR                  l
        UR                  S5      UR                  l        UR                  S5      b2  [        [        UR                  S5      5      5      UR                  l        UR                  S	5      b)  [        UR                  S	5      5      UR                  l        UR                  S
5      b  U R                  R#                  5       UR                  l        UR                  S
5      R'                  5        HU  u  pEUR                  R$                  R(                  R+                  U R                  R"                  R-                  XES95        MW     U$ )aN  Populates Alert Policy conditions translated from a Prometheus alert rule.

Args:
  messages: Object containing information about all message types allowed.
  group: Information about the parent group of the current rule.
  rule: The current alert rule being translated into an Alert Policy.

Raises:
  MissingRequiredFieldError: If the provided group/rule is missing an required
  field needed for translation.
  ValueError: If the provided rule name is not a valid Prometheus label name.

Returns:
   The Alert Policy condition corresponding to the Prometheus group and rule
   provided.
r   z+Missing rule group name in field group.namealertz2Missing alert rule name in field group.rules.alertzUAn invalid alert rule name in field group.rules.alert (not a valid PromQL label name)exprz6Missing a PromQL expression in field groups.rules.exprforr  r   r   value)rt    PrometheusQueryLanguageCondition conditionPrometheusQueryLanguagerA  r.   _VALID_LABEL_REGEXP	fullmatchr'  	ruleGroupru   	alertRulequeryrZ   rK  rY   rQ  evaluationIntervalLabelsValuer   itemsr   r   AdditionalProperty)r}   r   ruler~   kvs         r   BuildPrometheusConditionrm  z  s   "   ")//1 , YYv
#5  
XXg
#<  ""488G#45=
	*  
XXf
#@  :?69J),,6((7+)9='9J),,659XXf5E),,2 
XXe_ :I %1;I..7 YYz&@IIj!	
 ..A
 
XXh#11==? ..5 "((*0077LLSS

3
3
?
?
R
R S  + 
r   c                     [         R                  " U 5      nUc  [        S5      e/ nUR                  S5      c  [        S5      eUR                  S5       GH=  nUR                  S5      c  [        SUR                  S5      -  5      eUR                  S5       GH  n[	        XU5      nUR                  5       nUR                  R                  U5        UR                  S5      b  UR                  5       Ul	        UR                  S5      R                  S	5      b8  [        UR                  S5      R                  S	5      5      UR                  l        UR                  S5      R                  S
5      b8  [        UR                  S5      R                  S
5      5      UR                  l        SUR                  l        [        R                  UR                  S5      5      b6  SR!                  UR                  S5      UR                  S5      5      Ul        O5SR!                  UR                  S5      UR                  S5      5      Ul        [$        R&                  " SUR(                  SS9Ul        Ub  X(l        UR                  U5        GM     GM@     U$ ! [.         a  n	[1        SR!                  U	5      5      eSn	A	ff = f)a  Populates Alert Policies translated from Prometheus alert rules.

Args:
  rule_yaml: Opened object of the Prometheus YAML file provided.
  messages: Object containing information about all message types allowed.
  channels: List of Notification Channel names to be added to the translated
    policies.

Raises:
  YamlOrJsonLoadError: If the YAML file cannot be loaded.

Returns:
   A list of the Alert Policies corresponding to the Prometheus rules YAML
   file provided.
Nz&Failed to load YAML file. Is it empty?groupsz	No groupsruleszNo rules in group "%s"r   annotationssubjectr   ztext/markdownz{0}/{1}rZ  z	"{0}"/{1}ORr   r   Could not parse YAML: {0})r   rG   r'  rA  rm  r^   r   r   r   r   rX  rr  r   r   ra  rb  r3   ru   r	   r   r   r   r   rI   r   )
	rule_yamlr}   r   contentsr&  r   rj  r~   r\   rO   s
             r   PrometheusMessageFromStringrw    sb    3Gyy#H?@@H||H%{##h'	7		#1EIIf4EEFF))G$$,XdC	%%'  +88M".!)!7!7!9&
XXm$((3?:HH]+//	:<   ( XXm$((7C:HH]+//>@   ( +:&


'((6):;G(//ii'!2 &

  +11ii'!2 &
 $00&00J
 (0
%E %	 (P O	 G
9@@E
FFGs   JJ 
K$J>>Kc                     UR                  5       nXl        [        Ul        UR                   R	                  5       Ul        U$ )a`  Helper function for creating a basic Notification Channel translated from a Prometheus alert_manager YAML.

Args:
  channel_name: The display name of the desired channel.
  messages: Object containing information about all message types allowed.

Returns:
   A base Notification Channel containing the requested display_name and
   other basic fields.
)r   ru   MIGRATED_FROM_PROMETHEUS_TEXTr   rg  r   )r   r}   r   s      r   #CreateBasePromQLNotificationChannelrz    s;     ((*'$5'//;;='.	.r   c           	      ^   / nU R                  S5      nUc  [        S5      eU R                  S5      b  U R                  S5       H  nUR                  S5      c  M  [        X15      nSUl        UR                  R
                  R                  UR                  R                  R                  SUR                  S5      S95        UR                  U5        M     U R                  S5      b  U R                  S5       H  nUR                  S	5      c  M  [        X15      nS
Ul        UR                  R
                  R                  UR                  R                  R                  S	UR                  S	5      S95        UR                  U5        M     U R                  S5      b  U R                  S5       H  nUR                  S5      c  M  [        X15      nSUl        UR                  R
                  R                  UR                  R                  R                  SUR                  S5      S95        UR                  U5        M     [        / SQ5      nU R                  5        HE  nXv;  d  M
  [        R                  R                  SR                  XpR                  S5      S95        MG     U$ )a=  Populates a Notification Channel translated from Prometheus alert manager.

Args:
  receiver_config: Object containing information the Prometheus receiver. For
    example receiver_configs, see
    https://github.com/prometheus/alertmanager/blob/main/doc/examples/simple.yml
  messages: Object containing information about all message types allowed.

Raises:
  MissingRequiredFieldError: If the provided alert manager file contains
  receivers with missing required field(s).

Returns:
   The Notification Channel corresponding to the Prometheus alert manager
   provided.
r   zMSupplied alert manager file contains receiver without a required field "name"email_configstoemailemail_addressr]  pagerduty_configsservice_key	pagerdutywebhook_configsurlwebhook_tokenauth)r   r|  r  r  zOFound unsupported receiver type {field}. {name}.{field} will not be translated.)fieldr   )rA  r.   rz  r   r   r   r   r   rg  ri  setkeysr   outPrintr3   )receiver_configr}   r   r   fieldsr   supported_receiver_fieldsr  s           r   $BuildChannelsFromPrometheusReceiversr    sg   " ( $$V,,
#	 
 )5!%%o6	D		%5lM++22((44GG#6::d+; H 	

 	  7 ,-9!%%&9:	M	"	.5lM"++22((44GG!M)B H 	

 	  ; *+7!%%&78	E		&5lM*++22((44GGE!2 H 	

 	  9 "G ##%e-	ggmme2E2Ef2MN & 
/r   c                      [         R                  " U 5      n/ nUR                  S5       H  nU[        XQ5      -  nM     U$ ! [         a  n[        SR	                  U5      5      eSnAff = f)a}  Populates Alert Policies translated from Prometheus alert rules.

Args:
  alert_manager_yaml: Opened object of the Prometheus YAML file provided.
  messages: Object containing information about all message types allowed.

Raises:
  YamlOrJsonLoadError: If the YAML file cannot be loaded.

Returns:
   The Alert Policies corresponding to the Prometheus rules YAML file
   provided.
rt  N	receivers)r   rG   rI   r   r3   rA  r  )alert_manager_yamlr}   rv  rO   r   r  s         r   $NotificationChannelMessageFromStringr  d  sq    Gyy+,H (!k2o4_OOH 3	/ 
 G
9@@E
FFGs   A 
A+A&&A+c                     U R                  S5      (       a(  U R                  n/ nU H  nU[        XQU5      -  nM     U$ / nU$ )a  Builds a PromQL policies message from args.

Args:
  args: Flags provided by the user.
  messages: Object containing information about all message types allowed.
  channels: List of full Notification Channel names ("projects/<>/...") to be
    added to the translated policies.

Returns:
   The Alert Policies corresponding to the Prometheus rules YAML file
   provided. In the case that no file is specified, the default behavior is to
   return an empty list.
)policies_from_prometheus_alert_rules_yaml)r2   r  rw  )r4   r}   r   all_rule_yamlsr&  ru  s         r   CreatePromQLPoliciesFromArgsr  }  sU     
ABBCCNH#	-i8LLh $
 
/ H	/r   c                 h    U R                  S5      (       a  U R                  n[        X!5      nU$ / nU$ )an  Builds a notification channel message from args.

Args:
  args: Flags provided by the user.
  messages: Object containing information about all message types allowed.

Returns:
   The notification channels corresponding to the Prometheus alert manager
   YAML file provided. In the case that no file is specified, the default
   behavior is to return an empty list.
*channels_from_prometheus_alertmanager_yaml)r2   r  r  )r4   r}   r  r   s       r   "CreateNotificationChannelsFromArgsr    sB     
BCCHH3H
 
/ H	/r   c                     U=(       d1    [         R                  R                  R                  R	                  SS9n[
        R                  R                  U SU0SS9$ )NTr   r   z&monitoring.projects.uptimeCheckConfigsr   r   )uptime_check_namer   s     r   ParseUptimeCheckr    sX    Hz((--559949H'				!	!G$9 
" 
 r   c	           	         UR                   b  UR                   U l        UR                  b  [        UR                  5      S-   U l        UR                  b'  SSSSS.n	U	R                  UR                  5      U l        UGb!  U R                  b  [        R                  " SS5      eUR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                   S	.n
/ U l        U H-  nU R"                  R%                  U
R                  U5      5        M/     X@l        [)        X!U 5        [+        UUU UUUU5        U $ )
az  Modifies an UptimeCheckConfig based on the args and other inputs.

Args:
  uptime_check: UptimeCheckConfig that is being modified.
  messages: Object containing information about all message types allowed.
  args: Flags provided by the user.
  regions: Potentially updated selected regions.
  user_labels: Potentially updated user labels.
  headers: Potentially updated HTTP headers.
  status_classes: Potentially updated allowed status classes.
  status_codes: Potentially updated allowed status codes.
  update: If this is an update operation (true) or a create operation (false).

Returns:
   The updated UptimeCheckConfig object.
r4  60s300s600s900s)151015regions3Should not be set or updated for Synthetic Monitor.)z
usa-oregonzusa-iowazusa-virginiaeuropezsouth-americazasia-pacific)r   ru   timeoutstrperiodrA  syntheticMonitorrf   rh   UptimeCheckConfig'SelectedRegionsValueListEntryValuesEnum
USA_OREGONUSA_IOWAUSA_VIRGINIAEUROPESOUTH_AMERICAASIA_PACIFICselectedRegionsr   
userLabelsSetUptimeCheckMatcherFieldsSetUptimeCheckProtocolFields)uptime_checkr}   r4   r  user_labelsheadersstatus_classesstatus_codesr  period_mappingregion_mappingregions               r   ModifyUptimeCheckr    s   6 
"#00L	\\t||,s2L	[[	N ),,T[[9L$$011
J 
 &&NNYY &&NNWW &&NN[[ &&NNUU &&NN\\ &&NN[[#N( $&L "")).*<*<V*DE )dl;
 
r   c                    / SQn[        X5        UR                  5       nU R                  S5      (       a  [        XU5        O/U R                  S5      (       a  [	        XU5        O[        XU5        SnU R                  S5      (       ay  UR                  R                  5       nU R                  R                  5        HA  u  pVUR                  R                  UR                  R                  R                  XVS95        MC     SnU R                  S5      (       a|  UR                  R                  5       nUb_  U R                  R                  5        HA  u  pVUR                  R                  UR                  R                  R                  XVS95        MC     SUl        SUl        [#        UUU U R$                  UUU R&                  U R(                  S	9  U$ )
z#Builds an Uptime message from args.)z--resource-labelsz
--group-idz--synthetic-targetresource_labelsgroup_idNr  r]  r  r  )r  r  r  r  r  )r   r  r2   %SetUptimeCheckMonitoredResourceFieldsSetUptimeCheckGroupFieldsSetUptimeCheckSyntheticFieldsUserLabelsValuer  rh  r   r   ri  	HttpCheckHeadersValuer  r  r  r  r  r  r  )r4   r}   uptime_base_flagsr  r  rk  rl  r  s           r   CreateUptimeFromArgsr  	  s   Od6++-,	'(()$,G
##dl;!$,?+	m$$,,<<>K  &&(&&--

$
$
4
4
G
G H  ) '	i    --/G,,$$&$!$$++++>>1>N	
 ' ,,
ll(($$	 
r   c           	         SSSSSSSSS.nUR                  5       Ul        UR                  U R                  5      UR                  l        UR                   R                  5       UR                  l        U R                  R                  5        HU  u  pEUR                  R                  R                  R                  UR                   R
                  R                  XES	95        MW     g
)z,Set Monitored Resource fields based on args.
uptime_urlgce_instancegae_appaws_ec2_instanceaws_elb_load_balancerservicedirectory_servicecloud_run_revision)z
uptime-urlgce-instancezgae-appzaws-ec2-instanceaws-elb-load-balancerzservicedirectory-servicezcloud-run-revisionNr]  N)MonitoredResourcemonitoredResourcerA  resource_typer   rg  r   r  rh  r   r   ri  )r4   r}   r  resource_mappingrk  rl  s         r   r  r  9  s     !$,6"<0	 $,#=#=#?, (8(<(<T=O=O(P,  %  ,,.   ' ""((*da""))>>EE""..AA 	B 	
 +r   c                    SSSS.nUR                  5       Ul        U R                  UR                  l        [        R
                  " UR                  U R                  5      UR                   R                  SS9UR                  l	        g)zSet Group fields based on args.INSTANCEAWS_ELB_LOAD_BALANCER)r  r  Nz
group typer   N)
ResourceGroupresourceGroupr  groupIdr	   r   rA  
group_typeResourceTypeValueValuesEnumresourceType)r4   r}   r  group_mappings       r   r  r  R  sv     !6-
  (557,'+}},$,5,B,B(88-,)r   c                     UR                  5       Ul        UR                  5       UR                  l        U R                  UR                  R                  l        g)z+Set Synthetic Monitor fields based on args.N)SyntheticMonitorTargetr  CloudFunctionV2TargetcloudFunctionV2synthetic_targetr   )r4   r}   r  s      r   r  r  b  sI    "*"A"A"C,$$& / 8<7L7L,//4r   c                 f   U R                  S5      (       Ga  UR                  b  [        R                  " SS5      eUR	                  5       nU R
                  Ul        UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  UR                  R                  R                  S.nUR                  U R                  5      Ul        U R                  S5      (       Ga  UR                   UR                  R                  R                  UR                  R                  R                  4;  a  [        R                  " SS5      eUR#                  5       Ul        U R&                  UR$                  l        UR"                  R*                  R,                  UR"                  R*                  R.                  UR"                  R*                  R,                  S	.nUR                  U R0                  5      UR$                  l        / Ul        UR4                  R7                  U5        gg)
z!Set Matcher fields based on args.matcher_contentNz--matcher_content(Should not be set for Synthetic Monitor.)zcontains-stringznot-contains-stringzmatches-regexznot-matches-regexzmatches-json-pathznot-matches-json-pathN	json_pathz--json-pathz1Should only be used with JSON_PATH matcher types.)zexact-matchzregex-matchN)r2   r  rf   rh   ContentMatcherr  r   MatcherValueValuesEnumCONTAINS_STRINGNOT_CONTAINS_STRINGMATCHES_REGEXNOT_MATCHES_REGEXMATCHES_JSON_PATHNOT_MATCHES_JSON_PATHrA  matcher_typematcherJsonPathMatcherjsonPathMatcherr  jsonPathJsonMatcherValueValuesEnumEXACT_MATCHREGEX_MATCHjson_path_matcher_typejsonMatchercontentMatchersr   )r4   r}   r  content_matchermatcher_mappingjsonpath_matcher_mappings         r   r  r  k  s9   	'(($$011
I  --/O"22O ##::JJ ##::NN ##::HH ##::LL ##::LL ##::PP%%<<LL'O* .11$2C2CDO$$		 	 

!
!
8
8
J
J

!
!
8
8
N
N) 
 33N
 	
 )1(@(@(Bo%15o%%. &&AAMM &&AAMM((CCOO" #
&
&t'B'B
C %%1 $&L   ''8o )r   c                    U(       d  U R                  S5      (       d  UR                  b  / SQnU H;  n[        U5      n	U R                  U	5      (       d  M&  [        R                  " US5      e   U(       a  [        R                  " SS5      eU(       a  [        R                  " SS5      eU(       a  [        R                  " SS5      egU(       d  U R
                  S	:X  d  UR                  GbN  U R                  c  UR                  c  [        S
5      eUR                  c  UR                  5       Ul        UR                  n
U R                  b  U R                  U
l        U R                  b0  UR                  5       U
l        U R                  U
R                  l        / SQnU H;  n[        U5      n	U R                  U	5      (       d  M&  [        R                  " US5      e   U(       a  [        R                  " SS5      eU(       a  [        R                  " SS5      eU(       a  [        R                  " SS5      egUR                  c  UR                  5       Ul        UR                  nU R                   b  U R                   Ul        U R"                  b  U R"                  Ul        U R&                  b  U R&                  Ul        U R*                  b  U R*                  Ul        UR.                  c  UR1                  5       Ul        U R2                  b  U R2                  UR.                  l        U R4                  b  U R4                  UR.                  l        U R                  b0  UR                  5       Ul        U R                  UR                  l        U R6                  b  U R6                  R9                  5       Ul        U(       d  U R
                  S:X  d  UR:                  (       a:  SUl        U R                  b  U R                  Ul        UR                  c  SUl        O9SUl        U R                  b  U R                  Ul        UR                  c  SUl        SUR<                  R>                  R@                  0nU RB                  b?  UR=                  5       Ul"        URG                  U RB                  5      URD                  l$        UR                  RJ                  RL                  UR                  RJ                  RN                  UR                  RJ                  RL                  S.nURP                  b  U RR                  b   URG                  U RR                  5      Ul(        UR                  RT                  RV                  UR                  RT                  RX                  UR                  RT                  RZ                  UR                  RT                  RV                  S.nUR\                  b  U R^                  b   URG                  U R^                  5      Ul.        X;l0        URb                  Rd                  Rf                  URb                  Rd                  Rh                  URb                  Rd                  Rj                  URb                  Rd                  Rl                  URb                  Rd                  Rn                  URb                  Rd                  Rp                  URb                  Rd                  Rr                  S.nUbH  / Ul:        U H:  nURt                  Rw                  URc                  URG                  U5      S95        M<     gUb9  / Ul:        U H+  nURt                  Rw                  URc                  US95        M-     gURt                  c?  / Ul:        URt                  Rw                  URc                  URG                  S5      S95        gg)z"Set Protocol fields based on args.r  N)--path--validate-ssl--mask-headers--custom-content-type
--username
--password--body--request-method--content-typez--portz--pings-count--service-agent-authr  r  r  zstatus-classeszstatus-codestcpzMissing required field "port")
r  r  r  r  r	  r
  r  r  r  r  z'Should not be set for TCP Uptime Check.z2Should not be set or updated for TCP Uptime Check.httpsTi  FP   z
oidc-token)rA  postN)unspecifiedzurl-encodedzuser-providedN)1xx2xx3xx4xx5xxr1   N)statusClass)statusValuer  )<r2   r  rW   rf   rh   protocoltcpCheckportr.   TcpCheckpings_count
PingConfig
pingConfig
pingsCount	httpCheckr  pathvalidate_sslvalidateSslmask_headersmaskHeaderscustom_content_typecustomContentTypeauthInfoBasicAuthenticationusernamepasswordbodyencodeuseSslServiceAgentAuthenticationTypeValueValuesEnum
OIDC_TOKENservice_agent_authserviceAgentAuthenticationrA  r   RequestMethodValueValuesEnumGETPOSTrequestMethodrequest_methodContentTypeValueValuesEnumTYPE_UNSPECIFIEDURL_ENCODEDUSER_PROVIDEDcontentTypecontent_typer  ResponseStatusCodeStatusClassValueValuesEnumSTATUS_CLASS_1XXSTATUS_CLASS_2XXSTATUS_CLASS_3XXSTATUS_CLASS_4XXSTATUS_CLASS_5XXSTATUS_CLASS_ANYSTATUS_CLASS_UNSPECIFIEDacceptedResponseStatusCodesr   )r4   r}   r  r  r  r  r  ri   rj   r7   	tcp_check
http_checkservice_agent_auth_mappingmethod_mappingcontent_mappingstatus_mappingstatuss                    r   r  r    s    T%%&899$$0 "d			$		33<
 	
 " 11
J  11

?  11
O   T]]e+(yy\22:%&EFF$&//1l%%Iyyyyin#%002i(,(8(8i% "d			$		33;
 	
 " 11
I  11
P  11
N  
 %'113l''Jyy		jo$#00j$#00j+%)%=%=j""$88:j}} %)]]j"}} %)]]j"#&113j)-)9)9j&yy		((*jot}}/J4E4Ej		))
		 
j		))
		 
//CCNN"
 *

-
-
/ + %
(
()@)@
A ++0 !!>>BB""??DD  ==AAN
 '4+>+>+J!/!3!3D4G4G!Hj 99JJ 99EE 99GG  ;;LLO %):):)F.2243D3DEj  ''BBSS ''BBSS ''BBSS ''BBSS ''BBSS ''BBSS ''BB[[)N. !/1j,"&..55''N4F4Fv4N'O	
 # 
	!/1j, &..55''F';	
 ! 
	/	/	7/1j,,,33

%
%.2D2DU2K
%
L 
8r   )NN)NNNNNNNNrC   )NNNNNNN)NNNNN)F)NNNNNN)Yr   
__future__r   r   r   r   apitools.base.pyr   googlecloudsdk.callioper   rf   #googlecloudsdk.command_lib.projectsr   r   $googlecloudsdk.command_lib.util.apisr	   $googlecloudsdk.command_lib.util.argsr
   googlecloudsdk.corer   r   r   r   googlecloudsdk.core.utilr   r:   r   r  ry  Errorr   r!   r%   r(   r+   r.   r8   rA   rE   rP   rW   rZ   ra   rk   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r0  r3  r@  compilejoinrB  rK  rQ  rV  rU  rS  rX  ra  rm  rw  rz  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   <module>r^     s   7 &  ' 	 % > E : < * # * ) $ * 
 -h7 $  G 
P*** PNZ-- NDZ-- DIZ-- IN
 0 0 NQ
 0 0 QK >B  1
 'T ;?48IM :z= JNGK?C#$L7)X:MM HL=A*.,44+
@>42n*Z2 EP, Ah !$7$<< D  3C 88 C  3C 88 C  3C 88 C 2377 C !4S!99 C 

chh233 
Od"D $HI **%JK ZZCE 74x jj!:; AHCGL$K\24.$ Od-`2 M99F Jr   