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

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

su  <- cur |> filter(team == TEAM, week == WEEK)
gid <- su$game_id[1]
g   <- p |> filter(game_id == gid, !is.na(pos_team))

# Drive-level trips into scoring range, computed directly so the exhibits match
# the narrative rather than relying on the pipeline's own opportunity counter.
drives <- g |>
  group_by(drive_id) |>
  summarise(team    = first(pos_team),
            closest = suppressWarnings(min(yards_to_goal, na.rm = TRUE)),
            result  = first(drive_result),
            pts     = first(drive_pts),
            plays   = n(),
            .groups = "drop") |>
  filter(is.finite(closest))

trips <- drives |> filter(closest <= 40)

trip_summary <- trips |>
  group_by(team) |>
  summarise(Trips = n(), Points = sum(pts, na.rm = TRUE),
            `Points per trip` = Points / Trips, .groups = "drop")

Exhibit 1 — Both teams reached scoring range. Only one of them is happy about it.

trip_summary |>
  mutate(team = factor(team, levels = c(OPP, TEAM))) |>
  arrange(team) |>
  rename(Team = team) |>
  gt() |>
  tab_header(
    title = md(sprintf("**Neither offense could finish — but %s needed to**", TEAM)),
    subtitle = md(sprintf(
      "Trips inside the opponent's 40-yard line and the points they produced | %s won 18-13",
      OPP))
  ) |>
  fmt_number(columns = `Points per trip`, decimals = 2) |>
  cols_align("center", columns = -Team) |>
  tab_style(style = cell_text(weight = "bold"), locations = cells_body(columns = Team)) |>
  tab_style(style = list(cell_fill(color = "#FFF3E6"), cell_text(weight = "bold")),
            locations = cells_body(rows = Team == TEAM)) |>
  tab_source_note(md(paste0("**", su_caption(SCOPE),
    "** — a trip is any drive reaching the opponent's 40."))) |>
  gt_theme_su()
Neither offense could finish — but Syracuse needed to
Trips inside the opponent’s 40-yard line and the points they produced | Clemson won 18-13
Team Trips Points Points per trip
Clemson 8 12 1.50
Syracuse 6 13 2.17
Data: CollegeFootballData via cfbfastR | 2026 Week 10 | Clemson 18, Syracuse 13 — a trip is any drive reaching the opponent’s 40.

Exhibit 2 — What Clemson did with its chances

trips |>
  filter(team == OPP) |>
  arrange(closest) |>
  transmute(`Got as close as` = sprintf("the %s %.0f", TEAM, closest),
            Plays = plays, Result = result, Points = pts) |>
  gt() |>
  tab_header(
    title = md(sprintf("**%s reached the %s 40 eight times and never scored a touchdown**",
                       OPP, TEAM)),
    subtitle = md(sprintf(
      "Four field goals, two punts, a missed field goal and a drive that ran out the half | %s succeeded on %.1f%% of its plays all afternoon",
      OPP, 100 * su$def_success_rate))
  ) |>
  cols_align("center", columns = c(Plays, Points)) |>
  cols_align("left", columns = c(`Got as close as`, Result)) |>
  tab_style(style = list(cell_fill(color = "#FFF3E6"), cell_text(weight = "bold")),
            locations = cells_body(rows = Points == 0)) |>
  tab_source_note(md(paste0("**", su_caption(SCOPE), "**"))) |>
  gt_theme_su()
Clemson reached the Syracuse 40 eight times and never scored a touchdown
Four field goals, two punts, a missed field goal and a drive that ran out the half | Clemson succeeded on 28.6% of its plays all afternoon
Got as close as Plays Result Points
the Syracuse 8 10 FG 3
the Syracuse 14 6 FG 3
the Syracuse 18 6 FG 3
the Syracuse 18 6 PUNT 0
the Syracuse 20 14 END OF HALF 0
the Syracuse 27 10 PUNT 0
the Syracuse 36 12 FG 3
the Syracuse 39 10 MISSED FG 0
Data: CollegeFootballData via cfbfastR | 2026 Week 10 | Clemson 18, Syracuse 13

Exhibit 3 — What Syracuse did with the same chances

trips |>
  filter(team == TEAM) |>
  arrange(closest) |>
  transmute(`Got as close as` = sprintf("the %s %.0f", OPP, closest),
            Plays = plays, Result = result, Points = pts) |>
  gt() |>
  tab_header(
    title = md(sprintf("**%s got two fewer chances and scored one more point**", TEAM)),
    subtitle = md(sprintf("Two field goals, a touchdown, a missed field goal, a drive that ran out the half — and an interception thrown from the %s 3-yard line",
                          OPP))
  ) |>
  cols_align("center", columns = c(Plays, Points)) |>
  cols_align("left", columns = c(`Got as close as`, Result)) |>
  tab_style(style = list(cell_fill(color = "#FFF3E6"), cell_text(weight = "bold")),
            locations = cells_body(rows = Points == 0)) |>
  tab_source_note(md(paste0("**", su_caption(SCOPE), "**"))) |>
  gt_theme_su()
Syracuse got two fewer chances and scored one more point
Two field goals, a touchdown, a missed field goal, a drive that ran out the half — and an interception thrown from the Clemson 3-yard line
Got as close as Plays Result Points
the Clemson 3 9 INT 0
the Clemson 8 15 FG 3
the Clemson 14 11 MISSED FG 0
the Clemson 28 8 FG 3
the Clemson 33 8 END OF HALF 0
the Clemson 33 5 TD 7
Data: CollegeFootballData via cfbfastR | 2026 Week 10 | Clemson 18, Syracuse 13

Exhibit 4 — The offense shrank as the field did

zones <- p |>
  select(all_of(intersect(NEEDED, names(p)))) |>
  filter(pos_team == TEAM) |>
  classify_plays() |>
  filter(is_scrimmage) |>
  mutate(zone = factor(ifelse(yards_to_goal <= 40,
                              sprintf("Inside the %s 40", OPP),
                              sprintf("Outside the %s 40", OPP)),
                       levels = c(sprintf("Outside the %s 40", OPP),
                                  sprintf("Inside the %s 40", OPP))),
         type = ifelse(pass == 1, "Pass", "Rush"))

zone_sr <- zones |>
  group_by(zone, type) |>
  summarise(plays = n(), sr = mean(success, na.rm = TRUE), .groups = "drop")

p_zone <- ggplot(zone_sr, aes(x = zone, y = sr, fill = type)) +
  geom_col(position = position_dodge(width = 0.72), width = 0.62) +
  geom_text(aes(label = sprintf("%.0f%%\n%d plays", 100 * sr, plays)),
            position = position_dodge(width = 0.72), vjust = -0.25,
            size = 3.3, fontface = "bold", lineheight = 0.95, color = SU$ink) +
  scale_fill_manual(values = c(Pass = SU$orange, Rush = SU$blue)) +
  scale_y_continuous(labels = percent, expand = expansion(mult = c(0, 0.22))) +
  labs(
    title = sprintf("%s's passing game fell apart once the field got short", TEAM),
    subtitle = "Success rate by field zone — the share of plays gaining enough to stay on schedule",
    x = NULL, y = "Success rate", fill = NULL,
    caption = su_caption(SCOPE)
  ) +
  theme_su(legend_pos = "top")

save_fig(p_zone, "01_success_rate_by_zone", height = 5)

zones |>
  group_by(zone) |>
  summarise(Plays = n(), Successes = sum(success, na.rm = TRUE),
            `Success rate` = mean(success, na.rm = TRUE), .groups = "drop") |>
  rename(Zone = zone) |>
  gt() |>
  tab_header(
    title = md("**All plays, by zone**"),
    subtitle = md("The passing-only figures appear in the chart above; these are every snap")
  ) |>
  fmt_percent(columns = `Success rate`, decimals = 1) |>
  cols_align("center", columns = -Zone) |>
  tab_style(style = cell_text(weight = "bold"), locations = cells_body(columns = Zone)) |>
  tab_source_note(md(paste0("**", su_caption(SCOPE), "**"))) |>
  gt_theme_su()
All plays, by zone
The passing-only figures appear in the chart above; these are every snap
Zone Plays Successes Success rate
Outside the Clemson 40 51 22 43.1%
Inside the Clemson 40 22 7 31.8%
Data: CollegeFootballData via cfbfastR | 2026 Week 10 | Clemson 18, Syracuse 13

Exhibit 5 — Seven of nine decided by one score

sched <- suppressWarnings(cfbd_game_info(SEASON, team = TEAM)) |>
  filter(!is.na(home_points)) |> arrange(week) |>
  mutate(opp = ifelse(home_team == TEAM, away_team, home_team),
         su_pts = ifelse(home_team == TEAM, home_points, away_points),
         op_pts = ifelse(home_team == TEAM, away_points, home_points),
         margin = su_pts - op_pts,
         one_score = abs(margin) <= 8,
         lab = sprintf("Wk %d  %s", week, opp),
         outcome = ifelse(margin > 0, "Win", "Loss")) |>
  mutate(lab = factor(lab, levels = rev(lab)))

p_margin <- ggplot(sched, aes(x = margin, y = lab)) +
  annotate("rect", xmin = -8, xmax = 8, ymin = -Inf, ymax = Inf,
           fill = SU$orange, alpha = 0.08) +
  geom_vline(xintercept = 0, color = SU$muted, linewidth = 0.5) +
  geom_segment(aes(x = 0, xend = margin, yend = lab, color = outcome), linewidth = 1.6) +
  geom_point(aes(color = outcome), size = 3.4) +
  geom_text(aes(label = sprintf("%+d", margin),
                hjust = ifelse(margin > 0, -0.45, 1.45)),
            size = 3.3, fontface = "bold", color = SU$ink) +
  scale_color_manual(values = c(Win = SU$orange, Loss = SU$blue), name = NULL) +
  scale_x_continuous(expand = expansion(mult = c(0.14, 0.14))) +
  labs(
    title = sprintf("%d of Syracuse's %d games have been decided by one score",
                    sum(sched$one_score), nrow(sched)),
    subtitle = sprintf(
      "Final margin by game | Shaded band: within 8 points | Syracuse is %d-%d in those games and %d-%d overall",
      sum(sched$one_score & sched$margin > 0), sum(sched$one_score & sched$margin < 0),
      sum(sched$margin > 0), sum(sched$margin < 0)),
    x = "Final margin", y = NULL,
    caption = su_caption("2026 season to date")
  ) +
  theme_su(legend_pos = "top")

save_fig(p_margin, "02_one_score_games", height = 5.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.\n")
}
## 300-dpi PNGs ready for the piece:
## 
##   figures/2026_wk10_story/01_success_rate_by_zone.png  (122 KB)
##   figures/2026_wk10_story/02_one_score_games.png  (149 KB)
## 
## Copy the gt tables from the browser into Google Docs — they paste as
## native editable tables.
LS0tCnRpdGxlOiAiU3lyYWN1c2UncyBEZWZlbnNlIERpZG4ndCBBbGxvdyBhIFRvdWNoZG93bi4gU3lyYWN1c2UgTG9zdC4iCnN1YnRpdGxlOiAiV2VlayAxMCAyMDI2IOKAlCBDbGVtc29uIDE4LCBTeXJhY3VzZSAxMyDigJQgZXhoaWJpdHMgZm9yIHB1YmxpY2F0aW9uIgphdXRob3I6ICJDaHJpcyBKaW1lbmV6IgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiCnBhcmFtczoKICBzZWFzb246IDIwMjYKICB3ZWVrOiAxMApvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogemVuYnVybgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogICAgY29kZV9kb3dubG9hZDogeWVzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgRU5DT0RJTkc6IGEgc2hlbGwgd2l0aCBubyBMQU5HIHNldCBzdGFydHMgUiBpbiB0aGUgQyAvIFVTLUFTQ0lJIGxvY2FsZSwgYW5kCiMgZ3QgYW5kIGdncGxvdCB0aGVuIEVTQ0FQRSBldmVyeSBub24tQVNDSUkgY2hhcmFjdGVyLiBGb3JjZSBVVEYtOCBzbyBlbSBkYXNoZXMKIyBzdXJ2aXZlIGludG8gcHVibGljYXRpb24tcmVhZHkgb3V0cHV0Lgpmb3IgKGxvYyBpbiBjKCJlbl9VUy5VVEYtOCIsICJDLlVURi04IiwgIlVURi04IikpIHsKICBpZiAobnpjaGFyKHN1cHByZXNzV2FybmluZ3MoU3lzLnNldGxvY2FsZSgiTENfQUxMIiwgbG9jKSkpKSBicmVhawp9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDYsIGRwaSA9IDE1MCkKYGBgCgpgYGB7ciBsaWJyYXJpZXN9CmxpYnJhcnkodGlkeXZlcnNlKTsgbGlicmFyeShhcnJvdyk7IGxpYnJhcnkoZ3QpOyBsaWJyYXJ5KHNjYWxlcyk7IGxpYnJhcnkoY2ZiZmFzdFIpCmBgYAoKYGBge3Igc3R5bGV9Cm9wdGlvbnMoY2ZiLmxpYl9vbmx5ID0gVFJVRSkKc291cmNlKCIuLi9SLzAyX3RlYW1fZ2FtZV9tZXRyaWNzLlIiKQpzb3VyY2UoIi4uL1IvMDVfdml6X3N0eWxlLlIiKQoKVEVBTSA8LSAiU3lyYWN1c2UiOyBPUFAgPC0gIkNsZW1zb24iClNFQVNPTiA8LSBwYXJhbXMkc2Vhc29uOyBXRUVLIDwtIHBhcmFtcyR3ZWVrCkZJR19ESVIgPC0gc3ByaW50ZigiZmlndXJlcy8lZF93ayUwMmRfc3RvcnkiLCBTRUFTT04sIFdFRUspClNDT1BFICAgPC0gc3ByaW50ZigiJWQgV2VlayAlZCB8ICVzICVkLCAlcyAlZCIsIFNFQVNPTiwgV0VFSywgT1BQLCAxOCwgVEVBTSwgMTMpCmBgYAoKYGBge3IgZGF0YX0KY3VyIDwtIHJlYWRfcGFycXVldChzcHJpbnRmKCJ+L2NmYi1kYXRhL3Byb2Nlc3NlZC90ZWFtX2dhbWVfbWV0cmljc18lZC5wYXJxdWV0IiwgU0VBU09OKSkKZmJzIDwtIHJlYWRSRFMoc3ByaW50Zigifi9jZmItZGF0YS9mYnNfdGVhbXNfJWQucmRzIiwgU0VBU09OKSkKcCAgIDwtIHJlYWRfcGFycXVldChzcHJpbnRmKCJ+L2NmYi1kYXRhL3Jhdy9wYnBfaW5zZWFzb24vcGJwXyVkX3drJTAyZC5wYXJxdWV0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFQVNPTiwgV0VFSykpCgpzdSAgPC0gY3VyIHw+IGZpbHRlcih0ZWFtID09IFRFQU0sIHdlZWsgPT0gV0VFSykKZ2lkIDwtIHN1JGdhbWVfaWRbMV0KZyAgIDwtIHAgfD4gZmlsdGVyKGdhbWVfaWQgPT0gZ2lkLCAhaXMubmEocG9zX3RlYW0pKQoKIyBEcml2ZS1sZXZlbCB0cmlwcyBpbnRvIHNjb3JpbmcgcmFuZ2UsIGNvbXB1dGVkIGRpcmVjdGx5IHNvIHRoZSBleGhpYml0cyBtYXRjaAojIHRoZSBuYXJyYXRpdmUgcmF0aGVyIHRoYW4gcmVseWluZyBvbiB0aGUgcGlwZWxpbmUncyBvd24gb3Bwb3J0dW5pdHkgY291bnRlci4KZHJpdmVzIDwtIGcgfD4KICBncm91cF9ieShkcml2ZV9pZCkgfD4KICBzdW1tYXJpc2UodGVhbSAgICA9IGZpcnN0KHBvc190ZWFtKSwKICAgICAgICAgICAgY2xvc2VzdCA9IHN1cHByZXNzV2FybmluZ3MobWluKHlhcmRzX3RvX2dvYWwsIG5hLnJtID0gVFJVRSkpLAogICAgICAgICAgICByZXN1bHQgID0gZmlyc3QoZHJpdmVfcmVzdWx0KSwKICAgICAgICAgICAgcHRzICAgICA9IGZpcnN0KGRyaXZlX3B0cyksCiAgICAgICAgICAgIHBsYXlzICAgPSBuKCksCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpIHw+CiAgZmlsdGVyKGlzLmZpbml0ZShjbG9zZXN0KSkKCnRyaXBzIDwtIGRyaXZlcyB8PiBmaWx0ZXIoY2xvc2VzdCA8PSA0MCkKCnRyaXBfc3VtbWFyeSA8LSB0cmlwcyB8PgogIGdyb3VwX2J5KHRlYW0pIHw+CiAgc3VtbWFyaXNlKFRyaXBzID0gbigpLCBQb2ludHMgPSBzdW0ocHRzLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBgUG9pbnRzIHBlciB0cmlwYCA9IFBvaW50cyAvIFRyaXBzLCAuZ3JvdXBzID0gImRyb3AiKQpgYGAKCiMjIEV4aGliaXQgMSDigJQgQm90aCB0ZWFtcyByZWFjaGVkIHNjb3JpbmcgcmFuZ2UuIE9ubHkgb25lIG9mIHRoZW0gaXMgaGFwcHkgYWJvdXQgaXQuCgpgYGB7ciBleGhpYml0LTF9CnRyaXBfc3VtbWFyeSB8PgogIG11dGF0ZSh0ZWFtID0gZmFjdG9yKHRlYW0sIGxldmVscyA9IGMoT1BQLCBURUFNKSkpIHw+CiAgYXJyYW5nZSh0ZWFtKSB8PgogIHJlbmFtZShUZWFtID0gdGVhbSkgfD4KICBndCgpIHw+CiAgdGFiX2hlYWRlcigKICAgIHRpdGxlID0gbWQoc3ByaW50ZigiKipOZWl0aGVyIG9mZmVuc2UgY291bGQgZmluaXNoIOKAlCBidXQgJXMgbmVlZGVkIHRvKioiLCBURUFNKSksCiAgICBzdWJ0aXRsZSA9IG1kKHNwcmludGYoCiAgICAgICJUcmlwcyBpbnNpZGUgdGhlIG9wcG9uZW50J3MgNDAteWFyZCBsaW5lIGFuZCB0aGUgcG9pbnRzIHRoZXkgcHJvZHVjZWQgfCAlcyB3b24gMTgtMTMiLAogICAgICBPUFApKQogICkgfD4KICBmbXRfbnVtYmVyKGNvbHVtbnMgPSBgUG9pbnRzIHBlciB0cmlwYCwgZGVjaW1hbHMgPSAyKSB8PgogIGNvbHNfYWxpZ24oImNlbnRlciIsIGNvbHVtbnMgPSAtVGVhbSkgfD4KICB0YWJfc3R5bGUoc3R5bGUgPSBjZWxsX3RleHQod2VpZ2h0ID0gImJvbGQiKSwgbG9jYXRpb25zID0gY2VsbHNfYm9keShjb2x1bW5zID0gVGVhbSkpIHw+CiAgdGFiX3N0eWxlKHN0eWxlID0gbGlzdChjZWxsX2ZpbGwoY29sb3IgPSAiI0ZGRjNFNiIpLCBjZWxsX3RleHQod2VpZ2h0ID0gImJvbGQiKSksCiAgICAgICAgICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IFRlYW0gPT0gVEVBTSkpIHw+CiAgdGFiX3NvdXJjZV9ub3RlKG1kKHBhc3RlMCgiKioiLCBzdV9jYXB0aW9uKFNDT1BFKSwKICAgICIqKiDigJQgYSB0cmlwIGlzIGFueSBkcml2ZSByZWFjaGluZyB0aGUgb3Bwb25lbnQncyA0MC4iKSkpIHw+CiAgZ3RfdGhlbWVfc3UoKQpgYGAKCiMjIEV4aGliaXQgMiDigJQgV2hhdCBDbGVtc29uIGRpZCB3aXRoIGl0cyBjaGFuY2VzCgpgYGB7ciBleGhpYml0LTJ9CnRyaXBzIHw+CiAgZmlsdGVyKHRlYW0gPT0gT1BQKSB8PgogIGFycmFuZ2UoY2xvc2VzdCkgfD4KICB0cmFuc211dGUoYEdvdCBhcyBjbG9zZSBhc2AgPSBzcHJpbnRmKCJ0aGUgJXMgJS4wZiIsIFRFQU0sIGNsb3Nlc3QpLAogICAgICAgICAgICBQbGF5cyA9IHBsYXlzLCBSZXN1bHQgPSByZXN1bHQsIFBvaW50cyA9IHB0cykgfD4KICBndCgpIHw+CiAgdGFiX2hlYWRlcigKICAgIHRpdGxlID0gbWQoc3ByaW50ZigiKiolcyByZWFjaGVkIHRoZSAlcyA0MCBlaWdodCB0aW1lcyBhbmQgbmV2ZXIgc2NvcmVkIGEgdG91Y2hkb3duKioiLAogICAgICAgICAgICAgICAgICAgICAgIE9QUCwgVEVBTSkpLAogICAgc3VidGl0bGUgPSBtZChzcHJpbnRmKAogICAgICAiRm91ciBmaWVsZCBnb2FscywgdHdvIHB1bnRzLCBhIG1pc3NlZCBmaWVsZCBnb2FsIGFuZCBhIGRyaXZlIHRoYXQgcmFuIG91dCB0aGUgaGFsZiB8ICVzIHN1Y2NlZWRlZCBvbiAlLjFmJSUgb2YgaXRzIHBsYXlzIGFsbCBhZnRlcm5vb24iLAogICAgICBPUFAsIDEwMCAqIHN1JGRlZl9zdWNjZXNzX3JhdGUpKQogICkgfD4KICBjb2xzX2FsaWduKCJjZW50ZXIiLCBjb2x1bW5zID0gYyhQbGF5cywgUG9pbnRzKSkgfD4KICBjb2xzX2FsaWduKCJsZWZ0IiwgY29sdW1ucyA9IGMoYEdvdCBhcyBjbG9zZSBhc2AsIFJlc3VsdCkpIHw+CiAgdGFiX3N0eWxlKHN0eWxlID0gbGlzdChjZWxsX2ZpbGwoY29sb3IgPSAiI0ZGRjNFNiIpLCBjZWxsX3RleHQod2VpZ2h0ID0gImJvbGQiKSksCiAgICAgICAgICAgIGxvY2F0aW9ucyA9IGNlbGxzX2JvZHkocm93cyA9IFBvaW50cyA9PSAwKSkgfD4KICB0YWJfc291cmNlX25vdGUobWQocGFzdGUwKCIqKiIsIHN1X2NhcHRpb24oU0NPUEUpLCAiKioiKSkpIHw+CiAgZ3RfdGhlbWVfc3UoKQpgYGAKCiMjIEV4aGliaXQgMyDigJQgV2hhdCBTeXJhY3VzZSBkaWQgd2l0aCB0aGUgc2FtZSBjaGFuY2VzCgpgYGB7ciBleGhpYml0LTN9CnRyaXBzIHw+CiAgZmlsdGVyKHRlYW0gPT0gVEVBTSkgfD4KICBhcnJhbmdlKGNsb3Nlc3QpIHw+CiAgdHJhbnNtdXRlKGBHb3QgYXMgY2xvc2UgYXNgID0gc3ByaW50ZigidGhlICVzICUuMGYiLCBPUFAsIGNsb3Nlc3QpLAogICAgICAgICAgICBQbGF5cyA9IHBsYXlzLCBSZXN1bHQgPSByZXN1bHQsIFBvaW50cyA9IHB0cykgfD4KICBndCgpIHw+CiAgdGFiX2hlYWRlcigKICAgIHRpdGxlID0gbWQoc3ByaW50ZigiKiolcyBnb3QgdHdvIGZld2VyIGNoYW5jZXMgYW5kIHNjb3JlZCBvbmUgbW9yZSBwb2ludCoqIiwgVEVBTSkpLAogICAgc3VidGl0bGUgPSBtZChzcHJpbnRmKCJUd28gZmllbGQgZ29hbHMsIGEgdG91Y2hkb3duLCBhIG1pc3NlZCBmaWVsZCBnb2FsLCBhIGRyaXZlIHRoYXQgcmFuIG91dCB0aGUgaGFsZiDigJQgYW5kIGFuIGludGVyY2VwdGlvbiB0aHJvd24gZnJvbSB0aGUgJXMgMy15YXJkIGxpbmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgIE9QUCkpCiAgKSB8PgogIGNvbHNfYWxpZ24oImNlbnRlciIsIGNvbHVtbnMgPSBjKFBsYXlzLCBQb2ludHMpKSB8PgogIGNvbHNfYWxpZ24oImxlZnQiLCBjb2x1bW5zID0gYyhgR290IGFzIGNsb3NlIGFzYCwgUmVzdWx0KSkgfD4KICB0YWJfc3R5bGUoc3R5bGUgPSBsaXN0KGNlbGxfZmlsbChjb2xvciA9ICIjRkZGM0U2IiksIGNlbGxfdGV4dCh3ZWlnaHQgPSAiYm9sZCIpKSwKICAgICAgICAgICAgbG9jYXRpb25zID0gY2VsbHNfYm9keShyb3dzID0gUG9pbnRzID09IDApKSB8PgogIHRhYl9zb3VyY2Vfbm90ZShtZChwYXN0ZTAoIioqIiwgc3VfY2FwdGlvbihTQ09QRSksICIqKiIpKSkgfD4KICBndF90aGVtZV9zdSgpCmBgYAoKIyMgRXhoaWJpdCA0IOKAlCBUaGUgb2ZmZW5zZSBzaHJhbmsgYXMgdGhlIGZpZWxkIGRpZAoKYGBge3IgZXhoaWJpdC00LCBmaWcuYXNwID0gMC41fQp6b25lcyA8LSBwIHw+CiAgc2VsZWN0KGFsbF9vZihpbnRlcnNlY3QoTkVFREVELCBuYW1lcyhwKSkpKSB8PgogIGZpbHRlcihwb3NfdGVhbSA9PSBURUFNKSB8PgogIGNsYXNzaWZ5X3BsYXlzKCkgfD4KICBmaWx0ZXIoaXNfc2NyaW1tYWdlKSB8PgogIG11dGF0ZSh6b25lID0gZmFjdG9yKGlmZWxzZSh5YXJkc190b19nb2FsIDw9IDQwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCJJbnNpZGUgdGhlICVzIDQwIiwgT1BQKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZigiT3V0c2lkZSB0aGUgJXMgNDAiLCBPUFApKSwKICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKHNwcmludGYoIk91dHNpZGUgdGhlICVzIDQwIiwgT1BQKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIkluc2lkZSB0aGUgJXMgNDAiLCBPUFApKSksCiAgICAgICAgIHR5cGUgPSBpZmVsc2UocGFzcyA9PSAxLCAiUGFzcyIsICJSdXNoIikpCgp6b25lX3NyIDwtIHpvbmVzIHw+CiAgZ3JvdXBfYnkoem9uZSwgdHlwZSkgfD4KICBzdW1tYXJpc2UocGxheXMgPSBuKCksIHNyID0gbWVhbihzdWNjZXNzLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gImRyb3AiKQoKcF96b25lIDwtIGdncGxvdCh6b25lX3NyLCBhZXMoeCA9IHpvbmUsIHkgPSBzciwgZmlsbCA9IHR5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNzIpLCB3aWR0aCA9IDAuNjIpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3ByaW50ZigiJS4wZiUlXG4lZCBwbGF5cyIsIDEwMCAqIHNyLCBwbGF5cykpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC43MiksIHZqdXN0ID0gLTAuMjUsCiAgICAgICAgICAgIHNpemUgPSAzLjMsIGZvbnRmYWNlID0gImJvbGQiLCBsaW5laGVpZ2h0ID0gMC45NSwgY29sb3IgPSBTVSRpbmspICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKFBhc3MgPSBTVSRvcmFuZ2UsIFJ1c2ggPSBTVSRibHVlKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50LCBleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMCwgMC4yMikpKSArCiAgbGFicygKICAgIHRpdGxlID0gc3ByaW50ZigiJXMncyBwYXNzaW5nIGdhbWUgZmVsbCBhcGFydCBvbmNlIHRoZSBmaWVsZCBnb3Qgc2hvcnQiLCBURUFNKSwKICAgIHN1YnRpdGxlID0gIlN1Y2Nlc3MgcmF0ZSBieSBmaWVsZCB6b25lIOKAlCB0aGUgc2hhcmUgb2YgcGxheXMgZ2FpbmluZyBlbm91Z2ggdG8gc3RheSBvbiBzY2hlZHVsZSIsCiAgICB4ID0gTlVMTCwgeSA9ICJTdWNjZXNzIHJhdGUiLCBmaWxsID0gTlVMTCwKICAgIGNhcHRpb24gPSBzdV9jYXB0aW9uKFNDT1BFKQogICkgKwogIHRoZW1lX3N1KGxlZ2VuZF9wb3MgPSAidG9wIikKCnNhdmVfZmlnKHBfem9uZSwgIjAxX3N1Y2Nlc3NfcmF0ZV9ieV96b25lIiwgaGVpZ2h0ID0gNSkKYGBgCgpgYGB7ciBleGhpYml0LTRifQp6b25lcyB8PgogIGdyb3VwX2J5KHpvbmUpIHw+CiAgc3VtbWFyaXNlKFBsYXlzID0gbigpLCBTdWNjZXNzZXMgPSBzdW0oc3VjY2VzcywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgYFN1Y2Nlc3MgcmF0ZWAgPSBtZWFuKHN1Y2Nlc3MsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAiZHJvcCIpIHw+CiAgcmVuYW1lKFpvbmUgPSB6b25lKSB8PgogIGd0KCkgfD4KICB0YWJfaGVhZGVyKAogICAgdGl0bGUgPSBtZCgiKipBbGwgcGxheXMsIGJ5IHpvbmUqKiIpLAogICAgc3VidGl0bGUgPSBtZCgiVGhlIHBhc3Npbmctb25seSBmaWd1cmVzIGFwcGVhciBpbiB0aGUgY2hhcnQgYWJvdmU7IHRoZXNlIGFyZSBldmVyeSBzbmFwIikKICApIHw+CiAgZm10X3BlcmNlbnQoY29sdW1ucyA9IGBTdWNjZXNzIHJhdGVgLCBkZWNpbWFscyA9IDEpIHw+CiAgY29sc19hbGlnbigiY2VudGVyIiwgY29sdW1ucyA9IC1ab25lKSB8PgogIHRhYl9zdHlsZShzdHlsZSA9IGNlbGxfdGV4dCh3ZWlnaHQgPSAiYm9sZCIpLCBsb2NhdGlvbnMgPSBjZWxsc19ib2R5KGNvbHVtbnMgPSBab25lKSkgfD4KICB0YWJfc291cmNlX25vdGUobWQocGFzdGUwKCIqKiIsIHN1X2NhcHRpb24oU0NPUEUpLCAiKioiKSkpIHw+CiAgZ3RfdGhlbWVfc3UoKQpgYGAKCiMjIEV4aGliaXQgNSDigJQgU2V2ZW4gb2YgbmluZSBkZWNpZGVkIGJ5IG9uZSBzY29yZQoKYGBge3IgZXhoaWJpdC01LCBmaWcuYXNwID0gMC41NX0Kc2NoZWQgPC0gc3VwcHJlc3NXYXJuaW5ncyhjZmJkX2dhbWVfaW5mbyhTRUFTT04sIHRlYW0gPSBURUFNKSkgfD4KICBmaWx0ZXIoIWlzLm5hKGhvbWVfcG9pbnRzKSkgfD4gYXJyYW5nZSh3ZWVrKSB8PgogIG11dGF0ZShvcHAgPSBpZmVsc2UoaG9tZV90ZWFtID09IFRFQU0sIGF3YXlfdGVhbSwgaG9tZV90ZWFtKSwKICAgICAgICAgc3VfcHRzID0gaWZlbHNlKGhvbWVfdGVhbSA9PSBURUFNLCBob21lX3BvaW50cywgYXdheV9wb2ludHMpLAogICAgICAgICBvcF9wdHMgPSBpZmVsc2UoaG9tZV90ZWFtID09IFRFQU0sIGF3YXlfcG9pbnRzLCBob21lX3BvaW50cyksCiAgICAgICAgIG1hcmdpbiA9IHN1X3B0cyAtIG9wX3B0cywKICAgICAgICAgb25lX3Njb3JlID0gYWJzKG1hcmdpbikgPD0gOCwKICAgICAgICAgbGFiID0gc3ByaW50ZigiV2sgJWQgICVzIiwgd2Vlaywgb3BwKSwKICAgICAgICAgb3V0Y29tZSA9IGlmZWxzZShtYXJnaW4gPiAwLCAiV2luIiwgIkxvc3MiKSkgfD4KICBtdXRhdGUobGFiID0gZmFjdG9yKGxhYiwgbGV2ZWxzID0gcmV2KGxhYikpKQoKcF9tYXJnaW4gPC0gZ2dwbG90KHNjaGVkLCBhZXMoeCA9IG1hcmdpbiwgeSA9IGxhYikpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAtOCwgeG1heCA9IDgsIHltaW4gPSAtSW5mLCB5bWF4ID0gSW5mLAogICAgICAgICAgIGZpbGwgPSBTVSRvcmFuZ2UsIGFscGhhID0gMC4wOCkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGNvbG9yID0gU1UkbXV0ZWQsIGxpbmV3aWR0aCA9IDAuNSkgKwogIGdlb21fc2VnbWVudChhZXMoeCA9IDAsIHhlbmQgPSBtYXJnaW4sIHllbmQgPSBsYWIsIGNvbG9yID0gb3V0Y29tZSksIGxpbmV3aWR0aCA9IDEuNikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gb3V0Y29tZSksIHNpemUgPSAzLjQpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc3ByaW50ZigiJStkIiwgbWFyZ2luKSwKICAgICAgICAgICAgICAgIGhqdXN0ID0gaWZlbHNlKG1hcmdpbiA+IDAsIC0wLjQ1LCAxLjQ1KSksCiAgICAgICAgICAgIHNpemUgPSAzLjMsIGZvbnRmYWNlID0gImJvbGQiLCBjb2xvciA9IFNVJGluaykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKFdpbiA9IFNVJG9yYW5nZSwgTG9zcyA9IFNVJGJsdWUpLCBuYW1lID0gTlVMTCkgKwogIHNjYWxlX3hfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4xNCwgMC4xNCkpKSArCiAgbGFicygKICAgIHRpdGxlID0gc3ByaW50ZigiJWQgb2YgU3lyYWN1c2UncyAlZCBnYW1lcyBoYXZlIGJlZW4gZGVjaWRlZCBieSBvbmUgc2NvcmUiLAogICAgICAgICAgICAgICAgICAgIHN1bShzY2hlZCRvbmVfc2NvcmUpLCBucm93KHNjaGVkKSksCiAgICBzdWJ0aXRsZSA9IHNwcmludGYoCiAgICAgICJGaW5hbCBtYXJnaW4gYnkgZ2FtZSB8IFNoYWRlZCBiYW5kOiB3aXRoaW4gOCBwb2ludHMgfCBTeXJhY3VzZSBpcyAlZC0lZCBpbiB0aG9zZSBnYW1lcyBhbmQgJWQtJWQgb3ZlcmFsbCIsCiAgICAgIHN1bShzY2hlZCRvbmVfc2NvcmUgJiBzY2hlZCRtYXJnaW4gPiAwKSwgc3VtKHNjaGVkJG9uZV9zY29yZSAmIHNjaGVkJG1hcmdpbiA8IDApLAogICAgICBzdW0oc2NoZWQkbWFyZ2luID4gMCksIHN1bShzY2hlZCRtYXJnaW4gPCAwKSksCiAgICB4ID0gIkZpbmFsIG1hcmdpbiIsIHkgPSBOVUxMLAogICAgY2FwdGlvbiA9IHN1X2NhcHRpb24oIjIwMjYgc2Vhc29uIHRvIGRhdGUiKQogICkgKwogIHRoZW1lX3N1KGxlZ2VuZF9wb3MgPSAidG9wIikKCnNhdmVfZmlnKHBfbWFyZ2luLCAiMDJfb25lX3Njb3JlX2dhbWVzIiwgaGVpZ2h0ID0gNS41KQpgYGAKCiMjIEZpZ3VyZXMgd3JpdHRlbiB0byBkaXNrCgpgYGB7ciBtYW5pZmVzdH0KZmlncyA8LSBsaXN0LmZpbGVzKEZJR19ESVIsIHBhdHRlcm4gPSAiXFwucG5nJCIsIGZ1bGwubmFtZXMgPSBUUlVFKQppZiAobGVuZ3RoKGZpZ3MpID09IDApIGNhdCgiTm8gZmlndXJlcyB3cml0dGVuLlxuIikgZWxzZSB7CiAgY2F0KCIzMDAtZHBpIFBOR3MgcmVhZHkgZm9yIHRoZSBwaWVjZTpcblxuIikKICBmb3IgKGYgaW4gZmlncykgY2F0KCIgICIsIGYsICIgICgiLCByb3VuZChmaWxlLmluZm8oZikkc2l6ZS8xMDI0KSwgIiBLQilcbiIsIHNlcCA9ICIiKQogIGNhdCgiXG5Db3B5IHRoZSBndCB0YWJsZXMgZnJvbSB0aGUgYnJvd3NlciBpbnRvIEdvb2dsZSBEb2NzIOKAlCB0aGV5IHBhc3RlIGFzXG4iKQogIGNhdCgibmF0aXZlIGVkaXRhYmxlIHRhYmxlcy5cbiIpCn0KYGBgCg==