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.

  1. 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.

  1. 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