library(jcolors)
package 㤼㸱jcolors㤼㸲 was built under R version 4.0.5
setwd("//atlas.uni.lux/users/isabel.rosety/GBA/PI_FACS")
#data <- read.csv("WB data for Rstudio plots.csv", header = T,  sep = ",")
OutPath= "//atlas.uni.lux/users/isabel.rosety/GBA/PI_FACS"
data <- read.xlsx("All samples.xlsx",sheet=2)
#data15 <- read.xlsx("WB data for Rstudio plots.xlsx", sheet = 1) #15d are in sheet 1
#Day=as.character(DataCombined$Day)

Mean of replicates - No normalization


#Mean of replicates
feature_names <- colnames(data[,5:ncol(data)])
  data%>%
    pivot_longer(feature_names,names_to = "Features", values_to = "Measure") -> Table_all_long
Table_all_long = drop_na(Table_all_long)  

Table_all_long %>%
  group_by(Condition,Batch,Features,CellLine) %>%
  summarize(MeanFeatures = mean(Measure)) -> Table_Mean
`summarise()` has grouped output by 'Condition', 'Batch', 'Features'. You can override using the `.groups` argument.
included_vars =c("Batch", "CellLine", "Condition")
Table_Mean %>% 
    pivot_wider(all_of(included_vars),names_from = Features,values_from = MeanFeatures)->Table_Mean_wide

Mean of replicates & normalizaton to controls


  #Mean of replicates
feature_names <- colnames(data[,5:ncol(data)])
  data%>%
    pivot_longer(feature_names,names_to = "Features", values_to = "Measure") -> Table_all_long
Table_all_long = drop_na(Table_all_long)  

Table_all_long %>%
  group_by(Condition,Batch,Features,CellLine) %>%
  summarize(MeanFeatures = mean(Measure)) -> Table_Mean
#  ungroup() %>% 
#  dplyr::select(-AreaName) %>% 
#  full_join(Table_all_long2, by="Features" ) 
    #full_join(Table_all_long2, by=c("Features")) %>% #if I wanted to normalize per WB membrane

#Normalizing to mean of controls
Table_Mean %>%
    dplyr::filter(Condition=="Control") %>% 
    group_by(Batch,Features, Condition) %>% 
    #group_by(Features, Batch) %>% 
    summarise(baseline = mean(MeanFeatures)) %>% 
    ungroup() %>% 
    dplyr::select(-Condition) %>% 
    #dplyr::select(-Batch) %>%
    full_join(Table_Mean, by=c("Features","Batch")) %>% 
    #full_join(Table_all_long2, by=c("Features")) %>% #if I wanted to normalize per WB membrane
    mutate(Foldchange = MeanFeatures /baseline) ->Table_all_based

included_vars =c("Batch", "CellLine", "Condition")
Table_all_based %>% 
    pivot_wider(all_of(included_vars),names_from = Features,values_from = Foldchange)->Table_all_based_wide
Table_all_based_wide<-filter(Table_all_based_wide,Batch!="46")
Table_all_based_wide %>%
  filter(!Condition%in%c("Control_DFX","GBA-PD_DFX")) -> Table_all_based_wide

Table_Mean_wide<-filter(Table_Mean_wide,Batch!="46")

for (i in 1:length(feature_names)) {
Table_Mean_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,width=0.5)+ #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=6)
}

Normalization if mean of duplicates already done

  data%>%
    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=="Control") %>% 
    #group_by(WB, Batch, Condition,Features) %>% 
    group_by(Condition,Features) %>% 
    summarise(baseline = median(Measure)) %>% 
    ungroup() %>% 
    dplyr::select(-Condition) %>% 
    #full_join(Table_all_long2, by="Features" ) %>% 
    full_join(Table_all_long2, by=c("Features")) %>% #To normalize per timepoint
    mutate(Foldchange = Measure /baseline) ->Table_all_based

#subset(Table_all_based,duplicated(Measure)) #to see duplicated rows

included_vars =c("Batch", "CellLine", "Condition")
Table_all_based %>% 
    pivot_wider(all_of(included_vars),names_from = Features,values_from = Foldchange)->Table_all_based_wide

Plot for one feature


data %>%
  ggplot(aes(x = Condition, y=Gcase.activity),ordered=TRUE)+
    geom_boxplot(aes(fill=Condition),width=0.5)+
        scale_fill_manual(values=c("#2171b5","#B22222","#008B8B"))+  #blue and red
  ylim(4,9)+
    ##geom_point(aes(color=cell_line, shape=Section), size=5)
    geom_point(aes(color=CellLine),size=3)+
    scale_color_viridis(option = "D", discrete=TRUE)+
    geom_point(shape = 1,size = 3,colour = "black")+
   #facet_grid(fct_relevel(Day, "15", "60"), scales="free") +
     labs(x     ="",
        y     = "Relative GCase activity",
       fill  = "Condition",
      title = "GCase activity") +
    #stat_compare_means(comparisons=list(c("Control", "PD N370S")), method = "t.test", label="p.signif", label.x = 1.5)+
    stat_compare_means(comparisons=list(c("Control", "PD-N370S")), method = "wilcox.test", label="p.signif", label.x = 1.5, size=7)+

    #ggpubr::stat_compare_means(comparisons=my_comparisons, method="wilcox.test", p.adjust.method="BH",label="p.signif", label.x = 1.5)+
    theme_bw() +
       theme(plot.title=element_text(size=20, face="bold", hjust=0.5),
          axis.text.x=element_text(size = 17, face = "bold",angle=45, hjust=1),
          axis.text.y=element_text(size = 16),
          axis.title.x=element_blank(), 
          axis.title.y=element_text(size=20),
          legend.title = element_text(size=20),
          legend.text = element_text(size=16))-> p #change legend text font size)  
  t<- cowplot::ggdraw(cowplot::add_sub(p, "wilcox.test, ***p=0.001, **p=0.01, *p=0.05",hjust=-0.1, size=15))

  print(t)
ggsave(paste0(Sys.Date()," GCase activity DIV30.pdf"), plot=t, height=7, width=6*1.2, path=OutPath)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KLS0tDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkocGhlYXRtYXApDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KGdnc2lnbmlmKQ0KbGlicmFyeShvcGVueGxzeCkNCmxpYnJhcnkodmlyaWRpcykNCmxpYnJhcnkoamNvbG9ycykNCmBgYA0KDQpgYGB7cn0NCnNldHdkKCIvL2F0bGFzLnVuaS5sdXgvdXNlcnMvaXNhYmVsLnJvc2V0eS9HQkEvUElfRkFDUyIpDQojZGF0YSA8LSByZWFkLmNzdigiV0IgZGF0YSBmb3IgUnN0dWRpbyBwbG90cy5jc3YiLCBoZWFkZXIgPSBULCAgc2VwID0gIiwiKQ0KT3V0UGF0aD0gIi8vYXRsYXMudW5pLmx1eC91c2Vycy9pc2FiZWwucm9zZXR5L0dCQS9QSV9GQUNTIg0KZGF0YSA8LSByZWFkLnhsc3goIkFsbCBzYW1wbGVzLnhsc3giLHNoZWV0PTIpDQojZGF0YTE1IDwtIHJlYWQueGxzeCgiV0IgZGF0YSBmb3IgUnN0dWRpbyBwbG90cy54bHN4Iiwgc2hlZXQgPSAxKSAjMTVkIGFyZSBpbiBzaGVldCAxDQojRGF5PWFzLmNoYXJhY3RlcihEYXRhQ29tYmluZWQkRGF5KQ0KYGBgDQoNCk1lYW4gb2YgcmVwbGljYXRlcyAtIE5vIG5vcm1hbGl6YXRpb24NCmBgYHtyfQ0KDQojTWVhbiBvZiByZXBsaWNhdGVzDQpmZWF0dXJlX25hbWVzIDwtIGNvbG5hbWVzKGRhdGFbLDU6bmNvbChkYXRhKV0pDQogIGRhdGElPiUNCiAgICBwaXZvdF9sb25nZXIoZmVhdHVyZV9uYW1lcyxuYW1lc190byA9ICJGZWF0dXJlcyIsIHZhbHVlc190byA9ICJNZWFzdXJlIikgLT4gVGFibGVfYWxsX2xvbmcNClRhYmxlX2FsbF9sb25nID0gZHJvcF9uYShUYWJsZV9hbGxfbG9uZykgIA0KDQpUYWJsZV9hbGxfbG9uZyAlPiUNCiAgZ3JvdXBfYnkoQ29uZGl0aW9uLEJhdGNoLEZlYXR1cmVzLENlbGxMaW5lKSAlPiUNCiAgc3VtbWFyaXplKE1lYW5GZWF0dXJlcyA9IG1lYW4oTWVhc3VyZSkpIC0+IFRhYmxlX01lYW4NCg0KaW5jbHVkZWRfdmFycyA9YygiQmF0Y2giLCAiQ2VsbExpbmUiLCAiQ29uZGl0aW9uIikNClRhYmxlX01lYW4gJT4lIA0KICAgIHBpdm90X3dpZGVyKGFsbF9vZihpbmNsdWRlZF92YXJzKSxuYW1lc19mcm9tID0gRmVhdHVyZXMsdmFsdWVzX2Zyb20gPSBNZWFuRmVhdHVyZXMpLT5UYWJsZV9NZWFuX3dpZGUNCg0KYGBgDQoNCk1lYW4gb2YgcmVwbGljYXRlcyAmIG5vcm1hbGl6YXRvbiB0byBjb250cm9scw0KYGBge3J9DQoNCiAgI01lYW4gb2YgcmVwbGljYXRlcw0KZmVhdHVyZV9uYW1lcyA8LSBjb2xuYW1lcyhkYXRhWyw1Om5jb2woZGF0YSldKQ0KICBkYXRhJT4lDQogICAgcGl2b3RfbG9uZ2VyKGZlYXR1cmVfbmFtZXMsbmFtZXNfdG8gPSAiRmVhdHVyZXMiLCB2YWx1ZXNfdG8gPSAiTWVhc3VyZSIpIC0+IFRhYmxlX2FsbF9sb25nDQpUYWJsZV9hbGxfbG9uZyA9IGRyb3BfbmEoVGFibGVfYWxsX2xvbmcpICANCg0KVGFibGVfYWxsX2xvbmcgJT4lDQogIGdyb3VwX2J5KENvbmRpdGlvbixCYXRjaCxGZWF0dXJlcyxDZWxsTGluZSkgJT4lDQogIHN1bW1hcml6ZShNZWFuRmVhdHVyZXMgPSBtZWFuKE1lYXN1cmUpKSAtPiBUYWJsZV9NZWFuDQojICB1bmdyb3VwKCkgJT4lIA0KIyAgZHBseXI6OnNlbGVjdCgtQXJlYU5hbWUpICU+JSANCiMgIGZ1bGxfam9pbihUYWJsZV9hbGxfbG9uZzIsIGJ5PSJGZWF0dXJlcyIgKSANCiAgICAjZnVsbF9qb2luKFRhYmxlX2FsbF9sb25nMiwgYnk9YygiRmVhdHVyZXMiKSkgJT4lICNpZiBJIHdhbnRlZCB0byBub3JtYWxpemUgcGVyIFdCIG1lbWJyYW5lDQoNCiNOb3JtYWxpemluZyB0byBtZWFuIG9mIGNvbnRyb2xzDQpUYWJsZV9NZWFuICU+JQ0KICAgIGRwbHlyOjpmaWx0ZXIoQ29uZGl0aW9uPT0iQ29udHJvbCIpICU+JSANCiAgICBncm91cF9ieShCYXRjaCxGZWF0dXJlcywgQ29uZGl0aW9uKSAlPiUgDQogICAgI2dyb3VwX2J5KEZlYXR1cmVzLCBCYXRjaCkgJT4lIA0KICAgIHN1bW1hcmlzZShiYXNlbGluZSA9IG1lYW4oTWVhbkZlYXR1cmVzKSkgJT4lIA0KICAgIHVuZ3JvdXAoKSAlPiUgDQogICAgZHBseXI6OnNlbGVjdCgtQ29uZGl0aW9uKSAlPiUgDQogICAgI2RwbHlyOjpzZWxlY3QoLUJhdGNoKSAlPiUNCiAgICBmdWxsX2pvaW4oVGFibGVfTWVhbiwgYnk9YygiRmVhdHVyZXMiLCJCYXRjaCIpKSAlPiUgDQogICAgI2Z1bGxfam9pbihUYWJsZV9hbGxfbG9uZzIsIGJ5PWMoIkZlYXR1cmVzIikpICU+JSAjaWYgSSB3YW50ZWQgdG8gbm9ybWFsaXplIHBlciBXQiBtZW1icmFuZQ0KICAgIG11dGF0ZShGb2xkY2hhbmdlID0gTWVhbkZlYXR1cmVzIC9iYXNlbGluZSkgLT5UYWJsZV9hbGxfYmFzZWQNCg0KaW5jbHVkZWRfdmFycyA9YygiQmF0Y2giLCAiQ2VsbExpbmUiLCAiQ29uZGl0aW9uIikNClRhYmxlX2FsbF9iYXNlZCAlPiUgDQogICAgcGl2b3Rfd2lkZXIoYWxsX29mKGluY2x1ZGVkX3ZhcnMpLG5hbWVzX2Zyb20gPSBGZWF0dXJlcyx2YWx1ZXNfZnJvbSA9IEZvbGRjaGFuZ2UpLT5UYWJsZV9hbGxfYmFzZWRfd2lkZQ0KYGBgDQoNCmBgYHtyfQ0KVGFibGVfYWxsX2Jhc2VkX3dpZGU8LWZpbHRlcihUYWJsZV9hbGxfYmFzZWRfd2lkZSxCYXRjaCE9IjQ2IikNClRhYmxlX2FsbF9iYXNlZF93aWRlICU+JQ0KICBmaWx0ZXIoIUNvbmRpdGlvbiVpbiVjKCJDb250cm9sX0RGWCIsIkdCQS1QRF9ERlgiKSkgLT4gVGFibGVfYWxsX2Jhc2VkX3dpZGUNCg0KVGFibGVfTWVhbl93aWRlPC1maWx0ZXIoVGFibGVfTWVhbl93aWRlLEJhdGNoIT0iNDYiKQ0KDQpmb3IgKGkgaW4gMTpsZW5ndGgoZmVhdHVyZV9uYW1lcykpIHsNClRhYmxlX01lYW5fd2lkZSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHM9ZmVhdHVyZV9uYW1lcywgbmFtZXNfdG8gPSAiZmVhdHVyZSIsIHZhbHVlc190byA9ICJ2YWx1ZSIpICU+JQ0KICBmaWx0ZXIoZmVhdHVyZSAlaW4lIGZlYXR1cmVfbmFtZXNbaV0pICU+JQ0KICBnZ3Bsb3QoIGFlcyh4PWZhY3RvcihDb25kaXRpb24sIGxldmVsID0gYygiQ1RSTCIsICJHQkEtUEQiKSksIHk9dmFsdWUpKSArDQogICNnZW9tX3Zpb2xpbiggYWVzKGZpbGw9Q29uZGl0aW9uKSxzaG93LmxlZ2VuZCA9IFQsIHRyaW09VCkrDQoNCiAgI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz0gYygiI2JkZDdlNyIsIiMyMTcxYjUiKSxuYW1lID0gIkNvbmRpdGlvbiIsIGd1aWRlID0gRkFMU0UpKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz0gYygiI0ZGRkZGRiIsIiM5OTk5OTkiKSxuYW1lID0gIkNvbmRpdGlvbiIsIGd1aWRlID0gIm5vbmUiKSsgI2d1aWRlIGZhbHNlIHdpbGwgcmVtb3ZlIHRoZSBsZWdlbmQgZm9yIHRoZSBjb25kaXRpb24NCiAgICAjZ2VvbV9ib3hwbG90KHdpZHRoPTAuMDcsIGZpbGw9IndoaXRlIikgKyANCiAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Q29uZGl0aW9uKSxzaG93LmxlZ2VuZCA9IEZBTFNFLHdpZHRoPTAuNSkrICNzaG93LmxlZ2VuZCB3aWxsIHJlbW92ZSBib3ggYXJvdW5kIHRoZSBwb2ludHMgb2YgdGhlIGxlZ2VuZA0KICAgIGdlb21fcG9pbnQoYWVzKGNvbG9yPUNlbGxMaW5lKSxzaXplPTMsc2hvdy5sZWdlbmQgPSBULGFscGhhID0gMC41KSsNCiAgICAjc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHJldihicmV3ZXIucGFsKG49NiwgbmFtZT0iT3JSZCIpKSkrDQogICAgc2NhbGVfY29sb3JfamNvbG9ycygicGFsNyIpKw0KICAgICNzY2FsZV9jb2xvcl92aXJpZGlzKG9wdGlvbiA9ICJEIiwgZGlzY3JldGU9VFJVRSkrDQogICAgI2dlb21fcG9pbnQoc2hhcGUgPSAxLHNpemUgPSAzLGNvbG91ciA9ICJibGFjayIpKw0KICAgIHRoZW1lKGxlZ2VuZC5rZXk9ZWxlbWVudF9ibGFuaygpKSArDQogICAgDQogIGdlb21fc2lnbmlmKGNvbXBhcmlzb25zID0gbGlzdChjKCJDVFJMIiwgIkdCQS1QRCIpKSwgdGVzdD0nd2lsY294LnRlc3QnLA0KICAgICAgICAgICAgICB2anVzdD0wLjUsIHNpemU9MC41LCB0ZXh0c2l6ZT05LCBtYXBfc2lnbmlmX2xldmVsPWMoIioqKiI9MC4wMDEsICIqKiI9MC4wMSwgIioiPTAuMDUsICAiICI9MikgKSArDQogICNmYWNldF9ncmlkKH5mY3RfcmVsZXZlbChEYXksICJkMTUiLCAiZDMwIiwiZDYwIiwgImQ5MCIpLCBzY2FsZXM9ImZyZWUiKSArDQogICAgICBsYWJzKHggICAgID0gIiIsDQogICAgICAgeSAgICAgPSBwYXN0ZShmZWF0dXJlX25hbWVzW2ldKSwNCiAgICAgICAjeSAgICAgPSBwYXN0ZShuYW1lc1tpXSksDQogICAgICAgZmlsbCAgPSAiQ29uZGl0aW9uIiwNCiAgICAgICAjdGl0bGUgPSBwYXN0ZShmZWF0dXJlX25hbWVzW2ldKSkgKw0KICAgICAgIHRpdGxlID0gIiIgKSsNCiAgdGhlbWVfYncoKSArDQogIHRoZW1lKA0KICAgIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAnYmxhY2snLCBzaXplID0gMC41KSAsDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MjEsIGNvbG9yPSJibGFjayIpLA0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjEpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9MTUsIGNvbG9yPSJibGFjayIpLA0KICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfbGluZSgpLA0KICAgIGF4aXMudGlja3MubGVuZ3RoPXVuaXQoLjI1LCAiY20iKSwNCiAgICAjY2hhbmdlIGxlZ2VuZCB0ZXh0IGZvbnQgc2l6ZSkNCiAgICAjbGVnZW5kLmtleS5zaXplID0gdW5pdCgwLjcsICJjbSIpLA0KICAgICNsZWdlbmQua2V5LndpZHRoID0gdW5pdCgwLjYsImNtIiksDQogICAgbGVnZW5kLmtleT1lbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjAsIGhqdXN0PTAuNSwgdmp1c3Q9IDEsIGZhY2UgPSAiYm9sZCIpLA0KICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X2JsYW5rKCksI2VsZW1lbnRfdGV4dChzaXplID0gMiwgaGp1c3Q9MC41KQ0KICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xMiwgdmp1c3Q9MC41KSwNCiAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9ImxpZ2h0Z3JheSIpLA0KICAgIyBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoZmlsbCA9IE5BLCBjb2xvciA9ICJibGFjayIpLA0KICAgIHBhbmVsLnNwYWNpbmcueSA9IHVuaXQoMC44LCAibGluZXMiKSwNCiAgICBzdHJpcC5zd2l0Y2gucGFkLndyYXA9dW5pdCgyMCwgImxpbmVzIiksDQogICAgbGVnZW5kLnBvc2l0aW9uPSJyaWdodCIsDQogICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNyksDQogICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTkpDQogICAgDQogICkgIC0+IHANCiAgI3Q8LSBjb3dwbG90OjpnZ2RyYXcoY293cGxvdDo6YWRkX3N1YihwLCAiV2lsY294LXRlc3QsICoqKnA9MC4wMDEsICoqcD0wLjAxLCAqcD0wLjA1IixoanVzdD0tMC4yLCBzaXplPTEzKSkNCiAgcHJpbnQocCkNCiAgIyNnZ3NhdmUocGFzdGUwKFN5cy5EYXRlKCksIl8iLCBuYW1lc1tpXSwgIi5wZGYiKSwgcGxvdD10KQ0KZ2dzYXZlKHBhc3RlMChTeXMuRGF0ZSgpLChzcHJpbnRmKCJQbG90XyVzX0RJVjMwLnBkZiIsZmVhdHVyZV9uYW1lc1tpXSkpKSxoZWlnaHQ9NikNCn0NCmBgYA0KDQpOb3JtYWxpemF0aW9uIGlmIG1lYW4gb2YgZHVwbGljYXRlcyBhbHJlYWR5IGRvbmUNCmBgYHtyfQ0KICBkYXRhJT4lDQogICAgcGl2b3RfbG9uZ2VyKGZlYXR1cmVfbmFtZXMsbmFtZXNfdG8gPSAiRmVhdHVyZXMiLCB2YWx1ZXNfdG8gPSAiTWVhc3VyZSIpIC0+IFRhYmxlX2FsbF9sb25nDQpUYWJsZV9hbGxfbG9uZzIgPSBkcm9wX25hKFRhYmxlX2FsbF9sb25nKSAgDQpUYWJsZV9hbGxfbG9uZzIgJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIoQ29uZGl0aW9uPT0iQ29udHJvbCIpICU+JSANCiAgICAjZ3JvdXBfYnkoV0IsIEJhdGNoLCBDb25kaXRpb24sRmVhdHVyZXMpICU+JSANCiAgICBncm91cF9ieShDb25kaXRpb24sRmVhdHVyZXMpICU+JSANCiAgICBzdW1tYXJpc2UoYmFzZWxpbmUgPSBtZWRpYW4oTWVhc3VyZSkpICU+JSANCiAgICB1bmdyb3VwKCkgJT4lIA0KICAgIGRwbHlyOjpzZWxlY3QoLUNvbmRpdGlvbikgJT4lIA0KICAgICNmdWxsX2pvaW4oVGFibGVfYWxsX2xvbmcyLCBieT0iRmVhdHVyZXMiICkgJT4lIA0KICAgIGZ1bGxfam9pbihUYWJsZV9hbGxfbG9uZzIsIGJ5PWMoIkZlYXR1cmVzIikpICU+JSAjVG8gbm9ybWFsaXplIHBlciB0aW1lcG9pbnQNCiAgICBtdXRhdGUoRm9sZGNoYW5nZSA9IE1lYXN1cmUgL2Jhc2VsaW5lKSAtPlRhYmxlX2FsbF9iYXNlZA0KDQojc3Vic2V0KFRhYmxlX2FsbF9iYXNlZCxkdXBsaWNhdGVkKE1lYXN1cmUpKSAjdG8gc2VlIGR1cGxpY2F0ZWQgcm93cw0KDQppbmNsdWRlZF92YXJzID1jKCJCYXRjaCIsICJDZWxsTGluZSIsICJDb25kaXRpb24iKQ0KVGFibGVfYWxsX2Jhc2VkICU+JSANCiAgICBwaXZvdF93aWRlcihhbGxfb2YoaW5jbHVkZWRfdmFycyksbmFtZXNfZnJvbSA9IEZlYXR1cmVzLHZhbHVlc19mcm9tID0gRm9sZGNoYW5nZSktPlRhYmxlX2FsbF9iYXNlZF93aWRlDQoNCmBgYA0KDQpQbG90IGZvciBvbmUgZmVhdHVyZQ0KYGBge3J9DQoNCmRhdGEgJT4lDQogIGdncGxvdChhZXMoeCA9IENvbmRpdGlvbiwgeT1HY2FzZS5hY3Rpdml0eSksb3JkZXJlZD1UUlVFKSsNCiAgICBnZW9tX2JveHBsb3QoYWVzKGZpbGw9Q29uZGl0aW9uKSx3aWR0aD0wLjUpKw0KICAgICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YygiIzIxNzFiNSIsIiNCMjIyMjIiLCIjMDA4QjhCIikpKyAgI2JsdWUgYW5kIHJlZA0KICB5bGltKDQsOSkrDQogICAgIyNnZW9tX3BvaW50KGFlcyhjb2xvcj1jZWxsX2xpbmUsIHNoYXBlPVNlY3Rpb24pLCBzaXplPTUpDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3I9Q2VsbExpbmUpLHNpemU9MykrDQogICAgc2NhbGVfY29sb3JfdmlyaWRpcyhvcHRpb24gPSAiRCIsIGRpc2NyZXRlPVRSVUUpKw0KICAgIGdlb21fcG9pbnQoc2hhcGUgPSAxLHNpemUgPSAzLGNvbG91ciA9ICJibGFjayIpKw0KICAgI2ZhY2V0X2dyaWQoZmN0X3JlbGV2ZWwoRGF5LCAiMTUiLCAiNjAiKSwgc2NhbGVzPSJmcmVlIikgKw0KICAgICBsYWJzKHggICAgID0iIiwNCiAgICAgICAgeSAgICAgPSAiUmVsYXRpdmUgR0Nhc2UgYWN0aXZpdHkiLA0KICAgICAgIGZpbGwgID0gIkNvbmRpdGlvbiIsDQogICAgICB0aXRsZSA9ICJHQ2FzZSBhY3Rpdml0eSIpICsNCiAgICAjc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zPWxpc3QoYygiQ29udHJvbCIsICJQRCBOMzcwUyIpKSwgbWV0aG9kID0gInQudGVzdCIsIGxhYmVsPSJwLnNpZ25pZiIsIGxhYmVsLnggPSAxLjUpKw0KICAgIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucz1saXN0KGMoIkNvbnRyb2wiLCAiUEQtTjM3MFMiKSksIG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsIGxhYmVsPSJwLnNpZ25pZiIsIGxhYmVsLnggPSAxLjUsIHNpemU9NykrDQoNCiAgICAjZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnM9bXlfY29tcGFyaXNvbnMsIG1ldGhvZD0id2lsY294LnRlc3QiLCBwLmFkanVzdC5tZXRob2Q9IkJIIixsYWJlbD0icC5zaWduaWYiLCBsYWJlbC54ID0gMS41KSsNCiAgICB0aGVtZV9idygpICsNCiAgICAgICB0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTIwLCBmYWNlPSJib2xkIiwgaGp1c3Q9MC41KSwNCiAgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZSA9IDE3LCBmYWNlID0gImJvbGQiLGFuZ2xlPTQ1LCBoanVzdD0xKSwNCiAgICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwNCiAgICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLCANCiAgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KHNpemU9MjApLA0KICAgICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTIwKSwNCiAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE2KSktPiBwICNjaGFuZ2UgbGVnZW5kIHRleHQgZm9udCBzaXplKSAgDQogIHQ8LSBjb3dwbG90OjpnZ2RyYXcoY293cGxvdDo6YWRkX3N1YihwLCAid2lsY294LnRlc3QsICoqKnA9MC4wMDEsICoqcD0wLjAxLCAqcD0wLjA1IixoanVzdD0tMC4xLCBzaXplPTE1KSkNCg0KICBwcmludCh0KQ0KZ2dzYXZlKHBhc3RlMChTeXMuRGF0ZSgpLCIgR0Nhc2UgYWN0aXZpdHkgRElWMzAucGRmIiksIHBsb3Q9dCwgaGVpZ2h0PTcsIHdpZHRoPTYqMS4yLCBwYXRoPU91dFBhdGgpDQpgYGANCg0KDQo=