Libraries

Load the required libraries.

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.2     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.2     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.1     ── Conflicts ────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(ggplot2)
library(scales)

Attaching package: ‘scales’

The following object is masked from ‘package:purrr’:

    discard

The following object is masked from ‘package:readr’:

    col_factor
library(pals)
library(ggrepel)
library(patchwork)

citation("tidyverse")
To cite package ‘tidyverse’ in publications use:

  Wickham H, Averick M, Bryan J, Chang W, McGowan LD, François R, Grolemund G, Hayes A, Henry L, Hester
  J, Kuhn M, Pedersen TL, Miller E, Bache SM, Müller K, Ooms J, Robinson D, Seidel DP, Spinu V,
  Takahashi K, Vaughan D, Wilke C, Woo K, Yutani H (2019). “Welcome to the tidyverse.” _Journal of Open
  Source Software_, *4*(43), 1686. doi:10.21105/joss.01686 <https://doi.org/10.21105/joss.01686>.

A BibTeX entry for LaTeX users is

  @Article{,
    title = {Welcome to the {tidyverse}},
    author = {Hadley Wickham and Mara Averick and Jennifer Bryan and Winston Chang and Lucy D'Agostino McGowan and Romain François and Garrett Grolemund and Alex Hayes and Lionel Henry and Jim Hester and Max Kuhn and Thomas Lin Pedersen and Evan Miller and Stephan Milton Bache and Kirill Müller and Jeroen Ooms and David Robinson and Dana Paige Seidel and Vitalie Spinu and Kohske Takahashi and Davis Vaughan and Claus Wilke and Kara Woo and Hiroaki Yutani},
    year = {2019},
    journal = {Journal of Open Source Software},
    volume = {4},
    number = {43},
    pages = {1686},
    doi = {10.21105/joss.01686},
  }
citation("ggplot2")
To cite ggplot2 in publications, please use

  H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2016.

A BibTeX entry for LaTeX users is

  @Book{,
    author = {Hadley Wickham},
    title = {ggplot2: Elegant Graphics for Data Analysis},
    publisher = {Springer-Verlag New York},
    year = {2016},
    isbn = {978-3-319-24277-4},
    url = {https://ggplot2.tidyverse.org},
  }
citation("scales")
To cite package ‘scales’ in publications use:

  Wickham H, Seidel D (2022). _scales: Scale Functions for Visualization_. R package version 1.2.1,
  <https://CRAN.R-project.org/package=scales>.

A BibTeX entry for LaTeX users is

  @Manual{,
    title = {scales: Scale Functions for Visualization},
    author = {Hadley Wickham and Dana Seidel},
    year = {2022},
    note = {R package version 1.2.1},
    url = {https://CRAN.R-project.org/package=scales},
  }
citation("pals")
To cite package ‘pals’ in publications use:

  Wright K (2021). _pals: Color Palettes, Colormaps, and Tools to Evaluate Them_. R package version
  1.7, <https://CRAN.R-project.org/package=pals>.

A BibTeX entry for LaTeX users is

  @Manual{,
    title = {pals: Color Palettes, Colormaps, and Tools to Evaluate Them},
    author = {Kevin Wright},
    year = {2021},
    note = {R package version 1.7},
    url = {https://CRAN.R-project.org/package=pals},
  }
citation("ggrepel")
To cite package ‘ggrepel’ in publications use:

  Slowikowski K (2023). _ggrepel: Automatically Position Non-Overlapping Text Labels with 'ggplot2'_. R
  package version 0.9.3, <https://CRAN.R-project.org/package=ggrepel>.

A BibTeX entry for LaTeX users is

  @Manual{,
    title = {ggrepel: Automatically Position Non-Overlapping Text Labels with
'ggplot2'},
    author = {Kamil Slowikowski},
    year = {2023},
    note = {R package version 0.9.3},
    url = {https://CRAN.R-project.org/package=ggrepel},
  }
citation("patchwork")
To cite package ‘patchwork’ in publications use:

  Pedersen T (2022). _patchwork: The Composer of Plots_. R package version 1.1.2,
  <https://CRAN.R-project.org/package=patchwork>.

A BibTeX entry for LaTeX users is

  @Manual{,
    title = {patchwork: The Composer of Plots},
    author = {Thomas Lin Pedersen},
    year = {2022},
    note = {R package version 1.1.2},
    url = {https://CRAN.R-project.org/package=patchwork},
  }
sessionInfo()
R version 4.3.0 (2023-04-21)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux 8.8 (Ootpa)

Matrix products: default
BLAS/LAPACK: /usr/lib64/libopenblasp-r0.3.15.so;  LAPACK version 3.9.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8    LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

time zone: America/Chicago
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] patchwork_1.1.2 ggrepel_0.9.3   pals_1.7        scales_1.2.1    lubridate_1.9.2 forcats_1.0.0   stringr_1.5.0  
 [8] dplyr_1.1.2     purrr_1.0.1     readr_2.1.4     tidyr_1.3.0     tibble_3.2.1    ggplot2_3.4.2   tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] gtable_0.3.3      compiler_4.3.0    maps_3.4.1        Rcpp_1.0.10       tidyselect_1.2.0  dichromat_2.0-0.1
 [7] R6_2.5.1          generics_0.1.3    mapproj_1.2.11    knitr_1.43        munsell_0.5.0     pillar_1.9.0     
[13] tzdb_0.4.0        rlang_1.1.1       utf8_1.2.3        stringi_1.7.12    xfun_0.39         timechange_0.2.0 
[19] cli_3.6.1         withr_2.5.0       magrittr_2.0.3    grid_4.3.0        rstudioapi_0.14   hms_1.1.3        
[25] lifecycle_1.0.3   vctrs_0.6.3       glue_1.6.2        fansi_1.0.4       colorspace_2.1-0  tools_4.3.0      
[31] pkgconfig_2.0.3  

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=