Assignment Objectives

  • Enhance understanding the procedure of likelihood-based chi-square hypothesis testing .

  • Implement the procedures for detecting overfitting/underfitting issues in practical applications.

Policies of Using AI Tools

Policy on AI Tool Use: Please adhere to the AI tool policy specified in the course syllabus. The direct copying of AI-generated content is strictly prohibited. All submitted work must reflect your own understanding; where external tools are consulted, content must be thoroughly rephrased and synthesized in your own words.

Code Inclusion Requirement: Any code included in your essay must be properly commented to explain the purpose and/or expected output of key code lines. Submitting AI-generated code without meaningful, student-added comments will not be accepted.

Testing Overfitting/Underfitting

In Machine Learning and Statistics, overfitting occurs when a model is too complex and learns noise, leading to poor performance on new data, while underfitting happens when a model is too simple to capture important patterns, resulting in high errors overall; both issues are explained by the Bias–Variance Tradeoff and can cause unreliable predictions in real-world applications.

The probability density function (PDF) of the Weibull distribution is:

\[ f(t; \lambda, \beta) = \frac{\beta}{\lambda} \left( \frac{t}{\lambda} \right)^{\beta-1} \exp\left[ -\left( \frac{t}{\lambda} \right)^\beta \right], \quad t \ge 0 \] where \(\lambda > 0\) is the scale parameter (characteristic life) and \(\beta > 0\) is the shape parameter.

When \(\beta = 1\), the Weibull PDF simplifies to the exponential PDF:

\[ f(t; \lambda) = \frac{1}{\lambda} \exp\left( -\frac{t}{\lambda} \right) \] with constant hazard rate \(h(t) = 1/\lambda\).

This assignment focuses on performing a hypothesis test for the shape parameter (\(\beta\)) of the Weibull distribution within a reliability mode

\[\begin{align} H_0&: \beta = 1 \quad \text{(Exponential model, simpler)} \\ H_1&: \beta \neq 1 \quad \text{(Weibull model, more complex)} \end{align}\]


Question: Reliability Application

A mid-sized manufacturing company producing industrial conveyor systems began experiencing unexpected downtime in one of its distribution facilities, prompting concern about the reliability of a newly sourced batch of ball bearings used in the motor assemblies. These bearings, supplied by a vendor adopting cost-saving production methods, were installed across multiple units operating under continuous load conditions. After several months, maintenance logs revealed a pattern of increasing failures, with components lasting anywhere from a few dozen to over 150 hours before breakdown. To investigate, the engineering team collected time-to-failure data from 50 identical bearings and conducted a Weibull analysis within the framework of Reliability Engineering. The 50 time-to-failure (survival time) are:

12.4, 18.7, 25.3, 30.1, 33.5, 35.2, 38.9, 40.3, 42.7, 45.1, 47.6, 49.8, 52.4, 55.0, 
57.3, 60.2, 62.8, 65.1, 67.9, 70.5, 72.3, 75.6, 78.2, 80.9, 83.4, 85.7, 88.1, 90.6, 
93.2, 95.8, 98.4, 101.0, 104.5, 107.3, 110.6, 113.2, 116.8, 120.1, 123.7, 127.4,
130.9, 134.5, 138.2, 142.0, 146.3, 150.7, 155.2, 160.8, 168.4, 175.9

This assignment focuses on hypothesis \(H_0: \beta = 1\) (exponential) against \(H_1: \beta \neq 1\) (Weibull). This framework detects overfitting (fitting a Weibull when exponential is true) and underfitting (fitting exponential when Weibull with \(\beta \neq 1\) is true).

a). Find the MLE of the Weibull parameters \(\lambda\) (scale) and \(\beta\) (shape), denoted by \(\hat{\lambda}\) and \(\hat{\beta}\), respectively, using the optim() procedure. [Hint: You should provide explicit expressions for the log-likelihood and gradient functions of the Weibull distribution parameters.]

############################################################
# HW: Weibull vs Exponential Model (Parts a–e)
# Data: Bearing time-to-failure (hours)
############################################################

# Input the data directly
t <- c(
  12.4, 18.7, 25.3, 30.1, 33.5, 35.2, 38.9, 40.3, 42.7, 45.1,
  47.6, 49.8, 52.4, 55.0, 57.3, 60.2, 62.8, 65.1, 67.9, 70.5,
  72.3, 75.6, 78.2, 80.9, 83.4, 85.7, 88.1, 90.6, 93.2, 95.8,
  98.4, 101.0, 104.5, 107.3, 110.6, 113.2, 116.8, 120.1, 123.7, 127.4,
  130.9, 134.5, 138.2, 142.0, 146.3, 150.7, 155.2, 160.8, 168.4, 175.9
)

n <- length(t)

############################################################
# (a) Weibull MLE using numerical optimization
############################################################

# Negative log-likelihood for Weibull
weibull_nll <- function(par, t) {
  lambda <- par[1]
  beta   <- par[2]
  
  # Enforce parameter constraints
  if (lambda <= 0 || beta <= 0) return(Inf)
  
  # Log-likelihood
  ll <- sum(log(beta/lambda) +
            (beta - 1)*log(t/lambda) -
            (t/lambda)^beta)
  
  return(-ll)  # minimize negative log-likelihood
}

# Initial parameter guesses
init <- c(lambda = mean(t), beta = 1)

# Run optimization
fit_weibull <- optim(init, weibull_nll, t = t, hessian = TRUE)

# Extract MLEs
lambda_hat <- fit_weibull$par[1]
beta_hat   <- fit_weibull$par[2]

cat("Weibull MLEs:\n")
Weibull MLEs:
cat("lambda_hat =", lambda_hat, "\n")
lambda_hat = 99.02759 
cat("beta_hat   =", beta_hat, "\n\n")
beta_hat   = 2.205876 

b). Find the MLE of the exponential parameter \(\lambda\) (scale), denoted by \(\hat{\lambda}\), using any procedure. [Hint: You should provide explicit expressions for the log-likelihood and gradient functions of the exponential distribution parameters.]

############################################################
# (b) Exponential MLE
############################################################

# MLE for exponential distribution
lambda_exp_hat <- mean(t)

cat("Exponential MLE:\n")
Exponential MLE:
cat("lambda_hat =", lambda_exp_hat, "\n\n")
lambda_hat = 87.61 

c). Perform the likelihood ratio \(\chi^2\) test on \(\beta = 1\). What is the p-value? [Hint: Use the results in a) and b).]

############################################################
# (c) Likelihood Ratio Test
############################################################

# Log-likelihood under Weibull
ll_weibull <- -fit_weibull$value

# Log-likelihood under exponential
ll_exp <- sum(-log(lambda_exp_hat) - t/lambda_exp_hat)

# LRT statistic
LRT_stat <- 2 * (ll_weibull - ll_exp)

# p-value
pval_LRT <- 1 - pchisq(LRT_stat, df = 1)

cat("Likelihood Ratio Test:\n")
Likelihood Ratio Test:
cat("LRT statistic =", LRT_stat, "\n")
LRT statistic = 34.44995 
cat("p-value       =", pval_LRT, "\n\n")
p-value       = 4.373535e-09 

d). Perform the Wald \(\chi^2\) on the same hypothesis \(\beta = 1\). What is the p-value? [Hint: You need to find the observed Fisher information matrix (i.e., the negative Hessian matrix from optim()) based on the Weibull distribution. The inverse of the negative observed Hessian matrix is the covariance matrix.]

############################################################
# (d) Wald Test
############################################################

# Variance-covariance matrix from Hessian
vcov_mat <- solve(fit_weibull$hessian)

# Variance of beta
var_beta <- vcov_mat[2,2]

# Wald statistic
W_stat <- (beta_hat - 1)^2 / var_beta

# p-value
pval_Wald <- 1 - pchisq(W_stat, df = 1)

cat("Wald Test:\n")
Wald Test:
cat("W statistic =", W_stat, "\n")
W statistic = 23.10901 
cat("p-value     =", pval_Wald, "\n\n")
p-value     = 1.530721e-06 

e). Write a summary of the above analyses to address the following:

  • Whether the two tests generated the same results.

  • Which model is recommended for the data.

  • Draw the density curve based on the MLE(s) of the parameter(s) and describe the distribution of the time-to-failure.

############################################################
# (e) Interpretation
############################################################

cat("Summary:\n")
Summary:
if (pval_LRT < 0.05 & pval_Wald < 0.05) {
  cat("Both tests reject H0: beta = 1.\n")
  cat("The Weibull model provides a significantly better fit.\n")
} else {
  cat("Fail to reject H0: exponential model may be adequate.\n")
}
Both tests reject H0: beta = 1.
The Weibull model provides a significantly better fit.
if (beta_hat > 1) {
  cat("beta_hat >", 1, ": increasing failure rate (wear-out behavior).\n")
} else if (beta_hat < 1) {
  cat("beta_hat <", 1, ": decreasing failure rate (early failures).\n")
} else {
  cat("beta_hat =", 1, ": constant failure rate.\n")
}
beta_hat > 1 : increasing failure rate (wear-out behavior).
############################################################
# Density Plot using Weibull MLEs
############################################################

# Create a sequence of x values
x_vals <- seq(min(t), max(t), length.out = 200)

# Weibull density using MLEs
weibull_density <- (beta_hat / lambda_hat) *
                   (x_vals / lambda_hat)^(beta_hat - 1) *
                   exp(-(x_vals / lambda_hat)^beta_hat)

# Plot histogram of data (scaled to density)
hist(t, probability = TRUE,
     main = "Weibull Fit to Time-to-Failure Data",
     xlab = "Time to Failure (hours)",
     border = "black")

# Overlay Weibull density curve
lines(x_vals, weibull_density, lwd = 2)

# Optional: add exponential curve for comparison
exp_density <- (1 / lambda_exp_hat) * exp(-x_vals / lambda_exp_hat)
lines(x_vals, exp_density, lwd = 2, lty = 2)

legend("topright",
       legend = c("Weibull Fit", "Exponential Fit"),
       lwd = 2,
       lty = c(1, 2))

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMTE6IERldGVjdGluZyBPdmVyZml0dGluZyBhbmQgT3ZlcmZpdHRpbmcgSXNzdWVzIg0KYXV0aG9yOiAiS2llcmFuIEhlZmZlcmFuICINCmRhdGU6ICIgRHVlOiA0LzE0LzI2ICINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUNCiAgICB0aGVtZTogc3BhY2VsYWINCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7YmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjsNCiAgICAgIGNvbG9yOiAjMDAwMDAwOw0KICAgICAgZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOw0KICAgICAgZm9udC1zaXplOiAxcmVtOw0KICAgICAgbGluZS1oZWlnaHQ6IDEuNjsNCiAgICAgIH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJWR0FNIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiVkdBTSIpDQogIGxpYnJhcnkoVkdBTSkNCn0NCiMjIyMgVkdBTQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQo8cD4NCiogRW5oYW5jZSB1bmRlcnN0YW5kaW5nIHRoZSBwcm9jZWR1cmUgb2YgbGlrZWxpaG9vZC1iYXNlZCBjaGktc3F1YXJlIGh5cG90aGVzaXMgdGVzdGluZyAuDQoNCiogSW1wbGVtZW50IHRoZSBwcm9jZWR1cmVzIGZvciBkZXRlY3Rpbmcgb3ZlcmZpdHRpbmcvdW5kZXJmaXR0aW5nIGlzc3VlcyBpbiBwcmFjdGljYWwgYXBwbGljYXRpb25zLg0KPC9wPg0KDQoNCiMjICoqUG9saWNpZXMgb2YgVXNpbmcgQUkgVG9vbHMqKg0KDQo8cD4NCioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFBsZWFzZSBhZGhlcmUgdG8gdGhlIEFJIHRvb2wgcG9saWN5IHNwZWNpZmllZCBpbiB0aGUgY291cnNlIHN5bGxhYnVzLiBUaGUgZGlyZWN0IGNvcHlpbmcgb2YgQUktZ2VuZXJhdGVkIGNvbnRlbnQgaXMgc3RyaWN0bHkgcHJvaGliaXRlZC4gQWxsIHN1Ym1pdHRlZCB3b3JrIG11c3QgcmVmbGVjdCB5b3VyIG93biB1bmRlcnN0YW5kaW5nOyB3aGVyZSBleHRlcm5hbCB0b29scyBhcmUgY29uc3VsdGVkLCBjb250ZW50IG11c3QgYmUgdGhvcm91Z2hseSByZXBocmFzZWQgYW5kIHN5bnRoZXNpemVkIGluIHlvdXIgb3duIHdvcmRzLg0KPC9wPg0KDQo8cD4NCioqQ29kZSBJbmNsdXNpb24gUmVxdWlyZW1lbnQqKjogQW55IGNvZGUgaW5jbHVkZWQgaW4geW91ciBlc3NheSBtdXN0IGJlIHByb3Blcmx5IGNvbW1lbnRlZCB0byBleHBsYWluIHRoZSBwdXJwb3NlIGFuZC9vciBleHBlY3RlZCBvdXRwdXQgb2Yga2V5IGNvZGUgbGluZXMuIFN1Ym1pdHRpbmcgQUktZ2VuZXJhdGVkIGNvZGUgd2l0aG91dCBtZWFuaW5nZnVsLCBzdHVkZW50LWFkZGVkIGNvbW1lbnRzIHdpbGwgbm90IGJlIGFjY2VwdGVkLg0KPC9wPg0KDQoNCiMjIFRlc3RpbmcgT3ZlcmZpdHRpbmcvVW5kZXJmaXR0aW5nDQoNCkluIE1hY2hpbmUgTGVhcm5pbmcgYW5kIFN0YXRpc3RpY3MsIG92ZXJmaXR0aW5nIG9jY3VycyB3aGVuIGEgbW9kZWwgaXMgdG9vIGNvbXBsZXggYW5kIGxlYXJucyBub2lzZSwgbGVhZGluZyB0byBwb29yIHBlcmZvcm1hbmNlIG9uIG5ldyBkYXRhLCB3aGlsZSB1bmRlcmZpdHRpbmcgaGFwcGVucyB3aGVuIGEgbW9kZWwgaXMgdG9vIHNpbXBsZSB0byBjYXB0dXJlIGltcG9ydGFudCBwYXR0ZXJucywgcmVzdWx0aW5nIGluIGhpZ2ggZXJyb3JzIG92ZXJhbGw7IGJvdGggaXNzdWVzIGFyZSBleHBsYWluZWQgYnkgdGhlIEJpYXPigJNWYXJpYW5jZSBUcmFkZW9mZiBhbmQgY2FuIGNhdXNlIHVucmVsaWFibGUgcHJlZGljdGlvbnMgaW4gcmVhbC13b3JsZCBhcHBsaWNhdGlvbnMuDQoNCg0KVGhlIHByb2JhYmlsaXR5IGRlbnNpdHkgZnVuY3Rpb24gKFBERikgb2YgdGhlIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIGlzOg0KDQokJA0KZih0OyBcbGFtYmRhLCBcYmV0YSkgPSBcZnJhY3tcYmV0YX17XGxhbWJkYX0gXGxlZnQoIFxmcmFje3R9e1xsYW1iZGF9IFxyaWdodClee1xiZXRhLTF9IFxleHBcbGVmdFsgLVxsZWZ0KCBcZnJhY3t0fXtcbGFtYmRhfSBccmlnaHQpXlxiZXRhIFxyaWdodF0sIFxxdWFkIHQgXGdlIDANCiQkDQp3aGVyZSAkXGxhbWJkYSA+IDAkIGlzIHRoZSBzY2FsZSBwYXJhbWV0ZXIgKGNoYXJhY3RlcmlzdGljIGxpZmUpIGFuZCAkXGJldGEgPiAwJCBpcyB0aGUgc2hhcGUgcGFyYW1ldGVyLg0KDQpXaGVuICRcYmV0YSA9IDEkLCB0aGUgV2VpYnVsbCBQREYgc2ltcGxpZmllcyB0byB0aGUgZXhwb25lbnRpYWwgUERGOg0KDQokJA0KZih0OyBcbGFtYmRhKSA9IFxmcmFjezF9e1xsYW1iZGF9IFxleHBcbGVmdCggLVxmcmFje3R9e1xsYW1iZGF9IFxyaWdodCkNCiQkDQp3aXRoIGNvbnN0YW50IGhhemFyZCByYXRlICRoKHQpID0gMS9cbGFtYmRhJC4NCg0KDQo8cD48Zm9udCBjb2xvciA9ICJkYXJrcmVkIj4qKlRoaXMgYXNzaWdubWVudCBmb2N1c2VzIG9uIHBlcmZvcm1pbmcgYSBoeXBvdGhlc2lzIHRlc3QgZm9yIHRoZSBzaGFwZSBwYXJhbWV0ZXIgKCRcYmV0YSQpIG9mIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbiB3aXRoaW4gYSByZWxpYWJpbGl0eSBtb2RlKio8L2ZvbnQ+PC9wPg0KDQoNClxiZWdpbnthbGlnbn0NCkhfMCY6IFxiZXRhID0gMSBccXVhZCBcdGV4dHsoRXhwb25lbnRpYWwgbW9kZWwsIHNpbXBsZXIpfSBcXA0KSF8xJjogXGJldGEgXG5lcSAxIFxxdWFkIFx0ZXh0eyhXZWlidWxsIG1vZGVsLCBtb3JlIGNvbXBsZXgpfQ0KXGVuZHthbGlnbn0NCg0KDQpcDQoNCiMjICoqUXVlc3Rpb246IFJlbGlhYmlsaXR5IEFwcGxpY2F0aW9uKioNCg0KPHA+DQpBIG1pZC1zaXplZCBtYW51ZmFjdHVyaW5nIGNvbXBhbnkgcHJvZHVjaW5nIGluZHVzdHJpYWwgY29udmV5b3Igc3lzdGVtcyBiZWdhbiBleHBlcmllbmNpbmcgdW5leHBlY3RlZCBkb3dudGltZSBpbiBvbmUgb2YgaXRzIGRpc3RyaWJ1dGlvbiBmYWNpbGl0aWVzLCBwcm9tcHRpbmcgY29uY2VybiBhYm91dCB0aGUgcmVsaWFiaWxpdHkgb2YgYSBuZXdseSBzb3VyY2VkIGJhdGNoIG9mIGJhbGwgYmVhcmluZ3MgdXNlZCBpbiB0aGUgbW90b3IgYXNzZW1ibGllcy4gVGhlc2UgYmVhcmluZ3MsIHN1cHBsaWVkIGJ5IGEgdmVuZG9yIGFkb3B0aW5nIGNvc3Qtc2F2aW5nIHByb2R1Y3Rpb24gbWV0aG9kcywgd2VyZSBpbnN0YWxsZWQgYWNyb3NzIG11bHRpcGxlIHVuaXRzIG9wZXJhdGluZyB1bmRlciBjb250aW51b3VzIGxvYWQgY29uZGl0aW9ucy4gQWZ0ZXIgc2V2ZXJhbCBtb250aHMsIG1haW50ZW5hbmNlIGxvZ3MgcmV2ZWFsZWQgYSBwYXR0ZXJuIG9mIGluY3JlYXNpbmcgZmFpbHVyZXMsIHdpdGggY29tcG9uZW50cyBsYXN0aW5nIGFueXdoZXJlIGZyb20gYSBmZXcgZG96ZW4gdG8gb3ZlciAxNTAgaG91cnMgYmVmb3JlIGJyZWFrZG93bi4gVG8gaW52ZXN0aWdhdGUsIHRoZSBlbmdpbmVlcmluZyB0ZWFtIGNvbGxlY3RlZCB0aW1lLXRvLWZhaWx1cmUgZGF0YSBmcm9tIDUwIGlkZW50aWNhbCBiZWFyaW5ncyBhbmQgY29uZHVjdGVkIGEgV2VpYnVsbCBhbmFseXNpcyB3aXRoaW4gdGhlIGZyYW1ld29yayBvZiBSZWxpYWJpbGl0eSBFbmdpbmVlcmluZy4gVGhlIDUwIHRpbWUtdG8tZmFpbHVyZSAoc3Vydml2YWwgdGltZSkgYXJlOg0KDQpgYGANCjEyLjQsIDE4LjcsIDI1LjMsIDMwLjEsIDMzLjUsIDM1LjIsIDM4LjksIDQwLjMsIDQyLjcsIDQ1LjEsIDQ3LjYsIDQ5LjgsIDUyLjQsIDU1LjAsIA0KNTcuMywgNjAuMiwgNjIuOCwgNjUuMSwgNjcuOSwgNzAuNSwgNzIuMywgNzUuNiwgNzguMiwgODAuOSwgODMuNCwgODUuNywgODguMSwgOTAuNiwgDQo5My4yLCA5NS44LCA5OC40LCAxMDEuMCwgMTA0LjUsIDEwNy4zLCAxMTAuNiwgMTEzLjIsIDExNi44LCAxMjAuMSwgMTIzLjcsIDEyNy40LA0KMTMwLjksIDEzNC41LCAxMzguMiwgMTQyLjAsIDE0Ni4zLCAxNTAuNywgMTU1LjIsIDE2MC44LCAxNjguNCwgMTc1LjkNCmBgYA0KPC9wPg0KDQpUaGlzIGFzc2lnbm1lbnQgZm9jdXNlcyBvbiBoeXBvdGhlc2lzICRIXzA6IFxiZXRhID0gMSQgKGV4cG9uZW50aWFsKSBhZ2FpbnN0ICRIXzE6IFxiZXRhIFxuZXEgMSQgKFdlaWJ1bGwpLiBUaGlzIGZyYW1ld29yayBkZXRlY3RzIG92ZXJmaXR0aW5nIChmaXR0aW5nIGEgV2VpYnVsbCB3aGVuIGV4cG9uZW50aWFsIGlzIHRydWUpIGFuZCB1bmRlcmZpdHRpbmcgKGZpdHRpbmcgZXhwb25lbnRpYWwgd2hlbiBXZWlidWxsIHdpdGggJFxiZXRhIFxuZXEgMSQgaXMgdHJ1ZSkuIA0KDQoNCjxwPg0KYSkuIEZpbmQgdGhlIE1MRSBvZiB0aGUgV2VpYnVsbCBwYXJhbWV0ZXJzICRcbGFtYmRhJCAoc2NhbGUpIGFuZCAkXGJldGEkIChzaGFwZSksIGRlbm90ZWQgYnkgJFxoYXR7XGxhbWJkYX0kIGFuZCAkXGhhdHtcYmV0YX0kLCByZXNwZWN0aXZlbHksIHVzaW5nIHRoZSBgb3B0aW0oKWAgcHJvY2VkdXJlLiBbKkhpbnQ6IFlvdSBzaG91bGQgcHJvdmlkZSBleHBsaWNpdCBleHByZXNzaW9ucyBmb3IgdGhlIGxvZy1saWtlbGlob29kIGFuZCBncmFkaWVudCBmdW5jdGlvbnMgb2YgdGhlIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIHBhcmFtZXRlcnMuKl0NCg0KYGBge3J9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgSFc6IFdlaWJ1bGwgdnMgRXhwb25lbnRpYWwgTW9kZWwgKFBhcnRzIGHigJNlKQ0KIyBEYXRhOiBCZWFyaW5nIHRpbWUtdG8tZmFpbHVyZSAoaG91cnMpDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyBJbnB1dCB0aGUgZGF0YSBkaXJlY3RseQ0KdCA8LSBjKA0KICAxMi40LCAxOC43LCAyNS4zLCAzMC4xLCAzMy41LCAzNS4yLCAzOC45LCA0MC4zLCA0Mi43LCA0NS4xLA0KICA0Ny42LCA0OS44LCA1Mi40LCA1NS4wLCA1Ny4zLCA2MC4yLCA2Mi44LCA2NS4xLCA2Ny45LCA3MC41LA0KICA3Mi4zLCA3NS42LCA3OC4yLCA4MC45LCA4My40LCA4NS43LCA4OC4xLCA5MC42LCA5My4yLCA5NS44LA0KICA5OC40LCAxMDEuMCwgMTA0LjUsIDEwNy4zLCAxMTAuNiwgMTEzLjIsIDExNi44LCAxMjAuMSwgMTIzLjcsIDEyNy40LA0KICAxMzAuOSwgMTM0LjUsIDEzOC4yLCAxNDIuMCwgMTQ2LjMsIDE1MC43LCAxNTUuMiwgMTYwLjgsIDE2OC40LCAxNzUuOQ0KKQ0KDQpuIDwtIGxlbmd0aCh0KQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgKGEpIFdlaWJ1bGwgTUxFIHVzaW5nIG51bWVyaWNhbCBvcHRpbWl6YXRpb24NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojIE5lZ2F0aXZlIGxvZy1saWtlbGlob29kIGZvciBXZWlidWxsDQp3ZWlidWxsX25sbCA8LSBmdW5jdGlvbihwYXIsIHQpIHsNCiAgbGFtYmRhIDwtIHBhclsxXQ0KICBiZXRhICAgPC0gcGFyWzJdDQogIA0KICAjIEVuZm9yY2UgcGFyYW1ldGVyIGNvbnN0cmFpbnRzDQogIGlmIChsYW1iZGEgPD0gMCB8fCBiZXRhIDw9IDApIHJldHVybihJbmYpDQogIA0KICAjIExvZy1saWtlbGlob29kDQogIGxsIDwtIHN1bShsb2coYmV0YS9sYW1iZGEpICsNCiAgICAgICAgICAgIChiZXRhIC0gMSkqbG9nKHQvbGFtYmRhKSAtDQogICAgICAgICAgICAodC9sYW1iZGEpXmJldGEpDQogIA0KICByZXR1cm4oLWxsKSAgIyBtaW5pbWl6ZSBuZWdhdGl2ZSBsb2ctbGlrZWxpaG9vZA0KfQ0KDQojIEluaXRpYWwgcGFyYW1ldGVyIGd1ZXNzZXMNCmluaXQgPC0gYyhsYW1iZGEgPSBtZWFuKHQpLCBiZXRhID0gMSkNCg0KIyBSdW4gb3B0aW1pemF0aW9uDQpmaXRfd2VpYnVsbCA8LSBvcHRpbShpbml0LCB3ZWlidWxsX25sbCwgdCA9IHQsIGhlc3NpYW4gPSBUUlVFKQ0KDQojIEV4dHJhY3QgTUxFcw0KbGFtYmRhX2hhdCA8LSBmaXRfd2VpYnVsbCRwYXJbMV0NCmJldGFfaGF0ICAgPC0gZml0X3dlaWJ1bGwkcGFyWzJdDQoNCmNhdCgiV2VpYnVsbCBNTEVzOlxuIikNCmNhdCgibGFtYmRhX2hhdCA9IiwgbGFtYmRhX2hhdCwgIlxuIikNCmNhdCgiYmV0YV9oYXQgICA9IiwgYmV0YV9oYXQsICJcblxuIikNCmBgYA0KDQpiKS4gRmluZCB0aGUgTUxFIG9mIHRoZSBleHBvbmVudGlhbCBwYXJhbWV0ZXIgJFxsYW1iZGEkIChzY2FsZSksIGRlbm90ZWQgYnkgJFxoYXR7XGxhbWJkYX0kLCB1c2luZyBhbnkgcHJvY2VkdXJlLiBbKkhpbnQ6IFlvdSBzaG91bGQgcHJvdmlkZSBleHBsaWNpdCBleHByZXNzaW9ucyBmb3IgdGhlIGxvZy1saWtlbGlob29kIGFuZCBncmFkaWVudCBmdW5jdGlvbnMgb2YgdGhlIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzLipdDQoNCmBgYHtyfQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIChiKSBFeHBvbmVudGlhbCBNTEUNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojIE1MRSBmb3IgZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uDQpsYW1iZGFfZXhwX2hhdCA8LSBtZWFuKHQpDQoNCmNhdCgiRXhwb25lbnRpYWwgTUxFOlxuIikNCmNhdCgibGFtYmRhX2hhdCA9IiwgbGFtYmRhX2V4cF9oYXQsICJcblxuIikNCmBgYA0KDQpjKS4gUGVyZm9ybSB0aGUgbGlrZWxpaG9vZCByYXRpbyAkXGNoaV4yJCB0ZXN0IG9uICRcYmV0YSA9IDEkLiBXaGF0IGlzIHRoZSBwLXZhbHVlPyBbKkhpbnQ6IFVzZSB0aGUgcmVzdWx0cyBpbiBhKSBhbmQgYikqLl0gDQoNCmBgYHtyfQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIChjKSBMaWtlbGlob29kIFJhdGlvIFRlc3QNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojIExvZy1saWtlbGlob29kIHVuZGVyIFdlaWJ1bGwNCmxsX3dlaWJ1bGwgPC0gLWZpdF93ZWlidWxsJHZhbHVlDQoNCiMgTG9nLWxpa2VsaWhvb2QgdW5kZXIgZXhwb25lbnRpYWwNCmxsX2V4cCA8LSBzdW0oLWxvZyhsYW1iZGFfZXhwX2hhdCkgLSB0L2xhbWJkYV9leHBfaGF0KQ0KDQojIExSVCBzdGF0aXN0aWMNCkxSVF9zdGF0IDwtIDIgKiAobGxfd2VpYnVsbCAtIGxsX2V4cCkNCg0KIyBwLXZhbHVlDQpwdmFsX0xSVCA8LSAxIC0gcGNoaXNxKExSVF9zdGF0LCBkZiA9IDEpDQoNCmNhdCgiTGlrZWxpaG9vZCBSYXRpbyBUZXN0OlxuIikNCmNhdCgiTFJUIHN0YXRpc3RpYyA9IiwgTFJUX3N0YXQsICJcbiIpDQpjYXQoInAtdmFsdWUgICAgICAgPSIsIHB2YWxfTFJULCAiXG5cbiIpDQpgYGANCg0KZCkuIFBlcmZvcm0gdGhlIFdhbGQgJFxjaGleMiQgb24gdGhlIHNhbWUgaHlwb3RoZXNpcyAkXGJldGEgPSAxJC4gV2hhdCBpcyB0aGUgcC12YWx1ZT8gWypIaW50OiBZb3UgbmVlZCB0byBmaW5kIHRoZSBvYnNlcnZlZCBGaXNoZXIgaW5mb3JtYXRpb24gbWF0cml4IChpLmUuLCB0aGUgbmVnYXRpdmUgSGVzc2lhbiBtYXRyaXggZnJvbSBgb3B0aW0oKWApIGJhc2VkIG9uIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbi4gVGhlIGludmVyc2Ugb2YgdGhlIDxmb250IGNvbG9yID0gImJsdWUiPm5lZ2F0aXZlPC9mb250PiBvYnNlcnZlZCBIZXNzaWFuIG1hdHJpeCBpcyB0aGUgY292YXJpYW5jZSBtYXRyaXgqLl0gDQoNCmBgYHtyfQ0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIChkKSBXYWxkIFRlc3QNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojIFZhcmlhbmNlLWNvdmFyaWFuY2UgbWF0cml4IGZyb20gSGVzc2lhbg0KdmNvdl9tYXQgPC0gc29sdmUoZml0X3dlaWJ1bGwkaGVzc2lhbikNCg0KIyBWYXJpYW5jZSBvZiBiZXRhDQp2YXJfYmV0YSA8LSB2Y292X21hdFsyLDJdDQoNCiMgV2FsZCBzdGF0aXN0aWMNCldfc3RhdCA8LSAoYmV0YV9oYXQgLSAxKV4yIC8gdmFyX2JldGENCg0KIyBwLXZhbHVlDQpwdmFsX1dhbGQgPC0gMSAtIHBjaGlzcShXX3N0YXQsIGRmID0gMSkNCg0KY2F0KCJXYWxkIFRlc3Q6XG4iKQ0KY2F0KCJXIHN0YXRpc3RpYyA9IiwgV19zdGF0LCAiXG4iKQ0KY2F0KCJwLXZhbHVlICAgICA9IiwgcHZhbF9XYWxkLCAiXG5cbiIpDQpgYGANCg0KZSkuIFdyaXRlIGEgc3VtbWFyeSBvZiB0aGUgYWJvdmUgYW5hbHlzZXMgdG8gYWRkcmVzcyB0aGUgZm9sbG93aW5nOg0KDQoqIFdoZXRoZXIgdGhlIHR3byB0ZXN0cyBnZW5lcmF0ZWQgdGhlIHNhbWUgcmVzdWx0cy4NCg0KKiBXaGljaCBtb2RlbCBpcyByZWNvbW1lbmRlZCBmb3IgdGhlIGRhdGEuDQoNCiogRHJhdyB0aGUgZGVuc2l0eSBjdXJ2ZSBiYXNlZCBvbiB0aGUgTUxFKHMpIG9mIHRoZSBwYXJhbWV0ZXIocykgYW5kIGRlc2NyaWJlIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHRpbWUtdG8tZmFpbHVyZS4NCjwvcD4NCg0KYGBge3J9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgKGUpIEludGVycHJldGF0aW9uDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KY2F0KCJTdW1tYXJ5OlxuIikNCg0KaWYgKHB2YWxfTFJUIDwgMC4wNSAmIHB2YWxfV2FsZCA8IDAuMDUpIHsNCiAgY2F0KCJCb3RoIHRlc3RzIHJlamVjdCBIMDogYmV0YSA9IDEuXG4iKQ0KICBjYXQoIlRoZSBXZWlidWxsIG1vZGVsIHByb3ZpZGVzIGEgc2lnbmlmaWNhbnRseSBiZXR0ZXIgZml0LlxuIikNCn0gZWxzZSB7DQogIGNhdCgiRmFpbCB0byByZWplY3QgSDA6IGV4cG9uZW50aWFsIG1vZGVsIG1heSBiZSBhZGVxdWF0ZS5cbiIpDQp9DQoNCmlmIChiZXRhX2hhdCA+IDEpIHsNCiAgY2F0KCJiZXRhX2hhdCA+IiwgMSwgIjogaW5jcmVhc2luZyBmYWlsdXJlIHJhdGUgKHdlYXItb3V0IGJlaGF2aW9yKS5cbiIpDQp9IGVsc2UgaWYgKGJldGFfaGF0IDwgMSkgew0KICBjYXQoImJldGFfaGF0IDwiLCAxLCAiOiBkZWNyZWFzaW5nIGZhaWx1cmUgcmF0ZSAoZWFybHkgZmFpbHVyZXMpLlxuIikNCn0gZWxzZSB7DQogIGNhdCgiYmV0YV9oYXQgPSIsIDEsICI6IGNvbnN0YW50IGZhaWx1cmUgcmF0ZS5cbiIpDQp9DQoNCmBgYA0KYGBge3J9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMgRGVuc2l0eSBQbG90IHVzaW5nIFdlaWJ1bGwgTUxFcw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCiMgQ3JlYXRlIGEgc2VxdWVuY2Ugb2YgeCB2YWx1ZXMNCnhfdmFscyA8LSBzZXEobWluKHQpLCBtYXgodCksIGxlbmd0aC5vdXQgPSAyMDApDQoNCiMgV2VpYnVsbCBkZW5zaXR5IHVzaW5nIE1MRXMNCndlaWJ1bGxfZGVuc2l0eSA8LSAoYmV0YV9oYXQgLyBsYW1iZGFfaGF0KSAqDQogICAgICAgICAgICAgICAgICAgKHhfdmFscyAvIGxhbWJkYV9oYXQpXihiZXRhX2hhdCAtIDEpICoNCiAgICAgICAgICAgICAgICAgICBleHAoLSh4X3ZhbHMgLyBsYW1iZGFfaGF0KV5iZXRhX2hhdCkNCg0KIyBQbG90IGhpc3RvZ3JhbSBvZiBkYXRhIChzY2FsZWQgdG8gZGVuc2l0eSkNCmhpc3QodCwgcHJvYmFiaWxpdHkgPSBUUlVFLA0KICAgICBtYWluID0gIldlaWJ1bGwgRml0IHRvIFRpbWUtdG8tRmFpbHVyZSBEYXRhIiwNCiAgICAgeGxhYiA9ICJUaW1lIHRvIEZhaWx1cmUgKGhvdXJzKSIsDQogICAgIGJvcmRlciA9ICJibGFjayIpDQoNCiMgT3ZlcmxheSBXZWlidWxsIGRlbnNpdHkgY3VydmUNCmxpbmVzKHhfdmFscywgd2VpYnVsbF9kZW5zaXR5LCBsd2QgPSAyKQ0KDQojIE9wdGlvbmFsOiBhZGQgZXhwb25lbnRpYWwgY3VydmUgZm9yIGNvbXBhcmlzb24NCmV4cF9kZW5zaXR5IDwtICgxIC8gbGFtYmRhX2V4cF9oYXQpICogZXhwKC14X3ZhbHMgLyBsYW1iZGFfZXhwX2hhdCkNCmxpbmVzKHhfdmFscywgZXhwX2RlbnNpdHksIGx3ZCA9IDIsIGx0eSA9IDIpDQoNCmxlZ2VuZCgidG9wcmlnaHQiLA0KICAgICAgIGxlZ2VuZCA9IGMoIldlaWJ1bGwgRml0IiwgIkV4cG9uZW50aWFsIEZpdCIpLA0KICAgICAgIGx3ZCA9IDIsDQogICAgICAgbHR5ID0gYygxLCAyKSkNCmBgYA==