We saw previously that when linear models are fitted to time series data, the residuals can display autocorrelation. The consequences of autocorrelation are that

Accounting for Autocorrelation in the Errors

The consequence of standard errors and p-values being out means that we need to account for autocorrelation in the errors when it is present.

This will require two steps:

We now consider modeling the errors using autoregressive models.

Autoregressive Models

In a time series, the errors \(\varepsilon_1, \varepsilon_2, \ldots, \varepsilon_n\) can be thought of as a realization of a random process (in time).

We can model serial correlation between these errors by making each one explicitly dependent on the previous one: \[\varepsilon_t = \phi \varepsilon_{t-1} + \eta_t\] where \(\eta_t~(t=1,2,\ldots,n)\) is white noise, that is, a sequence of independent and identically distributed (normal) random variables with zero mean.

ACF Plots for AR1 Processes

To illustrate an ACF plot for a function demonstrating autocorrelation, we create two variables from white noise

Z1 = rnorm(1000)
X1 = Z1[-1] + 0.85 * Z1[-1000]
X2 = Z1[-1] - 0.85 * Z1[-1000]
par(mfrow = c(1, 2), mai = rep(0.5, 4))
plot(X1, type = "l")
plot(X2, type = "l")

unlabelled

par(mfrow = c(1, 2))
acf(X1)
acf(X2)

unlabelled

The X1 series has correlation of 0.502 at lag 1, while the X2 series has autocorrelation of -0.478 at lag1

Autoregressive Models for Errors in Linear Modelling

If residuals in a linear model for time series data display autocorrelation then we change the model to allow for an AR1 correlation structure for the residuals in our model to account for this.

N.B. More complex models are also possible. For example:

Application to the Tourism Data

Download motel.csv

## tourism <- read_csv(file = "motel.csv")
tourism <- tourism |>
    mutate(Time = round(time_length(Date - min(Date), unit = "month")), Month = factor(month(Date,
        label = TRUE), ordered = FALSE), Year = year(Date))
tourism
# A tibble: 180 × 6
   Date       RoomNights AvePrice  Time Month  Year
   <date>          <dbl>    <dbl> <dbl> <fct> <dbl>
 1 1980-01-01     276986     27.7     0 Jan    1980
 2 1980-02-01     260633     28.7     1 Feb    1980
 3 1980-03-01     291551     28.6     2 Mar    1980
 4 1980-04-01     275383     28.3     3 Apr    1980
 5 1980-05-01     275302     28.7     4 May    1980
 6 1980-06-01     231693     28.6     5 Jun    1980
 7 1980-07-01     238829     29.2     6 Jul    1980
 8 1980-08-01     274215     29.8     7 Aug    1980
 9 1980-09-01     277808     29.6     8 Sep    1980
10 1980-10-01     299060     30.3     9 Oct    1980
# ℹ 170 more rows

tourism.lm <- lm(RoomNights ~ Time + Month, data = tourism)
acf(resid(tourism.lm))

unlabelled

There is a suggestion of exponential decay in autocorrelations. - AR1 model (with positive \(\phi\)) for errors seems reasonable.

The model incorporating the AR1 error process, and written in regression format, is as follows:

\[\begin{aligned} Y_{t} &= \beta_0 + \beta_1 \mbox{Time} + \beta_2 z_{t,2} + \beta_3 z_{t,3} + \ldots + \beta_{12} z_{t,12} + \varepsilon_t \\ \varepsilon_t &= \phi \varepsilon_{t-1} + \eta_{t}\end{aligned}\]

where:

Model Fitting with Autoregressive Errors

To fit a model with AR1 errors, we must:

The AR1 parameter, \(\phi\), can be estimated by the method of (restricted) maximum likelihood.

The details are beyond the scope of this paper, but you will meet maximum likelihood estimation if you take 161.304 or 161.331.

Once \(\phi\) is estimated, we can account for the AR1 nature of the errors by fitting the linear model using generalized least squares.

Generalized Least Squares

Once we have \(\phi\) estimated, we can then estimate the regression coefficients \(\beta\) by rearranging the regression equation to eliminate the autocorrelation:

Suppose \[ \begin{aligned} y_t &= \beta_0 + \beta_1 x_t + \varepsilon_t\\ \varepsilon_t &= \phi \varepsilon_{t-1} + \eta_t \end{aligned} \] where \(\eta_t \underset{\mathsf{iid}}\sim N(0, 1)\). Then \[ \begin{aligned} y_t - \phi y_{t-1} &= \beta_0 + \beta_1 x_t + \varepsilon_t - \phi (\beta_0 + \beta_1 x_{t-1} + \varepsilon_{t-1})\\ &= \beta_0(1 - \phi) + \beta_1 (x_t - \phi x_{t-1}) + \varepsilon_t - \phi \varepsilon_{t-1}\\ &= \beta_0(1 - \phi) + \beta_1 (x_t - \phi x_{t-1}) + \eta_t \end{aligned} \] which is a standard linear regression in the new variables \(Y_t = y_t - \phi y_{t-1}\), \(X_t = x_t - \phi x_{t-1}\).

Thus we can fit this with least squares. The “generalised” bit is the trick we use to transform something that is not regular least squares to a least squares situation - it turns out we can do this no matter what the covariance structure is among the predictors as long as the structure is estimable from the data.

Generalized Least Squares in R

In R, linear models can be fitted using this technique using the gls() command found in the nlme add-on package.

Call this package using library(nlme) before using the gls() command.

library(nlme)

Generalized Least Squares and the Tourism Data

tourism.gls <- gls(RoomNights ~ Time + Month, correlation = corAR1(), data = tourism)
anova(tourism.gls)
Denom. DF: 167 
            numDF  F-value p-value
(Intercept)     1 45239.15  <.0001
Time            1  1092.85  <.0001
Month          11    81.94  <.0001

The use of an AR1 error process is obtained by setting correlation=corAR1() in the gls() command.

Both Time and Month are associated with RoomNights (P-value less than \(0.0001\) in both cases).

summary(tourism.gls)
Generalized least squares fit by REML
  Model: RoomNights ~ Time + Month 
  Data: tourism 
       AIC      BIC    logLik
  3727.911 3774.681 -1848.955

Correlation Structure: AR(1)
 Formula: ~1 
 Parameter estimate(s):
     Phi 
0.392721 

Coefficients:
                Value Std.Error   t-value p-value
(Intercept) 275492.20  4692.407  58.71021  0.0000
Time          1062.25    31.870  33.33115  0.0000
MonthFeb    -31194.09  4205.044  -7.41825  0.0000
MonthMar     23482.73  4959.531   4.73487  0.0000
MonthApr     -2170.47  5225.494  -0.41536  0.6784
MonthMay    -19419.12  5325.710  -3.64630  0.0004
MonthJun    -65827.11  5362.987 -12.27434  0.0000
MonthJul    -44522.34  5373.207  -8.28599  0.0000
MonthAug    -29768.74  5365.559  -5.54812  0.0000
MonthSep    -12039.27  5331.948  -2.25795  0.0252
MonthOct     26393.95  5238.620   5.03834  0.0000
MonthNov     16471.67  4988.022   3.30224  0.0012
MonthDec    -58631.94  4272.401 -13.72342  0.0000

 Correlation: 
         (Intr) Time   MnthFb MnthMr MnthAp MnthMy MnthJn MnthJl MnthAg MnthSp
Time     -0.586                                                               
MonthFeb -0.447  0.003                                                        
MonthMar -0.525 -0.001  0.589                                                 
MonthApr -0.551 -0.005  0.462  0.659                                          
MonthMay -0.558 -0.011  0.416  0.535  0.682                                   
MonthJun -0.559 -0.016  0.398  0.487  0.560  0.690                            
MonthJul -0.557 -0.022  0.391  0.468  0.512  0.568  0.692                     
MonthAug -0.552 -0.028  0.387  0.460  0.492  0.520  0.571  0.692              
MonthSep -0.545 -0.034  0.383  0.454  0.481  0.498  0.520  0.569  0.690       
MonthOct -0.532 -0.039  0.376  0.445  0.470  0.482  0.493  0.513  0.561  0.683
MonthNov -0.502 -0.044  0.358  0.423  0.446  0.456  0.463  0.471  0.491  0.538
MonthDec -0.426 -0.048  0.308  0.364  0.384  0.392  0.396  0.400  0.407  0.425
         MnthOc MnthNv
Time                  
MonthFeb              
MonthMar              
MonthApr              
MonthMay              
MonthJun              
MonthJul              
MonthAug              
MonthSep              
MonthOct              
MonthNov  0.662       
MonthDec  0.471  0.597

Standardized residuals:
       Min         Q1        Med         Q3        Max 
-2.5656600 -0.6285951 -0.1307054  0.5424996  3.2823396 

Residual standard error: 14799.38 
Degrees of freedom: 180 total; 167 residual

Comments on the Analysis

The estimated value of AR1 correlation parameter is \(\hat \phi = 0.393\).

Comparison of the output from summary(tourism.gls) with the corresponding output from the earlier analysis (assuming independent errors) shows that the standard errors are usually larger here, particularly for the intercept and the coefficient of Time:

# A tibble: 2 × 4
  model term  estimate std.error
  <chr> <chr>    <dbl>     <dbl>
1 gls   Time     1062.      31.9
2 lm    Time     1059.      21.2

The only remaining question is, was the use of gls() successful?

We can get the normalized residuals (i.e. ‘decorrelated’ residuals) with

residuals(tourism.gls, type = "normalized")

acf(residuals(tourism.gls, type = "normalized"))

unlabelled

Next steps?

What might be the next step? It looks like there is a significant 12-month correlation, which would also make sense.

But we will leave the task of adjusting for more complicated correlation structures for another course.

LS0tDQp0aXRsZTogIkxlY3R1cmUgMzU6IE1vZGVscyB3aXRoIEF1dG9yZWdyZXNzaXZlIEVycm9ycyINCnN1YnRpdGxlOiAxNjEuMjUxIFJlZ3Jlc3Npb24gTW9kZWxsaW5nDQphdXRob3I6ICJQcmVzZW50ZWQgYnkgSm9uYXRoYW4gTWFyc2hhbGwgPEouQy5tYXJzaGFsbEBtYXNzZXkuYWMubno+IiAgDQpkYXRlOiAiV2VlayAxMiBvZiBTZW1lc3RlciAyLCBgciBsdWJyaWRhdGU6OnllYXIobHVicmlkYXRlOjpub3coKSlgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGlvc2xpZGVzX3ByZXNlbnRhdGlvbjoNCiAgICB3aWRlc2NyZWVuOiB0cnVlDQogICAgc21hbGxlcjogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHNsaWR5X3ByZXNlbnRhdGlvbjogDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KDQoNCjwhLS0tIERhdGEgaXMgb24NCmh0dHBzOi8vci1yZXNvdXJjZXMubWFzc2V5LmFjLm56L2RhdGEvMTYxMjUxLw0KLS0tPg0KDQpgYGB7ciBzZXR1cCwgcHVybD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldChkZXY9YygicG5nIiwgInBkZiIpKQ0Kb3B0c19jaHVuayRzZXQoZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgZmlnLnBhdGg9IkZpZ3VyZXMvIiwgZmlnLmFsdD0idW5sYWJlbGxlZCIpDQpvcHRzX2NodW5rJHNldChjb21tZW50PSIiLCBmaWcuYWxpZ249ImNlbnRlciIsIHRpZHk9VFJVRSkNCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCjwhLS0tIERvIG5vdCBlZGl0IGFueXRoaW5nIGFib3ZlIHRoaXMgbGluZS4gLS0tPg0KDQoNCmBgYHtyIGV4dHJhTGliLCBpbmNsdWRlPUZBTFNFfSANCmxpYnJhcnkobmxtZSkgICAgICAgIA0KYGBgDQoNCg0KIyMNCg0KV2Ugc2F3IHByZXZpb3VzbHkgdGhhdCB3aGVuIGxpbmVhciBtb2RlbHMgYXJlIGZpdHRlZCB0byB0aW1lIHNlcmllcyBkYXRhLCB0aGUgcmVzaWR1YWxzIGNhbiBkaXNwbGF5IGF1dG9jb3JyZWxhdGlvbi4gVGhlIGNvbnNlcXVlbmNlcyBvZiBhdXRvY29ycmVsYXRpb24gYXJlIHRoYXQNCg0KLSBzdGFuZGFyZCBlcnJvcnMgZ2l2ZW4gYnkgc3RhbmRhcmQgbGVhc3Qgc3F1YXJlcyB0aGVvcnkgKGFuZA0KICAgIGhlbmNlIGJ5IHN0YW5kYXJkIFIgb3V0cHV0KSB3aWxsIHVzdWFsbHkgYmUgc21hbGxlciB0aGFuIHRoZSB0cnVlDQogICAgc3RhbmRhcmQgZGV2aWF0aW9ucyBvZiB0aGUgcGFyYW1ldGVyIGVzdGltYXRlcy4NCiAgICANCi0gdGhlIHJlc3VsdCBpcyB0aGF0ICp0Ki10ZXN0IHN0YXRpc3RpY3Mgd2lsbCBiZSBpbmZsYXRlZCwgcC12YWx1ZXMgdG9vIHNtYWxsLCBhbmQgDQogICAgY29uZmlkZW5jZSBpbnRlcnZhbHMgd2lsbCBiZSB0b28gbmFycm93Lg0KICAgIA0KDQojIyBBY2NvdW50aW5nIGZvciBBdXRvY29ycmVsYXRpb24gaW4gdGhlIEVycm9ycw0KDQpUaGUgY29uc2VxdWVuY2Ugb2Ygc3RhbmRhcmQgZXJyb3JzIGFuZCBwLXZhbHVlcyBiZWluZyBvdXQgbWVhbnMgdGhhdCB3ZSBuZWVkIHRvIGFjY291bnQgZm9yIGF1dG9jb3JyZWxhdGlvbiBpbiB0aGUgZXJyb3JzIHdoZW4gaXQgaXMgcHJlc2VudC4NCg0KVGhpcyB3aWxsIHJlcXVpcmUgdHdvIHN0ZXBzOg0KICAgIA0KLSBEZWZpbml0aW9uIG9mIGFuIGFwcHJvcHJpYXRlIG1vZGVsIGZvciBhdXRvY29ycmVsYXRlZCBlcnJvcnM7DQotIEZpdHRpbmcgdGhlIGxpbmVhciBtb2RlbCB3aXRoIGF1dG9jb3JyZWxhdGVkIGVycm9ycy4NCg0KV2Ugbm93IGNvbnNpZGVyIG1vZGVsaW5nIHRoZSAgZXJyb3JzIHVzaW5nIGF1dG9yZWdyZXNzaXZlIG1vZGVscy4NCg0KIyMgQXV0b3JlZ3Jlc3NpdmUgTW9kZWxzDQoNCkluIGEgdGltZSBzZXJpZXMsIHRoZSBlcnJvcnMgJFx2YXJlcHNpbG9uXzEsIFx2YXJlcHNpbG9uXzIsIFxsZG90cywgXHZhcmVwc2lsb25fbiQNCiAgICBjYW4gYmUgdGhvdWdodCBvZiBhcyBhIHJlYWxpemF0aW9uIG9mIGEgcmFuZG9tIHByb2Nlc3MgKGluIHRpbWUpLg0KDQpXZSBjYW4gbW9kZWwgc2VyaWFsIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlc2UgZXJyb3JzIGJ5IG1ha2luZyBlYWNoDQogICAgb25lIGV4cGxpY2l0bHkgZGVwZW5kZW50IG9uIHRoZSBwcmV2aW91cyBvbmU6DQogICAgJCRcdmFyZXBzaWxvbl90ID0gXHBoaSBcdmFyZXBzaWxvbl97dC0xfSArIFxldGFfdCQkIHdoZXJlICRcZXRhX3R+KHQ9MSwyLFxsZG90cyxuKSQgaXMgKip3aGl0ZSAgbm9pc2UqKiwgdGhhdCBpcywgYSBzZXF1ZW5jZSBvZiBpbmRlcGVuZGVudCBhbmQgaWRlbnRpY2FsbHkgZGlzdHJpYnV0ZWQgIChub3JtYWwpIHJhbmRvbSB2YXJpYWJsZXMgd2l0aCB6ZXJvIG1lYW4uDQoNCi0gVGhpcyBlcXVhdGlvbiAgaXMgYSBmaXJzdCBvcmRlciBhdXRvcmVncmVzc2l2ZSAob3IgICAgICoqQVIxKiopIG1vZGVsIGZvciAkXHZhcmVwc2lsb25fdCQuDQotIFVuZGVyIHRoaXMgbW9kZWwsICRcbWJveHtDb3JyfShcdmFyZXBzaWxvbl90LCBcdmFyZXBzaWxvbl97dC0xfSkgPSBccGhpJC4NCi0gQ29uc2VxdWVudGx5LCBtb3JlIGdlbmVyYWxseSwgJFxtYm94e0NvcnJ9KFx2YXJlcHNpbG9uX3QsIFx2YXJlcHNpbG9uX3t0LWt9KSA9IFxwaGleayQNCg0KIyMgQUNGIFBsb3RzIGZvciBBUjEgUHJvY2Vzc2VzDQoNClRvIGlsbHVzdHJhdGUgYW4gQUNGIHBsb3QgZm9yIGEgZnVuY3Rpb24gZGVtb25zdHJhdGluZyBhdXRvY29ycmVsYXRpb24sIHdlIGNyZWF0ZSB0d28gdmFyaWFibGVzIGZyb20gd2hpdGUgbm9pc2UgDQoNCmBgYHtyIHdoaXRlTm9pc2UsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTN9DQpaMSA9IHJub3JtKDEwMDApDQpYMSA9IFoxWy0xXSArIDAuODUqWjFbLTEwMDBdDQpYMiA9IFoxWy0xXSAtIDAuODUqWjFbLTEwMDBdDQpwYXIobWZyb3c9YygxLDIpLCBtYWk9cmVwKDAuNSwgNCkpDQpwbG90KFgxLCB0eXBlPSJsIikNCnBsb3QoWDIsIHR5cGU9ImwiKQ0KYGBgDQoNCiMjDQoNCmBgYHtyIHdoaXRlTm9pc2UyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0KcGFyKG1mcm93PWMoMSwyKSkNCmFjZihYMSkNCmFjZihYMikNCmBgYA0KDQpUaGUgYFgxYCBzZXJpZXMgaGFzIGNvcnJlbGF0aW9uIG9mIGByIHJvdW5kKGNvcihYMVstMV0sWDFbLTk5OV0pLDMpYCBhdCBsYWcgMSwgd2hpbGUgdGhlIGBYMmAgc2VyaWVzIGhhcyBhdXRvY29ycmVsYXRpb24gb2YgYHIgcm91bmQoY29yKFgyWy0xXSxYMlstOTk5XSksMylgIGF0IGxhZzEgDQoNCg0KIyMgQXV0b3JlZ3Jlc3NpdmUgTW9kZWxzIGZvciBFcnJvcnMgaW4gTGluZWFyIE1vZGVsbGluZw0KDQpJZiByZXNpZHVhbHMgaW4gYSBsaW5lYXIgbW9kZWwgZm9yIHRpbWUgc2VyaWVzIGRhdGEgZGlzcGxheSBhdXRvY29ycmVsYXRpb24gdGhlbiB3ZSBjaGFuZ2UgdGhlIG1vZGVsIHRvIGFsbG93IGZvciBhbiBBUjEgY29ycmVsYXRpb24gc3RydWN0dXJlIGZvciB0aGUgcmVzaWR1YWxzIGluIG91ciBtb2RlbCB0byBhY2NvdW50IGZvciB0aGlzLg0KDQpOLkIuIE1vcmUgY29tcGxleCBtb2RlbHMgYXJlIGFsc28gcG9zc2libGUuIEZvciBleGFtcGxlOg0KICAgIA0KLSBBUiBtb2RlbHMgb2Ygb3JkZXIgKnE+MSosIHdoZXJlICRcdmFyZXBzaWxvbl90JCBpcyBtb2RlbGxlZCBhcyBleHBsaWNpdGx5IGRlcGVuZGVudCBvbiB0aGUgcHJldmlvdXMgKnEqIGVycm9yczsNCi0gbW92aW5nIGF2ZXJhZ2UgKE1BKSBtb2RlbHMgYW5kIGF1dG9yZWdyZXNzaXZlIG1vdmluZyBhdmVyYWdlIChBUk1BKSBtb2RlbHMuDQotIEZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBjb3Vyc2Ugd2Ugd2lsbCBmb2N1cyBvbiBBUjEgbW9kZWxzIGZvciB0aGUNCiAgICBlcnJvciBwcm9jZXNzLg0KDQojIyBBcHBsaWNhdGlvbiB0byB0aGUgVG91cmlzbSBEYXRhDQoNCmByIHhmdW46OmVtYmVkX2ZpbGUoIi4uLy4uL2RhdGEvbW90ZWwuY3N2IilgDQoNCg0KYGBge3IgZ2V0VG91cmlzbURhdGEsIGVjaG89LTEsIGV2YWw9LTIsIG1lc3NhZ2U9RkFMU0V9DQp0b3VyaXNtIDwtIHJlYWRfY3N2KGZpbGU9Ii4uLy4uL2RhdGEvbW90ZWwuY3N2IikNCnRvdXJpc20gPC0gcmVhZF9jc3YoZmlsZT0ibW90ZWwuY3N2IikNCnRvdXJpc20gPC0gdG91cmlzbSB8Pg0KICBtdXRhdGUoVGltZSA9IHJvdW5kKHRpbWVfbGVuZ3RoKERhdGUgLSBtaW4oRGF0ZSksIHVuaXQ9Im1vbnRoIikpLA0KICAgICAgICAgTW9udGggPSBmYWN0b3IobW9udGgoRGF0ZSwgbGFiZWw9VFJVRSksIG9yZGVyZWQ9RkFMU0UpLA0KICAgICAgICAgWWVhciA9IHllYXIoRGF0ZSkpDQp0b3VyaXNtDQpgYGANCg0KIyMNCg0KYGBge3IgVG91cmlzbS5sbVJlc2lkQUNGLGZpZy5oZWlnaHQ9NC41fQ0KdG91cmlzbS5sbSA8LSBsbShSb29tTmlnaHRzIH4gVGltZSArIE1vbnRoLCBkYXRhPXRvdXJpc20pDQphY2YocmVzaWQodG91cmlzbS5sbSkpDQpgYGANCg0KVGhlcmUgaXMgYSBzdWdnZXN0aW9uIG9mIGV4cG9uZW50aWFsIGRlY2F5IGluIGF1dG9jb3JyZWxhdGlvbnMuDQotIEFSMSBtb2RlbCAod2l0aCBwb3NpdGl2ZSAkXHBoaSQpIGZvciBlcnJvcnMgc2VlbXMgcmVhc29uYWJsZS4NCg0KIyMNCg0KVGhlIG1vZGVsIGluY29ycG9yYXRpbmcgdGhlIEFSMSBlcnJvciBwcm9jZXNzLCBhbmQgd3JpdHRlbiBpbiByZWdyZXNzaW9uIGZvcm1hdCwNCmlzIGFzIGZvbGxvd3M6IA0KDQokJFxiZWdpbnthbGlnbmVkfQ0KWV97dH0gJj0gXGJldGFfMCArIFxiZXRhXzEgXG1ib3h7VGltZX0gKyBcYmV0YV8yIHpfe3QsMn0gKyBcYmV0YV8zIHpfe3QsM30gDQorIFxsZG90cyArIFxiZXRhX3sxMn0gel97dCwxMn0gKyBcdmFyZXBzaWxvbl90IFxcDQpcdmFyZXBzaWxvbl90ICY9IFxwaGkgXHZhcmVwc2lsb25fe3QtMX0gKyBcZXRhX3t0fVxlbmR7YWxpZ25lZH0kJCANCg0Kd2hlcmU6DQoNCi0gJFlfdCQgaXMgdGhlICR0JF50aF4gb2JzZXJ2YXRpb24gb2YgYFJvb21OaWdodHNgOw0KLSAkel97dCxqfSA9IDEkIGlmIG9ic2VydmF0aW9uICR0JCBpcyB0YWtlbiBpbiBtb250aCAkaiQ7DQotICR6X3t0LGp9ID0gMCQgb3RoZXJ3aXNlLg0KLSAkXGV0YV8xLCBcbGRvdHMsIFxldGFfbiQgYXJlIGluZGVwZW5kZW50IGFuZCBpZGVudGljYWxseQ0KICAgIGRpc3RyaWJ1dGVkIG5vcm1hbCByYW5kb20gdmFyaWFibGVzIHdpdGggbWVhbiB6ZXJvLg0KDQojIyBNb2RlbCBGaXR0aW5nIHdpdGggQXV0b3JlZ3Jlc3NpdmUgRXJyb3JzDQoNClRvIGZpdCBhIG1vZGVsIHdpdGggQVIxIGVycm9ycywgd2UgbXVzdDoNCg0KLSBFc3RpbWF0ZSB0aGUgc2l6ZSBvZiB0aGUgYXV0b2NvcnJlbGF0aW9uIHBhcmFtZXRlciwgJFxwaGkkLg0KLSBBY2NvdW50IGZvciB0aGUgYXV0b2NvcnJlbGF0aW9uIGluIGVycm9ycyB3aGVuIGVzdGltYXRpbmcgdGhlDQogICAgICAgIHJlZ3Jlc3Npb24gY29lZmZpY2llbnRzLg0KDQpUaGUgQVIxIHBhcmFtZXRlciwgJFxwaGkkLCBjYW4gYmUgZXN0aW1hdGVkIGJ5IHRoZSBtZXRob2Qgb2YNCiAgICAocmVzdHJpY3RlZCkgbWF4aW11bSBsaWtlbGlob29kLg0KDQpUaGUgZGV0YWlscyBhcmUgYmV5b25kIHRoZSBzY29wZSBvZiB0aGlzIHBhcGVyLCBidXQgeW91IHdpbGwgbWVldCBtYXhpbXVtIGxpa2VsaWhvb2QgZXN0aW1hdGlvbiBpZiB5b3UgdGFrZSAxNjEuMzA0IG9yIDE2MS4zMzEuDQoNCk9uY2UgJFxwaGkkIGlzIGVzdGltYXRlZCwgd2UgY2FuIGFjY291bnQgZm9yIHRoZSBBUjEgbmF0dXJlIG9mIHRoZQ0KICAgIGVycm9ycyBieSBmaXR0aW5nIHRoZSBsaW5lYXIgbW9kZWwgdXNpbmcgKipnZW5lcmFsaXplZCBsZWFzdA0KICAgIHNxdWFyZXMqKi4NCiAgICANCiMjIEdlbmVyYWxpemVkIExlYXN0IFNxdWFyZXMNCg0KT25jZSB3ZSBoYXZlICRccGhpJCBlc3RpbWF0ZWQsIHdlIGNhbiB0aGVuIGVzdGltYXRlIHRoZSByZWdyZXNzaW9uIGNvZWZmaWNpZW50cyAkXGJldGEkIGJ5IHJlYXJyYW5naW5nIHRoZSByZWdyZXNzaW9uIGVxdWF0aW9uIHRvIGVsaW1pbmF0ZSB0aGUgYXV0b2NvcnJlbGF0aW9uOg0KDQpTdXBwb3NlDQokJA0KXGJlZ2lue2FsaWduZWR9DQp5X3QgJj0gXGJldGFfMCArIFxiZXRhXzEgeF90ICsgXHZhcmVwc2lsb25fdFxcDQpcdmFyZXBzaWxvbl90ICY9IFxwaGkgXHZhcmVwc2lsb25fe3QtMX0gKyBcZXRhX3QNClxlbmR7YWxpZ25lZH0NCiQkDQp3aGVyZSAkXGV0YV90IFx1bmRlcnNldHtcbWF0aHNme2lpZH19XHNpbSBOKDAsIDEpJC4gVGhlbg0KJCQNClxiZWdpbnthbGlnbmVkfQ0KeV90IC0gXHBoaSB5X3t0LTF9ICY9IFxiZXRhXzAgKyBcYmV0YV8xIHhfdCArIFx2YXJlcHNpbG9uX3QgLSBccGhpIChcYmV0YV8wICsgXGJldGFfMSB4X3t0LTF9ICsgXHZhcmVwc2lsb25fe3QtMX0pXFwNCiY9IFxiZXRhXzAoMSAtIFxwaGkpICsgXGJldGFfMSAoeF90IC0gXHBoaSB4X3t0LTF9KSArIFx2YXJlcHNpbG9uX3QgLSBccGhpIFx2YXJlcHNpbG9uX3t0LTF9XFwNCiY9IFxiZXRhXzAoMSAtIFxwaGkpICsgXGJldGFfMSAoeF90IC0gXHBoaSB4X3t0LTF9KSArIFxldGFfdA0KXGVuZHthbGlnbmVkfQ0KJCQNCndoaWNoIGlzIGEgc3RhbmRhcmQgbGluZWFyIHJlZ3Jlc3Npb24gaW4gdGhlIG5ldyB2YXJpYWJsZXMgJFlfdCA9IHlfdCAtIFxwaGkgeV97dC0xfSQsICRYX3QgPSB4X3QgLSBccGhpIHhfe3QtMX0kLg0KDQpUaHVzIHdlIGNhbiBmaXQgdGhpcyB3aXRoIGxlYXN0IHNxdWFyZXMuIFRoZSAiZ2VuZXJhbGlzZWQiIGJpdCBpcyB0aGUgdHJpY2sgd2UgdXNlIHRvIHRyYW5zZm9ybSBzb21ldGhpbmcgdGhhdCBpcyBub3QgcmVndWxhciBsZWFzdCBzcXVhcmVzIHRvIGEgbGVhc3Qgc3F1YXJlcyBzaXR1YXRpb24gLSBpdCB0dXJucyBvdXQgd2UgY2FuIGRvIHRoaXMgbm8gbWF0dGVyIHdoYXQgdGhlIGNvdmFyaWFuY2Ugc3RydWN0dXJlIGlzIGFtb25nIHRoZSBwcmVkaWN0b3JzIGFzIGxvbmcgYXMgdGhlIHN0cnVjdHVyZSBpcyBlc3RpbWFibGUgZnJvbSB0aGUgZGF0YS4NCg0KIyMgR2VuZXJhbGl6ZWQgTGVhc3QgU3F1YXJlcyBpbiBSDQoNCkluIFIsIGxpbmVhciBtb2RlbHMgY2FuIGJlIGZpdHRlZCB1c2luZyB0aGlzIHRlY2huaXF1ZSB1c2luZyB0aGUgYGdscygpYCBjb21tYW5kIGZvdW5kIGluIHRoZSBgbmxtZWAgYWRkLW9uIHBhY2thZ2UuDQoNCkNhbGwgdGhpcyBwYWNrYWdlIHVzaW5nIGBsaWJyYXJ5KG5sbWUpYCBiZWZvcmUgdXNpbmcgdGhlIGBnbHMoKWAgY29tbWFuZC4NCg0KYGBge3IgZ2V0TGliLCBtZXNzYWdlPUZBTFNFfQ0KbGlicmFyeShubG1lKQ0KYGBgDQoNCi0gVGhlIGBnbHMoKWAgY29tbWFuZCB1c2VzIHRoZSBzYW1lIG1vZGVsIGZvcm11bGEgYXMgYGxtKClgLCBidXQgYWxzbyBhY2NlcHRzIGFuIGFkZGl0aW9uYWwgYXJndW1lbnQgdG8gZGVzY3JpYmUgICAgdGhlIGNvcnJlbGF0aW9uIHN0cnVjdHVyZSBmb3IgdGhlIGVycm9ycy4NCg0KIyMgR2VuZXJhbGl6ZWQgTGVhc3QgU3F1YXJlcyBhbmQgdGhlIFRvdXJpc20gRGF0YQ0KDQpgYGB7ciBUb3VyaXNtLmdsc30NCnRvdXJpc20uZ2xzIDwtIGdscyhSb29tTmlnaHRzIH4gVGltZSArIE1vbnRoLCBjb3JyZWxhdGlvbj1jb3JBUjEoKSwgZGF0YT10b3VyaXNtKSANCmFub3ZhKHRvdXJpc20uZ2xzKQ0KYGBgDQpUaGUgdXNlIG9mIGFuIEFSMSBlcnJvciBwcm9jZXNzIGlzIG9idGFpbmVkIGJ5IHNldHRpbmcgYGNvcnJlbGF0aW9uPWNvckFSMSgpYCBpbiB0aGUgYGdscygpYCBjb21tYW5kLg0KDQpCb3RoIGBUaW1lYCBhbmQgYE1vbnRoYCBhcmUgYXNzb2NpYXRlZCB3aXRoDQogICAgUm9vbU5pZ2h0cyAoKlAqLXZhbHVlIGxlc3MgdGhhbiAkMC4wMDAxJCBpbiBib3RoDQogICAgY2FzZXMpLg0KDQojIw0KDQpgYGB7ciBzdW1tYXJ5VG91cmlzbS5nbHN9DQpzdW1tYXJ5KHRvdXJpc20uZ2xzKQ0KYGBgDQoNCg0KDQojIyBDb21tZW50cyBvbiB0aGUgQW5hbHlzaXMNCg0KVGhlIGVzdGltYXRlZCB2YWx1ZSBvZiBBUjEgY29ycmVsYXRpb24gcGFyYW1ldGVyIGlzICRcaGF0IFxwaGkgPSAwLjM5MyQuDQoNCkNvbXBhcmlzb24gb2YgdGhlIG91dHB1dCBmcm9tIGBzdW1tYXJ5KHRvdXJpc20uZ2xzKWAgd2l0aA0KICAgIHRoZSBjb3JyZXNwb25kaW5nIG91dHB1dCBmcm9tIHRoZSBlYXJsaWVyIGFuYWx5c2lzIChhc3N1bWluZw0KICAgIGluZGVwZW5kZW50IGVycm9ycykgc2hvd3MgdGhhdCB0aGUgc3RhbmRhcmQgZXJyb3JzIGFyZSB1c3VhbGx5DQogICAgbGFyZ2VyIGhlcmUsIHBhcnRpY3VsYXJseSBmb3IgdGhlIGludGVyY2VwdCBhbmQgdGhlIGNvZWZmaWNpZW50IG9mIGBUaW1lYDoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGJyb29tLm1peGVkKQ0KbGlzdChnbHM9dG91cmlzbS5nbHMgfD4gdGlkeSgpLA0KICAgICBsbT10b3VyaXNtLmxtIHw+IHRpZHkoKSkgfD4NCiAgYmluZF9yb3dzKCwgLmlkPSJtb2RlbCIpIHw+DQogIGZpbHRlcih0ZXJtID09ICJUaW1lIikgfD4NCiAgc2VsZWN0KG1vZGVsLCB0ZXJtLCBlc3RpbWF0ZSwgc3RkLmVycm9yKQ0KYGBgDQoNClRoZSBvbmx5IHJlbWFpbmluZyBxdWVzdGlvbiBpcywgd2FzIHRoZSB1c2Ugb2YgYGdscygpYCBzdWNjZXNzZnVsPw0KDQpXZSBjYW4gZ2V0IHRoZSBub3JtYWxpemVkIHJlc2lkdWFscyAoaS5lLiAnZGVjb3JyZWxhdGVkJyByZXNpZHVhbHMpIHdpdGgNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpyZXNpZHVhbHModG91cmlzbS5nbHMsIHR5cGUgPSAibm9ybWFsaXplZCIpDQpgYGANCg0KIyMNCg0KYGBge3IgZ2V0UmVzaWRzfQ0KYWNmKHJlc2lkdWFscyh0b3VyaXNtLmdscywgdHlwZT0ibm9ybWFsaXplZCIpKQ0KYGBgDQoNCiMjIE5leHQgc3RlcHM/DQoNCldoYXQgbWlnaHQgYmUgdGhlIG5leHQgc3RlcD8gIEl0IGxvb2tzIGxpa2UgdGhlcmUgaXMgYSBzaWduaWZpY2FudCAxMi1tb250aCBjb3JyZWxhdGlvbiwgd2hpY2ggd291bGQgYWxzbyBtYWtlIHNlbnNlLg0KDQpCdXQgd2Ugd2lsbCBsZWF2ZSB0aGUgdGFzayBvZiBhZGp1c3RpbmcgZm9yIG1vcmUgY29tcGxpY2F0ZWQgY29ycmVsYXRpb24gc3RydWN0dXJlcyBmb3IgYW5vdGhlciBjb3Vyc2UuDQo=