Setup knitr and load utility functions

knitr::opts_chunk$set(echo = TRUE)
knitr::opts_knit$set(root.dir="E:/DISC/reproducibility")
utilities_path = "./source/utilities.r"
source(utilities_path)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
reldist: Relative Distribution Methods
Version 1.6-6 created on 2016-10-07.
copyright (c) 2003, Mark S. Handcock, University of California-Los Angeles
 For citation information, type citation("reldist").
 Type help(package="reldist") to get started.

Settings

method_name = c("Raw", "DISC", "scVI", "MAGIC", "DCA", "scScope", "DeepImpute", "VIPER", "scImpute")
method_color = c("#A5A5A5", "#E83828", "#278BC4", "#EADE36", "#198B41", "#920783", "#F8B62D", "#8E5E32", "#1E2B68")
text_color = rep("black", length(method_name))
names(text_color) = method_name
text_color["DISC"] = "red"

Here, we use Spearman Correlation Coefficient as an indicator to evaluate the similarity between bulk data and imputed single data. For replicated bulk samples, we average their profiles as this paper (https://www.biorxiv.org/content/10.1101/2020.01.29.925974v1).

gene_bulk_fpkm = readh5_loom("./data/JURKAT_293T/bulk_fpkm.loom")
[1] "./data/JURKAT_293T/bulk_fpkm.loom"
[1] 58011     4
gene_bulk_fpkm_log1p = log1p(gene_bulk_fpkm)
bulk_data = cbind(rowMeans(gene_bulk_fpkm_log1p[, 1:2]), rowMeans(gene_bulk_fpkm_log1p[, 3:4]))
colnames(bulk_data) = c("293T", "Jurkat")

cor_list = list()

293T

gene_bc_mat = readh5_loom("./data/JURKAT_293T/raw_293T.loom")
[1] "./data/JURKAT_293T/raw_293T.loom"
[1] 32738  2885
gene_filter = gene_selection(gene_bc_mat, 10)
sc_gene = rownames(gene_bc_mat)[gene_filter]
compare_gene = intersect(sc_gene, rownames(bulk_data))
cor_list[["293T"]] = c()
for(ii in method_name){
  switch(ii, 
         "Raw" = {
           gene_bc_filt = gene_bc_mat[sc_gene, ]
         },
         "DISC" = {
           gene_bc_mat = readh5_loom(paste0("./data/JURKAT_293T/DISC_293T.loom"))
           gene_bc_filt = gene_bc_mat[sc_gene, ]
         }, {
           gene_bc_mat = readh5_imputation(paste0("./data/JURKAT_293T/", ii, "_293T.hdf5"))
           gene_bc_filt = gene_bc_mat[sc_gene, ]
         }
  )
  seurat_obj = CreateSeuratObject(counts = as.data.frame(gene_bc_filt), min.cells = 0, min.features = 0)
  seurat_obj = NormalizeData(seurat_obj, normalization.method = "LogNormalize", scale.factor = 10000)
  sc_norm = as.matrix(seurat_obj[["RNA"]]@data)
  rownames(sc_norm) = sc_gene
  sc_data = sc_norm[compare_gene, ]
  cor_list[["293T"]] = c(cor_list[["293T"]], cor(rowMeans(sc_data), bulk_data[compare_gene, 1], method = "spearman"))
}
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DISC_293T.loom"
[1] 32738  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scVI_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/MAGIC_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DCA_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scScope_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DeepImpute_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/VIPER_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scImpute_293T.hdf5"
[1] 11974  2885
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
names(cor_list[["293T"]]) = method_name

Jurkat

gene_bc_mat = readh5_loom("./data/JURKAT_293T/raw_Jurkat.loom")
[1] "./data/JURKAT_293T/raw_Jurkat.loom"
[1] 32738  3258
gene_filter = gene_selection(gene_bc_mat, 10)
sc_gene = rownames(gene_bc_mat)[gene_filter]
compare_gene = intersect(sc_gene, rownames(bulk_data))
cor_list[["Jurkat"]] = c()
for(ii in method_name){
  switch(ii, 
         "Raw" = {
           gene_bc_filt = gene_bc_mat[sc_gene, ]
         },
         "DISC" = {
           gene_bc_mat = readh5_loom(paste0("./data/JURKAT_293T/DISC_Jurkat.loom"))
           gene_bc_filt = gene_bc_mat[sc_gene, ]
         }, {
           gene_bc_mat = readh5_imputation(paste0("./data/JURKAT_293T/", ii, "_Jurkat.hdf5"))
           gene_bc_filt = gene_bc_mat[sc_gene, ]
         }
  )
  seurat_obj = CreateSeuratObject(counts = as.data.frame(gene_bc_filt), min.cells = 0, min.features = 0)
  seurat_obj = NormalizeData(seurat_obj, normalization.method = "LogNormalize", scale.factor = 10000)
  sc_norm = as.matrix(seurat_obj[["RNA"]]@data)
  rownames(sc_norm) = sc_gene
  sc_data = sc_norm[compare_gene, ]
  cor_list[["Jurkat"]] = c(cor_list[["Jurkat"]], cor(rowMeans(sc_data), bulk_data[compare_gene, 2], method = "spearman"))
}
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DISC_Jurkat.loom"
[1] 32738  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scVI_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/MAGIC_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DCA_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scScope_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DeepImpute_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/VIPER_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scImpute_Jurkat.hdf5"
[1] 11293  3258
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
names(cor_list[["Jurkat"]]) = method_name

JURKAT_293T

gene_bc_mat = readh5_loom("./data/JURKAT_293T/raw.loom")
[1] "./data/JURKAT_293T/raw.loom"
[1] 32738  6143
gene_filter = gene_selection(gene_bc_mat, 10)
sc_gene = rownames(gene_bc_mat)[gene_filter]
cell_Jurkat = colnames(gene_bc_mat)[grep("JURKAT", colnames(gene_bc_mat))]
cell_293T = colnames(gene_bc_mat)[grep("293T", colnames(gene_bc_mat))]
compare_gene = intersect(sc_gene, rownames(bulk_data))
cor_list[["JURKAT_293T"]] = c()
for(ii in method_name){
  if(ii == "Raw"){
    gene_bc_filt = gene_bc_mat[sc_gene, ]
  }else{
    gene_bc_mat = readh5_loom(paste0("./data/JURKAT_293T/", ii, "_JURKAT_293T.loom"))
    gene_bc_filt = gene_bc_mat[sc_gene, ]
  }
  seurat_obj = CreateSeuratObject(counts = as.data.frame(gene_bc_filt), min.cells = 0, min.features = 0)
  seurat_obj = NormalizeData(seurat_obj, normalization.method = "LogNormalize", scale.factor = 10000)
  sc_norm = as.matrix(seurat_obj[["RNA"]]@data)
  rownames(sc_norm) = sc_gene
  sc_data = sc_norm[compare_gene, ]
  cor_list[["JURKAT_293T"]] = c(cor_list[["JURKAT_293T"]], cor(rowMeans(sc_data[, cell_293T]) - rowMeans(sc_data[, cell_Jurkat]), bulk_data[compare_gene, 1] - bulk_data[compare_gene, 2], method = "spearman"))
}
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DISC_JURKAT_293T.loom"
[1] 32738  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scVI_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/MAGIC_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DCA_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scScope_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/DeepImpute_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/VIPER_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
[1] "./data/JURKAT_293T/scImpute_JURKAT_293T.loom"
[1] 13328  6143
Feature names cannot have underscores ('_'), replacing with dashes ('-')Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
names(cor_list[["JURKAT_293T"]]) = method_name

Results

barplot_usage(cor_list[["Jurkat"]], main = "", cex.main = 1.5, bar_color = method_color, text_color = text_color, use_data_order = T, ylab = "Jurkat", cex.lab = 1.5, font.main = 1, ylim = c(-0.1, 1), use_border = F, decreasing = T)

barplot_usage(cor_list[["293T"]], main = "", cex.main = 1.5, bar_color = method_color, text_color = text_color, use_data_order = T, ylab = "293T", cex.lab = 1.5, font.main = 1, ylim = c(-0.1, 1), use_border = F, decreasing = T)

barplot_usage(cor_list[["JURKAT_293T"]], main = "", cex.main = 1.5, bar_color = method_color, text_color = text_color, use_data_order = T, ylab = "JURKAT_293T", cex.lab = 1.5, font.main = 1, ylim = c(-0.1, 1), use_border = F, decreasing = T)

LS0tDQp0aXRsZTogIlNwZWFybWFuIENvcnJlbGF0aW9uIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCiMjIyBTZXR1cCBrbml0ciBhbmQgbG9hZCB1dGlsaXR5IGZ1bmN0aW9ucw0KYGBge3Igc2V0dXB9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQprbml0cjo6b3B0c19rbml0JHNldChyb290LmRpcj0iRTovRElTQy9yZXByb2R1Y2liaWxpdHkiKQ0KYGBgDQpgYGB7cn0NCnV0aWxpdGllc19wYXRoID0gIi4vc291cmNlL3V0aWxpdGllcy5yIg0Kc291cmNlKHV0aWxpdGllc19wYXRoKQ0KYGBgDQojIyMgU2V0dGluZ3MNCmBgYHtyfQ0KbWV0aG9kX25hbWUgPSBjKCJSYXciLCAiRElTQyIsICJzY1ZJIiwgIk1BR0lDIiwgIkRDQSIsICJzY1Njb3BlIiwgIkRlZXBJbXB1dGUiLCAiVklQRVIiLCAic2NJbXB1dGUiKQ0KbWV0aG9kX2NvbG9yID0gYygiI0E1QTVBNSIsICIjRTgzODI4IiwgIiMyNzhCQzQiLCAiI0VBREUzNiIsICIjMTk4QjQxIiwgIiM5MjA3ODMiLCAiI0Y4QjYyRCIsICIjOEU1RTMyIiwgIiMxRTJCNjgiKQ0KdGV4dF9jb2xvciA9IHJlcCgiYmxhY2siLCBsZW5ndGgobWV0aG9kX25hbWUpKQ0KbmFtZXModGV4dF9jb2xvcikgPSBtZXRob2RfbmFtZQ0KdGV4dF9jb2xvclsiRElTQyJdID0gInJlZCINCmBgYA0KSGVyZSwgd2UgdXNlIFNwZWFybWFuIENvcnJlbGF0aW9uIENvZWZmaWNpZW50IGFzIGFuIGluZGljYXRvciB0byBldmFsdWF0ZSB0aGUgc2ltaWxhcml0eSBiZXR3ZWVuIGJ1bGsgZGF0YSBhbmQgaW1wdXRlZCBzaW5nbGUgZGF0YS4NCkZvciByZXBsaWNhdGVkIGJ1bGsgc2FtcGxlcywgd2UgYXZlcmFnZSB0aGVpciBwcm9maWxlcyBhcyB0aGlzIHBhcGVyIChodHRwczovL3d3dy5iaW9yeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvMjAyMC4wMS4yOS45MjU5NzR2MSkuDQpgYGB7cn0NCmdlbmVfYnVsa19mcGttID0gcmVhZGg1X2xvb20oIi4vZGF0YS9KVVJLQVRfMjkzVC9idWxrX2Zwa20ubG9vbSIpDQpnZW5lX2J1bGtfZnBrbV9sb2cxcCA9IGxvZzFwKGdlbmVfYnVsa19mcGttKQ0KYnVsa19kYXRhID0gY2JpbmQocm93TWVhbnMoZ2VuZV9idWxrX2Zwa21fbG9nMXBbLCAxOjJdKSwgcm93TWVhbnMoZ2VuZV9idWxrX2Zwa21fbG9nMXBbLCAzOjRdKSkNCmNvbG5hbWVzKGJ1bGtfZGF0YSkgPSBjKCIyOTNUIiwgIkp1cmthdCIpDQoNCmNvcl9saXN0ID0gbGlzdCgpDQpgYGANCiMjIyAyOTNUDQpgYGB7cn0NCmdlbmVfYmNfbWF0ID0gcmVhZGg1X2xvb20oIi4vZGF0YS9KVVJLQVRfMjkzVC9yYXdfMjkzVC5sb29tIikNCmdlbmVfZmlsdGVyID0gZ2VuZV9zZWxlY3Rpb24oZ2VuZV9iY19tYXQsIDEwKQ0Kc2NfZ2VuZSA9IHJvd25hbWVzKGdlbmVfYmNfbWF0KVtnZW5lX2ZpbHRlcl0NCmNvbXBhcmVfZ2VuZSA9IGludGVyc2VjdChzY19nZW5lLCByb3duYW1lcyhidWxrX2RhdGEpKQ0KY29yX2xpc3RbWyIyOTNUIl1dID0gYygpDQpmb3IoaWkgaW4gbWV0aG9kX25hbWUpew0KICBzd2l0Y2goaWksIA0KICAgICAgICAgIlJhdyIgPSB7DQogICAgICAgICAgIGdlbmVfYmNfZmlsdCA9IGdlbmVfYmNfbWF0W3NjX2dlbmUsIF0NCiAgICAgICAgIH0sDQogICAgICAgICAiRElTQyIgPSB7DQogICAgICAgICAgIGdlbmVfYmNfbWF0ID0gcmVhZGg1X2xvb20ocGFzdGUwKCIuL2RhdGEvSlVSS0FUXzI5M1QvRElTQ18yOTNULmxvb20iKSkNCiAgICAgICAgICAgZ2VuZV9iY19maWx0ID0gZ2VuZV9iY19tYXRbc2NfZ2VuZSwgXQ0KICAgICAgICAgfSwgew0KICAgICAgICAgICBnZW5lX2JjX21hdCA9IHJlYWRoNV9pbXB1dGF0aW9uKHBhc3RlMCgiLi9kYXRhL0pVUktBVF8yOTNULyIsIGlpLCAiXzI5M1QuaGRmNSIpKQ0KICAgICAgICAgICBnZW5lX2JjX2ZpbHQgPSBnZW5lX2JjX21hdFtzY19nZW5lLCBdDQogICAgICAgICB9DQogICkNCiAgc2V1cmF0X29iaiA9IENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBhcy5kYXRhLmZyYW1lKGdlbmVfYmNfZmlsdCksIG1pbi5jZWxscyA9IDAsIG1pbi5mZWF0dXJlcyA9IDApDQogIHNldXJhdF9vYmogPSBOb3JtYWxpemVEYXRhKHNldXJhdF9vYmosIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkxvZ05vcm1hbGl6ZSIsIHNjYWxlLmZhY3RvciA9IDEwMDAwKQ0KICBzY19ub3JtID0gYXMubWF0cml4KHNldXJhdF9vYmpbWyJSTkEiXV1AZGF0YSkNCiAgcm93bmFtZXMoc2Nfbm9ybSkgPSBzY19nZW5lDQogIHNjX2RhdGEgPSBzY19ub3JtW2NvbXBhcmVfZ2VuZSwgXQ0KICBjb3JfbGlzdFtbIjI5M1QiXV0gPSBjKGNvcl9saXN0W1siMjkzVCJdXSwgY29yKHJvd01lYW5zKHNjX2RhdGEpLCBidWxrX2RhdGFbY29tcGFyZV9nZW5lLCAxXSwgbWV0aG9kID0gInNwZWFybWFuIikpDQp9DQpuYW1lcyhjb3JfbGlzdFtbIjI5M1QiXV0pID0gbWV0aG9kX25hbWUNCmBgYA0KIyMjIEp1cmthdA0KYGBge3J9DQpnZW5lX2JjX21hdCA9IHJlYWRoNV9sb29tKCIuL2RhdGEvSlVSS0FUXzI5M1QvcmF3X0p1cmthdC5sb29tIikNCmdlbmVfZmlsdGVyID0gZ2VuZV9zZWxlY3Rpb24oZ2VuZV9iY19tYXQsIDEwKQ0Kc2NfZ2VuZSA9IHJvd25hbWVzKGdlbmVfYmNfbWF0KVtnZW5lX2ZpbHRlcl0NCmNvbXBhcmVfZ2VuZSA9IGludGVyc2VjdChzY19nZW5lLCByb3duYW1lcyhidWxrX2RhdGEpKQ0KY29yX2xpc3RbWyJKdXJrYXQiXV0gPSBjKCkNCmZvcihpaSBpbiBtZXRob2RfbmFtZSl7DQogIHN3aXRjaChpaSwgDQogICAgICAgICAiUmF3IiA9IHsNCiAgICAgICAgICAgZ2VuZV9iY19maWx0ID0gZ2VuZV9iY19tYXRbc2NfZ2VuZSwgXQ0KICAgICAgICAgfSwNCiAgICAgICAgICJESVNDIiA9IHsNCiAgICAgICAgICAgZ2VuZV9iY19tYXQgPSByZWFkaDVfbG9vbShwYXN0ZTAoIi4vZGF0YS9KVVJLQVRfMjkzVC9ESVNDX0p1cmthdC5sb29tIikpDQogICAgICAgICAgIGdlbmVfYmNfZmlsdCA9IGdlbmVfYmNfbWF0W3NjX2dlbmUsIF0NCiAgICAgICAgIH0sIHsNCiAgICAgICAgICAgZ2VuZV9iY19tYXQgPSByZWFkaDVfaW1wdXRhdGlvbihwYXN0ZTAoIi4vZGF0YS9KVVJLQVRfMjkzVC8iLCBpaSwgIl9KdXJrYXQuaGRmNSIpKQ0KICAgICAgICAgICBnZW5lX2JjX2ZpbHQgPSBnZW5lX2JjX21hdFtzY19nZW5lLCBdDQogICAgICAgICB9DQogICkNCiAgc2V1cmF0X29iaiA9IENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBhcy5kYXRhLmZyYW1lKGdlbmVfYmNfZmlsdCksIG1pbi5jZWxscyA9IDAsIG1pbi5mZWF0dXJlcyA9IDApDQogIHNldXJhdF9vYmogPSBOb3JtYWxpemVEYXRhKHNldXJhdF9vYmosIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkxvZ05vcm1hbGl6ZSIsIHNjYWxlLmZhY3RvciA9IDEwMDAwKQ0KICBzY19ub3JtID0gYXMubWF0cml4KHNldXJhdF9vYmpbWyJSTkEiXV1AZGF0YSkNCiAgcm93bmFtZXMoc2Nfbm9ybSkgPSBzY19nZW5lDQogIHNjX2RhdGEgPSBzY19ub3JtW2NvbXBhcmVfZ2VuZSwgXQ0KICBjb3JfbGlzdFtbIkp1cmthdCJdXSA9IGMoY29yX2xpc3RbWyJKdXJrYXQiXV0sIGNvcihyb3dNZWFucyhzY19kYXRhKSwgYnVsa19kYXRhW2NvbXBhcmVfZ2VuZSwgMl0sIG1ldGhvZCA9ICJzcGVhcm1hbiIpKQ0KfQ0KbmFtZXMoY29yX2xpc3RbWyJKdXJrYXQiXV0pID0gbWV0aG9kX25hbWUNCmBgYA0KIyMjIEpVUktBVF8yOTNUDQpgYGB7cn0NCmdlbmVfYmNfbWF0ID0gcmVhZGg1X2xvb20oIi4vZGF0YS9KVVJLQVRfMjkzVC9yYXcubG9vbSIpDQpnZW5lX2ZpbHRlciA9IGdlbmVfc2VsZWN0aW9uKGdlbmVfYmNfbWF0LCAxMCkNCnNjX2dlbmUgPSByb3duYW1lcyhnZW5lX2JjX21hdClbZ2VuZV9maWx0ZXJdDQpjZWxsX0p1cmthdCA9IGNvbG5hbWVzKGdlbmVfYmNfbWF0KVtncmVwKCJKVVJLQVQiLCBjb2xuYW1lcyhnZW5lX2JjX21hdCkpXQ0KY2VsbF8yOTNUID0gY29sbmFtZXMoZ2VuZV9iY19tYXQpW2dyZXAoIjI5M1QiLCBjb2xuYW1lcyhnZW5lX2JjX21hdCkpXQ0KY29tcGFyZV9nZW5lID0gaW50ZXJzZWN0KHNjX2dlbmUsIHJvd25hbWVzKGJ1bGtfZGF0YSkpDQpjb3JfbGlzdFtbIkpVUktBVF8yOTNUIl1dID0gYygpDQpmb3IoaWkgaW4gbWV0aG9kX25hbWUpew0KICBpZihpaSA9PSAiUmF3Iil7DQogICAgZ2VuZV9iY19maWx0ID0gZ2VuZV9iY19tYXRbc2NfZ2VuZSwgXQ0KICB9ZWxzZXsNCiAgICBnZW5lX2JjX21hdCA9IHJlYWRoNV9sb29tKHBhc3RlMCgiLi9kYXRhL0pVUktBVF8yOTNULyIsIGlpLCAiX0pVUktBVF8yOTNULmxvb20iKSkNCiAgICBnZW5lX2JjX2ZpbHQgPSBnZW5lX2JjX21hdFtzY19nZW5lLCBdDQogIH0NCiAgc2V1cmF0X29iaiA9IENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBhcy5kYXRhLmZyYW1lKGdlbmVfYmNfZmlsdCksIG1pbi5jZWxscyA9IDAsIG1pbi5mZWF0dXJlcyA9IDApDQogIHNldXJhdF9vYmogPSBOb3JtYWxpemVEYXRhKHNldXJhdF9vYmosIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkxvZ05vcm1hbGl6ZSIsIHNjYWxlLmZhY3RvciA9IDEwMDAwKQ0KICBzY19ub3JtID0gYXMubWF0cml4KHNldXJhdF9vYmpbWyJSTkEiXV1AZGF0YSkNCiAgcm93bmFtZXMoc2Nfbm9ybSkgPSBzY19nZW5lDQogIHNjX2RhdGEgPSBzY19ub3JtW2NvbXBhcmVfZ2VuZSwgXQ0KICBjb3JfbGlzdFtbIkpVUktBVF8yOTNUIl1dID0gYyhjb3JfbGlzdFtbIkpVUktBVF8yOTNUIl1dLCBjb3Iocm93TWVhbnMoc2NfZGF0YVssIGNlbGxfMjkzVF0pIC0gcm93TWVhbnMoc2NfZGF0YVssIGNlbGxfSnVya2F0XSksIGJ1bGtfZGF0YVtjb21wYXJlX2dlbmUsIDFdIC0gYnVsa19kYXRhW2NvbXBhcmVfZ2VuZSwgMl0sIG1ldGhvZCA9ICJzcGVhcm1hbiIpKQ0KfQ0KbmFtZXMoY29yX2xpc3RbWyJKVVJLQVRfMjkzVCJdXSkgPSBtZXRob2RfbmFtZQ0KYGBgDQojIyMgUmVzdWx0cw0KYGBge3IgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NX0NCmJhcnBsb3RfdXNhZ2UoY29yX2xpc3RbWyJKdXJrYXQiXV0sIG1haW4gPSAiIiwgY2V4Lm1haW4gPSAxLjUsIGJhcl9jb2xvciA9IG1ldGhvZF9jb2xvciwgdGV4dF9jb2xvciA9IHRleHRfY29sb3IsIHVzZV9kYXRhX29yZGVyID0gVCwgeWxhYiA9ICJKdXJrYXQiLCBjZXgubGFiID0gMS41LCBmb250Lm1haW4gPSAxLCB5bGltID0gYygtMC4xLCAxKSwgdXNlX2JvcmRlciA9IEYsIGRlY3JlYXNpbmcgPSBUKQ0KYmFycGxvdF91c2FnZShjb3JfbGlzdFtbIjI5M1QiXV0sIG1haW4gPSAiIiwgY2V4Lm1haW4gPSAxLjUsIGJhcl9jb2xvciA9IG1ldGhvZF9jb2xvciwgdGV4dF9jb2xvciA9IHRleHRfY29sb3IsIHVzZV9kYXRhX29yZGVyID0gVCwgeWxhYiA9ICIyOTNUIiwgY2V4LmxhYiA9IDEuNSwgZm9udC5tYWluID0gMSwgeWxpbSA9IGMoLTAuMSwgMSksIHVzZV9ib3JkZXIgPSBGLCBkZWNyZWFzaW5nID0gVCkNCmJhcnBsb3RfdXNhZ2UoY29yX2xpc3RbWyJKVVJLQVRfMjkzVCJdXSwgbWFpbiA9ICIiLCBjZXgubWFpbiA9IDEuNSwgYmFyX2NvbG9yID0gbWV0aG9kX2NvbG9yLCB0ZXh0X2NvbG9yID0gdGV4dF9jb2xvciwgdXNlX2RhdGFfb3JkZXIgPSBULCB5bGFiID0gIkpVUktBVF8yOTNUIiwgY2V4LmxhYiA9IDEuNSwgZm9udC5tYWluID0gMSwgeWxpbSA9IGMoLTAuMSwgMSksIHVzZV9ib3JkZXIgPSBGLCBkZWNyZWFzaW5nID0gVCkNCmBgYA==