# load in CardiffCOGS dataset
pheno <- read_sav("Complete CardiffCogs 2022.sav")

# load in samples with genetic information
geno <-  read.delim("genetic.ids", header = F)

# filter to those with phenotype and genotype information
pheno <- pheno[pheno$Study_ID %in% geno$V1, ] # 

# inclusion criteria
pheno <- pheno %>%
  # filter to people with schizophrenia or schizoaffective disorder depressed type.
  filter(SZ_SZAFFDEP_diag == 1) %>%
  # remove individuals with inappropriate ratings (above 3 on Calgary, above 5 on SAPs/SANS) or NA values in phenotype measures. 
  subset(Calgary_Depression <4) %>%   
  subset(Calgary_Suicide <4) %>%   
  subset(SAPS_Global_Hals <6) %>%
  subset(SAPS_Global_Delusions <6) %>%
  subset(SANS_Global_Alogia <6) %>%
  subset(SANS_Global_Anhedonia_Asociality <6) %>%
  subset(SANS_Global_Affective_Flattening <6) %>%
  subset(SANS_Global_Avolition_Apathy <6) %>%
  subset(!is.na(ZNAB_Mazes_Imp)) %>%
  subset(!is.na(ZHVLT_Imp)) %>%
  subset(!is.na(ZBVMT_Imp)) %>%
  subset(!is.na(ZCPT_Imp)) %>%
  subset(!is.na(ZSoP_Imp)) %>%
  subset(!is.na(ZWM_Imp)) %>%
  # remove individuals with missing medication information.
  subset(AP_dose != 9999) %>% # dose unknown
  subset(AP_dose != 7777) %>% # pro re nata
  subset(Antipsychotic != 89) %>% # antipsychotic name unknown
  subset(!is.na(Adherence))

# exclude IDs in CardiffCOGS that are also present in CLOZUK2/3 or with missing dose information in 2nd or 3rd antipsychotics
remove_1 <- read.delim("prs/CLOZUK23_CardiffCOGS_overlaps.txt", header = F)
remove_2 <- read.delim("missing_dose.ids", header = F)
remove <- rbind(remove_1, remove_2)
remove_ids <- unique(remove$V1)
pheno <- pheno[!pheno$Study_ID %in% remove_ids, ]

rm(remove_1, remove_2, remove, remove_ids)

# extract IDs for calculating genetic PCs
# ids <- pheno[1]
# ids$Study_ID2 <- ids$Study_ID
# write_tsv(x = ids, file = "COGS_SZ_SZAFF.ids", col_names = F) 
# load schizophrenia PGS 
setwd(dir = "D:/siobh/Documents/Uni/PhD/Y1/Symptoms Project/symptoms-cogs/prs/edu/")

# find all .profile files
list_file <- list.files(pattern = "*.profile") %>% 
 gtools::mixedsort()

# sum across chromosomes
prs_cs_ea <- analyze(list_file)
colnames(prs_cs_ea) <- c("Study_ID", "EA_PRScs")
# standardise all variables 
test_df_dim_std <- datawizard::standardise(x = test_df_dim)

# do this for clozapine using sample (filter by current clozapine status)
test_df_dim_std_c <- datawizard::standardise(x = filter(test_df_dim, clozapine_current==1))

Medication and pharmacogenomic effects on cross-sectional symptom severity and cognitive ability in schizophrenia


Siobhan K. Lock, Djenifer B. Kappel, Michael J. Owen, James T.R. Walters, Michael C. O’Donovan, Antonio .F. Pardiñas, and Sophie E. Legge.


Background: People with schizophrenia differ in the type and severity of symptoms experienced, as well as their response to medication. A better understanding of the factors that influence this heterogeneity is necessary for the development of individualised patient care. Here, we sought to investigate the relationships between phenotypic severity and both medication and pharmacogenomic variables in a cross-sectional sample of people with schizophrenia or schizoaffective disorder depressed type.

Methods: Confirmatory factor analysis derived five dimensions relating to current symptoms (positive symptoms, negative symptoms of diminished expressivity, negative symptoms of reduced motivation and pleasure, depression and suicide) and cognitive ability in participants prescribed with antipsychotic medication. Linear models were fit to test for associations between medication and pharmacogenomic variables with dimension scores in the full sample (N = 585), and in a sub-sample of participants prescribed clozapine (N = 215).

Outcomes: Lower cognitive ability was associated with higher chlorpromazine-equivalent daily antipsychotic dose and with the prescription of clozapine and anticholinergic medication. We also found associations between pharmacogenomics-inferred cytochrome P450 (CYP) enzyme activity and symptom dimensions. Increased genotype-predicted CYP2C19 and CYP3A5 activity were associated with reduced severity of positive and negative symptoms, respectively. Faster predicted CYP1A2 activity was associated with higher cognitive dimension scores in people taking clozapine.

Interpretation: Our results confirm the importance of taking account of medication history (and particularly antipsychotic type and dose) in assessing potential causes of cognitive impairment or poor functioning in patients with schizophrenia. We also highlight the potential for pharmacogenomic variation to be a useful tool to help guide drug prescription, although these findings require further validation.

Funding: This project was supported by a Medical Research Council Programme Grant (MR/Y004094/1) and The National Centre for Mental Health, funded by the Welsh Government through Health and Care Research Wales. SKL was funded by a PhD studentship from Mental Health Research UK (MHRUK). DBK, JTRW, MCOD and AFP were supported by the European Union’s Horizon 2020 research and innovation programme under grant agreement 964874.

Acknowledgements: We thank the participants, clinicians, field team, and Medical Research Council Centre for Neuropsychiatric Genetics and Genomics core laboratory staff for their help with the CardiffCOGS study. We thank the staff at the Broad Institute of Harvard and MIT, and deCODE Genetics for sample genotyping. We thank the Psychosis team at Cardiff University’s Centre for Neuropsychiatric Genetics and Genomics, particularly Isabella Willcocks and Sophie Smart for their help and guidance over the course of this project. We acknowledge the support of the Supercomputing Wales project, which is part-funded by the European Regional Development Fund (ERDF) via Welsh Government.




Introduction

Introduction

Schizophrenia is characterised by positive, negative, and disorganised symptoms alongside affective features and cognitive deficits. The presentation of schizophrenia is heterogeneous in the range and severity of symptoms and in the degree to which those respond to antipsychotic treatment. Heterogeneity in treatment response has been associated with pre-morbid functioning, initial symptom severity, age of onset, duration of untreated psychosis, as well as comorbid psychiatric and substance abuse disorders1. Genetic factors may also play a role, with one study suggesting that higher common variant liability to schizophrenia, as indexed by polygenic scores (PGS), is associated with poorer response to antipsychotics after 12 weeks of treatment2. Similarly, both longitudinal and cross-sectional research has demonstrated an association between higher schizophrenia PGS and greater severity of negative and cognitive symptom dimensions3–5.

Beyond polygenic risk, variation in genes encoding proteins key to pharmacokinetic or pharmacodynamic processes (“pharmacogenes”) may also influence response to antipsychotic medication6. Pharmacogenomic star alleles describe single or multiple genetic markers that alter the function of proteins influencing drug response. The most widely researched pharmacogenes are within the cytochrome P450 (CYP) family, which are implicated in drug metabolism and are highly variable within and across populations. While drug metabolism pathways are often well-studied biochemically, the extent to which between-person variability in these pathways influences drug effectiveness is still unclear. Figure 1 illustrates how a pharmacogenomic alteration in a key metabolic enzyme might affect response to a medication. While such effects are intuitive and form the basis of successful prospective trials7, as of June 2024, only 10 antipsychotics have regulator-approved guidelines with actionable pharmacogenomic markers in the PharmGKB database8. Reviews from expert consortia report a similar number of drugs where pharmacogenomic information might be of use in clinical settings9, though they also highlight the paucity of studies in the area.

knitr::include_graphics("Writing/figs/fin1st.png")
Figure 1. The majority of CYP-mediated drug metabolism occurs hepatically. Pharmacogenomic variation can result in increased, decreased, or no change to enzyme activity. Increased enzyme activity leads to faster metabolism, resulting in a lower drug concentration. This can be expected to lead to its reduced effectiveness but also a reduced risk for toxicity and adverse drug reactions. Conversely, variation leading to reduced enzyme activity results in slower metabolism of enzyme substrates. This can result in higher drug concentrations that might result in increased effectiveness but also increased risk of toxicity. The exact consequences of pharmacogenomic variation depend on the enzyme, drug, and metabolite(s) in question; for example, effects might vary if the metabolite has the potential to cause side effects or if the administered drug is a prodrug.

Figure 1. The majority of CYP-mediated drug metabolism occurs hepatically. Pharmacogenomic variation can result in increased, decreased, or no change to enzyme activity. Increased enzyme activity leads to faster metabolism, resulting in a lower drug concentration. This can be expected to lead to its reduced effectiveness but also a reduced risk for toxicity and adverse drug reactions. Conversely, variation leading to reduced enzyme activity results in slower metabolism of enzyme substrates. This can result in higher drug concentrations that might result in increased effectiveness but also increased risk of toxicity. The exact consequences of pharmacogenomic variation depend on the enzyme, drug, and metabolite(s) in question; for example, effects might vary if the metabolite has the potential to cause side effects or if the administered drug is a prodrug.


Establishing a pharmacogenomic marker as “actionable” requires an evaluation of its effects on phenotypes beyond drug metabolism and pharmacokinetics, and studies on clinical outcomes can be valuable in these decisions9. There is preliminary evidence that leveraging pharmacogenomic star alleles to infer enzyme activity may help predict schizophrenia symptom severity in those taking clozapine, the only evidence-based medication for treatment-resistant schizophrenia (TRS). Clozapine has a complex metabolic pathway but most of its first-pass bioconversion is driven by CYP1A2, with minor contributions of CYP2C19 and CYP2D610. Two recent studies reported associations between schizophrenia symptom severity and genotype-predicted enzyme activity for CYP1A211 and CYP2C1912 in people with TRS taking this medication. However, the effects reported were inconsistent between studies, and their interpretation is complicated by differences in the statistical methodology and symptom rating scales used.

The present study aims to investigate possible links between medication and pharmacogenomic variables with current schizophrenia symptom severity and cognitive ability in a UK-based sample of individuals treated with antipsychotic medication. Although cross-sectional, the inclusion of pharmacogenomic information alongside medication variables offers the potential to inform the causal direction of associations. We also reproduced previous pharmacogenomic analyses11,12 in a subsample restricted to patients prescribed clozapine. Our work follows recent calls to overcome “one size fits all” approaches in psychopharmacology by directly searching for predictors of clinical outcomes and pharmacodynamics13,14, as these are essential to advancing the field of precision psychiatry through effective patient stratification.





Methods

Methods

Participants

We included 585 individuals from the Cardiff COGnition in Schizophrenia (CardiffCOGS) cohort (Supplementary Figure 1). CardiffCOGS received approval from the South-East Wales Research Ethics Committee (07/WSE03/110) and all participants provided written informed consent. Participants were recruited from inpatient and community adult mental health services and voluntary services across the UK. Patients were also recruited from clozapine clinics; therefore, the cohort was enriched for those with treatment resistance (TRS; N = 37%). All participants completed a clinical research interview based on the Schedules for Clinical Assessment in Neuropsychiatry15 (SCAN) and provided a blood sample for genetic analyses. All participants met DSM-IV16 or ICD-1017 diagnoses for schizophrenia or schizoaffective disorder, depressed type based on the SCAN-based interview and clinical case note review. A full description of the cohort with additional details is provided elsewhere4.


Phenotype Data

The severity of positive, negative, affective, and disorganised symptoms were assessed at the time of the interview and are referred to hereafter as “current” symptoms. Symptoms were rated using the Scale for the Assessment of Positive Symptoms18 (SAPS), the Scale for the Assessment of Negative Symptoms19 (SANS), and the Calgary Depression Scale for Schizophrenia20. Cognitive ability was assessed using the MATRICS Consensus Cognitive Battery21 (MCCB). Missing values for MATRICS variables were imputed in accordance with guidance from the MCCB handbook before being standardised against unaffected controls.

All participants were treated with antipsychotics at the time of the interview. Medication data were obtained via self-report and case note review. A binary medication adherence variable was created from an ordinal questionnaire response that was based on the Medication Adherence Rating Scale22 (see Supplementary Materials). Antipsychotic doses were converted to chlorpromazine equivalents using the ChlorpromazineR package23. Doses were converted based on international consensus values where available, and World Health Organisation Daily Defined Dose variables otherwise24,25. Where individuals reported taking multiple antipsychotics concurrently, each antipsychotic dose was converted and then summed to give the total chlorpromazine-equivalent dose. Participants (N = 88) were excluded when (i) no adherence information was available or when, for any antipsychotic reported: (ii) the drug name was not documented or (iii) no dose information was reported.

A binary index for the presence/absence of current anticholinergic drug use was created based on the current prescription of Procyclidine, Hyoscine, Benztropine, Benzhexol, or Pirenzepine. The Global Assessment Scale26 was used as a measure of current functioning.


Genetic Data

Participants were genotyped with the Illumina HumanOmniExpressExome v8 or the Illumina HumanOmniExpress v12 (Illumina Inc, USA) at the Broad Institute of Harvard and MIT, MA, USA and deCODE Genetics, Reykjavík, Iceland. This procedure and the curation and harmonisation of data from different arrays have been described previously27. Combined genetic data for all samples were processed using the DRAGON-data quality-control pipeline “GenotypeQCtoHRC”28 with default parameters and imputed on the Michigan Imputation Server (see Supplementary Materials).

Pharmacogenomic markers for enzymes known to metabolise antipsychotic drugs (CYP1A2, CYP2C9, CYP2C19, CYP2D6, and CYP3A5) were called using the run-chip-pipeline command in PyPGx v0.20.029 in Python v3.9.230. Activity scores were derived from pharmacogenomic alleles as described in the Supplementary Materials and Supplementary Table 1.

PGS for schizophrenia31, intelligence32, and educational attainment33 were calculated using PRS-CS34 and PLINK v1.935. SNP effect sizes (BETA/Odds Ratio) were used alongside standard errors to compute posterior effect sizes in PRS-CS. The 1000 Genomes Project phase 3 European Linkage Disequilibrium (LD) reference panel was used to account for linkage disequilibrium36. Additional parameters in PRS-CS included 10,000 burn-in iterations, 25,000 Markov chain Monte Carlo iterations, and a global shrinkage parameter phi of 1 for schizophrenia or “auto” for intelligence and education attainment. Effect sizes generated in PRS-CS were passed to PLINK v1.9 for scoring. PGS were based on custom GWAS datasets from which all participants of the current study had been excluded.

To account for population stratification, a subset of common SNPs with high imputation quality (MAF > 0.05, INFO > 0.9), and low levels of LD (r2 < 0.2) was selected to calculate principal components using the principal component analysis function in PLINK v235.


Statistical Analysis

Data were analysed using R v4.4.0 in R Studio 2024.04.0 Build 73537. Confirmatory Factor Analysis (CFA) was used to derive a latent factor model for current symptom severity in schizophrenia based on other latent models4,5,38,39. Variables contributing to the model were global symptom measures from the SAPS and SANS, the self-report depressed mood and suicidal ideation and acts items from the Calgary Depression Scale for Schizophrenia, and the domain scores (excluding social cognition) from MATRICS. Ratings from SAPS, SANS, and Calgary Depression Scale for Schizophrenia were ordinal (0 – 5, SAPS and SANS; 0 – 3, Calgary Depression Scale for Schizophrenia). MATRICS variables were continuous. lavaan was used to fit the CFA, using default settings40. Dimension scores based on the best fit CFA model were calculated for each participant. Model fit was guided by the Comparative Fit Index, Root Mean Square Error of Approximation, and the Standardised Root Mean Squared Residual. We would expect that current phenotype severity, indexed by latent variable scores, would be associated with functional impairments. Therefore, as an in-sample validity check of our derived variables, we regressed each factor against the Global Assessment Scale.

Linear regression models were used to test for associations between medication variables and symptom dimensions. Medication variables included daily chlorpromazine-equivalent antipsychotic dose, clozapine use, and anticholinergic use. All continuous variables were standardised, and all models controlled for schizophrenia PGS, medication adherence, age, sex, and the first 5 genetic principal components. Finally, intelligence and educational attainment PGS were used as an estimate for premorbid intelligence in the analyses investigating the cognitive ability dimension. We chose these PGS as together they are the strongest genetic predictor of intelligence in previous research41,42, and neither variable was associated with chlorpromazine-equivalent antipsychotic dose in our total sample. In contrast, premorbid intelligence estimated from the National Adult Reading Test (NART)43 was associated with dose indicating the possibility that antipsychotic dose influenced performance on the NART or vice versa. Nevertheless, an alternative analysis using premorbid intelligence as estimated by the NART is provided in the Supplementary Materials.

The model was extended by including activity scores for CYP1A2, CYP2C9, CYP2C19, CYP2D6, and CYP3A5 to test their potential to mediate or moderate any associations in the total sample, and in the subgroup of participants prescribed clozapine (N = 215) separately. Note that analyses of the effects of the pharmacogenomic variables are adjusted for dose, clozapine use, and anticholinergic use. Finally, we performed a sensitivity analysis to test whether our pharmacogenomic models changed after controlling for concomitant medication or lifestyle factors that may influence enzyme function (“phenoconversion”44) as described in the Supplementary Materials.

This study followed the STrengthening the REporting of Genetic Association Studies reporting recommendations45 (STREGA), an extension of the STROBE Statement46. The checklist can be found here.





Results

Results

#get descriptive statistics for in-text
df_total <- test_df_dim %>%
   filter(if_all(c(Study_ID, positive, express, mandp, sad, cog, cpz_eq, Adherence_coded, clozapine_current, antichol_present, SZ_PRScs, Age_at_Interview, Sex, PC1, PC2, PC3, PC4, PC5), complete.cases))

meds <- dplyr::select(pheno, c("Study_ID", "Antipsychotic", "AP_dose", "antidepressant", "AD_dose", "Mood_Stabiliser", "MS_dose", "Benzodiazepine", "Ben_dose", "Anticholinergic", "Anticholinergic_dose" , "other_medication", "Other_medication_dose", "Current_smoking"))

meds$Antipsychotic[!(meds$Antipsychotic %in% AP_codes)] <- NA
meds$antidepressant[!(meds$antidepressant %in% AP_codes)] <- NA
meds$Mood_Stabiliser[!(meds$Mood_Stabiliser%in% AP_codes)] <- NA
meds$Benzodiazepine[!(meds$Benzodiazepine %in% AP_codes)] <- NA
meds$Anticholinergic[!(meds$Anticholinergic %in% AP_codes)] <- NA
meds$other_medication[!(meds$other_medication %in% AP_codes)] <- NA

# remove doses for non-useful drugs
meds$AP_dose[is.na(meds$Antipsychotic)] <- NA
meds$AD_dose[is.na(meds$antidepressant)] <- NA
meds$MS_dose[is.na(meds$Mood_Stabiliser)] <- NA
meds$Ben_dose[is.na(meds$Benzodiazepine)] <- NA
meds$Anticholinergic_dose[is.na(meds$Anticholinergic)] <- NA
meds$Other_medication_dose[is.na(meds$other_medication)] <- NA

aps <- table(meds$Antipsychotic) %>% as.data.frame()
ads <- table(meds$antidepressant) %>% as.data.frame()
mss <- table(meds$Mood_Stabiliser) %>% as.data.frame()
bzs <- table(meds$Benzodiazepine) %>% as.data.frame()
acs <- table(meds$Anticholinergic) %>% as.data.frame()
ots <- table(meds$other_medication) %>% as.data.frame()

med_freq <- full_join(aps, ads, by = "Var1")
med_freq <- full_join(med_freq, mss, by = "Var1")
med_freq <- full_join(med_freq, bzs, by = "Var1")
med_freq <- full_join(med_freq, acs, by = "Var1")
med_freq <- full_join(med_freq, ots, by = "Var1")

cols <- colnames(med_freq)

med_freq$total <- rowSums(med_freq[, cols[-1]], na.rm = TRUE)

med_freq <- as.data.frame(recode_selected_codes(df = med_freq, recode_vector = recode_vector, columns_to_recode = "Var1"))

med_df <- dplyr::select(med_freq, c("Var1", "total"))
med_df <- med_df %>%
    mutate(Var1 = str_to_sentence(Var1))
colnames(med_df) <- c("Antipsychotic", "N")

med_df$Administration <- c("Oral", "Oral", "Oral", "Oral", "Oral", "Depot", "Oral", "Depot", "Oral", "Depot", "Oral", "Oral", "Depot", "Oral", "Oral", "Depot", "Oral", "Oral", "Oral","Depot", "Depot")

med_df <- med_df %>% dplyr::select(c("Antipsychotic", "Administration", "N"))

med_df$Antipsychotic[6] <- "Flupenthixol"

rm(meds, aps, ads, mss, bzs, acs, ots, cols,  med_freq)

We included 585 participants with schizophrenia or schizoaffective disorder, depressed type (205 [35%] female; mean [SD] age of 43.5 [11.7] years). At the time of the interview, participants were prescribed at least one of 16 different antipsychotics, administered orally or by long-acting injection. Clozapine (36.8%) and olanzapine (17.6%) were the most frequently prescribed antipsychotics. Descriptive statistics (Supplementary Table 2), the frequency of antipsychotics reported (Supplementary Table 3), and the allele frequency of pharmacogenomic star alleles (Supplementary Table 4) are found in the Supplementary Materials. Only associations that pass the 5% False Discovery Rate (FDR) threshold are highlighted. Effect sizes are standardised and reported alongside uncorrected and FDR-corrected p values.


Confirmatory Factor Analysis of Schizophrenia Phenotypes.

Four factor structures were fit to determine which best represented the data as described in Supplementary Table 5. The model with the best fit (Comparative Fit Index = 0.997, Square Error of Approximation = 0.019, Standardised Root Mean Square Residual = 0.043) had five dimensions related to positive symptoms, negative symptoms of diminished expressivity, negative symptoms of reduced motivation and pleasure, depression and suicide, and cognitive ability (Figure 2). The derived factors were all significantly associated with the Global Assessment Scale in the expected direction (Supplementary Materials). Further information about the pre-morbid variables considered and their associations with the cognitive dimension and dose are reported in the Supplementary Materials.

knitr::include_graphics("Writing/figs/Figure 2.png")
Figure 2. Factor structure from the confirmatory factor analysis of current schizophrenia phenotypes within the CardiffCOGS sample. Standardised loadings between latent factors (circles) and contributing phenotypes (rectangles) are reported on straight lines. Curved lines represent correlations between latent factors.  EXP, Diminished Expressivity; MAP, Reduced Motivation and Pleasure; HVLT, Hopkins Visual Learning Test; BVMT, Brief Visuospatial Memory Test-Revised; CPT, Continuous Performance Test.

Figure 2. Factor structure from the confirmatory factor analysis of current schizophrenia phenotypes within the CardiffCOGS sample. Standardised loadings between latent factors (circles) and contributing phenotypes (rectangles) are reported on straight lines. Curved lines represent correlations between latent factors. EXP, Diminished Expressivity; MAP, Reduced Motivation and Pleasure; HVLT, Hopkins Visual Learning Test; BVMT, Brief Visuospatial Memory Test-Revised; CPT, Continuous Performance Test.



Associations between Phenotype Dimensions and Medication Variables.

Only associations that passed the 5% False Discovery Rate (FDR) threshold were considered significant. Effect sizes were standardised and shown alongside uncorrected p values. The results of association tests between phenotype dimensions and medication variables are shown in Table 1. Extended versions of this (and other tables) that include associations between further covariates and phenotype dimensions are given in Supplementary Tables 6 – 8.

Higher scores on the positive dimension were associated with higher chlorpromazine-equivalent antipsychotic dose (β = 0.145; 95%CI, 0.06 to 0.23; p = 8x10⁻⁴). Higher scores on the diminished expressivity dimension were associated with clozapine use (β = 0.417; 95%CI, 0.25 to 0.59; p = 2x10⁻⁶). Higher scores on the reduced motivation and pleasure dimension were also associated with clozapine use (β = 0.232; 95%CI, 0.06 to 0.41; p = 0.009). Higher scores on the suicide and depression dimension were associated with higher chlorpromazine-equivalent antipsychotic dose (β = 0.099; 95%CI, 0.02 to 0.18; p = 0.021).

Lower scores on the cognition dimension, indicating poorer cognitive ability, were associated with higher chlorpromazine-equivalent daily antipsychotic dose (β = -0.12; 95%CI, -0.19 to -0.05; p = 0.001), clozapine use (β = -0.498; 95%CI, -0.65 to -0.35; p = 3x10⁻¹⁰), and anticholinergic use (β = -0.345; 95%CI, -0.55 to -0.14; p = 8x10⁻⁴).

#### create table ####
t1 <- make_tab(pos)
t2 <- make_tab(exp)
t3 <- make_tab(map)
t4 <- make_tab(sad)
t5 <- make_tab(cog)

f1 <- get_fit(pos)
f2 <- get_fit(exp)
f3 <- get_fit(map)
f4 <- get_fit(sad)
f5 <- get_fit(cog)

main_res <- rbind(t1, t2, t3, t4, t5)
extra <- cbind(f1, f2[2], f3[2], f4[2], f5[2])

main_res_fdr <- mutate(group_by(main_res, Predictor), FDR=p.adjust(p,"fdr"))

main_res_fdr$p <- format_p(main_res_fdr$p)
main_res_fdr$FDR <- format_p(main_res_fdr$FDR)

main_res_fdr$`p (FDR)` <- paste0(main_res_fdr$p, " (", main_res_fdr$FDR, ")")
main_res_fdr <- dplyr::select(main_res_fdr, -c("p", "FDR"))

tmp <- split(main_res_fdr, f = main_res_fdr$Outcome)  

t1 <- as.data.frame(tmp$positive[-1]) 
t1 <- t1[-c(4:12), ]
t2 <- as.data.frame(tmp$express[-1])
t2 <- t2[-c(4:12), ]
t3 <- as.data.frame(tmp$mandp[-1])
t3 <- t3[-c(4:12), ]
t4 <- as.data.frame(tmp$sad[-1])
t4 <- t4[-c(4:12), ]
t5 <- as.data.frame(tmp$cog[-1])
t5 <- t5[-c(4:14), ]

main <- left_join(t1, t2, by = "Predictor")
main <- left_join(main, t3, by = "Predictor")
main <- left_join(main, t4, by = "Predictor")
main <- full_join(main, t5, by = "Predictor")

main <- column_as_rownames(main, var = "Predictor")
rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)")

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)" ), caption = "Table 1. Associations between medication variables with schizophrenia symptom and cognitive ability dimensions in CardiffCOGS. Five separate models were fit, each with severity scores for a schizophrenia phenotype as the outcome variable. Variables of interest included the medication variables, chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use. All models controlled for medication adherence, schizophrenia PGS, age, sex, and the first five genetic principal components. Intelligence PGS and Educational Attainment PGS were included as additional covariates in the model where the cognitive ability dimension is the outcome. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score.") %>% 
   add_header_above(header = c( " " = 1, "Positive" = 2, "Diminished Expressivity" = 2, "Reduced Motivation and Pleasure" = 2, "Suicide and Depression" = 2, "Cognition" = 2)) %>%
  kable_classic(full_width = T) 
Table 1. Associations between medication variables with schizophrenia symptom and cognitive ability dimensions in CardiffCOGS. Five separate models were fit, each with severity scores for a schizophrenia phenotype as the outcome variable. Variables of interest included the medication variables, chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use. All models controlled for medication adherence, schizophrenia PGS, age, sex, and the first five genetic principal components. Intelligence PGS and Educational Attainment PGS were included as additional covariates in the model where the cognitive ability dimension is the outcome. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score.
Positive
Diminished Expressivity
Reduced Motivation and Pleasure
Suicide and Depression
Cognition
Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR)
CPZ-eq Antipsychotic Dose (mg/day) 0.145 (0.04) 8x10⁻⁴ (0.004) 0.043 (0.04) 0.307 (0.307) 0.056 (0.04) 0.195 (0.244) 0.099 (0.04) 0.021 (0.034) -0.12 (0.04) 0.001 (0.004)
Clozapine (Yes) -0.061 (0.09) 0.491 (0.613) 0.417 (0.09) 2x10⁻⁶ (6x10⁻⁶) 0.232 (0.09) 0.009 (0.015) -0.007 (0.09) 0.937 (0.937) -0.498 (0.08) 3x10⁻¹⁰ (1x10⁻⁹)
Anticholinergic (Yes) 0.081 (0.12) 0.493 (0.493) 0.222 (0.12) 0.055 (0.076) 0.272 (0.12) 0.021 (0.053) 0.221 (0.12) 0.06 (0.076) -0.345 (0.1) 8x10⁻⁴ (0.004)


Pharmacogenomic Associations with the Phenotype Dimensions.

All pharmacogenomic associations were adjusted for medication variables. The addition of pharmacogenomic variables into the models did not substantially influence the associations between the medication variables and schizophrenia phenotype dimensions described above. While some attenuation of p values was observed, there was no change to the overall pattern of results, with previously significant associations remaining so.

In the full sample, we found several associations in which lower symptom dimension scores, and so less severe symptoms, were associated with faster genotype-inferred enzyme activity. Lower scores on the positive symptom dimension were associated with higher CYP2C19 activity scores (β = -0.108; 95%CI, -0.19 to -0.03; p = 0.009). Lower scores on the diminished expressivity dimension were associated with higher CYP3A5 activity score (β = -0.113; 95%CI, -0.19 to -0.03; p = 0.007). Similarly, we also found an association between lower scores on the reduced motivation and pleasure dimension and higher CYP3A5 activity score (β = -0.106; 95%CI, -0.19 to -0.02; p = 0.012). There were no pharmacogenomic associations with either the suicide and depression or the cognitive ability dimension (Table 2).

#### create table ####
t1 <- make_tab(pos_pgx)
t2 <- make_tab(exp_pgx)
t3 <- make_tab(map_pgx)
t4 <- make_tab(sad_pgx)
t5 <- make_tab(cog_pgx)

f1 <- get_fit(pos_pgx)
f2 <- get_fit(exp_pgx)
f3 <- get_fit(map_pgx)
f4 <- get_fit(sad_pgx)
f5 <- get_fit(cog_pgx)

main_res <- rbind(t1, t2, t3, t4, t5)
extra <- cbind(f1, f2[2], f3[2], f4[2], f5[2])

main_res_fdr <- mutate(group_by(main_res, Predictor), FDR=p.adjust(p,"fdr"))

main_res_fdr$p <- format_p(main_res_fdr$p)
main_res_fdr$FDR <- format_p(main_res_fdr$FDR)

main_res_fdr$`p (FDR)` <- paste0(main_res_fdr$p, " (", main_res_fdr$FDR, ")")
main_res_fdr <- dplyr::select(main_res_fdr, -c("p", "FDR"))

tmp <- split(main_res_fdr, f = main_res_fdr$Outcome)  

t1 <- as.data.frame(tmp$positive[-1]) 
t1 <- t1[-c(9:17), ]
t2 <- as.data.frame(tmp$express[-1])
t2 <- t2[-c(9:17), ]
t3 <- as.data.frame(tmp$mandp[-1])
t3 <- t3[-c(9:17), ]
t4 <- as.data.frame(tmp$sad[-1])
t4 <- t4[-c(9:17), ]
t5 <- as.data.frame(tmp$cog[-1])
t5 <- t5[-c(9:19), ]

main <- left_join(t1, t2, by = "Predictor")
main <- left_join(main, t3, by = "Predictor")
main <- left_join(main, t4, by = "Predictor")
main <- full_join(main, t5, by = "Predictor")

main <- column_as_rownames(main, var = "Predictor")
rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)","CYP1A2 Activity Score", "CYP2D6 Activity Score", "CYP3A5 Activity Score", "CYP2C19 Activity Score", "CYP2C9 Activity Score")

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)" ), caption = "Table 2. Associations between medication and pharmacogenomic variables with schizophrenia symptom and cognitive ability dimensions in CardiffCOGS. Five separate models were fit, each with severity scores for a schizophrenia phenotype as the outcome variable. Variables of interest included the medication variables (i.e., chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use) and pharmacogenomic variables (i.e., the genetics-inferred enzyme activity scores). All models controlled for medication adherence, schizophrenia PGS, age, sex, and the first five genetic principal components. Intelligence PGS and Educational Attainment PGS were included as additional covariates in the model where the cognitive ability dimension is the outcome. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score.") %>% 
   add_header_above(header = c( " " = 1, "Positive" = 2, "Diminished Expressivity" = 2, "Reduced Motivation and Pleasure" = 2, "Suicide and Depression" = 2, "Cognition" = 2)) %>%
  kable_classic(full_width = T) 
Table 2. Associations between medication and pharmacogenomic variables with schizophrenia symptom and cognitive ability dimensions in CardiffCOGS. Five separate models were fit, each with severity scores for a schizophrenia phenotype as the outcome variable. Variables of interest included the medication variables (i.e., chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use) and pharmacogenomic variables (i.e., the genetics-inferred enzyme activity scores). All models controlled for medication adherence, schizophrenia PGS, age, sex, and the first five genetic principal components. Intelligence PGS and Educational Attainment PGS were included as additional covariates in the model where the cognitive ability dimension is the outcome. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score.
Positive
Diminished Expressivity
Reduced Motivation and Pleasure
Suicide and Depression
Cognition
Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR)
CPZ-eq Antipsychotic Dose (mg/day) 0.146 (0.04) 7x10⁻⁴ (0.003) 0.035 (0.04) 0.405 (0.405) 0.045 (0.04) 0.296 (0.37) 0.098 (0.04) 0.023 (0.039) -0.115 (0.04) 0.003 (0.006)
Clozapine (Yes) -0.044 (0.09) 0.623 (0.778) 0.414 (0.09) 3x10⁻⁶ (8x10⁻⁶) 0.236 (0.09) 0.008 (0.014) 0.004 (0.09) 0.961 (0.961) -0.499 (0.08) 4x10⁻¹⁰ (2x10⁻⁹)
Anticholinergic (Yes) 0.059 (0.12) 0.618 (0.618) 0.209 (0.12) 0.073 (0.104) 0.266 (0.12) 0.025 (0.062) 0.205 (0.12) 0.083 (0.104) -0.329 (0.1) 0.002 (0.008)
CYP1A2 Activity Score -0.051 (0.04) 0.227 (0.365) -0.066 (0.04) 0.116 (0.289) -0.039 (0.04) 0.365 (0.365) -0.042 (0.04) 0.321 (0.365) 0.07 (0.04) 0.06 (0.289)
CYP2D6 Activity Score -0.022 (0.04) 0.595 (0.744) 0.047 (0.04) 0.25 (0.67) 0.046 (0.04) 0.268 (0.67) -0.008 (0.04) 0.847 (0.847) -0.02 (0.04) 0.587 (0.744)
CYP3A5 Activity Score -0.042 (0.04) 0.319 (0.333) -0.113 (0.04) 0.007 (0.031) -0.106 (0.04) 0.012 (0.031) -0.041 (0.04) 0.333 (0.333) 0.037 (0.04) 0.321 (0.333)
CYP2C19 Activity Score -0.108 (0.04) 0.009 (0.047) -0.003 (0.04) 0.936 (0.936) -0.04 (0.04) 0.339 (0.565) -0.079 (0.04) 0.057 (0.143) 0.008 (0.04) 0.817 (0.936)
CYP2C9 Activity Score -0.049 (0.04) 0.237 (0.54) -0.012 (0.04) 0.764 (0.919) 0.004 (0.04) 0.919 (0.919) -0.041 (0.04) 0.324 (0.54) -0.048 (0.04) 0.188 (0.54)



Within the subgroup of participants taking clozapine, higher CYP1A2 activity score was associated with higher cognitive ability (β = 0.17; 95%CI, 0.05 to 0.29; p = 0.005). No other pharmacogenomic variables were significantly associated with schizophrenia phenotype severity after correcting for multiple comparisons in this clozapine taking group (Table 3), although higher dose of antipsychotic was nominally associated with lower cognitive ability (β = -0.147; 95%CI, -0.27 to -0.02; p = 0.02).

#### create table ####
t1 <- make_tab(cpos_pgx)
t2 <- make_tab(cexp_pgx)
t3 <- make_tab(cmap_pgx)
t4 <- make_tab(csad_pgx)
t5 <- make_tab(ccog_pgx)

f1 <- get_fit(cpos_pgx)
f2 <- get_fit(cexp_pgx)
f3 <- get_fit(cmap_pgx)
f4 <- get_fit(csad_pgx)
f5 <- get_fit(ccog_pgx)

main_res <- rbind(t1, t2, t3, t4, t5)
extra <- cbind(f1, f2[2], f3[2], f4[2], f5[2])

main_res_fdr <- mutate(group_by(main_res, Predictor), FDR=p.adjust(p,"fdr"))

main_res_fdr$p <- format_p(main_res_fdr$p)
main_res_fdr$FDR <- format_p(main_res_fdr$FDR)

main_res_fdr$`p (FDR)` <- paste0(main_res_fdr$p, " (", main_res_fdr$FDR, ")")
main_res_fdr <- dplyr::select(main_res_fdr, -c("p", "FDR"))

tmp <- split(main_res_fdr, f = main_res_fdr$Outcome)  

t1 <- as.data.frame(tmp$positive[-1]) 
t1 <- t1[-c(8:16), ]
t2 <- as.data.frame(tmp$express[-1])
t2 <- t2[-c(8:16), ]
t3 <- as.data.frame(tmp$mandp[-1])
t3 <- t3[-c(8:16), ]
t4 <- as.data.frame(tmp$sad[-1])
t4 <- t4[-c(8:16), ]
t5 <- as.data.frame(tmp$cog[-1])
t5 <- t5[-c(8:18), ]

main <- left_join(t1, t2, by = "Predictor")
main <- left_join(main, t3, by = "Predictor")
main <- left_join(main, t4, by = "Predictor")
main <- full_join(main, t5, by = "Predictor")

main <- column_as_rownames(main, var = "Predictor")
rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Anticholinergic (Yes)","CYP1A2 Activity Score", "CYP2D6 Activity Score", "CYP3A5 Activity Score", "CYP2C19 Activity Score", "CYP2C9 Activity Score")

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)" ), caption = "Table 3. Associations between medication and pharmacogenomic variables with schizophrenia symptom and cognitive ability dimensions in the subgroup of CardiffCOGS participants prescribed clozapine. Five separate models were fit, each with severity scores for a schizophrenia phenotype as the outcome variable. Variables of interest included the medication variables (i.e., chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use) and pharmacogenomic variables (i.e., the genetics-inferred enzyme activity scores). All models controlled for medication adherence, schizophrenia PGS, age, sex, and the first five genetic principal components. Intelligence PGS and Educational Attainment PGS were included as additional covariates in the model where the cognitive ability dimension is the outcome. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score.") %>% 
   add_header_above(header = c( " " = 1, "Positive (Clozapine Subgroup)" = 2, "Diminished Expressivity (Clozapine Subgroup)" = 2, "Reduced Motivation and Pleasure (Clozapine Subgroup)" = 2, "Suicide and Depression (Clozapine Subgroup)" = 2, "Cognition (Clozapine Subgroup)" = 2)) %>%
  kable_classic(full_width = T) 
Table 3. Associations between medication and pharmacogenomic variables with schizophrenia symptom and cognitive ability dimensions in the subgroup of CardiffCOGS participants prescribed clozapine. Five separate models were fit, each with severity scores for a schizophrenia phenotype as the outcome variable. Variables of interest included the medication variables (i.e., chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use) and pharmacogenomic variables (i.e., the genetics-inferred enzyme activity scores). All models controlled for medication adherence, schizophrenia PGS, age, sex, and the first five genetic principal components. Intelligence PGS and Educational Attainment PGS were included as additional covariates in the model where the cognitive ability dimension is the outcome. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score.
Positive (Clozapine Subgroup)
Diminished Expressivity (Clozapine Subgroup)
Reduced Motivation and Pleasure (Clozapine Subgroup)
Suicide and Depression (Clozapine Subgroup)
Cognition (Clozapine Subgroup)
Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR)
CPZ-eq Antipsychotic Dose (mg/day) 0.02 (0.07) 0.786 (0.786) 0.077 (0.07) 0.273 (0.683) 0.03 (0.07) 0.673 (0.786) 0.05 (0.07) 0.471 (0.785) -0.147 (0.06) 0.02 (0.1)
Anticholinergic (Yes) -0.076 (0.2) 0.704 (0.88) 0.023 (0.19) 0.907 (0.907) 0.137 (0.2) 0.486 (0.81) 0.189 (0.19) 0.327 (0.81) -0.274 (0.17) 0.109 (0.547)
CYP1A2 Activity Score -0.083 (0.07) 0.242 (0.404) -0.108 (0.07) 0.117 (0.293) -0.041 (0.07) 0.556 (0.556) -0.059 (0.07) 0.387 (0.484) 0.17 (0.06) 0.005 (0.026)
CYP2D6 Activity Score -0.028 (0.07) 0.695 (0.836) 0.071 (0.07) 0.315 (0.836) 0.064 (0.07) 0.369 (0.836) -0.039 (0.07) 0.574 (0.836) -0.013 (0.06) 0.836 (0.836)
CYP3A5 Activity Score -0.082 (0.07) 0.251 (0.251) -0.12 (0.07) 0.085 (0.198) -0.103 (0.07) 0.147 (0.198) -0.126 (0.07) 0.07 (0.198) 0.087 (0.06) 0.158 (0.198)
CYP2C19 Activity Score -0.05 (0.07) 0.481 (0.843) 0.014 (0.07) 0.843 (0.843) 0.014 (0.07) 0.84 (0.843) 0.052 (0.07) 0.444 (0.843) 0.023 (0.06) 0.699 (0.843)
CYP2C9 Activity Score -0.041 (0.07) 0.564 (0.62) -0.164 (0.07) 0.019 (0.095) -0.121 (0.07) 0.086 (0.215) -0.098 (0.07) 0.155 (0.258) 0.03 (0.06) 0.62 (0.62)



As recommended in the STREGA guidelines, we provide unadjusted estimates for associations between pharmacogenomic variables and symptom dimensions (Supplementary Tables 9 & 10). Sensitivity analyses in which we controlled for medication that may lead to phenoconversion did not lead to different results (Supplementary Tables 11 & 12). However, inclusion of an interaction term between CYP1A2 and smoking status in our model attenuated the association between CYP1A2 activity score and the cognitive dimension (Supplementary Table 13). This suggests that this pharmacogenomic association may be partly explained by patient lifestyle factors. However, our sensitivity analysis is limited by incomplete smoking information in the sample; thus, diminished statistical power may also account for this weakened association.





Discussion

Discussion

This cross-sectional study investigated medication and pharmacogenomic correlates of current phenotype severity in people with schizophrenia or schizoaffective disorder depressed-type. We found that higher daily chlorpromazine-equivalent antipsychotic dose was associated with more severe scores on both the positive symptom and the suicide and depression dimensions, while clozapine use was associated with worse scores on the two negative symptom dimensions (i.e., diminished expressivity, reduced motivation and pleasure). We also found that chlorpromazine-equivalent daily antipsychotic dose, clozapine use, and anticholinergic use were all associated with lower scores on the cognitive dimension, indicating poorer cognitive ability.

Some of the associations we have observed between drug dosage and symptomatology are likely to reflect influences of the latter on prescribing patterns. Higher doses of antipsychotic medication are likely to be prescribed to help manage more severe or incompletely resolved positive symptoms, while negative symptoms do not generally respond well to typical antipsychotics and may trigger the prescription of clozapine which does have efficacy in this domain47.

Our findings that antipsychotic dose, clozapine use, and anticholinergic use were associated with poorer cognition are consistent with other research48–53. Moreover, our effect sizes were, in some instances, substantial, with our strongest association indicating that scores on the cognitive ability dimension are nearly 0.5 standard deviations lower in patients prescribed clozapine. These findings could be plausibly related, in part, to causal effects of drug treatment. However, interpreting cross-sectional findings relating to cognition and medication use is challenging due to the possibility of reverse causation whereby patients with cognitive impairment could be more likely to receive higher doses of medication. The situation with respect to clozapine may be even more complex because a prescription of clozapine usually necessitates a diagnosis of TRS, which is itself associated with greater cognitive impairment than treatment-responsive schizophrenia54–56. Nevertheless, the associations observed between both antipsychotic dose and clozapine use with poorer cognition were significant after controlling for premorbid intelligence as indexed by PGS for intelligence and educational attainment. These medication associations mostly replicate in the alternative analysis described in the Supplementary Materials using NART to estimate premorbid intelligence, albeit with weaker signals. In all, our analyses tentatively support the interpretation that the association may be causally related to medication use, instead of reflecting the confounding effects of lower premorbid cognitive ability in those who subsequently receive clozapine or higher doses of antipsychotics.

Our combined analysis of pharmacogenomic and medication variables offers a potential means of drawing causal inferences in regard to the observed associations between drug treatment and cognition. CYP1A2 is the main enzyme responsible for clozapine first-pass metabolism57,58. Higher enzyme activity can be expected to result in lower clozapine bioavailability for a given dose. Under a causal model, this should lead to fewer clozapine-induced cognitive effects. We indeed observed this in the association between higher cognitive ability and faster genotype-inferred CYP1A2 activity in people prescribed clozapine (Table 3), which points to the possibility that any negative impact of clozapine in cognition could be ameliorated in those with faster clozapine metabolism. In parallel, a nominally significant association also exists between higher cognitive ability and lower dose in those prescribed clozapine. In the context of all these results, we remark the use of pharmacogenetic information to phenotype enzyme activity and thus drug metabolism, highlighting individuals that could be particularly vulnerable to dose-dependent adverse drug reactions (ADRs). We also note that while this research takes advantage of such a phenotyping approach, the atypical instances of clozapine metabolism that would characterise these individuals in clinical scenarios can already be detected by therapeutic drug monitoring. For this reason, we echo the recent recommendations for therapeutic drug monitoring procedures to be more readily adopted as a routine part of the clinical management of those on clozapine59.

We also reported an inverse association between prescription of anticholinergic medication and cognition. Some antipsychotics cause extra-pyramidal side effects, generally as a dose-dependent ADR60,61. Extra pyramidal side effects are managed with anticholinergic medication, and although not recommended, these drugs may be prescribed prophylactically, pre-empting the onset of these ADRs62,63. The association between anticholinergic prescription and cognition is independent of daily antipsychotic dose. Therefore, this likely reflects a distinct contribution of anticholinergics on cognition, as opposed to capturing our reported dose-cognition association given the higher rates of anticholinergic prescription amongst people on high antipsychotic doses64.

We observed several associations between faster genotype-inferred enzyme activity with lower schizophrenia symptom severity. Increased CYP2C19 activity was associated with lower severity of positive symptoms. Associations between CYP2C19 with both schizophrenia severity12,65 and symptom improvement66 have been reported although those studies included only people taking clozapine and employed a single, general measure of symptom severity. In the absence of longitudinal symptom scores, we cannot investigate the rather counter-intuitive hypothesis suggested by our data that greater antipsychotic clearance, indexed by CYP2C19 activity, might lead to increased drug effectiveness. CYP2C19 is thought to play a minor part within the clozapine metabolic pathway67 but its role in antipsychotic metabolism more widely is poorly documented68. This is an avenue for future studies to follow.

Increased genetically inferred CYP3A5 activity was associated with lower scores on both the negative symptom dimensions. While associations with the two domains increases confidence in the findings, caution is warranted given that these are moderately correlated (see Figure 2), and we did not find orthogonal evidence that either of these dimensions were associated with antipsychotic dose. Thus, replication of these associations is required. CYP3A5 is relatively under-examined in antipsychotic research69 and its main genotype that leads to poor metabolism (*1/*3) is common worldwide but particularly in European populations. Indeed, it has been observed that major differences in genotype/phenotype distributions for this enzyme are mainly driven by the inclusion of African ancestries in studies70,71, as functional CYP3A5 alleles are more common in Africa. Populations from Asian countries also seem to have higher diversity of CYP3A5 alleles than Europe, though research in this continent is still scarce72. Future research aiming to investigate the relevance of CYP3A5 for outcomes in psychiatric populations should therefore aim to include more cohorts from admixed and non-European ancestral makeups.

Finally, we did not observe evidence for an association between CYP1A2 activity score and either the positive or negative schizophrenia symptom dimensions. A correlation between CYP1A2 activity and symptom severity has been reported11, and while several differences exist between the methods and sample employed in our own and the previous study, the observed trends in our data are not consistent with their findings. We also found no association between the CYP2C9 activity score and any of our phenotype severity scores.

The primary limitation of this study is its cross-sectional nature which means we are unable to assess drug treatment response, constraining our ability to make robust inferences about the causal directions for any of the associations. Second, our best fitting CFA model did not include a disorganised dimension, and therefore our study cannot address the possible relationships between this symptom dimension with medication and pharmacogenomic variables. Finally, although no individuals were excluded based on ancestry, 95% of the sample reported UK/European as their ethnic background. Cross-cultural differences permeate most aspects of psychiatry, with variation existing in diagnostic criteria, prognosis, therapeutic/prescribing practices, and more73. While ancestrally diverse samples are becoming more common, particularly in larger scale genetics studies, this hasn’t always been the case. Therefore, replication of this work across ancestrally diverse samples is required to determine whether these results are generalisable outside of White European backgrounds.

Overall, our findings indicate that poorer cognitive ability in individuals with schizophrenia was associated with the use of clozapine and anticholinergics, alongside high doses of antipsychotic medication. Cognition is an important predictor of schizophrenia functional outcomes74. Therefore, understanding the potentially multifaceted burden of these drugs could help clinicians minimise the likelihood of cognitive impairment and other poor outcomes during schizophrenia pharmacotherapy. Longitudinal studies, particularly randomised controlled trials, are required to fully understand the role that pharmacotherapy, especially clozapine and anticholinergics, has on cognitive outcomes for those with schizophrenia. However, given the lack of evidence-based guidelines for optimising antipsychotic doses in the maintenance phase of treatment75, addressing potential cognitive impacts might be an actionable target for future interventional research. For example, if information from prescription records (e.g. drug classes and doses) could contribute to identifying patients at high risk of reduced cognition, they could be prioritised for closer monitoring and/or mitigations (e.g., cognitive remediation therapy or avoiding prophylactic anticholinergics).

We also identify associations between the increased activity of certain CYP enzymes and the reduced severity of positive, negative, and cognitive symptoms. Except for CYP1A2 in patients taking clozapine, which we discuss earlier, the mechanisms by which variation within these pharmacogenes could influence schizophrenia severity are unclear. While our results implicate pharmacogenomic variation in antipsychotic pharmacodynamics, an area of psychopharmacology where robust predictors are particularly scarce, further validation of our findings in larger, more diverse samples is required before charting a course from this basic evidence towards improved strategies for patient support and care.





References

References


1 Carbon M, Correll CU. Clinical predictors of therapeutic response to antipsychotics in schizophrenia. Dialogues Clin Neurosci 2014; 16: 505–24.

2 Zhang J-P, Robinson D, Yu J, et al. Schizophrenia Polygenic Risk Score as a Predictor of Antipsychotic Efficacy in First-Episode Psychosis. AJP 2019; 176: 21–8.

3 Jonas KG, Lencz T, Li K, et al. Schizophrenia polygenic risk score and 20-year course of illness in psychotic disorders. Transl Psychiatry 2019; 9: 1–8.

4 Legge SE, Cardno AG, Allardyce J, et al. Associations Between Schizophrenia Polygenic Liability, Symptom Dimensions, and Cognitive Ability in Schizophrenia. JAMA Psychiatry 2021; 78: 1143–51.

5 Ahangari M, Bustamante D, Kirkpatrick R, et al. Relationship between polygenic risk scores and symptom dimensions of schizophrenia and schizotypy in multiplex families with schizophrenia. The British Journal of Psychiatry 2023; 223: 301–8.

6 van Westrhenen R, Aitchison KJ, Ingelman-Sundberg M, Jukić MM. Pharmacogenomics of Antidepressant and Antipsychotic Treatment: How Far Have We Got and Where Are We Going? Frontiers in Psychiatry 2020; 11.

7 Swen JJ, van der Wouden CH, Manson LE, et al. A 12-gene pharmacogenetic panel to prevent adverse drug reactions: an open-label, multicentre, controlled, cluster-randomised crossover implementation study. The Lancet 2023; 401: 347–56.

8 Whirl-Carrillo M, Huddart R, Gong L, et al. An Evidence-Based Framework for Evaluating Pharmacogenomics Knowledge for Personalized Medicine. Clinical Pharmacology & Therapeutics 2021; 110: 563–72.

9 Beunk L, Nijenhuis M, Soree B, et al. Dutch Pharmacogenetics Working Group (DPWG) guideline for the gene-drug interaction between CYP2D6, CYP3A4 and CYP1A2 and antipsychotics. Eur J Hum Genet 2024; 32: 278–85.

10 Pardiñas AF, Owen MJ, Walters JTR. Pharmacogenomics: A road ahead for precision medicine in psychiatry. Neuron 2021; 109: 3914–29.

11 Lesche D, Mostafa S, Everall I, Pantelis C, Bousman CA. Impact of CYP1A2, CYP2C19, and CYP2D6 genotype- and phenoconversion-predicted enzyme activity on clozapine exposure and symptom severity. The Pharmacogenomics Journal 2020; 20: 192–201.

12 Okhuijsen-Pfeifer C, van der Horst MZ, Bousman CA, et al. Genome-wide association analyses of symptom severity among clozapine-treated patients with schizophrenia spectrum disorders. Transl Psychiatry 2022; 12: 145.

13 Leucht S, Chaimani A, Krause M, et al. The response of subgroups of patients with schizophrenia to different antipsychotic drugs: a systematic review and meta-analysis. The Lancet Psychiatry 2022; 9: 884–93.

14 Bousman CA, Maruf AA, Marques DF, Brown LC, Müller DJ. The emergence, implementation, and future growth of pharmacogenomics in psychiatry: a narrative review. Psychol Med 2023; 53: 7983–93.

15 Wing JK, Babor T, Brugha T, et al. SCAN: Schedules for Clinical Assessment in Neuropsychiatry. Archives of General Psychiatry 1990; 47: 589–93.

16 American Psychiatric Association. Diagnostic and Statistical Manual of Mental Disorders: DSM-IV., 4th edn. American Psychiatric Association., 1994.

17 World Health Organization. The ICD-10 classification of mental and behavioural disorders: clinical descriptions and diagnostic guidelines. World Health Organization, 1992.

18 Andreasen NC. Scale for the Assessment of Positive Symptoms. 1986.

19 Andreasen NC. The Scale for the Assessment of Negative Symptoms (SANS): conceptual and theoretical foundations. The British journal of psychiatry 1989; 155: 49–52.

20 Addington D, Addington J, Maticka-Tyndale E. Assessing Depression in Schizophrenia: The Calgary Depression Scale. The British Journal of Psychiatry 1993; 163: 39–44.

21 Nuechterlein KH, Green MF, Kern RS, et al. The MATRICS Consensus Cognitive Battery, Part 1: Test Selection, Reliability, and Validity. AJP 2008; 165: 203–13.

22 Thompson K, Kulkarni J, Sergejew AA. Reliability and validity of a new Medication Adherence Rating Scale (MARS) for the psychoses. Schizophrenia Research 2000; 42: 241–7.

23 Brown E, Shah P, Kim J. ChlorpromazineR: Convert Antipsychotic Doses to Chlorpromazine Equivalents. 2021. https://github.com/ropensci/chlorpromazineR.

24 Gardner D, Murphy A, O’Donnell H, Centorrino F, Baldessarini R. International Consensus Study of Antipsychotic Dosing. American Journal of Psychiatry 2010; 167: 686–93.

25 Leucht S, Samara M, Heres S, Davis JM. Dose Equivalents for Antipsychotic Drugs: The DDD Method. Schizophrenia Bulletin 2016; 42: S90–4.

26 Endicott J, Spitzer RL, Fleiss JL, Cohen J. The Global Assessment Scale: A procedure for measuring overall severity of psychiatric disturbance. Archives of general psychiatry 1976; 33: 766–71.

27 Pardiñas AF, Holmans P, Pocklington AJ, et al. Common schizophrenia alleles are enriched in mutation-intolerant genes and in regions under strong background selection. Nature Genetics 2018; 50: 381–9.

28 Lynham AJ, Knott S, Underwood JFG, et al. DRAGON-Data: a platform and protocol for integrating genomic and phenotypic data across large psychiatric cohorts. BJPsych Open 2023; 9: 1–8.

29 Lee S, Shin J-Y, Kwon N-J, Kim C, Seo J-S. ClinPharmSeq: A targeted sequencing panel for clinical pharmacogenetics implementation. PLOS ONE 2022; 17: 1–19.

30 Van Rossum G, Drake FL. Python 3 Reference Manual. 2009.

31 Trubetskoy V, Pardiñas AF, Qi T, et al. Mapping genomic loci implicates genes and synaptic biology in schizophrenia. Nature 2022; 604: 502–8.

32 Savage JE, Jansen PR, Stringer S, et al. Genome-wide association meta-analysis in 269,867 individuals identifies new genetic and functional links to intelligence. Nat Genet 2018; 50: 912–9.

33 Okbay A, Wu Y, Wang N, et al. Polygenic prediction of educational attainment within and between families from genome-wide association analyses in 3 million individuals. Nat Genet 2022; 54: 437–49.

34 Ge T, Chen C-Y, Ni Y, Feng Y-CA, Smoller JW. Polygenic prediction via Bayesian regression and continuous shrinkage priors. Nat Commun 2019; 10: 1776.

35 Chang CC, Chow CC, Tellier LCAM, Vattikuti S, Purcell SM, Lee JJ. Second-generation PLINK: rising to the challenge of larger and richer datasets. GigaScience 2015; 4: 7.

36 The 1000 Genomes Project Consortium, Auton A, Abecasis GR, et al. A global reference for human genetic variation. Nature 2015; 526: 68–74.

37 R Core Team. R: A Language and Environment for Statistical Computing. 2021. https://www.R-project.org/.

38 Fanous AH, Zhou B, Aggen SH, et al. Genome-Wide Association Study of Clinical Dimensions of Schizophrenia: Polygenic Effect on Disorganized Symptoms. AJP 2012; 169: 1309–17.

39 Quattrone D, Forti MD, Gayer-Anderson C, et al. Transdiagnostic dimensions of psychopathology at first episode psychosis: findings from the multinational EU-GEI study. Psychological Medicine 2019; 49: 1378–91.

40 Rosseel Y. lavaan: An R Package for Structural Equation Modeling. Journal of Statistical Software 2012; 48: 1–36.

41 Allegrini AG, Selzam S, Rimfeld K, von Stumm S, Pingault JB, Plomin R. Genomic prediction of cognitive traits in childhood and adolescence. Mol Psychiatry 2019; 24: 819–27.

42 von Stumm S, Plomin R. Using DNA to predict intelligence. Intelligence 2021; 86: 101530.

43 Nelson HE. THE NATIONAL ADULT READING TEST (NART). NFER-NELSON, 1991.

44 Mostafa S, Polasek TM, Bousman CA, et al. Pharmacogenomics in Psychiatry – the Challenge of Cytochrome P450 Enzyme Phenoconversion and Solutions to Assist Precision Dosing. Pharmacogenomics 2022; 23: 857–67.

45 Little J, Higgins JPT, Ioannidis JPA, et al. Strengthening the reporting of genetic association studies (STREGA): an extension of the STROBE Statement. Hum Genet 2009; 125: 131–51.

46 von Elm E, Altman DG, Egger M, et al. The Strengthening the Reporting of Observational Studies in Epidemiology (STROBE) statement: guidelines for reporting observational studies. Ann Intern Med 2007; 147: 573–7.

47 Siskind D, McCartney L, Goldschlager R, Kisely S. Clozapine v. first- and second-generation antipsychotics in treatment-refractory schizophrenia: systematic review and meta-analysis. The British Journal of Psychiatry 2016; 209: 385–92.

48 Hori H, Noguchi H, Hashimoto R, et al. Antipsychotic medication and cognitive function in schizophrenia. Schizophrenia Research 2006; 86: 138–46.

49 Ballesteros A, Sánchez-Torres AM, López-Ilundain JM, et al. Is cognitive impairment associated with antipsychotic dose and anticholinergic equivalent loads in first-episode psychosis? Psychological Medicine 2018; 48: 2247–56.

50 Baldez DP, Biazus TB, Rabelo-da-Ponte FD, et al. The effect of antipsychotics on the cognitive performance of individuals with psychotic disorders: Network meta-analyses of randomized controlled trials. Neuroscience & Biobehavioral Reviews 2021; 126: 265–75.

51 Lu C, Jin X, Liu N, et al. The relationship of cardiovascular disease risk, clozapine antipsychotic use and cognitive function in a large Chinese schizophrenia cohort. Brain Research 2024; 1845: 149220.

52 Haddad C, Salameh P, Sacre H, Clément J-P, Calvet B. Effects of antipsychotic and anticholinergic medications on cognition in chronic patients with schizophrenia. BMC Psychiatry 2023; 23.

53 Feber L, Peter NL, Chiocchia V, et al. Antipsychotic Drugs and Cognitive Function: A Systematic Review and Pairwise Network Meta-Analysis. JAMA Psychiatry 2024; published online Oct 16. DOI:10.1001/jamapsychiatry.2024.2890.

54 Iasevoli F, Avagliano C, Altavilla B, et al. Disease Severity in Treatment Resistant Schizophrenia Patients Is Mainly Affected by Negative Symptoms, Which Mediate the Effects of Cognitive Dysfunctions and Neurological Soft Signs. Front Psychiatry 2018; 9.

55 Legge SE, Dennison CA, Pardiñas AF, et al. Clinical indicators of treatment-resistant psychosis. The British Journal of Psychiatry 2020; 216: 259–66.

56 Sun J, Yee JY, See YM, et al. Association between treatment resistance and cognitive function in schizophrenia. Singapore Medical Journal 2024; 65: 552.

57 Bertilsson L, Carrillo J, Dahl M, et al. Clozapine disposition covaries with CYP1A2 activity determined by a caffeine test. British Journal of Clinical Pharmacology 1994; 38: 471–3.

58 Eiermann B, Engel G, Johansson I, Zanger UM, Bertilsson L. The involvement of CYP1A2 and CYP3A4 in the metabolism of clozapine. British Journal of Clinical Pharmacology 1997; 44: 439–46.

59 Flanagan RJ, Gee S, Belsey S, Couchman L, Lally J. Therapeutic monitoring of plasma clozapine and N-desmethylclozapine (norclozapine): practical considerations. BJPsych Advances 2023; 29: 92–102.

60 Siafis S, Wu H, Wang D, et al. Antipsychotic dose, dopamine D2 receptor occupancy and extrapyramidal side-effects: a systematic review and dose-response meta-analysis. Mol Psychiatry 2023; 28: 3267–77.

61 Yoshida K, Takeuchi H. Dose-dependent effects of antipsychotics on efficacy and adverse effects in schizophrenia. Behavioural Brain Research 2021; 402: 113098.

62 Ogino S, Miyamoto S, Miyake N, Yamaguchi N. Benefits and limits of anticholinergic use in schizophrenia: Focusing on its effect on cognitive function. Psychiatry and Clinical Neurosciences 2014; 68: 37–49.

63 Chatterjee K, Dangi A, Sharma R, Yadav P, Chauhan VS, Prakash J. Adding pre-emptive anticholinergics to antipsychotics: Is it justified? Ind Psychiatry J 2022; 31: 370–3.

64 Hori H, Yasui-Furukori N, Hasegawa N, et al. Prescription of Anticholinergic Drugs in Patients With Schizophrenia: Analysis of Antipsychotic Prescription Patterns and Hospital Characteristics. Front Psychiatry 2022; 13. DOI:10.3389/fpsyt.2022.823826.

65 Rodrigues-Silva C, Semedo AT, Neri HF da S, et al. The CYP2C192 and CYP2C1917 Polymorphisms Influence Responses to Clozapine for the Treatment of Schizophrenia. Neuropsychiatric Disease and Treatment 2020; 16: 427–32.

66 Piatkov I, Caetano D, Assur Y, et al. CYP2C19*17 protects against metabolic complications of clozapine treatment. World J Biol Psychiatry 2017; 18: 521–7.

67 Dean L, Kane M. Medical Genetics Summaries Expert Reviewers. National Center for Biotechnology Information (US), 2021 https://www.ncbi.nlm.nih.gov/books/NBK436916/.

68 de Brabander E, Kleine Schaars K, van Amelsvoort T, et al. Influence of CYP2C19 and CYP2D6 on side effects of aripiprazole and risperidone: A systematic review. Journal of Psychiatric Research 2024; 174: 137–52.

69 Ragia G, Dahl M-L, Manolopoulos VG. Influence of CYP3A5 polymorphism on the pharmacokinetics of psychiatric drugs. Curr Drug Metab 2016; 17: 227–36.

70 Bains RK, Kovacevic M, Plaster CA, et al. Molecular diversity and population structure at the Cytochrome P450 3A5 gene in Africa. BMC Genetics 2013; 14: 34.

71 Masimirembwa C, Dandara C, Hasler J. Chapter 43 - Population Diversity and Pharmacogenomics in Africa. In: Padmanabhan S, ed. Handbook of Pharmacogenomics and Stratified Medicine. San Diego: Academic Press, 2014: 971–98.

72 Dorji PW, Tshering G, Na-Bangchang K. CYP2C9, CYP2C19, CYP2D6 and CYP3A5 polymorphisms in South-East and East Asian populations: A systematic review. Journal of Clinical Pharmacy and Therapeutics 2019; 44: 508–24.

73 Gopalkrishnan N. Cultural Diversity and Mental Health: Considerations for Policy and Practice. Front Public Health 2018; 6. DOI:10.3389/fpubh.2018.00179.

74 McCutcheon RA, Keefe RSE, McGuire PK. Cognitive impairment in schizophrenia: aetiology, pathophysiology, and treatment. Mol Psychiatry 2023; 28: 1902–18.

75 Shimomura Y, Kikuchi Y, Suzuki T, Uchida H, Mimura M, Takeuchi H. Antipsychotic treatment in the maintenance phase of schizophrenia: An updated systematic review of the guidelines and algorithms. Schizophrenia Research 2020; 215: 8–16.





Supplementary Notes - Methods

Adherence Questionnaire Item

Adherence Questionnaire Item

Adherence to current medication was measured on an ordinal scale as described below. Participants were rated according to the most appropriate statement:

  1. Doesn’t take medication.
  2. Takes medication only rarely (1-2/week).
  3. Misses over 50% doses.
  4. Misses doses every week.
  5. Rarely misses doses.
  6. Medication supervised and takes as prescribed.

Responses were dichotomised due to low numbers of ratings in certain categories. Participants who missed doses every week, or more frequently (0-3) were assigned as non-adherent. Those who reported rarely missed doses, or were medication supervised (4-5) were assigned as adherent.

QC of Genetic Data

Quality control of Genetic Data

Pre-imputation quality control (QC) was performed as follows; SNPs were excluded due to call rates < 0.95, MAF < 0.01, or a Hardy-Weinberg Equilibrium mid-p < 10-6. Individuals were excluded with genotyping coverage rates < 0.95 or potential errors in a PLINK “sex check” analysis (i.e., ambiguous genetic sex, or mismatch between self-reported and genetic sex).

The Michigan Imputation server1 and Minimac-4 were utilised for imputation, using the Haplotype Reference Consortium v1.1 as the reference panel. Pre-imputation statistical phasing was carried out in the Michigan built-in service using Eagle 2.42. Post imputation, SNPs were removed when they had a hard-call genotype probability threshold < 0.9, R2 < 0.9, MAF < 0.01, and genotyping rates < 0.95. Relatedness was assessed through the PC-Relate algorithm3 and a cutoff of π > 0.4 was used to remove related individuals4.

For pharmacogenomic allele calling we retained any monomorphic variants in the dataset and used a more relaxed imputation quality threshold (R2 < 0.7; Hard-call genotype probability < 0.8). This allowed us to retain a greater number of pharmacogenomic informative SNPs to increase the allele calling accuracy, while still being stringent enough to avoid imputation errors in common genetic variants5,6



Pharmacogenomic Activity Score Mapping

Pharmacogenomic Activity Score Mapping

PyPGx v0.20.07 predicts enzyme metabolism phenotypes in two ways, through activity scores or diplotype-phenotype mapping. Despite this, it does not explicitly report activity scores in its output. Where available, activity scores were mapped to pharmacogenomic alleles called using the allele table within the PyPGx package. This was feasible for CYP2D6 and CYP2C9. For the remaining enzymes, the mapping of pharmacogenomic alleles to activity scores was based on existing literature or inferred from PharmGKB Allele Functionality Reference Tables (see Supplementary Table 1).

For CYP1A2, PharmGKB does not yet provide an allele functionality table. Thus, activity score assignment was based on consensus values from the literature8,9. No guidance was available for *1K, therefore it was assigned the same activity score as *1C, also a decreased function allele. Where CYP1A2*1F/*1C was called on a single haplotype, we assigned an activity score of 1 based on past work10.

Enzyme Allele Function Activity Score Source
CYP1A2 1A Normal 1 Lesche et al., 2019
CYP1A2 1C Decreased 0.5 Saiz-Rodriguez et al., 2019
CYP1A2 1F Increased 1.5 Lesche et al., 2019
CYP1A2 1K Decreased 0.5 -
CYP2D6 1 Normal 1 pypgx
CYP2D6 2 Normal 1 pypgx
CYP2D6 4 Null 0 pypgx
CYP2D6 10 Decreased 0.25 pypgx
CYP2D6 17 Decreased 0.5 pypgx
CYP2D6 28 Uncertain N/A pypgx
CYP2D6 35 Normal 1 pypgx
CYP2D6 41 Decreased 0.5 pypgx
CYP2D6 59 Decreased 0.5 pypgx
CYP2D6 117 Uncertain N/A pypgx
CYP3A5 1 Normal 1 CPIC PharmGKB Reference Tables
CYP3A5 3 Null 0 CPIC PharmGKB Reference Tables
CYP2C19 1 Normal 1 Lesche et al., 2019
CYP2C19 2 Null 0 Lesche et al., 2019
CYP2C19 8 Null 0 CPIC PharmGKB Reference Tables
CYP2C19 15 Normal 1 CPIC PharmGKB Reference Tables
CYP2C19 17 Increased 1.5 Lesche et al., 2019
CYP2C9 1 Normal 1 pypgx
CYP2C9 2 Decreased 0.5 pypgx
CYP2C9 3 Null 0 pypgx
CYP2C9 9 Normal 1 pypgx
CYP2C9 11 Decreased 0.5 pypgx
CYP2C9 12 Decreased 0.5 pypgx


Supplementary Table 1. CYP pharmacogenomic star alleles called in the CardiffCOGS sample. Star allele function, and corresponding activity scores are listed, alongside sources for mapping of star alleles to activity scores.



Additional Analyses

Accounting for Phenoconversion

Phenoconversion describes the gap between genetically inferred enzymatic status and actual enzyme activity11. Many different factors can influence enzyme activity, and in particular CYP enzymes may be induced or inhibited by a host of variables including concomitant medication, lifestyle factors, diet, and inflammation12.

We observed associations between three pharmacogenomic activity scores and schizophrenia phenotype dimensions. Based on the Food and Drug Administration’s (FDA) table of CYP Enzyme- and Transporter System-Based Clinical Substrates, Inhibitors, or Inducers13, we identified three drugs within the CardiffCOGS sample that could influence the activity of these enzymes. These drugs include the CYP2C19 strong inhibitor fluoxetine (N = 34), the CYP3A5 strong inducer carbamazepine (N = 5), and the CYP1A2 moderate inducer cigarette smoking (N = rnrow(filter(test_df_dim, smoking == 1))`). We are however unable to account for other drugs and factors not reported in our study (e.g., oral contraceptives, dietary factors, disease, and inflammation) that may further influence enzyme activity11,12.

We accounted for phenoconversion using two methods, (i) statistically through an interaction term between the enzyme activity score and a binary variable representing use of the relevant drug, and (ii) traditionally by replacing standard activity scores with phenoconversion-corrected activity scores. Phenoconversion-corrected activity scores were calculated based on work by Lesche and colleagues9. Scores were multiplied by 1.5 in the presence of an inducer, and by 0 when a strong inhibitor was present. Models were fit only where a pharmacogenomic variable was associated with a phenotype dimension in our previous analyses, for example:

  1. positive ~ CYP2C19 activity score * fluoxetine use + …
  2. positive ~ CYP2C19 phenoconversion-corrected activity score + …

Medication variables and control covariates were included within the models as in our main analyses, and each model only included one pharmacogenomic variable.



Accounting for pre-morbid Intelligence with NART IQ

Associations between cognitive ability and medication variables could reflect a causal effect of medication use on cognition, or equally that people with lower cognitive ability are more likely to be prescribed higher doses or different medications to those with higher cognitive ability. Therefore, we aimed to control for a measure of premorbid intelligence in the regression models. For analysis, NART was converted to predicted WAIS-R full scale IQ via the recommended transformation IQ = 130.6-1.24*NART error score. We compared two measures that estimate premorbid intelligence (the NART and intelligence and education PRS) by investigating their association with current cognition and chlorpromazine-equivalent antipsychotic dose in the total sample:

  1. cognition ~ NART score + Age + Sex
  2. cognition ~ intelligence PGS + education attainment PGS + Age + Sex + PC1:5
  3. daily dose ~ NART score + Age + Sex
  4. daily dose ~ intelligence PGS + education attainment PGS + Age + Sex + PC1:5





Supplementary Notes - Results

Sample Information

Sample Ascertainment

Ascertainment of sample size
knitr::include_graphics("Writing/figs/SF1.png")
Supplementary Figure 1. Diagram showing participant exclusion based on several criteria and ascertainment of the final sample.

Supplementary Figure 1. Diagram showing participant exclusion based on several criteria and ascertainment of the final sample.



Model Variables

Model Variables in CardiffCOGS
df_total <- test_df_dim %>%
   filter(if_all(c(Study_ID, positive, express, mandp, sad, cog, cpz_eq, Adherence_coded, clozapine_current, antichol_present, SZ_PRScs, Age_at_Interview, Sex, PC1, PC2, PC3, PC4, PC5), complete.cases))

a <- df_total %>%
  tbl_summary(include = c(cpz_eq, clozapine_current, antichol_present,  Adherence_coded, Age_at_Interview, Sex, ap_poly, smoking, fluoxetine,carbamazepine), statistic = list(
      all_continuous() ~ "{mean} ({sd})",
      all_categorical() ~ "{n} ({p}%)"
    ), digits =  all_continuous() ~ 1, label = list(cpz_eq ~ "Chlorpromazine Equivalent Antipsychotic Dose", clozapine_current ~ "Clozapine Use", antichol_present ~ "Anticholinergic Use", Adherence_coded ~ "Adherent", Age_at_Interview ~ "Age", Sex ~ "Sex", ap_poly ~ "Antipsychotic Polypharmacy", smoking ~ "Cigarette Use", fluoxetine ~ "Fluoxetine Use", carbamazepine ~ "Carbamazepine Use")) %>% 
  modify_header(
    label = "Variable",
    stat_0 = "Mean (SD); n (%)") %>%
  modify_footnote(update = everything() ~ NA) 

#####
b <- as.data.frame(a)
b[3,1] <- "No"
b[4,1] <- "Yes"

b[6,1] <- "No"
b[7,1] <- "Yes"

b[9,1] <- "No"
b[10,1] <- "Yes"

b[13,1] <- "Male"
b[14,1] <- "Female"

b[16,1] <- "No"
b[17,1] <- "Yes"

b[19,1] <- "No"
b[20,1] <- "Yes"

b[23,1] <- "No"
b[24,1] <- "Yes"

b[26,1] <- "No"
b[27,1] <- "Yes"


row_head <- c("Variable", "n (%)")
age <- b[11,]

b <- b[-11,]
b <- insertRow2(b, age, 2)
b <- insertRow2(b, row_head, 3)


#####
kable(b, row.names = F, digits = T, caption = "Supplementary Table 2. Descriptive statistics for key variables in the analysed sample (N = 585). Mean (SD) is reported for continuous variables and n (%) is reported for categorical variables.", col.names = c("Variable", "Mean (SD)")) %>% 
  row_spec(0,bold=TRUE) %>% 
  row_spec(3,bold=TRUE) %>% 
  add_indent(
  c(5,6, 8,9, 11,12, 14,15, 17,18, 20,21,22, 24,25, 27,28),
  level_of_indent = 1,
  all_cols = FALSE,
  target_cols = 1
) %>%
  kable_styling(full_width = F)
Supplementary Table 2. Descriptive statistics for key variables in the analysed sample (N = 585). Mean (SD) is reported for continuous variables and n (%) is reported for categorical variables.
Variable Mean (SD)
Chlorpromazine Equivalent Antipsychotic Dose 587.6 (390.1)
Age 43.5 (11.7)
Variable n (%)
Clozapine Use
No 370 (63%)
Yes 215 (37%)
Anticholinergic Use
No 494 (84%)
Yes 91 (16%)
Adherent
No 31 (5.3%)
Yes 554 (95%)
Sex
Male 380 (65%)
Female 205 (35%)
Antipsychotic Polypharmacy
No 486 (83%)
Yes 99 (17%)
Cigarette Use
No 235 (44%)
Yes 305 (56%)
Unknown 45
Fluoxetine Use
No 551 (94%)
Yes 34 (5.8%)
Carbamazepine Use
No 580 (99%)
Yes 5 (0.9%)


Antipsychotic Use

Antipsychotic Use in CardiffCOGS
meds <- dplyr::select(pheno, c("Study_ID", "Antipsychotic", "AP_dose", "antidepressant", "AD_dose", "Mood_Stabiliser", "MS_dose", "Benzodiazepine", "Ben_dose", "Anticholinergic", "Anticholinergic_dose" , "other_medication", "Other_medication_dose", "Current_smoking"))

meds$Antipsychotic[!(meds$Antipsychotic %in% AP_codes)] <- NA
meds$antidepressant[!(meds$antidepressant %in% AP_codes)] <- NA
meds$Mood_Stabiliser[!(meds$Mood_Stabiliser%in% AP_codes)] <- NA
meds$Benzodiazepine[!(meds$Benzodiazepine %in% AP_codes)] <- NA
meds$Anticholinergic[!(meds$Anticholinergic %in% AP_codes)] <- NA
meds$other_medication[!(meds$other_medication %in% AP_codes)] <- NA

# remove doses for non-useful drugs
meds$AP_dose[is.na(meds$Antipsychotic)] <- NA
meds$AD_dose[is.na(meds$antidepressant)] <- NA
meds$MS_dose[is.na(meds$Mood_Stabiliser)] <- NA
meds$Ben_dose[is.na(meds$Benzodiazepine)] <- NA
meds$Anticholinergic_dose[is.na(meds$Anticholinergic)] <- NA
meds$Other_medication_dose[is.na(meds$other_medication)] <- NA

aps <- table(meds$Antipsychotic) %>% as.data.frame()
ads <- table(meds$antidepressant) %>% as.data.frame()
mss <- table(meds$Mood_Stabiliser) %>% as.data.frame()
bzs <- table(meds$Benzodiazepine) %>% as.data.frame()
acs <- table(meds$Anticholinergic) %>% as.data.frame()
ots <- table(meds$other_medication) %>% as.data.frame()

med_freq <- full_join(aps, ads, by = "Var1")
med_freq <- full_join(med_freq, mss, by = "Var1")
med_freq <- full_join(med_freq, bzs, by = "Var1")
med_freq <- full_join(med_freq, acs, by = "Var1")
med_freq <- full_join(med_freq, ots, by = "Var1")

cols <- colnames(med_freq)

med_freq$total <- rowSums(med_freq[, cols[-1]], na.rm = TRUE)

recode_vector <- c(
  "1" = "Amisulpride",
  "2" = "Aripiprazole",
  "3" = "Chlorpromazine",
  "4" = "Clozapine",
  "5" = "Flupenthixol",
  "6" = "Flupenthixol", 
  "7" = "Fluphenazine",
  "8" = "Fluphenazine",
  "9" = "Haloperidol",
  "10" = "Haloperidol",
  "12" = "Olanzapine",
  "15" = "Pimozide",
  "16" = "Pipotiazine",
  "20" = "Quetiapine",
  "21" = "Risperidone",
  "22" = "Risperidone",
  "24" = "Sulpiride",
  "26" = "Trifluoperazine",
  "28" = "Zuclopenthixol",
  "29" = "Zuclopenthixol",
  "87" = "Paliperidone"
)

med_freq <- as.data.frame(recode_selected_codes(df = med_freq, recode_vector = recode_vector, columns_to_recode = "Var1"))

med_df <- dplyr::select(med_freq, c("Var1", "total"))

alt_df <- setDT(med_df)[, .(value=sum(total)) , by = Var1]
alt_df <- alt_df[order(alt_df$Var1),]

alt_df$value[alt_df$value <5] <- "< 5"
alt_df <- alt_df[order(alt_df$Var1),]
colnames(alt_df) <- c("Antipsychotic", "N")

kable(alt_df, row.names = F, digits = T, caption = "Supplementary Table 3. Frequency of currently used antipsychotics in the CardiffCOGS sample .") %>% kable_styling(full_width = T)
Supplementary Table 3. Frequency of currently used antipsychotics in the CardiffCOGS sample .
Antipsychotic N
Amisulpride 50
Aripiprazole 74
Chlorpromazine 8
Clozapine 215
Flupenthixol 60
Fluphenazine 6
Haloperidol 15
Olanzapine 103
Paliperidone < 5
Pimozide < 5
Pipotiazine < 5
Quetiapine 52
Risperidone 81
Sulpiride 10
Trifluoperazine < 5
Zuclopenthixol 13
#med_df <- med_df %>%
#    mutate(Var1 = str_to_sentence(Var1))
#colnames(med_df) <- c("Antipsychotic", "N")

#med_df$Administration <- c("Oral", "Oral", "Oral", "Oral", "Oral", "Depot", "Oral", "Depot", "Oral", "Depot", "Oral", "Oral", "Depot", "Oral", "Oral", "Depot", "Oral", "Oral", "Oral","Depot", "Depot")

#med_df <- med_df %>% dplyr::select(c("Antipsychotic", "Administration", "N"))

#kable(med_df, row.names = F, digits = T, caption = "Supplementary Table 3. Frequency of currently used antipsychotics in the CardiffCOGS sample and their mode of administration.") %>% kable_styling(full_width = F)

rm(meds, aps, ads, mss, bzs, acs, ots, cols,  med_freq)



Star Allele Frequency

Star Allele Frequencies for CardiffCOGS
#### cyp1a2 ####
star_cyp1a2 <- left_join(test_df_dim, pypgx_1a2)

A_1a2 <- as.data.frame(table(star_cyp1a2$Haplotype1))
B_1a2 <- as.data.frame(table(star_cyp1a2$Haplotype2))

freq_1a2 <- full_join(A_1a2, B_1a2, by = "Var1")
freq_1a2$Total <- rowSums(freq_1a2[-1], na.rm = T)
freq_1a2$Frequency <- round(freq_1a2$Total/sum(freq_1a2$Total), 3)
freq_1a2$Gene <- "<i>CYP1A2</i>"

freq_1a2 <- freq_1a2 %>% dplyr::select("Gene", "Var1", "Total", "Frequency")
colnames(freq_1a2) <- c("Gene", "Star Allele", "Total", "Frequency")

#### cyp2d6 ####

star_cyp2d6 <- left_join(test_df_dim, pypgx_2d6)

A_2d6 <- as.data.frame(table(star_cyp2d6$Geno1))
B_2d6 <- as.data.frame(table(star_cyp2d6$Geno2))

freq_2d6 <- full_join(A_2d6, B_2d6, by = "Var1")
freq_2d6$Total <- rowSums(freq_2d6[-1], na.rm = T)
freq_2d6$Frequency <- round(freq_2d6$Total/sum(freq_2d6$Total), 3)
freq_2d6$Gene <- "<i>CYP2D6</i>"

freq_2d6 <- freq_2d6 %>% dplyr::select("Gene", "Var1", "Total", "Frequency")

colnames(freq_2d6) <- c("Gene", "Star Allele", "Total", "Frequency")

#### cyp2a5 ####

star_cyp3a5 <- left_join(test_df_dim, pypgx_3a5)

A_3a5 <- as.data.frame(table(star_cyp3a5$Geno1))
B_3a5 <- as.data.frame(table(star_cyp3a5$Geno2))

freq_3a5 <- full_join(A_3a5, B_3a5, by = "Var1")
freq_3a5$Total <- rowSums(freq_3a5[-1], na.rm = T)
freq_3a5$Frequency <- round(freq_3a5$Total/sum(freq_3a5$Total), 3)
freq_3a5$Gene <- "<i>CYP3A5</i>"

freq_3a5 <- freq_3a5 %>% dplyr::select("Gene", "Var1", "Total", "Frequency")
colnames(freq_3a5) <- c("Gene", "Star Allele", "Total", "Frequency")

#### cyp2c19 ####

star_cyp2c19 <- left_join(test_df_dim, pypgx_2c19)

A_2c19 <- as.data.frame(table(star_cyp2c19$Geno1))
B_2c19 <- as.data.frame(table(star_cyp2c19$Geno2))

freq_2c19 <- full_join(A_2c19, B_2c19, by = "Var1")
freq_2c19$Total <- rowSums(freq_2c19[-1], na.rm = T)
freq_2c19$Frequency <- round(freq_2c19$Total/sum(freq_2c19$Total), 3)
freq_2c19$Gene <- "<i>CYP2C19</i>"

freq_2c19 <- freq_2c19 %>% dplyr::select("Gene", "Var1", "Total", "Frequency")
colnames(freq_2c19) <- c("Gene", "Star Allele", "Total", "Frequency")

#### cyp2c9 ####

star_cyp2c9 <- left_join(test_df_dim, pypgx_2c9)

A_2c9 <- as.data.frame(table(star_cyp2c9$Geno1))
B_2c9 <- as.data.frame(table(star_cyp2c9$Geno2))

freq_2c9 <- full_join(A_2c9, B_2c9, by = "Var1")
freq_2c9$Total <- rowSums(freq_2c9[-1], na.rm = T)
freq_2c9$Frequency <- round(freq_2c9$Total/sum(freq_2c9$Total), 3)
freq_2c9$Gene <- "<i>CYP2C9</i>"

freq_2c9 <- freq_2c9 %>% dplyr::select("Gene", "Var1", "Total", "Frequency")
colnames(freq_2c9) <- c("Gene", "Star Allele", "Total", "Frequency")

all_freq <- rbind(freq_1a2, freq_2d6, freq_3a5, freq_2c19, freq_2c9)

all_freq %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 4. Total allele count, and allele frequency for CYP pharmacogenomic star alleles found in the CardiffCOGS sample.") %>%
  collapse_rows(columns = 1, valign = "top") %>%
  kable_classic(full_width = T)
Supplementary Table 4. Total allele count, and allele frequency for CYP pharmacogenomic star alleles found in the CardiffCOGS sample.
Gene Star Allele Total Frequency
CYP1A2 *1A 403 0.344
1C1F 16 0.014
*1F 748 0.639
*1K 3 0.003
CYP2D6 *1 556 0.475
*10 10 0.009
*2 181 0.155
*35 50 0.043
*4 246 0.210
*41 110 0.094
*117 2 0.002
*17 5 0.004
*28 5 0.004
*59 5 0.004
CYP3A5 *1 67 0.057
*3 1103 0.943
CYP2C19 *1 740 0.632
*15 1 0.001
*17 255 0.218
*2 172 0.147
*8 2 0.002
CYP2C9 *1 946 0.809
*2 135 0.115
*3 78 0.067
*11 8 0.007
*12 2 0.002
*9 1 0.001



CFA

CFA Measures and Preliminary Analysis

Associations with Global Assessment Scale

Four factor structures were fit to determine which best represented the data as described in Supplementary Table 4. Scores for all latent variables were significantly associated with current Global Assessment Scale ratings in models that controlled for age and sex. In all instances, increased symptom severity was associated with reduced scores on the Global Assessment Scale. This manifested as inverse associations between the positive (β = -0.54; 95%CI, -0.62 to -0.46; p = 6x10⁻³⁷), diminished expressivity (β = -0.416; 95%CI, -0.5 to -0.33; p = 2x10⁻²¹), reduced motivation and pleasure (β = -0.544; 95%CI, -0.62 to -0.47; p = 4x10⁻³⁹), and depression/suicide dimensions (β = -0.543; 95%CI, -0.62 to -0.47; p = 3x10⁻³⁷) with Global Assessment Scale scores. The cognition dimension was positively associated with GAS (β = 0.174; 95%CI, 0.09 to 0.26; p = 3x10⁻⁵), with higher ratings across the Global Assessment Scale and the cognition dimension both reflecting improved functioning.


a3 <- as.data.frame(core_fitmeasures(fits$four)) %>% rownames_to_column(var = "Fit Measure") 

loadings <- as.data.frame(standardizedSolution(fits$four))
loadings <- dplyr::filter(loadings, op == "=~")
loadings <- loadings %>% dplyr::select(c("lhs", "op", "rhs", "est.std", "se", "pvalue"))
loadings$pvalue <- format.pval(loadings$pvalue)
loadings$est.std <- round(loadings$est.std, 3)
loadings$se <- round(loadings$se, 3)


mod_5a <- dplyr::select(loadings, c("lhs", "rhs", "est.std"))
stat_5a <- a3 


tab <- full_join(base_6, mod_5a, by = c("lhs", "rhs"))
tab <- full_join(tab, mod_5b, by = c("lhs", "rhs"))
tab <- full_join(tab, mod_4, by = c("lhs", "rhs"))

results <- data.frame(
  Variable = character(),
  Mean = numeric(),
  SD = numeric(),
  Min = numeric(),
  Max = numeric(),
  stringsAsFactors = FALSE
)


sum_cols <- tab[[2]]

# Loop through the specified columns
for (column_name in sum_cols) {
  column <- pheno[[column_name]]
  stats <- summary_stats(column)
  new_row <- data.frame(
        Variable = column_name,
        Mean = stats$Mean,
        SD = stats$SD,
        Min = stats$Min,
        Max = stats$Max,
        stringsAsFactors = FALSE
      )
      # Append the new row to the results dataframe
      results <- rbind(results, new_row)
}

colnames(tab) <- c("Latent Factor", "Variable", "M1 (6)", "M2 (5)", "M3 (5b)", "M4 (4)")

df <- left_join(tab, results, by = "Variable")

df <- dplyr::select(df, c("Latent Factor", "Variable", "Mean", "SD", "Min", "Max", "M1 (6)", "M2 (5)", "M3 (5b)", "M4 (4)"))

gof <- left_join(stat_6, stat_5a)
gof <- left_join(gof, stat_5b)
gof <- left_join(gof, stat_4)

colnames(gof) <- c("Goodness of Fit Measure", "M1", "M2", "M3", "M4" )
gof <- gof[-c(1:4, 7:8),]
gof$`Goodness of Fit Measure` <- toupper(gof$`Goodness of Fit Measure`)

df %>% 
  kable(format = "html", escape = F) %>%
  kable_classic(full_width = T) %>%
   column_spec(2, bold = T, border_right = T) %>%
   column_spec(1, bold = T) 
Latent Factor Variable Mean SD Min Max M1 (6) M2 (5) M3 (5b) M4 (4)
positive SAPS_Global_Hals 1.338 1.852 0.00 5.00 0.769 0.874 0.681 0.858
positive SAPS_Global_Delusions 1.255 1.595 0.00 5.00 0.750 0.659 0.847 0.672
express SANS_Global_Affective_Flattening 1.383 1.435 0.00 5.00 0.872 0.880 0.859 0.867
express SANS_Global_Alogia 1.125 1.475 0.00 5.00 0.771 0.764 0.782 0.775
mandp SANS_Global_Avolition_Apathy 1.781 1.327 0.00 5.00 0.840 0.839 0.847 0.846
mandp SANS_Global_Anhedonia_Asociality 1.853 1.516 0.00 5.00 0.760 0.762 0.754 0.756
dis SAPS_Global_Positive_Thought_Disorder 0.583 1.106 0.00 5.00 0.492 0.493
dis SANS_Inappropriate_Affect 0.080 0.448 0.00 4.00 0.526 0.525
sad Calgary_Suicide 0.157 0.417 0.00 3.00 0.913 0.904
sad Calgary_Depression 0.533 0.747 0.00 3.00 0.808 0.817
cog ZNAB_Mazes_Imp -1.513 1.294 -3.99 1.17 0.653 0.654 0.652 0.653
cog ZHVLT_Imp -2.447 1.521 -6.38 1.59 0.743 0.742 0.744 0.742
cog ZBVMT_Imp -1.646 1.222 -3.92 1.52 0.707 0.708 0.708 0.709
cog ZCPT_Imp -1.438 1.228 -5.52 2.25 0.733 0.732 0.732 0.730
cog ZSoP_Imp -1.951 1.104 -5.45 1.32 0.834 0.835 0.835 0.836
cog ZWM_Imp -1.641 1.193 -4.59 1.56 0.831 0.831 0.832 0.832
gof %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 5. Summary of full CFA results. Descriptive statistics are listed alongside factor loadings for each variable onto its latent factors across the four considered models (M1 – M4). Key fit statistics are listed below, with the best fit highlighted in red. M1 represents the maximal model with all variables included. M2 represents the maximal model without the disorganised variables. M3 represents the maximal model without the suicide/depression variables (i.e., the 5-factor model as based on Legge et al., (2021)). M4 represents the maximal model with neither the suicide/depression nor disorganised factors. EXCL = excluded; CFI = Comparative Fit Index; RMSEA = Root Mean Square Error of Approximation; SRMR = Standardised Root Mean Square Residual.  *MATRICS variables were imputed and standardised against unaffected controls.", row.names = F, align=c("l", "r", "r", "r", "r"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) %>%
    column_spec(3, bold = T, color = "red")
Supplementary Table 5. Summary of full CFA results. Descriptive statistics are listed alongside factor loadings for each variable onto its latent factors across the four considered models (M1 – M4). Key fit statistics are listed below, with the best fit highlighted in red. M1 represents the maximal model with all variables included. M2 represents the maximal model without the disorganised variables. M3 represents the maximal model without the suicide/depression variables (i.e., the 5-factor model as based on Legge et al., (2021)). M4 represents the maximal model with neither the suicide/depression nor disorganised factors. EXCL = excluded; CFI = Comparative Fit Index; RMSEA = Root Mean Square Error of Approximation; SRMR = Standardised Root Mean Square Residual. *MATRICS variables were imputed and standardised against unaffected controls.
Goodness of Fit Measure M1 M2 M3 M4
CFI 0.996 0.997 0.996 0.995
RMSEA 0.020 0.019 0.024 0.028
SRMR 0.053 0.043 0.050 0.044



Full Results

Medication Model

Extended Results for Manuscript Table 1.
#### create table ####
t1 <- make_tab(pos)
t2 <- make_tab(exp)
t3 <- make_tab(map)
t4 <- make_tab(sad)
t5 <- make_tab(cog)

f1 <- get_fit(pos)
f2 <- get_fit(exp)
f3 <- get_fit(map)
f4 <- get_fit(sad)
f5 <- get_fit(cog)

main_res <- rbind(t1, t2, t3, t4, t5)
extra <- cbind(f1, f2[2], f3[2], f4[2], f5[2])

main_res_fdr <- mutate(group_by(main_res, Predictor), FDR=p.adjust(p,"fdr"))

main_res_fdr$p <- format_p(main_res_fdr$p)
main_res_fdr$FDR <- format_p(main_res_fdr$FDR)

main_res_fdr$`p (FDR)` <- paste0(main_res_fdr$p, " (", main_res_fdr$FDR, ")")
main_res_fdr <- dplyr::select(main_res_fdr, -c("p", "FDR"))

tmp <- split(main_res_fdr, f = main_res_fdr$Outcome)  

t1 <- as.data.frame(tmp$positive[-1]) 
t2 <- as.data.frame(tmp$express[-1])
t3 <- as.data.frame(tmp$mandp[-1])
t4 <- as.data.frame(tmp$sad[-1])
t5 <- as.data.frame(tmp$cog[-1])

main <- left_join(t1, t2, by = "Predictor")
main <- left_join(main, t3, by = "Predictor")
main <- left_join(main, t4, by = "Predictor")
main <- full_join(main, t5, by = "Predictor")


main <- main[c(1,2,3,4,5,13,14,6,7,8,9,10,11,12),]
main <- column_as_rownames(main, var = "Predictor")
rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)", "Adherent (Yes)", "Schizophrenia PGS", "Intelligence PGS", "Educational Attainment PGS", "Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5")

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)" )) %>% 
   add_header_above(header = c( " " = 1, "Positive" = 2, "Expressivity" = 2, "Motivation and Pleasure" = 2, "Suicide and Depression" = 2, "Cognition" = 2)) %>%
  kable_classic(full_width = T) 
Positive
Expressivity
Motivation and Pleasure
Suicide and Depression
Cognition
Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR)
CPZ-eq Antipsychotic Dose (mg/day) 0.145 (0.04) 8x10⁻⁴ (0.004) 0.043 (0.04) 0.307 (0.307) 0.056 (0.04) 0.195 (0.244) 0.099 (0.04) 0.021 (0.034) -0.12 (0.04) 0.001 (0.004)
Clozapine (Yes) -0.061 (0.09) 0.491 (0.613) 0.417 (0.09) 2x10⁻⁶ (6x10⁻⁶) 0.232 (0.09) 0.009 (0.015) -0.007 (0.09) 0.937 (0.937) -0.498 (0.08) 3x10⁻¹⁰ (1x10⁻⁹)
Anticholinergic (Yes) 0.081 (0.12) 0.493 (0.493) 0.222 (0.12) 0.055 (0.076) 0.272 (0.12) 0.021 (0.053) 0.221 (0.12) 0.06 (0.076) -0.345 (0.1) 8x10⁻⁴ (0.004)
Adherent (Yes) -0.498 (0.19) 0.008 (0.038) -0.235 (0.18) 0.201 (0.201) -0.364 (0.19) 0.051 (0.107) -0.345 (0.19) 0.064 (0.107) 0.26 (0.16) 0.11 (0.138)
Schizophrenia PGS -0.041 (0.04) 0.335 (0.558) 0.029 (0.04) 0.495 (0.618) -0.006 (0.04) 0.879 (0.879) -0.063 (0.04) 0.138 (0.345) -0.1 (0.04) 0.009 (0.043)
Intelligence PGS 0.075 (0.04) 0.091 (0.091)
Educational Attainment PGS 0.13 (0.04) 0.003 (0.003)
Age -0.048 (0.04) 0.261 (0.435) 0.061 (0.04) 0.147 (0.367) 0.036 (0.04) 0.395 (0.493) 0.001 (0.04) 0.985 (0.985) -0.376 (0.04) 2x10⁻²² (1x10⁻²¹)
Sex (Female) 0.052 (0.09) 0.547 (0.684) -0.176 (0.09) 0.04 (0.146) -0.104 (0.09) 0.232 (0.386) 0.165 (0.09) 0.058 (0.146) 0.021 (0.08) 0.783 (0.783)
PC1 -0.026 (0.04) 0.534 (0.668) 0.009 (0.04) 0.835 (0.835) -0.028 (0.04) 0.501 (0.668) -0.065 (0.04) 0.126 (0.631) 0.029 (0.04) 0.429 (0.668)
PC2 -0.034 (0.04) 0.411 (0.594) 0.026 (0.04) 0.52 (0.594) 0.022 (0.04) 0.594 (0.594) -0.054 (0.04) 0.192 (0.481) -0.047 (0.04) 0.191 (0.481)
PC3 -0.062 (0.04) 0.132 (0.658) 0.008 (0.04) 0.835 (0.97) 0.008 (0.04) 0.85 (0.97) 0.002 (0.04) 0.97 (0.97) -0.018 (0.04) 0.617 (0.97)
PC4 0.003 (0.04) 0.942 (0.942) -0.031 (0.04) 0.455 (0.892) -0.015 (0.04) 0.713 (0.892) -0.021 (0.04) 0.616 (0.892) 0.041 (0.04) 0.264 (0.892)
PC5 -0.032 (0.04) 0.441 (0.551) 0.064 (0.04) 0.115 (0.315) 0.063 (0.04) 0.126 (0.315) 0.034 (0.04) 0.402 (0.551) 0.021 (0.04) 0.562 (0.562)
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 6. Associations between medication variables with schizophrenia symptom severity and cognitive ability dimensions in CardiffCOGS, showing extended results from Table 1 in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 6. Associations between medication variables with schizophrenia symptom severity and cognitive ability dimensions in CardiffCOGS, showing extended results from Table 1 in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.
R2 0.045 0.068 0.042 0.041 0.274
adjusted R2 0.025 0.049 0.022 0.021 0.256
N 585.000 585.000 585.000 585.000 585.000



Pharmacogenomic Model

Extended Results for Manuscript Table 2.
#### create table ####
t1 <- make_tab(pos_pgx)
t2 <- make_tab(exp_pgx)
t3 <- make_tab(map_pgx)
t4 <- make_tab(sad_pgx)
t5 <- make_tab(cog_pgx)

f1 <- get_fit(pos_pgx)
f2 <- get_fit(exp_pgx)
f3 <- get_fit(map_pgx)
f4 <- get_fit(sad_pgx)
f5 <- get_fit(cog_pgx)

main_res <- rbind(t1, t2, t3, t4, t5)
extra <- cbind(f1, f2[2], f3[2], f4[2], f5[2])

main_res_fdr <- mutate(group_by(main_res, Predictor), FDR=p.adjust(p,"fdr"))

main_res_fdr$p <- format_p(main_res_fdr$p)
main_res_fdr$FDR <- format_p(main_res_fdr$FDR)

main_res_fdr$`p (FDR)` <- paste0(main_res_fdr$p, " (", main_res_fdr$FDR, ")")
main_res_fdr <- dplyr::select(main_res_fdr, -c("p", "FDR"))

tmp <- split(main_res_fdr, f = main_res_fdr$Outcome)  

t1 <- as.data.frame(tmp$positive[-1]) 
t2 <- as.data.frame(tmp$express[-1])
t3 <- as.data.frame(tmp$mandp[-1])
t4 <- as.data.frame(tmp$sad[-1])
t5 <- as.data.frame(tmp$cog[-1])

main <- left_join(t1, t2, by = "Predictor")
main <- left_join(main, t3, by = "Predictor")
main <- left_join(main, t4, by = "Predictor")
main <- full_join(main, t5, by = "Predictor")

main <- column_as_rownames(main, var = "Predictor")

main <- main[c(1,2,3,4,5,6,7,8,9,10,18,19,11,12,13,14,15,16, 17),] 

rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)", "CYP1A2 Activity Score", "CYP2D6 Activity Score", "CYP3A5 Activity Score", "CYP2C19 Activity Score", "CYP2C9 Activity Score", "Adherent (Yes)", "Schizophrenia PGS", "Intelligence PGS", "Educational Attainment PGS", "Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5")

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)" )) %>% 
   add_header_above(header = c( " " = 1, "Positive" = 2, "Diminished Expressivity" = 2, "Motivation and Pleasure" = 2, "Suicide and Depression" = 2, "Cognition" = 2)) %>%
  kable_classic(full_width = T) 
Positive
Diminished Expressivity
Motivation and Pleasure
Suicide and Depression
Cognition
Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR)
CPZ-eq Antipsychotic Dose (mg/day) 0.146 (0.04) 7x10⁻⁴ (0.003) 0.035 (0.04) 0.405 (0.405) 0.045 (0.04) 0.296 (0.37) 0.098 (0.04) 0.023 (0.039) -0.115 (0.04) 0.003 (0.006)
Clozapine (Yes) -0.044 (0.09) 0.623 (0.778) 0.414 (0.09) 3x10⁻⁶ (8x10⁻⁶) 0.236 (0.09) 0.008 (0.014) 0.004 (0.09) 0.961 (0.961) -0.499 (0.08) 4x10⁻¹⁰ (2x10⁻⁹)
Anticholinergic (Yes) 0.059 (0.12) 0.618 (0.618) 0.209 (0.12) 0.073 (0.104) 0.266 (0.12) 0.025 (0.062) 0.205 (0.12) 0.083 (0.104) -0.329 (0.1) 0.002 (0.008)
CYP1A2 Activity Score -0.051 (0.04) 0.227 (0.365) -0.066 (0.04) 0.116 (0.289) -0.039 (0.04) 0.365 (0.365) -0.042 (0.04) 0.321 (0.365) 0.07 (0.04) 0.06 (0.289)
CYP2D6 Activity Score -0.022 (0.04) 0.595 (0.744) 0.047 (0.04) 0.25 (0.67) 0.046 (0.04) 0.268 (0.67) -0.008 (0.04) 0.847 (0.847) -0.02 (0.04) 0.587 (0.744)
CYP3A5 Activity Score -0.042 (0.04) 0.319 (0.333) -0.113 (0.04) 0.007 (0.031) -0.106 (0.04) 0.012 (0.031) -0.041 (0.04) 0.333 (0.333) 0.037 (0.04) 0.321 (0.333)
CYP2C19 Activity Score -0.108 (0.04) 0.009 (0.047) -0.003 (0.04) 0.936 (0.936) -0.04 (0.04) 0.339 (0.565) -0.079 (0.04) 0.057 (0.143) 0.008 (0.04) 0.817 (0.936)
CYP2C9 Activity Score -0.049 (0.04) 0.237 (0.54) -0.012 (0.04) 0.764 (0.919) 0.004 (0.04) 0.919 (0.919) -0.041 (0.04) 0.324 (0.54) -0.048 (0.04) 0.188 (0.54)
Adherent (Yes) -0.418 (0.19) 0.026 (0.122) -0.257 (0.19) 0.167 (0.167) -0.371 (0.19) 0.051 (0.122) -0.34 (0.19) 0.073 (0.122) 0.257 (0.17) 0.121 (0.152)
Schizophrenia PGS -0.044 (0.04) 0.3 (0.501) 0.021 (0.04) 0.615 (0.73) -0.015 (0.04) 0.73 (0.73) -0.063 (0.04) 0.144 (0.36) -0.092 (0.04) 0.017 (0.083)
Intelligence PGS 0.084 (0.04) 0.06 (0.06)
Educational Attainment PGS 0.123 (0.04) 0.006 (0.006)
Age -0.052 (0.04) 0.218 (0.363) 0.059 (0.04) 0.162 (0.363) 0.033 (0.04) 0.444 (0.555) -0.005 (0.04) 0.91 (0.91) -0.375 (0.04) 9x10⁻²² (4x10⁻²¹)
Sex (Female) 0.053 (0.09) 0.541 (0.676) -0.197 (0.09) 0.023 (0.115) -0.126 (0.09) 0.151 (0.252) 0.147 (0.09) 0.094 (0.236) 0.03 (0.08) 0.698 (0.698)
PC1 -0.019 (0.04) 0.651 (0.724) 0.02 (0.04) 0.628 (0.724) -0.015 (0.04) 0.724 (0.724) -0.057 (0.04) 0.18 (0.724) 0.029 (0.04) 0.433 (0.724)
PC2 -0.032 (0.04) 0.442 (0.665) 0.022 (0.04) 0.595 (0.665) 0.018 (0.04) 0.665 (0.665) -0.052 (0.04) 0.209 (0.539) -0.045 (0.04) 0.216 (0.539)
PC3 -0.048 (0.04) 0.248 (0.728) 0.022 (0.04) 0.589 (0.728) 0.023 (0.04) 0.578 (0.728) 0.014 (0.04) 0.728 (0.728) -0.018 (0.04) 0.615 (0.728)
PC4 0.007 (0.04) 0.866 (0.961) -0.016 (0.04) 0.703 (0.961) -0.002 (0.04) 0.961 (0.961) -0.018 (0.04) 0.676 (0.961) 0.036 (0.04) 0.33 (0.961)
PC5 -0.03 (0.04) 0.466 (0.582) 0.076 (0.04) 0.064 (0.24) 0.069 (0.04) 0.096 (0.24) 0.036 (0.04) 0.388 (0.582) 0.012 (0.04) 0.751 (0.751)
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 7. Associations between medication and pharmacogenomic variables with schizophrenia symptom severity and cognitive ability dimensions in CardiffCOGS, showing extended results from Table 2 in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 7. Associations between medication and pharmacogenomic variables with schizophrenia symptom severity and cognitive ability dimensions in CardiffCOGS, showing extended results from Table 2 in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.
R2 0.060 0.084 0.056 0.051 0.280
adjusted R2 0.032 0.056 0.027 0.022 0.256
N 578.000 578.000 578.000 578.000 578.000



Pharmacogenomic Model (Clozapine Subgroup)

Extended Results for Manuscript Table 3.
#### create table ####
t1 <- make_tab(cpos_pgx)
t2 <- make_tab(cexp_pgx)
t3 <- make_tab(cmap_pgx)
t4 <- make_tab(csad_pgx)
t5 <- make_tab(ccog_pgx)

f1 <- get_fit(cpos_pgx)
f2 <- get_fit(cexp_pgx)
f3 <- get_fit(cmap_pgx)
f4 <- get_fit(csad_pgx)
f5 <- get_fit(ccog_pgx)

main_res <- rbind(t1, t2, t3, t4, t5)
extra <- cbind(f1, f2[2], f3[2], f4[2], f5[2])

main_res_fdr <- mutate(group_by(main_res, Predictor), FDR=p.adjust(p,"fdr"))

main_res_fdr$p <- format_p(main_res_fdr$p)
main_res_fdr$FDR <- format_p(main_res_fdr$FDR)

main_res_fdr$`p (FDR)` <- paste0(main_res_fdr$p, " (", main_res_fdr$FDR, ")")
main_res_fdr <- dplyr::select(main_res_fdr, -c("p", "FDR"))

tmp <- split(main_res_fdr, f = main_res_fdr$Outcome)  

t1 <- as.data.frame(tmp$positive[-1]) 
t2 <- as.data.frame(tmp$express[-1])
t3 <- as.data.frame(tmp$mandp[-1])
t4 <- as.data.frame(tmp$sad[-1])
t5 <- as.data.frame(tmp$cog[-1])

main <- left_join(t1, t2, by = "Predictor")
main <- left_join(main, t3, by = "Predictor")
main <- left_join(main, t4, by = "Predictor")
main <- full_join(main, t5, by = "Predictor")

main <- column_as_rownames(main, var = "Predictor")

main <- main[c(1,2,3,4,5,6,7,8,9,17,18, 10,11,12,13,14,15,16),] 

rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Anticholinergic (Yes)", "CYP1A2 Activity Score", "CYP2D6 Activity Score", "CYP3A5 Activity Score", "CYP2C19 Activity Score", "CYP2C9 Activity Score", "Adherent (Yes)", "Schizophrenia PGS", "Intelligence PGS", "Educational Attainment PGS","Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5")

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)", "Estimate (SE)", "p (FDR)" )) %>% 
   add_header_above(header = c( " " = 1, "Positive (Clozapine Subgroup)" = 2, "Diminished Expressivity (Clozapine Subgroup)" = 2, "Motivation and Pleasure (Clozapine Subgroup)" = 2, "Suicide and Depression (Clozapine Subgroup)" = 2, "Cognition (Clozapine Subgroup)" = 2)) %>%
  kable_classic(full_width = T) 
Positive (Clozapine Subgroup)
Diminished Expressivity (Clozapine Subgroup)
Motivation and Pleasure (Clozapine Subgroup)
Suicide and Depression (Clozapine Subgroup)
Cognition (Clozapine Subgroup)
Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR) Estimate (SE) p (FDR)
CPZ-eq Antipsychotic Dose (mg/day) 0.02 (0.07) 0.786 (0.786) 0.077 (0.07) 0.273 (0.683) 0.03 (0.07) 0.673 (0.786) 0.05 (0.07) 0.471 (0.785) -0.147 (0.06) 0.02 (0.1)
Anticholinergic (Yes) -0.076 (0.2) 0.704 (0.88) 0.023 (0.19) 0.907 (0.907) 0.137 (0.2) 0.486 (0.81) 0.189 (0.19) 0.327 (0.81) -0.274 (0.17) 0.109 (0.547)
CYP1A2 Activity Score -0.083 (0.07) 0.242 (0.404) -0.108 (0.07) 0.117 (0.293) -0.041 (0.07) 0.556 (0.556) -0.059 (0.07) 0.387 (0.484) 0.17 (0.06) 0.005 (0.026)
CYP2D6 Activity Score -0.028 (0.07) 0.695 (0.836) 0.071 (0.07) 0.315 (0.836) 0.064 (0.07) 0.369 (0.836) -0.039 (0.07) 0.574 (0.836) -0.013 (0.06) 0.836 (0.836)
CYP3A5 Activity Score -0.082 (0.07) 0.251 (0.251) -0.12 (0.07) 0.085 (0.198) -0.103 (0.07) 0.147 (0.198) -0.126 (0.07) 0.07 (0.198) 0.087 (0.06) 0.158 (0.198)
CYP2C19 Activity Score -0.05 (0.07) 0.481 (0.843) 0.014 (0.07) 0.843 (0.843) 0.014 (0.07) 0.84 (0.843) 0.052 (0.07) 0.444 (0.843) 0.023 (0.06) 0.699 (0.843)
CYP2C9 Activity Score -0.041 (0.07) 0.564 (0.62) -0.164 (0.07) 0.019 (0.095) -0.121 (0.07) 0.086 (0.215) -0.098 (0.07) 0.155 (0.258) 0.03 (0.06) 0.62 (0.62)
Adherent (Yes) -0.168 (0.52) 0.749 (0.749) -0.306 (0.51) 0.549 (0.749) -0.411 (0.52) 0.429 (0.749) -0.36 (0.51) 0.479 (0.749) 0.226 (0.45) 0.615 (0.749)
Schizophrenia PGS -0.021 (0.07) 0.772 (0.772) 0.022 (0.07) 0.748 (0.772) -0.034 (0.07) 0.632 (0.772) -0.135 (0.07) 0.053 (0.229) -0.108 (0.06) 0.092 (0.229)
Intelligence PGS 0.14 (0.08) 0.076 (0.076)
Educational Attainment PGS 0.083 (0.08) 0.279 (0.279)
Age -0.135 (0.07) 0.06 (0.15) 0.057 (0.07) 0.41 (0.683) 0.017 (0.07) 0.813 (0.992) 0.001 (0.07) 0.992 (0.992) -0.398 (0.06) 6x10⁻¹⁰ (3x10⁻⁹)
Sex (Female) 0.236 (0.15) 0.112 (0.279) -0.192 (0.14) 0.182 (0.304) -0.067 (0.15) 0.649 (0.812) 0.245 (0.14) 0.089 (0.279) 0.008 (0.13) 0.948 (0.948)
PC1 -0.036 (0.08) 0.631 (0.631) -0.11 (0.07) 0.131 (0.164) -0.114 (0.07) 0.127 (0.164) -0.165 (0.07) 0.024 (0.121) 0.102 (0.06) 0.111 (0.164)
PC2 -0.087 (0.15) 0.566 (0.566) -0.197 (0.15) 0.181 (0.302) -0.232 (0.15) 0.123 (0.302) -0.316 (0.15) 0.032 (0.16) 0.132 (0.13) 0.305 (0.381)
PC3 0.018 (0.29) 0.951 (0.951) 0.377 (0.28) 0.181 (0.302) 0.331 (0.29) 0.247 (0.309) 0.46 (0.28) 0.102 (0.254) -0.41 (0.25) 0.097 (0.254)
PC4 -0.024 (0.28) 0.932 (0.932) -0.448 (0.27) 0.1 (0.126) -0.469 (0.28) 0.091 (0.126) -0.467 (0.27) 0.086 (0.126) 0.396 (0.24) 0.097 (0.126)
PC5 0.053 (0.1) 0.61 (0.763) -0.136 (0.1) 0.178 (0.444) -0.216 (0.1) 0.036 (0.182) 0.052 (0.1) 0.601 (0.763) 0.019 (0.09) 0.833 (0.833)
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 8. Associations between medication and pharmacogenomic variables with schizophrenia symptom severity and cognitive ability dimensions in CardiffCOGS participants currently prescribed clozapine, showing extended results from Table 3 in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 8. Associations between medication and pharmacogenomic variables with schizophrenia symptom severity and cognitive ability dimensions in CardiffCOGS participants currently prescribed clozapine, showing extended results from Table 3 in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.
R2 0.063 0.114 0.082 0.122 0.335
adjusted R2 -0.013 0.043 0.008 0.051 0.274
N 215.000 215.000 215.000 215.000 215.000



Unadjusted PGx Estimates

Unadjusted estimates for pharmacogenomic variables in total sample.

heat_dat <- dplyr::select(test_df_dim_std, c("positive", "express", "mandp", "sad", "cog", "CYP1A2_AS", "CYP2D6_AS", "CYP3A5_AS", "CYP2C19_AS", "CYP2C9_AS")) %>%
   filter_all(complete.cases)

colnames(heat_dat) <- c("Positive", "Expressivity", "Motivation & Pleasure", "Suicide & Depression", "Cognition", "CYP1A2 AS", "CYP2D6 AS", "CYP3A5 AS", "CYP2C19 AS", "CYP2C9 AS")

dims <-  c("Positive", "Expressivity", "Motivation & Pleasure", "Suicide & Depression", "Cognition")
vars <- c("CYP1A2 AS", "CYP2D6 AS", "CYP3A5 AS", "CYP2C19 AS", "CYP2C9 AS")

out <- data.frame(Dimension = NA,
                  Enzyme = NA,
                  Corr = NA,
                  p = NA)
test <- out

for (i in dims) {
  for (j in vars){
    x <- heat_dat[i]
    y <- heat_dat[j]
    stat <- corr.test(x, y, method = "pearson")
    test$Dimension <- i
    test$Enzyme <- j
    test$Corr <- stat$r
    test$p <- stat$p
    out <- rbind(out, test)
  }
}

out <- na.omit(out)

out$Enzyme[out$Enzyme == "CYP1A2 AS"] <- "CYP1A2 Activity Score"
out$Enzyme[out$Enzyme == "CYP2D6 AS"] <- "CYP2D6 Activity Score"
out$Enzyme[out$Enzyme == "CYP3A5 AS"] <- "CYP3A5 Activity Score"
out$Enzyme[out$Enzyme == "CYP2C19 AS"] <- "CYP2C19 Activity Score"
out$Enzyme[out$Enzyme == "CYP2C9 AS"] <- "CYP2C9 Activity Score"

mat <- out[c(1:4)]

mat_wide <- pivot_wider(mat, names_from = "Dimension", values_from = c("Corr", "p")) %>% remove_rownames() %>% column_to_rownames(var = "Enzyme")

mat_wide <- mat_wide %>% dplyr::select(c("Corr_Positive", "p_Positive", "Corr_Expressivity", "p_Expressivity", "Corr_Motivation & Pleasure", "p_Motivation & Pleasure", "Corr_Suicide & Depression", "p_Suicide & Depression", "Corr_Cognition", "p_Cognition"))

mat_wide %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 9. Unadjusted estimates for pharmacogenomic variables against schizophrenia phenotype dimensions. Table shows Pearson’s correlation coefficient and p value for each dimension-enzyme pairing.", col.names = c("r", "p", "r", "p", "r", "p", "r", "p", "r", "p")) %>% 
   add_header_above(header = c( " " = 1, "Positive" = 2, "Expressivity" = 2, "Motivation and Pleasure" = 2, "Suicide and Depression" = 2, "Cognition" = 2)) %>%
  kable_classic(full_width = T) 
Supplementary Table 9. Unadjusted estimates for pharmacogenomic variables against schizophrenia phenotype dimensions. Table shows Pearson’s correlation coefficient and p value for each dimension-enzyme pairing.
Positive
Expressivity
Motivation and Pleasure
Suicide and Depression
Cognition
r p r p r p r p r p
CYP1A2 Activity Score -0.052 0.209 -0.050 0.231 -0.026 0.525 -0.044 0.290 0.092 0.026
CYP2D6 Activity Score 0.004 0.919 0.048 0.245 0.048 0.248 0.014 0.744 -0.063 0.128
CYP3A5 Activity Score -0.046 0.265 -0.098 0.018 -0.095 0.022 -0.040 0.333 0.025 0.548
CYP2C19 Activity Score -0.114 0.006 -0.003 0.937 -0.045 0.281 -0.085 0.041 0.017 0.687
CYP2C9 Activity Score -0.050 0.233 -0.029 0.486 -0.009 0.821 -0.046 0.268 -0.026 0.533



Unadjusted estimates for pharmacogenomic variables in the subgroup of participants prescribed clozapine.

heat_dat <- dplyr::select(test_df_dim_std_c, c("positive", "express", "mandp", "sad", "cog", "CYP1A2_AS", "CYP2D6_AS", "CYP3A5_AS", "CYP2C19_AS", "CYP2C9_AS")) %>%
   filter_all(complete.cases)

colnames(heat_dat) <- c("Positive", "Expressivity", "Motivation & Pleasure", "Suicide & Depression", "Cognition", "CYP1A2 AS", "CYP2D6 AS", "CYP3A5 AS", "CYP2C19 AS", "CYP2C9 AS")

dims <-  c("Positive", "Expressivity", "Motivation & Pleasure", "Suicide & Depression", "Cognition")
vars <- c("CYP1A2 AS", "CYP2D6 AS", "CYP3A5 AS", "CYP2C19 AS", "CYP2C9 AS")

out <- data.frame(Dimension = NA,
                  Enzyme = NA,
                  Corr = NA,
                  p = NA)
test <- out

for (i in dims) {
  for (j in vars){
    x <- heat_dat[i]
    y <- heat_dat[j]
    stat <- corr.test(x, y, method = "pearson")
    test$Dimension <- i
    test$Enzyme <- j
    test$Corr <- stat$r
    test$p <- stat$p
    out <- rbind(out, test)
  }
}

out <- na.omit(out)

out$Enzyme[out$Enzyme == "CYP1A2 AS"] <- "CYP1A2 Activity Score"
out$Enzyme[out$Enzyme == "CYP2D6 AS"] <- "CYP2D6 Activity Score"
out$Enzyme[out$Enzyme == "CYP3A5 AS"] <- "CYP3A5 Activity Score"
out$Enzyme[out$Enzyme == "CYP2C19 AS"] <- "CYP2C19 Activity Score"
out$Enzyme[out$Enzyme == "CYP2C9 AS"] <- "CYP2C9 Activity Score"


mat <- out[c(1:4)]

mat_wide <- pivot_wider(mat, names_from = "Dimension", values_from = c("Corr", "p")) %>% remove_rownames() %>% column_to_rownames(var = "Enzyme")

mat_wide <- mat_wide %>% dplyr::select(c("Corr_Positive", "p_Positive", "Corr_Expressivity", "p_Expressivity", "Corr_Motivation & Pleasure", "p_Motivation & Pleasure", "Corr_Suicide & Depression", "p_Suicide & Depression", "Corr_Cognition", "p_Cognition"))

mat_wide %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 10. Unadjusted estimates for pharmacogenomic variables against Schizophrenia Phenotype Dimensions. Table shows Pearson’s correlation coefficient and p value for each dimension-enzyme pairing dimensions in CardiffCOGS participants currently prescribed clozapine.", col.names = c("r", "p", "r", "p", "r", "p", "r", "p", "r", "p")) %>% 
   add_header_above(header = c( " " = 1, "Positive" = 2, "Expressivity" = 2, "Motivation and Pleasure" = 2, "Suicide and Depression" = 2, "Cognition" = 2)) %>%
  kable_classic(full_width = T) 
Supplementary Table 10. Unadjusted estimates for pharmacogenomic variables against Schizophrenia Phenotype Dimensions. Table shows Pearson’s correlation coefficient and p value for each dimension-enzyme pairing dimensions in CardiffCOGS participants currently prescribed clozapine.
Positive
Expressivity
Motivation and Pleasure
Suicide and Depression
Cognition
r p r p r p r p r p
CYP1A2 Activity Score -0.055 0.422 -0.102 0.137 -0.035 0.613 -0.040 0.561 0.205 0.002
CYP2D6 Activity Score -0.014 0.844 0.114 0.094 0.102 0.135 0.025 0.711 -0.110 0.107
CYP3A5 Activity Score -0.084 0.221 -0.113 0.100 -0.105 0.125 -0.123 0.072 0.068 0.319
CYP2C19 Activity Score -0.066 0.337 0.017 0.806 0.009 0.890 0.038 0.575 -0.026 0.705
CYP2C9 Activity Score -0.044 0.517 -0.186 0.006 -0.142 0.037 -0.138 0.043 0.089 0.195



Sensitivity Analysis: Phenoconversion

Accounting for Phenoconversion

CYP2C19
CYP2C19 and Fluoxetine

There was no evidence of a significant interaction between the CYP2C19 activity score and fluoxetine use (β = -0.123; 95%CI, -0.41 to 0.17; p = 0.41). However, CYP2C19 activity remained significantly associated with the positive symptom dimension (β = -0.09; 95%CI, -0.17 to -0.01; p = 0.037), and fluoxetine use was also inversely associated with positive dimension scores (β = -0.363; 95%CI, -0.71 to -0.02; p = 0.04). A phenoconversion-corrected CYP2C19 activity score was not associated with the positive symptom dimension (β = -0.022; 95%CI, -0.1 to 0.06; p = 0.6). Full results are available in Supplementary Table 11.

t1 <- make_tab(pos_pgx_pc)
f1 <- get_fit(pos_pgx_pc)
t1$p <- format_p(t1$p)

t1 <- t1[-1]

t2 <- make_tab(pos_pgx_pcas)
f2 <- get_fit(pos_pgx_pcas)
t2$p <- format_p(t2$p)

t2 <- t2[-1]
extra <- cbind(f1, f2[2])

main <- full_join(t1, t2, by = "Predictor")
main <- column_as_rownames(main, var = "Predictor")

rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)","CYP2C19 Activity Score", "Fluoxetine (Yes)", "Adherent (Yes)", "Schizophrenia PGS", "Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5", "CYP2C19-Fluoxetine interaction", "Phenoconversion-Corrected CYP2C19 Activity Score")

main <- main[c(1,2,3,4,5,15,16,6:14),]

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p", "Estimate (SE)", "p")) %>%
  add_header_above(header = c( " " = 1, "Positive - Fluoxetine Interaction" = 2, "Positive - Corrected Scores" = 2)) %>%
  kable_classic(full_width = T) 
Positive - Fluoxetine Interaction
Positive - Corrected Scores
Estimate (SE) p Estimate (SE) p
CPZ-eq Antipsychotic Dose (mg/day) 0.135 (0.04) 0.002 0.145 (0.04) 7x10⁻⁴
Clozapine (Yes) -0.056 (0.09) 0.522 -0.058 (0.09) 0.515
Anticholinergic (Yes) 0.081 (0.12) 0.487 0.077 (0.12) 0.513
CYP2C19 Activity Score -0.09 (0.04) 0.037
Fluoxetine (Yes) -0.363 (0.18) 0.04
CYP2C19-Fluoxetine interaction -0.123 (0.15) 0.408
Phenoconversion-Corrected CYP2C19 Activity Score -0.022 (0.04) 0.6
Adherent (Yes) -0.517 (0.19) 0.005 -0.491 (0.19) 0.009
Schizophrenia PGS -0.045 (0.04) 0.289 -0.042 (0.04) 0.321
Age -0.056 (0.04) 0.186 -0.048 (0.04) 0.262
Sex (Female) 0.07 (0.09) 0.419 0.05 (0.09) 0.566
PC1 -0.027 (0.04) 0.525 -0.025 (0.04) 0.549
PC2 -0.019 (0.04) 0.643 -0.036 (0.04) 0.392
PC3 -0.053 (0.04) 0.196 -0.061 (0.04) 0.139
PC4 0.003 (0.04) 0.95 0.003 (0.04) 0.949
PC5 -0.034 (0.04) 0.401 -0.033 (0.04) 0.428
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 11. Sensitivity analyses to account for the potential of fluoxetine to inhibit CYP2C19 activity. This is accounted for through a control (fluoxetine yes/no) covariate, or by inclusion of a phenoconversion activity score (activity score * 0 if participant reports fluoxetine). Sensitivity analyses were performed only in the positive dimension where an association with CYP2C19 was previously observed. ", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 11. Sensitivity analyses to account for the potential of fluoxetine to inhibit CYP2C19 activity. This is accounted for through a control (fluoxetine yes/no) covariate, or by inclusion of a phenoconversion activity score (activity score * 0 if participant reports fluoxetine). Sensitivity analyses were performed only in the positive dimension where an association with CYP2C19 was previously observed.
R2 0.062 0.045
adjusted R2 0.037 0.024
N 585.000 585.000



CYP3A5
CYP3A5 and Carbamazepine

The number of individuals taking carbamazepine was very low (N = 5); therefore, we were unable to model an interaction between CYP3A5 with Carbamazepine use. Equally, we did not calculate phenoconversion-corrected activity scores as all carbamazepine users had null function alleles – thus, their activity scores would have been unchanged (i.e., 0 x 1.5 = 0). The associations between CYP3A5 activity remained with both the diminished expressivity (β = -0.106; 95%CI, -0.19 to -0.02; p = 0.01) and reduced motivation and pleasure dimensions (β = -0.1; 95%CI, -0.18 to -0.02; p = 0.018) after accounting for carbamazepine use through a covariate, which was itself not associated with either symptom dimension. Full results are available in Supplementary Table 12.

t1 <- make_tab(exp_pgx_pc)
f1 <- get_fit(exp_pgx_pc)
t1$p <- format_p(t1$p)

t1 <- t1[-1]

t2 <- make_tab(map_pgx_pc)
f2 <- get_fit(map_pgx_pc)
t2$p <- format_p(t2$p)

t2 <- t2[-1]

#t3 <- make_tab(exp_pgx_pcas)
#f3 <- get_fit(exp_pgx_pcas)
#t3$p <- format_p(t3$p)

#t3 <- t3[-1]

#t4 <- make_tab(map_pgx_pcas)
#f4 <- get_fit(map_pgx_pcas)
#t4$p <- format_p(t4$p)

#t4 <- t4[-1]


extra <- cbind(f1, f2[2]) #, f3[2], f4[2])

main <- full_join(t1, t2, by = "Predictor")
#main <- full_join(main, t3, by = "Predictor")
#main <- full_join(main, t4, by = "Predictor")

main <- column_as_rownames(main, var = "Predictor")

rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)","CYP3A5 Activity Score", "Carbamazepine (Yes)", "Adherent (Yes)", "Schizophrenia PGS", "Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5")

#main <- main[c(1,2,3,4,5,15,6:14),]

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p", "Estimate (SE)", "p")) %>%
  add_header_above(header = c( " " = 1, "Diminished Expressivity - Carbamazepine Covariate" = 2, "Motivation and Pleasure - Carbamazepine Covariate" = 2)) %>%
  kable_classic(full_width = T) 
Diminished Expressivity - Carbamazepine Covariate
Motivation and Pleasure - Carbamazepine Covariate
Estimate (SE) p Estimate (SE) p
CPZ-eq Antipsychotic Dose (mg/day) 0.043 (0.04) 0.303 0.056 (0.04) 0.192
Clozapine (Yes) 0.428 (0.09) 1x10⁻⁶ 0.242 (0.09) 0.006
Anticholinergic (Yes) 0.236 (0.12) 0.041 0.284 (0.12) 0.015
CYP3A5 Activity Score -0.106 (0.04) 0.01 -0.1 (0.04) 0.018
Carbamazepine (Yes) 0.644 (0.44) 0.142 0.597 (0.44) 0.18
Adherent (Yes) -0.229 (0.18) 0.21 -0.359 (0.19) 0.053
Schizophrenia PGS 0.029 (0.04) 0.492 -0.006 (0.04) 0.88
Age 0.065 (0.04) 0.12 0.04 (0.04) 0.345
Sex (Female) -0.181 (0.09) 0.034 -0.109 (0.09) 0.21
PC1 0.024 (0.04) 0.573 -0.015 (0.04) 0.732
PC2 0.02 (0.04) 0.631 0.016 (0.04) 0.703
PC3 0.02 (0.04) 0.629 0.018 (0.04) 0.659
PC4 -0.018 (0.04) 0.663 -0.003 (0.04) 0.937
PC5 0.064 (0.04) 0.112 0.063 (0.04) 0.124
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 12. Sensitivity analysis to account for the potential of carbamazepine to induce CYP3A5 activity. This is accounted for through a control (carbamazepine yes/no) covariate for both symptom dimensions (i.e., diminished expressivity, reduced motivation and pleasure) where an association with CYP3A5 activity score was previously observed.", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 12. Sensitivity analysis to account for the potential of carbamazepine to induce CYP3A5 activity. This is accounted for through a control (carbamazepine yes/no) covariate for both symptom dimensions (i.e., diminished expressivity, reduced motivation and pleasure) where an association with CYP3A5 activity score was previously observed.
R2 0.083 0.054
adjusted R2 0.060 0.031
N 585.000 585.000



CYP1A2
CYP1A2 and Cigarette Smoking

We saw no significant interaction between the CYP1A2 activity score and cigarette use (β = -0.066; 95%CI, -0.33 to 0.19; p = 0.62). Cigarette smoking was inversely associated with cognition (β = -0.29; 95%CI, -0.54 to -0.04; p = 0.026); however, the association between CYP1A2 activity and cognitive ability weakened (β = 0.19; 95%CI, -0.01 to 0.39; p = 0.06). Finally, we observed no significant association between phenoconversion-corrected CYP1A2 activity scores and cognition (β = -0.022; 95%CI, -0.15 to 0.11; p = 0.74). Full results are in Supplementary Table 13.

The p value for the association between CYP1A2 activity score and cognition became larger after controlling for smoking status, suggesting that part of the variance in cognition explained by CYP1A2 is due to the inductive effect of cigarette smoking. However, information regarding patient smoking status was absent for just under 10% of the original subgroup (N = 18). The attenuation of the CYP1A2-cognition association could be explained in part by this loss of statistical power. We note that the negative association between cigarette smoking, and cognition is somewhat contrary to expectations. Cigarette smoke is a known CYP1A2 inducer, binding with aryl hydrocarbon receptors and resulting in increased enzyme activity14. However, chronic smoking is also robustly associated with cognitive impairment15. Therefore, smoking may be exerting dual, contradictory effects on cognition in our sample; a larger, inverse direct effect, and a more modest indirect, positive effect through induction of CYP1A2 activity.

t1 <- make_tab(cog_pgx_pc)
f1 <- get_fit(cog_pgx_pc)
t1$p <- format_p(t1$p)

t1 <- t1[-1]

t2 <- make_tab(cog_pgx_pcas)
f2 <- get_fit(cog_pgx_pcas)
t2$p <- format_p(t2$p)

t2 <- t2[-1]
extra <- cbind(f1, f2[2])

main <- full_join(t1, t2, by = "Predictor")
main <- column_as_rownames(main, var = "Predictor")

rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Anticholinergic (Yes)","CYP1A2 Activity Score", "Cigarettes (Yes)", "Adherent (Yes)", "Schizophrenia PGS", "Intelligence PGS", "Educational Attainment PGS", "Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5", "CYP1A2-Smoking interaction", "Phenoconversion-Corrected CYP1A2 Activity Score")

main <- main[c(1,2,3,4,16,17,5:15),]

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p", "Estimate (SE)", "p")) %>%
  add_header_above(header = c( " " = 1, "Cognition (Clozapine Subgroup) - Smoking Interaction" = 2, "Cognition (Clozapine Subgroup) - Corrected Scores" = 2)) %>%
  kable_classic(full_width = T) 
Cognition (Clozapine Subgroup) - Smoking Interaction
Cognition (Clozapine Subgroup) - Corrected Scores
Estimate (SE) p Estimate (SE) p
CPZ-eq Antipsychotic Dose (mg/day) -0.133 (0.06) 0.038 -0.147 (0.06) 0.024
Anticholinergic (Yes) -0.352 (0.17) 0.043 -0.375 (0.18) 0.034
CYP1A2 Activity Score 0.19 (0.1) 0.06
Cigarettes (Yes) -0.29 (0.13) 0.026
CYP1A2-Smoking interaction -0.066 (0.13) 0.618
Phenoconversion-Corrected CYP1A2 Activity Score -0.022 (0.06) 0.739
Adherent (Yes) 0.206 (0.44) 0.644 0.207 (0.45) 0.648
Schizophrenia PGS -0.092 (0.07) 0.165 -0.102 (0.07) 0.133
Intelligence PGS 0.147 (0.08) 0.078 0.14 (0.08) 0.094
Educational Attainment PGS 0.032 (0.08) 0.704 0.074 (0.08) 0.367
Age -0.401 (0.06) 8x10⁻¹⁰ -0.405 (0.06) 9x10⁻¹⁰
Sex (Female) 0.029 (0.13) 0.823 0.066 (0.13) 0.617
PC1 0.094 (0.06) 0.143 0.09 (0.06) 0.165
PC2 0.138 (0.13) 0.293 0.178 (0.13) 0.18
PC3 -0.429 (0.25) 0.091 -0.488 (0.26) 0.058
PC4 0.403 (0.25) 0.102 0.482 (0.25) 0.054
PC5 -0.018 (0.09) 0.848 0.008 (0.09) 0.931
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 13. Sensitivity analysis to account for the potential of smoking to influence CYP1A2 activity. This is accounted for through a control (smoking yes/no) covariate, or by inclusion of a phenoconversion activity score (activity score * 1.5 if participant is a smoker). Sensitivity analyses were performed only in the cognitive dimension where an association with CYP1A2 activity score was previously observed.", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 13. Sensitivity analysis to account for the potential of smoking to influence CYP1A2 activity. This is accounted for through a control (smoking yes/no) covariate, or by inclusion of a phenoconversion activity score (activity score * 1.5 if participant is a smoker). Sensitivity analyses were performed only in the cognitive dimension where an association with CYP1A2 activity score was previously observed.
R2 0.340 0.304
adjusted R2 0.281 0.250
N 197.000 197.000



Alternative Analysis: Premorbid IQ

Exploring Measures of Premorbid Intelligence

Comparison of premorbid intelligence measures
# models for current cognition
nart_cog <- lm(cog ~  NARTIQ + Age_at_Interview  + Sex, data = test_df_dim_std)
joint_cog <- lm(cog ~ Int_PRScs + EA_PRScs + Age_at_Interview  + Sex, data = test_df_dim_std)


# linear models testing whether our intelligence measures (IQ PRS and NARTIQ) are associated with medication variables
d_nart <- lm(cpz_eq ~ NARTIQ + Age_at_Interview  + Sex, data = test_df_dim_std)
d_joint <- lm(cpz_eq ~ Int_PRScs + EA_PRScs + Age_at_Interview  + Sex, data = test_df_dim_std)

coefs5a <- data.frame(coef(summary(nart_cog)))
coefs5b <- data.frame(coef(summary(joint_cog))) 
coefs5c <- data.frame(coef(summary(d_nart))) 
coefs5d <- data.frame(coef(summary(d_joint))) 

Premorbid intelligence as estimated by the NART had a stronger association with the cognitive ability dimension (β = 0.517; 95%CI, 0.45 to 0.58; p = 5x10⁻⁴⁷), compared to the intelligence PGS (β = 0.097; 95%CI, 0.01 to 0.19; p = 0.034) and educational attainment PGS (β = 0.115; 95%CI, 0.03 to 0.2; p = 0.012).

However, we also found premorbid intelligence as estimated by the NART was inversely associated with chlorpromazine-equivalent antipsychotic dose (β = -0.131; 95%CI, -0.21 to -0.05; p = 0.002) whereas there was no such association with dose for either intelligence PGS (β = -0.034; 95%CI, -0.13 to 0.06; p = 0.495) or educational attainment PGS (β = -0.016; 95%CI, -0.11 to 0.08; p = 0.75).

The results could indicate that participants with lower premorbid intelligence scores from the NART were prescribed higher antipsychotic doses. An alternative interpretation is that performance on the NART was affected by the participant’s antipsychotic dose (i.e. sedation effects) and therefore, might not fully reflect pre-morbid intelligence in this sample16. As we were not able to distinguish between these potential confounding effects, we selected to use both intelligence and educational PGS as the estimates of premorbid intelligence in our primary analyses. However, we have conducted secondary analyses controlling for the NART, shown below.


Alternative analyses controlling for premorbid intelligence as estimated by NART

This secondary analysis controls for premorbid intelligence as estimated by the NART, instead of PGS for intelligence and educational attainment, in analyses where the cognitive ability dimension is the outcome. Results are presented in Supplementary Table 14. NART data was not available for all participants in the full sample (N = 27) and those prescribed clozapine (N = 13); hence, these analyses have a lower sample size than those reported in the main text.

The associations between antipsychotic dose, clozapine use, and anticholinergic use with cognitive ability remained significant when including NART in the models, despite an attenuation in the strength of effect sizes and p-values. However, in the pharmacogenomic model including only patients prescribed clozapine, covarying for NART reduced the effect size for the associations of cognitive ability with anticholinergic use and CYP1A2 activity score, rendering their p-values non-significant.

ncog <- lm(cog ~  cpz_eq + clozapine_current + antichol_present +  Adherence_coded + SZ_PRScs + NARTIQ + Age_at_Interview  + Sex  + PC1 + PC2 + PC3 + PC4 + PC5, data = test_df_dim_std)

ncog_pgx <- lm(cog ~  cpz_eq + clozapine_current + antichol_present + CYP1A2_AS + CYP2D6_AS + CYP3A5_AS + CYP2C19_AS + CYP2C9_AS + Adherence_coded + SZ_PRScs + NARTIQ + Age_at_Interview  + Sex + PC1 + PC2 + PC3 + PC4 + PC5, data = test_df_dim_std)

nccog_pgx <- lm(cog ~  cpz_eq + antichol_present + CYP1A2_AS + CYP2D6_AS + CYP3A5_AS + CYP2C19_AS + CYP2C9_AS + Adherence_coded + SZ_PRScs +  NARTIQ + Age_at_Interview  + Sex + PC1 + PC2 + PC3 + PC4 + PC5, data = test_df_dim_std_c)

#### create table ####
t1 <- make_tab(ncog)
f1 <- get_fit(ncog)
t1$p <- format_p(t1$p)
t1 <- t1[-1]

t2 <- make_tab(ncog_pgx)
f2 <- get_fit(ncog_pgx)
t2$p <- format_p(t2$p)
t2 <- t2[-1]

t3 <- make_tab(nccog_pgx)
f3 <- get_fit(nccog_pgx)
t3$p <- format_p(t3$p)
t3 <- t3[-1]

extra <- cbind(f1, f2[2], f3[2])

main <- full_join(t1, t2, by = "Predictor")
main <- full_join(main, t3, by = "Predictor")
main <- column_as_rownames(main, var = "Predictor")

rownames(main) <- c("CPZ-eq Antipsychotic Dose (mg/day)", "Clozapine (Yes)", "Anticholinergic (Yes)",  "Adherent (Yes)", "Schizophrenia PGS", "NART IQ", "Age", "Sex (Female)", "PC1", "PC2", "PC3", "PC4", "PC5", "CYP1A2 Activity Score", "CYP2D6 Activity Score", "CYP3A5 Activity Score", "CYP2C19 Activity Score", "CYP2C9 Activity Score")

main <- main[c(1,2,3,14,15,16,17,18,6,4,5,7,8,9,10,11,12,13),] 

main %>% 
  kable(format = "html", escape = F, col.names = c("Estimate (SE)", "p", "Estimate (SE)", "p", "Estimate (SE)", "p")) %>%
  add_header_above(header = c( " " = 1, "Medication Model" = 2, "Medication & Pharmacogenomic Model" = 2,  "Medication & Pharmacogenomic Model (Clozapine Subgroup)" = 2)) %>%
  kable_classic(full_width = T) 
Medication Model
Medication & Pharmacogenomic Model
Medication & Pharmacogenomic Model (Clozapine Subgroup)
Estimate (SE) p Estimate (SE) p Estimate (SE) p
CPZ-eq Antipsychotic Dose (mg/day) -0.071 (0.03) 0.03 -0.066 (0.03) 0.047 -0.134 (0.05) 0.012
Clozapine (Yes) -0.339 (0.07) 7x10⁻⁷ -0.339 (0.07) 1x10⁻⁶
Anticholinergic (Yes) -0.276 (0.09) 0.002 -0.271 (0.09) 0.003 -0.187 (0.15) 0.203
CYP1A2 Activity Score 0.025 (0.03) 0.433 0.066 (0.05) 0.221
CYP2D6 Activity Score -0.037 (0.03) 0.25 -0.02 (0.05) 0.7
CYP3A5 Activity Score 0.039 (0.03) 0.221 0.082 (0.05) 0.117
CYP2C19 Activity Score 0.018 (0.03) 0.57 0.005 (0.05) 0.917
CYP2C9 Activity Score -0.025 (0.03) 0.435 0.031 (0.05) 0.553
NART IQ 0.475 (0.03) 3x10⁻⁴² 0.474 (0.03) 7x10⁻⁴¹ 0.454 (0.05) 5x10⁻¹⁵
Adherent (Yes) 0.254 (0.14) 0.073 0.26 (0.14) 0.073 0.056 (0.38) 0.881
Schizophrenia PGS -0.063 (0.03) 0.049 -0.059 (0.03) 0.068 -0.097 (0.05) 0.063
Age -0.442 (0.03) 3x10⁻³⁷ -0.438 (0.03) 8x10⁻³⁶ -0.481 (0.05) 1x10⁻¹⁶
Sex (Female) 0.103 (0.07) 0.118 0.112 (0.07) 0.094 0.053 (0.11) 0.63
PC1 0.074 (0.03) 0.023 0.069 (0.03) 0.038 0.059 (0.05) 0.276
PC2 -0.023 (0.03) 0.446 -0.022 (0.03) 0.474 0.161 (0.11) 0.157
PC3 -0.035 (0.03) 0.254 -0.04 (0.03) 0.199 -0.509 (0.22) 0.021
PC4 0.027 (0.03) 0.371 0.022 (0.03) 0.483 0.398 (0.21) 0.061
PC5 0.009 (0.03) 0.778 0.004 (0.03) 0.904 -0.088 (0.08) 0.257
extra %>% 
  kable(format = "html", escape = F, caption = "Supplementary Table 14. Associations between medication and pharmacogenomic variables with the cognitive ability dimensions in CardiffCOGS. NART IQ is included as a proxy of premorbid intelligence in place of the Intelligence PGS and Educational Attainment PGS used in the analyses presented in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.", col.names = NULL, align=c("l", "c", "c", "c", "c", "c"), digits = 3, format.args = list(nsmall = 3)) %>%
  kable_classic(full_width = T) 
Supplementary Table 14. Associations between medication and pharmacogenomic variables with the cognitive ability dimensions in CardiffCOGS. NART IQ is included as a proxy of premorbid intelligence in place of the Intelligence PGS and Educational Attainment PGS used in the analyses presented in the main text. Standardised regression estimates are reported. CPZ-eq = chlorpromazine-equivalent; SE = Standard Error; PGS = Polygenic Score; PC = Genetic Principal Component.
R2 0.469 0.470 0.510
adjusted R2 0.457 0.452 0.465
N 558.000 551.000 202.000





Supplementary References

Supplementary References

1 Das S, Forer L, Schönherr S, et al. Next-generation genotype imputation service and methods. Nature Genetics 2016; 48: 1284–7.

2 Loh P-R, Danecek P, Palamara PF, et al. Reference-based phasing using the Haplotype Reference Consortium panel. Nat Genet 2016; 48: 1443–8.

3 Lynham AJ, Knott S, Underwood JFG, et al. DRAGON-Data: a platform and protocol for integrating genomic and phenotypic data across large psychiatric cohorts. BJPsych Open 2023; 9: 1–8.

4 Legge SE, Cardno AG, Allardyce J, et al. Associations Between Schizophrenia Polygenic Liability, Symptom Dimensions, and Cognitive Ability in Schizophrenia. JAMA Psychiatry 2021; 78: 1143–51.

5 Surakka I, Sarin A-P, Ruotsalainen SE, et al. The rate of false polymorphisms introduced when imputing genotypes from global imputation panels. 2016; : 080770.

6 Uffelmann E, Huang QQ, Munung NS, et al. Genome-wide association studies. Nat Rev Methods Primers 2021; 1: 1–21.

7 Lee S, Shin J-Y, Kwon N-J, Kim C, Seo J-S. ClinPharmSeq: A targeted sequencing panel for clinical pharmacogenetics implementation. PLOS ONE 2022; 17: 1–19.

8 Saiz-Rodríguez M, Ochoa D, Belmonte C, et al. Polymorphisms in CYP1A2, CYP2C9 and ABCB1 affect agomelatine pharmacokinetics. Journal of Psychopharmacology 2019; 33: 522–31.

9 Lesche D, Mostafa S, Everall I, Pantelis C, Bousman CA. Impact of CYP1A2, CYP2C19, and CYP2D6 genotype- and phenoconversion-predicted enzyme activity on clozapine exposure and symptom severity. The Pharmacogenomics Journal 2020; 20: 192–201.

10 Tian D, Natesan S, White JR, Paine MF. Effects of Common CYP1A2 Genotypes and Other Key Factors on Intraindividual Variation in the Caffeine Metabolic Ratio: An Exploratory Analysis. Clinical and Translational Science 2019; 12: 39–46.

11 Mostafa S, Polasek TM, Sheffield LJ, Huppert D, Kirkpatrick CMJ. Quantifying the Impact of Phenoconversion on Medications With Actionable Pharmacogenomic Guideline Recommendations in an Acute Aged Persons Mental Health Setting. Front Psychiatry 2021; 12: 724170.

12 Klomp SD, Manson ML, Guchelaar H-J, Swen JJ. Phenoconversion of Cytochrome P450 Metabolism: A Systematic Review. Journal of Clinical Medicine 2020; 9: 2890.

13 Food and Drug Administration. Drug Development and Drug Interactions: Table of Substrates, Inhibitors and Inducers. 2023; published online April 12. https://www.fda.gov/drugs/drug-interactions-labeling/drug-development-and-druginteractions-table-substrates-inhibitors-and-inducers (accessed Feb 9, 2024).

14 Hukkanen J, Jacob P, Peng M, Dempsey D, Benowitz NL. Effect of nicotine on cytochrome P450 1A2 activity. British Journal of Clinical Pharmacology 2011; 72: 836–8.

15 Coustals N, Martelli C, Brunet-Lecomte M, Petillion A, Romeo B, Benyamina A. Chronic smoking and cognition in patients with schizophrenia: A meta-analysis. Schizophrenia Research 2020; 222: 113–21.

16 Tracy JI, McGrory AC, Josiassen RC, Monaco CA. A comparison of reading and demographic-based estimates of premorbid intelligence in schizophrenia. Schizophrenia Research 1996; 22: 103–9.





Session Info

sessionInfo()
## R version 4.4.0 Patched (2024-05-06 r86526 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19045)
## 
## Matrix products: default
## 
## 
## locale:
## [1] LC_COLLATE=English_United Kingdom.utf8 
## [2] LC_CTYPE=English_United Kingdom.utf8   
## [3] LC_MONETARY=English_United Kingdom.utf8
## [4] LC_NUMERIC=C                           
## [5] LC_TIME=English_United Kingdom.utf8    
## 
## time zone: Europe/London
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] phenoconverter_0.1.0  rvest_1.0.4           gsubfn_0.7           
##  [4] proto_1.0.0           shiny_1.10.0          gtsummary_1.7.2      
##  [7] flextable_0.9.5       semPlot_1.1.6         semptools_0.2.10     
## [10] lavaanPlot_0.8.1      lavaan_0.6-17         thematic_0.1.5       
## [13] sjPlot_2.8.15         chlorpromazineR_0.2.0 AER_1.2-12           
## [16] survival_3.6-4        sandwich_3.1-0        lmtest_0.9-40        
## [19] zoo_1.8-12            car_3.1-2             carData_3.0-5        
## [22] arsenal_3.6.3         datawizard_0.10.0     data.table_1.15.4    
## [25] scales_1.3.0          tidyselect_1.2.1      reshape2_1.4.4       
## [28] kableExtra_1.4.0      psych_2.4.3           ggpubr_0.6.0         
## [31] lubridate_1.9.3       forcats_1.0.0         stringr_1.5.1        
## [34] dplyr_1.1.4           purrr_1.0.2           readr_2.1.5          
## [37] tidyr_1.3.1           tibble_3.2.1          ggplot2_3.5.1        
## [40] tidyverse_2.0.0       haven_2.5.4           beepr_1.3            
## 
## loaded via a namespace (and not attached):
##   [1] later_1.3.2             splines_4.4.0           XML_3.99-0.16.1        
##   [4] rpart_4.1.23            lifecycle_1.0.4         tcltk_4.4.0            
##   [7] rstatix_0.7.2           vroom_1.6.5             lattice_0.22-6         
##  [10] MASS_7.3-60.2           insight_0.19.10         rockchalk_1.8.157      
##  [13] backports_1.4.1         magrittr_2.0.3          openxlsx_4.2.5.2       
##  [16] Hmisc_5.1-2             sass_0.4.9              rmarkdown_2.27         
##  [19] jquerylib_0.1.4         yaml_2.3.8              httpuv_1.6.15          
##  [22] qgraph_1.9.8            askpass_1.2.0           zip_2.3.1              
##  [25] pbapply_1.7-2           minqa_1.2.6             RColorBrewer_1.1-3     
##  [28] multcomp_1.4-25         abind_1.4-5             audio_0.1-11           
##  [31] quadprog_1.5-8          nnet_7.3-19             TH.data_1.1-2          
##  [34] gdtools_0.3.7           crul_1.4.2              arm_1.14-4             
##  [37] performance_0.11.0      svglite_2.1.3           codetools_0.2-20       
##  [40] xml2_1.3.6              httpcode_0.3.0          ggeffects_1.5.2        
##  [43] lme4_1.1-35.3           stats4_4.4.0            base64enc_0.1-3        
##  [46] showtext_0.9-7          broom.helpers_1.15.0    jsonlite_1.8.8         
##  [49] Formula_1.2-5           emmeans_1.10.5          systemfonts_1.0.6      
##  [52] tools_4.4.0             ragg_1.3.0              Rcpp_1.0.13-1          
##  [55] glue_1.7.0              mnormt_2.1.1            gridExtra_2.3          
##  [58] xfun_0.43               withr_3.0.0             fastmap_1.2.0          
##  [61] boot_1.3-30             fansi_1.0.6             openssl_2.1.2          
##  [64] digest_0.6.35           mime_0.12               mi_1.1                 
##  [67] timechange_0.3.0        R6_2.5.1                estimability_1.5       
##  [70] textshaping_0.3.7       colorspace_2.1-0        wakefield_0.3.6        
##  [73] gtools_3.9.5            jpeg_0.1-10             DiagrammeR_1.0.11      
##  [76] utf8_1.2.4              generics_0.1.3          fontLiberation_0.1.0   
##  [79] corpcor_1.6.10          httr_1.4.7              htmlwidgets_1.6.4      
##  [82] pkgconfig_2.0.3         sem_3.1-15              gtable_0.3.5           
##  [85] emojifont_0.5.5         htmltools_0.5.8.1       fontBitstreamVera_0.1.1
##  [88] sysfonts_0.8.9          png_0.1-8               knitr_1.46             
##  [91] rstudioapi_0.16.0       uuid_1.2-0              tzdb_0.4.0             
##  [94] coda_0.19-4.1           visNetwork_2.1.2        checkmate_2.3.1        
##  [97] nlme_3.1-164            curl_5.2.1              nloptr_2.0.3           
## [100] showtextdb_3.0          cachem_1.1.0            sjlabelled_1.2.0       
## [103] parallel_4.4.0          foreign_0.8-86          pillar_1.9.0           
## [106] grid_4.4.0              vctrs_0.6.5             promises_1.3.2         
## [109] OpenMx_2.21.11          xtable_1.8-4            cluster_2.1.6          
## [112] archive_1.1.10          htmlTable_2.4.2         evaluate_0.23          
## [115] pbivnorm_0.6.0          mvtnorm_1.2-4           cli_3.6.2              
## [118] kutils_1.73             compiler_4.4.0          rlang_1.1.3            
## [121] crayon_1.5.2            ggsignif_0.6.4          modelr_0.1.11          
## [124] fdrtool_1.2.17          plyr_1.8.9              sjmisc_2.8.9           
## [127] stringi_1.8.3           viridisLite_0.4.2       munsell_0.5.1          
## [130] lisrelToR_0.3           bayestestR_0.13.2       fontquiver_0.2.1       
## [133] Matrix_1.7-0            sjstats_0.18.2          hms_1.1.3              
## [136] glasso_1.11             bit64_4.0.5             gfonts_0.2.0           
## [139] highr_0.10              gt_0.10.1               igraph_2.0.3           
## [142] broom_1.0.5             RcppParallel_5.1.7      bslib_0.7.0            
## [145] bit_4.0.5               officer_0.6.5



LS0tDQp0aXRsZTogPGNlbnRlcj4gPHN0cm9uZz4gTWVkaWNhdGlvbiBhbmQgcGhhcm1hY29nZW5vbWljIGVmZmVjdHMgb24gY3Jvc3Mtc2VjdGlvbmFsIHN5bXB0b20gc2V2ZXJpdHkgYW5kIGNvZ25pdGl2ZSBhYmlsaXR5IGluIHNjaGl6b3BocmVuaWEuIDwvc3Ryb25nPiA8L2NlbnRlcj4NCmF1dGhvcjogPGNlbnRlcj4gPHNtYWxsPiBTaW9iaGFuIExvY2sgIDwvc21hbGw+IDwvY2VudGVyPg0KZGF0ZTogPGNlbnRlcj4gPHNtYWxsPiBgciBmb3JtYXQoU3lzLkRhdGUoKSwgZm9ybWF0PSIlQiAlZCAlWSIpYCA8L3NtYWxsPiA8L2NlbnRlcj4NCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY3NzOiAic3R5bGUuY3NzIiAgICAgICAgDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZSANCiAgICBjb2RlX2ZvbGRpbmc6ICdoaWRlJw0KICAgIHRoZW1lOg0KICAgICAgY29sb3ItY29udHJhc3Qtd2FybmluZ3M6IGZhbHNlDQogICAgICBiZzogIiNFRkVGRUYiDQogICAgICBmZzogIiMwMDAiDQogICAgICBwcmltYXJ5OiAiIzk4NDFEQiINCiAgICAgIHNlY29uZGFyeTogIiM5ODQxREIiDQogICAgICBiYXNlX2ZvbnQ6DQogICAgICAgIGdvb2dsZTogTW9udHNlcnJhdA0KICAgICAgaGVhZGluZ19mb250Og0KICAgICAgICBnb29nbGU6IEJ1bmdlZQ0KICAgICAgY29kZV9mb250Og0KICAgICAgICBnb29nbGU6ICJSb2JvdG8gTW9ubyINCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgDQoNCi0tLQ0KDQo8c3R5bGU+IA0KDQoNCg0KYm9keSB7DQogIG1heC13aWR0aDogMTkyMHB4Ow0KICBtYXJnaW4tbGVmdDogYXV0byA7DQogIG1hcmdpbi1yaWdodDogYXV0bzsNCn0NCg0KDQojaGVhZGVyIHsgDQovKiBQZXJtYWxpbmsgLSB1c2UgdG8gZWRpdCBhbmQgc2hhcmUgdGhpcyBncmFkaWVudDogaHR0cHM6Ly9jb2xvcnppbGxhLmNvbS9ncmFkaWVudC1lZGl0b3IvI2UzYWRmZiswLDk4NDFkYis4OCAqLw0KYmFja2dyb3VuZDogI2UzYWRmZjsgLyogT2xkIGJyb3dzZXJzICovDQovKiBJRTkgU1ZHLCBuZWVkcyBjb25kaXRpb25hbCBvdmVycmlkZSBvZiAnZmlsdGVyJyB0byAnbm9uZScgKi8NCmJhY2tncm91bmQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQS9QZ284YzNabklIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2QybGtkR2c5SWpFd01DVWlJR2hsYVdkb2REMGlNVEF3SlNJZ2RtbGxkMEp2ZUQwaU1DQXdJREVnTVNJZ2NISmxjMlZ5ZG1WQmMzQmxZM1JTWVhScGJ6MGlibTl1WlNJK0NpQWdQSEpoWkdsaGJFZHlZV1JwWlc1MElHbGtQU0puY21Ga0xYVmpaMmN0WjJWdVpYSmhkR1ZrSWlCbmNtRmthV1Z1ZEZWdWFYUnpQU0oxYzJWeVUzQmhZMlZQYmxWelpTSWdZM2c5SWpVd0pTSWdZM2s5SWpVd0pTSWdjajBpTnpVbElqNEtJQ0FnSUR4emRHOXdJRzltWm5ObGREMGlNQ1VpSUhOMGIzQXRZMjlzYjNJOUlpTmxNMkZrWm1ZaUlITjBiM0F0YjNCaFkybDBlVDBpTVNJdlBnb2dJQ0FnUEhOMGIzQWdiMlptYzJWMFBTSTRPQ1VpSUhOMGIzQXRZMjlzYjNJOUlpTTVPRFF4WkdJaUlITjBiM0F0YjNCaFkybDBlVDBpTVNJdlBnb2dJRHd2Y21Ga2FXRnNSM0poWkdsbGJuUStDaUFnUEhKbFkzUWdlRDBpTFRVd0lpQjVQU0l0TlRBaUlIZHBaSFJvUFNJeE1ERWlJR2hsYVdkb2REMGlNVEF4SWlCbWFXeHNQU0oxY213b0kyZHlZV1F0ZFdOblp5MW5aVzVsY21GMFpXUXBJaUF2UGdvOEwzTjJaejQ9KTsNCmJhY2tncm91bmQ6IC1tb3otcmFkaWFsLWdyYWRpZW50KGNlbnRlciwgZWxsaXBzZSBjb3ZlciwgICNlM2FkZmYgMCUsICM5ODQxZGIgODglKTsgLyogRkYzLjYtMTUgKi8NCmJhY2tncm91bmQ6IC13ZWJraXQtZ3JhZGllbnQocmFkaWFsLCBjZW50ZXIgY2VudGVyLCAwcHgsIGNlbnRlciBjZW50ZXIsIDEwMCUsIGNvbG9yLXN0b3AoMCUsI2UzYWRmZiksIGNvbG9yLXN0b3AoODglLCM5ODQxZGIpKTsgLyogQ2hyb21lNC05LFNhZmFyaTQtNSAqLw0KYmFja2dyb3VuZDogLXdlYmtpdC1yYWRpYWwtZ3JhZGllbnQoY2VudGVyLCBlbGxpcHNlIGNvdmVyLCAgI2UzYWRmZiAwJSwjOTg0MWRiIDg4JSk7IC8qIENocm9tZTEwLTI1LFNhZmFyaTUuMS02ICovDQpiYWNrZ3JvdW5kOiAtby1yYWRpYWwtZ3JhZGllbnQoY2VudGVyLCBlbGxpcHNlIGNvdmVyLCAgI2UzYWRmZiAwJSwjOTg0MWRiIDg4JSk7IC8qIE9wZXJhIDEyKyAqLw0KYmFja2dyb3VuZDogLW1zLXJhZGlhbC1ncmFkaWVudChjZW50ZXIsIGVsbGlwc2UgY292ZXIsICAjZTNhZGZmIDAlLCM5ODQxZGIgODglKTsgLyogSUUxMCBwcmV2aWV3ICovDQpiYWNrZ3JvdW5kOiByYWRpYWwtZ3JhZGllbnQoZWxsaXBzZSBhdCBjZW50ZXIsICAjZTNhZGZmIDAlLCM5ODQxZGIgODglKTsgLyogVzNDLCBJRTEwKywgRkYxNissIENocm9tZTI2KywgT3BlcmExMissIFNhZmFyaTcrICovDQpmaWx0ZXI6IHByb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5ncmFkaWVudCggc3RhcnRDb2xvcnN0cj0nI2UzYWRmZicsIGVuZENvbG9yc3RyPScjOTg0MWRiJyxHcmFkaWVudFR5cGU9MSApOyAvKiBJRTYtOCBmYWxsYmFjayBvbiBob3Jpem9udGFsIGdyYWRpZW50ICovDQoNCg0KDQogIGNvbG9yOiAjRUZFRkVGOw0KICBoZWlnaHQ6IDQwMHB4Ow0KICBwYWRkaW5nOiAxNXB4Ow0KICB9DQoNCi5tYWluLWNvbnRhaW5lciB7DQogIG1heC13aWR0aDogMTIwMHB4Ow0KICBtYXJnaW4tbGVmdDogYXV0bzsNCiAgbWFyZ2luLXJpZ2h0OiBhdXRvOw0KICB9DQoNCmRpdi5ibHVlIHsgYmFja2dyb3VuZC1jb2xvcjojRUZFRkVGOyBib3JkZXItcmFkaXVzOiAyMHB4OyBwYWRkaW5nOiAyMHB4O30NCg0KPC9zdHlsZT4NCg0KPGJyPg0KPGJyPg0KDQpgYGB7ciBzZXQgdXAsIGVjaG8gPSBGLCB3YXJuaW5nPSBGQUxTRX0NCiMjIyMgbWFya2Rvd24gc2V0dGluZ3MgIyMjIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBlY2hvID0gVFJVRSwgZmlnLmFsaWduID0gImNlbnRlciIsIGRldiA9ICJwbmciLCBkZXYuYXJncz1saXN0KGJnPSJ0cmFuc3BhcmVudCIpKSANCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCm9wdGlvbnMoc2NpcGVuID0gMCkNCm9wdGlvbnMoZGlnaXRzID0gMykNCg0Kc2V0LnNlZWQoNjY2KQ0KDQpsaWJyYXJ5KGJlZXByKQ0KDQojIyMjIGZ1bmN0aW9ucyAjIyMjDQojIyMjIGZ1bmN0aW9uIHRvIGJlZXAgb24gZXJyb3Igb3IgdXBvbiBjb21wbGV0aW5nIGtuaXQgIyMjIw0Kb3B0aW9ucyhlcnJvciA9IGZ1bmN0aW9uKCl7ICAgIA0KICBiZWVwcjo6YmVlcChzb3VuZCA9IDEwKQ0KICBTeXMuc2xlZXAodGltZSA9IDEpDQogIH0NCiApDQoNCi5MYXN0IDwtIGZ1bmN0aW9uKCkgeyAgICAgICAgICANCiAgYmVlcHI6OmJlZXAoc291bmQgPSA1KQ0KICBTeXMuc2xlZXAodGltZSA9IDEpDQp9DQoNCg0KIyMjIyBmdW5jdGlvbiBmb3Igc3VtbWluZyBhY3Jvc3MgY2hyb21vc29tZXMgIyMjIw0KYW5hbHl6ZSA8LSBmdW5jdGlvbih0aHJlc2hvbGQpIHsNCiAgI3ByZXBhcmUNCiAgZGF0IDwtIGxhcHBseSh0aHJlc2hvbGQscmVhZC50YWJsZSwgaGVhZGVyID0gVFJVRSwgc2VwPSAiIikNCiAgbXlfY29scyA8LSBjKCJGSUQiLCAiU0NPUkVTVU0iKQ0KICBkYXQgPC0gbGFwcGx5KGRhdCwgIlsiLCAsIG15X2NvbHMpDQogICNzdW0NCiAgc3VtIDwtIGJpbmRfcm93cyhkYXQpICU+JQ0KICBncm91cF9ieShGSUQpICU+JQ0KICBzdW1tYXJpc2UoQUxMX0NIUl9TVU0gPSBzdW0oU0NPUkVTVU0pKQ0KICB9DQoNCg0KIyMjIyBmdW5jdGlvbnMgZm9yIGNyZWF0aW5nIHJlZ3Jlc3Npb24gdGFibGVzICMjIyMNCiMgcmVzdWx0cyB0YWJsZXMgd2l0aCBjb25maWRlbmNlIGludGVydmFscw0KbWFrZV90YWJfY2kgPC0gZnVuY3Rpb24oeCl7DQogIHN0YXQgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoeCkpKVtjKDEsNCldICU+JSAjIGV4dHJhY3QgZXN0aW1hdGVzL3AgdmFscw0KICAgIHJvd25hbWVzX2FzX2NvbHVtbih2YXIgPSAiUHJlZGljdG9yIikNCiAgY2kgPC0gZGF0YS5mcmFtZShjb25maW50KHgpKSAlPiUgIHJvdW5kKDIpICU+JSAgICAgICAgICAgICAgICAjIGV4dHJhY3QgY2lzDQogICAgcm93bmFtZXNfYXNfY29sdW1uKHZhciA9ICJQcmVkaWN0b3IiKQ0KDQogIG91dCA8LSBsZWZ0X2pvaW4oc3RhdCwgY2ksIGJ5ID0gIlByZWRpY3RvciIpDQogIG91dCRDSTwtIHBhc3RlMChvdXQkWDIuNS4uLCAiLCAiLCBvdXQkWDk3LjUuLikNCiAgb3V0JEVzdGltYXRlIDwtIHJvdW5kKG91dCRFc3RpbWF0ZSwgMykNCiAgb3V0JHAgPC0gb3V0JFByLi4udC4uIA0KICBvdXQkT3V0Y29tZSA8LSBjb2xuYW1lcyh4JG1vZGVsKVsxXQ0KICBvdXQkYEVzdGltYXRlICg5NSUgQ0kpYCA8LSBwYXN0ZTAob3V0JEVzdGltYXRlLCAiICgiLCBvdXQkQ0ksICIpIikNCiAgZGYgPC0gZHBseXI6OnNlbGVjdChvdXQsIGMoIk91dGNvbWUiLCAiUHJlZGljdG9yIiwgIkVzdGltYXRlICg5NSUgQ0kpIiwgInAiKSkgIyBqb2luIGFuZCBmb3JtYXQNCiAgZGYgPC0gZGZbLTEsXSANCiAgcmV0dXJuKGRmKQ0KfQ0KDQptYWtlX3RhYl9jaTIgPC0gZnVuY3Rpb24oeCl7DQogIHN0YXQgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoeCkpKVtjKDEsNCldICU+JSAjIGV4dHJhY3QgZXN0aW1hdGVzL3AgdmFscw0KICAgIHJvd25hbWVzX2FzX2NvbHVtbih2YXIgPSAiUHJlZGljdG9yIikNCiAgY2kgPC0gZGF0YS5mcmFtZShjb25maW50KHgpKSAlPiUgIHJvdW5kKDIpICU+JSAgICAgICAgICAgICAgICAjIGV4dHJhY3QgY2lzDQogICAgcm93bmFtZXNfYXNfY29sdW1uKHZhciA9ICJQcmVkaWN0b3IiKQ0KDQogIG91dCA8LSBsZWZ0X2pvaW4oc3RhdCwgY2ksIGJ5ID0gIlByZWRpY3RvciIpDQogIG91dCRFc3RpbWF0ZSA8LSByb3VuZChvdXQkRXN0aW1hdGUsIDMpDQogIG91dCRwIDwtIG91dCRQci4uLnQuLiANCiAgb3V0JE91dGNvbWUgPC0gY29sbmFtZXMoeCRtb2RlbClbMV0NCiAgb3V0JExvd2VyIDwtIG91dCRYMi41Li4NCiAgb3V0JFVwcGVyIDwtIG91dCRYOTcuNS4uDQogIGRmIDwtIGRwbHlyOjpzZWxlY3Qob3V0LCBjKCJPdXRjb21lIiwgIlByZWRpY3RvciIsICJFc3RpbWF0ZSIsICJMb3dlciIsICJVcHBlciIsICJwIikpICMgam9pbiBhbmQgZm9ybWF0DQogIGRmIDwtIGRmWy0xLF0gDQogIHJldHVybihkZikNCn0NCg0KIyByZXN1bHRzIHRhYmxlcyB3aXRoIHN0YW5kYXJkIGVycm9yDQptYWtlX3RhYiA8LSBmdW5jdGlvbih4KXsNCiAgb3V0IDwtIGRhdGEuZnJhbWUoY29lZihzdW1tYXJ5KHgpKSlbLWMoMyldICU+JSAjIGV4dHJhY3QgZXN0aW1hdGVzLCBzdGFuZGFyZCBlcnJvcnMsIHAgdmFscw0KICAgIHJvd25hbWVzX2FzX2NvbHVtbih2YXIgPSAiUHJlZGljdG9yIikNCiAgb3V0JEVzdGltYXRlIDwtIHJvdW5kKG91dCRFc3RpbWF0ZSwgMykNCiAgb3V0JFNFIDwtIHJvdW5kKG91dCRTdGQuLkVycm9yLCAyKQ0KICBvdXQkcCA8LSBvdXQkUHIuLi50Li4gDQogIG91dCRPdXRjb21lIDwtIGNvbG5hbWVzKHgkbW9kZWwpWzFdDQogIG91dCRgRXN0aW1hdGUgKFNFKWAgPC0gcGFzdGUwKG91dCRFc3RpbWF0ZSwgIiAoIiwgb3V0JFNFLCAiKSIpDQogIGRmIDwtIGRwbHlyOjpzZWxlY3Qob3V0LCBjKCJPdXRjb21lIiwgIlByZWRpY3RvciIsICJFc3RpbWF0ZSAoU0UpIiwgInAiKSkgIyBqb2luIGFuZCBmb3JtYXQNCiAgZGYgPC0gZGZbLTEsXSANCiAgcmV0dXJuKGRmKQ0KfQ0KDQojIG1vZGVsIHN0YXRpc3RpY3MgDQpnZXRfZml0IDwtIGZ1bmN0aW9uKHgpew0KICBuIDwtcm91bmQobm9icyh4KSwgZGlnaXRzID0gMykNCiAgbW9kIDwtIHN1bW1hcnkoeCkNCiAgcjIgPC0gbW9kJHIuc3F1YXJlZA0KICBhcjIgPC0gbW9kJGFkai5yLnNxdWFyZWQNCiAgZGYgPC0gZGF0YS5mcmFtZShsYWJlbCA9IGMoIlIyIiwgImFkanVzdGVkIFIyIiwgIk4iKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpdCA9IGMocjIsIGFyMiwgbikpIA0KICByZXR1cm4oZGYpDQp9DQoNCiMgdHJhbnNmb3JtcyBudW1iZXJzIHRvIHN1cGVyc2NyaXB0DQp0b19zdXBlcnNjcmlwdCA8LSBmdW5jdGlvbih4KSB7DQogIHN1cGVyc2NyaXB0X2RpZ2l0cyA8LSBjKA0KICAgICcwJyA9ICdcdTIwNzAnLCAnMScgPSAnXHUwMEI5JywgJzInID0gJ1x1MDBCMicsICczJyA9ICdcdTAwQjMnLCANCiAgICAnNCcgPSAnXHUyMDc0JywgJzUnID0gJ1x1MjA3NScsICc2JyA9ICdcdTIwNzYnLCAnNycgPSAnXHUyMDc3JywgDQogICAgJzgnID0gJ1x1MjA3OCcsICc5JyA9ICdcdTIwNzknLCAnLScgPSAnXHUyMDdCJw0KICApDQogIGNoYXJzIDwtIHN0cnNwbGl0KHgsIE5VTEwpW1sxXV0NCiAgc3VwZXJzY3JpcHQgPC0gc2FwcGx5KGNoYXJzLCBmdW5jdGlvbihjaGFyKSBzdXBlcnNjcmlwdF9kaWdpdHNbY2hhcl0pDQogIHJldHVybihwYXN0ZTAoc3VwZXJzY3JpcHQsIGNvbGxhcHNlID0gIiIpKQ0KfQ0KDQojIHRyYW5zZm9ybXMgbnVtYmVycyBmcm9tIDZlLTUgdG8gNngxMC01DQpmb3JtYXRfcCA8LSBmdW5jdGlvbih4KSB7DQogIHNpZ25pZmljYW50X2RpZ2l0cyA8LSBpZmVsc2UoeCA8IDAuMDEsIDEsIGlmZWxzZSh4IDwgMC4xLCAyLCAzKSkgIA0KICB0bXAgPC0gYXMuY2hhcmFjdGVyKHNpZ25pZih4LCBkaWdpdHMgPSBzaWduaWZpY2FudF9kaWdpdHMpKQ0KICAgDQogIHRtcCA8LSBnc3ViKCJlLTAiLCAieDEwXi0iLCB0bXApDQogIHRtcCA8LSBnc3ViKCJlIiwgIngxMF4iLCB0bXApDQoNCiAgdG1wIDwtIGdzdWJmbigieDEwXFxeKC0/XFxkKykiLCBmdW5jdGlvbih5KSB7DQogICAgcG93ZXIgPC0gZ3N1YigieDEwXFxeIiwgIiIsIHkpDQogICAgcGFzdGUwKCJ4MTAiLCB0b19zdXBlcnNjcmlwdChwb3dlcikpDQogIH0sIHRtcCkNCiAgcmV0dXJuKHRtcCkNCn0NCg0KIyMjIyBmdW5jdGlvbiB0byBjYWxjdWxhdGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBmb3IgYSB2YXJpYWJsZSAjIyMjDQpzdW1tYXJ5X3N0YXRzIDwtIGZ1bmN0aW9uKHZhcmlhYmxlKSB7DQogIG1lYW5fdmFsdWUgPC0gbWVhbih2YXJpYWJsZSkNCiAgc2RfdmFsdWUgPC0gc2QodmFyaWFibGUpDQogIG1pbl92YWx1ZSA8LSBtaW4odmFyaWFibGUpDQogIG1heF92YWx1ZSA8LSBtYXgodmFyaWFibGUpDQogIA0KICByZXN1bHQgPC0gbGlzdCgNCiAgICBNZWFuID0gbWVhbl92YWx1ZSwNCiAgICBTRCA9IHNkX3ZhbHVlLA0KICAgIE1pbiA9IG1pbl92YWx1ZSwNCiAgICBNYXggPSBtYXhfdmFsdWUNCiAgKQ0KICANCiAgcmV0dXJuKHJlc3VsdCkNCn0NCg0KIyMjIyBmdW5jdGlvbiB0byByZS1jb2RlIGFudGlwc3ljaG90aWMgbWVkaWNhdGlvbiBjb2RlcyB0byBuYW1lcyAjIyMjDQpyZWNvZGVfc2VsZWN0ZWRfY29kZXMgPC0gZnVuY3Rpb24oZGYsIHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlKSB7DQogICMgQ3JlYXRlIGEgZnVuY3Rpb24gdG8gbWFwIHRoZSByZWNvZGVfdmVjdG9yIHRvIGNhc2Vfd2hlbg0KICByZWNvZGVfY2FzZV93aGVuIDwtIGZ1bmN0aW9uKHgsIHJlY29kZV92ZWN0b3IpIHsNCiAgICBkcGx5cjo6Y2FzZV93aGVuKA0KICAgICAgeCAlaW4lIG5hbWVzKHJlY29kZV92ZWN0b3IpIH4gcmVjb2RlX3ZlY3Rvclthcy5jaGFyYWN0ZXIoeCldLA0KICAgICAgVFJVRSB+IGFzLmNoYXJhY3Rlcih4KQ0KICAgICkNCiAgfQ0KICAjIFJlY29kZSBzcGVjaWZpZWQgY29sdW1ucyBiYXNlZCBvbiB0aGUgcmVjb2RlX3ZlY3Rvcg0KICBkZl9yZWNvZGVkIDwtIGRmICU+JQ0KICAgIG11dGF0ZShhY3Jvc3MoYWxsX29mKGNvbHVtbnNfdG9fcmVjb2RlKSwgfiByZWNvZGVfY2FzZV93aGVuKC54LCByZWNvZGVfdmVjdG9yKSkpDQogIHJldHVybihkZl9yZWNvZGVkKQ0KfQ0KDQojIyMjIGZ1bmN0aW9uIHRvIGNvbnZlcnQgZHJ1Z3MgaW50byBjcHotZXEgcmVnYXJkbGVzcyBvZiBhZG1pbiAjIyMjDQpjb252ZXJ0IDwtIGZ1bmN0aW9uKGRmLCB4LCB5KXsNCiAgDQogIGRmJGFkbWluIDwtIGlmZWxzZShpcy5uYShkZiRhZG1pbiksICJOQV92YWx1ZSIsIGRmJGFkbWluKQ0KICBhZG1pbl92YWx1ZXMgPC0gdW5pcXVlKGRmJGFkbWluW2RmJGFkbWluICE9ICJOQV92YWx1ZSJdKQ0KICANCiAgIyBEZWZpbmUgdGhlIGNvbW1hbmRzIGZvciBlYWNoIGNvbmRpdGlvbg0KICBpZiAoYWxsKGFkbWluX3ZhbHVlcyA9PSAib3JhbCIpKSB7DQogICAgbWVzc2FnZSgiT25seSBvcmFsIGRydWdzIGZvdW5kLiIpDQogICAgb3JhbCA8LSBmaWx0ZXIoZGYsIGFkbWluID09ICJvcmFsIikNCiAgICBpZiAobnJvdyhvcmFsKSA+IDApIHsNCiAgICAgICMgY29udmVydA0KICAgICAgY3B6X29yYWwgPC0gdG9fY3B6KG9yYWwsIGFwX2xhYmVsID0geCwgZG9zZV9sYWJlbCA9IHksIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlID0gIm9yYWwiLCAga2V5ID0gZ2FyZG5lcl9sZXVjaHQpIA0KICAgICAgY3B6IDwtIGNwel9vcmFsDQogICAgICByZXR1cm4oY3B6KQ0KICAgIH0gZWxzZSB7DQogICAgICBtZXNzYWdlKCJObyBkYXRhIGZvdW5kIGZvciBvcmFsIGRydWdzLiIpDQogICAgICByZXR1cm4oTlVMTCkNCiAgICAgIH0NCiAgICAjIFlvdXIgY29tbWFuZCBmb3IgIm9yYWwiIGdvZXMgaGVyZQ0KICB9IGVsc2UgaWYgKGFsbChhZG1pbl92YWx1ZXMgPT0gImxhaSIpKSB7DQogICAgbWVzc2FnZSgiT25seSBMQUkgZHJ1Z3MgZm91bmQuIikNCiAgICBkZXBvdCA8LSBmaWx0ZXIoZGYsIGFkbWluID09ICJsYWkiKQ0KICAgIGlmIChucm93KGRlcG90KSA+IDApIHsNCiAgICAgICMgY29udmVydA0KICAgICAgY3B6X2RlcG90IDwtIHRvX2NweihkZXBvdCwgYXBfbGFiZWwgPSB4LCBkb3NlX2xhYmVsID0geSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJvdXRlID0gImxhaSIsIHFfbGFiZWwgPSAxLCBrZXkgPSBnYXJkbmVyX2xldWNodCkgDQogICAgICBjcHogPC0gY3B6X2RlcG90DQogICAgICByZXR1cm4oY3B6KQ0KICAgIH0gZWxzZSB7DQogICAgICBtZXNzYWdlKCJObyBkYXRhIGZvdW5kIGZvciBMQUkgZHJ1Z3MuIikNCiAgICAgIHJldHVybihOVUxMKQ0KICAgIH0NCiAgfSBlbHNlIGlmIChhbGwoYWRtaW5fdmFsdWVzICVpbiUgYygib3JhbCIsICJsYWkiKSkpIHsNCiAgICBtZXNzYWdlKCJPcmFsIGFuZCBMQUkgZHJ1Z3MgZm91bmQuIikNCiAgICAjIHNwbGl0IGJ5IHJvdXRlDQogICAgb3JhbCA8LSBmaWx0ZXIoZGYsIGFkbWluID09ICJvcmFsIikNCiAgICBkZXBvdCA8LSBmaWx0ZXIoZGYsIGFkbWluID09ICJsYWkiKQ0KICAgIA0KICAgIGlmIChucm93KG9yYWwpID4gMCAmIG5yb3coZGVwb3QpID4gMCkgew0KICAgICAgIyBjb252ZXJ0DQogICAgICBjcHpfb3JhbCA8LSB0b19jcHoob3JhbCwgYXBfbGFiZWwgPSB4LCBkb3NlX2xhYmVsID0geSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgcm91dGUgPSAib3JhbCIsICBrZXkgPSBnYXJkbmVyMjAxMCkgDQogICAgICBjcHpfZGVwb3QgPC0gdG9fY3B6KGRlcG90LCBhcF9sYWJlbCA9IHgsIGRvc2VfbGFiZWwgPSB5LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgcm91dGUgPSAibGFpIiwgcV9sYWJlbCA9IDEsIGtleSA9IGdhcmRuZXJfbGV1Y2h0KSANCiAgICAgIGNweiA8LSByYmluZChjcHpfb3JhbCwgY3B6X2RlcG90KSANCiAgICAgIHJldHVybihjcHopDQogICAgfSBlbHNlIHsNCiAgICAgIG1lc3NhZ2UoIk5vIGRhdGEgZm91bmQgZm9yIG9uZSBvciBib3RoIHJvdXRlcy4iKQ0KICAgICAgcmV0dXJuKE5VTEwpDQogICAgfQ0KICB9IA0KICBlbHNlIHsNCiAgICBtZXNzYWdlKCJVbmV4cGVjdGVkIHZhbHVlcyBpbiAnYWRtaW4nIGNvbHVtbi4iKQ0KICB9DQp9DQoNCiMjIyMgZXh0cmFjdCBjb3JlIGZpdCBtZWFzdXJlcyBmcm9tIGxhdmFhbiBvYmplY3QgIyMjIw0KY29yZV9maXRtZWFzdXJlcyA8LSBmdW5jdGlvbihmaXQgPSBmaXQsIGZpdGluZGljaWVzPXYkZml0aW5kaWNpZXMsIGRpZ2l0cz0zKSB7DQogIHggPC0gZml0bWVhc3VyZXMoZml0KQ0KICByb3VuZCh4W2ZpdGluZGljaWVzXSwgZGlnaXRzKQ0KfQ0KDQojIyMjIGFkZCByb3cgdG8gZGYgIyMjIw0KaW5zZXJ0Um93MiA8LSBmdW5jdGlvbihleGlzdGluZ0RGLCBuZXdyb3csIHIpIHsNCiAgZXhpc3RpbmdERiA8LSByYmluZChleGlzdGluZ0RGLG5ld3JvdykNCiAgZXhpc3RpbmdERiA8LSBleGlzdGluZ0RGW29yZGVyKGMoMToobnJvdyhleGlzdGluZ0RGKS0xKSxyLTAuNSkpLF0NCiAgcm93Lm5hbWVzKGV4aXN0aW5nREYpIDwtIDE6bnJvdyhleGlzdGluZ0RGKQ0KICByZXR1cm4oZXhpc3RpbmdERikgIA0KfQ0KDQpgYGANCg0KDQpgYGB7ciBsb2FkIHBhY2thZ2VzLCBpbmNsdWRlPUZBTFNFfQ0KIyBzZXQgd29ya2luZyBkaXJldG9yeQ0Kc2V0d2QoZGlyID0gIkQ6L3Npb2JoL0RvY3VtZW50cy9VbmkvUGhEL1kxL1N5bXB0b21zIFByb2plY3Qvc3ltcHRvbXMtY29ncy8iKQ0KDQojIGxvYWQgcmVxdWlyZWQgcGFja2FnZXMNCmxpYnJhcnkoaGF2ZW4pDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dwdWJyKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoa2FibGVFeHRyYSkNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KHRpZHlzZWxlY3QpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoZGF0YXdpemFyZCkNCmxpYnJhcnkoYXJzZW5hbCkNCmxpYnJhcnkoQUVSKQ0KbGlicmFyeShjaGxvcnByb21hemluZVIpDQpsaWJyYXJ5KHNqUGxvdCkNCmxpYnJhcnkodGhlbWF0aWMpDQpsaWJyYXJ5KGxhdmFhbikNCmxpYnJhcnkobGF2YWFuUGxvdCkNCmxpYnJhcnkoc2VtcHRvb2xzKQ0KbGlicmFyeShzZW1QbG90KQ0KbGlicmFyeShmbGV4dGFibGUpDQpsaWJyYXJ5KGd0c3VtbWFyeSkNCmxpYnJhcnkoc2hpbnkpDQpsaWJyYXJ5KGdzdWJmbikNCmxpYnJhcnkocnZlc3QpDQpsaWJyYXJ5KHBoZW5vY29udmVydGVyKQ0KYGBgDQoNCmBgYHtyIGxvYWQgQ2FyZGlmZkNPR1MgZGF0YX0NCiMgbG9hZCBpbiBDYXJkaWZmQ09HUyBkYXRhc2V0DQpwaGVubyA8LSByZWFkX3NhdigiQ29tcGxldGUgQ2FyZGlmZkNvZ3MgMjAyMi5zYXYiKQ0KDQojIGxvYWQgaW4gc2FtcGxlcyB3aXRoIGdlbmV0aWMgaW5mb3JtYXRpb24NCmdlbm8gPC0gIHJlYWQuZGVsaW0oImdlbmV0aWMuaWRzIiwgaGVhZGVyID0gRikNCg0KIyBmaWx0ZXIgdG8gdGhvc2Ugd2l0aCBwaGVub3R5cGUgYW5kIGdlbm90eXBlIGluZm9ybWF0aW9uDQpwaGVubyA8LSBwaGVub1twaGVubyRTdHVkeV9JRCAlaW4lIGdlbm8kVjEsIF0gIyANCg0KIyBpbmNsdXNpb24gY3JpdGVyaWENCnBoZW5vIDwtIHBoZW5vICU+JQ0KICAjIGZpbHRlciB0byBwZW9wbGUgd2l0aCBzY2hpem9waHJlbmlhIG9yIHNjaGl6b2FmZmVjdGl2ZSBkaXNvcmRlciBkZXByZXNzZWQgdHlwZS4NCiAgZmlsdGVyKFNaX1NaQUZGREVQX2RpYWcgPT0gMSkgJT4lDQogICMgcmVtb3ZlIGluZGl2aWR1YWxzIHdpdGggaW5hcHByb3ByaWF0ZSByYXRpbmdzIChhYm92ZSAzIG9uIENhbGdhcnksIGFib3ZlIDUgb24gU0FQcy9TQU5TKSBvciBOQSB2YWx1ZXMgaW4gcGhlbm90eXBlIG1lYXN1cmVzLiANCiAgc3Vic2V0KENhbGdhcnlfRGVwcmVzc2lvbiA8NCkgJT4lICAgDQogIHN1YnNldChDYWxnYXJ5X1N1aWNpZGUgPDQpICU+JSAgIA0KICBzdWJzZXQoU0FQU19HbG9iYWxfSGFscyA8NikgJT4lDQogIHN1YnNldChTQVBTX0dsb2JhbF9EZWx1c2lvbnMgPDYpICU+JQ0KICBzdWJzZXQoU0FOU19HbG9iYWxfQWxvZ2lhIDw2KSAlPiUNCiAgc3Vic2V0KFNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IDw2KSAlPiUNCiAgc3Vic2V0KFNBTlNfR2xvYmFsX0FmZmVjdGl2ZV9GbGF0dGVuaW5nIDw2KSAlPiUNCiAgc3Vic2V0KFNBTlNfR2xvYmFsX0F2b2xpdGlvbl9BcGF0aHkgPDYpICU+JQ0KICBzdWJzZXQoIWlzLm5hKFpOQUJfTWF6ZXNfSW1wKSkgJT4lDQogIHN1YnNldCghaXMubmEoWkhWTFRfSW1wKSkgJT4lDQogIHN1YnNldCghaXMubmEoWkJWTVRfSW1wKSkgJT4lDQogIHN1YnNldCghaXMubmEoWkNQVF9JbXApKSAlPiUNCiAgc3Vic2V0KCFpcy5uYShaU29QX0ltcCkpICU+JQ0KICBzdWJzZXQoIWlzLm5hKFpXTV9JbXApKSAlPiUNCiAgIyByZW1vdmUgaW5kaXZpZHVhbHMgd2l0aCBtaXNzaW5nIG1lZGljYXRpb24gaW5mb3JtYXRpb24uDQogIHN1YnNldChBUF9kb3NlICE9IDk5OTkpICU+JSAjIGRvc2UgdW5rbm93bg0KICBzdWJzZXQoQVBfZG9zZSAhPSA3Nzc3KSAlPiUgIyBwcm8gcmUgbmF0YQ0KICBzdWJzZXQoQW50aXBzeWNob3RpYyAhPSA4OSkgJT4lICMgYW50aXBzeWNob3RpYyBuYW1lIHVua25vd24NCiAgc3Vic2V0KCFpcy5uYShBZGhlcmVuY2UpKQ0KDQojIGV4Y2x1ZGUgSURzIGluIENhcmRpZmZDT0dTIHRoYXQgYXJlIGFsc28gcHJlc2VudCBpbiBDTE9aVUsyLzMgb3Igd2l0aCBtaXNzaW5nIGRvc2UgaW5mb3JtYXRpb24gaW4gMm5kIG9yIDNyZCBhbnRpcHN5Y2hvdGljcw0KcmVtb3ZlXzEgPC0gcmVhZC5kZWxpbSgicHJzL0NMT1pVSzIzX0NhcmRpZmZDT0dTX292ZXJsYXBzLnR4dCIsIGhlYWRlciA9IEYpDQpyZW1vdmVfMiA8LSByZWFkLmRlbGltKCJtaXNzaW5nX2Rvc2UuaWRzIiwgaGVhZGVyID0gRikNCnJlbW92ZSA8LSByYmluZChyZW1vdmVfMSwgcmVtb3ZlXzIpDQpyZW1vdmVfaWRzIDwtIHVuaXF1ZShyZW1vdmUkVjEpDQpwaGVubyA8LSBwaGVub1shcGhlbm8kU3R1ZHlfSUQgJWluJSByZW1vdmVfaWRzLCBdDQoNCnJtKHJlbW92ZV8xLCByZW1vdmVfMiwgcmVtb3ZlLCByZW1vdmVfaWRzKQ0KDQojIGV4dHJhY3QgSURzIGZvciBjYWxjdWxhdGluZyBnZW5ldGljIFBDcw0KIyBpZHMgPC0gcGhlbm9bMV0NCiMgaWRzJFN0dWR5X0lEMiA8LSBpZHMkU3R1ZHlfSUQNCiMgd3JpdGVfdHN2KHggPSBpZHMsIGZpbGUgPSAiQ09HU19TWl9TWkFGRi5pZHMiLCBjb2xfbmFtZXMgPSBGKSANCg0KYGBgDQoNCmBgYHtyIGZpbmQgbnVtYmVyIGV4Y2x1ZGVkIGZvciBpbmNvbXBsZXRlIG1lZHMsIGluY2x1ZGUgPSBGQUxTRX0NCmEgPC0gcmVhZF9zYXYoIkNvbXBsZXRlIENhcmRpZmZDb2dzIDIwMjIuc2F2IikNCg0KYSA8LSBhW2EkU3R1ZHlfSUQgJWluJSBnZW5vJFYxLCBdICMgDQoNCmEgPC0gYSAlPiUNCiAgZmlsdGVyKFNaX1NaQUZGREVQX2RpYWcgPT0gMSkgJT4lDQogIHN1YnNldChDYWxnYXJ5X0RlcHJlc3Npb24gPDQpICU+JSAgIA0KICBzdWJzZXQoQ2FsZ2FyeV9TdWljaWRlIDw0KSAlPiUgICANCiAgc3Vic2V0KFNBUFNfR2xvYmFsX0hhbHMgPDYpICU+JQ0KICBzdWJzZXQoU0FQU19HbG9iYWxfRGVsdXNpb25zIDw2KSAlPiUNCiAgc3Vic2V0KFNBTlNfR2xvYmFsX0Fsb2dpYSA8NikgJT4lDQogIHN1YnNldChTQU5TX0dsb2JhbF9BbmhlZG9uaWFfQXNvY2lhbGl0eSA8NikgJT4lDQogIHN1YnNldChTQU5TX0dsb2JhbF9BZmZlY3RpdmVfRmxhdHRlbmluZyA8NikgJT4lDQogIHN1YnNldChTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5IDw2KSAlPiUNCiAgc3Vic2V0KCFpcy5uYShaTkFCX01hemVzX0ltcCkpICU+JQ0KICBzdWJzZXQoIWlzLm5hKFpIVkxUX0ltcCkpICU+JQ0KICBzdWJzZXQoIWlzLm5hKFpCVk1UX0ltcCkpICU+JQ0KICBzdWJzZXQoIWlzLm5hKFpDUFRfSW1wKSkgJT4lDQogIHN1YnNldCghaXMubmEoWlNvUF9JbXApKSAlPiUNCiAgc3Vic2V0KCFpcy5uYShaV01fSW1wKSkNCg0KcmVtb3ZlIDwtIHJlYWQuZGVsaW0oInBycy9DTE9aVUsyM19DYXJkaWZmQ09HU19vdmVybGFwcy50eHQiLCBoZWFkZXIgPSBGKQ0KcmVtb3ZlX2lkcyA8LSB1bmlxdWUocmVtb3ZlJFYxKQ0KYSA8LSBhWyFhJFN0dWR5X0lEICVpbiUgcmVtb3ZlX2lkcywgXQ0KDQpiIDwtIGEgJT4lDQogIHN1YnNldChBUF9kb3NlICE9IDk5OTkpICU+JQ0KICBzdWJzZXQoQVBfZG9zZSAhPSA3Nzc3KSAlPiUNCiAgc3Vic2V0KEFudGlwc3ljaG90aWMgIT0gODkpICU+JSANCiAgc3Vic2V0KCFpcy5uYShBZGhlcmVuY2UpKQ0KDQpyZW1vdmUgPC0gcmVhZC5kZWxpbSgibWlzc2luZ19kb3NlLmlkcyIsIGhlYWRlciA9IEYpDQpyZW1vdmVfaWRzIDwtIHVuaXF1ZShyZW1vdmUkVjEpDQpiIDwtIGJbIWIkU3R1ZHlfSUQgJWluJSByZW1vdmVfaWRzLCBdDQoNCm5fZXhjbCA8LSBucm93KGEpIC0gbnJvdyhiKSANCg0KcmVtb3ZlKGEsIGIsIHJlbW92ZSwgcmVtb3ZlX2lkcywgZ2VubykNCmBgYA0KDQoNCg0KYGBge3IgbG9hZCBweXBneCBwZ3ggZGF0YSwgaW5jbHVkZT1GQUxTRX0NCg0KIyMjIyAxYTIgIyMjIw0KcHlwZ3hfMWEyIDwtICByZWFkX2RlbGltKCJwZ3gvcHlwZ3gvY3lwMWEyLnRzdiIsZGVsaW09Ilx0IiwgY29sX25hbWVzID0gYygiU3R1ZHlfSUQiLCAiR2Vub3R5cGUiLCAiUGhlbm90eXBlIiwgIkhhcGxvdHlwZTEiLCAiSGFwbG90eXBlMiIsICJBbHRlcm5hdGl2ZVBoYXNlIiwgIlZhcmlhbnREYXRhIiwgIkNOViIpKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgxOjUpDQpweXBneF8xYTIgPC0gIHB5cGd4XzFhMlstMSxdDQoNCiMjIyMgMmQ2ICMjIyMNCnB5cGd4XzJkNiA8LSAgcmVhZF9kZWxpbSgicGd4L3B5cGd4L2N5cDJkNi50c3YiLGRlbGltPSJcdCIsIGNvbF9uYW1lcyA9IGMoIlN0dWR5X0lEIiwgIkdlbm90eXBlIiwgIlBoZW5vdHlwZSIsICJIYXBsb3R5cGUxIiwgIkhhcGxvdHlwZTIiLCAiQWx0ZXJuYXRpdmVQaGFzZSIsICJWYXJpYW50RGF0YSIsICJDTlYiKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoMTo1KQ0KcHlwZ3hfMmQ2IDwtICBweXBneF8yZDZbLTEsXQ0KDQpweXBneF8yZDYkUGhlbm90eXBlPC1nc3ViKCJNZXRhYm9saXplciIsIm1ldGFib2xpc2VyIixhcy5jaGFyYWN0ZXIocHlwZ3hfMmQ2JFBoZW5vdHlwZSkpDQoNCiMjIyMgMmM5ICMjIyMNCnB5cGd4XzJjOSA8LSAgcmVhZF9kZWxpbSgicGd4L3B5cGd4L2N5cDJjOS50c3YiLGRlbGltPSJcdCIsIGNvbF9uYW1lcyA9IGMoIlN0dWR5X0lEIiwgIkdlbm90eXBlIiwgIlBoZW5vdHlwZSIsICJIYXBsb3R5cGUxIiwgIkhhcGxvdHlwZTIiLCAiQWx0ZXJuYXRpdmVQaGFzZSIsICJWYXJpYW50RGF0YSIsICJDTlYiKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoMTo1KQ0KcHlwZ3hfMmM5IDwtICBweXBneF8yYzlbLTEsXQ0KDQpweXBneF8yYzkkUGhlbm90eXBlPC1nc3ViKCJNZXRhYm9saXplciIsIm1ldGFib2xpc2VyIixhcy5jaGFyYWN0ZXIocHlwZ3hfMmM5JFBoZW5vdHlwZSkpDQoNCiMjIyMgMmMxOSAjIyMjDQpweXBneF8yYzE5IDwtICByZWFkX2RlbGltKCJwZ3gvcHlwZ3gvY3lwMmMxOS50c3YiLGRlbGltPSJcdCIsIGNvbF9uYW1lcyA9IGMoIlN0dWR5X0lEIiwgIkdlbm90eXBlIiwgIlBoZW5vdHlwZSIsICJIYXBsb3R5cGUxIiwgIkhhcGxvdHlwZTIiLCAiQWx0ZXJuYXRpdmVQaGFzZSIsICJWYXJpYW50RGF0YSIsICJDTlYiKSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoMTo1KQ0KcHlwZ3hfMmMxOSA8LSAgcHlwZ3hfMmMxOVstMSxdDQoNCnB5cGd4XzJjMTkkUGhlbm90eXBlPC1nc3ViKCJNZXRhYm9saXplciIsIm1ldGFib2xpc2VyIixhcy5jaGFyYWN0ZXIocHlwZ3hfMmMxOSRQaGVub3R5cGUpKQ0KDQojIyMjIDNhNSAjIyMjDQpweXBneF8zYTUgPC0gIHJlYWRfZGVsaW0oInBneC9weXBneC9jeXAzYTUudHN2IixkZWxpbT0iXHQiLCBjb2xfbmFtZXMgPSBjKCJTdHVkeV9JRCIsICJHZW5vdHlwZSIsICJQaGVub3R5cGUiLCAiSGFwbG90eXBlMSIsICJIYXBsb3R5cGUyIiwgIkFsdGVybmF0aXZlUGhhc2UiLCAiVmFyaWFudERhdGEiLCAiQ05WIikpICU+JQ0KICBkcGx5cjo6c2VsZWN0KDE6NSkNCnB5cGd4XzNhNSA8LSAgcHlwZ3hfM2E1Wy0xLF0NCnB5cGd4XzNhNSRQaGVub3R5cGU8LWdzdWIoIk1ldGFib2xpemVyIiwibWV0YWJvbGlzZXIiLGFzLmNoYXJhY3RlcihweXBneF8zYTUkUGhlbm90eXBlKSkNCg0KDQpgYGANCg0KYGBge3IgY3lwMWEyIGFjdGl2aXR5IHNjb3JlcywgaW5jbHVkZT1GQUxTRX0NCiMgY3JlYXRlIGNvbHVtbnMgZm9yIGExIGFuZCBjbGVhbiBoYXBsb3R5cGUNCnB5cGd4XzFhMiRzY29yZTEgPSBOQQ0KcHlwZ3hfMWEyJEhhcGxvdHlwZTE8LWdzdWIoIjsiLCIiLGFzLmNoYXJhY3RlcihweXBneF8xYTIkSGFwbG90eXBlMSkpDQoNCiMgYXNzaWduIGFzIGZvciBhMQ0KcHlwZ3hfMWEyJHNjb3JlMVtweXBneF8xYTIkSGFwbG90eXBlMSA9PSIqMUEiXSA8LSAxDQpweXBneF8xYTIkc2NvcmUxW3B5cGd4XzFhMiRIYXBsb3R5cGUxPT0iKjFGIl0gPC0gMS41DQpweXBneF8xYTIkc2NvcmUxW3B5cGd4XzFhMiRIYXBsb3R5cGUxPT0iKjFDIl0gPC0gMC41DQpweXBneF8xYTIkc2NvcmUxW3B5cGd4XzFhMiRIYXBsb3R5cGUxPT0iKjFLIl0gPC0gMC41DQpweXBneF8xYTIkc2NvcmUxW3B5cGd4XzFhMiRIYXBsb3R5cGUxPT0iKjFDKjFGIl0gPC0gMQ0KDQojIGNyZWF0ZSBjb2x1bW5zIGZvciBhMiBhbmQgY2xlYW4gaGFwbG90eXBlDQpweXBneF8xYTIkc2NvcmUyID0gTkENCnB5cGd4XzFhMiRIYXBsb3R5cGUyPC1nc3ViKCI7IiwiIixhcy5jaGFyYWN0ZXIocHlwZ3hfMWEyJEhhcGxvdHlwZTIpKQ0KDQojIGFzc2lnbiAgYXMgZm9yIGEyDQpweXBneF8xYTIkc2NvcmUyW3B5cGd4XzFhMiRIYXBsb3R5cGUyID09IioxQSJdIDwtIDENCnB5cGd4XzFhMiRzY29yZTJbcHlwZ3hfMWEyJEhhcGxvdHlwZTI9PSIqMUYiXSA8LSAxLjUNCnB5cGd4XzFhMiRzY29yZTJbcHlwZ3hfMWEyJEhhcGxvdHlwZTI9PSIqMUMiXSA8LSAwLjUNCnB5cGd4XzFhMiRzY29yZTJbcHlwZ3hfMWEyJEhhcGxvdHlwZTI9PSIqMUsiXSA8LSAwLjUNCnB5cGd4XzFhMiRzY29yZTJbcHlwZ3hfMWEyJEhhcGxvdHlwZTI9PSIqMUMqMUYiXSA8LSAxDQoNCiMgZ2l2ZSB0b3RhbCBhcw0KcHlwZ3hfMWEyJGVzdF9zY29yZSA9IHB5cGd4XzFhMiRzY29yZTEgKyBweXBneF8xYTIkc2NvcmUyDQoNCmBgYA0KDQpgYGB7ciBhY3Rpdml0eSBzY29yZXMgY3lwMmQ2LCBpbmNsdWRlPUZBTFNFfQ0KIyB1c2luZyBhbGxlbGUgdGFibGUgZnJvbSBweXBneCBhcGkvZGF0YSBvbiBnaXRodWIgMTAvMTEvMjMNCiMgcHlwZ3gvcHlwZ3gvYXBpL2RhdGEvYWxsZWxlLXRhYmxlLmNzdg0KDQojIHNwbGl0IGdlbm90eXBlIGNvbHVtbg0KcHlwZ3hfMmQ2IDwtIHNlcGFyYXRlKHB5cGd4XzJkNiwgY29sPUdlbm90eXBlLCBpbnRvPWMoJ0dlbm8xJywgJ0dlbm8yJyksIHNlcD0nLycsIHJlbW92ZSA9IEYpDQoNCiMgY3JlYXRlIGNvbHVtbnMNCnB5cGd4XzJkNiRzY29yZTEgPSBOQQ0KcHlwZ3hfMmQ2JHNjb3JlMiA9IE5BDQpweXBneF8yZDYkZXN0X3Njb3JlID0gTkENCg0KIyBhc3NpZ24gYXMgZm9yIGExDQpweXBneF8yZDYkc2NvcmUxW3B5cGd4XzJkNiRHZW5vMSA9PSAiKjEiXSA8LSAxICMgbm9ybWFsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmQ2JHNjb3JlMVtweXBneF8yZDYkR2VubzEgPT0gIioxMCJdIDwtIDAuMjUgIyBkZWNyZWFzZWQgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yZDYkc2NvcmUxW3B5cGd4XzJkNiRHZW5vMSA9PSAiKjE3Il0gPC0gMC41ICMgZGVjcmVhc2VkIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmQ2JHNjb3JlMVtweXBneF8yZDYkR2VubzEgPT0gIioyIl0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTFbcHlwZ3hfMmQ2JEdlbm8xID09ICIqMjgiXSA8LSBOQSAjIHVuY2VydGFpbiBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTFbcHlwZ3hfMmQ2JEdlbm8xID09ICIqMzUiXSA8LSAxICMgbm9ybWFsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmQ2JHNjb3JlMVtweXBneF8yZDYkR2VubzEgPT0gIio0Il0gPC0gMCAjIG51bGwgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yZDYkc2NvcmUxW3B5cGd4XzJkNiRHZW5vMSA9PSAiKjQxIl0gPC0gMC41ICMgZGVjcmVhc2VkIGZ1bmN0aW9uIGFsbGVsZQ0KDQojIGFzc2lnbiBhcyBmb3IgYTINCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqMSJdIDwtIDEgIyBub3JtYWwgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yZDYkc2NvcmUyW3B5cGd4XzJkNiRHZW5vMiA9PSAiKjEwIl0gPC0gMC4yNSAjIGRlY3JlYXNlZCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqMTciXSA8LSAwLjUgIyBkZWNyZWFzZWQgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yZDYkc2NvcmUyW3B5cGd4XzJkNiRHZW5vMiA9PSAiKjExNyJdIDwtIE5BICMgdW5jZXJ0YWluIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmQ2JHNjb3JlMltweXBneF8yZDYkR2VubzIgPT0gIioyIl0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqMjgiXSA8LSBOQSAjIHVuY2VydGFpbiBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqMjkiXSA8LSAwLjUgIyBkZWNyZWFzZWQgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yZDYkc2NvcmUyW3B5cGd4XzJkNiRHZW5vMiA9PSAiKjM1Il0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqNCJdIDwtIDAgIyBudWxsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmQ2JHNjb3JlMltweXBneF8yZDYkR2VubzIgPT0gIio0MSJdIDwtIDAuNSAjIGRlY3JlYXNlZCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqNDUiXSA8LSAxICMgbm9ybWFsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmQ2JHNjb3JlMltweXBneF8yZDYkR2VubzIgPT0gIio1OSJdIDwtIDAuNSAjIGRlY3JlYXNlZCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJkNiRzY29yZTJbcHlwZ3hfMmQ2JEdlbm8yID09ICIqNjUiXSA8LSBOQSAjIHVuY2VydGFpbiBmdW5jdGlvbiBhbGxlbGUNCg0KIyBnaXZlIHRvdGFsIGFzDQpweXBneF8yZDYkZXN0X3Njb3JlIDwtIHB5cGd4XzJkNiRzY29yZTEgKyBweXBneF8yZDYkc2NvcmUyDQoNCmBgYA0KDQpgYGB7ciBhY3Rpdml0eSBzY29yZXMgY3lwMmM5LCBpbmNsdWRlPUZBTFNFfQ0KIyB1c2luZyBhbGxlbGUgdGFibGUgZnJvbSBweXBneCBhcGkvZGF0YSBvbiBnaXRodWIgMTAvMTEvMjMNCiMgcHlwZ3gvcHlwZ3gvYXBpL2RhdGEvYWxsZWxlLXRhYmxlLmNzdg0KDQojIHNwbGl0IGdlbm90eXBlIGNvbHVtbg0KcHlwZ3hfMmM5IDwtIHNlcGFyYXRlKHB5cGd4XzJjOSwgY29sPUdlbm90eXBlLCBpbnRvPWMoJ0dlbm8xJywgJ0dlbm8yJyksIHNlcD0nLycsIHJlbW92ZSA9IEYpDQoNCiMgY3JlYXRlIGNvbHVtbnMNCnB5cGd4XzJjOSRzY29yZTEgPSBOQQ0KcHlwZ3hfMmM5JHNjb3JlMiA9IE5BDQpweXBneF8yYzkkZXN0X3Njb3JlID0gTkENCg0KIyBhc3NpZ24gYXMgZm9yIGExDQpweXBneF8yYzkkc2NvcmUxW3B5cGd4XzJjOSRHZW5vMSA9PSAiKjEiXSA8LSAxICMgbm9ybWFsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmM5JHNjb3JlMVtweXBneF8yYzkkR2VubzEgPT0gIioyIl0gPC0gMC41ICMgZGVjcmVhc2VkIGZ1bmN0aW9uDQpweXBneF8yYzkkc2NvcmUxW3B5cGd4XzJjOSRHZW5vMSA9PSAiKjMiXSA8LSAwICMgbm8gZnVuY3Rpb24NCnB5cGd4XzJjOSRzY29yZTFbcHlwZ3hfMmM5JEdlbm8xID09ICIqMTEiXSA8LSAwLjUgIyBkZWNyZWFzZWQgZnVuY3Rpb24NCg0KIyBhc3NpZ24gYXMgZm9yIGEyDQpweXBneF8yYzkkc2NvcmUyW3B5cGd4XzJjOSRHZW5vMiA9PSAiKjEiXSA8LSAxICMgbm9ybWFsIGZ1bmN0aW9uDQpweXBneF8yYzkkc2NvcmUyW3B5cGd4XzJjOSRHZW5vMiA9PSAiKjIiXSA8LSAwLjUgIyBkZWNyZWFzZWQgZnVuY3Rpb24NCnB5cGd4XzJjOSRzY29yZTJbcHlwZ3hfMmM5JEdlbm8yID09ICIqMyJdIDwtIDAgICMgbnVsbCBmdW5jdGlvbg0KcHlwZ3hfMmM5JHNjb3JlMltweXBneF8yYzkkR2VubzIgPT0gIio5Il0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbg0KcHlwZ3hfMmM5JHNjb3JlMltweXBneF8yYzkkR2VubzIgPT0gIioxMSJdIDwtIDAuNSAjIGRlY3JlYXNlZCBmdW5jdGlvbg0KcHlwZ3hfMmM5JHNjb3JlMltweXBneF8yYzkkR2VubzIgPT0gIioxMiJdIDwtIDAuNSAjIGRlY3JlYXNlZCBmdW5jdGlvbg0KDQojIGdpdmUgdG90YWwgYXMNCnB5cGd4XzJjOSRlc3Rfc2NvcmUgPC0gcHlwZ3hfMmM5JHNjb3JlMSArIHB5cGd4XzJjOSRzY29yZTINCg0KYGBgDQoNCmBgYHtyIGFjdGl2aXR5IHNjb3JlcyBjeXAyYzE5LCBpbmNsdWRlPUZBTFNFfQ0KIyBhY3Rpdml0eSBzY29yZXMgZm9yICoxICgxLjApLCAqMiAoMCksICoxNyAoMS41KSBvYnRhaW5lZCBmcm9tIExlc2NoZSBldCBhbC4sIDIwMTkgLg0KIyBhY3Rpdml0eSBzY29yZXMgZm9yICo4IChudWxsID0gMCksICoxMSAobm9ybWFsID0gMSksICoxMyAobm9ybWFsID0gMSksICoxNSAobm9ybWFsID0gMSkgaW5mZXJyZWQgZnJvbSBhbGxlbGUgZnVuY3Rpb24gaW4gQ1BJQyBQaGFybUdLQiBDWVAyQzE5IGFsbGVsZSBmdW5jdGlvbmFsaXR5IHJlZmVyZW5jZSAoaHR0cHM6Ly93d3cucGhhcm1na2Iub3JnL3BhZ2UvY3lwMmMxOVJlZk1hdGVyaWFscykuIA0KIyB0aGVzZSBhbGwgbWF0Y2ggdXAgd2l0aCB0aGUgYWxsZWxlIGZ1bmN0aW9ucyBpbiB0aGUgcHlwZ3ggYWxsZWxlIHRhYmxlLg0KDQojIHNwbGl0IGdlbm90eXBlIGNvbHVtbg0KcHlwZ3hfMmMxOSA8LSBzZXBhcmF0ZShweXBneF8yYzE5LCBjb2w9R2Vub3R5cGUsIGludG89YygnR2VubzEnLCAnR2VubzInKSwgc2VwPScvJywgcmVtb3ZlID0gRikNCg0KIyBjcmVhdGUgY29sdW1ucw0KcHlwZ3hfMmMxOSRzY29yZTEgPSBOQQ0KcHlwZ3hfMmMxOSRzY29yZTIgPSBOQQ0KcHlwZ3hfMmMxOSRlc3Rfc2NvcmUgPSBOQQ0KDQojIGFzc2lnbiBhcyBmb3IgYTENCnB5cGd4XzJjMTkkc2NvcmUxW3B5cGd4XzJjMTkkR2VubzEgPT0gIioxIl0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJjMTkkc2NvcmUxW3B5cGd4XzJjMTkkR2VubzEgPT0gIioxNSJdIDwtIDEgIyBub3JtYWwgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yYzE5JHNjb3JlMVtweXBneF8yYzE5JEdlbm8xID09ICIqMTciXSA8LSAxLjUgIyBpbmNyZWFzZWQgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yYzE5JHNjb3JlMVtweXBneF8yYzE5JEdlbm8xID09ICIqMiJdIDwtIDAgIyBudWxsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmMxOSRzY29yZTFbcHlwZ3hfMmMxOSRHZW5vMSA9PSAiKjgiXSA8LSAwICMgbnVsbCBmdW5jdGlvbiBhbGxlbGUNCg0KIyBhc3NpZ24gYXMgZm9yIGEyDQpweXBneF8yYzE5JHNjb3JlMltweXBneF8yYzE5JEdlbm8yID09ICIqMSJdIDwtIDEgIyBub3JtYWwgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yYzE5JHNjb3JlMltweXBneF8yYzE5JEdlbm8yID09ICIqMTMiXSA8LSAxICMgbm9ybWFsIGZ1bmN0aW9uIGFsbGVsZQ0KcHlwZ3hfMmMxOSRzY29yZTJbcHlwZ3hfMmMxOSRHZW5vMiA9PSAiKjE1Il0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJjMTkkc2NvcmUyW3B5cGd4XzJjMTkkR2VubzIgPT0gIioxNyJdIDwtIDEuNSAjIGluY3JlYXNlZCBmdW5jdGlvbiBhbGxlbGUNCnB5cGd4XzJjMTkkc2NvcmUyW3B5cGd4XzJjMTkkR2VubzIgPT0gIioyIl0gPC0gMCAjIG51bGwgZnVuY3Rpb24gYWxsZWxlDQpweXBneF8yYzE5JHNjb3JlMltweXBneF8yYzE5JEdlbm8yID09ICIqOCJdIDwtIDAgIyBudWxsIGZ1bmN0aW9uIGFsbGVsZQ0KDQpweXBneF8yYzE5JGVzdF9zY29yZSA8LSBweXBneF8yYzE5JHNjb3JlMSArIHB5cGd4XzJjMTkkc2NvcmUyDQpgYGANCg0KYGBge3IgYWN0aXZpdHkgc2NvcmVzIGN5cDNhNSwgaW5jbHVkZT1GQUxTRX0NCg0KIyBhbGxlbGUgZnVuY3Rpb25zIG9idGFpbmVkIGZyb20gQ1BJQyBQaGFybUdLQiBDWVAzQTUgYWxsZWxlIGZ1bmN0aW9uYWxpdHkgcmVmZXJlbmNlIGZpbGUgMTAvMTEvMjMNCiMgYWN0aXZpdHkgc2NvcmVzIGluZmVycmVkIGZyb20gYWxsZWxlIGZ1bmN0aW9uLCBvbmx5IG5vcm1hbCBhbmQgbnVsbCBmdW5jdGlvbiBhbGxlbGVzIGFyZSBwcmVzZW50IHdoaWNoIG1ha2VzIHRoaW5ncyBlYXN5Lg0KIyAxIGFzc2lnbmVkIHRvIG5vcm1hbCBmdW5jdGlvbiBhbGxlbGVzIGFuZCAwIHRvIG51bGwgZnVuY3Rpb24gYWxsZWxlcy4gDQoNCiMgc3BsaXQgZ2Vub3R5cGUgY29sdW1uDQpweXBneF8zYTUgPC0gc2VwYXJhdGUocHlwZ3hfM2E1LCBjb2w9R2Vub3R5cGUsIGludG89YygnR2VubzEnLCAnR2VubzInKSwgc2VwPScvJywgcmVtb3ZlID0gRikNCg0KIyBjcmVhdGUgY29sdW1ucw0KcHlwZ3hfM2E1JHNjb3JlMSA9IE5BDQpweXBneF8zYTUkc2NvcmUyID0gTkENCnB5cGd4XzNhNSRlc3Rfc2NvcmUgPSBOQQ0KDQojIGFzc2lnbiBhcyB0byBhMQ0KcHlwZ3hfM2E1JHNjb3JlMVtweXBneF8zYTUkR2VubzEgPT0gIioxIl0gPC0gMSAjIG5vcm1hbCBmdW5jdGlvbg0KcHlwZ3hfM2E1JHNjb3JlMVtweXBneF8zYTUkR2VubzEgPT0gIiozIl0gPC0gMCAjIG51bGwgZnVuY3Rpb24NCg0KIyBhc3NpZ24gYXMgdG8gYTINCnB5cGd4XzNhNSRzY29yZTJbcHlwZ3hfM2E1JEdlbm8yID09ICIqMSJdIDwtIDEgIyBub3JtYWwgZnVuY3Rpb24NCnB5cGd4XzNhNSRzY29yZTJbcHlwZ3hfM2E1JEdlbm8yID09ICIqMyJdIDwtIDAgIyBudWxsIGZ1bmN0aW9uDQpweXBneF8zYTUkc2NvcmUyW3B5cGd4XzNhNSRHZW5vMiA9PSAiKjYiXSA8LSAwICMgbnVsbCBmdW5jdGlvbg0KDQojIGdpdmUgdG90YWwgYXMNCnB5cGd4XzNhNSRlc3Rfc2NvcmUgPC0gcHlwZ3hfM2E1JHNjb3JlMSArIHB5cGd4XzNhNSRzY29yZTINCmBgYA0KDQpgYGB7ciBjcmVhdGUgY29tYm8gdmFyaWFibGUsIGluY2x1ZGU9RkFMU0V9DQojIG1lcmdlIGFsbCByZWxldmFudCBwZ3ggaW5mb3JtYXRpb24gdG9nZXRoZXINCmFsbF9wZ3ggPC0gbGVmdF9qb2luKGRwbHlyOjpzZWxlY3QocHlwZ3hfMWEyLCBjKCJTdHVkeV9JRCIsICJlc3Rfc2NvcmUiKSksIGRwbHlyOjpzZWxlY3QocHlwZ3hfMmQ2LCBjKCJTdHVkeV9JRCIsICJlc3Rfc2NvcmUiKSksIGJ5ID0gIlN0dWR5X0lEIikNCmFsbF9wZ3ggPC0gbGVmdF9qb2luKGFsbF9wZ3gsIGRwbHlyOjpzZWxlY3QocHlwZ3hfMmM5LCBjKCJTdHVkeV9JRCIsICJlc3Rfc2NvcmUiKSksIGJ5ID0gIlN0dWR5X0lEIikNCmFsbF9wZ3ggPC0gbGVmdF9qb2luKGFsbF9wZ3gsIGRwbHlyOjpzZWxlY3QocHlwZ3hfMmMxOSwgYygiU3R1ZHlfSUQiLCAiZXN0X3Njb3JlIikpLCBieSA9ICJTdHVkeV9JRCIpDQphbGxfcGd4IDwtIGxlZnRfam9pbihhbGxfcGd4LCBkcGx5cjo6c2VsZWN0KHB5cGd4XzNhNSwgYygiU3R1ZHlfSUQiLCAiZXN0X3Njb3JlIikpLCBieSA9ICJTdHVkeV9JRCIpDQoNCiMgcmVuYW1lIGNvbHVtbnMNCmNvbG5hbWVzKGFsbF9wZ3gpIDwtIGMoIlN0dWR5X0lEIiwgIkNZUDFBMl9BUyIsICJDWVAyRDZfQVMiLCAgIkNZUDJDOV9BUyIsICJDWVAyQzE5X0FTIiwgIkNZUDNBNV9BUyIpDQoNCmBgYA0KDQoNCmBgYHtyIGluaXRpYWwgcGNzLCBpbmNsdWRlPUZBTFNFfQ0KIyBsb2FkIGluIGdlbmV0aWMgcHJpbmNpcGFsIGNvbXBvbmVudHMNCnBjYSA8LSByZWFkLnRhYmxlKCJDT0dTLmFsbGNoci5laWdlbnZlYyIsaGVhZGVyPUYpDQoNCnBjYSA8LSBwY2FbMjoxMl0NCg0KY29sbmFtZXMocGNhKSA8LSBjKCAiU3R1ZHlfSUQiLCAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIsICJQQzYiLCAiUEM3IiwgIlBDOCIsICJQQzkiLCAiUEMxMCIpDQoNCmBgYA0KDQoNCmBgYHtyIHBycyBzeiwgaW5jbHVkZT1GQUxTRX0NCg0KIyBsb2FkIHNjaGl6b3BocmVuaWEgUEdTIA0Kc2V0d2QoZGlyID0gIkQ6L3Npb2JoL0RvY3VtZW50cy9VbmkvUGhEL1kxL1N5bXB0b21zIFByb2plY3Qvc3ltcHRvbXMtY29ncy9wcnMvc3ovY3NfcHJzLyIpDQoNCiMgZmluZCBhbGwgLnByb2ZpbGUgZmlsZXMNCmxpc3RfZmlsZSA8LSBsaXN0LmZpbGVzKHBhdHRlcm4gPSAiKi5wcm9maWxlIikgJT4lIA0KIGd0b29sczo6bWl4ZWRzb3J0KCkNCg0KIyBzdW0gYWNyb3NzIGNocm9tb3NvbWVzDQpwcnNfY3Nfc3ogPC0gYW5hbHl6ZShsaXN0X2ZpbGUpDQpjb2xuYW1lcyhwcnNfY3Nfc3opIDwtIGMoIlN0dWR5X0lEIiwgIlNaX1BSU2NzIikNCmBgYA0KDQpgYGB7ciBwcnMgaW50LCBpbmNsdWRlPUZBTFNFfQ0KDQojIGxvYWQgaW50ZWxsaWdlbmNlIFBHUw0Kc2V0d2QoZGlyID0gIkQ6L3Npb2JoL0RvY3VtZW50cy9VbmkvUGhEL1kxL1N5bXB0b21zIFByb2plY3Qvc3ltcHRvbXMtY29ncy9wcnMvaW50ZWxsaWdlbmNlLyIpDQoNCiMgZmluZCBhbGwgLnByb2ZpbGUgZmlsZXMNCmxpc3RfZmlsZSA8LSBsaXN0LmZpbGVzKHBhdHRlcm4gPSAiKi5wcm9maWxlIikgJT4lIA0KIGd0b29sczo6bWl4ZWRzb3J0KCkNCg0KIyBzdW0gYWNyb3NzIGNocm9tb3NvbWVzDQpwcnNfY3NfaW50IDwtIGFuYWx5emUobGlzdF9maWxlKQ0KY29sbmFtZXMocHJzX2NzX2ludCkgPC0gYygiU3R1ZHlfSUQiLCAiSW50X1BSU2NzIikNCg0KYGBgDQoNCg0KYGBge3IgZWR1Y2F0aW9uYWwgYXR0YWlubWVudH0NCiMgbG9hZCBzY2hpem9waHJlbmlhIFBHUyANCnNldHdkKGRpciA9ICJEOi9zaW9iaC9Eb2N1bWVudHMvVW5pL1BoRC9ZMS9TeW1wdG9tcyBQcm9qZWN0L3N5bXB0b21zLWNvZ3MvcHJzL2VkdS8iKQ0KDQojIGZpbmQgYWxsIC5wcm9maWxlIGZpbGVzDQpsaXN0X2ZpbGUgPC0gbGlzdC5maWxlcyhwYXR0ZXJuID0gIioucHJvZmlsZSIpICU+JSANCiBndG9vbHM6Om1peGVkc29ydCgpDQoNCiMgc3VtIGFjcm9zcyBjaHJvbW9zb21lcw0KcHJzX2NzX2VhIDwtIGFuYWx5emUobGlzdF9maWxlKQ0KY29sbmFtZXMocHJzX2NzX2VhKSA8LSBjKCJTdHVkeV9JRCIsICJFQV9QUlNjcyIpDQpgYGANCg0KDQpgYGB7ciBjb21iaW5lIHBycywgaW5jbHVkZT1GQUxTRX0NCiMgbWVyZ2UgUFJTIGluZm9ybWF0aW9uDQphbGxfcHJzIDwtIGxlZnRfam9pbihwcnNfY3Nfc3osIHByc19jc19pbnQsIGJ5ID0gIlN0dWR5X0lEIikNCmFsbF9wcnMgPC0gbGVmdF9qb2luKGFsbF9wcnMsIHByc19jc19lYSwgYnkgPSAiU3R1ZHlfSUQiKQ0KDQpybShwcnNfY3Nfc3osIHByc19jc19pbnQsIHByc19jc19lYSkNCmBgYA0KDQpgYGB7ciBjb252ZXJ0IHNldCB1cCwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCg0KIyBnZXQgb25seSB0aGUgbWVkaWNhdGlvbiB2YXJpYWJsZXMNCm1lZHMgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAiQW50aXBzeWNob3RpYyIsICJBUF9kb3NlIiwgImFudGlkZXByZXNzYW50IiwgIkFEX2Rvc2UiLCAiTW9vZF9TdGFiaWxpc2VyIiwgIk1TX2Rvc2UiLCAiQmVuem9kaWF6ZXBpbmUiLCAiQmVuX2Rvc2UiLCAiQW50aWNob2xpbmVyZ2ljIiwgIkFudGljaG9saW5lcmdpY19kb3NlIiAsICJvdGhlcl9tZWRpY2F0aW9uIiwgIk90aGVyX21lZGljYXRpb25fZG9zZSIsICJDdXJyZW50X3Ntb2tpbmciKSkNCg0KQVBfY29kZXMgPC0gYygxOjE2LCAxODoyOSwgODcpICMgY29ycmVzcG9uZHMgdG8gYW50aXBzeWNob3RpYyBtZWRpY2F0aW9uIG9ubHkNCg0KIyByZW1vdmUgYWxsIGRydWdzIChhbmQgY29ycmVzcG9uZGluZyBkb3NlcykgdGhhdCBhcmVuJ3QgdXNlZnVsIEFQIChpLmUuLCAxIC0gMjkgJiA4NywgZXhjbHVkaW5nIDE3KQ0KbWVkcyRBbnRpcHN5Y2hvdGljWyEobWVkcyRBbnRpcHN5Y2hvdGljICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KbWVkcyRhbnRpZGVwcmVzc2FudFshKG1lZHMkYW50aWRlcHJlc3NhbnQgJWluJSBBUF9jb2RlcyldIDwtIE5BDQptZWRzJE1vb2RfU3RhYmlsaXNlclshKG1lZHMkTW9vZF9TdGFiaWxpc2VyJWluJSBBUF9jb2RlcyldIDwtIE5BDQptZWRzJEJlbnpvZGlhemVwaW5lWyEobWVkcyRCZW56b2RpYXplcGluZSAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCm1lZHMkQW50aWNob2xpbmVyZ2ljWyEobWVkcyRBbnRpY2hvbGluZXJnaWMgJWluJSBBUF9jb2RlcyldIDwtIE5BDQptZWRzJG90aGVyX21lZGljYXRpb25bIShtZWRzJG90aGVyX21lZGljYXRpb24gJWluJSBBUF9jb2RlcyldIDwtIE5BDQoNCiMgcmVtb3ZlIGRvc2VzIGZvciBub24tdXNlZnVsIGRydWdzDQptZWRzJEFQX2Rvc2VbaXMubmEobWVkcyRBbnRpcHN5Y2hvdGljKV0gPC0gTkENCm1lZHMkQURfZG9zZVtpcy5uYShtZWRzJGFudGlkZXByZXNzYW50KV0gPC0gTkENCm1lZHMkTVNfZG9zZVtpcy5uYShtZWRzJE1vb2RfU3RhYmlsaXNlcildIDwtIE5BDQptZWRzJEJlbl9kb3NlW2lzLm5hKG1lZHMkQmVuem9kaWF6ZXBpbmUpXSA8LSBOQQ0KbWVkcyRBbnRpY2hvbGluZXJnaWNfZG9zZVtpcy5uYShtZWRzJEFudGljaG9saW5lcmdpYyldIDwtIE5BDQptZWRzJE90aGVyX21lZGljYXRpb25fZG9zZVtpcy5uYShtZWRzJG90aGVyX21lZGljYXRpb24pXSA8LSBOQQ0KDQojIHJlbW92ZSBwYXJ0aWNpcGFudCB3aGVyZSBubyBkb3NlIChzdHJpY3QpIA0KI21lZHMkYW50aWRlcHJlc3NhbnQgPC0gaWZlbHNlKCFpcy5uYShtZWRzJGFudGlkZXByZXNzYW50KSAmIGlzLm5hKG1lZHMkQURfZG9zZSksIDk5OTksIG1lZHMkYW50aWRlcHJlc3NhbnQpDQojbWVkcyRNb29kX1N0YWJpbGlzZXIgPC0gaWZlbHNlKCFpcy5uYShtZWRzJE1vb2RfU3RhYmlsaXNlcikgJiBpcy5uYShtZWRzJE1TX2Rvc2UpLCA5OTk5LCBtZWRzJE1vb2RfU3RhYmlsaXNlcikNCiNtZWRzJEJlbnpvZGlhemVwaW5lIDwtIGlmZWxzZSghaXMubmEobWVkcyRCZW56b2RpYXplcGluZSkgJiBpcy5uYShtZWRzJEJlbl9kb3NlKSwgOTk5OSwgbWVkcyRCZW56b2RpYXplcGluZSkNCiNtZWRzJEFudGljaG9saW5lcmdpYyA8LSBpZmVsc2UoIWlzLm5hKG1lZHMkQW50aWNob2xpbmVyZ2ljKSAmIGlzLm5hKG1lZHMkQW50aWNob2xpbmVyZ2ljX2Rvc2UpLCA5OTk5LCBtZWRzJEFudGljaG9saW5lcmdpY19kb3NlKQ0KI21lZHMkb3RoZXJfbWVkaWNhdGlvbiA8LSBpZmVsc2UoIWlzLm5hKG1lZHMkb3RoZXJfbWVkaWNhdGlvbikgJiBpcy5uYShtZWRzJE90aGVyX21lZGljYXRpb25fZG9zZSksIDk5OTksIG1lZHMkb3RoZXJfbWVkaWNhdGlvbikNCg0KI3JlbW92ZV9pZHMgPC0gbWVkcyRTdHVkeV9JRFttZWRzJGFudGlkZXByZXNzYW50ID09IDk5OTkgfCBtZWRzJE1vb2RfU3RhYmlsaXNlciA9PSA5OTk5IHwgbWVkcyRCZW56b2RpYXplcGluZSA9PSA5OTk5IHwgbWVkcyRBbnRpY2hvbGluZXJnaWMgPT0gOTk5OSB8IG1lZHMkb3RoZXJfbWVkaWNhdGlvbiA9PSA5OTk5XQ0KDQojIHJlbW92ZV9pZHMgPC0gYXMuZGF0YS5mcmFtZShuYS5vbWl0KHJlbW92ZV9pZHMpKQ0KIyB3cml0ZV90c3YoeCA9IHJlbW92ZV9pZHMsIGZpbGUgPSAibWlzc2luZ19kb3NlLmlkcyIsIGNvbF9uYW1lcyA9IEYpDQoNCg0KIyBkZXBvdCBtZWRpY2F0aW9uIGZvdW5kIHdpdGhpbiB0aGUgZm9sbG93aW5nIGNvbHVtbnMNCiMgY3JlYXRlIG5ldyAnZGFpbHknIHZhcmlhYmxlIGJ5IGRpdmlkaW5nIGFsbCBkZXBvdCBkcnVncyBkb3NlcyBieSA3IA0KDQptZWRzJGRhaWx5X0FQIDwtIG1lZHMkQVBfZG9zZQ0KbWVkcyRkYWlseV9hbnRpY2hvbCA8LSBtZWRzJEFudGljaG9saW5lcmdpY19kb3NlDQptZWRzJGRhaWx5X290aGVyIDwtIG1lZHMkT3RoZXJfbWVkaWNhdGlvbl9kb3NlDQoNCm1lZHMgPC0gbWVkcyAlPiUNCiAgbXV0YXRlKGRhaWx5X0FQID0gY2FzZV93aGVuKEFudGlwc3ljaG90aWMgPT0gNiB+IChkYWlseV9BUCAvIDcpLCAjIHRoaXMgaXMgdGhlIERFUE9UIFZlcnNpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFudGlwc3ljaG90aWMgPT0gOCB+IChkYWlseV9BUCAvIDcpLCAjIHRoaXMgaXMgdGhlIERFUE9UIHZlcnNpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFudGlwc3ljaG90aWMgPT0gMTAgfiAoZGFpbHlfQVAgLyA3KSwgIyB0aGlzIGlzIHRoZSBERVBPVCB2ZXJzaW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnRpcHN5Y2hvdGljID09IDE2IH4gKGRhaWx5X0FQIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50aXBzeWNob3RpYyA9PSAyMiB+IChkYWlseV9BUCAvIDcpLCAjIHRoaXMgaXMgdGhlIERFUE9UIHZlcnNpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFudGlwc3ljaG90aWMgPT0gMjkgfiAoZGFpbHlfQVAgLyA3KSwgIyB0aGlzIGlzIHRoZSBERVBPVCB2ZXJzaW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnRpcHN5Y2hvdGljID09IDg3IH4gKGRhaWx5X0FQIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IGFzLmRvdWJsZShkYWlseV9BUCkNCiAgKSkNCg0KbWVkcyA8LSBtZWRzICU+JQ0KICAgIG11dGF0ZShkYWlseV9hbnRpY2hvbCA9IGNhc2Vfd2hlbihBbnRpY2hvbGluZXJnaWMgPT0gNiB+IChkYWlseV9hbnRpY2hvbCAvIDcpLCAjIHRoaXMgaXMgdGhlIERFUE9UIFZlcnNpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFudGljaG9saW5lcmdpYyA9PSA4IH4gKGRhaWx5X2FudGljaG9sIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50aWNob2xpbmVyZ2ljID09IDEwIH4gKGRhaWx5X2FudGljaG9sIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50aWNob2xpbmVyZ2ljID09IDE2IH4gKGRhaWx5X2FudGljaG9sIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50aWNob2xpbmVyZ2ljID09IDIyIH4gKGRhaWx5X2FudGljaG9sIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50aWNob2xpbmVyZ2ljID09IDI5IH4gKGRhaWx5X2FudGljaG9sIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQW50aWNob2xpbmVyZ2ljID09IDg3IH4gKGRhaWx5X2FudGljaG9sIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+IGFzLmRvdWJsZShkYWlseV9hbnRpY2hvbCkgKSApDQoNCm1lZHMgPC0gbWVkcyAlPiUNCiAgICBtdXRhdGUoZGFpbHlfb3RoZXIgPSBjYXNlX3doZW4ob3RoZXJfbWVkaWNhdGlvbiA9PSA2IH4gKGRhaWx5X290aGVyIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgVmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfbWVkaWNhdGlvbiA9PSA4IH4gKGRhaWx5X290aGVyIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfbWVkaWNhdGlvbiA9PSAxMCB+IChkYWlseV9vdGhlciAvIDcpLCAjIHRoaXMgaXMgdGhlIERFUE9UIHZlcnNpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyX21lZGljYXRpb24gPT0gMTYgfiAoZGFpbHlfb3RoZXIgLyA3KSwgIyB0aGlzIGlzIHRoZSBERVBPVCB2ZXJzaW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9tZWRpY2F0aW9uID09IDIyIH4gKGRhaWx5X290aGVyIC8gNyksICMgdGhpcyBpcyB0aGUgREVQT1QgdmVyc2lvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJfbWVkaWNhdGlvbiA9PSAyOSB+IChkYWlseV9vdGhlciAvIDcpLCAjIHRoaXMgaXMgdGhlIERFUE9UIHZlcnNpb24NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG90aGVyX21lZGljYXRpb24gPT0gODcgfiAoZGFpbHlfb3RoZXIgLyA3KSwgIyB0aGlzIGlzIHRoZSBERVBPVCB2ZXJzaW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gYXMuZG91YmxlKGRhaWx5X290aGVyKSApICkNCg0KIyBkaXZpZGUgDQphcCA8LSBtZWRzICU+JSBkcGx5cjo6c2VsZWN0KFN0dWR5X0lELCBBbnRpcHN5Y2hvdGljLCBkYWlseV9BUCkNCmFkIDwtIG1lZHMgJT4lIGRwbHlyOjpzZWxlY3QoU3R1ZHlfSUQsIGFudGlkZXByZXNzYW50LCBBRF9kb3NlKQ0KbXMgPC0gbWVkcyAlPiUgZHBseXI6OnNlbGVjdChTdHVkeV9JRCwgTW9vZF9TdGFiaWxpc2VyLCBNU19kb3NlKQ0KYnogPC0gbWVkcyAlPiUgZHBseXI6OnNlbGVjdChTdHVkeV9JRCwgQmVuem9kaWF6ZXBpbmUsIEJlbl9kb3NlKQ0KYWMgPC0gbWVkcyAlPiUgZHBseXI6OnNlbGVjdChTdHVkeV9JRCwgQW50aWNob2xpbmVyZ2ljLCBkYWlseV9hbnRpY2hvbCkNCm90IDwtIG1lZHMgJT4lIGRwbHlyOjpzZWxlY3QoU3R1ZHlfSUQsIG90aGVyX21lZGljYXRpb24sIGRhaWx5X290aGVyKQ0KDQojIyMjIGFzc2lnbiByb3V0ZSAjIyMjDQojIGFudGlwc3ljaG90aWMNCmFwJGFkbWluWyFpcy5uYShhcCRBbnRpcHN5Y2hvdGljKV0gPC0gIm9yYWwiDQphcCRhZG1pblthcCRBbnRpcHN5Y2hvdGljID09IDZdIDwtICJsYWkiDQphcCRhZG1pblthcCRBbnRpcHN5Y2hvdGljID09IDhdIDwtICJsYWkiDQphcCRhZG1pblthcCRBbnRpcHN5Y2hvdGljID09IDEwXSA8LSAibGFpIg0KYXAkYWRtaW5bYXAkQW50aXBzeWNob3RpYyA9PSAxNl0gPC0gImxhaSINCmFwJGFkbWluW2FwJEFudGlwc3ljaG90aWMgPT0gMjJdIDwtICJsYWkiDQphcCRhZG1pblthcCRBbnRpcHN5Y2hvdGljID09IDI5XSA8LSAibGFpIiAgICAgDQphcCRhZG1pblthcCRBbnRpcHN5Y2hvdGljID09IDg3XSA8LSAibGFpIiAgICAgDQoNCiMgY3JlYXRpbmcgYSBkZXBvdCB2YXJpYWJsZQ0KYXAkZGVwb3RfY3VycmVudCA8LSBOQQ0KYXAkZGVwb3RfY3VycmVudFthcCRhZG1pbiA9PSAib3JhbCJdIDwtIDANCmFwJGRlcG90X2N1cnJlbnRbYXAkYWRtaW4gPT0gImxhaSJdIDwtIDENCg0KIyBhbnRpZGVwcmVzc2FudA0KYWQkYWRtaW5bIWlzLm5hKGFkJGFudGlkZXByZXNzYW50KV0gPC0gIm9yYWwiDQphZCRhZG1pblthZCRhbnRpZGVwcmVzc2FudCA9PSA2XSA8LSAibGFpIg0KYWQkYWRtaW5bYWQkYW50aWRlcHJlc3NhbnQgPT0gOF0gPC0gImxhaSINCmFkJGFkbWluW2FkJGFudGlkZXByZXNzYW50ID09IDEwXSA8LSAibGFpIg0KYWQkYWRtaW5bYWQkYW50aWRlcHJlc3NhbnQgPT0gMTZdIDwtICJsYWkiDQphZCRhZG1pblthZCRhbnRpZGVwcmVzc2FudCA9PSAyMl0gPC0gImxhaSINCmFkJGFkbWluW2FkJGFudGlkZXByZXNzYW50ID09IDI5XSA8LSAibGFpIiAgICAgDQphZCRhZG1pblthZCRhbnRpZGVwcmVzc2FudCA9PSA4N10gPC0gImxhaSIgICAgIA0KDQojIGNyZWF0aW5nIGEgZGVwb3QgdmFyaWFibGUNCmFkJGRlcG90X2N1cnJlbnQgPC0gTkENCmFkJGRlcG90X2N1cnJlbnRbYWQkYWRtaW4gPT0gIm9yYWwiXSA8LSAwDQphZCRkZXBvdF9jdXJyZW50W2FkJGFkbWluID09ICJsYWkiXSA8LSAxDQoNCiMgTW9vZF9TdGFiaWxpc2VyDQptcyRhZG1pblshaXMubmEobXMkTW9vZF9TdGFiaWxpc2VyKV0gPC0gIm9yYWwiDQptcyRhZG1pblttcyRNb29kX1N0YWJpbGlzZXIgPT0gNl0gPC0gImxhaSINCm1zJGFkbWluW21zJE1vb2RfU3RhYmlsaXNlciA9PSA4XSA8LSAibGFpIg0KbXMkYWRtaW5bbXMkTW9vZF9TdGFiaWxpc2VyID09IDEwXSA8LSAibGFpIg0KbXMkYWRtaW5bbXMkTW9vZF9TdGFiaWxpc2VyID09IDE2XSA8LSAibGFpIg0KbXMkYWRtaW5bbXMkTW9vZF9TdGFiaWxpc2VyID09IDIyXSA8LSAibGFpIg0KbXMkYWRtaW5bbXMkTW9vZF9TdGFiaWxpc2VyID09IDI5XSA8LSAibGFpIiAgICAgDQptcyRhZG1pblttcyRNb29kX1N0YWJpbGlzZXIgPT0gODddIDwtICJsYWkiICAgICANCg0KIyBjcmVhdGluZyBhIGRlcG90IHZhcmlhYmxlDQptcyRkZXBvdF9jdXJyZW50IDwtIE5BDQptcyRkZXBvdF9jdXJyZW50W21zJGFkbWluID09ICJvcmFsIl0gPC0gMA0KbXMkZGVwb3RfY3VycmVudFttcyRhZG1pbiA9PSAibGFpIl0gPC0gMQ0KDQojIEJlbnpvZGlhemVwaW5lDQpieiRhZG1pblshaXMubmEoYnokQmVuem9kaWF6ZXBpbmUpXSA8LSAib3JhbCINCmJ6JGFkbWluW2J6JEJlbnpvZGlhemVwaW5lID09IDZdIDwtICJsYWkiDQpieiRhZG1pbltieiRCZW56b2RpYXplcGluZSA9PSA4XSA8LSAibGFpIg0KYnokYWRtaW5bYnokQmVuem9kaWF6ZXBpbmUgPT0gMTBdIDwtICJsYWkiDQpieiRhZG1pbltieiRCZW56b2RpYXplcGluZSA9PSAxNl0gPC0gImxhaSINCmJ6JGFkbWluW2J6JEJlbnpvZGlhemVwaW5lID09IDIyXSA8LSAibGFpIg0KYnokYWRtaW5bYnokQmVuem9kaWF6ZXBpbmUgPT0gMjldIDwtICJsYWkiICAgICANCmJ6JGFkbWluW2J6JEJlbnpvZGlhemVwaW5lID09IDg3XSA8LSAibGFpIiAgICAgDQoNCiMgY3JlYXRpbmcgYSBkZXBvdCB2YXJpYWJsZQ0KYnokZGVwb3RfY3VycmVudCA8LSBOQQ0KYnokZGVwb3RfY3VycmVudFtieiRhZG1pbiA9PSAib3JhbCJdIDwtIDANCmJ6JGRlcG90X2N1cnJlbnRbYnokYWRtaW4gPT0gImxhaSJdIDwtIDENCg0KIyBBbnRpY2hvbGluZXJnaWMNCmFjJGFkbWluWyFpcy5uYShhYyRBbnRpY2hvbGluZXJnaWMpXSA8LSAib3JhbCINCmFjJGFkbWluW2FjJEFudGljaG9saW5lcmdpYyA9PSA2XSA8LSAibGFpIg0KYWMkYWRtaW5bYWMkQW50aWNob2xpbmVyZ2ljID09IDhdIDwtICJsYWkiDQphYyRhZG1pblthYyRBbnRpY2hvbGluZXJnaWMgPT0gMTBdIDwtICJsYWkiDQphYyRhZG1pblthYyRBbnRpY2hvbGluZXJnaWMgPT0gMTZdIDwtICJsYWkiDQphYyRhZG1pblthYyRBbnRpY2hvbGluZXJnaWMgPT0gMjJdIDwtICJsYWkiDQphYyRhZG1pblthYyRBbnRpY2hvbGluZXJnaWMgPT0gMjldIDwtICJsYWkiICAgICANCmFjJGFkbWluW2FjJEFudGljaG9saW5lcmdpYyA9PSA4N10gPC0gImxhaSIgICAgIA0KDQojIGNyZWF0aW5nIGEgZGVwb3QgdmFyaWFibGUNCmFjJGRlcG90X2N1cnJlbnQgPC0gTkENCmFjJGRlcG90X2N1cnJlbnRbYWMkYWRtaW4gPT0gIm9yYWwiXSA8LSAwDQphYyRkZXBvdF9jdXJyZW50W2FjJGFkbWluID09ICJsYWkiXSA8LSAxDQoNCiMgb3RoZXINCm90JGFkbWluWyFpcy5uYShvdCRvdGhlcl9tZWRpY2F0aW9uKV0gPC0gIm9yYWwiDQpvdCRhZG1pbltvdCRvdGhlcl9tZWRpY2F0aW9uID09IDZdIDwtICJsYWkiDQpvdCRhZG1pbltvdCRvdGhlcl9tZWRpY2F0aW9uID09IDhdIDwtICJsYWkiDQpvdCRhZG1pbltvdCRvdGhlcl9tZWRpY2F0aW9uID09IDEwXSA8LSAibGFpIg0Kb3QkYWRtaW5bb3Qkb3RoZXJfbWVkaWNhdGlvbiA9PSAxNl0gPC0gImxhaSINCm90JGFkbWluW290JG90aGVyX21lZGljYXRpb24gPT0gMjJdIDwtICJsYWkiDQpvdCRhZG1pbltvdCRvdGhlcl9tZWRpY2F0aW9uID09IDI5XSA8LSAibGFpIiAgICAgDQpvdCRhZG1pbltvdCRvdGhlcl9tZWRpY2F0aW9uID09IDg3XSA8LSAibGFpIiAgICAgDQoNCiMgY3JlYXRpbmcgYSBkZXBvdCB2YXJpYWJsZQ0Kb3QkZGVwb3RfY3VycmVudCA8LSBOQQ0Kb3QkZGVwb3RfY3VycmVudFtvdCRhZG1pbiA9PSAib3JhbCJdIDwtIDANCm90JGRlcG90X2N1cnJlbnRbb3QkYWRtaW4gPT0gImxhaSJdIDwtIDENCg0KIyMjIyBtZWRpY2F0aW9uIGNvZGUgLSBuYW1lIG1hcHBpbmcgIyMjIw0KcmVjb2RlX3ZlY3RvciA8LSBjKA0KICAiMSIgPSAiYW1pc3VscHJpZGUiLA0KICAiMiIgPSAiYXJpcGlwcmF6b2xlIiwNCiAgIjMiID0gImNobG9ycHJvbWF6aW5lIiwNCiAgIjQiID0gImNsb3phcGluZSIsDQogICI1IiA9ICJmbHVwZW50aGl4b2wiLA0KICAiNiIgPSAiZmx1cGVudGl4b2wiLCANCiMgYW1lcmljYW5pc2VkIHNwZWxsaW5nIHRvIGZvcmNlIHVzZSBvZiBMZXVjaHQgMjAxNiBEREQgY29udmVyc2lvbiBmb3IgZmx1cGVudGhpeG9sIGxhaS4gVGhlIHNpemUgb2YgY29udmVyc2lvbiBkaWZmZXJzIGdyZWF0bHkgYmV0d2VlbiB0aGUgdHdvICg3NS4yLCBEREQgdnMgMjEwLCBHYXJkbmVyKSBhbmQgdXNpbmcgR2FyZG5lcidzIGVxdWl2YWxlbnRzIHJlc3VsdHMgaW4gcGVvcGxlIGhhdmluZyBhIHRvdGFsIGRhaWx5IGRvc2UgPiA2MDAwIG1nIChjb21wYXJlZCB0byA+IDIwMDBtZyB3aGVuIHRoZSBEREQgZmx1cGVudGl4b2wgTEFJIGNvbnZlcnNpb24gaXMgdXNlZCkuDQogICI3IiA9ICJmbHVwaGVuYXppbmUiLA0KICAiOCIgPSAiZmx1cGhlbmF6aW5lIiwNCiAgIjkiID0gImhhbG9wZXJpZG9sIiwNCiAgIjEwIiA9ICJoYWxvcGVyaWRvbCIsDQogICIxMiIgPSAib2xhbnphcGluZSIsDQogICIxNSIgPSAicGltb3ppZGUiLA0KICAiMTYiID0gInBpcG90aWF6aW5lIiwNCiAgIjIwIiA9ICJxdWV0aWFwaW5lIiwNCiAgIjIxIiA9ICJyaXNwZXJpZG9uZSIsDQogICIyMiIgPSAicmlzcGVyaWRvbmUiLA0KICAiMjQiID0gInN1bHBpcmlkZSIsDQogICIyNiIgPSAidHJpZmx1b3BlcmF6aW5lIiwNCiAgIjI4IiA9ICJ6dWNsb3BlbnRoaXhvbCIsDQogICIyOSIgPSAienVjbG9wZW50aGl4b2wiLA0KICAiODciID0gInBhbGlwZXJpZG9uZSINCikNCg0KIyByZWNvZGUgYWxsIG51bWVyaWMgY29kZXMgdG8gbWVkaWNhdGlvbiBuYW1lcw0KYXAgPC0gYXMuZGF0YS5mcmFtZShyZWNvZGVfc2VsZWN0ZWRfY29kZXMoZGYgPSBhcCwgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlID0gIkFudGlwc3ljaG90aWMiKSkNCg0KYWQgPC0gYXMuZGF0YS5mcmFtZShyZWNvZGVfc2VsZWN0ZWRfY29kZXMoZGYgPSBhZCwgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlID0gImFudGlkZXByZXNzYW50IikpDQoNCm1zIDwtIGFzLmRhdGEuZnJhbWUocmVjb2RlX3NlbGVjdGVkX2NvZGVzKGRmID0gbXMsIHJlY29kZV92ZWN0b3IgPSByZWNvZGVfdmVjdG9yLCBjb2x1bW5zX3RvX3JlY29kZSA9ICJNb29kX1N0YWJpbGlzZXIiKSkNCg0KYnogPC0gYXMuZGF0YS5mcmFtZShyZWNvZGVfc2VsZWN0ZWRfY29kZXMoZGYgPSBieiwgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlID0gIkJlbnpvZGlhemVwaW5lIikpDQoNCmFjIDwtIGFzLmRhdGEuZnJhbWUocmVjb2RlX3NlbGVjdGVkX2NvZGVzKGRmID0gYWMsIHJlY29kZV92ZWN0b3IgPSByZWNvZGVfdmVjdG9yLCBjb2x1bW5zX3RvX3JlY29kZSA9ICJBbnRpY2hvbGluZXJnaWMiKSkNCg0Kb3QgPC0gYXMuZGF0YS5mcmFtZShyZWNvZGVfc2VsZWN0ZWRfY29kZXMoZGYgPSBvdCwgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlID0gIm90aGVyX21lZGljYXRpb24iKSkNCg0KYGBgDQoNCg0KYGBge3IgY2hsb3Jwcm9tYXppbmVSIGNvbnZlcnNpb24sIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQoNCiMgbWFraW5nIGN1c3RvbSBjb252ZXJzaW9uLCB3aGljaCB1c2VzIHRoZSBjb252ZXJzaW9ucyBmcm9tIEdhcmRuZXIgZXQgYWwuLCAoMjAxMCkgZmlyc3QgdGhlbiB0aGUgREREIGZyb20gTGV1Y2h0IGV0IGFsLiwgKDIwMTYpIHdoZW4gY29udmVyc2lvbnMgYWJzZW50IGZyb20gR2FyZG5lciBldCBhbC4sICgyMDEwKSwgYXMgcmVjb21tZW5kZWQgaW4gdGhlIGRvY3VtZW50YXRpb24sIGFuZCBieSBMZXVjaHQgZXQgYWwuLCAoMjAxNikuDQpnYXJkbmVyX2xldWNodCA8LSBhZGRfa2V5KGJhc2UgPSBnYXJkbmVyMjAxMCwgYWRkID0gbGV1Y2h0MjAxNiwgdHJpbSA9IFRSVUUpDQoNCiMgY2hlY2tzOiBkbyB3ZSBoYXZlIGtleXMgZm9yIGFsbCBhbnRpcHN5Y2hvdGljcyBpbiBkYXRhc2V0DQogICMgY2hlY2tfYXAobXMsIGFwX2xhYmVsID0gIk1vb2RfU3RhYmlsaXNlciIsIHJvdXRlID0gIm9yYWwiLCBrZXk9Z2FyZG5lcl9sZXVjaHQpDQogICMgY2hlY2tfYXAoZXhhbXBsZV9waGVubywgYXBfbGFiZWwgPSAiYW50aXBzeWNob3RpYyIsIHJvdXRlID0gImxhaSIsIGtleT1nYXJkbmVyX2xldWNodCkNCiAgIyBjb2xTdW1zKGlzLm5hKGV4YW1wbGVfcGhlbm8pKQ0KDQojIGNvbnZlcnQgYWxsIGFudGlwc3ljaG90aWNzDQphcGMgPC0gY29udmVydChhcCwgIkFudGlwc3ljaG90aWMiLCAiZGFpbHlfQVAiKSAlPiUgZHBseXI6OnNlbGVjdChjKCJTdHVkeV9JRCIsICJjcHpfZXEiKSkNCmFkYyA8LSBjb252ZXJ0KGFkLCAiYW50aWRlcHJlc3NhbnQiLCAiQURfZG9zZSIpICU+JSBkcGx5cjo6c2VsZWN0KGMoIlN0dWR5X0lEIiwgImNwel9lcSIpKQ0KbXNjIDwtIGNvbnZlcnQobXMsICJNb29kX1N0YWJpbGlzZXIiLCAiTVNfZG9zZSIpICU+JSBkcGx5cjo6c2VsZWN0KGMoIlN0dWR5X0lEIiwgImNwel9lcSIpKQ0KYnpjIDwtIGNvbnZlcnQoYnosICJCZW56b2RpYXplcGluZSIsICJCZW5fZG9zZSIpICU+JSBkcGx5cjo6c2VsZWN0KGMoIlN0dWR5X0lEIiwgImNwel9lcSIpKQ0KYWNjIDwtIGNvbnZlcnQoYWMsICJBbnRpY2hvbGluZXJnaWMiLCAiZGFpbHlfYW50aWNob2wiKSAlPiUgZHBseXI6OnNlbGVjdChjKCJTdHVkeV9JRCIsICJjcHpfZXEiKSkNCm90YyA8LSBjb252ZXJ0KG90LCAib3RoZXJfbWVkaWNhdGlvbiIsICJkYWlseV9vdGhlciIpICU+JSBkcGx5cjo6c2VsZWN0KGMoIlN0dWR5X0lEIiwgImNwel9lcSIpKQ0KDQojIGpvaW4gdG9nZXRoZXIgdG8gZm9ybSBjcHogZGF0YXNldA0KY3B6IDwtIGZ1bGxfam9pbihhcGMsIGFkYywgYnkgPSAiU3R1ZHlfSUQiKQ0KY3B6IDwtIGZ1bGxfam9pbihjcHosIG1zYywgYnkgPSAiU3R1ZHlfSUQiKQ0KY3B6IDwtIGZ1bGxfam9pbihjcHosIGJ6YywgYnkgPSAiU3R1ZHlfSUQiKQ0KY3B6IDwtIGZ1bGxfam9pbihjcHosIGFjYywgYnkgPSAiU3R1ZHlfSUQiKQ0KY3B6IDwtIGZ1bGxfam9pbihjcHosIG90YywgYnkgPSAiU3R1ZHlfSUQiKQ0KDQpjb2xzIDwtIGNvbG5hbWVzKGNweikNCg0KIyBzdW0gYWxsIGNobG9ycHJvbWF6aW5lIGVxdWl2YWxlbnRzDQpjcHokdG90YWwgPC0gcm93U3VtcyhjcHpbLCBjb2xzWy0xXV0sIG5hLnJtID0gVFJVRSkNCmNweiA8LSBjcHogJT4lIGRwbHlyOjpzZWxlY3QoIlN0dWR5X0lEIiwgInRvdGFsIikgDQpjb2xuYW1lcyhjcHopIDwtIGMoIlN0dWR5X0lEIiwgImNwel9lcSIpIA0KDQpwaGVubyA8LSBsZWZ0X2pvaW4ocGhlbm8sIGNweiwgYnkgPSAiU3R1ZHlfSUQiKQ0KDQojIHJlbW92ZSBpbnRlcm1lZGlhdGVzDQpybShhYywgYWNjLCBhZCwgYWRjLCBhcCwgYXBjLCBieiwgYnpjLCBtcyxtc2MsIG90LCBvdGMpDQoNCmBgYA0KDQoNCg0KYGBge3IgaW1wb3J0YW50IHZhcmlhYmxlcywgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCiMjIyMgZXh0cmFjdGluZyBwaGVub3R5cGUgdmFyaWFibGVzICMjIyMNCiMgb25seSBjdXJyZW50IHN5bXB0b21zICh1c2VkIGZvciBkZXJpdmluZyBmYWN0b3JzKQ0KcG9zaXRpdmUgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAiU0FQU19HbG9iYWxfSGFscyIsICAiU0FQU19HbG9iYWxfRGVsdXNpb25zIikpDQoNCm5lZ2F0aXZlIDwtIGRwbHlyOjpzZWxlY3QocGhlbm8sIGMoIlN0dWR5X0lEIiwgIlNBTlNfR2xvYmFsX0FmZmVjdGl2ZV9GbGF0dGVuaW5nIiwgICJTQU5TX0dsb2JhbF9BbG9naWEiLCAgIlNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IiwiU0FOU19HbG9iYWxfQXZvbGl0aW9uX0FwYXRoeSIpKQ0KDQpvdGhlcnMgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDYWxnYXJ5X1N1aWNpZGUiLCAiQ2FsZ2FyeV9EZXByZXNzaW9uIiAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlpOQUJfTWF6ZXNfSW1wIiwiWkhWTFRfSW1wIiwgIlpCVk1UX0ltcCIsICJaQ1BUX0ltcCIsICJaU29QX0ltcCIsICJaV01fSW1wIikpDQoNCiMgam9pbiBzeW1wdG9tcyB0b2dldGhlcg0Kc3ltcHRvbXMgPC0gbGVmdF9qb2luKHBvc2l0aXZlLCBuZWdhdGl2ZSwgYnkgPSAiU3R1ZHlfSUQiKQ0Kc3ltcHRvbXMgPC0gbGVmdF9qb2luKHN5bXB0b21zLCBvdGhlcnMsIGJ5ID0gIlN0dWR5X0lEIikNCg0KIyMjIyBleHRyYWN0aW5nIGFkZGl0aW9uYWwgdmFyaWFibGVzICMjIyMNCiMgc2VsZWN0IG90aGVyIGNvdmFyaWF0ZXMNCmNvdmFyaWF0ZXMgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAgIlNleCIsICJBZ2VfYXRfSW50ZXJ2aWV3IiwgIkFQX2Rvc2UiLCAiY3B6X2VxIiwgIkFudGlwc3ljaG90aWMiLCAiYW50aWRlcHJlc3NhbnQiLCAiTW9vZF9TdGFiaWxpc2VyIiwgIkJlbnpvZGlhemVwaW5lIiwgIkFudGljaG9saW5lcmdpYyIsICJvdGhlcl9tZWRpY2F0aW9uIiwgIkFkaGVyZW5jZSIsICJHQVNfUGFzdF9XZWVrIiwgIlB0X0hpZ2hlc3RfRWR1Y24iLCAiTkFSVElRIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpDQojIyMjIHByZXBhcmluZyBtZWRpY2F0aW9uIHZhcmlhYmxlcyAjIyMjDQojIHNlbGVjdCBjb2x1bW5zIGZvciBjb2RpbmcgbWVkaWNhdGlvbiB2YXJpYWJsZXMNCm1lZHMgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAiQW50aXBzeWNob3RpYyIsICJhbnRpZGVwcmVzc2FudCIsICJNb29kX1N0YWJpbGlzZXIiLCAiQmVuem9kaWF6ZXBpbmUiLCAiQW50aWNob2xpbmVyZ2ljIiwgIm90aGVyX21lZGljYXRpb24iLCAiQ3VycmVudF9zbW9raW5nIikpDQoNCiMgY29kZSBjbG96YXBpbmUgY3VycmVudCAoY2hlY2tpbmcgZm9yIGNsb3phcGluZSBjb2RlICg0KSBhY3Jvc3MgYWxsIG1lZGljYXRpb24gY29sdW1ucykNCiMgY29kZSBmbHVveGV0aW5lIGN1cnJlbnQgKGNoZWNraW5nIGZvciBmbHVveGV0aW5lIGNvZGUgKDM4KSBhY3Jvc3MgYWxsIG1lZGljYXRpb24gY29sdW1ucykNCiMgY29kZSBjYXJiYW1hemVwaW5lIGN1cnJlbnQgKGNoZWNraW5nIGZvciBjYXJiYW1hemVwaW5lIGNvZGUgKDU4KSBhY3Jvc3MgYWxsIG1lZGljYXRpb24gY29sdW1ucykNCg0KbWVkcyA8LSBtZWRzICU+JQ0KICBtdXRhdGUoY2xvel9wcmVzZW50ID0gcm93U3VtcyhkcGx5cjo6c2VsZWN0KC4sIGMoMjo3KSkgPT0gNCwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgIGZsdW94X3ByZXNlbnQgPSByb3dTdW1zKGRwbHlyOjpzZWxlY3QoLiwgYygyOjcpKSA9PSAzOCwgbmEucm0gPSBUUlVFKSwNCiAgICAgICAgIGNhcmJfcHJlc2VudCA9IHJvd1N1bXMoZHBseXI6OnNlbGVjdCguLCBjKDI6NykpID09IDU4LCBuYS5ybSA9IFRSVUUpKQ0KDQojIGNyZWF0ZSBiaW5hcnkgdmFyaWFibGUgZm9yIGFib3ZlDQptZWRzJGNsb3phcGluZV9jdXJyZW50IDwtIDANCm1lZHMkY2xvemFwaW5lX2N1cnJlbnRbbWVkcyRjbG96X3ByZXNlbnQgPj0gMV0gPC0gMQ0KDQptZWRzJGZsdW94ZXRpbmUgPC0gMA0KbWVkcyRmbHVveGV0aW5lW21lZHMkZmx1b3hfcHJlc2VudCA+PSAxXSA8LSAxDQoNCm1lZHMkY2FyYmFtYXplcGluZSA8LSAwDQptZWRzJGNhcmJhbWF6ZXBpbmVbbWVkcyRjYXJiX3ByZXNlbnQgPj0gMV0gPC0gMQ0KDQojIHJlLWNvZGUgY3VycmVudCBzbW9raW5nIHN0YXR1cyBzbyBpdCBtYWtlcyBtb3JlIHNlbnNlIDEgPSBwcmVzZW5jZSwgMCA9IGFic2VuY2UuDQptZWRzJHNtb2tpbmcgPC0gTkENCm1lZHMkc21va2luZ1ttZWRzJEN1cnJlbnRfc21va2luZyA9PSAxXSA8LSAxICMgbGFiZWxzIDEgPSB5ZXMsIDIgPSBubw0KbWVkcyRzbW9raW5nW21lZHMkQ3VycmVudF9zbW9raW5nID09IDJdIDwtIDAgIyBsYWJlbHMgMSA9IHllcywgMiA9IG5vDQoNCiMgY3JlYXRlIGFudGljaG9saW5lcmdpYyB2YXJpYWJsZSBpZGVudGlmeWluZyBhbnRpY2hvbGluZXJnaWNzICg4MC04MyBhbmQgMTcpIGFjcm9zcyBtZWRpY2F0aW9uIGNvbHVtbnMNCmFudGkgPC0gbWVkcyAlPiUNCiAgbXV0YXRlKGFudGljaF9wcmVzZW50ID0gcm93U3VtcyhkcGx5cjo6c2VsZWN0KC4sIGMoMjo3KSkgPT0gODAgfCBkcGx5cjo6c2VsZWN0KC4sIGMoMjo3KSkgPT0gODEgfCBkcGx5cjo6c2VsZWN0KC4sIGMoMjo3KSkgPT0gODIgfCBkcGx5cjo6c2VsZWN0KC4sIGMoMjo3KSkgPT0gODMgfCBkcGx5cjo6c2VsZWN0KC4sIGMoMjo3KSkgPT0gMTcsIG5hLnJtID0gVFJVRSkpDQoNCiMgY3JlYXRlIGJpbmFyeSB2YXJpYWJsZSBmb3IgYW50aWNob2xpbmVyZ2ljIHByZXNlbmNlICgxKSAvIGFic2VuY2UgKDApIA0KYW50aSRhbnRpY2hvbF9wcmVzZW50IDwtIDANCmFudGkkYW50aWNob2xfcHJlc2VudFthbnRpJGFudGljaF9wcmVzZW50ID49IDFdIDwtIDENCg0KYW50aV9wIDwtIGRwbHlyOjpzZWxlY3QoYW50aSwgYygiU3R1ZHlfSUQiLCAiYW50aWNob2xfcHJlc2VudCIpKQ0KDQojIGNyZWF0ZSBhbnRpcHN5Y2hvdGljIHBvbHlwaGFybWFjeSB2YXJpYWJsZQ0KcHAgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAiQW50aXBzeWNob3RpYyIsICJhbnRpZGVwcmVzc2FudCIsICJNb29kX1N0YWJpbGlzZXIiLCAiQmVuem9kaWF6ZXBpbmUiLCAiQW50aWNob2xpbmVyZ2ljIiwgIm90aGVyX21lZGljYXRpb24iKSkNCg0KIyByZW1vdmUgbm9uIGFudGlwc3ljaG90aWMgZHJ1Z3MNCnBwJEFudGlwc3ljaG90aWNbIShwcCRBbnRpcHN5Y2hvdGljICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KcHAkYW50aWRlcHJlc3NhbnRbIShwcCRhbnRpZGVwcmVzc2FudCAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCnBwJE1vb2RfU3RhYmlsaXNlclshKHBwJE1vb2RfU3RhYmlsaXNlciVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KcHAkQmVuem9kaWF6ZXBpbmVbIShwcCRCZW56b2RpYXplcGluZSAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCnBwJEFudGljaG9saW5lcmdpY1shKHBwJEFudGljaG9saW5lcmdpYyAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCnBwJG90aGVyX21lZGljYXRpb25bIShwcCRvdGhlcl9tZWRpY2F0aW9uICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KDQojIGdldCBtZWRpY2F0aW9uIGNvbHVtbiBuYW1lcw0KY29scyA8LSBjb2xuYW1lcyhwcFstMV0pDQoNCnJlY29kZV92ZWN0b3IgPC0gYygNCiAgIjEiID0gIkFtaXN1bHByaWRlIiwNCiAgIjIiID0gIkFyaXBpcHJhem9sZSIsDQogICIzIiA9ICJDaGxvcnByb21hemluZSIsDQogICI0IiA9ICJDbG96YXBpbmUiLA0KICAiNSIgPSAiRmx1cGVudGhpeG9sIiwNCiAgIjYiID0gIkZsdXBlbnRoaXhvbCIsIA0KICAiNyIgPSAiRmx1cGhlbmF6aW5lIiwNCiAgIjgiID0gIkZsdXBoZW5hemluZSIsDQogICI5IiA9ICJIYWxvcGVyaWRvbCIsDQogICIxMCIgPSAiSGFsb3Blcmlkb2wiLA0KICAiMTIiID0gIk9sYW56YXBpbmUiLA0KICAiMTUiID0gIlBpbW96aWRlIiwNCiAgIjE2IiA9ICJQaXBvdGlhemluZSIsDQogICIyMCIgPSAiUXVldGlhcGluZSIsDQogICIyMSIgPSAiUmlzcGVyaWRvbmUiLA0KICAiMjIiID0gIlJpc3Blcmlkb25lIiwNCiAgIjI0IiA9ICJTdWxwaXJpZGUiLA0KICAiMjYiID0gIlRyaWZsdW9wZXJhemluZSIsDQogICIyOCIgPSAiWnVjbG9wZW50aGl4b2wiLA0KICAiMjkiID0gIlp1Y2xvcGVudGhpeG9sIiwNCiAgIjg3IiA9ICJQYWxpcGVyaWRvbmUiDQopDQoNCiMgY29udmVydCBudW1iZXJzIHRvIGRydWcgbmFtZXMNCnBwX2ZyZXEgPC0gYXMuZGF0YS5mcmFtZShyZWNvZGVfc2VsZWN0ZWRfY29kZXMoZGYgPSBwcCwgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlID0gY29scykpDQoNCiMgY3JlYXRlIHZhcmlhYmxlIHdpdGggYWxsIG1lZGljYXRpb24gbmFtZXMgcGVyIHJvdyBpbiBpdCwgc2VwYXJhdGVkIGJ5IGNvbW1hcywgbm8gZHVwbGljYXRlcywgYW5kIGluIGFscGhhYmV0aWNhbCBvcmRlcg0KcHBfZnJlcSA8LSBwcF9mcmVxICU+JQ0KICBtdXRhdGUodG90YWwgPSBwbWFwX2NocihkcGx5cjo6c2VsZWN0KC4sIC1TdHVkeV9JRCksIH50b1N0cmluZyhzb3J0KHVuaXF1ZShuYS5vbWl0KGMoLi4uKSkpKSkpKQ0KDQojIGlkZW50aWZ5IHBlb3BsZSBvbiBBUFAgdnMgbm90IEFQUCBieSB3aGV0aGVyIG9yIG5vdCB0aGVyZSBpcyBhIGNvbW1hIGluIHRoZSB2YXJpYWJsZQ0KcHBfZnJlcSA8LSBwcF9mcmVxICU+JQ0KICBtdXRhdGUoYXBfcG9seSA9IGNhc2Vfd2hlbihncmVwbCgiLCIsIHRvdGFsKSB+IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIWdyZXBsKCIsIiwgdG90YWwpIH4wKSkNCg0KcHAgPC0gZHBseXI6OnNlbGVjdChwcF9mcmVxLCBjKCJTdHVkeV9JRCIsICJhcF9wb2x5IikpDQoNCiMgam9pbiBuZXcgdmFyaWFibGVzIHRvZ2V0aGVyDQpjb3ZhcmlhdGVzICA8LSBsZWZ0X2pvaW4oY292YXJpYXRlcywgZHBseXI6OnNlbGVjdChtZWRzLCBjKCJTdHVkeV9JRCIsICJjbG96YXBpbmVfY3VycmVudCIsICJmbHVveGV0aW5lIiwgImNhcmJhbWF6ZXBpbmUiICwic21va2luZyIpKSkNCmNvdmFyaWF0ZXMgPC0gbGVmdF9qb2luKGNvdmFyaWF0ZXMsIGFudGlfcCwgYnkgPSAiU3R1ZHlfSUQiICkNCmNvdmFyaWF0ZXMgPC0gbGVmdF9qb2luKGNvdmFyaWF0ZXMsIHBwLCBieSA9ICJTdHVkeV9JRCIgKQ0KDQojIGNvZGUgYWRoZXJlbmNlIGl0ZW1zDQpjb3ZhcmlhdGVzJEFkaGVyZW5jZVtjb3ZhcmlhdGVzJEFkaGVyZW5jZSA9PSA3XSA8LSBOQQ0KY292YXJpYXRlcyRBZGhlcmVuY2VfY29kZWRbY292YXJpYXRlcyRBZGhlcmVuY2UgPj00XSA8LSAxIA0KY292YXJpYXRlcyRBZGhlcmVuY2VfY29kZWRbY292YXJpYXRlcyRBZGhlcmVuY2UgPD0zXSA8LSAwIA0KY292YXJpYXRlcyRBZGhlcmVuY2VfY29kZWQgPC0gYXMuZmFjdG9yKGNvdmFyaWF0ZXMkQWRoZXJlbmNlX2NvZGVkKQ0KY292YXJpYXRlcyRBZGhlcmVuY2UgPC0gYXMuZmFjdG9yKGNvdmFyaWF0ZXMkQWRoZXJlbmNlKQ0KIyBsZXZlbHMgPSBjKCJEb2Vzbid0IHRha2UgbWVkaWNhdGlvbiIsICJUYWtlcyBtZWRpY2F0aW9uIG9ubHkgcmFyZWx5IiwgIk1pc3NlcyBvdmVyIDUwJSBkb3NlcyIsICJNaXNzZXMgZG9zZXMgZXZlcnkgd2VlayIsICJSYXJlbHkgbWlzc2VzIGRvc2VzIiwgIk1lZGljYXRpb24gc3VwZXJ2aXNlZCBhbmQgdGFrZXMgYXMgcHJlc2NyaWJlZCIpKQ0KDQojIG1ha2UgYmluYXJ5IHZhcmlhYmxlcyBmYWN0b3JzDQpjb3ZhcmlhdGVzJFNleCA8LSBhcy5mYWN0b3IoY292YXJpYXRlcyRTZXgpDQpjb3ZhcmlhdGVzJGNsb3phcGluZV9jdXJyZW50IDwtIGFzLmZhY3Rvcihjb3ZhcmlhdGVzJGNsb3phcGluZV9jdXJyZW50KQ0KY292YXJpYXRlcyRzbW9raW5nIDwtIGFzLmZhY3Rvcihjb3ZhcmlhdGVzJHNtb2tpbmcpDQpjb3ZhcmlhdGVzJGZsdW94ZXRpbmUgPC0gYXMuZmFjdG9yKGNvdmFyaWF0ZXMkZmx1b3hldGluZSkNCmNvdmFyaWF0ZXMkY2FyYmFtYXplcGluZSA8LSBhcy5mYWN0b3IoY292YXJpYXRlcyRjYXJiYW1hemVwaW5lKQ0KY292YXJpYXRlcyRhbnRpY2hvbF9wcmVzZW50IDwtIGFzLmZhY3Rvcihjb3ZhcmlhdGVzJGFudGljaG9sX3ByZXNlbnQpDQpjb3ZhcmlhdGVzJGFwX3BvbHkgPC0gYXMuZmFjdG9yKGNvdmFyaWF0ZXMkYXBfcG9seSkNCg0KDQpgYGANCg0KDQpgYGB7ciBtYWtlIGRhdGFzZXQsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojIGpvaW4gZ2VuZXRpYyBkYXRhDQphbGxfZ2VuIDwtIGxlZnRfam9pbihhbGxfcHJzLCBhbGxfcGd4LCBieSA9ICJTdHVkeV9JRCIpDQphbGxfZ2VuIDwtIGxlZnRfam9pbihhbGxfZ2VuLCBwY2EsIGJ5ID0gIlN0dWR5X0lEIikNCg0KIyBtZXJnZSB3aXRoIHBoZW5vdHlwZSBkYXRhDQpkZiA8LSBsZWZ0X2pvaW4oY292YXJpYXRlcywgYWxsX2dlbiwgYnkgPSAiU3R1ZHlfSUQiKQ0KdGVzdF9kZiA8LSBsZWZ0X2pvaW4oc3ltcHRvbXMsIGRmLCBieSA9ICJTdHVkeV9JRCIpDQoNCiMgdHJlYXQgU0FQUy9TQU5TL0NhbGdhcnkgdmFyaWFibGVzIGFzIG9yZGluYWwNCnRlc3RfZGZbLGMoIlNBUFNfR2xvYmFsX0RlbHVzaW9ucyIsIlNBUFNfR2xvYmFsX0hhbHMiLCAiU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmciLCAiU0FOU19HbG9iYWxfQWxvZ2lhIiwgIlNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IiwgICJTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5IiwgDQogICAgICAgICAgIkNhbGdhcnlfU3VpY2lkZSIsICJDYWxnYXJ5X0RlcHJlc3Npb24iDQogICAgICAgICAgICldIDwtDQogICAgIGxhcHBseSh0ZXN0X2RmWyxjKCJTQVBTX0dsb2JhbF9EZWx1c2lvbnMiLCJTQVBTX0dsb2JhbF9IYWxzIiwgIlNBTlNfR2xvYmFsX0FmZmVjdGl2ZV9GbGF0dGVuaW5nIiwgIlNBTlNfR2xvYmFsX0Fsb2dpYSIsICJTQU5TX0dsb2JhbF9BbmhlZG9uaWFfQXNvY2lhbGl0eSIsICAiU0FOU19HbG9iYWxfQXZvbGl0aW9uX0FwYXRoeSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAiQ2FsZ2FyeV9TdWljaWRlIiwgIkNhbGdhcnlfRGVwcmVzc2lvbiINCiAgICAgICAgICAgICAgICAgICAgICAgKV0sIG9yZGVyZWQpIA0KDQojIHJlbW92ZSBpbnRlcm1lZGlhdGUgZGZzDQpybShhbGxfZ2VuLCBhbGxfcHJzLCBhbGxfcGd4KQ0Kcm0ocG9zaXRpdmUsIG5lZ2F0aXZlLCBjb3ZhcmlhdGVzLCBvdGhlcnMsIHBwLCBhbnRpLCBhbnRpX3ApDQpgYGANCg0KDQpgYGB7ciBoZWxwZXIgY2ZhLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KZml0czwtbGlzdCgpDQoNCnY8LWxpc3QoKQ0KdiRpdGVtczwtdGVzdF9kZiRuYW1lcw0KdiRmaXRpbmRpY2llczwtYygibnBhciIsICJjaGlzcSIsICJkZiIsICJwdmFsdWUiLCAiY2ZpIiwgInJtc2VhIiwgInJtc2VhLmNpLmxvd2VyIiwgInJtc2VhLmNpLnVwcGVyIiwgInNybXIiKQ0KDQpgYGANCg0KYGBge3IgY2ZhLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbW9kZWw0IDwtICdwb3NpdGl2ZSA9fiBTQVBTX0dsb2JhbF9IYWxzICsgU0FQU19HbG9iYWxfRGVsdXNpb25zDQogICAgICAgICAgIGV4cHJlc3MgPX4gU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmcgKyBTQU5TX0dsb2JhbF9BbG9naWEgDQogICAgICAgICAgIG1hbmRwID1+ICBTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5ICsgU0FOU19HbG9iYWxfQW5oZWRvbmlhX0Fzb2NpYWxpdHkNCiAgICAgICAgICAgc2FkID1+IENhbGdhcnlfRGVwcmVzc2lvbiArIENhbGdhcnlfU3VpY2lkZQ0KICAgICAgICAgICBjb2cgPX4gWk5BQl9NYXplc19JbXAgKyBaSFZMVF9JbXAgKyBaQlZNVF9JbXAgKyBaQ1BUX0ltcCArIFpTb1BfSW1wICsgWldNX0ltcCcNCg0KZml0cyRmb3VyIDwtIGNmYShtb2RlbDQsIGRhdGE9dGVzdF9kZikNCg0KIyBnZXQgZGltZW5zaW9ucyBmb3IgbW9kZWwgNA0KbGF0ZW50X3ZhcmlhYmxlczwtbGF2UHJlZGljdChmaXRzJGZvdXIpDQoNCmlkeCA8LSBsYXZJbnNwZWN0KGZpdHMkZm91ciwgImNhc2UuaWR4IikNCg0KIyBzZWxlY3Qgb25seSB2YXJpYWJsZXMgcmVsZXZhbnQgdG8gZG93bnN0cmVhbSBhbmFseXNpcw0KDQp0ZXN0X2RmX2RpbSA8LSB0ZXN0X2RmDQoNCg0KZm9yIChmcyBpbiBjb2xuYW1lcyhsYXRlbnRfdmFyaWFibGVzKSkgew0KICB0ZXN0X2RmX2RpbVtpZHgsIGZzXSA8LSBsYXRlbnRfdmFyaWFibGVzWyAsIGZzXQ0KfQ0KYGBgDQoNCmBgYHtyIHN0YW5kYXJkaXNlIGFuZCBzdHJhdGlmeSB0aGUgZGltZW5zaW9ucyBkYXRhfQ0KIyBzdGFuZGFyZGlzZSBhbGwgdmFyaWFibGVzIA0KdGVzdF9kZl9kaW1fc3RkIDwtIGRhdGF3aXphcmQ6OnN0YW5kYXJkaXNlKHggPSB0ZXN0X2RmX2RpbSkNCg0KIyBkbyB0aGlzIGZvciBjbG96YXBpbmUgdXNpbmcgc2FtcGxlIChmaWx0ZXIgYnkgY3VycmVudCBjbG96YXBpbmUgc3RhdHVzKQ0KdGVzdF9kZl9kaW1fc3RkX2MgPC0gZGF0YXdpemFyZDo6c3RhbmRhcmRpc2UoeCA9IGZpbHRlcih0ZXN0X2RmX2RpbSwgY2xvemFwaW5lX2N1cnJlbnQ9PTEpKQ0KDQpgYGANCg0KIyBNZWRpY2F0aW9uIGFuZCBwaGFybWFjb2dlbm9taWMgZWZmZWN0cyBvbiBjcm9zcy1zZWN0aW9uYWwgc3ltcHRvbSBzZXZlcml0eSBhbmQgY29nbml0aXZlIGFiaWxpdHkgaW4gc2NoaXpvcGhyZW5pYSB7LnRhYnNldH0NCg0KPGJyPg0KKipTaW9iaGFuIEsuIExvY2ssIERqZW5pZmVyIEIuIEthcHBlbCwgTWljaGFlbCBKLiBPd2VuLCBKYW1lcyBULlIuIFdhbHRlcnMsIE1pY2hhZWwgQy4gTydEb25vdmFuLCA8YSBocmVmID0gIm1haWx0bzogUGFyZGluYXNBQGNhcmRpZmYuYWMudWsiPiBBbnRvbmlvIC5GLiBQYXJkacOxYXMsIDwvYT4gYW5kIDxhIGhyZWYgPSAibWFpbHRvOiBMZWdnZVNFOEBjYXJkaWZmLmFjLnVrIj4gU29waGllIEUuIExlZ2dlLiA8L2E+KioNCg0KPGJyPg0KDQoqKkJhY2tncm91bmQ6KiogUGVvcGxlIHdpdGggc2NoaXpvcGhyZW5pYSBkaWZmZXIgaW4gdGhlIHR5cGUgYW5kIHNldmVyaXR5IG9mIHN5bXB0b21zIGV4cGVyaWVuY2VkLCBhcyB3ZWxsIGFzIHRoZWlyIHJlc3BvbnNlIHRvIG1lZGljYXRpb24uIEEgYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIGZhY3RvcnMgdGhhdCBpbmZsdWVuY2UgdGhpcyBoZXRlcm9nZW5laXR5IGlzIG5lY2Vzc2FyeSBmb3IgdGhlIGRldmVsb3BtZW50IG9mIGluZGl2aWR1YWxpc2VkIHBhdGllbnQgY2FyZS4gSGVyZSwgd2Ugc291Z2h0IHRvIGludmVzdGlnYXRlIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gcGhlbm90eXBpYyBzZXZlcml0eSBhbmQgYm90aCBtZWRpY2F0aW9uIGFuZCBwaGFybWFjb2dlbm9taWMgdmFyaWFibGVzIGluIGEgY3Jvc3Mtc2VjdGlvbmFsIHNhbXBsZSBvZiBwZW9wbGUgd2l0aCBzY2hpem9waHJlbmlhIG9yIHNjaGl6b2FmZmVjdGl2ZSBkaXNvcmRlciBkZXByZXNzZWQgdHlwZS4NCg0KKipNZXRob2RzOioqIENvbmZpcm1hdG9yeSBmYWN0b3IgYW5hbHlzaXMgZGVyaXZlZCBmaXZlIGRpbWVuc2lvbnMgcmVsYXRpbmcgdG8gY3VycmVudCBzeW1wdG9tcyAocG9zaXRpdmUgc3ltcHRvbXMsIG5lZ2F0aXZlIHN5bXB0b21zIG9mIGRpbWluaXNoZWQgZXhwcmVzc2l2aXR5LCBuZWdhdGl2ZSBzeW1wdG9tcyBvZiByZWR1Y2VkIG1vdGl2YXRpb24gYW5kIHBsZWFzdXJlLCBkZXByZXNzaW9uIGFuZCBzdWljaWRlKSBhbmQgY29nbml0aXZlIGFiaWxpdHkgaW4gcGFydGljaXBhbnRzIHByZXNjcmliZWQgd2l0aCBhbnRpcHN5Y2hvdGljIG1lZGljYXRpb24uIExpbmVhciBtb2RlbHMgd2VyZSBmaXQgdG8gdGVzdCBmb3IgYXNzb2NpYXRpb25zIGJldHdlZW4gbWVkaWNhdGlvbiBhbmQgcGhhcm1hY29nZW5vbWljIHZhcmlhYmxlcyB3aXRoIGRpbWVuc2lvbiBzY29yZXMgaW4gdGhlIGZ1bGwgc2FtcGxlIChOID0gNTg1KSwgYW5kIGluIGEgc3ViLXNhbXBsZSBvZiBwYXJ0aWNpcGFudHMgcHJlc2NyaWJlZCBjbG96YXBpbmUgKE4gPSAyMTUpLiANCg0KKipPdXRjb21lczoqKiBMb3dlciBjb2duaXRpdmUgYWJpbGl0eSB3YXMgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBjaGxvcnByb21hemluZS1lcXVpdmFsZW50IGRhaWx5IGFudGlwc3ljaG90aWMgZG9zZSBhbmQgd2l0aCB0aGUgcHJlc2NyaXB0aW9uIG9mIGNsb3phcGluZSBhbmQgYW50aWNob2xpbmVyZ2ljIG1lZGljYXRpb24uIFdlIGFsc28gZm91bmQgYXNzb2NpYXRpb25zIGJldHdlZW4gcGhhcm1hY29nZW5vbWljcy1pbmZlcnJlZCBjeXRvY2hyb21lIFA0NTAgKENZUCkgZW56eW1lIGFjdGl2aXR5IGFuZCBzeW1wdG9tIGRpbWVuc2lvbnMuIEluY3JlYXNlZCBnZW5vdHlwZS1wcmVkaWN0ZWQgQ1lQMkMxOSBhbmQgQ1lQM0E1IGFjdGl2aXR5IHdlcmUgYXNzb2NpYXRlZCB3aXRoIHJlZHVjZWQgc2V2ZXJpdHkgb2YgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHN5bXB0b21zLCByZXNwZWN0aXZlbHkuIEZhc3RlciBwcmVkaWN0ZWQgQ1lQMUEyIGFjdGl2aXR5IHdhcyBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIGNvZ25pdGl2ZSBkaW1lbnNpb24gc2NvcmVzIGluIHBlb3BsZSB0YWtpbmcgY2xvemFwaW5lLiANCg0KKipJbnRlcnByZXRhdGlvbjoqKiBPdXIgcmVzdWx0cyBjb25maXJtIHRoZSBpbXBvcnRhbmNlIG9mIHRha2luZyBhY2NvdW50IG9mIG1lZGljYXRpb24gaGlzdG9yeSAoYW5kIHBhcnRpY3VsYXJseSBhbnRpcHN5Y2hvdGljIHR5cGUgYW5kIGRvc2UpIGluIGFzc2Vzc2luZyBwb3RlbnRpYWwgY2F1c2VzIG9mIGNvZ25pdGl2ZSBpbXBhaXJtZW50IG9yIHBvb3IgZnVuY3Rpb25pbmcgaW4gcGF0aWVudHMgd2l0aCBzY2hpem9waHJlbmlhLiBXZSBhbHNvIGhpZ2hsaWdodCB0aGUgcG90ZW50aWFsIGZvciBwaGFybWFjb2dlbm9taWMgdmFyaWF0aW9uIHRvIGJlIGEgdXNlZnVsIHRvb2wgdG8gaGVscCBndWlkZSBkcnVnIHByZXNjcmlwdGlvbiwgYWx0aG91Z2ggdGhlc2UgZmluZGluZ3MgcmVxdWlyZSBmdXJ0aGVyIHZhbGlkYXRpb24uICANCg0KKipGdW5kaW5nOioqIFRoaXMgcHJvamVjdCB3YXMgc3VwcG9ydGVkIGJ5IGEgTWVkaWNhbCBSZXNlYXJjaCBDb3VuY2lsIFByb2dyYW1tZSBHcmFudCAoTVIvWTAwNDA5NC8xKSBhbmQgVGhlIE5hdGlvbmFsIENlbnRyZSBmb3IgTWVudGFsIEhlYWx0aCwgZnVuZGVkIGJ5IHRoZSBXZWxzaCBHb3Zlcm5tZW50IHRocm91Z2ggSGVhbHRoIGFuZCBDYXJlIFJlc2VhcmNoIFdhbGVzLiBTS0wgd2FzIGZ1bmRlZCBieSBhIFBoRCBzdHVkZW50c2hpcCBmcm9tIE1lbnRhbCBIZWFsdGggUmVzZWFyY2ggVUsgKE1IUlVLKS4gREJLLCBKVFJXLCBNQ09EIGFuZCBBRlAgd2VyZSBzdXBwb3J0ZWQgYnkgdGhlIEV1cm9wZWFuIFVuaW9u4oCZcyBIb3Jpem9uIDIwMjAgcmVzZWFyY2ggYW5kIGlubm92YXRpb24gcHJvZ3JhbW1lIHVuZGVyIGdyYW50IGFncmVlbWVudCA5NjQ4NzQuDQoNCioqQWNrbm93bGVkZ2VtZW50czoqKiBXZSB0aGFuayB0aGUgcGFydGljaXBhbnRzLCBjbGluaWNpYW5zLCBmaWVsZCB0ZWFtLCBhbmQgTWVkaWNhbCBSZXNlYXJjaCBDb3VuY2lsIENlbnRyZSBmb3IgTmV1cm9wc3ljaGlhdHJpYyBHZW5ldGljcyBhbmQgR2Vub21pY3MgY29yZSBsYWJvcmF0b3J5IHN0YWZmIGZvciB0aGVpciBoZWxwIHdpdGggdGhlIENhcmRpZmZDT0dTIHN0dWR5LiBXZSB0aGFuayB0aGUgc3RhZmYgYXQgdGhlIEJyb2FkIEluc3RpdHV0ZSBvZiBIYXJ2YXJkIGFuZCBNSVQsIGFuZCBkZUNPREUgR2VuZXRpY3MgZm9yIHNhbXBsZSBnZW5vdHlwaW5nLiBXZSB0aGFuayB0aGUgUHN5Y2hvc2lzIHRlYW0gYXQgQ2FyZGlmZiBVbml2ZXJzaXR54oCZcyBDZW50cmUgZm9yIE5ldXJvcHN5Y2hpYXRyaWMgR2VuZXRpY3MgYW5kIEdlbm9taWNzLCBwYXJ0aWN1bGFybHkgSXNhYmVsbGEgV2lsbGNvY2tzIGFuZCBTb3BoaWUgU21hcnQgZm9yIHRoZWlyIGhlbHAgYW5kIGd1aWRhbmNlIG92ZXIgdGhlIGNvdXJzZSBvZiB0aGlzIHByb2plY3QuIFdlIGFja25vd2xlZGdlIHRoZSBzdXBwb3J0IG9mIHRoZSBTdXBlcmNvbXB1dGluZyBXYWxlcyBwcm9qZWN0LCB3aGljaCBpcyBwYXJ0LWZ1bmRlZCBieSB0aGUgRXVyb3BlYW4gUmVnaW9uYWwgRGV2ZWxvcG1lbnQgRnVuZCAoRVJERikgdmlhIFdlbHNoIEdvdmVybm1lbnQuDQoNCg0KPGJyPg0KPGJyPg0KPGJyPg0KDQoNCiMjIDxzdHJvbmc+IEludHJvZHVjdGlvbiA8L3N0cm9uZz4NCg0KDQojIyMgSW50cm9kdWN0aW9uDQoNClNjaGl6b3BocmVuaWEgaXMgY2hhcmFjdGVyaXNlZCBieSBwb3NpdGl2ZSwgbmVnYXRpdmUsIGFuZCBkaXNvcmdhbmlzZWQgc3ltcHRvbXMgYWxvbmdzaWRlIGFmZmVjdGl2ZSBmZWF0dXJlcyBhbmQgY29nbml0aXZlIGRlZmljaXRzLiBUaGUgcHJlc2VudGF0aW9uIG9mIHNjaGl6b3BocmVuaWEgaXMgaGV0ZXJvZ2VuZW91cyBpbiB0aGUgcmFuZ2UgYW5kIHNldmVyaXR5IG9mIHN5bXB0b21zIGFuZCBpbiB0aGUgZGVncmVlIHRvIHdoaWNoIHRob3NlIHJlc3BvbmQgdG8gYW50aXBzeWNob3RpYyB0cmVhdG1lbnQuIEhldGVyb2dlbmVpdHkgaW4gdHJlYXRtZW50IHJlc3BvbnNlIGhhcyBiZWVuIGFzc29jaWF0ZWQgd2l0aCBwcmUtbW9yYmlkIGZ1bmN0aW9uaW5nLCBpbml0aWFsIHN5bXB0b20gc2V2ZXJpdHksIGFnZSBvZiBvbnNldCwgZHVyYXRpb24gb2YgdW50cmVhdGVkIHBzeWNob3NpcywgYXMgd2VsbCBhcyBjb21vcmJpZCBwc3ljaGlhdHJpYyBhbmQgc3Vic3RhbmNlIGFidXNlIGRpc29yZGVyc14xXi4gR2VuZXRpYyBmYWN0b3JzIG1heSBhbHNvIHBsYXkgYSByb2xlLCB3aXRoIG9uZSBzdHVkeSBzdWdnZXN0aW5nIHRoYXQgaGlnaGVyIGNvbW1vbiB2YXJpYW50IGxpYWJpbGl0eSB0byBzY2hpem9waHJlbmlhLCBhcyBpbmRleGVkIGJ5IHBvbHlnZW5pYyBzY29yZXMgKFBHUyksIGlzIGFzc29jaWF0ZWQgd2l0aCBwb29yZXIgcmVzcG9uc2UgdG8gYW50aXBzeWNob3RpY3MgYWZ0ZXIgMTIgd2Vla3Mgb2YgdHJlYXRtZW50XjJeLiBTaW1pbGFybHksIGJvdGggbG9uZ2l0dWRpbmFsIGFuZCBjcm9zcy1zZWN0aW9uYWwgcmVzZWFyY2ggaGFzIGRlbW9uc3RyYXRlZCBhbiBhc3NvY2lhdGlvbiBiZXR3ZWVuIGhpZ2hlciBzY2hpem9waHJlbmlhIFBHUyBhbmQgZ3JlYXRlciBzZXZlcml0eSBvZiBuZWdhdGl2ZSBhbmQgY29nbml0aXZlIHN5bXB0b20gZGltZW5zaW9uc14z4oCTNV4uICANCg0KQmV5b25kIHBvbHlnZW5pYyByaXNrLCB2YXJpYXRpb24gaW4gZ2VuZXMgZW5jb2RpbmcgcHJvdGVpbnMga2V5IHRvIHBoYXJtYWNva2luZXRpYyBvciBwaGFybWFjb2R5bmFtaWMgcHJvY2Vzc2VzICjigJxwaGFybWFjb2dlbmVz4oCdKSBtYXkgYWxzbyBpbmZsdWVuY2UgcmVzcG9uc2UgdG8gYW50aXBzeWNob3RpYyBtZWRpY2F0aW9uXjZeLiBQaGFybWFjb2dlbm9taWMgc3RhciBhbGxlbGVzIGRlc2NyaWJlIHNpbmdsZSBvciBtdWx0aXBsZSBnZW5ldGljIG1hcmtlcnMgdGhhdCBhbHRlciB0aGUgZnVuY3Rpb24gb2YgcHJvdGVpbnMgaW5mbHVlbmNpbmcgZHJ1ZyByZXNwb25zZS4gVGhlIG1vc3Qgd2lkZWx5IHJlc2VhcmNoZWQgcGhhcm1hY29nZW5lcyBhcmUgd2l0aGluIHRoZSBjeXRvY2hyb21lIFA0NTAgKENZUCkgZmFtaWx5LCB3aGljaCBhcmUgaW1wbGljYXRlZCBpbiBkcnVnIG1ldGFib2xpc20gYW5kIGFyZSBoaWdobHkgdmFyaWFibGUgd2l0aGluIGFuZCBhY3Jvc3MgcG9wdWxhdGlvbnMuIFdoaWxlIGRydWcgbWV0YWJvbGlzbSBwYXRod2F5cyBhcmUgb2Z0ZW4gd2VsbC1zdHVkaWVkIGJpb2NoZW1pY2FsbHksIHRoZSBleHRlbnQgdG8gd2hpY2ggYmV0d2Vlbi1wZXJzb24gdmFyaWFiaWxpdHkgaW4gdGhlc2UgcGF0aHdheXMgaW5mbHVlbmNlcyBkcnVnIGVmZmVjdGl2ZW5lc3MgaXMgc3RpbGwgdW5jbGVhci4gKipGaWd1cmUgMSoqIGlsbHVzdHJhdGVzIGhvdyBhIHBoYXJtYWNvZ2Vub21pYyBhbHRlcmF0aW9uIGluIGEga2V5IG1ldGFib2xpYyBlbnp5bWUgbWlnaHQgYWZmZWN0IHJlc3BvbnNlIHRvIGEgbWVkaWNhdGlvbi4gV2hpbGUgc3VjaCBlZmZlY3RzIGFyZSBpbnR1aXRpdmUgYW5kIGZvcm0gdGhlIGJhc2lzIG9mIHN1Y2Nlc3NmdWwgcHJvc3BlY3RpdmUgdHJpYWxzXjdeLCBhcyBvZiBKdW5lIDIwMjQsIG9ubHkgMTAgYW50aXBzeWNob3RpY3MgaGF2ZSByZWd1bGF0b3ItYXBwcm92ZWQgZ3VpZGVsaW5lcyB3aXRoIGFjdGlvbmFibGUgcGhhcm1hY29nZW5vbWljIG1hcmtlcnMgaW4gdGhlIFBoYXJtR0tCIGRhdGFiYXNlXjheLiBSZXZpZXdzIGZyb20gZXhwZXJ0IGNvbnNvcnRpYSByZXBvcnQgYSBzaW1pbGFyIG51bWJlciBvZiBkcnVncyB3aGVyZSBwaGFybWFjb2dlbm9taWMgaW5mb3JtYXRpb24gbWlnaHQgYmUgb2YgdXNlIGluIGNsaW5pY2FsIHNldHRpbmdzXjleLCB0aG91Z2ggdGhleSBhbHNvIGhpZ2hsaWdodCB0aGUgcGF1Y2l0eSBvZiBzdHVkaWVzIGluIHRoZSBhcmVhLiAgDQoNCmBgYHtyIGZpZyAxLCBmaWcuY2FwPSAiRmlndXJlIDEuIFRoZSBtYWpvcml0eSBvZiBDWVAtbWVkaWF0ZWQgZHJ1ZyBtZXRhYm9saXNtIG9jY3VycyBoZXBhdGljYWxseS4gUGhhcm1hY29nZW5vbWljIHZhcmlhdGlvbiBjYW4gcmVzdWx0IGluIGluY3JlYXNlZCwgZGVjcmVhc2VkLCBvciBubyBjaGFuZ2UgdG8gZW56eW1lIGFjdGl2aXR5LiBJbmNyZWFzZWQgZW56eW1lIGFjdGl2aXR5IGxlYWRzIHRvIGZhc3RlciBtZXRhYm9saXNtLCByZXN1bHRpbmcgaW4gYSBsb3dlciBkcnVnIGNvbmNlbnRyYXRpb24uIFRoaXMgY2FuIGJlIGV4cGVjdGVkIHRvIGxlYWQgdG8gaXRzIHJlZHVjZWQgZWZmZWN0aXZlbmVzcyBidXQgYWxzbyBhIHJlZHVjZWQgcmlzayBmb3IgdG94aWNpdHkgYW5kIGFkdmVyc2UgZHJ1ZyByZWFjdGlvbnMuIENvbnZlcnNlbHksIHZhcmlhdGlvbiBsZWFkaW5nIHRvIHJlZHVjZWQgZW56eW1lIGFjdGl2aXR5IHJlc3VsdHMgaW4gc2xvd2VyIG1ldGFib2xpc20gb2YgZW56eW1lIHN1YnN0cmF0ZXMuIFRoaXMgY2FuIHJlc3VsdCBpbiBoaWdoZXIgZHJ1ZyBjb25jZW50cmF0aW9ucyB0aGF0IG1pZ2h0IHJlc3VsdCBpbiBpbmNyZWFzZWQgZWZmZWN0aXZlbmVzcyBidXQgYWxzbyBpbmNyZWFzZWQgcmlzayBvZiB0b3hpY2l0eS4gVGhlIGV4YWN0IGNvbnNlcXVlbmNlcyBvZiBwaGFybWFjb2dlbm9taWMgdmFyaWF0aW9uIGRlcGVuZCBvbiB0aGUgZW56eW1lLCBkcnVnLCBhbmQgbWV0YWJvbGl0ZShzKSBpbiBxdWVzdGlvbjsgZm9yIGV4YW1wbGUsIGVmZmVjdHMgbWlnaHQgdmFyeSBpZiB0aGUgbWV0YWJvbGl0ZSBoYXMgdGhlIHBvdGVudGlhbCB0byBjYXVzZSBzaWRlIGVmZmVjdHMgb3IgaWYgdGhlIGFkbWluaXN0ZXJlZCBkcnVnIGlzIGEgcHJvZHJ1Zy4ifQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiV3JpdGluZy9maWdzL2ZpbjFzdC5wbmciKQ0KYGBgDQoNCjxicj4NCg0KDQpFc3RhYmxpc2hpbmcgYSBwaGFybWFjb2dlbm9taWMgbWFya2VyIGFzIOKAnGFjdGlvbmFibGXigJ0gcmVxdWlyZXMgYW4gZXZhbHVhdGlvbiBvZiBpdHMgZWZmZWN0cyBvbiBwaGVub3R5cGVzIGJleW9uZCBkcnVnIG1ldGFib2xpc20gYW5kIHBoYXJtYWNva2luZXRpY3MsIGFuZCBzdHVkaWVzIG9uIGNsaW5pY2FsIG91dGNvbWVzIGNhbiBiZSB2YWx1YWJsZSBpbiB0aGVzZSBkZWNpc2lvbnNeOV4uIFRoZXJlIGlzIHByZWxpbWluYXJ5IGV2aWRlbmNlIHRoYXQgbGV2ZXJhZ2luZyBwaGFybWFjb2dlbm9taWMgc3RhciBhbGxlbGVzIHRvIGluZmVyIGVuenltZSBhY3Rpdml0eSBtYXkgaGVscCBwcmVkaWN0IHNjaGl6b3BocmVuaWEgc3ltcHRvbSBzZXZlcml0eSBpbiB0aG9zZSB0YWtpbmcgY2xvemFwaW5lLCB0aGUgb25seSBldmlkZW5jZS1iYXNlZCBtZWRpY2F0aW9uIGZvciB0cmVhdG1lbnQtcmVzaXN0YW50IHNjaGl6b3BocmVuaWEgKFRSUykuIENsb3phcGluZSBoYXMgYSBjb21wbGV4IG1ldGFib2xpYyBwYXRod2F5IGJ1dCBtb3N0IG9mIGl0cyBmaXJzdC1wYXNzIGJpb2NvbnZlcnNpb24gaXMgZHJpdmVuIGJ5IENZUDFBMiwgd2l0aCBtaW5vciBjb250cmlidXRpb25zIG9mIENZUDJDMTkgYW5kIENZUDJENl4xMF4uIFR3byByZWNlbnQgc3R1ZGllcyByZXBvcnRlZCBhc3NvY2lhdGlvbnMgYmV0d2VlbiBzY2hpem9waHJlbmlhIHN5bXB0b20gc2V2ZXJpdHkgYW5kIGdlbm90eXBlLXByZWRpY3RlZCBlbnp5bWUgYWN0aXZpdHkgZm9yIENZUDFBMl4xMV4gYW5kIENZUDJDMTleMTJeIGluIHBlb3BsZSB3aXRoIFRSUyB0YWtpbmcgdGhpcyBtZWRpY2F0aW9uLiBIb3dldmVyLCB0aGUgZWZmZWN0cyByZXBvcnRlZCB3ZXJlIGluY29uc2lzdGVudCBiZXR3ZWVuIHN0dWRpZXMsIGFuZCB0aGVpciBpbnRlcnByZXRhdGlvbiBpcyBjb21wbGljYXRlZCBieSBkaWZmZXJlbmNlcyBpbiB0aGUgc3RhdGlzdGljYWwgbWV0aG9kb2xvZ3kgYW5kIHN5bXB0b20gcmF0aW5nIHNjYWxlcyB1c2VkLg0KDQpUaGUgcHJlc2VudCBzdHVkeSBhaW1zIHRvIGludmVzdGlnYXRlIHBvc3NpYmxlIGxpbmtzIGJldHdlZW4gbWVkaWNhdGlvbiBhbmQgcGhhcm1hY29nZW5vbWljIHZhcmlhYmxlcyB3aXRoIGN1cnJlbnQgc2NoaXpvcGhyZW5pYSBzeW1wdG9tIHNldmVyaXR5IGFuZCBjb2duaXRpdmUgYWJpbGl0eSBpbiBhIFVLLWJhc2VkIHNhbXBsZSBvZiBpbmRpdmlkdWFscyB0cmVhdGVkIHdpdGggYW50aXBzeWNob3RpYyBtZWRpY2F0aW9uLiBBbHRob3VnaCBjcm9zcy1zZWN0aW9uYWwsIHRoZSBpbmNsdXNpb24gb2YgcGhhcm1hY29nZW5vbWljIGluZm9ybWF0aW9uIGFsb25nc2lkZSBtZWRpY2F0aW9uIHZhcmlhYmxlcyBvZmZlcnMgdGhlIHBvdGVudGlhbCB0byBpbmZvcm0gdGhlIGNhdXNhbCBkaXJlY3Rpb24gb2YgYXNzb2NpYXRpb25zLiBXZSBhbHNvIHJlcHJvZHVjZWQgcHJldmlvdXMgcGhhcm1hY29nZW5vbWljIGFuYWx5c2VzXjExLDEyXiBpbiBhIHN1YnNhbXBsZSByZXN0cmljdGVkIHRvIHBhdGllbnRzIHByZXNjcmliZWQgY2xvemFwaW5lLiBPdXIgd29yayBmb2xsb3dzIHJlY2VudCBjYWxscyB0byBvdmVyY29tZSDigJxvbmUgc2l6ZSBmaXRzIGFsbOKAnSBhcHByb2FjaGVzIGluIHBzeWNob3BoYXJtYWNvbG9neSBieSBkaXJlY3RseSBzZWFyY2hpbmcgZm9yIHByZWRpY3RvcnMgb2YgY2xpbmljYWwgb3V0Y29tZXMgYW5kIHBoYXJtYWNvZHluYW1pY3NeMTMsMTReLCBhcyB0aGVzZSBhcmUgZXNzZW50aWFsIHRvIGFkdmFuY2luZyB0aGUgZmllbGQgb2YgcHJlY2lzaW9uIHBzeWNoaWF0cnkgdGhyb3VnaCBlZmZlY3RpdmUgcGF0aWVudCBzdHJhdGlmaWNhdGlvbi4gDQoNCjxicj4NCjxicj4NCjxicj4NCjxicj4NCg0KIyMgPHN0cm9uZz4gTWV0aG9kcyA8L3N0cm9uZz4gDQojIyMgTWV0aG9kcw0KDQojIyMjIFBhcnRpY2lwYW50cw0KDQpXZSBpbmNsdWRlZCBgciBucm93KHRlc3RfZGZfZGltX3N0ZClgIGluZGl2aWR1YWxzIGZyb20gdGhlIENhcmRpZmYgQ09Hbml0aW9uIGluIFNjaGl6b3BocmVuaWEgKENhcmRpZmZDT0dTKSBjb2hvcnQgKCoqU3VwcGxlbWVudGFyeSBGaWd1cmUgMSoqKS4gQ2FyZGlmZkNPR1MgcmVjZWl2ZWQgYXBwcm92YWwgZnJvbSB0aGUgU291dGgtRWFzdCBXYWxlcyBSZXNlYXJjaCBFdGhpY3MgQ29tbWl0dGVlICgwNy9XU0UwMy8xMTApIGFuZCBhbGwgcGFydGljaXBhbnRzIHByb3ZpZGVkIHdyaXR0ZW4gaW5mb3JtZWQgY29uc2VudC4gUGFydGljaXBhbnRzIHdlcmUgcmVjcnVpdGVkIGZyb20gaW5wYXRpZW50IGFuZCBjb21tdW5pdHkgYWR1bHQgbWVudGFsIGhlYWx0aCBzZXJ2aWNlcyBhbmQgdm9sdW50YXJ5IHNlcnZpY2VzIGFjcm9zcyB0aGUgVUsuIFBhdGllbnRzIHdlcmUgYWxzbyByZWNydWl0ZWQgZnJvbSBjbG96YXBpbmUgY2xpbmljczsgdGhlcmVmb3JlLCB0aGUgY29ob3J0IHdhcyBlbnJpY2hlZCBmb3IgdGhvc2Ugd2l0aCB0cmVhdG1lbnQgcmVzaXN0YW5jZSAoVFJTOyBOID0gYHIgcm91bmQobnJvdyh0ZXN0X2RmX2RpbV9zdGRfYykvbnJvdyh0ZXN0X2RmX2RpbV9zdGQpKjEwMCwgMClgJSkuICBBbGwgcGFydGljaXBhbnRzIGNvbXBsZXRlZCBhIGNsaW5pY2FsIHJlc2VhcmNoIGludGVydmlldyBiYXNlZCBvbiB0aGUgU2NoZWR1bGVzIGZvciBDbGluaWNhbCBBc3Nlc3NtZW50IGluIE5ldXJvcHN5Y2hpYXRyeV4xNV4gKFNDQU4pIGFuZCBwcm92aWRlZCBhIGJsb29kIHNhbXBsZSBmb3IgZ2VuZXRpYyBhbmFseXNlcy4gQWxsIHBhcnRpY2lwYW50cyBtZXQgRFNNLUlWXjE2XiBvciBJQ0QtMTBeMTdeIGRpYWdub3NlcyBmb3Igc2NoaXpvcGhyZW5pYSBvciBzY2hpem9hZmZlY3RpdmUgZGlzb3JkZXIsIGRlcHJlc3NlZCB0eXBlIGJhc2VkIG9uIHRoZSBTQ0FOLWJhc2VkIGludGVydmlldyBhbmQgY2xpbmljYWwgY2FzZSBub3RlIHJldmlldy4gQSBmdWxsIGRlc2NyaXB0aW9uIG9mIHRoZSBjb2hvcnQgd2l0aCBhZGRpdGlvbmFsIGRldGFpbHMgaXMgcHJvdmlkZWQgZWxzZXdoZXJlXjReLiANCg0KDQoNCjxicj4NCg0KIyMjIyBQaGVub3R5cGUgRGF0YQ0KDQpUaGUgc2V2ZXJpdHkgb2YgcG9zaXRpdmUsIG5lZ2F0aXZlLCBhZmZlY3RpdmUsIGFuZCBkaXNvcmdhbmlzZWQgc3ltcHRvbXMgd2VyZSBhc3Nlc3NlZCBhdCB0aGUgdGltZSBvZiB0aGUgaW50ZXJ2aWV3IGFuZCBhcmUgcmVmZXJyZWQgdG8gaGVyZWFmdGVyIGFzIOKAnGN1cnJlbnTigJ0gc3ltcHRvbXMuIFN5bXB0b21zIHdlcmUgcmF0ZWQgdXNpbmcgdGhlIFNjYWxlIGZvciB0aGUgQXNzZXNzbWVudCBvZiBQb3NpdGl2ZSBTeW1wdG9tc14xOF4gKFNBUFMpLCB0aGUgU2NhbGUgZm9yIHRoZSBBc3Nlc3NtZW50IG9mIE5lZ2F0aXZlIFN5bXB0b21zXjE5XiAoU0FOUyksIGFuZCB0aGUgQ2FsZ2FyeSBEZXByZXNzaW9uIFNjYWxlIGZvciBTY2hpem9waHJlbmlhXjIwXi4gQ29nbml0aXZlIGFiaWxpdHkgd2FzIGFzc2Vzc2VkIHVzaW5nIHRoZSBNQVRSSUNTIENvbnNlbnN1cyBDb2duaXRpdmUgQmF0dGVyeV4yMV4gKE1DQ0IpLiBNaXNzaW5nIHZhbHVlcyBmb3IgTUFUUklDUyB2YXJpYWJsZXMgd2VyZSBpbXB1dGVkIGluIGFjY29yZGFuY2Ugd2l0aCBndWlkYW5jZSBmcm9tIHRoZSBNQ0NCIGhhbmRib29rIGJlZm9yZSBiZWluZyBzdGFuZGFyZGlzZWQgYWdhaW5zdCB1bmFmZmVjdGVkIGNvbnRyb2xzLiANCg0KQWxsIHBhcnRpY2lwYW50cyB3ZXJlIHRyZWF0ZWQgd2l0aCBhbnRpcHN5Y2hvdGljcyBhdCB0aGUgdGltZSBvZiB0aGUgaW50ZXJ2aWV3LiBNZWRpY2F0aW9uIGRhdGEgd2VyZSBvYnRhaW5lZCB2aWEgc2VsZi1yZXBvcnQgYW5kIGNhc2Ugbm90ZSByZXZpZXcuIEEgYmluYXJ5IG1lZGljYXRpb24gYWRoZXJlbmNlIHZhcmlhYmxlIHdhcyBjcmVhdGVkIGZyb20gYW4gb3JkaW5hbCBxdWVzdGlvbm5haXJlIHJlc3BvbnNlIHRoYXQgd2FzIGJhc2VkIG9uIHRoZSBNZWRpY2F0aW9uIEFkaGVyZW5jZSBSYXRpbmcgU2NhbGVeMjJeIChzZWUgKipTdXBwbGVtZW50YXJ5IE1hdGVyaWFscyoqKS4gQW50aXBzeWNob3RpYyBkb3NlcyB3ZXJlIGNvbnZlcnRlZCB0byBjaGxvcnByb21hemluZSBlcXVpdmFsZW50cyB1c2luZyB0aGUgKkNobG9ycHJvbWF6aW5lUiogcGFja2FnZV4yM14uIERvc2VzIHdlcmUgY29udmVydGVkIGJhc2VkIG9uIGludGVybmF0aW9uYWwgY29uc2Vuc3VzIHZhbHVlcyB3aGVyZSBhdmFpbGFibGUsIGFuZCBXb3JsZCBIZWFsdGggT3JnYW5pc2F0aW9uIERhaWx5IERlZmluZWQgRG9zZSB2YXJpYWJsZXMgb3RoZXJ3aXNlXjI0LDI1Xi4gV2hlcmUgaW5kaXZpZHVhbHMgcmVwb3J0ZWQgdGFraW5nIG11bHRpcGxlIGFudGlwc3ljaG90aWNzIGNvbmN1cnJlbnRseSwgZWFjaCBhbnRpcHN5Y2hvdGljIGRvc2Ugd2FzIGNvbnZlcnRlZCBhbmQgdGhlbiBzdW1tZWQgdG8gZ2l2ZSB0aGUgdG90YWwgY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudCBkb3NlLiBQYXJ0aWNpcGFudHMgIChOID0gYHIgbl9leGNsYCkgd2VyZSBleGNsdWRlZCB3aGVuIChpKSBubyBhZGhlcmVuY2UgaW5mb3JtYXRpb24gd2FzIGF2YWlsYWJsZSBvciB3aGVuLCBmb3IgYW55IGFudGlwc3ljaG90aWMgcmVwb3J0ZWQ6IChpaSkgdGhlIGRydWcgbmFtZSB3YXMgbm90IGRvY3VtZW50ZWQgb3IgKGlpaSkgbm8gZG9zZSBpbmZvcm1hdGlvbiB3YXMgcmVwb3J0ZWQuDQoNCkEgYmluYXJ5IGluZGV4IGZvciB0aGUgcHJlc2VuY2UvYWJzZW5jZSBvZiBjdXJyZW50IGFudGljaG9saW5lcmdpYyBkcnVnIHVzZSB3YXMgY3JlYXRlZCBiYXNlZCBvbiB0aGUgY3VycmVudCBwcmVzY3JpcHRpb24gb2YgUHJvY3ljbGlkaW5lLCBIeW9zY2luZSwgQmVuenRyb3BpbmUsIEJlbnpoZXhvbCwgb3IgUGlyZW56ZXBpbmUuICBUaGUgR2xvYmFsIEFzc2Vzc21lbnQgU2NhbGVeMjZeICB3YXMgdXNlZCBhcyBhIG1lYXN1cmUgb2YgY3VycmVudCBmdW5jdGlvbmluZy4gDQoNCjxicj4NCg0KIyMjIyBHZW5ldGljIERhdGENCg0KUGFydGljaXBhbnRzIHdlcmUgZ2Vub3R5cGVkIHdpdGggdGhlIElsbHVtaW5hIEh1bWFuT21uaUV4cHJlc3NFeG9tZSB2OCBvciB0aGUgSWxsdW1pbmEgSHVtYW5PbW5pRXhwcmVzcyB2MTIgKElsbHVtaW5hIEluYywgVVNBKSBhdCB0aGUgQnJvYWQgSW5zdGl0dXRlIG9mIEhhcnZhcmQgYW5kIE1JVCwgTUEsIFVTQSBhbmQgZGVDT0RFIEdlbmV0aWNzLCBSZXlramF2w61rLCBJY2VsYW5kLiBUaGlzIHByb2NlZHVyZSBhbmQgdGhlIGN1cmF0aW9uIGFuZCBoYXJtb25pc2F0aW9uIG9mIGRhdGEgZnJvbSBkaWZmZXJlbnQgYXJyYXlzIGhhdmUgYmVlbiBkZXNjcmliZWQgcHJldmlvdXNseV4yN14uIENvbWJpbmVkIGdlbmV0aWMgZGF0YSBmb3IgYWxsIHNhbXBsZXMgd2VyZSBwcm9jZXNzZWQgdXNpbmcgdGhlIERSQUdPTi1kYXRhIHF1YWxpdHktY29udHJvbCBwaXBlbGluZSDigJxHZW5vdHlwZVFDdG9IUkPigJ1eMjheIHdpdGggZGVmYXVsdCBwYXJhbWV0ZXJzIGFuZCBpbXB1dGVkIG9uIHRoZSBNaWNoaWdhbiBJbXB1dGF0aW9uIFNlcnZlciAoc2VlICoqU3VwcGxlbWVudGFyeSBNYXRlcmlhbHMqKikuIA0KDQpQaGFybWFjb2dlbm9taWMgbWFya2VycyBmb3IgZW56eW1lcyBrbm93biB0byBtZXRhYm9saXNlIGFudGlwc3ljaG90aWMgZHJ1Z3MgKENZUDFBMiwgQ1lQMkM5LCBDWVAyQzE5LCBDWVAyRDYsIGFuZCBDWVAzQTUpIHdlcmUgY2FsbGVkIHVzaW5nIHRoZSAqcnVuLWNoaXAtcGlwZWxpbmUqIGNvbW1hbmQgaW4gUHlQR3ggdjAuMjAuMF4yOV4gaW4gUHl0aG9uIHYzLjkuMl4zMF4uIEFjdGl2aXR5IHNjb3JlcyB3ZXJlIGRlcml2ZWQgZnJvbSBwaGFybWFjb2dlbm9taWMgYWxsZWxlcyBhcyBkZXNjcmliZWQgaW4gdGhlICoqU3VwcGxlbWVudGFyeSBNYXRlcmlhbHMqKiBhbmQgKipTdXBwbGVtZW50YXJ5IFRhYmxlIDEqKi4NCg0KUEdTIGZvciBzY2hpem9waHJlbmlhXjMxXiwgaW50ZWxsaWdlbmNlXjMyXiwgYW5kIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnReMzNeIHdlcmUgY2FsY3VsYXRlZCB1c2luZyBQUlMtQ1NeMzReIGFuZCBQTElOSyB2MS45XjM1Xi4gU05QIGVmZmVjdCBzaXplcyAoQkVUQS9PZGRzIFJhdGlvKSB3ZXJlIHVzZWQgYWxvbmdzaWRlIHN0YW5kYXJkIGVycm9ycyB0byBjb21wdXRlIHBvc3RlcmlvciBlZmZlY3Qgc2l6ZXMgaW4gUFJTLUNTLiBUaGUgMTAwMCBHZW5vbWVzIFByb2plY3QgcGhhc2UgMyBFdXJvcGVhbiBMaW5rYWdlIERpc2VxdWlsaWJyaXVtIChMRCkgcmVmZXJlbmNlIHBhbmVsIHdhcyB1c2VkIHRvIGFjY291bnQgZm9yIGxpbmthZ2UgZGlzZXF1aWxpYnJpdW1eMzZeLiBBZGRpdGlvbmFsIHBhcmFtZXRlcnMgaW4gUFJTLUNTIGluY2x1ZGVkIDEwLDAwMCBidXJuLWluIGl0ZXJhdGlvbnMsIDI1LDAwMCBNYXJrb3YgY2hhaW4gTW9udGUgQ2FybG8gaXRlcmF0aW9ucywgYW5kIGEgZ2xvYmFsIHNocmlua2FnZSBwYXJhbWV0ZXIgcGhpIG9mIDEgZm9yIHNjaGl6b3BocmVuaWEgb3Ig4oCcYXV0b+KAnSBmb3IgaW50ZWxsaWdlbmNlIGFuZCBlZHVjYXRpb24gYXR0YWlubWVudC4gRWZmZWN0IHNpemVzIGdlbmVyYXRlZCBpbiBQUlMtQ1Mgd2VyZSBwYXNzZWQgdG8gUExJTksgdjEuOSBmb3Igc2NvcmluZy4gUEdTIHdlcmUgYmFzZWQgb24gY3VzdG9tIEdXQVMgZGF0YXNldHMgZnJvbSB3aGljaCBhbGwgcGFydGljaXBhbnRzIG9mIHRoZSBjdXJyZW50IHN0dWR5IGhhZCBiZWVuIGV4Y2x1ZGVkLg0KDQpUbyBhY2NvdW50IGZvciBwb3B1bGF0aW9uIHN0cmF0aWZpY2F0aW9uLCBhIHN1YnNldCBvZiBjb21tb24gU05QcyB3aXRoIGhpZ2ggaW1wdXRhdGlvbiBxdWFsaXR5IChNQUYgPiAwLjA1LCBJTkZPID4gMC45KSwgYW5kIGxvdyBsZXZlbHMgb2YgTEQgKHIyIDwgMC4yKSB3YXMgc2VsZWN0ZWQgdG8gY2FsY3VsYXRlIHByaW5jaXBhbCBjb21wb25lbnRzIHVzaW5nIHRoZSBwcmluY2lwYWwgY29tcG9uZW50IGFuYWx5c2lzIGZ1bmN0aW9uIGluIFBMSU5LIHYyXjM1Xi4gDQoNCg0KPGJyPg0KDQojIyMjIFN0YXRpc3RpY2FsIEFuYWx5c2lzDQoNCkRhdGEgd2VyZSBhbmFseXNlZCB1c2luZyBSIHY0LjQuMCBpbiBSIFN0dWRpbyAyMDI0LjA0LjAgQnVpbGQgNzM1XjM3Xi4gQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyAoQ0ZBKSB3YXMgdXNlZCB0byBkZXJpdmUgYSBsYXRlbnQgZmFjdG9yIG1vZGVsIGZvciBjdXJyZW50IHN5bXB0b20gc2V2ZXJpdHkgaW4gc2NoaXpvcGhyZW5pYSBiYXNlZCBvbiBvdGhlciBsYXRlbnQgbW9kZWxzXjQsNSwzOCwzOV4uIFZhcmlhYmxlcyBjb250cmlidXRpbmcgdG8gdGhlIG1vZGVsIHdlcmUgZ2xvYmFsIHN5bXB0b20gbWVhc3VyZXMgZnJvbSB0aGUgU0FQUyBhbmQgU0FOUywgdGhlIHNlbGYtcmVwb3J0IGRlcHJlc3NlZCBtb29kIGFuZCBzdWljaWRhbCBpZGVhdGlvbiBhbmQgYWN0cyBpdGVtcyBmcm9tIHRoZSBDYWxnYXJ5IERlcHJlc3Npb24gU2NhbGUgZm9yIFNjaGl6b3BocmVuaWEsIGFuZCB0aGUgZG9tYWluIHNjb3JlcyAoZXhjbHVkaW5nIHNvY2lhbCBjb2duaXRpb24pIGZyb20gTUFUUklDUy4gUmF0aW5ncyBmcm9tIFNBUFMsIFNBTlMsIGFuZCBDYWxnYXJ5IERlcHJlc3Npb24gU2NhbGUgZm9yIFNjaGl6b3BocmVuaWEgd2VyZSBvcmRpbmFsICgwIOKAkyA1LCBTQVBTIGFuZCBTQU5TOyAwIOKAkyAzLCBDYWxnYXJ5IERlcHJlc3Npb24gU2NhbGUgZm9yIFNjaGl6b3BocmVuaWEpLiBNQVRSSUNTIHZhcmlhYmxlcyB3ZXJlIGNvbnRpbnVvdXMuICpsYXZhYW4qIHdhcyB1c2VkIHRvIGZpdCB0aGUgQ0ZBLCB1c2luZyBkZWZhdWx0IHNldHRpbmdzXjQwXi4gRGltZW5zaW9uIHNjb3JlcyBiYXNlZCBvbiB0aGUgYmVzdCBmaXQgQ0ZBIG1vZGVsIHdlcmUgY2FsY3VsYXRlZCBmb3IgZWFjaCBwYXJ0aWNpcGFudC4gTW9kZWwgZml0IHdhcyBndWlkZWQgYnkgdGhlIENvbXBhcmF0aXZlIEZpdCBJbmRleCwgUm9vdCBNZWFuIFNxdWFyZSBFcnJvciBvZiBBcHByb3hpbWF0aW9uLCBhbmQgdGhlIFN0YW5kYXJkaXNlZCBSb290IE1lYW4gU3F1YXJlZCBSZXNpZHVhbC4gV2Ugd291bGQgZXhwZWN0IHRoYXQgY3VycmVudCBwaGVub3R5cGUgc2V2ZXJpdHksIGluZGV4ZWQgYnkgbGF0ZW50IHZhcmlhYmxlIHNjb3Jlcywgd291bGQgYmUgYXNzb2NpYXRlZCB3aXRoIGZ1bmN0aW9uYWwgaW1wYWlybWVudHMuIFRoZXJlZm9yZSwgYXMgYW4gaW4tc2FtcGxlIHZhbGlkaXR5IGNoZWNrIG9mIG91ciBkZXJpdmVkIHZhcmlhYmxlcywgd2UgcmVncmVzc2VkIGVhY2ggZmFjdG9yIGFnYWluc3QgdGhlIEdsb2JhbCBBc3Nlc3NtZW50IFNjYWxlLg0KDQpMaW5lYXIgcmVncmVzc2lvbiBtb2RlbHMgd2VyZSB1c2VkIHRvIHRlc3QgZm9yIGFzc29jaWF0aW9ucyBiZXR3ZWVuIG1lZGljYXRpb24gdmFyaWFibGVzIGFuZCBzeW1wdG9tIGRpbWVuc2lvbnMuIE1lZGljYXRpb24gdmFyaWFibGVzIGluY2x1ZGVkIGRhaWx5IGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQgYW50aXBzeWNob3RpYyBkb3NlLCBjbG96YXBpbmUgdXNlLCBhbmQgYW50aWNob2xpbmVyZ2ljIHVzZS4gQWxsIGNvbnRpbnVvdXMgdmFyaWFibGVzIHdlcmUgc3RhbmRhcmRpc2VkLCBhbmQgYWxsIG1vZGVscyBjb250cm9sbGVkIGZvciBzY2hpem9waHJlbmlhIFBHUywgbWVkaWNhdGlvbiBhZGhlcmVuY2UsIGFnZSwgc2V4LCBhbmQgdGhlIGZpcnN0IDUgZ2VuZXRpYyBwcmluY2lwYWwgY29tcG9uZW50cy4gRmluYWxseSwgaW50ZWxsaWdlbmNlIGFuZCBlZHVjYXRpb25hbCBhdHRhaW5tZW50IFBHUyB3ZXJlIHVzZWQgYXMgYW4gZXN0aW1hdGUgZm9yIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2UgaW4gdGhlIGFuYWx5c2VzIGludmVzdGlnYXRpbmcgdGhlIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbi4gIFdlIGNob3NlIHRoZXNlIFBHUyBhcyB0b2dldGhlciB0aGV5IGFyZSB0aGUgc3Ryb25nZXN0IGdlbmV0aWMgcHJlZGljdG9yIG9mIGludGVsbGlnZW5jZSBpbiBwcmV2aW91cyByZXNlYXJjaF40MSw0Ml4sIGFuZCBuZWl0aGVyIHZhcmlhYmxlIHdhcyBhc3NvY2lhdGVkIHdpdGggY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudCBhbnRpcHN5Y2hvdGljIGRvc2UgaW4gb3VyIHRvdGFsIHNhbXBsZS4gSW4gY29udHJhc3QsIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2UgZXN0aW1hdGVkIGZyb20gdGhlIE5hdGlvbmFsIEFkdWx0IFJlYWRpbmcgVGVzdCAoTkFSVCleNDNeIHdhcyBhc3NvY2lhdGVkIHdpdGggZG9zZSBpbmRpY2F0aW5nIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGFudGlwc3ljaG90aWMgZG9zZSBpbmZsdWVuY2VkIHBlcmZvcm1hbmNlIG9uIHRoZSBOQVJUIG9yIHZpY2UgdmVyc2EuIE5ldmVydGhlbGVzcywgYW4gYWx0ZXJuYXRpdmUgYW5hbHlzaXMgdXNpbmcgcHJlbW9yYmlkIGludGVsbGlnZW5jZSBhcyBlc3RpbWF0ZWQgYnkgdGhlIE5BUlQgaXMgcHJvdmlkZWQgaW4gdGhlICoqU3VwcGxlbWVudGFyeSBNYXRlcmlhbHMqKi4gIA0KDQpUaGUgbW9kZWwgd2FzIGV4dGVuZGVkIGJ5IGluY2x1ZGluZyBhY3Rpdml0eSBzY29yZXMgZm9yIENZUDFBMiwgQ1lQMkM5LCBDWVAyQzE5LCBDWVAyRDYsIGFuZCBDWVAzQTUgdG8gdGVzdCB0aGVpciBwb3RlbnRpYWwgdG8gbWVkaWF0ZSBvciBtb2RlcmF0ZSBhbnkgYXNzb2NpYXRpb25zIGluIHRoZSB0b3RhbCBzYW1wbGUsIGFuZCBpbiB0aGUgc3ViZ3JvdXAgb2YgcGFydGljaXBhbnRzIHByZXNjcmliZWQgY2xvemFwaW5lIChOID0gYHIgbnJvdyh0ZXN0X2RmX2RpbV9zdGRfYylgKSBzZXBhcmF0ZWx5LiBOb3RlIHRoYXQgYW5hbHlzZXMgb2YgdGhlIGVmZmVjdHMgb2YgdGhlIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgYXJlIGFkanVzdGVkIGZvciBkb3NlLCBjbG96YXBpbmUgdXNlLCBhbmQgYW50aWNob2xpbmVyZ2ljIHVzZS4gRmluYWxseSwgd2UgcGVyZm9ybWVkIGEgc2Vuc2l0aXZpdHkgYW5hbHlzaXMgdG8gdGVzdCB3aGV0aGVyIG91ciBwaGFybWFjb2dlbm9taWMgbW9kZWxzIGNoYW5nZWQgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIGNvbmNvbWl0YW50IG1lZGljYXRpb24gb3IgbGlmZXN0eWxlIGZhY3RvcnMgdGhhdCBtYXkgaW5mbHVlbmNlIGVuenltZSBmdW5jdGlvbiAo4oCccGhlbm9jb252ZXJzaW9u4oCdXjQ0XikgYXMgZGVzY3JpYmVkIGluIHRoZSAqKlN1cHBsZW1lbnRhcnkgTWF0ZXJpYWxzKiouIA0KDQpUaGlzIHN0dWR5IGZvbGxvd2VkIHRoZSBTVHJlbmd0aGVuaW5nIHRoZSBSRXBvcnRpbmcgb2YgR2VuZXRpYyBBc3NvY2lhdGlvbiBTdHVkaWVzIHJlcG9ydGluZyByZWNvbW1lbmRhdGlvbnNeNDVeIChTVFJFR0EpLCBhbiBleHRlbnNpb24gb2YgdGhlIFNUUk9CRSBTdGF0ZW1lbnReNDZeLiBUaGUgY2hlY2tsaXN0IGNhbiBiZSBmb3VuZCA8YSBocmVmPVdyaXRpbmcvZmlncy9TVFJFR0EucGRmIHRhcmdldD0iX2JsYW5rIj5oZXJlPC9hPi4gDQoNCjxicj4NCjxicj4NCjxicj4NCjxicj4NCg0KDQojIyA8c3Ryb25nPiBSZXN1bHRzIDwvc3Ryb25nPiANCiMjIyBSZXN1bHRzDQoNCmBgYHtyIGRlc2NyaXB0aXZlc30NCg0KI2dldCBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGZvciBpbi10ZXh0DQpkZl90b3RhbCA8LSB0ZXN0X2RmX2RpbSAlPiUNCiAgIGZpbHRlcihpZl9hbGwoYyhTdHVkeV9JRCwgcG9zaXRpdmUsIGV4cHJlc3MsIG1hbmRwLCBzYWQsIGNvZywgY3B6X2VxLCBBZGhlcmVuY2VfY29kZWQsIGNsb3phcGluZV9jdXJyZW50LCBhbnRpY2hvbF9wcmVzZW50LCBTWl9QUlNjcywgQWdlX2F0X0ludGVydmlldywgU2V4LCBQQzEsIFBDMiwgUEMzLCBQQzQsIFBDNSksIGNvbXBsZXRlLmNhc2VzKSkNCg0KbWVkcyA8LSBkcGx5cjo6c2VsZWN0KHBoZW5vLCBjKCJTdHVkeV9JRCIsICJBbnRpcHN5Y2hvdGljIiwgIkFQX2Rvc2UiLCAiYW50aWRlcHJlc3NhbnQiLCAiQURfZG9zZSIsICJNb29kX1N0YWJpbGlzZXIiLCAiTVNfZG9zZSIsICJCZW56b2RpYXplcGluZSIsICJCZW5fZG9zZSIsICJBbnRpY2hvbGluZXJnaWMiLCAiQW50aWNob2xpbmVyZ2ljX2Rvc2UiICwgIm90aGVyX21lZGljYXRpb24iLCAiT3RoZXJfbWVkaWNhdGlvbl9kb3NlIiwgIkN1cnJlbnRfc21va2luZyIpKQ0KDQptZWRzJEFudGlwc3ljaG90aWNbIShtZWRzJEFudGlwc3ljaG90aWMgJWluJSBBUF9jb2RlcyldIDwtIE5BDQptZWRzJGFudGlkZXByZXNzYW50WyEobWVkcyRhbnRpZGVwcmVzc2FudCAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCm1lZHMkTW9vZF9TdGFiaWxpc2VyWyEobWVkcyRNb29kX1N0YWJpbGlzZXIlaW4lIEFQX2NvZGVzKV0gPC0gTkENCm1lZHMkQmVuem9kaWF6ZXBpbmVbIShtZWRzJEJlbnpvZGlhemVwaW5lICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KbWVkcyRBbnRpY2hvbGluZXJnaWNbIShtZWRzJEFudGljaG9saW5lcmdpYyAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCm1lZHMkb3RoZXJfbWVkaWNhdGlvblshKG1lZHMkb3RoZXJfbWVkaWNhdGlvbiAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCg0KIyByZW1vdmUgZG9zZXMgZm9yIG5vbi11c2VmdWwgZHJ1Z3MNCm1lZHMkQVBfZG9zZVtpcy5uYShtZWRzJEFudGlwc3ljaG90aWMpXSA8LSBOQQ0KbWVkcyRBRF9kb3NlW2lzLm5hKG1lZHMkYW50aWRlcHJlc3NhbnQpXSA8LSBOQQ0KbWVkcyRNU19kb3NlW2lzLm5hKG1lZHMkTW9vZF9TdGFiaWxpc2VyKV0gPC0gTkENCm1lZHMkQmVuX2Rvc2VbaXMubmEobWVkcyRCZW56b2RpYXplcGluZSldIDwtIE5BDQptZWRzJEFudGljaG9saW5lcmdpY19kb3NlW2lzLm5hKG1lZHMkQW50aWNob2xpbmVyZ2ljKV0gPC0gTkENCm1lZHMkT3RoZXJfbWVkaWNhdGlvbl9kb3NlW2lzLm5hKG1lZHMkb3RoZXJfbWVkaWNhdGlvbildIDwtIE5BDQoNCmFwcyA8LSB0YWJsZShtZWRzJEFudGlwc3ljaG90aWMpICU+JSBhcy5kYXRhLmZyYW1lKCkNCmFkcyA8LSB0YWJsZShtZWRzJGFudGlkZXByZXNzYW50KSAlPiUgYXMuZGF0YS5mcmFtZSgpDQptc3MgPC0gdGFibGUobWVkcyRNb29kX1N0YWJpbGlzZXIpICU+JSBhcy5kYXRhLmZyYW1lKCkNCmJ6cyA8LSB0YWJsZShtZWRzJEJlbnpvZGlhemVwaW5lKSAlPiUgYXMuZGF0YS5mcmFtZSgpDQphY3MgPC0gdGFibGUobWVkcyRBbnRpY2hvbGluZXJnaWMpICU+JSBhcy5kYXRhLmZyYW1lKCkNCm90cyA8LSB0YWJsZShtZWRzJG90aGVyX21lZGljYXRpb24pICU+JSBhcy5kYXRhLmZyYW1lKCkNCg0KbWVkX2ZyZXEgPC0gZnVsbF9qb2luKGFwcywgYWRzLCBieSA9ICJWYXIxIikNCm1lZF9mcmVxIDwtIGZ1bGxfam9pbihtZWRfZnJlcSwgbXNzLCBieSA9ICJWYXIxIikNCm1lZF9mcmVxIDwtIGZ1bGxfam9pbihtZWRfZnJlcSwgYnpzLCBieSA9ICJWYXIxIikNCm1lZF9mcmVxIDwtIGZ1bGxfam9pbihtZWRfZnJlcSwgYWNzLCBieSA9ICJWYXIxIikNCm1lZF9mcmVxIDwtIGZ1bGxfam9pbihtZWRfZnJlcSwgb3RzLCBieSA9ICJWYXIxIikNCg0KY29scyA8LSBjb2xuYW1lcyhtZWRfZnJlcSkNCg0KbWVkX2ZyZXEkdG90YWwgPC0gcm93U3VtcyhtZWRfZnJlcVssIGNvbHNbLTFdXSwgbmEucm0gPSBUUlVFKQ0KDQptZWRfZnJlcSA8LSBhcy5kYXRhLmZyYW1lKHJlY29kZV9zZWxlY3RlZF9jb2RlcyhkZiA9IG1lZF9mcmVxLCByZWNvZGVfdmVjdG9yID0gcmVjb2RlX3ZlY3RvciwgY29sdW1uc190b19yZWNvZGUgPSAiVmFyMSIpKQ0KDQptZWRfZGYgPC0gZHBseXI6OnNlbGVjdChtZWRfZnJlcSwgYygiVmFyMSIsICJ0b3RhbCIpKQ0KbWVkX2RmIDwtIG1lZF9kZiAlPiUNCiAgICBtdXRhdGUoVmFyMSA9IHN0cl90b19zZW50ZW5jZShWYXIxKSkNCmNvbG5hbWVzKG1lZF9kZikgPC0gYygiQW50aXBzeWNob3RpYyIsICJOIikNCg0KbWVkX2RmJEFkbWluaXN0cmF0aW9uIDwtIGMoIk9yYWwiLCAiT3JhbCIsICJPcmFsIiwgIk9yYWwiLCAiT3JhbCIsICJEZXBvdCIsICJPcmFsIiwgIkRlcG90IiwgIk9yYWwiLCAiRGVwb3QiLCAiT3JhbCIsICJPcmFsIiwgIkRlcG90IiwgIk9yYWwiLCAiT3JhbCIsICJEZXBvdCIsICJPcmFsIiwgIk9yYWwiLCAiT3JhbCIsIkRlcG90IiwgIkRlcG90IikNCg0KbWVkX2RmIDwtIG1lZF9kZiAlPiUgZHBseXI6OnNlbGVjdChjKCJBbnRpcHN5Y2hvdGljIiwgIkFkbWluaXN0cmF0aW9uIiwgIk4iKSkNCg0KbWVkX2RmJEFudGlwc3ljaG90aWNbNl0gPC0gIkZsdXBlbnRoaXhvbCINCg0Kcm0obWVkcywgYXBzLCBhZHMsIG1zcywgYnpzLCBhY3MsIG90cywgY29scywgIG1lZF9mcmVxKQ0KDQpgYGANCg0KV2UgaW5jbHVkZWQgYHIgbnJvdyhkZl90b3RhbClgIHBhcnRpY2lwYW50cyB3aXRoIHNjaGl6b3BocmVuaWEgb3Igc2NoaXpvYWZmZWN0aXZlIGRpc29yZGVyLCBkZXByZXNzZWQgdHlwZSAoYHIgYXMubnVtZXJpYyh0YWJsZShkZl90b3RhbCRTZXgpWzJdKWAgW2ByIHJvdW5kKChhcy5udW1lcmljKHRhYmxlKGRmX3RvdGFsJFNleClbMl0sIDEpIC8gbnJvdyhkZl90b3RhbCkpICogMTAwLCAxKWAlXSBmZW1hbGU7IG1lYW4gW1NEXSBhZ2Ugb2YgYHIgcm91bmQobWVhbihkZl90b3RhbCRBZ2VfYXRfSW50ZXJ2aWV3KSwgMSlgIFtgciByb3VuZChzZChkZl90b3RhbCRBZ2VfYXRfSW50ZXJ2aWV3KSwxKWBdIHllYXJzKS4gQXQgdGhlIHRpbWUgb2YgdGhlIGludGVydmlldywgcGFydGljaXBhbnRzIHdlcmUgcHJlc2NyaWJlZCBhdCBsZWFzdCBvbmUgb2YgYHIgbGVuZ3RoKHVuaXF1ZShtZWRfZGYkQW50aXBzeWNob3RpYykpYCBkaWZmZXJlbnQgYW50aXBzeWNob3RpY3MsIGFkbWluaXN0ZXJlZCBvcmFsbHkgb3IgYnkgbG9uZy1hY3RpbmcgaW5qZWN0aW9uLiBDbG96YXBpbmUgKGByIHJvdW5kKG1lZF9kZiROW21lZF9kZiRBbnRpcHN5Y2hvdGljID09ICJDbG96YXBpbmUiXS9ucm93KGRmX3RvdGFsKSoxMDAsIDEpYCUpIGFuZCBvbGFuemFwaW5lIChgciByb3VuZChtZWRfZGYkTlttZWRfZGYkQW50aXBzeWNob3RpYyA9PSAiT2xhbnphcGluZSJdL25yb3coZGZfdG90YWwpKjEwMCwgMSlgJSkgd2VyZSB0aGUgbW9zdCBmcmVxdWVudGx5IHByZXNjcmliZWQgYW50aXBzeWNob3RpY3MuIERlc2NyaXB0aXZlIHN0YXRpc3RpY3MgKCoqU3VwcGxlbWVudGFyeSBUYWJsZSAyKiopLCB0aGUgZnJlcXVlbmN5IG9mIGFudGlwc3ljaG90aWNzIHJlcG9ydGVkICgqKlN1cHBsZW1lbnRhcnkgVGFibGUgMyoqKSwgYW5kIHRoZSBhbGxlbGUgZnJlcXVlbmN5IG9mIHBoYXJtYWNvZ2Vub21pYyBzdGFyIGFsbGVsZXMgKCoqU3VwcGxlbWVudGFyeSBUYWJsZSA0KiopIGFyZSBmb3VuZCBpbiB0aGUgKipTdXBwbGVtZW50YXJ5IE1hdGVyaWFscyoqLiAgT25seSBhc3NvY2lhdGlvbnMgdGhhdCBwYXNzIHRoZSA1JSBGYWxzZSBEaXNjb3ZlcnkgUmF0ZSAoRkRSKSB0aHJlc2hvbGQgYXJlIGhpZ2hsaWdodGVkLiBFZmZlY3Qgc2l6ZXMgYXJlIHN0YW5kYXJkaXNlZCBhbmQgcmVwb3J0ZWQgYWxvbmdzaWRlIHVuY29ycmVjdGVkIGFuZCBGRFItY29ycmVjdGVkICpwKiB2YWx1ZXMuIA0KDQo8YnI+DQoNCiMjIyMgQ29uZmlybWF0b3J5IEZhY3RvciBBbmFseXNpcyBvZiBTY2hpem9waHJlbmlhIFBoZW5vdHlwZXMuDQoNCkZvdXIgZmFjdG9yIHN0cnVjdHVyZXMgd2VyZSBmaXQgdG8gZGV0ZXJtaW5lIHdoaWNoIGJlc3QgcmVwcmVzZW50ZWQgdGhlIGRhdGEgYXMgZGVzY3JpYmVkIGluICoqU3VwcGxlbWVudGFyeSBUYWJsZSA1KiouIFRoZSBtb2RlbCB3aXRoIHRoZSBiZXN0IGZpdCAoQ29tcGFyYXRpdmUgRml0IEluZGV4ID0gYHIgYXMuZGF0YS5mcmFtZShjb3JlX2ZpdG1lYXN1cmVzKGZpdHMkZm91cikpWzUsMV1gLCBTcXVhcmUgRXJyb3Igb2YgQXBwcm94aW1hdGlvbiA9IGByIGFzLmRhdGEuZnJhbWUoY29yZV9maXRtZWFzdXJlcyhmaXRzJGZvdXIpKVs2LDFdYCwgU3RhbmRhcmRpc2VkIFJvb3QgTWVhbiBTcXVhcmUgUmVzaWR1YWwgPSBgciBhcy5kYXRhLmZyYW1lKGNvcmVfZml0bWVhc3VyZXMoZml0cyRmb3VyKSlbOSwxXWApIGhhZCBmaXZlIGRpbWVuc2lvbnMgcmVsYXRlZCB0byBwb3NpdGl2ZSBzeW1wdG9tcywgbmVnYXRpdmUgc3ltcHRvbXMgb2YgZGltaW5pc2hlZCBleHByZXNzaXZpdHksIG5lZ2F0aXZlIHN5bXB0b21zIG9mIHJlZHVjZWQgbW90aXZhdGlvbiBhbmQgcGxlYXN1cmUsIGRlcHJlc3Npb24gYW5kIHN1aWNpZGUsIGFuZCBjb2duaXRpdmUgYWJpbGl0eSAoKipGaWd1cmUgMioqKS4gVGhlIGRlcml2ZWQgZmFjdG9ycyB3ZXJlIGFsbCBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCB0aGUgR2xvYmFsIEFzc2Vzc21lbnQgU2NhbGUgaW4gdGhlIGV4cGVjdGVkIGRpcmVjdGlvbiAoKipTdXBwbGVtZW50YXJ5IE1hdGVyaWFscyoqKS4gRnVydGhlciBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcHJlLW1vcmJpZCB2YXJpYWJsZXMgY29uc2lkZXJlZCBhbmQgdGhlaXIgYXNzb2NpYXRpb25zIHdpdGggdGhlIGNvZ25pdGl2ZSBkaW1lbnNpb24gYW5kIGRvc2UgYXJlIHJlcG9ydGVkIGluIHRoZSAqKlN1cHBsZW1lbnRhcnkgTWF0ZXJpYWxzKiouDQoNCmBgYHtyIGNmYSA0IHBsb3QgcGFwZXIsIGZpZy5jYXA9ICJGaWd1cmUgMi4gRmFjdG9yIHN0cnVjdHVyZSBmcm9tIHRoZSBjb25maXJtYXRvcnkgZmFjdG9yIGFuYWx5c2lzIG9mIGN1cnJlbnQgc2NoaXpvcGhyZW5pYSBwaGVub3R5cGVzIHdpdGhpbiB0aGUgQ2FyZGlmZkNPR1Mgc2FtcGxlLiBTdGFuZGFyZGlzZWQgbG9hZGluZ3MgYmV0d2VlbiBsYXRlbnQgZmFjdG9ycyAoY2lyY2xlcykgYW5kIGNvbnRyaWJ1dGluZyBwaGVub3R5cGVzIChyZWN0YW5nbGVzKSBhcmUgcmVwb3J0ZWQgb24gc3RyYWlnaHQgbGluZXMuIEN1cnZlZCBsaW5lcyByZXByZXNlbnQgY29ycmVsYXRpb25zIGJldHdlZW4gbGF0ZW50IGZhY3RvcnMuICBFWFAsIERpbWluaXNoZWQgRXhwcmVzc2l2aXR5OyBNQVAsIFJlZHVjZWQgTW90aXZhdGlvbiBhbmQgUGxlYXN1cmU7IEhWTFQsIEhvcGtpbnMgVmlzdWFsIExlYXJuaW5nIFRlc3Q7IEJWTVQsIEJyaWVmIFZpc3Vvc3BhdGlhbCBNZW1vcnkgVGVzdC1SZXZpc2VkOyBDUFQsIENvbnRpbnVvdXMgUGVyZm9ybWFuY2UgVGVzdC4ifQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiV3JpdGluZy9maWdzL0ZpZ3VyZSAyLnBuZyIpDQoNCg0KYGBgDQoNCg0KPGJyPg0KPGJyPg0KDQojIyMjIEFzc29jaWF0aW9ucyBiZXR3ZWVuIFBoZW5vdHlwZSBEaW1lbnNpb25zIGFuZCBNZWRpY2F0aW9uIFZhcmlhYmxlcy4NCg0KYGBge3IgbWFpbiBtb2RlbCwgaW5jbHVkZSA9IEZBTFNFfQ0KDQojIHRlc3Rpbmcgd2hldGhlciBtZWRpY2F0aW9uIHZhcmlhYmxlcyBhcmUgYXNzb2NpYXRlZCB3aXRoIHBoZW5vdHlwZSBkaW1lbnNpb25zIGluIHRoZSB0b3RhbCBzYW1wbGUuIA0KDQpwb3MgPC0gbG0ocG9zaXRpdmUgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICArICBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArIEFnZV9hdF9JbnRlcnZpZXcgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCmV4cCA8LSBsbShleHByZXNzIH4gIGNwel9lcSArIGNsb3phcGluZV9jdXJyZW50ICsgYW50aWNob2xfcHJlc2VudCAgKyAgQWRoZXJlbmNlX2NvZGVkICsgU1pfUFJTY3MgKyAgQWdlX2F0X0ludGVydmlldyAgKyBTZXggICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQptYXAgPC0gbG0obWFuZHAgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICArICBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArICBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCAgKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUgLCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpjb2cgPC0gbG0oY29nIH4gIGNwel9lcSArIGNsb3phcGluZV9jdXJyZW50ICsgYW50aWNob2xfcHJlc2VudCArICBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArIEludF9QUlNjcyArIEVBX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpzYWQgPC0gbG0oc2FkIH4gIGNwel9lcSArIGNsb3phcGluZV9jdXJyZW50ICsgYW50aWNob2xfcHJlc2VudCAgICsgIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4ICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpjb2VmczFhIDwtIGRhdGEuZnJhbWUoY29lZihzdW1tYXJ5KHBvcykpKSANCmNvZWZzMWIgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZXhwKSkpIA0KY29lZnMxYyA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShtYXApKSkgDQpjb2VmczFkIDwtIGRhdGEuZnJhbWUoY29lZihzdW1tYXJ5KHNhZCkpKSANCmNvZWZzMWUgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoY29nKSkpIA0KDQpgYGANCg0KT25seSBhc3NvY2lhdGlvbnMgdGhhdCBwYXNzZWQgdGhlIDUlIEZhbHNlIERpc2NvdmVyeSBSYXRlIChGRFIpIHRocmVzaG9sZCB3ZXJlIGNvbnNpZGVyZWQgc2lnbmlmaWNhbnQuIEVmZmVjdCBzaXplcyB3ZXJlIHN0YW5kYXJkaXNlZCBhbmQgc2hvd24gYWxvbmdzaWRlIHVuY29ycmVjdGVkIHAgdmFsdWVzLiBUaGUgcmVzdWx0cyBvZiBhc3NvY2lhdGlvbiB0ZXN0cyBiZXR3ZWVuIHBoZW5vdHlwZSBkaW1lbnNpb25zIGFuZCBtZWRpY2F0aW9uIHZhcmlhYmxlcyBhcmUgc2hvd24gaW4gKipUYWJsZSAxKiouIEV4dGVuZGVkIHZlcnNpb25zIG9mIHRoaXMgKGFuZCBvdGhlciB0YWJsZXMpIHRoYXQgaW5jbHVkZSBhc3NvY2lhdGlvbnMgYmV0d2VlbiBmdXJ0aGVyIGNvdmFyaWF0ZXMgYW5kIHBoZW5vdHlwZSBkaW1lbnNpb25zIGFyZSBnaXZlbiBpbiAqKlN1cHBsZW1lbnRhcnkgVGFibGVzIDYg4oCTIDgqKi4NCg0KSGlnaGVyIHNjb3JlcyBvbiB0aGUgcG9zaXRpdmUgZGltZW5zaW9uIHdlcmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBjaGxvcnByb21hemluZS1lcXVpdmFsZW50IGFudGlwc3ljaG90aWMgZG9zZSAozrIgPSBgciBjb2VmczFhJEVzdGltYXRlWzJdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQocG9zKVsyLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChwb3MpWzIsMl0sIDIpYDsgKnAqID0gYHIgZm9ybWF0X3AoY29lZnMxYSRQci4uLnQuLlsyXSlgKS4gSGlnaGVyIHNjb3JlcyBvbiB0aGUgZGltaW5pc2hlZCBleHByZXNzaXZpdHkgZGltZW5zaW9uIHdlcmUgYXNzb2NpYXRlZCB3aXRoIGNsb3phcGluZSB1c2UgKM6yID0gYHIgY29lZnMxYiRFc3RpbWF0ZVszXWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KGV4cClbMywxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoZXhwKVszLDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdF9wKGNvZWZzMWIkUHIuLi50Li5bM10pYCkuIEhpZ2hlciBzY29yZXMgb24gdGhlIHJlZHVjZWQgbW90aXZhdGlvbiBhbmQgcGxlYXN1cmUgZGltZW5zaW9uIHdlcmUgYWxzbyBhc3NvY2lhdGVkIHdpdGggY2xvemFwaW5lIHVzZSAozrIgPSBgciBjb2VmczFjJEVzdGltYXRlWzNdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQobWFwKVszLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChtYXApWzMsMl0sIDIpYDsgKnAqID0gYHIgZm9ybWF0X3AoY29lZnMxYyRQci4uLnQuLlszXSlgKS4gSGlnaGVyIHNjb3JlcyBvbiB0aGUgc3VpY2lkZSBhbmQgZGVwcmVzc2lvbiBkaW1lbnNpb24gd2VyZSBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQgYW50aXBzeWNob3RpYyBkb3NlICjOsiA9IGByIGNvZWZzMWQkRXN0aW1hdGVbMl1gOyA5NSVDSSwgYHIgcm91bmQoY29uZmludChzYWQpWzIsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KHNhZClbMiwyXSwgMilgOyAqcCogPSBgciBmb3JtYXRfcChjb2VmczFkJFByLi4udC4uWzJdKWApLg0KDQpMb3dlciBzY29yZXMgb24gdGhlIGNvZ25pdGlvbiBkaW1lbnNpb24sIGluZGljYXRpbmcgcG9vcmVyIGNvZ25pdGl2ZSBhYmlsaXR5LCB3ZXJlIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudCBkYWlseSBhbnRpcHN5Y2hvdGljIGRvc2UgKM6yID0gYHIgY29lZnMxZSRFc3RpbWF0ZVsyXWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KGNvZylbMiwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoY29nKVsyLDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdF9wKGNvZWZzMWUkUHIuLi50Li5bMl0pYCksIGNsb3phcGluZSB1c2UgKM6yID0gYHIgY29lZnMxZSRFc3RpbWF0ZVszXWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KGNvZylbMywxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoY29nKVszLDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdF9wKGNvZWZzMWUkUHIuLi50Li5bM10pYCksIGFuZCBhbnRpY2hvbGluZXJnaWMgdXNlICjOsiA9IGByIGNvZWZzMWUkRXN0aW1hdGVbNF1gOyA5NSVDSSwgYHIgcm91bmQoY29uZmludChjb2cpWzQsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KGNvZylbNCwyXSwgMilgOyAqcCogPSBgciBmb3JtYXRfcChjb2VmczFlJFByLi4udC4uWzRdKWApLiANCg0KYGBge3IgVGFibGUgMX0NCiMjIyMgY3JlYXRlIHRhYmxlICMjIyMNCnQxIDwtIG1ha2VfdGFiKHBvcykNCnQyIDwtIG1ha2VfdGFiKGV4cCkNCnQzIDwtIG1ha2VfdGFiKG1hcCkNCnQ0IDwtIG1ha2VfdGFiKHNhZCkNCnQ1IDwtIG1ha2VfdGFiKGNvZykNCg0KZjEgPC0gZ2V0X2ZpdChwb3MpDQpmMiA8LSBnZXRfZml0KGV4cCkNCmYzIDwtIGdldF9maXQobWFwKQ0KZjQgPC0gZ2V0X2ZpdChzYWQpDQpmNSA8LSBnZXRfZml0KGNvZykNCg0KbWFpbl9yZXMgPC0gcmJpbmQodDEsIHQyLCB0MywgdDQsIHQ1KQ0KZXh0cmEgPC0gY2JpbmQoZjEsIGYyWzJdLCBmM1syXSwgZjRbMl0sIGY1WzJdKQ0KDQptYWluX3Jlc19mZHIgPC0gbXV0YXRlKGdyb3VwX2J5KG1haW5fcmVzLCBQcmVkaWN0b3IpLCBGRFI9cC5hZGp1c3QocCwiZmRyIikpDQoNCm1haW5fcmVzX2ZkciRwIDwtIGZvcm1hdF9wKG1haW5fcmVzX2ZkciRwKQ0KbWFpbl9yZXNfZmRyJEZEUiA8LSBmb3JtYXRfcChtYWluX3Jlc19mZHIkRkRSKQ0KDQptYWluX3Jlc19mZHIkYHAgKEZEUilgIDwtIHBhc3RlMChtYWluX3Jlc19mZHIkcCwgIiAoIiwgbWFpbl9yZXNfZmRyJEZEUiwgIikiKQ0KbWFpbl9yZXNfZmRyIDwtIGRwbHlyOjpzZWxlY3QobWFpbl9yZXNfZmRyLCAtYygicCIsICJGRFIiKSkNCg0KdG1wIDwtIHNwbGl0KG1haW5fcmVzX2ZkciwgZiA9IG1haW5fcmVzX2ZkciRPdXRjb21lKSAgDQoNCnQxIDwtIGFzLmRhdGEuZnJhbWUodG1wJHBvc2l0aXZlWy0xXSkgDQp0MSA8LSB0MVstYyg0OjEyKSwgXQ0KdDIgPC0gYXMuZGF0YS5mcmFtZSh0bXAkZXhwcmVzc1stMV0pDQp0MiA8LSB0MlstYyg0OjEyKSwgXQ0KdDMgPC0gYXMuZGF0YS5mcmFtZSh0bXAkbWFuZHBbLTFdKQ0KdDMgPC0gdDNbLWMoNDoxMiksIF0NCnQ0IDwtIGFzLmRhdGEuZnJhbWUodG1wJHNhZFstMV0pDQp0NCA8LSB0NFstYyg0OjEyKSwgXQ0KdDUgPC0gYXMuZGF0YS5mcmFtZSh0bXAkY29nWy0xXSkNCnQ1IDwtIHQ1Wy1jKDQ6MTQpLCBdDQoNCm1haW4gPC0gbGVmdF9qb2luKHQxLCB0MiwgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gbGVmdF9qb2luKG1haW4sIHQzLCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBsZWZ0X2pvaW4obWFpbiwgdDQsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGZ1bGxfam9pbihtYWluLCB0NSwgYnkgPSAiUHJlZGljdG9yIikNCg0KbWFpbiA8LSBjb2x1bW5fYXNfcm93bmFtZXMobWFpbiwgdmFyID0gIlByZWRpY3RvciIpDQpyb3duYW1lcyhtYWluKSA8LSBjKCJDUFotZXEgQW50aXBzeWNob3RpYyBEb3NlIChtZy9kYXkpIiwgIkNsb3phcGluZSAoWWVzKSIsICJBbnRpY2hvbGluZXJnaWMgKFllcykiKQ0KDQptYWluICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjb2wubmFtZXMgPSBjKCJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiApLCBjYXB0aW9uID0gIlRhYmxlIDEuIEFzc29jaWF0aW9ucyBiZXR3ZWVuIG1lZGljYXRpb24gdmFyaWFibGVzIHdpdGggc2NoaXpvcGhyZW5pYSBzeW1wdG9tIGFuZCBjb2duaXRpdmUgYWJpbGl0eSBkaW1lbnNpb25zIGluIENhcmRpZmZDT0dTLiBGaXZlIHNlcGFyYXRlIG1vZGVscyB3ZXJlIGZpdCwgZWFjaCB3aXRoIHNldmVyaXR5IHNjb3JlcyBmb3IgYSBzY2hpem9waHJlbmlhIHBoZW5vdHlwZSBhcyB0aGUgb3V0Y29tZSB2YXJpYWJsZS4gVmFyaWFibGVzIG9mIGludGVyZXN0IGluY2x1ZGVkIHRoZSBtZWRpY2F0aW9uIHZhcmlhYmxlcywgY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudCBkYWlseSBhbnRpcHN5Y2hvdGljIGRvc2UsIGNsb3phcGluZSB1c2UsIGFuZCBhbnRpY2hvbGluZXJnaWMgdXNlLiBBbGwgbW9kZWxzIGNvbnRyb2xsZWQgZm9yIG1lZGljYXRpb24gYWRoZXJlbmNlLCBzY2hpem9waHJlbmlhIFBHUywgYWdlLCBzZXgsIGFuZCB0aGUgZmlyc3QgZml2ZSBnZW5ldGljIHByaW5jaXBhbCBjb21wb25lbnRzLiBJbnRlbGxpZ2VuY2UgUEdTIGFuZCBFZHVjYXRpb25hbCBBdHRhaW5tZW50IFBHUyB3ZXJlIGluY2x1ZGVkIGFzIGFkZGl0aW9uYWwgY292YXJpYXRlcyBpbiB0aGUgbW9kZWwgd2hlcmUgdGhlIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbiBpcyB0aGUgb3V0Y29tZS4gU3RhbmRhcmRpc2VkIHJlZ3Jlc3Npb24gZXN0aW1hdGVzIGFyZSByZXBvcnRlZC4gQ1BaLWVxID0gY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudDsgU0UgPSBTdGFuZGFyZCBFcnJvcjsgUEdTID0gUG9seWdlbmljIFNjb3JlLiIpICU+JSANCiAgIGFkZF9oZWFkZXJfYWJvdmUoaGVhZGVyID0gYyggIiAiID0gMSwgIlBvc2l0aXZlIiA9IDIsICJEaW1pbmlzaGVkIEV4cHJlc3Npdml0eSIgPSAyLCAiUmVkdWNlZCBNb3RpdmF0aW9uIGFuZCBQbGVhc3VyZSIgPSAyLCAiU3VpY2lkZSBhbmQgRGVwcmVzc2lvbiIgPSAyLCAiQ29nbml0aW9uIiA9IDIpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQpgYGANCg0KPGJyPg0KDQojIyMjIFBoYXJtYWNvZ2Vub21pYyBBc3NvY2lhdGlvbnMgd2l0aCB0aGUgUGhlbm90eXBlIERpbWVuc2lvbnMuDQoNCmBgYHtyIHBneCBtb2RlbCwgaW5jbHVkZSA9IEZBTFNFfQ0KIyB0ZXN0aW5nIHdoZXRoZXIgbWVkaWNhdGlvbiBvciBwaGFybWFjb2dlbm9taWMgdmFyaWFibGVzIGFyZSBhc3NvY2lhdGVkIHdpdGggcGhlbm90eXBlIGRpbWVuc2lvbnMgaW4gdGhlIHRvdGFsIHNhbXBsZS4gDQoNCnBvc19wZ3ggPC0gbG0ocG9zaXRpdmUgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQMUEyX0FTICsgQ1lQMkQ2X0FTICsgQ1lQM0E1X0FTICsgQ1lQMkMxOV9BUyArIENZUDJDOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICArIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4ICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpleHBfcGd4IDwtIGxtKGV4cHJlc3MgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQMUEyX0FTICsgQ1lQMkQ2X0FTICsgQ1lQM0E1X0FTICsgQ1lQMkMxOV9BUyArIENZUDJDOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICArIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4ICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQptYXBfcGd4IDwtIGxtKG1hbmRwIH4gIGNwel9lcSArIGNsb3phcGluZV9jdXJyZW50ICsgYW50aWNob2xfcHJlc2VudCArIENZUDFBMl9BUyArIENZUDJENl9BUyArIENZUDNBNV9BUyArIENZUDJDMTlfQVMgKyBDWVAyQzlfQVMgKyBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4ICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpzYWRfcGd4IDwtIGxtKHNhZCB+ICBjcHpfZXEgICsgY2xvemFwaW5lX2N1cnJlbnQrIGFudGljaG9sX3ByZXNlbnQgKyBDWVAxQTJfQVMgKyBDWVAyRDZfQVMgKyBDWVAzQTVfQVMgKyBDWVAyQzE5X0FTICsgQ1lQMkM5X0FTICsgQWRoZXJlbmNlX2NvZGVkICsgU1pfUFJTY3MgICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCmNvZ19wZ3ggPC0gbG0oY29nIH4gIGNwel9lcSArIGNsb3phcGluZV9jdXJyZW50ICsgYW50aWNob2xfcHJlc2VudCArIENZUDFBMl9BUyArIENZUDJENl9BUyArIENZUDNBNV9BUyArIENZUDJDMTlfQVMgKyBDWVAyQzlfQVMgKyBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArIEludF9QUlNjcyArIEVBX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCmNvZWZzMmEgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkocG9zX3BneCkpKSANCmNvZWZzMmIgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZXhwX3BneCkpKSANCmNvZWZzMmMgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkobWFwX3BneCkpKSANCmNvZWZzMmUgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoY29nX3BneCkpKSANCg0KYGBgDQoNCkFsbCBwaGFybWFjb2dlbm9taWMgYXNzb2NpYXRpb25zIHdlcmUgYWRqdXN0ZWQgZm9yIG1lZGljYXRpb24gdmFyaWFibGVzLiBUaGUgYWRkaXRpb24gb2YgcGhhcm1hY29nZW5vbWljIHZhcmlhYmxlcyBpbnRvIHRoZSBtb2RlbHMgZGlkIG5vdCBzdWJzdGFudGlhbGx5IGluZmx1ZW5jZSB0aGUgYXNzb2NpYXRpb25zIGJldHdlZW4gdGhlIG1lZGljYXRpb24gdmFyaWFibGVzIGFuZCBzY2hpem9waHJlbmlhIHBoZW5vdHlwZSBkaW1lbnNpb25zIGRlc2NyaWJlZCBhYm92ZS4gV2hpbGUgc29tZSBhdHRlbnVhdGlvbiBvZiBwIHZhbHVlcyB3YXMgb2JzZXJ2ZWQsIHRoZXJlIHdhcyBubyBjaGFuZ2UgdG8gdGhlIG92ZXJhbGwgcGF0dGVybiBvZiByZXN1bHRzLCB3aXRoIHByZXZpb3VzbHkgc2lnbmlmaWNhbnQgYXNzb2NpYXRpb25zIHJlbWFpbmluZyBzby4gDQoNCkluIHRoZSBmdWxsIHNhbXBsZSwgd2UgZm91bmQgc2V2ZXJhbCBhc3NvY2lhdGlvbnMgaW4gd2hpY2ggbG93ZXIgc3ltcHRvbSBkaW1lbnNpb24gc2NvcmVzLCBhbmQgc28gbGVzcyBzZXZlcmUgc3ltcHRvbXMsIHdlcmUgYXNzb2NpYXRlZCB3aXRoIGZhc3RlciBnZW5vdHlwZS1pbmZlcnJlZCBlbnp5bWUgYWN0aXZpdHkuIExvd2VyIHNjb3JlcyBvbiB0aGUgcG9zaXRpdmUgc3ltcHRvbSBkaW1lbnNpb24gd2VyZSBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIENZUDJDMTkgYWN0aXZpdHkgc2NvcmVzICjOsiA9IGByIGNvZWZzMmEkRXN0aW1hdGVbOF1gOyA5NSVDSSwgYHIgcm91bmQoY29uZmludChwb3NfcGd4KVs4LDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChwb3NfcGd4KVs4LDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdF9wKGNvZWZzMmEkUHIuLi50Li5bOF0pYCkuIExvd2VyIHNjb3JlcyBvbiB0aGUgZGltaW5pc2hlZCBleHByZXNzaXZpdHkgZGltZW5zaW9uIHdlcmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBDWVAzQTUgYWN0aXZpdHkgc2NvcmUgKM6yID0gYHIgY29lZnMyYiRFc3RpbWF0ZVs3XWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KGV4cF9wZ3gpWzcsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KGV4cF9wZ3gpWzcsMl0sIDIpYDsgKnAqID0gYHIgZm9ybWF0X3AoY29lZnMyYiRQci4uLnQuLls3XSlgKS4gU2ltaWxhcmx5LCB3ZSBhbHNvIGZvdW5kIGFuIGFzc29jaWF0aW9uIGJldHdlZW4gbG93ZXIgc2NvcmVzIG9uIHRoZSByZWR1Y2VkIG1vdGl2YXRpb24gYW5kIHBsZWFzdXJlIGRpbWVuc2lvbiBhbmQgaGlnaGVyIENZUDNBNSBhY3Rpdml0eSBzY29yZSAozrIgPSBgciBjb2VmczJjJEVzdGltYXRlWzddYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQobWFwX3BneClbNywxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQobWFwX3BneClbNywyXSwgMilgOyAqcCogPSBgciBmb3JtYXRfcChjb2VmczJjJFByLi4udC4uWzddKWApLiBUaGVyZSB3ZXJlIG5vIHBoYXJtYWNvZ2Vub21pYyBhc3NvY2lhdGlvbnMgd2l0aCBlaXRoZXIgdGhlIHN1aWNpZGUgYW5kIGRlcHJlc3Npb24gb3IgdGhlIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbiAoKipUYWJsZSAyKiopLg0KDQpgYGB7ciBUYWJsZSAyfQ0KIyMjIyBjcmVhdGUgdGFibGUgIyMjIw0KdDEgPC0gbWFrZV90YWIocG9zX3BneCkNCnQyIDwtIG1ha2VfdGFiKGV4cF9wZ3gpDQp0MyA8LSBtYWtlX3RhYihtYXBfcGd4KQ0KdDQgPC0gbWFrZV90YWIoc2FkX3BneCkNCnQ1IDwtIG1ha2VfdGFiKGNvZ19wZ3gpDQoNCmYxIDwtIGdldF9maXQocG9zX3BneCkNCmYyIDwtIGdldF9maXQoZXhwX3BneCkNCmYzIDwtIGdldF9maXQobWFwX3BneCkNCmY0IDwtIGdldF9maXQoc2FkX3BneCkNCmY1IDwtIGdldF9maXQoY29nX3BneCkNCg0KbWFpbl9yZXMgPC0gcmJpbmQodDEsIHQyLCB0MywgdDQsIHQ1KQ0KZXh0cmEgPC0gY2JpbmQoZjEsIGYyWzJdLCBmM1syXSwgZjRbMl0sIGY1WzJdKQ0KDQptYWluX3Jlc19mZHIgPC0gbXV0YXRlKGdyb3VwX2J5KG1haW5fcmVzLCBQcmVkaWN0b3IpLCBGRFI9cC5hZGp1c3QocCwiZmRyIikpDQoNCm1haW5fcmVzX2ZkciRwIDwtIGZvcm1hdF9wKG1haW5fcmVzX2ZkciRwKQ0KbWFpbl9yZXNfZmRyJEZEUiA8LSBmb3JtYXRfcChtYWluX3Jlc19mZHIkRkRSKQ0KDQptYWluX3Jlc19mZHIkYHAgKEZEUilgIDwtIHBhc3RlMChtYWluX3Jlc19mZHIkcCwgIiAoIiwgbWFpbl9yZXNfZmRyJEZEUiwgIikiKQ0KbWFpbl9yZXNfZmRyIDwtIGRwbHlyOjpzZWxlY3QobWFpbl9yZXNfZmRyLCAtYygicCIsICJGRFIiKSkNCg0KdG1wIDwtIHNwbGl0KG1haW5fcmVzX2ZkciwgZiA9IG1haW5fcmVzX2ZkciRPdXRjb21lKSAgDQoNCnQxIDwtIGFzLmRhdGEuZnJhbWUodG1wJHBvc2l0aXZlWy0xXSkgDQp0MSA8LSB0MVstYyg5OjE3KSwgXQ0KdDIgPC0gYXMuZGF0YS5mcmFtZSh0bXAkZXhwcmVzc1stMV0pDQp0MiA8LSB0MlstYyg5OjE3KSwgXQ0KdDMgPC0gYXMuZGF0YS5mcmFtZSh0bXAkbWFuZHBbLTFdKQ0KdDMgPC0gdDNbLWMoOToxNyksIF0NCnQ0IDwtIGFzLmRhdGEuZnJhbWUodG1wJHNhZFstMV0pDQp0NCA8LSB0NFstYyg5OjE3KSwgXQ0KdDUgPC0gYXMuZGF0YS5mcmFtZSh0bXAkY29nWy0xXSkNCnQ1IDwtIHQ1Wy1jKDk6MTkpLCBdDQoNCm1haW4gPC0gbGVmdF9qb2luKHQxLCB0MiwgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gbGVmdF9qb2luKG1haW4sIHQzLCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBsZWZ0X2pvaW4obWFpbiwgdDQsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGZ1bGxfam9pbihtYWluLCB0NSwgYnkgPSAiUHJlZGljdG9yIikNCg0KbWFpbiA8LSBjb2x1bW5fYXNfcm93bmFtZXMobWFpbiwgdmFyID0gIlByZWRpY3RvciIpDQpyb3duYW1lcyhtYWluKSA8LSBjKCJDUFotZXEgQW50aXBzeWNob3RpYyBEb3NlIChtZy9kYXkpIiwgIkNsb3phcGluZSAoWWVzKSIsICJBbnRpY2hvbGluZXJnaWMgKFllcykiLCJDWVAxQTIgQWN0aXZpdHkgU2NvcmUiLCAiQ1lQMkQ2IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDNBNSBBY3Rpdml0eSBTY29yZSIsICJDWVAyQzE5IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDJDOSBBY3Rpdml0eSBTY29yZSIpDQoNCm1haW4gJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiICksIGNhcHRpb24gPSAiVGFibGUgMi4gQXNzb2NpYXRpb25zIGJldHdlZW4gbWVkaWNhdGlvbiBhbmQgcGhhcm1hY29nZW5vbWljIHZhcmlhYmxlcyB3aXRoIHNjaGl6b3BocmVuaWEgc3ltcHRvbSBhbmQgY29nbml0aXZlIGFiaWxpdHkgZGltZW5zaW9ucyBpbiBDYXJkaWZmQ09HUy4gRml2ZSBzZXBhcmF0ZSBtb2RlbHMgd2VyZSBmaXQsIGVhY2ggd2l0aCBzZXZlcml0eSBzY29yZXMgZm9yIGEgc2NoaXpvcGhyZW5pYSBwaGVub3R5cGUgYXMgdGhlIG91dGNvbWUgdmFyaWFibGUuIFZhcmlhYmxlcyBvZiBpbnRlcmVzdCBpbmNsdWRlZCB0aGUgbWVkaWNhdGlvbiB2YXJpYWJsZXMgKGkuZS4sIGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQgZGFpbHkgYW50aXBzeWNob3RpYyBkb3NlLCBjbG96YXBpbmUgdXNlLCBhbmQgYW50aWNob2xpbmVyZ2ljIHVzZSkgYW5kIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgKGkuZS4sIHRoZSBnZW5ldGljcy1pbmZlcnJlZCBlbnp5bWUgYWN0aXZpdHkgc2NvcmVzKS4gQWxsIG1vZGVscyBjb250cm9sbGVkIGZvciBtZWRpY2F0aW9uIGFkaGVyZW5jZSwgc2NoaXpvcGhyZW5pYSBQR1MsIGFnZSwgc2V4LCBhbmQgdGhlIGZpcnN0IGZpdmUgZ2VuZXRpYyBwcmluY2lwYWwgY29tcG9uZW50cy4gSW50ZWxsaWdlbmNlIFBHUyBhbmQgRWR1Y2F0aW9uYWwgQXR0YWlubWVudCBQR1Mgd2VyZSBpbmNsdWRlZCBhcyBhZGRpdGlvbmFsIGNvdmFyaWF0ZXMgaW4gdGhlIG1vZGVsIHdoZXJlIHRoZSBjb2duaXRpdmUgYWJpbGl0eSBkaW1lbnNpb24gaXMgdGhlIG91dGNvbWUuIFN0YW5kYXJkaXNlZCByZWdyZXNzaW9uIGVzdGltYXRlcyBhcmUgcmVwb3J0ZWQuIENQWi1lcSA9IGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQ7IFNFID0gU3RhbmRhcmQgRXJyb3I7IFBHUyA9IFBvbHlnZW5pYyBTY29yZS4iKSAlPiUgDQogICBhZGRfaGVhZGVyX2Fib3ZlKGhlYWRlciA9IGMoICIgIiA9IDEsICJQb3NpdGl2ZSIgPSAyLCAiRGltaW5pc2hlZCBFeHByZXNzaXZpdHkiID0gMiwgIlJlZHVjZWQgTW90aXZhdGlvbiBhbmQgUGxlYXN1cmUiID0gMiwgIlN1aWNpZGUgYW5kIERlcHJlc3Npb24iID0gMiwgIkNvZ25pdGlvbiIgPSAyKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQpgYGANCg0KPGJyPg0KPGJyPg0KDQoNCmBgYHtyIHBneCBtb2RlbCBpbiBjbG96YXBpbmUgc3ViZ3JvdXAsIGluY2x1ZGUgPSBGQUxTRX0NCmNwb3NfcGd4IDwtIGxtKHBvc2l0aXZlIH4gIGNwel9lcSArIGFudGljaG9sX3ByZXNlbnQgKyBDWVAxQTJfQVMgKyBDWVAyRDZfQVMgKyBDWVAzQTVfQVMgKyBDWVAyQzE5X0FTICsgQ1lQMkM5X0FTICsgQWRoZXJlbmNlX2NvZGVkICsgU1pfUFJTY3MgKyAgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGRfYykNCg0KY2V4cF9wZ3ggPC0gbG0oZXhwcmVzcyB+ICBjcHpfZXEgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQMUEyX0FTICsgQ1lQMkQ2X0FTICsgQ1lQM0E1X0FTICsgQ1lQMkMxOV9BUyArIENZUDJDOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4ICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkX2MpDQoNCmNtYXBfcGd4IDwtIGxtKG1hbmRwIH4gIGNwel9lcSArIGFudGljaG9sX3ByZXNlbnQgKyBDWVAxQTJfQVMgKyBDWVAyRDZfQVMgKyBDWVAzQTVfQVMgKyBDWVAyQzE5X0FTICsgQ1lQMkM5X0FTICsgQWRoZXJlbmNlX2NvZGVkICsgU1pfUFJTY3MgKyAgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGRfYykNCg0KY3NhZF9wZ3ggPC0gbG0oc2FkIH4gIGNwel9lcSAgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQMUEyX0FTICsgQ1lQMkQ2X0FTICsgQ1lQM0E1X0FTICsgQ1lQMkMxOV9BUyArIENZUDJDOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4ICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkX2MpDQoNCmNjb2dfcGd4IDwtIGxtKGNvZyB+ICBjcHpfZXEgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQMUEyX0FTICsgQ1lQMkQ2X0FTICsgQ1lQM0E1X0FTICsgQ1lQMkMxOV9BUyArIENZUDJDOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgIEludF9QUlNjcyArIEVBX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGRfYykNCg0KDQpjb2VmczNiIDwtIGRhdGEuZnJhbWUoY29lZihzdW1tYXJ5KGNleHBfcGd4KSkpIA0KY29lZnMzZSA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShjY29nX3BneCkpKSANCg0KYGBgDQoNCldpdGhpbiB0aGUgc3ViZ3JvdXAgb2YgcGFydGljaXBhbnRzIHRha2luZyBjbG96YXBpbmUsIGhpZ2hlciBDWVAxQTIgYWN0aXZpdHkgc2NvcmUgd2FzIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgY29nbml0aXZlIGFiaWxpdHkgKM6yID0gYHIgY29lZnMzZSRFc3RpbWF0ZVs0XWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KGNjb2dfcGd4KVs0LDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChjY29nX3BneClbNCwyXSwgMilgOyAqcCogPSBgciBmb3JtYXRfcChjb2VmczNlJFByLi4udC4uWzRdKWApLiBObyBvdGhlciBwaGFybWFjb2dlbm9taWMgdmFyaWFibGVzIHdlcmUgc2lnbmlmaWNhbnRseSBhc3NvY2lhdGVkIHdpdGggc2NoaXpvcGhyZW5pYSBwaGVub3R5cGUgc2V2ZXJpdHkgYWZ0ZXIgY29ycmVjdGluZyBmb3IgbXVsdGlwbGUgY29tcGFyaXNvbnMgaW4gdGhpcyBjbG96YXBpbmUgdGFraW5nIGdyb3VwIChUYWJsZSAzKSwgYWx0aG91Z2ggaGlnaGVyIGRvc2Ugb2YgYW50aXBzeWNob3RpYyB3YXMgbm9taW5hbGx5IGFzc29jaWF0ZWQgd2l0aCBsb3dlciBjb2duaXRpdmUgYWJpbGl0eSAozrIgPSBgciBjb2VmczNlJEVzdGltYXRlWzJdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoY2NvZ19wZ3gpWzIsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KGNjb2dfcGd4KVsyLDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdF9wKGNvZWZzM2UkUHIuLi50Li5bMl0pYCkuDQoNCg0KYGBge3IgVGFibGUgM30NCiMjIyMgY3JlYXRlIHRhYmxlICMjIyMNCnQxIDwtIG1ha2VfdGFiKGNwb3NfcGd4KQ0KdDIgPC0gbWFrZV90YWIoY2V4cF9wZ3gpDQp0MyA8LSBtYWtlX3RhYihjbWFwX3BneCkNCnQ0IDwtIG1ha2VfdGFiKGNzYWRfcGd4KQ0KdDUgPC0gbWFrZV90YWIoY2NvZ19wZ3gpDQoNCmYxIDwtIGdldF9maXQoY3Bvc19wZ3gpDQpmMiA8LSBnZXRfZml0KGNleHBfcGd4KQ0KZjMgPC0gZ2V0X2ZpdChjbWFwX3BneCkNCmY0IDwtIGdldF9maXQoY3NhZF9wZ3gpDQpmNSA8LSBnZXRfZml0KGNjb2dfcGd4KQ0KDQptYWluX3JlcyA8LSByYmluZCh0MSwgdDIsIHQzLCB0NCwgdDUpDQpleHRyYSA8LSBjYmluZChmMSwgZjJbMl0sIGYzWzJdLCBmNFsyXSwgZjVbMl0pDQoNCm1haW5fcmVzX2ZkciA8LSBtdXRhdGUoZ3JvdXBfYnkobWFpbl9yZXMsIFByZWRpY3RvciksIEZEUj1wLmFkanVzdChwLCJmZHIiKSkNCg0KbWFpbl9yZXNfZmRyJHAgPC0gZm9ybWF0X3AobWFpbl9yZXNfZmRyJHApDQptYWluX3Jlc19mZHIkRkRSIDwtIGZvcm1hdF9wKG1haW5fcmVzX2ZkciRGRFIpDQoNCm1haW5fcmVzX2ZkciRgcCAoRkRSKWAgPC0gcGFzdGUwKG1haW5fcmVzX2ZkciRwLCAiICgiLCBtYWluX3Jlc19mZHIkRkRSLCAiKSIpDQptYWluX3Jlc19mZHIgPC0gZHBseXI6OnNlbGVjdChtYWluX3Jlc19mZHIsIC1jKCJwIiwgIkZEUiIpKQ0KDQp0bXAgPC0gc3BsaXQobWFpbl9yZXNfZmRyLCBmID0gbWFpbl9yZXNfZmRyJE91dGNvbWUpICANCg0KdDEgPC0gYXMuZGF0YS5mcmFtZSh0bXAkcG9zaXRpdmVbLTFdKSANCnQxIDwtIHQxWy1jKDg6MTYpLCBdDQp0MiA8LSBhcy5kYXRhLmZyYW1lKHRtcCRleHByZXNzWy0xXSkNCnQyIDwtIHQyWy1jKDg6MTYpLCBdDQp0MyA8LSBhcy5kYXRhLmZyYW1lKHRtcCRtYW5kcFstMV0pDQp0MyA8LSB0M1stYyg4OjE2KSwgXQ0KdDQgPC0gYXMuZGF0YS5mcmFtZSh0bXAkc2FkWy0xXSkNCnQ0IDwtIHQ0Wy1jKDg6MTYpLCBdDQp0NSA8LSBhcy5kYXRhLmZyYW1lKHRtcCRjb2dbLTFdKQ0KdDUgPC0gdDVbLWMoODoxOCksIF0NCg0KbWFpbiA8LSBsZWZ0X2pvaW4odDEsIHQyLCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBsZWZ0X2pvaW4obWFpbiwgdDMsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGxlZnRfam9pbihtYWluLCB0NCwgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gZnVsbF9qb2luKG1haW4sIHQ1LCBieSA9ICJQcmVkaWN0b3IiKQ0KDQptYWluIDwtIGNvbHVtbl9hc19yb3duYW1lcyhtYWluLCB2YXIgPSAiUHJlZGljdG9yIikNCnJvd25hbWVzKG1haW4pIDwtIGMoIkNQWi1lcSBBbnRpcHN5Y2hvdGljIERvc2UgKG1nL2RheSkiLCAiQW50aWNob2xpbmVyZ2ljIChZZXMpIiwiQ1lQMUEyIEFjdGl2aXR5IFNjb3JlIiwgIkNZUDJENiBBY3Rpdml0eSBTY29yZSIsICJDWVAzQTUgQWN0aXZpdHkgU2NvcmUiLCAiQ1lQMkMxOSBBY3Rpdml0eSBTY29yZSIsICJDWVAyQzkgQWN0aXZpdHkgU2NvcmUiKQ0KDQptYWluICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjb2wubmFtZXMgPSBjKCJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiApLCBjYXB0aW9uID0gIlRhYmxlIDMuIEFzc29jaWF0aW9ucyBiZXR3ZWVuIG1lZGljYXRpb24gYW5kIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgd2l0aCBzY2hpem9waHJlbmlhIHN5bXB0b20gYW5kIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbnMgaW4gdGhlIHN1Ymdyb3VwIG9mIENhcmRpZmZDT0dTIHBhcnRpY2lwYW50cyBwcmVzY3JpYmVkIGNsb3phcGluZS4gRml2ZSBzZXBhcmF0ZSBtb2RlbHMgd2VyZSBmaXQsIGVhY2ggd2l0aCBzZXZlcml0eSBzY29yZXMgZm9yIGEgc2NoaXpvcGhyZW5pYSBwaGVub3R5cGUgYXMgdGhlIG91dGNvbWUgdmFyaWFibGUuIFZhcmlhYmxlcyBvZiBpbnRlcmVzdCBpbmNsdWRlZCB0aGUgbWVkaWNhdGlvbiB2YXJpYWJsZXMgKGkuZS4sIGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQgZGFpbHkgYW50aXBzeWNob3RpYyBkb3NlLCBjbG96YXBpbmUgdXNlLCBhbmQgYW50aWNob2xpbmVyZ2ljIHVzZSkgYW5kIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgKGkuZS4sIHRoZSBnZW5ldGljcy1pbmZlcnJlZCBlbnp5bWUgYWN0aXZpdHkgc2NvcmVzKS4gQWxsIG1vZGVscyBjb250cm9sbGVkIGZvciBtZWRpY2F0aW9uIGFkaGVyZW5jZSwgc2NoaXpvcGhyZW5pYSBQR1MsIGFnZSwgc2V4LCBhbmQgdGhlIGZpcnN0IGZpdmUgZ2VuZXRpYyBwcmluY2lwYWwgY29tcG9uZW50cy4gSW50ZWxsaWdlbmNlIFBHUyBhbmQgRWR1Y2F0aW9uYWwgQXR0YWlubWVudCBQR1Mgd2VyZSBpbmNsdWRlZCBhcyBhZGRpdGlvbmFsIGNvdmFyaWF0ZXMgaW4gdGhlIG1vZGVsIHdoZXJlIHRoZSBjb2duaXRpdmUgYWJpbGl0eSBkaW1lbnNpb24gaXMgdGhlIG91dGNvbWUuIFN0YW5kYXJkaXNlZCByZWdyZXNzaW9uIGVzdGltYXRlcyBhcmUgcmVwb3J0ZWQuIENQWi1lcSA9IGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQ7IFNFID0gU3RhbmRhcmQgRXJyb3I7IFBHUyA9IFBvbHlnZW5pYyBTY29yZS4iKSAlPiUgDQogICBhZGRfaGVhZGVyX2Fib3ZlKGhlYWRlciA9IGMoICIgIiA9IDEsICJQb3NpdGl2ZSAoQ2xvemFwaW5lIFN1Ymdyb3VwKSIgPSAyLCAiRGltaW5pc2hlZCBFeHByZXNzaXZpdHkgKENsb3phcGluZSBTdWJncm91cCkiID0gMiwgIlJlZHVjZWQgTW90aXZhdGlvbiBhbmQgUGxlYXN1cmUgKENsb3phcGluZSBTdWJncm91cCkiID0gMiwgIlN1aWNpZGUgYW5kIERlcHJlc3Npb24gKENsb3phcGluZSBTdWJncm91cCkiID0gMiwgIkNvZ25pdGlvbiAoQ2xvemFwaW5lIFN1Ymdyb3VwKSIgPSAyKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQpgYGANCg0KPGJyPg0KPGJyPg0KDQpBcyByZWNvbW1lbmRlZCBpbiB0aGUgU1RSRUdBIGd1aWRlbGluZXMsIHdlIHByb3ZpZGUgdW5hZGp1c3RlZCBlc3RpbWF0ZXMgZm9yIGFzc29jaWF0aW9ucyBiZXR3ZWVuIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgYW5kIHN5bXB0b20gZGltZW5zaW9ucyAoKipTdXBwbGVtZW50YXJ5IFRhYmxlcyA5ICYgMTAqKikuIFNlbnNpdGl2aXR5IGFuYWx5c2VzIGluIHdoaWNoIHdlIGNvbnRyb2xsZWQgZm9yIG1lZGljYXRpb24gdGhhdCBtYXkgbGVhZCB0byBwaGVub2NvbnZlcnNpb24gZGlkIG5vdCBsZWFkIHRvIGRpZmZlcmVudCByZXN1bHRzICgqKlN1cHBsZW1lbnRhcnkgVGFibGVzIDExICYgMTIqKikuIEhvd2V2ZXIsIGluY2x1c2lvbiBvZiBhbiBpbnRlcmFjdGlvbiB0ZXJtIGJldHdlZW4gQ1lQMUEyIGFuZCBzbW9raW5nIHN0YXR1cyBpbiBvdXIgbW9kZWwgYXR0ZW51YXRlZCB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBDWVAxQTIgYWN0aXZpdHkgc2NvcmUgYW5kIHRoZSBjb2duaXRpdmUgZGltZW5zaW9uICgqKlN1cHBsZW1lbnRhcnkgVGFibGUgMTMqKikuIFRoaXMgc3VnZ2VzdHMgdGhhdCB0aGlzIHBoYXJtYWNvZ2Vub21pYyBhc3NvY2lhdGlvbiBtYXkgYmUgcGFydGx5IGV4cGxhaW5lZCBieSBwYXRpZW50IGxpZmVzdHlsZSBmYWN0b3JzLiBIb3dldmVyLCBvdXIgc2Vuc2l0aXZpdHkgYW5hbHlzaXMgaXMgbGltaXRlZCBieSBpbmNvbXBsZXRlIHNtb2tpbmcgaW5mb3JtYXRpb24gaW4gdGhlIHNhbXBsZTsgdGh1cywgZGltaW5pc2hlZCBzdGF0aXN0aWNhbCBwb3dlciBtYXkgYWxzbyBhY2NvdW50IGZvciB0aGlzIHdlYWtlbmVkIGFzc29jaWF0aW9uLg0KDQo8YnI+DQo8YnI+DQo8YnI+DQo8YnI+DQoNCiMjIDxzdHJvbmc+IERpc2N1c3Npb24gPC9zdHJvbmc+DQoNCiMjIyBEaXNjdXNzaW9uDQoNClRoaXMgY3Jvc3Mtc2VjdGlvbmFsIHN0dWR5IGludmVzdGlnYXRlZCBtZWRpY2F0aW9uIGFuZCBwaGFybWFjb2dlbm9taWMgY29ycmVsYXRlcyBvZiBjdXJyZW50IHBoZW5vdHlwZSBzZXZlcml0eSBpbiBwZW9wbGUgd2l0aCBzY2hpem9waHJlbmlhIG9yIHNjaGl6b2FmZmVjdGl2ZSBkaXNvcmRlciBkZXByZXNzZWQtdHlwZS4gV2UgZm91bmQgdGhhdCBoaWdoZXIgZGFpbHkgY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudCBhbnRpcHN5Y2hvdGljIGRvc2Ugd2FzIGFzc29jaWF0ZWQgd2l0aCBtb3JlIHNldmVyZSBzY29yZXMgb24gYm90aCB0aGUgcG9zaXRpdmUgc3ltcHRvbSBhbmQgdGhlIHN1aWNpZGUgYW5kIGRlcHJlc3Npb24gZGltZW5zaW9ucywgd2hpbGUgY2xvemFwaW5lIHVzZSB3YXMgYXNzb2NpYXRlZCB3aXRoIHdvcnNlIHNjb3JlcyBvbiB0aGUgdHdvIG5lZ2F0aXZlIHN5bXB0b20gZGltZW5zaW9ucyAoaS5lLiwgZGltaW5pc2hlZCBleHByZXNzaXZpdHksIHJlZHVjZWQgbW90aXZhdGlvbiBhbmQgcGxlYXN1cmUpLiBXZSBhbHNvIGZvdW5kIHRoYXQgY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudCBkYWlseSBhbnRpcHN5Y2hvdGljIGRvc2UsIGNsb3phcGluZSB1c2UsIGFuZCBhbnRpY2hvbGluZXJnaWMgdXNlIHdlcmUgYWxsIGFzc29jaWF0ZWQgd2l0aCBsb3dlciBzY29yZXMgb24gdGhlIGNvZ25pdGl2ZSBkaW1lbnNpb24sIGluZGljYXRpbmcgcG9vcmVyIGNvZ25pdGl2ZSBhYmlsaXR5LiANCg0KU29tZSBvZiB0aGUgYXNzb2NpYXRpb25zIHdlIGhhdmUgb2JzZXJ2ZWQgYmV0d2VlbiBkcnVnIGRvc2FnZSBhbmQgc3ltcHRvbWF0b2xvZ3kgYXJlIGxpa2VseSB0byByZWZsZWN0IGluZmx1ZW5jZXMgb2YgdGhlIGxhdHRlciBvbiBwcmVzY3JpYmluZyBwYXR0ZXJucy4gSGlnaGVyIGRvc2VzIG9mIGFudGlwc3ljaG90aWMgbWVkaWNhdGlvbiBhcmUgbGlrZWx5IHRvIGJlIHByZXNjcmliZWQgdG8gaGVscCBtYW5hZ2UgbW9yZSBzZXZlcmUgb3IgaW5jb21wbGV0ZWx5IHJlc29sdmVkIHBvc2l0aXZlIHN5bXB0b21zLCB3aGlsZSBuZWdhdGl2ZSBzeW1wdG9tcyBkbyBub3QgZ2VuZXJhbGx5IHJlc3BvbmQgd2VsbCB0byB0eXBpY2FsIGFudGlwc3ljaG90aWNzIGFuZCBtYXkgdHJpZ2dlciB0aGUgcHJlc2NyaXB0aW9uIG9mIGNsb3phcGluZSB3aGljaCBkb2VzIGhhdmUgZWZmaWNhY3kgaW4gdGhpcyBkb21haW5eNDdeLiANCg0KT3VyIGZpbmRpbmdzIHRoYXQgYW50aXBzeWNob3RpYyBkb3NlLCBjbG96YXBpbmUgdXNlLCBhbmQgYW50aWNob2xpbmVyZ2ljIHVzZSB3ZXJlIGFzc29jaWF0ZWQgd2l0aCBwb29yZXIgY29nbml0aW9uIGFyZSBjb25zaXN0ZW50IHdpdGggb3RoZXIgcmVzZWFyY2heNDjigJM1M14uIE1vcmVvdmVyLCBvdXIgZWZmZWN0IHNpemVzIHdlcmUsIGluIHNvbWUgaW5zdGFuY2VzLCBzdWJzdGFudGlhbCwgd2l0aCBvdXIgc3Ryb25nZXN0IGFzc29jaWF0aW9uIGluZGljYXRpbmcgdGhhdCBzY29yZXMgb24gdGhlIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbiBhcmUgbmVhcmx5IDAuNSBzdGFuZGFyZCBkZXZpYXRpb25zIGxvd2VyIGluIHBhdGllbnRzIHByZXNjcmliZWQgY2xvemFwaW5lLiBUaGVzZSBmaW5kaW5ncyBjb3VsZCBiZSBwbGF1c2libHkgcmVsYXRlZCwgaW4gcGFydCwgdG8gY2F1c2FsIGVmZmVjdHMgb2YgZHJ1ZyB0cmVhdG1lbnQuIEhvd2V2ZXIsIGludGVycHJldGluZyBjcm9zcy1zZWN0aW9uYWwgZmluZGluZ3MgcmVsYXRpbmcgdG8gY29nbml0aW9uIGFuZCBtZWRpY2F0aW9uIHVzZSBpcyBjaGFsbGVuZ2luZyBkdWUgdG8gdGhlIHBvc3NpYmlsaXR5IG9mIHJldmVyc2UgY2F1c2F0aW9uIHdoZXJlYnkgcGF0aWVudHMgd2l0aCBjb2duaXRpdmUgaW1wYWlybWVudCBjb3VsZCBiZSBtb3JlIGxpa2VseSB0byByZWNlaXZlIGhpZ2hlciBkb3NlcyBvZiBtZWRpY2F0aW9uLiBUaGUgc2l0dWF0aW9uIHdpdGggcmVzcGVjdCB0byBjbG96YXBpbmUgbWF5IGJlIGV2ZW4gbW9yZSBjb21wbGV4IGJlY2F1c2UgYSBwcmVzY3JpcHRpb24gb2YgY2xvemFwaW5lIHVzdWFsbHkgbmVjZXNzaXRhdGVzIGEgZGlhZ25vc2lzIG9mIFRSUywgd2hpY2ggaXMgaXRzZWxmIGFzc29jaWF0ZWQgd2l0aCBncmVhdGVyIGNvZ25pdGl2ZSBpbXBhaXJtZW50IHRoYW4gdHJlYXRtZW50LXJlc3BvbnNpdmUgc2NoaXpvcGhyZW5pYV41NOKAkzU2Xi4gIE5ldmVydGhlbGVzcywgdGhlIGFzc29jaWF0aW9ucyBvYnNlcnZlZCBiZXR3ZWVuIGJvdGggYW50aXBzeWNob3RpYyBkb3NlIGFuZCBjbG96YXBpbmUgdXNlIHdpdGggcG9vcmVyIGNvZ25pdGlvbiB3ZXJlIHNpZ25pZmljYW50IGFmdGVyIGNvbnRyb2xsaW5nIGZvciBwcmVtb3JiaWQgaW50ZWxsaWdlbmNlIGFzIGluZGV4ZWQgYnkgUEdTIGZvciBpbnRlbGxpZ2VuY2UgYW5kIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQuIFRoZXNlIG1lZGljYXRpb24gYXNzb2NpYXRpb25zIG1vc3RseSByZXBsaWNhdGUgaW4gdGhlIGFsdGVybmF0aXZlIGFuYWx5c2lzIGRlc2NyaWJlZCBpbiB0aGUgKipTdXBwbGVtZW50YXJ5IE1hdGVyaWFscyoqIHVzaW5nIE5BUlQgdG8gZXN0aW1hdGUgcHJlbW9yYmlkIGludGVsbGlnZW5jZSwgYWxiZWl0IHdpdGggd2Vha2VyIHNpZ25hbHMuIEluIGFsbCwgb3VyIGFuYWx5c2VzIHRlbnRhdGl2ZWx5IHN1cHBvcnQgdGhlIGludGVycHJldGF0aW9uIHRoYXQgdGhlIGFzc29jaWF0aW9uIG1heSBiZSBjYXVzYWxseSByZWxhdGVkIHRvIG1lZGljYXRpb24gdXNlLCBpbnN0ZWFkIG9mIHJlZmxlY3RpbmcgdGhlIGNvbmZvdW5kaW5nIGVmZmVjdHMgb2YgbG93ZXIgcHJlbW9yYmlkIGNvZ25pdGl2ZSBhYmlsaXR5IGluIHRob3NlIHdobyBzdWJzZXF1ZW50bHkgcmVjZWl2ZSBjbG96YXBpbmUgb3IgaGlnaGVyIGRvc2VzIG9mIGFudGlwc3ljaG90aWNzLg0KDQpPdXIgY29tYmluZWQgYW5hbHlzaXMgb2YgcGhhcm1hY29nZW5vbWljIGFuZCBtZWRpY2F0aW9uIHZhcmlhYmxlcyBvZmZlcnMgYSBwb3RlbnRpYWwgbWVhbnMgb2YgZHJhd2luZyBjYXVzYWwgaW5mZXJlbmNlcyBpbiByZWdhcmQgdG8gdGhlIG9ic2VydmVkIGFzc29jaWF0aW9ucyBiZXR3ZWVuIGRydWcgdHJlYXRtZW50IGFuZCBjb2duaXRpb24uIENZUDFBMiBpcyB0aGUgbWFpbiBlbnp5bWUgcmVzcG9uc2libGUgZm9yIGNsb3phcGluZSBmaXJzdC1wYXNzIG1ldGFib2xpc21eNTcsNTheLiBIaWdoZXIgZW56eW1lIGFjdGl2aXR5IGNhbiBiZSBleHBlY3RlZCB0byByZXN1bHQgaW4gbG93ZXIgY2xvemFwaW5lIGJpb2F2YWlsYWJpbGl0eSBmb3IgYSBnaXZlbiBkb3NlLiBVbmRlciBhIGNhdXNhbCBtb2RlbCwgdGhpcyBzaG91bGQgbGVhZCB0byBmZXdlciBjbG96YXBpbmUtaW5kdWNlZCBjb2duaXRpdmUgZWZmZWN0cy4gV2UgaW5kZWVkIG9ic2VydmVkIHRoaXMgaW4gdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gaGlnaGVyIGNvZ25pdGl2ZSBhYmlsaXR5IGFuZCBmYXN0ZXIgZ2Vub3R5cGUtaW5mZXJyZWQgQ1lQMUEyIGFjdGl2aXR5IGluIHBlb3BsZSBwcmVzY3JpYmVkIGNsb3phcGluZSAoKipUYWJsZSAzKiopLCB3aGljaCBwb2ludHMgdG8gdGhlIHBvc3NpYmlsaXR5IHRoYXQgYW55IG5lZ2F0aXZlIGltcGFjdCBvZiBjbG96YXBpbmUgaW4gY29nbml0aW9uIGNvdWxkIGJlIGFtZWxpb3JhdGVkIGluIHRob3NlIHdpdGggZmFzdGVyIGNsb3phcGluZSBtZXRhYm9saXNtLiBJbiBwYXJhbGxlbCwgYSBub21pbmFsbHkgc2lnbmlmaWNhbnQgYXNzb2NpYXRpb24gYWxzbyBleGlzdHMgYmV0d2VlbiBoaWdoZXIgY29nbml0aXZlIGFiaWxpdHkgYW5kIGxvd2VyIGRvc2UgaW4gdGhvc2UgcHJlc2NyaWJlZCBjbG96YXBpbmUuIEluIHRoZSBjb250ZXh0IG9mIGFsbCB0aGVzZSByZXN1bHRzLCB3ZSByZW1hcmsgdGhlIHVzZSBvZiBwaGFybWFjb2dlbmV0aWMgaW5mb3JtYXRpb24gdG8gcGhlbm90eXBlIGVuenltZSBhY3Rpdml0eSBhbmQgdGh1cyBkcnVnIG1ldGFib2xpc20sIGhpZ2hsaWdodGluZyBpbmRpdmlkdWFscyB0aGF0IGNvdWxkIGJlIHBhcnRpY3VsYXJseSB2dWxuZXJhYmxlIHRvIGRvc2UtZGVwZW5kZW50IGFkdmVyc2UgZHJ1ZyByZWFjdGlvbnMgKEFEUnMpLiBXZSBhbHNvIG5vdGUgdGhhdCB3aGlsZSB0aGlzIHJlc2VhcmNoIHRha2VzIGFkdmFudGFnZSBvZiBzdWNoIGEgcGhlbm90eXBpbmcgYXBwcm9hY2gsIHRoZSBhdHlwaWNhbCBpbnN0YW5jZXMgb2YgY2xvemFwaW5lIG1ldGFib2xpc20gdGhhdCB3b3VsZCBjaGFyYWN0ZXJpc2UgdGhlc2UgaW5kaXZpZHVhbHMgaW4gY2xpbmljYWwgc2NlbmFyaW9zIGNhbiBhbHJlYWR5IGJlIGRldGVjdGVkIGJ5IHRoZXJhcGV1dGljIGRydWcgbW9uaXRvcmluZy4gRm9yIHRoaXMgcmVhc29uLCB3ZSBlY2hvIHRoZSByZWNlbnQgcmVjb21tZW5kYXRpb25zIGZvciB0aGVyYXBldXRpYyBkcnVnIG1vbml0b3JpbmcgcHJvY2VkdXJlcyB0byBiZSBtb3JlIHJlYWRpbHkgYWRvcHRlZCBhcyBhIHJvdXRpbmUgcGFydCBvZiB0aGUgY2xpbmljYWwgbWFuYWdlbWVudCBvZiB0aG9zZSBvbiBjbG96YXBpbmVeNTleLg0KDQpXZSBhbHNvIHJlcG9ydGVkIGFuIGludmVyc2UgYXNzb2NpYXRpb24gYmV0d2VlbiBwcmVzY3JpcHRpb24gb2YgYW50aWNob2xpbmVyZ2ljIG1lZGljYXRpb24gYW5kIGNvZ25pdGlvbi4gU29tZSBhbnRpcHN5Y2hvdGljcyBjYXVzZSBleHRyYS1weXJhbWlkYWwgc2lkZSBlZmZlY3RzLCBnZW5lcmFsbHkgYXMgYSBkb3NlLWRlcGVuZGVudCBBRFJeNjAsNjFeLiBFeHRyYSBweXJhbWlkYWwgc2lkZSBlZmZlY3RzIGFyZSBtYW5hZ2VkIHdpdGggYW50aWNob2xpbmVyZ2ljIG1lZGljYXRpb24sIGFuZCBhbHRob3VnaCBub3QgcmVjb21tZW5kZWQsIHRoZXNlIGRydWdzIG1heSBiZSBwcmVzY3JpYmVkIHByb3BoeWxhY3RpY2FsbHksIHByZS1lbXB0aW5nIHRoZSBvbnNldCBvZiB0aGVzZSBBRFJzXjYyLDYzXi4gVGhlIGFzc29jaWF0aW9uIGJldHdlZW4gYW50aWNob2xpbmVyZ2ljIHByZXNjcmlwdGlvbiBhbmQgY29nbml0aW9uIGlzIGluZGVwZW5kZW50IG9mIGRhaWx5IGFudGlwc3ljaG90aWMgZG9zZS4gVGhlcmVmb3JlLCB0aGlzIGxpa2VseSByZWZsZWN0cyBhIGRpc3RpbmN0IGNvbnRyaWJ1dGlvbiBvZiBhbnRpY2hvbGluZXJnaWNzIG9uIGNvZ25pdGlvbiwgYXMgb3Bwb3NlZCB0byBjYXB0dXJpbmcgb3VyIHJlcG9ydGVkIGRvc2UtY29nbml0aW9uIGFzc29jaWF0aW9uIGdpdmVuIHRoZSBoaWdoZXIgcmF0ZXMgb2YgYW50aWNob2xpbmVyZ2ljIHByZXNjcmlwdGlvbiBhbW9uZ3N0IHBlb3BsZSBvbiBoaWdoIGFudGlwc3ljaG90aWMgZG9zZXNeNjReLiANCg0KV2Ugb2JzZXJ2ZWQgc2V2ZXJhbCBhc3NvY2lhdGlvbnMgYmV0d2VlbiBmYXN0ZXIgZ2Vub3R5cGUtaW5mZXJyZWQgZW56eW1lIGFjdGl2aXR5IHdpdGggbG93ZXIgc2NoaXpvcGhyZW5pYSBzeW1wdG9tIHNldmVyaXR5LiBJbmNyZWFzZWQgQ1lQMkMxOSBhY3Rpdml0eSB3YXMgYXNzb2NpYXRlZCB3aXRoIGxvd2VyIHNldmVyaXR5IG9mIHBvc2l0aXZlIHN5bXB0b21zLiBBc3NvY2lhdGlvbnMgYmV0d2VlbiBDWVAyQzE5IHdpdGggYm90aCBzY2hpem9waHJlbmlhIHNldmVyaXR5XjEyLDY1XiBhbmQgc3ltcHRvbSBpbXByb3ZlbWVudF42Nl4gaGF2ZSBiZWVuIHJlcG9ydGVkIGFsdGhvdWdoIHRob3NlIHN0dWRpZXMgaW5jbHVkZWQgb25seSBwZW9wbGUgdGFraW5nIGNsb3phcGluZSBhbmQgZW1wbG95ZWQgYSBzaW5nbGUsIGdlbmVyYWwgbWVhc3VyZSBvZiBzeW1wdG9tIHNldmVyaXR5LiBJbiB0aGUgYWJzZW5jZSBvZiBsb25naXR1ZGluYWwgc3ltcHRvbSBzY29yZXMsIHdlIGNhbm5vdCBpbnZlc3RpZ2F0ZSB0aGUgcmF0aGVyIGNvdW50ZXItaW50dWl0aXZlIGh5cG90aGVzaXMgc3VnZ2VzdGVkIGJ5IG91ciBkYXRhIHRoYXQgZ3JlYXRlciBhbnRpcHN5Y2hvdGljIGNsZWFyYW5jZSwgaW5kZXhlZCBieSBDWVAyQzE5IGFjdGl2aXR5LCBtaWdodCBsZWFkIHRvIGluY3JlYXNlZCBkcnVnIGVmZmVjdGl2ZW5lc3MuIENZUDJDMTkgaXMgdGhvdWdodCB0byBwbGF5IGEgbWlub3IgcGFydCB3aXRoaW4gdGhlIGNsb3phcGluZSBtZXRhYm9saWMgcGF0aHdheV42N14gYnV0IGl0cyByb2xlIGluIGFudGlwc3ljaG90aWMgbWV0YWJvbGlzbSBtb3JlIHdpZGVseSBpcyBwb29ybHkgZG9jdW1lbnRlZF42OF4uIFRoaXMgaXMgYW4gYXZlbnVlIGZvciBmdXR1cmUgc3R1ZGllcyB0byBmb2xsb3cuIA0KDQpJbmNyZWFzZWQgZ2VuZXRpY2FsbHkgaW5mZXJyZWQgQ1lQM0E1IGFjdGl2aXR5IHdhcyBhc3NvY2lhdGVkIHdpdGggbG93ZXIgc2NvcmVzIG9uIGJvdGggdGhlIG5lZ2F0aXZlIHN5bXB0b20gZGltZW5zaW9ucy4gV2hpbGUgYXNzb2NpYXRpb25zIHdpdGggdGhlIHR3byBkb21haW5zIGluY3JlYXNlcyBjb25maWRlbmNlIGluIHRoZSBmaW5kaW5ncywgY2F1dGlvbiBpcyB3YXJyYW50ZWQgZ2l2ZW4gdGhhdCB0aGVzZSBhcmUgbW9kZXJhdGVseSBjb3JyZWxhdGVkIChzZWUgKipGaWd1cmUgMioqKSwgYW5kIHdlIGRpZCBub3QgZmluZCBvcnRob2dvbmFsIGV2aWRlbmNlIHRoYXQgZWl0aGVyIG9mIHRoZXNlIGRpbWVuc2lvbnMgd2VyZSBhc3NvY2lhdGVkIHdpdGggYW50aXBzeWNob3RpYyBkb3NlLiAgVGh1cywgcmVwbGljYXRpb24gb2YgdGhlc2UgYXNzb2NpYXRpb25zIGlzIHJlcXVpcmVkLiBDWVAzQTUgaXMgcmVsYXRpdmVseSB1bmRlci1leGFtaW5lZCBpbiBhbnRpcHN5Y2hvdGljIHJlc2VhcmNoXjY5XiBhbmQgaXRzIG1haW4gZ2Vub3R5cGUgdGhhdCBsZWFkcyB0byBwb29yIG1ldGFib2xpc20gKFwqMS9cKjMpIGlzIGNvbW1vbiB3b3JsZHdpZGUgYnV0IHBhcnRpY3VsYXJseSBpbiBFdXJvcGVhbiBwb3B1bGF0aW9ucy4gSW5kZWVkLCBpdCBoYXMgYmVlbiBvYnNlcnZlZCB0aGF0IG1ham9yIGRpZmZlcmVuY2VzIGluIGdlbm90eXBlL3BoZW5vdHlwZSBkaXN0cmlidXRpb25zIGZvciB0aGlzIGVuenltZSBhcmUgbWFpbmx5IGRyaXZlbiBieSB0aGUgaW5jbHVzaW9uIG9mIEFmcmljYW4gYW5jZXN0cmllcyBpbiBzdHVkaWVzXjcwLDcxXiwgYXMgZnVuY3Rpb25hbCBDWVAzQTUgYWxsZWxlcyBhcmUgbW9yZSBjb21tb24gaW4gQWZyaWNhLiBQb3B1bGF0aW9ucyBmcm9tIEFzaWFuIGNvdW50cmllcyBhbHNvIHNlZW0gdG8gaGF2ZSBoaWdoZXIgZGl2ZXJzaXR5IG9mIENZUDNBNSBhbGxlbGVzIHRoYW4gRXVyb3BlLCB0aG91Z2ggcmVzZWFyY2ggaW4gdGhpcyBjb250aW5lbnQgaXMgc3RpbGwgc2NhcmNlXjcyXi4gRnV0dXJlIHJlc2VhcmNoIGFpbWluZyB0byBpbnZlc3RpZ2F0ZSB0aGUgcmVsZXZhbmNlIG9mIENZUDNBNSBmb3Igb3V0Y29tZXMgaW4gcHN5Y2hpYXRyaWMgcG9wdWxhdGlvbnMgc2hvdWxkIHRoZXJlZm9yZSBhaW0gdG8gaW5jbHVkZSBtb3JlIGNvaG9ydHMgZnJvbSBhZG1peGVkIGFuZCBub24tRXVyb3BlYW4gYW5jZXN0cmFsIG1ha2V1cHMuIA0KDQpGaW5hbGx5LCB3ZSBkaWQgbm90IG9ic2VydmUgZXZpZGVuY2UgZm9yIGFuIGFzc29jaWF0aW9uIGJldHdlZW4gQ1lQMUEyIGFjdGl2aXR5IHNjb3JlIGFuZCBlaXRoZXIgdGhlIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIHNjaGl6b3BocmVuaWEgc3ltcHRvbSBkaW1lbnNpb25zLiBBIGNvcnJlbGF0aW9uIGJldHdlZW4gQ1lQMUEyIGFjdGl2aXR5IGFuZCBzeW1wdG9tIHNldmVyaXR5IGhhcyBiZWVuIHJlcG9ydGVkXjExXiwgYW5kIHdoaWxlIHNldmVyYWwgZGlmZmVyZW5jZXMgZXhpc3QgYmV0d2VlbiB0aGUgbWV0aG9kcyBhbmQgc2FtcGxlIGVtcGxveWVkIGluIG91ciBvd24gYW5kIHRoZSBwcmV2aW91cyBzdHVkeSwgdGhlIG9ic2VydmVkIHRyZW5kcyBpbiBvdXIgZGF0YSBhcmUgbm90IGNvbnNpc3RlbnQgd2l0aCB0aGVpciBmaW5kaW5ncy4gV2UgYWxzbyBmb3VuZCBubyBhc3NvY2lhdGlvbiBiZXR3ZWVuIHRoZSBDWVAyQzkgYWN0aXZpdHkgc2NvcmUgYW5kIGFueSBvZiBvdXIgcGhlbm90eXBlIHNldmVyaXR5IHNjb3Jlcy4NCg0KVGhlIHByaW1hcnkgbGltaXRhdGlvbiBvZiB0aGlzIHN0dWR5IGlzIGl0cyBjcm9zcy1zZWN0aW9uYWwgbmF0dXJlIHdoaWNoIG1lYW5zIHdlIGFyZSB1bmFibGUgdG8gYXNzZXNzIGRydWcgdHJlYXRtZW50IHJlc3BvbnNlLCBjb25zdHJhaW5pbmcgb3VyIGFiaWxpdHkgdG8gbWFrZSByb2J1c3QgaW5mZXJlbmNlcyBhYm91dCB0aGUgY2F1c2FsIGRpcmVjdGlvbnMgZm9yIGFueSBvZiB0aGUgYXNzb2NpYXRpb25zLiBTZWNvbmQsIG91ciBiZXN0IGZpdHRpbmcgQ0ZBIG1vZGVsIGRpZCBub3QgaW5jbHVkZSBhIGRpc29yZ2FuaXNlZCBkaW1lbnNpb24sIGFuZCB0aGVyZWZvcmUgb3VyIHN0dWR5IGNhbm5vdCBhZGRyZXNzIHRoZSBwb3NzaWJsZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhpcyBzeW1wdG9tIGRpbWVuc2lvbiB3aXRoIG1lZGljYXRpb24gYW5kIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMuIEZpbmFsbHksIGFsdGhvdWdoIG5vIGluZGl2aWR1YWxzIHdlcmUgZXhjbHVkZWQgYmFzZWQgb24gYW5jZXN0cnksIDk1JSBvZiB0aGUgc2FtcGxlIHJlcG9ydGVkIFVLL0V1cm9wZWFuIGFzIHRoZWlyIGV0aG5pYyBiYWNrZ3JvdW5kLiBDcm9zcy1jdWx0dXJhbCBkaWZmZXJlbmNlcyBwZXJtZWF0ZSBtb3N0IGFzcGVjdHMgb2YgcHN5Y2hpYXRyeSwgd2l0aCB2YXJpYXRpb24gZXhpc3RpbmcgaW4gZGlhZ25vc3RpYyBjcml0ZXJpYSwgcHJvZ25vc2lzLCB0aGVyYXBldXRpYy9wcmVzY3JpYmluZyBwcmFjdGljZXMsIGFuZCBtb3JlXjczXi4gV2hpbGUgYW5jZXN0cmFsbHkgZGl2ZXJzZSBzYW1wbGVzIGFyZSBiZWNvbWluZyBtb3JlIGNvbW1vbiwgcGFydGljdWxhcmx5IGluIGxhcmdlciBzY2FsZSBnZW5ldGljcyBzdHVkaWVzLCB0aGlzIGhhc27igJl0IGFsd2F5cyBiZWVuIHRoZSBjYXNlLiBUaGVyZWZvcmUsIHJlcGxpY2F0aW9uIG9mIHRoaXMgd29yayBhY3Jvc3MgYW5jZXN0cmFsbHkgZGl2ZXJzZSBzYW1wbGVzIGlzIHJlcXVpcmVkIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZXNlIHJlc3VsdHMgYXJlIGdlbmVyYWxpc2FibGUgb3V0c2lkZSBvZiBXaGl0ZSBFdXJvcGVhbiBiYWNrZ3JvdW5kcy4NCg0KT3ZlcmFsbCwgb3VyIGZpbmRpbmdzIGluZGljYXRlIHRoYXQgcG9vcmVyIGNvZ25pdGl2ZSBhYmlsaXR5IGluIGluZGl2aWR1YWxzIHdpdGggc2NoaXpvcGhyZW5pYSB3YXMgYXNzb2NpYXRlZCB3aXRoIHRoZSB1c2Ugb2YgY2xvemFwaW5lIGFuZCBhbnRpY2hvbGluZXJnaWNzLCBhbG9uZ3NpZGUgaGlnaCBkb3NlcyBvZiBhbnRpcHN5Y2hvdGljIG1lZGljYXRpb24uIENvZ25pdGlvbiBpcyBhbiBpbXBvcnRhbnQgcHJlZGljdG9yIG9mIHNjaGl6b3BocmVuaWEgZnVuY3Rpb25hbCBvdXRjb21lc143NF4uIFRoZXJlZm9yZSwgdW5kZXJzdGFuZGluZyB0aGUgcG90ZW50aWFsbHkgbXVsdGlmYWNldGVkIGJ1cmRlbiBvZiB0aGVzZSBkcnVncyBjb3VsZCBoZWxwIGNsaW5pY2lhbnMgbWluaW1pc2UgdGhlIGxpa2VsaWhvb2Qgb2YgY29nbml0aXZlIGltcGFpcm1lbnQgYW5kIG90aGVyIHBvb3Igb3V0Y29tZXMgZHVyaW5nIHNjaGl6b3BocmVuaWEgcGhhcm1hY290aGVyYXB5LiBMb25naXR1ZGluYWwgc3R1ZGllcywgcGFydGljdWxhcmx5IHJhbmRvbWlzZWQgY29udHJvbGxlZCB0cmlhbHMsIGFyZSByZXF1aXJlZCB0byBmdWxseSB1bmRlcnN0YW5kIHRoZSByb2xlIHRoYXQgcGhhcm1hY290aGVyYXB5LCBlc3BlY2lhbGx5IGNsb3phcGluZSBhbmQgYW50aWNob2xpbmVyZ2ljcywgaGFzIG9uIGNvZ25pdGl2ZSBvdXRjb21lcyBmb3IgdGhvc2Ugd2l0aCBzY2hpem9waHJlbmlhLiBIb3dldmVyLCBnaXZlbiB0aGUgbGFjayBvZiBldmlkZW5jZS1iYXNlZCBndWlkZWxpbmVzIGZvciBvcHRpbWlzaW5nIGFudGlwc3ljaG90aWMgZG9zZXMgaW4gdGhlIG1haW50ZW5hbmNlIHBoYXNlIG9mIHRyZWF0bWVudF43NV4sIGFkZHJlc3NpbmcgcG90ZW50aWFsIGNvZ25pdGl2ZSBpbXBhY3RzIG1pZ2h0IGJlIGFuIGFjdGlvbmFibGUgdGFyZ2V0IGZvciBmdXR1cmUgaW50ZXJ2ZW50aW9uYWwgcmVzZWFyY2guIEZvciBleGFtcGxlLCBpZiBpbmZvcm1hdGlvbiBmcm9tIHByZXNjcmlwdGlvbiByZWNvcmRzIChlLmcuIGRydWcgY2xhc3NlcyBhbmQgZG9zZXMpIGNvdWxkIGNvbnRyaWJ1dGUgdG8gaWRlbnRpZnlpbmcgcGF0aWVudHMgYXQgaGlnaCByaXNrIG9mIHJlZHVjZWQgY29nbml0aW9uLCB0aGV5IGNvdWxkIGJlIHByaW9yaXRpc2VkIGZvciBjbG9zZXIgbW9uaXRvcmluZyBhbmQvb3IgbWl0aWdhdGlvbnMgKGUuZy4sIGNvZ25pdGl2ZSByZW1lZGlhdGlvbiB0aGVyYXB5IG9yIGF2b2lkaW5nIHByb3BoeWxhY3RpYyBhbnRpY2hvbGluZXJnaWNzKS4gDQoNCldlIGFsc28gaWRlbnRpZnkgYXNzb2NpYXRpb25zIGJldHdlZW4gdGhlIGluY3JlYXNlZCBhY3Rpdml0eSBvZiBjZXJ0YWluIENZUCBlbnp5bWVzIGFuZCB0aGUgcmVkdWNlZCBzZXZlcml0eSBvZiBwb3NpdGl2ZSwgbmVnYXRpdmUsIGFuZCBjb2duaXRpdmUgc3ltcHRvbXMuIEV4Y2VwdCBmb3IgQ1lQMUEyIGluIHBhdGllbnRzIHRha2luZyBjbG96YXBpbmUsIHdoaWNoIHdlIGRpc2N1c3MgZWFybGllciwgdGhlIG1lY2hhbmlzbXMgYnkgd2hpY2ggdmFyaWF0aW9uIHdpdGhpbiB0aGVzZSBwaGFybWFjb2dlbmVzIGNvdWxkIGluZmx1ZW5jZSBzY2hpem9waHJlbmlhIHNldmVyaXR5IGFyZSB1bmNsZWFyLiBXaGlsZSBvdXIgcmVzdWx0cyBpbXBsaWNhdGUgcGhhcm1hY29nZW5vbWljIHZhcmlhdGlvbiBpbiBhbnRpcHN5Y2hvdGljIHBoYXJtYWNvZHluYW1pY3MsIGFuIGFyZWEgb2YgcHN5Y2hvcGhhcm1hY29sb2d5IHdoZXJlIHJvYnVzdCBwcmVkaWN0b3JzIGFyZSBwYXJ0aWN1bGFybHkgc2NhcmNlLCBmdXJ0aGVyIHZhbGlkYXRpb24gb2Ygb3VyIGZpbmRpbmdzIGluIGxhcmdlciwgbW9yZSBkaXZlcnNlIHNhbXBsZXMgaXMgcmVxdWlyZWQgYmVmb3JlIGNoYXJ0aW5nIGEgY291cnNlIGZyb20gdGhpcyBiYXNpYyBldmlkZW5jZSB0b3dhcmRzIGltcHJvdmVkIHN0cmF0ZWdpZXMgZm9yIHBhdGllbnQgc3VwcG9ydCBhbmQgY2FyZS4gDQoNCjxicj4NCjxicj4NCjxicj4NCjxicj4NCg0KIyMgPHN0cm9uZz4gUmVmZXJlbmNlcyA8L3N0cm9uZz4NCiMjIyBSZWZlcmVuY2VzIA0KDQo8YnI+DQoxCUNhcmJvbiBNLCBDb3JyZWxsIENVLiBDbGluaWNhbCBwcmVkaWN0b3JzIG9mIHRoZXJhcGV1dGljIHJlc3BvbnNlIHRvIGFudGlwc3ljaG90aWNzIGluIHNjaGl6b3BocmVuaWEuIERpYWxvZ3VlcyBDbGluIE5ldXJvc2NpIDIwMTQ7IDE2OiA1MDXigJMyNC4NCg0KMglaaGFuZyBKLVAsIFJvYmluc29uIEQsIFl1IEosIGV0IGFsLiBTY2hpem9waHJlbmlhIFBvbHlnZW5pYyBSaXNrIFNjb3JlIGFzIGEgUHJlZGljdG9yIG9mIEFudGlwc3ljaG90aWMgRWZmaWNhY3kgaW4gRmlyc3QtRXBpc29kZSBQc3ljaG9zaXMuIEFKUCAyMDE5OyAxNzY6IDIx4oCTOC4NCg0KMwlKb25hcyBLRywgTGVuY3ogVCwgTGkgSywgZXQgYWwuIFNjaGl6b3BocmVuaWEgcG9seWdlbmljIHJpc2sgc2NvcmUgYW5kIDIwLXllYXIgY291cnNlIG9mIGlsbG5lc3MgaW4gcHN5Y2hvdGljIGRpc29yZGVycy4gVHJhbnNsIFBzeWNoaWF0cnkgMjAxOTsgOTogMeKAkzguDQoNCjQJTGVnZ2UgU0UsIENhcmRubyBBRywgQWxsYXJkeWNlIEosIGV0IGFsLiBBc3NvY2lhdGlvbnMgQmV0d2VlbiBTY2hpem9waHJlbmlhIFBvbHlnZW5pYyBMaWFiaWxpdHksIFN5bXB0b20gRGltZW5zaW9ucywgYW5kIENvZ25pdGl2ZSBBYmlsaXR5IGluIFNjaGl6b3BocmVuaWEuIEpBTUEgUHN5Y2hpYXRyeSAyMDIxOyA3ODogMTE0M+KAkzUxLg0KDQo1CUFoYW5nYXJpIE0sIEJ1c3RhbWFudGUgRCwgS2lya3BhdHJpY2sgUiwgZXQgYWwuIFJlbGF0aW9uc2hpcCBiZXR3ZWVuIHBvbHlnZW5pYyByaXNrIHNjb3JlcyBhbmQgc3ltcHRvbSBkaW1lbnNpb25zIG9mIHNjaGl6b3BocmVuaWEgYW5kIHNjaGl6b3R5cHkgaW4gbXVsdGlwbGV4IGZhbWlsaWVzIHdpdGggc2NoaXpvcGhyZW5pYS4gVGhlIEJyaXRpc2ggSm91cm5hbCBvZiBQc3ljaGlhdHJ5IDIwMjM7IDIyMzogMzAx4oCTOC4NCg0KNgl2YW4gV2VzdHJoZW5lbiBSLCBBaXRjaGlzb24gS0osIEluZ2VsbWFuLVN1bmRiZXJnIE0sIEp1a2nEhyBNTS4gUGhhcm1hY29nZW5vbWljcyBvZiBBbnRpZGVwcmVzc2FudCBhbmQgQW50aXBzeWNob3RpYyBUcmVhdG1lbnQ6IEhvdyBGYXIgSGF2ZSBXZSBHb3QgYW5kIFdoZXJlIEFyZSBXZSBHb2luZz8gRnJvbnRpZXJzIGluIFBzeWNoaWF0cnkgMjAyMDsgMTEuDQoNCjcJU3dlbiBKSiwgdmFuIGRlciBXb3VkZW4gQ0gsIE1hbnNvbiBMRSwgZXQgYWwuIEEgMTItZ2VuZSBwaGFybWFjb2dlbmV0aWMgcGFuZWwgdG8gcHJldmVudCBhZHZlcnNlIGRydWcgcmVhY3Rpb25zOiBhbiBvcGVuLWxhYmVsLCBtdWx0aWNlbnRyZSwgY29udHJvbGxlZCwgY2x1c3Rlci1yYW5kb21pc2VkIGNyb3Nzb3ZlciBpbXBsZW1lbnRhdGlvbiBzdHVkeS4gVGhlIExhbmNldCAyMDIzOyA0MDE6IDM0N+KAkzU2Lg0KDQo4CVdoaXJsLUNhcnJpbGxvIE0sIEh1ZGRhcnQgUiwgR29uZyBMLCBldCBhbC4gQW4gRXZpZGVuY2UtQmFzZWQgRnJhbWV3b3JrIGZvciBFdmFsdWF0aW5nIFBoYXJtYWNvZ2Vub21pY3MgS25vd2xlZGdlIGZvciBQZXJzb25hbGl6ZWQgTWVkaWNpbmUuIENsaW5pY2FsIFBoYXJtYWNvbG9neSAmIFRoZXJhcGV1dGljcyAyMDIxOyAxMTA6IDU2M+KAkzcyLg0KDQo5CUJldW5rIEwsIE5pamVuaHVpcyBNLCBTb3JlZSBCLCBldCBhbC4gRHV0Y2ggUGhhcm1hY29nZW5ldGljcyBXb3JraW5nIEdyb3VwIChEUFdHKSBndWlkZWxpbmUgZm9yIHRoZSBnZW5lLWRydWcgaW50ZXJhY3Rpb24gYmV0d2VlbiBDWVAyRDYsIENZUDNBNCBhbmQgQ1lQMUEyIGFuZCBhbnRpcHN5Y2hvdGljcy4gRXVyIEogSHVtIEdlbmV0IDIwMjQ7IDMyOiAyNzjigJM4NS4NCg0KMTAJUGFyZGnDsWFzIEFGLCBPd2VuIE1KLCBXYWx0ZXJzIEpUUi4gUGhhcm1hY29nZW5vbWljczogQSByb2FkIGFoZWFkIGZvciBwcmVjaXNpb24gbWVkaWNpbmUgaW4gcHN5Y2hpYXRyeS4gTmV1cm9uIDIwMjE7IDEwOTogMzkxNOKAkzI5Lg0KDQoxMQlMZXNjaGUgRCwgTW9zdGFmYSBTLCBFdmVyYWxsIEksIFBhbnRlbGlzIEMsIEJvdXNtYW4gQ0EuIEltcGFjdCBvZiBDWVAxQTIsIENZUDJDMTksIGFuZCBDWVAyRDYgZ2Vub3R5cGUtIGFuZCBwaGVub2NvbnZlcnNpb24tcHJlZGljdGVkIGVuenltZSBhY3Rpdml0eSBvbiBjbG96YXBpbmUgZXhwb3N1cmUgYW5kIHN5bXB0b20gc2V2ZXJpdHkuIFRoZSBQaGFybWFjb2dlbm9taWNzIEpvdXJuYWwgMjAyMDsgMjA6IDE5MuKAkzIwMS4NCg0KMTIJT2todWlqc2VuLVBmZWlmZXIgQywgdmFuIGRlciBIb3JzdCBNWiwgQm91c21hbiBDQSwgZXQgYWwuIEdlbm9tZS13aWRlIGFzc29jaWF0aW9uIGFuYWx5c2VzIG9mIHN5bXB0b20gc2V2ZXJpdHkgYW1vbmcgY2xvemFwaW5lLXRyZWF0ZWQgcGF0aWVudHMgd2l0aCBzY2hpem9waHJlbmlhIHNwZWN0cnVtIGRpc29yZGVycy4gVHJhbnNsIFBzeWNoaWF0cnkgMjAyMjsgMTI6IDE0NS4NCg0KMTMJTGV1Y2h0IFMsIENoYWltYW5pIEEsIEtyYXVzZSBNLCBldCBhbC4gVGhlIHJlc3BvbnNlIG9mIHN1Ymdyb3VwcyBvZiBwYXRpZW50cyB3aXRoIHNjaGl6b3BocmVuaWEgdG8gZGlmZmVyZW50IGFudGlwc3ljaG90aWMgZHJ1Z3M6IGEgc3lzdGVtYXRpYyByZXZpZXcgYW5kIG1ldGEtYW5hbHlzaXMuIFRoZSBMYW5jZXQgUHN5Y2hpYXRyeSAyMDIyOyA5OiA4ODTigJM5My4NCg0KMTQJQm91c21hbiBDQSwgTWFydWYgQUEsIE1hcnF1ZXMgREYsIEJyb3duIExDLCBNw7xsbGVyIERKLiBUaGUgZW1lcmdlbmNlLCBpbXBsZW1lbnRhdGlvbiwgYW5kIGZ1dHVyZSBncm93dGggb2YgcGhhcm1hY29nZW5vbWljcyBpbiBwc3ljaGlhdHJ5OiBhIG5hcnJhdGl2ZSByZXZpZXcuIFBzeWNob2wgTWVkIDIwMjM7IDUzOiA3OTgz4oCTOTMuDQoNCjE1CVdpbmcgSkssIEJhYm9yIFQsIEJydWdoYSBULCBldCBhbC4gU0NBTjogU2NoZWR1bGVzIGZvciBDbGluaWNhbCBBc3Nlc3NtZW50IGluIE5ldXJvcHN5Y2hpYXRyeS4gQXJjaGl2ZXMgb2YgR2VuZXJhbCBQc3ljaGlhdHJ5IDE5OTA7IDQ3OiA1ODnigJM5My4NCg0KMTYJQW1lcmljYW4gUHN5Y2hpYXRyaWMgQXNzb2NpYXRpb24uIERpYWdub3N0aWMgYW5kIFN0YXRpc3RpY2FsIE1hbnVhbCBvZiBNZW50YWwgRGlzb3JkZXJzOiBEU00tSVYuLCA0dGggZWRuLiBBbWVyaWNhbiBQc3ljaGlhdHJpYyBBc3NvY2lhdGlvbi4sIDE5OTQuDQoNCjE3CVdvcmxkIEhlYWx0aCBPcmdhbml6YXRpb24uIFRoZSBJQ0QtMTAgY2xhc3NpZmljYXRpb24gb2YgbWVudGFsIGFuZCBiZWhhdmlvdXJhbCBkaXNvcmRlcnM6IGNsaW5pY2FsIGRlc2NyaXB0aW9ucyBhbmQgZGlhZ25vc3RpYyBndWlkZWxpbmVzLiBXb3JsZCBIZWFsdGggT3JnYW5pemF0aW9uLCAxOTkyLg0KDQoxOAlBbmRyZWFzZW4gTkMuIFNjYWxlIGZvciB0aGUgQXNzZXNzbWVudCBvZiBQb3NpdGl2ZSBTeW1wdG9tcy4gMTk4Ni4NCg0KMTkJQW5kcmVhc2VuIE5DLiBUaGUgU2NhbGUgZm9yIHRoZSBBc3Nlc3NtZW50IG9mIE5lZ2F0aXZlIFN5bXB0b21zIChTQU5TKTogY29uY2VwdHVhbCBhbmQgdGhlb3JldGljYWwgZm91bmRhdGlvbnMuIFRoZSBCcml0aXNoIGpvdXJuYWwgb2YgcHN5Y2hpYXRyeSAxOTg5OyAxNTU6IDQ54oCTNTIuDQoNCjIwCUFkZGluZ3RvbiBELCBBZGRpbmd0b24gSiwgTWF0aWNrYS1UeW5kYWxlIEUuIEFzc2Vzc2luZyBEZXByZXNzaW9uIGluIFNjaGl6b3BocmVuaWE6IFRoZSBDYWxnYXJ5IERlcHJlc3Npb24gU2NhbGUuIFRoZSBCcml0aXNoIEpvdXJuYWwgb2YgUHN5Y2hpYXRyeSAxOTkzOyAxNjM6IDM54oCTNDQuDQoNCjIxCU51ZWNodGVybGVpbiBLSCwgR3JlZW4gTUYsIEtlcm4gUlMsIGV0IGFsLiBUaGUgTUFUUklDUyBDb25zZW5zdXMgQ29nbml0aXZlIEJhdHRlcnksIFBhcnQgMTogVGVzdCBTZWxlY3Rpb24sIFJlbGlhYmlsaXR5LCBhbmQgVmFsaWRpdHkuIEFKUCAyMDA4OyAxNjU6IDIwM+KAkzEzLg0KDQoyMglUaG9tcHNvbiBLLCBLdWxrYXJuaSBKLCBTZXJnZWpldyBBQS4gUmVsaWFiaWxpdHkgYW5kIHZhbGlkaXR5IG9mIGEgbmV3IE1lZGljYXRpb24gQWRoZXJlbmNlIFJhdGluZyBTY2FsZSAoTUFSUykgZm9yIHRoZSBwc3ljaG9zZXMuIFNjaGl6b3BocmVuaWEgUmVzZWFyY2ggMjAwMDsgNDI6IDI0MeKAkzcuDQoNCjIzCUJyb3duIEUsIFNoYWggUCwgS2ltIEouIENobG9ycHJvbWF6aW5lUjogQ29udmVydCBBbnRpcHN5Y2hvdGljIERvc2VzIHRvIENobG9ycHJvbWF6aW5lIEVxdWl2YWxlbnRzLiAyMDIxLiBodHRwczovL2dpdGh1Yi5jb20vcm9wZW5zY2kvY2hsb3Jwcm9tYXppbmVSLg0KDQoyNAlHYXJkbmVyIEQsIE11cnBoeSBBLCBP4oCZRG9ubmVsbCBILCBDZW50b3JyaW5vIEYsIEJhbGRlc3NhcmluaSBSLiBJbnRlcm5hdGlvbmFsIENvbnNlbnN1cyBTdHVkeSBvZiBBbnRpcHN5Y2hvdGljIERvc2luZy4gQW1lcmljYW4gSm91cm5hbCBvZiBQc3ljaGlhdHJ5IDIwMTA7IDE2NzogNjg24oCTOTMuDQoNCjI1CUxldWNodCBTLCBTYW1hcmEgTSwgSGVyZXMgUywgRGF2aXMgSk0uIERvc2UgRXF1aXZhbGVudHMgZm9yIEFudGlwc3ljaG90aWMgRHJ1Z3M6IFRoZSBEREQgTWV0aG9kLiBTY2hpem9waHJlbmlhIEJ1bGxldGluIDIwMTY7IDQyOiBTOTDigJM0Lg0KDQoyNglFbmRpY290dCBKLCBTcGl0emVyIFJMLCBGbGVpc3MgSkwsIENvaGVuIEouIFRoZSBHbG9iYWwgQXNzZXNzbWVudCBTY2FsZTogQSBwcm9jZWR1cmUgZm9yIG1lYXN1cmluZyBvdmVyYWxsIHNldmVyaXR5IG9mIHBzeWNoaWF0cmljIGRpc3R1cmJhbmNlLiBBcmNoaXZlcyBvZiBnZW5lcmFsIHBzeWNoaWF0cnkgMTk3NjsgMzM6IDc2NuKAkzcxLg0KDQoyNwlQYXJkacOxYXMgQUYsIEhvbG1hbnMgUCwgUG9ja2xpbmd0b24gQUosIGV0IGFsLiBDb21tb24gc2NoaXpvcGhyZW5pYSBhbGxlbGVzIGFyZSBlbnJpY2hlZCBpbiBtdXRhdGlvbi1pbnRvbGVyYW50IGdlbmVzIGFuZCBpbiByZWdpb25zIHVuZGVyIHN0cm9uZyBiYWNrZ3JvdW5kIHNlbGVjdGlvbi4gTmF0dXJlIEdlbmV0aWNzIDIwMTg7IDUwOiAzODHigJM5Lg0KDQoyOAlMeW5oYW0gQUosIEtub3R0IFMsIFVuZGVyd29vZCBKRkcsIGV0IGFsLiBEUkFHT04tRGF0YTogYSBwbGF0Zm9ybSBhbmQgcHJvdG9jb2wgZm9yIGludGVncmF0aW5nIGdlbm9taWMgYW5kIHBoZW5vdHlwaWMgZGF0YSBhY3Jvc3MgbGFyZ2UgcHN5Y2hpYXRyaWMgY29ob3J0cy4gQkpQc3ljaCBPcGVuIDIwMjM7IDk6IDHigJM4Lg0KDQoyOQlMZWUgUywgU2hpbiBKLVksIEt3b24gTi1KLCBLaW0gQywgU2VvIEotUy4gQ2xpblBoYXJtU2VxOiBBIHRhcmdldGVkIHNlcXVlbmNpbmcgcGFuZWwgZm9yIGNsaW5pY2FsIHBoYXJtYWNvZ2VuZXRpY3MgaW1wbGVtZW50YXRpb24uIFBMT1MgT05FIDIwMjI7IDE3OiAx4oCTMTkuDQoNCjMwCVZhbiBSb3NzdW0gRywgRHJha2UgRkwuIFB5dGhvbiAzIFJlZmVyZW5jZSBNYW51YWwuIDIwMDkuDQoNCjMxCVRydWJldHNrb3kgViwgUGFyZGnDsWFzIEFGLCBRaSBULCBldCBhbC4gTWFwcGluZyBnZW5vbWljIGxvY2kgaW1wbGljYXRlcyBnZW5lcyBhbmQgc3luYXB0aWMgYmlvbG9neSBpbiBzY2hpem9waHJlbmlhLiBOYXR1cmUgMjAyMjsgNjA0OiA1MDLigJM4Lg0KDQozMglTYXZhZ2UgSkUsIEphbnNlbiBQUiwgU3RyaW5nZXIgUywgZXQgYWwuIEdlbm9tZS13aWRlIGFzc29jaWF0aW9uIG1ldGEtYW5hbHlzaXMgaW4gMjY5LDg2NyBpbmRpdmlkdWFscyBpZGVudGlmaWVzIG5ldyBnZW5ldGljIGFuZCBmdW5jdGlvbmFsIGxpbmtzIHRvIGludGVsbGlnZW5jZS4gTmF0IEdlbmV0IDIwMTg7IDUwOiA5MTLigJM5Lg0KDQozMwlPa2JheSBBLCBXdSBZLCBXYW5nIE4sIGV0IGFsLiBQb2x5Z2VuaWMgcHJlZGljdGlvbiBvZiBlZHVjYXRpb25hbCBhdHRhaW5tZW50IHdpdGhpbiBhbmQgYmV0d2VlbiBmYW1pbGllcyBmcm9tIGdlbm9tZS13aWRlIGFzc29jaWF0aW9uIGFuYWx5c2VzIGluIDMgbWlsbGlvbiBpbmRpdmlkdWFscy4gTmF0IEdlbmV0IDIwMjI7IDU0OiA0MzfigJM0OS4NCg0KMzQJR2UgVCwgQ2hlbiBDLVksIE5pIFksIEZlbmcgWS1DQSwgU21vbGxlciBKVy4gUG9seWdlbmljIHByZWRpY3Rpb24gdmlhIEJheWVzaWFuIHJlZ3Jlc3Npb24gYW5kIGNvbnRpbnVvdXMgc2hyaW5rYWdlIHByaW9ycy4gTmF0IENvbW11biAyMDE5OyAxMDogMTc3Ni4NCg0KMzUJQ2hhbmcgQ0MsIENob3cgQ0MsIFRlbGxpZXIgTENBTSwgVmF0dGlrdXRpIFMsIFB1cmNlbGwgU00sIExlZSBKSi4gU2Vjb25kLWdlbmVyYXRpb24gUExJTks6IHJpc2luZyB0byB0aGUgY2hhbGxlbmdlIG9mIGxhcmdlciBhbmQgcmljaGVyIGRhdGFzZXRzLiBHaWdhU2NpZW5jZSAyMDE1OyA0OiA3Lg0KDQozNglUaGUgMTAwMCBHZW5vbWVzIFByb2plY3QgQ29uc29ydGl1bSwgQXV0b24gQSwgQWJlY2FzaXMgR1IsIGV0IGFsLiBBIGdsb2JhbCByZWZlcmVuY2UgZm9yIGh1bWFuIGdlbmV0aWMgdmFyaWF0aW9uLiBOYXR1cmUgMjAxNTsgNTI2OiA2OOKAkzc0Lg0KDQozNwlSIENvcmUgVGVhbS4gUjogQSBMYW5ndWFnZSBhbmQgRW52aXJvbm1lbnQgZm9yIFN0YXRpc3RpY2FsIENvbXB1dGluZy4gMjAyMS4gaHR0cHM6Ly93d3cuUi1wcm9qZWN0Lm9yZy8uDQoNCjM4CUZhbm91cyBBSCwgWmhvdSBCLCBBZ2dlbiBTSCwgZXQgYWwuIEdlbm9tZS1XaWRlIEFzc29jaWF0aW9uIFN0dWR5IG9mIENsaW5pY2FsIERpbWVuc2lvbnMgb2YgU2NoaXpvcGhyZW5pYTogUG9seWdlbmljIEVmZmVjdCBvbiBEaXNvcmdhbml6ZWQgU3ltcHRvbXMuIEFKUCAyMDEyOyAxNjk6IDEzMDnigJMxNy4NCg0KMzkJUXVhdHRyb25lIEQsIEZvcnRpIE1ELCBHYXllci1BbmRlcnNvbiBDLCBldCBhbC4gVHJhbnNkaWFnbm9zdGljIGRpbWVuc2lvbnMgb2YgcHN5Y2hvcGF0aG9sb2d5IGF0IGZpcnN0IGVwaXNvZGUgcHN5Y2hvc2lzOiBmaW5kaW5ncyBmcm9tIHRoZSBtdWx0aW5hdGlvbmFsIEVVLUdFSSBzdHVkeS4gUHN5Y2hvbG9naWNhbCBNZWRpY2luZSAyMDE5OyA0OTogMTM3OOKAkzkxLg0KDQo0MAlSb3NzZWVsIFkuIGxhdmFhbjogQW4gUiBQYWNrYWdlIGZvciBTdHJ1Y3R1cmFsIEVxdWF0aW9uIE1vZGVsaW5nLiBKb3VybmFsIG9mIFN0YXRpc3RpY2FsIFNvZnR3YXJlIDIwMTI7IDQ4OiAx4oCTMzYuDQoNCjQxCUFsbGVncmluaSBBRywgU2VsemFtIFMsIFJpbWZlbGQgSywgdm9uIFN0dW1tIFMsIFBpbmdhdWx0IEpCLCBQbG9taW4gUi4gR2Vub21pYyBwcmVkaWN0aW9uIG9mIGNvZ25pdGl2ZSB0cmFpdHMgaW4gY2hpbGRob29kIGFuZCBhZG9sZXNjZW5jZS4gTW9sIFBzeWNoaWF0cnkgMjAxOTsgMjQ6IDgxOeKAkzI3Lg0KDQo0Mgl2b24gU3R1bW0gUywgUGxvbWluIFIuIFVzaW5nIEROQSB0byBwcmVkaWN0IGludGVsbGlnZW5jZS4gSW50ZWxsaWdlbmNlIDIwMjE7IDg2OiAxMDE1MzAuDQoNCjQzCU5lbHNvbiBIRS4gVEhFIE5BVElPTkFMIEFEVUxUIFJFQURJTkcgVEVTVCAoTkFSVCkuIE5GRVItTkVMU09OLCAxOTkxLg0KDQo0NAlNb3N0YWZhIFMsIFBvbGFzZWsgVE0sIEJvdXNtYW4gQ0EsIGV0IGFsLiBQaGFybWFjb2dlbm9taWNzIGluIFBzeWNoaWF0cnkg4oCTIHRoZSBDaGFsbGVuZ2Ugb2YgQ3l0b2Nocm9tZSBQNDUwIEVuenltZSBQaGVub2NvbnZlcnNpb24gYW5kIFNvbHV0aW9ucyB0byBBc3Npc3QgUHJlY2lzaW9uIERvc2luZy4gUGhhcm1hY29nZW5vbWljcyAyMDIyOyAyMzogODU34oCTNjcuDQoNCjQ1CUxpdHRsZSBKLCBIaWdnaW5zIEpQVCwgSW9hbm5pZGlzIEpQQSwgZXQgYWwuIFN0cmVuZ3RoZW5pbmcgdGhlIHJlcG9ydGluZyBvZiBnZW5ldGljIGFzc29jaWF0aW9uIHN0dWRpZXMgKFNUUkVHQSk6IGFuIGV4dGVuc2lvbiBvZiB0aGUgU1RST0JFIFN0YXRlbWVudC4gSHVtIEdlbmV0IDIwMDk7IDEyNTogMTMx4oCTNTEuDQoNCjQ2CXZvbiBFbG0gRSwgQWx0bWFuIERHLCBFZ2dlciBNLCBldCBhbC4gVGhlIFN0cmVuZ3RoZW5pbmcgdGhlIFJlcG9ydGluZyBvZiBPYnNlcnZhdGlvbmFsIFN0dWRpZXMgaW4gRXBpZGVtaW9sb2d5IChTVFJPQkUpIHN0YXRlbWVudDogZ3VpZGVsaW5lcyBmb3IgcmVwb3J0aW5nIG9ic2VydmF0aW9uYWwgc3R1ZGllcy4gQW5uIEludGVybiBNZWQgMjAwNzsgMTQ3OiA1NzPigJM3Lg0KDQo0NwlTaXNraW5kIEQsIE1jQ2FydG5leSBMLCBHb2xkc2NobGFnZXIgUiwgS2lzZWx5IFMuIENsb3phcGluZSB2LiBmaXJzdC0gYW5kIHNlY29uZC1nZW5lcmF0aW9uIGFudGlwc3ljaG90aWNzIGluIHRyZWF0bWVudC1yZWZyYWN0b3J5IHNjaGl6b3BocmVuaWE6IHN5c3RlbWF0aWMgcmV2aWV3IGFuZCBtZXRhLWFuYWx5c2lzLiBUaGUgQnJpdGlzaCBKb3VybmFsIG9mIFBzeWNoaWF0cnkgMjAxNjsgMjA5OiAzODXigJM5Mi4NCg0KNDgJSG9yaSBILCBOb2d1Y2hpIEgsIEhhc2hpbW90byBSLCBldCBhbC4gQW50aXBzeWNob3RpYyBtZWRpY2F0aW9uIGFuZCBjb2duaXRpdmUgZnVuY3Rpb24gaW4gc2NoaXpvcGhyZW5pYS4gU2NoaXpvcGhyZW5pYSBSZXNlYXJjaCAyMDA2OyA4NjogMTM44oCTNDYuDQoNCjQ5CUJhbGxlc3Rlcm9zIEEsIFPDoW5jaGV6LVRvcnJlcyBBTSwgTMOzcGV6LUlsdW5kYWluIEpNLCBldCBhbC4gSXMgY29nbml0aXZlIGltcGFpcm1lbnQgYXNzb2NpYXRlZCB3aXRoIGFudGlwc3ljaG90aWMgZG9zZSBhbmQgYW50aWNob2xpbmVyZ2ljIGVxdWl2YWxlbnQgbG9hZHMgaW4gZmlyc3QtZXBpc29kZSBwc3ljaG9zaXM/IFBzeWNob2xvZ2ljYWwgTWVkaWNpbmUgMjAxODsgNDg6IDIyNDfigJM1Ni4NCg0KNTAJQmFsZGV6IERQLCBCaWF6dXMgVEIsIFJhYmVsby1kYS1Qb250ZSBGRCwgZXQgYWwuIFRoZSBlZmZlY3Qgb2YgYW50aXBzeWNob3RpY3Mgb24gdGhlIGNvZ25pdGl2ZSBwZXJmb3JtYW5jZSBvZiBpbmRpdmlkdWFscyB3aXRoIHBzeWNob3RpYyBkaXNvcmRlcnM6IE5ldHdvcmsgbWV0YS1hbmFseXNlcyBvZiByYW5kb21pemVkIGNvbnRyb2xsZWQgdHJpYWxzLiBOZXVyb3NjaWVuY2UgJiBCaW9iZWhhdmlvcmFsIFJldmlld3MgMjAyMTsgMTI2OiAyNjXigJM3NS4NCg0KNTEJTHUgQywgSmluIFgsIExpdSBOLCBldCBhbC4gVGhlIHJlbGF0aW9uc2hpcCBvZiBjYXJkaW92YXNjdWxhciBkaXNlYXNlIHJpc2ssIGNsb3phcGluZSBhbnRpcHN5Y2hvdGljIHVzZSBhbmQgY29nbml0aXZlIGZ1bmN0aW9uIGluIGEgbGFyZ2UgQ2hpbmVzZSBzY2hpem9waHJlbmlhIGNvaG9ydC4gQnJhaW4gUmVzZWFyY2ggMjAyNDsgMTg0NTogMTQ5MjIwLg0KDQo1MglIYWRkYWQgQywgU2FsYW1laCBQLCBTYWNyZSBILCBDbMOpbWVudCBKLVAsIENhbHZldCBCLiBFZmZlY3RzIG9mIGFudGlwc3ljaG90aWMgYW5kIGFudGljaG9saW5lcmdpYyBtZWRpY2F0aW9ucyBvbiBjb2duaXRpb24gaW4gY2hyb25pYyBwYXRpZW50cyB3aXRoIHNjaGl6b3BocmVuaWEuIEJNQyBQc3ljaGlhdHJ5IDIwMjM7IDIzLg0KDQo1MwlGZWJlciBMLCBQZXRlciBOTCwgQ2hpb2NjaGlhIFYsIGV0IGFsLiBBbnRpcHN5Y2hvdGljIERydWdzIGFuZCBDb2duaXRpdmUgRnVuY3Rpb246IEEgU3lzdGVtYXRpYyBSZXZpZXcgYW5kIFBhaXJ3aXNlIE5ldHdvcmsgTWV0YS1BbmFseXNpcy4gSkFNQSBQc3ljaGlhdHJ5IDIwMjQ7IHB1Ymxpc2hlZCBvbmxpbmUgT2N0IDE2LiBET0k6MTAuMTAwMS9qYW1hcHN5Y2hpYXRyeS4yMDI0LjI4OTAuDQoNCjU0CUlhc2V2b2xpIEYsIEF2YWdsaWFubyBDLCBBbHRhdmlsbGEgQiwgZXQgYWwuIERpc2Vhc2UgU2V2ZXJpdHkgaW4gVHJlYXRtZW50IFJlc2lzdGFudCBTY2hpem9waHJlbmlhIFBhdGllbnRzIElzIE1haW5seSBBZmZlY3RlZCBieSBOZWdhdGl2ZSBTeW1wdG9tcywgV2hpY2ggTWVkaWF0ZSB0aGUgRWZmZWN0cyBvZiBDb2duaXRpdmUgRHlzZnVuY3Rpb25zIGFuZCBOZXVyb2xvZ2ljYWwgU29mdCBTaWducy4gRnJvbnQgUHN5Y2hpYXRyeSAyMDE4OyA5Lg0KDQo1NQlMZWdnZSBTRSwgRGVubmlzb24gQ0EsIFBhcmRpw7FhcyBBRiwgZXQgYWwuIENsaW5pY2FsIGluZGljYXRvcnMgb2YgdHJlYXRtZW50LXJlc2lzdGFudCBwc3ljaG9zaXMuIFRoZSBCcml0aXNoIEpvdXJuYWwgb2YgUHN5Y2hpYXRyeSAyMDIwOyAyMTY6IDI1OeKAkzY2Lg0KDQo1NglTdW4gSiwgWWVlIEpZLCBTZWUgWU0sIGV0IGFsLiBBc3NvY2lhdGlvbiBiZXR3ZWVuIHRyZWF0bWVudCByZXNpc3RhbmNlIGFuZCBjb2duaXRpdmUgZnVuY3Rpb24gaW4gc2NoaXpvcGhyZW5pYS4gU2luZ2Fwb3JlIE1lZGljYWwgSm91cm5hbCAyMDI0OyA2NTogNTUyLg0KDQo1NwlCZXJ0aWxzc29uIEwsIENhcnJpbGxvIEosIERhaGwgTSwgZXQgYWwuIENsb3phcGluZSBkaXNwb3NpdGlvbiBjb3ZhcmllcyB3aXRoIENZUDFBMiBhY3Rpdml0eSBkZXRlcm1pbmVkIGJ5IGEgY2FmZmVpbmUgdGVzdC4gQnJpdGlzaCBKb3VybmFsIG9mIENsaW5pY2FsIFBoYXJtYWNvbG9neSAxOTk0OyAzODogNDcx4oCTMy4NCg0KNTgJRWllcm1hbm4gQiwgRW5nZWwgRywgSm9oYW5zc29uIEksIFphbmdlciBVTSwgQmVydGlsc3NvbiBMLiBUaGUgaW52b2x2ZW1lbnQgb2YgQ1lQMUEyIGFuZCBDWVAzQTQgaW4gdGhlIG1ldGFib2xpc20gb2YgY2xvemFwaW5lLiBCcml0aXNoIEpvdXJuYWwgb2YgQ2xpbmljYWwgUGhhcm1hY29sb2d5IDE5OTc7IDQ0OiA0MznigJM0Ni4NCg0KNTkJRmxhbmFnYW4gUkosIEdlZSBTLCBCZWxzZXkgUywgQ291Y2htYW4gTCwgTGFsbHkgSi4gVGhlcmFwZXV0aWMgbW9uaXRvcmluZyBvZiBwbGFzbWEgY2xvemFwaW5lIGFuZCBOLWRlc21ldGh5bGNsb3phcGluZSAobm9yY2xvemFwaW5lKTogcHJhY3RpY2FsIGNvbnNpZGVyYXRpb25zLiBCSlBzeWNoIEFkdmFuY2VzIDIwMjM7IDI5OiA5MuKAkzEwMi4NCg0KNjAJU2lhZmlzIFMsIFd1IEgsIFdhbmcgRCwgZXQgYWwuIEFudGlwc3ljaG90aWMgZG9zZSwgZG9wYW1pbmUgRDIgcmVjZXB0b3Igb2NjdXBhbmN5IGFuZCBleHRyYXB5cmFtaWRhbCBzaWRlLWVmZmVjdHM6IGEgc3lzdGVtYXRpYyByZXZpZXcgYW5kIGRvc2UtcmVzcG9uc2UgbWV0YS1hbmFseXNpcy4gTW9sIFBzeWNoaWF0cnkgMjAyMzsgMjg6IDMyNjfigJM3Ny4NCg0KNjEJWW9zaGlkYSBLLCBUYWtldWNoaSBILiBEb3NlLWRlcGVuZGVudCBlZmZlY3RzIG9mIGFudGlwc3ljaG90aWNzIG9uIGVmZmljYWN5IGFuZCBhZHZlcnNlIGVmZmVjdHMgaW4gc2NoaXpvcGhyZW5pYS4gQmVoYXZpb3VyYWwgQnJhaW4gUmVzZWFyY2ggMjAyMTsgNDAyOiAxMTMwOTguDQoNCjYyCU9naW5vIFMsIE1peWFtb3RvIFMsIE1peWFrZSBOLCBZYW1hZ3VjaGkgTi4gQmVuZWZpdHMgYW5kIGxpbWl0cyBvZiBhbnRpY2hvbGluZXJnaWMgdXNlIGluIHNjaGl6b3BocmVuaWE6IEZvY3VzaW5nIG9uIGl0cyBlZmZlY3Qgb24gY29nbml0aXZlIGZ1bmN0aW9uLiBQc3ljaGlhdHJ5IGFuZCBDbGluaWNhbCBOZXVyb3NjaWVuY2VzIDIwMTQ7IDY4OiAzN+KAkzQ5Lg0KDQo2MwlDaGF0dGVyamVlIEssIERhbmdpIEEsIFNoYXJtYSBSLCBZYWRhdiBQLCBDaGF1aGFuIFZTLCBQcmFrYXNoIEouIEFkZGluZyBwcmUtZW1wdGl2ZSBhbnRpY2hvbGluZXJnaWNzIHRvIGFudGlwc3ljaG90aWNzOiBJcyBpdCBqdXN0aWZpZWQ/IEluZCBQc3ljaGlhdHJ5IEogMjAyMjsgMzE6IDM3MOKAkzMuDQoNCjY0CUhvcmkgSCwgWWFzdWktRnVydWtvcmkgTiwgSGFzZWdhd2EgTiwgZXQgYWwuIFByZXNjcmlwdGlvbiBvZiBBbnRpY2hvbGluZXJnaWMgRHJ1Z3MgaW4gUGF0aWVudHMgV2l0aCBTY2hpem9waHJlbmlhOiBBbmFseXNpcyBvZiBBbnRpcHN5Y2hvdGljIFByZXNjcmlwdGlvbiBQYXR0ZXJucyBhbmQgSG9zcGl0YWwgQ2hhcmFjdGVyaXN0aWNzLiBGcm9udCBQc3ljaGlhdHJ5IDIwMjI7IDEzLiBET0k6MTAuMzM4OS9mcHN5dC4yMDIyLjgyMzgyNi4NCg0KNjUJUm9kcmlndWVzLVNpbHZhIEMsIFNlbWVkbyBBVCwgTmVyaSBIRiBkYSBTLCBldCBhbC4gVGhlIENZUDJDMTkqMiBhbmQgQ1lQMkMxOSoxNyBQb2x5bW9ycGhpc21zIEluZmx1ZW5jZSBSZXNwb25zZXMgdG8gQ2xvemFwaW5lIGZvciB0aGUgVHJlYXRtZW50IG9mIFNjaGl6b3BocmVuaWEuIE5ldXJvcHN5Y2hpYXRyaWMgRGlzZWFzZSBhbmQgVHJlYXRtZW50IDIwMjA7IDE2OiA0MjfigJMzMi4NCg0KNjYJUGlhdGtvdiBJLCBDYWV0YW5vIEQsIEFzc3VyIFksIGV0IGFsLiBDWVAyQzE5KjE3IHByb3RlY3RzIGFnYWluc3QgbWV0YWJvbGljIGNvbXBsaWNhdGlvbnMgb2YgY2xvemFwaW5lIHRyZWF0bWVudC4gV29ybGQgSiBCaW9sIFBzeWNoaWF0cnkgMjAxNzsgMTg6IDUyMeKAkzcuDQoNCjY3CURlYW4gTCwgS2FuZSBNLiBNZWRpY2FsIEdlbmV0aWNzIFN1bW1hcmllcyBFeHBlcnQgUmV2aWV3ZXJzLiBOYXRpb25hbCBDZW50ZXIgZm9yIEJpb3RlY2hub2xvZ3kgSW5mb3JtYXRpb24gKFVTKSwgMjAyMSBodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L2Jvb2tzL05CSzQzNjkxNi8uDQoNCjY4CWRlIEJyYWJhbmRlciBFLCBLbGVpbmUgU2NoYWFycyBLLCB2YW4gQW1lbHN2b29ydCBULCBldCBhbC4gSW5mbHVlbmNlIG9mIENZUDJDMTkgYW5kIENZUDJENiBvbiBzaWRlIGVmZmVjdHMgb2YgYXJpcGlwcmF6b2xlIGFuZCByaXNwZXJpZG9uZTogQSBzeXN0ZW1hdGljIHJldmlldy4gSm91cm5hbCBvZiBQc3ljaGlhdHJpYyBSZXNlYXJjaCAyMDI0OyAxNzQ6IDEzN+KAkzUyLg0KDQo2OQlSYWdpYSBHLCBEYWhsIE0tTCwgTWFub2xvcG91bG9zIFZHLiBJbmZsdWVuY2Ugb2YgQ1lQM0E1IHBvbHltb3JwaGlzbSBvbiB0aGUgcGhhcm1hY29raW5ldGljcyBvZiBwc3ljaGlhdHJpYyBkcnVncy4gQ3VyciBEcnVnIE1ldGFiIDIwMTY7IDE3OiAyMjfigJMzNi4NCg0KNzAJQmFpbnMgUkssIEtvdmFjZXZpYyBNLCBQbGFzdGVyIENBLCBldCBhbC4gTW9sZWN1bGFyIGRpdmVyc2l0eSBhbmQgcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgYXQgdGhlIEN5dG9jaHJvbWUgUDQ1MCAzQTUgZ2VuZSBpbiBBZnJpY2EuIEJNQyBHZW5ldGljcyAyMDEzOyAxNDogMzQuDQoNCjcxCU1hc2ltaXJlbWJ3YSBDLCBEYW5kYXJhIEMsIEhhc2xlciBKLiBDaGFwdGVyIDQzIC0gUG9wdWxhdGlvbiBEaXZlcnNpdHkgYW5kIFBoYXJtYWNvZ2Vub21pY3MgaW4gQWZyaWNhLiBJbjogUGFkbWFuYWJoYW4gUywgZWQuIEhhbmRib29rIG9mIFBoYXJtYWNvZ2Vub21pY3MgYW5kIFN0cmF0aWZpZWQgTWVkaWNpbmUuIFNhbiBEaWVnbzogQWNhZGVtaWMgUHJlc3MsIDIwMTQ6IDk3MeKAkzk4Lg0KDQo3MglEb3JqaSBQVywgVHNoZXJpbmcgRywgTmEtQmFuZ2NoYW5nIEsuIENZUDJDOSwgQ1lQMkMxOSwgQ1lQMkQ2IGFuZCBDWVAzQTUgcG9seW1vcnBoaXNtcyBpbiBTb3V0aC1FYXN0IGFuZCBFYXN0IEFzaWFuIHBvcHVsYXRpb25zOiBBIHN5c3RlbWF0aWMgcmV2aWV3LiBKb3VybmFsIG9mIENsaW5pY2FsIFBoYXJtYWN5IGFuZCBUaGVyYXBldXRpY3MgMjAxOTsgNDQ6IDUwOOKAkzI0Lg0KDQo3MwlHb3BhbGtyaXNobmFuIE4uIEN1bHR1cmFsIERpdmVyc2l0eSBhbmQgTWVudGFsIEhlYWx0aDogQ29uc2lkZXJhdGlvbnMgZm9yIFBvbGljeSBhbmQgUHJhY3RpY2UuIEZyb250IFB1YmxpYyBIZWFsdGggMjAxODsgNi4gRE9JOjEwLjMzODkvZnB1YmguMjAxOC4wMDE3OS4NCg0KNzQJTWNDdXRjaGVvbiBSQSwgS2VlZmUgUlNFLCBNY0d1aXJlIFBLLiBDb2duaXRpdmUgaW1wYWlybWVudCBpbiBzY2hpem9waHJlbmlhOiBhZXRpb2xvZ3ksIHBhdGhvcGh5c2lvbG9neSwgYW5kIHRyZWF0bWVudC4gTW9sIFBzeWNoaWF0cnkgMjAyMzsgMjg6IDE5MDLigJMxOC4NCg0KNzUJU2hpbW9tdXJhIFksIEtpa3VjaGkgWSwgU3V6dWtpIFQsIFVjaGlkYSBILCBNaW11cmEgTSwgVGFrZXVjaGkgSC4gQW50aXBzeWNob3RpYyB0cmVhdG1lbnQgaW4gdGhlIG1haW50ZW5hbmNlIHBoYXNlIG9mIHNjaGl6b3BocmVuaWE6IEFuIHVwZGF0ZWQgc3lzdGVtYXRpYyByZXZpZXcgb2YgdGhlIGd1aWRlbGluZXMgYW5kIGFsZ29yaXRobXMuIFNjaGl6b3BocmVuaWEgUmVzZWFyY2ggMjAyMDsgMjE1OiA44oCTMTYuDQoNCjxicj4NCjxicj4NCjxicj4NCjxicj4NCg0KIyMgPHN0cm9uZz4gU3VwcGxlbWVudGFyeSBOb3RlcyAtIE1ldGhvZHMgPC9zdHJvbmc+IHsudGFic2V0fQ0KIyMjIEFkaGVyZW5jZSBRdWVzdGlvbm5haXJlIEl0ZW0NCiMjIyMgQWRoZXJlbmNlIFF1ZXN0aW9ubmFpcmUgSXRlbQ0KDQpBZGhlcmVuY2UgdG8gY3VycmVudCBtZWRpY2F0aW9uIHdhcyBtZWFzdXJlZCBvbiBhbiBvcmRpbmFsIHNjYWxlIGFzIGRlc2NyaWJlZCBiZWxvdy4gUGFydGljaXBhbnRzIHdlcmUgcmF0ZWQgYWNjb3JkaW5nIHRvIHRoZSBtb3N0IGFwcHJvcHJpYXRlIHN0YXRlbWVudDoNCg0KMCkJRG9lc24ndCB0YWtlIG1lZGljYXRpb24uDQoxKQlUYWtlcyBtZWRpY2F0aW9uIG9ubHkgcmFyZWx5ICgxLTIvd2VlaykuDQoyKQlNaXNzZXMgb3ZlciA1MCUgZG9zZXMuDQozKQlNaXNzZXMgZG9zZXMgZXZlcnkgd2Vlay4gDQo0KQlSYXJlbHkgbWlzc2VzIGRvc2VzLg0KNSkJTWVkaWNhdGlvbiBzdXBlcnZpc2VkIGFuZCB0YWtlcyBhcyBwcmVzY3JpYmVkLg0KDQpSZXNwb25zZXMgd2VyZSBkaWNob3RvbWlzZWQgZHVlIHRvIGxvdyBudW1iZXJzIG9mIHJhdGluZ3MgaW4gY2VydGFpbiBjYXRlZ29yaWVzLiBQYXJ0aWNpcGFudHMgd2hvIG1pc3NlZCBkb3NlcyBldmVyeSB3ZWVrLCBvciBtb3JlIGZyZXF1ZW50bHkgKDAtMykgd2VyZSBhc3NpZ25lZCBhcyBub24tYWRoZXJlbnQuIFRob3NlIHdobyByZXBvcnRlZCByYXJlbHkgbWlzc2VkIGRvc2VzLCBvciB3ZXJlIG1lZGljYXRpb24gc3VwZXJ2aXNlZCAoNC01KSB3ZXJlIGFzc2lnbmVkIGFzIGFkaGVyZW50Lg0KPGJyPg0KPGJyPg0KDQojIyMgUUMgb2YgR2VuZXRpYyBEYXRhDQojIyMjIFF1YWxpdHkgY29udHJvbCBvZiBHZW5ldGljIERhdGENCg0KUHJlLWltcHV0YXRpb24gcXVhbGl0eSBjb250cm9sIChRQykgd2FzIHBlcmZvcm1lZCBhcyBmb2xsb3dzOyBTTlBzIHdlcmUgZXhjbHVkZWQgZHVlIHRvIGNhbGwgcmF0ZXMgPCAwLjk1LCBNQUYgPCAwLjAxLCBvciBhIEhhcmR5LVdlaW5iZXJnIEVxdWlsaWJyaXVtIG1pZC1wIDwgMTBeLTZeLiBJbmRpdmlkdWFscyB3ZXJlIGV4Y2x1ZGVkIHdpdGggZ2Vub3R5cGluZyBjb3ZlcmFnZSByYXRlcyA8IDAuOTUgb3IgcG90ZW50aWFsIGVycm9ycyBpbiBhIFBMSU5LIOKAnHNleCBjaGVja+KAnSBhbmFseXNpcyAoaS5lLiwgYW1iaWd1b3VzIGdlbmV0aWMgc2V4LCBvciBtaXNtYXRjaCBiZXR3ZWVuIHNlbGYtcmVwb3J0ZWQgYW5kIGdlbmV0aWMgc2V4KS4gDQoNClRoZSBNaWNoaWdhbiBJbXB1dGF0aW9uIHNlcnZlcl4xXiBhbmQgTWluaW1hYy00IHdlcmUgdXRpbGlzZWQgZm9yIGltcHV0YXRpb24sIHVzaW5nIHRoZSBIYXBsb3R5cGUgUmVmZXJlbmNlIENvbnNvcnRpdW0gdjEuMSBhcyB0aGUgcmVmZXJlbmNlIHBhbmVsLiBQcmUtaW1wdXRhdGlvbiBzdGF0aXN0aWNhbCBwaGFzaW5nIHdhcyBjYXJyaWVkIG91dCBpbiB0aGUgTWljaGlnYW4gYnVpbHQtaW4gc2VydmljZSB1c2luZyBFYWdsZSAyLjReMl4uIFBvc3QgaW1wdXRhdGlvbiwgU05QcyB3ZXJlIHJlbW92ZWQgd2hlbiB0aGV5IGhhZCBhIGhhcmQtY2FsbCBnZW5vdHlwZSBwcm9iYWJpbGl0eSB0aHJlc2hvbGQgPCAwLjksIFIyIDwgMC45LCBNQUYgPCAwLjAxLCBhbmQgZ2Vub3R5cGluZyByYXRlcyA8IDAuOTUuIFJlbGF0ZWRuZXNzIHdhcyBhc3Nlc3NlZCB0aHJvdWdoIHRoZSBQQy1SZWxhdGUgYWxnb3JpdGhtXjNeIGFuZCBhIGN1dG9mZiBvZiDPgCA+IDAuNCB3YXMgdXNlZCB0byByZW1vdmUgcmVsYXRlZCBpbmRpdmlkdWFsc140Xi4gDQoNCkZvciBwaGFybWFjb2dlbm9taWMgYWxsZWxlIGNhbGxpbmcgd2UgcmV0YWluZWQgYW55IG1vbm9tb3JwaGljIHZhcmlhbnRzIGluIHRoZSBkYXRhc2V0IGFuZCB1c2VkIGEgbW9yZSByZWxheGVkIGltcHV0YXRpb24gcXVhbGl0eSB0aHJlc2hvbGQgKFIyIDwgMC43OyBIYXJkLWNhbGwgZ2Vub3R5cGUgcHJvYmFiaWxpdHkgPCAwLjgpLiBUaGlzIGFsbG93ZWQgdXMgdG8gcmV0YWluIGEgZ3JlYXRlciBudW1iZXIgb2YgcGhhcm1hY29nZW5vbWljIGluZm9ybWF0aXZlIFNOUHMgdG8gaW5jcmVhc2UgdGhlIGFsbGVsZSBjYWxsaW5nIGFjY3VyYWN5LCB3aGlsZSBzdGlsbCBiZWluZyBzdHJpbmdlbnQgZW5vdWdoIHRvIGF2b2lkIGltcHV0YXRpb24gZXJyb3JzIGluIGNvbW1vbiBnZW5ldGljIHZhcmlhbnRzXjUsNl4NCg0KPGJyPg0KPGJyPg0KDQojIyMgUGhhcm1hY29nZW5vbWljIEFjdGl2aXR5IFNjb3JlIE1hcHBpbmcNCiMjIyMgUGhhcm1hY29nZW5vbWljIEFjdGl2aXR5IFNjb3JlIE1hcHBpbmcNClB5UEd4IHYwLjIwLjBeN14gcHJlZGljdHMgZW56eW1lIG1ldGFib2xpc20gcGhlbm90eXBlcyBpbiB0d28gd2F5cywgdGhyb3VnaCBhY3Rpdml0eSBzY29yZXMgb3IgZGlwbG90eXBlLXBoZW5vdHlwZSBtYXBwaW5nLiBEZXNwaXRlIHRoaXMsIGl0IGRvZXMgbm90IGV4cGxpY2l0bHkgcmVwb3J0IGFjdGl2aXR5IHNjb3JlcyBpbiBpdHMgb3V0cHV0LiBXaGVyZSBhdmFpbGFibGUsIGFjdGl2aXR5IHNjb3JlcyB3ZXJlIG1hcHBlZCB0byBwaGFybWFjb2dlbm9taWMgYWxsZWxlcyBjYWxsZWQgdXNpbmcgdGhlIGFsbGVsZSB0YWJsZSB3aXRoaW4gdGhlIFB5UEd4IHBhY2thZ2UuIFRoaXMgd2FzIGZlYXNpYmxlIGZvciBDWVAyRDYgYW5kIENZUDJDOS4gRm9yIHRoZSByZW1haW5pbmcgZW56eW1lcywgdGhlIG1hcHBpbmcgb2YgcGhhcm1hY29nZW5vbWljIGFsbGVsZXMgdG8gYWN0aXZpdHkgc2NvcmVzIHdhcyBiYXNlZCBvbiBleGlzdGluZyBsaXRlcmF0dXJlIG9yIGluZmVycmVkIGZyb20gUGhhcm1HS0IgQWxsZWxlIEZ1bmN0aW9uYWxpdHkgUmVmZXJlbmNlIFRhYmxlcyAoc2VlICoqU3VwcGxlbWVudGFyeSBUYWJsZSAxKiopLiANCg0KRm9yIENZUDFBMiwgUGhhcm1HS0IgZG9lcyBub3QgeWV0IHByb3ZpZGUgYW4gYWxsZWxlIGZ1bmN0aW9uYWxpdHkgdGFibGUuIFRodXMsIGFjdGl2aXR5IHNjb3JlIGFzc2lnbm1lbnQgd2FzIGJhc2VkIG9uIGNvbnNlbnN1cyB2YWx1ZXMgZnJvbSB0aGUgbGl0ZXJhdHVyZV44LDleLiBObyBndWlkYW5jZSB3YXMgYXZhaWxhYmxlIGZvciBcKjFLLCB0aGVyZWZvcmUgaXQgd2FzIGFzc2lnbmVkIHRoZSBzYW1lIGFjdGl2aXR5IHNjb3JlIGFzIFwqMUMsIGFsc28gYSBkZWNyZWFzZWQgZnVuY3Rpb24gYWxsZWxlLiBXaGVyZSBDWVAxQTJcKjFGL1wqMUMgd2FzIGNhbGxlZCBvbiBhIHNpbmdsZSBoYXBsb3R5cGUsIHdlIGFzc2lnbmVkIGFuIGFjdGl2aXR5IHNjb3JlIG9mIDEgYmFzZWQgb24gcGFzdCB3b3JrXjEwXi4NCg0KDQp8ICoqRW56eW1lKiogfCAqKkFsbGVsZSoqIHwgKipGdW5jdGlvbioqIHwgKipBY3Rpdml0eSBTY29yZSoqIHwgKipTb3VyY2UqKiAgICAgICAgICAgICAgICAgICAgIHwNCnwgLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfA0KfCBDWVAxQTIgICAgIHwgMUEgICAgICAgICB8IE5vcm1hbCAgICAgICB8IDEgICAgICAgICAgICAgICAgICB8IExlc2NoZSBldCBhbC4sIDIwMTkgICAgICAgICAgICB8DQp8IENZUDFBMiAgICAgfCAxQyAgICAgICAgIHwgRGVjcmVhc2VkICAgIHwgMC41ICAgICAgICAgICAgICAgIHwgU2Fpei1Sb2RyaWd1ZXogZXQgYWwuLCAyMDE5ICAgIHwNCnwgQ1lQMUEyICAgICB8IDFGICAgICAgICAgfCBJbmNyZWFzZWQgICAgfCAxLjUgICAgICAgICAgICAgICAgfCBMZXNjaGUgZXQgYWwuLCAyMDE5ICAgICAgICAgICAgfA0KfCBDWVAxQTIgICAgIHwgMUsgICAgICAgICB8IERlY3JlYXNlZCAgICB8IDAuNSAgICAgICAgICAgICAgICB8IFwtICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IENZUDJENiAgICAgfCAxICAgICAgICAgIHwgTm9ybWFsICAgICAgIHwgMSAgICAgICAgICAgICAgICAgIHwgcHlwZ3ggICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgQ1lQMkQ2ICAgICB8IDIgICAgICAgICAgfCBOb3JtYWwgICAgICAgfCAxICAgICAgICAgICAgICAgICAgfCBweXBneCAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBDWVAyRDYgICAgIHwgNCAgICAgICAgICB8IE51bGwgICAgICAgICB8IDAgICAgICAgICAgICAgICAgICB8IHB5cGd4ICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IENZUDJENiAgICAgfCAxMCAgICAgICAgIHwgRGVjcmVhc2VkICAgIHwgMC4yNSAgICAgICAgICAgICAgIHwgcHlwZ3ggICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgQ1lQMkQ2ICAgICB8IDE3ICAgICAgICAgfCBEZWNyZWFzZWQgICAgfCAwLjUgICAgICAgICAgICAgICAgfCBweXBneCAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBDWVAyRDYgICAgIHwgMjggICAgICAgICB8IFVuY2VydGFpbiAgICB8IE4vQSAgICAgICAgICAgICAgICB8IHB5cGd4ICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IENZUDJENiAgICAgfCAzNSAgICAgICAgIHwgTm9ybWFsICAgICAgIHwgMSAgICAgICAgICAgICAgICAgIHwgcHlwZ3ggICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgQ1lQMkQ2ICAgICB8IDQxICAgICAgICAgfCBEZWNyZWFzZWQgICAgfCAwLjUgICAgICAgICAgICAgICAgfCBweXBneCAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBDWVAyRDYgICAgIHwgNTkgICAgICAgICB8IERlY3JlYXNlZCAgICB8IDAuNSAgICAgICAgICAgICAgICB8IHB5cGd4ICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IENZUDJENiAgICAgfCAxMTcgICAgICAgIHwgVW5jZXJ0YWluICAgIHwgTi9BICAgICAgICAgICAgICAgIHwgcHlwZ3ggICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgQ1lQM0E1ICAgICB8IDEgICAgICAgICAgfCBOb3JtYWwgICAgICAgfCAxICAgICAgICAgICAgICAgICAgfCBDUElDIFBoYXJtR0tCIFJlZmVyZW5jZSBUYWJsZXMgfA0KfCBDWVAzQTUgICAgIHwgMyAgICAgICAgICB8IE51bGwgICAgICAgICB8IDAgICAgICAgICAgICAgICAgICB8IENQSUMgUGhhcm1HS0IgUmVmZXJlbmNlIFRhYmxlcyB8DQp8IENZUDJDMTkgICAgfCAxICAgICAgICAgIHwgTm9ybWFsICAgICAgIHwgMSAgICAgICAgICAgICAgICAgIHwgTGVzY2hlIGV0IGFsLiwgMjAxOSAgICAgICAgICAgIHwNCnwgQ1lQMkMxOSAgICB8IDIgICAgICAgICAgfCBOdWxsICAgICAgICAgfCAwICAgICAgICAgICAgICAgICAgfCBMZXNjaGUgZXQgYWwuLCAyMDE5ICAgICAgICAgICAgfA0KfCBDWVAyQzE5ICAgIHwgOCAgICAgICAgICB8IE51bGwgICAgICAgICB8IDAgICAgICAgICAgICAgICAgICB8IENQSUMgUGhhcm1HS0IgUmVmZXJlbmNlIFRhYmxlcyB8DQp8IENZUDJDMTkgICAgfCAxNSAgICAgICAgIHwgTm9ybWFsICAgICAgIHwgMSAgICAgICAgICAgICAgICAgIHwgQ1BJQyBQaGFybUdLQiBSZWZlcmVuY2UgVGFibGVzIHwNCnwgQ1lQMkMxOSAgICB8IDE3ICAgICAgICAgfCBJbmNyZWFzZWQgICAgfCAxLjUgICAgICAgICAgICAgICAgfCBMZXNjaGUgZXQgYWwuLCAyMDE5ICAgICAgICAgICAgfA0KfCBDWVAyQzkgICAgIHwgMSAgICAgICAgICB8IE5vcm1hbCAgICAgICB8IDEgICAgICAgICAgICAgICAgICB8IHB5cGd4ICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IENZUDJDOSAgICAgfCAyICAgICAgICAgIHwgRGVjcmVhc2VkICAgIHwgMC41ICAgICAgICAgICAgICAgIHwgcHlwZ3ggICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgQ1lQMkM5ICAgICB8IDMgICAgICAgICAgfCBOdWxsICAgICAgICAgfCAwICAgICAgICAgICAgICAgICAgfCBweXBneCAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBDWVAyQzkgICAgIHwgOSAgICAgICAgICB8IE5vcm1hbCAgICAgICB8IDEgICAgICAgICAgICAgICAgICB8IHB5cGd4ICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IENZUDJDOSAgICAgfCAxMSAgICAgICAgIHwgRGVjcmVhc2VkICAgIHwgMC41ICAgICAgICAgICAgICAgIHwgcHlwZ3ggICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwgQ1lQMkM5ICAgICB8IDEyICAgICAgICAgfCBEZWNyZWFzZWQgICAgfCAwLjUgICAgICAgICAgICAgICAgfCBweXBneCAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KDQo8YnI+DQoNClN1cHBsZW1lbnRhcnkgVGFibGUgMS4gQ1lQIHBoYXJtYWNvZ2Vub21pYyBzdGFyIGFsbGVsZXMgY2FsbGVkIGluIHRoZSBDYXJkaWZmQ09HUyBzYW1wbGUuIFN0YXIgYWxsZWxlIGZ1bmN0aW9uLCBhbmQgY29ycmVzcG9uZGluZyBhY3Rpdml0eSBzY29yZXMgYXJlIGxpc3RlZCwgYWxvbmdzaWRlIHNvdXJjZXMgZm9yIG1hcHBpbmcgb2Ygc3RhciBhbGxlbGVzIHRvIGFjdGl2aXR5IHNjb3Jlcy4NCg0KPGJyPg0KPGJyPg0KDQojIyMgQWRkaXRpb25hbCBBbmFseXNlcw0KIyMjIyBBY2NvdW50aW5nIGZvciBQaGVub2NvbnZlcnNpb24NCg0KUGhlbm9jb252ZXJzaW9uIGRlc2NyaWJlcyB0aGUgZ2FwIGJldHdlZW4gZ2VuZXRpY2FsbHkgaW5mZXJyZWQgZW56eW1hdGljIHN0YXR1cyBhbmQgYWN0dWFsIGVuenltZSBhY3Rpdml0eV4xMV4uIE1hbnkgZGlmZmVyZW50IGZhY3RvcnMgY2FuIGluZmx1ZW5jZSBlbnp5bWUgYWN0aXZpdHksIGFuZCBpbiBwYXJ0aWN1bGFyIENZUCBlbnp5bWVzIG1heSBiZSBpbmR1Y2VkIG9yIGluaGliaXRlZCBieSBhIGhvc3Qgb2YgdmFyaWFibGVzIGluY2x1ZGluZyBjb25jb21pdGFudCBtZWRpY2F0aW9uLCBsaWZlc3R5bGUgZmFjdG9ycywgZGlldCwgYW5kIGluZmxhbW1hdGlvbl4xMl4uIA0KDQpXZSBvYnNlcnZlZCBhc3NvY2lhdGlvbnMgYmV0d2VlbiB0aHJlZSBwaGFybWFjb2dlbm9taWMgYWN0aXZpdHkgc2NvcmVzIGFuZCBzY2hpem9waHJlbmlhIHBoZW5vdHlwZSBkaW1lbnNpb25zLiBCYXNlZCBvbiB0aGUgRm9vZCBhbmQgRHJ1ZyBBZG1pbmlzdHJhdGlvbuKAmXMgKEZEQSkgdGFibGUgb2YgQ1lQIEVuenltZS0gYW5kIFRyYW5zcG9ydGVyIFN5c3RlbS1CYXNlZCBDbGluaWNhbCBTdWJzdHJhdGVzLCBJbmhpYml0b3JzLCBvciBJbmR1Y2Vyc14xM14sIHdlIGlkZW50aWZpZWQgdGhyZWUgZHJ1Z3Mgd2l0aGluIHRoZSBDYXJkaWZmQ09HUyBzYW1wbGUgdGhhdCBjb3VsZCBpbmZsdWVuY2UgdGhlIGFjdGl2aXR5IG9mIHRoZXNlIGVuenltZXMuIFRoZXNlIGRydWdzIGluY2x1ZGUgdGhlIENZUDJDMTkgc3Ryb25nIGluaGliaXRvciBmbHVveGV0aW5lIChOID0gYHIgIG5yb3coZmlsdGVyKHRlc3RfZGZfZGltLCBmbHVveGV0aW5lID09IDEpKWApLCB0aGUgQ1lQM0E1IHN0cm9uZyBpbmR1Y2VyIGNhcmJhbWF6ZXBpbmUgIChOID0gYHIgbnJvdyhmaWx0ZXIodGVzdF9kZl9kaW0sIGNhcmJhbWF6ZXBpbmUgPT0gMSkpYCksIGFuZCB0aGUgQ1lQMUEyIG1vZGVyYXRlIGluZHVjZXIgY2lnYXJldHRlIHNtb2tpbmcgKE4gPSBgciBgbnJvdyhmaWx0ZXIodGVzdF9kZl9kaW0sIHNtb2tpbmcgPT0gMSkpYCkuIFdlIGFyZSBob3dldmVyIHVuYWJsZSB0byBhY2NvdW50IGZvciBvdGhlciBkcnVncyBhbmQgZmFjdG9ycyBub3QgcmVwb3J0ZWQgaW4gb3VyIHN0dWR5IChlLmcuLCBvcmFsIGNvbnRyYWNlcHRpdmVzLCBkaWV0YXJ5IGZhY3RvcnMsIGRpc2Vhc2UsIGFuZCBpbmZsYW1tYXRpb24pIHRoYXQgbWF5IGZ1cnRoZXIgaW5mbHVlbmNlIGVuenltZSBhY3Rpdml0eV4xMSwxMl4uIA0KDQpXZSBhY2NvdW50ZWQgZm9yIHBoZW5vY29udmVyc2lvbiB1c2luZyB0d28gbWV0aG9kcywgKGkpIHN0YXRpc3RpY2FsbHkgdGhyb3VnaCBhbiBpbnRlcmFjdGlvbiB0ZXJtIGJldHdlZW4gdGhlIGVuenltZSBhY3Rpdml0eSBzY29yZSBhbmQgYSBiaW5hcnkgdmFyaWFibGUgcmVwcmVzZW50aW5nIHVzZSBvZiB0aGUgcmVsZXZhbnQgZHJ1ZywgYW5kIChpaSkgdHJhZGl0aW9uYWxseSBieSByZXBsYWNpbmcgc3RhbmRhcmQgYWN0aXZpdHkgc2NvcmVzIHdpdGggcGhlbm9jb252ZXJzaW9uLWNvcnJlY3RlZCBhY3Rpdml0eSBzY29yZXMuIFBoZW5vY29udmVyc2lvbi1jb3JyZWN0ZWQgYWN0aXZpdHkgc2NvcmVzIHdlcmUgY2FsY3VsYXRlZCBiYXNlZCBvbiB3b3JrIGJ5IExlc2NoZSBhbmQgY29sbGVhZ3Vlc145Xi4gU2NvcmVzIHdlcmUgbXVsdGlwbGllZCBieSAxLjUgaW4gdGhlIHByZXNlbmNlIG9mIGFuIGluZHVjZXIsIGFuZCBieSAwIHdoZW4gYSBzdHJvbmcgaW5oaWJpdG9yIHdhcyBwcmVzZW50LiBNb2RlbHMgd2VyZSBmaXQgb25seSB3aGVyZSBhIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZSB3YXMgYXNzb2NpYXRlZCB3aXRoIGEgcGhlbm90eXBlIGRpbWVuc2lvbiBpbiBvdXIgcHJldmlvdXMgYW5hbHlzZXMsIGZvciBleGFtcGxlOg0KDQo+IGkpCXBvc2l0aXZlIH4gQ1lQMkMxOSBhY3Rpdml0eSBzY29yZSAqIGZsdW94ZXRpbmUgdXNlICsg4oCmDQppaSkJcG9zaXRpdmUgfiBDWVAyQzE5IHBoZW5vY29udmVyc2lvbi1jb3JyZWN0ZWQgYWN0aXZpdHkgc2NvcmUgKyDigKYNCg0KTWVkaWNhdGlvbiB2YXJpYWJsZXMgYW5kIGNvbnRyb2wgY292YXJpYXRlcyB3ZXJlIGluY2x1ZGVkIHdpdGhpbiB0aGUgbW9kZWxzIGFzIGluIG91ciBtYWluIGFuYWx5c2VzLCBhbmQgZWFjaCBtb2RlbCBvbmx5IGluY2x1ZGVkIG9uZSBwaGFybWFjb2dlbm9taWMgdmFyaWFibGUuDQoNCjxicj4NCjxicj4NCg0KIyMjIyBBY2NvdW50aW5nIGZvciBwcmUtbW9yYmlkIEludGVsbGlnZW5jZSB3aXRoIE5BUlQgSVENCg0KQXNzb2NpYXRpb25zIGJldHdlZW4gY29nbml0aXZlIGFiaWxpdHkgYW5kIG1lZGljYXRpb24gdmFyaWFibGVzIGNvdWxkIHJlZmxlY3QgYSBjYXVzYWwgZWZmZWN0IG9mIG1lZGljYXRpb24gdXNlIG9uIGNvZ25pdGlvbiwgb3IgZXF1YWxseSB0aGF0IHBlb3BsZSB3aXRoIGxvd2VyIGNvZ25pdGl2ZSBhYmlsaXR5IGFyZSBtb3JlIGxpa2VseSB0byBiZSBwcmVzY3JpYmVkIGhpZ2hlciBkb3NlcyBvciBkaWZmZXJlbnQgbWVkaWNhdGlvbnMgdG8gdGhvc2Ugd2l0aCBoaWdoZXIgY29nbml0aXZlIGFiaWxpdHkuIFRoZXJlZm9yZSwgd2UgYWltZWQgdG8gY29udHJvbCBmb3IgYSBtZWFzdXJlIG9mIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2UgaW4gdGhlIHJlZ3Jlc3Npb24gbW9kZWxzLiBGb3IgYW5hbHlzaXMsIE5BUlQgd2FzIGNvbnZlcnRlZCB0byBwcmVkaWN0ZWQgV0FJUy1SIGZ1bGwgc2NhbGUgSVEgdmlhIHRoZSByZWNvbW1lbmRlZCB0cmFuc2Zvcm1hdGlvbiBJUSA9IDEzMC42LTEuMjQqTkFSVCBlcnJvciBzY29yZS4gV2UgY29tcGFyZWQgdHdvIG1lYXN1cmVzIHRoYXQgZXN0aW1hdGUgcHJlbW9yYmlkIGludGVsbGlnZW5jZSAodGhlIE5BUlQgYW5kIGludGVsbGlnZW5jZSBhbmQgZWR1Y2F0aW9uIFBSUykgYnkgaW52ZXN0aWdhdGluZyB0aGVpciBhc3NvY2lhdGlvbiB3aXRoIGN1cnJlbnQgY29nbml0aW9uIGFuZCBjaGxvcnByb21hemluZS1lcXVpdmFsZW50IGFudGlwc3ljaG90aWMgZG9zZSBpbiB0aGUgdG90YWwgc2FtcGxlOg0KDQo+IGkpCWNvZ25pdGlvbiB+IE5BUlQgc2NvcmUgKyBBZ2UgKyBTZXgNCmlpKQljb2duaXRpb24gfiBpbnRlbGxpZ2VuY2UgUEdTICsgZWR1Y2F0aW9uIGF0dGFpbm1lbnQgUEdTICsgQWdlICsgU2V4ICsgUEMxOjUNCmlpaSkJZGFpbHkgZG9zZSB+IE5BUlQgc2NvcmUgKyBBZ2UgKyBTZXgNCml2KQlkYWlseSBkb3NlIH4gaW50ZWxsaWdlbmNlIFBHUyArIGVkdWNhdGlvbiBhdHRhaW5tZW50IFBHUyArIEFnZSArIFNleCArIFBDMTo1DQoNCg0KPGJyPg0KPGJyPg0KPGJyPg0KPGJyPg0KDQojIyA8c3Ryb25nPiBTdXBwbGVtZW50YXJ5IE5vdGVzIC0gUmVzdWx0cyA8L3N0cm9uZz4gey50YWJzZXR9DQojIyMgU2FtcGxlIEluZm9ybWF0aW9uIHsudGFic2V0fQ0KIyMjIyBTYW1wbGUgQXNjZXJ0YWlubWVudA0KIyMjIyMgQXNjZXJ0YWlubWVudCBvZiBzYW1wbGUgc2l6ZSANCg0KYGBge3IgU0YgMSAoU2FtcGxlIE4pLCBmaWcuYWxpZ24gPSAnY2VudHJlJyxmaWcuY2FwPSAiU3VwcGxlbWVudGFyeSBGaWd1cmUgMS4gRGlhZ3JhbSBzaG93aW5nIHBhcnRpY2lwYW50IGV4Y2x1c2lvbiBiYXNlZCBvbiBzZXZlcmFsIGNyaXRlcmlhIGFuZCBhc2NlcnRhaW5tZW50IG9mIHRoZSBmaW5hbCBzYW1wbGUuIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJXcml0aW5nL2ZpZ3MvU0YxLnBuZyIpDQpgYGANCg0KPGJyPg0KPGJyPg0KDQoNCiMjIyMgTW9kZWwgVmFyaWFibGVzDQojIyMjIyBNb2RlbCBWYXJpYWJsZXMgaW4gQ2FyZGlmZkNPR1MNCmBgYHtyIFNUIDIgKERlc2NyaXB0aXZlIFN0YXRpc3RpY3MpfQ0KZGZfdG90YWwgPC0gdGVzdF9kZl9kaW0gJT4lDQogICBmaWx0ZXIoaWZfYWxsKGMoU3R1ZHlfSUQsIHBvc2l0aXZlLCBleHByZXNzLCBtYW5kcCwgc2FkLCBjb2csIGNwel9lcSwgQWRoZXJlbmNlX2NvZGVkLCBjbG96YXBpbmVfY3VycmVudCwgYW50aWNob2xfcHJlc2VudCwgU1pfUFJTY3MsIEFnZV9hdF9JbnRlcnZpZXcsIFNleCwgUEMxLCBQQzIsIFBDMywgUEM0LCBQQzUpLCBjb21wbGV0ZS5jYXNlcykpDQoNCmEgPC0gZGZfdG90YWwgJT4lDQogIHRibF9zdW1tYXJ5KGluY2x1ZGUgPSBjKGNwel9lcSwgY2xvemFwaW5lX2N1cnJlbnQsIGFudGljaG9sX3ByZXNlbnQsICBBZGhlcmVuY2VfY29kZWQsIEFnZV9hdF9JbnRlcnZpZXcsIFNleCwgYXBfcG9seSwgc21va2luZywgZmx1b3hldGluZSxjYXJiYW1hemVwaW5lKSwgc3RhdGlzdGljID0gbGlzdCgNCiAgICAgIGFsbF9jb250aW51b3VzKCkgfiAie21lYW59ICh7c2R9KSIsDQogICAgICBhbGxfY2F0ZWdvcmljYWwoKSB+ICJ7bn0gKHtwfSUpIg0KICAgICksIGRpZ2l0cyA9ICBhbGxfY29udGludW91cygpIH4gMSwgbGFiZWwgPSBsaXN0KGNwel9lcSB+ICJDaGxvcnByb21hemluZSBFcXVpdmFsZW50IEFudGlwc3ljaG90aWMgRG9zZSIsIGNsb3phcGluZV9jdXJyZW50IH4gIkNsb3phcGluZSBVc2UiLCBhbnRpY2hvbF9wcmVzZW50IH4gIkFudGljaG9saW5lcmdpYyBVc2UiLCBBZGhlcmVuY2VfY29kZWQgfiAiQWRoZXJlbnQiLCBBZ2VfYXRfSW50ZXJ2aWV3IH4gIkFnZSIsIFNleCB+ICJTZXgiLCBhcF9wb2x5IH4gIkFudGlwc3ljaG90aWMgUG9seXBoYXJtYWN5Iiwgc21va2luZyB+ICJDaWdhcmV0dGUgVXNlIiwgZmx1b3hldGluZSB+ICJGbHVveGV0aW5lIFVzZSIsIGNhcmJhbWF6ZXBpbmUgfiAiQ2FyYmFtYXplcGluZSBVc2UiKSkgJT4lIA0KICBtb2RpZnlfaGVhZGVyKA0KICAgIGxhYmVsID0gIlZhcmlhYmxlIiwNCiAgICBzdGF0XzAgPSAiTWVhbiAoU0QpOyBuICglKSIpICU+JQ0KICBtb2RpZnlfZm9vdG5vdGUodXBkYXRlID0gZXZlcnl0aGluZygpIH4gTkEpIA0KDQojIyMjIw0KYiA8LSBhcy5kYXRhLmZyYW1lKGEpDQpiWzMsMV0gPC0gIk5vIg0KYls0LDFdIDwtICJZZXMiDQoNCmJbNiwxXSA8LSAiTm8iDQpiWzcsMV0gPC0gIlllcyINCg0KYls5LDFdIDwtICJObyINCmJbMTAsMV0gPC0gIlllcyINCg0KYlsxMywxXSA8LSAiTWFsZSINCmJbMTQsMV0gPC0gIkZlbWFsZSINCg0KYlsxNiwxXSA8LSAiTm8iDQpiWzE3LDFdIDwtICJZZXMiDQoNCmJbMTksMV0gPC0gIk5vIg0KYlsyMCwxXSA8LSAiWWVzIg0KDQpiWzIzLDFdIDwtICJObyINCmJbMjQsMV0gPC0gIlllcyINCg0KYlsyNiwxXSA8LSAiTm8iDQpiWzI3LDFdIDwtICJZZXMiDQoNCg0Kcm93X2hlYWQgPC0gYygiVmFyaWFibGUiLCAibiAoJSkiKQ0KYWdlIDwtIGJbMTEsXQ0KDQpiIDwtIGJbLTExLF0NCmIgPC0gaW5zZXJ0Um93MihiLCBhZ2UsIDIpDQpiIDwtIGluc2VydFJvdzIoYiwgcm93X2hlYWQsIDMpDQoNCg0KIyMjIyMNCmthYmxlKGIsIHJvdy5uYW1lcyA9IEYsIGRpZ2l0cyA9IFQsIGNhcHRpb24gPSAiU3VwcGxlbWVudGFyeSBUYWJsZSAyLiBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGZvciBrZXkgdmFyaWFibGVzIGluIHRoZSBhbmFseXNlZCBzYW1wbGUgKE4gPSA1ODUpLiBNZWFuIChTRCkgaXMgcmVwb3J0ZWQgZm9yIGNvbnRpbnVvdXMgdmFyaWFibGVzIGFuZCBuICglKSBpcyByZXBvcnRlZCBmb3IgY2F0ZWdvcmljYWwgdmFyaWFibGVzLiIsIGNvbC5uYW1lcyA9IGMoIlZhcmlhYmxlIiwgIk1lYW4gKFNEKSIpKSAlPiUgDQogIHJvd19zcGVjKDAsYm9sZD1UUlVFKSAlPiUgDQogIHJvd19zcGVjKDMsYm9sZD1UUlVFKSAlPiUgDQogIGFkZF9pbmRlbnQoDQogIGMoNSw2LCA4LDksIDExLDEyLCAxNCwxNSwgMTcsMTgsIDIwLDIxLDIyLCAyNCwyNSwgMjcsMjgpLA0KICBsZXZlbF9vZl9pbmRlbnQgPSAxLA0KICBhbGxfY29scyA9IEZBTFNFLA0KICB0YXJnZXRfY29scyA9IDENCikgJT4lDQogIGthYmxlX3N0eWxpbmcoZnVsbF93aWR0aCA9IEYpDQpgYGANCg0KPGJyPg0KDQojIyMjIEFudGlwc3ljaG90aWMgVXNlDQojIyMjIyBBbnRpcHN5Y2hvdGljIFVzZSBpbiBDYXJkaWZmQ09HUw0KYGBge3IgU1QzIChBUCBCcmVha2Rvd24pfQ0KDQptZWRzIDwtIGRwbHlyOjpzZWxlY3QocGhlbm8sIGMoIlN0dWR5X0lEIiwgIkFudGlwc3ljaG90aWMiLCAiQVBfZG9zZSIsICJhbnRpZGVwcmVzc2FudCIsICJBRF9kb3NlIiwgIk1vb2RfU3RhYmlsaXNlciIsICJNU19kb3NlIiwgIkJlbnpvZGlhemVwaW5lIiwgIkJlbl9kb3NlIiwgIkFudGljaG9saW5lcmdpYyIsICJBbnRpY2hvbGluZXJnaWNfZG9zZSIgLCAib3RoZXJfbWVkaWNhdGlvbiIsICJPdGhlcl9tZWRpY2F0aW9uX2Rvc2UiLCAiQ3VycmVudF9zbW9raW5nIikpDQoNCm1lZHMkQW50aXBzeWNob3RpY1shKG1lZHMkQW50aXBzeWNob3RpYyAlaW4lIEFQX2NvZGVzKV0gPC0gTkENCm1lZHMkYW50aWRlcHJlc3NhbnRbIShtZWRzJGFudGlkZXByZXNzYW50ICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KbWVkcyRNb29kX1N0YWJpbGlzZXJbIShtZWRzJE1vb2RfU3RhYmlsaXNlciVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KbWVkcyRCZW56b2RpYXplcGluZVshKG1lZHMkQmVuem9kaWF6ZXBpbmUgJWluJSBBUF9jb2RlcyldIDwtIE5BDQptZWRzJEFudGljaG9saW5lcmdpY1shKG1lZHMkQW50aWNob2xpbmVyZ2ljICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KbWVkcyRvdGhlcl9tZWRpY2F0aW9uWyEobWVkcyRvdGhlcl9tZWRpY2F0aW9uICVpbiUgQVBfY29kZXMpXSA8LSBOQQ0KDQojIHJlbW92ZSBkb3NlcyBmb3Igbm9uLXVzZWZ1bCBkcnVncw0KbWVkcyRBUF9kb3NlW2lzLm5hKG1lZHMkQW50aXBzeWNob3RpYyldIDwtIE5BDQptZWRzJEFEX2Rvc2VbaXMubmEobWVkcyRhbnRpZGVwcmVzc2FudCldIDwtIE5BDQptZWRzJE1TX2Rvc2VbaXMubmEobWVkcyRNb29kX1N0YWJpbGlzZXIpXSA8LSBOQQ0KbWVkcyRCZW5fZG9zZVtpcy5uYShtZWRzJEJlbnpvZGlhemVwaW5lKV0gPC0gTkENCm1lZHMkQW50aWNob2xpbmVyZ2ljX2Rvc2VbaXMubmEobWVkcyRBbnRpY2hvbGluZXJnaWMpXSA8LSBOQQ0KbWVkcyRPdGhlcl9tZWRpY2F0aW9uX2Rvc2VbaXMubmEobWVkcyRvdGhlcl9tZWRpY2F0aW9uKV0gPC0gTkENCg0KYXBzIDwtIHRhYmxlKG1lZHMkQW50aXBzeWNob3RpYykgJT4lIGFzLmRhdGEuZnJhbWUoKQ0KYWRzIDwtIHRhYmxlKG1lZHMkYW50aWRlcHJlc3NhbnQpICU+JSBhcy5kYXRhLmZyYW1lKCkNCm1zcyA8LSB0YWJsZShtZWRzJE1vb2RfU3RhYmlsaXNlcikgJT4lIGFzLmRhdGEuZnJhbWUoKQ0KYnpzIDwtIHRhYmxlKG1lZHMkQmVuem9kaWF6ZXBpbmUpICU+JSBhcy5kYXRhLmZyYW1lKCkNCmFjcyA8LSB0YWJsZShtZWRzJEFudGljaG9saW5lcmdpYykgJT4lIGFzLmRhdGEuZnJhbWUoKQ0Kb3RzIDwtIHRhYmxlKG1lZHMkb3RoZXJfbWVkaWNhdGlvbikgJT4lIGFzLmRhdGEuZnJhbWUoKQ0KDQptZWRfZnJlcSA8LSBmdWxsX2pvaW4oYXBzLCBhZHMsIGJ5ID0gIlZhcjEiKQ0KbWVkX2ZyZXEgPC0gZnVsbF9qb2luKG1lZF9mcmVxLCBtc3MsIGJ5ID0gIlZhcjEiKQ0KbWVkX2ZyZXEgPC0gZnVsbF9qb2luKG1lZF9mcmVxLCBienMsIGJ5ID0gIlZhcjEiKQ0KbWVkX2ZyZXEgPC0gZnVsbF9qb2luKG1lZF9mcmVxLCBhY3MsIGJ5ID0gIlZhcjEiKQ0KbWVkX2ZyZXEgPC0gZnVsbF9qb2luKG1lZF9mcmVxLCBvdHMsIGJ5ID0gIlZhcjEiKQ0KDQpjb2xzIDwtIGNvbG5hbWVzKG1lZF9mcmVxKQ0KDQptZWRfZnJlcSR0b3RhbCA8LSByb3dTdW1zKG1lZF9mcmVxWywgY29sc1stMV1dLCBuYS5ybSA9IFRSVUUpDQoNCnJlY29kZV92ZWN0b3IgPC0gYygNCiAgIjEiID0gIkFtaXN1bHByaWRlIiwNCiAgIjIiID0gIkFyaXBpcHJhem9sZSIsDQogICIzIiA9ICJDaGxvcnByb21hemluZSIsDQogICI0IiA9ICJDbG96YXBpbmUiLA0KICAiNSIgPSAiRmx1cGVudGhpeG9sIiwNCiAgIjYiID0gIkZsdXBlbnRoaXhvbCIsIA0KICAiNyIgPSAiRmx1cGhlbmF6aW5lIiwNCiAgIjgiID0gIkZsdXBoZW5hemluZSIsDQogICI5IiA9ICJIYWxvcGVyaWRvbCIsDQogICIxMCIgPSAiSGFsb3Blcmlkb2wiLA0KICAiMTIiID0gIk9sYW56YXBpbmUiLA0KICAiMTUiID0gIlBpbW96aWRlIiwNCiAgIjE2IiA9ICJQaXBvdGlhemluZSIsDQogICIyMCIgPSAiUXVldGlhcGluZSIsDQogICIyMSIgPSAiUmlzcGVyaWRvbmUiLA0KICAiMjIiID0gIlJpc3Blcmlkb25lIiwNCiAgIjI0IiA9ICJTdWxwaXJpZGUiLA0KICAiMjYiID0gIlRyaWZsdW9wZXJhemluZSIsDQogICIyOCIgPSAiWnVjbG9wZW50aGl4b2wiLA0KICAiMjkiID0gIlp1Y2xvcGVudGhpeG9sIiwNCiAgIjg3IiA9ICJQYWxpcGVyaWRvbmUiDQopDQoNCm1lZF9mcmVxIDwtIGFzLmRhdGEuZnJhbWUocmVjb2RlX3NlbGVjdGVkX2NvZGVzKGRmID0gbWVkX2ZyZXEsIHJlY29kZV92ZWN0b3IgPSByZWNvZGVfdmVjdG9yLCBjb2x1bW5zX3RvX3JlY29kZSA9ICJWYXIxIikpDQoNCm1lZF9kZiA8LSBkcGx5cjo6c2VsZWN0KG1lZF9mcmVxLCBjKCJWYXIxIiwgInRvdGFsIikpDQoNCmFsdF9kZiA8LSBzZXREVChtZWRfZGYpWywgLih2YWx1ZT1zdW0odG90YWwpKSAsIGJ5ID0gVmFyMV0NCmFsdF9kZiA8LSBhbHRfZGZbb3JkZXIoYWx0X2RmJFZhcjEpLF0NCg0KYWx0X2RmJHZhbHVlW2FsdF9kZiR2YWx1ZSA8NV0gPC0gIjwgNSINCmFsdF9kZiA8LSBhbHRfZGZbb3JkZXIoYWx0X2RmJFZhcjEpLF0NCmNvbG5hbWVzKGFsdF9kZikgPC0gYygiQW50aXBzeWNob3RpYyIsICJOIikNCg0Ka2FibGUoYWx0X2RmLCByb3cubmFtZXMgPSBGLCBkaWdpdHMgPSBULCBjYXB0aW9uID0gIlN1cHBsZW1lbnRhcnkgVGFibGUgMy4gRnJlcXVlbmN5IG9mIGN1cnJlbnRseSB1c2VkIGFudGlwc3ljaG90aWNzIGluIHRoZSBDYXJkaWZmQ09HUyBzYW1wbGUgLiIpICU+JSBrYWJsZV9zdHlsaW5nKGZ1bGxfd2lkdGggPSBUKQ0KDQojbWVkX2RmIDwtIG1lZF9kZiAlPiUNCiMgICAgbXV0YXRlKFZhcjEgPSBzdHJfdG9fc2VudGVuY2UoVmFyMSkpDQojY29sbmFtZXMobWVkX2RmKSA8LSBjKCJBbnRpcHN5Y2hvdGljIiwgIk4iKQ0KDQojbWVkX2RmJEFkbWluaXN0cmF0aW9uIDwtIGMoIk9yYWwiLCAiT3JhbCIsICJPcmFsIiwgIk9yYWwiLCAiT3JhbCIsICJEZXBvdCIsICJPcmFsIiwgIkRlcG90IiwgIk9yYWwiLCAiRGVwb3QiLCAiT3JhbCIsICJPcmFsIiwgIkRlcG90IiwgIk9yYWwiLCAiT3JhbCIsICJEZXBvdCIsICJPcmFsIiwgIk9yYWwiLCAiT3JhbCIsIkRlcG90IiwgIkRlcG90IikNCg0KI21lZF9kZiA8LSBtZWRfZGYgJT4lIGRwbHlyOjpzZWxlY3QoYygiQW50aXBzeWNob3RpYyIsICJBZG1pbmlzdHJhdGlvbiIsICJOIikpDQoNCiNrYWJsZShtZWRfZGYsIHJvdy5uYW1lcyA9IEYsIGRpZ2l0cyA9IFQsIGNhcHRpb24gPSAiU3VwcGxlbWVudGFyeSBUYWJsZSAzLiBGcmVxdWVuY3kgb2YgY3VycmVudGx5IHVzZWQgYW50aXBzeWNob3RpY3MgaW4gdGhlIENhcmRpZmZDT0dTIHNhbXBsZSBhbmQgdGhlaXIgbW9kZSBvZiBhZG1pbmlzdHJhdGlvbi4iKSAlPiUga2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gRikNCg0Kcm0obWVkcywgYXBzLCBhZHMsIG1zcywgYnpzLCBhY3MsIG90cywgY29scywgIG1lZF9mcmVxKQ0KYGBgDQoNCg0KPGJyPg0KPGJyPg0KDQojIyMjIFN0YXIgQWxsZWxlIEZyZXF1ZW5jeQ0KIyMjIyMgU3RhciBBbGxlbGUgRnJlcXVlbmNpZXMgZm9yIENhcmRpZmZDT0dTDQpgYGB7ciBTVDQgKFN0YXIgQWxsZWxlcyl9DQojIyMjIGN5cDFhMiAjIyMjDQpzdGFyX2N5cDFhMiA8LSBsZWZ0X2pvaW4odGVzdF9kZl9kaW0sIHB5cGd4XzFhMikNCg0KQV8xYTIgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzdGFyX2N5cDFhMiRIYXBsb3R5cGUxKSkNCkJfMWEyIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc3Rhcl9jeXAxYTIkSGFwbG90eXBlMikpDQoNCmZyZXFfMWEyIDwtIGZ1bGxfam9pbihBXzFhMiwgQl8xYTIsIGJ5ID0gIlZhcjEiKQ0KZnJlcV8xYTIkVG90YWwgPC0gcm93U3VtcyhmcmVxXzFhMlstMV0sIG5hLnJtID0gVCkNCmZyZXFfMWEyJEZyZXF1ZW5jeSA8LSByb3VuZChmcmVxXzFhMiRUb3RhbC9zdW0oZnJlcV8xYTIkVG90YWwpLCAzKQ0KZnJlcV8xYTIkR2VuZSA8LSAiPGk+Q1lQMUEyPC9pPiINCg0KZnJlcV8xYTIgPC0gZnJlcV8xYTIgJT4lIGRwbHlyOjpzZWxlY3QoIkdlbmUiLCAiVmFyMSIsICJUb3RhbCIsICJGcmVxdWVuY3kiKQ0KY29sbmFtZXMoZnJlcV8xYTIpIDwtIGMoIkdlbmUiLCAiU3RhciBBbGxlbGUiLCAiVG90YWwiLCAiRnJlcXVlbmN5IikNCg0KIyMjIyBjeXAyZDYgIyMjIw0KDQpzdGFyX2N5cDJkNiA8LSBsZWZ0X2pvaW4odGVzdF9kZl9kaW0sIHB5cGd4XzJkNikNCg0KQV8yZDYgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzdGFyX2N5cDJkNiRHZW5vMSkpDQpCXzJkNiA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHN0YXJfY3lwMmQ2JEdlbm8yKSkNCg0KZnJlcV8yZDYgPC0gZnVsbF9qb2luKEFfMmQ2LCBCXzJkNiwgYnkgPSAiVmFyMSIpDQpmcmVxXzJkNiRUb3RhbCA8LSByb3dTdW1zKGZyZXFfMmQ2Wy0xXSwgbmEucm0gPSBUKQ0KZnJlcV8yZDYkRnJlcXVlbmN5IDwtIHJvdW5kKGZyZXFfMmQ2JFRvdGFsL3N1bShmcmVxXzJkNiRUb3RhbCksIDMpDQpmcmVxXzJkNiRHZW5lIDwtICI8aT5DWVAyRDY8L2k+Ig0KDQpmcmVxXzJkNiA8LSBmcmVxXzJkNiAlPiUgZHBseXI6OnNlbGVjdCgiR2VuZSIsICJWYXIxIiwgIlRvdGFsIiwgIkZyZXF1ZW5jeSIpDQoNCmNvbG5hbWVzKGZyZXFfMmQ2KSA8LSBjKCJHZW5lIiwgIlN0YXIgQWxsZWxlIiwgIlRvdGFsIiwgIkZyZXF1ZW5jeSIpDQoNCiMjIyMgY3lwMmE1ICMjIyMNCg0Kc3Rhcl9jeXAzYTUgPC0gbGVmdF9qb2luKHRlc3RfZGZfZGltLCBweXBneF8zYTUpDQoNCkFfM2E1IDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc3Rhcl9jeXAzYTUkR2VubzEpKQ0KQl8zYTUgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzdGFyX2N5cDNhNSRHZW5vMikpDQoNCmZyZXFfM2E1IDwtIGZ1bGxfam9pbihBXzNhNSwgQl8zYTUsIGJ5ID0gIlZhcjEiKQ0KZnJlcV8zYTUkVG90YWwgPC0gcm93U3VtcyhmcmVxXzNhNVstMV0sIG5hLnJtID0gVCkNCmZyZXFfM2E1JEZyZXF1ZW5jeSA8LSByb3VuZChmcmVxXzNhNSRUb3RhbC9zdW0oZnJlcV8zYTUkVG90YWwpLCAzKQ0KZnJlcV8zYTUkR2VuZSA8LSAiPGk+Q1lQM0E1PC9pPiINCg0KZnJlcV8zYTUgPC0gZnJlcV8zYTUgJT4lIGRwbHlyOjpzZWxlY3QoIkdlbmUiLCAiVmFyMSIsICJUb3RhbCIsICJGcmVxdWVuY3kiKQ0KY29sbmFtZXMoZnJlcV8zYTUpIDwtIGMoIkdlbmUiLCAiU3RhciBBbGxlbGUiLCAiVG90YWwiLCAiRnJlcXVlbmN5IikNCg0KIyMjIyBjeXAyYzE5ICMjIyMNCg0Kc3Rhcl9jeXAyYzE5IDwtIGxlZnRfam9pbih0ZXN0X2RmX2RpbSwgcHlwZ3hfMmMxOSkNCg0KQV8yYzE5IDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc3Rhcl9jeXAyYzE5JEdlbm8xKSkNCkJfMmMxOSA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHN0YXJfY3lwMmMxOSRHZW5vMikpDQoNCmZyZXFfMmMxOSA8LSBmdWxsX2pvaW4oQV8yYzE5LCBCXzJjMTksIGJ5ID0gIlZhcjEiKQ0KZnJlcV8yYzE5JFRvdGFsIDwtIHJvd1N1bXMoZnJlcV8yYzE5Wy0xXSwgbmEucm0gPSBUKQ0KZnJlcV8yYzE5JEZyZXF1ZW5jeSA8LSByb3VuZChmcmVxXzJjMTkkVG90YWwvc3VtKGZyZXFfMmMxOSRUb3RhbCksIDMpDQpmcmVxXzJjMTkkR2VuZSA8LSAiPGk+Q1lQMkMxOTwvaT4iDQoNCmZyZXFfMmMxOSA8LSBmcmVxXzJjMTkgJT4lIGRwbHlyOjpzZWxlY3QoIkdlbmUiLCAiVmFyMSIsICJUb3RhbCIsICJGcmVxdWVuY3kiKQ0KY29sbmFtZXMoZnJlcV8yYzE5KSA8LSBjKCJHZW5lIiwgIlN0YXIgQWxsZWxlIiwgIlRvdGFsIiwgIkZyZXF1ZW5jeSIpDQoNCiMjIyMgY3lwMmM5ICMjIyMNCg0Kc3Rhcl9jeXAyYzkgPC0gbGVmdF9qb2luKHRlc3RfZGZfZGltLCBweXBneF8yYzkpDQoNCkFfMmM5IDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc3Rhcl9jeXAyYzkkR2VubzEpKQ0KQl8yYzkgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzdGFyX2N5cDJjOSRHZW5vMikpDQoNCmZyZXFfMmM5IDwtIGZ1bGxfam9pbihBXzJjOSwgQl8yYzksIGJ5ID0gIlZhcjEiKQ0KZnJlcV8yYzkkVG90YWwgPC0gcm93U3VtcyhmcmVxXzJjOVstMV0sIG5hLnJtID0gVCkNCmZyZXFfMmM5JEZyZXF1ZW5jeSA8LSByb3VuZChmcmVxXzJjOSRUb3RhbC9zdW0oZnJlcV8yYzkkVG90YWwpLCAzKQ0KZnJlcV8yYzkkR2VuZSA8LSAiPGk+Q1lQMkM5PC9pPiINCg0KZnJlcV8yYzkgPC0gZnJlcV8yYzkgJT4lIGRwbHlyOjpzZWxlY3QoIkdlbmUiLCAiVmFyMSIsICJUb3RhbCIsICJGcmVxdWVuY3kiKQ0KY29sbmFtZXMoZnJlcV8yYzkpIDwtIGMoIkdlbmUiLCAiU3RhciBBbGxlbGUiLCAiVG90YWwiLCAiRnJlcXVlbmN5IikNCg0KYWxsX2ZyZXEgPC0gcmJpbmQoZnJlcV8xYTIsIGZyZXFfMmQ2LCBmcmVxXzNhNSwgZnJlcV8yYzE5LCBmcmVxXzJjOSkNCg0KYWxsX2ZyZXEgJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNhcHRpb24gPSAiU3VwcGxlbWVudGFyeSBUYWJsZSA0LiBUb3RhbCBhbGxlbGUgY291bnQsIGFuZCBhbGxlbGUgZnJlcXVlbmN5IGZvciBDWVAgcGhhcm1hY29nZW5vbWljIHN0YXIgYWxsZWxlcyBmb3VuZCBpbiB0aGUgQ2FyZGlmZkNPR1Mgc2FtcGxlLiIpICU+JQ0KICBjb2xsYXBzZV9yb3dzKGNvbHVtbnMgPSAxLCB2YWxpZ24gPSAidG9wIikgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpDQoNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCg0KDQojIyMgQ0ZBIA0KIyMjIyBDRkEgTWVhc3VyZXMgYW5kIFByZWxpbWluYXJ5IEFuYWx5c2lzDQojIyMjIyBBc3NvY2lhdGlvbnMgd2l0aCBHbG9iYWwgQXNzZXNzbWVudCBTY2FsZQ0KDQpgYGB7ciBsbSBHQVMgUGFzdCBXZWVrLCBpbmNsdWRlID0gRkFMU0V9DQoNCg0KZGZfdG90YWxfc3RkIDwtIGRhdGF3aXphcmQ6OnN0YW5kYXJkaXNlKHggPSBkZl90b3RhbCkNCg0KIyB0ZXN0aW5nIHdoZXRoZXIgbWVkaWNhdGlvbiwgUEd4LCBvciBQUlMgdmFyaWFibGVzIGFyZSBhc3NvY2lhdGVkIHdpdGggc3ltcHRvbSBkaW1lbnNpb25zIGluIHRoZSB0b3RhbCBzYW1wbGUuIA0KDQpnYXNfcG9zIDwtIGxtKHBvc2l0aXZlIH4gIEdBU19QYXN0X1dlZWsgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZCkNCg0KZ2FzX2V4cCA8LSBsbShleHByZXNzIH4gIEdBU19QYXN0X1dlZWsgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZCkNCg0KZ2FzX21hcCA8LSBsbShtYW5kcCB+ICBHQVNfUGFzdF9XZWVrICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXgsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCmdhc19jb2cgPC0gbG0oY29nIH4gR0FTX1Bhc3RfV2VlayArIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpnYXNfc2FkIDwtIGxtKHNhZCB+ICBHQVNfUGFzdF9XZWVrICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXgsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCmNvZWZzNGEgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZ2FzX3BvcykpKSANCmNvZWZzNGIgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZ2FzX2V4cCkpKSANCmNvZWZzNGMgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZ2FzX21hcCkpKSANCmNvZWZzNGQgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZ2FzX3NhZCkpKSANCmNvZWZzNGUgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZ2FzX2NvZykpKSANCg0KYGBgDQoNCkZvdXIgZmFjdG9yIHN0cnVjdHVyZXMgd2VyZSBmaXQgdG8gZGV0ZXJtaW5lIHdoaWNoIGJlc3QgcmVwcmVzZW50ZWQgdGhlIGRhdGEgYXMgZGVzY3JpYmVkIGluICoqU3VwcGxlbWVudGFyeSBUYWJsZSA0KiouIFNjb3JlcyBmb3IgYWxsIGxhdGVudCB2YXJpYWJsZXMgd2VyZSBzaWduaWZpY2FudGx5IGFzc29jaWF0ZWQgd2l0aCBjdXJyZW50IEdsb2JhbCBBc3Nlc3NtZW50IFNjYWxlIHJhdGluZ3MgaW4gbW9kZWxzIHRoYXQgY29udHJvbGxlZCBmb3IgYWdlIGFuZCBzZXguIEluIGFsbCBpbnN0YW5jZXMsIGluY3JlYXNlZCBzeW1wdG9tIHNldmVyaXR5IHdhcyBhc3NvY2lhdGVkIHdpdGggcmVkdWNlZCBzY29yZXMgb24gdGhlIEdsb2JhbCBBc3Nlc3NtZW50IFNjYWxlLiBUaGlzIG1hbmlmZXN0ZWQgYXMgaW52ZXJzZSBhc3NvY2lhdGlvbnMgYmV0d2VlbiB0aGUgcG9zaXRpdmUgKM6yID0gYHIgY29lZnM0YVsyLDFdIGA7ICA5NSVDSSwgYHIgcm91bmQoY29uZmludChnYXNfcG9zKVsyLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChnYXNfcG9zKVsyLDJdLCAyKWA7ICpwKiA9ICBgciBmb3JtYXRfcChjb2VmczRhWzIsNF0pYCksIGRpbWluaXNoZWQgZXhwcmVzc2l2aXR5ICjOsiA9IGByIGNvZWZzNGJbMiwxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoZ2FzX2V4cClbMiwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoZ2FzX2V4cClbMiwyXSwgMilgOyAqcCogPSAgYHIgZm9ybWF0X3AoY29lZnM0YlsyLDRdKWApLCByZWR1Y2VkIG1vdGl2YXRpb24gYW5kIHBsZWFzdXJlICjOsiA9IGByIGNvZWZzNGNbMiwxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoZ2FzX21hcClbMiwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoZ2FzX21hcClbMiwyXSwgMilgOyAqcCogPSAgYHIgZm9ybWF0X3AoY29lZnM0Y1syLDRdKWApLCBhbmQgZGVwcmVzc2lvbi9zdWljaWRlIGRpbWVuc2lvbnMgICjOsiA9IGByIGNvZWZzNGRbMiwxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoZ2FzX3NhZClbMiwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoZ2FzX3NhZClbMiwyXSwgMilgOyAqcCogPSAgYHIgZm9ybWF0X3AoY29lZnM0ZFsyLDRdKWApIHdpdGggR2xvYmFsIEFzc2Vzc21lbnQgU2NhbGUgc2NvcmVzLiBUaGUgY29nbml0aW9uIGRpbWVuc2lvbiB3YXMgcG9zaXRpdmVseSBhc3NvY2lhdGVkIHdpdGggR0FTICjOsiA9IGByIGNvZWZzNGVbMiwxXSBgOyA5NSVDSSwgYHIgcm91bmQoY29uZmludChnYXNfY29nKVsyLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChnYXNfY29nKVsyLDJdLCAyKWA7ICpwKiA9ICBgciBmb3JtYXRfcChjb2VmczRlWzIsNF0pYCksIHdpdGggaGlnaGVyIHJhdGluZ3MgYWNyb3NzIHRoZSBHbG9iYWwgQXNzZXNzbWVudCBTY2FsZSBhbmQgdGhlIGNvZ25pdGlvbiBkaW1lbnNpb24gYm90aCByZWZsZWN0aW5nIGltcHJvdmVkIGZ1bmN0aW9uaW5nLg0KDQo8YnI+DQoNCmBgYHtyIENGQSBtb2RlbHMsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIGluY2x1ZGUgPSBGQUxTRX0NCiMjIyMgZm91ciBmYWN0b3IgbW9kZWwgIyMjIw0KcG9zaXRpdmUgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAiU0FQU19HbG9iYWxfSGFscyIsICAiU0FQU19HbG9iYWxfRGVsdXNpb25zIikpDQoNCm5lZ2F0aXZlIDwtIGRwbHlyOjpzZWxlY3QocGhlbm8sIGMoIlN0dWR5X0lEIiwgIlNBTlNfR2xvYmFsX0FmZmVjdGl2ZV9GbGF0dGVuaW5nIiwgICJTQU5TX0dsb2JhbF9BbG9naWEiLCAgIlNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IiwiU0FOU19HbG9iYWxfQXZvbGl0aW9uX0FwYXRoeSIpKQ0KDQpvdGhlcnMgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJaTkFCX01hemVzX0ltcCIsIlpIVkxUX0ltcCIsICJaQlZNVF9JbXAiLCAiWkNQVF9JbXAiLCAiWlNvUF9JbXAiLCAiWldNX0ltcCIpKQ0KDQpzeW1wdG9tcyA8LSBsZWZ0X2pvaW4ocG9zaXRpdmUsIG5lZ2F0aXZlLCBieSA9ICJTdHVkeV9JRCIpDQpzeW1wdG9tcyA8LSBsZWZ0X2pvaW4oc3ltcHRvbXMsIG90aGVycywgYnkgPSAiU3R1ZHlfSUQiKQ0KDQp0ZXN0X2RmIDwtIGxlZnRfam9pbihzeW1wdG9tcywgZGYsIGJ5ID0gIlN0dWR5X0lEIikNCg0KdGVzdF9kZlssYygiU0FQU19HbG9iYWxfRGVsdXNpb25zIiwiU0FQU19HbG9iYWxfSGFscyIsICJTQU5TX0dsb2JhbF9BZmZlY3RpdmVfRmxhdHRlbmluZyIsICJTQU5TX0dsb2JhbF9BbG9naWEiLCAiU0FOU19HbG9iYWxfQW5oZWRvbmlhX0Fzb2NpYWxpdHkiLCAgIlNBTlNfR2xvYmFsX0F2b2xpdGlvbl9BcGF0aHkiDQogICAgICAgICAgICldIDwtDQogICAgIGxhcHBseSh0ZXN0X2RmWyxjKCJTQVBTX0dsb2JhbF9EZWx1c2lvbnMiLCJTQVBTX0dsb2JhbF9IYWxzIiwgIlNBTlNfR2xvYmFsX0FmZmVjdGl2ZV9GbGF0dGVuaW5nIiwgIlNBTlNfR2xvYmFsX0Fsb2dpYSIsICJTQU5TX0dsb2JhbF9BbmhlZG9uaWFfQXNvY2lhbGl0eSIsICAiU0FOU19HbG9iYWxfQXZvbGl0aW9uX0FwYXRoeSINCiAgICAgICAgICAgICAgICAgICAgICAgKV0sIG9yZGVyZWQpIA0KDQoNCm1vZGVsMCA8LSAncG9zaXRpdmUgPX4gU0FQU19HbG9iYWxfSGFscyArIFNBUFNfR2xvYmFsX0RlbHVzaW9ucw0KICAgICAgICAgICBleHByZXNzID1+IFNBTlNfR2xvYmFsX0FmZmVjdGl2ZV9GbGF0dGVuaW5nICsgU0FOU19HbG9iYWxfQWxvZ2lhIA0KICAgICAgICAgICBtYW5kcCA9fiAgU0FOU19HbG9iYWxfQXZvbGl0aW9uX0FwYXRoeSArIFNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5DQogICAgICAgICAgIGNvZyA9fiBaTkFCX01hemVzX0ltcCArIFpIVkxUX0ltcCArIFpCVk1UX0ltcCArIFpDUFRfSW1wICsgWlNvUF9JbXAgKyBaV01fSW1wJw0KDQpmaXRzJHplcm8gPC0gY2ZhKG1vZGVsMCwgZGF0YT10ZXN0X2RmKQ0KDQphMyA8LSBhcy5kYXRhLmZyYW1lKGNvcmVfZml0bWVhc3VyZXMoZml0cyR6ZXJvKSkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiRml0IE1lYXN1cmUiKSANCg0KbG9hZGluZ3MgPC0gYXMuZGF0YS5mcmFtZShzdGFuZGFyZGl6ZWRTb2x1dGlvbihmaXRzJHplcm8pKQ0KbG9hZGluZ3MgPC0gZHBseXI6OmZpbHRlcihsb2FkaW5ncywgb3AgPT0gIj1+IikNCg0KYTIgPC0gbG9hZGluZ3MgJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkxhdGVudCBWYXJpYWJsZSIsICJvcCIsICJSYXcgVmFyaWFibGUiLCAiRXN0aW1hdGUgKHN0ZCkiLCAiU0UiLCAieiIsICJwIHZhbHVlIiwgIkNJIChsb3dlcikiLCAiQ0kgKHVwcGVyKSIpLCAgY2FwdGlvbiA9IHBhc3RlMCgiRmFjdG9yIExvYWRpbmdzIGZvciBhIEZvdXIgRmFjdG9yIE1vZGVsLiBDRkk6ICIsIGEzWzUsMl0sICIsIFJNU0VBOiAiLCBhM1s2LDJdLCAiLCBTUk1SOiAiLCBhM1s5LDJdKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpICU+JQ0KICBjb2x1bW5fc3BlYygzLCBib2xkID0gVCwgYm9yZGVyX3JpZ2h0ID0gVCkgJT4lDQogICBjb2x1bW5fc3BlYygyLCBib2xkID0gVCkgJT4lDQogICBjb2x1bW5fc3BlYygxLCBib2xkID0gVCkgDQoNCmthYmxlRXh0cmE6OnJlbW92ZV9jb2x1bW4oa2FibGVfaW5wdXQgPSBhMiwgY29sdW1ucyA9IGMoMiwgNiw3KSkNCg0KbW9kXzQgPC0gZHBseXI6OnNlbGVjdChsb2FkaW5ncywgYygibGhzIiwgInJocyIsICJlc3Quc3RkIikpDQpzdGF0XzQgPC0gYTMNCg0KIyMjIyBmaXZlIGZhY3RvciBtb2RlbCAoYWx0ZXJuYXRpdmUpICMjIyMNCnBvc2l0aXZlIDwtIGRwbHlyOjpzZWxlY3QocGhlbm8sIGMoIlN0dWR5X0lEIiwgIlNBUFNfR2xvYmFsX0hhbHMiLCAgIlNBUFNfR2xvYmFsX0RlbHVzaW9ucyIpKQ0KDQpuZWdhdGl2ZSA8LSBkcGx5cjo6c2VsZWN0KHBoZW5vLCBjKCJTdHVkeV9JRCIsICJTQU5TX0dsb2JhbF9BZmZlY3RpdmVfRmxhdHRlbmluZyIsICAiU0FOU19HbG9iYWxfQWxvZ2lhIiwgICJTQU5TX0dsb2JhbF9BbmhlZG9uaWFfQXNvY2lhbGl0eSIsIlNBTlNfR2xvYmFsX0F2b2xpdGlvbl9BcGF0aHkiKSkNCg0Kb3RoZXJzIDwtIGRwbHlyOjpzZWxlY3QocGhlbm8sIGMoIlN0dWR5X0lEIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU0FQU19HbG9iYWxfUG9zaXRpdmVfVGhvdWdodF9EaXNvcmRlciIsICJTQU5TX0luYXBwcm9wcmlhdGVfQWZmZWN0IiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWk5BQl9NYXplc19JbXAiLCJaSFZMVF9JbXAiLCAiWkJWTVRfSW1wIiwgIlpDUFRfSW1wIiwgIlpTb1BfSW1wIiwgIlpXTV9JbXAiKSkNCg0Kc3ltcHRvbXMgPC0gbGVmdF9qb2luKHBvc2l0aXZlLCBuZWdhdGl2ZSwgYnkgPSAiU3R1ZHlfSUQiKQ0Kc3ltcHRvbXMgPC0gbGVmdF9qb2luKHN5bXB0b21zLCBvdGhlcnMsIGJ5ID0gIlN0dWR5X0lEIikNCg0KdGVzdF9kZiA8LSBsZWZ0X2pvaW4oc3ltcHRvbXMsIGRmLCBieSA9ICJTdHVkeV9JRCIpDQoNCnRlc3RfZGZbLGMoIlNBUFNfR2xvYmFsX0RlbHVzaW9ucyIsIlNBUFNfR2xvYmFsX0hhbHMiLCAiU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmciLCAiU0FOU19HbG9iYWxfQWxvZ2lhIiwgIlNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IiwgICJTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5IiwgDQogICAgICAgICAgIlNBUFNfR2xvYmFsX1Bvc2l0aXZlX1Rob3VnaHRfRGlzb3JkZXIiLCAiU0FOU19JbmFwcHJvcHJpYXRlX0FmZmVjdCINCiAgICAgICAgICAgKV0gPC0NCiAgICAgbGFwcGx5KHRlc3RfZGZbLGMoIlNBUFNfR2xvYmFsX0RlbHVzaW9ucyIsIlNBUFNfR2xvYmFsX0hhbHMiLCAiU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmciLCAiU0FOU19HbG9iYWxfQWxvZ2lhIiwgIlNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IiwgICJTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5IiwgDQogICAgICAgICAgICAgICAgICAgICAgICJTQVBTX0dsb2JhbF9Qb3NpdGl2ZV9UaG91Z2h0X0Rpc29yZGVyIiwgIlNBTlNfSW5hcHByb3ByaWF0ZV9BZmZlY3QiDQogICAgICAgICAgICAgICAgICAgICAgICldLCBvcmRlcmVkKSANCg0KDQptb2RlbDEgPC0gJ3Bvc2l0aXZlID1+IFNBUFNfR2xvYmFsX0hhbHMgKyBTQVBTX0dsb2JhbF9EZWx1c2lvbnMNCiAgICAgICAgICAgZXhwcmVzcyA9fiBTQU5TX0dsb2JhbF9BZmZlY3RpdmVfRmxhdHRlbmluZyArIFNBTlNfR2xvYmFsX0Fsb2dpYSANCiAgICAgICAgICAgbWFuZHAgPX4gIFNBTlNfR2xvYmFsX0F2b2xpdGlvbl9BcGF0aHkgKyBTQU5TX0dsb2JhbF9BbmhlZG9uaWFfQXNvY2lhbGl0eQ0KICAgICAgICAgICBkaXMgPX4gIFNBUFNfR2xvYmFsX1Bvc2l0aXZlX1Rob3VnaHRfRGlzb3JkZXIgKyBTQU5TX0luYXBwcm9wcmlhdGVfQWZmZWN0DQogICAgICAgICAgIGNvZyA9fiBaTkFCX01hemVzX0ltcCArIFpIVkxUX0ltcCArIFpCVk1UX0ltcCArIFpDUFRfSW1wICsgWlNvUF9JbXAgKyBaV01fSW1wJw0KDQpmaXRzJG9uZSA8LSBjZmEobW9kZWwxLCBkYXRhPXRlc3RfZGYpDQoNCmEzIDwtIGFzLmRhdGEuZnJhbWUoY29yZV9maXRtZWFzdXJlcyhmaXRzJG9uZSkpICU+JSByb3duYW1lc190b19jb2x1bW4odmFyID0gIkZpdCBNZWFzdXJlIikgDQoNCmxvYWRpbmdzIDwtIGFzLmRhdGEuZnJhbWUoc3RhbmRhcmRpemVkU29sdXRpb24oZml0cyRvbmUpKQ0KbG9hZGluZ3MgPC0gZHBseXI6OmZpbHRlcihsb2FkaW5ncywgb3AgPT0gIj1+IikNCg0KeGMgPC0gc2VxKG1pbihsb2FkaW5ncyRlc3Quc3RkKSwgbWF4KGxvYWRpbmdzJGVzdC5zdGQpLCBsZW5ndGgub3V0ID0gMTApDQoNCmEyIDwtIGxvYWRpbmdzICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjb2wubmFtZXMgPSBjKCJMYXRlbnQgVmFyaWFibGUiLCAib3AiLCAiUmF3IFZhcmlhYmxlIiwgIkVzdGltYXRlIChzdGQpIiwgIlNFIiwgInoiLCAicCB2YWx1ZSIsICJDSSAobG93ZXIpIiwgIkNJICh1cHBlcikiKSwgY2FwdGlvbiA9IHBhc3RlMCgiRmFjdG9yIExvYWRpbmdzIGZvciB0aGUgRml2ZSBGYWN0b3IgTW9kZWwuIENGSTogIiwgYTNbNSwyXSwgIiwgUk1TRUE6ICIsIGEzWzYsMl0sICIsIFNSTVI6ICIsIGEzWzksMl0pKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgJT4lDQogIGNvbHVtbl9zcGVjKDMsIGJvbGQgPSBULCBib3JkZXJfcmlnaHQgPSBUKSAlPiUNCiAgIGNvbHVtbl9zcGVjKDIsIGJvbGQgPSBUKSAlPiUNCiAgIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUKSANCg0Ka2FibGVFeHRyYTo6cmVtb3ZlX2NvbHVtbihrYWJsZV9pbnB1dCA9IGEyLCBjb2x1bW5zID0gYygyLCA2LDcpKQ0KDQptb2RfNWIgPC0gZHBseXI6OnNlbGVjdChsb2FkaW5ncywgYygibGhzIiwgInJocyIsICJlc3Quc3RkIikpDQpzdGF0XzViIDwtIGEzDQoNCiMjIyMgc2l4IGZhY3RvciBtb2RlbCAjIyMjDQpwb3NpdGl2ZSA8LSBkcGx5cjo6c2VsZWN0KHBoZW5vLCBjKCJTdHVkeV9JRCIsICJTQVBTX0dsb2JhbF9IYWxzIiwgICJTQVBTX0dsb2JhbF9EZWx1c2lvbnMiKSkNCg0KbmVnYXRpdmUgPC0gZHBseXI6OnNlbGVjdChwaGVubywgYygiU3R1ZHlfSUQiLCAiU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmciLCAgIlNBTlNfR2xvYmFsX0Fsb2dpYSIsICAiU0FOU19HbG9iYWxfQW5oZWRvbmlhX0Fzb2NpYWxpdHkiLCJTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5IikpDQoNCm90aGVycyA8LSBkcGx5cjo6c2VsZWN0KHBoZW5vLCBjKCJTdHVkeV9JRCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNBUFNfR2xvYmFsX1Bvc2l0aXZlX1Rob3VnaHRfRGlzb3JkZXIiLCAiU0FOU19JbmFwcHJvcHJpYXRlX0FmZmVjdCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhbGdhcnlfU3VpY2lkZSIsICJDYWxnYXJ5X0RlcHJlc3Npb24iICwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWk5BQl9NYXplc19JbXAiLCJaSFZMVF9JbXAiLCAiWkJWTVRfSW1wIiwgIlpDUFRfSW1wIiwgIlpTb1BfSW1wIiwgIlpXTV9JbXAiKSkNCg0Kc3ltcHRvbXMgPC0gbGVmdF9qb2luKHBvc2l0aXZlLCBuZWdhdGl2ZSwgYnkgPSAiU3R1ZHlfSUQiKQ0Kc3ltcHRvbXMgPC0gbGVmdF9qb2luKHN5bXB0b21zLCBvdGhlcnMsIGJ5ID0gIlN0dWR5X0lEIikNCg0KdGVzdF9kZiA8LSBsZWZ0X2pvaW4oc3ltcHRvbXMsIGRmLCBieSA9ICJTdHVkeV9JRCIpDQoNCnRlc3RfZGZbLGMoIlNBUFNfR2xvYmFsX0RlbHVzaW9ucyIsIlNBUFNfR2xvYmFsX0hhbHMiLCAiU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmciLCAiU0FOU19HbG9iYWxfQWxvZ2lhIiwgIlNBTlNfR2xvYmFsX0FuaGVkb25pYV9Bc29jaWFsaXR5IiwgICJTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5IiwgDQogICAgICAgICAgICJTQVBTX0dsb2JhbF9Qb3NpdGl2ZV9UaG91Z2h0X0Rpc29yZGVyIiwgIlNBTlNfSW5hcHByb3ByaWF0ZV9BZmZlY3QiLA0KICAgICAgICAgICJDYWxnYXJ5X1N1aWNpZGUiLCAiQ2FsZ2FyeV9EZXByZXNzaW9uIg0KICAgICAgICAgICApXSA8LQ0KICAgICBsYXBwbHkodGVzdF9kZlssYygiU0FQU19HbG9iYWxfRGVsdXNpb25zIiwiU0FQU19HbG9iYWxfSGFscyIsICJTQU5TX0dsb2JhbF9BZmZlY3RpdmVfRmxhdHRlbmluZyIsICJTQU5TX0dsb2JhbF9BbG9naWEiLCAiU0FOU19HbG9iYWxfQW5oZWRvbmlhX0Fzb2NpYWxpdHkiLCAgIlNBTlNfR2xvYmFsX0F2b2xpdGlvbl9BcGF0aHkiLCAiU0FQU19HbG9iYWxfUG9zaXRpdmVfVGhvdWdodF9EaXNvcmRlciIsICJTQU5TX0luYXBwcm9wcmlhdGVfQWZmZWN0IiwNCiAgICAgICAgICAgICAgICAgICAgICAgIkNhbGdhcnlfU3VpY2lkZSIsICJDYWxnYXJ5X0RlcHJlc3Npb24iDQogICAgICAgICAgICAgICAgICAgICAgICldLCBvcmRlcmVkKSANCg0KbW9kZWwyIDwtICdwb3NpdGl2ZSA9fiBTQVBTX0dsb2JhbF9IYWxzICsgU0FQU19HbG9iYWxfRGVsdXNpb25zDQogICAgICAgICAgIGV4cHJlc3MgPX4gU0FOU19HbG9iYWxfQWZmZWN0aXZlX0ZsYXR0ZW5pbmcgKyBTQU5TX0dsb2JhbF9BbG9naWEgDQogICAgICAgICAgIG1hbmRwID1+ICBTQU5TX0dsb2JhbF9Bdm9saXRpb25fQXBhdGh5ICsgU0FOU19HbG9iYWxfQW5oZWRvbmlhX0Fzb2NpYWxpdHkNCiAgICAgICAgICAgZGlzID1+ICBTQVBTX0dsb2JhbF9Qb3NpdGl2ZV9UaG91Z2h0X0Rpc29yZGVyICsgU0FOU19JbmFwcHJvcHJpYXRlX0FmZmVjdA0KICAgICAgICAgICBzYWQgPX4gQ2FsZ2FyeV9TdWljaWRlICsgQ2FsZ2FyeV9EZXByZXNzaW9uDQogICAgICAgICAgIGNvZyA9fiBaTkFCX01hemVzX0ltcCArIFpIVkxUX0ltcCArIFpCVk1UX0ltcCArIFpDUFRfSW1wICsgWlNvUF9JbXAgKyBaV01fSW1wJw0KDQpmaXRzJHR3byA8LSBjZmEobW9kZWwyLCBkYXRhPXRlc3RfZGYpDQoNCmEzIDwtIGFzLmRhdGEuZnJhbWUoY29yZV9maXRtZWFzdXJlcyhmaXRzJHR3bykpICU+JSByb3duYW1lc190b19jb2x1bW4odmFyID0gIkZpdCBNZWFzdXJlIikgDQoNCmxvYWRpbmdzIDwtIGFzLmRhdGEuZnJhbWUoc3RhbmRhcmRpemVkU29sdXRpb24oZml0cyR0d28pKQ0KbG9hZGluZ3MgPC0gZHBseXI6OmZpbHRlcihsb2FkaW5ncywgb3AgPT0gIj1+IikNCg0KeGMgPC0gc2VxKG1pbihsb2FkaW5ncyRlc3Quc3RkKSwgbWF4KGxvYWRpbmdzJGVzdC5zdGQpLCBsZW5ndGgub3V0ID0gMTApDQoNCmEyIDwtIGxvYWRpbmdzICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjb2wubmFtZXMgPSBjKCJMYXRlbnQgVmFyaWFibGUiLCAib3AiLCAiUmF3IFZhcmlhYmxlIiwgIkVzdGltYXRlIChzdGQpIiwgIlNFIiwgInoiLCAicCB2YWx1ZSIsICJDSSAobG93ZXIpIiwgIkNJICh1cHBlcikiKSwgY2FwdGlvbiA9IHBhc3RlMCgiRmFjdG9yIExvYWRpbmdzIGZvciBhIFNpeCBGYWN0b3IgTW9kZWwuIENGSTogIiwgYTNbNSwyXSwgIiwgUk1TRUE6ICIsIGEzWzYsMl0sICIsIFNSTVI6ICIsIGEzWzksMl0pKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgJT4lDQogIGNvbHVtbl9zcGVjKDMsIGJvbGQgPSBULCBib3JkZXJfcmlnaHQgPSBUKSAlPiUNCiAgIGNvbHVtbl9zcGVjKDIsIGJvbGQgPSBUKSAlPiUNCiAgIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUKSANCg0Ka2FibGVFeHRyYTo6cmVtb3ZlX2NvbHVtbihrYWJsZV9pbnB1dCA9IGEyLCBjb2x1bW5zID0gYygyLCA2LDcpKQ0KDQoNCmxvYWRpbmdzIDwtIGxvYWRpbmdzICU+JSBkcGx5cjo6c2VsZWN0KGMoImxocyIsICJvcCIsICJyaHMiLCAiZXN0LnN0ZCIsICJzZSIsICJwdmFsdWUiKSkNCmxvYWRpbmdzJHB2YWx1ZSA8LSBmb3JtYXQucHZhbChsb2FkaW5ncyRwdmFsdWUpDQpsb2FkaW5ncyRlc3Quc3RkIDwtIHJvdW5kKGxvYWRpbmdzJGVzdC5zdGQsIDMpDQpsb2FkaW5ncyRzZSA8LSByb3VuZChsb2FkaW5ncyRzZSwgMykNCg0KDQpiYXNlXzYgPC0gZHBseXI6OnNlbGVjdChsb2FkaW5ncywgYygibGhzIiwgInJocyIsICJlc3Quc3RkIikpDQpzdGF0XzYgPC0gYTMNCmBgYA0KDQpgYGB7ciBTVDUgKENGQSBNb2RlbHMpfQ0KYTMgPC0gYXMuZGF0YS5mcmFtZShjb3JlX2ZpdG1lYXN1cmVzKGZpdHMkZm91cikpICU+JSByb3duYW1lc190b19jb2x1bW4odmFyID0gIkZpdCBNZWFzdXJlIikgDQoNCmxvYWRpbmdzIDwtIGFzLmRhdGEuZnJhbWUoc3RhbmRhcmRpemVkU29sdXRpb24oZml0cyRmb3VyKSkNCmxvYWRpbmdzIDwtIGRwbHlyOjpmaWx0ZXIobG9hZGluZ3MsIG9wID09ICI9fiIpDQpsb2FkaW5ncyA8LSBsb2FkaW5ncyAlPiUgZHBseXI6OnNlbGVjdChjKCJsaHMiLCAib3AiLCAicmhzIiwgImVzdC5zdGQiLCAic2UiLCAicHZhbHVlIikpDQpsb2FkaW5ncyRwdmFsdWUgPC0gZm9ybWF0LnB2YWwobG9hZGluZ3MkcHZhbHVlKQ0KbG9hZGluZ3MkZXN0LnN0ZCA8LSByb3VuZChsb2FkaW5ncyRlc3Quc3RkLCAzKQ0KbG9hZGluZ3Mkc2UgPC0gcm91bmQobG9hZGluZ3Mkc2UsIDMpDQoNCg0KbW9kXzVhIDwtIGRwbHlyOjpzZWxlY3QobG9hZGluZ3MsIGMoImxocyIsICJyaHMiLCAiZXN0LnN0ZCIpKQ0Kc3RhdF81YSA8LSBhMyANCg0KDQp0YWIgPC0gZnVsbF9qb2luKGJhc2VfNiwgbW9kXzVhLCBieSA9IGMoImxocyIsICJyaHMiKSkNCnRhYiA8LSBmdWxsX2pvaW4odGFiLCBtb2RfNWIsIGJ5ID0gYygibGhzIiwgInJocyIpKQ0KdGFiIDwtIGZ1bGxfam9pbih0YWIsIG1vZF80LCBieSA9IGMoImxocyIsICJyaHMiKSkNCg0KcmVzdWx0cyA8LSBkYXRhLmZyYW1lKA0KICBWYXJpYWJsZSA9IGNoYXJhY3RlcigpLA0KICBNZWFuID0gbnVtZXJpYygpLA0KICBTRCA9IG51bWVyaWMoKSwNCiAgTWluID0gbnVtZXJpYygpLA0KICBNYXggPSBudW1lcmljKCksDQogIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRQ0KKQ0KDQoNCnN1bV9jb2xzIDwtIHRhYltbMl1dDQoNCiMgTG9vcCB0aHJvdWdoIHRoZSBzcGVjaWZpZWQgY29sdW1ucw0KZm9yIChjb2x1bW5fbmFtZSBpbiBzdW1fY29scykgew0KICBjb2x1bW4gPC0gcGhlbm9bW2NvbHVtbl9uYW1lXV0NCiAgc3RhdHMgPC0gc3VtbWFyeV9zdGF0cyhjb2x1bW4pDQogIG5ld19yb3cgPC0gZGF0YS5mcmFtZSgNCiAgICAgICAgVmFyaWFibGUgPSBjb2x1bW5fbmFtZSwNCiAgICAgICAgTWVhbiA9IHN0YXRzJE1lYW4sDQogICAgICAgIFNEID0gc3RhdHMkU0QsDQogICAgICAgIE1pbiA9IHN0YXRzJE1pbiwNCiAgICAgICAgTWF4ID0gc3RhdHMkTWF4LA0KICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UNCiAgICAgICkNCiAgICAgICMgQXBwZW5kIHRoZSBuZXcgcm93IHRvIHRoZSByZXN1bHRzIGRhdGFmcmFtZQ0KICAgICAgcmVzdWx0cyA8LSByYmluZChyZXN1bHRzLCBuZXdfcm93KQ0KfQ0KDQpjb2xuYW1lcyh0YWIpIDwtIGMoIkxhdGVudCBGYWN0b3IiLCAiVmFyaWFibGUiLCAiTTEgKDYpIiwgIk0yICg1KSIsICJNMyAoNWIpIiwgIk00ICg0KSIpDQoNCmRmIDwtIGxlZnRfam9pbih0YWIsIHJlc3VsdHMsIGJ5ID0gIlZhcmlhYmxlIikNCg0KZGYgPC0gZHBseXI6OnNlbGVjdChkZiwgYygiTGF0ZW50IEZhY3RvciIsICJWYXJpYWJsZSIsICJNZWFuIiwgIlNEIiwgIk1pbiIsICJNYXgiLCAiTTEgKDYpIiwgIk0yICg1KSIsICJNMyAoNWIpIiwgIk00ICg0KSIpKQ0KDQpnb2YgPC0gbGVmdF9qb2luKHN0YXRfNiwgc3RhdF81YSkNCmdvZiA8LSBsZWZ0X2pvaW4oZ29mLCBzdGF0XzViKQ0KZ29mIDwtIGxlZnRfam9pbihnb2YsIHN0YXRfNCkNCg0KY29sbmFtZXMoZ29mKSA8LSBjKCJHb29kbmVzcyBvZiBGaXQgTWVhc3VyZSIsICJNMSIsICJNMiIsICJNMyIsICJNNCIgKQ0KZ29mIDwtIGdvZlstYygxOjQsIDc6OCksXQ0KZ29mJGBHb29kbmVzcyBvZiBGaXQgTWVhc3VyZWAgPC0gdG91cHBlcihnb2YkYEdvb2RuZXNzIG9mIEZpdCBNZWFzdXJlYCkNCg0KZGYgJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBUKSAlPiUNCiAgIGNvbHVtbl9zcGVjKDIsIGJvbGQgPSBULCBib3JkZXJfcmlnaHQgPSBUKSAlPiUNCiAgIGNvbHVtbl9zcGVjKDEsIGJvbGQgPSBUKSANCg0KZ29mICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjYXB0aW9uID0gIlN1cHBsZW1lbnRhcnkgVGFibGUgNS4gU3VtbWFyeSBvZiBmdWxsIENGQSByZXN1bHRzLiBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzIGFyZSBsaXN0ZWQgYWxvbmdzaWRlIGZhY3RvciBsb2FkaW5ncyBmb3IgZWFjaCB2YXJpYWJsZSBvbnRvIGl0cyBsYXRlbnQgZmFjdG9ycyBhY3Jvc3MgdGhlIGZvdXIgY29uc2lkZXJlZCBtb2RlbHMgKE0xIOKAkyBNNCkuIEtleSBmaXQgc3RhdGlzdGljcyBhcmUgbGlzdGVkIGJlbG93LCB3aXRoIHRoZSBiZXN0IGZpdCBoaWdobGlnaHRlZCBpbiByZWQuIE0xIHJlcHJlc2VudHMgdGhlIG1heGltYWwgbW9kZWwgd2l0aCBhbGwgdmFyaWFibGVzIGluY2x1ZGVkLiBNMiByZXByZXNlbnRzIHRoZSBtYXhpbWFsIG1vZGVsIHdpdGhvdXQgdGhlIGRpc29yZ2FuaXNlZCB2YXJpYWJsZXMuIE0zIHJlcHJlc2VudHMgdGhlIG1heGltYWwgbW9kZWwgd2l0aG91dCB0aGUgc3VpY2lkZS9kZXByZXNzaW9uIHZhcmlhYmxlcyAoaS5lLiwgdGhlIDUtZmFjdG9yIG1vZGVsIGFzIGJhc2VkIG9uIExlZ2dlIGV0IGFsLiwgKDIwMjEpKS4gTTQgcmVwcmVzZW50cyB0aGUgbWF4aW1hbCBtb2RlbCB3aXRoIG5laXRoZXIgdGhlIHN1aWNpZGUvZGVwcmVzc2lvbiBub3IgZGlzb3JnYW5pc2VkIGZhY3RvcnMuIEVYQ0wgPSBleGNsdWRlZDsgQ0ZJID0gQ29tcGFyYXRpdmUgRml0IEluZGV4OyBSTVNFQSA9IFJvb3QgTWVhbiBTcXVhcmUgRXJyb3Igb2YgQXBwcm94aW1hdGlvbjsgU1JNUiA9IFN0YW5kYXJkaXNlZCBSb290IE1lYW4gU3F1YXJlIFJlc2lkdWFsLiAgKk1BVFJJQ1MgdmFyaWFibGVzIHdlcmUgaW1wdXRlZCBhbmQgc3RhbmRhcmRpc2VkIGFnYWluc3QgdW5hZmZlY3RlZCBjb250cm9scy4iLCByb3cubmFtZXMgPSBGLCBhbGlnbj1jKCJsIiwgInIiLCAiciIsICJyIiwgInIiKSwgZGlnaXRzID0gMywgZm9ybWF0LmFyZ3MgPSBsaXN0KG5zbWFsbCA9IDMpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgJT4lDQogICAgY29sdW1uX3NwZWMoMywgYm9sZCA9IFQsIGNvbG9yID0gInJlZCIpDQoNCg0KDQoNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCiMjIyBGdWxsIFJlc3VsdHMgey50YWJzZXR9DQojIyMjIE1lZGljYXRpb24gTW9kZWwNCiMjIyMjIEV4dGVuZGVkIFJlc3VsdHMgZm9yIE1hbnVzY3JpcHQgVGFibGUgMS4NCmBgYHtyIFNUNiAoRnVsbCBSZXN1bHRzIC0gTWFpbil9DQojIyMjIGNyZWF0ZSB0YWJsZSAjIyMjDQp0MSA8LSBtYWtlX3RhYihwb3MpDQp0MiA8LSBtYWtlX3RhYihleHApDQp0MyA8LSBtYWtlX3RhYihtYXApDQp0NCA8LSBtYWtlX3RhYihzYWQpDQp0NSA8LSBtYWtlX3RhYihjb2cpDQoNCmYxIDwtIGdldF9maXQocG9zKQ0KZjIgPC0gZ2V0X2ZpdChleHApDQpmMyA8LSBnZXRfZml0KG1hcCkNCmY0IDwtIGdldF9maXQoc2FkKQ0KZjUgPC0gZ2V0X2ZpdChjb2cpDQoNCm1haW5fcmVzIDwtIHJiaW5kKHQxLCB0MiwgdDMsIHQ0LCB0NSkNCmV4dHJhIDwtIGNiaW5kKGYxLCBmMlsyXSwgZjNbMl0sIGY0WzJdLCBmNVsyXSkNCg0KbWFpbl9yZXNfZmRyIDwtIG11dGF0ZShncm91cF9ieShtYWluX3JlcywgUHJlZGljdG9yKSwgRkRSPXAuYWRqdXN0KHAsImZkciIpKQ0KDQptYWluX3Jlc19mZHIkcCA8LSBmb3JtYXRfcChtYWluX3Jlc19mZHIkcCkNCm1haW5fcmVzX2ZkciRGRFIgPC0gZm9ybWF0X3AobWFpbl9yZXNfZmRyJEZEUikNCg0KbWFpbl9yZXNfZmRyJGBwIChGRFIpYCA8LSBwYXN0ZTAobWFpbl9yZXNfZmRyJHAsICIgKCIsIG1haW5fcmVzX2ZkciRGRFIsICIpIikNCm1haW5fcmVzX2ZkciA8LSBkcGx5cjo6c2VsZWN0KG1haW5fcmVzX2ZkciwgLWMoInAiLCAiRkRSIikpDQoNCnRtcCA8LSBzcGxpdChtYWluX3Jlc19mZHIsIGYgPSBtYWluX3Jlc19mZHIkT3V0Y29tZSkgIA0KDQp0MSA8LSBhcy5kYXRhLmZyYW1lKHRtcCRwb3NpdGl2ZVstMV0pIA0KdDIgPC0gYXMuZGF0YS5mcmFtZSh0bXAkZXhwcmVzc1stMV0pDQp0MyA8LSBhcy5kYXRhLmZyYW1lKHRtcCRtYW5kcFstMV0pDQp0NCA8LSBhcy5kYXRhLmZyYW1lKHRtcCRzYWRbLTFdKQ0KdDUgPC0gYXMuZGF0YS5mcmFtZSh0bXAkY29nWy0xXSkNCg0KbWFpbiA8LSBsZWZ0X2pvaW4odDEsIHQyLCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBsZWZ0X2pvaW4obWFpbiwgdDMsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGxlZnRfam9pbihtYWluLCB0NCwgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gZnVsbF9qb2luKG1haW4sIHQ1LCBieSA9ICJQcmVkaWN0b3IiKQ0KDQoNCm1haW4gPC0gbWFpbltjKDEsMiwzLDQsNSwxMywxNCw2LDcsOCw5LDEwLDExLDEyKSxdDQptYWluIDwtIGNvbHVtbl9hc19yb3duYW1lcyhtYWluLCB2YXIgPSAiUHJlZGljdG9yIikNCnJvd25hbWVzKG1haW4pIDwtIGMoIkNQWi1lcSBBbnRpcHN5Y2hvdGljIERvc2UgKG1nL2RheSkiLCAiQ2xvemFwaW5lIChZZXMpIiwgIkFudGljaG9saW5lcmdpYyAoWWVzKSIsICJBZGhlcmVudCAoWWVzKSIsICJTY2hpem9waHJlbmlhIFBHUyIsICJJbnRlbGxpZ2VuY2UgUEdTIiwgIkVkdWNhdGlvbmFsIEF0dGFpbm1lbnQgUEdTIiwgIkFnZSIsICJTZXggKEZlbWFsZSkiLCAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIpDQoNCm1haW4gJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiICkpICU+JSANCiAgIGFkZF9oZWFkZXJfYWJvdmUoaGVhZGVyID0gYyggIiAiID0gMSwgIlBvc2l0aXZlIiA9IDIsICJFeHByZXNzaXZpdHkiID0gMiwgIk1vdGl2YXRpb24gYW5kIFBsZWFzdXJlIiA9IDIsICJTdWljaWRlIGFuZCBEZXByZXNzaW9uIiA9IDIsICJDb2duaXRpb24iID0gMikpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBUKSANCg0KZXh0cmEgJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNhcHRpb24gPSAiU3VwcGxlbWVudGFyeSBUYWJsZSA2LiBBc3NvY2lhdGlvbnMgYmV0d2VlbiBtZWRpY2F0aW9uIHZhcmlhYmxlcyB3aXRoIHNjaGl6b3BocmVuaWEgc3ltcHRvbSBzZXZlcml0eSBhbmQgY29nbml0aXZlIGFiaWxpdHkgZGltZW5zaW9ucyBpbiBDYXJkaWZmQ09HUywgc2hvd2luZyBleHRlbmRlZCByZXN1bHRzIGZyb20gVGFibGUgMSBpbiB0aGUgbWFpbiB0ZXh0LiBTdGFuZGFyZGlzZWQgcmVncmVzc2lvbiBlc3RpbWF0ZXMgYXJlIHJlcG9ydGVkLiBDUFotZXEgPSBjaGxvcnByb21hemluZS1lcXVpdmFsZW50OyBTRSA9IFN0YW5kYXJkIEVycm9yOyBQR1MgPSBQb2x5Z2VuaWMgU2NvcmU7IFBDID0gR2VuZXRpYyBQcmluY2lwYWwgQ29tcG9uZW50LiIsIGNvbC5uYW1lcyA9IE5VTEwsIGFsaWduPWMoImwiLCAiYyIsICJjIiwgImMiLCAiYyIsICJjIiksIGRpZ2l0cyA9IDMsIGZvcm1hdC5hcmdzID0gbGlzdChuc21hbGwgPSAzKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQoNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCiMjIyMgUGhhcm1hY29nZW5vbWljIE1vZGVsDQojIyMjIyBFeHRlbmRlZCBSZXN1bHRzIGZvciBNYW51c2NyaXB0IFRhYmxlIDIuDQoNCmBgYHtyIFNUNyAoRnVsbCBSZXN1bHRzIC0gUEd4KX0NCg0KIyMjIyBjcmVhdGUgdGFibGUgIyMjIw0KdDEgPC0gbWFrZV90YWIocG9zX3BneCkNCnQyIDwtIG1ha2VfdGFiKGV4cF9wZ3gpDQp0MyA8LSBtYWtlX3RhYihtYXBfcGd4KQ0KdDQgPC0gbWFrZV90YWIoc2FkX3BneCkNCnQ1IDwtIG1ha2VfdGFiKGNvZ19wZ3gpDQoNCmYxIDwtIGdldF9maXQocG9zX3BneCkNCmYyIDwtIGdldF9maXQoZXhwX3BneCkNCmYzIDwtIGdldF9maXQobWFwX3BneCkNCmY0IDwtIGdldF9maXQoc2FkX3BneCkNCmY1IDwtIGdldF9maXQoY29nX3BneCkNCg0KbWFpbl9yZXMgPC0gcmJpbmQodDEsIHQyLCB0MywgdDQsIHQ1KQ0KZXh0cmEgPC0gY2JpbmQoZjEsIGYyWzJdLCBmM1syXSwgZjRbMl0sIGY1WzJdKQ0KDQptYWluX3Jlc19mZHIgPC0gbXV0YXRlKGdyb3VwX2J5KG1haW5fcmVzLCBQcmVkaWN0b3IpLCBGRFI9cC5hZGp1c3QocCwiZmRyIikpDQoNCm1haW5fcmVzX2ZkciRwIDwtIGZvcm1hdF9wKG1haW5fcmVzX2ZkciRwKQ0KbWFpbl9yZXNfZmRyJEZEUiA8LSBmb3JtYXRfcChtYWluX3Jlc19mZHIkRkRSKQ0KDQptYWluX3Jlc19mZHIkYHAgKEZEUilgIDwtIHBhc3RlMChtYWluX3Jlc19mZHIkcCwgIiAoIiwgbWFpbl9yZXNfZmRyJEZEUiwgIikiKQ0KbWFpbl9yZXNfZmRyIDwtIGRwbHlyOjpzZWxlY3QobWFpbl9yZXNfZmRyLCAtYygicCIsICJGRFIiKSkNCg0KdG1wIDwtIHNwbGl0KG1haW5fcmVzX2ZkciwgZiA9IG1haW5fcmVzX2ZkciRPdXRjb21lKSAgDQoNCnQxIDwtIGFzLmRhdGEuZnJhbWUodG1wJHBvc2l0aXZlWy0xXSkgDQp0MiA8LSBhcy5kYXRhLmZyYW1lKHRtcCRleHByZXNzWy0xXSkNCnQzIDwtIGFzLmRhdGEuZnJhbWUodG1wJG1hbmRwWy0xXSkNCnQ0IDwtIGFzLmRhdGEuZnJhbWUodG1wJHNhZFstMV0pDQp0NSA8LSBhcy5kYXRhLmZyYW1lKHRtcCRjb2dbLTFdKQ0KDQptYWluIDwtIGxlZnRfam9pbih0MSwgdDIsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGxlZnRfam9pbihtYWluLCB0MywgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gbGVmdF9qb2luKG1haW4sIHQ0LCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBmdWxsX2pvaW4obWFpbiwgdDUsIGJ5ID0gIlByZWRpY3RvciIpDQoNCm1haW4gPC0gY29sdW1uX2FzX3Jvd25hbWVzKG1haW4sIHZhciA9ICJQcmVkaWN0b3IiKQ0KDQptYWluIDwtIG1haW5bYygxLDIsMyw0LDUsNiw3LDgsOSwxMCwxOCwxOSwxMSwxMiwxMywxNCwxNSwxNiwgMTcpLF0gDQoNCnJvd25hbWVzKG1haW4pIDwtIGMoIkNQWi1lcSBBbnRpcHN5Y2hvdGljIERvc2UgKG1nL2RheSkiLCAiQ2xvemFwaW5lIChZZXMpIiwgIkFudGljaG9saW5lcmdpYyAoWWVzKSIsICJDWVAxQTIgQWN0aXZpdHkgU2NvcmUiLCAiQ1lQMkQ2IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDNBNSBBY3Rpdml0eSBTY29yZSIsICJDWVAyQzE5IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDJDOSBBY3Rpdml0eSBTY29yZSIsICJBZGhlcmVudCAoWWVzKSIsICJTY2hpem9waHJlbmlhIFBHUyIsICJJbnRlbGxpZ2VuY2UgUEdTIiwgIkVkdWNhdGlvbmFsIEF0dGFpbm1lbnQgUEdTIiwgIkFnZSIsICJTZXggKEZlbWFsZSkiLCAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIpDQoNCm1haW4gJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiICkpICU+JSANCiAgIGFkZF9oZWFkZXJfYWJvdmUoaGVhZGVyID0gYyggIiAiID0gMSwgIlBvc2l0aXZlIiA9IDIsICJEaW1pbmlzaGVkIEV4cHJlc3Npdml0eSIgPSAyLCAiTW90aXZhdGlvbiBhbmQgUGxlYXN1cmUiID0gMiwgIlN1aWNpZGUgYW5kIERlcHJlc3Npb24iID0gMiwgIkNvZ25pdGlvbiIgPSAyKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQpleHRyYSAlPiUgDQogIGthYmxlKGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRiwgY2FwdGlvbiA9ICJTdXBwbGVtZW50YXJ5IFRhYmxlIDcuIEFzc29jaWF0aW9ucyBiZXR3ZWVuIG1lZGljYXRpb24gYW5kIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgd2l0aCBzY2hpem9waHJlbmlhIHN5bXB0b20gc2V2ZXJpdHkgYW5kIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbnMgaW4gQ2FyZGlmZkNPR1MsIHNob3dpbmcgZXh0ZW5kZWQgcmVzdWx0cyBmcm9tIFRhYmxlIDIgaW4gdGhlIG1haW4gdGV4dC4gU3RhbmRhcmRpc2VkIHJlZ3Jlc3Npb24gZXN0aW1hdGVzIGFyZSByZXBvcnRlZC4gQ1BaLWVxID0gY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudDsgU0UgPSBTdGFuZGFyZCBFcnJvcjsgUEdTID0gUG9seWdlbmljIFNjb3JlOyBQQyA9IEdlbmV0aWMgUHJpbmNpcGFsIENvbXBvbmVudC4iLCBjb2wubmFtZXMgPSBOVUxMLCBhbGlnbj1jKCJsIiwgImMiLCAiYyIsICJjIiwgImMiLCAiYyIpLCBkaWdpdHMgPSAzLCBmb3JtYXQuYXJncyA9IGxpc3QobnNtYWxsID0gMykpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBUKSANCg0KYGBgDQoNCjxicj4NCjxicj4NCg0KIyMjIyBQaGFybWFjb2dlbm9taWMgTW9kZWwgKENsb3phcGluZSBTdWJncm91cCkNCiMjIyMjIEV4dGVuZGVkIFJlc3VsdHMgZm9yIE1hbnVzY3JpcHQgVGFibGUgMy4NCg0KYGBge3IgU1Q4IChGdWxsIFJlc3VsdHMgLSBDbG96YXBpbmUgUEd4KX0NCg0KIyMjIyBjcmVhdGUgdGFibGUgIyMjIw0KdDEgPC0gbWFrZV90YWIoY3Bvc19wZ3gpDQp0MiA8LSBtYWtlX3RhYihjZXhwX3BneCkNCnQzIDwtIG1ha2VfdGFiKGNtYXBfcGd4KQ0KdDQgPC0gbWFrZV90YWIoY3NhZF9wZ3gpDQp0NSA8LSBtYWtlX3RhYihjY29nX3BneCkNCg0KZjEgPC0gZ2V0X2ZpdChjcG9zX3BneCkNCmYyIDwtIGdldF9maXQoY2V4cF9wZ3gpDQpmMyA8LSBnZXRfZml0KGNtYXBfcGd4KQ0KZjQgPC0gZ2V0X2ZpdChjc2FkX3BneCkNCmY1IDwtIGdldF9maXQoY2NvZ19wZ3gpDQoNCm1haW5fcmVzIDwtIHJiaW5kKHQxLCB0MiwgdDMsIHQ0LCB0NSkNCmV4dHJhIDwtIGNiaW5kKGYxLCBmMlsyXSwgZjNbMl0sIGY0WzJdLCBmNVsyXSkNCg0KbWFpbl9yZXNfZmRyIDwtIG11dGF0ZShncm91cF9ieShtYWluX3JlcywgUHJlZGljdG9yKSwgRkRSPXAuYWRqdXN0KHAsImZkciIpKQ0KDQptYWluX3Jlc19mZHIkcCA8LSBmb3JtYXRfcChtYWluX3Jlc19mZHIkcCkNCm1haW5fcmVzX2ZkciRGRFIgPC0gZm9ybWF0X3AobWFpbl9yZXNfZmRyJEZEUikNCg0KbWFpbl9yZXNfZmRyJGBwIChGRFIpYCA8LSBwYXN0ZTAobWFpbl9yZXNfZmRyJHAsICIgKCIsIG1haW5fcmVzX2ZkciRGRFIsICIpIikNCm1haW5fcmVzX2ZkciA8LSBkcGx5cjo6c2VsZWN0KG1haW5fcmVzX2ZkciwgLWMoInAiLCAiRkRSIikpDQoNCnRtcCA8LSBzcGxpdChtYWluX3Jlc19mZHIsIGYgPSBtYWluX3Jlc19mZHIkT3V0Y29tZSkgIA0KDQp0MSA8LSBhcy5kYXRhLmZyYW1lKHRtcCRwb3NpdGl2ZVstMV0pIA0KdDIgPC0gYXMuZGF0YS5mcmFtZSh0bXAkZXhwcmVzc1stMV0pDQp0MyA8LSBhcy5kYXRhLmZyYW1lKHRtcCRtYW5kcFstMV0pDQp0NCA8LSBhcy5kYXRhLmZyYW1lKHRtcCRzYWRbLTFdKQ0KdDUgPC0gYXMuZGF0YS5mcmFtZSh0bXAkY29nWy0xXSkNCg0KbWFpbiA8LSBsZWZ0X2pvaW4odDEsIHQyLCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBsZWZ0X2pvaW4obWFpbiwgdDMsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGxlZnRfam9pbihtYWluLCB0NCwgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gZnVsbF9qb2luKG1haW4sIHQ1LCBieSA9ICJQcmVkaWN0b3IiKQ0KDQptYWluIDwtIGNvbHVtbl9hc19yb3duYW1lcyhtYWluLCB2YXIgPSAiUHJlZGljdG9yIikNCg0KbWFpbiA8LSBtYWluW2MoMSwyLDMsNCw1LDYsNyw4LDksMTcsMTgsIDEwLDExLDEyLDEzLDE0LDE1LDE2KSxdIA0KDQpyb3duYW1lcyhtYWluKSA8LSBjKCJDUFotZXEgQW50aXBzeWNob3RpYyBEb3NlIChtZy9kYXkpIiwgIkFudGljaG9saW5lcmdpYyAoWWVzKSIsICJDWVAxQTIgQWN0aXZpdHkgU2NvcmUiLCAiQ1lQMkQ2IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDNBNSBBY3Rpdml0eSBTY29yZSIsICJDWVAyQzE5IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDJDOSBBY3Rpdml0eSBTY29yZSIsICJBZGhlcmVudCAoWWVzKSIsICJTY2hpem9waHJlbmlhIFBHUyIsICJJbnRlbGxpZ2VuY2UgUEdTIiwgIkVkdWNhdGlvbmFsIEF0dGFpbm1lbnQgUEdTIiwiQWdlIiwgIlNleCAoRmVtYWxlKSIsICJQQzEiLCAiUEMyIiwgIlBDMyIsICJQQzQiLCAiUEM1IikNCg0KbWFpbiAlPiUgDQogIGthYmxlKGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRiwgY29sLm5hbWVzID0gYygiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIsICJFc3RpbWF0ZSAoU0UpIiwgInAgKEZEUikiLCAiRXN0aW1hdGUgKFNFKSIsICJwIChGRFIpIiwgIkVzdGltYXRlIChTRSkiLCAicCAoRkRSKSIgKSkgJT4lIA0KICAgYWRkX2hlYWRlcl9hYm92ZShoZWFkZXIgPSBjKCAiICIgPSAxLCAiUG9zaXRpdmUgKENsb3phcGluZSBTdWJncm91cCkiID0gMiwgIkRpbWluaXNoZWQgRXhwcmVzc2l2aXR5IChDbG96YXBpbmUgU3ViZ3JvdXApIiA9IDIsICJNb3RpdmF0aW9uIGFuZCBQbGVhc3VyZSAoQ2xvemFwaW5lIFN1Ymdyb3VwKSIgPSAyLCAiU3VpY2lkZSBhbmQgRGVwcmVzc2lvbiAoQ2xvemFwaW5lIFN1Ymdyb3VwKSIgPSAyLCAiQ29nbml0aW9uIChDbG96YXBpbmUgU3ViZ3JvdXApIiA9IDIpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQoNCmV4dHJhICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjYXB0aW9uID0gIlN1cHBsZW1lbnRhcnkgVGFibGUgOC4gQXNzb2NpYXRpb25zIGJldHdlZW4gbWVkaWNhdGlvbiBhbmQgcGhhcm1hY29nZW5vbWljIHZhcmlhYmxlcyB3aXRoIHNjaGl6b3BocmVuaWEgc3ltcHRvbSBzZXZlcml0eSBhbmQgY29nbml0aXZlIGFiaWxpdHkgZGltZW5zaW9ucyBpbiBDYXJkaWZmQ09HUyBwYXJ0aWNpcGFudHMgY3VycmVudGx5IHByZXNjcmliZWQgY2xvemFwaW5lLCBzaG93aW5nIGV4dGVuZGVkIHJlc3VsdHMgZnJvbSBUYWJsZSAzIGluIHRoZSBtYWluIHRleHQuIFN0YW5kYXJkaXNlZCByZWdyZXNzaW9uIGVzdGltYXRlcyBhcmUgcmVwb3J0ZWQuIENQWi1lcSA9IGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQ7IFNFID0gU3RhbmRhcmQgRXJyb3I7IFBHUyA9IFBvbHlnZW5pYyBTY29yZTsgUEMgPSBHZW5ldGljIFByaW5jaXBhbCBDb21wb25lbnQuIiwgY29sLm5hbWVzID0gTlVMTCwgYWxpZ249YygibCIsICJjIiwgImMiLCAiYyIsICJjIiwgImMiKSwgZGlnaXRzID0gMywgZm9ybWF0LmFyZ3MgPSBsaXN0KG5zbWFsbCA9IDMpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQoNCmBgYA0KDQo8YnI+DQo8YnI+DQoNCiMjIyBVbmFkanVzdGVkIFBHeCBFc3RpbWF0ZXMNCiMjIyMgVW5hZGp1c3RlZCBlc3RpbWF0ZXMgZm9yIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgaW4gdG90YWwgc2FtcGxlLiANCg0KYGBge3IgdW5pdmFyaWF0ZSB0b3RhbCB9DQpoZWF0X2RhdCA8LSBkcGx5cjo6c2VsZWN0KHRlc3RfZGZfZGltX3N0ZCwgYygicG9zaXRpdmUiLCAiZXhwcmVzcyIsICJtYW5kcCIsICJzYWQiLCAiY29nIiwgIkNZUDFBMl9BUyIsICJDWVAyRDZfQVMiLCAiQ1lQM0E1X0FTIiwgIkNZUDJDMTlfQVMiLCAiQ1lQMkM5X0FTIikpICU+JQ0KICAgZmlsdGVyX2FsbChjb21wbGV0ZS5jYXNlcykNCg0KY29sbmFtZXMoaGVhdF9kYXQpIDwtIGMoIlBvc2l0aXZlIiwgIkV4cHJlc3Npdml0eSIsICJNb3RpdmF0aW9uICYgUGxlYXN1cmUiLCAiU3VpY2lkZSAmIERlcHJlc3Npb24iLCAiQ29nbml0aW9uIiwgIkNZUDFBMiBBUyIsICJDWVAyRDYgQVMiLCAiQ1lQM0E1IEFTIiwgIkNZUDJDMTkgQVMiLCAiQ1lQMkM5IEFTIikNCg0KZGltcyA8LSAgYygiUG9zaXRpdmUiLCAiRXhwcmVzc2l2aXR5IiwgIk1vdGl2YXRpb24gJiBQbGVhc3VyZSIsICJTdWljaWRlICYgRGVwcmVzc2lvbiIsICJDb2duaXRpb24iKQ0KdmFycyA8LSBjKCJDWVAxQTIgQVMiLCAiQ1lQMkQ2IEFTIiwgIkNZUDNBNSBBUyIsICJDWVAyQzE5IEFTIiwgIkNZUDJDOSBBUyIpDQoNCm91dCA8LSBkYXRhLmZyYW1lKERpbWVuc2lvbiA9IE5BLA0KICAgICAgICAgICAgICAgICAgRW56eW1lID0gTkEsDQogICAgICAgICAgICAgICAgICBDb3JyID0gTkEsDQogICAgICAgICAgICAgICAgICBwID0gTkEpDQp0ZXN0IDwtIG91dA0KDQpmb3IgKGkgaW4gZGltcykgew0KICBmb3IgKGogaW4gdmFycyl7DQogICAgeCA8LSBoZWF0X2RhdFtpXQ0KICAgIHkgPC0gaGVhdF9kYXRbal0NCiAgICBzdGF0IDwtIGNvcnIudGVzdCh4LCB5LCBtZXRob2QgPSAicGVhcnNvbiIpDQogICAgdGVzdCREaW1lbnNpb24gPC0gaQ0KICAgIHRlc3QkRW56eW1lIDwtIGoNCiAgICB0ZXN0JENvcnIgPC0gc3RhdCRyDQogICAgdGVzdCRwIDwtIHN0YXQkcA0KICAgIG91dCA8LSByYmluZChvdXQsIHRlc3QpDQogIH0NCn0NCg0Kb3V0IDwtIG5hLm9taXQob3V0KQ0KDQpvdXQkRW56eW1lW291dCRFbnp5bWUgPT0gIkNZUDFBMiBBUyJdIDwtICJDWVAxQTIgQWN0aXZpdHkgU2NvcmUiDQpvdXQkRW56eW1lW291dCRFbnp5bWUgPT0gIkNZUDJENiBBUyJdIDwtICJDWVAyRDYgQWN0aXZpdHkgU2NvcmUiDQpvdXQkRW56eW1lW291dCRFbnp5bWUgPT0gIkNZUDNBNSBBUyJdIDwtICJDWVAzQTUgQWN0aXZpdHkgU2NvcmUiDQpvdXQkRW56eW1lW291dCRFbnp5bWUgPT0gIkNZUDJDMTkgQVMiXSA8LSAiQ1lQMkMxOSBBY3Rpdml0eSBTY29yZSINCm91dCRFbnp5bWVbb3V0JEVuenltZSA9PSAiQ1lQMkM5IEFTIl0gPC0gIkNZUDJDOSBBY3Rpdml0eSBTY29yZSINCg0KbWF0IDwtIG91dFtjKDE6NCldDQoNCm1hdF93aWRlIDwtIHBpdm90X3dpZGVyKG1hdCwgbmFtZXNfZnJvbSA9ICJEaW1lbnNpb24iLCB2YWx1ZXNfZnJvbSA9IGMoIkNvcnIiLCAicCIpKSAlPiUgcmVtb3ZlX3Jvd25hbWVzKCkgJT4lIGNvbHVtbl90b19yb3duYW1lcyh2YXIgPSAiRW56eW1lIikNCg0KbWF0X3dpZGUgPC0gbWF0X3dpZGUgJT4lIGRwbHlyOjpzZWxlY3QoYygiQ29ycl9Qb3NpdGl2ZSIsICJwX1Bvc2l0aXZlIiwgIkNvcnJfRXhwcmVzc2l2aXR5IiwgInBfRXhwcmVzc2l2aXR5IiwgIkNvcnJfTW90aXZhdGlvbiAmIFBsZWFzdXJlIiwgInBfTW90aXZhdGlvbiAmIFBsZWFzdXJlIiwgIkNvcnJfU3VpY2lkZSAmIERlcHJlc3Npb24iLCAicF9TdWljaWRlICYgRGVwcmVzc2lvbiIsICJDb3JyX0NvZ25pdGlvbiIsICJwX0NvZ25pdGlvbiIpKQ0KDQptYXRfd2lkZSAlPiUgDQogIGthYmxlKGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRiwgY2FwdGlvbiA9ICJTdXBwbGVtZW50YXJ5IFRhYmxlIDkuIFVuYWRqdXN0ZWQgZXN0aW1hdGVzIGZvciBwaGFybWFjb2dlbm9taWMgdmFyaWFibGVzIGFnYWluc3Qgc2NoaXpvcGhyZW5pYSBwaGVub3R5cGUgZGltZW5zaW9ucy4gVGFibGUgc2hvd3MgUGVhcnNvbuKAmXMgY29ycmVsYXRpb24gY29lZmZpY2llbnQgYW5kIHAgdmFsdWUgZm9yIGVhY2ggZGltZW5zaW9uLWVuenltZSBwYWlyaW5nLiIsIGNvbC5uYW1lcyA9IGMoInIiLCAicCIsICJyIiwgInAiLCAiciIsICJwIiwgInIiLCAicCIsICJyIiwgInAiKSkgJT4lIA0KICAgYWRkX2hlYWRlcl9hYm92ZShoZWFkZXIgPSBjKCAiICIgPSAxLCAiUG9zaXRpdmUiID0gMiwgIkV4cHJlc3Npdml0eSIgPSAyLCAiTW90aXZhdGlvbiBhbmQgUGxlYXN1cmUiID0gMiwgIlN1aWNpZGUgYW5kIERlcHJlc3Npb24iID0gMiwgIkNvZ25pdGlvbiIgPSAyKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQpgYGANCg0KDQo8YnI+DQo8YnI+DQoNCiMjIyMgVW5hZGp1c3RlZCBlc3RpbWF0ZXMgZm9yIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgaW4gdGhlIHN1Ymdyb3VwIG9mIHBhcnRpY2lwYW50cyBwcmVzY3JpYmVkIGNsb3phcGluZS4NCg0KYGBge3IgdW5pdmFyaWF0ZSBjbG96YXBpbmV9DQpoZWF0X2RhdCA8LSBkcGx5cjo6c2VsZWN0KHRlc3RfZGZfZGltX3N0ZF9jLCBjKCJwb3NpdGl2ZSIsICJleHByZXNzIiwgIm1hbmRwIiwgInNhZCIsICJjb2ciLCAiQ1lQMUEyX0FTIiwgIkNZUDJENl9BUyIsICJDWVAzQTVfQVMiLCAiQ1lQMkMxOV9BUyIsICJDWVAyQzlfQVMiKSkgJT4lDQogICBmaWx0ZXJfYWxsKGNvbXBsZXRlLmNhc2VzKQ0KDQpjb2xuYW1lcyhoZWF0X2RhdCkgPC0gYygiUG9zaXRpdmUiLCAiRXhwcmVzc2l2aXR5IiwgIk1vdGl2YXRpb24gJiBQbGVhc3VyZSIsICJTdWljaWRlICYgRGVwcmVzc2lvbiIsICJDb2duaXRpb24iLCAiQ1lQMUEyIEFTIiwgIkNZUDJENiBBUyIsICJDWVAzQTUgQVMiLCAiQ1lQMkMxOSBBUyIsICJDWVAyQzkgQVMiKQ0KDQpkaW1zIDwtICBjKCJQb3NpdGl2ZSIsICJFeHByZXNzaXZpdHkiLCAiTW90aXZhdGlvbiAmIFBsZWFzdXJlIiwgIlN1aWNpZGUgJiBEZXByZXNzaW9uIiwgIkNvZ25pdGlvbiIpDQp2YXJzIDwtIGMoIkNZUDFBMiBBUyIsICJDWVAyRDYgQVMiLCAiQ1lQM0E1IEFTIiwgIkNZUDJDMTkgQVMiLCAiQ1lQMkM5IEFTIikNCg0Kb3V0IDwtIGRhdGEuZnJhbWUoRGltZW5zaW9uID0gTkEsDQogICAgICAgICAgICAgICAgICBFbnp5bWUgPSBOQSwNCiAgICAgICAgICAgICAgICAgIENvcnIgPSBOQSwNCiAgICAgICAgICAgICAgICAgIHAgPSBOQSkNCnRlc3QgPC0gb3V0DQoNCmZvciAoaSBpbiBkaW1zKSB7DQogIGZvciAoaiBpbiB2YXJzKXsNCiAgICB4IDwtIGhlYXRfZGF0W2ldDQogICAgeSA8LSBoZWF0X2RhdFtqXQ0KICAgIHN0YXQgPC0gY29yci50ZXN0KHgsIHksIG1ldGhvZCA9ICJwZWFyc29uIikNCiAgICB0ZXN0JERpbWVuc2lvbiA8LSBpDQogICAgdGVzdCRFbnp5bWUgPC0gag0KICAgIHRlc3QkQ29yciA8LSBzdGF0JHINCiAgICB0ZXN0JHAgPC0gc3RhdCRwDQogICAgb3V0IDwtIHJiaW5kKG91dCwgdGVzdCkNCiAgfQ0KfQ0KDQpvdXQgPC0gbmEub21pdChvdXQpDQoNCm91dCRFbnp5bWVbb3V0JEVuenltZSA9PSAiQ1lQMUEyIEFTIl0gPC0gIkNZUDFBMiBBY3Rpdml0eSBTY29yZSINCm91dCRFbnp5bWVbb3V0JEVuenltZSA9PSAiQ1lQMkQ2IEFTIl0gPC0gIkNZUDJENiBBY3Rpdml0eSBTY29yZSINCm91dCRFbnp5bWVbb3V0JEVuenltZSA9PSAiQ1lQM0E1IEFTIl0gPC0gIkNZUDNBNSBBY3Rpdml0eSBTY29yZSINCm91dCRFbnp5bWVbb3V0JEVuenltZSA9PSAiQ1lQMkMxOSBBUyJdIDwtICJDWVAyQzE5IEFjdGl2aXR5IFNjb3JlIg0Kb3V0JEVuenltZVtvdXQkRW56eW1lID09ICJDWVAyQzkgQVMiXSA8LSAiQ1lQMkM5IEFjdGl2aXR5IFNjb3JlIg0KDQoNCm1hdCA8LSBvdXRbYygxOjQpXQ0KDQptYXRfd2lkZSA8LSBwaXZvdF93aWRlcihtYXQsIG5hbWVzX2Zyb20gPSAiRGltZW5zaW9uIiwgdmFsdWVzX2Zyb20gPSBjKCJDb3JyIiwgInAiKSkgJT4lIHJlbW92ZV9yb3duYW1lcygpICU+JSBjb2x1bW5fdG9fcm93bmFtZXModmFyID0gIkVuenltZSIpDQoNCm1hdF93aWRlIDwtIG1hdF93aWRlICU+JSBkcGx5cjo6c2VsZWN0KGMoIkNvcnJfUG9zaXRpdmUiLCAicF9Qb3NpdGl2ZSIsICJDb3JyX0V4cHJlc3Npdml0eSIsICJwX0V4cHJlc3Npdml0eSIsICJDb3JyX01vdGl2YXRpb24gJiBQbGVhc3VyZSIsICJwX01vdGl2YXRpb24gJiBQbGVhc3VyZSIsICJDb3JyX1N1aWNpZGUgJiBEZXByZXNzaW9uIiwgInBfU3VpY2lkZSAmIERlcHJlc3Npb24iLCAiQ29ycl9Db2duaXRpb24iLCAicF9Db2duaXRpb24iKSkNCg0KbWF0X3dpZGUgJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNhcHRpb24gPSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxMC4gVW5hZGp1c3RlZCBlc3RpbWF0ZXMgZm9yIHBoYXJtYWNvZ2Vub21pYyB2YXJpYWJsZXMgYWdhaW5zdCBTY2hpem9waHJlbmlhIFBoZW5vdHlwZSBEaW1lbnNpb25zLiBUYWJsZSBzaG93cyBQZWFyc29u4oCZcyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCBhbmQgcCB2YWx1ZSBmb3IgZWFjaCBkaW1lbnNpb24tZW56eW1lIHBhaXJpbmcgZGltZW5zaW9ucyBpbiBDYXJkaWZmQ09HUyBwYXJ0aWNpcGFudHMgY3VycmVudGx5IHByZXNjcmliZWQgY2xvemFwaW5lLiIsIGNvbC5uYW1lcyA9IGMoInIiLCAicCIsICJyIiwgInAiLCAiciIsICJwIiwgInIiLCAicCIsICJyIiwgInAiKSkgJT4lIA0KICAgYWRkX2hlYWRlcl9hYm92ZShoZWFkZXIgPSBjKCAiICIgPSAxLCAiUG9zaXRpdmUiID0gMiwgIkV4cHJlc3Npdml0eSIgPSAyLCAiTW90aXZhdGlvbiBhbmQgUGxlYXN1cmUiID0gMiwgIlN1aWNpZGUgYW5kIERlcHJlc3Npb24iID0gMiwgIkNvZ25pdGlvbiIgPSAyKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQpgYGANCg0KDQo8YnI+DQo8YnI+DQoNCg0KIyMjIFNlbnNpdGl2aXR5IEFuYWx5c2lzOiBQaGVub2NvbnZlcnNpb24NCg0KYGBge3IgY29udmVydCB0byBwaGVub2NvbnZlcnNpb24gY29ycmVjdGVkIGFjdGl2aXR5IHNjb3JlcywgaW5jbHVkZSA9IEZBTFNFfQ0KbWVkcyA8LSBkcGx5cjo6c2VsZWN0KHBoZW5vLCBjKCJTdHVkeV9JRCIsICJBbnRpcHN5Y2hvdGljIiwgImFudGlkZXByZXNzYW50IiwgIk1vb2RfU3RhYmlsaXNlciIsICJCZW56b2RpYXplcGluZSIsICJBbnRpY2hvbGluZXJnaWMiLCAib3RoZXJfbWVkaWNhdGlvbiIsICJDdXJyZW50X3Ntb2tpbmciKSkNCg0KIyMjIyBtZWRpY2F0aW9uIGNvZGUgLSBuYW1lIG1hcHBpbmcgIyMjIw0KcmVjb2RlX3ZlY3RvciA8LSBjKA0KICAiMSIgPSAiYW1pc3VscHJpZGUiLA0KICAiMiIgPSAiYXJpcGlwcmF6b2xlIiwNCiAgIjMiID0gImNobG9ycHJvbWF6aW5lIiwNCiAgIjQiID0gImNsb3phcGluZSIsDQogICI1IiA9ICJmbHVwZW50aGl4b2wiLCANCiAgIjYiID0gImZsdXBlbnRoaXhvbCIsIA0KICAiNyIgPSAiZmx1cGhlbmF6aW5lIiwNCiAgIjgiID0gImZsdXBoZW5hemluZSIsDQogICI5IiA9ICJoYWxvcGVyaWRvbCIsDQogICIxMCIgPSAiaGFsb3Blcmlkb2wiLA0KICAiMTEiID0gImxldm9tZXByb21hemluZSIsDQogICIxMiIgPSAib2xhbnphcGluZSIsDQogICIxMyIgPSAicGVyaWN5YXppbmUiLA0KICAiMTQiID0gInBlcnBoZW5hemluZSIsDQogICIxNSIgPSAicGltb3ppZGUiLA0KICAiMTYiID0gInBpcG90aWF6aW5lIiwNCiAgIjE3IiA9ICJwaXJlbnplcGluZSIsDQogICIxOCIgPSAicHJvY2hsb3JwZXJhemluZSIsDQogICIxOSIgPSAicHJvbWF6aW5lIiwNCiAgIjIwIiA9ICJxdWV0aWFwaW5lIiwNCiAgIjIxIiA9ICJyaXNwZXJpZG9uZSIsDQogICIyMiIgPSAicmlzcGVyaWRvbmUiLA0KICAiMjMiID0gInNlcnRpbmRvbGUiLA0KICAiMjQiID0gInN1bHBpcmlkZSIsDQogICIyNSIgPSAidGhpb3JpZGF6aW5lIiwNCiAgIjI2IiA9ICJ0cmlmbHVvcGVyYXppbmUiLA0KICAiMjciID0gInpvdGVwaW5lIiwNCiAgIjI4IiA9ICJ6dWNsb3BlbnRoaXhvbCIsDQogICIyOSIgPSAienVjbG9wZW50aGl4b2wiLA0KICAiMzAiID0gImFtaXRyaXB0eWxpbmUiLA0KICAiMzEiID0gImFtb3hhcGluZSIsDQogICIzMiIgPSAiY2xvbWlwcmFtaW5lIiwNCiAgIjMzIiA9ICJjaXRhbG9wcmFtIiwNCiAgIjM0IiA9ICJkb3RoaWVwaW4iLA0KICAiMzUiID0gImRveGVwaW4iLA0KICAiMzYiID0gImR1bG94ZXRpbmUiLA0KICAiMzciID0gImVzY2l0YWxvcHJhbSIsDQogICIzOCIgPSAiZmx1b3hldGluZSIsDQogICIzOSIgPSAiZmx1dm94YW1pbmUiLA0KICAiNDAiID0gImltaXByYW1pbmUiLA0KICAiNDEiID0gImlzb2NhcmJveGF6aWQiLA0KICAiNDIiID0gImxvZmVwcmFtaW5lIiwNCiAgIjQzIiA9ICJtYXByb3RpbGluZSIsDQogICI0NCIgPSAibWlhbnNlcmluIiwNCiAgIjQ1IiA9ICJtaXJ0YXphcGluZSIsDQogICI0NiIgPSAibW9jbG9iZW1pZGUiLA0KICAiNDciID0gIm5lZmF6YWRvbmUiLA0KICAiNDgiID0gIm5vcnRyaXB0eWxpbmUiLA0KICAiNDkiID0gInBhcm94ZXRpbmUiLA0KICAiNTAiID0gInBoZW5lbHppbmUiLA0KICAiNTEiID0gInJlYm94ZXRpbmUiLA0KICAiNTIiID0gInNlcnRyYWxpbmUiLA0KICAiNTMiID0gInRyYW55bGN5cHJvbWluZSIsDQogICI1NCIgPSAidHJhem9kb25lIiwNCiAgIjU1IiA9ICJ0cmltaXByYW1pbmUiLA0KICAiNTYiID0gInRyeXB0b3BoYW4iLA0KICAiNTciID0gInZlbmxhZmF4aW5lIiwNCiAgIjU4IiA9ICJjYXJiYW1hemVwaW5lIiwNCiAgIjU5IiA9ICJsYW1vdHJpZ2luZSIsDQogICI2MCIgPSAibGl0aGl1bSBjYXJib25hdGUiLA0KICAiNjEiID0gInNvZGl1bSB2YWxwcm9hdGUiLA0KICAiNjIiID0gInZhbHByb2ljIGFjaWQiLA0KICAiNjMiID0gImFscHJhem9sYW0iLA0KICAiNjQiID0gImJ1c3Bpcm9uZSIsDQogICI2NSIgPSAiY2hsb3JkaWF6ZXBveGlkZSIsDQogICI2NiIgPSAiY2xvYmF6YW0iLA0KICAiNjciID0gImNsb25hemVwYW0iLA0KICAiNjgiID0gImRpYXplcGFtIiwNCiAgIjY5IiA9ICJmbHVyYXplcGFtIiwNCiAgIjcwIiA9ICJsb3ByYXpvbGFtIiwNCiAgIjcxIiA9ICJsb3JhemVwYW0iLA0KICAiNzIiID0gIm1pZGF6b2xhbSIsDQogICI3MyIgPSAibml0cmF6ZXBhbSIsDQogICI3NCIgPSAib3hhemVwYW0iLA0KICAiNzUiID0gInByb3ByYW5vbG9sIiwNCiAgIjc2IiA9ICJ0ZW1hemVwYW0iLA0KICAiNzciID0gInphbGVwbG9uIiwNCiAgIjc4IiA9ICJ6b2xwaWRlbSIsDQogICI3OSIgPSAiem9waWNsb25lIiwNCiAgIjgwIiA9ICJwcm9jeWNsaWRpbmUiLA0KICAiODEiID0gImJlbnp0cm9waW5lIiwNCiAgIjgyIiA9ICJoeW9zY2luZSIsDQogICI4MyIgPSAiYmVuemhleG9sIiwNCiAgIjg0IiA9ICJ0aHlyb3hpbmUiLA0KICAiODUiID0gIm9tZWdhLTMgZmF0dHkgYWNpZHMiLA0KICAiODYiID0gImdhYmFwZW50aW4iLA0KICAiODciID0gInBhbGlwZXJpZG9uZSIsDQogICI4OCIgPSAiYW50aWRlcHJlc3NhbnQsIG5hbWUgdW5rbm93biIsDQogICI4OSIgPSAiYW50aXBzeWNob3RpYywgbmFtZSB1bmtub3duIiwNCiAgIjAiID0gTkEsDQogICI5MCIgPSBOQSwNCiAgIjkxIiA9IE5BDQogICkNCg0KDQoNCiNtZWRzJEN1cnJlbnRfc21va2luZ1tpcy5uYShtZWRzJEN1cnJlbnRfc21va2luZyldIDwtIDk5OQ0KDQpyZWNvZGVfdmVjdG9yMiA8LSBjKA0KICAiMSIgPSAiY2lnYXJldHRlcyIsDQogICIyIiA9IE5BKQ0KDQoNCg0KY29sX25hbWVzIDwtIGNvbG5hbWVzKG1lZHMpDQoNCmRmIDwtIGFzLmRhdGEuZnJhbWUocmVjb2RlX3NlbGVjdGVkX2NvZGVzKGRmID0gbWVkcywgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IsIGNvbHVtbnNfdG9fcmVjb2RlID0gY29sX25hbWVzWzI6N10pKQ0KZGYgPC0gYXMuZGF0YS5mcmFtZShyZWNvZGVfc2VsZWN0ZWRfY29kZXMoZGYgPSBkZiwgcmVjb2RlX3ZlY3RvciA9IHJlY29kZV92ZWN0b3IyLCBjb2x1bW5zX3RvX3JlY29kZSA9IGNvbF9uYW1lc1s4XSkpDQoNCiMjIyMgcGhlbm9jb252ZXJzaW9uIGNvcnJlY3Rpb24gZm9yIGFsbCBlbnp5bWVzICMjIyMNCiMgdXNpbmcgcGhlbm9jb252ZXJ0ZXI6OnBoZW5vY29udmVydCgpDQoNCmRmX3RjIDwtIHRyYW5zZm9ybV9hbmRfY2xlYW4oZGYsIGlkID0gIlN0dWR5X0lEIiwgdmFyaWFibGVfbmFtZXMgPSBjKCJBbnRpcHN5Y2hvdGljIiwgImFudGlkZXByZXNzYW50IiwgIm90aGVyX21lZGljYXRpb24iLCAiQW50aWNob2xpbmVyZ2ljIiwgIkJlbnpvZGlhemVwaW5lIiwgIk1vb2RfU3RhYmlsaXNlciIsICJDdXJyZW50X3Ntb2tpbmciKSkNCiMgYSRzdWJzdGFuY2VfYWxsIDwtIGdzdWIoIiwuKiIsICIiLCBhJHN1YnN0YW5jZV9hbGwpDQoNCnBjX3ByZXAgPC0gbGVmdF9qb2luKHRlc3RfZGZfZGltLCBkcGx5cjo6c2VsZWN0KGRmX3RjLCBjKCJTdHVkeV9JRCIsICJzdWJzdGFuY2VfYWxsIikpLCBieSA9ICJTdHVkeV9JRCIpDQoNCmVuenltZXMgPC0gYygiQ1lQMUEyIiwgIkNZUDJENiIsICJDWVAyQzkiLCAiQ1lQMkMxOSIsICJDWVAzQTUiKQ0KDQpwaGVub2NvbnZlcnRlZCA8LSBkYXRhLmZyYW1lKFN0dWR5X0lEID0gcGNfcHJlcCRTdHVkeV9JRCkNCg0KZm9yIChpIGluIGVuenltZXMpew0KICBwYyA8LSBwaGVub2NvbnZlcnQoaW5wdXRfZGF0YSA9IHBjX3ByZXAsIGlkID0gIlN0dWR5X0lEIiwgZW56eW1lID0gaSwgYWN0aXZpdHlfc2NvcmUgPSBwYXN0ZTAoaSwgIl9BUyIpLCBtZWRpY2F0aW9uID0gInN1YnN0YW5jZV9hbGwiKQ0KICBwaGVub2NvbnZlcnRlZCA8LSBsZWZ0X2pvaW4ocGhlbm9jb252ZXJ0ZWQsIHBjW2MoMSwgbmNvbChwYykpXSwgYnkgPSAiU3R1ZHlfSUQiKQ0KfQ0KDQp0ZXN0X2RmX2RpbV9wYyA8LSBsZWZ0X2pvaW4odGVzdF9kZl9kaW0sIHBoZW5vY29udmVydGVkLCBieSA9ICJTdHVkeV9JRCIpDQoNCiMgcmVtb3ZlIHBlb3BsZSB3aXRoIG5vIHNtb2tpbmcgZGF0YQ0KdGVzdF9kZl9kaW1fcGMkUENfQ1lQMUEyX0FTW2lzLm5hKHRlc3RfZGZfZGltJHNtb2tpbmcpXSA8LSBOQSANCg0KIyBjcmVhdGUgcGhlbm9jb252ZXJzaW9uIGNvcnJlY3RlZCBBUyB1c2luZyBtdXRhdGUNCnRlc3RfZGZfZGltX3BjJGFsdFBDX0NZUDJDMTlfQVMgPC0gaWZlbHNlKHRlc3RfZGZfZGltX3BjJGZsdW94ZXRpbmUgPT0gMSwgdGVzdF9kZl9kaW1fcGMkQ1lQMkMxOV9BUyAqIDAsIHRlc3RfZGZfZGltX3BjJENZUDJDMTlfQVMpDQoNCnRlc3RfZGZfZGltX3BjJGFsdFBDX0NZUDNBNV9BUyA8LSBpZmVsc2UodGVzdF9kZl9kaW1fcGMkY2FyYmFtYXplcGluZSA9PSAxLCB0ZXN0X2RmX2RpbV9wYyRDWVAzQTVfQVMgKiAxLjUsIHRlc3RfZGZfZGltX3BjJENZUDNBNV9BUykNCg0KdGVzdF9kZl9kaW1fcGMkYWx0UENfQ1lQMUEyX0FTIDwtIGlmZWxzZSh0ZXN0X2RmX2RpbV9wYyRzbW9raW5nID09IDEsIHRlc3RfZGZfZGltX3BjJENZUDFBMl9BUyAqIDEuNSwgdGVzdF9kZl9kaW1fcGMkQ1lQMUEyX0FTKQ0KDQojICMgdGVzdCB3aGV0aGVyIHBoZW5vY29udmVyc2lvbnMgbWF0Y2ggd2l0aCB0aG9zZSBjcmVhdGVkIHVzaW5nIHBoZW5vY29udmVydGVyOjpwaGVub2NvbnZlcnQoKSBwYWNrYWdlDQp0ZXN0X2RmX2RpbV9wYyRtYXRjaF8xYTIgPSBpZmVsc2UodGVzdF9kZl9kaW1fcGMkUENfQ1lQMUEyX0FTID09IHRlc3RfZGZfZGltX3BjJGFsdFBDX0NZUDFBMl9BUywgJ09LJywgIlBST0JMRU0iKSANCg0KDQp0ZXN0X2RmX2RpbV9wYyRtYXRjaF8yYzE5ID0gaWZlbHNlKHRlc3RfZGZfZGltX3BjJFBDX0NZUDJDMTlfQVMgPT0gdGVzdF9kZl9kaW1fcGMkYWx0UENfQ1lQMkMxOV9BUywgJ09LJywgIlBST0JMRU0iKSANCg0KDQp0ZXN0X2RmX2RpbV9wYyRtYXRjaF8zYTUgPSBpZmVsc2UodGVzdF9kZl9kaW1fcGMkUENfQ1lQM0E1X0FTID09IHRlc3RfZGZfZGltX3BjJGFsdFBDX0NZUDNBNV9BUywgJ09LJywgIlBST0JMRU0iKSANCg0KYGBgDQoNCg0KYGBge3IgcGhlbm9jb252ZXJzaW9uIGFuYWx5c2VzLCBpbmNsdWRlID0gRkFMU0V9DQoNCiMjIyMgQ1lQMkMxOSBhbmQgZmx1b3hldGluZSAjIyMjDQojIGRhdGEgZHJpdmVuDQpwb3NfcGd4X3BjIDwtIGxtKHBvc2l0aXZlIH4gIGNwel9lcSArIGNsb3phcGluZV9jdXJyZW50ICsgYW50aWNob2xfcHJlc2VudCArIENZUDJDMTlfQVMgKiBmbHVveGV0aW5lICsgQWRoZXJlbmNlX2NvZGVkICsgU1pfUFJTY3MgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCArIFBDMSArIFBDMiArIFBDMyArIFBDNCArIFBDNSwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZCkNCg0KY29lZnM2YSA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShwb3NfcGd4X3BjKSkpIA0KDQojIGNoZWNrIHRoYXQgcGhlbm9jb252ZXJzaW9uIGNvcnJlY3RlZCBhY3Rpdml0eSBzY29yZXMgbWF0Y2ggKGZyb20gcGhlbm9jb252ZXJ0ciB2cyB1c2luZyBtdXRhdGUpDQoNCmNoZWNrIDwtIHVuaXF1ZSh0ZXN0X2RmX2RpbV9wYyRtYXRjaF8yYzE5KQ0KDQppZiAoICEiUFJPQkxFTSIgJWluJSBjaGVjayl7DQogIA0KdGVzdF9kZl9kaW1fcGNfc3RkIDwtIGRhdGF3aXphcmQ6OnN0YW5kYXJkaXNlKHRlc3RfZGZfZGltX3BjKQ0KDQpwb3NfcGd4X3BjYXMgPC0gbG0ocG9zaXRpdmUgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgUENfQ1lQMkMxOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9wY19zdGQpDQoNCmNvZWZzNmFpIDwtIGRhdGEuZnJhbWUoY29lZihzdW1tYXJ5KHBvc19wZ3hfcGNhcykpKSANCn0NCg0KIyMjIyBDWVAzQTUgYW5kIGNhcmJhbWF6ZXBpbmUgIyMjIw0KDQojIG5vdCB1c2luZyBwaGVub2NvbnZlcnNpb24gY29ycmVjdGVkIGFjdGl2aXR5IHNjb3JlcyBmb3IgY3lwM2E1IHRoZXJlZm9yZSBubyBuZWVkIGZvciBjaGVjay4NCiMgZGF0YSBkcml2ZW4gKGZvciBib3RoIGV4cHJlc3Npdml0eSBhbmQgbW90aXZhdGlvbiBhbmQgcGxlYXN1cmUgZGltZW5zaW9uKQ0KDQpleHBfcGd4X3BjIDwtIGxtKGV4cHJlc3MgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQM0E1X0FTICsgY2FyYmFtYXplcGluZSArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCm1hcF9wZ3hfcGMgPC0gbG0obWFuZHAgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQM0E1X0FTICsgY2FyYmFtYXplcGluZSArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCmNvZWZzN2IgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZXhwX3BneF9wYykpKSANCmNvZWZzN2MgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkobWFwX3BneF9wYykpKSANCg0KIyMjIyBDWVAxQTIgYW5kIGNpZ2FyZXR0ZSB1c2UgIyMjIw0KDQojIGRhdGEgZHJpdmVuIA0KY29nX3BneF9wYyA8LSBsbShjb2cgfiAgY3B6X2VxICsgYW50aWNob2xfcHJlc2VudCArIENZUDFBMl9BUyAqIHNtb2tpbmcgKyBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArIEludF9QUlNjcyArIEVBX1BSU2NzICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGRfYykNCg0KY29lZnM4ZSA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShjb2dfcGd4X3BjKSkpIA0KDQpjaGVjayA8LSB1bmlxdWUodGVzdF9kZl9kaW1fcGMkbWF0Y2hfMWEyKQ0KDQojIGNoZWNrIHRoYXQgcGhlbm9jb252ZXJzaW9uIGNvcnJlY3RlZCBhY3Rpdml0eSBzY29yZXMgbWF0Y2ggKGZyb20gcGhlbm9jb252ZXJ0ciB2cyB1c2luZyBtdXRhdGUpIA0KDQppZiAoICEiUFJPQkxFTSIgJWluJSBjaGVjayl7DQp0ZXN0X2RmX2RpbV9wY19zdGRfYyA8LSBkYXRhd2l6YXJkOjpzdGFuZGFyZGlzZSh4ID0gZmlsdGVyKHRlc3RfZGZfZGltX3BjLCBjbG96YXBpbmVfY3VycmVudD09MSkpDQoNCmNvZ19wZ3hfcGNhcyA8LSBsbShjb2cgfiAgY3B6X2VxICsgYW50aWNob2xfcHJlc2VudCArIFBDX0NZUDFBMl9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgSW50X1BSU2NzICsgRUFfUFJTY3MgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCArIFBDMSArIFBDMiArIFBDMyArIFBDNCArIFBDNSwgZGF0YSA9IHRlc3RfZGZfZGltX3BjX3N0ZF9jKQ0KDQpjb2VmczhlaSA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShjb2dfcGd4X3BjYXMpKSkgDQp9DQoNCg0Kc21vIDwtIGFzLmRhdGEuZnJhbWUodGFibGUodGVzdF9kZl9kaW1fc3RkX2Mkc21va2luZywgdXNlTkEgPSAiaWZhbnkiKSkNCg0KYGBgDQoNCiMjIyMgQWNjb3VudGluZyBmb3IgUGhlbm9jb252ZXJzaW9uIHsudGFic2V0fQ0KIyMjIyMgQ1lQMkMxOQ0KIyMjIyMjIENZUDJDMTkgYW5kIEZsdW94ZXRpbmUNCg0KVGhlcmUgd2FzIG5vIGV2aWRlbmNlIG9mIGEgc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGUgQ1lQMkMxOSBhY3Rpdml0eSBzY29yZSBhbmQgZmx1b3hldGluZSB1c2UgICjOsiA9IGByIGNvZWZzNmEkRXN0aW1hdGVbMTZdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQocG9zX3BneF9wYylbMTYsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KHBvc19wZ3hfcGMpWzE2LDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdC5wdmFsKGNvZWZzNmEkUHIuLi50Li5bMTZdLCAyKWApLiBIb3dldmVyLCBDWVAyQzE5IGFjdGl2aXR5IHJlbWFpbmVkIHNpZ25pZmljYW50bHkgYXNzb2NpYXRlZCB3aXRoIHRoZSBwb3NpdGl2ZSBzeW1wdG9tIGRpbWVuc2lvbiAozrIgPSBgciBjb2VmczZhJEVzdGltYXRlWzVdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQocG9zX3BneF9wYylbNSwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQocG9zX3BneF9wYylbNSwyXSwgMilgOyAqcCogPSBgciBmb3JtYXQucHZhbChjb2VmczZhJFByLi4udC4uWzVdLCAyKWApLCBhbmQgZmx1b3hldGluZSB1c2Ugd2FzIGFsc28gaW52ZXJzZWx5IGFzc29jaWF0ZWQgd2l0aCBwb3NpdGl2ZSBkaW1lbnNpb24gc2NvcmVzICjOsiA9IGByIGNvZWZzNmEkRXN0aW1hdGVbNl1gOyA5NSVDSSwgYHIgcm91bmQoY29uZmludChwb3NfcGd4X3BjKVs2LDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChwb3NfcGd4X3BjKVs2LDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdC5wdmFsKGNvZWZzNmEkUHIuLi50Li5bNl0sIDIpYCkuIEEgcGhlbm9jb252ZXJzaW9uLWNvcnJlY3RlZCBDWVAyQzE5IGFjdGl2aXR5IHNjb3JlIHdhcyBub3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBwb3NpdGl2ZSBzeW1wdG9tIGRpbWVuc2lvbiAozrIgPSBgciBjb2VmczZhaSRFc3RpbWF0ZVs1XWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KHBvc19wZ3hfcGNhcylbNSwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQocG9zX3BneF9wY2FzKVs1LDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdC5wdmFsKGNvZWZzNmFpJFByLi4udC4uWzVdLCAyKWApLiBGdWxsIHJlc3VsdHMgYXJlIGF2YWlsYWJsZSBpbiAqKlN1cHBsZW1lbnRhcnkgVGFibGUgMTEqKi4NCg0KYGBge3IgU1Q5IChDWVAyQzE5IFBoZW5vY29udmVyc2lvbikgfQ0KdDEgPC0gbWFrZV90YWIocG9zX3BneF9wYykNCmYxIDwtIGdldF9maXQocG9zX3BneF9wYykNCnQxJHAgPC0gZm9ybWF0X3AodDEkcCkNCg0KdDEgPC0gdDFbLTFdDQoNCnQyIDwtIG1ha2VfdGFiKHBvc19wZ3hfcGNhcykNCmYyIDwtIGdldF9maXQocG9zX3BneF9wY2FzKQ0KdDIkcCA8LSBmb3JtYXRfcCh0MiRwKQ0KDQp0MiA8LSB0MlstMV0NCmV4dHJhIDwtIGNiaW5kKGYxLCBmMlsyXSkNCg0KbWFpbiA8LSBmdWxsX2pvaW4odDEsIHQyLCBieSA9ICJQcmVkaWN0b3IiKQ0KbWFpbiA8LSBjb2x1bW5fYXNfcm93bmFtZXMobWFpbiwgdmFyID0gIlByZWRpY3RvciIpDQoNCnJvd25hbWVzKG1haW4pIDwtIGMoIkNQWi1lcSBBbnRpcHN5Y2hvdGljIERvc2UgKG1nL2RheSkiLCAiQ2xvemFwaW5lIChZZXMpIiwgIkFudGljaG9saW5lcmdpYyAoWWVzKSIsIkNZUDJDMTkgQWN0aXZpdHkgU2NvcmUiLCAiRmx1b3hldGluZSAoWWVzKSIsICJBZGhlcmVudCAoWWVzKSIsICJTY2hpem9waHJlbmlhIFBHUyIsICJBZ2UiLCAiU2V4IChGZW1hbGUpIiwgIlBDMSIsICJQQzIiLCAiUEMzIiwgIlBDNCIsICJQQzUiLCAiQ1lQMkMxOS1GbHVveGV0aW5lIGludGVyYWN0aW9uIiwgIlBoZW5vY29udmVyc2lvbi1Db3JyZWN0ZWQgQ1lQMkMxOSBBY3Rpdml0eSBTY29yZSIpDQoNCm1haW4gPC0gbWFpbltjKDEsMiwzLDQsNSwxNSwxNiw2OjE0KSxdDQoNCm1haW4gJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkVzdGltYXRlIChTRSkiLCAicCIsICJFc3RpbWF0ZSAoU0UpIiwgInAiKSkgJT4lDQogIGFkZF9oZWFkZXJfYWJvdmUoaGVhZGVyID0gYyggIiAiID0gMSwgIlBvc2l0aXZlIC0gRmx1b3hldGluZSBJbnRlcmFjdGlvbiIgPSAyLCAiUG9zaXRpdmUgLSBDb3JyZWN0ZWQgU2NvcmVzIiA9IDIpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQoNCmV4dHJhICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjYXB0aW9uID0gIlN1cHBsZW1lbnRhcnkgVGFibGUgMTEuIFNlbnNpdGl2aXR5IGFuYWx5c2VzIHRvIGFjY291bnQgZm9yIHRoZSBwb3RlbnRpYWwgb2YgZmx1b3hldGluZSB0byBpbmhpYml0IENZUDJDMTkgYWN0aXZpdHkuIFRoaXMgaXMgYWNjb3VudGVkIGZvciB0aHJvdWdoIGEgY29udHJvbCAoZmx1b3hldGluZSB5ZXMvbm8pIGNvdmFyaWF0ZSwgb3IgYnkgaW5jbHVzaW9uIG9mIGEgcGhlbm9jb252ZXJzaW9uIGFjdGl2aXR5IHNjb3JlIChhY3Rpdml0eSBzY29yZSAqIDAgaWYgcGFydGljaXBhbnQgcmVwb3J0cyBmbHVveGV0aW5lKS4gU2Vuc2l0aXZpdHkgYW5hbHlzZXMgd2VyZSBwZXJmb3JtZWQgb25seSBpbiB0aGUgcG9zaXRpdmUgZGltZW5zaW9uIHdoZXJlIGFuIGFzc29jaWF0aW9uIHdpdGggQ1lQMkMxOSB3YXMgcHJldmlvdXNseSBvYnNlcnZlZC4gIiwgY29sLm5hbWVzID0gTlVMTCwgYWxpZ249YygibCIsICJjIiwgImMiLCAiYyIsICJjIiwgImMiKSwgZGlnaXRzID0gMywgZm9ybWF0LmFyZ3MgPSBsaXN0KG5zbWFsbCA9IDMpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQpgYGANCg0KPGJyPg0KPGJyPg0KDQojIyMjIyBDWVAzQTUNCiMjIyMjIyBDWVAzQTUgYW5kIENhcmJhbWF6ZXBpbmUNCg0KVGhlIG51bWJlciBvZiBpbmRpdmlkdWFscyB0YWtpbmcgY2FyYmFtYXplcGluZSB3YXMgdmVyeSBsb3cgKE4gPSBgciAgbnJvdyhmaWx0ZXIodGVzdF9kZl9kaW0sIGNhcmJhbWF6ZXBpbmUgPT0gMSkpYCk7IHRoZXJlZm9yZSwgd2Ugd2VyZSB1bmFibGUgdG8gbW9kZWwgYW4gaW50ZXJhY3Rpb24gYmV0d2VlbiBDWVAzQTUgd2l0aCBDYXJiYW1hemVwaW5lIHVzZS4gRXF1YWxseSwgd2UgZGlkIG5vdCBjYWxjdWxhdGUgcGhlbm9jb252ZXJzaW9uLWNvcnJlY3RlZCBhY3Rpdml0eSBzY29yZXMgYXMgYWxsIGNhcmJhbWF6ZXBpbmUgdXNlcnMgaGFkIG51bGwgZnVuY3Rpb24gYWxsZWxlcyDigJMgdGh1cywgdGhlaXIgYWN0aXZpdHkgc2NvcmVzIHdvdWxkIGhhdmUgYmVlbiB1bmNoYW5nZWQgKGkuZS4sIDAgeCAxLjUgPSAwKS4gVGhlIGFzc29jaWF0aW9ucyBiZXR3ZWVuIENZUDNBNSBhY3Rpdml0eSByZW1haW5lZCB3aXRoIGJvdGggdGhlIGRpbWluaXNoZWQgZXhwcmVzc2l2aXR5ICjOsiA9IGByIGNvZWZzN2IkRXN0aW1hdGVbNV1gOyA5NSVDSSwgYHIgcm91bmQoY29uZmludChleHBfcGd4X3BjKVs1LDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChleHBfcGd4X3BjKVs1LDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdC5wdmFsKGNvZWZzN2IkUHIuLi50Li5bNV0sIDIpYCkgYW5kIHJlZHVjZWQgbW90aXZhdGlvbiBhbmQgcGxlYXN1cmUgZGltZW5zaW9ucyAozrIgPSBgciBjb2VmczdjJEVzdGltYXRlWzVdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQobWFwX3BneF9wYylbNSwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQobWFwX3BneF9wYylbNSwyXSwgMilgOyAqcCogPSBgciBmb3JtYXQucHZhbChjb2VmczdjJFByLi4udC4uWzVdLCAyKWApIGFmdGVyIGFjY291bnRpbmcgZm9yIGNhcmJhbWF6ZXBpbmUgdXNlIHRocm91Z2ggYSBjb3ZhcmlhdGUsIHdoaWNoIHdhcyBpdHNlbGYgbm90IGFzc29jaWF0ZWQgd2l0aCBlaXRoZXIgc3ltcHRvbSBkaW1lbnNpb24uIEZ1bGwgcmVzdWx0cyBhcmUgYXZhaWxhYmxlIGluICoqU3VwcGxlbWVudGFyeSBUYWJsZSAxMioqLg0KDQpgYGB7ciBTVDEwIChDWVAzQTUgUGhlbm9jb252ZXJzaW9uKSB9DQp0MSA8LSBtYWtlX3RhYihleHBfcGd4X3BjKQ0KZjEgPC0gZ2V0X2ZpdChleHBfcGd4X3BjKQ0KdDEkcCA8LSBmb3JtYXRfcCh0MSRwKQ0KDQp0MSA8LSB0MVstMV0NCg0KdDIgPC0gbWFrZV90YWIobWFwX3BneF9wYykNCmYyIDwtIGdldF9maXQobWFwX3BneF9wYykNCnQyJHAgPC0gZm9ybWF0X3AodDIkcCkNCg0KdDIgPC0gdDJbLTFdDQoNCiN0MyA8LSBtYWtlX3RhYihleHBfcGd4X3BjYXMpDQojZjMgPC0gZ2V0X2ZpdChleHBfcGd4X3BjYXMpDQojdDMkcCA8LSBmb3JtYXRfcCh0MyRwKQ0KDQojdDMgPC0gdDNbLTFdDQoNCiN0NCA8LSBtYWtlX3RhYihtYXBfcGd4X3BjYXMpDQojZjQgPC0gZ2V0X2ZpdChtYXBfcGd4X3BjYXMpDQojdDQkcCA8LSBmb3JtYXRfcCh0NCRwKQ0KDQojdDQgPC0gdDRbLTFdDQoNCg0KZXh0cmEgPC0gY2JpbmQoZjEsIGYyWzJdKSAjLCBmM1syXSwgZjRbMl0pDQoNCm1haW4gPC0gZnVsbF9qb2luKHQxLCB0MiwgYnkgPSAiUHJlZGljdG9yIikNCiNtYWluIDwtIGZ1bGxfam9pbihtYWluLCB0MywgYnkgPSAiUHJlZGljdG9yIikNCiNtYWluIDwtIGZ1bGxfam9pbihtYWluLCB0NCwgYnkgPSAiUHJlZGljdG9yIikNCg0KbWFpbiA8LSBjb2x1bW5fYXNfcm93bmFtZXMobWFpbiwgdmFyID0gIlByZWRpY3RvciIpDQoNCnJvd25hbWVzKG1haW4pIDwtIGMoIkNQWi1lcSBBbnRpcHN5Y2hvdGljIERvc2UgKG1nL2RheSkiLCAiQ2xvemFwaW5lIChZZXMpIiwgIkFudGljaG9saW5lcmdpYyAoWWVzKSIsIkNZUDNBNSBBY3Rpdml0eSBTY29yZSIsICJDYXJiYW1hemVwaW5lIChZZXMpIiwgIkFkaGVyZW50IChZZXMpIiwgIlNjaGl6b3BocmVuaWEgUEdTIiwgIkFnZSIsICJTZXggKEZlbWFsZSkiLCAiUEMxIiwgIlBDMiIsICJQQzMiLCAiUEM0IiwgIlBDNSIpDQoNCiNtYWluIDwtIG1haW5bYygxLDIsMyw0LDUsMTUsNjoxNCksXQ0KDQptYWluICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjb2wubmFtZXMgPSBjKCJFc3RpbWF0ZSAoU0UpIiwgInAiLCAiRXN0aW1hdGUgKFNFKSIsICJwIikpICU+JQ0KICBhZGRfaGVhZGVyX2Fib3ZlKGhlYWRlciA9IGMoICIgIiA9IDEsICJEaW1pbmlzaGVkIEV4cHJlc3Npdml0eSAtIENhcmJhbWF6ZXBpbmUgQ292YXJpYXRlIiA9IDIsICJNb3RpdmF0aW9uIGFuZCBQbGVhc3VyZSAtIENhcmJhbWF6ZXBpbmUgQ292YXJpYXRlIiA9IDIpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQoNCmV4dHJhICU+JSANCiAga2FibGUoZm9ybWF0ID0gImh0bWwiLCBlc2NhcGUgPSBGLCBjYXB0aW9uID0gIlN1cHBsZW1lbnRhcnkgVGFibGUgMTIuIFNlbnNpdGl2aXR5IGFuYWx5c2lzIHRvIGFjY291bnQgZm9yIHRoZSBwb3RlbnRpYWwgb2YgY2FyYmFtYXplcGluZSB0byBpbmR1Y2UgQ1lQM0E1IGFjdGl2aXR5LiBUaGlzIGlzIGFjY291bnRlZCBmb3IgdGhyb3VnaCBhIGNvbnRyb2wgKGNhcmJhbWF6ZXBpbmUgeWVzL25vKSBjb3ZhcmlhdGUgZm9yIGJvdGggc3ltcHRvbSBkaW1lbnNpb25zIChpLmUuLCBkaW1pbmlzaGVkIGV4cHJlc3Npdml0eSwgcmVkdWNlZCBtb3RpdmF0aW9uIGFuZCBwbGVhc3VyZSkgd2hlcmUgYW4gYXNzb2NpYXRpb24gd2l0aCBDWVAzQTUgYWN0aXZpdHkgc2NvcmUgd2FzIHByZXZpb3VzbHkgb2JzZXJ2ZWQuIiwgY29sLm5hbWVzID0gTlVMTCwgYWxpZ249YygibCIsICJjIiwgImMiLCAiYyIsICJjIiwgImMiKSwgZGlnaXRzID0gMywgZm9ybWF0LmFyZ3MgPSBsaXN0KG5zbWFsbCA9IDMpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQpgYGANCg0KPGJyPg0KPGJyPg0KDQojIyMjIyBDWVAxQTINCiMjIyMjIyBDWVAxQTIgYW5kIENpZ2FyZXR0ZSBTbW9raW5nDQoNCldlIHNhdyBubyBzaWduaWZpY2FudCBpbnRlcmFjdGlvbiBiZXR3ZWVuIHRoZSBDWVAxQTIgYWN0aXZpdHkgc2NvcmUgYW5kIGNpZ2FyZXR0ZSB1c2UgICjOsiA9IGByIGNvZWZzOGUkRXN0aW1hdGVbMTddYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoY29nX3BneF9wYylbMTcsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KGNvZ19wZ3hfcGMpWzE3LDJdLCAyKWA7ICpwKiA9IGByIGZvcm1hdC5wdmFsKGNvZWZzOGUkUHIuLi50Li5bMTddLCAyKWApLiBDaWdhcmV0dGUgc21va2luZyB3YXMgaW52ZXJzZWx5IGFzc29jaWF0ZWQgd2l0aCBjb2duaXRpb24gKM6yID0gYHIgY29lZnM4ZSRFc3RpbWF0ZVs1XWA7IDk1JUNJLCBgciByb3VuZChjb25maW50KGNvZ19wZ3hfcGMpWzUsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KGNvZ19wZ3hfcGMpWzUsMl0sIDIpYDsgKnAqID0gYHIgZm9ybWF0LnB2YWwoY29lZnM4ZSRQci4uLnQuLls1XSwgMilgKTsgaG93ZXZlciwgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gQ1lQMUEyIGFjdGl2aXR5IGFuZCBjb2duaXRpdmUgYWJpbGl0eSB3ZWFrZW5lZCAozrIgPSBgciBjb2VmczhlJEVzdGltYXRlWzRdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoY29nX3BneF9wYylbNCwxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoY29nX3BneF9wYylbNCwyXSwgMilgOyAqcCogPSBgciBmb3JtYXQucHZhbChjb2VmczhlJFByLi4udC4uWzRdLCAyKWApLiBGaW5hbGx5LCB3ZSBvYnNlcnZlZCBubyBzaWduaWZpY2FudCBhc3NvY2lhdGlvbiBiZXR3ZWVuIHBoZW5vY29udmVyc2lvbi1jb3JyZWN0ZWQgQ1lQMUEyIGFjdGl2aXR5IHNjb3JlcyBhbmQgY29nbml0aW9uICjOsiA9IGByIGNvZWZzOGVpJEVzdGltYXRlWzRdYDsgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoY29nX3BneF9wY2FzKVs0LDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChjb2dfcGd4X3BjYXMpWzQsMl0sIDIpYDsgKnAqID0gYHIgZm9ybWF0LnB2YWwoY29lZnM4ZWkkUHIuLi50Li5bNF0sIDIpYCkuIEZ1bGwgcmVzdWx0cyBhcmUgaW4gKipTdXBwbGVtZW50YXJ5IFRhYmxlIDEzKiouDQoNClRoZSAqcCogdmFsdWUgZm9yIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIENZUDFBMiBhY3Rpdml0eSBzY29yZSBhbmQgY29nbml0aW9uIGJlY2FtZSBsYXJnZXIgYWZ0ZXIgY29udHJvbGxpbmcgZm9yIHNtb2tpbmcgc3RhdHVzLCBzdWdnZXN0aW5nIHRoYXQgcGFydCBvZiB0aGUgdmFyaWFuY2UgaW4gY29nbml0aW9uIGV4cGxhaW5lZCBieSBDWVAxQTIgaXMgZHVlIHRvIHRoZSBpbmR1Y3RpdmUgZWZmZWN0IG9mIGNpZ2FyZXR0ZSBzbW9raW5nLiBIb3dldmVyLCBpbmZvcm1hdGlvbiByZWdhcmRpbmcgcGF0aWVudCBzbW9raW5nIHN0YXR1cyB3YXMgYWJzZW50IGZvciBqdXN0IHVuZGVyIDEwJSBvZiB0aGUgb3JpZ2luYWwgc3ViZ3JvdXAgKE4gPSBgciBzbW8kRnJlcVszXWApLiBUaGUgYXR0ZW51YXRpb24gb2YgdGhlIENZUDFBMi1jb2duaXRpb24gYXNzb2NpYXRpb24gY291bGQgYmUgZXhwbGFpbmVkIGluIHBhcnQgYnkgdGhpcyBsb3NzIG9mIHN0YXRpc3RpY2FsIHBvd2VyLiBXZSBub3RlIHRoYXQgdGhlIG5lZ2F0aXZlIGFzc29jaWF0aW9uIGJldHdlZW4gY2lnYXJldHRlIHNtb2tpbmcsIGFuZCBjb2duaXRpb24gaXMgc29tZXdoYXQgY29udHJhcnkgdG8gZXhwZWN0YXRpb25zLiBDaWdhcmV0dGUgc21va2UgaXMgYSBrbm93biBDWVAxQTIgaW5kdWNlciwgYmluZGluZyB3aXRoIGFyeWwgaHlkcm9jYXJib24gcmVjZXB0b3JzIGFuZCByZXN1bHRpbmcgaW4gaW5jcmVhc2VkIGVuenltZSBhY3Rpdml0eV4xNF4uIEhvd2V2ZXIsIGNocm9uaWMgc21va2luZyBpcyBhbHNvIHJvYnVzdGx5IGFzc29jaWF0ZWQgd2l0aCBjb2duaXRpdmUgaW1wYWlybWVudF4xNV4uIFRoZXJlZm9yZSwgc21va2luZyBtYXkgYmUgZXhlcnRpbmcgZHVhbCwgY29udHJhZGljdG9yeSBlZmZlY3RzIG9uIGNvZ25pdGlvbiBpbiBvdXIgc2FtcGxlOyBhIGxhcmdlciwgaW52ZXJzZSBkaXJlY3QgZWZmZWN0LCBhbmQgYSBtb3JlIG1vZGVzdCBpbmRpcmVjdCwgcG9zaXRpdmUgZWZmZWN0IHRocm91Z2ggaW5kdWN0aW9uIG9mIENZUDFBMiBhY3Rpdml0eS4gDQoNCg0KDQpgYGB7ciBTVDExIChDWVAxQTIgUGhlbm9jb252ZXJzaW9uKX0NCnQxIDwtIG1ha2VfdGFiKGNvZ19wZ3hfcGMpDQpmMSA8LSBnZXRfZml0KGNvZ19wZ3hfcGMpDQp0MSRwIDwtIGZvcm1hdF9wKHQxJHApDQoNCnQxIDwtIHQxWy0xXQ0KDQp0MiA8LSBtYWtlX3RhYihjb2dfcGd4X3BjYXMpDQpmMiA8LSBnZXRfZml0KGNvZ19wZ3hfcGNhcykNCnQyJHAgPC0gZm9ybWF0X3AodDIkcCkNCg0KdDIgPC0gdDJbLTFdDQpleHRyYSA8LSBjYmluZChmMSwgZjJbMl0pDQoNCm1haW4gPC0gZnVsbF9qb2luKHQxLCB0MiwgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gY29sdW1uX2FzX3Jvd25hbWVzKG1haW4sIHZhciA9ICJQcmVkaWN0b3IiKQ0KDQpyb3duYW1lcyhtYWluKSA8LSBjKCJDUFotZXEgQW50aXBzeWNob3RpYyBEb3NlIChtZy9kYXkpIiwgIkFudGljaG9saW5lcmdpYyAoWWVzKSIsIkNZUDFBMiBBY3Rpdml0eSBTY29yZSIsICJDaWdhcmV0dGVzIChZZXMpIiwgIkFkaGVyZW50IChZZXMpIiwgIlNjaGl6b3BocmVuaWEgUEdTIiwgIkludGVsbGlnZW5jZSBQR1MiLCAiRWR1Y2F0aW9uYWwgQXR0YWlubWVudCBQR1MiLCAiQWdlIiwgIlNleCAoRmVtYWxlKSIsICJQQzEiLCAiUEMyIiwgIlBDMyIsICJQQzQiLCAiUEM1IiwgIkNZUDFBMi1TbW9raW5nIGludGVyYWN0aW9uIiwgIlBoZW5vY29udmVyc2lvbi1Db3JyZWN0ZWQgQ1lQMUEyIEFjdGl2aXR5IFNjb3JlIikNCg0KbWFpbiA8LSBtYWluW2MoMSwyLDMsNCwxNiwxNyw1OjE1KSxdDQoNCm1haW4gJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkVzdGltYXRlIChTRSkiLCAicCIsICJFc3RpbWF0ZSAoU0UpIiwgInAiKSkgJT4lDQogIGFkZF9oZWFkZXJfYWJvdmUoaGVhZGVyID0gYyggIiAiID0gMSwgIkNvZ25pdGlvbiAoQ2xvemFwaW5lIFN1Ymdyb3VwKSAtIFNtb2tpbmcgSW50ZXJhY3Rpb24iID0gMiwgIkNvZ25pdGlvbiAoQ2xvemFwaW5lIFN1Ymdyb3VwKSAtIENvcnJlY3RlZCBTY29yZXMiID0gMikpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBUKSANCg0KZXh0cmEgJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNhcHRpb24gPSAiU3VwcGxlbWVudGFyeSBUYWJsZSAxMy4gU2Vuc2l0aXZpdHkgYW5hbHlzaXMgdG8gYWNjb3VudCBmb3IgdGhlIHBvdGVudGlhbCBvZiBzbW9raW5nIHRvIGluZmx1ZW5jZSBDWVAxQTIgYWN0aXZpdHkuIFRoaXMgaXMgYWNjb3VudGVkIGZvciB0aHJvdWdoIGEgY29udHJvbCAoc21va2luZyB5ZXMvbm8pIGNvdmFyaWF0ZSwgb3IgYnkgaW5jbHVzaW9uIG9mIGEgcGhlbm9jb252ZXJzaW9uIGFjdGl2aXR5IHNjb3JlIChhY3Rpdml0eSBzY29yZSAqIDEuNSBpZiBwYXJ0aWNpcGFudCBpcyBhIHNtb2tlcikuIFNlbnNpdGl2aXR5IGFuYWx5c2VzIHdlcmUgcGVyZm9ybWVkIG9ubHkgaW4gdGhlIGNvZ25pdGl2ZSBkaW1lbnNpb24gd2hlcmUgYW4gYXNzb2NpYXRpb24gd2l0aCBDWVAxQTIgYWN0aXZpdHkgc2NvcmUgd2FzIHByZXZpb3VzbHkgb2JzZXJ2ZWQuIiwgY29sLm5hbWVzID0gTlVMTCwgYWxpZ249YygibCIsICJjIiwgImMiLCAiYyIsICJjIiwgImMiKSwgZGlnaXRzID0gMywgZm9ybWF0LmFyZ3MgPSBsaXN0KG5zbWFsbCA9IDMpKSAlPiUNCiAga2FibGVfY2xhc3NpYyhmdWxsX3dpZHRoID0gVCkgDQpgYGANCg0KPGJyPg0KPGJyPg0KDQojIyMgQWx0ZXJuYXRpdmUgQW5hbHlzaXM6IFByZW1vcmJpZCBJUQ0KIyMjIyBFeHBsb3JpbmcgTWVhc3VyZXMgb2YgUHJlbW9yYmlkIEludGVsbGlnZW5jZQ0KIyMjIyMgQ29tcGFyaXNvbiBvZiBwcmVtb3JiaWQgaW50ZWxsaWdlbmNlIG1lYXN1cmVzDQoNCmBgYHtyIG5hcnQgYW5hbHlzZXN9DQojIG1vZGVscyBmb3IgY3VycmVudCBjb2duaXRpb24NCm5hcnRfY29nIDwtIGxtKGNvZyB+ICBOQVJUSVEgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZCkNCmpvaW50X2NvZyA8LSBsbShjb2cgfiBJbnRfUFJTY3MgKyBFQV9QUlNjcyArIEFnZV9hdF9JbnRlcnZpZXcgICsgU2V4LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQoNCiMgbGluZWFyIG1vZGVscyB0ZXN0aW5nIHdoZXRoZXIgb3VyIGludGVsbGlnZW5jZSBtZWFzdXJlcyAoSVEgUFJTIGFuZCBOQVJUSVEpIGFyZSBhc3NvY2lhdGVkIHdpdGggbWVkaWNhdGlvbiB2YXJpYWJsZXMNCmRfbmFydCA8LSBsbShjcHpfZXEgfiBOQVJUSVEgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZCkNCmRfam9pbnQgPC0gbG0oY3B6X2VxIH4gSW50X1BSU2NzICsgRUFfUFJTY3MgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZCkNCg0KY29lZnM1YSA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShuYXJ0X2NvZykpKQ0KY29lZnM1YiA8LSBkYXRhLmZyYW1lKGNvZWYoc3VtbWFyeShqb2ludF9jb2cpKSkgDQpjb2VmczVjIDwtIGRhdGEuZnJhbWUoY29lZihzdW1tYXJ5KGRfbmFydCkpKSANCmNvZWZzNWQgPC0gZGF0YS5mcmFtZShjb2VmKHN1bW1hcnkoZF9qb2ludCkpKSANCg0KDQpgYGANCg0KUHJlbW9yYmlkIGludGVsbGlnZW5jZSBhcyBlc3RpbWF0ZWQgYnkgdGhlIE5BUlQgaGFkIGEgc3Ryb25nZXIgYXNzb2NpYXRpb24gd2l0aCB0aGUgY29nbml0aXZlIGFiaWxpdHkgZGltZW5zaW9uICjOsiA9IGByIGNvZWZzNWFbMiwxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQobmFydF9jb2cpWzIsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KG5hcnRfY29nKVsyLDJdLCAyKWA7ICpwKiA9ICBgciBmb3JtYXRfcChjb2VmczVhWzIsNF0pYCksIGNvbXBhcmVkIHRvIHRoZSBpbnRlbGxpZ2VuY2UgUEdTICjOsiA9IGByIGNvZWZzNWJbMiwxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoam9pbnRfY29nKVsyLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChqb2ludF9jb2cpWzIsMl0sIDIpYDsgKnAqID0gIGByIGZvcm1hdF9wKGNvZWZzNWJbMiw0XSlgKSBhbmQgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCBQR1MgKM6yID0gYHIgY29lZnM1YlszLDFdIGA7ICA5NSVDSSwgYHIgcm91bmQoY29uZmludChqb2ludF9jb2cpWzMsMV0sIDIpYCB0byBgciByb3VuZChjb25maW50KGpvaW50X2NvZylbMywyXSwgMilgOyAqcCogPSAgYHIgZm9ybWF0X3AoY29lZnM1YlszLDRdKWApLg0KDQpIb3dldmVyLCB3ZSBhbHNvIGZvdW5kIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2UgYXMgZXN0aW1hdGVkIGJ5IHRoZSBOQVJUIHdhcyBpbnZlcnNlbHkgYXNzb2NpYXRlZCB3aXRoIGNobG9ycHJvbWF6aW5lLWVxdWl2YWxlbnQgYW50aXBzeWNob3RpYyBkb3NlICjOsiA9IGByIGNvZWZzNWNbMiwxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoZF9uYXJ0KVsyLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChkX25hcnQpWzIsMl0sIDIpYDsgKnAqID0gIGByIGZvcm1hdF9wKGNvZWZzNWNbMiw0XSlgKSB3aGVyZWFzIHRoZXJlIHdhcyBubyBzdWNoIGFzc29jaWF0aW9uIHdpdGggZG9zZSBmb3IgZWl0aGVyIGludGVsbGlnZW5jZSBQR1MgKM6yID0gYHIgY29lZnM1ZFsyLDFdIGA7ICA5NSVDSSwgYHIgcm91bmQoY29uZmludChkX2pvaW50KVsyLDFdLCAyKWAgdG8gYHIgcm91bmQoY29uZmludChkX2pvaW50KVsyLDJdLCAyKWA7ICpwKiA9ICBgciBmb3JtYXRfcChjb2VmczVkWzIsNF0pYCkgb3IgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCBQR1MgICjOsiA9IGByIGNvZWZzNWRbMywxXSBgOyAgOTUlQ0ksIGByIHJvdW5kKGNvbmZpbnQoZF9qb2ludClbMywxXSwgMilgIHRvIGByIHJvdW5kKGNvbmZpbnQoZF9qb2ludClbMywyXSwgMilgOyAqcCogPSAgYHIgZm9ybWF0X3AoY29lZnM1ZFszLDRdKWApLg0KDQpUaGUgcmVzdWx0cyBjb3VsZCBpbmRpY2F0ZSB0aGF0IHBhcnRpY2lwYW50cyB3aXRoIGxvd2VyIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2Ugc2NvcmVzIGZyb20gdGhlIE5BUlQgd2VyZSBwcmVzY3JpYmVkIGhpZ2hlciBhbnRpcHN5Y2hvdGljIGRvc2VzLiBBbiBhbHRlcm5hdGl2ZSBpbnRlcnByZXRhdGlvbiBpcyB0aGF0IHBlcmZvcm1hbmNlIG9uIHRoZSBOQVJUIHdhcyBhZmZlY3RlZCBieSB0aGUgcGFydGljaXBhbnTigJlzIGFudGlwc3ljaG90aWMgZG9zZSAoaS5lLiBzZWRhdGlvbiBlZmZlY3RzKSBhbmQgdGhlcmVmb3JlLCBtaWdodCBub3QgZnVsbHkgcmVmbGVjdCBwcmUtbW9yYmlkIGludGVsbGlnZW5jZSBpbiB0aGlzIHNhbXBsZV4xNl4uIEFzIHdlIHdlcmUgbm90IGFibGUgdG8gZGlzdGluZ3Vpc2ggYmV0d2VlbiB0aGVzZSBwb3RlbnRpYWwgY29uZm91bmRpbmcgZWZmZWN0cywgd2Ugc2VsZWN0ZWQgdG8gdXNlIGJvdGggaW50ZWxsaWdlbmNlIGFuZCBlZHVjYXRpb25hbCBQR1MgYXMgdGhlIGVzdGltYXRlcyBvZiBwcmVtb3JiaWQgaW50ZWxsaWdlbmNlIGluIG91ciBwcmltYXJ5IGFuYWx5c2VzLiBIb3dldmVyLCB3ZSBoYXZlIGNvbmR1Y3RlZCBzZWNvbmRhcnkgYW5hbHlzZXMgY29udHJvbGxpbmcgZm9yIHRoZSBOQVJULCBzaG93biBiZWxvdy4gDQoNCjxicj4NCg0KIyMjIyMgQWx0ZXJuYXRpdmUgYW5hbHlzZXMgY29udHJvbGxpbmcgZm9yIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2UgYXMgZXN0aW1hdGVkIGJ5IE5BUlQNClRoaXMgc2Vjb25kYXJ5IGFuYWx5c2lzIGNvbnRyb2xzIGZvciBwcmVtb3JiaWQgaW50ZWxsaWdlbmNlIGFzIGVzdGltYXRlZCBieSB0aGUgTkFSVCwgaW5zdGVhZCBvZiBQR1MgZm9yIGludGVsbGlnZW5jZSBhbmQgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCwgaW4gYW5hbHlzZXMgd2hlcmUgdGhlIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbiBpcyB0aGUgb3V0Y29tZS4gUmVzdWx0cyBhcmUgcHJlc2VudGVkIGluICoqU3VwcGxlbWVudGFyeSBUYWJsZSAxNCoqLiBOQVJUIGRhdGEgd2FzIG5vdCBhdmFpbGFibGUgZm9yIGFsbCBwYXJ0aWNpcGFudHMgaW4gdGhlIGZ1bGwgc2FtcGxlIChOID0gYHIgYXMuZGF0YS5mcmFtZSh0YWJsZShpcy5uYSh0ZXN0X2RmX2RpbV9zdGQkTkFSVElRKSkpWzIsMl1gKSBhbmQgdGhvc2UgcHJlc2NyaWJlZCBjbG96YXBpbmUgKE4gPSBgciBhcy5kYXRhLmZyYW1lKHRhYmxlKGlzLm5hKHRlc3RfZGZfZGltX3N0ZF9jJE5BUlRJUSkpKVsyLDJdYCk7IGhlbmNlLCB0aGVzZSBhbmFseXNlcyBoYXZlIGEgbG93ZXIgc2FtcGxlIHNpemUgdGhhbiB0aG9zZSByZXBvcnRlZCBpbiB0aGUgbWFpbiB0ZXh0Lg0KDQpUaGUgYXNzb2NpYXRpb25zIGJldHdlZW4gYW50aXBzeWNob3RpYyBkb3NlLCBjbG96YXBpbmUgdXNlLCBhbmQgYW50aWNob2xpbmVyZ2ljIHVzZSB3aXRoIGNvZ25pdGl2ZSBhYmlsaXR5IHJlbWFpbmVkIHNpZ25pZmljYW50IHdoZW4gaW5jbHVkaW5nIE5BUlQgaW4gdGhlIG1vZGVscywgZGVzcGl0ZSBhbiBhdHRlbnVhdGlvbiBpbiB0aGUgc3RyZW5ndGggb2YgZWZmZWN0IHNpemVzIGFuZCBwLXZhbHVlcy4gIEhvd2V2ZXIsIGluIHRoZSBwaGFybWFjb2dlbm9taWMgbW9kZWwgaW5jbHVkaW5nIG9ubHkgcGF0aWVudHMgcHJlc2NyaWJlZCBjbG96YXBpbmUsIGNvdmFyeWluZyBmb3IgTkFSVCByZWR1Y2VkIHRoZSBlZmZlY3Qgc2l6ZSBmb3IgdGhlIGFzc29jaWF0aW9ucyBvZiBjb2duaXRpdmUgYWJpbGl0eSB3aXRoIGFudGljaG9saW5lcmdpYyB1c2UgYW5kIENZUDFBMiBhY3Rpdml0eSBzY29yZSwgcmVuZGVyaW5nIHRoZWlyIHAtdmFsdWVzIG5vbi1zaWduaWZpY2FudC4NCg0KYGBge3IgbmFydCByZXN1bHRzfQ0KbmNvZyA8LSBsbShjb2cgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgTkFSVElRICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggICsgUEMxICsgUEMyICsgUEMzICsgUEM0ICsgUEM1LCBkYXRhID0gdGVzdF9kZl9kaW1fc3RkKQ0KDQpuY29nX3BneCA8LSBsbShjb2cgfiAgY3B6X2VxICsgY2xvemFwaW5lX2N1cnJlbnQgKyBhbnRpY2hvbF9wcmVzZW50ICsgQ1lQMUEyX0FTICsgQ1lQMkQ2X0FTICsgQ1lQM0E1X0FTICsgQ1lQMkMxOV9BUyArIENZUDJDOV9BUyArIEFkaGVyZW5jZV9jb2RlZCArIFNaX1BSU2NzICsgTkFSVElRICsgQWdlX2F0X0ludGVydmlldyAgKyBTZXggKyBQQzEgKyBQQzIgKyBQQzMgKyBQQzQgKyBQQzUsIGRhdGEgPSB0ZXN0X2RmX2RpbV9zdGQpDQoNCm5jY29nX3BneCA8LSBsbShjb2cgfiAgY3B6X2VxICsgYW50aWNob2xfcHJlc2VudCArIENZUDFBMl9BUyArIENZUDJENl9BUyArIENZUDNBNV9BUyArIENZUDJDMTlfQVMgKyBDWVAyQzlfQVMgKyBBZGhlcmVuY2VfY29kZWQgKyBTWl9QUlNjcyArICBOQVJUSVEgKyBBZ2VfYXRfSW50ZXJ2aWV3ICArIFNleCArIFBDMSArIFBDMiArIFBDMyArIFBDNCArIFBDNSwgZGF0YSA9IHRlc3RfZGZfZGltX3N0ZF9jKQ0KDQojIyMjIGNyZWF0ZSB0YWJsZSAjIyMjDQp0MSA8LSBtYWtlX3RhYihuY29nKQ0KZjEgPC0gZ2V0X2ZpdChuY29nKQ0KdDEkcCA8LSBmb3JtYXRfcCh0MSRwKQ0KdDEgPC0gdDFbLTFdDQoNCnQyIDwtIG1ha2VfdGFiKG5jb2dfcGd4KQ0KZjIgPC0gZ2V0X2ZpdChuY29nX3BneCkNCnQyJHAgPC0gZm9ybWF0X3AodDIkcCkNCnQyIDwtIHQyWy0xXQ0KDQp0MyA8LSBtYWtlX3RhYihuY2NvZ19wZ3gpDQpmMyA8LSBnZXRfZml0KG5jY29nX3BneCkNCnQzJHAgPC0gZm9ybWF0X3AodDMkcCkNCnQzIDwtIHQzWy0xXQ0KDQpleHRyYSA8LSBjYmluZChmMSwgZjJbMl0sIGYzWzJdKQ0KDQptYWluIDwtIGZ1bGxfam9pbih0MSwgdDIsIGJ5ID0gIlByZWRpY3RvciIpDQptYWluIDwtIGZ1bGxfam9pbihtYWluLCB0MywgYnkgPSAiUHJlZGljdG9yIikNCm1haW4gPC0gY29sdW1uX2FzX3Jvd25hbWVzKG1haW4sIHZhciA9ICJQcmVkaWN0b3IiKQ0KDQpyb3duYW1lcyhtYWluKSA8LSBjKCJDUFotZXEgQW50aXBzeWNob3RpYyBEb3NlIChtZy9kYXkpIiwgIkNsb3phcGluZSAoWWVzKSIsICJBbnRpY2hvbGluZXJnaWMgKFllcykiLCAgIkFkaGVyZW50IChZZXMpIiwgIlNjaGl6b3BocmVuaWEgUEdTIiwgIk5BUlQgSVEiLCAiQWdlIiwgIlNleCAoRmVtYWxlKSIsICJQQzEiLCAiUEMyIiwgIlBDMyIsICJQQzQiLCAiUEM1IiwgIkNZUDFBMiBBY3Rpdml0eSBTY29yZSIsICJDWVAyRDYgQWN0aXZpdHkgU2NvcmUiLCAiQ1lQM0E1IEFjdGl2aXR5IFNjb3JlIiwgIkNZUDJDMTkgQWN0aXZpdHkgU2NvcmUiLCAiQ1lQMkM5IEFjdGl2aXR5IFNjb3JlIikNCg0KbWFpbiA8LSBtYWluW2MoMSwyLDMsMTQsMTUsMTYsMTcsMTgsNiw0LDUsNyw4LDksMTAsMTEsMTIsMTMpLF0gDQoNCm1haW4gJT4lIA0KICBrYWJsZShmb3JtYXQgPSAiaHRtbCIsIGVzY2FwZSA9IEYsIGNvbC5uYW1lcyA9IGMoIkVzdGltYXRlIChTRSkiLCAicCIsICJFc3RpbWF0ZSAoU0UpIiwgInAiLCAiRXN0aW1hdGUgKFNFKSIsICJwIikpICU+JQ0KICBhZGRfaGVhZGVyX2Fib3ZlKGhlYWRlciA9IGMoICIgIiA9IDEsICJNZWRpY2F0aW9uIE1vZGVsIiA9IDIsICJNZWRpY2F0aW9uICYgUGhhcm1hY29nZW5vbWljIE1vZGVsIiA9IDIsICAiTWVkaWNhdGlvbiAmIFBoYXJtYWNvZ2Vub21pYyBNb2RlbCAoQ2xvemFwaW5lIFN1Ymdyb3VwKSIgPSAyKSkgJT4lDQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQpIA0KDQpleHRyYSAlPiUgDQogIGthYmxlKGZvcm1hdCA9ICJodG1sIiwgZXNjYXBlID0gRiwgY2FwdGlvbiA9ICJTdXBwbGVtZW50YXJ5IFRhYmxlIDE0LiBBc3NvY2lhdGlvbnMgYmV0d2VlbiBtZWRpY2F0aW9uIGFuZCBwaGFybWFjb2dlbm9taWMgdmFyaWFibGVzIHdpdGggdGhlIGNvZ25pdGl2ZSBhYmlsaXR5IGRpbWVuc2lvbnMgaW4gQ2FyZGlmZkNPR1MuIE5BUlQgSVEgaXMgaW5jbHVkZWQgYXMgYSBwcm94eSBvZiBwcmVtb3JiaWQgaW50ZWxsaWdlbmNlIGluIHBsYWNlIG9mIHRoZSBJbnRlbGxpZ2VuY2UgUEdTIGFuZCBFZHVjYXRpb25hbCBBdHRhaW5tZW50IFBHUyB1c2VkIGluIHRoZSBhbmFseXNlcyBwcmVzZW50ZWQgaW4gdGhlIG1haW4gdGV4dC4gU3RhbmRhcmRpc2VkIHJlZ3Jlc3Npb24gZXN0aW1hdGVzIGFyZSByZXBvcnRlZC4gQ1BaLWVxID0gY2hsb3Jwcm9tYXppbmUtZXF1aXZhbGVudDsgU0UgPSBTdGFuZGFyZCBFcnJvcjsgUEdTID0gUG9seWdlbmljIFNjb3JlOyBQQyA9IEdlbmV0aWMgUHJpbmNpcGFsIENvbXBvbmVudC4iLCBjb2wubmFtZXMgPSBOVUxMLCBhbGlnbj1jKCJsIiwgImMiLCAiYyIsICJjIiwgImMiLCAiYyIpLCBkaWdpdHMgPSAzLCBmb3JtYXQuYXJncyA9IGxpc3QobnNtYWxsID0gMykpICU+JQ0KICBrYWJsZV9jbGFzc2ljKGZ1bGxfd2lkdGggPSBUKSANCg0KYGBgDQoNCjxicj4NCjxicj4NCjxicj4NCjxicj4NCg0KIyMgPHN0cm9uZz4gU3VwcGxlbWVudGFyeSBSZWZlcmVuY2VzIDwvc3Ryb25nPiANCiMjIyBTdXBwbGVtZW50YXJ5IFJlZmVyZW5jZXMNCg0KMQlEYXMgUywgRm9yZXIgTCwgU2Now7ZuaGVyciBTLCBldCBhbC4gTmV4dC1nZW5lcmF0aW9uIGdlbm90eXBlIGltcHV0YXRpb24gc2VydmljZSBhbmQgbWV0aG9kcy4gTmF0dXJlIEdlbmV0aWNzIDIwMTY7IDQ4OiAxMjg04oCTNy4NCg0KMglMb2ggUC1SLCBEYW5lY2VrIFAsIFBhbGFtYXJhIFBGLCBldCBhbC4gUmVmZXJlbmNlLWJhc2VkIHBoYXNpbmcgdXNpbmcgdGhlIEhhcGxvdHlwZSBSZWZlcmVuY2UgQ29uc29ydGl1bSBwYW5lbC4gTmF0IEdlbmV0IDIwMTY7IDQ4OiAxNDQz4oCTOC4NCg0KMwlMeW5oYW0gQUosIEtub3R0IFMsIFVuZGVyd29vZCBKRkcsIGV0IGFsLiBEUkFHT04tRGF0YTogYSBwbGF0Zm9ybSBhbmQgcHJvdG9jb2wgZm9yIGludGVncmF0aW5nIGdlbm9taWMgYW5kIHBoZW5vdHlwaWMgZGF0YSBhY3Jvc3MgbGFyZ2UgcHN5Y2hpYXRyaWMgY29ob3J0cy4gQkpQc3ljaCBPcGVuIDIwMjM7IDk6IDHigJM4Lg0KDQo0CUxlZ2dlIFNFLCBDYXJkbm8gQUcsIEFsbGFyZHljZSBKLCBldCBhbC4gQXNzb2NpYXRpb25zIEJldHdlZW4gU2NoaXpvcGhyZW5pYSBQb2x5Z2VuaWMgTGlhYmlsaXR5LCBTeW1wdG9tIERpbWVuc2lvbnMsIGFuZCBDb2duaXRpdmUgQWJpbGl0eSBpbiBTY2hpem9waHJlbmlhLiBKQU1BIFBzeWNoaWF0cnkgMjAyMTsgNzg6IDExNDPigJM1MS4NCg0KNQlTdXJha2thIEksIFNhcmluIEEtUCwgUnVvdHNhbGFpbmVuIFNFLCBldCBhbC4gVGhlIHJhdGUgb2YgZmFsc2UgcG9seW1vcnBoaXNtcyBpbnRyb2R1Y2VkIHdoZW4gaW1wdXRpbmcgZ2Vub3R5cGVzIGZyb20gZ2xvYmFsIGltcHV0YXRpb24gcGFuZWxzLiAyMDE2OyA6IDA4MDc3MC4NCg0KNglVZmZlbG1hbm4gRSwgSHVhbmcgUVEsIE11bnVuZyBOUywgZXQgYWwuIEdlbm9tZS13aWRlIGFzc29jaWF0aW9uIHN0dWRpZXMuIE5hdCBSZXYgTWV0aG9kcyBQcmltZXJzIDIwMjE7IDE6IDHigJMyMS4NCg0KNwlMZWUgUywgU2hpbiBKLVksIEt3b24gTi1KLCBLaW0gQywgU2VvIEotUy4gQ2xpblBoYXJtU2VxOiBBIHRhcmdldGVkIHNlcXVlbmNpbmcgcGFuZWwgZm9yIGNsaW5pY2FsIHBoYXJtYWNvZ2VuZXRpY3MgaW1wbGVtZW50YXRpb24uIFBMT1MgT05FIDIwMjI7IDE3OiAx4oCTMTkuDQoNCjgJU2Fpei1Sb2Ryw61ndWV6IE0sIE9jaG9hIEQsIEJlbG1vbnRlIEMsIGV0IGFsLiBQb2x5bW9ycGhpc21zIGluIENZUDFBMiwgQ1lQMkM5IGFuZCBBQkNCMSBhZmZlY3QgYWdvbWVsYXRpbmUgcGhhcm1hY29raW5ldGljcy4gSm91cm5hbCBvZiBQc3ljaG9waGFybWFjb2xvZ3kgMjAxOTsgMzM6IDUyMuKAkzMxLg0KDQo5CUxlc2NoZSBELCBNb3N0YWZhIFMsIEV2ZXJhbGwgSSwgUGFudGVsaXMgQywgQm91c21hbiBDQS4gSW1wYWN0IG9mIENZUDFBMiwgQ1lQMkMxOSwgYW5kIENZUDJENiBnZW5vdHlwZS0gYW5kIHBoZW5vY29udmVyc2lvbi1wcmVkaWN0ZWQgZW56eW1lIGFjdGl2aXR5IG9uIGNsb3phcGluZSBleHBvc3VyZSBhbmQgc3ltcHRvbSBzZXZlcml0eS4gVGhlIFBoYXJtYWNvZ2Vub21pY3MgSm91cm5hbCAyMDIwOyAyMDogMTky4oCTMjAxLg0KDQoxMAlUaWFuIEQsIE5hdGVzYW4gUywgV2hpdGUgSlIsIFBhaW5lIE1GLiBFZmZlY3RzIG9mIENvbW1vbiBDWVAxQTIgR2Vub3R5cGVzIGFuZCBPdGhlciBLZXkgRmFjdG9ycyBvbiBJbnRyYWluZGl2aWR1YWwgVmFyaWF0aW9uIGluIHRoZSBDYWZmZWluZSBNZXRhYm9saWMgUmF0aW86IEFuIEV4cGxvcmF0b3J5IEFuYWx5c2lzLiBDbGluaWNhbCBhbmQgVHJhbnNsYXRpb25hbCBTY2llbmNlIDIwMTk7IDEyOiAzOeKAkzQ2Lg0KDQoxMQlNb3N0YWZhIFMsIFBvbGFzZWsgVE0sIFNoZWZmaWVsZCBMSiwgSHVwcGVydCBELCBLaXJrcGF0cmljayBDTUouIFF1YW50aWZ5aW5nIHRoZSBJbXBhY3Qgb2YgUGhlbm9jb252ZXJzaW9uIG9uIE1lZGljYXRpb25zIFdpdGggQWN0aW9uYWJsZSBQaGFybWFjb2dlbm9taWMgR3VpZGVsaW5lIFJlY29tbWVuZGF0aW9ucyBpbiBhbiBBY3V0ZSBBZ2VkIFBlcnNvbnMgTWVudGFsIEhlYWx0aCBTZXR0aW5nLiBGcm9udCBQc3ljaGlhdHJ5IDIwMjE7IDEyOiA3MjQxNzAuDQoNCjEyCUtsb21wIFNELCBNYW5zb24gTUwsIEd1Y2hlbGFhciBILUosIFN3ZW4gSkouIFBoZW5vY29udmVyc2lvbiBvZiBDeXRvY2hyb21lIFA0NTAgTWV0YWJvbGlzbTogQSBTeXN0ZW1hdGljIFJldmlldy4gSm91cm5hbCBvZiBDbGluaWNhbCBNZWRpY2luZSAyMDIwOyA5OiAyODkwLg0KDQoxMwlGb29kIGFuZCBEcnVnIEFkbWluaXN0cmF0aW9uLiBEcnVnIERldmVsb3BtZW50IGFuZCBEcnVnIEludGVyYWN0aW9uczogVGFibGUgb2YgU3Vic3RyYXRlcywgSW5oaWJpdG9ycyBhbmQgSW5kdWNlcnMuIDIwMjM7IHB1Ymxpc2hlZCBvbmxpbmUgQXByaWwgMTIuIGh0dHBzOi8vd3d3LmZkYS5nb3YvZHJ1Z3MvZHJ1Zy1pbnRlcmFjdGlvbnMtbGFiZWxpbmcvZHJ1Zy1kZXZlbG9wbWVudC1hbmQtZHJ1Z2ludGVyYWN0aW9ucy10YWJsZS1zdWJzdHJhdGVzLWluaGliaXRvcnMtYW5kLWluZHVjZXJzIChhY2Nlc3NlZCBGZWIgOSwgMjAyNCkuDQoNCjE0CUh1a2thbmVuIEosIEphY29iIFAsIFBlbmcgTSwgRGVtcHNleSBELCBCZW5vd2l0eiBOTC4gRWZmZWN0IG9mIG5pY290aW5lIG9uIGN5dG9jaHJvbWUgUDQ1MCAxQTIgYWN0aXZpdHkuIEJyaXRpc2ggSm91cm5hbCBvZiBDbGluaWNhbCBQaGFybWFjb2xvZ3kgMjAxMTsgNzI6IDgzNuKAkzguDQoNCjE1CUNvdXN0YWxzIE4sIE1hcnRlbGxpIEMsIEJydW5ldC1MZWNvbXRlIE0sIFBldGlsbGlvbiBBLCBSb21lbyBCLCBCZW55YW1pbmEgQS4gQ2hyb25pYyBzbW9raW5nIGFuZCBjb2duaXRpb24gaW4gcGF0aWVudHMgd2l0aCBzY2hpem9waHJlbmlhOiBBIG1ldGEtYW5hbHlzaXMuIFNjaGl6b3BocmVuaWEgUmVzZWFyY2ggMjAyMDsgMjIyOiAxMTPigJMyMS4NCg0KMTYJVHJhY3kgSkksIE1jR3JvcnkgQUMsIEpvc2lhc3NlbiBSQywgTW9uYWNvIENBLiBBIGNvbXBhcmlzb24gb2YgcmVhZGluZyBhbmQgZGVtb2dyYXBoaWMtYmFzZWQgZXN0aW1hdGVzIG9mIHByZW1vcmJpZCBpbnRlbGxpZ2VuY2UgaW4gc2NoaXpvcGhyZW5pYS4gU2NoaXpvcGhyZW5pYSBSZXNlYXJjaCAxOTk2OyAyMjogMTAz4oCTOS4NCg0KPGJyPg0KPGJyPg0KPGJyPg0KPGJyPg0KDQojIyA8c3Ryb25nPiBTZXNzaW9uIEluZm8gPC9zdHJvbmc+IA0KDQpgYGB7ciBzZXNzaW9uIGluZm99DQpzZXNzaW9uSW5mbygpDQpgYGANCg0KDQo8YnI+DQo8YnI+DQoNCg==