Executive Summary
This report investigates whether a workplace wellness program reduces
employee medical costs. The analysis utilizes a Randomized Control Trial
(RCT), considered the gold standard for causal inference.
The Business Question: Does offering a wellness
program reduce medical spending?
Data Dictionary: Understanding the Variables
Key variables used in the analysis include:
- Random Assignment: 1 = Offered the program, 0 = Not
offered.
- Participation Status: 1 = Enrolled, 0 = Did not
enroll.
- Insurance Coverage Weight: Used to adjust for
partial-year employees.
- Baseline Total Spending: Medical costs before the
program (2015-2016).
- Outcome Total Spending: Medical costs during the
program (2016-2017).
- Baseline Hospital Spending: Hospital costs
(2015-2016).
- Baseline Office Visit Spending: Office visit costs
(2015-2016).
- Outcome Hospital Spending: Hospital costs
(2016-2017).
- Outcome Office Visit Spending: Office visit costs
(2016-2017).
- Gender (Male): 1 = Male, 0 = Female.
- Age 37-49: 1 = 37-49 years old.
- Age 50+: 1 = 50+ years old.
- Race (White): 1 = White.
# Load required packages
library(tidyverse)
library(ggplot2)
library(modelsummary)
library(vtable)
library(haven)
library(estimatr)
library(ivreg)
library(sandwich)
library(skimr)
# Set global options
knitr::opts_chunk$set(echo = TRUE, eval = TRUE, message = FALSE, warning = FALSE)
# Load data
my_data <- read_dta("https://reifjulian.github.io/illinois-wellness-data/data/stata/claims.dta")
# Rename columns using Base R based on data dictionary
names(my_data)[names(my_data) == "treat"] <- "Random Assignment"
names(my_data)[names(my_data) == "hra_c_yr1"] <- "Participation Status"
names(my_data)[names(my_data) == "covg_0816_0717"] <- "Insurance Coverage Weight"
names(my_data)[names(my_data) == "spend_0715_0716"] <- "Baseline Total Spending"
names(my_data)[names(my_data) == "spend_0816_0717"] <- "Outcome Total Spending"
names(my_data)[names(my_data) == "spendHosp_0715_0716"] <- "Baseline Hospital Spending"
names(my_data)[names(my_data) == "spendOff_0715_0716"] <- "Baseline Office Visit Spending"
names(my_data)[names(my_data) == "spendHosp_0816_0717"] <- "Outcome Hospital Spending"
names(my_data)[names(my_data) == "spendOff_0816_0717"] <- "Outcome Office Visit Spending"
names(my_data)[names(my_data) == "male"] <- "Gender (Male)"
names(my_data)[names(my_data) == "age37_49"] <- "Age 37-49"
names(my_data)[names(my_data) == "age50"] <- "Age 50+"
names(my_data)[names(my_data) == "white"] <- "Race (White)"
# Create grouping variables for analysis
my_data$`Enrollment Status` <- ifelse(my_data$`Participation Status` == 1, "Enrolled", "Not Enrolled")
my_data$`Treatment Group` <- ifelse(my_data$`Random Assignment` == 1, "Treatment", "Control")
# Inspect data
skim(my_data)
── Data Summary ────────────────────────
Values
Name my_data
Number of rows 4834
Number of columns 60
_______________________
Column type frequency:
character 2
numeric 58
________________________
Group variables None
Summary Statistics Among Employers With Workplace Wellness
Programs
The initial analysis focuses on employees offered the program
(Random Assignment == 1), comparing those who chose to
enroll versus those who did not.
# Filter for employees offered the program
only_treat <- subset(my_data, `Random Assignment` == 1)
# Summary of employee characteristics by enrollment
sumtable(
only_treat,
vars = c(
"Gender (Male)", "Age 37-49", "Age 50+", "Race (White)",
"Baseline Hospital Spending", "Baseline Office Visit Spending", "Baseline Total Spending"
),
group = "Enrollment Status",
title = "Summary of Employee Characteristics by Wellness Program Enrollment",
out = "kable"
) %>%
kableExtra::kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed"))
Summary of Employee Characteristics by Wellness Program Enrollment
| Variable |
N |
Mean |
SD |
N |
Mean |
SD |
| Enrollment Status |
Enrolled |
|
|
Not Enrolled |
|
|
| Gender (Male) |
1848 |
0.4 |
0.49 |
1452 |
0.46 |
0.5 |
| Age 37-49 |
1848 |
0.34 |
0.47 |
1452 |
0.33 |
0.47 |
| Age 50+ |
1848 |
0.31 |
0.46 |
1452 |
0.34 |
0.47 |
| Race (White) |
1848 |
0.84 |
0.37 |
1452 |
0.84 |
0.37 |
| Baseline Hospital Spending |
1318 |
222 |
433 |
870 |
316 |
1078 |
| Baseline Office Visit Spending |
1318 |
59 |
153 |
870 |
56 |
168 |
| Baseline Total Spending |
1318 |
424 |
779 |
870 |
527 |
1331 |
# Summary of health outcomes by enrollment
sumtable(
only_treat,
vars = c("Outcome Hospital Spending", "Outcome Office Visit Spending", "Outcome Total Spending"),
group = "Enrollment Status",
title = "Summary of Health Outcomes by Wellness Program Enrollment",
out = "kable"
) %>%
kableExtra::kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed"))
Summary of Health Outcomes by Wellness Program Enrollment
| Variable |
N |
Mean |
SD |
N |
Mean |
SD |
| Enrollment Status |
Enrolled |
|
|
Not Enrolled |
|
|
| Outcome Hospital Spending |
1338 |
268 |
687 |
870 |
371 |
1446 |
| Outcome Office Visit Spending |
1338 |
73 |
175 |
870 |
58 |
159 |
| Outcome Total Spending |
1338 |
517 |
1064 |
870 |
635 |
1715 |
Now, let’s visualize the spending differences.
# Plot distribution of healthcare spending by enrollment
ggplot(
data = only_treat,
aes(
x = log(`Outcome Total Spending` + 1),
fill = as.factor(`Enrollment Status`),
color = as.factor(`Enrollment Status`)
)
) +
geom_density(alpha = 0.4, na.rm = TRUE) +
labs(
title = "Distribution of Total Healthcare Spending by Enrollment",
x = "Total Spending (2016–2017)",
y = "Density",
fill = "Enrollment Status",
color = "Enrollment Status"
)

# Box plot of log outcome spending to visualize outliers
ggplot(
data = only_treat,
aes(x = `Enrollment Status`, y = log(`Outcome Total Spending` + 1), fill = `Enrollment Status`)
) +
geom_boxplot() +
labs(
title = "Box Plot of Healthcare Spending by Enrollment",
x = "Enrollment Status",
y = "Total Spending (2016–2017)",
fill = "Enrollment Status"
)

Interpretation: The “Selection Bias” Trap
The table and plots indicate that employees who enrolled in the
program spent significantly less money before the program even
started (Baseline Spending).
This illustrates Selection Bias. Participants in
wellness programs are typically those who are already healthy and
health-conscious. Consequently, observed lower costs may reflect
pre-existing health status rather than program effectiveness. Comparing
enrollees to non-enrollees without adjustment leads to biased
conclusions.
Regression Analysis (The “Biased View”)
Standard statistical analysis (OLS Regression) provides estimates if
selection bias is ignored.
# Baseline model
baseline <- lm(`Outcome Total Spending` ~ `Participation Status`, data = only_treat, weights = `Insurance Coverage Weight`)
# Add additional models with controls
with_controls <- lm(`Outcome Total Spending` ~ `Participation Status` + `Gender (Male)` + `Age 37-49` + `Age 50+` + `Race (White)`, data = only_treat, weights = `Insurance Coverage Weight`)
# Present in a regression table
models <- list(baseline, with_controls)
modelsummary(models,
coef_omit = "(Intercept)",
statistic = c("std.error", "statistic", "conf.int"), fmt = 4,
gof_map = c("nobs", "r.squared"),
vcov = "HC1",
title = "OLS Estimates of the Effect of Wellness Program on Total Spending"
)
tinytable_dsgcdw77bzywrbjhqxdb
OLS Estimates of the Effect of Wellness Program on Total Spending
| |
(1) |
(2) |
| Participation Status |
-137.3006 |
-152.4476 |
|
(68.5928) |
(66.3829) |
|
(-2.0017) |
(-2.2965) |
|
[-271.8138, -2.7873] |
[-282.6273, -22.2680] |
| Gender (Male) |
|
-276.5082 |
|
|
(60.4891) |
|
|
(-4.5712) |
|
|
[-395.1299, -157.8865] |
| Age 37-49 |
|
69.0354 |
|
|
(55.3430) |
|
|
(1.2474) |
|
|
[-39.4946, 177.5653] |
| Age 50+ |
|
390.6435 |
|
|
(84.3748) |
|
|
(4.6299) |
|
|
[225.1810, 556.1059] |
| Race (White) |
|
171.1125 |
|
|
(54.8499) |
|
|
(3.1196) |
|
|
[63.5494, 278.6755] |
| Num.Obs. |
2208 |
2208 |
| R2 |
0.002 |
0.032 |
Interpretation: The “Healthy User” Effect
The regression results show a negative coefficient for the program
effect, suggesting that enrolling reduces spending by about $137 to
$152.
However, this result is misleading as it captures the
“Healthy User” effect. The analysis credits the program
for the participants’ underlying good health. Since “healthiness” is not
perfectly measured by age and gender alone, the regression cannot fully
separate the program’s effect from the participants’ pre-existing
health. Relying on these results would lead to incorrect business
decisions.
Comparison of Treatment and Control Groups (The “Reality
Check”)
The Randomized Control Trial (RCT) design addresses this issue. In an
RCT, individuals are randomly assigned to be offered the
program or not. This randomization creates two statistically identical
groups.
# Create a table summarizing the characteristics for treated and untreated enrollees
sumtable(my_data,
vars = c("Gender (Male)", "Age 37-49", "Age 50+", "Race (White)", "Baseline Hospital Spending", "Baseline Office Visit Spending", "Baseline Total Spending"),
group = "Treatment Group", title = "Comparison of Baseline Characteristics by Treatment Group", out = "kable"
) %>%
kableExtra::kable_styling(full_width = TRUE, bootstrap_options = c("striped", "hover", "condensed"))
Comparison of Baseline Characteristics by Treatment Group
| Variable |
N |
Mean |
SD |
N |
Mean |
SD |
| Treatment Group |
Control |
|
|
Treatment |
|
|
| Gender (Male) |
1534 |
0.43 |
0.49 |
3300 |
0.43 |
0.49 |
| Age 37-49 |
1534 |
0.34 |
0.47 |
3300 |
0.33 |
0.47 |
| Age 50+ |
1534 |
0.32 |
0.47 |
3300 |
0.33 |
0.47 |
| Race (White) |
1534 |
0.84 |
0.37 |
3300 |
0.84 |
0.37 |
| Baseline Hospital Spending |
1035 |
283 |
683 |
2188 |
259 |
759 |
| Baseline Office Visit Spending |
1035 |
67 |
400 |
2188 |
58 |
159 |
| Baseline Total Spending |
1035 |
506 |
1099 |
2188 |
465 |
1035 |
# Test whether characteristics are different
t.test(`Gender (Male)` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Gender (Male) by Random Assignment
t = -0.12372, df = 2990.4, p-value = 0.9015
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-0.03186374 0.02808120
sample estimates:
mean in group 0 mean in group 1
0.4256845 0.4275758
t.test(`Age 37-49` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Age 37-49 by Random Assignment
t = 0.53784, df = 2973.3, p-value = 0.5907
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-0.02080130 0.03652648
sample estimates:
mean in group 0 mean in group 1
0.3402868 0.3324242
t.test(`Age 50+` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Age 50+ by Random Assignment
t = -0.23005, df = 2996, p-value = 0.8181
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-0.03170200 0.02504403
sample estimates:
mean in group 0 mean in group 1
0.3233377 0.3266667
t.test(`Race (White)` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Race (White) by Random Assignment
t = 0.45642, df = 3024.1, p-value = 0.6481
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-0.01707684 0.02743913
sample estimates:
mean in group 0 mean in group 1
0.8409387 0.8357576
t.test(`Baseline Hospital Spending` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Baseline Hospital Spending by Random Assignment
t = 0.89886, df = 2235, p-value = 0.3688
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-28.39434 76.45223
sample estimates:
mean in group 0 mean in group 1
283.3604 259.3314
t.test(`Baseline Office Visit Spending` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Baseline Office Visit Spending by Random Assignment
t = 0.67712, df = 1191.9, p-value = 0.4985
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-16.57693 34.04946
sample estimates:
mean in group 0 mean in group 1
66.71167 57.97540
t.test(`Baseline Total Spending` ~ `Random Assignment`, data = my_data)
Welch Two Sample t-test
data: Baseline Total Spending by Random Assignment
t = 1.0014, df = 1923.8, p-value = 0.3168
alternative hypothesis: true difference in means between group 0 and group 1 is not equal to 0
95 percent confidence interval:
-39.07482 120.60487
sample estimates:
mean in group 0 mean in group 1
505.5786 464.8136
Interpretation: Why “No Difference” is Good
T-tests were conducted to compare the “Treatment” group (offered the
program) and the “Control” group (not offered). The results show
no statistically significant difference between them in
terms of age, gender, or past spending.
This confirms that the randomization was successful. The two groups
are effectively identical. Any difference in future spending can be
confidently attributed to the program, not to pre-existing
differences.
IV Estimates (The “Causal Truth”)
The Instrumental Variables (IV) technique was
utilized to isolate the true effect. The random assignment
(Random Assignment) serves as an instrument for enrollment
(Participation Status), filtering out selection bias.
# Replace workplace wellness variable with 0 for observations in the control group
my_data$`Participation Status`[is.na(my_data$`Participation Status`)] <- 0
# Estimate the first stage
first_stage <- lm(`Participation Status` ~ `Random Assignment`, data = my_data, weights = `Insurance Coverage Weight`)
# Estimate the reduced form
rf <- lm(`Outcome Total Spending` ~ `Random Assignment`, data = my_data, weights = `Insurance Coverage Weight`)
# Estimate 2SLS
iv <- ivreg(`Outcome Total Spending` ~ `Participation Status` | `Random Assignment`, data = my_data, weights = `Insurance Coverage Weight`)
# Report results in a regression table
iv_models <- list(first_stage, rf, iv)
modelsummary(iv_models,
coef_omit = "(Intercept)",
vcov = "robust",
statistic = c("std.error", "statistic", "conf.int"), fmt = 4,
gof_map = c("nobs", "r.squared"),
title = "IV Estimates of the Effect of Wellness Program on Total Spending"
)
tinytable_4b929c24d0n68v7zhkxu
IV Estimates of the Effect of Wellness Program on Total Spending
| |
(1) |
(2) |
(3) |
| Random Assignment |
0.6135 |
10.8341 |
|
|
(0.0071) |
(48.5229) |
|
|
(86.8366) |
(0.2233) |
|
|
[0.5997, 0.6274] |
[-84.3046, 105.9728] |
|
| Participation Status |
|
|
17.6582 |
|
|
|
(79.0955) |
|
|
|
(0.2233) |
|
|
|
[-137.4242, 172.7405] |
| Num.Obs. |
3239 |
3239 |
3239 |
| R2 |
0.334 |
0.000 |
-0.000 |
Interpretation: The Final Verdict
- OLS (Biased): Suggested the program saves
~$150.
- IV (True Causal Effect): The coefficient is not
statistically significant (effectively zero).
The difference is stark. Adjusting for selection bias reveals that
the savings disappear. The program does not cause
employees to spend less. The OLS result was an artifact of healthy
people self-selecting into the program.
Conclusion
Recommendation to the Employer:
Do not count on this wellness program to cut medical
costs.
Rigorous analysis shows that the program has zero
impact on reducing healthcare spending. The apparent savings in
simple reports are misleading—reflecting only that healthy employees are
more likely to join wellness programs.
If the program is maintained for morale, recruiting, or employee
happiness, that is a valid choice. However, if the primary goal is
financial ROI from medical cost reduction, this program is not the
solution. Alternative strategies or a redesign targeting high-risk
employees should be considered.
LS0tDQp0aXRsZTogIkFzc2Vzc2luZyB3ZWxsbmVzcyBwcm9ncmFtbWUiDQphdXRob3I6ICJKb2huYnVsbCBPd2VudmJ1Z2llIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyBFeGVjdXRpdmUgU3VtbWFyeQ0KDQpUaGlzIHJlcG9ydCBpbnZlc3RpZ2F0ZXMgd2hldGhlciBhIHdvcmtwbGFjZSB3ZWxsbmVzcyBwcm9ncmFtIHJlZHVjZXMgZW1wbG95ZWUgbWVkaWNhbCBjb3N0cy4gVGhlIGFuYWx5c2lzIHV0aWxpemVzIGEgUmFuZG9taXplZCBDb250cm9sIFRyaWFsIChSQ1QpLCBjb25zaWRlcmVkIHRoZSBnb2xkIHN0YW5kYXJkIGZvciBjYXVzYWwgaW5mZXJlbmNlLg0KDQoqKlRoZSBCdXNpbmVzcyBRdWVzdGlvbjoqKiBEb2VzIG9mZmVyaW5nIGEgd2VsbG5lc3MgcHJvZ3JhbSByZWR1Y2UgbWVkaWNhbCBzcGVuZGluZz8NCg0KDQojIERhdGEgRGljdGlvbmFyeTogVW5kZXJzdGFuZGluZyB0aGUgVmFyaWFibGVzDQoNCktleSB2YXJpYWJsZXMgdXNlZCBpbiB0aGUgYW5hbHlzaXMgaW5jbHVkZToNCg0KKiAgICoqUmFuZG9tIEFzc2lnbm1lbnQqKjogMSA9IE9mZmVyZWQgdGhlIHByb2dyYW0sIDAgPSBOb3Qgb2ZmZXJlZC4NCiogICAqKlBhcnRpY2lwYXRpb24gU3RhdHVzKio6IDEgPSBFbnJvbGxlZCwgMCA9IERpZCBub3QgZW5yb2xsLg0KKiAgICoqSW5zdXJhbmNlIENvdmVyYWdlIFdlaWdodCoqOiBVc2VkIHRvIGFkanVzdCBmb3IgcGFydGlhbC15ZWFyIGVtcGxveWVlcy4NCiogICAqKkJhc2VsaW5lIFRvdGFsIFNwZW5kaW5nKio6IE1lZGljYWwgY29zdHMgYmVmb3JlIHRoZSBwcm9ncmFtICgyMDE1LTIwMTYpLg0KKiAgICoqT3V0Y29tZSBUb3RhbCBTcGVuZGluZyoqOiBNZWRpY2FsIGNvc3RzIGR1cmluZyB0aGUgcHJvZ3JhbSAoMjAxNi0yMDE3KS4NCiogICAqKkJhc2VsaW5lIEhvc3BpdGFsIFNwZW5kaW5nKio6IEhvc3BpdGFsIGNvc3RzICgyMDE1LTIwMTYpLg0KKiAgICoqQmFzZWxpbmUgT2ZmaWNlIFZpc2l0IFNwZW5kaW5nKio6IE9mZmljZSB2aXNpdCBjb3N0cyAoMjAxNS0yMDE2KS4NCiogICAqKk91dGNvbWUgSG9zcGl0YWwgU3BlbmRpbmcqKjogSG9zcGl0YWwgY29zdHMgKDIwMTYtMjAxNykuDQoqICAgKipPdXRjb21lIE9mZmljZSBWaXNpdCBTcGVuZGluZyoqOiBPZmZpY2UgdmlzaXQgY29zdHMgKDIwMTYtMjAxNykuDQoqICAgKipHZW5kZXIgKE1hbGUpKio6IDEgPSBNYWxlLCAwID0gRmVtYWxlLg0KKiAgICoqQWdlIDM3LTQ5Kio6IDEgPSAzNy00OSB5ZWFycyBvbGQuDQoqICAgKipBZ2UgNTArKio6IDEgPSA1MCsgeWVhcnMgb2xkLg0KKiAgICoqUmFjZSAoV2hpdGUpKio6IDEgPSBXaGl0ZS4NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9VFJVRX0NCiMgTG9hZCByZXF1aXJlZCBwYWNrYWdlcw0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KG1vZGVsc3VtbWFyeSkNCmxpYnJhcnkodnRhYmxlKQ0KbGlicmFyeShoYXZlbikNCmxpYnJhcnkoZXN0aW1hdHIpDQpsaWJyYXJ5KGl2cmVnKQ0KbGlicmFyeShzYW5kd2ljaCkNCmxpYnJhcnkoc2tpbXIpDQoNCiMgU2V0IGdsb2JhbCBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkNCg0KIyBMb2FkIGRhdGENCm15X2RhdGEgPC0gcmVhZF9kdGEoImh0dHBzOi8vcmVpZmp1bGlhbi5naXRodWIuaW8vaWxsaW5vaXMtd2VsbG5lc3MtZGF0YS9kYXRhL3N0YXRhL2NsYWltcy5kdGEiKQ0KDQojIFJlbmFtZSBjb2x1bW5zIHVzaW5nIEJhc2UgUiBiYXNlZCBvbiBkYXRhIGRpY3Rpb25hcnkNCm5hbWVzKG15X2RhdGEpW25hbWVzKG15X2RhdGEpID09ICJ0cmVhdCJdIDwtICJSYW5kb20gQXNzaWdubWVudCINCm5hbWVzKG15X2RhdGEpW25hbWVzKG15X2RhdGEpID09ICJocmFfY195cjEiXSA8LSAiUGFydGljaXBhdGlvbiBTdGF0dXMiDQpuYW1lcyhteV9kYXRhKVtuYW1lcyhteV9kYXRhKSA9PSAiY292Z18wODE2XzA3MTciXSA8LSAiSW5zdXJhbmNlIENvdmVyYWdlIFdlaWdodCINCm5hbWVzKG15X2RhdGEpW25hbWVzKG15X2RhdGEpID09ICJzcGVuZF8wNzE1XzA3MTYiXSA8LSAiQmFzZWxpbmUgVG90YWwgU3BlbmRpbmciDQpuYW1lcyhteV9kYXRhKVtuYW1lcyhteV9kYXRhKSA9PSAic3BlbmRfMDgxNl8wNzE3Il0gPC0gIk91dGNvbWUgVG90YWwgU3BlbmRpbmciDQpuYW1lcyhteV9kYXRhKVtuYW1lcyhteV9kYXRhKSA9PSAic3BlbmRIb3NwXzA3MTVfMDcxNiJdIDwtICJCYXNlbGluZSBIb3NwaXRhbCBTcGVuZGluZyINCm5hbWVzKG15X2RhdGEpW25hbWVzKG15X2RhdGEpID09ICJzcGVuZE9mZl8wNzE1XzA3MTYiXSA8LSAiQmFzZWxpbmUgT2ZmaWNlIFZpc2l0IFNwZW5kaW5nIg0KbmFtZXMobXlfZGF0YSlbbmFtZXMobXlfZGF0YSkgPT0gInNwZW5kSG9zcF8wODE2XzA3MTciXSA8LSAiT3V0Y29tZSBIb3NwaXRhbCBTcGVuZGluZyINCm5hbWVzKG15X2RhdGEpW25hbWVzKG15X2RhdGEpID09ICJzcGVuZE9mZl8wODE2XzA3MTciXSA8LSAiT3V0Y29tZSBPZmZpY2UgVmlzaXQgU3BlbmRpbmciDQpuYW1lcyhteV9kYXRhKVtuYW1lcyhteV9kYXRhKSA9PSAibWFsZSJdIDwtICJHZW5kZXIgKE1hbGUpIg0KbmFtZXMobXlfZGF0YSlbbmFtZXMobXlfZGF0YSkgPT0gImFnZTM3XzQ5Il0gPC0gIkFnZSAzNy00OSINCm5hbWVzKG15X2RhdGEpW25hbWVzKG15X2RhdGEpID09ICJhZ2U1MCJdIDwtICJBZ2UgNTArIg0KbmFtZXMobXlfZGF0YSlbbmFtZXMobXlfZGF0YSkgPT0gIndoaXRlIl0gPC0gIlJhY2UgKFdoaXRlKSINCg0KIyBDcmVhdGUgZ3JvdXBpbmcgdmFyaWFibGVzIGZvciBhbmFseXNpcw0KbXlfZGF0YSRgRW5yb2xsbWVudCBTdGF0dXNgIDwtIGlmZWxzZShteV9kYXRhJGBQYXJ0aWNpcGF0aW9uIFN0YXR1c2AgPT0gMSwgIkVucm9sbGVkIiwgIk5vdCBFbnJvbGxlZCIpDQpteV9kYXRhJGBUcmVhdG1lbnQgR3JvdXBgIDwtIGlmZWxzZShteV9kYXRhJGBSYW5kb20gQXNzaWdubWVudGAgPT0gMSwgIlRyZWF0bWVudCIsICJDb250cm9sIikNCg0KIyBJbnNwZWN0IGRhdGENCnNraW0obXlfZGF0YSkNCmBgYA0KDQojIFN1bW1hcnkgU3RhdGlzdGljcyBBbW9uZyBFbXBsb3llcnMgV2l0aCBXb3JrcGxhY2UgV2VsbG5lc3MgUHJvZ3JhbXMNCg0KVGhlIGluaXRpYWwgYW5hbHlzaXMgZm9jdXNlcyBvbiBlbXBsb3llZXMgb2ZmZXJlZCB0aGUgcHJvZ3JhbSAoYFJhbmRvbSBBc3NpZ25tZW50ID09IDFgKSwgY29tcGFyaW5nIHRob3NlIHdobyBjaG9zZSB0byBlbnJvbGwgdmVyc3VzIHRob3NlIHdobyBkaWQgbm90Lg0KDQpgYGB7cn0NCiMgRmlsdGVyIGZvciBlbXBsb3llZXMgb2ZmZXJlZCB0aGUgcHJvZ3JhbQ0Kb25seV90cmVhdCA8LSBzdWJzZXQobXlfZGF0YSwgYFJhbmRvbSBBc3NpZ25tZW50YCA9PSAxKQ0KDQojIFN1bW1hcnkgb2YgZW1wbG95ZWUgY2hhcmFjdGVyaXN0aWNzIGJ5IGVucm9sbG1lbnQNCnN1bXRhYmxlKA0KICBvbmx5X3RyZWF0LA0KICB2YXJzID0gYygNCiAgICAiR2VuZGVyIChNYWxlKSIsICJBZ2UgMzctNDkiLCAiQWdlIDUwKyIsICJSYWNlIChXaGl0ZSkiLA0KICAgICJCYXNlbGluZSBIb3NwaXRhbCBTcGVuZGluZyIsICJCYXNlbGluZSBPZmZpY2UgVmlzaXQgU3BlbmRpbmciLCAiQmFzZWxpbmUgVG90YWwgU3BlbmRpbmciDQogICksDQogIGdyb3VwID0gIkVucm9sbG1lbnQgU3RhdHVzIiwNCiAgdGl0bGUgPSAiU3VtbWFyeSBvZiBFbXBsb3llZSBDaGFyYWN0ZXJpc3RpY3MgYnkgV2VsbG5lc3MgUHJvZ3JhbSBFbnJvbGxtZW50IiwNCiAgb3V0ID0gImthYmxlIg0KKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKQ0KDQojIFN1bW1hcnkgb2YgaGVhbHRoIG91dGNvbWVzIGJ5IGVucm9sbG1lbnQNCnN1bXRhYmxlKA0KICBvbmx5X3RyZWF0LA0KICB2YXJzID0gYygiT3V0Y29tZSBIb3NwaXRhbCBTcGVuZGluZyIsICJPdXRjb21lIE9mZmljZSBWaXNpdCBTcGVuZGluZyIsICJPdXRjb21lIFRvdGFsIFNwZW5kaW5nIiksDQogIGdyb3VwID0gIkVucm9sbG1lbnQgU3RhdHVzIiwNCiAgdGl0bGUgPSAiU3VtbWFyeSBvZiBIZWFsdGggT3V0Y29tZXMgYnkgV2VsbG5lc3MgUHJvZ3JhbSBFbnJvbGxtZW50IiwNCiAgb3V0ID0gImthYmxlIg0KKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKQ0KYGBgDQoNCk5vdywgbGV0J3MgdmlzdWFsaXplIHRoZSBzcGVuZGluZyBkaWZmZXJlbmNlcy4NCg0KYGBge3J9DQojIFBsb3QgZGlzdHJpYnV0aW9uIG9mIGhlYWx0aGNhcmUgc3BlbmRpbmcgYnkgZW5yb2xsbWVudA0KZ2dwbG90KA0KICBkYXRhID0gb25seV90cmVhdCwNCiAgYWVzKA0KICAgIHggPSBsb2coYE91dGNvbWUgVG90YWwgU3BlbmRpbmdgICsgMSksDQogICAgZmlsbCA9IGFzLmZhY3RvcihgRW5yb2xsbWVudCBTdGF0dXNgKSwNCiAgICBjb2xvciA9IGFzLmZhY3RvcihgRW5yb2xsbWVudCBTdGF0dXNgKQ0KICApDQopICsNCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC40LCBuYS5ybSA9IFRSVUUpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgVG90YWwgSGVhbHRoY2FyZSBTcGVuZGluZyBieSBFbnJvbGxtZW50IiwNCiAgICB4ID0gIlRvdGFsIFNwZW5kaW5nICgyMDE24oCTMjAxNykiLA0KICAgIHkgPSAiRGVuc2l0eSIsDQogICAgZmlsbCA9ICJFbnJvbGxtZW50IFN0YXR1cyIsDQogICAgY29sb3IgPSAiRW5yb2xsbWVudCBTdGF0dXMiDQogICkNCg0KIyBCb3ggcGxvdCBvZiBsb2cgb3V0Y29tZSBzcGVuZGluZyB0byB2aXN1YWxpemUgb3V0bGllcnMNCmdncGxvdCgNCiAgZGF0YSA9IG9ubHlfdHJlYXQsDQogIGFlcyh4ID0gYEVucm9sbG1lbnQgU3RhdHVzYCwgeSA9IGxvZyhgT3V0Y29tZSBUb3RhbCBTcGVuZGluZ2AgKyAxKSwgZmlsbCA9IGBFbnJvbGxtZW50IFN0YXR1c2ApDQopICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkJveCBQbG90IG9mIEhlYWx0aGNhcmUgU3BlbmRpbmcgYnkgRW5yb2xsbWVudCIsDQogICAgeCA9ICJFbnJvbGxtZW50IFN0YXR1cyIsDQogICAgeSA9ICJUb3RhbCBTcGVuZGluZyAoMjAxNuKAkzIwMTcpIiwNCiAgICBmaWxsID0gIkVucm9sbG1lbnQgU3RhdHVzIg0KICApDQpgYGANCg0KKipJbnRlcnByZXRhdGlvbjogVGhlICJTZWxlY3Rpb24gQmlhcyIgVHJhcCoqDQoNClRoZSB0YWJsZSBhbmQgcGxvdHMgaW5kaWNhdGUgdGhhdCBlbXBsb3llZXMgd2hvIGVucm9sbGVkIGluIHRoZSBwcm9ncmFtIHNwZW50IHNpZ25pZmljYW50bHkgbGVzcyBtb25leSAqYmVmb3JlIHRoZSBwcm9ncmFtIGV2ZW4gc3RhcnRlZCogKEJhc2VsaW5lIFNwZW5kaW5nKS4NCg0KVGhpcyBpbGx1c3RyYXRlcyAqKlNlbGVjdGlvbiBCaWFzKiouIFBhcnRpY2lwYW50cyBpbiB3ZWxsbmVzcyBwcm9ncmFtcyBhcmUgdHlwaWNhbGx5IHRob3NlIHdobyBhcmUgYWxyZWFkeSBoZWFsdGh5IGFuZCBoZWFsdGgtY29uc2Npb3VzLiBDb25zZXF1ZW50bHksIG9ic2VydmVkIGxvd2VyIGNvc3RzIG1heSByZWZsZWN0IHByZS1leGlzdGluZyBoZWFsdGggc3RhdHVzIHJhdGhlciB0aGFuIHByb2dyYW0gZWZmZWN0aXZlbmVzcy4gQ29tcGFyaW5nIGVucm9sbGVlcyB0byBub24tZW5yb2xsZWVzIHdpdGhvdXQgYWRqdXN0bWVudCBsZWFkcyB0byBiaWFzZWQgY29uY2x1c2lvbnMuDQoNCiMgUmVncmVzc2lvbiBBbmFseXNpcyAoVGhlICJCaWFzZWQgVmlldyIpDQoNClN0YW5kYXJkIHN0YXRpc3RpY2FsIGFuYWx5c2lzIChPTFMgUmVncmVzc2lvbikgcHJvdmlkZXMgZXN0aW1hdGVzIGlmIHNlbGVjdGlvbiBiaWFzIGlzIGlnbm9yZWQuDQoNCmBgYHtyfQ0KIyBCYXNlbGluZSBtb2RlbA0KYmFzZWxpbmUgPC0gbG0oYE91dGNvbWUgVG90YWwgU3BlbmRpbmdgIH4gYFBhcnRpY2lwYXRpb24gU3RhdHVzYCwgZGF0YSA9IG9ubHlfdHJlYXQsIHdlaWdodHMgPSBgSW5zdXJhbmNlIENvdmVyYWdlIFdlaWdodGApDQoNCiMgQWRkIGFkZGl0aW9uYWwgbW9kZWxzIHdpdGggY29udHJvbHMNCndpdGhfY29udHJvbHMgPC0gbG0oYE91dGNvbWUgVG90YWwgU3BlbmRpbmdgIH4gYFBhcnRpY2lwYXRpb24gU3RhdHVzYCArIGBHZW5kZXIgKE1hbGUpYCArIGBBZ2UgMzctNDlgICsgYEFnZSA1MCtgICsgYFJhY2UgKFdoaXRlKWAsIGRhdGEgPSBvbmx5X3RyZWF0LCB3ZWlnaHRzID0gYEluc3VyYW5jZSBDb3ZlcmFnZSBXZWlnaHRgKQ0KDQojIFByZXNlbnQgaW4gYSByZWdyZXNzaW9uIHRhYmxlDQptb2RlbHMgPC0gbGlzdChiYXNlbGluZSwgd2l0aF9jb250cm9scykNCm1vZGVsc3VtbWFyeShtb2RlbHMsDQogIGNvZWZfb21pdCA9ICIoSW50ZXJjZXB0KSIsDQogIHN0YXRpc3RpYyA9IGMoInN0ZC5lcnJvciIsICJzdGF0aXN0aWMiLCAiY29uZi5pbnQiKSwgZm10ID0gNCwNCiAgZ29mX21hcCA9IGMoIm5vYnMiLCAici5zcXVhcmVkIiksDQogIHZjb3YgPSAiSEMxIiwNCiAgdGl0bGUgPSAiT0xTIEVzdGltYXRlcyBvZiB0aGUgRWZmZWN0IG9mIFdlbGxuZXNzIFByb2dyYW0gb24gVG90YWwgU3BlbmRpbmciDQopDQpgYGANCg0KKipJbnRlcnByZXRhdGlvbjogVGhlICJIZWFsdGh5IFVzZXIiIEVmZmVjdCoqDQoNClRoZSByZWdyZXNzaW9uIHJlc3VsdHMgc2hvdyBhIG5lZ2F0aXZlIGNvZWZmaWNpZW50IGZvciB0aGUgcHJvZ3JhbSBlZmZlY3QsIHN1Z2dlc3RpbmcgdGhhdCBlbnJvbGxpbmcgcmVkdWNlcyBzcGVuZGluZyBieSBhYm91dCAkMTM3IHRvICQxNTIuDQoNCkhvd2V2ZXIsIHRoaXMgcmVzdWx0IGlzIG1pc2xlYWRpbmcgYXMgaXQgY2FwdHVyZXMgdGhlICoqIkhlYWx0aHkgVXNlciIgZWZmZWN0KiouIFRoZSBhbmFseXNpcyBjcmVkaXRzIHRoZSBwcm9ncmFtIGZvciB0aGUgcGFydGljaXBhbnRzJyB1bmRlcmx5aW5nIGdvb2QgaGVhbHRoLiBTaW5jZSAiaGVhbHRoaW5lc3MiIGlzIG5vdCBwZXJmZWN0bHkgbWVhc3VyZWQgYnkgYWdlIGFuZCBnZW5kZXIgYWxvbmUsIHRoZSByZWdyZXNzaW9uIGNhbm5vdCBmdWxseSBzZXBhcmF0ZSB0aGUgcHJvZ3JhbSdzIGVmZmVjdCBmcm9tIHRoZSBwYXJ0aWNpcGFudHMnIHByZS1leGlzdGluZyBoZWFsdGguIFJlbHlpbmcgb24gdGhlc2UgcmVzdWx0cyB3b3VsZCBsZWFkIHRvIGluY29ycmVjdCBidXNpbmVzcyBkZWNpc2lvbnMuDQoNCiMgQ29tcGFyaXNvbiBvZiBUcmVhdG1lbnQgYW5kIENvbnRyb2wgR3JvdXBzIChUaGUgIlJlYWxpdHkgQ2hlY2siKQ0KDQpUaGUgUmFuZG9taXplZCBDb250cm9sIFRyaWFsIChSQ1QpIGRlc2lnbiBhZGRyZXNzZXMgdGhpcyBpc3N1ZS4gSW4gYW4gUkNULCBpbmRpdmlkdWFscyBhcmUgcmFuZG9tbHkgYXNzaWduZWQgdG8gYmUgKm9mZmVyZWQqIHRoZSBwcm9ncmFtIG9yIG5vdC4gVGhpcyByYW5kb21pemF0aW9uIGNyZWF0ZXMgdHdvIHN0YXRpc3RpY2FsbHkgaWRlbnRpY2FsIGdyb3Vwcy4NCg0KYGBge3J9DQojIENyZWF0ZSBhIHRhYmxlIHN1bW1hcml6aW5nIHRoZSBjaGFyYWN0ZXJpc3RpY3MgZm9yIHRyZWF0ZWQgYW5kIHVudHJlYXRlZCBlbnJvbGxlZXMNCnN1bXRhYmxlKG15X2RhdGEsDQogIHZhcnMgPSBjKCJHZW5kZXIgKE1hbGUpIiwgIkFnZSAzNy00OSIsICJBZ2UgNTArIiwgIlJhY2UgKFdoaXRlKSIsICJCYXNlbGluZSBIb3NwaXRhbCBTcGVuZGluZyIsICJCYXNlbGluZSBPZmZpY2UgVmlzaXQgU3BlbmRpbmciLCAiQmFzZWxpbmUgVG90YWwgU3BlbmRpbmciKSwNCiAgZ3JvdXAgPSAiVHJlYXRtZW50IEdyb3VwIiwgdGl0bGUgPSAiQ29tcGFyaXNvbiBvZiBCYXNlbGluZSBDaGFyYWN0ZXJpc3RpY3MgYnkgVHJlYXRtZW50IEdyb3VwIiwgb3V0ID0gImthYmxlIg0KKSAlPiUNCiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZyhmdWxsX3dpZHRoID0gVFJVRSwgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpKQ0KDQojIFRlc3Qgd2hldGhlciBjaGFyYWN0ZXJpc3RpY3MgYXJlIGRpZmZlcmVudA0KdC50ZXN0KGBHZW5kZXIgKE1hbGUpYCB+IGBSYW5kb20gQXNzaWdubWVudGAsIGRhdGEgPSBteV9kYXRhKQ0KdC50ZXN0KGBBZ2UgMzctNDlgIH4gYFJhbmRvbSBBc3NpZ25tZW50YCwgZGF0YSA9IG15X2RhdGEpDQp0LnRlc3QoYEFnZSA1MCtgIH4gYFJhbmRvbSBBc3NpZ25tZW50YCwgZGF0YSA9IG15X2RhdGEpDQp0LnRlc3QoYFJhY2UgKFdoaXRlKWAgfiBgUmFuZG9tIEFzc2lnbm1lbnRgLCBkYXRhID0gbXlfZGF0YSkNCnQudGVzdChgQmFzZWxpbmUgSG9zcGl0YWwgU3BlbmRpbmdgIH4gYFJhbmRvbSBBc3NpZ25tZW50YCwgZGF0YSA9IG15X2RhdGEpDQp0LnRlc3QoYEJhc2VsaW5lIE9mZmljZSBWaXNpdCBTcGVuZGluZ2AgfiBgUmFuZG9tIEFzc2lnbm1lbnRgLCBkYXRhID0gbXlfZGF0YSkNCnQudGVzdChgQmFzZWxpbmUgVG90YWwgU3BlbmRpbmdgIH4gYFJhbmRvbSBBc3NpZ25tZW50YCwgZGF0YSA9IG15X2RhdGEpDQpgYGANCg0KKipJbnRlcnByZXRhdGlvbjogV2h5ICJObyBEaWZmZXJlbmNlIiBpcyBHb29kKioNCg0KVC10ZXN0cyB3ZXJlIGNvbmR1Y3RlZCB0byBjb21wYXJlIHRoZSAiVHJlYXRtZW50IiBncm91cCAob2ZmZXJlZCB0aGUgcHJvZ3JhbSkgYW5kIHRoZSAiQ29udHJvbCIgZ3JvdXAgKG5vdCBvZmZlcmVkKS4gVGhlIHJlc3VsdHMgc2hvdyAqKm5vIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSoqIGJldHdlZW4gdGhlbSBpbiB0ZXJtcyBvZiBhZ2UsIGdlbmRlciwgb3IgcGFzdCBzcGVuZGluZy4NCg0KVGhpcyBjb25maXJtcyB0aGF0IHRoZSByYW5kb21pemF0aW9uIHdhcyBzdWNjZXNzZnVsLiBUaGUgdHdvIGdyb3VwcyBhcmUgZWZmZWN0aXZlbHkgaWRlbnRpY2FsLiBBbnkgZGlmZmVyZW5jZSBpbiBmdXR1cmUgc3BlbmRpbmcgY2FuIGJlIGNvbmZpZGVudGx5IGF0dHJpYnV0ZWQgdG8gdGhlIHByb2dyYW0sIG5vdCB0byBwcmUtZXhpc3RpbmcgZGlmZmVyZW5jZXMuDQoNCiMgSVYgRXN0aW1hdGVzIChUaGUgIkNhdXNhbCBUcnV0aCIpDQoNClRoZSAqKkluc3RydW1lbnRhbCBWYXJpYWJsZXMgKElWKSoqIHRlY2huaXF1ZSB3YXMgdXRpbGl6ZWQgdG8gaXNvbGF0ZSB0aGUgdHJ1ZSBlZmZlY3QuIFRoZSByYW5kb20gYXNzaWdubWVudCAoYFJhbmRvbSBBc3NpZ25tZW50YCkgc2VydmVzIGFzIGFuIGluc3RydW1lbnQgZm9yIGVucm9sbG1lbnQgKGBQYXJ0aWNpcGF0aW9uIFN0YXR1c2ApLCBmaWx0ZXJpbmcgb3V0IHNlbGVjdGlvbiBiaWFzLg0KDQpgYGB7cn0NCiMgUmVwbGFjZSB3b3JrcGxhY2Ugd2VsbG5lc3MgdmFyaWFibGUgd2l0aCAwIGZvciBvYnNlcnZhdGlvbnMgaW4gdGhlIGNvbnRyb2wgZ3JvdXANCm15X2RhdGEkYFBhcnRpY2lwYXRpb24gU3RhdHVzYFtpcy5uYShteV9kYXRhJGBQYXJ0aWNpcGF0aW9uIFN0YXR1c2ApXSA8LSAwDQoNCiMgRXN0aW1hdGUgdGhlIGZpcnN0IHN0YWdlDQpmaXJzdF9zdGFnZSA8LSBsbShgUGFydGljaXBhdGlvbiBTdGF0dXNgIH4gYFJhbmRvbSBBc3NpZ25tZW50YCwgZGF0YSA9IG15X2RhdGEsIHdlaWdodHMgPSBgSW5zdXJhbmNlIENvdmVyYWdlIFdlaWdodGApDQoNCiMgRXN0aW1hdGUgdGhlIHJlZHVjZWQgZm9ybQ0KcmYgPC0gbG0oYE91dGNvbWUgVG90YWwgU3BlbmRpbmdgIH4gYFJhbmRvbSBBc3NpZ25tZW50YCwgZGF0YSA9IG15X2RhdGEsIHdlaWdodHMgPSBgSW5zdXJhbmNlIENvdmVyYWdlIFdlaWdodGApDQoNCiMgRXN0aW1hdGUgMlNMUw0KaXYgPC0gaXZyZWcoYE91dGNvbWUgVG90YWwgU3BlbmRpbmdgIH4gYFBhcnRpY2lwYXRpb24gU3RhdHVzYCB8IGBSYW5kb20gQXNzaWdubWVudGAsIGRhdGEgPSBteV9kYXRhLCB3ZWlnaHRzID0gYEluc3VyYW5jZSBDb3ZlcmFnZSBXZWlnaHRgKQ0KDQojIFJlcG9ydCByZXN1bHRzIGluIGEgcmVncmVzc2lvbiB0YWJsZQ0KaXZfbW9kZWxzIDwtIGxpc3QoZmlyc3Rfc3RhZ2UsIHJmLCBpdikNCm1vZGVsc3VtbWFyeShpdl9tb2RlbHMsDQogIGNvZWZfb21pdCA9ICIoSW50ZXJjZXB0KSIsDQogIHZjb3YgPSAicm9idXN0IiwNCiAgc3RhdGlzdGljID0gYygic3RkLmVycm9yIiwgInN0YXRpc3RpYyIsICJjb25mLmludCIpLCBmbXQgPSA0LA0KICBnb2ZfbWFwID0gYygibm9icyIsICJyLnNxdWFyZWQiKSwNCiAgdGl0bGUgPSAiSVYgRXN0aW1hdGVzIG9mIHRoZSBFZmZlY3Qgb2YgV2VsbG5lc3MgUHJvZ3JhbSBvbiBUb3RhbCBTcGVuZGluZyINCikNCmBgYA0KDQoqKkludGVycHJldGF0aW9uOiBUaGUgRmluYWwgVmVyZGljdCoqDQoNCiogICAqKk9MUyAoQmlhc2VkKToqKiBTdWdnZXN0ZWQgdGhlIHByb2dyYW0gc2F2ZXMgfiQxNTAuDQoqICAgKipJViAoVHJ1ZSBDYXVzYWwgRWZmZWN0KToqKiBUaGUgY29lZmZpY2llbnQgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKGVmZmVjdGl2ZWx5IHplcm8pLg0KDQpUaGUgZGlmZmVyZW5jZSBpcyBzdGFyay4gQWRqdXN0aW5nIGZvciBzZWxlY3Rpb24gYmlhcyByZXZlYWxzIHRoYXQgKip0aGUgc2F2aW5ncyBkaXNhcHBlYXIqKi4gVGhlIHByb2dyYW0gZG9lcyBub3QgY2F1c2UgZW1wbG95ZWVzIHRvIHNwZW5kIGxlc3MuIFRoZSBPTFMgcmVzdWx0IHdhcyBhbiBhcnRpZmFjdCBvZiBoZWFsdGh5IHBlb3BsZSBzZWxmLXNlbGVjdGluZyBpbnRvIHRoZSBwcm9ncmFtLg0KDQojIENvbmNsdXNpb24NCg0KKipSZWNvbW1lbmRhdGlvbiB0byB0aGUgRW1wbG95ZXI6KioNCg0KKipEbyBub3QgY291bnQgb24gdGhpcyB3ZWxsbmVzcyBwcm9ncmFtIHRvIGN1dCBtZWRpY2FsIGNvc3RzLioqDQoNClJpZ29yb3VzIGFuYWx5c2lzIHNob3dzIHRoYXQgdGhlIHByb2dyYW0gaGFzICoqemVybyBpbXBhY3QqKiBvbiByZWR1Y2luZyBoZWFsdGhjYXJlIHNwZW5kaW5nLiBUaGUgYXBwYXJlbnQgc2F2aW5ncyBpbiBzaW1wbGUgcmVwb3J0cyBhcmUgbWlzbGVhZGluZ+KAlHJlZmxlY3Rpbmcgb25seSB0aGF0IGhlYWx0aHkgZW1wbG95ZWVzIGFyZSBtb3JlIGxpa2VseSB0byBqb2luIHdlbGxuZXNzIHByb2dyYW1zLg0KDQpJZiB0aGUgcHJvZ3JhbSBpcyBtYWludGFpbmVkIGZvciBtb3JhbGUsIHJlY3J1aXRpbmcsIG9yIGVtcGxveWVlIGhhcHBpbmVzcywgdGhhdCBpcyBhIHZhbGlkIGNob2ljZS4gSG93ZXZlciwgaWYgdGhlIHByaW1hcnkgZ29hbCBpcyBmaW5hbmNpYWwgUk9JIGZyb20gbWVkaWNhbCBjb3N0IHJlZHVjdGlvbiwgdGhpcyBwcm9ncmFtIGlzIG5vdCB0aGUgc29sdXRpb24uIEFsdGVybmF0aXZlIHN0cmF0ZWdpZXMgb3IgYSByZWRlc2lnbiB0YXJnZXRpbmcgaGlnaC1yaXNrIGVtcGxveWVlcyBzaG91bGQgYmUgY29uc2lkZXJlZC4NCg==