1 Overview

The samples contain 5 mutants and a wild-type (WT) control grown in several media and instilled in mice for 1 hour. This document uses the mouse raw reverse strand counts.

# https://haozhu233.github.io/kableExtra/awesome_table_in_html.html
#setwd("/Volumes/VTL_Lab_HQ/System/Volumes/Data/Users/VTL_Lab1/Documents/El-Husseini_Nour/rnaseq/ed")
library(kableExtra)
library(dplyr)
dt <- read.csv("ed_sample_table.csv")

dt %>% 
  filter(Media == "Mouse instilled") %>%
#  filter(Media == "LB" | Media == "LB + 0.5 M urea") %>%
#  filter(Media == "PBS-T") %>%
#  filter(Media == "Mice urine") %>%
#  filter(Strain == "WT") %>%
#  filter(Media == "LB" | Media == "LB + 0.5 M urea") %>%
  kbl() %>%
  kable_classic(full_width = T, html_font = "Computer modern") 
Sample Strain Media Batch
SM043 PA14 WT Mouse instilled 1
SM044 PA14 WT Mouse instilled 2
SM045 PA14 WT Mouse instilled 3
SM046 ∆eda Mouse instilled 1
SM047 ∆eda Mouse instilled 2
SM048 ∆eda Mouse instilled 3
SM049 ∆edd Mouse instilled 1
SM050 ∆edd Mouse instilled 2
SM051 ∆edd Mouse instilled 3
SM052 ∆gcd Mouse instilled 1
SM053 ∆gcd Mouse instilled 2
SM054 ∆gcd Mouse instilled 3
SM055 ∆pgl Mouse instilled 1
SM056 ∆pgl Mouse instilled 2
SM057 ∆pgl Mouse instilled 3
SM058 ∆zwf Mouse instilled 1
SM059 ∆zwf Mouse instilled 2
SM060 ∆zwf Mouse instilled 3
library(DESeq2)
library(ggplot2)
library(dplyr)

metadata=read.csv("metadata_ed.csv", row.names = 1, header = TRUE)
# these are the upside down counts
# rawcounts=read.csv("htseq_unfiltered_ed.csv", row.names =1 ) 


#rawcounts=read.csv("htseq_SM_unfiltered_reverse_strand_count.csv", row.names =1 )

# mus counts
rawcounts <- read.csv("htseq_unfiltered_reverse_strand_count_mus.csv", header = TRUE)
rawcounts <- filter(rawcounts,rowSums(rawcounts[,2:19])> 0, na.rm = TRUE)

# append b to batch column
metadata[["batch"]] <- paste0("b",metadata[["batch"]])

# filter samples 

### Mice instilled 
#metadata <- filter(metadata, media != "LB" & media != "LB_0.5 M_urea")
#metadata <- filter(metadata, media == "PBS-T")
metadata <- filter(metadata, media == "mice_instilled")
#metadata <- filter(metadata, media == "mice_urine")
#metadata <- filter(metadata, strain == "WT")


# filter poor quality samples
metadata <- filter(metadata, !rownames(metadata) %in% c("SM040", "SM048", "SM053")) 

samples <- rownames(metadata)

rawcounts <- select(rawcounts, all_of(samples))

# check that the samples are in order
all(rownames(metadata) == colnames(rawcounts))
## [1] TRUE
# filter 0's 

# check that the samples are in order

dds=DESeqDataSetFromMatrix(countData = rawcounts, colData =metadata, design = ~ condition + batch) 

2 Raw count graphs

2.1 Distribution of raw counts

# boxplot of average raw counts per sample

boxplot(log10(assays(dds)[["counts"]]), las=2, ylab="log10(assays(dds)[[counts]])")

2.2 Library size per sample

bp <- barplot(colSums(rawcounts), 
          #    ylim = c(0,4000000),
              las=2,)
mtext("Top axis", side=2, line=4)

2.3 Expression distribution

library(geomtextpath)

dat <- stack(rawcounts)

ggplot(dat, aes(x = log2(values+1),  fill=ind, label = ind )) + 
  geom_density(alpha = 0.5, position = "identity") + 
  ylab("Density") + 
  geom_textdensity(hjust = "ymax", vjust = 0,
           text_only = TRUE, text_smoothing = 20) + 
   theme(panel.grid = element_blank(),
        panel.background = element_blank(),
        panel.border = element_rect(fill = NA),
        legend.position = "none",
        legend.key = element_rect(fill = NA)) +
  coord_cartesian(xlim = c(0, 20))

2.4 Non-zero genes observed

x <- colSums(rawcounts)
y <- colSums(rawcounts != 0) 
df <- data.frame(x,y)
df$ind <- rownames(df)

ggplot(data = df, aes(x = x, y = y, color = ind, label = ind)) + geom_point() +
  geom_text(hjust=-0.1, vjust=-0.1) + 
  scale_x_continuous(limits = c(0,7e6), breaks = c(0, 1e6,2e6,3e6,4e6, 5e6, 6e6, 7e6), labels = (c(0,1,2,3,4,5,6, 7))) +
  xlab("CPM") + ylab("Number of non-zero genes observed") + 
  theme(panel.grid = element_blank(),
        panel.background = element_blank(),
        panel.border = element_rect(fill = NA),
        legend.position = "none",
        legend.key = element_rect(fill = NA)) 

2.5 Blind dispersion estimation

# variance stabilizing transformations (VST)
vsd <- vst(dds, blind=TRUE)

2.6 Principal component plot of the samples

library(ggplot2)
# PCA plot
pcaData <- plotPCA(vsd, intgroup=c("condition", "batch", "strain", "media"), returnData=TRUE)
percentVar <- round(100 * attr(pcaData, "percentVar"))
pca <- ggplot(pcaData, aes(PC1, PC2, color=strain, shape=media)) +
  geom_point(size=3) + 
  xlab(paste0("PC1: ",percentVar[1],"% variance")) +
  ylab(paste0("PC2: ",percentVar[2],"% variance"))  + 
  scale_colour_brewer(palette = "Dark2") +
  #scale_shape_manual(values=c(16,17,15,18,7,8,3,10)) +
  geom_rug() + 
# ylim(-40, 40) +
 # xlim(-50,60) +
  coord_fixed() + 
  labs(color = "Strain", shape = "Strain") + 
  theme(panel.grid = element_blank(),
        panel.background = element_blank(),
        panel.border = element_rect(fill = NA),
        legend.key = element_rect(fill = NA)) 

pca

2.7 Heatmap of sample to sample distances

library("RColorBrewer")
library("pheatmap")

sampleDists <- dist(t(assay(vsd)))
sampleDistMatrix <- as.matrix(sampleDists)
df <- as.data.frame(colData(dds)[,c("condition","batch")])
anno_col <- select(metadata, all_of(c("strain")))

pheatmap(sampleDistMatrix,
         clustering_distance_rows=sampleDists,
         clustering_distance_cols=sampleDists,
         labels_row = colnames(rawcounts),
         labels_col = colnames(rawcounts),
         angle_col = 45,
         show_colnames = TRUE)

LS0tCnRpdGxlOiAiMjAyMjExMDhfTW91c2VfUmV2ZXJzZV9FRF9kYXRhX3RyYW5zZm9ybWF0aW9uc192aXN1YWxpemF0aW9uIgphdXRob3I6ICJOb3VyIEVsIEh1c3NlaW5pIgpkYXRlOiAiMTEvMDgvMjAyMiIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgbWFpbmZvbnQ6ICJDb21wdXRlciBtb2Rlcm4iCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGhpZ2hsaWdodDogcHlnbWVudHMKICAgIHRoZW1lOgogICAgICBib290c3dhdGNoOiBsdW1lbgogIHBkZl9kb2N1bWVudDoKICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleAogICAgdG9jOiB5ZXMKICAgIGhpZ2hsaWdodDogcHlnbWVudHMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCi0tLQoKCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CiAgYm9keXsKICBmb250LXNpemU6IDE0cHQ7Cn0KPC9zdHlsZT4KCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQprbml0cjo6b3B0c19rbml0JHNldChnbG9iYWwucGFyID0gVFJVRSkKYGBgCgojIE92ZXJ2aWV3CgpUaGUgc2FtcGxlcyBjb250YWluIDUgbXV0YW50cyBhbmQgYSB3aWxkLXR5cGUgKFdUKSBjb250cm9sIGdyb3duIGluIHNldmVyYWwgbWVkaWEgYW5kIGluc3RpbGxlZCBpbiBtaWNlIGZvciAxIGhvdXIuIFRoaXMgZG9jdW1lbnQgdXNlcyB0aGUgKiptb3VzZSByYXcgcmV2ZXJzZSBzdHJhbmQgY291bnRzKiouIApgYGB7ciBzYW1wbGUgdGFibGUsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCiMgaHR0cHM6Ly9oYW96aHUyMzMuZ2l0aHViLmlvL2thYmxlRXh0cmEvYXdlc29tZV90YWJsZV9pbl9odG1sLmh0bWwKI3NldHdkKCIvVm9sdW1lcy9WVExfTGFiX0hRL1N5c3RlbS9Wb2x1bWVzL0RhdGEvVXNlcnMvVlRMX0xhYjEvRG9jdW1lbnRzL0VsLUh1c3NlaW5pX05vdXIvcm5hc2VxL2VkIikKbGlicmFyeShrYWJsZUV4dHJhKQpsaWJyYXJ5KGRwbHlyKQpkdCA8LSByZWFkLmNzdigiZWRfc2FtcGxlX3RhYmxlLmNzdiIpCgpkdCAlPiUgCiAgZmlsdGVyKE1lZGlhID09ICJNb3VzZSBpbnN0aWxsZWQiKSAlPiUKIyAgZmlsdGVyKE1lZGlhID09ICJMQiIgfCBNZWRpYSA9PSAiTEIgKyAwLjUgTSB1cmVhIikgJT4lCiMgIGZpbHRlcihNZWRpYSA9PSAiUEJTLVQiKSAlPiUKIyAgZmlsdGVyKE1lZGlhID09ICJNaWNlIHVyaW5lIikgJT4lCiMgIGZpbHRlcihTdHJhaW4gPT0gIldUIikgJT4lCiMgIGZpbHRlcihNZWRpYSA9PSAiTEIiIHwgTWVkaWEgPT0gIkxCICsgMC41IE0gdXJlYSIpICU+JQogIGtibCgpICU+JQogIGthYmxlX2NsYXNzaWMoZnVsbF93aWR0aCA9IFQsIGh0bWxfZm9udCA9ICJDb21wdXRlciBtb2Rlcm4iKSAKCmBgYCAKCgpgYGB7ciBsb2FkIGRhdGEsIGVjaG89VFJVRSwgZXZhbD1UUlVFLCBlcnJvcj1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmxpYnJhcnkoREVTZXEyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCgptZXRhZGF0YT1yZWFkLmNzdigibWV0YWRhdGFfZWQuY3N2Iiwgcm93Lm5hbWVzID0gMSwgaGVhZGVyID0gVFJVRSkKIyB0aGVzZSBhcmUgdGhlIHVwc2lkZSBkb3duIGNvdW50cwojIHJhd2NvdW50cz1yZWFkLmNzdigiaHRzZXFfdW5maWx0ZXJlZF9lZC5jc3YiLCByb3cubmFtZXMgPTEgKSAKCgojcmF3Y291bnRzPXJlYWQuY3N2KCJodHNlcV9TTV91bmZpbHRlcmVkX3JldmVyc2Vfc3RyYW5kX2NvdW50LmNzdiIsIHJvdy5uYW1lcyA9MSApCgojIG11cyBjb3VudHMKcmF3Y291bnRzIDwtIHJlYWQuY3N2KCJodHNlcV91bmZpbHRlcmVkX3JldmVyc2Vfc3RyYW5kX2NvdW50X211cy5jc3YiLCBoZWFkZXIgPSBUUlVFKQpyYXdjb3VudHMgPC0gZmlsdGVyKHJhd2NvdW50cyxyb3dTdW1zKHJhd2NvdW50c1ssMjoxOV0pPiAwLCBuYS5ybSA9IFRSVUUpCgojIGFwcGVuZCBiIHRvIGJhdGNoIGNvbHVtbgptZXRhZGF0YVtbImJhdGNoIl1dIDwtIHBhc3RlMCgiYiIsbWV0YWRhdGFbWyJiYXRjaCJdXSkKCiMgZmlsdGVyIHNhbXBsZXMgCgojIyMgTWljZSBpbnN0aWxsZWQgCiNtZXRhZGF0YSA8LSBmaWx0ZXIobWV0YWRhdGEsIG1lZGlhICE9ICJMQiIgJiBtZWRpYSAhPSAiTEJfMC41IE1fdXJlYSIpCiNtZXRhZGF0YSA8LSBmaWx0ZXIobWV0YWRhdGEsIG1lZGlhID09ICJQQlMtVCIpCm1ldGFkYXRhIDwtIGZpbHRlcihtZXRhZGF0YSwgbWVkaWEgPT0gIm1pY2VfaW5zdGlsbGVkIikKI21ldGFkYXRhIDwtIGZpbHRlcihtZXRhZGF0YSwgbWVkaWEgPT0gIm1pY2VfdXJpbmUiKQojbWV0YWRhdGEgPC0gZmlsdGVyKG1ldGFkYXRhLCBzdHJhaW4gPT0gIldUIikKCgojIGZpbHRlciBwb29yIHF1YWxpdHkgc2FtcGxlcwptZXRhZGF0YSA8LSBmaWx0ZXIobWV0YWRhdGEsICFyb3duYW1lcyhtZXRhZGF0YSkgJWluJSBjKCJTTTA0MCIsICJTTTA0OCIsICJTTTA1MyIpKSAKCnNhbXBsZXMgPC0gcm93bmFtZXMobWV0YWRhdGEpCgpyYXdjb3VudHMgPC0gc2VsZWN0KHJhd2NvdW50cywgYWxsX29mKHNhbXBsZXMpKQoKIyBjaGVjayB0aGF0IHRoZSBzYW1wbGVzIGFyZSBpbiBvcmRlcgphbGwocm93bmFtZXMobWV0YWRhdGEpID09IGNvbG5hbWVzKHJhd2NvdW50cykpCgojIGZpbHRlciAwJ3MgCgojIGNoZWNrIHRoYXQgdGhlIHNhbXBsZXMgYXJlIGluIG9yZGVyCgpkZHM9REVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGEgPSByYXdjb3VudHMsIGNvbERhdGEgPW1ldGFkYXRhLCBkZXNpZ24gPSB+IGNvbmRpdGlvbiArIGJhdGNoKSAKCmBgYAoKIyBSYXcgY291bnQgZ3JhcGhzCgojIyBEaXN0cmlidXRpb24gb2YgcmF3IGNvdW50cyAKCmBgYHtyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgYm94cGxvdCBvZiBhdmVyYWdlIHJhdyBjb3VudHMgcGVyIHNhbXBsZQoKYm94cGxvdChsb2cxMChhc3NheXMoZGRzKVtbImNvdW50cyJdXSksIGxhcz0yLCB5bGFiPSJsb2cxMChhc3NheXMoZGRzKVtbY291bnRzXV0pIikKCmBgYAoKIyMgTGlicmFyeSBzaXplIHBlciBzYW1wbGUKCmBgYHtyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmJwIDwtIGJhcnBsb3QoY29sU3VtcyhyYXdjb3VudHMpLCAKICAgICAgICAgICMgICAgeWxpbSA9IGMoMCw0MDAwMDAwKSwKICAgICAgICAgICAgICBsYXM9MiwpCm10ZXh0KCJUb3AgYXhpcyIsIHNpZGU9MiwgbGluZT00KQpgYGAKCiMjIEV4cHJlc3Npb24gZGlzdHJpYnV0aW9uCgpgYGB7ciwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGdlb210ZXh0cGF0aCkKCmRhdCA8LSBzdGFjayhyYXdjb3VudHMpCgpnZ3Bsb3QoZGF0LCBhZXMoeCA9IGxvZzIodmFsdWVzKzEpLCAgZmlsbD1pbmQsIGxhYmVsID0gaW5kICkpICsgCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41LCBwb3NpdGlvbiA9ICJpZGVudGl0eSIpICsgCiAgeWxhYigiRGVuc2l0eSIpICsgCiAgZ2VvbV90ZXh0ZGVuc2l0eShoanVzdCA9ICJ5bWF4Iiwgdmp1c3QgPSAwLAogICAgICAgICAgIHRleHRfb25seSA9IFRSVUUsIHRleHRfc21vb3RoaW5nID0gMjApICsgCiAgIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSwKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsCiAgICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEpKSArCiAgY29vcmRfY2FydGVzaWFuKHhsaW0gPSBjKDAsIDIwKSkKCmBgYAoKIyMgTm9uLXplcm8gZ2VuZXMgb2JzZXJ2ZWQKCmBgYHtyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnggPC0gY29sU3VtcyhyYXdjb3VudHMpCnkgPC0gY29sU3VtcyhyYXdjb3VudHMgIT0gMCkgCmRmIDwtIGRhdGEuZnJhbWUoeCx5KQpkZiRpbmQgPC0gcm93bmFtZXMoZGYpCgpnZ3Bsb3QoZGF0YSA9IGRmLCBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IGluZCwgbGFiZWwgPSBpbmQpKSArIGdlb21fcG9pbnQoKSArCiAgZ2VvbV90ZXh0KGhqdXN0PS0wLjEsIHZqdXN0PS0wLjEpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCw3ZTYpLCBicmVha3MgPSBjKDAsIDFlNiwyZTYsM2U2LDRlNiwgNWU2LCA2ZTYsIDdlNiksIGxhYmVscyA9IChjKDAsMSwyLDMsNCw1LDYsIDcpKSkgKwogIHhsYWIoIkNQTSIpICsgeWxhYigiTnVtYmVyIG9mIG5vbi16ZXJvIGdlbmVzIG9ic2VydmVkIikgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLAogICAgICAgIGxlZ2VuZC5rZXkgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSkgCgpgYGAKCiMjIEJsaW5kIGRpc3BlcnNpb24gZXN0aW1hdGlvbgoKYGBge3IgdHJhbnNmb3JtIFZTVH0KIyB2YXJpYW5jZSBzdGFiaWxpemluZyB0cmFuc2Zvcm1hdGlvbnMgKFZTVCkKdnNkIDwtIHZzdChkZHMsIGJsaW5kPVRSVUUpCmBgYAoKIyMgUHJpbmNpcGFsIGNvbXBvbmVudCBwbG90IG9mIHRoZSBzYW1wbGVzCgoKCmBgYHtyLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoZ2dwbG90MikKIyBQQ0EgcGxvdApwY2FEYXRhIDwtIHBsb3RQQ0EodnNkLCBpbnRncm91cD1jKCJjb25kaXRpb24iLCAiYmF0Y2giLCAic3RyYWluIiwgIm1lZGlhIiksIHJldHVybkRhdGE9VFJVRSkKcGVyY2VudFZhciA8LSByb3VuZCgxMDAgKiBhdHRyKHBjYURhdGEsICJwZXJjZW50VmFyIikpCnBjYSA8LSBnZ3Bsb3QocGNhRGF0YSwgYWVzKFBDMSwgUEMyLCBjb2xvcj1zdHJhaW4sIHNoYXBlPW1lZGlhKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0zKSArIAogIHhsYWIocGFzdGUwKCJQQzE6ICIscGVyY2VudFZhclsxXSwiJSB2YXJpYW5jZSIpKSArCiAgeWxhYihwYXN0ZTAoIlBDMjogIixwZXJjZW50VmFyWzJdLCIlIHZhcmlhbmNlIikpICArIAogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJEYXJrMiIpICsKICAjc2NhbGVfc2hhcGVfbWFudWFsKHZhbHVlcz1jKDE2LDE3LDE1LDE4LDcsOCwzLDEwKSkgKwogIGdlb21fcnVnKCkgKyAKIyB5bGltKC00MCwgNDApICsKICMgeGxpbSgtNTAsNjApICsKICBjb29yZF9maXhlZCgpICsgCiAgbGFicyhjb2xvciA9ICJTdHJhaW4iLCBzaGFwZSA9ICJTdHJhaW4iKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BKSwKICAgICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSkpIAoKcGNhCmBgYAoKIyMgSGVhdG1hcCBvZiBzYW1wbGUgdG8gc2FtcGxlIGRpc3RhbmNlcwoKYGBge3IsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSgiUkNvbG9yQnJld2VyIikKbGlicmFyeSgicGhlYXRtYXAiKQoKc2FtcGxlRGlzdHMgPC0gZGlzdCh0KGFzc2F5KHZzZCkpKQpzYW1wbGVEaXN0TWF0cml4IDwtIGFzLm1hdHJpeChzYW1wbGVEaXN0cykKZGYgPC0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKGRkcylbLGMoImNvbmRpdGlvbiIsImJhdGNoIildKQphbm5vX2NvbCA8LSBzZWxlY3QobWV0YWRhdGEsIGFsbF9vZihjKCJzdHJhaW4iKSkpCgpwaGVhdG1hcChzYW1wbGVEaXN0TWF0cml4LAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3M9c2FtcGxlRGlzdHMsCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2VfY29scz1zYW1wbGVEaXN0cywKICAgICAgICAgbGFiZWxzX3JvdyA9IGNvbG5hbWVzKHJhd2NvdW50cyksCiAgICAgICAgIGxhYmVsc19jb2wgPSBjb2xuYW1lcyhyYXdjb3VudHMpLAogICAgICAgICBhbmdsZV9jb2wgPSA0NSwKICAgICAgICAgc2hvd19jb2xuYW1lcyA9IFRSVUUpCmBgYAo=