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 Markers3 (MAST with RNA Assay)
cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(markers_mast_RNA)
Number of genes with p_val_adj = 0: 78
Number of genes with p_val_adj = 1: 4853
Number of significant genes (p_val_adj < 0.05): 8198
Number of upregulated genes (avg_log2FC > 1): 4183
Number of downregulated genes (avg_log2FC < 1): 2606
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', '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 MAST with RNA Assay
EnhancedVolcano(markers_mast_RNA,
lab = markers_mast_RNA$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "MAST with RNA 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 MAST with RNA Assay
EnhancedVolcano(markers_mast_RNA,
lab = markers_mast_RNA$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 = 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_mast_RNA <- markers_mast_RNA %>%
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: 72
Number of genes with p_val_adj = 1: 2208
Number of significant genes (p_val_adj < 0.05): 2969
Number of upregulated genes (avg_log2FC > 1): 4514
Number of downregulated genes (avg_log2FC < 1): 125
5.4 Summary for Markers3 (MAST with RNA Assay)
cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(markers_mast_RNA)
Number of genes with p_val_adj = 0: 78
Number of genes with p_val_adj = 1: 567
Number of significant genes (p_val_adj < 0.05): 4092
Number of upregulated genes (avg_log2FC > 1): 1407
Number of downregulated genes (avg_log2FC < 1): 703
5.1.1 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)
# Apply additional filters for markers_mast_no_batch
filtered_markers_mast_RNA <- markers_mast_RNA %>%
filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)
# Save filtered results
write.csv(filtered_markers_mast_SCT, file = "../0-robj/1-MAST_with_SCT_batch_patient_cellline_as_Covariate_filtered.csv", row.names = TRUE)
write.csv(filtered_markers_mast_RNA, file = "../0-robj/2-MAST_with_RNA_batch_patient_cellline_as_Covariate_filtered.csv", row.names = TRUE)
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 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.4 Summarize Markers2 (markers_mast_RNA)
cat("Markers2 Summary (markers_mast_RNA):\n")
Markers2 Summary (markers_mast_RNA):
summarize_markers(filtered_markers_mast_RNA)
Number of genes with p_val_adj = 0: 16
Number of genes with p_val_adj = 1: 0
Number of significant genes (p_val_adj < 0.05): 1488
Number of upregulated genes (avg_log2FC > 1): 791
Number of downregulated genes (avg_log2FC < -1): 697
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 MAST with RNA Assay
EnhancedVolcano(filtered_markers_mast_RNA,
lab = filtered_markers_mast_RNA$gene,
x = "avg_log2FC",
y = "p_val_adj",
title = "MAST with RNA 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.4 Volcano Plot for MAST with RNA Assay
EnhancedVolcano(filtered_markers_mast_RNA,
lab = filtered_markers_mast_RNA$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...

LS0tCnRpdGxlOiAiRmlsdGVyaW5nIGFuZCBWaXN1YWxpemF0aW9uKE1BU1Qgb24gU0NUIGFuZCBSTkEpIG9uIGNlbGxfbGluZSBhbmQgZGVmYXVsdF9taW5wY3RfbG9nZmMiCmF1dGhvcjogTmFzaXIgTWFobW9vZCBBYmJhc2kKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICB0b2NfY29sbGFwc2VkOiB0cnVlCi0tLQoKIyAxLiBMb2FkIExpYnJhcmllcwpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShkcGx5cikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KEVuaGFuY2VkVm9sY2FubykKbGlicmFyeShwaGVhdG1hcCkKbGlicmFyeSh0aWJibGUpCmBgYAoKIyAyLiBMb2FkIERhdGEKIyMgMi4xIExvYWQgQ1NWIEZpbGVzIHdpdGggTWVhbiBFeHByZXNzaW9uCmBgYHtyfQoKIyBMb2FkIHRoZSBDU1YgZmlsZXMgd2l0aCBtZWFuIGV4cHJlc3Npb24gZGF0YQptYXJrZXJzX21hc3RfU0NUIDwtIHJlYWQuY3N2KCIuLi8wLXJvYmovUk5BX1NDVF90ZXN0X2RlZmF1bHRfcGN0X2ZjX3BhcmFtZXRlcnMvMS1NQVNUX3dpdGhfU0NUX2JhdGNoX2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCgptYXJrZXJzX21hc3RfUk5BIDwtIHJlYWQuY3N2KCIuLi8wLXJvYmovUk5BX1NDVF90ZXN0X2RlZmF1bHRfcGN0X2ZjX3BhcmFtZXRlcnMvMi1NQVNUX3dpdGhfUk5BX2JhdGNoX2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCgpgYGAKCiMgMy4gU3VtbWFyaXplIFJlc3VsdHMKIyMgMy4xIFN1bW1hcnkgRnVuY3Rpb24KYGBge3J9CnN1bW1hcml6ZV9tYXJrZXJzIDwtIGZ1bmN0aW9uKG1hcmtlcnMpIHsKICBudW1fcHZhbDAgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDApCiAgbnVtX3B2YWwxIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAxKQogIG51bV9zaWduaWZpY2FudCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPCAwLjA1KQogIG51bV91cHJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDID4gMSkKICBudW1fZG93bnJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDIDwgLTEpCiAgCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAwOiIsIG51bV9wdmFsMCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDE6IiwgbnVtX3B2YWwxLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHNpZ25pZmljYW50IGdlbmVzIChwX3ZhbF9hZGogPCAwLjA1KToiLCBudW1fc2lnbmlmaWNhbnQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgdXByZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPiAxKToiLCBudW1fdXByZWd1bGF0ZWQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZG93bnJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA8IDEpOiIsIG51bV9kb3ducmVndWxhdGVkLCAiXG4iKQp9CgpgYGAKCiMjIDMuMiBTdW1tYXJpemUgTWFya2VyczEgKE1BU1Qgd2l0aCBTQ1QgQXNzYXkpCmBgYHtyfQpjYXQoIk1hcmtlcnMxIFN1bW1hcnkgKE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKG1hcmtlcnNfbWFzdF9TQ1QpCgpgYGAKCgoKIyMgMy4zIFN1bW1hcnkgZm9yIE1hcmtlcnMzIChNQVNUIHdpdGggUk5BIEFzc2F5KQpgYGB7cn0KY2F0KCJNYXJrZXJzMyBTdW1tYXJ5IChNQVNUIHdpdGhvdXQgQmF0Y2ggQ29ycmVjdGlvbik6XG4iKQpzdW1tYXJpemVfbWFya2VycyhtYXJrZXJzX21hc3RfUk5BKQpgYGAKCgoKIyA0LiBWb2xjYW5vIFBsb3RzIGZvciBBbGwgR2VuZXMKIyMgNC4xIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRoIFNDVCBBc3NheQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc19tYXN0X1NDVCwKICAgICAgICAgICAgICAgIGxhYiA9IG1hcmtlcnNfbWFzdF9TQ1QkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJNQVNUIHdpdGggU0NUIGFzc2F5IChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAwLjUpCmBgYAoKIyMgNC4yIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRoIFNDVCBBc3NheQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc19tYXN0X1NDVCwgCiAgICAgICAgICAgICAgICBsYWIgPSBtYXJrZXJzX21hc3RfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0tJUjNETDInLCAnVE9YJywgJ1RXSVNUMScsICdDRDUyJywgJ0NDUjQnLCAnSUwyUkEnLCAnQ0Q3JywgJ0RQUDQnLCAnQ0NSNycsICdHQVRBMycsICdGT1hQMycsICdETk0zJywgJ05DUjEnLCAnQ0Q3MCcsICdBSVJFJywgJ1BEQ0QxIChQRC0xKScsICdDRDI3NCAoUEQtTDEpJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENENCBUIGNlbGxzIHZzIE5vcm1hbCBDRDQgVCBjZWxscyIsCiAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDAwMSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMC41LCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdibGFjaycsCiAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKCmBgYAoKIyMgNC4zIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRoIFJOQSBBc3NheQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc19tYXN0X1JOQSwKICAgICAgICAgICAgICAgIGxhYiA9IG1hcmtlcnNfbWFzdF9STkEkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJNQVNUIHdpdGggUk5BIEFzc2F5IChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAwLjUpCmBgYAoKCiMjIDQuNCBWb2xjYW5vIFBsb3QgZm9yIE1BU1Qgd2l0aCBSTkEgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfbWFzdF9STkEsIAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc19tYXN0X1JOQSRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwgCiAgICAgICAgICAgICAgICB5ID0gInBfdmFsX2FkaiIsCiAgICAgICAgICAgICAgICBzZWxlY3RMYWIgPSBjKCdLSVIzREwyJywgJ1RPWCcsICdUV0lTVDEnLCAnQ0Q1MicsICdDQ1I0JywgJ0lMMlJBJywgJ0NENycsICdEUFA0JywgJ0NDUjcnLCAnR0FUQTMnLCAnRk9YUDMnLCAnRE5NMycsICdOQ1IxJywgJ0NENzAnLCAnQUlSRScsICdQRENEMSAoUEQtMSknLCAnQ0QyNzQgKFBELUwxKScpLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiU8OpemFyeSBDRDQgVCBjZWxscyB2cyBOb3JtYWwgQ0Q0IFQgY2VsbHMiLAogICAgICAgICAgICAgICAgeGxhYiA9IGJxdW90ZSh+TG9nWzJdfiAnZm9sZCBjaGFuZ2UnKSwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjAwMDEsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDAuNSwgCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gMy4wLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnYmxhY2snLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCgpgYGAKCiMgNS4gRmlsdGVyIGFuZCBTdW1tYXJpemUgUmVzdWx0cwojIyA1LjEgQXBwbHkgRXhwcmVzc2lvbiBGaWx0ZXIgRmlyc3QKYGBge3J9CiMgQXBwbHkgdGhlIGV4cHJlc3Npb24gZmlsdGVyIGZpcnN0Cm1hcmtlcnNfbWFzdF9TQ1QgPC0gbWFya2Vyc19tYXN0X1NDVCAlPiUKICBmaWx0ZXIoIShtZWFuX2V4cHJfZ3JvdXAxIDwgMC4yICYgbWVhbl9leHByX2dyb3VwMiA8IDAuMikpCgoKbWFya2Vyc19tYXN0X1JOQSA8LSBtYXJrZXJzX21hc3RfUk5BICU+JQogIGZpbHRlcighKG1lYW5fZXhwcl9ncm91cDEgPCAwLjIgJiBtZWFuX2V4cHJfZ3JvdXAyIDwgMC4yKSkKCmBgYAoKCiMjIDUuMiBTdW1tYXJ5IEZ1bmN0aW9uCmBgYHtyfQpzdW1tYXJpemVfbWFya2VycyA8LSBmdW5jdGlvbihtYXJrZXJzKSB7CiAgbnVtX3B2YWwwIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAwKQogIG51bV9wdmFsMSA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMSkKICBudW1fc2lnbmlmaWNhbnQgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqIDwgMC4wNSkKICBudW1fdXByZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA+IDEpCiAgbnVtX2Rvd25yZWd1bGF0ZWQgPC0gc3VtKG1hcmtlcnMkYXZnX2xvZzJGQyA8IC0xKQogIAogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMDoiLCBudW1fcHZhbDAsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAxOiIsIG51bV9wdmFsMSwgIlxuIikKICBjYXQoIk51bWJlciBvZiBzaWduaWZpY2FudCBnZW5lcyAocF92YWxfYWRqIDwgMC4wNSk6IiwgbnVtX3NpZ25pZmljYW50LCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHVwcmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDID4gMSk6IiwgbnVtX3VwcmVndWxhdGVkLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGRvd25yZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPCAxKToiLCBudW1fZG93bnJlZ3VsYXRlZCwgIlxuIikKfQoKYGBgCgojIyA1LjMgU3VtbWFyaXplIE1hcmtlcnMxIChNQVNUIHdpdGggU0NUIEFzc2F5KQpgYGB7cn0KY2F0KCJNYXJrZXJzMSBTdW1tYXJ5IChNQVNUIHdpdGggQmF0Y2ggQ29ycmVjdGlvbik6XG4iKQpzdW1tYXJpemVfbWFya2VycyhtYXJrZXJzX21hc3RfU0NUKQoKYGBgCgoKCiMjIDUuNCBTdW1tYXJ5IGZvciBNYXJrZXJzMyAoTUFTVCB3aXRoIFJOQSBBc3NheSkKYGBge3J9CmNhdCgiTWFya2VyczMgU3VtbWFyeSAoTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24pOlxuIikKc3VtbWFyaXplX21hcmtlcnMobWFya2Vyc19tYXN0X1JOQSkKYGBgCgoKIyMgNS4xLjEgQXBwbHkgQWRkaXRpb25hbCBGaWx0ZXJzIGZvciBTdGF0aXN0aWNhbCBTaWduaWZpY2FuY2UgYW5kIEZvbGQgQ2hhbmdlCmBgYHtyfQojIERlZmluZSBmaWx0ZXJpbmcgY3JpdGVyaWEKcF92YWxfdGhyZXNob2xkIDwtIDAuMDUKbG9nZmNfdGhyZXNob2xkIDwtIDEKCiMgQXBwbHkgYWRkaXRpb25hbCBmaWx0ZXJzIGZvciBtYXJrZXJzX21hc3RfYmF0Y2gKZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCA8LSBtYXJrZXJzX21hc3RfU0NUICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCgoKCiMgQXBwbHkgYWRkaXRpb25hbCBmaWx0ZXJzIGZvciBtYXJrZXJzX21hc3Rfbm9fYmF0Y2gKZmlsdGVyZWRfbWFya2Vyc19tYXN0X1JOQSA8LSBtYXJrZXJzX21hc3RfUk5BICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCgojIFNhdmUgZmlsdGVyZWQgcmVzdWx0cwp3cml0ZS5jc3YoZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCwgZmlsZSA9ICIuLi8wLXJvYmovUk5BX1NDVF90ZXN0X2RlZmF1bHRfcGN0X2ZjX3BhcmFtZXRlcnMvMS1NQVNUX3dpdGhfU0NUX2JhdGNoX2NlbGxsaW5lX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uX2ZpbHRlcmVkLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpCndyaXRlLmNzdihmaWx0ZXJlZF9tYXJrZXJzX21hc3RfUk5BLCBmaWxlID0gIi4uLzAtcm9iai9STkFfU0NUX3Rlc3RfZGVmYXVsdF9wY3RfZmNfcGFyYW1ldGVycy8yLU1BU1Rfd2l0aF9STkFfYmF0Y2hfY2VsbGxpbmVfYXNfQ292YXJpYXRlX3dpdGhfbWVhbkV4cHJlc3Npb25fZmlsdGVyZWQuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgojIyA1LjIgU3VtbWFyeSBGdW5jdGlvbgpgYGB7cn0Kc3VtbWFyaXplX21hcmtlcnMgPC0gZnVuY3Rpb24obWFya2VycykgewogIG51bV9wdmFsMCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMCkKICBudW1fcHZhbDEgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDEpCiAgbnVtX3NpZ25pZmljYW50IDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA8IDAuMDUpCiAgbnVtX3VwcmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPiAxKQogIG51bV9kb3ducmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPCAtMSkKICAKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDA6IiwgbnVtX3B2YWwwLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMToiLCBudW1fcHZhbDEsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2Ygc2lnbmlmaWNhbnQgZ2VuZXMgKHBfdmFsX2FkaiA8IDAuMDUpOiIsIG51bV9zaWduaWZpY2FudCwgIlxuIikKICBjYXQoIk51bWJlciBvZiB1cHJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA+IDEpOiIsIG51bV91cHJlZ3VsYXRlZCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBkb3ducmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDIDwgLTEpOiIsIG51bV9kb3ducmVndWxhdGVkLCAiXG4iKQp9CmBgYAoKIyMgNS4zIFN1bW1hcml6ZSBNYXJrZXJzMSAoTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24pCmBgYHtyfQpjYXQoIk1hcmtlcnMxIFN1bW1hcnkgKG1hcmtlcnNfbWFzdF9TQ1QpOlxuIikKc3VtbWFyaXplX21hcmtlcnMoZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCkKYGBgCgojIyA1LjQgU3VtbWFyaXplIE1hcmtlcnMyIChtYXJrZXJzX21hc3RfUk5BKQpgYGB7cn0KY2F0KCJNYXJrZXJzMiBTdW1tYXJ5IChtYXJrZXJzX21hc3RfUk5BKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9STkEpCmBgYAoKCiMgNi4gVmlzdWFsaXphdGlvbiBvZiBGaWx0ZXJlZCBSZXN1bHRzCiMjIDYuMSBWb2xjYW5vIFBsb3QgZm9yIG1hcmtlcnNfbWFzdF9TQ1QKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9TQ1QsCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX21hc3RfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTUFTVCB3aXRoIFNDVCBhc3NheSAoQWxsIEdlbmVzKSIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMSkKYGBgCgoKIyMgNi4yIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRoIFNDVCBBc3NheQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8oZmlsdGVyZWRfbWFya2Vyc19tYXN0X1NDVCwgCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX21hc3RfU0NUJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLCAKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoJ0tJUjNETDInLCAnVE9YJywgJ1RXSVNUMScsICdDRDUyJywgJ0NDUjQnLCAnSUwyUkEnLCAnQ0Q3JywgJ0RQUDQnLCAnQ0NSNycsICdHQVRBMycsICdGT1hQMycsICdETk0zJywgJ05DUjEnLCAnQ0Q3MCcsICdBSVJFJywgJ1BEQ0QxIChQRC0xKScsICdDRDI3NCAoUEQtTDEpJyksCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJTw6l6YXJ5IENENCBUIGNlbGxzIHZzIE5vcm1hbCBDRDQgVCBjZWxscyIsCiAgICAgICAgICAgICAgICB4bGFiID0gYnF1b3RlKH5Mb2dbMl1+ICdmb2xkIGNoYW5nZScpLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDAwMSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMSwgCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gMy4wLAogICAgICAgICAgICAgICAgYm94ZWRMYWJlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgY29sQWxwaGEgPSAwLjUsCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDQuMCwKICAgICAgICAgICAgICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgICAgICAgICAgICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuNSwKICAgICAgICAgICAgICAgIGNvbENvbm5lY3RvcnMgPSAnYmxhY2snLAogICAgICAgICAgICAgICAgYXJyb3doZWFkcyA9IEZBTFNFLAogICAgICAgICAgICAgICAgbWF4Lm92ZXJsYXBzID0gMzApCgpgYGAKCiMjIDYuMyBWb2xjYW5vIFBsb3QgZm9yIE1BU1Qgd2l0aCBSTkEgQXNzYXkKYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9STkEsCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX21hc3RfUk5BJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTUFTVCB3aXRoIFJOQSBBc3NheSAoQWxsIEdlbmVzKSIsCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wNSwKICAgICAgICAgICAgICAgIEZDY3V0b2ZmID0gMS4wKQpgYGAKCgojIyA2LjQgVm9sY2FubyBQbG90IGZvciBNQVNUIHdpdGggUk5BIEFzc2F5CmBgYHtyLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9MTJ9CkVuaGFuY2VkVm9sY2FubyhmaWx0ZXJlZF9tYXJrZXJzX21hc3RfUk5BLCAKICAgICAgICAgICAgICAgIGxhYiA9IGZpbHRlcmVkX21hcmtlcnNfbWFzdF9STkEkZ2VuZSwKICAgICAgICAgICAgICAgIHggPSAiYXZnX2xvZzJGQyIsIAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYygnS0lSM0RMMicsICdUT1gnLCAnVFdJU1QxJywgJ0NENTInLCAnQ0NSNCcsICdJTDJSQScsICdDRDcnLCAnRFBQNCcsICdDQ1I3JywgJ0dBVEEzJywgJ0ZPWFAzJywgJ0ROTTMnLCAnTkNSMScsICdDRDcwJywgJ0FJUkUnLCAnUERDRDEgKFBELTEpJywgJ0NEMjc0IChQRC1MMSknKSwKICAgICAgICAgICAgICAgIHRpdGxlID0gIlPDqXphcnkgQ0Q0IFQgY2VsbHMgdnMgTm9ybWFsIENENCBUIGNlbGxzIiwKICAgICAgICAgICAgICAgIHhsYWIgPSBicXVvdGUofkxvZ1syXX4gJ2ZvbGQgY2hhbmdlJyksCiAgICAgICAgICAgICAgICBwQ3V0b2ZmID0gMC4wMDAxLAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLCAKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDMuMCwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSAzLjAsCiAgICAgICAgICAgICAgICBib3hlZExhYmVscyA9IFRSVUUsCiAgICAgICAgICAgICAgICBjb2xBbHBoYSA9IDAuNSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gNC4wLAogICAgICAgICAgICAgICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgICAgICAgICAgICAgd2lkdGhDb25uZWN0b3JzID0gMC41LAogICAgICAgICAgICAgICAgY29sQ29ubmVjdG9ycyA9ICdibGFjaycsCiAgICAgICAgICAgICAgICBhcnJvd2hlYWRzID0gRkFMU0UsCiAgICAgICAgICAgICAgICBtYXgub3ZlcmxhcHMgPSAzMCkKCmBgYAoK