Overview
Out of a total of 132,846 EEBO records, 60,227 (45.34%) are in
EEBO-TCP (but 66 EEBO records have multiple TCP ids).
The 60,327 EEBO-TCP records are divided into phase 1 and phase 2. In
detail, phase 1 contains 25,368 of these records (42.05%) while phase 2
contains 34,959 of these records (57.95%). In terms of EEBO, 25,304
records (19.05%) are in EEBO-TCP phase 1, while 34,931 records (26.29%)
are in EEBO-TCP phase 2.
In terms of the ESTC, out of the 132,846 EEBO records, 6,802 (5.12%)
could not be matched to an ESTC record and will be left out of the
analysis. On the other hand, 7,373 EEBO records (5.55%) were matched to
more than one ESTC record, possibly causing bias.
Out of the 60,327 EEBO-TCP records, 1,143 (1.89%) could not be
matched to an ESTC record and will be left out of the analysis. On the
other hand, 3,269 EEBO-TCP records (5.42%) were matched to more than one
ESTC record, possibly causing bias.
In the analysis, only ESTC records with publication years in the
range [1474,1700) have been included. This results in the exclusion of
4,862 (4.17%) ESTC records that have representation in EEBO, possibly
causing bias. 2,119 (3.41%) of the ESTC records with representation in
EEBO-TCP are removed due to this filtering condition.
In the end, our working dataset:
- From the viewpoint of EEBO, contains 121,328 (91.33%) out of the
original 132,846 EEBO ids.
- From the viewpoint of EEBO-TCP, contains 57,461 (95.25%) out of the
original 60,327 EEBO ids.
- Consists of 132,412 ESTC records, of which 111,816 (84.45%) we
estimate to have representation in EEBO, and 60,095 (45.38%) to have
representation in EEBO-TCP.
Publication type analysis
Coverage of different publication types in EEBO
library(ggbeeswarm)
bind_rows(
df %>% mutate(group = "Editions"),
df %>% filter(edition_type!="Singular") %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),.groups="drop") %>%
mutate(group = "Works",edition_type=if_else(publication_year==first_publication_year,"First year work","Later work"))
) %>%
mutate(edition_type=fct_relevel(edition_type,"Singular","First year work","Later work","First year edition","Later edition")) %>%
filter(type %in% c("Book","Pamphlet")) %>%
group_by(publication_year, edition_type, group, type, in_eebo) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo) %>%
ggplot(aes(x = type, y = prop, group = edition_type, color = edition_type)) +
geom_quasirandom(aes(size = tn), dodge = 1.0) +
stat_summary(aes(group = edition_type), position = position_dodge(width = 1.0), fun = median, fun.min = median, fun.max = median, geom = "crossbar", width = 0.5, color = "red") +
theme_hsci_discrete() +
xlab(NULL) +
ylab("EEBO coverage") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.05)) +
scale_size(breaks = c(250, 500, 1500), range = c(0.1, 8.0)) +
theme(legend.justification = c(0, 0), legend.position = c(0.02, 0.02), legend.background = element_blank(), legend.box.just = "bottom", legend.key = element_blank(), legend.box = "horizontal") +
labs(color = "Representation type", size = "Count") +
guides(shape = "none")

In terms of coverage of ESTC’s pre-18th-century material, EEBO is
quite good, with a median coverage of about 95% of books both at the
edition as well as the work-level, with only a slight drop in coverage
for later year editions (meaning that even for later editions, EEBO
often contains at least one edition from each year, but may not contain
all distinct printings from that year).
For pamphlets, coverage is about 85% across the board, with an
interesting increase for later year editions (this may be caused either
by reprinted pamphlets having been though of as important to capture, or
due to e.g. temporal artifacts, even though it does not appear that
overall coverage improves with time, as seen later).
Coverage of different publication types in EEBO-TCP
library(ggbeeswarm)
bind_rows(
df %>% mutate(group = "Editions"),
df %>% filter(edition_type!="Singular") %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),.groups="drop") %>%
mutate(group = "Works",edition_type=if_else(publication_year==first_publication_year,"First year work","Later work"))
) %>%
mutate(edition_type=fct_relevel(edition_type,"Singular","First year work","Later work","First year edition","Later edition")) %>%
filter(type %in% c("Book","Pamphlet")) %>%
group_by(publication_year, edition_type, group, type, in_eebo_tcp) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp) %>%
ggplot(aes(x = type, y = prop, group = edition_type, color = edition_type)) +
geom_quasirandom(aes(size = tn), dodge = 1.0) +
stat_summary(aes(group = edition_type), position = position_dodge(width = 1.0), fun = median, fun.min = median, fun.max = median, geom = "crossbar", width = 0.5, color = "red") +
theme_hsci_discrete() +
xlab(NULL) +
ylab("EEBO-TCP coverage") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.05)) +
scale_size(breaks = c(250, 500, 1500), range = c(0.1, 8.0)) +
theme(legend.justification = c(0, 1), legend.position = c(0.02, 0.98), legend.background = element_blank(), legend.box.just = "bottom", legend.key = element_blank(), legend.box = "horizontal") +
labs(color = "Representation type", size = "Count") +
guides(shape = "none")

Coverage of different publication types in EEBO-TCP phase 1
library(ggbeeswarm)
bind_rows(
df %>% mutate(group = "Editions"),
df %>% filter(edition_type!="Singular") %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),.groups="drop") %>%
mutate(group = "Works",edition_type=if_else(publication_year==first_publication_year,"First year work","Later work"))
) %>%
mutate(edition_type=fct_relevel(edition_type,"Singular","First year work","Later work","First year edition","Later edition")) %>%
filter(type %in% c("Book","Pamphlet")) %>%
group_by(publication_year, edition_type, group, type, in_eebo_tcp_phase_1) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp_phase_1) %>%
ggplot(aes(x = type, y = prop, group = edition_type, color = edition_type)) +
geom_quasirandom(aes(size = tn), dodge = 1.0) +
stat_summary(aes(group = edition_type), position = position_dodge(width = 1.0), fun = median, fun.min = median, fun.max = median, geom = "crossbar", width = 0.5, color = "red") +
theme_hsci_discrete() +
xlab(NULL) +
ylab("EEBO-TCP phase 1 coverage") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.05)) +
scale_size(breaks = c(250, 500, 1500), range = c(0.1, 8.0)) +
theme(legend.justification = c(0, 1), legend.position = c(0.02, 0.98), legend.background = element_blank(), legend.box.just = "bottom", legend.key = element_blank(), legend.box = "horizontal") +
labs(color = "Representation type", size = "Count") +
guides(shape = "none")

Coverage of different publication types in EEBO-TCP phase 2
library(ggbeeswarm)
bind_rows(
df %>% mutate(group = "Editions"),
df %>% filter(edition_type!="Singular") %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),.groups="drop") %>%
mutate(group = "Works",edition_type=if_else(publication_year==first_publication_year,"First year work","Later work"))
) %>%
mutate(edition_type=fct_relevel(edition_type,"Singular","First year work","Later work","First year edition","Later edition")) %>%
filter(type %in% c("Book","Pamphlet")) %>%
group_by(publication_year, edition_type, group, type, in_eebo_tcp_phase_2) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp_phase_2) %>%
ggplot(aes(x = type, y = prop, group = edition_type, color = edition_type)) +
geom_quasirandom(aes(size = tn), dodge = 1.0) +
stat_summary(aes(group = edition_type), position = position_dodge(width = 1.0), fun = median, fun.min = median, fun.max = median, geom = "crossbar", width = 0.5, color = "red") +
theme_hsci_discrete() +
xlab(NULL) +
ylab("EEBO-TCP phase 2 coverage") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.05)) +
scale_size(breaks = c(250, 500, 1500), range = c(0.1, 8.0)) +
theme(legend.justification = c(0, 1), legend.position = c(0.02, 0.98), legend.background = element_blank(), legend.box.just = "bottom", legend.key = element_blank(), legend.box = "horizontal") +
labs(color = "Representation type", size = "Count") +
guides(shape = "none")

For coverage in EEBO-TCP, a clear pattern emerges where coverage of
singular and first editions is much better than coverage of later
editions. There are also no clear differences between EEBO-TCP phase 1
and phase 2 in behavior with regard to this. This has an important
bearing for all following analyses, which in the case of EEBO-TCP,
should mostly evaluate coverage on this work-level. As a separate
observation, interestingly, coverage of books and pamphlets also seems
quite even even. Another observation is that EEBO-TCP phase 2 contains
more singular works than phase 1. This may indicate a broader collection
of “non-core” works, instead of focusing on first editions of popular
(and thus later reprinted) works.
Edition-level temporal overview
df %>% mutate(g = case_when(
!certain ~ "Uncertain dating",
in_eebo_tcp_phase_1 ~ "In EEBO-TCP phase 1",
in_eebo_tcp_phase_2 ~ "In EEBO-TCP phase 2",
in_eebo ~ "In EEBO",
T ~ "ESTC total",
)) %>%
ggplot(aes(x = publication_year, fill = fct_relevel(g, "Uncertain dating", "ESTC total", "In EEBO","In EEBO-TCP phase 1","In EEBO-TCP phase 2"))) +
geom_bar(width = 1) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(breaks = seq(0, 10000, by = 500)) +
xlab("Year") +
ylab("ESTC entries") +
theme(legend.justification = c(0, 1), legend.position = c(0.05, 0.95), legend.background = element_blank(), legend.key = element_blank()) +
labs(fill = NULL) +
guides(fill = guide_legend(reverse = TRUE))

In terms of a temporal overview, it is important to note how here in
an absolute graph, the amount of entries grows significantly overall
through time, as well as has large variations and spikes multiple times
between 1640 and 1700 (with the larger bump between 1640 and 1660 most
likely consisting mainly of the Thomason Tracts).
df %>% filter(certain) %>% mutate(g = case_when(
in_eebo_tcp_phase_1 ~ "In EEBO-TCP phase 1",
in_eebo_tcp_phase_2 ~ "In EEBO-TCP phase 2",
in_eebo ~ "In EEBO",
T ~ "Not in EEBO",
)) %>%
ggplot(aes(x = publication_year, fill = fct_relevel(g, "Not in EEBO", "In EEBO","In EEBO-TCP phase 2","In EEBO-TCP phase 1"))) +
geom_bar(width = 1,position='fill') +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(breaks = seq(0, 1, by = 0.1),labels=scales::percent_format(accuracy=1)) +
xlab("Year") +
ylab("Proportion of ESTC entries") +
theme(legend.position="bottom") +
labs(fill = NULL) +
guides(fill = guide_legend(reverse = TRUE))

In terms of edition-level proportional coverage, EEBO coverage is
quite balanced throughout the period, with just a slight drop at the end
of the 17th century. For EEBO-TCP, edition-level coverage is much more
varied, but as noted, it actually does not make that much sense to look
at edition-level coverage with respect to it.
Work-level temporal overview
df %>%
filter(first_publication_year>1474) %>%
group_by(work_id,first_publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),certain=any(first_year_publication & certain),.groups="drop") %>%
mutate(g = case_when(
!certain ~ "Uncertain dating",
in_eebo_tcp_phase_1 ~ "In EEBO-TCP phase 1",
in_eebo_tcp_phase_2 ~ "In EEBO-TCP phase 2",
in_eebo ~ "In EEBO",
T ~ "ESTC total",
)) %>%
ggplot(aes(x = first_publication_year, fill = fct_relevel(g, "Uncertain dating", "ESTC total", "In EEBO","In EEBO-TCP phase 2","In EEBO-TCP phase 1"))) +
geom_bar(width = 1) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(breaks = seq(0, 10000, by = 500)) +
xlab("Year") +
ylab("ESTC entries") +
theme(legend.justification = c(0, 1), legend.position = c(0.05, 0.95), legend.background = element_blank(), legend.key = element_blank()) +
labs(fill = NULL) +
guides(fill = guide_legend(reverse = TRUE))

df %>%
filter(first_publication_year>1474) %>%
group_by(work_id,first_publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),certain=any(first_year_publication & certain),.groups="drop") %>% mutate(g = case_when(
in_eebo_tcp_phase_1 ~ "In EEBO-TCP phase 1",
in_eebo_tcp_phase_2 ~ "In EEBO-TCP phase 2",
in_eebo ~ "In EEBO",
T ~ "Not in EEBO",
)) %>%
filter(certain) %>%
ggplot(aes(x = first_publication_year, fill = fct_relevel(g, "Not in EEBO", "In EEBO","In EEBO-TCP phase 2","In EEBO-TCP phase 1"))) +
geom_bar(width = 1,position='fill') +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(breaks = seq(0, 1, by = 0.1),labels=scales::percent_format(accuracy=1)) +
xlab("Year of first publication") +
ylab("Proportion of ESTC works") +
theme(legend.position="bottom") +
labs(fill = NULL) +
guides(fill = guide_legend(reverse = TRUE))

In terms of work-level coverage, also EEBO-TCP appears quite nicely
balanced temporally, apart from dips between 1500 and 1530. However, it
must be noted how the total amount of content is also very low for those
early years, so larger variation can also be expected. The addition of
phase 2 improves the evenness of EEBO-TCP coverage a bit with regard to
phase 1, where coverage diminishes toward the end of the century.
Document type coverage through time
bind_rows(
df %>% mutate(group = "Editions",type=recode(type,"Book"="Book (edition-level)","Pamphlet"="Pamphlet (edition-level)")),
df %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),certain=any(first_year_publication & certain),.groups="drop") %>%
mutate(group = "Works")
) %>%
mutate(type=fct_relevel(type,"Pamphlet (edition-level)","Book (edition-level)","Pamphlet","Book")) %>%
filter(certain) %>%
filter(!is.na(type),type!="In-between") %>%
group_by(publication_year, type, in_eebo) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo) %>%
ggplot(aes(x = publication_year, y = prop, color = type)) +
geom_smooth(aes(weight = n, fill = type), span = 0.3, method='loess',formula=y~x) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
scale_size(breaks = c(500, 2000, 3500), range = c(0.1, 8.0))

Drilling in and separating books and pamphlets from each other, we
can see that EEBO coverage of both is very good, apart from a noticeable
drop in pamphlet coverage in the late 17th century.
bind_rows(
df %>% mutate(group = "Editions",type=recode(type,"Book"="Book (edition-level)","Pamphlet"="Pamphlet (edition-level)")),
df %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),certain=any(first_year_publication & certain),.groups="drop") %>%
mutate(group = "Works")
) %>%
mutate(type=fct_relevel(type,"Pamphlet (edition-level)","Book (edition-level)","Pamphlet","Book")) %>%
filter(certain) %>%
filter(!is.na(type),type!="In-between") %>%
group_by(publication_year, type, in_eebo_tcp) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp) %>%
ggplot(aes(x = publication_year, y = prop, color = type)) +
geom_smooth(aes(weight = n, fill = type), span = 0.3, method='loess',formula=y~x) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO-TCP coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
scale_size(breaks = c(500, 2000, 3500), range = c(0.1, 8.0))

For EEBO-TCP, on the work level, the same drop in coverage for
pamphlets at the end of the 17th century can be seen, but otherwise
coverage is relatively stable through time for both books as well as
pamphlets, except for a marked uptick between 1640 and 1660 (caused most
likely by more judicious inclusion of the Thomason Tracts). On the work
level, pamphlets are just slightly better covered than books, but on the
on the edition level, coverage of books is much lower. This can be seen
as only the natural consequence of EEBO-TCP favouring including only
first editions. Books typically have more editions than pamphlets, so
excluding later editions affects edition-level coverage for books much
more than it does for pamphlets.
bind_rows(
df %>% mutate(group = "Editions",type=recode(type,"Book"="Book (edition-level)","Pamphlet"="Pamphlet (edition-level)")),
df %>% group_by(work_id,type,first_publication_year,publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),certain=any(first_year_publication & certain),.groups="drop") %>%
mutate(group = "Works")
) %>%
mutate(type=fct_relevel(type,"Pamphlet (edition-level)","Book (edition-level)","Pamphlet","Book")) %>%
filter(certain) %>%
filter(!is.na(type),type!="In-between") %>%
group_by(publication_year, type, in_eebo_tcp_phase_1) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp_phase_1) %>%
ggplot(aes(x = publication_year, y = prop, color = type)) +
geom_smooth(aes(weight = n, fill = type), span = 0.3, method='loess',formula=y~x) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO-TCP phase 1 coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
scale_size(breaks = c(500, 2000, 3500), range = c(0.1, 8.0))

Looking only at phase 1, there is a clear bump in the representation
of pamphlets in the 1560s, which interestingly is corrected for when
taking in also phase 2. In terms of book coverage, there is also a
linear decline in coverage between about 1560 and 1650 (before 1540 the
data is so sparse that reliable conclusions cannot be drawn from
it).
Topical coverage EEBO-TCP vs EEBO
EEBO work-level genre use frequencies
(subset that is in ESTC to get the work information)
eebo_ustc_genres %>%
inner_join(eebo_core,by=c("eebo_id")) %>%
inner_join(estc_core,by=c("estc_id")) %>%
mutate(ustc_genre=str_trunc(ustc_genre,65),status=case_when(
in_eebo_tcp_phase_1 ~ "EEBO-TCP phase 1",
in_eebo_tcp_phase_2 ~ "EEBO-TCP phase 2",
T ~ "Not in EEBO-TCP")) %>%
group_by(ustc_genre,status) %>%
summarize(n=n_distinct(work_id),.groups="drop") %>%
group_by(ustc_genre) %>%
mutate(tn=sum(n)) %>%
ungroup() %>%
mutate(ustc_genre=fct_reorder(ustc_genre,tn)) %>%
ggplot(aes(x=ustc_genre,y=n,fill=status)) +
geom_col() +
theme_hsci_discrete() +
theme(legend.justification = c(1, 0), legend.box.just = "bottom", legend.position = c(0.98, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(fill=NULL) +
xlab("USTC genre") +
ylab("Number of works") +
scale_y_continuous(labels=scales::number) +
coord_flip()

Open question: are the USTC categories usable? Is this a believable
genre distribution? If it is, the below graphs show interesting
difference and temporal shifts in the coverage of the various
categories, the interpretation of which I leave up to you.
EEBO-TCP work-level genre coverage
eebo_ustc_genres %>%
inner_join(eebo_core,by=c("eebo_id")) %>%
inner_join(estc_core,by=c("estc_id")) %>%
mutate(ustc_genre=str_trunc(ustc_genre,65)) %>%
group_by(work_id,ustc_genre) %>%
summarize(in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),.groups="drop") %>%
group_by(ustc_genre) %>%
summarize(n=n(),`EEBO-TCP`=sum(in_eebo_tcp)/n(),`EEBO-TCP phase 1`=sum(in_eebo_tcp_phase_1)/n(),`EEBO-TCP phase 2`=sum(in_eebo_tcp_phase_2)/n(),.groups="drop") %>%
mutate(ustc_genre=fct_reorder(str_c(ustc_genre,' (',n,')'),n)) %>%
pivot_longer(`EEBO-TCP phase 1`:`EEBO-TCP phase 2`,names_to="part", values_to = "prop") %>%
ggplot(aes(x=ustc_genre,y=prop,fill=fct_relevel(part,'EEBO-TCP phase 2'))) +
geom_col(position='stack') +
theme_hsci_discrete() +
scale_y_continuous(labels=scales::percent_format(accuracy=1)) +
xlab("USTC genre") +
ylab("Coverage by work") +
theme(legend.position = "bottom") +
# theme(legend.justification = c(1, 0), legend.box.just = "bottom", legend.position = c(0.98, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(fill=NULL) +
coord_flip()

Here, we can first see which categories have been excluded from
EEBO-TCP: almanacs,academic dissertations, astrology and cosmography, as
well as dictionaries. Apart from this, we also see how poetry and drama
are heavily overemphasized in EEBO-TCP phase 1, whereas phase 2 corrects
nicely for these as well as other imbalances. What remains interesting
is a low coverage of dialectics and rhetoric, linguistics and philology
and classical authors.
EEBO-TCP phase genre composition comparison
EEBO work-level language frequencies
eebo_core %>%
inner_join(estc_core,by=c("estc_id")) %>%
mutate(status=case_when(
in_eebo_tcp_phase_1 ~ "EEBO-TCP phase 1",
in_eebo_tcp_phase_2 ~ "EEBO-TCP phase 2",
T ~ "Not in EEBO-TCP")) %>%
group_by(eebo_tls_language,status) %>%
summarize(n=n_distinct(work_id),.groups="drop") %>%
group_by(eebo_tls_language) %>%
mutate(tn=sum(n)) %>%
ungroup() %>%
mutate(eebo_tls_language=fct_reorder(eebo_tls_language,tn)) %>%
ggplot(aes(x=eebo_tls_language,y=n,fill=status)) +
geom_col() +
theme_hsci_discrete() +
theme(legend.justification = c(1, 0), legend.box.just = "bottom", legend.position = c(0.98, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(fill=NULL) +
xlab("Language") +
ylab("Number of works (log10)") +
scale_y_continuous(labels=scales::number,trans="log10") +
coord_flip()

EEBO-TCP work-level language coverage vs EEBO
eebo_core %>%
filter(!is.na(eebo_tls_language)) %>%
inner_join(estc_core,by=c("estc_id")) %>%
group_by(work_id,eebo_tls_language) %>%
summarize(in_eebo_tcp=any(in_eebo_tcp),in_eebo_tcp_phase_1=any(in_eebo_tcp_phase_1),in_eebo_tcp_phase_2=any(in_eebo_tcp_phase_2),.groups="drop") %>%
group_by(eebo_tls_language) %>%
summarize(n=n(),`EEBO-TCP`=sum(in_eebo_tcp)/n(),`EEBO-TCP phase 1`=sum(in_eebo_tcp_phase_1)/n(),`EEBO-TCP phase 2`=sum(in_eebo_tcp_phase_2)/n(),.groups="drop") %>%
mutate(eebo_tls_language=fct_reorder(str_c(eebo_tls_language,' (',n,')'),n)) %>%
pivot_longer(`EEBO-TCP phase 1`:`EEBO-TCP phase 2`,names_to="part", values_to = "prop") %>%
ggplot(aes(x=eebo_tls_language,y=prop,fill=part)) +
geom_col(position='stack') +
theme_hsci_discrete() +
scale_y_continuous(labels=scales::percent_format(accuracy=1)) +
xlab("Language") +
ylab("Coverage by work as compared to EEBO") +
theme(legend.justification = c(1, 0), legend.box.just = "bottom", legend.position = c(0.98, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(fill=NULL) +
coord_flip()

Welsh and Scottish are very well covered. Of the major languages,
Latin in particular is very poorly covered overall, and particularly in
phase 2 (which we already knew from the background info at https://textcreationpartnership.org/tcp-texts/eebo-tcp-early-english-books-online/).
French fares a bit better, but not too great.
EEBO-TCP phase language composition comparison (against EEBO,
English excluded)
EEBO-TCP phase edition type composition comparison
Genre coverage through time (EEBO-TCP against EEBO)

In many major genre categories such as religious, literature and
history and chronicles, phase 1 of EEBO-TCP shows a clearly diminishing
coverage toward the end of the century. However, when phase 2 is added
to the data, in addition to significantly improving coverage overall,
this bias disappears.
Topical coverage of EEBO vs ESTC through time
Here, we are projecting subject category information from EEBO/ECCO
throughout the whole of the ESTC in order to compare their coverage. For
the 18th century and ECCO, this seemed to work relatively well for all
the 8 categories. For USTC/EEBO, I was comfortable including only the
religious/history and chronicles and economics -categories.
Using projected ECCO modules
df %>%
filter(first_publication_year>1474) %>%
group_by(work_id,first_publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),certain=any(first_year_publication & certain),.groups="drop") %>%
filter(certain) %>%
left_join(combined_projected_ecco_modules,by=c("work_id")) %>%
replace_na(list(projected_ecco_module="Other/Unknown")) %>%
mutate(projected_ecco_module=fct_relevel(projected_ecco_module,"Other/Unknown")) %>%
group_by(first_publication_year, projected_ecco_module, in_eebo) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo) %>%
ggplot(aes(x = first_publication_year, y = prop, color = projected_ecco_module)) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
geom_smooth(aes(weight = n, fill = projected_ecco_module), span = 0.3, method='loess',formula=y~x) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 40)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
coord_cartesian(ylim=c(0.5,1)) +
scale_size(breaks = c(100, 500, 1000), range = c(0.1, 8.0)) +
guides(color="none",fill="none") +
facet_wrap(~projected_ecco_module,ncol=3)

Using projected USTC Religious/History and chronicles/Economics
df %>%
filter(first_publication_year>1474) %>%
group_by(work_id,first_publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),certain=any(first_year_publication & certain),.groups="drop") %>%
filter(certain) %>%
left_join(estc_projected_ustc_genres %>%
filter(max_prop>=0.7,projected_ustc_genre %in% c("Religious","History and chronicles","Economics")),by=c("work_id")) %>%
replace_na(list(projected_ustc_genre="Other/Unknown")) %>%
mutate(projected_ustc_genre=fct_relevel(projected_ustc_genre,"Other/Unknown")) %>%
group_by(first_publication_year, projected_ustc_genre, in_eebo) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo) %>%
ggplot(aes(x = first_publication_year, y = prop, color = projected_ustc_genre)) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
geom_smooth(aes(weight = n, fill = projected_ustc_genre), span = 0.3, method='loess',formula=y~x) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
coord_cartesian(ylim=c(0,1)) +
scale_size(breaks = c(100, 500, 1000), range = c(0.1, 8.0))

Topical coverage of EEBO-TCP vs ESTC through time
Using projected ECCO modules
df %>%
filter(first_publication_year>1474) %>%
group_by(work_id,first_publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),certain=any(first_year_publication & certain),.groups="drop") %>%
filter(certain) %>%
left_join(combined_projected_ecco_modules,by=c("work_id")) %>%
replace_na(list(projected_ecco_module="Other/Unknown")) %>%
mutate(projected_ecco_module=fct_relevel(projected_ecco_module,"Other/Unknown")) %>%
group_by(first_publication_year, projected_ecco_module, in_eebo_tcp) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp) %>%
ggplot(aes(x = first_publication_year, y = prop, color = projected_ecco_module)) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
geom_smooth(aes(weight = n, fill = projected_ecco_module), span = 0.3, method='loess',formula=y~x) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 40)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO-TCP coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
coord_cartesian(ylim=c(0,1)) +
scale_size(breaks = c(100, 500, 1000), range = c(0.1, 8.0)) +
guides(color="none",fill="none") +
facet_wrap(~projected_ecco_module,ncol=3)

Using projected USTC Religious/History and chronicles/Economics
df %>%
filter(first_publication_year>1474) %>%
group_by(work_id,first_publication_year) %>%
summarize(in_eebo=any(in_eebo),in_eebo_tcp=any(in_eebo_tcp),certain=any(first_year_publication & certain),.groups="drop") %>%
filter(certain) %>%
left_join(combined_projected_ustc_genres %>%
filter(projected_ustc_genre %in% c("Religious","History and chronicles","Economics")),by=c("work_id")) %>%
replace_na(list(projected_ustc_genre="Other/Unknown")) %>%
mutate(projected_ustc_genre=fct_relevel(projected_ustc_genre,"Other/Unknown")) %>%
group_by(first_publication_year, projected_ustc_genre, in_eebo_tcp) %>%
tally() %>%
mutate(prop = n / sum(n), tn = sum(n)) %>%
filter(in_eebo_tcp) %>%
ggplot(aes(x = first_publication_year, y = prop, color = projected_ustc_genre)) +
geom_point(color = "gray", shape = 21, aes(size = tn)) +
geom_point(aes(size = n)) +
geom_smooth(aes(weight = n, fill = projected_ustc_genre), span = 0.3, method='loess',formula=y~x) +
theme_hsci_discrete() +
scale_x_continuous(breaks = seq(1000, 2000, by = 20)) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1), breaks = seq(0, 1, by = 0.10)) +
xlab("Year") +
ylab("EEBO-TCP coverage") +
theme(legend.justification = c(0, 0), legend.box.just = "bottom", legend.position = c(0.05, 0.02), legend.background = element_blank(), legend.key = element_blank(), legend.box = "horizontal") +
labs(color = NULL, size = NULL, shape = NULL, fill = NULL) +
coord_cartesian(ylim=c(0,1)) +
scale_size(breaks = c(100, 500, 1000), range = c(0.1, 8.0))

(compare this with the raw EEBO-TCP vs EEBO coverage as well as the
ECCO module coverage graphs)
LS0tCnRpdGxlOiAiRUVCTy9FU1RDIGFuYWx5c2lzIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICB0b2M6IHllcwotLS0KCmBgYHtyIHNldHVwLGVjaG89Rn0Ka25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBoZXJlOjpoZXJlKCkpCmBgYAoKYGBge3IsaW5jbHVkZT1GfQpzb3VyY2UoaGVyZTo6aGVyZSgiY29kZS9sb2FkX2FuZF9wcmVwYXJlX2RhdGEuUiIpLCBsb2NhbCA9IGtuaXRyOjprbml0X2dsb2JhbCgpKQpgYGAKCmBgYHtyLGluY2x1ZGU9Rn0KbGlicmFyeSh0aWR5dmVyc2UpCnBhazo6cGtnX2luc3RhbGwoImhzY2ktci9nZ2hzY2kiKQpsaWJyYXJ5KGdnaHNjaSkKYGBgCgpgYGB7cixpbmNsdWRlPUZ9CnAgPC0gZnVuY3Rpb24obnVtYmVyKSB7CiAgcmV0dXJuKGZvcm1hdChudW1iZXIsIHNjaWVudGlmaWMgPSBGQUxTRSwgYmlnLm1hcmsgPSAiLCIpKQp9CnBwIDwtIGZ1bmN0aW9uKHBlcmNlbnRhZ2UsYWNjdXJhY3k9MC4wMSkgewogIHJldHVybihzY2FsZXM6OnBlcmNlbnQocGVyY2VudGFnZSwgYWNjdXJhY3kgPSBhY2N1cmFjeSkpCn0KYGBgCgpgYGB7cixpbmNsdWRlPUZ9CmxpYnJhcnkoYXNzZXJ0dGhhdCkKCm5fZWVib19pZHMgPC0gZWVib19jb3JlICU+JQogIGRpc3RpbmN0KGVlYm9faWQpICU+JQogIG5yb3coKQpuX2VlYm9fdGNwX2lkcyA8LSBlZWJvX3RjcF9jb3JlICU+JQogIGRpc3RpbmN0KGVlYm9fdGNwX2lkKSAlPiUKICBucm93KCkKbl9lZWJvX3RjcF9pZHNfcGhhc2VfMSA8LSBlZWJvX3RjcF9jb3JlICU+JQogIGZpbHRlcihlZWJvX3RjcF9waGFzZT09IkVFQk8tVENQIHBoYXNlIDEiKSAlPiUKICBkaXN0aW5jdChlZWJvX3RjcF9pZCkgJT4lCiAgbnJvdygpCm5fZWVib190Y3BfaWRzX3BoYXNlXzIgPC0gZWVib190Y3BfY29yZSAlPiUKICBmaWx0ZXIoZWVib190Y3BfcGhhc2U9PSJFRUJPLVRDUCBwaGFzZSAyIikgJT4lCiAgZGlzdGluY3QoZWVib190Y3BfaWQpICU+JQogIG5yb3coKQogIApuX2VlYm9faWRzX2luX2VlYm9fdGNwIDwtIGVlYm9fY29yZSAlPiUKICBmaWx0ZXIoIWlzLm5hKGVlYm9fdGNwX2lkKSkgJT4lCiAgZGlzdGluY3QoZWVib19pZCkgJT4lCiAgbnJvdygpCm5fZWVib19pZHNfaW5fZWVib190Y3BfcGhhc2VfMSA8LSBlZWJvX3RjcF9jb3JlICU+JSAKICBmaWx0ZXIoZWVib190Y3BfcGhhc2U9PSJFRUJPLVRDUCBwaGFzZSAxIikgJT4lCiAgZGlzdGluY3QoZWVib19pZCkgJT4lCiAgbnJvdygpCm5fZWVib19pZHNfaW5fZWVib190Y3BfcGhhc2VfMiA8LSBlZWJvX3RjcF9jb3JlICU+JSAKICBmaWx0ZXIoZWVib190Y3BfcGhhc2U9PSJFRUJPLVRDUCBwaGFzZSAyIikgJT4lCiAgZGlzdGluY3QoZWVib19pZCkgJT4lCiAgbnJvdygpCgphc3NlcnRfdGhhdChlZWJvX2NvcmUgJT4lIGZpbHRlcighaXMubmEoZWVib190Y3BfaWQpKSAlPiUgZGlzdGluY3QoZWVib19pZCwgZWVib190Y3BfaWQpICU+JSBjb3VudChlZWJvX3RjcF9pZCkgJT4lIGZpbHRlcihuID4gMSkgJT4lIG5yb3coKSA9PSAwKQoKbl9lZWJvX2lkc19tdWx0aW1hcHBlZF90b19lZWJvX3RjcCA8LSBlZWJvX2NvcmUgJT4lCiAgZmlsdGVyKCFpcy5uYShlZWJvX3RjcF9pZCkpICU+JQogIGRpc3RpbmN0KGVlYm9faWQsIGVlYm9fdGNwX2lkKSAlPiUKICBjb3VudChlZWJvX2lkKSAlPiUKICBmaWx0ZXIobiA+IDEpICU+JQogIG5yb3coKQoKbl9lZWJvX2lkc19ub3RfaW5fZXN0YyA8LSBlZWJvX2NvcmUgJT4lCiAgZmlsdGVyKGlzLm5hKGVzdGNfaWQpKSAlPiUKICBkaXN0aW5jdChlZWJvX2lkKSAlPiUKICBucm93KCkKbl9lZWJvX3RjcF9pZHNfbm90X2luX2VzdGMgPC0gZWVib190Y3BfY29yZSAlPiUKICBmaWx0ZXIoaXMubmEoZXN0Y19pZCkpICU+JQogIGRpc3RpbmN0KGVlYm9fdGNwX2lkKSAlPiUKICBucm93KCkKCm5fZWVib19pZHNfbXVsdGltYXBwZWRfdG9fZXN0YyA8LSBlZWJvX2NvcmUgJT4lCiAgZmlsdGVyKCFpcy5uYShlc3RjX2lkKSkgJT4lCiAgZGlzdGluY3QoZWVib19pZCwgZXN0Y19pZCkgJT4lCiAgY291bnQoZWVib19pZCkgJT4lCiAgZmlsdGVyKG4gPiAxKSAlPiUKICBucm93KCkKbl9lZWJvX3RjcF9pZHNfbXVsdGltYXBwZWRfdG9fZXN0YyA8LSBlZWJvX3RjcF9jb3JlICU+JQogIGZpbHRlcighaXMubmEoZXN0Y19pZCkpICU+JQogIGRpc3RpbmN0KGVlYm9fdGNwX2lkLCBlc3RjX2lkKSAlPiUKICBjb3VudChlZWJvX3RjcF9pZCkgJT4lCiAgZmlsdGVyKG4gPiAxKSAlPiUKICBucm93KCkKCm5fZXN0Y19pZHNfd2l0aF9lZWJvX2lkcyA8LSBlc3RjX2NvcmUgJT4lCiAgZmlsdGVyKGluX2VlYm8pICU+JQogIG5yb3coKQpuX2VzdGNfaWRzX2luX2RmX3dpdGhfZWVib19pZHMgPC0gZGYgJT4lCiAgZmlsdGVyKGluX2VlYm8pICU+JQogIG5yb3coKQpuX2VzdGNfaWRzX3dpdGhfZWVib190Y3BfaWRzIDwtIGVzdGNfY29yZSAlPiUKICBmaWx0ZXIoaW5fZWVib190Y3ApICU+JQogIG5yb3coKQpuX2VzdGNfaWRzX2luX2RmX3dpdGhfZWVib190Y3BfaWRzIDwtIGRmICU+JQogIGZpbHRlcihpbl9lZWJvX3RjcCkgJT4lCiAgbnJvdygpCgpuX2VzdGNfaWRzX2luX2RmIDwtIGRmICU+JSBucm93KCkKbl9lZWJvX2lkc19pbl9kZiA8LSBkZiAlPiUKICBpbm5lcl9qb2luKGVlYm9fY29yZSwgYnkgPSBjKCJlc3RjX2lkIikpICU+JQogIGRpc3RpbmN0KGVlYm9faWQpICU+JQogIG5yb3coKQpuX2VlYm9fdGNwX2lkc19pbl9kZiA8LSBkZiAlPiUKICBpbm5lcl9qb2luKGVlYm9fdGNwX2NvcmUsIGJ5ID0gYygiZXN0Y19pZCIpKSAlPiUKICBkaXN0aW5jdChlZWJvX3RjcF9pZCkgJT4lCiAgbnJvdygpCmBgYAoKIyBPdmVydmlldwoKT3V0IG9mIGEgdG90YWwgb2YgYHIgcChuX2VlYm9faWRzKWAgRUVCTyByZWNvcmRzLCBgciBwKG5fZWVib19pZHNfaW5fZWVib190Y3ApYCAoYHIgcHAobl9lZWJvX2lkc19pbl9lZWJvX3RjcC9uX2VlYm9faWRzKWApIGFyZSBpbiBFRUJPLVRDUCAoYnV0IGByIHAobl9lZWJvX2lkc19tdWx0aW1hcHBlZF90b19lZWJvX3RjcClgIEVFQk8gcmVjb3JkcyBoYXZlIG11bHRpcGxlIFRDUCBpZHMpLgoKVGhlIGByIHAobl9lZWJvX3RjcF9pZHMpYCBFRUJPLVRDUCByZWNvcmRzIGFyZSBkaXZpZGVkIGludG8gcGhhc2UgMSBhbmQgcGhhc2UgMi4gSW4gZGV0YWlsLCBwaGFzZSAxIGNvbnRhaW5zIGByIHAobl9lZWJvX3RjcF9pZHNfcGhhc2VfMSlgIG9mIHRoZXNlIHJlY29yZHMgKGByIHBwKG5fZWVib190Y3BfaWRzX3BoYXNlXzEvbl9lZWJvX3RjcF9pZHMpYCkgd2hpbGUgcGhhc2UgMiBjb250YWlucyBgciBwKG5fZWVib190Y3BfaWRzX3BoYXNlXzIpYCBvZiB0aGVzZSByZWNvcmRzIChgciBwcChuX2VlYm9fdGNwX2lkc19waGFzZV8yL25fZWVib190Y3BfaWRzKWApLiBJbiB0ZXJtcyBvZiBFRUJPLCBgciBwKG5fZWVib19pZHNfaW5fZWVib190Y3BfcGhhc2VfMSlgIHJlY29yZHMgKGByIHBwKG5fZWVib19pZHNfaW5fZWVib190Y3BfcGhhc2VfMS9uX2VlYm9faWRzKWApIGFyZSBpbiBFRUJPLVRDUCBwaGFzZSAxLCB3aGlsZSBgciBwKG5fZWVib19pZHNfaW5fZWVib190Y3BfcGhhc2VfMilgIHJlY29yZHMgKGByIHBwKG5fZWVib19pZHNfaW5fZWVib190Y3BfcGhhc2VfMi9uX2VlYm9faWRzKWApIGFyZSBpbiBFRUJPLVRDUCBwaGFzZSAyLgoKSW4gdGVybXMgb2YgdGhlIEVTVEMsIG91dCBvZiB0aGUgYHIgcChuX2VlYm9faWRzKWAgRUVCTyByZWNvcmRzLCBgciBwKG5fZWVib19pZHNfbm90X2luX2VzdGMpYCAgKGByIHBwKG5fZWVib19pZHNfbm90X2luX2VzdGMvbl9lZWJvX2lkcylgKSBjb3VsZCBub3QgYmUgbWF0Y2hlZCB0byBhbiBFU1RDIHJlY29yZCBhbmQgd2lsbCBiZSBsZWZ0IG91dCBvZiB0aGUgYW5hbHlzaXMuIE9uIHRoZSBvdGhlciBoYW5kLCBgciBwKG5fZWVib19pZHNfbXVsdGltYXBwZWRfdG9fZXN0YylgIEVFQk8gcmVjb3JkcyAoYHIgcHAobl9lZWJvX2lkc19tdWx0aW1hcHBlZF90b19lc3RjL25fZWVib19pZHMpYCkgd2VyZSBtYXRjaGVkIHRvIG1vcmUgdGhhbiBvbmUgRVNUQyByZWNvcmQsIHBvc3NpYmx5IGNhdXNpbmcgYmlhcy4KCk91dCBvZiB0aGUgYHIgcChuX2VlYm9fdGNwX2lkcylgIEVFQk8tVENQIHJlY29yZHMsIGByIHAobl9lZWJvX3RjcF9pZHNfbm90X2luX2VzdGMpYCAoYHIgcHAobl9lZWJvX3RjcF9pZHNfbm90X2luX2VzdGMvbl9lZWJvX3RjcF9pZHMpYCkgY291bGQgbm90IGJlIG1hdGNoZWQgdG8gYW4gRVNUQyByZWNvcmQgYW5kIHdpbGwgYmUgbGVmdCBvdXQgb2YgdGhlIGFuYWx5c2lzLiBPbiB0aGUgb3RoZXIgaGFuZCwgYHIgcChuX2VlYm9fdGNwX2lkc19tdWx0aW1hcHBlZF90b19lc3RjKWAgRUVCTy1UQ1AgcmVjb3JkcyAoYHIgcHAobl9lZWJvX3RjcF9pZHNfbXVsdGltYXBwZWRfdG9fZXN0Yy9uX2VlYm9fdGNwX2lkcylgKSB3ZXJlIG1hdGNoZWQgdG8gbW9yZSB0aGFuIG9uZSBFU1RDIHJlY29yZCwgcG9zc2libHkgY2F1c2luZyBiaWFzLgoKSW4gdGhlIGFuYWx5c2lzLCBvbmx5IEVTVEMgcmVjb3JkcyB3aXRoIHB1YmxpY2F0aW9uIHllYXJzIGluIHRoZSByYW5nZSBbMTQ3NCwxNzAwKSBoYXZlIGJlZW4gaW5jbHVkZWQuIFRoaXMgcmVzdWx0cyBpbiB0aGUgZXhjbHVzaW9uIG9mIGByIHAobl9lc3RjX2lkc193aXRoX2VlYm9faWRzLW5fZXN0Y19pZHNfaW5fZGZfd2l0aF9lZWJvX2lkcylgIChgciBwcCgobl9lc3RjX2lkc193aXRoX2VlYm9faWRzLW5fZXN0Y19pZHNfaW5fZGZfd2l0aF9lZWJvX2lkcykvbl9lc3RjX2lkc193aXRoX2VlYm9faWRzKWApIEVTVEMgcmVjb3JkcyB0aGF0IGhhdmUgcmVwcmVzZW50YXRpb24gaW4gRUVCTywgcG9zc2libHkgY2F1c2luZyBiaWFzLiBgciBwKG5fZXN0Y19pZHNfd2l0aF9lZWJvX3RjcF9pZHMtbl9lc3RjX2lkc19pbl9kZl93aXRoX2VlYm9fdGNwX2lkcylgIChgciBwcCgobl9lc3RjX2lkc193aXRoX2VlYm9fdGNwX2lkcy1uX2VzdGNfaWRzX2luX2RmX3dpdGhfZWVib190Y3BfaWRzKS9uX2VzdGNfaWRzX3dpdGhfZWVib190Y3BfaWRzKWApIG9mIHRoZSBFU1RDIHJlY29yZHMgd2l0aCByZXByZXNlbnRhdGlvbiBpbiBFRUJPLVRDUCBhcmUgcmVtb3ZlZCBkdWUgdG8gdGhpcyBmaWx0ZXJpbmcgY29uZGl0aW9uLgoKSW4gdGhlIGVuZCwgb3VyIHdvcmtpbmcgZGF0YXNldDoKCiogRnJvbSB0aGUgdmlld3BvaW50IG9mIEVFQk8sIGNvbnRhaW5zIGByIHAobl9lZWJvX2lkc19pbl9kZilgIChgciBwcChuX2VlYm9faWRzX2luX2RmL25fZWVib19pZHMpYCkgb3V0IG9mIHRoZSBvcmlnaW5hbCBgciBwKG5fZWVib19pZHMpYCBFRUJPIGlkcy4gCiogRnJvbSB0aGUgdmlld3BvaW50IG9mIEVFQk8tVENQLCBjb250YWlucyBgciBwKG5fZWVib190Y3BfaWRzX2luX2RmKWAgKGByIHBwKG5fZWVib190Y3BfaWRzX2luX2RmL25fZWVib190Y3BfaWRzKWApIG91dCBvZiB0aGUgb3JpZ2luYWwgYHIgcChuX2VlYm9fdGNwX2lkcylgIEVFQk8gaWRzLiAKKiBDb25zaXN0cyBvZiBgciBwKG5fZXN0Y19pZHNfaW5fZGYpYCBFU1RDIHJlY29yZHMsIG9mIHdoaWNoIGByIHAobl9lc3RjX2lkc19pbl9kZl93aXRoX2VlYm9faWRzKWAgKGByIHBwKG5fZXN0Y19pZHNfaW5fZGZfd2l0aF9lZWJvX2lkcy9uX2VzdGNfaWRzX2luX2RmKWApIHdlIGVzdGltYXRlIHRvIGhhdmUgcmVwcmVzZW50YXRpb24gaW4gRUVCTywgYW5kIGByIHAobl9lc3RjX2lkc19pbl9kZl93aXRoX2VlYm9fdGNwX2lkcylgIChgciBwcChuX2VzdGNfaWRzX2luX2RmX3dpdGhfZWVib190Y3BfaWRzL25fZXN0Y19pZHNfaW5fZGYpYCkgdG8gaGF2ZSByZXByZXNlbnRhdGlvbiBpbiBFRUJPLVRDUC4KCiMgUHVibGljYXRpb24gdHlwZSBhbmFseXNpcwoKIyMgQ292ZXJhZ2Ugb2YgZGlmZmVyZW50IHB1YmxpY2F0aW9uIHR5cGVzIGluIEVFQk8KCmBgYHtyLGZpZy53aWR0aD03fQpsaWJyYXJ5KGdnYmVlc3dhcm0pCmJpbmRfcm93cygKICBkZiAlPiUgbXV0YXRlKGdyb3VwID0gIkVkaXRpb25zIiksCiAgZGYgJT4lIGZpbHRlcihlZGl0aW9uX3R5cGUhPSJTaW5ndWxhciIpICU+JSBncm91cF9ieSh3b3JrX2lkLHR5cGUsZmlyc3RfcHVibGljYXRpb25feWVhcixwdWJsaWNhdGlvbl95ZWFyKSAlPiUKICAgIHN1bW1hcml6ZShpbl9lZWJvPWFueShpbl9lZWJvKSxpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGluX2VlYm9fdGNwX3BoYXNlXzE9YW55KGluX2VlYm9fdGNwX3BoYXNlXzEpLGluX2VlYm9fdGNwX3BoYXNlXzI9YW55KGluX2VlYm9fdGNwX3BoYXNlXzIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICAgIG11dGF0ZShncm91cCA9ICJXb3JrcyIsZWRpdGlvbl90eXBlPWlmX2Vsc2UocHVibGljYXRpb25feWVhcj09Zmlyc3RfcHVibGljYXRpb25feWVhciwiRmlyc3QgeWVhciB3b3JrIiwiTGF0ZXIgd29yayIpKQopICU+JQogIG11dGF0ZShlZGl0aW9uX3R5cGU9ZmN0X3JlbGV2ZWwoZWRpdGlvbl90eXBlLCJTaW5ndWxhciIsIkZpcnN0IHllYXIgd29yayIsIkxhdGVyIHdvcmsiLCJGaXJzdCB5ZWFyIGVkaXRpb24iLCJMYXRlciBlZGl0aW9uIikpICU+JQogIGZpbHRlcih0eXBlICVpbiUgYygiQm9vayIsIlBhbXBobGV0IikpICU+JQogIGdyb3VwX2J5KHB1YmxpY2F0aW9uX3llYXIsIGVkaXRpb25fdHlwZSwgZ3JvdXAsIHR5cGUsIGluX2VlYm8pICU+JSAKICB0YWxseSgpICU+JSAKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obiksIHRuID0gc3VtKG4pKSAlPiUgCiAgZmlsdGVyKGluX2VlYm8pICU+JQogIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBwcm9wLCBncm91cCA9IGVkaXRpb25fdHlwZSwgY29sb3IgPSBlZGl0aW9uX3R5cGUpKSArCiAgZ2VvbV9xdWFzaXJhbmRvbShhZXMoc2l6ZSA9IHRuKSwgZG9kZ2UgPSAxLjApICsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gZWRpdGlvbl90eXBlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEuMCksIGZ1biA9IG1lZGlhbiwgZnVuLm1pbiA9IG1lZGlhbiwgZnVuLm1heCA9IG1lZGlhbiwgZ2VvbSA9ICJjcm9zc2JhciIsIHdpZHRoID0gMC41LCBjb2xvciA9ICJyZWQiKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB4bGFiKE5VTEwpICsKICB5bGFiKCJFRUJPIGNvdmVyYWdlIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGJyZWFrcyA9IHNlcSgwLCAxLCBieSA9IDAuMDUpKSArCiAgc2NhbGVfc2l6ZShicmVha3MgPSBjKDI1MCwgNTAwLCAxNTAwKSwgcmFuZ2UgPSBjKDAuMSwgOC4wKSkgKwogIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAwKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjAyLCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKSArCiAgbGFicyhjb2xvciA9ICJSZXByZXNlbnRhdGlvbiB0eXBlIiwgc2l6ZSA9ICJDb3VudCIpICsKICBndWlkZXMoc2hhcGUgPSAibm9uZSIpCmBgYAoKSW4gdGVybXMgb2YgY292ZXJhZ2Ugb2YgRVNUQydzIHByZS0xOHRoLWNlbnR1cnkgbWF0ZXJpYWwsIEVFQk8gaXMgcXVpdGUgZ29vZCwgd2l0aCBhIG1lZGlhbiBjb3ZlcmFnZSBvZiBhYm91dCA5NSUgb2YgYm9va3MgYm90aCBhdCB0aGUgZWRpdGlvbiBhcyB3ZWxsIGFzIHRoZSB3b3JrLWxldmVsLCB3aXRoIG9ubHkgYSBzbGlnaHQgZHJvcCBpbiBjb3ZlcmFnZSBmb3IgbGF0ZXIgeWVhciBlZGl0aW9ucyAobWVhbmluZyB0aGF0IGV2ZW4gZm9yIGxhdGVyIGVkaXRpb25zLCBFRUJPIG9mdGVuIGNvbnRhaW5zIGF0IGxlYXN0IG9uZSBlZGl0aW9uIGZyb20gZWFjaCB5ZWFyLCBidXQgbWF5IG5vdCBjb250YWluIGFsbCBkaXN0aW5jdCBwcmludGluZ3MgZnJvbSB0aGF0IHllYXIpLgoKRm9yIHBhbXBobGV0cywgY292ZXJhZ2UgaXMgYWJvdXQgODUlIGFjcm9zcyB0aGUgYm9hcmQsIHdpdGggYW4gaW50ZXJlc3RpbmcgaW5jcmVhc2UgZm9yIGxhdGVyIHllYXIgZWRpdGlvbnMgKHRoaXMgbWF5IGJlIGNhdXNlZCBlaXRoZXIgYnkgcmVwcmludGVkIHBhbXBobGV0cyBoYXZpbmcgYmVlbiB0aG91Z2ggb2YgYXMgaW1wb3J0YW50IHRvIGNhcHR1cmUsIG9yIGR1ZSB0byBlLmcuIHRlbXBvcmFsIGFydGlmYWN0cywgZXZlbiB0aG91Z2ggaXQgZG9lcyBub3QgYXBwZWFyIHRoYXQgb3ZlcmFsbCBjb3ZlcmFnZSBpbXByb3ZlcyB3aXRoIHRpbWUsIGFzIHNlZW4gbGF0ZXIpLgoKIyMgQ292ZXJhZ2Ugb2YgZGlmZmVyZW50IHB1YmxpY2F0aW9uIHR5cGVzIGluIEVFQk8tVENQCgpgYGB7cixmaWcud2lkdGg9N30KbGlicmFyeShnZ2JlZXN3YXJtKQpiaW5kX3Jvd3MoCiAgZGYgJT4lIG11dGF0ZShncm91cCA9ICJFZGl0aW9ucyIpLAogIGRmICU+JSBmaWx0ZXIoZWRpdGlvbl90eXBlIT0iU2luZ3VsYXIiKSAlPiUgZ3JvdXBfYnkod29ya19pZCx0eXBlLGZpcnN0X3B1YmxpY2F0aW9uX3llYXIscHVibGljYXRpb25feWVhcikgJT4lCiAgICBzdW1tYXJpemUoaW5fZWVibz1hbnkoaW5fZWVibyksaW5fZWVib190Y3A9YW55KGluX2VlYm9fdGNwKSxpbl9lZWJvX3RjcF9waGFzZV8xPWFueShpbl9lZWJvX3RjcF9waGFzZV8xKSxpbl9lZWJvX3RjcF9waGFzZV8yPWFueShpbl9lZWJvX3RjcF9waGFzZV8yKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgICBtdXRhdGUoZ3JvdXAgPSAiV29ya3MiLGVkaXRpb25fdHlwZT1pZl9lbHNlKHB1YmxpY2F0aW9uX3llYXI9PWZpcnN0X3B1YmxpY2F0aW9uX3llYXIsIkZpcnN0IHllYXIgd29yayIsIkxhdGVyIHdvcmsiKSkKKSAlPiUKICBtdXRhdGUoZWRpdGlvbl90eXBlPWZjdF9yZWxldmVsKGVkaXRpb25fdHlwZSwiU2luZ3VsYXIiLCJGaXJzdCB5ZWFyIHdvcmsiLCJMYXRlciB3b3JrIiwiRmlyc3QgeWVhciBlZGl0aW9uIiwiTGF0ZXIgZWRpdGlvbiIpKSAlPiUKICBmaWx0ZXIodHlwZSAlaW4lIGMoIkJvb2siLCJQYW1waGxldCIpKSAlPiUKICBncm91cF9ieShwdWJsaWNhdGlvbl95ZWFyLCBlZGl0aW9uX3R5cGUsIGdyb3VwLCB0eXBlLCBpbl9lZWJvX3RjcCkgJT4lIAogIHRhbGx5KCkgJT4lIAogIG11dGF0ZShwcm9wID0gbiAvIHN1bShuKSwgdG4gPSBzdW0obikpICU+JSAKICBmaWx0ZXIoaW5fZWVib190Y3ApICU+JQogIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBwcm9wLCBncm91cCA9IGVkaXRpb25fdHlwZSwgY29sb3IgPSBlZGl0aW9uX3R5cGUpKSArCiAgZ2VvbV9xdWFzaXJhbmRvbShhZXMoc2l6ZSA9IHRuKSwgZG9kZ2UgPSAxLjApICsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gZWRpdGlvbl90eXBlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEuMCksIGZ1biA9IG1lZGlhbiwgZnVuLm1pbiA9IG1lZGlhbiwgZnVuLm1heCA9IG1lZGlhbiwgZ2VvbSA9ICJjcm9zc2JhciIsIHdpZHRoID0gMC41LCBjb2xvciA9ICJyZWQiKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB4bGFiKE5VTEwpICsKICB5bGFiKCJFRUJPLVRDUCBjb3ZlcmFnZSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLCBicmVha3MgPSBzZXEoMCwgMSwgYnkgPSAwLjA1KSkgKwogIHNjYWxlX3NpemUoYnJlYWtzID0gYygyNTAsIDUwMCwgMTUwMCksIHJhbmdlID0gYygwLjEsIDguMCkpICsKICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4wMiwgMC45OCksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGxhYnMoY29sb3IgPSAiUmVwcmVzZW50YXRpb24gdHlwZSIsIHNpemUgPSAiQ291bnQiKSArCiAgZ3VpZGVzKHNoYXBlID0gIm5vbmUiKQpgYGAKCiMjIyBDb3ZlcmFnZSBvZiBkaWZmZXJlbnQgcHVibGljYXRpb24gdHlwZXMgaW4gRUVCTy1UQ1AgcGhhc2UgMQoKYGBge3IsZmlnLndpZHRoPTd9CmxpYnJhcnkoZ2diZWVzd2FybSkKYmluZF9yb3dzKAogIGRmICU+JSBtdXRhdGUoZ3JvdXAgPSAiRWRpdGlvbnMiKSwKICBkZiAlPiUgZmlsdGVyKGVkaXRpb25fdHlwZSE9IlNpbmd1bGFyIikgJT4lIGdyb3VwX2J5KHdvcmtfaWQsdHlwZSxmaXJzdF9wdWJsaWNhdGlvbl95ZWFyLHB1YmxpY2F0aW9uX3llYXIpICU+JQogICAgc3VtbWFyaXplKGluX2VlYm89YW55KGluX2VlYm8pLGluX2VlYm9fdGNwPWFueShpbl9lZWJvX3RjcCksaW5fZWVib190Y3BfcGhhc2VfMT1hbnkoaW5fZWVib190Y3BfcGhhc2VfMSksaW5fZWVib190Y3BfcGhhc2VfMj1hbnkoaW5fZWVib190Y3BfcGhhc2VfMiksLmdyb3Vwcz0iZHJvcCIpICU+JQogICAgbXV0YXRlKGdyb3VwID0gIldvcmtzIixlZGl0aW9uX3R5cGU9aWZfZWxzZShwdWJsaWNhdGlvbl95ZWFyPT1maXJzdF9wdWJsaWNhdGlvbl95ZWFyLCJGaXJzdCB5ZWFyIHdvcmsiLCJMYXRlciB3b3JrIikpCikgJT4lCiAgbXV0YXRlKGVkaXRpb25fdHlwZT1mY3RfcmVsZXZlbChlZGl0aW9uX3R5cGUsIlNpbmd1bGFyIiwiRmlyc3QgeWVhciB3b3JrIiwiTGF0ZXIgd29yayIsIkZpcnN0IHllYXIgZWRpdGlvbiIsIkxhdGVyIGVkaXRpb24iKSkgJT4lCiAgZmlsdGVyKHR5cGUgJWluJSBjKCJCb29rIiwiUGFtcGhsZXQiKSkgJT4lCiAgZ3JvdXBfYnkocHVibGljYXRpb25feWVhciwgZWRpdGlvbl90eXBlLCBncm91cCwgdHlwZSwgaW5fZWVib190Y3BfcGhhc2VfMSkgJT4lIAogIHRhbGx5KCkgJT4lIAogIG11dGF0ZShwcm9wID0gbiAvIHN1bShuKSwgdG4gPSBzdW0obikpICU+JSAKICBmaWx0ZXIoaW5fZWVib190Y3BfcGhhc2VfMSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdHlwZSwgeSA9IHByb3AsIGdyb3VwID0gZWRpdGlvbl90eXBlLCBjb2xvciA9IGVkaXRpb25fdHlwZSkpICsKICBnZW9tX3F1YXNpcmFuZG9tKGFlcyhzaXplID0gdG4pLCBkb2RnZSA9IDEuMCkgKwogIHN0YXRfc3VtbWFyeShhZXMoZ3JvdXAgPSBlZGl0aW9uX3R5cGUpLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMS4wKSwgZnVuID0gbWVkaWFuLCBmdW4ubWluID0gbWVkaWFuLCBmdW4ubWF4ID0gbWVkaWFuLCBnZW9tID0gImNyb3NzYmFyIiwgd2lkdGggPSAwLjUsIGNvbG9yID0gInJlZCIpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHhsYWIoTlVMTCkgKwogIHlsYWIoIkVFQk8tVENQIHBoYXNlIDEgY292ZXJhZ2UiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4wNSkpICsKICBzY2FsZV9zaXplKGJyZWFrcyA9IGMoMjUwLCA1MDAsIDE1MDApLCByYW5nZSA9IGMoMC4xLCA4LjApKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDIsIDAuOTgpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveC5qdXN0ID0gImJvdHRvbSIsIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGNvbG9yID0gIlJlcHJlc2VudGF0aW9uIHR5cGUiLCBzaXplID0gIkNvdW50IikgKwogIGd1aWRlcyhzaGFwZSA9ICJub25lIikKYGBgCgojIyMgQ292ZXJhZ2Ugb2YgZGlmZmVyZW50IHB1YmxpY2F0aW9uIHR5cGVzIGluIEVFQk8tVENQIHBoYXNlIDIKCmBgYHtyLGZpZy53aWR0aD03fQpsaWJyYXJ5KGdnYmVlc3dhcm0pCmJpbmRfcm93cygKICBkZiAlPiUgbXV0YXRlKGdyb3VwID0gIkVkaXRpb25zIiksCiAgZGYgJT4lIGZpbHRlcihlZGl0aW9uX3R5cGUhPSJTaW5ndWxhciIpICU+JSBncm91cF9ieSh3b3JrX2lkLHR5cGUsZmlyc3RfcHVibGljYXRpb25feWVhcixwdWJsaWNhdGlvbl95ZWFyKSAlPiUKICAgIHN1bW1hcml6ZShpbl9lZWJvPWFueShpbl9lZWJvKSxpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGluX2VlYm9fdGNwX3BoYXNlXzE9YW55KGluX2VlYm9fdGNwX3BoYXNlXzEpLGluX2VlYm9fdGNwX3BoYXNlXzI9YW55KGluX2VlYm9fdGNwX3BoYXNlXzIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICAgIG11dGF0ZShncm91cCA9ICJXb3JrcyIsZWRpdGlvbl90eXBlPWlmX2Vsc2UocHVibGljYXRpb25feWVhcj09Zmlyc3RfcHVibGljYXRpb25feWVhciwiRmlyc3QgeWVhciB3b3JrIiwiTGF0ZXIgd29yayIpKQopICU+JQogIG11dGF0ZShlZGl0aW9uX3R5cGU9ZmN0X3JlbGV2ZWwoZWRpdGlvbl90eXBlLCJTaW5ndWxhciIsIkZpcnN0IHllYXIgd29yayIsIkxhdGVyIHdvcmsiLCJGaXJzdCB5ZWFyIGVkaXRpb24iLCJMYXRlciBlZGl0aW9uIikpICU+JQogIGZpbHRlcih0eXBlICVpbiUgYygiQm9vayIsIlBhbXBobGV0IikpICU+JQogIGdyb3VwX2J5KHB1YmxpY2F0aW9uX3llYXIsIGVkaXRpb25fdHlwZSwgZ3JvdXAsIHR5cGUsIGluX2VlYm9fdGNwX3BoYXNlXzIpICU+JSAKICB0YWxseSgpICU+JSAKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obiksIHRuID0gc3VtKG4pKSAlPiUgCiAgZmlsdGVyKGluX2VlYm9fdGNwX3BoYXNlXzIpICU+JQogIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBwcm9wLCBncm91cCA9IGVkaXRpb25fdHlwZSwgY29sb3IgPSBlZGl0aW9uX3R5cGUpKSArCiAgZ2VvbV9xdWFzaXJhbmRvbShhZXMoc2l6ZSA9IHRuKSwgZG9kZ2UgPSAxLjApICsKICBzdGF0X3N1bW1hcnkoYWVzKGdyb3VwID0gZWRpdGlvbl90eXBlKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEuMCksIGZ1biA9IG1lZGlhbiwgZnVuLm1pbiA9IG1lZGlhbiwgZnVuLm1heCA9IG1lZGlhbiwgZ2VvbSA9ICJjcm9zc2JhciIsIHdpZHRoID0gMC41LCBjb2xvciA9ICJyZWQiKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB4bGFiKE5VTEwpICsKICB5bGFiKCJFRUJPLVRDUCBwaGFzZSAyIGNvdmVyYWdlIikgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGJyZWFrcyA9IHNlcSgwLCAxLCBieSA9IDAuMDUpKSArCiAgc2NhbGVfc2l6ZShicmVha3MgPSBjKDI1MCwgNTAwLCAxNTAwKSwgcmFuZ2UgPSBjKDAuMSwgOC4wKSkgKwogIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAxKSwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjAyLCAwLjk4KSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKSArCiAgbGFicyhjb2xvciA9ICJSZXByZXNlbnRhdGlvbiB0eXBlIiwgc2l6ZSA9ICJDb3VudCIpICsKICBndWlkZXMoc2hhcGUgPSAibm9uZSIpCmBgYApGb3IgY292ZXJhZ2UgaW4gRUVCTy1UQ1AsIGEgY2xlYXIgcGF0dGVybiBlbWVyZ2VzIHdoZXJlIGNvdmVyYWdlIG9mIHNpbmd1bGFyIGFuZCBmaXJzdCBlZGl0aW9ucyBpcyBtdWNoIGJldHRlciB0aGFuIGNvdmVyYWdlIG9mIGxhdGVyIGVkaXRpb25zLiBUaGVyZSBhcmUgYWxzbyBubyBjbGVhciBkaWZmZXJlbmNlcyBiZXR3ZWVuIEVFQk8tVENQIHBoYXNlIDEgYW5kIHBoYXNlIDIgaW4gYmVoYXZpb3Igd2l0aCByZWdhcmQgdG8gdGhpcy4gVGhpcyBoYXMgYW4gaW1wb3J0YW50IGJlYXJpbmcgZm9yIGFsbCBmb2xsb3dpbmcgYW5hbHlzZXMsIHdoaWNoIGluIHRoZSBjYXNlIG9mIEVFQk8tVENQLCBzaG91bGQgbW9zdGx5IGV2YWx1YXRlIGNvdmVyYWdlIG9uIHRoaXMgd29yay1sZXZlbC4gQXMgYSBzZXBhcmF0ZSBvYnNlcnZhdGlvbiwgaW50ZXJlc3RpbmdseSwgY292ZXJhZ2Ugb2YgYm9va3MgYW5kIHBhbXBobGV0cyBhbHNvIHNlZW1zIHF1aXRlIGV2ZW4gZXZlbi4gQW5vdGhlciBvYnNlcnZhdGlvbiBpcyB0aGF0IEVFQk8tVENQIHBoYXNlIDIgY29udGFpbnMgbW9yZSBzaW5ndWxhciB3b3JrcyB0aGFuIHBoYXNlIDEuIFRoaXMgbWF5IGluZGljYXRlIGEgYnJvYWRlciBjb2xsZWN0aW9uIG9mICJub24tY29yZSIgd29ya3MsIGluc3RlYWQgb2YgZm9jdXNpbmcgb24gZmlyc3QgZWRpdGlvbnMgb2YgcG9wdWxhciAoYW5kIHRodXMgbGF0ZXIgcmVwcmludGVkKSB3b3Jrcy4KCiMgRWRpdGlvbi1sZXZlbCB0ZW1wb3JhbCBvdmVydmlldwoKYGBge3IsZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDN9CmRmICU+JSAgbXV0YXRlKGcgPSBjYXNlX3doZW4oCiAgIWNlcnRhaW4gfiAiVW5jZXJ0YWluIGRhdGluZyIsCiAgaW5fZWVib190Y3BfcGhhc2VfMSAgfiAiSW4gRUVCTy1UQ1AgcGhhc2UgMSIsCiAgaW5fZWVib190Y3BfcGhhc2VfMiAgfiAiSW4gRUVCTy1UQ1AgcGhhc2UgMiIsCiAgaW5fZWVibyB+ICJJbiBFRUJPIiwKICBUIH4gIkVTVEMgdG90YWwiLAopKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwdWJsaWNhdGlvbl95ZWFyLCBmaWxsID0gZmN0X3JlbGV2ZWwoZywgIlVuY2VydGFpbiBkYXRpbmciLCAiRVNUQyB0b3RhbCIsICJJbiBFRUJPIiwiSW4gRUVCTy1UQ1AgcGhhc2UgMSIsIkluIEVFQk8tVENQIHBoYXNlIDIiKSkpICsKICBnZW9tX2Jhcih3aWR0aCA9IDEpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSAyMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMDAwLCBieSA9IDUwMCkpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkVTVEMgZW50cmllcyIpICsKICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMSksIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4wNSwgMC45NSksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpKSArCiAgbGFicyhmaWxsID0gTlVMTCkgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHJldmVyc2UgPSBUUlVFKSkKYGBgCkluIHRlcm1zIG9mIGEgdGVtcG9yYWwgb3ZlcnZpZXcsIGl0IGlzIGltcG9ydGFudCB0byBub3RlIGhvdyBoZXJlIGluIGFuIGFic29sdXRlIGdyYXBoLCB0aGUgYW1vdW50IG9mIGVudHJpZXMgZ3Jvd3Mgc2lnbmlmaWNhbnRseSBvdmVyYWxsIHRocm91Z2ggdGltZSwgYXMgd2VsbCBhcyBoYXMgbGFyZ2UgdmFyaWF0aW9ucyBhbmQgc3Bpa2VzIG11bHRpcGxlIHRpbWVzIGJldHdlZW4gMTY0MCBhbmQgMTcwMCAod2l0aCB0aGUgbGFyZ2VyIGJ1bXAgYmV0d2VlbiAxNjQwIGFuZCAxNjYwIG1vc3QgbGlrZWx5IGNvbnNpc3RpbmcgbWFpbmx5IG9mIHRoZSBUaG9tYXNvbiBUcmFjdHMpLgoKYGBge3IsZmlnLndpZHRoID0gNiwgZmlnLmhlaWdodCA9IDN9CmRmICU+JSBmaWx0ZXIoY2VydGFpbikgJT4lIG11dGF0ZShnID0gY2FzZV93aGVuKAogIGluX2VlYm9fdGNwX3BoYXNlXzEgIH4gIkluIEVFQk8tVENQIHBoYXNlIDEiLAogIGluX2VlYm9fdGNwX3BoYXNlXzIgIH4gIkluIEVFQk8tVENQIHBoYXNlIDIiLAogIGluX2VlYm8gfiAiSW4gRUVCTyIsCiAgVCB+ICJOb3QgaW4gRUVCTyIsCikpICU+JQogIGdncGxvdChhZXMoeCA9IHB1YmxpY2F0aW9uX3llYXIsIGZpbGwgPSBmY3RfcmVsZXZlbChnLCAiTm90IGluIEVFQk8iLCAiSW4gRUVCTyIsIkluIEVFQk8tVENQIHBoYXNlIDIiLCJJbiBFRUJPLVRDUCBwaGFzZSAxIikpKSArCiAgZ2VvbV9iYXIod2lkdGggPSAxLHBvc2l0aW9uPSdmaWxsJykgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxMDAwLCAyMDAwLCBieSA9IDIwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMSwgYnkgPSAwLjEpLGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTEpKSArCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJQcm9wb3J0aW9uIG9mIEVTVEMgZW50cmllcyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIpICsKICBsYWJzKGZpbGwgPSBOVUxMKSArCiAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQocmV2ZXJzZSA9IFRSVUUpKQpgYGAKSW4gdGVybXMgb2YgZWRpdGlvbi1sZXZlbCBwcm9wb3J0aW9uYWwgY292ZXJhZ2UsIEVFQk8gY292ZXJhZ2UgaXMgcXVpdGUgYmFsYW5jZWQgdGhyb3VnaG91dCB0aGUgcGVyaW9kLCB3aXRoIGp1c3QgYSBzbGlnaHQgZHJvcCBhdCB0aGUgZW5kIG9mIHRoZSAxN3RoIGNlbnR1cnkuIEZvciBFRUJPLVRDUCwgZWRpdGlvbi1sZXZlbCBjb3ZlcmFnZSBpcyBtdWNoIG1vcmUgdmFyaWVkLCBidXQgYXMgbm90ZWQsIGl0IGFjdHVhbGx5IGRvZXMgbm90IG1ha2UgdGhhdCBtdWNoIHNlbnNlIHRvIGxvb2sgYXQgZWRpdGlvbi1sZXZlbCBjb3ZlcmFnZSB3aXRoIHJlc3BlY3QgdG8gaXQuCgojIFdvcmstbGV2ZWwgdGVtcG9yYWwgb3ZlcnZpZXcKCmBgYHtyLGZpZy53aWR0aD02LGZpZy5oZWlnaHQ9M30KZGYgJT4lIAogIGZpbHRlcihmaXJzdF9wdWJsaWNhdGlvbl95ZWFyPjE0NzQpICU+JQogIGdyb3VwX2J5KHdvcmtfaWQsZmlyc3RfcHVibGljYXRpb25feWVhcikgJT4lCiAgc3VtbWFyaXplKGluX2VlYm89YW55KGluX2VlYm8pLGluX2VlYm9fdGNwPWFueShpbl9lZWJvX3RjcCksaW5fZWVib190Y3BfcGhhc2VfMT1hbnkoaW5fZWVib190Y3BfcGhhc2VfMSksaW5fZWVib190Y3BfcGhhc2VfMj1hbnkoaW5fZWVib190Y3BfcGhhc2VfMiksY2VydGFpbj1hbnkoZmlyc3RfeWVhcl9wdWJsaWNhdGlvbiAmIGNlcnRhaW4pLC5ncm91cHM9ImRyb3AiKSAlPiUgCiAgbXV0YXRlKGcgPSBjYXNlX3doZW4oCiAgICAhY2VydGFpbiB+ICJVbmNlcnRhaW4gZGF0aW5nIiwKICAgIGluX2VlYm9fdGNwX3BoYXNlXzEgIH4gIkluIEVFQk8tVENQIHBoYXNlIDEiLAogICAgaW5fZWVib190Y3BfcGhhc2VfMiAgfiAiSW4gRUVCTy1UQ1AgcGhhc2UgMiIsCiAgICBpbl9lZWJvIH4gIkluIEVFQk8iLAogICAgVCB+ICJFU1RDIHRvdGFsIiwKICApKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZmlyc3RfcHVibGljYXRpb25feWVhciwgZmlsbCA9IGZjdF9yZWxldmVsKGcsICJVbmNlcnRhaW4gZGF0aW5nIiwgIkVTVEMgdG90YWwiLCAiSW4gRUVCTyIsIkluIEVFQk8tVENQIHBoYXNlIDIiLCJJbiBFRUJPLVRDUCBwaGFzZSAxIikpKSArCiAgZ2VvbV9iYXIod2lkdGggPSAxKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwMDAsIDIwMDAsIGJ5ID0gMjApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMDAwMCwgYnkgPSA1MDApKSArCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJFU1RDIGVudHJpZXMiKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDEpLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDUsIDAuOTUpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGxhYnMoZmlsbCA9IE5VTEwpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpCmBgYAoKCmBgYHtyLGZpZy53aWR0aD02LGZpZy5oZWlnaHQ9M30KZGYgJT4lIAogIGZpbHRlcihmaXJzdF9wdWJsaWNhdGlvbl95ZWFyPjE0NzQpICU+JQogIGdyb3VwX2J5KHdvcmtfaWQsZmlyc3RfcHVibGljYXRpb25feWVhcikgJT4lCiAgc3VtbWFyaXplKGluX2VlYm89YW55KGluX2VlYm8pLGluX2VlYm9fdGNwPWFueShpbl9lZWJvX3RjcCksaW5fZWVib190Y3BfcGhhc2VfMT1hbnkoaW5fZWVib190Y3BfcGhhc2VfMSksaW5fZWVib190Y3BfcGhhc2VfMj1hbnkoaW5fZWVib190Y3BfcGhhc2VfMiksY2VydGFpbj1hbnkoZmlyc3RfeWVhcl9wdWJsaWNhdGlvbiAmIGNlcnRhaW4pLC5ncm91cHM9ImRyb3AiKSAlPiUgbXV0YXRlKGcgPSBjYXNlX3doZW4oCiAgaW5fZWVib190Y3BfcGhhc2VfMSAgfiAiSW4gRUVCTy1UQ1AgcGhhc2UgMSIsCiAgaW5fZWVib190Y3BfcGhhc2VfMiAgfiAiSW4gRUVCTy1UQ1AgcGhhc2UgMiIsCiAgaW5fZWVibyB+ICJJbiBFRUJPIiwKICBUIH4gIk5vdCBpbiBFRUJPIiwKKSkgJT4lIAogIGZpbHRlcihjZXJ0YWluKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmaXJzdF9wdWJsaWNhdGlvbl95ZWFyLCBmaWxsID0gZmN0X3JlbGV2ZWwoZywgIk5vdCBpbiBFRUJPIiwgIkluIEVFQk8iLCJJbiBFRUJPLVRDUCBwaGFzZSAyIiwiSW4gRUVCTy1UQ1AgcGhhc2UgMSIpKSkgKwogIGdlb21fYmFyKHdpZHRoID0gMSxwb3NpdGlvbj0nZmlsbCcpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSAyMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4xKSxsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0xKSkgKwogIHhsYWIoIlllYXIgb2YgZmlyc3QgcHVibGljYXRpb24iKSArCiAgeWxhYigiUHJvcG9ydGlvbiBvZiBFU1RDIHdvcmtzIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKwogIGxhYnMoZmlsbCA9IE5VTEwpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICAKYGBgCkluIHRlcm1zIG9mIHdvcmstbGV2ZWwgY292ZXJhZ2UsIGFsc28gRUVCTy1UQ1AgYXBwZWFycyBxdWl0ZSBuaWNlbHkgYmFsYW5jZWQgdGVtcG9yYWxseSwgYXBhcnQgZnJvbSBkaXBzIGJldHdlZW4gMTUwMCBhbmQgMTUzMC4gSG93ZXZlciwgaXQgbXVzdCBiZSBub3RlZCBob3cgdGhlIHRvdGFsIGFtb3VudCBvZiBjb250ZW50IGlzIGFsc28gdmVyeSBsb3cgZm9yIHRob3NlIGVhcmx5IHllYXJzLCBzbyBsYXJnZXIgdmFyaWF0aW9uIGNhbiBhbHNvIGJlIGV4cGVjdGVkLiBUaGUgYWRkaXRpb24gb2YgcGhhc2UgMiBpbXByb3ZlcyB0aGUgZXZlbm5lc3Mgb2YgRUVCTy1UQ1AgY292ZXJhZ2UgYSBiaXQgd2l0aCByZWdhcmQgdG8gcGhhc2UgMSwgd2hlcmUgY292ZXJhZ2UgZGltaW5pc2hlcyB0b3dhcmQgdGhlIGVuZCBvZiB0aGUgY2VudHVyeS4KCiMgRG9jdW1lbnQgdHlwZSBjb3ZlcmFnZSB0aHJvdWdoIHRpbWUKCmBgYHtyLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NH0KYmluZF9yb3dzKAogIGRmICU+JSBtdXRhdGUoZ3JvdXAgPSAiRWRpdGlvbnMiLHR5cGU9cmVjb2RlKHR5cGUsIkJvb2siPSJCb29rIChlZGl0aW9uLWxldmVsKSIsIlBhbXBobGV0Ij0iUGFtcGhsZXQgKGVkaXRpb24tbGV2ZWwpIikpLAogIGRmICU+JSBncm91cF9ieSh3b3JrX2lkLHR5cGUsZmlyc3RfcHVibGljYXRpb25feWVhcixwdWJsaWNhdGlvbl95ZWFyKSAlPiUKICAgIHN1bW1hcml6ZShpbl9lZWJvPWFueShpbl9lZWJvKSxpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGNlcnRhaW49YW55KGZpcnN0X3llYXJfcHVibGljYXRpb24gJiBjZXJ0YWluKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgICBtdXRhdGUoZ3JvdXAgPSAiV29ya3MiKQopICU+JQogIG11dGF0ZSh0eXBlPWZjdF9yZWxldmVsKHR5cGUsIlBhbXBobGV0IChlZGl0aW9uLWxldmVsKSIsIkJvb2sgKGVkaXRpb24tbGV2ZWwpIiwiUGFtcGhsZXQiLCJCb29rIikpICU+JQogIGZpbHRlcihjZXJ0YWluKSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh0eXBlKSx0eXBlIT0iSW4tYmV0d2VlbiIpICU+JSAKICBncm91cF9ieShwdWJsaWNhdGlvbl95ZWFyLCB0eXBlLCBpbl9lZWJvKSAlPiUgCiAgdGFsbHkoKSAlPiUgCiAgbXV0YXRlKHByb3AgPSBuIC8gc3VtKG4pLCB0biA9IHN1bShuKSkgJT4lIAogIGZpbHRlcihpbl9lZWJvKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBwdWJsaWNhdGlvbl95ZWFyLCB5ID0gcHJvcCwgY29sb3IgPSB0eXBlKSkgKwogIGdlb21fc21vb3RoKGFlcyh3ZWlnaHQgPSBuLCBmaWxsID0gdHlwZSksIHNwYW4gPSAwLjMsIG1ldGhvZD0nbG9lc3MnLGZvcm11bGE9eX54KSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJncmF5Iiwgc2hhcGUgPSAyMSwgYWVzKHNpemUgPSB0bikpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gbikpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSAyMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLCBicmVha3MgPSBzZXEoMCwgMSwgYnkgPSAwLjEwKSkgKwogIHhsYWIoIlllYXIiKSArCiAgeWxhYigiRUVCTyBjb3ZlcmFnZSIpICsKICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDUsIDAuMDIpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGxhYnMoY29sb3IgPSBOVUxMLCBzaXplID0gTlVMTCwgc2hhcGUgPSBOVUxMLCBmaWxsID0gTlVMTCkgKwogIHNjYWxlX3NpemUoYnJlYWtzID0gYyg1MDAsIDIwMDAsIDM1MDApLCByYW5nZSA9IGMoMC4xLCA4LjApKQpgYGAKRHJpbGxpbmcgaW4gYW5kIHNlcGFyYXRpbmcgYm9va3MgYW5kIHBhbXBobGV0cyBmcm9tIGVhY2ggb3RoZXIsIHdlIGNhbiBzZWUgdGhhdCBFRUJPIGNvdmVyYWdlIG9mIGJvdGggaXMgdmVyeSBnb29kLCBhcGFydCBmcm9tIGEgbm90aWNlYWJsZSBkcm9wIGluIHBhbXBobGV0IGNvdmVyYWdlIGluIHRoZSBsYXRlIDE3dGggY2VudHVyeS4KCmBgYHtyLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NH0KYmluZF9yb3dzKAogIGRmICU+JSBtdXRhdGUoZ3JvdXAgPSAiRWRpdGlvbnMiLHR5cGU9cmVjb2RlKHR5cGUsIkJvb2siPSJCb29rIChlZGl0aW9uLWxldmVsKSIsIlBhbXBobGV0Ij0iUGFtcGhsZXQgKGVkaXRpb24tbGV2ZWwpIikpLAogIGRmICU+JSBncm91cF9ieSh3b3JrX2lkLHR5cGUsZmlyc3RfcHVibGljYXRpb25feWVhcixwdWJsaWNhdGlvbl95ZWFyKSAlPiUKICAgIHN1bW1hcml6ZShpbl9lZWJvPWFueShpbl9lZWJvKSxpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGNlcnRhaW49YW55KGZpcnN0X3llYXJfcHVibGljYXRpb24gJiBjZXJ0YWluKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgICBtdXRhdGUoZ3JvdXAgPSAiV29ya3MiKQopICU+JQogIG11dGF0ZSh0eXBlPWZjdF9yZWxldmVsKHR5cGUsIlBhbXBobGV0IChlZGl0aW9uLWxldmVsKSIsIkJvb2sgKGVkaXRpb24tbGV2ZWwpIiwiUGFtcGhsZXQiLCJCb29rIikpICU+JQogIGZpbHRlcihjZXJ0YWluKSAlPiUgCiAgZmlsdGVyKCFpcy5uYSh0eXBlKSx0eXBlIT0iSW4tYmV0d2VlbiIpICU+JSAKICBncm91cF9ieShwdWJsaWNhdGlvbl95ZWFyLCB0eXBlLCBpbl9lZWJvX3RjcCkgJT4lIAogIHRhbGx5KCkgJT4lIAogIG11dGF0ZShwcm9wID0gbiAvIHN1bShuKSwgdG4gPSBzdW0obikpICU+JSAKICBmaWx0ZXIoaW5fZWVib190Y3ApICU+JQogIGdncGxvdChhZXMoeCA9IHB1YmxpY2F0aW9uX3llYXIsIHkgPSBwcm9wLCBjb2xvciA9IHR5cGUpKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHdlaWdodCA9IG4sIGZpbGwgPSB0eXBlKSwgc3BhbiA9IDAuMywgbWV0aG9kPSdsb2VzcycsZm9ybXVsYT15fngpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImdyYXkiLCBzaGFwZSA9IDIxLCBhZXMoc2l6ZSA9IHRuKSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuKSkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxMDAwLCAyMDAwLCBieSA9IDIwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGJyZWFrcyA9IHNlcSgwLCAxLCBieSA9IDAuMTApKSArCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJFRUJPLVRDUCBjb3ZlcmFnZSIpICsKICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDUsIDAuMDIpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGxhYnMoY29sb3IgPSBOVUxMLCBzaXplID0gTlVMTCwgc2hhcGUgPSBOVUxMLCBmaWxsID0gTlVMTCkgKwogIHNjYWxlX3NpemUoYnJlYWtzID0gYyg1MDAsIDIwMDAsIDM1MDApLCByYW5nZSA9IGMoMC4xLCA4LjApKQpgYGAKRm9yIEVFQk8tVENQLCBvbiB0aGUgd29yayBsZXZlbCwgdGhlIHNhbWUgZHJvcCBpbiBjb3ZlcmFnZSBmb3IgcGFtcGhsZXRzIGF0IHRoZSBlbmQgb2YgdGhlIDE3dGggY2VudHVyeSBjYW4gYmUgc2VlbiwgYnV0IG90aGVyd2lzZSBjb3ZlcmFnZSBpcyByZWxhdGl2ZWx5IHN0YWJsZSB0aHJvdWdoIHRpbWUgZm9yIGJvdGggYm9va3MgYXMgd2VsbCBhcyBwYW1waGxldHMsIGV4Y2VwdCBmb3IgYSBtYXJrZWQgdXB0aWNrIGJldHdlZW4gMTY0MCBhbmQgMTY2MCAoY2F1c2VkIG1vc3QgbGlrZWx5IGJ5IG1vcmUganVkaWNpb3VzIGluY2x1c2lvbiBvZiB0aGUgVGhvbWFzb24gVHJhY3RzKS4gT24gdGhlIHdvcmsgbGV2ZWwsIHBhbXBobGV0cyBhcmUganVzdCBzbGlnaHRseSBiZXR0ZXIgY292ZXJlZCB0aGFuIGJvb2tzLCBidXQgb24gdGhlIG9uIHRoZSBlZGl0aW9uIGxldmVsLCBjb3ZlcmFnZSBvZiBib29rcyBpcyBtdWNoIGxvd2VyLiBUaGlzIGNhbiBiZSBzZWVuIGFzIG9ubHkgdGhlIG5hdHVyYWwgY29uc2VxdWVuY2Ugb2YgRUVCTy1UQ1AgZmF2b3VyaW5nIGluY2x1ZGluZyBvbmx5IGZpcnN0IGVkaXRpb25zLiBCb29rcyB0eXBpY2FsbHkgaGF2ZSBtb3JlIGVkaXRpb25zIHRoYW4gcGFtcGhsZXRzLCBzbyBleGNsdWRpbmcgbGF0ZXIgZWRpdGlvbnMgYWZmZWN0cyBlZGl0aW9uLWxldmVsIGNvdmVyYWdlIGZvciBib29rcyBtdWNoIG1vcmUgdGhhbiBpdCBkb2VzIGZvciBwYW1waGxldHMuCgpgYGB7cixmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTR9CmJpbmRfcm93cygKICBkZiAlPiUgbXV0YXRlKGdyb3VwID0gIkVkaXRpb25zIix0eXBlPXJlY29kZSh0eXBlLCJCb29rIj0iQm9vayAoZWRpdGlvbi1sZXZlbCkiLCJQYW1waGxldCI9IlBhbXBobGV0IChlZGl0aW9uLWxldmVsKSIpKSwKICBkZiAlPiUgZ3JvdXBfYnkod29ya19pZCx0eXBlLGZpcnN0X3B1YmxpY2F0aW9uX3llYXIscHVibGljYXRpb25feWVhcikgJT4lCiAgICBzdW1tYXJpemUoaW5fZWVibz1hbnkoaW5fZWVibyksaW5fZWVib190Y3A9YW55KGluX2VlYm9fdGNwKSxpbl9lZWJvX3RjcF9waGFzZV8xPWFueShpbl9lZWJvX3RjcF9waGFzZV8xKSxjZXJ0YWluPWFueShmaXJzdF95ZWFyX3B1YmxpY2F0aW9uICYgY2VydGFpbiksLmdyb3Vwcz0iZHJvcCIpICU+JQogICAgbXV0YXRlKGdyb3VwID0gIldvcmtzIikKKSAlPiUKICBtdXRhdGUodHlwZT1mY3RfcmVsZXZlbCh0eXBlLCJQYW1waGxldCAoZWRpdGlvbi1sZXZlbCkiLCJCb29rIChlZGl0aW9uLWxldmVsKSIsIlBhbXBobGV0IiwiQm9vayIpKSAlPiUKICBmaWx0ZXIoY2VydGFpbikgJT4lIAogIGZpbHRlcighaXMubmEodHlwZSksdHlwZSE9IkluLWJldHdlZW4iKSAlPiUgCiAgZ3JvdXBfYnkocHVibGljYXRpb25feWVhciwgdHlwZSwgaW5fZWVib190Y3BfcGhhc2VfMSkgJT4lIAogIHRhbGx5KCkgJT4lIAogIG11dGF0ZShwcm9wID0gbiAvIHN1bShuKSwgdG4gPSBzdW0obikpICU+JSAKICBmaWx0ZXIoaW5fZWVib190Y3BfcGhhc2VfMSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gcHVibGljYXRpb25feWVhciwgeSA9IHByb3AsIGNvbG9yID0gdHlwZSkpICsKICBnZW9tX3Ntb290aChhZXMod2VpZ2h0ID0gbiwgZmlsbCA9IHR5cGUpLCBzcGFuID0gMC4zLCBtZXRob2Q9J2xvZXNzJyxmb3JtdWxhPXl+eCkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAiZ3JheSIsIHNoYXBlID0gMjEsIGFlcyhzaXplID0gdG4pKSArCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IG4pKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwMDAsIDIwMDAsIGJ5ID0gMjApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4xMCkpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkVFQk8tVENQIHBoYXNlIDEgY292ZXJhZ2UiKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDApLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjA1LCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGNvbG9yID0gTlVMTCwgc2l6ZSA9IE5VTEwsIHNoYXBlID0gTlVMTCwgZmlsbCA9IE5VTEwpICsKICBzY2FsZV9zaXplKGJyZWFrcyA9IGMoNTAwLCAyMDAwLCAzNTAwKSwgcmFuZ2UgPSBjKDAuMSwgOC4wKSkKYGBgCgpMb29raW5nIG9ubHkgYXQgcGhhc2UgMSwgdGhlcmUgaXMgYSBjbGVhciBidW1wIGluIHRoZSByZXByZXNlbnRhdGlvbiBvZiBwYW1waGxldHMgaW4gdGhlIDE1NjBzLCB3aGljaCBpbnRlcmVzdGluZ2x5IGlzIGNvcnJlY3RlZCBmb3Igd2hlbiB0YWtpbmcgaW4gYWxzbyBwaGFzZSAyLiBJbiB0ZXJtcyBvZiBib29rIGNvdmVyYWdlLCB0aGVyZSBpcyBhbHNvIGEgbGluZWFyIGRlY2xpbmUgaW4gY292ZXJhZ2UgYmV0d2VlbiBhYm91dCAxNTYwIGFuZCAxNjUwIChiZWZvcmUgMTU0MCB0aGUgZGF0YSBpcyBzbyBzcGFyc2UgdGhhdCByZWxpYWJsZSBjb25jbHVzaW9ucyBjYW5ub3QgYmUgZHJhd24gZnJvbSBpdCkuCgojIFRvcGljYWwgY292ZXJhZ2UgRUVCTy1UQ1AgdnMgRUVCTwoKIyMgRUVCTyB3b3JrLWxldmVsIGdlbnJlIHVzZSBmcmVxdWVuY2llcwoKKHN1YnNldCB0aGF0IGlzIGluIEVTVEMgdG8gZ2V0IHRoZSB3b3JrIGluZm9ybWF0aW9uKQoKYGBge3IsZmlnLndpZHRoPTcsZmlnLmhlaWdodD01fQplZWJvX3VzdGNfZ2VucmVzICU+JSAKICBpbm5lcl9qb2luKGVlYm9fY29yZSxieT1jKCJlZWJvX2lkIikpICU+JQogIGlubmVyX2pvaW4oZXN0Y19jb3JlLGJ5PWMoImVzdGNfaWQiKSkgJT4lIAogIG11dGF0ZSh1c3RjX2dlbnJlPXN0cl90cnVuYyh1c3RjX2dlbnJlLDY1KSxzdGF0dXM9Y2FzZV93aGVuKAogICAgaW5fZWVib190Y3BfcGhhc2VfMSB+ICJFRUJPLVRDUCBwaGFzZSAxIiwKICAgIGluX2VlYm9fdGNwX3BoYXNlXzIgfiAiRUVCTy1UQ1AgcGhhc2UgMiIsCiAgICBUIH4gIk5vdCBpbiBFRUJPLVRDUCIpKSAlPiUKICBncm91cF9ieSh1c3RjX2dlbnJlLHN0YXR1cykgJT4lCiAgc3VtbWFyaXplKG49bl9kaXN0aW5jdCh3b3JrX2lkKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgZ3JvdXBfYnkodXN0Y19nZW5yZSkgJT4lCiAgbXV0YXRlKHRuPXN1bShuKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZSh1c3RjX2dlbnJlPWZjdF9yZW9yZGVyKHVzdGNfZ2VucmUsdG4pKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dXN0Y19nZW5yZSx5PW4sZmlsbD1zdGF0dXMpKSArIAogIGdlb21fY29sKCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDApLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk4LCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGZpbGw9TlVMTCkgKyAgCiAgeGxhYigiVVNUQyBnZW5yZSIpICsKICB5bGFiKCJOdW1iZXIgb2Ygd29ya3MiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6Om51bWJlcikgKwogIGNvb3JkX2ZsaXAoKQpgYGAKCk9wZW4gcXVlc3Rpb246IGFyZSB0aGUgVVNUQyBjYXRlZ29yaWVzIHVzYWJsZT8gSXMgdGhpcyBhIGJlbGlldmFibGUgZ2VucmUgZGlzdHJpYnV0aW9uPyBJZiBpdCBpcywgdGhlIGJlbG93IGdyYXBocyBzaG93IGludGVyZXN0aW5nIGRpZmZlcmVuY2UgYW5kIHRlbXBvcmFsIHNoaWZ0cyBpbiB0aGUgY292ZXJhZ2Ugb2YgdGhlIHZhcmlvdXMgY2F0ZWdvcmllcywgdGhlIGludGVycHJldGF0aW9uIG9mIHdoaWNoIEkgbGVhdmUgdXAgdG8geW91LiAKCmBgYHtyLGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZ29vZ2xlc2hlZXRzNCkKc2V0LnNlZWQoNDIpCmVlYm9fdXN0Y19nZW5yZV9zYW1wbGUgPC0gZWVib19jb3JlICU+JSAKICBmaWx0ZXIoIWlzLm5hKHByb3F1ZXN0X3VybCkpICU+JQogIGRpc3RpbmN0KGVlYm9faWQscHJvcXVlc3RfdXJsKSAlPiUKICBsZWZ0X2pvaW4oZWVib191c3RjX2dlbnJlcykgJT4lIAogIGdyb3VwX2J5KHVzdGNfZ2VucmUpICU+JSAKICBzbGljZV9zYW1wbGUobj0yMCkgJT4lIAogIHVuZ3JvdXAoKSAlPiUKICBkaXN0aW5jdChlZWJvX2lkLHByb3F1ZXN0X3VybCkgJT4lIAogIGxlZnRfam9pbihlZWJvX3VzdGNfZ2VucmVzKSAlPiUgCiAgZGlzdGluY3QoZWVib19pZCxwcm9xdWVzdF91cmwsdXN0Y19nZW5yZSkgJT4lCiAgZ3JvdXBfYnkoZWVib19pZCxwcm9xdWVzdF91cmwpICU+JSAKICBzdW1tYXJpemUodXN0Y19nZW5yZXM9c3RyX2ZsYXR0ZW4odXN0Y19nZW5yZSxjb2xsYXBzZT0ifCIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBhcnJhbmdlKHVzdGNfZ2VucmVzKSAlPiUKICBtdXRhdGUocHJvcXVlc3RfdXJsPWdzNF9mb3JtdWxhKHN0cl9jKCc9SFlQRVJMSU5LKCInLHByb3F1ZXN0X3VybCwnIiwiJyxwcm9xdWVzdF91cmwsJyIpJykpKQojd3JpdGVfc2hlZXQoZWVib191c3RjX2dlbnJlX3NhbXBsZSxzcz0iMUhxMmN2YV9LNUpBNWswczhxSGVrRWd3R0JHdDZNeENUXzNjcFZuTHdQN3ciLHNoZWV0PSJlZWJvX3VzdGNfZ2VucmVfc2FtcGxlIikKI2dzNF9jcmVhdGUoImVlYm9fdXN0Y19nZW5yZV9zYW1wbGUiLHNoZWV0cz1lZWJvX3VzdGNfZ2VucmVfc2FtcGxlKQpgYGAKCgojIyBFRUJPLVRDUCB3b3JrLWxldmVsIGdlbnJlIGNvdmVyYWdlCgpgYGB7cixmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTV9CmVlYm9fdXN0Y19nZW5yZXMgJT4lIAogICAgaW5uZXJfam9pbihlZWJvX2NvcmUsYnk9YygiZWVib19pZCIpKSAlPiUKICAgIGlubmVyX2pvaW4oZXN0Y19jb3JlLGJ5PWMoImVzdGNfaWQiKSkgJT4lCiAgbXV0YXRlKHVzdGNfZ2VucmU9c3RyX3RydW5jKHVzdGNfZ2VucmUsNjUpKSAlPiUKICBncm91cF9ieSh3b3JrX2lkLHVzdGNfZ2VucmUpICU+JQogIHN1bW1hcml6ZShpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGluX2VlYm9fdGNwX3BoYXNlXzE9YW55KGluX2VlYm9fdGNwX3BoYXNlXzEpLGluX2VlYm9fdGNwX3BoYXNlXzI9YW55KGluX2VlYm9fdGNwX3BoYXNlXzIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBncm91cF9ieSh1c3RjX2dlbnJlKSAlPiUKICBzdW1tYXJpemUobj1uKCksYEVFQk8tVENQYD1zdW0oaW5fZWVib190Y3ApL24oKSxgRUVCTy1UQ1AgcGhhc2UgMWA9c3VtKGluX2VlYm9fdGNwX3BoYXNlXzEpL24oKSxgRUVCTy1UQ1AgcGhhc2UgMmA9c3VtKGluX2VlYm9fdGNwX3BoYXNlXzIpL24oKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgbXV0YXRlKHVzdGNfZ2VucmU9ZmN0X3Jlb3JkZXIoc3RyX2ModXN0Y19nZW5yZSwnICgnLG4sJyknKSxuKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGBFRUJPLVRDUCBwaGFzZSAxYDpgRUVCTy1UQ1AgcGhhc2UgMmAsbmFtZXNfdG89InBhcnQiLCB2YWx1ZXNfdG8gPSAicHJvcCIpICU+JQogIGdncGxvdChhZXMoeD11c3RjX2dlbnJlLHk9cHJvcCxmaWxsPWZjdF9yZWxldmVsKHBhcnQsJ0VFQk8tVENQIHBoYXNlIDInKSkpICsgCiAgZ2VvbV9jb2wocG9zaXRpb249J3N0YWNrJykgKyAKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHM9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeT0xKSkgKwogIHhsYWIoIlVTVEMgZ2VucmUiKSArCiAgeWxhYigiQ292ZXJhZ2UgYnkgd29yayIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikgKwojICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwgMCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuMDIpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGxhYnMoZmlsbD1OVUxMKSArCiAgY29vcmRfZmxpcCgpIApgYGAKCkhlcmUsIHdlIGNhbiBmaXJzdCBzZWUgd2hpY2ggY2F0ZWdvcmllcyBoYXZlIGJlZW4gZXhjbHVkZWQgZnJvbSBFRUJPLVRDUDogYWxtYW5hY3MsYWNhZGVtaWMgZGlzc2VydGF0aW9ucywgYXN0cm9sb2d5IGFuZCBjb3Ntb2dyYXBoeSwgYXMgd2VsbCBhcyBkaWN0aW9uYXJpZXMuIEFwYXJ0IGZyb20gdGhpcywgd2UgYWxzbyBzZWUgaG93IHBvZXRyeSBhbmQgZHJhbWEgYXJlIGhlYXZpbHkgb3ZlcmVtcGhhc2l6ZWQgaW4gRUVCTy1UQ1AgcGhhc2UgMSwgd2hlcmVhcyBwaGFzZSAyIGNvcnJlY3RzIG5pY2VseSBmb3IgdGhlc2UgYXMgd2VsbCBhcyBvdGhlciBpbWJhbGFuY2VzLiBXaGF0IHJlbWFpbnMgaW50ZXJlc3RpbmcgaXMgYSBsb3cgY292ZXJhZ2Ugb2YgZGlhbGVjdGljcyBhbmQgcmhldG9yaWMsIGxpbmd1aXN0aWNzIGFuZCBwaGlsb2xvZ3kgYW5kIGNsYXNzaWNhbCBhdXRob3JzLgoKIyMgRUVCTy1UQ1AgcGhhc2UgZ2VucmUgY29tcG9zaXRpb24gY29tcGFyaXNvbgoKIyMjIFRPRE86IFRvIHJlbW92ZT8gRG9lcyB0aGlzIGFkZCBhbnkgaW5mb3JtYXRpb24/IFdpdGhpbi1kYXRhc2V0IHByb3BvcnRpb25zIGFyZSB1bmludHVpdGl2ZSB0byBjb21wYXJlIGJldHdlZW4gZGF0YXNldHMuCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTV9CmVlYm9fdXN0Y19nZW5yZXMgJT4lCiAgaW5uZXJfam9pbihlZWJvX3RjcF9jb3JlLGJ5PWMoImVlYm9faWQiKSkgJT4lCiAgaW5uZXJfam9pbihlc3RjX2NvcmUsYnk9YygiZXN0Y19pZCIpKSAlPiUKICBtdXRhdGUodXN0Y19nZW5yZT1zdHJfdHJ1bmModXN0Y19nZW5yZSw2NSkpICU+JQogIGNvdW50KGVlYm9fdGNwX3BoYXNlLHVzdGNfZ2VucmUpICU+JQogIGdyb3VwX2J5KGVlYm9fdGNwX3BoYXNlKSAlPiUgbXV0YXRlKHByb3A9bi9zdW0obikpICU+JQogIG11dGF0ZSh1c3RjX2dlbnJlPWZjdF9yZW9yZGVyKHVzdGNfZ2VucmUscHJvcCkpICU+JQogIGdncGxvdChhZXMoeD11c3RjX2dlbnJlLHk9cHJvcCxmaWxsPWVlYm9fdGNwX3BoYXNlICU+JSByZWNvZGUoIkVFQk8tVENQIHBhcnQgMSI9IkVFQk8tVENQIHBoYXNlIDEiLCJFRUJPLVRDUCBwYXJ0IDIiPSJFRUJPLVRDUCBwaGFzZSAyIikpKSArIAogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpICsgCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3k9MSkpICsKICB4bGFiKCJVU1RDIGdlbnJlIikgKwogIHlsYWIoIlByb3BvcnRpb24gb2YgRUVCTy1UQ1AgcGhhc2UiKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDApLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjk4LCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGZpbGw9TlVMTCkgKwogIGNvb3JkX2ZsaXAoKSAKYGBgCgojIyBFRUJPIHdvcmstbGV2ZWwgbGFuZ3VhZ2UgZnJlcXVlbmNpZXMKCmBgYHtyLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NX0KZWVib19jb3JlICU+JQogIGlubmVyX2pvaW4oZXN0Y19jb3JlLGJ5PWMoImVzdGNfaWQiKSkgJT4lIAogIG11dGF0ZShzdGF0dXM9Y2FzZV93aGVuKAogICAgaW5fZWVib190Y3BfcGhhc2VfMSB+ICJFRUJPLVRDUCBwaGFzZSAxIiwKICAgIGluX2VlYm9fdGNwX3BoYXNlXzIgfiAiRUVCTy1UQ1AgcGhhc2UgMiIsCiAgICBUIH4gIk5vdCBpbiBFRUJPLVRDUCIpKSAlPiUKICBncm91cF9ieShlZWJvX3Rsc19sYW5ndWFnZSxzdGF0dXMpICU+JQogIHN1bW1hcml6ZShuPW5fZGlzdGluY3Qod29ya19pZCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGdyb3VwX2J5KGVlYm9fdGxzX2xhbmd1YWdlKSAlPiUKICBtdXRhdGUodG49c3VtKG4pKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKGVlYm9fdGxzX2xhbmd1YWdlPWZjdF9yZW9yZGVyKGVlYm9fdGxzX2xhbmd1YWdlLHRuKSkgJT4lCiAgZ2dwbG90KGFlcyh4PWVlYm9fdGxzX2xhbmd1YWdlLHk9bixmaWxsPXN0YXR1cykpICsgCiAgZ2VvbV9jb2woKSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMSwgMCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuOTgsIDAuMDIpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGxhYnMoZmlsbD1OVUxMKSArICAKICB4bGFiKCJMYW5ndWFnZSIpICsKICB5bGFiKCJOdW1iZXIgb2Ygd29ya3MgKGxvZzEwKSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzPXNjYWxlczo6bnVtYmVyLHRyYW5zPSJsb2cxMCIpICsKICBjb29yZF9mbGlwKCkKYGBgCgojIyBFRUJPLVRDUCB3b3JrLWxldmVsIGxhbmd1YWdlIGNvdmVyYWdlIHZzIEVFQk8KCmBgYHtyLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NX0KZWVib19jb3JlICU+JQogIGZpbHRlcighaXMubmEoZWVib190bHNfbGFuZ3VhZ2UpKSAlPiUKICBpbm5lcl9qb2luKGVzdGNfY29yZSxieT1jKCJlc3RjX2lkIikpICU+JQogIGdyb3VwX2J5KHdvcmtfaWQsZWVib190bHNfbGFuZ3VhZ2UpICU+JQogIHN1bW1hcml6ZShpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGluX2VlYm9fdGNwX3BoYXNlXzE9YW55KGluX2VlYm9fdGNwX3BoYXNlXzEpLGluX2VlYm9fdGNwX3BoYXNlXzI9YW55KGluX2VlYm9fdGNwX3BoYXNlXzIpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBncm91cF9ieShlZWJvX3Rsc19sYW5ndWFnZSkgJT4lCiAgc3VtbWFyaXplKG49bigpLGBFRUJPLVRDUGA9c3VtKGluX2VlYm9fdGNwKS9uKCksYEVFQk8tVENQIHBoYXNlIDFgPXN1bShpbl9lZWJvX3RjcF9waGFzZV8xKS9uKCksYEVFQk8tVENQIHBoYXNlIDJgPXN1bShpbl9lZWJvX3RjcF9waGFzZV8yKS9uKCksLmdyb3Vwcz0iZHJvcCIpICU+JQogIG11dGF0ZShlZWJvX3Rsc19sYW5ndWFnZT1mY3RfcmVvcmRlcihzdHJfYyhlZWJvX3Rsc19sYW5ndWFnZSwnICgnLG4sJyknKSxuKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGBFRUJPLVRDUCBwaGFzZSAxYDpgRUVCTy1UQ1AgcGhhc2UgMmAsbmFtZXNfdG89InBhcnQiLCB2YWx1ZXNfdG8gPSAicHJvcCIpICU+JQogIGdncGxvdChhZXMoeD1lZWJvX3Rsc19sYW5ndWFnZSx5PXByb3AsZmlsbD1wYXJ0KSkgKyAKICBnZW9tX2NvbChwb3NpdGlvbj0nc3RhY2snKSArIAogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTEpKSArCiAgeGxhYigiTGFuZ3VhZ2UiKSArCiAgeWxhYigiQ292ZXJhZ2UgYnkgd29yayBhcyBjb21wYXJlZCB0byBFRUJPIikgKwogIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygxLCAwKSwgbGVnZW5kLmJveC5qdXN0ID0gImJvdHRvbSIsIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC45OCwgMC4wMiksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKSArCiAgbGFicyhmaWxsPU5VTEwpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKV2Vsc2ggYW5kIFNjb3R0aXNoIGFyZSB2ZXJ5IHdlbGwgY292ZXJlZC4gT2YgdGhlIG1ham9yIGxhbmd1YWdlcywgTGF0aW4gaW4gcGFydGljdWxhciBpcyB2ZXJ5IHBvb3JseSBjb3ZlcmVkIG92ZXJhbGwsIGFuZCBwYXJ0aWN1bGFybHkgaW4gcGhhc2UgMiAod2hpY2ggd2UgYWxyZWFkeSBrbmV3IGZyb20gdGhlIGJhY2tncm91bmQgaW5mbyBhdCBodHRwczovL3RleHRjcmVhdGlvbnBhcnRuZXJzaGlwLm9yZy90Y3AtdGV4dHMvZWViby10Y3AtZWFybHktZW5nbGlzaC1ib29rcy1vbmxpbmUvKS4gRnJlbmNoIGZhcmVzIGEgYml0IGJldHRlciwgYnV0IG5vdCB0b28gZ3JlYXQuCgojIyBFRUJPLVRDUCBwaGFzZSBsYW5ndWFnZSBjb21wb3NpdGlvbiBjb21wYXJpc29uIChhZ2FpbnN0IEVFQk8sIEVuZ2xpc2ggZXhjbHVkZWQpCgojIyMgVE9ETzogVG8gcmVtb3ZlPyBEb2VzIHRoaXMgYWRkIGFueSBpbmZvcm1hdGlvbj8gV2l0aGluLWRhdGFzZXQgcHJvcG9ydGlvbnMgYXJlIHVuaW50dWl0aXZlIHRvIGNvbXBhcmUgYmV0d2VlbiBkYXRhc2V0cy4KCmBgYHtyLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NH0KbGlicmFyeShnZ2JyZWFrKQplZWJvX2NvcmUgJT4lIAogIGxlZnRfam9pbihlZWJvX3RjcF9jb3JlICU+JSBkaXN0aW5jdChlZWJvX2lkLGVlYm9fdGNwX3BoYXNlKSxieT1jKCJlZWJvX2lkIikpICU+JQogIHJlcGxhY2VfbmEobGlzdChlZWJvX3RjcF9waGFzZT0iSW4gRUVCTyBidXQgbm90IGluIEVFQk8tVENQIikpICU+JQogIG11dGF0ZShsYW5ndWFnZT1mY3RfbHVtcF9uKGVlYm9fdGxzX2xhbmd1YWdlLDcpKSAlPiUKICBjb3VudChlZWJvX3RjcF9waGFzZSxsYW5ndWFnZSkgJT4lCiAgZ3JvdXBfYnkoZWVib190Y3BfcGhhc2UpICU+JQogIG11dGF0ZShwcm9wPW4vc3VtKG4pKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgZmlsdGVyKGxhbmd1YWdlIT0iRW5nbGlzaCIpICU+JQogIGdncGxvdChhZXMoeD1sYW5ndWFnZSxmaWxsPWVlYm9fdGNwX3BoYXNlLHk9cHJvcCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLDEsYnk9MC4wMDUpLGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTAuMSkpICsKICBzY2FsZV95X2JyZWFrKGMoMC4wMTgsMC4xMCkpICsKICB5bGFiKCJQZXJjZW50YWdlIikgKwogIHhsYWIoIkxhbmd1YWdlIikgKwogIGdlb21fY29sKHBvc2l0aW9uPSdkb2RnZScpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKwogIGxhYnMoZmlsbD1OVUxMKQpgYGAKCiMjIEVFQk8tVENQIHBoYXNlIGVkaXRpb24gdHlwZSBjb21wb3NpdGlvbiBjb21wYXJpc29uCgojIyMgVE9ETzogVG8gcmVtb3ZlPyBUaGlzIGRvZXNuJ3Qgc2VlbSB0byBhZGQgYW55IGluZm9ybWF0aW9uIHRvIHRoZSAiQ292ZXJhZ2Ugb2YgZGlmZmVyZW50IHB1YmxpY2F0aW9uIHR5cGVzIiBncmFwaHMgYW5kIHdpdGhpbi1kYXRhc2V0IHByb3BvcnRpb25zIGFyZSB1bmludHVpdGl2ZSB0byBjb21wYXJlIGJldHdlZW4gZGF0YXNldHMuCgpgYGB7cn0KYmluZF9yb3dzKAogIGRmICU+JSBmaWx0ZXIoZWRpdGlvbl90eXBlPT0iU2luZ3VsYXIiKSAlPiUgc2VsZWN0KHdvcmtfaWQscHVibGljYXRpb25feWVhcixlZGl0aW9uX3R5cGUpLAogIGRmICU+JSAKICAgIGZpbHRlcihlZGl0aW9uX3R5cGUhPSJTaW5ndWxhciIpICU+JSAKICAgIGdyb3VwX2J5KHdvcmtfaWQsdHlwZSxmaXJzdF9wdWJsaWNhdGlvbl95ZWFyLHB1YmxpY2F0aW9uX3llYXIpICU+JQogICAgbXV0YXRlKGVkaXRpb25fdHlwZT1pZl9lbHNlKHB1YmxpY2F0aW9uX3llYXI9PWZpcnN0X3B1YmxpY2F0aW9uX3llYXIsIkZpcnN0IHllYXIgd29yayIsIkxhdGVyIHdvcmsiKSkgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBkaXN0aW5jdCh3b3JrX2lkLHB1YmxpY2F0aW9uX3llYXIsZWRpdGlvbl90eXBlKQopICU+JQogIG11dGF0ZShlZGl0aW9uX3R5cGU9ZmN0X3JlbGV2ZWwoZWRpdGlvbl90eXBlLCJTaW5ndWxhciIsIkZpcnN0IHllYXIgd29yayIsIkxhdGVyIHdvcmsiKSkgJT4lCiAgaW5uZXJfam9pbihlc3RjX2NvcmUgJT4lIHNlbGVjdChlc3RjX2lkLHdvcmtfaWQpLGJ5PWMoIndvcmtfaWQiKSkgJT4lCiAgaW5uZXJfam9pbihlZWJvX2NvcmUsYnk9YygiZXN0Y19pZCIpKSAlPiUKICBsZWZ0X2pvaW4oZWVib190Y3BfY29yZSAlPiUgZGlzdGluY3QoZWVib19pZCxlZWJvX3RjcF9waGFzZSksYnk9YygiZWVib19pZCIpKSAlPiUKICByZXBsYWNlX25hKGxpc3QoZWVib190Y3BfcGhhc2U9IkluIEVFQk8gYnV0IG5vdCBpbiBFRUJPLVRDUCIpKSAlPiUKICBjb3VudChlZGl0aW9uX3R5cGUsZWVib190Y3BfcGhhc2UpICU+JSAKICBncm91cF9ieShlZWJvX3RjcF9waGFzZSkgJT4lCiAgbXV0YXRlKHByb3A9bi9zdW0obikpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBnZ3Bsb3QoYWVzKHg9ZWRpdGlvbl90eXBlLGZpbGw9ZWVib190Y3BfcGhhc2UseT1wcm9wKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3M9c2VxKDAsMSxieT0wLjEpLGxhYmVscz1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5PTEpKSArCiAgeWxhYigiUGVyY2VudGFnZSIpICsKICB4bGFiKCJFZGl0aW9uIHR5cGUiKSArCiAgZ2VvbV9jb2wocG9zaXRpb249J2RvZGdlJykgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKSArCiAgbGFicyhmaWxsPU5VTEwpICAKYGBgCgojIyBHZW5yZSBjb3ZlcmFnZSB0aHJvdWdoIHRpbWUgKEVFQk8tVENQIGFnYWluc3QgRUVCTykKCmBgYHtyLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9OH0KZWVib19jb3JlICU+JSAKICBpbm5lcl9qb2luKGRmLGJ5PWMoImVzdGNfaWQiKSkgJT4lCiAgZmlsdGVyKGZpcnN0X3B1YmxpY2F0aW9uX3llYXI+MTQ3NCkgJT4lCiAgZ3JvdXBfYnkod29ya19pZCxmaXJzdF9wdWJsaWNhdGlvbl95ZWFyKSAlPiUKICBzdW1tYXJpemUoaW5fZWVibz1hbnkoaW5fZWVibyksaW5fZWVib190Y3BfcGhhc2VfMT1hbnkoaW5fZWVib190Y3BfcGhhc2VfMSksaW5fZWVib190Y3A9YW55KGluX2VlYm9fdGNwKSxjZXJ0YWluPWFueShmaXJzdF95ZWFyX3B1YmxpY2F0aW9uICYgY2VydGFpbiksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGZpbHRlcihjZXJ0YWluKSAlPiUgCiAgbGVmdF9qb2luKGVlYm9fdXN0Y19nZW5yZXMgJT4lIAogICAgICAgICAgICAgIGlubmVyX2pvaW4oZWVib19jb3JlLGJ5PWMoImVlYm9faWQiKSkgJT4lCiAgICAgICAgICAgICAgaW5uZXJfam9pbihlc3RjX2NvcmUsYnk9YygiZXN0Y19pZCIpKSAlPiUKICAgICAgICAgICAgICBkaXN0aW5jdCh3b3JrX2lkLHVzdGNfZ2VucmUpICU+JQogICAgICAgICAgICAgIG11dGF0ZSh1c3RjX2dlbnJlPWZjdF9sdW1wX24odXN0Y19nZW5yZSwxMCkpLAogICAgICAgICAgICBieT1jKCJ3b3JrX2lkIikKICAgICAgICAgICAgKSAlPiUKICBtdXRhdGUodXN0Y19nZW5yZT1mY3RfZXhwbGljaXRfbmEodXN0Y19nZW5yZSwiVW5rbm93biIpKSAlPiUKICBncm91cF9ieShmaXJzdF9wdWJsaWNhdGlvbl95ZWFyLCB1c3RjX2dlbnJlKSAlPiUgCiAgc3VtbWFyaXplKGVlYm9fdGNwX249c3VtKGluX2VlYm9fdGNwKSxlZWJvX3RjcF9wcm9wPXN1bShpbl9lZWJvX3RjcCkvbigpLGVlYm9fdGNwX3BoYXNlXzFfbj1zdW0oaW5fZWVib190Y3BfcGhhc2VfMSksZWVib190Y3BfcGhhc2VfMV9wcm9wPXN1bShpbl9lZWJvX3RjcF9waGFzZV8xKS9uKCksdG49bigpLC5ncm91cHM9ImRyb3AiKSAlPiUKICBwaXZvdF9sb25nZXIoZWVib190Y3BfbjplZWJvX3RjcF9waGFzZV8xX3Byb3AsbmFtZXNfdG89YygicGFydCIsIi52YWx1ZSIpLG5hbWVzX3BhdHRlcm49IiguKilfKC4qKSIpICU+JQogIG11dGF0ZShwYXJ0PWlmX2Vsc2UocGFydD09ImVlYm9fdGNwX3BoYXNlXzEiLCJFRUJPLVRDUCBwaGFzZSAxIiwiRUVCTy1UQ1AiKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmlyc3RfcHVibGljYXRpb25feWVhciwgeSA9IHByb3AsIGNvbG9yID0gcGFydCkpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImdyYXkiLCBzaGFwZSA9IDIxLCBhZXMoc2l6ZSA9IHRuKSkgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBuKSkgKwogIGdlb21fc21vb3RoKGFlcyh3ZWlnaHQgPSB0biwgZmlsbCA9IHBhcnQpLCBzcGFuID0gMC4zLCBtZXRob2Q9J2xvZXNzJyxmb3JtdWxhPXl+eCkgKwogIHRoZW1lX2hzY2lfZGlzY3JldGUoKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgxMDAwLCAyMDAwLCBieSA9IDQwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMSksIGJyZWFrcyA9IHNlcSgwLCAxLCBieSA9IDAuMTApKSArCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJFRUJPLVRDUCBjb3ZlcmFnZSIpICsKICB0aGVtZShsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMCksIGxlZ2VuZC5ib3guanVzdCA9ICJib3R0b20iLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDUsIDAuMDIpLCBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmtleSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGxhYnMoY29sb3IgPSBOVUxMLCBzaXplID0gTlVMTCwgc2hhcGUgPSBOVUxMLCBmaWxsID0gTlVMTCkgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoMCwxKSkgKwogIHNjYWxlX3NpemUoYnJlYWtzID0gYygxMDAsIDUwMCwgMTAwMCksIHJhbmdlID0gYygwLjEsIDguMCkpICsKICBndWlkZXMoZmlsbD0ibm9uZSIpICsKICBmYWNldF93cmFwKH51c3RjX2dlbnJlLG5jb2w9MykKYGBgCgpJbiBtYW55IG1ham9yIGdlbnJlIGNhdGVnb3JpZXMgc3VjaCBhcyByZWxpZ2lvdXMsIGxpdGVyYXR1cmUgYW5kIGhpc3RvcnkgYW5kIGNocm9uaWNsZXMsIHBoYXNlIDEgb2YgRUVCTy1UQ1Agc2hvd3MgYSBjbGVhcmx5IGRpbWluaXNoaW5nIGNvdmVyYWdlIHRvd2FyZCB0aGUgZW5kIG9mIHRoZSBjZW50dXJ5LiBIb3dldmVyLCB3aGVuIHBoYXNlIDIgaXMgYWRkZWQgdG8gdGhlIGRhdGEsIGluIGFkZGl0aW9uIHRvIHNpZ25pZmljYW50bHkgaW1wcm92aW5nIGNvdmVyYWdlIG92ZXJhbGwsIHRoaXMgYmlhcyBkaXNhcHBlYXJzLgoKIyBUb3BpY2FsIGNvdmVyYWdlIG9mIEVFQk8gdnMgRVNUQyB0aHJvdWdoIHRpbWUKCkhlcmUsIHdlIGFyZSBwcm9qZWN0aW5nIHN1YmplY3QgY2F0ZWdvcnkgaW5mb3JtYXRpb24gZnJvbSBFRUJPL0VDQ08gdGhyb3VnaG91dCB0aGUgd2hvbGUgb2YgdGhlIEVTVEMgaW4gb3JkZXIgdG8gY29tcGFyZSB0aGVpciBjb3ZlcmFnZS4gRm9yIHRoZSAxOHRoIGNlbnR1cnkgYW5kIEVDQ08sIHRoaXMgc2VlbWVkIHRvIHdvcmsgcmVsYXRpdmVseSB3ZWxsIGZvciBhbGwgdGhlIDggY2F0ZWdvcmllcy4gRm9yIFVTVEMvRUVCTywgSSB3YXMgY29tZm9ydGFibGUgaW5jbHVkaW5nIG9ubHkgdGhlIHJlbGlnaW91cy9oaXN0b3J5IGFuZCBjaHJvbmljbGVzIGFuZCBlY29ub21pY3MgLWNhdGVnb3JpZXMuCgojIyBVc2luZyBwcm9qZWN0ZWQgRUNDTyBtb2R1bGVzCgpgYGB7cixpbmNsdWRlPUZ9CnBhazo6cGtnX2luc3RhbGwoIkNPTUhJUy9lY2NvciIpCmxpYnJhcnkoZWNjb3IpCmVjY29fY29yZSA8LSBsb2FkX2VjY29fY29yZSgpCmNvbWJpbmVkX3Byb2plY3RlZF9lY2NvX21vZHVsZXMgPC0gZWNjb19jb3JlICU+JSAKICBpbm5lcl9qb2luKGVzdGNfY29yZSxieT1jKCJlc3RjX2lkIikpICU+JQogIGRpc3RpbmN0KHdvcmtfaWQscHJvamVjdGVkX2VjY29fbW9kdWxlPWVjY29fbW9kdWxlKQoKY29tYmluZWRfcHJvamVjdGVkX2VjY29fbW9kdWxlcyA8LSBjb21iaW5lZF9wcm9qZWN0ZWRfZWNjb19tb2R1bGVzICU+JQogIGJpbmRfcm93cyhlc3RjX3Byb2plY3RlZF9lY2NvX21vZHVsZXMgJT4lIAogICAgZmlsdGVyKG1heF9wcm9wPj0wLjcpICU+JQogICAgICBzZWxlY3QoLW1heF9wcm9wKSAlPiUKICAgICAgYW50aV9qb2luKGNvbWJpbmVkX3Byb2plY3RlZF9lY2NvX21vZHVsZXMsYnk9Yygid29ya19pZCIpKSkKYGBgCgpgYGB7cixmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTh9CmRmICU+JSAKICBmaWx0ZXIoZmlyc3RfcHVibGljYXRpb25feWVhcj4xNDc0KSAlPiUKICBncm91cF9ieSh3b3JrX2lkLGZpcnN0X3B1YmxpY2F0aW9uX3llYXIpICU+JQogIHN1bW1hcml6ZShpbl9lZWJvPWFueShpbl9lZWJvKSxpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGNlcnRhaW49YW55KGZpcnN0X3llYXJfcHVibGljYXRpb24gJiBjZXJ0YWluKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgZmlsdGVyKGNlcnRhaW4pICU+JSAKICBsZWZ0X2pvaW4oY29tYmluZWRfcHJvamVjdGVkX2VjY29fbW9kdWxlcyxieT1jKCJ3b3JrX2lkIikpICU+JQogIHJlcGxhY2VfbmEobGlzdChwcm9qZWN0ZWRfZWNjb19tb2R1bGU9Ik90aGVyL1Vua25vd24iKSkgJT4lCiAgbXV0YXRlKHByb2plY3RlZF9lY2NvX21vZHVsZT1mY3RfcmVsZXZlbChwcm9qZWN0ZWRfZWNjb19tb2R1bGUsIk90aGVyL1Vua25vd24iKSkgJT4lCiAgZ3JvdXBfYnkoZmlyc3RfcHVibGljYXRpb25feWVhciwgcHJvamVjdGVkX2VjY29fbW9kdWxlLCBpbl9lZWJvKSAlPiUgCiAgdGFsbHkoKSAlPiUgCiAgbXV0YXRlKHByb3AgPSBuIC8gc3VtKG4pLCB0biA9IHN1bShuKSkgJT4lIAogIGZpbHRlcihpbl9lZWJvKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmaXJzdF9wdWJsaWNhdGlvbl95ZWFyLCB5ID0gcHJvcCwgY29sb3IgPSBwcm9qZWN0ZWRfZWNjb19tb2R1bGUpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJncmF5Iiwgc2hhcGUgPSAyMSwgYWVzKHNpemUgPSB0bikpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gbikpICsKICBnZW9tX3Ntb290aChhZXMod2VpZ2h0ID0gbiwgZmlsbCA9IHByb2plY3RlZF9lY2NvX21vZHVsZSksIHNwYW4gPSAwLjMsIG1ldGhvZD0nbG9lc3MnLGZvcm11bGE9eX54KSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwMDAsIDIwMDAsIGJ5ID0gNDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4xMCkpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkVFQk8gY292ZXJhZ2UiKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDApLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjA1LCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGNvbG9yID0gTlVMTCwgc2l6ZSA9IE5VTEwsIHNoYXBlID0gTlVMTCwgZmlsbCA9IE5VTEwpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAuNSwxKSkgKyAgCiAgc2NhbGVfc2l6ZShicmVha3MgPSBjKDEwMCwgNTAwLCAxMDAwKSwgcmFuZ2UgPSBjKDAuMSwgOC4wKSkgKyAKICBndWlkZXMoY29sb3I9Im5vbmUiLGZpbGw9Im5vbmUiKSArCiAgZmFjZXRfd3JhcCh+cHJvamVjdGVkX2VjY29fbW9kdWxlLG5jb2w9MykKYGBgCgojIyBVc2luZyBwcm9qZWN0ZWQgVVNUQyBSZWxpZ2lvdXMvSGlzdG9yeSBhbmQgY2hyb25pY2xlcy9FY29ub21pY3MKCmBgYHtyLGluY2x1ZGU9Rn0KY29tYmluZWRfcHJvamVjdGVkX3VzdGNfZ2VucmVzIDwtIGVlYm9fdXN0Y19nZW5yZXMgJT4lCiAgaW5uZXJfam9pbihlZWJvX2NvcmUsYnk9YygiZWVib19pZCIpKSAlPiUKICBpbm5lcl9qb2luKGVzdGNfY29yZSxieT1jKCJlc3RjX2lkIikpICU+JQogIGRpc3RpbmN0KHdvcmtfaWQscHJvamVjdGVkX3VzdGNfZ2VucmU9dXN0Y19nZW5yZSkKCmNvbWJpbmVkX3Byb2plY3RlZF91c3RjX2dlbnJlcyA8LSBjb21iaW5lZF9wcm9qZWN0ZWRfdXN0Y19nZW5yZXMgJT4lCiAgYmluZF9yb3dzKGVzdGNfcHJvamVjdGVkX3VzdGNfZ2VucmVzICU+JSAKICAgIGZpbHRlcihtYXhfcHJvcD49MC43KSAlPiUKICAgICAgc2VsZWN0KC1tYXhfcHJvcCkgJT4lCiAgICAgIGFudGlfam9pbihjb21iaW5lZF9wcm9qZWN0ZWRfdXN0Y19nZW5yZXMsYnk9Yygid29ya19pZCIpKSkKYGBgCgpgYGB7cixmaWcud2lkdGg9NixmaWcuaGVpZ2h0PTN9CmRmICU+JSAKICBmaWx0ZXIoZmlyc3RfcHVibGljYXRpb25feWVhcj4xNDc0KSAlPiUKICBncm91cF9ieSh3b3JrX2lkLGZpcnN0X3B1YmxpY2F0aW9uX3llYXIpICU+JQogIHN1bW1hcml6ZShpbl9lZWJvPWFueShpbl9lZWJvKSxpbl9lZWJvX3RjcD1hbnkoaW5fZWVib190Y3ApLGNlcnRhaW49YW55KGZpcnN0X3llYXJfcHVibGljYXRpb24gJiBjZXJ0YWluKSwuZ3JvdXBzPSJkcm9wIikgJT4lCiAgZmlsdGVyKGNlcnRhaW4pICU+JSAKICBsZWZ0X2pvaW4oZXN0Y19wcm9qZWN0ZWRfdXN0Y19nZW5yZXMgJT4lIAogIGZpbHRlcihtYXhfcHJvcD49MC43LHByb2plY3RlZF91c3RjX2dlbnJlICVpbiUgYygiUmVsaWdpb3VzIiwiSGlzdG9yeSBhbmQgY2hyb25pY2xlcyIsIkVjb25vbWljcyIpKSxieT1jKCJ3b3JrX2lkIikpICU+JQogIHJlcGxhY2VfbmEobGlzdChwcm9qZWN0ZWRfdXN0Y19nZW5yZT0iT3RoZXIvVW5rbm93biIpKSAlPiUKICBtdXRhdGUocHJvamVjdGVkX3VzdGNfZ2VucmU9ZmN0X3JlbGV2ZWwocHJvamVjdGVkX3VzdGNfZ2VucmUsIk90aGVyL1Vua25vd24iKSkgJT4lCiAgZ3JvdXBfYnkoZmlyc3RfcHVibGljYXRpb25feWVhciwgcHJvamVjdGVkX3VzdGNfZ2VucmUsIGluX2VlYm8pICU+JSAKICB0YWxseSgpICU+JSAKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obiksIHRuID0gc3VtKG4pKSAlPiUgCiAgZmlsdGVyKGluX2VlYm8pICU+JQogIGdncGxvdChhZXMoeCA9IGZpcnN0X3B1YmxpY2F0aW9uX3llYXIsIHkgPSBwcm9wLCBjb2xvciA9IHByb2plY3RlZF91c3RjX2dlbnJlKSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAiZ3JheSIsIHNoYXBlID0gMjEsIGFlcyhzaXplID0gdG4pKSArCiAgZ2VvbV9wb2ludChhZXMoc2l6ZSA9IG4pKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHdlaWdodCA9IG4sIGZpbGwgPSBwcm9qZWN0ZWRfdXN0Y19nZW5yZSksIHNwYW4gPSAwLjMsIG1ldGhvZD0nbG9lc3MnLGZvcm11bGE9eX54KSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwMDAsIDIwMDAsIGJ5ID0gMjApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4xMCkpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkVFQk8gY292ZXJhZ2UiKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDApLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjA1LCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGNvbG9yID0gTlVMTCwgc2l6ZSA9IE5VTEwsIHNoYXBlID0gTlVMTCwgZmlsbCA9IE5VTEwpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsMSkpICsKICBzY2FsZV9zaXplKGJyZWFrcyA9IGMoMTAwLCA1MDAsIDEwMDApLCByYW5nZSA9IGMoMC4xLCA4LjApKQpgYGAKCiMgVG9waWNhbCBjb3ZlcmFnZSBvZiBFRUJPLVRDUCB2cyBFU1RDIHRocm91Z2ggdGltZQoKIyMgVXNpbmcgcHJvamVjdGVkIEVDQ08gbW9kdWxlcwoKYGBge3IsZmlnLndpZHRoPTcsZmlnLmhlaWdodD04fQpkZiAlPiUgCiAgZmlsdGVyKGZpcnN0X3B1YmxpY2F0aW9uX3llYXI+MTQ3NCkgJT4lCiAgZ3JvdXBfYnkod29ya19pZCxmaXJzdF9wdWJsaWNhdGlvbl95ZWFyKSAlPiUKICBzdW1tYXJpemUoaW5fZWVibz1hbnkoaW5fZWVibyksaW5fZWVib190Y3A9YW55KGluX2VlYm9fdGNwKSxjZXJ0YWluPWFueShmaXJzdF95ZWFyX3B1YmxpY2F0aW9uICYgY2VydGFpbiksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGZpbHRlcihjZXJ0YWluKSAlPiUgCiAgbGVmdF9qb2luKGNvbWJpbmVkX3Byb2plY3RlZF9lY2NvX21vZHVsZXMsYnk9Yygid29ya19pZCIpKSAlPiUKICByZXBsYWNlX25hKGxpc3QocHJvamVjdGVkX2VjY29fbW9kdWxlPSJPdGhlci9Vbmtub3duIikpICU+JQogIG11dGF0ZShwcm9qZWN0ZWRfZWNjb19tb2R1bGU9ZmN0X3JlbGV2ZWwocHJvamVjdGVkX2VjY29fbW9kdWxlLCJPdGhlci9Vbmtub3duIikpICU+JQogIGdyb3VwX2J5KGZpcnN0X3B1YmxpY2F0aW9uX3llYXIsIHByb2plY3RlZF9lY2NvX21vZHVsZSwgaW5fZWVib190Y3ApICU+JSAKICB0YWxseSgpICU+JSAKICBtdXRhdGUocHJvcCA9IG4gLyBzdW0obiksIHRuID0gc3VtKG4pKSAlPiUgCiAgZmlsdGVyKGluX2VlYm9fdGNwKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBmaXJzdF9wdWJsaWNhdGlvbl95ZWFyLCB5ID0gcHJvcCwgY29sb3IgPSBwcm9qZWN0ZWRfZWNjb19tb2R1bGUpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJncmF5Iiwgc2hhcGUgPSAyMSwgYWVzKHNpemUgPSB0bikpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gbikpICsKICBnZW9tX3Ntb290aChhZXMod2VpZ2h0ID0gbiwgZmlsbCA9IHByb2plY3RlZF9lY2NvX21vZHVsZSksIHNwYW4gPSAwLjMsIG1ldGhvZD0nbG9lc3MnLGZvcm11bGE9eX54KSArCiAgdGhlbWVfaHNjaV9kaXNjcmV0ZSgpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDEwMDAsIDIwMDAsIGJ5ID0gNDApKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxKSwgYnJlYWtzID0gc2VxKDAsIDEsIGJ5ID0gMC4xMCkpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkVFQk8tVENQIGNvdmVyYWdlIikgKwogIHRoZW1lKGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAwKSwgbGVnZW5kLmJveC5qdXN0ID0gImJvdHRvbSIsIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4wNSwgMC4wMiksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQua2V5ID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQuYm94ID0gImhvcml6b250YWwiKSArCiAgbGFicyhjb2xvciA9IE5VTEwsIHNpemUgPSBOVUxMLCBzaGFwZSA9IE5VTEwsIGZpbGwgPSBOVUxMKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW09YygwLDEpKSArCiAgc2NhbGVfc2l6ZShicmVha3MgPSBjKDEwMCwgNTAwLCAxMDAwKSwgcmFuZ2UgPSBjKDAuMSwgOC4wKSkgKwogIGd1aWRlcyhjb2xvcj0ibm9uZSIsZmlsbD0ibm9uZSIpICsKICBmYWNldF93cmFwKH5wcm9qZWN0ZWRfZWNjb19tb2R1bGUsbmNvbD0zKQpgYGAKCiMjIFVzaW5nIHByb2plY3RlZCBVU1RDIFJlbGlnaW91cy9IaXN0b3J5IGFuZCBjaHJvbmljbGVzL0Vjb25vbWljcwoKYGBge3IsZmlnLndpZHRoPTYsZmlnLmhlaWdodD0zfQpkZiAlPiUgCiAgZmlsdGVyKGZpcnN0X3B1YmxpY2F0aW9uX3llYXI+MTQ3NCkgJT4lCiAgZ3JvdXBfYnkod29ya19pZCxmaXJzdF9wdWJsaWNhdGlvbl95ZWFyKSAlPiUKICBzdW1tYXJpemUoaW5fZWVibz1hbnkoaW5fZWVibyksaW5fZWVib190Y3A9YW55KGluX2VlYm9fdGNwKSxjZXJ0YWluPWFueShmaXJzdF95ZWFyX3B1YmxpY2F0aW9uICYgY2VydGFpbiksLmdyb3Vwcz0iZHJvcCIpICU+JQogIGZpbHRlcihjZXJ0YWluKSAlPiUgCiAgbGVmdF9qb2luKGNvbWJpbmVkX3Byb2plY3RlZF91c3RjX2dlbnJlcyAlPiUgCiAgZmlsdGVyKHByb2plY3RlZF91c3RjX2dlbnJlICVpbiUgYygiUmVsaWdpb3VzIiwiSGlzdG9yeSBhbmQgY2hyb25pY2xlcyIsIkVjb25vbWljcyIpKSxieT1jKCJ3b3JrX2lkIikpICU+JQogIHJlcGxhY2VfbmEobGlzdChwcm9qZWN0ZWRfdXN0Y19nZW5yZT0iT3RoZXIvVW5rbm93biIpKSAlPiUKICBtdXRhdGUocHJvamVjdGVkX3VzdGNfZ2VucmU9ZmN0X3JlbGV2ZWwocHJvamVjdGVkX3VzdGNfZ2VucmUsIk90aGVyL1Vua25vd24iKSkgJT4lCiAgZ3JvdXBfYnkoZmlyc3RfcHVibGljYXRpb25feWVhciwgcHJvamVjdGVkX3VzdGNfZ2VucmUsIGluX2VlYm9fdGNwKSAlPiUgCiAgdGFsbHkoKSAlPiUgCiAgbXV0YXRlKHByb3AgPSBuIC8gc3VtKG4pLCB0biA9IHN1bShuKSkgJT4lIAogIGZpbHRlcihpbl9lZWJvX3RjcCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZmlyc3RfcHVibGljYXRpb25feWVhciwgeSA9IHByb3AsIGNvbG9yID0gcHJvamVjdGVkX3VzdGNfZ2VucmUpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJncmF5Iiwgc2hhcGUgPSAyMSwgYWVzKHNpemUgPSB0bikpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gbikpICsKICBnZW9tX3Ntb290aChhZXMod2VpZ2h0ID0gbiwgZmlsbCA9IHByb2plY3RlZF91c3RjX2dlbnJlKSwgc3BhbiA9IDAuMywgbWV0aG9kPSdsb2VzcycsZm9ybXVsYT15fngpICsKICB0aGVtZV9oc2NpX2Rpc2NyZXRlKCkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMTAwMCwgMjAwMCwgYnkgPSAyMCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDEpLCBicmVha3MgPSBzZXEoMCwgMSwgYnkgPSAwLjEwKSkgKwogIHhsYWIoIlllYXIiKSArCiAgeWxhYigiRUVCTy1UQ1AgY292ZXJhZ2UiKSArCiAgdGhlbWUobGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDApLCBsZWdlbmQuYm94Lmp1c3QgPSAiYm90dG9tIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjA1LCAwLjAyKSwgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBsYWJzKGNvbG9yID0gTlVMTCwgc2l6ZSA9IE5VTEwsIHNoYXBlID0gTlVMTCwgZmlsbCA9IE5VTEwpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsMSkpICsKICBzY2FsZV9zaXplKGJyZWFrcyA9IGMoMTAwLCA1MDAsIDEwMDApLCByYW5nZSA9IGMoMC4xLCA4LjApKQpgYGAKKGNvbXBhcmUgdGhpcyB3aXRoIHRoZSByYXcgRUVCTy1UQ1AgdnMgRUVCTyBjb3ZlcmFnZSBhcyB3ZWxsIGFzIHRoZSBFQ0NPIG1vZHVsZSBjb3ZlcmFnZSBncmFwaHMp