1. Load Libraries

2. Load Data

2.1 Load CSV Files with Mean Expression


# Load the CSV files with mean expression data
markers_mast_batch <- read.csv("0-robj/1-MAST_with_batch_as_Covariate_with_meanExpression.csv", row.names = 1)
markers_wilcox <- read.csv("0-robj/2-Wilcox_min.pct_logfcT-0_with_meanExpression.csv", row.names = 1)
markers_mast_no_batch <- read.csv("0-robj/3-MAST_without_batch_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 Batch Correction)

cat("Markers1 Summary (MAST with Batch Correction):\n")
Markers1 Summary (MAST with Batch Correction):
summarize_markers(markers_mast_batch)
Number of genes with p_val_adj = 0: 74 
Number of genes with p_val_adj = 1: 19337 
Number of significant genes (p_val_adj < 0.05): 5615 
Number of upregulated genes (avg_log2FC > 1): 15048 
Number of downregulated genes (avg_log2FC < -1): 2281 

3.3 Summary for Markers2 (Wilcoxon Test)

cat("Markers2 Summary (Wilcoxon Test):\n")
Markers2 Summary (Wilcoxon Test):
summarize_markers(markers_wilcox)
Number of genes with p_val_adj = 0: 4208 
Number of genes with p_val_adj = 1: 10428 
Number of significant genes (p_val_adj < 0.05): 15043 
Number of upregulated genes (avg_log2FC > 1): 15048 
Number of downregulated genes (avg_log2FC < -1): 2281 

3.4 Summary for Markers3 (MAST without Batch Correction)

cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(markers_mast_no_batch)
Number of genes with p_val_adj = 0: 4679 
Number of genes with p_val_adj = 1: 9855 
Number of significant genes (p_val_adj < 0.05): 15579 
Number of upregulated genes (avg_log2FC > 1): 15048 
Number of downregulated genes (avg_log2FC < -1): 2281 

4. Volcano Plots for All Genes

4.1 Volcano Plot for MAST with Batch Correction

EnhancedVolcano(markers_mast_batch,
                lab = markers_mast_batch$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "MAST with Batch Correction (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...

4.2 Volcano Plot for Wilcoxon Test

EnhancedVolcano(markers_wilcox,
                lab = markers_wilcox$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "Wilcoxon Test (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...

4.3 Volcano Plot for MAST without Batch Correction

EnhancedVolcano(markers_mast_no_batch,
                lab = markers_mast_no_batch$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "MAST without Batch Correction (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...

5. Filter and Summarize Results

5.1 Apply Expression Filter First

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

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

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

5.2 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_batch <- markers_mast_batch %>%
  filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)

# Apply additional filters for markers_wilcox
filtered_markers_wilcox <- markers_wilcox %>%
  filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)

# Apply additional filters for markers_mast_no_batch
filtered_markers_mast_no_batch <- markers_mast_no_batch %>%
  filter(p_val_adj < p_val_threshold & abs(avg_log2FC) > logfc_threshold)

# Save filtered results
 write.csv(filtered_markers_mast_batch, file = "0-robj/1-MAST_with_batch_as_Covariate_filtered.csv", row.names = TRUE)
 write.csv(filtered_markers_wilcox, file = "0-robj/2-Wilcox_min.pct_logfcT-Default_filtered.csv", row.names = TRUE)
 write.csv(filtered_markers_mast_no_batch, file = "0-robj/3-MAST_without_batch_as_Covariate_filtered.csv", row.names = TRUE)

5.3 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.4 Summarize Markers1 (MAST with Batch Correction)

cat("Markers1 Summary (MAST with Batch Correction):\n")
Markers1 Summary (MAST with Batch Correction):
summarize_markers(filtered_markers_mast_batch)
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.5 Summarize Markers2 (Wilcoxon Test)

cat("Markers2 Summary (Wilcoxon Test):\n")
Markers2 Summary (Wilcoxon Test):
summarize_markers(filtered_markers_wilcox)
Number of genes with p_val_adj = 0: 3765 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4639 
Number of upregulated genes (avg_log2FC > 1): 4514 
Number of downregulated genes (avg_log2FC < -1): 125 

5.6 Summarize Markers3 (MAST without Batch Correction)

cat("Markers3 Summary (MAST without Batch Correction):\n")
Markers3 Summary (MAST without Batch Correction):
summarize_markers(filtered_markers_mast_no_batch)
Number of genes with p_val_adj = 0: 3955 
Number of genes with p_val_adj = 1: 0 
Number of significant genes (p_val_adj < 0.05): 4639 
Number of upregulated genes (avg_log2FC > 1): 4514 
Number of downregulated genes (avg_log2FC < -1): 125 

6. Visualization of Filtered Results

6.1 Volcano Plot for Filtered MAST with Batch Correction

EnhancedVolcano(filtered_markers_mast_batch,
                lab = filtered_markers_mast_batch$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "Filtered MAST with Batch Correction",
                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.2 Volcano Plot for Wilcoxon Test

EnhancedVolcano(filtered_markers_wilcox,
                lab = filtered_markers_wilcox$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "Filtered Wilcoxon Test",
                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.3 Volcano Plot for MAST without Batch Correction

EnhancedVolcano(filtered_markers_mast_no_batch,
                lab = filtered_markers_mast_no_batch$gene,
                x = "avg_log2FC",
                y = "p_val_adj",
                title = "Filtered MAST withrout Batch Correction",
                pCutoff = 0.05,
                FCcutoff = 1.0)
Avis : One or more p-values is 0. Converting to 10^-1 * current lowest non-zero p-value...

LS0tCnRpdGxlOiAiRGlmZmVyZW50aWFsIEV4cHJlc3Npb24gQW5hbHlzaXMgLSBGaWx0ZXJpbmcgYW5kIFZpc3VhbGl6YXRpb24tTkVXVU1BUCIKYXV0aG9yOiBOYXNpciBNYWhtb29kIEFiYmFzaQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKLS0tCgojIDEuIExvYWQgTGlicmFyaWVzCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KHRpYmJsZSkKYGBgCgojIDIuIExvYWQgRGF0YQojIyAyLjEgTG9hZCBDU1YgRmlsZXMgd2l0aCBNZWFuIEV4cHJlc3Npb24KYGBge3J9CgojIExvYWQgdGhlIENTViBmaWxlcyB3aXRoIG1lYW4gZXhwcmVzc2lvbiBkYXRhCm1hcmtlcnNfbWFzdF9iYXRjaCA8LSByZWFkLmNzdigiMC1yb2JqLzEtTUFTVF93aXRoX2JhdGNoX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCm1hcmtlcnNfd2lsY294IDwtIHJlYWQuY3N2KCIwLXJvYmovMi1XaWxjb3hfbWluLnBjdF9sb2dmY1QtMF93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCm1hcmtlcnNfbWFzdF9ub19iYXRjaCA8LSByZWFkLmNzdigiMC1yb2JqLzMtTUFTVF93aXRob3V0X2JhdGNoX2FzX0NvdmFyaWF0ZV93aXRoX21lYW5FeHByZXNzaW9uLmNzdiIsIHJvdy5uYW1lcyA9IDEpCgpgYGAKCiMgMy4gU3VtbWFyaXplIFJlc3VsdHMKIyMgMy4xIFN1bW1hcnkgRnVuY3Rpb24KYGBge3J9CnN1bW1hcml6ZV9tYXJrZXJzIDwtIGZ1bmN0aW9uKG1hcmtlcnMpIHsKICBudW1fcHZhbDAgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDApCiAgbnVtX3B2YWwxIDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA9PSAxKQogIG51bV9zaWduaWZpY2FudCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPCAwLjA1KQogIG51bV91cHJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDID4gMSkKICBudW1fZG93bnJlZ3VsYXRlZCA8LSBzdW0obWFya2VycyRhdmdfbG9nMkZDIDwgLTEpCiAgCiAgY2F0KCJOdW1iZXIgb2YgZ2VuZXMgd2l0aCBwX3ZhbF9hZGogPSAwOiIsIG51bV9wdmFsMCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDE6IiwgbnVtX3B2YWwxLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIHNpZ25pZmljYW50IGdlbmVzIChwX3ZhbF9hZGogPCAwLjA1KToiLCBudW1fc2lnbmlmaWNhbnQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgdXByZWd1bGF0ZWQgZ2VuZXMgKGF2Z19sb2cyRkMgPiAxKToiLCBudW1fdXByZWd1bGF0ZWQsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2YgZG93bnJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA8IC0xKToiLCBudW1fZG93bnJlZ3VsYXRlZCwgIlxuIikKfQoKYGBgCgojIyAzLjIgU3VtbWFyaXplIE1hcmtlcnMxIChNQVNUIHdpdGggQmF0Y2ggQ29ycmVjdGlvbikKYGBge3J9CmNhdCgiTWFya2VyczEgU3VtbWFyeSAoTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24pOlxuIikKc3VtbWFyaXplX21hcmtlcnMobWFya2Vyc19tYXN0X2JhdGNoKQoKYGBgCgojIyAzLjMgU3VtbWFyeSBmb3IgTWFya2VyczIgKFdpbGNveG9uIFRlc3QpCmBgYHtyfQpjYXQoIk1hcmtlcnMyIFN1bW1hcnkgKFdpbGNveG9uIFRlc3QpOlxuIikKc3VtbWFyaXplX21hcmtlcnMobWFya2Vyc193aWxjb3gpCmBgYAoKIyMgMy40IFN1bW1hcnkgZm9yIE1hcmtlcnMzIChNQVNUIHdpdGhvdXQgQmF0Y2ggQ29ycmVjdGlvbikKYGBge3J9CmNhdCgiTWFya2VyczMgU3VtbWFyeSAoTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24pOlxuIikKc3VtbWFyaXplX21hcmtlcnMobWFya2Vyc19tYXN0X25vX2JhdGNoKQpgYGAKCgoKIyA0LiBWb2xjYW5vIFBsb3RzIGZvciBBbGwgR2VuZXMKIyMgNC4xIFZvbGNhbm8gUGxvdCBmb3IgTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24KYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKG1hcmtlcnNfbWFzdF9iYXRjaCwKICAgICAgICAgICAgICAgIGxhYiA9IG1hcmtlcnNfbWFzdF9iYXRjaCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIk1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uIChBbGwgR2VuZXMpIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoKIyMgNC4yIFZvbGNhbm8gUGxvdCBmb3IgV2lsY294b24gVGVzdApgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc193aWxjb3gsCiAgICAgICAgICAgICAgICBsYWIgPSBtYXJrZXJzX3dpbGNveCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIldpbGNveG9uIFRlc3QgKEFsbCBHZW5lcykiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEuMCkKYGBgCgojIyA0LjMgVm9sY2FubyBQbG90IGZvciBNQVNUIHdpdGhvdXQgQmF0Y2ggQ29ycmVjdGlvbgpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8obWFya2Vyc19tYXN0X25vX2JhdGNoLAogICAgICAgICAgICAgICAgbGFiID0gbWFya2Vyc19tYXN0X25vX2JhdGNoJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiTUFTVCB3aXRob3V0IEJhdGNoIENvcnJlY3Rpb24gKEFsbCBHZW5lcykiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEuMCkKYGBgCgojIDUuIEZpbHRlciBhbmQgU3VtbWFyaXplIFJlc3VsdHMKIyMgNS4xIEFwcGx5IEV4cHJlc3Npb24gRmlsdGVyIEZpcnN0CmBgYHtyfQojIEFwcGx5IHRoZSBleHByZXNzaW9uIGZpbHRlciBmaXJzdAptYXJrZXJzX21hc3RfYmF0Y2ggPC0gbWFya2Vyc19tYXN0X2JhdGNoICU+JQogIGZpbHRlcighKG1lYW5fZXhwcl9ncm91cDEgPCAwLjIgJiBtZWFuX2V4cHJfZ3JvdXAyIDwgMC4yKSkKCm1hcmtlcnNfd2lsY294IDwtIG1hcmtlcnNfd2lsY294ICU+JQogIGZpbHRlcighKG1lYW5fZXhwcl9ncm91cDEgPCAwLjIgJiBtZWFuX2V4cHJfZ3JvdXAyIDwgMC4yKSkKCm1hcmtlcnNfbWFzdF9ub19iYXRjaCA8LSBtYXJrZXJzX21hc3Rfbm9fYmF0Y2ggJT4lCiAgZmlsdGVyKCEobWVhbl9leHByX2dyb3VwMSA8IDAuMiAmIG1lYW5fZXhwcl9ncm91cDIgPCAwLjIpKQpgYGAKCiMjIDUuMiBBcHBseSBBZGRpdGlvbmFsIEZpbHRlcnMgZm9yIFN0YXRpc3RpY2FsIFNpZ25pZmljYW5jZSBhbmQgRm9sZCBDaGFuZ2UKYGBge3J9CiMgRGVmaW5lIGZpbHRlcmluZyBjcml0ZXJpYQpwX3ZhbF90aHJlc2hvbGQgPC0gMC4wNQpsb2dmY190aHJlc2hvbGQgPC0gMQoKIyBBcHBseSBhZGRpdGlvbmFsIGZpbHRlcnMgZm9yIG1hcmtlcnNfbWFzdF9iYXRjaApmaWx0ZXJlZF9tYXJrZXJzX21hc3RfYmF0Y2ggPC0gbWFya2Vyc19tYXN0X2JhdGNoICU+JQogIGZpbHRlcihwX3ZhbF9hZGogPCBwX3ZhbF90aHJlc2hvbGQgJiBhYnMoYXZnX2xvZzJGQykgPiBsb2dmY190aHJlc2hvbGQpCgojIEFwcGx5IGFkZGl0aW9uYWwgZmlsdGVycyBmb3IgbWFya2Vyc193aWxjb3gKZmlsdGVyZWRfbWFya2Vyc193aWxjb3ggPC0gbWFya2Vyc193aWxjb3ggJT4lCiAgZmlsdGVyKHBfdmFsX2FkaiA8IHBfdmFsX3RocmVzaG9sZCAmIGFicyhhdmdfbG9nMkZDKSA+IGxvZ2ZjX3RocmVzaG9sZCkKCiMgQXBwbHkgYWRkaXRpb25hbCBmaWx0ZXJzIGZvciBtYXJrZXJzX21hc3Rfbm9fYmF0Y2gKZmlsdGVyZWRfbWFya2Vyc19tYXN0X25vX2JhdGNoIDwtIG1hcmtlcnNfbWFzdF9ub19iYXRjaCAlPiUKICBmaWx0ZXIocF92YWxfYWRqIDwgcF92YWxfdGhyZXNob2xkICYgYWJzKGF2Z19sb2cyRkMpID4gbG9nZmNfdGhyZXNob2xkKQoKIyBTYXZlIGZpbHRlcmVkIHJlc3VsdHMKIHdyaXRlLmNzdihmaWx0ZXJlZF9tYXJrZXJzX21hc3RfYmF0Y2gsIGZpbGUgPSAiMC1yb2JqLzEtTUFTVF93aXRoX2JhdGNoX2FzX0NvdmFyaWF0ZV9maWx0ZXJlZC5jc3YiLCByb3cubmFtZXMgPSBUUlVFKQogd3JpdGUuY3N2KGZpbHRlcmVkX21hcmtlcnNfd2lsY294LCBmaWxlID0gIjAtcm9iai8yLVdpbGNveF9taW4ucGN0X2xvZ2ZjVC1EZWZhdWx0X2ZpbHRlcmVkLmNzdiIsIHJvdy5uYW1lcyA9IFRSVUUpCiB3cml0ZS5jc3YoZmlsdGVyZWRfbWFya2Vyc19tYXN0X25vX2JhdGNoLCBmaWxlID0gIjAtcm9iai8zLU1BU1Rfd2l0aG91dF9iYXRjaF9hc19Db3ZhcmlhdGVfZmlsdGVyZWQuY3N2Iiwgcm93Lm5hbWVzID0gVFJVRSkKYGBgCgojIyA1LjMgU3VtbWFyeSBGdW5jdGlvbgpgYGB7cn0Kc3VtbWFyaXplX21hcmtlcnMgPC0gZnVuY3Rpb24obWFya2VycykgewogIG51bV9wdmFsMCA8LSBzdW0obWFya2VycyRwX3ZhbF9hZGogPT0gMCkKICBudW1fcHZhbDEgPC0gc3VtKG1hcmtlcnMkcF92YWxfYWRqID09IDEpCiAgbnVtX3NpZ25pZmljYW50IDwtIHN1bShtYXJrZXJzJHBfdmFsX2FkaiA8IDAuMDUpCiAgbnVtX3VwcmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPiAxKQogIG51bV9kb3ducmVndWxhdGVkIDwtIHN1bShtYXJrZXJzJGF2Z19sb2cyRkMgPCAtMSkKICAKICBjYXQoIk51bWJlciBvZiBnZW5lcyB3aXRoIHBfdmFsX2FkaiA9IDA6IiwgbnVtX3B2YWwwLCAiXG4iKQogIGNhdCgiTnVtYmVyIG9mIGdlbmVzIHdpdGggcF92YWxfYWRqID0gMToiLCBudW1fcHZhbDEsICJcbiIpCiAgY2F0KCJOdW1iZXIgb2Ygc2lnbmlmaWNhbnQgZ2VuZXMgKHBfdmFsX2FkaiA8IDAuMDUpOiIsIG51bV9zaWduaWZpY2FudCwgIlxuIikKICBjYXQoIk51bWJlciBvZiB1cHJlZ3VsYXRlZCBnZW5lcyAoYXZnX2xvZzJGQyA+IDEpOiIsIG51bV91cHJlZ3VsYXRlZCwgIlxuIikKICBjYXQoIk51bWJlciBvZiBkb3ducmVndWxhdGVkIGdlbmVzIChhdmdfbG9nMkZDIDwgLTEpOiIsIG51bV9kb3ducmVndWxhdGVkLCAiXG4iKQp9CmBgYAoKIyMgNS40IFN1bW1hcml6ZSBNYXJrZXJzMSAoTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24pCmBgYHtyfQpjYXQoIk1hcmtlcnMxIFN1bW1hcnkgKE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uKTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9iYXRjaCkKYGBgCgojIyA1LjUgU3VtbWFyaXplIE1hcmtlcnMyIChXaWxjb3hvbiBUZXN0KQpgYGB7cn0KY2F0KCJNYXJrZXJzMiBTdW1tYXJ5IChXaWxjb3hvbiBUZXN0KTpcbiIpCnN1bW1hcml6ZV9tYXJrZXJzKGZpbHRlcmVkX21hcmtlcnNfd2lsY294KQpgYGAKCiMjIDUuNiBTdW1tYXJpemUgTWFya2VyczMgKE1BU1Qgd2l0aG91dCBCYXRjaCBDb3JyZWN0aW9uKQpgYGB7cn0KY2F0KCJNYXJrZXJzMyBTdW1tYXJ5IChNQVNUIHdpdGhvdXQgQmF0Y2ggQ29ycmVjdGlvbik6XG4iKQpzdW1tYXJpemVfbWFya2VycyhmaWx0ZXJlZF9tYXJrZXJzX21hc3Rfbm9fYmF0Y2gpCmBgYAoKIyA2LiBWaXN1YWxpemF0aW9uIG9mIEZpbHRlcmVkIFJlc3VsdHMKIyMgNi4xIFZvbGNhbm8gUGxvdCBmb3IgRmlsdGVyZWQgTUFTVCB3aXRoIEJhdGNoIENvcnJlY3Rpb24KYGBge3IsIGZpZy5oZWlnaHQ9MTIsIGZpZy53aWR0aD0xMn0KRW5oYW5jZWRWb2xjYW5vKGZpbHRlcmVkX21hcmtlcnNfbWFzdF9iYXRjaCwKICAgICAgICAgICAgICAgIGxhYiA9IGZpbHRlcmVkX21hcmtlcnNfbWFzdF9iYXRjaCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkZpbHRlcmVkIE1BU1Qgd2l0aCBCYXRjaCBDb3JyZWN0aW9uIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoKIyMgNi4yIFZvbGNhbm8gUGxvdCBmb3IgV2lsY294b24gVGVzdApgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8oZmlsdGVyZWRfbWFya2Vyc193aWxjb3gsCiAgICAgICAgICAgICAgICBsYWIgPSBmaWx0ZXJlZF9tYXJrZXJzX3dpbGNveCRnZW5lLAogICAgICAgICAgICAgICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgICAgICAgICAgICAgIHkgPSAicF92YWxfYWRqIiwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkZpbHRlcmVkIFdpbGNveG9uIFRlc3QiLAogICAgICAgICAgICAgICAgcEN1dG9mZiA9IDAuMDUsCiAgICAgICAgICAgICAgICBGQ2N1dG9mZiA9IDEuMCkKYGBgCgojIyA2LjMgVm9sY2FubyBQbG90IGZvciBNQVNUIHdpdGhvdXQgQmF0Y2ggQ29ycmVjdGlvbgpgYGB7ciwgZmlnLmhlaWdodD0xMiwgZmlnLndpZHRoPTEyfQpFbmhhbmNlZFZvbGNhbm8oZmlsdGVyZWRfbWFya2Vyc19tYXN0X25vX2JhdGNoLAogICAgICAgICAgICAgICAgbGFiID0gZmlsdGVyZWRfbWFya2Vyc19tYXN0X25vX2JhdGNoJGdlbmUsCiAgICAgICAgICAgICAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgICAgICAgICAgICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiRmlsdGVyZWQgTUFTVCB3aXRocm91dCBCYXRjaCBDb3JyZWN0aW9uIiwKICAgICAgICAgICAgICAgIHBDdXRvZmYgPSAwLjA1LAogICAgICAgICAgICAgICAgRkNjdXRvZmYgPSAxLjApCmBgYAoK