• TODO: Box, create ‘plasma’, print out plots, name xlsx appropriately. Check out olps further.

1 Introduction

2 Gene annotations

hg_annot <- load_biomart_annotations()
## The biomart annotations file already exists, loading from it.
hg_df <- hg_annot[["gene_annotations"]]

3 Sample sheet annotation

We have an older revision of the sample sheet for this dataset. I added some samples from Dr. Mosser in order to compare against M1/M2 activation states. These extra samples are not likely to be the most appropriate because they are not U937 samples.

hg38_se <- create_se("sample_sheets/macrogen_samples.xlsx",
                     file_column = "hisat_hg38", gene_info = hg_df)
## Reading the sample metadata.
## Checking the state of the condition column.
## Warning in extract_metadata(metadata, id_column = id_column, condition_column =
## condition_column, : There were NA values in the condition column, setting them
## to 'undefined'.
## Checking the state of the batch column.
## Warning in extract_metadata(metadata, id_column = id_column, condition_column =
## condition_column, : There were NA values in the condition column, setting them
## to 'undefined'.
## Checking the condition factor.
## The sample definitions comprises: 54 rows(samples) and 21 columns(metadata fields).
## Warning in create_se("sample_sheets/macrogen_samples.xlsx", file_column =
## "hisat_hg38", : Some samples were removed when cross referencing the samples
## against the count data.
## Matched 21405 annotations and counts.
## Some annotations were lost in merging, setting them to 'undefined'.
## The final summarized experiment has 21481 rows and 21 columns.
hg38_sampletype <- set_conditions(hg38_se, fact = "sampletype")
## The numbers of samples by condition are:
## 
## Asymptomatic      Chronic      control      Healthy 
##            5            5            3            2

4 Plots

hg38_norm <- normalize(hg38_sampletype, convert = "cpm", norm = "quant",
                       transform = "log2", filter = TRUE)
## Removing 9903 low-count genes (11578 remaining).
## transform_counts: Found 26 values equal to 0, adding 1 to the matrix.
plot_quantreads(hg38_sampletype)
## Library sizes of 15 samples, 
## ranging from 1,872,219 to 7,805,747.

plot_nonzero(hg38_sampletype, y_intercept = 0.65)
## The following samples have less than 13962.65 genes.
##  [1] "m1"      "m2"      "a_20179" "c_10036" "a_20187" "c_10046" "a_20132"
##  [8] "c_10063" "a_20133" "c_10093" "su1160"  "a_20134" "c_10073"
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the hpgltools package.
##   Please report the issue to the authors.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## A non-zero genes plot of 15 samples.
## These samples have an average 3.382 CPM coverage and 13550 genes observed, ranging from 12975 to
## 14728.

plot_corheat(hg38_norm)
## A heatmap of pairwise sample correlations ranging from: 
## 0.932974671519701 to 0.990409066934894.

plot_pca(hg38_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by Asymptomatic, Chronic, control, Healthy
## Shapes are defined by undefined.

hg38_nb <- normalize(hg38_sampletype, convert = "cpm", batch = "svaseq",
                     filter = TRUE, transform = "log2")
## Removing 9903 low-count genes (11578 remaining).
## transform_counts: Found 169 values less than 0.
## transform_counts: Found 169 values equal to 0, adding 1 to the matrix.
plot_pca(hg38_nb)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by Asymptomatic, Chronic, control, Healthy
## Shapes are defined by undefined.

5 DE

keepers <- list(
  "chr_asy" = c("Chronic", "Asymptomatic"),
  "chr_hea" = c("Chronic", "Healthy"),
  "chr_con" = c("Chronic", "control"),
  "asy_hea" = c("Asymptomatic", "Healthy"),
  "asy_con" = c("Asymptomatic", "control"),
  "hea_con" = c("Healthy", "control"))

hg38_de <- all_pairwise(hg38_sampletype, keepers = keepers, model_fstring = "~ 0 + condition",
                        model_svs = "svaseq", filter = TRUE)
## Asymptomatic      Chronic      control      Healthy 
##            5            5            3            2
## Removing 9903 low-count genes (11578 remaining).
## Basic step 0/3: Normalizing data.
## Basic step 0/3: Converting data.
## I think this is failing? SummarizedExperiment
## Basic step 0/3: Transforming data.
## Setting 4687 entries to zero.
## This received a matrix of SVs.
## converting counts to integer mode
## gene-wise dispersion estimates
## mean-dispersion relationship
## final dispersion estimates
## conditions
## Asymptomatic      Chronic      control      Healthy 
##            5            5            3            2
## conditions
## Asymptomatic      Chronic      control      Healthy 
##            5            5            3            2
## conditions
## Asymptomatic      Chronic      control      Healthy 
##            5            5            3            2

hg38_de
## A pairwise differential expression with results from: basic, deseq, ebseq, edger, limma, noiseq.
## This used a surrogate/batch estimate from: svaseq.
## The primary analysis performed 6 comparisons.
hg38_tables <- combine_de_tables(hg38_de, excel = "excel/hg38_tables.xlsx")
## Deleting the file excel/hg38_tables.xlsx before writing the tables.
## Looking for subscript invalid names, start of extract_keepers.
## Looking for subscript invalid names, end of extract_keepers.
hg38_tables
## A set of combined differential expression results.
##                     table deseq_sigup deseq_sigdown edger_sigup edger_sigdown
## 1 Chronic_vs_Asymptomatic          31            41          43            73
## 2      Chronic_vs_Healthy          59            43          98            77
## 3      Chronic_vs_control         680           458         748           551
## 4 Asymptomatic_vs_Healthy         112            83         183           127
## 5 Asymptomatic_vs_control         759           492         837           575
## 6      Healthy_vs_control         427           311         488           421
##   limma_sigup limma_sigdown
## 1          46            28
## 2          34            46
## 3         611           554
## 4          92           113
## 5         646           626
## 6         414           392
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## ℹ The deprecated feature was likely used in the UpSetR package.
##   Please report the issue to the authors.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## ℹ The deprecated feature was likely used in the UpSetR package.
##   Please report the issue to the authors.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Plot describing unique/shared genes in a differential expression table.

hg38_sig <- extract_significant_genes(hg38_tables, excel = "excel/hg38_sig.xlsx",
                                      according_to = "deseq")
## Deleting the file excel/hg38_sig.xlsx before writing the tables.
hg38_sig
## A set of genes deemed significant according to deseq.
## The parameters defining significant were:
## LFC cutoff: 1 adj P cutoff: 0.05
##                         deseq_up deseq_down
## Chronic_vs_Asymptomatic       31         41
## Chronic_vs_Healthy            59         43
## Chronic_vs_control           680        458
## Asymptomatic_vs_Healthy      112         83
## Asymptomatic_vs_control      759        492
## Healthy_vs_control           427        311

6 Repeat without the controls

no_controls <- subset_se(hg38_sampletype, subset = "condition!='control'")

no_controls_norm <- normalize(no_controls, transform = "log2", convert = "cpm",
                              norm = "quant", filter = TRUE)
## Removing 10032 low-count genes (11449 remaining).
## transform_counts: Found 6 values equal to 0, adding 1 to the matrix.
plot_pca(no_controls_norm)
## The result of performing a fast_svd dimension reduction.
## The x-axis is PC1 and the y-axis is PC2
## Colors are defined by Asymptomatic, Chronic, Healthy
## Shapes are defined by undefined.

no_control_keepers <- list(
  "chr_asy" = c("Chronic", "Asymptomatic"),
  "chr_hea" = c("Chronic", "Healthy"),
  "asy_hea" = c("Asymptomatic", "Healthy"))
no_control_de <- all_pairwise(no_controls, keepers = no_control_keepers,
                              model_fstring = "~ 0 + condition", model_svs = "svaseq",
                              filter = TRUE)
## Asymptomatic      Chronic      Healthy 
##            5            5            2
## Removing 10032 low-count genes (11449 remaining).
## Basic step 0/3: Normalizing data.
## Basic step 0/3: Converting data.
## I think this is failing? SummarizedExperiment
## Basic step 0/3: Transforming data.
## Setting 2623 entries to zero.
## This received a matrix of SVs.
## converting counts to integer mode
## gene-wise dispersion estimates
## mean-dispersion relationship
## final dispersion estimates
## conditions
## Asymptomatic      Chronic      Healthy 
##            5            5            2
## conditions
## Asymptomatic      Chronic      Healthy 
##            5            5            2
## conditions
## Asymptomatic      Chronic      Healthy 
##            5            5            2

no_control_table <- combine_de_tables(no_control_de, excel = "excel/hg38_nocontrols_tables.xlsx")
## Deleting the file excel/hg38_nocontrols_tables.xlsx before writing the tables.
## Looking for subscript invalid names, start of extract_keepers.
## Looking for subscript invalid names, end of extract_keepers.
no_control_sig <- extract_significant_genes(
  no_control_table, according_to = "deseq", excel = "excel/hg38_nocontrol_sig.xlsx")
## Deleting the file excel/hg38_nocontrol_sig.xlsx before writing the tables.
pp(file = "images/no_control_sig_barplot.png", image = no_control_sig[["sig_bar_plots"]][["deseq"]])

7 Repeat GSE(A) analyses

all_gp <- all_gprofiler(hg38_sig)
all_cp <- all_cprofiler(hg38_sig, hg38_tables)
## Error in simple_clusterprofiler(sig_genes = structure(list(ensembl_transcript_id = c("ENST00000492807",  : 
##   unused argument (internal = FALSE)
## Error in simple_clusterprofiler(sig_genes = structure(list(ensembl_transcript_id = c("ENST00000256104",  : 
##   unused argument (internal = FALSE)
## Error in `simple_cl[["kegg_universe"]]`:
## ! subscript out of bounds
## cp_test <- simple_clusterprofiler(ups, de_table = table, orgdb = pombe_orgdb,
##                                  orgdb_to = "GID", orgdb_from = "GID")
pander::pander(sessionInfo())
message(paste0("This is hpgltools commit: ", get_git_commit()))
message(paste0("Saving to ", savefile))
tmp <- sm(saveme(filename = savefile))
tmp <- loadme(filename = savefile)
LS0tCnRpdGxlOiAiUmV2aXNpdGluZyBhIG1hY3JvZ2VuIGV4cGVyaW1lbnQuIgphdXRob3I6ICJhdGIgYWJlbGV3QGdtYWlsLmNvbSIKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB6ZW5idXJuCiAgICBrZWVwX21kOiBmYWxzZQogICAgbW9kZTogc2VsZmNvbnRhaW5lZAogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQotLS0KCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShkcGx5cikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KGdsdWUpCmxpYnJhcnkoaHBnbHRvb2xzKQpsaWJyYXJ5KHRpZHlyKQoKa25pdHI6Om9wdHNfa25pdCRzZXQocHJvZ3Jlc3MgPSBUUlVFLCB2ZXJib3NlID0gVFJVRSwgd2lkdGggPSA5MCwgZWNobyA9IFRSVUUpCmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlcnJvciA9IFRSVUUsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4LCBmaWcucmV0aW5hID0gMiwKICBvdXQud2lkdGggPSAiMTAwJSIsIGRldiA9ICJwbmciLAogIGRldi5hcmdzID0gbGlzdChwbmcgPSBsaXN0KHR5cGUgPSAiY2Fpcm8tcG5nIikpKQpvbGRfb3B0aW9ucyA8LSBvcHRpb25zKGRpZ2l0cyA9IDQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSwga25pdHIuZHVwbGljYXRlLmxhYmVsID0gImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDEyKSkKdmVyIDwtIFN5cy5nZXRlbnYoIlZFUlNJT04iKQpydW5kYXRlIDwtIGZvcm1hdChTeXMuRGF0ZSgpLCBmb3JtYXQgPSAiJVklbSVkIikKcm1kX2ZpbGUgPC0gInByb3RfdnNfcm5hLlJtZCIKc2F2ZWZpbGUgPC0gZ3N1YihwYXR0ZXJuID0gIlxcLlJtZCIsIHJlcGxhY2UgPSAiXFwucmRhXFwueHoiLCB4ID0gcm1kX2ZpbGUpCmBgYAoKKiBUT0RPOiBCb3gsIGNyZWF0ZSAncGxhc21hJywgcHJpbnQgb3V0IHBsb3RzLCBuYW1lIHhsc3ggYXBwcm9wcmlhdGVseS4KICAgICAgICBDaGVjayBvdXQgb2xwcyBmdXJ0aGVyLgoKIyBJbnRyb2R1Y3Rpb24KCiMgR2VuZSBhbm5vdGF0aW9ucwoKYGBge3J9CmhnX2Fubm90IDwtIGxvYWRfYmlvbWFydF9hbm5vdGF0aW9ucygpCmhnX2RmIDwtIGhnX2Fubm90W1siZ2VuZV9hbm5vdGF0aW9ucyJdXQpgYGAKCiMgU2FtcGxlIHNoZWV0IGFubm90YXRpb24KCldlIGhhdmUgYW4gb2xkZXIgcmV2aXNpb24gb2YgdGhlIHNhbXBsZSBzaGVldCBmb3IgdGhpcyBkYXRhc2V0LiAgSQphZGRlZCBzb21lIHNhbXBsZXMgZnJvbSBEci4gTW9zc2VyIGluIG9yZGVyIHRvIGNvbXBhcmUgYWdhaW5zdCBNMS9NMgphY3RpdmF0aW9uIHN0YXRlcy4gIFRoZXNlIGV4dHJhIHNhbXBsZXMgYXJlIG5vdCBsaWtlbHkgdG8gYmUgdGhlIG1vc3QKYXBwcm9wcmlhdGUgYmVjYXVzZSB0aGV5IGFyZSBub3QgVTkzNyBzYW1wbGVzLgoKYGBge3J9CmhnMzhfc2UgPC0gY3JlYXRlX3NlKCJzYW1wbGVfc2hlZXRzL21hY3JvZ2VuX3NhbXBsZXMueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgIGZpbGVfY29sdW1uID0gImhpc2F0X2hnMzgiLCBnZW5lX2luZm8gPSBoZ19kZikKCmhnMzhfc2FtcGxldHlwZSA8LSBzZXRfY29uZGl0aW9ucyhoZzM4X3NlLCBmYWN0ID0gInNhbXBsZXR5cGUiKQpgYGAKCiMgUGxvdHMKCmBgYHtyfQpoZzM4X25vcm0gPC0gbm9ybWFsaXplKGhnMzhfc2FtcGxldHlwZSwgY29udmVydCA9ICJjcG0iLCBub3JtID0gInF1YW50IiwKICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2Zvcm0gPSAibG9nMiIsIGZpbHRlciA9IFRSVUUpCgpwbG90X3F1YW50cmVhZHMoaGczOF9zYW1wbGV0eXBlKQpwbG90X25vbnplcm8oaGczOF9zYW1wbGV0eXBlLCB5X2ludGVyY2VwdCA9IDAuNjUpCnBsb3RfY29yaGVhdChoZzM4X25vcm0pCnBsb3RfcGNhKGhnMzhfbm9ybSkKCmhnMzhfbmIgPC0gbm9ybWFsaXplKGhnMzhfc2FtcGxldHlwZSwgY29udmVydCA9ICJjcG0iLCBiYXRjaCA9ICJzdmFzZXEiLAogICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBUUlVFLCB0cmFuc2Zvcm0gPSAibG9nMiIpCnBsb3RfcGNhKGhnMzhfbmIpCmBgYAoKIyBERQoKYGBge3J9CmtlZXBlcnMgPC0gbGlzdCgKICAiY2hyX2FzeSIgPSBjKCJDaHJvbmljIiwgIkFzeW1wdG9tYXRpYyIpLAogICJjaHJfaGVhIiA9IGMoIkNocm9uaWMiLCAiSGVhbHRoeSIpLAogICJjaHJfY29uIiA9IGMoIkNocm9uaWMiLCAiY29udHJvbCIpLAogICJhc3lfaGVhIiA9IGMoIkFzeW1wdG9tYXRpYyIsICJIZWFsdGh5IiksCiAgImFzeV9jb24iID0gYygiQXN5bXB0b21hdGljIiwgImNvbnRyb2wiKSwKICAiaGVhX2NvbiIgPSBjKCJIZWFsdGh5IiwgImNvbnRyb2wiKSkKCmhnMzhfZGUgPC0gYWxsX3BhaXJ3aXNlKGhnMzhfc2FtcGxldHlwZSwga2VlcGVycyA9IGtlZXBlcnMsIG1vZGVsX2ZzdHJpbmcgPSAifiAwICsgY29uZGl0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxfc3ZzID0gInN2YXNlcSIsIGZpbHRlciA9IFRSVUUpCmhnMzhfZGUKCmhnMzhfdGFibGVzIDwtIGNvbWJpbmVfZGVfdGFibGVzKGhnMzhfZGUsIGV4Y2VsID0gImV4Y2VsL2hnMzhfdGFibGVzLnhsc3giKQpoZzM4X3RhYmxlcwoKaGczOF9zaWcgPC0gZXh0cmFjdF9zaWduaWZpY2FudF9nZW5lcyhoZzM4X3RhYmxlcywgZXhjZWwgPSAiZXhjZWwvaGczOF9zaWcueGxzeCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3JkaW5nX3RvID0gImRlc2VxIikKaGczOF9zaWcKYGBgCgojIFJlcGVhdCB3aXRob3V0IHRoZSBjb250cm9scwoKYGBge3J9Cm5vX2NvbnRyb2xzIDwtIHN1YnNldF9zZShoZzM4X3NhbXBsZXR5cGUsIHN1YnNldCA9ICJjb25kaXRpb24hPSdjb250cm9sJyIpCgpub19jb250cm9sc19ub3JtIDwtIG5vcm1hbGl6ZShub19jb250cm9scywgdHJhbnNmb3JtID0gImxvZzIiLCBjb252ZXJ0ID0gImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm0gPSAicXVhbnQiLCBmaWx0ZXIgPSBUUlVFKQpwbG90X3BjYShub19jb250cm9sc19ub3JtKQoKbm9fY29udHJvbF9rZWVwZXJzIDwtIGxpc3QoCiAgImNocl9hc3kiID0gYygiQ2hyb25pYyIsICJBc3ltcHRvbWF0aWMiKSwKICAiY2hyX2hlYSIgPSBjKCJDaHJvbmljIiwgIkhlYWx0aHkiKSwKICAiYXN5X2hlYSIgPSBjKCJBc3ltcHRvbWF0aWMiLCAiSGVhbHRoeSIpKQpub19jb250cm9sX2RlIDwtIGFsbF9wYWlyd2lzZShub19jb250cm9scywga2VlcGVycyA9IG5vX2NvbnRyb2xfa2VlcGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWxfZnN0cmluZyA9ICJ+IDAgKyBjb25kaXRpb24iLCBtb2RlbF9zdnMgPSAic3Zhc2VxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyID0gVFJVRSkKbm9fY29udHJvbF90YWJsZSA8LSBjb21iaW5lX2RlX3RhYmxlcyhub19jb250cm9sX2RlLCBleGNlbCA9ICJleGNlbC9oZzM4X25vY29udHJvbHNfdGFibGVzLnhsc3giKQpub19jb250cm9sX3NpZyA8LSBleHRyYWN0X3NpZ25pZmljYW50X2dlbmVzKAogIG5vX2NvbnRyb2xfdGFibGUsIGFjY29yZGluZ190byA9ICJkZXNlcSIsIGV4Y2VsID0gImV4Y2VsL2hnMzhfbm9jb250cm9sX3NpZy54bHN4IikKCnBwKGZpbGUgPSAiaW1hZ2VzL25vX2NvbnRyb2xfc2lnX2JhcnBsb3QucG5nIiwgaW1hZ2UgPSBub19jb250cm9sX3NpZ1tbInNpZ19iYXJfcGxvdHMiXV1bWyJkZXNlcSJdXSkKYGBgCgojIFJlcGVhdCBHU0UoQSkgYW5hbHlzZXMKCmBgYHtyfQphbGxfZ3AgPC0gYWxsX2dwcm9maWxlcihoZzM4X3NpZykKYWxsX2NwIDwtIGFsbF9jcHJvZmlsZXIoaGczOF9zaWcsIGhnMzhfdGFibGVzKQoKIyMgY3BfdGVzdCA8LSBzaW1wbGVfY2x1c3RlcnByb2ZpbGVyKHVwcywgZGVfdGFibGUgPSB0YWJsZSwgb3JnZGIgPSBwb21iZV9vcmdkYiwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JnZGJfdG8gPSAiR0lEIiwgb3JnZGJfZnJvbSA9ICJHSUQiKQoKYGBgCgpgYGB7ciBzYXZlbWUsIGV2YWw9RkFMU0V9CnBhbmRlcjo6cGFuZGVyKHNlc3Npb25JbmZvKCkpCm1lc3NhZ2UocGFzdGUwKCJUaGlzIGlzIGhwZ2x0b29scyBjb21taXQ6ICIsIGdldF9naXRfY29tbWl0KCkpKQptZXNzYWdlKHBhc3RlMCgiU2F2aW5nIHRvICIsIHNhdmVmaWxlKSkKdG1wIDwtIHNtKHNhdmVtZShmaWxlbmFtZSA9IHNhdmVmaWxlKSkKYGBgCgpgYGB7ciBsb2FkbWVfYWZ0ZXIsIGV2YWw9RkFMU0V9CnRtcCA8LSBsb2FkbWUoZmlsZW5hbWUgPSBzYXZlZmlsZSkKYGBgCg==