List of R colors:

http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf

Time Series

Example 1

To gain an better understanding of how time series operate, we will examine the monthly sales figures for a mobile phone Model M sold by a particular retailer. The monthly sales figures over a 24 month period are given in the table below:

Month Monthly Sales Figures (Year 1) Monthly Sales Figures (Year 2)
Jan 197 296
Feb 211 276
Mar 203 305
Apr 247 308
May 239 356
Jun 269 393
Jul 308 363
Aug 262 386
Sep 258 443
Oct 256 308
Nov 261 358
Dec 288 384
  • To begin the times series analysis of this data, we create a data vector MS (Monthly Sales) to contain the sales data:
MS<-c(197,211,203,247,239,269,308,262,258,256,261,288,296,276,305,308,356,393,363,386,443,308,358,384)
MS
length(MS)

Next we need to create a time vector against which these sales figures are plotted: We need a vector with the same length as MS, i.e. with 24 entries, starting at 1 and increasing in increments of 1. * We can automate a lot of this for future examples using the length() and seq() functions

Time <- seq(1,length(MS),1)
Time
length(Time)
  • This creates a sequence of values starting at 1, ending at length(MS) and increasing with a step-size 1.

  • Time and MS now both have 24 entries, so we can plot them on the same graph:

plot(Time,MS,pch=15,col="red",ylab="Monthly Sales Figures", xlab="Month",main="Monthly Sales Figures of Phone Model M")
lines(Time,MS)
  • The function lines() indicates that a line should be drawn between each of the data points of the time series.
  • Recall that the argument pch appearing in plot() selects the type of marker used to mark the data points. Its possible values are 1 to 26.

Forecasting

  • Recall from lectures that we used a linear regression model to model the data in this time series. This model was given by \[ \hat{y}_t=198.03+8.07t \] where \(t\) referred to a month number.

  • We will now create our own R function corresponding to this, which we are going to call Forecast1

Forecast1 <- function(t){
  198.03+8.07*t
}
  • The values predicted by this model at each of the months in Time are now given by
Forecast1(Time)

Mean Absolute Deviation (MAD) & Mean Square Error (MSE)

  • Recall that the Mean Absolute Deviation (MAD) of a model, was given by

\[ MAD= \frac{1}{n}\sum_{t=1}^{N}\vert y_{t}-\hat{y}_t\vert \]

  • \(y_t\) denotes the actual value of the variable \(y\) at time \(t\)
  • \(\hat{y}_t\) denotes the predicted value of the variable \(y\) at time \(t\)
  • \(n\) is the number of observations we have, i.e. the number of actual values \(y_t\).
  • R will calculate this for us automatically as follows:
MAD1<-mean(abs(MS-Forecast1(Time)))
MAD1
  • The code and the formula correspond as follows

    1. MS \(\leftrightarrow y_t\),

    2. Forecast(Time) \(\leftrightarrow \hat{y}_t\)

    3. abs(MS-Forecast1(Time)) \(\leftrightarrow \vert y_t-\hat{y}_t\vert\)

    4. mean(abs(MS-Forecast1(Time))) \(\leftrightarrow \frac{1}{n}\sum_{t=1}^{n}\vert y_t-\hat{y}_t\vert\)

  • Recall also that the Mean Square Error (MSE) of a model is given by \[ MSE=\frac{1}{n}\sum_{t=1}^{n}\vert y_t-\hat{y}_t\vert^2 \]

Exercise 1

Modify this code block to find the MSE of the model.

MSE1<-mean(abs(MS-Forecast1(Time))^2)
MSE1

Prediction Intervals

\(t_{\frac{\alpha}{2},n-2}\) we us the

t_star = abs(qt(0.05,df=22)) # df= Number of months-2

\(x^*\)

x_star=27

\(y^*\)

y_star=Forecast1(27)
y_star

MSE

MSE1

\(\bar{x}\)

x_bar=mean(Time)

\(\Sigma_{i=1}^{n}(x_i-\bar{x})^2\)

Sum1=sum((Time-x_bar)^2)

Upper boundary of CI

y_star+t_star*sqrt(MSE1*(1+1/24+(x_star-x_bar)/Sum1))

Lower boundary of CI

y_star-t_star*sqrt(MSE1*(1+1/24+(x_star-x_bar)/Sum1))

The 90% Prediction Interval

We are 90% confident that sales in the 27th month will be between 362 and 469 units.

Exercise 2

Find the 90% prediction interval for sales in the 27th month.

Exercise 3

The closing values of Apple Inc. (AAPL) Stock on the NASDAQ Stock Exchange from 8 August 2017 to 8 November 2017 are given in the data file AppleQuotes(3M).csv, available on Moodle. (Available at http://www.nasdaq.com)

Using this data set answer the following:

  1. Import the data in this file using the following and call the data structure AAPL
AAPL<-read.csv('AppleQuotes(3M).csv')
  1. Create two data vectors from this file, one for the closing value and one for the day
  1. Create a time series plot for this data.

  2. From this data plot, determine if there is a trend in the closing value of Apple stock over the past 3 months.

  3. Use the function lm(Closing Value ~ Day) to create a linear regression model for this data.

lm(Closing~Day)
  1. Create a linear model to forecast this data.

  2. Create an R function to represent this model.

  3. Find the MAD and MSE of this model

  4. Find the 95% prediction interval for the closing price of Apple Stock in 10 days from now.

Exercise 4

The closing values of Google Inc. (GOOGL) Stock on the NASDAQ Stock Exchange from 8 November 2016 to 8 November 2017 are given in the data file GoogleQuotes(3M).csv, available on Moodle . (Available at http://www.nasdaq.com).

Using this data set answer the following:

  1. Import the data in this file using the following and call the data structure GOOGL
GOOGL<-read.csv('GoogleQuotes(1Y).csv')
  1. Create two data vectors from this file, one for the trading value and one for the day

  2. Create a time series plot for this data.

  3. From this data plot, determine if there is a trend in the closing value of Google stock over the past year.

  4. Use the function lm(Trading Value ~ Day) to create a linear regression model for this data.

  1. Create a linear model to forecast this data.

  2. Create an R function to represent this model.

  3. Find the MAD and MSE of this model

  4. Find the 90% and 99% prediction intervals for the trading volume of Google Stock in 10 days from now.

Exercise 5

The % Growth in GDP of Chin, the UK, the US, Ireland, the EU, the OECD and the World, for the years 1961-2016 are given in the data file RegionalGDPGrowth(1961-2016).csv. Import this data file into R and answer the following questions. (Available at http://www.worldbank.org)

  1. Create a data vector for the Year a separate vector for the GDP growth of each country in the data file.

  2. Use the function par(mfrow=c(A,B)) to create a collection of time-series plots in A=1 row and B=2 columns for the GDP growth of China and the US To illustrate how this function works, the time-series plot from Example 1 is plotted in 1 row and 2 columns

par(mfrow=c(1,2))
plot(Time,MS,pch=15,col="red",ylab="Monthly Sales Figures", xlab="Month",main="Monthly Sales Figures of Phone Model M")
lines(Time,MS)
plot(Time,MS,pch=15,col="red",ylab="Monthly Sales Figures", xlab="Month",main="Monthly Sales Figures of Phone Model M")
lines(Time,MS)
  1. Use the function par(mfrow=c(A,B)) to create a collection of time-series plots in A=3 row and B=1 columns for the GDP growth of China and the US, the UK

  2. Use the function par(mfrow=c(A,B)) to create a collection of time-series plots in A=2 row and B=2 columns for the GDP growth of the EU, the US, the OECD and the World.

  3. Is there any apparent trend in economic growth observable from these time-series.

  4. From the time-series plots, which region has shown the most consistent economic growth between 1961 and 2016.

LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpc2F0aW9uIDIwMTkgLSBBc3NpZ25tZW50IDYiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KCgoKIyMgTGlzdCBvZiBSIGNvbG9yczoKaHR0cDovL3d3dy5zdGF0LmNvbHVtYmlhLmVkdS9+dHpoZW5nL2ZpbGVzL1Jjb2xvci5wZGYKCgojIFRpbWUgU2VyaWVzCgoqIFRoZSBiYXNpYyBpZGVhIGJlaGluZCB0aW1lIHNlcmllcyBpcyB0aGF0IHdlIHVzZSB0aGUgcGFzdCBiZWhhdmlvciBvZiBhIHZhcmlhYmxlIHRvIHByZWRpY3QgaXRzIGZ1dHVyZSB2YWx1ZXMuCgoqIFRpbWUgc2VyaWVzIGFyaXNlIGluIGEgdmFzdCB2ZXJpdHkgb2YgY2lyY3Vtc3RhbmNlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bzoKICAgIAogICAgKiBEYWlseSBjbG9zaW5nIHN0b2NrIHByaWNlcwogICAgKiBEYWlseSByZWxhdGl2ZSB2YWx1ZXMgb2YgY3VycmVuY2llcwogICAgKiBNb250aGx5IHVuZW1wbG95bWVudCByYXRlcyBpbiBhIGNvdW50cnkKICAgICogUXVhcnRlcmx5IHB1YmxpYyBkZWJ0IGxldmVscyBpbiBhIGNvdW50cnkKICAgICogV2Vla2x5IHZpZXdlcnNoaXAgZmlndXJlcyBvZiBhIFRWIHNlcmllcwogICAgKiBBdmVyYWdlIGFubnVhbCBDTzIgZW1pc3Npb25zCiAgICAqIFF1YXJ0ZXJseSBzYWxlcyBmaWd1cmVzIG9mIGEgcmV0YWlsZXIKICAgICogTW9udGhseSBwcm9kdWN0aW9uIGZpZ3VyZXMgb2YgYSBmYWN0b3J5CiAgICAqIEFubnVhbCAlIGdyb3d0aCBvZiBHRFAgb2YgYW4gZWNvbm9teQogICAgKiBldGMuIGV0Yy4gZXRjLgogICAgCiMjIEV4YW1wbGUgMSAKClRvIGdhaW4gYW4gYmV0dGVyIHVuZGVyc3RhbmRpbmcgb2YgaG93IHRpbWUgc2VyaWVzIG9wZXJhdGUsIHdlIHdpbGwgZXhhbWluZSB0aGUgbW9udGhseSBzYWxlcyBmaWd1cmVzIGZvciBhIG1vYmlsZSBwaG9uZSBfX01vZGVsIE1fXyBzb2xkIGJ5IGEgcGFydGljdWxhciByZXRhaWxlci4gVGhlIG1vbnRobHkgc2FsZXMgZmlndXJlcyBvdmVyIGEgMjQgbW9udGggcGVyaW9kIGFyZSBnaXZlbiBpbiB0aGUgdGFibGUgYmVsb3c6Cgp8ICBNb250aCAgfCBNb250aGx5IFNhbGVzIEZpZ3VyZXMgKFllYXIgMSkgfCBNb250aGx5IFNhbGVzIEZpZ3VyZXMgKFllYXIgMikgIHwKfC0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgICBKYW4gICB8ICAgICAgICAgICAgICAgMTk3ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDI5NiAgICAgICAgICAgICAgICAgfAp8ICAgRmViICAgfCAgICAgICAgICAgICAgIDIxMSAgICAgICAgICAgICAgfCAgICAgICAgICAgICAyNzYgICAgICAgICAgICAgICAgIHwKfCAgIE1hciAgIHwgICAgICAgICAgICAgICAyMDMgICAgICAgICAgICAgIHwgICAgICAgICAgICAgMzA1ICAgICAgICAgICAgICAgICB8CnwgICBBcHIgICB8ICAgICAgICAgICAgICAgMjQ3ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDMwOCAgICAgICAgICAgICAgICAgfAp8ICAgTWF5ICAgfCAgICAgICAgICAgICAgIDIzOSAgICAgICAgICAgICAgfCAgICAgICAgICAgICAzNTYgICAgICAgICAgICAgICAgIHwKfCAgIEp1biAgIHwgICAgICAgICAgICAgICAyNjkgICAgICAgICAgICAgIHwgICAgICAgICAgICAgMzkzICAgICAgICAgICAgICAgICB8CnwgICBKdWwgICB8ICAgICAgICAgICAgICAgMzA4ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDM2MyAgICAgICAgICAgICAgICAgfAp8ICAgQXVnICAgfCAgICAgICAgICAgICAgIDI2MiAgICAgICAgICAgICAgfCAgICAgICAgICAgICAzODYgICAgICAgICAgICAgICAgIHwKfCAgIFNlcCAgIHwgICAgICAgICAgICAgICAyNTggICAgICAgICAgICAgIHwgICAgICAgICAgICAgNDQzICAgICAgICAgICAgICAgICB8CnwgICBPY3QgICB8ICAgICAgICAgICAgICAgMjU2ICAgICAgICAgICAgICB8ICAgICAgICAgICAgIDMwOCAgICAgICAgICAgICAgICAgfAp8ICAgTm92ICAgfCAgICAgICAgICAgICAgIDI2MSAgICAgICAgICAgICAgfCAgICAgICAgICAgICAzNTggICAgICAgICAgICAgICAgIHwKfCAgIERlYyAgIHwgICAgICAgICAgICAgICAyODggICAgICAgICAgICAgIHwgICAgICAgICAgICAgMzg0ICAgICAgICAgICAgICAgICB8CgoqIFRvIGJlZ2luIHRoZSB0aW1lcyBzZXJpZXMgYW5hbHlzaXMgb2YgdGhpcyBkYXRhLCB3ZSBjcmVhdGUgYSBkYXRhIHZlY3RvciBfX01TX18gKE1vbnRobHkgU2FsZXMpIHRvIGNvbnRhaW4gdGhlIHNhbGVzIGRhdGE6CmBgYHtyfQpNUzwtYygxOTcsMjExLDIwMywyNDcsMjM5LDI2OSwzMDgsMjYyLDI1OCwyNTYsMjYxLDI4OCwyOTYsMjc2LDMwNSwzMDgsMzU2LDM5MywzNjMsMzg2LDQ0MywzMDgsMzU4LDM4NCkKTVMKbGVuZ3RoKE1TKQpgYGAKKk5leHQgd2UgbmVlZCB0byBjcmVhdGUgYSBfdGltZSB2ZWN0b3JfIGFnYWluc3Qgd2hpY2ggdGhlc2Ugc2FsZXMgZmlndXJlcyBhcmUgcGxvdHRlZDoKICAgICogV2UgbmVlZCBhIHZlY3RvciB3aXRoIHRoZSBzYW1lIGxlbmd0aCBhcyBfX01TX18sIGkuZS4gd2l0aCAyNCBlbnRyaWVzLCBzdGFydGluZyBhdCAxIGFuZCBpbmNyZWFzaW5nICAgICAgICBpbiBpbmNyZW1lbnRzIG9mIDEuCiAgICAqIFdlIGNhbiBhdXRvbWF0ZSBhIGxvdCBvZiB0aGlzIGZvciBmdXR1cmUgZXhhbXBsZXMgdXNpbmcgdGhlIF9fbGVuZ3RoKClfXyBhbmQgX19zZXEoKV9fIGZ1bmN0aW9ucwpgYGB7cn0KVGltZSA8LSBzZXEoMSxsZW5ndGgoTVMpLDEpClRpbWUKbGVuZ3RoKFRpbWUpCmBgYAoqIFRoaXMgY3JlYXRlcyBhIHNlcXVlbmNlIG9mIHZhbHVlcyBzdGFydGluZyBhdCAxLCBlbmRpbmcgYXQgX19sZW5ndGgoTVMpX18gYW5kIGluY3JlYXNpbmcgd2l0aCBhIHN0ZXAtc2l6ZSAxLgoKKiBfX1RpbWVfXyBhbmQgX19NU19fIG5vdyBib3RoIGhhdmUgMjQgZW50cmllcywgc28gd2UgY2FuIHBsb3QgdGhlbSBvbiB0aGUgc2FtZSBncmFwaDoKYGBge3J9CnBsb3QoVGltZSxNUyxwY2g9MTUsY29sPSJyZWQiLHlsYWI9Ik1vbnRobHkgU2FsZXMgRmlndXJlcyIsIHhsYWI9Ik1vbnRoIixtYWluPSJNb250aGx5IFNhbGVzIEZpZ3VyZXMgb2YgUGhvbmUgTW9kZWwgTSIpCmxpbmVzKFRpbWUsTVMpCmBgYAoqIFRoZSBmdW5jdGlvbiBfX2xpbmVzKClfXyBpbmRpY2F0ZXMgdGhhdCBhIGxpbmUgc2hvdWxkIGJlIGRyYXduIGJldHdlZW4gZWFjaCBvZiB0aGUgZGF0YSBwb2ludHMgb2YgdGhlIHRpbWUgc2VyaWVzLiAKKiBSZWNhbGwgdGhhdCB0aGUgYXJndW1lbnQgX19wY2hfXyBhcHBlYXJpbmcgaW4gX19wbG90KClfXyBzZWxlY3RzIHRoZSB0eXBlIG9mIG1hcmtlciB1c2VkIHRvIG1hcmsgdGhlIGRhdGEgcG9pbnRzLiAgSXRzIHBvc3NpYmxlIHZhbHVlcyBhcmUgMSB0byAyNi4KCiMjIEZvcmVjYXN0aW5nCiogUmVjYWxsIGZyb20gbGVjdHVyZXMgdGhhdCB3ZSB1c2VkIGEgX19saW5lYXIgcmVncmVzc2lvbiBtb2RlbF9fIHRvIG1vZGVsIHRoZSBkYXRhIGluIHRoaXMgdGltZSBzZXJpZXMuIFRoaXMgbW9kZWwgd2FzIGdpdmVuIGJ5ClxbClxoYXR7eX1fdD0xOTguMDMrOC4wN3QKXF0Kd2hlcmUgJHQkIHJlZmVycmVkIHRvIGEgbW9udGggbnVtYmVyLgoKKiBXZSB3aWxsIG5vdyBjcmVhdGUgb3VyIG93biBfX1IgZnVuY3Rpb25fXyBjb3JyZXNwb25kaW5nIHRvIHRoaXMsIHdoaWNoIHdlIGFyZSBnb2luZyB0byBjYWxsIF9fRm9yZWNhc3QxX18KCmBgYHtyfQpGb3JlY2FzdDEgPC0gZnVuY3Rpb24odCl7CiAgMTk4LjAzKzguMDcqdAp9CmBgYAoqIFRoZSB2YWx1ZXMgcHJlZGljdGVkIGJ5IHRoaXMgbW9kZWwgYXQgZWFjaCBvZiB0aGUgbW9udGhzIGluIF9fVGltZV9fIGFyZSBub3cgZ2l2ZW4gYnkKYGBge3J9CkZvcmVjYXN0MShUaW1lKQpgYGAKIyMgTWVhbiBBYnNvbHV0ZSBEZXZpYXRpb24gKE1BRCkgJiBNZWFuIFNxdWFyZSBFcnJvciAoTVNFKQoqIFJlY2FsbCB0aGF0IHRoZSBfX01lYW4gQWJzb2x1dGUgRGV2aWF0aW9uX18gIChfX01BRF9fKSBvZiBhIG1vZGVsLCB3YXMgZ2l2ZW4gYnkKClxbCk1BRD0gXGZyYWN7MX17bn1cc3VtX3t0PTF9XntOfVx2ZXJ0IHlfe3R9LVxoYXR7eX1fdFx2ZXJ0ClxdCiAgICAKICAqICR5X3QkIGRlbm90ZXMgdGhlIGFjdHVhbCB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgJHkkIGF0IHRpbWUgJHQkCiAgKiAkXGhhdHt5fV90JCBkZW5vdGVzIHRoZSBwcmVkaWN0ZWQgdmFsdWUgb2YgdGhlIHZhcmlhYmxlICR5JCBhdCB0aW1lICR0JAogICogJG4kIGlzIHRoZSBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIHdlIGhhdmUsIGkuZS4gdGhlIG51bWJlciBvZiBhY3R1YWwgdmFsdWVzICR5X3QkLgogICogX19SX18gd2lsbCBjYWxjdWxhdGUgdGhpcyBmb3IgdXMgYXV0b21hdGljYWxseSBhcyBmb2xsb3dzOgpgYGB7cn0KTUFEMTwtbWVhbihhYnMoTVMtRm9yZWNhc3QxKFRpbWUpKSkKTUFEMQpgYGAKKiBUaGUgY29kZSBhbmQgdGhlIGZvcm11bGEgY29ycmVzcG9uZCBhcyBmb2xsb3dzCgogICAgMS4gX19NU19fICRcbGVmdHJpZ2h0YXJyb3cgeV90JCwgCiAgICAKICAgIDIuIF9fRm9yZWNhc3QoVGltZSlfXyAkXGxlZnRyaWdodGFycm93IFxoYXR7eX1fdCQKICAgIAogICAgMy4gX19hYnMoTVMtRm9yZWNhc3QxKFRpbWUpKV9fICRcbGVmdHJpZ2h0YXJyb3cgXHZlcnQgeV90LVxoYXR7eX1fdFx2ZXJ0JAogICAgCiAgICA0LiBfX21lYW4oYWJzKE1TLUZvcmVjYXN0MShUaW1lKSkpX18gJFxsZWZ0cmlnaHRhcnJvdyBcZnJhY3sxfXtufVxzdW1fe3Q9MX1ee259XHZlcnQgeV90LVxoYXR7eX1fdFx2ZXJ0JAoKKiBSZWNhbGwgYWxzbyB0aGF0IHRoZSBfX01lYW4gU3F1YXJlIEVycm9yX18gIChfX01TRV9fKSBvZiBhIG1vZGVsIGlzIGdpdmVuIGJ5ClxbCk1TRT1cZnJhY3sxfXtufVxzdW1fe3Q9MX1ee259XHZlcnQgeV90LVxoYXR7eX1fdFx2ZXJ0XjIKXF0KCiMjIEV4ZXJjaXNlIDEKCk1vZGlmeSB0aGlzIGNvZGUgYmxvY2sgdG8gZmluZCB0aGUgX19NU0VfXyBvZiB0aGUgbW9kZWwuIAoKYGBge3J9Ck1TRTE8LW1lYW4oYWJzKE1TLUZvcmVjYXN0MShUaW1lKSleMikKTVNFMQpgYGAKCgojIFByZWRpY3Rpb24gSW50ZXJ2YWxzCiogV2UgY2FuIGFsc28gdXNlIHRoZSBtb2RlbCB0byBmb3JlY2FzdCBmdXR1cmUgc2FsZXMgdmFsdWVzIG9mIHBob25lIG1vZGVsIE0uCgoqIFRvIGZpbmQgdGhlIF9fOTAlIFByZWRpY3Rpb24gSW50ZXJ2YWxfXyBvZiB0aGUgbW9kZWwgYXQgbW9udGggMjcgc2F5LCB3ZSBjYW4gdXNlIHRoZWUgZm9sbG93aW5nIGZvcm11bGEgZm9yIHRoaXMgaW50ZXJ2YWwKXFsKICBcaGF0e3l9X3t4XnsqfX1ccG0gdF97XGZyYWN7XGFscGhhfXsyfSxuLTJ9XHNxcnR7TVNFXGxlZnQoMStcZnJhY3sxfXtufStcZnJhY3t4XnsqfS1cYmFye3h9fXtcc3VtX3tpPTF9XntufSh4X2ktXGJhcnt4fSleMn1ccmlnaHQpfQpcXQoqIFRoZSBzeW1ib2xzIGluIHRoZSBmb3JtdWxhIGhhdmUgdGhlIGZvbGxvd2luZyBtZWFuaW5nCiAgICAxLiAkeF57Kn09MjckLCB0aGUgbW9udGggbnVtYmVyIHdlIHdhbnQgdG8gcHJlZGljdCBzYWxlcyBmaWd1cmVzIGZvcgogICAgMi4gJFxoYXR7eX1fe3heeyp9fSA9IFxoYXR7eX1fezI3fSQsIHRoZSBwcmVkaWN0ZWQgc2FsZXMgZm9yIG1vbnRoIDI3CiAgICAzLiAkXGFscGhhID0gMS1cZnJhY3s5MH17MTAwfT0wLjEkLCB0aGUgY29uZmlkZW5jZSBwYXJhbWV0ZXIgZnJvIHRoZSA5MCUgUHJlZGljdGlvbiBJbnRlcnZhbAogICAgNC4gJG49MjQkLCB0aGUgbnVtYmVyIG9mIGFjdHVhbCBkYXRhIHZhbHVlcyB3ZSBoYXZlCiAgICA2LiAkbi0yJCB0aGUgbnVtYmVyIG9mIF9fZGVncmVlcyBvZiBmcmVlZG9tIChkZilfXyB1c2VkIAogICAgNy4gJHRfe1xmcmFje1xhbHBoYX17Mn0sbi0yfSQsIHRoZSBjcml0aWNhbCAkdCQtdmFsdWUgZ2l2ZW4gdGhlc2UgcGFyYW1ldGVycwogICAgOC4gJE1TRSQgdGhlIG1lYW4gc3F1YXJlIGVycm9yIG9mIHRoZSBtb2RlbAogICAgOS4gJFxiYXJ7eH0kIHRoZSBtZWFuIG1vbnRoIG51bWJlciwgaW4gdGhpcyBjYXNlICRcYmFye3h9PVxmcmFjezF9ezI0fVxzdW1fe2k9MX1eezI0fWkgPSBcZnJhY3sxKzIrXGxkb3RzKzI0fXsyNH0kCiogVG8gZmluZCB0aGUgY3JpdGljYWwgdmFsdWUKCiR0X3tcZnJhY3tcYWxwaGF9ezJ9LG4tMn0kIHdlIHVzIHRoZSAKYGBge3J9CnRfc3RhciA9IGFicyhxdCgwLjA1LGRmPTIyKSkgIyBkZj0gTnVtYmVyIG9mIG1vbnRocy0yCmBgYAokeF4qJApgYGB7cn0KeF9zdGFyPTI3CmBgYAoKJHleKiQKCmBgYHtyfQp5X3N0YXI9Rm9yZWNhc3QxKDI3KQp5X3N0YXIKYGBgCk1TRQpgYGB7cn0KTVNFMQpgYGAKCiRcYmFye3h9JAoKYGBge3J9CnhfYmFyPW1lYW4oVGltZSkKYGBgCgokXFNpZ21hX3tpPTF9XntufSh4X2ktXGJhcnt4fSleMiQKYGBge3J9ClN1bTE9c3VtKChUaW1lLXhfYmFyKV4yKQpgYGAKCiMjIyBVcHBlciBib3VuZGFyeSBvZiBDSQoKYGBge3J9Cnlfc3Rhcit0X3N0YXIqc3FydChNU0UxKigxKzEvMjQrKHhfc3Rhci14X2JhcikvU3VtMSkpCmBgYAojIyMgTG93ZXIgYm91bmRhcnkgb2YgQ0kKCmBgYHtyfQp5X3N0YXItdF9zdGFyKnNxcnQoTVNFMSooMSsxLzI0Kyh4X3N0YXIteF9iYXIpL1N1bTEpKQpgYGAKCiMjIFRoZSA5MCUgUHJlZGljdGlvbiBJbnRlcnZhbApXZSBhcmUgOTAlIGNvbmZpZGVudCB0aGF0IHNhbGVzIGluIHRoZSAyN3RoIG1vbnRoIHdpbGwgYmUgYmV0d2VlbiAzNjIgYW5kIDQ2OSB1bml0cy4gCgoKCiMgRXhlcmNpc2UgMgpGaW5kIHRoZSA5MCUgcHJlZGljdGlvbiBpbnRlcnZhbCBmb3Igc2FsZXMgaW4gdGhlIDI3dGggbW9udGguCgojIEV4ZXJjaXNlIDMKClRoZSBjbG9zaW5nIHZhbHVlcyBvZiBBcHBsZSBJbmMuIChBQVBMKSBTdG9jayBvbiB0aGUgTkFTREFRIFN0b2NrIEV4Y2hhbmdlIGZyb20gOCBBdWd1c3QgMjAxNyB0byA4IE5vdmVtYmVyIDIwMTcgYXJlIGdpdmVuIGluIHRoZSBkYXRhIGZpbGUgX19BcHBsZVF1b3RlcygzTSkuY3N2X18sIGF2YWlsYWJsZSBvbiBNb29kbGUuCihBdmFpbGFibGUgYXQgaHR0cDovL3d3dy5uYXNkYXEuY29tKQoKClVzaW5nIHRoaXMgZGF0YSBzZXQgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBJbXBvcnQgdGhlIGRhdGEgaW4gdGhpcyBmaWxlIHVzaW5nIHRoZSBmb2xsb3dpbmcgYW5kIGNhbGwgdGhlIGRhdGEgc3RydWN0dXJlIF9fQUFQTF9fCmBgYHtyfQpBQVBMPC1yZWFkLmNzdignQXBwbGVRdW90ZXMoM00pLmNzdicpCmBgYAoyLiBDcmVhdGUgX190d29fXyBkYXRhIHZlY3RvcnMgZnJvbSB0aGlzIGZpbGUsIG9uZSBmb3IgdGhlIF9fY2xvc2luZyB2YWx1ZV9fIGFuZCBvbmUgZm9yIHRoZSBfX2RheV9fCgpgYGB7cn0KCmBgYAozLiBDcmVhdGUgYSB0aW1lIHNlcmllcyBwbG90IGZvciB0aGlzIGRhdGEuCgo0LiBGcm9tIHRoaXMgZGF0YSBwbG90LCBkZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSB0cmVuZCBpbiB0aGUgY2xvc2luZyB2YWx1ZSBvZiBBcHBsZSBzdG9jayBvdmVyIHRoZSBwYXN0IDMgbW9udGhzLgoKNS4gVXNlIHRoZSBmdW5jdGlvbiBfX2xtKENsb3NpbmcgVmFsdWUgfiBEYXkpX18gdG8gY3JlYXRlIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoaXMgZGF0YS4KYGBge3J9CmxtKENsb3Npbmd+RGF5KQpgYGAKNi4gQ3JlYXRlIGEgbGluZWFyIG1vZGVsIHRvIGZvcmVjYXN0IHRoaXMgZGF0YS4KCjcuIENyZWF0ZSBhbiBfX1JfXyBmdW5jdGlvbiB0byByZXByZXNlbnQgdGhpcyBtb2RlbC4KCjguIEZpbmQgdGhlIE1BRCBhbmQgTVNFIG9mIHRoaXMgbW9kZWwKCjkuIEZpbmQgdGhlIDk1JSBwcmVkaWN0aW9uIGludGVydmFsIGZvciB0aGUgY2xvc2luZyBwcmljZSBvZiBBcHBsZSBTdG9jayBpbiAxMCBkYXlzIGZyb20gbm93LgoKCiMgRXhlcmNpc2UgNAoKVGhlIGNsb3NpbmcgdmFsdWVzIG9mIEdvb2dsZSBJbmMuIChHT09HTCkgU3RvY2sgb24gdGhlIE5BU0RBUSBTdG9jayBFeGNoYW5nZSBmcm9tIDggTm92ZW1iZXIgMjAxNiB0byA4IE5vdmVtYmVyIDIwMTcgYXJlIGdpdmVuIGluIHRoZSBkYXRhIGZpbGUgX19Hb29nbGVRdW90ZXMoM00pLmNzdl9fLCBhdmFpbGFibGUgb24gTW9vZGxlIC4KKEF2YWlsYWJsZSBhdCBodHRwOi8vd3d3Lm5hc2RhcS5jb20pLgoKClVzaW5nIHRoaXMgZGF0YSBzZXQgYW5zd2VyIHRoZSBmb2xsb3dpbmc6CgoxLiBJbXBvcnQgdGhlIGRhdGEgaW4gdGhpcyBmaWxlIHVzaW5nIHRoZSBmb2xsb3dpbmcgYW5kIGNhbGwgdGhlIGRhdGEgc3RydWN0dXJlIF9fR09PR0xfXwpgYGB7cn0KR09PR0w8LXJlYWQuY3N2KCdHb29nbGVRdW90ZXMoMVkpLmNzdicpCmBgYAoyLiBDcmVhdGUgX190d29fXyBkYXRhIHZlY3RvcnMgZnJvbSB0aGlzIGZpbGUsIG9uZSBmb3IgdGhlIF9fdHJhZGluZyB2YWx1ZV9fIGFuZCBvbmUgZm9yIHRoZSBfX2RheV9fCgozLiBDcmVhdGUgYSB0aW1lIHNlcmllcyBwbG90IGZvciB0aGlzIGRhdGEuCgo0LiBGcm9tIHRoaXMgZGF0YSBwbG90LCBkZXRlcm1pbmUgaWYgdGhlcmUgaXMgYSB0cmVuZCBpbiB0aGUgY2xvc2luZyB2YWx1ZSBvZiBHb29nbGUgc3RvY2sgb3ZlciB0aGUgcGFzdCB5ZWFyLgoKNS4gVXNlIHRoZSBmdW5jdGlvbiBfX2xtKFRyYWRpbmcgVmFsdWUgfiBEYXkpX18gdG8gY3JlYXRlIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgZm9yIHRoaXMgZGF0YS4KYGBge3J9CgpgYGAKNi4gQ3JlYXRlIGEgbGluZWFyIG1vZGVsIHRvIGZvcmVjYXN0IHRoaXMgZGF0YS4KCjcuIENyZWF0ZSBhbiBfX1JfXyBmdW5jdGlvbiB0byByZXByZXNlbnQgdGhpcyBtb2RlbC4KCjguIEZpbmQgdGhlIF9fTUFEX18gYW5kIF9fTVNFX18gb2YgdGhpcyBtb2RlbAoKOS4gRmluZCB0aGUgOTAlIGFuZCA5OSUgcHJlZGljdGlvbiBpbnRlcnZhbHMgZm9yIHRoZSAgdHJhZGluZyB2b2x1bWUgb2YgR29vZ2xlIFN0b2NrIGluIDEwIGRheXMgZnJvbSBub3cuCgojIEV4ZXJjaXNlIDUKClRoZSAlIEdyb3d0aCBpbiBHRFAgb2YgQ2hpbiwgdGhlIFVLLCB0aGUgVVMsIElyZWxhbmQsIHRoZSBFVSwgdGhlIE9FQ0QgYW5kIHRoZSBXb3JsZCwgZm9yIHRoZSB5ZWFycyAxOTYxLTIwMTYgYXJlIGdpdmVuIGluIHRoZSBkYXRhIGZpbGUgX19SZWdpb25hbEdEUEdyb3d0aCgxOTYxLTIwMTYpLmNzdl9fLiBJbXBvcnQgdGhpcyBkYXRhIGZpbGUgaW50byBfX1JfXyBhbmQgYW5zd2VyIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zLiAKKEF2YWlsYWJsZSBhdCBodHRwOi8vd3d3LndvcmxkYmFuay5vcmcpCgoKMS4gQ3JlYXRlIGEgZGF0YSB2ZWN0b3IgZm9yIHRoZSBfX1llYXJfXyAgYSBzZXBhcmF0ZSB2ZWN0b3IgZm9yIHRoZSBHRFAgZ3Jvd3RoIG9mIGVhY2ggY291bnRyeSBpbiB0aGUgZGF0YSBmaWxlLgoKMi4gVXNlIHRoZSBmdW5jdGlvbiBfX3BhcihtZnJvdz1jKEEsQikpX18gdG8gY3JlYXRlIGEgY29sbGVjdGlvbiBvZiB0aW1lLXNlcmllcyBwbG90cyBpbiBfX0E9MV9fIHJvdyBhbmQgX19CPTJfXyBjb2x1bW5zIGZvciB0aGUgR0RQIGdyb3d0aCBvZiBDaGluYSBhbmQgdGhlIFVTCiBUbyBpbGx1c3RyYXRlIGhvdyB0aGlzIGZ1bmN0aW9uIHdvcmtzLCB0aGUgdGltZS1zZXJpZXMgcGxvdCBmcm9tIF9fRXhhbXBsZSAxX18gaXMgcGxvdHRlZCBpbiBfXzFfXyByb3cgYW5kIF9fMl9fIGNvbHVtbnMgIApgYGB7cn0KcGFyKG1mcm93PWMoMSwyKSkKcGxvdChUaW1lLE1TLHBjaD0xNSxjb2w9InJlZCIseWxhYj0iTW9udGhseSBTYWxlcyBGaWd1cmVzIiwgeGxhYj0iTW9udGgiLG1haW49Ik1vbnRobHkgU2FsZXMgRmlndXJlcyBvZiBQaG9uZSBNb2RlbCBNIikKbGluZXMoVGltZSxNUykKcGxvdChUaW1lLE1TLHBjaD0xNSxjb2w9InJlZCIseWxhYj0iTW9udGhseSBTYWxlcyBGaWd1cmVzIiwgeGxhYj0iTW9udGgiLG1haW49Ik1vbnRobHkgU2FsZXMgRmlndXJlcyBvZiBQaG9uZSBNb2RlbCBNIikKbGluZXMoVGltZSxNUykKYGBgCjMuIFVzZSB0aGUgZnVuY3Rpb24gX19wYXIobWZyb3c9YyhBLEIpKV9fIHRvIGNyZWF0ZSBhIGNvbGxlY3Rpb24gb2YgdGltZS1zZXJpZXMgcGxvdHMgaW4gX19BPTNfXyByb3cgYW5kIF9fQj0xX18gY29sdW1ucyBmb3IgdGhlIEdEUCBncm93dGggb2YgQ2hpbmEgYW5kIHRoZSBVUywgdGhlIFVLCgogCjQuIFVzZSB0aGUgZnVuY3Rpb24gX19wYXIobWZyb3c9YyhBLEIpKV9fIHRvIGNyZWF0ZSBhIGNvbGxlY3Rpb24gb2YgdGltZS1zZXJpZXMgcGxvdHMgaW4gX19BPTJfXyByb3cgYW5kIF9fQj0yX18gY29sdW1ucyBmb3IgdGhlIEdEUCBncm93dGggb2YgdGhlIEVVLCB0aGUgVVMsIHRoZSBPRUNEIGFuZCB0aGUgV29ybGQuCgo1LiBJcyB0aGVyZSBhbnkgYXBwYXJlbnQgdHJlbmQgaW4gZWNvbm9taWMgZ3Jvd3RoIG9ic2VydmFibGUgZnJvbSB0aGVzZSB0aW1lLXNlcmllcy4KCjYuIEZyb20gdGhlIHRpbWUtc2VyaWVzIHBsb3RzLCB3aGljaCByZWdpb24gaGFzIHNob3duIHRoZSBtb3N0IGNvbnNpc3RlbnQgZWNvbm9taWMgZ3Jvd3RoIGJldHdlZW4gMTk2MSBhbmQgMjAxNi4K