library(tidyverse); library(arrow); library(gt); library(ggrepel); library(scales)
options(cfb.lib_only = TRUE)
source("../R/02_team_game_metrics.R")
source("../R/04_storyline_engine.R")
source("../R/05_viz_style.R")

TEAM <- "Syracuse"; OPP <- "UConn"
SEASON <- params$season; WEEK <- params$week
FIG_DIR <- sprintf("figures/%d_wk%02d_story", SEASON, WEEK)
SCOPE   <- sprintf("%d Week %d | %s at %s (OT)", SEASON, WEEK, TEAM, OPP)
cur  <- read_parquet("~/cfb-data/processed/team_game_metrics_2026.parquet")
fbs  <- readRDS("~/cfb-data/fbs_teams_2026.rds")
p    <- read_parquet(sprintf("~/cfb-data/raw/pbp_inseason/pbp_%d_wk%02d.parquet",
                             SEASON, WEEK))

gid <- p$game_id[p$pos_team == TEAM][1]
g   <- p |> filter(game_id == gid)

peers <- cur |> filter(team %in% fbs, !low_volume, is_fbs_matchup, week == WEEK)
su5   <- cur |> filter(team == TEAM, week == WEEK)

secs_left <- function(m, s) m * 60 + coalesce(s, 0)

# Elapsed game time, so the whole game lays out on one axis.
g <- g |>
  mutate(
    sl      = secs_left(clock_minutes, clock_seconds),
    elapsed = (pmin(period, 4) - 1) * 900 + (900 - sl),
    elapsed = ifelse(period >= 5, 3600 + row_number() / n() * 300, elapsed),
    su_score  = ifelse(pos_team == TEAM, pos_team_score, def_pos_team_score),
    opp_score = ifelse(pos_team == TEAM, def_pos_team_score, pos_team_score)
  )

Exhibit 1 — The shape of the game

# Running score across elapsed game time. The flat orange stretch IS the story.
# A running score can only go up. Some plays carry corrupted score fields --
# raw values dip and recover, producing impossible spikes -- so the series is
# forced monotonic with cummax() before plotting.
tl <- g |>
  filter(!is.na(su_score), !is.na(opp_score), period <= 4) |>
  arrange(elapsed) |>
  mutate(Syracuse = cummax(su_score), UConn = cummax(opp_score)) |>
  select(elapsed, Syracuse, UConn) |>
  pivot_longer(-elapsed, names_to = "team", values_to = "score")

# Drought window: from Syracuse's last regulation score to the end of regulation
su_scores <- tl |> filter(team == "Syracuse")
last_pts  <- max(su_scores$score, na.rm = TRUE)
drought_start <- min(su_scores$elapsed[su_scores$score == last_pts], na.rm = TRUE)

# Both teams finish regulation tied at 34, so the end labels would print on top
# of one another. Separate them vertically rather than letting them collide.
ends <- tl |> group_by(team) |> slice_max(elapsed, n = 1) |> ungroup() |>
  mutate(lab_y = score + ifelse(team == "Syracuse", 2.6, -2.6))

p_timeline <- ggplot(tl, aes(elapsed, score, color = team)) +
  annotate("rect", xmin = drought_start, xmax = 3600, ymin = -Inf, ymax = Inf,
           fill = SU$orange, alpha = 0.08) +
  annotate("text", x = (drought_start + 3600) / 2, y = 5,
           label = sprintf("%d minutes without a point", round((3600 - drought_start) / 60)),
           size = 3.4, fontface = "italic", color = SU$ink2) +
  geom_step(linewidth = 1.1) +
  geom_text(data = ends, aes(y = lab_y, label = sprintf("%s %d", team, score)),
            hjust = -0.08, size = 3.6, fontface = "bold") +
  scale_color_manual(values = c(Syracuse = SU$orange, UConn = SU$blue), guide = "none") +
  scale_x_continuous(breaks = seq(0, 3600, 900),
                     labels = c("Kickoff", "End Q1", "Half", "End Q3", "End Q4"),
                     expand = expansion(mult = c(0.02, 0.12))) +
  labs(
    title = "Syracuse scored four touchdowns in the first half, then nothing until overtime",
    subtitle = sprintf(
      "Running score through regulation | Shaded: %d minutes of game clock in which Syracuse did not score and %s scored 20",
      round((3600 - drought_start) / 60), OPP),
    x = NULL, y = "Points",
    caption = su_caption(SCOPE)
  ) +
  theme_su(legend_pos = "none")

save_fig(p_timeline, "01_game_timeline", height = 5.2)

Syracuse led by as many as three scores. UConn scored 20 unanswered to force overtime, where Syracuse scored first and held on.

Exhibit 2 — The mechanism: the passing game, by half

halves <- g |>
  select(all_of(intersect(NEEDED, names(g))), period) |>
  filter(pos_team == TEAM) |>
  classify_plays() |>
  filter(is_scrimmage, period <= 4) |>
  mutate(half = ifelse(period <= 2, "First half", "Second half"),
         type = ifelse(pass == 1, "Pass", "Rush")) |>
  group_by(half, type) |>
  summarise(plays = n(), sr = mean(success, na.rm = TRUE),
            epa = mean(EPA, na.rm = TRUE), .groups = "drop")

p_half <- ggplot(halves, aes(x = half, y = epa, fill = type)) +
  geom_hline(yintercept = 0, color = SU$muted, linewidth = 0.4) +
  geom_col(position = position_dodge(width = 0.72), width = 0.62) +
  geom_text(aes(label = sprintf("%+.3f\n%.0f%% success\n%d plays", epa, 100 * sr, plays),
                vjust = ifelse(epa >= 0, -0.25, 1.15)),
            position = position_dodge(width = 0.72),
            size = 3.1, fontface = "bold", lineheight = 0.95, color = SU$ink) +
  scale_fill_manual(values = c(Pass = SU$orange, Rush = SU$blue)) +
  scale_y_continuous(expand = expansion(mult = c(0.3, 0.3))) +
  labs(
    title = "The run game was slightly better after halftime. The passing game fell off a cliff.",
    subtitle = "EPA per play by half | Regulation only | Higher is better",
    x = NULL, y = "EPA per play", fill = NULL,
    caption = su_caption(SCOPE)
  ) +
  theme_su(legend_pos = "top")

save_fig(p_half, "02_passing_by_half", height = 5)

Exhibit 3 — Four possessions, zero points

drives <- g |>
  mutate(sl = secs_left(clock_minutes, clock_seconds)) |>
  group_by(drive_id) |>
  summarise(team = first(pos_team), per = first(period), clk = first(sl),
            start = first(drive_start_yards_to_goal),
            closest = suppressWarnings(min(yards_to_goal, na.rm = TRUE)),
            plays = n(), result = first(drive_result), pts = first(drive_pts),
            .groups = "drop") |>
  filter(!is.na(team)) |>
  arrange(per, desc(clk))

su_dr  <- drives |> filter(team == TEAM, per <= 4)
last_i <- max(which(su_dr$pts > 0))
drought <- su_dr |> slice((last_i + 1):n())

opp_pts <- drives |>
  filter(team != TEAM, per <= 4,
         per > su_dr$per[last_i] |
           (per == su_dr$per[last_i] & clk < su_dr$clk[last_i])) |>
  summarise(x = sum(pts, na.rm = TRUE)) |> pull(x)

drought |>
  transmute(
    When = sprintf("Q%d %02d:%02d", per, clk %/% 60, clk %% 60),
    `Started at` = sprintf("own %.0f", 100 - start),
    `Got as far as` = ifelse(is.finite(closest) & closest <= 50,
                             sprintf("the %s %.0f", OPP, closest),
                             sprintf("own %.0f", 100 - closest)),
    Plays = plays,
    Result = result
  ) |>
  gt() |>
  tab_header(
    title = md("**After the opening drive of the second half, Syracuse ran four possessions and scored on none of them**"),
    subtitle = md(sprintf("UConn scored %d points over the same stretch", opp_pts))
  ) |>
  cols_align("center", columns = Plays) |>
  cols_align("left", columns = c(When, `Started at`, `Got as far as`, Result)) |>
  tab_style(style = list(cell_fill(color = "#FFF3E6"), cell_text(weight = "bold")),
            locations = cells_body(rows = Result %in% c("INT", "DOWNS", "MISSED FG"))) |>
  tab_source_note(md(paste0("**", su_caption(SCOPE), "**"))) |>
  gt_theme_su()
After the opening drive of the second half, Syracuse ran four possessions and scored on none of them
UConn scored 20 points over the same stretch
When Started at Got as far as Plays Result
Q3 03:46 own 25 own 35 2 INT
Q3 03:07 own 22 own 43 6 DOWNS
Q4 14:55 own 25 own 45 9 PUNT
Q4 01:36 own 38 the UConn 25 12 MISSED FG
Data: CollegeFootballData via cfbfastR | 2026 Week 5 | Syracuse at UConn (OT)

Exhibit 4 — The scoring-opportunity recovery

season <- cur |> filter(team == TEAM) |> arrange(week)

wk_rank <- function(w) {
  pg <- cur |> filter(team %in% fbs, !low_volume, week == w,
                      is_fbs_matchup == (w != 1))
  as.integer(round(rank(-pg$off_pts_per_opp,
                        na.last = "keep")[pg$team == TEAM]))
}
wk_n <- function(w) {
  nrow(cur |> filter(team %in% fbs, !low_volume, week == w,
                     is_fbs_matchup == (w != 1)))
}

tibble::tibble(
  Game = c("Wk 1 — New Hampshire (FCS)", "Wk 2 — California",
           "Wk 3 — Pittsburgh", "Wk 5 — UConn"),
  `Scoring opportunities` = season$off_scoring_opps,
  `Points per opportunity` = season$off_pts_per_opp,
  Rank = map_chr(season$week, \(w) sprintf("%s of %d",
                                           scales::ordinal(wk_rank(w)), wk_n(w)))
) |>
  gt() |>
  tab_header(
    title = md("**Syracuse went from 99th in the country at finishing drives to 22nd in one week**"),
    subtitle = md("Points per trip inside the opponent's 40 | Ranks are among teams facing the same opponent class that week")
  ) |>
  fmt_number(columns = `Points per opportunity`, decimals = 2) |>
  cols_align("center", columns = -Game) |>
  tab_style(style = cell_text(weight = "bold"), locations = cells_body(columns = Game)) |>
  tab_style(style = list(cell_fill(color = "#FFF3E6"), cell_text(weight = "bold")),
            locations = cells_body(rows = Game == "Wk 5 — UConn")) |>
  data_color(columns = `Points per opportunity`, method = "numeric", palette = SU_SEQ) |>
  tab_source_note(md(paste0("**", su_caption("2026 Weeks 1-5"),
    "** — Week 1 is compared against FBS teams facing FCS opponents; the rest against FBS-vs-FBS."))) |>
  gt_theme_su()
Syracuse went from 99th in the country at finishing drives to 22nd in one week
Points per trip inside the opponent’s 40 | Ranks are among teams facing the same opponent class that week
Game Scoring opportunities Points per opportunity Rank
Wk 1 — New Hampshire (FCS) 11 5.18 21st of 48
Wk 2 — California 8 2.25 84th of 98
Wk 3 — Pittsburgh 7 1.86 100th of 114
Wk 5 — UConn 7 5.00 22nd of 112
Data: CollegeFootballData via cfbfastR | 2026 Weeks 1-5 — Week 1 is compared against FBS teams facing FCS opponents; the rest against FBS-vs-FBS.

Exhibit 5 — The caveat: outplayed, and won anyway

pr <- function(col, hb = TRUE) {
  v <- peers[[col]]
  as.integer(round(rank(if (hb) -v else v, na.last = "keep")[peers$team == TEAM]))
}

tibble::tibble(
  Metric = c("Offensive success rate", "Points per scoring opportunity",
             "Defensive EPA allowed per play", "Net EPA per play"),
  Value = c(su5$off_success_rate, su5$off_pts_per_opp,
            su5$def_epa_play, su5$net_epa_play),
  Rank = c(sprintf("%s of %d", scales::ordinal(pr("off_success_rate")), nrow(peers)),
           sprintf("%s of %d", scales::ordinal(pr("off_pts_per_opp")), nrow(peers)),
           sprintf("%s of %d", scales::ordinal(pr("def_epa_play", FALSE)), nrow(peers)),
           sprintf("%s of %d", scales::ordinal(pr("net_epa_play")), nrow(peers)))
) |>
  gt() |>
  tab_header(
    title = md("**The offense was among the best in the country. The team was not.**"),
    subtitle = md("Syracuse was outplayed on a per-play basis and won in overtime — the mirror image of the California loss")
  ) |>
  fmt_number(columns = Value, decimals = 3) |>
  cols_align("center", columns = -Metric) |>
  tab_style(style = cell_text(weight = "bold"), locations = cells_body(columns = Metric)) |>
  tab_source_note(md(paste0("**", su_caption(SCOPE),
    "** — ranks among FBS teams that played FBS opponents in Week 5."))) |>
  gt_theme_su()
The offense was among the best in the country. The team was not.
Syracuse was outplayed on a per-play basis and won in overtime — the mirror image of the California loss
Metric Value Rank
Offensive success rate 0.506 20th of 112
Points per scoring opportunity 5.000 22nd of 112
Defensive EPA allowed per play 0.178 93rd of 112
Net EPA per play −0.195 92nd of 112
Data: CollegeFootballData via cfbfastR | 2026 Week 5 | Syracuse at UConn (OT) — ranks among FBS teams that played FBS opponents in Week 5.

Figures written to disk

figs <- list.files(FIG_DIR, pattern = "\\.png$", full.names = TRUE)
if (length(figs) == 0) cat("No figures written.\n") else {
  cat("300-dpi PNGs ready for the piece:\n\n")
  for (f in figs) cat("  ", f, "  (", round(file.info(f)$size/1024), " KB)\n", sep = "")
  cat("\nCopy the gt tables from the browser into Google Docs — they paste as\n")
  cat("native editable tables you can restyle.\n")
}
## 300-dpi PNGs ready for the piece:
## 
##   figures/2026_wk05_story/01_game_timeline.png  (111 KB)
##   figures/2026_wk05_story/02_passing_by_half.png  (125 KB)
## 
## Copy the gt tables from the browser into Google Docs — they paste as
## native editable tables you can restyle.
LS0tCnRpdGxlOiAiVGhpcnR5IEdvb2QgTWludXRlcywgVGhlbiBOb3RoaW5nIgpzdWJ0aXRsZTogIldlZWsgNSAyMDI2IOKAlCBTeXJhY3VzZSA0MiwgVUNvbm4gNDEgKE9UKSDigJQgZXhoaWJpdHMgZm9yIHB1YmxpY2F0aW9uIgphdXRob3I6ICJDaHJpcyBKaW1lbmV6IgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiCnBhcmFtczoKICBzZWFzb246IDIwMjYKICB3ZWVrOiA1Cm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGZsYXRseQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyBFTkNPRElORzogYSBzaGVsbCB3aXRoIG5vIExBTkcgc2V0IHN0YXJ0cyBSIGluIHRoZSBDIC8gVVMtQVNDSUkgbG9jYWxlLCBhbmQKIyBndCBhbmQgZ2dwbG90IHRoZW4gRVNDQVBFIGV2ZXJ5IG5vbi1BU0NJSSBjaGFyYWN0ZXIuIEZvcmNlIFVURi04IHNvIGVtIGRhc2hlcwojIHN1cnZpdmUgaW50byBwdWJsaWNhdGlvbi1yZWFkeSBvdXRwdXQuCmZvciAobG9jIGluIGMoImVuX1VTLlVURi04IiwgIkMuVVRGLTgiLCAiVVRGLTgiKSkgewogIGlmIChuemNoYXIoc3VwcHJlc3NXYXJuaW5ncyhTeXMuc2V0bG9jYWxlKCJMQ19BTEwiLCBsb2MpKSkpIGJyZWFrCn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gNiwgZHBpID0gMTUwKQpgYGAKCmBgYHtyIGxpYnJhcmllc30KbGlicmFyeSh0aWR5dmVyc2UpOyBsaWJyYXJ5KGFycm93KTsgbGlicmFyeShndCk7IGxpYnJhcnkoZ2dyZXBlbCk7IGxpYnJhcnkoc2NhbGVzKQpgYGAKCmBgYHtyIHN0eWxlfQpvcHRpb25zKGNmYi5saWJfb25seSA9IFRSVUUpCnNvdXJjZSgiLi4vUi8wMl90ZWFtX2dhbWVfbWV0cmljcy5SIikKc291cmNlKCIuLi9SLzA0X3N0b3J5bGluZV9lbmdpbmUuUiIpCnNvdXJjZSgiLi4vUi8wNV92aXpfc3R5bGUuUiIpCgpURUFNIDwtICJTeXJhY3VzZSI7IE9QUCA8LSAiVUNvbm4iClNFQVNPTiA8LSBwYXJhbXMkc2Vhc29uOyBXRUVLIDwtIHBhcmFtcyR3ZWVrCkZJR19ESVIgPC0gc3ByaW50ZigiZmlndXJlcy8lZF93ayUwMmRfc3RvcnkiLCBTRUFTT04sIFdFRUspClNDT1BFICAgPC0gc3ByaW50ZigiJWQgV2VlayAlZCB8ICVzIGF0ICVzIChPVCkiLCBTRUFTT04sIFdFRUssIFRFQU0sIE9QUCkKYGBgCgpgYGB7ciBkYXRhfQpjdXIgIDwtIHJlYWRfcGFycXVldCgifi9jZmItZGF0YS9wcm9jZXNzZWQvdGVhbV9nYW1lX21ldHJpY3NfMjAyNi5wYXJxdWV0IikKZmJzICA8LSByZWFkUkRTKCJ+L2NmYi1kYXRhL2Zic190ZWFtc18yMDI2LnJkcyIpCnAgICAgPC0gcmVhZF9wYXJxdWV0KHNwcmludGYoIn4vY2ZiLWRhdGEvcmF3L3BicF9pbnNlYXNvbi9wYnBfJWRfd2slMDJkLnBhcnF1ZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQVNPTiwgV0VFSykpCgpnaWQgPC0gcCRnYW1lX2lkW3AkcG9zX3RlYW0gPT0gVEVBTV1bMV0KZyAgIDwtIHAgfD4gZmlsdGVyKGdhbWVfaWQgPT0gZ2lkKQoKcGVlcnMgPC0gY3VyIHw+IGZpbHRlcih0ZWFtICVpbiUgZmJzLCAhbG93X3ZvbHVtZSwgaXNfZmJzX21hdGNodXAsIHdlZWsgPT0gV0VFSykKc3U1ICAgPC0gY3VyIHw+IGZpbHRlcih0ZWFtID09IFRFQU0sIHdlZWsgPT0gV0VFSykKCnNlY3NfbGVmdCA8LSBmdW5jdGlvbihtLCBzKSBtICogNjAgKyBjb2FsZXNjZShzLCAwKQoKIyBFbGFwc2VkIGdhbWUgdGltZSwgc28gdGhlIHdob2xlIGdhbWUgbGF5cyBvdXQgb24gb25lIGF4aXMuCmcgPC0gZyB8PgogIG11dGF0ZSgKICAgIHNsICAgICAgPSBzZWNzX2xlZnQoY2xvY2tfbWludXRlcywgY2xvY2tfc2Vjb25kcyksCiAgICBlbGFwc2VkID0gKHBtaW4ocGVyaW9kLCA0KSAtIDEpICogOTAwICsgKDkwMCAtIHNsKSwKICAgIGVsYXBzZWQgPSBpZmVsc2UocGVyaW9kID49IDUsIDM2MDAgKyByb3dfbnVtYmVyKCkgLyBuKCkgKiAzMDAsIGVsYXBzZWQpLAogICAgc3Vfc2NvcmUgID0gaWZlbHNlKHBvc190ZWFtID09IFRFQU0sIHBvc190ZWFtX3Njb3JlLCBkZWZfcG9zX3RlYW1fc2NvcmUpLAogICAgb3BwX3Njb3JlID0gaWZlbHNlKHBvc190ZWFtID09IFRFQU0sIGRlZl9wb3NfdGVhbV9zY29yZSwgcG9zX3RlYW1fc2NvcmUpCiAgKQpgYGAKCiMjIEV4aGliaXQgMSDigJQgVGhlIHNoYXBlIG9mIHRoZSBnYW1lCgpgYGB7ciBleGhpYml0LTEsIGZpZy5hc3AgPSAwLjUyfQojIFJ1bm5pbmcgc2NvcmUgYWNyb3NzIGVsYXBzZWQgZ2FtZSB0aW1lLiBUaGUgZmxhdCBvcmFuZ2Ugc3RyZXRjaCBJUyB0aGUgc3RvcnkuCiMgQSBydW5uaW5nIHNjb3JlIGNhbiBvbmx5IGdvIHVwLiBTb21lIHBsYXlzIGNhcnJ5IGNvcnJ1cHRlZCBzY29yZSBmaWVsZHMgLS0KIyByYXcgdmFsdWVzIGRpcCBhbmQgcmVjb3ZlciwgcHJvZHVjaW5nIGltcG9zc2libGUgc3Bpa2VzIC0tIHNvIHRoZSBzZXJpZXMgaXMKIyBmb3JjZWQgbW9ub3RvbmljIHdpdGggY3VtbWF4KCkgYmVmb3JlIHBsb3R0aW5nLgp0bCA8LSBnIHw+CiAgZmlsdGVyKCFpcy5uYShzdV9zY29yZSksICFpcy5uYShvcHBfc2NvcmUpLCBwZXJpb2QgPD0gNCkgfD4KICBhcnJhbmdlKGVsYXBzZWQpIHw+CiAgbXV0YXRlKFN5cmFjdXNlID0gY3VtbWF4KHN1X3Njb3JlKSwgVUNvbm4gPSBjdW1tYXgob3BwX3Njb3JlKSkgfD4KICBzZWxlY3QoZWxhcHNlZCwgU3lyYWN1c2UsIFVDb25uKSB8PgogIHBpdm90X2xvbmdlcigtZWxhcHNlZCwgbmFtZXNfdG8gPSAidGVhbSIsIHZhbHVlc190byA9ICJzY29yZSIpCgojIERyb3VnaHQgd2luZG93OiBmcm9tIFN5cmFjdXNlJ3MgbGFzdCByZWd1bGF0aW9uIHNjb3JlIHRvIHRoZSBlbmQgb2YgcmVndWxhdGlvbgpzdV9zY29yZXMgPC0gdGwgfD4gZmlsdGVyKHRlYW0gPT0gIlN5cmFjdXNlIikKbGFzdF9wdHMgIDwtIG1heChzdV9zY29yZXMkc2NvcmUsIG5hLnJtID0gVFJVRSkKZHJvdWdodF9zdGFydCA8LSBtaW4oc3Vfc2NvcmVzJGVsYXBzZWRbc3Vfc2NvcmVzJHNjb3JlID09IGxhc3RfcHRzXSwgbmEucm0gPSBUUlVFKQoKIyBCb3RoIHRlYW1zIGZpbmlzaCByZWd1bGF0aW9uIHRpZWQgYXQgMzQsIHNvIHRoZSBlbmQgbGFiZWxzIHdvdWxkIHByaW50IG9uIHRvcAojIG9mIG9uZSBhbm90aGVyLiBTZXBhcmF0ZSB0aGVtIHZlcnRpY2FsbHkgcmF0aGVyIHRoYW4gbGV0dGluZyB0aGVtIGNvbGxpZGUuCmVuZHMgPC0gdGwgfD4gZ3JvdXBfYnkodGVhbSkgfD4gc2xpY2VfbWF4KGVsYXBzZWQsIG4gPSAxKSB8PiB1bmdyb3VwKCkgfD4KICBtdXRhdGUobGFiX3kgPSBzY29yZSArIGlmZWxzZSh0ZWFtID09ICJTeXJhY3VzZSIsIDIuNiwgLTIuNikpCgpwX3RpbWVsaW5lIDwtIGdncGxvdCh0bCwgYWVzKGVsYXBzZWQsIHNjb3JlLCBjb2xvciA9IHRlYW0pKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gZHJvdWdodF9zdGFydCwgeG1heCA9IDM2MDAsIHltaW4gPSAtSW5mLCB5bWF4ID0gSW5mLAogICAgICAgICAgIGZpbGwgPSBTVSRvcmFuZ2UsIGFscGhhID0gMC4wOCkgKwogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IChkcm91Z2h0X3N0YXJ0ICsgMzYwMCkgLyAyLCB5ID0gNSwKICAgICAgICAgICBsYWJlbCA9IHNwcmludGYoIiVkIG1pbnV0ZXMgd2l0aG91dCBhIHBvaW50Iiwgcm91bmQoKDM2MDAgLSBkcm91Z2h0X3N0YXJ0KSAvIDYwKSksCiAgICAgICAgICAgc2l6ZSA9IDMuNCwgZm9udGZhY2UgPSAiaXRhbGljIiwgY29sb3IgPSBTVSRpbmsyKSArCiAgZ2VvbV9zdGVwKGxpbmV3aWR0aCA9IDEuMSkgKwogIGdlb21fdGV4dChkYXRhID0gZW5kcywgYWVzKHkgPSBsYWJfeSwgbGFiZWwgPSBzcHJpbnRmKCIlcyAlZCIsIHRlYW0sIHNjb3JlKSksCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMDgsIHNpemUgPSAzLjYsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoU3lyYWN1c2UgPSBTVSRvcmFuZ2UsIFVDb25uID0gU1UkYmx1ZSksIGd1aWRlID0gIm5vbmUiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjAwLCA5MDApLAogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJLaWNrb2ZmIiwgIkVuZCBRMSIsICJIYWxmIiwgIkVuZCBRMyIsICJFbmQgUTQiKSwKICAgICAgICAgICAgICAgICAgICAgZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDIsIDAuMTIpKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJTeXJhY3VzZSBzY29yZWQgZm91ciB0b3VjaGRvd25zIGluIHRoZSBmaXJzdCBoYWxmLCB0aGVuIG5vdGhpbmcgdW50aWwgb3ZlcnRpbWUiLAogICAgc3VidGl0bGUgPSBzcHJpbnRmKAogICAgICAiUnVubmluZyBzY29yZSB0aHJvdWdoIHJlZ3VsYXRpb24gfCBTaGFkZWQ6ICVkIG1pbnV0ZXMgb2YgZ2FtZSBjbG9jayBpbiB3aGljaCBTeXJhY3VzZSBkaWQgbm90IHNjb3JlIGFuZCAlcyBzY29yZWQgMjAiLAogICAgICByb3VuZCgoMzYwMCAtIGRyb3VnaHRfc3RhcnQpIC8gNjApLCBPUFApLAogICAgeCA9IE5VTEwsIHkgPSAiUG9pbnRzIiwKICAgIGNhcHRpb24gPSBzdV9jYXB0aW9uKFNDT1BFKQogICkgKwogIHRoZW1lX3N1KGxlZ2VuZF9wb3MgPSAibm9uZSIpCgpzYXZlX2ZpZyhwX3RpbWVsaW5lLCAiMDFfZ2FtZV90aW1lbGluZSIsIGhlaWdodCA9IDUuMikKYGBgCgpTeXJhY3VzZSBsZWQgYnkgYXMgbWFueSBhcyB0aHJlZSBzY29yZXMuIFVDb25uIHNjb3JlZCAyMCB1bmFuc3dlcmVkIHRvIGZvcmNlCm92ZXJ0aW1lLCB3aGVyZSBTeXJhY3VzZSBzY29yZWQgZmlyc3QgYW5kIGhlbGQgb24uCgojIyBFeGhpYml0IDIg4oCUIFRoZSBtZWNoYW5pc206IHRoZSBwYXNzaW5nIGdhbWUsIGJ5IGhhbGYKCmBgYHtyIGV4aGliaXQtMiwgZmlnLmFzcCA9IDAuNX0KaGFsdmVzIDwtIGcgfD4KICBzZWxlY3QoYWxsX29mKGludGVyc2VjdChORUVERUQsIG5hbWVzKGcpKSksIHBlcmlvZCkgfD4KICBmaWx0ZXIocG9zX3RlYW0gPT0gVEVBTSkgfD4KICBjbGFzc2lmeV9wbGF5cygpIHw+CiAgZmlsdGVyKGlzX3NjcmltbWFnZSwgcGVyaW9kIDw9IDQpIHw+CiAgbXV0YXRlKGhhbGYgPSBpZmVsc2UocGVyaW9kIDw9IDIsICJGaXJzdCBoYWxmIiwgIlNlY29uZCBoYWxmIiksCiAgICAgICAgIHR5cGUgPSBpZmVsc2UocGFzcyA9PSAxLCAiUGFzcyIsICJSdXNoIikpIHw+CiAgZ3JvdXBfYnkoaGFsZiwgdHlwZSkgfD4KICBzdW1tYXJpc2UocGxheXMgPSBuKCksIHNyID0gbWVhbihzdWNjZXNzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBlcGEgPSBtZWFuKEVQQSwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICJkcm9wIikKCnBfaGFsZiA8LSBnZ3Bsb3QoaGFsdmVzLCBhZXMoeCA9IGhhbGYsIHkgPSBlcGEsIGZpbGwgPSB0eXBlKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gU1UkbXV0ZWQsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjcyKSwgd2lkdGggPSAwLjYyKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHNwcmludGYoIiUrLjNmXG4lLjBmJSUgc3VjY2Vzc1xuJWQgcGxheXMiLCBlcGEsIDEwMCAqIHNyLCBwbGF5cyksCiAgICAgICAgICAgICAgICB2anVzdCA9IGlmZWxzZShlcGEgPj0gMCwgLTAuMjUsIDEuMTUpKSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNzIpLAogICAgICAgICAgICBzaXplID0gMy4xLCBmb250ZmFjZSA9ICJib2xkIiwgbGluZWhlaWdodCA9IDAuOTUsIGNvbG9yID0gU1UkaW5rKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhQYXNzID0gU1Ukb3JhbmdlLCBSdXNoID0gU1UkYmx1ZSkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMywgMC4zKSkpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVGhlIHJ1biBnYW1lIHdhcyBzbGlnaHRseSBiZXR0ZXIgYWZ0ZXIgaGFsZnRpbWUuIFRoZSBwYXNzaW5nIGdhbWUgZmVsbCBvZmYgYSBjbGlmZi4iLAogICAgc3VidGl0bGUgPSAiRVBBIHBlciBwbGF5IGJ5IGhhbGYgfCBSZWd1bGF0aW9uIG9ubHkgfCBIaWdoZXIgaXMgYmV0dGVyIiwKICAgIHggPSBOVUxMLCB5ID0gIkVQQSBwZXIgcGxheSIsIGZpbGwgPSBOVUxMLAogICAgY2FwdGlvbiA9IHN1X2NhcHRpb24oU0NPUEUpCiAgKSArCiAgdGhlbWVfc3UobGVnZW5kX3BvcyA9ICJ0b3AiKQoKc2F2ZV9maWcocF9oYWxmLCAiMDJfcGFzc2luZ19ieV9oYWxmIiwgaGVpZ2h0ID0gNSkKYGBgCgojIyBFeGhpYml0IDMg4oCUIEZvdXIgcG9zc2Vzc2lvbnMsIHplcm8gcG9pbnRzCgpgYGB7ciBleGhpYml0LTN9CmRyaXZlcyA8LSBnIHw+CiAgbXV0YXRlKHNsID0gc2Vjc19sZWZ0KGNsb2NrX21pbnV0ZXMsIGNsb2NrX3NlY29uZHMpKSB8PgogIGdyb3VwX2J5KGRyaXZlX2lkKSB8PgogIHN1bW1hcmlzZSh0ZWFtID0gZmlyc3QocG9zX3RlYW0pLCBwZXIgPSBmaXJzdChwZXJpb2QpLCBjbGsgPSBmaXJzdChzbCksCiAgICAgICAgICAgIHN0YXJ0ID0gZmlyc3QoZHJpdmVfc3RhcnRfeWFyZHNfdG9fZ29hbCksCiAgICAgICAgICAgIGNsb3Nlc3QgPSBzdXBwcmVzc1dhcm5pbmdzKG1pbih5YXJkc190b19nb2FsLCBuYS5ybSA9IFRSVUUpKSwKICAgICAgICAgICAgcGxheXMgPSBuKCksIHJlc3VsdCA9IGZpcnN0KGRyaXZlX3Jlc3VsdCksIHB0cyA9IGZpcnN0KGRyaXZlX3B0cyksCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpIHw+CiAgZmlsdGVyKCFpcy5uYSh0ZWFtKSkgfD4KICBhcnJhbmdlKHBlciwgZGVzYyhjbGspKQoKc3VfZHIgIDwtIGRyaXZlcyB8PiBmaWx0ZXIodGVhbSA9PSBURUFNLCBwZXIgPD0gNCkKbGFzdF9pIDwtIG1heCh3aGljaChzdV9kciRwdHMgPiAwKSkKZHJvdWdodCA8LSBzdV9kciB8PiBzbGljZSgobGFzdF9pICsgMSk6bigpKQoKb3BwX3B0cyA8LSBkcml2ZXMgfD4KICBmaWx0ZXIodGVhbSAhPSBURUFNLCBwZXIgPD0gNCwKICAgICAgICAgcGVyID4gc3VfZHIkcGVyW2xhc3RfaV0gfAogICAgICAgICAgIChwZXIgPT0gc3VfZHIkcGVyW2xhc3RfaV0gJiBjbGsgPCBzdV9kciRjbGtbbGFzdF9pXSkpIHw+CiAgc3VtbWFyaXNlKHggPSBzdW0ocHRzLCBuYS5ybSA9IFRSVUUpKSB8PiBwdWxsKHgpCgpkcm91Z2h0IHw+CiAgdHJhbnNtdXRlKAogICAgV2hlbiA9IHNwcmludGYoIlElZCAlMDJkOiUwMmQiLCBwZXIsIGNsayAlLyUgNjAsIGNsayAlJSA2MCksCiAgICBgU3RhcnRlZCBhdGAgPSBzcHJpbnRmKCJvd24gJS4wZiIsIDEwMCAtIHN0YXJ0KSwKICAgIGBHb3QgYXMgZmFyIGFzYCA9IGlmZWxzZShpcy5maW5pdGUoY2xvc2VzdCkgJiBjbG9zZXN0IDw9IDUwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoInRoZSAlcyAlLjBmIiwgT1BQLCBjbG9zZXN0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCJvd24gJS4wZiIsIDEwMCAtIGNsb3Nlc3QpKSwKICAgIFBsYXlzID0gcGxheXMsCiAgICBSZXN1bHQgPSByZXN1bHQKICApIHw+CiAgZ3QoKSB8PgogIHRhYl9oZWFkZXIoCiAgICB0aXRsZSA9IG1kKCIqKkFmdGVyIHRoZSBvcGVuaW5nIGRyaXZlIG9mIHRoZSBzZWNvbmQgaGFsZiwgU3lyYWN1c2UgcmFuIGZvdXIgcG9zc2Vzc2lvbnMgYW5kIHNjb3JlZCBvbiBub25lIG9mIHRoZW0qKiIpLAogICAgc3VidGl0bGUgPSBtZChzcHJpbnRmKCJVQ29ubiBzY29yZWQgJWQgcG9pbnRzIG92ZXIgdGhlIHNhbWUgc3RyZXRjaCIsIG9wcF9wdHMpKQogICkgfD4KICBjb2xzX2FsaWduKCJjZW50ZXIiLCBjb2x1bW5zID0gUGxheXMpIHw+CiAgY29sc19hbGlnbigibGVmdCIsIGNvbHVtbnMgPSBjKFdoZW4sIGBTdGFydGVkIGF0YCwgYEdvdCBhcyBmYXIgYXNgLCBSZXN1bHQpKSB8PgogIHRhYl9zdHlsZShzdHlsZSA9IGxpc3QoY2VsbF9maWxsKGNvbG9yID0gIiNGRkYzRTYiKSwgY2VsbF90ZXh0KHdlaWdodCA9ICJib2xkIikpLAogICAgICAgICAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSBSZXN1bHQgJWluJSBjKCJJTlQiLCAiRE9XTlMiLCAiTUlTU0VEIEZHIikpKSB8PgogIHRhYl9zb3VyY2Vfbm90ZShtZChwYXN0ZTAoIioqIiwgc3VfY2FwdGlvbihTQ09QRSksICIqKiIpKSkgfD4KICBndF90aGVtZV9zdSgpCmBgYAoKIyMgRXhoaWJpdCA0IOKAlCBUaGUgc2NvcmluZy1vcHBvcnR1bml0eSByZWNvdmVyeQoKYGBge3IgZXhoaWJpdC00fQpzZWFzb24gPC0gY3VyIHw+IGZpbHRlcih0ZWFtID09IFRFQU0pIHw+IGFycmFuZ2Uod2VlaykKCndrX3JhbmsgPC0gZnVuY3Rpb24odykgewogIHBnIDwtIGN1ciB8PiBmaWx0ZXIodGVhbSAlaW4lIGZicywgIWxvd192b2x1bWUsIHdlZWsgPT0gdywKICAgICAgICAgICAgICAgICAgICAgIGlzX2Zic19tYXRjaHVwID09ICh3ICE9IDEpKQogIGFzLmludGVnZXIocm91bmQocmFuaygtcGckb2ZmX3B0c19wZXJfb3BwLAogICAgICAgICAgICAgICAgICAgICAgICBuYS5sYXN0ID0gImtlZXAiKVtwZyR0ZWFtID09IFRFQU1dKSkKfQp3a19uIDwtIGZ1bmN0aW9uKHcpIHsKICBucm93KGN1ciB8PiBmaWx0ZXIodGVhbSAlaW4lIGZicywgIWxvd192b2x1bWUsIHdlZWsgPT0gdywKICAgICAgICAgICAgICAgICAgICAgaXNfZmJzX21hdGNodXAgPT0gKHcgIT0gMSkpKQp9Cgp0aWJibGU6OnRpYmJsZSgKICBHYW1lID0gYygiV2sgMSDigJQgTmV3IEhhbXBzaGlyZSAoRkNTKSIsICJXayAyIOKAlCBDYWxpZm9ybmlhIiwKICAgICAgICAgICAiV2sgMyDigJQgUGl0dHNidXJnaCIsICJXayA1IOKAlCBVQ29ubiIpLAogIGBTY29yaW5nIG9wcG9ydHVuaXRpZXNgID0gc2Vhc29uJG9mZl9zY29yaW5nX29wcHMsCiAgYFBvaW50cyBwZXIgb3Bwb3J0dW5pdHlgID0gc2Vhc29uJG9mZl9wdHNfcGVyX29wcCwKICBSYW5rID0gbWFwX2NocihzZWFzb24kd2VlaywgXCh3KSBzcHJpbnRmKCIlcyBvZiAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6Om9yZGluYWwod2tfcmFuayh3KSksIHdrX24odykpKQopIHw+CiAgZ3QoKSB8PgogIHRhYl9oZWFkZXIoCiAgICB0aXRsZSA9IG1kKCIqKlN5cmFjdXNlIHdlbnQgZnJvbSA5OXRoIGluIHRoZSBjb3VudHJ5IGF0IGZpbmlzaGluZyBkcml2ZXMgdG8gMjJuZCBpbiBvbmUgd2VlayoqIiksCiAgICBzdWJ0aXRsZSA9IG1kKCJQb2ludHMgcGVyIHRyaXAgaW5zaWRlIHRoZSBvcHBvbmVudCdzIDQwIHwgUmFua3MgYXJlIGFtb25nIHRlYW1zIGZhY2luZyB0aGUgc2FtZSBvcHBvbmVudCBjbGFzcyB0aGF0IHdlZWsiKQogICkgfD4KICBmbXRfbnVtYmVyKGNvbHVtbnMgPSBgUG9pbnRzIHBlciBvcHBvcnR1bml0eWAsIGRlY2ltYWxzID0gMikgfD4KICBjb2xzX2FsaWduKCJjZW50ZXIiLCBjb2x1bW5zID0gLUdhbWUpIHw+CiAgdGFiX3N0eWxlKHN0eWxlID0gY2VsbF90ZXh0KHdlaWdodCA9ICJib2xkIiksIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkoY29sdW1ucyA9IEdhbWUpKSB8PgogIHRhYl9zdHlsZShzdHlsZSA9IGxpc3QoY2VsbF9maWxsKGNvbG9yID0gIiNGRkYzRTYiKSwgY2VsbF90ZXh0KHdlaWdodCA9ICJib2xkIikpLAogICAgICAgICAgICBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KHJvd3MgPSBHYW1lID09ICJXayA1IOKAlCBVQ29ubiIpKSB8PgogIGRhdGFfY29sb3IoY29sdW1ucyA9IGBQb2ludHMgcGVyIG9wcG9ydHVuaXR5YCwgbWV0aG9kID0gIm51bWVyaWMiLCBwYWxldHRlID0gU1VfU0VRKSB8PgogIHRhYl9zb3VyY2Vfbm90ZShtZChwYXN0ZTAoIioqIiwgc3VfY2FwdGlvbigiMjAyNiBXZWVrcyAxLTUiKSwKICAgICIqKiDigJQgV2VlayAxIGlzIGNvbXBhcmVkIGFnYWluc3QgRkJTIHRlYW1zIGZhY2luZyBGQ1Mgb3Bwb25lbnRzOyB0aGUgcmVzdCBhZ2FpbnN0IEZCUy12cy1GQlMuIikpKSB8PgogIGd0X3RoZW1lX3N1KCkKYGBgCgojIyBFeGhpYml0IDUg4oCUIFRoZSBjYXZlYXQ6IG91dHBsYXllZCwgYW5kIHdvbiBhbnl3YXkKCmBgYHtyIGV4aGliaXQtNX0KcHIgPC0gZnVuY3Rpb24oY29sLCBoYiA9IFRSVUUpIHsKICB2IDwtIHBlZXJzW1tjb2xdXQogIGFzLmludGVnZXIocm91bmQocmFuayhpZiAoaGIpIC12IGVsc2UgdiwgbmEubGFzdCA9ICJrZWVwIilbcGVlcnMkdGVhbSA9PSBURUFNXSkpCn0KCnRpYmJsZTo6dGliYmxlKAogIE1ldHJpYyA9IGMoIk9mZmVuc2l2ZSBzdWNjZXNzIHJhdGUiLCAiUG9pbnRzIHBlciBzY29yaW5nIG9wcG9ydHVuaXR5IiwKICAgICAgICAgICAgICJEZWZlbnNpdmUgRVBBIGFsbG93ZWQgcGVyIHBsYXkiLCAiTmV0IEVQQSBwZXIgcGxheSIpLAogIFZhbHVlID0gYyhzdTUkb2ZmX3N1Y2Nlc3NfcmF0ZSwgc3U1JG9mZl9wdHNfcGVyX29wcCwKICAgICAgICAgICAgc3U1JGRlZl9lcGFfcGxheSwgc3U1JG5ldF9lcGFfcGxheSksCiAgUmFuayA9IGMoc3ByaW50ZigiJXMgb2YgJWQiLCBzY2FsZXM6Om9yZGluYWwocHIoIm9mZl9zdWNjZXNzX3JhdGUiKSksIG5yb3cocGVlcnMpKSwKICAgICAgICAgICBzcHJpbnRmKCIlcyBvZiAlZCIsIHNjYWxlczo6b3JkaW5hbChwcigib2ZmX3B0c19wZXJfb3BwIikpLCBucm93KHBlZXJzKSksCiAgICAgICAgICAgc3ByaW50ZigiJXMgb2YgJWQiLCBzY2FsZXM6Om9yZGluYWwocHIoImRlZl9lcGFfcGxheSIsIEZBTFNFKSksIG5yb3cocGVlcnMpKSwKICAgICAgICAgICBzcHJpbnRmKCIlcyBvZiAlZCIsIHNjYWxlczo6b3JkaW5hbChwcigibmV0X2VwYV9wbGF5IikpLCBucm93KHBlZXJzKSkpCikgfD4KICBndCgpIHw+CiAgdGFiX2hlYWRlcigKICAgIHRpdGxlID0gbWQoIioqVGhlIG9mZmVuc2Ugd2FzIGFtb25nIHRoZSBiZXN0IGluIHRoZSBjb3VudHJ5LiBUaGUgdGVhbSB3YXMgbm90LioqIiksCiAgICBzdWJ0aXRsZSA9IG1kKCJTeXJhY3VzZSB3YXMgb3V0cGxheWVkIG9uIGEgcGVyLXBsYXkgYmFzaXMgYW5kIHdvbiBpbiBvdmVydGltZSDigJQgdGhlIG1pcnJvciBpbWFnZSBvZiB0aGUgQ2FsaWZvcm5pYSBsb3NzIikKICApIHw+CiAgZm10X251bWJlcihjb2x1bW5zID0gVmFsdWUsIGRlY2ltYWxzID0gMykgfD4KICBjb2xzX2FsaWduKCJjZW50ZXIiLCBjb2x1bW5zID0gLU1ldHJpYykgfD4KICB0YWJfc3R5bGUoc3R5bGUgPSBjZWxsX3RleHQod2VpZ2h0ID0gImJvbGQiKSwgbG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gTWV0cmljKSkgfD4KICB0YWJfc291cmNlX25vdGUobWQocGFzdGUwKCIqKiIsIHN1X2NhcHRpb24oU0NPUEUpLAogICAgIioqIOKAlCByYW5rcyBhbW9uZyBGQlMgdGVhbXMgdGhhdCBwbGF5ZWQgRkJTIG9wcG9uZW50cyBpbiBXZWVrIDUuIikpKSB8PgogIGd0X3RoZW1lX3N1KCkKYGBgCgojIyBGaWd1cmVzIHdyaXR0ZW4gdG8gZGlzawoKYGBge3IgbWFuaWZlc3R9CmZpZ3MgPC0gbGlzdC5maWxlcyhGSUdfRElSLCBwYXR0ZXJuID0gIlxcLnBuZyQiLCBmdWxsLm5hbWVzID0gVFJVRSkKaWYgKGxlbmd0aChmaWdzKSA9PSAwKSBjYXQoIk5vIGZpZ3VyZXMgd3JpdHRlbi5cbiIpIGVsc2UgewogIGNhdCgiMzAwLWRwaSBQTkdzIHJlYWR5IGZvciB0aGUgcGllY2U6XG5cbiIpCiAgZm9yIChmIGluIGZpZ3MpIGNhdCgiICAiLCBmLCAiICAoIiwgcm91bmQoZmlsZS5pbmZvKGYpJHNpemUvMTAyNCksICIgS0IpXG4iLCBzZXAgPSAiIikKICBjYXQoIlxuQ29weSB0aGUgZ3QgdGFibGVzIGZyb20gdGhlIGJyb3dzZXIgaW50byBHb29nbGUgRG9jcyDigJQgdGhleSBwYXN0ZSBhc1xuIikKICBjYXQoIm5hdGl2ZSBlZGl0YWJsZSB0YWJsZXMgeW91IGNhbiByZXN0eWxlLlxuIikKfQpgYGAK