Downloading R and RStudio (for homework)
In this course we will use the statistical package R to compliment the material we cover in lectures.
All of these practicals will be done using RStudio which is an add-on environment for using the R statistical package.
The R package can be downloaded from R Download. This must be installed before you can use RStudio
The RStudio interface can be downloaded from RStudio Dowlonad. Choose the free option when you download, as this has all the features we will require in this module.
The R Notebook Environment
Viewing the notebook
This is an R Markdown Notebook. This means everything we write in this white space is written in the Markdown language.
To see how this notebook appears when we post it to a web browser, you can click the Preview tab above, and this will render the contents of this notebook in html.
This workbook can also be viewed in a web browser by clicking the Open in Browser tab which appear in the pop-up window.
Creating and running R code
To input R code into a workbook we need to create a code-chunk as shown below.
rr # Code chunk (# creates a comment in the code chunk)
You can type the characters at start and end of the code-chunk shown above to create one directly.
Alternatively, you can use the shortcut Ctrl+Alt+I to insert a code-chunk.
Otherwise, you can insert a code-chunk from the menu by clicking the Code tab above and selecting the option Insert Chunk option from that menu.
To execute a code-chunk, click the Run button (green triangle) within the chunk.
- Alternatively, placing your cursor inside the chunk and pressing Ctrl+Shift+Enter will also execute the code.
Example:
- Run the code chunk below. The file cars is a data-file prepackaged with R and plot is a command to plot the data in the data set.
rr plot(cars)
Creating and Importing Data Files
In many of the practicals we will obtain data files from various sources and use R to perform various tasks with this data.
We will also create our own data sets and import them into R
In most cases, the data files we create will be of .csv type (csv= comma separated values).
These files are easily created in spread-sheet packages like Excel, LibreOffice etc.
To import these files we use the embedded commands read.csv(file.choose())
Example:
The cars in a car-park were counted by make, with the following data collected
| Audi |
3 |
| BMW |
2 |
| Citroen |
5 |
| Ford |
8 |
| Hyundai |
9 |
| Opel |
6 |
| Toyota |
8 |
| VW |
6 |
Create a file to represent this data in Excel and save this file with the extension .csv
Import this data file as Data1 into R using the embedded commands read.csv(file.choose())
rr Data1 <-read.csv(file.choose())
In the code chunk above I have imported a data file I created myself, and saved the contents of this file as a data structure I call Data1.
To display this data structure simply run Data1 inside a code chunk as follows
rr Data1
The column titles Make and Number are named by myself in the data file I created.
To select the data from one of these columns we simply call Data1$ColumnName. For example to display all the car makes in the data file we run
rr Data1$Make
- Display the number of cars of each type, using the data structure you created.
Exercise 1
The closing price of shares in Glanbia PLC on the Irish Stock Exchange, from 28th August – 5th September, 2018 are shown in the table below.
| 5/9/2018 |
14.80 |
| 4/9/2018 |
14.83 |
| 3/9/2018 |
14.71 |
| 31/8/2018 |
14.53 |
| 30/8/2018 |
14.53 |
| 29/8/2018 |
14.50 |
| 28/8/2018 |
14.53 |
Create a .csv file for this data.
Import the data from this file into R.
Display the data from the individual columns of this data structure.
R Functions on Data Sets
The main aim of this course is to find the best way to represent the information in a data set. For that reason, there will be a certain amount of mathematical work involved in this course, which we will cover using simple examples and simple data sets during lectures.
While the mathematics involved is not particularly difficult, when we use real-world data sets (which tend become large data sets), then mathematics can become cumbersome and tedious, and practically impossible to complete by hand.
The R statistical package can do a huge amount of this work for us for these larger data sets, and during the practicals we will try to implement some of the material we learnt during lectures.
Some of the matematical functions we will be applying to data sets will be
- Mean (i.e. Average)
- Median
- Standard Deviation among others.
Example:
Create a data structure to represent the data set \[S=\{1,5,-32,1,1,4,33,6,-6,10,12,-15,22,3,3,-4,18,-19,2,-2,2,1\}\]
Using this data structure answer the following:
Find the mean of \(S\)
Find the median of \(S\)
Find the standard deviation of \(S^2\), where \(S^2\) means each element of \(S\) should be squared individually.
Find the mean of \(S^2+3S\)
Find the median of \(4S^2+S+4\)
To begin we create a data structre which we will name S as follows:
rr S<-c(1,5,-32,1,1,4,33,6,-6,10,12,-15,22,3,3,-4,18,-19,2,-2,2,1) S
- Typing S a second time forces R to display the data in S.
Note: It is crucial that a c is put before the parentheses of the data set, without it R will not interpret this as a data set.
- The mean is found using the function mean()
rr mean(S)
- So the average value of all the numbers in \(S\) is 2.090909.
- The meadian is found with median()
rr median(S)
- So the median value of all the numbers in \(S\) is 2. This means half the data in \(S\) is less than 2 and half is greater than 2.
- To find \(S^2\) we simply write
rr S^2
- We see that each individual value in \(S\) has been squared.
Exercise 2
The closing price of shares in
- The standard deviation is found using the function sd()
rr sd(S^2)
- The values of \(S^2+3S\) are given by
rr S^2+3*S
Note: Do not forget to use * when you want to apply multiplication. For example R does not know how to interpret 3S e.g.
rr # 3S
- The mean of \(S^2+3S\) is
rr mean(S^2+3*S)
- The median of \(4S^2+S+4\) is
rr median(4*S^2+S+4)
Exercise 3
The historical data of shares in Amazon.com, Inc. on the NASDAQ Stock Exchange, from 6th May 2018 - 6th September 2018, is shown in the table below. The data for this table is available at Amazon.com NASDAQ Price, and can be down loaded as a .csv file from Moodle->Data Visualisation->Data Files->Quotes(AMZN).csv.
rr AMZN<-read.csv(file.choose()) AMZN
- Extract the close, open, high and low data columns from this data structure (see Exercise 1) and answer the following:
Find the mean closing price of the shares over the three months, i.e. find the mean of close
Find the median difference between the opening and closing values, i.e. the mean of ( close - open )
Find the standard deviation of high
Find the mean, median and standard deviation of ( high - low )
Exercise 4
The historical data of shares in Red Hat, Inc. on the NASDAQ Stock Exchange is available at Red Hat NASDAQ Price. Downlowad the historical data for the past 18 months as a .csv file, from this website. Import this data into R as RHT and repeat the steps of Exercise 3 for this data structure.
LS0tDQp0aXRsZTogIkRhdGEgVmlzdWFsaXNhdGlvbiAyMDE4IC0tIEludHJvZHVjdGlvbiB0byBSIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOiBkZWZhdWx0DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQojIyBEb3dubG9hZGluZyBSIGFuZCBSU3R1ZGlvIChmb3IgaG9tZXdvcmspDQoNCiogSW4gdGhpcyBjb3Vyc2Ugd2Ugd2lsbCB1c2UgdGhlIHN0YXRpc3RpY2FsIHBhY2thZ2UgX19SX18gdG8gY29tcGxpbWVudCB0aGUgbWF0ZXJpYWwgd2UgY292ZXIgaW4gbGVjdHVyZXMuDQoNCiogQWxsIG9mIHRoZXNlIHByYWN0aWNhbHMgd2lsbCBiZSBkb25lIHVzaW5nIF9fUlN0dWRpb19fIHdoaWNoIGlzIGFuIGFkZC1vbiBlbnZpcm9ubWVudCBmb3IgdXNpbmcgdGhlIF9fUl9fIHN0YXRpc3RpY2FsIHBhY2thZ2UuDQoNCiogVGhlIF9fUl9fIHBhY2thZ2UgY2FuIGJlIGRvd25sb2FkZWQgZnJvbSANCltSIERvd25sb2FkXShodHRwOi8vZnRwLmhlYW5ldC5pZS9taXJyb3JzL2NyYW4uci1wcm9qZWN0Lm9yZy8pLg0KVGhpcyBtdXN0IGJlIGluc3RhbGxlZCBiZWZvcmUgeW91IGNhbiB1c2UgX19SU3R1ZGlvX18NCg0KKiBUaGUgX19SU3R1ZGlvX18gaW50ZXJmYWNlIGNhbiBiZSBkb3dubG9hZGVkIGZyb20NCltSU3R1ZGlvIERvd2xvbmFkXShodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9wcm9kdWN0cy9yc3R1ZGlvL2Rvd25sb2FkLykuDQpDaG9vc2UgdGhlIGZyZWUgb3B0aW9uIHdoZW4geW91IGRvd25sb2FkLCBhcyB0aGlzIGhhcyBhbGwgdGhlIGZlYXR1cmVzIHdlIHdpbGwgcmVxdWlyZSBpbiB0aGlzIG1vZHVsZS4NCg0KDQojIFRoZSBSIE5vdGVib29rIEVudmlyb25tZW50DQoNCiMjIFZpZXdpbmcgdGhlIG5vdGVib29rDQoNCiogVGhpcyBpcyBhbiBSIE1hcmtkb3duIE5vdGVib29rLiBUaGlzIG1lYW5zIGV2ZXJ5dGhpbmcgd2Ugd3JpdGUgaW4gdGhpcyB3aGl0ZSBzcGFjZSBpcyB3cml0dGVuIGluIHRoZSBfX01hcmtkb3duIGxhbmd1YWdlX18uDQoNCiogVG8gc2VlIGhvdyB0aGlzIG5vdGVib29rIGFwcGVhcnMgd2hlbiB3ZSBwb3N0IGl0IHRvIGEgd2ViIGJyb3dzZXIsIHlvdSBjYW4gY2xpY2sgdGhlIF9fUHJldmlld19fIHRhYiBhYm92ZSwgYW5kIHRoaXMgd2lsbCByZW5kZXIgdGhlIGNvbnRlbnRzIG9mIHRoaXMgbm90ZWJvb2sgaW4gaHRtbC4NCg0KKiBUaGlzIHdvcmtib29rIGNhbiBhbHNvIGJlIHZpZXdlZCBpbiBhIHdlYiBicm93c2VyIGJ5IGNsaWNraW5nIHRoZSBfX09wZW4gaW4gQnJvd3Nlcl9fIHRhYiB3aGljaCBhcHBlYXIgaW4gdGhlIHBvcC11cCB3aW5kb3cuDQoNCg0KDQojIyBDcmVhdGluZyBhbmQgcnVubmluZyBfX1JfXyBjb2RlDQoNClRvIGlucHV0IF9fUl9fIGNvZGUgaW50byBhIHdvcmtib29rIHdlIG5lZWQgdG8gY3JlYXRlIGEgY29kZS1jaHVuayBhcyBzaG93biBiZWxvdy4NCg0KYGBge3J9DQojIENvZGUgY2h1bmsgKCMgY3JlYXRlcyBhIGNvbW1lbnQgaW4gdGhlIGNvZGUgY2h1bmspDQpgYGANCg0KKiBZb3UgY2FuIHR5cGUgdGhlIGNoYXJhY3RlcnMgYXQgc3RhcnQgYW5kIGVuZCBvZiB0aGUgY29kZS1jaHVuayBzaG93biBhYm92ZSB0byBjcmVhdGUgb25lIGRpcmVjdGx5Lg0KDQoqIEFsdGVybmF0aXZlbHksIHlvdSBjYW4gdXNlIHRoZSBzaG9ydGN1dCBfX0N0cmwrQWx0K0lfXyB0byBpbnNlcnQgYSBjb2RlLWNodW5rLg0KDQoqIE90aGVyd2lzZSwgeW91IGNhbiBpbnNlcnQgYSBjb2RlLWNodW5rIGZyb20gdGhlIG1lbnUgYnkgY2xpY2tpbmcgdGhlIF9fQ29kZV9fIHRhYiBhYm92ZSBhbmQgc2VsZWN0aW5nIHRoZSBvcHRpb24gX19JbnNlcnQgQ2h1bmtfXyBvcHRpb24gZnJvbSB0aGF0IG1lbnUuDQoNClRvIF9fZXhlY3V0ZV9fIGEgY29kZS1jaHVuaywgY2xpY2sgdGhlIF9fUnVuIGJ1dHRvbl9fIChncmVlbiB0cmlhbmdsZSkgd2l0aGluIHRoZSBjaHVuay4NCg0KKiBBbHRlcm5hdGl2ZWx5LCBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSB0aGUgY2h1bmsgYW5kIHByZXNzaW5nIF9fQ3RybCtTaGlmdCtFbnRlcl9fIHdpbGwgYWxzbyBleGVjdXRlIHRoZSBjb2RlLg0KDQojIyMgRXhhbXBsZToNCg0KKiBSdW4gdGhlIGNvZGUgY2h1bmsgYmVsb3cuIFRoZSBmaWxlIF9jYXJzXyBpcyBhIGRhdGEtZmlsZSBwcmVwYWNrYWdlZCB3aXRoIF9fUl9fIGFuZCBfX3Bsb3RfXyBpcyBhIGNvbW1hbmQgdG8gcGxvdCB0aGUgZGF0YSBpbiB0aGUgZGF0YSBzZXQuDQoNCmBgYHtyfQ0KcGxvdChjYXJzKQ0KYGBgDQoNCg0KDQojIENyZWF0aW5nIGFuZCBJbXBvcnRpbmcgRGF0YSBGaWxlcw0KDQoqIEluIG1hbnkgb2YgdGhlIHByYWN0aWNhbHMgd2Ugd2lsbCBvYnRhaW4gZGF0YSBmaWxlcyBmcm9tIHZhcmlvdXMgc291cmNlcyBhbmQgdXNlIF9fUl9fIHRvIHBlcmZvcm0gdmFyaW91cyB0YXNrcyB3aXRoIHRoaXMgZGF0YS4NCg0KKiBXZSB3aWxsIGFsc28gY3JlYXRlIG91ciBvd24gZGF0YSBzZXRzIGFuZCBpbXBvcnQgdGhlbSBpbnRvIF9fUl9fDQoNCiogSW4gbW9zdCBjYXNlcywgdGhlIGRhdGEgZmlsZXMgd2UgY3JlYXRlIHdpbGwgYmUgb2YgX18uY3N2X18gdHlwZSAoX19jc3ZfXz0gX19jb21tYSBzZXBhcmF0ZWQgdmFsdWVzX18pLg0KDQoqIFRoZXNlIGZpbGVzIGFyZSBlYXNpbHkgY3JlYXRlZCBpbiBzcHJlYWQtc2hlZXQgcGFja2FnZXMgbGlrZSBfX0V4Y2VsX18sIF9fTGlicmVPZmZpY2VfXyBldGMuDQoNCiogVG8gX19pbXBvcnRfXyB0aGVzZSBmaWxlcyB3ZSB1c2UgdGhlIGVtYmVkZGVkIGNvbW1hbmRzIF9fcmVhZC5jc3YoZmlsZS5jaG9vc2UoKSlfXw0KDQojIyMgRXhhbXBsZToNCg0KVGhlIGNhcnMgaW4gYSBjYXItcGFyayB3ZXJlIGNvdW50ZWQgYnkgbWFrZSwgd2l0aCB0aGUgZm9sbG93aW5nIGRhdGEgY29sbGVjdGVkDQoNCnwgIE1ha2UgIHwgIE51bWJlciB8DQp8LS0tLS0tLS18LS0tLS0tLS0tfA0KfCBBdWRpICAgfCAgICAzICAgIHwNCnwgQk1XICAgIHwgICAgMiAgICB8DQp8IENpdHJvZW58ICAgIDUgICAgfA0KfCBGb3JkICAgfCAgICA4ICAgIHwNCnwgSHl1bmRhaXwgICAgOSAgICB8DQp8IE9wZWwgICB8ICAgIDYgICAgfA0KfCBUb3lvdGEgfCAgICA4ICAgIHwNCnwgVlcgICAgIHwgICAgNiAgICB8DQoNCjEuIENyZWF0ZSBhIGZpbGUgdG8gcmVwcmVzZW50IHRoaXMgZGF0YSBpbiBfX0V4Y2VsX18gYW5kIHNhdmUgdGhpcyBmaWxlIHdpdGggdGhlIGV4dGVuc2lvbiBfXy5jc3ZfXyANCg0KMi4gSW1wb3J0IHRoaXMgZGF0YSBmaWxlICBhcyBfX0RhdGExX18gaW50byBfX1JfXyB1c2luZyB0aGUgZW1iZWRkZWQgY29tbWFuZHMgX19yZWFkLmNzdihmaWxlLmNob29zZSgpKV9fDQoNCg0KYGBge3J9DQpEYXRhMSA8LXJlYWQuY3N2KGZpbGUuY2hvb3NlKCkpDQpgYGANCg0KDQoqIEluIHRoZSBjb2RlIGNodW5rIGFib3ZlIEkgaGF2ZSBpbXBvcnRlZCBhIGRhdGEgZmlsZSAgSSBjcmVhdGVkIG15c2VsZiwgYW5kIHNhdmVkIHRoZSBjb250ZW50cyBvZiB0aGlzIGZpbGUgYXMgYSBkYXRhIHN0cnVjdHVyZSBJIGNhbGwgX19EYXRhMV9fLg0KDQoNCiogVG8gZGlzcGxheSB0aGlzIGRhdGEgc3RydWN0dXJlIHNpbXBseSBydW4gX19EYXRhMV9fIGluc2lkZSBhIGNvZGUgY2h1bmsgYXMgZm9sbG93cw0KYGBge3J9DQpEYXRhMQ0KYGBgDQoNCiogVGhlIGNvbHVtbiB0aXRsZXMgX19NYWtlX18gYW5kIF9fTnVtYmVyX18gYXJlIG5hbWVkIGJ5IG15c2VsZiBpbiB0aGUgZGF0YSBmaWxlIEkgY3JlYXRlZC4NCg0KKiBUbyBzZWxlY3QgdGhlIGRhdGEgZnJvbSBvbmUgb2YgdGhlc2UgY29sdW1ucyB3ZSBzaW1wbHkgY2FsbCBfX0RhdGExJENvbHVtbk5hbWVfXy4gRm9yIGV4YW1wbGUgdG8gZGlzcGxheSBhbGwgdGhlIGNhciBtYWtlcyBpbiB0aGUgZGF0YSBmaWxlIHdlIHJ1bg0KYGBge3J9DQpEYXRhMSRNYWtlDQpgYGANCg0KMy4gRGlzcGxheSB0aGUgbnVtYmVyIG9mIGNhcnMgb2YgZWFjaCB0eXBlLCB1c2luZyB0aGUgZGF0YSBzdHJ1Y3R1cmUgeW91IGNyZWF0ZWQuDQoNCg0KIyMjIEV4ZXJjaXNlIDENCg0KVGhlIGNsb3NpbmcgcHJpY2Ugb2Ygc2hhcmVzIGluIF9fR2xhbmJpYSBQTENfXyBvbiB0aGUgSXJpc2ggU3RvY2sgRXhjaGFuZ2UsIGZyb20gMjh0aCBBdWd1c3QgLS0gNXRoIFNlcHRlbWJlciwgMjAxOCBhcmUgc2hvd24gaW4gdGhlIHRhYmxlIGJlbG93Lg0KDQoNCnwgICBEYXRlICAgfCBQcmljZSB8DQp8LS0tLS0tLS0tLXwtLS0tLS0tfA0KfCA1LzkvMjAxOCB8IDE0LjgwIHwNCnwgNC85LzIwMTggfCAxNC44MyB8DQp8IDMvOS8yMDE4IHwgMTQuNzEgfA0KfCAzMS84LzIwMTh8IDE0LjUzIHwNCnwgMzAvOC8yMDE4fCAxNC41MyB8DQp8IDI5LzgvMjAxOHwgMTQuNTAgfA0KfCAyOC84LzIwMTh8IDE0LjUzIHwNCg0KMS4gQ3JlYXRlIGEgX18uY3N2X18gZmlsZSBmb3IgdGhpcyBkYXRhLg0KDQoyLiBJbXBvcnQgdGhlIGRhdGEgZnJvbSB0aGlzIGZpbGUgaW50byBfX1JfXy4NCg0KMy4gRGlzcGxheSB0aGUgZGF0YSBmcm9tIHRoZSBpbmRpdmlkdWFsIGNvbHVtbnMgb2YgdGhpcyBkYXRhIHN0cnVjdHVyZS4NCg0KDQojIFIgRnVuY3Rpb25zIG9uIERhdGEgU2V0cw0KDQoqIFRoZSBtYWluIGFpbSBvZiB0aGlzIGNvdXJzZSBpcyB0byBmaW5kIHRoZSBiZXN0IHdheSB0byByZXByZXNlbnQgdGhlIGluZm9ybWF0aW9uIGluIGEgZGF0YSBzZXQuIEZvciB0aGF0IHJlYXNvbiwgdGhlcmUgd2lsbCBiZSBhIGNlcnRhaW4gYW1vdW50IG9mIG1hdGhlbWF0aWNhbCB3b3JrIGludm9sdmVkIGluIHRoaXMgY291cnNlLCB3aGljaCB3ZSB3aWxsIGNvdmVyIHVzaW5nIHNpbXBsZSBleGFtcGxlcyBhbmQgc2ltcGxlIGRhdGEgc2V0cyBkdXJpbmcgbGVjdHVyZXMuDQoNCiogV2hpbGUgdGhlIG1hdGhlbWF0aWNzIGludm9sdmVkIGlzIG5vdCBwYXJ0aWN1bGFybHkgZGlmZmljdWx0LCB3aGVuIHdlIHVzZSByZWFsLXdvcmxkIGRhdGEgc2V0cyAod2hpY2ggdGVuZCBiZWNvbWUgbGFyZ2UgZGF0YSBzZXRzKSwgdGhlbiBtYXRoZW1hdGljcyBjYW4gYmVjb21lIGN1bWJlcnNvbWUgYW5kIHRlZGlvdXMsIGFuZCBwcmFjdGljYWxseSBpbXBvc3NpYmxlIHRvIGNvbXBsZXRlIGJ5IGhhbmQuDQoNCiogVGhlIF9fUl9fIHN0YXRpc3RpY2FsIHBhY2thZ2UgY2FuIGRvIGEgaHVnZSBhbW91bnQgb2YgdGhpcyB3b3JrIGZvciB1cyBmb3IgdGhlc2UgbGFyZ2VyIGRhdGEgc2V0cywgYW5kIGR1cmluZyB0aGUgcHJhY3RpY2FscyB3ZSB3aWxsIHRyeSB0byBpbXBsZW1lbnQgc29tZSBvZiB0aGUgbWF0ZXJpYWwgd2UgbGVhcm50IGR1cmluZyBsZWN0dXJlcy4NCg0KDQoqIFNvbWUgb2YgdGhlIG1hdGVtYXRpY2FsIGZ1bmN0aW9ucyB3ZSB3aWxsIGJlIGFwcGx5aW5nIHRvIGRhdGEgc2V0cyB3aWxsIGJlDQogIA0KICAgICogX19NZWFuX18gKGkuZS4gIF9fQXZlcmFnZV9fKQ0KICAgICogX19NZWRpYW5fXw0KICAgICogX19TdGFuZGFyZCBEZXZpYXRpb25fXyANCmFtb25nIG90aGVycy4gDQoNCiMjIyBFeGFtcGxlOg0KDQoqIENyZWF0ZSBhIGRhdGEgc3RydWN0dXJlIHRvIHJlcHJlc2VudCB0aGUgZGF0YSBzZXQNClxbUz1cezEsNSwtMzIsMSwxLDQsMzMsNiwtNiwxMCwxMiwtMTUsMjIsMywzLC00LDE4LC0xOSwyLC0yLDIsMVx9XF0NCg0KKiBVc2luZyB0aGlzIGRhdGEgc3RydWN0dXJlIGFuc3dlciB0aGUgZm9sbG93aW5nOg0KDQogIDEuIEZpbmQgdGhlIF9fbWVhbl9fIG9mICRTJA0KICANCiAgMi4gRmluZCB0aGUgX19tZWRpYW5fXyBvZiAkUyQNCiAgDQogIDMuIEZpbmQgdGhlIF9fc3RhbmRhcmQgZGV2aWF0aW9uX18gb2YgJFNeMiQsIHdoZXJlICRTXjIkIG1lYW5zIGVhY2ggZWxlbWVudCBvZiAkUyQgc2hvdWxkIGJlIHNxdWFyZWQgaW5kaXZpZHVhbGx5Lg0KICANCiAgNC4gRmluZCB0aGUgX19tZWFuX18gb2YgJFNeMiszUyQNCiAgDQogIDUuIEZpbmQgdGhlIF9fbWVkaWFuX18gb2YgJDRTXjIrUys0JA0KDQpUbyBiZWdpbiB3ZSBjcmVhdGUgYSBkYXRhIHN0cnVjdHJlIHdoaWNoIHdlIHdpbGwgbmFtZSBfX1NfXyBhcyBmb2xsb3dzOg0KYGBge3J9DQpTPC1jKDEsNSwtMzIsMSwxLDQsMzMsNiwtNiwxMCwxMiwtMTUsMjIsMywzLC00LDE4LC0xOSwyLC0yLDIsMSkNClMNCmBgYA0KKiBUeXBpbmcgX19TX18gYSBzZWNvbmQgdGltZSBmb3JjZXMgX19SX18gdG8gZGlzcGxheSB0aGUgZGF0YSBpbiBfX1NfXy4NCg0KX19Ob3RlOl9fIEl0IGlzIGNydWNpYWwgdGhhdCBhIF9fY19fIGlzIHB1dCBiZWZvcmUgdGhlIHBhcmVudGhlc2VzIG9mIHRoZSBkYXRhIHNldCwgd2l0aG91dCBpdCBfX1JfXyB3aWxsIG5vdCBpbnRlcnByZXQgdGhpcyBhcyBhIGRhdGEgc2V0LiANCg0KMS4gVGhlIG1lYW4gaXMgZm91bmQgdXNpbmcgdGhlIGZ1bmN0aW9uIF9fbWVhbigpX18NCg0KYGBge3J9DQptZWFuKFMpDQpgYGANCiAgKiBTbyB0aGUgYXZlcmFnZSB2YWx1ZSBvZiBhbGwgdGhlIG51bWJlcnMgaW4gJFMkIGlzIDIuMDkwOTA5Lg0KICANCjIuIFRoZSBtZWFkaWFuIGlzIGZvdW5kIHdpdGggX19tZWRpYW4oKV9fDQoNCmBgYHtyfQ0KbWVkaWFuKFMpDQpgYGANCiogU28gdGhlIG1lZGlhbiB2YWx1ZSBvZiBhbGwgdGhlIG51bWJlcnMgaW4gJFMkIGlzIDIuIFRoaXMgbWVhbnMgX19oYWxmIHRoZSBkYXRhX18gaW4gJFMkIGlzIGxlc3MgdGhhbiAyIGFuZCBoYWxmIGlzIGdyZWF0ZXIgdGhhbiAyLg0KDQozLiBUbyBmaW5kICRTXjIkIHdlIHNpbXBseSB3cml0ZQ0KYGBge3J9DQpTXjINCmBgYA0KKiBXZSBzZWUgdGhhdCBlYWNoIGluZGl2aWR1YWwgdmFsdWUgaW4gJFMkIGhhcyBiZWVuIHNxdWFyZWQuDQoNCiMgRXhlcmNpc2UgMg0KDQpUaGUgY2xvc2luZyBwcmljZSBvZiBzaGFyZXMgaW4gDQoNCiogVGhlIHN0YW5kYXJkIGRldmlhdGlvbiBpcyBmb3VuZCB1c2luZyB0aGUgZnVuY3Rpb24gX19zZCgpX18NCmBgYHtyfQ0Kc2QoU14yKQ0KYGBgDQoNCjQuIFRoZSB2YWx1ZXMgb2YgJFNeMiszUyQgYXJlIGdpdmVuIGJ5DQpgYGB7cn0NClNeMiszKlMNCmBgYA0KX19Ob3RlOl9fIERvIG5vdCBmb3JnZXQgdG8gdXNlICogd2hlbiB5b3Ugd2FudCB0byBhcHBseSBtdWx0aXBsaWNhdGlvbi4gRm9yIGV4YW1wbGUgX19SX18gZG9lcyBub3Qga25vdyBob3cgdG8gaW50ZXJwcmV0IDNTIGUuZy4NCmBgYHtyfQ0KIyAzUw0KYGBgDQoqIFRoZSBtZWFuIG9mICRTXjIrM1MkIGlzIA0KYGBge3J9DQptZWFuKFNeMiszKlMpDQpgYGANCg0KDQoqIFRoZSBtZWRpYW4gb2YgJDRTXjIrUys0JCBpcw0KYGBge3J9DQptZWRpYW4oNCpTXjIrUys0KQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSAzDQoNClRoZSBoaXN0b3JpY2FsIGRhdGEgb2Ygc2hhcmVzIGluIF9fQW1hem9uLmNvbSwgSW5jLl9fIG9uIHRoZSBOQVNEQVEgU3RvY2sgRXhjaGFuZ2UsIGZyb20gNnRoIE1heSAyMDE4IC0gNnRoIFNlcHRlbWJlciAyMDE4LCBpcyBzaG93biBpbiB0aGUgdGFibGUgYmVsb3cuIFRoZSBkYXRhIGZvciB0aGlzIHRhYmxlIGlzIGF2YWlsYWJsZSBhdCBbQW1hem9uLmNvbSBOQVNEQVEgUHJpY2VdKGh0dHBzOi8vd3d3Lm5hc2RhcS5jb20vc3ltYm9sL2Ftem4vaGlzdG9yaWNhbCksIGFuZCBjYW4gYmUgZG93biBsb2FkZWQgYXMgYSBfXy5jc3ZfXyBmaWxlIGZyb20gX19Nb29kbGUtPkRhdGEgVmlzdWFsaXNhdGlvbi0+RGF0YSBGaWxlcy0+UXVvdGVzKEFNWk4pLmNzdl9fLg0KDQpgYGB7cn0NCkFNWk48LXJlYWQuY3N2KGZpbGUuY2hvb3NlKCkpDQpBTVpODQpgYGANCg0KKiBFeHRyYWN0IHRoZSBfX2Nsb3NlX18sIF9fb3Blbl9fLCBfX2hpZ2hfXyBhbmQgX19sb3dfXyBkYXRhIGNvbHVtbnMgZnJvbSB0aGlzIGRhdGEgc3RydWN0dXJlIChzZWUgRXhlcmNpc2UgMSkgYW5kIGFuc3dlciB0aGUgZm9sbG93aW5nOg0KDQoxLiBGaW5kIHRoZSBtZWFuIGNsb3NpbmcgcHJpY2Ugb2YgdGhlIHNoYXJlcyBvdmVyIHRoZSB0aHJlZSBtb250aHMsIGkuZS4gZmluZCB0aGUgbWVhbiBvZiBfX2Nsb3NlX18NCg0KMi4gRmluZCB0aGUgbWVkaWFuIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgb3BlbmluZyBhbmQgY2xvc2luZyB2YWx1ZXMsIGkuZS4gdGhlIG1lYW4gb2YgKCBfX2Nsb3NlX18gLSBfX29wZW5fXyApDQoNCjMuIEZpbmQgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBfX2hpZ2hfXyANCg0KNC4gRmluZCB0aGUgbWVhbiwgbWVkaWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgKCBfX2hpZ2hfXyAtIF9fbG93X18gKQ0KDQojIyMgRXhlcmNpc2UgNA0KDQpUaGUgaGlzdG9yaWNhbCBkYXRhIG9mIHNoYXJlcyBpbiBfX1JlZCBIYXQsIEluYy5fXyBvbiB0aGUgTkFTREFRIFN0b2NrIEV4Y2hhbmdlIGlzIGF2YWlsYWJsZSBhdCBbUmVkIEhhdCBOQVNEQVEgUHJpY2VdKGh0dHBzOi8vd3d3Lm5hc2RhcS5jb20vc3ltYm9sL3JodC9oaXN0b3JpY2FsKS4gRG93bmxvd2FkIHRoZSBoaXN0b3JpY2FsIGRhdGEgZm9yIHRoZSBwYXN0IF9fMTggbW9udGhzX18gYXMgYSBfXy5jc3ZfXyBmaWxlLCBmcm9tIHRoaXMgd2Vic2l0ZS4gSW1wb3J0IHRoaXMgZGF0YSBpbnRvIF9fUl9fIGFzIF9fUkhUX18gYW5kIHJlcGVhdCB0aGUgc3RlcHMgb2YgRXhlcmNpc2UgMyBmb3IgdGhpcyBkYXRhIHN0cnVjdHVyZS4NCg==