1 WHAT IS R?

R is a programming language and environment for statistical computing and graphics. The software is free and open-source.

R provides wide variety of statistical and graphical techniques, and is highly extensible (i.e. designed so that users or developers can expand or add to its capabilities). There are many user written packages.

The following is pulled from the “About R” section of the R Project’s website (https://www.r-project.org/about.html)

R is an integrated suite of software facilities for data manipulation, calculation and graphical display. It includes an effective data handling and storage facility, a suite of operators for calculations on arrays, in particular matrices, a large, coherent, integrated collection of intermediate tools for data analysis, graphical facilities for data analysis and display either on-screen or on hardcopy, and a well-developed, simple and effective programming language which includes conditionals, loops, user-defined recursive functions and input and output facilities.

1.1 R can be used in many ways

Download and apply GUIs (graphical user interface; provides a more user friendly environment) to R language. –> Makes it look like SPSS –> No programming needed –> This way of doing things is useful as a first exposure

Learn and use the syntax of specific packages (a common way non-programmers use R) –> Packages are groups of function and help files. Someone else has already “programmed” the solution, and you are using it because it fits your needs well enough. –> Each package has its own syntax, constraints, and bugs –> Packages are all open source

Learn R-programming –> Write your own functions –> Hardest to learn, but gives maximum flexibility

2 What is R Studio?

R Studio is an integrated development environment (IDE) for R. It includes a console, syntax-highlighting editor that supports direct code execution, and tools for plotting, history, debugging and workspace management. It makes R easier to use, as it is a relatively user-friendly environment. And free!

2.1 Where to download R and R Studio?

R https://cran.r-project.org/bin/windows/base/

See https://cran.r-project.org/doc/FAQ/R-FAQ.html for information about the current version of R, and how it can be obtained and installed.

R Studio https://www.rstudio.com/products/rstudio/download3/ or https://www.rstudio.com/products/rstudio/download/preview/

See https://www.rstudio.com/products/RStudio/ for more information about R Studio

2.2 Basics of Using R Studio

*For a more in-depth introduction to R Studio, see http://dss.princeton.edu/training/RStudio101.pdf

2.2.1 R Studio Elements

Drop-down Menus: Drop down menus at the top ofthe window provide menu options that allow you to maneuver in R Studio a bit without writing out lines of code. As might be expected, the options are limited in comparison to what you can code yourself, but they may feel more user-friendly for those not used to coding, and can provide useful shortcuts.

Text Editor: This is where you write in the script you want to run. You can type multiple lines of code into the text editor without having each line evaluated by R.

Pressing “enter” will move the cursor to the next line, but will not command the code to run.

To run a line or block of code: PC users: ctrl+enter

Mac users: apple+enter

Putting “#” in front of a line means code won’t run; instead, allows you comment Common pitfall: using a capital letter in some lines of code and not in others (e.g., “Time1” in some places and “time1” in others). Capitalization must be consistent Spaces between commands, however, don’t matter.

*directions to follow all involve commands you will enter into the text editor.

Console: You can type commands in the console as you do in the text editor, as well as see output.

Environment The Environment tab stores and shows all of the active objects, values, and functions (and anything else you create) during your R session.

2.3 To set the working directory

The “working directory” is the specific location - i.e. the filepath - where you want R to read in data or files from and write out results to.

If you don’t specify the working directory at the beginning of your session, you run the risk of pulling from the wrong dataset, or missing the dataset, and saving out to the wrong location and therefore losing your results.

In PCs, you can find the filepath by left-clicking on the bar at the top of the folder you want to designate as your working directory.

In Macs, you can find the filepath by selecting the folder you want, hitting Command+i or right-clicking on the folder and selecting “Get Info,” then clicking on “Where” under “General.”

# set the working directory with the following function: setwd(filepath)

#setwd('C:/Users/PsychologyDept/Desktop') 
# This example shows how to set the working directory in R to the folder "Downloads" within the folder "PsychologyDept," which in turn is in the folder "Users" on the C drive.

#Note that you must use the forward slash / or double backslash \\ in R. The Windows format of single backslash will not work.

#You can check what your working directory is by using the following function:

#getwd()

More information on working directories and workspaces can be found at: https://support.rstudio.com/hc/en-us/articles/200711843-Working-Directories-and-Workspaces

Data in R can be stored in a few different forms. Numerics is the default computational type of data. Both integers and decimal values will initially be read as numeric, though you can specify that you want to treat your data as Integer data subsequently (see Chapter 2 for more details) Logicals, as described below, set up true/false comparisons between variables.
Character data, or string data, means the data is treated as a sequence of symbols to which we don’t necessarily attach other meaning. So, for example, words would be stored in R as character or string data.

See Chapter 2 for more information on data types and how to modify them when needed.

R’s data structures include vectors, matrices, arrays, lists, and data frames. Vectors, matrices, and data frames will be introduced below, after a few other introductory bits and pieces.

3 R the calculator

In its most basic form, R can be used as a simple calculator.

# Addition
5 + 4 
## [1] 9
# Subtraction
5 - 4 
## [1] 1
# Multiplication
3 * 4
## [1] 12
# Division
(5 + 5) / 2 
## [1] 5
# Exponentiation
5^2
## [1] 25
#Note: console in R Studio shows results of work you're doing, i.e. "prints" answers.

#If you create a new object, you can see it in Console by typing what you have called it, after you create it. 
#See c.sq e.g. in Part 3.1

4 Creating Variables

#To name a variable, use <-
  #E.g. to create a variable named "Pirate.1" that is just a single number, do:
Chocolate <- 4

#See how things are stored in console, and in values, as you create variables
#You type:
  Sugar = 5
  Sugar <- 5
  Flour <- 2*Sugar
  Cookie<-Sugar*Flour

#What does your Console show?
#What does your Values tab (where it is keeping track of objects) show?

#If you then type b and result.1 it will print it, i.e. show value in console
#Type:
  Flour
## [1] 10
  Cookie
## [1] 50
#What does your Console show?

WARNING: DON’T name new variables that refer to preexisting functions. For example, “mean” is a preexisting function. To check if something is already a function, type name in parentheses and hover cursor over what you just typed, see if variable name appears to populate it.

#hover cursors over the two lines below
(mean)
## function (x, ...) 
## UseMethod("mean")
## <bytecode: 0x00000000177ef5d0>
## <environment: namespace:base>
(median)
## function (x, na.rm = FALSE, ...) 
## UseMethod("median")
## <bytecode: 0x0000000013f31978>
## <environment: namespace:stats>

5 Logicals

Logicals are a variable type used to compare variables. See Chapter 2 for more information.

3 == 3
## [1] TRUE
#== means equals
3 != 4 
## [1] TRUE
#!= means not equals
3 < 2
## [1] FALSE
!(3 < 2)
## [1] TRUE
#What does your Console show?

6 Vectors

A vector is a sequence of data elements of the same basic type. See http://www.r-tutor.com/r-introduction/vector for a longer introduction to vectors in R Studio, and see Chapter 2 for more in depth discussion of vector types.

#Make A vector

Ice.Cream <- c(4,2,6,3,7,4,1,9,1,6) #Correct. This gives us a vector of 10 data elements that are all numerical values.

# Brussel.Sprouts <- 4,2,6,3,7,4,1,9,1,6      #gives an error
# Kale <- 4 2 6 3 7 4 1 9 1 6       #gives an error
#(the error-giving commands are commented out so script can run, but you can remove # at beginning of line to see what happens when you try to run them)


#So what does "c()" do? Combines values into a vector or list.
#to find out what something doesin R, can look it up in R like this:
?c

#another way of doing it:
(Brownie <- c(0,2,0,4,0)) #the () around the "call" causes it to appear without the need to call (i.e. use) Brownie
## [1] 0 2 0 4 0

7 Simple vectors manipulation

#vector X Vector has to be the same length such as this: 

Sundae <- Ice.Cream * Ice.Cream
Sundae
##  [1] 16  4 36  9 49 16  1 81  1 36
#What does console show after you input "c.sq" ?

#Vector can also be a multiple
length(Ice.Cream)/ length(Brownie)
## [1] 2
Ice.Cream * Brownie
##  [1]  0  4  0 12  0  0  2  0  4  0
#Note: multiplies first value by first value, second value by second value, third value by third value. 
#When one vector runs out of values, starts again with first value

7.1 Matrix Math

Snack <- matrix(1:12, ncol = 3, nrow = 4)
Snack
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12
#see how this created a matrix with values from 1-12, with 3 columns and 4 rows

t(Snack) #transpose a matrix
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12
#see how now there are 4 columns and 3 rows

Snack*Snack #multiply the matrix by its self
##      [,1] [,2] [,3]
## [1,]    1   25   81
## [2,]    4   36  100
## [3,]    9   49  121
## [4,]   16   64  144
#see how each cell was multiplied by itself

7.1.1 Vectors x matrices

#vector of 1
Bite <-2 
Big.Snack<- Snack * Bite
#i.e. 'Snack' matrix*2

#vector of 2
Bites <-c(2,4)
Bigger.Snack<-Snack * Bites
#i.e. 'Snack' matrix variables are multiplied by 2, then 4, then 2, then 4, etc.


#Look at the data tables that were created in a separate window, or by printing new matrices
Big.Snack
##      [,1] [,2] [,3]
## [1,]    2   10   18
## [2,]    4   12   20
## [3,]    6   14   22
## [4,]    8   16   24
Bigger.Snack
##      [,1] [,2] [,3]
## [1,]    2   10   18
## [2,]    8   24   40
## [3,]    6   14   22
## [4,]   16   32   48

8 Working with built in functions

#Reminder of Ice.Cream (a vector we built earlier)
Ice.Cream
##  [1] 4 2 6 3 7 4 1 9 1 6
#check out these built in functions!
mean(Ice.Cream)
## [1] 4.3
median(Ice.Cream)
## [1] 4
var(Ice.Cream)
## [1] 7.122222
sd(Ice.Cream)
## [1] 2.668749
summary(Ice.Cream)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00    2.25    4.00    4.30    6.00    9.00
#a list of useful built in functions
# http://www.sr.bham.ac.uk/~ajrs/R/r-function_list.html

#builtins() # List all built-in functions

#?NA        # Help page on handling of missing data values
#abs(x)     # The absolute value of "x"
#append()   # Add elements to a vector
#c(x)       # A generic function which combines its arguments 
#cbind()    # Combine vectors by row/column (cf. "paste" in Unix)
#diff(x)    # Returns suitably lagged and iterated differences
#identical()  # Test if 2 objects are *exactly* equal
#jitter()     # Add a small amount of noise to a numeric vector
#length(x)    # Return no. of elements in vector x
#paste(x)     # Concatenate vectors after converting to character
#range(x)     # Returns the minimum and maximum of x
#rep(1,5)     # Repeat the number 1 five times
#rev(x)       # List the elements of "x" in reverse order
#seq(1,10,0.4)  # Generate a sequence (1 -> 10, spaced by 0.4)
#sign(x)        # Returns the signs of the elements of x
#sort(x)        # Sort the vector x
#order(x)       # list sorted element numbers of x
#unique(x)      # Remove duplicate entries from vector


#quick and dirty plots
#hist(x)    #histogram
#plot(x,y)  #scatter

8.1 Passing arguments

“Passing an argument” to a function means that you are providing inputs that specify certain parameters regarding how that function is computed. Arguments can represent data, or parameters that specifies the action of the function.

Take note! To use a built in function, follow “help” for each one you want to use in order to figure out what the default arguments are. Then you can decide whether you want to adjust defaults.

?mean
#see "Arguments" section of description in the Help section that appears for what the arguments below can do if set differently. Example below of how you could pass "trim" argument to the mean function.

mean(Ice.Cream, trim = 0, na.rm = FALSE) #default settings
## [1] 4.3
# trim and na.rm are arguments that are passed to the mean function, meaning that they each have instructions on how to compute the mean of the Ice.Cream data.

?trim
## No documentation for 'trim' in specified packages and libraries:
## you could try '??trim'
?na.rm
## No documentation for 'na.rm' in specified packages and libraries:
## you could try '??na.rm'
# you can change the specifications for these arguments
mean(Ice.Cream, trim = 0.5)
## [1] 4

You can also write your own function (a “custom” function), and pass multiple data vectors to it. You can name your function anything you like. It’s helpful to create a “return statement.” This specifies what you want returned to you when you run the function.

In the case below, a function called “Yummy.test” is created which comprises the more complex function defined in the {}. It calculates the mean of x and multiplies it by the mean of y, and divides the whole thing by the sum of y.

Yummy.test <- function(x,y) {
  result<- mean(x) * mean(y) /  sum(y)
  return(result)
}

Yummy.test(Ice.Cream,Brownie)
## [1] 0.86

9 Dataframes

Data frames are like tables in a relational database, and are a primary way data are stored in R. A data frame is a table, or two-dimensional array-like structure, in which each column contains measurements on one variable, and each row contains one case. Technically, in R a data frame is a list of column vectors.

Let’s build a data frame!

#build some vectors of equal length

Ice.Cream <- c(4,2,6,3,7,4,1,9,1,6)
Gummy.Bears <- c(7,3,5,3,9,2,0,0,4,8)
Potato.Chips <- c(5,0,8,1,2,3,9,4,9,2)

snacky.dataframe = data.frame(Ice.Cream, Gummy.Bears, Potato.Chips)       
# snacky.dataframe is a data frame

?data.frame

9.1 Attributes

Any data that you enter into R can be given an attribute. An attribute is a characteristic of your data, and you can find that information and change it. For example, The names and the dimensions of matrices and arrays are stored in R as attributes of the object. These attributes can be seen as labeled values you can attach to any object.

To see all the attributes of an object, you can use the attributes() function.

?attributes

attributes(Bigger.Snack)
## $dim
## [1] 4 3
?dim


attributes(snacky.dataframe)
## $names
## [1] "Ice.Cream"    "Gummy.Bears"  "Potato.Chips"
## 
## $row.names
##  [1]  1  2  3  4  5  6  7  8  9 10
## 
## $class
## [1] "data.frame"
?names
?row.names
?class


str(Bigger.Snack)
##  num [1:4, 1:3] 2 8 6 16 10 24 14 32 18 40 ...
str(snacky.dataframe)
## 'data.frame':    10 obs. of  3 variables:
##  $ Ice.Cream   : num  4 2 6 3 7 4 1 9 1 6
##  $ Gummy.Bears : num  7 3 5 3 9 2 0 0 4 8
##  $ Potato.Chips: num  5 0 8 1 2 3 9 4 9 2
?str

#note that when you see the structure of the vector, and then of the dataframe, it shows that all variables are stored as numeric. See Chapter 2 for more details on how to modify.
LS0tDQp0aXRsZTogIkNoYXB0ZXIgMTogVGhlIEJhc2ljcyINCmF1dGhvcjogIkRhdmkgTGFraW5kIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUNCiAgICBmb250c2l6ZTogOHB0DQogICAgdG9jOiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIFdIQVQgSVMgUj8NCg0KUiBpcyBhIHByb2dyYW1taW5nIGxhbmd1YWdlIGFuZCBlbnZpcm9ubWVudCBmb3Igc3RhdGlzdGljYWwgY29tcHV0aW5nIGFuZCBncmFwaGljcy4gVGhlIHNvZnR3YXJlIGlzIGZyZWUgYW5kIG9wZW4tc291cmNlLg0KDQpSIHByb3ZpZGVzIHdpZGUgdmFyaWV0eSBvZiBzdGF0aXN0aWNhbCBhbmQgZ3JhcGhpY2FsIHRlY2huaXF1ZXMsIGFuZCBpcyBoaWdobHkgZXh0ZW5zaWJsZSAoaS5lLiBkZXNpZ25lZCBzbyB0aGF0IHVzZXJzIG9yIGRldmVsb3BlcnMgY2FuIGV4cGFuZCBvciBhZGQgdG8gaXRzIGNhcGFiaWxpdGllcykuIFRoZXJlIGFyZSBtYW55IHVzZXIgd3JpdHRlbiBwYWNrYWdlcy4gDQoNClRoZSBmb2xsb3dpbmcgaXMgcHVsbGVkIGZyb20gdGhlICJBYm91dCBSIiBzZWN0aW9uIG9mIHRoZSBSIFByb2plY3QncyB3ZWJzaXRlIChodHRwczovL3d3dy5yLXByb2plY3Qub3JnL2Fib3V0Lmh0bWwpDQoNClIgaXMgYW4gaW50ZWdyYXRlZCBzdWl0ZSBvZiBzb2Z0d2FyZSBmYWNpbGl0aWVzIGZvciBkYXRhIG1hbmlwdWxhdGlvbiwgY2FsY3VsYXRpb24gYW5kIGdyYXBoaWNhbCBkaXNwbGF5LiBJdCBpbmNsdWRlcyBhbiBlZmZlY3RpdmUgZGF0YSBoYW5kbGluZyBhbmQgc3RvcmFnZSBmYWNpbGl0eSwgYSBzdWl0ZSBvZiBvcGVyYXRvcnMgZm9yIGNhbGN1bGF0aW9ucyBvbiBhcnJheXMsIGluIHBhcnRpY3VsYXIgbWF0cmljZXMsIGEgbGFyZ2UsIGNvaGVyZW50LCBpbnRlZ3JhdGVkIGNvbGxlY3Rpb24gb2YgaW50ZXJtZWRpYXRlIHRvb2xzIGZvciBkYXRhIGFuYWx5c2lzLCBncmFwaGljYWwgZmFjaWxpdGllcyBmb3IgZGF0YSBhbmFseXNpcyBhbmQgZGlzcGxheSBlaXRoZXIgb24tc2NyZWVuIG9yIG9uIGhhcmRjb3B5LCBhbmQgYSB3ZWxsLWRldmVsb3BlZCwgc2ltcGxlIGFuZCBlZmZlY3RpdmUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2Ugd2hpY2ggaW5jbHVkZXMgY29uZGl0aW9uYWxzLCBsb29wcywgdXNlci1kZWZpbmVkIHJlY3Vyc2l2ZSBmdW5jdGlvbnMgYW5kIGlucHV0IGFuZCBvdXRwdXQgZmFjaWxpdGllcy4NCg0KDQoNCiMjIFIgY2FuIGJlIHVzZWQgaW4gbWFueSB3YXlzDQoNCioqRG93bmxvYWQgYW5kIGFwcGx5IEdVSXMgKGdyYXBoaWNhbCB1c2VyIGludGVyZmFjZTsgcHJvdmlkZXMgYSBtb3JlIHVzZXIgZnJpZW5kbHkgZW52aXJvbm1lbnQpIHRvIFIgbGFuZ3VhZ2UuKiogDQotLT4gTWFrZXMgaXQgbG9vayBsaWtlIFNQU1MNCi0tPiBObyBwcm9ncmFtbWluZyBuZWVkZWQNCi0tPiBUaGlzIHdheSBvZiBkb2luZyB0aGluZ3MgaXMgdXNlZnVsIGFzIGEgZmlyc3QgZXhwb3N1cmUNCg0KKipMZWFybiBhbmQgdXNlIHRoZSBzeW50YXggb2Ygc3BlY2lmaWMgcGFja2FnZXMgKGEgY29tbW9uIHdheSBub24tcHJvZ3JhbW1lcnMgdXNlIFIpKioNCi0tPiBQYWNrYWdlcyBhcmUgZ3JvdXBzIG9mIGZ1bmN0aW9uIGFuZCBoZWxwIGZpbGVzLiBTb21lb25lIGVsc2UgaGFzIGFscmVhZHkgInByb2dyYW1tZWQiIHRoZSBzb2x1dGlvbiwgYW5kIHlvdSBhcmUgdXNpbmcgaXQgYmVjYXVzZSBpdCBmaXRzIHlvdXIgbmVlZHMgd2VsbCBlbm91Z2guIA0KLS0+IEVhY2ggcGFja2FnZSBoYXMgaXRzIG93biBzeW50YXgsIGNvbnN0cmFpbnRzLCBhbmQgYnVncyANCi0tPiAqUGFja2FnZXMgYXJlIGFsbCBvcGVuIHNvdXJjZSoNCiAgDQoqKkxlYXJuIFItcHJvZ3JhbW1pbmcqKg0KLS0+IFdyaXRlIHlvdXIgb3duIGZ1bmN0aW9ucyANCi0tPiBIYXJkZXN0IHRvIGxlYXJuLCBidXQgZ2l2ZXMgbWF4aW11bSBmbGV4aWJpbGl0eQ0KDQoNCg0KIyBXaGF0IGlzIFIgU3R1ZGlvPw0KDQpSIFN0dWRpbyBpcyBhbiBpbnRlZ3JhdGVkIGRldmVsb3BtZW50IGVudmlyb25tZW50IChJREUpIGZvciBSLiBJdCBpbmNsdWRlcyBhIGNvbnNvbGUsIHN5bnRheC1oaWdobGlnaHRpbmcgZWRpdG9yIHRoYXQgc3VwcG9ydHMgZGlyZWN0IGNvZGUgZXhlY3V0aW9uLCBhbmQgdG9vbHMgZm9yIHBsb3R0aW5nLCBoaXN0b3J5LCBkZWJ1Z2dpbmcgYW5kIHdvcmtzcGFjZSBtYW5hZ2VtZW50LiBJdCBtYWtlcyBSIGVhc2llciB0byB1c2UsIGFzIGl0IGlzIGEgcmVsYXRpdmVseSB1c2VyLWZyaWVuZGx5IGVudmlyb25tZW50LiBBbmQgZnJlZSENCg0KIyMgV2hlcmUgdG8gZG93bmxvYWQgUiBhbmQgUiBTdHVkaW8/DQoqKlIqKg0KaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvYmluL3dpbmRvd3MvYmFzZS8NCg0KU2VlIGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL2RvYy9GQVEvUi1GQVEuaHRtbCBmb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBSLCBhbmQgaG93IGl0IGNhbiBiZSBvYnRhaW5lZCBhbmQgaW5zdGFsbGVkLg0KDQoqKlIgU3R1ZGlvKiogDQpodHRwczovL3d3dy5yc3R1ZGlvLmNvbS9wcm9kdWN0cy9yc3R1ZGlvL2Rvd25sb2FkMy8gb3IgaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC9wcmV2aWV3Lw0KDQpTZWUgaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvUlN0dWRpby8gZm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgUiBTdHVkaW8NCg0KDQoNCiMjIEJhc2ljcyBvZiBVc2luZyBSIFN0dWRpbw0KDQoqRm9yIGEgbW9yZSBpbi1kZXB0aCBpbnRyb2R1Y3Rpb24gdG8gUiBTdHVkaW8sIHNlZSBodHRwOi8vZHNzLnByaW5jZXRvbi5lZHUvdHJhaW5pbmcvUlN0dWRpbzEwMS5wZGYNCg0KDQojIyMgUiBTdHVkaW8gRWxlbWVudHMNCg0KKipEcm9wLWRvd24gTWVudXM6KiogRHJvcCBkb3duIG1lbnVzIGF0IHRoZSB0b3Agb2Z0aGUgd2luZG93IHByb3ZpZGUgbWVudSBvcHRpb25zIHRoYXQgYWxsb3cgeW91IHRvIG1hbmV1dmVyIGluIFIgU3R1ZGlvIGEgYml0IHdpdGhvdXQgd3JpdGluZyBvdXQgbGluZXMgb2YgY29kZS4gQXMgbWlnaHQgYmUgZXhwZWN0ZWQsIHRoZSBvcHRpb25zIGFyZSBsaW1pdGVkIGluIGNvbXBhcmlzb24gdG8gd2hhdCB5b3UgY2FuIGNvZGUgeW91cnNlbGYsIGJ1dCB0aGV5IG1heSBmZWVsIG1vcmUgdXNlci1mcmllbmRseSBmb3IgdGhvc2Ugbm90IHVzZWQgdG8gY29kaW5nLCBhbmQgY2FuIHByb3ZpZGUgdXNlZnVsIHNob3J0Y3V0cy4gICAgDQoNCioqVGV4dCBFZGl0b3I6KiogVGhpcyBpcyB3aGVyZSB5b3Ugd3JpdGUgaW4gdGhlIHNjcmlwdCB5b3Ugd2FudCB0byBydW4uIFlvdSBjYW4gdHlwZSBtdWx0aXBsZSBsaW5lcyBvZiBjb2RlIGludG8gdGhlIHRleHQgZWRpdG9yIHdpdGhvdXQgaGF2aW5nIGVhY2ggbGluZSBldmFsdWF0ZWQgYnkgUi4gDQoNCipQcmVzc2luZyAiZW50ZXIiIHdpbGwgbW92ZSB0aGUgY3Vyc29yIHRvIHRoZSBuZXh0IGxpbmUsIGJ1dCB3aWxsIG5vdCBjb21tYW5kIHRoZSBjb2RlIHRvIHJ1bi4qIA0KDQoqVG8gcnVuIGEgbGluZSBvciBibG9jayBvZiBjb2RlOiogDQpQQyB1c2VyczogY3RybCtlbnRlcg0KDQpNYWMgdXNlcnM6IGFwcGxlK2VudGVyDQoNCipQdXR0aW5nICIjIiBpbiBmcm9udCBvZiBhIGxpbmUgbWVhbnMgY29kZSB3b24ndCBydW47IGluc3RlYWQsIGFsbG93cyB5b3UgY29tbWVudCoNCipDb21tb24gcGl0ZmFsbDogdXNpbmcgYSBjYXBpdGFsIGxldHRlciBpbiBzb21lIGxpbmVzIG9mIGNvZGUgYW5kIG5vdCBpbiBvdGhlcnMgKGUuZy4sICJUaW1lMSIgaW4gc29tZSBwbGFjZXMgYW5kICJ0aW1lMSIgaW4gb3RoZXJzKS4gQ2FwaXRhbGl6YXRpb24gbXVzdCBiZSBjb25zaXN0ZW50Kg0KKlNwYWNlcyBiZXR3ZWVuIGNvbW1hbmRzLCBob3dldmVyLCBkb24ndCBtYXR0ZXIuKg0KDQoqZGlyZWN0aW9ucyB0byBmb2xsb3cgYWxsIGludm9sdmUgY29tbWFuZHMgeW91IHdpbGwgZW50ZXIgaW50byB0aGUgdGV4dCBlZGl0b3IuDQoNCioqQ29uc29sZToqKiBZb3UgY2FuIHR5cGUgY29tbWFuZHMgaW4gdGhlIGNvbnNvbGUgYXMgeW91IGRvIGluIHRoZSB0ZXh0IGVkaXRvciwgYXMgd2VsbCBhcyBzZWUgb3V0cHV0LiAgIA0KDQoqKkVudmlyb25tZW50KiogVGhlIEVudmlyb25tZW50IHRhYiBzdG9yZXMgYW5kIHNob3dzIGFsbCBvZiB0aGUgYWN0aXZlIG9iamVjdHMsIHZhbHVlcywgYW5kIGZ1bmN0aW9ucyAoYW5kIGFueXRoaW5nIGVsc2UgeW91IGNyZWF0ZSkgZHVyaW5nIHlvdXIgUiBzZXNzaW9uLiAgDQoNCg0KDQojIyBUbyBzZXQgdGhlIHdvcmtpbmcgZGlyZWN0b3J5DQpUaGUgIndvcmtpbmcgZGlyZWN0b3J5IiBpcyB0aGUgc3BlY2lmaWMgbG9jYXRpb24gLSBpLmUuIHRoZSBmaWxlcGF0aCAtIHdoZXJlIHlvdSB3YW50IFIgdG8gcmVhZCBpbiBkYXRhIG9yIGZpbGVzIGZyb20gYW5kIHdyaXRlIG91dCByZXN1bHRzIHRvLg0KDQpJZiB5b3UgZG9uJ3Qgc3BlY2lmeSB0aGUgd29ya2luZyBkaXJlY3RvcnkgYXQgdGhlIGJlZ2lubmluZyBvZiB5b3VyIHNlc3Npb24sIHlvdSBydW4gdGhlIHJpc2sgb2YgcHVsbGluZyBmcm9tIHRoZSB3cm9uZyBkYXRhc2V0LCBvciBtaXNzaW5nIHRoZSBkYXRhc2V0LCBhbmQgc2F2aW5nIG91dCB0byB0aGUgd3JvbmcgbG9jYXRpb24gYW5kIHRoZXJlZm9yZSBsb3NpbmcgeW91ciByZXN1bHRzLiANCg0KSW4gUENzLCB5b3UgY2FuIGZpbmQgdGhlIGZpbGVwYXRoIGJ5IGxlZnQtY2xpY2tpbmcgb24gdGhlIGJhciBhdCB0aGUgdG9wIG9mIHRoZSBmb2xkZXIgeW91IHdhbnQgdG8gZGVzaWduYXRlIGFzIHlvdXIgd29ya2luZyBkaXJlY3RvcnkuDQoNCkluIE1hY3MsIHlvdSBjYW4gZmluZCB0aGUgZmlsZXBhdGggYnkgc2VsZWN0aW5nIHRoZSBmb2xkZXIgeW91IHdhbnQsIGhpdHRpbmcgQ29tbWFuZCtpIG9yIHJpZ2h0LWNsaWNraW5nIG9uIHRoZSBmb2xkZXIgYW5kIHNlbGVjdGluZyAiR2V0IEluZm8sIiB0aGVuIGNsaWNraW5nIG9uICJXaGVyZSIgdW5kZXIgIkdlbmVyYWwuIg0KDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KDQojIHNldCB0aGUgd29ya2luZyBkaXJlY3Rvcnkgd2l0aCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uOiBzZXR3ZChmaWxlcGF0aCkNCg0KI3NldHdkKCdDOi9Vc2Vycy9Qc3ljaG9sb2d5RGVwdC9EZXNrdG9wJykgDQojIFRoaXMgZXhhbXBsZSBzaG93cyBob3cgdG8gc2V0IHRoZSB3b3JraW5nIGRpcmVjdG9yeSBpbiBSIHRvIHRoZSBmb2xkZXIgIkRvd25sb2FkcyIgd2l0aGluIHRoZSBmb2xkZXIgIlBzeWNob2xvZ3lEZXB0LCIgd2hpY2ggaW4gdHVybiBpcyBpbiB0aGUgZm9sZGVyICJVc2VycyIgb24gdGhlIEMgZHJpdmUuDQoNCiNOb3RlIHRoYXQgeW91IG11c3QgdXNlIHRoZSBmb3J3YXJkIHNsYXNoIC8gb3IgZG91YmxlIGJhY2tzbGFzaCBcXCBpbiBSLiBUaGUgV2luZG93cyBmb3JtYXQgb2Ygc2luZ2xlIGJhY2tzbGFzaCB3aWxsIG5vdCB3b3JrLg0KDQojWW91IGNhbiBjaGVjayB3aGF0IHlvdXIgd29ya2luZyBkaXJlY3RvcnkgaXMgYnkgdXNpbmcgdGhlIGZvbGxvd2luZyBmdW5jdGlvbjoNCg0KI2dldHdkKCkNCg0KYGBgDQoNCk1vcmUgaW5mb3JtYXRpb24gb24gd29ya2luZyBkaXJlY3RvcmllcyBhbmQgd29ya3NwYWNlcyBjYW4gYmUgZm91bmQgYXQ6IGh0dHBzOi8vc3VwcG9ydC5yc3R1ZGlvLmNvbS9oYy9lbi11cy9hcnRpY2xlcy8yMDA3MTE4NDMtV29ya2luZy1EaXJlY3Rvcmllcy1hbmQtV29ya3NwYWNlcw0KDQpEYXRhIGluIFIgY2FuIGJlIHN0b3JlZCBpbiBhIGZldyBkaWZmZXJlbnQgZm9ybXMuDQoqTnVtZXJpY3MqIGlzIHRoZSBkZWZhdWx0IGNvbXB1dGF0aW9uYWwgdHlwZSBvZiBkYXRhLiBCb3RoIGludGVnZXJzIGFuZCBkZWNpbWFsIHZhbHVlcyB3aWxsIGluaXRpYWxseSBiZSByZWFkIGFzIG51bWVyaWMsIHRob3VnaCB5b3UgY2FuIHNwZWNpZnkgdGhhdCB5b3Ugd2FudCB0byB0cmVhdCB5b3VyIGRhdGEgYXMgKkludGVnZXIqIGRhdGEgc3Vic2VxdWVudGx5IChzZWUgQ2hhcHRlciAyIGZvciBtb3JlIGRldGFpbHMpIA0KKkxvZ2ljYWxzKiwgYXMgZGVzY3JpYmVkIGJlbG93LCBzZXQgdXAgdHJ1ZS9mYWxzZSBjb21wYXJpc29ucyBiZXR3ZWVuIHZhcmlhYmxlcy4gIA0KKkNoYXJhY3RlciBkYXRhKiwgb3Igc3RyaW5nIGRhdGEsIG1lYW5zIHRoZSBkYXRhIGlzIHRyZWF0ZWQgYXMgYSBzZXF1ZW5jZSBvZiBzeW1ib2xzIHRvIHdoaWNoIHdlIGRvbid0IG5lY2Vzc2FyaWx5IGF0dGFjaCBvdGhlciBtZWFuaW5nLiBTbywgZm9yIGV4YW1wbGUsIHdvcmRzIHdvdWxkIGJlIHN0b3JlZCBpbiBSIGFzIGNoYXJhY3RlciBvciBzdHJpbmcgZGF0YS4gIA0KDQpTZWUgQ2hhcHRlciAyIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRhdGEgdHlwZXMgYW5kIGhvdyB0byBtb2RpZnkgdGhlbSB3aGVuIG5lZWRlZC4NCg0KDQpSJ3MgZGF0YSBzdHJ1Y3R1cmVzIGluY2x1ZGUgdmVjdG9ycywgbWF0cmljZXMsIGFycmF5cywgbGlzdHMsIGFuZCBkYXRhIGZyYW1lcy4gVmVjdG9ycywgbWF0cmljZXMsIGFuZCBkYXRhIGZyYW1lcyB3aWxsIGJlIGludHJvZHVjZWQgYmVsb3csIGFmdGVyIGEgZmV3IG90aGVyIGludHJvZHVjdG9yeSBiaXRzIGFuZCBwaWVjZXMuDQoNCiMgUiB0aGUgY2FsY3VsYXRvcg0KDQpJbiBpdHMgbW9zdCBiYXNpYyBmb3JtLCBSIGNhbiBiZSB1c2VkIGFzIGEgc2ltcGxlIGNhbGN1bGF0b3IuDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQojIEFkZGl0aW9uDQo1ICsgNCANCg0KIyBTdWJ0cmFjdGlvbg0KNSAtIDQgDQoNCiMgTXVsdGlwbGljYXRpb24NCjMgKiA0DQoNCiMgRGl2aXNpb24NCig1ICsgNSkgLyAyIA0KDQojIEV4cG9uZW50aWF0aW9uDQo1XjINCg0KI05vdGU6IGNvbnNvbGUgaW4gUiBTdHVkaW8gc2hvd3MgcmVzdWx0cyBvZiB3b3JrIHlvdSdyZSBkb2luZywgaS5lLiAicHJpbnRzIiBhbnN3ZXJzLg0KDQojSWYgeW91IGNyZWF0ZSBhIG5ldyBvYmplY3QsIHlvdSBjYW4gc2VlIGl0IGluIENvbnNvbGUgYnkgdHlwaW5nIHdoYXQgeW91IGhhdmUgY2FsbGVkIGl0LCBhZnRlciB5b3UgY3JlYXRlIGl0LiANCiNTZWUgYy5zcSBlLmcuIGluIFBhcnQgMy4xDQpgYGANCg0KDQojIENyZWF0aW5nIFZhcmlhYmxlcw0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCg0KI1RvIG5hbWUgYSB2YXJpYWJsZSwgdXNlIDwtDQogICNFLmcuIHRvIGNyZWF0ZSBhIHZhcmlhYmxlIG5hbWVkICJQaXJhdGUuMSIgdGhhdCBpcyBqdXN0IGEgc2luZ2xlIG51bWJlciwgZG86DQpDaG9jb2xhdGUgPC0gNA0KDQojU2VlIGhvdyB0aGluZ3MgYXJlIHN0b3JlZCBpbiBjb25zb2xlLCBhbmQgaW4gdmFsdWVzLCBhcyB5b3UgY3JlYXRlIHZhcmlhYmxlcw0KI1lvdSB0eXBlOg0KICBTdWdhciA9IDUNCiAgU3VnYXIgPC0gNQ0KICBGbG91ciA8LSAyKlN1Z2FyDQogIENvb2tpZTwtU3VnYXIqRmxvdXINCg0KI1doYXQgZG9lcyB5b3VyIENvbnNvbGUgc2hvdz8NCiNXaGF0IGRvZXMgeW91ciBWYWx1ZXMgdGFiICh3aGVyZSBpdCBpcyBrZWVwaW5nIHRyYWNrIG9mIG9iamVjdHMpIHNob3c/DQoNCiNJZiB5b3UgdGhlbiB0eXBlIGIgYW5kIHJlc3VsdC4xIGl0IHdpbGwgcHJpbnQgaXQsIGkuZS4gc2hvdyB2YWx1ZSBpbiBjb25zb2xlDQojVHlwZToNCiAgRmxvdXINCiAgQ29va2llDQoNCiNXaGF0IGRvZXMgeW91ciBDb25zb2xlIHNob3c/DQogIA0KYGBgDQoNCldBUk5JTkc6IERPTidUIG5hbWUgbmV3IHZhcmlhYmxlcyB0aGF0IHJlZmVyIHRvIHByZWV4aXN0aW5nIGZ1bmN0aW9ucy4gRm9yIGV4YW1wbGUsICJtZWFuIiBpcyBhIHByZWV4aXN0aW5nIGZ1bmN0aW9uLiBUbyBjaGVjayBpZiBzb21ldGhpbmcgaXMgYWxyZWFkeSBhIGZ1bmN0aW9uLCB0eXBlIG5hbWUgaW4gcGFyZW50aGVzZXMgYW5kIGhvdmVyIGN1cnNvciBvdmVyIHdoYXQgeW91IGp1c3QgdHlwZWQsIHNlZSBpZiB2YXJpYWJsZSBuYW1lIGFwcGVhcnMgdG8gcG9wdWxhdGUgaXQuDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KI2hvdmVyIGN1cnNvcnMgb3ZlciB0aGUgdHdvIGxpbmVzIGJlbG93DQoobWVhbikNCihtZWRpYW4pDQoNCmBgYA0KDQoNCiMgTG9naWNhbHMNCkxvZ2ljYWxzIGFyZSBhIHZhcmlhYmxlIHR5cGUgdXNlZCB0byBjb21wYXJlIHZhcmlhYmxlcy4gU2VlIENoYXB0ZXIgMiBmb3IgbW9yZSBpbmZvcm1hdGlvbi4NCg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQozID09IDMNCiM9PSBtZWFucyBlcXVhbHMNCjMgIT0gNCANCiMhPSBtZWFucyBub3QgZXF1YWxzDQozIDwgMg0KISgzIDwgMikNCg0KI1doYXQgZG9lcyB5b3VyIENvbnNvbGUgc2hvdz8NCg0KYGBgDQoNCiMgVmVjdG9ycw0KDQpBIHZlY3RvciBpcyBhIHNlcXVlbmNlIG9mIGRhdGEgZWxlbWVudHMgb2YgdGhlIHNhbWUgYmFzaWMgdHlwZS4gU2VlIGh0dHA6Ly93d3cuci10dXRvci5jb20vci1pbnRyb2R1Y3Rpb24vdmVjdG9yIGZvciBhIGxvbmdlciBpbnRyb2R1Y3Rpb24gdG8gdmVjdG9ycyBpbiBSIFN0dWRpbywgYW5kIHNlZSBDaGFwdGVyIDIgZm9yIG1vcmUgaW4gZGVwdGggZGlzY3Vzc2lvbiBvZiB2ZWN0b3IgdHlwZXMuIA0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCiNNYWtlIEEgdmVjdG9yDQoNCkljZS5DcmVhbSA8LSBjKDQsMiw2LDMsNyw0LDEsOSwxLDYpICNDb3JyZWN0LiBUaGlzIGdpdmVzIHVzIGEgdmVjdG9yIG9mIDEwIGRhdGEgZWxlbWVudHMgdGhhdCBhcmUgYWxsIG51bWVyaWNhbCB2YWx1ZXMuDQoNCiMgQnJ1c3NlbC5TcHJvdXRzIDwtIDQsMiw2LDMsNyw0LDEsOSwxLDYgCSAgI2dpdmVzIGFuIGVycm9yDQojIEthbGUgPC0gNCAyIDYgMyA3IDQgMSA5IDEgNgkJI2dpdmVzIGFuIGVycm9yDQojKHRoZSBlcnJvci1naXZpbmcgY29tbWFuZHMgYXJlIGNvbW1lbnRlZCBvdXQgc28gc2NyaXB0IGNhbiBydW4sIGJ1dCB5b3UgY2FuIHJlbW92ZSAjIGF0IGJlZ2lubmluZyBvZiBsaW5lIHRvIHNlZSB3aGF0IGhhcHBlbnMgd2hlbiB5b3UgdHJ5IHRvIHJ1biB0aGVtKQ0KDQoNCiNTbyB3aGF0IGRvZXMgImMoKSIgZG8/IENvbWJpbmVzIHZhbHVlcyBpbnRvIGEgdmVjdG9yIG9yIGxpc3QuDQojdG8gZmluZCBvdXQgd2hhdCBzb21ldGhpbmcgZG9lc2luIFIsIGNhbiBsb29rIGl0IHVwIGluIFIgbGlrZSB0aGlzOg0KP2MNCg0KI2Fub3RoZXIgd2F5IG9mIGRvaW5nIGl0Og0KKEJyb3duaWUgPC0gYygwLDIsMCw0LDApKSAjdGhlICgpIGFyb3VuZCB0aGUgImNhbGwiIGNhdXNlcyBpdCB0byBhcHBlYXIgd2l0aG91dCB0aGUgbmVlZCB0byBjYWxsIChpLmUuIHVzZSkgQnJvd25pZQ0KYGBgDQoNCg0KIyBTaW1wbGUgdmVjdG9ycyBtYW5pcHVsYXRpb24gDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KI3ZlY3RvciBYIFZlY3RvciBoYXMgdG8gYmUgdGhlIHNhbWUgbGVuZ3RoIHN1Y2ggYXMgdGhpczogDQoNClN1bmRhZSA8LSBJY2UuQ3JlYW0gKiBJY2UuQ3JlYW0NClN1bmRhZQ0KDQojV2hhdCBkb2VzIGNvbnNvbGUgc2hvdyBhZnRlciB5b3UgaW5wdXQgImMuc3EiID8NCg0KI1ZlY3RvciBjYW4gYWxzbyBiZSBhIG11bHRpcGxlDQpsZW5ndGgoSWNlLkNyZWFtKS8gbGVuZ3RoKEJyb3duaWUpDQoNCkljZS5DcmVhbSAqIEJyb3duaWUNCg0KI05vdGU6IG11bHRpcGxpZXMgZmlyc3QgdmFsdWUgYnkgZmlyc3QgdmFsdWUsIHNlY29uZCB2YWx1ZSBieSBzZWNvbmQgdmFsdWUsIHRoaXJkIHZhbHVlIGJ5IHRoaXJkIHZhbHVlLiANCiNXaGVuIG9uZSB2ZWN0b3IgcnVucyBvdXQgb2YgdmFsdWVzLCBzdGFydHMgYWdhaW4gd2l0aCBmaXJzdCB2YWx1ZQ0KYGBgDQoNCg0KIyMgTWF0cml4IE1hdGgNCg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQpTbmFjayA8LSBtYXRyaXgoMToxMiwgbmNvbCA9IDMsIG5yb3cgPSA0KQ0KU25hY2sNCiNzZWUgaG93IHRoaXMgY3JlYXRlZCBhIG1hdHJpeCB3aXRoIHZhbHVlcyBmcm9tIDEtMTIsIHdpdGggMyBjb2x1bW5zIGFuZCA0IHJvd3MNCg0KdChTbmFjaykgI3RyYW5zcG9zZSBhIG1hdHJpeA0KI3NlZSBob3cgbm93IHRoZXJlIGFyZSA0IGNvbHVtbnMgYW5kIDMgcm93cw0KDQpTbmFjaypTbmFjayAjbXVsdGlwbHkgdGhlIG1hdHJpeCBieSBpdHMgc2VsZg0KI3NlZSBob3cgZWFjaCBjZWxsIHdhcyBtdWx0aXBsaWVkIGJ5IGl0c2VsZg0KYGBgDQoNCiMjIyBWZWN0b3JzIHggbWF0cmljZXMNCg0KYGBgIHtyLCBtZXNzYWdlPUZBTFNFLCBlY2hvPVRSVUV9DQoNCiN2ZWN0b3Igb2YgMQ0KQml0ZSA8LTIgDQpCaWcuU25hY2s8LSBTbmFjayAqIEJpdGUNCiNpLmUuICdTbmFjaycgbWF0cml4KjINCg0KI3ZlY3RvciBvZiAyDQpCaXRlcyA8LWMoMiw0KQ0KQmlnZ2VyLlNuYWNrPC1TbmFjayAqIEJpdGVzDQojaS5lLiAnU25hY2snIG1hdHJpeCB2YXJpYWJsZXMgYXJlIG11bHRpcGxpZWQgYnkgMiwgdGhlbiA0LCB0aGVuIDIsIHRoZW4gNCwgZXRjLg0KDQoNCiNMb29rIGF0IHRoZSBkYXRhIHRhYmxlcyB0aGF0IHdlcmUgY3JlYXRlZCBpbiBhIHNlcGFyYXRlIHdpbmRvdywgb3IgYnkgcHJpbnRpbmcgbmV3IG1hdHJpY2VzDQpCaWcuU25hY2sNCg0KQmlnZ2VyLlNuYWNrDQoNCmBgYA0KDQoNCiMgV29ya2luZyB3aXRoIGJ1aWx0IGluIGZ1bmN0aW9ucw0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0V9DQoNCiNSZW1pbmRlciBvZiBJY2UuQ3JlYW0gKGEgdmVjdG9yIHdlIGJ1aWx0IGVhcmxpZXIpDQpJY2UuQ3JlYW0NCg0KI2NoZWNrIG91dCB0aGVzZSBidWlsdCBpbiBmdW5jdGlvbnMhDQptZWFuKEljZS5DcmVhbSkNCm1lZGlhbihJY2UuQ3JlYW0pDQp2YXIoSWNlLkNyZWFtKQ0Kc2QoSWNlLkNyZWFtKQ0Kc3VtbWFyeShJY2UuQ3JlYW0pDQoNCiNhIGxpc3Qgb2YgdXNlZnVsIGJ1aWx0IGluIGZ1bmN0aW9ucw0KIyBodHRwOi8vd3d3LnNyLmJoYW0uYWMudWsvfmFqcnMvUi9yLWZ1bmN0aW9uX2xpc3QuaHRtbA0KDQojYnVpbHRpbnMoKSAjIExpc3QgYWxsIGJ1aWx0LWluIGZ1bmN0aW9ucw0KDQojP05BICAgICAgICAjIEhlbHAgcGFnZSBvbiBoYW5kbGluZyBvZiBtaXNzaW5nIGRhdGEgdmFsdWVzDQojYWJzKHgpICAgICAjIFRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiAieCINCiNhcHBlbmQoKSAgICMgQWRkIGVsZW1lbnRzIHRvIGEgdmVjdG9yDQojYyh4KSAgICAgICAjIEEgZ2VuZXJpYyBmdW5jdGlvbiB3aGljaCBjb21iaW5lcyBpdHMgYXJndW1lbnRzIA0KI2NiaW5kKCkgICAgIyBDb21iaW5lIHZlY3RvcnMgYnkgcm93L2NvbHVtbiAoY2YuICJwYXN0ZSIgaW4gVW5peCkNCiNkaWZmKHgpICAgICMgUmV0dXJucyBzdWl0YWJseSBsYWdnZWQgYW5kIGl0ZXJhdGVkIGRpZmZlcmVuY2VzDQojaWRlbnRpY2FsKCkgICMgVGVzdCBpZiAyIG9iamVjdHMgYXJlICpleGFjdGx5KiBlcXVhbA0KI2ppdHRlcigpICAgICAjIEFkZCBhIHNtYWxsIGFtb3VudCBvZiBub2lzZSB0byBhIG51bWVyaWMgdmVjdG9yDQojbGVuZ3RoKHgpICAgICMgUmV0dXJuIG5vLiBvZiBlbGVtZW50cyBpbiB2ZWN0b3IgeA0KI3Bhc3RlKHgpICAgICAjIENvbmNhdGVuYXRlIHZlY3RvcnMgYWZ0ZXIgY29udmVydGluZyB0byBjaGFyYWN0ZXINCiNyYW5nZSh4KSAgICAgIyBSZXR1cm5zIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIG9mIHgNCiNyZXAoMSw1KSAgICAgIyBSZXBlYXQgdGhlIG51bWJlciAxIGZpdmUgdGltZXMNCiNyZXYoeCkgICAgICAgIyBMaXN0IHRoZSBlbGVtZW50cyBvZiAieCIgaW4gcmV2ZXJzZSBvcmRlcg0KI3NlcSgxLDEwLDAuNCkgICMgR2VuZXJhdGUgYSBzZXF1ZW5jZSAoMSAtPiAxMCwgc3BhY2VkIGJ5IDAuNCkNCiNzaWduKHgpICAgICAgICAjIFJldHVybnMgdGhlIHNpZ25zIG9mIHRoZSBlbGVtZW50cyBvZiB4DQojc29ydCh4KSAgICAgICAgIyBTb3J0IHRoZSB2ZWN0b3IgeA0KI29yZGVyKHgpICAgICAgICMgbGlzdCBzb3J0ZWQgZWxlbWVudCBudW1iZXJzIG9mIHgNCiN1bmlxdWUoeCkgICAgICAjIFJlbW92ZSBkdXBsaWNhdGUgZW50cmllcyBmcm9tIHZlY3Rvcg0KDQoNCiNxdWljayBhbmQgZGlydHkgcGxvdHMNCiNoaXN0KHgpICAgICNoaXN0b2dyYW0NCiNwbG90KHgseSkgICNzY2F0dGVyDQpgYGANCg0KIyMgUGFzc2luZyBhcmd1bWVudHMgDQoNCiJQYXNzaW5nIGFuIGFyZ3VtZW50IiB0byBhIGZ1bmN0aW9uIG1lYW5zIHRoYXQgeW91IGFyZSBwcm92aWRpbmcgaW5wdXRzIHRoYXQgc3BlY2lmeSBjZXJ0YWluIHBhcmFtZXRlcnMgcmVnYXJkaW5nIGhvdyB0aGF0IGZ1bmN0aW9uIGlzIGNvbXB1dGVkLiBBcmd1bWVudHMgY2FuIHJlcHJlc2VudCBkYXRhLCBvciBwYXJhbWV0ZXJzIHRoYXQgc3BlY2lmaWVzIHRoZSBhY3Rpb24gb2YgdGhlIGZ1bmN0aW9uLg0KDQoNClRha2Ugbm90ZSEgVG8gdXNlIGEgYnVpbHQgaW4gZnVuY3Rpb24sIGZvbGxvdyAiaGVscCIgZm9yIGVhY2ggb25lIHlvdSB3YW50IHRvIHVzZSBpbiBvcmRlciB0byBmaWd1cmUgb3V0IHdoYXQgdGhlIGRlZmF1bHQgYXJndW1lbnRzIGFyZS4gVGhlbiB5b3UgY2FuIGRlY2lkZSB3aGV0aGVyIHlvdSB3YW50IHRvIGFkanVzdCBkZWZhdWx0cy4NCg0KDQpgYGAge3IsIG1lc3NhZ2U9RkFMU0UsIGVjaG89VFJVRX0NCg0KP21lYW4NCiNzZWUgIkFyZ3VtZW50cyIgc2VjdGlvbiBvZiBkZXNjcmlwdGlvbiBpbiB0aGUgSGVscCBzZWN0aW9uIHRoYXQgYXBwZWFycyBmb3Igd2hhdCB0aGUgYXJndW1lbnRzIGJlbG93IGNhbiBkbyBpZiBzZXQgZGlmZmVyZW50bHkuIEV4YW1wbGUgYmVsb3cgb2YgaG93IHlvdSBjb3VsZCBwYXNzICJ0cmltIiBhcmd1bWVudCB0byB0aGUgbWVhbiBmdW5jdGlvbi4NCg0KbWVhbihJY2UuQ3JlYW0sIHRyaW0gPSAwLCBuYS5ybSA9IEZBTFNFKSAjZGVmYXVsdCBzZXR0aW5ncw0KIyB0cmltIGFuZCBuYS5ybSBhcmUgYXJndW1lbnRzIHRoYXQgYXJlIHBhc3NlZCB0byB0aGUgbWVhbiBmdW5jdGlvbiwgbWVhbmluZyB0aGF0IHRoZXkgZWFjaCBoYXZlIGluc3RydWN0aW9ucyBvbiBob3cgdG8gY29tcHV0ZSB0aGUgbWVhbiBvZiB0aGUgSWNlLkNyZWFtIGRhdGEuDQoNCj90cmltDQo/bmEucm0NCg0KIyB5b3UgY2FuIGNoYW5nZSB0aGUgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZXNlIGFyZ3VtZW50cw0KbWVhbihJY2UuQ3JlYW0sIHRyaW0gPSAwLjUpDQoNCg0KYGBgDQoNCllvdSBjYW4gYWxzbyB3cml0ZSB5b3VyIG93biBmdW5jdGlvbiAoYSAiY3VzdG9tIiBmdW5jdGlvbiksIGFuZCBwYXNzIG11bHRpcGxlIGRhdGEgdmVjdG9ycyB0byBpdC4gWW91IGNhbiBuYW1lIHlvdXIgZnVuY3Rpb24gYW55dGhpbmcgeW91IGxpa2UuIEl0J3MgaGVscGZ1bCB0byBjcmVhdGUgYSAicmV0dXJuIHN0YXRlbWVudC4iIFRoaXMgc3BlY2lmaWVzIHdoYXQgeW91IHdhbnQgcmV0dXJuZWQgdG8geW91IHdoZW4geW91IHJ1biB0aGUgZnVuY3Rpb24uDQoNCkluIHRoZSBjYXNlIGJlbG93LCBhIGZ1bmN0aW9uIGNhbGxlZCAiWXVtbXkudGVzdCIgaXMgY3JlYXRlZCB3aGljaCBjb21wcmlzZXMgdGhlIG1vcmUgY29tcGxleCBmdW5jdGlvbiBkZWZpbmVkIGluIHRoZSB7fS4gSXQgY2FsY3VsYXRlcyB0aGUgbWVhbiBvZiB4IGFuZCBtdWx0aXBsaWVzIGl0IGJ5IHRoZSBtZWFuIG9mIHksIGFuZCBkaXZpZGVzIHRoZSB3aG9sZSB0aGluZyBieSB0aGUgc3VtIG9mIHkuIA0KDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KWXVtbXkudGVzdCA8LSBmdW5jdGlvbih4LHkpIHsNCiAgcmVzdWx0PC0gbWVhbih4KSAqIG1lYW4oeSkgLyAgc3VtKHkpDQogIHJldHVybihyZXN1bHQpDQp9DQoNCll1bW15LnRlc3QoSWNlLkNyZWFtLEJyb3duaWUpDQoNCg0KYGBgDQoNCg0KIyBEYXRhZnJhbWVzDQoNCkRhdGEgZnJhbWVzIGFyZSBsaWtlIHRhYmxlcyBpbiBhIHJlbGF0aW9uYWwgZGF0YWJhc2UsIGFuZCBhcmUgYSBwcmltYXJ5IHdheSBkYXRhIGFyZSBzdG9yZWQgaW4gUi4gQSBkYXRhIGZyYW1lIGlzIGEgdGFibGUsIG9yIHR3by1kaW1lbnNpb25hbCBhcnJheS1saWtlIHN0cnVjdHVyZSwgaW4gd2hpY2ggZWFjaCBjb2x1bW4gY29udGFpbnMgbWVhc3VyZW1lbnRzIG9uIG9uZSB2YXJpYWJsZSwgYW5kIGVhY2ggcm93IGNvbnRhaW5zIG9uZSBjYXNlLiBUZWNobmljYWxseSwgaW4gUiBhIGRhdGEgZnJhbWUgaXMgYSBsaXN0IG9mIGNvbHVtbiB2ZWN0b3JzLiANCg0KTGV0J3MgYnVpbGQgYSBkYXRhIGZyYW1lIQ0KDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KDQojYnVpbGQgc29tZSB2ZWN0b3JzIG9mIGVxdWFsIGxlbmd0aA0KDQpJY2UuQ3JlYW0gPC0gYyg0LDIsNiwzLDcsNCwxLDksMSw2KQ0KR3VtbXkuQmVhcnMgPC0gYyg3LDMsNSwzLDksMiwwLDAsNCw4KQ0KUG90YXRvLkNoaXBzIDwtIGMoNSwwLDgsMSwyLDMsOSw0LDksMikNCg0Kc25hY2t5LmRhdGFmcmFtZSA9IGRhdGEuZnJhbWUoSWNlLkNyZWFtLCBHdW1teS5CZWFycywgUG90YXRvLkNoaXBzKSAgICAgICANCiMgc25hY2t5LmRhdGFmcmFtZSBpcyBhIGRhdGEgZnJhbWUNCg0KP2RhdGEuZnJhbWUNCg0KYGBgDQojIyBBdHRyaWJ1dGVzDQoNCkFueSBkYXRhIHRoYXQgeW91IGVudGVyIGludG8gUiBjYW4gYmUgZ2l2ZW4gYW4gYXR0cmlidXRlLiBBbiBhdHRyaWJ1dGUgaXMgYSBjaGFyYWN0ZXJpc3RpYyBvZiB5b3VyIGRhdGEsIGFuZCB5b3UgY2FuIGZpbmQgdGhhdCBpbmZvcm1hdGlvbiBhbmQgY2hhbmdlIGl0LiBGb3IgZXhhbXBsZSwgVGhlIG5hbWVzIGFuZCB0aGUgZGltZW5zaW9ucyBvZiBtYXRyaWNlcyBhbmQgYXJyYXlzIGFyZSBzdG9yZWQgaW4gUiBhcyBhdHRyaWJ1dGVzIG9mIHRoZSBvYmplY3QuIFRoZXNlIGF0dHJpYnV0ZXMgY2FuIGJlIHNlZW4gYXMgbGFiZWxlZCB2YWx1ZXMgeW91IGNhbiBhdHRhY2ggdG8gYW55IG9iamVjdC4NCg0KVG8gc2VlIGFsbCB0aGUgYXR0cmlidXRlcyBvZiBhbiBvYmplY3QsIHlvdSBjYW4gdXNlIHRoZSBhdHRyaWJ1dGVzKCkgZnVuY3Rpb24uDQoNCmBgYCB7ciwgbWVzc2FnZT1GQUxTRSwgZWNobz1UUlVFfQ0KDQo/YXR0cmlidXRlcw0KDQphdHRyaWJ1dGVzKEJpZ2dlci5TbmFjaykNCj9kaW0NCg0KDQphdHRyaWJ1dGVzKHNuYWNreS5kYXRhZnJhbWUpDQo/bmFtZXMNCj9yb3cubmFtZXMNCj9jbGFzcw0KDQoNCnN0cihCaWdnZXIuU25hY2spDQpzdHIoc25hY2t5LmRhdGFmcmFtZSkNCj9zdHINCg0KI25vdGUgdGhhdCB3aGVuIHlvdSBzZWUgdGhlIHN0cnVjdHVyZSBvZiB0aGUgdmVjdG9yLCBhbmQgdGhlbiBvZiB0aGUgZGF0YWZyYW1lLCBpdCBzaG93cyB0aGF0IGFsbCB2YXJpYWJsZXMgYXJlIHN0b3JlZCBhcyBudW1lcmljLiBTZWUgQ2hhcHRlciAyIGZvciBtb3JlIGRldGFpbHMgb24gaG93IHRvIG1vZGlmeS4NCmBgYA0KDQoNCjxzY3JpcHQ+DQogIChmdW5jdGlvbihpLHMsbyxnLHIsYSxtKXtpWydHb29nbGVBbmFseXRpY3NPYmplY3QnXT1yO2lbcl09aVtyXXx8ZnVuY3Rpb24oKXsNCiAgKGlbcl0ucT1pW3JdLnF8fFtdKS5wdXNoKGFyZ3VtZW50cyl9LGlbcl0ubD0xKm5ldyBEYXRlKCk7YT1zLmNyZWF0ZUVsZW1lbnQobyksDQogIG09cy5nZXRFbGVtZW50c0J5VGFnTmFtZShvKVswXTthLmFzeW5jPTE7YS5zcmM9ZzttLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsbSkNCiAgfSkod2luZG93LGRvY3VtZW50LCdzY3JpcHQnLCdodHRwczovL3d3dy5nb29nbGUtYW5hbHl0aWNzLmNvbS9hbmFseXRpY3MuanMnLCdnYScpOw0KDQogIGdhKCdjcmVhdGUnLCAnVUEtOTg4Nzg3OTMtMScsICdhdXRvJyk7DQogIGdhKCdzZW5kJywgJ3BhZ2V2aWV3Jyk7DQoNCjwvc2NyaXB0Pg==