knitr::opts_chunk$set(cache = TRUE, dev = c("png", "pdf"))
library(here)
source(here("src", "model_quadratic_grampians_internal_validation.R"))

SAMPLING FOR MODEL 'continuous' NOW (CHAIN 1).
Chain 1: 
Chain 1: Gradient evaluation took 0.000645 seconds
Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 6.45 seconds.
Chain 1: Adjust your expectations accordingly!
Chain 1: 
Chain 1: 
Chain 1: Iteration:   1 / 1000 [  0%]  (Warmup)
Chain 1: Iteration: 100 / 1000 [ 10%]  (Warmup)
Chain 1: Iteration: 200 / 1000 [ 20%]  (Warmup)
Chain 1: Iteration: 300 / 1000 [ 30%]  (Warmup)
Chain 1: Iteration: 400 / 1000 [ 40%]  (Warmup)
Chain 1: Iteration: 500 / 1000 [ 50%]  (Warmup)
Chain 1: Iteration: 501 / 1000 [ 50%]  (Sampling)
Chain 1: Iteration: 600 / 1000 [ 60%]  (Sampling)
Chain 1: Iteration: 700 / 1000 [ 70%]  (Sampling)
Chain 1: Iteration: 800 / 1000 [ 80%]  (Sampling)
Chain 1: Iteration: 900 / 1000 [ 90%]  (Sampling)
Chain 1: Iteration: 1000 / 1000 [100%]  (Sampling)
Chain 1: 
Chain 1:  Elapsed Time: 21.7004 seconds (Warm-up)
Chain 1:                8.58763 seconds (Sampling)
Chain 1:                30.2881 seconds (Total)
Chain 1: 

SAMPLING FOR MODEL 'continuous' NOW (CHAIN 2).
Chain 2: 
Chain 2: Gradient evaluation took 0.000918 seconds
Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 9.18 seconds.
Chain 2: Adjust your expectations accordingly!
Chain 2: 
Chain 2: 
Chain 2: Iteration:   1 / 1000 [  0%]  (Warmup)
Chain 2: Iteration: 100 / 1000 [ 10%]  (Warmup)
Chain 2: Iteration: 200 / 1000 [ 20%]  (Warmup)
Chain 2: Iteration: 300 / 1000 [ 30%]  (Warmup)
Chain 2: Iteration: 400 / 1000 [ 40%]  (Warmup)
Chain 2: Iteration: 500 / 1000 [ 50%]  (Warmup)
Chain 2: Iteration: 501 / 1000 [ 50%]  (Sampling)
Chain 2: Iteration: 600 / 1000 [ 60%]  (Sampling)
Chain 2: Iteration: 700 / 1000 [ 70%]  (Sampling)
Chain 2: Iteration: 800 / 1000 [ 80%]  (Sampling)
Chain 2: Iteration: 900 / 1000 [ 90%]  (Sampling)
Chain 2: Iteration: 1000 / 1000 [100%]  (Sampling)
Chain 2: 
Chain 2:  Elapsed Time: 26.6919 seconds (Warm-up)
Chain 2:                8.89649 seconds (Sampling)
Chain 2:                35.5884 seconds (Total)
Chain 2: 

SAMPLING FOR MODEL 'continuous' NOW (CHAIN 3).
Chain 3: 
Chain 3: Gradient evaluation took 0.000529 seconds
Chain 3: 1000 transitions using 10 leapfrog steps per transition would take 5.29 seconds.
Chain 3: Adjust your expectations accordingly!
Chain 3: 
Chain 3: 
Chain 3: Iteration:   1 / 1000 [  0%]  (Warmup)
Chain 3: Iteration: 100 / 1000 [ 10%]  (Warmup)
Chain 3: Iteration: 200 / 1000 [ 20%]  (Warmup)
Chain 3: Iteration: 300 / 1000 [ 30%]  (Warmup)
Chain 3: Iteration: 400 / 1000 [ 40%]  (Warmup)
Chain 3: Iteration: 500 / 1000 [ 50%]  (Warmup)
Chain 3: Iteration: 501 / 1000 [ 50%]  (Sampling)
Chain 3: Iteration: 600 / 1000 [ 60%]  (Sampling)
Chain 3: Iteration: 700 / 1000 [ 70%]  (Sampling)
Chain 3: Iteration: 800 / 1000 [ 80%]  (Sampling)
Chain 3: Iteration: 900 / 1000 [ 90%]  (Sampling)
Chain 3: Iteration: 1000 / 1000 [100%]  (Sampling)
Chain 3: 
Chain 3:  Elapsed Time: 29.9949 seconds (Warm-up)
Chain 3:                9.73212 seconds (Sampling)
Chain 3:                39.7271 seconds (Total)
Chain 3: 
library(arm)
library(forcats)
library(ggplot2)
library(gridExtra)
library(tidyr)

vars <- c("mlq", "mlq2", "twi", "twi2", "r1k", "r1k2", "tn", "tn2")
taxa <- unique(mds$taxon)
taxa_x_region <- unique(mds[, c("taxon", "ibra_subregion")])
traits <- sapply(
  taxa,
  function(x) unlist(unique(mds[mds$taxon == x, c("sla", "sm", "mh")]))
)

Calculate the responses of each species in each region using single-species/single-region glms.

observed_responses <- mapply(
  function(taxoni, region) {
    df <- subset(mds, taxon == taxoni & ibra_subregion == region)
    model <- bayesglm(
      formula(sprintf("y ~ %s", paste(vars, collapse = " + "))),
      binomial, df, prior.scale = 1, prior.df = Inf
    )
    data.frame(
      Taxon = taxoni, Region = region, Var = vars,
      summary(model)$coefficients[vars, 1:2]
    )
  },
  taxa_x_region[, 1], taxa_x_region[, 2],
  SIMPLIFY = FALSE
)

observed_responses <- do.call(rbind, observed_responses)

Calculate the predicted responses of each species in each region based on the Grampians model and their trait values.

nsims <- 1000
sims <- fixef(sim(model_grampians, nsims))

predicted_responses <- function(taxon) {
  ans <- vapply(
    vars, function(x) {
      rowSums(
        sweep(sims[, grep(x, colnames(sims))], 2, c(1, traits[, taxon]), "*")
      )
    },
    numeric(nsims)
  )
  t(
    apply(
      ans, 2, function(x) c(Prediction = mean(x), "Predicted..Error" = sd(x))
    )
  )
}

predicted_responses <- do.call(
  rbind, sapply(taxa, predicted_responses, simplify = FALSE)[taxa_x_region[, 1]]
)

responses <- cbind(observed_responses, predicted_responses)

responses <- merge(
  responses, subset(perf, !random_effect),
  by.x = c("Taxon", "Region"), by.y = c("taxon", "ibra_subregion")
)

plot_regions <- c(
  "Snowy Mountains", "Jervis", "Victorian Alps", "Strzelecki Ranges",
  "Greater Grampians"
)

responses <- rbind(responses, grampians_responses)

responses$Region <- forcats::fct_relevel(responses$Region, plot_regions)

scatters <- ggplot(
    subset(
      responses[order(responses$AUC),],
      Var %in% c("mlq", "twi") & Region %in% plot_regions
    )
  ) +
  xlim(-2, 6) +
  ylim(-7, 3) +
  geom_hline(yintercept = 0) +
  geom_vline(xintercept = 0) +
  geom_abline(slope = 1, intercept = 0, lty = 2) +
  aes(Estimate, Prediction) +
  geom_point(aes(color = AUC), size = 2) +
  scale_color_gradient(low = "white", high = "black") +
  facet_grid(
    Region ~ Var,
    labeller = labeller(
      Var = as_labeller(
        c(
          mlq  = "Moisture Lowest Quarter",
          twi  = "Topographic Wetness"
        )
      )
    )
  ) +
  theme_bw() +
  theme(
    legend.position = c(0.35, .89),
    legend.key.width = unit(.07, "inches"),
    legend.key.height = unit(.09, "inches"),
    legend.background = element_rect(fill = "transparent"),
    legend.title = element_text(size = 8),
    legend.text = element_text(size = 6),
    strip.background = element_blank(),
    strip.text.y = element_blank()
  )

perf$ibra_subregion <- forcats::fct_relevel(perf$ibra_subregion, plot_regions)

hist_data <- subset(perf, ibra_subregion %in% plot_regions & !random_effect)
med_data <- with(hist_data, tapply(AUC, ibra_subregion, median))
med_data <- as.data.frame(med_data)
med_data <- na.omit(med_data)
med_data$ibra_subregion <- row.names(med_data)
med_data$ibra_subregion <- fct_relevel(med_data$ibra_subregion, plot_regions)

hists <- ggplot(hist_data) +
  aes(AUC) +
  geom_histogram() +
  facet_grid(ibra_subregion ~ random_effect) +
  geom_vline(aes(xintercept = med_data), med_data, col = "grey", size = 2) +
  xlab("AUC") +
  ylab("No. of taxa") +
  theme_bw() +
  theme(
    strip.background = element_blank(),
    strip.text.x = element_text(color = "transparent")
  )

Plot of the observed vs. predicted responses for each covariate grey-coded by region.

grid.arrange(scatters, hists, ncol = 2, widths = c(.45, .55))

Plot of the observed vs. predicted responses to TWI grey-coded by trait values.

ggplot(
  merge(
    subset(
      responses,
      Var == "twi" & Region %in% plot_regions[c(1, 3, 5)]
    ),
    gather(
      unique(
        rbind(
          mdg[c("taxon", "ibra_subregion", "sla", "sm")],
          mds[c("taxon", "ibra_subregion", "sla", "sm")]
        )
      ),
      "trait",
      "value",
      sla, sm
    ),
    by.x = c("Taxon", "Region"), by.y = c("taxon", "ibra_subregion")
  )
) +
xlim(-3, 3) +
ylim(-3, 3) +
geom_hline(yintercept = 0) +
geom_vline(xintercept = 0) +
geom_abline(slope = 1, intercept = 0, lty = 2) +
aes(Estimate, Prediction) +
geom_point(aes(color = value), size = 2) +
scale_color_gradient(
  name = "SD", low = "white", high = "black"
) +
facet_grid(
  Region ~ trait,
  labeller = labeller(
    trait = as_labeller(
      c(
        sla = "Specific Leaf Area",
        sm  = "Seed Mass"
      )
    )
  )
) +
theme_bw() +
theme(
  legend.position = c(0.07, .91),
  legend.key.width = unit(.07, "inches"),
  legend.key.height = unit(.09, "inches"),
  legend.background = element_rect(fill = "transparent"),
  legend.title = element_text(size = 8),
  legend.text = element_text(size = 6),
  strip.background = element_blank()
)

# Calculate the correlation between predicted vs observed response coefficients
# for each covariate among all taxa within a region.
# calccor
# correlations <- lapply(
#   vars,
#   function(var) {
#     ans <- sapply(
#       rgn_names,
#       function(region) {
#         ss <- subset(responses, Region == region & Var == var)
#         cor(ss$Estimate, ss$Prediction)
#       }
#     )
#     data.frame(
#       var2 = var, region = names(ans), cor = ans, stringsAsFactors = FALSE,
#       row.names = NULL
#     )
#   }
# )
#
# correlations <- do.call(rbind, correlations)
#
# correlations <- data.frame(
#   correlations,
#   var = gsub("2", "", correlations$var),
#   KLD = kldists[correlations$region],
#   GD = dists[correlations$region],
#   stringsAsFactors = FALSE
# )
#
# correlations <- merge(correlations, kldists_univariate)
#
# Plot the correlations vs. the KL distance of the regions environment from the
# Grampians.
# plotcors1, fig.width=11
# ggplot(correlations) +
# aes(KLD, cor) +
# geom_point() +
# geom_smooth(method = "lm") +
# xlim(0, 35) +
# ylim(-1, 1) +
# facet_wrap("var2", 2, dir = "v")
#
# Plot the correlations vs. the univariate KL distance of the regions
# environment from the Grampians.
# plotcors2, fig.width=11
# ggplot(correlations) +
# aes(kldist_var, cor) +
# geom_point() +
# geom_smooth(method = "lm") +
# ylim(-1, 1) +
# facet_wrap("var2", 2, scales = "free_x", dir = "v")
#
# Plot the correlations vs. the geographic (centroid) distance of the region
# to the Grampians.
# plotcors3, fig.width=11
# ggplot(correlations) +
# aes(GD, cor) +
# geom_point() +
# geom_smooth(method = "lm") +
# xlim(0, 1000) +
# ylim(-1, 1) +
# facet_wrap("var2", 2, dir = "v")
IycgLS0tCiMnIHRpdGxlOiAiVmFsaWRhdGluZyB0aGUgc3BlY2llcyByZXNwb25zZXMgZm9yIGdyYW1waWFucyB0cmFpdC1lbnZpcm9ubWVudAojJyAgIG1vZGVsIHdpdGggcXVhZHJhdGljIHJlbGF0aW9uc2hpcHMiCiMnIGF1dGhvcjogIldpbGxpYW0gSy4gTW9ycmlzIgojJyBkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCiMnIG91dHB1dDoKIycgICBybWFya2Rvd246Omh0bWxfbm90ZWJvb2s6CiMnICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKIycgLS0tCgojKyBzZXR1cCwgbWVzc2FnZT1GQUxTRSwgZmlnLmtlZXA9Im5vbmUiLCBmaWcuc2hvdz0iaGlkZSIKa25pdHI6Om9wdHNfY2h1bmskc2V0KGNhY2hlID0gVFJVRSwgZGV2ID0gYygicG5nIiwgInBkZiIpKQpsaWJyYXJ5KGhlcmUpCnNvdXJjZShoZXJlKCJzcmMiLCAibW9kZWxfcXVhZHJhdGljX2dyYW1waWFuc19pbnRlcm5hbF92YWxpZGF0aW9uLlIiKSkKbGlicmFyeShhcm0pCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeSh0aWR5cikKCnZhcnMgPC0gYygibWxxIiwgIm1scTIiLCAidHdpIiwgInR3aTIiLCAicjFrIiwgInIxazIiLCAidG4iLCAidG4yIikKdGF4YSA8LSB1bmlxdWUobWRzJHRheG9uKQp0YXhhX3hfcmVnaW9uIDwtIHVuaXF1ZShtZHNbLCBjKCJ0YXhvbiIsICJpYnJhX3N1YnJlZ2lvbiIpXSkKdHJhaXRzIDwtIHNhcHBseSgKICB0YXhhLAogIGZ1bmN0aW9uKHgpIHVubGlzdCh1bmlxdWUobWRzW21kcyR0YXhvbiA9PSB4LCBjKCJzbGEiLCAic20iLCAibWgiKV0pKQopCgojJyBDYWxjdWxhdGUgdGhlIHJlc3BvbnNlcyBvZiBlYWNoIHNwZWNpZXMgaW4gZWFjaCByZWdpb24gdXNpbmcKIycgc2luZ2xlLXNwZWNpZXMvc2luZ2xlLXJlZ2lvbiBnbG1zLgojKyBvYnNyZXNwCm9ic2VydmVkX3Jlc3BvbnNlcyA8LSBtYXBwbHkoCiAgZnVuY3Rpb24odGF4b25pLCByZWdpb24pIHsKICAgIGRmIDwtIHN1YnNldChtZHMsIHRheG9uID09IHRheG9uaSAmIGlicmFfc3VicmVnaW9uID09IHJlZ2lvbikKICAgIG1vZGVsIDwtIGJheWVzZ2xtKAogICAgICBmb3JtdWxhKHNwcmludGYoInkgfiAlcyIsIHBhc3RlKHZhcnMsIGNvbGxhcHNlID0gIiArICIpKSksCiAgICAgIGJpbm9taWFsLCBkZiwgcHJpb3Iuc2NhbGUgPSAxLCBwcmlvci5kZiA9IEluZgogICAgKQogICAgZGF0YS5mcmFtZSgKICAgICAgVGF4b24gPSB0YXhvbmksIFJlZ2lvbiA9IHJlZ2lvbiwgVmFyID0gdmFycywKICAgICAgc3VtbWFyeShtb2RlbCkkY29lZmZpY2llbnRzW3ZhcnMsIDE6Ml0KICAgICkKICB9LAogIHRheGFfeF9yZWdpb25bLCAxXSwgdGF4YV94X3JlZ2lvblssIDJdLAogIFNJTVBMSUZZID0gRkFMU0UKKQoKb2JzZXJ2ZWRfcmVzcG9uc2VzIDwtIGRvLmNhbGwocmJpbmQsIG9ic2VydmVkX3Jlc3BvbnNlcykKCiMnIENhbGN1bGF0ZSB0aGUgcHJlZGljdGVkIHJlc3BvbnNlcyBvZiBlYWNoIHNwZWNpZXMgaW4gZWFjaCByZWdpb24gYmFzZWQgb24gdGhlCiMnIEdyYW1waWFucyBtb2RlbCBhbmQgdGhlaXIgdHJhaXQgdmFsdWVzLgojKyBwcmVkcmVzcApuc2ltcyA8LSAxMDAwCnNpbXMgPC0gZml4ZWYoc2ltKG1vZGVsX2dyYW1waWFucywgbnNpbXMpKQoKcHJlZGljdGVkX3Jlc3BvbnNlcyA8LSBmdW5jdGlvbih0YXhvbikgewogIGFucyA8LSB2YXBwbHkoCiAgICB2YXJzLCBmdW5jdGlvbih4KSB7CiAgICAgIHJvd1N1bXMoCiAgICAgICAgc3dlZXAoc2ltc1ssIGdyZXAoeCwgY29sbmFtZXMoc2ltcykpXSwgMiwgYygxLCB0cmFpdHNbLCB0YXhvbl0pLCAiKiIpCiAgICAgICkKICAgIH0sCiAgICBudW1lcmljKG5zaW1zKQogICkKICB0KAogICAgYXBwbHkoCiAgICAgIGFucywgMiwgZnVuY3Rpb24oeCkgYyhQcmVkaWN0aW9uID0gbWVhbih4KSwgIlByZWRpY3RlZC4uRXJyb3IiID0gc2QoeCkpCiAgICApCiAgKQp9CgpwcmVkaWN0ZWRfcmVzcG9uc2VzIDwtIGRvLmNhbGwoCiAgcmJpbmQsIHNhcHBseSh0YXhhLCBwcmVkaWN0ZWRfcmVzcG9uc2VzLCBzaW1wbGlmeSA9IEZBTFNFKVt0YXhhX3hfcmVnaW9uWywgMV1dCikKCnJlc3BvbnNlcyA8LSBjYmluZChvYnNlcnZlZF9yZXNwb25zZXMsIHByZWRpY3RlZF9yZXNwb25zZXMpCgpyZXNwb25zZXMgPC0gbWVyZ2UoCiAgcmVzcG9uc2VzLCBzdWJzZXQocGVyZiwgIXJhbmRvbV9lZmZlY3QpLAogIGJ5LnggPSBjKCJUYXhvbiIsICJSZWdpb24iKSwgYnkueSA9IGMoInRheG9uIiwgImlicmFfc3VicmVnaW9uIikKKQoKcGxvdF9yZWdpb25zIDwtIGMoCiAgIlNub3d5IE1vdW50YWlucyIsICJKZXJ2aXMiLCAiVmljdG9yaWFuIEFscHMiLCAiU3RyemVsZWNraSBSYW5nZXMiLAogICJHcmVhdGVyIEdyYW1waWFucyIKKQoKcmVzcG9uc2VzIDwtIHJiaW5kKHJlc3BvbnNlcywgZ3JhbXBpYW5zX3Jlc3BvbnNlcykKCnJlc3BvbnNlcyRSZWdpb24gPC0gZm9yY2F0czo6ZmN0X3JlbGV2ZWwocmVzcG9uc2VzJFJlZ2lvbiwgcGxvdF9yZWdpb25zKQoKc2NhdHRlcnMgPC0gZ2dwbG90KAogICAgc3Vic2V0KAogICAgICByZXNwb25zZXNbb3JkZXIocmVzcG9uc2VzJEFVQyksXSwKICAgICAgVmFyICVpbiUgYygibWxxIiwgInR3aSIpICYgUmVnaW9uICVpbiUgcGxvdF9yZWdpb25zCiAgICApCiAgKSArCiAgeGxpbSgtMiwgNikgKwogIHlsaW0oLTcsIDMpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwogIGdlb21fYWJsaW5lKHNsb3BlID0gMSwgaW50ZXJjZXB0ID0gMCwgbHR5ID0gMikgKwogIGFlcyhFc3RpbWF0ZSwgUHJlZGljdGlvbikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gQVVDKSwgc2l6ZSA9IDIpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3cgPSAid2hpdGUiLCBoaWdoID0gImJsYWNrIikgKwogIGZhY2V0X2dyaWQoCiAgICBSZWdpb24gfiBWYXIsCiAgICBsYWJlbGxlciA9IGxhYmVsbGVyKAogICAgICBWYXIgPSBhc19sYWJlbGxlcigKICAgICAgICBjKAogICAgICAgICAgbWxxICA9ICJNb2lzdHVyZSBMb3dlc3QgUXVhcnRlciIsCiAgICAgICAgICB0d2kgID0gIlRvcG9ncmFwaGljIFdldG5lc3MiCiAgICAgICAgKQogICAgICApCiAgICApCiAgKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAuMzUsIC44OSksCiAgICBsZWdlbmQua2V5LndpZHRoID0gdW5pdCguMDcsICJpbmNoZXMiKSwKICAgIGxlZ2VuZC5rZXkuaGVpZ2h0ID0gdW5pdCguMDksICJpbmNoZXMiKSwKICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiKSwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gNiksCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF9ibGFuaygpCiAgKQoKcGVyZiRpYnJhX3N1YnJlZ2lvbiA8LSBmb3JjYXRzOjpmY3RfcmVsZXZlbChwZXJmJGlicmFfc3VicmVnaW9uLCBwbG90X3JlZ2lvbnMpCgpoaXN0X2RhdGEgPC0gc3Vic2V0KHBlcmYsIGlicmFfc3VicmVnaW9uICVpbiUgcGxvdF9yZWdpb25zICYgIXJhbmRvbV9lZmZlY3QpCm1lZF9kYXRhIDwtIHdpdGgoaGlzdF9kYXRhLCB0YXBwbHkoQVVDLCBpYnJhX3N1YnJlZ2lvbiwgbWVkaWFuKSkKbWVkX2RhdGEgPC0gYXMuZGF0YS5mcmFtZShtZWRfZGF0YSkKbWVkX2RhdGEgPC0gbmEub21pdChtZWRfZGF0YSkKbWVkX2RhdGEkaWJyYV9zdWJyZWdpb24gPC0gcm93Lm5hbWVzKG1lZF9kYXRhKQptZWRfZGF0YSRpYnJhX3N1YnJlZ2lvbiA8LSBmY3RfcmVsZXZlbChtZWRfZGF0YSRpYnJhX3N1YnJlZ2lvbiwgcGxvdF9yZWdpb25zKQoKaGlzdHMgPC0gZ2dwbG90KGhpc3RfZGF0YSkgKwogIGFlcyhBVUMpICsKICBnZW9tX2hpc3RvZ3JhbSgpICsKICBmYWNldF9ncmlkKGlicmFfc3VicmVnaW9uIH4gcmFuZG9tX2VmZmVjdCkgKwogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQgPSBtZWRfZGF0YSksIG1lZF9kYXRhLCBjb2wgPSAiZ3JleSIsIHNpemUgPSAyKSArCiAgeGxhYigiQVVDIikgKwogIHlsYWIoIk5vLiBvZiB0YXhhIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKAogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJ0cmFuc3BhcmVudCIpCiAgKQoKIycgUGxvdCBvZiB0aGUgb2JzZXJ2ZWQgdnMuIHByZWRpY3RlZCByZXNwb25zZXMgZm9yIGVhY2ggY292YXJpYXRlIGdyZXktY29kZWQKIycgYnkgcmVnaW9uLgojKyBwbG90cmVzcG9uc2UsIGZpZy53aWR0aCA9IDcuNSwgZmlnLmhlaWdodCA9IDcuMSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UKZ3JpZC5hcnJhbmdlKHNjYXR0ZXJzLCBoaXN0cywgbmNvbCA9IDIsIHdpZHRocyA9IGMoLjQ1LCAuNTUpKQoKIycgUGxvdCBvZiB0aGUgb2JzZXJ2ZWQgdnMuIHByZWRpY3RlZCByZXNwb25zZXMgdG8gVFdJIGdyZXktY29kZWQKIycgYnkgdHJhaXQgdmFsdWVzLgojKyBwbG90cmVzcG9uc2V0cmFpdHMsIGZpZy53aWR0aCA9IDMuNSwgZmlnLmhlaWdodCA9IDQuNSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UKZ2dwbG90KAogIG1lcmdlKAogICAgc3Vic2V0KAogICAgICByZXNwb25zZXMsCiAgICAgIFZhciA9PSAidHdpIiAmIFJlZ2lvbiAlaW4lIHBsb3RfcmVnaW9uc1tjKDEsIDMsIDUpXQogICAgKSwKICAgIGdhdGhlcigKICAgICAgdW5pcXVlKAogICAgICAgIHJiaW5kKAogICAgICAgICAgbWRnW2MoInRheG9uIiwgImlicmFfc3VicmVnaW9uIiwgInNsYSIsICJzbSIpXSwKICAgICAgICAgIG1kc1tjKCJ0YXhvbiIsICJpYnJhX3N1YnJlZ2lvbiIsICJzbGEiLCAic20iKV0KICAgICAgICApCiAgICAgICksCiAgICAgICJ0cmFpdCIsCiAgICAgICJ2YWx1ZSIsCiAgICAgIHNsYSwgc20KICAgICksCiAgICBieS54ID0gYygiVGF4b24iLCAiUmVnaW9uIiksIGJ5LnkgPSBjKCJ0YXhvbiIsICJpYnJhX3N1YnJlZ2lvbiIpCiAgKQopICsKeGxpbSgtMywgMykgKwp5bGltKC0zLCAzKSArCmdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsKZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCkgKwpnZW9tX2FibGluZShzbG9wZSA9IDEsIGludGVyY2VwdCA9IDAsIGx0eSA9IDIpICsKYWVzKEVzdGltYXRlLCBQcmVkaWN0aW9uKSArCmdlb21fcG9pbnQoYWVzKGNvbG9yID0gdmFsdWUpLCBzaXplID0gMikgKwpzY2FsZV9jb2xvcl9ncmFkaWVudCgKICBuYW1lID0gIlNEIiwgbG93ID0gIndoaXRlIiwgaGlnaCA9ICJibGFjayIKKSArCmZhY2V0X2dyaWQoCiAgUmVnaW9uIH4gdHJhaXQsCiAgbGFiZWxsZXIgPSBsYWJlbGxlcigKICAgIHRyYWl0ID0gYXNfbGFiZWxsZXIoCiAgICAgIGMoCiAgICAgICAgc2xhID0gIlNwZWNpZmljIExlYWYgQXJlYSIsCiAgICAgICAgc20gID0gIlNlZWQgTWFzcyIKICAgICAgKQogICAgKQogICkKKSArCnRoZW1lX2J3KCkgKwp0aGVtZSgKICBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDcsIC45MSksCiAgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoLjA3LCAiaW5jaGVzIiksCiAgbGVnZW5kLmtleS5oZWlnaHQgPSB1bml0KC4wOSwgImluY2hlcyIpLAogIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiKSwKICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLAogIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwKICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpCikKCiMgQ2FsY3VsYXRlIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIHByZWRpY3RlZCB2cyBvYnNlcnZlZCByZXNwb25zZSBjb2VmZmljaWVudHMKIyBmb3IgZWFjaCBjb3ZhcmlhdGUgYW1vbmcgYWxsIHRheGEgd2l0aGluIGEgcmVnaW9uLgojIGNhbGNjb3IKIyBjb3JyZWxhdGlvbnMgPC0gbGFwcGx5KAojICAgdmFycywKIyAgIGZ1bmN0aW9uKHZhcikgewojICAgICBhbnMgPC0gc2FwcGx5KAojICAgICAgIHJnbl9uYW1lcywKIyAgICAgICBmdW5jdGlvbihyZWdpb24pIHsKIyAgICAgICAgIHNzIDwtIHN1YnNldChyZXNwb25zZXMsIFJlZ2lvbiA9PSByZWdpb24gJiBWYXIgPT0gdmFyKQojICAgICAgICAgY29yKHNzJEVzdGltYXRlLCBzcyRQcmVkaWN0aW9uKQojICAgICAgIH0KIyAgICAgKQojICAgICBkYXRhLmZyYW1lKAojICAgICAgIHZhcjIgPSB2YXIsIHJlZ2lvbiA9IG5hbWVzKGFucyksIGNvciA9IGFucywgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAojICAgICAgIHJvdy5uYW1lcyA9IE5VTEwKIyAgICAgKQojICAgfQojICkKIwojIGNvcnJlbGF0aW9ucyA8LSBkby5jYWxsKHJiaW5kLCBjb3JyZWxhdGlvbnMpCiMKIyBjb3JyZWxhdGlvbnMgPC0gZGF0YS5mcmFtZSgKIyAgIGNvcnJlbGF0aW9ucywKIyAgIHZhciA9IGdzdWIoIjIiLCAiIiwgY29ycmVsYXRpb25zJHZhciksCiMgICBLTEQgPSBrbGRpc3RzW2NvcnJlbGF0aW9ucyRyZWdpb25dLAojICAgR0QgPSBkaXN0c1tjb3JyZWxhdGlvbnMkcmVnaW9uXSwKIyAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQojICkKIwojIGNvcnJlbGF0aW9ucyA8LSBtZXJnZShjb3JyZWxhdGlvbnMsIGtsZGlzdHNfdW5pdmFyaWF0ZSkKIwojIFBsb3QgdGhlIGNvcnJlbGF0aW9ucyB2cy4gdGhlIEtMIGRpc3RhbmNlIG9mIHRoZSByZWdpb25zIGVudmlyb25tZW50IGZyb20gdGhlCiMgR3JhbXBpYW5zLgojIHBsb3Rjb3JzMSwgZmlnLndpZHRoPTExCiMgZ2dwbG90KGNvcnJlbGF0aW9ucykgKwojIGFlcyhLTEQsIGNvcikgKwojIGdlb21fcG9pbnQoKSArCiMgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwojIHhsaW0oMCwgMzUpICsKIyB5bGltKC0xLCAxKSArCiMgZmFjZXRfd3JhcCgidmFyMiIsIDIsIGRpciA9ICJ2IikKIwojIFBsb3QgdGhlIGNvcnJlbGF0aW9ucyB2cy4gdGhlIHVuaXZhcmlhdGUgS0wgZGlzdGFuY2Ugb2YgdGhlIHJlZ2lvbnMKIyBlbnZpcm9ubWVudCBmcm9tIHRoZSBHcmFtcGlhbnMuCiMgcGxvdGNvcnMyLCBmaWcud2lkdGg9MTEKIyBnZ3Bsb3QoY29ycmVsYXRpb25zKSArCiMgYWVzKGtsZGlzdF92YXIsIGNvcikgKwojIGdlb21fcG9pbnQoKSArCiMgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwojIHlsaW0oLTEsIDEpICsKIyBmYWNldF93cmFwKCJ2YXIyIiwgMiwgc2NhbGVzID0gImZyZWVfeCIsIGRpciA9ICJ2IikKIwojIFBsb3QgdGhlIGNvcnJlbGF0aW9ucyB2cy4gdGhlIGdlb2dyYXBoaWMgKGNlbnRyb2lkKSBkaXN0YW5jZSBvZiB0aGUgcmVnaW9uCiMgdG8gdGhlIEdyYW1waWFucy4KIyBwbG90Y29yczMsIGZpZy53aWR0aD0xMQojIGdncGxvdChjb3JyZWxhdGlvbnMpICsKIyBhZXMoR0QsIGNvcikgKwojIGdlb21fcG9pbnQoKSArCiMgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwojIHhsaW0oMCwgMTAwMCkgKwojIHlsaW0oLTEsIDEpICsKIyBmYWNldF93cmFwKCJ2YXIyIiwgMiwgZGlyID0gInYiKQo=