# 0) Packages
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(broom)
library(stringr)
library(forcats)
# 1) File path
excel_path <- "UNO Survey Responses v4.xlsx"
# Soft Likert color palette (academic & clean)
likert_colors <- c(
"1" = "#E8E8E8",
"2" = "#CFE1F2",
"3" = "#A6C8E0",
"4" = "#6FAED9",
"5" = "#3C8DC5"
)
likert7_colors <- c(
"1" = "#F0F0F0",
"2" = "#D9E6F2",
"3" = "#BFD7EA",
"4" = "#9EC5DF",
"5" = "#6FAED9",
"6" = "#4A97CF",
"7" = "#2C7FB8"
)
eval_colors <- c(
"Very Bad" = "#E6E6E6",
"Bad" = "#D1E5F0",
"Same" = "#BDBDBD",
"Good" = "#92C5DE",
"Very Good" = "#4393C3"
)
. Project Background
(MDP / MRP / Research Questions)
Management Decision
Problem (MDP)
UNO aims to increase its market share in Türkiye and must decide
between two growth paths:
-
Market penetration: Strengthening traditional packaged
breads.
-
Product development: Launching an international/premium
bread line (e.g., brioche).
Marketing Research
Problem (MRP)
This research aims to identify which strategic direction—market
penetration or product development—better aligns with consumer behavior,
brand perception, and current market dynamics in Türkiye.
Research Questions
& Hypotheses
We focus on consumer behavior, unmet needs, trial intent, segment
differences, and UNO brand equity fit. Key hypotheses include: - H1
(Penetration): Purchase frequency can increase if UNO improves
freshness, pricing, and availability. - H2 (Product Development):
Consumers perceive packaged breads as similar; differentiated products
(brioche) may satisfy novelty needs. - H3 (Product Development):
Younger/urban consumers have higher adoption potential for
international-style breads. - H4 (Brand Equity): UNO is strongly linked
to traditional breads, but can extend to premium through branding and
packaging.
. Research Design &
Data Sources
We use a mixed-method design: exploratory (focus group + expert
interview) followed by a descriptive online survey and a conjoint-style
rating experiment.
Qualitative
Insights
Focus group insights highlight: - concerns about additives/shelf
life, - packaging smell/material issues, - emotional connection to
traditional white bread, - brioche as taste/experience (not daily health
choice), - trial triggers: tasting, novelty, social media virality, “not
found in bakeries”.
Expert (dietitian) interview highlights: - consumers struggle to find
“clean-label + fresh” bread, - brioche is an indulgence (weekend
breakfasts, guests/snacking), - core trial triggers: ingredient quality
and taste, - UNO is perceived as a reliable everyday brand (more
traditional).
. Data Import (Survey
Summaries + Conjoint)
Helper function to
read “Option / Count” sheets safely
read_summary_sheet <- function(path, sheet_name) {
raw <- read_excel(path, sheet = sheet_name, col_names = FALSE)
# find first row that looks like a header (contains "Count")
header_row <- which(apply(raw, 1, function(x) any(str_detect(as.character(x), "^Count$"))))[1]
# if not found, assume first row is header
if (is.na(header_row)) header_row <- 1
df <- raw[(header_row):nrow(raw), ]
colnames(df) <- as.character(df[1, ])
df <- df[-1, ] %>% as.data.frame()
# convert Count to numeric if present
if ("Count" %in% names(df)) {
df$Count <- as.numeric(df$Count)
}
df
}
Read sheets
# Demographics (Option/Count)
ageData <- read_summary_sheet(excel_path, "Age")
## New names:
## • `` -> `...1`
## • `` -> `...2`
incomeData <- read_summary_sheet(excel_path, "Income")
## New names:
## • `` -> `...1`
## • `` -> `...2`
genderData <- read_summary_sheet(excel_path, "Gender")
## New names:
## • `` -> `...1`
## • `` -> `...2`
educationData <- read_summary_sheet(excel_path, "Education")
## New names:
## • `` -> `...1`
## • `` -> `...2`
# Category behavior (Option/Count)
usageOccasion <- read_summary_sheet(excel_path, "Bread Usage Occasion")
## New names:
## • `` -> `...1`
## • `` -> `...2`
trialMotives <- read_summary_sheet(excel_path, "Premium_Bread_Trial_Motivation")
## New names:
## • `` -> `...1`
## • `` -> `...2`
purchaseSev <- read_summary_sheet(excel_path, "Purchase Severity")
## New names:
## • `` -> `...1`
## • `` -> `...2`
briochePurch <- read_summary_sheet(excel_path, "Brioche Purchasing")
## New names:
## • `` -> `...1`
## • `` -> `...2`
# UNO questions (grid counts)
uno_q1 <- read_excel(excel_path, sheet = "UNO Question1")
uno_q2 <- read_excel(excel_path, sheet = "UNO Question2")
uno_q3 <- read_excel(excel_path, sheet = "UNO Question3")
# Conjoint (individual-level)
conjoint <- read_excel(excel_path, sheet = "Conjoint_Long")
. Sample Profile
(Demographics)
Age Distribution
ggplot(ageData, aes(x = .data[[names(ageData)[1]]], y = Count)) +
geom_col() +
labs(title = "Age Distribution", x = "Age Range", y = "Number of Respondents") +
theme_minimal()

Profile Summary:
The respondent profile is concentrated in the 25–54 age range with a
female-majority sample. Education levels are primarily Bachelor’s and
Master’s, and a substantial share of respondents fall into higher-income
brackets. Overall, the sample reflects urban, economically active
consumers who are relevant for evaluating premium packaged bread
positioning.
Gender / Education /
Income
plot_count_bar <- function(df, title, xlab) {
ggplot(df, aes(x = .data[[names(df)[1]]], y = Count)) +
geom_col() +
labs(title = title, x = xlab, y = "Number of Respondents") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))
}
plot_count_bar(genderData, "Gender Distribution", "Gender")

plot_count_bar(educationData, "Education Distribution", "Education")

plot_count_bar(incomeData, "Income Distribution", "Income Range")

. Category Behavior
Findings (Option/Count Sheets)
Bread Usage
Occasion
plot_count_bar(usageOccasion, "When Do Consumers Use Packaged Bread?", "Occasion")

- The top occasions indicate whether packaged bread is mainly used for
daily convenience vs special
moments.
- Use this to connect to the focus group’s “daily habits + freshness”
themes. :contentReferenceoaicite:13
Motivation to Try a
New Premium Bread
plot_count_bar(trialMotives, "Top Motivations to Try Premium Packaged Bread", "Motivation")

Interpretation guide: Compare the top motivations
with qualitative triggers (tasting, novelty, social media).
:contentReferenceoaicite:14
## Purchase Severity (how often they buy packaged bread / category intensity)
``` r
purchaseSev <- purchaseSev %>%
mutate(pct = round(100 * Count / sum(Count), 1)) %>%
arrange(desc(Count))
purchaseSev
purchaseSev %>%
mutate(Purchase_Severity = fct_reorder(Purchase_Severity, Count)) %>%
ggplot(aes(x = Purchase_Severity, y = Count)) +
geom_col() +
geom_text(aes(label = paste0(pct, "%")), vjust = -0.3, size = 3) +
labs(
title = "Purchase Severity (Category Engagement)",
x = "Purchase Frequency / Severity",
y = "Number of Respondents"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))

Interpretation:
The purchase severity distribution indicates the overall intensity of
packaged bread consumption in our sample. This is important because it
frames whether demand is driven by daily routines (supporting market
penetration) or whether premium and specialty products would remain
niche (supporting a more targeted product development strategy).
International Bread
Usage Purpose (Brioche/Baguette)
briochePurch <- briochePurch %>%
mutate(pct = round(100 * Count / sum(Count), 1)) %>%
arrange(desc(Count))
briochePurch
briochePurch %>%
mutate(International_Bread_Usage_Purpose =
fct_reorder(International_Bread_Usage_Purpose, Count)) %>%
ggplot(aes(x = International_Bread_Usage_Purpose, y = Count)) +
geom_col() +
geom_text(aes(label = paste0(pct, "%")), vjust = -0.3, size = 3) +
labs(
title = "Why Consumers Eat International Breads (Brioche/Baguette)",
x = "Usage Purpose",
y = "Number of Respondents"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 20, hjust = 1))

Interpretation:
International breads (e.g., brioche/baguette) are consumed mainly for
specific occasions rather than as a daily staple. This aligns with our
qualitative findings that brioche is often seen as an indulgent or
“special moment” product (e.g., weekend breakfasts, guests, snacking),
suggesting that a premium/international line would likely be an
adjacent growth opportunity rather than a replacement for core
daily breads.
. UNO Question 1 —
Brand Perceptions (1–5 scale)
Plot (faceted bar
charts)
q1_item <- names(uno_q1)[1] # first column = statement name (e.g., High_Quality)
uno_q1_long <- uno_q1 %>%
pivot_longer(cols = where(is.numeric),
names_to = "Scale",
values_to = "Count") %>%
mutate(Scale = as.factor(Scale))
ggplot(uno_q1_long, aes(x = Scale, y = Count, fill = Scale)) +
geom_col(width = 0.7) +
facet_wrap(~ UNO_Agreement_Level, scales = "free_y") +
scale_fill_manual(values = likert_colors) +
labs(
title = "UNO Brand Perceptions (1 = Low, 5 = High)",
x = "Agreement Level",
y = "Number of Respondents"
) +
theme_minimal(base_size = 11) +
theme(
legend.position = "bottom",
strip.text = element_text(face = "bold"),
plot.title = element_text(face = "bold")
)

“Top-box” summary
(simple, very useful)
q1_topbox <- uno_q1_long %>%
group_by(.data[[q1_item]]) %>%
summarise(
total = sum(Count, na.rm=TRUE),
topbox_4_5 = sum(Count[Scale %in% c("4","5")], na.rm=TRUE),
topbox_pct = round(100 * topbox_4_5 / total, 1),
.groups = "drop"
) %>%
arrange(desc(topbox_pct))
q1_topbox
UNO Brand Perceptions (Q1) — Key
Insights
-
Strongest association: New Product Success (55.4%)
-
Solid core strengths: Reliable Everyday (45.8%), Value
for Money (42.2%), Healthy Trust (41.0%)
-
Weaker perceptions: Premium Brand (32.5%), Attractive
Packaging (31.3%)
Overall, respondents believe that UNO can successfully develop new
products and perceive it as a reliable everyday brand offering
reasonable value and health-related trust. However, premium brand
perception and packaging attractiveness are relatively weaker. This
suggests that while UNO has the credibility to launch a premium line,
premium cues—particularly packaging design and positioning—must be
strengthened to justify higher pricing.
. UNO Question 2 —
Action Likelihood for Premium Bread (1–7 scale)
q2_item <- names(uno_q2)[1]
uno_q2_long <- uno_q2 %>%
pivot_longer(
cols = where(is.numeric),
names_to = "Scale",
values_to = "Count"
) %>%
mutate(Scale = as.factor(Scale))
ggplot(uno_q2_long, aes(x = Scale, y = Count, fill = Scale)) +
geom_col(width = 0.7) +
facet_wrap(as.formula(paste("~", q2_item)), scales = "free_y") +
scale_fill_manual(values = likert7_colors) +
labs(
title = "Likelihood of Actions if UNO Launches Premium Bread (1 = Low, 7 = High)",
x = "Likelihood Level",
y = "Number of Respondents"
) +
theme_minimal(base_size = 11) +
theme(legend.position = "bottom")

Top-box for 7-point
(6–7)
q2_topbox <- uno_q2_long %>%
group_by(.data[[q2_item]]) %>%
summarise(
total = sum(Count, na.rm=TRUE),
topbox_6_7 = sum(Count[Scale %in% c("6","7")], na.rm=TRUE),
topbox_pct = round(100 * topbox_6_7 / total, 1),
.groups = "drop"
) %>%
arrange(desc(topbox_pct))
q2_topbox
Behavioral intentions (Q2) — funnel
interpretation:
The strongest intention is trying UNO’s premium bread at least once,
indicating high trial potential. In contrast, willingness to pay a
premium price is more moderate and purchase-on-promotion appears
important, suggesting price sensitivity. Following product announcements
online is low, implying that awareness-building may work better through
in-store visibility, packaging, and sampling rather than relying on
consumers actively tracking updates online.
Managerial Interpretation
(Q2)
Trial intention for a premium UNO bread is high, indicating strong
curiosity and openness among consumers. However, willingness to pay a
higher price is more moderate, and buying on promotion appears
important. This suggests that premium adoption will depend on clear
value communication and controlled pricing rather than purely
brand-driven willingness to pay.
. UNO Question 3 —
Comparative UNO Ratings (Very Bad → Very Good)
q3_item <- names(uno_q3)[1] # attribute name column (Taste, Freshness, etc.)
uno_q3_long <- uno_q3 %>%
pivot_longer(cols = -all_of(q3_item),
names_to = "Evaluation",
values_to = "Count") %>%
mutate(Evaluation = factor(Evaluation, levels = c("Very Bad","Bad","Same","Good","Very Good")))
ggplot(uno_q3_long, aes(x = Evaluation, y = Count, fill = Evaluation)) +
geom_col(width = 0.7) +
facet_wrap(~ Comparative_UNO_Ratings, scales = "free_y") +
scale_fill_manual(values = eval_colors) +
labs(
title = "UNO vs Other Bread Brands (Comparative Evaluation)",
x = "Evaluation",
y = "Number of Respondents"
) +
theme_minimal(base_size = 11) +
theme(
legend.position = "bottom",
strip.text = element_text(face = "bold"),
plot.title = element_text(face = "bold")
)

Comparative Evaluation of UNO vs Other Bread Brands
This section evaluates how UNO performs relative to other packaged bread
brands across key attributes such as taste, freshness, price, packaging,
healthiness, availability, innovativeness, and premium feel. Overall,
UNO performs strongly on core functional attributes. Taste and
availability receive a high concentration of “Good” and “Very Good”
ratings, indicating that consumers perceive UNO as competitive or
superior to other brands in everyday consumption contexts. Healthiness
also shows a favorable distribution, supporting earlier qualitative
insights that position UNO as a reliable and trusted option for daily
bread needs. In contrast, attributes related to premium
positioning—particularly premium feel and innovativeness—show a more
mixed distribution, with many respondents selecting “Same” rather than
“Good” or “Very Good.” This suggests that while UNO is not perceived as
weak in these dimensions, it is not yet clearly differentiated as a
premium or highly innovative brand compared to alternatives.
These results reinforce the interpretation that UNO’s current brand
strength lies in functional performance and reliability rather than
symbolic or premium differentiation. Consequently, any premium bread
extension would need to rely on stronger innovation signals, packaging
design, and product storytelling to shift consumer perceptions beyond
parity with existing brands.
. Conjoint Regression
(Individual-Level Model)
# Ensure categorical fields are treated as factors
conjoint <- conjoint %>%
mutate(
Bread_Type = as.factor(Bread_Type),
Slice_Type = as.factor(Slice_Type),
Package_Type = as.factor(Package_Type),
Price = as.factor(Price)
)
rating_model <- lm(Rating ~ Bread_Type + Slice_Type + Price + Package_Type, data = conjoint)
summary(rating_model)
##
## Call:
## lm(formula = Rating ~ Bread_Type + Slice_Type + Price + Package_Type,
## data = conjoint)
##
## Residuals:
## Min 1Q Median 3Q Max
## -3.3940 -1.4284 -0.2546 1.3089 4.8860
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.10782 0.17067 24.069 < 2e-16 ***
## Bread_TypeTraditional -0.01912 0.12146 -0.157 0.87496
## Bread_TypeWhole grain 0.38851 0.12146 3.199 0.00141 **
## Slice_TypeThick -0.29523 0.12207 -2.419 0.01570 *
## Slice_TypeThin -0.37151 0.12740 -2.916 0.00360 **
## Price150 TL -0.78767 0.15431 -5.105 3.74e-07 ***
## Price25 TL -0.10233 0.17102 -0.598 0.54969
## Price35 TL -0.17494 0.14914 -1.173 0.24098
## Price50 TL -0.35000 0.15710 -2.228 0.02604 *
## Package_TypePlastic Bag -0.89179 0.10087 -8.841 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.876 on 1484 degrees of freedom
## Multiple R-squared: 0.08997, Adjusted R-squared: 0.08446
## F-statistic: 16.3 on 9 and 1484 DF, p-value: < 2.2e-16
Conjoint Regression Results
A rating-based conjoint regression was estimated to examine how
different product attributes influence overall bread ratings. The model
is statistically significant (F-test p < 0.001), indicating that the
included attributes collectively explain variation in consumer
preferences. While the R-squared value is modest, this is expected in
consumer preference data and does not limit the interpretability of
relative attribute effects.
The regression results reveal clear differences in how
consumers evaluate product attributes:
Bread Type: Whole grain bread has a positive and
statistically significant effect on ratings, indicating a strong
preference for healthier or more natural bread options. Traditional
bread does not significantly increase ratings relative to the reference
category.
Slice Type: Both thick and thin slice options
negatively affect ratings. This suggests that consumers prefer a
standard slice thickness and penalize deviations from it.
Price: Higher prices reduce ratings,
particularly at the extreme level (150 TL), which has a strong negative
effect. Lower price increases show weaker and mostly insignificant
effects, suggesting some tolerance at moderate price levels.
Package Type: Plastic packaging has the
strongest negative impact on ratings. This highlights packaging as a
critical driver of preference and suggests that plastic is perceived as
inconsistent with quality or premium positioning.
Coefficient plot
(easy to understand for presentation)
coef_df <- tidy(rating_model) %>% filter(term != "(Intercept)")
ggplot(coef_df, aes(x = estimate, y = reorder(term, estimate))) +
geom_point(size = 3) +
geom_errorbarh(aes(xmin = estimate - 1.96*std.error, xmax = estimate + 1.96*std.error), height = 0.2) +
geom_vline(xintercept = 0, linetype = "dashed") +
labs(title = "Conjoint Regression: Effect of Attributes on Rating",
x = "Estimated impact on Rating", y = "Attribute level") +
theme_minimal()
## Warning: `geom_errorbarh()` was deprecated in ggplot2 4.0.0.
## ℹ Please use the `orientation` argument of `geom_errorbar()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `height` was translated to `width`.

Overall, packaging and price emerge as the most influential
attributes in shaping consumer ratings, followed by bread type. Slice
type plays a secondary role and appears to function as a hygiene factor
rather than a differentiator.
. Hypothesis
Evaluation
H1 (Market Penetration):
Supported. UNO is perceived as reliable, accessible, and competitive in
taste and healthiness. These attributes support continued penetration in
the core packaged bread market.
H2 (Product Development – Differentiation):
Partially supported. Consumers show strong willingness to try a premium
UNO bread, but premium perceptions are not yet well established.
Differentiation would require clear innovation and packaging cues.
H3 (Premium Adoption Potential):
Partially supported. While trial intent is high, sustained behaviors
such as weekly purchase and willingness to pay a higher price are more
moderate, suggesting selective rather than mass adoption.
H4 (Brand Stretch to Premium):
Conditionally supported. UNO has strong brand credibility, but premium
positioning is weaker. A premium extension is feasible if supported by
distinctive packaging, health-oriented positioning, and controlled
pricing.
. Managerial
Recommendation (Decision: Traditional vs Brioche)
Based on the combined qualitative insights, survey findings, and
conjoint regression results, we recommend a focused product development
strategy rather than a broad repositioning of the core UNO
portfolio.
UNO should introduce a premium or international-style bread line as a
complementary offering, targeting specific consumption occasions such as
special breakfasts, guests, or indulgent snacking. The success of this
extension will depend heavily on non-plastic, premium packaging, clear
health or quality cues, and a pricing strategy that remains within
acceptable thresholds.
At the same time, UNO should continue strengthening its core packaged
bread business by reinforcing trust, freshness, and
availability—attributes where the brand already performs strongly.
LS0tCnRpdGxlOiAiRGF0YSBJbnNpZ2h0cyBmb3IgTWFya2V0aW5nIChNaU04MTApIC0gR3JvdXA0IgpzdWJ0aXRsZTogIlVOTyBCcmVhZCBDb25zdW1lciBTdXJ2ZXkgJiBDb25qb2ludCBBbmFseXNpcyBSZXN1bHRzIgphdXRob3I6ICJHcm91cCA0IgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCksICclQiAlZCwgJVknKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGZsYXRseQogICAgaGlnaGxpZ2h0OiBweWdtZW50cwogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB0cnVlCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBkZl9wcmludDogcGFnZWQKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICBtYXRoamF4OiBkZWZhdWx0Ci0tLQoKYGBge3Igc2V0dXAsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMgMCkgUGFja2FnZXMgCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShmb3JjYXRzKQoKIyAxKSBGaWxlIHBhdGgKZXhjZWxfcGF0aCA8LSAiVU5PIFN1cnZleSBSZXNwb25zZXMgdjQueGxzeCIKCiMgU29mdCBMaWtlcnQgY29sb3IgcGFsZXR0ZSAoYWNhZGVtaWMgJiBjbGVhbikKbGlrZXJ0X2NvbG9ycyA8LSBjKAogICIxIiA9ICIjRThFOEU4IiwKICAiMiIgPSAiI0NGRTFGMiIsCiAgIjMiID0gIiNBNkM4RTAiLAogICI0IiA9ICIjNkZBRUQ5IiwKICAiNSIgPSAiIzNDOERDNSIKKQoKbGlrZXJ0N19jb2xvcnMgPC0gYygKICAiMSIgPSAiI0YwRjBGMCIsCiAgIjIiID0gIiNEOUU2RjIiLAogICIzIiA9ICIjQkZEN0VBIiwKICAiNCIgPSAiIzlFQzVERiIsCiAgIjUiID0gIiM2RkFFRDkiLAogICI2IiA9ICIjNEE5N0NGIiwKICAiNyIgPSAiIzJDN0ZCOCIKKQoKZXZhbF9jb2xvcnMgPC0gYygKICAiVmVyeSBCYWQiID0gIiNFNkU2RTYiLAogICJCYWQiID0gIiNEMUU1RjAiLAogICJTYW1lIiA9ICIjQkRCREJEIiwKICAiR29vZCIgPSAiIzkyQzVERSIsCiAgIlZlcnkgR29vZCIgPSAiIzQzOTNDMyIKKQoKCgpgYGAKCi0tLQoKIyAuIFByb2plY3QgQmFja2dyb3VuZCAoTURQIC8gTVJQIC8gUmVzZWFyY2ggUXVlc3Rpb25zKQoKIyMgTWFuYWdlbWVudCBEZWNpc2lvbiBQcm9ibGVtIChNRFApCgpVTk8gYWltcyB0byBpbmNyZWFzZSBpdHMgbWFya2V0IHNoYXJlIGluIFTDvHJraXllIGFuZCBtdXN0IGRlY2lkZSBiZXR3ZWVuIHR3byBncm93dGggcGF0aHM6Cgo8b2w+CiAgPGxpPjxzdHJvbmc+TWFya2V0IHBlbmV0cmF0aW9uOjwvc3Ryb25nPiBTdHJlbmd0aGVuaW5nIHRyYWRpdGlvbmFsIHBhY2thZ2VkIGJyZWFkcy48L2xpPgogIDxsaT48c3Ryb25nPlByb2R1Y3QgZGV2ZWxvcG1lbnQ6PC9zdHJvbmc+IExhdW5jaGluZyBhbiBpbnRlcm5hdGlvbmFsL3ByZW1pdW0gYnJlYWQgbGluZSAoZS5nLiwgYnJpb2NoZSkuPC9saT4KPC9vbD4KCgojIyBNYXJrZXRpbmcgUmVzZWFyY2ggUHJvYmxlbSAoTVJQKQoKVGhpcyByZXNlYXJjaCBhaW1zIHRvIGlkZW50aWZ5IHdoaWNoIHN0cmF0ZWdpYyBkaXJlY3Rpb27igJRtYXJrZXQgcGVuZXRyYXRpb24gb3IgcHJvZHVjdCBkZXZlbG9wbWVudOKAlGJldHRlciBhbGlnbnMgd2l0aCBjb25zdW1lciBiZWhhdmlvciwgYnJhbmQgcGVyY2VwdGlvbiwgYW5kIGN1cnJlbnQgbWFya2V0IGR5bmFtaWNzIGluIFTDvHJraXllLgoKIyMgUmVzZWFyY2ggUXVlc3Rpb25zICYgSHlwb3RoZXNlcwoKV2UgZm9jdXMgb24gY29uc3VtZXIgYmVoYXZpb3IsIHVubWV0IG5lZWRzLCB0cmlhbCBpbnRlbnQsIHNlZ21lbnQgZGlmZmVyZW5jZXMsIGFuZCBVTk8gYnJhbmQgZXF1aXR5IGZpdC4KS2V5IGh5cG90aGVzZXMgaW5jbHVkZToKLSBIMSAoUGVuZXRyYXRpb24pOiBQdXJjaGFzZSBmcmVxdWVuY3kgY2FuIGluY3JlYXNlIGlmIFVOTyBpbXByb3ZlcyBmcmVzaG5lc3MsIHByaWNpbmcsIGFuZCBhdmFpbGFiaWxpdHkuCi0gSDIgKFByb2R1Y3QgRGV2ZWxvcG1lbnQpOiBDb25zdW1lcnMgcGVyY2VpdmUgcGFja2FnZWQgYnJlYWRzIGFzIHNpbWlsYXI7IGRpZmZlcmVudGlhdGVkIHByb2R1Y3RzIChicmlvY2hlKSBtYXkgc2F0aXNmeSBub3ZlbHR5IG5lZWRzLgotIEgzIChQcm9kdWN0IERldmVsb3BtZW50KTogWW91bmdlci91cmJhbiBjb25zdW1lcnMgaGF2ZSBoaWdoZXIgYWRvcHRpb24gcG90ZW50aWFsIGZvciBpbnRlcm5hdGlvbmFsLXN0eWxlIGJyZWFkcy4KLSBINCAoQnJhbmQgRXF1aXR5KTogVU5PIGlzIHN0cm9uZ2x5IGxpbmtlZCB0byB0cmFkaXRpb25hbCBicmVhZHMsIGJ1dCBjYW4gZXh0ZW5kIHRvIHByZW1pdW0gdGhyb3VnaCBicmFuZGluZyBhbmQgcGFja2FnaW5nLgoKIyAuIFJlc2VhcmNoIERlc2lnbiAmIERhdGEgU291cmNlcwoKV2UgdXNlIGEgbWl4ZWQtbWV0aG9kIGRlc2lnbjogZXhwbG9yYXRvcnkgKGZvY3VzIGdyb3VwICsgZXhwZXJ0IGludGVydmlldykgZm9sbG93ZWQgYnkgYSBkZXNjcmlwdGl2ZSBvbmxpbmUgc3VydmV5IGFuZCBhIGNvbmpvaW50LXN0eWxlIHJhdGluZyBleHBlcmltZW50LgoKIyMgUXVhbGl0YXRpdmUgSW5zaWdodHMKCkZvY3VzIGdyb3VwIGluc2lnaHRzIGhpZ2hsaWdodDoKLSBjb25jZXJucyBhYm91dCBhZGRpdGl2ZXMvc2hlbGYgbGlmZSwKLSBwYWNrYWdpbmcgc21lbGwvbWF0ZXJpYWwgaXNzdWVzLAotIGVtb3Rpb25hbCBjb25uZWN0aW9uIHRvIHRyYWRpdGlvbmFsIHdoaXRlIGJyZWFkLAotIGJyaW9jaGUgYXMgdGFzdGUvZXhwZXJpZW5jZSAobm90IGRhaWx5IGhlYWx0aCBjaG9pY2UpLAotIHRyaWFsIHRyaWdnZXJzOiB0YXN0aW5nLCBub3ZlbHR5LCBzb2NpYWwgbWVkaWEgdmlyYWxpdHksIOKAnG5vdCBmb3VuZCBpbiBiYWtlcmllc+KAnS4KCkV4cGVydCAoZGlldGl0aWFuKSBpbnRlcnZpZXcgaGlnaGxpZ2h0czoKLSBjb25zdW1lcnMgc3RydWdnbGUgdG8gZmluZCDigJxjbGVhbi1sYWJlbCArIGZyZXNo4oCdIGJyZWFkLAotIGJyaW9jaGUgaXMgYW4gaW5kdWxnZW5jZSAod2Vla2VuZCBicmVha2Zhc3RzLCBndWVzdHMvc25hY2tpbmcpLAotIGNvcmUgdHJpYWwgdHJpZ2dlcnM6IGluZ3JlZGllbnQgcXVhbGl0eSBhbmQgdGFzdGUsCi0gVU5PIGlzIHBlcmNlaXZlZCBhcyBhIHJlbGlhYmxlIGV2ZXJ5ZGF5IGJyYW5kIChtb3JlIHRyYWRpdGlvbmFsKS4KCiMgLiBEYXRhIEltcG9ydCAoU3VydmV5IFN1bW1hcmllcyArIENvbmpvaW50KQoKIyMgSGVscGVyIGZ1bmN0aW9uIHRvIHJlYWQg4oCcT3B0aW9uIC8gQ291bnTigJ0gc2hlZXRzIHNhZmVseQoKYGBge3IgaGVscGVyLXJlYWQtc3VtbWFyeX0KcmVhZF9zdW1tYXJ5X3NoZWV0IDwtIGZ1bmN0aW9uKHBhdGgsIHNoZWV0X25hbWUpIHsKICByYXcgPC0gcmVhZF9leGNlbChwYXRoLCBzaGVldCA9IHNoZWV0X25hbWUsIGNvbF9uYW1lcyA9IEZBTFNFKQoKICAjIGZpbmQgZmlyc3Qgcm93IHRoYXQgbG9va3MgbGlrZSBhIGhlYWRlciAoY29udGFpbnMgIkNvdW50IikKICBoZWFkZXJfcm93IDwtIHdoaWNoKGFwcGx5KHJhdywgMSwgZnVuY3Rpb24oeCkgYW55KHN0cl9kZXRlY3QoYXMuY2hhcmFjdGVyKHgpLCAiXkNvdW50JCIpKSkpWzFdCgogICMgaWYgbm90IGZvdW5kLCBhc3N1bWUgZmlyc3Qgcm93IGlzIGhlYWRlcgogIGlmIChpcy5uYShoZWFkZXJfcm93KSkgaGVhZGVyX3JvdyA8LSAxCgogIGRmIDwtIHJhd1soaGVhZGVyX3Jvdyk6bnJvdyhyYXcpLCBdCiAgY29sbmFtZXMoZGYpIDwtIGFzLmNoYXJhY3RlcihkZlsxLCBdKQogIGRmIDwtIGRmWy0xLCBdICU+JSBhcy5kYXRhLmZyYW1lKCkKCiAgIyBjb252ZXJ0IENvdW50IHRvIG51bWVyaWMgaWYgcHJlc2VudAogIGlmICgiQ291bnQiICVpbiUgbmFtZXMoZGYpKSB7CiAgICBkZiRDb3VudCA8LSBhcy5udW1lcmljKGRmJENvdW50KQogIH0KICBkZgp9CmBgYAoKCiMjIFJlYWQgc2hlZXRzCgoKYGBge3IgcmVhZC1kYXRhfQojIERlbW9ncmFwaGljcyAoT3B0aW9uL0NvdW50KQphZ2VEYXRhICAgICAgIDwtIHJlYWRfc3VtbWFyeV9zaGVldChleGNlbF9wYXRoLCAiQWdlIikKaW5jb21lRGF0YSAgICA8LSByZWFkX3N1bW1hcnlfc2hlZXQoZXhjZWxfcGF0aCwgIkluY29tZSIpCmdlbmRlckRhdGEgICAgPC0gcmVhZF9zdW1tYXJ5X3NoZWV0KGV4Y2VsX3BhdGgsICJHZW5kZXIiKQplZHVjYXRpb25EYXRhIDwtIHJlYWRfc3VtbWFyeV9zaGVldChleGNlbF9wYXRoLCAiRWR1Y2F0aW9uIikKCiMgQ2F0ZWdvcnkgYmVoYXZpb3IgKE9wdGlvbi9Db3VudCkKdXNhZ2VPY2Nhc2lvbiA8LSByZWFkX3N1bW1hcnlfc2hlZXQoZXhjZWxfcGF0aCwgIkJyZWFkIFVzYWdlIE9jY2FzaW9uIikKdHJpYWxNb3RpdmVzICA8LSByZWFkX3N1bW1hcnlfc2hlZXQoZXhjZWxfcGF0aCwgIlByZW1pdW1fQnJlYWRfVHJpYWxfTW90aXZhdGlvbiIpCnB1cmNoYXNlU2V2ICAgPC0gcmVhZF9zdW1tYXJ5X3NoZWV0KGV4Y2VsX3BhdGgsICJQdXJjaGFzZSBTZXZlcml0eSIpCmJyaW9jaGVQdXJjaCAgPC0gcmVhZF9zdW1tYXJ5X3NoZWV0KGV4Y2VsX3BhdGgsICJCcmlvY2hlIFB1cmNoYXNpbmciKQoKIyBVTk8gcXVlc3Rpb25zIChncmlkIGNvdW50cykKdW5vX3ExIDwtIHJlYWRfZXhjZWwoZXhjZWxfcGF0aCwgc2hlZXQgPSAiVU5PIFF1ZXN0aW9uMSIpCnVub19xMiA8LSByZWFkX2V4Y2VsKGV4Y2VsX3BhdGgsIHNoZWV0ID0gIlVOTyBRdWVzdGlvbjIiKQp1bm9fcTMgPC0gcmVhZF9leGNlbChleGNlbF9wYXRoLCBzaGVldCA9ICJVTk8gUXVlc3Rpb24zIikKCiMgQ29uam9pbnQgKGluZGl2aWR1YWwtbGV2ZWwpCmNvbmpvaW50IDwtIHJlYWRfZXhjZWwoZXhjZWxfcGF0aCwgc2hlZXQgPSAiQ29uam9pbnRfTG9uZyIpCgpgYGAKCgotLS0KCiMgLiBTYW1wbGUgUHJvZmlsZSAoRGVtb2dyYXBoaWNzKQoKIyMgQWdlIERpc3RyaWJ1dGlvbgoKYGBge3IgcGxvdC1hZ2V9CmdncGxvdChhZ2VEYXRhLCBhZXMoeCA9IC5kYXRhW1tuYW1lcyhhZ2VEYXRhKVsxXV1dLCB5ID0gQ291bnQpKSArCiAgZ2VvbV9jb2woKSArCiAgbGFicyh0aXRsZSA9ICJBZ2UgRGlzdHJpYnV0aW9uIiwgeCA9ICJBZ2UgUmFuZ2UiLCB5ID0gIk51bWJlciBvZiBSZXNwb25kZW50cyIpICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYAoKCj4qKlByb2ZpbGUgU3VtbWFyeToqKiAgClRoZSByZXNwb25kZW50IHByb2ZpbGUgaXMgY29uY2VudHJhdGVkIGluIHRoZSAyNeKAkzU0IGFnZSByYW5nZSB3aXRoIGEgZmVtYWxlLW1ham9yaXR5IHNhbXBsZS4gRWR1Y2F0aW9uIGxldmVscyBhcmUgcHJpbWFyaWx5IEJhY2hlbG9y4oCZcyBhbmQgTWFzdGVy4oCZcywgYW5kIGEgc3Vic3RhbnRpYWwgc2hhcmUgb2YgcmVzcG9uZGVudHMgZmFsbCBpbnRvIGhpZ2hlci1pbmNvbWUgYnJhY2tldHMuIE92ZXJhbGwsIHRoZSBzYW1wbGUgcmVmbGVjdHMgdXJiYW4sIGVjb25vbWljYWxseSBhY3RpdmUgY29uc3VtZXJzIHdobyBhcmUgcmVsZXZhbnQgZm9yIGV2YWx1YXRpbmcgcHJlbWl1bSBwYWNrYWdlZCBicmVhZCBwb3NpdGlvbmluZy4KCgojIyBHZW5kZXIgLyBFZHVjYXRpb24gLyBJbmNvbWUKCmBgYHtyIHBsb3QtZGVtb2dyYXBoaWNzfQpwbG90X2NvdW50X2JhciA8LSBmdW5jdGlvbihkZiwgdGl0bGUsIHhsYWIpIHsKICBnZ3Bsb3QoZGYsIGFlcyh4ID0gLmRhdGFbW25hbWVzKGRmKVsxXV1dLCB5ID0gQ291bnQpKSArCiAgICBnZW9tX2NvbCgpICsKICAgIGxhYnModGl0bGUgPSB0aXRsZSwgeCA9IHhsYWIsIHkgPSAiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIikgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjAsIGhqdXN0ID0gMSkpCn0KCnBsb3RfY291bnRfYmFyKGdlbmRlckRhdGEsICAgICJHZW5kZXIgRGlzdHJpYnV0aW9uIiwgIkdlbmRlciIpCnBsb3RfY291bnRfYmFyKGVkdWNhdGlvbkRhdGEsICJFZHVjYXRpb24gRGlzdHJpYnV0aW9uIiwgIkVkdWNhdGlvbiIpCnBsb3RfY291bnRfYmFyKGluY29tZURhdGEsICAgICJJbmNvbWUgRGlzdHJpYnV0aW9uIiwgIkluY29tZSBSYW5nZSIpCgpgYGAKCgotLS0KCiMgLiBDYXRlZ29yeSBCZWhhdmlvciBGaW5kaW5ncyAoT3B0aW9uL0NvdW50IFNoZWV0cykKCiMjIEJyZWFkIFVzYWdlIE9jY2FzaW9uCgoKYGBge3IgcGxvdC11c2FnZS1vY2Nhc2lvbn0KcGxvdF9jb3VudF9iYXIodXNhZ2VPY2Nhc2lvbiwgIldoZW4gRG8gQ29uc3VtZXJzIFVzZSBQYWNrYWdlZCBCcmVhZD8iLCAiT2NjYXNpb24iKQoKYGBgCgo+Ci0gVGhlIHRvcCBvY2Nhc2lvbnMgaW5kaWNhdGUgd2hldGhlciBwYWNrYWdlZCBicmVhZCBpcyBtYWlubHkgdXNlZCBmb3IgKipkYWlseSBjb252ZW5pZW5jZSoqIHZzICoqc3BlY2lhbCBtb21lbnRzKiouCi0gVXNlIHRoaXMgdG8gY29ubmVjdCB0byB0aGUgZm9jdXMgZ3JvdXDigJlzIOKAnGRhaWx5IGhhYml0cyArIGZyZXNobmVzc+KAnSB0aGVtZXMuIDpjb250ZW50UmVmZXJlbmNlW29haWNpdGU6MTNde2luZGV4PTEzfQoKCiMjIE1vdGl2YXRpb24gdG8gVHJ5IGEgTmV3IFByZW1pdW0gQnJlYWQKCmBgYHtyIHBsb3QtdHJpYWwtbW90aXZlc30KcGxvdF9jb3VudF9iYXIodHJpYWxNb3RpdmVzLCAiVG9wIE1vdGl2YXRpb25zIHRvIFRyeSBQcmVtaXVtIFBhY2thZ2VkIEJyZWFkIiwgIk1vdGl2YXRpb24iKQpgYGAKCj4qKkludGVycHJldGF0aW9uIGd1aWRlOioqCkNvbXBhcmUgdGhlIHRvcCBtb3RpdmF0aW9ucyB3aXRoIHF1YWxpdGF0aXZlIHRyaWdnZXJzICh0YXN0aW5nLCBub3ZlbHR5LCBzb2NpYWwgbWVkaWEpLiA6Y29udGVudFJlZmVyZW5jZVtvYWljaXRlOjE0XXtpbmRleD0xNH0KYGBgCgojIyBQdXJjaGFzZSBTZXZlcml0eSAoaG93IG9mdGVuIHRoZXkgYnV5IHBhY2thZ2VkIGJyZWFkIC8gY2F0ZWdvcnkgaW50ZW5zaXR5KQoKYGBge3IgcHVyY2hhc2Utc2V2ZXJpdHktdGFibGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnB1cmNoYXNlU2V2IDwtIHB1cmNoYXNlU2V2ICU+JQogIG11dGF0ZShwY3QgPSByb3VuZCgxMDAgKiBDb3VudCAvIHN1bShDb3VudCksIDEpKSAlPiUKICBhcnJhbmdlKGRlc2MoQ291bnQpKQoKcHVyY2hhc2VTZXYKYGBgCgoKCmBgYHtyIHB1cmNoYXNlLXNldmVyaXR5LXBsb3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnB1cmNoYXNlU2V2ICU+JQogIG11dGF0ZShQdXJjaGFzZV9TZXZlcml0eSA9IGZjdF9yZW9yZGVyKFB1cmNoYXNlX1NldmVyaXR5LCBDb3VudCkpICU+JQogIGdncGxvdChhZXMoeCA9IFB1cmNoYXNlX1NldmVyaXR5LCB5ID0gQ291bnQpKSArCiAgZ2VvbV9jb2woKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMChwY3QsICIlIikpLCB2anVzdCA9IC0wLjMsIHNpemUgPSAzKSArCiAgbGFicygKICAgIHRpdGxlID0gIlB1cmNoYXNlIFNldmVyaXR5IChDYXRlZ29yeSBFbmdhZ2VtZW50KSIsCiAgICB4ID0gIlB1cmNoYXNlIEZyZXF1ZW5jeSAvIFNldmVyaXR5IiwKICAgIHkgPSAiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyMCwgaGp1c3QgPSAxKSkKYGBgCgo+KipJbnRlcnByZXRhdGlvbjogKiogIApUaGUgcHVyY2hhc2Ugc2V2ZXJpdHkgZGlzdHJpYnV0aW9uIGluZGljYXRlcyB0aGUgb3ZlcmFsbCBpbnRlbnNpdHkgb2YgcGFja2FnZWQgYnJlYWQgY29uc3VtcHRpb24gaW4gb3VyIHNhbXBsZS4gVGhpcyBpcyBpbXBvcnRhbnQgYmVjYXVzZSBpdCBmcmFtZXMgd2hldGhlciBkZW1hbmQgaXMgZHJpdmVuIGJ5IGRhaWx5IHJvdXRpbmVzIChzdXBwb3J0aW5nIG1hcmtldCBwZW5ldHJhdGlvbikgb3Igd2hldGhlciBwcmVtaXVtIGFuZCBzcGVjaWFsdHkgcHJvZHVjdHMgd291bGQgcmVtYWluIG5pY2hlIChzdXBwb3J0aW5nIGEgbW9yZSB0YXJnZXRlZCBwcm9kdWN0IGRldmVsb3BtZW50IHN0cmF0ZWd5KS4KCgojIyBJbnRlcm5hdGlvbmFsIEJyZWFkIFVzYWdlIFB1cnBvc2UgKEJyaW9jaGUvQmFndWV0dGUpCgpgYGB7ciBpbnRsLWJyZWFkLXB1cnBvc2UtdGFibGUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmJyaW9jaGVQdXJjaCA8LSBicmlvY2hlUHVyY2ggJT4lCiAgbXV0YXRlKHBjdCA9IHJvdW5kKDEwMCAqIENvdW50IC8gc3VtKENvdW50KSwgMSkpICU+JQogIGFycmFuZ2UoZGVzYyhDb3VudCkpCgpicmlvY2hlUHVyY2gKYGBgCgoKCmBgYHtyIGludGwtYnJlYWQtcHVycG9zZS1wbG90LCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpicmlvY2hlUHVyY2ggJT4lCiAgbXV0YXRlKEludGVybmF0aW9uYWxfQnJlYWRfVXNhZ2VfUHVycG9zZSA9CiAgICAgICAgICAgZmN0X3Jlb3JkZXIoSW50ZXJuYXRpb25hbF9CcmVhZF9Vc2FnZV9QdXJwb3NlLCBDb3VudCkpICU+JQogIGdncGxvdChhZXMoeCA9IEludGVybmF0aW9uYWxfQnJlYWRfVXNhZ2VfUHVycG9zZSwgeSA9IENvdW50KSkgKwogIGdlb21fY29sKCkgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZTAocGN0LCAiJSIpKSwgdmp1c3QgPSAtMC4zLCBzaXplID0gMykgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJXaHkgQ29uc3VtZXJzIEVhdCBJbnRlcm5hdGlvbmFsIEJyZWFkcyAoQnJpb2NoZS9CYWd1ZXR0ZSkiLAogICAgeCA9ICJVc2FnZSBQdXJwb3NlIiwKICAgIHkgPSAiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyMCwgaGp1c3QgPSAxKSkKYGBgCgoKPioqSW50ZXJwcmV0YXRpb246KiogIApJbnRlcm5hdGlvbmFsIGJyZWFkcyAoZS5nLiwgYnJpb2NoZS9iYWd1ZXR0ZSkgYXJlIGNvbnN1bWVkIG1haW5seSBmb3Igc3BlY2lmaWMgb2NjYXNpb25zIHJhdGhlciB0aGFuIGFzIGEgZGFpbHkgc3RhcGxlLiBUaGlzIGFsaWducyB3aXRoIG91ciBxdWFsaXRhdGl2ZSBmaW5kaW5ncyB0aGF0IGJyaW9jaGUgaXMgb2Z0ZW4gc2VlbiBhcyBhbiBpbmR1bGdlbnQgb3Ig4oCcc3BlY2lhbCBtb21lbnTigJ0gcHJvZHVjdCAoZS5nLiwgd2Vla2VuZCBicmVha2Zhc3RzLCBndWVzdHMsIHNuYWNraW5nKSwgc3VnZ2VzdGluZyB0aGF0IGEgcHJlbWl1bS9pbnRlcm5hdGlvbmFsIGxpbmUgd291bGQgbGlrZWx5IGJlIGFuICphZGphY2VudCogZ3Jvd3RoIG9wcG9ydHVuaXR5IHJhdGhlciB0aGFuIGEgcmVwbGFjZW1lbnQgZm9yIGNvcmUgZGFpbHkgYnJlYWRzLgoKIyAuIFVOTyBRdWVzdGlvbiAxIOKAlCBCcmFuZCBQZXJjZXB0aW9ucyAoMeKAkzUgc2NhbGUpCgojIyBQbG90IChmYWNldGVkIGJhciBjaGFydHMpCgpgYGB7ciB1bm8tcTEtcGxvdH0KcTFfaXRlbSA8LSBuYW1lcyh1bm9fcTEpWzFdICAgIyBmaXJzdCBjb2x1bW4gPSBzdGF0ZW1lbnQgbmFtZSAoZS5nLiwgSGlnaF9RdWFsaXR5KQoKdW5vX3ExX2xvbmcgPC0gdW5vX3ExICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gd2hlcmUoaXMubnVtZXJpYyksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlNjYWxlIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIkNvdW50IikgJT4lCiAgbXV0YXRlKFNjYWxlID0gYXMuZmFjdG9yKFNjYWxlKSkKCmdncGxvdCh1bm9fcTFfbG9uZywgYWVzKHggPSBTY2FsZSwgeSA9IENvdW50LCBmaWxsID0gU2NhbGUpKSArCiAgZ2VvbV9jb2wod2lkdGggPSAwLjcpICsKICBmYWNldF93cmFwKH4gVU5PX0FncmVlbWVudF9MZXZlbCwgc2NhbGVzID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBsaWtlcnRfY29sb3JzKSArCiAgbGFicygKICAgIHRpdGxlID0gIlVOTyBCcmFuZCBQZXJjZXB0aW9ucyAoMSA9IExvdywgNSA9IEhpZ2gpIiwKICAgIHggPSAiQWdyZWVtZW50IExldmVsIiwKICAgIHkgPSAiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikKICApCmBgYAoKCiMjIOKAnFRvcC1ib3jigJ0gc3VtbWFyeSAoc2ltcGxlLCB2ZXJ5IHVzZWZ1bCkKCgpgYGB7ciB1bm8tcTEtdG9wYm94fQpxMV90b3Bib3ggPC0gdW5vX3ExX2xvbmcgJT4lCiAgZ3JvdXBfYnkoLmRhdGFbW3ExX2l0ZW1dXSkgJT4lCiAgc3VtbWFyaXNlKAogICAgdG90YWwgPSBzdW0oQ291bnQsIG5hLnJtPVRSVUUpLAogICAgdG9wYm94XzRfNSA9IHN1bShDb3VudFtTY2FsZSAlaW4lIGMoIjQiLCI1IildLCBuYS5ybT1UUlVFKSwKICAgIHRvcGJveF9wY3QgPSByb3VuZCgxMDAgKiB0b3Bib3hfNF81IC8gdG90YWwsIDEpLAogICAgLmdyb3VwcyA9ICJkcm9wIgogICkgJT4lCiAgYXJyYW5nZShkZXNjKHRvcGJveF9wY3QpKQoKcTFfdG9wYm94CgpgYGAKCjxkaXYgY2xhc3M9Im5vdGUtYm94Ij4KPHNwYW4gY2xhc3M9Im5vdGUtdGl0bGUiPlVOTyBCcmFuZCBQZXJjZXB0aW9ucyAoUTEpIOKAlCBLZXkgSW5zaWdodHM8L3NwYW4+Cgo8dWw+CiAgPGxpPjxzdHJvbmc+U3Ryb25nZXN0IGFzc29jaWF0aW9uOjwvc3Ryb25nPiBOZXcgUHJvZHVjdCBTdWNjZXNzICg1NS40JSk8L2xpPgogIDxsaT48c3Ryb25nPlNvbGlkIGNvcmUgc3RyZW5ndGhzOjwvc3Ryb25nPiBSZWxpYWJsZSBFdmVyeWRheSAoNDUuOCUpLCBWYWx1ZSBmb3IgTW9uZXkgKDQyLjIlKSwgSGVhbHRoeSBUcnVzdCAoNDEuMCUpPC9saT4KICA8bGk+PHN0cm9uZz5XZWFrZXIgcGVyY2VwdGlvbnM6PC9zdHJvbmc+IFByZW1pdW0gQnJhbmQgKDMyLjUlKSwgQXR0cmFjdGl2ZSBQYWNrYWdpbmcgKDMxLjMlKTwvbGk+CjwvdWw+CgpPdmVyYWxsLCByZXNwb25kZW50cyBiZWxpZXZlIHRoYXQgVU5PIGNhbiBzdWNjZXNzZnVsbHkgZGV2ZWxvcCBuZXcgcHJvZHVjdHMgYW5kIHBlcmNlaXZlIGl0IGFzIGEgcmVsaWFibGUgZXZlcnlkYXkgYnJhbmQgb2ZmZXJpbmcgcmVhc29uYWJsZSB2YWx1ZSBhbmQgaGVhbHRoLXJlbGF0ZWQgdHJ1c3QuIEhvd2V2ZXIsIHByZW1pdW0gYnJhbmQgcGVyY2VwdGlvbiBhbmQgcGFja2FnaW5nIGF0dHJhY3RpdmVuZXNzIGFyZSByZWxhdGl2ZWx5IHdlYWtlci4gVGhpcyBzdWdnZXN0cyB0aGF0IHdoaWxlIFVOTyBoYXMgdGhlIGNyZWRpYmlsaXR5IHRvIGxhdW5jaCBhIHByZW1pdW0gbGluZSwgcHJlbWl1bSBjdWVz4oCUcGFydGljdWxhcmx5IHBhY2thZ2luZyBkZXNpZ24gYW5kIHBvc2l0aW9uaW5n4oCUbXVzdCBiZSBzdHJlbmd0aGVuZWQgdG8ganVzdGlmeSBoaWdoZXIgcHJpY2luZy4KPC9kaXY+CgoKIyAuIFVOTyBRdWVzdGlvbiAyIOKAlCBBY3Rpb24gTGlrZWxpaG9vZCBmb3IgUHJlbWl1bSBCcmVhZCAoMeKAkzcgc2NhbGUpCgpgYGB7ciB1bm8tcTItcGxvdH0KcTJfaXRlbSA8LSBuYW1lcyh1bm9fcTIpWzFdCgp1bm9fcTJfbG9uZyA8LSB1bm9fcTIgJT4lCiAgcGl2b3RfbG9uZ2VyKAogICAgY29scyA9IHdoZXJlKGlzLm51bWVyaWMpLAogICAgbmFtZXNfdG8gPSAiU2NhbGUiLAogICAgdmFsdWVzX3RvID0gIkNvdW50IgogICkgJT4lCiAgbXV0YXRlKFNjYWxlID0gYXMuZmFjdG9yKFNjYWxlKSkKCmdncGxvdCh1bm9fcTJfbG9uZywgYWVzKHggPSBTY2FsZSwgeSA9IENvdW50LCBmaWxsID0gU2NhbGUpKSArCiAgZ2VvbV9jb2wod2lkdGggPSAwLjcpICsKICBmYWNldF93cmFwKGFzLmZvcm11bGEocGFzdGUoIn4iLCBxMl9pdGVtKSksIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbGlrZXJ0N19jb2xvcnMpICsKICBsYWJzKAogICAgdGl0bGUgPSAiTGlrZWxpaG9vZCBvZiBBY3Rpb25zIGlmIFVOTyBMYXVuY2hlcyBQcmVtaXVtIEJyZWFkICgxID0gTG93LCA3ID0gSGlnaCkiLAogICAgeCA9ICJMaWtlbGlob29kIExldmVsIiwKICAgIHkgPSAiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKCgoKYGBgCgoKIyMgVG9wLWJveCBmb3IgNy1wb2ludCAoNuKAkzcpCgoKYGBge3IgdW5vLXEyLXRvcGJveH0KcTJfdG9wYm94IDwtIHVub19xMl9sb25nICU+JQogIGdyb3VwX2J5KC5kYXRhW1txMl9pdGVtXV0pICU+JQogIHN1bW1hcmlzZSgKICAgIHRvdGFsID0gc3VtKENvdW50LCBuYS5ybT1UUlVFKSwKICAgIHRvcGJveF82XzcgPSBzdW0oQ291bnRbU2NhbGUgJWluJSBjKCI2IiwiNyIpXSwgbmEucm09VFJVRSksCiAgICB0b3Bib3hfcGN0ID0gcm91bmQoMTAwICogdG9wYm94XzZfNyAvIHRvdGFsLCAxKSwKICAgIC5ncm91cHMgPSAiZHJvcCIKICApICU+JQogIGFycmFuZ2UoZGVzYyh0b3Bib3hfcGN0KSkKCnEyX3RvcGJveAoKYGBgCgo+KipCZWhhdmlvcmFsIGludGVudGlvbnMgKFEyKSDigJQgZnVubmVsIGludGVycHJldGF0aW9uOioqICAKVGhlIHN0cm9uZ2VzdCBpbnRlbnRpb24gaXMgdHJ5aW5nIFVOT+KAmXMgcHJlbWl1bSBicmVhZCBhdCBsZWFzdCBvbmNlLCBpbmRpY2F0aW5nIGhpZ2ggdHJpYWwgcG90ZW50aWFsLiBJbiBjb250cmFzdCwgd2lsbGluZ25lc3MgdG8gcGF5IGEgcHJlbWl1bSBwcmljZSBpcyBtb3JlIG1vZGVyYXRlIGFuZCBwdXJjaGFzZS1vbi1wcm9tb3Rpb24gYXBwZWFycyBpbXBvcnRhbnQsIHN1Z2dlc3RpbmcgcHJpY2Ugc2Vuc2l0aXZpdHkuIEZvbGxvd2luZyBwcm9kdWN0IGFubm91bmNlbWVudHMgb25saW5lIGlzIGxvdywgaW1wbHlpbmcgdGhhdCBhd2FyZW5lc3MtYnVpbGRpbmcgbWF5IHdvcmsgYmV0dGVyIHRocm91Z2ggaW4tc3RvcmUgdmlzaWJpbGl0eSwgcGFja2FnaW5nLCBhbmQgc2FtcGxpbmcgcmF0aGVyIHRoYW4gcmVseWluZyBvbiBjb25zdW1lcnMgYWN0aXZlbHkgdHJhY2tpbmcgdXBkYXRlcyBvbmxpbmUuCgoKPGRpdiBjbGFzcz0ibm90ZS1ib3giPgo8c3BhbiBjbGFzcz0ibm90ZS10aXRsZSI+TWFuYWdlcmlhbCBJbnRlcnByZXRhdGlvbiAoUTIpPC9zcGFuPjxicj4KClRyaWFsIGludGVudGlvbiBmb3IgYSBwcmVtaXVtIFVOTyBicmVhZCBpcyBoaWdoLCBpbmRpY2F0aW5nIHN0cm9uZyBjdXJpb3NpdHkgYW5kIG9wZW5uZXNzIGFtb25nIGNvbnN1bWVycy4gSG93ZXZlciwgd2lsbGluZ25lc3MgdG8gcGF5IGEgaGlnaGVyIHByaWNlIGlzIG1vcmUgbW9kZXJhdGUsIGFuZCBidXlpbmcgb24gcHJvbW90aW9uIGFwcGVhcnMgaW1wb3J0YW50LiBUaGlzIHN1Z2dlc3RzIHRoYXQgcHJlbWl1bSBhZG9wdGlvbiB3aWxsIGRlcGVuZCBvbiBjbGVhciB2YWx1ZSBjb21tdW5pY2F0aW9uIGFuZCBjb250cm9sbGVkIHByaWNpbmcgcmF0aGVyIHRoYW4gcHVyZWx5IGJyYW5kLWRyaXZlbiB3aWxsaW5nbmVzcyB0byBwYXkuCjwvZGl2PgoKCiMgLiBVTk8gUXVlc3Rpb24gMyDigJQgQ29tcGFyYXRpdmUgVU5PIFJhdGluZ3MgKFZlcnkgQmFkIOKGkiBWZXJ5IEdvb2QpCgpgYGB7ciB1bm8tcTMtcGxvdH0KcTNfaXRlbSA8LSBuYW1lcyh1bm9fcTMpWzFdICAjIGF0dHJpYnV0ZSBuYW1lIGNvbHVtbiAoVGFzdGUsIEZyZXNobmVzcywgZXRjLikKCnVub19xM19sb25nIDwtIHVub19xMyAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1hbGxfb2YocTNfaXRlbSksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIkV2YWx1YXRpb24iLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiQ291bnQiKSAlPiUKICBtdXRhdGUoRXZhbHVhdGlvbiA9IGZhY3RvcihFdmFsdWF0aW9uLCBsZXZlbHMgPSBjKCJWZXJ5IEJhZCIsIkJhZCIsIlNhbWUiLCJHb29kIiwiVmVyeSBHb29kIikpKQoKZ2dwbG90KHVub19xM19sb25nLCBhZXMoeCA9IEV2YWx1YXRpb24sIHkgPSBDb3VudCwgZmlsbCA9IEV2YWx1YXRpb24pKSArCiAgZ2VvbV9jb2wod2lkdGggPSAwLjcpICsKICBmYWNldF93cmFwKH4gQ29tcGFyYXRpdmVfVU5PX1JhdGluZ3MsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gZXZhbF9jb2xvcnMpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVU5PIHZzIE90aGVyIEJyZWFkIEJyYW5kcyAoQ29tcGFyYXRpdmUgRXZhbHVhdGlvbikiLAogICAgeCA9ICJFdmFsdWF0aW9uIiwKICAgIHkgPSAiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIgogICkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKSwKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikKICApCgoKYGBgCgo+KipDb21wYXJhdGl2ZSBFdmFsdWF0aW9uIG9mIFVOTyB2cyBPdGhlciBCcmVhZCBCcmFuZHMqKgpUaGlzIHNlY3Rpb24gZXZhbHVhdGVzIGhvdyBVTk8gcGVyZm9ybXMgcmVsYXRpdmUgdG8gb3RoZXIgcGFja2FnZWQgYnJlYWQgYnJhbmRzIGFjcm9zcyBrZXkgYXR0cmlidXRlcyBzdWNoIGFzIHRhc3RlLCBmcmVzaG5lc3MsIHByaWNlLCBwYWNrYWdpbmcsIGhlYWx0aGluZXNzLCBhdmFpbGFiaWxpdHksIGlubm92YXRpdmVuZXNzLCBhbmQgcHJlbWl1bSBmZWVsLgpPdmVyYWxsLCBVTk8gcGVyZm9ybXMgc3Ryb25nbHkgb24gY29yZSBmdW5jdGlvbmFsIGF0dHJpYnV0ZXMuIFRhc3RlIGFuZCBhdmFpbGFiaWxpdHkgcmVjZWl2ZSBhIGhpZ2ggY29uY2VudHJhdGlvbiBvZiDigJxHb29k4oCdIGFuZCDigJxWZXJ5IEdvb2TigJ0gcmF0aW5ncywgaW5kaWNhdGluZyB0aGF0IGNvbnN1bWVycyBwZXJjZWl2ZSBVTk8gYXMgY29tcGV0aXRpdmUgb3Igc3VwZXJpb3IgdG8gb3RoZXIgYnJhbmRzIGluIGV2ZXJ5ZGF5IGNvbnN1bXB0aW9uIGNvbnRleHRzLiBIZWFsdGhpbmVzcyBhbHNvIHNob3dzIGEgZmF2b3JhYmxlIGRpc3RyaWJ1dGlvbiwgc3VwcG9ydGluZyBlYXJsaWVyIHF1YWxpdGF0aXZlIGluc2lnaHRzIHRoYXQgcG9zaXRpb24gVU5PIGFzIGEgcmVsaWFibGUgYW5kIHRydXN0ZWQgb3B0aW9uIGZvciBkYWlseSBicmVhZCBuZWVkcy4KSW4gY29udHJhc3QsIGF0dHJpYnV0ZXMgcmVsYXRlZCB0byBwcmVtaXVtIHBvc2l0aW9uaW5n4oCUcGFydGljdWxhcmx5IHByZW1pdW0gZmVlbCBhbmQgaW5ub3ZhdGl2ZW5lc3PigJRzaG93IGEgbW9yZSBtaXhlZCBkaXN0cmlidXRpb24sIHdpdGggbWFueSByZXNwb25kZW50cyBzZWxlY3Rpbmcg4oCcU2FtZeKAnSByYXRoZXIgdGhhbiDigJxHb29k4oCdIG9yIOKAnFZlcnkgR29vZC7igJ0gVGhpcyBzdWdnZXN0cyB0aGF0IHdoaWxlIFVOTyBpcyBub3QgcGVyY2VpdmVkIGFzIHdlYWsgaW4gdGhlc2UgZGltZW5zaW9ucywgaXQgaXMgbm90IHlldCBjbGVhcmx5IGRpZmZlcmVudGlhdGVkIGFzIGEgcHJlbWl1bSBvciBoaWdobHkgaW5ub3ZhdGl2ZSBicmFuZCBjb21wYXJlZCB0byBhbHRlcm5hdGl2ZXMuCgo+VGhlc2UgcmVzdWx0cyByZWluZm9yY2UgdGhlIGludGVycHJldGF0aW9uIHRoYXQgVU5P4oCZcyBjdXJyZW50IGJyYW5kIHN0cmVuZ3RoIGxpZXMgaW4gZnVuY3Rpb25hbCBwZXJmb3JtYW5jZSBhbmQgcmVsaWFiaWxpdHkgcmF0aGVyIHRoYW4gc3ltYm9saWMgb3IgcHJlbWl1bSBkaWZmZXJlbnRpYXRpb24uIENvbnNlcXVlbnRseSwgYW55IHByZW1pdW0gYnJlYWQgZXh0ZW5zaW9uIHdvdWxkIG5lZWQgdG8gcmVseSBvbiBzdHJvbmdlciBpbm5vdmF0aW9uIHNpZ25hbHMsIHBhY2thZ2luZyBkZXNpZ24sIGFuZCBwcm9kdWN0IHN0b3J5dGVsbGluZyB0byBzaGlmdCBjb25zdW1lciBwZXJjZXB0aW9ucyBiZXlvbmQgcGFyaXR5IHdpdGggZXhpc3RpbmcgYnJhbmRzLgoKCiMgLiBDb25qb2ludCBSZWdyZXNzaW9uIChJbmRpdmlkdWFsLUxldmVsIE1vZGVsKQoKYGBge3IgY29uam9pbnQtbW9kZWx9CiMgRW5zdXJlIGNhdGVnb3JpY2FsIGZpZWxkcyBhcmUgdHJlYXRlZCBhcyBmYWN0b3JzCmNvbmpvaW50IDwtIGNvbmpvaW50ICU+JQogIG11dGF0ZSgKICAgIEJyZWFkX1R5cGUgICA9IGFzLmZhY3RvcihCcmVhZF9UeXBlKSwKICAgIFNsaWNlX1R5cGUgICA9IGFzLmZhY3RvcihTbGljZV9UeXBlKSwKICAgIFBhY2thZ2VfVHlwZSA9IGFzLmZhY3RvcihQYWNrYWdlX1R5cGUpLAogICAgUHJpY2UgICAgICAgID0gYXMuZmFjdG9yKFByaWNlKQogICkKCnJhdGluZ19tb2RlbCA8LSBsbShSYXRpbmcgfiBCcmVhZF9UeXBlICsgU2xpY2VfVHlwZSArIFByaWNlICsgUGFja2FnZV9UeXBlLCBkYXRhID0gY29uam9pbnQpCnN1bW1hcnkocmF0aW5nX21vZGVsKQoKYGBgCgo+KipDb25qb2ludCBSZWdyZXNzaW9uIFJlc3VsdHMqKgoKPkEgcmF0aW5nLWJhc2VkIGNvbmpvaW50IHJlZ3Jlc3Npb24gd2FzIGVzdGltYXRlZCB0byBleGFtaW5lIGhvdyBkaWZmZXJlbnQgcHJvZHVjdCBhdHRyaWJ1dGVzIGluZmx1ZW5jZSBvdmVyYWxsIGJyZWFkIHJhdGluZ3MuIFRoZSBtb2RlbCBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChGLXRlc3QgcCA8IDAuMDAxKSwgaW5kaWNhdGluZyB0aGF0IHRoZSBpbmNsdWRlZCBhdHRyaWJ1dGVzIGNvbGxlY3RpdmVseSBleHBsYWluIHZhcmlhdGlvbiBpbiBjb25zdW1lciBwcmVmZXJlbmNlcy4gV2hpbGUgdGhlIFItc3F1YXJlZCB2YWx1ZSBpcyBtb2Rlc3QsIHRoaXMgaXMgZXhwZWN0ZWQgaW4gY29uc3VtZXIgcHJlZmVyZW5jZSBkYXRhIGFuZCBkb2VzIG5vdCBsaW1pdCB0aGUgaW50ZXJwcmV0YWJpbGl0eSBvZiByZWxhdGl2ZSBhdHRyaWJ1dGUgZWZmZWN0cy4KCioqVGhlIHJlZ3Jlc3Npb24gcmVzdWx0cyByZXZlYWwgY2xlYXIgZGlmZmVyZW5jZXMgaW4gaG93IGNvbnN1bWVycyBldmFsdWF0ZSBwcm9kdWN0IGF0dHJpYnV0ZXM6KioKCi0gKipCcmVhZCBUeXBlOioqIFdob2xlIGdyYWluIGJyZWFkIGhhcyBhIHBvc2l0aXZlIGFuZCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGVmZmVjdCBvbiByYXRpbmdzLCBpbmRpY2F0aW5nIGEgc3Ryb25nIHByZWZlcmVuY2UgZm9yIGhlYWx0aGllciBvciBtb3JlIG5hdHVyYWwgYnJlYWQgb3B0aW9ucy4gVHJhZGl0aW9uYWwgYnJlYWQgZG9lcyBub3Qgc2lnbmlmaWNhbnRseSBpbmNyZWFzZSByYXRpbmdzIHJlbGF0aXZlIHRvIHRoZSByZWZlcmVuY2UgY2F0ZWdvcnkuCgotICoqU2xpY2UgVHlwZToqKiBCb3RoIHRoaWNrIGFuZCB0aGluIHNsaWNlIG9wdGlvbnMgbmVnYXRpdmVseSBhZmZlY3QgcmF0aW5ncy4gVGhpcyBzdWdnZXN0cyB0aGF0IGNvbnN1bWVycyBwcmVmZXIgYSBzdGFuZGFyZCBzbGljZSB0aGlja25lc3MgYW5kIHBlbmFsaXplIGRldmlhdGlvbnMgZnJvbSBpdC4KCi0gKipQcmljZToqKiBIaWdoZXIgcHJpY2VzIHJlZHVjZSByYXRpbmdzLCBwYXJ0aWN1bGFybHkgYXQgdGhlIGV4dHJlbWUgbGV2ZWwgKDE1MCBUTCksIHdoaWNoIGhhcyBhIHN0cm9uZyBuZWdhdGl2ZSBlZmZlY3QuIExvd2VyIHByaWNlIGluY3JlYXNlcyBzaG93IHdlYWtlciBhbmQgbW9zdGx5IGluc2lnbmlmaWNhbnQgZWZmZWN0cywgc3VnZ2VzdGluZyBzb21lIHRvbGVyYW5jZSBhdCBtb2RlcmF0ZSBwcmljZSBsZXZlbHMuCgotICoqUGFja2FnZSBUeXBlOioqIFBsYXN0aWMgcGFja2FnaW5nIGhhcyB0aGUgc3Ryb25nZXN0IG5lZ2F0aXZlIGltcGFjdCBvbiByYXRpbmdzLiBUaGlzIGhpZ2hsaWdodHMgcGFja2FnaW5nIGFzIGEgY3JpdGljYWwgZHJpdmVyIG9mIHByZWZlcmVuY2UgYW5kIHN1Z2dlc3RzIHRoYXQgcGxhc3RpYyBpcyBwZXJjZWl2ZWQgYXMgaW5jb25zaXN0ZW50IHdpdGggcXVhbGl0eSBvciBwcmVtaXVtIHBvc2l0aW9uaW5nLgoKCgojIyBDb2VmZmljaWVudCBwbG90IChlYXN5IHRvIHVuZGVyc3RhbmQgZm9yIHByZXNlbnRhdGlvbikKCgpgYGB7ciBjb25qb2ludC1jb2VmLXBsb3R9CmNvZWZfZGYgPC0gdGlkeShyYXRpbmdfbW9kZWwpICU+JSBmaWx0ZXIodGVybSAhPSAiKEludGVyY2VwdCkiKQoKZ2dwbG90KGNvZWZfZGYsIGFlcyh4ID0gZXN0aW1hdGUsIHkgPSByZW9yZGVyKHRlcm0sIGVzdGltYXRlKSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHhtaW4gPSBlc3RpbWF0ZSAtIDEuOTYqc3RkLmVycm9yLCB4bWF4ID0gZXN0aW1hdGUgKyAxLjk2KnN0ZC5lcnJvciksIGhlaWdodCA9IDAuMikgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBsYWJzKHRpdGxlID0gIkNvbmpvaW50IFJlZ3Jlc3Npb246IEVmZmVjdCBvZiBBdHRyaWJ1dGVzIG9uIFJhdGluZyIsCiAgICAgICB4ID0gIkVzdGltYXRlZCBpbXBhY3Qgb24gUmF0aW5nIiwgeSA9ICJBdHRyaWJ1dGUgbGV2ZWwiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpgYGAKCj5PdmVyYWxsLCBwYWNrYWdpbmcgYW5kIHByaWNlIGVtZXJnZSBhcyB0aGUgbW9zdCBpbmZsdWVudGlhbCBhdHRyaWJ1dGVzIGluIHNoYXBpbmcgY29uc3VtZXIgcmF0aW5ncywgZm9sbG93ZWQgYnkgYnJlYWQgdHlwZS4gU2xpY2UgdHlwZSBwbGF5cyBhIHNlY29uZGFyeSByb2xlIGFuZCBhcHBlYXJzIHRvIGZ1bmN0aW9uIGFzIGEgaHlnaWVuZSBmYWN0b3IgcmF0aGVyIHRoYW4gYSBkaWZmZXJlbnRpYXRvci4KCgojIC4gSHlwb3RoZXNpcyBFdmFsdWF0aW9uCgoqKkgxIChNYXJrZXQgUGVuZXRyYXRpb24pOioqICAKU3VwcG9ydGVkLiBVTk8gaXMgcGVyY2VpdmVkIGFzIHJlbGlhYmxlLCBhY2Nlc3NpYmxlLCBhbmQgY29tcGV0aXRpdmUgaW4gdGFzdGUgYW5kIGhlYWx0aGluZXNzLiBUaGVzZSBhdHRyaWJ1dGVzIHN1cHBvcnQgY29udGludWVkIHBlbmV0cmF0aW9uIGluIHRoZSBjb3JlIHBhY2thZ2VkIGJyZWFkIG1hcmtldC4KCioqSDIgKFByb2R1Y3QgRGV2ZWxvcG1lbnQg4oCTIERpZmZlcmVudGlhdGlvbik6KiogIApQYXJ0aWFsbHkgc3VwcG9ydGVkLiBDb25zdW1lcnMgc2hvdyBzdHJvbmcgd2lsbGluZ25lc3MgdG8gdHJ5IGEgcHJlbWl1bSBVTk8gYnJlYWQsIGJ1dCBwcmVtaXVtIHBlcmNlcHRpb25zIGFyZSBub3QgeWV0IHdlbGwgZXN0YWJsaXNoZWQuIERpZmZlcmVudGlhdGlvbiB3b3VsZCByZXF1aXJlIGNsZWFyIGlubm92YXRpb24gYW5kIHBhY2thZ2luZyBjdWVzLgoKKipIMyAoUHJlbWl1bSBBZG9wdGlvbiBQb3RlbnRpYWwpOioqICAKUGFydGlhbGx5IHN1cHBvcnRlZC4gV2hpbGUgdHJpYWwgaW50ZW50IGlzIGhpZ2gsIHN1c3RhaW5lZCBiZWhhdmlvcnMgc3VjaCBhcyB3ZWVrbHkgcHVyY2hhc2UgYW5kIHdpbGxpbmduZXNzIHRvIHBheSBhIGhpZ2hlciBwcmljZSBhcmUgbW9yZSBtb2RlcmF0ZSwgc3VnZ2VzdGluZyBzZWxlY3RpdmUgcmF0aGVyIHRoYW4gbWFzcyBhZG9wdGlvbi4KCioqSDQgKEJyYW5kIFN0cmV0Y2ggdG8gUHJlbWl1bSk6KiogIApDb25kaXRpb25hbGx5IHN1cHBvcnRlZC4gVU5PIGhhcyBzdHJvbmcgYnJhbmQgY3JlZGliaWxpdHksIGJ1dCBwcmVtaXVtIHBvc2l0aW9uaW5nIGlzIHdlYWtlci4gQSBwcmVtaXVtIGV4dGVuc2lvbiBpcyBmZWFzaWJsZSBpZiBzdXBwb3J0ZWQgYnkgZGlzdGluY3RpdmUgcGFja2FnaW5nLCBoZWFsdGgtb3JpZW50ZWQgcG9zaXRpb25pbmcsIGFuZCBjb250cm9sbGVkIHByaWNpbmcuCgoKCiMgLiBNYW5hZ2VyaWFsIFJlY29tbWVuZGF0aW9uIChEZWNpc2lvbjogVHJhZGl0aW9uYWwgdnMgQnJpb2NoZSkKCkJhc2VkIG9uIHRoZSBjb21iaW5lZCBxdWFsaXRhdGl2ZSBpbnNpZ2h0cywgc3VydmV5IGZpbmRpbmdzLCBhbmQgY29uam9pbnQgcmVncmVzc2lvbiByZXN1bHRzLCB3ZSByZWNvbW1lbmQgYSBmb2N1c2VkIHByb2R1Y3QgZGV2ZWxvcG1lbnQgc3RyYXRlZ3kgcmF0aGVyIHRoYW4gYSBicm9hZCByZXBvc2l0aW9uaW5nIG9mIHRoZSBjb3JlIFVOTyBwb3J0Zm9saW8uCgpVTk8gc2hvdWxkIGludHJvZHVjZSBhIHByZW1pdW0gb3IgaW50ZXJuYXRpb25hbC1zdHlsZSBicmVhZCBsaW5lIGFzIGEgY29tcGxlbWVudGFyeSBvZmZlcmluZywgdGFyZ2V0aW5nIHNwZWNpZmljIGNvbnN1bXB0aW9uIG9jY2FzaW9ucyBzdWNoIGFzIHNwZWNpYWwgYnJlYWtmYXN0cywgZ3Vlc3RzLCBvciBpbmR1bGdlbnQgc25hY2tpbmcuIFRoZSBzdWNjZXNzIG9mIHRoaXMgZXh0ZW5zaW9uIHdpbGwgZGVwZW5kIGhlYXZpbHkgb24gbm9uLXBsYXN0aWMsIHByZW1pdW0gcGFja2FnaW5nLCBjbGVhciBoZWFsdGggb3IgcXVhbGl0eSBjdWVzLCBhbmQgYSBwcmljaW5nIHN0cmF0ZWd5IHRoYXQgcmVtYWlucyB3aXRoaW4gYWNjZXB0YWJsZSB0aHJlc2hvbGRzLgoKQXQgdGhlIHNhbWUgdGltZSwgVU5PIHNob3VsZCBjb250aW51ZSBzdHJlbmd0aGVuaW5nIGl0cyBjb3JlIHBhY2thZ2VkIGJyZWFkIGJ1c2luZXNzIGJ5IHJlaW5mb3JjaW5nIHRydXN0LCBmcmVzaG5lc3MsIGFuZCBhdmFpbGFiaWxpdHnigJRhdHRyaWJ1dGVzIHdoZXJlIHRoZSBicmFuZCBhbHJlYWR5IHBlcmZvcm1zIHN0cm9uZ2x5LgoKCg==