Assignment Objectives
Master the fundamental concepts of point estimation and
performance metrics
Understand the theoretical foundation of the method of moments
estimator (MME)
Implement MME in R, incorporating numerical approximation
methods
Use of AI Tools
Policy on AI Tool Use: Students must 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.
Log-logistic Distribution
The log-logistic distribution (also known as the Fisk distribution)
is a continuous probability distribution that is particularly useful in
contexts where data exhibit non-negative, skewed behavior and where the
hazard rate is unimodal (increases to a peak and then decreases). It has
been widely used in the areas such as survival analysis and reliability
engineering, environmental science, economics, pharmacology, finance and
risk management, etc.
For given shape parameter \(\beta\)
and scale parameter \(\alpha\), the
cumulative distribution function
\[
F(x) = \frac{1}{1+(x/\alpha)^{-\beta}}
\]
As an exercise, you can derive the density in the following form
\[
f(x) =
\frac{(\beta/\alpha)(x/\alpha)^{\beta-1}}{[1+(x/\alpha)^\beta]^2}, \ \
\text{ for } \ \ x > 0.
\]
After some algebra, we can find the \(k\)th moment
\[
\mu_k = E[X^k] = \alpha^k B\left(1+\frac{k}{\beta}, 1 - \frac{k}{\beta}
\right).
\]
This assignment will focus on finding MME of parameters \(\alpha\) and \(\beta\) based on a real-world application
data set.
Question 1: Derive the log-logistic density function
Given the CDF of the two-parameter log-logistic distribution
\[
F(x) = \frac{1}{1+(x/\alpha)^{-\beta}}.
\]
The distribution function of the log-logistic function is given
above. Differentiation can be used to find the density function, f(x),
of the log-logistic distribution.
f(x) = \(\frac{d}{dx}\) F(x) = \(\frac{d}{dx}\) \(\frac{1}{1+(x/\alpha)^{-\beta}}\)
This entire distribution function F(x) can be multiplied by \(\frac{(x/\alpha)^{\beta}}{(x/\alpha)^{\beta}}\)
to remove the negative exponent in the denominator.
F(x) = \(\frac{1}{1+(x/\alpha)^{-\beta}}\) * \(\frac{(x/\alpha)^{\beta}}{(x/\alpha)^{\beta}}\)
= \(\frac{(x/\alpha)^{\beta}}{(x/\alpha)^{\beta} + [
(x/\alpha)^{\beta}*(x/\alpha)^{-\beta}]}\) = \(\frac{(x/\alpha)^{\beta}}{(x/\alpha)^{\beta} +
1}\) = \(\frac{(x/\alpha)^{\beta}}{1
+(x/\alpha)^{\beta}}\)
So, F(x) = \(\frac{(x/\alpha)^{\beta}}{1
+(x/\alpha)^{\beta}}\) and f(x) = \(\frac{d}{dx}\) \(\frac{(x/\alpha)^{\beta}}{1
+(x/\alpha)^{\beta}}\)
In order to find the density function, differentiation with the
quotient rule will be conducted. f(x) = \(\frac{u'(x)v(x) -
u(x)v'(x)}{[v(x)]^2}\)
For this function, the parts of the quotient rule are as follows.
u(x) = \((x/\alpha)^{\beta}\) and
u’(x) = \((\beta/\alpha)
*(x/\alpha)^{\beta-1}\)
v(x) = \(1 +(x/\alpha)^{\beta}\) and
v’(x) = \((\beta/\alpha)
*(x/\alpha)^{\beta-1}\)
So, now the quotient rule formula will be used to find the density
function f(x) for this log-logistic distribution.
f(x) = \(\frac{[(\beta/\alpha)(x/\alpha)^{\beta-1}(1
+(x/\alpha)^{\beta})] - [(x/\alpha)^{\beta}(\beta/\alpha)
*(x/\alpha)^{\beta-1}]}{[1 +(x/\alpha)^{\beta}]^2}\) = \(\frac{[(\beta/\alpha)(x/\alpha)^{\beta-1}
+(x/\alpha)^{\beta}(\beta/\alpha)(x/\alpha)^{\beta-1}] -
[(x/\alpha)^{\beta}(\beta/\alpha) *(x/\alpha)^{\beta-1}]}{[1
+(x/\alpha)^{\beta}]^2}\)
= \(\frac{(\beta/\alpha)(x/\alpha)^{\beta-1}
+(\beta/\alpha)(x/\alpha)^{2\beta-1} - (\beta/\alpha)
*(x/\alpha)^{2\beta-1}}{[1 +(x/\alpha)^{\beta}]^2}\) = \(\frac{(\beta/\alpha)(x/\alpha)^{\beta-1}
+(\beta/\alpha)(x/\alpha)^{2\beta-1} - (\beta/\alpha)
*(x/\alpha)^{2\beta-1}}{[1 +(x/\alpha)^{\beta}]^2}\) = \(\frac{(\beta/\alpha)(x/\alpha)^{\beta-1}}{[1
+(x/\alpha)^{\beta}]^2}\), for \(x >
0\)
So, the density function, f(x), for the log-logistic distribution is
given as:
f(x) = \(\frac{(\beta/\alpha)(x/\alpha)^{\beta-1}}{[1
+(x/\alpha)^{\beta}]^2}\) , for \(x
> 0\)
Question 2: Distribution of Recovery Time from A
Surgery
Time to recovery (in days) after a specific knee surgery procedure.
This follows a typical log-logistic pattern in medical
survival/recovery analysis:
8.23, 12.74, 14.83, 16.61, 18.16, 19.55, 20.80, 21.94, 23.00, 23.98, 24.89, 25.75, 26.56,
27.34, 28.08, 28.79, 29.48, 30.15, 30.81, 31.45, 32.08, 32.70, 33.31, 33.92, 34.53, 35.13,
35.73, 36.33, 36.93, 37.53, 38.14, 38.75, 39.37, 40.00, 40.64, 41.29, 41.95, 42.63, 43.33,
44.05, 44.79, 45.56, 46.36, 47.20, 48.08, 49.02, 50.03, 51.12, 52.32, 53.65
Based on the above data to perform the following analysis.
- Using method of moment estimation to estimate \(\alpha\) and \(\beta\), denoted by \(\hat{\alpha}\) and \(\hat{\beta}\), respectively.
To begin, a data set of the above values will be created. These
values represent the time to recovery, in days, after a knee surgery
procedure. This data set will be called ‘recovery’.
recovery <- c(8.23, 12.74, 14.83, 16.61, 18.16, 19.55, 20.80, 21.94, 23.00, 23.98, 24.89, 25.75, 26.56, 27.34, 28.08, 28.79, 29.48, 30.15, 30.81, 31.45, 32.08, 32.70, 33.31, 33.92, 34.53, 35.13, 35.73, 36.33, 36.93, 37.53, 38.14, 38.75, 39.37, 40.00, 40.64, 41.29, 41.95, 42.63, 43.33, 44.05, 44.79, 45.56, 46.36, 47.20, 48.08, 49.02, 50.03, 51.12, 52.32, 53.65)
Next, the method of moments estimation will be used to estimate \(\alpha\) and \(\beta\) for the recovery data set. These
estimated values will be denoted as \(\hat{\alpha}\) and \(\hat{\beta}\).
m1 <- mean(recovery)
m2 <- mean(recovery^2)
mom_equation <- function(beta) {
term1 <- beta(1 + 2/beta, 1 - 2/beta)
term2 <- beta(1 + 1/beta, 1 - 1/beta)^2
return(m2/m1^2 - term1/term2)}
mom_beta <- uniroot(mom_equation, lower = 2, upper = 50)$root
mom_alpha <- m1 / beta(1 + 1/mom_beta, 1 - 1/mom_beta)
cat("MoM estimates:\n",
" alpha_hat =", round(mom_alpha, 4),
", beta_hat =", round(mom_beta, 4), "\n")
MoM estimates:
alpha_hat = 32.6543 , beta_hat = 6.0062
The estimates found by the method of moment estimation are as
follows: \(\hat{\alpha}\) = 32.6543 and
\(\hat{\beta}\) = 6.0062.
- Since the moment estimates \(\hat{\alpha}\) and \(\hat{\beta}\) are random, construct
bootstrap sampling distributions for each. To visualize these
distributions, plot separate bootstrap histograms for \(\hat{\alpha}\) and \(\hat{\beta}\). Then, overlay a smooth
density curve on each histogram using Gaussian kernel density
estimation. Finally, describe the patterns of these density curves.
I will begin by generating the bootstrap estimates to construct the
bootstrap sampling distribution.
set.seed(123)
B <- 5000
alpha_boot <- numeric(B)
beta_boot <- numeric(B)
n <- length(recovery)
for (i in 1:B) {
boot_sample <- sample(recovery, n, replace = TRUE)
# The first and second moments
m1_boot <- mean(boot_sample)
m2_boot <- mean(boot_sample^2)
# The method of moments equation
mom_equation <- function(beta) {
term1 <- beta(1 + 2/beta, 1 - 2/beta)
term2 <- beta(1 + 1/beta, 1 - 1/beta)^2
return(m2_boot/m1_boot^2 - term1/term2)
}
# Solving for beta hat
beta_hat <- tryCatch(
uniroot(mom_equation, lower = 2, upper = 50)$root,
error = function(e) NA )
# Solving for alpha hat
alpha_hat <- m1_boot / beta(1 + 1/beta_hat, 1 - 1/beta_hat)
alpha_boot[i] <- alpha_hat
beta_boot[i] <- beta_hat
}
# I will remove missing values
alpha_boot <- alpha_boot[!is.na(alpha_boot)]
beta_boot <- beta_boot[!is.na(beta_boot)]
Now, I will plot the bootstrap distributions of \(\hat{\alpha}\) and \(\hat{\beta}\). For each plot, I will
overlay a smooth density curve on each histogram using Gaussian kernel
density estimation.
par(mfrow = c(1,2))
# Alpha Hat
hist(alpha_boot, probability = TRUE, breaks = 25,
main = "Bootstrap for Alpha Hat",
xlab = "Alpha Hat")
lines(density(alpha_boot), col = "purple", lwd = 2)
# Beta Hat
hist(beta_boot, probability = TRUE, breaks = 25,
main = "Bootstrap for beta Hat",
xlab = "Beta Hat")
lines(density(beta_boot), col = "purple", lwd = 2)

The bootstrap distribution of \(\hat{\alpha}\) appears to be symmetric and
unimodal, with an approximately Normal distribution. The mean of \(\hat{\alpha}\) is roughly between 32 and
33, which matches up perfectly with the estimate of \(\hat{\alpha}\) from the previous part which
was found to be 32.6543. The bootstrap distribution of \(\hat{\beta}\) is unimodal and appears to be
ever so slightly skewed to the right. The mean of the \(\hat{\beta}\) appears to be around 6, which
matches up perfectly with the estimate of \(\hat{\beta}\) = 6.0062 from the previous
part, which was found to be 6.0062.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMzogTWV0aG9kcyBvZiBNb21lbnQgRXN0aW1hdGlvbiINCmF1dGhvcjogIkpvc2llIEdhbGxvcCINCmRhdGU6ICIgRHVlOiAwMi0yNC0yMDI2Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIHRoZW1lOiBsdW1lbg0KICBwZGZfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiAzDQogICAgZmlnX2hlaWdodDogMw0KICB3b3JkX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCmVkaXRvcl9vcHRpb25zOiANCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KLS0tDQoNCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0NCiNUT0M6OmJlZm9yZSB7DQogIGNvbnRlbnQ6ICJUYWJsZSBvZiBDb250ZW50cyI7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LXNpemU6IDEuMmVtOw0KICBkaXNwbGF5OiBibG9jazsNCiAgY29sb3I6IG5hdnk7DQogIG1hcmdpbi1ib3R0b206IDEwcHg7DQp9DQoNCg0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLw0KICAgIGxpc3Qtc3R5bGU6dXBwZXItcm9tYW47DQogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOw0KICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7DQogICAgYmFja2dyb3VuZC1wb3NpdGlvbjowOw0KfQ0KDQpoMS50aXRsZSB7ICAgIC8qIGxldmVsIDEgaGVhZGVyIG9mIHRpdGxlICAqLw0KICBmb250LXNpemU6IDIycHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQoNCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMTVweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBuYXZ5Ow0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoMSB7IC8qIEhlYWRlciAxIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDIgeyAvKiBIZWFkZXIgMiAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNnB4Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE0cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIEFkZCBkb3RzIGFmdGVyIG51bWJlcmVkIGhlYWRlcnMgKi8NCi5oZWFkZXItc2VjdGlvbi1udW1iZXI6OmFmdGVyIHsNCiAgY29udGVudDogIi4iOw0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQp9DQpgYGANCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgDQojIHdpbGwgYmUgaW5jbHVkZWQgaW4gdGhlIG91dHB1dCBmaWxlcy4NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBhbmRlciIpDQogICBsaWJyYXJ5KHBhbmRlcikNCn0NCmlmICghcmVxdWlyZSgiZ2dwbG90MiIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KDQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogIGxpYnJhcnkocGxvdGx5KQ0KfQ0KIyMjIw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUNCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgIyBzb21ldGltZXMsIHlvdSBjb2RlIG1heSBwcm9kdWNlIHdhcm5pbmcgbWVzc2FnZXMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgeW91IGNhbiBjaG9vc2UgdG8gaW5jbHVkZSB0aGUgd2FybmluZyBtZXNzYWdlcyBpbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFRSVUUsICAgICMgeW91IGNhbiBhbHNvIGRlY2lkZSB3aGV0aGVyIHRvIGluY2x1ZGUgdGhlIG91dHB1dA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGluIHRoZSBvdXRwdXQgZmlsZS4NCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BDQogICAgICAgICAgICAgICAgICAgICAgKSAgDQpgYGANCiANCiBcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIE1hc3RlciB0aGUgZnVuZGFtZW50YWwgY29uY2VwdHMgb2YgcG9pbnQgZXN0aW1hdGlvbiBhbmQgcGVyZm9ybWFuY2UgbWV0cmljcw0KDQoqIFVuZGVyc3RhbmQgdGhlIHRoZW9yZXRpY2FsIGZvdW5kYXRpb24gb2YgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGVzdGltYXRvciAoTU1FKQ0KDQoqIEltcGxlbWVudCBNTUUgaW4gUiwgaW5jb3Jwb3JhdGluZyBudW1lcmljYWwgYXBwcm94aW1hdGlvbiBtZXRob2RzDQoNClwNCg0KKipVc2Ugb2YgQUkgVG9vbHMqKg0KDQoqKlBvbGljeSBvbiBBSSBUb29sIFVzZSoqOiBTdHVkZW50cyBtdXN0IGFkaGVyZSB0byB0aGUgQUkgdG9vbCBwb2xpY3kgc3BlY2lmaWVkIGluIHRoZSBjb3Vyc2Ugc3lsbGFidXMuIFRoZSBkaXJlY3QgY29weWluZyBvZiBBSS1nZW5lcmF0ZWQgY29udGVudCBpcyBzdHJpY3RseSBwcm9oaWJpdGVkLiBBbGwgc3VibWl0dGVkIHdvcmsgbXVzdCByZWZsZWN0IHlvdXIgb3duIHVuZGVyc3RhbmRpbmc7IHdoZXJlIGV4dGVybmFsIHRvb2xzIGFyZSBjb25zdWx0ZWQsIGNvbnRlbnQgbXVzdCBiZSB0aG9yb3VnaGx5IHJlcGhyYXNlZCBhbmQgc3ludGhlc2l6ZWQgaW4geW91ciBvd24gd29yZHMuDQoNCioqQ29kZSBJbmNsdXNpb24gUmVxdWlyZW1lbnQqKjogQW55IGNvZGUgaW5jbHVkZWQgaW4geW91ciBlc3NheSBtdXN0IGJlIHByb3Blcmx5IGNvbW1lbnRlZCB0byBleHBsYWluIHRoZSBwdXJwb3NlIGFuZC9vciBleHBlY3RlZCBvdXRwdXQgb2Yga2V5IGNvZGUgbGluZXMuIFN1Ym1pdHRpbmcgQUktZ2VuZXJhdGVkIGNvZGUgd2l0aG91dCBtZWFuaW5nZnVsLCBzdHVkZW50LWFkZGVkIGNvbW1lbnRzIHdpbGwgbm90IGJlIGFjY2VwdGVkLg0KDQpcDQoNCioqTG9nLWxvZ2lzdGljIERpc3RyaWJ1dGlvbioqDQoNClRoZSBsb2ctbG9naXN0aWMgZGlzdHJpYnV0aW9uIChhbHNvIGtub3duIGFzIHRoZSBGaXNrIGRpc3RyaWJ1dGlvbikgaXMgYSBjb250aW51b3VzIHByb2JhYmlsaXR5IGRpc3RyaWJ1dGlvbiB0aGF0IGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgaW4gY29udGV4dHMgd2hlcmUgZGF0YSBleGhpYml0IG5vbi1uZWdhdGl2ZSwgc2tld2VkIGJlaGF2aW9yIGFuZCB3aGVyZSB0aGUgaGF6YXJkIHJhdGUgaXMgdW5pbW9kYWwgKGluY3JlYXNlcyB0byBhIHBlYWsgYW5kIHRoZW4gZGVjcmVhc2VzKS4gSXQgaGFzIGJlZW4gd2lkZWx5IHVzZWQgaW4gdGhlIGFyZWFzIHN1Y2ggYXMgc3Vydml2YWwgYW5hbHlzaXMgYW5kIHJlbGlhYmlsaXR5IGVuZ2luZWVyaW5nLCBlbnZpcm9ubWVudGFsIHNjaWVuY2UsIGVjb25vbWljcywgcGhhcm1hY29sb2d5LCBmaW5hbmNlIGFuZCByaXNrIG1hbmFnZW1lbnQsIGV0Yy4gDQoNCkZvciBnaXZlbiBzaGFwZSBwYXJhbWV0ZXIgJFxiZXRhJCBhbmQgc2NhbGUgcGFyYW1ldGVyICRcYWxwaGEkLCB0aGUgY3VtdWxhdGl2ZSBkaXN0cmlidXRpb24gZnVuY3Rpb24NCg0KJCQNCkYoeCkgPSBcZnJhY3sxfXsxKyh4L1xhbHBoYSleey1cYmV0YX19DQokJA0KDQpBcyBhbiBleGVyY2lzZSwgeW91IGNhbiBkZXJpdmUgdGhlIGRlbnNpdHkgaW4gdGhlIGZvbGxvd2luZyBmb3JtDQoNCiQkDQpmKHgpID0gXGZyYWN7KFxiZXRhL1xhbHBoYSkoeC9cYWxwaGEpXntcYmV0YS0xfX17WzErKHgvXGFscGhhKV5cYmV0YV1eMn0sIFwgXCBcdGV4dHsgZm9yIH0gXCBcIHggPiAwLg0KJCQNCg0KQWZ0ZXIgc29tZSBhbGdlYnJhLCB3ZSBjYW4gZmluZCB0aGUgJGskdGggbW9tZW50DQoNCiQkDQpcbXVfayA9IEVbWF5rXSA9IFxhbHBoYV5rIEJcbGVmdCgxK1xmcmFje2t9e1xiZXRhfSwgMSAtIFxmcmFje2t9e1xiZXRhfSBccmlnaHQpLg0KJCQNCg0KVGhpcyBhc3NpZ25tZW50IHdpbGwgZm9jdXMgb24gZmluZGluZyBNTUUgb2YgcGFyYW1ldGVycyAkXGFscGhhJCBhbmQgJFxiZXRhJCBiYXNlZCBvbiBhIHJlYWwtd29ybGQgYXBwbGljYXRpb24gZGF0YSBzZXQuDQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uIDE6IERlcml2ZSB0aGUgbG9nLWxvZ2lzdGljIGRlbnNpdHkgZnVuY3Rpb24gKioNCg0KR2l2ZW4gdGhlIENERiBvZiB0aGUgdHdvLXBhcmFtZXRlciBsb2ctbG9naXN0aWMgZGlzdHJpYnV0aW9uDQoNCiQkDQpGKHgpID0gXGZyYWN7MX17MSsoeC9cYWxwaGEpXnstXGJldGF9fS4NCiQkDQoNClRoZSBkaXN0cmlidXRpb24gZnVuY3Rpb24gb2YgdGhlIGxvZy1sb2dpc3RpYyBmdW5jdGlvbiBpcyBnaXZlbiBhYm92ZS4gRGlmZmVyZW50aWF0aW9uIGNhbiBiZSB1c2VkIHRvIGZpbmQgdGhlIGRlbnNpdHkgZnVuY3Rpb24sIGYoeCksIG9mIHRoZSBsb2ctbG9naXN0aWMgZGlzdHJpYnV0aW9uLg0KDQpmKHgpID0gJFxmcmFje2R9e2R4fSQgRih4KSA9ICRcZnJhY3tkfXtkeH0kICRcZnJhY3sxfXsxKyh4L1xhbHBoYSleey1cYmV0YX19JA0KDQoNClRoaXMgZW50aXJlIGRpc3RyaWJ1dGlvbiBmdW5jdGlvbiBGKHgpIGNhbiBiZSBtdWx0aXBsaWVkIGJ5ICRcZnJhY3soeC9cYWxwaGEpXntcYmV0YX19eyh4L1xhbHBoYSlee1xiZXRhfX0kIHRvIHJlbW92ZSB0aGUgbmVnYXRpdmUgZXhwb25lbnQgaW4gdGhlIGRlbm9taW5hdG9yLiANCg0KRih4KSA9ICRcZnJhY3sxfXsxKyh4L1xhbHBoYSleey1cYmV0YX19JCAqICRcZnJhY3soeC9cYWxwaGEpXntcYmV0YX19eyh4L1xhbHBoYSlee1xiZXRhfX0kICA9ICRcZnJhY3soeC9cYWxwaGEpXntcYmV0YX19eyh4L1xhbHBoYSlee1xiZXRhfSArIFsgKHgvXGFscGhhKV57XGJldGF9Kih4L1xhbHBoYSleey1cYmV0YX1dfSQgID0gJFxmcmFjeyh4L1xhbHBoYSlee1xiZXRhfX17KHgvXGFscGhhKV57XGJldGF9ICsgMX0kICA9ICRcZnJhY3soeC9cYWxwaGEpXntcYmV0YX19ezEgKyh4L1xhbHBoYSlee1xiZXRhfX0kDQoNClNvLCBGKHgpID0gJFxmcmFjeyh4L1xhbHBoYSlee1xiZXRhfX17MSArKHgvXGFscGhhKV57XGJldGF9fSQgYW5kIGYoeCkgPSAkXGZyYWN7ZH17ZHh9JCAkXGZyYWN7KHgvXGFscGhhKV57XGJldGF9fXsxICsoeC9cYWxwaGEpXntcYmV0YX19JA0KDQpJbiBvcmRlciB0byBmaW5kIHRoZSBkZW5zaXR5IGZ1bmN0aW9uLCBkaWZmZXJlbnRpYXRpb24gd2l0aCB0aGUgcXVvdGllbnQgcnVsZSB3aWxsIGJlIGNvbmR1Y3RlZC4gZih4KSA9ICRcZnJhY3t1Jyh4KXYoeCkgLSB1KHgpdicoeCl9e1t2KHgpXV4yfSQNCg0KRm9yIHRoaXMgZnVuY3Rpb24sIHRoZSBwYXJ0cyBvZiB0aGUgcXVvdGllbnQgcnVsZSBhcmUgYXMgZm9sbG93cy4gDQoNCnUoeCkgPSAkKHgvXGFscGhhKV57XGJldGF9JCAgYW5kIHUnKHgpID0gJChcYmV0YS9cYWxwaGEpICooeC9cYWxwaGEpXntcYmV0YS0xfSQNCg0Kdih4KSA9ICQxICsoeC9cYWxwaGEpXntcYmV0YX0kICBhbmQgdicoeCkgPSAgJChcYmV0YS9cYWxwaGEpICooeC9cYWxwaGEpXntcYmV0YS0xfSQNCg0KDQpTbywgbm93IHRoZSBxdW90aWVudCBydWxlIGZvcm11bGEgd2lsbCBiZSB1c2VkIHRvIGZpbmQgdGhlIGRlbnNpdHkgZnVuY3Rpb24gZih4KSBmb3IgdGhpcyBsb2ctbG9naXN0aWMgZGlzdHJpYnV0aW9uLg0KDQoNCmYoeCkgPSAkXGZyYWN7WyhcYmV0YS9cYWxwaGEpKHgvXGFscGhhKV57XGJldGEtMX0oMSArKHgvXGFscGhhKV57XGJldGF9KV0gLSBbKHgvXGFscGhhKV57XGJldGF9KFxiZXRhL1xhbHBoYSkgKih4L1xhbHBoYSlee1xiZXRhLTF9XX17WzEgKyh4L1xhbHBoYSlee1xiZXRhfV1eMn0kICA9ICRcZnJhY3tbKFxiZXRhL1xhbHBoYSkoeC9cYWxwaGEpXntcYmV0YS0xfSArKHgvXGFscGhhKV57XGJldGF9KFxiZXRhL1xhbHBoYSkoeC9cYWxwaGEpXntcYmV0YS0xfV0gIC0gWyh4L1xhbHBoYSlee1xiZXRhfShcYmV0YS9cYWxwaGEpICooeC9cYWxwaGEpXntcYmV0YS0xfV19e1sxICsoeC9cYWxwaGEpXntcYmV0YX1dXjJ9JCANCg0KDQo9ICRcZnJhY3soXGJldGEvXGFscGhhKSh4L1xhbHBoYSlee1xiZXRhLTF9ICsoXGJldGEvXGFscGhhKSh4L1xhbHBoYSleezJcYmV0YS0xfSAgLSAoXGJldGEvXGFscGhhKSAqKHgvXGFscGhhKV57MlxiZXRhLTF9fXtbMSArKHgvXGFscGhhKV57XGJldGF9XV4yfSQgID0gJFxmcmFjeyhcYmV0YS9cYWxwaGEpKHgvXGFscGhhKV57XGJldGEtMX0gKyhcYmV0YS9cYWxwaGEpKHgvXGFscGhhKV57MlxiZXRhLTF9ICAtIChcYmV0YS9cYWxwaGEpICooeC9cYWxwaGEpXnsyXGJldGEtMX19e1sxICsoeC9cYWxwaGEpXntcYmV0YX1dXjJ9JCAgID0gJFxmcmFjeyhcYmV0YS9cYWxwaGEpKHgvXGFscGhhKV57XGJldGEtMX19e1sxICsoeC9cYWxwaGEpXntcYmV0YX1dXjJ9JCwgZm9yICR4ID4gMCQNCg0KDQpTbywgdGhlIGRlbnNpdHkgZnVuY3Rpb24sIGYoeCksIGZvciB0aGUgbG9nLWxvZ2lzdGljIGRpc3RyaWJ1dGlvbiBpcyBnaXZlbiBhczogDQoNCmYoeCkgPSAkXGZyYWN7KFxiZXRhL1xhbHBoYSkoeC9cYWxwaGEpXntcYmV0YS0xfX17WzEgKyh4L1xhbHBoYSlee1xiZXRhfV1eMn0kICwgZm9yICR4ID4gMCQgDQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uIDI6IERpc3RyaWJ1dGlvbiBvZiBSZWNvdmVyeSBUaW1lIGZyb20gQSBTdXJnZXJ5KioNCg0KVGltZSB0byByZWNvdmVyeSAoaW4gZGF5cykgYWZ0ZXIgYSBzcGVjaWZpYyBrbmVlIHN1cmdlcnkgcHJvY2VkdXJlLiBUaGlzIGZvbGxvd3MgYSB0eXBpY2FsICoqbG9nLWxvZ2lzdGljIHBhdHRlcm4qKiBpbiBtZWRpY2FsIHN1cnZpdmFsL3JlY292ZXJ5IGFuYWx5c2lzOg0KDQpgYGANCjguMjMsIDEyLjc0LCAxNC44MywgMTYuNjEsIDE4LjE2LCAxOS41NSwgMjAuODAsIDIxLjk0LCAyMy4wMCwgMjMuOTgsIDI0Ljg5LCAyNS43NSwgMjYuNTYsIA0KMjcuMzQsIDI4LjA4LCAyOC43OSwgMjkuNDgsIDMwLjE1LCAzMC44MSwgMzEuNDUsIDMyLjA4LCAzMi43MCwgMzMuMzEsIDMzLjkyLCAzNC41MywgMzUuMTMsIA0KMzUuNzMsIDM2LjMzLCAzNi45MywgMzcuNTMsIDM4LjE0LCAzOC43NSwgMzkuMzcsIDQwLjAwLCA0MC42NCwgNDEuMjksIDQxLjk1LCA0Mi42MywgNDMuMzMsIA0KNDQuMDUsIDQ0Ljc5LCA0NS41NiwgNDYuMzYsIDQ3LjIwLCA0OC4wOCwgNDkuMDIsIDUwLjAzLCA1MS4xMiwgNTIuMzIsIDUzLjY1DQpgYGANCkJhc2VkIG9uIHRoZSBhYm92ZSBkYXRhIHRvIHBlcmZvcm0gdGhlIGZvbGxvd2luZyBhbmFseXNpcy4NCg0KYSkgVXNpbmcgbWV0aG9kIG9mIG1vbWVudCBlc3RpbWF0aW9uIHRvIGVzdGltYXRlICRcYWxwaGEkIGFuZCAkXGJldGEkLCBkZW5vdGVkIGJ5ICRcaGF0e1xhbHBoYX0kIGFuZCAkXGhhdHtcYmV0YX0kLCByZXNwZWN0aXZlbHkuIA0KDQpUbyBiZWdpbiwgYSBkYXRhIHNldCBvZiB0aGUgYWJvdmUgdmFsdWVzIHdpbGwgYmUgY3JlYXRlZC4gVGhlc2UgdmFsdWVzIHJlcHJlc2VudCB0aGUgdGltZSB0byByZWNvdmVyeSwgaW4gZGF5cywgYWZ0ZXIgYSBrbmVlIHN1cmdlcnkgcHJvY2VkdXJlLiBUaGlzIGRhdGEgc2V0IHdpbGwgYmUgY2FsbGVkICdyZWNvdmVyeScuIA0KDQpgYGB7cn0NCnJlY292ZXJ5IDwtIGMoOC4yMywgMTIuNzQsIDE0LjgzLCAxNi42MSwgMTguMTYsIDE5LjU1LCAyMC44MCwgMjEuOTQsIDIzLjAwLCAyMy45OCwgMjQuODksIDI1Ljc1LCAyNi41NiwgMjcuMzQsIDI4LjA4LCAyOC43OSwgMjkuNDgsIDMwLjE1LCAzMC44MSwgMzEuNDUsIDMyLjA4LCAzMi43MCwgMzMuMzEsIDMzLjkyLCAzNC41MywgMzUuMTMsIDM1LjczLCAzNi4zMywgMzYuOTMsIDM3LjUzLCAzOC4xNCwgMzguNzUsIDM5LjM3LCA0MC4wMCwgNDAuNjQsIDQxLjI5LCA0MS45NSwgNDIuNjMsIDQzLjMzLCA0NC4wNSwgNDQuNzksIDQ1LjU2LCA0Ni4zNiwgNDcuMjAsIDQ4LjA4LCA0OS4wMiwgNTAuMDMsIDUxLjEyLCA1Mi4zMiwgNTMuNjUpDQpgYGANCg0KTmV4dCwgdGhlIG1ldGhvZCBvZiBtb21lbnRzIGVzdGltYXRpb24gd2lsbCBiZSB1c2VkIHRvIGVzdGltYXRlICRcYWxwaGEkIGFuZCAkXGJldGEkIGZvciB0aGUgcmVjb3ZlcnkgZGF0YSBzZXQuIFRoZXNlIGVzdGltYXRlZCB2YWx1ZXMgd2lsbCBiZSBkZW5vdGVkIGFzICAkXGhhdHtcYWxwaGF9JCBhbmQgJFxoYXR7XGJldGF9JC4gDQoNCmBgYHtyfQ0KbTEgPC0gbWVhbihyZWNvdmVyeSkNCm0yIDwtIG1lYW4ocmVjb3ZlcnleMikNCg0KbW9tX2VxdWF0aW9uIDwtIGZ1bmN0aW9uKGJldGEpIHsNCiAgdGVybTEgPC0gYmV0YSgxICsgMi9iZXRhLCAxIC0gMi9iZXRhKQ0KICB0ZXJtMiA8LSBiZXRhKDEgKyAxL2JldGEsIDEgLSAxL2JldGEpXjINCiAgcmV0dXJuKG0yL20xXjIgLSB0ZXJtMS90ZXJtMil9DQoNCm1vbV9iZXRhIDwtIHVuaXJvb3QobW9tX2VxdWF0aW9uLCBsb3dlciA9IDIsIHVwcGVyID0gNTApJHJvb3QNCg0KbW9tX2FscGhhIDwtIG0xIC8gYmV0YSgxICsgMS9tb21fYmV0YSwgMSAtIDEvbW9tX2JldGEpDQoNCmNhdCgiTW9NIGVzdGltYXRlczpcbiIsDQogICAgIiAgIGFscGhhX2hhdCA9Iiwgcm91bmQobW9tX2FscGhhLCA0KSwNCiAgICAiLCBiZXRhX2hhdCA9Iiwgcm91bmQobW9tX2JldGEsIDQpLCAiXG4iKQ0KYGBgDQoNClRoZSBlc3RpbWF0ZXMgZm91bmQgYnkgdGhlIG1ldGhvZCBvZiBtb21lbnQgZXN0aW1hdGlvbiBhcmUgYXMgZm9sbG93czogJFxoYXR7XGFscGhhfSQgPSAzMi42NTQzIGFuZCAkXGhhdHtcYmV0YX0kID0gNi4wMDYyLg0KDQoNCg0KYikgU2luY2UgdGhlIG1vbWVudCBlc3RpbWF0ZXMgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQgYXJlIHJhbmRvbSwgY29uc3RydWN0IGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb25zIGZvciBlYWNoLiBUbyB2aXN1YWxpemUgdGhlc2UgZGlzdHJpYnV0aW9ucywgcGxvdCBzZXBhcmF0ZSBib290c3RyYXAgaGlzdG9ncmFtcyBmb3IgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQuICBUaGVuLCBvdmVybGF5IGEgc21vb3RoIGRlbnNpdHkgY3VydmUgb24gZWFjaCBoaXN0b2dyYW0gdXNpbmcgR2F1c3NpYW4ga2VybmVsIGRlbnNpdHkgZXN0aW1hdGlvbi4gRmluYWxseSwgZGVzY3JpYmUgdGhlIHBhdHRlcm5zIG9mIHRoZXNlIGRlbnNpdHkgY3VydmVzLg0KDQpJIHdpbGwgYmVnaW4gYnkgZ2VuZXJhdGluZyB0aGUgYm9vdHN0cmFwIGVzdGltYXRlcyB0byBjb25zdHJ1Y3QgdGhlIGJvb3RzdHJhcCBzYW1wbGluZyBkaXN0cmlidXRpb24uDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0KQiA8LSA1MDAwDQoNCmFscGhhX2Jvb3QgPC0gbnVtZXJpYyhCKQ0KYmV0YV9ib290IDwtIG51bWVyaWMoQikNCm4gPC0gbGVuZ3RoKHJlY292ZXJ5KQ0KDQpmb3IgKGkgaW4gMTpCKSB7DQogIGJvb3Rfc2FtcGxlIDwtIHNhbXBsZShyZWNvdmVyeSwgbiwgcmVwbGFjZSA9IFRSVUUpDQogIA0KICAjIFRoZSBmaXJzdCBhbmQgc2Vjb25kIG1vbWVudHMNCiAgbTFfYm9vdCA8LSBtZWFuKGJvb3Rfc2FtcGxlKQ0KICBtMl9ib290IDwtIG1lYW4oYm9vdF9zYW1wbGVeMikNCiAgDQogICMgVGhlIG1ldGhvZCBvZiBtb21lbnRzIGVxdWF0aW9uDQogIG1vbV9lcXVhdGlvbiA8LSBmdW5jdGlvbihiZXRhKSB7DQogICAgdGVybTEgPC0gYmV0YSgxICsgMi9iZXRhLCAxIC0gMi9iZXRhKQ0KICAgIHRlcm0yIDwtIGJldGEoMSArIDEvYmV0YSwgMSAtIDEvYmV0YSleMg0KICAgIHJldHVybihtMl9ib290L20xX2Jvb3ReMiAtIHRlcm0xL3Rlcm0yKQ0KICB9DQogIA0KICAjIFNvbHZpbmcgZm9yIGJldGEgaGF0DQogIGJldGFfaGF0IDwtIHRyeUNhdGNoKA0KICAgIHVuaXJvb3QobW9tX2VxdWF0aW9uLCBsb3dlciA9IDIsIHVwcGVyID0gNTApJHJvb3QsDQogICAgZXJyb3IgPSBmdW5jdGlvbihlKSBOQSApDQogIA0KICAjIFNvbHZpbmcgZm9yIGFscGhhIGhhdA0KICAgIGFscGhhX2hhdCA8LSBtMV9ib290IC8gYmV0YSgxICsgMS9iZXRhX2hhdCwgMSAtIDEvYmV0YV9oYXQpDQogICAgYWxwaGFfYm9vdFtpXSA8LSBhbHBoYV9oYXQNCiAgICBiZXRhX2Jvb3RbaV0gPC0gYmV0YV9oYXQNCn0NCg0KIyBJIHdpbGwgcmVtb3ZlIG1pc3NpbmcgdmFsdWVzDQphbHBoYV9ib290IDwtIGFscGhhX2Jvb3RbIWlzLm5hKGFscGhhX2Jvb3QpXQ0KYmV0YV9ib290IDwtIGJldGFfYm9vdFshaXMubmEoYmV0YV9ib290KV0NCmBgYA0KDQpOb3csIEkgd2lsbCBwbG90IHRoZSBib290c3RyYXAgZGlzdHJpYnV0aW9ucyBvZiAgJFxoYXR7XGFscGhhfSQgIGFuZCAgJFxoYXR7XGJldGF9JC4gRm9yIGVhY2ggcGxvdCwgSSB3aWxsIG92ZXJsYXkgYSBzbW9vdGggZGVuc2l0eSBjdXJ2ZSBvbiBlYWNoIGhpc3RvZ3JhbSB1c2luZyBHYXVzc2lhbiBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0aW9uLg0KDQpgYGB7cn0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCg0KIyBBbHBoYSBIYXQNCmhpc3QoYWxwaGFfYm9vdCwgcHJvYmFiaWxpdHkgPSBUUlVFLCBicmVha3MgPSAyNSwNCiAgICAgbWFpbiA9ICJCb290c3RyYXAgZm9yIEFscGhhIEhhdCIsDQogICAgIHhsYWIgPSAiQWxwaGEgSGF0IikNCmxpbmVzKGRlbnNpdHkoYWxwaGFfYm9vdCksIGNvbCA9ICJwdXJwbGUiLCBsd2QgPSAyKQ0KDQojIEJldGEgSGF0DQpoaXN0KGJldGFfYm9vdCwgcHJvYmFiaWxpdHkgPSBUUlVFLCBicmVha3MgPSAyNSwNCiAgICAgbWFpbiA9ICJCb290c3RyYXAgZm9yIGJldGEgSGF0IiwNCiAgICAgeGxhYiA9ICJCZXRhIEhhdCIpDQpsaW5lcyhkZW5zaXR5KGJldGFfYm9vdCksIGNvbCA9ICJwdXJwbGUiLCBsd2QgPSAyKQ0KYGBgDQoNCg0KVGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gb2YgJFxoYXR7XGFscGhhfSQgYXBwZWFycyB0byBiZSBzeW1tZXRyaWMgYW5kIHVuaW1vZGFsLCB3aXRoIGFuIGFwcHJveGltYXRlbHkgTm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlIG1lYW4gb2YgJFxoYXR7XGFscGhhfSQgaXMgcm91Z2hseSBiZXR3ZWVuIDMyIGFuZCAzMywgd2hpY2ggbWF0Y2hlcyB1cCBwZXJmZWN0bHkgd2l0aCB0aGUgZXN0aW1hdGUgb2YgJFxoYXR7XGFscGhhfSQgZnJvbSB0aGUgcHJldmlvdXMgcGFydCB3aGljaCB3YXMgZm91bmQgdG8gYmUgMzIuNjU0My4gVGhlIGJvb3RzdHJhcCBkaXN0cmlidXRpb24gb2YgJFxoYXR7XGJldGF9JCBpcyB1bmltb2RhbCBhbmQgYXBwZWFycyB0byBiZSBldmVyIHNvIHNsaWdodGx5IHNrZXdlZCB0byB0aGUgcmlnaHQuIFRoZSBtZWFuIG9mIHRoZSAkXGhhdHtcYmV0YX0kIGFwcGVhcnMgdG8gYmUgYXJvdW5kIDYsIHdoaWNoIG1hdGNoZXMgdXAgcGVyZmVjdGx5IHdpdGggdGhlIGVzdGltYXRlIG9mICRcaGF0e1xiZXRhfSQgPSA2LjAwNjIgZnJvbSB0aGUgcHJldmlvdXMgcGFydCwgd2hpY2ggd2FzIGZvdW5kIHRvIGJlIDYuMDA2Mi4NCg0KDQoNCg0K