Data Import and Setup
Reads the Gencode summarized data files from Kraken Output (https://github.com/npbhavya/Kraken2-output-manipulation)
into R.
gencode_PB=read.csv(file="gencode_PM_PB_species_kraken_summary", header=TRUE)
gencode_PL=read.csv(file="gencode_PM_PL_species_kraken_summary", header=TRUE)
gencode_PM=read.csv(file="gencode_PM_PM_species_kraken_summary", header=TRUE)
gencode_PS=read.csv(file="gencode_PM_PS_species_kraken_summary", header=TRUE)
gencode_star=read.delim(file="star_alignment_plot.tsv", header=TRUE, sep="\t")
gencode_PB$PM_14_PB_RN_BA_220606=as.integer(gencode_PB$PM_14_PB_RN_BA_220606)
gencode_PB$PM_58_PB_RN_BA_220916=as.integer(gencode_PB$PM_58_PB_RN_BA_220916)
gencode_PL$PM_15_PL_RN_BA_220622=as.integer(gencode_PL$PM_15_PL_RN_BA_220622)
gencode_PL$PM_58_PL_RN_BA_220923=as.integer(gencode_PL$PM_58_PL_RN_BA_220923)
gencode_PM$PM_15_PM_RN_BA_220614=as.integer(gencode_PM$PM_15_PM_RN_BA_220614)
gencode_PM$PM_58_PM_RN_BA_220920=as.integer(gencode_PM$PM_58_PM_RN_BA_220920)
gencode_PS$PM_17_PS_RN_BA_220628=as.integer(gencode_PS$PM_17_PS_RN_BA_220628)
gencode_PS$PM_58_PS_RN_BA_220921=as.integer(gencode_PS$PM_58_PS_RN_BA_220921)
Pivots the data from wide to long format, renames the new columns,
arranges the columns in ascending order by sample name and descending
order by number of counts, groups the rows by sample, removes the “Homo”
rows, slices the top 5 rows for each sample, and removes all information
from the sample codes besides the project identifier, the subject
number, and the collection/extraction method identifier.
gencode_PB_long_top5=gencode_PB %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5)
gencode_PB_long_top5$Sample=gsub("_RN.*", "", gencode_PB_long_top5$Sample)
sum(gencode_PB_long_top5$Counts)
[1] 37289760
gencode_PL_long_top5=gencode_PL %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5)
gencode_PL_long_top5$Sample=gsub("_RN.*", "", gencode_PL_long_top5$Sample)
sum(gencode_PL_long_top5$Counts)
[1] 161591358
gencode_PM_long_top5=gencode_PM %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5)
gencode_PM_long_top5$Sample=gsub("_RN.*", "", gencode_PM_long_top5$Sample)
sum(gencode_PM_long_top5$Counts)
[1] 121341438
gencode_PS_long_top5=gencode_PS %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5)
gencode_PS_long_top5$Sample=gsub("_RN.*", "", gencode_PS_long_top5$Sample)
sum(gencode_PS_long_top5$Counts)
[1] 164300830
Examples of before and after data format manipulation.
head(gencode_PB, n=10)
head(gencode_PB_long_top5, n=10)
gencode_STAR_PB=gencode_star %>%
filter(str_detect(Category, "PB_RN_BA"))
gencode_STAR_PL=gencode_star %>%
filter(str_detect(Category, "PL_RN_BA"))
gencode_STAR_PM=gencode_star %>%
filter(str_detect(Category, "PM_RN_BA"))
gencode_STAR_PS=gencode_star %>%
filter(str_detect(Category, "PS_RN_BA"))
gencode_STAR_PB_combined=gencode_PB %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PB, gencode_PB, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
select(Sample, Contamination, Uniquely_mapped) %>%
pivot_longer(!Sample, names_to="Category", values_to="Counts")
gencode_STAR_PB_combined$Sample=gsub("_RN.*", "", gencode_STAR_PB_combined$Sample)
gencode_PB %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PB, gencode_PB, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE)))
(58318198/(58318198+2620435021))*100
[1] 2.177065
gencode_STAR_PL_combined=gencode_PL %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PL, gencode_PL, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
select(Sample, Contamination, Uniquely_mapped) %>%
pivot_longer(!Sample, names_to="Category", values_to="Counts")
gencode_STAR_PL_combined$Sample=gsub("_RN.*", "", gencode_STAR_PL_combined$Sample)
gencode_PL %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PL, gencode_PL, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE)))
(196998568/(196998568+1864812120))*100
[1] 9.554639
gencode_STAR_PM_combined=gencode_PM %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PM, gencode_PM, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
select(Sample, Contamination, Uniquely_mapped) %>%
pivot_longer(!Sample, names_to="Category", values_to="Counts")
gencode_STAR_PM_combined$Sample=gsub("_RN.*", "", gencode_STAR_PM_combined$Sample)
gencode_PM %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PM, gencode_PM, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE)))
(152994840/(152994840+2618897827))*100
[1] 5.519508
gencode_STAR_PS_combined=gencode_PS %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PS, gencode_PS, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
select(Sample, Contamination, Uniquely_mapped) %>%
pivot_longer(!Sample, names_to="Category", values_to="Counts")
gencode_STAR_PS_combined$Sample=gsub("_RN.*", "", gencode_STAR_PS_combined$Sample)
gencode_PS %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE))) %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Category=name, Contamination=value) %>%
left_join(gencode_STAR_PS, gencode_PS, by=join_by(Category==Category)) %>%
rename(Sample=Category) %>%
arrange(Sample) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm=TRUE)))
(217314524/(217314524+1425300221))*100
[1] 13.22979
Defines the function for use in creating the y-axis labels for the
plots.
everysecond=function(x){
x=sort(unique(x))
x[seq(2, length(x), 2)]=""
x
}
Summarization of the occurrence of a top 5 Species across all top 5
for each collection method.
gencode_PB_long_top5_summary=gencode_PB %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5) %>%
ungroup(Sample) %>%
group_by(Taxa) %>%
summarise(n=n())
gencode_PL_long_top5_summary=gencode_PL %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5) %>%
ungroup(Sample) %>%
group_by(Taxa) %>%
summarise(n=n())
gencode_PM_long_top5_summary=gencode_PM %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5) %>%
ungroup(Sample) %>%
group_by(Taxa) %>%
summarise(n=n())
gencode_PS_long_top5_summary=gencode_PS %>%
pivot_longer(cols=starts_with("PM")) %>%
rename(Sample=name, Counts=value) %>%
arrange(Sample, desc(Counts)) %>%
group_by(Sample) %>%
filter(!str_detect(Taxa, "Homo sapiens")) %>%
slice(1:5) %>%
ungroup(Sample) %>%
group_by(Taxa) %>%
summarise(n=n())
An example of summarized data format manipulation.
gencode_PB_long_top5_summary
Plots
Brain (PB)
# Counts
# ggplot()+
# geom_col(data=gencode_PB_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
# scale_y_discrete(labels=everysecond(gencode_PB_long_top5$Sample), expand=expansion(mult=0.03))+
# scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))
# Proportion
# ggplot()+
# geom_col(data=gencode_PB_long_top5, aes(x=Counts, y=Sample, fill=Taxa), color="black", position="fill")+
# scale_y_discrete(labels=everysecond(gencode_PB_long_top5$Sample))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Proportion")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PB_long_top5_summary, aes(x=n, y=Taxa, fill=Taxa), color="black")+
# geom_text(data=gencode_PB_long_top5_summary, aes(x=n, y=Taxa, label=n), hjust=-0.2)+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PB_long_top5_summary, aes(x=n, y=reorder(Taxa, n), fill=Taxa), color="black")+
# geom_text(data=gencode_PB_long_top5_summary, aes(x=n, y=reorder(Taxa, n), label=n), hjust=-0.2)+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")+
# ylab("Taxa")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PB_long_top5_summary, aes(x=n, y=reorder(Taxa, n)), fill="black", color="black", alpha=0.5)+
# geom_text(data=gencode_PB_long_top5_summary, aes(x=n, y=reorder(Taxa, n), label=n), hjust=-0.2)+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")+
# ylab("Taxa")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PB_long_top5_summary, aes(x=reorder(Taxa, n), y=n, fill=Taxa), color="black")+
# geom_text(data=gencode_PB_long_top5_summary, aes(x=reorder(Taxa, n), y=n, label=n), vjust=-0.2)+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1), angle=60, hjust=1),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Taxa")+
# ylab("Occurrence")
# Taxa Occurrence
# ggplot()+
# geom_segment(data=gencode_PB_long_top5_summary, aes(y=reorder(Taxa, n), yend=reorder(Taxa, n), x=0, xend=n),
# color="black")+
# geom_point(data=gencode_PB_long_top5_summary, aes(x=n, y=reorder(Taxa, n), color=Taxa), size=3) +
# scale_color_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")+
# ylab("Taxa")
# Counts
brain1=ggplot()+
geom_col(data=gencode_PB_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
scale_y_discrete(labels=everysecond(gencode_PB_long_top5$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(10)), name="Taxa",
limits=c("Babesia bovis", "Clostridium baratii", "Clostridium perfringens", "Myroides phaeus",
"Paeniclostridium sordellii", "Paraclostridium bifermentans",
"Proteus mirabilis", "Romboutsia hominis", "Romboutsia ilealis",
"Viridibacillus sp. JNUCC-6"),
labels=c("B. bovis", "C. baratii", "C. perfringens", "M. phaeus",
"P. sordellii", "P. bifermentans",
"P. mirabilis", "R. hominis", "R. ilealis",
"V. sp. JNUCC-6"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="italic", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=5))
# Taxa Occurrence
brain2=ggplot()+
geom_col(data=gencode_PB_long_top5_summary, aes(x=reorder(Taxa, n), y=n), fill="black", color="black", alpha=0.75)+
geom_text(data=gencode_PB_long_top5_summary, aes(x=reorder(Taxa, n), y=n, label=n), vjust=-0.4, size=1.1)+
scale_x_discrete(expand=expansion(mult=0.02))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
axis.text.x=element_text(color="black", face="italic", size=rel(0.75), angle=60, hjust=1, vjust=1),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_blank(),
axis.title.y=element_text(color="black", face="bold", size=rel(1)),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.x=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="none",
legend.key.size=unit(rel(0.5), "cm"),
legend.title=element_text(color="black", face="bold", size=rel(0.6)),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
xlab("Taxa")+
ylab("Occurrence")
# Counts
brain3=ggplot()+
geom_col(data=gencode_STAR_PB_combined, aes(x=Counts, y=Sample, fill=Category), color="black")+
scale_y_discrete(labels=everysecond(gencode_STAR_PB_combined$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(2)), name="Category",
limits=c("Contamination", "Uniquely_mapped"),
labels=c("Contaminants", "Uniquely Mapped"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=1))
Combined Taxa Figure
brain_patchwork=(brain3 + brain1) / brain2 + plot_layout(nrow=2)
brain_patchwork + plot_annotation(tag_levels="A")
ggsave("PM_brain_taxonomy_plots.png", width=7, height=10, unit="in", dpi=320)

Lung (PL)
# Counts
# ggplot()+
# geom_col(data=gencode_PL_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
# scale_y_discrete(labels=everysecond(gencode_PL_long_top5$Sample), expand=expansion(mult=0.03))+
# scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))
# Proportion
# ggplot()+
# geom_col(data=gencode_PL_long_top5, aes(x=Counts, y=Sample, fill=Taxa), color="black", position="fill")+
# scale_y_discrete(labels=everysecond(gencode_PL_long_top5$Sample))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Proportion")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PL_long_top5_summary, aes(x=n, y=Taxa, fill=Taxa), color="black")+
# geom_text(data=gencode_PL_long_top5_summary, aes(x=n, y=Taxa, label=n), hjust=-0.2)+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")
# Counts
lung1=ggplot()+
geom_col(data=gencode_PL_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
scale_y_discrete(labels=everysecond(gencode_PL_long_top5$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(15)), name="Taxa",
limits=c("Anaerostipes hadrus", "Clostridium baratii", "Clostridium bornimense",
"Clostridium botulinum", "Clostridium cellulovorans", "Clostridium drakei",
"Clostridium novyi", "Clostridium sp. JN-9", "Clostridium thermarum",
"Paeniclostridium sordellii", "Paraclostridium bifermentans",
"Peptacetobacter hiranonis", "Romboutsia hominis", "Romboutsia ilealis",
"Romboutsia sp. CE17"),
labels=c("A. hadrus", "C. baratii", "C. bornimense", "C. botulinum", "C. cellulovorans", "C. drakei",
"C. novyi", "C. sp. JN-9", "C. thermarum", "P. sordellii", "P. bifermentans",
"P. hiranonis", "R. hominis", "R. ilealis", "R. sp. CE17"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="italic", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=8))
# Taxa Occurrence
lung2=ggplot()+
geom_col(data=gencode_PL_long_top5_summary, aes(x=reorder(Taxa, n), y=n), fill="black", color="black", alpha=0.75)+
geom_text(data=gencode_PL_long_top5_summary, aes(x=reorder(Taxa, n), y=n, label=n), vjust=-0.4, size=1.1)+
scale_x_discrete(expand=expansion(mult=0.02))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
axis.text.x=element_text(color="black", face="italic", size=rel(0.5), angle=60, hjust=1, vjust=1),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_blank(),
axis.title.y=element_text(color="black", face="bold", size=rel(1)),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.x=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="none",
legend.key.size=unit(rel(0.5), "cm"),
legend.title=element_text(color="black", face="bold", size=rel(0.6)),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
xlab("Taxa")+
ylab("Occurrence")
# Counts
lung3=ggplot()+
geom_col(data=gencode_STAR_PL_combined, aes(x=Counts, y=Sample, fill=Category), color="black")+
scale_y_discrete(labels=everysecond(gencode_STAR_PL_combined$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(2)), name="Category",
limits=c("Contamination", "Uniquely_mapped"),
labels=c("Contaminants", "Uniquely Mapped"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=1))
Combined Taxa Figure
lung_patchwork=(lung3 + lung1) / lung2 + plot_layout(nrow=2)
lung_patchwork + plot_annotation(tag_levels="A")
ggsave("PM_lung_taxonomy_plots.png", width=7, height=10, unit="in", dpi=320)

Muscle (PM)
# Counts
# ggplot()+
# geom_col(data=gencode_PM_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
# scale_y_discrete(labels=everysecond(gencode_PM_long_top5$Sample), expand=expansion(mult=0.03))+
# scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# # legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.title=element_blank(),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))
# Proportion
# ggplot()+
# geom_col(data=gencode_PM_long_top5, aes(x=Counts, y=Sample, fill=Taxa), color="black", position="fill")+
# scale_y_discrete(labels=everysecond(gencode_PM_long_top5$Sample))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Proportion")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PM_long_top5_summary, aes(x=n, y=Taxa, fill=Taxa), color="black")+
# geom_text(data=gencode_PM_long_top5_summary, aes(x=n, y=Taxa, label=n), hjust=-0.2)+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")
# Counts
muscle1=ggplot()+
geom_col(data=gencode_PM_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
scale_y_discrete(labels=everysecond(gencode_PM_long_top5$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(14)), name="Taxa",
limits=c("Clostridium baratii", "Clostridium chauvoei", "Clostridium isatidis", "Clostridium novyi",
"Clostridium septicum", "Haemophilus parainfluenzae", "Ignatzschineria sp. HR5S32",
"Myroides phaeus", "Paeniclostridium sordellii", "Photobacterium damselae",
"Photobacterium toruni", "Vagococcus teuberi", "Veillonella atypica", "Veillonella parvula"),
labels=c("C. baratii", "C. chauvoei", "C. isatidis", "C. novyi",
"C. septicum", "H. parainfluenzae", "I. sp. HR5S32",
"M. phaeus", "P. sordellii", "P. damselae",
"P. toruni", "V. teuberi", "V. atypica", "V. parvula"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="italic", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=7))
# Taxa Occurrence
muscle2=ggplot()+
geom_col(data=gencode_PM_long_top5_summary, aes(x=reorder(Taxa, n), y=n), fill="black", color="black", alpha=0.75)+
geom_text(data=gencode_PM_long_top5_summary, aes(x=reorder(Taxa, n), y=n, label=n), vjust=-0.4, size=1.1)+
scale_x_discrete(expand=expansion(mult=0.02))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
axis.text.x=element_text(color="black", face="italic", size=rel(0.5), angle=60, hjust=1, vjust=1),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_blank(),
axis.title.y=element_text(color="black", face="bold", size=rel(1)),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.x=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="none",
legend.key.size=unit(rel(0.5), "cm"),
legend.title=element_text(color="black", face="bold", size=rel(0.6)),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
xlab("Taxa")+
ylab("Occurrence")
# Counts
muscle3=ggplot()+
geom_col(data=gencode_STAR_PM_combined, aes(x=Counts, y=Sample, fill=Category), color="black")+
scale_y_discrete(labels=everysecond(gencode_STAR_PM_combined$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(2)), name="Category",
limits=c("Contamination", "Uniquely_mapped"),
labels=c("Contaminants", "Uniquely Mapped"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=1))
Combined Taxa Figure
muscle_patchwork=(muscle3 + muscle1) / muscle2 + plot_layout(nrow=2)
muscle_patchwork + plot_annotation(tag_levels="A")
ggsave("PM_muscle_taxonomy_plots.png", width=7, height=10, unit="in", dpi=320)

Blood (PS)
# Counts
# ggplot()+
# geom_col(data=gencode_PS_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
# scale_y_discrete(labels=everysecond(gencode_PS_long_top5$Sample), expand=expansion(mult=0.03))+
# scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# # legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.title=element_blank(),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))
# Proportion
# ggplot()+
# geom_col(data=gencode_PS_long_top5, aes(x=Counts, y=Sample, fill=Taxa), color="black", position="fill")+
# scale_y_discrete(labels=everysecond(gencode_PS_long_top5$Sample))+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="bottom",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Proportion")
# Taxa Occurrence
# ggplot()+
# geom_col(data=gencode_PS_long_top5_summary, aes(x=n, y=Taxa, fill=Taxa), color="black")+
# geom_text(data=gencode_PS_long_top5_summary, aes(x=n, y=Taxa, label=n), hjust=-0.2)+
# scale_fill_manual(values=as.vector(polychrome(26)))+
# theme_minimal()+
# theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
# axis.text.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
# panel.border=element_rect(color="black", linewidth=1, fill=NA),
# strip.background=element_rect(color="black", linewidth=1),
# strip.text=element_text(color="black", face="bold", size=rel(0.8)),
# axis.line=element_blank(),
# axis.ticks=element_line(linewidth=1),
# legend.position="none",
# legend.key.size=unit(rel(0.5), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(0.6)),
# legend.text=element_text(color="black", face="bold", size=rel(0.6)),
# plot.title=element_text(color="black", face="bold", size=rel(1)),
# plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
# xlab("Occurrence")
# Counts
blood1=ggplot()+
geom_col(data=gencode_PS_long_top5, aes(x=Counts, y=Sample, fill=if_else(Counts>1000000, Taxa, NA)), color="black")+
scale_y_discrete(labels=everysecond(gencode_PS_long_top5$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(21)), name="Taxa",
limits=c("Anaerostipes hadrus", "Bacteroides salyersiae", "Blautia obeum", "Blautia wexlerae",
"Carnobacterium divergens", "Clostridium baratii", "Clostridium gasigenes",
"Clostridium manihotivorum", "Clostridium novyi", "Clostridium perfringens",
"Clostridium septicum", "Enterobacter hormaechei", "Ewingella americana",
"Limnobaculum parvum", "Paeniclostridium sordellii", "Phocaeicola dorei",
"Pseudomonas lundensis", "Romboutsia hominis", "Romboutsia ilealis", "Rouxiella badensis",
"Vagococcus teuberi"),
labels=c("A. hadrus", "B. salyersiae", "B. obeum", "B. wexlerae",
"C. divergens", "C. baratii", "C. gasigenes",
"C. manihotivorum", "C. novyi", "C. perfringens",
"C. speticum", "E. hormaechei", "E. americana",
"L. parvum", "P. sordellii", "P. dorei",
"P. lundensis", "R. hominis", "R. ilealis", "R. badensis",
"V. teuberi"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="italic", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=11))
# Taxa Occurrence
blood2=ggplot()+
geom_col(data=gencode_PS_long_top5_summary, aes(x=reorder(Taxa, n), y=n), fill="black", color="black", alpha=0.75)+
geom_text(data=gencode_PS_long_top5_summary, aes(x=reorder(Taxa, n), y=n, label=n), vjust=-0.4, size=1.1)+
scale_x_discrete(expand=expansion(mult=0.02))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(1)),
axis.text.x=element_text(color="black", face="italic", size=rel(0.5), angle=60, hjust=1, vjust=1),
# axis.title.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_blank(),
axis.title.y=element_text(color="black", face="bold", size=rel(1)),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.x=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="none",
legend.key.size=unit(rel(0.5), "cm"),
legend.title=element_text(color="black", face="bold", size=rel(0.6)),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
xlab("Taxa")+
ylab("Occurrence")
# Counts
blood3=ggplot()+
geom_col(data=gencode_STAR_PS_combined, aes(x=Counts, y=Sample, fill=Category), color="black")+
scale_y_discrete(labels=everysecond(gencode_STAR_PS_combined$Sample), expand=expansion(mult=0.03))+
scale_x_continuous(labels=scales::label_number_si(), expand=expansion(mult=0.03))+
scale_fill_manual(values=as.vector(polychrome(2)), name="Category",
limits=c("Contamination", "Uniquely_mapped"),
labels=c("Contaminants", "Uniquely Mapped"))+
theme_minimal()+
theme(axis.text.y=element_text(color="black", face="bold", size=rel(0.75)),
axis.text.x=element_text(color="black", face="bold", size=rel(1)),
axis.title.x=element_text(color="black", face="bold", size=rel(1)),
# axis.title.y=element_text(color="black", face="bold", size=rel(1)),
axis.title.y=element_blank(),
panel.border=element_rect(color="black", linewidth=1, fill=NA),
panel.grid.major.y=element_blank(),
strip.background=element_rect(color="black", linewidth=1),
strip.text=element_text(color="black", face="bold", size=rel(0.8)),
axis.line=element_blank(),
axis.ticks=element_line(linewidth=1),
legend.position="bottom",
legend.key.size=unit(rel(0.25), "cm"),
# legend.title=element_text(color="black", face="bold", size=rel(1)),
legend.title=element_blank(),
legend.text=element_text(color="black", face="bold", size=rel(0.6)),
plot.title=element_text(color="black", face="bold", size=rel(1)),
plot.margin=unit(c(0.1, 0.3, 0.1, 0.1), "cm"))+
guides(fill=guide_legend(nrow=1))
Combined Taxa Figure
blood_patchwork=(blood3 + blood1) / blood2 + plot_layout(nrow=2)
blood_patchwork + plot_annotation(tag_levels="A")
ggsave("PM_blood_taxonomy_plots.png", width=7, height=10, unit="in", dpi=320)

LS0tCnRpdGxlOiAiRkFBIEdFTiBhbmFseXNpczogUG9zdG1vcnRlbSBQcm9qZWN0LCBUYXhvbm9teSBWaXN1YWxpemF0aW9uIgphdXRob3I6IENocmlzdG9waGVyIEouIFRyYWN5CmRhdGU6IDIwMjMuMDguMDQtMjAyMy4wOC4xOApvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKZWRpdG9yX29wdGlvbnM6CiAgbWFya2Rvd246CiAgICB3cmFwOiAxNDQKLS0tCgoqKkxpYnJhcmllcyoqCj09PQpMb2FkIHRoZSByZXF1aXJlZCBsaWJyYXJpZXMuCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShwYWxzKQpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkocGF0Y2h3b3JrKQoKY2l0YXRpb24oInRpZHl2ZXJzZSIpCmNpdGF0aW9uKCJnZ3Bsb3QyIikKY2l0YXRpb24oInNjYWxlcyIpCmNpdGF0aW9uKCJwYWxzIikKY2l0YXRpb24oImdncmVwZWwiKQpjaXRhdGlvbigicGF0Y2h3b3JrIikKCnNlc3Npb25JbmZvKCkKYGBgCgoqKkRhdGEgSW1wb3J0IGFuZCBTZXR1cCoqCj09PQpSZWFkcyB0aGUgR2VuY29kZSBzdW1tYXJpemVkIGRhdGEgZmlsZXMgZnJvbSBLcmFrZW4gT3V0cHV0IChodHRwczovL2dpdGh1Yi5jb20vbnBiaGF2eWEvS3Jha2VuMi1vdXRwdXQtbWFuaXB1bGF0aW9uKSBpbnRvIFIuCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmdlbmNvZGVfUEI9cmVhZC5jc3YoZmlsZT0iZ2VuY29kZV9QTV9QQl9zcGVjaWVzX2tyYWtlbl9zdW1tYXJ5IiwgaGVhZGVyPVRSVUUpCmdlbmNvZGVfUEw9cmVhZC5jc3YoZmlsZT0iZ2VuY29kZV9QTV9QTF9zcGVjaWVzX2tyYWtlbl9zdW1tYXJ5IiwgaGVhZGVyPVRSVUUpCmdlbmNvZGVfUE09cmVhZC5jc3YoZmlsZT0iZ2VuY29kZV9QTV9QTV9zcGVjaWVzX2tyYWtlbl9zdW1tYXJ5IiwgaGVhZGVyPVRSVUUpCmdlbmNvZGVfUFM9cmVhZC5jc3YoZmlsZT0iZ2VuY29kZV9QTV9QU19zcGVjaWVzX2tyYWtlbl9zdW1tYXJ5IiwgaGVhZGVyPVRSVUUpCmdlbmNvZGVfc3Rhcj1yZWFkLmRlbGltKGZpbGU9InN0YXJfYWxpZ25tZW50X3Bsb3QudHN2IiwgaGVhZGVyPVRSVUUsIHNlcD0iXHQiKQpnZW5jb2RlX1BCJFBNXzE0X1BCX1JOX0JBXzIyMDYwNj1hcy5pbnRlZ2VyKGdlbmNvZGVfUEIkUE1fMTRfUEJfUk5fQkFfMjIwNjA2KQpnZW5jb2RlX1BCJFBNXzU4X1BCX1JOX0JBXzIyMDkxNj1hcy5pbnRlZ2VyKGdlbmNvZGVfUEIkUE1fNThfUEJfUk5fQkFfMjIwOTE2KQpnZW5jb2RlX1BMJFBNXzE1X1BMX1JOX0JBXzIyMDYyMj1hcy5pbnRlZ2VyKGdlbmNvZGVfUEwkUE1fMTVfUExfUk5fQkFfMjIwNjIyKQpnZW5jb2RlX1BMJFBNXzU4X1BMX1JOX0JBXzIyMDkyMz1hcy5pbnRlZ2VyKGdlbmNvZGVfUEwkUE1fNThfUExfUk5fQkFfMjIwOTIzKQpnZW5jb2RlX1BNJFBNXzE1X1BNX1JOX0JBXzIyMDYxND1hcy5pbnRlZ2VyKGdlbmNvZGVfUE0kUE1fMTVfUE1fUk5fQkFfMjIwNjE0KQpnZW5jb2RlX1BNJFBNXzU4X1BNX1JOX0JBXzIyMDkyMD1hcy5pbnRlZ2VyKGdlbmNvZGVfUE0kUE1fNThfUE1fUk5fQkFfMjIwOTIwKQpnZW5jb2RlX1BTJFBNXzE3X1BTX1JOX0JBXzIyMDYyOD1hcy5pbnRlZ2VyKGdlbmNvZGVfUFMkUE1fMTdfUFNfUk5fQkFfMjIwNjI4KQpnZW5jb2RlX1BTJFBNXzU4X1BTX1JOX0JBXzIyMDkyMT1hcy5pbnRlZ2VyKGdlbmNvZGVfUFMkUE1fNThfUFNfUk5fQkFfMjIwOTIxKQpgYGAKClBpdm90cyB0aGUgZGF0YSBmcm9tIHdpZGUgdG8gbG9uZyBmb3JtYXQsIHJlbmFtZXMgdGhlIG5ldyBjb2x1bW5zLCBhcnJhbmdlcyB0aGUgY29sdW1ucyBpbiBhc2NlbmRpbmcgb3JkZXIgYnkgc2FtcGxlIG5hbWUgYW5kIGRlc2NlbmRpbmcgb3JkZXIgYnkgbnVtYmVyIG9mIGNvdW50cywgZ3JvdXBzIHRoZSByb3dzIGJ5IHNhbXBsZSwgcmVtb3ZlcyB0aGUgIkhvbW8iIHJvd3MsIHNsaWNlcyB0aGUgdG9wIDUgcm93cyBmb3IgZWFjaCBzYW1wbGUsIGFuZCByZW1vdmVzIGFsbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBzYW1wbGUgY29kZXMgYmVzaWRlcyB0aGUgcHJvamVjdCBpZGVudGlmaWVyLCB0aGUgc3ViamVjdCBudW1iZXIsIGFuZCB0aGUgY29sbGVjdGlvbi9leHRyYWN0aW9uIG1ldGhvZCBpZGVudGlmaWVyLgpgYGB7cn0KZ2VuY29kZV9QQl9sb25nX3RvcDU9Z2VuY29kZV9QQiAlPiUKICBwaXZvdF9sb25nZXIoY29scz1zdGFydHNfd2l0aCgiUE0iKSkgJT4lCiAgcmVuYW1lKFNhbXBsZT1uYW1lLCBDb3VudHM9dmFsdWUpICU+JQogIGFycmFuZ2UoU2FtcGxlLCBkZXNjKENvdW50cykpICU+JSAKICBncm91cF9ieShTYW1wbGUpICU+JQogIGZpbHRlcighc3RyX2RldGVjdChUYXhhLCAiSG9tbyBzYXBpZW5zIikpICU+JQogIHNsaWNlKDE6NSkKZ2VuY29kZV9QQl9sb25nX3RvcDUkU2FtcGxlPWdzdWIoIl9STi4qIiwgIiIsIGdlbmNvZGVfUEJfbG9uZ190b3A1JFNhbXBsZSkKc3VtKGdlbmNvZGVfUEJfbG9uZ190b3A1JENvdW50cykKCmdlbmNvZGVfUExfbG9uZ190b3A1PWdlbmNvZGVfUEwgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShTYW1wbGU9bmFtZSwgQ291bnRzPXZhbHVlKSAlPiUKICBhcnJhbmdlKFNhbXBsZSwgZGVzYyhDb3VudHMpKSAlPiUgCiAgZ3JvdXBfYnkoU2FtcGxlKSAlPiUKICBmaWx0ZXIoIXN0cl9kZXRlY3QoVGF4YSwgIkhvbW8gc2FwaWVucyIpKSAlPiUKICBzbGljZSgxOjUpCmdlbmNvZGVfUExfbG9uZ190b3A1JFNhbXBsZT1nc3ViKCJfUk4uKiIsICIiLCBnZW5jb2RlX1BMX2xvbmdfdG9wNSRTYW1wbGUpCnN1bShnZW5jb2RlX1BMX2xvbmdfdG9wNSRDb3VudHMpCgpnZW5jb2RlX1BNX2xvbmdfdG9wNT1nZW5jb2RlX1BNICU+JQogIHBpdm90X2xvbmdlcihjb2xzPXN0YXJ0c193aXRoKCJQTSIpKSAlPiUKICByZW5hbWUoU2FtcGxlPW5hbWUsIENvdW50cz12YWx1ZSkgJT4lCiAgYXJyYW5nZShTYW1wbGUsIGRlc2MoQ291bnRzKSkgJT4lIAogIGdyb3VwX2J5KFNhbXBsZSkgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc2xpY2UoMTo1KQpnZW5jb2RlX1BNX2xvbmdfdG9wNSRTYW1wbGU9Z3N1YigiX1JOLioiLCAiIiwgZ2VuY29kZV9QTV9sb25nX3RvcDUkU2FtcGxlKQpzdW0oZ2VuY29kZV9QTV9sb25nX3RvcDUkQ291bnRzKQoKZ2VuY29kZV9QU19sb25nX3RvcDU9Z2VuY29kZV9QUyAlPiUKICBwaXZvdF9sb25nZXIoY29scz1zdGFydHNfd2l0aCgiUE0iKSkgJT4lCiAgcmVuYW1lKFNhbXBsZT1uYW1lLCBDb3VudHM9dmFsdWUpICU+JQogIGFycmFuZ2UoU2FtcGxlLCBkZXNjKENvdW50cykpICU+JSAKICBncm91cF9ieShTYW1wbGUpICU+JQogIGZpbHRlcighc3RyX2RldGVjdChUYXhhLCAiSG9tbyBzYXBpZW5zIikpICU+JQogIHNsaWNlKDE6NSkKZ2VuY29kZV9QU19sb25nX3RvcDUkU2FtcGxlPWdzdWIoIl9STi4qIiwgIiIsIGdlbmNvZGVfUFNfbG9uZ190b3A1JFNhbXBsZSkKc3VtKGdlbmNvZGVfUFNfbG9uZ190b3A1JENvdW50cykKYGBgCgpFeGFtcGxlcyBvZiBiZWZvcmUgYW5kIGFmdGVyIGRhdGEgZm9ybWF0IG1hbmlwdWxhdGlvbi4KYGBge3J9CmhlYWQoZ2VuY29kZV9QQiwgbj0xMCkKaGVhZChnZW5jb2RlX1BCX2xvbmdfdG9wNSwgbj0xMCkKYGBgCgpgYGB7cn0KZ2VuY29kZV9TVEFSX1BCPWdlbmNvZGVfc3RhciAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdChDYXRlZ29yeSwgIlBCX1JOX0JBIikpCmdlbmNvZGVfU1RBUl9QTD1nZW5jb2RlX3N0YXIgJT4lCiAgZmlsdGVyKHN0cl9kZXRlY3QoQ2F0ZWdvcnksICJQTF9STl9CQSIpKQpnZW5jb2RlX1NUQVJfUE09Z2VuY29kZV9zdGFyICU+JQogIGZpbHRlcihzdHJfZGV0ZWN0KENhdGVnb3J5LCAiUE1fUk5fQkEiKSkKZ2VuY29kZV9TVEFSX1BTPWdlbmNvZGVfc3RhciAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdChDYXRlZ29yeSwgIlBTX1JOX0JBIikpCgpnZW5jb2RlX1NUQVJfUEJfY29tYmluZWQ9Z2VuY29kZV9QQiAlPiUKICBmaWx0ZXIoIXN0cl9kZXRlY3QoVGF4YSwgIkhvbW8gc2FwaWVucyIpKSAlPiUKICBzdW1tYXJpc2UoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHN1bSgueCwgbmEucm09VFJVRSkpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scz1zdGFydHNfd2l0aCgiUE0iKSkgJT4lCiAgcmVuYW1lKENhdGVnb3J5PW5hbWUsIENvbnRhbWluYXRpb249dmFsdWUpICU+JQogIGxlZnRfam9pbihnZW5jb2RlX1NUQVJfUEIsIGdlbmNvZGVfUEIsIGJ5PWpvaW5fYnkoQ2F0ZWdvcnk9PUNhdGVnb3J5KSkgJT4lCiAgcmVuYW1lKFNhbXBsZT1DYXRlZ29yeSkgJT4lCiAgYXJyYW5nZShTYW1wbGUpICU+JQogIHNlbGVjdChTYW1wbGUsIENvbnRhbWluYXRpb24sIFVuaXF1ZWx5X21hcHBlZCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCFTYW1wbGUsIG5hbWVzX3RvPSJDYXRlZ29yeSIsIHZhbHVlc190bz0iQ291bnRzIikKZ2VuY29kZV9TVEFSX1BCX2NvbWJpbmVkJFNhbXBsZT1nc3ViKCJfUk4uKiIsICIiLCBnZW5jb2RlX1NUQVJfUEJfY29tYmluZWQkU2FtcGxlKQoKZ2VuY29kZV9QQiAlPiUKICBmaWx0ZXIoIXN0cl9kZXRlY3QoVGF4YSwgIkhvbW8gc2FwaWVucyIpKSAlPiUKICBzdW1tYXJpc2UoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHN1bSgueCwgbmEucm09VFJVRSkpKSAlPiUKICBwaXZvdF9sb25nZXIoY29scz1zdGFydHNfd2l0aCgiUE0iKSkgJT4lCiAgcmVuYW1lKENhdGVnb3J5PW5hbWUsIENvbnRhbWluYXRpb249dmFsdWUpICU+JQogIGxlZnRfam9pbihnZW5jb2RlX1NUQVJfUEIsIGdlbmNvZGVfUEIsIGJ5PWpvaW5fYnkoQ2F0ZWdvcnk9PUNhdGVnb3J5KSkgJT4lCiAgcmVuYW1lKFNhbXBsZT1DYXRlZ29yeSkgJT4lCiAgYXJyYW5nZShTYW1wbGUpICU+JQogIHN1bW1hcmlzZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gc3VtKC54LCBuYS5ybT1UUlVFKSkpCig1ODMxODE5OC8oNTgzMTgxOTgrMjYyMDQzNTAyMSkpKjEwMAoKZ2VuY29kZV9TVEFSX1BMX2NvbWJpbmVkPWdlbmNvZGVfUEwgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBzdW0oLngsIG5hLnJtPVRSVUUpKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShDYXRlZ29yeT1uYW1lLCBDb250YW1pbmF0aW9uPXZhbHVlKSAlPiUKICBsZWZ0X2pvaW4oZ2VuY29kZV9TVEFSX1BMLCBnZW5jb2RlX1BMLCBieT1qb2luX2J5KENhdGVnb3J5PT1DYXRlZ29yeSkpICU+JQogIHJlbmFtZShTYW1wbGU9Q2F0ZWdvcnkpICU+JQogIGFycmFuZ2UoU2FtcGxlKSAlPiUKICBzZWxlY3QoU2FtcGxlLCBDb250YW1pbmF0aW9uLCBVbmlxdWVseV9tYXBwZWQpICU+JQogIHBpdm90X2xvbmdlcighU2FtcGxlLCBuYW1lc190bz0iQ2F0ZWdvcnkiLCB2YWx1ZXNfdG89IkNvdW50cyIpCmdlbmNvZGVfU1RBUl9QTF9jb21iaW5lZCRTYW1wbGU9Z3N1YigiX1JOLioiLCAiIiwgZ2VuY29kZV9TVEFSX1BMX2NvbWJpbmVkJFNhbXBsZSkKCmdlbmNvZGVfUEwgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBzdW0oLngsIG5hLnJtPVRSVUUpKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShDYXRlZ29yeT1uYW1lLCBDb250YW1pbmF0aW9uPXZhbHVlKSAlPiUKICBsZWZ0X2pvaW4oZ2VuY29kZV9TVEFSX1BMLCBnZW5jb2RlX1BMLCBieT1qb2luX2J5KENhdGVnb3J5PT1DYXRlZ29yeSkpICU+JQogIHJlbmFtZShTYW1wbGU9Q2F0ZWdvcnkpICU+JQogIGFycmFuZ2UoU2FtcGxlKSAlPiUKICBzdW1tYXJpc2UoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHN1bSgueCwgbmEucm09VFJVRSkpKQooMTk2OTk4NTY4LygxOTY5OTg1NjgrMTg2NDgxMjEyMCkpKjEwMAoKZ2VuY29kZV9TVEFSX1BNX2NvbWJpbmVkPWdlbmNvZGVfUE0gJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBzdW0oLngsIG5hLnJtPVRSVUUpKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShDYXRlZ29yeT1uYW1lLCBDb250YW1pbmF0aW9uPXZhbHVlKSAlPiUKICBsZWZ0X2pvaW4oZ2VuY29kZV9TVEFSX1BNLCBnZW5jb2RlX1BNLCBieT1qb2luX2J5KENhdGVnb3J5PT1DYXRlZ29yeSkpICU+JQogIHJlbmFtZShTYW1wbGU9Q2F0ZWdvcnkpICU+JQogIGFycmFuZ2UoU2FtcGxlKSAlPiUKICBzZWxlY3QoU2FtcGxlLCBDb250YW1pbmF0aW9uLCBVbmlxdWVseV9tYXBwZWQpICU+JQogIHBpdm90X2xvbmdlcighU2FtcGxlLCBuYW1lc190bz0iQ2F0ZWdvcnkiLCB2YWx1ZXNfdG89IkNvdW50cyIpCmdlbmNvZGVfU1RBUl9QTV9jb21iaW5lZCRTYW1wbGU9Z3N1YigiX1JOLioiLCAiIiwgZ2VuY29kZV9TVEFSX1BNX2NvbWJpbmVkJFNhbXBsZSkKCmdlbmNvZGVfUE0gJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBzdW0oLngsIG5hLnJtPVRSVUUpKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShDYXRlZ29yeT1uYW1lLCBDb250YW1pbmF0aW9uPXZhbHVlKSAlPiUKICBsZWZ0X2pvaW4oZ2VuY29kZV9TVEFSX1BNLCBnZW5jb2RlX1BNLCBieT1qb2luX2J5KENhdGVnb3J5PT1DYXRlZ29yeSkpICU+JQogIHJlbmFtZShTYW1wbGU9Q2F0ZWdvcnkpICU+JQogIGFycmFuZ2UoU2FtcGxlKSAlPiUKICBzdW1tYXJpc2UoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHN1bSgueCwgbmEucm09VFJVRSkpKQooMTUyOTk0ODQwLygxNTI5OTQ4NDArMjYxODg5NzgyNykpKjEwMAoKZ2VuY29kZV9TVEFSX1BTX2NvbWJpbmVkPWdlbmNvZGVfUFMgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBzdW0oLngsIG5hLnJtPVRSVUUpKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShDYXRlZ29yeT1uYW1lLCBDb250YW1pbmF0aW9uPXZhbHVlKSAlPiUKICBsZWZ0X2pvaW4oZ2VuY29kZV9TVEFSX1BTLCBnZW5jb2RlX1BTLCBieT1qb2luX2J5KENhdGVnb3J5PT1DYXRlZ29yeSkpICU+JQogIHJlbmFtZShTYW1wbGU9Q2F0ZWdvcnkpICU+JQogIGFycmFuZ2UoU2FtcGxlKSAlPiUKICBzZWxlY3QoU2FtcGxlLCBDb250YW1pbmF0aW9uLCBVbmlxdWVseV9tYXBwZWQpICU+JQogIHBpdm90X2xvbmdlcighU2FtcGxlLCBuYW1lc190bz0iQ2F0ZWdvcnkiLCB2YWx1ZXNfdG89IkNvdW50cyIpCmdlbmNvZGVfU1RBUl9QU19jb21iaW5lZCRTYW1wbGU9Z3N1YigiX1JOLioiLCAiIiwgZ2VuY29kZV9TVEFSX1BTX2NvbWJpbmVkJFNhbXBsZSkKCmdlbmNvZGVfUFMgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiBzdW0oLngsIG5hLnJtPVRSVUUpKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHM9c3RhcnRzX3dpdGgoIlBNIikpICU+JQogIHJlbmFtZShDYXRlZ29yeT1uYW1lLCBDb250YW1pbmF0aW9uPXZhbHVlKSAlPiUKICBsZWZ0X2pvaW4oZ2VuY29kZV9TVEFSX1BTLCBnZW5jb2RlX1BTLCBieT1qb2luX2J5KENhdGVnb3J5PT1DYXRlZ29yeSkpICU+JQogIHJlbmFtZShTYW1wbGU9Q2F0ZWdvcnkpICU+JQogIGFycmFuZ2UoU2FtcGxlKSAlPiUKICBzdW1tYXJpc2UoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHN1bSgueCwgbmEucm09VFJVRSkpKQooMjE3MzE0NTI0LygyMTczMTQ1MjQrMTQyNTMwMDIyMSkpKjEwMApgYGAKCkRlZmluZXMgdGhlIGZ1bmN0aW9uIGZvciB1c2UgaW4gY3JlYXRpbmcgdGhlIHktYXhpcyBsYWJlbHMgZm9yIHRoZSBwbG90cy4KYGBge3J9CmV2ZXJ5c2Vjb25kPWZ1bmN0aW9uKHgpewogIHg9c29ydCh1bmlxdWUoeCkpCiAgeFtzZXEoMiwgbGVuZ3RoKHgpLCAyKV09IiIKICB4Cn0KYGBgCgpTdW1tYXJpemF0aW9uIG9mIHRoZSBvY2N1cnJlbmNlIG9mIGEgdG9wIDUgU3BlY2llcyBhY3Jvc3MgYWxsIHRvcCA1IGZvciBlYWNoIGNvbGxlY3Rpb24gbWV0aG9kLgpgYGB7cn0KZ2VuY29kZV9QQl9sb25nX3RvcDVfc3VtbWFyeT1nZW5jb2RlX1BCICU+JQogIHBpdm90X2xvbmdlcihjb2xzPXN0YXJ0c193aXRoKCJQTSIpKSAlPiUKICByZW5hbWUoU2FtcGxlPW5hbWUsIENvdW50cz12YWx1ZSkgJT4lCiAgYXJyYW5nZShTYW1wbGUsIGRlc2MoQ291bnRzKSkgJT4lIAogIGdyb3VwX2J5KFNhbXBsZSkgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc2xpY2UoMTo1KSAlPiUKICB1bmdyb3VwKFNhbXBsZSkgJT4lCiAgZ3JvdXBfYnkoVGF4YSkgJT4lCiAgc3VtbWFyaXNlKG49bigpKQoKZ2VuY29kZV9QTF9sb25nX3RvcDVfc3VtbWFyeT1nZW5jb2RlX1BMICU+JQogIHBpdm90X2xvbmdlcihjb2xzPXN0YXJ0c193aXRoKCJQTSIpKSAlPiUKICByZW5hbWUoU2FtcGxlPW5hbWUsIENvdW50cz12YWx1ZSkgJT4lCiAgYXJyYW5nZShTYW1wbGUsIGRlc2MoQ291bnRzKSkgJT4lIAogIGdyb3VwX2J5KFNhbXBsZSkgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc2xpY2UoMTo1KSAlPiUKICB1bmdyb3VwKFNhbXBsZSkgJT4lCiAgZ3JvdXBfYnkoVGF4YSkgJT4lCiAgc3VtbWFyaXNlKG49bigpKQoKZ2VuY29kZV9QTV9sb25nX3RvcDVfc3VtbWFyeT1nZW5jb2RlX1BNICU+JQogIHBpdm90X2xvbmdlcihjb2xzPXN0YXJ0c193aXRoKCJQTSIpKSAlPiUKICByZW5hbWUoU2FtcGxlPW5hbWUsIENvdW50cz12YWx1ZSkgJT4lCiAgYXJyYW5nZShTYW1wbGUsIGRlc2MoQ291bnRzKSkgJT4lIAogIGdyb3VwX2J5KFNhbXBsZSkgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc2xpY2UoMTo1KSAlPiUKICB1bmdyb3VwKFNhbXBsZSkgJT4lCiAgZ3JvdXBfYnkoVGF4YSkgJT4lCiAgc3VtbWFyaXNlKG49bigpKQoKZ2VuY29kZV9QU19sb25nX3RvcDVfc3VtbWFyeT1nZW5jb2RlX1BTICU+JQogIHBpdm90X2xvbmdlcihjb2xzPXN0YXJ0c193aXRoKCJQTSIpKSAlPiUKICByZW5hbWUoU2FtcGxlPW5hbWUsIENvdW50cz12YWx1ZSkgJT4lCiAgYXJyYW5nZShTYW1wbGUsIGRlc2MoQ291bnRzKSkgJT4lIAogIGdyb3VwX2J5KFNhbXBsZSkgJT4lCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KFRheGEsICJIb21vIHNhcGllbnMiKSkgJT4lCiAgc2xpY2UoMTo1KSAlPiUKICB1bmdyb3VwKFNhbXBsZSkgJT4lCiAgZ3JvdXBfYnkoVGF4YSkgJT4lCiAgc3VtbWFyaXNlKG49bigpKQpgYGAKCkFuIGV4YW1wbGUgb2Ygc3VtbWFyaXplZCBkYXRhIGZvcm1hdCBtYW5pcHVsYXRpb24uCmBgYHtyfQpnZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5CmBgYAoKKipQbG90cyoqCj09PQojIyMgQnJhaW4gKFBCKQpgYGB7ciB3YXJuaW5nPUZBTFNFfQojIENvdW50cwojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNSwgYWVzKHg9Q291bnRzLCB5PVNhbXBsZSwgZmlsbD1pZl9lbHNlKENvdW50cz4xMDAwMDAwLCBUYXhhLCBOQSkpLCBjb2xvcj0iYmxhY2siKSsKIyAgIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWV2ZXJ5c2Vjb25kKGdlbmNvZGVfUEJfbG9uZ190b3A1JFNhbXBsZSksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiMgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMjYpKSkrCiMgICB0aGVtZV9taW5pbWFsKCkrCiMgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKIyAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAojICAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuNSksICJjbSIpLAojICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkKCiMgUHJvcG9ydGlvbgojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNSwgYWVzKHg9Q291bnRzLCB5PVNhbXBsZSwgZmlsbD1UYXhhKSwgY29sb3I9ImJsYWNrIiwgcG9zaXRpb249ImZpbGwiKSsKIyAgIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWV2ZXJ5c2Vjb25kKGdlbmNvZGVfUEJfbG9uZ190b3A1JFNhbXBsZSkpKwojICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDI2KSkpKwojICAgdGhlbWVfbWluaW1hbCgpKwojICAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjc1KSksCiMgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAojICAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAojICAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAojICAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKIyAgICAgeGxhYigiUHJvcG9ydGlvbiIpCgojIFRheGEgT2NjdXJyZW5jZQojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1uLCB5PVRheGEsIGZpbGw9VGF4YSksIGNvbG9yPSJibGFjayIpKwojICAgZ2VvbV90ZXh0KGRhdGE9Z2VuY29kZV9QQl9sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9biwgeT1UYXhhLCBsYWJlbD1uKSwgaGp1c3Q9LTAuMikrCiMgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMjYpKSkrCiMgICB0aGVtZV9taW5pbWFsKCkrCiMgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKIyAgICAgeGxhYigiT2NjdXJyZW5jZSIpCgojIFRheGEgT2NjdXJyZW5jZQojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1uLCB5PXJlb3JkZXIoVGF4YSwgbiksIGZpbGw9VGF4YSksIGNvbG9yPSJibGFjayIpKwojICAgZ2VvbV90ZXh0KGRhdGE9Z2VuY29kZV9QQl9sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9biwgeT1yZW9yZGVyKFRheGEsIG4pLCBsYWJlbD1uKSwgaGp1c3Q9LTAuMikrCiMgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMjYpKSkrCiMgICB0aGVtZV9taW5pbWFsKCkrCiMgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKIyAgIHhsYWIoIk9jY3VycmVuY2UiKSsgIAojICAgeWxhYigiVGF4YSIpCgojIFRheGEgT2NjdXJyZW5jZQojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1uLCB5PXJlb3JkZXIoVGF4YSwgbikpLCBmaWxsPSJibGFjayIsIGNvbG9yPSJibGFjayIsIGFscGhhPTAuNSkrCiMgICBnZW9tX3RleHQoZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1uLCB5PXJlb3JkZXIoVGF4YSwgbiksIGxhYmVsPW4pLCBoanVzdD0tMC4yKSsKIyAgIHRoZW1lX21pbmltYWwoKSsKIyAgIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKIyAgICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKIyAgICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiMgICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLAojICAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuNSksICJjbSIpLCAKIyAgICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpKwojICAgeGxhYigiT2NjdXJyZW5jZSIpKyAgCiMgICB5bGFiKCJUYXhhIikKCiMgVGF4YSBPY2N1cnJlbmNlCiMgZ2dwbG90KCkrCiMgICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUEJfbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PXJlb3JkZXIoVGF4YSwgbiksIHk9biwgZmlsbD1UYXhhKSwgY29sb3I9ImJsYWNrIikrCiMgICBnZW9tX3RleHQoZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1yZW9yZGVyKFRheGEsIG4pLCB5PW4sIGxhYmVsPW4pLCB2anVzdD0tMC4yKSsKIyAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1hcy52ZWN0b3IocG9seWNocm9tZSgyNikpKSsKIyAgIHRoZW1lX21pbmltYWwoKSsKIyAgIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSwgYW5nbGU9NjAsIGhqdXN0PTEpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKIyAgIHhsYWIoIlRheGEiKSsgIAojICAgeWxhYigiT2NjdXJyZW5jZSIpCgojIFRheGEgT2NjdXJyZW5jZQojIGdncGxvdCgpKwojICAgZ2VvbV9zZWdtZW50KGRhdGE9Z2VuY29kZV9QQl9sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHk9cmVvcmRlcihUYXhhLCBuKSwgeWVuZD1yZW9yZGVyKFRheGEsIG4pLCB4PTAsIHhlbmQ9biksCiMgICAgICAgICAgICAgICAgY29sb3I9ImJsYWNrIikrCiMgICBnZW9tX3BvaW50KGRhdGE9Z2VuY29kZV9QQl9sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9biwgeT1yZW9yZGVyKFRheGEsIG4pLCBjb2xvcj1UYXhhKSwgc2l6ZT0zKSArCiMgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDI2KSkpKwojICAgdGhlbWVfbWluaW1hbCgpKwojICAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAojICAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAojICAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAojICAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsCiMgICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC41KSwgImNtIiksIAojICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiMgICB4bGFiKCJPY2N1cnJlbmNlIikrICAKIyAgIHlsYWIoIlRheGEiKQoKIyBDb3VudHMKYnJhaW4xPWdncGxvdCgpKwogIGdlb21fY29sKGRhdGE9Z2VuY29kZV9QQl9sb25nX3RvcDUsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9aWZfZWxzZShDb3VudHM+MTAwMDAwMCwgVGF4YSwgTkEpKSwgY29sb3I9ImJsYWNrIikrCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHM9ZXZlcnlzZWNvbmQoZ2VuY29kZV9QQl9sb25nX3RvcDUkU2FtcGxlKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDEwKSksIG5hbWU9IlRheGEiLCAKICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygiQmFiZXNpYSBib3ZpcyIsICJDbG9zdHJpZGl1bSBiYXJhdGlpIiwgIkNsb3N0cmlkaXVtIHBlcmZyaW5nZW5zIiwgIk15cm9pZGVzIHBoYWV1cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlBhZW5pY2xvc3RyaWRpdW0gc29yZGVsbGlpIiwgIlBhcmFjbG9zdHJpZGl1bSBiaWZlcm1lbnRhbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQcm90ZXVzIG1pcmFiaWxpcyIsICJSb21ib3V0c2lhIGhvbWluaXMiLCAiUm9tYm91dHNpYSBpbGVhbGlzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlZpcmlkaWJhY2lsbHVzIHNwLiBKTlVDQy02IiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIkIuIGJvdmlzIiwgIkMuIGJhcmF0aWkiLCAiQy4gcGVyZnJpbmdlbnMiLCAiTS4gcGhhZXVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUC4gc29yZGVsbGlpIiwgIlAuIGJpZmVybWVudGFucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlAuIG1pcmFiaWxpcyIsICJSLiBob21pbmlzIiwgIlIuIGlsZWFsaXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVi4gc3AuIEpOVUNDLTYiKSkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC43NSkpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICAjIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAogICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsCiAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuMjUpLCAiY20iKSwKICAgICAgICAjIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJpdGFsaWMiLCBzaXplPXJlbCgwLjYpKSwKICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKG5yb3c9NSkpCgojIFRheGEgT2NjdXJyZW5jZQpicmFpbjI9Z2dwbG90KCkrCiAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BCX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1yZW9yZGVyKFRheGEsIG4pLCB5PW4pLCBmaWxsPSJibGFjayIsIGNvbG9yPSJibGFjayIsIGFscGhhPTAuNzUpKwogIGdlb21fdGV4dChkYXRhPWdlbmNvZGVfUEJfbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PXJlb3JkZXIoVGF4YSwgbiksIHk9biwgbGFiZWw9biksIHZqdXN0PS0wLjQsIHNpemU9MS4xKSsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAyKSkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJpdGFsaWMiLCBzaXplPXJlbCgwLjc1KSwgYW5nbGU9NjAsIGhqdXN0PTEsIHZqdXN0PTEpLAogICAgICAgICMgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueD1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAogICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLAogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiAgeGxhYigiVGF4YSIpKyAgCiAgeWxhYigiT2NjdXJyZW5jZSIpCgojIENvdW50cwpicmFpbjM9Z2dwbG90KCkrCiAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1NUQVJfUEJfY29tYmluZWQsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9Q2F0ZWdvcnkpLCBjb2xvcj0iYmxhY2siKSsKICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1ldmVyeXNlY29uZChnZW5jb2RlX1NUQVJfUEJfY29tYmluZWQkU2FtcGxlKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDIpKSwgbmFtZT0iQ2F0ZWdvcnkiLAogICAgICAgICAgICAgICAgICAgIGxpbWl0cz1jKCJDb250YW1pbmF0aW9uIiwgIlVuaXF1ZWx5X21hcHBlZCIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJDb250YW1pbmFudHMiLCAiVW5pcXVlbHkgTWFwcGVkIikpKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgIyBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjI1KSwgImNtIiksCiAgICAgICAgIyBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQobnJvdz0xKSkKYGBgCgpDb21iaW5lZCBUYXhhIEZpZ3VyZQpgYGB7cn0KYnJhaW5fcGF0Y2h3b3JrPShicmFpbjMgKyBicmFpbjEpIC8gYnJhaW4yICsgcGxvdF9sYXlvdXQobnJvdz0yKQpicmFpbl9wYXRjaHdvcmsgKyBwbG90X2Fubm90YXRpb24odGFnX2xldmVscz0iQSIpCmdnc2F2ZSgiUE1fYnJhaW5fdGF4b25vbXlfcGxvdHMucG5nIiwgd2lkdGg9NywgaGVpZ2h0PTEwLCB1bml0PSJpbiIsIGRwaT0zMjApCmBgYAoKIyMjIEx1bmcgKFBMKQpgYGB7ciB3YXJuaW5nPUZBTFNFfQojIENvdW50cwojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BMX2xvbmdfdG9wNSwgYWVzKHg9Q291bnRzLCB5PVNhbXBsZSwgZmlsbD1pZl9lbHNlKENvdW50cz4xMDAwMDAwLCBUYXhhLCBOQSkpLCBjb2xvcj0iYmxhY2siKSsKIyAgIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWV2ZXJ5c2Vjb25kKGdlbmNvZGVfUExfbG9uZ190b3A1JFNhbXBsZSksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiMgICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiMgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMjYpKSkrCiMgICB0aGVtZV9taW5pbWFsKCkrCiMgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKIyAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAojICAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuNSksICJjbSIpLAojICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkKCiMgUHJvcG9ydGlvbgojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BMX2xvbmdfdG9wNSwgYWVzKHg9Q291bnRzLCB5PVNhbXBsZSwgZmlsbD1UYXhhKSwgY29sb3I9ImJsYWNrIiwgcG9zaXRpb249ImZpbGwiKSsKIyAgIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWV2ZXJ5c2Vjb25kKGdlbmNvZGVfUExfbG9uZ190b3A1JFNhbXBsZSkpKwojICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDI2KSkpKwojICAgdGhlbWVfbWluaW1hbCgpKwojICAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjc1KSksCiMgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAojICAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAojICAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAojICAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKIyAgICAgeGxhYigiUHJvcG9ydGlvbiIpCgojIFRheGEgT2NjdXJyZW5jZQojIGdncGxvdCgpKwojICAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BMX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1uLCB5PVRheGEsIGZpbGw9VGF4YSksIGNvbG9yPSJibGFjayIpKwojICAgZ2VvbV90ZXh0KGRhdGE9Z2VuY29kZV9QTF9sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9biwgeT1UYXhhLCBsYWJlbD1uKSwgaGp1c3Q9LTAuMikrCiMgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMjYpKSkrCiMgICB0aGVtZV9taW5pbWFsKCkrCiMgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwgCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKIyAgICAgeGxhYigiT2NjdXJyZW5jZSIpCgojIENvdW50cwpsdW5nMT1nZ3Bsb3QoKSsKICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUExfbG9uZ190b3A1LCBhZXMoeD1Db3VudHMsIHk9U2FtcGxlLCBmaWxsPWlmX2Vsc2UoQ291bnRzPjEwMDAwMDAsIFRheGEsIE5BKSksIGNvbG9yPSJibGFjayIpKwogIHNjYWxlX3lfZGlzY3JldGUobGFiZWxzPWV2ZXJ5c2Vjb25kKGdlbmNvZGVfUExfbG9uZ190b3A1JFNhbXBsZSksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OmxhYmVsX251bWJlcl9zaSgpLCBleHBhbmQ9ZXhwYW5zaW9uKG11bHQ9MC4wMykpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1hcy52ZWN0b3IocG9seWNocm9tZSgxNSkpLCBuYW1lPSJUYXhhIiwgCiAgICAgICAgICAgICAgICAgICAgbGltaXRzPWMoIkFuYWVyb3N0aXBlcyBoYWRydXMiLCAiQ2xvc3RyaWRpdW0gYmFyYXRpaSIsICJDbG9zdHJpZGl1bSBib3JuaW1lbnNlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsb3N0cmlkaXVtIGJvdHVsaW51bSIsICJDbG9zdHJpZGl1bSBjZWxsdWxvdm9yYW5zIiwgIkNsb3N0cmlkaXVtIGRyYWtlaSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsb3N0cmlkaXVtIG5vdnlpIiwgIkNsb3N0cmlkaXVtIHNwLiBKTi05IiwgIkNsb3N0cmlkaXVtIHRoZXJtYXJ1bSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQYWVuaWNsb3N0cmlkaXVtIHNvcmRlbGxpaSIsICJQYXJhY2xvc3RyaWRpdW0gYmlmZXJtZW50YW5zIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGVwdGFjZXRvYmFjdGVyIGhpcmFub25pcyIsICJSb21ib3V0c2lhIGhvbWluaXMiLCAiUm9tYm91dHNpYSBpbGVhbGlzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJvbWJvdXRzaWEgc3AuIENFMTciKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQS4gaGFkcnVzIiwgIkMuIGJhcmF0aWkiLCAiQy4gYm9ybmltZW5zZSIsICJDLiBib3R1bGludW0iLCAiQy4gY2VsbHVsb3ZvcmFucyIsICJDLiBkcmFrZWkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDLiBub3Z5aSIsICJDLiBzcC4gSk4tOSIsICJDLiB0aGVybWFydW0iLCAiUC4gc29yZGVsbGlpIiwgIlAuIGJpZmVybWVudGFucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlAuIGhpcmFub25pcyIsICJSLiBob21pbmlzIiwgIlIuIGlsZWFsaXMiLCAiUi4gc3AuIENFMTciKSkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC43NSkpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICAjIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAogICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsCiAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuMjUpLCAiY20iKSwKICAgICAgICAjIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJpdGFsaWMiLCBzaXplPXJlbCgwLjYpKSwKICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKG5yb3c9OCkpCgojIFRheGEgT2NjdXJyZW5jZQpsdW5nMj1nZ3Bsb3QoKSsKICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUExfbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PXJlb3JkZXIoVGF4YSwgbiksIHk9biksIGZpbGw9ImJsYWNrIiwgY29sb3I9ImJsYWNrIiwgYWxwaGE9MC43NSkrCiAgZ2VvbV90ZXh0KGRhdGE9Z2VuY29kZV9QTF9sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9cmVvcmRlcihUYXhhLCBuKSwgeT1uLCBsYWJlbD1uKSwgdmp1c3Q9LTAuNCwgc2l6ZT0xLjEpKwogIHNjYWxlX3hfZGlzY3JldGUoZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDIpKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9Iml0YWxpYyIsIHNpemU9cmVsKDAuNSksIGFuZ2xlPTYwLCBoanVzdD0xLCB2anVzdD0xKSwKICAgICAgICAjIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwKICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC41KSwgImNtIiksIAogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpKwogIHhsYWIoIlRheGEiKSsgIAogIHlsYWIoIk9jY3VycmVuY2UiKQoKIyBDb3VudHMKbHVuZzM9Z2dwbG90KCkrCiAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1NUQVJfUExfY29tYmluZWQsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9Q2F0ZWdvcnkpLCBjb2xvcj0iYmxhY2siKSsKICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1ldmVyeXNlY29uZChnZW5jb2RlX1NUQVJfUExfY29tYmluZWQkU2FtcGxlKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDIpKSwgbmFtZT0iQ2F0ZWdvcnkiLAogICAgICAgICAgICAgICAgICAgIGxpbWl0cz1jKCJDb250YW1pbmF0aW9uIiwgIlVuaXF1ZWx5X21hcHBlZCIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJDb250YW1pbmFudHMiLCAiVW5pcXVlbHkgTWFwcGVkIikpKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgIyBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjI1KSwgImNtIiksCiAgICAgICAgIyBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQobnJvdz0xKSkKYGBgCgpDb21iaW5lZCBUYXhhIEZpZ3VyZQpgYGB7cn0KbHVuZ19wYXRjaHdvcms9KGx1bmczICsgbHVuZzEpIC8gbHVuZzIgKyBwbG90X2xheW91dChucm93PTIpCmx1bmdfcGF0Y2h3b3JrICsgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHM9IkEiKQpnZ3NhdmUoIlBNX2x1bmdfdGF4b25vbXlfcGxvdHMucG5nIiwgd2lkdGg9NywgaGVpZ2h0PTEwLCB1bml0PSJpbiIsIGRwaT0zMjApCmBgYAoKIyMjIE11c2NsZSAoUE0pCmBgYHtyIHdhcm5pbmc9RkFMU0V9CiMgQ291bnRzCiMgZ2dwbG90KCkrCiMgICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUE1fbG9uZ190b3A1LCBhZXMoeD1Db3VudHMsIHk9U2FtcGxlLCBmaWxsPWlmX2Vsc2UoQ291bnRzPjEwMDAwMDAsIFRheGEsIE5BKSksIGNvbG9yPSJibGFjayIpKwojICAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHM9ZXZlcnlzZWNvbmQoZ2VuY29kZV9QTV9sb25nX3RvcDUkU2FtcGxlKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKIyAgIHNjYWxlX3hfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpsYWJlbF9udW1iZXJfc2koKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKIyAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1hcy52ZWN0b3IocG9seWNocm9tZSgyNikpKSsKIyAgIHRoZW1lX21pbmltYWwoKSsKIyAgIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC43NSkpLAojICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKIyAgICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKIyAgICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiMgICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsCiMgICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC41KSwgImNtIiksCiMgICAgICAgICAjIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKQoKIyBQcm9wb3J0aW9uCiMgZ2dwbG90KCkrCiMgICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUE1fbG9uZ190b3A1LCBhZXMoeD1Db3VudHMsIHk9U2FtcGxlLCBmaWxsPVRheGEpLCBjb2xvcj0iYmxhY2siLCBwb3NpdGlvbj0iZmlsbCIpKwojICAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHM9ZXZlcnlzZWNvbmQoZ2VuY29kZV9QTV9sb25nX3RvcDUkU2FtcGxlKSkrCiMgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMjYpKSkrCiMgICB0aGVtZV9taW5pbWFsKCkrCiMgICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKIyAgICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiMgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiMgICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiMgICAgICAgICBheGlzLmxpbmU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAojICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAojICAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuNSksICJjbSIpLCAKIyAgICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpKwojICAgICB4bGFiKCJQcm9wb3J0aW9uIikKCiMgVGF4YSBPY2N1cnJlbmNlCiMgZ2dwbG90KCkrCiMgICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUE1fbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PW4sIHk9VGF4YSwgZmlsbD1UYXhhKSwgY29sb3I9ImJsYWNrIikrCiMgICBnZW9tX3RleHQoZGF0YT1nZW5jb2RlX1BNX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1uLCB5PVRheGEsIGxhYmVsPW4pLCBoanVzdD0tMC4yKSsKIyAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1hcy52ZWN0b3IocG9seWNocm9tZSgyNikpKSsKIyAgIHRoZW1lX21pbmltYWwoKSsKIyAgIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAojICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKIyAgICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKIyAgICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiMgICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLAojICAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuNSksICJjbSIpLCAKIyAgICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpKwojICAgICB4bGFiKCJPY2N1cnJlbmNlIikKCiMgQ291bnRzCm11c2NsZTE9Z2dwbG90KCkrCiAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BNX2xvbmdfdG9wNSwgYWVzKHg9Q291bnRzLCB5PVNhbXBsZSwgZmlsbD1pZl9lbHNlKENvdW50cz4xMDAwMDAwLCBUYXhhLCBOQSkpLCBjb2xvcj0iYmxhY2siKSsKICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1ldmVyeXNlY29uZChnZW5jb2RlX1BNX2xvbmdfdG9wNSRTYW1wbGUpLCBleHBhbmQ9ZXhwYW5zaW9uKG11bHQ9MC4wMykpKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpsYWJlbF9udW1iZXJfc2koKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9YXMudmVjdG9yKHBvbHljaHJvbWUoMTQpKSwgbmFtZT0iVGF4YSIsIAogICAgICAgICAgICAgICAgICAgIGxpbWl0cz1jKCJDbG9zdHJpZGl1bSBiYXJhdGlpIiwgIkNsb3N0cmlkaXVtIGNoYXV2b2VpIiwgIkNsb3N0cmlkaXVtIGlzYXRpZGlzIiwgIkNsb3N0cmlkaXVtIG5vdnlpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2xvc3RyaWRpdW0gc2VwdGljdW0iLCAiSGFlbW9waGlsdXMgcGFyYWluZmx1ZW56YWUiLCAiSWduYXR6c2NoaW5lcmlhIHNwLiBIUjVTMzIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTXlyb2lkZXMgcGhhZXVzIiwgIlBhZW5pY2xvc3RyaWRpdW0gc29yZGVsbGlpIiwgIlBob3RvYmFjdGVyaXVtIGRhbXNlbGFlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGhvdG9iYWN0ZXJpdW0gdG9ydW5pIiwgIlZhZ29jb2NjdXMgdGV1YmVyaSIsICJWZWlsbG9uZWxsYSBhdHlwaWNhIiwgIlZlaWxsb25lbGxhIHBhcnZ1bGEiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQy4gYmFyYXRpaSIsICJDLiBjaGF1dm9laSIsICJDLiBpc2F0aWRpcyIsICJDLiBub3Z5aSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkMuIHNlcHRpY3VtIiwgIkguIHBhcmFpbmZsdWVuemFlIiwgIkkuIHNwLiBIUjVTMzIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTS4gcGhhZXVzIiwgIlAuIHNvcmRlbGxpaSIsICJQLiBkYW1zZWxhZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlAuIHRvcnVuaSIsICJWLiB0ZXViZXJpIiwgIlYuIGF0eXBpY2EiLCAiVi4gcGFydnVsYSIpKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjc1KSksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgICMgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAogICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC4yNSksICJjbSIpLAogICAgICAgICMgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9Iml0YWxpYyIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQobnJvdz03KSkKCiMgVGF4YSBPY2N1cnJlbmNlCm11c2NsZTI9Z2dwbG90KCkrCiAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1BNX2xvbmdfdG9wNV9zdW1tYXJ5LCBhZXMoeD1yZW9yZGVyKFRheGEsIG4pLCB5PW4pLCBmaWxsPSJibGFjayIsIGNvbG9yPSJibGFjayIsIGFscGhhPTAuNzUpKwogIGdlb21fdGV4dChkYXRhPWdlbmNvZGVfUE1fbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PXJlb3JkZXIoVGF4YSwgbiksIHk9biwgbGFiZWw9biksIHZqdXN0PS0wLjQsIHNpemU9MS4xKSsKICBzY2FsZV94X2Rpc2NyZXRlKGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAyKSkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJpdGFsaWMiLCBzaXplPXJlbCgwLjUpLCBhbmdsZT02MCwgaGp1c3Q9MSwgdmp1c3Q9MSksCiAgICAgICAgIyBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAogICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsCiAgICAgICAgbGVnZW5kLmtleS5zaXplPXVuaXQocmVsKDAuNSksICJjbSIpLCAKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKICB4bGFiKCJUYXhhIikrICAKICB5bGFiKCJPY2N1cnJlbmNlIikKCiMgQ291bnRzCm11c2NsZTM9Z2dwbG90KCkrCiAgZ2VvbV9jb2woZGF0YT1nZW5jb2RlX1NUQVJfUE1fY29tYmluZWQsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9Q2F0ZWdvcnkpLCBjb2xvcj0iYmxhY2siKSsKICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1ldmVyeXNlY29uZChnZW5jb2RlX1NUQVJfUE1fY29tYmluZWQkU2FtcGxlKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDIpKSwgbmFtZT0iQ2F0ZWdvcnkiLAogICAgICAgICAgICAgICAgICAgIGxpbWl0cz1jKCJDb250YW1pbmF0aW9uIiwgIlVuaXF1ZWx5X21hcHBlZCIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJDb250YW1pbmFudHMiLCAiVW5pcXVlbHkgTWFwcGVkIikpKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgIyBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjI1KSwgImNtIiksCiAgICAgICAgIyBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgcGxvdC5tYXJnaW49dW5pdChjKDAuMSwgMC4zLCAwLjEsIDAuMSksICJjbSIpKSsKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQobnJvdz0xKSkKYGBgCgpDb21iaW5lZCBUYXhhIEZpZ3VyZQpgYGB7cn0KbXVzY2xlX3BhdGNod29yaz0obXVzY2xlMyArIG11c2NsZTEpIC8gbXVzY2xlMiArIHBsb3RfbGF5b3V0KG5yb3c9MikKbXVzY2xlX3BhdGNod29yayArIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzPSJBIikKZ2dzYXZlKCJQTV9tdXNjbGVfdGF4b25vbXlfcGxvdHMucG5nIiwgd2lkdGg9NywgaGVpZ2h0PTEwLCB1bml0PSJpbiIsIGRwaT0zMjApCmBgYAoKIyMjIEJsb29kIChQUykKYGBge3Igd2FybmluZz1GQUxTRX0KIyBDb3VudHMKIyBnZ3Bsb3QoKSsKIyAgIGdlb21fY29sKGRhdGE9Z2VuY29kZV9QU19sb25nX3RvcDUsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9aWZfZWxzZShDb3VudHM+MTAwMDAwMCwgVGF4YSwgTkEpKSwgY29sb3I9ImJsYWNrIikrCiMgICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1ldmVyeXNlY29uZChnZW5jb2RlX1BTX2xvbmdfdG9wNSRTYW1wbGUpLCBleHBhbmQ9ZXhwYW5zaW9uKG11bHQ9MC4wMykpKwojICAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OmxhYmVsX251bWJlcl9zaSgpLCBleHBhbmQ9ZXhwYW5zaW9uKG11bHQ9MC4wMykpKwojICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDI2KSkpKwojICAgdGhlbWVfbWluaW1hbCgpKwojICAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjc1KSksCiMgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAojICAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAojICAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAojICAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKIyAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjUpLCAiY20iKSwKIyAgICAgICAgICMgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKIyAgICAgICAgIHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpCgojIFByb3BvcnRpb24KIyBnZ3Bsb3QoKSsKIyAgIGdlb21fY29sKGRhdGE9Z2VuY29kZV9QU19sb25nX3RvcDUsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9VGF4YSksIGNvbG9yPSJibGFjayIsIHBvc2l0aW9uPSJmaWxsIikrCiMgICBzY2FsZV95X2Rpc2NyZXRlKGxhYmVscz1ldmVyeXNlY29uZChnZW5jb2RlX1BTX2xvbmdfdG9wNSRTYW1wbGUpKSsKIyAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1hcy52ZWN0b3IocG9seWNocm9tZSgyNikpKSsKIyAgIHRoZW1lX21pbmltYWwoKSsKIyAgIHRoZW1lKGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC43NSkpLAojICAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKIyAgICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIHN0cmlwLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjgpKSwKIyAgICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiMgICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsCiMgICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC41KSwgImNtIiksIAojICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiMgICAgIHhsYWIoIlByb3BvcnRpb24iKQoKIyBUYXhhIE9jY3VycmVuY2UKIyBnZ3Bsb3QoKSsKIyAgIGdlb21fY29sKGRhdGE9Z2VuY29kZV9QU19sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9biwgeT1UYXhhLCBmaWxsPVRheGEpLCBjb2xvcj0iYmxhY2siKSsKIyAgIGdlb21fdGV4dChkYXRhPWdlbmNvZGVfUFNfbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PW4sIHk9VGF4YSwgbGFiZWw9biksIGhqdXN0PS0wLjIpKwojICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDI2KSkpKwojICAgdGhlbWVfbWluaW1hbCgpKwojICAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiMgICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEsIGZpbGw9TkEpLAojICAgICAgICAgc3RyaXAuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgbGluZXdpZHRoPTEpLAojICAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAojICAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGlja3M9ZWxlbWVudF9saW5lKGxpbmV3aWR0aD0xKSwKIyAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsCiMgICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC41KSwgImNtIiksIAojICAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiMgICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAojICAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKIyAgICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiMgICAgIHhsYWIoIk9jY3VycmVuY2UiKQoKIyBDb3VudHMKYmxvb2QxPWdncGxvdCgpKwogIGdlb21fY29sKGRhdGE9Z2VuY29kZV9QU19sb25nX3RvcDUsIGFlcyh4PUNvdW50cywgeT1TYW1wbGUsIGZpbGw9aWZfZWxzZShDb3VudHM+MTAwMDAwMCwgVGF4YSwgTkEpKSwgY29sb3I9ImJsYWNrIikrCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHM9ZXZlcnlzZWNvbmQoZ2VuY29kZV9QU19sb25nX3RvcDUkU2FtcGxlKSwgZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDMpKSsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bGFiZWxfbnVtYmVyX3NpKCksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWFzLnZlY3Rvcihwb2x5Y2hyb21lKDIxKSksIG5hbWU9IlRheGEiLCAKICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygiQW5hZXJvc3RpcGVzIGhhZHJ1cyIsICJCYWN0ZXJvaWRlcyBzYWx5ZXJzaWFlIiwgIkJsYXV0aWEgb2JldW0iLCAiQmxhdXRpYSB3ZXhsZXJhZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNhcm5vYmFjdGVyaXVtIGRpdmVyZ2VucyIsICJDbG9zdHJpZGl1bSBiYXJhdGlpIiwgIkNsb3N0cmlkaXVtIGdhc2lnZW5lcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDbG9zdHJpZGl1bSBtYW5paG90aXZvcnVtIiwgIkNsb3N0cmlkaXVtIG5vdnlpIiwgIkNsb3N0cmlkaXVtIHBlcmZyaW5nZW5zIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsb3N0cmlkaXVtIHNlcHRpY3VtIiwgIkVudGVyb2JhY3RlciBob3JtYWVjaGVpIiwgIkV3aW5nZWxsYSBhbWVyaWNhbmEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGltbm9iYWN1bHVtIHBhcnZ1bSIsICJQYWVuaWNsb3N0cmlkaXVtIHNvcmRlbGxpaSIsICJQaG9jYWVpY29sYSBkb3JlaSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQc2V1ZG9tb25hcyBsdW5kZW5zaXMiLCAiUm9tYm91dHNpYSBob21pbmlzIiwgIlJvbWJvdXRzaWEgaWxlYWxpcyIsICJSb3V4aWVsbGEgYmFkZW5zaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJWYWdvY29jY3VzIHRldWJlcmkiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQS4gaGFkcnVzIiwgIkIuIHNhbHllcnNpYWUiLCAiQi4gb2JldW0iLCAiQi4gd2V4bGVyYWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDLiBkaXZlcmdlbnMiLCAiQy4gYmFyYXRpaSIsICJDLiBnYXNpZ2VuZXMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQy4gbWFuaWhvdGl2b3J1bSIsICJDLiBub3Z5aSIsICJDLiBwZXJmcmluZ2VucyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDLiBzcGV0aWN1bSIsICJFLiBob3JtYWVjaGVpIiwgIkUuIGFtZXJpY2FuYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMLiBwYXJ2dW0iLCAiUC4gc29yZGVsbGlpIiwgIlAuIGRvcmVpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlAuIGx1bmRlbnNpcyIsICJSLiBob21pbmlzIiwgIlIuIGlsZWFsaXMiLCAiUi4gYmFkZW5zaXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJWLiB0ZXViZXJpIikpKwogIHRoZW1lX21pbmltYWwoKSsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNzUpKSwKICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgIyBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAogICAgICAgIGxlZ2VuZC5rZXkuc2l6ZT11bml0KHJlbCgwLjI1KSwgImNtIiksCiAgICAgICAgIyBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iaXRhbGljIiwgc2l6ZT1yZWwoMC42KSksCiAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpKwogIGd1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZChucm93PTExKSkKCiMgVGF4YSBPY2N1cnJlbmNlCmJsb29kMj1nZ3Bsb3QoKSsKICBnZW9tX2NvbChkYXRhPWdlbmNvZGVfUFNfbG9uZ190b3A1X3N1bW1hcnksIGFlcyh4PXJlb3JkZXIoVGF4YSwgbiksIHk9biksIGZpbGw9ImJsYWNrIiwgY29sb3I9ImJsYWNrIiwgYWxwaGE9MC43NSkrCiAgZ2VvbV90ZXh0KGRhdGE9Z2VuY29kZV9QU19sb25nX3RvcDVfc3VtbWFyeSwgYWVzKHg9cmVvcmRlcihUYXhhLCBuKSwgeT1uLCBsYWJlbD1uKSwgdmp1c3Q9LTAuNCwgc2l6ZT0xLjEpKwogIHNjYWxlX3hfZGlzY3JldGUoZXhwYW5kPWV4cGFuc2lvbihtdWx0PTAuMDIpKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9Iml0YWxpYyIsIHNpemU9cmVsKDAuNSksIGFuZ2xlPTYwLCBoanVzdD0xLCB2anVzdD0xKSwKICAgICAgICAjIGF4aXMudGl0bGUueD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBwYW5lbC5ib3JkZXI9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xLCBmaWxsPU5BKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQ9ZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIGxpbmV3aWR0aD0xKSwKICAgICAgICBzdHJpcC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC44KSksCiAgICAgICAgYXhpcy5saW5lPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfbGluZShsaW5ld2lkdGg9MSksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwKICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC41KSwgImNtIiksIAogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuNikpLAogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMC42KSksCiAgICAgICAgcGxvdC50aXRsZT1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDEpKSwKICAgICAgICBwbG90Lm1hcmdpbj11bml0KGMoMC4xLCAwLjMsIDAuMSwgMC4xKSwgImNtIikpKwogIHhsYWIoIlRheGEiKSsgIAogIHlsYWIoIk9jY3VycmVuY2UiKQoKIyBDb3VudHMKYmxvb2QzPWdncGxvdCgpKwogIGdlb21fY29sKGRhdGE9Z2VuY29kZV9TVEFSX1BTX2NvbWJpbmVkLCBhZXMoeD1Db3VudHMsIHk9U2FtcGxlLCBmaWxsPUNhdGVnb3J5KSwgY29sb3I9ImJsYWNrIikrCiAgc2NhbGVfeV9kaXNjcmV0ZShsYWJlbHM9ZXZlcnlzZWNvbmQoZ2VuY29kZV9TVEFSX1BTX2NvbWJpbmVkJFNhbXBsZSksIGV4cGFuZD1leHBhbnNpb24obXVsdD0wLjAzKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OmxhYmVsX251bWJlcl9zaSgpLCBleHBhbmQ9ZXhwYW5zaW9uKG11bHQ9MC4wMykpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1hcy52ZWN0b3IocG9seWNocm9tZSgyKSksIG5hbWU9IkNhdGVnb3J5IiwKICAgICAgICAgICAgICAgICAgICBsaW1pdHM9YygiQ29udGFtaW5hdGlvbiIsICJVbmlxdWVseV9tYXBwZWQiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiQ29udGFtaW5hbnRzIiwgIlVuaXF1ZWx5IE1hcHBlZCIpKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgdGhlbWUoYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjc1KSksCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgxKSksCiAgICAgICAgYXhpcy50aXRsZS54PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgICMgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuYm9yZGVyPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSwgZmlsbD1OQSksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iYmxhY2siLCBsaW5ld2lkdGg9MSksCiAgICAgICAgc3RyaXAudGV4dD1lbGVtZW50X3RleHQoY29sb3I9ImJsYWNrIiwgZmFjZT0iYm9sZCIsIHNpemU9cmVsKDAuOCkpLAogICAgICAgIGF4aXMubGluZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcz1lbGVtZW50X2xpbmUobGluZXdpZHRoPTEpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKICAgICAgICBsZWdlbmQua2V5LnNpemU9dW5pdChyZWwoMC4yNSksICJjbSIpLAogICAgICAgICMgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCksCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KGNvbG9yPSJibGFjayIsIGZhY2U9ImJvbGQiLCBzaXplPXJlbCgwLjYpKSwKICAgICAgICBwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChjb2xvcj0iYmxhY2siLCBmYWNlPSJib2xkIiwgc2l6ZT1yZWwoMSkpLAogICAgICAgIHBsb3QubWFyZ2luPXVuaXQoYygwLjEsIDAuMywgMC4xLCAwLjEpLCAiY20iKSkrCiAgZ3VpZGVzKGZpbGw9Z3VpZGVfbGVnZW5kKG5yb3c9MSkpCmBgYAoKQ29tYmluZWQgVGF4YSBGaWd1cmUKYGBge3J9CmJsb29kX3BhdGNod29yaz0oYmxvb2QzICsgYmxvb2QxKSAvIGJsb29kMiArIHBsb3RfbGF5b3V0KG5yb3c9MikKYmxvb2RfcGF0Y2h3b3JrICsgcGxvdF9hbm5vdGF0aW9uKHRhZ19sZXZlbHM9IkEiKQpnZ3NhdmUoIlBNX2Jsb29kX3RheG9ub215X3Bsb3RzLnBuZyIsIHdpZHRoPTcsIGhlaWdodD0xMCwgdW5pdD0iaW4iLCBkcGk9MzIwKQpgYGA=