1 Parameters

2 Functions


library(stringi)
library(reticulate)
source_from_github(repositoy = "DEG_functions",version = "0.2.24")
source_from_github(repositoy = "cNMF_functions",version = "0.3.85",script_name = "cnmf_function_Harmony.R")

no_neg <- function(x) {
  x = x + abs(min(x))
  x
}

sum_2_one <- function(x) {
  x =x/sum(x)
  x
}

3 Data

xeno = readRDS("./Data/10x_xeno_1000.Rds")
lung = readRDS("./Data/lung_cancercells_withTP_onlyPatients.rds")
lung_patients = lung$patient.ident %>% unique() %>% as.character()
lung_patients_filtered = lung_patients[!(lung_patients %in% c("X1055new","X1099"))] # remove patients with less than 100 malignant cells
lung = subset(x = lung,subset = patient.ident %in% lung_patients_filtered)

4 Models 2K vargenes

suffix = r.suffix
import pickle
from cnmf import cNMF
f = open('./Data/cnmf/cnmf_objects/models_2Kvargenes_cnmf_obj.pckl', 'rb')
cnmf_obj = pickle.load(f)
f.close()
# gep_scores = readRDS("/sci/labs/yotamd/lab_share/avishai.wizel/R_projects/EGFR/Data/cnmf/harmony_models_gep_scores.rds")
selected_k = 3
density_threshold = 0.1
# cnmf_obj.consensus(k=selected_k, density_threshold=density_threshold)
usage_norm, gep_scores, gep_tpm, topgenes = cnmf_obj.load_results(K=selected_k, density_threshold=density_threshold)

5 programs enrichment

gep_scores = py$gep_scores
gep_tpm = py$gep_tpm
usage_norm= py$usage_norm
names (gep_scores) = c("Hypoxia","TNFa","Cell_cycle")
plt_list = list()

for (program  in names (gep_scores)) {
 p = ggplot(gep_scores, aes(x=!!ensym(program))) +
  geom_density()+xlab(program)+
   geom_vline(
    aes(xintercept=sort(gep_scores[,program],TRUE)[200]  ,color="top200"),
          linetype="dashed", size=1)+
   geom_vline(
    aes(xintercept=sort(gep_scores[,program],TRUE)[100]  ,color="top100"),
          linetype="dashed", size=1)+
      geom_vline(
    aes(xintercept=sort(gep_scores[,program],TRUE)[50]  ,color="top50"),
          linetype="dashed", size=1)+
         geom_vline(
    aes(xintercept=sort(gep_scores[,program],TRUE)[150]  ,color="top150"),
          linetype="dashed", size=1)+
   scale_color_manual(name = "top n genes", values = c(top200 = "blue",top100 = "red",top150 = "yellow",top50 = "green"))
   plt_list[[program]] <- p

}
 
ggarrange(plotlist = plt_list)

ntop = 150
plt_list = list()
hif_targets_set = data.frame(gs_name = "hif_targets",gene_symbol = hif_targets)

for (i in 1:ncol(gep_scores)) {
  top_genes = gep_scores  %>%  arrange(desc(gep_scores[i])) #sort by score a
  top = head(rownames(top_genes),ntop) #take top top_genes_num
  res = genes_vec_enrichment(genes = top,background = rownames(gep_scores),homer = T,title = 
                    i,silent = T,return_all = T,custom_pathways  = hif_targets_set)
   
  plt_list[[i]] = res$plt
}
gridExtra::grid.arrange(grobs = plt_list)

xeno = FindVariableFeatures(object = xeno,nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

6 Test with expr after harmony

import numpy as np
import scanpy as sc

expr_after_harmony = sc.read_h5ad('./Data/cnmf/xeno_Harmony_NoNeg_2Kvargenes.h5ad').to_df()
tpm =  compute_tpm(expr_after_harmony)
cnmf_genes = expr_after_harmony.keys().to_list()
usage_by_calc = get_usage_from_score(counts=expr_after_harmony,tpm=tpm,genes=cnmf_genes,cnmf_obj=cnmf_obj,k=3)

7 Check if original cNMF score is like the calculated score

usage_by_calc = py$usage_by_calc
usage_norm = py$usage_norm
cor(usage_by_calc,usage_norm)

8 calculate score for Xeno

usage_by_calc = get_usage_from_score(counts=xeno_expression,tpm=tpm,genes=xeno_vargenes, cnmf_obj=cnmf_obj,k=3)
/sci/labs/yotamd/lab_share/avishai.wizel/python_envs/miniconda/envs/cnmf_env_6/bin/python3.7:7: FutureWarning: X.dtype being converted to np.float32 from float64. In the next version of anndata (0.9) conversion will not be automatic. Pass dtype explicitly to avoid this warning. Pass `AnnData(X, dtype=X.dtype, ...)` to get the future behavour.
/sci/labs/yotamd/lab_share/avishai.wizel/python_envs/miniconda/envs/cnmf_env_6/bin/python3.7:8: FutureWarning: X.dtype being converted to np.float32 from float64. In the next version of anndata (0.9) conversion will not be automatic. Pass dtype explicitly to avoid this warning. Pass `AnnData(X, dtype=X.dtype, ...)` to get the future behavour.
all_metagenes = py$usage_by_calc

9 programs expression


names (all_metagenes) = c("Hypoxia","TNFa","Cell_cycle")
#add each metagene to metadata
for (i  in 1:ncol(all_metagenes)) {
  metage_metadata = all_metagenes %>% dplyr::select(i)
  # metage_metadata = scale(metage_metadata)
  xeno = AddMetaData(object = xeno,metadata = metage_metadata,col.name = names(all_metagenes)[i])
}

print_tab(plt = FeaturePlot(object = xeno,features = colnames(all_metagenes)),title = "umap expression")

umap expression

NA

10 programs regulation

metagenes_mean_compare(dataset = xeno,time.point_var = "treatment",prefix = "model",patient.ident_var = "orig.ident",pre_on = c("NT","OSI"),test = "wilcox.test",programs = c("Hypoxia","TNFa","Cell_cycle"))

Hypoxia per patient

Hypoxia

TNFa per patient

TNFa

Cell_cycle per patient

Cell_cycle

NA

hallmark_name = "GO_MITOTIC_CELL_CYCLE"
genesets  =getGmt("./Data/h.all.v7.0.symbols.pluscc.gmt")
var_features=xeno@assays$RNA@var.features
geneIds= genesets[[hallmark_name]]@geneIds
score <- apply(xeno@assays$RNA@data[intersect(geneIds,var_features),],2,mean)
xeno=AddMetaData(xeno,score,"GO_MITOTIC_CC")
metagenes_mean_compare(dataset = xeno,time.point_var = "treatment",prefix = "model",patient.ident_var = "orig.ident",pre_on = c("NT","OSI","res"),programs = c("GO_MITOTIC_CC"))

GO_MITOTIC_CC per patient

GO_MITOTIC_CC

NA

DotPlot(object = xeno, features =  c("Hypoxia","TNFa","Cell_cycle","GO_MITOTIC_CC"),scale = F,group.by  = 'treatment')
DotPlot(object = xeno, features =  c("Hypoxia","TNFa","Cell_cycle","GO_MITOTIC_CC"),scale = T,group.by  = 'treatment')

11 program assignment

larger_by = 1.5
xeno = program_assignment(dataset = xeno,larger_by = larger_by,program_names = colnames(all_metagenes))
print_tab(plt = 
            DimPlot(xeno,group.by = "program.assignment",cols = c(Hypoxia = "red",TNFa = "green",Cell_cycle = "blue","NA" = "grey"))
          ,title = "program.assignment",subtitle_num = 2)
print_tab(plt = 
              DimPlot(xeno,group.by = "orig.ident")
          ,title = "orig.ident",subtitle_num = 2)
print_tab(plt = 
            DimPlot(xeno,group.by = "treatment")
          ,title = "treatment",subtitle_num = 2)

p = cell_percentage(dataset = xeno,time.point_var = "treatment",by_program = T,x_order = c("NT","OSI","res"))
print_tab(plt = p,title = "by program",subtitle_num = 2)

p = cell_percentage(dataset = xeno,time.point_var = "treatment",by_tp  = T,x_order =c("Hypoxia","TNFa","Cell_cycle","NA"))
print_tab(plt = p,title = "by time point",subtitle_num = 2)
top_genes = gep_scores  %>%  arrange(desc(gep_scores["Hypoxia"])) #sort by score a
hypoxia_genes = head(rownames(top_genes),20) #take top top_genes_num
intersect(cluster_3_genes,hypoxia_genes)
library(ggvenn)
all = list(hypoxia_genes = hypoxia_genes, hif_targets = cluster_3_genes)
ggvenn(
  all
)

12 HIF_targets- Hypoxia correlation


for (genes in list(hif_targets,xeno_cluster_3_genes,xeno_cluster_3_2_genes)) {
  hif_targets_by_tp = FetchData(object = xeno,vars = c(genes)) %>% rowSums() %>% as.data.frame() #mean expression
  # hif_targets_by_tp[,2] = tnf_and_hypoxia2[,1]
  hif_targets_by_tp[,2] = xeno$Hypoxia
  
  names(hif_targets_by_tp) = c("hif_targets","hypoxia_program")
  
  
  
  p1 = ggplot(hif_targets_by_tp, aes(x=hif_targets, y=hypoxia_program)) + 
      geom_point()+
    geom_density_2d(aes(color = ..level..)) +
    geom_smooth(method=lm) +
    stat_cor(method = "pearson", label.x = 20, label.y = 1.1)+
    scale_color_viridis_c()
  
  p2 = ggplot(hif_targets_by_tp, aes(x=hif_targets, y=hypoxia_program)) + 
    geom_bin2d() +
    theme_bw()+ scale_fill_gradientn(limits=c(0,1100), breaks=seq(0, 1100, by=200), colours=c("blue","yellow","red"))+ 
    stat_cor(method = "pearson", label.x = 20, label.y = 1.1)+
    geom_smooth(method=lm) 
  
  p = ggarrange(plotlist = list(p1,p2),nrow  = 2)  
  
  print_tab(plt = p,title = "geom_bin2d")
}

Warning in FetchData.Seurat(object = xeno, vars = c(genes)) : The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1 geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’ ## geom_bin2d {.unnumbered }

geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’ ## geom_bin2d {.unnumbered }

geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’ ## geom_bin2d {.unnumbered }

NA

13 UMAPS

hif_targets_by_tp = FetchData(object = xeno,vars = c(hif_targets)) %>% rowSums() %>% as.data.frame() #mean expression
Warning in FetchData.Seurat(object = xeno, vars = c(hif_targets)) :
  The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1
hif_targets_by_tp[,2] = xeno$Hypoxia
names(hif_targets_by_tp) = c("hif_targets","hypoxia_program")

high_hif_low_hypoxia_cells = hif_targets_by_tp %>% filter(hif_targets>25 & hypoxia_program < 0.2) %>% rownames()
low_hif_high_hypoxia_cells = hif_targets_by_tp %>% filter(hif_targets<15 & hypoxia_program > 0.6) %>% rownames()

hif_targets_by_tp = FetchData(object = xeno,vars = c(hif_targets)) %>% rowSums() %>% as.data.frame() #mean expression
Warning in FetchData.Seurat(object = xeno, vars = c(hif_targets)) :
  The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1
xeno = AddMetaData(object = xeno, metadata = hif_targets_by_tp,col.name = "HIF_targets_score")
cells_to_highlight =  list(high_hif_low_hypoxia_cells = high_hif_low_hypoxia_cells, low_hif_high_hypoxia_cells = low_hif_high_hypoxia_cells)

DimPlot(object = xeno, cells.highlight = cells_to_highlight, cols.highlight = c("red","blue"), cols = "gray", order = TRUE)

FeaturePlot(object = xeno,features = c( "HIF_targets_score","Hypoxia","Cell_cycle" ))

markers = FindMarkers(object = xeno, ident.1 = "high_hif_low_hypoxia",ident.2 = "high_hif_high_hypoxia",densify = T)

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~27s          
  |++                                                | 2 % ~22s          
  |++                                                | 3 % ~21s          
  |+++                                               | 4 % ~20s          
  |+++                                               | 5 % ~19s          
  |++++                                              | 6 % ~19s          
  |++++                                              | 7 % ~19s          
  |+++++                                             | 8 % ~19s          
  |+++++                                             | 9 % ~18s          
  |++++++                                            | 10% ~18s          
  |++++++                                            | 11% ~19s          
  |+++++++                                           | 12% ~18s          
  |+++++++                                           | 13% ~18s          
  |++++++++                                          | 14% ~18s          
  |++++++++                                          | 15% ~17s          
  |+++++++++                                         | 16% ~17s          
  |+++++++++                                         | 17% ~16s          
  |++++++++++                                        | 18% ~16s          
  |++++++++++                                        | 19% ~16s          
  |+++++++++++                                       | 20% ~15s          
  |+++++++++++                                       | 21% ~15s          
  |++++++++++++                                      | 22% ~15s          
  |++++++++++++                                      | 23% ~14s          
  |+++++++++++++                                     | 24% ~14s          
  |+++++++++++++                                     | 25% ~14s          
  |++++++++++++++                                    | 26% ~14s          
  |++++++++++++++                                    | 27% ~13s          
  |+++++++++++++++                                   | 28% ~13s          
  |+++++++++++++++                                   | 29% ~13s          
  |++++++++++++++++                                  | 30% ~13s          
  |++++++++++++++++                                  | 31% ~13s          
  |+++++++++++++++++                                 | 32% ~12s          
  |+++++++++++++++++                                 | 33% ~12s          
  |++++++++++++++++++                                | 34% ~12s          
  |++++++++++++++++++                                | 35% ~12s          
  |+++++++++++++++++++                               | 36% ~11s          
  |+++++++++++++++++++                               | 37% ~11s          
  |++++++++++++++++++++                              | 38% ~11s          
  |++++++++++++++++++++                              | 39% ~11s          
  |+++++++++++++++++++++                             | 40% ~11s          
  |+++++++++++++++++++++                             | 41% ~10s          
  |++++++++++++++++++++++                            | 42% ~10s          
  |++++++++++++++++++++++                            | 43% ~10s          
  |+++++++++++++++++++++++                           | 44% ~10s          
  |+++++++++++++++++++++++                           | 45% ~10s          
  |++++++++++++++++++++++++                          | 46% ~09s          
  |++++++++++++++++++++++++                          | 47% ~09s          
  |+++++++++++++++++++++++++                         | 48% ~09s          
  |+++++++++++++++++++++++++                         | 49% ~09s          
  |++++++++++++++++++++++++++                        | 51% ~09s          
  |++++++++++++++++++++++++++                        | 52% ~09s          
  |+++++++++++++++++++++++++++                       | 53% ~08s          
  |+++++++++++++++++++++++++++                       | 54% ~08s          
  |++++++++++++++++++++++++++++                      | 55% ~08s          
  |++++++++++++++++++++++++++++                      | 56% ~08s          
  |+++++++++++++++++++++++++++++                     | 57% ~08s          
  |+++++++++++++++++++++++++++++                     | 58% ~08s          
  |++++++++++++++++++++++++++++++                    | 59% ~07s          
  |++++++++++++++++++++++++++++++                    | 60% ~07s          
  |+++++++++++++++++++++++++++++++                   | 61% ~07s          
  |+++++++++++++++++++++++++++++++                   | 62% ~07s          
  |++++++++++++++++++++++++++++++++                  | 63% ~07s          
  |++++++++++++++++++++++++++++++++                  | 64% ~06s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~06s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~06s          
  |++++++++++++++++++++++++++++++++++                | 67% ~06s          
  |++++++++++++++++++++++++++++++++++                | 68% ~06s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~06s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~05s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~05s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~05s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~05s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~05s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~04s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~04s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~04s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~04s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~04s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=18s  
updeg = markers %>% filter(p_val_adj<0.05 & avg_log2FC>0) %>% rownames()

new_hif_targets = hif_targets[!hif_targets %in% updeg]
hif_targets_by_tp = FetchData(object = xeno,vars = c(new_hif_targets)) %>% rowSums() %>% as.data.frame() #mean expression

Warning in FetchData.Seurat(object = xeno, vars = c(new_hif_targets)) : The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1

  hif_targets_by_tp[,2] = xeno$Hypoxia
  
  names(hif_targets_by_tp) = c("hif_targets","hypoxia_program")
  
  
  
  p1 = ggplot(hif_targets_by_tp, aes(x=hif_targets, y=hypoxia_program)) + 
      geom_point()+
    geom_density_2d(aes(color = ..level..)) +
    geom_smooth(method=lm) +
    stat_cor(method = "pearson", label.x = 20, label.y = 1.1)+
    scale_color_viridis_c()
  
  p2 = ggplot(hif_targets_by_tp, aes(x=hif_targets, y=hypoxia_program)) + 
    geom_bin2d() +
    theme_bw()+ scale_fill_gradientn(limits=c(0,1100), breaks=seq(0, 1100, by=200), colours=c("blue","yellow","red"))+ 
    stat_cor(method = "pearson", label.x = 20, label.y = 1.1)+
    geom_smooth(method=lm) 
  
  p = ggarrange(plotlist = list(p1,p2),nrow  = 2)  

geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’

  
  print_tab(plt = p,title = "geom_bin2d")

geom_bin2d

NA

upreg_hif_targets = hif_targets[hif_targets %in% updeg]
upreg_hif_targets_expr = FetchData(object = xeno,vars = c(upreg_hif_targets)) %>% rowSums() %>% as.data.frame() #mean expression
xeno = AddMetaData(object = xeno, metadata = upreg_hif_targets_expr,col.name = "upreg_hif_targets_score")
FeaturePlot(object = xeno,features = "upreg_hif_targets_score")

14 Calculate usage without cc in sum to 1

import numpy as np
import scanpy as sc
xeno_expression = r.xeno_expression
xeno_vargenes = r.xeno_vargenes
tpm =  compute_tpm(xeno_expression)
usage_by_calc = get_usage_from_score(counts=xeno_expression,tpm=tpm,genes=xeno_vargenes, cnmf_obj=cnmf_obj,k=3)
/sci/labs/yotamd/lab_share/avishai.wizel/python_envs/miniconda/envs/cnmf_env_6/bin/python3.7:7: FutureWarning: X.dtype being converted to np.float32 from float64. In the next version of anndata (0.9) conversion will not be automatic. Pass dtype explicitly to avoid this warning. Pass `AnnData(X, dtype=X.dtype, ...)` to get the future behavour.
/sci/labs/yotamd/lab_share/avishai.wizel/python_envs/miniconda/envs/cnmf_env_6/bin/python3.7:8: FutureWarning: X.dtype being converted to np.float32 from float64. In the next version of anndata (0.9) conversion will not be automatic. Pass dtype explicitly to avoid this warning. Pass `AnnData(X, dtype=X.dtype, ...)` to get the future behavour.
all_metagenes_noSumTo1 = py$usage_by_calc
tnf_and_hypoxia = all_metagenes_noSumTo1[,1:2]
tnf_and_hypoxia = apply(X = tnf_and_hypoxia, MARGIN = 1, sum_2_one) %>% t() %>%  as.data.frame()
tnf_and_hypoxia[is.na(tnf_and_hypoxia)] <- 0 #replace NAN's with 0.
# plot correlation for every subset of hif targets
for (genes in list(hif_targets,xeno_cluster_3_genes,xeno_cluster_3_2_genes)) {
  hif_targets_by_tp = FetchData(object = xeno,vars = c(genes)) %>% rowSums() %>% as.data.frame() #mean expression
  hif_targets_by_tp[,2] = tnf_and_hypoxia[,1]
  # hif_targets_by_tp[,2] = xeno$Hypoxia
  
  names(hif_targets_by_tp) = c("hif_targets","hypoxia_program")
  
  
  
  p1 = ggplot(hif_targets_by_tp, aes(x=hif_targets, y=hypoxia_program)) + 
      geom_point()+
    geom_density_2d(aes(color = ..level..)) +
    geom_smooth(method=lm) +
    stat_cor(method = "pearson", label.x = 20, label.y = 1.1)+
    scale_color_viridis_c()
  
  p2 = ggplot(hif_targets_by_tp, aes(x=hif_targets, y=hypoxia_program)) + 
    geom_bin2d() +
    theme_bw()+ scale_fill_gradientn(limits=c(0,1100), breaks=seq(0, 1100, by=200), colours=c("blue","yellow","red"))+ 
    stat_cor(method = "pearson", label.x = 20, label.y = 1.1)+
    geom_smooth(method=lm) 
  
  p = ggarrange(plotlist = list(p1,p2),nrow  = 2)  
  
  print_tab(plt = p,title = "geom_bin2d")
}

Warning in FetchData.Seurat(object = xeno, vars = c(genes)) : The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1 geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’ ## geom_bin2d {.unnumbered }

geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’ ## geom_bin2d {.unnumbered }

geom_smooth() using formula ‘y ~ x’ geom_smooth() using formula ‘y ~ x’ ## geom_bin2d {.unnumbered }

NA

15 UMAPS

hif_targets_by_tp = FetchData(object = xeno,vars = c(hif_targets)) %>% rowSums() %>% as.data.frame() #mean expression
Warning in FetchData.Seurat(object = xeno, vars = c(hif_targets)) :
  The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1
hif_targets_by_tp[,2] = tnf_and_hypoxia[,1]
names(hif_targets_by_tp) = c("hif_targets","hypoxia_program")

high_hif_low_hypoxia_cells = hif_targets_by_tp %>% filter(hif_targets>25 & hypoxia_program < 0.2) %>% rownames()

hif_targets_by_tp = FetchData(object = xeno,vars = c(hif_targets)) %>% rowSums() %>% as.data.frame() #mean expression
Warning in FetchData.Seurat(object = xeno, vars = c(hif_targets)) :
  The following requested variables were not found: AK4P1, BNIP3P1, LDHAP5, AL158201.1, MIR210, NLRP3P1, AL109946.1
xeno = AddMetaData(object = xeno, metadata = hif_targets_by_tp,col.name = "HIF_targets_score")
xeno = AddMetaData(object = xeno, metadata = tnf_and_hypoxia[,1],col.name = "Hypoxia2")

DimPlot(object = xeno, cells.highlight = high_hif_low_hypoxia_cells, cols.highlight = "red", cols = "gray", order = TRUE)

FeaturePlot(object = xeno,features = c( "HIF_targets_score","Hypoxia2","Cell_cycle" ))

FeaturePlot(object = xeno,features = c("Hypoxia2"))

DimPlot(object = xeno,group.by = "orig.ident")

16 Hypoxia raw

xeno = AddMetaData(object = xeno,metadata = all_metagenes_noSumTo1[,1],col.name = "hypoxia_raw")
FeaturePlot(object = xeno,features = "hypoxia_raw") + scale_color_gradientn(colours = rainbow(5), limits = c(0, 3000))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.

LS0tCnRpdGxlOiAnYHIgcnN0dWRpb2FwaTo6Z2V0U291cmNlRWRpdG9yQ29udGV4dCgpJHBhdGggJT4lIGJhc2VuYW1lKCkgJT4lIGdzdWIocGF0dGVybiA9ICJcXC5SbWQiLHJlcGxhY2VtZW50ID0gIiIpYCcgCmF1dGhvcjogIkF2aXNoYWkgV2l6ZWwiCmRhdGU6ICdgciBTeXMudGltZSgpYCcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOiAKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdG9jOiB5ZXMKICAgIHRvY19jb2xsYXBzZTogeWVzCiAgICB0b2NfZmxvYXQ6IAogICAgICBjb2xsYXBzZWQ6IEZBTFNFCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHRvY19kZXB0aDogMQotLS0KCiMgUGFyYW1ldGVycwoKYGBge3Igd2FybmluZz1GQUxTRX0KCmBgYAoKCiMgRnVuY3Rpb25zCgpgYGB7ciB3YXJuaW5nPUZBTFNFfQoKbGlicmFyeShzdHJpbmdpKQpsaWJyYXJ5KHJldGljdWxhdGUpCnNvdXJjZV9mcm9tX2dpdGh1YihyZXBvc2l0b3kgPSAiREVHX2Z1bmN0aW9ucyIsdmVyc2lvbiA9ICIwLjIuMjQiKQpzb3VyY2VfZnJvbV9naXRodWIocmVwb3NpdG95ID0gImNOTUZfZnVuY3Rpb25zIix2ZXJzaW9uID0gIjAuMy44NSIsc2NyaXB0X25hbWUgPSAiY25tZl9mdW5jdGlvbl9IYXJtb255LlIiKQoKbm9fbmVnIDwtIGZ1bmN0aW9uKHgpIHsKICB4ID0geCArIGFicyhtaW4oeCkpCiAgeAp9CgpzdW1fMl9vbmUgPC0gZnVuY3Rpb24oeCkgewogIHggPXgvc3VtKHgpCiAgeAp9CmBgYAoKCiMgRGF0YQoKYGBge3IgcmVhZF9kYXRhfQp4ZW5vID0gcmVhZFJEUygiLi9EYXRhLzEweF94ZW5vXzEwMDAuUmRzIikKbHVuZyA9IHJlYWRSRFMoIi4vRGF0YS9sdW5nX2NhbmNlcmNlbGxzX3dpdGhUUF9vbmx5UGF0aWVudHMucmRzIikKbHVuZ19wYXRpZW50cyA9IGx1bmckcGF0aWVudC5pZGVudCAlPiUgdW5pcXVlKCkgJT4lIGFzLmNoYXJhY3RlcigpCmx1bmdfcGF0aWVudHNfZmlsdGVyZWQgPSBsdW5nX3BhdGllbnRzWyEobHVuZ19wYXRpZW50cyAlaW4lIGMoIlgxMDU1bmV3IiwiWDEwOTkiKSldICMgcmVtb3ZlIHBhdGllbnRzIHdpdGggbGVzcyB0aGFuIDEwMCBtYWxpZ25hbnQgY2VsbHMKbHVuZyA9IHN1YnNldCh4ID0gbHVuZyxzdWJzZXQgPSBwYXRpZW50LmlkZW50ICVpbiUgbHVuZ19wYXRpZW50c19maWx0ZXJlZCkKYGBgCgojIE1vZGVscyAySyB2YXJnZW5lcyAKCmBgYHtweXRob259CnN1ZmZpeCA9IHIuc3VmZml4CmltcG9ydCBwaWNrbGUKZnJvbSBjbm1mIGltcG9ydCBjTk1GCmYgPSBvcGVuKCcuL0RhdGEvY25tZi9jbm1mX29iamVjdHMvbW9kZWxzXzJLdmFyZ2VuZXNfY25tZl9vYmoucGNrbCcsICdyYicpCmNubWZfb2JqID0gcGlja2xlLmxvYWQoZikKZi5jbG9zZSgpCmBgYAoKYGBge3J9CiMgZ2VwX3Njb3JlcyA9IHJlYWRSRFMoIi9zY2kvbGFicy95b3RhbWQvbGFiX3NoYXJlL2F2aXNoYWkud2l6ZWwvUl9wcm9qZWN0cy9FR0ZSL0RhdGEvY25tZi9oYXJtb255X21vZGVsc19nZXBfc2NvcmVzLnJkcyIpCmBgYAoKCmBgYHtweXRob259CnNlbGVjdGVkX2sgPSAzCmRlbnNpdHlfdGhyZXNob2xkID0gMC4xCiMgY25tZl9vYmouY29uc2Vuc3VzKGs9c2VsZWN0ZWRfaywgZGVuc2l0eV90aHJlc2hvbGQ9ZGVuc2l0eV90aHJlc2hvbGQpCnVzYWdlX25vcm0sIGdlcF9zY29yZXMsIGdlcF90cG0sIHRvcGdlbmVzID0gY25tZl9vYmoubG9hZF9yZXN1bHRzKEs9c2VsZWN0ZWRfaywgZGVuc2l0eV90aHJlc2hvbGQ9ZGVuc2l0eV90aHJlc2hvbGQpCmBgYAoKIyBwcm9ncmFtcyBlbnJpY2htZW50CgoKCmBgYHtyfQpnZXBfc2NvcmVzID0gcHkkZ2VwX3Njb3JlcwpnZXBfdHBtID0gcHkkZ2VwX3RwbQp1c2FnZV9ub3JtPSBweSR1c2FnZV9ub3JtCmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9Cm5hbWVzIChnZXBfc2NvcmVzKSA9IGMoIkh5cG94aWEiLCJUTkZhIiwiQ2VsbF9jeWNsZSIpCnBsdF9saXN0ID0gbGlzdCgpCgpmb3IgKHByb2dyYW0gIGluIG5hbWVzIChnZXBfc2NvcmVzKSkgewogcCA9IGdncGxvdChnZXBfc2NvcmVzLCBhZXMoeD0hIWVuc3ltKHByb2dyYW0pKSkgKwogIGdlb21fZGVuc2l0eSgpK3hsYWIocHJvZ3JhbSkrCiAgIGdlb21fdmxpbmUoCiAgICBhZXMoeGludGVyY2VwdD1zb3J0KGdlcF9zY29yZXNbLHByb2dyYW1dLFRSVUUpWzIwMF0gICxjb2xvcj0idG9wMjAwIiksCiAgICAgICAgICBsaW5ldHlwZT0iZGFzaGVkIiwgc2l6ZT0xKSsKICAgZ2VvbV92bGluZSgKICAgIGFlcyh4aW50ZXJjZXB0PXNvcnQoZ2VwX3Njb3Jlc1sscHJvZ3JhbV0sVFJVRSlbMTAwXSAgLGNvbG9yPSJ0b3AxMDAiKSwKICAgICAgICAgIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpKwogICAgICBnZW9tX3ZsaW5lKAogICAgYWVzKHhpbnRlcmNlcHQ9c29ydChnZXBfc2NvcmVzWyxwcm9ncmFtXSxUUlVFKVs1MF0gICxjb2xvcj0idG9wNTAiKSwKICAgICAgICAgIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpKwogICAgICAgICBnZW9tX3ZsaW5lKAogICAgYWVzKHhpbnRlcmNlcHQ9c29ydChnZXBfc2NvcmVzWyxwcm9ncmFtXSxUUlVFKVsxNTBdICAsY29sb3I9InRvcDE1MCIpLAogICAgICAgICAgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkrCiAgIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lID0gInRvcCBuIGdlbmVzIiwgdmFsdWVzID0gYyh0b3AyMDAgPSAiYmx1ZSIsdG9wMTAwID0gInJlZCIsdG9wMTUwID0gInllbGxvdyIsdG9wNTAgPSAiZ3JlZW4iKSkKICAgcGx0X2xpc3RbW3Byb2dyYW1dXSA8LSBwCgp9CiAKZ2dhcnJhbmdlKHBsb3RsaXN0ID0gcGx0X2xpc3QpCgpgYGAKCgoKCgoKCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIHJlc3VsdHM9J2hpZGUnfQpudG9wID0gMTUwCnBsdF9saXN0ID0gbGlzdCgpCmhpZl90YXJnZXRzX3NldCA9IGRhdGEuZnJhbWUoZ3NfbmFtZSA9ICJoaWZfdGFyZ2V0cyIsZ2VuZV9zeW1ib2wgPSBoaWZfdGFyZ2V0cykKCmZvciAoaSBpbiAxOm5jb2woZ2VwX3Njb3JlcykpIHsKICB0b3BfZ2VuZXMgPSBnZXBfc2NvcmVzICAlPiUgIGFycmFuZ2UoZGVzYyhnZXBfc2NvcmVzW2ldKSkgI3NvcnQgYnkgc2NvcmUgYQogIHRvcCA9IGhlYWQocm93bmFtZXModG9wX2dlbmVzKSxudG9wKSAjdGFrZSB0b3AgdG9wX2dlbmVzX251bQogIHJlcyA9IGdlbmVzX3ZlY19lbnJpY2htZW50KGdlbmVzID0gdG9wLGJhY2tncm91bmQgPSByb3duYW1lcyhnZXBfc2NvcmVzKSxob21lciA9IFQsdGl0bGUgPSAKICAgICAgICAgICAgICAgICAgICBpLHNpbGVudCA9IFQscmV0dXJuX2FsbCA9IFQsY3VzdG9tX3BhdGh3YXlzICA9IGhpZl90YXJnZXRzX3NldCkKICAgCiAgcGx0X2xpc3RbW2ldXSA9IHJlcyRwbHQKfQpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZShncm9icyA9IHBsdF9saXN0KQpgYGAKCgoKYGBge3J9Cnhlbm8gPSBGaW5kVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSB4ZW5vLG5mZWF0dXJlcyA9IDIwMDApCnhlbm9fdmFyZ2VuZXMgPSBWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IHhlbm8pCgp4ZW5vX2V4cHJlc3Npb24gPSBGZXRjaERhdGEob2JqZWN0ID0geGVubyx2YXJzID0geGVub192YXJnZW5lcyxzbG90PSdjb3VudHMnKQphbGxfMF9nZW5lcyA9IGNvbG5hbWVzKHhlbm9fZXhwcmVzc2lvbilbY29sU3Vtcyh4ZW5vX2V4cHJlc3Npb249PTAsIG5hLnJtPVRSVUUpPT1ucm93KHhlbm9fZXhwcmVzc2lvbildICNkZWxldGUgcm93cyB0aGF0IGhhdmUgYWxsIDAKeGVub192YXJnZW5lcyA9IHhlbm9fdmFyZ2VuZXNbIXhlbm9fdmFyZ2VuZXMgJWluJSBhbGxfMF9nZW5lc10KCmBgYAoKCgoKIyBUZXN0IHdpdGggZXhwciBhZnRlciBoYXJtb255CmBgYHtweXRob259CmltcG9ydCBudW1weSBhcyBucAppbXBvcnQgc2NhbnB5IGFzIHNjCgpleHByX2FmdGVyX2hhcm1vbnkgPSBzYy5yZWFkX2g1YWQoJy4vRGF0YS9jbm1mL3hlbm9fSGFybW9ueV9Ob05lZ18yS3ZhcmdlbmVzLmg1YWQnKS50b19kZigpCnRwbSA9ICBjb21wdXRlX3RwbShleHByX2FmdGVyX2hhcm1vbnkpCmNubWZfZ2VuZXMgPSBleHByX2FmdGVyX2hhcm1vbnkua2V5cygpLnRvX2xpc3QoKQp1c2FnZV9ieV9jYWxjID0gZ2V0X3VzYWdlX2Zyb21fc2NvcmUoY291bnRzPWV4cHJfYWZ0ZXJfaGFybW9ueSx0cG09dHBtLGdlbmVzPWNubWZfZ2VuZXMsY25tZl9vYmo9Y25tZl9vYmosaz0zKQpgYGAKCiMgQ2hlY2sgaWYgb3JpZ2luYWwgY05NRiBzY29yZSBpcyBsaWtlIHRoZSBjYWxjdWxhdGVkIHNjb3JlCmBgYHtyfQp1c2FnZV9ieV9jYWxjID0gcHkkdXNhZ2VfYnlfY2FsYwp1c2FnZV9ub3JtID0gcHkkdXNhZ2Vfbm9ybQpjb3IodXNhZ2VfYnlfY2FsYyx1c2FnZV9ub3JtKQpgYGAKCiMgY2FsY3VsYXRlIHNjb3JlIGZvciBYZW5vCmBgYHtweXRob259CmltcG9ydCBudW1weSBhcyBucAppbXBvcnQgc2NhbnB5IGFzIHNjCnhlbm9fZXhwcmVzc2lvbiA9IHIueGVub19leHByZXNzaW9uCnhlbm9fdmFyZ2VuZXMgPSByLnhlbm9fdmFyZ2VuZXMKdHBtID0gIGNvbXB1dGVfdHBtKHhlbm9fZXhwcmVzc2lvbikKdXNhZ2VfYnlfY2FsYyA9IGdldF91c2FnZV9mcm9tX3Njb3JlKGNvdW50cz14ZW5vX2V4cHJlc3Npb24sdHBtPXRwbSxnZW5lcz14ZW5vX3ZhcmdlbmVzLCBjbm1mX29iaj1jbm1mX29iaixrPTMpCmBgYAoKYGBge3J9CmFsbF9tZXRhZ2VuZXMgPSBweSR1c2FnZV9ieV9jYWxjCmBgYAoKIyBwcm9ncmFtcyBleHByZXNzaW9uIHsudGFic2V0fQpgYGB7ciBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTksIHJlc3VsdHM9J2FzaXMnfQoKbmFtZXMgKGFsbF9tZXRhZ2VuZXMpID0gYygiSHlwb3hpYSIsIlRORmEiLCJDZWxsX2N5Y2xlIikKI2FkZCBlYWNoIG1ldGFnZW5lIHRvIG1ldGFkYXRhCmZvciAoaSAgaW4gMTpuY29sKGFsbF9tZXRhZ2VuZXMpKSB7CiAgbWV0YWdlX21ldGFkYXRhID0gYWxsX21ldGFnZW5lcyAlPiUgZHBseXI6OnNlbGVjdChpKQogICMgbWV0YWdlX21ldGFkYXRhID0gc2NhbGUobWV0YWdlX21ldGFkYXRhKQogIHhlbm8gPSBBZGRNZXRhRGF0YShvYmplY3QgPSB4ZW5vLG1ldGFkYXRhID0gbWV0YWdlX21ldGFkYXRhLGNvbC5uYW1lID0gbmFtZXMoYWxsX21ldGFnZW5lcylbaV0pCn0KCnByaW50X3RhYihwbHQgPSBGZWF0dXJlUGxvdChvYmplY3QgPSB4ZW5vLGZlYXR1cmVzID0gY29sbmFtZXMoYWxsX21ldGFnZW5lcykpLHRpdGxlID0gInVtYXAgZXhwcmVzc2lvbiIpCgoKYGBgCgoKCiMgcHJvZ3JhbXMgcmVndWxhdGlvbiB7LnRhYnNldH0KYGBge3IgZWNobz1UUlVFLCAgcmVzdWx0cz0nYXNpcyd9Cm1ldGFnZW5lc19tZWFuX2NvbXBhcmUoZGF0YXNldCA9IHhlbm8sdGltZS5wb2ludF92YXIgPSAidHJlYXRtZW50IixwcmVmaXggPSAibW9kZWwiLHBhdGllbnQuaWRlbnRfdmFyID0gIm9yaWcuaWRlbnQiLHByZV9vbiA9IGMoIk5UIiwiT1NJIiksdGVzdCA9ICJ3aWxjb3gudGVzdCIscHJvZ3JhbXMgPSBjKCJIeXBveGlhIiwiVE5GYSIsIkNlbGxfY3ljbGUiKSkKCmBgYAoKCgpgYGB7cn0KaGFsbG1hcmtfbmFtZSA9ICJHT19NSVRPVElDX0NFTExfQ1lDTEUiCmdlbmVzZXRzICA9Z2V0R210KCIuL0RhdGEvaC5hbGwudjcuMC5zeW1ib2xzLnBsdXNjYy5nbXQiKQp2YXJfZmVhdHVyZXM9eGVub0Bhc3NheXMkUk5BQHZhci5mZWF0dXJlcwpnZW5lSWRzPSBnZW5lc2V0c1tbaGFsbG1hcmtfbmFtZV1dQGdlbmVJZHMKc2NvcmUgPC0gYXBwbHkoeGVub0Bhc3NheXMkUk5BQGRhdGFbaW50ZXJzZWN0KGdlbmVJZHMsdmFyX2ZlYXR1cmVzKSxdLDIsbWVhbikKeGVubz1BZGRNZXRhRGF0YSh4ZW5vLHNjb3JlLCJHT19NSVRPVElDX0NDIikKYGBgCgpgYGB7ciBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQptZXRhZ2VuZXNfbWVhbl9jb21wYXJlKGRhdGFzZXQgPSB4ZW5vLHRpbWUucG9pbnRfdmFyID0gInRyZWF0bWVudCIscHJlZml4ID0gIm1vZGVsIixwYXRpZW50LmlkZW50X3ZhciA9ICJvcmlnLmlkZW50IixwcmVfb24gPSBjKCJOVCIsIk9TSSIsInJlcyIpLHByb2dyYW1zID0gYygiR09fTUlUT1RJQ19DQyIpKQoKYGBgCmBgYHtyfQpEb3RQbG90KG9iamVjdCA9IHhlbm8sIGZlYXR1cmVzID0gIGMoIkh5cG94aWEiLCJUTkZhIiwiQ2VsbF9jeWNsZSIsIkdPX01JVE9USUNfQ0MiKSxzY2FsZSA9IEYsZ3JvdXAuYnkgID0gJ3RyZWF0bWVudCcpCmBgYAoKYGBge3J9CkRvdFBsb3Qob2JqZWN0ID0geGVubywgZmVhdHVyZXMgPSAgYygiSHlwb3hpYSIsIlRORmEiLCJDZWxsX2N5Y2xlIiwiR09fTUlUT1RJQ19DQyIpLHNjYWxlID0gVCxncm91cC5ieSAgPSAndHJlYXRtZW50JykKYGBgCgojIHByb2dyYW0gYXNzaWdubWVudCB7LnRhYnNldH0KYGBge3J9Cmxhcmdlcl9ieSA9IDEuNQp4ZW5vID0gcHJvZ3JhbV9hc3NpZ25tZW50KGRhdGFzZXQgPSB4ZW5vLGxhcmdlcl9ieSA9IGxhcmdlcl9ieSxwcm9ncmFtX25hbWVzID0gY29sbmFtZXMoYWxsX21ldGFnZW5lcykpCmBgYCAKCmBgYHtyIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgRGltUGxvdCh4ZW5vLGdyb3VwLmJ5ID0gInByb2dyYW0uYXNzaWdubWVudCIsY29scyA9IGMoSHlwb3hpYSA9ICJyZWQiLFRORmEgPSAiZ3JlZW4iLENlbGxfY3ljbGUgPSAiYmx1ZSIsIk5BIiA9ICJncmV5IikpCiAgICAgICAgICAsdGl0bGUgPSAicHJvZ3JhbS5hc3NpZ25tZW50IixzdWJ0aXRsZV9udW0gPSAyKQpwcmludF90YWIocGx0ID0gCiAgICAgICAgICAgICAgRGltUGxvdCh4ZW5vLGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKQogICAgICAgICAgLHRpdGxlID0gIm9yaWcuaWRlbnQiLHN1YnRpdGxlX251bSA9IDIpCnByaW50X3RhYihwbHQgPSAKICAgICAgICAgICAgRGltUGxvdCh4ZW5vLGdyb3VwLmJ5ID0gInRyZWF0bWVudCIpCiAgICAgICAgICAsdGl0bGUgPSAidHJlYXRtZW50IixzdWJ0aXRsZV9udW0gPSAyKQoKcCA9IGNlbGxfcGVyY2VudGFnZShkYXRhc2V0ID0geGVubyx0aW1lLnBvaW50X3ZhciA9ICJ0cmVhdG1lbnQiLGJ5X3Byb2dyYW0gPSBULHhfb3JkZXIgPSBjKCJOVCIsIk9TSSIsInJlcyIpKQpwcmludF90YWIocGx0ID0gcCx0aXRsZSA9ICJieSBwcm9ncmFtIixzdWJ0aXRsZV9udW0gPSAyKQoKcCA9IGNlbGxfcGVyY2VudGFnZShkYXRhc2V0ID0geGVubyx0aW1lLnBvaW50X3ZhciA9ICJ0cmVhdG1lbnQiLGJ5X3RwICA9IFQseF9vcmRlciA9YygiSHlwb3hpYSIsIlRORmEiLCJDZWxsX2N5Y2xlIiwiTkEiKSkKcHJpbnRfdGFiKHBsdCA9IHAsdGl0bGUgPSAiYnkgdGltZSBwb2ludCIsc3VidGl0bGVfbnVtID0gMikKCgpgYGAKCgpgYGB7cn0KdG9wX2dlbmVzID0gZ2VwX3Njb3JlcyAgJT4lICBhcnJhbmdlKGRlc2MoZ2VwX3Njb3Jlc1siSHlwb3hpYSJdKSkgI3NvcnQgYnkgc2NvcmUgYQpoeXBveGlhX2dlbmVzID0gaGVhZChyb3duYW1lcyh0b3BfZ2VuZXMpLDIwKSAjdGFrZSB0b3AgdG9wX2dlbmVzX251bQppbnRlcnNlY3QoY2x1c3Rlcl8zX2dlbmVzLGh5cG94aWFfZ2VuZXMpCmBgYAoKYGBge3J9CmxpYnJhcnkoZ2d2ZW5uKQphbGwgPSBsaXN0KGh5cG94aWFfZ2VuZXMgPSBoeXBveGlhX2dlbmVzLCBoaWZfdGFyZ2V0cyA9IGNsdXN0ZXJfM19nZW5lcykKZ2d2ZW5uKAogIGFsbAopCmBgYAoKCgojIEhJRl90YXJnZXRzLSBIeXBveGlhIGNvcnJlbGF0aW9uICB7LnRhYnNldH0KYGBge3IgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD02LCByZXN1bHRzPSdhc2lzJ30KIyBwbG90IGNvcnJlbGF0aW9uIGZvciBldmVyeSBzdWJzZXQgb2YgaGlmIHRhcmdldHMKZm9yIChnZW5lcyBpbiBsaXN0KGhpZl90YXJnZXRzLHhlbm9fY2x1c3Rlcl8zX2dlbmVzLHhlbm9fY2x1c3Rlcl8zXzJfZ2VuZXMpKSB7CiAgaGlmX3RhcmdldHNfYnlfdHAgPSBGZXRjaERhdGEob2JqZWN0ID0geGVubyx2YXJzID0gYyhnZW5lcykpICU+JSByb3dTdW1zKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSAjbWVhbiBleHByZXNzaW9uCiAgaGlmX3RhcmdldHNfYnlfdHBbLDJdID0geGVubyRIeXBveGlhCiAgCiAgbmFtZXMoaGlmX3RhcmdldHNfYnlfdHApID0gYygiaGlmX3RhcmdldHMiLCJoeXBveGlhX3Byb2dyYW0iKQogIAogIAogIAogIHAxID0gZ2dwbG90KGhpZl90YXJnZXRzX2J5X3RwLCBhZXMoeD1oaWZfdGFyZ2V0cywgeT1oeXBveGlhX3Byb2dyYW0pKSArIAogICAgICBnZW9tX3BvaW50KCkrCiAgICBnZW9tX2RlbnNpdHlfMmQoYWVzKGNvbG9yID0gLi5sZXZlbC4uKSkgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSArCiAgICBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIsIGxhYmVsLnggPSAyMCwgbGFiZWwueSA9IDEuMSkrCiAgICBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKQogIAogIHAyID0gZ2dwbG90KGhpZl90YXJnZXRzX2J5X3RwLCBhZXMoeD1oaWZfdGFyZ2V0cywgeT1oeXBveGlhX3Byb2dyYW0pKSArIAogICAgZ2VvbV9iaW4yZCgpICsKICAgIHRoZW1lX2J3KCkrIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGxpbWl0cz1jKDAsMTEwMCksIGJyZWFrcz1zZXEoMCwgMTEwMCwgYnk9MjAwKSwgY29sb3Vycz1jKCJibHVlIiwieWVsbG93IiwicmVkIikpKyAKICAgIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIiwgbGFiZWwueCA9IDIwLCBsYWJlbC55ID0gMS4xKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZD1sbSkgCiAgCiAgcCA9IGdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIpLG5yb3cgID0gMikgIAogIAogIHByaW50X3RhYihwbHQgPSBwLHRpdGxlID0gImdlb21fYmluMmQiKQp9CgoKYGBgCgoKIyBVTUFQUwpgYGB7ciBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD0xMH0KaGlmX3RhcmdldHNfYnlfdHAgPSBGZXRjaERhdGEob2JqZWN0ID0geGVubyx2YXJzID0gYyhoaWZfdGFyZ2V0cykpICU+JSByb3dTdW1zKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSAjbWVhbiBleHByZXNzaW9uCmhpZl90YXJnZXRzX2J5X3RwWywyXSA9IHhlbm8kSHlwb3hpYQpuYW1lcyhoaWZfdGFyZ2V0c19ieV90cCkgPSBjKCJoaWZfdGFyZ2V0cyIsImh5cG94aWFfcHJvZ3JhbSIpCgpoaWdoX2hpZl9sb3dfaHlwb3hpYV9jZWxscyA9IGhpZl90YXJnZXRzX2J5X3RwICU+JSBmaWx0ZXIoaGlmX3RhcmdldHM+MjUgJiBoeXBveGlhX3Byb2dyYW0gPCAwLjIpICU+JSByb3duYW1lcygpCmxvd19oaWZfaGlnaF9oeXBveGlhX2NlbGxzID0gaGlmX3RhcmdldHNfYnlfdHAgJT4lIGZpbHRlcihoaWZfdGFyZ2V0czwxNSAmIGh5cG94aWFfcHJvZ3JhbSA+IDAuNikgJT4lIHJvd25hbWVzKCkKCmhpZl90YXJnZXRzX2J5X3RwID0gRmV0Y2hEYXRhKG9iamVjdCA9IHhlbm8sdmFycyA9IGMoaGlmX3RhcmdldHMpKSAlPiUgcm93U3VtcygpICU+JSBhcy5kYXRhLmZyYW1lKCkgI21lYW4gZXhwcmVzc2lvbgp4ZW5vID0gQWRkTWV0YURhdGEob2JqZWN0ID0geGVubywgbWV0YWRhdGEgPSBoaWZfdGFyZ2V0c19ieV90cCxjb2wubmFtZSA9ICJISUZfdGFyZ2V0c19zY29yZSIpCmNlbGxzX3RvX2hpZ2hsaWdodCA9ICBsaXN0KGhpZ2hfaGlmX2xvd19oeXBveGlhX2NlbGxzID0gaGlnaF9oaWZfbG93X2h5cG94aWFfY2VsbHMsIGxvd19oaWZfaGlnaF9oeXBveGlhX2NlbGxzID0gbG93X2hpZl9oaWdoX2h5cG94aWFfY2VsbHMpCgpEaW1QbG90KG9iamVjdCA9IHhlbm8sIGNlbGxzLmhpZ2hsaWdodCA9IGNlbGxzX3RvX2hpZ2hsaWdodCwgY29scy5oaWdobGlnaHQgPSBjKCJyZWQiLCJibHVlIiksIGNvbHMgPSAiZ3JheSIsIG9yZGVyID0gVFJVRSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0geGVubyxmZWF0dXJlcyA9IGMoICJISUZfdGFyZ2V0c19zY29yZSIsIkh5cG94aWEiLCJDZWxsX2N5Y2xlIiApKQoKYGBgCmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQpoaWZfaHlwb3hpYV9jb3JyZWxhdGVkX2NlbGxzID0gY29sbmFtZXMoeGVubykgWyFjb2xuYW1lcyh4ZW5vKSAlaW4lIGhpZ2hfaGlmX2xvd19oeXBveGlhX2NlbGxzICYgIWNvbG5hbWVzKHhlbm8pICVpbiUgaGlnaF9oaWZfbG93X2h5cG94aWFfY2VsbHNdCmhpZl90YXJnZXRzX3Njb3JlID0gRmV0Y2hEYXRhKG9iamVjdCA9IHhlbm8sdmFycyA9IGMoaGlmX3RhcmdldHMpKSAlPiUgcm93U3VtcygpICU+JSBhcy5kYXRhLmZyYW1lKCkgI21lYW4gZXhwcmVzc2lvbgpoaWZfdGFyZ2V0c19zY29yZVssMl0gPSB4ZW5vJEh5cG94aWEKbmFtZXMoaGlmX3RhcmdldHNfc2NvcmUpID0gYygiaGlmX3RhcmdldHMiLCJoeXBveGlhX3Byb2dyYW0iKQpoaWZfdGFyZ2V0c19zY29yZSAgPSBoaWZfdGFyZ2V0c19zY29yZSAlPiUgbXV0YXRlKHR5cGUgPSBjYXNlX3doZW4oaGlmX3RhcmdldHM+MjUgJiBoeXBveGlhX3Byb2dyYW0gPCAwLjIgfiAiaGlnaF9oaWZfbG93X2h5cG94aWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlmX3RhcmdldHM8MTUgJiBoeXBveGlhX3Byb2dyYW0gPiAwLjYgfiAibG93X2hpZl9oaWdoX2h5cG94aWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlmX3RhcmdldHM+MjUgJiBoeXBveGlhX3Byb2dyYW0gPiAwLjYgfiAiaGlnaF9oaWZfaGlnaF9oeXBveGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZl90YXJnZXRzPDE1ICYgaHlwb3hpYV9wcm9ncmFtIDwwLjIgfiAiaGlnaF9oaWZfaGlnaF9oeXBveGlhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAib3RoZXIiKSkKeGVubyA9IEFkZE1ldGFEYXRhKG9iamVjdCA9IHhlbm8sbWV0YWRhdGEgPSBoaWZfdGFyZ2V0c19zY29yZVssInR5cGUiLCBkcm9wID0gRl0sY29sLm5hbWUgPSAic2NvcmVfY29ycmVsYXRpb24iKQp4ZW5vID0gU2V0SWRlbnQob2JqZWN0ID0geGVubyx2YWx1ZSA9ICJzY29yZV9jb3JyZWxhdGlvbiIpCkRpbVBsb3Qob2JqZWN0ID0geGVubyxncm91cC5ieSA9ICJzY29yZV9jb3JyZWxhdGlvbiIpCm1hcmtlcnMgPSBGaW5kTWFya2VycyhvYmplY3QgPSB4ZW5vLCBpZGVudC4xID0gImhpZ2hfaGlmX2xvd19oeXBveGlhIixpZGVudC4yID0gImhpZ2hfaGlmX2hpZ2hfaHlwb3hpYSIsZGVuc2lmeSA9IFQpCmBgYApgYGB7ciBlY2hvPVRSVUUsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTYsIHJlc3VsdHM9J2FzaXMnfQp1cGRlZyA9IG1hcmtlcnMgJT4lIGZpbHRlcihwX3ZhbF9hZGo8MC4wNSAmIGF2Z19sb2cyRkM+MCkgJT4lIHJvd25hbWVzKCkKCm5ld19oaWZfdGFyZ2V0cyA9IGhpZl90YXJnZXRzWyFoaWZfdGFyZ2V0cyAlaW4lIHVwZGVnXQpoaWZfdGFyZ2V0c19ieV90cCA9IEZldGNoRGF0YShvYmplY3QgPSB4ZW5vLHZhcnMgPSBjKG5ld19oaWZfdGFyZ2V0cykpICU+JSByb3dTdW1zKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSAjbWVhbiBleHByZXNzaW9uCiAgaGlmX3RhcmdldHNfYnlfdHBbLDJdID0geGVubyRIeXBveGlhCiAgCiAgbmFtZXMoaGlmX3RhcmdldHNfYnlfdHApID0gYygiaGlmX3RhcmdldHMiLCJoeXBveGlhX3Byb2dyYW0iKQogIAogIAogIAogIHAxID0gZ2dwbG90KGhpZl90YXJnZXRzX2J5X3RwLCBhZXMoeD1oaWZfdGFyZ2V0cywgeT1oeXBveGlhX3Byb2dyYW0pKSArIAogICAgICBnZW9tX3BvaW50KCkrCiAgICBnZW9tX2RlbnNpdHlfMmQoYWVzKGNvbG9yID0gLi5sZXZlbC4uKSkgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSArCiAgICBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIsIGxhYmVsLnggPSAyMCwgbGFiZWwueSA9IDEuMSkrCiAgICBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKQogIAogIHAyID0gZ2dwbG90KGhpZl90YXJnZXRzX2J5X3RwLCBhZXMoeD1oaWZfdGFyZ2V0cywgeT1oeXBveGlhX3Byb2dyYW0pKSArIAogICAgZ2VvbV9iaW4yZCgpICsKICAgIHRoZW1lX2J3KCkrIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGxpbWl0cz1jKDAsMTEwMCksIGJyZWFrcz1zZXEoMCwgMTEwMCwgYnk9MjAwKSwgY29sb3Vycz1jKCJibHVlIiwieWVsbG93IiwicmVkIikpKyAKICAgIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIiwgbGFiZWwueCA9IDIwLCBsYWJlbC55ID0gMS4xKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZD1sbSkgCiAgCiAgcCA9IGdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIpLG5yb3cgID0gMikgIAogIAogIHByaW50X3RhYihwbHQgPSBwLHRpdGxlID0gImdlb21fYmluMmQiKQoKCmBgYAoKCmBgYHtyfQp1cHJlZ19oaWZfdGFyZ2V0cyA9IGhpZl90YXJnZXRzW2hpZl90YXJnZXRzICVpbiUgdXBkZWddCnVwcmVnX2hpZl90YXJnZXRzX2V4cHIgPSBGZXRjaERhdGEob2JqZWN0ID0geGVubyx2YXJzID0gYyh1cHJlZ19oaWZfdGFyZ2V0cykpICU+JSByb3dTdW1zKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSAjbWVhbiBleHByZXNzaW9uCnhlbm8gPSBBZGRNZXRhRGF0YShvYmplY3QgPSB4ZW5vLCBtZXRhZGF0YSA9IHVwcmVnX2hpZl90YXJnZXRzX2V4cHIsY29sLm5hbWUgPSAidXByZWdfaGlmX3RhcmdldHNfc2NvcmUiKQpGZWF0dXJlUGxvdChvYmplY3QgPSB4ZW5vLGZlYXR1cmVzID0gInVwcmVnX2hpZl90YXJnZXRzX3Njb3JlIikKYGBgCgoKIyBDYWxjdWxhdGUgdXNhZ2Ugd2l0aG91dCBjYyBpbiBzdW0gdG8gMQpgYGB7cHl0aG9ufQppbXBvcnQgbnVtcHkgYXMgbnAKaW1wb3J0IHNjYW5weSBhcyBzYwp4ZW5vX2V4cHJlc3Npb24gPSByLnhlbm9fZXhwcmVzc2lvbgp4ZW5vX3ZhcmdlbmVzID0gci54ZW5vX3ZhcmdlbmVzCnRwbSA9ICBjb21wdXRlX3RwbSh4ZW5vX2V4cHJlc3Npb24pCnVzYWdlX2J5X2NhbGMgPSBnZXRfdXNhZ2VfZnJvbV9zY29yZShjb3VudHM9eGVub19leHByZXNzaW9uLHRwbT10cG0sZ2VuZXM9eGVub192YXJnZW5lcywgY25tZl9vYmo9Y25tZl9vYmosaz0zLHN1bVRvMT1GYWxzZSkKYGBgCmBgYHtyfQphbGxfbWV0YWdlbmVzX25vU3VtVG8xID0gcHkkdXNhZ2VfYnlfY2FsYwp0bmZfYW5kX2h5cG94aWEgPSBhbGxfbWV0YWdlbmVzX25vU3VtVG8xWywxOjJdCnRuZl9hbmRfaHlwb3hpYSA9IGFwcGx5KFggPSB0bmZfYW5kX2h5cG94aWEsIE1BUkdJTiA9IDEsIHN1bV8yX29uZSkgJT4lIHQoKSAlPiUgIGFzLmRhdGEuZnJhbWUoKQp0bmZfYW5kX2h5cG94aWFbaXMubmEodG5mX2FuZF9oeXBveGlhKV0gPC0gMCAjcmVwbGFjZSBOQU4ncyB3aXRoIDAuCmBgYAoKYGBge3IgZWNobz1UUlVFLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD02LCByZXN1bHRzPSdhc2lzJ30KIyBwbG90IGNvcnJlbGF0aW9uIGZvciBldmVyeSBzdWJzZXQgb2YgaGlmIHRhcmdldHMKZm9yIChnZW5lcyBpbiBsaXN0KGhpZl90YXJnZXRzLHhlbm9fY2x1c3Rlcl8zX2dlbmVzLHhlbm9fY2x1c3Rlcl8zXzJfZ2VuZXMpKSB7CiAgaGlmX3RhcmdldHNfYnlfdHAgPSBGZXRjaERhdGEob2JqZWN0ID0geGVubyx2YXJzID0gYyhnZW5lcykpICU+JSByb3dTdW1zKCkgJT4lIGFzLmRhdGEuZnJhbWUoKSAjbWVhbiBleHByZXNzaW9uCiAgaGlmX3RhcmdldHNfYnlfdHBbLDJdID0gdG5mX2FuZF9oeXBveGlhWywxXQogICMgaGlmX3RhcmdldHNfYnlfdHBbLDJdID0geGVubyRIeXBveGlhCiAgCiAgbmFtZXMoaGlmX3RhcmdldHNfYnlfdHApID0gYygiaGlmX3RhcmdldHMiLCJoeXBveGlhX3Byb2dyYW0iKQogIAogIAogIAogIHAxID0gZ2dwbG90KGhpZl90YXJnZXRzX2J5X3RwLCBhZXMoeD1oaWZfdGFyZ2V0cywgeT1oeXBveGlhX3Byb2dyYW0pKSArIAogICAgICBnZW9tX3BvaW50KCkrCiAgICBnZW9tX2RlbnNpdHlfMmQoYWVzKGNvbG9yID0gLi5sZXZlbC4uKSkgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSArCiAgICBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIsIGxhYmVsLnggPSAyMCwgbGFiZWwueSA9IDEuMSkrCiAgICBzY2FsZV9jb2xvcl92aXJpZGlzX2MoKQogIAogIHAyID0gZ2dwbG90KGhpZl90YXJnZXRzX2J5X3RwLCBhZXMoeD1oaWZfdGFyZ2V0cywgeT1oeXBveGlhX3Byb2dyYW0pKSArIAogICAgZ2VvbV9iaW4yZCgpICsKICAgIHRoZW1lX2J3KCkrIHNjYWxlX2ZpbGxfZ3JhZGllbnRuKGxpbWl0cz1jKDAsMTEwMCksIGJyZWFrcz1zZXEoMCwgMTEwMCwgYnk9MjAwKSwgY29sb3Vycz1jKCJibHVlIiwieWVsbG93IiwicmVkIikpKyAKICAgIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIiwgbGFiZWwueCA9IDIwLCBsYWJlbC55ID0gMS4xKSsKICAgIGdlb21fc21vb3RoKG1ldGhvZD1sbSkgCiAgCiAgcCA9IGdnYXJyYW5nZShwbG90bGlzdCA9IGxpc3QocDEscDIpLG5yb3cgID0gMikgIAogIAogIHByaW50X3RhYihwbHQgPSBwLHRpdGxlID0gImdlb21fYmluMmQiKQp9CgoKYGBgCgojIFVNQVBTCmBgYHtyIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTh9CmhpZl90YXJnZXRzX2J5X3RwID0gRmV0Y2hEYXRhKG9iamVjdCA9IHhlbm8sdmFycyA9IGMoaGlmX3RhcmdldHMpKSAlPiUgcm93U3VtcygpICU+JSBhcy5kYXRhLmZyYW1lKCkgI21lYW4gZXhwcmVzc2lvbgpoaWZfdGFyZ2V0c19ieV90cFssMl0gPSB0bmZfYW5kX2h5cG94aWFbLDFdCm5hbWVzKGhpZl90YXJnZXRzX2J5X3RwKSA9IGMoImhpZl90YXJnZXRzIiwiaHlwb3hpYV9wcm9ncmFtIikKCmhpZ2hfaGlmX2xvd19oeXBveGlhX2NlbGxzID0gaGlmX3RhcmdldHNfYnlfdHAgJT4lIGZpbHRlcihoaWZfdGFyZ2V0cz4yNSAmIGh5cG94aWFfcHJvZ3JhbSA8IDAuMikgJT4lIHJvd25hbWVzKCkKCmhpZl90YXJnZXRzX2J5X3RwID0gRmV0Y2hEYXRhKG9iamVjdCA9IHhlbm8sdmFycyA9IGMoaGlmX3RhcmdldHMpKSAlPiUgcm93U3VtcygpICU+JSBhcy5kYXRhLmZyYW1lKCkgI21lYW4gZXhwcmVzc2lvbgp4ZW5vID0gQWRkTWV0YURhdGEob2JqZWN0ID0geGVubywgbWV0YWRhdGEgPSBoaWZfdGFyZ2V0c19ieV90cCxjb2wubmFtZSA9ICJISUZfdGFyZ2V0c19zY29yZSIpCnhlbm8gPSBBZGRNZXRhRGF0YShvYmplY3QgPSB4ZW5vLCBtZXRhZGF0YSA9IHRuZl9hbmRfaHlwb3hpYVssMV0sY29sLm5hbWUgPSAiSHlwb3hpYTIiKQoKRGltUGxvdChvYmplY3QgPSB4ZW5vLCBjZWxscy5oaWdobGlnaHQgPSBoaWdoX2hpZl9sb3dfaHlwb3hpYV9jZWxscywgY29scy5oaWdobGlnaHQgPSAicmVkIiwgY29scyA9ICJncmF5Iiwgb3JkZXIgPSBUUlVFKQpGZWF0dXJlUGxvdChvYmplY3QgPSB4ZW5vLGZlYXR1cmVzID0gYyggIkhJRl90YXJnZXRzX3Njb3JlIiwiSHlwb3hpYTIiLCJDZWxsX2N5Y2xlIiApKQpGZWF0dXJlUGxvdChvYmplY3QgPSB4ZW5vLGZlYXR1cmVzID0gYygiSHlwb3hpYTIiKSkKRGltUGxvdChvYmplY3QgPSB4ZW5vLGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKQoKYGBgCgojIEh5cG94aWEgcmF3CmBgYHtyIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTEwfQp4ZW5vID0gQWRkTWV0YURhdGEob2JqZWN0ID0geGVubyxtZXRhZGF0YSA9IGFsbF9tZXRhZ2VuZXNfbm9TdW1UbzFbLDFdLGNvbC5uYW1lID0gImh5cG94aWFfcmF3IikKRmVhdHVyZVBsb3Qob2JqZWN0ID0geGVubyxmZWF0dXJlcyA9ICJoeXBveGlhX3JhdyIpICsgc2NhbGVfY29sb3JfZ3JhZGllbnRuKGNvbG91cnMgPSByYWluYm93KDUpLCBsaW1pdHMgPSBjKDAsIDMwMDApKQpgYGAKCgoKPHNjcmlwdCBzcmM9Imh0dHBzOi8vaHlwb3RoZXMuaXMvZW1iZWQuanMiIGFzeW5jPjwvc2NyaXB0Pgo=