Associated material

Module: Module 01 - Introducing R and Rstudio

Readings:

Before we start

This web site provides two kinds of materials – module notes and zoom notes. The module pages cover the content of each online session in detail. They often provide additional in-depth discussion and examples. You can use the module notes to revise and extend lesson content on your own at any time. The zoom notes contain an outline of the material covered in each module and coding exercises that you can work through after the lesson to solidify your understanding and build your skills. We can work through these exercises together in each week’s face to face practical session.

At the top right hand corner of each notes page is a “Code” button. This toggles showing/hiding the code used to create the page as an Rmarkdown file (we cover Rmarkdown more in-depth in module/zoom notes 4). When working through the zoom notes, you can use this button to hide the exercise solutions if you prefer to tackle them first on your own.


R and RStudio

R is a programming language. RStudio is an integrated development environment (IDE) which provides a graphical interface (among other things) for interacting with R.

The RStudio screen is comprised of panels.

Panels of RStudio

  • console
  • source
  • environment/history
  • file/plot/help/viewer


Scripts

Scripts are text files that contain R code. Scripts provide a persistent record of the steps we perform in our data analysis, and can be used to recreate what we have done without having to retype.

Scripts can be either:

R Script - plain text document that contains R commands

RMarkdown - a plain text document that has text areas and code areas. RMarkdown files are processed/compiled to an output format such as html or pdf which contains formatted text, code, and the results of the code embedded in the document. We’ll cover this in more depth Module/Handout 4.


R Syntax

General syntax info:

  • R is case sensitive (e.g. weight and Weight are different entities)
  • Spaces are ignored in assignments and expressions. For example 8+3 and 8 + 3 are functionally equivalent. However, generous use of white space is encouraged to improve accessibility.
  • Variable and function names in R conventionally use snake case. All letters are lower case, and words are separated by underscore (e.g. annual_mean_rainfall).


Mathematical operators

Addition: +

Subtraction: -

Multiplication: *

Division: /

Exponentiation: ^

Modulo (remainder): %%

# Addition
1 + 2
## [1] 3

# Subtraction
3 - 6
## [1] -3

# Multiplication
4 * 2
## [1] 8

# Division
12 / 3
## [1] 4

# Exponentiation
2 ** 5
## [1] 32

# Modulo
5 %% 2
## [1] 1

Data types

R has three primary types of data:

  • numeric
  • characters
  • boolean

Numeric data can be integer (whole numbers) or “double” (having a decimal part).

Character data items are comprised of one or more letters, numbers, or (permitted) symbols. In the vernacular, these are called “strings”. Strings are defined in R by enclosing them in quotation marks (e.g. "Emperor Penguin").

Booleans are logical data. They can take on only the values TRUE or FALSE, and are used for logical operations.

R functions (see discussion below) accept input data of specific type(s). Applying a function or operation to the “wrong” type of data will cause an error.


Variables

Variables are named objects in which we store data. The stored values can be referenced/used later in our code.

Variable names must:

  • Start with a letter
  • Contain no non-alphanumeric symbols except . (full stop) and _ (underscore)

Variable names should always be descriptive of their contents. This will help you remember what data they hold when they are used in the code.


Assignment operators

In R <- and = are both used for assignment. <- is used to assign a value to a variable. = is used inside a function call to assign a value to a function input.

The right-hand side of an assignment statement is evaluated first. The result is then assigned to the variable on the left-hand side. Thus the statement x <- x * 2 means “First multiply the current value of x by 2. Take the result of that operation and assign it as the new value of x.”

Note that variables only contain the last thing that was assigned to them. Assigning a value to a variable overwrites any existing value.

Functions

Functions are encapsulated, named chunks of code. We call a function by typing its name, followed by (). We provide any required data inputs (called function arguments in this context) by placing them between the round brackets. When a function is called, R executes the code which it encapsulates and returns the result.

For example, if we want to find the square root of a number, we can use the sqrt function and provide the number as input:

sqrt(64)
## [1] 8

Many functions require multiple pieces of input data. Multiple arguments are placed between the round brackets, separated by commas.

Each function argument has a name. Arguments can be identified by name, or by ordinal position within the round brackets.

# by position
round(3.142, 1)
## [1] 3.1

# by name
round(x = 3.142, digits = 1)
## [1] 3.1

To see what arguments a function requires, call the args function, passing in the function name:

args(round)
## function (x, digits = 0) 
## NULL

R contains many, many, powerful pre-defined functions. In one of our later modules, we will learn how to write our own custom functions.


Comparison Operators

Comparison operators evaluate to either TRUE or FALSE.

Comparators:

  • equality: ==
  • not equal to:!=
  • greater than: >
  • greater than or equal to: >=
  • less than: <
  • less than or equal to: <=

Logical operators

  • not: !
  • or: |
  • and: &

We’ll cover these in more depth in the Selecting and Filtering Module.


Comments

The # symbol denotes a comment. R will ignore all text following the # on the same line. Comments should explain the logic of the code. This helps other people understand your code; it also helps you remember your thinking when you revisit your own code in the future. Thorough commenting is so essential to software development that most professionals write their comments first, then fill in the code following the structure defined by the comments.


Complex Data

Vectors

A vector is a complex data structure that holds multiple data elements. Vectors are homogeneous – all their elements must be of the same data type.

To create a vector use function c(), the combine function. Items are separated by commas.

some_letters <- c("a", "b", "c")
some_letters
## [1] "a" "b" "c"

some_numbers <- c(2, 4, 6)
some_numbers
## [1] 2 4 6

We can see the data type of a vector using typeof

typeof(some_letters)
## [1] "character"

typeof(some_numbers)
## [1] "double"


Subsetting by index

To access individual items in a vector use [], the index operator, as shown below. Place the item’s ordinal position between the square brackets. Select multiple items by placing a vector of positions between the square brackets.

some_numbers
## [1] 2 4 6

# pull out the second item
some_numbers[2]
## [1] 4

some_letters
## [1] "a" "b" "c"

# pull out items 1 and 3
some_letters[c(1,3)]
## [1] "a" "c"

We will see examples of more complex data structures and their use in later modules.


Getting Help

To access the R documentation for a function, call help() passing in the function name, or type ? followed by the name of the function (no intervening space).

  • help(lm)
  • ?lm

Language documentation tends to be terse, and targeted to the advanced user. Frequently you will want more detailed explanation than is available from the built-in help. We recommend Google (my most common search is “how to … in R”) or one of the many useful text books available through the University library (see for example, https://otago.primo.exlibrisgroup.com/permalink/64OTAGO_INST/qef3lj/alma9926179377401891)


Projects

Projects within RStudio provide a mechanism to organise your work. A Project is a directory on your computer where you gather related code, documentation, data, and outputs so that everything needed to recreate an analysis is “bundled together”.

To create a new Project:

  • File -> New Project -> New Directory -> New Project
  • Choose where you want it to live and give it a name
  • Click “Create Project”

It is useful to add some subfolders to your Project folder. A common organisation is to have separate subfolders for your scripts, input files, output files, and documentation.

You can create subfolders by using the “New Folder” button in the Files panel or using the dir.create() function, as shown below.

dir.create("scripts")
dir.create("data")
dir.create("data")
dir.create("outputs")


Module 01 Exercises

  1. Create a vector of 5 numbers and assign it to a variable.

  2. Find out the length of the vector.

  3. Divide the entire vector by 2 and store the result into a variable called div_2. Explain what happens when you perform a mathematical operation on a vector.

  4. Calculate the minimum, maximum, mean, and standard deviation for the div_2 vector. Round each result to 2 decimal places.

  5. Create and assign a vector of at least 4 animal names into animals.

  6. Compute the number of characters in each item. Use only one line of code.

  7. Extract the first and fourth animal into a new variable.

  8. Remove the third animal from your original animals vector. There are multiple syntactically legal ways to achieve this in R, but some are more elegant than others. (Hint: what does using a negative index do?)

  9. Create a vector that has three copies of this updated animals vector. Use only one line of code.

  10. Combine your animal and number vectors together into a new variable called coerced. Run typeof on this vector. Explain why the types of some elements have been changed.

Example solutions

my_numbers <- c(12, 63, 3, 7, 84)

length(my_numbers)
## [1] 5

div_2 <- my_numbers / 2
div_2
## [1]  6.0 31.5  1.5  3.5 42.0

# When a mathematical operator is applied to a vector, the operation is
# performed on each individual vector element, and the whole set of new values
# is returned.

# Note the range of syntactic options. Strive for a balance between clarity and
# parsimony.

# minimum
min_number <- min(div_2)
round(min_number, digits = 2)
## [1] 1.5

# maximum
max_number <- max(div_2)
round(max_number, 2)
## [1] 42

# mean
round(mean(div_2), digits = 2)
## [1] 16.9

# standard deviation
round(sd(div_2), 2)
## [1] 18.57

animals <- c("lion", "tiger", "snake", "beetle", "turtle")
animals
## [1] "lion"   "tiger"  "snake"  "beetle" "turtle"

nchar(animals)
## [1] 4 5 5 6 6

two_animals <- animals[c(1,4)]
two_animals
## [1] "lion"   "beetle"

animals <- animals[-3]
animals
## [1] "lion"   "tiger"  "beetle" "turtle"

animals3 <- c(animals, animals, animals)
animals3
##  [1] "lion"   "tiger"  "beetle" "turtle" "lion"   "tiger"  "beetle" "turtle"
##  [9] "lion"   "tiger"  "beetle" "turtle"

my_numbers
## [1] 12 63  3  7 84
typeof(my_numbers)
## [1] "double"
animals
## [1] "lion"   "tiger"  "beetle" "turtle"
typeof(animals)
## [1] "character"

combined <- c(my_numbers, animals)
typeof(combined)
## [1] "character"
combined
## [1] "12"     "63"     "3"      "7"      "84"     "lion"   "tiger"  "beetle"
## [9] "turtle"

# The numeric elements have been coerced to type character so that
# the vector remains homogeneous.
LS0tCnRpdGxlOiAiWm9vbSBOb3RlcyAwMTogSW50cm9kdWNpbmcgUiBhbmQgUlN0dWRpbyIKZGF0ZTogIlNlbWVzdGVyIDIsIDIwMjMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiBzaG93Ci0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoa25pdHIpCgprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZmlnLnBhdGggPSAiZmlndXJlcy8wMS8iLCAjIHVzZSBvbmx5IGZvciBzaW5nbGUgUm1kIGZpbGVzCiAgY29sbGFwc2UgPSBUUlVFLAogIGVjaG8gPSBUUlVFCikKCgpgYGAKCgoKPiAjIyMjIEFzc29jaWF0ZWQgbWF0ZXJpYWwKPiBNb2R1bGU6IFtNb2R1bGUgMDEgLSBJbnRyb2R1Y2luZyBSIGFuZCBSc3R1ZGlvXSgwMS1pbnRyby5odG1sKQo+IAo+IFJlYWRpbmdzOgo+Cj4gLSBbUiBmb3IgRGF0YSBTY2llbmNlIC0gQ2hhcHRlciAxXShodHRwczovL3I0ZHMuaGFkLmNvLm56L2ludHJvZHVjdGlvbi5odG1sKQo+IC0gW1IgZm9yIERhdGEgU2NpZW5jZSAtIENoYXB0ZXIgNF0oaHR0cHM6Ly9yNGRzLmhhZC5jby5uei93b3JrZmxvdy1iYXNpY3MuaHRtKQoKCiMjIyMgQmVmb3JlIHdlIHN0YXJ0CgpUaGlzIHdlYiBzaXRlIHByb3ZpZGVzIHR3byBraW5kcyBvZiBtYXRlcmlhbHMgLS0gbW9kdWxlIG5vdGVzIGFuZCB6b29tIG5vdGVzLiBUaGUgbW9kdWxlIHBhZ2VzIGNvdmVyIHRoZSBjb250ZW50IG9mIGVhY2ggb25saW5lIHNlc3Npb24gaW4gZGV0YWlsLiBUaGV5IG9mdGVuIHByb3ZpZGUgYWRkaXRpb25hbCBpbi1kZXB0aCBkaXNjdXNzaW9uIGFuZCBleGFtcGxlcy4gWW91IGNhbiB1c2UgdGhlIG1vZHVsZSBub3RlcyB0byByZXZpc2UgYW5kIGV4dGVuZCBsZXNzb24gY29udGVudCBvbiB5b3VyIG93biBhdCBhbnkgdGltZS4gVGhlIHpvb20gbm90ZXMgY29udGFpbiBhbiBvdXRsaW5lIG9mIHRoZSBtYXRlcmlhbCBjb3ZlcmVkIGluIGVhY2ggbW9kdWxlIGFuZCBjb2RpbmcgZXhlcmNpc2VzIHRoYXQgeW91IGNhbiB3b3JrIHRocm91Z2ggYWZ0ZXIgdGhlIGxlc3NvbiB0byBzb2xpZGlmeSB5b3VyIHVuZGVyc3RhbmRpbmcgYW5kIGJ1aWxkIHlvdXIgc2tpbGxzLiBXZSBjYW4gIHdvcmsgdGhyb3VnaCB0aGVzZSBleGVyY2lzZXMgdG9nZXRoZXIgaW4gZWFjaCB3ZWVrJ3MgZmFjZSB0byBmYWNlIHByYWN0aWNhbCBzZXNzaW9uLiAKCkF0IHRoZSB0b3AgcmlnaHQgaGFuZCBjb3JuZXIgb2YgZWFjaCBub3RlcyBwYWdlIGlzIGEgIkNvZGUiIGJ1dHRvbi4gVGhpcyB0b2dnbGVzIHNob3dpbmcvaGlkaW5nIHRoZSBjb2RlIHVzZWQgdG8gY3JlYXRlIHRoZSBwYWdlIGFzIGFuIFJtYXJrZG93biBmaWxlICh3ZSBjb3ZlciBSbWFya2Rvd24gbW9yZSBpbi1kZXB0aCBpbiBbbW9kdWxlXSgwNC1jb21tdW5pY2F0ZS5odG1sKS9bem9vbSBub3Rlc10oem9vbV9ub3Rlc18wNF9jb21tdW5pY2F0ZS5odG1sKSA0KS4gV2hlbiB3b3JraW5nIHRocm91Z2ggdGhlIHpvb20gbm90ZXMsIHlvdSBjYW4gdXNlIHRoaXMgYnV0dG9uIHRvIGhpZGUgdGhlIGV4ZXJjaXNlIHNvbHV0aW9ucyBpZiB5b3UgcHJlZmVyIHRvIHRhY2tsZSB0aGVtIGZpcnN0IG9uIHlvdXIgb3duLgoKXAoKIyBSIGFuZCBSU3R1ZGlvCgpSIGlzIGEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuIFJTdHVkaW8gaXMgYW4gaW50ZWdyYXRlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCAoSURFKSB3aGljaCBwcm92aWRlcyBhIGdyYXBoaWNhbCBpbnRlcmZhY2UgKGFtb25nIG90aGVyIHRoaW5ncykgZm9yIGludGVyYWN0aW5nIHdpdGggUi4gCgpUaGUgUlN0dWRpbyBzY3JlZW4gaXMgY29tcHJpc2VkIG9mIHBhbmVscy4KClBhbmVscyBvZiBSU3R1ZGlvCgotIGNvbnNvbGUKLSBzb3VyY2UKLSBlbnZpcm9ubWVudC9oaXN0b3J5Ci0gZmlsZS9wbG90L2hlbHAvdmlld2VyCgpcCgojIFNjcmlwdHMKClNjcmlwdHMgYXJlIHRleHQgZmlsZXMgdGhhdCBjb250YWluIFIgY29kZS4gU2NyaXB0cyBwcm92aWRlIGEgcGVyc2lzdGVudCByZWNvcmQgb2YgdGhlIHN0ZXBzIHdlIHBlcmZvcm0gaW4gb3VyIGRhdGEgYW5hbHlzaXMsIGFuZCBjYW4gYmUgdXNlZCB0byByZWNyZWF0ZSB3aGF0IHdlIGhhdmUgZG9uZSB3aXRob3V0IGhhdmluZyB0byByZXR5cGUuIAoKU2NyaXB0cyBjYW4gYmUgZWl0aGVyOgoKUiBTY3JpcHQgLSBwbGFpbiB0ZXh0IGRvY3VtZW50IHRoYXQgY29udGFpbnMgUiBjb21tYW5kcwoKUk1hcmtkb3duIC0gYSBwbGFpbiB0ZXh0IGRvY3VtZW50IHRoYXQgaGFzIHRleHQgYXJlYXMgYW5kIGNvZGUgYXJlYXMuIFJNYXJrZG93biBmaWxlcyBhcmUgcHJvY2Vzc2VkL2NvbXBpbGVkIHRvIGFuIG91dHB1dCBmb3JtYXQgc3VjaCBhcyBodG1sIG9yIHBkZiB3aGljaCBjb250YWlucyBmb3JtYXR0ZWQgdGV4dCwgY29kZSwgYW5kIHRoZSByZXN1bHRzIG9mIHRoZSBjb2RlIGVtYmVkZGVkIGluIHRoZSBkb2N1bWVudC4gV2UnbGwgY292ZXIgdGhpcyBpbiBtb3JlIGRlcHRoIE1vZHVsZS9IYW5kb3V0IDQuCgpcCgojIFIgU3ludGF4CgpHZW5lcmFsIHN5bnRheCBpbmZvOgoKLSBSIGlzIGNhc2Ugc2Vuc2l0aXZlIChlLmcuIGB3ZWlnaHRgIGFuZCBgV2VpZ2h0YCBhcmUgZGlmZmVyZW50IGVudGl0aWVzKQotIFNwYWNlcyBhcmUgaWdub3JlZCBpbiBhc3NpZ25tZW50cyBhbmQgZXhwcmVzc2lvbnMuIEZvciBleGFtcGxlIGA4KzNgIGFuZCBgOCArIDNgIGFyZSBmdW5jdGlvbmFsbHkgZXF1aXZhbGVudC4gSG93ZXZlciwgZ2VuZXJvdXMgdXNlIG9mIHdoaXRlIHNwYWNlIGlzIGVuY291cmFnZWQgdG8gaW1wcm92ZSBhY2Nlc3NpYmlsaXR5LgotIFZhcmlhYmxlIGFuZCBmdW5jdGlvbiBuYW1lcyBpbiBSIGNvbnZlbnRpb25hbGx5IHVzZSAqKnNuYWtlIGNhc2UqKi4gQWxsIGxldHRlcnMgYXJlIGxvd2VyIGNhc2UsIGFuZCB3b3JkcyBhcmUgc2VwYXJhdGVkIGJ5IHVuZGVyc2NvcmUgKGUuZy4gYGFubnVhbF9tZWFuX3JhaW5mYWxsYCkuCgpcCgojIyBNYXRoZW1hdGljYWwgb3BlcmF0b3JzCgpBZGRpdGlvbjogYCtgCgpTdWJ0cmFjdGlvbjogYC1gCgpNdWx0aXBsaWNhdGlvbjogYCpgCgpEaXZpc2lvbjogYC9gCgpFeHBvbmVudGlhdGlvbjogYF5gCgpNb2R1bG8gKHJlbWFpbmRlcik6IGAlJWAKCmBgYHtyfQojIEFkZGl0aW9uCjEgKyAyCgojIFN1YnRyYWN0aW9uCjMgLSA2CgojIE11bHRpcGxpY2F0aW9uCjQgKiAyCgojIERpdmlzaW9uCjEyIC8gMwoKIyBFeHBvbmVudGlhdGlvbgoyICoqIDUKCiMgTW9kdWxvCjUgJSUgMgoKYGBgCgojIyBEYXRhIHR5cGVzCgpSIGhhcyB0aHJlZSBwcmltYXJ5IHR5cGVzIG9mIGRhdGE6CgotIG51bWVyaWMKLSBjaGFyYWN0ZXJzCi0gYm9vbGVhbgoKTnVtZXJpYyBkYXRhIGNhbiBiZSBpbnRlZ2VyICh3aG9sZSBudW1iZXJzKSBvciAiZG91YmxlIiAoaGF2aW5nIGEgZGVjaW1hbCBwYXJ0KS4KCkNoYXJhY3RlciBkYXRhIGl0ZW1zIGFyZSBjb21wcmlzZWQgb2Ygb25lIG9yIG1vcmUgbGV0dGVycywgbnVtYmVycywgb3IgKHBlcm1pdHRlZCkgc3ltYm9scy4gSW4gdGhlIHZlcm5hY3VsYXIsIHRoZXNlIGFyZSBjYWxsZWQgInN0cmluZ3MiLiBTdHJpbmdzIGFyZSBkZWZpbmVkIGluIFIgYnkgZW5jbG9zaW5nIHRoZW0gaW4gcXVvdGF0aW9uIG1hcmtzIChlLmcuIGAiRW1wZXJvciBQZW5ndWluImApLgoKQm9vbGVhbnMgYXJlIGxvZ2ljYWwgZGF0YS4gVGhleSBjYW4gdGFrZSBvbiBvbmx5IHRoZSB2YWx1ZXMgYFRSVUVgIG9yIGBGQUxTRWAsIGFuZCBhcmUgdXNlZCBmb3IgbG9naWNhbCBvcGVyYXRpb25zLgoKUiBmdW5jdGlvbnMgKHNlZSBkaXNjdXNzaW9uIGJlbG93KSBhY2NlcHQgaW5wdXQgZGF0YSBvZiBzcGVjaWZpYyB0eXBlKHMpLiBBcHBseWluZyBhIGZ1bmN0aW9uIG9yIG9wZXJhdGlvbiB0byB0aGUgIndyb25nIiB0eXBlIG9mIGRhdGEgd2lsbCBjYXVzZSBhbiBlcnJvci4KClwKCiMjIFZhcmlhYmxlcwoKVmFyaWFibGVzIGFyZSBuYW1lZCBvYmplY3RzIGluIHdoaWNoIHdlIHN0b3JlIGRhdGEuIFRoZSBzdG9yZWQgdmFsdWVzIGNhbiBiZSByZWZlcmVuY2VkL3VzZWQgbGF0ZXIgaW4gb3VyIGNvZGUuCgpWYXJpYWJsZSBuYW1lcyBtdXN0OgoKLSBTdGFydCB3aXRoIGEgbGV0dGVyCi0gQ29udGFpbiBubyBub24tYWxwaGFudW1lcmljIHN5bWJvbHMgZXhjZXB0IC4gKGZ1bGwgc3RvcCkgYW5kIF8gKHVuZGVyc2NvcmUpCgpWYXJpYWJsZSBuYW1lcyBzaG91bGQgYWx3YXlzIGJlIGRlc2NyaXB0aXZlIG9mIHRoZWlyIGNvbnRlbnRzLiBUaGlzIHdpbGwgaGVscCB5b3UgcmVtZW1iZXIgd2hhdCBkYXRhIHRoZXkgaG9sZCB3aGVuIHRoZXkgYXJlIHVzZWQgaW4gdGhlIGNvZGUuCgpcCgojIyBBc3NpZ25tZW50IG9wZXJhdG9ycwoKSW4gUiBgPC1gIGFuZCBgPWAgYXJlIGJvdGggdXNlZCBmb3IgYXNzaWdubWVudC4gIGA8LWAgaXMgdXNlZCB0byBhc3NpZ24gYSB2YWx1ZSB0byBhIHZhcmlhYmxlLiBgPWAgaXMgdXNlZCBpbnNpZGUgYSBmdW5jdGlvbiBjYWxsIHRvIGFzc2lnbiBhIHZhbHVlIHRvIGEgZnVuY3Rpb24gaW5wdXQuCgpUaGUgcmlnaHQtaGFuZCBzaWRlIG9mIGFuIGFzc2lnbm1lbnQgc3RhdGVtZW50IGlzIGV2YWx1YXRlZCBmaXJzdC4gVGhlIHJlc3VsdCBpcyB0aGVuIGFzc2lnbmVkIHRvIHRoZSB2YXJpYWJsZSBvbiB0aGUgbGVmdC1oYW5kIHNpZGUuIFRodXMgdGhlIHN0YXRlbWVudCBgeCA8LSB4ICogMmAgbWVhbnMgIkZpcnN0IG11bHRpcGx5IHRoZSBjdXJyZW50IHZhbHVlIG9mIHggYnkgMi4gVGFrZSB0aGUgcmVzdWx0IG9mIHRoYXQgb3BlcmF0aW9uIGFuZCBhc3NpZ24gaXQgYXMgdGhlIG5ldyB2YWx1ZSBvZiB4LiIKCk5vdGUgdGhhdCB2YXJpYWJsZXMgKipvbmx5IGNvbnRhaW4gdGhlIGxhc3QgdGhpbmcgdGhhdCB3YXMgYXNzaWduZWQgdG8gdGhlbSoqLiBBc3NpZ25pbmcgYSB2YWx1ZSB0byBhIHZhcmlhYmxlIG92ZXJ3cml0ZXMgYW55IGV4aXN0aW5nIHZhbHVlLgpcCgojIyBGdW5jdGlvbnMKCkZ1bmN0aW9ucyBhcmUgZW5jYXBzdWxhdGVkLCBuYW1lZCBjaHVua3Mgb2YgY29kZS4gV2UgKipjYWxsKiogYSBmdW5jdGlvbiBieSB0eXBpbmcgaXRzIG5hbWUsIGZvbGxvd2VkIGJ5ICgpLiBXZSBwcm92aWRlIGFueSByZXF1aXJlZCBkYXRhIGlucHV0cyAoY2FsbGVkICpmdW5jdGlvbiBhcmd1bWVudHMqIGluIHRoaXMgY29udGV4dCkgYnkgcGxhY2luZyB0aGVtIGJldHdlZW4gdGhlIHJvdW5kIGJyYWNrZXRzLiBXaGVuIGEgZnVuY3Rpb24gaXMgY2FsbGVkLCBSIGV4ZWN1dGVzIHRoZSBjb2RlIHdoaWNoIGl0IGVuY2Fwc3VsYXRlcyBhbmQgcmV0dXJucyB0aGUgcmVzdWx0LgoKRm9yIGV4YW1wbGUsIGlmIHdlIHdhbnQgdG8gZmluZCB0aGUgc3F1YXJlIHJvb3Qgb2YgYSBudW1iZXIsIHdlIGNhbiB1c2UgdGhlIGBzcXJ0YCBmdW5jdGlvbiBhbmQgcHJvdmlkZSB0aGUgbnVtYmVyIGFzIGlucHV0OgoKYGBge3J9CnNxcnQoNjQpCmBgYAoKTWFueSBmdW5jdGlvbnMgcmVxdWlyZSBtdWx0aXBsZSBwaWVjZXMgb2YgaW5wdXQgZGF0YS4gTXVsdGlwbGUgYXJndW1lbnRzIGFyZSBwbGFjZWQgYmV0d2VlbiB0aGUgcm91bmQgYnJhY2tldHMsIHNlcGFyYXRlZCBieSBjb21tYXMuIAoKRWFjaCBmdW5jdGlvbiBhcmd1bWVudCBoYXMgYSBuYW1lLiBBcmd1bWVudHMgY2FuIGJlIGlkZW50aWZpZWQgYnkgbmFtZSwgb3IgYnkgb3JkaW5hbCBwb3NpdGlvbiB3aXRoaW4gdGhlIHJvdW5kIGJyYWNrZXRzLgoKYGBge3J9CiMgYnkgcG9zaXRpb24Kcm91bmQoMy4xNDIsIDEpCgojIGJ5IG5hbWUKcm91bmQoeCA9IDMuMTQyLCBkaWdpdHMgPSAxKQpgYGAKClRvIHNlZSB3aGF0IGFyZ3VtZW50cyBhIGZ1bmN0aW9uIHJlcXVpcmVzLCBjYWxsIHRoZSBgYXJnc2AgZnVuY3Rpb24sIHBhc3NpbmcgaW4gdGhlIGZ1bmN0aW9uIG5hbWU6CgpgYGB7cn0KYXJncyhyb3VuZCkKYGBgCgpSIGNvbnRhaW5zIG1hbnksIG1hbnksIHBvd2VyZnVsIHByZS1kZWZpbmVkIGZ1bmN0aW9ucy4gSW4gb25lIG9mIG91ciBsYXRlciBtb2R1bGVzLCB3ZSB3aWxsIGxlYXJuIGhvdyB0byB3cml0ZSBvdXIgb3duIGN1c3RvbSBmdW5jdGlvbnMuCgpcCgojIyBDb21wYXJpc29uIE9wZXJhdG9ycwoKQ29tcGFyaXNvbiBvcGVyYXRvcnMgZXZhbHVhdGUgdG8gZWl0aGVyIGBUUlVFYCBvciBgRkFMU0VgLgoKQ29tcGFyYXRvcnM6CgotIGVxdWFsaXR5OiBgPT1gCi0gbm90IGVxdWFsIHRvOmAhPWAKLSBncmVhdGVyIHRoYW46IGA+YAotIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bzogYD49YAotIGxlc3MgdGhhbjogYDxgCi0gbGVzcyB0aGFuIG9yIGVxdWFsIHRvOiBgPD1gCgpMb2dpY2FsIG9wZXJhdG9ycwoKLSBub3Q6IGAhYAotIG9yOiBgfGAKLSBhbmQ6IGAmYAoKV2UnbGwgY292ZXIgdGhlc2UgaW4gbW9yZSBkZXB0aCBpbiB0aGUgW1NlbGVjdGluZyBhbmQgRmlsdGVyaW5nIE1vZHVsZV0oMDMtc3Vic2V0Lmh0bWwpLgoKXAoKIyMgQ29tbWVudHMKClRoZSBgI2Agc3ltYm9sIGRlbm90ZXMgYSBjb21tZW50LiBSIHdpbGwgaWdub3JlIGFsbCB0ZXh0IGZvbGxvd2luZyB0aGUgYCNgIG9uIHRoZSBzYW1lIGxpbmUuIENvbW1lbnRzIHNob3VsZCBleHBsYWluIHRoZSBsb2dpYyBvZiB0aGUgY29kZS4gVGhpcyBoZWxwcyBvdGhlciBwZW9wbGUgdW5kZXJzdGFuZCB5b3VyIGNvZGU7IGl0IGFsc28gaGVscHMgeW91IHJlbWVtYmVyIHlvdXIgdGhpbmtpbmcgd2hlbiB5b3UgcmV2aXNpdCB5b3VyIG93biBjb2RlIGluIHRoZSBmdXR1cmUuIFRob3JvdWdoIGNvbW1lbnRpbmcgaXMgc28gZXNzZW50aWFsIHRvIHNvZnR3YXJlIGRldmVsb3BtZW50IHRoYXQgbW9zdCBwcm9mZXNzaW9uYWxzICp3cml0ZSB0aGVpciBjb21tZW50cyBmaXJzdCosIHRoZW4gZmlsbCBpbiB0aGUgY29kZSBmb2xsb3dpbmcgdGhlIHN0cnVjdHVyZSBkZWZpbmVkIGJ5IHRoZSBjb21tZW50cy4KClwKCiMgQ29tcGxleCBEYXRhCgojIyBWZWN0b3JzCgpBIHZlY3RvciBpcyBhIGNvbXBsZXggZGF0YSBzdHJ1Y3R1cmUgdGhhdCBob2xkcyBtdWx0aXBsZSBkYXRhIGVsZW1lbnRzLiBWZWN0b3JzIGFyZSAqKmhvbW9nZW5lb3VzKiogLS0gYWxsIHRoZWlyIGVsZW1lbnRzIG11c3QgYmUgb2YgdGhlIHNhbWUgZGF0YSB0eXBlLiAKClRvIGNyZWF0ZSBhIHZlY3RvciB1c2UgZnVuY3Rpb24gYGMoKWAsIHRoZSBfY29tYmluZV8gZnVuY3Rpb24uIEl0ZW1zIGFyZSBzZXBhcmF0ZWQgYnkgY29tbWFzLgoKYGBge3J9CnNvbWVfbGV0dGVycyA8LSBjKCJhIiwgImIiLCAiYyIpCnNvbWVfbGV0dGVycwoKc29tZV9udW1iZXJzIDwtIGMoMiwgNCwgNikKc29tZV9udW1iZXJzCmBgYAoKV2UgY2FuIHNlZSB0aGUgZGF0YSB0eXBlIG9mIGEgdmVjdG9yIHVzaW5nIGB0eXBlb2ZgCgpgYGB7cn0KdHlwZW9mKHNvbWVfbGV0dGVycykKCnR5cGVvZihzb21lX251bWJlcnMpCmBgYAoKXAoKIyMgU3Vic2V0dGluZyBieSBpbmRleAoKVG8gYWNjZXNzIGluZGl2aWR1YWwgaXRlbXMgaW4gYSB2ZWN0b3IgdXNlIGBbXWAsIHRoZSAqKmluZGV4IG9wZXJhdG9yKiosIGFzIHNob3duIGJlbG93LiBQbGFjZSB0aGUgaXRlbSdzIG9yZGluYWwgcG9zaXRpb24gYmV0d2VlbiB0aGUgc3F1YXJlIGJyYWNrZXRzLiBTZWxlY3QgbXVsdGlwbGUgaXRlbXMgYnkgcGxhY2luZyBhIHZlY3RvciBvZiBwb3NpdGlvbnMgYmV0d2VlbiB0aGUgc3F1YXJlIGJyYWNrZXRzLgoKCmBgYHtyfQpzb21lX251bWJlcnMKCiMgcHVsbCBvdXQgdGhlIHNlY29uZCBpdGVtCnNvbWVfbnVtYmVyc1syXQoKc29tZV9sZXR0ZXJzCgojIHB1bGwgb3V0IGl0ZW1zIDEgYW5kIDMKc29tZV9sZXR0ZXJzW2MoMSwzKV0KYGBgCgpXZSB3aWxsIHNlZSBleGFtcGxlcyBvZiBtb3JlIGNvbXBsZXggZGF0YSBzdHJ1Y3R1cmVzIGFuZCB0aGVpciB1c2UgaW4gbGF0ZXIgbW9kdWxlcy4KCgpcCgojIEdldHRpbmcgSGVscAoKVG8gYWNjZXNzIHRoZSBSIGRvY3VtZW50YXRpb24gZm9yIGEgZnVuY3Rpb24sIGNhbGwgYGhlbHAoKWAgcGFzc2luZyBpbiB0aGUgZnVuY3Rpb24gbmFtZSwgb3IgdHlwZSBgP2AgZm9sbG93ZWQgYnkgdGhlIG5hbWUgb2YgdGhlIGZ1bmN0aW9uIChubyBpbnRlcnZlbmluZyBzcGFjZSkuCgotIGBoZWxwKGxtKWAgCi0gYD9sbWAKCkxhbmd1YWdlIGRvY3VtZW50YXRpb24gdGVuZHMgdG8gYmUgdGVyc2UsIGFuZCB0YXJnZXRlZCB0byB0aGUgYWR2YW5jZWQgdXNlci4gRnJlcXVlbnRseSB5b3Ugd2lsbCB3YW50IG1vcmUgZGV0YWlsZWQgZXhwbGFuYXRpb24gdGhhbiBpcyBhdmFpbGFibGUgZnJvbSB0aGUgYnVpbHQtaW4gaGVscC4gV2UgcmVjb21tZW5kIEdvb2dsZSAobXkgbW9zdCBjb21tb24gc2VhcmNoIGlzICJob3cgdG8gLi4uIGluIFIiKSBvciBvbmUgb2YgdGhlIG1hbnkgdXNlZnVsIHRleHQgYm9va3MgYXZhaWxhYmxlIHRocm91Z2ggdGhlIFVuaXZlcnNpdHkgbGlicmFyeSAoc2VlIGZvciBleGFtcGxlLCBodHRwczovL290YWdvLnByaW1vLmV4bGlicmlzZ3JvdXAuY29tL3Blcm1hbGluay82NE9UQUdPX0lOU1QvcWVmM2xqL2FsbWE5OTI2MTc5Mzc3NDAxODkxKQoKXAoKCiMgUHJvamVjdHMKClByb2plY3RzIHdpdGhpbiBSU3R1ZGlvIHByb3ZpZGUgYSBtZWNoYW5pc20gdG8gb3JnYW5pc2UgeW91ciB3b3JrLiBBIFByb2plY3QgaXMgYSBkaXJlY3Rvcnkgb24geW91ciBjb21wdXRlciB3aGVyZSB5b3UgZ2F0aGVyIHJlbGF0ZWQgY29kZSwgZG9jdW1lbnRhdGlvbiwgZGF0YSwgYW5kIG91dHB1dHMgc28gdGhhdCBldmVyeXRoaW5nIG5lZWRlZCB0byByZWNyZWF0ZSBhbiBhbmFseXNpcyBpcyAiYnVuZGxlZCB0b2dldGhlciIuCgpUbyBjcmVhdGUgYSBuZXcgUHJvamVjdDogCgotIEZpbGUgLT4gTmV3IFByb2plY3QgLT4gTmV3IERpcmVjdG9yeSAtPiBOZXcgUHJvamVjdAotIENob29zZSB3aGVyZSB5b3Ugd2FudCBpdCB0byBsaXZlIGFuZCBnaXZlIGl0IGEgbmFtZQotIENsaWNrICJDcmVhdGUgUHJvamVjdCIKCkl0IGlzIHVzZWZ1bCB0byBhZGQgc29tZSBzdWJmb2xkZXJzIHRvIHlvdXIgUHJvamVjdCBmb2xkZXIuIEEgY29tbW9uIG9yZ2FuaXNhdGlvbiBpcyB0byBoYXZlIHNlcGFyYXRlIHN1YmZvbGRlcnMgZm9yIHlvdXIgc2NyaXB0cywgaW5wdXQgZmlsZXMsIG91dHB1dCBmaWxlcywgYW5kIGRvY3VtZW50YXRpb24uCgpZb3UgY2FuIGNyZWF0ZSBzdWJmb2xkZXJzIGJ5IHVzaW5nIHRoZSAiTmV3IEZvbGRlciIgYnV0dG9uIGluIHRoZSBGaWxlcyBwYW5lbCBvciB1c2luZyB0aGUgYGRpci5jcmVhdGUoKWAgZnVuY3Rpb24sIGFzIHNob3duIGJlbG93LgoKYGBge3IsIGV2YWw9RkFMU0V9CmRpci5jcmVhdGUoInNjcmlwdHMiKQpkaXIuY3JlYXRlKCJkYXRhIikKZGlyLmNyZWF0ZSgiZGF0YSIpCmRpci5jcmVhdGUoIm91dHB1dHMiKQpgYGAKClwKCiMgTW9kdWxlIDAxIEV4ZXJjaXNlcwoKCjEuIENyZWF0ZSBhIHZlY3RvciBvZiA1IG51bWJlcnMgYW5kIGFzc2lnbiBpdCB0byBhIHZhcmlhYmxlLgoKMi4gRmluZCBvdXQgdGhlIGBsZW5ndGhgIG9mIHRoZSB2ZWN0b3IuCgozLiBEaXZpZGUgdGhlIGVudGlyZSB2ZWN0b3IgYnkgMiBhbmQgc3RvcmUgdGhlIHJlc3VsdCBpbnRvIGEgdmFyaWFibGUgY2FsbGVkICpkaXZfMiouIEV4cGxhaW4gd2hhdCBoYXBwZW5zIHdoZW4geW91IHBlcmZvcm0gYSBtYXRoZW1hdGljYWwgb3BlcmF0aW9uIG9uIGEgdmVjdG9yLgoKNC4gQ2FsY3VsYXRlIHRoZSBtaW5pbXVtLCBtYXhpbXVtLCBtZWFuLCBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciB0aGUgKmRpdl8yKiB2ZWN0b3IuIFJvdW5kIGVhY2ggcmVzdWx0IHRvIDIgZGVjaW1hbCBwbGFjZXMuCgo1LiBDcmVhdGUgYW5kIGFzc2lnbiBhIHZlY3RvciBvZiBhdCBsZWFzdCA0IGFuaW1hbCBuYW1lcyBpbnRvIF9hbmltYWxzXy4KCjYuIENvbXB1dGUgdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIGluIGVhY2ggaXRlbS4gVXNlIG9ubHkgb25lIGxpbmUgb2YgY29kZS4KCjcuIEV4dHJhY3QgdGhlIGZpcnN0IGFuZCBmb3VydGggYW5pbWFsIGludG8gYSBuZXcgdmFyaWFibGUuCgo4LiBSZW1vdmUgdGhlIHRoaXJkIGFuaW1hbCBmcm9tIHlvdXIgb3JpZ2luYWwgYW5pbWFscyB2ZWN0b3IuIFRoZXJlIGFyZSBtdWx0aXBsZSBzeW50YWN0aWNhbGx5IGxlZ2FsIHdheXMgdG8gYWNoaWV2ZSB0aGlzIGluIFIsIGJ1dCBzb21lIGFyZSBtb3JlIGVsZWdhbnQgdGhhbiBvdGhlcnMuIChIaW50OiB3aGF0IGRvZXMgdXNpbmcgYSBuZWdhdGl2ZSBpbmRleCBkbz8pCgo5LiBDcmVhdGUgYSB2ZWN0b3IgdGhhdCBoYXMgdGhyZWUgY29waWVzIG9mIHRoaXMgdXBkYXRlZCBhbmltYWxzIHZlY3Rvci4gVXNlIG9ubHkgb25lIGxpbmUgb2YgY29kZS4KCjEwLiBDb21iaW5lIHlvdXIgYW5pbWFsIGFuZCBudW1iZXIgdmVjdG9ycyB0b2dldGhlciBpbnRvIGEgbmV3IHZhcmlhYmxlIGNhbGxlZCBfY29lcmNlZF8uIFJ1biBgdHlwZW9mYCBvbiB0aGlzIHZlY3Rvci4gRXhwbGFpbiB3aHkgdGhlIHR5cGVzIG9mIHNvbWUgZWxlbWVudHMgaGF2ZSBiZWVuIGNoYW5nZWQuCgoKIyMjIEV4YW1wbGUgc29sdXRpb25zCgoxLgoKYGBge3IsIHpuMDFfc29sbjEsIGNsYXNzLnNvdXJjZSA9ICJmb2xkLWhpZGUifQpteV9udW1iZXJzIDwtIGMoMTIsIDYzLCAzLCA3LCA4NCkKYGBgCgotLS0tCgoyLgoKYGBge3IsIHpuMDJfc29sbjIsIGNsYXNzLnNvdXJjZSA9ICJmb2xkLWhpZGUifQpsZW5ndGgobXlfbnVtYmVycykKYGBgCgotLS0tCgozLiAKCmBgYHtyIHpuMDFfc29sbjMsIGNsYXNzLnNvdXJjZSA9ICJmb2xkLWhpZGUifQpkaXZfMiA8LSBteV9udW1iZXJzIC8gMgpkaXZfMgoKIyBXaGVuIGEgbWF0aGVtYXRpY2FsIG9wZXJhdG9yIGlzIGFwcGxpZWQgdG8gYSB2ZWN0b3IsIHRoZSBvcGVyYXRpb24gaXMKIyBwZXJmb3JtZWQgb24gZWFjaCBpbmRpdmlkdWFsIHZlY3RvciBlbGVtZW50LCBhbmQgdGhlIHdob2xlIHNldCBvZiBuZXcgdmFsdWVzCiMgaXMgcmV0dXJuZWQuCgpgYGAKCi0tLS0KCjQuCgpgYGB7ciB6bjAxX3NvbG40LCBjbGFzcy5zb3VyY2UgPSAiZm9sZC1oaWRlIn0KIyBOb3RlIHRoZSByYW5nZSBvZiBzeW50YWN0aWMgb3B0aW9ucy4gU3RyaXZlIGZvciBhIGJhbGFuY2UgYmV0d2VlbiBjbGFyaXR5IGFuZAojIHBhcnNpbW9ueS4KCiMgbWluaW11bQptaW5fbnVtYmVyIDwtIG1pbihkaXZfMikKcm91bmQobWluX251bWJlciwgZGlnaXRzID0gMikKCiMgbWF4aW11bQptYXhfbnVtYmVyIDwtIG1heChkaXZfMikKcm91bmQobWF4X251bWJlciwgMikKCiMgbWVhbgpyb3VuZChtZWFuKGRpdl8yKSwgZGlnaXRzID0gMikKCiMgc3RhbmRhcmQgZGV2aWF0aW9uCnJvdW5kKHNkKGRpdl8yKSwgMikKYGBgCgotLS0tLQoKNS4KCmBgYHtyIHpuMDFfc29sbjUsIGNsYXNzLnNvdXJjZSA9ICJmb2xkLWhpZGUifQphbmltYWxzIDwtIGMoImxpb24iLCAidGlnZXIiLCAic25ha2UiLCAiYmVldGxlIiwgInR1cnRsZSIpCmFuaW1hbHMKYGBgCgotLS0KCjYuCgpgYGB7ciwgem4wMV9zb2xuNiwgY2xhc3Muc291cmNlID0gImZvbGQtaGlkZSJ9Cm5jaGFyKGFuaW1hbHMpCmBgYAoKLS0tLQoKNy4KCmBgYHtyLCB6bjAxX3NvbG43LCBjbGFzcy5zb3VyY2UgPSAiZm9sZC1oaWRlIn0KdHdvX2FuaW1hbHMgPC0gYW5pbWFsc1tjKDEsNCldCnR3b19hbmltYWxzCmBgYAoKLS0tLS0KCjguCgpgYGB7ciB6bjAxX3NvbG44LCBjbGFzcy5zb3VyY2UgPSAiZm9sZC1oaWRlIn0KYW5pbWFscyA8LSBhbmltYWxzWy0zXQphbmltYWxzCmBgYAoKLS0tCgo5LgoKYGBge3IsIHpuMDFfc29sbjksIGNsYXNzLnNvdXJjZSA9ICJmb2xkLWhpZGUifQphbmltYWxzMyA8LSBjKGFuaW1hbHMsIGFuaW1hbHMsIGFuaW1hbHMpCmFuaW1hbHMzCmBgYAoKLS0tCgoxMC4KCmBgYHtyIHpuMTBfc29sbjEwLCBjbGFzcy5zb3VyY2UgPSAiZm9sZC1oaWRlIn0KbXlfbnVtYmVycwp0eXBlb2YobXlfbnVtYmVycykKYW5pbWFscwp0eXBlb2YoYW5pbWFscykKCmNvbWJpbmVkIDwtIGMobXlfbnVtYmVycywgYW5pbWFscykKdHlwZW9mKGNvbWJpbmVkKQpjb21iaW5lZAoKIyBUaGUgbnVtZXJpYyBlbGVtZW50cyBoYXZlIGJlZW4gY29lcmNlZCB0byB0eXBlIGNoYXJhY3RlciBzbyB0aGF0CiMgdGhlIHZlY3RvciByZW1haW5zIGhvbW9nZW5lb3VzLgpgYGAKCg==