#!/usr/bin/env bash
# Aztec V5 monitoring installer — self-hosted Prometheus/Grafana/Alertmanager + Telegram.
# Runs on the Aztec node (metrics setup) or a monitoring machine (dashboard/alerts).

# ---- portability layer ----
OS="other"
case "$(uname -s 2>/dev/null || echo other)" in
  Linux)  OS="linux" ;;
  Darwin) OS="macos" ;;
esac

lower() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]'; }

# sed_inplace <expr> <file> — portable in-place edit (BSD & GNU) via temp file.
sed_inplace() {
  local _si_expr="$1" _si_file="$2" _si_tmp="${2}.sitmp.$$"
  sed "$_si_expr" "$_si_file" > "$_si_tmp" && mv "$_si_tmp" "$_si_file" || { rm -f "$_si_tmp"; return 1; }
}

# readlink_f <path> — portable "resolve to absolute" (no GNU readlink -f).
readlink_f() {
  ( cd "$(dirname "$1")" 2>/dev/null && printf '%s/%s\n' "$(pwd)" "$(basename "$1")" )
}

# b64_decode — portable base64 decode (GNU --decode/-d, BSD/macOS -D).
b64_decode() {
  if printf '' | base64 --decode >/dev/null 2>&1; then base64 --decode
  elif printf '' | base64 -d >/dev/null 2>&1; then base64 -d
  else base64 -D; fi
}

c_red()   { printf '\033[31m%s\033[0m\n' "$*"; }
c_green() { printf '\033[32m%s\033[0m\n' "$*"; }
c_yellow(){ printf '\033[33m%s\033[0m\n' "$*"; }
info()    { printf '%s\n' "$*"; }

# color only when stdout is a TTY and not explicitly disabled
if [ -t 1 ] && [ "${NO_COLOR:-}" != "1" ]; then
  _C_RESET="$(printf '\033[0m')"; _C_BOLD="$(printf '\033[1m')"; _C_CYAN="$(printf '\033[36m')"; _C_DIM="$(printf '\033[2m')"
else
  _C_RESET=""; _C_BOLD=""; _C_CYAN=""; _C_DIM=""
fi

# header — a bold, cyan section header (honors the TTY color guard; plain when piped).
header() { printf '%s%s%s\n' "${_C_BOLD}${_C_CYAN}" "$*" "${_C_RESET}"; }

# primary_ip — best-effort LAN/primary IP of this machine (Linux + macOS). Empty if unknown.
primary_ip() {
  _ip=""
  if command -v ip >/dev/null 2>&1; then
    _ip="$(ip route get 1.1.1.1 2>/dev/null | grep -oE 'src [0-9.]+' | awk '{print $2}' | head -1)"
  fi
  if [ -z "$_ip" ] && command -v hostname >/dev/null 2>&1; then
    _ip="$(hostname -I 2>/dev/null | awk '{print $1}')"   # Linux
  fi
  if [ -z "$_ip" ] && command -v ipconfig >/dev/null 2>&1; then
    _ip="$(ipconfig getifaddr en0 2>/dev/null)"           # macOS
  fi
  printf '%s' "$_ip"
}

# ---- state ----
STATE_DIR="${STATE_DIR:-$HOME/.aztec-monitoring}"
STATE_FILE="${STATE_FILE:-$STATE_DIR/state.env}"

state_load() {
  [ -f "$STATE_FILE" ] || return 0
  local _line _k _v
  while IFS= read -r _line || [ -n "$_line" ]; do
    case "$_line" in
      ''|'#'*) continue ;;               # skip blanks and comments
      *=*) : ;;                          # must look like KEY=VALUE
      *) continue ;;
    esac
    _k=${_line%%=*}                       # everything before first =
    _v=${_line#*=}                        # everything after first =
    # only accept plausible env-var key names (no metachars); ignore junk lines
    case "$_k" in
      [A-Za-z_]*) : ;;
      *) continue ;;
    esac
    export "${_k}=${_v}"
  done < "$STATE_FILE"
}

# state_set KEY VALUE — write/replace KEY=VALUE, no duplicates. Never store secrets here.
state_set() {
  local _sk="$1" _sv="$2"
  mkdir -p "$STATE_DIR"; chmod 700 "$STATE_DIR" 2>/dev/null || true
  touch "$STATE_FILE"
  if grep -q "^${_sk}=" "$STATE_FILE" 2>/dev/null; then
    # grep -v exits 1 when it removes the only line(s); don't let that skip the mv.
    grep -v "^${_sk}=" "$STATE_FILE" > "${STATE_FILE}.tmp.$$" || true
    mv "${STATE_FILE}.tmp.$$" "$STATE_FILE"
  fi
  printf '%s=%s\n' "$_sk" "$_sv" >> "$STATE_FILE"
  # export so the current process sees it immediately (no eval; safe for any value)
  export "${_sk}=${_sv}"
}

# state_unset KEY — remove KEY from the state file and the current environment.
state_unset() {
  local _uk="$1"
  if [ -f "$STATE_FILE" ] && grep -q "^${_uk}=" "$STATE_FILE" 2>/dev/null; then
    grep -v "^${_uk}=" "$STATE_FILE" > "${STATE_FILE}.tmp.$$" || true
    mv "${STATE_FILE}.tmp.$$" "$STATE_FILE"
  fi
  unset "$_uk" 2>/dev/null || true
}

# state_prune_if_empty — delete the state file + dir if no meaningful keys remain.
state_prune_if_empty() {
  [ -f "$STATE_FILE" ] || return 0
  # count lines that look like KEY=VALUE (ignore blanks and comments)
  if ! grep -qE '^[A-Za-z_][A-Za-z0-9_]*=' "$STATE_FILE" 2>/dev/null; then
    rm -f "$STATE_FILE"
    rmdir "$STATE_DIR" 2>/dev/null || true
  fi
}

# ---- node list (multi-node) ----
# MON_NODES format: nodes joined by ';', each node "endpoint|label" (label may be empty).
# ';' and '|' cannot occur in a host:port or a sanitized label ([A-Za-z0-9._-]), so
# splitting on them is unambiguous.

# nodes_load_string — prints the current MON_NODES ';'-joined string, migrating a
# legacy single-node state (NODE_ENDPOINT/MON_INSTANCE_NAME) if MON_NODES is unset.
nodes_load_string() {
  state_load
  if [ -z "${MON_NODES:-}" ] && [ -n "${NODE_ENDPOINT:-}" ]; then
    MON_NODES="${NODE_ENDPOINT}|${MON_INSTANCE_NAME:-}"
  fi
  printf '%s' "${MON_NODES:-}"
}

# node_list_print <nodes-string> — print a numbered list (label + endpoint).
# `read` drops a final line with no trailing newline, so the last (or only) node would
# be skipped; `|| [ -n "$_n" ]` keeps it (same pattern as state_load).
node_list_print() {
  _i=1
  printf '%s' "$1" | tr ';' '\n' | while IFS= read -r _n || [ -n "$_n" ]; do
    [ -z "$_n" ] && continue
    _ep="${_n%%|*}"; _lb="${_n#*|}"
    printf '  %s. %s   %s\n' "$_i" "${_lb:-<no label>}" "$_ep"
    _i=$((_i+1))
  done
}

# node_list_count <nodes-string> — print the number of nodes.
node_list_count() { printf '%s' "$1" | tr ';' '\n' | grep -c '.' ; }

# node_list_has_label <nodes-string> <label> — exit 0 if label already present.
node_list_has_label() {
  [ -z "$2" ] && return 1
  _oldifs="$IFS"; IFS=';'
  for _n in $1; do
    [ -z "$_n" ] && continue
    [ "${_n#*|}" = "$2" ] && { IFS="$_oldifs"; return 0; }
  done
  IFS="$_oldifs"; return 1
}

# node_list_has_endpoint <nodes-string> <endpoint> — return 0 if the endpoint is present.
node_list_has_endpoint() {
  _found=1; _oldifs="$IFS"; IFS=';'
  for _n in $1; do
    [ -z "$_n" ] && continue
    [ "${_n%%|*}" = "$2" ] && { _found=0; break; }
  done
  IFS="$_oldifs"; return $_found
}

# node_list_remove <nodes-string> <index> — print the list with the Nth node removed.
# IFS-for-loop split (no pipe, no subshell) so the built-up string survives.
node_list_remove() {
  _idx="$2"; _i=0; _out=""; _oldifs="$IFS"; IFS=';'
  for _n in $1; do
    [ -z "$_n" ] && continue
    _i=$((_i+1))
    [ "$_i" -eq "$_idx" ] && continue
    _out="${_out:+$_out;}$_n"
  done
  IFS="$_oldifs"; printf '%s' "$_out"
}

# node_list_append <nodes-string> <endpoint> <label> — print the list with a node appended.
node_list_append() {
  if [ -n "$1" ]; then
    printf '%s;%s|%s' "$1" "$2" "$3"
  else
    printf '%s|%s' "$2" "$3"
  fi
}


# ---- embedded artifacts (generated by build/embed.sh; do not edit by hand) ----
write_dashboard_json() { b64_decode > "$1" <<'B64'
ewogICJhbm5vdGF0aW9ucyI6IHsKICAgICJsaXN0IjogWwogICAgICB7CiAgICAgICAgImJ1aWx0
SW4iOiAxLAogICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgInR5cGUiOiAiZ3JhZmFu
YSIsCiAgICAgICAgICAidWlkIjogIi0tIEdyYWZhbmEgLS0iCiAgICAgICAgfSwKICAgICAgICAi
ZW5hYmxlIjogdHJ1ZSwKICAgICAgICAiaGlkZSI6IHRydWUsCiAgICAgICAgImljb25Db2xvciI6
ICJyZ2JhKDAsIDIxMSwgMjU1LCAxKSIsCiAgICAgICAgIm5hbWUiOiAiQW5ub3RhdGlvbnMgJiBB
bGVydHMiLAogICAgICAgICJ0eXBlIjogImRhc2hib2FyZCIKICAgICAgfQogICAgXQogIH0sCiAg
ImRlc2NyaXB0aW9uIjogIk9wZXJhdG9yLWZhY2luZyBoZWFsdGggZGFzaGJvYXJkIGZvciBhIHNl
bGYtaG9zdGVkIEF6dGVjIFY1IHNlcXVlbmNlci92YWxpZGF0b3Igbm9kZS4gQW5zd2VycyAnaXMg
bXkgbm9kZSBPSywgb3Igd2hhdCBkbyBJIGZpeD8nIGF0IGEgZ2xhbmNlLiBTZWxmLWhvc3QgYWdh
aW5zdCB5b3VyIG93biBub2RlLiBWZXJpZmllZCBhZ2FpbnN0IGxpdmUgVjUgbm9kZXMgKHY1LjAu
MCkuIFNlZSBtb25pdG9yaW5nLWd1aWRlLm1kLiIsCiAgImVkaXRhYmxlIjogdHJ1ZSwKICAiZmlz
Y2FsWWVhclN0YXJ0TW9udGgiOiAwLAogICJncmFwaFRvb2x0aXAiOiAxLAogICJsaW5rcyI6IFtd
LAogICJsaXZlTm93IjogZmFsc2UsCiAgInJlZnJlc2giOiAiMzBzIiwKICAic2NoZW1hVmVyc2lv
biI6IDM5LAogICJ0YWdzIjogWwogICAgImF6dGVjIiwKICAgICJ2NSIsCiAgICAic2VxdWVuY2Vy
IiwKICAgICJ2YWxpZGF0b3IiLAogICAgIm9wZXJhdG9yIgogIF0sCiAgInRlbXBsYXRpbmciOiB7
CiAgICAibGlzdCI6IFsKICAgICAgewogICAgICAgICJjdXJyZW50Ijoge30sCiAgICAgICAgImRh
dGFzb3VyY2UiOiB7CiAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICJ1
aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICB9LAogICAgICAgICJkZWZpbml0aW9uIjog
ImxhYmVsX3ZhbHVlcyhhenRlY19hcmNoaXZlcl9ibG9ja19oZWlnaHQsIGluc3RhbmNlKSIsCiAg
ICAgICAgImhpZGUiOiAwLAogICAgICAgICJpbmNsdWRlQWxsIjogdHJ1ZSwKICAgICAgICAibGFi
ZWwiOiAiTm9kZSAoaW5zdGFuY2UpIiwKICAgICAgICAibXVsdGkiOiB0cnVlLAogICAgICAgICJu
YW1lIjogImluc3RhbmNlIiwKICAgICAgICAib3B0aW9ucyI6IFtdLAogICAgICAgICJxdWVyeSI6
IHsKICAgICAgICAgICJxdWVyeSI6ICJsYWJlbF92YWx1ZXMoYXp0ZWNfYXJjaGl2ZXJfYmxvY2tf
aGVpZ2h0LCBpbnN0YW5jZSkiLAogICAgICAgICAgInJlZklkIjogIlN0YW5kYXJkVmFyaWFibGVR
dWVyeSIKICAgICAgICB9LAogICAgICAgICJyZWZyZXNoIjogMiwKICAgICAgICAicmVnZXgiOiAi
IiwKICAgICAgICAic29ydCI6IDEsCiAgICAgICAgInR5cGUiOiAicXVlcnkiCiAgICAgIH0sCiAg
ICAgIHsKICAgICAgICAiY3VycmVudCI6IHt9LAogICAgICAgICJkYXRhc291cmNlIjogewogICAg
ICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVU
SEVVU30iCiAgICAgICAgfSwKICAgICAgICAiZGVmaW5pdGlvbiI6ICJsYWJlbF92YWx1ZXMoYXp0
ZWNfdmFsaWRhdG9yX2F0dGVzdGVkX2Vwb2NoX2NvdW50LCBhenRlY19hdHRlc3Rlcl9hZGRyZXNz
KSIsCiAgICAgICAgImhpZGUiOiAwLAogICAgICAgICJpbmNsdWRlQWxsIjogdHJ1ZSwKICAgICAg
ICAibGFiZWwiOiAiQXR0ZXN0ZXIiLAogICAgICAgICJtdWx0aSI6IHRydWUsCiAgICAgICAgIm5h
bWUiOiAiYXR0ZXN0ZXIiLAogICAgICAgICJvcHRpb25zIjogW10sCiAgICAgICAgInF1ZXJ5Ijog
ewogICAgICAgICAgInF1ZXJ5IjogImxhYmVsX3ZhbHVlcyhhenRlY192YWxpZGF0b3JfYXR0ZXN0
ZWRfZXBvY2hfY291bnQsIGF6dGVjX2F0dGVzdGVyX2FkZHJlc3MpIiwKICAgICAgICAgICJyZWZJ
ZCI6ICJTdGFuZGFyZFZhcmlhYmxlUXVlcnkiCiAgICAgICAgfSwKICAgICAgICAicmVmcmVzaCI6
IDIsCiAgICAgICAgInJlZ2V4IjogIiIsCiAgICAgICAgInNvcnQiOiAxLAogICAgICAgICJ0eXBl
IjogInF1ZXJ5IgogICAgICB9CiAgICBdCiAgfSwKICAidGltZSI6IHsKICAgICJmcm9tIjogIm5v
dy0yNGgiLAogICAgInRvIjogIm5vdyIKICB9LAogICJ0aW1lcGlja2VyIjoge30sCiAgInRpbWV6
b25lIjogImJyb3dzZXIiLAogICJ0aXRsZSI6ICJBenRlYyBWNSBOb2RlIFx1MjAxNCBPcGVyYXRv
ciBIZWFsdGgiLAogICJ1aWQiOiAiYXp0ZWMtdjUtb3BlcmF0b3IiLAogICJ2ZXJzaW9uIjogMSwK
ICAicGFuZWxzIjogWwogICAgewogICAgICAiY29sbGFwc2VkIjogZmFsc2UsCiAgICAgICJncmlk
UG9zIjogewogICAgICAgICJoIjogMSwKICAgICAgICAidyI6IDI0LAogICAgICAgICJ4IjogMCwK
ICAgICAgICAieSI6IDAKICAgICAgfSwKICAgICAgImlkIjogMTAwLAogICAgICAidGl0bGUiOiAi
U2VxdWVuY2VyIEhlYWx0aCIsCiAgICAgICJ0eXBlIjogInJvdyIsCiAgICAgICJwYW5lbHMiOiBb
XQogICAgfSwKICAgIHsKICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgInR5cGUiOiAicHJv
bWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICB9LAogICAg
ICAiZGVzY3JpcHRpb24iOiAiSXMgdGhlIG5vZGUgdXAgYW5kIGJlaW5nIHNjcmFwZWQ/IiwKICAg
ICAgImZpZWxkQ29uZmlnIjogewogICAgICAgICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJjb2xv
ciI6IHsKICAgICAgICAgICAgIm1vZGUiOiAidGhyZXNob2xkcyIKICAgICAgICAgIH0sCiAgICAg
ICAgICAibWFwcGluZ3MiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAidHlwZSI6ICJ2
YWx1ZSIsCiAgICAgICAgICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgICAgICAgICAiMCI6IHsK
ICAgICAgICAgICAgICAgICAgInRleHQiOiAiRE9XTiIsCiAgICAgICAgICAgICAgICAgICJjb2xv
ciI6ICJyZWQiCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIjEiOiB7CiAgICAg
ICAgICAgICAgICAgICJ0ZXh0IjogIlVQIiwKICAgICAgICAgICAgICAgICAgImNvbG9yIjogImdy
ZWVuIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAg
ICAgICAgXSwKICAgICAgICAgICJ0aHJlc2hvbGRzIjogewogICAgICAgICAgICAibW9kZSI6ICJh
YnNvbHV0ZSIsCiAgICAgICAgICAgICJzdGVwcyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAg
ICAgICAgICAiY29sb3IiOiAicmVkIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6IG51bGwKICAg
ICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb2xvciI6ICJn
cmVlbiIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAxCiAgICAgICAgICAgICAgfQogICAgICAg
ICAgICBdCiAgICAgICAgICB9LAogICAgICAgICAgInVuaXQiOiAibm9uZSIKICAgICAgICB9LAog
ICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3JpZFBvcyI6IHsKICAgICAg
ICAiaCI6IDQsCiAgICAgICAgInciOiA0LAogICAgICAgICJ4IjogMCwKICAgICAgICAieSI6IDEK
ICAgICAgfSwKICAgICAgImlkIjogMSwKICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgImNvbG9y
TW9kZSI6ICJiYWNrZ3JvdW5kIiwKICAgICAgICAiZ3JhcGhNb2RlIjogIm5vbmUiLAogICAgICAg
ICJyZWR1Y2VPcHRpb25zIjogewogICAgICAgICAgImNhbGNzIjogWwogICAgICAgICAgICAibGFz
dE5vdE51bGwiCiAgICAgICAgICBdLAogICAgICAgICAgImZpZWxkcyI6ICIiLAogICAgICAgICAg
InZhbHVlcyI6IGZhbHNlCiAgICAgICAgfSwKICAgICAgICAidGV4dE1vZGUiOiAidmFsdWUiCiAg
ICAgIH0sCiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNl
IjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6
ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogIm1heCh1
cHtqb2I9XCJhenRlYy1ub2RlXCIsIGluc3RhbmNlPX5cIiRpbnN0YW5jZVwifSkiLAogICAgICAg
ICAgInJlZklkIjogIkEiCiAgICAgICAgfQogICAgICBdLAogICAgICAidGl0bGUiOiAiTm9kZSB1
cCIsCiAgICAgICJ0eXBlIjogInN0YXQiCiAgICB9LAogICAgewogICAgICAiZGF0YXNvdXJjZSI6
IHsKICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAidWlkIjogIiR7RFNfUFJP
TUVUSEVVU30iCiAgICAgIH0sCiAgICAgICJkZXNjcmlwdGlvbiI6ICJBdHRlc3RhdGlvbiBkdXR5
IG91dGNvbWUgb3ZlciB0aGUgbGFzdCBob3VyLiBBVFRFU1RFRDogYXQgbGVhc3Qgb25lIHN1Y2Nl
c3NmdWwgYXR0ZXN0YXRpb24uIE5PIERVVElFUzogbm8gY29tbWl0dGVlIHNsb3RzIGZlbGwgdG8g
dGhpcyBub2RlIHRoaXMgaG91ciBcdTIwMTQgdGhlIG5vcm1hbCBzdGF0ZSBhdCBtYWlubmV0IGNh
ZGVuY2UsIG5vdCBhIHByb2JsZW0uIE1JU1NJTkcgRFVUSUVTOiB0aGUgbm9kZSB3YXMgb24gdGhl
IGNvbW1pdHRlZSBhbmQgZmFpbGVkIHRvIGF0dGVzdCBmb3IgYSBub2RlLXNpZGUgcmVhc29uIChz
YW1lIGZpbHRlciBhcyB0aGUgQXp0ZWNGYWlsZWRBdHRlc3RhdGlvbnMgYWxlcnQpOyBpbnZlc3Rp
Z2F0ZS4gQmVpbmcgZWplY3RlZCBvciBuZXZlciBzZWxlY3RlZCBpcyBub3QgdmlzaWJsZSBpbiBu
b2RlIG1ldHJpY3MgXHUyMDE0IHdhdGNoIHRoZSBBdHRlc3RlciBwYXJ0aWNpcGF0aW9uIHJhdGUg
cGFuZWwgZm9yIGxvbmctdGVybSB0cmVuZHMuIiwKICAgICAgImZpZWxkQ29uZmlnIjogewogICAg
ICAgICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAgIm1vZGUi
OiAidGhyZXNob2xkcyIKICAgICAgICAgIH0sCiAgICAgICAgICAibWFwcGluZ3MiOiBbCiAgICAg
ICAgICAgIHsKICAgICAgICAgICAgICAidHlwZSI6ICJ2YWx1ZSIsCiAgICAgICAgICAgICAgIm9w
dGlvbnMiOiB7CiAgICAgICAgICAgICAgICAiLTEiOiB7CiAgICAgICAgICAgICAgICAgICJ0ZXh0
IjogIk1JU1NJTkcgRFVUSUVTIiwKICAgICAgICAgICAgICAgICAgImNvbG9yIjogInJlZCIsCiAg
ICAgICAgICAgICAgICAgICJpbmRleCI6IDAKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAg
ICAgICAiMCI6IHsKICAgICAgICAgICAgICAgICAgInRleHQiOiAiTk8gRFVUSUVTIiwKICAgICAg
ICAgICAgICAgICAgImNvbG9yIjogInRleHQiLAogICAgICAgICAgICAgICAgICAiaW5kZXgiOiAx
CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIjEiOiB7CiAgICAgICAgICAgICAg
ICAgICJ0ZXh0IjogIkFUVEVTVEVEIiwKICAgICAgICAgICAgICAgICAgImNvbG9yIjogImdyZWVu
IiwKICAgICAgICAgICAgICAgICAgImluZGV4IjogMgogICAgICAgICAgICAgICAgfQogICAgICAg
ICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJ0aHJlc2hvbGRz
IjogewogICAgICAgICAgICAibW9kZSI6ICJhYnNvbHV0ZSIsCiAgICAgICAgICAgICJzdGVwcyI6
IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29sb3IiOiAidGV4dCIsCiAgICAg
ICAgICAgICAgICAidmFsdWUiOiBudWxsCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAg
ICAgICAgICB9LAogICAgICAgICAgInVuaXQiOiAic2hvcnQiLAogICAgICAgICAgImRlY2ltYWxz
IjogMAogICAgICAgIH0sCiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAgICAgICJn
cmlkUG9zIjogewogICAgICAgICJoIjogNCwKICAgICAgICAidyI6IDQsCiAgICAgICAgIngiOiA0
LAogICAgICAgICJ5IjogMQogICAgICB9LAogICAgICAiaWQiOiAyLAogICAgICAib3B0aW9ucyI6
IHsKICAgICAgICAiY29sb3JNb2RlIjogImJhY2tncm91bmQiLAogICAgICAgICJncmFwaE1vZGUi
OiAibm9uZSIsCiAgICAgICAgInJlZHVjZU9wdGlvbnMiOiB7CiAgICAgICAgICAiY2FsY3MiOiBb
CiAgICAgICAgICAgICJsYXN0Tm90TnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAiZmllbGRz
IjogIiIsCiAgICAgICAgICAidmFsdWVzIjogZmFsc2UKICAgICAgICB9LAogICAgICAgICJ0ZXh0
TW9kZSI6ICJ2YWx1ZSIKICAgICAgfSwKICAgICAgInRhcmdldHMiOiBbCiAgICAgICAgewogICAg
ICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAog
ICAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgICAgICB9LAogICAgICAg
ICAgImV4cHIiOiAiY2xhbXBfbWluKChjbGFtcF9taW4oKHN1bShhenRlY192YWxpZGF0b3JfYXR0
ZXN0YXRpb25fc3VjY2Vzc19jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIG9yIHZlY3Rv
cigwKSkgLSAoc3VtKGF6dGVjX3ZhbGlkYXRvcl9hdHRlc3RhdGlvbl9zdWNjZXNzX2NvdW50e2lu
c3RhbmNlPX5cIiRpbnN0YW5jZVwifSBvZmZzZXQgMWgpIG9yIHZlY3RvcigwKSksIDApID4gYm9v
bCAwKSAtIDIqKGNsYW1wX21pbigoc3VtKGF6dGVjX3ZhbGlkYXRvcl9hdHRlc3RhdGlvbl9mYWls
ZWRfbm9kZV9pc3N1ZV9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIiwgYXp0ZWNfaXNfY29t
bWl0dGVlX21lbWJlcj1cInRydWVcIiwgYXp0ZWNfZXJyb3JfdHlwZSE9XCJibG9ja19udW1iZXJf
YWxyZWFkeV9leGlzdHNcIn0pIG9yIHZlY3RvcigwKSkgLSAoc3VtKGF6dGVjX3ZhbGlkYXRvcl9h
dHRlc3RhdGlvbl9mYWlsZWRfbm9kZV9pc3N1ZV9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2Vc
IiwgYXp0ZWNfaXNfY29tbWl0dGVlX21lbWJlcj1cInRydWVcIiwgYXp0ZWNfZXJyb3JfdHlwZSE9
XCJibG9ja19udW1iZXJfYWxyZWFkeV9leGlzdHNcIn0gb2Zmc2V0IDFoKSBvciB2ZWN0b3IoMCkp
LCAwKSA+IGJvb2wgMCksIC0xKSIsCiAgICAgICAgICAicmVmSWQiOiAiQSIKICAgICAgICB9CiAg
ICAgIF0sCiAgICAgICJ0aXRsZSI6ICJBdHRlc3RpbmcgKGxhc3QgMWgpIiwKICAgICAgInR5cGUi
OiAic3RhdCIKICAgIH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBl
IjogInByb21ldGhldXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAg
fSwKICAgICAgImRlc2NyaXB0aW9uIjogIkdlbnVpbmUgbWlzc2VkIGF0dGVzdGF0aW9ucyBpbiB0
aGUgTEFTVCAyNCBIT1VSUyAocm9sbGluZyB3aW5kb3cpOiBjb21taXR0ZWUgc2xvdHMgdGhhdCBm
YWlsZWQgZm9yIGEgbm9kZS1zaWRlIHJlYXNvbiwgZXhjbHVkaW5nIGJlbmlnbiByYWNlcyBhbmQg
Y29ycmVjdCByZWplY3Rpb25zIG9mIGludmFsaWQgcHJvcG9zYWxzLiBUaGlzIGNhbiByZWFkIDAg
d2hpbGUgdGhlIGxpZmV0aW1lIHRvdGFscyBpbiB0aGUgRHV0aWVzIHJvdyBhcmUgbm9uLXplcm8g
XHUyMDE0IHRoYXQgbWVhbnMgcGFzdCBmYWlsdXJlcywgbm9uZSByZWNlbnQuIDAgaXMgaGVhbHRo
eS4iLAogICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAg
ICAgImNvbG9yIjogewogICAgICAgICAgICAibW9kZSI6ICJ0aHJlc2hvbGRzIgogICAgICAgICAg
fSwKICAgICAgICAgICJ0aHJlc2hvbGRzIjogewogICAgICAgICAgICAibW9kZSI6ICJhYnNvbHV0
ZSIsCiAgICAgICAgICAgICJzdGVwcyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAg
ICAiY29sb3IiOiAiZ3JlZW4iLAogICAgICAgICAgICAgICAgInZhbHVlIjogbnVsbAogICAgICAg
ICAgICAgIH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImNvbG9yIjogInllbGxv
dyIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiAxCiAgICAgICAgICAgICAgfSwKICAgICAgICAg
ICAgICB7CiAgICAgICAgICAgICAgICAiY29sb3IiOiAicmVkIiwKICAgICAgICAgICAgICAgICJ2
YWx1ZSI6IDUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0KICAgICAgICAgIH0sCiAgICAg
ICAgICAidW5pdCI6ICJzaG9ydCIsCiAgICAgICAgICAiZGVjaW1hbHMiOiAwCiAgICAgICAgfSwK
ICAgICAgICAib3ZlcnJpZGVzIjogW10KICAgICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAg
ICAgImgiOiA0LAogICAgICAgICJ3IjogNCwKICAgICAgICAieCI6IDgsCiAgICAgICAgInkiOiAx
CiAgICAgIH0sCiAgICAgICJpZCI6IDMsCiAgICAgICJvcHRpb25zIjogewogICAgICAgICJjb2xv
ck1vZGUiOiAiYmFja2dyb3VuZCIsCiAgICAgICAgImdyYXBoTW9kZSI6ICJub25lIiwKICAgICAg
ICAicmVkdWNlT3B0aW9ucyI6IHsKICAgICAgICAgICJjYWxjcyI6IFsKICAgICAgICAgICAgImxh
c3ROb3ROdWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJmaWVsZHMiOiAiIiwKICAgICAgICAg
ICJ2YWx1ZXMiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgInRleHRNb2RlIjogInZhbHVlIgog
ICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0YXNvdXJj
ZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1aWQi
OiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJyb3Vu
ZChjbGFtcF9taW4oc3VtKGF6dGVjX3ZhbGlkYXRvcl9hdHRlc3RhdGlvbl9mYWlsZWRfbm9kZV9p
c3N1ZV9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIiwgYXp0ZWNfaXNfY29tbWl0dGVlX21l
bWJlcj1cInRydWVcIiwgYXp0ZWNfZXJyb3JfdHlwZSE9XCJibG9ja19udW1iZXJfYWxyZWFkeV9l
eGlzdHNcIn0pIC0gc3VtKGF6dGVjX3ZhbGlkYXRvcl9hdHRlc3RhdGlvbl9mYWlsZWRfbm9kZV9p
c3N1ZV9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIiwgYXp0ZWNfaXNfY29tbWl0dGVlX21l
bWJlcj1cInRydWVcIiwgYXp0ZWNfZXJyb3JfdHlwZSE9XCJibG9ja19udW1iZXJfYWxyZWFkeV9l
eGlzdHNcIn0gb2Zmc2V0IDI0aCksIDApKSBvciByb3VuZChzdW0oYXp0ZWNfdmFsaWRhdG9yX2F0
dGVzdGF0aW9uX2ZhaWxlZF9ub2RlX2lzc3VlX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwi
LCBhenRlY19pc19jb21taXR0ZWVfbWVtYmVyPVwidHJ1ZVwiLCBhenRlY19lcnJvcl90eXBlIT1c
ImJsb2NrX251bWJlcl9hbHJlYWR5X2V4aXN0c1wifSkpIiwKICAgICAgICAgICJyZWZJZCI6ICJB
IgogICAgICAgIH0KICAgICAgXSwKICAgICAgInRpdGxlIjogIkZhaWxlZCBhdHRlc3RhdGlvbnMg
KDI0aCkiLAogICAgICAidHlwZSI6ICJzdGF0IgogICAgfSwKICAgIHsKICAgICAgImRhdGFzb3Vy
Y2UiOiB7CiAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIke0RT
X1BST01FVEhFVVN9IgogICAgICB9LAogICAgICAiZGVzY3JpcHRpb24iOiAiR2VudWluZSBwcm9w
b3NhbCBmYXVsdHMgaW4gdGhlIExBU1QgMjQgSE9VUlMgKHJvbGxpbmcgd2luZG93KTogY2hlY2tw
b2ludCBwcm9wb3NhbCBmYWlsdXJlcyBwbHVzIGJsb2NrIGJ1aWxkIGZhaWx1cmVzLCBleGNsdWRp
bmcgc2xvdHMgc2tpcHBlZCBmb3IgdG9vIGZldyB2YWxpZCB0cmFuc2FjdGlvbnMuIFRoaXMgY2Fu
IHJlYWQgMCB3aGlsZSB0aGUgbGlmZXRpbWUgdG90YWxzIGluIHRoZSBEdXRpZXMgcm93IGFyZSBu
b24temVybyBcdTIwMTQgdGhhdCBtZWFucyBwYXN0IGZhaWx1cmVzLCBub25lIHJlY2VudC4gMCBp
cyBoZWFsdGh5LiIsCiAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7
CiAgICAgICAgICAiY29sb3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInRocmVzaG9sZHMiCiAg
ICAgICAgICB9LAogICAgICAgICAgInRocmVzaG9sZHMiOiB7CiAgICAgICAgICAgICJtb2RlIjog
ImFic29sdXRlIiwKICAgICAgICAgICAgInN0ZXBzIjogWwogICAgICAgICAgICAgIHsKICAgICAg
ICAgICAgICAgICJjb2xvciI6ICJncmVlbiIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiBudWxs
CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29sb3Ii
OiAieWVsbG93IiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6IDEKICAgICAgICAgICAgICB9LAog
ICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb2xvciI6ICJyZWQiLAogICAgICAgICAg
ICAgICAgInZhbHVlIjogMwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgXQogICAgICAgICAg
fSwKICAgICAgICAgICJ1bml0IjogInNob3J0IiwKICAgICAgICAgICJkZWNpbWFscyI6IDAKICAg
ICAgICB9LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3JpZFBvcyI6
IHsKICAgICAgICAiaCI6IDQsCiAgICAgICAgInciOiA0LAogICAgICAgICJ4IjogMTIsCiAgICAg
ICAgInkiOiAxCiAgICAgIH0sCiAgICAgICJpZCI6IDQsCiAgICAgICJvcHRpb25zIjogewogICAg
ICAgICJjb2xvck1vZGUiOiAiYmFja2dyb3VuZCIsCiAgICAgICAgImdyYXBoTW9kZSI6ICJub25l
IiwKICAgICAgICAicmVkdWNlT3B0aW9ucyI6IHsKICAgICAgICAgICJjYWxjcyI6IFsKICAgICAg
ICAgICAgImxhc3ROb3ROdWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJmaWVsZHMiOiAiIiwK
ICAgICAgICAgICJ2YWx1ZXMiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgInRleHRNb2RlIjog
InZhbHVlIgogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAi
ZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAg
ICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhw
ciI6ICJyb3VuZChjbGFtcF9taW4oKHN1bShhenRlY19zZXF1ZW5jZXJfY2hlY2twb2ludF9wcm9w
b3NhbF9mYWlsZWRfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSArIHN1bShhenRlY19z
ZXF1ZW5jZXJfYmxvY2tfcHJvcG9zYWxfZmFpbGVkX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0YW5j
ZVwiLCBhenRlY19lcnJvcl90eXBlIX5cImluc3VmZmljaWVudF90eHN8aW5zdWZmaWNpZW50X3Zh
bGlkX3R4c1wifSkpIC0gKHN1bShhenRlY19zZXF1ZW5jZXJfY2hlY2twb2ludF9wcm9wb3NhbF9m
YWlsZWRfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9IG9mZnNldCAyNGgpICsgc3VtKGF6
dGVjX3NlcXVlbmNlcl9ibG9ja19wcm9wb3NhbF9mYWlsZWRfY291bnR7aW5zdGFuY2U9flwiJGlu
c3RhbmNlXCIsIGF6dGVjX2Vycm9yX3R5cGUhflwiaW5zdWZmaWNpZW50X3R4c3xpbnN1ZmZpY2ll
bnRfdmFsaWRfdHhzXCJ9IG9mZnNldCAyNGgpKSwgMCkpIG9yIHJvdW5kKHN1bShhenRlY19zZXF1
ZW5jZXJfY2hlY2twb2ludF9wcm9wb3NhbF9mYWlsZWRfY291bnR7aW5zdGFuY2U9flwiJGluc3Rh
bmNlXCJ9KSArIHN1bShhenRlY19zZXF1ZW5jZXJfYmxvY2tfcHJvcG9zYWxfZmFpbGVkX2NvdW50
e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwiLCBhenRlY19lcnJvcl90eXBlIX5cImluc3VmZmljaWVu
dF90eHN8aW5zdWZmaWNpZW50X3ZhbGlkX3R4c1wifSkpIiwKICAgICAgICAgICJyZWZJZCI6ICJB
IgogICAgICAgIH0KICAgICAgXSwKICAgICAgInRpdGxlIjogIkZhaWxlZCBwcm9wb3NhbHMgKDI0
aCkiLAogICAgICAidHlwZSI6ICJzdGF0IgogICAgfSwKICAgIHsKICAgICAgImRhdGFzb3VyY2Ui
OiB7CiAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIke0RTX1BS
T01FVEhFVVN9IgogICAgICB9LAogICAgICAiZGVzY3JpcHRpb24iOiAiRmFpbGVkIGJsb2NrIHJl
LWV4ZWN1dGlvbnMgaW4gdGhlIGxhc3QgMjQgaG91cnMuIEluIFY1IGV2ZXJ5IG5vZGUgcmUtZXhl
Y3V0ZXMgYmxvY2tzOyAwIGlzIGhlYWx0aHkuIiwKICAgICAgImZpZWxkQ29uZmlnIjogewogICAg
ICAgICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAgIm1vZGUi
OiAidGhyZXNob2xkcyIKICAgICAgICAgIH0sCiAgICAgICAgICAidGhyZXNob2xkcyI6IHsKICAg
ICAgICAgICAgIm1vZGUiOiAiYWJzb2x1dGUiLAogICAgICAgICAgICAic3RlcHMiOiBbCiAgICAg
ICAgICAgICAgewogICAgICAgICAgICAgICAgImNvbG9yIjogImdyZWVuIiwKICAgICAgICAgICAg
ICAgICJ2YWx1ZSI6IG51bGwKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAg
ICAgICAgICAgICJjb2xvciI6ICJyZWQiLAogICAgICAgICAgICAgICAgInZhbHVlIjogMQogICAg
ICAgICAgICAgIH0KICAgICAgICAgICAgXQogICAgICAgICAgfSwKICAgICAgICAgICJ1bml0Ijog
InNob3J0IiwKICAgICAgICAgICJkZWNpbWFscyI6IDAKICAgICAgICB9LAogICAgICAgICJvdmVy
cmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3JpZFBvcyI6IHsKICAgICAgICAiaCI6IDQsCiAg
ICAgICAgInciOiA0LAogICAgICAgICJ4IjogMTYsCiAgICAgICAgInkiOiAxCiAgICAgIH0sCiAg
ICAgICJpZCI6IDUsCiAgICAgICJvcHRpb25zIjogewogICAgICAgICJjb2xvck1vZGUiOiAiYmFj
a2dyb3VuZCIsCiAgICAgICAgImdyYXBoTW9kZSI6ICJub25lIiwKICAgICAgICAicmVkdWNlT3B0
aW9ucyI6IHsKICAgICAgICAgICJjYWxjcyI6IFsKICAgICAgICAgICAgImxhc3ROb3ROdWxsIgog
ICAgICAgICAgXSwKICAgICAgICAgICJmaWVsZHMiOiAiIiwKICAgICAgICAgICJ2YWx1ZXMiOiBm
YWxzZQogICAgICAgIH0sCiAgICAgICAgInRleHRNb2RlIjogInZhbHVlIgogICAgICB9LAogICAg
ICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAg
ICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9N
RVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJyb3VuZChjbGFtcF9taW4o
c3VtKGF6dGVjX3ZhbGlkYXRvcl9mYWlsZWRfcmVleGVjdXRpb25fY291bnR7aW5zdGFuY2U9flwi
JGluc3RhbmNlXCJ9KSAtIHN1bShhenRlY192YWxpZGF0b3JfZmFpbGVkX3JlZXhlY3V0aW9uX2Nv
dW50e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwifSBvZmZzZXQgMjRoKSwgMCkpIG9yIHJvdW5kKHN1
bShhenRlY192YWxpZGF0b3JfZmFpbGVkX3JlZXhlY3V0aW9uX2NvdW50e2luc3RhbmNlPX5cIiRp
bnN0YW5jZVwifSkpIiwKICAgICAgICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0KICAgICAgXSwK
ICAgICAgInRpdGxlIjogIkZhaWxlZCByZS1leGVjdXRpb25zICgyNGgpIiwKICAgICAgInR5cGUi
OiAic3RhdCIKICAgIH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBl
IjogInByb21ldGhldXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAg
fSwKICAgICAgImRlc2NyaXB0aW9uIjogIkdhcCBiZXR3ZWVuIHRoZSBub2RlJ3MgY2hhaW4gdGlw
IGFuZCB0aGUgcHJvdmVuIHRpcC4gTmVhciAwIG1lYW5zIHN5bmNlZC4iLAogICAgICAiZmllbGRD
b25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewogICAg
ICAgICAgICAibW9kZSI6ICJ0aHJlc2hvbGRzIgogICAgICAgICAgfSwKICAgICAgICAgICJ0aHJl
c2hvbGRzIjogewogICAgICAgICAgICAibW9kZSI6ICJhYnNvbHV0ZSIsCiAgICAgICAgICAgICJz
dGVwcyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29sb3IiOiAiZ3JlZW4i
LAogICAgICAgICAgICAgICAgInZhbHVlIjogbnVsbAogICAgICAgICAgICAgIH0sCiAgICAgICAg
ICAgICAgewogICAgICAgICAgICAgICAgImNvbG9yIjogInllbGxvdyIsCiAgICAgICAgICAgICAg
ICAidmFsdWUiOiA1CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAg
ICAgICAiY29sb3IiOiAicmVkIiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6IDIwCiAgICAgICAg
ICAgICAgfQogICAgICAgICAgICBdCiAgICAgICAgICB9LAogICAgICAgICAgInVuaXQiOiAibm9u
ZSIKICAgICAgICB9LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3Jp
ZFBvcyI6IHsKICAgICAgICAiaCI6IDQsCiAgICAgICAgInciOiA0LAogICAgICAgICJ4IjogMjAs
CiAgICAgICAgInkiOiAxCiAgICAgIH0sCiAgICAgICJpZCI6IDYsCiAgICAgICJvcHRpb25zIjog
ewogICAgICAgICJjb2xvck1vZGUiOiAiYmFja2dyb3VuZCIsCiAgICAgICAgImdyYXBoTW9kZSI6
ICJub25lIiwKICAgICAgICAicmVkdWNlT3B0aW9ucyI6IHsKICAgICAgICAgICJjYWxjcyI6IFsK
ICAgICAgICAgICAgImxhc3ROb3ROdWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJmaWVsZHMi
OiAiIiwKICAgICAgICAgICJ2YWx1ZXMiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgInRleHRN
b2RlIjogInZhbHVlIgogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAg
ICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAg
ICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAg
ICAiZXhwciI6ICJtYXgoYXp0ZWNfYXJjaGl2ZXJfYmxvY2tfaGVpZ2h0e2luc3RhbmNlPX5cIiRp
bnN0YW5jZVwiLCBhenRlY19zdGF0dXM9XCJwcm9wb3NlZFwifSkgLSBtYXgoYXp0ZWNfYXJjaGl2
ZXJfYmxvY2tfaGVpZ2h0e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwiLCBhenRlY19zdGF0dXM9XCJj
aGVja3BvaW50ZWRcIn0pIiwKICAgICAgICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0KICAgICAg
XSwKICAgICAgInRpdGxlIjogIlN5bmMgZ2FwIChibG9ja3MpIiwKICAgICAgInR5cGUiOiAic3Rh
dCIKICAgIH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInBy
b21ldGhldXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAg
ICAgImlkIjogMTA3LAogICAgICAidHlwZSI6ICJzdGF0IiwKICAgICAgInRpdGxlIjogIkN1cnJl
bnQgZXBvY2giLAogICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIGN1cnJlbnQgZXBvY2ggbnVtYmVy
IChpbmZvcm1hdGlvbmFsKS4iLAogICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1
bHRzIjogewogICAgICAgICAgImNvbG9yIjogewogICAgICAgICAgICAibW9kZSI6ICJ0aHJlc2hv
bGRzIgogICAgICAgICAgfSwKICAgICAgICAgICJ0aHJlc2hvbGRzIjogewogICAgICAgICAgICAi
bW9kZSI6ICJhYnNvbHV0ZSIsCiAgICAgICAgICAgICJzdGVwcyI6IFsKICAgICAgICAgICAgICB7
CiAgICAgICAgICAgICAgICAiY29sb3IiOiAidGV4dCIsCiAgICAgICAgICAgICAgICAidmFsdWUi
OiBudWxsCiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAgICAgICAgICB9LAogICAgICAg
ICAgInVuaXQiOiAibm9uZSIsCiAgICAgICAgICAiZGVjaW1hbHMiOiAwCiAgICAgICAgfSwKICAg
ICAgICAib3ZlcnJpZGVzIjogW10KICAgICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAg
ImgiOiA0LAogICAgICAgICJ3IjogNiwKICAgICAgICAieCI6IDAsCiAgICAgICAgInkiOiA1CiAg
ICAgIH0sCiAgICAgICJvcHRpb25zIjogewogICAgICAgICJjb2xvck1vZGUiOiAibm9uZSIsCiAg
ICAgICAgImdyYXBoTW9kZSI6ICJub25lIiwKICAgICAgICAicmVkdWNlT3B0aW9ucyI6IHsKICAg
ICAgICAgICJjYWxjcyI6IFsKICAgICAgICAgICAgImxhc3ROb3ROdWxsIgogICAgICAgICAgXSwK
ICAgICAgICAgICJmaWVsZHMiOiAiIiwKICAgICAgICAgICJ2YWx1ZXMiOiBmYWxzZQogICAgICAg
IH0sCiAgICAgICAgInRleHRNb2RlIjogInZhbHVlIgogICAgICB9LAogICAgICAidGFyZ2V0cyI6
IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUi
OiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAg
ICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJtYXgoYXp0ZWNfdmFsaWRhdG9yX2N1cnJlbnRf
ZXBvY2h7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSIsCiAgICAgICAgICAicmVmSWQiOiAiQSIK
ICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAg
ICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVT
fSIKICAgICAgfSwKICAgICAgImlkIjogMTEyLAogICAgICAidHlwZSI6ICJ0YWJsZSIsCiAgICAg
ICJ0aXRsZSI6ICJOb2RlIGluZm8iLAogICAgICAiZGVzY3JpcHRpb24iOiAiTm9kZSBpZGVudGl0
eSBhbmQgdmVyc2lvbiByZXBvcnRlZCBieSB0aGUgbm9kZSAoZnJvbSB0YXJnZXRfaW5mbykuIiwK
ICAgICAgImZpZWxkQ29uZmlnIjogewogICAgICAgICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJj
dXN0b20iOiB7CiAgICAgICAgICAgICJhbGlnbiI6ICJhdXRvIiwKICAgICAgICAgICAgImZpbHRl
cmFibGUiOiBmYWxzZQogICAgICAgICAgfSwKICAgICAgICAgICJtYXBwaW5ncyI6IFtdLAogICAg
ICAgICAgInRocmVzaG9sZHMiOiB7CiAgICAgICAgICAgICJtb2RlIjogImFic29sdXRlIiwKICAg
ICAgICAgICAgInN0ZXBzIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJjb2xv
ciI6ICJncmVlbiIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiBudWxsCiAgICAgICAgICAgICAg
fQogICAgICAgICAgICBdCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVz
IjogW10KICAgICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiA0LAogICAgICAg
ICJ3IjogMTIsCiAgICAgICAgIngiOiA2LAogICAgICAgICJ5IjogNQogICAgICB9LAogICAgICAi
b3B0aW9ucyI6IHsKICAgICAgICAic2hvd0hlYWRlciI6IHRydWUsCiAgICAgICAgImNlbGxIZWln
aHQiOiAic20iLAogICAgICAgICJmb290ZXIiOiB7CiAgICAgICAgICAic2hvdyI6IGZhbHNlCiAg
ICAgICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAi
ZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAg
ICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhw
ciI6ICJ0YXJnZXRfaW5mb3tpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0iLAogICAgICAgICAgImZv
cm1hdCI6ICJ0YWJsZSIsCiAgICAgICAgICAiaW5zdGFudCI6IHRydWUsCiAgICAgICAgICAicmVm
SWQiOiAiQSIKICAgICAgICB9CiAgICAgIF0sCiAgICAgICJ0cmFuc2Zvcm1hdGlvbnMiOiBbCiAg
ICAgICAgewogICAgICAgICAgImlkIjogIm9yZ2FuaXplIiwKICAgICAgICAgICJvcHRpb25zIjog
ewogICAgICAgICAgICAiZXhjbHVkZUJ5TmFtZSI6IHsKICAgICAgICAgICAgICAiVGltZSI6IHRy
dWUsCiAgICAgICAgICAgICAgIlZhbHVlIjogdHJ1ZSwKICAgICAgICAgICAgICAiX19uYW1lX18i
OiB0cnVlLAogICAgICAgICAgICAgICJqb2IiOiB0cnVlLAogICAgICAgICAgICAgICJpbnN0YW5j
ZSI6IHRydWUsCiAgICAgICAgICAgICAgImF6dGVjX3JlZ2lzdHJ5X2FkZHJlc3MiOiB0cnVlLAog
ICAgICAgICAgICAgICJhenRlY19yb2xsdXBfYWRkcmVzcyI6IHRydWUsCiAgICAgICAgICAgICAg
ImF6dGVjX3JvbGx1cF92ZXJzaW9uIjogdHJ1ZSwKICAgICAgICAgICAgICAib3NfdHlwZSI6IHRy
dWUsCiAgICAgICAgICAgICAgInRlbGVtZXRyeV9zZGtfbGFuZ3VhZ2UiOiB0cnVlLAogICAgICAg
ICAgICAgICJ0ZWxlbWV0cnlfc2RrX25hbWUiOiB0cnVlLAogICAgICAgICAgICAgICJ0ZWxlbWV0
cnlfc2RrX3ZlcnNpb24iOiB0cnVlLAogICAgICAgICAgICAgICJvdGVsX3Njb3BlX25hbWUiOiB0
cnVlLAogICAgICAgICAgICAgICJvdGVsX3Njb3BlX3ZlcnNpb24iOiB0cnVlLAogICAgICAgICAg
ICAgICJvdGVsX3Njb3BlX3NjaGVtYV91cmwiOiB0cnVlLAogICAgICAgICAgICAgICJleHBvcnRl
ZF9pbnN0YW5jZSI6IHRydWUsCiAgICAgICAgICAgICAgImV4cG9ydGVkX2pvYiI6IHRydWUsCiAg
ICAgICAgICAgICAgIm5ldHdvcmsiOiB0cnVlLAogICAgICAgICAgICAgICJub2RlX3JvbGUiOiB0
cnVlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJyZW5hbWVCeU5hbWUiOiB7CiAgICAgICAg
ICAgICAgInNlcnZpY2VfdmVyc2lvbiI6ICJWZXJzaW9uIiwKICAgICAgICAgICAgICAiYXp0ZWNf
bm9kZV9yb2xlIjogIlJvbGUiLAogICAgICAgICAgICAgICJvc192ZXJzaW9uIjogIk9TIgogICAg
ICAgICAgICB9LAogICAgICAgICAgICAiaW5kZXhCeU5hbWUiOiB7CiAgICAgICAgICAgICAgInNl
cnZpY2VfdmVyc2lvbiI6IDAsCiAgICAgICAgICAgICAgImF6dGVjX25vZGVfcm9sZSI6IDEsCiAg
ICAgICAgICAgICAgIm9zX3ZlcnNpb24iOiAyCiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAg
ICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJjb2xsYXBzZWQiOiBmYWxzZSwKICAg
ICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiAxLAogICAgICAgICJ3IjogMjQsCiAgICAgICAg
IngiOiAwLAogICAgICAgICJ5IjogOQogICAgICB9LAogICAgICAiaWQiOiAxMDEsCiAgICAgICJ0
aXRsZSI6ICJEdXRpZXMiLAogICAgICAidHlwZSI6ICJyb3ciLAogICAgICAicGFuZWxzIjogW10K
ICAgIH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21l
dGhldXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAg
ImRlc2NyaXB0aW9uIjogIlJ1bm5pbmcgdG90YWxzIG9mIHN1Y2Nlc3NmdWwgdnMgZmFpbGVkIGF0
dGVzdGF0aW9ucywgY3VtdWxhdGl2ZSBzaW5jZSBub2RlIHN0YXJ0IChub3QgYSAyNC1ob3VyIHdp
bmRvdykuIEJvdGggbGluZXMgc2hvdWxkIGNsaW1iOyB0aGUgZmFpbGVkIGxpbmUgc2hvdWxkIHN0
YXkgZmxhdC4iLAogICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewog
ICAgICAgICAgImNvbG9yIjogewogICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMi
CiAgICAgICAgICB9LAogICAgICAgICAgImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHls
ZSI6ICJsaW5lIiwKICAgICAgICAgICAgImxpbmVXaWR0aCI6IDIsCiAgICAgICAgICAgICJmaWxs
T3BhY2l0eSI6IDUKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJzaG9ydCIsCiAgICAg
ICAgICAiZGVjaW1hbHMiOiAwCiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVzIjogW10KICAg
ICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiA4LAogICAgICAgICJ3IjogMTIs
CiAgICAgICAgIngiOiAwLAogICAgICAgICJ5IjogMTAKICAgICAgfSwKICAgICAgImlkIjogNywK
ICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5
TW9kZSI6ICJsaXN0IiwKICAgICAgICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAg
ICJzaG93TGVnZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAg
ICAgICAibW9kZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjog
WwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6
ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAg
ICAgICAgfSwKICAgICAgICAgICJleHByIjogInN1bShhenRlY192YWxpZGF0b3JfYXR0ZXN0YXRp
b25fc3VjY2Vzc19jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIiwKICAgICAgICAgICJs
ZWdlbmRGb3JtYXQiOiAic3VjY2Vzc2Z1bCAodG90YWwpIiwKICAgICAgICAgICJyZWZJZCI6ICJB
IgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAg
ICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVU
SEVVU30iCiAgICAgICAgICB9LAogICAgICAgICAgImV4cHIiOiAic3VtKGF6dGVjX3ZhbGlkYXRv
cl9hdHRlc3RhdGlvbl9mYWlsZWRfbm9kZV9pc3N1ZV9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFu
Y2VcIiwgYXp0ZWNfaXNfY29tbWl0dGVlX21lbWJlcj1cInRydWVcIiwgYXp0ZWNfZXJyb3JfdHlw
ZSE9XCJibG9ja19udW1iZXJfYWxyZWFkeV9leGlzdHNcIn0pIiwKICAgICAgICAgICJsZWdlbmRG
b3JtYXQiOiAiZmFpbGVkICh0b3RhbCkiLAogICAgICAgICAgInJlZklkIjogIkIiCiAgICAgICAg
fQogICAgICBdLAogICAgICAidGl0bGUiOiAiQXR0ZXN0YXRpb25zOiBzdWNjZXNzZnVsIHZzIGZh
aWxlZCIsCiAgICAgICJ0eXBlIjogInRpbWVzZXJpZXMiCiAgICB9LAogICAgewogICAgICAiZGF0
YXNvdXJjZSI6IHsKICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAidWlkIjog
IiR7RFNfUFJPTUVUSEVVU30iCiAgICAgIH0sCiAgICAgICJkZXNjcmlwdGlvbiI6ICJDdW11bGF0
aXZlIGNvdW50IG9mIGZhaWxlZCBhdHRlc3RhdGlvbnMgYnkgcmVhc29uIChjb21taXR0ZWUgc2xv
dHMpLCBzaW5jZSBub2RlIHN0YXJ0IChub3QgYSAyNC1ob3VyIHdpbmRvdykuIGJsb2NrX251bWJl
cl9hbHJlYWR5X2V4aXN0cyBpcyBhIGJlbmlnbiBpbnRlcm5hbCByYWNlIGFuZCBpcyBub3QgY291
bnRlZCBhcyBhIG1pc3NlZCBhdHRlc3RhdGlvbiBpbiB0aGUgaGVhZGxpbmUgc3RhdC4gQSBub24t
emVybyB0b3RhbCBjYW4gYmUgaGlzdG9yaWNhbDsgY2hlY2sgdGhlIDI0LWhvdXIgJ0ZhaWxlZCBh
dHRlc3RhdGlvbnMnIGhlYWRsaW5lIHN0YXQgZm9yIHJlY2VudCBmYWlsdXJlcy4iLAogICAgICAi
ZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjog
ewogICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAg
ICAgICAgImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAg
ICAgICAgImxpbmVXaWR0aCI6IDIsCiAgICAgICAgICAgICJmaWxsT3BhY2l0eSI6IDUKICAgICAg
ICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJzaG9ydCIsCiAgICAgICAgICAiZGVjaW1hbHMiOiAw
CiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVzIjogW10KICAgICAgfSwKICAgICAgImdyaWRQ
b3MiOiB7CiAgICAgICAgImgiOiA4LAogICAgICAgICJ3IjogMTIsCiAgICAgICAgIngiOiAxMiwK
ICAgICAgICAieSI6IDEwCiAgICAgIH0sCiAgICAgICJpZCI6IDgsCiAgICAgICJvcHRpb25zIjog
ewogICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlzdCIsCiAg
ICAgICAgICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAic2hvd0xlZ2VuZCI6IHRy
dWUKICAgICAgICB9LAogICAgICAgICJ0b29sdGlwIjogewogICAgICAgICAgIm1vZGUiOiAibXVs
dGkiCiAgICAgICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAg
ICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAg
ICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAg
ICAiZXhwciI6ICJzdW0gYnkgKGF6dGVjX2Vycm9yX3R5cGUpIChhenRlY192YWxpZGF0b3JfYXR0
ZXN0YXRpb25fZmFpbGVkX25vZGVfaXNzdWVfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCIs
IGF6dGVjX2lzX2NvbW1pdHRlZV9tZW1iZXI9XCJ0cnVlXCIsIGF6dGVjX2Vycm9yX3R5cGUhPVwi
XCIsIGF6dGVjX2Vycm9yX3R5cGUhPVwiYmxvY2tfbnVtYmVyX2FscmVhZHlfZXhpc3RzXCJ9KSIs
CiAgICAgICAgICAibGVnZW5kRm9ybWF0IjogInt7YXp0ZWNfZXJyb3JfdHlwZX19IiwKICAgICAg
ICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0KICAgICAgXSwKICAgICAgInRpdGxlIjogIkZhaWxl
ZCBhdHRlc3RhdGlvbnMgYnkgcmVhc29uIiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAg
IH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhl
dXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImRl
c2NyaXB0aW9uIjogIkJsb2NrcyB0aGlzIG5vZGUgYnVpbHQsIGJ5IHN0YXR1cywgYXMgY3VtdWxh
dGl2ZSB0b3RhbHMgc2luY2Ugbm9kZSBzdGFydCAobm90IGEgMjQtaG91ciB3aW5kb3cpLiBJbiBW
NSB0aGUgbm9kZSBidWlsZHMgYmxvY2tzLCB0aGVuIHBhY2tzIHRoZW0gaW50byBhIGNoZWNrcG9p
bnQgdGhhdCBpcyBwcm9wb3NlZCB0byBMMS4iLAogICAgICAiZmllbGRDb25maWciOiB7CiAgICAg
ICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewogICAgICAgICAgICAibW9kZSI6
ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAgICAgICAgImN1c3RvbSI6IHsKICAg
ICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAgICAgImxpbmVXaWR0aCI6IDIs
CiAgICAgICAgICAgICJmaWxsT3BhY2l0eSI6IDUKICAgICAgICAgIH0sCiAgICAgICAgICAidW5p
dCI6ICJzaG9ydCIsCiAgICAgICAgICAiZGVjaW1hbHMiOiAwCiAgICAgICAgfSwKICAgICAgICAi
b3ZlcnJpZGVzIjogW10KICAgICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiA4
LAogICAgICAgICJ3IjogMTIsCiAgICAgICAgIngiOiAwLAogICAgICAgICJ5IjogMTgKICAgICAg
fSwKICAgICAgImlkIjogOSwKICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgImxlZ2VuZCI6IHsK
ICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJsaXN0IiwKICAgICAgICAgICJwbGFjZW1lbnQiOiAi
Ym90dG9tIiwKICAgICAgICAgICJzaG93TGVnZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAg
InRvb2x0aXAiOiB7CiAgICAgICAgICAibW9kZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0s
CiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewog
ICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RT
X1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogInN1bSBieSAoYXp0
ZWNfc3RhdHVzKSAoYXp0ZWNfc2VxdWVuY2VyX2Jsb2NrX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0
YW5jZVwifSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJ7e2F6dGVjX3N0YXR1c319IiwK
ICAgICAgICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0KICAgICAgXSwKICAgICAgInRpdGxlIjog
IkJsb2NrcyBidWlsdCAodG90YWwpIiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAgIH0s
CiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhldXMi
LAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImRlc2Ny
aXB0aW9uIjogIkN1bXVsYXRpdmUgdG90YWxzIHNpbmNlIHRoZSBub2RlIHN0YXJ0ZWQgKG5vdCBh
IDI0LWhvdXIgd2luZG93KS4gUHJvcG9zZWQgPSBjaGVja3BvaW50cyB0aGlzIG5vZGUgc3VjY2Vz
c2Z1bGx5IGJyb2FkY2FzdDsgRmFpbGVkID0gcHJvcG9zYWwgYXR0ZW1wdHMgdGhhdCBmYWlsZWQg
KHNlZSB0aGUgYnktcmVhc29uIHBhbmVsKS4gV2hldGhlciBhIHByb3Bvc2VkIGNoZWNrcG9pbnQg
dWx0aW1hdGVseSBsYW5kcyAobWluZXMpIG9uIEwxIGlzIGNoYWluIHN0YXRlLCB0cmFja2VkIG9u
LWNoYWluIChzdGFraW5nIGRhc2hib2FyZCAvIGJsb2NrIGV4cGxvcmVyKSwgbm90IGluIG5vZGUg
bWV0cmljcy4iLAogICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewog
ICAgICAgICAgImNvbG9yIjogewogICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMi
CiAgICAgICAgICB9LAogICAgICAgICAgImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHls
ZSI6ICJsaW5lIiwKICAgICAgICAgICAgImxpbmVXaWR0aCI6IDIsCiAgICAgICAgICAgICJmaWxs
T3BhY2l0eSI6IDUKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJzaG9ydCIsCiAgICAg
ICAgICAiZGVjaW1hbHMiOiAwCiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVzIjogW10KICAg
ICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiA4LAogICAgICAgICJ3IjogMTIs
CiAgICAgICAgIngiOiAxMiwKICAgICAgICAieSI6IDE4CiAgICAgIH0sCiAgICAgICJpZCI6IDEw
LAogICAgICAib3B0aW9ucyI6IHsKICAgICAgICAibGVnZW5kIjogewogICAgICAgICAgImRpc3Bs
YXlNb2RlIjogImxpc3QiLAogICAgICAgICAgInBsYWNlbWVudCI6ICJib3R0b20iLAogICAgICAg
ICAgInNob3dMZWdlbmQiOiB0cnVlCiAgICAgICAgfSwKICAgICAgICAidG9vbHRpcCI6IHsKICAg
ICAgICAgICJtb2RlIjogIm11bHRpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInRhcmdldHMi
OiBbCiAgICAgICAgewogICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgICAgICJ0eXBl
IjogInByb21ldGhldXMiLAogICAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAg
ICAgICAgICB9LAogICAgICAgICAgImV4cHIiOiAic3VtKGF6dGVjX3NlcXVlbmNlcl9jaGVja3Bv
aW50X3Byb3Bvc2FsX3N1Y2Nlc3NfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSIsCiAg
ICAgICAgICAibGVnZW5kRm9ybWF0IjogInByb3Bvc2VkIChzdWNjZXNzKSIsCiAgICAgICAgICAi
cmVmSWQiOiAiQSIKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjog
ewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIk
e0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogInN1bShhenRl
Y19zZXF1ZW5jZXJfY2hlY2twb2ludF9wcm9wb3NhbF9mYWlsZWRfY291bnR7aW5zdGFuY2U9flwi
JGluc3RhbmNlXCJ9KSIsCiAgICAgICAgICAibGVnZW5kRm9ybWF0IjogImZhaWxlZCIsCiAgICAg
ICAgICAicmVmSWQiOiAiQiIKICAgICAgICB9CiAgICAgIF0sCiAgICAgICJ0aXRsZSI6ICJDaGVj
a3BvaW50IHByb3Bvc2FscyAodG90YWwpIiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAg
IH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhl
dXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImlk
IjogMTE1LAogICAgICAidHlwZSI6ICJ0aW1lc2VyaWVzIiwKICAgICAgInRpdGxlIjogIkNoZWNr
cG9pbnQgcHJvcG9zYWwgZmFpbHVyZXMgYnkgcmVhc29uIiwKICAgICAgImRlc2NyaXB0aW9uIjog
IkN1bXVsYXRpdmUgY291bnQgc2luY2Ugbm9kZSBzdGFydCwgYnJva2VuIGRvd24gYnkgcmVhc29u
IChmb3IgZXhhbXBsZSBoZWFkZXJfdmFsaWRhdGlvbl9mYWlsZWQpLiBBbGwgcmVhc29ucyBoZXJl
IGFyZSByZWFsIGZhdWx0cy4gQSBub24temVybyB0b3RhbCBjYW4gYmUgaGlzdG9yaWNhbDsgY2hl
Y2sgdGhlIHRpbWUgcmFuZ2Ugb3IgdGhlIDI0LWhvdXIgJ0ZhaWxlZCBwcm9wb3NhbHMnIGhlYWRs
aW5lIHN0YXQgdG8gc2VlIHdoZXRoZXIgZmFpbHVyZXMgYXJlIHJlY2VudC4iLAogICAgICAiZmll
bGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewog
ICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAgICAg
ICAgImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAg
ICAgImxpbmVXaWR0aCI6IDIKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJzaG9ydCIs
CiAgICAgICAgICAiZGVjaW1hbHMiOiAwCiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVzIjog
W10KICAgICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiA4LAogICAgICAgICJ3
IjogMjQsCiAgICAgICAgIngiOiAwLAogICAgICAgICJ5IjogMjYKICAgICAgfSwKICAgICAgIm9w
dGlvbnMiOiB7CiAgICAgICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJs
aXN0IiwKICAgICAgICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAgICJzaG93TGVn
ZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAgICAgICAibW9k
ZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjogWwogICAgICAg
IHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRo
ZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwK
ICAgICAgICAgICJleHByIjogInN1bSBieSAoYXp0ZWNfZXJyb3JfdHlwZSkgKGF6dGVjX3NlcXVl
bmNlcl9jaGVja3BvaW50X3Byb3Bvc2FsX2ZhaWxlZF9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFu
Y2VcIiwgYXp0ZWNfZXJyb3JfdHlwZSE9XCJcIn0pIiwKICAgICAgICAgICJsZWdlbmRGb3JtYXQi
OiAie3thenRlY19lcnJvcl90eXBlfX0iLAogICAgICAgICAgInJlZklkIjogIkEiCiAgICAgICAg
fQogICAgICBdCiAgICB9LAogICAgewogICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAidHlw
ZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAg
IH0sCiAgICAgICJpZCI6IDExMywKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIsCiAgICAgICJ0
aXRsZSI6ICJBdHRlc3RlZCBlcG9jaHMgcGVyIGF0dGVzdGVyIiwKICAgICAgImRlc2NyaXB0aW9u
IjogIkF0dGVzdGVkIGVwb2NocyBmb3IgZWFjaCBhdHRlc3RlciBrZXkgb24gdGhpcyBub2RlLiBF
YWNoIGtleSBpcyBhIHNlcGFyYXRlIGxpbmU7IGEgZmxhdCBvciBkZWNsaW5pbmcgbGluZSBtZWFu
cyB0aGF0IGtleSBpcyBtaXNzaW5nIGl0cyBkdXRpZXMgZXZlbiBpZiB0aGUgb3RoZXJzIGFyZSBm
aW5lLiBPbiBhIHNpbmdsZS1hdHRlc3RlciBub2RlIHRoaXMgc2hvd3Mgb25lIGxpbmUuIiwKICAg
ICAgImZpZWxkQ29uZmlnIjogewogICAgICAgICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJjb2xv
ciI6IHsKICAgICAgICAgICAgIm1vZGUiOiAicGFsZXR0ZS1jbGFzc2ljIgogICAgICAgICAgfSwK
ICAgICAgICAgICJjdXN0b20iOiB7CiAgICAgICAgICAgICJkcmF3U3R5bGUiOiAibGluZSIsCiAg
ICAgICAgICAgICJsaW5lV2lkdGgiOiAyCiAgICAgICAgICB9LAogICAgICAgICAgInVuaXQiOiAi
c2hvcnQiLAogICAgICAgICAgImRlY2ltYWxzIjogMAogICAgICAgIH0sCiAgICAgICAgIm92ZXJy
aWRlcyI6IFtdCiAgICAgIH0sCiAgICAgICJncmlkUG9zIjogewogICAgICAgICJoIjogOCwKICAg
ICAgICAidyI6IDEyLAogICAgICAgICJ4IjogMCwKICAgICAgICAieSI6IDM0CiAgICAgIH0sCiAg
ICAgICJvcHRpb25zIjogewogICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxheU1v
ZGUiOiAibGlzdCIsCiAgICAgICAgICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAi
c2hvd0xlZ2VuZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJ0b29sdGlwIjogewogICAgICAg
ICAgIm1vZGUiOiAibXVsdGkiCiAgICAgICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsK
ICAgICAgICB7CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAi
cHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAg
ICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJzdW0gYnkgKGF6dGVjX2F0dGVzdGVyX2FkZHJlc3Mp
IChhenRlY192YWxpZGF0b3JfYXR0ZXN0ZWRfZXBvY2hfY291bnR7aW5zdGFuY2U9flwiJGluc3Rh
bmNlXCIsIGF6dGVjX2F0dGVzdGVyX2FkZHJlc3M9flwiJGF0dGVzdGVyXCJ9KSIsCiAgICAgICAg
ICAibGVnZW5kRm9ybWF0IjogInt7YXp0ZWNfYXR0ZXN0ZXJfYWRkcmVzc319IiwKICAgICAgICAg
ICJyZWZJZCI6ICJBIgogICAgICAgIH0KICAgICAgXQogICAgfSwKICAgIHsKICAgICAgImRhdGFz
b3VyY2UiOiB7CiAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIk
e0RTX1BST01FVEhFVVN9IgogICAgICB9LAogICAgICAiaWQiOiAxMTQsCiAgICAgICJ0eXBlIjog
InRpbWVzZXJpZXMiLAogICAgICAidGl0bGUiOiAiQXR0ZXN0ZXIgcGFydGljaXBhdGlvbiByYXRl
IiwKICAgICAgImRlc2NyaXB0aW9uIjogIkVhY2ggYXR0ZXN0ZXIncyBhdHRlc3RlZC1lcG9jaCBj
b3VudCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBlcG9jaCwgYXMgYSBwZXJjZW50YWdlLiBBIGtl
eSB0cmVuZGluZyBiZWxvdyB0aGUgb3RoZXJzIGlzIHVuZGVyLXBhcnRpY2lwYXRpbmcuIE9uIGEg
c2luZ2xlLWF0dGVzdGVyIG5vZGUgdGhpcyBzaG93cyBvbmUgbGluZS4iLAogICAgICAiZmllbGRD
b25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewogICAg
ICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAgICAgICAg
ImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAgICAg
ImxpbmVXaWR0aCI6IDIKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJwZXJjZW50IiwK
ICAgICAgICAgICJkZWNpbWFscyI6IDEsCiAgICAgICAgICAibWF4IjogMTAwLAogICAgICAgICAg
Im1pbiI6IDAKICAgICAgICB9LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAg
ICAiZ3JpZFBvcyI6IHsKICAgICAgICAiaCI6IDgsCiAgICAgICAgInciOiAxMiwKICAgICAgICAi
eCI6IDEyLAogICAgICAgICJ5IjogMzQKICAgICAgfSwKICAgICAgIm9wdGlvbnMiOiB7CiAgICAg
ICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJsaXN0IiwKICAgICAgICAg
ICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAgICJzaG93TGVnZW5kIjogdHJ1ZQogICAg
ICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAgICAgICAibW9kZSI6ICJtdWx0aSIKICAg
ICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAgICJk
YXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAg
ICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHBy
IjogInN1bSBieSAoYXp0ZWNfYXR0ZXN0ZXJfYWRkcmVzcykgKGF6dGVjX3ZhbGlkYXRvcl9hdHRl
c3RlZF9lcG9jaF9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIiwgYXp0ZWNfYXR0ZXN0ZXJf
YWRkcmVzcz1+XCIkYXR0ZXN0ZXJcIn0pIC8gb24oKSBncm91cF9sZWZ0KCkgbWF4KGF6dGVjX3Zh
bGlkYXRvcl9jdXJyZW50X2Vwb2Noe2luc3RhbmNlPX5cIiRpbnN0YW5jZVwifSkgKiAxMDAiLAog
ICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJ7e2F6dGVjX2F0dGVzdGVyX2FkZHJlc3N9fSIsCiAg
ICAgICAgICAicmVmSWQiOiAiQSIKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAg
ICJjb2xsYXBzZWQiOiBmYWxzZSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiAxLAog
ICAgICAgICJ3IjogMjQsCiAgICAgICAgIngiOiAwLAogICAgICAgICJ5IjogNDIKICAgICAgfSwK
ICAgICAgImlkIjogMTAyLAogICAgICAidGl0bGUiOiAiTDEgQ29zdHMiLAogICAgICAidHlwZSI6
ICJyb3ciLAogICAgICAicGFuZWxzIjogW10KICAgIH0sCiAgICB7CiAgICAgICJkYXRhc291cmNl
IjogewogICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19Q
Uk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0aW9uIjogIk1lYXN1cmVkIHRvdGFs
IEwxIHRyYW5zYWN0aW9uIGZlZXMgcGFpZCBieSB0aGlzIG5vZGUgb3ZlciB0aGUgbGFzdCAyNCBo
b3Vycy4gVGhlIG5vZGUgcmVwb3J0cyBmZWVzIG9ubHkgd2hlbiBpdCBsYW5kcyBhIHByb3Bvc2Ug
dHJhbnNhY3Rpb24sIHNvIHRoaXMgc3RheXMgZW1wdHkgdW50aWwgdGhlIGZpcnN0IHN1Y2Nlc3Nm
dWwgYmxvY2sgcHVibGlzaCBzaW5jZSB0aGUgbm9kZSdzIGxhc3QgcmVzdGFydC4iLAogICAgICAi
ZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjog
ewogICAgICAgICAgICAibW9kZSI6ICJ0aHJlc2hvbGRzIgogICAgICAgICAgfSwKICAgICAgICAg
ICJ0aHJlc2hvbGRzIjogewogICAgICAgICAgICAibW9kZSI6ICJhYnNvbHV0ZSIsCiAgICAgICAg
ICAgICJzdGVwcyI6IFsKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29sb3IiOiAi
Z3JlZW4iLAogICAgICAgICAgICAgICAgInZhbHVlIjogbnVsbAogICAgICAgICAgICAgIH0KICAg
ICAgICAgICAgXQogICAgICAgICAgfSwKICAgICAgICAgICJ1bml0IjogIm5vbmUiLAogICAgICAg
ICAgImRlY2ltYWxzIjogNiwKICAgICAgICAgICJub1ZhbHVlIjogIm5vIHB1Ymxpc2hlcyB5ZXQi
CiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVzIjogW10KICAgICAgfSwKICAgICAgImdyaWRQ
b3MiOiB7CiAgICAgICAgImgiOiA0LAogICAgICAgICJ3IjogNiwKICAgICAgICAieCI6IDAsCiAg
ICAgICAgInkiOiA0MwogICAgICB9LAogICAgICAiaWQiOiAxMSwKICAgICAgIm9wdGlvbnMiOiB7
CiAgICAgICAgImNvbG9yTW9kZSI6ICJ2YWx1ZSIsCiAgICAgICAgImdyYXBoTW9kZSI6ICJhcmVh
IiwKICAgICAgICAicmVkdWNlT3B0aW9ucyI6IHsKICAgICAgICAgICJjYWxjcyI6IFsKICAgICAg
ICAgICAgImxhc3ROb3ROdWxsIgogICAgICAgICAgXSwKICAgICAgICAgICJmaWVsZHMiOiAiIiwK
ICAgICAgICAgICJ2YWx1ZXMiOiBmYWxzZQogICAgICAgIH0KICAgICAgfSwKICAgICAgInRhcmdl
dHMiOiBbCiAgICAgICAgewogICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgICAgICJ0
eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30i
CiAgICAgICAgICB9LAogICAgICAgICAgImV4cHIiOiAic3VtKGluY3JlYXNlKGF6dGVjX2wxX3B1
Ymxpc2hlcl90eF90b3RhbF9mZWVfZXRoX3N1bXtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn1bMjRo
XSkpIiwKICAgICAgICAgICJsZWdlbmRGb3JtYXQiOiAiRVRIIHNwZW50ICgyNGgpIiwKICAgICAg
ICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0KICAgICAgXSwKICAgICAgInRpdGxlIjogIkVUSCBz
cGVudCBvbiBMMSAoMjRoKSIsCiAgICAgICJ0eXBlIjogInN0YXQiCiAgICB9LAogICAgewogICAg
ICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAi
dWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgIH0sCiAgICAgICJkZXNjcmlwdGlvbiI6ICJQ
dWJsaXNoZXIgYWNjb3VudCBiYWxhbmNlIGluIEVUSCAocHJlc2VudCBmcm9tIG5vZGUgc3RhcnR1
cCkuIEJlbG93IDAuMSBFVEggYSBwcm9wb3NlIHRyYW5zYWN0aW9uIGNhbiBmYWlsIGR1cmluZyBh
biBMMSBnYXMgc3Bpa2UuIiwKICAgICAgImZpZWxkQ29uZmlnIjogewogICAgICAgICJkZWZhdWx0
cyI6IHsKICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAgIm1vZGUiOiAidGhyZXNob2xk
cyIKICAgICAgICAgIH0sCiAgICAgICAgICAidGhyZXNob2xkcyI6IHsKICAgICAgICAgICAgIm1v
ZGUiOiAiYWJzb2x1dGUiLAogICAgICAgICAgICAic3RlcHMiOiBbCiAgICAgICAgICAgICAgewog
ICAgICAgICAgICAgICAgImNvbG9yIjogInJlZCIsCiAgICAgICAgICAgICAgICAidmFsdWUiOiBu
dWxsCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiY29s
b3IiOiAieWVsbG93IiwKICAgICAgICAgICAgICAgICJ2YWx1ZSI6IDAuMQogICAgICAgICAgICAg
IH0sCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgImNvbG9yIjogImdyZWVuIiwKICAg
ICAgICAgICAgICAgICJ2YWx1ZSI6IDAuMjUKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0K
ICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJub25lIiwKICAgICAgICAgICJkZWNpbWFs
cyI6IDQKICAgICAgICB9LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAi
Z3JpZFBvcyI6IHsKICAgICAgICAiaCI6IDQsCiAgICAgICAgInciOiA2LAogICAgICAgICJ4Ijog
NiwKICAgICAgICAieSI6IDQzCiAgICAgIH0sCiAgICAgICJpZCI6IDEyLAogICAgICAib3B0aW9u
cyI6IHsKICAgICAgICAiY29sb3JNb2RlIjogImJhY2tncm91bmQiLAogICAgICAgICJncmFwaE1v
ZGUiOiAiYXJlYSIsCiAgICAgICAgInJlZHVjZU9wdGlvbnMiOiB7CiAgICAgICAgICAiY2FsY3Mi
OiBbCiAgICAgICAgICAgICJsYXN0Tm90TnVsbCIKICAgICAgICAgIF0sCiAgICAgICAgICAiZmll
bGRzIjogIiIsCiAgICAgICAgICAidmFsdWVzIjogZmFsc2UKICAgICAgICB9CiAgICAgIH0sCiAg
ICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAg
ICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BS
T01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogInN1bSBieSAoYXp0ZWNf
bDFfc2VuZGVyKSAoYXp0ZWNfbDFfYmFsYW5jZV9ldGh7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9
KSIsCiAgICAgICAgICAibGVnZW5kRm9ybWF0IjogInt7YXp0ZWNfbDFfc2VuZGVyfX0iLAogICAg
ICAgICAgInJlZklkIjogIkEiCiAgICAgICAgfQogICAgICBdLAogICAgICAidGl0bGUiOiAiUHVi
bGlzaGVyIGJhbGFuY2UgKEVUSCkiLAogICAgICAidHlwZSI6ICJzdGF0IgogICAgfSwKICAgIHsK
ICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAg
ICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICB9LAogICAgICAiZGVzY3JpcHRpb24i
OiAiTDEgdHJhbnNhY3Rpb25zIHNlbnQgaW4gdGhlIGxhc3QgMjRoLCBieSBvdXRjb21lLiIsCiAg
ICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7CiAgICAgICAgICAiY29s
b3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAgICAgICAgIH0s
CiAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiZHJhd1N0eWxlIjogImJhcnMiLAog
ICAgICAgICAgICAiZmlsbE9wYWNpdHkiOiA2MAogICAgICAgICAgfSwKICAgICAgICAgICJ1bml0
IjogInNob3J0IiwKICAgICAgICAgICJkZWNpbWFscyI6IDAKICAgICAgICB9LAogICAgICAgICJv
dmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3JpZFBvcyI6IHsKICAgICAgICAiaCI6IDQs
CiAgICAgICAgInciOiAxMiwKICAgICAgICAieCI6IDEyLAogICAgICAgICJ5IjogNDMKICAgICAg
fSwKICAgICAgImlkIjogMTMsCiAgICAgICJvcHRpb25zIjogewogICAgICAgICJsZWdlbmQiOiB7
CiAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlzdCIsCiAgICAgICAgICAicGxhY2VtZW50Ijog
InJpZ2h0IiwKICAgICAgICAgICJzaG93TGVnZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAg
InRvb2x0aXAiOiB7CiAgICAgICAgICAibW9kZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0s
CiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewog
ICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RT
X1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogInJvdW5kKGNsYW1w
X21pbihzdW0oYXp0ZWNfbDFfdHhfbWluZWRfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9
KSAtIHN1bShhenRlY19sMV90eF9taW5lZF9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0g
b2Zmc2V0IDI0aCksIDApKSBvciByb3VuZChzdW0oYXp0ZWNfbDFfdHhfbWluZWRfY291bnR7aW5z
dGFuY2U9flwiJGluc3RhbmNlXCJ9KSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJtaW5l
ZCIsCiAgICAgICAgICAicmVmSWQiOiAiQSIKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAg
ICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAg
ICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJl
eHByIjogInJvdW5kKGNsYW1wX21pbihzdW0oYXp0ZWNfbDFfdHhfcmV2ZXJ0ZWRfY291bnR7aW5z
dGFuY2U9flwiJGluc3RhbmNlXCJ9KSAtIHN1bShhenRlY19sMV90eF9yZXZlcnRlZF9jb3VudHtp
bnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0gb2Zmc2V0IDI0aCksIDApKSBvciByb3VuZChzdW0oYXp0
ZWNfbDFfdHhfcmV2ZXJ0ZWRfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSkiLAogICAg
ICAgICAgImxlZ2VuZEZvcm1hdCI6ICJyZXZlcnRlZCIsCiAgICAgICAgICAicmVmSWQiOiAiQiIK
ICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAg
ICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhF
VVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogInJvdW5kKGNsYW1wX21pbihzdW0o
YXp0ZWNfbDFfdHhfY2FuY2VsbGVkX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwifSkgLSBz
dW0oYXp0ZWNfbDFfdHhfY2FuY2VsbGVkX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwifSBv
ZmZzZXQgMjRoKSwgMCkpIG9yIHJvdW5kKHN1bShhenRlY19sMV90eF9jYW5jZWxsZWRfY291bnR7
aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJj
YW5jZWxsZWQiLAogICAgICAgICAgInJlZklkIjogIkMiCiAgICAgICAgfSwKICAgICAgICB7CiAg
ICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIs
CiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAg
ICAgICAiZXhwciI6ICJyb3VuZChjbGFtcF9taW4oc3VtKGF6dGVjX2wxX3R4X25vdF9taW5lZF9j
b3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIC0gc3VtKGF6dGVjX2wxX3R4X25vdF9taW5l
ZF9jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0gb2Zmc2V0IDI0aCksIDApKSBvciByb3Vu
ZChzdW0oYXp0ZWNfbDFfdHhfbm90X21pbmVkX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwi
fSkpIiwKICAgICAgICAgICJsZWdlbmRGb3JtYXQiOiAibm90IG1pbmVkIiwKICAgICAgICAgICJy
ZWZJZCI6ICJEIgogICAgICAgIH0KICAgICAgXSwKICAgICAgInRpdGxlIjogIkwxIHRyYW5zYWN0
aW9uIG91dGNvbWVzICgyNGgpIiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAgIH0sCiAg
ICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAog
ICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0
aW9uIjogIlB1Ymxpc2hlciBhY2NvdW50IGJhbGFuY2Ugb3ZlciB0aW1lIChwcmVzZW50IGZyb20g
bm9kZSBzdGFydHVwKS4gQSBzdGVhZHkgZG93bndhcmQgc2xvcGUgaXMgeW91ciBMMSBzcGVuZCBy
YXRlLiIsCiAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7CiAgICAg
ICAgICAiY29sb3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAg
ICAgICAgIH0sCiAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiZHJhd1N0eWxlIjog
ImxpbmUiLAogICAgICAgICAgICAibGluZVdpZHRoIjogMiwKICAgICAgICAgICAgImZpbGxPcGFj
aXR5IjogMTAKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJub25lIiwKICAgICAgICAg
ICJkZWNpbWFscyI6IDQKICAgICAgICB9LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9
LAogICAgICAiZ3JpZFBvcyI6IHsKICAgICAgICAiaCI6IDgsCiAgICAgICAgInciOiAxMiwKICAg
ICAgICAieCI6IDAsCiAgICAgICAgInkiOiA0NwogICAgICB9LAogICAgICAiaWQiOiAxNCwKICAg
ICAgIm9wdGlvbnMiOiB7CiAgICAgICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5TW9k
ZSI6ICJsaXN0IiwKICAgICAgICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAgICJz
aG93TGVnZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAgICAg
ICAibW9kZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjogWwog
ICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJw
cm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAg
ICAgfSwKICAgICAgICAgICJleHByIjogImF2ZyBieSAoYXp0ZWNfbDFfc2VuZGVyKSAoYXp0ZWNf
bDFfYmFsYW5jZV9ldGh7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSIsCiAgICAgICAgICAibGVn
ZW5kRm9ybWF0IjogInt7YXp0ZWNfbDFfc2VuZGVyfX0iLAogICAgICAgICAgInJlZklkIjogIkEi
CiAgICAgICAgfQogICAgICBdLAogICAgICAidGl0bGUiOiAiUHVibGlzaGVyIGJhbGFuY2UgdHJl
bmQiLAogICAgICAidHlwZSI6ICJ0aW1lc2VyaWVzIgogICAgfSwKICAgIHsKICAgICAgImRhdGFz
b3VyY2UiOiB7CiAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIk
e0RTX1BST01FVEhFVVN9IgogICAgICB9LAogICAgICAiZGVzY3JpcHRpb24iOiAiTDEgZ2FzIHBy
aWNlIHRoaXMgbm9kZSBpcyBwYXlpbmcgKHA1MC9wOTApLiBIaWdoZXIgZ2FzIG1lYW5zIGhpZ2hl
ciBzcGVuZCBwZXIgcHJvcG9zYWwuIE5vIGRhdGEgdW50aWwgdGhpcyBub2RlIHByb3Bvc2VzLiIs
CiAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7CiAgICAgICAgICAi
Y29sb3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAgICAgICAg
IH0sCiAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiZHJhd1N0eWxlIjogImxpbmUi
LAogICAgICAgICAgICAibGluZVdpZHRoIjogMiwKICAgICAgICAgICAgInNob3dQb2ludHMiOiAi
YWx3YXlzIiwKICAgICAgICAgICAgInBvaW50U2l6ZSI6IDYsCiAgICAgICAgICAgICJzcGFuTnVs
bHMiOiB0cnVlCiAgICAgICAgICB9LAogICAgICAgICAgInVuaXQiOiAibm9uZSIKICAgICAgICB9
LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3JpZFBvcyI6IHsKICAg
ICAgICAiaCI6IDgsCiAgICAgICAgInciOiAxMiwKICAgICAgICAieCI6IDEyLAogICAgICAgICJ5
IjogNDcKICAgICAgfSwKICAgICAgImlkIjogMTUsCiAgICAgICJvcHRpb25zIjogewogICAgICAg
ICJsZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlzdCIsCiAgICAgICAgICAi
cGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAic2hvd0xlZ2VuZCI6IHRydWUKICAgICAg
ICB9LAogICAgICAgICJ0b29sdGlwIjogewogICAgICAgICAgIm1vZGUiOiAibXVsdGkiCiAgICAg
ICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0
YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAg
ICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6
ICJoaXN0b2dyYW1fcXVhbnRpbGUoMC41LCBzdW0gYnkgKGluc3RhbmNlLCBsZSkgKHJhdGUoYXp0
ZWNfbDFfcHVibGlzaGVyX2dhc19wcmljZV9nd2VpX2J1Y2tldHtpbnN0YW5jZT1+XCIkaW5zdGFu
Y2VcIn1bJF9fcmF0ZV9pbnRlcnZhbF0pKSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJw
NTAiLAogICAgICAgICAgInJlZklkIjogIkEiCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAg
ICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAg
ICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAi
ZXhwciI6ICJoaXN0b2dyYW1fcXVhbnRpbGUoMC45LCBzdW0gYnkgKGluc3RhbmNlLCBsZSkgKHJh
dGUoYXp0ZWNfbDFfcHVibGlzaGVyX2dhc19wcmljZV9nd2VpX2J1Y2tldHtpbnN0YW5jZT1+XCIk
aW5zdGFuY2VcIn1bJF9fcmF0ZV9pbnRlcnZhbF0pKSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1h
dCI6ICJwOTAiLAogICAgICAgICAgInJlZklkIjogIkIiCiAgICAgICAgfQogICAgICBdLAogICAg
ICAidGl0bGUiOiAiTDEgZ2FzIHByaWNlIChnd2VpKSIsCiAgICAgICJ0eXBlIjogInRpbWVzZXJp
ZXMiCiAgICB9LAogICAgewogICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAidHlwZSI6ICJw
cm9tZXRoZXVzIiwKICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgIH0sCiAg
ICAgICJpZCI6IDEwNiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIsCiAgICAgICJ0aXRsZSI6
ICJMMSBnYXMgdXNlZCBwZXIgdHg6IGNhbGxkYXRhIHZzIGJsb2IiLAogICAgICAiZGVzY3JpcHRp
b24iOiAiQXZlcmFnZSBMMSBnYXMgcGVyIHRyYW5zYWN0aW9uIG92ZXIgdGhlIGxhc3QgMjQgaG91
cnMsIHNwbGl0IGludG8gY2FsbGRhdGEgZ2FzIGFuZCBibG9iIGdhcy4gRm9yIGEgcm9sbHVwLCBi
bG9iIGdhcyBpcyB1c3VhbGx5IHRoZSBsYXJnZXIgc2hhcmUuIE5vIGRhdGEgdW50aWwgdGhpcyBu
b2RlIHByb3Bvc2VzIChmZWUgbWV0cmljcyBzdGFydCBhdCB0aGUgZmlyc3Qgc3VjY2Vzc2Z1bCBw
dWJsaXNoIGFmdGVyIGEgcmVzdGFydCkuIiwKICAgICAgImZpZWxkQ29uZmlnIjogewogICAgICAg
ICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAgIm1vZGUiOiAi
cGFsZXR0ZS1jbGFzc2ljIgogICAgICAgICAgfSwKICAgICAgICAgICJjdXN0b20iOiB7CiAgICAg
ICAgICAgICJkcmF3U3R5bGUiOiAibGluZSIsCiAgICAgICAgICAgICJsaW5lV2lkdGgiOiAyLAog
ICAgICAgICAgICAiZmlsbE9wYWNpdHkiOiAxMAogICAgICAgICAgfSwKICAgICAgICAgICJ1bml0
IjogInN1ZmZpeDpnYXMiLAogICAgICAgICAgImRlY2ltYWxzIjogMAogICAgICAgIH0sCiAgICAg
ICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAgICAgICJncmlkUG9zIjogewogICAgICAgICJo
IjogOCwKICAgICAgICAidyI6IDEyLAogICAgICAgICJ4IjogMCwKICAgICAgICAieSI6IDU2CiAg
ICAgIH0sCiAgICAgICJvcHRpb25zIjogewogICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAi
ZGlzcGxheU1vZGUiOiAibGlzdCIsCiAgICAgICAgICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAg
ICAgICAgICAic2hvd0xlZ2VuZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJ0b29sdGlwIjog
ewogICAgICAgICAgIm1vZGUiOiAibXVsdGkiCiAgICAgICAgfQogICAgICB9LAogICAgICAidGFy
Z2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAg
InR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVT
fSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJzdW0oaW5jcmVhc2UoYXp0ZWNfbDFf
cHVibGlzaGVyX3R4X2NhbGxkYXRhX2dhc19zdW17aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9WzI0
aF0pKSAvIGNsYW1wX21pbihzdW0oaW5jcmVhc2UoYXp0ZWNfbDFfcHVibGlzaGVyX3R4X2NhbGxk
YXRhX2dhc19jb3VudHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn1bMjRoXSkpLCAxKSIsCiAgICAg
ICAgICAibGVnZW5kRm9ybWF0IjogImNhbGxkYXRhIGdhcyAoYXZnL3R4LCAyNGgpIiwKICAgICAg
ICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImRhdGFzb3Vy
Y2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAgICAidWlk
IjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgICAgICB9LAogICAgICAgICAgImV4cHIiOiAic3Vt
KGluY3JlYXNlKGF6dGVjX2wxX3B1Ymxpc2hlcl90eF9ibG9iZGF0YV9nYXNfdXNlZF9zdW17aW5z
dGFuY2U9flwiJGluc3RhbmNlXCJ9WzI0aF0pKSAvIGNsYW1wX21pbihzdW0oaW5jcmVhc2UoYXp0
ZWNfbDFfcHVibGlzaGVyX3R4X2Jsb2JkYXRhX2dhc191c2VkX2NvdW50e2luc3RhbmNlPX5cIiRp
bnN0YW5jZVwifVsyNGhdKSksIDEpIiwKICAgICAgICAgICJsZWdlbmRGb3JtYXQiOiAiYmxvYiBn
YXMgKGF2Zy90eCwgMjRoKSIsCiAgICAgICAgICAicmVmSWQiOiAiQiIKICAgICAgICB9CiAgICAg
IF0KICAgIH0sCiAgICB7CiAgICAgICJjb2xsYXBzZWQiOiBmYWxzZSwKICAgICAgImdyaWRQb3Mi
OiB7CiAgICAgICAgImgiOiAxLAogICAgICAgICJ3IjogMjQsCiAgICAgICAgIngiOiAwLAogICAg
ICAgICJ5IjogNjQKICAgICAgfSwKICAgICAgImlkIjogMTA0LAogICAgICAidGl0bGUiOiAiU2Vy
dmVyIGhlYWx0aCIsCiAgICAgICJ0eXBlIjogInJvdyIsCiAgICAgICJwYW5lbHMiOiBbXQogICAg
fSwKICAgIHsKICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1
cyIsCiAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICB9LAogICAgICAiZGVz
Y3JpcHRpb24iOiAiQ1BVIHVzYWdlIGFzIGEgc2hhcmUgb2YgYWxsIGNvcmVzICgxLjAgPSBmdWxs
eSBidXN5KS4gTG9hZCBzY2FsZXMgd2l0aCB0aGUgbnVtYmVyIG9mIG5vZGVzIHlvdSBydW4sIG5v
dCB0aGUgbnVtYmVyIG9mIGF0dGVzdGVycyBwZXIgbm9kZS4iLAogICAgICAiZmllbGRDb25maWci
OiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewogICAgICAgICAg
ICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAgICAgICAgImN1c3Rv
bSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAgICAgImxpbmVX
aWR0aCI6IDIsCiAgICAgICAgICAgICJmaWxsT3BhY2l0eSI6IDEwCiAgICAgICAgICB9LAogICAg
ICAgICAgInVuaXQiOiAicGVyY2VudHVuaXQiLAogICAgICAgICAgIm1heCI6IDEsCiAgICAgICAg
ICAibWluIjogMAogICAgICAgIH0sCiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAg
ICAgICJncmlkUG9zIjogewogICAgICAgICJoIjogOCwKICAgICAgICAidyI6IDgsCiAgICAgICAg
IngiOiAwLAogICAgICAgICJ5IjogNjUKICAgICAgfSwKICAgICAgImlkIjogMTcsCiAgICAgICJv
cHRpb25zIjogewogICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxheU1vZGUiOiAi
bGlzdCIsCiAgICAgICAgICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAic2hvd0xl
Z2VuZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJ0b29sdGlwIjogewogICAgICAgICAgIm1v
ZGUiOiAibXVsdGkiCiAgICAgICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAg
ICB7CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0
aGV1cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0s
CiAgICAgICAgICAiZXhwciI6ICJzdW0gYnkgKGluc3RhbmNlKSAocHJvY2Vzc19jcHVfdXRpbGl6
YXRpb257aW5zdGFuY2U9flwiJGluc3RhbmNlXCIsIHByb2Nlc3NfY3B1X3N0YXRlPVwidXNlclwi
fSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJ1c2VyIiwKICAgICAgICAgICJyZWZJZCI6
ICJBIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAg
ICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAgICAidWlkIjogIiR7RFNfUFJP
TUVUSEVVU30iCiAgICAgICAgICB9LAogICAgICAgICAgImV4cHIiOiAic3VtIGJ5IChpbnN0YW5j
ZSkgKHByb2Nlc3NfY3B1X3V0aWxpemF0aW9ue2luc3RhbmNlPX5cIiRpbnN0YW5jZVwiLCBwcm9j
ZXNzX2NwdV9zdGF0ZT1cInN5c3RlbVwifSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJz
eXN0ZW0iLAogICAgICAgICAgInJlZklkIjogIkIiCiAgICAgICAgfQogICAgICBdLAogICAgICAi
dGl0bGUiOiAiQ1BVIiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAgIH0sCiAgICB7CiAg
ICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAg
ICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0aW9uIjog
Ik1lbW9yeSB1c2VkIGJ5IHRoZSBub2RlIHByb2Nlc3MuIiwKICAgICAgImZpZWxkQ29uZmlnIjog
ewogICAgICAgICJkZWZhdWx0cyI6IHsKICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAg
Im1vZGUiOiAicGFsZXR0ZS1jbGFzc2ljIgogICAgICAgICAgfSwKICAgICAgICAgICJjdXN0b20i
OiB7CiAgICAgICAgICAgICJkcmF3U3R5bGUiOiAibGluZSIsCiAgICAgICAgICAgICJsaW5lV2lk
dGgiOiAyLAogICAgICAgICAgICAiZmlsbE9wYWNpdHkiOiAxMAogICAgICAgICAgfSwKICAgICAg
ICAgICJ1bml0IjogImJ5dGVzIgogICAgICAgIH0sCiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAg
ICAgIH0sCiAgICAgICJncmlkUG9zIjogewogICAgICAgICJoIjogOCwKICAgICAgICAidyI6IDgs
CiAgICAgICAgIngiOiA4LAogICAgICAgICJ5IjogNjUKICAgICAgfSwKICAgICAgImlkIjogMTgs
CiAgICAgICJvcHRpb25zIjogewogICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxh
eU1vZGUiOiAibGlzdCIsCiAgICAgICAgICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAg
ICAic2hvd0xlZ2VuZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJ0b29sdGlwIjogewogICAg
ICAgICAgIm1vZGUiOiAibXVsdGkiCiAgICAgICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6
IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUi
OiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAg
ICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJhdmcgYnkgKGluc3RhbmNlKSAocHJvY2Vzc19t
ZW1vcnlfdXNhZ2V7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSIsCiAgICAgICAgICAibGVnZW5k
Rm9ybWF0IjogInt7aW5zdGFuY2V9fSIsCiAgICAgICAgICAicmVmSWQiOiAiQSIKICAgICAgICB9
CiAgICAgIF0sCiAgICAgICJ0aXRsZSI6ICJNZW1vcnkiLAogICAgICAidHlwZSI6ICJ0aW1lc2Vy
aWVzIgogICAgfSwKICAgIHsKICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgInR5cGUiOiAi
cHJvbWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICB9LAog
ICAgICAiZGVzY3JpcHRpb24iOiAiRGlzayB1c2VkIGJ5IHRoZSBub2RlJ3MgZGF0YWJhc2VzLiIs
CiAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7CiAgICAgICAgICAi
Y29sb3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAgICAgICAg
IH0sCiAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiZHJhd1N0eWxlIjogImxpbmUi
LAogICAgICAgICAgICAibGluZVdpZHRoIjogMgogICAgICAgICAgfSwKICAgICAgICAgICJ1bml0
IjogImJ5dGVzIgogICAgICAgIH0sCiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAg
ICAgICJncmlkUG9zIjogewogICAgICAgICJoIjogOCwKICAgICAgICAidyI6IDgsCiAgICAgICAg
IngiOiAxNiwKICAgICAgICAieSI6IDY1CiAgICAgIH0sCiAgICAgICJpZCI6IDE5LAogICAgICAi
b3B0aW9ucyI6IHsKICAgICAgICAibGVnZW5kIjogewogICAgICAgICAgImRpc3BsYXlNb2RlIjog
Imxpc3QiLAogICAgICAgICAgInBsYWNlbWVudCI6ICJib3R0b20iLAogICAgICAgICAgInNob3dM
ZWdlbmQiOiB0cnVlCiAgICAgICAgfSwKICAgICAgICAidG9vbHRpcCI6IHsKICAgICAgICAgICJt
b2RlIjogIm11bHRpIgogICAgICAgIH0KICAgICAgfSwKICAgICAgInRhcmdldHMiOiBbCiAgICAg
ICAgewogICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogInByb21l
dGhldXMiLAogICAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgICAgICB9
LAogICAgICAgICAgImV4cHIiOiAiYXZnIGJ5IChpbnN0YW5jZSwgYXp0ZWNfZGJfdHlwZSkgKGF6
dGVjX2RiX3VzZWRfc2l6ZV9ieXRlc3tpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIiwKICAgICAg
ICAgICJsZWdlbmRGb3JtYXQiOiAie3thenRlY19kYl90eXBlfX0iLAogICAgICAgICAgInJlZklk
IjogIkEiCiAgICAgICAgfQogICAgICBdLAogICAgICAidGl0bGUiOiAiRGlzayB1c2VkIChkYXRh
YmFzZXMpIiwKICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAgIH0sCiAgICB7CiAgICAgICJk
YXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICJ1aWQi
OiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImRlc2NyaXB0aW9uIjogIkNvbm5l
Y3RlZCBwZWVycyBhbmQgaGVhbHRoeSBwZWVycy4gVG9vIGZldyBoZWFsdGh5IHBlZXJzIHNsb3dz
IGF0dGVzdGF0aW9uIGFuZCBibG9jayBwcm9wYWdhdGlvbi4iLAogICAgICAiZmllbGRDb25maWci
OiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewogICAgICAgICAg
ICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAgICAgICAgImN1c3Rv
bSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAgICAgImxpbmVX
aWR0aCI6IDIKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJub25lIgogICAgICAgIH0s
CiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAgICAgICJncmlkUG9zIjogewogICAg
ICAgICJoIjogOCwKICAgICAgICAidyI6IDgsCiAgICAgICAgIngiOiAwLAogICAgICAgICJ5Ijog
NzMKICAgICAgfSwKICAgICAgImlkIjogMjAsCiAgICAgICJvcHRpb25zIjogewogICAgICAgICJs
ZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlzdCIsCiAgICAgICAgICAicGxh
Y2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAic2hvd0xlZ2VuZCI6IHRydWUKICAgICAgICB9
LAogICAgICAgICJ0b29sdGlwIjogewogICAgICAgICAgIm1vZGUiOiAibXVsdGkiCiAgICAgICAg
fQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7CiAgICAgICAgICAiZGF0YXNv
dXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgICAgICJ1
aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAgICAgICAgICAiZXhwciI6ICJh
dmcgYnkgKGluc3RhbmNlKSAoYXp0ZWNfcGVlcl9tYW5hZ2VyX3BlZXJfY291bnRfcGVlcnN7aW5z
dGFuY2U9flwiJGluc3RhbmNlXCJ9KSIsCiAgICAgICAgICAibGVnZW5kRm9ybWF0IjogImNvbm5l
Y3RlZCIsCiAgICAgICAgICAicmVmSWQiOiAiQSIKICAgICAgICB9LAogICAgICAgIHsKICAgICAg
ICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAg
ICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAg
ICJleHByIjogImF2ZyBieSAoaW5zdGFuY2UpIChhenRlY19wZWVyX21hbmFnZXJfaGVhbHRoeV9w
ZWVyX2NvdW50X3BlZXJze2luc3RhbmNlPX5cIiRpbnN0YW5jZVwifSkiLAogICAgICAgICAgImxl
Z2VuZEZvcm1hdCI6ICJoZWFsdGh5IiwKICAgICAgICAgICJyZWZJZCI6ICJCIgogICAgICAgIH0K
ICAgICAgXSwKICAgICAgInRpdGxlIjogIlBlZXJzIGNvbm5lY3RlZCIsCiAgICAgICJ0eXBlIjog
InRpbWVzZXJpZXMiCiAgICB9LAogICAgewogICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAi
dHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAg
ICAgIH0sCiAgICAgICJkZXNjcmlwdGlvbiI6ICJUaGUgTDIgYmxvY2sgaGVpZ2h0IHRoaXMgbm9k
ZSBoYXMgc3luY2VkIHRvLiBTaG91bGQgYmUgYSBzdGVhZGlseSByaXNpbmcgbGluZS4gKEwxIGhl
aWdodCBpcyBzaG93biBzZXBhcmF0ZWx5IGluIHRoZSBMMSBjb25uZWN0aW9uIHBhbmVsLikiLAog
ICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNv
bG9yIjogewogICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9
LAogICAgICAgICAgImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwK
ICAgICAgICAgICAgImxpbmVXaWR0aCI6IDIKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6
ICJub25lIgogICAgICAgIH0sCiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAgICAg
ICJncmlkUG9zIjogewogICAgICAgICJoIjogOCwKICAgICAgICAidyI6IDgsCiAgICAgICAgIngi
OiA4LAogICAgICAgICJ5IjogNzMKICAgICAgfSwKICAgICAgImlkIjogMjEsCiAgICAgICJvcHRp
b25zIjogewogICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlz
dCIsCiAgICAgICAgICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAic2hvd0xlZ2Vu
ZCI6IHRydWUKICAgICAgICB9LAogICAgICAgICJ0b29sdGlwIjogewogICAgICAgICAgIm1vZGUi
OiAibXVsdGkiCiAgICAgICAgfQogICAgICB9LAogICAgICAidGFyZ2V0cyI6IFsKICAgICAgICB7
CiAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1
cyIsCiAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgIH0sCiAg
ICAgICAgICAiZXhwciI6ICJtYXggYnkgKGluc3RhbmNlKSAoYXp0ZWNfYXJjaGl2ZXJfYmxvY2tf
aGVpZ2h0e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwiLCBhenRlY19zdGF0dXM9XCJwcm9wb3NlZFwi
fSkiLAogICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJMMiBibG9jayBoZWlnaHQiLAogICAgICAg
ICAgInJlZklkIjogIkEiCiAgICAgICAgfQogICAgICBdLAogICAgICAidGl0bGUiOiAiTDIgYmxv
Y2tzIHN5bmNlZCIsCiAgICAgICJ0eXBlIjogInRpbWVzZXJpZXMiCiAgICB9LAogICAgewogICAg
ICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAi
dWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgIH0sCiAgICAgICJkZXNjcmlwdGlvbiI6ICJI
b3cgZmFyIGJlaGluZCByZWFsIHRpbWUgdGhlIG5vZGUncyBwcm9jZXNzaW5nIGxvb3AgaXMgKHA5
MCkuIEhpZ2ggdmFsdWVzIG1lYW4gdGhlIG5vZGUgaXMgb3ZlcmxvYWRlZC4iLAogICAgICAiZmll
bGRDb25maWciOiB7CiAgICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgImNvbG9yIjogewog
ICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNzaWMiCiAgICAgICAgICB9LAogICAgICAg
ICAgImN1c3RvbSI6IHsKICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAg
ICAgImxpbmVXaWR0aCI6IDIKICAgICAgICAgIH0sCiAgICAgICAgICAidW5pdCI6ICJtcyIKICAg
ICAgICB9LAogICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICB9LAogICAgICAiZ3JpZFBvcyI6
IHsKICAgICAgICAiaCI6IDgsCiAgICAgICAgInciOiA4LAogICAgICAgICJ4IjogMTYsCiAgICAg
ICAgInkiOiA3MwogICAgICB9LAogICAgICAiaWQiOiAyMiwKICAgICAgIm9wdGlvbnMiOiB7CiAg
ICAgICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJsaXN0IiwKICAgICAg
ICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAgICJzaG93TGVnZW5kIjogdHJ1ZQog
ICAgICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAgICAgICAibW9kZSI6ICJtdWx0aSIK
ICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAg
ICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAg
ICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJl
eHByIjogImF2ZyBieSAoaW5zdGFuY2UpIChub2RlanNfZXZlbnRsb29wX2RlbGF5X3A5MF9uYW5v
c2Vjb25kc3tpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIC8gMWU2IiwKICAgICAgICAgICJsZWdl
bmRGb3JtYXQiOiAiZXZlbnQtbG9vcCBwOTAiLAogICAgICAgICAgInJlZklkIjogIkEiCiAgICAg
ICAgfQogICAgICBdLAogICAgICAidGl0bGUiOiAiUHJvY2Vzc2luZyBsYWcgKGV2ZW50LWxvb3Ag
cDkwKSIsCiAgICAgICJ0eXBlIjogInRpbWVzZXJpZXMiCiAgICB9LAogICAgewogICAgICAiZGF0
YXNvdXJjZSI6IHsKICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAidWlkIjog
IiR7RFNfUFJPTUVUSEVVU30iCiAgICAgIH0sCiAgICAgICJpZCI6IDExMSwKICAgICAgInR5cGUi
OiAidGltZXNlcmllcyIsCiAgICAgICJ0aXRsZSI6ICJMMSBjb25uZWN0aW9uIChMMSBibG9jayBo
ZWlnaHQpIiwKICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBMMSBibG9jayBoZWlnaHQgdGhlIG5v
ZGUncyBwdWJsaXNoZXIgaXMgdHJhY2tpbmcuIFRoaXMgbGluZSBzaG91bGQga2VlcCBjbGltYmlu
ZyAoTDEgcHJvZHVjZXMgYSBibG9jayByb3VnaGx5IGV2ZXJ5IDEyIHNlY29uZHMpLiBBIGZsYXQg
bGluZSBtZWFucyB0aGUgTDEgUlBDIGVuZHBvaW50IGlzIHVucmVhY2hhYmxlIG9yIHN0dWNrLiIs
CiAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7CiAgICAgICAgICAi
Y29sb3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAgICAgICAg
IH0sCiAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAgICAiZHJhd1N0eWxlIjogImxpbmUi
LAogICAgICAgICAgICAibGluZVdpZHRoIjogMgogICAgICAgICAgfSwKICAgICAgICAgICJ1bml0
IjogIm5vbmUiLAogICAgICAgICAgImRlY2ltYWxzIjogMAogICAgICAgIH0sCiAgICAgICAgIm92
ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAgICAgICJncmlkUG9zIjogewogICAgICAgICJoIjogOCwK
ICAgICAgICAidyI6IDgsCiAgICAgICAgIngiOiAwLAogICAgICAgICJ5IjogODEKICAgICAgfSwK
ICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5
TW9kZSI6ICJsaXN0IiwKICAgICAgICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAg
ICJzaG93TGVnZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAg
ICAgICAibW9kZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjog
WwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6
ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAg
ICAgICAgfSwKICAgICAgICAgICJleHByIjogIm1heCBieSAoaW5zdGFuY2UpKGF6dGVjX2wxX2Js
b2NrX2hlaWdodHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIiwKICAgICAgICAgICJsZWdlbmRG
b3JtYXQiOiAiTDEgYmxvY2sgaGVpZ2h0IiwKICAgICAgICAgICJyZWZJZCI6ICJBIgogICAgICAg
IH0KICAgICAgXQogICAgfSwKICAgIHsKICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgInR5
cGUiOiAicHJvbWV0aGV1cyIsCiAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAg
ICB9LAogICAgICAiaWQiOiAxMDgsCiAgICAgICJ0eXBlIjogInRpbWVzZXJpZXMiLAogICAgICAi
dGl0bGUiOiAiTmV0d29yayBlcnJvcnMgJiBkcm9wcGVkIHBhY2tldHMiLAogICAgICAiZGVzY3Jp
cHRpb24iOiAiSG9zdCBuZXR3b3JrIGludGVyZmFjZSBlcnJvcnMgYW5kIGRyb3BwZWQgcGFja2V0
cyAocGVyIHNlY29uZCkuIE5vbi16ZXJvIHZhbHVlcyBpbmRpY2F0ZSBOSUMgb3IgZHJpdmVyIHBy
b2JsZW1zIG9uIHRoZSBob3N0LiIsCiAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAiZGVm
YXVsdHMiOiB7CiAgICAgICAgICAiY29sb3IiOiB7CiAgICAgICAgICAgICJtb2RlIjogInBhbGV0
dGUtY2xhc3NpYyIKICAgICAgICAgIH0sCiAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAg
ICAiZHJhd1N0eWxlIjogImxpbmUiLAogICAgICAgICAgICAibGluZVdpZHRoIjogMgogICAgICAg
ICAgfSwKICAgICAgICAgICJ1bml0IjogIm5vbmUiLAogICAgICAgICAgImRlY2ltYWxzIjogMgog
ICAgICAgIH0sCiAgICAgICAgIm92ZXJyaWRlcyI6IFtdCiAgICAgIH0sCiAgICAgICJncmlkUG9z
IjogewogICAgICAgICJoIjogOCwKICAgICAgICAidyI6IDgsCiAgICAgICAgIngiOiA4LAogICAg
ICAgICJ5IjogODEKICAgICAgfSwKICAgICAgIm9wdGlvbnMiOiB7CiAgICAgICAgImxlZ2VuZCI6
IHsKICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJsaXN0IiwKICAgICAgICAgICJwbGFjZW1lbnQi
OiAiYm90dG9tIiwKICAgICAgICAgICJzaG93TGVnZW5kIjogdHJ1ZQogICAgICAgIH0sCiAgICAg
ICAgInRvb2x0aXAiOiB7CiAgICAgICAgICAibW9kZSI6ICJtdWx0aSIKICAgICAgICB9CiAgICAg
IH0sCiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjog
ewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIk
e0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJleHByIjogInN1bShyYXRl
KHN5c3RlbV9uZXR3b3JrX2Vycm9yc190b3RhbHtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn1bJF9f
cmF0ZV9pbnRlcnZhbF0pKSIsCiAgICAgICAgICAibGVnZW5kRm9ybWF0IjogImVycm9ycy9zIiwK
ICAgICAgICAgICJyZWZJZCI6ICJBIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImRh
dGFzb3VyY2UiOiB7CiAgICAgICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAg
ICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgICAgICB9LAogICAgICAgICAgImV4cHIi
OiAic3VtKHJhdGUoc3lzdGVtX25ldHdvcmtfZHJvcHBlZF90b3RhbHtpbnN0YW5jZT1+XCIkaW5z
dGFuY2VcIn1bJF9fcmF0ZV9pbnRlcnZhbF0pKSIsCiAgICAgICAgICAibGVnZW5kRm9ybWF0Ijog
ImRyb3BwZWQvcyIsCiAgICAgICAgICAicmVmSWQiOiAiQiIKICAgICAgICB9CiAgICAgIF0KICAg
IH0sCiAgICB7CiAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICJ0eXBlIjogInByb21ldGhl
dXMiLAogICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgfSwKICAgICAgImlk
IjogMTA5LAogICAgICAidHlwZSI6ICJ0aW1lc2VyaWVzIiwKICAgICAgInRpdGxlIjogIk5ldHdv
cmsgSS9PIiwKICAgICAgImRlc2NyaXB0aW9uIjogIkhvc3QgbmV0d29yayB0aHJvdWdocHV0IChi
eXRlcyBwZXIgc2Vjb25kLCB0cmFuc21pdCArIHJlY2VpdmUpLiIsCiAgICAgICJmaWVsZENvbmZp
ZyI6IHsKICAgICAgICAiZGVmYXVsdHMiOiB7CiAgICAgICAgICAiY29sb3IiOiB7CiAgICAgICAg
ICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAgICAgICAgIH0sCiAgICAgICAgICAiY3Vz
dG9tIjogewogICAgICAgICAgICAiZHJhd1N0eWxlIjogImxpbmUiLAogICAgICAgICAgICAibGlu
ZVdpZHRoIjogMiwKICAgICAgICAgICAgImZpbGxPcGFjaXR5IjogMTAKICAgICAgICAgIH0sCiAg
ICAgICAgICAidW5pdCI6ICJCcHMiCiAgICAgICAgfSwKICAgICAgICAib3ZlcnJpZGVzIjogW10K
ICAgICAgfSwKICAgICAgImdyaWRQb3MiOiB7CiAgICAgICAgImgiOiA4LAogICAgICAgICJ3Ijog
OCwKICAgICAgICAieCI6IDE2LAogICAgICAgICJ5IjogODEKICAgICAgfSwKICAgICAgIm9wdGlv
bnMiOiB7CiAgICAgICAgImxlZ2VuZCI6IHsKICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJsaXN0
IiwKICAgICAgICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAgICJzaG93TGVnZW5k
IjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInRvb2x0aXAiOiB7CiAgICAgICAgICAibW9kZSI6
ICJtdWx0aSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJ0YXJnZXRzIjogWwogICAgICAgIHsK
ICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVz
IiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgfSwKICAg
ICAgICAgICJleHByIjogInN1bShyYXRlKHN5c3RlbV9uZXR3b3JrX2lvX3RvdGFse2luc3RhbmNl
PX5cIiRpbnN0YW5jZVwifVskX19yYXRlX2ludGVydmFsXSkpIiwKICAgICAgICAgICJsZWdlbmRG
b3JtYXQiOiAidGhyb3VnaHB1dCIsCiAgICAgICAgICAicmVmSWQiOiAiQSIKICAgICAgICB9CiAg
ICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJjb2xsYXBzZWQiOiB0cnVlLAogICAgICAiZ3JpZFBv
cyI6IHsKICAgICAgICAiaCI6IDEsCiAgICAgICAgInciOiAyNCwKICAgICAgICAieCI6IDAsCiAg
ICAgICAgInkiOiA4OQogICAgICB9LAogICAgICAiaWQiOiAxMDUsCiAgICAgICJ0aXRsZSI6ICJI
QSBzaWduaW5nICYgbm9kZSBpbnRlcm5hbHMiLAogICAgICAidHlwZSI6ICJyb3ciLAogICAgICAi
cGFuZWxzIjogWwogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAg
ICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhF
VVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJMYXRlc3QgY2hlY2tw
b2ludCBoZWlnaHQgc2VlbiBieSB0aGUgYXJjaGl2ZXIuIFY1IGdyb3VwcyBibG9jayBwcm9kdWN0
aW9uIGludG8gY2hlY2twb2ludHMuIiwKICAgICAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAg
ICAgICAgImRlZmF1bHRzIjogewogICAgICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAg
ICAgICJtb2RlIjogInBhbGV0dGUtY2xhc3NpYyIKICAgICAgICAgICAgICB9LAogICAgICAgICAg
ICAgICJjdXN0b20iOiB7CiAgICAgICAgICAgICAgICAiZHJhd1N0eWxlIjogImxpbmUiLAogICAg
ICAgICAgICAgICAgImxpbmVXaWR0aCI6IDIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAg
ICJ1bml0IjogIm5vbmUiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJvdmVycmlkZXMiOiBb
XQogICAgICAgICAgfSwKICAgICAgICAgICJncmlkUG9zIjogewogICAgICAgICAgICAiaCI6IDgs
CiAgICAgICAgICAgICJ3IjogMTIsCiAgICAgICAgICAgICJ4IjogMCwKICAgICAgICAgICAgInki
OiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJpZCI6IDIzLAogICAgICAgICAgIm9wdGlvbnMi
OiB7CiAgICAgICAgICAgICJsZWdlbmQiOiB7CiAgICAgICAgICAgICAgImRpc3BsYXlNb2RlIjog
Imxpc3QiLAogICAgICAgICAgICAgICJwbGFjZW1lbnQiOiAiYm90dG9tIiwKICAgICAgICAgICAg
ICAic2hvd0xlZ2VuZCI6IHRydWUKICAgICAgICAgICAgfSwKICAgICAgICAgICAgInRvb2x0aXAi
OiB7CiAgICAgICAgICAgICAgIm1vZGUiOiAibXVsdGkiCiAgICAgICAgICAgIH0KICAgICAgICAg
IH0sCiAgICAgICAgICAidGFyZ2V0cyI6IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICJk
YXRhc291cmNlIjogewogICAgICAgICAgICAgICAgInR5cGUiOiAicHJvbWV0aGV1cyIsCiAgICAg
ICAgICAgICAgICAidWlkIjogIiR7RFNfUFJPTUVUSEVVU30iCiAgICAgICAgICAgICAgfSwKICAg
ICAgICAgICAgICAiZXhwciI6ICJhdmcgYnkgKGluc3RhbmNlKSAoYXp0ZWNfYXJjaGl2ZXJfY2hl
Y2twb2ludF9oZWlnaHR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSIsCiAgICAgICAgICAgICAg
ImxlZ2VuZEZvcm1hdCI6ICJjaGVja3BvaW50IGhlaWdodCIsCiAgICAgICAgICAgICAgInJlZklk
IjogIkEiCiAgICAgICAgICAgIH0KICAgICAgICAgIF0sCiAgICAgICAgICAidGl0bGUiOiAiQ2hl
Y2twb2ludCBoZWlnaHQiLAogICAgICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAgICAgICB9
LAogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAgICAgICAidHlwZSI6
ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAg
ICAgICAgfSwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJIaWdoLWF2YWlsYWJpbGl0eSBzaWdu
ZXIgb3V0Y29tZXMgcGVyIG1pbnV0ZS4gQSBub24temVybyBzbGFzaGluZy1wcm90ZWN0aW9uIHJh
dGUgbWVhbnMgYSBzZWNvbmQgcHJvY2VzcyBpcyB0cnlpbmcgdG8gc2lnbiBmb3IgdGhlIHNhbWUg
a2V5LiIsCiAgICAgICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgICAgICJkZWZhdWx0cyI6
IHsKICAgICAgICAgICAgICAiY29sb3IiOiB7CiAgICAgICAgICAgICAgICAibW9kZSI6ICJwYWxl
dHRlLWNsYXNzaWMiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAiY3VzdG9tIjogewog
ICAgICAgICAgICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAgICAgICAgICJsaW5l
V2lkdGgiOiAyCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAidW5pdCI6ICJub25lIgog
ICAgICAgICAgICB9LAogICAgICAgICAgICAib3ZlcnJpZGVzIjogW10KICAgICAgICAgIH0sCiAg
ICAgICAgICAiZ3JpZFBvcyI6IHsKICAgICAgICAgICAgImgiOiA4LAogICAgICAgICAgICAidyI6
IDEyLAogICAgICAgICAgICAieCI6IDEyLAogICAgICAgICAgICAieSI6IDkwCiAgICAgICAgICB9
LAogICAgICAgICAgImlkIjogMjUsCiAgICAgICAgICAib3B0aW9ucyI6IHsKICAgICAgICAgICAg
ImxlZ2VuZCI6IHsKICAgICAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlzdCIsCiAgICAgICAg
ICAgICAgInBsYWNlbWVudCI6ICJib3R0b20iLAogICAgICAgICAgICAgICJzaG93TGVnZW5kIjog
dHJ1ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAidG9vbHRpcCI6IHsKICAgICAgICAgICAg
ICAibW9kZSI6ICJtdWx0aSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJ0
YXJnZXRzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAg
ICAgICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgICAgICJ1aWQi
OiAiJHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJleHBy
IjogInN1bSBieSAoaW5zdGFuY2UpIChyYXRlKGF6dGVjX2hhX3NpZ25lcl9zaWduaW5nX3N1Y2Nl
c3NfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9WyRfX3JhdGVfaW50ZXJ2YWxdKSkgKiA2
MCIsCiAgICAgICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJzdWNjZXNzL21pbiIsCiAgICAgICAg
ICAgICAgInJlZklkIjogIkEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAg
ICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjogInByb21ldGhldXMi
LAogICAgICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9IgogICAgICAgICAgICAg
IH0sCiAgICAgICAgICAgICAgImV4cHIiOiAic3VtIGJ5IChpbnN0YW5jZSkgKHJhdGUoYXp0ZWNf
aGFfc2lnbmVyX3NpZ25pbmdfZXJyb3JfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9WyRf
X3JhdGVfaW50ZXJ2YWxdKSkgKiA2MCIsCiAgICAgICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJl
cnJvci9taW4iLAogICAgICAgICAgICAgICJyZWZJZCI6ICJCIgogICAgICAgICAgICB9LAogICAg
ICAgICAgICB7CiAgICAgICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAgICAgICAgICAgICAi
dHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgICAgICJ1aWQiOiAiJHtEU19QUk9NRVRI
RVVTfSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJleHByIjogInN1bSBieSAoaW5z
dGFuY2UpIChyYXRlKGF6dGVjX2hhX3NpZ25lcl9zbGFzaGluZ19wcm90ZWN0aW9uX2NvdW50e2lu
c3RhbmNlPX5cIiRpbnN0YW5jZVwifVskX19yYXRlX2ludGVydmFsXSkpICogNjAiLAogICAgICAg
ICAgICAgICJsZWdlbmRGb3JtYXQiOiAic2xhc2hpbmctcHJvdGVjdGlvbi9taW4iLAogICAgICAg
ICAgICAgICJyZWZJZCI6ICJDIgogICAgICAgICAgICB9CiAgICAgICAgICBdLAogICAgICAgICAg
InRpdGxlIjogIkhBIHNpZ25lciBvdXRjb21lcyIsCiAgICAgICAgICAidHlwZSI6ICJ0aW1lc2Vy
aWVzIgogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAg
ICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAgICAidWlkIjogIiR7RFNfUFJP
TUVUSEVVU30iCiAgICAgICAgICB9LAogICAgICAgICAgImlkIjogMTEwLAogICAgICAgICAgInR5
cGUiOiAidGltZXNlcmllcyIsCiAgICAgICAgICAidGl0bGUiOiAiSEEgc2lnbmluZyBsYXRlbmN5
IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJBdmVyYWdlIGVuZC10by1lbmQgSEEgc2lnbmlu
ZyB0aW1lIGJ5IGR1dHkgdHlwZSAobG9jayArIHNpZ24gKyByZWNvcmQpLiBPbmx5IG1lYW5pbmdm
dWwgZm9yIG11bHRpLW5vZGUgaGlnaC1hdmFpbGFiaWxpdHkgc2V0dXBzOyByaXNpbmcgbGF0ZW5j
eSBzdWdnZXN0cyB0aGUgbG9jayBjb29yZGluYXRpb24gaXMgZGVncmFkaW5nIGFuZCByaXNrcyBt
aXNzZWQgZHV0aWVzLiBTaW5nbGUtbm9kZSBvcGVyYXRvcnMgY2FuIGlnbm9yZSB0aGlzLiIsCiAg
ICAgICAgICAiZmllbGRDb25maWciOiB7CiAgICAgICAgICAgICJkZWZhdWx0cyI6IHsKICAgICAg
ICAgICAgICAiY29sb3IiOiB7CiAgICAgICAgICAgICAgICAibW9kZSI6ICJwYWxldHRlLWNsYXNz
aWMiCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAiY3VzdG9tIjogewogICAgICAgICAg
ICAgICAgImRyYXdTdHlsZSI6ICJsaW5lIiwKICAgICAgICAgICAgICAgICJsaW5lV2lkdGgiOiAy
CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAidW5pdCI6ICJtcyIsCiAgICAgICAgICAg
ICAgImRlY2ltYWxzIjogMQogICAgICAgICAgICB9LAogICAgICAgICAgICAib3ZlcnJpZGVzIjog
W10KICAgICAgICAgIH0sCiAgICAgICAgICAiZ3JpZFBvcyI6IHsKICAgICAgICAgICAgImgiOiA4
LAogICAgICAgICAgICAidyI6IDEyLAogICAgICAgICAgICAieCI6IDAsCiAgICAgICAgICAgICJ5
IjogOTgKICAgICAgICAgIH0sCiAgICAgICAgICAib3B0aW9ucyI6IHsKICAgICAgICAgICAgImxl
Z2VuZCI6IHsKICAgICAgICAgICAgICAiZGlzcGxheU1vZGUiOiAibGlzdCIsCiAgICAgICAgICAg
ICAgInBsYWNlbWVudCI6ICJib3R0b20iLAogICAgICAgICAgICAgICJzaG93TGVnZW5kIjogdHJ1
ZQogICAgICAgICAgICB9LAogICAgICAgICAgICAidG9vbHRpcCI6IHsKICAgICAgICAgICAgICAi
bW9kZSI6ICJtdWx0aSIKICAgICAgICAgICAgfQogICAgICAgICAgfSwKICAgICAgICAgICJ0YXJn
ZXRzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgImRhdGFzb3VyY2UiOiB7CiAgICAg
ICAgICAgICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgICAgICJ1aWQiOiAi
JHtEU19QUk9NRVRIRVVTfSIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJleHByIjog
InN1bSBieSAoYXp0ZWNfaGFfc2lnbmVyX2R1dHlfdHlwZSkoYXp0ZWNfaGFfc2lnbmVyX3NpZ25p
bmdfZHVyYXRpb25fbWlsbGlzZWNvbmRzX3N1bXtpbnN0YW5jZT1+XCIkaW5zdGFuY2VcIn0pIC8g
c3VtIGJ5IChhenRlY19oYV9zaWduZXJfZHV0eV90eXBlKShhenRlY19oYV9zaWduZXJfc2lnbmlu
Z19kdXJhdGlvbl9taWxsaXNlY29uZHNfY291bnR7aW5zdGFuY2U9flwiJGluc3RhbmNlXCJ9KSIs
CiAgICAgICAgICAgICAgImxlZ2VuZEZvcm1hdCI6ICJ7e2F6dGVjX2hhX3NpZ25lcl9kdXR5X3R5
cGV9fSIsCiAgICAgICAgICAgICAgInJlZklkIjogIkEiCiAgICAgICAgICAgIH0KICAgICAgICAg
IF0KICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJkYXRhc291cmNlIjogewogICAgICAg
ICAgICAidHlwZSI6ICJwcm9tZXRoZXVzIiwKICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01F
VEhFVVN9IgogICAgICAgICAgfSwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJXb3JsZC1zdGF0
ZSBjcml0aWNhbCBlcnJvcnMgYW5kIHNpbGVudGx5LXNraXBwZWQgcHVibGljIHByb2Nlc3Npbmcu
IiwKICAgICAgICAgICJmaWVsZENvbmZpZyI6IHsKICAgICAgICAgICAgImRlZmF1bHRzIjogewog
ICAgICAgICAgICAgICJjb2xvciI6IHsKICAgICAgICAgICAgICAgICJtb2RlIjogInBhbGV0dGUt
Y2xhc3NpYyIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJjdXN0b20iOiB7CiAgICAg
ICAgICAgICAgICAiZHJhd1N0eWxlIjogImxpbmUiLAogICAgICAgICAgICAgICAgImxpbmVXaWR0
aCI6IDIKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICJ1bml0IjogIm5vbmUiCiAgICAg
ICAgICAgIH0sCiAgICAgICAgICAgICJvdmVycmlkZXMiOiBbXQogICAgICAgICAgfSwKICAgICAg
ICAgICJncmlkUG9zIjogewogICAgICAgICAgICAiaCI6IDgsCiAgICAgICAgICAgICJ3IjogMTIs
CiAgICAgICAgICAgICJ4IjogMTIsCiAgICAgICAgICAgICJ5IjogOTgKICAgICAgICAgIH0sCiAg
ICAgICAgICAiaWQiOiAyNiwKICAgICAgICAgICJvcHRpb25zIjogewogICAgICAgICAgICAibGVn
ZW5kIjogewogICAgICAgICAgICAgICJkaXNwbGF5TW9kZSI6ICJsaXN0IiwKICAgICAgICAgICAg
ICAicGxhY2VtZW50IjogImJvdHRvbSIsCiAgICAgICAgICAgICAgInNob3dMZWdlbmQiOiB0cnVl
CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJ0b29sdGlwIjogewogICAgICAgICAgICAgICJt
b2RlIjogIm11bHRpIgogICAgICAgICAgICB9CiAgICAgICAgICB9LAogICAgICAgICAgInRhcmdl
dHMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAg
ICAgICAgICAgICJ0eXBlIjogInByb21ldGhldXMiLAogICAgICAgICAgICAgICAgInVpZCI6ICIk
e0RTX1BST01FVEhFVVN9IgogICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgImV4cHIiOiAi
c3VtIGJ5IChpbnN0YW5jZSkgKGluY3JlYXNlKGF6dGVjX3dvcmxkX3N0YXRlX2NyaXRpY2FsX2Vy
cm9yX2NvdW50e2luc3RhbmNlPX5cIiRpbnN0YW5jZVwifVskX19yYXRlX2ludGVydmFsXSkpIiwK
ICAgICAgICAgICAgICAibGVnZW5kRm9ybWF0IjogIndvcmxkLXN0YXRlIGNyaXRpY2FsIGVycm9y
cyIsCiAgICAgICAgICAgICAgInJlZklkIjogIkEiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAg
IHsKICAgICAgICAgICAgICAiZGF0YXNvdXJjZSI6IHsKICAgICAgICAgICAgICAgICJ0eXBlIjog
InByb21ldGhldXMiLAogICAgICAgICAgICAgICAgInVpZCI6ICIke0RTX1BST01FVEhFVVN9Igog
ICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgImV4cHIiOiAic3VtIGJ5IChpbnN0YW5jZSkg
KGluY3JlYXNlKGF6dGVjX3B1YmxpY19wcm9jZXNzb3Jfc2lsZW50bHlfc2tpcHBlZF9jb3VudHtp
bnN0YW5jZT1+XCIkaW5zdGFuY2VcIn1bJF9fcmF0ZV9pbnRlcnZhbF0pKSIsCiAgICAgICAgICAg
ICAgImxlZ2VuZEZvcm1hdCI6ICJzaWxlbnRseSBza2lwcGVkIiwKICAgICAgICAgICAgICAicmVm
SWQiOiAiQiIKICAgICAgICAgICAgfQogICAgICAgICAgXSwKICAgICAgICAgICJ0aXRsZSI6ICJJ
bnRlcm5hbCBlcnJvcnMiLAogICAgICAgICAgInR5cGUiOiAidGltZXNlcmllcyIKICAgICAgICB9
CiAgICAgIF0KICAgIH0KICBdCn0K
B64
}
write_alerts_yaml() { cat > "$1" <<'ALERTS_EOF'
# Recommended Prometheus alert rules for a self-hosted Aztec V5 sequencer/validator node.
#
# This is a portable starting point you run inside your OWN Prometheus. It has no
# dependency on any external service. Tune thresholds and `for:` durations to your
# setup before relying on them in production.
#
# Target version: V5 (v5.0.0). Metric names verified against live V5 nodes and
# the Aztec project's own dashboards/alerts. See monitoring-guide.md.
#
# The rules are grouped to match the dashboard: "Am I OK?" health, duties, costs,
# server health, and a few internal-correctness checks.
#
# Label note: these rules group by `instance` (the Prometheus scrape target). If you
# scrape multiple nodes in one Prometheus, each fires per node. If you run several node
# processes behind one target, pin OTEL_RESOURCE_ATTRIBUTES=service.instance.id per
# process and add that label to the grouping.
#
# Grafana-managed alerting is an alternative: recreate these as Grafana alert rules
# pointing at the same Prometheus datasource. The PromQL below transfers directly.

groups:
  - name: aztec-health
    rules:
      - alert: AztecNodeDown
        # The scrape target itself is unreachable.
        expr: up{job="aztec-node"} == 0
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "Node is down ({{ $labels.instance }})"
          description: "Prometheus cannot scrape the node's metrics endpoint. The node process may be down, or the metrics port is unreachable. Check the process and the metrics endpoint."

      - alert: AztecNoNewBlocks
        # No new proposed block height in 10 minutes = the node is not following the chain.
        expr: max by (instance) (increase(aztec_archiver_block_height{aztec_status="proposed"}[10m])) == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "No new blocks for 10 minutes ({{ $labels.instance }})"
          description: "The node has not seen a new block in the last 10 minutes. It may be disconnected from peers or its L1 RPC. Check peers, L1 RPC reachability, and logs."

      - alert: AztecNotSynced
        # Synced L1 height not advancing for 5 minutes = the L1 RPC is stale or unreachable.
        expr: increase(aztec_archiver_l1_block_height[5m]) == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Node not keeping up with L1 ({{ $labels.instance }})"
          description: "The node's synced L1 block height has not moved in 5 minutes. The L1 execution/beacon RPC may be down, lagging, or misconfigured. Verify the L1 endpoints."

      - alert: AztecL1RpcStuck
        # The publisher's view of the L1 height stops advancing = the L1 RPC is stuck.
        # L1 produces a block roughly every 12s, so zero growth over 10m means the RPC
        # endpoint is unreachable or stalled.
        expr: increase(aztec_l1_block_height[10m]) == 0
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "L1 RPC appears stuck ({{ $labels.instance }})"
          description: "The L1 block height the node is tracking has not advanced in 10 minutes. The node's L1 RPC endpoint is likely unreachable or stalled. Check the L1 execution RPC and beacon endpoint configuration and connectivity."

  - name: aztec-duties
    rules:
      - alert: AztecFailedAttestations
        # A genuine missed attestation = the node was on the committee, was due to attest,
        # and failed for a node-side reason. We therefore:
        #  - filter aztec_is_committee_member="true" (the metric is also split on the
        #    "false" series, so summing both double-counts a single event), and
        #  - exclude aztec_error_type="block_number_already_exists" (a benign internal race
        #    of attesting to an already-known block, not a missed duty), mirroring the
        #    insufficient_txs benign-filter precedent.
        # bad_proposal failures are excluded entirely: those are the validator correctly
        # refusing to attest to an invalid block, which is correct behavior, not a fault.
        # Cumulative gauge -> use the 1h offset delta, not increase().
        expr: |
          sum by (instance) (aztec_validator_attestation_failed_node_issue_count{aztec_is_committee_member="true", aztec_error_type!="block_number_already_exists"})
          - sum by (instance) (aztec_validator_attestation_failed_node_issue_count{aztec_is_committee_member="true", aztec_error_type!="block_number_already_exists"} offset 1h) > 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Failed attestations ({{ $labels.instance }})"
          description: "The node missed one or more attestations it was due to make in the last hour. Sustained failures precede an inactivity penalty. Check resources, peers, and logs; see the 'Failed attestations by reason' panel."

      - alert: AztecFailedProposals
        # Genuine proposal failures = checkpoint-proposal faults (all real) plus block-build
        # faults, excluding the benign tx-shortage error types.
        # Cumulative gauges: use the 1h offset delta, not increase().
        # Exclude aztec_error_type insufficient_txs AND insufficient_valid_txs on the
        # block-proposal term: both mark a slot skipped for having too few (valid)
        # transactions to build a block (benign on a quiet network), not a real fault.
        # checkpoint_proposal_failed error types (header_validation_failed, block_build_failed)
        # are all genuine faults and are kept.
        expr: |
          (sum by (instance) (aztec_sequencer_block_proposal_failed_count{aztec_error_type!~"insufficient_txs|insufficient_valid_txs"})
           - sum by (instance) (aztec_sequencer_block_proposal_failed_count{aztec_error_type!~"insufficient_txs|insufficient_valid_txs"} offset 1h))
          + (sum by (instance) (aztec_sequencer_checkpoint_proposal_failed_count)
             - sum by (instance) (aztec_sequencer_checkpoint_proposal_failed_count offset 1h)) > 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Failed proposals ({{ $labels.instance }})"
          description: "The node had one or more genuine block or checkpoint proposal failures in the last hour (benign too-few-transaction skips are excluded). Review L1 connectivity, publisher balance, and logs; see the 'Checkpoint proposal failures by reason' panel."

      - alert: AztecFailedReexecution
        # In V5 all nodes re-execute; sustained failures mean the node cannot validate blocks.
        # Cumulative gauge: use the 1h offset delta, not increase().
        expr: |
          sum by (instance) (aztec_validator_failed_reexecution_count)
          - sum by (instance) (aztec_validator_failed_reexecution_count offset 1h) > 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Failed block re-executions ({{ $labels.instance }})"
          description: "The node failed to re-execute one or more blocks in the last hour. In V5 all nodes re-execute blocks; sustained failures mean the node cannot validate the chain. Review logs and resource pressure."

  - name: aztec-costs
    rules:
      - alert: AztecPublisherBalanceLow
        # Below 0.1 ETH a single propose tx in an L1 gas spike can fail or drain the account.
        # Uses aztec_l1_balance_eth (present from node startup) rather than the
        # publisher-scope metric, which is only emitted after the node starts proposing.
        # This lets the alert fire from startup if the account is underfunded.
        expr: aztec_l1_balance_eth < 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Publisher balance below 0.1 ETH ({{ $labels.instance }})"
          description: "The publisher account balance is below 0.1 ETH. A propose transaction during an L1 gas spike can fail or empty the account, which stops block production. Top up the publisher account."

      - alert: AztecBlobTxFailures
        # Sustained blob tx failures = proposals are not landing on L1.
        # Cumulative gauge: use the 15m offset delta, not increase().
        expr: |
          sum by (instance) (aztec_l1_publisher_blob_tx_failure)
          - sum by (instance) (aztec_l1_publisher_blob_tx_failure offset 15m) > 0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Blob transaction failures ({{ $labels.instance }})"
          description: "The node recorded blob transaction failures in the last 15 minutes. Proposals may not be landing on L1. Check L1 RPC, the blob-capable beacon endpoint, gas pricing, and the publisher balance."

  - name: aztec-server-health
    rules:
      - alert: AztecHighCpu
        # process_cpu_utilization is a 0..1 ratio (OTEL); compare directly, do not rate().
        expr: avg by (instance) (process_cpu_utilization{process_cpu_state="user"}) > 0.7
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High CPU ({{ $labels.instance }})"
          description: "User CPU utilization above 0.7 (of all cores) for 10 minutes. A CPU-saturated node can miss duties. Node load is flat with attester count and scales with the number of nodes, so review per-node sizing."

      - alert: AztecHighMemory
        # system_memory_utilization carries a system_memory_state label (used/free).
        expr: avg by (instance) (system_memory_utilization{system_memory_state="used"}) > 0.9
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High memory ({{ $labels.instance }})"
          description: "Used memory above 90% for 10 minutes. Risk of out-of-memory kills. Review host sizing and any memory growth trend."

      - alert: AztecHighProcessingLag
        # nodejs event-loop p90 in nanoseconds; 0.2s p90 means the process is saturated.
        expr: avg by (instance) (nodejs_eventloop_delay_p90_nanoseconds) / 1e6 > 200
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High processing lag ({{ $labels.instance }})"
          description: "Event-loop p90 delay above 200ms for 10 minutes. The process is CPU-bound and may miss duties. Investigate CPU pressure and host sizing."

      - alert: AztecLowHealthyPeers
        # Too few healthy peers degrades gossip and attestation propagation.
        expr: aztec_peer_manager_healthy_peer_count_peers < 5
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Low healthy peer count ({{ $labels.instance }})"
          description: "Fewer than 5 healthy peers for 10 minutes. Gossip and attestation propagation degrade with too few peers. Check networking, the P2P port forwarding/firewall, and the bootnode list."

  - name: aztec-correctness
    rules:
      - alert: AztecWorldStateCriticalError
        # Any world-state critical error is serious and can lead to chain divergence.
        # Cumulative gauge: use the 5m offset delta, not increase().
        expr: |
          sum by (instance) (aztec_world_state_critical_error_count)
          - sum by (instance) (aztec_world_state_critical_error_count offset 5m) > 0
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: "World-state critical error ({{ $labels.instance }})"
          description: "The world-state recorded a critical error. This can lead to divergence from the canonical chain. Capture logs and review the node's state; a resync may be required."

      - alert: AztecHaSignerSlashingProtectionTriggered
        # Slashing protection blocked a sign — a duplicate/conflicting signer is likely active.
        # Cumulative gauge: use the 15m offset delta, not increase().
        expr: |
          sum by (instance) (aztec_ha_signer_slashing_protection_count)
          - sum by (instance) (aztec_ha_signer_slashing_protection_count offset 15m) > 0
        for: 0m
        labels:
          severity: critical
        annotations:
          summary: "Signer slashing protection triggered ({{ $labels.instance }})"
          description: "The signer's slashing-protection layer blocked a signature in the last 15 minutes. This usually means a second process tried to sign for the same key. Confirm only one active signer per key before continuing."
ALERTS_EOF
}
write_alertmanager_yml() { cat > "$1" <<'AM_EOF'
# Alertmanager configuration for delivering the Aztec node alerts to Telegram.
#
# This routes the alerts defined in alerts.yaml to a Telegram chat using
# Alertmanager's built-in Telegram receiver. There is no custom bot code and no extra
# service to maintain beyond Alertmanager itself. You run your own bot and your own
# Alertmanager; nothing connects to any external or Foundation-run service.
#
# alerts.yaml (loaded by Prometheus) stays the source of truth for the alert rules.
# Alertmanager only decides how those alerts are grouped, throttled, and delivered.
#
# Fill in the two placeholders below before use:
#   - bot_token: the token @BotFather gives you when you create a bot.
#   - chat_id:   the numeric ID of the chat/channel to send to (see the guide).
# See "Get alerts on Telegram" in monitoring-guide.md for the full setup.

global:
  resolve_timeout: 5m

route:
  receiver: telegram
  group_by: ["alertname"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

receivers:
  - name: telegram
    telegram_configs:
      - bot_token: "REPLACE_WITH_YOUR_BOT_TOKEN"   # from @BotFather
        # Replace with your numeric chat_id (integer, no quotes). The value below is a
        # placeholder that lets the config validate; it will not reach your chat until
        # you set your real chat_id (see the guide).
        chat_id: 123456789
        api_url: "https://api.telegram.org"
        parse_mode: HTML
        send_resolved: true
        # Concise, glanceable message: one compact block per alert in the group.
        # Iterate over .Alerts and use per-alert .Labels / .Annotations — NOT
        # .CommonLabels / .CommonAnnotations, which only carry fields identical across
        # every alert in the group, so per-alert fields (node, summary) would render blank
        # when grouped alerts differ. Emoji: critical -> red, warning -> yellow,
        # resolved -> check. Full remediation guidance lives in the guide's alert reference.
        message: |
          {{ range .Alerts }}{{ if eq .Status "resolved" }}✅ <b>RESOLVED:</b> {{ else if eq .Labels.severity "critical" }}🔴 <b>FIRING:</b> {{ else if eq .Labels.severity "warning" }}🟡 <b>FIRING:</b> {{ else }}🔴 <b>FIRING:</b> {{ end }}<b>{{ .Labels.alertname }}</b>
          <b>Severity:</b> {{ .Labels.severity }}{{ if .Labels.instance }}
          <b>Node:</b> <code>{{ .Labels.instance }}</code>{{ end }}
          {{ .Annotations.summary }}
          {{ end }}
AM_EOF
}

# ---- stack file writers ----
write_collector_config() { cat > "$1" <<'OTEL_EOF'
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318
exporters:
  prometheus:
    endpoint: 0.0.0.0:8889
processors:
  batch: {}
service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [prometheus]
OTEL_EOF
}

write_monitoring_compose() { cat > "$1" <<'MC_EOF'
services:
  grafana:
    image: grafana/grafana:11.4.0
    container_name: aztec-grafana
    ports: ["3000:3000"]
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana-provisioning:/etc/grafana/provisioning
      - ./dashboards:/var/lib/grafana/dashboards
    networks: [monitoring]
    restart: unless-stopped
  prometheus:
    image: prom/prometheus:v3.0.1
    container_name: aztec-prometheus
    ports: ["9090:9090"]
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
      - "--storage.tsdb.retention.time=15d"
      - "--web.enable-lifecycle"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./prometheus/rules:/etc/prometheus/rules:ro
      - prometheus-data:/prometheus
    networks: [monitoring]
    restart: unless-stopped
  alertmanager:
    image: prom/alertmanager:latest
    container_name: aztec-alertmanager
    ports: ["9093:9093"]
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    networks: [monitoring]
    restart: unless-stopped
networks:
  monitoring:
    driver: bridge
volumes:
  grafana-data:
  prometheus-data:
MC_EOF
}

write_prometheus_yml() { # $1=path $2=nodes-string (";"-joined "endpoint|label")
  # One aztec-node job with one static_configs block per node. Each block sets a
  # target-level `instance` label (labels: { instance: <label> }); with the default
  # honor_labels=false, that pins the dashboard series while the node's generated
  # service.instance.id is preserved as exported_instance. Verified against a live V5 node.
  local _path="$1" _nodes="$2" _blocks="" _ep _lb _oldifs
  _oldifs="$IFS"; IFS=';'
  for _n in $_nodes; do
    [ -z "$_n" ] && continue
    _ep="${_n%%|*}"; _lb="${_n#*|}"
    if [ -n "$_lb" ]; then
      _blocks="${_blocks}
      - targets: [\"${_ep}\"]
        labels:
          instance: \"${_lb}\""
    else
      _blocks="${_blocks}
      - targets: [\"${_ep}\"]"
    fi
  done
  IFS="$_oldifs"
  # Heredoc is UNQUOTED so ${_blocks} interpolates; _blocks holds only quotes/newlines
  # (no $ or backticks), so it is safe to expand here.
  cat > "$_path" <<PROM_EOF
global:
  scrape_interval: 15s
  evaluation_interval: 15s
rule_files:
  - "/etc/prometheus/rules/*.yml"
  - "/etc/prometheus/rules/*.yaml"
alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]
scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: "aztec-node"
    metrics_path: /metrics
    static_configs:${_blocks}
PROM_EOF
}

write_grafana_provisioning() { # $1=monitoring dir root
  mkdir -p "$1/grafana-provisioning/datasources" "$1/grafana-provisioning/dashboards" "$1/dashboards"
  cat > "$1/grafana-provisioning/datasources/prometheus.yml" <<'DS_EOF'
apiVersion: 1
datasources:
  - name: Prometheus
    uid: aztec-prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: true
DS_EOF
  cat > "$1/grafana-provisioning/dashboards/dashboards.yml" <<'DP_EOF'
apiVersion: 1
providers:
  - name: aztec
    orgId: 1
    folder: ""
    type: file
    disableDeletion: false
    editable: true
    options:
      path: /var/lib/grafana/dashboards
DP_EOF
  write_dashboard_json "$1/dashboards/aztec-v5-operator.json"
  sed_inplace 's/${DS_PROMETHEUS}/aztec-prometheus/g' "$1/dashboards/aztec-v5-operator.json"
}

# ---- preflight ----
have_cmd() { command -v "$1" >/dev/null 2>&1; }

require_docker() {
  if ! have_cmd docker; then
    c_red "Docker is not installed."
    if [ "$OS" = "macos" ]; then
      info "Install Docker Desktop: https://www.docker.com/products/docker-desktop/"
    else
      info "Install Docker Engine + the compose plugin for your distro, then re-run."
    fi
    return 1
  fi
  if ! docker compose version >/dev/null 2>&1; then
    c_red "The 'docker compose' plugin is not available."
    info "Install the Docker Compose v2 plugin, then re-run."
    return 1
  fi
  if ! docker info >/dev/null 2>&1; then
    c_red "Docker is installed but not running."
    [ "$OS" = "macos" ] && info "Start Docker Desktop and wait until it is ready."
    return 1
  fi
  return 0
}

# endpoint_up <host:port> — true if /metrics returns aztec_ series.
endpoint_up() {
  curl -fsS --max-time 8 "http://$1/metrics" 2>/dev/null | grep -q '^aztec_'
}

# wait_for_endpoint <host:port> <max tries> <seconds between tries> — poll endpoint_up
# until it answers; 0 on success, 1 on timeout. A keep-alive note lands every ~30s of
# sleep (every ceil(30/$3) tries) so a slow node restart does not read as a hang.
# Interval 0 would divide by zero, so it falls back to every 30 tries. No arrays (bash 3.2).
wait_for_endpoint() {
  local _ep="$1" _tries="$2" _sleep="$3" _i=0 _every
  # Malformed args must not abort under the runtime set -e (sleep '') or skip the
  # poll entirely (a test -lt error evaluates false): normalize instead.
  [ "$_tries" -gt 0 ] 2>/dev/null || _tries=1
  if [ "$_sleep" -gt 0 ] 2>/dev/null; then _every=$(( (30 + _sleep - 1) / _sleep )); else _every=30; _sleep=0; fi
  while [ "$_i" -lt "$_tries" ]; do
    endpoint_up "$_ep" && return 0
    _i=$((_i+1))
    if [ "$_i" -lt "$_tries" ]; then
      sleep "$_sleep"
      [ $((_i % _every)) -eq 0 ] && info "Still waiting — a restarting node can take several minutes to serve metrics..."
    fi
  done
  return 1
}

# ---- telegram ----
tg_extract_chat_id() { # $1=getUpdates json body -> prints chat.id or empty
  if have_cmd python3; then
    printf '%s' "$1" | python3 -c 'import json,sys
try:
    d=json.load(sys.stdin); r=d.get("result",[])
    print(r[-1]["message"]["chat"]["id"] if r else "")
except Exception:
    print("")'
  else
    printf '%s' "$1" | grep -o '"chat":{"id":[0-9-]*' | head -1 | grep -o '[0-9-]*$'
  fi
}

tg_get_me() { curl -fsS --max-time 10 "https://api.telegram.org/bot$1/getMe" 2>/dev/null | grep -q '"ok":true'; }
tg_get_updates() { curl -fsS --max-time 10 "https://api.telegram.org/bot$1/getUpdates" 2>/dev/null || printf ''; }
tg_webhook_url() { curl -fsS --max-time 10 "https://api.telegram.org/bot$1/getWebhookInfo" 2>/dev/null | grep -o '"url":"[^"]*"' | head -1 | sed 's/"url":"//; s/"$//'; }
tg_delete_webhook() { curl -fsS --max-time 10 "https://api.telegram.org/bot$1/deleteWebhook" >/dev/null 2>&1; }

tg_write_creds() { # $1=am.yml $2=token $3=chat_id
  sed_inplace "s|REPLACE_WITH_YOUR_BOT_TOKEN|$2|" "$1"
  sed_inplace "s|chat_id: 123456789|chat_id: $3|" "$1"
  chmod 600 "$1" 2>/dev/null || true
}

# Read the live values back out of alertmanager.yml. Match only the real config lines
# (leading whitespace), not the comment lines that also contain the words
# bot_token / chat_id. chat_id may be negative (group chats). Print nothing — and do
# not fail under set -e/pipefail — when the file or the line is missing.
am_read_token() { # $1=am.yml
  [ -f "$1" ] || return 0
  # sed -n/p: an unrecognized line (e.g. hand-edited unquoted token) must yield
  # nothing, never pass through as the whole line.
  grep -E '^[[:space:]]*- bot_token:' "$1" | head -1 | sed -n 's/.*"\(.*\)".*/\1/p' || true
}
am_read_chat_id() { # $1=am.yml
  [ -f "$1" ] || return 0
  grep -E '^[[:space:]]*chat_id:[[:space:]]*[0-9-]+' "$1" | head -1 | sed -n 's/.*chat_id:[[:space:]]*\([0-9-]*\).*/\1/p' || true
}

# Refresh alertmanager.yml from the embedded template without losing configured
# Telegram credentials: template changes still propagate on re-apply, but a real
# token/chat_id already in the file must survive (tg_write_creds keeps the 600 mode).
rewrite_alertmanager_preserving_creds() { # $1=am.yml
  local _amt _amc
  _amt="$(am_read_token "$1")"
  _amc="$(am_read_chat_id "$1")"
  write_alertmanager_yml "$1"
  # Re-inject only a plausible BotFather-charset token: sed-special characters
  # (|, &, \ — hand-edit only) would corrupt or abort tg_write_creds' sed.
  # chat_id is already constrained to [0-9-] by its capture group.
  case "$_amt" in ''|REPLACE_WITH_YOUR_BOT_TOKEN|*[!A-Za-z0-9:_-]*) return 0 ;; esac
  [ -n "$_amc" ] || return 0
  tg_write_creds "$1" "$_amt" "$_amc"
}

tg_send_test() { # $1=token $2=chat_id
  curl -fsS --max-time 12 -X POST "https://api.telegram.org/bot$1/sendMessage" \
    --data-urlencode "chat_id=$2" \
    --data-urlencode "text=Aztec monitoring: Telegram configured successfully." >/dev/null 2>&1
}

configure_telegram() { # $1=path to alertmanager.yml
  local _am="$1" _tok _wh _yn _chat _n _manual
  printf '\n'
  header "Set up Telegram alerts"
  info "You need a bot token and your chat id. If you do not have a bot yet:"
  info "  1. In Telegram, open @BotFather and send /newbot"
  info "  2. Follow the prompts (a display name, then a username ending in 'bot')"
  info "  3. BotFather replies with a bot TOKEN — copy it"
  info "  4. Open your new bot and press Start (or send /start) so it can message you"
  printf 'Telegram bot token (from @BotFather): '; read -r _tok
  if ! tg_get_me "$_tok"; then c_red "Token rejected by Telegram (getMe failed). Check you copied the whole token."; return 1; fi
  c_green "Token valid."
  info "In Telegram, open THIS bot and press Start (or send /start) if you have not already,"
  info "then send it any message. This is required before it can message you. Press Enter when done."
  read -r _
  _wh="$(tg_webhook_url "$_tok")"
  if [ -n "$_wh" ]; then
    c_yellow "A webhook is set ($_wh); getUpdates will be empty until it is removed."
    printf 'Delete the webhook now? [y/N]: '; read -r _yn
    case "$_yn" in y|Y) tg_delete_webhook "$_tok"; info "Webhook deleted. Send your bot another message, then press Enter."; read -r _ ;; esac
  fi
  _chat=""; _n=0
  while [ "$_n" -lt 3 ]; do
    _chat="$(tg_extract_chat_id "$(tg_get_updates "$_tok")")"
    [ -n "$_chat" ] && break
    c_yellow "No chat id yet. Make sure you pressed Start and sent a message."
    printf 'Press Enter to retry (or type the chat id manually): '; read -r _manual
    [ -n "$_manual" ] && { _chat="$_manual"; break; }
    _n=$((_n+1))
  done
  if [ -z "$_chat" ]; then c_red "Could not determine chat id."; return 1; fi
  info "Using chat id: $_chat"
  tg_write_creds "$_am" "$_tok" "$_chat"
  state_set TELEGRAM_CONFIGURED "yes"
  c_green "Telegram credentials written."
}

# ---- node-side ----

detect_node_service() { # $1=compose path -> prints service whose image looks like aztec, else first service
  if have_cmd python3; then
    python3 - "$1" <<'PY'
import sys
try:
    import yaml
except Exception:
    yaml=None
path=sys.argv[1]; name=""
if yaml:
    try:
        d=yaml.safe_load(open(path)) or {}
    except Exception:
        d={}
    svcs=d.get("services",{}) or {}
    for n,s in svcs.items():
        if "aztec" in str((s or {}).get("image","")).lower():
            name=n; break
    if not name and svcs:
        name=list(svcs.keys())[0]
print(name)
PY
  else
    # Fallback when python3 is unavailable. Service keys are indented under
    # "services:"; grab the first one. Skip blank/comment lines. Prefer a
    # service whose following lines reference an aztec image, else the first.
    awk '
      /^[[:space:]]*#/ { next }
      /^services:[[:space:]]*$/ { f=1; next }
      f && /^[^[:space:]]/ { exit }                      # left the services block
      f && /^[[:space:]]+[A-Za-z0-9_.-]+:[[:space:]]*$/ { # a service key
        line=$0; sub(/:[[:space:]]*$/,"",line); sub(/^[[:space:]]+/,"",line)
        if (first=="") first=line
        cur=line; next
      }
      f && cur!="" && tolower($0) ~ /image:.*aztec/ { print cur; done=1; exit }
      END { if (!done && first!="") print first }
    ' "$1"
  fi
}

detect_node_networks() { # $1=compose path $2=node_service -> prints network name(s) the node service is on (first is what we attach the collector to); empty = default network
  have_cmd python3 || return 0
  python3 - "$1" "$2" <<'PY'
import sys
try:
    import yaml
except Exception:
    yaml=None
path=sys.argv[1]; svc=sys.argv[2]; nets=[]
if yaml:
    try:
        d=yaml.safe_load(open(path)) or {}
    except Exception:
        d={}
    s=((d.get("services",{}) or {}).get(svc,{}) or {})
    n=s.get("networks")
    if isinstance(n,dict):
        nets=[str(k) for k in n.keys()]
    elif isinstance(n,list):
        # list entries are network names (strings); ignore non-strings defensively
        nets=[str(x) for x in n if isinstance(x,(str,int,float))]
    # if no networks key -> nets stays empty -> signal "use default"
print(" ".join(nets))
PY
}

write_node_override() { # $1=path $2=node_service $3=instance_name $4=node_network (may be empty)
  local _p="$1" _svc="$2" _inst="$3" _net="${4:-}"
  if [ -n "$_net" ]; then
    cat > "$_p" <<OV_EOF
# Added by aztec-monitoring.sh — exposes node metrics via an OpenTelemetry Collector.
# Docker Compose auto-merges this file with your base compose. Remove this file to undo.
services:
  ${_svc}:
    environment:
      - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://otel-collector:4318/v1/metrics
      - OTEL_SERVICE_NAME=aztec-sequencer
      - OTEL_RESOURCE_ATTRIBUTES=service.instance.id=${_inst}
    networks:
      - ${_net}
  otel-collector:
    image: otel/opentelemetry-collector-contrib:latest
    container_name: aztec-otel-collector
    command: ["--config=/etc/otel/config.yaml"]
    volumes:
      - ./otel-collector.yaml:/etc/otel/config.yaml:ro
    ports:
      - "8889:8889"
    networks:
      - ${_net}
    restart: unless-stopped
networks:
  ${_net}:
    external: true
OV_EOF
  else
    cat > "$_p" <<OV_EOF
# Added by aztec-monitoring.sh — exposes node metrics via an OpenTelemetry Collector.
# Docker Compose auto-merges this file with your base compose. Remove this file to undo.
services:
  ${_svc}:
    environment:
      - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://otel-collector:4318/v1/metrics
      - OTEL_SERVICE_NAME=aztec-sequencer
      - OTEL_RESOURCE_ATTRIBUTES=service.instance.id=${_inst}
  otel-collector:
    image: otel/opentelemetry-collector-contrib:latest
    container_name: aztec-otel-collector
    command: ["--config=/etc/otel/config.yaml"]
    volumes:
      - ./otel-collector.yaml:/etc/otel/config.yaml:ro
    ports:
      - "8889:8889"
    restart: unless-stopped
OV_EOF
  fi
}

setup_node() {
  [ "$OS" = "macos" ] && { c_yellow "Option 1 is for your Linux Aztec node, not this machine."; return 1; }
  require_docker || return 1
  state_load
  local _compose="${NODE_COMPOSE:-}" _dir _svc _net _default_inst _inst _ovr _yn
  if [ -z "$_compose" ]; then
    for c in ./docker-compose.yml ./compose.yml "$HOME/aztec/docker-compose.yml" "$HOME/.aztec/docker-compose.yml"; do
      [ -f "$c" ] && { _compose="$c"; break; }
    done
  fi
  if [ -z "$_compose" ] || [ ! -f "$_compose" ]; then
    printf 'Path to your Aztec node docker-compose.yml (absolute path, e.g. /root/aztec-sequencer/docker-compose.yml): '; read -r _compose
    case "$_compose" in
      "~/"*) _compose="$HOME/${_compose#\~/}" ;;
      "~") _compose="$HOME" ;;
    esac
  fi
  [ -f "$_compose" ] || { c_red "No compose file at: $_compose"; return 1; }
  _dir="$(cd "$(dirname "$_compose")" && pwd)"
  _svc="$(detect_node_service "$_compose")"
  [ -n "$_svc" ] || { c_red "Could not find a node service in the compose file."; return 1; }
  info "Node service: $_svc"
  _net="$(detect_node_networks "$_compose" "$_svc" | awk '{print $1}')"
  [ -n "$_net" ] && info "Node network: $_net (collector will join it)"
  # The node's service.instance.id is set below for future-proofing, but current node
  # versions override it with a generated value, so it does not name the dashboard series.
  # The dashboard instance label is pinned on the monitoring side (option 2). No prompt here.
  _inst="${NODE_INSTANCE:-$(hostname 2>/dev/null || echo aztec-node)}"
  _inst="$(printf '%s' "$_inst" | tr -d '\n\r' | tr -c 'A-Za-z0-9._-' '_')"
  write_collector_config "$_dir/otel-collector.yaml"
  _ovr="$_dir/docker-compose.override.yml"
  if [ -f "$_ovr" ]; then
    c_yellow "An override file already exists: $_ovr"
    cp "$_ovr" "$_ovr.bak.$(date +%s 2>/dev/null || echo backup).$$"
    info "Backed it up. This script will overwrite it with the metrics override."
    printf 'Continue? [y/N]: '; read -r _yn; case "$_yn" in y|Y) : ;; *) return 1;; esac
  fi
  write_node_override "$_ovr" "$_svc" "$_inst" "$_net"
  info "----- planned changes (docker-compose.override.yml) -----"
  cat "$_ovr"
  info "---------------------------------------------------------"
  printf 'Apply and restart the node with these changes? [y/N]: '; read -r _yn
  case "$_yn" in y|Y) : ;; *) c_yellow "Aborted; override written but not applied. Remove $_ovr to discard."; return 1;; esac
  if ( cd "$_dir" && docker compose up -d ); then
    state_set NODE_COMPOSE "$_compose"; state_set NODE_INSTANCE "$_inst"
  else
    c_red "docker compose up -d failed. Your override is at $_ovr."
    info "Review 'docker compose -f \"$_compose\" config', check that port 8889 is free, then re-run or remove the override to revert."
    return 1
  fi
  info "Waiting for metrics on localhost:8889 (a node restart can take several minutes)..."
  if wait_for_endpoint "localhost:8889" 60 5; then
    c_green "Metrics are live on localhost:8889/metrics."
    info "Allow your monitoring machine to reach this host on :8889 (private/firewalled, not public)."
    info "The dashboard's node label is set on the monitoring machine (option 2), not here."
  else
    c_yellow "No metrics on :8889 yet — the setup is applied and nothing needs re-running; the node is likely still starting."
    info "Re-check later with: curl -s localhost:8889/metrics | grep -c '^aztec_'  (or menu option 4)."
    info "Only if it stays empty well after the node finishes syncing, check 'docker compose logs otel-collector'."
  fi
}

# ---- monitoring-side ----
# Not "$HOME/aztec-monitoring": that is where a 'git clone' of this repo lands, and the
# stack must not write runtime files (including a creds-filled alertmanager.yml) into a
# git checkout.
MON_DIR_DEFAULT="$HOME/aztec-monitoring-stack"

setup_monitoring() {
  require_docker || return 1
  state_load
  local _dir="${MON_DIR:-$MON_DIR_DEFAULT}" _nodes _in _lb _yn _tok _cid _idx _n_count _choice _first_run=0
  # A git checkout of this repo must not become the stack directory: option 2 writes
  # runtime files there, including alertmanager.yml with real credentials, which a
  # 'git pull' or checkout would then fight with. Installs recorded in state keep
  # their directory (moving would orphan a running stack) but get a warning.
  if [ -e "$_dir/.git" ] || [ -f "$_dir/aztec-monitoring.sh" ]; then
    if [ -n "${MON_DIR:-}" ]; then
      c_yellow "Warning: your monitoring stack directory ($_dir) looks like a git checkout of this repo. Consider migrating (uninstall option 5, re-run option 2) so 'git pull' never conflicts with your live credentials."
    else
      c_yellow "$_dir looks like a git checkout of this repo; using $HOME/aztec-monitoring-stack for the stack instead."
      _dir="$HOME/aztec-monitoring-stack"
    fi
  fi
  mkdir -p "$_dir/prometheus/rules"
  # Working node list, seeded from state (with legacy single-node migration).
  _nodes="$(nodes_load_string)"
  # First run = no monitoring stack recorded yet.
  [ -z "${MON_DIR:-}" ] && _first_run=1

  # If there are no nodes yet, require at least the first one before showing the menu.
  if [ -z "$_nodes" ]; then
    header "Add your first Aztec node"
    while [ -z "$_nodes" ]; do
      printf 'Aztec node metrics endpoint (host:port, e.g. <node-ip>:8889): '
      read -r _in || { c_yellow "Cancelled; no changes applied."; return 0; }
      case "$_in" in
        *:*) : ;;
        *) c_yellow "That does not look like host:port (needs a ':'). Try again."; continue ;;
      esac
      case "$_in" in *[\;\|]*) c_yellow "Endpoint may not contain ';' or '|'. Try again."; continue ;; esac
      [ -n "$_in" ] || continue
      printf 'Pin a stable dashboard instance label for this node (optional, e.g. sequencer-1): '; read -r _lb
      [ -n "$_lb" ] && _lb="$(printf '%s' "$_lb" | tr -d '\n\r' | tr -c 'A-Za-z0-9._-' '_')"
      _nodes="$(node_list_append "$_nodes" "$_in" "$_lb")"
    done
  fi

  # Node-management loop.
  while :; do
    printf '\n'
    header "Nodes to monitor"
    node_list_print "$_nodes"
    printf '\n'
    info "  a) Add a node   r) Remove a node   d) Done (apply)   c) Cancel"
    printf 'Choose [a/r/d/c]: '
    read -r _choice || { c_yellow "Cancelled; no changes applied."; return 0; }
    case "$_choice" in
      a|A)
        printf 'Aztec node metrics endpoint (host:port, e.g. <node-ip>:8889): '; read -r _in
        case "$_in" in
          *:*) : ;;
          *) c_yellow "That does not look like host:port (needs a ':'). Not added."; continue ;;
        esac
        case "$_in" in *[\;\|]*) c_yellow "Endpoint may not contain ';' or '|'. Not added."; continue ;; esac
        [ -n "$_in" ] || { c_yellow "Empty endpoint; not added."; continue; }
        if node_list_has_endpoint "$_nodes" "$_in"; then
          c_yellow "This endpoint is already monitored."
          printf 'Add anyway? [y/N]: '; read -r _yn
          case "$_yn" in y|Y) : ;; *) c_yellow "Not added."; continue ;; esac
        fi
        printf 'Pin a stable dashboard instance label (optional, e.g. sequencer-2): '; read -r _lb
        [ -n "$_lb" ] && _lb="$(printf '%s' "$_lb" | tr -d '\n\r' | tr -c 'A-Za-z0-9._-' '_')"
        if node_list_has_label "$_nodes" "$_lb"; then
          c_yellow "Label '$_lb' is already used; two targets with the same instance label will collide on the dashboard."
          printf 'Add anyway? [y/N]: '; read -r _yn
          case "$_yn" in y|Y) : ;; *) c_yellow "Not added."; continue ;; esac
        fi
        _nodes="$(node_list_append "$_nodes" "$_in" "$_lb")"
        c_green "Added."
        ;;
      r|R)
        _n_count="$(node_list_count "$_nodes")"
        if [ "$_n_count" -le 0 ]; then c_yellow "No nodes to remove."; continue; fi
        printf 'Remove which? [1-%s] (or blank to cancel): ' "$_n_count"; read -r _idx
        case "$_idx" in
          ''|*[!0-9]*) c_yellow "Nothing removed."; continue ;;
        esac
        if [ "$_idx" -lt 1 ] || [ "$_idx" -gt "$_n_count" ]; then c_yellow "Out of range; nothing removed."; continue; fi
        _nodes="$(node_list_remove "$_nodes" "$_idx")"
        c_green "Removed."
        ;;
      d|D)
        if [ -z "$_nodes" ]; then c_yellow "You have no nodes; add at least one or cancel."; continue; fi
        break
        ;;
      c|C)
        c_yellow "Cancelled; no changes applied."
        return 0
        ;;
      *) c_yellow "Please choose a, r, d, or c." ;;
    esac
  done

  # Apply.
  write_monitoring_compose "$_dir/docker-compose.yml"
  write_prometheus_yml "$_dir/prometheus/prometheus.yml" "$_nodes"
  write_alerts_yaml "$_dir/prometheus/rules/alerts.yaml"
  rewrite_alertmanager_preserving_creds "$_dir/alertmanager.yml"
  write_grafana_provisioning "$_dir"
  state_set MON_DIR "$_dir"; state_set MON_NODES "$_nodes"
  # Legacy single-node keys are now fully represented by MON_NODES; drop them.
  state_unset NODE_ENDPOINT; state_unset MON_INSTANCE_NAME
  # Offer Telegram on first setup, or later if it is not yet configured.
  if [ "$_first_run" -eq 1 ] || [ "${TELEGRAM_CONFIGURED:-no}" != "yes" ]; then
    printf 'Set up Telegram alerts now? [Y/n]: '; read -r _yn
    case "$_yn" in
      n|N) c_yellow "Skipping Telegram; you can run menu option 3 later." ;;
      *) configure_telegram "$_dir/alertmanager.yml" || c_yellow "Telegram not configured; continuing." ;;
    esac
  fi
  if ( cd "$_dir" && docker compose up -d ); then
    c_green "Stack is up."
    # `up -d` recreates prometheus only if its compose definition changed, not when the
    # mounted prometheus.yml changed. Reload the running config so an edited node list is
    # picked up without a restart; fall back to a forced recreate if the reload signal fails.
    ( cd "$_dir" && docker compose exec -T prometheus kill -HUP 1 ) >/dev/null 2>&1 \
      || ( cd "$_dir" && docker compose up -d --force-recreate prometheus ) >/dev/null 2>&1 || true
    _myip="$(primary_ip)"
    printf '\n'
    header "Open the dashboard"
    info "  - On this machine:        http://localhost:3000"
    if [ -n "$_myip" ]; then
      info "  - From another computer:  http://$_myip:3000   (this machine's IP)"
    fi
    info "  Login: admin / admin  (change the password after first login)."
    info "  Prometheus: http://localhost:9090${_myip:+  (or http://$_myip:9090)}"
    info "  If this is a remote/cloud server, use its public IP, or tunnel with:"
    info "    ssh -L 3000:localhost:3000 <user>@<this-server>   then open http://localhost:3000"
  else
    c_red "docker compose up -d failed in $_dir. Check the compose output above for the cause:"
    info "  - image pull / 'failed to resolve reference' errors: this machine cannot reach docker.io — check network, VPN, and Docker's DNS (try 'docker pull alpine'), then re-run."
    info "  - port conflicts: ports 3000/9090/9093 must be free."
    info "  Nothing is lost — your settings are kept; re-run option 2 and apply once the cause is fixed."
    return 1
  fi
  info "Verifying the node scrape targets (this can take up to ~40s for the first scrape)..."
  _n_total="$(node_list_count "$_nodes")"
  _tgt_ok=0; _up=0; _i=0
  while [ "$_i" -lt 12 ]; do
    _up="$(curl -fsS --max-time 8 "http://localhost:9090/api/v1/targets" 2>/dev/null \
            | grep -o '"health":"up"' | grep -c . || true)"
    # localhost:9090 (prometheus self-scrape) is one of the "up" targets; require the
    # aztec-node targets to be up too, i.e. more ups than just prometheus itself.
    if [ "$_up" -ge $((_n_total + 1)) ]; then _tgt_ok=1; break; fi
    _i=$((_i+1)); sleep 4
  done
  if [ "$_tgt_ok" -eq 1 ]; then
    c_green "Prometheus targets are up ($_n_total node target(s) reporting)."
  else
    c_yellow "Not all node targets are up yet ($_up of $((_n_total + 1)) up, incl. prometheus). Check each node is reachable and firewall-open on :8889 (open http://localhost:9090/targets to inspect)."
  fi
  if [ "${TELEGRAM_CONFIGURED:-no}" = "yes" ]; then
    info "Firing a Telegram test alert..."
    _tok="$(am_read_token "$_dir/alertmanager.yml")"
    _cid="$(am_read_chat_id "$_dir/alertmanager.yml")"
    if [ -n "$_tok" ] && [ -n "$_cid" ] && [ "$_tok" != "REPLACE_WITH_YOUR_BOT_TOKEN" ]; then
      # retry a few times — a transient network blip should not read as "failed".
      _tg_ok=0; _j=0
      while [ "$_j" -lt 3 ]; do
        if tg_send_test "$_tok" "$_cid"; then _tg_ok=1; break; fi
        _j=$((_j+1)); sleep 3
      done
      if [ "$_tg_ok" -eq 1 ]; then
        c_green "Test message sent to Telegram."
      else
        c_yellow "Could not send a Telegram test message. The token and chat id are saved; check this machine can reach api.telegram.org, then re-test with menu option 3."
      fi
    fi
  fi
}

# ---- status / uninstall ----
show_status() {
  state_load
  header "Status"
  info "OS: $OS"
  info "State file: $STATE_FILE"
  [ -f "$STATE_FILE" ] && sed 's/^/  /' "$STATE_FILE"
  _nodes="$(nodes_load_string)"
  if [ -n "$_nodes" ]; then
    info "Monitored nodes:"
    node_list_print "$_nodes"
  fi
  if have_cmd docker && docker info >/dev/null 2>&1; then
    info "Containers:"
    docker ps --format '  {{.Names}}  {{.Status}}' | grep -E 'aztec-(grafana|prometheus|alertmanager|otel)' || info "  (none running)"
    if curl -fsS --max-time 5 http://localhost:9090/api/v1/targets >/dev/null 2>&1; then
      info "Prometheus target health:"
      curl -fsS http://localhost:9090/api/v1/targets 2>/dev/null | grep -o '"health":"[a-z]*"' | sort | uniq -c | sed 's/^/  /' || info "  (no targets reporting yet)"
    fi
  fi
  info "Telegram configured: ${TELEGRAM_CONFIGURED:-no}"
}

uninstall() {
  state_load
  local _u _d _yn
  printf 'Uninstall which? [1] node-side override  [2] monitoring stack  [c] cancel: '; read -r _u
  case "$_u" in
    1)
      if [ -n "${NODE_COMPOSE:-}" ]; then
        _d="$(dirname "$NODE_COMPOSE")"
        rm -f "$_d/docker-compose.override.yml" "$_d/otel-collector.yaml"
        # --remove-orphans drops the otel-collector service that is no longer in the
        # (now override-less) config; plain 'up -d' would leave it running.
        ( cd "$_d" && docker compose up -d --remove-orphans ) || c_yellow "Removed override, but 'docker compose up -d' reported an issue."
        # Belt-and-suspenders: remove the collector container directly in case it was not
        # tracked as a project orphan.
        docker rm -f aztec-otel-collector >/dev/null 2>&1 || true
        c_green "Removed node override + collector; your base compose was untouched."
        state_unset NODE_COMPOSE; state_unset NODE_INSTANCE
        state_prune_if_empty
      else
        c_yellow "No node install recorded in state."
      fi ;;
    2)
      if [ -n "${MON_DIR:-}" ] && [ -d "$MON_DIR" ]; then
        ( cd "$MON_DIR" && docker compose down ) || c_yellow "'docker compose down' reported an issue."
        printf 'Also delete %s? [y/N]: ' "$MON_DIR"; read -r _yn
        case "$_yn" in y|Y) rm -rf "$MON_DIR"; c_green "Deleted $MON_DIR." ;; *) c_green "Stack stopped; files kept." ;; esac
        state_unset MON_DIR; state_unset MON_NODES; state_unset NODE_ENDPOINT; state_unset MON_INSTANCE_NAME; state_unset TELEGRAM_CONFIGURED
        state_prune_if_empty
      else
        c_yellow "No monitoring install recorded in state."
      fi ;;
    *) info "Cancelled." ;;
  esac
}

# ---- lib-only guard: when sourced as a library, stop here (do not run main) ----
if [ "${AZTEC_MON_LIB_ONLY:-0}" = "1" ]; then
  return 0 2>/dev/null || true
fi

set -euo pipefail

main() {
  state_load
  while :; do
    printf '\n'
    printf '%s\n' "${_C_BOLD}${_C_CYAN}Aztec V5 Monitoring Setup${_C_RESET}"
    printf '%s\n' "${_C_DIM}─────────────────────────${_C_RESET}"
    printf '  %s1%s  Set up node metrics        %srun on your Aztec node (Linux)%s\n' "${_C_BOLD}" "${_C_RESET}" "${_C_DIM}" "${_C_RESET}"
    printf '  %s2%s  Set up monitoring stack    %srun on your monitoring machine%s\n' "${_C_BOLD}" "${_C_RESET}" "${_C_DIM}" "${_C_RESET}"
    printf '  %s3%s  Configure / test Telegram  %spush alerts to your phone%s\n' "${_C_BOLD}" "${_C_RESET}" "${_C_DIM}" "${_C_RESET}"
    printf '  %s4%s  Show status                %swhat is installed / running%s\n' "${_C_BOLD}" "${_C_RESET}" "${_C_DIM}" "${_C_RESET}"
    printf '  %s5%s  Uninstall%s\n' "${_C_BOLD}" "${_C_RESET}" ""
    printf '  %s6%s  Exit%s\n' "${_C_BOLD}" "${_C_RESET}" ""
    printf 'Choose: '
    read -r _c || exit 0
    case "$_c" in
      1) setup_node || true ;;
      2) setup_monitoring || true ;;
      3)
        state_load
        _amp="${MON_DIR:-$MON_DIR_DEFAULT}/alertmanager.yml"
        if [ -f "$_amp" ]; then
          # With saved credentials, "test" comes first — no re-pasting the token.
          _t3_tok="$(am_read_token "$_amp")"; _t3_cid="$(am_read_chat_id "$_amp")"
          _t3_reconf=1
          if [ -n "$_t3_tok" ] && [ "$_t3_tok" != "REPLACE_WITH_YOUR_BOT_TOKEN" ] && [ -n "$_t3_cid" ]; then
            info "Sending a test message with the saved Telegram settings..."
            if tg_send_test "$_t3_tok" "$_t3_cid"; then
              c_green "Test message sent to Telegram."
            else
              c_yellow "Could not send with the saved settings. Check this machine can reach api.telegram.org, or reconfigure below."
            fi
            printf 'Reconfigure Telegram credentials? [y/N]: '; read -r _yn
            case "$_yn" in y|Y) : ;; *) _t3_reconf=0 ;; esac
          fi
          if [ "$_t3_reconf" -eq 1 ]; then
            if configure_telegram "$_amp"; then
              ( cd "$(dirname "$_amp")" && docker compose up -d --force-recreate alertmanager >/dev/null 2>&1 ) || true
              c_green "Alertmanager reloaded with new Telegram settings."
              _t3_tok="$(am_read_token "$_amp")"; _t3_cid="$(am_read_chat_id "$_amp")"
              if [ -n "$_t3_tok" ] && [ "$_t3_tok" != "REPLACE_WITH_YOUR_BOT_TOKEN" ] && [ -n "$_t3_cid" ] && tg_send_test "$_t3_tok" "$_t3_cid"; then
                c_green "Test message sent to Telegram."
              fi
            fi
          fi
        else
          c_yellow "Set up the monitoring stack (option 2) first."
        fi || true ;;
      4) show_status || true ;;
      5) uninstall || true ;;
      6|q|Q) exit 0 ;;
      *) c_yellow "Pick 1-6." ;;
    esac
  done
}
main "$@"
