1 Functions


scAssign_db <- function(tissue) {
  lapply(c("dplyr","Seurat","HGNChelper"), library, character.only = T)
  source("https://raw.githubusercontent.com/IanevskiAleksandr/sc-type/master/R/gene_sets_prepare.R"); source("https://raw.githubusercontent.com/IanevskiAleksandr/sc-type/master/R/sctype_score_.R")
  
  db_ = "https://raw.githubusercontent.com/IanevskiAleksandr/sc-type/master/ScTypeDB_full.xlsx";
  tissue = tissue # e.g. Immune system,Pancreas,Liver,Eye,Kidney,Brain,Lung,Adrenal,Heart,Intestine,Muscle,Placenta,Spleen,Stomach,Thymus 
  
  # prepare gene sets
  gs_list = gene_sets_prepare(db_, tissue)
  return(gs_list)
}

scAssign <- function(seuratObj,gs_list) {
  es.max = sctype_score(scRNAseqData = seuratObj[["RNA"]]@scale.data, scaled = TRUE, 
                      gs = gs_list$gs_positive, gs2 = gs_list$gs_negative) 
  # merge by cluster
  cL_resutls = do.call("rbind", lapply(unique(seuratObj@meta.data$seurat_clusters), function(cl){
      es.max.cl = sort(rowSums(es.max[ ,rownames(seuratObj@meta.data[seuratObj@meta.data$seurat_clusters==cl, ])]), decreasing = !0)
      head(data.frame(cluster = cl, type = names(es.max.cl), scores = es.max.cl, ncells = sum(seuratObj@meta.data$seurat_clusters==cl)), 10)
  }))
  sctype_scores = cL_resutls %>% group_by(cluster) %>% top_n(n = 1, wt = scores)  
  
  # set low-confident (low ScType score) clusters to "unknown"
  sctype_scores$type[as.numeric(as.character(sctype_scores$scores)) < sctype_scores$ncells/4] = "Unknown"
  print(sctype_scores[,1:3])
  
  seuratObj@meta.data$cell_identity = ""
  for(j in unique(sctype_scores$cluster)){
    cl_type = sctype_scores[sctype_scores$cluster==j,]; 
    seuratObj@meta.data$cell_identity[seuratObj@meta.data$seurat_clusters == j] = as.character(cl_type$type[1])
  }
  return(seuratObj)
}

2 Data

acc_immune = LoadH5Seurat(file = "./Data/acc_immune_5KvarGenes.h5seurat")

3 Clustering

acc_immune <- FindClusters(acc_immune, resolution = 5,verbose = F, algorithm = 1)
DimPlot(acc_immune,label = T)

4 Cell type assignment

4.1 cluster scores

gs_list = scAssign_db(tissue = "Immune system")

Warning in checkGeneSymbols(markers_all) : Human gene symbols should be all upper-case except for the ‘orf’ in open reading frames. The case of some letters was corrected. Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols Warning in checkGeneSymbols(markers_all) : x contains non-approved gene symbols

acc_immune %<>% scAssign(gs_list = gs_list)
acc_immune %<>%  SetIdent(value = "cell_identity")
print_tab(DimPlot(acc_immune,group.by = "cell_identity"),title = "UMAP")

UMAP

print_tab(plt = acc_immune$cell_identity %>% table() %>% as.data.frame(), title = "cell count")

cell count

NA

5 Markers

FeaturePlot(acc_immune, features = c("CD8A","MS4A1", "CD4","CD14","MS4A2"))

6 Markers heatmaps

print_tab(plt = 
            DoHeatmap(acc_immune, features =c("CD8A","MS4A1", "CD4","CD14","MS4A2"), size = 3,slot = "data")
          ,title = "markers")

markers

print_tab(plt = 
            DoHeatmap(subset(acc_immune,subset = cell_identity == "Macrophages"), features
                      =gs_list$gs_positive$Macrophages, size = 3,slot = "data")
          ,title = "Macrophages markers")

Macrophages markers

Warning in DoHeatmap(subset(acc_immune, subset = cell_identity == “Macrophages”), : The following features were omitted as they were not found in the data slot for the RNA assay: PF4

NA

7 Cell type correlation

acc_immune = SetIdent(object = acc_immune,value = "cell_identity")
correlation = cor(AverageExpression(object = acc_immune) %>% as.data.frame())
colnames(correlation) <- gsub(pattern = "RNA.",replacement = "",x = colnames(correlation))
rownames(correlation) <- gsub(pattern = "RNA.",replacement = "",x = rownames(correlation))

pheatmap(mat = correlation,main = "Expression correlation")

8 Antigen presenting machinery

apm_genes = c("HLA-A","HLA-B","HLA-C","B2M","TAP1","TAP2", "TAPBP")
apm_score = FetchData(acc_immune,vars = apm_genes,slot = "data") %>% rowMeans()
acc_immune = AddMetaData(object = acc_immune,metadata = apm_score,col.name = "APM_score")
print_tab(plt = FeaturePlot(acc_immune,features = apm_genes),title = "genes")
print_tab(plt = FeaturePlot(acc_immune,features = "APM_score"),title = "score")

9 Exhaustion markers

exhausted_genes = c("PDCD1","CD244","CD160","CTLA4","HAVCR2")
FeaturePlot(acc_immune,features = exhausted_genes)

10 Immune receptors

receptors = c("CCR3", "CCR4", "CCR10","CXCR2", "CXCR3", "CXCR4", "IL17A")
FeaturePlot(acc_immune,features = receptors)

11 CellphoneDB

acc_cancer_cells_pri = readRDS("/sci/labs/yotamd/lab_share/avishai.wizel/R_projects/ACC_microenv/Data/acc_cancer_no146_primaryonly15k_cancercells.rds")
acc_caf = readRDS("/sci/labs/yotamd/lab_share/ACC/ACC_sc/analysis/acc_tpm_nCount_mito_no146_cafs.rds")
acc_immune_pri = subset(acc_immune, subset = origin == "Primary")
# merge cancer and immune
common_genes = intersect(rownames(acc_cancer_cells_pri),rownames(acc_immune_pri)) %>% intersect(rownames(acc_caf_cells))
acc_cancer_and_cd45 = merge(acc_cancer_cells_pri[common_genes,],acc_immune_pri[common_genes,])
overlapping_cells = colnames(acc_cancer_cells_pri) %>% intersect(colnames(acc_caf)) 
acc_cancer_cd45_caf = merge(acc_cancer_and_cd45[common_genes,],acc_caf_cells[common_genes,!colnames(acc_caf_cells) %in% overlapping_cells] )
  #write metadata

#create lum or myo
lum_over_myo = FetchData(object = acc_cancer_cells_pri,vars = "luminal_over_myo")
lum_over_myo$lum_or_myo = "Unknown"
lum_over_myo$lum_or_myo [lum_over_myo$luminal_over_myo>1]  = "Luminal"
lum_over_myo$lum_or_myo [lum_over_myo$luminal_over_myo<(-1)]  = "Myo"
lum_or_myo = lum_over_myo[,"lum_or_myo",drop = F]
names(lum_or_myo)[1] = "cell_identity"
lum_or_myo = lum_or_myo %>% filter(cell_identity != "Unknown") #remove unknown cells
  
# combine
immune_identity =FetchData(object = acc_immune_pri,vars = "cell_identity")
caf_identity =FetchData(object = acc_caf_cells,vars = "cell.type")
names(caf_identity)[1] = "cell_identity"
all_identity = do.call("rbind", list(lum_or_myo, immune_identity, caf_identity))

#rename and sort columns
all_identity$barcode_sample = rownames(all_identity)
all_identity = all_identity %>% rename(cell_type = cell_identity)
all_identity = all_identity[,c(2,1)]
write.table(x = all_identity,file = "./Data/CellphoneDB/metadata_primary.tsv",row.names =F,sep = "\t")
#write normalized counts
acc_cancer_cd45_caf = acc_cancer_cd45_caf[,rownames(all_identity)]
count_matrix = as.data.frame(acc_cancer_cd45_caf@assays[["RNA"]]@data)
fwrite(count_matrix, file = "./Data/CellphoneDB/counts_primary.txt",sep = "\t",row.names = T)
library(ktplots)
library(reticulate)
acc_cancer_cd45_caf$cell_type = all_identity[,2,drop = F] # add cells identities to Seurat

#read data:
pvals =  py$pvalues
means = py$means

#or:
pvals = read.delim("./Data/CellphoneDB/output_primary/statistical_analysis_pvalues_08_01_2023_16:13:32.txt",check.names = F)
means = read.delim("./Data/CellphoneDB/output_primary/statistical_analysis_means_08_01_2023_16:13:32.txt",check.names = F)

12 significant interactions heatmap

plot_cpdb_heatmap(scdata = acc_cancer_cd45_caf, idents = 'cell_type',pvals =  pvals,main = "Number of significant interactions",alpha = 0.05,treeheight_row = 50)

trace(plot_cpdb,edit = T)
untrace(plot_cpdb)
plot_cpdb_with_col_clustering = plot_cpdb
to_insert =quote(
   if (ncol(means_mat) > 2) {
              d <- dist(as.data.frame(t(means_mat)))
              h <- hclust(d)
              means_mat <- means_mat[, h$order, drop = FALSE]
              pvals_mat <- pvals_mat[, h$order, drop = FALSE]
              plot(h, main = cell_type2)
  }
)


body(plot_cpdb_with_col_clustering) <- body(plot_cpdb_with_col_clustering) %>% as.list %>% append(to_insert,after =  41) %>% as.call
trace(plot_cpdb_with_col_clustering,edit = T)
uniq_interactions <- function(cell_type1, cell_type2_a ,cell_type2_b, gene.family = NULL,genes = NULL) {
  require(purrr)
  a = plot_cpdb(cell_type1 = cell_type1, cell_type2 =cell_type2_a, scdata = acc_cancer_cd45_caf,
                      idents = 'cell_type', means = means, pvals = pvals,
                      gene.family = gene.family,return_table = T, p.adjust.method = "fdr",keep_significant_only = T, genes = genes)
  
  b = plot_cpdb(cell_type1 = cell_type1, cell_type2 = cell_type2_b, scdata = acc_cancer_cd45_caf,
                      idents = 'cell_type', means = means, pvals = pvals,
                      gene.family = gene.family,return_table = T,p.adjust.method = "fdr",keep_significant_only = T, genes = genes)
  
  
  all = list()
  i=0
  nelements = a$Var2 %>% unique() %>% length()
  a_couples = a$Var2 %>% unique()%>% as.vector()  
  b_couples = b$Var2 %>% unique()%>% as.vector()  
  for (i in 1:nelements) {
    sig_couples_a = a %>% filter(Var2 == a_couples[i]) %>% filter(pvals_adj <= 0.05) %>%  pull(Var1) %>% as.vector()  
    sig_couples_b = b %>% filter(Var2 == b_couples[i]) %>% filter(pvals_adj <= 0.05) %>%  pull(Var1) %>% as.vector()  
    only_in_a = sig_couples_a[! sig_couples_a %in% sig_couples_b]
    all[[a_couples[i]]] = only_in_a 
    i = i+1
  }
  all = t(map_dfr(all, ~as_tibble(t(.)))) %>% as.data.frame() %>%  set_names(a_couples)
  return(all)
}

13 All interactions

acc_immune <- StashIdent(object = acc_immune, save.name = "cell_identity")
With Seurat 3.X, stashing identity classes can be accomplished with the following:
acc_immune[["cell_identity"]] <- Idents(object = acc_immune)
SeuratDisk::SaveH5Seurat(object = acc_immune,filename = "./Data/acc_immune_5KvarGenes_V2_cellIdentity.h5seurat")
Creating h5Seurat file for version 3.1.5.9900
Adding counts for RNA
Adding data for RNA
Adding scale.data for RNA
Adding variable features for RNA
Adding feature-level metadata for RNA
Adding cell embeddings for pca
Adding loadings for pca
No projected loadings for pca
Adding standard deviations for pca
No JackStraw data for pca
Adding cell embeddings for umap
No loadings for umap
No projected loadings for umap
No standard deviations for umap
No JackStraw data for umap

14 Coinhibitory interactions


print_tab(plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Luminal', scdata = acc_cancer_cd45_caf,
          idents = 'cell_type', means = means, pvals = pvals,
          gene.family = 'coinhibitory',return_table = F,max_size = 4,p.adjust.method = "fdr",keep_significant_only = F,cluster_rows = F)+
  ggtitle("coinhibitory Luminal"),title = "Luminal")

print_tab(plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Myo', scdata = acc_cancer_cd45_caf,
          idents = 'cell_type', means = means, pvals = pvals,
          gene.family = 'coinhibitory',return_table = F,max_size = 4,p.adjust.method = "fdr",keep_significant_only = F,cluster_rows = F)+
  ggtitle("coinhibitory Myo"),title = "Myo")

print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'Luminal',cell_type2_b = "Myo",gene.family = "coinhibitory")
,title = "unique in luminal")


print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'Myo',cell_type2_b = "Luminal",gene.family = "coinhibitory")
,title = "unique in myo")

print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'CAF',cell_type2_b = "Myo|Luminal",gene.family = "coinhibitory")
,title = "unique in CAF")

15 Chemokines interactions

print_tab(
  plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Luminal', scdata = acc_cancer_cd45_caf,
          idents = 'cell_type', means = means, pvals = pvals,
          gene.family = 'chemokines',return_table = F,max_size = 4,p.adjust.method = "fdr",keep_significant_only = F,cluster_rows = F)+
  ggtitle("chemokines Luminal"),title = "Luminal")

print_tab(
  plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Myo', scdata = acc_cancer_cd45_caf,
          idents = 'cell_type', means = means, pvals = pvals,
          gene.family = 'chemokines',return_table = F,max_size = 4,p.adjust.method = "fdr",keep_significant_only = F,cluster_rows = F)+
  ggtitle("chemokines Myo"),title = "Myo")


print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'Luminal',cell_type2_b = "Myo",gene.family = "chemokines")
,title = "unique in luminal")


print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'Myo',cell_type2_b = "Luminal",gene.family = "chemokines")
,title = "unique in myo")

print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'CAF',cell_type2_b = "Myo|Luminal",gene.family = "chemokines")
,title = "unique in CAF")

16 Chemokine ligands

genes = c("CXCL1\\D", "CXCL2\\D","CXCL3\\D","CXCL17","C3","CXCL14")
print_tab(plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Myo', scdata = acc_cancer_cd45_caf,
    idents = 'cell_type', means = means, pvals = pvals,
 genes = genes,return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F) 
 ,title = "Myo")

print_tab(plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Luminal', scdata = acc_cancer_cd45_caf,
    idents = 'cell_type', means = means, pvals = pvals,
  genes = genes,return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F) 
,title = "Luminal")


print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'Luminal',cell_type2_b = "Myo", genes = genes)
,title = "unique in luminal")


print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'Myo',cell_type2_b = "Luminal", genes = genes)
,title = "unique in myo")

print_tab(plt = 
            uniq_interactions(cell_type1 = 'CD|B|FC',cell_type2_a  = 'CAF',cell_type2_b = "Myo|Luminal", genes = genes)
,title = "unique in CAF")

17 CCL22 and CCL28

print_tab(plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Myo', scdata = acc_cancer_cd45_caf,
    idents = 'cell_type', means = means, pvals = pvals,
 genes = c("CCL22", "CCL28" ),return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F),title = "Myo")

print_tab(plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Luminal', scdata = acc_cancer_cd45_caf,
    idents = 'cell_type', means = means, pvals = pvals,
  genes = c("CCL22", "CCL28" ),return_table = F,max_size = 6,p.adjust.method = "fdr" ,keep_significant_only = F),title = "Luminal")
plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Myo', scdata = acc_cancer_cd45_caf,
    idents = 'cell_type', means = means, pvals = pvals,
 genes = c("JAG", "MYB" ),return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F) 

plot_cpdb(cell_type1 = 'CD|B|FC', cell_type2 = 'Luminal', scdata = acc_cancer_cd45_caf,
    idents = 'cell_type', means = means, pvals = pvals,
  genes = c("JAG", "MYB" , "NOTCH","HES1","HEY"),return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F) 
LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCgoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CgpzY0Fzc2lnbl9kYiA8LSBmdW5jdGlvbih0aXNzdWUpIHsKICBsYXBwbHkoYygiZHBseXIiLCJTZXVyYXQiLCJIR05DaGVscGVyIiksIGxpYnJhcnksIGNoYXJhY3Rlci5vbmx5ID0gVCkKICBzb3VyY2UoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9JYW5ldnNraUFsZWtzYW5kci9zYy10eXBlL21hc3Rlci9SL2dlbmVfc2V0c19wcmVwYXJlLlIiKTsgc291cmNlKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSWFuZXZza2lBbGVrc2FuZHIvc2MtdHlwZS9tYXN0ZXIvUi9zY3R5cGVfc2NvcmVfLlIiKQogIAogIGRiXyA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSWFuZXZza2lBbGVrc2FuZHIvc2MtdHlwZS9tYXN0ZXIvU2NUeXBlREJfZnVsbC54bHN4IjsKICB0aXNzdWUgPSB0aXNzdWUgIyBlLmcuIEltbXVuZSBzeXN0ZW0sUGFuY3JlYXMsTGl2ZXIsRXllLEtpZG5leSxCcmFpbixMdW5nLEFkcmVuYWwsSGVhcnQsSW50ZXN0aW5lLE11c2NsZSxQbGFjZW50YSxTcGxlZW4sU3RvbWFjaCxUaHltdXMgCiAgCiAgIyBwcmVwYXJlIGdlbmUgc2V0cwogIGdzX2xpc3QgPSBnZW5lX3NldHNfcHJlcGFyZShkYl8sIHRpc3N1ZSkKICByZXR1cm4oZ3NfbGlzdCkKfQoKc2NBc3NpZ24gPC0gZnVuY3Rpb24oc2V1cmF0T2JqLGdzX2xpc3QpIHsKICBlcy5tYXggPSBzY3R5cGVfc2NvcmUoc2NSTkFzZXFEYXRhID0gc2V1cmF0T2JqW1siUk5BIl1dQHNjYWxlLmRhdGEsIHNjYWxlZCA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgZ3MgPSBnc19saXN0JGdzX3Bvc2l0aXZlLCBnczIgPSBnc19saXN0JGdzX25lZ2F0aXZlKSAKICAjIG1lcmdlIGJ5IGNsdXN0ZXIKICBjTF9yZXN1dGxzID0gZG8uY2FsbCgicmJpbmQiLCBsYXBwbHkodW5pcXVlKHNldXJhdE9iakBtZXRhLmRhdGEkc2V1cmF0X2NsdXN0ZXJzKSwgZnVuY3Rpb24oY2wpewogICAgICBlcy5tYXguY2wgPSBzb3J0KHJvd1N1bXMoZXMubWF4WyAscm93bmFtZXMoc2V1cmF0T2JqQG1ldGEuZGF0YVtzZXVyYXRPYmpAbWV0YS5kYXRhJHNldXJhdF9jbHVzdGVycz09Y2wsIF0pXSksIGRlY3JlYXNpbmcgPSAhMCkKICAgICAgaGVhZChkYXRhLmZyYW1lKGNsdXN0ZXIgPSBjbCwgdHlwZSA9IG5hbWVzKGVzLm1heC5jbCksIHNjb3JlcyA9IGVzLm1heC5jbCwgbmNlbGxzID0gc3VtKHNldXJhdE9iakBtZXRhLmRhdGEkc2V1cmF0X2NsdXN0ZXJzPT1jbCkpLCAxMCkKICB9KSkKICBzY3R5cGVfc2NvcmVzID0gY0xfcmVzdXRscyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG4gPSAxLCB3dCA9IHNjb3JlcykgIAogIAogICMgc2V0IGxvdy1jb25maWRlbnQgKGxvdyBTY1R5cGUgc2NvcmUpIGNsdXN0ZXJzIHRvICJ1bmtub3duIgogIHNjdHlwZV9zY29yZXMkdHlwZVthcy5udW1lcmljKGFzLmNoYXJhY3RlcihzY3R5cGVfc2NvcmVzJHNjb3JlcykpIDwgc2N0eXBlX3Njb3JlcyRuY2VsbHMvNF0gPSAiVW5rbm93biIKICBwcmludChzY3R5cGVfc2NvcmVzWywxOjNdKQogIAogIHNldXJhdE9iakBtZXRhLmRhdGEkY2VsbF9pZGVudGl0eSA9ICIiCiAgZm9yKGogaW4gdW5pcXVlKHNjdHlwZV9zY29yZXMkY2x1c3RlcikpewogICAgY2xfdHlwZSA9IHNjdHlwZV9zY29yZXNbc2N0eXBlX3Njb3JlcyRjbHVzdGVyPT1qLF07IAogICAgc2V1cmF0T2JqQG1ldGEuZGF0YSRjZWxsX2lkZW50aXR5W3NldXJhdE9iakBtZXRhLmRhdGEkc2V1cmF0X2NsdXN0ZXJzID09IGpdID0gYXMuY2hhcmFjdGVyKGNsX3R5cGUkdHlwZVsxXSkKICB9CiAgcmV0dXJuKHNldXJhdE9iaikKfQoKYGBgCgojIERhdGEKCmBgYHtyfQphY2NfaW1tdW5lID0gTG9hZEg1U2V1cmF0KGZpbGUgPSAiLi9EYXRhL2FjY19pbW11bmVfNUt2YXJHZW5lcy5oNXNldXJhdCIpCmBgYAoKIyBDbHVzdGVyaW5nCmBgYHtyfQphY2NfaW1tdW5lIDwtIEZpbmRDbHVzdGVycyhhY2NfaW1tdW5lLCByZXNvbHV0aW9uID0gNSx2ZXJib3NlID0gRiwgYWxnb3JpdGhtID0gMSkKRGltUGxvdChhY2NfaW1tdW5lLGxhYmVsID0gVCkKYGBgCgoKCiMgQ2VsbCB0eXBlIGFzc2lnbm1lbnQgIHsudGFic2V0fQoKIyMgY2x1c3RlciBzY29yZXMKYGBge3IgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KZ3NfbGlzdCA9IHNjQXNzaWduX2RiKHRpc3N1ZSA9ICJJbW11bmUgc3lzdGVtIikKYWNjX2ltbXVuZSAlPD4lIHNjQXNzaWduKGdzX2xpc3QgPSBnc19saXN0KQpgYGAKCgoKYGBge3IgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KYWNjX2ltbXVuZSAlPD4lICBTZXRJZGVudCh2YWx1ZSA9ICJjZWxsX2lkZW50aXR5IikKcHJpbnRfdGFiKERpbVBsb3QoYWNjX2ltbXVuZSxncm91cC5ieSA9ICJjZWxsX2lkZW50aXR5IiksdGl0bGUgPSAiVU1BUCIpCnByaW50X3RhYihwbHQgPSBhY2NfaW1tdW5lJGNlbGxfaWRlbnRpdHkgJT4lIHRhYmxlKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSwgdGl0bGUgPSAiY2VsbCBjb3VudCIpCmBgYAojIE1hcmtlcnMKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTB9CkZlYXR1cmVQbG90KGFjY19pbW11bmUsIGZlYXR1cmVzID0gYygiQ0Q4QSIsIk1TNEExIiwgIkNENCIsIkNEMTQiLCJNUzRBMiIpKQpgYGAKCgoKIyBNYXJrZXJzIGhlYXRtYXBzIHsudGFic2V0fQpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMiwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICBEb0hlYXRtYXAoYWNjX2ltbXVuZSwgZmVhdHVyZXMgPWMoIkNEOEEiLCJNUzRBMSIsICJDRDQiLCJDRDE0IiwiTVM0QTIiKSwgc2l6ZSA9IDMsc2xvdCA9ICJkYXRhIikKICAgICAgICAgICx0aXRsZSA9ICJtYXJrZXJzIikKCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgRG9IZWF0bWFwKHN1YnNldChhY2NfaW1tdW5lLHN1YnNldCA9IGNlbGxfaWRlbnRpdHkgPT0gIk1hY3JvcGhhZ2VzIiksIGZlYXR1cmVzCiAgICAgICAgICAgICAgICAgICAgICA9Z3NfbGlzdCRnc19wb3NpdGl2ZSRNYWNyb3BoYWdlcywgc2l6ZSA9IDMsc2xvdCA9ICJkYXRhIikKICAgICAgICAgICx0aXRsZSA9ICJNYWNyb3BoYWdlcyBtYXJrZXJzIikKCmBgYAoKIyBDZWxsIHR5cGUgY29ycmVsYXRpb24KYGBge3J9CmFjY19pbW11bmUgPSBTZXRJZGVudChvYmplY3QgPSBhY2NfaW1tdW5lLHZhbHVlID0gImNlbGxfaWRlbnRpdHkiKQpjb3JyZWxhdGlvbiA9IGNvcihBdmVyYWdlRXhwcmVzc2lvbihvYmplY3QgPSBhY2NfaW1tdW5lKSAlPiUgYXMuZGF0YS5mcmFtZSgpKQpjb2xuYW1lcyhjb3JyZWxhdGlvbikgPC0gZ3N1YihwYXR0ZXJuID0gIlJOQS4iLHJlcGxhY2VtZW50ID0gIiIseCA9IGNvbG5hbWVzKGNvcnJlbGF0aW9uKSkKcm93bmFtZXMoY29ycmVsYXRpb24pIDwtIGdzdWIocGF0dGVybiA9ICJSTkEuIixyZXBsYWNlbWVudCA9ICIiLHggPSByb3duYW1lcyhjb3JyZWxhdGlvbikpCgpwaGVhdG1hcChtYXQgPSBjb3JyZWxhdGlvbixtYWluID0gIkV4cHJlc3Npb24gY29ycmVsYXRpb24iKQpgYGAKCiMgQW50aWdlbiBwcmVzZW50aW5nIG1hY2hpbmVyeSB7LnRhYnNldH0KYGBge3J9CmFwbV9nZW5lcyA9IGMoIkhMQS1BIiwiSExBLUIiLCJITEEtQyIsIkIyTSIsIlRBUDEiLCJUQVAyIiwgIlRBUEJQIikKYXBtX3Njb3JlID0gRmV0Y2hEYXRhKGFjY19pbW11bmUsdmFycyA9IGFwbV9nZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgcm93TWVhbnMoKQphY2NfaW1tdW5lID0gQWRkTWV0YURhdGEob2JqZWN0ID0gYWNjX2ltbXVuZSxtZXRhZGF0YSA9IGFwbV9zY29yZSxjb2wubmFtZSA9ICJBUE1fc2NvcmUiKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwLCByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKHBsdCA9IEZlYXR1cmVQbG90KGFjY19pbW11bmUsZmVhdHVyZXMgPSBhcG1fZ2VuZXMpLHRpdGxlID0gImdlbmVzIikKcHJpbnRfdGFiKHBsdCA9IEZlYXR1cmVQbG90KGFjY19pbW11bmUsZmVhdHVyZXMgPSAiQVBNX3Njb3JlIiksdGl0bGUgPSAic2NvcmUiKQpgYGAKCiMgRXhoYXVzdGlvbiBtYXJrZXJzCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQpleGhhdXN0ZWRfZ2VuZXMgPSBjKCJQRENEMSIsIkNEMjQ0IiwiQ0QxNjAiLCJDVExBNCIsIkhBVkNSMiIpCkZlYXR1cmVQbG90KGFjY19pbW11bmUsZmVhdHVyZXMgPSBleGhhdXN0ZWRfZ2VuZXMpCmBgYAojIEltbXVuZSByZWNlcHRvcnMKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTB9CnJlY2VwdG9ycyA9IGMoIkNDUjMiLCAiQ0NSNCIsICJDQ1IxMCIsIkNYQ1IyIiwgIkNYQ1IzIiwgIkNYQ1I0IiwgIklMMTdBIikKRmVhdHVyZVBsb3QoYWNjX2ltbXVuZSxmZWF0dXJlcyA9IHJlY2VwdG9ycykKYGBgCgojIENlbGxwaG9uZURCCmBgYHtyfQphY2NfY2FuY2VyX2NlbGxzX3ByaSA9IHJlYWRSRFMoIi9zY2kvbGFicy95b3RhbWQvbGFiX3NoYXJlL2F2aXNoYWkud2l6ZWwvUl9wcm9qZWN0cy9BQ0NfbWljcm9lbnYvRGF0YS9hY2NfY2FuY2VyX25vMTQ2X3ByaW1hcnlvbmx5MTVrX2NhbmNlcmNlbGxzLnJkcyIpCmFjY19jYWYgPSByZWFkUkRTKCIvc2NpL2xhYnMveW90YW1kL2xhYl9zaGFyZS9BQ0MvQUNDX3NjL2FuYWx5c2lzL2FjY190cG1fbkNvdW50X21pdG9fbm8xNDZfY2Fmcy5yZHMiKQphY2NfaW1tdW5lX3ByaSA9IHN1YnNldChhY2NfaW1tdW5lLCBzdWJzZXQgPSBvcmlnaW4gPT0gIlByaW1hcnkiKQpgYGAKCgpgYGB7cn0KIyBtZXJnZSBjYW5jZXIgYW5kIGltbXVuZQpjb21tb25fZ2VuZXMgPSBpbnRlcnNlY3Qocm93bmFtZXMoYWNjX2NhbmNlcl9jZWxsc19wcmkpLHJvd25hbWVzKGFjY19pbW11bmVfcHJpKSkgJT4lIGludGVyc2VjdChyb3duYW1lcyhhY2NfY2FmX2NlbGxzKSkKYWNjX2NhbmNlcl9hbmRfY2Q0NSA9IG1lcmdlKGFjY19jYW5jZXJfY2VsbHNfcHJpW2NvbW1vbl9nZW5lcyxdLGFjY19pbW11bmVfcHJpW2NvbW1vbl9nZW5lcyxdKQpvdmVybGFwcGluZ19jZWxscyA9IGNvbG5hbWVzKGFjY19jYW5jZXJfY2VsbHNfcHJpKSAlPiUgaW50ZXJzZWN0KGNvbG5hbWVzKGFjY19jYWYpKSAKYWNjX2NhbmNlcl9jZDQ1X2NhZiA9IG1lcmdlKGFjY19jYW5jZXJfYW5kX2NkNDVbY29tbW9uX2dlbmVzLF0sYWNjX2NhZl9jZWxsc1tjb21tb25fZ2VuZXMsIWNvbG5hbWVzKGFjY19jYWZfY2VsbHMpICVpbiUgb3ZlcmxhcHBpbmdfY2VsbHNdICkKCmBgYAoKYGBge3J9CiAgI3dyaXRlIG1ldGFkYXRhCgojY3JlYXRlIGx1bSBvciBteW8KbHVtX292ZXJfbXlvID0gRmV0Y2hEYXRhKG9iamVjdCA9IGFjY19jYW5jZXJfY2VsbHNfcHJpLHZhcnMgPSAibHVtaW5hbF9vdmVyX215byIpCmx1bV9vdmVyX215byRsdW1fb3JfbXlvID0gIlVua25vd24iCmx1bV9vdmVyX215byRsdW1fb3JfbXlvIFtsdW1fb3Zlcl9teW8kbHVtaW5hbF9vdmVyX215bz4xXSAgPSAiTHVtaW5hbCIKbHVtX292ZXJfbXlvJGx1bV9vcl9teW8gW2x1bV9vdmVyX215byRsdW1pbmFsX292ZXJfbXlvPCgtMSldICA9ICJNeW8iCmx1bV9vcl9teW8gPSBsdW1fb3Zlcl9teW9bLCJsdW1fb3JfbXlvIixkcm9wID0gRl0KbmFtZXMobHVtX29yX215bylbMV0gPSAiY2VsbF9pZGVudGl0eSIKbHVtX29yX215byA9IGx1bV9vcl9teW8gJT4lIGZpbHRlcihjZWxsX2lkZW50aXR5ICE9ICJVbmtub3duIikgI3JlbW92ZSB1bmtub3duIGNlbGxzCiAgCiMgY29tYmluZQppbW11bmVfaWRlbnRpdHkgPUZldGNoRGF0YShvYmplY3QgPSBhY2NfaW1tdW5lX3ByaSx2YXJzID0gImNlbGxfaWRlbnRpdHkiKQpjYWZfaWRlbnRpdHkgPUZldGNoRGF0YShvYmplY3QgPSBhY2NfY2FmX2NlbGxzLHZhcnMgPSAiY2VsbC50eXBlIikKbmFtZXMoY2FmX2lkZW50aXR5KVsxXSA9ICJjZWxsX2lkZW50aXR5IgphbGxfaWRlbnRpdHkgPSBkby5jYWxsKCJyYmluZCIsIGxpc3QobHVtX29yX215bywgaW1tdW5lX2lkZW50aXR5LCBjYWZfaWRlbnRpdHkpKQoKI3JlbmFtZSBhbmQgc29ydCBjb2x1bW5zCmFsbF9pZGVudGl0eSRiYXJjb2RlX3NhbXBsZSA9IHJvd25hbWVzKGFsbF9pZGVudGl0eSkKYWxsX2lkZW50aXR5ID0gYWxsX2lkZW50aXR5ICU+JSByZW5hbWUoY2VsbF90eXBlID0gY2VsbF9pZGVudGl0eSkKYWxsX2lkZW50aXR5ID0gYWxsX2lkZW50aXR5WyxjKDIsMSldCgoKYGBgCgpgYGB7cn0Kd3JpdGUudGFibGUoeCA9IGFsbF9pZGVudGl0eSxmaWxlID0gIi4vRGF0YS9DZWxscGhvbmVEQi9tZXRhZGF0YV9wcmltYXJ5LnRzdiIscm93Lm5hbWVzID1GLHNlcCA9ICJcdCIpCmBgYAoKYGBge3J9CiN3cml0ZSBub3JtYWxpemVkIGNvdW50cwphY2NfY2FuY2VyX2NkNDVfY2FmID0gYWNjX2NhbmNlcl9jZDQ1X2NhZlsscm93bmFtZXMoYWxsX2lkZW50aXR5KV0KY291bnRfbWF0cml4ID0gYXMuZGF0YS5mcmFtZShhY2NfY2FuY2VyX2NkNDVfY2FmQGFzc2F5c1tbIlJOQSJdXUBkYXRhKQpmd3JpdGUoY291bnRfbWF0cml4LCBmaWxlID0gIi4vRGF0YS9DZWxscGhvbmVEQi9jb3VudHNfcHJpbWFyeS50eHQiLHNlcCA9ICJcdCIscm93Lm5hbWVzID0gVCkKYGBgCgoKCgpgYGB7cHl0aG9uIGluY2x1ZGU9RkFMU0V9CiNkb3dubG9hZCBkYXRhYmFzZQppbXBvcnQgcGFuZGFzIGFzIHBkCmltcG9ydCBnbG9iCmltcG9ydCBvcwojIC0tIFZlcnNpb24gb2YgdGhlIGRhdGFic2UKY3BkYl92ZXJzaW9uID0gJ3Y0LjEuMCcKCiMgLS0gUGF0aCB3aGVyZSB0aGUgaW5wdXQgZmlsZXMgdG8gZ2VuZXJhdGUgdGhlIGRhdGFiYXNlIGFyZSBsb2NhdGVkCmNwZGJfdGFyZ2V0X2RpciA9IG9zLnBhdGguam9pbignLi9EYXRhL0NlbGxwaG9uZURCLycsIGNwZGJfdmVyc2lvbikKCiMgRG93bmxvYWQgZGF0YWJhc2UKZnJvbSBjZWxscGhvbmVkYi51dGlscyBpbXBvcnQgZGJfdXRpbHMKZGJfdXRpbHMuZG93bmxvYWRfZGF0YWJhc2UoY3BkYl90YXJnZXRfZGlyLCBjcGRiX3ZlcnNpb24pCmBgYAoKYGBge3B5dGhvbiBpbmNsdWRlPUZBTFNFfQpmcm9tIGNlbGxwaG9uZWRiLnNyYy5jb3JlLm1ldGhvZHMgaW1wb3J0IGNwZGJfc3RhdGlzdGljYWxfYW5hbHlzaXNfbWV0aG9kCgpkZWNvbnZvbHV0ZWQsIG1lYW5zLCBwdmFsdWVzLCBzaWduaWZpY2FudF9tZWFucyA9IGNwZGJfc3RhdGlzdGljYWxfYW5hbHlzaXNfbWV0aG9kLmNhbGwoCiAgICBjcGRiX2ZpbGVfcGF0aCA9ICIuL0RhdGEvQ2VsbHBob25lREIvdjQuMS4wL2NlbGxwaG9uZWRiLnppcCIsICAgICAgICAgICAgICAgICAjIG1hbmRhdG9yeTogQ2VsbFBob25lREIgZGF0YWJhc2UgemlwIGZpbGUuCiAgICBtZXRhX2ZpbGVfcGF0aCA9ICIuL0RhdGEvQ2VsbHBob25lREIvbWV0YWRhdGFfcHJpbWFyeS50c3YiLCAgICAgICAgICAgICAgICAgIyBtYW5kYXRvcnk6IHRzdiBmaWxlIGRlZmluaW5nIGJhcmNvZGVzIHRvIGNlbGwgbGFiZWwuCiAgICBjb3VudHNfZmlsZV9wYXRoID0gIi4vRGF0YS9DZWxscGhvbmVEQi9jb3VudHNfcHJpbWFyeS50eHQiLCAgICAgICAgICAgICAjIG1hbmRhdG9yeTogbm9ybWFsaXplZCBjb3VudCBtYXRyaXguCiAgICBjb3VudHNfZGF0YSA9ICdoZ25jX3N5bWJvbCcsICAgICAgICAgICAgICAgICAgICAgIyBkZWZpbmVzIHRoZSBnZW5lIGFubm90YXRpb24gaW4gY291bnRzIG1hdHJpeC4KICAgIG91dHB1dF9wYXRoID0gIi4vRGF0YS9DZWxscGhvbmVEQi9vdXRwdXRfcHJpbWFyeSIsICAgICAgICAgICAgICAgICAgICAgICAgICAjIFBhdGggdG8gc2F2ZSByZXN1bHRzLgopCmBgYCAgIAoKCmBgYHtyfQpsaWJyYXJ5KGt0cGxvdHMpCmxpYnJhcnkocmV0aWN1bGF0ZSkKYWNjX2NhbmNlcl9jZDQ1X2NhZiRjZWxsX3R5cGUgPSBhbGxfaWRlbnRpdHlbLDIsZHJvcCA9IEZdICMgYWRkIGNlbGxzIGlkZW50aXRpZXMgdG8gU2V1cmF0CgojcmVhZCBkYXRhOgpwdmFscyA9ICBweSRwdmFsdWVzCm1lYW5zID0gcHkkbWVhbnMKCiNvcjoKcHZhbHMgPSByZWFkLmRlbGltKCIuL0RhdGEvQ2VsbHBob25lREIvb3V0cHV0X3ByaW1hcnkvc3RhdGlzdGljYWxfYW5hbHlzaXNfcHZhbHVlc18wOF8wMV8yMDIzXzE2OjEzOjMyLnR4dCIsY2hlY2submFtZXMgPSBGKQptZWFucyA9IHJlYWQuZGVsaW0oIi4vRGF0YS9DZWxscGhvbmVEQi9vdXRwdXRfcHJpbWFyeS9zdGF0aXN0aWNhbF9hbmFseXNpc19tZWFuc18wOF8wMV8yMDIzXzE2OjEzOjMyLnR4dCIsY2hlY2submFtZXMgPSBGKQoKYGBgCgojIHNpZ25pZmljYW50IGludGVyYWN0aW9ucyBoZWF0bWFwCmBgYHtyfQpwbG90X2NwZGJfaGVhdG1hcChzY2RhdGEgPSBhY2NfY2FuY2VyX2NkNDVfY2FmLCBpZGVudHMgPSAnY2VsbF90eXBlJyxwdmFscyA9ICBwdmFscyxtYWluID0gIk51bWJlciBvZiBzaWduaWZpY2FudCBpbnRlcmFjdGlvbnMiLGFscGhhID0gMC4wNSx0cmVlaGVpZ2h0X3JvdyA9IDUwKQpgYGAKCgoKYGBge3J9Cgp0cmFjZShwbG90X2NwZGIsZWRpdCA9IFQpCnVudHJhY2UocGxvdF9jcGRiKQpwbG90X2NwZGJfd2l0aF9jb2xfY2x1c3RlcmluZyA9IHBsb3RfY3BkYgp0b19pbnNlcnQgPXF1b3RlKAogICBpZiAobmNvbChtZWFuc19tYXQpID4gMikgewogICAgICAgICAgICAgIGQgPC0gZGlzdChhcy5kYXRhLmZyYW1lKHQobWVhbnNfbWF0KSkpCiAgICAgICAgICAgICAgaCA8LSBoY2x1c3QoZCkKICAgICAgICAgICAgICBtZWFuc19tYXQgPC0gbWVhbnNfbWF0WywgaCRvcmRlciwgZHJvcCA9IEZBTFNFXQogICAgICAgICAgICAgIHB2YWxzX21hdCA8LSBwdmFsc19tYXRbLCBoJG9yZGVyLCBkcm9wID0gRkFMU0VdCiAgICAgICAgICAgICAgcGxvdChoLCBtYWluID0gY2VsbF90eXBlMikKICB9CikKCgpib2R5KHBsb3RfY3BkYl93aXRoX2NvbF9jbHVzdGVyaW5nKSA8LSBib2R5KHBsb3RfY3BkYl93aXRoX2NvbF9jbHVzdGVyaW5nKSAlPiUgYXMubGlzdCAlPiUgYXBwZW5kKHRvX2luc2VydCxhZnRlciA9ICA0MSkgJT4lIGFzLmNhbGwKdHJhY2UocGxvdF9jcGRiX3dpdGhfY29sX2NsdXN0ZXJpbmcsZWRpdCA9IFQpCmBgYAoKCgpgYGB7cn0KdW5pcV9pbnRlcmFjdGlvbnMgPC0gZnVuY3Rpb24oY2VsbF90eXBlMSwgY2VsbF90eXBlMl9hICxjZWxsX3R5cGUyX2IsIGdlbmUuZmFtaWx5ID0gTlVMTCxnZW5lcyA9IE5VTEwpIHsKICByZXF1aXJlKHB1cnJyKQogIGEgPSBwbG90X2NwZGIoY2VsbF90eXBlMSA9IGNlbGxfdHlwZTEsIGNlbGxfdHlwZTIgPWNlbGxfdHlwZTJfYSwgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgICAgICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgICAgICAgICAgICAgZ2VuZS5mYW1pbHkgPSBnZW5lLmZhbWlseSxyZXR1cm5fdGFibGUgPSBULCBwLmFkanVzdC5tZXRob2QgPSAiZmRyIixrZWVwX3NpZ25pZmljYW50X29ubHkgPSBULCBnZW5lcyA9IGdlbmVzKQogIAogIGIgPSBwbG90X2NwZGIoY2VsbF90eXBlMSA9IGNlbGxfdHlwZTEsIGNlbGxfdHlwZTIgPSBjZWxsX3R5cGUyX2IsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICAgICAgICAgICAgICAgICAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICAgICAgICAgICAgICAgICAgICAgIGdlbmUuZmFtaWx5ID0gZ2VuZS5mYW1pbHkscmV0dXJuX3RhYmxlID0gVCxwLmFkanVzdC5tZXRob2QgPSAiZmRyIixrZWVwX3NpZ25pZmljYW50X29ubHkgPSBULCBnZW5lcyA9IGdlbmVzKQogIAogIAogIGFsbCA9IGxpc3QoKQogIGk9MAogIG5lbGVtZW50cyA9IGEkVmFyMiAlPiUgdW5pcXVlKCkgJT4lIGxlbmd0aCgpCiAgYV9jb3VwbGVzID0gYSRWYXIyICU+JSB1bmlxdWUoKSU+JSBhcy52ZWN0b3IoKSAgCiAgYl9jb3VwbGVzID0gYiRWYXIyICU+JSB1bmlxdWUoKSU+JSBhcy52ZWN0b3IoKSAgCiAgZm9yIChpIGluIDE6bmVsZW1lbnRzKSB7CiAgICBzaWdfY291cGxlc19hID0gYSAlPiUgZmlsdGVyKFZhcjIgPT0gYV9jb3VwbGVzW2ldKSAlPiUgZmlsdGVyKHB2YWxzX2FkaiA8PSAwLjA1KSAlPiUgIHB1bGwoVmFyMSkgJT4lIGFzLnZlY3RvcigpICAKICAgIHNpZ19jb3VwbGVzX2IgPSBiICU+JSBmaWx0ZXIoVmFyMiA9PSBiX2NvdXBsZXNbaV0pICU+JSBmaWx0ZXIocHZhbHNfYWRqIDw9IDAuMDUpICU+JSAgcHVsbChWYXIxKSAlPiUgYXMudmVjdG9yKCkgIAogICAgb25seV9pbl9hID0gc2lnX2NvdXBsZXNfYVshIHNpZ19jb3VwbGVzX2EgJWluJSBzaWdfY291cGxlc19iXQogICAgYWxsW1thX2NvdXBsZXNbaV1dXSA9IG9ubHlfaW5fYSAKICAgIGkgPSBpKzEKICB9CiAgYWxsID0gdChtYXBfZGZyKGFsbCwgfmFzX3RpYmJsZSh0KC4pKSkpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lICBzZXRfbmFtZXMoYV9jb3VwbGVzKQogIHJldHVybihhbGwpCn0KCmBgYCAgIAoKIyBBbGwgaW50ZXJhY3Rpb25zIHsudGFic2V0fQpgYGB7ciBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MjAsIHJlc3VsdHM9J2FzaXMnfQpwbG90X2NwZGJfd2l0aF9jb2xfY2x1c3RlcmluZyhjZWxsX3R5cGUxID0gJ0NEfEJ8TmF0dXJhbHxtb25vfE1hY3JvJywgY2VsbF90eXBlMiA9ICdMdW1pbmFsJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgICAgICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgICAgICAgICAgICAgZ2VuZS5mYW1pbHkgPSBOVUxMLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSAzLHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IFQsY2x1c3Rlcl9yb3dzID0gVCkrCiAgICAgICAgICAgIGdndGl0bGUoImFsbCBMdW1pbmFsIikrCnRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgYXhpcy50aWNrcy55PWVsZW1lbnRfYmxhbmsoKSkrCiAgcGxvdF9jcGRiX3dpdGhfY29sX2NsdXN0ZXJpbmcoY2VsbF90eXBlMSA9ICdDRHxCfE5hdHVyYWx8bW9ub3xNYWNybycsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgICAgICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgICAgICAgICAgICAgZ2VuZS5mYW1pbHkgPSBOVUxMLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSAzLHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IFQsY2x1c3Rlcl9yb3dzID0gVCkrCiAgICAgICAgICAgIGdndGl0bGUoImFsbCBNeW8iKSsKdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLAogICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpKQogICAgICAKICAgICAgCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgcGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTHVtaW5hbCcsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICAgICAgICAgICAgICAgICAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICAgICAgICAgICAgICAgICAgICAgIGdlbmUuZmFtaWx5ID0gTlVMTCxyZXR1cm5fdGFibGUgPSBGLG1heF9zaXplID0gMyxwLmFkanVzdC5tZXRob2QgPSAiZmRyIixrZWVwX3NpZ25pZmljYW50X29ubHkgPSBULGNsdXN0ZXJfcm93cyA9IFQpKwogICAgICAgICAgICBnZ3RpdGxlKCJhbGwgTHVtaW5hbCIpKwp0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpCiAgLHRpdGxlID0gIkx1bWluYWwiKQoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICBwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRHxCfEZDJywgY2VsbF90eXBlMiA9ICdNeW8nLCBzY2RhdGEgPSBhY2NfY2FuY2VyX2NkNDVfY2FmLAogICAgICAgICAgICAgICAgICAgICAgaWRlbnRzID0gJ2NlbGxfdHlwZScsIG1lYW5zID0gbWVhbnMsIHB2YWxzID0gcHZhbHMsCiAgICAgICAgICAgICAgICAgICAgICBnZW5lLmZhbWlseSA9IE5VTEwscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDMscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gVCxjbHVzdGVyX3Jvd3MgPSBUKSsKICAgICAgICAgICAgZ2d0aXRsZSgiYWxsIE15byIpKwp0aGVtZShheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksCiAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCkpCiAgLHRpdGxlID0gIkx1bWluYWwiKQoKCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgcGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgICAgICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgICAgICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY29zdGltdWxhdG9yeScscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDMscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gVCxjbHVzdGVyX3Jvd3MgPSBGKSsKICAgICAgICAgICAgZ2d0aXRsZSgiQ29zdGltdWxhdG9yeSBNeW8iKQogICx0aXRsZSA9ICJNeW8iKQoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICBwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRHxCfEZDJywgY2VsbF90eXBlMiA9ICdDQUYnLCBzY2RhdGEgPSBhY2NfY2FuY2VyX2NkNDVfY2FmLAogICAgICAgICAgICAgICAgICAgICAgaWRlbnRzID0gJ2NlbGxfdHlwZScsIG1lYW5zID0gbWVhbnMsIHB2YWxzID0gcHZhbHMsCiAgICAgICAgICAgICAgICAgICAgICBnZW5lLmZhbWlseSA9ICdjb3N0aW11bGF0b3J5JyxyZXR1cm5fdGFibGUgPSBGLG1heF9zaXplID0gMyxwLmFkanVzdC5tZXRob2QgPSAiZmRyIixrZWVwX3NpZ25pZmljYW50X29ubHkgPSBULGNsdXN0ZXJfcm93cyA9IEYpKwogICAgICAgICAgICBnZ3RpdGxlKCJDb3N0aW11bGF0b3J5IENBRiIpCiAgLHRpdGxlID0gIkNBRiIpCgpwcmludF90YWIocGx0ID0gCiAgICAgICAgICAgIHVuaXFfaW50ZXJhY3Rpb25zKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsY2VsbF90eXBlMl9hICA9ICdMdW1pbmFsJyxjZWxsX3R5cGUyX2IgPSAiTXlvIixnZW5lLmZhbWlseSA9ICJDb3N0aW11bGF0b3J5IikKLHRpdGxlID0gInVuaXF1ZSBpbiBsdW1pbmFsIikKCgpwcmludF90YWIocGx0ID0gCiAgICAgICAgICAgIHVuaXFfaW50ZXJhY3Rpb25zKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsY2VsbF90eXBlMl9hICA9ICdNeW8nLGNlbGxfdHlwZTJfYiA9ICJMdW1pbmFsIixnZW5lLmZhbWlseSA9ICJDb3N0aW11bGF0b3J5IikKLHRpdGxlID0gInVuaXF1ZSBpbiBteW8iKQoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICB1bmlxX2ludGVyYWN0aW9ucyhjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLGNlbGxfdHlwZTJfYSAgPSAnQ0FGJyxjZWxsX3R5cGUyX2IgPSAiTXlvfEx1bWluYWwiLGdlbmUuZmFtaWx5ID0gIkNvc3RpbXVsYXRvcnkiKQosdGl0bGUgPSAidW5pcXVlIGluIENBRiIpCmBgYAoKYGBge3J9CmFjY19pbW11bmUkc3BlY2lmaWNfaWRlbnRpdHkgPSBhY2NfaW1tdW5lJGNlbGxfaWRlbnRpdHkKYWNjX2ltbXVuZSAlPD4lIFNldElkZW50KHZhbHVlID0gInNwZWNpZmljX2lkZW50aXR5IikKYWNjX2ltbXVuZSA8LSBSZW5hbWVJZGVudHMoYWNjX2ltbXVuZSwgJ05haXZlIENENCsgVCBjZWxscycgPSAnQ0Q0KycsICdFZmZlY3RvciBDRDgrIFQgY2VsbHMnID0gJ0NEOCsnLCdDRDgrIE5LVC1saWtlIGNlbGxzJyA9ICJDRDgrIiwgJ05haXZlIENEOCsgVCBjZWxscycgPSAiQ0Q4KyIsICdFZmZlY3RvciBDRDQrIFQgY2VsbHMnID0gIkNENCsiKQphY2NfaW1tdW5lW1siY2VsbF9pZGVudGl0eSJdXSA8LSBJZGVudHMob2JqZWN0ID0gYWNjX2ltbXVuZSkKYGBgCgpgYGB7cn0KU2V1cmF0RGlzazo6U2F2ZUg1U2V1cmF0KG9iamVjdCA9IGFjY19pbW11bmUsZmlsZW5hbWUgPSAiLi9EYXRhL2FjY19pbW11bmVfNUt2YXJHZW5lc19WMl9jZWxsSWRlbnRpdHkuaDVzZXVyYXQiKQpgYGAKCiMgQ29pbmhpYml0b3J5IGludGVyYWN0aW9ucyB7LnRhYnNldH0KCmBgYHtyIGZpZy5oZWlnaHQ9NSxyZXN1bHRzPSdhc2lzJ30KCnByaW50X3RhYihwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRHxCfEZDJywgY2VsbF90eXBlMiA9ICdMdW1pbmFsJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY29pbmhpYml0b3J5JyxyZXR1cm5fdGFibGUgPSBGLG1heF9zaXplID0gNCxwLmFkanVzdC5tZXRob2QgPSAiZmRyIixrZWVwX3NpZ25pZmljYW50X29ubHkgPSBGLGNsdXN0ZXJfcm93cyA9IEYpKwogIGdndGl0bGUoImNvaW5oaWJpdG9yeSBMdW1pbmFsIiksdGl0bGUgPSAiTHVtaW5hbCIpCgpwcmludF90YWIocGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY29pbmhpYml0b3J5JyxyZXR1cm5fdGFibGUgPSBGLG1heF9zaXplID0gNCxwLmFkanVzdC5tZXRob2QgPSAiZmRyIixrZWVwX3NpZ25pZmljYW50X29ubHkgPSBGLGNsdXN0ZXJfcm93cyA9IEYpKwogIGdndGl0bGUoImNvaW5oaWJpdG9yeSBNeW8iKSx0aXRsZSA9ICJNeW8iKQoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICB1bmlxX2ludGVyYWN0aW9ucyhjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLGNlbGxfdHlwZTJfYSAgPSAnTHVtaW5hbCcsY2VsbF90eXBlMl9iID0gIk15byIsZ2VuZS5mYW1pbHkgPSAiY29pbmhpYml0b3J5IikKLHRpdGxlID0gInVuaXF1ZSBpbiBsdW1pbmFsIikKCgpwcmludF90YWIocGx0ID0gCiAgICAgICAgICAgIHVuaXFfaW50ZXJhY3Rpb25zKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsY2VsbF90eXBlMl9hICA9ICdNeW8nLGNlbGxfdHlwZTJfYiA9ICJMdW1pbmFsIixnZW5lLmZhbWlseSA9ICJjb2luaGliaXRvcnkiKQosdGl0bGUgPSAidW5pcXVlIGluIG15byIpCgpwcmludF90YWIocGx0ID0gCiAgICAgICAgICAgIHVuaXFfaW50ZXJhY3Rpb25zKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsY2VsbF90eXBlMl9hICA9ICdDQUYnLGNlbGxfdHlwZTJfYiA9ICJNeW98THVtaW5hbCIsZ2VuZS5mYW1pbHkgPSAiY29pbmhpYml0b3J5IikKLHRpdGxlID0gInVuaXF1ZSBpbiBDQUYiKQoKYGBgCgojIENoZW1va2luZXMgaW50ZXJhY3Rpb25zIHsudGFic2V0fQpgYGB7ciBmaWcuaGVpZ2h0PTYsIHJlc3VsdHM9J2FzaXMnfQpwcmludF90YWIoCiAgcGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTHVtaW5hbCcsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICAgICAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICAgICAgICAgIGdlbmUuZmFtaWx5ID0gJ2NoZW1va2luZXMnLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSA0LHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYsY2x1c3Rlcl9yb3dzID0gRikrCiAgZ2d0aXRsZSgiY2hlbW9raW5lcyBMdW1pbmFsIiksdGl0bGUgPSAiTHVtaW5hbCIpCgpwcmludF90YWIoCiAgcGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY2hlbW9raW5lcycscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gRixjbHVzdGVyX3Jvd3MgPSBGKSsKICBnZ3RpdGxlKCJjaGVtb2tpbmVzIE15byIpLHRpdGxlID0gIk15byIpCgoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICB1bmlxX2ludGVyYWN0aW9ucyhjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLGNlbGxfdHlwZTJfYSAgPSAnTHVtaW5hbCcsY2VsbF90eXBlMl9iID0gIk15byIsZ2VuZS5mYW1pbHkgPSAiY2hlbW9raW5lcyIpCix0aXRsZSA9ICJ1bmlxdWUgaW4gbHVtaW5hbCIpCgoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICB1bmlxX2ludGVyYWN0aW9ucyhjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLGNlbGxfdHlwZTJfYSAgPSAnTXlvJyxjZWxsX3R5cGUyX2IgPSAiTHVtaW5hbCIsZ2VuZS5mYW1pbHkgPSAiY2hlbW9raW5lcyIpCix0aXRsZSA9ICJ1bmlxdWUgaW4gbXlvIikKCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgdW5pcV9pbnRlcmFjdGlvbnMoY2VsbF90eXBlMSA9ICdDRHxCfEZDJyxjZWxsX3R5cGUyX2EgID0gJ0NBRicsY2VsbF90eXBlMl9iID0gIk15b3xMdW1pbmFsIixnZW5lLmZhbWlseSA9ICJjaGVtb2tpbmVzIikKLHRpdGxlID0gInVuaXF1ZSBpbiBDQUYiKQpgYGAKIyBDaGVtb2tpbmUgbGlnYW5kcyB7LnRhYnNldH0KYGBge3IgcmVzdWx0cz0nYXNpcyd9CmdlbmVzID0gYygiQ1hDTDFcXEQiLCAiQ1hDTDJcXEQiLCJDWENMM1xcRCIsIkNYQ0wxNyIsIkMzIiwiQ1hDTDE0IikKcHJpbnRfdGFiKHBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLCBjZWxsX3R5cGUyID0gJ015bycsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKIGdlbmVzID0gZ2VuZXMscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIgLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYpIAogLHRpdGxlID0gIk15byIpCgpwcmludF90YWIocGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTHVtaW5hbCcsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICBnZW5lcyA9IGdlbmVzLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSA0LHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiICxrZWVwX3NpZ25pZmljYW50X29ubHkgPSBGKSAKLHRpdGxlID0gIkx1bWluYWwiKQoKCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgdW5pcV9pbnRlcmFjdGlvbnMoY2VsbF90eXBlMSA9ICdDRHxCfEZDJyxjZWxsX3R5cGUyX2EgID0gJ0x1bWluYWwnLGNlbGxfdHlwZTJfYiA9ICJNeW8iLCBnZW5lcyA9IGdlbmVzKQosdGl0bGUgPSAidW5pcXVlIGluIGx1bWluYWwiKQoKCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgdW5pcV9pbnRlcmFjdGlvbnMoY2VsbF90eXBlMSA9ICdDRHxCfEZDJyxjZWxsX3R5cGUyX2EgID0gJ015bycsY2VsbF90eXBlMl9iID0gIkx1bWluYWwiLCBnZW5lcyA9IGdlbmVzKQosdGl0bGUgPSAidW5pcXVlIGluIG15byIpCgpwcmludF90YWIocGx0ID0gCiAgICAgICAgICAgIHVuaXFfaW50ZXJhY3Rpb25zKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsY2VsbF90eXBlMl9hICA9ICdDQUYnLGNlbGxfdHlwZTJfYiA9ICJNeW98THVtaW5hbCIsIGdlbmVzID0gZ2VuZXMpCix0aXRsZSA9ICJ1bmlxdWUgaW4gQ0FGIikKYGBgCiMgQ0NMMjIgYW5kIENDTDI4IHsudGFic2V0fQpgYGB7ciByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKHBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLCBjZWxsX3R5cGUyID0gJ015bycsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKIGdlbmVzID0gYygiQ0NMMjIiLCAiQ0NMMjgiICkscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIgLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYpLHRpdGxlID0gIk15byIpCgpwcmludF90YWIocGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0R8QnxGQycsIGNlbGxfdHlwZTIgPSAnTHVtaW5hbCcsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICBnZW5lcyA9IGMoIkNDTDIyIiwgIkNDTDI4IiApLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSA2LHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiICxrZWVwX3NpZ25pZmljYW50X29ubHkgPSBGKSx0aXRsZSA9ICJMdW1pbmFsIikKCgoKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTZ9CnBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEfEJ8RkMnLCBjZWxsX3R5cGUyID0gJ015bycsIHNjZGF0YSA9IGFjY19jYW5jZXJfY2Q0NV9jYWYsCiAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKIGdlbmVzID0gYygiSkFHIiwgIk1ZQiIgKSxyZXR1cm5fdGFibGUgPSBGLG1heF9zaXplID0gNCxwLmFkanVzdC5tZXRob2QgPSAiZmRyIiAsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gRikgCgpwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRHxCfEZDJywgY2VsbF90eXBlMiA9ICdMdW1pbmFsJywgc2NkYXRhID0gYWNjX2NhbmNlcl9jZDQ1X2NhZiwKICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogIGdlbmVzID0gYygiSkFHIiwgIk1ZQiIgLCAiTk9UQ0giLCJIRVMxIiwiSEVZIikscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIgLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYpIAoKCmBgYAoKPHNjcmlwdCBzcmM9Imh0dHBzOi8vaHlwb3RoZXMuaXMvZW1iZWQuanMiIGFzeW5jPjwvc2NyaXB0PgoK