Assignment Objectives

  • Comprehend the likelihood function and its properties.

  • Master the maximum likelihood estimation framework and required components.

  • Understand the plug-in principle underlying MLE.

  • Implement maximum likelihood estimation procedures in R.


Policies of Using 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.


Gamma Distribution Revisited

Let \(X\) be the two parameter Gamma random variable with density function

\[ f(x \mid \alpha, \beta) = \frac{1}{\Gamma(\alpha)\beta^\alpha} x^{\alpha-1} e^{-x/\beta} \ \ \text{for} \ \ x > 0, \]

where with \(\alpha > 0\) (shape), \(\beta>0\) (scale), and

\[ \Gamma(\alpha) = \int_{0}^{\infty} t^{\alpha-1} e^{-t} \, dt, \quad \alpha > 0. \]

\(\Gamma(x)\) can be computed in R using the gamma() function. The derivative of \(\Gamma(x)\) are given respectively by

\[ \Gamma^\prime(z) = \Gamma (z)\psi_0(z) \]

where \(\psi_0(z) = \frac{d}{dz} \ln \Gamma{z}\). In R, the digamma function \(\psi_0(z)\) is evaluated by digamma().


This assignment focuses on finding maximum likelihood estimate of parameters \(\alpha\) and \(\beta\) based on a real-world application data set.


Question 1: Derive gradient (first order partial derivative) of likelihood function

Assume that \(\{x_1, x_2, \cdots, x_n \} \to \text{ gamma }(\alpha, \beta)\) with density function given by

\[ f(x \mid \alpha, \beta) = \frac{1}{\Gamma(\alpha)\beta^\alpha} x^{\alpha-1} e^{-x/\beta} \ \ \text{for} \ \ x > 0, \]

Derive the gradient of the log-likelihood function with respect to the gamma distribution parameters \(\alpha\) and \(\beta\). To this end,

a). Write out the full log-likelihood function based on the given data and the density function provided above.

I will begin by finding the likelihood function.

\(L(\alpha, \beta) = \prod_{i=1}^{n} \frac{1}{\Gamma(\alpha)\beta^\alpha} x_i^{\alpha-1} e^{-x_i/\beta}\)

This likelihood function can be rewritten as follows.

\(L(\alpha, \beta) = \left[\frac{1}{\Gamma(\alpha)\beta^\alpha}\right]^n \prod_{i=1}^{n} x_i^{\alpha-1} \exp\left(-\frac{1}{\beta}\sum_{i=1}^{n} x_i\right).\)

Next, I will take the logarithm of this likelihood function in order to obtain the log-likelihood function.

\(\ell(\alpha, \beta) = \log L(\alpha, \beta)\)

Taking the logarithm of the likelihood function results in:

\(\ell(\alpha, \beta) = -n \log \Gamma(\alpha) - n\alpha \log \beta + (\alpha - 1)\sum_{i=1}^{n} \log x_i - \frac{1}{\beta}\sum_{i=1}^{n} x_i\)

Therefore, this is the log-likelihood function of the Gamma distribution with parameters \(\alpha\) and \(\beta\).

b). Derive the score functions (the gradient of the log-likelihood) from the full log-likelihood function in part (a).

First, I will derive the score function for \(\alpha\) from the log-likelihood function that I found in the previous part. I will take the partial derivative with respect to the \(\alpha\) parameter. This will give the score function.

To begin, I know that \(\frac{d}{d\alpha}\log \Gamma(\alpha) = \psi_0(\alpha)\) . So, I can use this fact to help with taking the partial derivative of the log-likelihood function with respect to the \(\alpha\) parameter. Doing so results in the following:

\(\frac{\partial \ell}{\partial \alpha} = -n\psi_0(\alpha) - n\log \beta + \sum_{i=1}^{n} \log x_i\)

Therefore the score function for \(\alpha\) is: \(s_\alpha(\alpha,\beta) = \sum_{i=1}^{n} \log x_i - n\log \beta - n\psi(\alpha)\)

Now, I will find the score function for \(\beta\). I will begin by taking the derivative with respect to \(\beta\) to get the partial derivative for the \(\beta\) parameter. This will give the score function.

To begin, I will differentiate the log-likelihood function with respect to the \(\beta\) parameter. From the original log-likelihood functions, there are two terms with the \(\beta\) parameter. I know these derivatives are as follows, \(\frac{\partial}{\partial \beta} (-n\alpha \log \beta) = -\frac{n\alpha}{\beta}\) and \(\frac{\partial}{\partial \beta} \left(-\frac{1}{\beta}\sum_{i=1}^{n} x_i\right) = \frac{1}{\beta^2}\sum_{i=1}^{n} x_i\)

So, the partial derivative of the log-likelihood function altogether results in the following.

\(\frac{\partial \ell}{\partial \beta} = -\frac{n\alpha}{\beta} + \frac{1}{\beta^2}\sum_{i=1}^{n} x_i\)

Therefore, the score function for \(\beta\) is: \(s_\beta(\alpha,\beta) = -\frac{n\alpha}{\beta} + \frac{1}{\beta^2}\sum_{i=1}^{n} x_i\)

So altogether, the score functions for \(\alpha\) and \(\beta\), respectively are the following:

\(s_\alpha(\alpha,\beta) = \sum_{i=1}^{n} \log x_i - n\log \beta - n\psi(\alpha)\)

\(s_\beta(\alpha,\beta) = -\frac{n\alpha}{\beta} + \frac{1}{\beta^2}\sum_{i=1}^{n} x_i\)


Question 2: Birth data set

The following R code reads in a data set containing, for each of 7 days, the lengths of time in hours spent by women in the delivery suite while giving birth (without a ceasarian section) at John Radcliffe Hospital in Oxford, England. The data are taken from Davison (Statistical Models. Cambridge University Press, 2003).

2.1, 3.4, 4.25, 5.6, 6.4, 7.3, 8.5, 8.75, 8.9, 9.5, 9.75, 10, 10.4, 10.4, 16, 19,
4, 4.1, 5, 5.5, 5.7, 6.5, 7.25, 7.3, 7.5, 8.2, 8.5, 9.75, 11, 11.2, 15, 16.5, 2.6, 
3.6, 3.6, 6.4, 6.8, 7.5, 7.5, 8.25, 8.5, 10.4, 10.75, 14.25, 14.5, 1.5, 4.7, 4.7, 
7.2, 7.25, 8.1, 8.5, 9.2, 9.5, 10.7, 11.5, 2.5, 2.5, 3.4, 4.2, 5.9, 6.25, 7.3, 7.5, 
7.8, 8.3, 8.3, 10.25, 12.9, 14.3, 4, 4, 5.25, 6.1, 6.5, 6.9, 7, 8.45, 9.25, 10.1, 
10.2, 12.75, 14.6, 2, 2.7, 2.75, 3.4, 4.2, 4.3, 4.9, 6.25, 7, 9, 9.25, 10.7

Assume the data are generated from a gamma distribution. The objective is to use these data and the designated algorithm to find the maximum likelihood estimates (MLEs) of the parameters \(\alpha\) and \(\beta\).

a). Find the MLEs of \(\alpha\) and \(\beta\), denoted by \(\hat{\alpha}\) and \(\hat{\beta}\), using gradient-based optimization via the R function optim() with the gradient vector derived in Question 1.

I will begin by storing the data values in a data set that will be named ‘time’.

time <- c(2.1, 3.4, 4.25, 5.6, 6.4, 7.3, 8.5, 8.75, 8.9, 9.5, 9.75, 10, 10.4, 10.4, 16, 19, 4, 4.1, 5, 5.5, 5.7, 6.5, 7.25, 7.3, 7.5, 8.2, 8.5, 9.75, 11, 11.2, 15, 16.5, 2.6, 3.6, 3.6, 6.4, 6.8, 7.5, 7.5, 8.25, 8.5, 10.4, 10.75, 14.25, 14.5, 1.5, 4.7, 4.7, 7.2, 7.25, 8.1, 8.5, 9.2, 9.5, 10.7, 11.5, 2.5, 2.5, 3.4, 4.2, 5.9, 6.25, 7.3, 7.5, 7.8, 8.3, 8.3, 10.25, 12.9, 14.3, 4, 4, 5.25, 6.1, 6.5, 6.9, 7, 8.45, 9.25, 10.1, 10.2, 12.75, 14.6, 2, 2.7, 2.75, 3.4, 4.2, 4.3, 4.9, 6.25, 7, 9, 9.25, 10.7)

Next, I will find the MLEs for \(\alpha\) and \(\beta\) by using the optim() function and the score functions I found in question #1 part b.

n <- length(time)

# Log-likelihood function
loglik <- function(par){
  alpha <- par[1]
  beta  <- par[2]
  
  if(alpha <= 0 || beta <= 0) return(Inf)
  
  -(-n*lgamma(alpha) 
    - n*alpha*log(beta)
    + (alpha-1)*sum(log(time))
    - sum(time)/beta)}

# Gradient functions from question #1
grad <- function(par){
  alpha <- par[1]
  beta  <- par[2]
  
  d_alpha <- sum(log(time)) - n*log(beta) - n*digamma(alpha)
  d_beta  <- -n*alpha/beta + sum(time)/beta^2
  
  return(-c(d_alpha, d_beta))
}

mean_time <- mean(time)
var_time <- var(time)

alpha_init <- mean_time^2 / var_time
beta_init  <- var_time / mean_time

# Using the optim() function to get the MLEs
optim(c(alpha_init, beta_init),
      loglik,
      grad,
      method="L-BFGS-B",
      lower=c(1e-6,1e-6))
$par
[1] 4.387855 1.760122

$value
[1] 251.1173

$counts
function gradient 
       8        8 

$convergence
[1] 0

$message
[1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"

It turns out that \(\hat{\alpha}\) = 4.388 and \(\hat{\beta}\) = 1.760.

b). Apply the method of moments to obtain estimators for \(\alpha\) and \(\beta\). Denote these moment estimators as \(\tilde{\alpha}\) and \(\tilde{\beta}\).

In this part, I will apply the method of moments to obtain the estimators for \(\alpha\) and \(\beta\). For a Gamma distribution, I know that \(E(X) = \alpha \beta\) and Var(X) = \(\alpha \beta^2\). I will write these in terms of the sample mean \(\bar{x}\) and the sample variance \(s^2 = \alpha \beta^2\).

\(\tilde{\alpha} = \frac{\bar{x}^2}{s^2}\)

\(\tilde{\beta} = \frac{s^2}{\bar{x}}\)

Now, to calculate the values of \(\tilde{\alpha}\) and \(\tilde{\beta}\) based upon these moments.

# Method of moments
alpha_mom <- mean_time^2 / var_time
beta_mom  <- var_time / mean_time

alpha_mom
[1] 4.685073
beta_mom
[1] 1.64846

It turns out that \(\tilde{\alpha}\) = 4.685 and \(\tilde{\beta}\) = 1.648.

c). Conduct a brief literature review comparing the method of moments estimation (MME) and maximum likelihood estimation (MLE). Synthesize the key advantages and limitations of each, concluding with a practical recommendation.

I used both the method of moments estimation and the maximum likelihood estimation to estimate the parameters \(\alpha\) and \(\beta\). Both the MLE and the MME methods resulted in similar values. The MLE method resulted in \(\hat{\alpha}\) = 4.388 and \(\hat{\beta}\) = 1.760. The MME method resulted in \(\tilde{\alpha}\) = 4.685 and \(\tilde{\beta}\) = 1.648. These values are quite similar showing that both methods provide use in estimating the parameters.

A major advantage of the Method of moments estimation method was that it is simpler and quicker to compute. For this method, I used facts I knew about the Gamma distribution and its mean and variance in order to get the sample moments, and with some short calculations, this gave me my parameter estimates. On the other hand, the maximum likelihood function required some more complex calculations which required the use of the R optim() function. This required a few extra steps and work to obtain the MLE estimations due to the additional computations required, and needing the use of the gradient functions I calculated in question #1 for the partial derivatives to get the score functions.

However, the MLE method does bring some advantages of its own. The MLE has strong asymptotic normality which brings consistency and states that the distribution of the estimators, in this case \(\alpha\) and \(\beta\) will approach a Normal distribution as the sample size increases to infinity. This property makes the MLE method consistent, reliable, and efficient.

Some limitations of the MME method include that it can be prone to bias, and this can happen especially in skewed distributions. This could occur if the sample moments are not the best representations of the true parameters they are estimating. Therefore, the MME does have some drawbacks and limitations when it comes to potential bias in its estimations if the population is skewed and therefore the sample moments do not provide the greatest accuracy towards the true parameters. On the other hand, the MLE method can also have some drawbacks. While the MLE method is great for large samples, in the case of small samples it can have some potential for bias as well. Additionally, the MLE method requires more complexity in its calculations especially when compared to the MME method.

Overall, I would use the Maximum likelihood estimation as the preferred approach due to its consistency and reliability, even for large sample sizes. The sample size in this scenario was significantly large, meaning that the issue of the MLE having potential for bias in small sample sizes will not be relevant in this case due to a large sample size. Additionally, even though the MLE method requires more complex calculations than the MME method, this trade off is worthwhile due to the consistency and reliability of its calculations. The MLE method is efficient and reliable, making it a great choice for estimation. In this case, I would recommend the MLE method for these reasons.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgNDogTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24iDQphdXRob3I6ICJKb3NpZSBHYWxsb3AiDQpkYXRlOiAiIER1ZTogMDMtMDMtMjAyNiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCiMjIyMNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQogDQpcDQogDQojIyAqKkFzc2lnbm1lbnQgT2JqZWN0aXZlcyoqIA0KDQoqIENvbXByZWhlbmQgdGhlIGxpa2VsaWhvb2QgZnVuY3Rpb24gYW5kIGl0cyBwcm9wZXJ0aWVzLg0KDQoqIE1hc3RlciB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gZnJhbWV3b3JrIGFuZCByZXF1aXJlZCBjb21wb25lbnRzLg0KDQoqIFVuZGVyc3RhbmQgdGhlIHBsdWctaW4gcHJpbmNpcGxlIHVuZGVybHlpbmcgTUxFLg0KDQoqIEltcGxlbWVudCBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBwcm9jZWR1cmVzIGluIFIuDQoNClwNCg0KIyMgKipQb2xpY2llcyBvZiBVc2luZyBBSSBUb29scyoqDQoNCioqUG9saWN5IG9uIEFJIFRvb2wgVXNlKio6IFN0dWRlbnRzIG11c3QgYWRoZXJlIHRvIHRoZSBBSSB0b29sIHBvbGljeSBzcGVjaWZpZWQgaW4gdGhlIGNvdXJzZSBzeWxsYWJ1cy4gVGhlIGRpcmVjdCBjb3B5aW5nIG9mIEFJLWdlbmVyYXRlZCBjb250ZW50IGlzIHN0cmljdGx5IHByb2hpYml0ZWQuIEFsbCBzdWJtaXR0ZWQgd29yayBtdXN0IHJlZmxlY3QgeW91ciBvd24gdW5kZXJzdGFuZGluZzsgd2hlcmUgZXh0ZXJuYWwgdG9vbHMgYXJlIGNvbnN1bHRlZCwgY29udGVudCBtdXN0IGJlIHRob3JvdWdobHkgcmVwaHJhc2VkIGFuZCBzeW50aGVzaXplZCBpbiB5b3VyIG93biB3b3Jkcy4NCg0KKipDb2RlIEluY2x1c2lvbiBSZXF1aXJlbWVudCoqOiBBbnkgY29kZSBpbmNsdWRlZCBpbiB5b3VyIGVzc2F5IG11c3QgYmUgcHJvcGVybHkgY29tbWVudGVkIHRvIGV4cGxhaW4gdGhlIHB1cnBvc2UgYW5kL29yIGV4cGVjdGVkIG91dHB1dCBvZiBrZXkgY29kZSBsaW5lcy4gU3VibWl0dGluZyBBSS1nZW5lcmF0ZWQgY29kZSB3aXRob3V0IG1lYW5pbmdmdWwsIHN0dWRlbnQtYWRkZWQgY29tbWVudHMgd2lsbCBub3QgYmUgYWNjZXB0ZWQuDQoNClwNCg0KKipHYW1tYSBEaXN0cmlidXRpb24gUmV2aXNpdGVkKioNCg0KTGV0ICRYJCBiZSB0aGUgdHdvIHBhcmFtZXRlciBHYW1tYSByYW5kb20gdmFyaWFibGUgd2l0aCBkZW5zaXR5IGZ1bmN0aW9uDQoNCiQkDQpmKHggXG1pZCBcYWxwaGEsIFxiZXRhKSA9IFxmcmFjezF9e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfSB4XntcYWxwaGEtMX0gZV57LXgvXGJldGF9ICBcIFwgXHRleHR7Zm9yfSBcIFwgIHggPiAwLA0KJCQNCg0Kd2hlcmUgd2l0aCAkXGFscGhhID4gMCQgKHNoYXBlKSwgJFxiZXRhPjAkIChzY2FsZSksIGFuZA0KDQokJA0KXEdhbW1hKFxhbHBoYSkgPSBcaW50X3swfV57XGluZnR5fSB0XntcYWxwaGEtMX0gZV57LXR9IFwsIGR0LCBccXVhZCBcYWxwaGEgPiAwLg0KJCQNCg0KJFxHYW1tYSh4KSQgY2FuIGJlIGNvbXB1dGVkIGluIFIgdXNpbmcgdGhlIGBnYW1tYSgpYCBmdW5jdGlvbi4gVGhlIGRlcml2YXRpdmUgb2YgJFxHYW1tYSh4KSQgYXJlIGdpdmVuIHJlc3BlY3RpdmVseSBieQ0KDQokJA0KXEdhbW1hXlxwcmltZSh6KSA9IFxHYW1tYSAoeilccHNpXzAoeikNCiQkDQoNCndoZXJlICRccHNpXzAoeikgPSBcZnJhY3tkfXtken0gXGxuIFxHYW1tYXt6fSQuIEluIFIsIHRoZSBkaWdhbW1hIGZ1bmN0aW9uICRccHNpXzAoeikkIGlzIGV2YWx1YXRlZCBieSBgZGlnYW1tYSgpYC4NCg0KDQoNClwNCg0KPGZvbnQgY29sb3IgPSAiYmx1ZSI+VGhpcyBhc3NpZ25tZW50IGZvY3VzZXMgb24gZmluZGluZyBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGUgb2YgcGFyYW1ldGVycyAkXGFscGhhJCBhbmQgJFxiZXRhJCBiYXNlZCBvbiBhIHJlYWwtd29ybGQgYXBwbGljYXRpb24gZGF0YSBzZXQuPC9mb250Pg0KDQoNClwNCg0KIyMgKipRdWVzdGlvbiAxOiBEZXJpdmUgZ3JhZGllbnQgKGZpcnN0IG9yZGVyIHBhcnRpYWwgZGVyaXZhdGl2ZSkgb2YgbGlrZWxpaG9vZCBmdW5jdGlvbioqDQoNCkFzc3VtZSB0aGF0ICRce3hfMSwgeF8yLCBcY2RvdHMsIHhfbiBcfSBcdG8gXHRleHR7IGdhbW1hIH0oXGFscGhhLCBcYmV0YSkkIHdpdGggZGVuc2l0eSBmdW5jdGlvbiBnaXZlbiBieQ0KDQokJA0KZih4IFxtaWQgXGFscGhhLCBcYmV0YSkgPSBcZnJhY3sxfXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX0geF57XGFscGhhLTF9IGVeey14L1xiZXRhfSAgXCBcIFx0ZXh0e2Zvcn0gXCBcICB4ID4gMCwNCiQkDQoNCkRlcml2ZSB0aGUgZ3JhZGllbnQgb2YgdGhlICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiB3aXRoIHJlc3BlY3QgdG8gdGhlIGdhbW1hIGRpc3RyaWJ1dGlvbiBwYXJhbWV0ZXJzICRcYWxwaGEkIGFuZCAkXGJldGEkLiBUbyB0aGlzIGVuZCwNCg0KDQphKS4gV3JpdGUgb3V0IHRoZSBmdWxsICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiBiYXNlZCBvbiB0aGUgZ2l2ZW4gZGF0YSBhbmQgdGhlIGRlbnNpdHkgZnVuY3Rpb24gcHJvdmlkZWQgYWJvdmUuDQoNCkkgd2lsbCBiZWdpbiBieSBmaW5kaW5nIHRoZSBsaWtlbGlob29kIGZ1bmN0aW9uLiANCg0KJEwoXGFscGhhLCBcYmV0YSkgPSBccHJvZF97aT0xfV57bn0gXGZyYWN7MX17XEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGF9IHhfaV57XGFscGhhLTF9IGVeey14X2kvXGJldGF9JA0KDQpUaGlzIGxpa2VsaWhvb2QgZnVuY3Rpb24gY2FuIGJlIHJld3JpdHRlbiBhcyBmb2xsb3dzLg0KDQokTChcYWxwaGEsIFxiZXRhKSA9IFxsZWZ0W1xmcmFjezF9e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfVxyaWdodF1ebiBccHJvZF97aT0xfV57bn0geF9pXntcYWxwaGEtMX0gXGV4cFxsZWZ0KC1cZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9XntufSB4X2lccmlnaHQpLiQNCg0KTmV4dCwgSSB3aWxsIHRha2UgdGhlIGxvZ2FyaXRobSBvZiB0aGlzIGxpa2VsaWhvb2QgZnVuY3Rpb24gaW4gb3JkZXIgdG8gb2J0YWluIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbi4gDQoNCiRcZWxsKFxhbHBoYSwgXGJldGEpID0gXGxvZyBMKFxhbHBoYSwgXGJldGEpJA0KDQpUYWtpbmcgdGhlIGxvZ2FyaXRobSBvZiB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiByZXN1bHRzIGluOiANCg0KJFxlbGwoXGFscGhhLCBcYmV0YSkgPSAtbiBcbG9nIFxHYW1tYShcYWxwaGEpIC0gblxhbHBoYSBcbG9nIFxiZXRhICsgKFxhbHBoYSAtIDEpXHN1bV97aT0xfV57bn0gXGxvZyB4X2kgLSBcZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9XntufSB4X2kkDQoNClRoZXJlZm9yZSwgdGhpcyBpcyB0aGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24gb2YgdGhlIEdhbW1hIGRpc3RyaWJ1dGlvbiB3aXRoIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuDQoNCg0KYikuIERlcml2ZSB0aGUgc2NvcmUgZnVuY3Rpb25zICh0aGUgZ3JhZGllbnQgb2YgdGhlIGxvZy1saWtlbGlob29kKSBmcm9tIHRoZSBmdWxsICoqbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24qKiBpbiBwYXJ0IChhKS4NCg0KRmlyc3QsIEkgd2lsbCBkZXJpdmUgdGhlIHNjb3JlIGZ1bmN0aW9uIGZvciAkXGFscGhhJCBmcm9tIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiB0aGF0IEkgZm91bmQgaW4gdGhlIHByZXZpb3VzIHBhcnQuIEkgd2lsbCB0YWtlIHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvIHRoZSAkXGFscGhhJCBwYXJhbWV0ZXIuIFRoaXMgd2lsbCBnaXZlIHRoZSBzY29yZSBmdW5jdGlvbi4NCg0KVG8gYmVnaW4sIEkga25vdyB0aGF0ICRcZnJhY3tkfXtkXGFscGhhfVxsb2cgXEdhbW1hKFxhbHBoYSkgPSBccHNpXzAoXGFscGhhKSQgLiBTbywgSSBjYW4gdXNlIHRoaXMgZmFjdCB0byBoZWxwIHdpdGggdGFraW5nIHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgb2YgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgJFxhbHBoYSQgcGFyYW1ldGVyLiBEb2luZyBzbyByZXN1bHRzIGluIHRoZSBmb2xsb3dpbmc6DQoNCiRcZnJhY3tccGFydGlhbCBcZWxsfXtccGFydGlhbCBcYWxwaGF9ID0gLW5ccHNpXzAoXGFscGhhKSAtIG5cbG9nIFxiZXRhICsgXHN1bV97aT0xfV57bn0gXGxvZyB4X2kkDQoNClRoZXJlZm9yZSB0aGUgc2NvcmUgZnVuY3Rpb24gZm9yICRcYWxwaGEkIGlzOg0KJHNfXGFscGhhKFxhbHBoYSxcYmV0YSkgPSBcc3VtX3tpPTF9XntufSBcbG9nIHhfaSAtIG5cbG9nIFxiZXRhIC0gblxwc2koXGFscGhhKSQNCg0KDQoNCg0KTm93LCBJIHdpbGwgZmluZCB0aGUgc2NvcmUgZnVuY3Rpb24gZm9yICRcYmV0YSQuIEkgd2lsbCBiZWdpbiBieSB0YWtpbmcgdGhlIGRlcml2YXRpdmUgd2l0aCByZXNwZWN0IHRvICRcYmV0YSQgdG8gZ2V0IHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgZm9yIHRoZSAkXGJldGEkIHBhcmFtZXRlci4gVGhpcyB3aWxsIGdpdmUgdGhlIHNjb3JlIGZ1bmN0aW9uLg0KDQpUbyBiZWdpbiwgSSB3aWxsIGRpZmZlcmVudGlhdGUgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIHdpdGggcmVzcGVjdCB0byB0aGUgJFxiZXRhJCBwYXJhbWV0ZXIuIEZyb20gdGhlIG9yaWdpbmFsIGxvZy1saWtlbGlob29kIGZ1bmN0aW9ucywgdGhlcmUgYXJlIHR3byB0ZXJtcyB3aXRoIHRoZSAkXGJldGEkIHBhcmFtZXRlci4gSSBrbm93IHRoZXNlIGRlcml2YXRpdmVzIGFyZSBhcyBmb2xsb3dzLA0KJFxmcmFje1xwYXJ0aWFsfXtccGFydGlhbCBcYmV0YX0gKC1uXGFscGhhIFxsb2cgXGJldGEpID0gLVxmcmFje25cYWxwaGF9e1xiZXRhfSQgYW5kICRcZnJhY3tccGFydGlhbH17XHBhcnRpYWwgXGJldGF9IFxsZWZ0KC1cZnJhY3sxfXtcYmV0YX1cc3VtX3tpPTF9XntufSB4X2lccmlnaHQpID0gXGZyYWN7MX17XGJldGFeMn1cc3VtX3tpPTF9XntufSB4X2kkDQoNClNvLCB0aGUgcGFydGlhbCBkZXJpdmF0aXZlIG9mIHRoZSBsb2ctbGlrZWxpaG9vZCBmdW5jdGlvbiBhbHRvZ2V0aGVyIHJlc3VsdHMgaW4gdGhlIGZvbGxvd2luZy4NCg0KJFxmcmFje1xwYXJ0aWFsIFxlbGx9e1xwYXJ0aWFsIFxiZXRhfSA9IC1cZnJhY3tuXGFscGhhfXtcYmV0YX0gKyBcZnJhY3sxfXtcYmV0YV4yfVxzdW1fe2k9MX1ee259IHhfaSQNCg0KVGhlcmVmb3JlLCB0aGUgc2NvcmUgZnVuY3Rpb24gZm9yICRcYmV0YSQgaXM6DQokc19cYmV0YShcYWxwaGEsXGJldGEpID0gLVxmcmFje25cYWxwaGF9e1xiZXRhfSArIFxmcmFjezF9e1xiZXRhXjJ9XHN1bV97aT0xfV57bn0geF9pJA0KDQoNClNvIGFsdG9nZXRoZXIsIHRoZSBzY29yZSBmdW5jdGlvbnMgZm9yICRcYWxwaGEkIGFuZCAkXGJldGEkLCByZXNwZWN0aXZlbHkgYXJlIHRoZSBmb2xsb3dpbmc6DQoNCiRzX1xhbHBoYShcYWxwaGEsXGJldGEpID0gXHN1bV97aT0xfV57bn0gXGxvZyB4X2kgLSBuXGxvZyBcYmV0YSAtIG5ccHNpKFxhbHBoYSkkDQoNCiRzX1xiZXRhKFxhbHBoYSxcYmV0YSkgPSAtXGZyYWN7blxhbHBoYX17XGJldGF9ICsgXGZyYWN7MX17XGJldGFeMn1cc3VtX3tpPTF9XntufSB4X2kkDQoNCg0KXA0KDQojIyAqKlF1ZXN0aW9uIDI6IEJpcnRoIGRhdGEgc2V0KioNCg0KVGhlIGZvbGxvd2luZyBSIGNvZGUgcmVhZHMgaW4gYSBkYXRhIHNldCBjb250YWluaW5nLCBmb3IgZWFjaCBvZiA3IGRheXMsIHRoZSBsZW5ndGhzIG9mIHRpbWUgaW4gaG91cnMgc3BlbnQgYnkNCndvbWVuIGluIHRoZSBkZWxpdmVyeSBzdWl0ZSB3aGlsZSBnaXZpbmcgYmlydGggKHdpdGhvdXQgYSBjZWFzYXJpYW4gc2VjdGlvbikgYXQgSm9obiBSYWRjbGlmZmUgSG9zcGl0YWwgaW4NCk94Zm9yZCwgRW5nbGFuZC4gVGhlIGRhdGEgYXJlIHRha2VuIGZyb20gRGF2aXNvbiAoU3RhdGlzdGljYWwgTW9kZWxzLiBDYW1icmlkZ2UgVW5pdmVyc2l0eSBQcmVzcywgMjAwMykuDQoNCmBgYA0KMi4xLCAzLjQsIDQuMjUsIDUuNiwgNi40LCA3LjMsIDguNSwgOC43NSwgOC45LCA5LjUsIDkuNzUsIDEwLCAxMC40LCAxMC40LCAxNiwgMTksDQo0LCA0LjEsIDUsIDUuNSwgNS43LCA2LjUsIDcuMjUsIDcuMywgNy41LCA4LjIsIDguNSwgOS43NSwgMTEsIDExLjIsIDE1LCAxNi41LCAyLjYsIA0KMy42LCAzLjYsIDYuNCwgNi44LCA3LjUsIDcuNSwgOC4yNSwgOC41LCAxMC40LCAxMC43NSwgMTQuMjUsIDE0LjUsIDEuNSwgNC43LCA0LjcsIA0KNy4yLCA3LjI1LCA4LjEsIDguNSwgOS4yLCA5LjUsIDEwLjcsIDExLjUsIDIuNSwgMi41LCAzLjQsIDQuMiwgNS45LCA2LjI1LCA3LjMsIDcuNSwgDQo3LjgsIDguMywgOC4zLCAxMC4yNSwgMTIuOSwgMTQuMywgNCwgNCwgNS4yNSwgNi4xLCA2LjUsIDYuOSwgNywgOC40NSwgOS4yNSwgMTAuMSwgDQoxMC4yLCAxMi43NSwgMTQuNiwgMiwgMi43LCAyLjc1LCAzLjQsIDQuMiwgNC4zLCA0LjksIDYuMjUsIDcsIDksIDkuMjUsIDEwLjcNCmBgYA0KDQpBc3N1bWUgdGhlIGRhdGEgYXJlIGdlbmVyYXRlZCBmcm9tIGEgZ2FtbWEgZGlzdHJpYnV0aW9uLiBUaGUgb2JqZWN0aXZlIGlzIHRvIHVzZSB0aGVzZSBkYXRhIGFuZCB0aGUgZGVzaWduYXRlZCBhbGdvcml0aG0gdG8gZmluZCB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRlcyAoTUxFcykgb2YgdGhlIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuDQoNCg0KYSkuIEZpbmQgdGhlIE1MRXMgb2YgJFxhbHBoYSQgYW5kICRcYmV0YSQsIGRlbm90ZWQgYnkgJFxoYXR7XGFscGhhfSQgYW5kICRcaGF0e1xiZXRhfSQsICB1c2luZyBncmFkaWVudC1iYXNlZCBvcHRpbWl6YXRpb24gdmlhIHRoZSBSIGZ1bmN0aW9uIGBvcHRpbSgpYCB3aXRoIHRoZSBncmFkaWVudCB2ZWN0b3IgZGVyaXZlZCBpbiBRdWVzdGlvbiAxLg0KDQpJIHdpbGwgYmVnaW4gYnkgc3RvcmluZyB0aGUgZGF0YSB2YWx1ZXMgaW4gYSBkYXRhIHNldCB0aGF0IHdpbGwgYmUgbmFtZWQgJ3RpbWUnLg0KDQpgYGB7cn0NCnRpbWUgPC0gYygyLjEsIDMuNCwgNC4yNSwgNS42LCA2LjQsIDcuMywgOC41LCA4Ljc1LCA4LjksIDkuNSwgOS43NSwgMTAsIDEwLjQsIDEwLjQsIDE2LCAxOSwgNCwgNC4xLCA1LCA1LjUsIDUuNywgNi41LCA3LjI1LCA3LjMsIDcuNSwgOC4yLCA4LjUsIDkuNzUsIDExLCAxMS4yLCAxNSwgMTYuNSwgMi42LCAzLjYsIDMuNiwgNi40LCA2LjgsIDcuNSwgNy41LCA4LjI1LCA4LjUsIDEwLjQsIDEwLjc1LCAxNC4yNSwgMTQuNSwgMS41LCA0LjcsIDQuNywgNy4yLCA3LjI1LCA4LjEsIDguNSwgOS4yLCA5LjUsIDEwLjcsIDExLjUsIDIuNSwgMi41LCAzLjQsIDQuMiwgNS45LCA2LjI1LCA3LjMsIDcuNSwgNy44LCA4LjMsIDguMywgMTAuMjUsIDEyLjksIDE0LjMsIDQsIDQsIDUuMjUsIDYuMSwgNi41LCA2LjksIDcsIDguNDUsIDkuMjUsIDEwLjEsIDEwLjIsIDEyLjc1LCAxNC42LCAyLCAyLjcsIDIuNzUsIDMuNCwgNC4yLCA0LjMsIDQuOSwgNi4yNSwgNywgOSwgOS4yNSwgMTAuNykNCmBgYA0KDQpOZXh0LCBJIHdpbGwgZmluZCB0aGUgTUxFcyBmb3IgJFxhbHBoYSQgYW5kICRcYmV0YSQgYnkgdXNpbmcgdGhlIG9wdGltKCkgZnVuY3Rpb24gYW5kIHRoZSBzY29yZSBmdW5jdGlvbnMgSSBmb3VuZCBpbiBxdWVzdGlvbiAjMSBwYXJ0IGIuIA0KDQpgYGB7cn0NCm4gPC0gbGVuZ3RoKHRpbWUpDQoNCiMgTG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24NCmxvZ2xpayA8LSBmdW5jdGlvbihwYXIpew0KICBhbHBoYSA8LSBwYXJbMV0NCiAgYmV0YSAgPC0gcGFyWzJdDQogIA0KICBpZihhbHBoYSA8PSAwIHx8IGJldGEgPD0gMCkgcmV0dXJuKEluZikNCiAgDQogIC0oLW4qbGdhbW1hKGFscGhhKSANCiAgICAtIG4qYWxwaGEqbG9nKGJldGEpDQogICAgKyAoYWxwaGEtMSkqc3VtKGxvZyh0aW1lKSkNCiAgICAtIHN1bSh0aW1lKS9iZXRhKX0NCg0KIyBHcmFkaWVudCBmdW5jdGlvbnMgZnJvbSBxdWVzdGlvbiAjMQ0KZ3JhZCA8LSBmdW5jdGlvbihwYXIpew0KICBhbHBoYSA8LSBwYXJbMV0NCiAgYmV0YSAgPC0gcGFyWzJdDQogIA0KICBkX2FscGhhIDwtIHN1bShsb2codGltZSkpIC0gbipsb2coYmV0YSkgLSBuKmRpZ2FtbWEoYWxwaGEpDQogIGRfYmV0YSAgPC0gLW4qYWxwaGEvYmV0YSArIHN1bSh0aW1lKS9iZXRhXjINCiAgDQogIHJldHVybigtYyhkX2FscGhhLCBkX2JldGEpKQ0KfQ0KDQptZWFuX3RpbWUgPC0gbWVhbih0aW1lKQ0KdmFyX3RpbWUgPC0gdmFyKHRpbWUpDQoNCmFscGhhX2luaXQgPC0gbWVhbl90aW1lXjIgLyB2YXJfdGltZQ0KYmV0YV9pbml0ICA8LSB2YXJfdGltZSAvIG1lYW5fdGltZQ0KDQojIFVzaW5nIHRoZSBvcHRpbSgpIGZ1bmN0aW9uIHRvIGdldCB0aGUgTUxFcw0Kb3B0aW0oYyhhbHBoYV9pbml0LCBiZXRhX2luaXQpLA0KICAgICAgbG9nbGlrLA0KICAgICAgZ3JhZCwNCiAgICAgIG1ldGhvZD0iTC1CRkdTLUIiLA0KICAgICAgbG93ZXI9YygxZS02LDFlLTYpKQ0KYGBgDQoNCkl0IHR1cm5zIG91dCB0aGF0ICRcaGF0e1xhbHBoYX0kID0gNC4zODggYW5kICRcaGF0e1xiZXRhfSQgPSAxLjc2MC4gDQoNCg0KYikuIEFwcGx5IHRoZSBtZXRob2Qgb2YgbW9tZW50cyB0byBvYnRhaW4gZXN0aW1hdG9ycyBmb3IgJFxhbHBoYSQgYW5kICRcYmV0YSQuIERlbm90ZSB0aGVzZSBtb21lbnQgZXN0aW1hdG9ycyBhcyAkXHRpbGRle1xhbHBoYX0kIGFuZCAkXHRpbGRle1xiZXRhfSQuDQoNCkluIHRoaXMgcGFydCwgSSB3aWxsIGFwcGx5IHRoZSBtZXRob2Qgb2YgbW9tZW50cyB0byBvYnRhaW4gdGhlIGVzdGltYXRvcnMgZm9yICRcYWxwaGEkIGFuZCAkXGJldGEkLiAgRm9yIGEgR2FtbWEgZGlzdHJpYnV0aW9uLCBJIGtub3cgdGhhdCAkRShYKSA9IFxhbHBoYSBcYmV0YSQgYW5kIFZhcihYKSA9ICRcYWxwaGEgXGJldGFeMiQuIEkgd2lsbCB3cml0ZSB0aGVzZSBpbiB0ZXJtcyBvZiB0aGUgc2FtcGxlIG1lYW4gJFxiYXJ7eH0kIGFuZCB0aGUgc2FtcGxlIHZhcmlhbmNlICRzXjIgPSBcYWxwaGEgXGJldGFeMiQuIA0KDQokXHRpbGRle1xhbHBoYX0gPSBcZnJhY3tcYmFye3h9XjJ9e3NeMn0kDQoNCiRcdGlsZGV7XGJldGF9ID0gXGZyYWN7c14yfXtcYmFye3h9fSQNCg0KTm93LCB0byBjYWxjdWxhdGUgdGhlIHZhbHVlcyBvZiAkXHRpbGRle1xhbHBoYX0kIGFuZCAkXHRpbGRle1xiZXRhfSQgYmFzZWQgdXBvbiB0aGVzZSBtb21lbnRzLiANCg0KYGBge3J9DQojIE1ldGhvZCBvZiBtb21lbnRzDQphbHBoYV9tb20gPC0gbWVhbl90aW1lXjIgLyB2YXJfdGltZQ0KYmV0YV9tb20gIDwtIHZhcl90aW1lIC8gbWVhbl90aW1lDQoNCmFscGhhX21vbQ0KYmV0YV9tb20NCmBgYA0KDQpJdCB0dXJucyBvdXQgdGhhdCAkXHRpbGRle1xhbHBoYX0kID0gNC42ODUgYW5kICRcdGlsZGV7XGJldGF9JCA9IDEuNjQ4LiANCg0KDQpjKS4gQ29uZHVjdCBhIGJyaWVmIGxpdGVyYXR1cmUgcmV2aWV3IGNvbXBhcmluZyB0aGUgbWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdGlvbiAoTU1FKSBhbmQgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gKE1MRSkuIFN5bnRoZXNpemUgdGhlIGtleSBhZHZhbnRhZ2VzIGFuZCBsaW1pdGF0aW9ucyBvZiBlYWNoLCBjb25jbHVkaW5nIHdpdGggYSBwcmFjdGljYWwgcmVjb21tZW5kYXRpb24uDQoNCkkgdXNlZCBib3RoIHRoZSBtZXRob2Qgb2YgbW9tZW50cyBlc3RpbWF0aW9uIGFuZCB0aGUgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gdG8gZXN0aW1hdGUgdGhlIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuIEJvdGggdGhlIE1MRSBhbmQgdGhlIE1NRSBtZXRob2RzIHJlc3VsdGVkIGluIHNpbWlsYXIgdmFsdWVzLiBUaGUgTUxFIG1ldGhvZCByZXN1bHRlZCBpbiAkXGhhdHtcYWxwaGF9JCA9IDQuMzg4IGFuZCAkXGhhdHtcYmV0YX0kID0gMS43NjAuIFRoZSBNTUUgbWV0aG9kIHJlc3VsdGVkIGluICRcdGlsZGV7XGFscGhhfSQgPSA0LjY4NSBhbmQgJFx0aWxkZXtcYmV0YX0kID0gMS42NDguIFRoZXNlIHZhbHVlcyBhcmUgcXVpdGUgc2ltaWxhciBzaG93aW5nIHRoYXQgYm90aCBtZXRob2RzIHByb3ZpZGUgdXNlIGluIGVzdGltYXRpbmcgdGhlIHBhcmFtZXRlcnMuIA0KDQpBIG1ham9yIGFkdmFudGFnZSBvZiB0aGUgTWV0aG9kIG9mIG1vbWVudHMgZXN0aW1hdGlvbiBtZXRob2Qgd2FzIHRoYXQgaXQgaXMgc2ltcGxlciBhbmQgcXVpY2tlciB0byBjb21wdXRlLiBGb3IgdGhpcyBtZXRob2QsIEkgdXNlZCBmYWN0cyBJIGtuZXcgYWJvdXQgdGhlIEdhbW1hIGRpc3RyaWJ1dGlvbiBhbmQgaXRzIG1lYW4gYW5kIHZhcmlhbmNlIGluIG9yZGVyIHRvIGdldCB0aGUgc2FtcGxlIG1vbWVudHMsIGFuZCB3aXRoIHNvbWUgc2hvcnQgY2FsY3VsYXRpb25zLCB0aGlzIGdhdmUgbWUgbXkgcGFyYW1ldGVyIGVzdGltYXRlcy4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSBtYXhpbXVtIGxpa2VsaWhvb2QgZnVuY3Rpb24gcmVxdWlyZWQgc29tZSBtb3JlIGNvbXBsZXggY2FsY3VsYXRpb25zIHdoaWNoIHJlcXVpcmVkIHRoZSB1c2Ugb2YgdGhlIFIgb3B0aW0oKSBmdW5jdGlvbi4gVGhpcyByZXF1aXJlZCBhIGZldyBleHRyYSBzdGVwcyBhbmQgd29yayB0byBvYnRhaW4gdGhlIE1MRSBlc3RpbWF0aW9ucyBkdWUgdG8gdGhlIGFkZGl0aW9uYWwgY29tcHV0YXRpb25zIHJlcXVpcmVkLCBhbmQgbmVlZGluZyB0aGUgdXNlIG9mIHRoZSBncmFkaWVudCBmdW5jdGlvbnMgSSBjYWxjdWxhdGVkIGluIHF1ZXN0aW9uICMxIGZvciB0aGUgcGFydGlhbCBkZXJpdmF0aXZlcyB0byBnZXQgdGhlIHNjb3JlIGZ1bmN0aW9ucy4gDQoNCkhvd2V2ZXIsIHRoZSBNTEUgbWV0aG9kIGRvZXMgYnJpbmcgc29tZSBhZHZhbnRhZ2VzIG9mIGl0cyBvd24uIFRoZSBNTEUgaGFzIHN0cm9uZyBhc3ltcHRvdGljIG5vcm1hbGl0eSB3aGljaCBicmluZ3MgY29uc2lzdGVuY3kgYW5kIHN0YXRlcyB0aGF0IHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIGVzdGltYXRvcnMsIGluIHRoaXMgY2FzZSAkXGFscGhhJCBhbmQgJFxiZXRhJCB3aWxsIGFwcHJvYWNoIGEgTm9ybWFsIGRpc3RyaWJ1dGlvbiBhcyB0aGUgc2FtcGxlIHNpemUgaW5jcmVhc2VzIHRvIGluZmluaXR5LiBUaGlzIHByb3BlcnR5IG1ha2VzIHRoZSBNTEUgbWV0aG9kIGNvbnNpc3RlbnQsIHJlbGlhYmxlLCBhbmQgZWZmaWNpZW50LiANCg0KU29tZSBsaW1pdGF0aW9ucyBvZiB0aGUgTU1FIG1ldGhvZCBpbmNsdWRlIHRoYXQgaXQgY2FuIGJlIHByb25lIHRvIGJpYXMsIGFuZCB0aGlzIGNhbiBoYXBwZW4gZXNwZWNpYWxseSBpbiBza2V3ZWQgZGlzdHJpYnV0aW9ucy4gVGhpcyBjb3VsZCBvY2N1ciBpZiB0aGUgc2FtcGxlIG1vbWVudHMgYXJlIG5vdCB0aGUgYmVzdCByZXByZXNlbnRhdGlvbnMgb2YgdGhlIHRydWUgcGFyYW1ldGVycyB0aGV5IGFyZSBlc3RpbWF0aW5nLiBUaGVyZWZvcmUsIHRoZSBNTUUgZG9lcyBoYXZlIHNvbWUgZHJhd2JhY2tzIGFuZCBsaW1pdGF0aW9ucyB3aGVuIGl0IGNvbWVzIHRvIHBvdGVudGlhbCBiaWFzIGluIGl0cyBlc3RpbWF0aW9ucyBpZiB0aGUgcG9wdWxhdGlvbiBpcyBza2V3ZWQgYW5kIHRoZXJlZm9yZSB0aGUgc2FtcGxlIG1vbWVudHMgZG8gbm90IHByb3ZpZGUgdGhlIGdyZWF0ZXN0IGFjY3VyYWN5IHRvd2FyZHMgdGhlIHRydWUgcGFyYW1ldGVycy4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSBNTEUgbWV0aG9kIGNhbiBhbHNvIGhhdmUgc29tZSBkcmF3YmFja3MuIFdoaWxlIHRoZSBNTEUgbWV0aG9kIGlzIGdyZWF0IGZvciBsYXJnZSBzYW1wbGVzLCBpbiB0aGUgY2FzZSBvZiBzbWFsbCBzYW1wbGVzIGl0IGNhbiBoYXZlIHNvbWUgcG90ZW50aWFsIGZvciBiaWFzIGFzIHdlbGwuIEFkZGl0aW9uYWxseSwgdGhlIE1MRSBtZXRob2QgcmVxdWlyZXMgbW9yZSBjb21wbGV4aXR5IGluIGl0cyBjYWxjdWxhdGlvbnMgZXNwZWNpYWxseSB3aGVuIGNvbXBhcmVkIHRvIHRoZSBNTUUgbWV0aG9kLiANCg0KT3ZlcmFsbCwgSSB3b3VsZCB1c2UgdGhlIE1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0aW9uIGFzIHRoZSBwcmVmZXJyZWQgYXBwcm9hY2ggZHVlIHRvIGl0cyBjb25zaXN0ZW5jeSBhbmQgcmVsaWFiaWxpdHksIGV2ZW4gZm9yIGxhcmdlIHNhbXBsZSBzaXplcy4gVGhlIHNhbXBsZSBzaXplIGluIHRoaXMgc2NlbmFyaW8gd2FzIHNpZ25pZmljYW50bHkgbGFyZ2UsIG1lYW5pbmcgdGhhdCB0aGUgaXNzdWUgb2YgdGhlIE1MRSBoYXZpbmcgcG90ZW50aWFsIGZvciBiaWFzIGluIHNtYWxsIHNhbXBsZSBzaXplcyB3aWxsIG5vdCBiZSByZWxldmFudCBpbiB0aGlzIGNhc2UgZHVlIHRvIGEgbGFyZ2Ugc2FtcGxlIHNpemUuIEFkZGl0aW9uYWxseSwgZXZlbiB0aG91Z2ggdGhlIE1MRSBtZXRob2QgcmVxdWlyZXMgbW9yZSBjb21wbGV4IGNhbGN1bGF0aW9ucyB0aGFuIHRoZSBNTUUgbWV0aG9kLCB0aGlzIHRyYWRlIG9mZiBpcyB3b3J0aHdoaWxlIGR1ZSB0byB0aGUgY29uc2lzdGVuY3kgYW5kIHJlbGlhYmlsaXR5IG9mIGl0cyBjYWxjdWxhdGlvbnMuIFRoZSBNTEUgbWV0aG9kIGlzIGVmZmljaWVudCBhbmQgcmVsaWFibGUsIG1ha2luZyBpdCBhIGdyZWF0IGNob2ljZSBmb3IgZXN0aW1hdGlvbi4gSW4gdGhpcyBjYXNlLCBJIHdvdWxkIHJlY29tbWVuZCB0aGUgTUxFIG1ldGhvZCBmb3IgdGhlc2UgcmVhc29ucy4g