1. Load Libraries

2. Load Data

2.1 Load CSV Files with Mean Expression


# Load the CSV files with mean expression data
markers_mast_SCT <- read.csv("../0-robj/1-MAST_with_SCT_batch_patient_cellline_as_Covariate_with_meanExpression.csv", row.names = 1)

markers_LR_SCT <- read.csv("../0-robj/1-LR_with_SCT_batch_patient_cellline_as_Covariate_with_meanExpression.csv", row.names = 1)

markers_negbinom_SCT <- read.csv("../0-robj/1-negbinom_with_SCT_batch_patient_cellline_as_Covariate_with_meanExpression.csv", row.names = 1)

3. Summarize Results

3.1 Summary Function

summarize_markers <- function(markers) {
  num_pval0 <- sum(markers$p_val_adj == 0)
  num_pval1 <- sum(markers$p_val_adj == 1)
  num_significant <- sum(markers$p_val_adj < 0.05)
  num_upregulated <- sum(markers$avg_log2FC > 1)
  num_downregulated <- sum(markers$avg_log2FC < -1)
  
  cat("Number of genes with p_val_adj = 0:", num_pval0, "\n")
  cat("Number of genes with p_val_adj = 1:", num_pval1, "\n")
  cat("Number of significant genes (p_val_adj < 0.05):", num_significant, "\n")
  cat("Number of upregulated genes (avg_log2FC > 1):", num_upregulated, "\n")
  cat("Number of downregulated genes (avg_log2FC < 1):", num_downregulated, "\n")
}

3.2 Summarize Markers1 (MAST with SCT Assay)

cat("Markers1 Summary (MAST with Batch Correction):\n")
Markers1 Summary (MAST with Batch Correction):
summarize_markers(markers_mast_SCT)
Number of genes with p_val_adj = 0: 72 
Number of genes with p_val_adj = 1: 8299 
Number of significant genes (p_val_adj < 0.05): 5084 
Number of upregulated genes (avg_log2FC > 1): 9917 
Number of downregulated genes (avg_log2FC < 1): 789 

3.3 Summary for Marker2 (LR with SCT Assay)

cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(markers_LR_SCT)
Number of genes with p_val_adj = 0: 1 
Number of genes with p_val_adj = 1: 25321 
Number of significant genes (p_val_adj < 0.05): 587 
Number of upregulated genes (avg_log2FC > 1): 15048 
Number of downregulated genes (avg_log2FC < 1): 2281 

3.4 Summary for Markers3 (negbinom with RNA Assay)

cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(markers_negbinom_SCT)
Number of genes with p_val_adj = 0: 60 
Number of genes with p_val_adj = 1: 21805 
Number of significant genes (p_val_adj < 0.05): 3653 
Number of upregulated genes (avg_log2FC > 1): 15047 
Number of downregulated genes (avg_log2FC < 1): 2262 

4. Volcano Plots for All Genes

4.1 Volcano Plot for MAST with SCT Assay

EnhancedVolcano(markers_mast_SCT,
                lab = markers_mast_SCT$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "MAST with SCT assay (All Genes)",
                pCutoff = 0.05,
                FCcutoff = 0.5)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.2 Volcano Plot for MAST with SCT Assay

EnhancedVolcano(markers_mast_SCT, 
                lab = markers_mast_SCT$gene,
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3','CD74','IL4','IL13', 'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)'),
                title = "Sézary CD4 T cells vs Normal CD4 T cells",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.0001,
                FCcutoff = 0.5, 
                pointSize = 3.0,
                labSize = 3.0,
                boxedLabels = TRUE,
                colAlpha = 0.5,
                legendPosition = 'right',
                legendLabSize = 10,
                legendIconSize = 4.0,
                drawConnectors = TRUE,
                widthConnectors = 0.5,
                colConnectors = 'black',
                arrowheads = FALSE,
                max.overlaps = 30)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.3 Volcano Plot for LR with SCT Assay

EnhancedVolcano(markers_LR_SCT,
                lab = markers_LR_SCT$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "LR with SCT Assay (All Genes)",
                pCutoff = 0.05,
                FCcutoff = 0.5)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.4 Volcano Plot for markers_LR_SCT

EnhancedVolcano(markers_LR_SCT, 
                lab = markers_LR_SCT$gene,
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3','CD74','IL4','IL13', 'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)'),
                title = "Sézary CD4 T cells vs Normal CD4 T cells",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 0.5, 
                pointSize = 3.0,
                labSize = 3.0,
                boxedLabels = TRUE,
                colAlpha = 0.5,
                legendPosition = 'right',
                legendLabSize = 10,
                legendIconSize = 4.0,
                drawConnectors = TRUE,
                widthConnectors = 0.5,
                colConnectors = 'black',
                arrowheads = FALSE,
                max.overlaps = 30)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.5 Volcano Plot for negbinom with SCT Assay

EnhancedVolcano(markers_negbinom_SCT,
                lab = markers_negbinom_SCT$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "LR with SCT Assay (All Genes)",
                pCutoff = 0.05,
                FCcutoff = 0.5)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

4.6 Volcano Plot for markers_negbinom_SCT

EnhancedVolcano(markers_negbinom_SCT, 
                lab = markers_negbinom_SCT$gene,
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3','CD74','IL4','IL13', 'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)'),
                title = "Sézary CD4 T cells vs Normal CD4 T cells",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 0.5, 
                pointSize = 3.0,
                labSize = 3.0,
                boxedLabels = TRUE,
                colAlpha = 0.5,
                legendPosition = 'right',
                legendLabSize = 10,
                legendIconSize = 4.0,
                drawConnectors = TRUE,
                widthConnectors = 0.5,
                colConnectors = 'black',
                arrowheads = FALSE,
                max.overlaps = 30)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

5. Filter and Summarize Results

5.1 Apply Expression Filter First

# Apply the expression filter first
markers_mast_SCT <- markers_mast_SCT %>%
  filter(!(mean_expr_group1 < 0.2 & mean_expr_group2 < 0.2))

markers_LR_SCT <- markers_LR_SCT %>%
  filter(!(mean_expr_group1 < 0.2 & mean_expr_group2 < 0.2))

markers_negbinom_SCT <- markers_negbinom_SCT %>%
  filter(!(mean_expr_group1 < 0.2 & mean_expr_group2 < 0.2))

5.2 Summary Function

summarize_markers <- function(markers) {
  num_pval0 <- sum(markers$p_val_adj == 0)
  num_pval1 <- sum(markers$p_val_adj == 1)
  num_significant <- sum(markers$p_val_adj < 0.05)
  num_upregulated <- sum(markers$avg_log2FC > 1)
  num_downregulated <- sum(markers$avg_log2FC < -1)
  
  cat("Number of genes with p_val_adj = 0:", num_pval0, "\n")
  cat("Number of genes with p_val_adj = 1:", num_pval1, "\n")
  cat("Number of significant genes (p_val_adj < 0.05):", num_significant, "\n")
  cat("Number of upregulated genes (avg_log2FC > 1):", num_upregulated, "\n")
  cat("Number of downregulated genes (avg_log2FC < 1):", num_downregulated, "\n")
}

5.3 Summarize Markers1 (MAST with SCT Assay)

cat("Markers1 Summary (MAST with Batch Correction):\n")
Markers1 Summary (MAST with Batch Correction):
summarize_markers(markers_mast_SCT)
Number of genes with p_val_adj = 0: 74 
Number of genes with p_val_adj = 1: 2209 
Number of significant genes (p_val_adj < 0.05): 3042 
Number of upregulated genes (avg_log2FC > 1): 4514 
Number of downregulated genes (avg_log2FC < 1): 125 

5.4 Summary for Markers3 (LR with SCT Assay)

cat("Markers3 Summary (LR with Batch Correction):\n")
Markers3 Summary (LR with Batch Correction):
summarize_markers(markers_LR_SCT)
Number of genes with p_val_adj = 0: 0 
Number of genes with p_val_adj = 1: 5214 
Number of significant genes (p_val_adj < 0.05): 358 
Number of upregulated genes (avg_log2FC > 1): 4514 
Number of downregulated genes (avg_log2FC < 1): 125 

5.5 Summary for Markers3 (negbinom with SCT Assay)

cat("Markers3 Summary (negbinom with Batch Correction):\n")
Markers3 Summary (negbinom with Batch Correction):
summarize_markers(markers_negbinom_SCT)
Number of genes with p_val_adj = 0: 59 
Number of genes with p_val_adj = 1: 3075 
Number of significant genes (p_val_adj < 0.05): 2340 
Number of upregulated genes (avg_log2FC > 1): 4514 
Number of downregulated genes (avg_log2FC < 1): 125 

5.6 Apply Additional Filters for Statistical Significance and Fold Change

# Define filtering criteria
p_val_threshold <- 0.05
logfc_threshold <- 1

# Apply additional filters for markers_mast_batch
filtered_markers_mast_SCT <- markers_mast_SCT %>%
  filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)


filtered_markers_LR_SCT <- markers_LR_SCT %>%
  filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)

filtered_markers_negbinom_SCT <- markers_negbinom_SCT %>%
  filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)


# Save filtered results
  write.csv(filtered_markers_mast_SCT, file = "../0-robj/SCT_MAST_LR_negbinom/1-MAST_with_SCT_batch_cellline_as_Covariate_with_meanExpression_filtered.csv", row.names = TRUE)
write.csv(filtered_markers_LR_SCT, file = "../0-robj/SCT_MAST_LR_negbinom/1-LR_with_SCT_batch_cellline_as_Covariate_with_meanExpression_filtered.csv", row.names = TRUE)

write.csv(filtered_markers_negbinom_SCT, file = "../0-robj/SCT_MAST_LR_negbinom/1-negbinom_with_SCT_batch_cellline_as_Covariate_with_meanExpression_filtered.csv", row.names = TRUE)

5.7 Summary Function

summarize_markers <- function(markers) {
  num_pval0 <- sum(markers$p_val_adj == 0)
  num_pval1 <- sum(markers$p_val_adj == 1)
  num_significant <- sum(markers$p_val_adj < 0.05)
  num_upregulated <- sum(markers$avg_log2FC > 1)
  num_downregulated <- sum(markers$avg_log2FC < -1)
  
  cat("Number of genes with p_val_adj = 0:", num_pval0, "\n")
  cat("Number of genes with p_val_adj = 1:", num_pval1, "\n")
  cat("Number of significant genes (p_val_adj < 0.05):", num_significant, "\n")
  cat("Number of upregulated genes (avg_log2FC > 1):", num_upregulated, "\n")
  cat("Number of downregulated genes (avg_log2FC < -1):", num_downregulated, "\n")
}

5.8 Summarize Markers1 (MAST with Batch Correction)

cat("Markers1 Summary (markers_mast_SCT):\n")
Markers1 Summary (markers_mast_SCT):
summarize_markers(filtered_markers_mast_SCT)
Number of genes with p_val_adj = 0: 35 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 2077 
Number of upregulated genes (avg_log2FC > 1): 1956 
Number of downregulated genes (avg_log2FC < -1): 121 

5.9 Summarize Markers2 (markers_LR_SCT)

cat("Markers2 Summary (markers_LR_SCT):\n")
Markers2 Summary (markers_LR_SCT):
summarize_markers(filtered_markers_LR_SCT)
Number of genes with p_val_adj = 0: 0 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 235 
Number of upregulated genes (avg_log2FC > 1): 198 
Number of downregulated genes (avg_log2FC < -1): 37 

5.10 Summarize Markers2 (markers_negbinom_SCT)

cat("Markers2 Summary (markers_negbinom_SCT):\n")
Markers2 Summary (markers_negbinom_SCT):
summarize_markers(filtered_markers_negbinom_SCT)
Number of genes with p_val_adj = 0: 23 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 1708 
Number of upregulated genes (avg_log2FC > 1): 1619 
Number of downregulated genes (avg_log2FC < -1): 89 

6. Visualization of Filtered Results

6.1 Volcano Plot for markers_mast_SCT

EnhancedVolcano(filtered_markers_mast_SCT,
                lab = filtered_markers_mast_SCT$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "MAST with SCT assay (All Genes)",
                pCutoff = 0.05,
                FCcutoff = 1)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

6.2 Volcano Plot for MAST with SCT Assay

EnhancedVolcano(filtered_markers_mast_SCT, 
                lab = filtered_markers_mast_SCT$gene,
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3', 'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)'),
                title = "Sézary CD4 T cells vs Normal CD4 T cells",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.0001,
                FCcutoff = 1, 
                pointSize = 3.0,
                labSize = 3.0,
                boxedLabels = TRUE,
                colAlpha = 0.5,
                legendPosition = 'right',
                legendLabSize = 10,
                legendIconSize = 4.0,
                drawConnectors = TRUE,
                widthConnectors = 0.5,
                colConnectors = 'black',
                arrowheads = FALSE,
                max.overlaps = 30)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

6.3 Volcano Plot for LR with SCT Assay

EnhancedVolcano(filtered_markers_LR_SCT,
                lab = filtered_markers_LR_SCT$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "LR with SCT Assay (All Genes)",
                pCutoff = 0.05,
                FCcutoff = 1.0)

6.4 Volcano Plot for LR with SCT Assay

EnhancedVolcano(filtered_markers_LR_SCT, 
                lab = filtered_markers_LR_SCT$gene,
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3', 'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)'),
                title = "Sézary CD4 T cells vs Normal CD4 T cells",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1, 
                pointSize = 3.0,
                labSize = 3.0,
                boxedLabels = TRUE,
                colAlpha = 0.5,
                legendPosition = 'right',
                legendLabSize = 10,
                legendIconSize = 4.0,
                drawConnectors = TRUE,
                widthConnectors = 0.5,
                colConnectors = 'black',
                arrowheads = FALSE,
                max.overlaps = 30)

6.5 Volcano Plot for negbinom with SCT Assay

EnhancedVolcano(filtered_markers_negbinom_SCT,
                lab = filtered_markers_negbinom_SCT$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "LR with SCT Assay (All Genes)",
                pCutoff = 0.05,
                FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

6.6 Volcano Plot for negbinom with SCT Assay

EnhancedVolcano(filtered_markers_negbinom_SCT, 
                lab = filtered_markers_negbinom_SCT$gene,
                x = "avg_log2FC", 
                y = "p_val_adj",
                selectLab = c('KIR3DL2', 'TOX', 'TWIST1', 'CD52', 'CCR4', 'IL2RA', 'CD7', 'DPP4', 'CCR7', 'GATA3', 'FOXP3', 'DNM3', 'NCR1', 'CD70', 'AIRE', 'PDCD1 (PD-1)', 'CD274 (PD-L1)'),
                title = "Sézary CD4 T cells vs Normal CD4 T cells",
                xlab = bquote(~Log[2]~ 'fold change'),
                pCutoff = 0.05,
                FCcutoff = 1, 
                pointSize = 3.0,
                labSize = 3.0,
                boxedLabels = TRUE,
                colAlpha = 0.5,
                legendPosition = 'right',
                legendLabSize = 10,
                legendIconSize = 4.0,
                drawConnectors = TRUE,
                widthConnectors = 0.5,
                colConnectors = 'black',
                arrowheads = FALSE,
                max.overlaps = 30)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

LS0tCnRpdGxlOiAiRmlsdGVyaW5nIGFuZCBWaXN1YWxpemF0aW9uKE1BU1QsIExSIGFuZCBuZWdiaW5vbSBvbiBTQ1QpIgphdXRob3I6IE5hc2lyIE1haG1vb2QgQWJiYXNpCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQotLS0KCiMgMS4gTG9hZCBMaWJyYXJpZXMKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCmxpYnJhcnkocGhlYXRtYXApCmxpYnJhcnkodGliYmxlKQpgYGAKCiMgMi4gTG9hZCBEYXRhCiMjIDIuMSBMb2FkIENTViBGaWxlcyB3aXRoIE1lYW4gRXhwcmVzc2lvbgpgYGB7cn0KCiMgTG9hZCB0aGUgQ1NWIGZpbGVzIHdpdGggbWVhbiBleHByZXNzaW9uIGRhdGEKbWFya2Vyc19tYXN0X1NDVCA8LSByZWFkLmNzdigiLi4vMC1yb2JqLzEtTUFTVF93aXRoX1NDVF9iYXRjaF9wYXRpZW50X2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCgptYXJrZXJzX0xSX1NDVCA8LSByZWFkLmNzdigiLi4vMC1yb2JqLzEtTFJfd2l0aF9TQ1RfYmF0Y2hfcGF0aWVudF9jZWxsbGluZV9hc19Db3ZhcmlhdGVfd2l0aF9tZWFuRXhwcmVzc2lvbi5jc3YiLCByb3cubmFtZXMgPSAxKQoKbWFya2Vyc19uZWdiaW5vbV9TQ1QgPC0gcmVhZC5jc3YoIi4uLzAtcm9iai8xLW5lZ2Jpbm9tX3dpdGhfU0NUX2JhdGNoX3BhdGllbnRfY2VsbGxpbmVfYXNfQ292YXJpYXRlX3dpdGhfbWVhbkV4cHJlc3Npb24uY3N2Iiwgcm93Lm5hbWVzID0gMSkKCmBgYAoKIyAzLiBTdW1tYXJpemUgUmVzdWx0cwojIyAzLjEgU3VtbWFyeSBGdW5jdGlvbgpgYGB7cn0Kc3VtbWFyaXplX21hcmtlcnMgPC0gZnVuY3Rpb24obWFya2VycykgewogIG51bV9wdmFsMCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMCkKICBudW1fcHZhbDEgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDEpCiAgbnVtX3NpZ25pZmljYW50IDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA8IDAuMDUpCiAgbnVtX3VwcmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPiAxKQogIG51bV9kb3ducmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPCAtMSkKICAKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDA6IiwgbnVtX3B2YWwwLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMToiLCBudW1fcHZhbDEsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2Ygc2lnbmlmaWNhbnQgZ2VuZXMgKHBfdmFsX2FkaiA8IDAuMDUpOiIsIG51bV9zaWduaWZpY2FudCwgIlxuIikKICBjYXQoIk51bWJlciBvZiB1cHJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA+IDEpOiIsIG51bV91cHJlZ3VsYXRlZCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBkb3ducmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDIDwgMSk6IiwgbnVtX2Rvd25yZWd1bGF0ZWQsICJcbiIpCn0KCmBgYAoKIyMgMy4yIFN1bW1hcml6ZSBNYXJrZXJzMSAoTUFTVCB3aXRoIFNDVCBBc3NheSkKYGBge3J9CmNhdCgiTWFya2VyczEgU3VtbWFyeSAoTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24pOlxuIikKc3VtbWFyaXplX21hcmtlcnMobWFya2Vyc19tYXN0X1NDVCkKCmBgYAoKCgojIyAzLjMgU3VtbWFyeSBmb3IgTWFya2VyMiAoTFIgd2l0aCBTQ1QgQXNzYXkpCmBgYHtyfQpjYXQoIk1hcmtlcnMzIFN1bW1hcnkgKE1BU1Qgd2l0aG91dCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfTFJfU0NUKQpgYGAKIyMgMy40IFN1bW1hcnkgZm9yIE1hcmtlcnMzIChuZWdiaW5vbSB3aXRoIFJOQSBBc3NheSkKYGBge3J9CmNhdCgiTWFya2VyczMgU3VtbWFyeSAoTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24pOlxuIikKc3VtbWFyaXplX21hcmtlcnMobWFya2Vyc19uZWdiaW5vbV9TQ1QpCmBgYAoKCiMgNC4gVm9sY2FubyBQbG90cyBmb3IgQWxsIEdlbmVzCiMjIDQuMSBWb2xjYW5vIFBsb3QgZm9yIE1BU1Qgd2l0aCBTQ1QgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfbWFzdF9TQ1QsCiAgICAgICAgICAgICAgICBsYWIgPSBtYXJrZXJzX21hc3RfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTUFTVCB3aXRoIFNDVCBhc3NheSAoQWxsIEdlbmVzKSIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMC41KQpgYGAKCiMjIDQuMiBWb2xjYW5vIFBsb3QgZm9yIE1BU1Qgd2l0aCBTQ1QgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfbWFzdF9TQ1QsIAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc19tYXN0X1NDVCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwgCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICBzZWxlY3RMYWIgPSBjKCdLSVIzREwyJywgJ1RPWCcsICdUV0lTVDEnLCAnQ0Q1MicsICdDQ1I0JywgJ0lMMlJBJywgJ0NENycsICdEUFA0JywgJ0NDUjcnLCAnR0FUQTMnLCAnRk9YUDMnLCAnRE5NMycsJ0NENzQnLCdJTDQnLCdJTDEzJywgJ05DUjEnLCAnQ0Q3MCcsICdBSVJFJywgJ1BEQ0QxIChQRC0xKScsICdDRDI3NCAoUEQtTDEpJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENENCBUIGNlbGxzIHZzIE5vcm1hbCBDRDQgVCBjZWxscyIsCiAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDAwMSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMC41LCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdibGFjaycsCiAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKCmBgYAoKIyMgNC4zIFZvbGNhbm8gUGxvdCBmb3IgTFIgd2l0aCBTQ1QgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfTFJfU0NULAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc19MUl9TQ1QkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJMUiB3aXRoIFNDVCBBc3NheSAoQWxsIEdlbmVzKSIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMC41KQpgYGAKCgojIyA0LjQgVm9sY2FubyBQbG90IGZvciBtYXJrZXJzX0xSX1NDVApgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc19MUl9TQ1QsIAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc19MUl9TQ1QkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnS0lSM0RMMicsICdUT1gnLCAnVFdJU1QxJywgJ0NENTInLCAnQ0NSNCcsICdJTDJSQScsICdDRDcnLCAnRFBQNCcsICdDQ1I3JywgJ0dBVEEzJywgJ0ZPWFAzJywgJ0ROTTMnLCdDRDc0JywnSUw0JywnSUwxMycsICdOQ1IxJywgJ0NENzAnLCAnQUlSRScsICdQRENEMSAoUEQtMSknLCAnQ0QyNzQgKFBELUwxKScpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiU8OpemFyeSBDRDQgVCBjZWxscyB2cyBOb3JtYWwgQ0Q0IFQgY2VsbHMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAwLjUsIAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2JsYWNrJywKICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQoKYGBgCiMjIDQuNSBWb2xjYW5vIFBsb3QgZm9yIG5lZ2Jpbm9tIHdpdGggU0NUIEFzc2F5CmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CkVuaGFuY2VkVm9sY2FubyhtYXJrZXJzX25lZ2Jpbm9tX1NDVCwKICAgICAgICAgICAgICAgIGxhYiA9IG1hcmtlcnNfbmVnYmlub21fU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTFIgd2l0aCBTQ1QgQXNzYXkgKEFsbCBHZW5lcykiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDAuNSkKYGBgCgojIyA0LjYgVm9sY2FubyBQbG90IGZvciBtYXJrZXJzX25lZ2Jpbm9tX1NDVApgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc19uZWdiaW5vbV9TQ1QsIAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc19uZWdiaW5vbV9TQ1QkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnS0lSM0RMMicsICdUT1gnLCAnVFdJU1QxJywgJ0NENTInLCAnQ0NSNCcsICdJTDJSQScsICdDRDcnLCAnRFBQNCcsICdDQ1I3JywgJ0dBVEEzJywgJ0ZPWFAzJywgJ0ROTTMnLCdDRDc0JywnSUw0JywnSUwxMycsICdOQ1IxJywgJ0NENzAnLCAnQUlSRScsICdQRENEMSAoUEQtMSknLCAnQ0QyNzQgKFBELUwxKScpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiU8OpemFyeSBDRDQgVCBjZWxscyB2cyBOb3JtYWwgQ0Q0IFQgY2VsbHMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAwLjUsIAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2JsYWNrJywKICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQoKYGBgCgojIDUuIEZpbHRlciBhbmQgU3VtbWFyaXplIFJlc3VsdHMKIyMgNS4xIEFwcGx5IEV4cHJlc3Npb24gRmlsdGVyIEZpcnN0CmBgYHtyfQojIEFwcGx5IHRoZSBleHByZXNzaW9uIGZpbHRlciBmaXJzdAptYXJrZXJzX21hc3RfU0NUIDwtIG1hcmtlcnNfbWFzdF9TQ1QgJT4lCiAgZmlsdGVyKCEobWVhbl9leHByX2dyb3VwMSA8IDAuMiAmIG1lYW5fZXhwcl9ncm91cDIgPCAwLjIpKQoKbWFya2Vyc19MUl9TQ1QgPC0gbWFya2Vyc19MUl9TQ1QgJT4lCiAgZmlsdGVyKCEobWVhbl9leHByX2dyb3VwMSA8IDAuMiAmIG1lYW5fZXhwcl9ncm91cDIgPCAwLjIpKQoKbWFya2Vyc19uZWdiaW5vbV9TQ1QgPC0gbWFya2Vyc19uZWdiaW5vbV9TQ1QgJT4lCiAgZmlsdGVyKCEobWVhbl9leHByX2dyb3VwMSA8IDAuMiAmIG1lYW5fZXhwcl9ncm91cDIgPCAwLjIpKQoKYGBgCgoKIyMgNS4yIFN1bW1hcnkgRnVuY3Rpb24KYGBge3J9CnN1bW1hcml6ZV9tYXJrZXJzIDwtIGZ1bmN0aW9uKG1hcmtlcnMpIHsKICBudW1fcHZhbDAgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDApCiAgbnVtX3B2YWwxIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAxKQogIG51bV9zaWduaWZpY2FudCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPCAwLjA1KQogIG51bV91cHJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDID4gMSkKICBudW1fZG93bnJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDIDwgLTEpCiAgCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAwOiIsIG51bV9wdmFsMCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDE6IiwgbnVtX3B2YWwxLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHNpZ25pZmljYW50IGdlbmVzIChwX3ZhbF9hZGogPCAwLjA1KToiLCBudW1fc2lnbmlmaWNhbnQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgdXByZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPiAxKToiLCBudW1fdXByZWd1bGF0ZWQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZG93bnJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA8IDEpOiIsIG51bV9kb3ducmVndWxhdGVkLCAiXG4iKQp9CgpgYGAKCiMjIDUuMyBTdW1tYXJpemUgTWFya2VyczEgKE1BU1Qgd2l0aCBTQ1QgQXNzYXkpCmBgYHtyfQpjYXQoIk1hcmtlcnMxIFN1bW1hcnkgKE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfbWFzdF9TQ1QpCgpgYGAKCgoKIyMgNS40IFN1bW1hcnkgZm9yIE1hcmtlcnMzIChMUiB3aXRoIFNDVCBBc3NheSkKYGBge3J9CmNhdCgiTWFya2VyczMgU3VtbWFyeSAoTFIgd2l0aCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfTFJfU0NUKQpgYGAKCiMjIDUuNSBTdW1tYXJ5IGZvciBNYXJrZXJzMyAobmVnYmlub20gd2l0aCBTQ1QgQXNzYXkpCmBgYHtyfQpjYXQoIk1hcmtlcnMzIFN1bW1hcnkgKG5lZ2Jpbm9tIHdpdGggQmF0Y2ggQ29ycmVjdGlvbik6XG4iKQpzdW1tYXJpemVfbWFya2VycyhtYXJrZXJzX25lZ2Jpbm9tX1NDVCkKYGBgCgojIyA1LjYgQXBwbHkgQWRkaXRpb25hbCBGaWx0ZXJzIGZvciBTdGF0aXN0aWNhbCBTaWduaWZpY2FuY2UgYW5kIEZvbGQgQ2hhbmdlCmBgYHtyfQojIERlZmluZSBmaWx0ZXJpbmcgY3JpdGVyaWEKcF92YWxfdGhyZXNob2xkIDwtIDAuMDUKbG9nZmNfdGhyZXNob2xkIDwtIDEKCiMgQXBwbHkgYWRkaXRpb25hbCBmaWx0ZXJzIGZvciBtYXJrZXJzX21hc3RfYmF0Y2gKZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCA8LSBtYXJrZXJzX21hc3RfU0NUICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCgoKZmlsdGVyZWRfbWFya2Vyc19MUl9TQ1QgPC0gbWFya2Vyc19MUl9TQ1QgJT4lCiAgZmlsdGVyKHBfdmFsX2FkaiA8IHBfdmFsX3RocmVzaG9sZCAmIGFicyhhdmdfbG9nMkZDKSA+IGxvZ2ZjX3RocmVzaG9sZCkKCmZpbHRlcmVkX21hcmtlcnNfbmVnYmlub21fU0NUIDwtIG1hcmtlcnNfbmVnYmlub21fU0NUICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCgoKIyBTYXZlIGZpbHRlcmVkIHJlc3VsdHMKICB3cml0ZS5jc3YoZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCwgZmlsZSA9ICIuLi8wLXJvYmovU0NUX01BU1RfTFJfbmVnYmlub20vMS1NQVNUX3dpdGhfU0NUX2JhdGNoX2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uX2ZpbHRlcmVkLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpCndyaXRlLmNzdihmaWx0ZXJlZF9tYXJrZXJzX0xSX1NDVCwgZmlsZSA9ICIuLi8wLXJvYmovU0NUX01BU1RfTFJfbmVnYmlub20vMS1MUl93aXRoX1NDVF9iYXRjaF9jZWxsbGluZV9hc19Db3ZhcmlhdGVfd2l0aF9tZWFuRXhwcmVzc2lvbl9maWx0ZXJlZC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQoKd3JpdGUuY3N2KGZpbHRlcmVkX21hcmtlcnNfbmVnYmlub21fU0NULCBmaWxlID0gIi4uLzAtcm9iai9TQ1RfTUFTVF9MUl9uZWdiaW5vbS8xLW5lZ2Jpbm9tX3dpdGhfU0NUX2JhdGNoX2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uX2ZpbHRlcmVkLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpCgpgYGAKCiMjIDUuNyBTdW1tYXJ5IEZ1bmN0aW9uCmBgYHtyfQpzdW1tYXJpemVfbWFya2VycyA8LSBmdW5jdGlvbihtYXJrZXJzKSB7CiAgbnVtX3B2YWwwIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAwKQogIG51bV9wdmFsMSA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMSkKICBudW1fc2lnbmlmaWNhbnQgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqIDwgMC4wNSkKICBudW1fdXByZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA+IDEpCiAgbnVtX2Rvd25yZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA8IC0xKQogIAogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMDoiLCBudW1fcHZhbDAsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAxOiIsIG51bV9wdmFsMSwgIlxuIikKICBjYXQoIk51bWJlciBvZiBzaWduaWZpY2FudCBnZW5lcyAocF92YWxfYWRqIDwgMC4wNSk6IiwgbnVtX3NpZ25pZmljYW50LCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHVwcmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDID4gMSk6IiwgbnVtX3VwcmVndWxhdGVkLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGRvd25yZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPCAtMSk6IiwgbnVtX2Rvd25yZWd1bGF0ZWQsICJcbiIpCn0KYGBgCgojIyA1LjggU3VtbWFyaXplIE1hcmtlcnMxIChNQVNUIHdpdGggQmF0Y2ggQ29ycmVjdGlvbikKYGBge3J9CmNhdCgiTWFya2VyczEgU3VtbWFyeSAobWFya2Vyc19tYXN0X1NDVCk6XG4iKQpzdW1tYXJpemVfbWFya2VycyhmaWx0ZXJlZF9tYXJrZXJzX21hc3RfU0NUKQpgYGAKCiMjIDUuOSBTdW1tYXJpemUgTWFya2VyczIgKG1hcmtlcnNfTFJfU0NUKQpgYGB7cn0KY2F0KCJNYXJrZXJzMiBTdW1tYXJ5IChtYXJrZXJzX0xSX1NDVCk6XG4iKQpzdW1tYXJpemVfbWFya2VycyhmaWx0ZXJlZF9tYXJrZXJzX0xSX1NDVCkKYGBgCgojIyA1LjEwIFN1bW1hcml6ZSBNYXJrZXJzMiAobWFya2Vyc19uZWdiaW5vbV9TQ1QpCmBgYHtyfQpjYXQoIk1hcmtlcnMyIFN1bW1hcnkgKG1hcmtlcnNfbmVnYmlub21fU0NUKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKGZpbHRlcmVkX21hcmtlcnNfbmVnYmlub21fU0NUKQpgYGAKCiMgNi4gVmlzdWFsaXphdGlvbiBvZiBGaWx0ZXJlZCBSZXN1bHRzCiMjIDYuMSBWb2xjYW5vIFBsb3QgZm9yIG1hcmtlcnNfbWFzdF9TQ1QKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9TQ1QsCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX21hc3RfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTUFTVCB3aXRoIFNDVCBhc3NheSAoQWxsIEdlbmVzKSIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMSkKYGBgCgoKIyMgNi4yIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRoIFNDVCBBc3NheQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8oZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCwgCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX21hc3RfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0tJUjNETDInLCAnVE9YJywgJ1RXSVNUMScsICdDRDUyJywgJ0NDUjQnLCAnSUwyUkEnLCAnQ0Q3JywgJ0RQUDQnLCAnQ0NSNycsICdHQVRBMycsICdGT1hQMycsICdETk0zJywgJ05DUjEnLCAnQ0Q3MCcsICdBSVJFJywgJ1BEQ0QxIChQRC0xKScsICdDRDI3NCAoUEQtTDEpJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENENCBUIGNlbGxzIHZzIE5vcm1hbCBDRDQgVCBjZWxscyIsCiAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDAwMSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMSwgCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gMy4wLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnYmxhY2snLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCgpgYGAKCiMjIDYuMyBWb2xjYW5vIFBsb3QgZm9yIExSIHdpdGggU0NUIEFzc2F5CmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CkVuaGFuY2VkVm9sY2FubyhmaWx0ZXJlZF9tYXJrZXJzX0xSX1NDVCwKICAgICAgICAgICAgICAgIGxhYiA9IGZpbHRlcmVkX21hcmtlcnNfTFJfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTFIgd2l0aCBTQ1QgQXNzYXkgKEFsbCBHZW5lcykiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEuMCkKYGBgCgoKIyMgNi40IFZvbGNhbm8gUGxvdCBmb3IgTFIgd2l0aCBTQ1QgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfTFJfU0NULCAKICAgICAgICAgICAgICAgIGxhYiA9IGZpbHRlcmVkX21hcmtlcnNfTFJfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0tJUjNETDInLCAnVE9YJywgJ1RXSVNUMScsICdDRDUyJywgJ0NDUjQnLCAnSUwyUkEnLCAnQ0Q3JywgJ0RQUDQnLCAnQ0NSNycsICdHQVRBMycsICdGT1hQMycsICdETk0zJywgJ05DUjEnLCAnQ0Q3MCcsICdBSVJFJywgJ1BEQ0QxIChQRC0xKScsICdDRDI3NCAoUEQtTDEpJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENENCBUIGNlbGxzIHZzIE5vcm1hbCBDRDQgVCBjZWxscyIsCiAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEsIAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gMy4wLAogICAgICAgICAgICAgICAgbGFiU2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGJveGVkTGFiZWxzID0gVFJVRSwKICAgICAgICAgICAgICAgIGNvbEFscGhhID0gMC41LAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSA0LjAsCiAgICAgICAgICAgICAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICAgICAgICAgICAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjUsCiAgICAgICAgICAgICAgICBjb2xDb25uZWN0b3JzID0gJ2JsYWNrJywKICAgICAgICAgICAgICAgIGFycm93aGVhZHMgPSBGQUxTRSwKICAgICAgICAgICAgICAgIG1heC5vdmVybGFwcyA9IDMwKQoKYGBgCgojIyA2LjUgVm9sY2FubyBQbG90IGZvciBuZWdiaW5vbSB3aXRoIFNDVCBBc3NheQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8oZmlsdGVyZWRfbWFya2Vyc19uZWdiaW5vbV9TQ1QsCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX25lZ2Jpbm9tX1NDVCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkxSIHdpdGggU0NUIEFzc2F5IChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoKCiMjIDYuNiBWb2xjYW5vIFBsb3QgZm9yIG5lZ2Jpbm9tIHdpdGggU0NUIEFzc2F5CmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CkVuaGFuY2VkVm9sY2FubyhmaWx0ZXJlZF9tYXJrZXJzX25lZ2Jpbm9tX1NDVCwgCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX25lZ2Jpbm9tX1NDVCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwgCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICBzZWxlY3RMYWIgPSBjKCdLSVIzREwyJywgJ1RPWCcsICdUV0lTVDEnLCAnQ0Q1MicsICdDQ1I0JywgJ0lMMlJBJywgJ0NENycsICdEUFA0JywgJ0NDUjcnLCAnR0FUQTMnLCAnRk9YUDMnLCAnRE5NMycsICdOQ1IxJywgJ0NENzAnLCAnQUlSRScsICdQRENEMSAoUEQtMSknLCAnQ0QyNzQgKFBELUwxKScpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiU8OpemFyeSBDRDQgVCBjZWxscyB2cyBOb3JtYWwgQ0Q0IFQgY2VsbHMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdibGFjaycsCiAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKCmBgYA==