1. load libraries
2. Load Seurat Object
load("/home/bioinfo/Cluster_to_Computer_Transfer_files_folder/All_Normal-PBMC_Abnormal-cellLines_T_cells_Merged_Annotated_UMAP_on_Clusters_to_USE.Robj")
All_samples_Merged <- SetIdent(All_samples_Merged, value = "cell_line")
DimPlot(All_samples_Merged,group.by = "cell_line",
reduction = "umap",
label.size = 3,
repel = T,
label = T)

DimPlot(All_samples_Merged,
group.by = "SCT_snn_res.0.9",
reduction = "umap",
label.size = 3,
repel = T,
label = T)

#cluster_table <- table(Idents(All_samples_Merged))
DimPlot(All_samples_Merged, group.by = "predicted.celltype.l2",
reduction = "umap",
label.size = 3,
repel = T,
label = T)

# library(clustree)
# clustree(All_samples_Merged, prefix = "SCT_snn_res.")
DimPlot(All_samples_Merged, group.by = "predicted.celltype.l1",
reduction = "umap",
label.size = 3,
repel = T,
label = T, label.box = T)

DimPlot(All_samples_Merged, group.by = "predicted.celltype.l1",
reduction = "umap",
label.size = 3,
repel = T,
label = F)

DimPlot(All_samples_Merged, group.by = "predicted.celltype.l2",
reduction = "umap",
label.size = 3,
repel = T,
label = T, label.box = T)

DimPlot(All_samples_Merged, group.by = "predicted.celltype.l2",
reduction = "umap",
label.size = 3,
repel = T,
label = F)

DimPlot(All_samples_Merged, group.by = "predicted.celltype.l2",
reduction = "umap",
label.size = 3,
repel = T,
label = T, label.box = T)

# table(All_samples_Merged$predicted.celltype.l2, All_samples_Merged$SCT_snn_res.0.9)
3. Perform DE analysis using the FindMarkers or FindAllMarkers
function
EnhancedVolcano(Patient_cell_lines_vs_PBMC_Tcells ,
lab=rownames(Patient_cell_lines_vs_PBMC_Tcells),
x ="avg_log2FC",
y ="p_val_adj",
title = "Sézary Cell Lines vs PBMC T cells",
pCutoff = 0.05,
FCcutoff = 1,
legendPosition = 'right',
labCol = 'black',
labFace = 'bold',
boxedLabels = TRUE,
pointSize = 3.0,
labSize = 5.0,
drawConnectors = TRUE,
widthConnectors = 0.25)
Warning: One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

EnhancedVolcano(Patient_cell_lines_vs_PBMC_Tcells ,
lab=rownames(Patient_cell_lines_vs_PBMC_Tcells),
x ="avg_log2FC",
y ="p_val_adj",
selectLab = c('EPCAM','BCAT1','KIR3DL2',
'FOXM1','TWIST1','TNFSF9','CD80','CD7','IL1B', 'TRBV7.6','TRBV5.4','TRBV12.4'),
title = "Sézary Cell Lines vs PBMC T cells",
xlab = bquote(~Log[2]~ 'fold change'),
pCutoff = 0.05,
FCcutoff = 1,
legendPosition = 'right',
legendLabSize = 14,
legendIconSize = 4.0,
labCol = 'black',
labFace = 'bold',
boxedLabels = TRUE,
pointSize = 3.0,
labSize = 5.0,
drawConnectors = TRUE,
widthConnectors = 0.75,
colConnectors = 'black')
Warning: One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

EnhancedVolcano(Patient_cell_lines_vs_PBMC_Tcells,
lab = ifelse(Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 1 & Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05,
rownames(Patient_cell_lines_vs_PBMC_Tcells),
""), # Label only significant genes
x = "avg_log2FC",
y = "p_val_adj",
title = "Sézary Cell Lines vs PBMC T cells",
pCutoff = 0.05,
FCcutoff = 1,
legendPosition = 'right',
labCol = 'black',
labFace = 'bold',
boxedLabels = TRUE,
pointSize = 3.0,
labSize = 5.0,
drawConnectors = TRUE,
widthConnectors = 0.25)
Warning: One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

EnhancedVolcano(Patient_cell_lines_vs_PBMC_Tcells,
lab = ifelse((Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 1.5 | Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC < -1.5) &
Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05,
rownames(Patient_cell_lines_vs_PBMC_Tcells),
""), # Label only significant genes
x = "avg_log2FC",
y = "p_val_adj",
title = "Sézary Cell Lines vs PBMC T cells",
pCutoff = 0.05,
FCcutoff = 1,
legendPosition = 'right',
labCol = 'black',
labFace = 'bold',
boxedLabels = TRUE,
pointSize = 3.0,
labSize = 5.0,
drawConnectors = TRUE,
widthConnectors = 0.25)
Warning: One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

All_samples_Merged <- SetIdent(All_samples_Merged, value = "SCT_snn_res.0.9")
L2_Thesholds <- FindMarkers(All_samples_Merged, ident.1 = "4", ident.2 = "9", min.pct = 0.10, thresh.use = 0.25)
EnhancedVolcano(L2_Thesholds ,
lab=rownames(L2_Thesholds),
x ="avg_log2FC",
y ="p_val_adj",
title = "4_vs_9",
pCutoff = 0.05,
FCcutoff = 1,
legendPosition = 'right',
labCol = 'black',
labFace = 'bold',
boxedLabels = TRUE,
pointSize = 3.0,
labSize = 3.0,
drawConnectors = FALSE,
widthConnectors = 0.75)
Warning: One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4. Enrichment Analysis
#Step-by-Step Guide for Gene Set Enrichment Analysis (GSEA) or Over-Representation Analysis (ORA)
# Load the packages
library(clusterProfiler)
library(org.Hs.eg.db)
library(enrichplot)
library(ReactomePA)
# Get upregulated genes
upregulated_genes <- rownames(Patient_cell_lines_vs_PBMC_Tcells[Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 1.5 & Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05, ])
# Get downregulated genes
downregulated_genes <- rownames(Patient_cell_lines_vs_PBMC_Tcells[Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC < -1.5 & Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05, ])
#Gene Ontology (GO) Enrichment Analysis
# GO enrichment for upregulated genes
go_up <- enrichGO(gene = upregulated_genes,
OrgDb = org.Hs.eg.db,
keyType = "SYMBOL",
ont = "BP", # "BP" for Biological Processes, "MF" for Molecular Function, "CC" for Cellular Component
pAdjustMethod = "BH",
pvalueCutoff = 0.05)
# GO enrichment for downregulated genes
go_down <- enrichGO(gene = downregulated_genes,
OrgDb = org.Hs.eg.db,
keyType = "SYMBOL",
ont = "BP",
pAdjustMethod = "BH",
pvalueCutoff = 0.05)
# Visualize the top enriched GO terms
dotplot(go_up, showCategory = 20, title = "GO Enrichment for Upregulated Genes")

dotplot(go_down, showCategory = 20, title = "GO Enrichment for Downregulated Genes")

#KEGG Pathway Enrichment
# Convert gene symbols to Entrez IDs for KEGG analysis
upregulated_entrez <- bitr(upregulated_genes, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)$ENTREZID
'select()' returned 1:many mapping between keys and columns
Warning: 17.78% of input gene IDs are fail to map...
downregulated_entrez <- bitr(downregulated_genes, fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)$ENTREZID
'select()' returned 1:1 mapping between keys and columns
Warning: 8.54% of input gene IDs are fail to map...
# KEGG pathway enrichment for upregulated genes
kegg_up <- enrichKEGG(gene = upregulated_entrez,
organism = "hsa",
pvalueCutoff = 0.05)
# KEGG pathway enrichment for downregulated genes
kegg_down <- enrichKEGG(gene = downregulated_entrez,
organism = "hsa",
pvalueCutoff = 0.05)
# Visualize KEGG pathway results
dotplot(kegg_up, showCategory = 20, title = "KEGG Pathway Enrichment for Upregulated Genes")

dotplot(kegg_down, showCategory = 20, title = "KEGG Pathway Enrichment for Downregulated Genes")

#Reactome Pathway Enrichment
# Reactome pathway enrichment for upregulated genes
reactome_up <- enrichPathway(gene = upregulated_entrez,
organism = "human",
pvalueCutoff = 0.05)
# Reactome pathway enrichment for downregulated genes
reactome_down <- enrichPathway(gene = downregulated_entrez,
organism = "human",
pvalueCutoff = 0.05)
# Visualize Reactome pathways
dotplot(reactome_up, showCategory = 20, title = "Reactome Pathway Enrichment for Upregulated Genes")

dotplot(reactome_down, showCategory = 20, title = "Reactome Pathway Enrichment for Downregulated Genes")

# Gene Set Enrichment Analysis (GSEA) (Optional)
# Create a ranked list of genes
gene_list <- Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC
names(gene_list) <- rownames(Patient_cell_lines_vs_PBMC_Tcells)
gene_list <- sort(gene_list, decreasing = TRUE)
# Convert gene symbols to Entrez IDs
gene_df <- bitr(names(gene_list), fromType = "SYMBOL", toType = "ENTREZID", OrgDb = org.Hs.eg.db)
'select()' returned 1:many mapping between keys and columns
Warning: 11.26% of input gene IDs are fail to map...
# Ensure the gene list matches the Entrez IDs
gene_list <- gene_list[names(gene_list) %in% gene_df$SYMBOL]
# Replace gene symbols with Entrez IDs
names(gene_list) <- gene_df$ENTREZID[match(names(gene_list), gene_df$SYMBOL)]
# Run GSEA using KEGG
gsea_kegg <- gseKEGG(geneList = gene_list,
organism = "hsa",
pvalueCutoff = 0.05)
using 'fgsea' for GSEA analysis, please cite Korotkevich et al (2019).
preparing geneSet collections...
GSEA analysis...
Warning: There are ties in the preranked stats (0.82% of the list).
The order of those tied genes will be arbitrary, which may produce unexpected results.Warning: There were 7 pathways for which P-values were not calculated properly due to unbalanced (positive and negative) gene-level statistic values. For such pathways pval, padj, NES, log2err are set to NA. You can try to increase the value of the argument nPermSimple (for example set it nPermSimple = 10000)Warning: For some of the pathways the P-values were likely overestimated. For such pathways log2err is set to NA.leading edge analysis...
done...
# Plot the GSEA results
gseaplot(gsea_kegg, geneSetID = 1, title = "Top KEGG Pathway")

# Extract the name of the top KEGG pathway
top_pathway <- gsea_kegg@result[1, "Description"]
# Plot GSEA with the top pathway's name as the title
gseaplot(gsea_kegg, geneSetID = 1, title = top_pathway)

NA
NA
5. Bar PLOT
# Filter for significant pathways
top_kegg_up <- kegg_up@result[kegg_up@result$p.adjust < 0.05, ]
top_kegg_down <- kegg_down@result[kegg_down@result$p.adjust < 0.05, ]
# If there are not enough pathways, consider relaxing the threshold or checking the output
top_kegg_up <- top_kegg_up[order(-top_kegg_up$p.adjust), ][1:10, ]
top_kegg_down <- top_kegg_down[order(top_kegg_down$p.adjust), ][1:10, ]
# Combine into one data frame
top_pathways <- rbind(
data.frame(Pathway = top_kegg_up$Description, p.adjust = top_kegg_up$p.adjust, Direction = "Upregulated"),
data.frame(Pathway = top_kegg_down$Description, p.adjust = top_kegg_down$p.adjust, Direction = "Downregulated")
)
# Convert p.adjust to -log10(p.adjust) for visualization
top_pathways$neg_log10_p <- -log10(top_pathways$p.adjust)
# Create the barplot
ggplot(top_pathways, aes(x = reorder(Pathway, neg_log10_p), y = neg_log10_p, fill = Direction)) +
geom_bar(stat = "identity", position = position_dodge()) +
scale_fill_manual(values = c("Upregulated" = "red", "Downregulated" = "blue")) +
coord_flip() + # Flip the coordinates for better readability
labs(title = "Top Significant Pathways",
x = "Pathways",
y = "-Log10 Adjusted P-Value") +
theme_minimal() +
theme(legend.title = element_blank())

# Load necessary library
library(ggplot2)
# Create the barplot
ggplot(top_pathways, aes(x = Pathway, y = neg_log10_p, fill = Direction)) +
geom_bar(stat = "identity", position = "identity") + # Use position = "identity"
scale_fill_manual(values = c("Upregulated" = "red", "Downregulated" = "blue")) +
coord_flip() + # Flip the coordinates for better readability
labs(title = "Top Significant Pathways",
x = "Pathways",
y = "-Log10 Adjusted P-Value") +
theme_minimal() +
theme(legend.title = element_blank())

NA
NA
NA
5. ggplot2 for Volcano
library(ggplot2)
library(ggrepel)
# Identify top and bottom genes
top_genes <- Patient_cell_lines_vs_PBMC_Tcells[Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05 & Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 2, ]
bottom_genes <- Patient_cell_lines_vs_PBMC_Tcells[Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05 & Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC < -1.5, ]
# Create a new column for color based on significance
Patient_cell_lines_vs_PBMC_Tcells$color <- ifelse(Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 2, "Top Gene",
ifelse(Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC < -1.5, "Bottom Gene", "Neutral"))
# Create a volcano plot
ggplot(Patient_cell_lines_vs_PBMC_Tcells, aes(x = avg_log2FC, y = -log10(p_val_adj))) +
geom_point(aes(color = color), alpha = 0.7, size = 2) +
# Add labels for top and bottom genes
geom_text_repel(data = top_genes, aes(label = gene), color = "black", vjust = 1, fontface = "bold") +
geom_text_repel(data = bottom_genes, aes(label = gene), color = "black", vjust = -1, fontface = "bold") +
# Customize labels and title
labs(title = "Volcano Plot",
x = "log2 Fold Change",
y = "-log10(p-value)") +
# Add significance threshold lines
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black") +
geom_vline(xintercept = c(-1.5, 2), linetype = "dashed", color = "black") +
# Set colors for top and bottom genes
scale_color_manual(values = c("Top Gene" = "red", "Bottom Gene" = "blue", "Neutral" = "darkgrey")) +
# Customize theme if needed
theme_minimal()

NA
NA
NA
NA
NA
library(ggplot2)
library(ggrepel)
# Identify top and bottom genes based on criteria
top_genes <- Patient_cell_lines_vs_PBMC_Tcells[Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05 & Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 2, ]
bottom_genes <- Patient_cell_lines_vs_PBMC_Tcells[Patient_cell_lines_vs_PBMC_Tcells$p_val_adj < 0.05 & Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC < -1.5, ]
# Sort and select the most significant top and bottom genes
top_genes <- top_genes[order(top_genes$p_val_adj), ][1:100, ] # Top 100 significant upregulated genes
bottom_genes <- bottom_genes[order(bottom_genes$p_val_adj), ][1:100, ] # Top 100 significant downregulated genes
# Create a new column for color based on significance
Patient_cell_lines_vs_PBMC_Tcells$color <- ifelse(Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC > 2, "Top Gene",
ifelse(Patient_cell_lines_vs_PBMC_Tcells$avg_log2FC < -1.5, "Bottom Gene", "Neutral"))
# Create a volcano plot
ggplot(Patient_cell_lines_vs_PBMC_Tcells, aes(x = avg_log2FC, y = -log10(p_val_adj))) +
geom_point(aes(color = color), alpha = 0.7, size = 2) +
# Add labels only for top 100 and bottom 100 genes
geom_text_repel(data = top_genes, aes(label = gene), color = "black", vjust = 1, fontface = "bold") +
geom_text_repel(data = bottom_genes, aes(label = gene), color = "black", vjust = -1, fontface = "bold") +
# Customize labels and title
labs(title = "Volcano Plot",
x = "log2 Fold Change",
y = "-log10(p-value)") +
# Add significance threshold lines
geom_hline(yintercept = -log10(0.05), linetype = "dashed", color = "black") +
geom_vline(xintercept = c(-1.5, 2), linetype = "dashed", color = "black") +
# Set colors for top and bottom genes
scale_color_manual(values = c("Top Gene" = "red", "Bottom Gene" = "blue", "Neutral" = "darkgrey")) +
# Customize theme if needed
theme_minimal()

NA
NA
NA
NA
NA
LS0tCnRpdGxlOiAiRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQW5hbHlzaXMgYXQgMC45IgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogICNybWRmb3JtYXRzOjpyZWFkdGhlZG93bgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQotLS0KCiMgMS4gbG9hZCBsaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KFNldXJhdE9iamVjdCkKbGlicmFyeShTZXVyYXREYXRhKQpsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeShoYXJtb255KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShyZXRpY3VsYXRlKQpsaWJyYXJ5KEF6aW11dGgpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoUnRzbmUpCmxpYnJhcnkoaGFybW9ueSkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQpgYGAKCiMgMi4gTG9hZCBTZXVyYXQgT2JqZWN0IApgYGB7ciBsb2FkX3NldXJhdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9MTB9CgogbG9hZCgiL2hvbWUvYmlvaW5mby9DbHVzdGVyX3RvX0NvbXB1dGVyX1RyYW5zZmVyX2ZpbGVzX2ZvbGRlci9BbGxfTm9ybWFsLVBCTUNfQWJub3JtYWwtY2VsbExpbmVzX1RfY2VsbHNfTWVyZ2VkX0Fubm90YXRlZF9VTUFQX29uX0NsdXN0ZXJzX3RvX1VTRS5Sb2JqIikKIApBbGxfc2FtcGxlc19NZXJnZWQgPC0gU2V0SWRlbnQoQWxsX3NhbXBsZXNfTWVyZ2VkLCB2YWx1ZSA9ICJjZWxsX2xpbmUiKQogIApEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCxncm91cC5ieSA9ICJjZWxsX2xpbmUiLCAKICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgbGFiZWwuc2l6ZSA9IDMsCiAgICAgICAgcmVwZWwgPSBULAogICAgICAgIGxhYmVsID0gVCkKCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLAogICAgICAgIGdyb3VwLmJ5ID0gIlNDVF9zbm5fcmVzLjAuOSIsIAogICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICBsYWJlbC5zaXplID0gMywKICAgICAgICByZXBlbCA9IFQsCiAgICAgICAgbGFiZWwgPSBUKQoKY2x1c3Rlcl90YWJsZSA8LSB0YWJsZShJZGVudHMoQWxsX3NhbXBsZXNfTWVyZ2VkKSkKCgpEaW1QbG90KEFsbF9zYW1wbGVzX01lcmdlZCwgZ3JvdXAuYnkgPSAicHJlZGljdGVkLmNlbGx0eXBlLmwyIiwgCiAgICAgICAgcmVkdWN0aW9uID0gInVtYXAiLAogICAgICAgIGxhYmVsLnNpemUgPSAzLAogICAgICAgIHJlcGVsID0gVCwKICAgICAgICBsYWJlbCA9IFQpCgogbGlicmFyeShjbHVzdHJlZSkKIGNsdXN0cmVlKEFsbF9zYW1wbGVzX01lcmdlZCwgcHJlZml4ID0gIlNDVF9zbm5fcmVzLiIpCgoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMSIsIAogICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICBsYWJlbC5zaXplID0gMywKICAgICAgICByZXBlbCA9IFQsCiAgICAgICAgbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMSIsIAogICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICBsYWJlbC5zaXplID0gMywKICAgICAgICByZXBlbCA9IFQsCiAgICAgICAgbGFiZWwgPSBGKQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsIAogICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICBsYWJlbC5zaXplID0gMywKICAgICAgICByZXBlbCA9IFQsCiAgICAgICAgbGFiZWwgPSBULCBsYWJlbC5ib3ggPSBUKQoKRGltUGxvdChBbGxfc2FtcGxlc19NZXJnZWQsIGdyb3VwLmJ5ID0gInByZWRpY3RlZC5jZWxsdHlwZS5sMiIsIAogICAgICAgIHJlZHVjdGlvbiA9ICJ1bWFwIiwKICAgICAgICBsYWJlbC5zaXplID0gMywKICAgICAgICByZXBlbCA9IFQsCiAgICAgICAgbGFiZWwgPSBGKQoKCkRpbVBsb3QoQWxsX3NhbXBsZXNfTWVyZ2VkLCBncm91cC5ieSA9ICJwcmVkaWN0ZWQuY2VsbHR5cGUubDIiLCAKICAgICAgICByZWR1Y3Rpb24gPSAidW1hcCIsCiAgICAgICAgbGFiZWwuc2l6ZSA9IDMsCiAgICAgICAgcmVwZWwgPSBULAogICAgICAgIGxhYmVsID0gVCwgbGFiZWwuYm94ID0gVCkKCgoKIHRhYmxlKEFsbF9zYW1wbGVzX01lcmdlZCRwcmVkaWN0ZWQuY2VsbHR5cGUubDIsIEFsbF9zYW1wbGVzX01lcmdlZCRTQ1Rfc25uX3Jlcy4wLjkpCgoKYGBgCgoKIyAzLiBQZXJmb3JtIERFIGFuYWx5c2lzIHVzaW5nIHRoZSBGaW5kTWFya2VycyBvciBGaW5kQWxsTWFya2VycyBmdW5jdGlvbgpgYGB7ciBkYXRhMSwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9MTJ9CiMgRmluZCBtYXJrZXJzIGZvciBhbGwgY2x1c3RlcnMKQWxsX21hcmtlcnNfZGVmYXVsdCA8LSBGaW5kQWxsTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQpCgpBbGxfbWFya2Vyc19EZWZhdWx0X21pbl9kaWZmICA8LSBGaW5kQWxsTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4ucGN0ID0gMC4yNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZmMudGhyZXNob2xkID0gMC4yNSkKCkFsbF9tYXJrZXJzXzAuNV9taW5fZGlmZiA8LSBGaW5kQWxsTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4ucGN0ID0gMC4yNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZmMudGhyZXNob2xkID0gMC4yNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluLnBjdC5kaWZmPSAwLjUpCgoKUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzIDwtIEZpbmRNYXJrZXJzKEFsbF9zYW1wbGVzX01lcmdlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjEgPSBjKCJMMSIsICJMMiIsICJMMyIsICJMNCIsICJMNSIsICJMNiIsICJMNyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9ICJQQk1DIikKCiMgRW5zdXJlIEFsbF9tYXJrZXJzX2RlZmF1bHQgaXMgYSBkYXRhIGZyYW1lCkFsbF9tYXJrZXJzX2RlZmF1bHQgPC0gYXMuZGF0YS5mcmFtZShBbGxfbWFya2Vyc19kZWZhdWx0KQoKIyBSZXBlYXQgZm9yIHRoZSBvdGhlciBkYXRhIGZyYW1lcwpBbGxfbWFya2Vyc19EZWZhdWx0X21pbl9kaWZmIDwtIGFzLmRhdGEuZnJhbWUoQWxsX21hcmtlcnNfRGVmYXVsdF9taW5fZGlmZikKQWxsX21hcmtlcnNfMC41X21pbl9kaWZmIDwtIGFzLmRhdGEuZnJhbWUoQWxsX21hcmtlcnNfMC41X21pbl9kaWZmKQoKCiMgU2F2ZSBBbGxfbWFya2Vyc19kZWZhdWx0IHRvIENTVgp3cml0ZS5jc3YoQWxsX21hcmtlcnNfZGVmYXVsdCwgIkFsbF9tYXJrZXJzX2RlZmF1bHQuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCgojIFNhdmUgQWxsX21hcmtlcnNfRGVmYXVsdF9taW5fZGlmZiB0byBDU1YKd3JpdGUuY3N2KEFsbF9tYXJrZXJzX0RlZmF1bHRfbWluX2RpZmYsICJBbGxfbWFya2Vyc19EZWZhdWx0X21pbl9kaWZmLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQoKIyBTYXZlIEFsbF9tYXJrZXJzXzAuNV9taW5fZGlmZiB0byBDU1YKd3JpdGUuY3N2KEFsbF9tYXJrZXJzXzAuNV9taW5fZGlmZiwgIkFsbF9tYXJrZXJzXzAuNV9taW5fZGlmZi5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKCiMgQ29udmVydCB0byBkYXRhIGZyYW1lIGFuZCBhZGQgZ2VuZSBuYW1lcyBhcyBhIG5ldyBjb2x1bW4KUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzIDwtIGFzLmRhdGEuZnJhbWUoUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzKQpQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkZ2VuZSA8LSByb3duYW1lcyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMpCgojIFJlYXJyYW5naW5nIHRoZSBjb2x1bW5zIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkgKG9wdGlvbmFsKQpQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMgPC0gUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzWywgYygiZ2VuZSIsICJwX3ZhbCIsICJhdmdfbG9nMkZDIiwgInBjdC4xIiwgInBjdC4yIiwgInBfdmFsX2FkaiIpXQoKd3JpdGUuY3N2KFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscywgIlBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscy5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKCgoKCgoKYGBgCgpgYGB7ciBlbmhhbmNlZFYsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQoKRW5oYW5jZWRWb2xjYW5vKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyAsIAogICAgICAgICAgICAgICAgbGFiPXJvd25hbWVzKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyksCiAgICAgICAgICAgICAgICB4ID0iYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9InBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENlbGwgTGluZXMgdnMgUEJNQyBUIGNlbGxzIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLCAKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywgCiAgICAgICAgICAgICAgICBsYWJDb2wgPSAnYmxhY2snLAogICAgICAgICAgICAgICAgbGFiRmFjZSA9ICdib2xkJywKICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA1LjAsIAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC4yNSkKCkVuaGFuY2VkVm9sY2FubyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMgLCAKICAgICAgICAgICAgICAgIGxhYj1yb3duYW1lcyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMpLAogICAgICAgICAgICAgICAgeCA9ImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnRVBDQU0nLCdCQ0FUMScsJ0tJUjNETDInLAogICAgICAnRk9YTTEnLCdUV0lTVDEnLCdUTkZTRjknLCdDRDgwJywnQ0Q3JywnSUwxQicsICdUUkJWNy42JywnVFJCVjUuNCcsJ1RSQlYxMi40JyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENlbGwgTGluZXMgdnMgUEJNQyBUIGNlbGxzIiwKICAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEsIAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLCAKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxNCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgbGFiQ29sID0gJ2JsYWNrJywKICAgICAgICAgICAgICAgIGxhYkZhY2UgPSAnYm9sZCcsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gNS4wLCAKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNzUsCiAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2JsYWNrJykKCgpFbmhhbmNlZFZvbGNhbm8oUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzLCAKICAgICAgICAgICAgICAgIGxhYiA9IGlmZWxzZShQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkYXZnX2xvZzJGQyA+IDEgJiBQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkcF92YWxfYWRqIDwgMC4wNSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93bmFtZXMoUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiIpLCAgIyBMYWJlbCBvbmx5IHNpZ25pZmljYW50IGdlbmVzCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIlPDqXphcnkgQ2VsbCBMaW5lcyB2cyBQQk1DIFQgY2VsbHMiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEsIAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLCAKICAgICAgICAgICAgICAgIGxhYkNvbCA9ICdibGFjaycsCiAgICAgICAgICAgICAgICBsYWJGYWNlID0gJ2JvbGQnLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDUuMCwgCiAgICAgICAgICAgICAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjI1KQoKRW5oYW5jZWRWb2xjYW5vKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscywgCiAgICAgICAgICAgICAgICBsYWIgPSBpZmVsc2UoKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRhdmdfbG9nMkZDID4gMS41IHwgUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJGF2Z19sb2cyRkMgPCAtMS41KSAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRwX3ZhbF9hZGogPCAwLjA1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3duYW1lcyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIiksICAjIExhYmVsIG9ubHkgc2lnbmlmaWNhbnQgZ2VuZXMKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiU8OpemFyeSBDZWxsIExpbmVzIHZzIFBCTUMgVCBjZWxscyIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMSwgCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsIAogICAgICAgICAgICAgICAgbGFiQ29sID0gJ2JsYWNrJywKICAgICAgICAgICAgICAgIGxhYkZhY2UgPSAnYm9sZCcsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gNS4wLCAKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuMjUpCgoKQWxsX3NhbXBsZXNfTWVyZ2VkIDwtIFNldElkZW50KEFsbF9zYW1wbGVzX01lcmdlZCwgdmFsdWUgPSAiU0NUX3Nubl9yZXMuMC45IikKCkwyX1RoZXNob2xkcyA8LSBGaW5kTWFya2VycyhBbGxfc2FtcGxlc19NZXJnZWQsIGlkZW50LjEgPSAiNCIsIGlkZW50LjIgPSAiOSIsIG1pbi5wY3QgPSAwLjEwLCB0aHJlc2gudXNlID0gMC4yNSkKCkVuaGFuY2VkVm9sY2FubyhMMl9UaGVzaG9sZHMgLCAKICAgICAgICAgICAgICAgIGxhYj1yb3duYW1lcyhMMl9UaGVzaG9sZHMpLAogICAgICAgICAgICAgICAgeCA9ImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiNF92c185IiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLCAKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywgCiAgICAgICAgICAgICAgICBsYWJDb2wgPSAnYmxhY2snLAogICAgICAgICAgICAgICAgbGFiRmFjZSA9ICdib2xkJywKICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSAzLjAsIAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNzUpCgoKCmBgYAoKIyA0LiBFbnJpY2htZW50IEFuYWx5c2lzCmBgYHtyIGRhdGEyLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KCiNTdGVwLWJ5LVN0ZXAgR3VpZGUgZm9yIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMgKEdTRUEpIG9yIE92ZXItUmVwcmVzZW50YXRpb24gQW5hbHlzaXMgKE9SQSkKCiMgTG9hZCB0aGUgcGFja2FnZXMKbGlicmFyeShjbHVzdGVyUHJvZmlsZXIpCmxpYnJhcnkob3JnLkhzLmVnLmRiKQpsaWJyYXJ5KGVucmljaHBsb3QpCmxpYnJhcnkoUmVhY3RvbWVQQSkKCgojIEdldCB1cHJlZ3VsYXRlZCBnZW5lcwp1cHJlZ3VsYXRlZF9nZW5lcyA8LSByb3duYW1lcyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHNbUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJGF2Z19sb2cyRkMgPiAxLjUgJiBQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkcF92YWxfYWRqIDwgMC4wNSwgXSkKCiMgR2V0IGRvd25yZWd1bGF0ZWQgZ2VuZXMKZG93bnJlZ3VsYXRlZF9nZW5lcyA8LSByb3duYW1lcyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHNbUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJGF2Z19sb2cyRkMgPCAtMS41ICYgUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUsIF0pCgojR2VuZSBPbnRvbG9neSAoR08pIEVucmljaG1lbnQgQW5hbHlzaXMKIyBHTyBlbnJpY2htZW50IGZvciB1cHJlZ3VsYXRlZCBnZW5lcwpnb191cCA8LSBlbnJpY2hHTyhnZW5lID0gdXByZWd1bGF0ZWRfZ2VuZXMsIAogICAgICAgICAgICAgICAgICBPcmdEYiA9IG9yZy5Icy5lZy5kYiwgCiAgICAgICAgICAgICAgICAgIGtleVR5cGUgPSAiU1lNQk9MIiwgCiAgICAgICAgICAgICAgICAgIG9udCA9ICJCUCIsICAgIyAiQlAiIGZvciBCaW9sb2dpY2FsIFByb2Nlc3NlcywgIk1GIiBmb3IgTW9sZWN1bGFyIEZ1bmN0aW9uLCAiQ0MiIGZvciBDZWxsdWxhciBDb21wb25lbnQKICAgICAgICAgICAgICAgICAgcEFkanVzdE1ldGhvZCA9ICJCSCIsIAogICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBHTyBlbnJpY2htZW50IGZvciBkb3ducmVndWxhdGVkIGdlbmVzCmdvX2Rvd24gPC0gZW5yaWNoR08oZ2VuZSA9IGRvd25yZWd1bGF0ZWRfZ2VuZXMsIAogICAgICAgICAgICAgICAgICAgIE9yZ0RiID0gb3JnLkhzLmVnLmRiLCAKICAgICAgICAgICAgICAgICAgICBrZXlUeXBlID0gIlNZTUJPTCIsIAogICAgICAgICAgICAgICAgICAgIG9udCA9ICJCUCIsIAogICAgICAgICAgICAgICAgICAgIHBBZGp1c3RNZXRob2QgPSAiQkgiLCAKICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBWaXN1YWxpemUgdGhlIHRvcCBlbnJpY2hlZCBHTyB0ZXJtcwpkb3RwbG90KGdvX3VwLCBzaG93Q2F0ZWdvcnkgPSAyMCwgdGl0bGUgPSAiR08gRW5yaWNobWVudCBmb3IgVXByZWd1bGF0ZWQgR2VuZXMiKQpkb3RwbG90KGdvX2Rvd24sIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9ICJHTyBFbnJpY2htZW50IGZvciBEb3ducmVndWxhdGVkIEdlbmVzIikKCiNLRUdHIFBhdGh3YXkgRW5yaWNobWVudAojIENvbnZlcnQgZ2VuZSBzeW1ib2xzIHRvIEVudHJleiBJRHMgZm9yIEtFR0cgYW5hbHlzaXMKdXByZWd1bGF0ZWRfZW50cmV6IDwtIGJpdHIodXByZWd1bGF0ZWRfZ2VuZXMsIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKSRFTlRSRVpJRApkb3ducmVndWxhdGVkX2VudHJleiA8LSBiaXRyKGRvd25yZWd1bGF0ZWRfZ2VuZXMsIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKSRFTlRSRVpJRAoKIyBLRUdHIHBhdGh3YXkgZW5yaWNobWVudCBmb3IgdXByZWd1bGF0ZWQgZ2VuZXMKa2VnZ191cCA8LSBlbnJpY2hLRUdHKGdlbmUgPSB1cHJlZ3VsYXRlZF9lbnRyZXosIAogICAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAiaHNhIiwgCiAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBLRUdHIHBhdGh3YXkgZW5yaWNobWVudCBmb3IgZG93bnJlZ3VsYXRlZCBnZW5lcwprZWdnX2Rvd24gPC0gZW5yaWNoS0VHRyhnZW5lID0gZG93bnJlZ3VsYXRlZF9lbnRyZXosIAogICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJoc2EiLCAKICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgVmlzdWFsaXplIEtFR0cgcGF0aHdheSByZXN1bHRzCmRvdHBsb3Qoa2VnZ191cCwgc2hvd0NhdGVnb3J5ID0gMjAsIHRpdGxlID0gIktFR0cgUGF0aHdheSBFbnJpY2htZW50IGZvciBVcHJlZ3VsYXRlZCBHZW5lcyIpCmRvdHBsb3Qoa2VnZ19kb3duLCBzaG93Q2F0ZWdvcnkgPSAyMCwgdGl0bGUgPSAiS0VHRyBQYXRod2F5IEVucmljaG1lbnQgZm9yIERvd25yZWd1bGF0ZWQgR2VuZXMiKQoKI1JlYWN0b21lIFBhdGh3YXkgRW5yaWNobWVudAoKIyBSZWFjdG9tZSBwYXRod2F5IGVucmljaG1lbnQgZm9yIHVwcmVndWxhdGVkIGdlbmVzCnJlYWN0b21lX3VwIDwtIGVucmljaFBhdGh3YXkoZ2VuZSA9IHVwcmVndWxhdGVkX2VudHJleiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAiaHVtYW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBSZWFjdG9tZSBwYXRod2F5IGVucmljaG1lbnQgZm9yIGRvd25yZWd1bGF0ZWQgZ2VuZXMKcmVhY3RvbWVfZG93biA8LSBlbnJpY2hQYXRod2F5KGdlbmUgPSBkb3ducmVndWxhdGVkX2VudHJleiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJodW1hbiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgVmlzdWFsaXplIFJlYWN0b21lIHBhdGh3YXlzCmRvdHBsb3QocmVhY3RvbWVfdXAsIHNob3dDYXRlZ29yeSA9IDIwLCB0aXRsZSA9ICJSZWFjdG9tZSBQYXRod2F5IEVucmljaG1lbnQgZm9yIFVwcmVndWxhdGVkIEdlbmVzIikKZG90cGxvdChyZWFjdG9tZV9kb3duLCBzaG93Q2F0ZWdvcnkgPSAyMCwgdGl0bGUgPSAiUmVhY3RvbWUgUGF0aHdheSBFbnJpY2htZW50IGZvciBEb3ducmVndWxhdGVkIEdlbmVzIikKCgojIEdlbmUgU2V0IEVucmljaG1lbnQgQW5hbHlzaXMgKEdTRUEpIChPcHRpb25hbCkKIyBDcmVhdGUgYSByYW5rZWQgbGlzdCBvZiBnZW5lcwpnZW5lX2xpc3QgPC0gUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJGF2Z19sb2cyRkMKbmFtZXMoZ2VuZV9saXN0KSA8LSByb3duYW1lcyhQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMpCmdlbmVfbGlzdCA8LSBzb3J0KGdlbmVfbGlzdCwgZGVjcmVhc2luZyA9IFRSVUUpCgojIENvbnZlcnQgZ2VuZSBzeW1ib2xzIHRvIEVudHJleiBJRHMKZ2VuZV9kZiA8LSBiaXRyKG5hbWVzKGdlbmVfbGlzdCksIGZyb21UeXBlID0gIlNZTUJPTCIsIHRvVHlwZSA9ICJFTlRSRVpJRCIsIE9yZ0RiID0gb3JnLkhzLmVnLmRiKQoKIyBFbnN1cmUgdGhlIGdlbmUgbGlzdCBtYXRjaGVzIHRoZSBFbnRyZXogSURzCmdlbmVfbGlzdCA8LSBnZW5lX2xpc3RbbmFtZXMoZ2VuZV9saXN0KSAlaW4lIGdlbmVfZGYkU1lNQk9MXQoKIyBSZXBsYWNlIGdlbmUgc3ltYm9scyB3aXRoIEVudHJleiBJRHMKbmFtZXMoZ2VuZV9saXN0KSA8LSBnZW5lX2RmJEVOVFJFWklEW21hdGNoKG5hbWVzKGdlbmVfbGlzdCksIGdlbmVfZGYkU1lNQk9MKV0KCgojIFJ1biBHU0VBIHVzaW5nIEtFR0cKZ3NlYV9rZWdnIDwtIGdzZUtFR0coZ2VuZUxpc3QgPSBnZW5lX2xpc3QsIAogICAgICAgICAgICAgICAgICAgICBvcmdhbmlzbSA9ICJoc2EiLCAKICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgUGxvdCB0aGUgR1NFQSByZXN1bHRzCmdzZWFwbG90KGdzZWFfa2VnZywgZ2VuZVNldElEID0gMSwgdGl0bGUgPSAiVG9wIEtFR0cgUGF0aHdheSIpCgojIEV4dHJhY3QgdGhlIG5hbWUgb2YgdGhlIHRvcCBLRUdHIHBhdGh3YXkKdG9wX3BhdGh3YXkgPC0gZ3NlYV9rZWdnQHJlc3VsdFsxLCAiRGVzY3JpcHRpb24iXQoKIyBQbG90IEdTRUEgd2l0aCB0aGUgdG9wIHBhdGh3YXkncyBuYW1lIGFzIHRoZSB0aXRsZQpnc2VhcGxvdChnc2VhX2tlZ2csIGdlbmVTZXRJRCA9IDEsIHRpdGxlID0gdG9wX3BhdGh3YXkpCgoKYGBgCiMgNS4gQmFyIFBMT1QKYGBge3IgZGF0YTMsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojIEZpbHRlciBmb3Igc2lnbmlmaWNhbnQgcGF0aHdheXMKdG9wX2tlZ2dfdXAgPC0ga2VnZ191cEByZXN1bHRba2VnZ191cEByZXN1bHQkcC5hZGp1c3QgPCAwLjA1LCBdCnRvcF9rZWdnX2Rvd24gPC0ga2VnZ19kb3duQHJlc3VsdFtrZWdnX2Rvd25AcmVzdWx0JHAuYWRqdXN0IDwgMC4wNSwgXQoKIyBJZiB0aGVyZSBhcmUgbm90IGVub3VnaCBwYXRod2F5cywgY29uc2lkZXIgcmVsYXhpbmcgdGhlIHRocmVzaG9sZCBvciBjaGVja2luZyB0aGUgb3V0cHV0CnRvcF9rZWdnX3VwIDwtIHRvcF9rZWdnX3VwW29yZGVyKC10b3Bfa2VnZ191cCRwLmFkanVzdCksIF1bMToxMCwgXQp0b3Bfa2VnZ19kb3duIDwtIHRvcF9rZWdnX2Rvd25bb3JkZXIodG9wX2tlZ2dfZG93biRwLmFkanVzdCksIF1bMToxMCwgXQoKIyBDb21iaW5lIGludG8gb25lIGRhdGEgZnJhbWUKdG9wX3BhdGh3YXlzIDwtIHJiaW5kKAogIGRhdGEuZnJhbWUoUGF0aHdheSA9IHRvcF9rZWdnX3VwJERlc2NyaXB0aW9uLCBwLmFkanVzdCA9IHRvcF9rZWdnX3VwJHAuYWRqdXN0LCBEaXJlY3Rpb24gPSAiVXByZWd1bGF0ZWQiKSwKICBkYXRhLmZyYW1lKFBhdGh3YXkgPSB0b3Bfa2VnZ19kb3duJERlc2NyaXB0aW9uLCBwLmFkanVzdCA9IHRvcF9rZWdnX2Rvd24kcC5hZGp1c3QsIERpcmVjdGlvbiA9ICJEb3ducmVndWxhdGVkIikKKQoKIyBDb252ZXJ0IHAuYWRqdXN0IHRvIC1sb2cxMChwLmFkanVzdCkgZm9yIHZpc3VhbGl6YXRpb24KdG9wX3BhdGh3YXlzJG5lZ19sb2cxMF9wIDwtIC1sb2cxMCh0b3BfcGF0aHdheXMkcC5hZGp1c3QpCgojIENyZWF0ZSB0aGUgYmFycGxvdApnZ3Bsb3QodG9wX3BhdGh3YXlzLCBhZXMoeCA9IHJlb3JkZXIoUGF0aHdheSwgbmVnX2xvZzEwX3ApLCB5ID0gbmVnX2xvZzEwX3AsIGZpbGwgPSBEaXJlY3Rpb24pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIlVwcmVndWxhdGVkIiA9ICJyZWQiLCAiRG93bnJlZ3VsYXRlZCIgPSAiYmx1ZSIpKSArCiAgY29vcmRfZmxpcCgpICsgICMgRmxpcCB0aGUgY29vcmRpbmF0ZXMgZm9yIGJldHRlciByZWFkYWJpbGl0eQogIGxhYnModGl0bGUgPSAiVG9wIFNpZ25pZmljYW50IFBhdGh3YXlzIiwKICAgICAgIHggPSAiUGF0aHdheXMiLAogICAgICAgeSA9ICItTG9nMTAgQWRqdXN0ZWQgUC1WYWx1ZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKCiMgTG9hZCBuZWNlc3NhcnkgbGlicmFyeQpsaWJyYXJ5KGdncGxvdDIpCgojIENyZWF0ZSB0aGUgYmFycGxvdApnZ3Bsb3QodG9wX3BhdGh3YXlzLCBhZXMoeCA9IFBhdGh3YXksIHkgPSBuZWdfbG9nMTBfcCwgZmlsbCA9IERpcmVjdGlvbikpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiaWRlbnRpdHkiKSArICAjIFVzZSBwb3NpdGlvbiA9ICJpZGVudGl0eSIKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJVcHJlZ3VsYXRlZCIgPSAicmVkIiwgIkRvd25yZWd1bGF0ZWQiID0gImJsdWUiKSkgKwogIGNvb3JkX2ZsaXAoKSArICAjIEZsaXAgdGhlIGNvb3JkaW5hdGVzIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkKICBsYWJzKHRpdGxlID0gIlRvcCBTaWduaWZpY2FudCBQYXRod2F5cyIsCiAgICAgICB4ID0gIlBhdGh3YXlzIiwKICAgICAgIHkgPSAiLUxvZzEwIEFkanVzdGVkIFAtVmFsdWUiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpCgoKCmBgYAoKIyA1LiBwZXJmb3JtIGdlbmUgZW5yaWNobWVudCBhbmFseXNpcyBhbmQgaWRlbnRpZnkgcGF0aHdheXMKYGBge3IgZGF0YTQsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEyfQojIExvYWQgdGhlIHBhY2thZ2VzCmxpYnJhcnkoY2x1c3RlclByb2ZpbGVyKQpsaWJyYXJ5KG9yZy5Icy5lZy5kYikKCiMgQXNzdW1pbmcgYHNpZ25pZmljYW50X2dlbmVzYCBpcyB5b3VyIGxpc3Qgb2Ygc2lnbmlmaWNhbnQgZ2VuZSBzeW1ib2xzCnNpZ25pZmljYW50X2dlbmVzIDwtIHJvd25hbWVzKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxsc1sKICAgIChQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkYXZnX2xvZzJGQyA+IDEuNSB8IAogICAgIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRhdmdfbG9nMkZDIDwgLTEuNSkgJiAKICAgIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRwX3ZhbF9hZGogPCAwLjA1LCBdKQoKZW50cmV6X2lkcyA8LSBiaXRyKHNpZ25pZmljYW50X2dlbmVzLCBmcm9tVHlwZSA9ICJTWU1CT0wiLCAKICAgICAgICAgICAgICAgICAgIHRvVHlwZSA9ICJFTlRSRVpJRCIsIAogICAgICAgICAgICAgICAgICAgT3JnRGIgPSBvcmcuSHMuZWcuZGIpCgprZWdnX3Jlc3VsdHMgPC0gZW5yaWNoS0VHRyhnZW5lID0gZW50cmV6X2lkcyRFTlRSRVpJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnYW5pc20gPSAnaHNhJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcHZhbHVlQ3V0b2ZmID0gMC4wNSkKCiMgVmlldyByZXN1bHRzCmhlYWQoa2VnZ19yZXN1bHRzKQoKCmdvX3Jlc3VsdHMgPC0gZW5yaWNoR08oZ2VuZSA9IGVudHJlel9pZHMkRU5UUkVaSUQsCiAgICAgICAgICAgICAgICAgICAgICAgT3JnRGIgPSBvcmcuSHMuZWcuZGIsCiAgICAgICAgICAgICAgICAgICAgICAgb250ID0gIkJQIiwgIyBCaW9sb2dpY2FsIFByb2Nlc3MKICAgICAgICAgICAgICAgICAgICAgICBwdmFsdWVDdXRvZmYgPSAwLjA1KQoKIyBWaWV3IHJlc3VsdHMKaGVhZChnb19yZXN1bHRzKQoKIyBEb3QgcGxvdCBmb3IgS0VHRyByZXN1bHRzCmRvdHBsb3Qoa2VnZ19yZXN1bHRzLCBzaG93Q2F0ZWdvcnk9MTApICsgZ2d0aXRsZSgiS0VHRyBQYXRod2F5IEVucmljaG1lbnQiKQoKIyBEb3QgcGxvdCBmb3IgR08gcmVzdWx0cwpkb3RwbG90KGdvX3Jlc3VsdHMsIHNob3dDYXRlZ29yeT0xMCkgKyBnZ3RpdGxlKCJHTyBCaW9sb2dpY2FsIFByb2Nlc3MgRW5yaWNobWVudCIpCgoKYGBgCgoKIyA1LiBnZ3Bsb3QyIGZvciBWb2xjYW5vCmBgYHtyIGRhdGE1LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncmVwZWwpCgojIElkZW50aWZ5IHRvcCBhbmQgYm90dG9tIGdlbmVzCnRvcF9nZW5lcyA8LSBQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHNbUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUgJiBQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkYXZnX2xvZzJGQyA+IDIsIF0KYm90dG9tX2dlbmVzIDwtIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxsc1tQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkcF92YWxfYWRqIDwgMC4wNSAmIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRhdmdfbG9nMkZDIDwgLTEuNSwgXQoKIyBDcmVhdGUgYSBuZXcgY29sdW1uIGZvciBjb2xvciBiYXNlZCBvbiBzaWduaWZpY2FuY2UKUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJGNvbG9yIDwtIGlmZWxzZShQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkYXZnX2xvZzJGQyA+IDIsICJUb3AgR2VuZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkYXZnX2xvZzJGQyA8IC0xLjUsICJCb3R0b20gR2VuZSIsICJOZXV0cmFsIikpCgojIENyZWF0ZSBhIHZvbGNhbm8gcGxvdApnZ3Bsb3QoUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzLCBhZXMoeCA9IGF2Z19sb2cyRkMsIHkgPSAtbG9nMTAocF92YWxfYWRqKSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvciA9IGNvbG9yKSwgYWxwaGEgPSAwLjcsIHNpemUgPSAyKSArCiAgCiAgIyBBZGQgbGFiZWxzIGZvciB0b3AgYW5kIGJvdHRvbSBnZW5lcwogIGdlb21fdGV4dF9yZXBlbChkYXRhID0gdG9wX2dlbmVzLCBhZXMobGFiZWwgPSBnZW5lKSwgY29sb3IgPSAiYmxhY2siLCB2anVzdCA9IDEsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgZ2VvbV90ZXh0X3JlcGVsKGRhdGEgPSBib3R0b21fZ2VuZXMsIGFlcyhsYWJlbCA9IGdlbmUpLCBjb2xvciA9ICJibGFjayIsIHZqdXN0ID0gLTEsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgCiAgIyBDdXN0b21pemUgbGFiZWxzIGFuZCB0aXRsZQogIGxhYnModGl0bGUgPSAiVm9sY2FubyBQbG90IiwKICAgICAgIHggPSAibG9nMiBGb2xkIENoYW5nZSIsCiAgICAgICB5ID0gIi1sb2cxMChwLXZhbHVlKSIpICsKICAKICAjIEFkZCBzaWduaWZpY2FuY2UgdGhyZXNob2xkIGxpbmVzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLWxvZzEwKDAuMDUpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKC0xLjUsIDIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsKICAKICAjIFNldCBjb2xvcnMgZm9yIHRvcCBhbmQgYm90dG9tIGdlbmVzCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIlRvcCBHZW5lIiA9ICJyZWQiLCAiQm90dG9tIEdlbmUiID0gImJsdWUiLCAiTmV1dHJhbCIgPSAiZGFya2dyZXkiKSkgKwogIAogICMgQ3VzdG9taXplIHRoZW1lIGlmIG5lZWRlZAogIHRoZW1lX21pbmltYWwoKQoKCgoKCmBgYAoKCmBgYHtyIGRhdGE2LCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xMn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdncmVwZWwpCgojIElkZW50aWZ5IHRvcCBhbmQgYm90dG9tIGdlbmVzIGJhc2VkIG9uIGNyaXRlcmlhCnRvcF9nZW5lcyA8LSBQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHNbUGF0aWVudF9jZWxsX2xpbmVzX3ZzX1BCTUNfVGNlbGxzJHBfdmFsX2FkaiA8IDAuMDUgJiBQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkYXZnX2xvZzJGQyA+IDIsIF0KYm90dG9tX2dlbmVzIDwtIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxsc1tQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkcF92YWxfYWRqIDwgMC4wNSAmIFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRhdmdfbG9nMkZDIDwgLTEuNSwgXQoKIyBTb3J0IGFuZCBzZWxlY3QgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgdG9wIGFuZCBib3R0b20gZ2VuZXMKdG9wX2dlbmVzIDwtIHRvcF9nZW5lc1tvcmRlcih0b3BfZ2VuZXMkcF92YWxfYWRqKSwgXVsxOjEwMCwgXSAgIyBUb3AgMTAwIHNpZ25pZmljYW50IHVwcmVndWxhdGVkIGdlbmVzCmJvdHRvbV9nZW5lcyA8LSBib3R0b21fZ2VuZXNbb3JkZXIoYm90dG9tX2dlbmVzJHBfdmFsX2FkaiksIF1bMToxMDAsIF0gICMgVG9wIDEwMCBzaWduaWZpY2FudCBkb3ducmVndWxhdGVkIGdlbmVzCgojIENyZWF0ZSBhIG5ldyBjb2x1bW4gZm9yIGNvbG9yIGJhc2VkIG9uIHNpZ25pZmljYW5jZQpQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMkY29sb3IgPC0gaWZlbHNlKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRhdmdfbG9nMkZDID4gMiwgIlRvcCBHZW5lIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKFBhdGllbnRfY2VsbF9saW5lc192c19QQk1DX1RjZWxscyRhdmdfbG9nMkZDIDwgLTEuNSwgIkJvdHRvbSBHZW5lIiwgIk5ldXRyYWwiKSkKCiMgQ3JlYXRlIGEgdm9sY2FubyBwbG90CmdncGxvdChQYXRpZW50X2NlbGxfbGluZXNfdnNfUEJNQ19UY2VsbHMsIGFlcyh4ID0gYXZnX2xvZzJGQywgeSA9IC1sb2cxMChwX3ZhbF9hZGopKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yID0gY29sb3IpLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDIpICsKICAKICAjIEFkZCBsYWJlbHMgb25seSBmb3IgdG9wIDEwMCBhbmQgYm90dG9tIDEwMCBnZW5lcwogIGdlb21fdGV4dF9yZXBlbChkYXRhID0gdG9wX2dlbmVzLCBhZXMobGFiZWwgPSBnZW5lKSwgY29sb3IgPSAiYmxhY2siLCB2anVzdCA9IDEsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgZ2VvbV90ZXh0X3JlcGVsKGRhdGEgPSBib3R0b21fZ2VuZXMsIGFlcyhsYWJlbCA9IGdlbmUpLCBjb2xvciA9ICJibGFjayIsIHZqdXN0ID0gLTEsIGZvbnRmYWNlID0gImJvbGQiKSArCiAgCiAgIyBDdXN0b21pemUgbGFiZWxzIGFuZCB0aXRsZQogIGxhYnModGl0bGUgPSAiVm9sY2FubyBQbG90IiwKICAgICAgIHggPSAibG9nMiBGb2xkIENoYW5nZSIsCiAgICAgICB5ID0gIi1sb2cxMChwLXZhbHVlKSIpICsKICAKICAjIEFkZCBzaWduaWZpY2FuY2UgdGhyZXNob2xkIGxpbmVzCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gLWxvZzEwKDAuMDUpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBjKC0xLjUsIDIpLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICJibGFjayIpICsKICAKICAjIFNldCBjb2xvcnMgZm9yIHRvcCBhbmQgYm90dG9tIGdlbmVzCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoIlRvcCBHZW5lIiA9ICJyZWQiLCAiQm90dG9tIEdlbmUiID0gImJsdWUiLCAiTmV1dHJhbCIgPSAiZGFya2dyZXkiKSkgKwogIAogICMgQ3VzdG9taXplIHRoZW1lIGlmIG5lZWRlZAogIHRoZW1lX21pbmltYWwoKQoKCgoKCmBgYAoK