Introduction
This R markdown document is a brief study of the Odd Lindley Half
Logistic Distribution, which was first proposed in the article “A new
one-parameter lifetime distribution and its regression model with
applications”, from the authors:
Eliwa MS, Altun E, Alhussain ZA, Ahmed EA, Salah MM, Ahmed HH, et
al. (2021) A new one-parameter lifetime distribution and its regression
model with applications. PLoS ONE 16(2): e0246969. https://doi.org/10.1371/journal.pone.0246969
The Odd Lindley Half Logistic Distribution probability density
function
\[\begin{equation}
f(x; \lambda) \boldsymbol{=} \frac{\lambda^{2}(1+e^x)}{4(1+\lambda)}
e^{ \boldsymbol{-}\frac{\lambda}{2}(e^{x}-1) + x}; x > 0
\end{equation}\]
The distribution is implemented as it follows
Random Variable generation from quantile function
set.seed(42)
lambda0 = 2
n = 10000
u = runif(n,0,1)
quantile_func <- function(u,param){
Q = log( -2/param *(1 + lambertWm1((1+param)*(u-1)*exp(-1-param))) - 1)
}
x = quantile_func(u,lambda0)
Empirical plotting
data_dist <- data.frame(u = rep(u, 3),lambda = factor(rep(1:3, each = length(u))),
xvalues = unlist(lapply(1:3, function(lambda) quantile_func(u, lambda))))
ggplot(data_dist, aes(x = xvalues, fill = lambda, color = lambda)) +
geom_histogram(aes(y = ..density..), position = "identity", alpha = 0.2, bins = 30) +
geom_density(aes(color = lambda), alpha = 0, size = 1) +
scale_fill_brewer(palette = "Set1") +
scale_color_brewer(palette = "Set1") +
xlim(0, 4) +
ylim(0, 1.2) +
labs(color = "Lambda", fill = "Lambda", title = "Empirical Density and Histograms", x = "Values", y = "Density") +
theme_light()

ggplot(data_dist, aes(x = xvalues, fill = lambda, color = lambda))+
stat_ecdf(geom = "step", lwd = 1)+
scale_fill_brewer(palette = "Set1") +
scale_color_brewer(palette = "Set1") +
xlim(0, 4) +
ylim(0, 1) +
labs(color = "Lambda", fill = "Lambda", title = "Empirical CDF", x = "Values", y = "CDF") +
theme_light()

Theoretical pdf, cdf, hrf
pdf <- function(x,shape){
fx = ((shape**2)*(1+exp(x)))/(4*(1+shape)) * exp( -(shape/2)*(exp(x) - 1) + x )
}
cdf <- function(x,shape){
Fx = 1 - ( ( shape*exp(x) + shape +2 ) / ( 2*(shape + 1) ) ) * exp( -(shape/2)*(exp(x) - 1))
}
hrf <- function(x,shape){
h = ((shape**2)*(1+exp(x))) / ( 2*( shape*(1+exp(-x)) + 2*exp(-x)) )
}
space <- seq(0, 4, length.out = 1000)
space_hrf <- seq(0, 5, length.out = 1000)
PDF
data_pdf <- data.frame(
x = rep(space, 5),
lambda = factor(rep(c(1, 2, 3, 1.5, 0.5), each = length(space))),
y = c(pdf(space, 1), pdf(space, 2), pdf(space, 3), pdf(space, 1.5), pdf(space, 0.5))
)
ggplot(data_pdf, aes(x = x, y = y, color = lambda)) +
geom_line(size = 1) +
scale_color_brewer(palette = "Set1") +
xlim(0, 4) +
ylim(0, 1.2) +
labs(color = expression(lambda), title = "pdf OLiHL", x = "Values", y = "Density") +
theme_classic()

CDF
data_cdf <- data.frame(
x = rep(space, 5),
lambda = factor(rep(c(1, 2, 3, 1.5, 0.5), each = length(space))),
y = c(cdf(space, 1), cdf(space, 2), cdf(space, 3), cdf(space, 1.5), cdf(space, 0.5))
)
ggplot(data_cdf, aes(x = x, y = y, color = lambda)) +
geom_line(size = 1) +
scale_color_brewer(palette = "Set1") +
xlim(0, 4) +
ylim(0, 1) +
labs(color = expression(lambda), title = "cdf OLiHL", x = "Values", y = "Density")+
theme_classic()

HRF
data_hrf <- data.frame(
x = rep(space_hrf, 5),
lambda = factor(rep(c(1, 2, 3, 1.5, 0.5), each = length(space))),
y = c(hrf(space_hrf, 1), hrf(space_hrf, 2), hrf(space_hrf, 3), hrf(space_hrf, 1.5), hrf(space_hrf, 0.5))
)
ggplot(data_hrf, aes(x = x, y = y, color = lambda)) +
geom_line(size = 1) +
scale_color_brewer(palette = "Set1") +
ylim(0,25) +
labs(color = expression(lambda), title = "hrf OLiHL", x = "Values", y = "Density")+
theme_classic()

ESTIMATION

MLE for λ : 2.000518
Building empirical Standard Error and Confidence Interval
If you are maximizing a likelihood, then the covariance matrix of the
estimates (observed information) is (asymptotically normal) the inverse
of the negative of the Hessian. The standard errors are the square roots
of the diagonal elements of the covariance matrix.
inv_fish <- solve(hessian)
se <- sqrt(inv_fish[1,1])
ub <- mle_lambda + (qnorm(0.025,0,1,lower.tail = FALSE)*se)
lb <- mle_lambda - (qnorm(0.025,0,1,lower.tail = FALSE)*se)
cat("CI at 95% confidence level = ", "[",lb,ub,"]")
CI at 95% confidence level = [ 1.96908 2.031957 ]
Monte Carlo Simulation for sample size n = 25
Set a sample size \(n_{mc}\);
Set a number of simulations (sampling)
Initialize parameters \(\lambda_{i}\)
Generate random variables from distribution
Perform calculations for mle, bias, mse, approximate confidence
intervals, and proportion of estimates contained in CI
set.seed(42)
n_mc = 25
n_sims = 1000
parameters <- c(0.1, 0.5, 1, 1.5, 3, 5)
results_mc <- list()
bias_mc <- list()
mse_mc <- list()
mle_mc <- list()
ci_mc <- list()
hessian_mc <- list()
proportion_ci_mc <- list()
nloglike_mc <- function(l, x) {
n <- length(x)
-1*(2*n*log(l)-n*log(4+4*l)+sum(log(1+exp(x)))-(l/2)*sum(exp(x)-1)+sum(x))
}
for (param in parameters) {
u_mc <- matrix(runif(n_sims * n_mc, 0, 1), nrow = n_sims, ncol = n_mc)
sims_mc <- apply(u_mc, c(1, 2), quantile_func, param = param)
results_mc[[as.character(param)]] <- sims_mc
mle_estimates_mc <- numeric(nrow(sims_mc))
hessian_estimates_mc <- list()
ci_param <- matrix(NA, nrow = nrow(sims_mc), ncol = 2)
for ( i in 1:nrow(sims_mc) ) {
x <- sims_mc[i, ]
result_mle_mc <- optim(1, nloglike_mc, x=x, method="L-BFGS-B", lower=0.01, upper=100, hessian=TRUE)
mle_estimates_mc[i] <- result_mle_mc$par
hessian_estimates_mc[[i]] <- result_mle_mc$hessian
se <- (diag(solve(result_mle_mc$hessian)))
ci_param[i, ] <- mle_estimates_mc[i] + qnorm(c(0.025, 0.975)) * sqrt(se)
}
mle_mc[[as.character(param)]] <- mle_estimates_mc
hessian_mc[[as.character(param)]] <- hessian_estimates_mc
ci_mc[[as.character(param)]] <- ci_param
within_ci <- apply(ci_param, 1, function(ci) param >= ci[1] && param <= ci[2])
proportion_ci_mc[[as.character(param)]] <- mean(within_ci)
bias_mc[[as.character(param)]] <- mean(mle_estimates_mc) - param
mse_mc[[as.character(param)]] <- mean((mle_estimates_mc - param)^2)
}
LS0tDQp0aXRsZTogIk9MaUhMIERpc3RyaWJ1dGlvbiINCmF1dGhvcjogQXJ0aHVyIE1hcnRpbnMNCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIG1hdGhqYXg6IGRlZmF1bHQNCi0tLQ0KDQojIyMgSW50cm9kdWN0aW9uIA0KVGhpcyBSIG1hcmtkb3duIGRvY3VtZW50IGlzIGEgYnJpZWYgc3R1ZHkgb2YgdGhlIE9kZCBMaW5kbGV5IEhhbGYgTG9naXN0aWMgRGlzdHJpYnV0aW9uLCB3aGljaCB3YXMgZmlyc3QgcHJvcG9zZWQgaW4gdGhlIGFydGljbGUgIkEgbmV3IG9uZS1wYXJhbWV0ZXIgbGlmZXRpbWUgZGlzdHJpYnV0aW9uIGFuZCBpdHMgcmVncmVzc2lvbiBtb2RlbCB3aXRoIGFwcGxpY2F0aW9ucyIsIGZyb20gdGhlIGF1dGhvcnM6DQoNCkVsaXdhIE1TLCBBbHR1biBFLCBBbGh1c3NhaW4gWkEsIEFobWVkIEVBLCBTYWxhaCBNTSwgQWhtZWQgSEgsIGV0IGFsLiAoMjAyMSkgQSBuZXcgb25lLXBhcmFtZXRlciBsaWZldGltZSBkaXN0cmlidXRpb24gYW5kIGl0cyByZWdyZXNzaW9uIG1vZGVsIHdpdGggYXBwbGljYXRpb25zLiBQTG9TIE9ORSAxNigyKTogZTAyNDY5NjkuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMzcxL2pvdXJuYWwucG9uZS4wMjQ2OTY5DQoNCg0KVGhlIE9kZCBMaW5kbGV5IEhhbGYgTG9naXN0aWMgRGlzdHJpYnV0aW9uIHByb2JhYmlsaXR5IGRlbnNpdHkgZnVuY3Rpb24NCmBgYHs9dGV4fQ0KXGJlZ2lue2VxdWF0aW9ufQ0KICAgIGYoeDsgXGxhbWJkYSkgXGJvbGRzeW1ib2x7PX0gXGZyYWN7XGxhbWJkYV57Mn0oMStlXngpfXs0KDErXGxhbWJkYSl9IGVeeyBcYm9sZHN5bWJvbHstfVxmcmFje1xsYW1iZGF9ezJ9KGVee3h9LTEpICsgeH07IHggPiAwIA0KXGVuZHtlcXVhdGlvbn0NCmBgYA0KDQpUaGUgZGlzdHJpYnV0aW9uIGlzIGltcGxlbWVudGVkIGFzIGl0IGZvbGxvd3MNCmBgYHtyLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgcmVzdWx0cyA9IEZBTFNFLCBlY2hvPUZBTFNFfQ0KI3JlbmRlcigiYW5hbHlzaXMuUm1kIikNCmxpYnJhcnkocm1hcmtkb3duKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShsYW1XKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpgYGANCg0KDQojIyMgUmFuZG9tIFZhcmlhYmxlIGdlbmVyYXRpb24gZnJvbSBxdWFudGlsZSBmdW5jdGlvbg0KYGBge3IsIHJlc3VsdHM9VFJVRX0NCnNldC5zZWVkKDQyKQ0KDQpsYW1iZGEwID0gMg0KbiA9IDEwMDAwDQp1ID0gcnVuaWYobiwwLDEpDQoNCnF1YW50aWxlX2Z1bmMgPC0gZnVuY3Rpb24odSxwYXJhbSl7DQogIFEgPSBsb2coIC0yL3BhcmFtICooMSArIGxhbWJlcnRXbTEoKDErcGFyYW0pKih1LTEpKmV4cCgtMS1wYXJhbSkpKSAtIDEpDQogIA0KfQ0KDQp4ID0gcXVhbnRpbGVfZnVuYyh1LGxhbWJkYTApDQpgYGANCg0KDQojIyMgRW1waXJpY2FsIHBsb3R0aW5nDQpgYGB7ciwgd2FybmluZyA9IEZBTFNFfQ0KZGF0YV9kaXN0IDwtIGRhdGEuZnJhbWUodSA9IHJlcCh1LCAzKSxsYW1iZGEgPSBmYWN0b3IocmVwKDE6MywgZWFjaCA9IGxlbmd0aCh1KSkpLA0KICAgICAgICAgICAgICAgICAgIHh2YWx1ZXMgPSB1bmxpc3QobGFwcGx5KDE6MywgZnVuY3Rpb24obGFtYmRhKSBxdWFudGlsZV9mdW5jKHUsIGxhbWJkYSkpKSkNCg0KDQpnZ3Bsb3QoZGF0YV9kaXN0LCBhZXMoeCA9IHh2YWx1ZXMsIGZpbGwgPSBsYW1iZGEsIGNvbG9yID0gbGFtYmRhKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgcG9zaXRpb24gPSAiaWRlbnRpdHkiLCBhbHBoYSA9IDAuMiwgYmlucyA9IDMwKSArDQogIGdlb21fZGVuc2l0eShhZXMoY29sb3IgPSBsYW1iZGEpLCBhbHBoYSA9IDAsIHNpemUgPSAxKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgeGxpbSgwLCA0KSArDQogIHlsaW0oMCwgMS4yKSArDQogIGxhYnMoY29sb3IgPSAiTGFtYmRhIiwgZmlsbCA9ICJMYW1iZGEiLCB0aXRsZSA9ICJFbXBpcmljYWwgRGVuc2l0eSBhbmQgSGlzdG9ncmFtcyIsIHggPSAiVmFsdWVzIiwgeSA9ICJEZW5zaXR5IikgKw0KICB0aGVtZV9saWdodCgpDQpgYGANCg0KDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGFfZGlzdCwgYWVzKHggPSB4dmFsdWVzLCBmaWxsID0gbGFtYmRhLCBjb2xvciA9IGxhbWJkYSkpKw0KICBzdGF0X2VjZGYoZ2VvbSA9ICJzdGVwIiwgbHdkID0gMSkrDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsNCiAgeGxpbSgwLCA0KSArDQogIHlsaW0oMCwgMSkgKw0KICBsYWJzKGNvbG9yID0gIkxhbWJkYSIsIGZpbGwgPSAiTGFtYmRhIiwgdGl0bGUgPSAiRW1waXJpY2FsIENERiIsIHggPSAiVmFsdWVzIiwgeSA9ICJDREYiKSArDQogIHRoZW1lX2xpZ2h0KCkNCmBgYA0KDQoNCiMjIyBUaGVvcmV0aWNhbCBwZGYsIGNkZiwgaHJmDQpgYGB7cn0NCg0KcGRmIDwtIGZ1bmN0aW9uKHgsc2hhcGUpew0KICBmeCA9ICgoc2hhcGUqKjIpKigxK2V4cCh4KSkpLyg0KigxK3NoYXBlKSkgKiBleHAoIC0oc2hhcGUvMikqKGV4cCh4KSAtIDEpICsgeCApDQp9DQoNCmNkZiA8LSBmdW5jdGlvbih4LHNoYXBlKXsNCiAgRnggPSAxIC0gKCAoIHNoYXBlKmV4cCh4KSArIHNoYXBlICsyICkgLyAoIDIqKHNoYXBlICsgMSkgKSApICogZXhwKCAtKHNoYXBlLzIpKihleHAoeCkgLSAxKSkgDQp9DQoNCmhyZiA8LSBmdW5jdGlvbih4LHNoYXBlKXsNCiAgaCA9ICgoc2hhcGUqKjIpKigxK2V4cCh4KSkpIC8gKCAyKiggc2hhcGUqKDErZXhwKC14KSkgKyAyKmV4cCgteCkpICkNCn0NCg0Kc3BhY2UgPC0gc2VxKDAsIDQsIGxlbmd0aC5vdXQgPSAxMDAwKQ0Kc3BhY2VfaHJmIDwtIHNlcSgwLCA1LCBsZW5ndGgub3V0ID0gMTAwMCkNCmBgYA0KDQojIyMgUERGDQpgYGB7cn0NCmRhdGFfcGRmIDwtIGRhdGEuZnJhbWUoDQogIHggPSByZXAoc3BhY2UsIDUpLA0KICBsYW1iZGEgPSBmYWN0b3IocmVwKGMoMSwgMiwgMywgMS41LCAwLjUpLCBlYWNoID0gbGVuZ3RoKHNwYWNlKSkpLA0KICB5ID0gYyhwZGYoc3BhY2UsIDEpLCBwZGYoc3BhY2UsIDIpLCBwZGYoc3BhY2UsIDMpLCBwZGYoc3BhY2UsIDEuNSksIHBkZihzcGFjZSwgMC41KSkNCikNCg0KZ2dwbG90KGRhdGFfcGRmLCBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IGxhbWJkYSkpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArDQogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArDQogIHhsaW0oMCwgNCkgKw0KICB5bGltKDAsIDEuMikgKw0KICBsYWJzKGNvbG9yID0gZXhwcmVzc2lvbihsYW1iZGEpLCB0aXRsZSA9ICJwZGYgT0xpSEwiLCB4ID0gIlZhbHVlcyIsIHkgPSAiRGVuc2l0eSIpICsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCiMjIyBDREYNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRX0NCmRhdGFfY2RmIDwtIGRhdGEuZnJhbWUoDQogIHggPSByZXAoc3BhY2UsIDUpLA0KICBsYW1iZGEgPSBmYWN0b3IocmVwKGMoMSwgMiwgMywgMS41LCAwLjUpLCBlYWNoID0gbGVuZ3RoKHNwYWNlKSkpLA0KICB5ID0gYyhjZGYoc3BhY2UsIDEpLCBjZGYoc3BhY2UsIDIpLCBjZGYoc3BhY2UsIDMpLCBjZGYoc3BhY2UsIDEuNSksIGNkZihzcGFjZSwgMC41KSkNCikNCg0KZ2dwbG90KGRhdGFfY2RmLCBhZXMoeCA9IHgsIHkgPSB5LCBjb2xvciA9IGxhbWJkYSkpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAxKSArDQogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArDQogIHhsaW0oMCwgNCkgKw0KICB5bGltKDAsIDEpICsNCiAgbGFicyhjb2xvciA9IGV4cHJlc3Npb24obGFtYmRhKSwgdGl0bGUgPSAiY2RmIE9MaUhMIiwgeCA9ICJWYWx1ZXMiLCB5ID0gIkRlbnNpdHkiKSsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCg0KIyMjIEhSRg0KYGBge3IsIHdhcm5pbmc9RkFMU0V9DQpkYXRhX2hyZiA8LSBkYXRhLmZyYW1lKA0KICB4ID0gcmVwKHNwYWNlX2hyZiwgNSksDQogIGxhbWJkYSA9IGZhY3RvcihyZXAoYygxLCAyLCAzLCAxLjUsIDAuNSksIGVhY2ggPSBsZW5ndGgoc3BhY2UpKSksDQogIHkgPSBjKGhyZihzcGFjZV9ocmYsIDEpLCBocmYoc3BhY2VfaHJmLCAyKSwgaHJmKHNwYWNlX2hyZiwgMyksIGhyZihzcGFjZV9ocmYsIDEuNSksIGhyZihzcGFjZV9ocmYsIDAuNSkpDQopDQoNCmdncGxvdChkYXRhX2hyZiwgYWVzKHggPSB4LCB5ID0geSwgY29sb3IgPSBsYW1iZGEpKSArDQogIGdlb21fbGluZShzaXplID0gMSkgKw0KICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKw0KICB5bGltKDAsMjUpICsNCiAgbGFicyhjb2xvciA9IGV4cHJlc3Npb24obGFtYmRhKSwgdGl0bGUgPSAiaHJmIE9MaUhMIiwgeCA9ICJWYWx1ZXMiLCB5ID0gIkRlbnNpdHkiKSsNCiAgdGhlbWVfY2xhc3NpYygpDQpgYGANCg0KIyMjIEVTVElNQVRJT04NCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgd2FybmluZz1GQUxTRWwsIGVjaG89RkFMU0V9DQoNCmxvZ2xpa2UgPC0gZnVuY3Rpb24obCl7DQogIDIqbipsb2cobCktbipsb2coNCs0KmwpK3N1bShsb2coMSArIGV4cCh4KSkpLShsLzIpKnN1bShleHAoeCkgLSAxKStzdW0oeCkNCn0NCg0KbF92YWx1ZXMgPC0gc2VxKDAuMDEsIDEyLCAwLjAxKQ0KDQpkYXRhX2xvZ2xpa2UgPC0gZGF0YS5mcmFtZSgNCiAgeCA9IGxfdmFsdWVzLA0KICB5ID0gc2FwcGx5KGxfdmFsdWVzLCBsb2dsaWtlKSApDQoNCmdncGxvdChkYXRhX2xvZ2xpa2UsIGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gIjIiKSkgKw0KICBnZW9tX2xpbmUobHdkID0gMSkgKw0KICBsYWJzKGNvbG9yID0gZXhwcmVzc2lvbihsYW1iZGEpLCB0aXRsZSA9ICJMb2dsaWtlbGlob29kIGZ1bmN0aW9uIiwgeCA9ICJWYWx1ZXMiLCB5ID0gImxvZ2xpa2VsaWhvb2QiKSsNCiAgdGhlbWVfY2xhc3NpYygpDQogIA0KYGBgDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCg0KbmxvZ2xpa2UgPC0gZnVuY3Rpb24obCl7DQogIC0xKigyKm4qbG9nKGwpLW4qbG9nKDQrNCpsKStzdW0obG9nKDEgKyBleHAoeCkpKS0obC8yKSpzdW0oZXhwKHgpIC0gMSkrc3VtKHgpKQ0KfQ0KDQpyZXN1bHRfbWxlX2luaXQgPC0gb3B0aW0oMSwgbmxvZ2xpa2UsIG1ldGhvZCA9ICJMLUJGR1MtQiIsIGxvd2VyID0gMCwgdXBwZXIgPSBJbmYsIGhlc3NpYW4gPSBUUlVFKQ0KDQptbGVfbGFtYmRhIDwtIHJlc3VsdF9tbGVfaW5pdCRwYXJbMV0NCmhlc3NpYW4gPC0gcmVzdWx0X21sZV9pbml0JGhlc3NpYW5bMV0NCg0KY2F0KCJNTEUgZm9yIiwgIlx1MDNCQiIsICI6IiwgbWxlX2xhbWJkYSkNCmBgYA0KDQoNCiMjIyBCdWlsZGluZyBlbXBpcmljYWwgU3RhbmRhcmQgRXJyb3IgYW5kIENvbmZpZGVuY2UgSW50ZXJ2YWwNCg0KSWYgeW91IGFyZSBtYXhpbWl6aW5nIGEgbGlrZWxpaG9vZCwgdGhlbiB0aGUgY292YXJpYW5jZSBtYXRyaXggb2YgdGhlIGVzdGltYXRlcyAob2JzZXJ2ZWQgaW5mb3JtYXRpb24pIGlzIChhc3ltcHRvdGljYWxseSBub3JtYWwpIHRoZSBpbnZlcnNlIG9mIHRoZSBuZWdhdGl2ZSBvZiB0aGUgSGVzc2lhbi4gVGhlIHN0YW5kYXJkIGVycm9ycyBhcmUgdGhlIHNxdWFyZSByb290cyBvZiB0aGUgZGlhZ29uYWwgZWxlbWVudHMgb2YgdGhlIGNvdmFyaWFuY2UgbWF0cml4Lg0KDQpgYGB7cn0NCmludl9maXNoIDwtIHNvbHZlKGhlc3NpYW4pDQpzZSA8LSBzcXJ0KGludl9maXNoWzEsMV0pDQp1YiA8LSBtbGVfbGFtYmRhICsgKHFub3JtKDAuMDI1LDAsMSxsb3dlci50YWlsID0gRkFMU0UpKnNlKQ0KbGIgPC0gbWxlX2xhbWJkYSAtIChxbm9ybSgwLjAyNSwwLDEsbG93ZXIudGFpbCA9IEZBTFNFKSpzZSkNCg0KY2F0KCJDSSBhdCA5NSUgY29uZmlkZW5jZSBsZXZlbCA9ICIsICJbIixsYix1YiwiXSIpDQpgYGANCg0KIyMjIE1vbnRlIENhcmxvIFNpbXVsYXRpb24gZm9yIHNhbXBsZSBzaXplIG4gPSAyNQ0KDQpTZXQgYSBzYW1wbGUgc2l6ZSAkbl97bWN9JDsgIA0KU2V0IGEgbnVtYmVyIG9mIHNpbXVsYXRpb25zIChzYW1wbGluZykgIA0KSW5pdGlhbGl6ZSBwYXJhbWV0ZXJzICRcbGFtYmRhX3tpfSQgIA0KR2VuZXJhdGUgcmFuZG9tIHZhcmlhYmxlcyBmcm9tIGRpc3RyaWJ1dGlvbiAgDQpQZXJmb3JtIGNhbGN1bGF0aW9ucyBmb3IgbWxlLCBiaWFzLCBtc2UsIGFwcHJveGltYXRlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLCBhbmQgcHJvcG9ydGlvbiBvZiBlc3RpbWF0ZXMgY29udGFpbmVkIGluIENJDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpzZXQuc2VlZCg0MikNCg0Kbl9tYyA9IDI1DQpuX3NpbXMgPSAxMDAwDQoNCnBhcmFtZXRlcnMgPC0gYygwLjEsIDAuNSwgMSwgMS41LCAzLCA1KQ0KDQpyZXN1bHRzX21jIDwtIGxpc3QoKQ0KYmlhc19tYyA8LSBsaXN0KCkNCm1zZV9tYyA8LSBsaXN0KCkNCm1sZV9tYyA8LSBsaXN0KCkNCmNpX21jIDwtIGxpc3QoKQ0KaGVzc2lhbl9tYyA8LSBsaXN0KCkNCnByb3BvcnRpb25fY2lfbWMgPC0gbGlzdCgpDQoNCm5sb2dsaWtlX21jIDwtIGZ1bmN0aW9uKGwsIHgpIHsNCiAgbiA8LSBsZW5ndGgoeCkNCiAgLTEqKDIqbipsb2cobCktbipsb2coNCs0KmwpK3N1bShsb2coMStleHAoeCkpKS0obC8yKSpzdW0oZXhwKHgpLTEpK3N1bSh4KSkNCn0NCg0KZm9yIChwYXJhbSBpbiBwYXJhbWV0ZXJzKSB7DQogIA0KICB1X21jIDwtIG1hdHJpeChydW5pZihuX3NpbXMgKiBuX21jLCAwLCAxKSwgbnJvdyA9IG5fc2ltcywgbmNvbCA9IG5fbWMpDQogIHNpbXNfbWMgPC0gYXBwbHkodV9tYywgYygxLCAyKSwgcXVhbnRpbGVfZnVuYywgcGFyYW0gPSBwYXJhbSkNCiAgcmVzdWx0c19tY1tbYXMuY2hhcmFjdGVyKHBhcmFtKV1dIDwtIHNpbXNfbWMNCiAgDQogIG1sZV9lc3RpbWF0ZXNfbWMgPC0gbnVtZXJpYyhucm93KHNpbXNfbWMpKQ0KICBoZXNzaWFuX2VzdGltYXRlc19tYyA8LSBsaXN0KCkNCiAgY2lfcGFyYW0gPC0gbWF0cml4KE5BLCBucm93ID0gbnJvdyhzaW1zX21jKSwgbmNvbCA9IDIpDQogIA0KICBmb3IgKCBpIGluIDE6bnJvdyhzaW1zX21jKSApIHsNCiAgICB4IDwtIHNpbXNfbWNbaSwgXQ0KICAgIHJlc3VsdF9tbGVfbWMgPC0gb3B0aW0oMSwgbmxvZ2xpa2VfbWMsIHg9eCwgbWV0aG9kPSJMLUJGR1MtQiIsIGxvd2VyPTAuMDEsIHVwcGVyPTEwMCwgaGVzc2lhbj1UUlVFKQ0KICAgIG1sZV9lc3RpbWF0ZXNfbWNbaV0gPC0gcmVzdWx0X21sZV9tYyRwYXINCiAgICBoZXNzaWFuX2VzdGltYXRlc19tY1tbaV1dIDwtIHJlc3VsdF9tbGVfbWMkaGVzc2lhbg0KICAgIA0KICAgIHNlIDwtIChkaWFnKHNvbHZlKHJlc3VsdF9tbGVfbWMkaGVzc2lhbikpKQ0KICAgIGNpX3BhcmFtW2ksIF0gPC0gbWxlX2VzdGltYXRlc19tY1tpXSArIHFub3JtKGMoMC4wMjUsIDAuOTc1KSkgKiBzcXJ0KHNlKQ0KICB9DQoNCiAgDQogIG1sZV9tY1tbYXMuY2hhcmFjdGVyKHBhcmFtKV1dIDwtIG1sZV9lc3RpbWF0ZXNfbWMNCiAgDQogIGhlc3NpYW5fbWNbW2FzLmNoYXJhY3RlcihwYXJhbSldXSA8LSBoZXNzaWFuX2VzdGltYXRlc19tYw0KICANCiAgY2lfbWNbW2FzLmNoYXJhY3RlcihwYXJhbSldXSA8LSBjaV9wYXJhbQ0KICANCiAgd2l0aGluX2NpIDwtIGFwcGx5KGNpX3BhcmFtLCAxLCBmdW5jdGlvbihjaSkgcGFyYW0gPj0gY2lbMV0gJiYgcGFyYW0gPD0gY2lbMl0pDQogIHByb3BvcnRpb25fY2lfbWNbW2FzLmNoYXJhY3RlcihwYXJhbSldXSA8LSBtZWFuKHdpdGhpbl9jaSkNCiAgDQogIGJpYXNfbWNbW2FzLmNoYXJhY3RlcihwYXJhbSldXSA8LSBtZWFuKG1sZV9lc3RpbWF0ZXNfbWMpIC0gcGFyYW0NCiAgICANCiAgbXNlX21jW1thcy5jaGFyYWN0ZXIocGFyYW0pXV0gPC0gbWVhbigobWxlX2VzdGltYXRlc19tYyAtIHBhcmFtKV4yKQ0KICANCn0NCmBgYA0KDQoNCg0KYGBge3IgZWNobz1GQUxTRX0NCnRhYmxlX2RhdGFfbWMgPC0gZGF0YS5mcmFtZSgNCiAgUGFyYW1ldGVyID0gcGFyYW1ldGVycywNCiAgU2FtcGxlU2l6ZSA9IHJlcChuX21jLCBsZW5ndGgocGFyYW1ldGVycykpLA0KICBNTEVfbWVhbiA9IHNhcHBseShtbGVfbWMsIG1lYW4pLA0KICBCaWFzID0gdW5saXN0KGJpYXNfbWMpLA0KICBNU0UgPSB1bmxpc3QobXNlX21jKSwNCiAgUEMgPSB1bmxpc3QocHJvcG9ydGlvbl9jaV9tYykNCikNCg0KcHJpbnQodGFibGVfZGF0YV9tYykNCmBgYA0KDQoNCg0KDQoNCg0K