8.11.1

a.

Figure 8.31 shows the ACFs for 36 random numbers, 360 random numbers and 1,000 random numbers. Explain the differences among these figures.

Do they all indicate that the data are white noise?

Starting with the definition of “white noise” which is “a time series that shows no autocorrelation”.

Yes. All three random time series are indeed white noise. Since they’re each comprised of random numbers, there should not be any correlation. To replicate the problem, the three time series for 36, 360, and 1000 random entries are plotted below.

A series is white noise if its mean equals zero. A check of the mean for each series shows this.

## The mean of random36 is -0.095. 
## The mean of random360 is 0.046. 
## The mean of random1000 is -0.029.

Plotting the Acf for each series shows that the correlation bars never exceed the individual bounds.

## Scale for 'x' is already present. Adding another scale for 'x', which will
## replace the existing scale.

Ljung-Box Test

Considers the first h autocorrelation values together. A significant test (a small p value < 0.05) indicates the data are probably not white noise. IOW, we fail to reject the null hypothesis if the p value from the Ljung-Box test is greater than 0.05. We see that each distribution’s p-value is above that threshold.

## 
##  Box-Ljung test
## 
## data:  random36
## X-squared = 16.438, df = 20, p-value = 0.6891
## 
##  Box-Ljung test
## 
## data:  random360
## X-squared = 25.853, df = 20, p-value = 0.1707
## 
##  Box-Ljung test
## 
## data:  random1000
## X-squared = 19.144, df = 20, p-value = 0.5125

White noise is a purely random time series. The Box Ljung test confirms whether you have a white noise time series.

As the author states:

we expect each autocorrelation to be close to zero. Of course, they will not be exactly equal to zero as there is some random variation. For a white noise series, we expect 95% of the spikes in the ACF to lie within \(\pm2/\sqrt{T}\) where \(T\) is the length of the time series.

b.

Why are the critical values at different distances from the mean of zero? Why are the autocorrelations different in each figure when they each refer to white noise?

The critical boundaries lines are defined by the formula: \(\pm1.96/\sqrt{N}\) where \(N\) is the size of the sample. In this problem, the size of the samples grow, therefore the critical bounds will change. The autocorrelations are different with each sample size since as the population grows, the chances that there will be correlations however remote declines.

8.11.2

A classic example of a non-stationary series is the daily closing IBM stock price series (data set ibmclose). Use R to plot the daily closing prices for IBM stock and the ACF and PACF. Explain how each plot shows that the series is non-stationary and should be differenced.

The author states: A stationary time series is one whose properties do not depend on the time at which the series is observed. Thus, time series with trends, or with seasonality, are not stationary - the trend and seasonality will affect the value of the time series at different times.

From the plot below, the closing price shows a slow rise, followed by a plateau, a brisk downward trend, and a bounce off the lows over the time period.

The ACF plot shows all previous lags to be significant and decaying slightly given the length of the lag. The PACF shows only one significant spike.

The ndiffs function shows that we should take one difference.

## [1] 1

The auto arima function shows that the time series should be an ARIMA(1,1,0)

## Series: ibmclose 
## ARIMA(1,1,0) 
## 
## Coefficients:
##          ar1
##       0.0869
## s.e.  0.0519
## 
## sigma^2 estimated as 52.36:  log likelihood=-1249.97
## AIC=2503.94   AICc=2503.98   BIC=2511.76
## 
## Training set error measures:
##                     ME     RMSE      MAE         MPE     MAPE      MASE
## Training set -0.252425 7.216455 5.205757 -0.07643735 1.198182 0.9993315
##                       ACF1
## Training set -0.0005345879

When one difference is applied to the ibmclose time series, we see from the plot that there is no trend nor seasonality.

The ACF plot shows spikes at three different lag periods which means that there’s some correlations in the data even after differencing. However, it is reasonably stationary at this point.

Finally, because the p-value for the differenced ibmclose time series from the Box test is lower than 0.05. That means that the residuals are independent

## 
##  Box-Ljung test
## 
## data:  diff(ibmclose)
## X-squared = 42.308, df = 25, p-value = 0.01665

8.11.3

For the following series, find an appropriate Box-Cox transformation and order of differencing in order to obtain stationary data.

a. usnetelec

The plots below show that the usnetelec time series is not stationary. From the plots below, we see a rising trend over time. Additionally, for a stationary time series, the ACF will drop to zero relatively quickly, while the ACF of non-stationary data decreases slowly.


To confirm that the series is stationary, I applied the Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test:

“The Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test figures out if a time series is stationary around a mean or linear trend, or is non-stationary due to a unit root. A stationary time series is one where statistical properties - like the mean and variance - are constant over time. The null hypothesis for the test is that the data is stationary. The alternate hypothesis for the test is that the data is not stationary”

  https://www.statisticshowto.com/kpss-test/
## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 3 lags. 
## 
## Value of test-statistic is: 1.464 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

Here, we see that the test statistic is 1.464 which means that we reject the null hypothesis that usnetelec is stationary.

The best lambda for usnetelec is: 0.52 and the number of difference is: 2

## [1] "The best lambda for usnetelec is: 0.52 and the number of difference is: 2"

Given that the test statistic is 0.4315 which is lower than the 5% significance level, we fail to reject the null hypothesis.

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 3 lags. 
## 
## Value of test-statistic is: 0.4315 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

b. usgdp

The best lambda for usgdp is: 0.37 and the number of difference is: 1

## [1] "The best lambda for usgdp is: 0.37 and the number of difference is: 1"

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 4 lags. 
## 
## Value of test-statistic is: 0.2013 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

The value of the test-statistic: 0.2013 is lower than any of the critical values so it’s a failure to reject the null hypothesis which is that the differenced time series is stationary.

c. mcopper

## [1] "The best lambda for mcopper is: 0.19 and the number of difference is: 1"

The value of the test-statistic: 0.0573 is lower than any of the critical values so it’s a failure to reject the null hypothesis which is that the differenced time series is stationary.

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 6 lags. 
## 
## Value of test-statistic is: 0.0573 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

d. enplanements

## [1] "The best lambda for mcopper is: -0.23 and the number of difference is: 1"

The value of the test-statistic: 0.0151 is lower than any of the critical values so it’s a failure to reject the null hypothesis which is that the differenced time series is stationary.

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 5 lags. 
## 
## Value of test-statistic is: 0.0151 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

e. visitors

## [1] "The best lambda for visitors is: 0.28 and the number of difference is: 1"

The value of the test-statistic: 0.0519 is lower than any of the critical values so it’s a failure to reject the null hypothesis which is that the differenced time series is stationary.

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 4 lags. 
## 
## Value of test-statistic is: 0.0519 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

8.11.5

For your retail data (from Exercise 3 in Section 2.10), find the appropriate order of differencing (after transformation if necessary) to obtain stationary data.

The best lambda for liquor_sales is: -0.04 and the number of difference is: 1

## [1] "The best lambda for liquor_sales is: -0.04 and the number of difference is: 1"

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 5 lags. 
## 
## Value of test-statistic is: 0.0286 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739
## Series: liquor_sales 
## ARIMA(1,1,2)(0,1,2)[12] 
## 
## Coefficients:
##          ar1      ma1     ma2     sma1    sma2
##       0.8917  -1.3669  0.3773  -0.3661  0.0926
## s.e.  0.0404   0.0686  0.0646   0.0552  0.0523
## 
## sigma^2 estimated as 25.41:  log likelihood=-1116.42
## AIC=2244.85   AICc=2245.08   BIC=2268.29

8.11.6

a.

Use the following R code to generate data from an AR(1) model with \(\phi_1=0.6\) and \(\sigma^2=1\) The process starts with \(y_1=0\)

To automate the code, the custom function, generate_AR1_model, takes in a value for \(\phi_1\) and produces time series

c. 

Write your own code to generate data from an MA(1) model with \(\theta_1=0.6\) and \(\sigma^2=1\)

To automate the code, the custom function, generate_MA1_model, takes in a value for \(\theta_1\) and produces time series

8.11.7

Consider wmurders, the number of women murdered each year (per 100,000 standard population) in the United States.

a.

By studying appropriate graphs of the series in R, find an appropriate ARIMA(p,d,q) model for these data.

Following the steps that the author lays Out:

1. Plot the data and identify any unusual observations.

We see from the plots below that the time series is not stationary. There is a sharp upward trend from 1960 through 1975, a plateau from 1975 to 1995, and then a decline from 1995 past 2000. The ACF shows us that there was significant auto correlation between the time periods. We can clearly see that this time series is not stationary.

2. If necessary, transform the data (using a Box-Cox transformation) to stabilise the variance.

Using the Box-Cox tranformation the variance of the time series was reduced to zero.

## [1] 0.5604752
## [1] 0.04259765

3. If the data are non-stationary, take first differences of the data until the data are stationary.

The time series only becomes stationary after taking 2 difference as the KPSS Unit Root Tests show.

Taking the first difference, wmurders_transformed_diff

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 3 lags. 
## 
## Value of test-statistic is: 0.5466 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

Taking the second difference, wmurders_transformed_ddiff:

## 
## ####################### 
## # KPSS Unit Root Test # 
## ####################### 
## 
## Test is of type: mu with 3 lags. 
## 
## Value of test-statistic is: 0.0532 
## 
## Critical value for a significance level of: 
##                 10pct  5pct 2.5pct  1pct
## critical values 0.347 0.463  0.574 0.739

4. Examine the ACF/PACF to determine the correct ARIMA(p,d,q) structure.

Looking at the ACF and PACF charts, it looks like the best model would be ARIMA(1,2,1).

5.Try your chosen model(s), and use the AICc to search for a better model.

The AICc results confirm that the best values for ARIMA(p,d,q) would be ARIMA(1,2,1).

## Series: wmurders 
## ARIMA(0,2,0) 
## 
## sigma^2 estimated as 0.1007:  log likelihood=-14.38
## AIC=30.76   AICc=30.84   BIC=32.73
## Series: wmurders 
## ARIMA(1,2,0) 
## 
## Coefficients:
##           ar1
##       -0.6719
## s.e.   0.0981
## 
## sigma^2 estimated as 0.05471:  log likelihood=2
## AIC=0   AICc=0.24   BIC=3.94
## Series: wmurders 
## ARIMA(1,2,1) 
## 
## Coefficients:
##           ar1      ma1
##       -0.2434  -0.8261
## s.e.   0.1553   0.1143
## 
## sigma^2 estimated as 0.04632:  log likelihood=6.44
## AIC=-6.88   AICc=-6.39   BIC=-0.97
## Series: wmurders 
## ARIMA(2,2,0) 
## 
## Coefficients:
##           ar1      ar2
##       -0.8289  -0.2246
## s.e.   0.1346   0.1353
## 
## sigma^2 estimated as 0.05292:  log likelihood=3.34
## AIC=-0.68   AICc=-0.19   BIC=5.23
## Series: wmurders 
## ARIMA(0,2,2) 
## 
## Coefficients:
##           ma1     ma2
##       -1.0181  0.1470
## s.e.   0.1220  0.1156
## 
## sigma^2 estimated as 0.04702:  log likelihood=6.03
## AIC=-6.06   AICc=-5.57   BIC=-0.15
## Series: wmurders 
## ARIMA(2,2,2) 
## 
## Coefficients:
##           ar1     ar2      ma1      ma2
##       -0.3200  0.1947  -0.7027  -0.1776
## s.e.   0.5955  0.2161   0.6030   0.5090
## 
## sigma^2 estimated as 0.04597:  log likelihood=7.63
## AIC=-5.26   AICc=-3.98   BIC=4.59

6. Check the residuals from your chosen model by plotting the ACF of the residuals, and doing a portmanteau test of the residuals. If they do not look like white noise, try a modified model. The ACF shows that the residuals are within the confidence boundaries as such they’re not correlated with each other. Also the histogram plot shows a normal distribution, and the portmanteau test returns a large p-value which confirms that the residuals are indeed white noise.

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,2,1)
## Q* = 12.419, df = 8, p-value = 0.1335
## 
## Model df: 2.   Total lags used: 10

b.

Should you include a constant in the model? Explain. No. In the ARIMA model, d=2. According to the author, Hyndman, “For \(d>1\) no constant is allowed as a quadratic or higher order trend is particularly dangerous when forecasting. The parameter \(\mu\) is called the”drift" in the R output when \(d=1\). Using a constant here would introduce drift into the forecast."

c. 

Write this model in terms of the backshift operator. \((1-\phi_1B)(1-B)^{2}y_t = \epsilon_t(1+\theta_1B)\)

d. 

Fit the model using R and examine the residuals. Is the model satisfactory?

Yes. the model is satisfactory. The residuals exhibit white noise behavior which means that they’re independent of each other.

##        ar1 
## 0.08688777

## 
##  Ljung-Box test
## 
## data:  Residuals from ARIMA(1,2,1)
## Q* = 12.419, df = 8, p-value = 0.1335
## 
## Model df: 2.   Total lags used: 10

e.

Forecast three times ahead. Check your forecasts by hand to make sure that you know how they have been calculated.

## [1] 2.589383
##      Point Forecast    Lo 80    Hi 80    Lo 95    Hi 95
## 2005       2.470660 2.194836 2.746484 2.048824 2.892496
## 2006       2.363106 1.986351 2.739862 1.786908 2.939304
## 2007       2.252833 1.765391 2.740276 1.507354 2.998313

f. 

Create a plot of the series with forecasts and prediction intervals for the next three periods shown.

### g. Does auto.arima() give the same model you have chosen? If not, which model do you think is better?

## Series: wmurders 
## ARIMA(1,2,1) 
## 
## Coefficients:
##           ar1      ma1
##       -0.2434  -0.8261
## s.e.   0.1553   0.1143
## 
## sigma^2 estimated as 0.04632:  log likelihood=6.44
## AIC=-6.88   AICc=-6.39   BIC=-0.97
LS0tDQp0aXRsZTogIkRBVEE2MjQgU3ByaW5nIDIwMjEgSFc4IC0gQVJJTUEiDQphdXRob3I6ICJKb2huIEsuIEhhbmNvY2siDQpkYXRlOiAiMy8yMS8yMDIxIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGhpZ2hsaWdodDogcHlnbWVudHMNCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQoNCg0KYGBge3IsIGluY2x1ZGU9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KCdmcHAyJykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2djb3JycGxvdCkNCmxpYnJhcnkobWxiZW5jaCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGNhcmV0KQ0KbGlicmFyeShNQVNTKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoImNvbXBhcmUiKQ0KbGlicmFyeShncmlkRXh0cmEpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoc2Vhc29uYWwpDQpsaWJyYXJ5KHVyY2EpDQpkYXRhKCJpYm1jbG9zZSIpDQpkYXRhKCJ1c25ldGVsZWMiKQ0KZGF0YSgidXNnZHAiKQ0KZGF0YSgibWNvcHBlciIpDQpkYXRhKCJlbnBsYW5lbWVudHMiKQ0KZGF0YSgidmlzaXRvcnMiKQ0KZGF0YSgid211cmRlcnMiKQ0KDQpgYGANCg0KIyMgOC4xMS4xDQoNCiMjIyBhLiANCg0KPGk+RmlndXJlIDguMzEgc2hvd3MgdGhlIEFDRnMgZm9yIDM2IHJhbmRvbSBudW1iZXJzLCAzNjAgcmFuZG9tIG51bWJlcnMgYW5kIDEsMDAwIHJhbmRvbSBudW1iZXJzLiBFeHBsYWluIHRoZSBkaWZmZXJlbmNlcyBhbW9uZyB0aGVzZSBmaWd1cmVzLiA8L2k+DQoNCjxpPkRvIHRoZXkgYWxsIGluZGljYXRlIHRoYXQgdGhlIGRhdGEgYXJlIHdoaXRlIG5vaXNlPzwvaT4NCg0KU3RhcnRpbmcgd2l0aCB0aGUgZGVmaW5pdGlvbiBvZiAid2hpdGUgbm9pc2UiIHdoaWNoIGlzICJhIHRpbWUgc2VyaWVzIHRoYXQgc2hvd3Mgbm8gYXV0b2NvcnJlbGF0aW9uIi4gDQoNClllcy4gQWxsIHRocmVlIHJhbmRvbSB0aW1lIHNlcmllcyBhcmUgaW5kZWVkIHdoaXRlIG5vaXNlLiBTaW5jZSB0aGV5J3JlIGVhY2ggY29tcHJpc2VkIG9mIHJhbmRvbSBudW1iZXJzLCB0aGVyZSBzaG91bGQgbm90IGJlIGFueSBjb3JyZWxhdGlvbi4gVG8gcmVwbGljYXRlIHRoZSBwcm9ibGVtLCB0aGUgdGhyZWUgdGltZSBzZXJpZXMgZm9yIDM2LCAzNjAsIGFuZCAxMDAwIHJhbmRvbSBlbnRyaWVzIGFyZSBwbG90dGVkIGJlbG93Lg0KDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMykNCnJhbmRvbTM2IDwtIHRzKHJub3JtKDM2KSkNCnJhbmRvbTM2MCA8LSB0cyhybm9ybSgzNjApKQ0KcmFuZG9tMTAwMCA8LSB0cyhybm9ybSgxMDAwKSkNCg0KYGBgDQoNCkEgc2VyaWVzIGlzIHdoaXRlIG5vaXNlIGlmIGl0cyBtZWFuIGVxdWFscyB6ZXJvLiAgQSBjaGVjayBvZiB0aGUgbWVhbiBmb3IgZWFjaCBzZXJpZXMgc2hvd3MgdGhpcy4gDQoNCmBgYHtyfQ0KY2F0KHBhc3RlMCgiVGhlIG1lYW4gb2YgcmFuZG9tMzYgaXMgIiwgcm91bmQobWVhbihyYW5kb20zNiksMyksICIuIFxuVGhlIG1lYW4gb2YgcmFuZG9tMzYwIGlzICIsIHJvdW5kKG1lYW4ocmFuZG9tMzYwKSwzKSwgIi4gXG5UaGUgbWVhbiBvZiByYW5kb20xMDAwIGlzICIsIHJvdW5kKG1lYW4ocmFuZG9tMTAwMCksMyksICIuICIpKQ0KDQpgYGANCg0KDQpgYGB7cn0NCmF1dG9wbG90KHJhbmRvbTM2KQ0KYGBgDQoNCmBgYHtyfQ0KYXV0b3Bsb3QocmFuZG9tMzYwKQ0KYGBgDQoNCmBgYHtyfQ0KYXV0b3Bsb3QocmFuZG9tMTAwMCkNCmBgYA0KUGxvdHRpbmcgdGhlIEFjZiBmb3IgZWFjaCBzZXJpZXMgc2hvd3MgdGhhdCB0aGUgY29ycmVsYXRpb24gYmFycyBuZXZlciBleGNlZWQgdGhlIGluZGl2aWR1YWwgYm91bmRzLiANCg0KYGBge3Igd2FybmluZz1GQUxTRX0NCngxIDwtIGdnQWNmKHJhbmRvbTM2KSArIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDUsIDIwKSkgKyANCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xLCAxKSkNCngyIDwtIGdnQWNmKHJhbmRvbTM2MCkgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMSwgMSkpDQp4MyA8LSBnZ0FjZihyYW5kb20xMDAwKSArIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xLCAxKSkNCmdyaWQuYXJyYW5nZSh4MSx4Mix4MyxuY29sPTMpDQpgYGANCg0KTGp1bmctQm94IFRlc3QNCg0KQ29uc2lkZXJzIHRoZSBmaXJzdCBoIGF1dG9jb3JyZWxhdGlvbiB2YWx1ZXMgdG9nZXRoZXIuIEEgc2lnbmlmaWNhbnQgdGVzdCAoYSBzbWFsbCBwIHZhbHVlIDwgMC4wNSkgaW5kaWNhdGVzIHRoZSBkYXRhIGFyZSBwcm9iYWJseSBub3Qgd2hpdGUgbm9pc2UuIElPVywgd2UgZmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBpZiB0aGUgcCB2YWx1ZSBmcm9tIHRoZSBManVuZy1Cb3ggdGVzdCBpcyBncmVhdGVyIHRoYW4gMC4wNS4gV2Ugc2VlIHRoYXQgZWFjaCBkaXN0cmlidXRpb24ncyBwLXZhbHVlIGlzIGFib3ZlIHRoYXQgdGhyZXNob2xkLiANCg0KDQpgYGB7cn0NCkJveC50ZXN0KHJhbmRvbTM2LCBsYWc9MjAsIGZpdGRmID0gMCwgdHlwZT0iTGoiKQ0KYGBgDQoNCg0KYGBge3J9DQpCb3gudGVzdChyYW5kb20zNjAsIGxhZz0yMCwgZml0ZGYgPSAwLCB0eXBlPSJMaiIpDQpgYGANCg0KDQoNCmBgYHtyfQ0KQm94LnRlc3QocmFuZG9tMTAwMCwgbGFnPTIwLCBmaXRkZiA9IDAsIHR5cGU9IkxqIikNCmBgYA0KDQpXaGl0ZSBub2lzZSBpcyBhIHB1cmVseSByYW5kb20gdGltZSBzZXJpZXMuIFRoZSBCb3ggTGp1bmcgdGVzdCBjb25maXJtcyB3aGV0aGVyIHlvdSBoYXZlIGEgd2hpdGUgbm9pc2UgdGltZSBzZXJpZXMuIA0KDQoNCkFzIHRoZSBhdXRob3Igc3RhdGVzOg0KDQp3ZSBleHBlY3QgZWFjaCBhdXRvY29ycmVsYXRpb24gdG8gYmUgY2xvc2UgdG8gemVyby4gT2YgY291cnNlLCB0aGV5IHdpbGwgbm90IGJlIGV4YWN0bHkgZXF1YWwgdG8gemVybyBhcyB0aGVyZSBpcyBzb21lIHJhbmRvbSB2YXJpYXRpb24uIEZvciBhIHdoaXRlIG5vaXNlIHNlcmllcywgd2UgZXhwZWN0IDk1JSBvZiB0aGUgc3Bpa2VzIGluIHRoZSBBQ0YgdG8gbGllIHdpdGhpbiAkXHBtMi9cc3FydHtUfSQgd2hlcmUgJFQkIGlzIHRoZSBsZW5ndGggb2YgdGhlIHRpbWUgc2VyaWVzLiANCg0KDQojIyMgYi4gDQoNCjxpPldoeSBhcmUgdGhlIGNyaXRpY2FsIHZhbHVlcyBhdCBkaWZmZXJlbnQgZGlzdGFuY2VzIGZyb20gdGhlIG1lYW4gb2YgemVybz8gV2h5IGFyZSB0aGUgYXV0b2NvcnJlbGF0aW9ucyBkaWZmZXJlbnQgaW4gZWFjaCBmaWd1cmUgd2hlbiB0aGV5IGVhY2ggcmVmZXIgdG8gd2hpdGUgbm9pc2U/PC9pPg0KDQpUaGUgY3JpdGljYWwgYm91bmRhcmllcyBsaW5lcyBhcmUgZGVmaW5lZCBieSB0aGUgZm9ybXVsYTogJFxwbTEuOTYvXHNxcnR7Tn0kIHdoZXJlICROJCBpcyB0aGUgc2l6ZSBvZiB0aGUgc2FtcGxlLiAgSW4gdGhpcyBwcm9ibGVtLCB0aGUgc2l6ZSBvZiB0aGUgc2FtcGxlcyBncm93LCB0aGVyZWZvcmUgdGhlIGNyaXRpY2FsIGJvdW5kcyB3aWxsIGNoYW5nZS4gVGhlIGF1dG9jb3JyZWxhdGlvbnMgYXJlIGRpZmZlcmVudCB3aXRoIGVhY2ggc2FtcGxlIHNpemUgc2luY2UgYXMgdGhlIHBvcHVsYXRpb24gZ3Jvd3MsIHRoZSBjaGFuY2VzIHRoYXQgdGhlcmUgd2lsbCBiZSBjb3JyZWxhdGlvbnMgaG93ZXZlciByZW1vdGUgZGVjbGluZXMuDQoNCg0KDQojIyA4LjExLjINCg0KPGk+QSBjbGFzc2ljIGV4YW1wbGUgb2YgYSBub24tc3RhdGlvbmFyeSBzZXJpZXMgaXMgdGhlIGRhaWx5IGNsb3NpbmcgSUJNIHN0b2NrIHByaWNlIHNlcmllcyAoZGF0YSBzZXQgaWJtY2xvc2UpLiBVc2UgUiB0byBwbG90IHRoZSBkYWlseSBjbG9zaW5nIHByaWNlcyBmb3IgSUJNIHN0b2NrIGFuZCB0aGUgQUNGIGFuZCBQQUNGLiBFeHBsYWluIGhvdyBlYWNoIHBsb3Qgc2hvd3MgdGhhdCB0aGUgc2VyaWVzIGlzIG5vbi1zdGF0aW9uYXJ5IGFuZCBzaG91bGQgYmUgZGlmZmVyZW5jZWQuPC9pPg0KDQpUaGUgYXV0aG9yIHN0YXRlczogPGk+QSBzdGF0aW9uYXJ5IHRpbWUgc2VyaWVzIGlzIG9uZSB3aG9zZSBwcm9wZXJ0aWVzIGRvIG5vdCBkZXBlbmQgb24gdGhlIHRpbWUgYXQgd2hpY2ggdGhlIHNlcmllcyBpcyBvYnNlcnZlZC4gVGh1cywgdGltZSBzZXJpZXMgd2l0aCB0cmVuZHMsIG9yIHdpdGggc2Vhc29uYWxpdHksIGFyZSBub3Qgc3RhdGlvbmFyeSAtIHRoZSB0cmVuZCBhbmQgc2Vhc29uYWxpdHkgd2lsbCBhZmZlY3QgdGhlIHZhbHVlIG9mIHRoZSB0aW1lIHNlcmllcyBhdCBkaWZmZXJlbnQgdGltZXMuPC9pPg0KDQpGcm9tIHRoZSBwbG90IGJlbG93LCB0aGUgY2xvc2luZyBwcmljZSBzaG93cyBhIHNsb3cgcmlzZSwgZm9sbG93ZWQgYnkgYSBwbGF0ZWF1LCBhIGJyaXNrIGRvd253YXJkIHRyZW5kLCBhbmQgYSBib3VuY2Ugb2ZmIHRoZSBsb3dzIG92ZXIgdGhlIHRpbWUgcGVyaW9kLg0KDQoNCmBgYHtyfQ0KYXV0b3Bsb3QoaWJtY2xvc2UpDQpgYGANCg0KVGhlIEFDRiBwbG90IHNob3dzIGFsbCBwcmV2aW91cyBsYWdzIHRvIGJlIHNpZ25pZmljYW50IGFuZCBkZWNheWluZyBzbGlnaHRseSBnaXZlbiB0aGUgbGVuZ3RoIG9mIHRoZSBsYWcuIFRoZSBQQUNGIHNob3dzIG9ubHkgb25lIHNpZ25pZmljYW50IHNwaWtlLg0KDQoNCmBgYHtyfQ0KZ2dBY2YoaWJtY2xvc2UpDQpgYGANCg0KYGBge3J9DQpnZ1BhY2YoaWJtY2xvc2UpDQpgYGANCg0KVGhlIG5kaWZmcyBmdW5jdGlvbiBzaG93cyB0aGF0IHdlIHNob3VsZCB0YWtlIG9uZSBkaWZmZXJlbmNlLg0KDQpgYGB7cn0NCm5kaWZmcyhpYm1jbG9zZSkNCmBgYA0KDQpUaGUgYXV0byBhcmltYSBmdW5jdGlvbiBzaG93cyB0aGF0IHRoZSB0aW1lIHNlcmllcyBzaG91bGQgYmUgYW4gQVJJTUEoMSwxLDApDQoNCmBgYHtyfQ0KZml0IDwtIGF1dG8uYXJpbWEoaWJtY2xvc2UsIHNlYXNvbmFsPUZBTFNFLA0KICBzdGVwd2lzZT1GQUxTRSwgYXBwcm94aW1hdGlvbj1GQUxTRSkNCnN1bW1hcnkoZml0KQ0KYGBgDQoNCldoZW4gb25lIGRpZmZlcmVuY2UgaXMgYXBwbGllZCB0byB0aGUgaWJtY2xvc2UgdGltZSBzZXJpZXMsIHdlIHNlZSBmcm9tIHRoZSBwbG90IHRoYXQgdGhlcmUgaXMgbm8gdHJlbmQgbm9yIHNlYXNvbmFsaXR5Lg0KDQoNCmBgYHtyfQ0KYXV0b3Bsb3QoZGlmZihpYm1jbG9zZSkpDQpgYGANCg0KVGhlIEFDRiBwbG90IHNob3dzIHNwaWtlcyBhdCB0aHJlZSBkaWZmZXJlbnQgbGFnIHBlcmlvZHMgd2hpY2ggbWVhbnMgdGhhdCB0aGVyZSdzIHNvbWUgY29ycmVsYXRpb25zIGluIHRoZSBkYXRhIGV2ZW4gYWZ0ZXIgZGlmZmVyZW5jaW5nLiBIb3dldmVyLCBpdCBpcyByZWFzb25hYmx5IHN0YXRpb25hcnkgYXQgdGhpcyBwb2ludC4gDQoNCg0KDQoNCg0KYGBge3J9DQpnZ0FjZihkaWZmKGlibWNsb3NlKSkNCmBgYA0KDQpgYGB7cn0NCmdnUGFjZihkaWZmKGlibWNsb3NlKSkNCmBgYA0KDQpGaW5hbGx5LCBiZWNhdXNlIHRoZSBwLXZhbHVlIGZvciB0aGUgPGI+ZGlmZmVyZW5jZWQgaWJtY2xvc2U8L2I+IHRpbWUgc2VyaWVzIGZyb20gdGhlIEJveCB0ZXN0IGlzIGxvd2VyIHRoYW4gMC4wNS4gVGhhdCBtZWFucyB0aGF0IHRoZSByZXNpZHVhbHMgYXJlIGluZGVwZW5kZW50DQoNCg0KYGBge3J9DQpCb3gudGVzdChkaWZmKGlibWNsb3NlKSwgbGFnPTI1LCAgdHlwZT0iTGp1bmctQm94IikNCmBgYA0KIyMgOC4xMS4zDQo8aT5Gb3IgdGhlIGZvbGxvd2luZyBzZXJpZXMsIGZpbmQgYW4gYXBwcm9wcmlhdGUgQm94LUNveCB0cmFuc2Zvcm1hdGlvbiBhbmQgb3JkZXIgb2YgZGlmZmVyZW5jaW5nIGluIG9yZGVyIHRvIG9idGFpbiBzdGF0aW9uYXJ5IGRhdGEuPC9pPg0KDQoNCiMjIyBDdXN0b20gZnVuY3Rpb24gLSBjcmVhdGVfcGxvdHMgYW5kIEJveENveF9TdGF0aW9uYXJ5DQpUaGlzIGN1c3RvbSBmdW5jdGlvbiwgImNyZWF0ZV9wbG90IiwgY3JlYXRlcyBwbG90cy4NCg0KDQpgYGB7cn0NCiNBIGZ1bmN0aW9uIHRoYXQgcGxvdHMgdGhlIHRpbWUgc2VyaWVzLCB0aGUgQWNmLCBhbmQgdGhlIFBBY2YNCg0KY3JlYXRlX3Bsb3RzIDwtIGZ1bmN0aW9uKHRzLCB0aXRsZSl7DQogICBncmlkLmFycmFuZ2UoIA0KICAgIGF1dG9wbG90KHRzKSArDQogICAgICBnZ3RpdGxlKHRpdGxlKSAsDQogICAgZ3JpZC5hcnJhbmdlKA0KICAgICAgZ2dBY2YodHMpICsNCiAgICAgICAgZ2d0aXRsZShwYXN0ZTAodGl0bGUsICIgQUNGIikpLCANCiAgICAgIGdnUGFjZih0cykgKyANCiAgICAgICAgZ2d0aXRsZShwYXN0ZTAodGl0bGUsICIgUEFDRiIpKSwgbmNvbCA9IDIpLCBucm93ID0gMikNCiAgDQogIA0KfQ0KDQpgYGANCg0KIyMjIEN1c3RvbSBmdW5jdGlvbiAtIEJveENveF9TdGF0aW9uYXJ5DQpUaGlzIGZ1bmN0aW9uIGFwcGxpZXMgYSBCb3ggQ294IHRyYW5zZm9ybWF0aW9uIG9uIGEgdGltZSBzZXJpZXMsIGZpbmRzIGFuZCByZXBvcnRzIG9uIHRoZSBudW1iZXIgb2YgZGlmZmVyZW5jZXMsIGFuZCB0aGVuIGFwcGxpZXMgdGhlIGRpZmZlcmVuY2VzLg0KDQpgYGB7cn0NCiNUaGUgQm94Q294X1N0YXRpb25hcnkgZnVuY3Rpb24gdGFrZXMgaW4gYSB0aW1lIHNlcmllcyBhbmQgdGl0bGUgZm9yIHRoZSBwbG90cyANCkJveENveF9TdGF0aW9uYXJ5IDwtIGZ1bmN0aW9uKHRzLCB0aXRsZSl7DQojVXNlIHRoZSBCb3hDb3ggbGFtYmRhIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIGJlc3QgbGFtYmRhIGFuZCBwcmludCBpdCBvdXQuDQogIGxhbWJkYSA8LSBCb3hDb3gubGFtYmRhKHRzKQ0KI1RyYW5zZm9ybSB0aGUgc2VyaWVzIHdpdGggQm94Q294IGZ1bmN0aW9uIGFuZCB0aGUgYmVzdCBsYW1iZGENCiAgdHNfdHJhbnNmb3JtIDwtIEJveENveCh0cywgbGFtYmRhKQ0KI0ZpbmQgdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlcyB0byB0YWtlIHdpdGggDQogIGRpZmZzIDwtIG5kaWZmcyh0c190cmFuc2Zvcm0pDQojUHJpbnQgb3V0IHRoZSBiZXN0IGxhbWJkYSBhbmQgdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlcw0KICBwcmludChwYXN0ZTAoIlRoZSBiZXN0IGxhbWJkYSBmb3IgIiwgdGl0bGUsICIgaXM6ICIsIHJvdW5kKGxhbWJkYSwyKSwgIiBhbmQgdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlIGlzOiAiLCBkaWZmcykpDQojRm9yIGxvb3AgZGlmZmVyZW50aWF0ZXMgdGhlIHRpbWUgc2VyaWVzIHVzaW5nIHRoZSBkaWZmcy4NCiAgZm9yIChpIGluIGRpZmZzKXsNCiAgICB0c190cmFuc2Zvcm0gPC0gZGlmZih0c190cmFuc2Zvcm0pDQogICAgfQ0KI1JldHVybiB0aGUgQm94IENveCB0cmFuc2Zvcm1lZCB0aW1lIHNlcmllcw0KICByZXR1cm4gKHRzX3RyYW5zZm9ybSkNCiAgfQ0KDQpgYGANCg0KDQojIyMgYS4gdXNuZXRlbGVjDQoNClRoZSBwbG90cyBiZWxvdyBzaG93IHRoYXQgdGhlIHVzbmV0ZWxlYyB0aW1lIHNlcmllcyBpcyBub3Qgc3RhdGlvbmFyeS4gRnJvbSB0aGUgcGxvdHMgYmVsb3csIHdlIHNlZSBhIHJpc2luZyB0cmVuZCBvdmVyIHRpbWUuIEFkZGl0aW9uYWxseSwgZm9yIGEgc3RhdGlvbmFyeSB0aW1lIHNlcmllcywgdGhlIEFDRiB3aWxsIGRyb3AgdG8gemVybyByZWxhdGl2ZWx5IHF1aWNrbHksIHdoaWxlIHRoZSBBQ0Ygb2Ygbm9uLXN0YXRpb25hcnkgZGF0YSBkZWNyZWFzZXMgc2xvd2x5LiAgDQoNCmBgYHtyfQ0KY3JlYXRlX3Bsb3RzKHVzbmV0ZWxlYywgInVzbmV0ZWxlYyIpDQpgYGANCjxiciAvPg0KVG8gY29uZmlybSB0aGF0IHRoZSBzZXJpZXMgaXMgc3RhdGlvbmFyeSwgSSBhcHBsaWVkIHRoZSBLd2lhdGtvd3NraS1QaGlsbGlwcy1TY2htaWR0LVNoaW4gKEtQU1MpIHRlc3Q6DQoNCiJUaGUgS3dpYXRrb3dza2ktUGhpbGxpcHMtU2NobWlkdC1TaGluIChLUFNTKSB0ZXN0IGZpZ3VyZXMgb3V0IGlmIGEgdGltZSBzZXJpZXMgaXMgc3RhdGlvbmFyeSBhcm91bmQgYSBtZWFuIG9yIGxpbmVhciB0cmVuZCwgb3IgaXMgbm9uLXN0YXRpb25hcnkgZHVlIHRvIGEgdW5pdCByb290LiBBIHN0YXRpb25hcnkgdGltZSBzZXJpZXMgaXMgb25lIHdoZXJlIHN0YXRpc3RpY2FsIHByb3BlcnRpZXMgLSBsaWtlIHRoZSBtZWFuIGFuZCB2YXJpYW5jZSAtIGFyZSBjb25zdGFudCBvdmVyIHRpbWUuIFRoZSBudWxsIGh5cG90aGVzaXMgZm9yIHRoZSB0ZXN0IGlzIHRoYXQgdGhlIGRhdGEgaXMgc3RhdGlvbmFyeS4gVGhlIGFsdGVybmF0ZSBoeXBvdGhlc2lzIGZvciB0aGUgdGVzdCBpcyB0aGF0IHRoZSBkYXRhIGlzIG5vdCBzdGF0aW9uYXJ5Ig0KICAgICAgDQogICAgICANCiAgICAgIGh0dHBzOi8vd3d3LnN0YXRpc3RpY3Nob3d0by5jb20va3Bzcy10ZXN0Lw0KDQpgYGB7cn0NCnVyLmtwc3ModXNuZXRlbGVjKSAlPiUgc3VtbWFyeSgpDQpgYGANCg0KSGVyZSwgd2Ugc2VlIHRoYXQgdGhlIHRlc3Qgc3RhdGlzdGljIGlzIDEuNDY0IHdoaWNoIG1lYW5zIHRoYXQgd2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB1c25ldGVsZWMgaXMgc3RhdGlvbmFyeS4gDQoNCg0KVGhlIGJlc3QgbGFtYmRhIGZvciB1c25ldGVsZWMgaXM6IDAuNTIgYW5kIHRoZSBudW1iZXIgb2YgZGlmZmVyZW5jZSBpczogMg0KDQpgYGB7cn0NCnVzbmV0ZWxlY190cmFucyA8LSBCb3hDb3hfU3RhdGlvbmFyeSh1c25ldGVsZWMsICJ1c25ldGVsZWMiKQ0KY3JlYXRlX3Bsb3RzKHVzbmV0ZWxlY190cmFucywgInVzbmV0ZWxlYyB0cmFuc2Zvcm1lZCIpDQpgYGANCg0KR2l2ZW4gdGhhdCB0aGUgdGVzdCBzdGF0aXN0aWMgaXMgMC40MzE1IHdoaWNoIGlzIGxvd2VyIHRoYW4gdGhlIDUlIHNpZ25pZmljYW5jZSBsZXZlbCwgd2UgPGI+ZmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpczwvYj4uDQoNCmBgYHtyfQ0KdXIua3Bzcyh1c25ldGVsZWNfdHJhbnMpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQoNCiMjIyBiLiB1c2dkcA0KDQoNCmBgYHtyfQ0KY3JlYXRlX3Bsb3RzKHVzZ2RwLCAidXNnZHAiKQ0KYGBgDQoNClRoZSBiZXN0IGxhbWJkYSBmb3IgdXNnZHAgaXM6IDAuMzcgYW5kIHRoZSBudW1iZXIgb2YgZGlmZmVyZW5jZSBpczogMQ0KDQpgYGB7cn0NCnVzZ2RwX3RyYW5zIDwtIEJveENveF9TdGF0aW9uYXJ5KHVzZ2RwLCAidXNnZHAiKQ0KY3JlYXRlX3Bsb3RzKHVzZ2RwX3RyYW5zLCAidXNnZHAgdHJhbnNmb3JtZWQiKQ0KYGBgDQoNCg0KYGBge3J9DQp1ci5rcHNzKHVzZ2RwX3RyYW5zKSAlPiUgc3VtbWFyeSgpDQpgYGANCg0KVGhlIHZhbHVlIG9mIHRoZSB0ZXN0LXN0YXRpc3RpYzogMC4yMDEzIGlzIGxvd2VyIHRoYW4gYW55IG9mIHRoZSBjcml0aWNhbCB2YWx1ZXMgc28gaXQncyBhIGZhaWx1cmUgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgd2hpY2ggaXMgdGhhdCB0aGUgZGlmZmVyZW5jZWQgdGltZSBzZXJpZXMgaXMgc3RhdGlvbmFyeS4NCg0KDQoNCiMjIyBjLiBtY29wcGVyDQoNCg0KYGBge3J9DQpjcmVhdGVfcGxvdHMobWNvcHBlciwgIm1jb3BwZXIiKQ0KYGBgDQoNCmBgYHtyfQ0KbWNvcHBlcl90cmFucyA8LSBCb3hDb3hfU3RhdGlvbmFyeShtY29wcGVyLCAibWNvcHBlciIpDQpjcmVhdGVfcGxvdHMobWNvcHBlcl90cmFucywgIm1jb3BwZXIgdHJhbnNmb3JtZWQiKQ0KYGBgDQoNClRoZSB2YWx1ZSBvZiB0aGUgdGVzdC1zdGF0aXN0aWM6IDAuMDU3MyBpcyBsb3dlciB0aGFuIGFueSBvZiB0aGUgY3JpdGljYWwgdmFsdWVzIHNvIGl0J3MgYSBmYWlsdXJlIHRvIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHdoaWNoIGlzIHRoYXQgdGhlIGRpZmZlcmVuY2VkIHRpbWUgc2VyaWVzIGlzIHN0YXRpb25hcnkuDQoNCg0KYGBge3J9DQp1ci5rcHNzKG1jb3BwZXJfdHJhbnMpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQojIyMgZC4gZW5wbGFuZW1lbnRzDQoNCg0KYGBge3J9DQpjcmVhdGVfcGxvdHMoZW5wbGFuZW1lbnRzLCAiZW5wbGFuZW1lbnRzIikNCmBgYA0KDQpgYGB7cn0NCmVucGxhbmVtZW50c190cmFucyA8LSBCb3hDb3hfU3RhdGlvbmFyeShlbnBsYW5lbWVudHMsICJtY29wcGVyIikNCmNyZWF0ZV9wbG90cyhlbnBsYW5lbWVudHNfdHJhbnMsICJlbnBsYW5lbWVudHMgdHJhbnNmb3JtZWQiKQ0KYGBgDQpUaGUgdmFsdWUgb2YgdGhlIHRlc3Qtc3RhdGlzdGljOiAwLjAxNTEgaXMgbG93ZXIgdGhhbiBhbnkgb2YgdGhlIGNyaXRpY2FsIHZhbHVlcyBzbyBpdCdzIGEgZmFpbHVyZSB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB3aGljaCBpcyB0aGF0IHRoZSBkaWZmZXJlbmNlZCB0aW1lIHNlcmllcyBpcyBzdGF0aW9uYXJ5Lg0KDQoNCmBgYHtyfQ0KdXIua3BzcyhlbnBsYW5lbWVudHNfdHJhbnMpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQoNCiMjIyBlLiB2aXNpdG9ycw0KDQoNCmBgYHtyfQ0KY3JlYXRlX3Bsb3RzKHZpc2l0b3JzLCAidmlzaXRvcnMiKQ0KYGBgDQoNCmBgYHtyfQ0KdmlzaXRvcnNfdHJhbnMgPC0gQm94Q294X1N0YXRpb25hcnkodmlzaXRvcnMsICJ2aXNpdG9ycyIpDQpjcmVhdGVfcGxvdHModmlzaXRvcnNfdHJhbnMsICJ2aXNpdG9ycyB0cmFuc2Zvcm1lZCIpDQpgYGANCg0KVGhlIHZhbHVlIG9mIHRoZSB0ZXN0LXN0YXRpc3RpYzogMC4wNTE5IGlzIGxvd2VyIHRoYW4gYW55IG9mIHRoZSBjcml0aWNhbCB2YWx1ZXMgc28gaXQncyBhIGZhaWx1cmUgdG8gcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgd2hpY2ggaXMgdGhhdCB0aGUgZGlmZmVyZW5jZWQgdGltZSBzZXJpZXMgaXMgc3RhdGlvbmFyeS4NCg0KDQpgYGB7cn0NCnVyLmtwc3ModmlzaXRvcnNfdHJhbnMpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQoNCiMjIDguMTEuNQ0KDQo8aT5Gb3IgeW91ciByZXRhaWwgZGF0YSAoZnJvbSBFeGVyY2lzZSAzIGluIFNlY3Rpb24gMi4xMCksIGZpbmQgdGhlIGFwcHJvcHJpYXRlIG9yZGVyIG9mIGRpZmZlcmVuY2luZyAoYWZ0ZXIgdHJhbnNmb3JtYXRpb24gaWYgbmVjZXNzYXJ5KSB0byBvYnRhaW4gc3RhdGlvbmFyeSBkYXRhLjwvaT4NCg0KDQpUaGUgYmVzdCBsYW1iZGEgZm9yIGxpcXVvcl9zYWxlcyBpczogLTAuMDQgYW5kIHRoZSBudW1iZXIgb2YgZGlmZmVyZW5jZSBpczogMQ0KDQpgYGB7cn0NCnJldGFpbGRhdGEgPC0gcmVhZF9leGNlbCgicmV0YWlsLnhsc3giLCBza2lwPTEpDQpsaXF1b3Jfc2FsZXMgPC0gdHMocmV0YWlsZGF0YVssIkEzMzQ5NDE0UiJdLA0KICBmcmVxdWVuY3k9MTIsIHN0YXJ0PWMoMTk4Miw0KSkNCmBgYA0KDQoNCg0KYGBge3J9DQpjcmVhdGVfcGxvdHMobGlxdW9yX3NhbGVzLCAibGlxdW9yX3NhbGVzIikNCmBgYA0KDQoNCmBgYHtyfQ0KbGlxdW9yX3NhbGVzX3RyYW5zIDwtIEJveENveF9TdGF0aW9uYXJ5KGxpcXVvcl9zYWxlcywgImxpcXVvcl9zYWxlcyIpDQpjcmVhdGVfcGxvdHMobGlxdW9yX3NhbGVzX3RyYW5zLCAibGlxdW9yX3NhbGVzX3RyYW5zZm9ybWVkIikNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCnVyLmtwc3MobGlxdW9yX3NhbGVzX3RyYW5zKSAlPiUgc3VtbWFyeSgpDQpgYGANCg0KYGBge3J9DQphdXRvLmFyaW1hKGxpcXVvcl9zYWxlcykNCmBgYA0KDQoNCg0KDQojIyA4LjExLjYNCg0KIyMjIGEuDQo8aT5Vc2UgdGhlIGZvbGxvd2luZyBSIGNvZGUgdG8gZ2VuZXJhdGUgZGF0YSBmcm9tIGFuIEFSKDEpIG1vZGVsIHdpdGggJFxwaGlfMT0wLjYkIGFuZCAkXHNpZ21hXjI9MSQgVGhlIHByb2Nlc3Mgc3RhcnRzIHdpdGggJHlfMT0wJCA8L2k+DQoNClRvIGF1dG9tYXRlIHRoZSBjb2RlLCB0aGUgY3VzdG9tIGZ1bmN0aW9uLCBnZW5lcmF0ZV9BUjFfbW9kZWwsIHRha2VzIGluIGEgdmFsdWUgZm9yICRccGhpXzEkIGFuZCBwcm9kdWNlcyB0aW1lIHNlcmllcw0KDQpgYGB7cn0NCmdlbmVyYXRlX0FSMV9tb2RlbCA8LSBmdW5jdGlvbihwaGkpew0KICAgIHNldC5zZWVkKDIyKQ0KICAgIHkgPC0gdHMobnVtZXJpYygxMDApKQ0KICAgIGUgPC0gcm5vcm0oMTAwKQ0KICAgIGVbMV0gPC0gMA0KICAgIGNvbnN0YW50IDwtIDAgDQogICAgZm9yKGkgaW4gMjoxMDApDQogICAgICB5W2ldIDwtIGNvbnN0YW50ICsgZVtpXSArIHBoaSp5W2ktMV0gDQogICAgcmV0dXJuKHkpDQp9DQpgYGANCg0KIyMjIGIuDQo8aT5Qcm9kdWNlIGEgdGltZSBwbG90IGZvciB0aGUgc2VyaWVzLiBIb3cgZG9lcyB0aGUgcGxvdCBjaGFuZ2UgYXMgeW91IGNoYW5nZSAgJFxwaGlfMSQgPC9pPg0KDQpBcyB0aGUgc2l6ZSBvZiBwaGkgbW92ZXMgZnJvbSBzbWFsbCB0byBsYXJnZSwgdGhlIHZhcmlhYmlsaXR5IG9mIHRoZSB0aW1lIHNlcmllcyBpbmNyZWFzZXMuIA0KDQpgYGB7cn0NCmF1dG9wbG90KGdlbmVyYXRlX0FSMV9tb2RlbCgwLjIpLCBzZXJpZXM9InBoaT0wLjYiKSArDQogIGF1dG9sYXllcihnZW5lcmF0ZV9BUjFfbW9kZWwoMC40KSAsIHNlcmllcyA9ICJwaGk9MC40IikgKw0KICBhdXRvbGF5ZXIoZ2VuZXJhdGVfQVIxX21vZGVsKDAuNikgLHNlcmllcyA9ICJwaGk9MC4yIikgKw0KICBhdXRvbGF5ZXIoZ2VuZXJhdGVfQVIxX21vZGVsKDAuNykgLHNlcmllcyA9ICJwaGk9MC43IikgKw0KICBhdXRvbGF5ZXIoZ2VuZXJhdGVfQVIxX21vZGVsKDAuOCkgLHNlcmllcyA9ICJwaGk9MC44IikgKw0KICB4bGFiKCJUaW1lIikgKw0KICB5bGFiKCJEaWZmZXJlbnQgTGV2ZWxzIG9mIFBoaSIpICsNCiAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQodGl0bGU9IkRpZmZlcmVudCBMZXZlbHMgb2YgUGhpIiksIA0KICAgICAgICAgZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IkFSIikpKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImRlZXBza3libHVlIiwgImRlZXBza3libHVlMSIsImRlZXBza3libHVlMiIsICAiZGVlcHNreWJsdWUzIiwgImRlZXBza3libHVlNCIpKQ0KDQoNCmBgYA0KDQojIyMgYy4gDQoNCjxpPldyaXRlIHlvdXIgb3duIGNvZGUgdG8gZ2VuZXJhdGUgZGF0YSBmcm9tIGFuIE1BKDEpIG1vZGVsIHdpdGggJFx0aGV0YV8xPTAuNiQgYW5kICRcc2lnbWFeMj0xJCAgPC9pPg0KDQpUbyBhdXRvbWF0ZSB0aGUgY29kZSwgdGhlIGN1c3RvbSBmdW5jdGlvbiwgZ2VuZXJhdGVfTUExX21vZGVsLCB0YWtlcyBpbiBhIHZhbHVlIGZvciAkXHRoZXRhXzEkIGFuZCBwcm9kdWNlcyB0aW1lIHNlcmllcw0KDQpgYGB7cn0NCmdlbmVyYXRlX01BMV9tb2RlbCA8LSBmdW5jdGlvbih0aGV0YSl7DQogICAgc2V0LnNlZWQoMjIpDQogICAgeSA8LSB0cyhudW1lcmljKDEwMCkpDQogICAgZSA8LSBybm9ybSgxMDApDQogICAgZVsxXSA8LSAwDQogICAgY29uc3RhbnQgPC0gMA0KICAgIGZvcihpIGluIDI6MTAwKQ0KICAgICAgeVtpXSA8LSAgY29uc3RhbnQgKyBlW2ldICsgdGhldGEqZVtpLTFdIA0KICAgIHJldHVybih5KQ0KfQ0KYGBgDQoNCg0KIyMjIGQuDQoNCjxpPlByb2R1Y2UgYSB0aW1lIHBsb3QgZm9yIHRoZSBzZXJpZXMuIEhvdyBkb2VzIHRoZSBwbG90IGNoYW5nZSBhcyB5b3UgY2hhbmdlICRcdGhldGFfMSQgPC9pPg0KDQokXHRoZXRhXzEkIGRvZXMgbGl0dGxlIHRvIG5vdGhpbmcgdG8gY2hhbmdlIHRoZSB2YXJpYXRpb24gb2YgdGhlIHNlcmllcy4NCg0KYGBge3J9DQphdXRvcGxvdChnZW5lcmF0ZV9NQTFfbW9kZWwoMC4yKSwgc2VyaWVzPSJ0aGV0YT0wLjYiKSArDQogIGF1dG9sYXllcihnZW5lcmF0ZV9NQTFfbW9kZWwoMC40KSAsIHNlcmllcyA9ICJ0aGV0YT0wLjQiKSArDQogIGF1dG9sYXllcihnZW5lcmF0ZV9NQTFfbW9kZWwoMC42KSAsc2VyaWVzID0gInRoZXRhPTAuMiIpICsNCiAgYXV0b2xheWVyKGdlbmVyYXRlX01BMV9tb2RlbCgwLjcpICxzZXJpZXMgPSAidGhldGE9MC43IikgKw0KICBhdXRvbGF5ZXIoZ2VuZXJhdGVfTUExX21vZGVsKDAuOCkgLHNlcmllcyA9ICJ0aGV0YT0wLjgiKSArDQogIHhsYWIoIlRpbWUiKSArDQogIHlsYWIoIkRpZmZlcmVudCBMZXZlbHMgb2YgdGhldGEiKSArDQogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKHRpdGxlPSJEaWZmZXJlbnQgTGV2ZWxzIG9mIHRoZXRhIiksIA0KICAgICAgICAgZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IkFSIikpKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdvbGQiLCAiZ29sZDEiLCJnb2xkMiIsICAiZ29sZDMiLCAiYmxhY2siKSkNCg0KYGBgDQoNCg0KDQojIyMgZS4gDQo8aT5HZW5lcmF0ZSBkYXRhIGZyb20gYW4gQVJNQSgxLDEpIG1vZGVsIHdpdGggJFxwaGlfMT0wLjYsIFx0aGV0YV8xPTAuNiwkIGFuZCAkIFxzaWdtYV4yPTEkIDwvaT4NCg0KDQoNCmBgYHtyfQ0KZ2VuZXJhdGVfQVJNQTFfMV9tb2RlbCA8LSBmdW5jdGlvbihwaGksIHRoZXRhKXsNCiAgICBzZXQuc2VlZCgyMikNCiAgICB5IDwtIHRzKG51bWVyaWMoMTAwKSkNCiAgICBlIDwtIHJub3JtKDEwMCkNCiAgICBlWzFdIDwtIDANCiAgICBjb25zdGFudCA8LSAwDQogICAgZm9yKGkgaW4gMjoxMDApDQogICAgICB5W2ldIDwtICBjb25zdGFudCArIGVbaV0gKyBwaGkqeVtpLTFdICsgdGhldGEqZVtpLTFdIA0KICAgIHJldHVybih5KQ0KfQ0KDQp5ID0gZ2VuZXJhdGVfQVJNQTFfMV9tb2RlbCguNiwgLjYpDQphdXRvcGxvdCh5KQ0KYGBgDQoNCg0KPGk+Zi4gR2VuZXJhdGUgZGF0YSBmcm9tIGFuIEFSKDIpIG1vZGVsIHdpdGggICRccGhpXzEgPSAtMC44JCAkXHBoaV8yID0gLTAuOCQgJFxzaWdtYV4yPTEkPC9pPg0KDQpgYGB7cn0NCmdlbmVyYXRlX0FSMl9tb2RlbCA8LSBmdW5jdGlvbihwaGlfMSwgcGhpXzIpew0KICAgIHNldC5zZWVkKDIyKQ0KICAgIHkgPC0gdHMobnVtZXJpYygxMDApKQ0KICAgIGUgPC0gcm5vcm0oMTAwKQ0KICAgIGNvbnN0YW50IDwtIDAgDQogICAgZm9yKGkgaW4gMzoxMDApDQogICAgICB5W2ldIDwtICBjb25zdGFudCArIGVbaV0gKyBwaGlfMSp5W2ktMV0gKyBwaGlfMip5W2ktMl0gIA0KICAgIHJldHVybih5KQ0KfQ0KDQp5IDwtIGdlbmVyYXRlX0FSMl9tb2RlbCgtMC44LCAuMykNCmF1dG9wbG90KHkpDQpgYGANCjxpPmcuIEdyYXBoIHRoZSBsYXR0ZXIgdHdvIHNlcmllcyBhbmQgY29tcGFyZSB0aGVtLjwvaT4NCg0KVGhlcmUgaXMgZ3JlYXRlciB2YXJpYXRpb24gaW4gdGhlIEFSIDIgcGFydGljdWxhcmx5IHRvd2FyZHMgdGhlIGVuZCBvZiB0aGUgc2VyaWVzLiBUaGUgbW9kZWwgd2hlcmVhcyB0aGUgQVJNQSgxLDEpIG1vZGVsIGhhcyBhIGxvdCBtb3JlDQoNCmBgYHtyfQ0KYXV0b3Bsb3QoZ2VuZXJhdGVfQVJNQTFfMV9tb2RlbCgwLjYsIDAuNiksIHNlcmllcz0iQVJNQSgxLCAxKSIpICsNCiAgYXV0b2xheWVyKGdlbmVyYXRlX0FSMl9tb2RlbCgtMC44LCAwLjMpICwgc2VyaWVzID0gIkFSKDIpIikgKw0KICB4bGFiKCJUaW1lIikgKw0KICB5bGFiKCJEaWZmZXJlbnQgTGV2ZWxzIG9mIHRoZXRhIikgKw0KICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZCh0aXRsZT0iRGlmZmVyZW50IExldmVscyBvZiB0aGV0YSIpLCANCiAgICAgICAgIGZpbGw9Z3VpZGVfbGVnZW5kKHRpdGxlPSJBUk1BIikpKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoICJvcmFuZ2UiLCAgImJsdWUiKSkNCmBgYA0KDQojIyA4LjExLjcNCg0KQ29uc2lkZXIgd211cmRlcnMsIHRoZSBudW1iZXIgb2Ygd29tZW4gbXVyZGVyZWQgZWFjaCB5ZWFyIChwZXIgMTAwLDAwMCBzdGFuZGFyZCBwb3B1bGF0aW9uKSBpbiB0aGUgVW5pdGVkIFN0YXRlcy4NCg0KIyMjIGEuIA0KDQo8aT5CeSBzdHVkeWluZyBhcHByb3ByaWF0ZSBncmFwaHMgb2YgdGhlIHNlcmllcyBpbiBSLCBmaW5kIGFuIGFwcHJvcHJpYXRlIEFSSU1BKHAsZCxxKSBtb2RlbCBmb3IgdGhlc2UgZGF0YS48L2k+PGJyIC8+DQoNCkZvbGxvd2luZyB0aGUgc3RlcHMgdGhhdCB0aGUgYXV0aG9yIGxheXMgT3V0OjxiciAvPg0KDQo8aT4xLiBQbG90IHRoZSBkYXRhIGFuZCBpZGVudGlmeSBhbnkgdW51c3VhbCBvYnNlcnZhdGlvbnMuPC9pPg0KDQpXZSBzZWUgZnJvbSB0aGUgcGxvdHMgYmVsb3cgdGhhdCB0aGUgdGltZSBzZXJpZXMgaXMgbm90IHN0YXRpb25hcnkuIFRoZXJlIGlzIGEgc2hhcnAgdXB3YXJkIHRyZW5kIGZyb20gMTk2MCB0aHJvdWdoIDE5NzUsIGEgcGxhdGVhdSBmcm9tIDE5NzUgdG8gMTk5NSwgYW5kIHRoZW4gYSBkZWNsaW5lIGZyb20gMTk5NSBwYXN0IDIwMDAuIFRoZSBBQ0Ygc2hvd3MgdXMgdGhhdCB0aGVyZSB3YXMgc2lnbmlmaWNhbnQgYXV0byBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRoZSB0aW1lIHBlcmlvZHMuIFdlIGNhbiBjbGVhcmx5IHNlZSB0aGF0IHRoaXMgdGltZSBzZXJpZXMgaXMgbm90IHN0YXRpb25hcnkuDQoNCmBgYHtyfQ0KY3JlYXRlX3Bsb3RzKHdtdXJkZXJzLCAiTXVyZGVycyBvZiBXb21lbiIpDQpgYGANCjxpPjIuIElmIG5lY2Vzc2FyeSwgdHJhbnNmb3JtIHRoZSBkYXRhICh1c2luZyBhIEJveC1Db3ggdHJhbnNmb3JtYXRpb24pIHRvIHN0YWJpbGlzZSB0aGUgdmFyaWFuY2UuPC9pPg0KDQpVc2luZyB0aGUgQm94LUNveCB0cmFuZm9ybWF0aW9uIHRoZSB2YXJpYW5jZSBvZiB0aGUgdGltZSBzZXJpZXMgd2FzIHJlZHVjZWQgdG8gemVyby4NCg0KYGBge3J9DQp2YXIod211cmRlcnMpDQpgYGANCg0KYGBge3J9DQojVXNlIHRoZSBCb3hDb3ggbGFtYmRhIGZ1bmN0aW9uIHRvIGZpbmQgdGhlIGJlc3QgbGFtYmRhIGFuZCBwcmludCBpdCBvdXQuDQogIGxhbWJkYSA8LSBCb3hDb3gubGFtYmRhKHdtdXJkZXJzKQ0KI1RyYW5zZm9ybSB0aGUgc2VyaWVzIHdpdGggQm94Q294IGZ1bmN0aW9uIGFuZCB0aGUgYmVzdCBsYW1iZGENCiAgd211cmRlcnNfdHJhbnNmb3JtZWQgPC0gQm94Q294KHdtdXJkZXJzLCBsYW1iZGEpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KdmFyKHdtdXJkZXJzX3RyYW5zZm9ybWVkKQ0KYGBgDQoNCg0KDQo8aT4zLiBJZiB0aGUgZGF0YSBhcmUgbm9uLXN0YXRpb25hcnksIHRha2UgZmlyc3QgZGlmZmVyZW5jZXMgb2YgdGhlIGRhdGEgdW50aWwgdGhlIGRhdGEgYXJlIHN0YXRpb25hcnkuPC9pPg0KDQpUaGUgdGltZSBzZXJpZXMgb25seSBiZWNvbWVzIHN0YXRpb25hcnkgYWZ0ZXIgdGFraW5nIDIgZGlmZmVyZW5jZSBhcyB0aGUgS1BTUyBVbml0IFJvb3QgVGVzdHMgc2hvdy4gDQoNCg0KVGFraW5nIHRoZSBmaXJzdCBkaWZmZXJlbmNlLCB3bXVyZGVyc190cmFuc2Zvcm1lZF9kaWZmDQoNCmBgYHtyfQ0KDQogIHdtdXJkZXJzX3RyYW5zZm9ybWVkX2RpZmYgPC0gZGlmZih3bXVyZGVyc190cmFuc2Zvcm1lZCkNCmBgYA0KDQoNCg0KYGBge3J9DQpjcmVhdGVfcGxvdHMod211cmRlcnNfdHJhbnNmb3JtZWRfZGlmZiwgIk11cmRlcnMgb2YgV29tZW4gLURpZmYiKQ0KYGBgDQoNCg0KYGBge3J9DQp1ci5rcHNzKHdtdXJkZXJzX3RyYW5zZm9ybWVkX2RpZmYpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQpUYWtpbmcgdGhlIHNlY29uZCBkaWZmZXJlbmNlLCB3bXVyZGVyc190cmFuc2Zvcm1lZF9kZGlmZjoNCg0KYGBge3J9DQp3bXVyZGVyc190cmFuc2Zvcm1lZF9kZGlmZiA8LSBkaWZmKHdtdXJkZXJzX3RyYW5zZm9ybWVkX2RpZmYpDQpgYGANCg0KDQoNCmBgYHtyfQ0KdXIua3Bzcyh3bXVyZGVyc190cmFuc2Zvcm1lZF9kZGlmZikgJT4lIHN1bW1hcnkoKQ0KYGBgDQoNCjxpPjQuIEV4YW1pbmUgdGhlIEFDRi9QQUNGIHRvIGRldGVybWluZSB0aGUgY29ycmVjdCBBUklNQShwLGQscSkgc3RydWN0dXJlLiA8L2k+DQoNCkxvb2tpbmcgYXQgdGhlIEFDRiBhbmQgUEFDRiBjaGFydHMsIGl0IGxvb2tzIGxpa2UgdGhlIGJlc3QgbW9kZWwgd291bGQgYmUgQVJJTUEoMSwyLDEpLiANCg0KDQpgYGB7cn0NCmNyZWF0ZV9wbG90cyh3bXVyZGVyc190cmFuc2Zvcm1lZF9kZGlmZiwgIk11cmRlcnMgb2YgV29tZW4gMiBEaWZmIikNCmBgYA0KDQo8aT41LlRyeSB5b3VyIGNob3NlbiBtb2RlbChzKSwgYW5kIHVzZSB0aGUgQUlDYyB0byBzZWFyY2ggZm9yIGEgYmV0dGVyIG1vZGVsLjwvaT4NCg0KVGhlIEFJQ2MgcmVzdWx0cyBjb25maXJtIHRoYXQgdGhlIGJlc3QgdmFsdWVzIGZvciBBUklNQShwLGQscSkgd291bGQgYmUgQVJJTUEoMSwyLDEpLg0KDQpgYGB7cn0NCkFyaW1hKHdtdXJkZXJzLCBvcmRlcj1jKDAsMiwwKSkNCmBgYA0KDQoNCg0KYGBge3J9DQpBcmltYSh3bXVyZGVycywgb3JkZXI9YygxLDIsMCkpDQpgYGANCg0KYGBge3J9DQpBcmltYSh3bXVyZGVycywgb3JkZXI9YygxLDIsMSkpDQpgYGANCg0KDQpgYGB7cn0NCkFyaW1hKHdtdXJkZXJzLCBvcmRlcj1jKDIsMiwwKSkNCmBgYA0KDQpgYGB7cn0NCkFyaW1hKHdtdXJkZXJzLCBvcmRlcj1jKDAsMiwyKSkNCmBgYA0KDQoNCmBgYHtyfQ0KQXJpbWEod211cmRlcnMsIG9yZGVyPWMoMiwyLDIpKQ0KYGBgDQoNCjxpPjYuIENoZWNrIHRoZSByZXNpZHVhbHMgZnJvbSB5b3VyIGNob3NlbiBtb2RlbCBieSBwbG90dGluZyB0aGUgQUNGIG9mIHRoZSByZXNpZHVhbHMsIGFuZCBkb2luZyBhIHBvcnRtYW50ZWF1IHRlc3Qgb2YgdGhlIHJlc2lkdWFscy4gSWYgdGhleSBkbyBub3QgbG9vayBsaWtlIHdoaXRlIG5vaXNlLCB0cnkgYSBtb2RpZmllZCBtb2RlbC48L2k+DQpUaGUgQUNGIHNob3dzIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgd2l0aGluIHRoZSBjb25maWRlbmNlIGJvdW5kYXJpZXMgYXMgc3VjaCB0aGV5J3JlIG5vdCBjb3JyZWxhdGVkIHdpdGggZWFjaCBvdGhlci4gIEFsc28gdGhlIGhpc3RvZ3JhbSBwbG90IHNob3dzIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgYW5kIHRoZSBwb3J0bWFudGVhdSB0ZXN0IHJldHVybnMgYSBsYXJnZSBwLXZhbHVlIHdoaWNoIGNvbmZpcm1zIHRoYXQgdGhlIHJlc2lkdWFscyBhcmUgaW5kZWVkIHdoaXRlIG5vaXNlLiANCg0KYGBge3J9DQpjaGVja3Jlc2lkdWFscyhBcmltYSh3bXVyZGVycywgb3JkZXI9YygxLDIsMSkpKQ0KYGBgDQoNCiMjIyBiLg0KPGk+U2hvdWxkIHlvdSBpbmNsdWRlIGEgY29uc3RhbnQgaW4gdGhlIG1vZGVsPyBFeHBsYWluLjwvaT4NCk5vLiAgSW4gdGhlIEFSSU1BIG1vZGVsLCBkPTIuICBBY2NvcmRpbmcgdG8gdGhlIGF1dGhvciwgSHluZG1hbiwgIkZvciAkZD4xJCBubyBjb25zdGFudCBpcyBhbGxvd2VkIGFzIGEgcXVhZHJhdGljIG9yIGhpZ2hlciBvcmRlciB0cmVuZCBpcyBwYXJ0aWN1bGFybHkgZGFuZ2Vyb3VzIHdoZW4gZm9yZWNhc3RpbmcuIFRoZSBwYXJhbWV0ZXIgJFxtdSQgaXMgY2FsbGVkIHRoZSAiZHJpZnQiIGluIHRoZSBSIG91dHB1dCB3aGVuICRkPTEkLiBVc2luZyBhIGNvbnN0YW50IGhlcmUgd291bGQgaW50cm9kdWNlIGRyaWZ0IGludG8gdGhlIGZvcmVjYXN0LiIgDQoNCg0KIyMjIGMuIA0KPGk+V3JpdGUgdGhpcyBtb2RlbCBpbiB0ZXJtcyBvZiB0aGUgYmFja3NoaWZ0IG9wZXJhdG9yLjwvaT4NCiQoMS1ccGhpXzFCKSgxLUIpXnsyfXlfdCA9ICBcZXBzaWxvbl90KDErXHRoZXRhXzFCKSQNCg0KDQojIyMgZC4gDQo8aT5GaXQgdGhlIG1vZGVsIHVzaW5nIFIgYW5kIGV4YW1pbmUgdGhlIHJlc2lkdWFscy4gSXMgdGhlIG1vZGVsIHNhdGlzZmFjdG9yeT88L2k+DQoNClllcy4gdGhlIG1vZGVsIGlzIHNhdGlzZmFjdG9yeS4gIFRoZSByZXNpZHVhbHMgZXhoaWJpdCB3aGl0ZSBub2lzZSBiZWhhdmlvciB3aGljaCBtZWFucyB0aGF0IHRoZXkncmUgaW5kZXBlbmRlbnQgb2YgZWFjaCBvdGhlci4gDQoNCmBgYHtyfQ0KZml0JGNvZWYNCmBgYA0KDQpgYGB7cn0NCmZpdCA8LSBBcmltYSh3bXVyZGVycywgb3JkZXI9YygxLDIsMSkpDQpjaGVja3Jlc2lkdWFscyhmaXQpDQpgYGANCg0KIyMjIGUuDQpGb3JlY2FzdCB0aHJlZSB0aW1lcyBhaGVhZC4gQ2hlY2sgeW91ciBmb3JlY2FzdHMgYnkgaGFuZCB0byBtYWtlIHN1cmUgdGhhdCB5b3Uga25vdyBob3cgdGhleSBoYXZlIGJlZW4gY2FsY3VsYXRlZC4NCg0KYGBge3J9DQp3bXVyZGVyc1s1NV0NCmBgYA0KDQpgYGB7cn0NCmZvcmVjYXN0KGZpdCwgaD0zKQ0KYGBgDQoNCiMjIyBmLiANCkNyZWF0ZSBhIHBsb3Qgb2YgdGhlIHNlcmllcyB3aXRoIGZvcmVjYXN0cyBhbmQgcHJlZGljdGlvbiBpbnRlcnZhbHMgZm9yIHRoZSBuZXh0IHRocmVlIHBlcmlvZHMgc2hvd24uDQoNCmBgYHtyfQ0KYXV0b3Bsb3QoZm9yZWNhc3QoZml0LGg9MykpDQpgYGANCiMjIyBnLg0KRG9lcyBhdXRvLmFyaW1hKCkgZ2l2ZSB0aGUgc2FtZSBtb2RlbCB5b3UgaGF2ZSBjaG9zZW4/IElmIG5vdCwgd2hpY2ggbW9kZWwgZG8geW91IHRoaW5rIGlzIGJldHRlcj8NCmBgYHtyfQ0KYXV0by5hcmltYSh3bXVyZGVycykNCmBgYA0K