Functions
Data
acc_immune = LoadH5Seurat(file = "./Data/acc_immune.h5seurat")
library("readxl")
signatures <- read_excel("./Data/Shengjin_et al_DataSheet_1.xlsx", sheet = "Gene Signature",skip = 42,col_names = F)
signatures = signatures %>% t() %>% as.data.frame() %>% janitor::row_to_names(1) %>% dplyr::filter(!row_number() %in% c(1))
log TMP
signatures
acc_immune = FindVariableFeatures(object = acc_immune,nfeatures = 5000,verbose = F)
for (col in 1:ncol(signatures)) {
genes = signatures[,col] %>% na.omit() %>% as.vector() %>% intersect(VariableFeatures(acc_immune))
if (length(genes) == 0 ){
print("skip")
next
}
score = acc_immune@assays$RNA@data[genes,] %>% colMeans()
acc_immune = AddMetaData(object = acc_immune,metadata = score, col.name = names(signatures)[col])
print_tab(FeaturePlot(object = acc_immune,features = names(signatures)[col]),title = names(signatures)[col])
}
Activated_B_cell

Activated_CD4_T_cell

Activated_CD8_T_cell

Central_memory_CD4_T_cel

Central_memory_CD8_T_cell

Effector_memeory_CD4_T_cell

Effector_memeory_CD8_T_cell

Gamma_delta_T_cell

Immature_B_cell

Memory_B_cell

Regulatory_T_cell

T_follicular_helper_cell

Type_1_T_helper_cell

Type_17_T_helper_cell

Type_2_T_helper_cell

Activated_dendritic_cell

CD56bright_natural_killer_cell

[1] “skip” ## Eosinophil {.unnumbered }

Immature_dendritic_cell

Macrophage

Mast_cell

MDSC

Monocyte

Natural_killer_cell

Natural_killer_T_cell

Neutrophil

Plasmacytoid_dendritic_cell

NA
scaled
data signatures
acc_immune = FindVariableFeatures(object = acc_immune,nfeatures = 5000,verbose = F)
for (col in 1:ncol(signatures)) {
genes = signatures[,col] %>% na.omit() %>% as.vector() %>% intersect(VariableFeatures(acc_immune))
if (length(genes) == 0 ){
print("skip")
next
}
score = acc_immune@assays$RNA@scale.data[genes,] %>% colMeans()
acc_immune = AddMetaData(object = acc_immune,metadata = score, col.name = names(signatures)[col])
print_tab(FeaturePlot(object = acc_immune,features = names(signatures)[col]),title = names(signatures)[col])
}
Activated_B_cell

Activated_CD4_T_cell

Activated_CD8_T_cell

Central_memory_CD4_T_cel

Central_memory_CD8_T_cell

Effector_memeory_CD4_T_cell

Effector_memeory_CD8_T_cell

Gamma_delta_T_cell

Immature_B_cell

Memory_B_cell

Regulatory_T_cell

T_follicular_helper_cell

Type_1_T_helper_cell

Type_17_T_helper_cell

Type_2_T_helper_cell

Activated_dendritic_cell

CD56bright_natural_killer_cell

[1] “skip” ## Eosinophil {.unnumbered }

Immature_dendritic_cell

Macrophage

Mast_cell

MDSC

Monocyte

Natural_killer_cell

Natural_killer_T_cell

Neutrophil

Plasmacytoid_dendritic_cell

# acc_immune <- AddModuleScore(
# object = acc_immune,
# features = list(genes),
# ctrl = 5,
# name = names(signatures)[col]
# )
# FeaturePlot(object = acc_immune,features = "Central_memory_CD4_T_cel1")
Clusters
acc_immune <- FindClusters(acc_immune, resolution = 1,verbose = F)
DimPlot(acc_immune,label = T)

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 = "Immune system" # 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)
ScType
es.max = sctype_score(scRNAseqData = acc_immune[["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(acc_immune@meta.data$seurat_clusters), function(cl){
es.max.cl = sort(rowSums(es.max[ ,rownames(acc_immune@meta.data[acc_immune@meta.data$seurat_clusters==cl, ])]), decreasing = !0)
head(data.frame(cluster = cl, type = names(es.max.cl), scores = es.max.cl, ncells = sum(acc_immune@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])
acc_immune@meta.data$cell_identity = ""
for(j in unique(sctype_scores$cluster)){
cl_type = sctype_scores[sctype_scores$cluster==j,];
acc_immune@meta.data$cell_identity[acc_immune@meta.data$seurat_clusters == j] = as.character(cl_type$type[1])
}
DimPlot(acc_immune, reduction = "umap", label = TRUE, repel = TRUE, group.by = 'cell_identity')

cL_resutls
acc_immune = SetIdent(object = acc_immune,value = "cell_identity")
g1_treat <- WhichCells(acc_immune, idents = c( "Macrophages"))
DimPlot(acc_immune, label=F, cells.highlight= g1_treat, cols.highlight = c( "red"), cols= "grey")
FindMarkers(object = acc_immune,ident.1 = "1",densify = T)
FeaturePlot(object = acc_immune,features = "GATA3")
scores_data = AverageExpression(object = acc_immune,features = names(signatures))
pheatmap(scores_data)
FeaturePlot(object = acc_immune,features = names(signatures)[1:6])
FeaturePlot(object = acc_immune,features = names(signatures)[7:13])
FeaturePlot(object = acc_immune,features = names(signatures)[14:17])
FeaturePlot(object = acc_immune,features = names(signatures)[20:26])
FeaturePlot(object = acc_immune,features = names(signatures)[27:28])
Immune markers
FeaturePlot(acc_immune, features = c("CD4","MS4A1", "SELL", "CD3E", "S100A4","CD14","GNLY","MS4A1"))
assign cell type
acc_immune <- RenameIdents(object = acc_immune,
"0" = "Naive CD4+ T",
"1" = "Memory CD4+",
"2" = "CD14+ Mono",
"3" = "Memory CD4+",
"4" = "CD8+ T",
"5" = "B",
"6" = "Naive CD4+ T",
"7" = "Memory CD4+",
"8" = "Memory CD4+")
acc_immune$cell_identity = acc_immune@active.ident
DimPlot(object = acc_immune,label = T)
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")
Exhaustion
markers
exhausted_genes = c("PDCD1","CD244","CD160","CTLA4","HAVCR2")
FeaturePlot(acc_immune,features = exhausted_genes)
Immune receptors
receptors = c("CCR3", "CCR4", "CCR10","CXCR2", "CXCR3", "CXCR4", "IL17A")
FeaturePlot(acc_immune,features = receptors)
CellphoneDB
acc_cancer_cells = readRDS("/sci/labs/yotamd/lab_share/avishai.wizel/R_projects/ACC_microenv/Data/acc_cancer_no146_primaryonly15k_cancercells.rds")
# merge cancer and immune
common_genes = intersect(rownames(acc_cancer_cells),rownames(acc_immune))
acc_cancer_and_cd45 = merge(acc_cancer_cells[common_genes,],acc_immune[common_genes,])
#write metadata
#create lum or myo
lum_over_myo = FetchData(object = acc_cancer_cells,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"
# combine
immune_identity =FetchData(object = acc_immune,vars = "cell_identity")
all_identity= rbind(lum_or_myo,immune_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.tsv",row.names =F,sep = "\t")
#write normalized counts
count_matrix = as.data.frame(acc_cancer_and_cd45@assays[["RNA"]]@data)
fwrite(count_matrix, file = "./Data/CellphoneDB/counts.txt",sep = "\t",row.names = T)
library(ktplots)
acc_cancer_and_cd45$cell_type = all_identity[,2,drop = F] # add cells identities to seurat
#read data:
pvals = read.delim(file = "./Data/CellphoneDB/output/statistical_analysis_pvalues_07_19_2023_12:16:16.txt", check.names = FALSE)
means = read.delim(file = "./Data/CellphoneDB/output/statistical_analysis_means_07_19_2023_12:16:16.txt", check.names = FALSE)
significant
interactions heatmap
plot_cpdb_heatmap(scdata = acc_cancer_and_cd45, idents = 'cell_type',pvals = pvals,main = "Number of significant interactions",alpha = 0.05)
Costimulatory interactions
print_tab(plt =
plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Luminal', scdata = acc_cancer_and_cd45,
idents = 'cell_type', means = means, pvals = pvals,
gene.family = 'costimulatory',return_table = F,max_size = 3,p.adjust.method = "fdr",keep_significant_only = T,cluster_rows = F)+
ggtitle("costimulatory Luminal")
,title = "Luminal")
print_tab(plt =
plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Myo', scdata = acc_cancer_and_cd45,
idents = 'cell_type', means = means, pvals = pvals,
gene.family = 'costimulatory',return_table = F,max_size = 3,p.adjust.method = "fdr",keep_significant_only = T,cluster_rows = F)+
ggtitle("costimulatory Myo")
,title = "Myo")
Coinhibitory interactions
print_tab(plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Luminal', scdata = acc_cancer_and_cd45,
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', cell_type2 = 'Myo', scdata = acc_cancer_and_cd45,
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")
Chemokines interactions
print_tab(
plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Luminal', scdata = acc_cancer_and_cd45,
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', cell_type2 = 'Myo', scdata = acc_cancer_and_cd45,
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")
Chemokine ligands
print_tab(plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Myo', scdata = acc_cancer_and_cd45,
idents = 'cell_type', means = means, pvals = pvals,
genes = c("CXCL1\\D", "CXCL2\\D","CXCL3\\D","CXCL17","C3","CXCL14"),return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F)
,title = "Myo")
print_tab(plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Luminal', scdata = acc_cancer_and_cd45,
idents = 'cell_type', means = means, pvals = pvals,
genes = c("CXCL1\\D", "CXCL2\\D","CXCL3\\D","CXCL17","C3","CXCL14"),return_table = F,max_size = 4,p.adjust.method = "fdr" ,keep_significant_only = F)
,title = "Luminal")
CCL22
and CCL28
print_tab(plot_cpdb(cell_type1 = 'CD', cell_type2 = 'Myo', scdata = acc_cancer_and_cd45,
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', cell_type2 = 'Luminal', scdata = acc_cancer_and_cd45,
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', cell_type2 = 'Myo', scdata = acc_cancer_and_cd45,
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', cell_type2 = 'Luminal', scdata = acc_cancer_and_cd45,
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)
LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCgoKIyBGdW5jdGlvbnMKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmBgYAoKIyBEYXRhCgpgYGB7cn0KYWNjX2ltbXVuZSA9IExvYWRINVNldXJhdChmaWxlID0gIi4vRGF0YS9hY2NfaW1tdW5lLmg1c2V1cmF0IikKYGBgCgpgYGB7cn0KbGlicmFyeSgicmVhZHhsIikKc2lnbmF0dXJlcyA8LSByZWFkX2V4Y2VsKCIuL0RhdGEvU2hlbmdqaW5fZXQgYWxfRGF0YVNoZWV0XzEueGxzeCIsIHNoZWV0ID0gIkdlbmUgU2lnbmF0dXJlIixza2lwID0gNDIsY29sX25hbWVzID0gRikKc2lnbmF0dXJlcyA9IHNpZ25hdHVyZXMgJT4lIHQoKSAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBqYW5pdG9yOjpyb3dfdG9fbmFtZXMoMSkgJT4lIGRwbHlyOjpmaWx0ZXIoIXJvd19udW1iZXIoKSAlaW4lIGMoMSkpCmBgYAoKCgojIGxvZyBUTVAgc2lnbmF0dXJlcyB7LnRhYnNldH0KYGBge3IgcmVzdWx0cz0nYXNpcyd9CmFjY19pbW11bmUgPSBGaW5kVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBhY2NfaW1tdW5lLG5mZWF0dXJlcyA9IDUwMDAsdmVyYm9zZSA9IEYpCmZvciAoY29sIGluIDE6bmNvbChzaWduYXR1cmVzKSkgewogIGdlbmVzID0gc2lnbmF0dXJlc1ssY29sXSAlPiUgbmEub21pdCgpICU+JSBhcy52ZWN0b3IoKSAlPiUgaW50ZXJzZWN0KFZhcmlhYmxlRmVhdHVyZXMoYWNjX2ltbXVuZSkpCiAgaWYgKGxlbmd0aChnZW5lcykgPT0gMCApewogICAgcHJpbnQoInNraXAiKQogICAgbmV4dAogIH0KICBzY29yZSA9IGFjY19pbW11bmVAYXNzYXlzJFJOQUBkYXRhW2dlbmVzLF0gJT4lIGNvbE1lYW5zKCkKICBhY2NfaW1tdW5lID0gQWRkTWV0YURhdGEob2JqZWN0ID0gYWNjX2ltbXVuZSxtZXRhZGF0YSA9IHNjb3JlLCBjb2wubmFtZSA9IG5hbWVzKHNpZ25hdHVyZXMpW2NvbF0pCiAgcHJpbnRfdGFiKEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19pbW11bmUsZmVhdHVyZXMgPSBuYW1lcyhzaWduYXR1cmVzKVtjb2xdKSx0aXRsZSA9IG5hbWVzKHNpZ25hdHVyZXMpW2NvbF0pCgp9CgpgYGAKIyBzY2FsZWQgZGF0YSBzaWduYXR1cmVzIHsudGFic2V0fQoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmFjY19pbW11bmUgPSBGaW5kVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBhY2NfaW1tdW5lLG5mZWF0dXJlcyA9IDUwMDAsdmVyYm9zZSA9IEYpCmZvciAoY29sIGluIDE6bmNvbChzaWduYXR1cmVzKSkgewogIGdlbmVzID0gc2lnbmF0dXJlc1ssY29sXSAlPiUgbmEub21pdCgpICU+JSBhcy52ZWN0b3IoKSAlPiUgaW50ZXJzZWN0KFZhcmlhYmxlRmVhdHVyZXMoYWNjX2ltbXVuZSkpCiAgaWYgKGxlbmd0aChnZW5lcykgPT0gMCApewogICAgcHJpbnQoInNraXAiKQogICAgbmV4dAogIH0KICBzY29yZSA9IGFjY19pbW11bmVAYXNzYXlzJFJOQUBzY2FsZS5kYXRhW2dlbmVzLF0gJT4lIGNvbE1lYW5zKCkKICBhY2NfaW1tdW5lID0gQWRkTWV0YURhdGEob2JqZWN0ID0gYWNjX2ltbXVuZSxtZXRhZGF0YSA9IHNjb3JlLCBjb2wubmFtZSA9IG5hbWVzKHNpZ25hdHVyZXMpW2NvbF0pCiAgcHJpbnRfdGFiKEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19pbW11bmUsZmVhdHVyZXMgPSBuYW1lcyhzaWduYXR1cmVzKVtjb2xdKSx0aXRsZSA9IG5hbWVzKHNpZ25hdHVyZXMpW2NvbF0pCgp9CgoKIyBhY2NfaW1tdW5lIDwtIEFkZE1vZHVsZVNjb3JlKAojICAgb2JqZWN0ID0gYWNjX2ltbXVuZSwKIyAgIGZlYXR1cmVzID0gbGlzdChnZW5lcyksCiMgICBjdHJsID0gNSwKIyAgIG5hbWUgPSBuYW1lcyhzaWduYXR1cmVzKVtjb2xdCiMgKQojIEZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19pbW11bmUsZmVhdHVyZXMgPSAiQ2VudHJhbF9tZW1vcnlfQ0Q0X1RfY2VsMSIpCgoKYGBgCiMgQ2x1c3RlcnMKYGBge3J9CmFjY19pbW11bmUgPC0gRmluZENsdXN0ZXJzKGFjY19pbW11bmUsIHJlc29sdXRpb24gPSAxLHZlcmJvc2UgPSBGKQpEaW1QbG90KGFjY19pbW11bmUsbGFiZWwgPSBUKQpgYGAKCmBgYHtyfQpsYXBwbHkoYygiZHBseXIiLCJTZXVyYXQiLCJIR05DaGVscGVyIiksIGxpYnJhcnksIGNoYXJhY3Rlci5vbmx5ID0gVCkKc291cmNlKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSWFuZXZza2lBbGVrc2FuZHIvc2MtdHlwZS9tYXN0ZXIvUi9nZW5lX3NldHNfcHJlcGFyZS5SIik7IHNvdXJjZSgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0lhbmV2c2tpQWxla3NhbmRyL3NjLXR5cGUvbWFzdGVyL1Ivc2N0eXBlX3Njb3JlXy5SIikKCmRiXyA9ICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vSWFuZXZza2lBbGVrc2FuZHIvc2MtdHlwZS9tYXN0ZXIvU2NUeXBlREJfZnVsbC54bHN4IjsKdGlzc3VlID0gIkltbXVuZSBzeXN0ZW0iICMgZS5nLiBJbW11bmUgc3lzdGVtLFBhbmNyZWFzLExpdmVyLEV5ZSxLaWRuZXksQnJhaW4sTHVuZyxBZHJlbmFsLEhlYXJ0LEludGVzdGluZSxNdXNjbGUsUGxhY2VudGEsU3BsZWVuLFN0b21hY2gsVGh5bXVzIAoKIyBwcmVwYXJlIGdlbmUgc2V0cwpnc19saXN0ID0gZ2VuZV9zZXRzX3ByZXBhcmUoZGJfLCB0aXNzdWUpCmBgYAoKIyBTY1R5cGUKYGBge3J9CmVzLm1heCA9IHNjdHlwZV9zY29yZShzY1JOQXNlcURhdGEgPSBhY2NfaW1tdW5lW1siUk5BIl1dQHNjYWxlLmRhdGEsIHNjYWxlZCA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgZ3MgPSBnc19saXN0JGdzX3Bvc2l0aXZlLCBnczIgPSBnc19saXN0JGdzX25lZ2F0aXZlKSAKIyBtZXJnZSBieSBjbHVzdGVyCmNMX3Jlc3V0bHMgPSBkby5jYWxsKCJyYmluZCIsIGxhcHBseSh1bmlxdWUoYWNjX2ltbXVuZUBtZXRhLmRhdGEkc2V1cmF0X2NsdXN0ZXJzKSwgZnVuY3Rpb24oY2wpewogICAgZXMubWF4LmNsID0gc29ydChyb3dTdW1zKGVzLm1heFsgLHJvd25hbWVzKGFjY19pbW11bmVAbWV0YS5kYXRhW2FjY19pbW11bmVAbWV0YS5kYXRhJHNldXJhdF9jbHVzdGVycz09Y2wsIF0pXSksIGRlY3JlYXNpbmcgPSAhMCkKICAgIGhlYWQoZGF0YS5mcmFtZShjbHVzdGVyID0gY2wsIHR5cGUgPSBuYW1lcyhlcy5tYXguY2wpLCBzY29yZXMgPSBlcy5tYXguY2wsIG5jZWxscyA9IHN1bShhY2NfaW1tdW5lQG1ldGEuZGF0YSRzZXVyYXRfY2x1c3RlcnM9PWNsKSksIDEwKQp9KSkKc2N0eXBlX3Njb3JlcyA9IGNMX3Jlc3V0bHMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuID0gMSwgd3QgPSBzY29yZXMpICAKCiMgc2V0IGxvdy1jb25maWRlbnQgKGxvdyBTY1R5cGUgc2NvcmUpIGNsdXN0ZXJzIHRvICJ1bmtub3duIgpzY3R5cGVfc2NvcmVzJHR5cGVbYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoc2N0eXBlX3Njb3JlcyRzY29yZXMpKSA8IHNjdHlwZV9zY29yZXMkbmNlbGxzLzRdID0gIlVua25vd24iCnByaW50KHNjdHlwZV9zY29yZXNbLDE6M10pCgphY2NfaW1tdW5lQG1ldGEuZGF0YSRjZWxsX2lkZW50aXR5ID0gIiIKZm9yKGogaW4gdW5pcXVlKHNjdHlwZV9zY29yZXMkY2x1c3RlcikpewogIGNsX3R5cGUgPSBzY3R5cGVfc2NvcmVzW3NjdHlwZV9zY29yZXMkY2x1c3Rlcj09aixdOyAKICBhY2NfaW1tdW5lQG1ldGEuZGF0YSRjZWxsX2lkZW50aXR5W2FjY19pbW11bmVAbWV0YS5kYXRhJHNldXJhdF9jbHVzdGVycyA9PSBqXSA9IGFzLmNoYXJhY3RlcihjbF90eXBlJHR5cGVbMV0pCn0KCkRpbVBsb3QoYWNjX2ltbXVuZSwgcmVkdWN0aW9uID0gInVtYXAiLCBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVFJVRSwgZ3JvdXAuYnkgPSAnY2VsbF9pZGVudGl0eScpICAKYGBgCgoKCmBgYHtyfQpjTF9yZXN1dGxzCmBgYAoKCmBgYHtyfQphY2NfaW1tdW5lID0gU2V0SWRlbnQob2JqZWN0ID0gYWNjX2ltbXVuZSx2YWx1ZSA9ICJjZWxsX2lkZW50aXR5IikKZzFfdHJlYXQgPC0gV2hpY2hDZWxscyhhY2NfaW1tdW5lLCBpZGVudHMgPSBjKCAiTWFjcm9waGFnZXMiKSkKRGltUGxvdChhY2NfaW1tdW5lLCBsYWJlbD1GLCBjZWxscy5oaWdobGlnaHQ9IGcxX3RyZWF0LCBjb2xzLmhpZ2hsaWdodCA9IGMoICJyZWQiKSwgY29scz0gImdyZXkiKQpgYGAKCmBgYHtyfQpGaW5kTWFya2VycyhvYmplY3QgPSBhY2NfaW1tdW5lLGlkZW50LjEgPSAiMSIsZGVuc2lmeSA9IFQpCmBgYAoKYGBge3J9CkZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19pbW11bmUsZmVhdHVyZXMgPSAiR0FUQTMiKQpgYGAKCgpgYGB7ciBmaWcud2lkdGg9MTJ9CnNjb3Jlc19kYXRhID0gQXZlcmFnZUV4cHJlc3Npb24ob2JqZWN0ID0gYWNjX2ltbXVuZSxmZWF0dXJlcyA9IG5hbWVzKHNpZ25hdHVyZXMpKQpwaGVhdG1hcChzY29yZXNfZGF0YSkKYGBgCgpgYGB7ciBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMH0KRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2ltbXVuZSxmZWF0dXJlcyA9IG5hbWVzKHNpZ25hdHVyZXMpWzE6Nl0pCkZlYXR1cmVQbG90KG9iamVjdCA9IGFjY19pbW11bmUsZmVhdHVyZXMgPSBuYW1lcyhzaWduYXR1cmVzKVs3OjEzXSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2ltbXVuZSxmZWF0dXJlcyA9IG5hbWVzKHNpZ25hdHVyZXMpWzE0OjE3XSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2ltbXVuZSxmZWF0dXJlcyA9IG5hbWVzKHNpZ25hdHVyZXMpWzIwOjI2XSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gYWNjX2ltbXVuZSxmZWF0dXJlcyA9IG5hbWVzKHNpZ25hdHVyZXMpWzI3OjI4XSkKCmBgYAoKCiMgSW1tdW5lIG1hcmtlcnMKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTB9CkZlYXR1cmVQbG90KGFjY19pbW11bmUsIGZlYXR1cmVzID0gYygiQ0Q0IiwiTVM0QTEiLCAiU0VMTCIsICJDRDNFIiwgICJTMTAwQTQiLCJDRDE0IiwiR05MWSIsIk1TNEExIikpCmBgYAojIGFzc2lnbiBjZWxsIHR5cGUKYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KYWNjX2ltbXVuZSA8LSBSZW5hbWVJZGVudHMob2JqZWN0ID0gYWNjX2ltbXVuZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMCIgPSAiTmFpdmUgQ0Q0KyBUIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxIiA9ICJNZW1vcnkgQ0Q0KyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMiIgPSAiQ0QxNCsgTW9ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMyIgPSAiTWVtb3J5IENENCsiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjQiID0gIkNEOCsgVCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNSIgPSAiQiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNiIgPSAiTmFpdmUgQ0Q0KyBUIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI3IiA9ICJNZW1vcnkgQ0Q0KyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOCIgPSAiTWVtb3J5IENENCsiKQphY2NfaW1tdW5lJGNlbGxfaWRlbnRpdHkgPSBhY2NfaW1tdW5lQGFjdGl2ZS5pZGVudApEaW1QbG90KG9iamVjdCA9IGFjY19pbW11bmUsbGFiZWwgPSBUKQpgYGAKCiMgQW50aWdlbiBwcmVzZW50aW5nIG1hY2hpbmVyeSB7LnRhYnNldH0KYGBge3J9CmFwbV9nZW5lcyA9IGMoIkhMQS1BIiwiSExBLUIiLCJITEEtQyIsIkIyTSIsIlRBUDEiLCJUQVAyIiwgIlRBUEJQIikKYXBtX3Njb3JlID0gRmV0Y2hEYXRhKGFjY19pbW11bmUsdmFycyA9IGFwbV9nZW5lcyxzbG90ID0gImRhdGEiKSAlPiUgcm93TWVhbnMoKQphY2NfaW1tdW5lID0gQWRkTWV0YURhdGEob2JqZWN0ID0gYWNjX2ltbXVuZSxtZXRhZGF0YSA9IGFwbV9zY29yZSxjb2wubmFtZSA9ICJBUE1fc2NvcmUiKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwLCByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKHBsdCA9IEZlYXR1cmVQbG90KGFjY19pbW11bmUsZmVhdHVyZXMgPSBhcG1fZ2VuZXMpLHRpdGxlID0gImdlbmVzIikKcHJpbnRfdGFiKHBsdCA9IEZlYXR1cmVQbG90KGFjY19pbW11bmUsZmVhdHVyZXMgPSAiQVBNX3Njb3JlIiksdGl0bGUgPSAic2NvcmUiKQpgYGAKCiMgRXhoYXVzdGlvbiBtYXJrZXJzCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQpleGhhdXN0ZWRfZ2VuZXMgPSBjKCJQRENEMSIsIkNEMjQ0IiwiQ0QxNjAiLCJDVExBNCIsIkhBVkNSMiIpCkZlYXR1cmVQbG90KGFjY19pbW11bmUsZmVhdHVyZXMgPSBleGhhdXN0ZWRfZ2VuZXMpCmBgYAojIEltbXVuZSByZWNlcHRvcnMKYGBge3IgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTB9CnJlY2VwdG9ycyA9IGMoIkNDUjMiLCAiQ0NSNCIsICJDQ1IxMCIsIkNYQ1IyIiwgIkNYQ1IzIiwgIkNYQ1I0IiwgIklMMTdBIikKRmVhdHVyZVBsb3QoYWNjX2ltbXVuZSxmZWF0dXJlcyA9IHJlY2VwdG9ycykKCmBgYAojIENlbGxwaG9uZURCCmBgYHtyfQphY2NfY2FuY2VyX2NlbGxzID0gcmVhZFJEUygiL3NjaS9sYWJzL3lvdGFtZC9sYWJfc2hhcmUvYXZpc2hhaS53aXplbC9SX3Byb2plY3RzL0FDQ19taWNyb2Vudi9EYXRhL2FjY19jYW5jZXJfbm8xNDZfcHJpbWFyeW9ubHkxNWtfY2FuY2VyY2VsbHMucmRzIikKYGBgCgoKCmBgYHtyfQojIG1lcmdlIGNhbmNlciBhbmQgaW1tdW5lCmNvbW1vbl9nZW5lcyA9IGludGVyc2VjdChyb3duYW1lcyhhY2NfY2FuY2VyX2NlbGxzKSxyb3duYW1lcyhhY2NfaW1tdW5lKSkKYWNjX2NhbmNlcl9hbmRfY2Q0NSA9IG1lcmdlKGFjY19jYW5jZXJfY2VsbHNbY29tbW9uX2dlbmVzLF0sYWNjX2ltbXVuZVtjb21tb25fZ2VuZXMsXSkKYGBgCgpgYGB7cn0KICAjd3JpdGUgbWV0YWRhdGEKCiNjcmVhdGUgbHVtIG9yIG15bwpsdW1fb3Zlcl9teW8gPSBGZXRjaERhdGEob2JqZWN0ID0gYWNjX2NhbmNlcl9jZWxscyx2YXJzID0gImx1bWluYWxfb3Zlcl9teW8iKQpsdW1fb3Zlcl9teW8kbHVtX29yX215byA9ICJVbmtub3duIgpsdW1fb3Zlcl9teW8kbHVtX29yX215byBbbHVtX292ZXJfbXlvJGx1bWluYWxfb3Zlcl9teW8+MV0gID0gIkx1bWluYWwiCmx1bV9vdmVyX215byRsdW1fb3JfbXlvIFtsdW1fb3Zlcl9teW8kbHVtaW5hbF9vdmVyX215bzwoLTEpXSAgPSAiTXlvIgpsdW1fb3JfbXlvID0gbHVtX292ZXJfbXlvWywibHVtX29yX215byIsZHJvcCA9IEZdCm5hbWVzKGx1bV9vcl9teW8pWzFdID0gImNlbGxfaWRlbnRpdHkiCgojIGNvbWJpbmUKaW1tdW5lX2lkZW50aXR5ID1GZXRjaERhdGEob2JqZWN0ID0gYWNjX2ltbXVuZSx2YXJzID0gImNlbGxfaWRlbnRpdHkiKQphbGxfaWRlbnRpdHk9IHJiaW5kKGx1bV9vcl9teW8saW1tdW5lX2lkZW50aXR5ICkKCiNyZW5hbWUgYW5kIHNvcnQgY29sdW1ucwphbGxfaWRlbnRpdHkkYmFyY29kZV9zYW1wbGUgPSByb3duYW1lcyhhbGxfaWRlbnRpdHkpCmFsbF9pZGVudGl0eSA9IGFsbF9pZGVudGl0eSAlPiUgcmVuYW1lKGNlbGxfdHlwZSA9IGNlbGxfaWRlbnRpdHkpCmFsbF9pZGVudGl0eSA9IGFsbF9pZGVudGl0eVssYygyLDEpXQoKCndyaXRlLnRhYmxlKHggPSBhbGxfaWRlbnRpdHksZmlsZSA9ICIuL0RhdGEvQ2VsbHBob25lREIvbWV0YWRhdGEudHN2Iixyb3cubmFtZXMgPUYsc2VwID0gIlx0IikKYGBgCgpgYGB7cn0KI3dyaXRlIG5vcm1hbGl6ZWQgY291bnRzCmNvdW50X21hdHJpeCA9IGFzLmRhdGEuZnJhbWUoYWNjX2NhbmNlcl9hbmRfY2Q0NUBhc3NheXNbWyJSTkEiXV1AZGF0YSkKZndyaXRlKGNvdW50X21hdHJpeCwgZmlsZSA9ICIuL0RhdGEvQ2VsbHBob25lREIvY291bnRzLnR4dCIsc2VwID0gIlx0Iixyb3cubmFtZXMgPSBUKQpgYGAKCgpgYGB7cHl0aG9uIGluY2x1ZGU9RkFMU0V9CiNkb3dubG9hZCBkYXRhYmFzZQppbXBvcnQgcGFuZGFzIGFzIHBkCmltcG9ydCBnbG9iCmltcG9ydCBvcwojIC0tIFZlcnNpb24gb2YgdGhlIGRhdGFic2UKY3BkYl92ZXJzaW9uID0gJ3Y0LjEuMCcKCiMgLS0gUGF0aCB3aGVyZSB0aGUgaW5wdXQgZmlsZXMgdG8gZ2VuZXJhdGUgdGhlIGRhdGFiYXNlIGFyZSBsb2NhdGVkCmNwZGJfdGFyZ2V0X2RpciA9IG9zLnBhdGguam9pbignLi9EYXRhL0NlbGxwaG9uZURCLycsIGNwZGJfdmVyc2lvbikKCiMgRG93bmxvYWQgZGF0YWJhc2UKZnJvbSBjZWxscGhvbmVkYi51dGlscyBpbXBvcnQgZGJfdXRpbHMKZGJfdXRpbHMuZG93bmxvYWRfZGF0YWJhc2UoY3BkYl90YXJnZXRfZGlyLCBjcGRiX3ZlcnNpb24pCmBgYAoKYGBge3B5dGhvbiBpbmNsdWRlPUZBTFNFfQpmcm9tIGNlbGxwaG9uZWRiLnNyYy5jb3JlLm1ldGhvZHMgaW1wb3J0IGNwZGJfc3RhdGlzdGljYWxfYW5hbHlzaXNfbWV0aG9kCgpkZWNvbnZvbHV0ZWQsIG1lYW5zLCBwdmFsdWVzLCBzaWduaWZpY2FudF9tZWFucyA9IGNwZGJfc3RhdGlzdGljYWxfYW5hbHlzaXNfbWV0aG9kLmNhbGwoCiAgICBjcGRiX2ZpbGVfcGF0aCA9ICIuL0RhdGEvQ2VsbHBob25lREIvdjQuMS4wL2NlbGxwaG9uZWRiLnppcCIsICAgICAgICAgICAgICAgICAjIG1hbmRhdG9yeTogQ2VsbFBob25lREIgZGF0YWJhc2UgemlwIGZpbGUuCiAgICBtZXRhX2ZpbGVfcGF0aCA9ICIuL0RhdGEvQ2VsbHBob25lREIvbWV0YWRhdGEudHN2IiwgICAgICAgICAgICAgICAgICMgbWFuZGF0b3J5OiB0c3YgZmlsZSBkZWZpbmluZyBiYXJjb2RlcyB0byBjZWxsIGxhYmVsLgogICAgY291bnRzX2ZpbGVfcGF0aCA9ICIuL0RhdGEvQ2VsbHBob25lREIvY291bnRzLnR4dCIsICAgICAgICAgICAgICMgbWFuZGF0b3J5OiBub3JtYWxpemVkIGNvdW50IG1hdHJpeC4KICAgIGNvdW50c19kYXRhID0gJ2hnbmNfc3ltYm9sJywgICAgICAgICAgICAgICAgICAgICAjIGRlZmluZXMgdGhlIGdlbmUgYW5ub3RhdGlvbiBpbiBjb3VudHMgbWF0cml4LgogICAgb3V0cHV0X3BhdGggPSAiLi9EYXRhL0NlbGxwaG9uZURCL291dHB1dCIsICAgICAgICAgICAgICAgICAgICAgICAgICAjIFBhdGggdG8gc2F2ZSByZXN1bHRzLgopCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KGt0cGxvdHMpCmFjY19jYW5jZXJfYW5kX2NkNDUkY2VsbF90eXBlID0gYWxsX2lkZW50aXR5WywyLGRyb3AgPSBGXSAjIGFkZCBjZWxscyBpZGVudGl0aWVzIHRvIHNldXJhdAoKI3JlYWQgZGF0YToKcHZhbHMgPSAgcmVhZC5kZWxpbShmaWxlID0gIi4vRGF0YS9DZWxscGhvbmVEQi9vdXRwdXQvc3RhdGlzdGljYWxfYW5hbHlzaXNfcHZhbHVlc18wN18xOV8yMDIzXzEyOjE2OjE2LnR4dCIsIGNoZWNrLm5hbWVzID0gRkFMU0UpCm1lYW5zID0gcmVhZC5kZWxpbShmaWxlID0gIi4vRGF0YS9DZWxscGhvbmVEQi9vdXRwdXQvc3RhdGlzdGljYWxfYW5hbHlzaXNfbWVhbnNfMDdfMTlfMjAyM18xMjoxNjoxNi50eHQiLCBjaGVjay5uYW1lcyA9IEZBTFNFKQoKYGBgCgojIHNpZ25pZmljYW50IGludGVyYWN0aW9ucyBoZWF0bWFwCmBgYHtyfQpwbG90X2NwZGJfaGVhdG1hcChzY2RhdGEgPSBhY2NfY2FuY2VyX2FuZF9jZDQ1LCBpZGVudHMgPSAnY2VsbF90eXBlJyxwdmFscyA9ICBwdmFscyxtYWluID0gIk51bWJlciBvZiBzaWduaWZpY2FudCBpbnRlcmFjdGlvbnMiLGFscGhhID0gMC4wNSkKYGBgCgojIENvc3RpbXVsYXRvcnkgaW50ZXJhY3Rpb25zIHsudGFic2V0fQpgYGB7ciBmaWcuaGVpZ2h0PTgsIHJlc3VsdHM9J2FzaXMnfQoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICBwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRCcsIGNlbGxfdHlwZTIgPSAnTHVtaW5hbCcsIHNjZGF0YSA9IGFjY19jYW5jZXJfYW5kX2NkNDUsCiAgICAgICAgICAgICAgICAgICAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICAgICAgICAgICAgICAgICAgICAgIGdlbmUuZmFtaWx5ID0gJ2Nvc3RpbXVsYXRvcnknLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSAzLHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IFQsY2x1c3Rlcl9yb3dzID0gRikrCiAgICAgICAgICAgIGdndGl0bGUoImNvc3RpbXVsYXRvcnkgTHVtaW5hbCIpCiAgLHRpdGxlID0gIkx1bWluYWwiKQoKcHJpbnRfdGFiKHBsdCA9IAogICAgICAgICAgICBwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRCcsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9hbmRfY2Q0NSwKICAgICAgICAgICAgICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgICAgICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY29zdGltdWxhdG9yeScscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDMscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gVCxjbHVzdGVyX3Jvd3MgPSBGKSsKICAgICAgICAgICAgZ2d0aXRsZSgiY29zdGltdWxhdG9yeSBNeW8iKQogICx0aXRsZSA9ICJNeW8iKQpgYGAKCiMgQ29pbmhpYml0b3J5IGludGVyYWN0aW9ucyB7LnRhYnNldH0KCmBgYHtyIGZpZy5oZWlnaHQ9NSxyZXN1bHRzPSdhc2lzJ30KCnByaW50X3RhYihwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRCcsIGNlbGxfdHlwZTIgPSAnTHVtaW5hbCcsIHNjZGF0YSA9IGFjY19jYW5jZXJfYW5kX2NkNDUsCiAgICAgICAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKICAgICAgICAgIGdlbmUuZmFtaWx5ID0gJ2NvaW5oaWJpdG9yeScscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gRixjbHVzdGVyX3Jvd3MgPSBGKSsKICBnZ3RpdGxlKCJjb2luaGliaXRvcnkgTHVtaW5hbCIpLHRpdGxlID0gIkx1bWluYWwiKQoKcHJpbnRfdGFiKHBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEJywgY2VsbF90eXBlMiA9ICdNeW8nLCBzY2RhdGEgPSBhY2NfY2FuY2VyX2FuZF9jZDQ1LAogICAgICAgICAgaWRlbnRzID0gJ2NlbGxfdHlwZScsIG1lYW5zID0gbWVhbnMsIHB2YWxzID0gcHZhbHMsCiAgICAgICAgICBnZW5lLmZhbWlseSA9ICdjb2luaGliaXRvcnknLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSA0LHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYsY2x1c3Rlcl9yb3dzID0gRikrCiAgZ2d0aXRsZSgiY29pbmhpYml0b3J5IE15byIpLHRpdGxlID0gIk15byIpCmBgYAoKIyBDaGVtb2tpbmVzIGludGVyYWN0aW9ucyB7LnRhYnNldH0KYGBge3IgZmlnLmhlaWdodD02LCByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKAogIHBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEJywgY2VsbF90eXBlMiA9ICdMdW1pbmFsJywgc2NkYXRhID0gYWNjX2NhbmNlcl9hbmRfY2Q0NSwKICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY2hlbW9raW5lcycscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gRixjbHVzdGVyX3Jvd3MgPSBGKSsKICBnZ3RpdGxlKCJjaGVtb2tpbmVzIEx1bWluYWwiKSx0aXRsZSA9ICJMdW1pbmFsIikKCnByaW50X3RhYigKICBwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRCcsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9hbmRfY2Q0NSwKICAgICAgICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogICAgICAgICAgZ2VuZS5mYW1pbHkgPSAnY2hlbW9raW5lcycscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gRixjbHVzdGVyX3Jvd3MgPSBGKSsKICBnZ3RpdGxlKCJjaGVtb2tpbmVzIE15byIpLHRpdGxlID0gIk15byIpCmBgYAojIENoZW1va2luZSBsaWdhbmRzIHsudGFic2V0fQpgYGB7ciByZXN1bHRzPSdhc2lzJ30KcHJpbnRfdGFiKHBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEJywgY2VsbF90eXBlMiA9ICdNeW8nLCBzY2RhdGEgPSBhY2NfY2FuY2VyX2FuZF9jZDQ1LAogICAgaWRlbnRzID0gJ2NlbGxfdHlwZScsIG1lYW5zID0gbWVhbnMsIHB2YWxzID0gcHZhbHMsCiBnZW5lcyA9IGMoIkNYQ0wxXFxEIiwgIkNYQ0wyXFxEIiwiQ1hDTDNcXEQiLCJDWENMMTciLCJDMyIsIkNYQ0wxNCIpLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSA0LHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiICxrZWVwX3NpZ25pZmljYW50X29ubHkgPSBGKSAKICx0aXRsZSA9ICJNeW8iKQoKcHJpbnRfdGFiKHBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEJywgY2VsbF90eXBlMiA9ICdMdW1pbmFsJywgc2NkYXRhID0gYWNjX2NhbmNlcl9hbmRfY2Q0NSwKICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogIGdlbmVzID0gYygiQ1hDTDFcXEQiLCAiQ1hDTDJcXEQiLCJDWENMM1xcRCIsIkNYQ0wxNyIsIkMzIiwiQ1hDTDE0IikscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIgLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYpIAosdGl0bGUgPSAiTHVtaW5hbCIpCgpgYGAKIyBDQ0wyMiBhbmQgQ0NMMjggey50YWJzZXR9CmBgYHtyIHJlc3VsdHM9J2FzaXMnfQpwcmludF90YWIocGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0QnLCBjZWxsX3R5cGUyID0gJ015bycsIHNjZGF0YSA9IGFjY19jYW5jZXJfYW5kX2NkNDUsCiAgICBpZGVudHMgPSAnY2VsbF90eXBlJywgbWVhbnMgPSBtZWFucywgcHZhbHMgPSBwdmFscywKIGdlbmVzID0gYygiQ0NMMjIiLCAiQ0NMMjgiICkscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIgLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYpLHRpdGxlID0gIk15byIpCgpwcmludF90YWIocGxvdF9jcGRiKGNlbGxfdHlwZTEgPSAnQ0QnLCBjZWxsX3R5cGUyID0gJ0x1bWluYWwnLCBzY2RhdGEgPSBhY2NfY2FuY2VyX2FuZF9jZDQ1LAogICAgaWRlbnRzID0gJ2NlbGxfdHlwZScsIG1lYW5zID0gbWVhbnMsIHB2YWxzID0gcHZhbHMsCiAgZ2VuZXMgPSBjKCJDQ0wyMiIsICJDQ0wyOCIgKSxyZXR1cm5fdGFibGUgPSBGLG1heF9zaXplID0gNixwLmFkanVzdC5tZXRob2QgPSAiZmRyIiAsa2VlcF9zaWduaWZpY2FudF9vbmx5ID0gRiksdGl0bGUgPSAiTHVtaW5hbCIpCgoKCmBgYAoKYGBge3IgZmlnLmhlaWdodD02fQpwbG90X2NwZGIoY2VsbF90eXBlMSA9ICdDRCcsIGNlbGxfdHlwZTIgPSAnTXlvJywgc2NkYXRhID0gYWNjX2NhbmNlcl9hbmRfY2Q0NSwKICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogZ2VuZXMgPSBjKCJKQUciLCAiTVlCIiApLHJldHVybl90YWJsZSA9IEYsbWF4X3NpemUgPSA0LHAuYWRqdXN0Lm1ldGhvZCA9ICJmZHIiICxrZWVwX3NpZ25pZmljYW50X29ubHkgPSBGKSAKCnBsb3RfY3BkYihjZWxsX3R5cGUxID0gJ0NEJywgY2VsbF90eXBlMiA9ICdMdW1pbmFsJywgc2NkYXRhID0gYWNjX2NhbmNlcl9hbmRfY2Q0NSwKICAgIGlkZW50cyA9ICdjZWxsX3R5cGUnLCBtZWFucyA9IG1lYW5zLCBwdmFscyA9IHB2YWxzLAogIGdlbmVzID0gYygiSkFHIiwgIk1ZQiIgLCAiTk9UQ0giLCJIRVMxIiwiSEVZIikscmV0dXJuX3RhYmxlID0gRixtYXhfc2l6ZSA9IDQscC5hZGp1c3QubWV0aG9kID0gImZkciIgLGtlZXBfc2lnbmlmaWNhbnRfb25seSA9IEYpIAoKCmBgYAo8c2NyaXB0IHNyYz0iaHR0cHM6Ly9oeXBvdGhlcy5pcy9lbWJlZC5qcyIgYXN5bmM+PC9zY3JpcHQ+Cgo=