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.]
windfarm= sort(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(windfarm)
#here we define the weibull log likelihood function
#
weibull_loglik = function(params, data) #weilbull distribution parameters: beta (shape), alpha (scale)
{
sum(dweibull(data, shape = params[1], #beta shape parameter
scale = params[2], #lambda scale parameter
log = TRUE #write the log likelihood of the weibull distribution
))
}
#Finding the MLEs using optim()
#use mean of data as reference
mle_weibull = optim(par = c(1, mean(windfarm)),
fn = weibull_loglik, # minimizes function
data= windfarm,
control = list(fnscale= -1) #-1 for maximization
)
hat_beta = mle_weibull$par[1]
hat_lambda = mle_weibull$par[2]
logL1_obs = mle_weibull$value
cat("Weibull MLEs Shape (Beta):", hat_beta, "Scale (Lambda):", hat_lambda)
Weibull MLEs Shape (Beta): 3.370336 Scale (Lambda): 31.41928
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.]
exp_loglik = function(lambda, data) #exponetial distrubution parameters: lambda
{
sum(dexp(data, rate= 1/lambda , #solve for rate with lambda parameter
log = TRUE #write the log likelihood of the exponential distribution
))
}
#Finding the MLEs using optim()
#use mean of data as reference
mle_exp = optim(par = c(mean(windfarm)), #intial guess starting point for lambda
fn = exp_loglik, # minimizes function
data= windfarm,
control = list(fnscale= -1) #-1 for maximization
)
hat_lambda_exp = mle_exp$par
loglike_exp_null = mle_exp$value
cat("Exponetial MLEs Scale (Lambda):", hat_lambda_exp,
"Max Log-Likelihood (Null):", loglike_exp_null)
Exponetial MLEs Scale (Lambda): 28.18533 Max Log-Likelihood (Null): -325.4101
c). Use a) and b) to perform the regular likelihood ratio \(\chi^2\) test for \(\beta = 1\) and report the p-value.
#Calculating the p value
#Find the difference of the from lower peak or higher peak
LR_obs = -2 *(loglike_exp_null - logL1_obs) #likelihood_ratio_test
#Calc p value w/ chisquare distrubution w/ 1 degree of freedom
p_val_chi2= 1-pchisq(LR_obs,1) #p_val =1-pchisq(likelihood_ratio_test,1)
cat("Likelihood Ratio Statistic (Observed):", LR_obs,
"\nChi-Square P-value:", p_val_chi2)
Likelihood Ratio Statistic (Observed): 100.6143
Chi-Square P-value: 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.] Algorithm
windfarm= sort(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))
B = 9999
n = length(windfarm)
#finding weilbuil MLEs
#using MLEs found in earlier sections
LR_obs = -2 * (loglike_exp_null - logL1_obs) #find log likehood ratio for observed values and force into a chi square distrubution
weibull_loglik = function(params, data) {
sum(dweibull(data, shape = params[1], scale = params[2], log = TRUE))
}
################Bootstrap Building###333
boot_lrt= function(data, hat_lambda_exp, B=B){
n = length(data)
LR_star = numeric(B) #bootstrap the log likelihood ratio
# Bootstrap distribution
LR_star <- numeric(B)
for (b in 1:B) {
#bootstrap sample under HO
z_star = rexp(n, rate =1/hat_lambda_exp)
# Fit null model (exponential distribution)
loglike_null_boot = sum(dexp(z_star, rate = 1 / mean(z_star), log = TRUE))
#Fit alternative model (weibull distribution)
fit_star = optim(par = c(1, mean(z_star)), fn = weibull_loglik, data = z_star, control = list(fnscale = -1))
logL1_star = fit_star$value
#Calculate the 'Fake' bootstrapped comparison Likelihood Ratio
LR_star[b] = -2 * (loglike_null_boot - logL1_star)
}
return(LR_star)
}
boot_results = boot_lrt(windfarm, hat_lambda_exp, B = B)
# Calculating the p-value:
#p_val_boot = (sum(boot_results >= LR_obs) + 1) / (length(boot_results) + 1)
p_val_boot = (sum(boot_results >= LR_obs)+1)/ (B+1) #number of bootstraps
cat("Bootstrap P-Value:", p_val_boot)
Bootstrap P-Value: 1e-04
e). Write a summary of the above analyses to address the
following:
Both hypothesis testing results preformed with MLE testing and
bootstrapped hypothesis tested were statistically significant,
suggesting that the complex model, the weibull distribution, is more
significant. In both approaches, the Weibull distribution does a better
job at explaining the data than the simpler, exponential model . In
generality, both the bootstrapped hypothesis test 10^{-4} and the
non-bootstrapped hypothesis test 0 convey the same information.
Considering the moderate sample size of 75 and further testing would
be required to know if there are strong violations against
distributional assumptions a bootstrap could be a strong recommendation
over the traditional hypothesis testing.Bootstrap hypothesis testing
provides robust analysis for small sample sizes and when distributional
assumptions are violated. Additionally, we do not need to assume a chi
square distribution for a bootstrap unlike the chi-square based
likelihood ratio statistic, allowing us to likely better suit the data
for analysis than a parametric test. Use a weibull distribution to
monitor the reliability of gearboxes.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMTI6IEJvb3RzdHJhcCBMaWtlbGlob29kIFJhdGlvIFRlc3QgKEJMUlQpIg0KYXV0aG9yOiAiRXphbmEgUml2ZXJzICINCmRhdGU6ICIgNC0yMTogIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIGhpZ2hsaWdodDogbW9ub2Nocm9tZQ0KICAgIHRoZW1lOiBzcGFjZWxhYg0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHtiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmZmZmOw0KICAgICAgY29sb3I6ICMwMDAwMDA7DQogICAgICBmb250LWZhbWlseTogQXJpYWwsIHNhbnMtc2VyaWY7DQogICAgICBmb250LXNpemU6IDFyZW07DQogICAgICBsaW5lLWhlaWdodDogMS42Ow0KICAgICAgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfQ0KDQppZiAoIXJlcXVpcmUoIlZHQU0iKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJWR0FNIikNCiAgbGlicmFyeShWR0FNKQ0KfQ0KIyMjIyBWR0FNDQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgICMgaW5jbHVkZSBjb2RlIGNodW5rIGluIHRoZSBvdXRwdXQgZmlsZQ0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICAjIHNvbWV0aW1lcywgeW91IGNvZGUgbWF5IHByb2R1Y2Ugd2FybmluZyBtZXNzYWdlcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB5b3UgY2FuIGNob29zZSB0byBpbmNsdWRlIHRoZSB3YXJuaW5nIG1lc3NhZ2VzIGluDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdGhlIG91dHB1dCBmaWxlLiANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAgIyB5b3UgY2FuIGFsc28gZGVjaWRlIHdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgb3V0cHV0DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaW4gdGhlIG91dHB1dCBmaWxlLg0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkENCiAgICAgICAgICAgICAgICAgICAgICApICANCmBgYA0KIA0KIFwNCiANCiMjICoqQXNzaWdubWVudCBPYmplY3RpdmVzKiogDQoNCjxwPg0KKiBFbmhhbmNlIHVuZGVyc3RhbmRpbmcgdGhlIHByb2NlZHVyZSBvZiBCb290c3RyYXAgaHlwb3RoZXNpcyB0ZXN0aW5nLg0KDQoqIEltcGxlbWVudCB0aGUgcHJvY2VkdXJlcyBmb3IgZGV0ZWN0aW5nIG92ZXJmaXR0aW5nL3VuZGVyZml0dGluZyBpc3N1ZXMgaW4gcHJhY3RpY2FsIGFwcGxpY2F0aW9ucyB1c2luZyBib290c3RyYXAgbGlrZWxpaG9vZCByYXRpbyB0ZXN0Lg0KPC9wPg0KDQoNCiMjICoqUG9saWNpZXMgb2YgVXNpbmcgQUkgVG9vbHMqKg0KDQo8cD4NCioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFBsZWFzZSBhZGhlcmUgdG8gdGhlIEFJIHRvb2wgcG9saWN5IHNwZWNpZmllZCBpbiB0aGUgY291cnNlIHN5bGxhYnVzLiBUaGUgZGlyZWN0IGNvcHlpbmcgb2YgQUktZ2VuZXJhdGVkIGNvbnRlbnQgaXMgc3RyaWN0bHkgcHJvaGliaXRlZC4gQWxsIHN1Ym1pdHRlZCB3b3JrIG11c3QgcmVmbGVjdCB5b3VyIG93biB1bmRlcnN0YW5kaW5nOyB3aGVyZSBleHRlcm5hbCB0b29scyBhcmUgY29uc3VsdGVkLCBjb250ZW50IG11c3QgYmUgdGhvcm91Z2hseSByZXBocmFzZWQgYW5kIHN5bnRoZXNpemVkIGluIHlvdXIgb3duIHdvcmRzLg0KPC9wPg0KDQo8cD4NCioqQ29kZSBJbmNsdXNpb24gUmVxdWlyZW1lbnQqKjogQW55IGNvZGUgaW5jbHVkZWQgaW4geW91ciBlc3NheSBtdXN0IGJlIHByb3Blcmx5IGNvbW1lbnRlZCB0byBleHBsYWluIHRoZSBwdXJwb3NlIGFuZC9vciBleHBlY3RlZCBvdXRwdXQgb2Yga2V5IGNvZGUgbGluZXMuIFN1Ym1pdHRpbmcgQUktZ2VuZXJhdGVkIGNvZGUgd2l0aG91dCBtZWFuaW5nZnVsLCBzdHVkZW50LWFkZGVkIGNvbW1lbnRzIHdpbGwgbm90IGJlIGFjY2VwdGVkLg0KPC9wPg0KDQoNCg0KDQojIyBUZXN0aW5nIE92ZXJmaXR0aW5nL1VuZGVyZml0dGluZw0KDQpJbiBNYWNoaW5lIExlYXJuaW5nIGFuZCBTdGF0aXN0aWNzLCBvdmVyZml0dGluZyBvY2N1cnMgd2hlbiBhIG1vZGVsIGlzIHRvbyBjb21wbGV4IGFuZCBsZWFybnMgbm9pc2UsIGxlYWRpbmcgdG8gcG9vciBwZXJmb3JtYW5jZSBvbiBuZXcgZGF0YSwgd2hpbGUgdW5kZXJmaXR0aW5nIGhhcHBlbnMgd2hlbiBhIG1vZGVsIGlzIHRvbyBzaW1wbGUgdG8gY2FwdHVyZSBpbXBvcnRhbnQgcGF0dGVybnMsIHJlc3VsdGluZyBpbiBoaWdoIGVycm9ycyBvdmVyYWxsOyBib3RoIGlzc3VlcyBhcmUgZXhwbGFpbmVkIGJ5IHRoZSBCaWFz4oCTVmFyaWFuY2UgVHJhZGVvZmYgYW5kIGNhbiBjYXVzZSB1bnJlbGlhYmxlIHByZWRpY3Rpb25zIGluIHJlYWwtd29ybGQgYXBwbGljYXRpb25zLg0KDQoNClRoZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGZ1bmN0aW9uIChQREYpIG9mIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbiBpczoNCg0KJCQNCmYodDsgXGxhbWJkYSwgXGJldGEpID0gXGZyYWN7XGJldGF9e1xsYW1iZGF9IFxsZWZ0KCBcZnJhY3t0fXtcbGFtYmRhfSBccmlnaHQpXntcYmV0YS0xfSBcZXhwXGxlZnRbIC1cbGVmdCggXGZyYWN7dH17XGxhbWJkYX0gXHJpZ2h0KV5cYmV0YSBccmlnaHRdLCBccXVhZCB0IFxnZSAwDQokJA0Kd2hlcmUgJFxsYW1iZGEgPiAwJCBpcyB0aGUgc2NhbGUgcGFyYW1ldGVyIChjaGFyYWN0ZXJpc3RpYyBsaWZlKSBhbmQgJFxiZXRhID4gMCQgaXMgdGhlIHNoYXBlIHBhcmFtZXRlci4NCg0KV2hlbiAkXGJldGEgPSAxJCwgdGhlIFdlaWJ1bGwgUERGIHNpbXBsaWZpZXMgdG8gdGhlIGV4cG9uZW50aWFsIFBERjoNCg0KJCQNCmYodDsgXGxhbWJkYSkgPSBcZnJhY3sxfXtcbGFtYmRhfSBcZXhwXGxlZnQoIC1cZnJhY3t0fXtcbGFtYmRhfSBccmlnaHQpDQokJA0Kd2l0aCBjb25zdGFudCBoYXphcmQgcmF0ZSAkaCh0KSA9IDEvXGxhbWJkYSQuDQoNCg0KPHA+PGZvbnQgY29sb3IgPSAiZGFya3JlZCI+KipUaGlzIGFzc2lnbm1lbnQgZm9jdXNlcyBvbiBwZXJmb3JtaW5nIGEgaHlwb3RoZXNpcyB0ZXN0IGZvciB0aGUgc2hhcGUgcGFyYW1ldGVyICgkXGJldGEkKSBvZiB0aGUgV2VpYnVsbCBkaXN0cmlidXRpb24gd2l0aGluIGEgcmVsaWFiaWxpdHkgbW9kZSoqPC9mb250PjwvcD4NCg0KDQpcYmVnaW57YWxpZ259DQpIXzAmOiBcYmV0YSA9IDEgXHF1YWQgXHRleHR7KEV4cG9uZW50aWFsIG1vZGVsLCBzaW1wbGVyKX0gXFwNCkhfMSY6IFxiZXRhIFxuZXEgMSBccXVhZCBcdGV4dHsoV2VpYnVsbCBtb2RlbCwgbW9yZSBjb21wbGV4KX0NClxlbmR7YWxpZ259DQoNCg0KDQojIyBTdGVwcyBvZiB0aGUgQkxSVA0KDQoNCiogRml0IG1vZGVscyB1bmRlciAkSF8wJCBhbmQgJEhfMSR9IHRvIHRoZSBvcmlnaW5hbCBkYXRhLCBjb21wdXRlICRcTGFtYmRhX3tcdGV4dHtvYnN9fSQuDQoNCiogR2VuZXJhdGUgYm9vdHN0cmFwIHNhbXBsZXMgdW5kZXIgJEhfMCR9OiANCiAgKyBFc3RpbWF0ZSBwYXJhbWV0ZXJzIHVuZGVyICRIXzAkIGZyb20gdGhlIG9yaWdpbmFsIGRhdGEuDQogICsgR2VuZXJhdGUgJEIkIGRhdGFzZXRzIGJ5IHNhbXBsaW5nIGZyb20gdGhlIG1vZGVsIHVuZGVyICRIXzAkIChwYXJhbWV0cmljIGJvb3RzdHJhcCkgb3IgYnkgcmVzYW1wbGluZyByZXNpZHVhbHMvY2FzZXMgKG5vbnBhcmFtZXRyaWMgYm9vdHN0cmFwOyBwYXJhbWV0cmljIGlzIGNvbW1vbiBmb3IgQkxSVCkuDQoNCiogRm9yIGVhY2ggYm9vdHN0cmFwIHNhbXBsZSAkYiA9IDEsXGRvdHMsQiQ6DQogICsgRml0ICRIXzAkIGFuZCAkSF8xJCBtb2RlbHMuDQogICsgQ29tcHV0ZSAkXExhbWJkYV9iID0gLTJbXGVsbF97MCxifSAtIFxlbGxfezEsYn1dJC4NCg0KKiBBcHByb3hpbWF0ZSBwLXZhbHVlOg0KDQokJA0KICBwID0gXGZyYWN7MX17Qn0gXHN1bV97Yj0xfV5CIEkoXExhbWJkYV9iIFxnZSBcTGFtYmRhX3tcdGV4dHtvYnN9fSkNCiQkDQooT2Z0ZW4gYSBzbWFsbCBhZGp1c3RtZW50IGlzIG1hZGUgZm9yIHN0YWJpbGl0eTogJCgxICsgXCNce1xMYW1iZGFfYiBcZ2UgXExhbWJkYV97XHRleHR7b2JzfX1cfSkvKEIrMSkkKS4NCg0KDQoNClwNCg0KIyMgKipRdWVzdGlvbjogUmVsaWFiaWxpdHkgQXBwbGljYXRpb24qKg0KDQo8cD4NCkEgd2luZCBlbmVyZ3kgY29tcGFueSBtb25pdG9ycyB0aGUgcmVsaWFiaWxpdHkgb2YgZ2VhcmJveGVzIGluIDc1IGlkZW50aWNhbCB3aW5kIHR1cmJpbmVzIGxvY2F0ZWQgaW4gYSBjb2FzdGFsIHdpbmQgZmFybS4gVGhlIGdlYXJib3ggaXMgYSBjcml0aWNhbCBjb21wb25lbnQ7IGl0cyBmYWlsdXJlIG9mdGVuIGxlYWRzIHRvIGNvc3RseSBkb3dudGltZSBhbmQgcmVwYWlycy4gUHJldmlvdXMgc3R1ZGllcyBzdWdnZXN0IHRoYXQgdGhlIGhhemFyZCByYXRlIChmYWlsdXJlIHJpc2spIG1heSBpbmNyZWFzZSBvdmVyIHRpbWUgZHVlIHRvIG1lY2hhbmljYWwgd2VhciAoZmF0aWd1ZSwgcGl0dGluZywgYmVhcmluZyBkZWdyYWRhdGlvbikuIEVuZ2luZWVycyB3YW50IHRvIHRlc3Qgd2hldGhlciB0aGUgZmFpbHVyZSB0aW1lIGRpc3RyaWJ1dGlvbiBmb2xsb3dzIGFuIGV4cG9uZW50aWFsIG1vZGVsIChjb25zdGFudCBoYXphcmQsIHJhbmRvbSBmYWlsdXJlcykgb3IgYSBXZWlidWxsIG1vZGVsIHdpdGggc2hhcGUgcGFyYW1ldGVyICRrPjEkIChpbmNyZWFzaW5nIGhhemFyZCwgaW5kaWNhdGl2ZSBvZiBhZ2luZy9kZWdyYWRhdGlvbikuIFRoZSBmYWlsdXJlIHRpbWVzIChpbiBtb250aHMpIGFyZToNCg0KYGBgDQogICA1LjIsICA3LjgsICA5LjEsIDExLjMsIDEyLjUsIDEzLjAsIDE0LjIsIDE1LjEsIDE1LjksIDE2LjcsIDE3LjIsIDE3LjgsIDE4LjQsIDE4LjksIA0KICAxOS4zLCAxOS43LCAyMC4yLCAyMC42LCAyMS4wLCAyMS41LCAyMS45LCAyMi4zLCAyMi43LCAyMy4xLCAyMy41LCAyMy45LCAyNC4zLCAyNC43LCANCiAgMjUuMSwgMjUuNSwgMjUuOSwgMjYuMywgMjYuNywgMjcuMSwgMjcuNSwgMjcuOSwgMjguMywgMjguNywgMjkuMSwgMjkuNSwgMjkuOSwgMzAuMywgDQogIDMwLjcsIDMxLjEsIDMxLjUsIDMxLjksIDMyLjMsIDMyLjcsIDMzLjEsIDMzLjUsIDMzLjksIDM0LjMsIDM0LjcsIDM1LjEsIDM1LjUsIDM1LjksIA0KICAzNi4zLCAzNi43LCAzNy4xLCAzNy41LCAzNy45LCAzOC4zLCAzOC43LCAzOS4xLCAzOS41LCAzOS45LCA0MC4zLCA0MC43LCA0MS4xLCA0MS41LA0KICA0MS45LCA0Mi4zLCA0Mi43LCA0My4xLCA0My41DQpgYGANCjwvcD4NCg0KVGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gaHlwb3RoZXNpcyAkSF8wOiBcYmV0YSA9IDEkIChleHBvbmVudGlhbCkgYWdhaW5zdCAkSF8xOiBcYmV0YSBcbmVxIDEkIChXZWlidWxsKS4gVGhpcyBmcmFtZXdvcmsgZGV0ZWN0cyBvdmVyZml0dGluZyAoZml0dGluZyBhIFdlaWJ1bGwgd2hlbiBleHBvbmVudGlhbCBpcyB0cnVlKSBhbmQgdW5kZXJmaXR0aW5nIChmaXR0aW5nIGV4cG9uZW50aWFsIHdoZW4gV2VpYnVsbCB3aXRoICRcYmV0YSBcbmVxIDEkIGlzIHRydWUpLiANCg0KDQo8cD4NCmEpLiBGaW5kIHRoZSBNTEUgb2YgdGhlIFdlaWJ1bGwgcGFyYW1ldGVycyAkXGxhbWJkYSQgKHNjYWxlKSBhbmQgJFxiZXRhJCAoc2hhcGUpLCBkZW5vdGVkIGJ5ICRcaGF0e1xsYW1iZGF9JCBhbmQgJFxoYXR7XGJldGF9JCwgcmVzcGVjdGl2ZWx5LCB1c2luZyB0aGUgYG9wdGltKClgIHByb2NlZHVyZS4gWypIaW50OiBZb3Ugc2hvdWxkIHByb3ZpZGUgZXhwbGljaXQgZXhwcmVzc2lvbnMgZm9yIHRoZSBsb2ctbGlrZWxpaG9vZCBhbmQgZ3JhZGllbnQgZnVuY3Rpb25zIG9mIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzLipdDQoNCmBgYHtyfQ0KDQp3aW5kZmFybT0gc29ydChjKDUuMiwgIDcuOCwgIDkuMSwgMTEuMywgMTIuNSwgMTMuMCwgMTQuMiwgMTUuMSwgMTUuOSwgMTYuNywgMTcuMiwgMTcuOCwgMTguNCwgMTguOSwgDQogIDE5LjMsIDE5LjcsIDIwLjIsIDIwLjYsIDIxLjAsIDIxLjUsIDIxLjksIDIyLjMsIDIyLjcsIDIzLjEsIDIzLjUsIDIzLjksIDI0LjMsIDI0LjcsIA0KICAyNS4xLCAyNS41LCAyNS45LCAyNi4zLCAyNi43LCAyNy4xLCAyNy41LCAyNy45LCAyOC4zLCAyOC43LCAyOS4xLCAyOS41LCAyOS45LCAzMC4zLCANCiAgMzAuNywgMzEuMSwgMzEuNSwgMzEuOSwgMzIuMywgMzIuNywgMzMuMSwgMzMuNSwgMzMuOSwgMzQuMywgMzQuNywgMzUuMSwgMzUuNSwgMzUuOSwgDQogIDM2LjMsIDM2LjcsIDM3LjEsIDM3LjUsIDM3LjksIDM4LjMsIDM4LjcsIDM5LjEsIDM5LjUsIDM5LjksIDQwLjMsIDQwLjcsIDQxLjEsIDQxLjUsDQogIDQxLjksIDQyLjMsIDQyLjcsIDQzLjEsIDQzLjUpKQ0KDQoNCm4gPSBsZW5ndGgod2luZGZhcm0pDQoNCg0KYGBgDQoNCg0KYGBge3J9DQojaGVyZSB3ZSBkZWZpbmUgdGhlIHdlaWJ1bGwgbG9nIGxpa2VsaWhvb2QgZnVuY3Rpb24NCiMNCndlaWJ1bGxfbG9nbGlrID0gZnVuY3Rpb24ocGFyYW1zLCBkYXRhKSAjd2VpbGJ1bGwgZGlzdHJpYnV0aW9uIHBhcmFtZXRlcnM6IGJldGEgKHNoYXBlKSwgYWxwaGEgKHNjYWxlKQ0Kew0KICBzdW0oZHdlaWJ1bGwoZGF0YSwgc2hhcGUgPSBwYXJhbXNbMV0sICNiZXRhIHNoYXBlIHBhcmFtZXRlcg0KICAgICAgICAgICAgICAgICAgICAgIHNjYWxlID0gcGFyYW1zWzJdLCAjbGFtYmRhIHNjYWxlIHBhcmFtZXRlcg0KICAgICAgICAgICAgICAgICAgICAgIGxvZyA9IFRSVUUgICAgICAgICAjd3JpdGUgdGhlIGxvZyBsaWtlbGlob29kIG9mIHRoZSB3ZWlidWxsIGRpc3RyaWJ1dGlvbg0KICAgICAgICAgICAgICAgICkpDQogIA0KICANCn0NCg0KDQojRmluZGluZyB0aGUgTUxFcyB1c2luZyBvcHRpbSgpDQogICN1c2UgbWVhbiBvZiBkYXRhIGFzIHJlZmVyZW5jZQ0KDQptbGVfd2VpYnVsbCA9IG9wdGltKHBhciA9IGMoMSwgbWVhbih3aW5kZmFybSkpLA0KICAgICAgICAgICAgICAgICAgICBmbiA9IHdlaWJ1bGxfbG9nbGlrLCAjIG1pbmltaXplcyBmdW5jdGlvbg0KICAgICAgICAgICAgICAgICAgICBkYXRhPSB3aW5kZmFybSwNCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoZm5zY2FsZT0gLTEpICMtMSBmb3IgbWF4aW1pemF0aW9uDQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICApDQoNCmhhdF9iZXRhID0gbWxlX3dlaWJ1bGwkcGFyWzFdDQpoYXRfbGFtYmRhID0gbWxlX3dlaWJ1bGwkcGFyWzJdDQpsb2dMMV9vYnMgPSBtbGVfd2VpYnVsbCR2YWx1ZQ0KDQoNCmNhdCgiV2VpYnVsbCBNTEVzIFNoYXBlIChCZXRhKToiLCBoYXRfYmV0YSwgIlNjYWxlIChMYW1iZGEpOiIsIGhhdF9sYW1iZGEpDQoNCmBgYA0KDQoNCg0KDQpiKS4gRmluZCB0aGUgTUxFIG9mIHRoZSBleHBvbmVudGlhbCBwYXJhbWV0ZXIgJFxsYW1iZGEkIChzY2FsZSksIGRlbm90ZWQgYnkgJFxoYXR7XGxhbWJkYX0kLCB1c2luZyBhbnkgcHJvY2VkdXJlLiBbKkhpbnQ6IFlvdSBzaG91bGQgcHJvdmlkZSBleHBsaWNpdCBleHByZXNzaW9ucyBmb3IgdGhlIGxvZy1saWtlbGlob29kIGFuZCBncmFkaWVudCBmdW5jdGlvbnMgb2YgdGhlIGV4cG9uZW50aWFsIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzLipdDQoNCmBgYHtyfQ0KDQpleHBfbG9nbGlrID0gZnVuY3Rpb24obGFtYmRhLCBkYXRhKSAjZXhwb25ldGlhbCBkaXN0cnVidXRpb24gcGFyYW1ldGVyczogbGFtYmRhDQp7DQogIHN1bShkZXhwKGRhdGEsIHJhdGU9IDEvbGFtYmRhICwgI3NvbHZlIGZvciByYXRlIHdpdGggbGFtYmRhIHBhcmFtZXRlcg0KICAgICAgICAgICAgICAgICAgICAgIGxvZyA9IFRSVUUgI3dyaXRlIHRoZSBsb2cgbGlrZWxpaG9vZCBvZiB0aGUgZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uDQogICAgICAgICAgICAgICAgKSkNCiAgDQogIA0KfQ0KDQoNCiNGaW5kaW5nIHRoZSBNTEVzIHVzaW5nIG9wdGltKCkNCiAgI3VzZSBtZWFuIG9mIGRhdGEgYXMgcmVmZXJlbmNlDQoNCm1sZV9leHAgPSBvcHRpbShwYXIgPSBjKG1lYW4od2luZGZhcm0pKSwgI2ludGlhbCBndWVzcyBzdGFydGluZyBwb2ludCBmb3IgbGFtYmRhDQogICAgICAgICAgICAgICAgICAgIGZuID0gZXhwX2xvZ2xpaywgIyBtaW5pbWl6ZXMgZnVuY3Rpb24NCiAgICAgICAgICAgICAgICAgICAgZGF0YT0gd2luZGZhcm0sDQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChmbnNjYWxlPSAtMSkgIy0xIGZvciBtYXhpbWl6YXRpb24NCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICkNCg0KDQoNCmhhdF9sYW1iZGFfZXhwID0gbWxlX2V4cCRwYXINCmxvZ2xpa2VfZXhwX251bGwgPSBtbGVfZXhwJHZhbHVlDQoNCg0KY2F0KCJFeHBvbmV0aWFsIE1MRXMgU2NhbGUgKExhbWJkYSk6IiwgaGF0X2xhbWJkYV9leHAsIA0KICAgICJNYXggTG9nLUxpa2VsaWhvb2QgKE51bGwpOiIsIGxvZ2xpa2VfZXhwX251bGwpDQpgYGANCg0KDQoNCmMpLiBVc2UgYSkgYW5kIGIpIHRvIHBlcmZvcm0gdGhlIHJlZ3VsYXIgbGlrZWxpaG9vZCByYXRpbyAkXGNoaV4yJCB0ZXN0IGZvciAkXGJldGEgPSAxJCBhbmQgcmVwb3J0IHRoZSBwLXZhbHVlLg0KDQoNCmBgYHtyfQ0KDQojQ2FsY3VsYXRpbmcgdGhlIHAgdmFsdWUNCg0KICAjRmluZCB0aGUgZGlmZmVyZW5jZSBvZiB0aGUgZnJvbSBsb3dlciBwZWFrIG9yIGhpZ2hlciBwZWFrDQoNCkxSX29icyA9IC0yICoobG9nbGlrZV9leHBfbnVsbCAtIGxvZ0wxX29icykgI2xpa2VsaWhvb2RfcmF0aW9fdGVzdA0KDQojQ2FsYyBwIHZhbHVlIHcvIGNoaXNxdWFyZSBkaXN0cnVidXRpb24gdy8gMSBkZWdyZWUgb2YgZnJlZWRvbQ0KcF92YWxfY2hpMj0gMS1wY2hpc3EoTFJfb2JzLDEpICNwX3ZhbCA9MS1wY2hpc3EobGlrZWxpaG9vZF9yYXRpb190ZXN0LDEpDQogIA0KICANCmNhdCgiTGlrZWxpaG9vZCBSYXRpbyBTdGF0aXN0aWMgKE9ic2VydmVkKToiLCBMUl9vYnMsIA0KICAgICJcbkNoaS1TcXVhcmUgUC12YWx1ZToiLCBwX3ZhbF9jaGkyKQ0KDQpgYGANCg0KDQoNCg0KZCkuIFVzZSB0aGUgQkxSVCBhbGdvcml0aG0gdG8gcGVyZm9ybSBhIGJvb3RzdHJhcCBsaWtlbGlob29kIHJhdGlvIHRlc3QgYW5kIHJlcG9ydCB0aGUgYm9vdHN0cmFwIHAtdmFsdWUuIE5vdGUgdGhhdCB5b3UgYXJlIGV4cGVjdGVkIHRvIHRyYW5zbGF0ZSB0aGUgQkxSVCBhbGdvcml0aG0gaW50byBSIGNvZGUgdG8gcGVyZm9ybSB0aGUgQkxSVC4gWypIaW50OiBUaGUgY2hpLXNxdWFyZSBkaXN0cmlidXRpb24gc2hvdWxkIG5vdCBiZSB1c2VkIGluIHRoaXMgcGFydCBvZiB0aGUgYW5hbHlzaXMuKl0NCioqQWxnb3JpdGhtKioNCg0KDQpgYGB7cn0NCg0KDQp3aW5kZmFybT0gc29ydChjKDUuMiwgIDcuOCwgIDkuMSwgMTEuMywgMTIuNSwgMTMuMCwgMTQuMiwgMTUuMSwgMTUuOSwgMTYuNywgMTcuMiwgMTcuOCwgMTguNCwgMTguOSwgDQogIDE5LjMsIDE5LjcsIDIwLjIsIDIwLjYsIDIxLjAsIDIxLjUsIDIxLjksIDIyLjMsIDIyLjcsIDIzLjEsIDIzLjUsIDIzLjksIDI0LjMsIDI0LjcsIA0KICAyNS4xLCAyNS41LCAyNS45LCAyNi4zLCAyNi43LCAyNy4xLCAyNy41LCAyNy45LCAyOC4zLCAyOC43LCAyOS4xLCAyOS41LCAyOS45LCAzMC4zLCANCiAgMzAuNywgMzEuMSwgMzEuNSwgMzEuOSwgMzIuMywgMzIuNywgMzMuMSwgMzMuNSwgMzMuOSwgMzQuMywgMzQuNywgMzUuMSwgMzUuNSwgMzUuOSwgDQogIDM2LjMsIDM2LjcsIDM3LjEsIDM3LjUsIDM3LjksIDM4LjMsIDM4LjcsIDM5LjEsIDM5LjUsIDM5LjksIDQwLjMsIDQwLjcsIDQxLjEsIDQxLjUsDQogIDQxLjksIDQyLjMsIDQyLjcsIDQzLjEsIDQzLjUpKQ0KDQpCID0gOTk5OQ0KbiA9IGxlbmd0aCh3aW5kZmFybSkNCg0KI2ZpbmRpbmcgd2VpbGJ1aWwgTUxFcw0KI3VzaW5nIE1MRXMgZm91bmQgaW4gZWFybGllciBzZWN0aW9ucyANCg0KTFJfb2JzID0gLTIgKiAobG9nbGlrZV9leHBfbnVsbCAtIGxvZ0wxX29icykgI2ZpbmQgbG9nIGxpa2Vob29kIHJhdGlvIGZvciBvYnNlcnZlZCB2YWx1ZXMgYW5kIGZvcmNlIGludG8gYSBjaGkgc3F1YXJlIGRpc3RydWJ1dGlvbg0KDQp3ZWlidWxsX2xvZ2xpayA9IGZ1bmN0aW9uKHBhcmFtcywgZGF0YSkgew0KICBzdW0oZHdlaWJ1bGwoZGF0YSwgc2hhcGUgPSBwYXJhbXNbMV0sIHNjYWxlID0gcGFyYW1zWzJdLCBsb2cgPSBUUlVFKSkNCn0NCiMjIyMjIyMjIyMjIyMjIyNCb290c3RyYXAgQnVpbGRpbmcjIyMzMzMNCmJvb3RfbHJ0PSBmdW5jdGlvbihkYXRhLCBoYXRfbGFtYmRhX2V4cCwgQj1CKXsgIA0KICANCiAgICBuID0gbGVuZ3RoKGRhdGEpDQogICAgTFJfc3RhciA9IG51bWVyaWMoQikgI2Jvb3RzdHJhcCB0aGUgbG9nIGxpa2VsaWhvb2QgcmF0aW8NCiAgICANCiAgICANCiAgICANCiAgICAjIEJvb3RzdHJhcCBkaXN0cmlidXRpb24NCiAgICBMUl9zdGFyIDwtIG51bWVyaWMoQikNCiAgICBmb3IgKGIgaW4gMTpCKSB7DQogICAgDQogICAgI2Jvb3RzdHJhcCBzYW1wbGUgdW5kZXIgSE8NCiAgICAgIHpfc3RhciA9IHJleHAobiwgcmF0ZSA9MS9oYXRfbGFtYmRhX2V4cCkNCiAgICANCiAgIyBGaXQgbnVsbCBtb2RlbCAoZXhwb25lbnRpYWwgZGlzdHJpYnV0aW9uKQ0KDQpsb2dsaWtlX251bGxfYm9vdCA9IHN1bShkZXhwKHpfc3RhciwgcmF0ZSA9IDEgLyBtZWFuKHpfc3RhciksIGxvZyA9IFRSVUUpKQ0KICAgICAgDQojRml0IGFsdGVybmF0aXZlICBtb2RlbCAod2VpYnVsbCBkaXN0cmlidXRpb24pDQoNCmZpdF9zdGFyID0gb3B0aW0ocGFyID0gYygxLCBtZWFuKHpfc3RhcikpLCBmbiA9IHdlaWJ1bGxfbG9nbGlrLCAgZGF0YSA9IHpfc3RhciwgY29udHJvbCA9IGxpc3QoZm5zY2FsZSA9IC0xKSkNCg0KbG9nTDFfc3RhciA9IGZpdF9zdGFyJHZhbHVlDQoNCiNDYWxjdWxhdGUgdGhlICdGYWtlJyBib290c3RyYXBwZWQgY29tcGFyaXNvbiBMaWtlbGlob29kIFJhdGlvDQogICAgTFJfc3RhcltiXSA9IC0yICogKGxvZ2xpa2VfbnVsbF9ib290IC0gbG9nTDFfc3RhcikNCiAgICB9DQogIA0KcmV0dXJuKExSX3N0YXIpDQoNCn0NCg0KYm9vdF9yZXN1bHRzID0gYm9vdF9scnQod2luZGZhcm0sIGhhdF9sYW1iZGFfZXhwLCBCID0gQikNCg0KIyBDYWxjdWxhdGluZyB0aGUgcC12YWx1ZToNCiNwX3ZhbF9ib290ID0gKHN1bShib290X3Jlc3VsdHMgPj0gTFJfb2JzKSArIDEpIC8gKGxlbmd0aChib290X3Jlc3VsdHMpICsgMSkNCg0KcF92YWxfYm9vdCA9IChzdW0oYm9vdF9yZXN1bHRzID49IExSX29icykrMSkvIChCKzEpICNudW1iZXIgb2YgYm9vdHN0cmFwcw0KDQoNCg0KDQoNCmNhdCgiQm9vdHN0cmFwIFAtVmFsdWU6IiwgcF92YWxfYm9vdCkNCg0KYGBgDQoNCg0KZSkuIFdyaXRlIGEgc3VtbWFyeSBvZiB0aGUgYWJvdmUgYW5hbHlzZXMgdG8gYWRkcmVzcyB0aGUgZm9sbG93aW5nOg0KDQoqIFdoZXRoZXIgdGhlIHR3byB0ZXN0cyBnZW5lcmF0ZWQgdGhlIHNhbWUgcmVzdWx0cy4NCg0KKiBXaGljaCBtb2RlbCBpcyByZWNvbW1lbmRlZCBmb3IgdGhlIGRhdGEuDQoNCjwvcD4NCiANCiANCkJvdGggaHlwb3RoZXNpcyB0ZXN0aW5nIHJlc3VsdHMgcHJlZm9ybWVkIHdpdGggTUxFIHRlc3RpbmcgYW5kIGJvb3RzdHJhcHBlZCBoeXBvdGhlc2lzIHRlc3RlZCB3ZXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHN1Z2dlc3RpbmcgdGhhdCB0aGUgY29tcGxleCBtb2RlbCwgdGhlIHdlaWJ1bGwgZGlzdHJpYnV0aW9uLCBpcyBtb3JlIHNpZ25pZmljYW50LiBJbiBib3RoIGFwcHJvYWNoZXMsIHRoZSBXZWlidWxsIGRpc3RyaWJ1dGlvbiBkb2VzIGEgYmV0dGVyIGpvYiBhdCBleHBsYWluaW5nIHRoZSBkYXRhIHRoYW4gdGhlIHNpbXBsZXIsIGV4cG9uZW50aWFsIG1vZGVsIC4gSW4gZ2VuZXJhbGl0eSwgYm90aCB0aGUgYm9vdHN0cmFwcGVkIGh5cG90aGVzaXMgdGVzdCBgciBwX3ZhbF9ib290YCBhbmQgdGhlIG5vbi1ib290c3RyYXBwZWQgaHlwb3RoZXNpcyB0ZXN0IGByIHBfdmFsX2NoaTJgIGNvbnZleSB0aGUgc2FtZSBpbmZvcm1hdGlvbi4gDQoNCg0KQ29uc2lkZXJpbmcgdGhlIG1vZGVyYXRlIHNhbXBsZSBzaXplIG9mIDc1IGFuZCBmdXJ0aGVyIHRlc3Rpbmcgd291bGQgYmUgcmVxdWlyZWQgdG8ga25vdyBpZiB0aGVyZSBhcmUgc3Ryb25nIHZpb2xhdGlvbnMgYWdhaW5zdCBkaXN0cmlidXRpb25hbCBhc3N1bXB0aW9ucyBhIGJvb3RzdHJhcCBjb3VsZCBiZSBhIHN0cm9uZyByZWNvbW1lbmRhdGlvbiBvdmVyIHRoZSB0cmFkaXRpb25hbCBoeXBvdGhlc2lzIHRlc3RpbmcuQm9vdHN0cmFwIGh5cG90aGVzaXMgdGVzdGluZyBwcm92aWRlcyByb2J1c3QgYW5hbHlzaXMgZm9yIHNtYWxsIHNhbXBsZSBzaXplcyBhbmQgd2hlbiBkaXN0cmlidXRpb25hbCBhc3N1bXB0aW9ucyBhcmUgdmlvbGF0ZWQuIA0KIEFkZGl0aW9uYWxseSwgd2UgZG8gbm90IG5lZWQgdG8gYXNzdW1lIGEgY2hpIHNxdWFyZSBkaXN0cmlidXRpb24gZm9yIGEgYm9vdHN0cmFwIHVubGlrZSB0aGUgY2hpLXNxdWFyZSBiYXNlZCBsaWtlbGlob29kIHJhdGlvIHN0YXRpc3RpYywgYWxsb3dpbmcgdXMgdG8gbGlrZWx5IGJldHRlciBzdWl0IHRoZSBkYXRhIGZvciBhbmFseXNpcyB0aGFuIGEgcGFyYW1ldHJpYyB0ZXN0LiBVc2UgYSB3ZWlidWxsIGRpc3RyaWJ1dGlvbiB0byAgbW9uaXRvciB0aGUgcmVsaWFiaWxpdHkgb2YgZ2VhcmJveGVzLg0KDQoNCg==