1 Average Sleep Over the Ages

This chart shows how our average sleep duration changes as we age. Notice the decline during adolescence, followed by a more gradual change throughout adulthood.

sleep_vs_age_plot <- timeuse_df %>%
  filter(activity == "Sleep", age < 90, age >= 6) %>%
  group_by(person_id, age, mult) %>%
  summarise(total_sleep_mins = sum(duration_mins, na.rm = TRUE),
            .groups = 'drop') %>%
  group_by(age) %>%
  summarise(avg_sleep_weighted_mins = weighted.mean(total_sleep_mins, w = mult, na.rm = TRUE)) %>%
  mutate(avg_sleep_hours = avg_sleep_weighted_mins / 60) %>%
  ggplot(aes(x = age, y = avg_sleep_hours)) +
  geom_smooth(
    method = "loess",
    se = TRUE,
    color = "black",
    fill = "gray80",
    linewidth = 0.8
  ) +
  scale_y_continuous(limits = c(0, 12), breaks = seq(0, 12, by = 2)) +
  scale_x_continuous(breaks = seq(10, 90, by = 20), limits = c(6, 95)) +
  labs(
    title = "Average daily sleep across ages",
    x = "Age (years)",
    y = "Sleep (hours/day)",
    caption = "Source: National Time Use Survey 2024"
  ) +
  theme_minimal() +
  theme(
    text = element_text(family = "ath", size = 9),
    plot.title = element_text(
      family = "ath",
      face = "bold",
      size = 10,
      margin = margin(b = 8)
    ),
    plot.caption = element_text(
      family = "ath",
      size = 7,
      color = "gray50",
      hjust = 0
    ),
    axis.title = element_text(family = "ath", size = 9),
    axis.text = element_text(size = 8),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_line(color = "gray90", linewidth = 0.3),
    plot.margin = margin(10, 10, 10, 10)
  )

sleep_vs_age_plot
## `geom_smooth()` using formula = 'y ~ x'

# --- Essential Sleep Only ---

night_sleep_vs_age_plot <- timeuse_df %>%
  filter(activity_code == "Night sleep/essential sleep", age < 90, age >= 6) %>%
  group_by(person_id, age, mult) %>%
  summarise(total_sleep_mins = sum(duration_mins, na.rm = TRUE),
            .groups = 'drop') %>%
  group_by(age) %>%
  summarise(avg_sleep_weighted_mins = weighted.mean(total_sleep_mins, w = mult, na.rm = TRUE)) %>%
  mutate(avg_sleep_hours = avg_sleep_weighted_mins / 60) %>%
  ggplot(aes(x = age, y = avg_sleep_hours)) +
  geom_smooth(
    method = "loess",
    se = TRUE,
    color = "navy",
    fill = "lightblue",
    linewidth = 0.8
  ) +
  scale_y_continuous(limits = c(0, 12), breaks = seq(0, 12, by = 2)) +
  scale_x_continuous(breaks = seq(10, 90, by = 20), limits = c(6, 95)) +
  labs(
    title = "Night sleep across ages",
    x = "Age (years)",
    y = "Sleep (hours/day)",
    caption = "Source: National Time Use Survey 2024"
  ) +
  theme_minimal() +
  theme(
    text = element_text(family = "ath", size = 9),
    plot.title = element_text(
      family = "ath",
      face = "bold",
      size = 12,
      margin = margin(b = 8)
    ),
    plot.caption = element_text(
      family = "ath",
      size = 7,
      color = "gray50",
      hjust = 0
    ),
    axis.title = element_text(family = "ath", size = 9),
    axis.text = element_text(size = 10),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_line(color = "gray90", linewidth = 0.3),
    plot.margin = margin(10, 10, 10, 10)
  )

night_sleep_vs_age_plot
## `geom_smooth()` using formula = 'y ~ x'

2 A Day in the Life Across Age Groups

high_level_summary <- timeuse_df %>%
  filter(!is.na(activity) & activity != "Unclassified") %>%
  mutate(
    activity_group = case_when(
      activity == "Sleep" ~ "Sleep",
      activity %in% c("Eating & Drinking", "Personal Hygiene & Health", "Receiving Care") ~ "Personal Care",
      activity %in% c(
        "Formal Employment",
        "Household Enterprise (Goods)",
        "Household Enterprise (Services)",
        "Work-Related Training",
        "Seeking Employment",
        "Setting up a Business"
      ) ~ "Paid Work",
      activity %in% c(
        "Food & Meal Management",
        "Cleaning & Maintenance",
        "Childcare & Instruction",
        "Shopping",
        "Agriculture & Fishing (Own-Use)",
        "Community Volunteering",
        "Direct Volunteering"
      ) ~ "Unpaid Work & Care",
      activity %in% c("Formal Education", "Homework", "Additional Study") ~ "Learning",
      TRUE ~ "Leisure, Social & Travel"
    )
  )

person_activity_group_summary <- high_level_summary %>%
  group_by(person_id, activity_group) %>%
  summarise(total_duration = sum(duration_mins, na.rm = TRUE),
            .groups = "drop")

stacking_order <- c(
  "Sleep",
  "Personal Care",
  "Paid Work",
  "Unpaid Work & Care",
  "Learning",
  "Leisure, Social & Travel"
)

# Summary for Total Population
all_persons_age_group <- high_level_summary %>%
  mutate(age_group = cut(
    age,
    breaks = c(5, 14, 24, 59, Inf),
    labels = c(
      "Children\n(6-14)",
      "Youth\n(15-24)",
      "Adults\n(25-59)",
      "Elderly\n(60+)"
    ),
    right = TRUE,
    include.lowest = TRUE
  )) %>%
  filter(!is.na(age_group)) %>%
  distinct(person_id, age_group, mult)

age_group_summary_total <- all_persons_age_group %>%
  tidyr::crossing(activity_group = unique(person_activity_group_summary$activity_group)) %>%
  left_join(person_activity_group_summary,
            by = c("person_id", "activity_group")) %>%
  mutate(total_duration = ifelse(is.na(total_duration), 0, total_duration)) %>%
  group_by(age_group, activity_group) %>%
  summarise(avg_hours = weighted.mean(total_duration, w = mult, na.rm = TRUE) / 60,
            .groups = "drop") %>%
  mutate(activity_group = factor(activity_group, levels = stacking_order))

# Summary by Gender
all_persons_age_gender_group <- high_level_summary %>%
  filter(gender %in% c("male", "female")) %>%
  mutate(age_group = cut(
    age,
    breaks = c(5, 14, 24, 59, Inf),
    labels = c(
      "Children\n(6-14)",
      "Youth\n(15-24)",
      "Adults\n(25-59)",
      "Elderly\n(60+)"
    ),
    right = TRUE,
    include.lowest = TRUE
  )) %>%
  filter(!is.na(age_group)) %>%
  distinct(person_id, age_group, gender, mult)

age_gender_group_summary <- all_persons_age_gender_group %>%
  tidyr::crossing(activity_group = unique(person_activity_group_summary$activity_group)) %>%
  left_join(person_activity_group_summary,
            by = c("person_id", "activity_group")) %>%
  mutate(total_duration = ifelse(is.na(total_duration), 0, total_duration)) %>%
  group_by(age_group, gender, activity_group) %>%
  summarise(avg_hours = weighted.mean(total_duration, w = mult, na.rm = TRUE) / 60,
            .groups = "drop") %>%
  mutate(activity_group = factor(activity_group, levels = stacking_order))

# Summary by Sector
all_persons_age_sector_group <- high_level_summary %>%
  mutate(age_group = cut(
    age,
    breaks = c(5, 14, 24, 59, Inf),
    labels = c(
      "Children\n(6-14)",
      "Youth\n(15-24)",
      "Adults\n(25-59)",
      "Elderly\n(60+)"
    ),
    right = TRUE,
    include.lowest = TRUE
  )) %>%
  filter(!is.na(age_group)) %>%
  distinct(person_id, age_group, sector, mult)

age_sector_group_summary <- all_persons_age_sector_group %>%
  tidyr::crossing(activity_group = unique(person_activity_group_summary$activity_group)) %>%
  left_join(person_activity_group_summary,
            by = c("person_id", "activity_group")) %>%
  mutate(total_duration = ifelse(is.na(total_duration), 0, total_duration)) %>%
  group_by(age_group, sector, activity_group) %>%
  summarise(avg_hours = weighted.mean(total_duration, w = mult, na.rm = TRUE) / 60,
            .groups = "drop") %>%
  mutate(activity_group = factor(activity_group, levels = stacking_order))



# 1. Define consistent colors and a reusable plotting function
activity_colors <- c(
  "Sleep" = "#1B9E77",
  "Personal Care" = "#D95F02",
  "Paid Work" = "#7570B3",
  "Unpaid Work & Care" = "#E7298A",
  "Learning" = "#666666",
  "Leisure, Social & Travel" = "#E6AB02"
)

create_age_strips_plot <- function(data, x_var = "age_group", main_title) {
  ggplot(data, aes(x = .data[[x_var]], y = avg_hours, fill = activity_group)) +
    geom_col(position = "fill", colour = "white", linewidth = 0.2) +
    scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
    scale_fill_manual(values = activity_colors, name = "") +
    labs(
      title = main_title,
      x = NULL,
      y = "% of day",
      caption = "Source: National Time Use Survey 2024"
    ) +
    theme_minimal() +
    theme(
      text = element_text(family = "ath", size = 8),
      plot.title = element_text(
        family = "ath",
        face = "bold",
        size = 12,
        margin = margin(b = 8)
      ),
      plot.caption = element_text(
        family = "ath",
        size = 7,
        color = "gray50",
        hjust = 0
      ),
      legend.position = "bottom",
      legend.text = element_text(size = 9),
      legend.key.size = unit(0.3, "cm"),
      axis.text = element_text(size = 8),
      axis.text.x = element_text(lineheight = 0.4),
      panel.grid = element_blank(),
      plot.margin = margin(10, 10, 10, 10)
    ) +
    guides(fill = guide_legend(nrow = 2, byrow = TRUE))
}

# 2. Generate the individual plots using the function
age_strips_plot_total <- create_age_strips_plot(
  data = age_group_summary_total, 
  main_title = "Time use by age group"
)

age_strips_plot_male <- create_age_strips_plot(
  data = age_gender_group_summary %>% filter(gender == "male"),
  main_title = "Time use by age: Men"
)

age_strips_plot_female <- create_age_strips_plot(
  data = age_gender_group_summary %>% filter(gender == "female"),
  main_title = "Time use by age: Women"
)

age_strips_plot_rural <- create_age_strips_plot(
  data = age_sector_group_summary %>% filter(sector == "Rural"),
  main_title = "Time use by age: Rural"
)

age_strips_plot_urban <- create_age_strips_plot(
  data = age_sector_group_summary %>% filter(sector == "Urban"),
  main_title = "Time use by age: Urban"
)


# 3. Generate the combined plot (it's different due to faceting)
combined_gender_strips_plot <- age_gender_group_summary %>%
  mutate(gender = str_to_title(gender)) %>%
  ggplot(aes(x = gender, y = avg_hours, fill = activity_group)) +
  geom_col(
    position = "fill",
    width = 0.8,
    color = "white",
    linewidth = 0.2
  ) +
  facet_wrap( ~ age_group, nrow = 1) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_fill_manual(values = activity_colors, name = "") +
  labs(
    title = "Time use by gender and age",
    x = NULL,
    y = "% of day",
    caption = "Source: National Time Use Survey 2024"
  ) +
  theme_minimal() +
  theme(
    text = element_text(family = "ath", size = 8),
    plot.title = element_text(
      family = "ath",
      face = "bold",
      size = 10,
      margin = margin(b = 8)
    ),
    plot.caption = element_text(
      family = "ath",
      size = 7,
      color = "gray50",
      hjust = 0
    ),
    legend.position = "bottom",
    legend.text = element_text(size = 7),
    legend.key.size = unit(0.3, "cm"),
    strip.text = element_text(face = "bold", size = 8, lineheight = 0.4),
    axis.text = element_text(size = 7),
    panel.grid = element_blank(),
    panel.spacing = unit(0.3, "lines"),
    plot.margin = margin(10, 10, 10, 10)
  ) +
  guides(fill = guide_legend(nrow = 2, byrow = TRUE))

age_strips_plot_rural

age_strips_plot_urban

age_strips_plot_total

age_strips_plot_male

age_strips_plot_female

combined_gender_strips_plot

2.1 Rural vs. Urban Comparison

all_persons_age_gender_sector_group <- high_level_summary %>%
  filter(gender %in% c("male", "female")) %>%
  mutate(age_group = cut(
    age,
    breaks = c(5, 14, 24, 59, Inf),
    labels = c(
      "Children\n(6-14)",
      "Youth\n(15-24)",
      "Adults\n(25-59)",
      "Elderly\n(60+)"
    ),
    right = TRUE,
    include.lowest = TRUE
  )) %>%
  filter(!is.na(age_group)) %>%
  distinct(person_id, age_group, gender, sector, mult)

age_gender_sector_group_summary <- all_persons_age_gender_sector_group %>%
  tidyr::crossing(activity_group = unique(person_activity_group_summary$activity_group)) %>%
  left_join(person_activity_group_summary,
            by = c("person_id", "activity_group")) %>%
  mutate(total_duration = ifelse(is.na(total_duration), 0, total_duration)) %>%
  group_by(age_group, gender, sector, activity_group) %>%
  summarise(avg_hours = weighted.mean(total_duration, w = mult, na.rm = TRUE) / 60,
            .groups = "drop") %>%
  mutate(activity_group = factor(activity_group, levels = stacking_order))


male_sector_strips_plot <- age_gender_sector_group_summary %>%
  filter(gender == "male") %>%
  ggplot(aes(x = sector, y = avg_hours, fill = activity_group)) +
  geom_col(
    position = "fill",
    width = 0.8,
    color = "white",
    linewidth = 0.2
  ) +
  facet_wrap( ~ age_group, nrow = 1) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_fill_manual(values = activity_colors, name = "") +
  labs(
    title = "Men: Time use by location and age",
    x = NULL,
    y = "% of day",
    caption = "Source: National Time Use Survey 2024"
  ) +
  theme_minimal() +
  theme(
    text = element_text(family = "ath", size = 8),
    plot.title = element_text(
      family = "ath",
      face = "bold",
      size = 10,
      margin = margin(b = 8)
    ),
    plot.caption = element_text(
      family = "ath",
      size = 7,
      color = "gray50",
      hjust = 0
    ),
    legend.position = "bottom",
    legend.text = element_text(size = 7),
    legend.key.size = unit(0.3, "cm"),
    strip.text = element_text(face = "bold", size = 8, lineheight = 0.4),
    axis.text = element_text(size = 7),
    panel.grid = element_blank(),
    panel.spacing = unit(0.3, "lines"),
    plot.margin = margin(10, 10, 10, 10)
  ) +
  guides(fill = guide_legend(nrow = 2, byrow = TRUE))

female_sector_strips_plot <- age_gender_sector_group_summary %>%
  filter(gender == "female") %>%
  ggplot(aes(x = sector, y = avg_hours, fill = activity_group)) +
  geom_col(
    position = "fill",
    width = 0.8,
    color = "white",
    linewidth = 0.2
  ) +
  facet_wrap( ~ age_group, nrow = 1) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  scale_fill_manual(values = activity_colors, name = "") +
  labs(
    title = "Women: Time use by location and age",
    x = NULL,
    y = "% of day",
    caption = "Source: National Time Use Survey 2024"
  ) +
  theme_minimal() +
  theme(
    text = element_text(family = "ath", size = 8),
    plot.title = element_text(
      family = "ath",
      face = "bold",
      size = 10,
      margin = margin(b = 8)
    ),
    plot.caption = element_text(
      family = "ath",
      size = 7,
      color = "gray50",
      hjust = 0
    ),
    legend.position = "bottom",
    legend.text = element_text(size = 7),
    legend.key.size = unit(0.3, "cm"),
    strip.text = element_text(face = "bold", size = 8, lineheight = 0.4),
    axis.text = element_text(size = 7),
    panel.grid = element_blank(),
    panel.spacing = unit(0.3, "lines"),
    plot.margin = margin(10, 10, 10, 10)
  ) +
  guides(fill = guide_legend(nrow = 2, byrow = TRUE))

male_sector_strips_plot

female_sector_strips_plot

3 Exports and Download

dir.create("shortlisted_textbook", showWarnings = FALSE)

export_theme <- theme(
  plot.title = element_text(size = 20, face = "bold"),
  plot.subtitle = element_text(size = 16),
  plot.caption = element_text(size = 11),
  axis.title = element_text(size = 14),
  axis.text = element_text(size = 14),
  legend.text = element_text(size = 14),
  legend.title = element_text(size = 14),
  strip.text = element_text(size = 14, face = "bold"),
  legend.key.size = unit(0.4, "cm")
)

# 1. Sleep plots - compact single-column width (4" x 3.5")
ggsave(filename = "shortlisted_textbook/01_sleep_vs_age.png",
       plot = sleep_vs_age_plot + export_theme,
       width = 2, height = 2, dpi = 300, units = "in")
## `geom_smooth()` using formula = 'y ~ x'
ggsave(filename = "shortlisted_textbook/02_essential_sleep_vs_age.png",
       plot = night_sleep_vs_age_plot + export_theme,
       width = 2, height = 2, dpi = 300, units = "in")
## `geom_smooth()` using formula = 'y ~ x'
# 2. Simple strip plots - slightly wider (5" x 4")
ggsave(filename = "shortlisted_textbook/03_age_strips_total.png",
       plot = age_strips_plot_total + export_theme,
       width = 3, height = 3, dpi = 300, units = "in")

ggsave(filename = "shortlisted_textbook/04_age_strips_rural.png",
       plot = age_strips_plot_rural + export_theme,
       width = 3, height = 3, dpi = 300, units = "in")

ggsave(filename = "shortlisted_textbook/05_age_strips_urban.png",
       plot = age_strips_plot_urban + export_theme,
       width = 3, height = 3, dpi = 300, units = "in")

# 3. Gender-specific plots (5" x 4")
ggsave(filename = "shortlisted_textbook/06_age_strips_male.png",
       plot = age_strips_plot_male + export_theme,
       width = 3, height = 3, dpi = 300, units = "in")

ggsave(filename = "shortlisted_textbook/07_age_strips_female.png",
       plot = age_strips_plot_female + export_theme,
       width = 3, height = 3, dpi = 300, units = "in")

# 4. Faceted plots - wider for readability (6.5" x 4")
ggsave(filename = "shortlisted_textbook/08_combined_gender_strips.png",
       plot = combined_gender_strips_plot + export_theme,
       width = 4, height = 3, dpi = 300, units = "in")

ggsave(filename = "shortlisted_textbook/09_male_sector_strips.png",
       plot = male_sector_strips_plot + export_theme,
       width = 4, height = 3, dpi = 300, units = "in")

ggsave(filename = "shortlisted_textbook/10_female_sector_strips.png",
       plot = female_sector_strips_plot + export_theme,
       width = 4, height = 3, dpi = 300, units = "in")
zip_file <- "time_use_textbook_bundle.zip"
files_to_zip <- c(
  list.files("shortlisted_textbook", full.names = TRUE, pattern = "\\.png$"),
  "shortlisted-tus-2024.Rmd"
)

if (file.exists(zip_file)) file.remove(zip_file)
zip::zip(zipfile = zip_file, files = files_to_zip, mode = "cherry-pick")

download_file(
  path = zip_file,
  output_name = "Download Textbook Bundle (ZIP)",
  button_label = "Download Bundle",
  button_type = "success",
  has_icon = TRUE,
  icon = "fa fa-download",
  self_contained = TRUE
)
LS0tCnRpdGxlOiAiU2hvcnRsaXN0ZWQgVFVTIDIwMjQgR3JhcGhzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRoZW1lOiByZWFkYWJsZQogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBmaWdfd2lkdGg6IDEwCiAgICBmaWdfaGVpZ2h0OiA4CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgc2VsZl9jb250YWluZWQ6IHRydWUKICAgIGtlZXBfbWQ6IGZhbHNlCmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoYXJyb3cpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGhyYnJ0aGVtZXMpCmxpYnJhcnkoc2hvd3RleHQpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShnZ3RleHQpCmxpYnJhcnkoZ2x1ZSkKbGlicmFyeShnZ3RoZW1lcykKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkoemlwKQpsaWJyYXJ5KGRvd25sb2FkdGhpcykKCmZvbnRfYWRkX2dvb2dsZSgiQXRraW5zb24gSHlwZXJsZWdpYmxlIiwgImF0aCIpCnNob3d0ZXh0X2F1dG8oKQoKZm9ybWF0X2hvdXJzX21pbnV0ZXMgPC0gZnVuY3Rpb24oeCkgewogIG91dCA8LSByZXAoTkFfY2hhcmFjdGVyXywgbGVuZ3RoKHgpKQogIHZhbGlkX2luZGljZXMgPC0gIWlzLm5hKHgpCiAgaWYgKCFhbnkodmFsaWRfaW5kaWNlcykpIHsKICAgIHJldHVybihvdXQpCiAgfQogIHZhbGlkX3ggPC0geFt2YWxpZF9pbmRpY2VzXQogIGhvdXJzIDwtIGZsb29yKHZhbGlkX3gpCiAgbWludXRlcyA8LSByb3VuZCgodmFsaWRfeCAlJSAxKSAqIDYwKQogIGlzXzYwIDwtIG1pbnV0ZXMgPT0gNjAKICBob3Vyc1tpc182MF0gPC0gaG91cnNbaXNfNjBdICsgMQogIG1pbnV0ZXNbaXNfNjBdIDwtIDAKICBmb3JtYXR0ZWRfc3RyaW5ncyA8LSBjYXNlX3doZW4oCiAgICBob3VycyA8IDEgfiBzcHJpbnRmKCIlZG0iLCBhcy5pbnRlZ2VyKG1pbnV0ZXMpKSwKICAgIG1pbnV0ZXMgPT0gMCB+IHNwcmludGYoIiVkaCIsIGFzLmludGVnZXIoaG91cnMpKSwKICAgIFRSVUUgfiBzcHJpbnRmKCIlZGggJTAyZG0iLCBhcy5pbnRlZ2VyKGhvdXJzKSwgYXMuaW50ZWdlcihtaW51dGVzKSkKICApCiAgb3V0W3ZhbGlkX2luZGljZXNdIDwtIGZvcm1hdHRlZF9zdHJpbmdzCiAgcmV0dXJuKG91dCkKfQoKCnRyeUNhdGNoKHsKICB0aW1ldXNlX2RmIDwtIGFycm93OjpyZWFkX3BhcnF1ZXQoInRpbWV1c2UucGFycXVldCIpCiAgcHJpbnQoIlN1Y2Nlc3NmdWxseSBsb2FkZWQgdGhlIHRpbWV1c2UucGFycXVldCBmaWxlLiIpCn0sIGVycm9yID0gZnVuY3Rpb24oZSkgewogIHByaW50KAogICAgIkVycm9yIGxvYWRpbmcgcGFycXVldCBmaWxlLiBNYWtlIHN1cmUgdGhlIGZpbGUgJ3RpbWV1c2UucGFycXVldCcgaXMgaW4geW91ciB3b3JraW5nIGRpcmVjdG9yeS4iCiAgKQogIHByaW50KGUpCn0pCgpjYWxjdWxhdGVfZHVyYXRpb24gPC0gZnVuY3Rpb24oZGYpIHsKICBkZiAlPiUKICAgIG11dGF0ZSgKICAgICAgc3RhcnRfc2VjcyA9IGx1YnJpZGF0ZTo6cGVyaW9kX3RvX3NlY29uZHMobHVicmlkYXRlOjpobSh0aW1lX2Zyb20pKSwKICAgICAgZW5kX3NlY3MgPSBsdWJyaWRhdGU6OnBlcmlvZF90b19zZWNvbmRzKGx1YnJpZGF0ZTo6aG0odGltZV90bykpLAogICAgICBkdXJhdGlvbl9taW5zID0gKGVuZF9zZWNzIC0gc3RhcnRfc2VjcykgLyA2MCwKICAgICAgZHVyYXRpb25fbWlucyA9IGlmZWxzZShkdXJhdGlvbl9taW5zIDwgMCwgZHVyYXRpb25fbWlucyArIDE0NDAsIGR1cmF0aW9uX21pbnMpCiAgICApCn0KCnRpbWV1c2VfZGYgPC0gY2FsY3VsYXRlX2R1cmF0aW9uKHRpbWV1c2VfZGYpCgp0aW1ldXNlX2RmIDwtIHRpbWV1c2VfZGYgJT4lCiAgbXV0YXRlKAogICAgYWN0aXZpdHkgPSBjYXNlX3doZW4oCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJFbXBsb3ltZW50IGluIGNvcnBvcmF0aW9ucywgZ292ZXJubWVudCBhbmQgbm9uLXByb2ZpdCBpbnN0aXR1dGlvbnMiCiAgICAgICkgfiAiRm9ybWFsIEVtcGxveW1lbnQiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiR3Jvd2luZyBvZiBjcm9wcyBmb3IgdGhlIG1hcmtldCBpbiBob3VzZWhvbGQgZW50ZXJwcmlzZXMiLAogICAgICAgICJSYWlzaW5nIGFuaW1hbHMgZm9yIHRoZSBtYXJrZXQgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIiwKICAgICAgICAiRm9yZXN0cnkgYW5kIGxvZ2dpbmcgZm9yIHRoZSBtYXJrZXQgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIiwKICAgICAgICAiRmlzaGluZyBmb3IgdGhlIG1hcmtldCBpbiBob3VzZWhvbGQgZW50ZXJwcmlzZXMiLAogICAgICAgICJBcXVhY3VsdHVyZSBmb3IgdGhlIG1hcmtldCBpbiBob3VzZWhvbGQgZW50ZXJwcmlzZXMiLAogICAgICAgICJNaW5pbmcgYW5kIHF1YXJyeWluZyBmb3IgdGhlIG1hcmtldCBpbiBob3VzZWhvbGQgZW50ZXJwcmlzZXMiLAogICAgICAgICJNYWtpbmcgYW5kIHByb2Nlc3NpbmcgZ29vZHMgZm9yIHRoZSBtYXJrZXQgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIiwKICAgICAgICAiQ29uc3RydWN0aW9uIGFjdGl2aXRpZXMgZm9yIHRoZSBtYXJrZXQgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIiwKICAgICAgICAiT3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIGVtcGxveW1lbnQgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIHRvIHByb2R1Y2UgZ29vZHMiCiAgICAgICkgfiAiSG91c2Vob2xkIEVudGVycHJpc2UgKEdvb2RzKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJWZW5kaW5nIGFuZCB0cmFkaW5nIG9mIGdvb2RzIGluIGhvdXNlaG9sZCBlbnRlcnByaXNlcyIsCiAgICAgICAgIlByb3ZpZGluZyBwYWlkIHJlcGFpciwgaW5zdGFsbGF0aW9uLCBtYWludGVuYW5jZSBhbmQgZGlzcG9zYWwgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIiwKICAgICAgICAiUHJvdmlkaW5nIHBhaWQgYnVzaW5lc3MgYW5kIHByb2Zlc3Npb25hbCBzZXJ2aWNlcyBpbiBob3VzZWhvbGQgZW50ZXJwcmlzZXMiLAogICAgICAgICJUcmFuc3BvcnRpbmcgZ29vZHMgYW5kIHBhc3NlbmdlcnMgZm9yIHBheSBvciBwcm9maXQgaW4gaG91c2Vob2xkIGVudGVycHJpc2VzIiwKICAgICAgICAiUHJvdmlkaW5nIHBhaWQgcGVyc29uYWwgY2FyZSBzZXJ2aWNlcyBpbiBob3VzZWhvbGQgZW50ZXJwcmlzZXMiLAogICAgICAgICJQcm92aWRpbmcgcGFpZCBkb21lc3RpYyBzZXJ2aWNlcyIsCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBlbXBsb3ltZW50IGluIGhvdXNlaG9sZCBlbnRlcnByaXNlcyBwcm92aWRpbmcgc2VydmljZXMiCiAgICAgICkgfiAiSG91c2Vob2xkIEVudGVycHJpc2UgKFNlcnZpY2VzKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJBY3Rpdml0aWVzIGFuY2lsbGFyeSB0byBlbXBsb3ltZW50IiwKICAgICAgICAiQnJlYWtzIGR1cmluZyB3b3JraW5nIHRpbWUgd2l0aGluIGVtcGxveW1lbnQiCiAgICAgICkgfiAiQW5jaWxsYXJ5ICYgQnJlYWtzIChXb3JrKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJUcmFpbmluZyBhbmQgc3R1ZGllcyBpbiByZWxhdGlvbiB0byBlbXBsb3ltZW50IikgfiAiV29yay1SZWxhdGVkIFRyYWluaW5nIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoIlNlZWtpbmcgZW1wbG95bWVudCIpIH4gIlNlZWtpbmcgRW1wbG95bWVudCIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJTZXR0aW5nIHVwIGEgYnVzaW5lc3MiKSB+ICJTZXR0aW5nIHVwIGEgQnVzaW5lc3MiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygiRW1wbG95bWVudC1yZWxhdGVkIHRyYXZlbCIsICJDb21tdXRpbmciKSB+ICJUcmF2ZWwgKFdvcmspIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIkdyb3dpbmcgY3JvcHMgYW5kIGtpdGNoZW4gZ2FyZGVuaW5nLCBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIkZhcm1pbmcgb2YgYW5pbWFscyBhbmQgcHJvZHVjdGlvbiBvZiBhbmltYWwgcHJvZHVjdHMgZm9yIG93biBmaW5hbCB1c2UiLAogICAgICAgICJIdW50aW5nLCB0cmFwcGluZyBhbmQgcHJvZHVjdGlvbiBvZiBhbmltYWwgc2tpbnMgZm9yIG93biBmaW5hbCB1c2UiLAogICAgICAgICJGb3Jlc3RyeSBhbmQgbG9nZ2luZyBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIkdhdGhlcmluZyB3aWxkIHByb2R1Y3RzIGZvciBvd24gZmluYWwgdXNlIiwKICAgICAgICAiRmlzaGluZyBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIkFxdWFjdWx0dXJlIGZvciBvd24gZmluYWwgdXNlIiwKICAgICAgICAiTWluaW5nIGFuZCBxdWFycnlpbmcgZm9yIG93biBmaW5hbCB1c2UiCiAgICAgICkgfiAiQWdyaWN1bHR1cmUgJiBGaXNoaW5nIChPd24tVXNlKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJNYWtpbmcsIHByb2Nlc3NpbmcgZm9vZCBwcm9kdWN0cywgYmV2ZXJhZ2VzIGFuZCB0b2JhY2NvIGZvciBvd24gZmluYWwgdXNlIiwKICAgICAgICAiTWFraW5nLCBwcm9jZXNzaW5nIHRleHRpbGVzLCB3ZWFyaW5nIGFwcGFyZWwsIGxlYXRoZXIgYW5kIHJlbGF0ZWQgcHJvZHVjdHMgZm9yIG93biBmaW5hbCB1c2UiLAogICAgICAgICJNYWtpbmcsIHByb2Nlc3Npbmcgb2Ygd29vZCBhbmQgYmFyayBwcm9kdWN0cyBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIk1ha2luZywgcHJvY2Vzc2luZyBicmlja3MsIGNvbmNyZXRlIHNsYWJzLCBob2xsb3cgYmxvY2tzLCB0aWxlcyBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIk1ha2luZywgcHJvY2Vzc2luZyBoZXJiYWwgYW5kIG1lZGljaW5hbCBwcmVwYXJhdGlvbnMgZm9yIG93biBmaW5hbCB1c2UiLAogICAgICAgICJNYWtpbmcsIHByb2Nlc3NpbmcgbWV0YWxzIGFuZCBtZXRhbCBwcm9kdWN0cyBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIk1ha2luZywgcHJvY2Vzc2luZyBvZiBwcm9kdWN0cyB1c2luZyBvdGhlciBtYXRlcmlhbHMgZm9yIG93biBmaW5hbCB1c2UiLAogICAgICAgICJBY3F1aXJpbmcgc3VwcGxpZXMgYW5kIGRpc3Bvc2luZyBvZiBwcm9kdWN0cyBhbmQgb3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIG1ha2luZyBhbmQgcHJvY2Vzc2luZyBnb29kcyBmb3Igb3duIGZpbmFsIHVzZSIKICAgICAgKSB+ICJQcm9jZXNzaW5nIEdvb2RzIChPd24tVXNlKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJDb25zdHJ1Y3Rpb24gYWN0aXZpdGllcyBmb3Igb3duIGZpbmFsIHVzZSIpIH4gIkNvbnN0cnVjdGlvbiAoT3duLVVzZSkiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiR2F0aGVyaW5nIGZpcmV3b29kIGFuZCBvdGhlciBuYXR1cmFsIHByb2R1Y3RzIHVzZWQgYXMgZnVlbCBmb3Igb3duIGZpbmFsIHVzZSIsCiAgICAgICAgIkZldGNoaW5nIHdhdGVyIGZyb20gbmF0dXJhbCBhbmQgb3RoZXIgc291cmNlcyBmb3Igb3duIGZpbmFsIHVzZSIKICAgICAgKSB+ICJDb2xsZWN0aW5nIFdhdGVyICYgRnVlbCAoT3duLVVzZSkiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiVHJhdmVsbGluZywgbW92aW5nLCB0cmFuc3BvcnRpbmcgb3IgYWNjb21wYW55aW5nIGdvb2RzIG9yIHBlcnNvbnMgcmVsYXRlZCB0byBvd24tdXNlIHByb2R1Y3Rpb24gb2YgZ29vZHMiCiAgICAgICkgfiAiVHJhdmVsIChPd24tVXNlIFByb2R1Y3Rpb24pIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlByZXBhcmluZyBtZWFscy9zbmFja3MiLAogICAgICAgICJTZXJ2aW5nIG1lYWxzL3NuYWNrcyIsCiAgICAgICAgIkNsZWFuaW5nIHVwIGFmdGVyIGZvb2QgcHJlcGFyYXRpb24vbWVhbHMvc25hY2tzIiwKICAgICAgICAiU3RvcmluZywgYXJyYW5naW5nLCBwcmVzZXJ2aW5nIGZvb2Qgc3RvY2tzIiwKICAgICAgICAiT3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIGZvb2QgYW5kIG1lYWxzIG1hbmFnZW1lbnQgYW5kIHByZXBhcmF0aW9uIgogICAgICApIH4gIkZvb2QgJiBNZWFsIE1hbmFnZW1lbnQiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiSW5kb29yIGNsZWFuaW5nIiwKICAgICAgICAiT3V0ZG9vciBjbGVhbmluZyIsCiAgICAgICAgIlJlY3ljbGluZyBhbmQgZGlzcG9zYWwgb2YgZ2FyYmFnZSIsCiAgICAgICAgIlVwa2VlcCBvZiBpbmRvb3Ivb3V0ZG9vciBwbGFudHMsIGhlZGdlcywgZ2FyZGVuLCBncm91bmRzLCBsYW5kc2NhcGUsIGV0Yy4iLAogICAgICAgICJUZW5kaW5nIGZ1cm5hY2UsIGJvaWxlciwgZmlyZXBsYWNlIGZvciBoZWF0aW5nIGFuZCB3YXRlciBzdXBwbHkiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gY2xlYW5pbmcgYW5kIHVwa2VlcCBvZiBkd2VsbGluZyBhbmQgc3Vycm91bmRpbmdzIgogICAgICApIH4gIkNsZWFuaW5nICYgTWFpbnRlbmFuY2UiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiRG8taXQteW91cnNlbGYgaW1wcm92ZW1lbnQsIG1haW50ZW5hbmNlIGFuZCByZXBhaXIgb2Ygb3duIGR3ZWxsaW5nIiwKICAgICAgICAiSW5zdGFsbGF0aW9uLCBzZXJ2aWNpbmcgYW5kIHJlcGFpciBvZiBwZXJzb25hbCBhbmQgaG91c2Vob2xkIGdvb2RzIGluY2x1ZGluZyBJQ1QgZXF1aXBtZW50IiwKICAgICAgICAiVmVoaWNsZSBtYWludGVuYW5jZSBhbmQgcmVwYWlycyIsCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBkby1pdC15b3Vyc2VsZiBkZWNvcmF0aW9uLCBtYWludGVuYW5jZSBhbmQgcmVwYWlyIgogICAgICApIH4gIkRJWSBNYWludGVuYW5jZSAmIFJlcGFpciIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJIYW5kL21hY2hpbmUtd2FzaGluZyIsCiAgICAgICAgIkRyeWluZyB0ZXh0aWxlcyBhbmQgY2xvdGhpbmciLAogICAgICAgICJJcm9uaW5nL3ByZXNzaW5nL2ZvbGRpbmciLAogICAgICAgICJNZW5kaW5nL3JlcGFpcmluZyBhbmQgY2FyZSBvZiBjbG90aGVzIGFuZCBzaG9lczsgY2xlYW5pbmcgYW5kIHBvbGlzaGluZyBzaG9lcyIsCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBjYXJlIG9mIHRleHRpbGVzIGFuZCBmb290d2VhciIKICAgICAgKSB+ICJUZXh0aWxlcyAmIEZvb3R3ZWFyIENhcmUiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiUGF5aW5nIGhvdXNlaG9sZCBiaWxscyIsCiAgICAgICAgIkJ1ZGdldGluZywgcGxhbm5pbmcsIG9yZ2FuaXppbmcgZHV0aWVzIGFuZCBhY3Rpdml0aWVzIGluIHRoZSBob3VzZWhvbGQiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gaG91c2Vob2xkIG1hbmFnZW1lbnQiCiAgICAgICkgfiAiSG91c2Vob2xkIE1hbmFnZW1lbnQiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiRGFpbHkgcGV0IGNhcmUiLAogICAgICAgICJVc2luZyB2ZXRlcmluYXJ5IGNhcmUgb3Igb3RoZXIgcGV0IGNhcmUgc2VydmljZXMgKGdyb29taW5nLCBzdGFibGluZywgaG9saWRheSBvciBkYXkgY2FyZSkiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gcGV0IGNhcmUiCiAgICAgICkgfiAiUGV0IENhcmUiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiU2hvcHBpbmcgZm9yL3B1cmNoYXNpbmcgb2YgZ29vZHMgYW5kIHJlbGF0ZWQgYWN0aXZpdGllcyIsCiAgICAgICAgIlNob3BwaW5nIGZvci9hdmFpbGluZyBvZiBzZXJ2aWNlcyBhbmQgcmVsYXRlZCBhY3Rpdml0eSIKICAgICAgKSB+ICJTaG9wcGluZyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJUcmF2ZWxsaW5nLCBtb3ZpbmcsIHRyYW5zcG9ydGluZyBvciBhY2NvbXBhbnlpbmcgZ29vZHMgb3IgcGVyc29ucyByZWxhdGVkIHRvIHVucGFpZCBkb21lc3RpYyBzZXJ2aWNlcyBmb3IgaG91c2Vob2xkIG1lbWJlcnMiCiAgICAgICkgfiAiVHJhdmVsIChEb21lc3RpYyBTZXJ2aWNlcykiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygiT3RoZXIgdW5wYWlkIGRvbWVzdGljIHNlcnZpY2VzIGZvciBob3VzZWhvbGQgbWVtYmVycyIpIH4gIk90aGVyIERvbWVzdGljIFNlcnZpY2VzIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIkNhcmluZyBmb3IgY2hpbGRyZW4gaW5jbHVkaW5nIGZlZWRpbmcsIGNsZWFuaW5nLCBwaHlzaWNhbCBjYXJlIiwKICAgICAgICAiUHJvdmlkaW5nIG1lZGljYWwgY2FyZSB0byBjaGlsZHJlbiIsCiAgICAgICAgIkluc3RydWN0aW5nLCB0ZWFjaGluZywgdHJhaW5pbmcsIGhlbHBpbmcgY2hpbGRyZW4iLAogICAgICAgICJUYWxraW5nIHdpdGggYW5kIHJlYWRpbmcgdG8gY2hpbGRyZW4iLAogICAgICAgICJQbGF5aW5nIGFuZCBzcG9ydHMgd2l0aCBjaGlsZHJlbiIsCiAgICAgICAgIk1pbmRpbmcgY2hpbGRyZW4gKHBhc3NpdmUgY2FyZSkiLAogICAgICAgICJNZWV0aW5ncyBhbmQgYXJyYW5nZW1lbnRzIHdpdGggc2Nob29scyBhbmQgY2hpbGQgY2FyZSBzZXJ2aWNlIHByb3ZpZGVycyIsCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBjaGlsZGNhcmUgYW5kIGluc3RydWN0aW9uIgogICAgICApIH4gIkNoaWxkY2FyZSAmIEluc3RydWN0aW9uIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIkFzc2lzdGluZyBkZXBlbmRlbnQgYWR1bHRzIHdpdGggdGFza3Mgb2YgZGFpbHkgbGl2aW5nIiwKICAgICAgICAiQXNzaXN0aW5nIGRlcGVuZGVudCBhZHVsdHMgd2l0aCBtZWRpY2FsIGNhcmUiLAogICAgICAgICJBc3Npc3RpbmcgZGVwZW5kZW50IGFkdWx0cyB3aXRoIGZvcm1zLCBhZG1pbmlzdHJhdGlvbiwgYWNjb3VudHMiLAogICAgICAgICJBZmZlY3RpdmUvZW1vdGlvbmFsIHN1cHBvcnQgZm9yIGRlcGVuZGVudCBhZHVsdHMiLAogICAgICAgICJQYXNzaXZlIGNhcmUgb2YgZGVwZW5kZW50IGFkdWx0IiwKICAgICAgICAiTWVldGluZ3MgYW5kIGFycmFuZ2VtZW50cyB3aXRoIGFkdWx0IGNhcmUgc2VydmljZSBwcm92aWRlcnMiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gY2FyZSBmb3IgZGVwZW5kZW50IGFkdWx0cyIKICAgICAgKSB+ICJDYXJlIGZvciBEZXBlbmRlbnQgQWR1bHRzIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIkZlZWRpbmcsIGNsZWFuaW5nLCBwaHlzaWNhbCBjYXJlIGZvciBub24tZGVwZW5kZW50IGFkdWx0IGhvdXNlaG9sZCBtZW1iZXJzIGluY2x1ZGluZyBmb3IgdGVtcG9yYXJ5IGlsbG5lc3MiLAogICAgICAgICJBZmZlY3RpdmUvZW1vdGlvbmFsIHN1cHBvcnQgZm9yIG5vbi1kZXBlbmRlbnQgYWR1bHQgaG91c2Vob2xkIG1lbWJlcnMiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gY2FyZSBmb3Igbm9uLWRlcGVuZGVudCBhZHVsdCBob3VzZWhvbGQgbWVtYmVycyIKICAgICAgKSB+ICJIZWxwIHRvIE5vbi1EZXBlbmRlbnQgQWR1bHRzIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlRyYXZlbGxpbmcgcmVsYXRlZCB0byBjYXJlLWdpdmluZyBzZXJ2aWNlcyBmb3IgaG91c2Vob2xkIG1lbWJlcnMiLAogICAgICAgICJBY2NvbXBhbnlpbmcgb3duIGNoaWxkcmVuIiwKICAgICAgICAiQWNjb21wYW55aW5nIGRlcGVuZGVudCBhZHVsdHMiLAogICAgICAgICJBY2NvbXBhbnlpbmcgbm9uLWRlcGVuZGVudCBhZHVsdCBob3VzZWhvbGQgbWVtYmVycyIKICAgICAgKSB+ICJUcmF2ZWwgKENhcmVnaXZpbmcpIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byB1bnBhaWQgY2FyZWdpdmluZyBzZXJ2aWNlcyBmb3IgaG91c2Vob2xkIG1lbWJlcnMiCiAgICAgICkgfiAiT3RoZXIgQ2FyZWdpdmluZyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJVbnBhaWQgdm9sdW50ZWVyIGhvdXNlaG9sZCBtYWludGVuYW5jZSwgbWFuYWdlbWVudCwgY29uc3RydWN0aW9uLCByZW5vdmF0aW9uIGFuZCByZXBhaXIiLAogICAgICAgICJVbnBhaWQgdm9sdW50ZWVyIHNob3BwaW5nL3B1cmNoYXNpbmcgZ29vZHMgYW5kIHNlcnZpY2VzIiwKICAgICAgICAiVW5wYWlkIHZvbHVudGVlciBjaGlsZGNhcmUgYW5kIGluc3RydWN0aW9uIiwKICAgICAgICAiVW5wYWlkIHZvbHVudGVlciBjYXJlIGZvciBhZHVsdHMiLAogICAgICAgICJVbnBhaWQgdm9sdW50ZWVyIGFjdGl2aXRpZXMgaW4gZW50ZXJwcmlzZXMgb3duZWQgYnkgb3RoZXIgaG91c2Vob2xkcyIsCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBkaXJlY3QgdW5wYWlkIHZvbHVudGVlcmluZyBmb3Igb3RoZXIgaG91c2Vob2xkcyIKICAgICAgKSB+ICJEaXJlY3QgVm9sdW50ZWVyaW5nIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlVucGFpZCB2b2x1bnRlZXIgd29yayBvbiByb2FkL2J1aWxkaW5nIHJlcGFpciwgY2xlYXJpbmcgYW5kIHByZXBhcmluZyBsYW5kLCBjbGVhbmluZyAoc3RyZWV0cywgbWFya2V0cywgZXRjLiksIGFuZCBjb25zdHJ1Y3Rpb24iLAogICAgICAgICJVbnBhaWQgdm9sdW50ZWVyIHByZXBhcmluZy9zZXJ2aW5nIG1lYWxzLCBjbGVhbmluZyB1cCIsCiAgICAgICAgIlVucGFpZCB2b2x1bnRlZXIgY3VsdHVyYWwgYWN0aXZpdGllcywgcmVjcmVhdGlvbiBhbmQgc3BvcnRzIGFjdGl2aXRpZXMiLAogICAgICAgICJVbnBhaWQgdm9sdW50ZWVyIG9mZmljZS9hZG1pbmlzdHJhdGl2ZSB3b3JrIiwKICAgICAgICAiT3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIGNvbW11bml0eS0gYW5kIG9yZ2FuaXphdGlvbmJhc2VkIHVucGFpZCB2b2x1bnRlZXJpbmciCiAgICAgICkgfiAiQ29tbXVuaXR5IFZvbHVudGVlcmluZyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJVbnBhaWQgdHJhaW5lZSB3b3JrIGFuZCByZWxhdGVkIGFjdGl2aXRpZXMiKSB+ICJUcmFpbmVlIFdvcmsiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiVHJhdmVsbGluZyB0aW1lIHJlbGF0ZWQgdG8gdW5wYWlkIHZvbHVudGVlciwgdHJhaW5lZSBhbmQgb3RoZXIgdW5wYWlkIHdvcmsiCiAgICAgICkgfiAiVHJhdmVsIChWb2x1bnRlZXJpbmcpIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoIk90aGVyIHVucGFpZCB3b3JrIGFjdGl2aXRpZXMiKSB+ICJPdGhlciBVbnBhaWQgV29yayIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJTY2hvb2wvdW5pdmVyc2l0eSBhdHRlbmRhbmNlIiwKICAgICAgICAiRXh0cmEtY3VycmljdWxhciBhY3Rpdml0aWVzIiwKICAgICAgICAiQnJlYWtzIGF0IHBsYWNlIG9mIGZvcm1hbCBlZHVjYXRpb24iLAogICAgICAgICJTZWxmLXN0dWR5IGZvciBkaXN0YW5jZSBlZHVjYXRpb24gY291cnNlIHdvcmsgKHZpZGVvLCBhdWRpbywgb25saW5lKSIsCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBmb3JtYWwgZWR1Y2F0aW9uIgogICAgICApIH4gIkZvcm1hbCBFZHVjYXRpb24iLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiSG9tZXdvcmssIGJlaW5nIHR1dG9yZWQsIGNvdXJzZSByZXZpZXcsIHJlc2VhcmNoIGFuZCBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gZm9ybWFsIGVkdWNhdGlvbiIKICAgICAgKSB+ICJIb21ld29yayIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJBZGRpdGlvbmFsIHN0dWR5LCBub24tZm9ybWFsIGVkdWNhdGlvbiBhbmQgY291cnNlcyIpIH4gIkFkZGl0aW9uYWwgU3R1ZHkiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygiVHJhdmVsbGluZyB0aW1lIHJlbGF0ZWQgdG8gbGVhcm5pbmciKSB+ICJUcmF2ZWwgKExlYXJuaW5nKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gbGVhcm5pbmciKSB+ICJPdGhlciBMZWFybmluZyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJUYWxraW5nLCBjb252ZXJzaW5nLCBjaGF0dGluZyIsCiAgICAgICAgIlNvY2lhbGl6aW5nL2dldHRpbmcgdG9nZXRoZXIvZ2F0aGVyaW5nIGFjdGl2aXRpZXMiLAogICAgICAgICJSZWFkaW5nIGFuZCB3cml0aW5nIG1haWwgKGluY2x1ZGluZyBlbWFpbCkiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gc29jaWFsaXppbmcgYW5kIGNvbW11bmljYXRpb24iCiAgICAgICkgfiAiU29jaWFsaXppbmcgJiBDb21tdW5pY2F0aW9uIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlBhcnRpY2lwYXRpbmcgaW4gY29tbXVuaXR5IGNlbGVicmF0aW9ucyBvZiBjdWx0dXJhbC9oaXN0b3JpYyBldmVudHMiLAogICAgICAgICJQYXJ0aWNpcGF0aW5nIGluIGNvbW11bml0eSByaXRlcy9ldmVudHMgKG5vbi1yZWxpZ2lvdXMpIG9mIHdlZGRpbmdzLCBmdW5lcmFscywgYmlydGhzIGFuZCBzaW1pbGFyIHJpdGVzLW9mcGFzc2FnZSIsCiAgICAgICAgIlBhcnRpY2lwYXRpbmcgaW4gY29tbXVuaXR5IHNvY2lhbCBmdW5jdGlvbnMgKG11c2ljLCBkYW5jZSwgZXRjLikiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gY29tbXVuaXR5IHBhcnRpY2lwYXRpb24iCiAgICAgICkgfiAiQ29tbXVuaXR5IEV2ZW50cyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJJbnZvbHZlbWVudCBpbiBjaXZpYyBhbmQgcmVsYXRlZCByZXNwb25zaWJpbGl0aWVzIikgfiAiQ2l2aWMgUmVzcG9uc2liaWxpdGllcyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJQcml2YXRlIHByYXllciwgbWVkaXRhdGlvbiBhbmQgb3RoZXIgc3Bpcml0dWFsIGFjdGl2aXRpZXMiLAogICAgICAgICJQYXJ0aWNpcGF0aW5nIGluIGNvbGxlY3RpdmUgcmVsaWdpb3VzIHByYWN0aWNlIiwKICAgICAgICAiT3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIHJlbGlnaW91cyBwcmFjdGljZSIKICAgICAgKSB+ICJSZWxpZ2lvdXMgUHJhY3RpY2VzIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlRyYXZlbGxpbmcgdGltZSByZWxhdGVkIHRvIHNvY2lhbGl6aW5nIGFuZCBjb21tdW5pY2F0aW9uLCBjb21tdW5pdHkgcGFydGljaXBhdGlvbiBhbmQgcmVsaWdpb3VzIHByYWN0aWNlIgogICAgICApIH4gIlRyYXZlbCAoU29jaWFsL0NvbW11bml0eSkiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiQXR0ZW5kYW5jZSBhdCBvcmdhbml6ZWQvbWFzcyBjdWx0dXJhbCBldmVudHMgYW5kIHNob3dzIiwKICAgICAgICAiQXR0ZW5kYW5jZSBhdCBwYXJrcy9nYXJkZW5zIiwKICAgICAgICAiQXR0ZW5kYW5jZSBhdCBzcG9ydHMgZXZlbnRzIiwKICAgICAgICAiT3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIGF0dGVuZGFuY2UgYXQgY3VsdHVyYWwsIGVudGVydGFpbm1lbnQgYW5kIHNwb3J0cyBldmVudHMiCiAgICAgICkgfiAiQXR0ZW5kaW5nIEV2ZW50cyIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJWaXN1YWwsIGxpdGVyYXJ5IGFuZCBwZXJmb3JtaW5nIGFydHMgKGFzIGhvYmJ5KSIsCiAgICAgICAgIkhvYmJpZXMiLAogICAgICAgICJQbGF5aW5nIGdhbWVzIGFuZCBvdGhlciBwYXN0aW1lIGFjdGl2aXRpZXMiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gY3VsdHVyYWwgcGFydGljaXBhdGlvbiwgaG9iYmllcywgZ2FtZXMiCiAgICAgICkgfiAiSG9iYmllcyAmIEdhbWVzIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoIlBhcnRpY2lwYXRpbmcgaW4gc3BvcnRzIiwgIkV4ZXJjaXNpbmciKSB+ICJTcG9ydHMgJiBFeGVyY2lzZSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKAogICAgICAgICJSZWFkaW5nIGZvciBsZWlzdXJlIiwKICAgICAgICAiV2F0Y2hpbmcvbGlzdGVuaW5nIHRvIHRlbGV2aXNpb24gYW5kIHZpZGVvIiwKICAgICAgICAiTGlzdGVuaW5nIHRvIHJhZGlvIGFuZCBhdWRpbyBkZXZpY2VzIiwKICAgICAgICAiT3RoZXIgYWN0aXZpdGllcyByZWxhdGVkIHRvIG1hc3MgbWVkaWEgdXNlIgogICAgICApIH4gIk1hc3MgTWVkaWEiLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygiQWN0aXZpdGllcyBhc3NvY2lhdGVkIHdpdGggcmVmbGVjdGluZywgcmVzdGluZywgcmVsYXhpbmciKSB+ICJSZXN0aW5nICYgUmVsYXhpbmciLAogICAgICBhY3Rpdml0eV9jb2RlICVpbiUgYygKICAgICAgICAiVHJhdmVsbGluZyB0aW1lIHJlbGF0ZWQgdG8gY3VsdHVyZSwgbGVpc3VyZSwgbWFzcy1tZWRpYSBhbmQgc3BvcnRzIHByYWN0aWNlcyIKICAgICAgKSB+ICJUcmF2ZWwgKExlaXN1cmUpIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIk90aGVyIGFjdGl2aXRpZXMgcmVsYXRlZCB0byBjdWx0dXJlLCBsZWlzdXJlLCBtYXNzLW1lZGlhIGFuZCBzcG9ydHMgcHJhY3RpY2VzIiwKICAgICAgICAiQ3VsdHVyZSwgbGVpc3VyZSwgbWFzcy1tZWRpYSBhbmQgc3BvcnRzIHByYWN0aWNlcyIKICAgICAgKSB+ICJPdGhlciBMZWlzdXJlIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIk5pZ2h0IHNsZWVwL2Vzc2VudGlhbCBzbGVlcCIsCiAgICAgICAgIkluY2lkZW50YWwgc2xlZXAvbmFwcyIsCiAgICAgICAgIlNsZWVwbGVzc25lc3MiLAogICAgICAgICJPdGhlciBzbGVlcCBhbmQgcmVsYXRlZCBhY3Rpdml0aWVzIgogICAgICApIH4gIlNsZWVwIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoIkVhdGluZyBtZWFscy9zbmFjayIsICJEcmlua2luZyBvdGhlciB0aGFuIHdpdGggbWVhbCBvciBzbmFjayIpIH4gIkVhdGluZyAmIERyaW5raW5nIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlBlcnNvbmFsIGh5Z2llbmUgYW5kIGNhcmUiLAogICAgICAgICJIZWFsdGgvbWVkaWNhbCBjYXJlIHRvIG9uZXNlbGYiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gcGVyc29uYWwgaHlnaWVuZSBhbmQgY2FyZSIKICAgICAgKSB+ICJQZXJzb25hbCBIeWdpZW5lICYgSGVhbHRoIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoCiAgICAgICAgIlJlY2VpdmluZyBwZXJzb25hbCBjYXJlIGZyb20gb3RoZXJzIiwKICAgICAgICAiUmVjZWl2aW5nIGhlYWx0aC9tZWRpY2FsIGNhcmUgZnJvbSBvdGhlcnMiLAogICAgICAgICJPdGhlciBhY3Rpdml0aWVzIHJlbGF0ZWQgdG8gcmVjZWl2aW5nIHBlcnNvbmFsIGFuZCBoZWFsdGgvbWVkaWNhbCBjYXJlIgogICAgICApIH4gIlJlY2VpdmluZyBDYXJlIiwKICAgICAgYWN0aXZpdHlfY29kZSAlaW4lIGMoIlRyYXZlbGxpbmcgdGltZSByZWxhdGVkIHRvIHNlbGYtY2FyZSBhbmQgbWFpbnRlbmFuY2UgYWN0aXZpdGllcyIpIH4gIlRyYXZlbCAoU2VsZi1DYXJlKSIsCiAgICAgIGFjdGl2aXR5X2NvZGUgJWluJSBjKCJPdGhlciBzZWxmLWNhcmUgYW5kIG1haW50ZW5hbmNlIGFjdGl2aXRpZXMiKSB+ICJPdGhlciBTZWxmLUNhcmUiLAogICAgICBUUlVFIH4gIlVuY2xhc3NpZmllZCIKICAgICkKICApCmBgYAoKIyMgQXZlcmFnZSBTbGVlcCBPdmVyIHRoZSBBZ2VzCgpUaGlzIGNoYXJ0IHNob3dzIGhvdyBvdXIgYXZlcmFnZSBzbGVlcCBkdXJhdGlvbiBjaGFuZ2VzIGFzIHdlIGFnZS4gTm90aWNlIHRoZSBkZWNsaW5lIGR1cmluZyBhZG9sZXNjZW5jZSwgZm9sbG93ZWQgYnkgYSBtb3JlIGdyYWR1YWwgY2hhbmdlIHRocm91Z2hvdXQgYWR1bHRob29kLgoKYGBge3Igc2xlZXAtYWdlLXBsb3QsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTV9CnNsZWVwX3ZzX2FnZV9wbG90IDwtIHRpbWV1c2VfZGYgJT4lCiAgZmlsdGVyKGFjdGl2aXR5ID09ICJTbGVlcCIsIGFnZSA8IDkwLCBhZ2UgPj0gNikgJT4lCiAgZ3JvdXBfYnkocGVyc29uX2lkLCBhZ2UsIG11bHQpICU+JQogIHN1bW1hcmlzZSh0b3RhbF9zbGVlcF9taW5zID0gc3VtKGR1cmF0aW9uX21pbnMsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGdyb3VwX2J5KGFnZSkgJT4lCiAgc3VtbWFyaXNlKGF2Z19zbGVlcF93ZWlnaHRlZF9taW5zID0gd2VpZ2h0ZWQubWVhbih0b3RhbF9zbGVlcF9taW5zLCB3ID0gbXVsdCwgbmEucm0gPSBUUlVFKSkgJT4lCiAgbXV0YXRlKGF2Z19zbGVlcF9ob3VycyA9IGF2Z19zbGVlcF93ZWlnaHRlZF9taW5zIC8gNjApICU+JQogIGdncGxvdChhZXMoeCA9IGFnZSwgeSA9IGF2Z19zbGVlcF9ob3VycykpICsKICBnZW9tX3Ntb290aCgKICAgIG1ldGhvZCA9ICJsb2VzcyIsCiAgICBzZSA9IFRSVUUsCiAgICBjb2xvciA9ICJibGFjayIsCiAgICBmaWxsID0gImdyYXk4MCIsCiAgICBsaW5ld2lkdGggPSAwLjgKICApICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxMiksIGJyZWFrcyA9IHNlcSgwLCAxMiwgYnkgPSAyKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAsIDkwLCBieSA9IDIwKSwgbGltaXRzID0gYyg2LCA5NSkpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQXZlcmFnZSBkYWlseSBzbGVlcCBhY3Jvc3MgYWdlcyIsCiAgICB4ID0gIkFnZSAoeWVhcnMpIiwKICAgIHkgPSAiU2xlZXAgKGhvdXJzL2RheSkiLAogICAgY2FwdGlvbiA9ICJTb3VyY2U6IE5hdGlvbmFsIFRpbWUgVXNlIFN1cnZleSAyMDI0IgogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJhdGgiLCBzaXplID0gOSksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KAogICAgICBmYW1pbHkgPSAiYXRoIiwKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDEwLAogICAgICBtYXJnaW4gPSBtYXJnaW4oYiA9IDgpCiAgICApLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KAogICAgICBmYW1pbHkgPSAiYXRoIiwKICAgICAgc2l6ZSA9IDcsCiAgICAgIGNvbG9yID0gImdyYXk1MCIsCiAgICAgIGhqdXN0ID0gMAogICAgKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gImF0aCIsIHNpemUgPSA5KSwKICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5OTAiLCBsaW5ld2lkdGggPSAwLjMpLAogICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApCiAgKQoKc2xlZXBfdnNfYWdlX3Bsb3QKCiMgLS0tIEVzc2VudGlhbCBTbGVlcCBPbmx5IC0tLQoKbmlnaHRfc2xlZXBfdnNfYWdlX3Bsb3QgPC0gdGltZXVzZV9kZiAlPiUKICBmaWx0ZXIoYWN0aXZpdHlfY29kZSA9PSAiTmlnaHQgc2xlZXAvZXNzZW50aWFsIHNsZWVwIiwgYWdlIDwgOTAsIGFnZSA+PSA2KSAlPiUKICBncm91cF9ieShwZXJzb25faWQsIGFnZSwgbXVsdCkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX3NsZWVwX21pbnMgPSBzdW0oZHVyYXRpb25fbWlucywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgLmdyb3VwcyA9ICdkcm9wJykgJT4lCiAgZ3JvdXBfYnkoYWdlKSAlPiUKICBzdW1tYXJpc2UoYXZnX3NsZWVwX3dlaWdodGVkX21pbnMgPSB3ZWlnaHRlZC5tZWFuKHRvdGFsX3NsZWVwX21pbnMsIHcgPSBtdWx0LCBuYS5ybSA9IFRSVUUpKSAlPiUKICBtdXRhdGUoYXZnX3NsZWVwX2hvdXJzID0gYXZnX3NsZWVwX3dlaWdodGVkX21pbnMgLyA2MCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYWdlLCB5ID0gYXZnX3NsZWVwX2hvdXJzKSkgKwogIGdlb21fc21vb3RoKAogICAgbWV0aG9kID0gImxvZXNzIiwKICAgIHNlID0gVFJVRSwKICAgIGNvbG9yID0gIm5hdnkiLAogICAgZmlsbCA9ICJsaWdodGJsdWUiLAogICAgbGluZXdpZHRoID0gMC44CiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMTIpLCBicmVha3MgPSBzZXEoMCwgMTIsIGJ5ID0gMikpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwLCA5MCwgYnkgPSAyMCksIGxpbWl0cyA9IGMoNiwgOTUpKSArCiAgbGFicygKICAgIHRpdGxlID0gIk5pZ2h0IHNsZWVwIGFjcm9zcyBhZ2VzIiwKICAgIHggPSAiQWdlICh5ZWFycykiLAogICAgeSA9ICJTbGVlcCAoaG91cnMvZGF5KSIsCiAgICBjYXB0aW9uID0gIlNvdXJjZTogTmF0aW9uYWwgVGltZSBVc2UgU3VydmV5IDIwMjQiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHRleHQgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gImF0aCIsIHNpemUgPSA5KSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgIGZhbWlseSA9ICJhdGgiLAogICAgICBmYWNlID0gImJvbGQiLAogICAgICBzaXplID0gMTIsCiAgICAgIG1hcmdpbiA9IG1hcmdpbihiID0gOCkKICAgICksCiAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoCiAgICAgIGZhbWlseSA9ICJhdGgiLAogICAgICBzaXplID0gNywKICAgICAgY29sb3IgPSAiZ3JheTUwIiwKICAgICAgaGp1c3QgPSAwCiAgICApLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiYXRoIiwgc2l6ZSA9IDkpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5OTAiLCBsaW5ld2lkdGggPSAwLjMpLAogICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApCiAgKQoKbmlnaHRfc2xlZXBfdnNfYWdlX3Bsb3QKYGBgCgojIyBBIERheSBpbiB0aGUgTGlmZSBBY3Jvc3MgQWdlIEdyb3VwcwoKYGBge3IgYWdlLXN0cmlwcy1wbG90LCBmaWcuaGVpZ2h0PTQuNSwgZmlnLndpZHRoPTZ9CmhpZ2hfbGV2ZWxfc3VtbWFyeSA8LSB0aW1ldXNlX2RmICU+JQogIGZpbHRlcighaXMubmEoYWN0aXZpdHkpICYgYWN0aXZpdHkgIT0gIlVuY2xhc3NpZmllZCIpICU+JQogIG11dGF0ZSgKICAgIGFjdGl2aXR5X2dyb3VwID0gY2FzZV93aGVuKAogICAgICBhY3Rpdml0eSA9PSAiU2xlZXAiIH4gIlNsZWVwIiwKICAgICAgYWN0aXZpdHkgJWluJSBjKCJFYXRpbmcgJiBEcmlua2luZyIsICJQZXJzb25hbCBIeWdpZW5lICYgSGVhbHRoIiwgIlJlY2VpdmluZyBDYXJlIikgfiAiUGVyc29uYWwgQ2FyZSIsCiAgICAgIGFjdGl2aXR5ICVpbiUgYygKICAgICAgICAiRm9ybWFsIEVtcGxveW1lbnQiLAogICAgICAgICJIb3VzZWhvbGQgRW50ZXJwcmlzZSAoR29vZHMpIiwKICAgICAgICAiSG91c2Vob2xkIEVudGVycHJpc2UgKFNlcnZpY2VzKSIsCiAgICAgICAgIldvcmstUmVsYXRlZCBUcmFpbmluZyIsCiAgICAgICAgIlNlZWtpbmcgRW1wbG95bWVudCIsCiAgICAgICAgIlNldHRpbmcgdXAgYSBCdXNpbmVzcyIKICAgICAgKSB+ICJQYWlkIFdvcmsiLAogICAgICBhY3Rpdml0eSAlaW4lIGMoCiAgICAgICAgIkZvb2QgJiBNZWFsIE1hbmFnZW1lbnQiLAogICAgICAgICJDbGVhbmluZyAmIE1haW50ZW5hbmNlIiwKICAgICAgICAiQ2hpbGRjYXJlICYgSW5zdHJ1Y3Rpb24iLAogICAgICAgICJTaG9wcGluZyIsCiAgICAgICAgIkFncmljdWx0dXJlICYgRmlzaGluZyAoT3duLVVzZSkiLAogICAgICAgICJDb21tdW5pdHkgVm9sdW50ZWVyaW5nIiwKICAgICAgICAiRGlyZWN0IFZvbHVudGVlcmluZyIKICAgICAgKSB+ICJVbnBhaWQgV29yayAmIENhcmUiLAogICAgICBhY3Rpdml0eSAlaW4lIGMoIkZvcm1hbCBFZHVjYXRpb24iLCAiSG9tZXdvcmsiLCAiQWRkaXRpb25hbCBTdHVkeSIpIH4gIkxlYXJuaW5nIiwKICAgICAgVFJVRSB+ICJMZWlzdXJlLCBTb2NpYWwgJiBUcmF2ZWwiCiAgICApCiAgKQoKcGVyc29uX2FjdGl2aXR5X2dyb3VwX3N1bW1hcnkgPC0gaGlnaF9sZXZlbF9zdW1tYXJ5ICU+JQogIGdyb3VwX2J5KHBlcnNvbl9pZCwgYWN0aXZpdHlfZ3JvdXApICU+JQogIHN1bW1hcmlzZSh0b3RhbF9kdXJhdGlvbiA9IHN1bShkdXJhdGlvbl9taW5zLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAuZ3JvdXBzID0gImRyb3AiKQoKc3RhY2tpbmdfb3JkZXIgPC0gYygKICAiU2xlZXAiLAogICJQZXJzb25hbCBDYXJlIiwKICAiUGFpZCBXb3JrIiwKICAiVW5wYWlkIFdvcmsgJiBDYXJlIiwKICAiTGVhcm5pbmciLAogICJMZWlzdXJlLCBTb2NpYWwgJiBUcmF2ZWwiCikKCiMgU3VtbWFyeSBmb3IgVG90YWwgUG9wdWxhdGlvbgphbGxfcGVyc29uc19hZ2VfZ3JvdXAgPC0gaGlnaF9sZXZlbF9zdW1tYXJ5ICU+JQogIG11dGF0ZShhZ2VfZ3JvdXAgPSBjdXQoCiAgICBhZ2UsCiAgICBicmVha3MgPSBjKDUsIDE0LCAyNCwgNTksIEluZiksCiAgICBsYWJlbHMgPSBjKAogICAgICAiQ2hpbGRyZW5cbig2LTE0KSIsCiAgICAgICJZb3V0aFxuKDE1LTI0KSIsCiAgICAgICJBZHVsdHNcbigyNS01OSkiLAogICAgICAiRWxkZXJseVxuKDYwKykiCiAgICApLAogICAgcmlnaHQgPSBUUlVFLAogICAgaW5jbHVkZS5sb3dlc3QgPSBUUlVFCiAgKSkgJT4lCiAgZmlsdGVyKCFpcy5uYShhZ2VfZ3JvdXApKSAlPiUKICBkaXN0aW5jdChwZXJzb25faWQsIGFnZV9ncm91cCwgbXVsdCkKCmFnZV9ncm91cF9zdW1tYXJ5X3RvdGFsIDwtIGFsbF9wZXJzb25zX2FnZV9ncm91cCAlPiUKICB0aWR5cjo6Y3Jvc3NpbmcoYWN0aXZpdHlfZ3JvdXAgPSB1bmlxdWUocGVyc29uX2FjdGl2aXR5X2dyb3VwX3N1bW1hcnkkYWN0aXZpdHlfZ3JvdXApKSAlPiUKICBsZWZ0X2pvaW4ocGVyc29uX2FjdGl2aXR5X2dyb3VwX3N1bW1hcnksCiAgICAgICAgICAgIGJ5ID0gYygicGVyc29uX2lkIiwgImFjdGl2aXR5X2dyb3VwIikpICU+JQogIG11dGF0ZSh0b3RhbF9kdXJhdGlvbiA9IGlmZWxzZShpcy5uYSh0b3RhbF9kdXJhdGlvbiksIDAsIHRvdGFsX2R1cmF0aW9uKSkgJT4lCiAgZ3JvdXBfYnkoYWdlX2dyb3VwLCBhY3Rpdml0eV9ncm91cCkgJT4lCiAgc3VtbWFyaXNlKGF2Z19ob3VycyA9IHdlaWdodGVkLm1lYW4odG90YWxfZHVyYXRpb24sIHcgPSBtdWx0LCBuYS5ybSA9IFRSVUUpIC8gNjAsCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIG11dGF0ZShhY3Rpdml0eV9ncm91cCA9IGZhY3RvcihhY3Rpdml0eV9ncm91cCwgbGV2ZWxzID0gc3RhY2tpbmdfb3JkZXIpKQoKIyBTdW1tYXJ5IGJ5IEdlbmRlcgphbGxfcGVyc29uc19hZ2VfZ2VuZGVyX2dyb3VwIDwtIGhpZ2hfbGV2ZWxfc3VtbWFyeSAlPiUKICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygibWFsZSIsICJmZW1hbGUiKSkgJT4lCiAgbXV0YXRlKGFnZV9ncm91cCA9IGN1dCgKICAgIGFnZSwKICAgIGJyZWFrcyA9IGMoNSwgMTQsIDI0LCA1OSwgSW5mKSwKICAgIGxhYmVscyA9IGMoCiAgICAgICJDaGlsZHJlblxuKDYtMTQpIiwKICAgICAgIllvdXRoXG4oMTUtMjQpIiwKICAgICAgIkFkdWx0c1xuKDI1LTU5KSIsCiAgICAgICJFbGRlcmx5XG4oNjArKSIKICAgICksCiAgICByaWdodCA9IFRSVUUsCiAgICBpbmNsdWRlLmxvd2VzdCA9IFRSVUUKICApKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGFnZV9ncm91cCkpICU+JQogIGRpc3RpbmN0KHBlcnNvbl9pZCwgYWdlX2dyb3VwLCBnZW5kZXIsIG11bHQpCgphZ2VfZ2VuZGVyX2dyb3VwX3N1bW1hcnkgPC0gYWxsX3BlcnNvbnNfYWdlX2dlbmRlcl9ncm91cCAlPiUKICB0aWR5cjo6Y3Jvc3NpbmcoYWN0aXZpdHlfZ3JvdXAgPSB1bmlxdWUocGVyc29uX2FjdGl2aXR5X2dyb3VwX3N1bW1hcnkkYWN0aXZpdHlfZ3JvdXApKSAlPiUKICBsZWZ0X2pvaW4ocGVyc29uX2FjdGl2aXR5X2dyb3VwX3N1bW1hcnksCiAgICAgICAgICAgIGJ5ID0gYygicGVyc29uX2lkIiwgImFjdGl2aXR5X2dyb3VwIikpICU+JQogIG11dGF0ZSh0b3RhbF9kdXJhdGlvbiA9IGlmZWxzZShpcy5uYSh0b3RhbF9kdXJhdGlvbiksIDAsIHRvdGFsX2R1cmF0aW9uKSkgJT4lCiAgZ3JvdXBfYnkoYWdlX2dyb3VwLCBnZW5kZXIsIGFjdGl2aXR5X2dyb3VwKSAlPiUKICBzdW1tYXJpc2UoYXZnX2hvdXJzID0gd2VpZ2h0ZWQubWVhbih0b3RhbF9kdXJhdGlvbiwgdyA9IG11bHQsIG5hLnJtID0gVFJVRSkgLyA2MCwKICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgbXV0YXRlKGFjdGl2aXR5X2dyb3VwID0gZmFjdG9yKGFjdGl2aXR5X2dyb3VwLCBsZXZlbHMgPSBzdGFja2luZ19vcmRlcikpCgojIFN1bW1hcnkgYnkgU2VjdG9yCmFsbF9wZXJzb25zX2FnZV9zZWN0b3JfZ3JvdXAgPC0gaGlnaF9sZXZlbF9zdW1tYXJ5ICU+JQogIG11dGF0ZShhZ2VfZ3JvdXAgPSBjdXQoCiAgICBhZ2UsCiAgICBicmVha3MgPSBjKDUsIDE0LCAyNCwgNTksIEluZiksCiAgICBsYWJlbHMgPSBjKAogICAgICAiQ2hpbGRyZW5cbig2LTE0KSIsCiAgICAgICJZb3V0aFxuKDE1LTI0KSIsCiAgICAgICJBZHVsdHNcbigyNS01OSkiLAogICAgICAiRWxkZXJseVxuKDYwKykiCiAgICApLAogICAgcmlnaHQgPSBUUlVFLAogICAgaW5jbHVkZS5sb3dlc3QgPSBUUlVFCiAgKSkgJT4lCiAgZmlsdGVyKCFpcy5uYShhZ2VfZ3JvdXApKSAlPiUKICBkaXN0aW5jdChwZXJzb25faWQsIGFnZV9ncm91cCwgc2VjdG9yLCBtdWx0KQoKYWdlX3NlY3Rvcl9ncm91cF9zdW1tYXJ5IDwtIGFsbF9wZXJzb25zX2FnZV9zZWN0b3JfZ3JvdXAgJT4lCiAgdGlkeXI6OmNyb3NzaW5nKGFjdGl2aXR5X2dyb3VwID0gdW5pcXVlKHBlcnNvbl9hY3Rpdml0eV9ncm91cF9zdW1tYXJ5JGFjdGl2aXR5X2dyb3VwKSkgJT4lCiAgbGVmdF9qb2luKHBlcnNvbl9hY3Rpdml0eV9ncm91cF9zdW1tYXJ5LAogICAgICAgICAgICBieSA9IGMoInBlcnNvbl9pZCIsICJhY3Rpdml0eV9ncm91cCIpKSAlPiUKICBtdXRhdGUodG90YWxfZHVyYXRpb24gPSBpZmVsc2UoaXMubmEodG90YWxfZHVyYXRpb24pLCAwLCB0b3RhbF9kdXJhdGlvbikpICU+JQogIGdyb3VwX2J5KGFnZV9ncm91cCwgc2VjdG9yLCBhY3Rpdml0eV9ncm91cCkgJT4lCiAgc3VtbWFyaXNlKGF2Z19ob3VycyA9IHdlaWdodGVkLm1lYW4odG90YWxfZHVyYXRpb24sIHcgPSBtdWx0LCBuYS5ybSA9IFRSVUUpIC8gNjAsCiAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIG11dGF0ZShhY3Rpdml0eV9ncm91cCA9IGZhY3RvcihhY3Rpdml0eV9ncm91cCwgbGV2ZWxzID0gc3RhY2tpbmdfb3JkZXIpKQoKCgojIDEuIERlZmluZSBjb25zaXN0ZW50IGNvbG9ycyBhbmQgYSByZXVzYWJsZSBwbG90dGluZyBmdW5jdGlvbgphY3Rpdml0eV9jb2xvcnMgPC0gYygKICAiU2xlZXAiID0gIiMxQjlFNzciLAogICJQZXJzb25hbCBDYXJlIiA9ICIjRDk1RjAyIiwKICAiUGFpZCBXb3JrIiA9ICIjNzU3MEIzIiwKICAiVW5wYWlkIFdvcmsgJiBDYXJlIiA9ICIjRTcyOThBIiwKICAiTGVhcm5pbmciID0gIiM2NjY2NjYiLAogICJMZWlzdXJlLCBTb2NpYWwgJiBUcmF2ZWwiID0gIiNFNkFCMDIiCikKCmNyZWF0ZV9hZ2Vfc3RyaXBzX3Bsb3QgPC0gZnVuY3Rpb24oZGF0YSwgeF92YXIgPSAiYWdlX2dyb3VwIiwgbWFpbl90aXRsZSkgewogIGdncGxvdChkYXRhLCBhZXMoeCA9IC5kYXRhW1t4X3Zhcl1dLCB5ID0gYXZnX2hvdXJzLCBmaWxsID0gYWN0aXZpdHlfZ3JvdXApKSArCiAgICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIiwgY29sb3VyID0gIndoaXRlIiwgbGluZXdpZHRoID0gMC4yKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBhY3Rpdml0eV9jb2xvcnMsIG5hbWUgPSAiIikgKwogICAgbGFicygKICAgICAgdGl0bGUgPSBtYWluX3RpdGxlLAogICAgICB4ID0gTlVMTCwKICAgICAgeSA9ICIlIG9mIGRheSIsCiAgICAgIGNhcHRpb24gPSAiU291cmNlOiBOYXRpb25hbCBUaW1lIFVzZSBTdXJ2ZXkgMjAyNCIKICAgICkgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIHRoZW1lKAogICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJhdGgiLCBzaXplID0gOCksCiAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoCiAgICAgICAgZmFtaWx5ID0gImF0aCIsCiAgICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgICBzaXplID0gMTIsCiAgICAgICAgbWFyZ2luID0gbWFyZ2luKGIgPSA4KQogICAgICApLAogICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoCiAgICAgICAgZmFtaWx5ID0gImF0aCIsCiAgICAgICAgc2l6ZSA9IDcsCiAgICAgICAgY29sb3IgPSAiZ3JheTUwIiwKICAgICAgICBoanVzdCA9IDAKICAgICAgKSwKICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA5KSwKICAgICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjMsICJjbSIpLAogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChsaW5laGVpZ2h0ID0gMC40KSwKICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApCiAgICApICsKICAgIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAyLCBieXJvdyA9IFRSVUUpKQp9CgojIDIuIEdlbmVyYXRlIHRoZSBpbmRpdmlkdWFsIHBsb3RzIHVzaW5nIHRoZSBmdW5jdGlvbgphZ2Vfc3RyaXBzX3Bsb3RfdG90YWwgPC0gY3JlYXRlX2FnZV9zdHJpcHNfcGxvdCgKICBkYXRhID0gYWdlX2dyb3VwX3N1bW1hcnlfdG90YWwsIAogIG1haW5fdGl0bGUgPSAiVGltZSB1c2UgYnkgYWdlIGdyb3VwIgopCgphZ2Vfc3RyaXBzX3Bsb3RfbWFsZSA8LSBjcmVhdGVfYWdlX3N0cmlwc19wbG90KAogIGRhdGEgPSBhZ2VfZ2VuZGVyX2dyb3VwX3N1bW1hcnkgJT4lIGZpbHRlcihnZW5kZXIgPT0gIm1hbGUiKSwKICBtYWluX3RpdGxlID0gIlRpbWUgdXNlIGJ5IGFnZTogTWVuIgopCgphZ2Vfc3RyaXBzX3Bsb3RfZmVtYWxlIDwtIGNyZWF0ZV9hZ2Vfc3RyaXBzX3Bsb3QoCiAgZGF0YSA9IGFnZV9nZW5kZXJfZ3JvdXBfc3VtbWFyeSAlPiUgZmlsdGVyKGdlbmRlciA9PSAiZmVtYWxlIiksCiAgbWFpbl90aXRsZSA9ICJUaW1lIHVzZSBieSBhZ2U6IFdvbWVuIgopCgphZ2Vfc3RyaXBzX3Bsb3RfcnVyYWwgPC0gY3JlYXRlX2FnZV9zdHJpcHNfcGxvdCgKICBkYXRhID0gYWdlX3NlY3Rvcl9ncm91cF9zdW1tYXJ5ICU+JSBmaWx0ZXIoc2VjdG9yID09ICJSdXJhbCIpLAogIG1haW5fdGl0bGUgPSAiVGltZSB1c2UgYnkgYWdlOiBSdXJhbCIKKQoKYWdlX3N0cmlwc19wbG90X3VyYmFuIDwtIGNyZWF0ZV9hZ2Vfc3RyaXBzX3Bsb3QoCiAgZGF0YSA9IGFnZV9zZWN0b3JfZ3JvdXBfc3VtbWFyeSAlPiUgZmlsdGVyKHNlY3RvciA9PSAiVXJiYW4iKSwKICBtYWluX3RpdGxlID0gIlRpbWUgdXNlIGJ5IGFnZTogVXJiYW4iCikKCgojIDMuIEdlbmVyYXRlIHRoZSBjb21iaW5lZCBwbG90IChpdCdzIGRpZmZlcmVudCBkdWUgdG8gZmFjZXRpbmcpCmNvbWJpbmVkX2dlbmRlcl9zdHJpcHNfcGxvdCA8LSBhZ2VfZ2VuZGVyX2dyb3VwX3N1bW1hcnkgJT4lCiAgbXV0YXRlKGdlbmRlciA9IHN0cl90b190aXRsZShnZW5kZXIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBnZW5kZXIsIHkgPSBhdmdfaG91cnMsIGZpbGwgPSBhY3Rpdml0eV9ncm91cCkpICsKICBnZW9tX2NvbCgKICAgIHBvc2l0aW9uID0gImZpbGwiLAogICAgd2lkdGggPSAwLjgsCiAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICBsaW5ld2lkdGggPSAwLjIKICApICsKICBmYWNldF93cmFwKCB+IGFnZV9ncm91cCwgbnJvdyA9IDEpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYWN0aXZpdHlfY29sb3JzLCBuYW1lID0gIiIpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVGltZSB1c2UgYnkgZ2VuZGVyIGFuZCBhZ2UiLAogICAgeCA9IE5VTEwsCiAgICB5ID0gIiUgb2YgZGF5IiwKICAgIGNhcHRpb24gPSAiU291cmNlOiBOYXRpb25hbCBUaW1lIFVzZSBTdXJ2ZXkgMjAyNCIKICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiYXRoIiwgc2l6ZSA9IDgpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFtaWx5ID0gImF0aCIsCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMCwKICAgICAgbWFyZ2luID0gbWFyZ2luKGIgPSA4KQogICAgKSwKICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFtaWx5ID0gImF0aCIsCiAgICAgIHNpemUgPSA3LAogICAgICBjb2xvciA9ICJncmF5NTAiLAogICAgICBoanVzdCA9IDAKICAgICksCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA3KSwKICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4zLCAiY20iKSwKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDgsIGxpbmVoZWlnaHQgPSAwLjQpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA3KSwKICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgwLjMsICJsaW5lcyIpLAogICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApCiAgKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobnJvdyA9IDIsIGJ5cm93ID0gVFJVRSkpCgphZ2Vfc3RyaXBzX3Bsb3RfcnVyYWwKYWdlX3N0cmlwc19wbG90X3VyYmFuCmFnZV9zdHJpcHNfcGxvdF90b3RhbAphZ2Vfc3RyaXBzX3Bsb3RfbWFsZQphZ2Vfc3RyaXBzX3Bsb3RfZmVtYWxlCmNvbWJpbmVkX2dlbmRlcl9zdHJpcHNfcGxvdApgYGAKCiMjIyBSdXJhbCB2cy4gVXJiYW4gQ29tcGFyaXNvbgoKYGBge3IgcnVyYWwtdXJiYW4tZ2VuZGVyLXN0cmlwcy1wbG90LCBmaWcuaGVpZ2h0PTQuNSwgZmlnLndpZHRoPTd9CmFsbF9wZXJzb25zX2FnZV9nZW5kZXJfc2VjdG9yX2dyb3VwIDwtIGhpZ2hfbGV2ZWxfc3VtbWFyeSAlPiUKICBmaWx0ZXIoZ2VuZGVyICVpbiUgYygibWFsZSIsICJmZW1hbGUiKSkgJT4lCiAgbXV0YXRlKGFnZV9ncm91cCA9IGN1dCgKICAgIGFnZSwKICAgIGJyZWFrcyA9IGMoNSwgMTQsIDI0LCA1OSwgSW5mKSwKICAgIGxhYmVscyA9IGMoCiAgICAgICJDaGlsZHJlblxuKDYtMTQpIiwKICAgICAgIllvdXRoXG4oMTUtMjQpIiwKICAgICAgIkFkdWx0c1xuKDI1LTU5KSIsCiAgICAgICJFbGRlcmx5XG4oNjArKSIKICAgICksCiAgICByaWdodCA9IFRSVUUsCiAgICBpbmNsdWRlLmxvd2VzdCA9IFRSVUUKICApKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGFnZV9ncm91cCkpICU+JQogIGRpc3RpbmN0KHBlcnNvbl9pZCwgYWdlX2dyb3VwLCBnZW5kZXIsIHNlY3RvciwgbXVsdCkKCmFnZV9nZW5kZXJfc2VjdG9yX2dyb3VwX3N1bW1hcnkgPC0gYWxsX3BlcnNvbnNfYWdlX2dlbmRlcl9zZWN0b3JfZ3JvdXAgJT4lCiAgdGlkeXI6OmNyb3NzaW5nKGFjdGl2aXR5X2dyb3VwID0gdW5pcXVlKHBlcnNvbl9hY3Rpdml0eV9ncm91cF9zdW1tYXJ5JGFjdGl2aXR5X2dyb3VwKSkgJT4lCiAgbGVmdF9qb2luKHBlcnNvbl9hY3Rpdml0eV9ncm91cF9zdW1tYXJ5LAogICAgICAgICAgICBieSA9IGMoInBlcnNvbl9pZCIsICJhY3Rpdml0eV9ncm91cCIpKSAlPiUKICBtdXRhdGUodG90YWxfZHVyYXRpb24gPSBpZmVsc2UoaXMubmEodG90YWxfZHVyYXRpb24pLCAwLCB0b3RhbF9kdXJhdGlvbikpICU+JQogIGdyb3VwX2J5KGFnZV9ncm91cCwgZ2VuZGVyLCBzZWN0b3IsIGFjdGl2aXR5X2dyb3VwKSAlPiUKICBzdW1tYXJpc2UoYXZnX2hvdXJzID0gd2VpZ2h0ZWQubWVhbih0b3RhbF9kdXJhdGlvbiwgdyA9IG11bHQsIG5hLnJtID0gVFJVRSkgLyA2MCwKICAgICAgICAgICAgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgbXV0YXRlKGFjdGl2aXR5X2dyb3VwID0gZmFjdG9yKGFjdGl2aXR5X2dyb3VwLCBsZXZlbHMgPSBzdGFja2luZ19vcmRlcikpCgoKbWFsZV9zZWN0b3Jfc3RyaXBzX3Bsb3QgPC0gYWdlX2dlbmRlcl9zZWN0b3JfZ3JvdXBfc3VtbWFyeSAlPiUKICBmaWx0ZXIoZ2VuZGVyID09ICJtYWxlIikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjdG9yLCB5ID0gYXZnX2hvdXJzLCBmaWxsID0gYWN0aXZpdHlfZ3JvdXApKSArCiAgZ2VvbV9jb2woCiAgICBwb3NpdGlvbiA9ICJmaWxsIiwKICAgIHdpZHRoID0gMC44LAogICAgY29sb3IgPSAid2hpdGUiLAogICAgbGluZXdpZHRoID0gMC4yCiAgKSArCiAgZmFjZXRfd3JhcCggfiBhZ2VfZ3JvdXAsIG5yb3cgPSAxKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGFjdGl2aXR5X2NvbG9ycywgbmFtZSA9ICIiKSArCiAgbGFicygKICAgIHRpdGxlID0gIk1lbjogVGltZSB1c2UgYnkgbG9jYXRpb24gYW5kIGFnZSIsCiAgICB4ID0gTlVMTCwKICAgIHkgPSAiJSBvZiBkYXkiLAogICAgY2FwdGlvbiA9ICJTb3VyY2U6IE5hdGlvbmFsIFRpbWUgVXNlIFN1cnZleSAyMDI0IgogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoCiAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KGZhbWlseSA9ICJhdGgiLCBzaXplID0gOCksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KAogICAgICBmYW1pbHkgPSAiYXRoIiwKICAgICAgZmFjZSA9ICJib2xkIiwKICAgICAgc2l6ZSA9IDEwLAogICAgICBtYXJnaW4gPSBtYXJnaW4oYiA9IDgpCiAgICApLAogICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KAogICAgICBmYW1pbHkgPSAiYXRoIiwKICAgICAgc2l6ZSA9IDcsCiAgICAgIGNvbG9yID0gImdyYXk1MCIsCiAgICAgIGhqdXN0ID0gMAogICAgKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcpLAogICAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjMsICJjbSIpLAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gOCwgbGluZWhlaWdodCA9IDAuNCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcpLAogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLnNwYWNpbmcgPSB1bml0KDAuMywgImxpbmVzIiksCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigxMCwgMTAsIDEwLCAxMCkKICApICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMiwgYnlyb3cgPSBUUlVFKSkKCmZlbWFsZV9zZWN0b3Jfc3RyaXBzX3Bsb3QgPC0gYWdlX2dlbmRlcl9zZWN0b3JfZ3JvdXBfc3VtbWFyeSAlPiUKICBmaWx0ZXIoZ2VuZGVyID09ICJmZW1hbGUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWN0b3IsIHkgPSBhdmdfaG91cnMsIGZpbGwgPSBhY3Rpdml0eV9ncm91cCkpICsKICBnZW9tX2NvbCgKICAgIHBvc2l0aW9uID0gImZpbGwiLAogICAgd2lkdGggPSAwLjgsCiAgICBjb2xvciA9ICJ3aGl0ZSIsCiAgICBsaW5ld2lkdGggPSAwLjIKICApICsKICBmYWNldF93cmFwKCB+IGFnZV9ncm91cCwgbnJvdyA9IDEpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYWN0aXZpdHlfY29sb3JzLCBuYW1lID0gIiIpICsKICBsYWJzKAogICAgdGl0bGUgPSAiV29tZW46IFRpbWUgdXNlIGJ5IGxvY2F0aW9uIGFuZCBhZ2UiLAogICAgeCA9IE5VTEwsCiAgICB5ID0gIiUgb2YgZGF5IiwKICAgIGNhcHRpb24gPSAiU291cmNlOiBOYXRpb25hbCBUaW1lIFVzZSBTdXJ2ZXkgMjAyNCIKICApICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAiYXRoIiwgc2l6ZSA9IDgpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFtaWx5ID0gImF0aCIsCiAgICAgIGZhY2UgPSAiYm9sZCIsCiAgICAgIHNpemUgPSAxMCwKICAgICAgbWFyZ2luID0gbWFyZ2luKGIgPSA4KQogICAgKSwKICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dCgKICAgICAgZmFtaWx5ID0gImF0aCIsCiAgICAgIHNpemUgPSA3LAogICAgICBjb2xvciA9ICJncmF5NTAiLAogICAgICBoanVzdCA9IDAKICAgICksCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA3KSwKICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC4zLCAiY20iKSwKICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDgsIGxpbmVoZWlnaHQgPSAwLjQpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA3KSwKICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5zcGFjaW5nID0gdW5pdCgwLjMsICJsaW5lcyIpLAogICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMTAsIDEwLCAxMCwgMTApCiAgKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQobnJvdyA9IDIsIGJ5cm93ID0gVFJVRSkpCgptYWxlX3NlY3Rvcl9zdHJpcHNfcGxvdApmZW1hbGVfc2VjdG9yX3N0cmlwc19wbG90CmBgYAoKIyMgRXhwb3J0cyBhbmQgRG93bmxvYWQKCmBgYHtyIHNhdmUtYWxsLXBsb3RzLCBpbmNsdWRlPVRSVUV9CmRpci5jcmVhdGUoInNob3J0bGlzdGVkX3RleHRib29rIiwgc2hvd1dhcm5pbmdzID0gRkFMU0UpCgpleHBvcnRfdGhlbWUgPC0gdGhlbWUoCiAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGZhY2UgPSAiYm9sZCIpLAogIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwKICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExKSwKICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksCiAgbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjQsICJjbSIpCikKCiMgMS4gU2xlZXAgcGxvdHMgLSBjb21wYWN0IHNpbmdsZS1jb2x1bW4gd2lkdGggKDQiIHggMy41IikKZ2dzYXZlKGZpbGVuYW1lID0gInNob3J0bGlzdGVkX3RleHRib29rLzAxX3NsZWVwX3ZzX2FnZS5wbmciLAogICAgICAgcGxvdCA9IHNsZWVwX3ZzX2FnZV9wbG90ICsgZXhwb3J0X3RoZW1lLAogICAgICAgd2lkdGggPSAyLCBoZWlnaHQgPSAyLCBkcGkgPSAzMDAsIHVuaXRzID0gImluIikKCmdnc2F2ZShmaWxlbmFtZSA9ICJzaG9ydGxpc3RlZF90ZXh0Ym9vay8wMl9lc3NlbnRpYWxfc2xlZXBfdnNfYWdlLnBuZyIsCiAgICAgICBwbG90ID0gbmlnaHRfc2xlZXBfdnNfYWdlX3Bsb3QgKyBleHBvcnRfdGhlbWUsCiAgICAgICB3aWR0aCA9IDIsIGhlaWdodCA9IDIsIGRwaSA9IDMwMCwgdW5pdHMgPSAiaW4iKQoKIyAyLiBTaW1wbGUgc3RyaXAgcGxvdHMgLSBzbGlnaHRseSB3aWRlciAoNSIgeCA0IikKZ2dzYXZlKGZpbGVuYW1lID0gInNob3J0bGlzdGVkX3RleHRib29rLzAzX2FnZV9zdHJpcHNfdG90YWwucG5nIiwKICAgICAgIHBsb3QgPSBhZ2Vfc3RyaXBzX3Bsb3RfdG90YWwgKyBleHBvcnRfdGhlbWUsCiAgICAgICB3aWR0aCA9IDMsIGhlaWdodCA9IDMsIGRwaSA9IDMwMCwgdW5pdHMgPSAiaW4iKQoKZ2dzYXZlKGZpbGVuYW1lID0gInNob3J0bGlzdGVkX3RleHRib29rLzA0X2FnZV9zdHJpcHNfcnVyYWwucG5nIiwKICAgICAgIHBsb3QgPSBhZ2Vfc3RyaXBzX3Bsb3RfcnVyYWwgKyBleHBvcnRfdGhlbWUsCiAgICAgICB3aWR0aCA9IDMsIGhlaWdodCA9IDMsIGRwaSA9IDMwMCwgdW5pdHMgPSAiaW4iKQoKZ2dzYXZlKGZpbGVuYW1lID0gInNob3J0bGlzdGVkX3RleHRib29rLzA1X2FnZV9zdHJpcHNfdXJiYW4ucG5nIiwKICAgICAgIHBsb3QgPSBhZ2Vfc3RyaXBzX3Bsb3RfdXJiYW4gKyBleHBvcnRfdGhlbWUsCiAgICAgICB3aWR0aCA9IDMsIGhlaWdodCA9IDMsIGRwaSA9IDMwMCwgdW5pdHMgPSAiaW4iKQoKIyAzLiBHZW5kZXItc3BlY2lmaWMgcGxvdHMgKDUiIHggNCIpCmdnc2F2ZShmaWxlbmFtZSA9ICJzaG9ydGxpc3RlZF90ZXh0Ym9vay8wNl9hZ2Vfc3RyaXBzX21hbGUucG5nIiwKICAgICAgIHBsb3QgPSBhZ2Vfc3RyaXBzX3Bsb3RfbWFsZSArIGV4cG9ydF90aGVtZSwKICAgICAgIHdpZHRoID0gMywgaGVpZ2h0ID0gMywgZHBpID0gMzAwLCB1bml0cyA9ICJpbiIpCgpnZ3NhdmUoZmlsZW5hbWUgPSAic2hvcnRsaXN0ZWRfdGV4dGJvb2svMDdfYWdlX3N0cmlwc19mZW1hbGUucG5nIiwKICAgICAgIHBsb3QgPSBhZ2Vfc3RyaXBzX3Bsb3RfZmVtYWxlICsgZXhwb3J0X3RoZW1lLAogICAgICAgd2lkdGggPSAzLCBoZWlnaHQgPSAzLCBkcGkgPSAzMDAsIHVuaXRzID0gImluIikKCiMgNC4gRmFjZXRlZCBwbG90cyAtIHdpZGVyIGZvciByZWFkYWJpbGl0eSAoNi41IiB4IDQiKQpnZ3NhdmUoZmlsZW5hbWUgPSAic2hvcnRsaXN0ZWRfdGV4dGJvb2svMDhfY29tYmluZWRfZ2VuZGVyX3N0cmlwcy5wbmciLAogICAgICAgcGxvdCA9IGNvbWJpbmVkX2dlbmRlcl9zdHJpcHNfcGxvdCArIGV4cG9ydF90aGVtZSwKICAgICAgIHdpZHRoID0gNCwgaGVpZ2h0ID0gMywgZHBpID0gMzAwLCB1bml0cyA9ICJpbiIpCgpnZ3NhdmUoZmlsZW5hbWUgPSAic2hvcnRsaXN0ZWRfdGV4dGJvb2svMDlfbWFsZV9zZWN0b3Jfc3RyaXBzLnBuZyIsCiAgICAgICBwbG90ID0gbWFsZV9zZWN0b3Jfc3RyaXBzX3Bsb3QgKyBleHBvcnRfdGhlbWUsCiAgICAgICB3aWR0aCA9IDQsIGhlaWdodCA9IDMsIGRwaSA9IDMwMCwgdW5pdHMgPSAiaW4iKQoKZ2dzYXZlKGZpbGVuYW1lID0gInNob3J0bGlzdGVkX3RleHRib29rLzEwX2ZlbWFsZV9zZWN0b3Jfc3RyaXBzLnBuZyIsCiAgICAgICBwbG90ID0gZmVtYWxlX3NlY3Rvcl9zdHJpcHNfcGxvdCArIGV4cG9ydF90aGVtZSwKICAgICAgIHdpZHRoID0gNCwgaGVpZ2h0ID0gMywgZHBpID0gMzAwLCB1bml0cyA9ICJpbiIpCmBgYAoKYGBge3IgY3JlYXRlLXppcC1hbmQtZG93bmxvYWQsIGluY2x1ZGU9VFJVRX0KemlwX2ZpbGUgPC0gInRpbWVfdXNlX3RleHRib29rX2J1bmRsZS56aXAiCmZpbGVzX3RvX3ppcCA8LSBjKAogIGxpc3QuZmlsZXMoInNob3J0bGlzdGVkX3RleHRib29rIiwgZnVsbC5uYW1lcyA9IFRSVUUsIHBhdHRlcm4gPSAiXFwucG5nJCIpLAogICJzaG9ydGxpc3RlZC10dXMtMjAyNC5SbWQiCikKCmlmIChmaWxlLmV4aXN0cyh6aXBfZmlsZSkpIGZpbGUucmVtb3ZlKHppcF9maWxlKQp6aXA6OnppcCh6aXBmaWxlID0gemlwX2ZpbGUsIGZpbGVzID0gZmlsZXNfdG9femlwLCBtb2RlID0gImNoZXJyeS1waWNrIikKCmRvd25sb2FkX2ZpbGUoCiAgcGF0aCA9IHppcF9maWxlLAogIG91dHB1dF9uYW1lID0gIkRvd25sb2FkIFRleHRib29rIEJ1bmRsZSAoWklQKSIsCiAgYnV0dG9uX2xhYmVsID0gIkRvd25sb2FkIEJ1bmRsZSIsCiAgYnV0dG9uX3R5cGUgPSAic3VjY2VzcyIsCiAgaGFzX2ljb24gPSBUUlVFLAogIGljb24gPSAiZmEgZmEtZG93bmxvYWQiLAogIHNlbGZfY29udGFpbmVkID0gVFJVRQopCmBgYAo=