ALL IMPORTED FILES MUST BE IN THE SAME DIRECTORY AS THIS SCRIPT

Load tidyverse package

library("tidyverse")

Import raw vcf data from “masterfile” and exclude variants with GnomAD non-cancer AF > 0.005

masterfile_consequence_1.3_or_LoF <- read.delim("masterfile_consequence_1.3_or_LoF.tsv", header=TRUE, row.names=NULL, na.strings = ".", stringsAsFactors=FALSE) %>% 
  rename("Sample"="X.Sample") %>% 
  filter(GnomAD_v2.1_non_cancer_AF<=0.005)

masterfile_consequence_4.6 <- read.delim("masterfile_consequence_4.6.tsv", header=TRUE, row.names=NULL, na.strings = ".", stringsAsFactors=FALSE) %>% 
  rename("Sample"="X.Sample") %>% 
  filter(GnomAD_v2.1_non_cancer_AF<=0.005)

masterfile <- union(masterfile_consequence_1.3_or_LoF,masterfile_consequence_4.6)

Exclude non-epithelial, uterine-only and BRCA +ve samples

ViP_Complete_Cohort <- read.delim("ViP_LoF_Complete_Cohort.txt", stringsAsFactors=FALSE)
ViP_Complete_Cohort_list <- ViP_Complete_Cohort[,1]

masterfile_eoc <- filter(masterfile,Sample%in%c(ViP_Complete_Cohort_list))
rm(masterfile)

Append patient path data

ViP_OvCa_Path_Data <- read.delim("ViP_OvCa_Path_Data.txt", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>% 
  dplyr::rename("Sample"=Exome.ID)
masterfile_eoc_withPath <- left_join(masterfile_eoc,ViP_OvCa_Path_Data,by="Sample",copy=FALSE)
rm(masterfile_eoc)

Exclude low-quality variants, GnomAD RF/InbreedingCoeff-flagged variants and protein-coding transcripts

masterfile_eoc_NPC_goodQ <- filter(masterfile_eoc_withPath, (QUAL>=30)&
                                 (Identified!="FilteredInAll")&
                                 (Sample.PMCDP>=10)&
                                 (Sample.PMCFREQ>=0.25)) %>% 
                                 filter((!str_detect(GnomAD_v2.1_FILTER_exome,"InbreedingCoeff")&
                                           !str_detect(GnomAD_v2.1_FILTER_exome,"RF"))|
                                       is.na(GnomAD_v2.1_FILTER_exome)) %>% 
  filter((!str_detect(GnomAD_v2.1_FILTER_genome,"InbreedingCoeff")&
            !str_detect(GnomAD_v2.1_FILTER_genome,"RF"))|
           is.na(GnomAD_v2.1_FILTER_genome)) %>% 
  filter(!BIOTYPE%in%c("protein_coding"))
rm(masterfile_eoc_withPath)

Exclude other mutation +ve samples (MLH1/MSH2/MSH6/PMS2, TP53, RAD51C/D, BRIP1)

ViP_Discovery_Cohort <- read.delim("ViP_LoF_Discovery_Cohort.txt", stringsAsFactors=FALSE)
ViP_Discovery_Cohort_list <- ViP_Discovery_Cohort[,1]

masterfile_eoc_NPC_goodQ2 <- filter(masterfile_eoc_NPC_goodQ,Sample%in%c(ViP_Discovery_Cohort_list))

Exclude MODIFIER impact variants + any non-protein-coding-transcripts with a transcribed protein ENSP ID e.g. immune system genes + any ‘pseudogenes’ (+ GnomAD popmax AF > 0.005 if needed)

masterfile_eoc_NPC_goodQ_ALL <- filter(masterfile_eoc_NPC_goodQ, IMPACT%in%c("HIGH","MODERATE","LOW")) %>% 
  filter(!grepl("ENSP",ENSP)) %>% 
  filter(!grepl("pseudogene",BIOTYPE)) %>% 
  distinct(.keep_all = FALSE)

masterfile_eoc_NPC_goodQ2_ALL <- filter(masterfile_eoc_NPC_goodQ2, IMPACT%in%c("HIGH","MODERATE","LOW")) %>% 
  filter(!grepl("ENSP",ENSP)) %>% 
  filter(!grepl("pseudogene",BIOTYPE)) %>% 
  distinct(.keep_all = FALSE)

Exclude MODIFIER impact variants + any non-protein-coding-transcripts other than ‘lincRNAs’ (+ GnomAD popmax AF > 0.005 if needed)

masterfile_eoc_lincRNA_goodQ_ALL <- filter(masterfile_eoc_NPC_goodQ, IMPACT%in%c("HIGH","MODERATE","LOW")) %>% 
  filter(BIOTYPE%in%"lincRNA") %>% 
  distinct(.keep_all = FALSE)

masterfile_eoc_lincRNA_goodQ2_ALL <- filter(masterfile_eoc_NPC_goodQ2, IMPACT%in%c("HIGH","MODERATE","LOW")) %>% 
  filter(BIOTYPE%in%"lincRNA") %>% 
  distinct(.keep_all = FALSE)

Separate Ensembl canonical and RefSeq canonical variants

masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical <- filter(masterfile_eoc_NPC_goodQ_ALL,CANONICAL=="YES") 

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical <- filter(masterfile_eoc_NPC_goodQ2_ALL,CANONICAL=="YES")

masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical <- filter(masterfile_eoc_lincRNA_goodQ_ALL,CANONICAL=="YES") 

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical <- filter(masterfile_eoc_lincRNA_goodQ2_ALL,CANONICAL=="YES") 

Sample variant counts and AFs

variants_heterozygous <- masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(alleles = "n()") %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants_homozygous <- masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(alleles = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants <- full_join(variants_heterozygous,variants_homozygous,by="HGVSc",copy=FALSE,suffix=c(".x",".y")) %>%
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Allele_Count=`sum(alleles).x`+`sum(alleles).y`) %>% 
  mutate(Sample_AF=Total_Allele_Count/(n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2))
masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_2 <- left_join(masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical,variants[,c(1,4:5)],by="HGVSc",copy=FALSE)

variants_heterozygous <- masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(alleles = "n()") %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants_homozygous <- masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(alleles = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants <- full_join(variants_heterozygous,variants_homozygous,by="HGVSc",copy=FALSE,suffix=c(".x",".y")) %>%
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Allele_Count=`sum(alleles).x`+`sum(alleles).y`) %>% 
  mutate(Sample_AF=Total_Allele_Count/(n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_2 <- left_join(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical,variants[,c(1,4:5)],by="HGVSc",copy=FALSE)

variants_heterozygous <- masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(alleles = "n()") %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants_homozygous <- masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(alleles = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants <- full_join(variants_heterozygous,variants_homozygous,by="HGVSc",copy=FALSE,suffix=c(".x",".y")) %>%
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Allele_Count=`sum(alleles).x`+`sum(alleles).y`) %>% 
  mutate(Sample_AF=Total_Allele_Count/(n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2))
masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_2 <- left_join(masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical,variants[,c(1,4:5)],by="HGVSc",copy=FALSE)

variants_heterozygous <- masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(alleles = "n()") %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants_homozygous <- masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical %>% 
  select(HGVSc,Sample.GT) %>% 
  group_by(HGVSc,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(alleles = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(HGVSc) %>% 
  summarise(sum(alleles))
variants <- full_join(variants_heterozygous,variants_homozygous,by="HGVSc",copy=FALSE,suffix=c(".x",".y")) %>%
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Allele_Count=`sum(alleles).x`+`sum(alleles).y`) %>% 
  mutate(Sample_AF=Total_Allele_Count/(n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_2 <- left_join(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical,variants[,c(1,4:5)],by="HGVSc",copy=FALSE)

Exclude variants with sample AF >0.01

masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_2,Sample_AF < 0.01)

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_2,Sample_AF < 0.01)

masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_2,Sample_AF < 0.01)

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01 <- filter(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_2,Sample_AF < 0.01)

Output list of genes and variants with sample AF >0.01

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_genesandvariants0.01 <- filter(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_2,Sample_AF > 0.01)
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_genesandvariants0.01[,c(2:6,25:54)] %>% 
  distinct(.keep_all = FALSE) %>% 
  write_excel_csv(file="masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_genesandvariants0.01.csv",na=".",append=FALSE,col_names=TRUE)

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_genesandvariants0.01 <- filter(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_2,Sample_AF > 0.01)
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_genesandvariants0.01[,c(2:6,25:54)] %>% 
  distinct(.keep_all = FALSE) %>% 
  write_excel_csv(file="masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_genesandvariants0.01.csv",na=".",append=FALSE,col_names=TRUE)

Sample gene counts and frequencies

genes_oneVarAllele <- masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(gene_Var = "n()") %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes_twoVarAllele <- masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(gene_Var = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes <- full_join(genes_oneVarAllele,genes_twoVarAllele,by="Gene",copy=FALSE,suffix=c(".x",".y")) %>% 
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Gene_Count=`sum(gene_Var).x`+`sum(gene_Var).y`) %>% 
  mutate(Sample_Gene_Freq=Total_Gene_Count/(n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2))
masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_2 <- left_join(masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01, genes[,c(1,4:5)],by="Gene",copy=FALSE)

genes_oneVarAllele <- masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(gene_Var = "n()") %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes_twoVarAllele <- masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(gene_Var = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes <- full_join(genes_oneVarAllele,genes_twoVarAllele,by="Gene",copy=FALSE,suffix=c(".x",".y")) %>% 
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Gene_Count=`sum(gene_Var).x`+`sum(gene_Var).y`) %>% 
  mutate(Sample_Gene_Freq=Total_Gene_Count/(n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_2 <- left_join(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01, genes[,c(1,4:5)],by="Gene",copy=FALSE)

genes_oneVarAllele <- masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(gene_Var = "n()") %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes_twoVarAllele <- masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(gene_Var = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes <- full_join(genes_oneVarAllele,genes_twoVarAllele,by="Gene",copy=FALSE,suffix=c(".x",".y")) %>% 
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Gene_Count=`sum(gene_Var).x`+`sum(gene_Var).y`) %>% 
  mutate(Sample_Gene_Freq=Total_Gene_Count/(n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2))
masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_2 <- left_join(masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01, genes[,c(1,4:5)],by="Gene",copy=FALSE)

genes_oneVarAllele <- masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT%in%c("'0/1","'1/0"))) %>% 
  rename(gene_Var = "n()") %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes_twoVarAllele <- masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01 %>% select(Gene,Sample.GT) %>% 
  select(Gene,Sample.GT) %>% 
  group_by(Gene,Sample.GT) %>% 
  summarise(n()) %>% 
  filter((Sample.GT!="'0/1")&(Sample.GT!="'1/0")) %>% 
  mutate(gene_Var = `n()`*2) %>% 
  select(-`n()`) %>% 
  group_by(Gene) %>% 
  summarise(sum(gene_Var))
genes <- full_join(genes_oneVarAllele,genes_twoVarAllele,by="Gene",copy=FALSE,suffix=c(".x",".y")) %>% 
  mutate_all(funs(replace(., is.na(.), 0))) %>% 
  mutate(Total_Gene_Count=`sum(gene_Var).x`+`sum(gene_Var).y`) %>% 
  mutate(Sample_Gene_Freq=Total_Gene_Count/(n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_2 <- left_join(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01, genes[,c(1,4:5)],by="Gene",copy=FALSE)

Add GnomAD gene-level data

ensembl_biotypes <- read.delim("ensembl_biotypes.tsv", stringsAsFactors=FALSE) %>% 
  select(ensembl_transcript_id,transcript_biotype) %>% 
  dplyr::rename("Feature"="ensembl_transcript_id","BIOTYPE"="transcript_biotype")

AgilentSSv6_list_ENSTcanonical_non_protein_coding <- read.delim("GnomAD.gene.stats.v2.RF.only.agilent.v6.only.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>% 
  filter(CANONICAL=="YES") %>% 
  dplyr::rename("SYMBOL"="X.Symbol") %>% 
  dplyr::rename("Gene"="ENSG") %>% 
  left_join(ensembl_biotypes,by="Feature",copy=FALSE) %>% 
  filter(!BIOTYPE%in%c("protein_coding")) %>% 
  filter(!grepl("ENSP",ENSP)) %>% 
  filter(!grepl("pseudogene",BIOTYPE)) %>% 
  select(SYMBOL,Feature,Gene,BIOTYPE) %>% 
  distinct(.keep_all = FALSE)

AgilentSSv6_list_ENSTcanonical_lincRNA <- read.delim("GnomAD.gene.stats.v2.RF.only.agilent.v6.only.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>% 
  filter(CANONICAL=="YES") %>% 
  dplyr::rename("SYMBOL"="X.Symbol") %>% 
  dplyr::rename("Gene"="ENSG") %>% 
  left_join(ensembl_biotypes,by="Feature",copy=FALSE) %>% 
  filter(BIOTYPE%in%"lincRNA") %>% 
  select(SYMBOL,Feature,Gene,BIOTYPE) %>% 
  distinct(.keep_all = FALSE)

GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding <- read.delim("agilent_v6_gnomad_v2.1.1_genestats_canonical_allIMPACTS.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>% 
  filter(Feature%in%(AgilentSSv6_list_ENSTcanonical_non_protein_coding$Feature)) %>% 
  dplyr::rename("Gene"="ENSG")

GnomAD_stats_ALL_VEP_ENSTcanonical_lincRNA <- read.delim("agilent_v6_gnomad_v2.1.1_genestats_canonical_allIMPACTS.tsv", header=TRUE, row.names=NULL, stringsAsFactors=FALSE) %>% 
  filter(Feature%in%(AgilentSSv6_list_ENSTcanonical_lincRNA$Feature)) %>% 
  dplyr::rename("Gene"="ENSG")

masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats <- left_join(masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_2, GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding[,c(2,14:19)],by="Feature",copy=FALSE) 
masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate_at(masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats,vars(starts_with("FILTER_")),funs(replace(., is.na(.), 0))) %>% 
  mutate_if(grepl("popmax$", names(.)),funs(ifelse(. == "NA", 0, as.numeric(.)))) %>% 
  mutate_at(vars(ends_with("popmax")),funs(replace(., is.na(.), 0)))

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats <- left_join(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_2, GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding[,c(2,14:19)],by="Feature",copy=FALSE) 
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate_at(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats,vars(starts_with("FILTER_")),funs(replace(., is.na(.), 0))) %>% 
  mutate_if(grepl("popmax$", names(.)),funs(ifelse(. == "NA", 0, as.numeric(.)))) %>% 
  mutate_at(vars(ends_with("popmax")),funs(replace(., is.na(.), 0)))

masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats <- left_join(masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_2, GnomAD_stats_ALL_VEP_ENSTcanonical_lincRNA[,c(2,14:19)],by="Feature",copy=FALSE) 
masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate_at(masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats,vars(starts_with("FILTER_")),funs(replace(., is.na(.), 0))) %>% 
  mutate_if(grepl("popmax$", names(.)),funs(ifelse(. == "NA", 0, as.numeric(.)))) %>% 
  mutate_at(vars(ends_with("popmax")),funs(replace(., is.na(.), 0)))

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats <- left_join(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_2, GnomAD_stats_ALL_VEP_ENSTcanonical_lincRNA[,c(2,14:19)],by="Feature",copy=FALSE) 
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate_at(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats,vars(starts_with("FILTER_")),funs(replace(., is.na(.), 0))) %>% 
  mutate_if(grepl("popmax$", names(.)),funs(ifelse(. == "NA", 0, as.numeric(.)))) %>% 
  mutate_at(vars(ends_with("popmax")),funs(replace(., is.na(.), 0)))

Calculate Sample/GnomAD gene freq and allele freq ratios for total and NFE GnomAD figures

masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate(masterfile_eoc_NPC_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats,
"Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ,      "Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ,      "Sample_Gene_ALL_AF_Ratio"=Sample_AF/GnomAD_v2.1_non_cancer_AF, 
"Sample_Gene_ALL_AF_Ratio_NFE"=Sample_AF/GnomAD_v2.1_non_cancer_AF_nfe)

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats, "Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ,      "Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ,      "Sample_Gene_ALL_AF_Ratio"=Sample_AF/GnomAD_v2.1_non_cancer_AF, 
"Sample_Gene_ALL_AF_Ratio_NFE"=Sample_AF/GnomAD_v2.1_non_cancer_AF_nfe)

masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate(masterfile_eoc_lincRNA_goodQ_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats,
"Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ,      "Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ,      "Sample_Gene_ALL_AF_Ratio"=Sample_AF/GnomAD_v2.1_non_cancer_AF, 
"Sample_Gene_ALL_AF_Ratio_NFE"=Sample_AF/GnomAD_v2.1_non_cancer_AF_nfe)

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 <- mutate(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats, "Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ,      "Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005"=Sample_Gene_Freq/FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ,      "Sample_Gene_ALL_AF_Ratio"=Sample_AF/GnomAD_v2.1_non_cancer_AF, 
"Sample_Gene_ALL_AF_Ratio_NFE"=Sample_AF/GnomAD_v2.1_non_cancer_AF_nfe)

Create data frames with Agilent SureSelect whole exome genes (ENST and non-protein-coding) for volcano plots

allGenes_AgilentSSv6_list_non_protein_coding_only <- GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding[,c(1:3,6,10)] %>% 
  filter(MAX_AN_NFE!=0) %>% 
  left_join(AgilentSSv6_list_ENSTcanonical_non_protein_coding[,c(2,4)],by="Feature",copy=FALSE)

allGenes_masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_biotypeNPC_list <- tibble("SYMBOL"=masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2$SYMBOL,"Gene"=masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2$Gene,"BIOTYPE"=masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2$BIOTYPE) %>% 
  distinct(.keep_all=TRUE) %>% 
  arrange(SYMBOL)

allGenes_masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_biotype_lincRNA_list <- tibble("SYMBOL"=masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2$SYMBOL,"Gene"=masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2$Gene,"BIOTYPE"=masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2$BIOTYPE) %>% 
  distinct(.keep_all=TRUE) %>% 
  arrange(SYMBOL)

volcano_sampleAF0.01_biotypeNPC_allGenes <- masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 %>% 
  mutate(Total_Case_Alleles=(n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2)) %>% 
  select(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles,Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005,Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005) %>% 
  distinct(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles,Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005,Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005) 
volcano_sampleAF0.01_biotypeNPC_allGenes2 <- left_join(allGenes_AgilentSSv6_list_non_protein_coding_only,volcano_sampleAF0.01_biotypeNPC_allGenes[,c(2:4)],by="Gene",copy=FALSE) %>% 
  bind_rows(anti_join(allGenes_AgilentSSv6_list_non_protein_coding_only[,c(1,3)],volcano_sampleAF0.01_biotypeNPC_allGenes,by="Gene")) %>% 
  mutate_at(vars("Total_Gene_Count"),funs(replace(., is.na(.), 0))) %>% 
  mutate_at(vars("Total_Case_Alleles"),funs(replace(., is.na(.), n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2))) %>% 
  distinct(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles) 
volcano_sampleAF0.01_biotypeNPC_allGenes3 <- right_join(
  volcano_sampleAF0.01_biotypeNPC_allGenes2,
  GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding,
  by="Gene",copy=FALSE) %>% 
  select("SYMBOL.x","Gene","Total_Gene_Count","Total_Case_Alleles","FILTER_RF_LOW.MODERATE.HIGH_AC_0.005","FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_NFE","MAX_AN","MAX_AN_NFE","FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ","FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ") %>% 
  dplyr::rename("SYMBOL"="SYMBOL.x") %>% 
  mutate(FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_ADJ=round((MAX_AN*FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ))) %>% 
  mutate(FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_NFE_ADJ=round((MAX_AN_NFE*FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ))) %>% 
  distinct(.keep_all=TRUE) %>% 
  filter(!is.na(MAX_AN_NFE)) %>% 
  filter(MAX_AN_NFE!=0)

volcano_sampleAF0.01_biotype_lincRNA_allGenes <- masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2 %>% 
  mutate(Total_Case_Alleles=(n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2)) %>% 
  # filter(!BIOTYPE%in%c("protein_coding")) %>% 
  select(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles,Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005,Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005) %>% 
  distinct(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles,Sample_Gene_ALL_Freq_Ratio_GnomAD_0.005,Sample_Gene_ALL_Freq_Ratio_GnomAD_NFE_0.005) 
volcano_sampleAF0.01_biotype_lincRNA_allGenes2 <- left_join(allGenes_AgilentSSv6_list_non_protein_coding_only,volcano_sampleAF0.01_biotype_lincRNA_allGenes[,c(2:4)],by="Gene",copy=FALSE) %>% 
  bind_rows(anti_join(allGenes_AgilentSSv6_list_non_protein_coding_only[,c(1,3)],volcano_sampleAF0.01_biotype_lincRNA_allGenes,by="Gene")) %>% 
  mutate_at(vars("Total_Gene_Count"),funs(replace(., is.na(.), 0))) %>% 
  mutate_at(vars("Total_Case_Alleles"),funs(replace(., is.na(.), n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2))) %>% 
  distinct(SYMBOL,Gene,Total_Gene_Count,Total_Case_Alleles) 
volcano_sampleAF0.01_biotype_lincRNA_allGenes3 <- right_join(
  volcano_sampleAF0.01_biotype_lincRNA_allGenes2,
  GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding,
  by="Gene",copy=FALSE) %>% 
  select("SYMBOL.x","Gene","Total_Gene_Count","Total_Case_Alleles","FILTER_RF_LOW.MODERATE.HIGH_AC_0.005","FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_NFE","MAX_AN","MAX_AN_NFE","FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ","FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ") %>% 
  dplyr::rename("SYMBOL"="SYMBOL.x") %>% 
  mutate(FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_ADJ=round((MAX_AN*FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_ADJ))) %>% 
  mutate(FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_NFE_ADJ=round((MAX_AN_NFE*FILTER_RF_LOW.MODERATE.HIGH_AF_0.005_NFE_ADJ))) %>% 
  distinct(.keep_all=TRUE) %>% 
  filter(!is.na(MAX_AN_NFE)) %>% 
  filter(MAX_AN_NFE!=0)

Calculate Fisher’s test values (Ensembl Canonical)

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults <- mutate(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2,Total_Case_Alleles=(n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2)) %>% 
  left_join(GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding[,c(2,6,10)],by="Feature",copy=FALSE) 
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2 <- mutate(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults, MAX_AN=replace(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults$MAX_AN, is.na(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults$MAX_AN), max(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults$MAX_AN, na.rm=TRUE))) %>% 
  filter(!is.na(MAX_AN_NFE)&
           MAX_AN_NFE!=0)

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults <- mutate(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats2,Total_Case_Alleles=(n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2)) %>% 
  left_join(GnomAD_stats_ALL_VEP_ENSTcanonical_non_protein_coding[,c(2,6,10)],by="Feature",copy=FALSE) 
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2 <- mutate(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults, MAX_AN=replace(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults$MAX_AN, is.na(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults$MAX_AN), max(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults$MAX_AN, na.rm=TRUE))) %>% 
  filter(!is.na(MAX_AN_NFE)&
           MAX_AN_NFE!=0)

fisherresults_ENST <- apply(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2[,c(262,264,274,275)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005 = sapply(fisherresults_ENST,function(x) round(x$p.value,12))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$OR_0.005 = sapply(fisherresults_ENST,function(x) round(x$estimate,4))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$`95%CI_0.005` = sapply(fisherresults_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$BH_0.005 = p.adjust(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005,method = "BH")

fisherresults2_ENST <- apply(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2[,c(262,267,274,276)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$p.value,12))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$OR_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$estimate,4))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$`95%CI_0.005_NFE` = sapply(fisherresults2_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$BH_0.005_NFE = p.adjust(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005_NFE,method = "BH")

fisherresults_ENST <- apply(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2[,c(262,264,274,275)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005 = sapply(fisherresults_ENST,function(x) round(x$p.value,12))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$OR_0.005 = sapply(fisherresults_ENST,function(x) round(x$estimate,4))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$`95%CI_0.005` = sapply(fisherresults_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$BH_0.005 = p.adjust(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005,method = "BH")

fisherresults2_ENST <- apply(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2[,c(262,267,274,276)],1,function(x) {fisher.test(rbind(x[1:2],c(x[3]-x[1],x[4]-x[2])))})

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$p.value,12))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$OR_0.005_NFE = sapply(fisherresults2_ENST,function(x) round(x$estimate,4))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$`95%CI_0.005_NFE` = sapply(fisherresults2_ENST,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$BH_0.005_NFE = p.adjust(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2$P_value_Fisher_0.005_NFE,method = "BH")

Calculate Fisher’s test values (volcano plot)

fisherresults_biotypeNPC_allGenes_volcano <- apply(volcano_sampleAF0.01_biotypeNPC_allGenes3[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})

volcano_sampleAF0.01_biotypeNPC_allGenes3$P_value_Fisher_0.005 = sapply(fisherresults_biotypeNPC_allGenes_volcano,function(x) round(x$p.value,15))
volcano_sampleAF0.01_biotypeNPC_allGenes3$OR_0.005 = sapply(fisherresults_biotypeNPC_allGenes_volcano,function(x) round(x$estimate,15))
volcano_sampleAF0.01_biotypeNPC_allGenes3$`95%CI_0.005` = sapply(fisherresults_biotypeNPC_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_sampleAF0.01_biotypeNPC_allGenes3$BH_0.005 = p.adjust(volcano_sampleAF0.01_biotypeNPC_allGenes3$P_value_Fisher_0.005,method = "BH")

fisherresults_biotypeNPC_NFE_volcano <- apply(volcano_sampleAF0.01_biotypeNPC_allGenes3[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})

volcano_sampleAF0.01_biotypeNPC_allGenes3$P_value_Fisher_0.005_NFE = sapply(fisherresults_biotypeNPC_NFE_volcano,function(x) round(x$p.value,15))
volcano_sampleAF0.01_biotypeNPC_allGenes3$OR_0.005_NFE = sapply(fisherresults_biotypeNPC_NFE_volcano,function(x) round(x$estimate,15))
volcano_sampleAF0.01_biotypeNPC_allGenes3$`95%CI_0.005_NFE` = sapply(fisherresults_biotypeNPC_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_sampleAF0.01_biotypeNPC_allGenes3$BH_0.005_NFE = p.adjust(volcano_sampleAF0.01_biotypeNPC_allGenes3$P_value_Fisher_0.005_NFE,method = "BH")

fisherresults_biotype_lincRNA_allGenes_volcano <- apply(volcano_sampleAF0.01_biotype_lincRNA_allGenes3[,c(3,5,4,7)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})

volcano_sampleAF0.01_biotype_lincRNA_allGenes3$P_value_Fisher_0.005 = sapply(fisherresults_biotype_lincRNA_allGenes_volcano,function(x) round(x$p.value,15))
volcano_sampleAF0.01_biotype_lincRNA_allGenes3$OR_0.005 = sapply(fisherresults_biotype_lincRNA_allGenes_volcano,function(x) round(x$estimate,15))
volcano_sampleAF0.01_biotype_lincRNA_allGenes3$`95%CI_0.005` = sapply(fisherresults_biotype_lincRNA_allGenes_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_sampleAF0.01_biotype_lincRNA_allGenes3$BH_0.005 = p.adjust(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$P_value_Fisher_0.005,method = "BH")

fisherresults_biotype_lincRNA_NFE_volcano <- apply(volcano_sampleAF0.01_biotype_lincRNA_allGenes3[,c(3,6,4,8)],1,function(x) {fisher.test(rbind(x[1:2],c(abs(x[3]-x[1]),abs(x[4]-x[2]))))})

volcano_sampleAF0.01_biotype_lincRNA_allGenes3$P_value_Fisher_0.005_NFE = sapply(fisherresults_biotype_lincRNA_NFE_volcano,function(x) round(x$p.value,15))
volcano_sampleAF0.01_biotype_lincRNA_allGenes3$OR_0.005_NFE = sapply(fisherresults_biotype_lincRNA_NFE_volcano,function(x) round(x$estimate,15))
volcano_sampleAF0.01_biotype_lincRNA_allGenes3$`95%CI_0.005_NFE` = sapply(fisherresults_biotype_lincRNA_NFE_volcano,function(x) paste(round(x$conf.int[1:2],2),collapse="~"))
volcano_sampleAF0.01_biotype_lincRNA_allGenes3$BH_0.005_NFE = p.adjust(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$P_value_Fisher_0.005_NFE,method = "BH")

Identify variants with filtering AF > maximum credible population AF in GnomAD for hereditary EOC (0.000181)

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults3 <- mutate(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2, FilteringAF_95_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95)>0.000181)) %>% 
  mutate(FilteringAF_95_NFE_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95_nfe)>0.000181))

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults3 <- mutate(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults2, FilteringAF_95_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95)>0.000181)) %>% 
  mutate(FilteringAF_95_NFE_Exceeds_MaxCredPopAF=((GnomAD_v2.1_non_cancer_Filtering_AF_95_nfe)>0.000181))

Identify variants that PASS/FAIL the LOFTEE 50bp rule

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults4 <- mutate(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults3,LoF_50_BP_RULE = ifelse(grepl("50_BP_RULE:PASS", LoF_info), TRUE, ifelse(grepl("50_BP_RULE:FAIL", LoF_info), FALSE, NA)))

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults4 <- mutate(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults3,LoF_50_BP_RULE = ifelse(grepl("50_BP_RULE:PASS", LoF_info), TRUE, ifelse(grepl("50_BP_RULE:FAIL", LoF_info), FALSE, NA)))

Import NMD depleted gene list and annotate variants accordingly

NMD_depleted_gene_list <- read.csv("NMD_depleted_gene_list.csv", stringsAsFactors=FALSE) %>% 
  rename("SYMBOL" = gene) %>% 
  rename("Feature" = txnames) %>% 
  rename("NMD_predictor_rank" = min.rank)

masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults5 <- left_join(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults4, NMD_depleted_gene_list[,c(2:3)],by="Feature",copy=FALSE)

masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults5 <- left_join(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults4, NMD_depleted_gene_list[,c(2:3)],by="Feature",copy=FALSE) 

Remove redundant objects and output data

rm(list=(ls(pattern="^genes")))
rm(list=(ls(pattern="^variants")))
rm(list=(ls(pattern="^fisherresults")))

write_excel_csv(masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults5,file="masterfile_eoc_NPC_goodQ2_ALL_ENSTcanonical_sampleAF0.01_biotypeNPC.csv",na=".",append=FALSE,col_names=TRUE)

write_excel_csv(masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_withGnomADstats_fisherresults5,file="masterfile_eoc_lincRNA_goodQ2_ALL_ENSTcanonical_sampleAF0.01_biotype_lincRNA.csv",na=".",append=FALSE,col_names=TRUE)

Calculate total LoF variants in sample vs total LoF variants in GnomAD non-cancer NFE and use for chi-squared test

oddsratio <- function (a, b = NULL, c = NULL, d = NULL, conf.level = 0.95, 
    p.calc.by.independence = TRUE) 
{
    if (is.matrix(a)) {
        if ((dim(a)[1] != 2L) | (dim(a)[2] != 2L)) {
            stop("Input matrix must be a 2x2 table.")
        }
        .a <- a[1, 1]
        .b <- a[1, 2]
        .c <- a[2, 1]
        .d <- a[2, 2]
        .data.name <- deparse(substitute(a))
    }
    else {
        .a <- a
        .b <- b
        .c <- c
        .d <- d
        .data.name <- paste(deparse(substitute(a)), deparse(substitute(b)), 
            deparse(substitute(c)), deparse(substitute(d)))
    }
    .MAT <- matrix(c(.a, .b, M1 <- .a + .b, .c, .d, M0 <- .c + 
        .d, N1 <- .a + .c, N0 <- .b + .d, Total <- .a + .b + 
        .c + .d), 3, 3)
    colnames(.MAT) <- c("Sample", "GnomAD", "Total") #("Disease", "Nondisease", "Total")
    rownames(.MAT) <- c("Variants", "No variants", "Total") #("Exposed", "Nonexposed", "Total")
    class(.MAT) <- "table"
    print(.MAT)
    ESTIMATE <- (.a /.b)/(.c/.d)
    norm.pp <- qnorm(1 - (1 - conf.level)/2)
    if (p.calc.by.independence) {
        p.v <- 2 * (1 - pnorm(abs((.a - N1 * M1/Total)/sqrt(N1 * 
            N0 * M1 * M0/Total/Total/(Total - 1)))))
    }
    else {
        p.v <- 2 * (1 - pnorm(log(ifelse(ESTIMATE > 1, ESTIMATE, 
            1/ESTIMATE))/sqrt(1/.a + 1/.b + 1/.c + 1/.d)))
    }
    ORL <- ESTIMATE * exp(-norm.pp * sqrt(1/.a + 1/.b + 1/.c + 
        1/.d))
    ORU <- ESTIMATE * exp(norm.pp * sqrt(1/.a + 1/.b + 1/.c + 
        1/.d)) %>% signif(digits=7)
    CINT <- paste(signif(ORL,digits = 7),signif(ORU,digits = 7),sep="~")
    attr(CINT, "conf.level") <- conf.level
    RVAL <- list(p.value = p.v, conf.int = CINT, estimate = ESTIMATE, 
        method = "Odds ratio estimate and its significance probability", 
        data.name = .data.name)
    class(RVAL) <- "htest"
    return(RVAL)
}

a <- sum(volcano_sampleAF0.01_biotypeNPC_allGenes3$Total_Gene_Count) %>% as.numeric()
b <- n_distinct(masterfile_eoc_NPC_goodQ2_ALL$Sample)*2*(nrow(allGenes_AgilentSSv6_list_non_protein_coding_only)) %>% as.numeric()
b1 <- b-a %>% as.numeric()
c <- sum(volcano_sampleAF0.01_biotypeNPC_allGenes3$FILTER_RF_LOW.MODERATE.HIGH_AC_0.005) %>% as.numeric()
d <- (max(volcano_sampleAF0.01_biotypeNPC_allGenes3$MAX_AN))*nrow(allGenes_AgilentSSv6_list_non_protein_coding_only) %>% as.numeric()
d1 <- d-c %>% as.numeric()
e <- sum(volcano_sampleAF0.01_biotypeNPC_allGenes3$FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_NFE) %>% as.numeric()
f <- (max(volcano_sampleAF0.01_biotypeNPC_allGenes3$MAX_AN_NFE))*nrow(allGenes_AgilentSSv6_list_non_protein_coding_only) %>% as.numeric()
f1 <- f-e %>% as.numeric()

chiX2_0.005_biotypeNPC <- matrix(c(a,b1,c,d1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_biotypeNPC <- matrix(c(a,b1,e,f1),nrow=2,byrow=TRUE)

sink(file="masterfile_eoc_ALL_volcano_chiX2_results.txt",append=TRUE)

chisq.test(chiX2_0.005_biotypeNPC,correct=FALSE)
oddsratio(chiX2_0.005_biotypeNPC)
chisq.test(chiX2_0.005_NFE_biotypeNPC,correct=FALSE)
oddsratio(chiX2_0.005_NFE_biotypeNPC)

sink()

g <- sum(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$Total_Gene_Count) %>% as.numeric()
h <- n_distinct(masterfile_eoc_NPC_goodQ2$Sample)*2*(nrow(allGenes_AgilentSSv6_list_non_protein_coding_only)) %>% as.numeric()
h1 <- h-g %>% as.numeric()
i <- sum(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$FILTER_RF_LOW.MODERATE.HIGH_AC_0.005) %>% as.numeric()
j <- (max(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$MAX_AN))*nrow(allGenes_AgilentSSv6_list_non_protein_coding_only) %>% as.numeric()
j1 <- j-i %>% as.numeric()
k <- sum(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$FILTER_RF_LOW.MODERATE.HIGH_AC_0.005_NFE) %>% as.numeric()
l <- (max(volcano_sampleAF0.01_biotype_lincRNA_allGenes3$MAX_AN_NFE))*nrow(allGenes_AgilentSSv6_list_non_protein_coding_only) %>% as.numeric()
l1 <- l-k %>% as.numeric()

chiX2_0.005_biotype_lincRNA <- matrix(c(g,h1,i,j1),nrow=2,byrow=TRUE)
chiX2_0.005_NFE_biotype_lincRNA <- matrix(c(g,h1,k,l1),nrow=2,byrow=TRUE)

sink(file="masterfile_eoc_ALL_volcano_chiX2_results.txt",append=TRUE)

chisq.test(chiX2_0.005_biotype_lincRNA,correct=FALSE)
oddsratio(chiX2_0.005_biotype_lincRNA)
chisq.test(chiX2_0.005_NFE_biotype_lincRNA,correct=FALSE)
oddsratio(chiX2_0.005_NFE_biotype_lincRNA)

sink()

Output data for log p-value volcano plots

volcano_sampleAF0.01_biotypeNPC_allGenes4 <- mutate(volcano_sampleAF0.01_biotypeNPC_allGenes3,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>% 
  arrange(desc(OR_0.005_NFE)) %>% 
  mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"= 
  if_else (`Log10_P-value_Fisher_0.05_NFE`<0, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>% 
  arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>% 
  left_join(AgilentSSv6_list_ENSTcanonical_non_protein_coding[,c(3,4)],by="Gene",copy="FALSE") %>% 
  left_join(volcano_sampleAF0.01_biotypeNPC_allGenes[,c(2,5,6)],by="Gene",copy="FALSE") %>% 
  write_excel_csv(file="volcano_sampleAF0.01_biotypeNPC_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)

volcano_sampleAF0.01_biotype_lincRNA_allGenes4 <- mutate(volcano_sampleAF0.01_biotype_lincRNA_allGenes3,"Log10_P-value_Fisher_0.05_NFE" = log10(P_value_Fisher_0.005_NFE)) %>% 
  arrange(desc(OR_0.005_NFE)) %>% 
  mutate("Plotted_Log10_P-value_Fisher_0.05_NFE"= 
  if_else (`Log10_P-value_Fisher_0.05_NFE`<0, `Log10_P-value_Fisher_0.05_NFE`*-1, `Log10_P-value_Fisher_0.05_NFE`, missing=NULL)) %>% 
  arrange(desc(`Plotted_Log10_P-value_Fisher_0.05_NFE`),desc(OR_0.005_NFE)) %>% 
  left_join(AgilentSSv6_list_ENSTcanonical_non_protein_coding[,c(3,4)],by="Gene",copy="FALSE") %>% 
  left_join(volcano_sampleAF0.01_biotype_lincRNA_allGenes[,c(2,5,6)],by="Gene",copy="FALSE") %>% 
  write_excel_csv(file="volcano_sampleAF0.01_biotype_lincRNA_allGenes_v6.csv",na=".",append=FALSE,col_names=TRUE)
LS0tCnRpdGxlOiAiVGhlc2lzIE5vbi1Qcm90ZWluLUNvZGluZyBWYXJpYW50cyBGaWx0ZXJpbmcgYW5kIEFuYWx5c2lzIFNjcmlwdCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKQUxMIElNUE9SVEVEIEZJTEVTIE1VU1QgQkUgSU4gVEhFIFNBTUUgRElSRUNUT1JZIEFTIFRISVMgU0NSSVBUCgpMb2FkIHRpZHl2ZXJzZSBwYWNrYWdlCmBgYHtyfQpsaWJyYXJ5KCJ0aWR5dmVyc2UiKQpgYGAKCkltcG9ydCByYXcgdmNmIGRhdGEgZnJvbSAibWFzdGVyZmlsZSIgYW5kIGV4Y2x1ZGUgdmFyaWFudHMgd2l0aCBHbm9tQUQgbm9uLWNhbmNlciBBRiA+IDAuMDA1CmBgYHtyfQptYXN0ZXJmaWxlX2NvbnNlcXVlbmNlXzEuM19vcl9Mb0YgPC0gcmVhZC5kZWxpbSgibWFzdGVyZmlsZV9jb25zZXF1ZW5jZV8xLjNfb3JfTG9GLnRzdiIsIGhlYWRlcj1UUlVFLCByb3cubmFtZXM9TlVMTCwgbmEuc3RyaW5ncyA9ICIuIiwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIHJlbmFtZSgiU2FtcGxlIj0iWC5TYW1wbGUiKSAlPiUgCiAgZmlsdGVyKEdub21BRF92Mi4xX25vbl9jYW5jZXJfQUY8PTAuMDA1KQoKbWFzdGVyZmlsZV9jb25zZXF1ZW5jZV80LjYgPC0gcmVhZC5kZWxpbSgibWFzdGVyZmlsZV9jb25zZXF1ZW5jZV80LjYudHN2IiwgaGVhZGVyPVRSVUUsIHJvdy5uYW1lcz1OVUxMLCBuYS5zdHJpbmdzID0gIi4iLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKSAlPiUgCiAgcmVuYW1lKCJTYW1wbGUiPSJYLlNhbXBsZSIpICU+JSAKICBmaWx0ZXIoR25vbUFEX3YyLjFfbm9uX2NhbmNlcl9BRjw9MC4wMDUpCgptYXN0ZXJmaWxlIDwtIHVuaW9uKG1hc3RlcmZpbGVfY29uc2VxdWVuY2VfMS4zX29yX0xvRixtYXN0ZXJmaWxlX2NvbnNlcXVlbmNlXzQuNikKYGBgCgpFeGNsdWRlIG5vbi1lcGl0aGVsaWFsLCB1dGVyaW5lLW9ubHkgYW5kIEJSQ0EgK3ZlIHNhbXBsZXMKYGBge3J9ClZpUF9Db21wbGV0ZV9Db2hvcnQgPC0gcmVhZC5kZWxpbSgiVmlQX0xvRl9Db21wbGV0ZV9Db2hvcnQudHh0Iiwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkKVmlQX0NvbXBsZXRlX0NvaG9ydF9saXN0IDwtIFZpUF9Db21wbGV0ZV9Db2hvcnRbLDFdCgptYXN0ZXJmaWxlX2VvYyA8LSBmaWx0ZXIobWFzdGVyZmlsZSxTYW1wbGUlaW4lYyhWaVBfQ29tcGxldGVfQ29ob3J0X2xpc3QpKQpybShtYXN0ZXJmaWxlKQpgYGAKCkFwcGVuZCBwYXRpZW50IHBhdGggZGF0YQpgYGB7cn0KVmlQX092Q2FfUGF0aF9EYXRhIDwtIHJlYWQuZGVsaW0oIlZpUF9PdkNhX1BhdGhfRGF0YS50eHQiLCBoZWFkZXI9VFJVRSwgcm93Lm5hbWVzPU5VTEwsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJTYW1wbGUiPUV4b21lLklEKQptYXN0ZXJmaWxlX2VvY193aXRoUGF0aCA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2MsVmlQX092Q2FfUGF0aF9EYXRhLGJ5PSJTYW1wbGUiLGNvcHk9RkFMU0UpCnJtKG1hc3RlcmZpbGVfZW9jKQpgYGAKCkV4Y2x1ZGUgbG93LXF1YWxpdHkgdmFyaWFudHMsIEdub21BRCBSRi9JbmJyZWVkaW5nQ29lZmYtZmxhZ2dlZCB2YXJpYW50cyBhbmQgcHJvdGVpbi1jb2RpbmcgdHJhbnNjcmlwdHMKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2Nfd2l0aFBhdGgsIChRVUFMPj0zMCkmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJZGVudGlmaWVkIT0iRmlsdGVyZWRJbkFsbCIpJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoU2FtcGxlLlBNQ0RQPj0xMCkmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChTYW1wbGUuUE1DRlJFUT49MC4yNSkpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCghc3RyX2RldGVjdChHbm9tQURfdjIuMV9GSUxURVJfZXhvbWUsIkluYnJlZWRpbmdDb2VmZiIpJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXN0cl9kZXRlY3QoR25vbUFEX3YyLjFfRklMVEVSX2V4b21lLCJSRiIpKXwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXMubmEoR25vbUFEX3YyLjFfRklMVEVSX2V4b21lKSkgJT4lIAogIGZpbHRlcigoIXN0cl9kZXRlY3QoR25vbUFEX3YyLjFfRklMVEVSX2dlbm9tZSwiSW5icmVlZGluZ0NvZWZmIikmCiAgICAgICAgICAgICFzdHJfZGV0ZWN0KEdub21BRF92Mi4xX0ZJTFRFUl9nZW5vbWUsIlJGIikpfAogICAgICAgICAgIGlzLm5hKEdub21BRF92Mi4xX0ZJTFRFUl9nZW5vbWUpKSAlPiUgCiAgZmlsdGVyKCFCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpCnJtKG1hc3RlcmZpbGVfZW9jX3dpdGhQYXRoKQpgYGAKCkV4Y2x1ZGUgb3RoZXIgbXV0YXRpb24gK3ZlIHNhbXBsZXMgKE1MSDEvTVNIMi9NU0g2L1BNUzIsIFRQNTMsIFJBRDUxQy9ELCBCUklQMSkKYGBge3J9ClZpUF9EaXNjb3ZlcnlfQ29ob3J0IDwtIHJlYWQuZGVsaW0oIlZpUF9Mb0ZfRGlzY292ZXJ5X0NvaG9ydC50eHQiLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQpWaVBfRGlzY292ZXJ5X0NvaG9ydF9saXN0IDwtIFZpUF9EaXNjb3ZlcnlfQ29ob3J0WywxXQoKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMiA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRLFNhbXBsZSVpbiVjKFZpUF9EaXNjb3ZlcnlfQ29ob3J0X2xpc3QpKQpgYGAKCkV4Y2x1ZGUgTU9ESUZJRVIgaW1wYWN0IHZhcmlhbnRzICsgYW55IG5vbi1wcm90ZWluLWNvZGluZy10cmFuc2NyaXB0cyB3aXRoIGEgdHJhbnNjcmliZWQgcHJvdGVpbiBFTlNQIElEIGUuZy4gaW1tdW5lIHN5c3RlbSBnZW5lcyArIGFueSAncHNldWRvZ2VuZXMnICgrIEdub21BRCBwb3BtYXggQUYgPiAwLjAwNSBpZiBuZWVkZWQpCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEsIElNUEFDVCVpbiVjKCJISUdIIiwiTU9ERVJBVEUiLCJMT1ciKSkgJT4lIAogIGZpbHRlcighZ3JlcGwoIkVOU1AiLEVOU1ApKSAlPiUgCiAgZmlsdGVyKCFncmVwbCgicHNldWRvZ2VuZSIsQklPVFlQRSkpICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGwgPSBGQUxTRSkKCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyLCBJTVBBQ1QlaW4lYygiSElHSCIsIk1PREVSQVRFIiwiTE9XIikpICU+JSAKICBmaWx0ZXIoIWdyZXBsKCJFTlNQIixFTlNQKSkgJT4lIAogIGZpbHRlcighZ3JlcGwoInBzZXVkb2dlbmUiLEJJT1RZUEUpKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsID0gRkFMU0UpCmBgYAoKRXhjbHVkZSBNT0RJRklFUiBpbXBhY3QgdmFyaWFudHMgKyBhbnkgbm9uLXByb3RlaW4tY29kaW5nLXRyYW5zY3JpcHRzIG90aGVyIHRoYW4gJ2xpbmNSTkFzJyAoKyBHbm9tQUQgcG9wbWF4IEFGID4gMC4wMDUgaWYgbmVlZGVkKQpgYGB7cn0KbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTEwgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUSwgSU1QQUNUJWluJWMoIkhJR0giLCJNT0RFUkFURSIsIkxPVyIpKSAlPiUgCiAgZmlsdGVyKEJJT1RZUEUlaW4lImxpbmNSTkEiKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsID0gRkFMU0UpCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTEwgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTIsIElNUEFDVCVpbiVjKCJISUdIIiwiTU9ERVJBVEUiLCJMT1ciKSkgJT4lIAogIGZpbHRlcihCSU9UWVBFJWluJSJsaW5jUk5BIikgJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbCA9IEZBTFNFKQpgYGAKClNlcGFyYXRlIEVuc2VtYmwgY2Fub25pY2FsIGFuZCBSZWZTZXEgY2Fub25pY2FsIHZhcmlhbnRzCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWwgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTEwsQ0FOT05JQ0FMPT0iWUVTIikgCgptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTCxDQU5PTklDQUw9PSJZRVMiKQoKbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTExfRU5TVGNhbm9uaWNhbCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTEwsQ0FOT05JQ0FMPT0iWUVTIikgCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbCA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMLENBTk9OSUNBTD09IllFUyIpIApgYGAKClNhbXBsZSB2YXJpYW50IGNvdW50cyBhbmQgQUZzCmBgYHtyfQp2YXJpYW50c19oZXRlcm96eWdvdXMgPC0gbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgcmVuYW1lKGFsbGVsZXMgPSAibigpIikgJT4lIAogIGdyb3VwX2J5KEhHVlNjKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShhbGxlbGVzKSkKdmFyaWFudHNfaG9tb3p5Z291cyA8LSBtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWwgJT4lIAogIHNlbGVjdChIR1ZTYyxTYW1wbGUuR1QpICU+JSAKICBncm91cF9ieShIR1ZTYyxTYW1wbGUuR1QpICU+JSAKICBzdW1tYXJpc2UobigpKSAlPiUgCiAgZmlsdGVyKChTYW1wbGUuR1QhPSInMC8xIikmKFNhbXBsZS5HVCE9IicxLzAiKSkgJT4lIAogIG11dGF0ZShhbGxlbGVzID0gYG4oKWAqMikgJT4lIAogIHNlbGVjdCgtYG4oKWApICU+JSAKICBncm91cF9ieShIR1ZTYykgJT4lIAogIHN1bW1hcmlzZShzdW0oYWxsZWxlcykpCnZhcmlhbnRzIDwtIGZ1bGxfam9pbih2YXJpYW50c19oZXRlcm96eWdvdXMsdmFyaWFudHNfaG9tb3p5Z291cyxieT0iSEdWU2MiLGNvcHk9RkFMU0Usc3VmZml4PWMoIi54IiwiLnkiKSkgJT4lCiAgbXV0YXRlX2FsbChmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkgJT4lIAogIG11dGF0ZShUb3RhbF9BbGxlbGVfQ291bnQ9YHN1bShhbGxlbGVzKS54YCtgc3VtKGFsbGVsZXMpLnlgKSAlPiUgCiAgbXV0YXRlKFNhbXBsZV9BRj1Ub3RhbF9BbGxlbGVfQ291bnQvKG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTEwkU2FtcGxlKSoyKSkKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsXzIgPC0gbGVmdF9qb2luKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTExfRU5TVGNhbm9uaWNhbCx2YXJpYW50c1ssYygxLDQ6NSldLGJ5PSJIR1ZTYyIsY29weT1GQUxTRSkKCnZhcmlhbnRzX2hldGVyb3p5Z291cyA8LSBtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgcmVuYW1lKGFsbGVsZXMgPSAibigpIikgJT4lIAogIGdyb3VwX2J5KEhHVlNjKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShhbGxlbGVzKSkKdmFyaWFudHNfaG9tb3p5Z291cyA8LSBtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUIT0iJzAvMSIpJihTYW1wbGUuR1QhPSInMS8wIikpICU+JSAKICBtdXRhdGUoYWxsZWxlcyA9IGBuKClgKjIpICU+JSAKICBzZWxlY3QoLWBuKClgKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGFsbGVsZXMpKQp2YXJpYW50cyA8LSBmdWxsX2pvaW4odmFyaWFudHNfaGV0ZXJvenlnb3VzLHZhcmlhbnRzX2hvbW96eWdvdXMsYnk9IkhHVlNjIixjb3B5PUZBTFNFLHN1ZmZpeD1jKCIueCIsIi55IikpICU+JQogIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGUoVG90YWxfQWxsZWxlX0NvdW50PWBzdW0oYWxsZWxlcykueGArYHN1bShhbGxlbGVzKS55YCkgJT4lIAogIG11dGF0ZShTYW1wbGVfQUY9VG90YWxfQWxsZWxlX0NvdW50LyhuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMJFNhbXBsZSkqMikpCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfMiA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbCx2YXJpYW50c1ssYygxLDQ6NSldLGJ5PSJIR1ZTYyIsY29weT1GQUxTRSkKCnZhcmlhbnRzX2hldGVyb3p5Z291cyA8LSBtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgcmVuYW1lKGFsbGVsZXMgPSAibigpIikgJT4lIAogIGdyb3VwX2J5KEhHVlNjKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShhbGxlbGVzKSkKdmFyaWFudHNfaG9tb3p5Z291cyA8LSBtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUIT0iJzAvMSIpJihTYW1wbGUuR1QhPSInMS8wIikpICU+JSAKICBtdXRhdGUoYWxsZWxlcyA9IGBuKClgKjIpICU+JSAKICBzZWxlY3QoLWBuKClgKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGFsbGVsZXMpKQp2YXJpYW50cyA8LSBmdWxsX2pvaW4odmFyaWFudHNfaGV0ZXJvenlnb3VzLHZhcmlhbnRzX2hvbW96eWdvdXMsYnk9IkhHVlNjIixjb3B5PUZBTFNFLHN1ZmZpeD1jKCIueCIsIi55IikpICU+JQogIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGUoVG90YWxfQWxsZWxlX0NvdW50PWBzdW0oYWxsZWxlcykueGArYHN1bShhbGxlbGVzKS55YCkgJT4lIAogIG11dGF0ZShTYW1wbGVfQUY9VG90YWxfQWxsZWxlX0NvdW50LyhuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTIkU2FtcGxlKSoyKSkKbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTExfRU5TVGNhbm9uaWNhbF8yIDwtIGxlZnRfam9pbihtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsLHZhcmlhbnRzWyxjKDEsNDo1KV0sYnk9IkhHVlNjIixjb3B5PUZBTFNFKQoKdmFyaWFudHNfaGV0ZXJvenlnb3VzIDwtIG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsICU+JSAKICBzZWxlY3QoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoSEdWU2MsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgcmVuYW1lKGFsbGVsZXMgPSAibigpIikgJT4lIAogIGdyb3VwX2J5KEhHVlNjKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShhbGxlbGVzKSkKdmFyaWFudHNfaG9tb3p5Z291cyA8LSBtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbCAlPiUgCiAgc2VsZWN0KEhHVlNjLFNhbXBsZS5HVCkgJT4lIAogIGdyb3VwX2J5KEhHVlNjLFNhbXBsZS5HVCkgJT4lIAogIHN1bW1hcmlzZShuKCkpICU+JSAKICBmaWx0ZXIoKFNhbXBsZS5HVCE9IicwLzEiKSYoU2FtcGxlLkdUIT0iJzEvMCIpKSAlPiUgCiAgbXV0YXRlKGFsbGVsZXMgPSBgbigpYCoyKSAlPiUgCiAgc2VsZWN0KC1gbigpYCkgJT4lIAogIGdyb3VwX2J5KEhHVlNjKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShhbGxlbGVzKSkKdmFyaWFudHMgPC0gZnVsbF9qb2luKHZhcmlhbnRzX2hldGVyb3p5Z291cyx2YXJpYW50c19ob21venlnb3VzLGJ5PSJIR1ZTYyIsY29weT1GQUxTRSxzdWZmaXg9YygiLngiLCIueSIpKSAlPiUKICBtdXRhdGVfYWxsKGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUgCiAgbXV0YXRlKFRvdGFsX0FsbGVsZV9Db3VudD1gc3VtKGFsbGVsZXMpLnhgK2BzdW0oYWxsZWxlcykueWApICU+JSAKICBtdXRhdGUoU2FtcGxlX0FGPVRvdGFsX0FsbGVsZV9Db3VudC8obl9kaXN0aW5jdChtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyJFNhbXBsZSkqMikpCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsXzIgPC0gbGVmdF9qb2luKG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsLHZhcmlhbnRzWyxjKDEsNDo1KV0sYnk9IkhHVlNjIixjb3B5PUZBTFNFKQpgYGAKCkV4Y2x1ZGUgdmFyaWFudHMgd2l0aCBzYW1wbGUgQUYgPjAuMDEKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTExfRU5TVGNhbm9uaWNhbF8yLFNhbXBsZV9BRiA8IDAuMDEpCgptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF8yLFNhbXBsZV9BRiA8IDAuMDEpCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSA8LSBmaWx0ZXIobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTExfRU5TVGNhbm9uaWNhbF8yLFNhbXBsZV9BRiA8IDAuMDEpCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsXzIsU2FtcGxlX0FGIDwgMC4wMSkKYGBgCgpPdXRwdXQgbGlzdCBvZiBnZW5lcyBhbmQgdmFyaWFudHMgd2l0aCBzYW1wbGUgQUYgPjAuMDEKYGBge3J9Cm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfZ2VuZXNhbmR2YXJpYW50czAuMDEgPC0gZmlsdGVyKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfMixTYW1wbGVfQUYgPiAwLjAxKQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxWyxjKDI6NiwyNTo1NCldICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGwgPSBGQUxTRSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihmaWxlPSJtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxLmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxIDwtIGZpbHRlcihtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF8yLFNhbXBsZV9BRiA+IDAuMDEpCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX2dlbmVzYW5kdmFyaWFudHMwLjAxWyxjKDI6NiwyNTo1NCldICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGwgPSBGQUxTRSkgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihmaWxlPSJtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9nZW5lc2FuZHZhcmlhbnRzMC4wMS5jc3YiLG5hPSIuIixhcHBlbmQ9RkFMU0UsY29sX25hbWVzPVRSVUUpCmBgYAoKU2FtcGxlIGdlbmUgY291bnRzIGFuZCBmcmVxdWVuY2llcwpgYGB7cn0KZ2VuZXNfb25lVmFyQWxsZWxlIDwtIG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEgJT4lIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIGdyb3VwX2J5KEdlbmUsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgcmVuYW1lKGdlbmVfVmFyID0gIm4oKSIpICU+JSAKICBncm91cF9ieShHZW5lKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShnZW5lX1ZhcikpCmdlbmVzX3R3b1ZhckFsbGVsZSA8LSBtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxICU+JSBzZWxlY3QoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBzZWxlY3QoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBncm91cF9ieShHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHN1bW1hcmlzZShuKCkpICU+JSAKICBmaWx0ZXIoKFNhbXBsZS5HVCE9IicwLzEiKSYoU2FtcGxlLkdUIT0iJzEvMCIpKSAlPiUgCiAgbXV0YXRlKGdlbmVfVmFyID0gYG4oKWAqMikgJT4lIAogIHNlbGVjdCgtYG4oKWApICU+JSAKICBncm91cF9ieShHZW5lKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShnZW5lX1ZhcikpCmdlbmVzIDwtIGZ1bGxfam9pbihnZW5lc19vbmVWYXJBbGxlbGUsZ2VuZXNfdHdvVmFyQWxsZWxlLGJ5PSJHZW5lIixjb3B5PUZBTFNFLHN1ZmZpeD1jKCIueCIsIi55IikpICU+JSAKICBtdXRhdGVfYWxsKGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUgCiAgbXV0YXRlKFRvdGFsX0dlbmVfQ291bnQ9YHN1bShnZW5lX1ZhcikueGArYHN1bShnZW5lX1ZhcikueWApICU+JSAKICBtdXRhdGUoU2FtcGxlX0dlbmVfRnJlcT1Ub3RhbF9HZW5lX0NvdW50LyhuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMJFNhbXBsZSkqMikpCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMiA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSwgZ2VuZXNbLGMoMSw0OjUpXSxieT0iR2VuZSIsY29weT1GQUxTRSkKCmdlbmVzX29uZVZhckFsbGVsZSA8LSBtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSAlPiUgc2VsZWN0KEdlbmUsU2FtcGxlLkdUKSAlPiUgCiAgc2VsZWN0KEdlbmUsU2FtcGxlLkdUKSAlPiUgCiAgZ3JvdXBfYnkoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBzdW1tYXJpc2UobigpKSAlPiUgCiAgZmlsdGVyKChTYW1wbGUuR1QlaW4lYygiJzAvMSIsIicxLzAiKSkpICU+JSAKICByZW5hbWUoZ2VuZV9WYXIgPSAibigpIikgJT4lIAogIGdyb3VwX2J5KEdlbmUpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGdlbmVfVmFyKSkKZ2VuZXNfdHdvVmFyQWxsZWxlIDwtIG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxICU+JSBzZWxlY3QoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBzZWxlY3QoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBncm91cF9ieShHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHN1bW1hcmlzZShuKCkpICU+JSAKICBmaWx0ZXIoKFNhbXBsZS5HVCE9IicwLzEiKSYoU2FtcGxlLkdUIT0iJzEvMCIpKSAlPiUgCiAgbXV0YXRlKGdlbmVfVmFyID0gYG4oKWAqMikgJT4lIAogIHNlbGVjdCgtYG4oKWApICU+JSAKICBncm91cF9ieShHZW5lKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShnZW5lX1ZhcikpCmdlbmVzIDwtIGZ1bGxfam9pbihnZW5lc19vbmVWYXJBbGxlbGUsZ2VuZXNfdHdvVmFyQWxsZWxlLGJ5PSJHZW5lIixjb3B5PUZBTFNFLHN1ZmZpeD1jKCIueCIsIi55IikpICU+JSAKICBtdXRhdGVfYWxsKGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUgCiAgbXV0YXRlKFRvdGFsX0dlbmVfQ291bnQ9YHN1bShnZW5lX1ZhcikueGArYHN1bShnZW5lX1ZhcikueWApICU+JSAKICBtdXRhdGUoU2FtcGxlX0dlbmVfRnJlcT1Ub3RhbF9HZW5lX0NvdW50LyhuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMJFNhbXBsZSkqMikpCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxXzIgPC0gbGVmdF9qb2luKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxLCBnZW5lc1ssYygxLDQ6NSldLGJ5PSJHZW5lIixjb3B5PUZBTFNFKQoKZ2VuZXNfb25lVmFyQWxsZWxlIDwtIG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxICU+JSBzZWxlY3QoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBzZWxlY3QoR2VuZSxTYW1wbGUuR1QpICU+JSAKICBncm91cF9ieShHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHN1bW1hcmlzZShuKCkpICU+JSAKICBmaWx0ZXIoKFNhbXBsZS5HVCVpbiVjKCInMC8xIiwiJzEvMCIpKSkgJT4lIAogIHJlbmFtZShnZW5lX1ZhciA9ICJuKCkiKSAlPiUgCiAgZ3JvdXBfYnkoR2VuZSkgJT4lIAogIHN1bW1hcmlzZShzdW0oZ2VuZV9WYXIpKQpnZW5lc190d29WYXJBbGxlbGUgPC0gbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEgJT4lIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIGdyb3VwX2J5KEdlbmUsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUIT0iJzAvMSIpJihTYW1wbGUuR1QhPSInMS8wIikpICU+JSAKICBtdXRhdGUoZ2VuZV9WYXIgPSBgbigpYCoyKSAlPiUgCiAgc2VsZWN0KC1gbigpYCkgJT4lIAogIGdyb3VwX2J5KEdlbmUpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGdlbmVfVmFyKSkKZ2VuZXMgPC0gZnVsbF9qb2luKGdlbmVzX29uZVZhckFsbGVsZSxnZW5lc190d29WYXJBbGxlbGUsYnk9IkdlbmUiLGNvcHk9RkFMU0Usc3VmZml4PWMoIi54IiwiLnkiKSkgJT4lIAogIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGUoVG90YWxfR2VuZV9Db3VudD1gc3VtKGdlbmVfVmFyKS54YCtgc3VtKGdlbmVfVmFyKS55YCkgJT4lIAogIG11dGF0ZShTYW1wbGVfR2VuZV9GcmVxPVRvdGFsX0dlbmVfQ291bnQvKG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMiRTYW1wbGUpKjIpKQptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yIDwtIGxlZnRfam9pbihtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMSwgZ2VuZXNbLGMoMSw0OjUpXSxieT0iR2VuZSIsY29weT1GQUxTRSkKCmdlbmVzX29uZVZhckFsbGVsZSA8LSBtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEgJT4lIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIGdyb3VwX2J5KEdlbmUsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUJWluJWMoIicwLzEiLCInMS8wIikpKSAlPiUgCiAgcmVuYW1lKGdlbmVfVmFyID0gIm4oKSIpICU+JSAKICBncm91cF9ieShHZW5lKSAlPiUgCiAgc3VtbWFyaXNlKHN1bShnZW5lX1ZhcikpCmdlbmVzX3R3b1ZhckFsbGVsZSA8LSBtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDEgJT4lIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIHNlbGVjdChHZW5lLFNhbXBsZS5HVCkgJT4lIAogIGdyb3VwX2J5KEdlbmUsU2FtcGxlLkdUKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIGZpbHRlcigoU2FtcGxlLkdUIT0iJzAvMSIpJihTYW1wbGUuR1QhPSInMS8wIikpICU+JSAKICBtdXRhdGUoZ2VuZV9WYXIgPSBgbigpYCoyKSAlPiUgCiAgc2VsZWN0KC1gbigpYCkgJT4lIAogIGdyb3VwX2J5KEdlbmUpICU+JSAKICBzdW1tYXJpc2Uoc3VtKGdlbmVfVmFyKSkKZ2VuZXMgPC0gZnVsbF9qb2luKGdlbmVzX29uZVZhckFsbGVsZSxnZW5lc190d29WYXJBbGxlbGUsYnk9IkdlbmUiLGNvcHk9RkFMU0Usc3VmZml4PWMoIi54IiwiLnkiKSkgJT4lIAogIG11dGF0ZV9hbGwoZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGUoVG90YWxfR2VuZV9Db3VudD1gc3VtKGdlbmVfVmFyKS54YCtgc3VtKGdlbmVfVmFyKS55YCkgJT4lIAogIG11dGF0ZShTYW1wbGVfR2VuZV9GcmVxPVRvdGFsX0dlbmVfQ291bnQvKG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMiRTYW1wbGUpKjIpKQptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMiA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxLCBnZW5lc1ssYygxLDQ6NSldLGJ5PSJHZW5lIixjb3B5PUZBTFNFKQpgYGAKCkFkZCBHbm9tQUQgZ2VuZS1sZXZlbCBkYXRhCmBgYHtyfQplbnNlbWJsX2Jpb3R5cGVzIDwtIHJlYWQuZGVsaW0oImVuc2VtYmxfYmlvdHlwZXMudHN2Iiwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIHNlbGVjdChlbnNlbWJsX3RyYW5zY3JpcHRfaWQsdHJhbnNjcmlwdF9iaW90eXBlKSAlPiUgCiAgZHBseXI6OnJlbmFtZSgiRmVhdHVyZSI9ImVuc2VtYmxfdHJhbnNjcmlwdF9pZCIsIkJJT1RZUEUiPSJ0cmFuc2NyaXB0X2Jpb3R5cGUiKQoKQWdpbGVudFNTdjZfbGlzdF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZyA8LSByZWFkLmRlbGltKCJHbm9tQUQuZ2VuZS5zdGF0cy52Mi5SRi5vbmx5LmFnaWxlbnQudjYub25seS50c3YiLCBoZWFkZXI9VFJVRSwgcm93Lm5hbWVzPU5VTEwsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpICU+JSAKICBmaWx0ZXIoQ0FOT05JQ0FMPT0iWUVTIikgJT4lIAogIGRwbHlyOjpyZW5hbWUoIlNZTUJPTCI9IlguU3ltYm9sIikgJT4lIAogIGRwbHlyOjpyZW5hbWUoIkdlbmUiPSJFTlNHIikgJT4lIAogIGxlZnRfam9pbihlbnNlbWJsX2Jpb3R5cGVzLGJ5PSJGZWF0dXJlIixjb3B5PUZBTFNFKSAlPiUgCiAgZmlsdGVyKCFCSU9UWVBFJWluJWMoInByb3RlaW5fY29kaW5nIikpICU+JSAKICBmaWx0ZXIoIWdyZXBsKCJFTlNQIixFTlNQKSkgJT4lIAogIGZpbHRlcighZ3JlcGwoInBzZXVkb2dlbmUiLEJJT1RZUEUpKSAlPiUgCiAgc2VsZWN0KFNZTUJPTCxGZWF0dXJlLEdlbmUsQklPVFlQRSkgJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbCA9IEZBTFNFKQoKQWdpbGVudFNTdjZfbGlzdF9FTlNUY2Fub25pY2FsX2xpbmNSTkEgPC0gcmVhZC5kZWxpbSgiR25vbUFELmdlbmUuc3RhdHMudjIuUkYub25seS5hZ2lsZW50LnY2Lm9ubHkudHN2IiwgaGVhZGVyPVRSVUUsIHJvdy5uYW1lcz1OVUxMLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKSAlPiUgCiAgZmlsdGVyKENBTk9OSUNBTD09IllFUyIpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJTWU1CT0wiPSJYLlN5bWJvbCIpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJHZW5lIj0iRU5TRyIpICU+JSAKICBsZWZ0X2pvaW4oZW5zZW1ibF9iaW90eXBlcyxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgJT4lIAogIGZpbHRlcihCSU9UWVBFJWluJSJsaW5jUk5BIikgJT4lIAogIHNlbGVjdChTWU1CT0wsRmVhdHVyZSxHZW5lLEJJT1RZUEUpICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGwgPSBGQUxTRSkKCkdub21BRF9zdGF0c19BTExfVkVQX0VOU1RjYW5vbmljYWxfbm9uX3Byb3RlaW5fY29kaW5nIDwtIHJlYWQuZGVsaW0oImFnaWxlbnRfdjZfZ25vbWFkX3YyLjEuMV9nZW5lc3RhdHNfY2Fub25pY2FsX2FsbElNUEFDVFMudHN2IiwgaGVhZGVyPVRSVUUsIHJvdy5uYW1lcz1OVUxMLCBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKSAlPiUgCiAgZmlsdGVyKEZlYXR1cmUlaW4lKEFnaWxlbnRTU3Y2X2xpc3RfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmckRmVhdHVyZSkpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJHZW5lIj0iRU5TRyIpCgpHbm9tQURfc3RhdHNfQUxMX1ZFUF9FTlNUY2Fub25pY2FsX2xpbmNSTkEgPC0gcmVhZC5kZWxpbSgiYWdpbGVudF92Nl9nbm9tYWRfdjIuMS4xX2dlbmVzdGF0c19jYW5vbmljYWxfYWxsSU1QQUNUUy50c3YiLCBoZWFkZXI9VFJVRSwgcm93Lm5hbWVzPU5VTEwsIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpICU+JSAKICBmaWx0ZXIoRmVhdHVyZSVpbiUoQWdpbGVudFNTdjZfbGlzdF9FTlNUY2Fub25pY2FsX2xpbmNSTkEkRmVhdHVyZSkpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJHZW5lIj0iRU5TRyIpCgptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cyA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV8yLCBHbm9tQURfc3RhdHNfQUxMX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZ1ssYygyLDE0OjE5KV0sYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpIAptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIgPC0gbXV0YXRlX2F0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUV9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzLHZhcnMoc3RhcnRzX3dpdGgoIkZJTFRFUl8iKSksZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGVfaWYoZ3JlcGwoInBvcG1heCQiLCBuYW1lcyguKSksZnVucyhpZmVsc2UoLiA9PSAiTkEiLCAwLCBhcy5udW1lcmljKC4pKSkpICU+JSAKICBtdXRhdGVfYXQodmFycyhlbmRzX3dpdGgoInBvcG1heCIpKSxmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkKCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cyA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMiwgR25vbUFEX3N0YXRzX0FMTF9WRVBfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmdbLGMoMiwxNDoxOSldLGJ5PSJGZWF0dXJlIixjb3B5PUZBTFNFKSAKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzMiA8LSBtdXRhdGVfYXQobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzLHZhcnMoc3RhcnRzX3dpdGgoIkZJTFRFUl8iKSksZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGVfaWYoZ3JlcGwoInBvcG1heCQiLCBuYW1lcyguKSksZnVucyhpZmVsc2UoLiA9PSAiTkEiLCAwLCBhcy5udW1lcmljKC4pKSkpICU+JSAKICBtdXRhdGVfYXQodmFycyhlbmRzX3dpdGgoInBvcG1heCIpKSxmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkKCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cyA8LSBsZWZ0X2pvaW4obWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUV9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMiwgR25vbUFEX3N0YXRzX0FMTF9WRVBfRU5TVGNhbm9uaWNhbF9saW5jUk5BWyxjKDIsMTQ6MTkpXSxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIgPC0gbXV0YXRlX2F0KG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cyx2YXJzKHN0YXJ0c193aXRoKCJGSUxURVJfIikpLGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUgCiAgbXV0YXRlX2lmKGdyZXBsKCJwb3BtYXgkIiwgbmFtZXMoLikpLGZ1bnMoaWZlbHNlKC4gPT0gIk5BIiwgMCwgYXMubnVtZXJpYyguKSkpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoZW5kc193aXRoKCJwb3BtYXgiKSksZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzIDwtIGxlZnRfam9pbihtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfMiwgR25vbUFEX3N0YXRzX0FMTF9WRVBfRU5TVGNhbm9uaWNhbF9saW5jUk5BWyxjKDIsMTQ6MTkpXSxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyIDwtIG11dGF0ZV9hdChtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzLHZhcnMoc3RhcnRzX3dpdGgoIkZJTFRFUl8iKSksZnVucyhyZXBsYWNlKC4sIGlzLm5hKC4pLCAwKSkpICU+JSAKICBtdXRhdGVfaWYoZ3JlcGwoInBvcG1heCQiLCBuYW1lcyguKSksZnVucyhpZmVsc2UoLiA9PSAiTkEiLCAwLCBhcy5udW1lcmljKC4pKSkpICU+JSAKICBtdXRhdGVfYXQodmFycyhlbmRzX3dpdGgoInBvcG1heCIpKSxmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkKYGBgCgpDYWxjdWxhdGUgU2FtcGxlL0dub21BRCBnZW5lIGZyZXEgYW5kIGFsbGVsZSBmcmVxIHJhdGlvcyBmb3IgdG90YWwgYW5kIE5GRSBHbm9tQUQgZmlndXJlcwpgYGB7cn0KbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cywKIlNhbXBsZV9HZW5lX0FMTF9GcmVxX1JhdGlvX0dub21BRF8wLjAwNSI9U2FtcGxlX0dlbmVfRnJlcS9GSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUZfMC4wMDVfQURKLCAgICAgICJTYW1wbGVfR2VuZV9BTExfRnJlcV9SYXRpb19Hbm9tQURfTkZFXzAuMDA1Ij1TYW1wbGVfR2VuZV9GcmVxL0ZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9ORkVfQURKLCAgICAgICJTYW1wbGVfR2VuZV9BTExfQUZfUmF0aW8iPVNhbXBsZV9BRi9Hbm9tQURfdjIuMV9ub25fY2FuY2VyX0FGLCAKIlNhbXBsZV9HZW5lX0FMTF9BRl9SYXRpb19ORkUiPVNhbXBsZV9BRi9Hbm9tQURfdjIuMV9ub25fY2FuY2VyX0FGX25mZSkKCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cywgIlNhbXBsZV9HZW5lX0FMTF9GcmVxX1JhdGlvX0dub21BRF8wLjAwNSI9U2FtcGxlX0dlbmVfRnJlcS9GSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUZfMC4wMDVfQURKLCAgICAgICJTYW1wbGVfR2VuZV9BTExfRnJlcV9SYXRpb19Hbm9tQURfTkZFXzAuMDA1Ij1TYW1wbGVfR2VuZV9GcmVxL0ZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9ORkVfQURKLCAgICAgICJTYW1wbGVfR2VuZV9BTExfQUZfUmF0aW8iPVNhbXBsZV9BRi9Hbm9tQURfdjIuMV9ub25fY2FuY2VyX0FGLCAKIlNhbXBsZV9HZW5lX0FMTF9BRl9SYXRpb19ORkUiPVNhbXBsZV9BRi9Hbm9tQURfdjIuMV9ub25fY2FuY2VyX0FGX25mZSkKCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFFfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0cywKIlNhbXBsZV9HZW5lX0FMTF9GcmVxX1JhdGlvX0dub21BRF8wLjAwNSI9U2FtcGxlX0dlbmVfRnJlcS9GSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUZfMC4wMDVfQURKLCAgICAgICJTYW1wbGVfR2VuZV9BTExfRnJlcV9SYXRpb19Hbm9tQURfTkZFXzAuMDA1Ij1TYW1wbGVfR2VuZV9GcmVxL0ZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9ORkVfQURKLCAgICAgICJTYW1wbGVfR2VuZV9BTExfQUZfUmF0aW8iPVNhbXBsZV9BRi9Hbm9tQURfdjIuMV9ub25fY2FuY2VyX0FGLCAKIlNhbXBsZV9HZW5lX0FMTF9BRl9SYXRpb19ORkUiPVNhbXBsZV9BRi9Hbm9tQURfdjIuMV9ub25fY2FuY2VyX0FGX25mZSkKCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyIDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzLCAiU2FtcGxlX0dlbmVfQUxMX0ZyZXFfUmF0aW9fR25vbUFEXzAuMDA1Ij1TYW1wbGVfR2VuZV9GcmVxL0ZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9BREosICAgICAgIlNhbXBsZV9HZW5lX0FMTF9GcmVxX1JhdGlvX0dub21BRF9ORkVfMC4wMDUiPVNhbXBsZV9HZW5lX0ZyZXEvRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FGXzAuMDA1X05GRV9BREosICAgICAgIlNhbXBsZV9HZW5lX0FMTF9BRl9SYXRpbyI9U2FtcGxlX0FGL0dub21BRF92Mi4xX25vbl9jYW5jZXJfQUYsIAoiU2FtcGxlX0dlbmVfQUxMX0FGX1JhdGlvX05GRSI9U2FtcGxlX0FGL0dub21BRF92Mi4xX25vbl9jYW5jZXJfQUZfbmZlKQpgYGAKCkNyZWF0ZSBkYXRhIGZyYW1lcyB3aXRoIEFnaWxlbnQgU3VyZVNlbGVjdCB3aG9sZSBleG9tZSBnZW5lcyAoRU5TVCBhbmQgbm9uLXByb3RlaW4tY29kaW5nKSBmb3Igdm9sY2FubyBwbG90cwpgYGB7cn0KYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSA8LSBHbm9tQURfc3RhdHNfQUxMX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZ1ssYygxOjMsNiwxMCldICU+JSAKICBmaWx0ZXIoTUFYX0FOX05GRSE9MCkgJT4lIAogIGxlZnRfam9pbihBZ2lsZW50U1N2Nl9saXN0X0VOU1RjYW5vbmljYWxfbm9uX3Byb3RlaW5fY29kaW5nWyxjKDIsNCldLGJ5PSJGZWF0dXJlIixjb3B5PUZBTFNFKQoKYWxsR2VuZXNfbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19saXN0IDwtIHRpYmJsZSgiU1lNQk9MIj1tYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyJFNZTUJPTCwiR2VuZSI9bWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzMiRHZW5lLCJCSU9UWVBFIj1tYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyJEJJT1RZUEUpICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGw9VFJVRSkgJT4lIAogIGFycmFuZ2UoU1lNQk9MKQoKYWxsR2VuZXNfbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9saXN0IDwtIHRpYmJsZSgiU1lNQk9MIj1tYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzMiRTWU1CT0wsIkdlbmUiPW1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyJEdlbmUsIkJJT1RZUEUiPW1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyJEJJT1RZUEUpICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGw9VFJVRSkgJT4lIAogIGFycmFuZ2UoU1lNQk9MKQoKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lcyA8LSBtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHMyICU+JSAKICBtdXRhdGUoVG90YWxfQ2FzZV9BbGxlbGVzPShuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMJFNhbXBsZSkqMikpICU+JSAKICBzZWxlY3QoU1lNQk9MLEdlbmUsVG90YWxfR2VuZV9Db3VudCxUb3RhbF9DYXNlX0FsbGVsZXMsU2FtcGxlX0dlbmVfQUxMX0ZyZXFfUmF0aW9fR25vbUFEXzAuMDA1LFNhbXBsZV9HZW5lX0FMTF9GcmVxX1JhdGlvX0dub21BRF9ORkVfMC4wMDUpICU+JSAKICBkaXN0aW5jdChTWU1CT0wsR2VuZSxUb3RhbF9HZW5lX0NvdW50LFRvdGFsX0Nhc2VfQWxsZWxlcyxTYW1wbGVfR2VuZV9BTExfRnJlcV9SYXRpb19Hbm9tQURfMC4wMDUsU2FtcGxlX0dlbmVfQUxMX0ZyZXFfUmF0aW9fR25vbUFEX05GRV8wLjAwNSkgCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXMyIDwtIGxlZnRfam9pbihhbGxHZW5lc19BZ2lsZW50U1N2Nl9saXN0X25vbl9wcm90ZWluX2NvZGluZ19vbmx5LHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXNbLGMoMjo0KV0sYnk9IkdlbmUiLGNvcHk9RkFMU0UpICU+JSAKICBiaW5kX3Jvd3MoYW50aV9qb2luKGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3Rfbm9uX3Byb3RlaW5fY29kaW5nX29ubHlbLGMoMSwzKV0sdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lcyxieT0iR2VuZSIpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoIlRvdGFsX0dlbmVfQ291bnQiKSxmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIDApKSkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKCJUb3RhbF9DYXNlX0FsbGVsZXMiKSxmdW5zKHJlcGxhY2UoLiwgaXMubmEoLiksIG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTEwkU2FtcGxlKSoyKSkpICU+JSAKICBkaXN0aW5jdChTWU1CT0wsR2VuZSxUb3RhbF9HZW5lX0NvdW50LFRvdGFsX0Nhc2VfQWxsZWxlcykgCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXMzIDwtIHJpZ2h0X2pvaW4oCiAgdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczIsCiAgR25vbUFEX3N0YXRzX0FMTF9WRVBfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmcsCiAgYnk9IkdlbmUiLGNvcHk9RkFMU0UpICU+JSAKICBzZWxlY3QoIlNZTUJPTC54IiwiR2VuZSIsIlRvdGFsX0dlbmVfQ291bnQiLCJUb3RhbF9DYXNlX0FsbGVsZXMiLCJGSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUNfMC4wMDUiLCJGSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUNfMC4wMDVfTkZFIiwiTUFYX0FOIiwiTUFYX0FOX05GRSIsIkZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9BREoiLCJGSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUZfMC4wMDVfTkZFX0FESiIpICU+JSAKICBkcGx5cjo6cmVuYW1lKCJTWU1CT0wiPSJTWU1CT0wueCIpICU+JSAKICBtdXRhdGUoRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FDXzAuMDA1X0FESj1yb3VuZCgoTUFYX0FOKkZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9BREopKSkgJT4lIAogIG11dGF0ZShGSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUNfMC4wMDVfTkZFX0FESj1yb3VuZCgoTUFYX0FOX05GRSpGSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUZfMC4wMDVfTkZFX0FESikpKSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsPVRSVUUpICU+JSAKICBmaWx0ZXIoIWlzLm5hKE1BWF9BTl9ORkUpKSAlPiUgCiAgZmlsdGVyKE1BWF9BTl9ORkUhPTApCgp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMgPC0gbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIgJT4lIAogIG11dGF0ZShUb3RhbF9DYXNlX0FsbGVsZXM9KG5fZGlzdGluY3QobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMiRTYW1wbGUpKjIpKSAlPiUgCiAgIyBmaWx0ZXIoIUJJT1RZUEUlaW4lYygicHJvdGVpbl9jb2RpbmciKSkgJT4lIAogIHNlbGVjdChTWU1CT0wsR2VuZSxUb3RhbF9HZW5lX0NvdW50LFRvdGFsX0Nhc2VfQWxsZWxlcyxTYW1wbGVfR2VuZV9BTExfRnJlcV9SYXRpb19Hbm9tQURfMC4wMDUsU2FtcGxlX0dlbmVfQUxMX0ZyZXFfUmF0aW9fR25vbUFEX05GRV8wLjAwNSkgJT4lIAogIGRpc3RpbmN0KFNZTUJPTCxHZW5lLFRvdGFsX0dlbmVfQ291bnQsVG90YWxfQ2FzZV9BbGxlbGVzLFNhbXBsZV9HZW5lX0FMTF9GcmVxX1JhdGlvX0dub21BRF8wLjAwNSxTYW1wbGVfR2VuZV9BTExfRnJlcV9SYXRpb19Hbm9tQURfTkZFXzAuMDA1KSAKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzMiA8LSBsZWZ0X2pvaW4oYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSx2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXNbLGMoMjo0KV0sYnk9IkdlbmUiLGNvcHk9RkFMU0UpICU+JSAKICBiaW5kX3Jvd3MoYW50aV9qb2luKGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3Rfbm9uX3Byb3RlaW5fY29kaW5nX29ubHlbLGMoMSwzKV0sdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzLGJ5PSJHZW5lIikpICU+JSAKICBtdXRhdGVfYXQodmFycygiVG90YWxfR2VuZV9Db3VudCIpLGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgMCkpKSAlPiUgCiAgbXV0YXRlX2F0KHZhcnMoIlRvdGFsX0Nhc2VfQWxsZWxlcyIpLGZ1bnMocmVwbGFjZSguLCBpcy5uYSguKSwgbl9kaXN0aW5jdChtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyJFNhbXBsZSkqMikpKSAlPiUgCiAgZGlzdGluY3QoU1lNQk9MLEdlbmUsVG90YWxfR2VuZV9Db3VudCxUb3RhbF9DYXNlX0FsbGVsZXMpIAp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzIDwtIHJpZ2h0X2pvaW4oCiAgdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzMiwKICBHbm9tQURfc3RhdHNfQUxMX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZywKICBieT0iR2VuZSIsY29weT1GQUxTRSkgJT4lIAogIHNlbGVjdCgiU1lNQk9MLngiLCJHZW5lIiwiVG90YWxfR2VuZV9Db3VudCIsIlRvdGFsX0Nhc2VfQWxsZWxlcyIsIkZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BQ18wLjAwNSIsIkZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BQ18wLjAwNV9ORkUiLCJNQVhfQU4iLCJNQVhfQU5fTkZFIiwiRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FGXzAuMDA1X0FESiIsIkZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9ORkVfQURKIikgJT4lIAogIGRwbHlyOjpyZW5hbWUoIlNZTUJPTCI9IlNZTUJPTC54IikgJT4lIAogIG11dGF0ZShGSUxURVJfUkZfTE9XLk1PREVSQVRFLkhJR0hfQUNfMC4wMDVfQURKPXJvdW5kKChNQVhfQU4qRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FGXzAuMDA1X0FESikpKSAlPiUgCiAgbXV0YXRlKEZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BQ18wLjAwNV9ORkVfQURKPXJvdW5kKChNQVhfQU5fTkZFKkZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BRl8wLjAwNV9ORkVfQURKKSkpICU+JSAKICBkaXN0aW5jdCgua2VlcF9hbGw9VFJVRSkgJT4lIAogIGZpbHRlcighaXMubmEoTUFYX0FOX05GRSkpICU+JSAKICBmaWx0ZXIoTUFYX0FOX05GRSE9MCkKYGBgCgpDYWxjdWxhdGUgRmlzaGVyJ3MgdGVzdCB2YWx1ZXMgKEVuc2VtYmwgQ2Fub25pY2FsKQpgYGB7cn0KbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIsVG90YWxfQ2FzZV9BbGxlbGVzPShuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMJFNhbXBsZSkqMikpICU+JSAKICBsZWZ0X2pvaW4oR25vbUFEX3N0YXRzX0FMTF9WRVBfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmdbLGMoMiw2LDEwKV0sYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpIAptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzLCBNQVhfQU49cmVwbGFjZShtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0cyRNQVhfQU4sIGlzLm5hKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzJE1BWF9BTiksIG1heChtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0cyRNQVhfQU4sIG5hLnJtPVRSVUUpKSkgJT4lIAogIGZpbHRlcighaXMubmEoTUFYX0FOX05GRSkmCiAgICAgICAgICAgTUFYX0FOX05GRSE9MCkKCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0cyA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0czIsVG90YWxfQ2FzZV9BbGxlbGVzPShuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTIkU2FtcGxlKSoyKSkgJT4lIAogIGxlZnRfam9pbihHbm9tQURfc3RhdHNfQUxMX1ZFUF9FTlNUY2Fub25pY2FsX25vbl9wcm90ZWluX2NvZGluZ1ssYygyLDYsMTApXSxieT0iRmVhdHVyZSIsY29weT1GQUxTRSkgCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0cywgTUFYX0FOPXJlcGxhY2UobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzJE1BWF9BTiwgaXMubmEobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzJE1BWF9BTiksIG1heChtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMkTUFYX0FOLCBuYS5ybT1UUlVFKSkpICU+JSAKICBmaWx0ZXIoIWlzLm5hKE1BWF9BTl9ORkUpJgogICAgICAgICAgIE1BWF9BTl9ORkUhPTApCgpmaXNoZXJyZXN1bHRzX0VOU1QgPC0gYXBwbHkobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyWyxjKDI2MiwyNjQsMjc0LDI3NSldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKHhbM10teFsxXSx4WzRdLXhbMl0pKSl9KQoKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfRU5TVCxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTIpKQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkT1JfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMiRgOTUlQ0lfMC4wMDVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfRU5TVCxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJEJIXzAuMDA1ID0gcC5hZGp1c3QobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1LG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzMl9FTlNUIDwtIGFwcGx5KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMlssYygyNjIsMjY3LDI3NCwyNzYpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyh4WzNdLXhbMV0seFs0XS14WzJdKSkpfSkKCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMiRQX3ZhbHVlX0Zpc2hlcl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0czJfRU5TVCxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTIpKQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkT1JfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX0VOU1QsZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSw0KSkKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJGA5NSVDSV8wLjAwNV9ORkVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX0VOU1QsZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCm1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMiRCSF8wLjAwNV9ORkUgPSBwLmFkanVzdChtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFLG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzX0VOU1QgPC0gYXBwbHkobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMlssYygyNjIsMjY0LDI3NCwyNzUpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyh4WzNdLXhbMV0seFs0XS14WzJdKSkpfSkKCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkT1JfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsNCkpCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkYDk1JUNJXzAuMDA1YCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX0VOU1QsZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkQkhfMC4wMDUgPSBwLmFkanVzdChtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1LG1ldGhvZCA9ICJCSCIpCgpmaXNoZXJyZXN1bHRzMl9FTlNUIDwtIGFwcGx5KG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czJbLGMoMjYyLDI2NywyNzQsMjc2KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoeFszXS14WzFdLHhbNF0teFsyXSkpKX0pCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9FTlNULGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxMikpCm1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkT1JfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHMyX0VOU1QsZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSw0KSkKbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMiRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzMl9FTlNULGZ1bmN0aW9uKHgpIHBhc3RlKHJvdW5kKHgkY29uZi5pbnRbMToyXSwyKSxjb2xsYXBzZT0ifiIpKQptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMyJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czIkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFLG1ldGhvZCA9ICJCSCIpCmBgYAoKQ2FsY3VsYXRlIEZpc2hlcidzIHRlc3QgdmFsdWVzICh2b2xjYW5vIHBsb3QpCmBgYHtyfQpmaXNoZXJyZXN1bHRzX2Jpb3R5cGVOUENfYWxsR2VuZXNfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzM1ssYygzLDUsNCw3KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkUF92YWx1ZV9GaXNoZXJfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlTlBDX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDE1KSkKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkT1JfMC4wMDUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlTlBDX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRlc3RpbWF0ZSwxNSkpCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXMzJGA5NSVDSV8wLjAwNWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlTlBDX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXMzJEJIXzAuMDA1ID0gcC5hZGp1c3Qodm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkUF92YWx1ZV9GaXNoZXJfMC4wMDUsbWV0aG9kID0gIkJIIikKCmZpc2hlcnJlc3VsdHNfYmlvdHlwZU5QQ19ORkVfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzM1ssYygzLDYsNCw4KV0sMSxmdW5jdGlvbih4KSB7ZmlzaGVyLnRlc3QocmJpbmQoeFsxOjJdLGMoYWJzKHhbM10teFsxXSksYWJzKHhbNF0teFsyXSkpKSl9KQoKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZU5QQ19ORkVfdm9sY2FubyxmdW5jdGlvbih4KSByb3VuZCh4JHAudmFsdWUsMTUpKQp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzMyRPUl8wLjAwNV9ORkUgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlTlBDX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsMTUpKQp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzMyRgOTUlQ0lfMC4wMDVfTkZFYCA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVOUENfTkZFX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcGFzdGUocm91bmQoeCRjb25mLmludFsxOjJdLDIpLGNvbGxhcHNlPSJ+IikpCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXMzJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXMzJFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSxtZXRob2QgPSAiQkgiKQoKZmlzaGVycmVzdWx0c19iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXNfdm9sY2FubyA8LSBhcHBseSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzWyxjKDMsNSw0LDcpXSwxLGZ1bmN0aW9uKHgpIHtmaXNoZXIudGVzdChyYmluZCh4WzE6Ml0sYyhhYnMoeFszXS14WzFdKSxhYnMoeFs0XS14WzJdKSkpKX0pCgp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJFBfdmFsdWVfRmlzaGVyXzAuMDA1ID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzX3ZvbGNhbm8sZnVuY3Rpb24oeCkgcm91bmQoeCRwLnZhbHVlLDE1KSkKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzMyRPUl8wLjAwNSA9IHNhcHBseShmaXNoZXJyZXN1bHRzX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lc192b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsMTUpKQp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJGA5NSVDSV8wLjAwNWAgPSBzYXBwbHkoZmlzaGVycmVzdWx0c19iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXNfdm9sY2FubyxmdW5jdGlvbih4KSBwYXN0ZShyb3VuZCh4JGNvbmYuaW50WzE6Ml0sMiksY29sbGFwc2U9In4iKSkKdm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzMyRCSF8wLjAwNSA9IHAuYWRqdXN0KHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMkUF92YWx1ZV9GaXNoZXJfMC4wMDUsbWV0aG9kID0gIkJIIikKCmZpc2hlcnJlc3VsdHNfYmlvdHlwZV9saW5jUk5BX05GRV92b2xjYW5vIDwtIGFwcGx5KHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczNbLGMoMyw2LDQsOCldLDEsZnVuY3Rpb24oeCkge2Zpc2hlci50ZXN0KHJiaW5kKHhbMToyXSxjKGFicyh4WzNdLXhbMV0pLGFicyh4WzRdLXhbMl0pKSkpfSkKCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZV9saW5jUk5BX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkcC52YWx1ZSwxNSkpCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMkT1JfMC4wMDVfTkZFID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZV9saW5jUk5BX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHJvdW5kKHgkZXN0aW1hdGUsMTUpKQp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJGA5NSVDSV8wLjAwNV9ORkVgID0gc2FwcGx5KGZpc2hlcnJlc3VsdHNfYmlvdHlwZV9saW5jUk5BX05GRV92b2xjYW5vLGZ1bmN0aW9uKHgpIHBhc3RlKHJvdW5kKHgkY29uZi5pbnRbMToyXSwyKSxjb2xsYXBzZT0ifiIpKQp2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJEJIXzAuMDA1X05GRSA9IHAuYWRqdXN0KHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMkUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFLG1ldGhvZCA9ICJCSCIpCmBgYAoKSWRlbnRpZnkgdmFyaWFudHMgd2l0aCBmaWx0ZXJpbmcgQUYgPiBtYXhpbXVtIGNyZWRpYmxlIHBvcHVsYXRpb24gQUYgaW4gR25vbUFEIGZvciBoZXJlZGl0YXJ5IEVPQyAoMC4wMDAxODEpCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czMgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMiwgRmlsdGVyaW5nQUZfOTVfRXhjZWVkc19NYXhDcmVkUG9wQUY9KChHbm9tQURfdjIuMV9ub25fY2FuY2VyX0ZpbHRlcmluZ19BRl85NSk+MC4wMDAxODEpKSAlPiUgCiAgbXV0YXRlKEZpbHRlcmluZ0FGXzk1X05GRV9FeGNlZWRzX01heENyZWRQb3BBRj0oKEdub21BRF92Mi4xX25vbl9jYW5jZXJfRmlsdGVyaW5nX0FGXzk1X25mZSk+MC4wMDAxODEpKQoKbWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMyA8LSBtdXRhdGUobWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMiwgRmlsdGVyaW5nQUZfOTVfRXhjZWVkc19NYXhDcmVkUG9wQUY9KChHbm9tQURfdjIuMV9ub25fY2FuY2VyX0ZpbHRlcmluZ19BRl85NSk+MC4wMDAxODEpKSAlPiUgCiAgbXV0YXRlKEZpbHRlcmluZ0FGXzk1X05GRV9FeGNlZWRzX01heENyZWRQb3BBRj0oKEdub21BRF92Mi4xX25vbl9jYW5jZXJfRmlsdGVyaW5nX0FGXzk1X25mZSk+MC4wMDAxODEpKQpgYGAKCklkZW50aWZ5IHZhcmlhbnRzIHRoYXQgUEFTUy9GQUlMIHRoZSBMT0ZURUUgNTBicCBydWxlCmBgYHtyfQptYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czQgPC0gbXV0YXRlKG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX3dpdGhHbm9tQURzdGF0c19maXNoZXJyZXN1bHRzMyxMb0ZfNTBfQlBfUlVMRSA9IGlmZWxzZShncmVwbCgiNTBfQlBfUlVMRTpQQVNTIiwgTG9GX2luZm8pLCBUUlVFLCBpZmVsc2UoZ3JlcGwoIjUwX0JQX1JVTEU6RkFJTCIsIExvRl9pbmZvKSwgRkFMU0UsIE5BKSkpCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHM0IDwtIG11dGF0ZShtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHMzLExvRl81MF9CUF9SVUxFID0gaWZlbHNlKGdyZXBsKCI1MF9CUF9SVUxFOlBBU1MiLCBMb0ZfaW5mbyksIFRSVUUsIGlmZWxzZShncmVwbCgiNTBfQlBfUlVMRTpGQUlMIiwgTG9GX2luZm8pLCBGQUxTRSwgTkEpKSkKYGBgCgpJbXBvcnQgTk1EIGRlcGxldGVkIGdlbmUgbGlzdCBhbmQgYW5ub3RhdGUgdmFyaWFudHMgYWNjb3JkaW5nbHkKYGBge3J9Ck5NRF9kZXBsZXRlZF9nZW5lX2xpc3QgPC0gcmVhZC5jc3YoIk5NRF9kZXBsZXRlZF9nZW5lX2xpc3QuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSkgJT4lIAogIHJlbmFtZSgiU1lNQk9MIiA9IGdlbmUpICU+JSAKICByZW5hbWUoIkZlYXR1cmUiID0gdHhuYW1lcykgJT4lIAogIHJlbmFtZSgiTk1EX3ByZWRpY3Rvcl9yYW5rIiA9IG1pbi5yYW5rKQoKbWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHM1IDwtIGxlZnRfam9pbihtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czQsIE5NRF9kZXBsZXRlZF9nZW5lX2xpc3RbLGMoMjozKV0sYnk9IkZlYXR1cmUiLGNvcHk9RkFMU0UpCgptYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHM1IDwtIGxlZnRfam9pbihtYXN0ZXJmaWxlX2VvY19saW5jUk5BX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHM0LCBOTURfZGVwbGV0ZWRfZ2VuZV9saXN0WyxjKDI6MyldLGJ5PSJGZWF0dXJlIixjb3B5PUZBTFNFKSAKYGBgCgpSZW1vdmUgcmVkdW5kYW50IG9iamVjdHMgYW5kIG91dHB1dCBkYXRhCmBgYHtyfQpybShsaXN0PShscyhwYXR0ZXJuPSJeZ2VuZXMiKSkpCnJtKGxpc3Q9KGxzKHBhdHRlcm49Il52YXJpYW50cyIpKSkKcm0obGlzdD0obHMocGF0dGVybj0iXmZpc2hlcnJlc3VsdHMiKSkpCgp3cml0ZV9leGNlbF9jc3YobWFzdGVyZmlsZV9lb2NfTlBDX2dvb2RRMl9BTExfRU5TVGNhbm9uaWNhbF9zYW1wbGVBRjAuMDFfd2l0aEdub21BRHN0YXRzX2Zpc2hlcnJlc3VsdHM1LGZpbGU9Im1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUEMuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQoKd3JpdGVfZXhjZWxfY3N2KG1hc3RlcmZpbGVfZW9jX2xpbmNSTkFfZ29vZFEyX0FMTF9FTlNUY2Fub25pY2FsX3NhbXBsZUFGMC4wMV93aXRoR25vbUFEc3RhdHNfZmlzaGVycmVzdWx0czUsZmlsZT0ibWFzdGVyZmlsZV9lb2NfbGluY1JOQV9nb29kUTJfQUxMX0VOU1RjYW5vbmljYWxfc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQS5jc3YiLG5hPSIuIixhcHBlbmQ9RkFMU0UsY29sX25hbWVzPVRSVUUpCmBgYAoKQ2FsY3VsYXRlIHRvdGFsIExvRiB2YXJpYW50cyBpbiBzYW1wbGUgdnMgdG90YWwgTG9GIHZhcmlhbnRzIGluIEdub21BRCBub24tY2FuY2VyIE5GRSBhbmQgdXNlIGZvciBjaGktc3F1YXJlZCB0ZXN0CmBgYHtyfQpvZGRzcmF0aW8gPC0gZnVuY3Rpb24gKGEsIGIgPSBOVUxMLCBjID0gTlVMTCwgZCA9IE5VTEwsIGNvbmYubGV2ZWwgPSAwLjk1LCAKICAgIHAuY2FsYy5ieS5pbmRlcGVuZGVuY2UgPSBUUlVFKSAKewogICAgaWYgKGlzLm1hdHJpeChhKSkgewogICAgICAgIGlmICgoZGltKGEpWzFdICE9IDJMKSB8IChkaW0oYSlbMl0gIT0gMkwpKSB7CiAgICAgICAgICAgIHN0b3AoIklucHV0IG1hdHJpeCBtdXN0IGJlIGEgMngyIHRhYmxlLiIpCiAgICAgICAgfQogICAgICAgIC5hIDwtIGFbMSwgMV0KICAgICAgICAuYiA8LSBhWzEsIDJdCiAgICAgICAgLmMgPC0gYVsyLCAxXQogICAgICAgIC5kIDwtIGFbMiwgMl0KICAgICAgICAuZGF0YS5uYW1lIDwtIGRlcGFyc2Uoc3Vic3RpdHV0ZShhKSkKICAgIH0KICAgIGVsc2UgewogICAgICAgIC5hIDwtIGEKICAgICAgICAuYiA8LSBiCiAgICAgICAgLmMgPC0gYwogICAgICAgIC5kIDwtIGQKICAgICAgICAuZGF0YS5uYW1lIDwtIHBhc3RlKGRlcGFyc2Uoc3Vic3RpdHV0ZShhKSksIGRlcGFyc2Uoc3Vic3RpdHV0ZShiKSksIAogICAgICAgICAgICBkZXBhcnNlKHN1YnN0aXR1dGUoYykpLCBkZXBhcnNlKHN1YnN0aXR1dGUoZCkpKQogICAgfQogICAgLk1BVCA8LSBtYXRyaXgoYyguYSwgLmIsIE0xIDwtIC5hICsgLmIsIC5jLCAuZCwgTTAgPC0gLmMgKyAKICAgICAgICAuZCwgTjEgPC0gLmEgKyAuYywgTjAgPC0gLmIgKyAuZCwgVG90YWwgPC0gLmEgKyAuYiArIAogICAgICAgIC5jICsgLmQpLCAzLCAzKQogICAgY29sbmFtZXMoLk1BVCkgPC0gYygiU2FtcGxlIiwgIkdub21BRCIsICJUb3RhbCIpICMoIkRpc2Vhc2UiLCAiTm9uZGlzZWFzZSIsICJUb3RhbCIpCiAgICByb3duYW1lcyguTUFUKSA8LSBjKCJWYXJpYW50cyIsICJObyB2YXJpYW50cyIsICJUb3RhbCIpICMoIkV4cG9zZWQiLCAiTm9uZXhwb3NlZCIsICJUb3RhbCIpCiAgICBjbGFzcyguTUFUKSA8LSAidGFibGUiCiAgICBwcmludCguTUFUKQogICAgRVNUSU1BVEUgPC0gKC5hIC8uYikvKC5jLy5kKQogICAgbm9ybS5wcCA8LSBxbm9ybSgxIC0gKDEgLSBjb25mLmxldmVsKS8yKQogICAgaWYgKHAuY2FsYy5ieS5pbmRlcGVuZGVuY2UpIHsKICAgICAgICBwLnYgPC0gMiAqICgxIC0gcG5vcm0oYWJzKCguYSAtIE4xICogTTEvVG90YWwpL3NxcnQoTjEgKiAKICAgICAgICAgICAgTjAgKiBNMSAqIE0wL1RvdGFsL1RvdGFsLyhUb3RhbCAtIDEpKSkpKQogICAgfQogICAgZWxzZSB7CiAgICAgICAgcC52IDwtIDIgKiAoMSAtIHBub3JtKGxvZyhpZmVsc2UoRVNUSU1BVEUgPiAxLCBFU1RJTUFURSwgCiAgICAgICAgICAgIDEvRVNUSU1BVEUpKS9zcXJ0KDEvLmEgKyAxLy5iICsgMS8uYyArIDEvLmQpKSkKICAgIH0KICAgIE9STCA8LSBFU1RJTUFURSAqIGV4cCgtbm9ybS5wcCAqIHNxcnQoMS8uYSArIDEvLmIgKyAxLy5jICsgCiAgICAgICAgMS8uZCkpCiAgICBPUlUgPC0gRVNUSU1BVEUgKiBleHAobm9ybS5wcCAqIHNxcnQoMS8uYSArIDEvLmIgKyAxLy5jICsgCiAgICAgICAgMS8uZCkpICU+JSBzaWduaWYoZGlnaXRzPTcpCiAgICBDSU5UIDwtIHBhc3RlKHNpZ25pZihPUkwsZGlnaXRzID0gNyksc2lnbmlmKE9SVSxkaWdpdHMgPSA3KSxzZXA9In4iKQogICAgYXR0cihDSU5ULCAiY29uZi5sZXZlbCIpIDwtIGNvbmYubGV2ZWwKICAgIFJWQUwgPC0gbGlzdChwLnZhbHVlID0gcC52LCBjb25mLmludCA9IENJTlQsIGVzdGltYXRlID0gRVNUSU1BVEUsIAogICAgICAgIG1ldGhvZCA9ICJPZGRzIHJhdGlvIGVzdGltYXRlIGFuZCBpdHMgc2lnbmlmaWNhbmNlIHByb2JhYmlsaXR5IiwgCiAgICAgICAgZGF0YS5uYW1lID0gLmRhdGEubmFtZSkKICAgIGNsYXNzKFJWQUwpIDwtICJodGVzdCIKICAgIHJldHVybihSVkFMKQp9CgphIDwtIHN1bSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzMyRUb3RhbF9HZW5lX0NvdW50KSAlPiUgYXMubnVtZXJpYygpCmIgPC0gbl9kaXN0aW5jdChtYXN0ZXJmaWxlX2VvY19OUENfZ29vZFEyX0FMTCRTYW1wbGUpKjIqKG5yb3coYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSkpICU+JSBhcy5udW1lcmljKCkKYjEgPC0gYi1hICU+JSBhcy5udW1lcmljKCkKYyA8LSBzdW0odm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FDXzAuMDA1KSAlPiUgYXMubnVtZXJpYygpCmQgPC0gKG1heCh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzMyRNQVhfQU4pKSpucm93KGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3Rfbm9uX3Byb3RlaW5fY29kaW5nX29ubHkpICU+JSBhcy5udW1lcmljKCkKZDEgPC0gZC1jICU+JSBhcy5udW1lcmljKCkKZSA8LSBzdW0odm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FDXzAuMDA1X05GRSkgJT4lIGFzLm51bWVyaWMoKQpmIDwtIChtYXgodm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZU5QQ19hbGxHZW5lczMkTUFYX0FOX05GRSkpKm5yb3coYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSkgJT4lIGFzLm51bWVyaWMoKQpmMSA8LSBmLWUgJT4lIGFzLm51bWVyaWMoKQoKY2hpWDJfMC4wMDVfYmlvdHlwZU5QQyA8LSBtYXRyaXgoYyhhLGIxLGMsZDEpLG5yb3c9MixieXJvdz1UUlVFKQpjaGlYMl8wLjAwNV9ORkVfYmlvdHlwZU5QQyA8LSBtYXRyaXgoYyhhLGIxLGUsZjEpLG5yb3c9MixieXJvdz1UUlVFKQoKc2luayhmaWxlPSJtYXN0ZXJmaWxlX2VvY19BTExfdm9sY2Fub19jaGlYMl9yZXN1bHRzLnR4dCIsYXBwZW5kPVRSVUUpCgpjaGlzcS50ZXN0KGNoaVgyXzAuMDA1X2Jpb3R5cGVOUEMsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X2Jpb3R5cGVOUEMpCmNoaXNxLnRlc3QoY2hpWDJfMC4wMDVfTkZFX2Jpb3R5cGVOUEMsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X05GRV9iaW90eXBlTlBDKQoKc2luaygpCgpnIDwtIHN1bSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJFRvdGFsX0dlbmVfQ291bnQpICU+JSBhcy5udW1lcmljKCkKaCA8LSBuX2Rpc3RpbmN0KG1hc3RlcmZpbGVfZW9jX05QQ19nb29kUTIkU2FtcGxlKSoyKihucm93KGFsbEdlbmVzX0FnaWxlbnRTU3Y2X2xpc3Rfbm9uX3Byb3RlaW5fY29kaW5nX29ubHkpKSAlPiUgYXMubnVtZXJpYygpCmgxIDwtIGgtZyAlPiUgYXMubnVtZXJpYygpCmkgPC0gc3VtKHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMkRklMVEVSX1JGX0xPVy5NT0RFUkFURS5ISUdIX0FDXzAuMDA1KSAlPiUgYXMubnVtZXJpYygpCmogPC0gKG1heCh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJE1BWF9BTikpKm5yb3coYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSkgJT4lIGFzLm51bWVyaWMoKQpqMSA8LSBqLWkgJT4lIGFzLm51bWVyaWMoKQprIDwtIHN1bSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXMzJEZJTFRFUl9SRl9MT1cuTU9ERVJBVEUuSElHSF9BQ18wLjAwNV9ORkUpICU+JSBhcy5udW1lcmljKCkKbCA8LSAobWF4KHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMkTUFYX0FOX05GRSkpKm5yb3coYWxsR2VuZXNfQWdpbGVudFNTdjZfbGlzdF9ub25fcHJvdGVpbl9jb2Rpbmdfb25seSkgJT4lIGFzLm51bWVyaWMoKQpsMSA8LSBsLWsgJT4lIGFzLm51bWVyaWMoKQoKY2hpWDJfMC4wMDVfYmlvdHlwZV9saW5jUk5BIDwtIG1hdHJpeChjKGcsaDEsaSxqMSksbnJvdz0yLGJ5cm93PVRSVUUpCmNoaVgyXzAuMDA1X05GRV9iaW90eXBlX2xpbmNSTkEgPC0gbWF0cml4KGMoZyxoMSxrLGwxKSxucm93PTIsYnlyb3c9VFJVRSkKCnNpbmsoZmlsZT0ibWFzdGVyZmlsZV9lb2NfQUxMX3ZvbGNhbm9fY2hpWDJfcmVzdWx0cy50eHQiLGFwcGVuZD1UUlVFKQoKY2hpc3EudGVzdChjaGlYMl8wLjAwNV9iaW90eXBlX2xpbmNSTkEsY29ycmVjdD1GQUxTRSkKb2Rkc3JhdGlvKGNoaVgyXzAuMDA1X2Jpb3R5cGVfbGluY1JOQSkKY2hpc3EudGVzdChjaGlYMl8wLjAwNV9ORkVfYmlvdHlwZV9saW5jUk5BLGNvcnJlY3Q9RkFMU0UpCm9kZHNyYXRpbyhjaGlYMl8wLjAwNV9ORkVfYmlvdHlwZV9saW5jUk5BKQoKc2luaygpCmBgYAoKT3V0cHV0IGRhdGEgZm9yIGxvZyBwLXZhbHVlIHZvbGNhbm8gcGxvdHMKYGBge3J9CnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVOUENfYWxsR2VuZXM0IDwtIG11dGF0ZSh2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzMywiTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkUiID0gbG9nMTAoUF92YWx1ZV9GaXNoZXJfMC4wMDVfTkZFKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhPUl8wLjAwNV9ORkUpKSAlPiUgCiAgbXV0YXRlKCJQbG90dGVkX0xvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIj0gCiAgaWZfZWxzZSAoYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYDwwLCBgTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgKi0xLCBgTG9nMTBfUC12YWx1ZV9GaXNoZXJfMC4wNV9ORkVgLCBtaXNzaW5nPU5VTEwpKSAlPiUgCiAgYXJyYW5nZShkZXNjKGBQbG90dGVkX0xvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCksZGVzYyhPUl8wLjAwNV9ORkUpKSAlPiUgCiAgbGVmdF9qb2luKEFnaWxlbnRTU3Y2X2xpc3RfRU5TVGNhbm9uaWNhbF9ub25fcHJvdGVpbl9jb2RpbmdbLGMoMyw0KV0sYnk9IkdlbmUiLGNvcHk9IkZBTFNFIikgJT4lIAogIGxlZnRfam9pbih2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzWyxjKDIsNSw2KV0sYnk9IkdlbmUiLGNvcHk9IkZBTFNFIikgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihmaWxlPSJ2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlTlBDX2FsbEdlbmVzX3Y2LmNzdiIsbmE9Ii4iLGFwcGVuZD1GQUxTRSxjb2xfbmFtZXM9VFJVRSkKCnZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczQgPC0gbXV0YXRlKHZvbGNhbm9fc2FtcGxlQUYwLjAxX2Jpb3R5cGVfbGluY1JOQV9hbGxHZW5lczMsIkxvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFIiA9IGxvZzEwKFBfdmFsdWVfRmlzaGVyXzAuMDA1X05GRSkpICU+JSAKICBhcnJhbmdlKGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIG11dGF0ZSgiUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRSI9IAogIGlmX2Vsc2UgKGBMb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWA8MCwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCotMSwgYExvZzEwX1AtdmFsdWVfRmlzaGVyXzAuMDVfTkZFYCwgbWlzc2luZz1OVUxMKSkgJT4lIAogIGFycmFuZ2UoZGVzYyhgUGxvdHRlZF9Mb2cxMF9QLXZhbHVlX0Zpc2hlcl8wLjA1X05GRWApLGRlc2MoT1JfMC4wMDVfTkZFKSkgJT4lIAogIGxlZnRfam9pbihBZ2lsZW50U1N2Nl9saXN0X0VOU1RjYW5vbmljYWxfbm9uX3Byb3RlaW5fY29kaW5nWyxjKDMsNCldLGJ5PSJHZW5lIixjb3B5PSJGQUxTRSIpICU+JSAKICBsZWZ0X2pvaW4odm9sY2Fub19zYW1wbGVBRjAuMDFfYmlvdHlwZV9saW5jUk5BX2FsbEdlbmVzWyxjKDIsNSw2KV0sYnk9IkdlbmUiLGNvcHk9IkZBTFNFIikgJT4lIAogIHdyaXRlX2V4Y2VsX2NzdihmaWxlPSJ2b2xjYW5vX3NhbXBsZUFGMC4wMV9iaW90eXBlX2xpbmNSTkFfYWxsR2VuZXNfdjYuY3N2IixuYT0iLiIsYXBwZW5kPUZBTFNFLGNvbF9uYW1lcz1UUlVFKQpgYGAK