Question: Reliability Application
A wind energy company monitors the reliability of gearboxes in 75
identical wind turbines located in a coastal wind farm. The gearbox is a
critical component; its failure often leads to costly downtime and
repairs. Previous studies suggest that the hazard rate (failure risk)
may increase over time due to mechanical wear (fatigue, pitting, bearing
degradation). Engineers want to test whether the failure time
distribution follows an exponential model (constant hazard, random
failures) or a Weibull model with shape parameter \(k>1\) (increasing hazard, indicative of
aging/degradation). The failure times (in months) are:
5.2, 7.8, 9.1, 11.3, 12.5, 13.0, 14.2, 15.1, 15.9, 16.7, 17.2, 17.8, 18.4, 18.9,
19.3, 19.7, 20.2, 20.6, 21.0, 21.5, 21.9, 22.3, 22.7, 23.1, 23.5, 23.9, 24.3, 24.7,
25.1, 25.5, 25.9, 26.3, 26.7, 27.1, 27.5, 27.9, 28.3, 28.7, 29.1, 29.5, 29.9, 30.3,
30.7, 31.1, 31.5, 31.9, 32.3, 32.7, 33.1, 33.5, 33.9, 34.3, 34.7, 35.1, 35.5, 35.9,
36.3, 36.7, 37.1, 37.5, 37.9, 38.3, 38.7, 39.1, 39.5, 39.9, 40.3, 40.7, 41.1, 41.5,
41.9, 42.3, 42.7, 43.1, 43.5
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.]
We test
\(H_0: \beta = 1\) (Exponential
model)
versus
\(H_1: \beta \ne 1\) (Weibull
model).
Under \(H_0\), the hazard is
constant. Under \(H_1\), the hazard may
increase or decrease with time.
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 and \(\beta>0\) is
the shape parameter. so that \[
\ell(\lambda, \beta) = \sum_{i=1}^{n} \log f(x_i; \lambda, \beta) = n
\log \beta - n \beta \log \lambda + (\beta - 1) \sum_{i=1}^{n} \log x_i
- \sum_{i=1}^{n} \left( \frac{x_i}{\lambda} \right)^\beta
\]
The gradient functions (partial derivatives) are \[
\frac{\partial \ell}{\partial \lambda} = \frac{\beta}{\lambda} \left[
\sum_{i=1}^n \left( \frac{x_i}{\lambda} \right)^\beta - n \right]
\] \[
\frac{\partial \ell}{\partial \beta} = \frac{n}{\beta} - n \log \lambda
+ \sum_{i=1}^{n} \log x_i - \sum_{i=1}^{n} \left( \frac{x_i}{\lambda}
\right)^\beta \log \left( \frac{x_i}{\lambda} \right)
\]
x <- c(
5.2, 7.8, 9.1, 11.3, 12.5, 13.0, 14.2, 15.1, 15.9, 16.7, 17.2, 17.8, 18.4, 18.9,
19.3, 19.7, 20.2, 20.6, 21.0, 21.5, 21.9, 22.3, 22.7, 23.1, 23.5, 23.9, 24.3, 24.7,
25.1, 25.5, 25.9, 26.3, 26.7, 27.1, 27.5, 27.9, 28.3, 28.7, 29.1, 29.5, 29.9, 30.3,
30.7, 31.1, 31.5, 31.9, 32.3, 32.7, 33.1, 33.5, 33.9, 34.3, 34.7, 35.1, 35.5, 35.9,
36.3, 36.7, 37.1, 37.5, 37.9, 38.3, 38.7, 39.1, 39.5, 39.9, 40.3, 40.7, 41.1, 41.5,
41.9, 42.3, 42.7, 43.1, 43.5
)
n <- length(x)
# Log-likelihood function
weibull_loglik <- function(par, data) {
lambda <- par[1]
beta <- par[2]
# Parameter constraint
if (lambda <= 0 || beta <= 0) return(-Inf)
ll <- length(data) * log(beta) -
length(data) * beta * log(lambda) +
(beta - 1) * sum(log(data)) -
sum((data / lambda)^beta)
return(ll)
}
# Negative log-likelihood (for minimization)
weibull_nll <- function(par, data) {
return(-weibull_loglik(par, data))
}
# Gradient function
weibull_grad <- function(par, data) {
lambda <- par[1]
beta <- par[2]
n <- length(data)
z <- (data / lambda)^beta
# derivative wrt lambda
d_lambda <- - (beta / lambda) * (sum(z) - n)
# derivative wrt beta
d_beta <- - (n / beta -
n * log(lambda) +
sum(log(data)) -
sum(z * log(data / lambda)))
return(c(d_lambda, d_beta))
}
# Run optimization
fit_weibull <- optim(
par = c(mean(x), 1.5), # initial values
fn = weibull_nll,
gr = weibull_grad,
data = x,
method = "L-BFGS-B",
lower = c(1e-8, 1e-8)
)
fit_weibull$par
[1] 31.418211 3.370789
Summary: Using optim(), the maximum likelihood
estimates are \(\hat{\beta} \approx
3.37\). Thus the fitted Weibull model is \(\hat{\lambda} \approx 31.42\).
Since \(\hat{\beta} > 1\), the
fitted model suggests an increasing hazard rate, which is consistent
with mechanical wear and aging.
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.]
Step 1: Model
When \(\beta =1\) \(f(t;\lambda) = \frac{1}{\lambda}
e^{-t/\lambda}\)
Step 2: Log likelihood
\(\ell(\lambda) = -n \log \lambda -
\frac{1}{\lambda} \sum_{i=1}^{n} x_i\)
Step 3: Derivative
\(\frac{d\ell}{d\lambda} =
-\frac{n}{\lambda} + \frac{\sum x_i}{\lambda^2}\) Set to
zero:\(\hat{\lambda} = \bar{x}\)
# Exponential MLE
lambda0_hat <- mean(x)
lambda0_hat
[1] 28.18533
Summary:
The estimate is\(\hat{\lambda}_0 = \bar{x}
\approx 28.1853\).
c). Use a) and b) to perform the regular likelihood ratio \(\chi^2\) test for \(\beta = 1\) and report the p-value.
Step 1: Statistic
\(LR = -2[\ell_0 - \ell_1]\)
Step 2:
# Exponential log-likelihood
exp_loglik <- function(lambda, data) {
-length(data) * log(lambda) - sum(data) / lambda
}
# Compute log-likelihoods
logLik0 <- exp_loglik(lambda0_hat, x)
lambda1_hat <- fit_weibull$par[1]
beta1_hat <- fit_weibull$par[2]
logLik1 <- weibull_loglik(c(lambda1_hat, beta1_hat), x)
# Likelihood ratio
LR_obs <- -2 * (logLik0 - logLik1)
# p-value (chi-square)
p_chisq <- 1 - pchisq(LR_obs, df = 1)
LR_obs
[1] 100.6144
[1] 0
Summary: Because \(LR
\approx 100.61\) \(p < 2.2 \times
10^{-16}\) Therefore, Reject \(H_0\).
d). Use the BLRT algorithm to perform a bootstrap likelihood ratio
test and report the bootstrap p-value. Note that you are expected to
translate the BLRT algorithm into R code to perform the BLRT. [Hint:
The chi-square distribution should not be used in this part of the
analysis.]
Step 1: IdeaInstead of: \(LR \sim
\chi^2\) we approximate the distribution using bootstrap.
Step 2: Algorithm Fit model under \(H_0\). Then, generate bootstrap samples
from exponential and compute LR each time. Last, Compare with
observed.
Step 3:
set.seed(123)
# Fit exponential
fit_exp_mle <- function(data) {
lambda_hat <- mean(data)
logLik <- -length(data) * log(lambda_hat) - sum(data) / lambda_hat
return(list(lambda_hat = lambda_hat, logLik = logLik))
}
# Fit Weibull
fit_weibull_mle <- function(data) {
out <- optim(
par = c(mean(data), 1.5),
fn = weibull_nll,
gr = weibull_grad,
data = data,
method = "L-BFGS-B",
lower = c(1e-8, 1e-8)
)
return(list(
lambda_hat = out$par[1],
beta_hat = out$par[2],
logLik = -out$value
))
}
# Observed statistic
fit0 <- fit_exp_mle(x)
fit1 <- fit_weibull_mle(x)
LR_obs <- -2 * (fit0$logLik - fit1$logLik)
# Bootstrap
B <- 2000
LR_boot <- numeric(B)
for (b in 1:B) {
# Generate from H0
x_star <- rexp(n, rate = 1 / fit0$lambda_hat)
fit0_b <- fit_exp_mle(x_star)
fit1_b <- fit_weibull_mle(x_star)
LR_boot[b] <- -2 * (fit0_b$logLik - fit1_b$logLik)
}
# Bootstrap p-value
p_boot <- (1 + sum(LR_boot >= LR_obs)) / (B + 1)
p_boot
[1] 0.0004997501
Summary:
Using \(B=2000\) bootstrap samples,
the bootstrap p-value is:\(p_{boot} \approx
0.0005\)This is extremely small, so the BLRT also rejects \(H_0\).Because bootstrap results depend
slightly on the random seed and the chosen \(B\), the exact value may vary a little, but
it will still be very small.DecisionSince \(p_{boot} \approx 0.0005 < 0.05\), we
again reject \(H_0: \beta = 1\).
e). Write a summary of the above analyses to address the
following:
- Whether the two tests generated the same results.
Summary: Both the classical likelihood ratio test
and the bootstrap LRT reject \(H_0:
\beta=1\), with p-values near zero (\(p
< 2.2 \times 10^{-16}\) and \(p_{boot} \approx 0.0005\)). This provides
strong evidence that the exponential model does not fit the data. The
estimated Weibull shape parameter \(\hat{\beta} \approx 3.37 > 1\) indicates
an increasing hazard rate over time, consistent with mechanical wear.
Therefore, the Weibull model is preferred, while the exponential model
underfits the data.
- Which model is recommended for the data.
Summary: Weibull model is recommended because it
captures increasing failure risk and fits the data significantly
better.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMTI6IEJvb3RzdHJhcCBMaWtlbGlob29kIFJhdGlvIFRlc3QgKEJMUlQpIg0KYXV0aG9yOiAiIFhpYW95aW5nIE1hICINCmRhdGU6ICIgRHVlOiAwNC8yMS8yMDI2ICINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUNCiAgICB0aGVtZTogc3BhY2VsYWINCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQogIHBkZl9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICBmaWdfd2lkdGg6IDMNCiAgICBmaWdfaGVpZ2h0OiAzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7YmFja2dyb3VuZC1jb2xvcjogI2ZmZmZmZjsNCiAgICAgIGNvbG9yOiAjMDAwMDAwOw0KICAgICAgZm9udC1mYW1pbHk6IEFyaWFsLCBzYW5zLXNlcmlmOw0KICAgICAgZm9udC1zaXplOiAxcmVtOw0KICAgICAgbGluZS1oZWlnaHQ6IDEuNjsNCiAgICAgIH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJWR0FNIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiVkdBTSIpDQogIGxpYnJhcnkoVkdBTSkNCn0NCiMjIyMgVkdBTQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCg0KDQoNCiMjIFRlc3RpbmcgT3ZlcmZpdHRpbmcvVW5kZXJmaXR0aW5nDQoNCkluIE1hY2hpbmUgTGVhcm5pbmcgYW5kIFN0YXRpc3RpY3MsIG92ZXJmaXR0aW5nIG9jY3VycyB3aGVuIGEgbW9kZWwgaXMgdG9vIGNvbXBsZXggYW5kIGxlYXJucyBub2lzZSwgbGVhZGluZyB0byBwb29yIHBlcmZvcm1hbmNlIG9uIG5ldyBkYXRhLCB3aGlsZSB1bmRlcmZpdHRpbmcgaGFwcGVucyB3aGVuIGEgbW9kZWwgaXMgdG9vIHNpbXBsZSB0byBjYXB0dXJlIGltcG9ydGFudCBwYXR0ZXJucywgcmVzdWx0aW5nIGluIGhpZ2ggZXJyb3JzIG92ZXJhbGw7IGJvdGggaXNzdWVzIGFyZSBleHBsYWluZWQgYnkgdGhlIEJpYXPigJNWYXJpYW5jZSBUcmFkZW9mZiBhbmQgY2FuIGNhdXNlIHVucmVsaWFibGUgcHJlZGljdGlvbnMgaW4gcmVhbC13b3JsZCBhcHBsaWNhdGlvbnMuDQoNCg0KVGhlIHByb2JhYmlsaXR5IGRlbnNpdHkgZnVuY3Rpb24gKFBERikgb2YgdGhlIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIGlzOg0KDQokJA0KZih0OyBcbGFtYmRhLCBcYmV0YSkgPSBcZnJhY3tcYmV0YX17XGxhbWJkYX0gXGxlZnQoIFxmcmFje3R9e1xsYW1iZGF9IFxyaWdodClee1xiZXRhLTF9IFxleHBcbGVmdFsgLVxsZWZ0KCBcZnJhY3t0fXtcbGFtYmRhfSBccmlnaHQpXlxiZXRhIFxyaWdodF0sIFxxdWFkIHQgXGdlIDANCiQkDQp3aGVyZSAkXGxhbWJkYSA+IDAkIGlzIHRoZSBzY2FsZSBwYXJhbWV0ZXIgKGNoYXJhY3RlcmlzdGljIGxpZmUpIGFuZCAkXGJldGEgPiAwJCBpcyB0aGUgc2hhcGUgcGFyYW1ldGVyLg0KDQpXaGVuICRcYmV0YSA9IDEkLCB0aGUgV2VpYnVsbCBQREYgc2ltcGxpZmllcyB0byB0aGUgZXhwb25lbnRpYWwgUERGOg0KDQokJA0KZih0OyBcbGFtYmRhKSA9IFxmcmFjezF9e1xsYW1iZGF9IFxleHBcbGVmdCggLVxmcmFje3R9e1xsYW1iZGF9IFxyaWdodCkNCiQkDQp3aXRoIGNvbnN0YW50IGhhemFyZCByYXRlICRoKHQpID0gMS9cbGFtYmRhJC4NCg0KDQo8cD48Zm9udCBjb2xvciA9ICJkYXJrcmVkIj4qKlRoaXMgYXNzaWdubWVudCBmb2N1c2VzIG9uIHBlcmZvcm1pbmcgYSBoeXBvdGhlc2lzIHRlc3QgZm9yIHRoZSBzaGFwZSBwYXJhbWV0ZXIgKCRcYmV0YSQpIG9mIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbiB3aXRoaW4gYSByZWxpYWJpbGl0eSBtb2RlKio8L2ZvbnQ+PC9wPg0KDQoNClxiZWdpbnthbGlnbn0NCkhfMCY6IFxiZXRhID0gMSBccXVhZCBcdGV4dHsoRXhwb25lbnRpYWwgbW9kZWwsIHNpbXBsZXIpfSBcXA0KSF8xJjogXGJldGEgXG5lcSAxIFxxdWFkIFx0ZXh0eyhXZWlidWxsIG1vZGVsLCBtb3JlIGNvbXBsZXgpfQ0KXGVuZHthbGlnbn0NCg0KDQoNCiMjIFN0ZXBzIG9mIHRoZSBCTFJUDQoNCg0KKiBGaXQgbW9kZWxzIHVuZGVyICRIXzAkIGFuZCAkSF8xJH0gdG8gdGhlIG9yaWdpbmFsIGRhdGEsIGNvbXB1dGUgJFxMYW1iZGFfe1x0ZXh0e29ic319JC4NCg0KKiBHZW5lcmF0ZSBib290c3RyYXAgc2FtcGxlcyB1bmRlciAkSF8wJH06IA0KICArIEVzdGltYXRlIHBhcmFtZXRlcnMgdW5kZXIgJEhfMCQgZnJvbSB0aGUgb3JpZ2luYWwgZGF0YS4NCiAgKyBHZW5lcmF0ZSAkQiQgZGF0YXNldHMgYnkgc2FtcGxpbmcgZnJvbSB0aGUgbW9kZWwgdW5kZXIgJEhfMCQgKHBhcmFtZXRyaWMgYm9vdHN0cmFwKSBvciBieSByZXNhbXBsaW5nIHJlc2lkdWFscy9jYXNlcyAobm9ucGFyYW1ldHJpYyBib290c3RyYXA7IHBhcmFtZXRyaWMgaXMgY29tbW9uIGZvciBCTFJUKS4NCg0KKiBGb3IgZWFjaCBib290c3RyYXAgc2FtcGxlICRiID0gMSxcZG90cyxCJDoNCiAgKyBGaXQgJEhfMCQgYW5kICRIXzEkIG1vZGVscy4NCiAgKyBDb21wdXRlICRcTGFtYmRhX2IgPSAtMltcZWxsX3swLGJ9IC0gXGVsbF97MSxifV0kLg0KDQoqIEFwcHJveGltYXRlIHAtdmFsdWU6DQoNCiQkDQogIHAgPSBcZnJhY3sxfXtCfSBcc3VtX3tiPTF9XkIgSShcTGFtYmRhX2IgXGdlIFxMYW1iZGFfe1x0ZXh0e29ic319KQ0KJCQNCihPZnRlbiBhIHNtYWxsIGFkanVzdG1lbnQgaXMgbWFkZSBmb3Igc3RhYmlsaXR5OiAkKDEgKyBcI1x7XExhbWJkYV9iIFxnZSBcTGFtYmRhX3tcdGV4dHtvYnN9fVx9KS8oQisxKSQpLg0KDQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uOiBSZWxpYWJpbGl0eSBBcHBsaWNhdGlvbioqDQoNCjxwPg0KQSB3aW5kIGVuZXJneSBjb21wYW55IG1vbml0b3JzIHRoZSByZWxpYWJpbGl0eSBvZiBnZWFyYm94ZXMgaW4gNzUgaWRlbnRpY2FsIHdpbmQgdHVyYmluZXMgbG9jYXRlZCBpbiBhIGNvYXN0YWwgd2luZCBmYXJtLiBUaGUgZ2VhcmJveCBpcyBhIGNyaXRpY2FsIGNvbXBvbmVudDsgaXRzIGZhaWx1cmUgb2Z0ZW4gbGVhZHMgdG8gY29zdGx5IGRvd250aW1lIGFuZCByZXBhaXJzLiBQcmV2aW91cyBzdHVkaWVzIHN1Z2dlc3QgdGhhdCB0aGUgaGF6YXJkIHJhdGUgKGZhaWx1cmUgcmlzaykgbWF5IGluY3JlYXNlIG92ZXIgdGltZSBkdWUgdG8gbWVjaGFuaWNhbCB3ZWFyIChmYXRpZ3VlLCBwaXR0aW5nLCBiZWFyaW5nIGRlZ3JhZGF0aW9uKS4gRW5naW5lZXJzIHdhbnQgdG8gdGVzdCB3aGV0aGVyIHRoZSBmYWlsdXJlIHRpbWUgZGlzdHJpYnV0aW9uIGZvbGxvd3MgYW4gZXhwb25lbnRpYWwgbW9kZWwgKGNvbnN0YW50IGhhemFyZCwgcmFuZG9tIGZhaWx1cmVzKSBvciBhIFdlaWJ1bGwgbW9kZWwgd2l0aCBzaGFwZSBwYXJhbWV0ZXIgJGs+MSQgKGluY3JlYXNpbmcgaGF6YXJkLCBpbmRpY2F0aXZlIG9mIGFnaW5nL2RlZ3JhZGF0aW9uKS4gVGhlIGZhaWx1cmUgdGltZXMgKGluIG1vbnRocykgYXJlOg0KDQpgYGANCiAgIDUuMiwgIDcuOCwgIDkuMSwgMTEuMywgMTIuNSwgMTMuMCwgMTQuMiwgMTUuMSwgMTUuOSwgMTYuNywgMTcuMiwgMTcuOCwgMTguNCwgMTguOSwgDQogIDE5LjMsIDE5LjcsIDIwLjIsIDIwLjYsIDIxLjAsIDIxLjUsIDIxLjksIDIyLjMsIDIyLjcsIDIzLjEsIDIzLjUsIDIzLjksIDI0LjMsIDI0LjcsIA0KICAyNS4xLCAyNS41LCAyNS45LCAyNi4zLCAyNi43LCAyNy4xLCAyNy41LCAyNy45LCAyOC4zLCAyOC43LCAyOS4xLCAyOS41LCAyOS45LCAzMC4zLCANCiAgMzAuNywgMzEuMSwgMzEuNSwgMzEuOSwgMzIuMywgMzIuNywgMzMuMSwgMzMuNSwgMzMuOSwgMzQuMywgMzQuNywgMzUuMSwgMzUuNSwgMzUuOSwgDQogIDM2LjMsIDM2LjcsIDM3LjEsIDM3LjUsIDM3LjksIDM4LjMsIDM4LjcsIDM5LjEsIDM5LjUsIDM5LjksIDQwLjMsIDQwLjcsIDQxLjEsIDQxLjUsDQogIDQxLjksIDQyLjMsIDQyLjcsIDQzLjEsIDQzLjUNCmBgYA0KPC9wPg0KDQpUaGlzIGFzc2lnbm1lbnQgZm9jdXNlcyBvbiBoeXBvdGhlc2lzICRIXzA6IFxiZXRhID0gMSQgKGV4cG9uZW50aWFsKSBhZ2FpbnN0ICRIXzE6IFxiZXRhIFxuZXEgMSQgKFdlaWJ1bGwpLiBUaGlzIGZyYW1ld29yayBkZXRlY3RzIG92ZXJmaXR0aW5nIChmaXR0aW5nIGEgV2VpYnVsbCB3aGVuIGV4cG9uZW50aWFsIGlzIHRydWUpIGFuZCB1bmRlcmZpdHRpbmcgKGZpdHRpbmcgZXhwb25lbnRpYWwgd2hlbiBXZWlidWxsIHdpdGggJFxiZXRhIFxuZXEgMSQgaXMgdHJ1ZSkuIA0KDQoNCjxwPg0KDQphKS4gRmluZCB0aGUgTUxFIG9mIHRoZSBXZWlidWxsIHBhcmFtZXRlcnMgJFxsYW1iZGEkIChzY2FsZSkgYW5kICRcYmV0YSQgKHNoYXBlKSwgZGVub3RlZCBieSAkXGhhdHtcbGFtYmRhfSQgYW5kICRcaGF0e1xiZXRhfSQsIHJlc3BlY3RpdmVseSwgdXNpbmcgdGhlIGBvcHRpbSgpYCBwcm9jZWR1cmUuIFsqSGludDogWW91IHNob3VsZCBwcm92aWRlIGV4cGxpY2l0IGV4cHJlc3Npb25zIGZvciB0aGUgbG9nLWxpa2VsaWhvb2QgYW5kIGdyYWRpZW50IGZ1bmN0aW9ucyBvZiB0aGUgV2VpYnVsbCBkaXN0cmlidXRpb24gcGFyYW1ldGVycy4qXSAgDQoNCldlIHRlc3QgDQoNCiRIXzA6IFxiZXRhID0gMSQgKEV4cG9uZW50aWFsIG1vZGVsKQ0KDQp2ZXJzdXMNCg0KJEhfMTogXGJldGEgXG5lIDEkIChXZWlidWxsIG1vZGVsKS4NCg0KVW5kZXIgJEhfMCQsIHRoZSBoYXphcmQgaXMgY29uc3RhbnQuIFVuZGVyICRIXzEkLCB0aGUgaGF6YXJkIG1heSBpbmNyZWFzZSBvciBkZWNyZWFzZSB3aXRoIHRpbWUuDQoNCg0KVGhlIHByb2JhYmlsaXR5IGRlbnNpdHkgZnVuY3Rpb24gKFBERikgb2YgdGhlIFdlaWJ1bGwgZGlzdHJpYnV0aW9uIGlzOg0KDQokJA0KZih0OyBcbGFtYmRhLCBcYmV0YSkgPSBcZnJhY3tcYmV0YX17XGxhbWJkYX0gXGxlZnQoIFxmcmFje3R9e1xsYW1iZGF9IFxyaWdodClee1xiZXRhLTF9IFxleHBcbGVmdFsgLVxsZWZ0KCBcZnJhY3t0fXtcbGFtYmRhfSBccmlnaHQpXlxiZXRhIFxyaWdodF0sIFxxdWFkIHQgXGdlIDANCiQkDQp3aGVyZSAkXGxhbWJkYT4wJCBpcyB0aGUgc2NhbGUgcGFyYW1ldGVyIGFuZCAkXGJldGE+MCQgaXMgdGhlIHNoYXBlIHBhcmFtZXRlci4NCnNvIHRoYXQNCiQkDQpcZWxsKFxsYW1iZGEsIFxiZXRhKSA9IFxzdW1fe2k9MX1ee259IFxsb2cgZih4X2k7IFxsYW1iZGEsIFxiZXRhKSA9IG4gXGxvZyBcYmV0YSAtIG4gXGJldGEgXGxvZyBcbGFtYmRhICsgKFxiZXRhIC0gMSkgXHN1bV97aT0xfV57bn0gXGxvZyB4X2kgLSBcc3VtX3tpPTF9XntufSBcbGVmdCggXGZyYWN7eF9pfXtcbGFtYmRhfSBccmlnaHQpXlxiZXRhDQokJA0KDQpUaGUgZ3JhZGllbnQgZnVuY3Rpb25zIChwYXJ0aWFsIGRlcml2YXRpdmVzKSBhcmUNCiQkDQpcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcbGFtYmRhfSA9IFxmcmFje1xiZXRhfXtcbGFtYmRhfSBcbGVmdFsgXHN1bV97aT0xfV5uIFxsZWZ0KCBcZnJhY3t4X2l9e1xsYW1iZGF9IFxyaWdodCleXGJldGEgLSBuIFxyaWdodF0NCiQkDQokJA0KXGZyYWN7XHBhcnRpYWwgXGVsbH17XHBhcnRpYWwgXGJldGF9ID0gXGZyYWN7bn17XGJldGF9IC0gbiBcbG9nIFxsYW1iZGEgKyBcc3VtX3tpPTF9XntufSBcbG9nIHhfaSAtIFxzdW1fe2k9MX1ee259IFxsZWZ0KCBcZnJhY3t4X2l9e1xsYW1iZGF9IFxyaWdodCleXGJldGEgXGxvZyBcbGVmdCggXGZyYWN7eF9pfXtcbGFtYmRhfSBccmlnaHQpDQokJA0KYGBge3J9DQoNCnggPC0gYygNCiAgNS4yLCA3LjgsIDkuMSwgMTEuMywgMTIuNSwgMTMuMCwgMTQuMiwgMTUuMSwgMTUuOSwgMTYuNywgMTcuMiwgMTcuOCwgMTguNCwgMTguOSwNCiAgMTkuMywgMTkuNywgMjAuMiwgMjAuNiwgMjEuMCwgMjEuNSwgMjEuOSwgMjIuMywgMjIuNywgMjMuMSwgMjMuNSwgMjMuOSwgMjQuMywgMjQuNywNCiAgMjUuMSwgMjUuNSwgMjUuOSwgMjYuMywgMjYuNywgMjcuMSwgMjcuNSwgMjcuOSwgMjguMywgMjguNywgMjkuMSwgMjkuNSwgMjkuOSwgMzAuMywNCiAgMzAuNywgMzEuMSwgMzEuNSwgMzEuOSwgMzIuMywgMzIuNywgMzMuMSwgMzMuNSwgMzMuOSwgMzQuMywgMzQuNywgMzUuMSwgMzUuNSwgMzUuOSwNCiAgMzYuMywgMzYuNywgMzcuMSwgMzcuNSwgMzcuOSwgMzguMywgMzguNywgMzkuMSwgMzkuNSwgMzkuOSwgNDAuMywgNDAuNywgNDEuMSwgNDEuNSwNCiAgNDEuOSwgNDIuMywgNDIuNywgNDMuMSwgNDMuNQ0KKQ0KbiA8LSBsZW5ndGgoeCkNCg0KIyBMb2ctbGlrZWxpaG9vZCBmdW5jdGlvbg0Kd2VpYnVsbF9sb2dsaWsgPC0gZnVuY3Rpb24ocGFyLCBkYXRhKSB7DQoNCiAgbGFtYmRhIDwtIHBhclsxXQ0KICBiZXRhICAgPC0gcGFyWzJdDQoNCiAgIyBQYXJhbWV0ZXIgY29uc3RyYWludA0KICBpZiAobGFtYmRhIDw9IDAgfHwgYmV0YSA8PSAwKSByZXR1cm4oLUluZikNCg0KICBsbCA8LSBsZW5ndGgoZGF0YSkgKiBsb2coYmV0YSkgLQ0KICAgICAgICBsZW5ndGgoZGF0YSkgKiBiZXRhICogbG9nKGxhbWJkYSkgKw0KICAgICAgICAoYmV0YSAtIDEpICogc3VtKGxvZyhkYXRhKSkgLQ0KICAgICAgICBzdW0oKGRhdGEgLyBsYW1iZGEpXmJldGEpDQoNCiAgcmV0dXJuKGxsKQ0KfQ0KDQojIE5lZ2F0aXZlIGxvZy1saWtlbGlob29kIChmb3IgbWluaW1pemF0aW9uKQ0Kd2VpYnVsbF9ubGwgPC0gZnVuY3Rpb24ocGFyLCBkYXRhKSB7DQogIHJldHVybigtd2VpYnVsbF9sb2dsaWsocGFyLCBkYXRhKSkNCn0NCg0KIyBHcmFkaWVudCBmdW5jdGlvbg0Kd2VpYnVsbF9ncmFkIDwtIGZ1bmN0aW9uKHBhciwgZGF0YSkgew0KDQogIGxhbWJkYSA8LSBwYXJbMV0NCiAgYmV0YSAgIDwtIHBhclsyXQ0KICBuIDwtIGxlbmd0aChkYXRhKQ0KDQogIHogPC0gKGRhdGEgLyBsYW1iZGEpXmJldGENCg0KICAjIGRlcml2YXRpdmUgd3J0IGxhbWJkYQ0KICBkX2xhbWJkYSA8LSAtIChiZXRhIC8gbGFtYmRhKSAqIChzdW0oeikgLSBuKQ0KDQogICMgZGVyaXZhdGl2ZSB3cnQgYmV0YQ0KICBkX2JldGEgPC0gLSAobiAvIGJldGEgLQ0KICAgICAgICAgICAgICAgbiAqIGxvZyhsYW1iZGEpICsNCiAgICAgICAgICAgICAgIHN1bShsb2coZGF0YSkpIC0NCiAgICAgICAgICAgICAgIHN1bSh6ICogbG9nKGRhdGEgLyBsYW1iZGEpKSkNCg0KICByZXR1cm4oYyhkX2xhbWJkYSwgZF9iZXRhKSkNCn0NCg0KIyBSdW4gb3B0aW1pemF0aW9uDQpmaXRfd2VpYnVsbCA8LSBvcHRpbSgNCiAgcGFyID0gYyhtZWFuKHgpLCAxLjUpLCAgICMgaW5pdGlhbCB2YWx1ZXMNCiAgZm4gID0gd2VpYnVsbF9ubGwsDQogIGdyICA9IHdlaWJ1bGxfZ3JhZCwNCiAgZGF0YSA9IHgsDQogIG1ldGhvZCA9ICJMLUJGR1MtQiIsDQogIGxvd2VyID0gYygxZS04LCAxZS04KQ0KKQ0KDQpmaXRfd2VpYnVsbCRwYXINCmBgYA0KDQoNCioqU3VtbWFyeToqKg0KVXNpbmcgb3B0aW0oKSwgdGhlIG1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0ZXMgYXJlICRcaGF0e1xiZXRhfSBcYXBwcm94IDMuMzckLiBUaHVzIHRoZSBmaXR0ZWQgV2VpYnVsbCBtb2RlbCBpcyAkXGhhdHtcbGFtYmRhfSBcYXBwcm94IDMxLjQyJC4NCg0KU2luY2UgJFxoYXR7XGJldGF9ID4gMSQsIHRoZSBmaXR0ZWQgbW9kZWwgc3VnZ2VzdHMgYW4gaW5jcmVhc2luZyBoYXphcmQgcmF0ZSwgd2hpY2ggaXMgY29uc2lzdGVudCB3aXRoIG1lY2hhbmljYWwgd2VhciBhbmQgYWdpbmcuDQoNCg0KYikuIEZpbmQgdGhlIE1MRSBvZiB0aGUgZXhwb25lbnRpYWwgcGFyYW1ldGVyICRcbGFtYmRhJCAoc2NhbGUpLCBkZW5vdGVkIGJ5ICRcaGF0e1xsYW1iZGF9JCwgdXNpbmcgYW55IHByb2NlZHVyZS4gWypIaW50OiBZb3Ugc2hvdWxkIHByb3ZpZGUgZXhwbGljaXQgZXhwcmVzc2lvbnMgZm9yIHRoZSBsb2ctbGlrZWxpaG9vZCBhbmQgZ3JhZGllbnQgZnVuY3Rpb25zIG9mIHRoZSBleHBvbmVudGlhbCBkaXN0cmlidXRpb24gcGFyYW1ldGVycy4qXQ0KDQoNClN0ZXAgMTogTW9kZWwNCg0KV2hlbiAkXGJldGEgPTEkIA0KJGYodDtcbGFtYmRhKSA9IFxmcmFjezF9e1xsYW1iZGF9IGVeey10L1xsYW1iZGF9JCAgDQoNClN0ZXAgMjogTG9nIGxpa2VsaWhvb2QgDQoNCiRcZWxsKFxsYW1iZGEpID0gLW4gXGxvZyBcbGFtYmRhIC0gXGZyYWN7MX17XGxhbWJkYX0gXHN1bV97aT0xfV57bn0geF9pJA0KDQpTdGVwIDM6IERlcml2YXRpdmUNCg0KJFxmcmFje2RcZWxsfXtkXGxhbWJkYX0gPSAtXGZyYWN7bn17XGxhbWJkYX0gKyBcZnJhY3tcc3VtIHhfaX17XGxhbWJkYV4yfSQNClNldCB0byB6ZXJvOiRcaGF0e1xsYW1iZGF9ID0gXGJhcnt4fSQNCg0KYGBge3J9DQoNCiMgRXhwb25lbnRpYWwgTUxFDQpsYW1iZGEwX2hhdCA8LSBtZWFuKHgpDQoNCmxhbWJkYTBfaGF0DQpgYGANCioqU3VtbWFyeToqKiANCg0KVGhlIGVzdGltYXRlIGlzJFxoYXR7XGxhbWJkYX1fMCA9IFxiYXJ7eH0gXGFwcHJveCAyOC4xODUzJC4NCg0KYykuIFVzZSBhKSBhbmQgYikgdG8gcGVyZm9ybSB0aGUgcmVndWxhciBsaWtlbGlob29kIHJhdGlvICRcY2hpXjIkIHRlc3QgZm9yICRcYmV0YSA9IDEkIGFuZCByZXBvcnQgdGhlIHAtdmFsdWUuDQoNCg0KU3RlcCAxOiBTdGF0aXN0aWMNCg0KJExSID0gLTJbXGVsbF8wIC0gXGVsbF8xXSQNCg0KU3RlcCAyOg0KYGBge3J9DQojIEV4cG9uZW50aWFsIGxvZy1saWtlbGlob29kDQpleHBfbG9nbGlrIDwtIGZ1bmN0aW9uKGxhbWJkYSwgZGF0YSkgew0KICAtbGVuZ3RoKGRhdGEpICogbG9nKGxhbWJkYSkgLSBzdW0oZGF0YSkgLyBsYW1iZGENCn0NCg0KIyBDb21wdXRlIGxvZy1saWtlbGlob29kcw0KbG9nTGlrMCA8LSBleHBfbG9nbGlrKGxhbWJkYTBfaGF0LCB4KQ0KDQpsYW1iZGExX2hhdCA8LSBmaXRfd2VpYnVsbCRwYXJbMV0NCmJldGExX2hhdCAgIDwtIGZpdF93ZWlidWxsJHBhclsyXQ0KDQpsb2dMaWsxIDwtIHdlaWJ1bGxfbG9nbGlrKGMobGFtYmRhMV9oYXQsIGJldGExX2hhdCksIHgpDQoNCiMgTGlrZWxpaG9vZCByYXRpbw0KTFJfb2JzIDwtIC0yICogKGxvZ0xpazAgLSBsb2dMaWsxKQ0KDQojIHAtdmFsdWUgKGNoaS1zcXVhcmUpDQpwX2NoaXNxIDwtIDEgLSBwY2hpc3EoTFJfb2JzLCBkZiA9IDEpDQoNCkxSX29icw0KcF9jaGlzcQ0KYGBgDQoNCioqU3VtbWFyeToqKg0KQmVjYXVzZSAkTFIgXGFwcHJveCAxMDAuNjEkICRwIDwgMi4yIFx0aW1lcyAxMF57LTE2fSQgVGhlcmVmb3JlLCBSZWplY3QgJEhfMCQuDQoNCg0KZCkuIFVzZSB0aGUgQkxSVCBhbGdvcml0aG0gdG8gcGVyZm9ybSBhIGJvb3RzdHJhcCBsaWtlbGlob29kIHJhdGlvIHRlc3QgYW5kIHJlcG9ydCB0aGUgYm9vdHN0cmFwIHAtdmFsdWUuIE5vdGUgdGhhdCB5b3UgYXJlIGV4cGVjdGVkIHRvIHRyYW5zbGF0ZSB0aGUgQkxSVCBhbGdvcml0aG0gaW50byBSIGNvZGUgdG8gcGVyZm9ybSB0aGUgQkxSVC4gWypIaW50OiBUaGUgY2hpLXNxdWFyZSBkaXN0cmlidXRpb24gc2hvdWxkIG5vdCBiZSB1c2VkIGluIHRoaXMgcGFydCBvZiB0aGUgYW5hbHlzaXMuKl0NCg0KU3RlcCAxOiBJZGVhSW5zdGVhZCBvZjoNCiRMUiBcc2ltIFxjaGleMiQgd2UgYXBwcm94aW1hdGUgdGhlIGRpc3RyaWJ1dGlvbiB1c2luZyBib290c3RyYXAuDQoNClN0ZXAgMjogQWxnb3JpdGhtDQpGaXQgbW9kZWwgdW5kZXIgJEhfMCQuIFRoZW4sIGdlbmVyYXRlIGJvb3RzdHJhcCBzYW1wbGVzIGZyb20gZXhwb25lbnRpYWwgYW5kIGNvbXB1dGUgTFIgZWFjaCB0aW1lLiBMYXN0LCBDb21wYXJlIHdpdGggb2JzZXJ2ZWQuDQoNClN0ZXAgMzogDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0KDQojIEZpdCBleHBvbmVudGlhbA0KZml0X2V4cF9tbGUgPC0gZnVuY3Rpb24oZGF0YSkgew0KICBsYW1iZGFfaGF0IDwtIG1lYW4oZGF0YSkNCiAgbG9nTGlrIDwtIC1sZW5ndGgoZGF0YSkgKiBsb2cobGFtYmRhX2hhdCkgLSBzdW0oZGF0YSkgLyBsYW1iZGFfaGF0DQogIHJldHVybihsaXN0KGxhbWJkYV9oYXQgPSBsYW1iZGFfaGF0LCBsb2dMaWsgPSBsb2dMaWspKQ0KfQ0KDQojIEZpdCBXZWlidWxsDQpmaXRfd2VpYnVsbF9tbGUgPC0gZnVuY3Rpb24oZGF0YSkgew0KICBvdXQgPC0gb3B0aW0oDQogICAgcGFyID0gYyhtZWFuKGRhdGEpLCAxLjUpLA0KICAgIGZuID0gd2VpYnVsbF9ubGwsDQogICAgZ3IgPSB3ZWlidWxsX2dyYWQsDQogICAgZGF0YSA9IGRhdGEsDQogICAgbWV0aG9kID0gIkwtQkZHUy1CIiwNCiAgICBsb3dlciA9IGMoMWUtOCwgMWUtOCkNCiAgKQ0KDQogIHJldHVybihsaXN0KA0KICAgIGxhbWJkYV9oYXQgPSBvdXQkcGFyWzFdLA0KICAgIGJldGFfaGF0ICAgPSBvdXQkcGFyWzJdLA0KICAgIGxvZ0xpayAgICAgPSAtb3V0JHZhbHVlDQogICkpDQp9DQoNCiMgT2JzZXJ2ZWQgc3RhdGlzdGljDQpmaXQwIDwtIGZpdF9leHBfbWxlKHgpDQpmaXQxIDwtIGZpdF93ZWlidWxsX21sZSh4KQ0KDQpMUl9vYnMgPC0gLTIgKiAoZml0MCRsb2dMaWsgLSBmaXQxJGxvZ0xpaykNCg0KIyBCb290c3RyYXANCkIgPC0gMjAwMA0KTFJfYm9vdCA8LSBudW1lcmljKEIpDQoNCmZvciAoYiBpbiAxOkIpIHsNCg0KICAjIEdlbmVyYXRlIGZyb20gSDANCiAgeF9zdGFyIDwtIHJleHAobiwgcmF0ZSA9IDEgLyBmaXQwJGxhbWJkYV9oYXQpDQoNCiAgZml0MF9iIDwtIGZpdF9leHBfbWxlKHhfc3RhcikNCiAgZml0MV9iIDwtIGZpdF93ZWlidWxsX21sZSh4X3N0YXIpDQoNCiAgTFJfYm9vdFtiXSA8LSAtMiAqIChmaXQwX2IkbG9nTGlrIC0gZml0MV9iJGxvZ0xpaykNCn0NCg0KIyBCb290c3RyYXAgcC12YWx1ZQ0KcF9ib290IDwtICgxICsgc3VtKExSX2Jvb3QgPj0gTFJfb2JzKSkgLyAoQiArIDEpDQoNCnBfYm9vdA0KYGBgDQoqKlN1bW1hcnk6KioNCg0KVXNpbmcgJEI9MjAwMCQgYm9vdHN0cmFwIHNhbXBsZXMsIHRoZSBib290c3RyYXAgcC12YWx1ZSBpczokcF97Ym9vdH0gXGFwcHJveCAwLjAwMDUkVGhpcyBpcyBleHRyZW1lbHkgc21hbGwsIHNvIHRoZSBCTFJUIGFsc28gcmVqZWN0cyAkSF8wJC5CZWNhdXNlIGJvb3RzdHJhcCByZXN1bHRzIGRlcGVuZCBzbGlnaHRseSBvbiB0aGUgcmFuZG9tIHNlZWQgYW5kIHRoZSBjaG9zZW4gJEIkLCB0aGUgZXhhY3QgdmFsdWUgbWF5IHZhcnkgYSBsaXR0bGUsIGJ1dCBpdCB3aWxsIHN0aWxsIGJlIHZlcnkgc21hbGwuRGVjaXNpb25TaW5jZSAkcF97Ym9vdH0gXGFwcHJveCAwLjAwMDUgPCAwLjA1JCwgd2UgYWdhaW4gcmVqZWN0ICRIXzA6IFxiZXRhID0gMSQuDQoNCg0KZSkuIFdyaXRlIGEgc3VtbWFyeSBvZiB0aGUgYWJvdmUgYW5hbHlzZXMgdG8gYWRkcmVzcyB0aGUgZm9sbG93aW5nOg0KDQoqIFdoZXRoZXIgdGhlIHR3byB0ZXN0cyBnZW5lcmF0ZWQgdGhlIHNhbWUgcmVzdWx0cy4NCg0KKipTdW1tYXJ5OioqDQpCb3RoIHRoZSBjbGFzc2ljYWwgbGlrZWxpaG9vZCByYXRpbyB0ZXN0IGFuZCB0aGUgYm9vdHN0cmFwIExSVCByZWplY3QgJEhfMDogXGJldGE9MSQsIHdpdGggcC12YWx1ZXMgbmVhciB6ZXJvICgkcCA8IDIuMiBcdGltZXMgMTBeey0xNn0kIGFuZCAkcF97Ym9vdH0gXGFwcHJveCAwLjAwMDUkKS4gVGhpcyBwcm92aWRlcyBzdHJvbmcgZXZpZGVuY2UgdGhhdCB0aGUgZXhwb25lbnRpYWwgbW9kZWwgZG9lcyBub3QgZml0IHRoZSBkYXRhLiBUaGUgZXN0aW1hdGVkIFdlaWJ1bGwgc2hhcGUgcGFyYW1ldGVyICRcaGF0e1xiZXRhfSBcYXBwcm94IDMuMzcgPiAxJCBpbmRpY2F0ZXMgYW4gaW5jcmVhc2luZyBoYXphcmQgcmF0ZSBvdmVyIHRpbWUsIGNvbnNpc3RlbnQgd2l0aCBtZWNoYW5pY2FsIHdlYXIuIFRoZXJlZm9yZSwgdGhlIFdlaWJ1bGwgbW9kZWwgaXMgcHJlZmVycmVkLCB3aGlsZSB0aGUgZXhwb25lbnRpYWwgbW9kZWwgdW5kZXJmaXRzIHRoZSBkYXRhLg0KDQoqIFdoaWNoIG1vZGVsIGlzIHJlY29tbWVuZGVkIGZvciB0aGUgZGF0YS4NCg0KKipTdW1tYXJ5OioqDQpXZWlidWxsIG1vZGVsIGlzIHJlY29tbWVuZGVkIGJlY2F1c2UgaXQgY2FwdHVyZXMgaW5jcmVhc2luZyBmYWlsdXJlIHJpc2sgYW5kIGZpdHMgdGhlIGRhdGEgc2lnbmlmaWNhbnRseSBiZXR0ZXIuDQoNCjwvcD4NCg0KDQoNCg==