library(ggplot2)
library(pheatmap)
library(RColorBrewer)
library(tidyverse)
library(ggpubr)
library(ggsignif)
library(openxlsx)
library(viridis)
package 㤼㸱viridis㤼㸲 was built under R version 4.0.5Loading required package: viridisLite
package 㤼㸱viridisLite㤼㸲 was built under R version 4.0.5
library(dplyr)
library(jcolors)
library(stringr)
setwd("//atlas.uni.lux/users/isabel.rosety/GBA/protein/WB/Plotting with Rstudio")
The working directory was changed to //atlas.uni.lux/users/isabel.rosety/GBA/protein/WB/Plotting with Rstudio inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
data <- read.xlsx("WB data for Rstudio plots.xlsx", sheet = 2)
data15 <- read.xlsx("WB data for Rstudio plots.xlsx", sheet = 1) #15d are in sheet 1
data30 <- read.xlsx("WB data for Rstudio plots.xlsx", sheet = 2)
data60 <- read.xlsx("WB data for Rstudio plots.xlsx", sheet = 3) #60d are in sheet
data90 <-read.xlsx("WB data for Rstudio plots.xlsx", sheet = 4)
dataCombined <- bind_rows(data15, data60,data30,data90)
dataCombined %>%
mutate(Condition = str_replace_all(Condition,
pattern = "PD N370S", replacement = "GBA-PD")) %>%
mutate(Condition = str_replace_all(Condition,
pattern = "Control", replacement = "CTRL")) ->dataCombined
Normalizing to the mean of the controls per feature
#Normalizing to mean of controls per WB
feature_names <- colnames(dataCombined[,6:ncol(dataCombined)])
dataCombined%>%
pivot_longer(feature_names,names_to = "Features", values_to = "Measure") -> Table_all_long
Table_all_long2 = drop_na(Table_all_long)
Table_all_long2 %>%
dplyr::filter(Condition=="CTRL") %>%
group_by(WB,Features,Day, Condition) %>%
#group_by(Features, Batch) %>%
summarise(baseline = mean(Measure)) %>%
ungroup() %>%
dplyr::select(-Condition) %>%
#dplyr::select(-Batch) %>%
full_join(Table_all_long2, by=c("Features","WB","Day")) %>%
#full_join(Table_all_long2, by=c("Features")) %>% #if I wanted to normalize per WB membrane
mutate(Foldchange = Measure /baseline) ->Table_all_based
`summarise()` has grouped output by 'WB', 'Features', 'Day'. You can override using the `.groups` argument.
#Mean of replicates if samples from same batch have been probed for the same marker in different membranes
Table_all_based %>%
group_by(Features,Day, Condition, Batch,CellLine) %>%
summarize(MeanFeatures = mean(Foldchange)) -> Table_Mean
`summarise()` has grouped output by 'Features', 'Day', 'Condition', 'Batch'. You can override using the `.groups` argument.
included_vars =c("Batch", "CellLine", "Condition","Day")
Table_Mean %>%
pivot_wider(all_of(included_vars),names_from = Features,values_from = MeanFeatures)->Table_all_based_wide
#write.csv(Table_all_based_wide, file = 'Table_all_Mean of replicates and Normalized to mean of controls.csv')
Table_all_based_wide15<-filter(Table_all_based_wide,Day=="D15")
Table_all_based_wide30<-filter(Table_all_based_wide,Day=="D30")
Table_all_based_wide60<-filter(Table_all_based_wide,Day=="D60")
Table_all_based_wide90<-filter(Table_all_based_wide,Day=="D90")
#Table of normalized values without doing the mean of replicates
included_vars2 =c("WB","Batch", "CellLine", "Condition","Day")
Table_all_based%>%
pivot_wider(all_of(included_vars2),names_from = Features,values_from = Foldchange)->Table_all_normalized_no_mean
#write.csv(Table_all_normalized_no_mean, file = 'Table_all_Normalized to mean of controls NO mean of replicates.csv')
Plots for all features one timepoint (loop)
feature_names <- colnames(Table_all_based_wide30[,5:ncol(Table_all_based_wide30)])
#subset = c("CellLine","Condition","Day","Batch","p62ByActin")
#Table_all_based_wide%>% #same
# dplyr::select(subset)->Table_all_based_wide3
#feature_names <- colnames(Table_all_based_wide3[,6:ncol(Table_all_based_wide3)])
for (i in 1:length(feature_names)) {
Table_all_based_wide30 %>%
pivot_longer(cols=feature_names, names_to = "feature", values_to = "value") %>%
filter(feature %in% feature_names[i]) %>%
ggplot( aes(x=factor(Condition, level = c("CTRL", "GBA-PD")), y=value)) +
#geom_violin( aes(fill=Condition),show.legend = T, trim=T)+
#scale_fill_manual(values= c("#bdd7e7","#2171b5"),name = "Condition", guide = FALSE)+
scale_fill_manual(values= c("#FFFFFF","#999999"),name = "Condition", guide = "none")+ #guide false will remove the legend for the condition
#geom_boxplot(width=0.07, fill="white") +
geom_boxplot(aes(fill=Condition),show.legend = FALSE,width=0.7)+ #show.legend will remove box around the points of the legend
geom_point(aes(color=CellLine),size=3,show.legend = T,alpha = 0.5)+
#scale_color_manual(values = rev(brewer.pal(n=6, name="OrRd")))+
scale_color_jcolors("pal7")+
#scale_color_viridis(option = "D", discrete=TRUE)+
#geom_point(shape = 1,size = 3,colour = "black")+
theme(legend.key=element_blank()) +
geom_signif(comparisons = list(c("CTRL", "GBA-PD")), test='wilcox.test',
vjust=0.5, size=0.5, textsize=9, map_signif_level=c("***"=0.001, "**"=0.01, "*"=0.05, " "=2) ) +
#facet_grid(~fct_relevel(Day, "d15", "d30","d60", "d90"), scales="free") +
labs(x = "",
y = paste(feature_names[i]),
#y = paste(names[i]),
fill = "Condition",
#title = paste(feature_names[i])) +
title = "" )+
theme_bw() +
theme(
axis.line = element_line(colour = 'black', size = 0.5) ,
axis.title.x = element_blank(),
axis.text.x = element_text(size=21, color="black"),
axis.title.y = element_text(size = 21),
axis.text.y = element_text(size=15, color="black"),
axis.ticks.y = element_line(),
axis.ticks.length=unit(.25, "cm"),
#change legend text font size)
#legend.key.size = unit(0.7, "cm"),
#legend.key.width = unit(0.6,"cm"),
legend.key=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
plot.title = element_text(size = 20, hjust=0.5, vjust= 1, face = "bold"),
plot.subtitle = element_blank(),#element_text(size = 2, hjust=0.5)
strip.text = element_text(size=12, vjust=0.5),
strip.background = element_rect(fill="lightgray"),
# panel.border = element_rect(fill = NA, color = "black"),
panel.spacing.y = unit(0.8, "lines"),
strip.switch.pad.wrap=unit(20, "lines"),
legend.position="right",
legend.text = element_text(size=17),
legend.title = element_text(size=19)
) -> p
#t<- cowplot::ggdraw(cowplot::add_sub(p, "Wilcox-test, ***p=0.001, **p=0.01, *p=0.05",hjust=-0.2, size=13))
print(p)
##ggsave(paste0(Sys.Date(),"_", names[i], ".pdf"), plot=t)
#ggsave(paste0(Sys.Date(),(sprintf("Plot_%s_DIV30.pdf",feature_names[i]))),height=4)
}


















Plots for all features and all timepoints (loop)
for (i in 1:length(feature_names)) {
Table_all_based_wide %>%
pivot_longer(cols=feature_names, names_to = "feature", values_to = "value") %>%
filter(feature %in% feature_names[i]) %>%
ggplot( aes(x=factor(Condition, level = c("CTRL", "GBA-PD")), y=value)) +
#geom_violin( aes(fill=Condition),show.legend = T, trim=T)+
#scale_fill_manual(values= c("#bdd7e7","#2171b5"),name = "Condition", guide = FALSE)+
scale_fill_manual(values= c("#FFFFFF","#999999"),name = "Condition", guide = "none")+ #guide false will remove the legend for the condition
#geom_boxplot(width=0.07, fill="white") +
geom_boxplot(aes(fill=Condition),show.legend = FALSE)+ #show.legend will remove box around the points of the legend
geom_point(aes(color=CellLine),size=2,show.legend = T,alpha = 0.5)+
scale_color_jcolors("pal7")+
theme(legend.key=element_blank()) +
geom_signif(comparisons = list(c("CTRL", "GBA-PD")), test='wilcox.test',
vjust=0.5, size=0.5, textsize=9, map_signif_level=c("***"=0.001, "**"=0.01, "*"=0.05, " "=2) ) +
facet_grid(~fct_relevel(Day, "d15", "d30","d60", "d90"), scales="free") +
labs(x = "",
y = paste(feature_names[i]),
#y = paste(names[i]),
fill = "Condition",
title = paste(feature_names[i])) +
theme_bw() +
theme(
axis.line = element_line(colour = 'black', size = 0.5) ,
axis.title.x = element_blank(),
axis.text.x = element_text(size=14, color="black", angle=45, vjust = 1, hjust = 0.95),
axis.title.y = element_text(size = 20),
axis.text.y = element_text(size=15, color="black"),
axis.ticks.y = element_line(),
axis.ticks.length=unit(.25, "cm"),
legend.key=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#panel.border = element_blank(),
plot.title = element_text(size = 20, hjust=0.5, vjust= 1, face = "bold"),
plot.subtitle = element_blank(),#element_text(size = 2, hjust=0.5)
strip.text = element_text(size=14, vjust=0.5),
strip.background = element_rect(fill="lightgray"),
# panel.border = element_rect(fill = NA, color = "black"),
panel.spacing.y = unit(0.8, "lines"),
strip.switch.pad.wrap=unit(20, "lines"),
legend.position="right",
legend.text = element_text(size=17),
legend.title = element_text(size=19)
) -> p
print(p)
#ggsave(paste0(Sys.Date(),(sprintf("Plot_%s_All_timepoints.pdf",feature_names[i]))),height=4)
}


















LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KLS0tDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGhlYXRtYXApDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KGdnc2lnbmlmKQ0KbGlicmFyeShvcGVueGxzeCkNCmxpYnJhcnkodmlyaWRpcykNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGpjb2xvcnMpDQpsaWJyYXJ5KHN0cmluZ3IpDQpgYGANCg0KYGBge3J9DQpzZXR3ZCgiLy9hdGxhcy51bmkubHV4L3VzZXJzL2lzYWJlbC5yb3NldHkvR0JBL3Byb3RlaW4vV0IvUGxvdHRpbmcgd2l0aCBSc3R1ZGlvIikNCg0KZGF0YSA8LSByZWFkLnhsc3goIldCIGRhdGEgZm9yIFJzdHVkaW8gcGxvdHMueGxzeCIsIHNoZWV0ID0gMikNCmRhdGExNSA8LSByZWFkLnhsc3goIldCIGRhdGEgZm9yIFJzdHVkaW8gcGxvdHMueGxzeCIsIHNoZWV0ID0gMSkgIzE1ZCBhcmUgaW4gc2hlZXQgMQ0KZGF0YTMwIDwtIHJlYWQueGxzeCgiV0IgZGF0YSBmb3IgUnN0dWRpbyBwbG90cy54bHN4Iiwgc2hlZXQgPSAyKQ0KZGF0YTYwIDwtIHJlYWQueGxzeCgiV0IgZGF0YSBmb3IgUnN0dWRpbyBwbG90cy54bHN4Iiwgc2hlZXQgPSAzKSAjNjBkIGFyZSBpbiBzaGVldCANCmRhdGE5MCA8LXJlYWQueGxzeCgiV0IgZGF0YSBmb3IgUnN0dWRpbyBwbG90cy54bHN4Iiwgc2hlZXQgPSA0KQ0KZGF0YUNvbWJpbmVkIDwtIGJpbmRfcm93cyhkYXRhMTUsIGRhdGE2MCxkYXRhMzAsZGF0YTkwKQ0KZGF0YUNvbWJpbmVkICU+JSANCiAgIG11dGF0ZShDb25kaXRpb24gPSBzdHJfcmVwbGFjZV9hbGwoQ29uZGl0aW9uLCANCiAgICAgICAgICAgIHBhdHRlcm4gPSAiUEQgTjM3MFMiLCByZXBsYWNlbWVudCA9ICJHQkEtUEQiKSkgJT4lDQogICAgIG11dGF0ZShDb25kaXRpb24gPSBzdHJfcmVwbGFjZV9hbGwoQ29uZGl0aW9uLCANCiAgICAgICAgICAgIHBhdHRlcm4gPSAiQ29udHJvbCIsIHJlcGxhY2VtZW50ID0gIkNUUkwiKSkgLT5kYXRhQ29tYmluZWQNCg0KYGBgDQoNCg0KTm9ybWFsaXppbmcgdG8gdGhlIG1lYW4gb2YgdGhlIGNvbnRyb2xzIHBlciBmZWF0dXJlDQpgYGB7cn0gDQoNCiNOb3JtYWxpemluZyB0byBtZWFuIG9mIGNvbnRyb2xzIHBlciBXQg0KZmVhdHVyZV9uYW1lcyA8LSBjb2xuYW1lcyhkYXRhQ29tYmluZWRbLDY6bmNvbChkYXRhQ29tYmluZWQpXSkNCiAgZGF0YUNvbWJpbmVkJT4lDQogICAgcGl2b3RfbG9uZ2VyKGZlYXR1cmVfbmFtZXMsbmFtZXNfdG8gPSAiRmVhdHVyZXMiLCB2YWx1ZXNfdG8gPSAiTWVhc3VyZSIpIC0+IFRhYmxlX2FsbF9sb25nDQpUYWJsZV9hbGxfbG9uZzIgPSBkcm9wX25hKFRhYmxlX2FsbF9sb25nKSAgDQpUYWJsZV9hbGxfbG9uZzIgJT4lDQogICAgZHBseXI6OmZpbHRlcihDb25kaXRpb249PSJDVFJMIikgJT4lIA0KICAgIGdyb3VwX2J5KFdCLEZlYXR1cmVzLERheSwgQ29uZGl0aW9uKSAlPiUgDQogICAgI2dyb3VwX2J5KEZlYXR1cmVzLCBCYXRjaCkgJT4lIA0KICAgIHN1bW1hcmlzZShiYXNlbGluZSA9IG1lYW4oTWVhc3VyZSkpICU+JSANCiAgICB1bmdyb3VwKCkgJT4lIA0KICAgIGRwbHlyOjpzZWxlY3QoLUNvbmRpdGlvbikgJT4lIA0KICAgICNkcGx5cjo6c2VsZWN0KC1CYXRjaCkgJT4lDQogICAgZnVsbF9qb2luKFRhYmxlX2FsbF9sb25nMiwgYnk9YygiRmVhdHVyZXMiLCJXQiIsIkRheSIpKSAlPiUgDQogICAgI2Z1bGxfam9pbihUYWJsZV9hbGxfbG9uZzIsIGJ5PWMoIkZlYXR1cmVzIikpICU+JSAjaWYgSSB3YW50ZWQgdG8gbm9ybWFsaXplIHBlciBXQiBtZW1icmFuZQ0KICAgIG11dGF0ZShGb2xkY2hhbmdlID0gTWVhc3VyZSAvYmFzZWxpbmUpIC0+VGFibGVfYWxsX2Jhc2VkDQoNCiNNZWFuIG9mIHJlcGxpY2F0ZXMgaWYgc2FtcGxlcyBmcm9tIHNhbWUgYmF0Y2ggaGF2ZSBiZWVuIHByb2JlZCBmb3IgdGhlIHNhbWUgbWFya2VyIGluIGRpZmZlcmVudCBtZW1icmFuZXMNClRhYmxlX2FsbF9iYXNlZCAlPiUNCiAgZ3JvdXBfYnkoRmVhdHVyZXMsRGF5LCBDb25kaXRpb24sIEJhdGNoLENlbGxMaW5lKSAlPiUNCiAgc3VtbWFyaXplKE1lYW5GZWF0dXJlcyA9IG1lYW4oRm9sZGNoYW5nZSkpIC0+IFRhYmxlX01lYW4NCg0KaW5jbHVkZWRfdmFycyA9YygiQmF0Y2giLCAiQ2VsbExpbmUiLCAiQ29uZGl0aW9uIiwiRGF5IikNClRhYmxlX01lYW4gJT4lIA0KICAgIHBpdm90X3dpZGVyKGFsbF9vZihpbmNsdWRlZF92YXJzKSxuYW1lc19mcm9tID0gRmVhdHVyZXMsdmFsdWVzX2Zyb20gPSBNZWFuRmVhdHVyZXMpLT5UYWJsZV9hbGxfYmFzZWRfd2lkZQ0KDQojd3JpdGUuY3N2KFRhYmxlX2FsbF9iYXNlZF93aWRlLCBmaWxlID0gJ1RhYmxlX2FsbF9NZWFuIG9mIHJlcGxpY2F0ZXMgYW5kIE5vcm1hbGl6ZWQgdG8gbWVhbiBvZiBjb250cm9scy5jc3YnKQ0KDQpUYWJsZV9hbGxfYmFzZWRfd2lkZTE1PC1maWx0ZXIoVGFibGVfYWxsX2Jhc2VkX3dpZGUsRGF5PT0iRDE1IikNClRhYmxlX2FsbF9iYXNlZF93aWRlMzA8LWZpbHRlcihUYWJsZV9hbGxfYmFzZWRfd2lkZSxEYXk9PSJEMzAiKQ0KVGFibGVfYWxsX2Jhc2VkX3dpZGU2MDwtZmlsdGVyKFRhYmxlX2FsbF9iYXNlZF93aWRlLERheT09IkQ2MCIpDQpUYWJsZV9hbGxfYmFzZWRfd2lkZTkwPC1maWx0ZXIoVGFibGVfYWxsX2Jhc2VkX3dpZGUsRGF5PT0iRDkwIikNCg0KDQojVGFibGUgb2Ygbm9ybWFsaXplZCB2YWx1ZXMgd2l0aG91dCBkb2luZyB0aGUgbWVhbiBvZiByZXBsaWNhdGVzDQppbmNsdWRlZF92YXJzMiA9YygiV0IiLCJCYXRjaCIsICJDZWxsTGluZSIsICJDb25kaXRpb24iLCJEYXkiKQ0KVGFibGVfYWxsX2Jhc2VkJT4lIA0KICAgIHBpdm90X3dpZGVyKGFsbF9vZihpbmNsdWRlZF92YXJzMiksbmFtZXNfZnJvbSA9IEZlYXR1cmVzLHZhbHVlc19mcm9tID0gRm9sZGNoYW5nZSktPlRhYmxlX2FsbF9ub3JtYWxpemVkX25vX21lYW4NCiN3cml0ZS5jc3YoVGFibGVfYWxsX25vcm1hbGl6ZWRfbm9fbWVhbiwgZmlsZSA9ICdUYWJsZV9hbGxfTm9ybWFsaXplZCB0byBtZWFuIG9mIGNvbnRyb2xzIE5PIG1lYW4gb2YgcmVwbGljYXRlcy5jc3YnKQ0KDQpgYGANCg0KUGxvdHMgZm9yIGFsbCBmZWF0dXJlcyBvbmUgdGltZXBvaW50IChsb29wKQ0KYGBge3J9IA0KZmVhdHVyZV9uYW1lcyA8LSBjb2xuYW1lcyhUYWJsZV9hbGxfYmFzZWRfd2lkZTMwWyw1Om5jb2woVGFibGVfYWxsX2Jhc2VkX3dpZGUzMCldKQ0KDQojc3Vic2V0ID0gYygiQ2VsbExpbmUiLCJDb25kaXRpb24iLCJEYXkiLCJCYXRjaCIsInA2MkJ5QWN0aW4iKQ0KI1RhYmxlX2FsbF9iYXNlZF93aWRlJT4lICNzYW1lIA0KIyAgZHBseXI6OnNlbGVjdChzdWJzZXQpLT5UYWJsZV9hbGxfYmFzZWRfd2lkZTMNCiNmZWF0dXJlX25hbWVzIDwtIGNvbG5hbWVzKFRhYmxlX2FsbF9iYXNlZF93aWRlM1ssNjpuY29sKFRhYmxlX2FsbF9iYXNlZF93aWRlMyldKQ0KDQoNCg0KZm9yIChpIGluIDE6bGVuZ3RoKGZlYXR1cmVfbmFtZXMpKSB7DQpUYWJsZV9hbGxfYmFzZWRfd2lkZTMwICU+JQ0KICBwaXZvdF9sb25nZXIoY29scz1mZWF0dXJlX25hbWVzLCBuYW1lc190byA9ICJmZWF0dXJlIiwgdmFsdWVzX3RvID0gInZhbHVlIikgJT4lDQogIGZpbHRlcihmZWF0dXJlICVpbiUgZmVhdHVyZV9uYW1lc1tpXSkgJT4lDQpnZ3Bsb3QoIGFlcyh4PWZhY3RvcihDb25kaXRpb24sIGxldmVsID0gYygiQ1RSTCIsICJHQkEtUEQiKSksIHk9dmFsdWUpKSArDQogICNnZW9tX3Zpb2xpbiggYWVzKGZpbGw9Q29uZGl0aW9uKSxzaG93LmxlZ2VuZCA9IFQsIHRyaW09VCkrDQoNCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz0gYygiI2JkZDdlNyIsIiMyMTcxYjUiKSxuYW1lID0gIkNvbmRpdGlvbiIsIGd1aWRlID0gRkFMU0UpKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz0gYygiI0ZGRkZGRiIsIiM5OTk5OTkiKSxuYW1lID0gIkNvbmRpdGlvbiIsIGd1aWRlID0gIm5vbmUiKSsgI2d1aWRlIGZhbHNlIHdpbGwgcmVtb3ZlIHRoZSBsZWdlbmQgZm9yIHRoZSBjb25kaXRpb24NCiAgICAjZ2VvbV9ib3hwbG90KHdpZHRoPTAuMDcsIGZpbGw9IndoaXRlIikgKyANCiAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Q29uZGl0aW9uKSxzaG93LmxlZ2VuZCA9IEZBTFNFLHdpZHRoPTAuNykrICNzaG93LmxlZ2VuZCB3aWxsIHJlbW92ZSBib3ggYXJvdW5kIHRoZSBwb2ludHMgb2YgdGhlIGxlZ2VuZA0KICAgIGdlb21fcG9pbnQoYWVzKGNvbG9yPUNlbGxMaW5lKSxzaXplPTMsc2hvdy5sZWdlbmQgPSBULGFscGhhID0gMC41KSsNCiAgICAjc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHJldihicmV3ZXIucGFsKG49NiwgbmFtZT0iT3JSZCIpKSkrDQogICAgc2NhbGVfY29sb3JfamNvbG9ycygicGFsNyIpKw0KICAgICNzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbiA9ICJEIiwgZGlzY3JldGU9VFJVRSkrDQogICAgI2dlb21fcG9pbnQoc2hhcGUgPSAxLHNpemUgPSAzLGNvbG91ciA9ICJibGFjayIpKw0KICAgIHRoZW1lKGxlZ2VuZC5rZXk9ZWxlbWVudF9ibGFuaygpKSArDQogICAgDQogIGdlb21fc2lnbmlmKGNvbXBhcmlzb25zID0gbGlzdChjKCJDVFJMIiwgIkdCQS1QRCIpKSwgdGVzdD0nd2lsY294LnRlc3QnLA0KICAgICAgICAgICAgICB2anVzdD0wLjUsIHNpemU9MC41LCB0ZXh0c2l6ZT05LCBtYXBfc2lnbmlmX2xldmVsPWMoIioqKiI9MC4wMDEsICIqKiI9MC4wMSwgIioiPTAuMDUsICAiICI9MikgKSArDQogICNmYWNldF9ncmlkKH5mY3RfcmVsZXZlbChEYXksICJkMTUiLCAiZDMwIiwiZDYwIiwgImQ5MCIpLCBzY2FsZXM9ImZyZWUiKSArDQogICAgICBsYWJzKHggICAgID0gIiIsDQogICAgICAgeSAgICAgPSBwYXN0ZShmZWF0dXJlX25hbWVzW2ldKSwNCiAgICAgICAjeSAgICAgPSBwYXN0ZShuYW1lc1tpXSksDQogICAgICAgZmlsbCAgPSAiQ29uZGl0aW9uIiwNCiAgICAgICAjdGl0bGUgPSBwYXN0ZShmZWF0dXJlX25hbWVzW2ldKSkgKw0KICAgICAgIHRpdGxlID0gIiIgKSsNCiAgdGhlbWVfYncoKSArDQogIHRoZW1lKA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAnYmxhY2snLCBzaXplID0gMC41KSAsDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MjEsIGNvbG9yPSJibGFjayIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjEpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTUsIGNvbG9yPSJibGFjayIpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfbGluZSgpLA0KICAgIGF4aXMudGlja3MubGVuZ3RoPXVuaXQoLjI1LCAiY20iKSwNCiAgICAjY2hhbmdlIGxlZ2VuZCB0ZXh0IGZvbnQgc2l6ZSkNCiAgICAjbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjcsICJjbSIpLA0KICAgICNsZWdlbmQua2V5LndpZHRoID0gdW5pdCgwLjYsImNtIiksDQogICAgbGVnZW5kLmtleT1lbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0PTAuNSwgdmp1c3Q9IDEsIGZhY2UgPSAiYm9sZCIpLA0KICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X2JsYW5rKCksI2VsZW1lbnRfdGV4dChzaXplID0gMiwgaGp1c3Q9MC41KQ0KICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiwgdmp1c3Q9MC41KSwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9ImxpZ2h0Z3JheSIpLA0KICAgIyBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvciA9ICJibGFjayIpLA0KICAgIHBhbmVsLnNwYWNpbmcueSA9IHVuaXQoMC44LCAibGluZXMiKSwNCiAgICBzdHJpcC5zd2l0Y2gucGFkLndyYXA9dW5pdCgyMCwgImxpbmVzIiksDQogICAgbGVnZW5kLnBvc2l0aW9uPSJyaWdodCIsDQogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNyksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTkpDQogICAgDQogICkgIC0+IHANCiAgI3Q8LSBjb3dwbG90OjpnZ2RyYXcoY293cGxvdDo6YWRkX3N1YihwLCAiV2lsY294LXRlc3QsICoqKnA9MC4wMDEsICoqcD0wLjAxLCAqcD0wLjA1IixoanVzdD0tMC4yLCBzaXplPTEzKSkNCiAgcHJpbnQocCkNCiAgIyNnZ3NhdmUocGFzdGUwKFN5cy5EYXRlKCksIl8iLCBuYW1lc1tpXSwgIi5wZGYiKSwgcGxvdD10KQ0KI2dnc2F2ZShwYXN0ZTAoU3lzLkRhdGUoKSwoc3ByaW50ZigiUGxvdF8lc19ESVYzMC5wZGYiLGZlYXR1cmVfbmFtZXNbaV0pKSksaGVpZ2h0PTQpDQp9DQpgYGANCg0KUGxvdHMgZm9yIGFsbCBmZWF0dXJlcyBhbmQgYWxsIHRpbWVwb2ludHMgKGxvb3ApDQpgYGB7cn0NCmZvciAoaSBpbiAxOmxlbmd0aChmZWF0dXJlX25hbWVzKSkgew0KVGFibGVfYWxsX2Jhc2VkX3dpZGUgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzPWZlYXR1cmVfbmFtZXMsIG5hbWVzX3RvID0gImZlYXR1cmUiLCB2YWx1ZXNfdG8gPSAidmFsdWUiKSAlPiUNCiAgZmlsdGVyKGZlYXR1cmUgJWluJSBmZWF0dXJlX25hbWVzW2ldKSAlPiUNCmdncGxvdCggYWVzKHg9ZmFjdG9yKENvbmRpdGlvbiwgbGV2ZWwgPSBjKCJDVFJMIiwgIkdCQS1QRCIpKSwgeT12YWx1ZSkpICsNCiAgI2dlb21fdmlvbGluKCBhZXMoZmlsbD1Db25kaXRpb24pLHNob3cubGVnZW5kID0gVCwgdHJpbT1UKSsNCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz0gYygiI2JkZDdlNyIsIiMyMTcxYjUiKSxuYW1lID0gIkNvbmRpdGlvbiIsIGd1aWRlID0gRkFMU0UpKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz0gYygiI0ZGRkZGRiIsIiM5OTk5OTkiKSxuYW1lID0gIkNvbmRpdGlvbiIsIGd1aWRlID0gIm5vbmUiKSsgI2d1aWRlIGZhbHNlIHdpbGwgcmVtb3ZlIHRoZSBsZWdlbmQgZm9yIHRoZSBjb25kaXRpb24NCiAgICAjZ2VvbV9ib3hwbG90KHdpZHRoPTAuMDcsIGZpbGw9IndoaXRlIikgKyANCiAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Q29uZGl0aW9uKSxzaG93LmxlZ2VuZCA9IEZBTFNFKSsgI3Nob3cubGVnZW5kIHdpbGwgcmVtb3ZlIGJveCBhcm91bmQgdGhlIHBvaW50cyBvZiB0aGUgbGVnZW5kDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3I9Q2VsbExpbmUpLHNpemU9MixzaG93LmxlZ2VuZCA9IFQsYWxwaGEgPSAwLjUpKw0KICAgIHNjYWxlX2NvbG9yX2pjb2xvcnMoInBhbDciKSsNCiAgICB0aGVtZShsZWdlbmQua2V5PWVsZW1lbnRfYmxhbmsoKSkgKw0KICBnZW9tX3NpZ25pZihjb21wYXJpc29ucyA9IGxpc3QoYygiQ1RSTCIsICJHQkEtUEQiKSksIHRlc3Q9J3dpbGNveC50ZXN0JywNCiAgICAgICAgICAgICAgdmp1c3Q9MC41LCBzaXplPTAuNSwgdGV4dHNpemU9OSwgbWFwX3NpZ25pZl9sZXZlbD1jKCIqKioiPTAuMDAxLCAiKioiPTAuMDEsICIqIj0wLjA1LCAgIiAiPTIpICkgKw0KICBmYWNldF9ncmlkKH5mY3RfcmVsZXZlbChEYXksICJkMTUiLCAiZDMwIiwiZDYwIiwgImQ5MCIpLCBzY2FsZXM9ImZyZWUiKSArDQogICAgICBsYWJzKHggICAgID0gIiIsDQogICAgICAgeSAgICAgPSBwYXN0ZShmZWF0dXJlX25hbWVzW2ldKSwNCiAgICAgICAjeSAgICAgPSBwYXN0ZShuYW1lc1tpXSksDQogICAgICAgZmlsbCAgPSAiQ29uZGl0aW9uIiwNCiAgICAgICB0aXRsZSA9IHBhc3RlKGZlYXR1cmVfbmFtZXNbaV0pKSArDQogIHRoZW1lX2J3KCkgKw0KICB0aGVtZSgNCiAgICBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gJ2JsYWNrJywgc2l6ZSA9IDAuNSkgLA0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTE0LCBjb2xvcj0iYmxhY2siLCBhbmdsZT00NSwgdmp1c3QgPSAxLCBoanVzdCA9IDAuOTUpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTUsIGNvbG9yPSJibGFjayIpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfbGluZSgpLA0KICAgIGF4aXMudGlja3MubGVuZ3RoPXVuaXQoLjI1LCAiY20iKSwNCg0KICAgIGxlZ2VuZC5rZXk9ZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgI3BhbmVsLmJvcmRlciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3Q9MC41LCB2anVzdD0gMSwgZmFjZSA9ICJib2xkIiksDQogICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwjZWxlbWVudF90ZXh0KHNpemUgPSAyLCBoanVzdD0wLjUpDQogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE0LCB2anVzdD0wLjUpLA0KICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0ibGlnaHRncmF5IiksDQogICAjIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG9yID0gImJsYWNrIiksDQogICAgcGFuZWwuc3BhY2luZy55ID0gdW5pdCgwLjgsICJsaW5lcyIpLA0KICAgIHN0cmlwLnN3aXRjaC5wYWQud3JhcD11bml0KDIwLCAibGluZXMiKSwNCiAgICBsZWdlbmQucG9zaXRpb249InJpZ2h0IiwNCiAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE3KSwNCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xOSkNCiAgICANCiAgKSAgLT4gcA0KICBwcmludChwKQ0KI2dnc2F2ZShwYXN0ZTAoU3lzLkRhdGUoKSwoc3ByaW50ZigiUGxvdF8lc19BbGxfdGltZXBvaW50cy5wZGYiLGZlYXR1cmVfbmFtZXNbaV0pKSksaGVpZ2h0PTQpDQp9DQpgYGANCg0KDQo=