What Is Autocorrelation?
Write our regression model as
\[Y_t = \mu_t + \varepsilon_t, \qquad
\mu_t = \mathbf{x}_t^\top\boldsymbol{\beta}.\]
The predictors in \(\mathbf{x}_t\)
describe the mean. Autocorrelation describes a relationship between
errors at different times, after accounting for that mean.
We cannot observe \(\varepsilon_t\),
because we do not know the true mean. We work with the fitted
residuals
\[e_t = y_t -
\widehat{\mu}_t.\]
A high \(R^2\) describes how closely
the fitted values track the responses. It does not tell us whether the
remaining deviations are related through time.
What Does a Lag Mean?
Lag \(k\) means a
separation of \(k\) observation
intervals. For quarterly data, lag 1 is one quarter and lag 4 is one
year. The observations must be equally spaced for this
interpretation.
Suppose the errors have constant variance \(\sigma^2\) and their covariance depends on
the time gap, rather than the calendar date. Then
\[\rho_k =
\operatorname{Corr}(\varepsilon_t,\varepsilon_{t-k})
=
\frac{\operatorname{Cov}(\varepsilon_t,\varepsilon_{t-k})}{\sigma^2}.\]
- \(\rho_1 > 0\): nearby errors
tend to have the same sign, producing persistent runs.
- \(\rho_1 < 0\): nearby errors
tend to alternate in sign.
- Independent errors have \(\rho_k =
0\) for every \(k > 0\). Zero
correlation alone does not establish independence.
A Classical Example: Consumer Expenditure and Money Stock
This example studies consumer expenditure (ConsExp) and
the stock of money (MoneyStk) in billions of US
dollars.
Download MoneyStock.csv
MoneyStock <- read.csv("../data/MoneyStock.csv", header = TRUE)
MoneyStock |>
head() |>
kable()
| 1952 |
1 |
214.6 |
159.3 |
1952.00 |
| 1952 |
2 |
217.7 |
161.2 |
1952.25 |
| 1952 |
3 |
219.6 |
162.8 |
1952.50 |
| 1952 |
4 |
227.2 |
164.6 |
1952.75 |
| 1953 |
1 |
230.9 |
165.9 |
1953.00 |
| 1953 |
2 |
233.3 |
167.9 |
1953.25 |
pairs(MoneyStock[3:5])

Fit the Regression Model
For quarter \(t\), we fit
\[\mathrm{ConsExp}_t = \beta_0 +
\beta_1\mathrm{MoneyStk}_t + \varepsilon_t.\]
MoneyStock_lm1 <- lm(ConsExp ~ MoneyStk, data = MoneyStock)
summary(MoneyStock_lm1)
Call:
lm(formula = ConsExp ~ MoneyStk, data = MoneyStock)
Residuals:
Min 1Q Median 3Q Max
-7.176 -3.396 1.396 2.928 6.361
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -154.7192 19.8500 -7.794 3.54e-07 ***
MoneyStk 2.3004 0.1146 20.080 8.99e-14 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 3.983 on 18 degrees of freedom
Multiple R-squared: 0.9573, Adjusted R-squared: 0.9549
F-statistic: 403.2 on 1 and 18 DF, p-value: 8.988e-14
MoneyStk and ConsExp have a strong linear
association: \(R^2\) is about 0.96. The
reported slope also looks precise. That precision calculation assumes
that knowing the error in one quarter tells us nothing about another
quarter’s error.
Residual Plot Over Time
Before running a test, follow the residuals from left to right. Look
for stretches above or below zero, alternation, and any remaining trend
or seasonal pattern.
plot(residuals(MoneyStock_lm1), type = "b", ylab = "Residuals", xlab = "Quarter")
abline(h = 0, lty = 2)

The residuals wander slowly above and below zero. Adjacent quarters
often have deviations in the same direction. Some runs occur by chance
even with independent errors; we need to judge whether this much
persistence is plausible.
Why Dependence Changes Precision
Start with a simpler calculation. Suppose two observations measure
the same mean \(\mu\), each with error
variance \(\sigma^2\) and correlation
\(\rho\). Their average has
variance
\[\begin{aligned}
\operatorname{Var}\left(\frac{Y_1+Y_2}{2}\right)
&= \frac{1}{4}\left[\operatorname{Var}(Y_1)+\operatorname{Var}(Y_2)
+2\operatorname{Cov}(Y_1,Y_2)\right] \\
&= \frac{\sigma^2}{2}(1+\rho).
\end{aligned}\]
With independent errors, \(\rho=0\)
and averaging halves the variance. With \(\rho=0.8\), the variance is \(0.9\sigma^2\): the second observation adds
little precision because the two errors tend to move together.
The standard error is then \(\sqrt{1.8}\approx1.34\) times the value
calculated under independence. Counting two observations does not give
us two independent pieces of information.
What Changes in Regression?
Remember the matrix form \(\mathbf{Y}=X\boldsymbol{\beta}+\boldsymbol{\varepsilon}\).
Treating \(X\) as fixed, let \(\Sigma=\operatorname{Var}(\boldsymbol{\varepsilon}\mid
X)\). The OLS estimate still satisfies
\[\widehat{\boldsymbol{\beta}}=\boldsymbol{\beta}+(X^\top
X)^{-1}X^\top\boldsymbol{\varepsilon}.\]
Its variance is
\[\operatorname{Var}(\widehat{\boldsymbol{\beta}}\mid
X)
=(X^\top X)^{-1}X^\top\Sigma X(X^\top X)^{-1}.\]
Independent errors with equal variance give \(\Sigma=\sigma^2 I\), reducing this to \(\sigma^2(X^\top X)^{-1}\). Autocorrelation
introduces non-zero off-diagonal covariances into \(\Sigma\).
If \(E(\boldsymbol{\varepsilon}\mid
X)=\mathbf{0}\), OLS remains unbiased. The usual standard errors
can still be wrong, so the reported confidence intervals and tests
become unreliable. For regression coefficients, the direction of that
error depends on both the predictors and the dependence pattern.
Runs Test
A run is an uninterrupted sequence on the same side
of a threshold. For example, \(+++\;--\;++\;-\) contains four runs,
although it contains eight observations.
The default RunsTest()
divides numerical residuals at their median. Write \(n_+\) for the number above the median and
\(n_-\) for the number at or below it.
Under random ordering, the expected number of runs is
\[E(R)=1+\frac{2n_+n_-}{n_++n_-}.\]
Too few runs indicate clustering on the same side; too many indicate
excessive alternation. The test compares the observed count with its
distribution under random ordering.
Runs in the MoneyStock Residuals
There are ten residuals on each side of the median, so under random
ordering we expect
\[E(R)=1+\frac{2(10)(10)}{20}=11\text{
runs}.\]
RunsTest(residuals(MoneyStock_lm1))
Runs Test for Randomness
data: residuals(MoneyStock_lm1)
runs = 5, m = 10, n = 10, p-value = 0.008985
alternative hypothesis: true number of runs is not equal the expected number
sample estimates:
median(x)
1.395704
We observe only five runs, with \(P\approx0.009\). This supports the
impression of long stretches on the same side. The default test is
two-sided, so it can detect either unusually few or unusually many runs.
It does not measure the size of the residuals or identify the process
producing them.
Durbin-Watson Test
Runs use only which side each residual falls on. Durbin-Watson uses
the sizes of the changes between neighbouring residuals:
\[d=\frac{\sum_{t=2}^{n}(e_t-e_{t-1})^2}{\sum_{t=1}^{n}e_t^2}.\]
The denominator measures the overall residual variation. The
numerator measures how much residuals change from one observation to the
next.
- Positive autocorrelation gives small neighbouring differences, so
\(d\) tends towards 0.
- With no lag-1 autocorrelation, \(d\) is typically near 2.
- Negative autocorrelation gives larger neighbouring differences, so
\(d\) tends towards 4.
These values guide interpretation; they are not significance
cut-offs.
Durbin-Watson for MoneyStock
We test \(H_0:\rho_1=0\) against
\(H_A:\rho_1>0\). The one-sided
alternative targets the positive autocorrelation suggested by the time
plot.
dwtest(MoneyStock_lm1, alternative = "greater")
Durbin-Watson test
data: MoneyStock_lm1
DW = 0.32821, p-value = 2.303e-08
alternative hypothesis: true autocorrelation is greater than 0
The statistic is \(d\approx0.33\),
with a very small P-value. The residuals change much less between
adjacent quarters than we would expect from their overall variation.
In dwtest(),
alternative = "greater" refers to correlation greater than
zero. Evidence for that alternative comes from a small
value of \(d\). The test’s reference
distribution accounts for the regression predictors; we do not simply
declare every value below 2 significant.
Measuring Correlation at Each Lag
Durbin-Watson focuses on neighbouring observations. The
autocorrelation function (ACF) lets us examine longer gaps as well. The
sample
autocorrelation at lag \(k\) is
\[r_k=\frac{\sum_{t=k+1}^{n}(e_t-\bar
e)(e_{t-k}-\bar e)}
{\sum_{t=1}^{n}(e_t-\bar e)^2}.\]
The numerator pairs residuals \(k\)
observations apart. Products are positive when both deviations from
\(\bar e\) have the same sign, and
negative when they have opposite signs. The denominator puts the result
on a correlation scale. Lag 0 is always 1.
For OLS with an intercept, \(\bar
e=0\) apart from numerical rounding. Expanding the squared
differences in Durbin-Watson then gives
\[d=2(1-r_1)-\frac{e_1^2+e_n^2}{\sum_{t=1}^{n}e_t^2}
\approx2(1-r_1).\]
The approximation drops the two endpoint terms. It can be noticeably
different in a short series, so use it to understand the direction of
\(d\), rather than to replace the
calculation.
ACF Plot
acf(residuals(MoneyStock_lm1), main = "ACF of MoneyStock residuals")

The lag-1 value is about 0.75, and positive correlation persists
across several quarters. This agrees with the slow movement in the time
plot. We should also check whether a missing time trend could explain
part of it.
Reading the ACF Reference Lines
Under an uncorrelated white-noise reference model, the default
approximate 95% reference limits at an individual non-zero lag are
\[\pm\frac{1.96}{\sqrt n}.\]
Here \(n=20\), giving limits of
about \(\pm0.44\). The lag-1
correlation is well outside them. A sequence of large correlations
deserves more attention than one isolated bar just beyond a line.
These are approximate, pointwise limits, not a simultaneous 95% band
for the whole plot. With many lags, some bars can cross by chance.
Fitting the regression also affects the behaviour of its residuals, so
treat the lines as a visual reference. The acf()
plotting documentation describes the white-noise assumption behind
them.
Ljung-Box Test
If several ACF bars look large, we can combine them. For a chosen
maximum lag \(m\), the hypotheses
are
\[H_0:\rho_1=\cdots=\rho_m=0, \qquad
H_A:\text{at least one of these correlations is non-zero}.\]
The Ljung-Box
statistic is
\[Q=n(n+2)\sum_{k=1}^{m}\frac{r_k^2}{n-k}.\]
Squaring prevents positive and negative correlations from cancelling.
Larger correlations give a larger \(Q\)
and more evidence against the null hypothesis. Choose \(m\) using the time scale and the available
sample size, before inspecting a collection of P-values.
Ljung-Box for MoneyStock
Here we use \(m=10\), combining
correlations over gaps from one to ten quarters.
Box.test(residuals(MoneyStock_lm1), lag = 10, type = "Ljung-Box")
Box-Ljung test
data: residuals(MoneyStock_lm1)
X-squared = 64.397, df = 10, p-value = 5.286e-10
We obtain \(Q\approx64.4\) and a
very small P-value. With the default fitdf = 0, Box.test()
compares this with an approximate \(\chi^2_{10}\) distribution.
There are only 20 observations here, and the residuals come from an
estimated regression, so treat that P-value as an approximate diagnostic
summary. The time plot, runs test and Durbin-Watson already give
substantial evidence of persistence. This result does not establish that
every lag is correlated or tell us which change to the model will
address it.
Work Through the Diagnostics
1. If \(d=0.6\),
what lag-1 correlation does \(d\approx2(1-r_1)\) suggest?
. . .
Rearranging gives \(r_1\approx1-d/2=0.7\), suggesting strong
positive correlation between neighbours. This is an approximation, not a
P-value.
. . .
2. If \(r_1=0\) but
\(r_4\) is large, which diagnostic
displays that pattern, and which can test a group of lags containing
it?
. . .
The ACF displays the lag-4 correlation. Ljung-Box with \(m\geq4\) includes it in a joint test; a
lag-1 diagnostic alone can miss it.
. . .
3. Why would shuffling complete rows of MoneyStock
leave the coefficients and \(R^2\)
unchanged but alter the residual diagnostics?
. . .
OLS minimises the same sum of squares after reordering. Runs,
neighbouring differences and lagged products depend on which
observations follow one another, so the diagnostics need the actual time
order.
A Modern Comparison: Seoul Bike Residuals
The same diagnostic logic applies to the richer daily bike model from
Lectures 32/33, which combined two Fourier pairs with the time trend and
weather predictors.
Download seoul_bike_daily.csv
seoul_daily <- read_csv("../data/seoul_bike_daily.csv", show_col_types = FALSE) |>
mutate(date = as.Date(date)) |>
arrange(date) |>
filter(functioning_day_all == "yes") |>
mutate(S1 = sin(2 * pi * day_index/365), C1 = cos(2 * pi * day_index/365), S2 = sin(4 *
pi * day_index/365), C2 = cos(4 * pi * day_index/365))
seoul_mean <- lm(rented_bike_count ~ day_index + S1 + C1 + S2 + C2 + mean_temperature +
total_rainfall + total_solar_radiation, data = seoul_daily)
seoul_diagnostics <- seoul_daily |>
mutate(residual = residuals(seoul_mean))
We fitted the mean model to all 352 functioning days. The dates
remain visible here, including the gaps left by 13 outage days.
Seoul: One Uninterrupted Period
For the daily diagnostics, select the longest uninterrupted period: 1
December 2017 through 10 April 2018. Otherwise, an ordinary ACF would
treat consecutive retained rows as though they were always one day
apart.
Refit the same mean formula on these 131 consecutive
days. All four diagnostics below use residuals from this refitted model,
so the Durbin-Watson test and the other summaries refer to the same
observations and fit.
seoul_run_data <- seoul_daily |>
filter(date >= as.Date("2017-12-01"), date <= as.Date("2018-04-10"))
seoul_run_model <- update(seoul_mean, data = seoul_run_data)
seoul_run_residuals <- residuals(seoul_run_model)
Seoul: Durbin-Watson
Use the sizes of the changes between consecutive daily residuals:
\[d=\frac{\sum_{t=2}^{n}(e_t-e_{t-1})^2}{\sum_{t=1}^{n}e_t^2}
=\frac{609135793}{453162261}
\approx 1.34.\]
seoul_dw <- dwtest(seoul_run_model, alternative = "greater")
seoul_dw
Durbin-Watson test
data: seoul_run_model
DW = 1.3442, p-value = 7.693e-06
alternative hypothesis: true autocorrelation is greater than 0
The statistic is below 2, with strong evidence against \(H_0:\rho_1=0\) in favour of positive
autocorrelation. Unlike the runs test, Durbin-Watson uses how far
neighbouring residuals move, as well as their direction.
Seoul: ACF of the Daily Residuals
acf(seoul_run_residuals, main = "ACF of Seoul residuals: refitted on consecutive days")

The lag-1 correlation is \(r_1\approx
0.327\). The approximate pointwise reference limits are
\[\pm\frac{1.96}{\sqrt{131}}\approx\pm
0.171.\]
Neighbouring daily residuals remain positively correlated after
refitting the mean. Read the other lags from the plot as well; the
reference lines are approximate and do not form a simultaneous band.
Seoul: Ljung-Box Across Two Weeks
Combine the correlations at lags 1 through 14, rather than testing
only neighbouring days:
\[Q=n(n+2)\sum_{k=1}^{14}\frac{r_k^2}{n-k}.\]
seoul_ljung_box <- Box.test(seoul_run_residuals, lag = 14, type = "Ljung-Box")
The small P-value gives evidence of remaining autocorrelation across
these lags. It does not imply that every lag is correlated. This is an
approximate diagnostic on fitted regression residuals, using the default
fitdf = 0.
The runs test gave weaker evidence because it discarded residual
magnitudes. Taken together, the time plot, Durbin-Watson, ACF and
Ljung-Box suggest that refitting the mean has not removed the
dependence. These results concern the 131-day fit, rather than
establishing adequacy over the entire gappy year.
Diagnostic Summary
The time plot comes first, then the ACF. The runs test, Durbin-Watson
and Ljung-Box each summarise a different feature of the ordered
residuals, so a collection of small P-values supports what we can
already see in the plots. None of them identifies the error process that
produced the pattern.
Before changing the error model, check the mean: a missing trend,
seasonal term or outage can leave a residual pattern of its own. For
both MoneyStock and Seoul we fitted reasonable mean models and the
dependence remained, so we treat it as part of the errors and model it
directly.
Looking Ahead
Every model we have fitted this semester assumed independent errors.
Flexible curves, factors and weights changed the mean or the variance;
the correlation between errors never entered the model. After this
lecture we know how to detect that correlation, and in MoneyStock and
Seoul it is clearly there.
Next lecture we model it. An AR(1) error model, fitted by generalised
least squares (GLS), keeps the mean formula and adds a correlation
structure to the errors instead. We will fit the tourism model with
gls() and corAR1(), compare the standard
errors with the ordinary fit, and check whether the normalised residuals
look closer to white noise.
LS0tDQp0aXRsZTogIkxlY3R1cmUgMzQ6IERpYWdub3NpbmcgQXV0b2NvcnJlbGF0ZWQgRXJyb3JzIg0Kc3VidGl0bGU6IDE2MS4yNTEgUmVncmVzc2lvbiBNb2RlbGxpbmcNCmF1dGhvcjogIlByZXNlbnRlZCBieSBOaWNrIEtub3dsdG9uIDxOLktub3dsdG9uQG1hc3NleS5hYy5uej4iICANCmRhdGU6ICJXZWVrIDEyIG9mIFNlbWVzdGVyIDIsIGByIGx1YnJpZGF0ZTo6eWVhcihsdWJyaWRhdGU6Om5vdygpKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0X3N0eWxlOiBweWdtZW50cw0KICBodG1sX25vdGVib29rOg0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodF9zdHlsZTogcHlnbWVudHMNCiAgaW9zbGlkZXNfcHJlc2VudGF0aW9uOg0KICAgIHdpZGVzY3JlZW46IHRydWUNCiAgICBzbWFsbGVyOiB0cnVlDQogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgc2xpZHlfcHJlc2VudGF0aW9uOiANCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodF9zdHlsZTogcHlnbWVudHMNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KDQoNCg0KPCEtLS0gRGF0YSBpcyBvbg0KaHR0cHM6Ly9yLXJlc291cmNlcy5tYXNzZXkuYWMubnovZGF0YS8xNjEyNTEvDQotLS0+DQoNCmBgYHtyIHNldHVwLCBwdXJsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCm9wdHNfY2h1bmskc2V0KGRldj1jKCJwbmciLCAicGRmIikpDQpvcHRzX2NodW5rJHNldChmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD03LCBmaWcucGF0aD0iRmlndXJlcy8iLCBmaWcuYWx0PSJ1bmxhYmVsbGVkIikNCm9wdHNfY2h1bmskc2V0KGNvbW1lbnQ9IiIsIGZpZy5hbGlnbj0iY2VudGVyIiwgdGlkeT1UUlVFKQ0Kb3B0aW9ucyhrbml0ci5rYWJsZS5OQSA9ICcnKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGJyb29tKQ0KYGBgDQoNCg0KPCEtLS0gRG8gbm90IGVkaXQgYW55dGhpbmcgYWJvdmUgdGhpcyBsaW5lLiAtLS0+DQoNCmBgYHtyIGRpYWdub3NpbmctYXV0b2NvcnJlbGF0aW9uLXNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShEZXNjVG9vbHMpDQpsaWJyYXJ5KGxtdGVzdCkNCmBgYA0KDQojIyBEaWFnbm9zaW5nIEF1dG9jb3JyZWxhdGVkIEVycm9ycw0KDQpJbiBMZWN0dXJlcyAzMi8zMyB3ZSB1c2VkIHRyZW5kLCBzZWFzb25hbCB0ZXJtcyBhbmQgd2VhdGhlciBwcmVkaWN0b3JzIHRvIGV4cGxhaW4gdGhlIG1lYW4gcmVzcG9uc2UgdGhyb3VnaCB0aW1lLiBBIGZpdHRlZCBjdXJ2ZSBjYW4gZm9sbG93IHRoZSBkYXRhIHF1aXRlIGNsb3NlbHkgYW5kIHN0aWxsIGxlYXZlIHNldmVyYWwgY29uc2VjdXRpdmUgb2JzZXJ2YXRpb25zIGFib3ZlIGl0LCBmb2xsb3dlZCBieSBzZXZlcmFsIGJlbG93IGl0Lg0KDQpJZiB0b2RheSdzIHJlc3BvbnNlIGlzIGhpZ2hlciB0aGFuIHRoZSBtb2RlbCBwcmVkaWN0cywgZG9lcyB0aGF0IHRlbGwgdXMgYW55dGhpbmcgYWJvdXQgdG9tb3Jyb3cncyBkZXZpYXRpb24/IElmIGl0IGRvZXMsIHRyZWF0aW5nIHRob3NlIG9ic2VydmF0aW9ucyBhcyBpbmRlcGVuZGVudCBnaXZlcyB1cyB0aGUgd3JvbmcgY2FsY3VsYXRpb24gb2YgcHJlY2lzaW9uLg0KDQpCeSB0aGUgZW5kIG9mIHRoaXMgbGVjdHVyZSwgc3R1ZGVudHMgc2hvdWxkIGJlIGFibGUgdG86DQoNCjEuIERlZmluZSBsYWdnZWQgYXV0b2NvcnJlbGF0aW9uIGFuZCBkaXN0aW5ndWlzaCBlcnJvcnMgZnJvbSByZXNpZHVhbHMuDQoyLiBVc2UgYSB2YXJpYW5jZSBjYWxjdWxhdGlvbiB0byBleHBsYWluIHdoeSBkZXBlbmRlbmNlIGNoYW5nZXMgcHJlY2lzaW9uLg0KMy4gRXhwbGFpbiBhbmQgdXNlIHJlc2lkdWFsIHBsb3RzLCBydW5zIHRlc3RzLCBEdXJiaW4tV2F0c29uLCBBQ0YgcGxvdHMsIGFuZCBManVuZy1Cb3ggdGVzdHMuDQo0LiBSZWNvZ25pc2Ugd2hlbiBkZXBlbmRlbmNlIHJlbWFpbnMgYWZ0ZXIgYSByZWFzb25hYmxlIG1lYW4gbW9kZWwgaGFzIGJlZW4gZml0dGVkLg0KDQojIyBXaGF0IElzIEF1dG9jb3JyZWxhdGlvbj8NCg0KV3JpdGUgb3VyIHJlZ3Jlc3Npb24gbW9kZWwgYXMNCg0KJCRZX3QgPSBcbXVfdCArIFx2YXJlcHNpbG9uX3QsIFxxcXVhZCBcbXVfdCA9IFxtYXRoYmZ7eH1fdF5cdG9wXGJvbGRzeW1ib2x7XGJldGF9LiQkDQoNClRoZSBwcmVkaWN0b3JzIGluICRcbWF0aGJme3h9X3QkIGRlc2NyaWJlIHRoZSBtZWFuLiBBdXRvY29ycmVsYXRpb24gZGVzY3JpYmVzIGEgcmVsYXRpb25zaGlwIGJldHdlZW4gZXJyb3JzIGF0IGRpZmZlcmVudCB0aW1lcywgYWZ0ZXIgYWNjb3VudGluZyBmb3IgdGhhdCBtZWFuLg0KDQpXZSBjYW5ub3Qgb2JzZXJ2ZSAkXHZhcmVwc2lsb25fdCQsIGJlY2F1c2Ugd2UgZG8gbm90IGtub3cgdGhlIHRydWUgbWVhbi4gV2Ugd29yayB3aXRoIHRoZSBmaXR0ZWQgcmVzaWR1YWxzDQoNCiQkZV90ID0geV90IC0gXHdpZGVoYXR7XG11fV90LiQkDQoNCkEgaGlnaCAkUl4yJCBkZXNjcmliZXMgaG93IGNsb3NlbHkgdGhlIGZpdHRlZCB2YWx1ZXMgdHJhY2sgdGhlIHJlc3BvbnNlcy4gSXQgZG9lcyBub3QgdGVsbCB1cyB3aGV0aGVyIHRoZSByZW1haW5pbmcgZGV2aWF0aW9ucyBhcmUgcmVsYXRlZCB0aHJvdWdoIHRpbWUuDQoNCiMjIFdoYXQgRG9lcyBhIExhZyBNZWFuPw0KDQoqKkxhZyAkayQqKiBtZWFucyBhIHNlcGFyYXRpb24gb2YgJGskIG9ic2VydmF0aW9uIGludGVydmFscy4gRm9yIHF1YXJ0ZXJseSBkYXRhLCBsYWcgMSBpcyBvbmUgcXVhcnRlciBhbmQgbGFnIDQgaXMgb25lIHllYXIuIFRoZSBvYnNlcnZhdGlvbnMgbXVzdCBiZSBlcXVhbGx5IHNwYWNlZCBmb3IgdGhpcyBpbnRlcnByZXRhdGlvbi4NCg0KU3VwcG9zZSB0aGUgZXJyb3JzIGhhdmUgY29uc3RhbnQgdmFyaWFuY2UgJFxzaWdtYV4yJCBhbmQgdGhlaXIgY292YXJpYW5jZSBkZXBlbmRzIG9uIHRoZSB0aW1lIGdhcCwgcmF0aGVyIHRoYW4gdGhlIGNhbGVuZGFyIGRhdGUuIFRoZW4NCg0KJCRccmhvX2sgPSBcb3BlcmF0b3JuYW1le0NvcnJ9KFx2YXJlcHNpbG9uX3QsXHZhcmVwc2lsb25fe3Qta30pDQo9IFxmcmFje1xvcGVyYXRvcm5hbWV7Q292fShcdmFyZXBzaWxvbl90LFx2YXJlcHNpbG9uX3t0LWt9KX17XHNpZ21hXjJ9LiQkDQoNCi0gJFxyaG9fMSA+IDAkOiBuZWFyYnkgZXJyb3JzIHRlbmQgdG8gaGF2ZSB0aGUgc2FtZSBzaWduLCBwcm9kdWNpbmcgcGVyc2lzdGVudCBydW5zLg0KLSAkXHJob18xIDwgMCQ6IG5lYXJieSBlcnJvcnMgdGVuZCB0byBhbHRlcm5hdGUgaW4gc2lnbi4NCi0gSW5kZXBlbmRlbnQgZXJyb3JzIGhhdmUgJFxyaG9fayA9IDAkIGZvciBldmVyeSAkayA+IDAkLiBaZXJvIGNvcnJlbGF0aW9uIGFsb25lIGRvZXMgbm90IGVzdGFibGlzaCBpbmRlcGVuZGVuY2UuDQoNCiMjIEEgQ2xhc3NpY2FsIEV4YW1wbGU6IENvbnN1bWVyIEV4cGVuZGl0dXJlIGFuZCBNb25leSBTdG9jaw0KDQpUaGlzIGV4YW1wbGUgc3R1ZGllcyBjb25zdW1lciBleHBlbmRpdHVyZSAoYENvbnNFeHBgKSBhbmQgdGhlIHN0b2NrIG9mIG1vbmV5IChgTW9uZXlTdGtgKSBpbiBiaWxsaW9ucyBvZiBVUyBkb2xsYXJzLg0KDQpgciB4ZnVuOjplbWJlZF9maWxlKCIuLi9kYXRhL01vbmV5U3RvY2suY3N2IilgDQoNCjo6Ojogey5jb2x1bW5zIC5tb25leS1zdG9jay1sYXlvdXR9DQo6Ojogey5jb2x1bW4gc3R5bGU9IndpZHRoOiAxMDAlOyJ9DQoNCmBgYHtyIHJlYWQtbW9uZXktc3RvY2t9DQpNb25leVN0b2NrIDwtIHJlYWQuY3N2KCIuLi9kYXRhL01vbmV5U3RvY2suY3N2IiwgaGVhZGVyID0gVFJVRSkNCk1vbmV5U3RvY2sgfD4gaGVhZCgpIHw+IGthYmxlKCkNCmBgYA0KDQo6OjoNCg0KOjo6IHsuY29sdW1uIHN0eWxlPSJ3aWR0aDogMTAwJTsifQ0KDQpgYGB7ciBtb25leS1zdG9jay1wYWlyc30NCnBhaXJzKE1vbmV5U3RvY2tbMzo1XSkNCmBgYA0KDQo6OjoNCjo6OjoNCg0KIyMgRml0IHRoZSBSZWdyZXNzaW9uIE1vZGVsDQoNCkZvciBxdWFydGVyICR0JCwgd2UgZml0DQoNCiQkXG1hdGhybXtDb25zRXhwfV90ID0gXGJldGFfMCArIFxiZXRhXzFcbWF0aHJte01vbmV5U3RrfV90ICsgXHZhcmVwc2lsb25fdC4kJA0KDQpgYGB7ciBtb25leS1zdG9jay1yZWdyZXNzaW9ufQ0KTW9uZXlTdG9ja19sbTEgPC0gbG0oQ29uc0V4cCB+IE1vbmV5U3RrLCBkYXRhID0gTW9uZXlTdG9jaykNCnN1bW1hcnkoTW9uZXlTdG9ja19sbTEpDQpgYGANCg0KYE1vbmV5U3RrYCBhbmQgYENvbnNFeHBgIGhhdmUgYSBzdHJvbmcgbGluZWFyIGFzc29jaWF0aW9uOiAkUl4yJCBpcyBhYm91dCAwLjk2LiBUaGUgcmVwb3J0ZWQgc2xvcGUgYWxzbyBsb29rcyBwcmVjaXNlLiBUaGF0IHByZWNpc2lvbiBjYWxjdWxhdGlvbiBhc3N1bWVzIHRoYXQga25vd2luZyB0aGUgZXJyb3IgaW4gb25lIHF1YXJ0ZXIgdGVsbHMgdXMgbm90aGluZyBhYm91dCBhbm90aGVyIHF1YXJ0ZXIncyBlcnJvci4NCg0KIyMgUmVzaWR1YWwgUGxvdCBPdmVyIFRpbWUNCg0KQmVmb3JlIHJ1bm5pbmcgYSB0ZXN0LCBmb2xsb3cgdGhlIHJlc2lkdWFscyBmcm9tIGxlZnQgdG8gcmlnaHQuIExvb2sgZm9yIHN0cmV0Y2hlcyBhYm92ZSBvciBiZWxvdyB6ZXJvLCBhbHRlcm5hdGlvbiwgYW5kIGFueSByZW1haW5pbmcgdHJlbmQgb3Igc2Vhc29uYWwgcGF0dGVybi4NCg0KYGBge3IgbW9uZXktc3RvY2stcmVzaWR1YWwtcGxvdH0NCnBsb3QocmVzaWR1YWxzKE1vbmV5U3RvY2tfbG0xKSwgdHlwZSA9ICJiIiwgeWxhYiA9ICJSZXNpZHVhbHMiLCB4bGFiID0gIlF1YXJ0ZXIiKQ0KYWJsaW5lKGggPSAwLCBsdHkgPSAyKQ0KYGBgDQoNClRoZSByZXNpZHVhbHMgd2FuZGVyIHNsb3dseSBhYm92ZSBhbmQgYmVsb3cgemVyby4gQWRqYWNlbnQgcXVhcnRlcnMgb2Z0ZW4gaGF2ZSBkZXZpYXRpb25zIGluIHRoZSBzYW1lIGRpcmVjdGlvbi4gU29tZSBydW5zIG9jY3VyIGJ5IGNoYW5jZSBldmVuIHdpdGggaW5kZXBlbmRlbnQgZXJyb3JzOyB3ZSBuZWVkIHRvIGp1ZGdlIHdoZXRoZXIgdGhpcyBtdWNoIHBlcnNpc3RlbmNlIGlzIHBsYXVzaWJsZS4NCg0KIyMgV2h5IERlcGVuZGVuY2UgQ2hhbmdlcyBQcmVjaXNpb24NCg0KU3RhcnQgd2l0aCBhIHNpbXBsZXIgY2FsY3VsYXRpb24uIFN1cHBvc2UgdHdvIG9ic2VydmF0aW9ucyBtZWFzdXJlIHRoZSBzYW1lIG1lYW4gJFxtdSQsIGVhY2ggd2l0aCBlcnJvciB2YXJpYW5jZSAkXHNpZ21hXjIkIGFuZCBjb3JyZWxhdGlvbiAkXHJobyQuIFRoZWlyIGF2ZXJhZ2UgaGFzIHZhcmlhbmNlDQoNCiQkXGJlZ2lue2FsaWduZWR9DQpcb3BlcmF0b3JuYW1le1Zhcn1cbGVmdChcZnJhY3tZXzErWV8yfXsyfVxyaWdodCkNCiY9IFxmcmFjezF9ezR9XGxlZnRbXG9wZXJhdG9ybmFtZXtWYXJ9KFlfMSkrXG9wZXJhdG9ybmFtZXtWYXJ9KFlfMikNCiAgKzJcb3BlcmF0b3JuYW1le0Nvdn0oWV8xLFlfMilccmlnaHRdIFxcDQomPSBcZnJhY3tcc2lnbWFeMn17Mn0oMStccmhvKS4NClxlbmR7YWxpZ25lZH0kJA0KDQpXaXRoIGluZGVwZW5kZW50IGVycm9ycywgJFxyaG89MCQgYW5kIGF2ZXJhZ2luZyBoYWx2ZXMgdGhlIHZhcmlhbmNlLiBXaXRoICRccmhvPTAuOCQsIHRoZSB2YXJpYW5jZSBpcyAkMC45XHNpZ21hXjIkOiB0aGUgc2Vjb25kIG9ic2VydmF0aW9uIGFkZHMgbGl0dGxlIHByZWNpc2lvbiBiZWNhdXNlIHRoZSB0d28gZXJyb3JzIHRlbmQgdG8gbW92ZSB0b2dldGhlci4NCg0KVGhlIHN0YW5kYXJkIGVycm9yIGlzIHRoZW4gJFxzcXJ0ezEuOH1cYXBwcm94MS4zNCQgdGltZXMgdGhlIHZhbHVlIGNhbGN1bGF0ZWQgdW5kZXIgaW5kZXBlbmRlbmNlLiBDb3VudGluZyB0d28gb2JzZXJ2YXRpb25zIGRvZXMgbm90IGdpdmUgdXMgdHdvIGluZGVwZW5kZW50IHBpZWNlcyBvZiBpbmZvcm1hdGlvbi4NCg0KIyMgV2hhdCBDaGFuZ2VzIGluIFJlZ3Jlc3Npb24/DQoNClJlbWVtYmVyIHRoZSBtYXRyaXggZm9ybSAkXG1hdGhiZntZfT1YXGJvbGRzeW1ib2x7XGJldGF9K1xib2xkc3ltYm9se1x2YXJlcHNpbG9ufSQuIFRyZWF0aW5nICRYJCBhcyBmaXhlZCwgbGV0ICRcU2lnbWE9XG9wZXJhdG9ybmFtZXtWYXJ9KFxib2xkc3ltYm9se1x2YXJlcHNpbG9ufVxtaWQgWCkkLiBUaGUgT0xTIGVzdGltYXRlIHN0aWxsIHNhdGlzZmllcw0KDQokJFx3aWRlaGF0e1xib2xkc3ltYm9se1xiZXRhfX09XGJvbGRzeW1ib2x7XGJldGF9KyhYXlx0b3AgWCleey0xfVheXHRvcFxib2xkc3ltYm9se1x2YXJlcHNpbG9ufS4kJA0KDQpJdHMgdmFyaWFuY2UgaXMNCg0KJCRcb3BlcmF0b3JuYW1le1Zhcn0oXHdpZGVoYXR7XGJvbGRzeW1ib2x7XGJldGF9fVxtaWQgWCkNCj0oWF5cdG9wIFgpXnstMX1YXlx0b3BcU2lnbWEgWChYXlx0b3AgWCleey0xfS4kJA0KDQpJbmRlcGVuZGVudCBlcnJvcnMgd2l0aCBlcXVhbCB2YXJpYW5jZSBnaXZlICRcU2lnbWE9XHNpZ21hXjIgSSQsIHJlZHVjaW5nIHRoaXMgdG8gJFxzaWdtYV4yKFheXHRvcCBYKV57LTF9JC4gQXV0b2NvcnJlbGF0aW9uIGludHJvZHVjZXMgbm9uLXplcm8gb2ZmLWRpYWdvbmFsIGNvdmFyaWFuY2VzIGludG8gJFxTaWdtYSQuDQoNCklmICRFKFxib2xkc3ltYm9se1x2YXJlcHNpbG9ufVxtaWQgWCk9XG1hdGhiZnswfSQsIE9MUyByZW1haW5zIHVuYmlhc2VkLiBUaGUgdXN1YWwgc3RhbmRhcmQgZXJyb3JzIGNhbiBzdGlsbCBiZSB3cm9uZywgc28gdGhlIHJlcG9ydGVkIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGFuZCB0ZXN0cyBiZWNvbWUgdW5yZWxpYWJsZS4gRm9yIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzLCB0aGUgZGlyZWN0aW9uIG9mIHRoYXQgZXJyb3IgZGVwZW5kcyBvbiBib3RoIHRoZSBwcmVkaWN0b3JzIGFuZCB0aGUgZGVwZW5kZW5jZSBwYXR0ZXJuLg0KDQojIyBEaWFnbm9zdGljIFRvb2xzDQoNCldlIGhhdmUgc2VlbiBhIHBhdHRlcm4gdGhhdCBjb3VsZCBtYWtlIG91ciBwcmVjaXNpb24gY2FsY3VsYXRpb24gdW5yZWxpYWJsZS4gRWFjaCBkaWFnbm9zdGljIHN1bW1hcmlzZXMgYSBkaWZmZXJlbnQgZmVhdHVyZSBvZiB0aGF0IHBhdHRlcm4uDQoNCnwgRGlhZ25vc3RpYyB8IFF1ZXN0aW9uIGFib3V0IHRoZSBvcmRlcmVkIHJlc2lkdWFscyB8DQp8Oi0tfDotLXwNCnwgUnVucyB0ZXN0IHwgRG8gcmVzaWR1YWxzIHN0YXkgb24gdGhlIHNhbWUgc2lkZSBvZiB0aGVpciBtZWRpYW4gdW51c3VhbGx5IGxvbmcsIG9yIHN3aXRjaCBzaWRlcyB1bnVzdWFsbHkgb2Z0ZW4/IHwNCnwgRHVyYmluLVdhdHNvbiB8IEhvdyBkaWZmZXJlbnQgaXMgZWFjaCByZXNpZHVhbCBmcm9tIHRoZSBvbmUgaW1tZWRpYXRlbHkgYmVmb3JlIGl0PyB8DQp8IEFDRiB8IEhvdyBzdHJvbmcgaXMgdGhlIGNvcnJlbGF0aW9uIGF0IGVhY2ggdGltZSBnYXA/IHwNCnwgTGp1bmctQm94IHwgSXMgdGhlcmUgZXZpZGVuY2Ugb2YgY29ycmVsYXRpb24gYWNyb3NzIGEgY2hvc2VuIGdyb3VwIG9mIGxhZ3M/IHwNCg0KS2VlcCB0aGUgdGltZSBvcmRlci4gUmVhcnJhbmdpbmcgb2JzZXJ2YXRpb25zIGxlYXZlcyB0aGUgZml0dGVkIHJlZ3Jlc3Npb24gdW5jaGFuZ2VkIGJ1dCBjaGFuZ2VzIHRoZXNlIGRpYWdub3N0aWNzLiBBbHNvIGNoZWNrIHRoZSBtZWFuIG1vZGVsOiBhIG1pc3NpbmcgdHJlbmQgb3Igc2Vhc29uYWwgdGVybSBjYW4gcHJvZHVjZSBhIHJlc2lkdWFsIHBhdHRlcm4gb2YgaXRzIG93bi4NCg0KIyMgUnVucyBUZXN0DQoNCkEgKipydW4qKiBpcyBhbiB1bmludGVycnVwdGVkIHNlcXVlbmNlIG9uIHRoZSBzYW1lIHNpZGUgb2YgYSB0aHJlc2hvbGQuIEZvciBleGFtcGxlLCAkKysrXDstLVw7KytcOy0kIGNvbnRhaW5zIGZvdXIgcnVucywgYWx0aG91Z2ggaXQgY29udGFpbnMgZWlnaHQgb2JzZXJ2YXRpb25zLg0KDQpUaGUgZGVmYXVsdCBbYFJ1bnNUZXN0KClgXShodHRwczovL2FuZHJpc2lnbm9yZWxsLmdpdGh1Yi5pby9EZXNjVG9vbHMvcmVmZXJlbmNlL1J1bnNUZXN0Lmh0bWwpIGRpdmlkZXMgbnVtZXJpY2FsIHJlc2lkdWFscyBhdCB0aGVpciBtZWRpYW4uIFdyaXRlICRuXyskIGZvciB0aGUgbnVtYmVyIGFib3ZlIHRoZSBtZWRpYW4gYW5kICRuXy0kIGZvciB0aGUgbnVtYmVyIGF0IG9yIGJlbG93IGl0LiBVbmRlciByYW5kb20gb3JkZXJpbmcsIHRoZSBleHBlY3RlZCBudW1iZXIgb2YgcnVucyBpcw0KDQokJEUoUik9MStcZnJhY3sybl8rbl8tfXtuXysrbl8tfS4kJA0KDQpUb28gZmV3IHJ1bnMgaW5kaWNhdGUgY2x1c3RlcmluZyBvbiB0aGUgc2FtZSBzaWRlOyB0b28gbWFueSBpbmRpY2F0ZSBleGNlc3NpdmUgYWx0ZXJuYXRpb24uIFRoZSB0ZXN0IGNvbXBhcmVzIHRoZSBvYnNlcnZlZCBjb3VudCB3aXRoIGl0cyBkaXN0cmlidXRpb24gdW5kZXIgcmFuZG9tIG9yZGVyaW5nLg0KDQojIyBSdW5zIGluIHRoZSBNb25leVN0b2NrIFJlc2lkdWFscw0KDQpUaGVyZSBhcmUgdGVuIHJlc2lkdWFscyBvbiBlYWNoIHNpZGUgb2YgdGhlIG1lZGlhbiwgc28gdW5kZXIgcmFuZG9tIG9yZGVyaW5nIHdlIGV4cGVjdA0KDQokJEUoUik9MStcZnJhY3syKDEwKSgxMCl9ezIwfT0xMVx0ZXh0eyBydW5zfS4kJA0KDQpgYGB7ciBtb25leS1zdG9jay1ydW5zLXRlc3R9DQpSdW5zVGVzdChyZXNpZHVhbHMoTW9uZXlTdG9ja19sbTEpKQ0KYGBgDQoNCldlIG9ic2VydmUgb25seSBmaXZlIHJ1bnMsIHdpdGggJFBcYXBwcm94MC4wMDkkLiBUaGlzIHN1cHBvcnRzIHRoZSBpbXByZXNzaW9uIG9mIGxvbmcgc3RyZXRjaGVzIG9uIHRoZSBzYW1lIHNpZGUuIFRoZSBkZWZhdWx0IHRlc3QgaXMgdHdvLXNpZGVkLCBzbyBpdCBjYW4gZGV0ZWN0IGVpdGhlciB1bnVzdWFsbHkgZmV3IG9yIHVudXN1YWxseSBtYW55IHJ1bnMuIEl0IGRvZXMgbm90IG1lYXN1cmUgdGhlIHNpemUgb2YgdGhlIHJlc2lkdWFscyBvciBpZGVudGlmeSB0aGUgcHJvY2VzcyBwcm9kdWNpbmcgdGhlbS4NCg0KIyMgRHVyYmluLVdhdHNvbiBUZXN0DQoNClJ1bnMgdXNlIG9ubHkgd2hpY2ggc2lkZSBlYWNoIHJlc2lkdWFsIGZhbGxzIG9uLiBEdXJiaW4tV2F0c29uIHVzZXMgdGhlIHNpemVzIG9mIHRoZSBjaGFuZ2VzIGJldHdlZW4gbmVpZ2hib3VyaW5nIHJlc2lkdWFsczoNCg0KJCRkPVxmcmFje1xzdW1fe3Q9Mn1ee259KGVfdC1lX3t0LTF9KV4yfXtcc3VtX3t0PTF9XntufWVfdF4yfS4kJA0KDQpUaGUgZGVub21pbmF0b3IgbWVhc3VyZXMgdGhlIG92ZXJhbGwgcmVzaWR1YWwgdmFyaWF0aW9uLiBUaGUgbnVtZXJhdG9yIG1lYXN1cmVzIGhvdyBtdWNoIHJlc2lkdWFscyBjaGFuZ2UgZnJvbSBvbmUgb2JzZXJ2YXRpb24gdG8gdGhlIG5leHQuDQoNCi0gUG9zaXRpdmUgYXV0b2NvcnJlbGF0aW9uIGdpdmVzIHNtYWxsIG5laWdoYm91cmluZyBkaWZmZXJlbmNlcywgc28gJGQkIHRlbmRzIHRvd2FyZHMgMC4NCi0gV2l0aCBubyBsYWctMSBhdXRvY29ycmVsYXRpb24sICRkJCBpcyB0eXBpY2FsbHkgbmVhciAyLg0KLSBOZWdhdGl2ZSBhdXRvY29ycmVsYXRpb24gZ2l2ZXMgbGFyZ2VyIG5laWdoYm91cmluZyBkaWZmZXJlbmNlcywgc28gJGQkIHRlbmRzIHRvd2FyZHMgNC4NCg0KVGhlc2UgdmFsdWVzIGd1aWRlIGludGVycHJldGF0aW9uOyB0aGV5IGFyZSBub3Qgc2lnbmlmaWNhbmNlIGN1dC1vZmZzLg0KDQojIyBEdXJiaW4tV2F0c29uIGZvciBNb25leVN0b2NrDQoNCldlIHRlc3QgJEhfMDpccmhvXzE9MCQgYWdhaW5zdCAkSF9BOlxyaG9fMT4wJC4gVGhlIG9uZS1zaWRlZCBhbHRlcm5hdGl2ZSB0YXJnZXRzIHRoZSBwb3NpdGl2ZSBhdXRvY29ycmVsYXRpb24gc3VnZ2VzdGVkIGJ5IHRoZSB0aW1lIHBsb3QuDQoNCmBgYHtyIG1vbmV5LXN0b2NrLWR1cmJpbi13YXRzb259DQpkd3Rlc3QoTW9uZXlTdG9ja19sbTEsIGFsdGVybmF0aXZlID0gImdyZWF0ZXIiKQ0KYGBgDQoNClRoZSBzdGF0aXN0aWMgaXMgJGRcYXBwcm94MC4zMyQsIHdpdGggYSB2ZXJ5IHNtYWxsIFAtdmFsdWUuIFRoZSByZXNpZHVhbHMgY2hhbmdlIG11Y2ggbGVzcyBiZXR3ZWVuIGFkamFjZW50IHF1YXJ0ZXJzIHRoYW4gd2Ugd291bGQgZXhwZWN0IGZyb20gdGhlaXIgb3ZlcmFsbCB2YXJpYXRpb24uDQoNCkluIFtgZHd0ZXN0KClgXShodHRwczovL3N0YXQuZXRoei5jaC9DUkFOL3dlYi9wYWNrYWdlcy9sbXRlc3QvbG10ZXN0LnBkZiksIGBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyImAgcmVmZXJzIHRvIGNvcnJlbGF0aW9uIGdyZWF0ZXIgdGhhbiB6ZXJvLiBFdmlkZW5jZSBmb3IgdGhhdCBhbHRlcm5hdGl2ZSBjb21lcyBmcm9tIGEgKipzbWFsbCoqIHZhbHVlIG9mICRkJC4gVGhlIHRlc3QncyByZWZlcmVuY2UgZGlzdHJpYnV0aW9uIGFjY291bnRzIGZvciB0aGUgcmVncmVzc2lvbiBwcmVkaWN0b3JzOyB3ZSBkbyBub3Qgc2ltcGx5IGRlY2xhcmUgZXZlcnkgdmFsdWUgYmVsb3cgMiBzaWduaWZpY2FudC4NCg0KIyMgTWVhc3VyaW5nIENvcnJlbGF0aW9uIGF0IEVhY2ggTGFnDQoNCkR1cmJpbi1XYXRzb24gZm9jdXNlcyBvbiBuZWlnaGJvdXJpbmcgb2JzZXJ2YXRpb25zLiBUaGUgYXV0b2NvcnJlbGF0aW9uIGZ1bmN0aW9uIChBQ0YpIGxldHMgdXMgZXhhbWluZSBsb25nZXIgZ2FwcyBhcyB3ZWxsLiBUaGUgW3NhbXBsZSBhdXRvY29ycmVsYXRpb25dKGh0dHBzOi8vd3d3Lml0bC5uaXN0Lmdvdi9kaXY4OTgvaGFuZGJvb2svZWRhL3NlY3Rpb24zL2VkYTM1Yy5odG0pIGF0IGxhZyAkayQgaXMNCg0KJCRyX2s9XGZyYWN7XHN1bV97dD1rKzF9XntufShlX3QtXGJhciBlKShlX3t0LWt9LVxiYXIgZSl9DQp7XHN1bV97dD0xfV57bn0oZV90LVxiYXIgZSleMn0uJCQNCg0KVGhlIG51bWVyYXRvciBwYWlycyByZXNpZHVhbHMgJGskIG9ic2VydmF0aW9ucyBhcGFydC4gUHJvZHVjdHMgYXJlIHBvc2l0aXZlIHdoZW4gYm90aCBkZXZpYXRpb25zIGZyb20gJFxiYXIgZSQgaGF2ZSB0aGUgc2FtZSBzaWduLCBhbmQgbmVnYXRpdmUgd2hlbiB0aGV5IGhhdmUgb3Bwb3NpdGUgc2lnbnMuIFRoZSBkZW5vbWluYXRvciBwdXRzIHRoZSByZXN1bHQgb24gYSBjb3JyZWxhdGlvbiBzY2FsZS4gTGFnIDAgaXMgYWx3YXlzIDEuDQoNCkZvciBPTFMgd2l0aCBhbiBpbnRlcmNlcHQsICRcYmFyIGU9MCQgYXBhcnQgZnJvbSBudW1lcmljYWwgcm91bmRpbmcuIEV4cGFuZGluZyB0aGUgc3F1YXJlZCBkaWZmZXJlbmNlcyBpbiBEdXJiaW4tV2F0c29uIHRoZW4gZ2l2ZXMNCg0KJCRkPTIoMS1yXzEpLVxmcmFje2VfMV4yK2Vfbl4yfXtcc3VtX3t0PTF9XntufWVfdF4yfQ0KXGFwcHJveDIoMS1yXzEpLiQkDQoNClRoZSBhcHByb3hpbWF0aW9uIGRyb3BzIHRoZSB0d28gZW5kcG9pbnQgdGVybXMuIEl0IGNhbiBiZSBub3RpY2VhYmx5IGRpZmZlcmVudCBpbiBhIHNob3J0IHNlcmllcywgc28gdXNlIGl0IHRvIHVuZGVyc3RhbmQgdGhlIGRpcmVjdGlvbiBvZiAkZCQsIHJhdGhlciB0aGFuIHRvIHJlcGxhY2UgdGhlIGNhbGN1bGF0aW9uLg0KDQojIyBBQ0YgUGxvdA0KDQpgYGB7ciBtb25leS1zdG9jay1hY2YsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTR9DQphY2YocmVzaWR1YWxzKE1vbmV5U3RvY2tfbG0xKSwgbWFpbiA9ICJBQ0Ygb2YgTW9uZXlTdG9jayByZXNpZHVhbHMiKQ0KYGBgDQoNClRoZSBsYWctMSB2YWx1ZSBpcyBhYm91dCAwLjc1LCBhbmQgcG9zaXRpdmUgY29ycmVsYXRpb24gcGVyc2lzdHMgYWNyb3NzIHNldmVyYWwgcXVhcnRlcnMuIFRoaXMgYWdyZWVzIHdpdGggdGhlIHNsb3cgbW92ZW1lbnQgaW4gdGhlIHRpbWUgcGxvdC4gV2Ugc2hvdWxkIGFsc28gY2hlY2sgd2hldGhlciBhIG1pc3NpbmcgdGltZSB0cmVuZCBjb3VsZCBleHBsYWluIHBhcnQgb2YgaXQuDQoNCiMjIFJlYWRpbmcgdGhlIEFDRiBSZWZlcmVuY2UgTGluZXMNCg0KVW5kZXIgYW4gdW5jb3JyZWxhdGVkIHdoaXRlLW5vaXNlIHJlZmVyZW5jZSBtb2RlbCwgdGhlIGRlZmF1bHQgYXBwcm94aW1hdGUgOTUlIHJlZmVyZW5jZSBsaW1pdHMgYXQgYW4gaW5kaXZpZHVhbCBub24temVybyBsYWcgYXJlDQoNCiQkXHBtXGZyYWN7MS45Nn17XHNxcnQgbn0uJCQNCg0KSGVyZSAkbj0yMCQsIGdpdmluZyBsaW1pdHMgb2YgYWJvdXQgJFxwbTAuNDQkLiBUaGUgbGFnLTEgY29ycmVsYXRpb24gaXMgd2VsbCBvdXRzaWRlIHRoZW0uIEEgc2VxdWVuY2Ugb2YgbGFyZ2UgY29ycmVsYXRpb25zIGRlc2VydmVzIG1vcmUgYXR0ZW50aW9uIHRoYW4gb25lIGlzb2xhdGVkIGJhciBqdXN0IGJleW9uZCBhIGxpbmUuDQoNClRoZXNlIGFyZSBhcHByb3hpbWF0ZSwgcG9pbnR3aXNlIGxpbWl0cywgbm90IGEgc2ltdWx0YW5lb3VzIDk1JSBiYW5kIGZvciB0aGUgd2hvbGUgcGxvdC4gV2l0aCBtYW55IGxhZ3MsIHNvbWUgYmFycyBjYW4gY3Jvc3MgYnkgY2hhbmNlLiBGaXR0aW5nIHRoZSByZWdyZXNzaW9uIGFsc28gYWZmZWN0cyB0aGUgYmVoYXZpb3VyIG9mIGl0cyByZXNpZHVhbHMsIHNvIHRyZWF0IHRoZSBsaW5lcyBhcyBhIHZpc3VhbCByZWZlcmVuY2UuIFRoZSBbYGFjZigpYCBwbG90dGluZyBkb2N1bWVudGF0aW9uXShodHRwczovL3N0YXQuZXRoei5jaC9SLW1hbnVhbC9SLWRldmVsL2xpYnJhcnkvc3RhdHMvaHRtbC9wbG90LmFjZi5odG1sKSBkZXNjcmliZXMgdGhlIHdoaXRlLW5vaXNlIGFzc3VtcHRpb24gYmVoaW5kIHRoZW0uDQoNCiMjIExqdW5nLUJveCBUZXN0DQoNCklmIHNldmVyYWwgQUNGIGJhcnMgbG9vayBsYXJnZSwgd2UgY2FuIGNvbWJpbmUgdGhlbS4gRm9yIGEgY2hvc2VuIG1heGltdW0gbGFnICRtJCwgdGhlIGh5cG90aGVzZXMgYXJlDQoNCiQkSF8wOlxyaG9fMT1cY2RvdHM9XHJob19tPTAsIFxxcXVhZA0KSF9BOlx0ZXh0e2F0IGxlYXN0IG9uZSBvZiB0aGVzZSBjb3JyZWxhdGlvbnMgaXMgbm9uLXplcm99LiQkDQoNClRoZSBbTGp1bmctQm94IHN0YXRpc3RpY10oaHR0cHM6Ly93d3cuaXRsLm5pc3QuZ292L2Rpdjg5OC9oYW5kYm9vay9wbWMvc2VjdGlvbjQvcG1jNDQ4MS5odG0pIGlzDQoNCiQkUT1uKG4rMilcc3VtX3trPTF9XnttfVxmcmFje3Jfa14yfXtuLWt9LiQkDQoNClNxdWFyaW5nIHByZXZlbnRzIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBjb3JyZWxhdGlvbnMgZnJvbSBjYW5jZWxsaW5nLiBMYXJnZXIgY29ycmVsYXRpb25zIGdpdmUgYSBsYXJnZXIgJFEkIGFuZCBtb3JlIGV2aWRlbmNlIGFnYWluc3QgdGhlIG51bGwgaHlwb3RoZXNpcy4gQ2hvb3NlICRtJCB1c2luZyB0aGUgdGltZSBzY2FsZSBhbmQgdGhlIGF2YWlsYWJsZSBzYW1wbGUgc2l6ZSwgYmVmb3JlIGluc3BlY3RpbmcgYSBjb2xsZWN0aW9uIG9mIFAtdmFsdWVzLg0KDQojIyBManVuZy1Cb3ggZm9yIE1vbmV5U3RvY2sNCg0KSGVyZSB3ZSB1c2UgJG09MTAkLCBjb21iaW5pbmcgY29ycmVsYXRpb25zIG92ZXIgZ2FwcyBmcm9tIG9uZSB0byB0ZW4gcXVhcnRlcnMuDQoNCmBgYHtyIG1vbmV5LXN0b2NrLWxqdW5nLWJveH0NCkJveC50ZXN0KHJlc2lkdWFscyhNb25leVN0b2NrX2xtMSksIGxhZyA9IDEwLCB0eXBlID0gIkxqdW5nLUJveCIpDQpgYGANCg0KV2Ugb2J0YWluICRRXGFwcHJveDY0LjQkIGFuZCBhIHZlcnkgc21hbGwgUC12YWx1ZS4gV2l0aCB0aGUgZGVmYXVsdCBgZml0ZGYgPSAwYCwgW2BCb3gudGVzdCgpYF0oaHR0cHM6Ly9zdGF0LmV0aHouY2gvUi1tYW51YWwvUi1kZXZlbC9saWJyYXJ5L3N0YXRzL2h0bWwvYm94LnRlc3QuaHRtbCkgY29tcGFyZXMgdGhpcyB3aXRoIGFuIGFwcHJveGltYXRlICRcY2hpXjJfezEwfSQgZGlzdHJpYnV0aW9uLg0KDQpUaGVyZSBhcmUgb25seSAyMCBvYnNlcnZhdGlvbnMgaGVyZSwgYW5kIHRoZSByZXNpZHVhbHMgY29tZSBmcm9tIGFuIGVzdGltYXRlZCByZWdyZXNzaW9uLCBzbyB0cmVhdCB0aGF0IFAtdmFsdWUgYXMgYW4gYXBwcm94aW1hdGUgZGlhZ25vc3RpYyBzdW1tYXJ5LiBUaGUgdGltZSBwbG90LCBydW5zIHRlc3QgYW5kIER1cmJpbi1XYXRzb24gYWxyZWFkeSBnaXZlIHN1YnN0YW50aWFsIGV2aWRlbmNlIG9mIHBlcnNpc3RlbmNlLiBUaGlzIHJlc3VsdCBkb2VzIG5vdCBlc3RhYmxpc2ggdGhhdCBldmVyeSBsYWcgaXMgY29ycmVsYXRlZCBvciB0ZWxsIHVzIHdoaWNoIGNoYW5nZSB0byB0aGUgbW9kZWwgd2lsbCBhZGRyZXNzIGl0Lg0KDQojIyBXb3JrIFRocm91Z2ggdGhlIERpYWdub3N0aWNzDQoNCioqMS4qKiBJZiAkZD0wLjYkLCB3aGF0IGxhZy0xIGNvcnJlbGF0aW9uIGRvZXMgJGRcYXBwcm94MigxLXJfMSkkIHN1Z2dlc3Q/DQoNCi4gLiAuDQoNClJlYXJyYW5naW5nIGdpdmVzICRyXzFcYXBwcm94MS1kLzI9MC43JCwgc3VnZ2VzdGluZyBzdHJvbmcgcG9zaXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBuZWlnaGJvdXJzLiBUaGlzIGlzIGFuIGFwcHJveGltYXRpb24sIG5vdCBhIFAtdmFsdWUuDQoNCi4gLiAuDQoNCioqMi4qKiBJZiAkcl8xPTAkIGJ1dCAkcl80JCBpcyBsYXJnZSwgd2hpY2ggZGlhZ25vc3RpYyBkaXNwbGF5cyB0aGF0IHBhdHRlcm4sIGFuZCB3aGljaCBjYW4gdGVzdCBhIGdyb3VwIG9mIGxhZ3MgY29udGFpbmluZyBpdD8NCg0KLiAuIC4NCg0KVGhlIEFDRiBkaXNwbGF5cyB0aGUgbGFnLTQgY29ycmVsYXRpb24uIExqdW5nLUJveCB3aXRoICRtXGdlcTQkIGluY2x1ZGVzIGl0IGluIGEgam9pbnQgdGVzdDsgYSBsYWctMSBkaWFnbm9zdGljIGFsb25lIGNhbiBtaXNzIGl0Lg0KDQouIC4gLg0KDQoqKjMuKiogV2h5IHdvdWxkIHNodWZmbGluZyBjb21wbGV0ZSByb3dzIG9mIE1vbmV5U3RvY2sgbGVhdmUgdGhlIGNvZWZmaWNpZW50cyBhbmQgJFJeMiQgdW5jaGFuZ2VkIGJ1dCBhbHRlciB0aGUgcmVzaWR1YWwgZGlhZ25vc3RpY3M/DQoNCi4gLiAuDQoNCk9MUyBtaW5pbWlzZXMgdGhlIHNhbWUgc3VtIG9mIHNxdWFyZXMgYWZ0ZXIgcmVvcmRlcmluZy4gUnVucywgbmVpZ2hib3VyaW5nIGRpZmZlcmVuY2VzIGFuZCBsYWdnZWQgcHJvZHVjdHMgZGVwZW5kIG9uIHdoaWNoIG9ic2VydmF0aW9ucyBmb2xsb3cgb25lIGFub3RoZXIsIHNvIHRoZSBkaWFnbm9zdGljcyBuZWVkIHRoZSBhY3R1YWwgdGltZSBvcmRlci4NCg0KIyMgQSBNb2Rlcm4gQ29tcGFyaXNvbjogU2VvdWwgQmlrZSBSZXNpZHVhbHMNCg0KVGhlIHNhbWUgZGlhZ25vc3RpYyBsb2dpYyBhcHBsaWVzIHRvIHRoZSByaWNoZXIgZGFpbHkgYmlrZSBtb2RlbCBmcm9tIExlY3R1cmVzIDMyLzMzLCB3aGljaCBjb21iaW5lZCB0d28gRm91cmllciBwYWlycyB3aXRoIHRoZSB0aW1lIHRyZW5kIGFuZCB3ZWF0aGVyIHByZWRpY3RvcnMuDQoNCmByIHhmdW46OmVtYmVkX2ZpbGUoIi4uL2RhdGEvc2VvdWxfYmlrZV9kYWlseS5jc3YiKWANCg0KOjo6OiB7LmNvbHVtbnMgLnNlb3VsLXJlc2lkdWFsLWxheW91dH0NCjo6OiB7LmNvbHVtbiBzdHlsZT0id2lkdGg6IDEwMCU7In0NCg0KYGBge3IgcmVhZC1zZW91bC1kYWlseS1kaWFnbm9zdGljcywgbWVzc2FnZT1GQUxTRX0NCnNlb3VsX2RhaWx5IDwtIHJlYWRfY3N2KCIuLi9kYXRhL3Nlb3VsX2Jpa2VfZGFpbHkuY3N2Iiwgc2hvd19jb2xfdHlwZXMgPSBGQUxTRSkgfD4NCiAgbXV0YXRlKGRhdGUgPSBhcy5EYXRlKGRhdGUpKSB8Pg0KICBhcnJhbmdlKGRhdGUpIHw+DQogIGZpbHRlcihmdW5jdGlvbmluZ19kYXlfYWxsID09ICJ5ZXMiKSB8Pg0KICBtdXRhdGUoDQogICAgUzEgPSBzaW4oMiAqIHBpICogZGF5X2luZGV4IC8gMzY1KSwNCiAgICBDMSA9IGNvcygyICogcGkgKiBkYXlfaW5kZXggLyAzNjUpLA0KICAgIFMyID0gc2luKDQgKiBwaSAqIGRheV9pbmRleCAvIDM2NSksDQogICAgQzIgPSBjb3MoNCAqIHBpICogZGF5X2luZGV4IC8gMzY1KQ0KICApDQoNCnNlb3VsX21lYW4gPC0gbG0oDQogIHJlbnRlZF9iaWtlX2NvdW50IH4gZGF5X2luZGV4ICsgUzEgKyBDMSArIFMyICsgQzIgKw0KICAgIG1lYW5fdGVtcGVyYXR1cmUgKyB0b3RhbF9yYWluZmFsbCArIHRvdGFsX3NvbGFyX3JhZGlhdGlvbiwNCiAgZGF0YSA9IHNlb3VsX2RhaWx5DQopDQoNCnNlb3VsX2RpYWdub3N0aWNzIDwtIHNlb3VsX2RhaWx5IHw+DQogIG11dGF0ZShyZXNpZHVhbCA9IHJlc2lkdWFscyhzZW91bF9tZWFuKSkNCmBgYA0KDQo6OjoNCg0KOjo6IHsuY29sdW1uIHN0eWxlPSJ3aWR0aDogMTAwJTsifQ0KDQpgYGB7ciBzZW91bC1yZXNpZHVhbC1wbG90LCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9IjEwMCUifQ0KZ2dwbG90KHNlb3VsX2RpYWdub3N0aWNzLCBhZXMoeCA9IGRhdGUsIHkgPSByZXNpZHVhbCkpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgbGFicyh4ID0gIkFjdHVhbCBkYXRlIiwgeSA9ICJSZXNpZHVhbCIsIHRpdGxlID0gIlNlb3VsIGJpa2UgcmVzaWR1YWxzIG9uIGZ1bmN0aW9uaW5nIGRheXMiKQ0KYGBgDQoNCjo6Og0KOjo6Og0KDQpXZSBmaXR0ZWQgdGhlIG1lYW4gbW9kZWwgdG8gYWxsIDM1MiBmdW5jdGlvbmluZyBkYXlzLiBUaGUgZGF0ZXMgcmVtYWluIHZpc2libGUgaGVyZSwgaW5jbHVkaW5nIHRoZSBnYXBzIGxlZnQgYnkgMTMgb3V0YWdlIGRheXMuDQoNCiMjIFNlb3VsOiBPbmUgVW5pbnRlcnJ1cHRlZCBQZXJpb2QNCg0KRm9yIHRoZSBkYWlseSBkaWFnbm9zdGljcywgc2VsZWN0IHRoZSBsb25nZXN0IHVuaW50ZXJydXB0ZWQgcGVyaW9kOiAxIERlY2VtYmVyIDIwMTcgdGhyb3VnaCAxMCBBcHJpbCAyMDE4LiBPdGhlcndpc2UsIGFuIG9yZGluYXJ5IEFDRiB3b3VsZCB0cmVhdCBjb25zZWN1dGl2ZSByZXRhaW5lZCByb3dzIGFzIHRob3VnaCB0aGV5IHdlcmUgYWx3YXlzIG9uZSBkYXkgYXBhcnQuDQoNClJlZml0IHRoZSAqKnNhbWUgbWVhbiBmb3JtdWxhKiogb24gdGhlc2UgMTMxIGNvbnNlY3V0aXZlIGRheXMuIEFsbCBmb3VyIGRpYWdub3N0aWNzIGJlbG93IHVzZSByZXNpZHVhbHMgZnJvbSB0aGlzIHJlZml0dGVkIG1vZGVsLCBzbyB0aGUgRHVyYmluLVdhdHNvbiB0ZXN0IGFuZCB0aGUgb3RoZXIgc3VtbWFyaWVzIHJlZmVyIHRvIHRoZSBzYW1lIG9ic2VydmF0aW9ucyBhbmQgZml0Lg0KDQpgYGB7ciBzZW91bC1kaWFnbm9zdGljLXRlc3RzfQ0Kc2VvdWxfcnVuX2RhdGEgPC0gc2VvdWxfZGFpbHkgfD4NCiAgZmlsdGVyKGRhdGUgPj0gYXMuRGF0ZSgiMjAxNy0xMi0wMSIpLCBkYXRlIDw9IGFzLkRhdGUoIjIwMTgtMDQtMTAiKSkNCg0Kc2VvdWxfcnVuX21vZGVsIDwtIHVwZGF0ZShzZW91bF9tZWFuLCBkYXRhID0gc2VvdWxfcnVuX2RhdGEpDQpzZW91bF9ydW5fcmVzaWR1YWxzIDwtIHJlc2lkdWFscyhzZW91bF9ydW5fbW9kZWwpDQpgYGANCg0KYGBge3Igc2VvdWwtZGlhZ25vc3RpYy1jYWxjdWxhdGlvbnMsIGluY2x1ZGU9RkFMU0V9DQpzZW91bF9uIDwtIGxlbmd0aChzZW91bF9ydW5fcmVzaWR1YWxzKQ0Kc2VvdWxfbWVkaWFuIDwtIG1lZGlhbihzZW91bF9ydW5fcmVzaWR1YWxzKQ0Kc2VvdWxfYWJvdmUgPC0gc2VvdWxfcnVuX3Jlc2lkdWFscyA+IHNlb3VsX21lZGlhbg0Kc2VvdWxfcnVuc19vYnNlcnZlZCA8LSBsZW5ndGgocmxlKHNlb3VsX2Fib3ZlKSRsZW5ndGhzKQ0Kc2VvdWxfbl9hYm92ZSA8LSBzdW0oc2VvdWxfYWJvdmUpDQpzZW91bF9uX2JlbG93IDwtIHN1bSghc2VvdWxfYWJvdmUpDQpzZW91bF9ydW5zX2V4cGVjdGVkIDwtIDEgKyAyICogc2VvdWxfbl9hYm92ZSAqIHNlb3VsX25fYmVsb3cgLyBzZW91bF9uDQoNCnNlb3VsX2R3X251bWVyYXRvciA8LSBzdW0oZGlmZihzZW91bF9ydW5fcmVzaWR1YWxzKV4yKQ0Kc2VvdWxfZHdfZGVub21pbmF0b3IgPC0gc3VtKHNlb3VsX3J1bl9yZXNpZHVhbHNeMikNCnNlb3VsX2FjZl92YWx1ZXMgPC0gYWNmKHNlb3VsX3J1bl9yZXNpZHVhbHMsIGxhZy5tYXggPSAxNCwgcGxvdCA9IEZBTFNFKQ0Kc2VvdWxfYWNmX2xpbWl0IDwtIHFub3JtKDAuOTc1KSAvIHNxcnQoc2VvdWxfbikNCmBgYA0KDQojIyBTZW91bDogUnVucyBBYm92ZSBhbmQgQmVsb3cgdGhlIE1lZGlhbg0KDQpEaXZpZGUgdGhlIHJlc2lkdWFscyBhdCB0aGVpciBtZWRpYW4sIGByIHJvdW5kKHNlb3VsX21lZGlhbiwgMSlgIGJpa2VzLiBFYWNoIHVuaW50ZXJydXB0ZWQgY29sb3VyIGJsb2NrIGlzIG9uZSBydW4uDQoNCmBgYHtyIHNlb3VsLXJ1bnMtc3RyaXAsIGVjaG89RkFMU0UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTEuMywgb3V0LndpZHRoPSI4NSUiLCBmaWcuYWx0PSJTZXF1ZW5jZSBvZiBTZW91bCByZXNpZHVhbHMgYWJvdmUgYW5kIGF0IG9yIGJlbG93IHRoZWlyIG1lZGlhbiwgd2l0aCBlYWNoIGNvbG91ciBibG9jayBtYXJraW5nIG9uZSBydW4ifQ0Kc2VvdWxfcnVuX2RhdGEgfD4NCiAgbXV0YXRlKHNpZGUgPSBpZl9lbHNlKHNlb3VsX2Fib3ZlLCAiQWJvdmUgbWVkaWFuIiwgIkF0IG9yIGJlbG93IG1lZGlhbiIpKSB8Pg0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gMSwgZmlsbCA9IHNpZGUpKSArDQogIGdlb21fdGlsZSh3aWR0aCA9IDEsIGhlaWdodCA9IDAuNikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJBYm92ZSBtZWRpYW4iID0gIiMxNzNmNWYiLCAiQXQgb3IgYmVsb3cgbWVkaWFuIiA9ICIjZDQ4NjNiIikpICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwsIGZpbGwgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTEpICsNCiAgdGhlbWUoDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSINCiAgKQ0KYGBgDQoNClRoZXJlIGFyZSBgciBzZW91bF9uX2Fib3ZlYCByZXNpZHVhbHMgYWJvdmUgdGhlIG1lZGlhbiBhbmQgYHIgc2VvdWxfbl9iZWxvd2AgYXQgb3IgYmVsb3cgaXQuIENvbXBhcmUgdGhlIGFjdHVhbCBydW4gY291bnQgd2l0aCAkRShSKT0xKzJuXytuXy0vbiQuDQoNCmBgYHtyIHNlb3VsLXJ1bnMtdGVzdH0NCnNlb3VsX3J1bnMgPC0gUnVuc1Rlc3Qoc2VvdWxfcnVuX3Jlc2lkdWFscykNCmBgYA0KDQpgYGB7ciBzZW91bC1ydW5zLXN1bW1hcnksIGVjaG89RkFMU0V9DQp0aWJibGUoDQogIGBPYnNlcnZlZCBydW5zYCA9IHNlb3VsX3J1bnNfb2JzZXJ2ZWQsDQogIGBFeHBlY3RlZCBydW5zYCA9IHJvdW5kKHNlb3VsX3J1bnNfZXhwZWN0ZWQsIDEpLA0KICBgVGVzdCBzdGF0aXN0aWMgemAgPSByb3VuZCh1bm5hbWUoc2VvdWxfcnVucyRzdGF0aXN0aWMpLCAyKSwNCiAgYFAtdmFsdWVgID0gZm9ybWF0LnB2YWwoc2VvdWxfcnVucyRwLnZhbHVlLCBkaWdpdHMgPSAzKQ0KKSB8PiBrYWJsZSgpDQpgYGANCg0KVGhlIGNvdW50IGlzICoqYHIgc2VvdWxfcnVuc19vYnNlcnZlZGAgcnVucyoqOyAkeiQgc3RhbmRhcmRpc2VzIGl0cyBkZXBhcnR1cmUgZnJvbSB0aGUgZXhwZWN0ZWQgY291bnQsIHdpdGggYSBjb250aW51aXR5IGNvcnJlY3Rpb24uIFRoZSB0d28tc2lkZWQgUC12YWx1ZSBpcyBqdXN0IGFib3ZlIDAuMDUuIFRoaXMgdGVzdCB1c2VzIG9ubHkgdGhlIG1lZGlhbi1zaWRlIHNlcXVlbmNlLCBzbyBpdCBjYW4gbWlzcyBkZXBlbmRlbmNlIHZpc2libGUgaW4gdGhlIHJlc2lkdWFsIG1hZ25pdHVkZXMuDQoNCiMjIFNlb3VsOiBEdXJiaW4tV2F0c29uDQoNClVzZSB0aGUgc2l6ZXMgb2YgdGhlIGNoYW5nZXMgYmV0d2VlbiBjb25zZWN1dGl2ZSBkYWlseSByZXNpZHVhbHM6DQoNCiQkZD1cZnJhY3tcc3VtX3t0PTJ9XntufShlX3QtZV97dC0xfSleMn17XHN1bV97dD0xfV57bn1lX3ReMn0NCj1cZnJhY3tgciBzcHJpbnRmKCIlLjBmIiwgc2VvdWxfZHdfbnVtZXJhdG9yKWB9e2ByIHNwcmludGYoIiUuMGYiLCBzZW91bF9kd19kZW5vbWluYXRvcilgfQ0KXGFwcHJveCBgciByb3VuZChzZW91bF9kd19udW1lcmF0b3IgLyBzZW91bF9kd19kZW5vbWluYXRvciwgMilgLiQkDQoNCmBgYHtyIHNlb3VsLWR1cmJpbi13YXRzb259DQpzZW91bF9kdyA8LSBkd3Rlc3Qoc2VvdWxfcnVuX21vZGVsLCBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikNCnNlb3VsX2R3DQpgYGANCg0KVGhlIHN0YXRpc3RpYyBpcyBiZWxvdyAyLCB3aXRoIHN0cm9uZyBldmlkZW5jZSBhZ2FpbnN0ICRIXzA6XHJob18xPTAkIGluIGZhdm91ciBvZiBwb3NpdGl2ZSBhdXRvY29ycmVsYXRpb24uIFVubGlrZSB0aGUgcnVucyB0ZXN0LCBEdXJiaW4tV2F0c29uIHVzZXMgaG93IGZhciBuZWlnaGJvdXJpbmcgcmVzaWR1YWxzIG1vdmUsIGFzIHdlbGwgYXMgdGhlaXIgZGlyZWN0aW9uLg0KDQojIyBTZW91bDogQUNGIG9mIHRoZSBEYWlseSBSZXNpZHVhbHMNCg0KYGBge3Igc2VvdWwtYWNmLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0zLCBvdXQud2lkdGg9Ijg1JSJ9DQphY2Yoc2VvdWxfcnVuX3Jlc2lkdWFscywgbWFpbiA9ICJBQ0Ygb2YgU2VvdWwgcmVzaWR1YWxzOiByZWZpdHRlZCBvbiBjb25zZWN1dGl2ZSBkYXlzIikNCmBgYA0KDQpUaGUgbGFnLTEgY29ycmVsYXRpb24gaXMgJHJfMVxhcHByb3ggYHIgcm91bmQoc2VvdWxfYWNmX3ZhbHVlcyRhY2ZbMl0sIDMpYCQuIFRoZSBhcHByb3hpbWF0ZSBwb2ludHdpc2UgcmVmZXJlbmNlIGxpbWl0cyBhcmUNCg0KJCRccG1cZnJhY3sxLjk2fXtcc3FydHtgciBzZW91bF9uYH19XGFwcHJveFxwbSBgciByb3VuZChzZW91bF9hY2ZfbGltaXQsIDMpYC4kJA0KDQpOZWlnaGJvdXJpbmcgZGFpbHkgcmVzaWR1YWxzIHJlbWFpbiBwb3NpdGl2ZWx5IGNvcnJlbGF0ZWQgYWZ0ZXIgcmVmaXR0aW5nIHRoZSBtZWFuLiBSZWFkIHRoZSBvdGhlciBsYWdzIGZyb20gdGhlIHBsb3QgYXMgd2VsbDsgdGhlIHJlZmVyZW5jZSBsaW5lcyBhcmUgYXBwcm94aW1hdGUgYW5kIGRvIG5vdCBmb3JtIGEgc2ltdWx0YW5lb3VzIGJhbmQuDQoNCiMjIFNlb3VsOiBManVuZy1Cb3ggQWNyb3NzIFR3byBXZWVrcw0KDQpDb21iaW5lIHRoZSBjb3JyZWxhdGlvbnMgYXQgbGFncyAxIHRocm91Z2ggMTQsIHJhdGhlciB0aGFuIHRlc3Rpbmcgb25seSBuZWlnaGJvdXJpbmcgZGF5czoNCg0KJCRRPW4obisyKVxzdW1fe2s9MX1eezE0fVxmcmFje3Jfa14yfXtuLWt9LiQkDQoNCmBgYHtyIHNlb3VsLWxqdW5nLWJveH0NCnNlb3VsX2xqdW5nX2JveCA8LSBCb3gudGVzdChzZW91bF9ydW5fcmVzaWR1YWxzLCBsYWcgPSAxNCwgdHlwZSA9ICJManVuZy1Cb3giKQ0KYGBgDQoNCmBgYHtyIHNlb3VsLWxqdW5nLWJveC1zdW1tYXJ5LCBlY2hvPUZBTFNFfQ0KdGliYmxlKA0KICBgU3RhdGlzdGljIFFgID0gcm91bmQodW5uYW1lKHNlb3VsX2xqdW5nX2JveCRzdGF0aXN0aWMpLCAyKSwNCiAgYFJlZmVyZW5jZSBkZmAgPSB1bm5hbWUoc2VvdWxfbGp1bmdfYm94JHBhcmFtZXRlciksDQogIGBQLXZhbHVlYCA9IGZvcm1hdC5wdmFsKHNlb3VsX2xqdW5nX2JveCRwLnZhbHVlLCBkaWdpdHMgPSAzKQ0KKSB8PiBrYWJsZSgpDQpgYGANCg0KVGhlIHNtYWxsIFAtdmFsdWUgZ2l2ZXMgZXZpZGVuY2Ugb2YgcmVtYWluaW5nIGF1dG9jb3JyZWxhdGlvbiBhY3Jvc3MgdGhlc2UgbGFncy4gSXQgZG9lcyBub3QgaW1wbHkgdGhhdCBldmVyeSBsYWcgaXMgY29ycmVsYXRlZC4gVGhpcyBpcyBhbiBhcHByb3hpbWF0ZSBkaWFnbm9zdGljIG9uIGZpdHRlZCByZWdyZXNzaW9uIHJlc2lkdWFscywgdXNpbmcgdGhlIGRlZmF1bHQgYGZpdGRmID0gMGAuDQoNClRoZSBydW5zIHRlc3QgZ2F2ZSB3ZWFrZXIgZXZpZGVuY2UgYmVjYXVzZSBpdCBkaXNjYXJkZWQgcmVzaWR1YWwgbWFnbml0dWRlcy4gVGFrZW4gdG9nZXRoZXIsIHRoZSB0aW1lIHBsb3QsIER1cmJpbi1XYXRzb24sIEFDRiBhbmQgTGp1bmctQm94IHN1Z2dlc3QgdGhhdCByZWZpdHRpbmcgdGhlIG1lYW4gaGFzIG5vdCByZW1vdmVkIHRoZSBkZXBlbmRlbmNlLiBUaGVzZSByZXN1bHRzIGNvbmNlcm4gdGhlIDEzMS1kYXkgZml0LCByYXRoZXIgdGhhbiBlc3RhYmxpc2hpbmcgYWRlcXVhY3kgb3ZlciB0aGUgZW50aXJlIGdhcHB5IHllYXIuDQoNCiMjIERpYWdub3N0aWMgU3VtbWFyeQ0KDQpUaGUgdGltZSBwbG90IGNvbWVzIGZpcnN0LCB0aGVuIHRoZSBBQ0YuIFRoZSBydW5zIHRlc3QsIER1cmJpbi1XYXRzb24gYW5kIExqdW5nLUJveCBlYWNoIHN1bW1hcmlzZSBhIGRpZmZlcmVudCBmZWF0dXJlIG9mIHRoZSBvcmRlcmVkIHJlc2lkdWFscywgc28gYSBjb2xsZWN0aW9uIG9mIHNtYWxsIFAtdmFsdWVzIHN1cHBvcnRzIHdoYXQgd2UgY2FuIGFscmVhZHkgc2VlIGluIHRoZSBwbG90cy4gTm9uZSBvZiB0aGVtIGlkZW50aWZpZXMgdGhlIGVycm9yIHByb2Nlc3MgdGhhdCBwcm9kdWNlZCB0aGUgcGF0dGVybi4NCg0KQmVmb3JlIGNoYW5naW5nIHRoZSBlcnJvciBtb2RlbCwgY2hlY2sgdGhlIG1lYW46IGEgbWlzc2luZyB0cmVuZCwgc2Vhc29uYWwgdGVybSBvciBvdXRhZ2UgY2FuIGxlYXZlIGEgcmVzaWR1YWwgcGF0dGVybiBvZiBpdHMgb3duLiBGb3IgYm90aCBNb25leVN0b2NrIGFuZCBTZW91bCB3ZSBmaXR0ZWQgcmVhc29uYWJsZSBtZWFuIG1vZGVscyBhbmQgdGhlIGRlcGVuZGVuY2UgcmVtYWluZWQsIHNvIHdlIHRyZWF0IGl0IGFzIHBhcnQgb2YgdGhlIGVycm9ycyBhbmQgbW9kZWwgaXQgZGlyZWN0bHkuDQoNCiMjIExvb2tpbmcgQWhlYWQNCg0KRXZlcnkgbW9kZWwgd2UgaGF2ZSBmaXR0ZWQgdGhpcyBzZW1lc3RlciBhc3N1bWVkIGluZGVwZW5kZW50IGVycm9ycy4gRmxleGlibGUgY3VydmVzLCBmYWN0b3JzIGFuZCB3ZWlnaHRzIGNoYW5nZWQgdGhlIG1lYW4gb3IgdGhlIHZhcmlhbmNlOyB0aGUgY29ycmVsYXRpb24gYmV0d2VlbiBlcnJvcnMgbmV2ZXIgZW50ZXJlZCB0aGUgbW9kZWwuIEFmdGVyIHRoaXMgbGVjdHVyZSB3ZSBrbm93IGhvdyB0byBkZXRlY3QgdGhhdCBjb3JyZWxhdGlvbiwgYW5kIGluIE1vbmV5U3RvY2sgYW5kIFNlb3VsIGl0IGlzIGNsZWFybHkgdGhlcmUuDQoNCk5leHQgbGVjdHVyZSB3ZSBtb2RlbCBpdC4gQW4gQVIoMSkgZXJyb3IgbW9kZWwsIGZpdHRlZCBieSBnZW5lcmFsaXNlZCBsZWFzdCBzcXVhcmVzIChHTFMpLCBrZWVwcyB0aGUgbWVhbiBmb3JtdWxhIGFuZCBhZGRzIGEgY29ycmVsYXRpb24gc3RydWN0dXJlIHRvIHRoZSBlcnJvcnMgaW5zdGVhZC4gV2Ugd2lsbCBmaXQgdGhlIHRvdXJpc20gbW9kZWwgd2l0aCBgZ2xzKClgIGFuZCBgY29yQVIxKClgLCBjb21wYXJlIHRoZSBzdGFuZGFyZCBlcnJvcnMgd2l0aCB0aGUgb3JkaW5hcnkgZml0LCBhbmQgY2hlY2sgd2hldGhlciB0aGUgbm9ybWFsaXNlZCByZXNpZHVhbHMgbG9vayBjbG9zZXIgdG8gd2hpdGUgbm9pc2UuDQo=