Md Mahmudul Hasan

Assignment

Assignment:

Write a report suitable for sharing with your CIO on the relationship between Gold, Inflation, and Interest rates in the U.S. Use monthly data from January 01, 2005 - January 01, 2019 with the following variables:

  1. Gold: Monthly log returns generated from the close price of the ETF “SPDR Gold Shares”

  2. Inflation: Monthly rate of change of Consumer Price Index for All Urban Consumers: All Items in U.S. City Average

  • There is a seasonally adjusted and a non-seasonally adjusted version
  • Use the seasonally adjusted series<p>
  1. Interest Rates: Change in Market Yield on U.S. Treasury Securities at 2-Year Constant Maturity, Quoted on an Investment Basis


Include the following in your report alongside brief, relevant discussion:
1. A full description of your final data sample (after any transformations). This includes # of observations, of missing values, mean, median, standard deviation, skewness, and kurtosis 
-Discuss any important statistical properties and include a discussion of any evident departures from normality and any implications of those departures for an investor 
2. Generate a time series plot of each variable of interest and describe any interesting patterns, trends, or “stories” behind the plot. (i.e. what was the narrative in the real world about the evolution of these variables over time?) 
-Include proper plot labels, titles, captions, and sources 
3. Run the following regressions, output regression tables, and discuss the relationships you find including a discussion of statistical significance: - Gold vs Inflation  - Gold vs Interest Rates  - Inflation vs Interest Rates  - Gold vs Interest Rates and Inflation 
4. Discuss whether the regression of Gold on both interest rates and inflation (d) is a better model than the regression of gold on interest rates (b) and gold on inflation (a) individually. 
5. Evaluate the Gold vs Interest Rate and Inflation regression (d) in part 3 for violations of the assumptions of OLS and identify any issues regarding:  - Heteroskedasticity  - Autocorrelation/Serial Correlation  - Normality of Residuals (Q-Q plot, Histogram, and a formal test)  - Include a discussion of how any issues may affect your results. 
6. If there are problems identified in part 5 that should be addressed, re-run the regression of Gold on Interest Rates and Inflation with appropriate corrections. 
7. One of the more difficult to evaluate assumptions of OLS is exogeneity. Do you think the regression of Gold on Inflation and Interest rates is likely to violate this assumption and why? 
8. End with a brief (2-3 sentence) conclusion on the use of Gold as an inflation hedge in the current environment and any suggested next steps. 

Gold Log Returns

Gold: Monthly log returns generated from the close price of the ETF “SPDR Gold Shares”

df<-tidyquant::tq_get(x=c("GLD"), #GLD is the ticker 
                           get="stock.prices", #stock.prices >tq_get >Yahoo Finance
                           from ="2005-01-01",     
                           to= "2018-12-31") %>%  
  tq_transmute(select = close, mutate_fun = to.monthly,indexAt = "firstof") 
# Note, the data we get daily, we have to transmute the data to monthly and first day of the month...
# "lastof" would take from the last day
df <- df %>%
  mutate(Gold_Log_Return = c(NA, diff(log(df$close))))


df %>% 
  ggplot(aes(date, Gold_Log_Return)) +
  geom_line(size = 1) +
  labs(title = "Close Price and Gold Log Return Over Time",
       x = "Date",
       y = "Gold_Log_Return") +
  theme(plot.title.position = 'plot', 
      plot.title = element_text(hjust = 0.5))+
  theme_minimal()

Close Price and Gold Log Return Over Time
date close Gold_Log_Return
2005-01-01 42.22 NA
2005-02-01 43.53 0.03055626
2005-03-01 42.82 -0.01644505
2005-04-01 43.35 0.01230139
2005-05-01 41.65 -0.04000526
2005-06-01 43.44 0.04207924
This is the summary of Gold Log Return Over Time
168 rows x 3 cols
Column Plot Overview Missing Mean Median SD
date 2005-01-012018-12-01 0.0% — — —
close 42178 0.0% 108.7 115.5 33.4
Gold_Log_Return -0.180.12 0.6% 0.0 0.0 0.1

Inflation


Consumer Price Index for All Urban Consumers(Seasonally Adjusted): All Items in U.S. City Average (CPIAUCSL)

df_cpi<-tidyquant::tq_get(c("CPIAUCSL"), 
                           get="economic.data",
                           from="2005-01-01", 
                           to="2018-12-31")

df <- df %>%
  mutate(Inflation_Rate_of_Change = (df_cpi$price / lag(df_cpi$price, 1) - 1) * 100)
head(df) %>%
  gt() %>% 
  gt_theme_guardian() %>% 
  tab_header(title = "Close Price, Gold Log Return and Inflation Rate of Change Over Time")
Close Price, Gold Log Return and Inflation Rate of Change Over Time
date close Gold_Log_Return Inflation_Rate_of_Change
2005-01-01 42.22 NA NA
2005-02-01 43.53 0.03055626 0.41753653
2005-03-01 42.82 -0.01644505 0.36382536
2005-04-01 43.35 0.01230139 0.31071983
2005-05-01 41.65 -0.04000526 -0.05162623
2005-06-01 43.44 0.04207924 0.05165289
df %>% 
  gt_plt_summary(title = "Summary of Gold Log Return and Inflation Rate of Change Over Time")
Summary of Gold Log Return and Inflation Rate of Change Over Time
168 rows x 4 cols
Column Plot Overview Missing Mean Median SD
date 2005-01-012018-12-01 0.0% — — —
close 42178 0.0% 108.7 115.5 33.4
Gold_Log_Return -0.180.12 0.6% 0.0 0.0 0.1
Inflation_Rate_of_Change -1.81.4 0.6% 0.2 0.2 0.3

Interest Rate


Market Yield on U.S. Treasury Securities at 2-Year Constant Maturity, Quoted on an Investment Basis (DGS2)

df_ir<-tidyquant::tq_get(c("DGS2"), 
                          get="economic.data", #economic.data indicates FRED
                          from="2005-01-01", 
                          to="2018-12-31") %>% 
  tidyr::pivot_wider(names_from = symbol, values_from = price) %>% 
  tq_transmute(mutate_fun = to.monthly, indexAt = "firstof")

df <- df %>%
  left_join(df_ir %>% 
              select(date, Interest_Rate_Change = DGS2), by = c("date" = "date"))
head(df) %>%
  gt() %>% 
  gt_theme_guardian() %>% 
  tab_header(title = "Close Price, Gold Log Return, Inflation Rate and Interest Rate of Change Over Time")
Close Price, Gold Log Return, Inflation Rate and Interest Rate of Change Over Time
date close Gold_Log_Return Inflation_Rate_of_Change Interest_Rate_Change
2005-01-01 42.22 NA NA 3.29
2005-02-01 43.53 0.03055626 0.41753653 3.59
2005-03-01 42.82 -0.01644505 0.36382536 3.80
2005-04-01 43.35 0.01230139 0.31071983 3.66
2005-05-01 41.65 -0.04000526 -0.05162623 3.60
2005-06-01 43.44 0.04207924 0.05165289 3.66
df %>% 
  gt_plt_summary(title = "This is the Summary")
This is the Summary
168 rows x 5 cols
Column Plot Overview Missing Mean Median SD
date 2005-01-012018-12-01 0.0% — — —
close 42178 0.0% 108.7 115.5 33.4
Gold_Log_Return -0.180.12 0.6% 0.0 0.0 0.1
Inflation_Rate_of_Change -1.81.4 0.6% 0.2 0.2 0.3
Interest_Rate_Change 0.25.2 0.0% 1.7 0.9 1.6

Calculations


Relationship between Gold monthly log returns,VS Inflation (monthly rate of change) VS Interest rates (change in market yield)

we can use multiple regression analysis. In this analysis:

The dependent variable could be Gold returns. The independent variables would be Inflation (monthly rate of change) and Interest rates (change in market yield).

We can run a multiple linear regression to see how changes in Inflation and Interest rates affect the log returns of Gold.

model <- lm(Gold_Log_Return ~ Inflation_Rate_of_Change + Interest_Rate_Change, data = df)
model_summary <- summary(model)
# Residuals summary
residuals <- model_summary$residuals
residuals_summary <- c(min(residuals), quantile(residuals, c(0.25, 0.5, 0.75)), max(residuals))
# Format the residuals in a data frame for better presentation
residuals_df <- data.frame(
  Statistic = c("Min", "1Q", "Median", "3Q", "Max"),
  Value = round(residuals_summary, 6)
)
# Format the coefficients in a data frame for better presentation
coefficients_df <- data.frame(
  Variable = rownames(model_summary$coefficients),
  Estimate = round(model_summary$coefficients[, 1], 7),
  `Std. Error` = round(model_summary$coefficients[, 2], 7),
  `t-value` = round(model_summary$coefficients[, 3], 3),
  `p-value` = round(model_summary$coefficients[, 4], 3)
)
# Extract model statistics
rse <- round(model_summary$sigma, 5)
r_squared <- round(model_summary$r.squared, 5)
adj_r_squared <- round(model_summary$adj.r.squared, 7)
f_statistic <- round(model_summary$fstatistic[1], 4)
f_pvalue <- round(pf(model_summary$fstatistic[1], 
                     model_summary$fstatistic[2], 
                     model_summary$fstatistic[3], 
                     lower.tail = FALSE), 4)
Statistic Value
Min -0.174301
1Q -0.031343
Median -0.002384
3Q 0.032946
Max 0.128592
Variable Estimate Std..Error t.value p.value
(Intercept) (Intercept) 0.0003414 0.0059291 0.058 0.954
Inflation_Rate_of_Change Inflation_Rate_of_Change 0.0075258 0.0126568 0.595 0.553
Interest_Rate_Change Interest_Rate_Change 0.0028289 0.0025958 1.090 0.277
## Residual Standard Error: 0.05104 (on 164 degrees of freedom)
## Multiple R-squared: 0.01127
## Adjusted R-squared: -0.0007894
## F-statistic: 0.9345 (on 2 and 164 DF)  p-value: 0.3949
library(stargazer)
## 
## Please cite as:
##  Hlavac, Marek (2022). stargazer: Well-Formatted Regression and Summary Statistics Tables.
##  R package version 5.2.3. https://CRAN.R-project.org/package=stargazer
# Regressions
reg_a <- lm(Gold_Log_Return ~ Inflation_Rate_of_Change, data = df)

reg_b <- lm(Gold_Log_Return ~ Interest_Rate_Change, data = df)

reg_c <- lm(Inflation_Rate_of_Change ~ Interest_Rate_Change, data = df)

reg_d <- lm(Gold_Log_Return ~ Interest_Rate_Change + Inflation_Rate_of_Change, data = df)

stargazer(reg_a, reg_b, reg_c, reg_d, 
          type = "text",        # 'text' for console, 'html' or 'latex' for documents
          title = "Regression Results: Gold, Inflation, and Interest Rates", 
          dep.var.labels = c("Gold Log Return", "Inflation Rate of Change"),
          covariate.labels = c("Inflation Rate of Change", "Interest Rate Change"),
          out = "regression_output.txt")  # save the output to a .txt file
## 
## Regression Results: Gold, Inflation, and Interest Rates
## =============================================================================================================
##                                                          Dependent variable:                                 
##                          ------------------------------------------------------------------------------------
##                                      Gold Log Return             Inflation Rate of Change   Gold_Log_Return  
##                                  (1)                 (2)                   (3)                    (4)        
## -------------------------------------------------------------------------------------------------------------
## Inflation Rate of Change        0.010                                                            0.008       
##                                (0.012)                                                          (0.013)      
##                                                                                                              
## Interest Rate Change                                0.003                0.040**                 0.003       
##                                                    (0.003)               (0.016)                (0.003)      
##                                                                                                              
## Constant                        0.005               0.001                0.099***               0.0003       
##                                (0.004)             (0.006)               (0.036)                (0.006)      
##                                                                                                              
## -------------------------------------------------------------------------------------------------------------
## Observations                     167                 167                   167                    167        
## R2                              0.004               0.009                 0.039                  0.011       
## Adjusted R2                    -0.002               0.003                 0.033                 -0.001       
## Residual Std. Error       0.051 (df = 165)    0.051 (df = 165)       0.314 (df = 165)      0.051 (df = 164)  
## F Statistic              0.681 (df = 1; 165) 1.521 (df = 1; 165)  6.660** (df = 1; 165)   0.935 (df = 2; 164)
## =============================================================================================================
## Note:                                                                             *p<0.1; **p<0.05; ***p<0.01

Breusch-Pagan Test for Heteroskedasticity

library(lmtest)
bptest(reg_d)
## 
##  studentized Breusch-Pagan test
## 
## data:  reg_d
## BP = 14.768, df = 2, p-value = 0.0006211

Interpretation: If the p-value is less than 0.05, then you reject the null hypothesis of homoscedasticity, meaning there is evidence of heteroskedasticity. Heteroskedasticity affects the standard errors, which means the significance of your coefficients might be misestimated.

Plotting Residuals vs. Fitted Values

# Plot residuals vs fitted values
plot(reg_d$fitted.values, reg_d$residuals, 
     xlab = "Fitted Values", ylab = "Residuals", 
     main = "Residuals vs Fitted")
abline(h = 0, col = "red")

Interpretation: If the spread of residuals increases or decreases as the fitted values increase, this indicates heteroskedasticity.

Autocorrelation/Serial Correlation:

# Perform Durbin-Watson test for autocorrelation
dwtest(reg_d)
## 
##  Durbin-Watson test
## 
## data:  reg_d
## DW = 2.2401, p-value = 0.9259
## alternative hypothesis: true autocorrelation is greater than 0

Interpretation: The Durbin-Watson statistic ranges from 0 to 4. A value near 2 indicates no autocorrelation. A value closer to 0 indicates positive autocorrelation. A value closer to 4 indicates negative autocorrelation. If the p-value is less than 0.05, autocorrelation is present, which can bias the coefficient estimates and affect hypothesis testing.

Q-Q Plot for Normality of Residuals

# Q-Q plot for normality
qqnorm(residuals(reg_d))
qqline(residuals(reg_d), col = "red")

Interpretation: If the points follow the 45-degree line closely, then the residuals are normally distributed. Deviations from the line suggest non-normality.

Histogram of Residuals

# Histogram of residuals
hist(residuals(reg_d), main = "Histogram of Residuals", 
     xlab = "Residuals", col = "lightblue")

Interpretation: A bell-shaped histogram suggests that the residuals are normally distributed.

Shapiro-Wilk Test for Normality

# Perform Shapiro-Wilk test for normality
shapiro.test(residuals(reg_d))
## 
##  Shapiro-Wilk normality test
## 
## data:  residuals(reg_d)
## W = 0.99226, p-value = 0.5112

Interpretation: If the p-value is less than 0.05, the residuals are not normally distributed. Non-normality can affect the validity of confidence intervals and hypothesis tests.

Heteroskedasticity:

library(sandwich)

# Re-run the regression with robust standard errors
coeftest(reg_d, vcov = vcovHC(reg_d, type = "HC1"))
## 
## t test of coefficients:
## 
##                            Estimate Std. Error t value Pr(>|t|)
## (Intercept)              0.00034139 0.00689068  0.0495   0.9605
## Interest_Rate_Change     0.00282891 0.00242141  1.1683   0.2444
## Inflation_Rate_of_Change 0.00752582 0.02179180  0.3454   0.7303

Model Summary
Gold_Log_Return ∼ Inflation_Rate_of_Change + Interest_Rate_Change

This indicates that we are trying to explain the log returns of gold using changes in inflation rates and changes in interest rates.

Residuals:

The residuals are the differences between the observed values and the predicted values from the model. The summary statistics indicate that the residuals are fairly symmetrically distributed, with minimum and maximum values showing some dispersion around zero.
Coefficients: Intercept: 0.0003414

This is the estimated value of Gold Log Returns when both Inflation Rate of Change and Interest Rate Change are zero.


Inflation Rate of Change: 0.0075258

For each unit increase in the inflation rate change, the Gold Log Return is estimated to increase by approximately 0.0075, holding the interest rate change constant. However, the p-value (0.553) indicates that this coefficient is not statistically significant, suggesting a weak relationship.


Interest Rate Change: 0.0028289

For each unit increase in the interest rate change, the Gold Log Return is estimated to increase by approximately 0.0028, holding the inflation rate change constant. The p-value (0.277) suggests this coefficient is also not statistically significant.


Residual Standard Error: 0.05104 indicates the average distance that the observed values fall from the regression line.


R-squared:
Multiple R-squared: 0.01127
Adjusted R-squared: −0.0007894

This suggests that only about 1.1% of the variability in Gold Log Returns is explained by the model. The adjusted R-squared being negative implies that the model is not better than a simple mean model, indicating poor explanatory power.

F-statistic and p-value:

F-statistic: 0.9345 with p-value: 0.3949 The overall model is not statistically significant, suggesting that neither of the predictor variables (Inflation Rate of Change and Interest Rate Change) contribute meaningfully to explaining the variation in Gold Log Returns.

Implications of the Model Weak Relationships:

The coefficients for both inflation and interest rate changes are not statistically significant, meaning there is no strong evidence to suggest that changes in inflation or interest rates have a meaningful impact on gold returns in this model.

Low Predictive Power:
The low R2 (R-squared) values indicate that the model does not explain much of the variability in gold log returns, suggesting that other factors not included in the model may be influencing gold returns.

Further Investigation: Given these results, it may be worthwhile to explore additional variables, consider nonlinear relationships, or examine interactions among variables to better understand what influences gold returns.

Caution in Interpretation: The non-significance of the predictors means caution should be taken when interpreting these relationships, as they may not hold true outside of this specific model.

In summary, the regression results imply that the model does not significantly explain variations in gold log returns based on inflation and interest rate changes. Further analysis may be needed to identify other influencing factors.


Md Mahmudul Hasan
MQIM 3760573
Faculty of Management
University of New Brunswick
mahmudul.hasan@unb.ca


LS0tDQp0aXRsZTogIkV4cGxvcmluZyB0aGUgRHluYW1pY3MgQmV0d2VlbiBHb2xkLCBJbmZsYXRpb24sIGFuZCBJbnRlcmVzdCBSYXRlcyBpbiB0aGUgVS5TLiBFY29ub215Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgaGlnaGxpZ2h0OiBlc3ByZXNzbw0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0KLS0tDQojIyMjICoqTWQgTWFobXVkdWwgSGFzYW4qKg0KPCEtLSBlY2hvPUZBTFNFOiBIaWRlIGNvZGUgYnV0IGRpc3BsYXkgdGhlIG91dHB1dC4gLS0+DQo8IS0tIGluY2x1ZGU9RkFMU0U6IEhpZGUgYm90aCBjb2RlIGFuZCBvdXRwdXQsIHVzZWZ1bCBmb3Igc2V0dXAgY2h1bmtzLiAtLT4NCjwhLS0gbWVzc2FnZT1GQUxTRSBhbmQgd2FybmluZz1GQUxTRTogU3VwcHJlc3MgYW55IG1lc3NhZ2VzIG9yIHdhcm5pbmdzLiAtLT4NCjwhLS0gZmlnLndpZHRoIGFuZCBmaWcuaGVpZ2h0OiBDb250cm9sIHRoZSBzaXplIG9mIHRoZSBwbG90LiAtLT4NCjwhLS0gb3V0LndpZHRoIGFuZCBvdXQuaGVpZ2h0OiBDb250cm9sIHRoZSBvdXRwdXQgc2l6ZSBvZiB0aGUgZmlndXJlLiAtLT4NCjwhLS0gSW5jbHVkZSBqUXVlcnkgLS0+DQo8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jb2RlLmpxdWVyeS5jb20vanF1ZXJ5LTMuNy4xLnNsaW0ubWluLmpzIj48L3NjcmlwdD4NCg0KPCEtLSBTY3JpcHQgdG8gbWFrZSBhbGwgbGlua3Mgb3BlbiBpbiBhIG5ldyB0YWIgLS0+DQo8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+DQogICQoZG9jdW1lbnQpLnJlYWR5KGZ1bmN0aW9uKCkgew0KICAkKCdhJykuYXR0cigndGFyZ2V0JywgJ19ibGFuaycpOw0KICB9KTsNCjwvc2NyaXB0Pg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoZnBwMikNCmxpYnJhcnkodGlkeXF1YW50KQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHF1YW50bW9kKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KGN1cmwpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoY293cGxvdCkNCmxpYnJhcnkoZ2dwdWJyKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShndCkNCmxpYnJhcnkoZ3RFeHRyYXMpDQpsaWJyYXJ5KGtuaXRyKQ0KYGBgDQoNCiMgey50YWJzZXR9DQoNCiMjIEFzc2lnbm1lbnQNCioqQXNzaWdubWVudDoqKiA8cD5Xcml0ZSBhIHJlcG9ydCBzdWl0YWJsZSBmb3Igc2hhcmluZyB3aXRoIHlvdXIgQ0lPIG9uIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBHb2xkLCBJbmZsYXRpb24sIGFuZCBJbnRlcmVzdCByYXRlcyBpbiB0aGUgVS5TLiBVc2UgbW9udGhseSBkYXRhIGZyb20gSmFudWFyeSAwMSwgMjAwNSAtIEphbnVhcnkgMDEsIDIwMTkgd2l0aCB0aGUgZm9sbG93aW5nIHZhcmlhYmxlczo8cD4NCiAxLiA8cD4qKkdvbGQ6KiogTW9udGhseSBsb2cgcmV0dXJucyBnZW5lcmF0ZWQgZnJvbSB0aGUgY2xvc2UgcHJpY2Ugb2YgdGhlIEVURiDigJxTUERSIEdvbGQgU2hhcmVz4oCdPHA+DQogMi4gPHA+KipJbmZsYXRpb246KiogTW9udGhseSByYXRlIG9mIGNoYW5nZSBvZiBDb25zdW1lciBQcmljZSBJbmRleCBmb3IgQWxsIFVyYmFuIENvbnN1bWVyczogQWxsIEl0ZW1zIGluIFUuUy4gQ2l0eSBBdmVyYWdlXA0KICAtICAgVGhlcmUgaXMgYSBzZWFzb25hbGx5IGFkanVzdGVkIGFuZCBhIG5vbi1zZWFzb25hbGx5IGFkanVzdGVkIHZlcnNpb25cDQogIC0gICBVc2UgdGhlIHNlYXNvbmFsbHkgYWRqdXN0ZWQgc2VyaWVzXDxwPg0KIDMuIDxwPioqSW50ZXJlc3QgUmF0ZXM6KiogQ2hhbmdlIGluIE1hcmtldCBZaWVsZCBvbiBVLlMuIFRyZWFzdXJ5IFNlY3VyaXRpZXMgYXQgMi1ZZWFyIENvbnN0YW50IE1hdHVyaXR5LCBRdW90ZWQgb24gYW4gSW52ZXN0bWVudCBCYXNpczxwPg0KPGJyPg0KDQoqKkluY2x1ZGUgdGhlIGZvbGxvd2luZyBpbiB5b3VyIHJlcG9ydCBhbG9uZ3NpZGUgYnJpZWYsIHJlbGV2YW50IGRpc2N1c3Npb246KiogPGJyPg0KICoqMS4qKiBBIGZ1bGwgZGVzY3JpcHRpb24gb2YgeW91ciBmaW5hbCBkYXRhIHNhbXBsZSAoYWZ0ZXIgYW55IHRyYW5zZm9ybWF0aW9ucykuIFRoaXMgaW5jbHVkZXMgIyBvZiBvYnNlcnZhdGlvbnMsIG9mIG1pc3NpbmcgdmFsdWVzLCBtZWFuLCBtZWRpYW4sIHN0YW5kYXJkIGRldmlhdGlvbiwgc2tld25lc3MsIGFuZCBrdXJ0b3Npc1wgPGJyPg0KICAtRGlzY3VzcyBhbnkgaW1wb3J0YW50IHN0YXRpc3RpY2FsIHByb3BlcnRpZXMgYW5kIGluY2x1ZGUgYSBkaXNjdXNzaW9uIG9mIGFueSBldmlkZW50IGRlcGFydHVyZXMgZnJvbSBub3JtYWxpdHkgYW5kIGFueSBpbXBsaWNhdGlvbnMgb2YgdGhvc2UgZGVwYXJ0dXJlcyBmb3IgYW4gaW52ZXN0b3JcIDxicj4NCiAqKjIuKiogR2VuZXJhdGUgYSB0aW1lIHNlcmllcyBwbG90IG9mIGVhY2ggdmFyaWFibGUgb2YgaW50ZXJlc3QgYW5kIGRlc2NyaWJlIGFueSBpbnRlcmVzdGluZyBwYXR0ZXJucywgdHJlbmRzLCBvciDigJxzdG9yaWVz4oCdIGJlaGluZCB0aGUgcGxvdC4gKGkuZS4gd2hhdCB3YXMgdGhlIG5hcnJhdGl2ZSBpbiB0aGUgcmVhbCB3b3JsZCBhYm91dCB0aGUgZXZvbHV0aW9uIG9mIHRoZXNlIHZhcmlhYmxlcyBvdmVyIHRpbWU/KVwgPGJyPg0KICAtSW5jbHVkZSBwcm9wZXIgcGxvdCBsYWJlbHMsIHRpdGxlcywgY2FwdGlvbnMsIGFuZCBzb3VyY2VzXCA8YnI+DQogKiozLioqIFJ1biB0aGUgZm9sbG93aW5nIHJlZ3Jlc3Npb25zLCBvdXRwdXQgcmVncmVzc2lvbiB0YWJsZXMsIGFuZCBkaXNjdXNzIHRoZSByZWxhdGlvbnNoaXBzIHlvdSBmaW5kIGluY2x1ZGluZyBhIGRpc2N1c3Npb24gb2Ygc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlOg0KICAtIEdvbGQgdnMgSW5mbGF0aW9uXCANCiAgLSBHb2xkIHZzIEludGVyZXN0IFJhdGVzXCANCiAgLSBJbmZsYXRpb24gdnMgSW50ZXJlc3QgUmF0ZXNcIA0KICAtIEdvbGQgdnMgSW50ZXJlc3QgUmF0ZXMgYW5kIEluZmxhdGlvblwgPGJyPg0KICoqNC4qKiBEaXNjdXNzIHdoZXRoZXIgdGhlIHJlZ3Jlc3Npb24gb2YgR29sZCBvbiBib3RoIGludGVyZXN0IHJhdGVzIGFuZCBpbmZsYXRpb24gKGQpIGlzIGEgYmV0dGVyIG1vZGVsIHRoYW4gdGhlIHJlZ3Jlc3Npb24gb2YgZ29sZCBvbiBpbnRlcmVzdCByYXRlcyAoYikgYW5kIGdvbGQgb24gaW5mbGF0aW9uIChhKSBpbmRpdmlkdWFsbHkuXCA8YnI+DQogKio1LioqIEV2YWx1YXRlIHRoZSBHb2xkIHZzIEludGVyZXN0IFJhdGUgYW5kIEluZmxhdGlvbiByZWdyZXNzaW9uIChkKSBpbiBwYXJ0IDMgZm9yIHZpb2xhdGlvbnMgb2YgdGhlIGFzc3VtcHRpb25zIG9mIE9MUyBhbmQgaWRlbnRpZnkgYW55IGlzc3VlcyByZWdhcmRpbmc6XCANCiAgLSBIZXRlcm9za2VkYXN0aWNpdHlcIA0KICAtIEF1dG9jb3JyZWxhdGlvbi9TZXJpYWwgQ29ycmVsYXRpb25cIA0KICAtIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMgKFEtUSBwbG90LCBIaXN0b2dyYW0sIGFuZCBhIGZvcm1hbCB0ZXN0KVwgDQogIC0gSW5jbHVkZSBhIGRpc2N1c3Npb24gb2YgaG93IGFueSBpc3N1ZXMgbWF5IGFmZmVjdCB5b3VyIHJlc3VsdHMuXCA8YnI+DQogKio2LioqIElmIHRoZXJlIGFyZSBwcm9ibGVtcyBpZGVudGlmaWVkIGluIHBhcnQgNSB0aGF0IHNob3VsZCBiZSBhZGRyZXNzZWQsIHJlLXJ1biB0aGUgcmVncmVzc2lvbiBvZiBHb2xkIG9uIEludGVyZXN0IFJhdGVzIGFuZCBJbmZsYXRpb24gd2l0aCBhcHByb3ByaWF0ZSBjb3JyZWN0aW9ucy5cIDxicj4NCiAqKjcuKiogT25lIG9mIHRoZSBtb3JlIGRpZmZpY3VsdCB0byBldmFsdWF0ZSBhc3N1bXB0aW9ucyBvZiBPTFMgaXMgZXhvZ2VuZWl0eS4gRG8geW91IHRoaW5rIHRoZSByZWdyZXNzaW9uIG9mIEdvbGQgb24gSW5mbGF0aW9uIGFuZCBJbnRlcmVzdCByYXRlcyBpcyBsaWtlbHkgdG8gdmlvbGF0ZSB0aGlzIGFzc3VtcHRpb24gYW5kIHdoeT9cIDxicj4NCiAqKjguKiogRW5kIHdpdGggYSBicmllZiAoMi0zIHNlbnRlbmNlKSBjb25jbHVzaW9uIG9uIHRoZSB1c2Ugb2YgR29sZCBhcyBhbiBpbmZsYXRpb24gaGVkZ2UgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQgYW5kIGFueSBzdWdnZXN0ZWQgbmV4dCBzdGVwcy5cIDxicj4NCg0KDQoNCg0KDQojIyBHb2xkIExvZyBSZXR1cm5zDQoNCioqR29sZDogTW9udGhseSBsb2cgcmV0dXJucyBnZW5lcmF0ZWQgZnJvbSB0aGUgY2xvc2UgcHJpY2Ugb2YgdGhlIEVURiDigJxTUERSIEdvbGQgU2hhcmVz4oCdICoqDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkZjwtdGlkeXF1YW50Ojp0cV9nZXQoeD1jKCJHTEQiKSwgI0dMRCBpcyB0aGUgdGlja2VyIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0PSJzdG9jay5wcmljZXMiLCAjc3RvY2sucHJpY2VzID50cV9nZXQgPllhaG9vIEZpbmFuY2UNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gPSIyMDA1LTAxLTAxIiwgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdG89ICIyMDE4LTEyLTMxIikgJT4lICANCiAgdHFfdHJhbnNtdXRlKHNlbGVjdCA9IGNsb3NlLCBtdXRhdGVfZnVuID0gdG8ubW9udGhseSxpbmRleEF0ID0gImZpcnN0b2YiKSANCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBOb3RlLCB0aGUgZGF0YSB3ZSBnZXQgZGFpbHksIHdlIGhhdmUgdG8gdHJhbnNtdXRlIHRoZSBkYXRhIHRvIG1vbnRobHkgYW5kIGZpcnN0IGRheSBvZiB0aGUgbW9udGguLi4NCiMgImxhc3RvZiIgd291bGQgdGFrZSBmcm9tIHRoZSBsYXN0IGRheQ0KZGYgPC0gZGYgJT4lDQogIG11dGF0ZShHb2xkX0xvZ19SZXR1cm4gPSBjKE5BLCBkaWZmKGxvZyhkZiRjbG9zZSkpKSkNCg0KDQpkZiAlPiUgDQogIGdncGxvdChhZXMoZGF0ZSwgR29sZF9Mb2dfUmV0dXJuKSkgKw0KICBnZW9tX2xpbmUoc2l6ZSA9IDEpICsNCiAgbGFicyh0aXRsZSA9ICJDbG9zZSBQcmljZSBhbmQgR29sZCBMb2cgUmV0dXJuIE92ZXIgVGltZSIsDQogICAgICAgeCA9ICJEYXRlIiwNCiAgICAgICB5ID0gIkdvbGRfTG9nX1JldHVybiIpICsNCiAgdGhlbWUocGxvdC50aXRsZS5wb3NpdGlvbiA9ICdwbG90JywgDQogICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkrDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmhlYWQoZGYpICU+JQ0KICBndCgpICU+JSANCiAgZ3RfdGhlbWVfZ3VhcmRpYW4oKSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSAiQ2xvc2UgUHJpY2UgYW5kIEdvbGQgTG9nIFJldHVybiBPdmVyIFRpbWUiKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkZiAlPiUgDQogIGd0X3BsdF9zdW1tYXJ5KHRpdGxlID0gIlRoaXMgaXMgdGhlIHN1bW1hcnkgb2YgR29sZCBMb2cgUmV0dXJuIE92ZXIgVGltZSIpDQoNCmBgYA0KDQojIyBJbmZsYXRpb24NCjxicj4NCioqQ29uc3VtZXIgUHJpY2UgSW5kZXggZm9yIEFsbCBVcmJhbiBDb25zdW1lcnMoU2Vhc29uYWxseSBBZGp1c3RlZCk6IEFsbCBJdGVtcyBpbiBVLlMuIENpdHkgQXZlcmFnZSAoQ1BJQVVDU0wpKipcDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGZfY3BpPC10aWR5cXVhbnQ6OnRxX2dldChjKCJDUElBVUNTTCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldD0iZWNvbm9taWMuZGF0YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tPSIyMDA1LTAxLTAxIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICB0bz0iMjAxOC0xMi0zMSIpDQoNCmRmIDwtIGRmICU+JQ0KICBtdXRhdGUoSW5mbGF0aW9uX1JhdGVfb2ZfQ2hhbmdlID0gKGRmX2NwaSRwcmljZSAvIGxhZyhkZl9jcGkkcHJpY2UsIDEpIC0gMSkgKiAxMDApDQpgYGANCg0KYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KaGVhZChkZikgJT4lDQogIGd0KCkgJT4lIA0KICBndF90aGVtZV9ndWFyZGlhbigpICU+JSANCiAgdGFiX2hlYWRlcih0aXRsZSA9ICJDbG9zZSBQcmljZSwgR29sZCBMb2cgUmV0dXJuIGFuZCBJbmZsYXRpb24gUmF0ZSBvZiBDaGFuZ2UgT3ZlciBUaW1lIikNCmBgYA0KDQpgYGB7ciBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkZiAlPiUgDQogIGd0X3BsdF9zdW1tYXJ5KHRpdGxlID0gIlN1bW1hcnkgb2YgR29sZCBMb2cgUmV0dXJuIGFuZCBJbmZsYXRpb24gUmF0ZSBvZiBDaGFuZ2UgT3ZlciBUaW1lIikNCmBgYA0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KIyBDYWxjdWxhdGUgdGhlIG1vbnRobHkgcmF0ZSBvZiBjaGFuZ2UgdXNpbmcgbGFnIGZ1bmN0aW9uDQojIGRmJFJhdGVfb2ZfQ2hhbmdlIDwtIChkZiRwcmljZSAvIGxhZyhkZiRwcmljZSwgMSkgLSAxKSAqIDEwMA0KIyBFeHBsYW5hdGlvbjoNCiMgbGFnKENQSSRwcmljZSwgMSk6IFNoaWZ0cyB0aGUgcHJpY2Ugc2VyaWVzIGJ5IG9uZSB0aW1lIHBlcmlvZCB0byByZWZlcmVuY2UgdGhlIHByZXZpb3VzIG1vbnRoLg0KIyBDUEkkcHJpY2UgLyBsYWcoQ1BJJHByaWNlLCAxKSAtIDE6IFRoaXMgY2FsY3VsYXRlcyB0aGUgcGVyY2VudGFnZSBjaGFuZ2UgcmVsYXRpdmUgdG8gdGhlIHByZXZpb3VzIG1vbnRoLg0KIyBUaGUgKiAxMDAgY29udmVydHMgdGhlIHJhdGUgb2YgY2hhbmdlIGludG8gYSBwZXJjZW50YWdlLg0KIyBUaGVyZeKAmXMgbm8gbmVlZCB0byB1c2UgZGlmZigpIHNpbmNlIHdlJ3JlIGNvbXBhcmluZyBlYWNoIG1vbnRoIHRvIHRoZSBwcmV2aW91cyBvbmUuDQojIE5vdywgdGhlIFJhdGVfb2ZfQ2hhbmdlIGNvbHVtbiBzaG91bGQgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYXMgeW91ciBvcmlnaW5hbCBkYXRhIGZyYW1lIHdpdGggdGhlIGZpcnN0IHZhbHVlIGJlaW5nIE5BIGR1ZSB0byB0aGUgbGFnZ2luZyBwcm9jZXNzLg0KYGBgDQoNCiMjIEludGVyZXN0IFJhdGUNCjxicj4NCioqTWFya2V0IFlpZWxkIG9uIFUuUy4gVHJlYXN1cnkgU2VjdXJpdGllcyBhdCAyLVllYXIgQ29uc3RhbnQgTWF0dXJpdHksIFF1b3RlZCBvbiBhbiBJbnZlc3RtZW50IEJhc2lzIChER1MyKSoqXA0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KZGZfaXI8LXRpZHlxdWFudDo6dHFfZ2V0KGMoIkRHUzIiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGdldD0iZWNvbm9taWMuZGF0YSIsICNlY29ub21pYy5kYXRhIGluZGljYXRlcyBGUkVEDQogICAgICAgICAgICAgICAgICAgICAgICAgIGZyb209IjIwMDUtMDEtMDEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG89IjIwMTgtMTItMzEiKSAlPiUgDQogIHRpZHlyOjpwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3ltYm9sLCB2YWx1ZXNfZnJvbSA9IHByaWNlKSAlPiUgDQogIHRxX3RyYW5zbXV0ZShtdXRhdGVfZnVuID0gdG8ubW9udGhseSwgaW5kZXhBdCA9ICJmaXJzdG9mIikNCg0KZGYgPC0gZGYgJT4lDQogIGxlZnRfam9pbihkZl9pciAlPiUgDQogICAgICAgICAgICAgIHNlbGVjdChkYXRlLCBJbnRlcmVzdF9SYXRlX0NoYW5nZSA9IERHUzIpLCBieSA9IGMoImRhdGUiID0gImRhdGUiKSkNCg0KYGBgDQoNCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmhlYWQoZGYpICU+JQ0KICBndCgpICU+JSANCiAgZ3RfdGhlbWVfZ3VhcmRpYW4oKSAlPiUgDQogIHRhYl9oZWFkZXIodGl0bGUgPSAiQ2xvc2UgUHJpY2UsIEdvbGQgTG9nIFJldHVybiwgSW5mbGF0aW9uIFJhdGUgYW5kIEludGVyZXN0IFJhdGUgb2YgQ2hhbmdlIE92ZXIgVGltZSIpDQpgYGANCg0KYGBge3IgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGYgJT4lIA0KICBndF9wbHRfc3VtbWFyeSh0aXRsZSA9ICJUaGlzIGlzIHRoZSBTdW1tYXJ5IikNCmBgYA0KDQojIyBDYWxjdWxhdGlvbnMNCjxicj4NCioqUmVsYXRpb25zaGlwIGJldHdlZW4gR29sZCBtb250aGx5IGxvZyByZXR1cm5zLFZTIEluZmxhdGlvbiAobW9udGhseSByYXRlIG9mIGNoYW5nZSkgVlMgSW50ZXJlc3QgcmF0ZXMgKGNoYW5nZSBpbiBtYXJrZXQgeWllbGQpKioNCg0KKip3ZSBjYW4gdXNlIG11bHRpcGxlIHJlZ3Jlc3Npb24gYW5hbHlzaXMuIEluIHRoaXMgYW5hbHlzaXM6Kio8YnI+DQo8cD5UaGUgZGVwZW5kZW50IHZhcmlhYmxlIGNvdWxkIGJlIEdvbGQgcmV0dXJucy4NClRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMgd291bGQgYmUgSW5mbGF0aW9uIChtb250aGx5IHJhdGUgb2YgY2hhbmdlKSBhbmQgSW50ZXJlc3QgcmF0ZXMgKGNoYW5nZSBpbiBtYXJrZXQgeWllbGQpLlwNCjxwPldlIGNhbiBydW4gYSBtdWx0aXBsZSBsaW5lYXIgcmVncmVzc2lvbiB0byBzZWUgaG93IGNoYW5nZXMgaW4gSW5mbGF0aW9uIGFuZCBJbnRlcmVzdCByYXRlcyBhZmZlY3QgdGhlIGxvZyByZXR1cm5zIG9mIEdvbGQuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQptb2RlbCA8LSBsbShHb2xkX0xvZ19SZXR1cm4gfiBJbmZsYXRpb25fUmF0ZV9vZl9DaGFuZ2UgKyBJbnRlcmVzdF9SYXRlX0NoYW5nZSwgZGF0YSA9IGRmKQ0KbW9kZWxfc3VtbWFyeSA8LSBzdW1tYXJ5KG1vZGVsKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIFJlc2lkdWFscyBzdW1tYXJ5DQpyZXNpZHVhbHMgPC0gbW9kZWxfc3VtbWFyeSRyZXNpZHVhbHMNCnJlc2lkdWFsc19zdW1tYXJ5IDwtIGMobWluKHJlc2lkdWFscyksIHF1YW50aWxlKHJlc2lkdWFscywgYygwLjI1LCAwLjUsIDAuNzUpKSwgbWF4KHJlc2lkdWFscykpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgRm9ybWF0IHRoZSByZXNpZHVhbHMgaW4gYSBkYXRhIGZyYW1lIGZvciBiZXR0ZXIgcHJlc2VudGF0aW9uDQpyZXNpZHVhbHNfZGYgPC0gZGF0YS5mcmFtZSgNCiAgU3RhdGlzdGljID0gYygiTWluIiwgIjFRIiwgIk1lZGlhbiIsICIzUSIsICJNYXgiKSwNCiAgVmFsdWUgPSByb3VuZChyZXNpZHVhbHNfc3VtbWFyeSwgNikNCikNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBGb3JtYXQgdGhlIGNvZWZmaWNpZW50cyBpbiBhIGRhdGEgZnJhbWUgZm9yIGJldHRlciBwcmVzZW50YXRpb24NCmNvZWZmaWNpZW50c19kZiA8LSBkYXRhLmZyYW1lKA0KICBWYXJpYWJsZSA9IHJvd25hbWVzKG1vZGVsX3N1bW1hcnkkY29lZmZpY2llbnRzKSwNCiAgRXN0aW1hdGUgPSByb3VuZChtb2RlbF9zdW1tYXJ5JGNvZWZmaWNpZW50c1ssIDFdLCA3KSwNCiAgYFN0ZC4gRXJyb3JgID0gcm91bmQobW9kZWxfc3VtbWFyeSRjb2VmZmljaWVudHNbLCAyXSwgNyksDQogIGB0LXZhbHVlYCA9IHJvdW5kKG1vZGVsX3N1bW1hcnkkY29lZmZpY2llbnRzWywgM10sIDMpLA0KICBgcC12YWx1ZWAgPSByb3VuZChtb2RlbF9zdW1tYXJ5JGNvZWZmaWNpZW50c1ssIDRdLCAzKQ0KKQ0KYGBgDQoNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgRXh0cmFjdCBtb2RlbCBzdGF0aXN0aWNzDQpyc2UgPC0gcm91bmQobW9kZWxfc3VtbWFyeSRzaWdtYSwgNSkNCnJfc3F1YXJlZCA8LSByb3VuZChtb2RlbF9zdW1tYXJ5JHIuc3F1YXJlZCwgNSkNCmFkal9yX3NxdWFyZWQgPC0gcm91bmQobW9kZWxfc3VtbWFyeSRhZGouci5zcXVhcmVkLCA3KQ0KZl9zdGF0aXN0aWMgPC0gcm91bmQobW9kZWxfc3VtbWFyeSRmc3RhdGlzdGljWzFdLCA0KQ0KZl9wdmFsdWUgPC0gcm91bmQocGYobW9kZWxfc3VtbWFyeSRmc3RhdGlzdGljWzFdLCANCiAgICAgICAgICAgICAgICAgICAgIG1vZGVsX3N1bW1hcnkkZnN0YXRpc3RpY1syXSwgDQogICAgICAgICAgICAgICAgICAgICBtb2RlbF9zdW1tYXJ5JGZzdGF0aXN0aWNbM10sIA0KICAgICAgICAgICAgICAgICAgICAgbG93ZXIudGFpbCA9IEZBTFNFKSwgNCkNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Ka2FibGUocmVzaWR1YWxzX2RmKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQprYWJsZShjb2VmZmljaWVudHNfZGYpDQpgYGANCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNhdChwYXN0ZSgiUmVzaWR1YWwgU3RhbmRhcmQgRXJyb3I6IiwgcnNlLCAiKG9uIiwgbW9kZWxfc3VtbWFyeSRkZlsyXSwgImRlZ3JlZXMgb2YgZnJlZWRvbSlcbiIpKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjYXQocGFzdGUoIk11bHRpcGxlIFItc3F1YXJlZDoiLCByX3NxdWFyZWQsICJcbiIpKQ0KYGBgDQoNCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpjYXQocGFzdGUoIkFkanVzdGVkIFItc3F1YXJlZDoiLCBhZGpfcl9zcXVhcmVkLCAiXG4iKSkNCmBgYA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KY2F0KHBhc3RlKCJGLXN0YXRpc3RpYzoiLCBmX3N0YXRpc3RpYywgIihvbiIsIG1vZGVsX3N1bW1hcnkkZnN0YXRpc3RpY1syXSwgImFuZCIsIG1vZGVsX3N1bW1hcnkkZnN0YXRpc3RpY1szXSwgIkRGKSAgcC12YWx1ZToiLCBmX3B2YWx1ZSwgIlxuIikpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbGlicmFyeShzdGFyZ2F6ZXIpDQojIFJlZ3Jlc3Npb25zDQpyZWdfYSA8LSBsbShHb2xkX0xvZ19SZXR1cm4gfiBJbmZsYXRpb25fUmF0ZV9vZl9DaGFuZ2UsIGRhdGEgPSBkZikNCg0KcmVnX2IgPC0gbG0oR29sZF9Mb2dfUmV0dXJuIH4gSW50ZXJlc3RfUmF0ZV9DaGFuZ2UsIGRhdGEgPSBkZikNCg0KcmVnX2MgPC0gbG0oSW5mbGF0aW9uX1JhdGVfb2ZfQ2hhbmdlIH4gSW50ZXJlc3RfUmF0ZV9DaGFuZ2UsIGRhdGEgPSBkZikNCg0KcmVnX2QgPC0gbG0oR29sZF9Mb2dfUmV0dXJuIH4gSW50ZXJlc3RfUmF0ZV9DaGFuZ2UgKyBJbmZsYXRpb25fUmF0ZV9vZl9DaGFuZ2UsIGRhdGEgPSBkZikNCg0Kc3RhcmdhemVyKHJlZ19hLCByZWdfYiwgcmVnX2MsIHJlZ19kLCANCiAgICAgICAgICB0eXBlID0gInRleHQiLCAgICAgICAgIyAndGV4dCcgZm9yIGNvbnNvbGUsICdodG1sJyBvciAnbGF0ZXgnIGZvciBkb2N1bWVudHMNCiAgICAgICAgICB0aXRsZSA9ICJSZWdyZXNzaW9uIFJlc3VsdHM6IEdvbGQsIEluZmxhdGlvbiwgYW5kIEludGVyZXN0IFJhdGVzIiwgDQogICAgICAgICAgZGVwLnZhci5sYWJlbHMgPSBjKCJHb2xkIExvZyBSZXR1cm4iLCAiSW5mbGF0aW9uIFJhdGUgb2YgQ2hhbmdlIiksDQogICAgICAgICAgY292YXJpYXRlLmxhYmVscyA9IGMoIkluZmxhdGlvbiBSYXRlIG9mIENoYW5nZSIsICJJbnRlcmVzdCBSYXRlIENoYW5nZSIpLA0KICAgICAgICAgIG91dCA9ICJyZWdyZXNzaW9uX291dHB1dC50eHQiKSAgIyBzYXZlIHRoZSBvdXRwdXQgdG8gYSAudHh0IGZpbGUNCg0KYGBgDQoNCkJyZXVzY2gtUGFnYW4gVGVzdCBmb3IgSGV0ZXJvc2tlZGFzdGljaXR5DQpgYGB7cn0NCmxpYnJhcnkobG10ZXN0KQ0KYnB0ZXN0KHJlZ19kKQ0KYGBgDQoNCkludGVycHJldGF0aW9uOg0KSWYgdGhlIHAtdmFsdWUgaXMgbGVzcyB0aGFuIDAuMDUsIHRoZW4geW91IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHksIG1lYW5pbmcgdGhlcmUgaXMgZXZpZGVuY2Ugb2YgaGV0ZXJvc2tlZGFzdGljaXR5Lg0KSGV0ZXJvc2tlZGFzdGljaXR5IGFmZmVjdHMgdGhlIHN0YW5kYXJkIGVycm9ycywgd2hpY2ggbWVhbnMgdGhlIHNpZ25pZmljYW5jZSBvZiB5b3VyIGNvZWZmaWNpZW50cyBtaWdodCBiZSBtaXNlc3RpbWF0ZWQuDQoNClBsb3R0aW5nIFJlc2lkdWFscyB2cy4gRml0dGVkIFZhbHVlcw0KYGBge3J9DQojIFBsb3QgcmVzaWR1YWxzIHZzIGZpdHRlZCB2YWx1ZXMNCnBsb3QocmVnX2QkZml0dGVkLnZhbHVlcywgcmVnX2QkcmVzaWR1YWxzLCANCiAgICAgeGxhYiA9ICJGaXR0ZWQgVmFsdWVzIiwgeWxhYiA9ICJSZXNpZHVhbHMiLCANCiAgICAgbWFpbiA9ICJSZXNpZHVhbHMgdnMgRml0dGVkIikNCmFibGluZShoID0gMCwgY29sID0gInJlZCIpDQoNCmBgYA0KSW50ZXJwcmV0YXRpb246DQpJZiB0aGUgc3ByZWFkIG9mIHJlc2lkdWFscyBpbmNyZWFzZXMgb3IgZGVjcmVhc2VzIGFzIHRoZSBmaXR0ZWQgdmFsdWVzIGluY3JlYXNlLCB0aGlzIGluZGljYXRlcyBoZXRlcm9za2VkYXN0aWNpdHkuDQoNCg0KQXV0b2NvcnJlbGF0aW9uL1NlcmlhbCBDb3JyZWxhdGlvbjoNCmBgYHtyfQ0KIyBQZXJmb3JtIER1cmJpbi1XYXRzb24gdGVzdCBmb3IgYXV0b2NvcnJlbGF0aW9uDQpkd3Rlc3QocmVnX2QpDQoNCmBgYA0KSW50ZXJwcmV0YXRpb246DQpUaGUgRHVyYmluLVdhdHNvbiBzdGF0aXN0aWMgcmFuZ2VzIGZyb20gMCB0byA0Lg0KQSB2YWx1ZSBuZWFyIDIgaW5kaWNhdGVzIG5vIGF1dG9jb3JyZWxhdGlvbi4NCkEgdmFsdWUgY2xvc2VyIHRvIDAgaW5kaWNhdGVzIHBvc2l0aXZlIGF1dG9jb3JyZWxhdGlvbi4NCkEgdmFsdWUgY2xvc2VyIHRvIDQgaW5kaWNhdGVzIG5lZ2F0aXZlIGF1dG9jb3JyZWxhdGlvbi4NCklmIHRoZSBwLXZhbHVlIGlzIGxlc3MgdGhhbiAwLjA1LCBhdXRvY29ycmVsYXRpb24gaXMgcHJlc2VudCwgd2hpY2ggY2FuIGJpYXMgdGhlIGNvZWZmaWNpZW50IGVzdGltYXRlcyBhbmQgYWZmZWN0IGh5cG90aGVzaXMgdGVzdGluZy4NCg0KDQoNCg0KUS1RIFBsb3QgZm9yIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCmBgYHtyfQ0KIyBRLVEgcGxvdCBmb3Igbm9ybWFsaXR5DQpxcW5vcm0ocmVzaWR1YWxzKHJlZ19kKSkNCnFxbGluZShyZXNpZHVhbHMocmVnX2QpLCBjb2wgPSAicmVkIikNCg0KYGBgDQpJbnRlcnByZXRhdGlvbjoNCklmIHRoZSBwb2ludHMgZm9sbG93IHRoZSA0NS1kZWdyZWUgbGluZSBjbG9zZWx5LCB0aGVuIHRoZSByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLg0KRGV2aWF0aW9ucyBmcm9tIHRoZSBsaW5lIHN1Z2dlc3Qgbm9uLW5vcm1hbGl0eS4NCg0KDQoNCg0KDQpIaXN0b2dyYW0gb2YgUmVzaWR1YWxzDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIHJlc2lkdWFscw0KaGlzdChyZXNpZHVhbHMocmVnX2QpLCBtYWluID0gIkhpc3RvZ3JhbSBvZiBSZXNpZHVhbHMiLCANCiAgICAgeGxhYiA9ICJSZXNpZHVhbHMiLCBjb2wgPSAibGlnaHRibHVlIikNCg0KYGBgDQpJbnRlcnByZXRhdGlvbjoNCkEgYmVsbC1zaGFwZWQgaGlzdG9ncmFtIHN1Z2dlc3RzIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQoNCg0KDQpTaGFwaXJvLVdpbGsgVGVzdCBmb3IgTm9ybWFsaXR5DQpgYGB7cn0NCiMgUGVyZm9ybSBTaGFwaXJvLVdpbGsgdGVzdCBmb3Igbm9ybWFsaXR5DQpzaGFwaXJvLnRlc3QocmVzaWR1YWxzKHJlZ19kKSkNCg0KYGBgDQpJbnRlcnByZXRhdGlvbjoNCklmIHRoZSBwLXZhbHVlIGlzIGxlc3MgdGhhbiAwLjA1LCB0aGUgcmVzaWR1YWxzIGFyZSBub3Qgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuIE5vbi1ub3JtYWxpdHkgY2FuIGFmZmVjdCB0aGUgdmFsaWRpdHkgb2YgY29uZmlkZW5jZSBpbnRlcnZhbHMgYW5kIGh5cG90aGVzaXMgdGVzdHMuDQoNCg0KSGV0ZXJvc2tlZGFzdGljaXR5Og0KYGBge3J9DQpsaWJyYXJ5KHNhbmR3aWNoKQ0KDQojIFJlLXJ1biB0aGUgcmVncmVzc2lvbiB3aXRoIHJvYnVzdCBzdGFuZGFyZCBlcnJvcnMNCmNvZWZ0ZXN0KHJlZ19kLCB2Y292ID0gdmNvdkhDKHJlZ19kLCB0eXBlID0gIkhDMSIpKQ0KYGBgDQoNCg0KDQo8YnI+DQoqKk1vZGVsIFN1bW1hcnkqKjxicj4NCioqR29sZF9Mb2dfUmV0dXJuIOKIvCBJbmZsYXRpb25fUmF0ZV9vZl9DaGFuZ2UgKyBJbnRlcmVzdF9SYXRlX0NoYW5nZSoqPGJyPg0KPHA+VGhpcyBpbmRpY2F0ZXMgdGhhdCB3ZSBhcmUgdHJ5aW5nIHRvIGV4cGxhaW4gdGhlIGxvZyByZXR1cm5zIG9mIGdvbGQgdXNpbmcgY2hhbmdlcyBpbiBpbmZsYXRpb24gcmF0ZXMgYW5kIGNoYW5nZXMgaW4gaW50ZXJlc3QgcmF0ZXMuPGJyPg0KDQoqKlJlc2lkdWFsczoqKg0KPHA+IFRoZSByZXNpZHVhbHMgYXJlIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBvYnNlcnZlZCB2YWx1ZXMgYW5kIHRoZSBwcmVkaWN0ZWQgdmFsdWVzIGZyb20gdGhlIG1vZGVsLiBUaGUgc3VtbWFyeSBzdGF0aXN0aWNzIGluZGljYXRlIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgZmFpcmx5IHN5bW1ldHJpY2FsbHkgZGlzdHJpYnV0ZWQsIHdpdGggbWluaW11bSBhbmQgbWF4aW11bSB2YWx1ZXMgc2hvd2luZyBzb21lIGRpc3BlcnNpb24gYXJvdW5kIHplcm8uPGJyPg0KKipDb2VmZmljaWVudHM6KioNCioqSW50ZXJjZXB0OioqIA0KMC4wMDAzNDE0DQo8cD5UaGlzIGlzIHRoZSBlc3RpbWF0ZWQgdmFsdWUgb2YgR29sZCBMb2cgUmV0dXJucyB3aGVuIGJvdGggSW5mbGF0aW9uIFJhdGUgb2YgQ2hhbmdlIGFuZCBJbnRlcmVzdCBSYXRlIENoYW5nZSBhcmUgemVyby4NCg0KPGJyPg0KKipJbmZsYXRpb24gUmF0ZSBvZiBDaGFuZ2U6ICoqDQowLjAwNzUyNTgNCjxwPkZvciBlYWNoIHVuaXQgaW5jcmVhc2UgaW4gdGhlIGluZmxhdGlvbiByYXRlIGNoYW5nZSwgdGhlIEdvbGQgTG9nIFJldHVybiBpcyBlc3RpbWF0ZWQgdG8gaW5jcmVhc2UgYnkgYXBwcm94aW1hdGVseSAwLjAwNzUsIGhvbGRpbmcgdGhlIGludGVyZXN0IHJhdGUgY2hhbmdlIGNvbnN0YW50LiBIb3dldmVyLCB0aGUgcC12YWx1ZSAoMC41NTMpIGluZGljYXRlcyB0aGF0IHRoaXMgY29lZmZpY2llbnQgaXMgbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHN1Z2dlc3RpbmcgYSB3ZWFrIHJlbGF0aW9uc2hpcC4NCg0KPGJyPg0KKipJbnRlcmVzdCBSYXRlIENoYW5nZTogKioNCjAuMDAyODI4OQ0KPHA+Rm9yIGVhY2ggdW5pdCBpbmNyZWFzZSBpbiB0aGUgaW50ZXJlc3QgcmF0ZSBjaGFuZ2UsIHRoZSBHb2xkIExvZyBSZXR1cm4gaXMgZXN0aW1hdGVkIHRvIGluY3JlYXNlIGJ5IGFwcHJveGltYXRlbHkgMC4wMDI4LCBob2xkaW5nIHRoZSBpbmZsYXRpb24gcmF0ZSBjaGFuZ2UgY29uc3RhbnQuIFRoZSBwLXZhbHVlICgwLjI3Nykgc3VnZ2VzdHMgdGhpcyBjb2VmZmljaWVudCBpcyBhbHNvIG5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50Lg0KDQoNCjxicj4NCioqUmVzaWR1YWwgU3RhbmRhcmQgRXJyb3I6KioNCjAuMDUxMDQgaW5kaWNhdGVzIHRoZSBhdmVyYWdlIGRpc3RhbmNlIHRoYXQgdGhlIG9ic2VydmVkIHZhbHVlcyBmYWxsIGZyb20gdGhlIHJlZ3Jlc3Npb24gbGluZS4NCg0KDQo8YnI+DQoqKlItc3F1YXJlZDoqKlwNCk11bHRpcGxlIFItc3F1YXJlZDogDQowLjAxMTI3PGJyPg0KQWRqdXN0ZWQgUi1zcXVhcmVkOiANCuKIkjAuMDAwNzg5NA0KPHA+VGhpcyBzdWdnZXN0cyB0aGF0IG9ubHkgYWJvdXQgMS4xJSBvZiB0aGUgdmFyaWFiaWxpdHkgaW4gR29sZCBMb2cgUmV0dXJucyBpcyBleHBsYWluZWQgYnkgdGhlIG1vZGVsLiBUaGUgYWRqdXN0ZWQgUi1zcXVhcmVkIGJlaW5nIG5lZ2F0aXZlIGltcGxpZXMgdGhhdCB0aGUgbW9kZWwgaXMgbm90IGJldHRlciB0aGFuIGEgc2ltcGxlIG1lYW4gbW9kZWwsIGluZGljYXRpbmcgcG9vciBleHBsYW5hdG9yeSBwb3dlci48YnI+DQoNCg0KKipGLXN0YXRpc3RpYyBhbmQgcC12YWx1ZToqKg0KDQoqKkYtc3RhdGlzdGljOioqIDAuOTM0NSB3aXRoICoqcC12YWx1ZToqKiAwLjM5NDkNClRoZSBvdmVyYWxsIG1vZGVsIGlzICoqbm90IHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQqKiwgc3VnZ2VzdGluZyB0aGF0IG5laXRoZXIgb2YgdGhlIHByZWRpY3RvciB2YXJpYWJsZXMgDQooSW5mbGF0aW9uIFJhdGUgb2YgQ2hhbmdlIGFuZCBJbnRlcmVzdCBSYXRlIENoYW5nZSkgY29udHJpYnV0ZSBtZWFuaW5nZnVsbHkgdG8gZXhwbGFpbmluZyB0aGUgdmFyaWF0aW9uIGluIEdvbGQgTG9nIFJldHVybnMuDQo8YnI+DQoNCg0KKipJbXBsaWNhdGlvbnMgb2YgdGhlIE1vZGVsIFdlYWsgUmVsYXRpb25zaGlwczogKioNCjxwPiBUaGUgY29lZmZpY2llbnRzIGZvciBib3RoIGluZmxhdGlvbiBhbmQgaW50ZXJlc3QgcmF0ZSBjaGFuZ2VzIGFyZSAqKm5vdCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50KiosIA0KbWVhbmluZyB0aGVyZSBpcyBubyBzdHJvbmcgZXZpZGVuY2UgdG8gc3VnZ2VzdCB0aGF0IGNoYW5nZXMgaW4gaW5mbGF0aW9uIG9yIGludGVyZXN0IHJhdGVzIA0KaGF2ZSBhIG1lYW5pbmdmdWwgaW1wYWN0IG9uIGdvbGQgcmV0dXJucyBpbiB0aGlzIG1vZGVsLjxicj4NCg0KPHA+KipMb3cgUHJlZGljdGl2ZSBQb3dlcjoqKiBcDQpUaGUgbG93IFIyIChSLXNxdWFyZWQpIHZhbHVlcyBpbmRpY2F0ZSB0aGF0IHRoZSBtb2RlbCBkb2VzIG5vdCBleHBsYWluIG11Y2ggb2YgdGhlIHZhcmlhYmlsaXR5IGluIGdvbGQgbG9nIHJldHVybnMsIHN1Z2dlc3RpbmcgdGhhdCBvdGhlciBmYWN0b3JzIG5vdCBpbmNsdWRlZCBpbiB0aGUgbW9kZWwgbWF5IGJlIGluZmx1ZW5jaW5nIGdvbGQgcmV0dXJucy48YnI+DQoNCjxwPioqRnVydGhlciBJbnZlc3RpZ2F0aW9uOioqIEdpdmVuIHRoZXNlIHJlc3VsdHMsIGl0IG1heSBiZSB3b3J0aHdoaWxlIHRvIGV4cGxvcmUgYWRkaXRpb25hbCB2YXJpYWJsZXMsDQpjb25zaWRlciBub25saW5lYXIgcmVsYXRpb25zaGlwcywgb3IgZXhhbWluZSBpbnRlcmFjdGlvbnMgYW1vbmcgdmFyaWFibGVzIHRvIGJldHRlciB1bmRlcnN0YW5kIHdoYXQgaW5mbHVlbmNlcyBnb2xkIHJldHVybnMuPGJyPg0KDQo8cD4qKkNhdXRpb24gaW4gSW50ZXJwcmV0YXRpb246KiogVGhlIG5vbi1zaWduaWZpY2FuY2Ugb2YgdGhlIHByZWRpY3RvcnMgbWVhbnMgY2F1dGlvbiBzaG91bGQgYmUgdGFrZW4gd2hlbiBpbnRlcnByZXRpbmcgdGhlc2UgcmVsYXRpb25zaGlwcywgYXMgdGhleSBtYXkgbm90IGhvbGQgdHJ1ZSBvdXRzaWRlIG9mIHRoaXMgc3BlY2lmaWMgbW9kZWwuPGJyPg0KDQoqKkluIHN1bW1hcnksKiogdGhlIHJlZ3Jlc3Npb24gcmVzdWx0cyBpbXBseSB0aGF0IHRoZSBtb2RlbCBkb2VzIG5vdCBzaWduaWZpY2FudGx5IGV4cGxhaW4gdmFyaWF0aW9ucyBpbiBnb2xkIGxvZyByZXR1cm5zIGJhc2VkIG9uIGluZmxhdGlvbiBhbmQgaW50ZXJlc3QgcmF0ZSBjaGFuZ2VzLiBGdXJ0aGVyIGFuYWx5c2lzIG1heSBiZSBuZWVkZWQgdG8gaWRlbnRpZnkgb3RoZXIgaW5mbHVlbmNpbmcgZmFjdG9ycy4NCg0KDQo8YnI+DQoNCjxzcGFuPiAgPHNwYW4gc3R5bGU9ImNvbG9yOiBTdGVlbGJsdWU7Ij4qKk1kIE1haG11ZHVsIEhhc2FuKio8L3NwYW4+IFwNCk1RSU0gMzc2MDU3M1wNCkZhY3VsdHkgb2YgTWFuYWdlbWVudCBcDQpVbml2ZXJzaXR5IG9mIE5ldyBCcnVuc3dpY2sgXA0KbWFobXVkdWwuaGFzYW5cQHVuYi5jYSBcDQoNCjxicj4=