1 Introduction

We have introduced different methods for estimating a parameter based on a random sample - point estimator. However, A point estimate gives a single number without indicating how precise or reliable it is.

A confidence interval (CI) provides a range of plausible values for an unknown parameter \(\theta\) with a specified confidence level \((1-\alpha)100\%\). Formally, for data \(X_1,\ldots,X_n\):

\[ P[L(X) \le \theta \le U(X)] = 1 - \alpha \]

where \(L(X)\) and \(U(X)\) are the lower and upper bounds that are expression of data values only.

The key logic of confidence interval is that if we repeated the sampling process infinitely many times and constructed a CI from each sample, a \((1-\alpha)\%\) of those intervals would contain the true parameter value.

Goodness Measures of CI

  • Coverage probability: \(P(\theta \in CI) = 1-\alpha\). It also called confidence level.

  • Width: \(U(X) - L(X)\) - calculate based on sample (estimated from the data), hence, it is random.

  • Expected length: \(E[U(X) - L(X)]\) - A theoretical length that is independent on the random sample.


A confidence interval tells us what values of the parameter are compatible with the observed data at a specified confidence level, based on the sampling distribution of the estimator.

2 Pivotal Quantity and Confidence Interval

Mathematical Formulation

A pivotal quantity \(Q(X,\theta)\) is a function of both data and parameter whose distribution does not depend on \(\theta\).

Some examples we learned before. Let \(\{X_1, X_2, \cdots, X_n \}\) be i.i.d. random sample from \(N(\mu, \sigma^2)\). Let \(\bar{X}\) be the sample mean and \(S^2\) be the sample variance. The following are expressions are pivotal quantities.

\[ Z(\mu) = \frac{\bar{X}-\mu}{\sigma_0/\sqrt{n}}, \ \ \ T(\mu) = \frac{\bar{X}-\mu}{s/\sqrt{n}}, \ \ \ W(\sigma) = \frac{(n-1)S^2}{\sigma^2}, \ \ \text{ etc.} \]

Clearly, \(Z(\mu)\xrightarrow{d} N(0, 1)\), \(T(\mu) \xrightarrow{d} t_{n-1}\), and \(W(\sigma) \xrightarrow{d} \chi_{n-1}^2\). The notation \(\xrightarrow{d}\) simply means follows in distribution. Furthermore, \(N(0, 1), t_{n-1}\) and \(\chi_{n-1}^2\) are not independent on parameters. Therefore, \(Z(\mu), T(\mu)\), and \(W(\sigma)\) are pivotal quantities.

To explain why a pivotal quantity can be used to construct confidence interval of a population parameter, we use the third pivotal quantity \(W(\sigma)\). Let \(1-\alpha\) be the confidence interval (see the area of the shaded region in the following figures)

include_graphics("pivotalQuant.png")

  • In Figure A (top panel), the area of the shaded region satisfies

\[ P(W > L) = 1-\alpha \ \ \text{ which is equivalent to } \ \ P\left[ \frac{(n-1)S^2}{\sigma^2} > L\right] = 1-\alpha \]

Solving inequality for \(\sigma^2\), we have

\[ \frac{(n-1)S^2}{\sigma^2} > L \quad \Rightarrow \quad \sigma^2 < \frac{(n-1)S^2}{L} \ \ \text{ i.e. } \ \ \sigma^2 \in \left(0, \frac{(n-1)S^2}{L} \right). \]

where \(L\) is \(100\alpha\)-th quantile one \(\alpha\) is given. Note also that the low limit 0 is due the fact that variance \(\sigma^2\) is greater than zero.

  • In Figure B (middle panel), the area of the shaded region satisfies

\[ P(c_1 < W < c_2) = 1-\alpha \ \ \text{ which is equivalent to } \ \ P\left[c_1 < \frac{(n-1)S^2}{\sigma^2} < c_2\right] = 1-\alpha \]

We can similarly solve for \(\sigma^2\) and obtain the range of \(\sigma^1\) as follows

\[ \frac{(n-1)S^2}{c_2} <\sigma^2 < \frac{(n-1)S^2}{c_1} \]

  • In Figure C (bottom panel), the area of the shaded region satisfies

\[ P(W < U) = 1-\alpha \ \ \text{ which is equivalent to } \ \ P\left[ \frac{(n-1)S^2}{\sigma^2} < U\right] = 1-\alpha \]

Solving inequality for \(\sigma^2\), we have

\[ \frac{(n-1)S^2}{\sigma^2} < U \quad \Rightarrow \quad \sigma^2 > \frac{(n-1)S^2}{U} \ \ \text{ i.e. } \ \ \sigma^2 \in \left( \frac{(n-1)S^2}{L}, \infty \right). \]

The above three scenarios represent two major types confident intervals: one-sided and two-sided confidence intervals:

  • One-sided confidence intervals - bound parameter from above or below. That is, the following two confidence intervals are one-sided.

\[ \sigma^2 \in \left( \frac{(n-1)S^2}{L}, \infty \right) \ \ \text{ and } \ \ \sigma^2 \in \left(0, \frac{(n-1)S^2}{L} \right) \]

  • Two-sided confidence interval - Estimate a parameter’s value within a range. The following is the two-sided confidence interval.

\[ \sigma^2 \in \left(\frac{(n-1)S^2}{c_2}, \frac{(n-1)S^2}{c_1}\right) \]

3 Steps for Constructing CI

Now that we have covered pivotal quantities and their role in constructing confidence intervals, we formalize the step-by-step procedure for using a pivotal quantity to build confidence intervals at a desired confidence level.

Step 1: Identify an Appropriate Pivotal Quantity

Find \(Q(X,\theta)\) whose distribution is known and independent of \(\theta\).

Step 2: Determine the Probability Statement

For confidence level (1-α), find constants a and b such that:

\[ P(a ≤ Q(X, \theta) ≤ b) = 1 - \theta \]

Typically choose \(a\) and \(b\) as quantiles: \(a = F^{-1}(\alpha/2), b = F^{-1}(1-\alpha/2)\))

Step 3: Algebraically Invert the Inequality

Manipulate the inequality \(a ≤ Q(X, \theta) ≤ b\) to isolate \(\theta\):

\[ P(a ≤ Q(X, \theta) ≤ b) = 1 - \alpha \quad \Longleftrightarrow \quad P[L(X) ≤ \theta ≤ U(X)] = 1 - α \]

where L(X) and U(X) are functions of data only.

Step 4: State the Confidence Interval

The \((1-\alpha)\%\) confidence interval for \(\theta\) is: \([L(X), U(X)]\).

Example 1: Normal Distribution with Known Variance

For \(X_i \sim N(\mu, \sigma^2)\) with known \(\sigma^2\), the pivotal quantity is:

\[ Q(X,\mu) = \frac{\bar{X} - \mu}{\sigma/\sqrt{n}} \sim N(0,1) \]

The \((1-\alpha)100\%\) CI for \(\mu\) is:

\[ \bar{X} \pm z_{1-\alpha/2} \frac{\sigma}{\sqrt{n}} \]

where \(z_{1-\alpha/2}\) is the \((1-\alpha/2)\)-quantile of \(N(0,1)\).

R Implementation Example: Pivotal CI for Normal Mean

# Example: Pivotal CI for normal mean (known variance)
set.seed(123)
n <- 30
mu_true <- 5
sigma <- 2
data <- rnorm(n, mu_true, sigma)

alpha <- 0.05
z_critical <- qnorm(1 - alpha/2)
x_bar <- mean(data)
ci_pivotal <- c(
  x_bar - z_critical * sigma/sqrt(n),
  x_bar + z_critical * sigma/sqrt(n)
)

cat("Pivotal 95% CI for \U00B5 (known \U03C3 = 2): [", ci_pivotal, "] \n",
"True \U00B5:", mu_true, "\n",
"Coverage:", ci_pivotal[1] <= mu_true & mu_true <= ci_pivotal[2], "\n")
Pivotal 95% CI for µ (known σ = 2): [ 4.190115 5.62147 ] 
 True µ: 5 
 Coverage: TRUE 


4 Asymptotic Confidence Intervals

In section 2, we introduced a few pivotal quantities based on based on normal distribution. These quantities follow exact distributions such standard normal, t, and \(\chi^2\) distributions that are independent on the unknown parameters \(\mu\) and \(\sigma\) of the normal distribution.

For i.i.d. random variables \(X_1,\ldots,X_n\) with \(E[X_i] = \mu\) and \(Var(X_i) = \sigma^2\), the Central Limit Theorem (CLT) states:

\[ \frac{\bar{X} - \mu}{\sigma/\sqrt{n}} \xrightarrow{d} N(0,1) \]

When \(\sigma^2\) is unknown, use the sample variance \(S^2\):

\[ \frac{\bar{X} - \mu}{S/\sqrt{n}} \xrightarrow{d} N(0,1) \quad \text{for large } n. \]

General Construction

For parameter \(\theta\) with estimator \(\hat{\theta}\):

  • Find asymptotic distribution: \(\hat{\theta} \xrightarrow{d} N(\theta, \widehat{Var}(\hat{\theta}))\)

  • Standardize: \(\frac{\hat{\theta} - \theta}{\sqrt{\widehat{Var}(\hat{\theta})}} \xrightarrow{d} N(0,1)\)

  • Construct CI: \(\hat{\theta} \pm z_{1-\alpha/2} \sqrt{\widehat{Var}(\hat{\theta})}\)

Example Using R: A public health agency wants to estimate the proportion of adults willing to receive a new COVID-19 booster vaccine. They survey n = 1,200 randomly selected adults and find that x = 780 are willing to get vaccinated. What proportion of the entire adult population is willing to receive the booster vaccine?.

Recall that when \(np > 10\) and \(n(1-p) > 10\), by CLT, we have

\[ \frac{\hat{p}-p}{\sqrt{\frac{\hat{p}(1-\hat{p})}{n}}} \xrightarrow{\text{Asymptotically}} N(0, 1) \]

Therefore,

\[ T = \frac{\hat{p}-p}{\sqrt{\frac{\hat{p}(1-\hat{p})}{n}}} \]

is an asymptotic pivotal quantity. \(100(1-\alpha)\%\) two-sided confidence interval of \(p\) satisfies

\[ P\left[ Z_{\alpha/2} <\frac{\hat{p}-p}{\sqrt{\frac{\hat{p}(1-\hat{p})}{n}}} < Z_{1-\alpha/2}\right] = 1 - \alpha \]

Solving \(p\) from the inequality,

\[ Z_{\alpha/2} <\frac{\hat{p}-p}{\sqrt{\frac{\hat{p}(1-\hat{p})}{n}}} < Z_{1-\alpha/2} \]

we have

\[ \hat{p} - Z_{1-\alpha/2}\sqrt{\frac{\hat{p}(1-\hat{p})}{n}} < p < \hat{p} - Z_{\alpha/2}\sqrt{\frac{\hat{p}(1-\hat{p})}{n}} \]

The R code below translates the confidence interval formula presented earlier, using a \(95\%\) confidence level.

# Example: CLT-based CI for binomial proportion
x <- 780
n <- 1200
p_hat = x/n
#
se <- sqrt(p_hat * (1 - p_hat) / n)
#
ci.low <- p_hat - qnorm(1 - 0.025) * se
ci.up <-  p_hat - qnorm(0.025) * se
ci <- c(ci.low, ci.up)
#
cat("CLT-based 95% CIs for proportion:\n",
 "Asymptotic CI: [", ci, "] \n")
CLT-based 95% CIs for proportion:
 Asymptotic CI: [ 0.6230134 0.6769866 ] 


5 Likelihood-Ratio Confidence Intervals

Likelihood-based confidence intervals, often called profile likelihood confidence intervals or likelihood ratio intervals, are a versatile and theoretically well-founded method for constructing confidence intervals for parameters in parametric models. They are based on the likelihood ratio test and often yield more accurate intervals than those based on asymptotic normality, especially for small or moderate sample sizes.

5.1 Likelihood Ratio

Let \(L(\theta; x)\) be the likelihood function for a parameter \(\theta\) given data \(x\) and \(\hat{\theta}_{\text{MLE}}\) be the maximum likelihood estimate of \(\theta\). We define the likelihood ratio function in the following

\[ \Lambda(\theta) = \frac{L(\theta; x)}{L(\hat{\theta}_{MLE}; x)} \]

where the denominator is the likelihood function evaluated at the MLE.

Wilks’ Theorem: Assume that \(\theta\) is the true unknown population parameter If sample size \(n\) is large, we have

\[ LR(\theta)=-2\log\Lambda(\theta) = 2\left[ \log L(\hat{\theta}_{MLE}; x) -\log L(\theta; x)\right]\xrightarrow{d} \chi^2_1 \]

Thus, \(LR(\theta)\) constitutes an asymptotic pivotal quantity with a \(\chi^2_1\) distribution that does not depend on the parameter \(\theta\).

5.2 Likelihood Ratio Confidence Intervals

We can similarly construct one- and two- sided confidence intervals.

Two-Sided Likelihood Ratio CI (Standard Case)

For a parameter \(\theta\) with MLE \(\hat{\theta}\), a two-sided \(100(1-\alpha)%\) likelihood ratio CI consists of all \(\theta_0\) satisfying:

\[ P[LR(\theta) \le \chi^2_{1,\alpha}]= 1 - \alpha \]

We re-expression the inequality in the above probability (left-hand side) as follows

\[ \log L(\hat{\theta}_{MLE}; x) -\log L(\theta; x) \le \chi^2_{1,\alpha}/2 \]

or equivalently

\[ l(\theta) \ge l(\hat{\theta}) - \frac{\chi^2_{1, \alpha}}{2} \]

The confidence limits for \(\theta\), denoted by \(\theta_0\) and \(\theta_1\), are roots of the following nonlinear equations respectively

\[ l(\theta) = l(\hat{\theta}) - \frac{\chi^2_{1, \alpha}}{2}. \]

In summary, we use the following steps for constructing LR confidence intervals:

  • Find the MLE: \(\hat{\theta}\) and compute \(\ell_{\max} = \ell(\hat{\theta})\).

  • Define the profile log-likelihood: for \(\theta\) (if there are nuisance parameters, maximize over them for each fixed \(\theta\)).

  • Solve for the two points: \(l(\theta) = l(\hat{\theta}) - \chi^2_{1, \alpha}/2.\). Let \(\theta_L = \min \{\theta_0, \theta_1 \}\) and \(\theta_U = \max \{\theta_0, \theta_1 \}\). The two-sided CI for \(\theta \in [\theta_L, \theta_U]\).


One-Sided Likelihood Ratio CIs

A \(100(1-\alpha)%\) one-sided CI consists of all \(\theta_0\) such that:

\[ 2[\ell(\hat{\theta}) - \ell(\theta_0)] \leq \chi^2_{1,1-2\alpha} \quad \text{(for $\alpha < 0.5$)} \]

5.3 A Case Study on Exponential Distribution

Let \(X_1, X_2, \dots, X_n\) be i.i.d. \(\text{Exp}(\lambda)\) with PDF:

\[ f(x|\lambda) = \lambda e^{-\lambda x}, \quad x > 0, \ \lambda > 0 \]

The likelihood function is:

\[ L(\lambda) = \lambda^n e^{-\lambda \sum_{i=1}^n x_i} \]

The log-likelihood of the the true \(\lambda\) is:

\[ \ell(\lambda) = n \ln \lambda - \lambda \sum_{i=1}^n x_i = n\ln\lambda -n\lambda \bar{x} \]

Taking derivative with respect to \(\lambda\), we have

\[ \frac{d\ell}{d\lambda} = \frac{n}{\lambda} - n\bar{x} = 0 \]

\[ \hat{\lambda} = \frac{n}{\sum_{i=1}^n x_i} = \frac{1}{\bar{x}}. \]

The maximum log-likelihood:

\[ \ell_{\max} = \ell(\hat{\lambda}) = n \ln \hat{\lambda} - n = n\ln (\bar{x})^{-1} - n = -n[1+\ln (\bar{x})]. \]

The likelihood ratio statistic is:

\[ \lambda_{LR} = 2\left[ \ell(\hat{\lambda}) - \ell(\lambda) \right] = 2\left\{-n[1+\ln (\bar{x})] - n[\ln\lambda -\lambda \bar{x}] \right\} . \]

Since \(\lambda\) is the true exponential parameter (rate), by Wilk’s Theorem,

\[ 2\left\{-n[1+\ln (\bar{x})] - n[\ln\lambda -\lambda \bar{x}] \right\} \xrightarrow{d} \chi^2_{1} \]

Where \(\chi^2_{1, 1-\alpha}\) is the \((1-\alpha)\) quantile of \(\chi^2_1\).

The interval endpoints \(\lambda_0\) and \(\lambda_1\) of \(100(1-\alpha)\%\) CI for \(\theta\) satisfy:

\[ n[\ln\lambda -\lambda \bar{x}] \ge -n[1+\ln (\bar{x})] - \chi^2_{1,\alpha}/2 \]

The above two equations are nonlinear and have no closed form solution, we need to use numerical procedure to find the solution. We will use R built-in function to illustrate the way of finding numerical solution.

Demo of Numerical Procedure: Let \(n = 50\), \(\bar{x} = 1.21\). We want find \(95\%\) CV: \(\chi^2_{1, 0.05} = 3.841459\) (upper tail)so:

\[ 50[\ln\lambda -1.21\lambda] \ge -50[1+\ln (1.21)] - 3.841459/2 \] we use uniroot() to find the root of the above nonlinear equation in the following code

xx <- seq(0,3,length=50)
fun <- function(x) 50*(log(x) - 1.21*x) +50*(1 + log(1.21)) + 3.841459/2
plot(xx, fun(xx), type = "l", lwd = 2, main = "LR Confidence Interval of Exponential Rate",
     xlab = "lambda",
     ylab = "")
abline(h=0, col = "blue")
lambda_0 <- uniroot(fun, interval = c(0.01, 1))$root
lambda_1 <- uniroot(fun, interval = c(1 , 1.5))$root
abline(v=c(lambda_0, lambda_1), col = "red")

 lambda.left lambda.right 
   0.6180284    1.0771560 


6 Applications and Practical Considerations


Goodness of Confidence Interval

A good CI honestly represents uncertainty, uses appropriate methods, and provides information useful for inference and decision-making—not just a ritualistic statistical procedure. Particularly, it should

  • have correct coverage: Should contain the true parameter value in exactly (or approximately) the stated percentage of repeated samples. For example, a 95% CI should contain the true parameter in 95% of studies if repeated infinitely

  • be short (minimum expected length), i.e., as narrow as possible for given confidence level and sample size. Note that that a balanced CI is important: not artificially narrow (underestimating uncertainty) or excessively wide (uninformative)

  • Methodologically Sound: This includes

    • Appropriate assumptions met for the data type
    • Robust to reasonable violations of assumptions
    • Uses correct distribution (t vs. normal, exact vs. approximate methods)
    • Transparent methodology clearly reported
  • Consistent with Data Properties

Choosing the Right Method

Method When to Use Assumptions
Pivotal Exact distribution known Full distributional knowledge
CLT-based Large samples or approx. normal Finite variance, independence
Likelihood General parametric models Correct model specification

Comparison Table

Property Pivotal CLT-based Likelihood
Exactness Exact Asymptotic Asymptotic
Assumptions Strong Moderate Moderate
Computation Simple Simple Iterative
Range May be infinite Finite Can be asymmetric

Important Formulas

  • Pivotal CI:

\[ \theta \in \{\theta: c_1 \le Q(X,\theta) \le c_2\} \]

  • Wald CI:

\[ \hat{\theta} \pm z_{1-\alpha/2} \sqrt{\widehat{Var}(\hat{\theta})} \]

  • Likelihood CI:

\[ \{\theta: -2\log\Lambda(\theta) \le \chi^2_{1,\alpha}\}, \ \ \text{ where } \alpha \text{ is the right-tailed area } \]

  • Coverage:

\[ CP(\theta) = P_\theta(L(X) \le \theta \le U(X)) \]

Practical Recommendations:

  • Use pivotal methods when exact distribution is known

  • Use CLT-based methods for large samples

  • Use likelihood methods for complex parameters

  • Always check assumptions and consider bootstrap alternatives

  • Report both point estimate and confidence interval

LS0tDQp0aXRsZTogIkNvbmNlcHRzIGFuZCBDb25zdHJ1Y3Rpb24gb2YgQ29uZmlkZW5jZSBJbnRlcnZhbHMiDQphdXRob3I6ICJDaGVuZyBQZW5nIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICBoaWdobGlnaHQ6IG1vbm9jaHJvbWUNCiAgICB0aGVtZTogc3BhY2VsYWINCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZml0ZGlzdHJwbHVzIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZml0ZGlzdHJwbHVzIikNCiAgbGlicmFyeShmaXRkaXN0cnBsdXMpDQp9DQojIyANCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQoNClwNCg0KIyBJbnRyb2R1Y3Rpb24NCg0KV2UgaGF2ZSBpbnRyb2R1Y2VkIGRpZmZlcmVudCBtZXRob2RzIGZvciBlc3RpbWF0aW5nIGEgcGFyYW1ldGVyIGJhc2VkIG9uIGEgcmFuZG9tIHNhbXBsZSAtIHBvaW50IGVzdGltYXRvci4gSG93ZXZlciwgQSBwb2ludCBlc3RpbWF0ZSBnaXZlcyBhIHNpbmdsZSBudW1iZXIgd2l0aG91dCBpbmRpY2F0aW5nIGhvdyBwcmVjaXNlIG9yIHJlbGlhYmxlIGl0IGlzLg0KDQpBICoqY29uZmlkZW5jZSBpbnRlcnZhbCAoQ0kpKiogcHJvdmlkZXMgYSByYW5nZSBvZiBwbGF1c2libGUgdmFsdWVzIGZvciBhbiB1bmtub3duIHBhcmFtZXRlciAkXHRoZXRhJCB3aXRoIGEgc3BlY2lmaWVkIGNvbmZpZGVuY2UgbGV2ZWwgJCgxLVxhbHBoYSkxMDBcJSQuIEZvcm1hbGx5LCBmb3IgZGF0YSAkWF8xLFxsZG90cyxYX24kOg0KDQokJA0KUFtMKFgpIFxsZSBcdGhldGEgXGxlIFUoWCldID0gMSAtIFxhbHBoYQ0KJCQNCg0Kd2hlcmUgJEwoWCkkIGFuZCAkVShYKSQgYXJlIHRoZSBsb3dlciBhbmQgdXBwZXIgYm91bmRzIHRoYXQgYXJlICoqZXhwcmVzc2lvbiBvZiBkYXRhIHZhbHVlcyBvbmx5KiouIA0KDQpUaGUga2V5IGxvZ2ljIG9mIGNvbmZpZGVuY2UgaW50ZXJ2YWwgaXMgdGhhdCBpZiB3ZSByZXBlYXRlZCB0aGUgc2FtcGxpbmcgcHJvY2VzcyBpbmZpbml0ZWx5IG1hbnkgdGltZXMgYW5kIGNvbnN0cnVjdGVkIGEgQ0kgZnJvbSBlYWNoIHNhbXBsZSwgYSAkKDEtXGFscGhhKVwlJCBvZiB0aG9zZSBpbnRlcnZhbHMgd291bGQgY29udGFpbiB0aGUgdHJ1ZSBwYXJhbWV0ZXIgdmFsdWUuDQoNCg0KKipHb29kbmVzcyBNZWFzdXJlcyBvZiBDSSoqDQoNCiogKipDb3ZlcmFnZSBwcm9iYWJpbGl0eSoqOiAkUChcdGhldGEgXGluIENJKSA9IDEtXGFscGhhJC4gSXQgYWxzbyBjYWxsZWQgY29uZmlkZW5jZSBsZXZlbC4NCg0KKiAqKldpZHRoKio6ICRVKFgpIC0gTChYKSQgLSBjYWxjdWxhdGUgYmFzZWQgb24gc2FtcGxlIChlc3RpbWF0ZWQgZnJvbSB0aGUgZGF0YSksIGhlbmNlLCBpdCBpcyByYW5kb20uDQoNCiogKipFeHBlY3RlZCBsZW5ndGgqKjogJEVbVShYKSAtIEwoWCldJCAtIEEgdGhlb3JldGljYWwgbGVuZ3RoIHRoYXQgaXMgaW5kZXBlbmRlbnQgb24gdGhlIHJhbmRvbSBzYW1wbGUuDQoNClwNCg0KQSBjb25maWRlbmNlIGludGVydmFsIHRlbGxzIHVzIHdoYXQgdmFsdWVzIG9mIHRoZSBwYXJhbWV0ZXIgYXJlIGNvbXBhdGlibGUgd2l0aCB0aGUgb2JzZXJ2ZWQgZGF0YSBhdCBhIHNwZWNpZmllZCBjb25maWRlbmNlIGxldmVsLCBiYXNlZCBvbiB0aGUgc2FtcGxpbmcgZGlzdHJpYnV0aW9uIG9mIHRoZSBlc3RpbWF0b3IuDQoNCg0KDQojIFBpdm90YWwgUXVhbnRpdHkgYW5kIENvbmZpZGVuY2UgSW50ZXJ2YWwNCg0KKipNYXRoZW1hdGljYWwgRm9ybXVsYXRpb24qKg0KDQpBICoqcGl2b3RhbCBxdWFudGl0eSoqICRRKFgsXHRoZXRhKSQgaXMgYSBmdW5jdGlvbiBvZiBib3RoIGRhdGEgYW5kIHBhcmFtZXRlciB3aG9zZSBkaXN0cmlidXRpb24gKipkb2VzIG5vdCoqIGRlcGVuZCBvbiAkXHRoZXRhJC4NCg0KU29tZSBleGFtcGxlcyB3ZSBsZWFybmVkIGJlZm9yZS4gTGV0ICRce1hfMSwgWF8yLCBcY2RvdHMsIFhfbiBcfSQgYmUgaS5pLmQuIHJhbmRvbSBzYW1wbGUgZnJvbSAkTihcbXUsIFxzaWdtYV4yKSQuIExldCAkXGJhcntYfSQgYmUgdGhlIHNhbXBsZSBtZWFuIGFuZCAkU14yJCBiZSB0aGUgc2FtcGxlIHZhcmlhbmNlLiBUaGUgZm9sbG93aW5nIGFyZSBleHByZXNzaW9ucyBhcmUgcGl2b3RhbCBxdWFudGl0aWVzLg0KDQoNCiQkDQpaKFxtdSkgPSBcZnJhY3tcYmFye1h9LVxtdX17XHNpZ21hXzAvXHNxcnR7bn19LCBcIFwgXCBUKFxtdSkgPSBcZnJhY3tcYmFye1h9LVxtdX17cy9cc3FydHtufX0sIFwgXCBcIFcoXHNpZ21hKSA9IFxmcmFjeyhuLTEpU14yfXtcc2lnbWFeMn0sIFwgXCBcdGV4dHsgZXRjLn0NCiQkDQoNCkNsZWFybHksICRaKFxtdSlceHJpZ2h0YXJyb3d7ZH0gTigwLCAxKSQsICRUKFxtdSkgXHhyaWdodGFycm93e2R9ICB0X3tuLTF9JCwgYW5kICRXKFxzaWdtYSkgXHhyaWdodGFycm93e2R9ICBcY2hpX3tuLTF9XjIkLiBUaGUgbm90YXRpb24gJFx4cmlnaHRhcnJvd3tkfSQgc2ltcGx5IG1lYW5zICoqZm9sbG93cyBpbiBkaXN0cmlidXRpb24qKi4gRnVydGhlcm1vcmUsICROKDAsIDEpLCB0X3tuLTF9JCBhbmQgJFxjaGlfe24tMX1eMiQgYXJlIG5vdCBpbmRlcGVuZGVudCBvbiBwYXJhbWV0ZXJzLiBUaGVyZWZvcmUsICRaKFxtdSksIFQoXG11KSQsIGFuZCAkVyhcc2lnbWEpJCBhcmUgKipwaXZvdGFsIHF1YW50aXRpZXMqKi4NCg0KVG8gZXhwbGFpbiB3aHkgYSBwaXZvdGFsIHF1YW50aXR5IGNhbiBiZSB1c2VkIHRvIGNvbnN0cnVjdCBjb25maWRlbmNlIGludGVydmFsIG9mIGEgcG9wdWxhdGlvbiBwYXJhbWV0ZXIsIHdlIHVzZSB0aGUgdGhpcmQgcGl2b3RhbCBxdWFudGl0eSAkVyhcc2lnbWEpJC4gTGV0ICQxLVxhbHBoYSQgYmUgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgKHNlZSB0aGUgYXJlYSBvZiB0aGUgc2hhZGVkIHJlZ2lvbiBpbiB0aGUgZm9sbG93aW5nIGZpZ3VyZXMpDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBvdXQud2lkdGg9IjYwJSJ9DQppbmNsdWRlX2dyYXBoaWNzKCJwaXZvdGFsUXVhbnQucG5nIikNCmBgYA0KDQoqICoqSW4gRmlndXJlIEEgKHRvcCBwYW5lbCkqKiwgdGhlIGFyZWEgb2YgdGhlIHNoYWRlZCByZWdpb24gc2F0aXNmaWVzDQoNCiQkDQpQKFcgPiBMKSA9IDEtXGFscGhhIFwgXCBcdGV4dHsgd2hpY2ggaXMgZXF1aXZhbGVudCB0byB9IFwgXCBQXGxlZnRbIFxmcmFjeyhuLTEpU14yfXtcc2lnbWFeMn0gPiBMXHJpZ2h0XSA9IDEtXGFscGhhDQokJA0KDQpTb2x2aW5nIGluZXF1YWxpdHkgZm9yICRcc2lnbWFeMiQsIHdlIGhhdmUgDQoNCiQkDQogXGZyYWN7KG4tMSlTXjJ9e1xzaWdtYV4yfSA+IEwgXHF1YWQgXFJpZ2h0YXJyb3cgXHF1YWQgXHNpZ21hXjIgPCBcZnJhY3sobi0xKVNeMn17TH0gXCBcIFx0ZXh0eyBpLmUuIH0gIFwgXCBcc2lnbWFeMiBcaW4gXGxlZnQoMCwgXGZyYWN7KG4tMSlTXjJ9e0x9IFxyaWdodCkuDQokJA0KDQp3aGVyZSAkTCQgaXMgJDEwMFxhbHBoYSQtdGggcXVhbnRpbGUgb25lICRcYWxwaGEkIGlzIGdpdmVuLiBOb3RlIGFsc28gdGhhdCB0aGUgbG93IGxpbWl0IDAgaXMgZHVlIHRoZSBmYWN0IHRoYXQgdmFyaWFuY2UgJFxzaWdtYV4yJCBpcyBncmVhdGVyIHRoYW4gemVyby4NCg0KDQoqICoqSW4gRmlndXJlIEIgKG1pZGRsZSBwYW5lbCkqKiwgdGhlIGFyZWEgb2YgdGhlIHNoYWRlZCByZWdpb24gc2F0aXNmaWVzDQoNCiQkDQpQKGNfMSA8IFcgPCBjXzIpID0gMS1cYWxwaGEgXCBcIFx0ZXh0eyB3aGljaCBpcyBlcXVpdmFsZW50IHRvIH0gXCBcIFBcbGVmdFtjXzEgPCBcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9IDwgY18yXHJpZ2h0XSA9IDEtXGFscGhhDQokJA0KDQpXZSBjYW4gc2ltaWxhcmx5IHNvbHZlIGZvciAkXHNpZ21hXjIkIGFuZCBvYnRhaW4gdGhlIHJhbmdlIG9mICRcc2lnbWFeMSQgYXMgZm9sbG93cw0KDQokJA0KXGZyYWN7KG4tMSlTXjJ9e2NfMn0gPFxzaWdtYV4yIDwgXGZyYWN7KG4tMSlTXjJ9e2NfMX0NCiQkDQoNCg0KKiAqKkluIEZpZ3VyZSBDIChib3R0b20gcGFuZWwpKiosIHRoZSBhcmVhIG9mIHRoZSBzaGFkZWQgcmVnaW9uIHNhdGlzZmllcw0KDQokJA0KUChXIDwgVSkgPSAxLVxhbHBoYSBcIFwgXHRleHR7IHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gfSBcIFwgUFxsZWZ0WyBcZnJhY3sobi0xKVNeMn17XHNpZ21hXjJ9IDwgVVxyaWdodF0gPSAxLVxhbHBoYQ0KJCQNCg0KU29sdmluZyBpbmVxdWFsaXR5IGZvciAkXHNpZ21hXjIkLCB3ZSBoYXZlIA0KDQokJA0KIFxmcmFjeyhuLTEpU14yfXtcc2lnbWFeMn0gPCBVIFxxdWFkIFxSaWdodGFycm93IFxxdWFkIFxzaWdtYV4yID4gXGZyYWN7KG4tMSlTXjJ9e1V9IFwgXCBcdGV4dHsgaS5lLiB9ICBcIFwgXHNpZ21hXjIgXGluIFxsZWZ0KCBcZnJhY3sobi0xKVNeMn17TH0sIFxpbmZ0eSBccmlnaHQpLg0KJCQNCg0KVGhlIGFib3ZlIHRocmVlIHNjZW5hcmlvcyByZXByZXNlbnQgdHdvIG1ham9yIHR5cGVzIGNvbmZpZGVudCBpbnRlcnZhbHM6IG9uZS1zaWRlZCBhbmQgdHdvLXNpZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzOg0KDQoqICoqT25lLXNpZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzKiogLSBib3VuZCBwYXJhbWV0ZXIgZnJvbSBhYm92ZSBvciBiZWxvdy4gVGhhdCBpcywgdGhlIGZvbGxvd2luZyB0d28gY29uZmlkZW5jZSBpbnRlcnZhbHMgYXJlIG9uZS1zaWRlZC4NCg0KJCQNClxzaWdtYV4yIFxpbiBcbGVmdCggXGZyYWN7KG4tMSlTXjJ9e0x9LCBcaW5mdHkgXHJpZ2h0KSBcIFwgXHRleHR7IGFuZCB9IFwgXCBcc2lnbWFeMiBcaW4gXGxlZnQoMCwgXGZyYWN7KG4tMSlTXjJ9e0x9IFxyaWdodCkNCiQkDQoNCiogKipUd28tc2lkZWQgY29uZmlkZW5jZSBpbnRlcnZhbCoqIC0gRXN0aW1hdGUgYSBwYXJhbWV0ZXIncyB2YWx1ZSB3aXRoaW4gYSByYW5nZS4gVGhlIGZvbGxvd2luZyBpcyB0aGUgdHdvLXNpZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWwuDQoNCiQkDQpcc2lnbWFeMiBcaW4gXGxlZnQoXGZyYWN7KG4tMSlTXjJ9e2NfMn0sICBcZnJhY3sobi0xKVNeMn17Y18xfVxyaWdodCkNCiQkDQoNCg0KDQojIFN0ZXBzIGZvciBDb25zdHJ1Y3RpbmcgQ0kNCg0KTm93IHRoYXQgd2UgaGF2ZSBjb3ZlcmVkIHBpdm90YWwgcXVhbnRpdGllcyBhbmQgdGhlaXIgcm9sZSBpbiBjb25zdHJ1Y3RpbmcgY29uZmlkZW5jZSBpbnRlcnZhbHMsIHdlIGZvcm1hbGl6ZSB0aGUgc3RlcC1ieS1zdGVwIHByb2NlZHVyZSBmb3IgdXNpbmcgYSBwaXZvdGFsIHF1YW50aXR5IHRvIGJ1aWxkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGF0IGEgZGVzaXJlZCBjb25maWRlbmNlIGxldmVsLg0KDQoNCioqU3RlcCAxOiBJZGVudGlmeSBhbiBBcHByb3ByaWF0ZSBQaXZvdGFsIFF1YW50aXR5KioNCg0KRmluZCAkUShYLFx0aGV0YSkkIHdob3NlIGRpc3RyaWJ1dGlvbiBpcyBrbm93biBhbmQgaW5kZXBlbmRlbnQgb2YgJFx0aGV0YSQuIA0KDQoNCioqU3RlcCAyOiBEZXRlcm1pbmUgdGhlIFByb2JhYmlsaXR5IFN0YXRlbWVudCoqDQoNCkZvciBjb25maWRlbmNlIGxldmVsICgxLc6xKSwgZmluZCBjb25zdGFudHMgYSBhbmQgYiBzdWNoIHRoYXQ6IA0KDQokJA0KUChhIOKJpCBRKFgsIFx0aGV0YSkg4omkIGIpID0gMSAtIFx0aGV0YQ0KJCQNCg0KVHlwaWNhbGx5IGNob29zZSAkYSQgYW5kICRiJCBhcyAqKnF1YW50aWxlcyoqOiAkYSA9IEZeey0xfShcYWxwaGEvMiksIGIgPSBGXnstMX0oMS1cYWxwaGEvMikkKQ0KDQoNCioqU3RlcCAzOiBBbGdlYnJhaWNhbGx5IEludmVydCB0aGUgSW5lcXVhbGl0eSoqDQoNCk1hbmlwdWxhdGUgdGhlIGluZXF1YWxpdHkgJGEg4omkIFEoWCwgXHRoZXRhKSDiiaQgYiQgdG8gaXNvbGF0ZSAkXHRoZXRhJDogDQoNCiQkDQpQKGEg4omkIFEoWCwgXHRoZXRhKSDiiaQgYikgPSAxIC0gXGFscGhhIFxxdWFkIFxMb25nbGVmdHJpZ2h0YXJyb3cgXHF1YWQNClBbTChYKSDiiaQgXHRoZXRhIOKJpCBVKFgpXSA9IDEgLSDOsQ0KJCQNCg0Kd2hlcmUgTChYKSBhbmQgVShYKSBhcmUgZnVuY3Rpb25zIG9mIGRhdGEgb25seS4NCg0KDQoqKlN0ZXAgNDogU3RhdGUgdGhlIENvbmZpZGVuY2UgSW50ZXJ2YWwqKg0KDQpUaGUgJCgxLVxhbHBoYSlcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgJFx0aGV0YSQgaXM6ICRbTChYKSwgVShYKV0kLg0KDQoNCg0KKipFeGFtcGxlIDEqKjogTm9ybWFsIERpc3RyaWJ1dGlvbiB3aXRoIEtub3duIFZhcmlhbmNlDQoNCkZvciAkWF9pIFxzaW0gTihcbXUsIFxzaWdtYV4yKSQgd2l0aCBrbm93biAkXHNpZ21hXjIkLCB0aGUgcGl2b3RhbCBxdWFudGl0eSBpczoNCg0KJCQNClEoWCxcbXUpID0gXGZyYWN7XGJhcntYfSAtIFxtdX17XHNpZ21hL1xzcXJ0e259fSBcc2ltIE4oMCwxKQ0KJCQNCg0KVGhlICQoMS1cYWxwaGEpMTAwXCUkIENJIGZvciAkXG11JCBpczoNCg0KJCQNClxiYXJ7WH0gXHBtIHpfezEtXGFscGhhLzJ9IFxmcmFje1xzaWdtYX17XHNxcnR7bn19DQokJA0KDQp3aGVyZSAkel97MS1cYWxwaGEvMn0kIGlzIHRoZSAkKDEtXGFscGhhLzIpJC1xdWFudGlsZSBvZiAkTigwLDEpJC4NCg0KDQoqKlIgSW1wbGVtZW50YXRpb24gRXhhbXBsZSoqOiBQaXZvdGFsIENJIGZvciBOb3JtYWwgTWVhbg0KDQpgYGB7cn0NCiMgRXhhbXBsZTogUGl2b3RhbCBDSSBmb3Igbm9ybWFsIG1lYW4gKGtub3duIHZhcmlhbmNlKQ0Kc2V0LnNlZWQoMTIzKQ0KbiA8LSAzMA0KbXVfdHJ1ZSA8LSA1DQpzaWdtYSA8LSAyDQpkYXRhIDwtIHJub3JtKG4sIG11X3RydWUsIHNpZ21hKQ0KDQphbHBoYSA8LSAwLjA1DQp6X2NyaXRpY2FsIDwtIHFub3JtKDEgLSBhbHBoYS8yKQ0KeF9iYXIgPC0gbWVhbihkYXRhKQ0KY2lfcGl2b3RhbCA8LSBjKA0KICB4X2JhciAtIHpfY3JpdGljYWwgKiBzaWdtYS9zcXJ0KG4pLA0KICB4X2JhciArIHpfY3JpdGljYWwgKiBzaWdtYS9zcXJ0KG4pDQopDQoNCmNhdCgiUGl2b3RhbCA5NSUgQ0kgZm9yIFxVMDBCNSAoa25vd24gXFUwM0MzID0gMik6IFsiLCBjaV9waXZvdGFsLCAiXSBcbiIsDQoiVHJ1ZSBcVTAwQjU6IiwgbXVfdHJ1ZSwgIlxuIiwNCiJDb3ZlcmFnZToiLCBjaV9waXZvdGFsWzFdIDw9IG11X3RydWUgJiBtdV90cnVlIDw9IGNpX3Bpdm90YWxbMl0sICJcbiIpDQpgYGANCg0KDQpcDQoNCg0KIyBBc3ltcHRvdGljIENvbmZpZGVuY2UgSW50ZXJ2YWxzDQoNCkluIHNlY3Rpb24gMiwgd2UgaW50cm9kdWNlZCBhIGZldyBwaXZvdGFsIHF1YW50aXRpZXMgYmFzZWQgb24gYmFzZWQgb24gbm9ybWFsIGRpc3RyaWJ1dGlvbi4gVGhlc2UgcXVhbnRpdGllcyBmb2xsb3cgZXhhY3QgZGlzdHJpYnV0aW9ucyBzdWNoIHN0YW5kYXJkIG5vcm1hbCwgdCwgYW5kICRcY2hpXjIkIGRpc3RyaWJ1dGlvbnMgdGhhdCBhcmUgaW5kZXBlbmRlbnQgb24gdGhlIHVua25vd24gcGFyYW1ldGVycyAkXG11JCBhbmQgJFxzaWdtYSQgb2YgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24uDQoNCg0KRm9yIGkuaS5kLiByYW5kb20gdmFyaWFibGVzICRYXzEsXGxkb3RzLFhfbiQgd2l0aCAkRVtYX2ldID0gXG11JCBhbmQgJFZhcihYX2kpID0gXHNpZ21hXjIkLCB0aGUgKipDZW50cmFsIExpbWl0IFRoZW9yZW0gKENMVCkqKiBzdGF0ZXM6DQoNCiQkDQpcZnJhY3tcYmFye1h9IC0gXG11fXtcc2lnbWEvXHNxcnR7bn19IFx4cmlnaHRhcnJvd3tkfSBOKDAsMSkNCiQkDQoNCg0KDQpXaGVuICRcc2lnbWFeMiQgaXMgdW5rbm93biwgdXNlIHRoZSBzYW1wbGUgdmFyaWFuY2UgJFNeMiQ6DQoNCiQkDQpcZnJhY3tcYmFye1h9IC0gXG11fXtTL1xzcXJ0e259fSBceHJpZ2h0YXJyb3d7ZH0gTigwLDEpIFxxdWFkIFx0ZXh0e2ZvciBsYXJnZSB9IG4uDQokJA0KDQoNCioqR2VuZXJhbCBDb25zdHJ1Y3Rpb24qKg0KDQpGb3IgcGFyYW1ldGVyICRcdGhldGEkIHdpdGggZXN0aW1hdG9yICRcaGF0e1x0aGV0YX0kOg0KDQoqIEZpbmQgYXN5bXB0b3RpYyBkaXN0cmlidXRpb246ICRcaGF0e1x0aGV0YX0gXHhyaWdodGFycm93e2R9IE4oXHRoZXRhLCBcd2lkZWhhdHtWYXJ9KFxoYXR7XHRoZXRhfSkpJA0KDQoqIFN0YW5kYXJkaXplOiAkXGZyYWN7XGhhdHtcdGhldGF9IC0gXHRoZXRhfXtcc3FydHtcd2lkZWhhdHtWYXJ9KFxoYXR7XHRoZXRhfSl9fSBceHJpZ2h0YXJyb3d7ZH0gTigwLDEpJA0KDQoqIENvbnN0cnVjdCBDSTogJFxoYXR7XHRoZXRhfSBccG0gel97MS1cYWxwaGEvMn0gXHNxcnR7XHdpZGVoYXR7VmFyfShcaGF0e1x0aGV0YX0pfSQNCiANCg0KKipFeGFtcGxlIFVzaW5nIFIqKjogQSBwdWJsaWMgaGVhbHRoIGFnZW5jeSB3YW50cyB0byBlc3RpbWF0ZSB0aGUgcHJvcG9ydGlvbiBvZiBhZHVsdHMgd2lsbGluZyB0byByZWNlaXZlIGEgbmV3IENPVklELTE5IGJvb3N0ZXIgdmFjY2luZS4gVGhleSBzdXJ2ZXkgbiA9IDEsMjAwIHJhbmRvbWx5IHNlbGVjdGVkIGFkdWx0cyBhbmQgZmluZCB0aGF0IHggPSA3ODAgYXJlIHdpbGxpbmcgdG8gZ2V0IHZhY2NpbmF0ZWQuIFdoYXQgcHJvcG9ydGlvbiBvZiB0aGUgZW50aXJlIGFkdWx0IHBvcHVsYXRpb24gaXMgd2lsbGluZyB0byByZWNlaXZlIHRoZSBib29zdGVyIHZhY2NpbmU/LiANCg0KUmVjYWxsIHRoYXQgd2hlbiAkbnAgPiAxMCQgYW5kICRuKDEtcCkgPiAxMCQsIGJ5IENMVCwgd2UgaGF2ZQ0KDQokJA0KXGZyYWN7XGhhdHtwfS1wfXtcc3FydHtcZnJhY3tcaGF0e3B9KDEtXGhhdHtwfSl9e259fX0gXHhyaWdodGFycm93e1x0ZXh0e0FzeW1wdG90aWNhbGx5fX0gTigwLCAxKQ0KJCQNCg0KVGhlcmVmb3JlLA0KDQokJA0KVCA9IFxmcmFje1xoYXR7cH0tcH17XHNxcnR7XGZyYWN7XGhhdHtwfSgxLVxoYXR7cH0pfXtufX19DQokJA0KDQppcyBhbiBhc3ltcHRvdGljIHBpdm90YWwgcXVhbnRpdHkuICQxMDAoMS1cYWxwaGEpXCUkIHR3by1zaWRlZCBjb25maWRlbmNlIGludGVydmFsIG9mICRwJCBzYXRpc2ZpZXMNCg0KJCQNClBcbGVmdFsgWl97XGFscGhhLzJ9IDxcZnJhY3tcaGF0e3B9LXB9e1xzcXJ0e1xmcmFje1xoYXR7cH0oMS1caGF0e3B9KX17bn19fSA8IFpfezEtXGFscGhhLzJ9XHJpZ2h0XSA9IDEgLSBcYWxwaGENCiQkDQoNClNvbHZpbmcgJHAkIGZyb20gdGhlIGluZXF1YWxpdHksDQoNCiQkDQpaX3tcYWxwaGEvMn0gPFxmcmFje1xoYXR7cH0tcH17XHNxcnR7XGZyYWN7XGhhdHtwfSgxLVxoYXR7cH0pfXtufX19IDwgWl97MS1cYWxwaGEvMn0NCiQkDQoNCndlIGhhdmUNCg0KJCQNClxoYXR7cH0gLSBaX3sxLVxhbHBoYS8yfVxzcXJ0e1xmcmFje1xoYXR7cH0oMS1caGF0e3B9KX17bn19IDwgcCA8IFxoYXR7cH0gLSBaX3tcYWxwaGEvMn1cc3FydHtcZnJhY3tcaGF0e3B9KDEtXGhhdHtwfSl9e259fQ0KJCQNCg0KVGhlIFIgY29kZSBiZWxvdyB0cmFuc2xhdGVzIHRoZSBjb25maWRlbmNlIGludGVydmFsIGZvcm11bGEgcHJlc2VudGVkIGVhcmxpZXIsIHVzaW5nIGEgJDk1XCUkIGNvbmZpZGVuY2UgbGV2ZWwuDQoNCg0KYGBge3J9DQojIEV4YW1wbGU6IENMVC1iYXNlZCBDSSBmb3IgYmlub21pYWwgcHJvcG9ydGlvbg0KeCA8LSA3ODANCm4gPC0gMTIwMA0KcF9oYXQgPSB4L24NCiMNCnNlIDwtIHNxcnQocF9oYXQgKiAoMSAtIHBfaGF0KSAvIG4pDQojDQpjaS5sb3cgPC0gcF9oYXQgLSBxbm9ybSgxIC0gMC4wMjUpICogc2UNCmNpLnVwIDwtICBwX2hhdCAtIHFub3JtKDAuMDI1KSAqIHNlDQpjaSA8LSBjKGNpLmxvdywgY2kudXApDQojDQpjYXQoIkNMVC1iYXNlZCA5NSUgQ0lzIGZvciBwcm9wb3J0aW9uOlxuIiwNCiAiQXN5bXB0b3RpYyBDSTogWyIsIGNpLCAiXSBcbiIpDQpgYGANCg0KXA0KDQojIExpa2VsaWhvb2QtUmF0aW8gQ29uZmlkZW5jZSBJbnRlcnZhbHMNCg0KKipMaWtlbGlob29kLWJhc2VkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzKiosIG9mdGVuIGNhbGxlZCAqKnByb2ZpbGUgbGlrZWxpaG9vZCBjb25maWRlbmNlIGludGVydmFscyoqIG9yICoqbGlrZWxpaG9vZCByYXRpbyBpbnRlcnZhbHMqKiwgYXJlIGEgdmVyc2F0aWxlIGFuZCB0aGVvcmV0aWNhbGx5IHdlbGwtZm91bmRlZCBtZXRob2QgZm9yIGNvbnN0cnVjdGluZyBjb25maWRlbmNlIGludGVydmFscyBmb3IgcGFyYW1ldGVycyBpbiBwYXJhbWV0cmljIG1vZGVscy4gVGhleSBhcmUgYmFzZWQgb24gdGhlIGxpa2VsaWhvb2QgcmF0aW8gdGVzdCBhbmQgb2Z0ZW4geWllbGQgbW9yZSBhY2N1cmF0ZSBpbnRlcnZhbHMgdGhhbiB0aG9zZSBiYXNlZCBvbiAqKmFzeW1wdG90aWMgbm9ybWFsaXR5KiosIGVzcGVjaWFsbHkgZm9yICoqc21hbGwqKiBvciAqKm1vZGVyYXRlKiogc2FtcGxlIHNpemVzLg0KDQojIyBMaWtlbGlob29kIFJhdGlvDQoNCkxldCAkTChcdGhldGE7IHgpJCBiZSB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiBmb3IgYSBwYXJhbWV0ZXIgJFx0aGV0YSQgZ2l2ZW4gZGF0YSAkeCQgYW5kICRcaGF0e1x0aGV0YX1fe1x0ZXh0e01MRX19JCBiZSB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRlIG9mICRcdGhldGEkLiBXZSBkZWZpbmUgdGhlICoqbGlrZWxpaG9vZCByYXRpbyBmdW5jdGlvbioqIGluIHRoZSBmb2xsb3dpbmcNCg0KJCQNClxMYW1iZGEoXHRoZXRhKSA9IFxmcmFje0woXHRoZXRhOyB4KX17TChcaGF0e1x0aGV0YX1fe01MRX07IHgpfQ0KJCQNCg0Kd2hlcmUgdGhlIGRlbm9taW5hdG9yIGlzIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uIGV2YWx1YXRlZCBhdCB0aGUgTUxFLiAgDQoNCioqV2lsa3MnIFRoZW9yZW0qKjogQXNzdW1lIHRoYXQgJFx0aGV0YSQgaXMgdGhlIHRydWUgdW5rbm93biBwb3B1bGF0aW9uIHBhcmFtZXRlciBJZiBzYW1wbGUgc2l6ZSAkbiQgaXMgbGFyZ2UsIHdlIGhhdmUgIA0KDQokJA0KTFIoXHRoZXRhKT0tMlxsb2dcTGFtYmRhKFx0aGV0YSkgPSAyXGxlZnRbIFxsb2cgTChcaGF0e1x0aGV0YX1fe01MRX07IHgpIC1cbG9nIEwoXHRoZXRhOyB4KVxyaWdodF1ceHJpZ2h0YXJyb3d7ZH0gXGNoaV4yXzENCiQkDQoNCj4gPGZvbnQgY29sb3IgPSAiZGFya3JlZCI+VGh1cywgJExSKFx0aGV0YSkkIGNvbnN0aXR1dGVzIGFuICoqYXN5bXB0b3RpYyBwaXZvdGFsIHF1YW50aXR5Kiogd2l0aCBhICRcY2hpXjJfMSQgZGlzdHJpYnV0aW9uIHRoYXQgZG9lcyBub3QgZGVwZW5kIG9uIHRoZSBwYXJhbWV0ZXIgJFx0aGV0YSQuPC9mb250Pg0KDQoNCiMjIExpa2VsaWhvb2QgUmF0aW8gQ29uZmlkZW5jZSBJbnRlcnZhbHMNCg0KDQpXZSBjYW4gc2ltaWxhcmx5IGNvbnN0cnVjdCBvbmUtIGFuZCB0d28tIHNpZGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzLg0KDQoqKlR3by1TaWRlZCBMaWtlbGlob29kIFJhdGlvIENJIChTdGFuZGFyZCBDYXNlKSoqDQoNCkZvciBhIHBhcmFtZXRlciAkXHRoZXRhJCB3aXRoIE1MRSAkXGhhdHtcdGhldGF9JCwgYSB0d28tc2lkZWQgJDEwMCgxLVxhbHBoYSklJCBsaWtlbGlob29kIHJhdGlvIENJIGNvbnNpc3RzIG9mIGFsbCAkXHRoZXRhXzAkIHNhdGlzZnlpbmc6DQoNCiQkDQpQW0xSKFx0aGV0YSkgXGxlIFxjaGleMl97MSxcYWxwaGF9XT0gMSAtIFxhbHBoYQ0KJCQNCg0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgb3V0LndpZHRoPSI2MCUifQ0KaW5jbHVkZV9ncmFwaGljcygiY2hpc3EtZGVuc2l0eS1jdXJ2ZS5wbmciKQ0KYGBgDQoNCldlIHJlLWV4cHJlc3Npb24gdGhlIGluZXF1YWxpdHkgaW4gdGhlIGFib3ZlIHByb2JhYmlsaXR5IChsZWZ0LWhhbmQgc2lkZSkgYXMgZm9sbG93cw0KDQokJA0KXGxvZyBMKFxoYXR7XHRoZXRhfV97TUxFfTsgeCkgLVxsb2cgTChcdGhldGE7IHgpIFxsZSBcY2hpXjJfezEsXGFscGhhfS8yDQokJA0KDQpvciBlcXVpdmFsZW50bHkNCg0KJCQNCmwoXHRoZXRhKSBcZ2UgbChcaGF0e1x0aGV0YX0pIC0gXGZyYWN7XGNoaV4yX3sxLCBcYWxwaGF9fXsyfQ0KJCQNCg0KYGBge3IgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIG91dC53aWR0aD0iNjAlIn0NCmluY2x1ZGVfZ3JhcGhpY3MoIkxSLUNJLURlbW8ucG5nIikNCmBgYA0KDQoNClRoZSBjb25maWRlbmNlIGxpbWl0cyBmb3IgJFx0aGV0YSQsIGRlbm90ZWQgYnkgJFx0aGV0YV8wJCBhbmQgJFx0aGV0YV8xJCwgYXJlIHJvb3RzIG9mIHRoZSBmb2xsb3dpbmcgbm9ubGluZWFyIGVxdWF0aW9ucyByZXNwZWN0aXZlbHkNCg0KJCQNCmwoXHRoZXRhKSAgPSBsKFxoYXR7XHRoZXRhfSkgLSBcZnJhY3tcY2hpXjJfezEsIFxhbHBoYX19ezJ9Lg0KJCQNClwNCg0KSW4gc3VtbWFyeSwgd2UgdXNlIHRoZSBmb2xsb3dpbmcgc3RlcHMgZm9yIGNvbnN0cnVjdGluZyBMUiBjb25maWRlbmNlIGludGVydmFsczoNCg0KKiAqKkZpbmQgdGhlIE1MRSoqOiAkXGhhdHtcdGhldGF9JCBhbmQgY29tcHV0ZSAkXGVsbF97XG1heH0gPSBcZWxsKFxoYXR7XHRoZXRhfSkkLg0KICAgIA0KKiAqKkRlZmluZSB0aGUgcHJvZmlsZSBsb2ctbGlrZWxpaG9vZCoqOiBmb3IgJFx0aGV0YSQgKGlmIHRoZXJlIGFyZSBudWlzYW5jZSBwYXJhbWV0ZXJzLCBtYXhpbWl6ZSBvdmVyIHRoZW0gZm9yIGVhY2ggZml4ZWQgJFx0aGV0YSQpLg0KICAgIA0KKiAqKlNvbHZlIGZvciB0aGUgdHdvIHBvaW50cyoqOiAkbChcdGhldGEpICA9IGwoXGhhdHtcdGhldGF9KSAtIFxjaGleMl97MSwgXGFscGhhfS8yLiQuIExldCAkXHRoZXRhX0wgPSBcbWluIFx7XHRoZXRhXzAsIFx0aGV0YV8xIFx9JCBhbmQgJFx0aGV0YV9VID0gXG1heCBce1x0aGV0YV8wLCBcdGhldGFfMSBcfSQuIFRoZSB0d28tc2lkZWQgQ0kgZm9yICRcdGhldGEgXGluIFtcdGhldGFfTCwgIFx0aGV0YV9VXSQuDQoNClwNCg0KKipPbmUtU2lkZWQgTGlrZWxpaG9vZCBSYXRpbyBDSXMqKg0KDQpBICQxMDAoMS1cYWxwaGEpJSQgb25lLXNpZGVkIENJIGNvbnNpc3RzIG9mIGFsbCAkXHRoZXRhXzAkIHN1Y2ggdGhhdDoNCg0KDQokJA0KMltcZWxsKFxoYXR7XHRoZXRhfSkgLSBcZWxsKFx0aGV0YV8wKV0gXGxlcSBcY2hpXjJfezEsMS0yXGFscGhhfSBccXVhZCBcdGV4dHsoZm9yICRcYWxwaGEgPCAwLjUkKX0NCiQkDQoNCg0KDQojIyBBIENhc2UgU3R1ZHkgb24gRXhwb25lbnRpYWwgRGlzdHJpYnV0aW9uDQoNCkxldCAkWF8xLCBYXzIsIFxkb3RzLCBYX24kIGJlIGkuaS5kLiAkXHRleHR7RXhwfShcbGFtYmRhKSQgd2l0aCBQREY6DQoNCiQkDQpmKHh8XGxhbWJkYSkgPSBcbGFtYmRhIGVeey1cbGFtYmRhIHh9LCBccXVhZCB4ID4gMCwgXCBcbGFtYmRhID4gMA0KJCQNCg0KVGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gaXM6DQoNCiQkDQpMKFxsYW1iZGEpID0gXGxhbWJkYV5uIGVeey1cbGFtYmRhIFxzdW1fe2k9MX1ebiB4X2l9DQokJA0KDQpUaGUgbG9nLWxpa2VsaWhvb2Qgb2YgdGhlIHRoZSB0cnVlICRcbGFtYmRhJCBpczoNCg0KJCQNClxlbGwoXGxhbWJkYSkgPSBuIFxsbiBcbGFtYmRhIC0gXGxhbWJkYSBcc3VtX3tpPTF9Xm4geF9pID0gblxsblxsYW1iZGEgLW5cbGFtYmRhIFxiYXJ7eH0NCiQkDQoNClRha2luZyBkZXJpdmF0aXZlIHdpdGggcmVzcGVjdCB0byAkXGxhbWJkYSQsIHdlIGhhdmUNCg0KJCQNClxmcmFje2RcZWxsfXtkXGxhbWJkYX0gPSBcZnJhY3tufXtcbGFtYmRhfSAtIG5cYmFye3h9ID0gMA0KJCQNCg0KJCQNClxoYXR7XGxhbWJkYX0gPSBcZnJhY3tufXtcc3VtX3tpPTF9Xm4geF9pfSA9IFxmcmFjezF9e1xiYXJ7eH19Lg0KJCQNCg0KVGhlIG1heGltdW0gbG9nLWxpa2VsaWhvb2Q6DQoNCiQkDQpcZWxsX3tcbWF4fSA9IFxlbGwoXGhhdHtcbGFtYmRhfSkgPSBuIFxsbiBcaGF0e1xsYW1iZGF9IC0gbiA9IG5cbG4gKFxiYXJ7eH0pXnstMX0gLSBuID0gLW5bMStcbG4gKFxiYXJ7eH0pXS4NCiQkDQoNCg0KVGhlIGxpa2VsaWhvb2QgcmF0aW8gc3RhdGlzdGljIGlzOg0KDQokJA0KXGxhbWJkYV97TFJ9ID0gMlxsZWZ0WyBcZWxsKFxoYXR7XGxhbWJkYX0pIC0gXGVsbChcbGFtYmRhKSBccmlnaHRdID0gMlxsZWZ0XHstblsxK1xsbiAoXGJhcnt4fSldIC0gbltcbG5cbGFtYmRhIC1cbGFtYmRhIFxiYXJ7eH1dIFxyaWdodFx9IC4NCiQkDQoNClNpbmNlICRcbGFtYmRhJCBpcyB0aGUgdHJ1ZSBleHBvbmVudGlhbCBwYXJhbWV0ZXIgKHJhdGUpLCBieSAqKldpbGsncyBUaGVvcmVtKiosDQoNCiQkDQoyXGxlZnRcey1uWzErXGxuIChcYmFye3h9KV0gLSBuW1xsblxsYW1iZGEgLVxsYW1iZGEgXGJhcnt4fV0gXHJpZ2h0XH0gXHhyaWdodGFycm93e2R9IFxjaGleMl97MX0NCiQkDQoNCldoZXJlICRcY2hpXjJfezEsIDEtXGFscGhhfSQgaXMgdGhlICQoMS1cYWxwaGEpJCBxdWFudGlsZSBvZiAkXGNoaV4yXzEkLg0KDQpUaGUgaW50ZXJ2YWwgZW5kcG9pbnRzICRcbGFtYmRhXzAkIGFuZCAkXGxhbWJkYV8xJCBvZiAkMTAwKDEtXGFscGhhKVwlJCBDSSBmb3IgJFx0aGV0YSQgc2F0aXNmeToNCg0KJCQNCm5bXGxuXGxhbWJkYSAtXGxhbWJkYSBcYmFye3h9XSBcZ2UgLW5bMStcbG4gKFxiYXJ7eH0pXSAtIFxjaGleMl97MSxcYWxwaGF9LzINCiQkDQoNClRoZSBhYm92ZSB0d28gZXF1YXRpb25zIGFyZSBub25saW5lYXIgYW5kIGhhdmUgbm8gY2xvc2VkIGZvcm0gc29sdXRpb24sIHdlIG5lZWQgdG8gdXNlIG51bWVyaWNhbCBwcm9jZWR1cmUgdG8gZmluZCB0aGUgc29sdXRpb24uIFdlIHdpbGwgdXNlIFIgYnVpbHQtaW4gZnVuY3Rpb24gdG8gaWxsdXN0cmF0ZSB0aGUgd2F5IG9mIGZpbmRpbmcgbnVtZXJpY2FsIHNvbHV0aW9uLg0KDQoqKkRlbW8gb2YgTnVtZXJpY2FsIFByb2NlZHVyZSoqOiBMZXQgJG4gPSA1MCQsICRcYmFye3h9ID0gMS4yMSQuIFdlIHdhbnQgZmluZCAkOTVcJSQgQ1Y6ICRcY2hpXjJfezEsIDAuMDV9ID0gMy44NDE0NTkkICh1cHBlciB0YWlsKXNvOg0KDQokJA0KNTBbXGxuXGxhbWJkYSAtMS4yMVxsYW1iZGFdIFxnZSAtNTBbMStcbG4gKDEuMjEpXSAtIDMuODQxNDU5LzINCiQkDQp3ZSB1c2UgYHVuaXJvb3QoKWAgdG8gZmluZCB0aGUgcm9vdCBvZiB0aGUgYWJvdmUgbm9ubGluZWFyIGVxdWF0aW9uIGluIHRoZSBmb2xsb3dpbmcgY29kZQ0KDQoNCmBgYHtyfQ0KeHggPC0gc2VxKDAsMyxsZW5ndGg9NTApDQpmdW4gPC0gZnVuY3Rpb24oeCkgNTAqKGxvZyh4KSAtIDEuMjEqeCkgKzUwKigxICsgbG9nKDEuMjEpKSArIDMuODQxNDU5LzINCnBsb3QoeHgsIGZ1bih4eCksIHR5cGUgPSAibCIsIGx3ZCA9IDIsIG1haW4gPSAiTFIgQ29uZmlkZW5jZSBJbnRlcnZhbCBvZiBFeHBvbmVudGlhbCBSYXRlIiwNCiAgICAgeGxhYiA9ICJsYW1iZGEiLA0KICAgICB5bGFiID0gIiIpDQphYmxpbmUoaD0wLCBjb2wgPSAiYmx1ZSIpDQpsYW1iZGFfMCA8LSB1bmlyb290KGZ1biwgaW50ZXJ2YWwgPSBjKDAuMDEsIDEpKSRyb290DQpsYW1iZGFfMSA8LSB1bmlyb290KGZ1biwgaW50ZXJ2YWwgPSBjKDEgLCAxLjUpKSRyb290DQphYmxpbmUodj1jKGxhbWJkYV8wLCBsYW1iZGFfMSksIGNvbCA9ICJyZWQiKQ0KYGBgDQoNCmBgYHtyIGVjaG8gPSBGQUxTRX0NCmMobGFtYmRhLmxlZnQgPSBsYW1iZGFfMCwgbGFtYmRhLnJpZ2h0ID0gbGFtYmRhXzEpDQpgYGANCg0KDQpcDQoNCiMgQXBwbGljYXRpb25zIGFuZCBQcmFjdGljYWwgQ29uc2lkZXJhdGlvbnMNCiANClwNCiANCjxmb250IGNvbG9yID0gImJsdWUiPioqR29vZG5lc3Mgb2YgQ29uZmlkZW5jZSBJbnRlcnZhbCoqPC9mb250Pg0KDQpBIGdvb2QgQ0kgaG9uZXN0bHkgcmVwcmVzZW50cyB1bmNlcnRhaW50eSwgdXNlcyBhcHByb3ByaWF0ZSBtZXRob2RzLCBhbmQgcHJvdmlkZXMgaW5mb3JtYXRpb24gdXNlZnVsIGZvciBpbmZlcmVuY2UgYW5kIGRlY2lzaW9uLW1ha2luZ+KAlG5vdCBqdXN0IGEgcml0dWFsaXN0aWMgc3RhdGlzdGljYWwgcHJvY2VkdXJlLiBQYXJ0aWN1bGFybHksIGl0IHNob3VsZA0KDQoqICoqaGF2ZSBjb3JyZWN0IGNvdmVyYWdlKio6IFNob3VsZCBjb250YWluIHRoZSB0cnVlIHBhcmFtZXRlciB2YWx1ZSBpbiBleGFjdGx5IChvciBhcHByb3hpbWF0ZWx5KSB0aGUgc3RhdGVkIHBlcmNlbnRhZ2Ugb2YgcmVwZWF0ZWQgc2FtcGxlcy4gRm9yIGV4YW1wbGUsIGEgOTUlIENJIHNob3VsZCBjb250YWluIHRoZSB0cnVlIHBhcmFtZXRlciBpbiA5NSUgb2Ygc3R1ZGllcyBpZiByZXBlYXRlZCBpbmZpbml0ZWx5DQoNCiogKipiZSBzaG9ydCAobWluaW11bSBleHBlY3RlZCBsZW5ndGgpKiosIGkuZS4sIGFzIG5hcnJvdyBhcyBwb3NzaWJsZSBmb3IgZ2l2ZW4gY29uZmlkZW5jZSBsZXZlbCBhbmQgc2FtcGxlIHNpemUuIE5vdGUgdGhhdCB0aGF0IGEgKipiYWxhbmNlZCoqIENJIGlzIGltcG9ydGFudDogbm90IGFydGlmaWNpYWxseSBuYXJyb3cgKHVuZGVyZXN0aW1hdGluZyB1bmNlcnRhaW50eSkgb3IgZXhjZXNzaXZlbHkgd2lkZSAodW5pbmZvcm1hdGl2ZSkNCg0KKiAqKk1ldGhvZG9sb2dpY2FsbHkgU291bmQqKjogVGhpcyBpbmNsdWRlcw0KICArICoqQXBwcm9wcmlhdGUgYXNzdW1wdGlvbnMgbWV0KiogZm9yIHRoZSBkYXRhIHR5cGUNCiAgKyAqKlJvYnVzdCoqIHRvIHJlYXNvbmFibGUgdmlvbGF0aW9ucyBvZiBhc3N1bXB0aW9ucw0KICArIFVzZXMgKipjb3JyZWN0IGRpc3RyaWJ1dGlvbioqICh0IHZzLiBub3JtYWwsIGV4YWN0IHZzLiBhcHByb3hpbWF0ZSBtZXRob2RzKQ0KICArICoqVHJhbnNwYXJlbnQgbWV0aG9kb2xvZ3kqKiBjbGVhcmx5IHJlcG9ydGVkDQoNCiogKipDb25zaXN0ZW50IHdpdGggRGF0YSBQcm9wZXJ0aWVzKioNCg0KDQo8Zm9udCBjb2xvciA9ICJibHVlIj4qKkNob29zaW5nIHRoZSBSaWdodCBNZXRob2QqKjwvZm9udD4NCg0KDQp8ICoqTWV0aG9kKiogfCAgKipXaGVuIHRvIFVzZSoqIHwgKipBc3N1bXB0aW9ucyoqIHwNCnw6LS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS18DQp8IFBpdm90YWwgfCAgRXhhY3QgZGlzdHJpYnV0aW9uIGtub3duIHwgIEZ1bGwgZGlzdHJpYnV0aW9uYWwga25vd2xlZGdlIHwgDQp8IENMVC1iYXNlZCB8ICBMYXJnZSBzYW1wbGVzIG9yIGFwcHJveC4gbm9ybWFsIHwgIEZpbml0ZSB2YXJpYW5jZSwgaW5kZXBlbmRlbmNlIHwgDQp8IExpa2VsaWhvb2QgfCAgR2VuZXJhbCBwYXJhbWV0cmljIG1vZGVscyB8ICBDb3JyZWN0IG1vZGVsIHNwZWNpZmljYXRpb24gfCANCg0KDQoNCg0KPGZvbnQgY29sb3IgPSAiYmx1ZSI+KipDb21wYXJpc29uIFRhYmxlKio8L2ZvbnQ+DQoNCg0KfCAqKlByb3BlcnR5KiogfCAqKlBpdm90YWwqKiB8ICoqQ0xULWJhc2VkKiogfCAqKkxpa2VsaWhvb2QqKnwNCnw6LS0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS0tLS0tfA0KfCBFeGFjdG5lc3MgfCAgRXhhY3QgfCAgQXN5bXB0b3RpYyB8ICBBc3ltcHRvdGljIHwgDQp8IEFzc3VtcHRpb25zIHwgIFN0cm9uZyB8ICBNb2RlcmF0ZSB8ICBNb2RlcmF0ZSB8IA0KfCBDb21wdXRhdGlvbiB8ICBTaW1wbGUgfCAgU2ltcGxlIHwgIEl0ZXJhdGl2ZSB8IA0KfCBSYW5nZSB8ICBNYXkgYmUgaW5maW5pdGUgfCAgRmluaXRlIHwgIENhbiBiZSBhc3ltbWV0cmljIHwgDQoNCg0KDQo8Zm9udCBjb2xvciA9ICJibHVlIj4qKkltcG9ydGFudCBGb3JtdWxhcyoqPC9mb250Pg0KDQoNCiogKipQaXZvdGFsIENJKio6DQoNCiQkDQpcdGhldGEgXGluIFx7XHRoZXRhOiBjXzEgXGxlIFEoWCxcdGhldGEpIFxsZSBjXzJcfQ0KJCQNCiAgICANCiogKipXYWxkIENJKio6DQoNCiQkDQpcaGF0e1x0aGV0YX0gXHBtIHpfezEtXGFscGhhLzJ9IFxzcXJ0e1x3aWRlaGF0e1Zhcn0oXGhhdHtcdGhldGF9KX0NCiQkDQogICAgDQoqICoqTGlrZWxpaG9vZCBDSSoqOg0KDQokJA0KXHtcdGhldGE6IC0yXGxvZ1xMYW1iZGEoXHRoZXRhKSBcbGUgXGNoaV4yX3sxLFxhbHBoYX1cfSwgXCBcIFx0ZXh0eyB3aGVyZSB9IFxhbHBoYSBcdGV4dHsgaXMgdGhlIHJpZ2h0LXRhaWxlZCBhcmVhIH0NCiQkDQogICAgDQoqICoqQ292ZXJhZ2UqKjoNCg0KJCQNCkNQKFx0aGV0YSkgPSBQX1x0aGV0YShMKFgpIFxsZSBcdGhldGEgXGxlIFUoWCkpDQokJA0KDQoNCjxmb250IGNvbG9yID0gImJsdWUiPioqUHJhY3RpY2FsIFJlY29tbWVuZGF0aW9ucyoqOjwvZm9udD4NCg0KKiBVc2UgcGl2b3RhbCBtZXRob2RzIHdoZW4gZXhhY3QgZGlzdHJpYnV0aW9uIGlzIGtub3duDQoNCiogVXNlIENMVC1iYXNlZCBtZXRob2RzIGZvciBsYXJnZSBzYW1wbGVzDQoNCiogVXNlIGxpa2VsaWhvb2QgbWV0aG9kcyBmb3IgY29tcGxleCBwYXJhbWV0ZXJzDQoNCiogQWx3YXlzIGNoZWNrIGFzc3VtcHRpb25zIGFuZCBjb25zaWRlciBib290c3RyYXAgYWx0ZXJuYXRpdmVzDQoNCiogUmVwb3J0IGJvdGggcG9pbnQgZXN0aW1hdGUgYW5kIGNvbmZpZGVuY2UgaW50ZXJ2YWwNCg0KDQoNCg0KDQoNCg0K