Question 1


One researcher (Dr. Boom) is convinced that kids born in the early 80s are more successful than those born in the mid-80s. He believes that this effect is “generational” where adults born in the early 80s will perform better in life than those born in the mid-80s. Based on this data, Dr. Boom examines the relationship between year born and income.

1.1) Create a plot with YearBorn on the X-axis and Income2008 on the Y-axis.
# Plot

library(ggplot2)

NLSdata = NLSdata

ggplot(NLSdata, aes(x = YearBorn, y = Income2008)) +
  geom_point() +
  geom_smooth(method = "lm", se = TRUE, color = "red") +
  theme_minimal(base_family = "Times New Roman") +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text = element_text(size = 12, face = "plain", family = "Times New Roman"),
    axis.title = element_text(size = 13, face = "plain", family = "Times New Roman"),
    plot.title = element_text(size = 16, face = "bold", family = "Times New Roman", hjust = 0.5)
  ) +
  labs(
    x = "Year of Birth",
    y = "Income 2008",
    title = "Income v. Birth Year"
  )


1.2) Use SPSS to fit a simple linear regression predicting Income2008 from YearBorn. Include code and output.

library(stats)

# Fit Linear Regression Model
modelIncomeBorn <- lm(Income2008 ~ YearBorn, data = NLSdata)

summary(modelIncomeBorn)

Call:
lm(formula = Income2008 ~ YearBorn, data = NLSdata)

Residuals:
   Min     1Q Median     3Q    Max 
-35556 -14406  -3214   9444  95779 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 4659987.3   475120.5   9.808   <2e-16 ***
YearBorn      -2335.6      239.7  -9.743   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 21620 on 4222 degrees of freedom
Multiple R-squared:  0.02199,   Adjusted R-squared:  0.02176 
F-statistic: 94.93 on 1 and 4222 DF,  p-value: < 2.2e-16

Question 3

Dr. Boom is convinced by his result and wants to write a paper published in Nature right
away! His colleague Dr. Mill has some doubts. Dr. Mill notices that the dataset also has the
ASVAB, which is the Armed Services Vocational Aptitude Battery, which is used by the US
military to determine qualifications for different positions. The ASVAB measures many
ability constructs such as general science, arithmetic, vocabulary, reading comprehension,
mathematics, etc. Higher scores on the ASVAB should suggest higher intellectual and
practical acumen (think of it as similar to an IQ test). Dr. Mill suggests they consider a
multiple linear regression where they predict Income2008 using both YearBorn and
ASVAB. Dr. Boom agrees. Dr. Boom says “Well because ASVAB is a measure of intellect and
skill, I think that when it is introduced to the model, the relationship between birth year and
income will go away. All of the variance that birth year explains in income should be shared
variance with the ASVAB. So birth year will not uniquely predict income.”

3.2) Fit a multiple linear regression model predicting Income2008 using both YearBorn
and ASVAB. Include your code and output.

# Fit Multiple Linear Regression Model
modelmultipleregression <- lm(Income2008 ~ YearBorn + ASVAB, data = NLSdata)

summary(modelmultipleregression)

Call:
lm(formula = Income2008 ~ YearBorn + ASVAB, data = NLSdata)

Residuals:
   Min     1Q Median     3Q    Max 
-44998 -13702  -2832   9390 104029 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.689e+06  4.582e+05   10.23   <2e-16 ***
YearBorn    -2.355e+03  2.312e+02  -10.19   <2e-16 ***
ASVAB        1.997e-01  1.120e-02   17.83   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 20860 on 4221 degrees of freedom
Multiple R-squared:  0.09049,   Adjusted R-squared:  0.09006 
F-statistic:   210 on 2 and 4221 DF,  p-value: < 2.2e-16

Question 6


Dr. Boom says “It’s hard to tell how good the model is overall! I wish there was just a simple
correlation coefficient to tell me how good this model is!” Dr. Mill says, “There is!” Calculate
R from the data, provide an interpretation of the estimate, and provide a visualization of
the correlation between the observed and predicted incomes.

library (stats)

# Predicted Values From the Model
predicted_values_ps2 <- predict(modelmultipleregression)

# Calculate the correlation coefficient (R)
R_ps2 <- cor(NLSdata$Income2008, predicted_values_ps2)

print(R_ps2)
[1] 0.3008149
# Plot of Predicted Values

library(ggplot2)

ggplot(NLSdata, aes(x = Income2008, y = predicted_values_ps2)) + 
  geom_point() + 
  geom_abline(intercept = 0, slope = 1, color = "red", size = 1.5) +
  theme_minimal(base_family = "Times New Roman")+
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text = element_text(size = 12, face = "plain", family = "Times New Roman"),
    axis.title = element_text(size = 13, face = "plain", family = "Times New Roman"),
    plot.title = element_text(size = 16, face = "bold", family = "Times New Roman", hjust = 0.5)
  ) +
  labs(title = "Correlation between Observed and Predicted Incomes", x = "Observed Income in 2008", y = "Predicted Income in 2008") 


Question 7


Consider the predicted values from the model. What would the model predicted Income in
2008 be for an individual born in 1984, with an ASVAB score of 75000. Show your work in
how you calculated this estimate.

# Dataframe for Prediction
dataframe_ps2 <- data.frame(YearBorn = 1984, ASVAB = 75000)

# Get the Predicted income
predicted_income <- predict(modelmultipleregression, newdata = dataframe_ps2)

print(predicted_income)
      1 
31238.8 

Question 8


Dr. Boom says “I like correlation coefficients very much. I find them very interpretable. Is
there a way to quantify the unique contributions of each variable to the prediction of
income using a correlation metric?” Dr. Mill says “Yes, in fact, there are two! Let’s look at
the partial and semi-partial correlations.”

8.1) Calculate the partial correlation between Income2008 and YearBorn, partialing out
ASVAB. Provide an estimate, an interpretation of the estimate, and a scatterplot that
aligns with the estimate (represent the two partialed variables which are used to
calculate the correlation).

# Using the PPCor Package

library(ppcor)

# Partial correlation
partial_correlation_income_year <- pcor.test(NLSdata$Income2008, NLSdata$YearBorn, NLSdata$ASVAB, method = "pearson")

print(partial_correlation_income_year)
# Hardcoded R 

# Regress Income2008 on ASVAB
model_income_on_asvab <- lm(Income2008 ~ ASVAB, data = NLSdata)
residuals_income <- residuals(model_income_on_asvab)

# Regress YearBorn on ASVAB
model_yearborn_on_asvab <- lm(YearBorn ~ ASVAB, data = NLSdata)
residuals_yearborn <- residuals(model_yearborn_on_asvab)

# Correlation of Residuals
partial_cor_income2008yearborn <- cor(residuals_income, residuals_yearborn)

print(partial_cor_income2008yearborn)
[1] -0.154896
partial_residuals_df <- data.frame(residuals_income = residuals_income, residuals_yearborn = residuals_yearborn)

# Plots Residuals

library(ggplot2)

ggplot(partial_residuals_df, aes(x = residuals_yearborn, y = residuals_income)) +
  geom_point() + 
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  theme_minimal(base_family = "Times New Roman") +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text = element_text(size = 11, face = "plain", family = "Times New Roman"),
    axis.title = element_text(size = 12, face = "plain", family = "Times New Roman"),
    plot.title = element_text(size = 14, face = "bold", family = "Times New Roman", hjust = 0.5)
  ) +
  labs(x = "Residuals for Year of Birth (controlling for ASVAB)",
       y = "Residuals for Income in 2008 (controlling for ASVAB)",
       title = "Partial Correlation between Income in 2008 and Year of Birth")


8.2) Calculate the semipartial correlation between Income2008 and YearBorn,
partialling out ASVAB. Provide an estimate, an interpretation of the estimate, and a
scatterplot that aligns with the estimate (represent the one partialed variables which
are used to calculate the correlation).

# Using PPcor Package
library(ppcor)

# Semi-partial correlation
semi_partial_correlation_income_year <- spcor.test(NLSdata$Income2008, NLSdata$YearBorn, NLSdata$ASVAB, method = "pearson")

print(semi_partial_correlation_income_year)
NA
# Hardcoded R 

# Regress Income2008 on ASVAB alone
model_income_on_asvab_only <- lm(Income2008 ~ ASVAB, data = NLSdata)
residuals_from_asvab_only <- residuals(model_income_on_asvab_only)

semipartial_cor_income2008yearborn <- cor(NLSdata$YearBorn, residuals_from_asvab_only)

print(semipartial_cor_income2008yearborn)
[1] -0.1548942
semi_residuals_df <- data.frame(YearBorn = NLSdata$YearBorn, residuals_income = residuals_from_asvab_only)

# Plots Semipartial

library(ggplot2)

ggplot(semi_residuals_df, aes(x = YearBorn, y = residuals_income)) +
  geom_point() + 
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  theme_minimal(base_family = "Times New Roman") +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text = element_text(size = 11, face = "plain", family = "Times New Roman"),
    axis.title = element_text(size = 12, face = "plain", family = "Times New Roman"),
    plot.title = element_text(size = 14, face = "bold", family = "Times New Roman", hjust = 0.5)
  ) +
  labs(x = "Year of Birth",
       y = "Residuals for Income in 2008 (controlling for ASVAB)",
       title = "Semi-Partial Correlation")


8.4) Calculate the partial correlation between Income2008 and ASVAB, partialing out
YearBorn. Provide an estimate, an interpretation of the estimate, and a scatterplot
that aligns with the estimate (represent the two partialed variables which are used to
calculate the correlation).

# Using the PPCor Package

library(ppcor)

# Partial correlation
partial_correlation_income_asvab <- pcor.test(NLSdata$Income2008, NLSdata$ASVAB, NLSdata$YearBorn, method = "pearson")

print(partial_correlation_income_asvab)
NA
# Hardcoded R 

# Regress Income2008 on YearBorn
model_income2008_on_yearborn <- lm(Income2008 ~ YearBorn, data = NLSdata)
residuals_income2008 <- residuals(model_income2008_on_yearborn)

# Regress ASVAB on YearBorn
model_ASVAB_on_yearborn <- lm(ASVAB ~ YearBorn, data = NLSdata)
residuals_ASVAB <- residuals(model_ASVAB_on_yearborn)

# Correlations on Residuals
partial_cor_income2008asvab <- cor(residuals_income2008, residuals_ASVAB)

print(partial_cor_income2008asvab)
[1] 0.26465
partial_residuals_df_2 <- data.frame(residuals_income = residuals_income2008, residuals_ASVAB = residuals_ASVAB)

# Plots Residuals

library(ggplot2)

ggplot(partial_residuals_df_2, aes(x = residuals_ASVAB, y = residuals_income2008)) +
  geom_point() + 
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  theme_minimal(base_family = "Times New Roman") +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text = element_text(size = 11, face = "plain", family = "Times New Roman"),
    axis.title = element_text(size = 12, face = "plain", family = "Times New Roman"),
    plot.title = element_text(size = 14, face = "bold", family = "Times New Roman", hjust = 0.5)
  ) +
  labs(x = "Residuals of ASVAB (controlling for Year of Birth)",
       y = "Residuals for Income in 2008 (controlling for Year of Birth)",
       title = "Partial Correlation")


8.5) Calculate the semipartial correlation between Income2008 and ASVAB, partialing
out YearBorn. Provide an estimate, an interpretation of the estimate, and a
scatterplot that aligns with the estimate (represent the two partialed variables which
are used to calculate the correlation).

# Using the PPCor Package

library(ppcor)

# Semi-partial correlation
semi_partial_correlation_income_asvab <- spcor.test(NLSdata$Income2008, NLSdata$ASVAB, NLSdata$YearBorn, method = "pearson")

print(semi_partial_correlation_income_asvab)
NA
# Hardcoded R 

# Regress Income2008 on ASVAB alone
model_income_on_yearborn_only <- lm(Income2008 ~ YearBorn, data = NLSdata)
residuals_from_yearborn_only <- residuals(model_income_on_yearborn_only)

semipartial_cor_income2008asvab <- cor(NLSdata$ASVAB, residuals_from_yearborn_only)

print(semipartial_cor_income2008asvab)
[1] 0.2646471
semi_residuals_df_2 <- data.frame(ASVAB = NLSdata$ASVAB, residuals_yearborn = residuals_from_yearborn_only)

# Plots Semipartial

library(ggplot2)

ggplot(semi_residuals_df_2, aes(x = ASVAB, y = residuals_yearborn)) +
  geom_point() + 
  geom_smooth(method = "lm", color = "red", se = FALSE) +
  theme_minimal(base_family = "Times New Roman") +
  theme(
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text = element_text(size = 11, face = "plain", family = "Times New Roman"),
    axis.title = element_text(size = 12, face = "plain", family = "Times New Roman"),
    plot.title = element_text(size = 14, face = "bold", family = "Times New Roman", hjust = 0.5)
  ) +
  labs(x = "ASVAB Score",
       y = "Residuals for Income in 2008 (controlling for Year of Birth)",
       title = "Semi-Partial Correlation")

LS0tCnRpdGxlOiAiUHN5Y2ggMjUwQyAtIFByb2JsZW0gU2V0IDIgLSAzMDU5NDY2MjQiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMgKipRdWVzdGlvbiAxKioKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKfCBPbmUgcmVzZWFyY2hlciAoRHIuIEJvb20pIGlzIGNvbnZpbmNlZCB0aGF0IGtpZHMgYm9ybiBpbiB0aGUgZWFybHkgODBzIGFyZSBtb3JlIHN1Y2Nlc3NmdWwgdGhhbiB0aG9zZSBib3JuIGluIHRoZSBtaWQtODBzLiBIZSBiZWxpZXZlcyB0aGF0IHRoaXMgZWZmZWN0IGlzICJnZW5lcmF0aW9uYWwiIHdoZXJlIGFkdWx0cyBib3JuIGluIHRoZSBlYXJseSA4MHMgd2lsbCBwZXJmb3JtIGJldHRlciBpbiBsaWZlIHRoYW4gdGhvc2UgYm9ybiBpbiB0aGUgbWlkLTgwcy4gQmFzZWQgb24gdGhpcyBkYXRhLCBEci4gQm9vbSBleGFtaW5lcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4geWVhciBib3JuIGFuZCBpbmNvbWUuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnwgMS4xKSBDcmVhdGUgYSBwbG90IHdpdGggWWVhckJvcm4gb24gdGhlIFgtYXhpcyBhbmQgSW5jb21lMjAwOCBvbiB0aGUgWS1heGlzLgoKYGBge3J9CiMgUGxvdAoKTkxTZGF0YSA8LSByZWFkLmNzdigiLi4uL1BzeWNoIDI1MEMvUHJvYmxlbSBTZXRzL1BzeWNoIDI1MEMgUHJvYmxlbXMgU2V0cy9OTFNkYXRhLmNzdiIpCgpsaWJyYXJ5KGdncGxvdDIpCgpnZ3Bsb3QoTkxTZGF0YSwgYWVzKHggPSBZZWFyQm9ybiwgeSA9IEluY29tZTIwMDgpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUsIGNvbG9yID0gInJlZCIpICsKICB0aGVtZV9taW5pbWFsKGJhc2VfZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpICsKICB0aGVtZSgKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJwbGFpbiIsIGZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iLCBoanVzdCA9IDAuNSkKICApICsKICBsYWJzKAogICAgeCA9ICJZZWFyIG9mIEJpcnRoIiwKICAgIHkgPSAiSW5jb21lIDIwMDgiLAogICAgdGl0bGUgPSAiSW5jb21lIHYuIEJpcnRoIFllYXIiCiAgKQoKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnwgMS4yKSBVc2UgU1BTUyB0byBmaXQgYSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gcHJlZGljdGluZyBJbmNvbWUyMDA4IGZyb20gWWVhckJvcm4uIEluY2x1ZGUgY29kZSBhbmQgb3V0cHV0LgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KbGlicmFyeShzdGF0cykKCiMgRml0IExpbmVhciBSZWdyZXNzaW9uIE1vZGVsCm1vZGVsSW5jb21lQm9ybiA8LSBsbShJbmNvbWUyMDA4IH4gWWVhckJvcm4sIGRhdGEgPSBOTFNkYXRhKQoKc3VtbWFyeShtb2RlbEluY29tZUJvcm4pCgpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBRdWVzdGlvbiAzCgp8IERyLiBCb29tIGlzIGNvbnZpbmNlZCBieSBoaXMgcmVzdWx0IGFuZCB3YW50cyB0byB3cml0ZSBhIHBhcGVyIHB1Ymxpc2hlZCBpbiBOYXR1cmUgcmlnaHQKfCBhd2F5ISBIaXMgY29sbGVhZ3VlIERyLiBNaWxsIGhhcyBzb21lIGRvdWJ0cy4gRHIuIE1pbGwgbm90aWNlcyB0aGF0IHRoZSBkYXRhc2V0IGFsc28gaGFzIHRoZQp8IEFTVkFCLCB3aGljaCBpcyB0aGUgQXJtZWQgU2VydmljZXMgVm9jYXRpb25hbCBBcHRpdHVkZSBCYXR0ZXJ5LCB3aGljaCBpcyB1c2VkIGJ5IHRoZSBVUwp8IG1pbGl0YXJ5IHRvIGRldGVybWluZSBxdWFsaWZpY2F0aW9ucyBmb3IgZGlmZmVyZW50IHBvc2l0aW9ucy4gVGhlIEFTVkFCIG1lYXN1cmVzIG1hbnkKfCBhYmlsaXR5IGNvbnN0cnVjdHMgc3VjaCBhcyBnZW5lcmFsIHNjaWVuY2UsIGFyaXRobWV0aWMsIHZvY2FidWxhcnksIHJlYWRpbmcgY29tcHJlaGVuc2lvbiwKfCBtYXRoZW1hdGljcywgZXRjLiBIaWdoZXIgc2NvcmVzIG9uIHRoZSBBU1ZBQiBzaG91bGQgc3VnZ2VzdCBoaWdoZXIgaW50ZWxsZWN0dWFsIGFuZAp8IHByYWN0aWNhbCBhY3VtZW4gKHRoaW5rIG9mIGl0IGFzIHNpbWlsYXIgdG8gYW4gSVEgdGVzdCkuIERyLiBNaWxsIHN1Z2dlc3RzIHRoZXkgY29uc2lkZXIgYQp8IG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIHdoZXJlIHRoZXkgcHJlZGljdCBJbmNvbWUyMDA4IHVzaW5nIGJvdGggWWVhckJvcm4gYW5kCnwgQVNWQUIuIERyLiBCb29tIGFncmVlcy4gRHIuIEJvb20gc2F5cyAiV2VsbCBiZWNhdXNlIEFTVkFCIGlzIGEgbWVhc3VyZSBvZiBpbnRlbGxlY3QgYW5kCnwgc2tpbGwsIEkgdGhpbmsgdGhhdCB3aGVuIGl0IGlzIGludHJvZHVjZWQgdG8gdGhlIG1vZGVsLCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYmlydGggeWVhciBhbmQKfCBpbmNvbWUgd2lsbCBnbyBhd2F5LiBBbGwgb2YgdGhlIHZhcmlhbmNlIHRoYXQgYmlydGggeWVhciBleHBsYWlucyBpbiBpbmNvbWUgc2hvdWxkIGJlIHNoYXJlZAp8IHZhcmlhbmNlIHdpdGggdGhlIEFTVkFCLiBTbyBiaXJ0aCB5ZWFyIHdpbGwgbm90IHVuaXF1ZWx5IHByZWRpY3QgaW5jb21lLiIKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKfCAzLjIpIEZpdCBhIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsIHByZWRpY3RpbmcgSW5jb21lMjAwOCB1c2luZyBib3RoIFllYXJCb3JuCnwgYW5kIEFTVkFCLiBJbmNsdWRlIHlvdXIgY29kZSBhbmQgb3V0cHV0LgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KIyBGaXQgTXVsdGlwbGUgTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWwKbW9kZWxtdWx0aXBsZXJlZ3Jlc3Npb24gPC0gbG0oSW5jb21lMjAwOCB+IFllYXJCb3JuICsgQVNWQUIsIGRhdGEgPSBOTFNkYXRhKQoKc3VtbWFyeShtb2RlbG11bHRpcGxlcmVncmVzc2lvbikKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyMgUXVlc3Rpb24gNgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp8IERyLiBCb29tIHNheXMgIkl0J3MgaGFyZCB0byB0ZWxsIGhvdyBnb29kIHRoZSBtb2RlbCBpcyBvdmVyYWxsISBJIHdpc2ggdGhlcmUgd2FzIGp1c3QgYSBzaW1wbGUKfCBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCB0byB0ZWxsIG1lIGhvdyBnb29kIHRoaXMgbW9kZWwgaXMhIiBEci4gTWlsbCBzYXlzLCAiVGhlcmUgaXMhIiBDYWxjdWxhdGUKfCBSIGZyb20gdGhlIGRhdGEsIHByb3ZpZGUgYW4gaW50ZXJwcmV0YXRpb24gb2YgdGhlIGVzdGltYXRlLCBhbmQgcHJvdmlkZSBhIHZpc3VhbGl6YXRpb24gb2YKfCB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgb2JzZXJ2ZWQgYW5kIHByZWRpY3RlZCBpbmNvbWVzLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KbGlicmFyeSAoc3RhdHMpCgojIFByZWRpY3RlZCBWYWx1ZXMgRnJvbSB0aGUgTW9kZWwKcHJlZGljdGVkX3ZhbHVlc19wczIgPC0gcHJlZGljdChtb2RlbG11bHRpcGxlcmVncmVzc2lvbikKCiMgQ2FsY3VsYXRlIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCAoUikKUl9wczIgPC0gY29yKE5MU2RhdGEkSW5jb21lMjAwOCwgcHJlZGljdGVkX3ZhbHVlc19wczIpCgpwcmludChSX3BzMikKYGBgCgpgYGB7cn0KIyBQbG90IG9mIFByZWRpY3RlZCBWYWx1ZXMKCmxpYnJhcnkoZ2dwbG90MikKCmdncGxvdChOTFNkYXRhLCBhZXMoeCA9IEluY29tZTIwMDgsIHkgPSBwcmVkaWN0ZWRfdmFsdWVzX3BzMikpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMS41KSArCiAgdGhlbWVfbWluaW1hbChiYXNlX2ZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iKSsKICB0aGVtZSgKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgZmFjZSA9ICJwbGFpbiIsIGZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEzLCBmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTYsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iLCBoanVzdCA9IDAuNSkKICApICsKICBsYWJzKHRpdGxlID0gIkNvcnJlbGF0aW9uIGJldHdlZW4gT2JzZXJ2ZWQgYW5kIFByZWRpY3RlZCBJbmNvbWVzIiwgeCA9ICJPYnNlcnZlZCBJbmNvbWUgaW4gMjAwOCIsIHkgPSAiUHJlZGljdGVkIEluY29tZSBpbiAyMDA4IikgCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjIFF1ZXN0aW9uIDcKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKfCBDb25zaWRlciB0aGUgcHJlZGljdGVkIHZhbHVlcyBmcm9tIHRoZSBtb2RlbC4gV2hhdCB3b3VsZCB0aGUgbW9kZWwgcHJlZGljdGVkIEluY29tZSBpbgp8IDIwMDggYmUgZm9yIGFuIGluZGl2aWR1YWwgYm9ybiBpbiAxOTg0LCB3aXRoIGFuIEFTVkFCIHNjb3JlIG9mIDc1MDAwLiBTaG93IHlvdXIgd29yayBpbgp8IGhvdyB5b3UgY2FsY3VsYXRlZCB0aGlzIGVzdGltYXRlLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KIyBEYXRhZnJhbWUgZm9yIFByZWRpY3Rpb24KZGF0YWZyYW1lX3BzMiA8LSBkYXRhLmZyYW1lKFllYXJCb3JuID0gMTk4NCwgQVNWQUIgPSA3NTAwMCkKCiMgR2V0IHRoZSBQcmVkaWN0ZWQgaW5jb21lCnByZWRpY3RlZF9pbmNvbWUgPC0gcHJlZGljdChtb2RlbG11bHRpcGxlcmVncmVzc2lvbiwgbmV3ZGF0YSA9IGRhdGFmcmFtZV9wczIpCgpwcmludChwcmVkaWN0ZWRfaW5jb21lKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIyBRdWVzdGlvbiA4CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnwgRHIuIEJvb20gc2F5cyAiSSBsaWtlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyB2ZXJ5IG11Y2guIEkgZmluZCB0aGVtIHZlcnkgaW50ZXJwcmV0YWJsZS4gSXMKfCB0aGVyZSBhIHdheSB0byBxdWFudGlmeSB0aGUgdW5pcXVlIGNvbnRyaWJ1dGlvbnMgb2YgZWFjaCB2YXJpYWJsZSB0byB0aGUgcHJlZGljdGlvbiBvZgp8IGluY29tZSB1c2luZyBhIGNvcnJlbGF0aW9uIG1ldHJpYz8iIERyLiBNaWxsIHNheXMgIlllcywgaW4gZmFjdCwgdGhlcmUgYXJlIHR3byEgTGV0J3MgbG9vayBhdAp8IHRoZSBwYXJ0aWFsIGFuZCBzZW1pLXBhcnRpYWwgY29ycmVsYXRpb25zLiIKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKfCA4LjEpIENhbGN1bGF0ZSB0aGUgcGFydGlhbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIEluY29tZTIwMDggYW5kIFllYXJCb3JuLCBwYXJ0aWFsaW5nIG91dAp8IEFTVkFCLiBQcm92aWRlIGFuIGVzdGltYXRlLCBhbiBpbnRlcnByZXRhdGlvbiBvZiB0aGUgZXN0aW1hdGUsIGFuZCBhIHNjYXR0ZXJwbG90IHRoYXQKfCBhbGlnbnMgd2l0aCB0aGUgZXN0aW1hdGUgKHJlcHJlc2VudCB0aGUgdHdvIHBhcnRpYWxlZCB2YXJpYWJsZXMgd2hpY2ggYXJlIHVzZWQgdG8KfCBjYWxjdWxhdGUgdGhlIGNvcnJlbGF0aW9uKS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3J9CiMgVXNpbmcgdGhlIFBQQ29yIFBhY2thZ2UKCmxpYnJhcnkocHBjb3IpCgojIFBhcnRpYWwgY29ycmVsYXRpb24KcGFydGlhbF9jb3JyZWxhdGlvbl9pbmNvbWVfeWVhciA8LSBwY29yLnRlc3QoTkxTZGF0YSRJbmNvbWUyMDA4LCBOTFNkYXRhJFllYXJCb3JuLCBOTFNkYXRhJEFTVkFCLCBtZXRob2QgPSAicGVhcnNvbiIpCgpwcmludChwYXJ0aWFsX2NvcnJlbGF0aW9uX2luY29tZV95ZWFyKQpgYGAKCmBgYHtyfQojIEhhcmRjb2RlZCBSIAoKIyBSZWdyZXNzIEluY29tZTIwMDggb24gQVNWQUIKbW9kZWxfaW5jb21lX29uX2FzdmFiIDwtIGxtKEluY29tZTIwMDggfiBBU1ZBQiwgZGF0YSA9IE5MU2RhdGEpCnJlc2lkdWFsc19pbmNvbWUgPC0gcmVzaWR1YWxzKG1vZGVsX2luY29tZV9vbl9hc3ZhYikKCiMgUmVncmVzcyBZZWFyQm9ybiBvbiBBU1ZBQgptb2RlbF95ZWFyYm9ybl9vbl9hc3ZhYiA8LSBsbShZZWFyQm9ybiB+IEFTVkFCLCBkYXRhID0gTkxTZGF0YSkKcmVzaWR1YWxzX3llYXJib3JuIDwtIHJlc2lkdWFscyhtb2RlbF95ZWFyYm9ybl9vbl9hc3ZhYikKCiMgQ29ycmVsYXRpb24gb2YgUmVzaWR1YWxzCnBhcnRpYWxfY29yX2luY29tZTIwMDh5ZWFyYm9ybiA8LSBjb3IocmVzaWR1YWxzX2luY29tZSwgcmVzaWR1YWxzX3llYXJib3JuKQoKcHJpbnQocGFydGlhbF9jb3JfaW5jb21lMjAwOHllYXJib3JuKQpgYGAKCmBgYHtyfQpwYXJ0aWFsX3Jlc2lkdWFsc19kZiA8LSBkYXRhLmZyYW1lKHJlc2lkdWFsc19pbmNvbWUgPSByZXNpZHVhbHNfaW5jb21lLCByZXNpZHVhbHNfeWVhcmJvcm4gPSByZXNpZHVhbHNfeWVhcmJvcm4pCgojIFBsb3RzIFJlc2lkdWFscwoKbGlicmFyeShnZ3Bsb3QyKQoKZ2dwbG90KHBhcnRpYWxfcmVzaWR1YWxzX2RmLCBhZXMoeCA9IHJlc2lkdWFsc195ZWFyYm9ybiwgeSA9IHJlc2lkdWFsc19pbmNvbWUpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAicmVkIiwgc2UgPSBGQUxTRSkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9mYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIikgKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAicGxhaW4iLCBmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsIGhqdXN0ID0gMC41KQogICkgKwogIGxhYnMoeCA9ICJSZXNpZHVhbHMgZm9yIFllYXIgb2YgQmlydGggKGNvbnRyb2xsaW5nIGZvciBBU1ZBQikiLAogICAgICAgeSA9ICJSZXNpZHVhbHMgZm9yIEluY29tZSBpbiAyMDA4IChjb250cm9sbGluZyBmb3IgQVNWQUIpIiwKICAgICAgIHRpdGxlID0gIlBhcnRpYWwgQ29ycmVsYXRpb24gYmV0d2VlbiBJbmNvbWUgaW4gMjAwOCBhbmQgWWVhciBvZiBCaXJ0aCIpCgpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKfCA4LjIpIENhbGN1bGF0ZSB0aGUgc2VtaXBhcnRpYWwgY29ycmVsYXRpb24gYmV0d2VlbiBJbmNvbWUyMDA4IGFuZCBZZWFyQm9ybiwKfCBwYXJ0aWFsbGluZyBvdXQgQVNWQUIuIFByb3ZpZGUgYW4gZXN0aW1hdGUsIGFuIGludGVycHJldGF0aW9uIG9mIHRoZSBlc3RpbWF0ZSwgYW5kIGEKfCBzY2F0dGVycGxvdCB0aGF0IGFsaWducyB3aXRoIHRoZSBlc3RpbWF0ZSAocmVwcmVzZW50IHRoZSBvbmUgcGFydGlhbGVkIHZhcmlhYmxlcyB3aGljaAp8IGFyZSB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgY29ycmVsYXRpb24pLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7cn0KIyBVc2luZyBQUGNvciBQYWNrYWdlCmxpYnJhcnkocHBjb3IpCgojIFNlbWktcGFydGlhbCBjb3JyZWxhdGlvbgpzZW1pX3BhcnRpYWxfY29ycmVsYXRpb25faW5jb21lX3llYXIgPC0gc3Bjb3IudGVzdChOTFNkYXRhJEluY29tZTIwMDgsIE5MU2RhdGEkWWVhckJvcm4sIE5MU2RhdGEkQVNWQUIsIG1ldGhvZCA9ICJwZWFyc29uIikKCnByaW50KHNlbWlfcGFydGlhbF9jb3JyZWxhdGlvbl9pbmNvbWVfeWVhcikKCmBgYAoKYGBge3J9CiMgSGFyZGNvZGVkIFIgCgojIFJlZ3Jlc3MgSW5jb21lMjAwOCBvbiBBU1ZBQiBhbG9uZQptb2RlbF9pbmNvbWVfb25fYXN2YWJfb25seSA8LSBsbShJbmNvbWUyMDA4IH4gQVNWQUIsIGRhdGEgPSBOTFNkYXRhKQpyZXNpZHVhbHNfZnJvbV9hc3ZhYl9vbmx5IDwtIHJlc2lkdWFscyhtb2RlbF9pbmNvbWVfb25fYXN2YWJfb25seSkKCnNlbWlwYXJ0aWFsX2Nvcl9pbmNvbWUyMDA4eWVhcmJvcm4gPC0gY29yKE5MU2RhdGEkWWVhckJvcm4sIHJlc2lkdWFsc19mcm9tX2FzdmFiX29ubHkpCgpwcmludChzZW1pcGFydGlhbF9jb3JfaW5jb21lMjAwOHllYXJib3JuKQpgYGAKCmBgYHtyfQpzZW1pX3Jlc2lkdWFsc19kZiA8LSBkYXRhLmZyYW1lKFllYXJCb3JuID0gTkxTZGF0YSRZZWFyQm9ybiwgcmVzaWR1YWxzX2luY29tZSA9IHJlc2lkdWFsc19mcm9tX2FzdmFiX29ubHkpCgojIFBsb3RzIFNlbWlwYXJ0aWFsCgpsaWJyYXJ5KGdncGxvdDIpCgpnZ3Bsb3Qoc2VtaV9yZXNpZHVhbHNfZGYsIGFlcyh4ID0gWWVhckJvcm4sIHkgPSByZXNpZHVhbHNfaW5jb21lKSkgKwogIGdlb21fcG9pbnQoKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gInJlZCIsIHNlID0gRkFMU0UpICsKICB0aGVtZV9taW5pbWFsKGJhc2VfZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpICsKICB0aGVtZSgKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSwgZmFjZSA9ICJwbGFpbiIsIGZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iKSwKICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpLAogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIsIGZhbWlseSA9ICJUaW1lcyBOZXcgUm9tYW4iLCBoanVzdCA9IDAuNSkKICApICsKICBsYWJzKHggPSAiWWVhciBvZiBCaXJ0aCIsCiAgICAgICB5ID0gIlJlc2lkdWFscyBmb3IgSW5jb21lIGluIDIwMDggKGNvbnRyb2xsaW5nIGZvciBBU1ZBQikiLAogICAgICAgdGl0bGUgPSAiU2VtaS1QYXJ0aWFsIENvcnJlbGF0aW9uIikKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnwgOC40KSBDYWxjdWxhdGUgdGhlIHBhcnRpYWwgY29ycmVsYXRpb24gYmV0d2VlbiBJbmNvbWUyMDA4IGFuZCBBU1ZBQiwgcGFydGlhbGluZyBvdXQKfCBZZWFyQm9ybi4gUHJvdmlkZSBhbiBlc3RpbWF0ZSwgYW4gaW50ZXJwcmV0YXRpb24gb2YgdGhlIGVzdGltYXRlLCBhbmQgYSBzY2F0dGVycGxvdAp8IHRoYXQgYWxpZ25zIHdpdGggdGhlIGVzdGltYXRlIChyZXByZXNlbnQgdGhlIHR3byBwYXJ0aWFsZWQgdmFyaWFibGVzIHdoaWNoIGFyZSB1c2VkIHRvCnwgY2FsY3VsYXRlIHRoZSBjb3JyZWxhdGlvbikuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmBgYHtyfQojIFVzaW5nIHRoZSBQUENvciBQYWNrYWdlCgpsaWJyYXJ5KHBwY29yKQoKIyBQYXJ0aWFsIGNvcnJlbGF0aW9uCnBhcnRpYWxfY29ycmVsYXRpb25faW5jb21lX2FzdmFiIDwtIHBjb3IudGVzdChOTFNkYXRhJEluY29tZTIwMDgsIE5MU2RhdGEkQVNWQUIsIE5MU2RhdGEkWWVhckJvcm4sIG1ldGhvZCA9ICJwZWFyc29uIikKCnByaW50KHBhcnRpYWxfY29ycmVsYXRpb25faW5jb21lX2FzdmFiKQoKYGBgCgpgYGB7cn0KIyBIYXJkY29kZWQgUiAKCiMgUmVncmVzcyBJbmNvbWUyMDA4IG9uIFllYXJCb3JuCm1vZGVsX2luY29tZTIwMDhfb25feWVhcmJvcm4gPC0gbG0oSW5jb21lMjAwOCB+IFllYXJCb3JuLCBkYXRhID0gTkxTZGF0YSkKcmVzaWR1YWxzX2luY29tZTIwMDggPC0gcmVzaWR1YWxzKG1vZGVsX2luY29tZTIwMDhfb25feWVhcmJvcm4pCgojIFJlZ3Jlc3MgQVNWQUIgb24gWWVhckJvcm4KbW9kZWxfQVNWQUJfb25feWVhcmJvcm4gPC0gbG0oQVNWQUIgfiBZZWFyQm9ybiwgZGF0YSA9IE5MU2RhdGEpCnJlc2lkdWFsc19BU1ZBQiA8LSByZXNpZHVhbHMobW9kZWxfQVNWQUJfb25feWVhcmJvcm4pCgojIENvcnJlbGF0aW9ucyBvbiBSZXNpZHVhbHMKcGFydGlhbF9jb3JfaW5jb21lMjAwOGFzdmFiIDwtIGNvcihyZXNpZHVhbHNfaW5jb21lMjAwOCwgcmVzaWR1YWxzX0FTVkFCKQoKcHJpbnQocGFydGlhbF9jb3JfaW5jb21lMjAwOGFzdmFiKQpgYGAKCmBgYHtyfQpwYXJ0aWFsX3Jlc2lkdWFsc19kZl8yIDwtIGRhdGEuZnJhbWUocmVzaWR1YWxzX2luY29tZSA9IHJlc2lkdWFsc19pbmNvbWUyMDA4LCByZXNpZHVhbHNfQVNWQUIgPSByZXNpZHVhbHNfQVNWQUIpCgojIFBsb3RzIFJlc2lkdWFscwoKbGlicmFyeShnZ3Bsb3QyKQoKZ2dwbG90KHBhcnRpYWxfcmVzaWR1YWxzX2RmXzIsIGFlcyh4ID0gcmVzaWR1YWxzX0FTVkFCLCB5ID0gcmVzaWR1YWxzX2luY29tZTIwMDgpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAicmVkIiwgc2UgPSBGQUxTRSkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9mYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIikgKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAicGxhaW4iLCBmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsIGhqdXN0ID0gMC41KQogICkgKwogIGxhYnMoeCA9ICJSZXNpZHVhbHMgb2YgQVNWQUIgKGNvbnRyb2xsaW5nIGZvciBZZWFyIG9mIEJpcnRoKSIsCiAgICAgICB5ID0gIlJlc2lkdWFscyBmb3IgSW5jb21lIGluIDIwMDggKGNvbnRyb2xsaW5nIGZvciBZZWFyIG9mIEJpcnRoKSIsCiAgICAgICB0aXRsZSA9ICJQYXJ0aWFsIENvcnJlbGF0aW9uIikKCmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgp8IDguNSkgQ2FsY3VsYXRlIHRoZSBzZW1pcGFydGlhbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIEluY29tZTIwMDggYW5kIEFTVkFCLCBwYXJ0aWFsaW5nCnwgb3V0IFllYXJCb3JuLiBQcm92aWRlIGFuIGVzdGltYXRlLCBhbiBpbnRlcnByZXRhdGlvbiBvZiB0aGUgZXN0aW1hdGUsIGFuZCBhCnwgc2NhdHRlcnBsb3QgdGhhdCBhbGlnbnMgd2l0aCB0aGUgZXN0aW1hdGUgKHJlcHJlc2VudCB0aGUgdHdvIHBhcnRpYWxlZCB2YXJpYWJsZXMgd2hpY2gKfCBhcmUgdXNlZCB0byBjYWxjdWxhdGUgdGhlIGNvcnJlbGF0aW9uKS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3J9CiMgVXNpbmcgdGhlIFBQQ29yIFBhY2thZ2UKCmxpYnJhcnkocHBjb3IpCgojIFNlbWktcGFydGlhbCBjb3JyZWxhdGlvbgpzZW1pX3BhcnRpYWxfY29ycmVsYXRpb25faW5jb21lX2FzdmFiIDwtIHNwY29yLnRlc3QoTkxTZGF0YSRJbmNvbWUyMDA4LCBOTFNkYXRhJEFTVkFCLCBOTFNkYXRhJFllYXJCb3JuLCBtZXRob2QgPSAicGVhcnNvbiIpCgpwcmludChzZW1pX3BhcnRpYWxfY29ycmVsYXRpb25faW5jb21lX2FzdmFiKQoKYGBgCgpgYGB7cn0KIyBIYXJkY29kZWQgUiAKCiMgUmVncmVzcyBJbmNvbWUyMDA4IG9uIEFTVkFCIGFsb25lCm1vZGVsX2luY29tZV9vbl95ZWFyYm9ybl9vbmx5IDwtIGxtKEluY29tZTIwMDggfiBZZWFyQm9ybiwgZGF0YSA9IE5MU2RhdGEpCnJlc2lkdWFsc19mcm9tX3llYXJib3JuX29ubHkgPC0gcmVzaWR1YWxzKG1vZGVsX2luY29tZV9vbl95ZWFyYm9ybl9vbmx5KQoKc2VtaXBhcnRpYWxfY29yX2luY29tZTIwMDhhc3ZhYiA8LSBjb3IoTkxTZGF0YSRBU1ZBQiwgcmVzaWR1YWxzX2Zyb21feWVhcmJvcm5fb25seSkKCnByaW50KHNlbWlwYXJ0aWFsX2Nvcl9pbmNvbWUyMDA4YXN2YWIpCgpgYGAKCmBgYHtyfQpzZW1pX3Jlc2lkdWFsc19kZl8yIDwtIGRhdGEuZnJhbWUoQVNWQUIgPSBOTFNkYXRhJEFTVkFCLCByZXNpZHVhbHNfeWVhcmJvcm4gPSByZXNpZHVhbHNfZnJvbV95ZWFyYm9ybl9vbmx5KQoKIyBQbG90cyBTZW1pcGFydGlhbAoKbGlicmFyeShnZ3Bsb3QyKQoKZ2dwbG90KHNlbWlfcmVzaWR1YWxzX2RmXzIsIGFlcyh4ID0gQVNWQUIsIHkgPSByZXNpZHVhbHNfeWVhcmJvcm4pKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAicmVkIiwgc2UgPSBGQUxTRSkgKwogIHRoZW1lX21pbmltYWwoYmFzZV9mYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIikgKwogIHRoZW1lKAogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBmYWNlID0gInBsYWluIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIpLAogICAgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGZhY2UgPSAicGxhaW4iLCBmYW1pbHkgPSAiVGltZXMgTmV3IFJvbWFuIiksCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiwgZmFtaWx5ID0gIlRpbWVzIE5ldyBSb21hbiIsIGhqdXN0ID0gMC41KQogICkgKwogIGxhYnMoeCA9ICJBU1ZBQiBTY29yZSIsCiAgICAgICB5ID0gIlJlc2lkdWFscyBmb3IgSW5jb21lIGluIDIwMDggKGNvbnRyb2xsaW5nIGZvciBZZWFyIG9mIEJpcnRoKSIsCiAgICAgICB0aXRsZSA9ICJTZW1pLVBhcnRpYWwgQ29ycmVsYXRpb24iKQpgYGAK