1.) Gradient Derivation

For this analysis we will assume that our random variable X is Gamma distributed and the instances which make up our random sample of x resemble those distributive characteristics. The conditional PDF of X, whose values depend on the parameters of the Gamma Distribution - \(\alpha\) to represent shape and \(\beta\) to represent rate - is written below.

\[\Large f(x | \alpha, \beta) = \frac{1}{\Gamma(\alpha)\beta^\alpha}x^{(\alpha-1)}e^{(-x/\beta)} \hspace{0.5cm}x,\alpha, \beta> 0 \] To perform the partial derivations throughout this analysis, standard derivative rules such as the power, product and quotient rule were heavily relied upon. The quotient rule in particular and the manner in which I used it is depicted below.


\[Quotient \ Rule \ =\Large \frac{g(x)h'(x)-h(x)g'(x)}{[g(x)]^2}\]
\[\Large \frac{h(x) = x^{\alpha-1}e^{-x/\beta}}{g(x) = \Gamma(\alpha)\beta^\alpha} \]

Derivation on Original Function

To enhance my understanding of how \(\alpha\) and \(\beta\) individually impact the value of x in our distribution, I found the rate of change that each parameter is respectively responsible for (ie the partial derivative or score function).

Partial Derivative W/ Respect to Alpha

\[\Large 1: \frac{\partial f}{\partial \alpha} = e^{-x/\beta}* \frac{d}{d\alpha}[\frac{x^{\alpha-1}}{\Gamma(\alpha)\beta^\alpha}] \]

\[\Large 2: \frac{d}{d\alpha}[\frac{x^{\alpha-1}}{\Gamma(\alpha)\beta^\alpha}] = \frac{(\Gamma(\alpha)\beta^\alpha)[x^{\alpha-1}ln(x)]-(x^{\alpha-1})(\frac{d}{d\alpha}[\Gamma(\alpha)\beta^\alpha])}{[\Gamma(\alpha)\beta^\alpha)]^2}\]
\[\Large 3: \frac{d}{d\alpha}[\Gamma(\alpha)\beta^\alpha] = \Gamma(\alpha)*\beta^\alpha ln(\beta)+\beta^\alpha*\frac{d}{d\alpha}[\Gamma(\alpha)] \]
\[\Large 4: \frac{d}{d\alpha}[\Gamma(\alpha)\beta^\alpha] = \Gamma(\alpha)*\beta^\alpha ln(\beta)+\Gamma(\alpha)\psi^{(0)}(\alpha)*\beta^\alpha\]
\[\Large 5: \frac{d}{d\alpha}[\frac{x^{\alpha-1}}{\Gamma(\alpha)\beta^\alpha}] = \frac{(\Gamma(\alpha)\beta^\alpha)[x^{\alpha-1}ln(x)]-(x^{\alpha-1})[\Gamma(\alpha)*\beta^\alpha ln(\beta)+\Gamma(\alpha)\psi^{(0)}(\alpha)*\beta^\alpha]}{[\Gamma(\alpha)\beta^\alpha)]^2}\]
\[\Large 6: \frac{d}{d\alpha}[\frac{x^{\alpha-1}}{\Gamma(\alpha)\beta^\alpha}] = \frac{x^{\alpha-1}[ln(x)-ln(\beta)+\psi^{(0)}(\alpha)]}{\Gamma(\alpha)*\beta^\alpha} \]
Now multiply constant component with derivative component \[\Large 7: \frac{\partial f}{\partial \alpha} = e^{-x/\beta}* \frac{d}{d\alpha}[\frac{x^{\alpha-1}}{\Gamma(\alpha)\beta^\alpha}] \]


\[\Large 8: \frac{\partial f}{\partial \alpha} = \frac{e^{-x/\beta}*x^{\alpha-1}[ln(x)-ln(\beta)+\psi^{(0)}(\alpha)]}{\Gamma(\alpha)*\beta^\alpha} \]
\[\Large 9: \frac{\partial f}{\partial \alpha} = \frac{x^{\alpha-1}e^{-x/\beta}}{\Gamma(\alpha)*\beta^\alpha} * [ln(x)-ln(\beta)+\psi^{(0)}(\alpha)] \]


\[\Large 10: \frac{\partial f}{\partial \alpha} = f(x|\alpha, \beta) * [ln(x)-ln(\beta)+\psi^{(0)}(\alpha)] \]

Partial Derivative W/ Respect to Beta


\[\Large 1: \frac{\partial f}{\partial \beta} = \frac{x^{\alpha-1}}{\Gamma(\alpha)} *\frac{d}{d\beta}[\frac{e^{(-x/\beta)}}{\beta^\alpha}] \]
Isolate derivative component \[\Large 2: \frac{d}{d\beta}[\frac{e^{-x/\beta}}\beta^\alpha] = \frac{\beta^\alpha * \frac{d}{d\beta}[e^{-x/\beta}]-e^{-x/\beta}*\frac{d}{d\beta}[\beta^\alpha]}{\beta^{2\alpha}} \]


\[\Large 3: \frac{d}{d\beta}[\frac{e^{-x/\beta}}\beta^\alpha] = \frac{\beta^\alpha*\frac{-x}{\beta^2}*e^{-x/\beta}-e^{-x/\beta}*\alpha\beta^{\alpha-1}}{\beta^{2\alpha}} \]


\[\Large 4: \frac{d}{d\beta}[\frac{e^{-x/\beta}}{\beta^\alpha}] = \frac{(\beta^{\alpha-2} * x*e^{-x/\beta})-(e^{-x/\beta}*\alpha\beta^{\alpha-1})}{\beta^{2\alpha}} \]


Now multiply constant component with derivative component \[\Large 5: \frac{\partial f}{\partial \beta} = \frac{(x^{\alpha-1})[\beta^{\alpha-2}xe^{-x/\beta}-e^{-x/\beta}\alpha\beta^{\alpha-1}]}{\Gamma(\alpha)\beta^{2\alpha}}\]
\[\Large 7: \frac{\partial f}{\partial \beta} = \frac{(x^{\alpha-1})(e^{-x/\beta})(\beta^{\alpha-1})(\beta^{-1}x-\alpha)}{\Gamma(\alpha)\beta^{2\alpha}} \]
\[\Large 8: \frac{\partial f}{\partial \beta} = \frac{(x^{\alpha-1})(e^{-x/\beta})(\beta^{-1}x-\alpha)}{\Gamma(\alpha)\beta^{\alpha+1}} \]
\[\Large 9:\frac{\partial f}{\partial \beta} =\frac{(x^{\alpha-1})(e^{-x/\beta})(\beta^{-1}x-\alpha)(\beta^{-(\alpha+1)})}{\Gamma(\alpha)} \]
\[\Large 10:\frac{\partial f}{\partial \beta} = \frac{(x^{\alpha-1})(e^{-x/\beta})}{\Gamma(\alpha)}*\frac{(\beta^{-1}x-\alpha)*\beta^{-\alpha}*\beta^{-1}}{1} \]
\[\Large 11: \frac{\partial f}{\partial \beta} = \frac{(x^{\alpha-1})(e^{-x/\beta})}{\Gamma(\alpha)\beta^\alpha}*\frac{(\beta^{-1}x-\alpha)*\beta^{-1}}{1} \]
\[\Large 12: \frac{\partial f}{\partial \beta} = \frac{(x^{\alpha-1})(e^{-x/\beta})}{\Gamma(\alpha)\beta^\alpha}*\frac{\beta^{-2}x-\beta^{-1}\alpha}{1} \]
\[\Large 13: \frac{\partial f}{\partial \beta} = {\frac{(x^{\alpha-1})(e^{-x/\beta})}{\Gamma(\alpha)\beta^\alpha}}*[\frac{x}{\beta^2}-\frac{\alpha}{\beta}]\]
\[\Large 14: \frac{\partial f}{\partial \beta} =f(x | \alpha, \beta) *[\frac{x}{\beta^2}-\frac{\alpha}{\beta}] \]

Gradient Vector of Original Function

Each of these partial derivatives then compose the gradient vector of the original density function. The top component \(\frac{\partial f}{\partial \alpha}\) tell us how a change in alpha’s value will affect the value of x, assuming all other parameters (like \(\beta\)) remain constant. Additionally, the bottom component tell us analogous information regarding \(\beta\).

\[\Large \nabla f_{\alpha,\beta} = \begin{bmatrix} \frac{\partial f}{\partial \alpha} \\ \frac{\partial f}{\partial \beta} \end{bmatrix} = \begin{bmatrix} f(x|\alpha, \beta) * [ln(x)-ln(\beta)+\psi^{(0)}(\alpha)] \\ f(x | \alpha, \beta) *[\frac{x}{\beta^2}-\frac{\alpha}{\beta}] \end{bmatrix} \]



1a.) Log Likelihood Transformation

The likelihood function tells us how probable or ‘likely’ our parameter of interest (usually denoted as \(\theta\)) is equal to what we believe it is equal to given our observed data. It is mathematically defined as the product of each observation’s conditional probability operating under the assumption that \(\theta\) = \(\theta\). In this instance, since the value of x is conditional upon the values of \(\alpha\) and \(\beta\), the likelihood function is the following:

\[\Large L(\theta | x) = \prod_{i=1}^{n} f(x_i | \theta) = \prod_{i=1}^{n} f(\alpha_i, \beta_i | \theta). \]
Given that product series can be notoriously difficult to work with, the log-likelihood function is more often used for parameter estimation as logs transform multiplicative procedures into additional ones. The defining of the log-likelihood function for our original given PDF is below.

\[\Large 1: ln[L(\theta|x)] = \sum_{i=1}^{n} ln[f(x_i | \theta)] = \sum_{i=1}^{n} ln[f(\alpha_i, \beta_i | \theta)] \]


\[\Large 2: ln[f(\alpha_i, \beta_i | \theta)] = ln[x^{\alpha-1}e^{-x/\beta}]-ln[\Gamma(\alpha)\beta^\alpha]\]


\[\Large 3: ln[f(\alpha_i, \beta_i | \theta)] = ln[x^{\alpha-1}]+ln[e^{-x/\beta}]-ln[\Gamma(\alpha)]-ln[\beta^\alpha]\]


\[\Large 4: ln[f(\alpha_i, \beta_i | \theta)] = (\alpha-1)ln(x) - \frac{x}{\beta}-ln[\Gamma(\alpha)]-\alpha ln[\beta]\]


\[\Large 5: ln[L(\theta | x)] = \sum_{i=1}^{n} (\alpha_i-1)ln(x_i) - \frac{x_i}{\beta_i}-ln[\Gamma(\alpha_i)]-\alpha_i ln[\beta_i]\]

1b.) Log Likelihood Gradient Derivation

Just as I previously found the partial derivatives of the density function, now I will compose the gradient for the log-likelihood function. This will tell us how a change in either parameter of interest - \(\alpha\) or \(\beta\) - affects the log-likelihood of our targeted estimation parameter \(\theta\). Calculations and breakdowns are below.

Partial LOG Derivative W/ Respect to Alpha

\[\Large 1: ln[\frac{\partial f}{\partial \alpha}] = \frac{d}{d\alpha}[\alpha ln(x) - ln(x)] - \frac{d}{d\alpha}[ln[\Gamma(\alpha)]] - ln[\beta] \]


\[\Large 2: ln[\frac{\partial f}{\partial \alpha}] = ln(x) - ln[\beta] - \frac{d}{d\alpha}[ln[\Gamma(\alpha)]]\]


\[\Large 3: ln[\frac{\partial f}{\partial \alpha}] = ln(x) - ln[\beta] - \psi^{(0)}(\alpha)]\]

Partial LOG Derivative W/ Respect to Beta

\[\Large 1: ln[\frac{\partial f}{\partial \beta}] = \frac{d}{d\beta}[\frac{-x}{\beta} - \alpha ln[\beta]]\]


\[\Large 2: ln[\frac{\partial f}{\partial \beta}] = x\beta^{-1-1}-\alpha*\frac{1}{\beta}\]


\[\Large 3: ln[\frac{\partial f}{\partial \beta}] = \frac{x}{\beta^2}-\frac{\alpha}{\beta}\]

Gradient Vector of LOG Likelihood Function

\[\Large \nabla ln[f_{\alpha,\beta}] = \begin{bmatrix} ln[\frac{\partial f}{\partial \alpha}] \\ ln[\frac{\partial f}{\partial \beta}] \end{bmatrix} = \begin{bmatrix} [ln(x_i)-ln(\beta)+\psi^{(0)}(\alpha)] \\ [\frac{x_i}{\beta^2}-\frac{\alpha}{\beta}] \end{bmatrix} \]

2.) Birth Data

The available data we are examining is a sample of 95 womens’ time spent (hours) in the delivery suite while giving birth at John Radcliffe Hospital in Oxford, England. The study was conducted decades ago. For greater context, summary statistics and a histogram visualization of the sample distribution are below.

Births = 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)

Births_Data = data.frame(Births)
sum_stats_table = function(variable){
  table = cbind(
    round(min(variable),2),
    round(quantile(variable, 0.25),2),
    round(median(variable),2),
    round(mean(variable),2),
    round(quantile(variable, 0.75),2),
    round(max(variable),2)
  )
  colnames(table) = c("Min", "Q1", "Med", "Mean", "Q3", "Max")
  rownames(table) = NULL
  return(table)
}
  # I created a table for summary statistics of a variable, can use this moving forward instead of manually putting the summary stats in table form


Summary_Table = sum_stats_table(variable = Births)

kable(Summary_Table,align = "c",
      caption = "<span style='color:##000000;'>Summary Stats of Birth Times (Hours)</span>") %>%
  kable_styling(
    bootstrap_options = c("striped", "bordered"),
    full_width = FALSE,
    position = "center")
Summary Stats of Birth Times (Hours)
Min Q1 Med Mean Q3 Max
1.5 4.95 7.5 7.72 9.75 19
hist(Births, 
     main = "Distribution of Delivery Times",
     xlab = "Delivery Time (Hours)",
     ylab = "Count",
)
box(lwd=3)

2a.) Using MLE to Approximate Alpha and Beta

Operating under the assumption that the broader population of delivery times for women at said hospital at said time period is gamma distributed, we will utilize the log-likelihood gradient derived earlier to estimate \(\alpha\) and \(\beta\). These estimations will be denoted as \(\hat{\alpha}\) and \(\hat{\beta}\). Note that the process of MLE is simply setting a partial derivative equal to zero, and solving for the isolated parameter of interest (first \(\alpha\), and then \(\beta\) in this case).

## Optim Estimation Redo

 # note: in R, there is no ln function, but the log function defaults to natural log

# Code is modeled after section 5.2.2 in class notes

# Overall log likelihood
Gamma_LogLikelihood = function(parameters, data){
  alpha = parameters[1]
  beta = parameters[2]
  
  n = length(data)
  
  LogLike = (n * alpha * log(beta)) - 
    (n * log(gamma(alpha))) +
    (alpha - 1) * sum(log(data)) - 
       (beta * sum(data))
}
    # I originally made programming error of having x as a parameter in my function instead of simply summing the data


# Gradient Equations
Gamma_Gradient = function(parameters, data){
  alpha = parameters[1]
  beta = parameters[2]
  
  n = length(data)
  
  # Alpha Gradient
  alpha_grad = sum(log(data)) - (n*log(beta)) + (n*digamma(alpha))
    # Simply distribute the n through and use the sum function for all iterations of the "x" datapoint in our birthing dataset
  
  # Beta Gradient
  beta_grad = ((sum(data)/(beta^2)) - (n*(alpha/beta)))
  
  return(c(alpha_grad, beta_grad))  
}

Starting_Parameters = c(alpha = 3, beta = 3)
  # Arbitrarily setting starting parameters

MLE = optim(
  par = Starting_Parameters,
  fn = Gamma_LogLikelihood,
  gr = Gamma_Gradient,
  data = Births,
#  method = "L-BFGS-B",
  hessian = TRUE,
  control = list(trace = FALSE,
                 fnscale = -1,
                 maxit = 500,
                 abstol = 1e-8)
)

invisible(
  round(MLE$par[1],3) # alpha 
)

invisible(
  round(MLE$par[2],3) # beta 
)

Via R’s optim() function, I found an approximate value of 4.389 for \(\hat{\alpha}\) (our shape parameter) and 0.568 for \(\hat{\beta}\) (our rate parameter). For further confirmation of reasonable accuracy, I plotted a Gamma distribution with said parameter values alongside the distribution of the birthing times from our sample data.

hist(Births, 
     main = "Distribution of Delivery Times",
     xlab = "Delivery Time (Hours)",
     ylab = "Probability Density",
     ylim = c(0, 0.13),
     prob = TRUE
)

# alpha = shape
# beta = scale
curve(dgamma(x , shape = 4.3885430, rate = 0.5681101), 
      col = "red",
      lwd = 3,
      add = TRUE)

legend("topright",
       legend = "Gamma (4.389, 0.568)",
       col = "red",
       lwd = 3,
       box.lwd=3)

box(lwd=3)

2b.) Using Moment Estimation to Approximate Alpha and Beta

Alongside using MLE, I chose to additionally approximate \(\alpha\) and \(\beta\) via moment estimation. The estimated parameters found via this method will be denoted as \({\widetilde\alpha}\) and \({\widetilde\beta}\).

## kth moment of distribution = summing datasets values raised to kth power, and then dividing by n

moment1 = mean(Births) # = 7.723158
moment2 = mean(Births^2) # = 72.24447
variance = moment2 - (moment1^2) # = 12.59731

# mean of Gamma distribution is alpha/beta
# var of Gamma distribution is alpha/(beta^2)
  ### Formulas are for shape parameter alpha and rate parameter beta, there are other versions of Gamma notation

Per the general formula of moment estimation, the kth moment occurs when all of a datasets’ values are raised to the kth power, summed and then divided by the sample size, n. Combining that with the expected value and variance formulas specific to the Gamma distribution, we can create the system of equations below.

\[\Large Moment 1 = \frac{\alpha}{\beta} = \bar{x} \approx 7.723 \] \[\Large Moment 2 = \frac{\alpha^2}{\beta^2} = \bar{x^2} \approx 72.244 \]

\[\Large Var = \frac{\alpha}{\beta^2} = \bar{x^2} - [\bar{x}]^2 \approx 12.597 \]

Now using this system of equations, algebraic manipulation is performed to isolate and estimate the values of our parameters \(\alpha\) and \(\beta\).

\[\Large \frac{\alpha}{\beta^2} = \frac{1}{\beta} * \frac{\alpha}{\beta}\]

\[\Large \frac{var}{mean} = \frac{1}{\beta} \]

\[\Large \beta = \frac{\bar{x}}{\bar{x^2} - [\bar{x}]^2} \]

\[\Large \alpha = \bar{x} * \beta \]

mom_beta = moment1/variance
mom_alpha = moment1*mom_beta

invisible(
  round(mom_alpha,3)
)

invisible(
  round(mom_beta,3)
)

After performing all calculations, the moment estimations are the following; \({\widetilde\alpha}\) = 4.735 and \({\widetilde\beta}\) = 0.613. These estimates are very similar to those found via MLE in the previous section. For enhanced comparison, gamma curves with adherence to each estimation method’s outcomes are overlaid on top of our sample data below.

hist(Births, 
     main = "Distribution of Delivery Times",
     xlab = "Delivery Time (Hours)",
     ylab = "Probability Density",
     ylim = c(0, 0.13),
     prob = TRUE
)

# alpha = shape
# beta = scale
curve(dgamma(x , shape = 4.3885430, rate = 0.5681101), 
      col = "red",
      lwd = 3,
      add = TRUE)

curve(dgamma(x , shape = 4.734915, rate = 0.6130801), 
      col = "blue",
      lwd = 3,
      add = TRUE)

legend("topright",
       legend = c("MLE (4.389, 0.568)", "MOM (4.735, 0.613)"),
       col = c("red", "blue"),
       lwd = 3,
       box.lwd=3)

box(lwd=3)

2c.) Moment Estimation vs MLE

Broadly speaking, both moment estimation (MME) and maximum likelihood estimation (MLE) are fundamentally sound methods of estimating population parameters. MME consists of creating a system of equations with heavy reliance on the kth moment principle. MLE on the other hand involves finding partial derivatives of the log likelihood function, equating them to zero and calculating which value of \(\theta\) makes our sample data most probable.

With regards to accuracy, MLE is generally the preferable approach, yielding results with lower variance and less risk of biased influence. Moment estimation can be particularly vulnerable to bias when sample sizes are not sufficiently large. On the other hand, likelihood estimation requires we know the applicable density function and that the partial derivative of that function can be reasonably found.

To summarize, resorting to moment estimation is ideal when we do now know a population’s density function or said function’s partial derivative goes beyond standard calculus-based/numerical techniques. However, if the density function is readily available, then likelihood estimation is preferred due to its greater accuracy.

LS0tCnRpdGxlOiAiTWF4aW11bSBMaWtlbGlob29kIEVzdGltYXRpb24gKE1MRSkiCmF1dGhvcjogIkNocmlzIEJhaG0iCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiB0cnVlCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUKICAgIHRvY19kZXB0aDogNAogICAgZmlnX3dpZHRoOiA2CiAgICBmaWdfaGVpZ2h0OiA0CiAgICBmaWdfY2FwdGlvbjogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogbHVtZW4KICAgIGhpZ2hsaWdodDogdGFuZ28KICBwZGZfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogNAogICAgZmlnX2NhcHRpb246IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogIHdvcmRfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogNAotLS0KCmBgYHtjc3MsIGVjaG8gPSBGQUxTRX0KZGl2I1RPQyBsaSB7ICAgICAvKiB0YWJsZSBvZiBjb250ZW50ICAqLwogICAgbGlzdC1zdHlsZTp1cHBlci1yb21hbjsKICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsKICAgIGJhY2tncm91bmQtcmVwZWF0Om5vbmU7CiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7Cn0KCmgxLnRpdGxlIHsgICAgLyogbGV2ZWwgMSBoZWFkZXIgb2YgdGl0bGUgICovCiAgZm9udC1zaXplOiAyNHB4OwogIGZvbnQtd2VpZ2h0OiBib2xkOwogIGNvbG9yOiBEYXJrUmVkOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE4cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE4cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7CiAgY29sb3I6IERhcmtCbHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAyMHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE4cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE2cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE0cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLwouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7CiAgY29udGVudDogIi4iOwp9CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCAKIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuCgppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsgICAgICAgICAgICAgICAgICAgICAgIyB1c2UgY29uZGl0aW9uYWwgc3RhdGVtZW50IHRvIGRldGVjdAogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpICAgICAgICAgICAgICAgICAgIyB3aGV0aGVyIGEgcGFja2FnZSB3YXMgaW5zdGFsbGVkIGluCiAgIGxpYnJhcnkoa25pdHIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdXIgbWFjaGluZS4gSWYgbm90LCBpbnN0YWxsIGl0IGFuZAp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBsb2FkIGl0IHRvIHRoZSB3b3JraW5nIGRpcmVjdG9yeS4KCmlmICghcmVxdWlyZSh0aWR5dmVyc2UpKSB7bGlicmFyeSh0aWR5dnNlcnNlKX0gCgppZiAoIXJlcXVpcmUoR0dhbGx5KSkge2xpYnJhcnkoR0dhbGx5KX0gCgppZiAoIXJlcXVpcmUoa2FibGVFeHRyYSkpIHtsaWJyYXJ5KGthYmxlRXh0cmEpfSAKCmlmICghcmVxdWlyZShnZ3Bsb3QyKSkge2xpYnJhcnkoZ2dwbG90Mil9IAoKaWYgKCFyZXF1aXJlKGNhcikpIHtsaWJyYXJ5KGNhcil9IAoKaWYgKCFyZXF1aXJlKGRwbHlyKSkge2xpYnJhcnkoZHBseXIpfSAKCmlmICghcmVxdWlyZShwYW5kZXIpKSB7bGlicmFyeShwYW5kZXIpfSAKCmlmICghcmVxdWlyZShmb3JlY2FzdCkpIHtsaWJyYXJ5KGZvcmVjYXN0KX0gCgppZiAoIXJlcXVpcmUobHVicmlkYXRlKSkge2xpYnJhcnkobHVicmlkYXRlKX0gCgppZiAoIXJlcXVpcmUoInNjYWxlcyIpKSB7Cmluc3RhbGwucGFja2FnZXMoInNjYWxlcyIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApsaWJyYXJ5KCJzY2FsZXMiKSAKfQoKa25pdHI6Om9wdHNfY2h1bmskc2V0KAoJZWNobyA9IFRSVUUsCgltZXNzYWdlID0gRkFMU0UsCgl3YXJuaW5nID0gRkFMU0UsCgljb21tZW50ID0gTkEsCglyZXN1bHRzID0gVFJVRSwKCWZpZy5hbGlnbiA9ICJjZW50ZXIiCikKYGBgCgoKCiMgMS4pIEdyYWRpZW50IERlcml2YXRpb24KRm9yIHRoaXMgYW5hbHlzaXMgd2Ugd2lsbCBhc3N1bWUgdGhhdCBvdXIgcmFuZG9tIHZhcmlhYmxlIFggaXMgR2FtbWEgZGlzdHJpYnV0ZWQgYW5kIHRoZSBpbnN0YW5jZXMgd2hpY2ggbWFrZSB1cCBvdXIgcmFuZG9tIHNhbXBsZSBvZiB4IHJlc2VtYmxlIHRob3NlIGRpc3RyaWJ1dGl2ZSBjaGFyYWN0ZXJpc3RpY3MuIFRoZSBjb25kaXRpb25hbCBQREYgb2YgWCwgd2hvc2UgdmFsdWVzIGRlcGVuZCBvbiB0aGUgcGFyYW1ldGVycyBvZiB0aGUgR2FtbWEgRGlzdHJpYnV0aW9uIC0gJFxhbHBoYSQgdG8gcmVwcmVzZW50IHNoYXBlIGFuZCAkXGJldGEkIHRvIHJlcHJlc2VudCByYXRlIC0gaXMgd3JpdHRlbiBiZWxvdy4KCiQkXExhcmdlIGYoeCB8IFxhbHBoYSwgXGJldGEpID0gXGZyYWN7MX17XEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGF9eF57KFxhbHBoYS0xKX1lXnsoLXgvXGJldGEpfSBcaHNwYWNlezAuNWNtfXgsXGFscGhhLCBcYmV0YT4gMCAgJCQKVG8gcGVyZm9ybSB0aGUgcGFydGlhbCBkZXJpdmF0aW9ucyB0aHJvdWdob3V0IHRoaXMgYW5hbHlzaXMsIHN0YW5kYXJkIGRlcml2YXRpdmUgcnVsZXMgc3VjaCBhcyB0aGUgcG93ZXIsIHByb2R1Y3QgYW5kIHF1b3RpZW50IHJ1bGUgd2VyZSBoZWF2aWx5IHJlbGllZCB1cG9uLiBUaGUgcXVvdGllbnQgcnVsZSBpbiBwYXJ0aWN1bGFyIGFuZCB0aGUgbWFubmVyIGluIHdoaWNoIEkgdXNlZCBpdCBpcyBkZXBpY3RlZCBiZWxvdy4KCjxicj4KCiQkUXVvdGllbnQgXCBSdWxlIFwgPVxMYXJnZSBcZnJhY3tnKHgpaCcoeCktaCh4KWcnKHgpfXtbZyh4KV1eMn0kJAo8YnI+CiQkXExhcmdlIFxmcmFje2goeCkgPSB4XntcYWxwaGEtMX1lXnsteC9cYmV0YX19e2coeCkgPSBcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX0gJCQKCiMjIERlcml2YXRpb24gb24gT3JpZ2luYWwgRnVuY3Rpb24KVG8gZW5oYW5jZSBteSB1bmRlcnN0YW5kaW5nIG9mIGhvdyAkXGFscGhhJCBhbmQgJFxiZXRhJCBpbmRpdmlkdWFsbHkgaW1wYWN0IHRoZSB2YWx1ZSBvZiB4IGluIG91ciBkaXN0cmlidXRpb24sIEkgZm91bmQgdGhlIHJhdGUgb2YgY2hhbmdlIHRoYXQgZWFjaCBwYXJhbWV0ZXIgaXMgcmVzcGVjdGl2ZWx5IHJlc3BvbnNpYmxlIGZvciAoaWUgdGhlIHBhcnRpYWwgZGVyaXZhdGl2ZSBvciBzY29yZSBmdW5jdGlvbikuICAKCiMjIyBQYXJ0aWFsIERlcml2YXRpdmUgVy8gUmVzcGVjdCB0byBBbHBoYSAKCiQkXExhcmdlIDE6IFxmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxhbHBoYX0gPSBlXnsteC9cYmV0YX0qIFxmcmFje2R9e2RcYWxwaGF9W1xmcmFje3hee1xhbHBoYS0xfX17XEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGF9XSAgJCQKPGJyPgoKJCRcTGFyZ2UgMjogXGZyYWN7ZH17ZFxhbHBoYX1bXGZyYWN7eF57XGFscGhhLTF9fXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX1dID0gXGZyYWN7KFxHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhKVt4XntcYWxwaGEtMX1sbih4KV0tKHhee1xhbHBoYS0xfSkoXGZyYWN7ZH17ZFxhbHBoYX1bXEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGFdKX17W1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhKV1eMn0kJAo8YnI+CiQkXExhcmdlIDM6IFxmcmFje2R9e2RcYWxwaGF9W1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhXSA9IFxHYW1tYShcYWxwaGEpKlxiZXRhXlxhbHBoYSBsbihcYmV0YSkrXGJldGFeXGFscGhhKlxmcmFje2R9e2RcYWxwaGF9W1xHYW1tYShcYWxwaGEpXSAkJAo8YnI+CiQkXExhcmdlIDQ6IFxmcmFje2R9e2RcYWxwaGF9W1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhXSA9IFxHYW1tYShcYWxwaGEpKlxiZXRhXlxhbHBoYSBsbihcYmV0YSkrXEdhbW1hKFxhbHBoYSlccHNpXnsoMCl9KFxhbHBoYSkqXGJldGFeXGFscGhhJCQKPGJyPgokJFxMYXJnZSA1OiBcZnJhY3tkfXtkXGFscGhhfVtcZnJhY3t4XntcYWxwaGEtMX19e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfV0gPSBcZnJhY3soXEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGEpW3hee1xhbHBoYS0xfWxuKHgpXS0oeF57XGFscGhhLTF9KVtcR2FtbWEoXGFscGhhKSpcYmV0YV5cYWxwaGEgbG4oXGJldGEpK1xHYW1tYShcYWxwaGEpXHBzaV57KDApfShcYWxwaGEpKlxiZXRhXlxhbHBoYV19e1tcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYSldXjJ9JCQKPGJyPgokJFxMYXJnZSA2OiBcZnJhY3tkfXtkXGFscGhhfVtcZnJhY3t4XntcYWxwaGEtMX19e1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhfV0gPSBcZnJhY3t4XntcYWxwaGEtMX1bbG4oeCktbG4oXGJldGEpK1xwc2leeygwKX0oXGFscGhhKV19e1xHYW1tYShcYWxwaGEpKlxiZXRhXlxhbHBoYX0gJCQKPGJyPgpOb3cgbXVsdGlwbHkgY29uc3RhbnQgY29tcG9uZW50IHdpdGggZGVyaXZhdGl2ZSBjb21wb25lbnQKJCRcTGFyZ2UgNzogXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGFscGhhfSA9IGVeey14L1xiZXRhfSogXGZyYWN7ZH17ZFxhbHBoYX1bXGZyYWN7eF57XGFscGhhLTF9fXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX1dICAkJAoKPGJyPgokJFxMYXJnZSA4OiBcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYWxwaGF9ID0gXGZyYWN7ZV57LXgvXGJldGF9Knhee1xhbHBoYS0xfVtsbih4KS1sbihcYmV0YSkrXHBzaV57KDApfShcYWxwaGEpXX17XEdhbW1hKFxhbHBoYSkqXGJldGFeXGFscGhhfSAkJAo8YnI+CiQkXExhcmdlIDk6IFxmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxhbHBoYX0gPSBcZnJhY3t4XntcYWxwaGEtMX1lXnsteC9cYmV0YX19e1xHYW1tYShcYWxwaGEpKlxiZXRhXlxhbHBoYX0gKiBbbG4oeCktbG4oXGJldGEpK1xwc2leeygwKX0oXGFscGhhKV0gJCQKCjxicj4KJCRcTGFyZ2UgMTA6IFxmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxhbHBoYX0gPSBmKHh8XGFscGhhLCBcYmV0YSkgKiBbbG4oeCktbG4oXGJldGEpK1xwc2leeygwKX0oXGFscGhhKV0gJCQgCgojIyMgUGFydGlhbCBEZXJpdmF0aXZlIFcvIFJlc3BlY3QgdG8gQmV0YQo8YnI+CiQkXExhcmdlIDE6IFxmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxiZXRhfSA9IFxmcmFje3hee1xhbHBoYS0xfX17XEdhbW1hKFxhbHBoYSl9ICpcZnJhY3tkfXtkXGJldGF9W1xmcmFje2VeeygteC9cYmV0YSl9fXtcYmV0YV5cYWxwaGF9XSAgJCQKPGJyPgpJc29sYXRlIGRlcml2YXRpdmUgY29tcG9uZW50CiQkXExhcmdlIDI6IFxmcmFje2R9e2RcYmV0YX1bXGZyYWN7ZV57LXgvXGJldGF9fVxiZXRhXlxhbHBoYV0gPSBcZnJhY3tcYmV0YV5cYWxwaGEgKiBcZnJhY3tkfXtkXGJldGF9W2Veey14L1xiZXRhfV0tZV57LXgvXGJldGF9KlxmcmFje2R9e2RcYmV0YX1bXGJldGFeXGFscGhhXX17XGJldGFeezJcYWxwaGF9fSAkJAoKPGJyPgokJFxMYXJnZSAzOiBcZnJhY3tkfXtkXGJldGF9W1xmcmFje2Veey14L1xiZXRhfX1cYmV0YV5cYWxwaGFdID0gXGZyYWN7XGJldGFeXGFscGhhKlxmcmFjey14fXtcYmV0YV4yfSplXnsteC9cYmV0YX0tZV57LXgvXGJldGF9KlxhbHBoYVxiZXRhXntcYWxwaGEtMX19e1xiZXRhXnsyXGFscGhhfX0gJCQKCjxicj4KJCRcTGFyZ2UgNDogXGZyYWN7ZH17ZFxiZXRhfVtcZnJhY3tlXnsteC9cYmV0YX19e1xiZXRhXlxhbHBoYX1dID0gXGZyYWN7KFxiZXRhXntcYWxwaGEtMn0gKiB4KmVeey14L1xiZXRhfSktKGVeey14L1xiZXRhfSpcYWxwaGFcYmV0YV57XGFscGhhLTF9KX17XGJldGFeezJcYWxwaGF9fSAkJAoKPGJyPgpOb3cgbXVsdGlwbHkgY29uc3RhbnQgY29tcG9uZW50IHdpdGggZGVyaXZhdGl2ZSBjb21wb25lbnQKJCRcTGFyZ2UgNTogXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGJldGF9ID0gXGZyYWN7KHhee1xhbHBoYS0xfSlbXGJldGFee1xhbHBoYS0yfXhlXnsteC9cYmV0YX0tZV57LXgvXGJldGF9XGFscGhhXGJldGFee1xhbHBoYS0xfV19e1xHYW1tYShcYWxwaGEpXGJldGFeezJcYWxwaGF9fSQkCjxicj4KJCRcTGFyZ2UgNzogXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGJldGF9ID0gXGZyYWN7KHhee1xhbHBoYS0xfSkoZV57LXgvXGJldGF9KShcYmV0YV57XGFscGhhLTF9KShcYmV0YV57LTF9eC1cYWxwaGEpfXtcR2FtbWEoXGFscGhhKVxiZXRhXnsyXGFscGhhfX0gJCQKPGJyPgokJFxMYXJnZSA4OiBcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYmV0YX0gPSBcZnJhY3soeF57XGFscGhhLTF9KShlXnsteC9cYmV0YX0pKFxiZXRhXnstMX14LVxhbHBoYSl9e1xHYW1tYShcYWxwaGEpXGJldGFee1xhbHBoYSsxfX0gICQkCjxicj4KJCRcTGFyZ2UgOTpcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYmV0YX0gPVxmcmFjeyh4XntcYWxwaGEtMX0pKGVeey14L1xiZXRhfSkoXGJldGFeey0xfXgtXGFscGhhKShcYmV0YV57LShcYWxwaGErMSl9KX17XEdhbW1hKFxhbHBoYSl9ICQkCjxicj4KJCRcTGFyZ2UgMTA6XGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGJldGF9ID0gXGZyYWN7KHhee1xhbHBoYS0xfSkoZV57LXgvXGJldGF9KX17XEdhbW1hKFxhbHBoYSl9KlxmcmFjeyhcYmV0YV57LTF9eC1cYWxwaGEpKlxiZXRhXnstXGFscGhhfSpcYmV0YV57LTF9fXsxfSAkJAo8YnI+CiQkXExhcmdlIDExOiBcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYmV0YX0gPSBcZnJhY3soeF57XGFscGhhLTF9KShlXnsteC9cYmV0YX0pfXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX0qXGZyYWN7KFxiZXRhXnstMX14LVxhbHBoYSkqXGJldGFeey0xfX17MX0gJCQKPGJyPgokJFxMYXJnZSAxMjogXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGJldGF9ID0gXGZyYWN7KHhee1xhbHBoYS0xfSkoZV57LXgvXGJldGF9KX17XEdhbW1hKFxhbHBoYSlcYmV0YV5cYWxwaGF9KlxmcmFje1xiZXRhXnstMn14LVxiZXRhXnstMX1cYWxwaGF9ezF9ICQkCjxicj4KJCRcTGFyZ2UgMTM6IFxmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxiZXRhfSA9IHtcZnJhY3soeF57XGFscGhhLTF9KShlXnsteC9cYmV0YX0pfXtcR2FtbWEoXGFscGhhKVxiZXRhXlxhbHBoYX19KltcZnJhY3t4fXtcYmV0YV4yfS1cZnJhY3tcYWxwaGF9e1xiZXRhfV0kJAo8YnI+CiQkXExhcmdlIDE0OiBcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYmV0YX0gPWYoeCB8IFxhbHBoYSwgXGJldGEpICpbXGZyYWN7eH17XGJldGFeMn0tXGZyYWN7XGFscGhhfXtcYmV0YX1dICAgJCQKCiMjIyBHcmFkaWVudCBWZWN0b3Igb2YgT3JpZ2luYWwgRnVuY3Rpb24KRWFjaCBvZiB0aGVzZSBwYXJ0aWFsIGRlcml2YXRpdmVzIHRoZW4gY29tcG9zZSB0aGUgZ3JhZGllbnQgdmVjdG9yIG9mIHRoZSBvcmlnaW5hbCBkZW5zaXR5IGZ1bmN0aW9uLiBUaGUgdG9wIGNvbXBvbmVudCAkXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGFscGhhfSQgdGVsbCB1cyBob3cgYSBjaGFuZ2UgaW4gYWxwaGEncyB2YWx1ZSB3aWxsIGFmZmVjdCB0aGUgdmFsdWUgb2YgeCwgKmFzc3VtaW5nKiBhbGwgb3RoZXIgcGFyYW1ldGVycyAobGlrZSAkXGJldGEkKSByZW1haW4gY29uc3RhbnQuIEFkZGl0aW9uYWxseSwgdGhlIGJvdHRvbSBjb21wb25lbnQgdGVsbCB1cyBhbmFsb2dvdXMgaW5mb3JtYXRpb24gcmVnYXJkaW5nICRcYmV0YSQuCgokJFxMYXJnZSBcbmFibGEgZl97XGFscGhhLFxiZXRhfSAKPSBcYmVnaW57Ym1hdHJpeH0gXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGFscGhhfSBcXCBcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYmV0YX0gXGVuZHtibWF0cml4fSAKPSBcYmVnaW57Ym1hdHJpeH0gZih4fFxhbHBoYSwgXGJldGEpICogW2xuKHgpLWxuKFxiZXRhKStccHNpXnsoMCl9KFxhbHBoYSldIFxcIGYoeCB8IFxhbHBoYSwgXGJldGEpICpbXGZyYWN7eH17XGJldGFeMn0tXGZyYWN7XGFscGhhfXtcYmV0YX1dIFxlbmR7Ym1hdHJpeH0gJCQgCgo8YnI+Cjxicj4KCiMjIDFhLikgTG9nIExpa2VsaWhvb2QgVHJhbnNmb3JtYXRpb24gClRoZSBsaWtlbGlob29kIGZ1bmN0aW9uIHRlbGxzIHVzIGhvdyBwcm9iYWJsZSBvciAnbGlrZWx5JyBvdXIgcGFyYW1ldGVyIG9mIGludGVyZXN0ICh1c3VhbGx5IGRlbm90ZWQgYXMgJFx0aGV0YSQpIGlzIGVxdWFsIHRvIHdoYXQgd2UgYmVsaWV2ZSBpdCBpcyBlcXVhbCB0byBnaXZlbiBvdXIgb2JzZXJ2ZWQgZGF0YS4gSXQgaXMgbWF0aGVtYXRpY2FsbHkgZGVmaW5lZCBhcyB0aGUgcHJvZHVjdCBvZiBlYWNoIG9ic2VydmF0aW9uJ3MgY29uZGl0aW9uYWwgcHJvYmFiaWxpdHkgb3BlcmF0aW5nIHVuZGVyIHRoZSBhc3N1bXB0aW9uIHRoYXQgJFx0aGV0YSQgPSAkXHRoZXRhJC4gSW4gdGhpcyBpbnN0YW5jZSwgc2luY2UgdGhlIHZhbHVlIG9mIHggaXMgY29uZGl0aW9uYWwgdXBvbiB0aGUgdmFsdWVzIG9mICRcYWxwaGEkIGFuZCAkXGJldGEkLCB0aGUgbGlrZWxpaG9vZCBmdW5jdGlvbiBpcyB0aGUgZm9sbG93aW5nOgoKCiQkXExhcmdlICBMKFx0aGV0YSB8IHgpID0gXHByb2Rfe2k9MX1ee259IGYoeF9pIHwgXHRoZXRhKSA9IFxwcm9kX3tpPTF9XntufSBmKFxhbHBoYV9pLCBcYmV0YV9pIHwgXHRoZXRhKS4gJCQKPGJyPgpHaXZlbiB0aGF0IHByb2R1Y3Qgc2VyaWVzIGNhbiBiZSBub3RvcmlvdXNseSBkaWZmaWN1bHQgdG8gd29yayB3aXRoLCB0aGUgbG9nLWxpa2VsaWhvb2QgZnVuY3Rpb24gaXMgbW9yZSBvZnRlbiB1c2VkIGZvciBwYXJhbWV0ZXIgZXN0aW1hdGlvbiBhcyBsb2dzIHRyYW5zZm9ybSBtdWx0aXBsaWNhdGl2ZSBwcm9jZWR1cmVzIGludG8gYWRkaXRpb25hbCBvbmVzLiBUaGUgZGVmaW5pbmcgb2YgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uIGZvciBvdXIgb3JpZ2luYWwgZ2l2ZW4gUERGIGlzIGJlbG93LgoKJCRcTGFyZ2UgMTogbG5bTChcdGhldGF8eCldID0gXHN1bV97aT0xfV57bn0gbG5bZih4X2kgfCBcdGhldGEpXSA9IFxzdW1fe2k9MX1ee259IGxuW2YoXGFscGhhX2ksIFxiZXRhX2kgfCBcdGhldGEpXSAkJAoKPGJyPgokJFxMYXJnZSAyOiBsbltmKFxhbHBoYV9pLCBcYmV0YV9pIHwgXHRoZXRhKV0gPSBsblt4XntcYWxwaGEtMX1lXnsteC9cYmV0YX1dLWxuW1xHYW1tYShcYWxwaGEpXGJldGFeXGFscGhhXSQkCgo8YnI+CiQkXExhcmdlIDM6IGxuW2YoXGFscGhhX2ksIFxiZXRhX2kgfCBcdGhldGEpXSA9IGxuW3hee1xhbHBoYS0xfV0rbG5bZV57LXgvXGJldGF9XS1sbltcR2FtbWEoXGFscGhhKV0tbG5bXGJldGFeXGFscGhhXSQkCgo8YnI+CiQkXExhcmdlIDQ6IGxuW2YoXGFscGhhX2ksIFxiZXRhX2kgfCBcdGhldGEpXSA9IChcYWxwaGEtMSlsbih4KSAtIFxmcmFje3h9e1xiZXRhfS1sbltcR2FtbWEoXGFscGhhKV0tXGFscGhhIGxuW1xiZXRhXSQkCgo8YnI+CiQkXExhcmdlIDU6IGxuW0woXHRoZXRhIHwgeCldID0gXHN1bV97aT0xfV57bn0gKFxhbHBoYV9pLTEpbG4oeF9pKSAtIFxmcmFje3hfaX17XGJldGFfaX0tbG5bXEdhbW1hKFxhbHBoYV9pKV0tXGFscGhhX2kgbG5bXGJldGFfaV0kJAoKCiMjIDFiLikgTG9nIExpa2VsaWhvb2QgR3JhZGllbnQgRGVyaXZhdGlvbgpKdXN0IGFzIEkgcHJldmlvdXNseSBmb3VuZCB0aGUgcGFydGlhbCBkZXJpdmF0aXZlcyBvZiB0aGUgZGVuc2l0eSBmdW5jdGlvbiwgbm93IEkgd2lsbCBjb21wb3NlIHRoZSBncmFkaWVudCBmb3IgdGhlIGxvZy1saWtlbGlob29kIGZ1bmN0aW9uLiBUaGlzIHdpbGwgdGVsbCB1cyBob3cgYSBjaGFuZ2UgaW4gZWl0aGVyIHBhcmFtZXRlciBvZiBpbnRlcmVzdCAtICRcYWxwaGEkIG9yICRcYmV0YSQgLSBhZmZlY3RzIHRoZSBsb2ctbGlrZWxpaG9vZCBvZiBvdXIgdGFyZ2V0ZWQgZXN0aW1hdGlvbiBwYXJhbWV0ZXIgJFx0aGV0YSQuIENhbGN1bGF0aW9ucyBhbmQgYnJlYWtkb3ducyBhcmUgYmVsb3cuCgojIyMgUGFydGlhbCBMT0cgRGVyaXZhdGl2ZSBXLyBSZXNwZWN0IHRvIEFscGhhIAoKJCRcTGFyZ2UgMTogbG5bXGZyYWN7XHBhcnRpYWwgZn17XHBhcnRpYWwgXGFscGhhfV0gPSBcZnJhY3tkfXtkXGFscGhhfVtcYWxwaGEgbG4oeCkgLSBsbih4KV0gLSBcZnJhY3tkfXtkXGFscGhhfVtsbltcR2FtbWEoXGFscGhhKV1dIC0gbG5bXGJldGFdICAkJAoKPGJyPgokJFxMYXJnZSAyOiBsbltcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYWxwaGF9XSA9IGxuKHgpIC0gbG5bXGJldGFdIC0gXGZyYWN7ZH17ZFxhbHBoYX1bbG5bXEdhbW1hKFxhbHBoYSldXSQkCgo8YnI+CiQkXExhcmdlIDM6IGxuW1xmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxhbHBoYX1dID0gbG4oeCkgLSBsbltcYmV0YV0gLSBccHNpXnsoMCl9KFxhbHBoYSldJCQKCiMjIyBQYXJ0aWFsIExPRyBEZXJpdmF0aXZlIFcvIFJlc3BlY3QgdG8gQmV0YQogCiQkXExhcmdlIDE6IGxuW1xmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxiZXRhfV0gPSBcZnJhY3tkfXtkXGJldGF9W1xmcmFjey14fXtcYmV0YX0gLSBcYWxwaGEgbG5bXGJldGFdXSQkCgo8YnI+CiQkXExhcmdlIDI6IGxuW1xmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxiZXRhfV0gPSB4XGJldGFeey0xLTF9LVxhbHBoYSpcZnJhY3sxfXtcYmV0YX0kJAoKPGJyPgokJFxMYXJnZSAzOiBsbltcZnJhY3tccGFydGlhbCBmfXtccGFydGlhbCBcYmV0YX1dID0gXGZyYWN7eH17XGJldGFeMn0tXGZyYWN7XGFscGhhfXtcYmV0YX0kJAoKIyMgR3JhZGllbnQgVmVjdG9yIG9mIExPRyBMaWtlbGlob29kIEZ1bmN0aW9uCgokJFxMYXJnZSBcbmFibGEgbG5bZl97XGFscGhhLFxiZXRhfV0gCj0gXGJlZ2lue2JtYXRyaXh9IGxuW1xmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxhbHBoYX1dIFxcIGxuW1xmcmFje1xwYXJ0aWFsIGZ9e1xwYXJ0aWFsIFxiZXRhfV0gXGVuZHtibWF0cml4fSAKPSBcYmVnaW57Ym1hdHJpeH0gW2xuKHhfaSktbG4oXGJldGEpK1xwc2leeygwKX0oXGFscGhhKV0gXFwgW1xmcmFje3hfaX17XGJldGFeMn0tXGZyYWN7XGFscGhhfXtcYmV0YX1dIFxlbmR7Ym1hdHJpeH0gJCQgCgoKIyAyLikgQmlydGggRGF0YQpUaGUgYXZhaWxhYmxlIGRhdGEgd2UgYXJlIGV4YW1pbmluZyBpcyBhIHNhbXBsZSBvZiA5NSB3b21lbnMnIHRpbWUgc3BlbnQgKGhvdXJzKSBpbiB0aGUgZGVsaXZlcnkgc3VpdGUgd2hpbGUgZ2l2aW5nIGJpcnRoIGF0IEpvaG4gUmFkY2xpZmZlIEhvc3BpdGFsIGluIE94Zm9yZCwgRW5nbGFuZC4gVGhlIHN0dWR5IHdhcyBjb25kdWN0ZWQgZGVjYWRlcyBhZ28uIEZvciBncmVhdGVyIGNvbnRleHQsIHN1bW1hcnkgc3RhdGlzdGljcyBhbmQgYSBoaXN0b2dyYW0gdmlzdWFsaXphdGlvbiBvZiB0aGUgc2FtcGxlIGRpc3RyaWJ1dGlvbiBhcmUgYmVsb3cuCgpgYGB7ciwgZmlnLmhlaWdodD01LjUsIGZpZy53aWR0aD02LjV9CkJpcnRocyA9IGMoMi4xLCAzLjQsIDQuMjUsIDUuNiwgNi40LCA3LjMsIDguNSwgOC43NSwgOC45LCA5LjUsIDkuNzUsIDEwLCAxMC40LCAxMC40LCAxNiwgMTksCjQsIDQuMSwgNSwgNS41LCA1LjcsIDYuNSwgNy4yNSwgNy4zLCA3LjUsIDguMiwgOC41LCA5Ljc1LCAxMSwgMTEuMiwgMTUsIDE2LjUsIDIuNiwgCjMuNiwgMy42LCA2LjQsIDYuOCwgNy41LCA3LjUsIDguMjUsIDguNSwgMTAuNCwgMTAuNzUsIDE0LjI1LCAxNC41LCAxLjUsIDQuNywgNC43LCAKNy4yLCA3LjI1LCA4LjEsIDguNSwgOS4yLCA5LjUsIDEwLjcsIDExLjUsIDIuNSwgMi41LCAzLjQsIDQuMiwgNS45LCA2LjI1LCA3LjMsIDcuNSwgCjcuOCwgOC4zLCA4LjMsIDEwLjI1LCAxMi45LCAxNC4zLCA0LCA0LCA1LjI1LCA2LjEsIDYuNSwgNi45LCA3LCA4LjQ1LCA5LjI1LCAxMC4xLCAKMTAuMiwgMTIuNzUsIDE0LjYsIDIsIDIuNywgMi43NSwgMy40LCA0LjIsIDQuMywgNC45LCA2LjI1LCA3LCA5LCA5LjI1LCAxMC43KQoKQmlydGhzX0RhdGEgPSBkYXRhLmZyYW1lKEJpcnRocykKc3VtX3N0YXRzX3RhYmxlID0gZnVuY3Rpb24odmFyaWFibGUpewogIHRhYmxlID0gY2JpbmQoCiAgICByb3VuZChtaW4odmFyaWFibGUpLDIpLAogICAgcm91bmQocXVhbnRpbGUodmFyaWFibGUsIDAuMjUpLDIpLAogICAgcm91bmQobWVkaWFuKHZhcmlhYmxlKSwyKSwKICAgIHJvdW5kKG1lYW4odmFyaWFibGUpLDIpLAogICAgcm91bmQocXVhbnRpbGUodmFyaWFibGUsIDAuNzUpLDIpLAogICAgcm91bmQobWF4KHZhcmlhYmxlKSwyKQogICkKICBjb2xuYW1lcyh0YWJsZSkgPSBjKCJNaW4iLCAiUTEiLCAiTWVkIiwgIk1lYW4iLCAiUTMiLCAiTWF4IikKICByb3duYW1lcyh0YWJsZSkgPSBOVUxMCiAgcmV0dXJuKHRhYmxlKQp9CiAgIyBJIGNyZWF0ZWQgYSB0YWJsZSBmb3Igc3VtbWFyeSBzdGF0aXN0aWNzIG9mIGEgdmFyaWFibGUsIGNhbiB1c2UgdGhpcyBtb3ZpbmcgZm9yd2FyZCBpbnN0ZWFkIG9mIG1hbnVhbGx5IHB1dHRpbmcgdGhlIHN1bW1hcnkgc3RhdHMgaW4gdGFibGUgZm9ybQoKClN1bW1hcnlfVGFibGUgPSBzdW1fc3RhdHNfdGFibGUodmFyaWFibGUgPSBCaXJ0aHMpCgprYWJsZShTdW1tYXJ5X1RhYmxlLGFsaWduID0gImMiLAogICAgICBjYXB0aW9uID0gIjxzcGFuIHN0eWxlPSdjb2xvcjojIzAwMDAwMDsnPlN1bW1hcnkgU3RhdHMgb2YgQmlydGggVGltZXMgKEhvdXJzKTwvc3Bhbj4iKSAlPiUKICBrYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImJvcmRlcmVkIiksCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICBwb3NpdGlvbiA9ICJjZW50ZXIiKQoKaGlzdChCaXJ0aHMsIAogICAgIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIERlbGl2ZXJ5IFRpbWVzIiwKICAgICB4bGFiID0gIkRlbGl2ZXJ5IFRpbWUgKEhvdXJzKSIsCiAgICAgeWxhYiA9ICJDb3VudCIsCikKYm94KGx3ZD0zKQpgYGAKCiMjIDJhLikgVXNpbmcgTUxFIHRvIEFwcHJveGltYXRlIEFscGhhIGFuZCBCZXRhCk9wZXJhdGluZyB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSBicm9hZGVyIHBvcHVsYXRpb24gb2YgZGVsaXZlcnkgdGltZXMgZm9yIHdvbWVuIGF0IHNhaWQgaG9zcGl0YWwgYXQgc2FpZCB0aW1lIHBlcmlvZCBpcyBnYW1tYSBkaXN0cmlidXRlZCwgd2Ugd2lsbCB1dGlsaXplIHRoZSBsb2ctbGlrZWxpaG9vZCBncmFkaWVudCBkZXJpdmVkIGVhcmxpZXIgdG8gZXN0aW1hdGUgJFxhbHBoYSQgYW5kICRcYmV0YSQuIFRoZXNlIGVzdGltYXRpb25zIHdpbGwgYmUgZGVub3RlZCBhcyAkXGhhdHtcYWxwaGF9JCBhbmQgJFxoYXR7XGJldGF9JC4gTm90ZSB0aGF0IHRoZSBwcm9jZXNzIG9mIE1MRSBpcyBzaW1wbHkgc2V0dGluZyBhIHBhcnRpYWwgZGVyaXZhdGl2ZSBlcXVhbCB0byB6ZXJvLCBhbmQgc29sdmluZyBmb3IgdGhlIGlzb2xhdGVkIHBhcmFtZXRlciBvZiBpbnRlcmVzdCAoZmlyc3QgJFxhbHBoYSQsIGFuZCB0aGVuICRcYmV0YSQgaW4gdGhpcyBjYXNlKS4KCmBgYHtyfQojIyBPcHRpbSBFc3RpbWF0aW9uIFJlZG8KCiAjIG5vdGU6IGluIFIsIHRoZXJlIGlzIG5vIGxuIGZ1bmN0aW9uLCBidXQgdGhlIGxvZyBmdW5jdGlvbiBkZWZhdWx0cyB0byBuYXR1cmFsIGxvZwoKIyBDb2RlIGlzIG1vZGVsZWQgYWZ0ZXIgc2VjdGlvbiA1LjIuMiBpbiBjbGFzcyBub3RlcwoKIyBPdmVyYWxsIGxvZyBsaWtlbGlob29kCkdhbW1hX0xvZ0xpa2VsaWhvb2QgPSBmdW5jdGlvbihwYXJhbWV0ZXJzLCBkYXRhKXsKICBhbHBoYSA9IHBhcmFtZXRlcnNbMV0KICBiZXRhID0gcGFyYW1ldGVyc1syXQogIAogIG4gPSBsZW5ndGgoZGF0YSkKICAKICBMb2dMaWtlID0gKG4gKiBhbHBoYSAqIGxvZyhiZXRhKSkgLSAKICAgIChuICogbG9nKGdhbW1hKGFscGhhKSkpICsKICAgIChhbHBoYSAtIDEpICogc3VtKGxvZyhkYXRhKSkgLSAKICAgICAgIChiZXRhICogc3VtKGRhdGEpKQp9CiAgICAjIEkgb3JpZ2luYWxseSBtYWRlIHByb2dyYW1taW5nIGVycm9yIG9mIGhhdmluZyB4IGFzIGEgcGFyYW1ldGVyIGluIG15IGZ1bmN0aW9uIGluc3RlYWQgb2Ygc2ltcGx5IHN1bW1pbmcgdGhlIGRhdGEKCgojIEdyYWRpZW50IEVxdWF0aW9ucwpHYW1tYV9HcmFkaWVudCA9IGZ1bmN0aW9uKHBhcmFtZXRlcnMsIGRhdGEpewogIGFscGhhID0gcGFyYW1ldGVyc1sxXQogIGJldGEgPSBwYXJhbWV0ZXJzWzJdCiAgCiAgbiA9IGxlbmd0aChkYXRhKQogIAogICMgQWxwaGEgR3JhZGllbnQKICBhbHBoYV9ncmFkID0gc3VtKGxvZyhkYXRhKSkgLSAobipsb2coYmV0YSkpICsgKG4qZGlnYW1tYShhbHBoYSkpCiAgICAjIFNpbXBseSBkaXN0cmlidXRlIHRoZSBuIHRocm91Z2ggYW5kIHVzZSB0aGUgc3VtIGZ1bmN0aW9uIGZvciBhbGwgaXRlcmF0aW9ucyBvZiB0aGUgIngiIGRhdGFwb2ludCBpbiBvdXIgYmlydGhpbmcgZGF0YXNldAogIAogICMgQmV0YSBHcmFkaWVudAogIGJldGFfZ3JhZCA9ICgoc3VtKGRhdGEpLyhiZXRhXjIpKSAtIChuKihhbHBoYS9iZXRhKSkpCiAgCiAgcmV0dXJuKGMoYWxwaGFfZ3JhZCwgYmV0YV9ncmFkKSkgIAp9CgpTdGFydGluZ19QYXJhbWV0ZXJzID0gYyhhbHBoYSA9IDMsIGJldGEgPSAzKQogICMgQXJiaXRyYXJpbHkgc2V0dGluZyBzdGFydGluZyBwYXJhbWV0ZXJzCgpNTEUgPSBvcHRpbSgKICBwYXIgPSBTdGFydGluZ19QYXJhbWV0ZXJzLAogIGZuID0gR2FtbWFfTG9nTGlrZWxpaG9vZCwKICBnciA9IEdhbW1hX0dyYWRpZW50LAogIGRhdGEgPSBCaXJ0aHMsCiMgIG1ldGhvZCA9ICJMLUJGR1MtQiIsCiAgaGVzc2lhbiA9IFRSVUUsCiAgY29udHJvbCA9IGxpc3QodHJhY2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICBmbnNjYWxlID0gLTEsCiAgICAgICAgICAgICAgICAgbWF4aXQgPSA1MDAsCiAgICAgICAgICAgICAgICAgYWJzdG9sID0gMWUtOCkKKQoKaW52aXNpYmxlKAogIHJvdW5kKE1MRSRwYXJbMV0sMykgIyBhbHBoYSAKKQoKaW52aXNpYmxlKAogIHJvdW5kKE1MRSRwYXJbMl0sMykgIyBiZXRhIAopCmBgYApWaWEgUidzIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+b3B0aW0oKTwvc3Bhbj4gZnVuY3Rpb24sIEkgZm91bmQgYW4gYXBwcm94aW1hdGUgdmFsdWUgb2YgYHIgcm91bmQoTUxFJHBhclsxXSwzKWAgZm9yICRcaGF0e1xhbHBoYX0kIChvdXIgc2hhcGUgcGFyYW1ldGVyKSBhbmQgYHIgcm91bmQoTUxFJHBhclsyXSwzKWAgZm9yICRcaGF0e1xiZXRhfSQgKG91ciByYXRlIHBhcmFtZXRlcikuIEZvciBmdXJ0aGVyIGNvbmZpcm1hdGlvbiBvZiByZWFzb25hYmxlIGFjY3VyYWN5LCBJIHBsb3R0ZWQgYSBHYW1tYSBkaXN0cmlidXRpb24gd2l0aCBzYWlkIHBhcmFtZXRlciB2YWx1ZXMgYWxvbmdzaWRlIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIGJpcnRoaW5nIHRpbWVzIGZyb20gb3VyIHNhbXBsZSBkYXRhLgoKCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02LjV9Cmhpc3QoQmlydGhzLCAKICAgICBtYWluID0gIkRpc3RyaWJ1dGlvbiBvZiBEZWxpdmVyeSBUaW1lcyIsCiAgICAgeGxhYiA9ICJEZWxpdmVyeSBUaW1lIChIb3VycykiLAogICAgIHlsYWIgPSAiUHJvYmFiaWxpdHkgRGVuc2l0eSIsCiAgICAgeWxpbSA9IGMoMCwgMC4xMyksCiAgICAgcHJvYiA9IFRSVUUKKQoKIyBhbHBoYSA9IHNoYXBlCiMgYmV0YSA9IHNjYWxlCmN1cnZlKGRnYW1tYSh4ICwgc2hhcGUgPSA0LjM4ODU0MzAsIHJhdGUgPSAwLjU2ODExMDEpLCAKICAgICAgY29sID0gInJlZCIsCiAgICAgIGx3ZCA9IDMsCiAgICAgIGFkZCA9IFRSVUUpCgpsZWdlbmQoInRvcHJpZ2h0IiwKICAgICAgIGxlZ2VuZCA9ICJHYW1tYSAoNC4zODksIDAuNTY4KSIsCiAgICAgICBjb2wgPSAicmVkIiwKICAgICAgIGx3ZCA9IDMsCiAgICAgICBib3gubHdkPTMpCgpib3gobHdkPTMpCmBgYAoKIyMgMmIuKSBVc2luZyBNb21lbnQgRXN0aW1hdGlvbiB0byBBcHByb3hpbWF0ZSBBbHBoYSBhbmQgQmV0YQpBbG9uZ3NpZGUgdXNpbmcgTUxFLCBJIGNob3NlIHRvIGFkZGl0aW9uYWxseSBhcHByb3hpbWF0ZSAkXGFscGhhJCBhbmQgJFxiZXRhJCB2aWEgbW9tZW50IGVzdGltYXRpb24uIFRoZSBlc3RpbWF0ZWQgcGFyYW1ldGVycyBmb3VuZCB2aWEgdGhpcyBtZXRob2Qgd2lsbCBiZSBkZW5vdGVkIGFzICR7XHdpZGV0aWxkZVxhbHBoYX0kIGFuZCAke1x3aWRldGlsZGVcYmV0YX0kLgoKYGBge3J9CiMjIGt0aCBtb21lbnQgb2YgZGlzdHJpYnV0aW9uID0gc3VtbWluZyBkYXRhc2V0cyB2YWx1ZXMgcmFpc2VkIHRvIGt0aCBwb3dlciwgYW5kIHRoZW4gZGl2aWRpbmcgYnkgbgoKbW9tZW50MSA9IG1lYW4oQmlydGhzKSAjID0gNy43MjMxNTgKbW9tZW50MiA9IG1lYW4oQmlydGhzXjIpICMgPSA3Mi4yNDQ0Nwp2YXJpYW5jZSA9IG1vbWVudDIgLSAobW9tZW50MV4yKSAjID0gMTIuNTk3MzEKCiMgbWVhbiBvZiBHYW1tYSBkaXN0cmlidXRpb24gaXMgYWxwaGEvYmV0YQojIHZhciBvZiBHYW1tYSBkaXN0cmlidXRpb24gaXMgYWxwaGEvKGJldGFeMikKICAjIyMgRm9ybXVsYXMgYXJlIGZvciBzaGFwZSBwYXJhbWV0ZXIgYWxwaGEgYW5kIHJhdGUgcGFyYW1ldGVyIGJldGEsIHRoZXJlIGFyZSBvdGhlciB2ZXJzaW9ucyBvZiBHYW1tYSBub3RhdGlvbgoKCmBgYApQZXIgdGhlIGdlbmVyYWwgZm9ybXVsYSBvZiBtb21lbnQgZXN0aW1hdGlvbiwgdGhlICprdGgqIG1vbWVudCBvY2N1cnMgd2hlbiBhbGwgb2YgYSBkYXRhc2V0cycgdmFsdWVzIGFyZSByYWlzZWQgdG8gdGhlICprdGgqIHBvd2VyLCBzdW1tZWQgYW5kIHRoZW4gZGl2aWRlZCBieSB0aGUgc2FtcGxlIHNpemUsIG4uIENvbWJpbmluZyB0aGF0IHdpdGggdGhlIGV4cGVjdGVkIHZhbHVlIGFuZCB2YXJpYW5jZSBmb3JtdWxhcyBzcGVjaWZpYyB0byB0aGUgR2FtbWEgZGlzdHJpYnV0aW9uLCB3ZSBjYW4gY3JlYXRlIHRoZSBzeXN0ZW0gb2YgZXF1YXRpb25zIGJlbG93LgoKCiQkXExhcmdlIE1vbWVudCAxID0gXGZyYWN7XGFscGhhfXtcYmV0YX0gPSAgXGJhcnt4fSBcYXBwcm94IGByIHJvdW5kKG1vbWVudDEsMylgICAkJAokJFxMYXJnZSBNb21lbnQgMiA9IFxmcmFje1xhbHBoYV4yfXtcYmV0YV4yfSA9ICBcYmFye3heMn0gXGFwcHJveCBgciByb3VuZChtb21lbnQyLDMpYCAgJCQKCiQkXExhcmdlIFZhciA9IFxmcmFje1xhbHBoYX17XGJldGFeMn0gPSBcYmFye3heMn0gLSBbXGJhcnt4fV1eMiAgXGFwcHJveCBgciByb3VuZCh2YXJpYW5jZSwzKWAgJCQKCk5vdyB1c2luZyB0aGlzIHN5c3RlbSBvZiBlcXVhdGlvbnMsIGFsZ2VicmFpYyBtYW5pcHVsYXRpb24gaXMgcGVyZm9ybWVkIHRvIGlzb2xhdGUgYW5kIGVzdGltYXRlIHRoZSB2YWx1ZXMgb2Ygb3VyIHBhcmFtZXRlcnMgJFxhbHBoYSQgYW5kICRcYmV0YSQuCgokJFxMYXJnZSBcZnJhY3tcYWxwaGF9e1xiZXRhXjJ9ID0gXGZyYWN7MX17XGJldGF9ICogXGZyYWN7XGFscGhhfXtcYmV0YX0kJAoKJCRcTGFyZ2UgXGZyYWN7dmFyfXttZWFufSA9IFxmcmFjezF9e1xiZXRhfSAkJAoKJCRcTGFyZ2UgXGJldGEgPSBcZnJhY3tcYmFye3h9fXtcYmFye3heMn0gLSBbXGJhcnt4fV1eMn0gJCQKCiQkXExhcmdlIFxhbHBoYSA9IFxiYXJ7eH0gKiBcYmV0YSAkJAoKYGBge3J9Cm1vbV9iZXRhID0gbW9tZW50MS92YXJpYW5jZQptb21fYWxwaGEgPSBtb21lbnQxKm1vbV9iZXRhCgppbnZpc2libGUoCiAgcm91bmQobW9tX2FscGhhLDMpCikKCmludmlzaWJsZSgKICByb3VuZChtb21fYmV0YSwzKQopCgpgYGAKQWZ0ZXIgcGVyZm9ybWluZyBhbGwgY2FsY3VsYXRpb25zLCB0aGUgbW9tZW50IGVzdGltYXRpb25zIGFyZSB0aGUgZm9sbG93aW5nOyAke1x3aWRldGlsZGVcYWxwaGF9JCA9IGByIHJvdW5kKG1vbV9hbHBoYSwzKWAgYW5kICR7XHdpZGV0aWxkZVxiZXRhfSQgPSBgciByb3VuZChtb21fYmV0YSwzKWAuIFRoZXNlIGVzdGltYXRlcyBhcmUgdmVyeSBzaW1pbGFyIHRvIHRob3NlIGZvdW5kIHZpYSBNTEUgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24uIEZvciBlbmhhbmNlZCBjb21wYXJpc29uLCBnYW1tYSBjdXJ2ZXMgd2l0aCBhZGhlcmVuY2UgdG8gZWFjaCBlc3RpbWF0aW9uIG1ldGhvZCdzIG91dGNvbWVzIGFyZSBvdmVybGFpZCBvbiB0b3Agb2Ygb3VyIHNhbXBsZSBkYXRhIGJlbG93LiAKCgpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Ni41fQpoaXN0KEJpcnRocywgCiAgICAgbWFpbiA9ICJEaXN0cmlidXRpb24gb2YgRGVsaXZlcnkgVGltZXMiLAogICAgIHhsYWIgPSAiRGVsaXZlcnkgVGltZSAoSG91cnMpIiwKICAgICB5bGFiID0gIlByb2JhYmlsaXR5IERlbnNpdHkiLAogICAgIHlsaW0gPSBjKDAsIDAuMTMpLAogICAgIHByb2IgPSBUUlVFCikKCiMgYWxwaGEgPSBzaGFwZQojIGJldGEgPSBzY2FsZQpjdXJ2ZShkZ2FtbWEoeCAsIHNoYXBlID0gNC4zODg1NDMwLCByYXRlID0gMC41NjgxMTAxKSwgCiAgICAgIGNvbCA9ICJyZWQiLAogICAgICBsd2QgPSAzLAogICAgICBhZGQgPSBUUlVFKQoKY3VydmUoZGdhbW1hKHggLCBzaGFwZSA9IDQuNzM0OTE1LCByYXRlID0gMC42MTMwODAxKSwgCiAgICAgIGNvbCA9ICJibHVlIiwKICAgICAgbHdkID0gMywKICAgICAgYWRkID0gVFJVRSkKCmxlZ2VuZCgidG9wcmlnaHQiLAogICAgICAgbGVnZW5kID0gYygiTUxFICg0LjM4OSwgMC41NjgpIiwgIk1PTSAoNC43MzUsIDAuNjEzKSIpLAogICAgICAgY29sID0gYygicmVkIiwgImJsdWUiKSwKICAgICAgIGx3ZCA9IDMsCiAgICAgICBib3gubHdkPTMpCgpib3gobHdkPTMpCmBgYAoKIyMgMmMuKSBNb21lbnQgRXN0aW1hdGlvbiB2cyBNTEUKQnJvYWRseSBzcGVha2luZywgYm90aCBtb21lbnQgZXN0aW1hdGlvbiAoTU1FKSBhbmQgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gKE1MRSkgYXJlIGZ1bmRhbWVudGFsbHkgc291bmQgbWV0aG9kcyBvZiBlc3RpbWF0aW5nIHBvcHVsYXRpb24gcGFyYW1ldGVycy4gTU1FIGNvbnNpc3RzIG9mIGNyZWF0aW5nIGEgc3lzdGVtIG9mIGVxdWF0aW9ucyB3aXRoIGhlYXZ5IHJlbGlhbmNlIG9uIHRoZSAqa3RoKiBtb21lbnQgcHJpbmNpcGxlLiBNTEUgb24gdGhlIG90aGVyIGhhbmQgaW52b2x2ZXMgZmluZGluZyBwYXJ0aWFsIGRlcml2YXRpdmVzIG9mIHRoZSBsb2cgbGlrZWxpaG9vZCBmdW5jdGlvbiwgZXF1YXRpbmcgdGhlbSB0byB6ZXJvIGFuZCBjYWxjdWxhdGluZyB3aGljaCB2YWx1ZSBvZiAkXHRoZXRhJCBtYWtlcyBvdXIgc2FtcGxlIGRhdGEgbW9zdCBwcm9iYWJsZS4KCldpdGggcmVnYXJkcyB0byBhY2N1cmFjeSwgTUxFIGlzIGdlbmVyYWxseSB0aGUgcHJlZmVyYWJsZSBhcHByb2FjaCwgeWllbGRpbmcgcmVzdWx0cyB3aXRoIGxvd2VyIHZhcmlhbmNlIGFuZCBsZXNzIHJpc2sgb2YgYmlhc2VkIGluZmx1ZW5jZS4gTW9tZW50IGVzdGltYXRpb24gY2FuIGJlIHBhcnRpY3VsYXJseSB2dWxuZXJhYmxlIHRvIGJpYXMgd2hlbiBzYW1wbGUgc2l6ZXMgYXJlIG5vdCBzdWZmaWNpZW50bHkgbGFyZ2UuIE9uIHRoZSBvdGhlciBoYW5kLCBsaWtlbGlob29kIGVzdGltYXRpb24gcmVxdWlyZXMgd2Uga25vdyB0aGUgYXBwbGljYWJsZSBkZW5zaXR5IGZ1bmN0aW9uIGFuZCB0aGF0IHRoZSBwYXJ0aWFsIGRlcml2YXRpdmUgb2YgdGhhdCBmdW5jdGlvbiBjYW4gYmUgcmVhc29uYWJseSBmb3VuZC4KClRvIHN1bW1hcml6ZSwgcmVzb3J0aW5nIHRvIG1vbWVudCBlc3RpbWF0aW9uIGlzIGlkZWFsIHdoZW4gd2UgZG8gbm93IGtub3cgYSBwb3B1bGF0aW9uJ3MgZGVuc2l0eSBmdW5jdGlvbiBvciBzYWlkIGZ1bmN0aW9uJ3MgcGFydGlhbCBkZXJpdmF0aXZlIGdvZXMgYmV5b25kIHN0YW5kYXJkIGNhbGN1bHVzLWJhc2VkL251bWVyaWNhbCB0ZWNobmlxdWVzLiBIb3dldmVyLCBpZiB0aGUgZGVuc2l0eSBmdW5jdGlvbiBpcyByZWFkaWx5IGF2YWlsYWJsZSwgdGhlbiBsaWtlbGlob29kIGVzdGltYXRpb24gaXMgcHJlZmVycmVkIGR1ZSB0byBpdHMgZ3JlYXRlciBhY2N1cmFjeS4KCgo=