Only keep articles from 2002 because few authors had nationality predictions before 2002 (mostly due to missing metadata). See 093.summary-stats for more details.

alpha_threshold <- qnorm(0.975)
load("Rdata/raws.Rdata")

pubmed_nat_df <- corr_authors %>%
  filter(year(year) >= 2002) %>%
  left_join(nationalize_df, by = c("fore_name", "last_name")) %>%
  group_by(pmid, journal, publication_date, year, adjusted_citations) %>%
  summarise_at(vars(African:SouthAsian), mean, na.rm = T) %>%
  ungroup()

iscb_nat_df <- keynotes %>%
  left_join(nationalize_df, by = c("fore_name", "last_name"))

start_year <- 1992
end_year <- 2019
n_years <- end_year - start_year
my_jours <- unique(pubmed_nat_df$journal)
my_confs <- unique(iscb_nat_df$conference)
n_jours <- length(my_jours)
n_confs <- length(my_confs)
region_levels <- paste(c("Celtic/English", "European", "East Asian", "Hispanic", "South Asian", "Arabic", "Hebrew", "African", "Nordic", "Greek"), "names")
region_levels_let <- toupper(letters[1:8])
region_cols <- c("#ffffb3", "#fccde5", "#b3de69", "#fdb462", "#80b1d3", "#8dd3c7", "#bebada", "#fb8072", "#bc80bd", "#ccebc5")

Names grouping:

our_country_map <- read_tsv("https://raw.githubusercontent.com/greenelab/wiki-nationality-estimate/7c22d0a5f661ce5aeb785215095deda40973ff17/data/country_to_region_NamePrism.tsv") %>%
  rename("region" = Region) %>%
  recode_region()
## 
## ── Column specification ──────────────────────────────────────────
## cols(
##   Country = col_character(),
##   Region = col_character()
## )
my_world <- world %>%
  select(-geometry) %>%
  rename(Country = "name") %>%
  left_join(our_country_map, by = "Country")

(gworld <- ggplot(data = my_world) +
  geom_sf(aes(fill = fct_relevel(region, region_levels))) +
  coord_sf(crs = "+proj=eqearth +wktext") +
  scale_fill_manual(
    values = region_cols,
    na.translate = FALSE
  ) +
  theme(
    panel.background = element_rect(fill = "azure"),
    legend.title = element_blank(),
    legend.position = "bottom",
    panel.border = element_rect(fill = NA)
  ))

ggsave("figs/2020-01-31_groupings.png", gworld, width = 7.2, height = 4.3)
ggsave("figs/2020-01-31_groupings.svg", gworld, width = 7.2, height = 4.3)

Descriptive statistics

Prepare data frames for later analyses:

  • rbind results of race predictions in iscb and Pubmed
  • pivot long
  • compute mean, sd, marginal error
iscb_pubmed_oth <- iscb_nat_df %>%
  rename("journal" = conference) %>%
  select(year, journal, African:SouthAsian, publication_date) %>%
  mutate(
    type = "Keynote speakers/Fellows",
    adjusted_citations = 1,
    pmid = -9999
  ) %>%
  bind_rows(
    pubmed_nat_df %>%
      select(pmid, year, journal, African:SouthAsian, publication_date, adjusted_citations) %>%
      mutate(type = "Pubmed authors")
  ) %>%
  mutate(OtherCategories = SouthAsian + Hispanic + Jewish + Muslim + Nordic + Greek + African) %>%
  pivot_longer(c(African:SouthAsian, OtherCategories),
    names_to = "region",
    values_to = "probabilities"
  ) %>%
  filter(!is.na(probabilities)) %>%
  group_by(type, year, region)

iscb_pubmed_sum_oth <- iscb_pubmed_oth %>%
  summarise(
    mean_prob = mean(probabilities),
    se_prob = sd(probabilities)/sqrt(n()),
    me_prob = alpha_threshold * se_prob,
    .groups = "drop"
  )

iscb_pubmed_sum <- iscb_pubmed_sum_oth %>%
  filter(region != "OtherCategories")

Prepare data frames for analysis

By conference keynotes/fellows

i <- 0
iscb_nat <- vector("list", length = n_confs)

for (conf in my_confs) {
  i <- i + 1
  iscb_nat[[i]] <- iscb_pubmed_oth %>%
    filter(region != "OtherCategories", type != "Pubmed authors" & journal == conf) %>%
    group_by(type, year, region, journal) %>%
    summarise(mean_prob = mean(probabilities), .groups = "drop")
}
save(my_world, iscb_pubmed_oth, iscb_nat, file = "Rdata/iscb-pubmed_nat.Rdata")

Figures for paper

Figure 4

Compared to the name collection of Pubmed authors, honorees with Celtic/English names are overrepresented while honorees with East Asian names are underrepresented.

fig_4a <- iscb_pubmed_sum %>%
  filter(year < "2020-01-01") %>%
  region_breakdown("main", region_levels, fct_rev(type)) +
  guides(fill = guide_legend(nrow = 2)) +
  theme(legend.position = "bottom")

large_regions <- c("CelticEnglish", "EastAsian", "European", "OtherCategories")
## Mean and standard deviation of predicted probabilities:
fig_4b <- iscb_pubmed_sum_oth %>%
  filter(region %in% large_regions) %>%
  recode_region() %>%
  gam_and_ci(
    df2 = iscb_pubmed_oth %>%
      filter(region %in% large_regions) %>%
      recode_region(),
    start_y = start_year, end_y = end_year
  ) +
  theme(
    legend.position = c(0.88, 0.83),
    panel.grid.minor = element_blank(),
    legend.margin = margin(-0.5, 0, 0, 0, unit = "cm"),
    legend.text = element_text(size = 7)
  ) +
  facet_wrap(vars(fct_relevel(region, large_regions)), nrow = 1)

fig_4 <- cowplot::plot_grid(fig_4a, fig_4b, labels = "AUTO", ncol = 1, rel_heights = c(1.3, 1))
## `geom_smooth()` using formula 'y ~ s(x, bs = "cs")'
fig_4

ggsave("figs/region_breakdown.png", fig_4, width = 6.7, height = 5.5, dpi = 600)
ggsave("figs/region_breakdown.svg", fig_4, width = 6.7, height = 5.5)

Hypothesis testing

iscb_lm <- iscb_pubmed_oth %>%
  ungroup() %>%
  mutate(
    # year = c(scale(year(year))),
    # year = as.factor(year),
    type = as.factor(type) %>% relevel(ref = "Pubmed authors")
  )
main_lm <- function(regioni) {
  glm(type ~ year + probabilities,
    data = iscb_lm %>%
      filter(region == regioni, !is.na(probabilities), year(year) >= 2002),
    family = "binomial"
  )
}

inte_lm <- function(regioni) {
  glm(type ~ year * probabilities,
    data = iscb_lm %>%
      filter(region == regioni, !is.na(probabilities), year(year) >= 2002),
    family = "binomial"
  )
}

main_list <- lapply(large_regions, main_lm)
names(main_list) <- large_regions
lapply(main_list, broom::tidy)
## $CelticEnglish
## # A tibble: 3 x 5
##   term           estimate std.error statistic  p.value
##   <chr>             <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)   -2.62     0.489         -5.36 8.47e- 8
## 2 year          -0.000250 0.0000321     -7.78 7.40e-15
## 3 probabilities  0.869    0.139          6.26 3.97e-10
## 
## $EastAsian
## # A tibble: 3 x 5
##   term           estimate std.error statistic  p.value
##   <chr>             <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)   -2.29     0.479         -4.77 1.81e- 6
## 2 year          -0.000241 0.0000320     -7.51 6.02e-14
## 3 probabilities -1.75     0.250         -7.00 2.51e-12
## 
## $European
## # A tibble: 3 x 5
##   term           estimate std.error statistic  p.value
##   <chr>             <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)   -2.15     0.484         -4.45 8.72e- 6
## 2 year          -0.000271 0.0000320     -8.46 2.62e-17
## 3 probabilities  0.222    0.137          1.62 1.05e- 1
## 
## $OtherCategories
## # A tibble: 3 x 5
##   term           estimate std.error statistic  p.value
##   <chr>             <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)   -2.07     0.479         -4.33 1.52e- 5
## 2 year          -0.000274 0.0000319     -8.58 9.22e-18
## 3 probabilities  0.159    0.151          1.05 2.95e- 1
inte_list <- lapply(large_regions, inte_lm)
lapply(inte_list, broom::tidy)
## [[1]]
## # A tibble: 4 x 5
##   term                 estimate std.error statistic  p.value
##   <chr>                   <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)        -2.48      0.627        -3.96  7.57e- 5
## 2 year               -0.000259  0.0000414    -6.26  3.96e-10
## 3 probabilities       0.451     1.19          0.380 7.04e- 1
## 4 year:probabilities  0.0000283 0.0000796     0.355 7.23e- 1
## 
## [[2]]
## # A tibble: 4 x 5
##   term                estimate std.error statistic  p.value
##   <chr>                  <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)        -2.45     0.500        -4.90  9.36e- 7
## 2 year               -0.000229 0.0000334    -6.87  6.37e-12
## 3 probabilities       0.853    2.19          0.389 6.97e- 1
## 4 year:probabilities -0.000172 0.000146     -1.18  2.38e- 1
## 
## [[3]]
## # A tibble: 4 x 5
##   term                estimate std.error statistic  p.value
##   <chr>                  <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)        -1.66     0.614         -2.71 6.75e- 3
## 2 year               -0.000303 0.0000410     -7.39 1.44e-13
## 3 probabilities      -1.28     1.20          -1.07 2.85e- 1
## 4 year:probabilities  0.000101 0.0000796      1.27 2.05e- 1
## 
## [[4]]
## # A tibble: 4 x 5
##   term                estimate std.error statistic  p.value
##   <chr>                  <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)        -1.55     0.598         -2.60 9.42e- 3
## 2 year               -0.000309 0.0000401     -7.70 1.31e-14
## 3 probabilities      -1.76     1.35          -1.30 1.92e- 1
## 4 year:probabilities  0.000127 0.0000882      1.44 1.50e- 1
for (i in 1:4) {
  print(anova(main_list[[i]], inte_list[[i]], test = "Chisq"))
}
## Analysis of Deviance Table
## 
## Model 1: type ~ year + probabilities
## Model 2: type ~ year * probabilities
##   Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1    163886     4599.0                     
## 2    163885     4598.9  1  0.12594   0.7227
## Analysis of Deviance Table
## 
## Model 1: type ~ year + probabilities
## Model 2: type ~ year * probabilities
##   Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1    163886     4554.1                     
## 2    163885     4552.7  1   1.3867    0.239
## Analysis of Deviance Table
## 
## Model 1: type ~ year + probabilities
## Model 2: type ~ year * probabilities
##   Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1    163886     4632.2                     
## 2    163885     4630.6  1    1.607   0.2049
## Analysis of Deviance Table
## 
## Model 1: type ~ year + probabilities
## Model 2: type ~ year * probabilities
##   Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1    163886     4633.7                     
## 2    163885     4631.6  1   2.0781   0.1494

Interaction terms do not predict type over and above the main effect of name origin probability and year (p > 0.01).

Conclusion

A Celtic/English name has 2.3850497 the odds of being selected as an honoree, significantly higher compared to other names (\(\beta_\textrm{Celtic/English} =\) 0.86922, P = 3.9713e-10). An East Asian name has 0.1731846 the odds of being selected as an honoree, significantly lower than to other names (\(\beta_\textrm{East Asian} =\) -1.7534, P = 2.5132e-12). The two groups of scientists did not have a significant association with names predicted to be European (P = 0.10527) or in Other categories (P = 0.29469).

Alternative approach

Sincere thanks to the reviewers, Byron Smith and Katie Pollard, for their detailed suggestion with code.

The question of what unit one should use to perform this type of analyses is a difficult one. We present here an alternative analysis that treats names as units instead of honors and authorships. We caution that this approach does not distinguish scientists who were honored 4 times vs. one time and hence may yield a conservative estimate of disparity. Further, different authors may have the same names, and to sum adjusted_citations across them may not be optimal.

Nonetheless, the finding here is consistent with what we have seen above where East Asian names are underrepresented in the honoree group.

keynotes_post_2002 <- keynotes %>%
  filter(year(year) >= 2002) %>%
  separate_rows(afflcountries, sep = ",") %>%
  filter(afflcountries == "United States") %>%
  group_by(fore_name_simple, last_name_simple) %>%
  summarise_at("year", n_distinct, na.rm = T)

# nationalize_df was not unique, so the left join to corr_authors resulted
# in (mostly) duplicate rows.
# FIXME: I was getting occasional crashes on this line, and it's slow.
# TRANG: fixed on June 3, 2021 using distinct().
# Also, the duplication was intentional.
# Please see our extensive discussion on the merge/join on full names vs
# fore_name and last_name here:
# <https://github.com/greenelab/iscb-diversity/issues/6>

distinct_nationalize_df <- nationalize_df %>%
  distinct(fore_name_simple, last_name_simple, .keep_all = TRUE)

# Calculate sum of adjusted citations for all publications for a first-name/
# last-name pair in db since 2002
# where the author countries include US.
authors <- corr_authors %>%
  filter(year(year) >= 2002) %>%
  separate_rows(countries, sep = ",") %>%
  filter(countries == "US") %>%
  group_by(fore_name_simple, last_name_simple) %>%
  summarise_at(vars(adjusted_citations), sum, na.rm = T) %>%
  left_join(
    keynotes_post_2002[c("fore_name_simple", "last_name_simple", "year")],
    by = c("fore_name_simple", "last_name_simple")
  ) %>%
  left_join(distinct_nationalize_df, by = c("fore_name_simple", "last_name_simple")) %>%
  mutate(OtherCategories = SouthAsian + Hispanic + Jewish + Muslim + Nordic + Greek + African)

for (large_region in large_regions) {
  glm(
    as.formula(paste("honoree ~ adjusted_citations +", large_region)),
    data = authors %>% mutate(honoree = !is.na(year)),
    family = "binomial",
    control = list(epsilon = 1e-12, maxit = 55, trace = FALSE)
  ) %>%
    broom::tidy() %>%
    print()
}
## # A tibble: 3 x 5
##   term               estimate std.error statistic   p.value
##   <chr>                 <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)         -5.79     0.160      -36.2  2.15e-286
## 2 adjusted_citations   0.0555   0.00426     13.0  8.68e- 39
## 3 CelticEnglish        0.453    0.272        1.66 9.65e-  2
## # A tibble: 3 x 5
##   term               estimate std.error statistic  p.value
##   <chr>                 <dbl>     <dbl>     <dbl>    <dbl>
## 1 (Intercept)         -5.42     0.130      -41.5  0.      
## 2 adjusted_citations   0.0566   0.00446     12.7  7.36e-37
## 3 EastAsian           -3.18     1.02        -3.10 1.91e- 3
## # A tibble: 3 x 5
##   term               estimate std.error statistic   p.value
##   <chr>                 <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)         -5.75     0.154      -37.3  6.30e-304
## 2 adjusted_citations   0.0560   0.00423     13.2  5.74e- 40
## 3 European             0.393    0.294        1.33 1.82e-  1
## # A tibble: 3 x 5
##   term               estimate std.error statistic   p.value
##   <chr>                 <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)         -5.76     0.163      -35.2  6.52e-272
## 2 adjusted_citations   0.0563   0.00425     13.3  3.70e- 40
## 3 OtherCategories      0.357    0.299        1.19 2.33e-  1

Time lag

In this section, we show that a 10-year lag model results in a similar result for East Asian scientists’ names, even though the effect size is less striking. For example, if we assume that honors accrue 10 years after their most prolific year with respect to authorships, the proportion of honor associated with East Asian name origins in 2019 is still substantially less than the proportion of senior authorships associated with East Asian names in 2009.

year_lag <- period(10, "years")
iscb_pubmed_oth_lag <- iscb_nat_df %>%
  rename("journal" = conference) %>%
  select(year, journal, African:SouthAsian, publication_date) %>%
  mutate(
    type = "Keynote speakers/Fellows",
    adjusted_citations = 1,
    pmid = -9999
  ) %>%
  bind_rows(
    pubmed_nat_df %>%
      select(pmid, year, journal, African:SouthAsian, publication_date, adjusted_citations) %>%
      mutate(type = "Pubmed authors", year = year + year_lag)
  ) %>%
  mutate(OtherCategories = SouthAsian + Hispanic + Jewish + Muslim + Nordic + Greek + African) %>%
  pivot_longer(c(African:SouthAsian, OtherCategories),
    names_to = "region",
    values_to = "probabilities"
  ) %>%
  filter(!is.na(probabilities), year(year) >= 2002) %>%
  group_by(type, year, region) 

iscb_lm_lag <- iscb_pubmed_oth_lag %>%
  ungroup() %>%
  mutate(type = as.factor(type) %>% relevel(ref = "Pubmed authors"))

main_lm <- function(regioni) {
  glm(type ~ year + probabilities,
    data = iscb_lm_lag %>%
      filter(region == regioni, !is.na(probabilities)),
    family = "binomial"
  )
}

main_list <- lapply(large_regions, main_lm)
names(main_list) <- large_regions
lapply(main_list, broom::tidy)
## $CelticEnglish
## # A tibble: 3 x 5
##   term          estimate std.error statistic   p.value
##   <chr>            <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)   29.0     1.19         24.5   4.51e-132
## 2 year          -0.00209 0.0000750   -27.9   5.63e-171
## 3 probabilities  0.130   0.170         0.767 4.43e-  1
## 
## $EastAsian
## # A tibble: 3 x 5
##   term          estimate std.error statistic   p.value
##   <chr>            <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)   28.9     1.18          24.6  3.99e-133
## 2 year          -0.00208 0.0000749    -27.7  2.99e-169
## 3 probabilities -1.01    0.280         -3.60 3.20e-  4
## 
## $European
## # A tibble: 3 x 5
##   term          estimate std.error statistic   p.value
##   <chr>            <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)   29.1     1.18         24.7   1.06e-134
## 2 year          -0.00210 0.0000748   -28.0   8.91e-173
## 3 probabilities  0.0595  0.166         0.358 7.20e-  1
## 
## $OtherCategories
## # A tibble: 3 x 5
##   term          estimate std.error statistic   p.value
##   <chr>            <dbl>     <dbl>     <dbl>     <dbl>
## 1 (Intercept)   29.1     1.18          24.8  2.82e-135
## 2 year          -0.00210 0.0000748    -28.1  7.58e-174
## 3 probabilities  0.432   0.183          2.36 1.80e-  2

Supplementary Figure S5

It’s difficult to come to a conclusion for other regions with so few data points and the imperfect accuracy of our prediction. There seems to be little difference between the proportion of keynote speakers of African, Arabic, South Asian and Hispanic origin than those in the field. However, just because a nationality isn’t underrepresented against the field doesn’t mean scientists from that nationality are appropriately represented.

# df2 <- iscb_pubmed_oth %>%
#   filter(region != "OtherCategories") %>%
#   recode_region()
# 
# fig_s5 <- iscb_pubmed_sum %>%
#   recode_region() %>%
#   gam_and_ci(
#     df2 = df2,
#     start_y = start_year, end_y = end_year
#   ) +
#   theme(legend.position = c(0.8, 0.1)) +
#   facet_wrap(vars(fct_relevel(region, region_levels)), ncol = 3)
# fig_s5
# ggsave("figs/fig_s5.png", fig_s5, width = 6, height = 6)
# ggsave("figs/fig_s5.svg", fig_s5, width = 6, height = 6)
sessionInfo()
## R version 4.0.3 (2020-10-10)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 20.04 LTS
## 
## Matrix products: default
## BLAS/LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.8.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods  
## [7] base     
## 
## other attached packages:
##  [1] gdtools_0.2.2       wru_0.1-10          rnaturalearth_0.1.0
##  [4] lubridate_1.7.9.2   caret_6.0-86        lattice_0.20-41    
##  [7] forcats_0.5.0       stringr_1.4.0       dplyr_1.0.2        
## [10] purrr_0.3.4         readr_1.4.0         tidyr_1.1.2        
## [13] tibble_3.0.4        ggplot2_3.3.2       tidyverse_1.3.0    
## 
## loaded via a namespace (and not attached):
##   [1] colorspace_2.0-0        ellipsis_0.3.1         
##   [3] class_7.3-17            rprojroot_1.3-2        
##   [5] fs_1.5.0                rstudioapi_0.12        
##   [7] farver_2.0.3            remotes_2.2.0          
##   [9] DT_0.16                 prodlim_2019.11.13     
##  [11] fansi_0.4.1             xml2_1.3.2             
##  [13] codetools_0.2-16        splines_4.0.3          
##  [15] knitr_1.30              pkgload_1.1.0          
##  [17] jsonlite_1.7.1          pROC_1.16.2            
##  [19] broom_0.7.2             dbplyr_2.0.0           
##  [21] rgeos_0.5-5             compiler_4.0.3         
##  [23] httr_1.4.2              backports_1.2.0        
##  [25] assertthat_0.2.1        Matrix_1.2-18          
##  [27] cli_2.1.0               htmltools_0.5.0        
##  [29] prettyunits_1.1.1       tools_4.0.3            
##  [31] gtable_0.3.0            glue_1.4.2             
##  [33] rnaturalearthdata_0.1.0 reshape2_1.4.4         
##  [35] Rcpp_1.0.5              cellranger_1.1.0       
##  [37] vctrs_0.3.4             svglite_1.2.3.2        
##  [39] nlme_3.1-149            iterators_1.0.13       
##  [41] crosstalk_1.1.0.1       timeDate_3043.102      
##  [43] gower_0.2.2             xfun_0.19              
##  [45] ps_1.4.0                testthat_3.0.0         
##  [47] rvest_0.3.6             lifecycle_0.2.0        
##  [49] devtools_2.3.2          MASS_7.3-53            
##  [51] scales_1.1.1            ipred_0.9-9            
##  [53] hms_0.5.3               RColorBrewer_1.1-2     
##  [55] yaml_2.2.1              curl_4.3               
##  [57] memoise_1.1.0           rpart_4.1-15           
##  [59] stringi_1.5.3           desc_1.2.0             
##  [61] foreach_1.5.1           e1071_1.7-4            
##  [63] pkgbuild_1.1.0          lava_1.6.8.1           
##  [65] systemfonts_0.3.2       rlang_0.4.8            
##  [67] pkgconfig_2.0.3         evaluate_0.14          
##  [69] sf_0.9-6                recipes_0.1.15         
##  [71] htmlwidgets_1.5.2       labeling_0.4.2         
##  [73] cowplot_1.1.0           tidyselect_1.1.0       
##  [75] processx_3.4.4          plyr_1.8.6             
##  [77] magrittr_1.5            R6_2.5.0               
##  [79] generics_0.1.0          DBI_1.1.0              
##  [81] mgcv_1.8-33             pillar_1.4.6           
##  [83] haven_2.3.1             withr_2.3.0            
##  [85] units_0.6-7             survival_3.2-7         
##  [87] sp_1.4-4                nnet_7.3-14            
##  [89] modelr_0.1.8            crayon_1.3.4           
##  [91] KernSmooth_2.23-17      utf8_1.1.4             
##  [93] rmarkdown_2.5           usethis_1.6.3          
##  [95] grid_4.0.3              readxl_1.3.1           
##  [97] data.table_1.13.2       callr_3.5.1            
##  [99] ModelMetrics_1.2.2.2    reprex_0.3.0           
## [101] digest_0.6.27           classInt_0.4-3         
## [103] stats4_4.0.3            munsell_0.5.0          
## [105] viridisLite_0.3.0       sessioninfo_1.1.1
LS0tCnRpdGxlOiAiUmVwcmVzZW50YXRpb24gYW5hbHlzaXMgb2YgbmFtZSBvcmlnaW5zIgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkKc291cmNlKCJ1dGlscy9yLXV0aWxzLlIiKQp0aGVtZV9zZXQodGhlbWVfYncoKSArIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkpCmBgYAoKT25seSBrZWVwIGFydGljbGVzIGZyb20gMjAwMiBiZWNhdXNlIGZldyBhdXRob3JzIGhhZCBuYXRpb25hbGl0eSBwcmVkaWN0aW9ucyBiZWZvcmUgMjAwMiAobW9zdGx5IGR1ZSB0byBtaXNzaW5nIG1ldGFkYXRhKS4KU2VlIFswOTMuc3VtbWFyeS1zdGF0c10oMDkzLnN1bW1hcnktc3RhdHMuaHRtbCkgZm9yIG1vcmUgZGV0YWlscy4KCmBgYHtyfQphbHBoYV90aHJlc2hvbGQgPC0gcW5vcm0oMC45NzUpCmxvYWQoIlJkYXRhL3Jhd3MuUmRhdGEiKQoKcHVibWVkX25hdF9kZiA8LSBjb3JyX2F1dGhvcnMgJT4lCiAgZmlsdGVyKHllYXIoeWVhcikgPj0gMjAwMikgJT4lCiAgbGVmdF9qb2luKG5hdGlvbmFsaXplX2RmLCBieSA9IGMoImZvcmVfbmFtZSIsICJsYXN0X25hbWUiKSkgJT4lCiAgZ3JvdXBfYnkocG1pZCwgam91cm5hbCwgcHVibGljYXRpb25fZGF0ZSwgeWVhciwgYWRqdXN0ZWRfY2l0YXRpb25zKSAlPiUKICBzdW1tYXJpc2VfYXQodmFycyhBZnJpY2FuOlNvdXRoQXNpYW4pLCBtZWFuLCBuYS5ybSA9IFQpICU+JQogIHVuZ3JvdXAoKQoKaXNjYl9uYXRfZGYgPC0ga2V5bm90ZXMgJT4lCiAgbGVmdF9qb2luKG5hdGlvbmFsaXplX2RmLCBieSA9IGMoImZvcmVfbmFtZSIsICJsYXN0X25hbWUiKSkKCnN0YXJ0X3llYXIgPC0gMTk5MgplbmRfeWVhciA8LSAyMDE5Cm5feWVhcnMgPC0gZW5kX3llYXIgLSBzdGFydF95ZWFyCm15X2pvdXJzIDwtIHVuaXF1ZShwdWJtZWRfbmF0X2RmJGpvdXJuYWwpCm15X2NvbmZzIDwtIHVuaXF1ZShpc2NiX25hdF9kZiRjb25mZXJlbmNlKQpuX2pvdXJzIDwtIGxlbmd0aChteV9qb3VycykKbl9jb25mcyA8LSBsZW5ndGgobXlfY29uZnMpCnJlZ2lvbl9sZXZlbHMgPC0gcGFzdGUoYygiQ2VsdGljL0VuZ2xpc2giLCAiRXVyb3BlYW4iLCAiRWFzdCBBc2lhbiIsICJIaXNwYW5pYyIsICJTb3V0aCBBc2lhbiIsICJBcmFiaWMiLCAiSGVicmV3IiwgIkFmcmljYW4iLCAiTm9yZGljIiwgIkdyZWVrIiksICJuYW1lcyIpCnJlZ2lvbl9sZXZlbHNfbGV0IDwtIHRvdXBwZXIobGV0dGVyc1sxOjhdKQpyZWdpb25fY29scyA8LSBjKCIjZmZmZmIzIiwgIiNmY2NkZTUiLCAiI2IzZGU2OSIsICIjZmRiNDYyIiwgIiM4MGIxZDMiLCAiIzhkZDNjNyIsICIjYmViYWRhIiwgIiNmYjgwNzIiLCAiI2JjODBiZCIsICIjY2NlYmM1IikKYGBgCgpOYW1lcyBncm91cGluZzoKYGBge3Igd2FybmluZz1GQUxTRSwgZmlnLmhlaWdodCA9IDN9Cm91cl9jb3VudHJ5X21hcCA8LSByZWFkX3RzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2dyZWVuZWxhYi93aWtpLW5hdGlvbmFsaXR5LWVzdGltYXRlLzdjMjJkMGE1ZjY2MWNlNWFlYjc4NTIxNTA5NWRlZGE0MDk3M2ZmMTcvZGF0YS9jb3VudHJ5X3RvX3JlZ2lvbl9OYW1lUHJpc20udHN2IikgJT4lCiAgcmVuYW1lKCJyZWdpb24iID0gUmVnaW9uKSAlPiUKICByZWNvZGVfcmVnaW9uKCkKCm15X3dvcmxkIDwtIHdvcmxkICU+JQogIHNlbGVjdCgtZ2VvbWV0cnkpICU+JQogIHJlbmFtZShDb3VudHJ5ID0gIm5hbWUiKSAlPiUKICBsZWZ0X2pvaW4ob3VyX2NvdW50cnlfbWFwLCBieSA9ICJDb3VudHJ5IikKCihnd29ybGQgPC0gZ2dwbG90KGRhdGEgPSBteV93b3JsZCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBmY3RfcmVsZXZlbChyZWdpb24sIHJlZ2lvbl9sZXZlbHMpKSkgKwogIGNvb3JkX3NmKGNycyA9ICIrcHJvaj1lcWVhcnRoICt3a3RleHQiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwoCiAgICB2YWx1ZXMgPSByZWdpb25fY29scywKICAgIG5hLnRyYW5zbGF0ZSA9IEZBTFNFCiAgKSArCiAgdGhlbWUoCiAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiYXp1cmUiKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSkKICApKQoKZ2dzYXZlKCJmaWdzLzIwMjAtMDEtMzFfZ3JvdXBpbmdzLnBuZyIsIGd3b3JsZCwgd2lkdGggPSA3LjIsIGhlaWdodCA9IDQuMykKZ2dzYXZlKCJmaWdzLzIwMjAtMDEtMzFfZ3JvdXBpbmdzLnN2ZyIsIGd3b3JsZCwgd2lkdGggPSA3LjIsIGhlaWdodCA9IDQuMykKYGBgCgoKIyMgRGVzY3JpcHRpdmUgc3RhdGlzdGljcwpQcmVwYXJlIGRhdGEgZnJhbWVzIGZvciBsYXRlciBhbmFseXNlczoKCi0gcmJpbmQgcmVzdWx0cyBvZiByYWNlIHByZWRpY3Rpb25zIGluIGlzY2IgYW5kIFB1Ym1lZAotIHBpdm90IGxvbmcKLSBjb21wdXRlIG1lYW4sIHNkLCBtYXJnaW5hbCBlcnJvcgoKYGBge3J9CmlzY2JfcHVibWVkX290aCA8LSBpc2NiX25hdF9kZiAlPiUKICByZW5hbWUoImpvdXJuYWwiID0gY29uZmVyZW5jZSkgJT4lCiAgc2VsZWN0KHllYXIsIGpvdXJuYWwsIEFmcmljYW46U291dGhBc2lhbiwgcHVibGljYXRpb25fZGF0ZSkgJT4lCiAgbXV0YXRlKAogICAgdHlwZSA9ICJLZXlub3RlIHNwZWFrZXJzL0ZlbGxvd3MiLAogICAgYWRqdXN0ZWRfY2l0YXRpb25zID0gMSwKICAgIHBtaWQgPSAtOTk5OQogICkgJT4lCiAgYmluZF9yb3dzKAogICAgcHVibWVkX25hdF9kZiAlPiUKICAgICAgc2VsZWN0KHBtaWQsIHllYXIsIGpvdXJuYWwsIEFmcmljYW46U291dGhBc2lhbiwgcHVibGljYXRpb25fZGF0ZSwgYWRqdXN0ZWRfY2l0YXRpb25zKSAlPiUKICAgICAgbXV0YXRlKHR5cGUgPSAiUHVibWVkIGF1dGhvcnMiKQogICkgJT4lCiAgbXV0YXRlKE90aGVyQ2F0ZWdvcmllcyA9IFNvdXRoQXNpYW4gKyBIaXNwYW5pYyArIEpld2lzaCArIE11c2xpbSArIE5vcmRpYyArIEdyZWVrICsgQWZyaWNhbikgJT4lCiAgcGl2b3RfbG9uZ2VyKGMoQWZyaWNhbjpTb3V0aEFzaWFuLCBPdGhlckNhdGVnb3JpZXMpLAogICAgbmFtZXNfdG8gPSAicmVnaW9uIiwKICAgIHZhbHVlc190byA9ICJwcm9iYWJpbGl0aWVzIgogICkgJT4lCiAgZmlsdGVyKCFpcy5uYShwcm9iYWJpbGl0aWVzKSkgJT4lCiAgZ3JvdXBfYnkodHlwZSwgeWVhciwgcmVnaW9uKQoKaXNjYl9wdWJtZWRfc3VtX290aCA8LSBpc2NiX3B1Ym1lZF9vdGggJT4lCiAgc3VtbWFyaXNlKAogICAgbWVhbl9wcm9iID0gbWVhbihwcm9iYWJpbGl0aWVzKSwKICAgIHNlX3Byb2IgPSBzZChwcm9iYWJpbGl0aWVzKS9zcXJ0KG4oKSksCiAgICBtZV9wcm9iID0gYWxwaGFfdGhyZXNob2xkICogc2VfcHJvYiwKICAgIC5ncm91cHMgPSAiZHJvcCIKICApCgppc2NiX3B1Ym1lZF9zdW0gPC0gaXNjYl9wdWJtZWRfc3VtX290aCAlPiUKICBmaWx0ZXIocmVnaW9uICE9ICJPdGhlckNhdGVnb3JpZXMiKQpgYGAKCiMjIFByZXBhcmUgZGF0YSBmcmFtZXMgZm9yIGFuYWx5c2lzCgojIyMgQnkgY29uZmVyZW5jZSBrZXlub3Rlcy9mZWxsb3dzCmBgYHtyIGZpZy5oZWlnaHQ9Nn0KaSA8LSAwCmlzY2JfbmF0IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG5fY29uZnMpCgpmb3IgKGNvbmYgaW4gbXlfY29uZnMpIHsKICBpIDwtIGkgKyAxCiAgaXNjYl9uYXRbW2ldXSA8LSBpc2NiX3B1Ym1lZF9vdGggJT4lCiAgICBmaWx0ZXIocmVnaW9uICE9ICJPdGhlckNhdGVnb3JpZXMiLCB0eXBlICE9ICJQdWJtZWQgYXV0aG9ycyIgJiBqb3VybmFsID09IGNvbmYpICU+JQogICAgZ3JvdXBfYnkodHlwZSwgeWVhciwgcmVnaW9uLCBqb3VybmFsKSAlPiUKICAgIHN1bW1hcmlzZShtZWFuX3Byb2IgPSBtZWFuKHByb2JhYmlsaXRpZXMpLCAuZ3JvdXBzID0gImRyb3AiKQp9CmBgYAoKYGBge3J9CnNhdmUobXlfd29ybGQsIGlzY2JfcHVibWVkX290aCwgaXNjYl9uYXQsIGZpbGUgPSAiUmRhdGEvaXNjYi1wdWJtZWRfbmF0LlJkYXRhIikKYGBgCgojIyBGaWd1cmVzIGZvciBwYXBlcgoKIyMjIEZpZ3VyZSA0CgpDb21wYXJlZCB0byB0aGUgbmFtZSBjb2xsZWN0aW9uIG9mIFB1Ym1lZCBhdXRob3JzLCBob25vcmVlcyB3aXRoIENlbHRpYy9FbmdsaXNoIG5hbWVzIGFyZSBvdmVycmVwcmVzZW50ZWQgd2hpbGUgaG9ub3JlZXMgd2l0aCBFYXN0IEFzaWFuIG5hbWVzIGFyZSB1bmRlcnJlcHJlc2VudGVkLgoKYGBge3IgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9OSwgd2FybmluZz1GQUxTRX0KZmlnXzRhIDwtIGlzY2JfcHVibWVkX3N1bSAlPiUKICBmaWx0ZXIoeWVhciA8ICIyMDIwLTAxLTAxIikgJT4lCiAgcmVnaW9uX2JyZWFrZG93bigibWFpbiIsIHJlZ2lvbl9sZXZlbHMsIGZjdF9yZXYodHlwZSkpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMikpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKCmxhcmdlX3JlZ2lvbnMgPC0gYygiQ2VsdGljRW5nbGlzaCIsICJFYXN0QXNpYW4iLCAiRXVyb3BlYW4iLCAiT3RoZXJDYXRlZ29yaWVzIikKIyMgTWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzOgpmaWdfNGIgPC0gaXNjYl9wdWJtZWRfc3VtX290aCAlPiUKICBmaWx0ZXIocmVnaW9uICVpbiUgbGFyZ2VfcmVnaW9ucykgJT4lCiAgcmVjb2RlX3JlZ2lvbigpICU+JQogIGdhbV9hbmRfY2koCiAgICBkZjIgPSBpc2NiX3B1Ym1lZF9vdGggJT4lCiAgICAgIGZpbHRlcihyZWdpb24gJWluJSBsYXJnZV9yZWdpb25zKSAlPiUKICAgICAgcmVjb2RlX3JlZ2lvbigpLAogICAgc3RhcnRfeSA9IHN0YXJ0X3llYXIsIGVuZF95ID0gZW5kX3llYXIKICApICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC44OCwgMC44MyksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigtMC41LCAwLCAwLCAwLCB1bml0ID0gImNtIiksCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNykKICApICsKICBmYWNldF93cmFwKHZhcnMoZmN0X3JlbGV2ZWwocmVnaW9uLCBsYXJnZV9yZWdpb25zKSksIG5yb3cgPSAxKQoKZmlnXzQgPC0gY293cGxvdDo6cGxvdF9ncmlkKGZpZ180YSwgZmlnXzRiLCBsYWJlbHMgPSAiQVVUTyIsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMS4zLCAxKSkKZmlnXzQKZ2dzYXZlKCJmaWdzL3JlZ2lvbl9icmVha2Rvd24ucG5nIiwgZmlnXzQsIHdpZHRoID0gNi43LCBoZWlnaHQgPSA1LjUsIGRwaSA9IDYwMCkKZ2dzYXZlKCJmaWdzL3JlZ2lvbl9icmVha2Rvd24uc3ZnIiwgZmlnXzQsIHdpZHRoID0gNi43LCBoZWlnaHQgPSA1LjUpCmBgYAoKCiMjIEh5cG90aGVzaXMgdGVzdGluZwoKYGBge3J9CmlzY2JfbG0gPC0gaXNjYl9wdWJtZWRfb3RoICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoCiAgICAjIHllYXIgPSBjKHNjYWxlKHllYXIoeWVhcikpKSwKICAgICMgeWVhciA9IGFzLmZhY3Rvcih5ZWFyKSwKICAgIHR5cGUgPSBhcy5mYWN0b3IodHlwZSkgJT4lIHJlbGV2ZWwocmVmID0gIlB1Ym1lZCBhdXRob3JzIikKICApCm1haW5fbG0gPC0gZnVuY3Rpb24ocmVnaW9uaSkgewogIGdsbSh0eXBlIH4geWVhciArIHByb2JhYmlsaXRpZXMsCiAgICBkYXRhID0gaXNjYl9sbSAlPiUKICAgICAgZmlsdGVyKHJlZ2lvbiA9PSByZWdpb25pLCAhaXMubmEocHJvYmFiaWxpdGllcyksIHllYXIoeWVhcikgPj0gMjAwMiksCiAgICBmYW1pbHkgPSAiYmlub21pYWwiCiAgKQp9CgppbnRlX2xtIDwtIGZ1bmN0aW9uKHJlZ2lvbmkpIHsKICBnbG0odHlwZSB+IHllYXIgKiBwcm9iYWJpbGl0aWVzLAogICAgZGF0YSA9IGlzY2JfbG0gJT4lCiAgICAgIGZpbHRlcihyZWdpb24gPT0gcmVnaW9uaSwgIWlzLm5hKHByb2JhYmlsaXRpZXMpLCB5ZWFyKHllYXIpID49IDIwMDIpLAogICAgZmFtaWx5ID0gImJpbm9taWFsIgogICkKfQoKbWFpbl9saXN0IDwtIGxhcHBseShsYXJnZV9yZWdpb25zLCBtYWluX2xtKQpuYW1lcyhtYWluX2xpc3QpIDwtIGxhcmdlX3JlZ2lvbnMKbGFwcGx5KG1haW5fbGlzdCwgYnJvb206OnRpZHkpCgppbnRlX2xpc3QgPC0gbGFwcGx5KGxhcmdlX3JlZ2lvbnMsIGludGVfbG0pCmxhcHBseShpbnRlX2xpc3QsIGJyb29tOjp0aWR5KQpmb3IgKGkgaW4gMTo0KSB7CiAgcHJpbnQoYW5vdmEobWFpbl9saXN0W1tpXV0sIGludGVfbGlzdFtbaV1dLCB0ZXN0ID0gIkNoaXNxIikpCn0KYGBgCkludGVyYWN0aW9uIHRlcm1zIGRvIG5vdCBwcmVkaWN0IGB0eXBlYCBvdmVyIGFuZCBhYm92ZSB0aGUgbWFpbiBlZmZlY3Qgb2YgbmFtZSBvcmlnaW4gcHJvYmFiaWxpdHkgYW5kIHllYXIgKF9wXyA+IDAuMDEpLgoKYGBge3IgZWNobyA9IEZ9CmdldF9wIDwtIGZ1bmN0aW9uKGksIGNvbHUpIHsKICBicm9vbTo6dGlkeShtYWluX2xpc3RbW2ldXSkgJT4lCiAgICBmaWx0ZXIodGVybSA9PSAicHJvYmFiaWxpdGllcyIpICU+JQogICAgcHVsbChjb2x1KQp9CgpwcmludF9wIDwtIGZ1bmN0aW9uKHgpIHNwcmludGYoIiUwLjVnIiwgeCkKYGBgCgojIyBDb25jbHVzaW9uCkEgQ2VsdGljL0VuZ2xpc2ggbmFtZSBoYXMgYHIgZXhwKGdldF9wKDEsICdlc3RpbWF0ZScpKWAgdGhlIG9kZHMgb2YgYmVpbmcgc2VsZWN0ZWQgYXMgYW4gaG9ub3JlZSwgc2lnbmlmaWNhbnRseSBoaWdoZXIgY29tcGFyZWQgdG8gb3RoZXIgbmFtZXMgKCRcYmV0YV9cdGV4dHJte0NlbHRpYy9FbmdsaXNofSA9JCBgciBwcmludF9wKGdldF9wKDEsICdlc3RpbWF0ZScpKWAsIF9QXyA9IGByIHByaW50X3AoZ2V0X3AoMSwgJ3AudmFsdWUnKSlgKS4KQW4gRWFzdCBBc2lhbiBuYW1lIGhhcyBgciBleHAoZ2V0X3AoMiwgJ2VzdGltYXRlJykpYCB0aGUgb2RkcyBvZiBiZWluZyBzZWxlY3RlZCBhcyBhbiBob25vcmVlLCBzaWduaWZpY2FudGx5IGxvd2VyIHRoYW4gdG8gb3RoZXIgbmFtZXMgKCRcYmV0YV9cdGV4dHJte0Vhc3QgQXNpYW59ID0kIGByIHByaW50X3AoZ2V0X3AoMiwgJ2VzdGltYXRlJykpYCwgX1BfID0gYHIgcHJpbnRfcChnZXRfcCgyLCAncC52YWx1ZScpKWApLgpUaGUgdHdvIGdyb3VwcyBvZiBzY2llbnRpc3RzIGRpZCBub3QgaGF2ZSBhIHNpZ25pZmljYW50IGFzc29jaWF0aW9uIHdpdGggbmFtZXMgcHJlZGljdGVkIHRvIGJlIEV1cm9wZWFuIChfUF8gPSBgciBwcmludF9wKGdldF9wKDMsICdwLnZhbHVlJykpYCkgb3IgaW4gT3RoZXIgY2F0ZWdvcmllcyAoX1BfID0gYHIgcHJpbnRfcChnZXRfcCg0LCAncC52YWx1ZScpKWApLgoKCiMjIEFsdGVybmF0aXZlIGFwcHJvYWNoCl9TaW5jZXJlIHRoYW5rcyB0byB0aGUgcmV2aWV3ZXJzLCBCeXJvbiBTbWl0aCBhbmQgS2F0aWUgUG9sbGFyZCwgZm9yIHRoZWlyIGRldGFpbGVkIHN1Z2dlc3Rpb24gd2l0aCBjb2RlLl8KClRoZSBxdWVzdGlvbiBvZiB3aGF0IHVuaXQgb25lIHNob3VsZCB1c2UgdG8gcGVyZm9ybSB0aGlzIHR5cGUgb2YgYW5hbHlzZXMgaXMgYSBkaWZmaWN1bHQgb25lLgpXZSBwcmVzZW50IGhlcmUgYW4gYWx0ZXJuYXRpdmUgYW5hbHlzaXMgdGhhdCB0cmVhdHMgX25hbWVzXyBhcyB1bml0cyBpbnN0ZWFkIG9mIF9ob25vcnNfIGFuZCBfYXV0aG9yc2hpcHNfLgpXZSBjYXV0aW9uIHRoYXQgdGhpcyBhcHByb2FjaCBkb2VzIG5vdCBkaXN0aW5ndWlzaCBzY2llbnRpc3RzIHdobyB3ZXJlIGhvbm9yZWQgNCB0aW1lcyB2cy4gb25lIHRpbWUKYW5kIGhlbmNlIG1heSB5aWVsZCBhIGNvbnNlcnZhdGl2ZSBlc3RpbWF0ZSBvZiBkaXNwYXJpdHkuCkZ1cnRoZXIsIGRpZmZlcmVudCBhdXRob3JzIG1heSBoYXZlIHRoZSBzYW1lIG5hbWVzLCAKYW5kIHRvIHN1bSBgYWRqdXN0ZWRfY2l0YXRpb25zYCBhY3Jvc3MgdGhlbSBtYXkgbm90IGJlIG9wdGltYWwuCgpOb25ldGhlbGVzcywgdGhlIGZpbmRpbmcgaGVyZSBpcyBjb25zaXN0ZW50IHdpdGggd2hhdCB3ZSBoYXZlIHNlZW4gYWJvdmUKd2hlcmUgRWFzdCBBc2lhbiBuYW1lcyBhcmUgdW5kZXJyZXByZXNlbnRlZCBpbiB0aGUgaG9ub3JlZSBncm91cC4KCmBgYHtyfQoKa2V5bm90ZXNfcG9zdF8yMDAyIDwtIGtleW5vdGVzICU+JQogIGZpbHRlcih5ZWFyKHllYXIpID49IDIwMDIpICU+JQogIHNlcGFyYXRlX3Jvd3MoYWZmbGNvdW50cmllcywgc2VwID0gIiwiKSAlPiUKICBmaWx0ZXIoYWZmbGNvdW50cmllcyA9PSAiVW5pdGVkIFN0YXRlcyIpICU+JQogIGdyb3VwX2J5KGZvcmVfbmFtZV9zaW1wbGUsIGxhc3RfbmFtZV9zaW1wbGUpICU+JQogIHN1bW1hcmlzZV9hdCgieWVhciIsIG5fZGlzdGluY3QsIG5hLnJtID0gVCkKCiMgbmF0aW9uYWxpemVfZGYgd2FzIG5vdCB1bmlxdWUsIHNvIHRoZSBsZWZ0IGpvaW4gdG8gY29ycl9hdXRob3JzIHJlc3VsdGVkCiMgaW4gKG1vc3RseSkgZHVwbGljYXRlIHJvd3MuCiMgRklYTUU6IEkgd2FzIGdldHRpbmcgb2NjYXNpb25hbCBjcmFzaGVzIG9uIHRoaXMgbGluZSwgYW5kIGl0J3Mgc2xvdy4KIyBUUkFORzogZml4ZWQgb24gSnVuZSAzLCAyMDIxIHVzaW5nIGRpc3RpbmN0KCkuCiMgQWxzbywgdGhlIGR1cGxpY2F0aW9uIHdhcyBpbnRlbnRpb25hbC4KIyBQbGVhc2Ugc2VlIG91ciBleHRlbnNpdmUgZGlzY3Vzc2lvbiBvbiB0aGUgbWVyZ2Uvam9pbiBvbiBmdWxsIG5hbWVzIHZzCiMgZm9yZV9uYW1lIGFuZCBsYXN0X25hbWUgaGVyZToKIyA8aHR0cHM6Ly9naXRodWIuY29tL2dyZWVuZWxhYi9pc2NiLWRpdmVyc2l0eS9pc3N1ZXMvNj4KCmRpc3RpbmN0X25hdGlvbmFsaXplX2RmIDwtIG5hdGlvbmFsaXplX2RmICU+JQogIGRpc3RpbmN0KGZvcmVfbmFtZV9zaW1wbGUsIGxhc3RfbmFtZV9zaW1wbGUsIC5rZWVwX2FsbCA9IFRSVUUpCgojIENhbGN1bGF0ZSBzdW0gb2YgYWRqdXN0ZWQgY2l0YXRpb25zIGZvciBhbGwgcHVibGljYXRpb25zIGZvciBhIGZpcnN0LW5hbWUvCiMgbGFzdC1uYW1lIHBhaXIgaW4gZGIgc2luY2UgMjAwMgojIHdoZXJlIHRoZSBhdXRob3IgY291bnRyaWVzIGluY2x1ZGUgVVMuCmF1dGhvcnMgPC0gY29ycl9hdXRob3JzICU+JQogIGZpbHRlcih5ZWFyKHllYXIpID49IDIwMDIpICU+JQogIHNlcGFyYXRlX3Jvd3MoY291bnRyaWVzLCBzZXAgPSAiLCIpICU+JQogIGZpbHRlcihjb3VudHJpZXMgPT0gIlVTIikgJT4lCiAgZ3JvdXBfYnkoZm9yZV9uYW1lX3NpbXBsZSwgbGFzdF9uYW1lX3NpbXBsZSkgJT4lCiAgc3VtbWFyaXNlX2F0KHZhcnMoYWRqdXN0ZWRfY2l0YXRpb25zKSwgc3VtLCBuYS5ybSA9IFQpICU+JQogIGxlZnRfam9pbigKICAgIGtleW5vdGVzX3Bvc3RfMjAwMltjKCJmb3JlX25hbWVfc2ltcGxlIiwgImxhc3RfbmFtZV9zaW1wbGUiLCAieWVhciIpXSwKICAgIGJ5ID0gYygiZm9yZV9uYW1lX3NpbXBsZSIsICJsYXN0X25hbWVfc2ltcGxlIikKICApICU+JQogIGxlZnRfam9pbihkaXN0aW5jdF9uYXRpb25hbGl6ZV9kZiwgYnkgPSBjKCJmb3JlX25hbWVfc2ltcGxlIiwgImxhc3RfbmFtZV9zaW1wbGUiKSkgJT4lCiAgbXV0YXRlKE90aGVyQ2F0ZWdvcmllcyA9IFNvdXRoQXNpYW4gKyBIaXNwYW5pYyArIEpld2lzaCArIE11c2xpbSArIE5vcmRpYyArIEdyZWVrICsgQWZyaWNhbikKCmZvciAobGFyZ2VfcmVnaW9uIGluIGxhcmdlX3JlZ2lvbnMpIHsKICBnbG0oCiAgICBhcy5mb3JtdWxhKHBhc3RlKCJob25vcmVlIH4gYWRqdXN0ZWRfY2l0YXRpb25zICsiLCBsYXJnZV9yZWdpb24pKSwKICAgIGRhdGEgPSBhdXRob3JzICU+JSBtdXRhdGUoaG9ub3JlZSA9ICFpcy5uYSh5ZWFyKSksCiAgICBmYW1pbHkgPSAiYmlub21pYWwiLAogICAgY29udHJvbCA9IGxpc3QoZXBzaWxvbiA9IDFlLTEyLCBtYXhpdCA9IDU1LCB0cmFjZSA9IEZBTFNFKQogICkgJT4lCiAgICBicm9vbTo6dGlkeSgpICU+JQogICAgcHJpbnQoKQp9CmBgYAoKPCEtLSBXZSBhcmd1ZSB0aGF0IGhvbm9ycyBhbmQgYXV0aG9yc2hpcHMgYXJlIHRoZSBhcHByb3ByaWF0ZSB1bml0cy4gLS0+CjwhLS0gQWx0aG91Z2ggdGhpcyBhcHByb2FjaCBtYXkgbm90IHNhdGlzZnkgdGhlIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseSBkaXN0cmlidXRlZCBhc3N1bXB0aW9uIC0tPgoKPCEtLSBob25vciB2cyBub3QgaG9ub3JlZC4gLS0+CjwhLS0gQnV0IHRoZW4gdGhpcyBpcyBjb25zaWRlcmluZyBzY2llbnRpc3RzIHdobyBoYXZlIDQgcm93cyBvZiBob25vcmVlcyBhcyBvbmUgIC0tPgo8IS0tIElzIHRoaXMgZmFpcj8gLS0+CjwhLS0gMTk1IHJvd3MvaG9ub3JzIG9mIGtleW5vdGVzIHBvc3QgMjAwMiB0byAxNDUgbmFtZXMvc2NpZW50aXN0cy4gLS0+CgojIyBUaW1lIGxhZwoKSW4gdGhpcyBzZWN0aW9uLCB3ZSBzaG93IHRoYXQgYSAxMC15ZWFyIGxhZyBtb2RlbCByZXN1bHRzIGluIGEgc2ltaWxhciByZXN1bHQgZm9yIEVhc3QgQXNpYW4gc2NpZW50aXN0cycgbmFtZXMsCmV2ZW4gdGhvdWdoIHRoZSBlZmZlY3Qgc2l6ZSBpcyBsZXNzIHN0cmlraW5nLgpGb3IgZXhhbXBsZSwgaWYgd2UgYXNzdW1lIHRoYXQgaG9ub3JzIGFjY3J1ZSAxMCB5ZWFycyBhZnRlciB0aGVpciBtb3N0IHByb2xpZmljIHllYXIgd2l0aCByZXNwZWN0IHRvIGF1dGhvcnNoaXBzLCAKdGhlIHByb3BvcnRpb24gb2YgaG9ub3IgYXNzb2NpYXRlZCB3aXRoIEVhc3QgQXNpYW4gbmFtZSBvcmlnaW5zIGluIDIwMTkgaXMgc3RpbGwgc3Vic3RhbnRpYWxseSBsZXNzIHRoYW4gdGhlIHByb3BvcnRpb24gb2Ygc2VuaW9yIGF1dGhvcnNoaXBzIGFzc29jaWF0ZWQgd2l0aCBFYXN0IEFzaWFuIG5hbWVzIGluIDIwMDkuCgpgYGB7cn0KeWVhcl9sYWcgPC0gcGVyaW9kKDEwLCAieWVhcnMiKQppc2NiX3B1Ym1lZF9vdGhfbGFnIDwtIGlzY2JfbmF0X2RmICU+JQogIHJlbmFtZSgiam91cm5hbCIgPSBjb25mZXJlbmNlKSAlPiUKICBzZWxlY3QoeWVhciwgam91cm5hbCwgQWZyaWNhbjpTb3V0aEFzaWFuLCBwdWJsaWNhdGlvbl9kYXRlKSAlPiUKICBtdXRhdGUoCiAgICB0eXBlID0gIktleW5vdGUgc3BlYWtlcnMvRmVsbG93cyIsCiAgICBhZGp1c3RlZF9jaXRhdGlvbnMgPSAxLAogICAgcG1pZCA9IC05OTk5CiAgKSAlPiUKICBiaW5kX3Jvd3MoCiAgICBwdWJtZWRfbmF0X2RmICU+JQogICAgICBzZWxlY3QocG1pZCwgeWVhciwgam91cm5hbCwgQWZyaWNhbjpTb3V0aEFzaWFuLCBwdWJsaWNhdGlvbl9kYXRlLCBhZGp1c3RlZF9jaXRhdGlvbnMpICU+JQogICAgICBtdXRhdGUodHlwZSA9ICJQdWJtZWQgYXV0aG9ycyIsIHllYXIgPSB5ZWFyICsgeWVhcl9sYWcpCiAgKSAlPiUKICBtdXRhdGUoT3RoZXJDYXRlZ29yaWVzID0gU291dGhBc2lhbiArIEhpc3BhbmljICsgSmV3aXNoICsgTXVzbGltICsgTm9yZGljICsgR3JlZWsgKyBBZnJpY2FuKSAlPiUKICBwaXZvdF9sb25nZXIoYyhBZnJpY2FuOlNvdXRoQXNpYW4sIE90aGVyQ2F0ZWdvcmllcyksCiAgICBuYW1lc190byA9ICJyZWdpb24iLAogICAgdmFsdWVzX3RvID0gInByb2JhYmlsaXRpZXMiCiAgKSAlPiUKICBmaWx0ZXIoIWlzLm5hKHByb2JhYmlsaXRpZXMpLCB5ZWFyKHllYXIpID49IDIwMDIpICU+JQogIGdyb3VwX2J5KHR5cGUsIHllYXIsIHJlZ2lvbikgCgppc2NiX2xtX2xhZyA8LSBpc2NiX3B1Ym1lZF9vdGhfbGFnICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUodHlwZSA9IGFzLmZhY3Rvcih0eXBlKSAlPiUgcmVsZXZlbChyZWYgPSAiUHVibWVkIGF1dGhvcnMiKSkKCm1haW5fbG0gPC0gZnVuY3Rpb24ocmVnaW9uaSkgewogIGdsbSh0eXBlIH4geWVhciArIHByb2JhYmlsaXRpZXMsCiAgICBkYXRhID0gaXNjYl9sbV9sYWcgJT4lCiAgICAgIGZpbHRlcihyZWdpb24gPT0gcmVnaW9uaSwgIWlzLm5hKHByb2JhYmlsaXRpZXMpKSwKICAgIGZhbWlseSA9ICJiaW5vbWlhbCIKICApCn0KCm1haW5fbGlzdCA8LSBsYXBwbHkobGFyZ2VfcmVnaW9ucywgbWFpbl9sbSkKbmFtZXMobWFpbl9saXN0KSA8LSBsYXJnZV9yZWdpb25zCmxhcHBseShtYWluX2xpc3QsIGJyb29tOjp0aWR5KQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0UsIGV2YWwgPSBGQUxTRX0KY2hlY2tkZiA8LSBpc2NiX2xtICU+JQogIGZpbHRlcigKICAgIHllYXIoeWVhcikgPT0gMjAxMCwKICAgIGFkanVzdGVkX2NpdGF0aW9ucyA+IDMuMSwgCiAgICBhZGp1c3RlZF9jaXRhdGlvbnMgPCAzLjMyLCAKICAgIHJlZ2lvbiA9PSAiRWFzdEFzaWFuIiwgCiAgICBwcm9iYWJpbGl0aWVzID4gMC41CiAgKQpgYGAKCgojIyBTdXBwbGVtZW50YXJ5IEZpZ3VyZSBTNSB7I3N1cF9maWdfczV9Ckl0J3MgZGlmZmljdWx0IHRvIGNvbWUgdG8gYSBjb25jbHVzaW9uIGZvciBvdGhlciByZWdpb25zIHdpdGggc28gZmV3IGRhdGEgcG9pbnRzIGFuZCB0aGUgaW1wZXJmZWN0IGFjY3VyYWN5IG9mIG91ciBwcmVkaWN0aW9uLgpUaGVyZSBzZWVtcyB0byBiZSBsaXR0bGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBwcm9wb3J0aW9uIG9mIGtleW5vdGUgc3BlYWtlcnMgb2YgQWZyaWNhbiwgQXJhYmljLCBTb3V0aCBBc2lhbiBhbmQgSGlzcGFuaWMgb3JpZ2luIHRoYW4gdGhvc2UgaW4gdGhlIGZpZWxkLgpIb3dldmVyLCBqdXN0IGJlY2F1c2UgYSBuYXRpb25hbGl0eSBpc24ndCB1bmRlcnJlcHJlc2VudGVkIGFnYWluc3QgdGhlIGZpZWxkIGRvZXNuJ3QgbWVhbiBzY2llbnRpc3RzIGZyb20gdGhhdCBuYXRpb25hbGl0eSBhcmUgYXBwcm9wcmlhdGVseSByZXByZXNlbnRlZC4KCmBgYHtyIGZpZy5oZWlnaHQ9Niwgd2FybmluZz1GQUxTRX0KIyBkZjIgPC0gaXNjYl9wdWJtZWRfb3RoICU+JQojICAgZmlsdGVyKHJlZ2lvbiAhPSAiT3RoZXJDYXRlZ29yaWVzIikgJT4lCiMgICByZWNvZGVfcmVnaW9uKCkKIyAKIyBmaWdfczUgPC0gaXNjYl9wdWJtZWRfc3VtICU+JQojICAgcmVjb2RlX3JlZ2lvbigpICU+JQojICAgZ2FtX2FuZF9jaSgKIyAgICAgZGYyID0gZGYyLAojICAgICBzdGFydF95ID0gc3RhcnRfeWVhciwgZW5kX3kgPSBlbmRfeWVhcgojICAgKSArCiMgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSBjKDAuOCwgMC4xKSkgKwojICAgZmFjZXRfd3JhcCh2YXJzKGZjdF9yZWxldmVsKHJlZ2lvbiwgcmVnaW9uX2xldmVscykpLCBuY29sID0gMykKIyBmaWdfczUKIyBnZ3NhdmUoImZpZ3MvZmlnX3M1LnBuZyIsIGZpZ19zNSwgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQojIGdnc2F2ZSgiZmlncy9maWdfczUuc3ZnIiwgZmlnX3M1LCB3aWR0aCA9IDYsIGhlaWdodCA9IDYpCmBgYAoKCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAo=