GitHub Repository
The Rmarkdown file can be downloaded from the Code drop down menu (top right).

This supplementary file contains the R workflow for processing and analysing the raw data, and creating figures for the manuscript ID: FE-2022-00608 titled “Pathogen load predicts host functional disruption: A meta-analysis of an amphibian fungal panzootic”.


Supplementary methods

Chytridiomycosis disease description

Both chytrid fungus species (Batrachochytrium dendrobatidis, Bd, and Batrachochytrium salamandrivorans, Bs) colonies the host skin via free-swimming motile zoospores and complete their life cycle within the epidermal layer of the skin (Berger et al., 2005; Martel et al., 2013). The chytrid fungus affects the host’s skin function through both the physical breakdown and chemical disruption of the epidermis (Brutyn et al., 2012; Voyles et al., 2009; Wu et al., 2019). Because amphibians rely heavily on their skin for maintaining physiological homeostasis such as electrolyte and fluid balance, and respiration (Hillyard et al., 2008), the resulting cutaneous disruption directly affects the host’s behaviour and physiology (Campbell et al., 2012; Kindermann et al., 2017; Peterson et al., 2013; Van Rooij et al., 2015; Voyles et al., 2007). The cause of death is proposed to be cardiac arrest due to low circulating ion levels (Voyles et al., 2009). The presence of the chytrid fungus also elicits a range of immunological responses (Grogan et al., 2018a; Rollins-Smith and Le Sage, 2021; Rollins-Smith et al., 2011) which in turn alters the host’s energy metabolism, behaviour, activity and movement patterns, and body condition (Grogan et al., 2018b; Richards-Zawacki, 2010; Wu et al., 2018).

Abstract inclusion and data exclusion criteria

Title and abstract screening of 1,038 records after duplicates were removed was conducted in Rayyan (Ouzzani et al., 2016), where the abstracts were screened for whether the study performed experimental infections, whether anurans were tested, and whether a functional trait or survival was measured. In the full-text screening, data were excluded for the following criteria:

  • Non-English literature, books without links to primary source, and non-peer-reviewed articles.
  • Studies that extracted Bd load from dead anurans in the wild, as death in the wild may not be directly caused by Bd directly.
  • Studies that did not quantify Bd load, and only presented Bd prevalence or categorical detection of Bd (positive or negative detection).
  • Studies that capped Bd load based on maximum standard runs, e.g. Brannelly et al. (2015).
  • Studies that exposed amphibians to Bs, or co-exposed Bd with Bs.
  • Exposed amphibians to Bd during the egg or larval life stage.
  • Treatments with additional experimental stressors e.g., agrochemicals, pharmaceuticals, UV exposure, presence of predators.
  • Data from isolated or cultured cells (in-vitro results), as they do not provide functionally relevant responses.
  • Non-quantifiable traits such as histological sections, electron-microscope images, multivariate principal components with arbitrary units.
  • Molecular responses not directly related to functional traits such as transcriptomics, proteomics, and mRNA expression.

Conversion statistics

The correlation coefficient (r) was calculated from inferential statistics with the following equations (1) from Lipsey and Wilson (2001), Nakagawa and Cuthill (2007), and Noble et al. (2017):

\[\begin{equation} r = \sqrt{[t^2 / (t^2 + d.f.)]} = \sqrt{[F / (F + d.f.)]} = \sqrt{(\chi^2 / n)}, \tag{1} \end{equation}\]

where \(t\) = t-statistics, \(F\) = F-statistics, \(d.f.\) = model denominator degrees of freedom, \(\chi^2\) = chi-squared statistics, and \(n\) = sample size. Effect sizes from inferential statistics were only retained when directions could be determined (e.g., \(F\) and \(\chi^2\) alone do not contain directional information). Studies that presented standardised mean differences, as Cohen’s d, were converted to r with the following equation (2) from Borenstein et al. (2009):

\[\begin{equation} r = \frac{d}{\sqrt{d^2 + a}}, \tag{2} \end{equation}\]

where \(a\) is a correction factor (3) for cases where \(n_1 \neq n_2\),

\[\begin{equation} a = \frac{(n_1 + n_2)^2}{n_1n_2}, \tag{3} \end{equation}\]

else, \(a\) = 4.

Keyword co-occurrence network analysis

During the systemetic review, a keyword co-occurrence network analysis was performed using the näive Boolean search from Web of Science and citations in Table S1 from Wu (2019) using the litsearchr R package (Grames et al., 2019).

# Import search results downloaded from Github
naive_results <- litsearchr::import_results(file = "/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Chytrid meta-analysis/Initial search/Wu_table_ref.txt")
naive_results_2 <- litsearchr::import_results(file = "/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/Chytrid meta-analysis/Initial search/naive_search_WoS_211028.txt")

# Extract terms from titles
terms_title <- litsearchr::extract_terms(text = naive_results[, "title"], method = "fakerake",
    min_freq = 4, max_n = 2)

terms_title2 <- litsearchr::extract_terms(text = naive_results_2[, "title"], method = "fakerake",
    min_freq = 2, max_n = 2)

# Combine search terms and create document-feature matrix (DFM)
terms <- unique(c(terms_title, terms_title2))  # Combine both term files
docs <- unique(c(naive_results[, "title"], naive_results_2[, "title"]))  # extract titles
dfm <- litsearchr::create_dfm(elements = docs, features = terms)  # create dfm
network <- litsearchr::create_network(dfm, min_studies = 5)

# Pruning
strengths <- igraph::strength(network)
term_strengths <- data.frame(term = names(strengths), strength = strengths, row.names = NULL) %>%
    dplyr::mutate(rank = rank(strength, ties.method = "min")) %>%
    dplyr::arrange(strength)

Fig. S1. Output from the keyword co-occurrence network analysis. (a) Visualisation of the network where each node represents a term, and the line thickness represents the weight of linking nodes, i.e., the terms appearing in more articles together. (b) The strength of each term in ascending order from left to right.

PRISMA flow-diagram

Fig. S2. PRISMA flow diagram for the systematic data-collection process. n = number of papers remaining after each stage of selection. k = number of effect size after processing individual data, and n is number of observations/records after processing data. Dashed boxes indicate Boolean search string for Web of Science and Scopus.


Dataset

Calculate effect size, \(Z_r\), and sampling variance, \(v(Z_r)\)

The raw data for analysis is available on GitHub. This section is the workflow to import and clean the raw data for analysis. Data were separated by raw data, correlation data, and survival data. The correlation coefficient and sample size was calculated from the raw data and merged with the correlation data (es_all_dat).

Effect size as the Fisher z-transformation of the correlation coefficient r, \(Z_r\) (4), and the sampling variance, \(v(Z_r)\) (5), was calculated following Hedges and Olkin (2014):

\[\begin{equation} Z_r = \frac{1}{2}ln \left( \frac{1+r}{1-r}\right), \tag{4} \end{equation}\]

\[\begin{equation} v(Z_r) = \frac{1}{n - 3}, \tag{5} \end{equation}\]

where r is the correlation coefficient, and n is the sampling size. The standard error, \(se_i\) (6), was calculated as:

\[\begin{equation} se_{i} = \frac{1}{\sqrt{n - 3}}. \tag{6} \end{equation}\]

The inverse of \(se_i\) or precision (7) was calculated as:

\[\begin{equation} p_{i} = \frac{1}{se_i}. \tag{7} \end{equation}\]

The inverse of sampling variance or weight (8) for calculating heterogeneity:

\[\begin{equation} w_{i} = \frac{1}{v(Z_r)}. \tag{8} \end{equation}\]

All conversions for the standard error (\(se_i\)), sampling variance, precision (the inverse of \(se_i\)) and weight (the inverse of variance) followed Nakagawa et al. (2022).

# Load and clean raw data
trait_dat <- read.csv("https://raw.githubusercontent.com/nicholaswunz/chytrid-meta-analysis/main/data/trait_raw_data.csv")  %>% 
  dplyr::filter(trait != "Survival") %>% 
  dplyr::mutate(species_OTL = as.factor(species_OTL),
                trait_value = as.numeric(trait_value),
                trait       = as.factor(trait),
                PCR_meth    = as.factor(PCR_meth),
                response    = as.factor(response),
                lnDose      = log(dose_ZE_ml + 1),
                lnBd        = log(Bd + 1),
                temp_K      = trt_temp + 273.15, # convert temperature Celcius to Kelvin
                inv_temp    = 1 / 8.62e-5  * (1 / mean(temp_K, na.rm = TRUE) - 1 / temp_K) # standardise to mean temp, Boltzmann constant as eV/K
  ) %>%
  dplyr::select(-one_of(c("notes", "title", "ref")))

# Clean effect size data
es_dat <- read.csv("https://raw.githubusercontent.com/nicholaswunz/chytrid-meta-analysis/main/data/trait_corr_data.csv")  %>% 
  dplyr::mutate(study_ID    = ifelse(notes == "repeated", study_ID, study_ID + max(trait_dat$study_ID)),
                species_OTL = as.factor(species_OTL),
                lnDose      = log(dose_ZE_ml + 1),
                lnBd        = log(Bd + 1),
                resistance  = as.factor(resistance),
                trait       = as.factor(trait),
                response    = as.factor(response),
                Zr          = (1 / 2) * log((1 + corr_coeff) / (1 - corr_coeff)), # Fisher-transformed correlation coefficient
                Zr_v        = 1 / (sample_size - 3), # sampling variance (v)
                Zr_sei      = 1 / sqrt(sample_size - 3), # standard error (SE)
                Zr_inv      = 1 / Zr_sei, # precision (inverse of SE) 
                Zr_w        = 1 / Zr_v) %>% # weight (inverse of Zr_v))
  dplyr::select(-one_of(c("notes", "title", "ref")))

# Clean survival data
surv_dat <- read.csv("https://raw.githubusercontent.com/nicholaswunz/chytrid-meta-analysis/main/data/trait_raw_data.csv")  %>% 
  dplyr::filter(trait == "Survival") %>% 
  dplyr::mutate(species_OTL = as.factor(species_OTL),
                resistance  = as.factor(resistance),
                life_stage  = as.factor(life_stage),
                lnDose      = log(dose_ZE_ml + 1),
                lnBd        = log(Bd + 1),
                lnMass      = log(mass_g),
                lnTime      = log(time_post_days),
                temp_K      = trt_temp + 273.15, # convert temperature Celcius to Kelvin
                inv_temp    = 1 / 8.62e-5  * (1 / mean(temp_K, na.rm = TRUE) - 1 / temp_K), # standardise to mean temp, Boltzmann constant as eV/K
                alive       = ifelse(trait_value == "Alive", 1, 0)) %>%
  tidyr::unite("species_lifestage", c("species", "life_stage"), sep = "_", remove = FALSE) %>%
  dplyr::select(-one_of(c("notes", "title", "ref"))) 

# For raw data (trait_dat), calculate correlation coefficient, then calculate effect size
effect_size_dat <- as.data.frame(trait_dat %>%
                                    dplyr::group_by(study_ID, bio_hier, trait, species, response) %>%
                                    dplyr::summarise(corr_coeff     = cor(Bd, trait_value, method = "pearson"),
                                                     sample_size    = length(trait_value),
                                                     author_first   = unique(author_first),
                                                     year           = median(year),
                                                     extracted      = unique(extracted),
                                                     order          = unique(order),
                                                     family         = unique(family),
                                                     species        = unique(species),
                                                     species_OTL    = unique(species_OTL),
                                                     origin         = unique(origin),
                                                     setting        = unique(setting),
                                                     life_stage     = unique(life_stage),
                                                     strain         = unique(strain),
                                                     mean_mass_g    = mean(mass_g),
                                                     trt_temp       = mean(trt_temp),
                                                     dose_ZE_ml     = mean(dose_ZE_ml[dose_ZE_ml != 0]),
                                                     Bd             = mean(Bd[Bd != 0]),
                                                     time_post_days = median(time_post_days[Bd != 0]),
                                                     lnBd           = mean(lnBd[lnBd != 0]))) %>%
  dplyr::mutate(Zr     = (1 / 2) * log((1 + corr_coeff) / (1 - corr_coeff)), # Fisher-transformed correlation coefficient
                Zr_v   = 1 / (sample_size - 3), # sampling variance (v)
                Zr_sei = 1 / sqrt(sample_size - 3), # standard error (SE)
                Zr_inv = 1 / Zr_sei, # precision (inverse of SE) 0
                Zr_w   = 1 / Zr_v, # weight (inverse of Zr_v)
                Zr     = ifelse(response %in% c("Evaporative water loss", "AQP activity", "Skin permeability", 
                                                'Cutaneous ion loss', 'Muscle water content', "Caspase activity"), -abs(Zr), Zr)) 

# Combine effect size dataset
es_all_dat <- bind_rows(effect_size_dat, es_dat) %>%
  tibble::rowid_to_column("es_ID") %>% # add effect size ID
  dplyr::mutate(year_centre = year - mean(year)) # mean-centring year of publication)

Data summary

The es_all_dat used for the meta-analysis comprises of 307 individual effect sizes from 69 studies across 52 species (detailed in Supplementary Table S1).

Table S1 - Summary

Table S1 - Responses. Trait categories associated with Bd infection and the specific responses within these traits. Number of effect sizes, studies and species are shown. Responses with asterisks were corrected for direction. AQP = aquaporins, ENaC = epithelial sodium channel, NKA = sodium potassium pump, CTmax = critical thermal maxima, CTmin = critical thermal minima.

Categorised trait Specific reponse Effect size (k) Studies (n) Species (n)
Behaviour Activity 2 2 2
Behaviour Feeding rate 8 1 6
Behaviour Sloughing 7 3 5
Behaviour Breathing rate 2 1 1
Behaviour Call duration 1 1 1
Behaviour Call rate 3 3 3
Behaviour Calling effort 1 1 1
Behaviour Dominant frequency 1 1 1
Behaviour Intercall interval 1 1 1
Behaviour Note duration 1 1 1
Behaviour Pulse rate 1 1 1
Behaviour Water conserving posture 1 1 1
Body condition Body condition (residual or index) 9 8 8
Body condition Body size (body mass or snout-vent-length) 14 6 12
Body condition Mass change 24 19 18
Body condition Body mass index 4 2 4
Body condition Fat mass 2 1 1
Cardiovascular Contraction force 2 1 2
Cardiovascular Haematocrit 1 1 1
Cardiovascular Heart rate 2 1 2
Cardiovascular Relative ventricular mass 2 1 2
Cardiovascular Blood CO2 1 1 1
Cardiovascular Haemoglobin 3 2 2
Cardiovascular pH 1 1 1
Cardiovascular RBC 3 2 2
Energy metabolism RMR 8 4 3
Hormone level Corticosterone 7 5 7
Hormone level Testosterone 1 1 1
Immune Bd-antibodies 2 1 2
Immune Brevinin-1Sa 1 1 1
Immune Lymphocyte/neutrophil ratio 1 1 1
Immune Lymphocytes 15 6 6
Immune Plasma protein 3 2 3
Immune Serotonin 1 1 1
Immune Spleen size 1 1 1
Immune Total peptides 1 1 1
Immune Bacterial killing ability 8 1 2
Immune Basophils 4 3 3
Immune Bone marrow 2 1 1
Immune Eosinophils 4 3 4
Immune Hematopoietic density 3 1 2
Immune Hematopoietic tissue 6 1 3
Immune Hepatosomatic index 1 1 1
Immune Liver ratio 2 1 2
Immune Monocytes 4 3 4
Immune Neutrophil/lymphocyte ratio 8 1 2
Immune Neutrophils 14 5 6
Immune Peptide profiles 4 1 1
Immune Spleen cells 3 1 3
Immune Spleen ratio 2 1 2
Immune Splenic cell viability 2 1 2
Immune Splenosomatic index 1 1 1
Immune Swelling response 3 1 1
Immune White blood cells 6 3 6
Osmoregulation Active sodium transport 2 2 1
Osmoregulation AQP activity 1 1 1
Osmoregulation Cutaneous ion loss* 1 1 1
Osmoregulation ENaC abundance 1 1 1
Osmoregulation Evaporative water loss* 9 3 9
Osmoregulation Muscle water content 1 1 1
Osmoregulation NKA abundance 1 1 1
Osmoregulation Plasma chloride 4 4 2
Osmoregulation Plasma osmolarity 3 3 2
Osmoregulation Plasma potassium 6 5 4
Osmoregulation Plasma sodium 7 6 4
Osmoregulation Water uptake 6 4 5
Osmoregulation Plasma calcium 3 2 2
Osmoregulation Plasma glucose 4 3 2
Reproduction Clutch size 1 1 1
Reproduction Colour score 1 1 1
Reproduction Egg size 1 1 1
Reproduction Ovary area 1 1 1
Reproduction Sperm count 1 1 1
Reproduction Testis area 1 1 1
Reproduction Tubule area 1 1 1
Reproduction Egg numbers 1 1 1
Reproduction Ovary mass 2 2 2
Reproduction Oviduct size 1 1 1
Reproduction Sexual display 1 1 1
Reproduction Spermatic cyst diameter 1 1 1
Reproduction Spermatocytes 2 1 2
Reproduction Spermatogenesis-stage cycts 2 1 2
Reproduction Spermatogonia 2 1 2
Reproduction Testes size 4 3 4
Reproduction Testes tubules 2 1 2
Skin integrity Caspase activity* 1 1 1
Skin integrity Skin permeability* 1 1 1
Skin integrity Skin resistance 5 3 4
Skin integrity Skin sheds* 2 1 1
Thermoregulation Body temp 4 4 4
Thermoregulation CTmax 1 1 1
Thermoregulation CTmin 2 1 2
Locomotor capacity Jumping acceleration 1 1 1
Locomotor capacity Jumping velocity 1 1 1

Life stage

Table S1 - Life stage. Continuation of data summary with additional information on the number of effect size, studies, and species in the database by life stage (adult or Juvenile).

Life stage Effect size (k) Studies (n) Species (n)
Adult 206 48 38
Juvenile 101 25 22

Species

Table S1 - Species. Continuation of data summary with additional information on the number of effect size, and studies in the database by species.

Species Effect size (k) Studies (n)
Litoria caerulea 58 13
Litoria verreauxii alpina 24 6
Rana cascadae 19 2
Pseudacris regilla 17 1
Lithobates pipiens 15 3
Litoria infrafrenata 15 1
Litoria aurea 13 3
Pseudophryne corroboree 12 2
Litoria rheocola 10 1
Anaxyrus boreas 8 3
Rana muscosa 8 2
Lissotriton helveticus 6 2
Litoria raniformis 6 1
Litoria serrata 6 2
Rhinella marina 6 3
Litoria chloris 5 1
Pseudacris triseriata 5 3
Atelopus zeteki 4 3
Xenopus laevis 4 2
Anaxyrus americanus 3 3
Bufo boreas 3 2
Dendropsophus�minutus 3 1
Hyla versicolor 3 2
Ischnocnema parva 3 1
Litoria wilcoxii 3 1
Physalaemus albonotatus 3 1
Pseudacris feriarum 3 1
Rana catesbeiana 3 2
Anaxyrus terrestris 2 1
Brachycephalus pitanga 2 1
Hyla japonica 2 1
Lechriodus fletcheri 2 2
Limnodynastes peronii 2 2
Limnodynastes tasmaniensis 2 2
Lithobates sylvaticus 2 1
Lithobates yavapaiensis 2 1
Osteopilus septentrionalis 2 1
Platyplectrum ornatum 2 2
Rana pipiens 2 1
Rana sphenocephala 2 1
Acris crepitans 1 1
Bufo bufo 1 1
Crinia signifera 1 1
Hyla chrysoscelis 1 1
Hyla cinerea 1 1
Leiopelma hochstetteri 1 1
Leiopelma pakeka 1 1
Lithobates palustris 1 1
Litoria citropa 1 1
Litoria ewingii 1 1
Litoria lesueurii 1 1
Pseudophryne pengilleyi 1 1
Rana boylii 1 1
Rana clamitans 1 1
Rana sylvatica 1 1

Traits

Table S1 - Traits Continuation of data summary with additional information on the number of effect size, studies, and species in the database traits.

Trait Effect size (k) Studies (k) Species (n)
Immune 102 15 16
Body condition 53 34 34
Osmoregulation 49 12 13
Behaviour 29 10 16
Reproduction 25 6 6
Cardiovascular 15 4 5
Skin integrity 9 6 6
Energy metabolism 8 4 3
Hormone level 8 5 7
Thermoregulation 7 6 7
Locomotor capacity 2 1 1

Prepare phylogeny for analysis

This section provides the workflow to extract the phylogenetic tree from the Open Tree of Life (OTL; see phylogenetic reconstruction in main text), match the OTL names with the data set, and create a correlation matrix for subsequent analysis. The phylogenetic tree produced in R for the Supplementary Figure S3 was modified in Adobe Illustrator for clarity.

species_comb <- rbind(es_all_dat %>%
    dplyr::select(order, family, species, species_OTL), surv_dat %>%
    dplyr::select(order, family, species, species_OTL))  # 'surv_data_clean' created below
species_all <- sort(unique(as.character(species_comb$species_OTL)))  # generate list of species (as character format)
taxa <- rotl::tnrs_match_names(names = species_all)  # match taxonomic names to the OTL

# check if species list match OT identifier taxa[taxa$approximate_match ==
# TRUE,] # none so far

# retrieving phylogenetic relationships among taxa in the form of a trimmed
# sub-tree
tree <- rotl::tol_induced_subtree(ott_ids = rotl::ott_id(taxa), label_format = "name")

# Compute branch lengths
tree <- ape::compute.brlen(tree, method = "Grafen", power = 1)
tree <- ape::multi2di(tree, random = TRUE)  # use a randomization approach to deal with polytomies

# Check tree is ultrametric ape::is.ultrametric(tree) # TRUE

# Create correlation matrix for analysis
phylo_cor <- ape::vcv(tree, cor = T)

Fig. S3. Phylogenetic reconstruction of 60 amphibians used in the study from the Open Tree of Life. The phylogeny was converted to a correlation matrix for the meta-analysis.


Meta-analysis

Phylogenetically controlled, multi-level meta-analysis and meta-regression

Run analysis to first look at the null effect of Bd infection on all responses (\(Z_r\)) without moderators (null_model), then with the following moderators days post-exposure, life stage (adults or juveniles), origin (wild caught or lab raised), natural logarithm of inoculation dose, and treatment temperature (overall_model). A follow up analysis was performed to estimate of coefficients for every factor level to obtain posterior distributions of effect size between biological and functional traits (trait_model).

meta_prior <- c(set_prior("cauchy(0, 1)", class = "sd"))  # Cauchy on tau (random effect variance), normal on fixed effect

# Null model - Without moderators
set.seed(10)
null_model <- brms::brm(Zr | se(Zr_sei) ~ 1 + (1 | es_ID) + (1 | study_ID) + (1 |
    species_OTL) + (1 | gr(species, cov = phylo)), data = es_all_dat, family = gaussian,
    data2 = list(phylo = phylo_cor), prior = meta_prior, iter = 10000, warmup = 5000,
    cores = 4, chains = 4, control = list(adapt_delta = 0.999, max_treedepth = 18))

# Meta-regression model - With moderators
overall_model <- brms::brm(Zr | se(Zr_sei) ~ time_post_days + life_stage + origin +
    lnDose + trt_temp + (1 | es_ID) + (1 | study_ID) + (1 | species_OTL) + (1 | gr(species,
    cov = phylo)), data = es_all_dat, family = gaussian, data2 = list(phylo = phylo_cor),
    prior = meta_prior, iter = 10000, warmup = 5000, cores = 4, chains = 4, control = list(adapt_delta = 0.999,
        max_treedepth = 18))

# Trait-specific meta-regression model
trait_model <- brms::brm(Zr | se(Zr_sei) ~ -1 + trait + life_stage + year_centre +
    (1 | es_ID) + (1 | study_ID) + (1 | species_OTL) + (1 | gr(species, cov = phylo)),
    data = es_all_dat %>%
        dplyr::group_by(trait) %>%
        dplyr::filter(n() >= 5), family = gaussian, data2 = list(phylo = phylo_cor),
    prior = meta_prior, iter = 10000, warmup = 5000, cores = 4, chains = 4, control = list(adapt_delta = 0.999,
        max_treedepth = 18))

Publication bias test

Publication bias was tested by using the same formula as the null_model with the inclusion of the mean centring of year (test for time-lag bias) and the square root of the sampling variance (test for samm-sample bias) as moderators (bias_model).

bias_model <- brms::brm(Zr | se(Zr_sei) ~ 1 + year_centre + sqrt(Zr_v) + (1 | es_ID) +
    (1 | study_ID) + (1 | species_OTL) + (1 | gr(species, cov = phylo)), data = es_all_dat,
    family = gaussian, data2 = list(phylo = phylo_cor), prior = meta_prior, iter = 10000,
    warmup = 5000, cores = 4, chains = 4, control = list(adapt_delta = 0.999, max_treedepth = 18))

Fig. S4. Scatterplots of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution for the (a) null model, (b) the overall model, (c) the trait model, and (c) the bias model. Dashed line represents a slope of 1.

Model output

Table S2 - Null model

Table S2. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the null model, which includes the intercept (\(\beta_0\)). Group-level effects include the standard deviations (\(\sigma\)) for individual-level observations (\(\sigma_{residual}^2\)), study-level observations (\(\sigma_{study}^2\)), species identity (\(\sigma_{species}^2\)), and phylogenetic relatedness (\(\sigma_{phylogeny}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
\(\beta_0\) -0.13 0.08 -0.28 0.05
Group-level effects
\(\sigma_{residual}^2\) 0.32 0.02 0.27 0.36
\(\sigma_{phylogeny}^2\) 0.09 0.08 0.00 0.32
\(\sigma_{species}^2\) 0.16 0.05 0.06 0.26
\(\sigma_{study}^2\) 0.19 0.05 0.09 0.29

Table S3 - Heterogeneity and variance

Table S3. Heterogeneity and \(R^2\) of the null and overall model. k = number of estimates, and \(I^2\) = heterogeneity. \(R_{marginal}^2\) represents the variance explained by moderators, while \(R_{conditional}^2\) represents the variance explained by both moderators and group-level effects. Estimates shown correspond to modes and 95% highest posterior density intervals.

Model \(I_{residual}^2\) \(I_{study}^2\) \(I_{species}^2\) \(I_{phylogeny}^2\) \(I_{total}^2\) \(R_{marginal}^2\) \(R_{conditional}^2\)
Null 41.6 25.2 22 1.8 97.3 0 72.2
[29.3–52.7] [13.3–35.7] [8.3–31.8] [0–29.5] [96.4–97.8] [0–0] [66.3–77.8]
Overall 31.2 28.8 22.5 9.1 98.1 12.81 78.3
[19.6–41.7] [11.8–45.5] [1.3–38.9] [0–38.5] [97.3–98.6] [2.96–24.89] [72.3–83.8]

Table S4 - Bias model

Table S4. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the bias model, which includes the intercept (\(\beta_0\)), publication year and sampling standard error as covariates to test and correct for publication bias. Group-level effects include the standard deviations (\(\sigma\)) for individual-level observations (\(\sigma_{residual}^2\)), study-level observations (\(\sigma_{study}^2\)), species identity (\(\sigma_{species}^2\)), and phylogenetic relatedness (\(\sigma_{phylogeny}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
\(\beta_0\) -0.06 0.12 -0.29 0.17
Publication year 0.01 0.01 -0.01 0.03
Sampling standard error -0.37 0.42 -1.19 0.46
Group-level effects
\(\sigma_{residual}^2\) 0.31 0.02 0.27 0.36
\(\sigma_{phylogeny}^2\) 0.10 0.09 0.00 0.33
\(\sigma_{species}^2\) 0.15 0.05 0.04 0.25
\(\sigma_{study}^2\) 0.19 0.05 0.09 0.30

Fig S5 - Funnel plot

Fig. S5. Funnel plot on the effect size against the study standard error. The white area bordered by dashed lines represents the region of 95% pseudo confidence intervals where 95% of studies are expected to fall in the absence of bias and heterogeneity.

Table S5 - Overall model

Table S5. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the overall model, which includes the intercept (\(\beta_0\)), days post-exposure, life stage (juvenile or adult), origin (wild caught or lab-reared), the natural logarithm of inoculation dose (lnDose), and treatment temperature as fixed effects. Group-level effects include the standard deviations (\(\sigma\)) for individual-level observations (\(\sigma_{residual}^2\)), study-level observations (\(\sigma_{study}^2\)), species identity (\(\sigma_{species}^2\)), and phylogenetic relatedness (\(\sigma_{phylogeny}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
\(\beta_0\) -1.19 0.80 -2.78 0.38
Days post-exposure 0.00 0.00 0.00 0.00
Life stage - Juveniles 0.08 0.17 -0.24 0.42
Origin - Wild -0.04 0.26 -0.55 0.46
lnDose 0.01 0.06 -0.10 0.12
Treatment temperature 0.05 0.02 0.01 0.09
Group-level effects
\(\sigma_{residual}^2\) 0.33 0.03 0.28 0.40
\(\sigma_{phylogeny}^2\) 0.20 0.16 0.01 0.61
\(\sigma_{species}^2\) 0.24 0.11 0.03 0.48
\(\sigma_{study}^2\) 0.32 0.11 0.12 0.56

Table S6 - Trait model

Table S6. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the trait model, which includes the biological and functional traits, life stage (juvenile or adult), and publication year as fixed effects. Group-level effects include the standard deviations (\(\sigma\)) for individual-level observations (\(\sigma_{residual}^2\)), study-level observations (\(\sigma_{study}^2\)), species identity (\(\sigma_{species}^2\)), and phylogenetic relatedness (\(\sigma_{phylogeny}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
Behaviour -0.18 0.13 -0.42 0.07
Body condition -0.21 0.11 -0.41 0.03
Cardiovascular 0.04 0.17 -0.28 0.37
Energy metabolism 0.58 0.19 0.21 0.97
Hormon elevel 0.05 0.19 -0.32 0.43
Immune -0.15 0.12 -0.37 0.09
Osmoregulation -0.21 0.12 -0.43 0.04
Reproduction -0.14 0.15 -0.44 0.17
Skin integrity -0.06 0.17 -0.40 0.29
Thermoregulation -0.22 0.19 -0.59 0.16
Life stage - Juveniles 0.03 0.09 -0.15 0.22
Publication year 0.01 0.01 -0.01 0.04
Group-level effects
\(\sigma_{residual}^2\) 0.30 0.02 0.25 0.34
\(\sigma_{phylogeny}^2\) 0.11 0.10 0.00 0.35
\(\sigma_{species}^2\) 0.16 0.05 0.04 0.26
\(\sigma_{study}^2\) 0.22 0.06 0.11 0.34

Trait sensitivity analysis

Calculating trait sensitivity

The following workflow uses the raw data set to estimate response-specific sensitivity to Bd infection. All response values were standardised to relative change in response.

# Extract mean, 10th and 90th quantile control values by species and responses
control_mean <- as.data.frame(trait_dat %>%
  dplyr::filter(Bd == 0) %>% 
  dplyr::group_by(species, response) %>% 
  dplyr::summarise(mean            = mean(trait_value, na.rm = TRUE),
                   quantile_10     = quantile(trait_value, .10),
                   quantile_90     = quantile(trait_value, .90)) %>%
  tidyr::unite("specific_response", c(species, response), sep = "_",  remove = FALSE)) # unique identifier by species and response

# Combine mean controls and calculate relative change of response
traits_exposed <- trait_dat %>% 
  tidyr::unite("specific_response", c(species, response), sep = "_",  remove = FALSE) %>%
  dplyr::mutate(control           = control_mean$mean[match(specific_response, control_mean$specific_response)], 
                change            = ifelse(trait_unit == "relative", trait_value, (trait_value - control) / control), # calculate relative change
                specific_response = as.factor(specific_response),
                quantile_90       = control_mean$quantile_90[match(specific_response, control_mean$specific_response)],
                quantile_10       = control_mean$quantile_10[match(specific_response, control_mean$specific_response)],
                control_90        = ifelse(trait_unit == "relative", trait_value, (quantile_90 - control) / control), # calculate relative 90th quantile
                control_10        = ifelse(trait_unit == "relative", trait_value, (quantile_10 - control) / control)) # calculate relative 10th quantile

# Run lm models to find ones with good R2 
R_sq_model <- as.data.frame(traits_exposed %>% 
                              dplyr::filter(!is.na(change)) %>% # remove NA's
                              dplyr::group_by(specific_response) %>%
                              dplyr::do(model = broom::glance(lm(change ~ lnBd, data = .))) %>%
                              tidyr::unnest(model)) %>%
  dplyr::select(specific_response, r.squared, adj.r.squared, p.value)

# extract equation (intercept and slope)
lm_eq <- as.data.frame(traits_exposed %>% 
                         dplyr::filter(!is.na(change)) %>%
                         dplyr::group_by(specific_response) %>%
                         dplyr::do(model = broom::tidy(lm(change ~ lnBd, data = .))) %>% 
                         tidyr::unnest(model)) %>%
  dplyr::select(specific_response, term, estimate) %>%
  reshape(idvar = "specific_response", timevar = "term", direction = "wide") %>% # from long to wide for estimate column
  dplyr::rename(intercept = "estimate.(Intercept)",
                slope     = "estimate.lnBd")

# Deal with relative units that were not converted previously (ifelse(trait_unit == "relative", trait_value, (quantile_90 - control) / control))
control_range <- as.data.frame(traits_exposed %>%
                                 dplyr::filter(Bd == 0) %>%
                                 dplyr::group_by(specific_response) %>%
                                 dplyr::summarise(control_90 = max(control_90),
                                                  control_10 = min(control_10)))

# Generate Bd load sequence from min and max and predict response
xseq       <- seq(0, max(traits_exposed$lnBd[!is.na(traits_exposed$lnBd)]), length.out = 50)
eq_bd_pred <- data.frame(lm_eq %>%
                           dplyr::group_by(specific_response) %>%
                           dplyr::summarise(pred = intercept + slope * xseq) %>%
                           dplyr::mutate(pred_bd    = xseq,
                                         trait      = traits_exposed$trait[match(specific_response, traits_exposed$specific_response)],
                                         control    = traits_exposed$control[match(specific_response, traits_exposed$specific_response)],
                                         control_90 = control_range$control_90[match(specific_response, control_range$specific_response)],
                                         control_10 = control_range$control_10[match(specific_response, control_range$specific_response)]))

# Keep specific responses with R2 >= 0.1 and p value <= 0.05
responses_kept <- R_sq_model %>% dplyr::filter(adj.r.squared >= 0.1 | p.value <= 0.05) %>% droplevels()
kept_pred      <- eq_bd_pred %>% dplyr::filter(specific_response %in% c(levels(responses_kept$specific_response))) %>% droplevels()

# Filter Bd load lower than 10th and higher than 90th quantile control values 
sensitivity_pos <- data.frame(kept_pred %>%
                                dplyr::group_by(specific_response) %>%
                                dplyr::filter(pred_bd != 0 & pred > 0) %>% # in positive direction
                                dplyr::filter(pred > control_90) %>%
                                dplyr::summarize(minBd = min(pred_bd)))

sensitivity_neg <- data.frame(kept_pred %>%
                               dplyr::group_by(specific_response) %>%
                               dplyr::filter(pred_bd != 0 & pred < 0) %>%  # in negative direction
                               dplyr::filter(case_when(control < 0 ~ pred < control_90, T ~ pred < control_10)) %>%
                               dplyr::summarize(minBd = min(pred_bd)))

# Combine sensitivity_pos and sensitivity_neg
sensitivity <- rbind(sensitivity_pos, sensitivity_neg) %>%
  dplyr::mutate(lnminBd     = minBd,
                response    = traits_exposed$response[match(specific_response, traits_exposed$specific_response)],
                trait       = traits_exposed$trait[match(specific_response, traits_exposed$specific_response)],
                bio_hier    = traits_exposed$bio_hier[match(specific_response, traits_exposed$specific_response)],
                species     = traits_exposed$species[match(specific_response, traits_exposed$specific_response)],
                species_OTL = traits_exposed$species_OTL[match(specific_response, traits_exposed$specific_response)],
                life_stage  = traits_exposed$life_stage[match(specific_response, traits_exposed$specific_response)],
                lnDose      = traits_exposed$lnDose[match(specific_response, traits_exposed$specific_response)],
                inv_temp    = traits_exposed$inv_temp[match(specific_response, traits_exposed$specific_response)])

sensitivity$species <- sub(" ", "_", sensitivity$species_OTL)
sensitivity$species <- factor(sensitivity$species, levels = tree_tip_label) # relevel order by tree

Sensitivity analysis

Run phylogenetic corrected, multi-level model to test the sensitivity of traits to Bd load.

set.seed(10)
sensitive_model <- brms::brm(lnminBd ~ -1 + trait + lnDose + inv_temp + (1 | species_OTL) + (1 | gr(species, cov = phylo)),
                             data    = sensitivity,
                             family  = gaussian,
                             data2   = list(phylo = phylo_cor),
                             prior   = c(prior(normal(0, 5), lb = 0), # mean of 0 and SD of 5
                                       prior(student_t(3, 0, 5), "sd"), # class of random effect deviation
                                       prior(student_t(3, 0, 5), "sigma")), # residual SD parameter
                             iter    = 1e4, warmup = 5e3, cores = 4, chains = 4,
                             control = list(adapt_delta = 0.99, max_treedepth = 18))

Fig. S6. Scatterplot of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution. Dashed line represents a slope of 1.

Model output

Table S7. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the sensitivity model, which includes the functional traits, natural logarithm of inoculation dose (lnDose), and the inverse of temperature as fixed effects. Group-level effects include the standard deviations (\(\sigma\)) for species identity (\(\sigma_{species}^2\)), and phylogenetic relatedness (\(\sigma_{phylogeny}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
Behaviour 4.87 2.34 0.63 9.67
Body condition 5.06 1.95 1.19 8.80
Cardiovascular 3.79 2.38 0.23 9.14
Energy metabolism 4.23 2.67 0.26 10.11
Hormone level 2.51 1.86 0.11 6.87
Immune 2.82 2.20 0.10 8.15
Osmoregulation 2.52 1.47 0.19 5.71
Reproduction 10.60 3.26 4.06 16.93
Skin integrity 2.46 1.70 0.11 6.43
lnDose 0.08 0.07 0.00 0.26
Inverse temperature 1.34 1.23 0.03 4.53
Group-level effects
\(\sigma_{phylogeny}^2\) 2.05 1.52 0.08 5.66
\(\sigma_{species}^2\) 4.08 1.74 0.57 7.49

Survival analysis

The survival data set comprises of 33 species.

# Rename species based on species_OTL
surv_dat$species <- sub(" ", "_", surv_dat$species_OTL)
surv_dat$species <- factor(surv_dat$species, levels = tree_tip_label)  # relevel order by tree
surv_dat <- surv_dat %>%
    dplyr::mutate(species = factor(species))

Survival and Bd and time-dependent mortality analysis

Run phylogenetic corrected, multi-level models to test for the influence of Bd load on survival.

# Binary logistic regression model
set.seed(10)
surv_model <- brms::brm(alive ~ 1 + lnBd + time_post_days + lnDose + life_stage +
    inv_temp + species_OTL + (1 | study_ID:species_OTL) + (1 | gr(species, cov = phylo)),
    data = surv_dat, family = bernoulli(link = "logit"), data2 = list(phylo = phylo_cor),
    prior = c(prior(normal(0, 2), class = Intercept), prior(normal(0, 2), class = b)),
    iter = 5000, warmup = 2000, chains = 4, cores = 4, control = list(adapt_delta = 0.99,
        max_treedepth = 18))

time_bd_model <- brms::brm(lnBd ~ lnTime * life_stage + lnDose + inv_temp + (1 |
    study_ID:species_OTL), data = surv_dat %>%
    dplyr::filter(alive == 0), family = gaussian(), prior = c(prior(normal(0, 2),
    class = Intercept), prior(normal(0, 2), class = b)), iter = 5000, warmup = 2000,
    chains = 4, cores = 4, control = list(adapt_delta = 0.99, max_treedepth = 18))

Fig. S7. Posterior predictive check for (a) the survival model, and (b) the Bd-time model. The Bd-time model is represented by a scatterplot of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution. Dashed line represents a slope of 1.

Model output

Table S8 - Survival model

Table S8. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the probability of survival, which includes the natural logarithm of Bd load (lnBd), days post exposure, natural logarithm of inoculation dose (lnDose), life stage, and the inverse of temperature as fixed effects. Group-level effects include the standard deviations (\(\sigma\)) for phylogenetic relatedness (\(\sigma_{phylogeny}^2\)) and species-study interaction (\(\sigma_{species:study}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
\(\beta_0\) 17.16 3.29 11.58 24.59
lnBd -0.96 0.05 -1.06 -0.85
Days post-exposure -0.03 0.01 -0.05 -0.02
lnDose -0.82 0.27 -1.44 -0.41
Life stage - Juvenile 2.15 0.48 1.23 3.11
Inverse temperature 0.94 0.60 -0.20 2.17
Group-level effects
\(\sigma_{phylogeny}^2\) 2.39 2.05 0.09 7.56
\(\sigma_{species:study}^2\) 7.41 1.42 5.08 10.61

Table S9 - Threshold

Table S9. Predicted 50% and 90% survival threshold by species presented as zoospore equivalent (ZE) and the natural logarithm of ZE (ln ZE + 1).

Species Family 50% (ln ZE + 1) 50% (ZE + 1) 90% (ln ZE + 1) 90% (ZE + 1)
Acris crepitans Hylidae 8.1 3134 10.3 30486
Anaxyrus americanus Bufonidae 7.8 2412 10.1 25431
Anaxyrus boreas Bufonidae 7.8 2412 10.1 24788
Anaxyrus terrestris Bufonidae 7.5 1886 9.9 20875
Atelopus zeteki Bufonidae 8.7 6142 11.1 63494
Dendropsophus_elegans Hylidae 8.6 5415 10.9 55199
Dendropsophus_minutus Hylidae 8.7 5908 11.0 59648
Dryophytes versicolor Hylidae 7.0 1055 9.4 11672
Ischnocnema parva Brachycephalidae 8.7 5964 11.0 60506
Lechriodus fletcheri Limnodynastidae 8.6 5274 10.9 51985
Limnodynastes ornatus Limnodynastidae 8.3 4073 10.6 41840
Limnodynastes peronii Limnodynastidae 8.1 3167 10.3 31350
Limnodynastes tasmaniensis Limnodynastidae 8.4 4476 10.7 46123
Litoria aurea Pelodryadidae 7.8 2458 10.2 25966
Litoria caerulea Pelodryadidae 8.3 4024 10.6 40368
Litoria ewingii Pelodryadidae 8.1 3167 10.4 32290
Litoria spenceri Pelodryadidae 8.2 3545 10.5 36467
Litoria verreauxii Pelodryadidae 7.5 1724 9.7 15618
Pseudacris feriarum Hylidae 7.2 1341 9.5 13080
Pseudacris regilla Hylidae 7.6 2077 10.1 24100
Pseudacris triseriata Hylidae 7.2 1386 9.5 13506
Pseudophryne corroboree Myobatrachidae 8.1 3134 10.3 30486
Rana aurora Ranidae 7.5 1724 9.7 15618
Rana muscosa Ranidae 8.7 6068 11.0 62587
Rana pipiens Ranidae 7.2 1310 9.5 12883
Rana sierrae Ranidae 8.7 6240 11.1 66762
Rana sphenocephala Ranidae 8.1 3429 10.5 35145
Rana sylvatica Ranidae 7.2 1379 9.5 13506
Average 8.0 3369 10.3 34349

Table S10 - Bd-time model

Table S10. Mean parameter estimates, estimate error, and 95% Bayesian credible intervals for the Bd-time model, which includes the natural logarithm of days post-exposure (lnTime), life stage, resistance, the inverse of temperature and the interaction of lnTime and life stage as fixed effects. Group-level effects include the species-study interaction (\(\sigma_{species:study}^2\)).

Parameter Estimate Est.Error Q2.5 Q97.5
Fixed effects
\(\beta_0\) 7.24 3.96 -1.08 14.68
lnTime -0.22 0.26 -0.74 0.27
Life stage - Juvenile 3.45 0.84 1.76 5.10
lnDose 0.26 0.34 -0.39 0.96
Inverse temperature 0.25 0.84 -1.39 1.92
lnTime : Life stage -1.90 0.36 -2.60 -1.19
Group-level effects
\(\sigma_{species:study}^2\) 3.61 0.67 2.55 5.15

Figures for main text

Figures produced here were modified in Adobe Illustrator for publication.

Figure 2 - Trait model

# Extract marginal effects from model
model_me <- brms::conditional_effects(trait_model, c("trait", "life_stage"))
trait_me <- as.data.frame(model_me[[1]]) %>%
    dplyr::rename(estimate = estimate__, ci.lb = lower__, ci.ub = upper__)

# Plot model output
trait_me %>%
    ggplot(aes(x = trait, y = estimate)) + geom_hline(yintercept = 0, linetype = "dashed",
    alpha = 0.5) + ggforce::geom_sina(data = es_all_dat, aes(x = trait, y = Zr, size = Zr_inv),
    colour = "#cfcfcf") + geom_point(aes(colour = trait), size = 4, show.legend = FALSE) +
    geom_errorbar(aes(ymin = ci.lb, ymax = ci.ub, colour = trait), size = 0.8, width = 0.1,
        show.legend = FALSE) + colorspace::scale_colour_discrete_sequential(palette = "RedOr",
    nmax = 14, order = 4:14) + xlab(NULL) + ylab(expression("Effect size" ~ (italic(Z)[r]))) +
    coord_flip() + mytheme() + theme(legend.position = "bottom")

Fig. 2. Effect of Bd infection on all biological (cardiovascular, immune, hormone level, energy metabolism, osmoregulation, skin integrity) and functional (behaviour, body condition, locomotor capacity, reproduction, thermoregulation) traits measured. Only traits with more than five effect size were analysed. Numbers on the right side of the plot indicate the number of effect sizes analysed. Effect sizes (Zr) presented as estimates ± 95% CI. Grey points represent individual effect size, and the size of each point indicates study precision (inverse of standard error).

Figure 3 - Sensitivity model

# Extract marginal effects
sensitive_me <- brms::conditional_effects(sensitive_model)
sensitive_me <- as.data.frame(sensitive_me[[1]]) %>%
    dplyr::rename(estimate = estimate__, ci.lb = lower__, ci.ub = upper__) %>%
    dplyr::mutate(estimate = exp(estimate), ci.lb = exp(ci.lb), ci.ub = exp(ci.ub))

sensitive_post <- brms::posterior_samples(sensitive_model) %>%
    dplyr::sample_n(4000) %>%
    dplyr::select(b_traitBehaviour:b_traitSkinintegrity) %>%
    reshape2::melt(value.name = "sample")

sensitive_post$variable <- substring(sensitive_post$variable, 8)
source("https://raw.githubusercontent.com/datavizpyr/data/master/half_flat_violinplot.R")

sensitive_post %>%
    dplyr::group_by(variable) %>%
    dplyr::summarise(mean = mean(sample)) %>%
    dplyr::mutate(variable = forcats::fct_reorder(variable, mean)) %>%
    ggplot() + geom_point(aes(x = variable, y = mean), size = 2) + geom_flat_violin(data = sensitive_post,
    aes(x = variable, y = sample, fill = variable), colour = NA, show.legend = FALSE) +
    geom_point(aes(x = variable, y = mean), size = 3) + geom_point(aes(x = variable,
    y = mean, colour = variable), size = 2, show.legend = FALSE) + colorspace::scale_fill_discrete_sequential(palette = "RedOr",
    nmax = 12, order = 4:12) + colorspace::scale_colour_discrete_sequential(palette = "RedOr",
    nmax = 12, order = 4:12) + xlab(NULL) + ylab("Infection intensity (log ZE + 1)") +
    coord_flip() + mytheme()

Fig. 3. Posterior distribution density (4,000 subset iterations) of the minimum Bd load (ln ZE +1) to change trait response above or below the normal response range (5th or 95th quantile). Enclosed circles represent the mean estimate response.

Figure 4 - Survival model

# Plot
surv_plot <- surv_marg_eff %>%
    ggplot(aes(x = x, y = predicted, colour = life_stage)) + geom_vline(xintercept = log(10000),
    linetype = "dashed", alpha = 0.5) + geom_line(aes(group = group, linetype = life_stage),
    size = 0.5) + geom_point(data = surv_dat, aes(x = lnBd, y = alive, colour = life_stage),
    size = 1.5, alpha = 0.5) + colorspace::scale_colour_discrete_sequential(palette = "Blues 3",
    nmax = 5, order = c(3, 5)) + ylab("Survival probabilty") + xlab("Infection intensity (ln ZE + 1)") +
    mytheme() + theme(legend.position = "top") + facet_grid(rows = vars(life_stage))

inflict_plot <- data.frame(surv_marg_eff %>%
    dplyr::group_by(group, life_stage) %>%
    dplyr::filter(predicted < 0.52 & predicted > 0.48) %>%
    dplyr::summarise(threshold = mean(x)) %>%
    dplyr::mutate(bd = exp(threshold))) %>%
    dplyr::mutate(group = forcats::fct_reorder(group, -threshold)) %>%
    ggplot(aes(x = group, y = threshold, colour = life_stage)) + geom_point(aes(shape = life_stage),
    size = 2) + colorspace::scale_colour_discrete_sequential(palette = "Blues 3",
    nmax = 5, order = c(3, 5)) + ylab(expression(atop(italic("Bd") ~ "load (ln ZE + 1)",
    "with 50% mortality probabilty"))) + xlab(NULL) + scale_x_discrete(position = "top") +
    coord_flip() + mytheme() + theme(legend.position = "top", axis.text.y = element_text(size = rel(0.8)))

cowplot::plot_grid(surv_plot, inflict_plot, labels = c("a", "b"), ncol = 2, align = "h",
    axis = "tb", rel_widths = c(0.9, 1))

Fig. 4. Relationship between infection intensity (ln ZE + 1) and the probability of survival of 27 species. (a) Species-specific survival probability were grouped either as adult or juveniles. Solid lines represent adult frogs and dashed lines represent juvenile frogs. Dashed vertical line represents the Vredenburg’s “10,000 zoospore rule” (Kinney et al., 2011). (b) The predicted inflection points for probability of infection that causes 50% mortality. Circles represent adults and triangles represent juveniles.

Figure 5 - Bd-time dependent mortality model

# Extract marginal effects
time_marg_eff <- as.data.frame(ggeffects::ggpredict(time_bd_model, terms = c("lnTime[sample = 50]",
    "life_stage")))

# Create matrix of min and max values per group
time_range <- surv_dat %>%
    dplyr::filter(alive == 0) %>%
    dplyr::group_by(life_stage) %>%
    dplyr::summarise(min = min(lnTime[!is.na(lnTime)]), max = max(lnTime[!is.na(lnTime)])) %>%
    as.data.frame()

# Add min and max values to model df and keep predictions within data range
time_marg_eff$min <- time_range$min[match(time_marg_eff$group, time_range$life_stage)]
time_marg_eff$max <- time_range$max[match(time_marg_eff$group, time_range$life_stage)]
time_marg_eff <- time_marg_eff %>%
    dplyr::group_by(group) %>%
    dplyr::filter(x >= min & x < max) %>%
    dplyr::mutate(life_stage = group, days = exp(x), Bd = exp(predicted))

# Plot
time_bd_plot <- ggplot(data = time_marg_eff, aes(x = x, y = predicted, group = life_stage)) +
    geom_point(data = surv_dat %>%
        dplyr::filter(alive == 0), aes(x = lnTime, y = lnBd, colour = life_stage,
        shape = life_stage), size = 2, alpha = 0.4) + geom_ribbon(aes(x = x, ymin = conf.low,
    ymax = conf.high, fill = life_stage), alpha = 0.1, show.legend = FALSE) + geom_line(aes(colour = life_stage,
    linetype = life_stage), size = 1) + colorspace::scale_colour_discrete_sequential(palette = "Blues 3",
    nmax = 5, order = c(3, 5)) + colorspace::scale_fill_discrete_sequential(palette = "Blues 3",
    nmax = 5, order = c(3, 5)) + ylab("Infection intensity (ln ZE + 1)") + xlab("Time post exposure (ln days)") +
    mytheme() + theme(legend.position = "top")

time_plot <- surv_dat %>%
    dplyr::filter(alive == 0) %>%
    ggplot(aes(x = life_stage, y = lnTime)) + geom_flat_violin(aes(fill = life_stage),
    colour = NA, alpha = 0.5, show.legend = FALSE) + geom_point(aes(shape = life_stage,
    colour = life_stage), size = 1.5) + colorspace::scale_colour_discrete_sequential(palette = "Blues 3",
    nmax = 5, order = c(3, 5)) + colorspace::scale_fill_discrete_sequential(palette = "Blues 3",
    nmax = 5, order = c(3, 5)) + ylab("Time post exposure (ln days)") + xlab(NULL) +
    mytheme() + theme(legend.position = "top")

cowplot::plot_grid(time_bd_plot, time_plot, labels = c("a", "b"), ncol = 2, align = "h",
    axis = "bt", rel_widths = c(1, 0.5))

Fig. 5. (a) Relationship between days post exposure to Bd (ln days) and the infection intensity (ln ZE + 1) at death. Regression lines (solid = adults, dashed = juveniles) represent model estimates and shaded area represents 95% CI. (b) Difference in time to death post-exposure between juvenile and adults.

Supplmentary figures

Fig S8 - Bd-time dependent mortality model

es_all_dat %>%
    ggplot(aes(x = response, y = Zr, colour = trait)) + geom_hline(yintercept = 0,
    linetype = "dashed", alpha = 0.5) + geom_point(aes(shape = life_stage), show.legend = FALSE) +
    viridis::scale_colour_viridis(discrete = TRUE) + xlab(NULL) + ylab(expression("Effect size" ~
    (italic(Z)[r]))) + coord_flip() + facet_wrap(~trait, ncol = 3, scales = "free_y") +
    mytheme() + theme(axis.text = element_text(size = 5), legend.position = "bottom")

Fig. S8. Effect of Bd infection on specific responses across different biological and functional traits. Data presented as individual effect sizes (\(Z_r\)). Circles represent adults and triangles represent juveniles.


References

Berger, L., Hyatt, A. D., Speare, R. and Longcore, J. E. (2005). Life cycle stages of the amphibian chytrid Batrachochytrium dendrobatidis. Diseases of Aquatic Organisms 68, 51–63.
Borenstein, M., Hedges, L. V., Higgins, J. P. and Rothstein, H. R. (2009). Converting among effect sizes. In Introduction to meta-analysis (ed. Borenstein, M.), Hedges, L. V.), Higgins, J. P.), and Rothstein, H. R.), West Sussex, Uk: John Wiley & Sons.
Brannelly, L. A., Berger, L., Marrantelli, G. and Skerratt, L. F. (2015). Low humidity is a failed treatment option for chytridiomycosis in the critically endangered southern corroboree frog. Wildlife Research 42, 44–49.
Brutyn, M., D’Herde, K., Dhaenens, M., Rooij, P. V., Verbrugghe, E., Hyatt, A. D., Croubels, S., Deforce, D., Ducatelle, R. and Haesebrouck, F. (2012). Batrachochytrium dendrobatidis zoospore secretions rapidly disturb intercellular junctions in frog skin. Fungal Genetics and Biology 49, 830–837.
Campbell, C. R., Voyles, J., Cook, D. I. and Dinudom, A. (2012). Frog skin epithelium: Electrolyte transport and chytridiomycosis. International Journal of Biochemistry & Cell Biology 44, 431–434.
Grames, E. M., Stillman, A. N., Tingley, M. W. and Elphick, C. S. (2019). An automated approach to identifying search terms for systematic reviews using keyword co‐occurrence networks. Methods in Ecology and Evolution 10, 1645–1654.
Grogan, L. F., Robert, J., Berger, L., Skerratt, L. F., Scheele, B. C., Castley, J. G., Newell, D. A. and McCallum, H. I. (2018a). Review of the amphibian immune response to chytridiomycosis, and future directions. Frontiers in Immunology 9, 2536.
Grogan, L. F., Skerratt, L. F., Berger, L., Cashins, S. D., Trengove, R. D. and Gummer, J. P. A. (2018b). Chytridiomycosis causes catastrophic organism-wide metabolic dysregulation including profound failure of cellular energy pathways. Scientific reports 8, 1–15.
Hedges, L. V. and Olkin, I. (2014). Statistical methods for meta-analysis. London, UK: Academic Press Inc.
Hillyard, S. D., Møbjerg, N., Tanaka, S. and Larsen, E. H. (2008). Osmotic and ionic regulation in amphibians. In Osmotic and ionic regulation: Cells and animals (ed. Evans, D. H.), FL, USA: CRC Press.
Kindermann, C., Narayan, E. J. and Hero, J.-M. (2017). Does physiological response to disease incur cost to reproductive ecology in a sexually dichromatic amphibian species? Comparative Biochemistry and Physiology Part A: Molecular & Integrative Physiology 203, 220–226.
Lipsey, M. W. and Wilson, D. B. (2001). Practical meta-analysis. SAGE publications, Inc.
Martel, A., Spitzen-van der Sluijs, A., Blooi, M., Bert, W., Ducatelle, R., Fisher, M. C., Woeltjes, A., Bosman, W., Chiers, K. and Bossuyt, F. (2013). Batrachochytrium salamandrivorans sp. nov. causes lethal chytridiomycosis in amphibians. Proceedings of the National Academy of Sciences 110, 15325–15329.
Nakagawa, S. and Cuthill, I. C. (2007). Effect size, confidence interval and statistical significance: A practical guide for biologists. Biological Reviews 82, 591–605.
Nakagawa, S., Lagisz, M., Jennions, M., Koricheva, J., Noble, D. W., Parker, T. H., Sánchez-Tójar, A., Yang, Y. and O’dea, R. E. (2022). Methods for testing publication bias in ecological and evolutionary meta-analyses. Methods in Ecology and Evolution 13, 4–21.
Noble, D. W., Lagisz, M., O’dea, R. E. and Nakagawa, S. (2017). Nonindependence and sensitivity analyses in ecological and evolutionary meta‐analyses. Molecular Ecology 26, 2410–2425.
Ouzzani, M., Hammady, H., Fedorowicz, Z. and Elmagarmid, A. (2016). Rayyan—a web and mobile app for systematic reviews. Systematic reviews 5, 1–10.
Peterson, J. D., Steffen, J. E., Reinert, L. K., Cobine, P. A., Appel, A., Rollins-Smith, L. and Mendonça, M. T. (2013). Host stress response is important for the pathogenesis of the deadly amphibian disease, chytridiomycosis, in Litoria caerulea. PLoS ONE 8, e62146.
Richards-Zawacki, C. L. (2010). Thermoregulatory behaviour affects prevalence of chytrid fungal infection in a wild population of panamanian golden frogs. Proceedings of the Royal Society B: Biological Sciences 277, 519–528.
Rollins-Smith, L. A. and Le Sage, E. H. (2021). Batrachochytrium fungi: Stealth invaders in amphibian skin. Current Opinion in Microbiology 61, 124–132.
Rollins-Smith, L. A., Ramsey, J. P., Pask, J. D., Reinert, L. K. and Woodhams, D. C. (2011). Amphibian immune defenses against chytridiomycosis: Impacts of changing environments. Integrative and Comparative Biology 51, 552–562.
Van Rooij, P., Martel, A., Haesebrouck, F. and Pasmans, F. (2015). Amphibian chytridiomycosis: A review with focus on fungus-host interactions. Veterinary Research 46, 137.
Voyles, J., Berger, L., Young, S., Speare, R., Webb, R., Warner, J., Rudd, D., Campbell, R. and Skerratt, L. F. (2007). Electrolyte depletion and osmotic imbalance in amphibians with chytridiomycosis. Diseases of Aquatic Organisms 77, 113–118.
Voyles, J., Young, S., Berger, L., Campbell, C., Voyles, W. F., Dinudom, A., Cook, D., Webb, R., Alford, R. A. and Skerratt, L. F. (2009). Pathogenesis of chytridiomycosis, a cause of catastrophic amphibian declines. Science 326, 582–585.
Wu, N. C., Cramp, R. L. and Franklin, C. E. (2018). Body size influences energetic and osmoregulatory costs in frogs infected with Batrachochytrium dendrobatidis. Scientific Reports 8, 3739.
Wu, N. C., Cramp, R. L., Ohmer, M. E. and Franklin, C. E. (2019). Epidermal epidemic: Unravelling the pathogenesis of chytridiomycosis. Journal of Experimental Biology 222, jeb191817.



Session Information

R version 4.2.1 (2022-06-23)

Platform: aarch64-apple-darwin20 (64-bit)

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: pander(v.0.6.5), ggraph(v.2.1.0), litsearchr(v.1.0.0), ggnewscale(v.0.4.8), ggtree(v.3.4.1), phytools(v.1.2-0), maps(v.3.4.1), ape(v.5.6-2), rotl(v.3.0.14), ggeffects(v.1.1.4), performance(v.0.10.1), bayestestR(v.0.13.0), rstan(v.2.21.7), StanHeaders(v.2.21.0-7), brms(v.2.18.0), Rcpp(v.1.0.9), cowplot(v.1.1.1), colorspace(v.2.0-3), forcats(v.0.5.2), stringr(v.1.4.1), dplyr(v.1.0.10), purrr(v.0.3.5), readr(v.2.1.3), tidyr(v.1.2.1), tibble(v.3.1.8), ggplot2(v.3.4.0), tidyverse(v.1.3.2), Matrix(v.1.5-3) and knitr(v.1.41)

loaded via a namespace (and not attached): pacman(v.0.5.1), utf8(v.1.2.2), synthesisr(v.0.3.0), tidyselect(v.1.2.0), htmlwidgets(v.1.5.4), grid(v.4.2.1), combinat(v.0.0-8), munsell(v.0.5.0), codetools(v.0.2-18), DT(v.0.26), rentrez(v.1.2.3), miniUI(v.0.1.1.1), withr(v.2.5.0), Brobdingnag(v.1.2-9), highr(v.0.9), rstudioapi(v.0.14), stats4(v.4.2.1), bayesplot(v.1.10.0), labeling(v.0.4.2), emmeans(v.1.8.2), polyclip(v.1.10-4), mnormt(v.2.1.1), optimParallel(v.1.0-2), farver(v.2.1.1), datawizard(v.0.6.4), bridgesampling(v.1.1-2), coda(v.0.19-4), vctrs(v.0.5.1), treeio(v.1.20.1), generics(v.0.1.3), metafor(v.3.8-1), clusterGeneration(v.1.3.7), xfun(v.0.35), timechange(v.0.1.1), R6(v.2.5.1), markdown(v.1.4), graphlayouts(v.0.8.3), cachem(v.1.0.6), gridGraphics(v.0.5-1), assertthat(v.0.2.1), promises(v.1.2.0.1), scales(v.1.2.1), googlesheets4(v.1.0.1), gtable(v.0.3.1), processx(v.3.8.0), phangorn(v.2.10.0), tidygraph(v.1.2.2), rlang(v.1.0.6), scatterplot3d(v.0.3-42), lazyeval(v.0.2.2), stopwords(v.2.3), gargle(v.1.2.1), broom(v.1.0.1), checkmate(v.2.1.0), inline(v.0.3.19), yaml(v.2.3.6), reshape2(v.1.4.4), abind(v.1.4-5), modelr(v.0.1.10), threejs(v.0.3.3), crosstalk(v.1.2.0), backports(v.1.4.1), httpuv(v.1.6.6), tensorA(v.0.36.2), tools(v.4.2.1), bookdown(v.0.30), ggplotify(v.0.1.0), cubature(v.2.0.4.5), ellipsis(v.0.3.2), jquerylib(v.0.1.4), posterior(v.1.3.1), MCMCglmm(v.2.34), plyr(v.1.8.8), base64enc(v.0.1-3), progress(v.1.2.2), ps(v.1.7.2), prettyunits(v.1.1.1), viridis(v.0.6.2), zoo(v.1.8-11), ggrepel(v.0.9.2), haven(v.2.5.1), fs(v.1.5.2), magrittr(v.2.0.3), colourpicker(v.1.2.0), reprex(v.2.0.2), googledrive(v.2.0.0), mvtnorm(v.1.1-3), matrixStats(v.0.63.0), hms(v.1.1.2), patchwork(v.1.1.2), shinyjs(v.2.1.0), mime(v.0.12), evaluate(v.0.18), xtable(v.1.8-4), shinystan(v.2.6.0), XML(v.3.99-0.12), readxl(v.1.4.1), gridExtra(v.2.3), rstantools(v.2.2.0), compiler(v.4.2.1), crayon(v.1.5.2), htmltools(v.0.5.3), corpcor(v.1.6.10), ggfun(v.0.0.9), later(v.1.3.0), tzdb(v.0.3.0), aplot(v.0.1.9), expm(v.0.999-6), RcppParallel(v.5.1.5), lubridate(v.1.9.0), DBI(v.1.1.3), sjlabelled(v.1.2.0), formatR(v.1.12), tweenr(v.2.0.2), dbplyr(v.2.2.1), MASS(v.7.3-58.1), cli(v.3.4.1), quadprog(v.1.5-8), parallel(v.4.2.1), insight(v.0.18.8), igraph(v.1.3.5), pkgconfig(v.2.0.3), rncl(v.0.8.6), numDeriv(v.2016.8-1.1), xml2(v.1.3.3), ngram(v.3.2.2), dygraphs(v.1.1.1.6), bslib(v.0.4.1), stringdist(v.0.9.10), estimability(v.1.4.1), rvest(v.1.0.3), yulab.utils(v.0.0.5), distributional(v.0.3.1), callr(v.3.7.3), digest(v.0.6.30), rmarkdown(v.2.18), cellranger(v.1.1.0), fastmatch(v.1.1-3), tidytree(v.0.4.1), curl(v.4.3.3), shiny(v.1.7.3), gtools(v.3.9.3), lifecycle(v.1.0.3), nlme(v.3.1-160), jsonlite(v.1.8.3), viridisLite(v.0.4.1), fansi(v.1.0.3), pillar(v.1.8.1), lattice(v.0.20-45), loo(v.2.5.1), fastmap(v.1.1.0), httr(v.1.4.4), plotrix(v.3.8-2), pkgbuild(v.1.4.0), glue(v.1.6.2), xts(v.0.12.2), metadat(v.1.2-0), shinythemes(v.1.2.0), ggforce(v.0.4.1), stringi(v.1.7.8), sass(v.0.4.4) and mathjaxr(v.1.6-0)


  1. Hawkesbury Institute for the Environment, Western Sydney University, NSW 2753, Australia, ↩︎

LS0tCnRpdGxlOiAiUGF0aG9nZW4gbG9hZCBwcmVkaWN0cyBob3N0IGZ1bmN0aW9uYWwgZGlzcnVwdGlvbjogQSBtZXRhLWFuYWx5c2lzIG9mIGFuIGFtcGhpYmlhbiBmdW5nYWwgcGFuem9vdGljIgpzdWJ0aXRsZTogIlN1cHBsZW1lbnRhcnkgSW5mb3JtYXRpb24iCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVkLyVtLyVZJylgIgphdXRob3I6CiAgLSBOaWNob2xhcyBDLiBXdV5bSGF3a2VzYnVyeSBJbnN0aXR1dGUgZm9yIHRoZSBFbnZpcm9ubWVudCwgV2VzdGVybiBTeWRuZXkgVW5pdmVyc2l0eSwgTlNXIDI3NTMsIEF1c3RyYWxpYSwgbmljaG9sYXMud3UubnpAZ21haWwuY29tXQpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IHllcwogICAgaGlnaGxpZ2h0OiB0YW5nbwplZGl0b3Jfb3B0aW9uczoKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQpjc2w6IC4vYmliL3RoZS1qb3VybmFsLW9mLWV4cGVyaW1lbnRhbC1iaW9sb2d5LmNzbApiaWJsaW9ncmFwaHk6IC4vYmliL2NoeXRyaWRfcmVmLmJpYgpsaW5rLWNpdGF0aW9uczogdHJ1ZQotLS0KCltHaXRIdWIgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL25pY2hvbGFzd3Vuei9jaHl0cmlkLW1ldGEtYW5hbHlzaXMpICAKVGhlIFJtYXJrZG93biBmaWxlIGNhbiBiZSBkb3dubG9hZGVkIGZyb20gdGhlICpDb2RlKiBkcm9wIGRvd24gbWVudSAodG9wIHJpZ2h0KS4KClRoaXMgc3VwcGxlbWVudGFyeSBmaWxlIGNvbnRhaW5zIHRoZSAqUiogd29ya2Zsb3cgZm9yIHByb2Nlc3NpbmcgYW5kIGFuYWx5c2luZyB0aGUgcmF3IGRhdGEsIGFuZCBjcmVhdGluZyBmaWd1cmVzIGZvciB0aGUgbWFudXNjcmlwdCBJRDogRkUtMjAyMi0wMDYwOCB0aXRsZWQgIioqUGF0aG9nZW4gbG9hZCBwcmVkaWN0cyBob3N0IGZ1bmN0aW9uYWwgZGlzcnVwdGlvbjogQSBtZXRhLWFuYWx5c2lzIG9mIGFuIGFtcGhpYmlhbiBmdW5nYWwgcGFuem9vdGljKioiLgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgY2FjaGUgPSBGQUxTRSwgdGlkeSA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQpvcHRpb25zKGRwbHlyLndpZHRoID0gSW5mLCBrbml0ci5rYWJsZS5OQSA9ICIiLCBkaWdpdHMgPSAyKQoKIyBMb2FkIGxpYnJhcnkKcGFjbWFuOjpwX2xvYWQoTWF0cml4LCB0aWR5dmVyc2UsIGZvcmNhdHMsIGNvbG9yc3BhY2UsIGNvd3Bsb3QsIGJybXMsIHJzdGFuLCBiYXllc3Rlc3RSLCBwZXJmb3JtYW5jZSwgZ2dlZmZlY3RzLCByb3RsLCBhcGUsIHBoeXRvb2xzLCBnZ3RyZWUsIGdnbmV3c2NhbGUsIGxpdHNlYXJjaHIsIGdncmFwaCwgcGFuZGVyKQoKIyBGdW5jdGlvbnMKbXl0aGVtZSA8LSBmdW5jdGlvbigpIHsKICB0aGVtZV9idygpICsKICAgIHRoZW1lKHBhbmVsLmJvcmRlciAgICAgICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG91ciA9ICJibGFjayIpLCAjIHNldCBib3JkZXIgYXJvdW5kIHBsb3QuCiAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yICAgICAgPSBlbGVtZW50X2JsYW5rKCksICMgcmVtb3ZlIG1ham9yIGdyaWQgbGluZXMKICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IgICAgICA9IGVsZW1lbnRfYmxhbmsoKSwgIyByZW1vdmUgbWlub3IgZ3JpZCBsaW5lcwogICAgICAgICAgYXhpcy5saW5lICAgICAgICAgICAgID0gZWxlbWVudF9ibGFuaygpLCAjIHJlbW92ZSBheGlzIGxpbmVzCiAgICAgICAgICBheGlzLnRpY2tzICAgICAgICAgICAgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgICBheGlzLnRleHQgICAgICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvdXIgPSAiYmxhY2siKSwgIyBheGlzIHRleHQgc2l6ZQogICAgICAgICAgYXhpcy50aXRsZSAgICAgICAgICAgID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksICMgYXhpcyB0aXRsZSBzaXplCiAgICAgICAgICBheGlzLnRpdGxlLnkgICAgICAgICAgPSBlbGVtZW50X3RleHQodmp1c3QgPSAzKSwgIyBpbmNyZWFzZSBkaXN0YW5jZSBmcm9tIHRoZSB5LWF4aXMKICAgICAgICAgIGF4aXMudGl0bGUueCAgICAgICAgICA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0xKSwgIyBpbmNyZWFzZSBkaXN0YW5jZSBmcm9tIHRoZSB4LWF4aXMKICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgICAgICA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpLAogICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kICAgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSksICMgcmVtb3ZlIGJhY2tncm91bmQgY29sb3VyCiAgICAgICAgICBwbG90Lm1hcmdpbiAgICAgICAgICAgPSB1bml0KGMoMC4yLCAwLjIsIDAuMiwgMC4yKSwgdW5pdHMgPSAsICJjbSIpLAogICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSksICMgZ2V0IHJpZCBvZiBsZWdlbmQgYmcKICAgICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gTkEpLCAjIGdldCByaWQgb2YgbGVnZW5kIHBhbmVsIGJnCiAgICAgICAgICBzdHJpcC50ZXh0LnggICAgICAgICAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICJibGFjayIsIGZhY2UgPSAiYm9sZCIpLCAjIGZvciBmYWNldCBwbG90cwogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCAgICAgID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3IgPSBOQSkKICAgICkKfSAjIHNldCB1cCBwbG90IHRoZW1lCgpmb3JtYXRfY2VsbHMgPC0gZnVuY3Rpb24oZGYsIHJvd3MgLGNvbHMsIHZhbHVlID0gYygiaXRhbGljcyIsICJib2xkIiwgInN0cmlrZXRocm91Z2giKSl7CiAgIyBzZWxlY3QgdGhlIGNvcnJlY3QgbWFya3VwCiAgIyBvbmUgKiBmb3IgaXRhbGljcywgdHdvICoqIGZvciBib2xkCiAgbWFwIDwtIHNldE5hbWVzKGMoIioiLCAiKioiLCAifn4iKSwgYygiaXRhbGljcyIsICJib2xkIiwgInN0cmlrZXRocm91Z2giKSkKICBtYXJrdXAgPC0gbWFwW3ZhbHVlXSAgCiAgZm9yIChyIGluIHJvd3MpewogICAgZm9yKGMgaW4gY29scyl7CiAgICAgICMgTWFrZSBzdXJlIHZhbHVlcyBhcmUgbm90IGZhY3RvcnMKICAgICAgZGZbW2NdXSA8LSBhcy5jaGFyYWN0ZXIoZGZbW2NdXSkKICAgICAgIyBVcGRhdGUgZm9ybWF0dGluZwogICAgICBkZltyLCBjXSA8LSBwYXN0ZTAobWFya3VwLCBkZltyLCBjXSwgbWFya3VwKQogICAgfQogIH0KICByZXR1cm4oZGYpCn0gIyBBbGxvd3MgdG8gc2VsZWN0IHRoZSBjZWxsIHJvdyBhbmQgY29sdW1ucyB3aGljaCBuZWVkIHRvIGJlIHJlZm9ybWF0dGVkIGFuZCBzZWxlY3QgdGhlIHN0eWxpbmcgdG8gYXBwbHkuCgphZGRwYXJlbnRoZXNlcyA8LSBmdW5jdGlvbih4KXtwYXN0ZSgiKCIsIHgsICIpIil9ICMgYWRkIHBhcmVudGhlc2VzIGJldHdlZW4gd29yZHMKYWRkYnJhY2tldCAgICAgPC0gZnVuY3Rpb24oeCl7cGFzdGUoIlsiLCB4LCAiXSIpfSAjIGFkZCBicmFja2V0cyBiZXR3ZWVuIHdvcmRzCgojIFNldCBvcHRpb25zIGluIFJzdGFuCnNldC5zZWVkKDEwKQpyc3Rhbl9vcHRpb25zKGF1dG9fd3JpdGUgPSBUUlVFKSAjIHRyYW5zbGF0ZSB0byBTVEFOIHBsYXRmb3JtIGZvciBydW5uaW5nIEJheWVzaWFuIG1vZGVsCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkgIyBkZXRlY3RzIGhvdyBtYW55IGNvcmVzIGF2YWlsYWJsZSB0byB1c2UKYGBgCgoqKioKCiMgU3VwcGxlbWVudGFyeSBtZXRob2RzIHstfQoKIyMgQ2h5dHJpZGlvbXljb3NpcyBkaXNlYXNlIGRlc2NyaXB0aW9uIHstfQoKQm90aCBjaHl0cmlkIGZ1bmd1cyBzcGVjaWVzICgqQmF0cmFjaG9jaHl0cml1bSBkZW5kcm9iYXRpZGlzKiwgKkJkKiwgYW5kICpCYXRyYWNob2NoeXRyaXVtIHNhbGFtYW5kcml2b3JhbnMqLCAqQnMqKSBjb2xvbmllcyB0aGUgaG9zdCBza2luIHZpYSBmcmVlLXN3aW1taW5nIG1vdGlsZSB6b29zcG9yZXMgYW5kIGNvbXBsZXRlIHRoZWlyIGxpZmUgY3ljbGUgd2l0aGluIHRoZSBlcGlkZXJtYWwgbGF5ZXIgb2YgdGhlIHNraW4gW0BCZXJnZXIyMDA1OyBATWFydGVsMjAxM10uIFRoZSBjaHl0cmlkIGZ1bmd1cyBhZmZlY3RzIHRoZSBob3N04oCZcyBza2luIGZ1bmN0aW9uIHRocm91Z2ggYm90aCB0aGUgcGh5c2ljYWwgYnJlYWtkb3duIGFuZCBjaGVtaWNhbCBkaXNydXB0aW9uIG9mIHRoZSBlcGlkZXJtaXMgW0BWb3lsZXMyMDA5OyBAQnJ1dHluMjAxMjsgQFd1MjAxOV0uIEJlY2F1c2UgYW1waGliaWFucyByZWx5IGhlYXZpbHkgb24gdGhlaXIgc2tpbiBmb3IgbWFpbnRhaW5pbmcgcGh5c2lvbG9naWNhbCBob21lb3N0YXNpcyBzdWNoIGFzIGVsZWN0cm9seXRlIGFuZCBmbHVpZCBiYWxhbmNlLCBhbmQgcmVzcGlyYXRpb24gW0BIaWxseWFyZDIwMDhdLCB0aGUgcmVzdWx0aW5nIGN1dGFuZW91cyBkaXNydXB0aW9uIGRpcmVjdGx5IGFmZmVjdHMgdGhlIGhvc3TigJlzIGJlaGF2aW91ciBhbmQgcGh5c2lvbG9neSBbQFZveWxlczIwMDc7IEBDYW1wYmVsbDIwMTI7IEBQZXRlcnNvbjIwMTM7IEBWYW5Sb29pajIwMTU7IEBLaW5kZXJtYW5uMjAxN10uIFRoZSBjYXVzZSBvZiBkZWF0aCBpcyBwcm9wb3NlZCB0byBiZSBjYXJkaWFjIGFycmVzdCBkdWUgdG8gbG93IGNpcmN1bGF0aW5nIGlvbiBsZXZlbHMgW0BWb3lsZXMyMDA5XS4gVGhlIHByZXNlbmNlIG9mIHRoZSBjaHl0cmlkIGZ1bmd1cyBhbHNvIGVsaWNpdHMgYSByYW5nZSBvZiBpbW11bm9sb2dpY2FsIHJlc3BvbnNlcyBbQFJvbGxpbnNTbWl0aDIwMTE7IEBHcm9nYW4yMDE4YTsgQFJvbGxpbnNTbWl0aDIwMjFdIHdoaWNoIGluIHR1cm4gYWx0ZXJzIHRoZSBob3N04oCZcyBlbmVyZ3kgbWV0YWJvbGlzbSwgYmVoYXZpb3VyLCBhY3Rpdml0eSBhbmQgbW92ZW1lbnQgcGF0dGVybnMsIGFuZCBib2R5IGNvbmRpdGlvbiBbQFJpY2hhcmRzWmF3YWNraTIwMTA7IEBHcm9nYW4yMDE4YjsgQFd1MjAxOF0uCgojIyBBYnN0cmFjdCBpbmNsdXNpb24gYW5kIGRhdGEgZXhjbHVzaW9uIGNyaXRlcmlhIHstfQoKVGl0bGUgYW5kIGFic3RyYWN0IHNjcmVlbmluZyBvZiAxLDAzOCByZWNvcmRzIGFmdGVyIGR1cGxpY2F0ZXMgd2VyZSByZW1vdmVkIHdhcyBjb25kdWN0ZWQgaW4gUmF5eWFuIFtAT3V6emFuaTIwMTZdLCB3aGVyZSB0aGUgYWJzdHJhY3RzIHdlcmUgc2NyZWVuZWQgZm9yIHdoZXRoZXIgdGhlIHN0dWR5IHBlcmZvcm1lZCBleHBlcmltZW50YWwgaW5mZWN0aW9ucywgd2hldGhlciBhbnVyYW5zIHdlcmUgdGVzdGVkLCBhbmQgd2hldGhlciBhIGZ1bmN0aW9uYWwgdHJhaXQgb3Igc3Vydml2YWwgd2FzIG1lYXN1cmVkLiBJbiB0aGUgZnVsbC10ZXh0IHNjcmVlbmluZywgZGF0YSB3ZXJlIGV4Y2x1ZGVkIGZvciB0aGUgZm9sbG93aW5nIGNyaXRlcmlhOgoKKiBOb24tRW5nbGlzaCBsaXRlcmF0dXJlLCBib29rcyB3aXRob3V0IGxpbmtzIHRvIHByaW1hcnkgc291cmNlLCBhbmQgbm9uLXBlZXItcmV2aWV3ZWQgYXJ0aWNsZXMuCioJU3R1ZGllcyB0aGF0IGV4dHJhY3RlZCAqQmQqIGxvYWQgZnJvbSBkZWFkIGFudXJhbnMgaW4gdGhlIHdpbGQsIGFzIGRlYXRoIGluIHRoZSB3aWxkIG1heSBub3QgYmUgZGlyZWN0bHkgY2F1c2VkIGJ5ICpCZCogZGlyZWN0bHkuCioJU3R1ZGllcyB0aGF0IGRpZCBub3QgcXVhbnRpZnkgKkJkKiBsb2FkLCBhbmQgb25seSBwcmVzZW50ZWQgKkJkKiBwcmV2YWxlbmNlIG9yIGNhdGVnb3JpY2FsIGRldGVjdGlvbiBvZiAqQmQqIChwb3NpdGl2ZSBvciBuZWdhdGl2ZSBkZXRlY3Rpb24pLgoqCVN0dWRpZXMgdGhhdCBjYXBwZWQgKkJkKiBsb2FkIGJhc2VkIG9uIG1heGltdW0gc3RhbmRhcmQgcnVucywgZS5nLiBAQnJhbm5lbGx5MjAxNS4KKglTdHVkaWVzIHRoYXQgZXhwb3NlZCBhbXBoaWJpYW5zIHRvICpCcyosIG9yIGNvLWV4cG9zZWQgKkJkKiB3aXRoICpCcyouCioJRXhwb3NlZCBhbXBoaWJpYW5zIHRvICpCZCogZHVyaW5nIHRoZSBlZ2cgb3IgbGFydmFsIGxpZmUgc3RhZ2UuCioJVHJlYXRtZW50cyB3aXRoIGFkZGl0aW9uYWwgZXhwZXJpbWVudGFsIHN0cmVzc29ycyBlLmcuLCBhZ3JvY2hlbWljYWxzLCBwaGFybWFjZXV0aWNhbHMsIFVWIGV4cG9zdXJlLCBwcmVzZW5jZSBvZiBwcmVkYXRvcnMuCioJRGF0YSBmcm9tIGlzb2xhdGVkIG9yIGN1bHR1cmVkIGNlbGxzICgqaW4tdml0cm8qIHJlc3VsdHMpLCBhcyB0aGV5IGRvIG5vdCBwcm92aWRlIGZ1bmN0aW9uYWxseSByZWxldmFudCByZXNwb25zZXMuCioJTm9uLXF1YW50aWZpYWJsZSB0cmFpdHMgc3VjaCBhcyBoaXN0b2xvZ2ljYWwgc2VjdGlvbnMsIGVsZWN0cm9uLW1pY3Jvc2NvcGUgaW1hZ2VzLCBtdWx0aXZhcmlhdGUgcHJpbmNpcGFsIGNvbXBvbmVudHMgd2l0aCBhcmJpdHJhcnkgdW5pdHMuCioJTW9sZWN1bGFyIHJlc3BvbnNlcyBub3QgZGlyZWN0bHkgcmVsYXRlZCB0byBmdW5jdGlvbmFsIHRyYWl0cyBzdWNoIGFzIHRyYW5zY3JpcHRvbWljcywgcHJvdGVvbWljcywgYW5kIG1STkEgZXhwcmVzc2lvbi4KCiMjIENvbnZlcnNpb24gc3RhdGlzdGljcyB7LX0KVGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50ICgqciopIHdhcyBjYWxjdWxhdGVkIGZyb20gaW5mZXJlbnRpYWwgc3RhdGlzdGljcyB3aXRoIHRoZSBmb2xsb3dpbmcgZXF1YXRpb25zIFxAcmVmKGVxOmNvbnYpIGZyb20gQExpcHNleTIwMDEsIEBOYWthZ2F3YTIwMDcsIGFuZCBATm9ibGUyMDE3OgoKXGJlZ2lue2VxdWF0aW9ufQpyID0gXHNxcnR7W3ReMiAvICh0XjIgKyBkLmYuKV19ID0gXHNxcnR7W0YgLyAoRiArIGQuZi4pXX0gPSBcc3FydHsoXGNoaV4yIC8gbil9LAooXCNlcTpjb252KQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJHQkID0gdC1zdGF0aXN0aWNzLCAkRiQgPSBGLXN0YXRpc3RpY3MsICRkLmYuJCA9IG1vZGVsIGRlbm9taW5hdG9yIGRlZ3JlZXMgb2YgZnJlZWRvbSwgJFxjaGleMiQgPSBjaGktc3F1YXJlZCBzdGF0aXN0aWNzLCBhbmQgJG4kID0gc2FtcGxlIHNpemUuIEVmZmVjdCBzaXplcyBmcm9tIGluZmVyZW50aWFsIHN0YXRpc3RpY3Mgd2VyZSBvbmx5IHJldGFpbmVkIHdoZW4gZGlyZWN0aW9ucyBjb3VsZCBiZSBkZXRlcm1pbmVkIChlLmcuLCAkRiQgYW5kICRcY2hpXjIkIGFsb25lIGRvIG5vdCBjb250YWluIGRpcmVjdGlvbmFsIGluZm9ybWF0aW9uKS4gU3R1ZGllcyB0aGF0IHByZXNlbnRlZCBzdGFuZGFyZGlzZWQgbWVhbiBkaWZmZXJlbmNlcywgYXMgQ29oZW7igJlzICpkKiwgd2VyZSBjb252ZXJ0ZWQgdG8gKnIqIHdpdGggdGhlIGZvbGxvd2luZyBlcXVhdGlvbiBcQHJlZihlcTpkY29udikgZnJvbSBAQm9yZW5zdGVpbjIwMDk6CgpcYmVnaW57ZXF1YXRpb259CnIgPSBcZnJhY3tkfXtcc3FydHtkXjIgKyBhfX0sCihcI2VxOmRjb252KQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgJGEkIGlzIGEgY29ycmVjdGlvbiBmYWN0b3IgXEByZWYoZXE6Y29ycikgZm9yIGNhc2VzIHdoZXJlICRuXzEgXG5lcSBuXzIkLAoKXGJlZ2lue2VxdWF0aW9ufQphID0gXGZyYWN7KG5fMSArIG5fMileMn17bl8xbl8yfSwKKFwjZXE6Y29ycikKXGVuZHtlcXVhdGlvbn0KCmVsc2UsICRhJCA9IDQuCgojIyBLZXl3b3JkIGNvLW9jY3VycmVuY2UgbmV0d29yayBhbmFseXNpcyB7LX0KCkR1cmluZyB0aGUgc3lzdGVtZXRpYyByZXZpZXcsIGEga2V5d29yZCBjby1vY2N1cnJlbmNlIG5ldHdvcmsgYW5hbHlzaXMgd2FzIHBlcmZvcm1lZCB1c2luZyB0aGUgbsOkaXZlIEJvb2xlYW4gc2VhcmNoIGZyb20gV2ViIG9mIFNjaWVuY2UgYW5kIGNpdGF0aW9ucyBpbiBUYWJsZSBTMSBmcm9tIFd1ICgyMDE5KSB1c2luZyB0aGUgYGxpdHNlYXJjaHJgICpSKiBwYWNrYWdlIFtAR3JhbWVzMjAxOV0uCgpgYGB7ciBuZXR3b3JrLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCByZXN1bHRzPSJoaWRlIn0KIyBJbXBvcnQgc2VhcmNoIHJlc3VsdHMgZG93bmxvYWRlZCBmcm9tIEdpdGh1YgpuYWl2ZV9yZXN1bHRzICAgPC0gbGl0c2VhcmNocjo6aW1wb3J0X3Jlc3VsdHMoZmlsZSA9ICIvVXNlcnMvbmljaG9sYXN3dS9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS1XZXN0ZXJuU3lkbmV5VW5pdmVyc2l0eS9DaHl0cmlkIG1ldGEtYW5hbHlzaXMvSW5pdGlhbCBzZWFyY2gvV3VfdGFibGVfcmVmLnR4dCIpCm5haXZlX3Jlc3VsdHNfMiA8LSBsaXRzZWFyY2hyOjppbXBvcnRfcmVzdWx0cyhmaWxlID0gIi9Vc2Vycy9uaWNob2xhc3d1L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVdlc3Rlcm5TeWRuZXlVbml2ZXJzaXR5L0NoeXRyaWQgbWV0YS1hbmFseXNpcy9Jbml0aWFsIHNlYXJjaC9uYWl2ZV9zZWFyY2hfV29TXzIxMTAyOC50eHQiKQoKIyBFeHRyYWN0IHRlcm1zIGZyb20gdGl0bGVzCnRlcm1zX3RpdGxlIDwtIGxpdHNlYXJjaHI6OmV4dHJhY3RfdGVybXModGV4dCA9IG5haXZlX3Jlc3VsdHNbLCAidGl0bGUiXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gImZha2VyYWtlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluX2ZyZXEgPSA0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhfbiA9IDIpCgp0ZXJtc190aXRsZTIgPC0gbGl0c2VhcmNocjo6ZXh0cmFjdF90ZXJtcyh0ZXh0ID0gbmFpdmVfcmVzdWx0c18yWywgInRpdGxlIl0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAiZmFrZXJha2UiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluX2ZyZXEgPSAyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4X24gPSAyKQoKIyBDb21iaW5lIHNlYXJjaCB0ZXJtcyBhbmQgY3JlYXRlIGRvY3VtZW50LWZlYXR1cmUgbWF0cml4IChERk0pCnRlcm1zICAgPC0gdW5pcXVlKGModGVybXNfdGl0bGUsIHRlcm1zX3RpdGxlMikpICMgQ29tYmluZSBib3RoIHRlcm0gZmlsZXMKZG9jcyAgICA8LSB1bmlxdWUoYyhuYWl2ZV9yZXN1bHRzWywgInRpdGxlIl0sIG5haXZlX3Jlc3VsdHNfMlssICJ0aXRsZSJdKSkgIyBleHRyYWN0IHRpdGxlcwpkZm0gICAgIDwtIGxpdHNlYXJjaHI6OmNyZWF0ZV9kZm0oZWxlbWVudHMgPSBkb2NzLCBmZWF0dXJlcyA9IHRlcm1zKSAjIGNyZWF0ZSBkZm0KbmV0d29yayA8LSBsaXRzZWFyY2hyOjpjcmVhdGVfbmV0d29yayhkZm0sIG1pbl9zdHVkaWVzID0gNSkKCiMgUHJ1bmluZwpzdHJlbmd0aHMgICAgICA8LSBpZ3JhcGg6OnN0cmVuZ3RoKG5ldHdvcmspCnRlcm1fc3RyZW5ndGhzIDwtIGRhdGEuZnJhbWUodGVybSA9IG5hbWVzKHN0cmVuZ3RocyksIHN0cmVuZ3RoID0gc3RyZW5ndGhzLCByb3cubmFtZXMgPSBOVUxMKSAlPiUKICBkcGx5cjo6bXV0YXRlKHJhbmsgPSByYW5rKHN0cmVuZ3RoLCB0aWVzLm1ldGhvZCA9ICJtaW4iKSkgJT4lCiAgZHBseXI6OmFycmFuZ2Uoc3RyZW5ndGgpCmBgYAoKCmBgYHtyIEZpZyBTMSwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD03LCBtZXNzYWdlPUZBTFNFfQojIFBsb3QgbmV0d29yawpmaWdTMWEgPC0gZ2dyYXBoOjpnZ3JhcGgobmV0d29yaywgbGF5b3V0ID0gInN0cmVzcyIpICsKICBjb29yZF9maXhlZCgpICsKICBleHBhbmRfbGltaXRzKHggPSBjKC0yLCAxMCkpICsKICBnZ3JhcGg6Omdlb21fZWRnZV9saW5rKGFlcyhhbHBoYSA9IHdlaWdodCkpICsKICBnZ3JhcGg6Omdlb21fbm9kZV9wb2ludChzaGFwZSA9ICJjaXJjbGUgZmlsbGVkIiwgZmlsbCA9ICJ3aGl0ZSIpICsKICBnZ3JhcGg6Omdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IG5hbWUpLCBoanVzdCA9ICJvdXR3YXJkIiwgCiAgICAgICAgICAgICAgICAgbnVkZ2VfeCA9IC0wLjA1LCBzaXplID0gMi41LCBjaGVja19vdmVybGFwID0gVFJVRSkgKwogIGd1aWRlcyhlZGdlX2FscGhhID0gIm5vbmUiKSArCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkKCiMgUGxvdCBzdHJlbmd0aApmaWdTMWIgPC0gZ2dwbG90KHRlcm1fc3RyZW5ndGhzLCBhZXMoeCA9IHJhbmssIHkgPSBzdHJlbmd0aCwgbGFiZWwgPSB0ZXJtKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KHNoYXBlID0gImNpcmNsZSBmaWxsZWQiLCBmaWxsID0gIndoaXRlIikgKwogIGdlb21fdGV4dChkYXRhID0gZHBseXI6OmZpbHRlcih0ZXJtX3N0cmVuZ3RocywgcmFuayA+IDUpLCBoanVzdCA9ICJyaWdodCIsIAogICAgICAgICAgICBzaXplID0gMi41LCBudWRnZV95ID0gMzAsIGNoZWNrX292ZXJsYXAgPSBUUlVFKSArCiAgeWxhYigiQ28tb2NjdXJhbmNlIHN0cmVuZ3RoIikgKyB4bGFiKCJSYW5rIikgKwogIG15dGhlbWUoKQoKY293cGxvdDo6cGxvdF9ncmlkKGZpZ1MxYSwgZmlnUzFiLCBuY29sID0gMSwgbGFiZWxzID0gYygiYSIsICJiIikpCmBgYAoKKipGaWcuIFMxLioqIE91dHB1dCBmcm9tIHRoZSBrZXl3b3JkIGNvLW9jY3VycmVuY2UgbmV0d29yayBhbmFseXNpcy4gKCoqYSoqKSBWaXN1YWxpc2F0aW9uIG9mIHRoZSBuZXR3b3JrIHdoZXJlIGVhY2ggbm9kZSByZXByZXNlbnRzIGEgdGVybSwgYW5kIHRoZSBsaW5lIHRoaWNrbmVzcyByZXByZXNlbnRzIHRoZSB3ZWlnaHQgb2YgbGlua2luZyBub2RlcywgaS5lLiwgdGhlIHRlcm1zIGFwcGVhcmluZyBpbiBtb3JlIGFydGljbGVzIHRvZ2V0aGVyLiAoKipiKiopIFRoZSBzdHJlbmd0aCBvZiBlYWNoIHRlcm0gaW4gYXNjZW5kaW5nIG9yZGVyIGZyb20gbGVmdCB0byByaWdodC4gCgojIyBQUklTTUEgZmxvdy1kaWFncmFtIHstfQoKIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uaWNob2xhc3d1bnovY2h5dHJpZC1tZXRhLWFuYWx5c2lzL21haW4vZmlsZXMvRmlnJTIwUzIlMjAtJTIwUFJJU01BJTIwZGlhZ3JhbS5wbmcpCgoqKkZpZy4gUzIuKiogUFJJU01BIGZsb3cgZGlhZ3JhbSBmb3IgdGhlIHN5c3RlbWF0aWMgZGF0YS1jb2xsZWN0aW9uIHByb2Nlc3MuICpuKiA9IG51bWJlciBvZiBwYXBlcnMgcmVtYWluaW5nIGFmdGVyIGVhY2ggc3RhZ2Ugb2Ygc2VsZWN0aW9uLiAqayogPSBudW1iZXIgb2YgZWZmZWN0IHNpemUgYWZ0ZXIgcHJvY2Vzc2luZyBpbmRpdmlkdWFsIGRhdGEsIGFuZCAqbiogaXMgbnVtYmVyIG9mIG9ic2VydmF0aW9ucy9yZWNvcmRzIGFmdGVyIHByb2Nlc3NpbmcgZGF0YS4gRGFzaGVkIGJveGVzIGluZGljYXRlIEJvb2xlYW4gc2VhcmNoIHN0cmluZyBmb3IgV2ViIG9mIFNjaWVuY2UgYW5kIFNjb3B1cy4gCgoqKioKIyBEYXRhc2V0IHstfQoKIyMgQ2FsY3VsYXRlIGVmZmVjdCBzaXplLCAkWl9yJCwgYW5kIHNhbXBsaW5nIHZhcmlhbmNlLCAkdihaX3IpJCB7LX0KClRoZSByYXcgZGF0YSBmb3IgYW5hbHlzaXMgaXMgYXZhaWxhYmxlIG9uIFtHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9uaWNob2xhc3d1bnovY2h5dHJpZC1tZXRhLWFuYWx5c2lzKS4gVGhpcyBzZWN0aW9uIGlzIHRoZSB3b3JrZmxvdyB0byBpbXBvcnQgYW5kIGNsZWFuIHRoZSByYXcgZGF0YSBmb3IgYW5hbHlzaXMuIERhdGEgd2VyZSBzZXBhcmF0ZWQgYnkgcmF3IGRhdGEsIGNvcnJlbGF0aW9uIGRhdGEsIGFuZCBzdXJ2aXZhbCBkYXRhLiBUaGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgYW5kIHNhbXBsZSBzaXplIHdhcyBjYWxjdWxhdGVkIGZyb20gdGhlIHJhdyBkYXRhIGFuZCBtZXJnZWQgd2l0aCB0aGUgY29ycmVsYXRpb24gZGF0YSAoYGVzX2FsbF9kYXRgKS4KCkVmZmVjdCBzaXplIGFzIHRoZSBGaXNoZXIgei10cmFuc2Zvcm1hdGlvbiBvZiB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgKnIqLCAkWl9yJCBcQHJlZihlcTpaciksIGFuZCB0aGUgc2FtcGxpbmcgdmFyaWFuY2UsICR2KFpfcikkIFxAcmVmKGVxOlpydiksIHdhcyBjYWxjdWxhdGVkIGZvbGxvd2luZyBASGVkZ2VzMjAxNDoKClxiZWdpbntlcXVhdGlvbn0KWl9yID0gXGZyYWN7MX17Mn1sbiBcbGVmdCggXGZyYWN7MStyfXsxLXJ9XHJpZ2h0KSwKKFwjZXE6WnIpClxlbmR7ZXF1YXRpb259CgpcYmVnaW57ZXF1YXRpb259CnYoWl9yKSA9IFxmcmFjezF9e24gLSAzfSwKKFwjZXE6WnJ2KQpcZW5ke2VxdWF0aW9ufQoKd2hlcmUgKnIqIGlzIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCwgYW5kICpuKiBpcyB0aGUgc2FtcGxpbmcgc2l6ZS4gVGhlICoqc3RhbmRhcmQgZXJyb3IqKiwgJHNlX2kkIFxAcmVmKGVxOlpyc2VpKSwgd2FzIGNhbGN1bGF0ZWQgYXM6CgpcYmVnaW57ZXF1YXRpb259CnNlX3tpfSA9IFxmcmFjezF9e1xzcXJ0e24gLSAzfX0uCihcI2VxOlpyc2VpKQpcZW5ke2VxdWF0aW9ufQoKVGhlIGludmVyc2Ugb2YgJHNlX2kkIG9yICoqcHJlY2lzaW9uKiogXEByZWYoZXE6WnJpbnYpIHdhcyBjYWxjdWxhdGVkIGFzOgoKXGJlZ2lue2VxdWF0aW9ufQpwX3tpfSA9IFxmcmFjezF9e3NlX2l9LgooXCNlcTpacmludikKXGVuZHtlcXVhdGlvbn0KClRoZSBpbnZlcnNlIG9mIHNhbXBsaW5nIHZhcmlhbmNlIG9yICoqd2VpZ2h0KiogXEByZWYoZXE6WnJ3KSBmb3IgY2FsY3VsYXRpbmcgaGV0ZXJvZ2VuZWl0eToKClxiZWdpbntlcXVhdGlvbn0Kd197aX0gPSBcZnJhY3sxfXt2KFpfcil9LgooXCNlcTpacncpClxlbmR7ZXF1YXRpb259CgpBbGwgY29udmVyc2lvbnMgZm9yIHRoZSBzdGFuZGFyZCBlcnJvciAoJHNlX2kkKSwgc2FtcGxpbmcgdmFyaWFuY2UsIHByZWNpc2lvbiAodGhlIGludmVyc2Ugb2YgJHNlX2kkKSBhbmQgd2VpZ2h0ICh0aGUgaW52ZXJzZSBvZiB2YXJpYW5jZSkgZm9sbG93ZWQgQE5ha2FnYXdhMjAyMi4KCmBgYHtyIGNsZWFuLCBtZXNzYWdlPUZBTFNFfQojIExvYWQgYW5kIGNsZWFuIHJhdyBkYXRhCnRyYWl0X2RhdCA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25pY2hvbGFzd3Vuei9jaHl0cmlkLW1ldGEtYW5hbHlzaXMvbWFpbi9kYXRhL3RyYWl0X3Jhd19kYXRhLmNzdiIpICAlPiUgCiAgZHBseXI6OmZpbHRlcih0cmFpdCAhPSAiU3Vydml2YWwiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzX09UTCA9IGFzLmZhY3RvcihzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICB0cmFpdF92YWx1ZSA9IGFzLm51bWVyaWModHJhaXRfdmFsdWUpLAogICAgICAgICAgICAgICAgdHJhaXQgICAgICAgPSBhcy5mYWN0b3IodHJhaXQpLAogICAgICAgICAgICAgICAgUENSX21ldGggICAgPSBhcy5mYWN0b3IoUENSX21ldGgpLAogICAgICAgICAgICAgICAgcmVzcG9uc2UgICAgPSBhcy5mYWN0b3IocmVzcG9uc2UpLAogICAgICAgICAgICAgICAgbG5Eb3NlICAgICAgPSBsb2coZG9zZV9aRV9tbCArIDEpLAogICAgICAgICAgICAgICAgbG5CZCAgICAgICAgPSBsb2coQmQgKyAxKSwKICAgICAgICAgICAgICAgIHRlbXBfSyAgICAgID0gdHJ0X3RlbXAgKyAyNzMuMTUsICMgY29udmVydCB0ZW1wZXJhdHVyZSBDZWxjaXVzIHRvIEtlbHZpbgogICAgICAgICAgICAgICAgaW52X3RlbXAgICAgPSAxIC8gOC42MmUtNSAgKiAoMSAvIG1lYW4odGVtcF9LLCBuYS5ybSA9IFRSVUUpIC0gMSAvIHRlbXBfSykgIyBzdGFuZGFyZGlzZSB0byBtZWFuIHRlbXAsIEJvbHR6bWFubiBjb25zdGFudCBhcyBlVi9LCiAgKSAlPiUKICBkcGx5cjo6c2VsZWN0KC1vbmVfb2YoYygibm90ZXMiLCAidGl0bGUiLCAicmVmIikpKQoKIyBDbGVhbiBlZmZlY3Qgc2l6ZSBkYXRhCmVzX2RhdCA8LSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25pY2hvbGFzd3Vuei9jaHl0cmlkLW1ldGEtYW5hbHlzaXMvbWFpbi9kYXRhL3RyYWl0X2NvcnJfZGF0YS5jc3YiKSAgJT4lIAogIGRwbHlyOjptdXRhdGUoc3R1ZHlfSUQgICAgPSBpZmVsc2Uobm90ZXMgPT0gInJlcGVhdGVkIiwgc3R1ZHlfSUQsIHN0dWR5X0lEICsgbWF4KHRyYWl0X2RhdCRzdHVkeV9JRCkpLAogICAgICAgICAgICAgICAgc3BlY2llc19PVEwgPSBhcy5mYWN0b3Ioc3BlY2llc19PVEwpLAogICAgICAgICAgICAgICAgbG5Eb3NlICAgICAgPSBsb2coZG9zZV9aRV9tbCArIDEpLAogICAgICAgICAgICAgICAgbG5CZCAgICAgICAgPSBsb2coQmQgKyAxKSwKICAgICAgICAgICAgICAgIHJlc2lzdGFuY2UgID0gYXMuZmFjdG9yKHJlc2lzdGFuY2UpLAogICAgICAgICAgICAgICAgdHJhaXQgICAgICAgPSBhcy5mYWN0b3IodHJhaXQpLAogICAgICAgICAgICAgICAgcmVzcG9uc2UgICAgPSBhcy5mYWN0b3IocmVzcG9uc2UpLAogICAgICAgICAgICAgICAgWnIgICAgICAgICAgPSAoMSAvIDIpICogbG9nKCgxICsgY29ycl9jb2VmZikgLyAoMSAtIGNvcnJfY29lZmYpKSwgIyBGaXNoZXItdHJhbnNmb3JtZWQgY29ycmVsYXRpb24gY29lZmZpY2llbnQKICAgICAgICAgICAgICAgIFpyX3YgICAgICAgID0gMSAvIChzYW1wbGVfc2l6ZSAtIDMpLCAjIHNhbXBsaW5nIHZhcmlhbmNlICh2KQogICAgICAgICAgICAgICAgWnJfc2VpICAgICAgPSAxIC8gc3FydChzYW1wbGVfc2l6ZSAtIDMpLCAjIHN0YW5kYXJkIGVycm9yIChTRSkKICAgICAgICAgICAgICAgIFpyX2ludiAgICAgID0gMSAvIFpyX3NlaSwgIyBwcmVjaXNpb24gKGludmVyc2Ugb2YgU0UpIAogICAgICAgICAgICAgICAgWnJfdyAgICAgICAgPSAxIC8gWnJfdikgJT4lICMgd2VpZ2h0IChpbnZlcnNlIG9mIFpyX3YpKQogIGRwbHlyOjpzZWxlY3QoLW9uZV9vZihjKCJub3RlcyIsICJ0aXRsZSIsICJyZWYiKSkpCgojIENsZWFuIHN1cnZpdmFsIGRhdGEKc3Vydl9kYXQgPC0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uaWNob2xhc3d1bnovY2h5dHJpZC1tZXRhLWFuYWx5c2lzL21haW4vZGF0YS90cmFpdF9yYXdfZGF0YS5jc3YiKSAgJT4lIAogIGRwbHlyOjpmaWx0ZXIodHJhaXQgPT0gIlN1cnZpdmFsIikgJT4lIAogIGRwbHlyOjptdXRhdGUoc3BlY2llc19PVEwgPSBhcy5mYWN0b3Ioc3BlY2llc19PVEwpLAogICAgICAgICAgICAgICAgcmVzaXN0YW5jZSAgPSBhcy5mYWN0b3IocmVzaXN0YW5jZSksCiAgICAgICAgICAgICAgICBsaWZlX3N0YWdlICA9IGFzLmZhY3RvcihsaWZlX3N0YWdlKSwKICAgICAgICAgICAgICAgIGxuRG9zZSAgICAgID0gbG9nKGRvc2VfWkVfbWwgKyAxKSwKICAgICAgICAgICAgICAgIGxuQmQgICAgICAgID0gbG9nKEJkICsgMSksCiAgICAgICAgICAgICAgICBsbk1hc3MgICAgICA9IGxvZyhtYXNzX2cpLAogICAgICAgICAgICAgICAgbG5UaW1lICAgICAgPSBsb2codGltZV9wb3N0X2RheXMpLAogICAgICAgICAgICAgICAgdGVtcF9LICAgICAgPSB0cnRfdGVtcCArIDI3My4xNSwgIyBjb252ZXJ0IHRlbXBlcmF0dXJlIENlbGNpdXMgdG8gS2VsdmluCiAgICAgICAgICAgICAgICBpbnZfdGVtcCAgICA9IDEgLyA4LjYyZS01ICAqICgxIC8gbWVhbih0ZW1wX0ssIG5hLnJtID0gVFJVRSkgLSAxIC8gdGVtcF9LKSwgIyBzdGFuZGFyZGlzZSB0byBtZWFuIHRlbXAsIEJvbHR6bWFubiBjb25zdGFudCBhcyBlVi9LCiAgICAgICAgICAgICAgICBhbGl2ZSAgICAgICA9IGlmZWxzZSh0cmFpdF92YWx1ZSA9PSAiQWxpdmUiLCAxLCAwKSkgJT4lCiAgdGlkeXI6OnVuaXRlKCJzcGVjaWVzX2xpZmVzdGFnZSIsIGMoInNwZWNpZXMiLCAibGlmZV9zdGFnZSIpLCBzZXAgPSAiXyIsIHJlbW92ZSA9IEZBTFNFKSAlPiUKICBkcGx5cjo6c2VsZWN0KC1vbmVfb2YoYygibm90ZXMiLCAidGl0bGUiLCAicmVmIikpKSAKCiMgRm9yIHJhdyBkYXRhICh0cmFpdF9kYXQpLCBjYWxjdWxhdGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQsIHRoZW4gY2FsY3VsYXRlIGVmZmVjdCBzaXplCmVmZmVjdF9zaXplX2RhdCA8LSBhcy5kYXRhLmZyYW1lKHRyYWl0X2RhdCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KHN0dWR5X0lELCBiaW9faGllciwgdHJhaXQsIHNwZWNpZXMsIHJlc3BvbnNlKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShjb3JyX2NvZWZmICAgICA9IGNvcihCZCwgdHJhaXRfdmFsdWUsIG1ldGhvZCA9ICJwZWFyc29uIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlX3NpemUgICAgPSBsZW5ndGgodHJhaXRfdmFsdWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhvcl9maXJzdCAgID0gdW5pcXVlKGF1dGhvcl9maXJzdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhciAgICAgICAgICAgPSBtZWRpYW4oeWVhciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFjdGVkICAgICAgPSB1bmlxdWUoZXh0cmFjdGVkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmRlciAgICAgICAgICA9IHVuaXF1ZShvcmRlciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5ICAgICAgICAgPSB1bmlxdWUoZmFtaWx5KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzICAgICAgICA9IHVuaXF1ZShzcGVjaWVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzX09UTCAgICA9IHVuaXF1ZShzcGVjaWVzX09UTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luICAgICAgICAgPSB1bmlxdWUob3JpZ2luKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXR0aW5nICAgICAgICA9IHVuaXF1ZShzZXR0aW5nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaWZlX3N0YWdlICAgICA9IHVuaXF1ZShsaWZlX3N0YWdlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJhaW4gICAgICAgICA9IHVuaXF1ZShzdHJhaW4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW5fbWFzc19nICAgID0gbWVhbihtYXNzX2cpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydF90ZW1wICAgICAgID0gbWVhbih0cnRfdGVtcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9zZV9aRV9tbCAgICAgPSBtZWFuKGRvc2VfWkVfbWxbZG9zZV9aRV9tbCAhPSAwXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmQgICAgICAgICAgICAgPSBtZWFuKEJkW0JkICE9IDBdKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lX3Bvc3RfZGF5cyA9IG1lZGlhbih0aW1lX3Bvc3RfZGF5c1tCZCAhPSAwXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG5CZCAgICAgICAgICAgPSBtZWFuKGxuQmRbbG5CZCAhPSAwXSkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKFpyICAgICA9ICgxIC8gMikgKiBsb2coKDEgKyBjb3JyX2NvZWZmKSAvICgxIC0gY29ycl9jb2VmZikpLCAjIEZpc2hlci10cmFuc2Zvcm1lZCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudAogICAgICAgICAgICAgICAgWnJfdiAgID0gMSAvIChzYW1wbGVfc2l6ZSAtIDMpLCAjIHNhbXBsaW5nIHZhcmlhbmNlICh2KQogICAgICAgICAgICAgICAgWnJfc2VpID0gMSAvIHNxcnQoc2FtcGxlX3NpemUgLSAzKSwgIyBzdGFuZGFyZCBlcnJvciAoU0UpCiAgICAgICAgICAgICAgICBacl9pbnYgPSAxIC8gWnJfc2VpLCAjIHByZWNpc2lvbiAoaW52ZXJzZSBvZiBTRSkgMAogICAgICAgICAgICAgICAgWnJfdyAgID0gMSAvIFpyX3YsICMgd2VpZ2h0IChpbnZlcnNlIG9mIFpyX3YpCiAgICAgICAgICAgICAgICBaciAgICAgPSBpZmVsc2UocmVzcG9uc2UgJWluJSBjKCJFdmFwb3JhdGl2ZSB3YXRlciBsb3NzIiwgIkFRUCBhY3Rpdml0eSIsICJTa2luIHBlcm1lYWJpbGl0eSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ3V0YW5lb3VzIGlvbiBsb3NzJywgJ011c2NsZSB3YXRlciBjb250ZW50JywgIkNhc3Bhc2UgYWN0aXZpdHkiKSwgLWFicyhaciksIFpyKSkgCgojIENvbWJpbmUgZWZmZWN0IHNpemUgZGF0YXNldAplc19hbGxfZGF0IDwtIGJpbmRfcm93cyhlZmZlY3Rfc2l6ZV9kYXQsIGVzX2RhdCkgJT4lCiAgdGliYmxlOjpyb3dpZF90b19jb2x1bW4oImVzX0lEIikgJT4lICMgYWRkIGVmZmVjdCBzaXplIElECiAgZHBseXI6Om11dGF0ZSh5ZWFyX2NlbnRyZSA9IHllYXIgLSBtZWFuKHllYXIpKSAjIG1lYW4tY2VudHJpbmcgeWVhciBvZiBwdWJsaWNhdGlvbikKYGBgCgojIyBEYXRhIHN1bW1hcnkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0KClRoZSBgZXNfYWxsX2RhdGAgdXNlZCBmb3IgdGhlIG1ldGEtYW5hbHlzaXMgY29tcHJpc2VzIG9mIGByIG5yb3coZXNfYWxsX2RhdClgIGluZGl2aWR1YWwgZWZmZWN0IHNpemVzIGZyb20gYHIgbGVuZ3RoKHVuaXF1ZShlc19hbGxfZGF0JHN0dWR5X0lEKSlgIHN0dWRpZXMgYWNyb3NzIGByIGxlbmd0aCh1bmlxdWUoZXNfYWxsX2RhdCRzcGVjaWVzX09UTCkpYCBzcGVjaWVzIChkZXRhaWxlZCBpbiAqKlN1cHBsZW1lbnRhcnkgVGFibGUgUzEqKikuCgojIyMgVGFibGUgUzEgLSBTdW1tYXJ5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMSAtIFJlc3BvbnNlcy4qKiBUcmFpdCBjYXRlZ29yaWVzIGFzc29jaWF0ZWQgd2l0aCAqQmQqIGluZmVjdGlvbiBhbmQgdGhlIHNwZWNpZmljIHJlc3BvbnNlcyB3aXRoaW4gdGhlc2UgdHJhaXRzLiBOdW1iZXIgb2YgZWZmZWN0IHNpemVzLCBzdHVkaWVzIGFuZCBzcGVjaWVzIGFyZSBzaG93bi4gUmVzcG9uc2VzIHdpdGggYXN0ZXJpc2tzIHdlcmUgY29ycmVjdGVkIGZvciBkaXJlY3Rpb24uIEFRUCA9IGFxdWFwb3JpbnMsIEVOYUMgPSBlcGl0aGVsaWFsIHNvZGl1bSBjaGFubmVsLCBOS0EgPSBzb2RpdW0gcG90YXNzaXVtIHB1bXAsICpDVH5tYXh+KiA9IGNyaXRpY2FsIHRoZXJtYWwgbWF4aW1hLCAqQ1R+bWlufiogPSBjcml0aWNhbCB0aGVybWFsIG1pbmltYS4KCmBgYHtyIHRhYmxlUzFhLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQp0YWJsZVMxIDwtIGRhdGEuZnJhbWUoZXNfYWxsX2RhdCAlPiUgCiAgZHBseXI6Omdyb3VwX2J5KHRyYWl0LCByZXNwb25zZSkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UoZWZfbiA9IG4oKSwKICAgICAgICAgICAgICAgICAgIHN0dWR5X24gPSBsZW5ndGgodW5pcXVlKHN0dWR5X0lEKSksCiAgICAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsZW5ndGgodW5pcXVlKHNwZWNpZXMpKSkpICU+JQogIGRwbHlyOjptdXRhdGUocmVzcG9uc2UgPSBjYXNlX3doZW4oCiAgICByZXNwb25zZSAlaW4lICJCb2R5IGNvbmRpdGlvbiIgfiAiQm9keSBjb25kaXRpb24gKHJlc2lkdWFsIG9yIGluZGV4KSIsCiAgICByZXNwb25zZSAlaW4lICJCb2R5IHNpemUiIH4gIkJvZHkgc2l6ZSAoYm9keSBtYXNzIG9yIHNub3V0LXZlbnQtbGVuZ3RoKSIsCiAgICByZXNwb25zZSAlaW4lICJCbG9vZCBDTzIiIH4gIkJsb29kIENPfjJ+IiwKICAgIHJlc3BvbnNlICVpbiUgIkJkLWFudGlib2RpZXMiIH4gIipCZCotYW50aWJvZGllcyIsCiAgICByZXNwb25zZSAlaW4lICJML04gcmF0aW8iIH4gIkx5bXBob2N5dGUvbmV1dHJvcGhpbCByYXRpbyIsCiAgICByZXNwb25zZSAlaW4lICJOL0wgcmF0aW8iIH4gIk5ldXRyb3BoaWwvbHltcGhvY3l0ZSByYXRpbyIsCiAgICByZXNwb25zZSAlaW4lICJDdXRhbmVvdXMgaW9uIGxvc3MiIH4gIkN1dGFuZW91cyBpb24gbG9zcyoiLAogICAgcmVzcG9uc2UgJWluJSAiRXZhcG9yYXRpdmUgd2F0ZXIgbG9zcyIgfiAiRXZhcG9yYXRpdmUgd2F0ZXIgbG9zcyoiLAogICAgcmVzcG9uc2UgJWluJSAiQ2FzcGFzZSBhY3Rpdml0eSIgfiAiQ2FzcGFzZSBhY3Rpdml0eSoiLAogICAgcmVzcG9uc2UgJWluJSAiU2tpbiBwZXJtZWFiaWxpdHkiIH4gIlNraW4gcGVybWVhYmlsaXR5KiIsCiAgICByZXNwb25zZSAlaW4lICJTa2luIHNoZWRzIiB+ICJTa2luIHNoZWRzKiIsCiAgICByZXNwb25zZSAlaW4lICJDVG1heCIgfiAiKkNUfm1heH4qIiwKICAgIHJlc3BvbnNlICVpbiUgIkNUbWluIiB+ICIqQ1R+bWlufioiLAogICAgVFJVRSB+IGFzLmNoYXJhY3RlcihyZXNwb25zZSkpKQogIAojIFByZXBhcmUgY29sdW1uIG5hbWVzIHdpdGggTGFUZVgKdGFibGVTMSAlPiUKICBkcGx5cjo6cmVuYW1lKCJDYXRlZ29yaXNlZCB0cmFpdCIgPSB0cmFpdCwKICAgICAgICAgICAgICAgICJTcGVjaWZpYyByZXBvbnNlIiAgPSByZXNwb25zZSwKICAgICAgICAgICAgICAgICJFZmZlY3Qgc2l6ZSAoKmsqKSIgPSBlZl9uLAogICAgICAgICAgICAgICAgIlN0dWRpZXMgKCpuKikiICAgICA9IHN0dWR5X24sCiAgICAgICAgICAgICAgICAiU3BlY2llcyAoKm4qKSIgICAgID0gc3BlY2llc19uKSAlPiUKICBrbml0cjo6a2FibGUoKSAKYGBgCgojIyMgTGlmZSBzdGFnZSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzEgLSBMaWZlIHN0YWdlLioqIENvbnRpbnVhdGlvbiBvZiBkYXRhIHN1bW1hcnkgd2l0aCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9uIHRoZSBudW1iZXIgb2YgZWZmZWN0IHNpemUsIHN0dWRpZXMsIGFuZCBzcGVjaWVzIGluIHRoZSBkYXRhYmFzZSBieSBsaWZlIHN0YWdlIChhZHVsdCBvciBKdXZlbmlsZSkuIAoKYGBge3IgdGFibGVTMWIsIGVjaG89RkFMU0V9CmRhdGEuZnJhbWUoZXNfYWxsX2RhdCAlPiUgCiAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkobGlmZV9zdGFnZSkgJT4lIAogICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZShlZl9uICAgID0gbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHVkeV9uID0gbGVuZ3RoKHVuaXF1ZShzdHVkeV9JRCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjaWVzX24gPSBsZW5ndGgodW5pcXVlKHNwZWNpZXMpKSkpICU+JQogIGRwbHlyOjphcnJhbmdlKC1lZl9uKSAlPiUKICBkcGx5cjo6cmVuYW1lKCJMaWZlIHN0YWdlIiAgICAgICAgPSBsaWZlX3N0YWdlLAogICAgICAgICAgICAgICAgIkVmZmVjdCBzaXplICgqayopIiA9IGVmX24sCiAgICAgICAgICAgICAgICAiU3R1ZGllcyAoKm4qKSIgICAgID0gc3R1ZHlfbiwKICAgICAgICAgICAgICAgICJTcGVjaWVzICgqbiopIiAgICAgPSBzcGVjaWVzX24pICU+JQogIGtuaXRyOjprYWJsZSgpCmBgYAoKIyMjIFNwZWNpZXMgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFMxIC0gU3BlY2llcy4qKiBDb250aW51YXRpb24gb2YgZGF0YSBzdW1tYXJ5IHdpdGggYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBvbiB0aGUgbnVtYmVyIG9mIGVmZmVjdCBzaXplLCBhbmQgc3R1ZGllcyBpbiB0aGUgZGF0YWJhc2UgYnkgc3BlY2llcy4gCgpgYGB7ciB0YWJsZVMxYywgZWNobz1GQUxTRX0KZGF0YS5mcmFtZShlc19hbGxfZGF0ICU+JSAKICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShzcGVjaWVzKSAlPiUgCiAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKGVmX24gICAgPSBuKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0dWR5X24gPSBsZW5ndGgodW5pcXVlKHN0dWR5X0lEKSkpKSAlPiUKICBmb3JtYXRfY2VsbHMoMTo1MiwgMSwgIml0YWxpY3MiKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNwZWNpZXMgPSBzdHJfcmVwbGFjZShzcGVjaWVzLCAiXyIsICIgIikpICU+JQogIGRwbHlyOjphcnJhbmdlKC1lZl9uKSAlPiUKICBkcGx5cjo6cmVuYW1lKCJTcGVjaWVzIiAgICAgICAgICAgPSBzcGVjaWVzLAogICAgICAgICAgICAgICAgIkVmZmVjdCBzaXplICgqayopIiA9IGVmX24sCiAgICAgICAgICAgICAgICAiU3R1ZGllcyAoKm4qKSIgICAgID0gc3R1ZHlfbikgJT4lCiAga25pdHI6OmthYmxlKCkKYGBgCgojIyMgVHJhaXRzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMSAtIFRyYWl0cyoqIENvbnRpbnVhdGlvbiBvZiBkYXRhIHN1bW1hcnkgd2l0aCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9uIHRoZSBudW1iZXIgb2YgZWZmZWN0IHNpemUsIHN0dWRpZXMsIGFuZCBzcGVjaWVzIGluIHRoZSBkYXRhYmFzZSB0cmFpdHMuIAoKYGBge3IgdGFibGVTMWQsIGVjaG89RkFMU0V9CmRhdGEuZnJhbWUoZXNfYWxsX2RhdCAlPiUgCiAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkodHJhaXQpICU+JSAKICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2UoZWZfbiAgICAgID0gbigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHVkeV9uICAgPSBsZW5ndGgodW5pcXVlKHN0dWR5X0lEKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpZXNfbiA9IGxlbmd0aCh1bmlxdWUoc3BlY2llcykpKSkgJT4lCiAgZHBseXI6OmFycmFuZ2UoLWVmX24pICU+JQogIGRwbHlyOjpyZW5hbWUoIlRyYWl0IiAgICAgICAgICAgICA9IHRyYWl0LAogICAgICAgICAgICAgICAgIkVmZmVjdCBzaXplICgqayopIiA9IGVmX24sCiAgICAgICAgICAgICAgICAiU3R1ZGllcyAoKmsqKSIgICAgID0gc3R1ZHlfbiwKICAgICAgICAgICAgICAgICJTcGVjaWVzICgqbiopIiAgICAgPSBzcGVjaWVzX24pICU+JQogIGtuaXRyOjprYWJsZSgpCmBgYAoKKioqCgojIyBQcmVwYXJlIHBoeWxvZ2VueSBmb3IgYW5hbHlzaXMgey19CgpUaGlzIHNlY3Rpb24gcHJvdmlkZXMgdGhlIHdvcmtmbG93IHRvIGV4dHJhY3QgdGhlIHBoeWxvZ2VuZXRpYyB0cmVlIGZyb20gdGhlIFtPcGVuIFRyZWUgb2YgTGlmZV0oaHR0cHM6Ly90cmVlLm9wZW50cmVlb2ZsaWZlLm9yZy8pIChPVEw7IHNlZSBwaHlsb2dlbmV0aWMgcmVjb25zdHJ1Y3Rpb24gaW4gbWFpbiB0ZXh0KSwgbWF0Y2ggdGhlIE9UTCBuYW1lcyB3aXRoIHRoZSBkYXRhIHNldCwgYW5kIGNyZWF0ZSBhIGNvcnJlbGF0aW9uIG1hdHJpeCBmb3Igc3Vic2VxdWVudCBhbmFseXNpcy4gVGhlIHBoeWxvZ2VuZXRpYyB0cmVlIHByb2R1Y2VkIGluICpSKiBmb3IgdGhlICoqU3VwcGxlbWVudGFyeSBGaWd1cmUgUzMqKiB3YXMgbW9kaWZpZWQgaW4gW0Fkb2JlIElsbHVzdHJhdG9yXShodHRwczovL3d3dy5hZG9iZS5jb20vYXUvcHJvZHVjdHMvaWxsdXN0cmF0b3IuaHRtbCkgZm9yIGNsYXJpdHkuCgpgYGB7ciBwaHlsbywgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0iaGlkZSJ9CnNwZWNpZXNfY29tYiA8LSByYmluZChlc19hbGxfZGF0ICU+JSBkcGx5cjo6c2VsZWN0KG9yZGVyLCBmYW1pbHksIHNwZWNpZXMsIHNwZWNpZXNfT1RMKSwgCiAgICAgICAgICAgICAgICAgICAgICBzdXJ2X2RhdCAlPiUgZHBseXI6OnNlbGVjdChvcmRlciwgZmFtaWx5LCBzcGVjaWVzLCBzcGVjaWVzX09UTCkpICMgJ3N1cnZfZGF0YV9jbGVhbicgY3JlYXRlZCBiZWxvdwpzcGVjaWVzX2FsbCAgPC0gc29ydCh1bmlxdWUoYXMuY2hhcmFjdGVyKHNwZWNpZXNfY29tYiRzcGVjaWVzX09UTCkpKSAjIGdlbmVyYXRlIGxpc3Qgb2Ygc3BlY2llcyAoYXMgY2hhcmFjdGVyIGZvcm1hdCkKdGF4YSAgICAgICAgIDwtIHJvdGw6OnRucnNfbWF0Y2hfbmFtZXMobmFtZXMgPSBzcGVjaWVzX2FsbCkgIyBtYXRjaCB0YXhvbm9taWMgbmFtZXMgdG8gdGhlIE9UTAoKIyBjaGVjayBpZiBzcGVjaWVzIGxpc3QgbWF0Y2ggT1QgaWRlbnRpZmllcgojdGF4YVt0YXhhJGFwcHJveGltYXRlX21hdGNoID09IFRSVUUsXSAjIG5vbmUgc28gZmFyCgojIHJldHJpZXZpbmcgcGh5bG9nZW5ldGljIHJlbGF0aW9uc2hpcHMgYW1vbmcgdGF4YSBpbiB0aGUgZm9ybSBvZiBhIHRyaW1tZWQgc3ViLXRyZWUKdHJlZSA8LSByb3RsOjp0b2xfaW5kdWNlZF9zdWJ0cmVlKG90dF9pZHMgPSByb3RsOjpvdHRfaWQodGF4YSksIGxhYmVsX2Zvcm1hdCA9ICJuYW1lIikKCiMgQ29tcHV0ZSBicmFuY2ggbGVuZ3Rocwp0cmVlIDwtIGFwZTo6Y29tcHV0ZS5icmxlbih0cmVlLCBtZXRob2QgPSAiR3JhZmVuIiwgcG93ZXIgPSAxKQp0cmVlIDwtIGFwZTo6bXVsdGkyZGkodHJlZSwgcmFuZG9tID0gVFJVRSkgIyB1c2UgYSByYW5kb21pemF0aW9uIGFwcHJvYWNoIHRvIGRlYWwgd2l0aCBwb2x5dG9taWVzCgojIENoZWNrIHRyZWUgaXMgdWx0cmFtZXRyaWMKI2FwZTo6aXMudWx0cmFtZXRyaWModHJlZSkgIyBUUlVFCgojIENyZWF0ZSBjb3JyZWxhdGlvbiBtYXRyaXggZm9yIGFuYWx5c2lzCnBoeWxvX2NvciA8LSBhcGU6OnZjdih0cmVlLCBjb3IgPSBUKQpgYGAKCgpgYGB7ciBGaWcgUzMsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLmhlaWdodD03LjUsIGZpZy53aWR0aD02LCBtZXNzYWdlPUZBTFNFfQp0cmVlX3RpcF9sYWJlbCAgICAgICA8LSB0cmVlJHRpcC5sYWJlbCAjIGV4dHJhY3QgdHJlZSB0aXAgbmFtZXMKZXNfYWxsX2RhdCRzcGVjaWVzICAgPC0gc3ViKCIgIiwgIl8iLCBlc19hbGxfZGF0JHNwZWNpZXNfT1RMKQplc19hbGxfZGF0JHNwZWNpZXMgICA8LSBmYWN0b3IoZXNfYWxsX2RhdCRzcGVjaWVzLCBsZXZlbHMgPSB0cmVlX3RpcF9sYWJlbCkgIyByZWxldmVsIG9yZGVyIGJ5IHRyZWUKc3BlY2llc19jb21iJHNwZWNpZXMgPC0gc3ViKCIgIiwgIl8iLCBzcGVjaWVzX2NvbWIkc3BlY2llc19PVEwpCnNwZWNpZXNfY29tYiRzcGVjaWVzIDwtIGZhY3RvcihzcGVjaWVzX2NvbWIkc3BlY2llcywgbGV2ZWxzID0gdHJlZV90aXBfbGFiZWwpICMgcmVsZXZlbCBvcmRlciBieSB0cmVlCgpzcF90cmFpdF9kYXQgPC0gc3BlY2llc19jb21iICU+JSAKICBkcGx5cjo6ZGlzdGluY3Qoc3BlY2llcykgJT4lIAogIGRwbHlyOjptdXRhdGUoZmFtaWx5ICAgICA9IGFzLmZhY3RvcihzcGVjaWVzX2NvbWIkZmFtaWx5W21hdGNoKHNwZWNpZXMsIHNwZWNpZXNfY29tYiRzcGVjaWVzKV0pLAogICAgICAgICAgICAgICAgb3JkZXIgICAgICA9IGFzLmZhY3RvcihzcGVjaWVzX2NvbWIkb3JkZXJbbWF0Y2goc3BlY2llcywgc3BlY2llc19jb21iJHNwZWNpZXMpXSksCiAgICAgICAgICAgICAgICBzcGVjaWVzX09UTCA9IHNwZWNpZXNfY29tYiRzcGVjaWVzW21hdGNoKHNwZWNpZXMsIHNwZWNpZXNfY29tYiRzcGVjaWVzKV0pICU+JSAKICB0aWJibGU6OmNvbHVtbl90b19yb3duYW1lcyh2YXIgPSAnc3BlY2llcycpCgojIFBsb3QgdHJlZQpteWNvbCA8LSB2aXJpZGlzOjp2aXJpZGlzKDEyKSAjIHNldCAxMiBkaXNjcmV0ZSBjb2xvdXJzCiNkaXZlcnNpdHJlZTo6dHJhaXQucGxvdCh0cmVlLCBzcF90cmFpdF9kYXQsIGNvbHMgPSBsaXN0KEZhbWlseSA9IG15Y29sKSwgdHlwZSA9ICdwJywgY2V4LmxhYiA9IDAuNywgdyA9IDAuMDUpCmBgYAoKIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uaWNob2xhc3d1bnovY2h5dHJpZC1tZXRhLWFuYWx5c2lzL21haW4vZmlsZXMvRmlnJTIwUzMlMjAtJTIwUGh5bG9nZW5ldGljJTIwdHJlZS5wbmcpCgoqKkZpZy4gUzMuKiogUGh5bG9nZW5ldGljIHJlY29uc3RydWN0aW9uIG9mIGByIGxlbmd0aCh1bmlxdWUobGV2ZWxzKHNwZWNpZXNfY29tYiRzcGVjaWVzX09UTCkpKWAgYW1waGliaWFucyB1c2VkIGluIHRoZSBzdHVkeSBmcm9tIHRoZSBPcGVuIFRyZWUgb2YgTGlmZS4gVGhlIHBoeWxvZ2VueSB3YXMgY29udmVydGVkIHRvIGEgY29ycmVsYXRpb24gbWF0cml4IGZvciB0aGUgbWV0YS1hbmFseXNpcy4KCioqKgoKIyBNZXRhLWFuYWx5c2lzIHstfQoKIyMgUGh5bG9nZW5ldGljYWxseSBjb250cm9sbGVkLCBtdWx0aS1sZXZlbCBtZXRhLWFuYWx5c2lzIGFuZCBtZXRhLXJlZ3Jlc3Npb24gey19CgpSdW4gYW5hbHlzaXMgdG8gZmlyc3QgbG9vayBhdCB0aGUgbnVsbCBlZmZlY3Qgb2YgKkJkKiBpbmZlY3Rpb24gb24gYWxsIHJlc3BvbnNlcyAoJFpfciQpIHdpdGhvdXQgbW9kZXJhdG9ycyAoYG51bGxfbW9kZWxgKSwgdGhlbiB3aXRoIHRoZSBmb2xsb3dpbmcgbW9kZXJhdG9ycyBkYXlzIHBvc3QtZXhwb3N1cmUsIGxpZmUgc3RhZ2UgKGFkdWx0cyBvciBqdXZlbmlsZXMpLCBvcmlnaW4gKHdpbGQgY2F1Z2h0IG9yIGxhYiByYWlzZWQpLCBuYXR1cmFsIGxvZ2FyaXRobSBvZiBpbm9jdWxhdGlvbiBkb3NlLCBhbmQgdHJlYXRtZW50IHRlbXBlcmF0dXJlIChgb3ZlcmFsbF9tb2RlbGApLiBBIGZvbGxvdyB1cCBhbmFseXNpcyB3YXMgcGVyZm9ybWVkIHRvIGVzdGltYXRlIG9mIGNvZWZmaWNpZW50cyBmb3IgZXZlcnkgZmFjdG9yIGxldmVsIHRvIG9idGFpbiBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyBvZiBlZmZlY3Qgc2l6ZSBiZXR3ZWVuIGJpb2xvZ2ljYWwgYW5kIGZ1bmN0aW9uYWwgdHJhaXRzIChgdHJhaXRfbW9kZWxgKS4KCmBgYHtyIG1vZGVscywgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9Cm1ldGFfcHJpb3IgICAgPC0gYyhzZXRfcHJpb3IoImNhdWNoeSgwLCAxKSIsIGNsYXNzID0gInNkIikpICMgQ2F1Y2h5IG9uIHRhdSAocmFuZG9tIGVmZmVjdCB2YXJpYW5jZSksIG5vcm1hbCBvbiBmaXhlZCBlZmZlY3QKCiMgTnVsbCBtb2RlbCAtIFdpdGhvdXQgbW9kZXJhdG9ycwpzZXQuc2VlZCgxMCkKbnVsbF9tb2RlbCA8LSBicm1zOjpicm0oWnIgfCBzZShacl9zZWkpIH4gMSArICgxIHwgZXNfSUQpICsgKDEgfCBzdHVkeV9JRCkgKyAoMSB8IHNwZWNpZXNfT1RMKSArICgxIHwgZ3Ioc3BlY2llcywgY292ID0gcGh5bG8pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSAgICA9IGVzX2FsbF9kYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSAgPSBnYXVzc2lhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTIgICA9IGxpc3QocGh5bG8gPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciAgID0gbWV0YV9wcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciAgICA9IDFlNCwgd2FybXVwID0gNWUzLCBjb3JlcyA9IDQsIGNoYWlucyA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OTksIG1heF90cmVlZGVwdGggPSAxOCkpCgojIE1ldGEtcmVncmVzc2lvbiBtb2RlbCAtIFdpdGggbW9kZXJhdG9ycwpvdmVyYWxsX21vZGVsIDwtIGJybXM6OmJybShaciB8IHNlKFpyX3NlaSkgfiB0aW1lX3Bvc3RfZGF5cyArIGxpZmVfc3RhZ2UgKyBvcmlnaW4gKyBsbkRvc2UgKyB0cnRfdGVtcCArIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIHwgZXNfSUQpICsgKDEgfCBzdHVkeV9JRCkgKyAoMSB8IHNwZWNpZXNfT1RMKSArICgxIHwgZ3Ioc3BlY2llcywgY292ID0gcGh5bG8pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSAgICA9IGVzX2FsbF9kYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSAgPSBnYXVzc2lhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTIgICA9IGxpc3QocGh5bG8gPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciAgID0gbWV0YV9wcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciAgICA9IDFlNCwgd2FybXVwID0gNWUzLCBjb3JlcyA9IDQsIGNoYWlucyA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OTksIG1heF90cmVlZGVwdGggPSAxOCkpCgojIFRyYWl0LXNwZWNpZmljIG1ldGEtcmVncmVzc2lvbiBtb2RlbAp0cmFpdF9tb2RlbCA8LSBicm1zOjpicm0oWnIgfCBzZShacl9zZWkpIH4gLTEgKyB0cmFpdCArIGxpZmVfc3RhZ2UgKyB5ZWFyX2NlbnRyZSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIHwgZXNfSUQpICsgKDEgfCBzdHVkeV9JRCkgKyAoMSB8IHNwZWNpZXNfT1RMKSArICgxIHwgZ3Ioc3BlY2llcywgY292ID0gcGh5bG8pKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgICAgPSBlc19hbGxfZGF0ICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkodHJhaXQpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihuKCkgPj0gNSksCiAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgID0gZ2F1c3NpYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhMiAgID0gbGlzdChwaHlsbyA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciAgID0gbWV0YV9wcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgICAgPSAxZTQsIHdhcm11cCA9IDVlMywgY29yZXMgPSA0LCBjaGFpbnMgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjk5OSwgbWF4X3RyZWVkZXB0aCA9IDE4KSkKYGBgCgojIyBQdWJsaWNhdGlvbiBiaWFzIHRlc3Qgey19CgpQdWJsaWNhdGlvbiBiaWFzIHdhcyB0ZXN0ZWQgYnkgdXNpbmcgdGhlIHNhbWUgZm9ybXVsYSBhcyB0aGUgYG51bGxfbW9kZWxgIHdpdGggdGhlIGluY2x1c2lvbiBvZiB0aGUgbWVhbiBjZW50cmluZyBvZiB5ZWFyICh0ZXN0IGZvciB0aW1lLWxhZyBiaWFzKSBhbmQgdGhlIHNxdWFyZSByb290IG9mIHRoZSBzYW1wbGluZyB2YXJpYW5jZSAodGVzdCBmb3Igc2FtbS1zYW1wbGUgYmlhcykgYXMgbW9kZXJhdG9ycyAoYGJpYXNfbW9kZWxgKS4KCmBgYHtyIGJpYXMsIG1lc3NhZ2U9RkFMU0UsIGNhY2hlPVRSVUUsIHJlc3VsdHM9ImhpZGUifQpiaWFzX21vZGVsIDwtIGJybXM6OmJybShaciB8IHNlKFpyX3NlaSkgfiAxICsgeWVhcl9jZW50cmUgKyBzcXJ0KFpyX3YpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSB8IGVzX0lEKSArICgxIHwgc3R1ZHlfSUQpICsgKDEgfCBzcGVjaWVzX09UTCkgKyAoMSB8IGdyKHNwZWNpZXMsIGNvdiA9IHBoeWxvKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgICAgPSBlc19hbGxfZGF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgID0gZ2F1c3NpYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEyICAgPSBsaXN0KHBoeWxvID0gcGh5bG9fY29yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgICA9IG1ldGFfcHJpb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgICAgPSAxZTQsIHdhcm11cCA9IDVlMywgY29yZXMgPSA0LCBjaGFpbnMgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTk5LCBtYXhfdHJlZWRlcHRoID0gMTgpKQoKYGBgCgoKYGBge3IgRmlnIFM0LCBlY2hvID0gRkFMU0UsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA2LCBmaWcuYWxpZ24gPScgY2VudGVyJ30KbnVsbF9tb2RlbF9wcCAgICA8LSBicm1zOjpwcF9jaGVjayhudWxsX21vZGVsLCB0eXBlID0gInNjYXR0ZXJfYXZnIikKb3ZlcmFsbF9tb2RlbF9wcCA8LSBicm1zOjpwcF9jaGVjayhvdmVyYWxsX21vZGVsLCB0eXBlID0gInNjYXR0ZXJfYXZnIikKdHJhaXRfbW9kZWxfcHAgICA8LSBicm1zOjpwcF9jaGVjayh0cmFpdF9tb2RlbCwgdHlwZSA9ICJzY2F0dGVyX2F2ZyIpCmJpYXNfbW9kZWxfcHAgICAgPC0gYnJtczo6cHBfY2hlY2soYmlhc19tb2RlbCwgdHlwZSA9ICJzY2F0dGVyX2F2ZyIpCgpjb3dwbG90OjpwbG90X2dyaWQobnVsbF9tb2RlbF9wcCwgb3ZlcmFsbF9tb2RlbF9wcCwgdHJhaXRfbW9kZWxfcHAsIGJpYXNfbW9kZWxfcHAsIAogICAgICAgICAgICAgICAgICAgbmNvbCA9IDIsIGxhYmVscyA9IGMoJ2EnLCAnYicsICdjJywgJ2QnKSkKYGBgCgoqKkZpZy4gUzQuKiogU2NhdHRlcnBsb3RzIG9mIHRoZSBvYnNlcnZlZCBkYXRhICh5KSB2cyB0aGUgYXZlcmFnZSBzaW11bGF0ZWQgZGF0YSAoeX5yZXB+KSBmcm9tIHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24gZm9yIHRoZSAoKiphKiopIG51bGwgbW9kZWwsICgqKmIqKikgdGhlIG92ZXJhbGwgbW9kZWwsICgqKmMqKikgdGhlIHRyYWl0IG1vZGVsLCBhbmQgKCoqYyoqKSB0aGUgYmlhcyBtb2RlbC4gRGFzaGVkIGxpbmUgcmVwcmVzZW50cyBhIHNsb3BlIG9mIDEuIAoKCiMjIE1vZGVsIG91dHB1dCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfQoKIyMjIFRhYmxlIFMyIC0gTnVsbCBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzIuKiogTWVhbiBwYXJhbWV0ZXIgZXN0aW1hdGVzLCBlc3RpbWF0ZSBlcnJvciwgYW5kIDk1JSBCYXllc2lhbiBjcmVkaWJsZSBpbnRlcnZhbHMgZm9yIHRoZSBudWxsIG1vZGVsLCB3aGljaCBpbmNsdWRlcyB0aGUgaW50ZXJjZXB0ICgkXGJldGFfMCQpLiBHcm91cC1sZXZlbCBlZmZlY3RzIGluY2x1ZGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgKCRcc2lnbWEkKSBmb3IgaW5kaXZpZHVhbC1sZXZlbCBvYnNlcnZhdGlvbnMgKCRcc2lnbWFfe3Jlc2lkdWFsfV4yJCksIHN0dWR5LWxldmVsIG9ic2VydmF0aW9ucyAoJFxzaWdtYV97c3R1ZHl9XjIkKSwgc3BlY2llcyBpZGVudGl0eSAoJFxzaWdtYV97c3BlY2llc31eMiQpLCBhbmQgcGh5bG9nZW5ldGljIHJlbGF0ZWRuZXNzICgkXHNpZ21hX3twaHlsb2dlbnl9XjIkKS4KCmBgYHtyIHRhYmxlUzIsIGVjaG8gPSBGQUxTRX0KIyBGaXhlZCBlZmZlY3QKZmVmIDwtIGJybXM6OmZpeGVmKG51bGxfbW9kZWwpICU+JSAKICBhcy5kYXRhLmZyYW1lKC4pICU+JQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBzdHJfcmVwbGFjZShQYXJhbWV0ZXIsICJNIiwgIi0iKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gY2FzZV93aGVuKAogICAgUGFyYW1ldGVyID09ICJJbnRlcmNlcHQiIH4gIiRcXGJldGFfMCQiKSkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipGaXhlZCBlZmZlY3RzKioiLCAuYmVmb3JlID0gMSkKCiMgUmFuZG9tIGVmZmVjdApyZWYgPC0gc3VtbWFyeShudWxsX21vZGVsKSRyYW5kb20gJT4lIAogIGJpbmRfcm93cygpICU+JSAjIHVubGlzdAogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgxOjUpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IGMoIiRcXHNpZ21hX3tyZXNpZHVhbH1eMiQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3twaHlsb2dlbnl9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3tzcGVjaWVzfV4yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97c3R1ZHl9XjIkIikpICU+JSAgIAogIGRwbHlyOjpyZW5hbWUoUTIuNSAgPSA0LCAKICAgICAgICAgICAgICAgIFE5Ny41ID0gNSkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipHcm91cC1sZXZlbCBlZmZlY3RzKioiLCAuYmVmb3JlID0gMSkKCiMgUmVuZGVyIHRhYmxlCmJpbmRfcm93cyhmZWYsIHJlZikgJT4lIAogIHJlbW92ZV9yb3duYW1lcygpICU+JSAKICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikKYGBgCgojIyMgVGFibGUgUzMgLSBIZXRlcm9nZW5laXR5IGFuZCB2YXJpYW5jZSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzMuKiogSGV0ZXJvZ2VuZWl0eSBhbmQgJFJeMiQgb2YgdGhlIG51bGwgYW5kIG92ZXJhbGwgbW9kZWwuICprKiA9IG51bWJlciBvZiBlc3RpbWF0ZXMsIGFuZCAkSV4yJCA9IGhldGVyb2dlbmVpdHkuICRSX3ttYXJnaW5hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IG1vZGVyYXRvcnMsIHdoaWxlICRSX3tjb25kaXRpb25hbH1eMiQgcmVwcmVzZW50cyB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGJvdGggbW9kZXJhdG9ycyBhbmQgZ3JvdXAtbGV2ZWwgZWZmZWN0cy4gRXN0aW1hdGVzIHNob3duIGNvcnJlc3BvbmQgdG8gbW9kZXMgYW5kIDk1JSBoaWdoZXN0IHBvc3RlcmlvciBkZW5zaXR5IGludGVydmFscy4KCmBgYHtyIHRhYmxlUzMsIGVjaG8gPSBGQUxTRX0KIyBIZXRlcm9nZW5laXR5IC0gTnVsbApudWxsX3Bvc3QgPC0gYnJtczo6cG9zdGVyaW9yX3NhbXBsZXMobnVsbF9tb2RlbCkgIyBleHRyYWN0aW5nIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9ucyBmcm9tIG91ciBtb2RlbHMKCiMgV0kgPSB3ZWlnaHQKV0kgPC0gbmEub21pdChlc19hbGxfZGF0JFpyX3cpCgojIHMySSA9IG1lYXN1cmVtZW50IGVycm9yIHZhcmlhbmNlID0gc2lnbWEybQpzMkkgPC0gc3VtKFdJW2lzLmZpbml0ZShXSSldICogKGxlbmd0aChXSSkgLSAxKSkgLyAoc3VtKFdJW2lzLmZpbml0ZShXSSldKSBeIDIgLSBzdW0oV0lbaXMuZmluaXRlKFdJKV0gXiAyKSkKCiMgdG90YWwgdmFyaWFuY2UsIGluY2x1ZGluZyBtZWFzdXJlbWVudCBlcnJvciB2YXJpYW5jZQp0b3RhbF92YXJfbnVsbCA8LSBudWxsX3Bvc3Qkc2RfZXNfSURfX0ludGVyY2VwdCArCiAgbnVsbF9wb3N0JHNkX3NwZWNpZXNfX0ludGVyY2VwdCArCiAgbnVsbF9wb3N0JHNkX3NwZWNpZXNfT1RMX19JbnRlcmNlcHQgKwogIG51bGxfcG9zdCRzZF9zdHVkeV9JRF9fSW50ZXJjZXB0ICsKICBzMkkKCiMgdG90YWwgaGV0ZXJvZ2VuZWl0eSBJMgpJMl90b3RhbCAgICAgPC0gKHRvdGFsX3Zhcl9udWxsIC0gczJJKSAvIHRvdGFsX3Zhcl9udWxsCkkyX3RvdGFsX2VzdCA8LSBkYXRhLmZyYW1lKCJ4IiA9IGFzLmNoYXJhY3Rlcihyb3VuZChNQ01DZ2xtbTo6cG9zdGVyaW9yLm1vZGUoSTJfdG90YWwpLCAzKSAqIDEwMCkpICU+JQogIHRpYmJsZTo6YWRkX3Jvdyh4ID0gZ3N1YigiICIsICIiLCBhZGRicmFja2V0KHBhc3RlKHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl90b3RhbCwgY2kgPSAwLjk1KSRDSV9sb3csIDMpICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl90b3RhbCwgY2kgPSAwLjk1KSRDSV9oaWdoLCAzKSAqIDEwMCwgc2VwID0gIuKAkyIpKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIiRJX3t0b3RhbH1eMiQiID0geCkKCiMgb2JzZXJ2YXRpb25hbCBsZXZlbCBJMgpJMl9lc0lEICAgICA8LSBudWxsX3Bvc3Qkc2RfZXNfSURfX0ludGVyY2VwdCAvIHRvdGFsX3Zhcl9udWxsCkkyX2VzSURfZXN0IDwtIGRhdGEuZnJhbWUoIngiID0gYXMuY2hhcmFjdGVyKHJvdW5kKE1DTUNnbG1tOjpwb3N0ZXJpb3IubW9kZShJMl9lc0lEKSwgMykgKiAxMDApKSAlPiUKICB0aWJibGU6OmFkZF9yb3coeCA9IGdzdWIoIiAiLCAiIiwgYWRkYnJhY2tldChwYXN0ZShyb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfZXNJRCwgY2kgPSAwLjk1KSRDSV9sb3csIDMpICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl9lc0lELCBjaSA9IDAuOTUpJENJX2hpZ2gsIDMpICogMTAwLCBzZXAgPSAi4oCTIikpKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgiJElfe3Jlc2lkdWFsfV4yJCIgPSB4KQoKCiMgc3R1ZHlJRCBJMgpJMl9zdHVkeUlEICAgICA8LSBudWxsX3Bvc3Qkc2Rfc3R1ZHlfSURfX0ludGVyY2VwdCAvIHRvdGFsX3Zhcl9udWxsCkkyX3N0dWR5SURfZXN0IDwtIGRhdGEuZnJhbWUoIngiID0gYXMuY2hhcmFjdGVyKHJvdW5kKE1DTUNnbG1tOjpwb3N0ZXJpb3IubW9kZShJMl9zdHVkeUlEKSwgMykgKiAxMDApKSAlPiUKICB0aWJibGU6OmFkZF9yb3coeCA9IGdzdWIoIiAiLCAiIiwgYWRkYnJhY2tldChwYXN0ZShyb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfc3R1ZHlJRCwgY2kgPSAwLjk1KSRDSV9sb3csIDMpICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl9zdHVkeUlELCBjaSA9IDAuOTUpJENJX2hpZ2gsIDMpICogMTAwLCBzZXAgPSAi4oCTIikpKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgiJElfe3N0dWR5fV4yJCIgPSB4KQoKIyBwaHlsb2dlbnkgSTI6IG5vdGljZSB0aGF0IHMySSBpcyBzdWJ0cmFjdGVkIGZyb20gdGhpcyBjYWxjdWxhdGlvbiBhcyBwaHlsb2dlbmV0aWMKIyByZWxhdGVkbmVzcyBpcyBhICJmaXhlZCByYW5kb20gZWZmZWN0IgpJMl9waHlsbyAgICAgPC0gbnVsbF9wb3N0JHNkX3NwZWNpZXNfX0ludGVyY2VwdCAvICh0b3RhbF92YXJfbnVsbCAtIHMySSkKSTJfcGh5bG9fZXN0IDwtIGRhdGEuZnJhbWUoIngiID0gYXMuY2hhcmFjdGVyKHJvdW5kKE1DTUNnbG1tOjpwb3N0ZXJpb3IubW9kZShJMl9waHlsbyksIDMpICogMTAwKSkgJT4lCiAgdGliYmxlOjphZGRfcm93KHggPSBnc3ViKCIgIiwgIiIsIGFkZGJyYWNrZXQocGFzdGUocm91bmQoYmF5ZXN0ZXN0Ujo6aGRpKEkyX3BoeWxvLCBjaSA9IDAuOTUpJENJX2xvdywgMykgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQoYmF5ZXN0ZXN0Ujo6aGRpKEkyX3BoeWxvLCBjaSA9IDAuOTUpJENJX2hpZ2gsIDMpICogMTAwLCBzZXAgPSAi4oCTIikpKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgiJElfe3BoeWxvZ2VueX1eMiQiID0geCkKCiMgc3BlY2llc0lEIEkyCkkyX3NwZWNpZXMgICAgIDwtIG51bGxfcG9zdCRzZF9zcGVjaWVzX09UTF9fSW50ZXJjZXB0IC8gdG90YWxfdmFyX251bGwKSTJfc3BlY2llc19lc3QgPC0gZGF0YS5mcmFtZSgieCIgPSBhcy5jaGFyYWN0ZXIocm91bmQoTUNNQ2dsbW06OnBvc3Rlcmlvci5tb2RlKEkyX3NwZWNpZXMpLCAzKSAqIDEwMCkpICU+JQogIHRpYmJsZTo6YWRkX3Jvdyh4ID0gZ3N1YigiICIsICIiLCBhZGRicmFja2V0KHBhc3RlKHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl9zcGVjaWVzLCBjaSA9IDAuOTUpJENJX2xvdywgMykgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQoYmF5ZXN0ZXN0Ujo6aGRpKEkyX3NwZWNpZXMsIGNpID0gMC45NSkkQ0lfaGlnaCwgMykgKiAxMDAsIHNlcCA9ICLigJMiKSkpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCIkSV97c3BlY2llc31eMiQiID0geCkKCiMgUjIgY2FsY3VsYXRpb24KcjJfbWFyIDwtIGRhdGEuZnJhbWUoIngiID0gYXMuY2hhcmFjdGVyKHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKG51bGxfbW9kZWwpKVsyLDFdLCA0KSAqIDEwMCkpICU+JQogIHRpYmJsZTo6YWRkX3Jvdyh4ID0gZ3N1YigiICIsICIiLCBhZGRicmFja2V0KHBhc3RlKHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKG51bGxfbW9kZWwpKVsyLDRdLCA0KSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhudWxsX21vZGVsKSlbMiw1XSwgNCkgKiAxMDAsIHNlcCA9ICLigJMiKSkpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCIkUl97bWFyZ2luYWx9XjIkIiA9IHgpCgpyMl9jb24gPC0gZGF0YS5mcmFtZSgieCIgPSBhcy5jaGFyYWN0ZXIocm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMobnVsbF9tb2RlbCkpWzEsMV0sIDMpICogMTAwKSkgJT4lCiAgdGliYmxlOjphZGRfcm93KHggPSBnc3ViKCIgIiwgIiIsIGFkZGJyYWNrZXQocGFzdGUocm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMobnVsbF9tb2RlbCkpWzEsNF0sIDMpICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKG51bGxfbW9kZWwpKVsxLDVdLCAzKSAqIDEwMCwgc2VwID0gIuKAkyIpKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIiRSX3tjb25kaXRpb25hbH1eMiQiID0geCkKICAKCiMgTnVsbCBzdW1tYXJ5Cm51bGxfaGV0IDwtIGNiaW5kKCJNb2RlbCIgPSBjKCJOdWxsIiwiIiksIEkyX2VzSURfZXN0LCBJMl9zdHVkeUlEX2VzdCwgSTJfc3BlY2llc19lc3QsIEkyX3BoeWxvX2VzdCwgSTJfdG90YWxfZXN0LCByMl9tYXIsIHIyX2NvbikKCiMgSGV0ZXJvZ2VuZWl0eSAtIE92ZXJhbGwKb3ZlcmFsbF9wb3N0IDwtIGJybXM6OnBvc3Rlcmlvcl9zYW1wbGVzKG92ZXJhbGxfbW9kZWwpICMgZXh0cmFjdGluZyB0aGUgcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbnMgZnJvbSBvdXIgbW9kZWxzCgojIHRvdGFsIHZhcmlhbmNlLCBpbmNsdWRpbmcgbWVhc3VyZW1lbnQgZXJyb3IgdmFyaWFuY2UKdG90YWxfdmFyX292ZXJhbGwgPC0gb3ZlcmFsbF9wb3N0JHNkX2VzX0lEX19JbnRlcmNlcHQgKwogIG92ZXJhbGxfcG9zdCRzZF9zcGVjaWVzX19JbnRlcmNlcHQgKwogIG92ZXJhbGxfcG9zdCRzZF9zcGVjaWVzX09UTF9fSW50ZXJjZXB0ICsKICBvdmVyYWxsX3Bvc3Qkc2Rfc3R1ZHlfSURfX0ludGVyY2VwdCArCiAgczJJCgojIHRvdGFsIGhldGVyb2dlbmVpdHkgSTIKSTJfdG90YWwgICAgIDwtICh0b3RhbF92YXJfb3ZlcmFsbCAtIHMySSkgLyB0b3RhbF92YXJfb3ZlcmFsbApJMl90b3RhbF9lc3QgPC0gZGF0YS5mcmFtZSgieCIgPSBhcy5jaGFyYWN0ZXIocm91bmQoTUNNQ2dsbW06OnBvc3Rlcmlvci5tb2RlKEkyX3RvdGFsKSwgMykgKiAxMDApKSAlPiUKICB0aWJibGU6OmFkZF9yb3coeCA9IGdzdWIoIiAiLCAiIiwgYWRkYnJhY2tldChwYXN0ZShyb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfdG90YWwsIGNpID0gMC45NSkkQ0lfbG93LCAzKSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfdG90YWwsIGNpID0gMC45NSkkQ0lfaGlnaCwgMykgKiAxMDAsIHNlcCA9ICLigJMiKSkpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCIkSV97dG90YWx9XjIkIiA9IHgpCgojIG9ic2VydmF0aW9uYWwgbGV2ZWwgSTIKSTJfZXNJRCAgICAgPC0gb3ZlcmFsbF9wb3N0JHNkX2VzX0lEX19JbnRlcmNlcHQgLyB0b3RhbF92YXJfb3ZlcmFsbApJMl9lc0lEX2VzdCA8LSBkYXRhLmZyYW1lKCJ4IiA9IGFzLmNoYXJhY3Rlcihyb3VuZChNQ01DZ2xtbTo6cG9zdGVyaW9yLm1vZGUoSTJfZXNJRCksIDMpICogMTAwKSkgJT4lCiAgdGliYmxlOjphZGRfcm93KHggPSBnc3ViKCIgIiwgIiIsIGFkZGJyYWNrZXQocGFzdGUocm91bmQoYmF5ZXN0ZXN0Ujo6aGRpKEkyX2VzSUQsIGNpID0gMC45NSkkQ0lfbG93LCAzKSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfZXNJRCwgY2kgPSAwLjk1KSRDSV9oaWdoLCAzKSAqIDEwMCwgc2VwID0gIuKAkyIpKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIiRJX3tyZXNpZHVhbH1eMiQiID0geCkKCgojIHN0dWR5SUQgSTIKSTJfc3R1ZHlJRCAgICAgPC0gb3ZlcmFsbF9wb3N0JHNkX3N0dWR5X0lEX19JbnRlcmNlcHQgLyB0b3RhbF92YXJfb3ZlcmFsbApJMl9zdHVkeUlEX2VzdCA8LSBkYXRhLmZyYW1lKCJ4IiA9IGFzLmNoYXJhY3Rlcihyb3VuZChNQ01DZ2xtbTo6cG9zdGVyaW9yLm1vZGUoSTJfc3R1ZHlJRCksIDMpICogMTAwKSkgJT4lCiAgdGliYmxlOjphZGRfcm93KHggPSBnc3ViKCIgIiwgIiIsIGFkZGJyYWNrZXQocGFzdGUocm91bmQoYmF5ZXN0ZXN0Ujo6aGRpKEkyX3N0dWR5SUQsIGNpID0gMC45NSkkQ0lfbG93LCAzKSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfc3R1ZHlJRCwgY2kgPSAwLjk1KSRDSV9oaWdoLCAzKSAqIDEwMCwgc2VwID0gIuKAkyIpKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIiRJX3tzdHVkeX1eMiQiID0geCkKCiMgcGh5bG9nZW55IEkyOiBub3RpY2UgdGhhdCBzMkkgaXMgc3VidHJhY3RlZCBmcm9tIHRoaXMgY2FsY3VsYXRpb24gYXMgcGh5bG9nZW5ldGljCiMgcmVsYXRlZG5lc3MgaXMgYSAiZml4ZWQgcmFuZG9tIGVmZmVjdCIKSTJfcGh5bG8gICAgIDwtIG92ZXJhbGxfcG9zdCRzZF9zcGVjaWVzX19JbnRlcmNlcHQgLyAodG90YWxfdmFyX292ZXJhbGwgLSBzMkkpCkkyX3BoeWxvX2VzdCA8LSBkYXRhLmZyYW1lKCJ4IiA9IGFzLmNoYXJhY3Rlcihyb3VuZChNQ01DZ2xtbTo6cG9zdGVyaW9yLm1vZGUoSTJfcGh5bG8pLCAzKSAqIDEwMCkpICU+JQogIHRpYmJsZTo6YWRkX3Jvdyh4ID0gZ3N1YigiICIsICIiLCBhZGRicmFja2V0KHBhc3RlKHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl9waHlsbywgY2kgPSAwLjk1KSRDSV9sb3csIDMpICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl9waHlsbywgY2kgPSAwLjk1KSRDSV9oaWdoLCAzKSAqIDEwMCwgc2VwID0gIuKAkyIpKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIiRJX3twaHlsb2dlbnl9XjIkIiA9IHgpCgojIHNwZWNpZXNJRCBJMgpJMl9zcGVjaWVzICAgICA8LSBvdmVyYWxsX3Bvc3Qkc2Rfc3BlY2llc19PVExfX0ludGVyY2VwdCAvIHRvdGFsX3Zhcl9vdmVyYWxsCkkyX3NwZWNpZXNfZXN0IDwtIGRhdGEuZnJhbWUoIngiID0gYXMuY2hhcmFjdGVyKHJvdW5kKE1DTUNnbG1tOjpwb3N0ZXJpb3IubW9kZShJMl9zcGVjaWVzKSwgMykgKiAxMDApKSAlPiUKICB0aWJibGU6OmFkZF9yb3coeCA9IGdzdWIoIiAiLCAiIiwgYWRkYnJhY2tldChwYXN0ZShyb3VuZChiYXllc3Rlc3RSOjpoZGkoSTJfc3BlY2llcywgY2kgPSAwLjk1KSRDSV9sb3csIDMpICogMTAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKGJheWVzdGVzdFI6OmhkaShJMl9zcGVjaWVzLCBjaSA9IDAuOTUpJENJX2hpZ2gsIDMpICogMTAwLCBzZXAgPSAi4oCTIikpKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgiJElfe3NwZWNpZXN9XjIkIiA9IHgpCgojIFIyIGNhbGN1bGF0aW9uCnIyX21hciA8LSBkYXRhLmZyYW1lKCJ4IiA9IGFzLmNoYXJhY3Rlcihyb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhvdmVyYWxsX21vZGVsKSlbMiwxXSwgNCkgKiAxMDApKSAlPiUKICB0aWJibGU6OmFkZF9yb3coeCA9IGdzdWIoIiAiLCAiIiwgYWRkYnJhY2tldChwYXN0ZShyb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhvdmVyYWxsX21vZGVsKSlbMiw0XSwgNCkgKiAxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm91bmQoZGF0YS5mcmFtZShwZXJmb3JtYW5jZTo6cjJfYmF5ZXMob3ZlcmFsbF9tb2RlbCkpWzIsNV0sIDQpICogMTAwLCBzZXAgPSAi4oCTIikpKSkgJT4lCiAgZHBseXI6OnJlbmFtZSgiJFJfe21hcmdpbmFsfV4yJCIgPSB4KQoKcjJfY29uIDwtIGRhdGEuZnJhbWUoIngiID0gYXMuY2hhcmFjdGVyKHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKG92ZXJhbGxfbW9kZWwpKVsxLDFdLCAzKSAqIDEwMCkpICU+JQogIHRpYmJsZTo6YWRkX3Jvdyh4ID0gZ3N1YigiICIsICIiLCBhZGRicmFja2V0KHBhc3RlKHJvdW5kKGRhdGEuZnJhbWUocGVyZm9ybWFuY2U6OnIyX2JheWVzKG92ZXJhbGxfbW9kZWwpKVsxLDRdLCAzKSAqIDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3VuZChkYXRhLmZyYW1lKHBlcmZvcm1hbmNlOjpyMl9iYXllcyhvdmVyYWxsX21vZGVsKSlbMSw1XSwgMykgKiAxMDAsIHNlcCA9ICLigJMiKSkpKSAlPiUKICBkcGx5cjo6cmVuYW1lKCIkUl97Y29uZGl0aW9uYWx9XjIkIiA9IHgpCgojIE51bGwgc3VtbWFyeQpvdmVyX2hldCA8LSBjYmluZCgiTW9kZWwiID0gYygiT3ZlcmFsbCIsIiIpLCBJMl9lc0lEX2VzdCwgSTJfc3R1ZHlJRF9lc3QsIEkyX3NwZWNpZXNfZXN0LCBJMl9waHlsb19lc3QsIEkyX3RvdGFsX2VzdCwgcjJfbWFyLCByMl9jb24pCgpiaW5kX3Jvd3MobnVsbF9oZXQsIG92ZXJfaGV0KSAlPiUKICByZW1vdmVfcm93bmFtZXMoKSAlPiUgCiAga25pdHI6OmthYmxlKCkKYGBgCgojIyMgVGFibGUgUzQgLSBCaWFzIG1vZGVsIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTNC4qKiBNZWFuIHBhcmFtZXRlciBlc3RpbWF0ZXMsIGVzdGltYXRlIGVycm9yLCBhbmQgOTUlIEJheWVzaWFuIGNyZWRpYmxlIGludGVydmFscyBmb3IgdGhlIGJpYXMgbW9kZWwsIHdoaWNoIGluY2x1ZGVzIHRoZSBpbnRlcmNlcHQgKCRcYmV0YV8wJCksIHB1YmxpY2F0aW9uIHllYXIgYW5kIHNhbXBsaW5nIHN0YW5kYXJkIGVycm9yIGFzIGNvdmFyaWF0ZXMgdG8gdGVzdCBhbmQgY29ycmVjdCBmb3IgcHVibGljYXRpb24gYmlhcy4gR3JvdXAtbGV2ZWwgZWZmZWN0cyBpbmNsdWRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zICgkXHNpZ21hJCkgZm9yIGluZGl2aWR1YWwtbGV2ZWwgb2JzZXJ2YXRpb25zICgkXHNpZ21hX3tyZXNpZHVhbH1eMiQpLCBzdHVkeS1sZXZlbCBvYnNlcnZhdGlvbnMgKCRcc2lnbWFfe3N0dWR5fV4yJCksIHNwZWNpZXMgaWRlbnRpdHkgKCRcc2lnbWFfe3NwZWNpZXN9XjIkKSwgYW5kIHBoeWxvZ2VuZXRpYyByZWxhdGVkbmVzcyAoJFxzaWdtYV97cGh5bG9nZW55fV4yJCkuCgpgYGB7ciB0YWJsZVM0LCBlY2hvID0gRkFMU0V9CiMgRml4ZWQgZWZmZWN0CmZlZiA8LSBicm1zOjpmaXhlZihiaWFzX21vZGVsKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSguKSAlPiUKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gc3RyX3JlcGxhY2UoUGFyYW1ldGVyLCAiTSIsICItIikpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IGNhc2Vfd2hlbigKICAgIFBhcmFtZXRlciA9PSAiSW50ZXJjZXB0IiB+ICIkXFxiZXRhXzAkIiwKICAgIFBhcmFtZXRlciA9PSAieWVhcl9jZW50cmUiICB+ICJQdWJsaWNhdGlvbiB5ZWFyIiwKICAgIFBhcmFtZXRlciA9PSAic3FydFpyX3YiICB+ICJTYW1wbGluZyBzdGFuZGFyZCBlcnJvciIpKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkZpeGVkIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSYW5kb20gZWZmZWN0CnJlZiA8LSBzdW1tYXJ5KGJpYXNfbW9kZWwpJHJhbmRvbSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lICMgdW5saXN0CiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KDE6NSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gYygiJFxcc2lnbWFfe3Jlc2lkdWFsfV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3BoeWxvZ2VueX1eMiQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3NwZWNpZXN9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3tzdHVkeX1eMiQiKSkgJT4lICAgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IDQsIAogICAgICAgICAgICAgICAgUTk3LjUgPSA1KSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkdyb3VwLWxldmVsIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKGZlZiwgcmVmKSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIAogIGtuaXRyOjprYWJsZShkaWdpdHMgPSAyKQpgYGAKCiMjIyBGaWcgUzUgLSBGdW5uZWwgcGxvdCAgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCmBgYHtyIGZ1bm5lbCwgZWNobyA9IEZBTFNFfQojIEZ1bm5lbCBwbG90Cm1ldGFmb3I6OmZ1bm5lbCh4ID0gZXNfYWxsX2RhdCRaciwgc2VpID0gZXNfYWxsX2RhdCRacl9zZWksIHBjaCA9IDEpCmBgYAoKKipGaWcuIFM1LioqIEZ1bm5lbCBwbG90IG9uIHRoZSBlZmZlY3Qgc2l6ZSBhZ2FpbnN0IHRoZSBzdHVkeSBzdGFuZGFyZCBlcnJvci4gVGhlIHdoaXRlIGFyZWEgYm9yZGVyZWQgYnkgZGFzaGVkIGxpbmVzIHJlcHJlc2VudHMgdGhlIHJlZ2lvbiBvZiA5NSUgcHNldWRvIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIHdoZXJlIDk1JSBvZiBzdHVkaWVzIGFyZSBleHBlY3RlZCB0byBmYWxsIGluIHRoZSBhYnNlbmNlIG9mIGJpYXMgYW5kIGhldGVyb2dlbmVpdHkuCgoKIyMjIFRhYmxlIFM1IC0gT3ZlcmFsbCBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzUuKiogTWVhbiBwYXJhbWV0ZXIgZXN0aW1hdGVzLCBlc3RpbWF0ZSBlcnJvciwgYW5kIDk1JSBCYXllc2lhbiBjcmVkaWJsZSBpbnRlcnZhbHMgZm9yIHRoZSBvdmVyYWxsIG1vZGVsLCB3aGljaCBpbmNsdWRlcyB0aGUgaW50ZXJjZXB0ICgkXGJldGFfMCQpLCBkYXlzIHBvc3QtZXhwb3N1cmUsIGxpZmUgc3RhZ2UgKGp1dmVuaWxlIG9yIGFkdWx0KSwgb3JpZ2luICh3aWxkIGNhdWdodCBvciBsYWItcmVhcmVkKSwgdGhlIG5hdHVyYWwgbG9nYXJpdGhtIG9mIGlub2N1bGF0aW9uIGRvc2UgKGxuRG9zZSksIGFuZCB0cmVhdG1lbnQgdGVtcGVyYXR1cmUgYXMgZml4ZWQgZWZmZWN0cy4gR3JvdXAtbGV2ZWwgZWZmZWN0cyBpbmNsdWRlIHRoZSBzdGFuZGFyZCBkZXZpYXRpb25zICgkXHNpZ21hJCkgZm9yIGluZGl2aWR1YWwtbGV2ZWwgb2JzZXJ2YXRpb25zICgkXHNpZ21hX3tyZXNpZHVhbH1eMiQpLCBzdHVkeS1sZXZlbCBvYnNlcnZhdGlvbnMgKCRcc2lnbWFfe3N0dWR5fV4yJCksIHNwZWNpZXMgaWRlbnRpdHkgKCRcc2lnbWFfe3NwZWNpZXN9XjIkKSwgYW5kIHBoeWxvZ2VuZXRpYyByZWxhdGVkbmVzcyAoJFxzaWdtYV97cGh5bG9nZW55fV4yJCkuCgpgYGB7ciB0YWJsZVM1LCBlY2hvID0gRkFMU0V9CiMgRml4ZWQgZWZmZWN0CmZlZiA8LSBicm1zOjpmaXhlZihvdmVyYWxsX21vZGVsKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSguKSAlPiUKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gc3RyX3JlcGxhY2UoUGFyYW1ldGVyLCAiTSIsICItIikpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IGNhc2Vfd2hlbigKICAgIFBhcmFtZXRlciA9PSAiSW50ZXJjZXB0IiB+ICIkXFxiZXRhXzAkIiwKICAgIFBhcmFtZXRlciA9PSAidGltZV9wb3N0X2RheXMiICB+ICJEYXlzIHBvc3QtZXhwb3N1cmUiLAogICAgUGFyYW1ldGVyID09ICJsaWZlX3N0YWdlSnV2ZW5pbGUiICB+ICJMaWZlIHN0YWdlIC0gSnV2ZW5pbGVzIiwKICAgIFBhcmFtZXRlciA9PSAib3JpZ2luV2lsZCIgIH4gIk9yaWdpbiAtIFdpbGQiLAogICAgUGFyYW1ldGVyID09ICJsbkRvc2UiICB+ICJsbkRvc2UiLAogICAgUGFyYW1ldGVyID09ICJ0cnRfdGVtcCIgIH4gIlRyZWF0bWVudCB0ZW1wZXJhdHVyZSIpKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkZpeGVkIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSYW5kb20gZWZmZWN0CnJlZiA8LSBzdW1tYXJ5KG92ZXJhbGxfbW9kZWwpJHJhbmRvbSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lICMgdW5saXN0CiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KDE6NSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gYygiJFxcc2lnbWFfe3Jlc2lkdWFsfV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3BoeWxvZ2VueX1eMiQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3NwZWNpZXN9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3tzdHVkeX1eMiQiKSkgJT4lICAgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IDQsIAogICAgICAgICAgICAgICAgUTk3LjUgPSA1KSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkdyb3VwLWxldmVsIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKGZlZiwgcmVmKSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIAogIGtuaXRyOjprYWJsZShkaWdpdHMgPSAyKQpgYGAKCgojIyMgVGFibGUgUzYgLSBUcmFpdCBtb2RlbCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzYuKiogTWVhbiBwYXJhbWV0ZXIgZXN0aW1hdGVzLCBlc3RpbWF0ZSBlcnJvciwgYW5kIDk1JSBCYXllc2lhbiBjcmVkaWJsZSBpbnRlcnZhbHMgZm9yIHRoZSB0cmFpdCBtb2RlbCwgd2hpY2ggaW5jbHVkZXMgdGhlIGJpb2xvZ2ljYWwgYW5kIGZ1bmN0aW9uYWwgdHJhaXRzLCBsaWZlIHN0YWdlIChqdXZlbmlsZSBvciBhZHVsdCksIGFuZCBwdWJsaWNhdGlvbiB5ZWFyIGFzIGZpeGVkIGVmZmVjdHMuIEdyb3VwLWxldmVsIGVmZmVjdHMgaW5jbHVkZSB0aGUgc3RhbmRhcmQgZGV2aWF0aW9ucyAoJFxzaWdtYSQpIGZvciBpbmRpdmlkdWFsLWxldmVsIG9ic2VydmF0aW9ucyAoJFxzaWdtYV97cmVzaWR1YWx9XjIkKSwgc3R1ZHktbGV2ZWwgb2JzZXJ2YXRpb25zICgkXHNpZ21hX3tzdHVkeX1eMiQpLCBzcGVjaWVzIGlkZW50aXR5ICgkXHNpZ21hX3tzcGVjaWVzfV4yJCksIGFuZCBwaHlsb2dlbmV0aWMgcmVsYXRlZG5lc3MgKCRcc2lnbWFfe3BoeWxvZ2VueX1eMiQpLgoKYGBge3IgdGFibGVTNiwgZWNobyA9IEZBTFNFfQojIEZpeGVkIGVmZmVjdApmZWYgPC0gYnJtczo6Zml4ZWYodHJhaXRfbW9kZWwpICU+JSAKICBhcy5kYXRhLmZyYW1lKC4pICU+JQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBzdHJfcmVwbGFjZShQYXJhbWV0ZXIsICJNIiwgIi0iKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gY2FzZV93aGVuKAogICAgUGFyYW1ldGVyID09ICJ0cmFpdEJlaGF2aW91ciIgfiAiQmVoYXZpb3VyIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRCb2R5Y29uZGl0aW9uIiB+ICJCb2R5IGNvbmRpdGlvbiIsCiAgICBQYXJhbWV0ZXIgPT0gInRyYWl0Q2FyZGlvdmFzY3VsYXIiIH4gIkNhcmRpb3Zhc2N1bGFyIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRFbmVyZ3ltZXRhYm9saXNtIiB+ICJFbmVyZ3kgbWV0YWJvbGlzbSIsCiAgICBQYXJhbWV0ZXIgPT0gInRyYWl0SG9ybW9uZWxldmVsIiB+ICJIb3Jtb24gZWxldmVsIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRJbW11bmUiIH4gIkltbXVuZSIsCiAgICBQYXJhbWV0ZXIgPT0gInRyYWl0T3Ntb3JlZ3VsYXRpb24iIH4gIk9zbW9yZWd1bGF0aW9uIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRSZXByb2R1Y3Rpb24iIH4gIlJlcHJvZHVjdGlvbiIsCiAgICBQYXJhbWV0ZXIgPT0gInRyYWl0U2tpbmludGVncml0eSIgfiAiU2tpbiBpbnRlZ3JpdHkiLAogICAgUGFyYW1ldGVyID09ICJ0cmFpdFRoZXJtb3JlZ3VsYXRpb24iIH4gIlRoZXJtb3JlZ3VsYXRpb24iLAogICAgUGFyYW1ldGVyID09ICJsaWZlX3N0YWdlSnV2ZW5pbGUiICB+ICJMaWZlIHN0YWdlIC0gSnV2ZW5pbGVzIiwKICAgIFBhcmFtZXRlciA9PSAieWVhcl9jZW50cmUiICB+ICJQdWJsaWNhdGlvbiB5ZWFyIikpICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqRml4ZWQgZWZmZWN0cyoqIiwgLmJlZm9yZSA9IDEpCgojIFJhbmRvbSBlZmZlY3QKcmVmIDwtIHN1bW1hcnkodHJhaXRfbW9kZWwpJHJhbmRvbSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lICMgdW5saXN0CiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KDE6NSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gYygiJFxcc2lnbWFfe3Jlc2lkdWFsfV4yJCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3BoeWxvZ2VueX1eMiQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJFxcc2lnbWFfe3NwZWNpZXN9XjIkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiRcXHNpZ21hX3tzdHVkeX1eMiQiKSkgJT4lICAgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IDQsIAogICAgICAgICAgICAgICAgUTk3LjUgPSA1KSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkdyb3VwLWxldmVsIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKGZlZiwgcmVmKSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIAogIGtuaXRyOjprYWJsZShkaWdpdHMgPSAyKQpgYGAKCioqKgoKIyBUcmFpdCBzZW5zaXRpdml0eSBhbmFseXNpcyB7LX0KCiMjIENhbGN1bGF0aW5nIHRyYWl0IHNlbnNpdGl2aXR5IHstfQoKVGhlIGZvbGxvd2luZyB3b3JrZmxvdyB1c2VzIHRoZSByYXcgZGF0YSBzZXQgdG8gZXN0aW1hdGUgcmVzcG9uc2Utc3BlY2lmaWMgc2Vuc2l0aXZpdHkgdG8gKkJkKiBpbmZlY3Rpb24uIEFsbCByZXNwb25zZSB2YWx1ZXMgd2VyZSBzdGFuZGFyZGlzZWQgdG8gcmVsYXRpdmUgY2hhbmdlIGluIHJlc3BvbnNlLgoKYGBge3Igc2VufQojIEV4dHJhY3QgbWVhbiwgMTB0aCBhbmQgOTB0aCBxdWFudGlsZSBjb250cm9sIHZhbHVlcyBieSBzcGVjaWVzIGFuZCByZXNwb25zZXMKY29udHJvbF9tZWFuIDwtIGFzLmRhdGEuZnJhbWUodHJhaXRfZGF0ICU+JQogIGRwbHlyOjpmaWx0ZXIoQmQgPT0gMCkgJT4lIAogIGRwbHlyOjpncm91cF9ieShzcGVjaWVzLCByZXNwb25zZSkgJT4lIAogIGRwbHlyOjpzdW1tYXJpc2UobWVhbiAgICAgICAgICAgID0gbWVhbih0cmFpdF92YWx1ZSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgIHF1YW50aWxlXzEwICAgICA9IHF1YW50aWxlKHRyYWl0X3ZhbHVlLCAuMTApLAogICAgICAgICAgICAgICAgICAgcXVhbnRpbGVfOTAgICAgID0gcXVhbnRpbGUodHJhaXRfdmFsdWUsIC45MCkpICU+JQogIHRpZHlyOjp1bml0ZSgic3BlY2lmaWNfcmVzcG9uc2UiLCBjKHNwZWNpZXMsIHJlc3BvbnNlKSwgc2VwID0gIl8iLCAgcmVtb3ZlID0gRkFMU0UpKSAjIHVuaXF1ZSBpZGVudGlmaWVyIGJ5IHNwZWNpZXMgYW5kIHJlc3BvbnNlCgojIENvbWJpbmUgbWVhbiBjb250cm9scyBhbmQgY2FsY3VsYXRlIHJlbGF0aXZlIGNoYW5nZSBvZiByZXNwb25zZQp0cmFpdHNfZXhwb3NlZCA8LSB0cmFpdF9kYXQgJT4lIAogIHRpZHlyOjp1bml0ZSgic3BlY2lmaWNfcmVzcG9uc2UiLCBjKHNwZWNpZXMsIHJlc3BvbnNlKSwgc2VwID0gIl8iLCAgcmVtb3ZlID0gRkFMU0UpICU+JQogIGRwbHlyOjptdXRhdGUoY29udHJvbCAgICAgICAgICAgPSBjb250cm9sX21lYW4kbWVhblttYXRjaChzcGVjaWZpY19yZXNwb25zZSwgY29udHJvbF9tZWFuJHNwZWNpZmljX3Jlc3BvbnNlKV0sIAogICAgICAgICAgICAgICAgY2hhbmdlICAgICAgICAgICAgPSBpZmVsc2UodHJhaXRfdW5pdCA9PSAicmVsYXRpdmUiLCB0cmFpdF92YWx1ZSwgKHRyYWl0X3ZhbHVlIC0gY29udHJvbCkgLyBjb250cm9sKSwgIyBjYWxjdWxhdGUgcmVsYXRpdmUgY2hhbmdlCiAgICAgICAgICAgICAgICBzcGVjaWZpY19yZXNwb25zZSA9IGFzLmZhY3RvcihzcGVjaWZpY19yZXNwb25zZSksCiAgICAgICAgICAgICAgICBxdWFudGlsZV85MCAgICAgICA9IGNvbnRyb2xfbWVhbiRxdWFudGlsZV85MFttYXRjaChzcGVjaWZpY19yZXNwb25zZSwgY29udHJvbF9tZWFuJHNwZWNpZmljX3Jlc3BvbnNlKV0sCiAgICAgICAgICAgICAgICBxdWFudGlsZV8xMCAgICAgICA9IGNvbnRyb2xfbWVhbiRxdWFudGlsZV8xMFttYXRjaChzcGVjaWZpY19yZXNwb25zZSwgY29udHJvbF9tZWFuJHNwZWNpZmljX3Jlc3BvbnNlKV0sCiAgICAgICAgICAgICAgICBjb250cm9sXzkwICAgICAgICA9IGlmZWxzZSh0cmFpdF91bml0ID09ICJyZWxhdGl2ZSIsIHRyYWl0X3ZhbHVlLCAocXVhbnRpbGVfOTAgLSBjb250cm9sKSAvIGNvbnRyb2wpLCAjIGNhbGN1bGF0ZSByZWxhdGl2ZSA5MHRoIHF1YW50aWxlCiAgICAgICAgICAgICAgICBjb250cm9sXzEwICAgICAgICA9IGlmZWxzZSh0cmFpdF91bml0ID09ICJyZWxhdGl2ZSIsIHRyYWl0X3ZhbHVlLCAocXVhbnRpbGVfMTAgLSBjb250cm9sKSAvIGNvbnRyb2wpKSAjIGNhbGN1bGF0ZSByZWxhdGl2ZSAxMHRoIHF1YW50aWxlCgojIFJ1biBsbSBtb2RlbHMgdG8gZmluZCBvbmVzIHdpdGggZ29vZCBSMiAKUl9zcV9tb2RlbCA8LSBhcy5kYXRhLmZyYW1lKHRyYWl0c19leHBvc2VkICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcighaXMubmEoY2hhbmdlKSkgJT4lICMgcmVtb3ZlIE5BJ3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KHNwZWNpZmljX3Jlc3BvbnNlKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmRvKG1vZGVsID0gYnJvb206OmdsYW5jZShsbShjaGFuZ2UgfiBsbkJkLCBkYXRhID0gLikpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlkeXI6OnVubmVzdChtb2RlbCkpICU+JQogIGRwbHlyOjpzZWxlY3Qoc3BlY2lmaWNfcmVzcG9uc2UsIHIuc3F1YXJlZCwgYWRqLnIuc3F1YXJlZCwgcC52YWx1ZSkKCiMgZXh0cmFjdCBlcXVhdGlvbiAoaW50ZXJjZXB0IGFuZCBzbG9wZSkKbG1fZXEgPC0gYXMuZGF0YS5mcmFtZSh0cmFpdHNfZXhwb3NlZCAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShjaGFuZ2UpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShzcGVjaWZpY19yZXNwb25zZSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZG8obW9kZWwgPSBicm9vbTo6dGlkeShsbShjaGFuZ2UgfiBsbkJkLCBkYXRhID0gLikpKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICB0aWR5cjo6dW5uZXN0KG1vZGVsKSkgJT4lCiAgZHBseXI6OnNlbGVjdChzcGVjaWZpY19yZXNwb25zZSwgdGVybSwgZXN0aW1hdGUpICU+JQogIHJlc2hhcGUoaWR2YXIgPSAic3BlY2lmaWNfcmVzcG9uc2UiLCB0aW1ldmFyID0gInRlcm0iLCBkaXJlY3Rpb24gPSAid2lkZSIpICU+JSAjIGZyb20gbG9uZyB0byB3aWRlIGZvciBlc3RpbWF0ZSBjb2x1bW4KICBkcGx5cjo6cmVuYW1lKGludGVyY2VwdCA9ICJlc3RpbWF0ZS4oSW50ZXJjZXB0KSIsCiAgICAgICAgICAgICAgICBzbG9wZSAgICAgPSAiZXN0aW1hdGUubG5CZCIpCgojIERlYWwgd2l0aCByZWxhdGl2ZSB1bml0cyB0aGF0IHdlcmUgbm90IGNvbnZlcnRlZCBwcmV2aW91c2x5IChpZmVsc2UodHJhaXRfdW5pdCA9PSAicmVsYXRpdmUiLCB0cmFpdF92YWx1ZSwgKHF1YW50aWxlXzkwIC0gY29udHJvbCkgLyBjb250cm9sKSkKY29udHJvbF9yYW5nZSA8LSBhcy5kYXRhLmZyYW1lKHRyYWl0c19leHBvc2VkICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKEJkID09IDApICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoc3BlY2lmaWNfcmVzcG9uc2UpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKGNvbnRyb2xfOTAgPSBtYXgoY29udHJvbF85MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbF8xMCA9IG1pbihjb250cm9sXzEwKSkpCgojIEdlbmVyYXRlIEJkIGxvYWQgc2VxdWVuY2UgZnJvbSBtaW4gYW5kIG1heCBhbmQgcHJlZGljdCByZXNwb25zZQp4c2VxICAgICAgIDwtIHNlcSgwLCBtYXgodHJhaXRzX2V4cG9zZWQkbG5CZFshaXMubmEodHJhaXRzX2V4cG9zZWQkbG5CZCldKSwgbGVuZ3RoLm91dCA9IDUwKQplcV9iZF9wcmVkIDwtIGRhdGEuZnJhbWUobG1fZXEgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShzcGVjaWZpY19yZXNwb25zZSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpc2UocHJlZCA9IGludGVyY2VwdCArIHNsb3BlICogeHNlcSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUocHJlZF9iZCAgICA9IHhzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhaXQgICAgICA9IHRyYWl0c19leHBvc2VkJHRyYWl0W21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCB0cmFpdHNfZXhwb3NlZCRzcGVjaWZpY19yZXNwb25zZSldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgICAgPSB0cmFpdHNfZXhwb3NlZCRjb250cm9sW21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCB0cmFpdHNfZXhwb3NlZCRzcGVjaWZpY19yZXNwb25zZSldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xfOTAgPSBjb250cm9sX3JhbmdlJGNvbnRyb2xfOTBbbWF0Y2goc3BlY2lmaWNfcmVzcG9uc2UsIGNvbnRyb2xfcmFuZ2Ukc3BlY2lmaWNfcmVzcG9uc2UpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sXzEwID0gY29udHJvbF9yYW5nZSRjb250cm9sXzEwW21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCBjb250cm9sX3JhbmdlJHNwZWNpZmljX3Jlc3BvbnNlKV0pKQoKIyBLZWVwIHNwZWNpZmljIHJlc3BvbnNlcyB3aXRoIFIyID49IDAuMSBhbmQgcCB2YWx1ZSA8PSAwLjA1CnJlc3BvbnNlc19rZXB0IDwtIFJfc3FfbW9kZWwgJT4lIGRwbHlyOjpmaWx0ZXIoYWRqLnIuc3F1YXJlZCA+PSAwLjEgfCBwLnZhbHVlIDw9IDAuMDUpICU+JSBkcm9wbGV2ZWxzKCkKa2VwdF9wcmVkICAgICAgPC0gZXFfYmRfcHJlZCAlPiUgZHBseXI6OmZpbHRlcihzcGVjaWZpY19yZXNwb25zZSAlaW4lIGMobGV2ZWxzKHJlc3BvbnNlc19rZXB0JHNwZWNpZmljX3Jlc3BvbnNlKSkpICU+JSBkcm9wbGV2ZWxzKCkKCiMgRmlsdGVyIEJkIGxvYWQgbG93ZXIgdGhhbiAxMHRoIGFuZCBoaWdoZXIgdGhhbiA5MHRoIHF1YW50aWxlIGNvbnRyb2wgdmFsdWVzIApzZW5zaXRpdml0eV9wb3MgPC0gZGF0YS5mcmFtZShrZXB0X3ByZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KHNwZWNpZmljX3Jlc3BvbnNlKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKHByZWRfYmQgIT0gMCAmIHByZWQgPiAwKSAlPiUgIyBpbiBwb3NpdGl2ZSBkaXJlY3Rpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKHByZWQgPiBjb250cm9sXzkwKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXplKG1pbkJkID0gbWluKHByZWRfYmQpKSkKCnNlbnNpdGl2aXR5X25lZyA8LSBkYXRhLmZyYW1lKGtlcHRfcHJlZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpncm91cF9ieShzcGVjaWZpY19yZXNwb25zZSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKHByZWRfYmQgIT0gMCAmIHByZWQgPCAwKSAlPiUgICMgaW4gbmVnYXRpdmUgZGlyZWN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGNhc2Vfd2hlbihjb250cm9sIDwgMCB+IHByZWQgPCBjb250cm9sXzkwLCBUIH4gcHJlZCA8IGNvbnRyb2xfMTApKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzdW1tYXJpemUobWluQmQgPSBtaW4ocHJlZF9iZCkpKQoKIyBDb21iaW5lIHNlbnNpdGl2aXR5X3BvcyBhbmQgc2Vuc2l0aXZpdHlfbmVnCnNlbnNpdGl2aXR5IDwtIHJiaW5kKHNlbnNpdGl2aXR5X3Bvcywgc2Vuc2l0aXZpdHlfbmVnKSAlPiUKICBkcGx5cjo6bXV0YXRlKGxubWluQmQgICAgID0gbWluQmQsCiAgICAgICAgICAgICAgICByZXNwb25zZSAgICA9IHRyYWl0c19leHBvc2VkJHJlc3BvbnNlW21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCB0cmFpdHNfZXhwb3NlZCRzcGVjaWZpY19yZXNwb25zZSldLAogICAgICAgICAgICAgICAgdHJhaXQgICAgICAgPSB0cmFpdHNfZXhwb3NlZCR0cmFpdFttYXRjaChzcGVjaWZpY19yZXNwb25zZSwgdHJhaXRzX2V4cG9zZWQkc3BlY2lmaWNfcmVzcG9uc2UpXSwKICAgICAgICAgICAgICAgIGJpb19oaWVyICAgID0gdHJhaXRzX2V4cG9zZWQkYmlvX2hpZXJbbWF0Y2goc3BlY2lmaWNfcmVzcG9uc2UsIHRyYWl0c19leHBvc2VkJHNwZWNpZmljX3Jlc3BvbnNlKV0sCiAgICAgICAgICAgICAgICBzcGVjaWVzICAgICA9IHRyYWl0c19leHBvc2VkJHNwZWNpZXNbbWF0Y2goc3BlY2lmaWNfcmVzcG9uc2UsIHRyYWl0c19leHBvc2VkJHNwZWNpZmljX3Jlc3BvbnNlKV0sCiAgICAgICAgICAgICAgICBzcGVjaWVzX09UTCA9IHRyYWl0c19leHBvc2VkJHNwZWNpZXNfT1RMW21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCB0cmFpdHNfZXhwb3NlZCRzcGVjaWZpY19yZXNwb25zZSldLAogICAgICAgICAgICAgICAgbGlmZV9zdGFnZSAgPSB0cmFpdHNfZXhwb3NlZCRsaWZlX3N0YWdlW21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCB0cmFpdHNfZXhwb3NlZCRzcGVjaWZpY19yZXNwb25zZSldLAogICAgICAgICAgICAgICAgbG5Eb3NlICAgICAgPSB0cmFpdHNfZXhwb3NlZCRsbkRvc2VbbWF0Y2goc3BlY2lmaWNfcmVzcG9uc2UsIHRyYWl0c19leHBvc2VkJHNwZWNpZmljX3Jlc3BvbnNlKV0sCiAgICAgICAgICAgICAgICBpbnZfdGVtcCAgICA9IHRyYWl0c19leHBvc2VkJGludl90ZW1wW21hdGNoKHNwZWNpZmljX3Jlc3BvbnNlLCB0cmFpdHNfZXhwb3NlZCRzcGVjaWZpY19yZXNwb25zZSldKQoKc2Vuc2l0aXZpdHkkc3BlY2llcyA8LSBzdWIoIiAiLCAiXyIsIHNlbnNpdGl2aXR5JHNwZWNpZXNfT1RMKQpzZW5zaXRpdml0eSRzcGVjaWVzIDwtIGZhY3RvcihzZW5zaXRpdml0eSRzcGVjaWVzLCBsZXZlbHMgPSB0cmVlX3RpcF9sYWJlbCkgIyByZWxldmVsIG9yZGVyIGJ5IHRyZWUKYGBgCgojIyBTZW5zaXRpdml0eSBhbmFseXNpcyB7LX0KClJ1biBwaHlsb2dlbmV0aWMgY29ycmVjdGVkLCBtdWx0aS1sZXZlbCBtb2RlbCB0byB0ZXN0IHRoZSBzZW5zaXRpdml0eSBvZiB0cmFpdHMgdG8gKkJkKiBsb2FkLgoKYGBge3Igc2VuIG1vZGVsLCBtZXNzYWdlPUZBTFNFLCBjYWNoZT1UUlVFLCByZXN1bHRzPSJoaWRlIn0Kc2V0LnNlZWQoMTApCnNlbnNpdGl2ZV9tb2RlbCA8LSBicm1zOjpicm0obG5taW5CZCB+IC0xICsgdHJhaXQgKyBsbkRvc2UgKyBpbnZfdGVtcCArICgxIHwgc3BlY2llc19PVEwpICsgKDEgfCBncihzcGVjaWVzLCBjb3YgPSBwaHlsbykpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgICAgPSBzZW5zaXRpdml0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgID0gZ2F1c3NpYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTIgICA9IGxpc3QocGh5bG8gPSBwaHlsb19jb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yICAgPSBjKHByaW9yKG5vcm1hbCgwLCA1KSwgbGIgPSAwKSwgIyBtZWFuIG9mIDAgYW5kIFNEIG9mIDUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3Ioc3R1ZGVudF90KDMsIDAsIDUpLCAic2QiKSwgIyBjbGFzcyBvZiByYW5kb20gZWZmZWN0IGRldmlhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvcihzdHVkZW50X3QoMywgMCwgNSksICJzaWdtYSIpKSwgIyByZXNpZHVhbCBTRCBwYXJhbWV0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyICAgID0gMWU0LCB3YXJtdXAgPSA1ZTMsIGNvcmVzID0gNCwgY2hhaW5zID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTksIG1heF90cmVlZGVwdGggPSAxOCkpCmBgYAoKYGBge3IgRmlnIFM2LCBlY2hvID0gRkFMU0UsIGZpZy53aWR0aCA9IDQsIGZpZy5oZWlnaHQgPSAzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30KYnJtczo6cHBfY2hlY2soc2Vuc2l0aXZlX21vZGVsLCB0eXBlID0gInNjYXR0ZXJfYXZnIikKYGBgCgoqKkZpZy4gUzYuKiogU2NhdHRlcnBsb3Qgb2YgdGhlIG9ic2VydmVkIGRhdGEgKHkpIHZzIHRoZSBhdmVyYWdlIHNpbXVsYXRlZCBkYXRhICh5cmVwKSBmcm9tIHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24uIERhc2hlZCBsaW5lIHJlcHJlc2VudHMgYSBzbG9wZSBvZiAxLgoKIyMgTW9kZWwgb3V0cHV0IHstfQoKKipUYWJsZSBTNy4qKiBNZWFuIHBhcmFtZXRlciBlc3RpbWF0ZXMsIGVzdGltYXRlIGVycm9yLCBhbmQgOTUlIEJheWVzaWFuIGNyZWRpYmxlIGludGVydmFscyBmb3IgdGhlIHNlbnNpdGl2aXR5IG1vZGVsLCB3aGljaCBpbmNsdWRlcyB0aGUgZnVuY3Rpb25hbCB0cmFpdHMsIG5hdHVyYWwgbG9nYXJpdGhtIG9mIGlub2N1bGF0aW9uIGRvc2UgKGxuRG9zZSksIGFuZCB0aGUgaW52ZXJzZSBvZiB0ZW1wZXJhdHVyZSBhcyBmaXhlZCBlZmZlY3RzLiBHcm91cC1sZXZlbCBlZmZlY3RzIGluY2x1ZGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgKCRcc2lnbWEkKSBmb3Igc3BlY2llcyBpZGVudGl0eSAoJFxzaWdtYV97c3BlY2llc31eMiQpLCBhbmQgcGh5bG9nZW5ldGljIHJlbGF0ZWRuZXNzICgkXHNpZ21hX3twaHlsb2dlbnl9XjIkKS4KCmBgYHtyIHRhYmxlUzcsIGVjaG8gPSBGQUxTRX0KIyBGaXhlZCBlZmZlY3QKZmVmIDwtIGJybXM6OmZpeGVmKHNlbnNpdGl2ZV9tb2RlbCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoLikgJT4lCiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6bXV0YXRlKFBhcmFtZXRlciA9IHN0cl9yZXBsYWNlKFBhcmFtZXRlciwgIk0iLCAiLSIpKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBjYXNlX3doZW4oCiAgICBQYXJhbWV0ZXIgPT0gInRyYWl0QmVoYXZpb3VyIiB+ICJCZWhhdmlvdXIiLAogICAgUGFyYW1ldGVyID09ICJ0cmFpdEJvZHljb25kaXRpb24iIH4gIkJvZHkgY29uZGl0aW9uIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRDYXJkaW92YXNjdWxhciIgfiAiQ2FyZGlvdmFzY3VsYXIiLAogICAgUGFyYW1ldGVyID09ICJ0cmFpdEVuZXJneW1ldGFib2xpc20iIH4gIkVuZXJneSBtZXRhYm9saXNtIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRIb3Jtb25lbGV2ZWwiIH4gIkhvcm1vbmUgbGV2ZWwiLAogICAgUGFyYW1ldGVyID09ICJ0cmFpdEltbXVuZSIgfiAiSW1tdW5lIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRPc21vcmVndWxhdGlvbiIgfiAiT3Ntb3JlZ3VsYXRpb24iLAogICAgUGFyYW1ldGVyID09ICJ0cmFpdFJlcHJvZHVjdGlvbiIgfiAiUmVwcm9kdWN0aW9uIiwKICAgIFBhcmFtZXRlciA9PSAidHJhaXRTa2luaW50ZWdyaXR5IiB+ICJTa2luIGludGVncml0eSIsCiAgICBQYXJhbWV0ZXIgPT0gImxuRG9zZSIgIH4gImxuRG9zZSIsCiAgICBQYXJhbWV0ZXIgPT0gImludl90ZW1wIiAgfiAiSW52ZXJzZSB0ZW1wZXJhdHVyZSIpKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkZpeGVkIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSYW5kb20gZWZmZWN0CnJlZiA8LSBzdW1tYXJ5KHNlbnNpdGl2ZV9tb2RlbCkkcmFuZG9tICU+JSAKICBiaW5kX3Jvd3MoKSAlPiUgIyB1bmxpc3QKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjpzZWxlY3QoMTo1KSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBjKCIkXFxzaWdtYV97cGh5bG9nZW55fV4yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97c3BlY2llc31eMiQiKSkgJT4lICAgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IDQsIAogICAgICAgICAgICAgICAgUTk3LjUgPSA1KSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkdyb3VwLWxldmVsIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKGZlZiwgcmVmKSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIAogIGtuaXRyOjprYWJsZShkaWdpdHMgPSAyKQpgYGAKCioqKgoKIyBTdXJ2aXZhbCBhbmFseXNpcyB7LX0KClRoZSBzdXJ2aXZhbCBkYXRhIHNldCBjb21wcmlzZXMgb2YgYHIgbGVuZ3RoKHVuaXF1ZShsZXZlbHMoc3Vydl9kYXQkc3BlY2llc19PVEwpKSlgIHNwZWNpZXMuIAoKYGBge3Igc3Vydn0KIyBSZW5hbWUgc3BlY2llcyBiYXNlZCBvbiBzcGVjaWVzX09UTApzdXJ2X2RhdCRzcGVjaWVzIDwtIHN1YigiICIsICJfIiwgc3Vydl9kYXQkc3BlY2llc19PVEwpCnN1cnZfZGF0JHNwZWNpZXMgPC0gZmFjdG9yKHN1cnZfZGF0JHNwZWNpZXMsIGxldmVscyA9IHRyZWVfdGlwX2xhYmVsKSAjIHJlbGV2ZWwgb3JkZXIgYnkgdHJlZQpzdXJ2X2RhdCA8LSBzdXJ2X2RhdCAlPiUgZHBseXI6Om11dGF0ZShzcGVjaWVzID0gZmFjdG9yKHNwZWNpZXMpKQpgYGAKCiMjIFN1cnZpdmFsIGFuZCAqQmQqIGFuZCB0aW1lLWRlcGVuZGVudCBtb3J0YWxpdHkgYW5hbHlzaXMgey19CgpSdW4gcGh5bG9nZW5ldGljIGNvcnJlY3RlZCwgbXVsdGktbGV2ZWwgbW9kZWxzIHRvIHRlc3QgZm9yIHRoZSBpbmZsdWVuY2Ugb2YgKkJkKiBsb2FkIG9uIHN1cnZpdmFsLgoKYGBge3Igc3VydiBtb2RlbCwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSwgcmVzdWx0cz0iaGlkZSJ9CiMgQmluYXJ5IGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwKc2V0LnNlZWQoMTApCnN1cnZfbW9kZWwgPC0gYnJtczo6YnJtKGFsaXZlIH4gMSArIGxuQmQgKyB0aW1lX3Bvc3RfZGF5cyArIGxuRG9zZSArIGxpZmVfc3RhZ2UgKyBpbnZfdGVtcCArIHNwZWNpZXNfT1RMICsgKDEgfCBzdHVkeV9JRDpzcGVjaWVzX09UTCkgKyAoMSB8IGdyKHNwZWNpZXMsIGNvdiA9IHBoeWxvKSksICAKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSAgID0gc3Vydl9kYXQsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJlcm5vdWxsaShsaW5rID0gImxvZ2l0IiksIAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhMiAgID0gbGlzdChwaHlsbyA9IHBoeWxvX2NvciksCiAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMiksIGNsYXNzID0gSW50ZXJjZXB0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAyKSwgY2xhc3MgPSBiKSksCiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgPSA1ZTMsIHdhcm11cCA9IDJlMywgY2hhaW5zID0gNCwgY29yZXMgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTksIG1heF90cmVlZGVwdGggPSAxOCkpCgp0aW1lX2JkX21vZGVsIDwtIGJybXM6OmJybShsbkJkIH4gbG5UaW1lICogbGlmZV9zdGFnZSArIGxuRG9zZSArIGludl90ZW1wICsgKDEgfCBzdHVkeV9JRDpzcGVjaWVzX09UTCksICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSAgICA9IHN1cnZfZGF0ICU+JSBkcGx5cjo6ZmlsdGVyKGFsaXZlID09IDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHkgID0gZ2F1c3NpYW4oKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IgICA9IGMocHJpb3Iobm9ybWFsKDAsIDIpLCBjbGFzcyA9IEludGVyY2VwdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKG5vcm1hbCgwLCAyKSwgY2xhc3MgPSBiKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgICAgPSA1ZTMsIHdhcm11cCA9IDJlMywgY2hhaW5zID0gNCwgY29yZXMgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTksIG1heF90cmVlZGVwdGggPSAxOCkpCmBgYAoKYGBge3IgRmlnIFM3LCBlY2hvID0gRkFMU0UsIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSAzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30Kc3Vydl9tb2RlbF9wcCAgICA8LSBicm1zOjpwcF9jaGVjayhzdXJ2X21vZGVsKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQp0aW1lX2JkX21vZGVsX3BwIDwtIGJybXM6OnBwX2NoZWNrKHRpbWVfYmRfbW9kZWwsIHR5cGUgPSAic2NhdHRlcl9hdmciKSAKCmNvd3Bsb3Q6OnBsb3RfZ3JpZChzdXJ2X21vZGVsX3BwLCB0aW1lX2JkX21vZGVsX3BwLCBuY29sID0gMiwgYWxpZ24gPSAiaCIsIGF4aXMgPSAiYnQiLCBsYWJlbHMgPSBjKCdhJywgJ2InKSkKYGBgCgoqKkZpZy4gUzcuKiogUG9zdGVyaW9yIHByZWRpY3RpdmUgY2hlY2sgZm9yICgqKmEqKikgdGhlIHN1cnZpdmFsIG1vZGVsLCBhbmQgKCoqYioqKSB0aGUgKkJkKi10aW1lIG1vZGVsLiBUaGUgKkJkKi10aW1lIG1vZGVsIGlzIHJlcHJlc2VudGVkIGJ5IGEgc2NhdHRlcnBsb3Qgb2YgdGhlIG9ic2VydmVkIGRhdGEgKHkpIHZzIHRoZSBhdmVyYWdlIHNpbXVsYXRlZCBkYXRhICh5cmVwKSBmcm9tIHRoZSBwb3N0ZXJpb3IgcHJlZGljdGl2ZSBkaXN0cmlidXRpb24uIERhc2hlZCBsaW5lIHJlcHJlc2VudHMgYSBzbG9wZSBvZiAxLgoKIyMgTW9kZWwgb3V0cHV0IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC0gfQoKIyMjIFRhYmxlIFM4IC0gU3Vydml2YWwgbW9kZWwgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHMgLX0gCgoqKlRhYmxlIFM4LioqIE1lYW4gcGFyYW1ldGVyIGVzdGltYXRlcywgZXN0aW1hdGUgZXJyb3IsIGFuZCA5NSUgQmF5ZXNpYW4gY3JlZGlibGUgaW50ZXJ2YWxzIGZvciB0aGUgcHJvYmFiaWxpdHkgb2Ygc3Vydml2YWwsIHdoaWNoIGluY2x1ZGVzIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiAqQmQqIGxvYWQgKGxuQmQpLCBkYXlzIHBvc3QgZXhwb3N1cmUsIG5hdHVyYWwgbG9nYXJpdGhtIG9mIGlub2N1bGF0aW9uIGRvc2UgKGxuRG9zZSksIGxpZmUgc3RhZ2UsIGFuZCB0aGUgaW52ZXJzZSBvZiB0ZW1wZXJhdHVyZSBhcyBmaXhlZCBlZmZlY3RzLiBHcm91cC1sZXZlbCBlZmZlY3RzIGluY2x1ZGUgdGhlIHN0YW5kYXJkIGRldmlhdGlvbnMgKCRcc2lnbWEkKSBmb3IgcGh5bG9nZW5ldGljIHJlbGF0ZWRuZXNzICgkXHNpZ21hX3twaHlsb2dlbnl9XjIkKSBhbmQgc3BlY2llcy1zdHVkeSBpbnRlcmFjdGlvbiAoJFxzaWdtYV97c3BlY2llczpzdHVkeX1eMiQpLgoKYGBge3IgdGFibGVTOCwgZWNobyA9IEZBTFNFfQojIEZpeGVkIGVmZmVjdApmZWYgPC0gYnJtczo6Zml4ZWYoc3Vydl9tb2RlbCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoLikgJT4lCiAgZHBseXI6OnNsaWNlX2hlYWQobiA9IDYpICU+JQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBzdHJfcmVwbGFjZShQYXJhbWV0ZXIsICJNIiwgIi0iKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gY2FzZV93aGVuKAogICAgUGFyYW1ldGVyID09ICJJbnRlcmNlcHQiIH4gIiRcXGJldGFfMCQiLAogICAgUGFyYW1ldGVyID09ICJsbkJkIiAgfiAibG5CZCIsCiAgICBQYXJhbWV0ZXIgPT0gInRpbWVfcG9zdF9kYXlzIiAgfiAiRGF5cyBwb3N0LWV4cG9zdXJlIiwKICAgIFBhcmFtZXRlciA9PSAibG5Eb3NlIiAgfiAibG5Eb3NlIiwKICAgIFBhcmFtZXRlciA9PSAibGlmZV9zdGFnZUp1dmVuaWxlIiAgfiAiTGlmZSBzdGFnZSAtIEp1dmVuaWxlIiwKICAgIFBhcmFtZXRlciA9PSAiaW52X3RlbXAiICB+ICJJbnZlcnNlIHRlbXBlcmF0dXJlIikpICU+JSAKICB0aWJibGU6OmFkZF9yb3coUGFyYW1ldGVyID0gIioqRml4ZWQgZWZmZWN0cyoqIiwgLmJlZm9yZSA9IDEpCgojIFJhbmRvbSBlZmZlY3QKcmVmIDwtIHN1bW1hcnkoc3Vydl9tb2RlbCkkcmFuZG9tICU+JSAKICBiaW5kX3Jvd3MoKSAlPiUgIyB1bmxpc3QKICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiUGFyYW1ldGVyIikgJT4lIAogIGRwbHlyOjpzZWxlY3QoMTo1KSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBjKCIkXFxzaWdtYV97cGh5bG9nZW55fV4yJCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIkXFxzaWdtYV97c3BlY2llczpzdHVkeX1eMiQiKSkgJT4lICAgCiAgZHBseXI6OnJlbmFtZShRMi41ICA9IDQsIAogICAgICAgICAgICAgICAgUTk3LjUgPSA1KSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkdyb3VwLWxldmVsIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSZW5kZXIgdGFibGUKYmluZF9yb3dzKGZlZiwgcmVmKSAlPiUgCiAgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIAogIGtuaXRyOjprYWJsZShkaWdpdHMgPSAyKQpgYGAKCiMjIyBUYWJsZSBTOSAtIFRocmVzaG9sZCB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxscyAtfSAKCioqVGFibGUgUzkuKiogUHJlZGljdGVkIDUwJSBhbmQgOTAlIHN1cnZpdmFsIHRocmVzaG9sZCBieSBzcGVjaWVzIHByZXNlbnRlZCBhcyB6b29zcG9yZSBlcXVpdmFsZW50IChaRSkgYW5kIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiBaRSAobG4gWkUgKyAxKS4KCmBgYHtyIHRhYmxlUzksIGVjaG8gPSBGQUxTRX0KIyBFeHRyYWN0IG1hcmdpbmFsIGVmZmVjdHMKc3Vydl9tYXJnX2VmZiA8LSBhcy5kYXRhLmZyYW1lKGdnZWZmZWN0czo6Z2dwcmVkaWN0KHN1cnZfbW9kZWwsIHRlcm1zID0gYygibG5CZFtzYW1wbGUgPSA0MDBdIiwgInNwZWNpZXNfT1RMIikpKQpzdXJ2X21hcmdfZWZmIDwtIHN1cnZfbWFyZ19lZmYgJT4lCiAgZHBseXI6Om11dGF0ZShzcGVjaWVzICAgID0gc3Vydl9kYXQkc3BlY2llc1ttYXRjaChncm91cCwgc3Vydl9kYXQkc3BlY2llc19PVEwpXSwKICAgICAgICAgICAgICAgIGZhbWlseSAgICAgPSBzdXJ2X2RhdCRmYW1pbHlbbWF0Y2goZ3JvdXAsIHN1cnZfZGF0JHNwZWNpZXNfT1RMKV0sCiAgICAgICAgICAgICAgICBsaWZlX3N0YWdlID0gc3Vydl9kYXQkbGlmZV9zdGFnZVttYXRjaChncm91cCwgc3Vydl9kYXQkc3BlY2llc19PVEwpXSkKCiMgUHJlZGljdCA1MCUgaW5mbGljdGlvbiBwb2ludAppbmZsaWN0X2VzdCA8LSBkYXRhLmZyYW1lKHN1cnZfbWFyZ19lZmYgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZ3JvdXAsIGZhbWlseSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihwcmVkaWN0ZWQgPCAwLjUyICYgcHJlZGljdGVkID4gMC40OCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZSh0aHJlc2hvbGQgPSBtZWFuKHgpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoYmQgPSBleHAodGhyZXNob2xkKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIlNwZWNpZXMiID0gZ3JvdXAsCiAgICAgICAgICAgICAgICAiRmFtaWx5IiAgPSBmYW1pbHksCiAgICAgICAgICAgICAgICAiNTAlIChsbiBaRSArIDEpIiA9IHRocmVzaG9sZCwKICAgICAgICAgICAgICAgICI1MCUgKFpFICsgMSkiID0gYmQpCgppbmZsaWN0XzkwX2VzdCA8LSBkYXRhLmZyYW1lKHN1cnZfbWFyZ19lZmYgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6Z3JvdXBfYnkoZ3JvdXAsIGZhbWlseSkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihwcmVkaWN0ZWQgPCAwLjEyICYgcHJlZGljdGVkID4gMC4wOCkgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OnN1bW1hcmlzZSh0aHJlc2hvbGQgPSBtZWFuKHgpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUoYmQgPSBleHAodGhyZXNob2xkKSkpICU+JQogIGRwbHlyOjpyZW5hbWUoIlNwZWNpZXMiID0gZ3JvdXAsCiAgICAgICAgICAgICAgICAiRmFtaWx5IiAgPSBmYW1pbHksCiAgICAgICAgICAgICAgICAiOTAlIChsbiBaRSArIDEpIiA9IHRocmVzaG9sZCwKICAgICAgICAgICAgICAgICI5MCUgKFpFICsgMSkiID0gYmQpCgptZXJnZShpbmZsaWN0X2VzdCwgaW5mbGljdF85MF9lc3QsIGJ5ID0gYygiU3BlY2llcyIsICJGYW1pbHkiKSkgJT4lCiAgZm9ybWF0X2NlbGxzKDE6MjgsIDEsICJpdGFsaWNzIikgJT4lCiAgdGliYmxlOjphZGRfcm93KFNwZWNpZXMgPSAiIikgJT4lCiAgdGliYmxlOjphZGRfcm93KFNwZWNpZXMgPSAiKipBdmVyYWdlKioiLAogICAgICAgICAgICAgICAgICAiNTAlIChsbiBaRSArIDEpIiA9IG1lYW4oaW5mbGljdF9lc3QkIjUwJSAobG4gWkUgKyAxKSIpLAogICAgICAgICAgICAgICAgICAiNTAlIChaRSArIDEpIiAgICA9IG1lYW4oaW5mbGljdF9lc3QkIjUwJSAoWkUgKyAxKSIpLAogICAgICAgICAgICAgICAgICAiOTAlIChsbiBaRSArIDEpIiA9IG1lYW4oaW5mbGljdF85MF9lc3QkIjkwJSAobG4gWkUgKyAxKSIpLAogICAgICAgICAgICAgICAgICAiOTAlIChaRSArIDEpIiAgICA9IG1lYW4oaW5mbGljdF85MF9lc3QkIjkwJSAoWkUgKyAxKSIpKSAlPiUKICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikKYGBgCgojIyMgVGFibGUgUzEwIC0gKkJkKi10aW1lIG1vZGVsIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzIC19IAoKKipUYWJsZSBTMTAuKiogTWVhbiBwYXJhbWV0ZXIgZXN0aW1hdGVzLCBlc3RpbWF0ZSBlcnJvciwgYW5kIDk1JSBCYXllc2lhbiBjcmVkaWJsZSBpbnRlcnZhbHMgZm9yIHRoZSAqQmQqLXRpbWUgbW9kZWwsIHdoaWNoIGluY2x1ZGVzIHRoZSBuYXR1cmFsIGxvZ2FyaXRobSBvZiBkYXlzIHBvc3QtZXhwb3N1cmUgKGxuVGltZSksIGxpZmUgc3RhZ2UsIHJlc2lzdGFuY2UsIHRoZSBpbnZlcnNlIG9mIHRlbXBlcmF0dXJlIGFuZCB0aGUgaW50ZXJhY3Rpb24gb2YgbG5UaW1lIGFuZCBsaWZlIHN0YWdlIGFzIGZpeGVkIGVmZmVjdHMuIEdyb3VwLWxldmVsIGVmZmVjdHMgaW5jbHVkZSB0aGUgc3BlY2llcy1zdHVkeSBpbnRlcmFjdGlvbiAoJFxzaWdtYV97c3BlY2llczpzdHVkeX1eMiQpLgoKYGBge3IgdGFibGVTMTAsIGVjaG8gPSBGQUxTRX0KIyBGaXhlZCBlZmZlY3QKZmVmIDwtIGJybXM6OmZpeGVmKHRpbWVfYmRfbW9kZWwpICU+JSAKICBhcy5kYXRhLmZyYW1lKC4pICU+JQogIHRpYmJsZTo6cm93bmFtZXNfdG9fY29sdW1uKCJQYXJhbWV0ZXIiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShQYXJhbWV0ZXIgPSBzdHJfcmVwbGFjZShQYXJhbWV0ZXIsICJNIiwgIi0iKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gY2FzZV93aGVuKAogICAgUGFyYW1ldGVyID09ICJJbnRlcmNlcHQiIH4gIiRcXGJldGFfMCQiLAogICAgUGFyYW1ldGVyID09ICJsblRpbWUiICB+ICJsblRpbWUiLAogICAgUGFyYW1ldGVyID09ICJsaWZlX3N0YWdlSnV2ZW5pbGUiICB+ICJMaWZlIHN0YWdlIC0gSnV2ZW5pbGUiLAogICAgUGFyYW1ldGVyID09ICJsbkRvc2UiICB+ICJsbkRvc2UiLAogICAgUGFyYW1ldGVyID09ICJpbnZfdGVtcCIgIH4gIkludmVyc2UgdGVtcGVyYXR1cmUiLAogICAgUGFyYW1ldGVyID09ICJsblRpbWU6bGlmZV9zdGFnZUp1dmVuaWxlIiAgfiAibG5UaW1lIDogTGlmZSBzdGFnZSIpKSAlPiUgCiAgdGliYmxlOjphZGRfcm93KFBhcmFtZXRlciA9ICIqKkZpeGVkIGVmZmVjdHMqKiIsIC5iZWZvcmUgPSAxKQoKIyBSYW5kb20gZWZmZWN0CnJlZiA8LSBzdW1tYXJ5KHRpbWVfYmRfbW9kZWwpJHJhbmRvbSAlPiUgCiAgYmluZF9yb3dzKCkgJT4lICMgdW5saXN0CiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4oIlBhcmFtZXRlciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KDE6NSkgJT4lIAogIGRwbHlyOjptdXRhdGUoUGFyYW1ldGVyID0gYygiJFxcc2lnbWFfe3NwZWNpZXM6c3R1ZHl9XjIkIikpICU+JSAgIAogIGRwbHlyOjpyZW5hbWUoUTIuNSAgPSA0LCAKICAgICAgICAgICAgICAgIFE5Ny41ID0gNSkgJT4lIAogIHRpYmJsZTo6YWRkX3JvdyhQYXJhbWV0ZXIgPSAiKipHcm91cC1sZXZlbCBlZmZlY3RzKioiLCAuYmVmb3JlID0gMSkKCiMgUmVuZGVyIHRhYmxlCmJpbmRfcm93cyhmZWYsIHJlZikgJT4lIAogIHJlbW92ZV9yb3duYW1lcygpICU+JSAKICBrbml0cjo6a2FibGUoZGlnaXRzID0gMikKYGBgCgoqKioKCiMgRmlndXJlcyBmb3IgbWFpbiB0ZXh0IHstfQoKRmlndXJlcyBwcm9kdWNlZCBoZXJlIHdlcmUgbW9kaWZpZWQgaW4gW0Fkb2JlIElsbHVzdHJhdG9yXShodHRwczovL3d3dy5hZG9iZS5jb20vYXUvcHJvZHVjdHMvaWxsdXN0cmF0b3IuaHRtbCkgZm9yIHB1YmxpY2F0aW9uLgoKIyMgRmlndXJlIDIgLSBUcmFpdCBtb2RlbCB7LX0KCmBgYHtyIEZpZyAyLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTQuNX0KIyBFeHRyYWN0IG1hcmdpbmFsIGVmZmVjdHMgZnJvbSBtb2RlbAptb2RlbF9tZSAgICAgIDwtIGJybXM6OmNvbmRpdGlvbmFsX2VmZmVjdHModHJhaXRfbW9kZWwsIGMoInRyYWl0IiwgImxpZmVfc3RhZ2UiKSkKdHJhaXRfbWUgICAgICA8LSBhcy5kYXRhLmZyYW1lKG1vZGVsX21lW1sxXV0pICU+JSBkcGx5cjo6cmVuYW1lKGVzdGltYXRlID0gZXN0aW1hdGVfXywgY2kubGIgPSBsb3dlcl9fLCBjaS51YiA9IHVwcGVyX18pCgojIFBsb3QgbW9kZWwgb3V0cHV0CnRyYWl0X21lICU+JSAKICBnZ3Bsb3QoYWVzKHggPSB0cmFpdCwgeSA9IGVzdGltYXRlKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGFscGhhID0gMC41KSArCiAgZ2dmb3JjZTo6Z2VvbV9zaW5hKGRhdGEgPSBlc19hbGxfZGF0LCBhZXMoeCA9IHRyYWl0LCB5ID0gWnIsIHNpemUgPSBacl9pbnYpLCBjb2xvdXIgPSAiI2NmY2ZjZiIpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSB0cmFpdCksIHNpemUgPSA0LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGNpLmxiLCB5bWF4ID0gY2kudWIsIGNvbG91ciA9IHRyYWl0KSwgc2l6ZSA9IDAuOCwgd2lkdGggPSAwLjEsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBjb2xvcnNwYWNlOjpzY2FsZV9jb2xvdXJfZGlzY3JldGVfc2VxdWVudGlhbChwYWxldHRlID0gIlJlZE9yIiwgbm1heCA9IDE0LCBvcmRlciA9IDQ6MTQpICsKICB4bGFiKE5VTEwpICsgeWxhYihleHByZXNzaW9uKCJFZmZlY3Qgc2l6ZSJ+KGl0YWxpYyhaKVtyXSkpKSArCiAgY29vcmRfZmxpcCgpICsKICBteXRoZW1lKCkgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgoqKkZpZy4gMi4qKiBFZmZlY3Qgb2YgKkJkKiBpbmZlY3Rpb24gb24gYWxsIGJpb2xvZ2ljYWwgKGNhcmRpb3Zhc2N1bGFyLCBpbW11bmUsIGhvcm1vbmUgbGV2ZWwsIGVuZXJneSBtZXRhYm9saXNtLCBvc21vcmVndWxhdGlvbiwgc2tpbiBpbnRlZ3JpdHkpIGFuZCBmdW5jdGlvbmFsIChiZWhhdmlvdXIsIGJvZHkgY29uZGl0aW9uLCBsb2NvbW90b3IgY2FwYWNpdHksIHJlcHJvZHVjdGlvbiwgdGhlcm1vcmVndWxhdGlvbikgdHJhaXRzIG1lYXN1cmVkLiBPbmx5IHRyYWl0cyB3aXRoIG1vcmUgdGhhbiBmaXZlIGVmZmVjdCBzaXplIHdlcmUgYW5hbHlzZWQuIE51bWJlcnMgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIHBsb3QgaW5kaWNhdGUgdGhlIG51bWJlciBvZiBlZmZlY3Qgc2l6ZXMgYW5hbHlzZWQuIEVmZmVjdCBzaXplcyAoWnIpIHByZXNlbnRlZCBhcyBlc3RpbWF0ZXMgwrEgOTUlIENJLiBHcmV5IHBvaW50cyByZXByZXNlbnQgaW5kaXZpZHVhbCBlZmZlY3Qgc2l6ZSwgYW5kIHRoZSBzaXplIG9mIGVhY2ggcG9pbnQgaW5kaWNhdGVzIHN0dWR5IHByZWNpc2lvbiAoaW52ZXJzZSBvZiBzdGFuZGFyZCBlcnJvcikuIAoKIyMgRmlndXJlIDMgLSBTZW5zaXRpdml0eSBtb2RlbCB7LX0KCmBgYHtyIEZpZyAzLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTQuNX0KIyBFeHRyYWN0IG1hcmdpbmFsIGVmZmVjdHMKc2Vuc2l0aXZlX21lIDwtIGJybXM6OmNvbmRpdGlvbmFsX2VmZmVjdHMoc2Vuc2l0aXZlX21vZGVsKQpzZW5zaXRpdmVfbWUgPC0gYXMuZGF0YS5mcmFtZShzZW5zaXRpdmVfbWVbWzFdXSkgJT4lIAogIGRwbHlyOjpyZW5hbWUoZXN0aW1hdGUgPSBlc3RpbWF0ZV9fLCBjaS5sYiA9IGxvd2VyX18sIGNpLnViID0gdXBwZXJfXykgJT4lCiAgZHBseXI6Om11dGF0ZShlc3RpbWF0ZSA9IGV4cChlc3RpbWF0ZSksCiAgICAgICAgICAgICAgICBjaS5sYiAgICA9IGV4cChjaS5sYiksCiAgICAgICAgICAgICAgICBjaS51YiAgICA9IGV4cChjaS51YikpCgpzZW5zaXRpdmVfcG9zdCA8LSBicm1zOjpwb3N0ZXJpb3Jfc2FtcGxlcyhzZW5zaXRpdmVfbW9kZWwpICU+JQogIGRwbHlyOjpzYW1wbGVfbig0MDAwKSAlPiUKICBkcGx5cjo6c2VsZWN0KGJfdHJhaXRCZWhhdmlvdXI6Yl90cmFpdFNraW5pbnRlZ3JpdHkpICU+JQogIHJlc2hhcGUyOjptZWx0KHZhbHVlLm5hbWUgPSAic2FtcGxlIikKICAKc2Vuc2l0aXZlX3Bvc3QkdmFyaWFibGUgPC0gc3Vic3RyaW5nKHNlbnNpdGl2ZV9wb3N0JHZhcmlhYmxlLCA4KQpzb3VyY2UoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9kYXRhdml6cHlyL2RhdGEvbWFzdGVyL2hhbGZfZmxhdF92aW9saW5wbG90LlIiKQoKc2Vuc2l0aXZlX3Bvc3QgJT4lCiAgZHBseXI6Omdyb3VwX2J5KHZhcmlhYmxlKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKG1lYW4gPSBtZWFuKHNhbXBsZSkpICU+JQogIGRwbHlyOjptdXRhdGUodmFyaWFibGUgPSBmb3JjYXRzOjpmY3RfcmVvcmRlcih2YXJpYWJsZSwgbWVhbikpICU+JQogIGdncGxvdCgpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gdmFyaWFibGUsIHkgPSBtZWFuKSwgc2l6ZSA9IDIpICsKICBnZW9tX2ZsYXRfdmlvbGluKGRhdGEgPSBzZW5zaXRpdmVfcG9zdCwgYWVzKHggPSB2YXJpYWJsZSwgeSA9IHNhbXBsZSwgZmlsbCA9IHZhcmlhYmxlKSwgY29sb3VyID0gTkEsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gdmFyaWFibGUsIHkgPSBtZWFuKSwgc2l6ZSA9IDMpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gdmFyaWFibGUsIHkgPSBtZWFuLCBjb2xvdXIgPSB2YXJpYWJsZSksIHNpemUgPSAyLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgY29sb3JzcGFjZTo6c2NhbGVfZmlsbF9kaXNjcmV0ZV9zZXF1ZW50aWFsKHBhbGV0dGUgPSAiUmVkT3IiLCBubWF4ID0gMTIsIG9yZGVyID0gNDoxMikgKwogIGNvbG9yc3BhY2U6OnNjYWxlX2NvbG91cl9kaXNjcmV0ZV9zZXF1ZW50aWFsKHBhbGV0dGUgPSAiUmVkT3IiLCBubWF4ID0gMTIsIG9yZGVyID0gNDoxMikgKwogIHhsYWIoTlVMTCkgKwogIHlsYWIoIkluZmVjdGlvbiBpbnRlbnNpdHkgKGxvZyBaRSArIDEpIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgbXl0aGVtZSgpCmBgYAoKKipGaWcuIDMuKiogUG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBkZW5zaXR5ICg0LDAwMCBzdWJzZXQgaXRlcmF0aW9ucykgb2YgdGhlIG1pbmltdW0gKkJkKiBsb2FkIChsbiBaRSArMSkgdG8gY2hhbmdlIHRyYWl0IHJlc3BvbnNlIGFib3ZlIG9yIGJlbG93IHRoZSBub3JtYWwgcmVzcG9uc2UgcmFuZ2UgKDV0aCBvciA5NXRoIHF1YW50aWxlKS4gRW5jbG9zZWQgY2lyY2xlcyByZXByZXNlbnQgdGhlIG1lYW4gZXN0aW1hdGUgcmVzcG9uc2UuIAoKIyMgRmlndXJlIDQgLSBTdXJ2aXZhbCBtb2RlbCB7LX0KCmBgYHtyIEZpZyA0LCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTd9CiMgUGxvdApzdXJ2X3Bsb3QgPC0gc3Vydl9tYXJnX2VmZiAlPiUKICBnZ3Bsb3QoYWVzKHggPSB4LCB5ID0gcHJlZGljdGVkLCBjb2xvdXIgPSBsaWZlX3N0YWdlKSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZygxZTQpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBhbHBoYSA9IDAuNSkgKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBncm91cCwgbGluZXR5cGUgPSBsaWZlX3N0YWdlKSwgc2l6ZSA9IDAuNSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1cnZfZGF0LCBhZXMoeCA9IGxuQmQsIHkgPSBhbGl2ZSwgY29sb3VyID0gbGlmZV9zdGFnZSksIHNpemUgPSAxLjUsIGFscGhhID0gMC41KSArCiAgY29sb3JzcGFjZTo6c2NhbGVfY29sb3VyX2Rpc2NyZXRlX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJCbHVlcyAzIiwgbm1heCA9IDUsIG9yZGVyID0gYygzLDUpKSArCiAgeWxhYigiU3Vydml2YWwgcHJvYmFiaWx0eSIpICsKICB4bGFiKCJJbmZlY3Rpb24gaW50ZW5zaXR5IChsbiBaRSArIDEpIikgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgZmFjZXRfZ3JpZChyb3dzID0gdmFycyhsaWZlX3N0YWdlKSkKCmluZmxpY3RfcGxvdCA8LSBkYXRhLmZyYW1lKHN1cnZfbWFyZ19lZmYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGdyb3VwLCBsaWZlX3N0YWdlKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKHByZWRpY3RlZCA8IDAuNTIgJiBwcmVkaWN0ZWQgPiAwLjQ4KSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c3VtbWFyaXNlKHRocmVzaG9sZCA9IG1lYW4oeCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShiZCA9IGV4cCh0aHJlc2hvbGQpKSkgJT4lCiAgZHBseXI6Om11dGF0ZShncm91cCA9IGZvcmNhdHM6OmZjdF9yZW9yZGVyKGdyb3VwLCAtdGhyZXNob2xkKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZ3JvdXAsIHkgPSB0aHJlc2hvbGQsIGNvbG91ciA9IGxpZmVfc3RhZ2UpKSArCiAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSBsaWZlX3N0YWdlKSwgc2l6ZSA9IDIpICsKICBjb2xvcnNwYWNlOjpzY2FsZV9jb2xvdXJfZGlzY3JldGVfc2VxdWVudGlhbChwYWxldHRlID0gIkJsdWVzIDMiLCBubWF4ID0gNSwgb3JkZXIgPSBjKDMsNSkpICsKICB5bGFiKGV4cHJlc3Npb24oYXRvcChpdGFsaWMoIkJkIil+ImxvYWQgKGxuIFpFICsgMSkiLCAid2l0aCA1MCUgbW9ydGFsaXR5IHByb2JhYmlsdHkiKSkpICsKICB4bGFiKE5VTEwpICsKICBzY2FsZV94X2Rpc2NyZXRlKHBvc2l0aW9uID0gInRvcCIpICsKICBjb29yZF9mbGlwKCkgKwogIG15dGhlbWUoKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuOCkpKQoKY293cGxvdDo6cGxvdF9ncmlkKHN1cnZfcGxvdCwgaW5mbGljdF9wbG90LCAKICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoJ2EnLCAnYicpLCAKICAgICAgICAgICAgICAgICAgIG5jb2wgPSAyLCAKICAgICAgICAgICAgICAgICAgIGFsaWduID0gImgiLCAKICAgICAgICAgICAgICAgICAgIGF4aXMgPSAidGIiLAogICAgICAgICAgICAgICAgICAgcmVsX3dpZHRocyA9IGMoMC45LCAxKSkKYGBgCgoqKkZpZy4gNC4qKiBSZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmZlY3Rpb24gaW50ZW5zaXR5IChsbiBaRSArIDEpIGFuZCB0aGUgcHJvYmFiaWxpdHkgb2Ygc3Vydml2YWwgb2YgMjcgc3BlY2llcy4gKiooYSkqKiBTcGVjaWVzLXNwZWNpZmljIHN1cnZpdmFsIHByb2JhYmlsaXR5IHdlcmUgZ3JvdXBlZCBlaXRoZXIgYXMgYWR1bHQgb3IganV2ZW5pbGVzLiBTb2xpZCBsaW5lcyByZXByZXNlbnQgYWR1bHQgZnJvZ3MgYW5kIGRhc2hlZCBsaW5lcyByZXByZXNlbnQganV2ZW5pbGUgZnJvZ3MuIERhc2hlZCB2ZXJ0aWNhbCBsaW5lIHJlcHJlc2VudHMgdGhlIFZyZWRlbmJ1cmfigJlzIOKAnDEwLDAwMCB6b29zcG9yZSBydWxl4oCdIChLaW5uZXkgZXQgYWwuLCAyMDExKS4gKiooYikqKiBUaGUgcHJlZGljdGVkIGluZmxlY3Rpb24gcG9pbnRzIGZvciBwcm9iYWJpbGl0eSBvZiBpbmZlY3Rpb24gdGhhdCBjYXVzZXMgNTAlIG1vcnRhbGl0eS4gQ2lyY2xlcyByZXByZXNlbnQgYWR1bHRzIGFuZCB0cmlhbmdsZXMgcmVwcmVzZW50IGp1dmVuaWxlcy4KCiMjIEZpZ3VyZSA1IC0gKkJkKi10aW1lIGRlcGVuZGVudCBtb3J0YWxpdHkgbW9kZWwgey19CgpgYGB7ciBGaWcgNSwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTMsIGZpZy53aWR0aD03fQojIEV4dHJhY3QgbWFyZ2luYWwgZWZmZWN0cwp0aW1lX21hcmdfZWZmIDwtIGFzLmRhdGEuZnJhbWUoZ2dlZmZlY3RzOjpnZ3ByZWRpY3QodGltZV9iZF9tb2RlbCwgdGVybXMgPSBjKCJsblRpbWVbc2FtcGxlID0gNTBdIiwgImxpZmVfc3RhZ2UiKSkpCgojIENyZWF0ZSBtYXRyaXggb2YgbWluIGFuZCBtYXggdmFsdWVzIHBlciBncm91cAp0aW1lX3JhbmdlIDwtIHN1cnZfZGF0ICU+JQogIGRwbHlyOjpmaWx0ZXIoYWxpdmUgPT0gMCkgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGxpZmVfc3RhZ2UpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UobWluID0gbWluKGxuVGltZVshaXMubmEobG5UaW1lKV0pLAogICAgICAgICAgICAgICAgICAgbWF4ID0gbWF4KGxuVGltZVshaXMubmEobG5UaW1lKV0pKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkKCiMgQWRkIG1pbiBhbmQgbWF4IHZhbHVlcyB0byBtb2RlbCBkZiBhbmQga2VlcCBwcmVkaWN0aW9ucyB3aXRoaW4gZGF0YSByYW5nZQp0aW1lX21hcmdfZWZmJG1pbiA8LSB0aW1lX3JhbmdlJG1pblttYXRjaCh0aW1lX21hcmdfZWZmJGdyb3VwLCB0aW1lX3JhbmdlJGxpZmVfc3RhZ2UpXQp0aW1lX21hcmdfZWZmJG1heCA8LSB0aW1lX3JhbmdlJG1heFttYXRjaCh0aW1lX21hcmdfZWZmJGdyb3VwLCB0aW1lX3JhbmdlJGxpZmVfc3RhZ2UpXQp0aW1lX21hcmdfZWZmICAgICA8LSB0aW1lX21hcmdfZWZmICU+JSAKICBkcGx5cjo6Z3JvdXBfYnkoZ3JvdXApICU+JQogIGRwbHlyOjpmaWx0ZXIoeCA+PSBtaW4gJiB4IDwgbWF4KSAlPiUKICBkcGx5cjo6bXV0YXRlKGxpZmVfc3RhZ2UgPSBncm91cCwKICAgICAgICAgICAgICAgIGRheXMgICAgICAgPSBleHAoeCksCiAgICAgICAgICAgICAgICBCZCAgICAgICAgID0gZXhwKHByZWRpY3RlZCkpCgojIFBsb3QgCnRpbWVfYmRfcGxvdCA8LSBnZ3Bsb3QoZGF0YSA9IHRpbWVfbWFyZ19lZmYsIGFlcyh4ID0geCwgeSA9IHByZWRpY3RlZCwgZ3JvdXAgPSBsaWZlX3N0YWdlKSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1cnZfZGF0ICU+JSBkcGx5cjo6ZmlsdGVyKGFsaXZlID09IDApLCBhZXMoeCA9IGxuVGltZSwgeSA9IGxuQmQsIGNvbG91ciA9IGxpZmVfc3RhZ2UsIHNoYXBlID0gbGlmZV9zdGFnZSksIHNpemUgPSAyLCBhbHBoYSA9IDAuNCkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0geCwgeW1pbiA9IGNvbmYubG93LCB5bWF4ID0gY29uZi5oaWdoLCBmaWxsID0gbGlmZV9zdGFnZSksIGFscGhhID0gMC4xLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvdXIgPSBsaWZlX3N0YWdlLCBsaW5ldHlwZSA9IGxpZmVfc3RhZ2UpLCBzaXplID0gMSkgKwogIGNvbG9yc3BhY2U6OnNjYWxlX2NvbG91cl9kaXNjcmV0ZV9zZXF1ZW50aWFsKHBhbGV0dGUgPSAiQmx1ZXMgMyIsIG5tYXggPSA1LCBvcmRlciA9IGMoMyw1KSkgKwogIGNvbG9yc3BhY2U6OnNjYWxlX2ZpbGxfZGlzY3JldGVfc2VxdWVudGlhbChwYWxldHRlID0gIkJsdWVzIDMiLCBubWF4ID0gNSwgb3JkZXIgPSBjKDMsNSkpICsKICB5bGFiKCJJbmZlY3Rpb24gaW50ZW5zaXR5IChsbiBaRSArIDEpIikgKwogIHhsYWIoIlRpbWUgcG9zdCBleHBvc3VyZSAobG4gZGF5cykiKSArCiAgbXl0aGVtZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikKCnRpbWVfcGxvdCA8LSBzdXJ2X2RhdCAlPiUgZHBseXI6OmZpbHRlcihhbGl2ZSA9PSAwKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbGlmZV9zdGFnZSwgeSA9IGxuVGltZSkpICsKICBnZW9tX2ZsYXRfdmlvbGluKGFlcyhmaWxsID0gbGlmZV9zdGFnZSksIGNvbG91ciA9IE5BLCBhbHBoYSA9IDAuNSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gbGlmZV9zdGFnZSwgY29sb3VyID0gbGlmZV9zdGFnZSksIHNpemUgPSAxLjUpICsKICBjb2xvcnNwYWNlOjpzY2FsZV9jb2xvdXJfZGlzY3JldGVfc2VxdWVudGlhbChwYWxldHRlID0gIkJsdWVzIDMiLCBubWF4ID0gNSwgb3JkZXIgPSBjKDMsNSkpICsKICBjb2xvcnNwYWNlOjpzY2FsZV9maWxsX2Rpc2NyZXRlX3NlcXVlbnRpYWwocGFsZXR0ZSA9ICJCbHVlcyAzIiwgbm1heCA9IDUsIG9yZGVyID0gYygzLDUpKSArCiAgeWxhYigiVGltZSBwb3N0IGV4cG9zdXJlIChsbiBkYXlzKSIpICsgeGxhYihOVUxMKSArCiAgbXl0aGVtZSgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikKCmNvd3Bsb3Q6OnBsb3RfZ3JpZCh0aW1lX2JkX3Bsb3QsIHRpbWVfcGxvdCwgCiAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCdhJywgJ2InKSwgCiAgICAgICAgICAgICAgICAgICBuY29sID0gMiwgCiAgICAgICAgICAgICAgICAgICBhbGlnbiA9ICJoIiwgCiAgICAgICAgICAgICAgICAgICBheGlzID0gImJ0IiwKICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHMgPSBjKDEsIDAuNSkpCmBgYAoKKipGaWcuIDUuIChhKSoqIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRheXMgcG9zdCBleHBvc3VyZSB0byAqQmQqIChsbiBkYXlzKSBhbmQgdGhlIGluZmVjdGlvbiBpbnRlbnNpdHkgKGxuIFpFICsgMSkgYXQgZGVhdGguIFJlZ3Jlc3Npb24gbGluZXMgKHNvbGlkID0gYWR1bHRzLCBkYXNoZWQgPSBqdXZlbmlsZXMpIHJlcHJlc2VudCBtb2RlbCBlc3RpbWF0ZXMgYW5kIHNoYWRlZCBhcmVhIHJlcHJlc2VudHMgOTUlIENJLiAqKihiKSoqIERpZmZlcmVuY2UgaW4gdGltZSB0byBkZWF0aCBwb3N0LWV4cG9zdXJlIGJldHdlZW4ganV2ZW5pbGUgYW5kIGFkdWx0cy4KCiMgU3VwcGxtZW50YXJ5IGZpZ3VyZXMgey19CgojIyBGaWcgUzggLSAqQmQqLXRpbWUgZGVwZW5kZW50IG1vcnRhbGl0eSBtb2RlbCB7LX0KCmBgYHtyIEZpZyBTOCwgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcuaGVpZ2h0PTksIGZpZy53aWR0aD04fQplc19hbGxfZGF0ICU+JQogIGdncGxvdChhZXMoeCA9IHJlc3BvbnNlLCB5ID0gWnIsIGNvbG91ciA9IHRyYWl0KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGFscGhhID0gMC41KSArCiAgZ2VvbV9wb2ludChhZXMoc2hhcGUgPSBsaWZlX3N0YWdlKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIHZpcmlkaXM6OnNjYWxlX2NvbG91cl92aXJpZGlzKGRpc2NyZXRlID0gVFJVRSkgKwogIHhsYWIoTlVMTCkgKyB5bGFiKGV4cHJlc3Npb24oIkVmZmVjdCBzaXplIn4oaXRhbGljKFopW3JdKSkpICsKICBjb29yZF9mbGlwKCkgKwogIGZhY2V0X3dyYXAofiB0cmFpdCwgbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgbXl0aGVtZSgpICsgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA1KSwKICAgICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgoqKkZpZy4gUzguKiogRWZmZWN0IG9mICpCZCogaW5mZWN0aW9uIG9uIHNwZWNpZmljIHJlc3BvbnNlcyBhY3Jvc3MgZGlmZmVyZW50IGJpb2xvZ2ljYWwgYW5kIGZ1bmN0aW9uYWwgdHJhaXRzLiBEYXRhIHByZXNlbnRlZCBhcyBpbmRpdmlkdWFsIGVmZmVjdCBzaXplcyAoJFpfciQpLiBDaXJjbGVzIHJlcHJlc2VudCBhZHVsdHMgYW5kIHRyaWFuZ2xlcyByZXByZXNlbnQganV2ZW5pbGVzLiAKCioqKgoKIyBSZWZlcmVuY2VzIHstfQoKPGRpdiBpZD0icmVmcyI+PC9kaXY+Cjxicj4KCioqKgoKIyMgU2Vzc2lvbiBJbmZvcm1hdGlvbiB7LX0KCmBgYHtyIHNlc3Npb25pbmZvLCBlY2hvID0gRkFMU0V9CnBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCksIGxvY2FsZSA9IEZBTFNFKQpgYGA=