library(tidyverse)
library(scales)
library(patchwork)
library(ggstance)
library(here)

# Wrap factor levels
# via Hadley: https://github.com/tidyverse/stringr/issues/107#issuecomment-233723948
str_wrap_factor <- function(x, ...) {
  levels(x) <- str_wrap(levels(x), ...)
  x
}

# Turn off grouping message
options(dplyr.summarise.inform = FALSE)

# Project-specific functions
source(here("R", "graphics.R"))

# General settings
source(here("analysis", "options.R"))

# Make all the randomness reproducible
set.seed(1234)
sim_excel_clean <- read_rds(here("data", "derived_data", "sim_excel_final.rds"))
sim_clean <- read_rds(here("data", "derived_data", "sim_final.rds"))

Simulations

Income across issue area, funding, and relationship

plot_income_issue <- sim_clean %>% 
  group_by(org_issue, persona_income) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Issue area") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_issue, 15)),
             x = avg_share, color = fct_rev(persona_income))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002)),
                     breaks = seq(0, 0.06, 0.02)) +
  scale_color_manual(values = c(clrs_ngo$vi_turquoise, clrs_ngo$vi_purple), guide = FALSE) +
  coord_cartesian(xlim = c(0, 0.06)) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(facet)) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_income_funding <- sim_clean %>% 
  group_by(org_funding, persona_income) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Funding sources") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_funding, 10)), 
             x = avg_share, color = fct_rev(persona_income))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.06)) +
  scale_color_manual(values = c(clrs_ngo$vi_turquoise, clrs_ngo$vi_purple), guide = FALSE) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(facet)) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_income_relationship <- sim_clean %>% 
  mutate(persona_income = fct_recode(persona_income,
                                     "< $61,372/year" = "Lower income",
                                     "> $61,372/year" = "Higher income")) %>% 
  group_by(org_relationship, persona_income) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Relationship with host government") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_relationship, 10)), 
             x = avg_share, color = fct_rev(persona_income))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5, 
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) +
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.003))) +
  coord_cartesian(xlim = c(0, 0.1)) +
  scale_color_manual(values = c(clrs_ngo$vi_turquoise, clrs_ngo$vi_purple), 
                     guide = guide_legend(reverse = TRUE, nrow = 1,
                                          override.aes = list(size = 0.25))) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(str_wrap(facet, 50))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_income_relationship_extreme <- sim_excel_clean %>% 
  mutate(persona_income = fct_recode(persona_income,
                                     "$50,000/year" = "Lower income",
                                     "$100,000/year" = "Higher income"),
         org_relationship = fct_recode(org_relationship,
                                       "Under crackdown" = "Crackdown")) %>% 
  group_by(org_relationship, persona_income) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Relationship with host government") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_relationship, 10)), 
             x = avg_share, color = fct_rev(persona_income))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.1)) +
  scale_color_manual(values = c(clrs_ngo$pl_yellow, clrs_ngo$pl_purple_light), 
                     guide = guide_legend(reverse = TRUE, nrow = 1,
                                          override.aes = list(size = 0.25))) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(str_wrap(facet, 50))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_income <- ((plot_income_issue + labs(x = NULL)) + 
  (plot_income_funding + labs(x = NULL))) / 
  (plot_income_relationship + plot_income_relationship_extreme)

plot_income

ggsave(plot_income, filename = here("analysis", "output", "figures", "income-all.pdf"),
       width = 6, height = 4.5, units = "in", device = cairo_pdf)
ggsave(plot_income, filename = here("analysis", "output", "figures", "income-all.png"),
       width = 6, height = 4.5, units = "in", type = "cairo", dpi = 300)

Education across issue area, funding, and relationship

plot_education_issue <- sim_clean %>% 
  group_by(org_issue, persona_education) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Issue area") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_issue, 15)), 
             x = avg_share, color = fct_rev(persona_education))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.06)) +
  scale_color_manual(values = c(clrs_ngo$pl_purple_dark, clrs_ngo$pl_orange), guide = FALSE) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(facet)) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_education_funding <- sim_clean %>% 
  group_by(org_funding, persona_education) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Funding sources") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_funding, 10)), 
             x = avg_share, color = fct_rev(persona_education))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.06)) +
  scale_color_manual(values = c(clrs_ngo$pl_purple_dark, clrs_ngo$pl_orange), guide = FALSE) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(facet)) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_education_relationship <- sim_clean %>% 
  group_by(org_relationship, persona_education) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Relationship with host government") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_relationship, 10)),
             x = avg_share, color = fct_rev(persona_education))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.1)) +
  scale_color_manual(values = c(clrs_ngo$pl_purple_dark, clrs_ngo$pl_orange), 
                     guide = guide_legend(reverse = TRUE, ncol = 1,
                                          override.aes = list(size = 0.25)),
                     labels = label_wrap(15)) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(str_wrap(facet, 20))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_education <- plot_education_issue + plot_education_funding + 
  plot_education_relationship + guide_area() +
  plot_layout(guides = "collect", ncol = 4)
plot_education

Religiosity across issue area, funding, and relationship

plot_religion_issue <- sim_clean %>% 
  group_by(org_issue, persona_religion) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Issue area") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_issue, 15)), 
             x = avg_share, color = fct_rev(persona_religion))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5, 
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.06)) +
  scale_color_manual(values = c(clrs_ngo$vi_blue_light, clrs_ngo$vi_yellow), guide = FALSE) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(facet)) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_religion_funding <- sim_clean %>% 
  group_by(org_funding, persona_religion) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Funding sources") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_funding, 10)), 
             x = avg_share, color = fct_rev(persona_religion))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.06)) +
  scale_color_manual(values = c(clrs_ngo$vi_blue_light, clrs_ngo$vi_yellow), guide = FALSE) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(facet)) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_religion_relationship <- sim_clean %>% 
  group_by(org_relationship, persona_religion) %>% 
  summarize(avg_share = mean(share)) %>% 
  mutate(facet = "Relationship with host government") %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_relationship, 10)), 
             x = avg_share, color = fct_rev(persona_religion))) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  coord_cartesian(xlim = c(0, 0.1)) +
  scale_color_manual(values = c(clrs_ngo$vi_blue_light, clrs_ngo$vi_yellow), 
                     guide = guide_legend(reverse = TRUE, ncol = 1,
                                          override.aes = list(size = 0.25)),
                     labels = label_wrap(20)) +
  labs(x = "Average donation share", y = NULL, color = NULL) +
  facet_wrap(vars(str_wrap(facet, 20))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_religion <- plot_religion_issue + plot_religion_funding + 
  plot_religion_relationship + guide_area() +
  plot_layout(guides = "collect", ncol = 4)
plot_religion

Education and religion across issue area, funding, and relationship

plot_education_religion <- (plot_education_issue + labs(x = NULL)) + 
  (plot_education_funding + labs(x = NULL)) + 
  (plot_education_relationship + labs(x = NULL)) + 
  guide_area() +
  plot_religion_issue + 
  plot_religion_funding + 
  plot_religion_relationship +
  plot_layout(guides = "collect", ncol = 4)

plot_education_religion

ggsave(plot_education_religion, 
       filename = here("analysis", "output", "figures", "education-religion-all.pdf"),
       width = 6.5, height = 4.5, units = "in", device = cairo_pdf)
ggsave(plot_education_religion, 
       filename = here("analysis", "output", "figures", "education-religion-all.png"),
       width = 6.5, height = 4.5, units = "in", type = "cairo", dpi = 300)

Social trust across issue area

plot_issue_social <- sim_clean %>% 
  group_by(org_issue, persona_trust, persona_ideology, persona_experience) %>% 
  summarize(avg_share = mean(share)) %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_issue, 15)), 
             x = avg_share, color = persona_trust)) +
  geom_pointrangeh(size = 0.75, fatten = 1.5, 
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  scale_color_manual(values = c(clrs_ngo$pl_blue, clrs_ngo$pl_pink), 
                     guide = guide_legend(reverse = TRUE,
                                          override.aes = list(size = 0.25))) +
  labs(x = "Average share of donations", y = NULL, color = NULL) +
  facet_grid(rows = vars(persona_ideology), cols = vars(str_wrap(persona_experience, 100))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_issue_social

ggsave(plot_issue_social, filename = here("analysis", "output", "figures", "issue-social.pdf"),
       width = 6, height = 4, units = "in", device = cairo_pdf)
ggsave(plot_issue_social, filename = here("analysis", "output", "figures", "issue-social.png"),
       width = 6, height = 4, units = "in", type = "cairo", dpi = 300)

Social trust across relationship

plot_relationship_social <- sim_clean %>% 
  group_by(org_relationship, persona_trust, persona_ideology, persona_experience) %>% 
  summarize(avg_share = mean(share)) %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_relationship, 10)), 
             x = avg_share, color = persona_trust)) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  scale_color_manual(values = c(clrs_ngo$pl_blue, clrs_ngo$pl_pink), 
                     guide = guide_legend(reverse = TRUE,
                                          override.aes = list(size = 0.25))) +
  labs(x = "Average share of donations", y = NULL, color = NULL) +
  facet_grid(rows = vars(persona_ideology), cols = vars(str_wrap(persona_experience, 100))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_relationship_social

ggsave(plot_relationship_social, filename = here("analysis", "output", "figures", "relationship-social.pdf"),
       width = 6, height = 4, units = "in", device = cairo_pdf)
ggsave(plot_relationship_social, filename = here("analysis", "output", "figures", "relationship-social.png"),
       width = 6, height = 4, units = "in", type = "cairo", dpi = 300)

Social trust across funding

plot_funding_social <- sim_clean %>% 
  group_by(org_funding, persona_trust, persona_ideology, persona_experience) %>% 
  summarize(avg_share = mean(share)) %>% 
  ggplot(aes(y = fct_rev(str_wrap_factor(org_funding, 15)), 
             x = avg_share, color = persona_trust)) +
  geom_pointrangeh(size = 0.75, fatten = 1.5,
                   aes(xmin = 0, xmax = ..x..), position = position_dodge(width = 0.5)) + 
  scale_x_continuous(labels = percent_format(accuracy = 1), expand = expansion(add = c(0, 0.002))) +
  scale_color_manual(values = c(clrs_ngo$pl_blue, clrs_ngo$pl_pink), 
                     guide = guide_legend(reverse = TRUE,
                                          override.aes = list(size = 0.25))) +
  labs(x = "Average share of donations", y = NULL, color = NULL) +
  facet_grid(rows = vars(persona_ideology), cols = vars(str_wrap(persona_experience, 100))) +
  theme_ngo() +
  theme(panel.grid.major.y = element_blank())

plot_funding_social

ggsave(plot_funding_social, filename = here("analysis", "output", "figures", "funding-social.pdf"),
       width = 6, height = 4, units = "in", device = cairo_pdf)
ggsave(plot_funding_social, filename = here("analysis", "output", "figures", "funding-social.png"),
       width = 6, height = 4, units = "in", type = "cairo", dpi = 300)


Original computing environment

devtools::session_info()
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.0.2 (2020-06-22)
##  os       macOS Catalina 10.15.6      
##  system   x86_64, darwin17.0          
##  ui       X11                         
##  language (EN)                        
##  collate  en_US.UTF-8                 
##  ctype    en_US.UTF-8                 
##  tz       America/New_York            
##  date     2020-10-01                  
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package     * version date       lib source        
##  assertthat    0.2.1   2019-03-21 [1] CRAN (R 4.0.0)
##  backports     1.1.9   2020-08-24 [1] CRAN (R 4.0.2)
##  base64enc     0.1-3   2015-07-28 [1] CRAN (R 4.0.0)
##  blob          1.2.1   2020-01-20 [1] CRAN (R 4.0.0)
##  broom         0.7.0   2020-07-09 [1] CRAN (R 4.0.2)
##  callr         3.4.3   2020-03-28 [1] CRAN (R 4.0.0)
##  cellranger    1.1.0   2016-07-27 [1] CRAN (R 4.0.0)
##  cli           2.0.2   2020-02-28 [1] CRAN (R 4.0.0)
##  colorspace    1.4-1   2019-03-18 [1] CRAN (R 4.0.0)
##  crayon        1.3.4   2017-09-16 [1] CRAN (R 4.0.0)
##  DBI           1.1.0   2019-12-15 [1] CRAN (R 4.0.0)
##  dbplyr        1.4.4   2020-05-27 [1] CRAN (R 4.0.2)
##  desc          1.2.0   2018-05-01 [1] CRAN (R 4.0.0)
##  devtools      2.3.1   2020-07-21 [1] CRAN (R 4.0.2)
##  digest        0.6.25  2020-02-23 [1] CRAN (R 4.0.0)
##  dplyr       * 1.0.2   2020-08-18 [1] CRAN (R 4.0.2)
##  ellipsis      0.3.1   2020-05-15 [1] CRAN (R 4.0.0)
##  evaluate      0.14    2019-05-28 [1] CRAN (R 4.0.0)
##  fansi         0.4.1   2020-01-08 [1] CRAN (R 4.0.0)
##  farver        2.0.3   2020-01-16 [1] CRAN (R 4.0.0)
##  forcats     * 0.5.0   2020-03-01 [1] CRAN (R 4.0.0)
##  fs            1.5.0   2020-07-31 [1] CRAN (R 4.0.2)
##  generics      0.0.2   2018-11-29 [1] CRAN (R 4.0.0)
##  ggplot2     * 3.3.2   2020-06-19 [1] CRAN (R 4.0.2)
##  ggstance    * 0.3.4   2020-04-02 [1] CRAN (R 4.0.0)
##  glue          1.4.2   2020-08-27 [1] CRAN (R 4.0.2)
##  gtable        0.3.0   2019-03-25 [1] CRAN (R 4.0.0)
##  haven         2.3.1   2020-06-01 [1] CRAN (R 4.0.2)
##  here        * 0.1     2017-05-28 [1] CRAN (R 4.0.0)
##  hms           0.5.3   2020-01-08 [1] CRAN (R 4.0.0)
##  htmltools     0.5.0   2020-06-16 [1] CRAN (R 4.0.0)
##  httr          1.4.2   2020-07-20 [1] CRAN (R 4.0.2)
##  jsonlite      1.7.0   2020-06-25 [1] CRAN (R 4.0.2)
##  knitr         1.29    2020-06-23 [1] CRAN (R 4.0.2)
##  labeling      0.3     2014-08-23 [1] CRAN (R 4.0.0)
##  lifecycle     0.2.0   2020-03-06 [1] CRAN (R 4.0.0)
##  lubridate     1.7.9   2020-06-08 [1] CRAN (R 4.0.2)
##  magrittr      1.5     2014-11-22 [1] CRAN (R 4.0.0)
##  memoise       1.1.0   2017-04-21 [1] CRAN (R 4.0.0)
##  modelr        0.1.8   2020-05-19 [1] CRAN (R 4.0.2)
##  munsell       0.5.0   2018-06-12 [1] CRAN (R 4.0.0)
##  pander        0.6.3   2018-11-06 [1] CRAN (R 4.0.0)
##  patchwork   * 1.0.1   2020-06-22 [1] CRAN (R 4.0.2)
##  pillar        1.4.6   2020-07-10 [1] CRAN (R 4.0.2)
##  pkgbuild      1.1.0   2020-07-13 [1] CRAN (R 4.0.2)
##  pkgconfig     2.0.3   2019-09-22 [1] CRAN (R 4.0.0)
##  pkgload       1.1.0   2020-05-29 [1] CRAN (R 4.0.2)
##  prettyunits   1.1.1   2020-01-24 [1] CRAN (R 4.0.0)
##  processx      3.4.3   2020-07-05 [1] CRAN (R 4.0.0)
##  ps            1.3.4   2020-08-11 [1] CRAN (R 4.0.2)
##  purrr       * 0.3.4   2020-04-17 [1] CRAN (R 4.0.0)
##  R6            2.4.1   2019-11-12 [1] CRAN (R 4.0.0)
##  Rcpp          1.0.5   2020-07-06 [1] CRAN (R 4.0.2)
##  readr       * 1.3.1   2018-12-21 [1] CRAN (R 4.0.0)
##  readxl        1.3.1   2019-03-13 [1] CRAN (R 4.0.0)
##  remotes       2.2.0   2020-07-21 [1] CRAN (R 4.0.2)
##  reprex        0.3.0   2019-05-16 [1] CRAN (R 4.0.0)
##  rlang         0.4.7   2020-07-09 [1] CRAN (R 4.0.2)
##  rmarkdown     2.3     2020-06-18 [1] CRAN (R 4.0.2)
##  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 4.0.0)
##  rstudioapi    0.11    2020-02-07 [1] CRAN (R 4.0.0)
##  rvest         0.3.6   2020-07-25 [1] CRAN (R 4.0.2)
##  scales      * 1.1.1   2020-05-11 [1] CRAN (R 4.0.0)
##  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 4.0.0)
##  stringi       1.4.6   2020-02-17 [1] CRAN (R 4.0.0)
##  stringr     * 1.4.0   2019-02-10 [1] CRAN (R 4.0.0)
##  testthat      2.3.2   2020-03-02 [1] CRAN (R 4.0.0)
##  tibble      * 3.0.3   2020-07-10 [1] CRAN (R 4.0.2)
##  tidyr       * 1.1.2   2020-08-27 [1] CRAN (R 4.0.2)
##  tidyselect    1.1.0   2020-05-11 [1] CRAN (R 4.0.0)
##  tidyverse   * 1.3.0   2019-11-21 [1] CRAN (R 4.0.0)
##  usethis       1.6.1   2020-04-29 [1] CRAN (R 4.0.0)
##  vctrs         0.3.4   2020-08-29 [1] CRAN (R 4.0.2)
##  viridisLite   0.3.0   2018-02-01 [1] CRAN (R 4.0.0)
##  withr         2.2.0   2020-04-20 [1] CRAN (R 4.0.0)
##  xfun          0.16    2020-07-24 [1] CRAN (R 4.0.2)
##  xml2          1.3.2   2020-04-23 [1] CRAN (R 4.0.0)
##  yaml          2.2.1   2020-02-01 [1] CRAN (R 4.0.0)
## 
## [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
writeLines(readLines(file.path(Sys.getenv("HOME"), ".R/Makevars")))
## # http://dirk.eddelbuettel.com/blog/2017/11/27/#011_faster_package_installation_one
## VER=
## CCACHE=ccache
## CC=$(CCACHE) gcc$(VER)
## CXX=$(CCACHE) g++$(VER)
## CXX11=$(CCACHE) g++$(VER)
## CXX14=$(CCACHE) g++$(VER)
## FC=$(CCACHE) gfortran$(VER)
## F77=$(CCACHE) gfortran$(VER)
## 
## CXX14FLAGS=-O3 -march=native -mtune=native -fPIC
LS0tCnRpdGxlOiAiQW5hbHlzaXMgYW5kIGZpZ3VyZXMiCmF1dGhvcjogIlN1cGFybmEgQ2hhdWRocnksIE1hcmMgRG90c29uLCBhbmQgQW5kcmV3IEhlaXNzIgpkYXRlOiAiTGFzdCBydW46IGByIGZvcm1hdChTeXMudGltZSgpLCAnJUYnKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgcGFuZG9jX2FyZ3M6CiAgICAgIC0gIi0tZGVmYXVsdC1pbWFnZS1leHRlbnNpb249cG5nIgplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGZpZy5yZXRpbmEgPSAzLCBmaWcuYWxpZ24gPSAiY2VudGVyIikKYGBgCgpgYGB7ciBsb2FkLXBhY2thZ2VzLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdnc3RhbmNlKQpsaWJyYXJ5KGhlcmUpCgojIFdyYXAgZmFjdG9yIGxldmVscwojIHZpYSBIYWRsZXk6IGh0dHBzOi8vZ2l0aHViLmNvbS90aWR5dmVyc2Uvc3RyaW5nci9pc3N1ZXMvMTA3I2lzc3VlY29tbWVudC0yMzM3MjM5NDgKc3RyX3dyYXBfZmFjdG9yIDwtIGZ1bmN0aW9uKHgsIC4uLikgewogIGxldmVscyh4KSA8LSBzdHJfd3JhcChsZXZlbHMoeCksIC4uLikKICB4Cn0KCiMgVHVybiBvZmYgZ3JvdXBpbmcgbWVzc2FnZQpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSkKCiMgUHJvamVjdC1zcGVjaWZpYyBmdW5jdGlvbnMKc291cmNlKGhlcmUoIlIiLCAiZ3JhcGhpY3MuUiIpKQoKIyBHZW5lcmFsIHNldHRpbmdzCnNvdXJjZShoZXJlKCJhbmFseXNpcyIsICJvcHRpb25zLlIiKSkKCiMgTWFrZSBhbGwgdGhlIHJhbmRvbW5lc3MgcmVwcm9kdWNpYmxlCnNldC5zZWVkKDEyMzQpCmBgYAoKYGBge3IgbG9hZC1kYXRhfQpzaW1fZXhjZWxfY2xlYW4gPC0gcmVhZF9yZHMoaGVyZSgiZGF0YSIsICJkZXJpdmVkX2RhdGEiLCAic2ltX2V4Y2VsX2ZpbmFsLnJkcyIpKQpzaW1fY2xlYW4gPC0gcmVhZF9yZHMoaGVyZSgiZGF0YSIsICJkZXJpdmVkX2RhdGEiLCAic2ltX2ZpbmFsLnJkcyIpKQpgYGAKCgojIEdlbmVyYWwgdHJlbmRzIGluIHByaXZhdGUgcGhpbGFudGhyb3B5CgpCYXNlZCBvbiBkYXRhIGZyb20gW0dpdmluZyBVU0FdKGh0dHBzOi8vdGhlY29udmVyc2F0aW9uLmNvbS9mZXdlci1hbWVyaWNhbnMtYXJlLWdpdmluZy1tb25leS10by1jaGFyaXR5LWJ1dC10b3RhbC1kb25hdGlvbnMtYXJlLWF0LXJlY29yZC1sZXZlbHMtYW55d2F5LTk4MjkxKSwgcGhpbGFudGhyb3B5IGluIHRoZSBVbml0ZWQgc3RhdGVzIGNvbnRpbnVlcyB0byBpbmNyZWFzZSwgYm90aCBpbiBhZ2dyZWdhdGUgYW5kIHBlciBjYXBpdGEuCgpgYGB7ciBnaXZpbmctdXNhLWRhdGEsIG1lc3NhZ2U9RkFMU0V9CmdpdmluZ19hZ2dyZWdhdGVfcmF3IDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAicmF3X2RhdGEiLCAiZGF0YS1GVGpVdi5jc3YiKSkKCmdpdmluZ19hZ2dyZWdhdGUgPC0gZ2l2aW5nX2FnZ3JlZ2F0ZV9yYXcgJT4lIAogIG11dGF0ZSh0b3RhbCA9IGBUb3RhbCBkb25hdGlvbnNgICogMTAwMDAwMDAwMCkKCmdpdmluZ19wZXJfY2FwaXRhX3JhdyA8LSByZWFkX2NzdihoZXJlKCJkYXRhIiwgInJhd19kYXRhIiwgImRhdGEteGV4dFQuY3N2IikpCgpnaXZpbmdfcGVyX2NhcGl0YSA8LSBnaXZpbmdfcGVyX2NhcGl0YV9yYXcKYGBgCgojIyBUb3RhbCBnaXZpbmcKCmBgYHtyIHBsb3QtdG90YWwtZ2l2aW5nLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD0yLjQsIG91dC53aWR0aD0iODAlIn0KZ2dwbG90KGdpdmluZ19hZ2dyZWdhdGUsIGFlcyh4ID0gWWVhciwgeSA9IGBUb3RhbCBkb25hdGlvbnNgKSkgKwogIGdlb21fbGluZShzaXplID0gMSwgY29sb3IgPSBjbHJzX25nbyR2aV9ibHVlX2RhcmspICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDE5ODAsIDIwMTUsIDUpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGRvbGxhciwgYnJlYWtzID0gc2VxKDEwMCwgNDUwLCA1MCkpICsgCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDEwMCwgNDUwKSkgKwogIGxhYnMoeCA9IE5VTEwsIHkgPSAiQmlsbGlvbnMgb2YgZG9sbGFycyIpICsgCiAgdGhlbWVfbmdvKCkKCmdnc2F2ZShoZXJlKCJhbmFseXNpcyIsICJvdXRwdXQiLCAiZmlndXJlcyIsICJnaXZpbmdfYWdncmVnYXRlLnBkZiIpLCAKICAgICAgIHdpZHRoID0gNCwgaGVpZ2h0ID0gMi40LCB1bml0cyA9ICJpbiIsIGRldmljZSA9IGNhaXJvX3BkZikKZ2dzYXZlKGhlcmUoImFuYWx5c2lzIiwgIm91dHB1dCIsICJmaWd1cmVzIiwgImdpdmluZ19hZ2dyZWdhdGUucG5nIiksIAogICAgICAgd2lkdGggPSA0LCBoZWlnaHQgPSAyLjQsIHVuaXRzID0gImluIiwgdHlwZSA9ICJjYWlybyIsIGRwaSA9IDMwMCkKYGBgCgojIyBBdmVyYWdlIHBlciBjYXBpdGEgZ2l2aW5nCgpgYGB7ciBwbG90LXBlci1jYXBpdGEtZ2l2aW5nLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD0yLjQsIG91dC53aWR0aD0iODAlIn0KZ2dwbG90KGdpdmluZ19wZXJfY2FwaXRhLCBhZXMoeCA9IFllYXIsIHkgPSBgQXZlcmFnZSBnaXZpbmdgKSkgKwogIGdlb21fbGluZShzaXplID0gMSwgY29sb3IgPSBjbHJzX25nbyR2aV9ibHVlX2RhcmspICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDIwMDAsIDIwMTQsIDIpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IGRvbGxhciwgYnJlYWtzID0gc2VxKDE3NTAsIDI3NTAsIDI1MCkpICsgCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDE3NTAsIDI3NTApKSArCiAgbGFicyh4ID0gTlVMTCwgeSA9ICJBdmVyYWdlIGFubnVhbCBkb25hdGlvbiIpICsgCiAgdGhlbWVfbmdvKCkKYGBgCgoKIyBTaW11bGF0aW9ucwoKIyMgSW5jb21lIGFjcm9zcyBpc3N1ZSBhcmVhLCBmdW5kaW5nLCBhbmQgcmVsYXRpb25zaGlwCgpgYGB7ciBpbmNvbWUtaXNzdWUtZnVuZGluZy1yZWxhdGlvbnNoaXAsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTQuNSwgb3V0LndpZHRoPSIxMDAlIn0KcGxvdF9pbmNvbWVfaXNzdWUgPC0gc2ltX2NsZWFuICU+JSAKICBncm91cF9ieShvcmdfaXNzdWUsIHBlcnNvbmFfaW5jb21lKSAlPiUgCiAgc3VtbWFyaXplKGF2Z19zaGFyZSA9IG1lYW4oc2hhcmUpKSAlPiUgCiAgbXV0YXRlKGZhY2V0ID0gIklzc3VlIGFyZWEiKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX2lzc3VlLCAxNSkpLAogICAgICAgICAgICAgeCA9IGF2Z19zaGFyZSwgY29sb3IgPSBmY3RfcmV2KHBlcnNvbmFfaW5jb21lKSkpICsKICBnZW9tX3BvaW50cmFuZ2VoKHNpemUgPSAwLjc1LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgICBhZXMoeG1pbiA9IDAsIHhtYXggPSAuLnguLiksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArIAogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLCBleHBhbmQgPSBleHBhbnNpb24oYWRkID0gYygwLCAwLjAwMikpLAogICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwgMC4wNiwgMC4wMikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhjbHJzX25nbyR2aV90dXJxdW9pc2UsIGNscnNfbmdvJHZpX3B1cnBsZSksIGd1aWRlID0gRkFMU0UpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMC4wNikpICsKICBsYWJzKHggPSAiQXZlcmFnZSBkb25hdGlvbiBzaGFyZSIsIHkgPSBOVUxMLCBjb2xvciA9IE5VTEwpICsKICBmYWNldF93cmFwKHZhcnMoZmFjZXQpKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKCnBsb3RfaW5jb21lX2Z1bmRpbmcgPC0gc2ltX2NsZWFuICU+JSAKICBncm91cF9ieShvcmdfZnVuZGluZywgcGVyc29uYV9pbmNvbWUpICU+JSAKICBzdW1tYXJpemUoYXZnX3NoYXJlID0gbWVhbihzaGFyZSkpICU+JSAKICBtdXRhdGUoZmFjZXQgPSAiRnVuZGluZyBzb3VyY2VzIikgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoc3RyX3dyYXBfZmFjdG9yKG9yZ19mdW5kaW5nLCAxMCkpLCAKICAgICAgICAgICAgIHggPSBhdmdfc2hhcmUsIGNvbG9yID0gZmN0X3JldihwZXJzb25hX2luY29tZSkpKSArCiAgZ2VvbV9wb2ludHJhbmdlaChzaXplID0gMC43NSwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICAgYWVzKHhtaW4gPSAwLCB4bWF4ID0gLi54Li4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IGMoMCwgMC4wMDIpKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLCAwLjA2KSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNscnNfbmdvJHZpX3R1cnF1b2lzZSwgY2xyc19uZ28kdmlfcHVycGxlKSwgZ3VpZGUgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJBdmVyYWdlIGRvbmF0aW9uIHNoYXJlIiwgeSA9IE5VTEwsIGNvbG9yID0gTlVMTCkgKwogIGZhY2V0X3dyYXAodmFycyhmYWNldCkpICsKICB0aGVtZV9uZ28oKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKQoKcGxvdF9pbmNvbWVfcmVsYXRpb25zaGlwIDwtIHNpbV9jbGVhbiAlPiUgCiAgbXV0YXRlKHBlcnNvbmFfaW5jb21lID0gZmN0X3JlY29kZShwZXJzb25hX2luY29tZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8ICQ2MSwzNzIveWVhciIgPSAiTG93ZXIgaW5jb21lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI+ICQ2MSwzNzIveWVhciIgPSAiSGlnaGVyIGluY29tZSIpKSAlPiUgCiAgZ3JvdXBfYnkob3JnX3JlbGF0aW9uc2hpcCwgcGVyc29uYV9pbmNvbWUpICU+JSAKICBzdW1tYXJpemUoYXZnX3NoYXJlID0gbWVhbihzaGFyZSkpICU+JSAKICBtdXRhdGUoZmFjZXQgPSAiUmVsYXRpb25zaGlwIHdpdGggaG9zdCBnb3Zlcm5tZW50IikgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoc3RyX3dyYXBfZmFjdG9yKG9yZ19yZWxhdGlvbnNoaXAsIDEwKSksIAogICAgICAgICAgICAgeCA9IGF2Z19zaGFyZSwgY29sb3IgPSBmY3RfcmV2KHBlcnNvbmFfaW5jb21lKSkpICsKICBnZW9tX3BvaW50cmFuZ2VoKHNpemUgPSAwLjc1LCBmYXR0ZW4gPSAxLjUsIAogICAgICAgICAgICAgICAgICAgYWVzKHhtaW4gPSAwLCB4bWF4ID0gLi54Li4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLCBleHBhbmQgPSBleHBhbnNpb24oYWRkID0gYygwLCAwLjAwMykpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIDAuMSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhjbHJzX25nbyR2aV90dXJxdW9pc2UsIGNscnNfbmdvJHZpX3B1cnBsZSksIAogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSwgbnJvdyA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDAuMjUpKSkgKwogIGxhYnMoeCA9ICJBdmVyYWdlIGRvbmF0aW9uIHNoYXJlIiwgeSA9IE5VTEwsIGNvbG9yID0gTlVMTCkgKwogIGZhY2V0X3dyYXAodmFycyhzdHJfd3JhcChmYWNldCwgNTApKSkgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpwbG90X2luY29tZV9yZWxhdGlvbnNoaXBfZXh0cmVtZSA8LSBzaW1fZXhjZWxfY2xlYW4gJT4lIAogIG11dGF0ZShwZXJzb25hX2luY29tZSA9IGZjdF9yZWNvZGUocGVyc29uYV9pbmNvbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJDUwLDAwMC95ZWFyIiA9ICJMb3dlciBpbmNvbWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiQxMDAsMDAwL3llYXIiID0gIkhpZ2hlciBpbmNvbWUiKSwKICAgICAgICAgb3JnX3JlbGF0aW9uc2hpcCA9IGZjdF9yZWNvZGUob3JnX3JlbGF0aW9uc2hpcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZGVyIGNyYWNrZG93biIgPSAiQ3JhY2tkb3duIikpICU+JSAKICBncm91cF9ieShvcmdfcmVsYXRpb25zaGlwLCBwZXJzb25hX2luY29tZSkgJT4lIAogIHN1bW1hcml6ZShhdmdfc2hhcmUgPSBtZWFuKHNoYXJlKSkgJT4lIAogIG11dGF0ZShmYWNldCA9ICJSZWxhdGlvbnNoaXAgd2l0aCBob3N0IGdvdmVybm1lbnQiKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX3JlbGF0aW9uc2hpcCwgMTApKSwgCiAgICAgICAgICAgICB4ID0gYXZnX3NoYXJlLCBjb2xvciA9IGZjdF9yZXYocGVyc29uYV9pbmNvbWUpKSkgKwogIGdlb21fcG9pbnRyYW5nZWgoc2l6ZSA9IDAuNzUsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgIGFlcyh4bWluID0gMCwgeG1heCA9IC4ueC4uKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAsIDAuMDAyKSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMC4xKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNscnNfbmdvJHBsX3llbGxvdywgY2xyc19uZ28kcGxfcHVycGxlX2xpZ2h0KSwgCiAgICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFLCBucm93ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMC4yNSkpKSArCiAgbGFicyh4ID0gIkF2ZXJhZ2UgZG9uYXRpb24gc2hhcmUiLCB5ID0gTlVMTCwgY29sb3IgPSBOVUxMKSArCiAgZmFjZXRfd3JhcCh2YXJzKHN0cl93cmFwKGZhY2V0LCA1MCkpKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKCnBsb3RfaW5jb21lIDwtICgocGxvdF9pbmNvbWVfaXNzdWUgKyBsYWJzKHggPSBOVUxMKSkgKyAKICAocGxvdF9pbmNvbWVfZnVuZGluZyArIGxhYnMoeCA9IE5VTEwpKSkgLyAKICAocGxvdF9pbmNvbWVfcmVsYXRpb25zaGlwICsgcGxvdF9pbmNvbWVfcmVsYXRpb25zaGlwX2V4dHJlbWUpCgpwbG90X2luY29tZQpnZ3NhdmUocGxvdF9pbmNvbWUsIGZpbGVuYW1lID0gaGVyZSgiYW5hbHlzaXMiLCAib3V0cHV0IiwgImZpZ3VyZXMiLCAiaW5jb21lLWFsbC5wZGYiKSwKICAgICAgIHdpZHRoID0gNiwgaGVpZ2h0ID0gNC41LCB1bml0cyA9ICJpbiIsIGRldmljZSA9IGNhaXJvX3BkZikKZ2dzYXZlKHBsb3RfaW5jb21lLCBmaWxlbmFtZSA9IGhlcmUoImFuYWx5c2lzIiwgIm91dHB1dCIsICJmaWd1cmVzIiwgImluY29tZS1hbGwucG5nIiksCiAgICAgICB3aWR0aCA9IDYsIGhlaWdodCA9IDQuNSwgdW5pdHMgPSAiaW4iLCB0eXBlID0gImNhaXJvIiwgZHBpID0gMzAwKQpgYGAKCiMjIEVkdWNhdGlvbiBhY3Jvc3MgaXNzdWUgYXJlYSwgZnVuZGluZywgYW5kIHJlbGF0aW9uc2hpcAoKYGBge3IgZWR1LWlzc3VlLWZ1bmRpbmctcmVsYXRpb25zaGlwLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yLjc1LCBvdXQud2lkdGg9IjEwMCUifQpwbG90X2VkdWNhdGlvbl9pc3N1ZSA8LSBzaW1fY2xlYW4gJT4lIAogIGdyb3VwX2J5KG9yZ19pc3N1ZSwgcGVyc29uYV9lZHVjYXRpb24pICU+JSAKICBzdW1tYXJpemUoYXZnX3NoYXJlID0gbWVhbihzaGFyZSkpICU+JSAKICBtdXRhdGUoZmFjZXQgPSAiSXNzdWUgYXJlYSIpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBmY3RfcmV2KHN0cl93cmFwX2ZhY3RvcihvcmdfaXNzdWUsIDE1KSksIAogICAgICAgICAgICAgeCA9IGF2Z19zaGFyZSwgY29sb3IgPSBmY3RfcmV2KHBlcnNvbmFfZWR1Y2F0aW9uKSkpICsKICBnZW9tX3BvaW50cmFuZ2VoKHNpemUgPSAwLjc1LCBmYXR0ZW4gPSAxLjUsCiAgICAgICAgICAgICAgICAgICBhZXMoeG1pbiA9IDAsIHhtYXggPSAuLnguLiksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArIAogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLCBleHBhbmQgPSBleHBhbnNpb24oYWRkID0gYygwLCAwLjAwMikpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIDAuMDYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoY2xyc19uZ28kcGxfcHVycGxlX2RhcmssIGNscnNfbmdvJHBsX29yYW5nZSksIGd1aWRlID0gRkFMU0UpICsKICBsYWJzKHggPSAiQXZlcmFnZSBkb25hdGlvbiBzaGFyZSIsIHkgPSBOVUxMLCBjb2xvciA9IE5VTEwpICsKICBmYWNldF93cmFwKHZhcnMoZmFjZXQpKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKCnBsb3RfZWR1Y2F0aW9uX2Z1bmRpbmcgPC0gc2ltX2NsZWFuICU+JSAKICBncm91cF9ieShvcmdfZnVuZGluZywgcGVyc29uYV9lZHVjYXRpb24pICU+JSAKICBzdW1tYXJpemUoYXZnX3NoYXJlID0gbWVhbihzaGFyZSkpICU+JSAKICBtdXRhdGUoZmFjZXQgPSAiRnVuZGluZyBzb3VyY2VzIikgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoc3RyX3dyYXBfZmFjdG9yKG9yZ19mdW5kaW5nLCAxMCkpLCAKICAgICAgICAgICAgIHggPSBhdmdfc2hhcmUsIGNvbG9yID0gZmN0X3JldihwZXJzb25hX2VkdWNhdGlvbikpKSArCiAgZ2VvbV9wb2ludHJhbmdlaChzaXplID0gMC43NSwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICAgYWVzKHhtaW4gPSAwLCB4bWF4ID0gLi54Li4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IGMoMCwgMC4wMDIpKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLCAwLjA2KSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNscnNfbmdvJHBsX3B1cnBsZV9kYXJrLCBjbHJzX25nbyRwbF9vcmFuZ2UpLCBndWlkZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkF2ZXJhZ2UgZG9uYXRpb24gc2hhcmUiLCB5ID0gTlVMTCwgY29sb3IgPSBOVUxMKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZhY2V0KSkgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpwbG90X2VkdWNhdGlvbl9yZWxhdGlvbnNoaXAgPC0gc2ltX2NsZWFuICU+JSAKICBncm91cF9ieShvcmdfcmVsYXRpb25zaGlwLCBwZXJzb25hX2VkdWNhdGlvbikgJT4lIAogIHN1bW1hcml6ZShhdmdfc2hhcmUgPSBtZWFuKHNoYXJlKSkgJT4lIAogIG11dGF0ZShmYWNldCA9ICJSZWxhdGlvbnNoaXAgd2l0aCBob3N0IGdvdmVybm1lbnQiKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX3JlbGF0aW9uc2hpcCwgMTApKSwKICAgICAgICAgICAgIHggPSBhdmdfc2hhcmUsIGNvbG9yID0gZmN0X3JldihwZXJzb25hX2VkdWNhdGlvbikpKSArCiAgZ2VvbV9wb2ludHJhbmdlaChzaXplID0gMC43NSwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICAgYWVzKHhtaW4gPSAwLCB4bWF4ID0gLi54Li4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IGMoMCwgMC4wMDIpKSkgKwogIGNvb3JkX2NhcnRlc2lhbih4bGltID0gYygwLCAwLjEpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoY2xyc19uZ28kcGxfcHVycGxlX2RhcmssIGNscnNfbmdvJHBsX29yYW5nZSksIAogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSwgbmNvbCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDAuMjUpKSwKICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gbGFiZWxfd3JhcCgxNSkpICsKICBsYWJzKHggPSAiQXZlcmFnZSBkb25hdGlvbiBzaGFyZSIsIHkgPSBOVUxMLCBjb2xvciA9IE5VTEwpICsKICBmYWNldF93cmFwKHZhcnMoc3RyX3dyYXAoZmFjZXQsIDIwKSkpICsKICB0aGVtZV9uZ28oKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKQoKcGxvdF9lZHVjYXRpb24gPC0gcGxvdF9lZHVjYXRpb25faXNzdWUgKyBwbG90X2VkdWNhdGlvbl9mdW5kaW5nICsgCiAgcGxvdF9lZHVjYXRpb25fcmVsYXRpb25zaGlwICsgZ3VpZGVfYXJlYSgpICsKICBwbG90X2xheW91dChndWlkZXMgPSAiY29sbGVjdCIsIG5jb2wgPSA0KQpwbG90X2VkdWNhdGlvbgpgYGAKCiMjIFJlbGlnaW9zaXR5IGFjcm9zcyBpc3N1ZSBhcmVhLCBmdW5kaW5nLCBhbmQgcmVsYXRpb25zaGlwCgpgYGB7ciByZWxpZ2lvbi1pc3N1ZS1mdW5kaW5nLXJlbGF0aW9uc2hpcCwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mi43NSwgb3V0LndpZHRoPSIxMDAlIn0KcGxvdF9yZWxpZ2lvbl9pc3N1ZSA8LSBzaW1fY2xlYW4gJT4lIAogIGdyb3VwX2J5KG9yZ19pc3N1ZSwgcGVyc29uYV9yZWxpZ2lvbikgJT4lIAogIHN1bW1hcml6ZShhdmdfc2hhcmUgPSBtZWFuKHNoYXJlKSkgJT4lIAogIG11dGF0ZShmYWNldCA9ICJJc3N1ZSBhcmVhIikgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoc3RyX3dyYXBfZmFjdG9yKG9yZ19pc3N1ZSwgMTUpKSwgCiAgICAgICAgICAgICB4ID0gYXZnX3NoYXJlLCBjb2xvciA9IGZjdF9yZXYocGVyc29uYV9yZWxpZ2lvbikpKSArCiAgZ2VvbV9wb2ludHJhbmdlaChzaXplID0gMC43NSwgZmF0dGVuID0gMS41LCAKICAgICAgICAgICAgICAgICAgIGFlcyh4bWluID0gMCwgeG1heCA9IC4ueC4uKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAsIDAuMDAyKSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMC4wNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhjbHJzX25nbyR2aV9ibHVlX2xpZ2h0LCBjbHJzX25nbyR2aV95ZWxsb3cpLCBndWlkZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkF2ZXJhZ2UgZG9uYXRpb24gc2hhcmUiLCB5ID0gTlVMTCwgY29sb3IgPSBOVUxMKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZhY2V0KSkgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpwbG90X3JlbGlnaW9uX2Z1bmRpbmcgPC0gc2ltX2NsZWFuICU+JSAKICBncm91cF9ieShvcmdfZnVuZGluZywgcGVyc29uYV9yZWxpZ2lvbikgJT4lIAogIHN1bW1hcml6ZShhdmdfc2hhcmUgPSBtZWFuKHNoYXJlKSkgJT4lIAogIG11dGF0ZShmYWNldCA9ICJGdW5kaW5nIHNvdXJjZXMiKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX2Z1bmRpbmcsIDEwKSksIAogICAgICAgICAgICAgeCA9IGF2Z19zaGFyZSwgY29sb3IgPSBmY3RfcmV2KHBlcnNvbmFfcmVsaWdpb24pKSkgKwogIGdlb21fcG9pbnRyYW5nZWgoc2l6ZSA9IDAuNzUsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgIGFlcyh4bWluID0gMCwgeG1heCA9IC4ueC4uKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAsIDAuMDAyKSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMC4wNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhjbHJzX25nbyR2aV9ibHVlX2xpZ2h0LCBjbHJzX25nbyR2aV95ZWxsb3cpLCBndWlkZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkF2ZXJhZ2UgZG9uYXRpb24gc2hhcmUiLCB5ID0gTlVMTCwgY29sb3IgPSBOVUxMKSArCiAgZmFjZXRfd3JhcCh2YXJzKGZhY2V0KSkgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpwbG90X3JlbGlnaW9uX3JlbGF0aW9uc2hpcCA8LSBzaW1fY2xlYW4gJT4lIAogIGdyb3VwX2J5KG9yZ19yZWxhdGlvbnNoaXAsIHBlcnNvbmFfcmVsaWdpb24pICU+JSAKICBzdW1tYXJpemUoYXZnX3NoYXJlID0gbWVhbihzaGFyZSkpICU+JSAKICBtdXRhdGUoZmFjZXQgPSAiUmVsYXRpb25zaGlwIHdpdGggaG9zdCBnb3Zlcm5tZW50IikgJT4lIAogIGdncGxvdChhZXMoeSA9IGZjdF9yZXYoc3RyX3dyYXBfZmFjdG9yKG9yZ19yZWxhdGlvbnNoaXAsIDEwKSksIAogICAgICAgICAgICAgeCA9IGF2Z19zaGFyZSwgY29sb3IgPSBmY3RfcmV2KHBlcnNvbmFfcmVsaWdpb24pKSkgKwogIGdlb21fcG9pbnRyYW5nZWgoc2l6ZSA9IDAuNzUsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgIGFlcyh4bWluID0gMCwgeG1heCA9IC4ueC4uKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAsIDAuMDAyKSkpICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMCwgMC4xKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNscnNfbmdvJHZpX2JsdWVfbGlnaHQsIGNscnNfbmdvJHZpX3llbGxvdyksIAogICAgICAgICAgICAgICAgICAgICBndWlkZSA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSwgbmNvbCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDAuMjUpKSwKICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gbGFiZWxfd3JhcCgyMCkpICsKICBsYWJzKHggPSAiQXZlcmFnZSBkb25hdGlvbiBzaGFyZSIsIHkgPSBOVUxMLCBjb2xvciA9IE5VTEwpICsKICBmYWNldF93cmFwKHZhcnMoc3RyX3dyYXAoZmFjZXQsIDIwKSkpICsKICB0aGVtZV9uZ28oKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpKQoKcGxvdF9yZWxpZ2lvbiA8LSBwbG90X3JlbGlnaW9uX2lzc3VlICsgcGxvdF9yZWxpZ2lvbl9mdW5kaW5nICsgCiAgcGxvdF9yZWxpZ2lvbl9yZWxhdGlvbnNoaXAgKyBndWlkZV9hcmVhKCkgKwogIHBsb3RfbGF5b3V0KGd1aWRlcyA9ICJjb2xsZWN0IiwgbmNvbCA9IDQpCnBsb3RfcmVsaWdpb24KYGBgCgojIyBFZHVjYXRpb24gYW5kIHJlbGlnaW9uIGFjcm9zcyBpc3N1ZSBhcmVhLCBmdW5kaW5nLCBhbmQgcmVsYXRpb25zaGlwCgpgYGB7ciBlZHVjYXRpb24tcmVsaWdpb24taXNzdWUtZnVuZGluZy1yZWxhdGlvbnNoaXAsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTQuNSwgb3V0LndpZHRoPSIxMDAlIn0KcGxvdF9lZHVjYXRpb25fcmVsaWdpb24gPC0gKHBsb3RfZWR1Y2F0aW9uX2lzc3VlICsgbGFicyh4ID0gTlVMTCkpICsgCiAgKHBsb3RfZWR1Y2F0aW9uX2Z1bmRpbmcgKyBsYWJzKHggPSBOVUxMKSkgKyAKICAocGxvdF9lZHVjYXRpb25fcmVsYXRpb25zaGlwICsgbGFicyh4ID0gTlVMTCkpICsgCiAgZ3VpZGVfYXJlYSgpICsKICBwbG90X3JlbGlnaW9uX2lzc3VlICsgCiAgcGxvdF9yZWxpZ2lvbl9mdW5kaW5nICsgCiAgcGxvdF9yZWxpZ2lvbl9yZWxhdGlvbnNoaXAgKwogIHBsb3RfbGF5b3V0KGd1aWRlcyA9ICJjb2xsZWN0IiwgbmNvbCA9IDQpCgpwbG90X2VkdWNhdGlvbl9yZWxpZ2lvbgpnZ3NhdmUocGxvdF9lZHVjYXRpb25fcmVsaWdpb24sIAogICAgICAgZmlsZW5hbWUgPSBoZXJlKCJhbmFseXNpcyIsICJvdXRwdXQiLCAiZmlndXJlcyIsICJlZHVjYXRpb24tcmVsaWdpb24tYWxsLnBkZiIpLAogICAgICAgd2lkdGggPSA2LjUsIGhlaWdodCA9IDQuNSwgdW5pdHMgPSAiaW4iLCBkZXZpY2UgPSBjYWlyb19wZGYpCmdnc2F2ZShwbG90X2VkdWNhdGlvbl9yZWxpZ2lvbiwgCiAgICAgICBmaWxlbmFtZSA9IGhlcmUoImFuYWx5c2lzIiwgIm91dHB1dCIsICJmaWd1cmVzIiwgImVkdWNhdGlvbi1yZWxpZ2lvbi1hbGwucG5nIiksCiAgICAgICB3aWR0aCA9IDYuNSwgaGVpZ2h0ID0gNC41LCB1bml0cyA9ICJpbiIsIHR5cGUgPSAiY2Fpcm8iLCBkcGkgPSAzMDApCmBgYAoKCiMjIFNvY2lhbCB0cnVzdCBhY3Jvc3MgaXNzdWUgYXJlYQoKYGBge3IgdHJ1c3QtaXNzdWVzLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00LCBvdXQud2lkdGg9IjEwMCUifQpwbG90X2lzc3VlX3NvY2lhbCA8LSBzaW1fY2xlYW4gJT4lIAogIGdyb3VwX2J5KG9yZ19pc3N1ZSwgcGVyc29uYV90cnVzdCwgcGVyc29uYV9pZGVvbG9neSwgcGVyc29uYV9leHBlcmllbmNlKSAlPiUgCiAgc3VtbWFyaXplKGF2Z19zaGFyZSA9IG1lYW4oc2hhcmUpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX2lzc3VlLCAxNSkpLCAKICAgICAgICAgICAgIHggPSBhdmdfc2hhcmUsIGNvbG9yID0gcGVyc29uYV90cnVzdCkpICsKICBnZW9tX3BvaW50cmFuZ2VoKHNpemUgPSAwLjc1LCBmYXR0ZW4gPSAxLjUsIAogICAgICAgICAgICAgICAgICAgYWVzKHhtaW4gPSAwLCB4bWF4ID0gLi54Li4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IGMoMCwgMC4wMDIpKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNscnNfbmdvJHBsX2JsdWUsIGNscnNfbmdvJHBsX3BpbmspLCAKICAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDAuMjUpKSkgKwogIGxhYnMoeCA9ICJBdmVyYWdlIHNoYXJlIG9mIGRvbmF0aW9ucyIsIHkgPSBOVUxMLCBjb2xvciA9IE5VTEwpICsKICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKHBlcnNvbmFfaWRlb2xvZ3kpLCBjb2xzID0gdmFycyhzdHJfd3JhcChwZXJzb25hX2V4cGVyaWVuY2UsIDEwMCkpKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKCnBsb3RfaXNzdWVfc29jaWFsCmdnc2F2ZShwbG90X2lzc3VlX3NvY2lhbCwgZmlsZW5hbWUgPSBoZXJlKCJhbmFseXNpcyIsICJvdXRwdXQiLCAiZmlndXJlcyIsICJpc3N1ZS1zb2NpYWwucGRmIiksCiAgICAgICB3aWR0aCA9IDYsIGhlaWdodCA9IDQsIHVuaXRzID0gImluIiwgZGV2aWNlID0gY2Fpcm9fcGRmKQpnZ3NhdmUocGxvdF9pc3N1ZV9zb2NpYWwsIGZpbGVuYW1lID0gaGVyZSgiYW5hbHlzaXMiLCAib3V0cHV0IiwgImZpZ3VyZXMiLCAiaXNzdWUtc29jaWFsLnBuZyIpLAogICAgICAgd2lkdGggPSA2LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsIHR5cGUgPSAiY2Fpcm8iLCBkcGkgPSAzMDApCmBgYAoKIyMgU29jaWFsIHRydXN0IGFjcm9zcyByZWxhdGlvbnNoaXAKCmBgYHtyIHRydXN0LXJlbGF0aW9uc2hpcCwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NCwgb3V0LndpZHRoPSIxMDAlIn0KcGxvdF9yZWxhdGlvbnNoaXBfc29jaWFsIDwtIHNpbV9jbGVhbiAlPiUgCiAgZ3JvdXBfYnkob3JnX3JlbGF0aW9uc2hpcCwgcGVyc29uYV90cnVzdCwgcGVyc29uYV9pZGVvbG9neSwgcGVyc29uYV9leHBlcmllbmNlKSAlPiUgCiAgc3VtbWFyaXplKGF2Z19zaGFyZSA9IG1lYW4oc2hhcmUpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX3JlbGF0aW9uc2hpcCwgMTApKSwgCiAgICAgICAgICAgICB4ID0gYXZnX3NoYXJlLCBjb2xvciA9IHBlcnNvbmFfdHJ1c3QpKSArCiAgZ2VvbV9wb2ludHJhbmdlaChzaXplID0gMC43NSwgZmF0dGVuID0gMS41LAogICAgICAgICAgICAgICAgICAgYWVzKHhtaW4gPSAwLCB4bWF4ID0gLi54Li4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IGMoMCwgMC4wMDIpKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKGNscnNfbmdvJHBsX2JsdWUsIGNscnNfbmdvJHBsX3BpbmspLCAKICAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDAuMjUpKSkgKwogIGxhYnMoeCA9ICJBdmVyYWdlIHNoYXJlIG9mIGRvbmF0aW9ucyIsIHkgPSBOVUxMLCBjb2xvciA9IE5VTEwpICsKICBmYWNldF9ncmlkKHJvd3MgPSB2YXJzKHBlcnNvbmFfaWRlb2xvZ3kpLCBjb2xzID0gdmFycyhzdHJfd3JhcChwZXJzb25hX2V4cGVyaWVuY2UsIDEwMCkpKSArCiAgdGhlbWVfbmdvKCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKCnBsb3RfcmVsYXRpb25zaGlwX3NvY2lhbApnZ3NhdmUocGxvdF9yZWxhdGlvbnNoaXBfc29jaWFsLCBmaWxlbmFtZSA9IGhlcmUoImFuYWx5c2lzIiwgIm91dHB1dCIsICJmaWd1cmVzIiwgInJlbGF0aW9uc2hpcC1zb2NpYWwucGRmIiksCiAgICAgICB3aWR0aCA9IDYsIGhlaWdodCA9IDQsIHVuaXRzID0gImluIiwgZGV2aWNlID0gY2Fpcm9fcGRmKQpnZ3NhdmUocGxvdF9yZWxhdGlvbnNoaXBfc29jaWFsLCBmaWxlbmFtZSA9IGhlcmUoImFuYWx5c2lzIiwgIm91dHB1dCIsICJmaWd1cmVzIiwgInJlbGF0aW9uc2hpcC1zb2NpYWwucG5nIiksCiAgICAgICB3aWR0aCA9IDYsIGhlaWdodCA9IDQsIHVuaXRzID0gImluIiwgdHlwZSA9ICJjYWlybyIsIGRwaSA9IDMwMCkKYGBgCgojIyBTb2NpYWwgdHJ1c3QgYWNyb3NzIGZ1bmRpbmcKCmBgYHtyIHRydXN0LWZ1bmRpbmcsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTQsIG91dC53aWR0aD0iMTAwJSJ9CnBsb3RfZnVuZGluZ19zb2NpYWwgPC0gc2ltX2NsZWFuICU+JSAKICBncm91cF9ieShvcmdfZnVuZGluZywgcGVyc29uYV90cnVzdCwgcGVyc29uYV9pZGVvbG9neSwgcGVyc29uYV9leHBlcmllbmNlKSAlPiUgCiAgc3VtbWFyaXplKGF2Z19zaGFyZSA9IG1lYW4oc2hhcmUpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gZmN0X3JldihzdHJfd3JhcF9mYWN0b3Iob3JnX2Z1bmRpbmcsIDE1KSksIAogICAgICAgICAgICAgeCA9IGF2Z19zaGFyZSwgY29sb3IgPSBwZXJzb25hX3RydXN0KSkgKwogIGdlb21fcG9pbnRyYW5nZWgoc2l6ZSA9IDAuNzUsIGZhdHRlbiA9IDEuNSwKICAgICAgICAgICAgICAgICAgIGFlcyh4bWluID0gMCwgeG1heCA9IC4ueC4uKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSBjKDAsIDAuMDAyKSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhjbHJzX25nbyRwbF9ibHVlLCBjbHJzX25nbyRwbF9waW5rKSwgCiAgICAgICAgICAgICAgICAgICAgIGd1aWRlID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAwLjI1KSkpICsKICBsYWJzKHggPSAiQXZlcmFnZSBzaGFyZSBvZiBkb25hdGlvbnMiLCB5ID0gTlVMTCwgY29sb3IgPSBOVUxMKSArCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhwZXJzb25hX2lkZW9sb2d5KSwgY29scyA9IHZhcnMoc3RyX3dyYXAocGVyc29uYV9leHBlcmllbmNlLCAxMDApKSkgKwogIHRoZW1lX25nbygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpwbG90X2Z1bmRpbmdfc29jaWFsCmdnc2F2ZShwbG90X2Z1bmRpbmdfc29jaWFsLCBmaWxlbmFtZSA9IGhlcmUoImFuYWx5c2lzIiwgIm91dHB1dCIsICJmaWd1cmVzIiwgImZ1bmRpbmctc29jaWFsLnBkZiIpLAogICAgICAgd2lkdGggPSA2LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsIGRldmljZSA9IGNhaXJvX3BkZikKZ2dzYXZlKHBsb3RfZnVuZGluZ19zb2NpYWwsIGZpbGVuYW1lID0gaGVyZSgiYW5hbHlzaXMiLCAib3V0cHV0IiwgImZpZ3VyZXMiLCAiZnVuZGluZy1zb2NpYWwucG5nIiksCiAgICAgICB3aWR0aCA9IDYsIGhlaWdodCA9IDQsIHVuaXRzID0gImluIiwgdHlwZSA9ICJjYWlybyIsIGRwaSA9IDMwMCkKYGBgCgoKXAoKIyBPcmlnaW5hbCBjb21wdXRpbmcgZW52aXJvbm1lbnQKCjxidXR0b24gZGF0YS10b2dnbGU9ImNvbGxhcHNlIiBkYXRhLXRhcmdldD0iI3Nlc3Npb25pbmZvIiBjbGFzcz0iYnRuIGJ0bi1wcmltYXJ5IGJ0bi1tZCBidG4taW5mbyI+SGVyZSdzIHdoYXQgd2UgdXNlZCB0aGUgbGFzdCB0aW1lIHdlIGJ1aWx0IHRoaXMgcGFnZTwvYnV0dG9uPgoKPGRpdiBpZD0ic2Vzc2lvbmluZm8iIGNsYXNzPSJjb2xsYXBzZSI+CgpgYGB7ciBzaG93LXNlc3Npb24taW5mbywgZWNobz1UUlVFLCB3aWR0aD0xMDB9CmRldnRvb2xzOjpzZXNzaW9uX2luZm8oKQoKd3JpdGVMaW5lcyhyZWFkTGluZXMoZmlsZS5wYXRoKFN5cy5nZXRlbnYoIkhPTUUiKSwgIi5SL01ha2V2YXJzIikpKQpgYGAKCjwvZGl2Pgo=