Introduction to R

RStudio is a program that helps you write and run R code more easily, especially for working with data, making graphs, and doing statistics.

You will have hopefully already downloaded R and RStudio. If not, follow the instructions on this page: R and RStudio setup

RStudio Interface

When we launch RStudio for the first time, we notice three main panels or quadrants:

Once we open a document, the interface will show four main panels:

1 - Top left panel

Files and scripts (source window or code editor)

This is your code editor, where you write, save, and run R scripts (.R), RMarkdown documents (.Rmd), or other file types.

2 - Bottom left panel

R console and terminal

This is the interactive R console, where code is executed immediately. You can:

  • Type and run commands interactively (great for testing small bits of code).
  • View outputs, error messages, and warnings in real time.
  • Switch to the Terminal tab for system-level commands.

3 - Top right panel

Objects, history, environment, tutorial and connections

This area lets you track what’s happening in your R session.

It has different tabs for different actions:

  • Environment: See all objects (like data frames, functions, variables) currently in memory.
  • History: View all commands you’ve previously run.
  • Connections: Manage database connections.
  • Tutorial: View built-in interactive tutorials (from the learnr package).

4 - Bottom right panel

Tree of folders, plots, packages, help, viewer

This panel contains various tools and outputs:

  • Files: Navigate your folder structure and open scripts.
  • Plots: View visualizations generated by your code.
  • Packages: Install, load, or update R packages.
  • Help: Search R documentation (?function_name shows here).
  • Viewer: View HTML content, like R Markdown outputs or Shiny apps.

Easing Into R

R as a Calculator

A good starting place for learning R is utilizing one of its most basic functions, which is that of a calculator. As mentioned above, there are four panels within RStudio, and to begin, let’s look at how this works in the R Console (bottom left panel).


Adding Numbers

You can add numbers using the plus sign +:

2 + 2


Subtracting Numbers

You can subtract numbers using a hyphen -:

10 - 4


Dividing Numbers

You can divide numbers using a slash /:

20/4


Multiplying Numbers

You can multiply numbers using the star *:

10 * 10


A quick note on the R console

As you can see from the actions above, the R console can be used as a place to type very small calculations or actions. However, a big draw back of using the console is that you can’t save the calculations that you are creating, and there is no way to add comments to your code. This is why we use R script files, as they allow us to keep track of everything that we’re doing in R with sufficient documentation for others (and yourself!) to interpret.

Types of files in R

There are two main types of files we can create in R studio to edit our code (R script files .R and RMarkdown files .Rmd)

The R script file (.R) is a plain text file that contains R code only. Use it when you want to write and run code line-by-line, such as for data cleaning, analysis, or function building. It’s good for experimenting, scripting, and running code interactively. It’s also good for sharing code with other researchers.

The RMarkdown file (.Rmd) has a mix of R code and written explanations, using Markdown formatting. It can be used to create dynamic, reproducible reports that can be knitted into HTML, PDF, or Word documents.It’s great for homework, research reports, dashboards, or combining narrative with code.

For the purposes of this program we’ll be using R scripts, but if you’re interested in learning more about RMarkdown, check out:


To create an R script file, select File > New File > R Script

Your Turn!

Create your first R script file.

Working in an R Script File

Let’s move to the R script file we have just created that is located in the top left panel. Let’s first try to re-run some of the mathematical calculations we ran above, but this time in the script:

2 + 2
10 - 4
20/4
10 * 10

Did it work?

Unless you have previous experience with R, or in you got quite clever with using a search engine, you will have noticed that R won’t simply run commands in a script when you press the enter/return button. This is because the R script is allowing you to freely type, edit, and adjust your code before it goes ahead and deploys it (another advantage over using the console).

Running Code in an R Script

There are a few different ways that you can run code in your R script:

  1. Point-and-click: In the top right of the RStudio screen, you will see a button that says Run. If you click on it, RStudio will run the line/chunk of code where your cursor is located. If your cursor is above a line of code, it will run the line below it, but if your cursor is below the code, it won’t run anything. You can also highlight multiple lines of code and press Run, and they will be run consecutively

  1. Keyboard commands: There are two main ways that you can use keyboard commands to code in R scripts:
  • Ctrl + Enter (Windows) / Command + RETURN (Mac) - will run a single line/chunk of code that your cursor is on
  • Ctrl + Shift + Enter (Window) / Command + Shift + Return (Mac) - will run all the code in your R script, beginning at the top.

Give these both a try with the calculations above, and start considering how you might use these as you move through your journey in learning R!

Basic Syntax of R

The most important components of an R script are objects and functions. Objects store information and functions are used to manipulate the data.

Assignment operators, pipes and arguments are used to link objects and functions and communicate what we want to do.


It should be noted that this diagram represents the full syntax of an R code snippet, which is the human language equivalent of a sentence. Much like learning a human language, we’re going to start off by learning about individual words and parts of speech before we jump into sentences (with paragraphs being the more advanced next step).

Let’s start by breaking down each one of these components:

Objects & Assignment Operators

An object is anything you create and name in R. It can be a number, a dataset, a function, or even a plot. Objects take on content from everything to the right of the assignment operator.

An assignment operator is how you store a value in R. It’s like saying: “Let this name hold this value.” It assigns content from the objects/functions/arguments on its right to the object on its left.

a <- 5 # x is now an object that holds the value 5
b <- "Anna" # b is now an object that holds the character Anna

Note

  • Since Anna is a series of characters (as opposed to numbers), it needs to be wrapped in quotations (we’ll learn more about data types in the next session).

You can overwrite a new value to the same object name. When you do this, the original value is replaced by the new value you assign to it.

name <- "Maria" # The "name" object now holds the value "Maria"

name <- "Anna" # The "name" object now holds the value "Anna", and no longer has the value "Maria".

Why overwriting is useful

  • As your analysis becomes more complicated, you often build your results step-by-step.

  • Instead of creating dozens of different object names, you can reuse the same object name to store updated versions of your data or results.

  • This keeps your environment clean and your code easier to read.


Objects can also be assigned several values. This is done by using the c() command, which stands for concatenate, and where the strings of values go into the brackets. You can think of this function as “glueing” elements together into one group. It can be used like this:

numbers <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

sports <- c("Basketball", "Golf", "Soccer", "Tennis")

You’ll notice that the word strings, or strings of characters, are surrounded by quotation marks "". This is because R, and most coding languages, handle character strings uniquely, and require quotations to surround words and phrases. We’ll cover this more in the next section, but for now, just know that every time you want to use a character string as a value in R, you need to use quotation marks.

Test yourself!

  1. Create an object called w, and assign it a value of 100.
  2. Create an object called x, and assign it a value of 25.
  3. Create an object called y, and assign it the value of basketball.
  4. Create an object called z, and assign it the value of baseball.

If this all worked, you will see in the top-right Environment pane the four new values that you have created.

Let’s keep playing:

  1. Use the additional symbol + to add w and x.
  2. Use the division symbol / to divide w by x.
  3. Re-write objects w and x to give them new values of your choosing.
  4. Use the additional symbol + to add y and z. Did it work? If not, what do you think might have happened?
  5. Try creating an object that contains multiple values.

Answers

# 1) w <- 100
# 2) x <- 25
# 3) y <- "basketball"
# 4) z <- "baseball"
# 5) w + x
# 6) w/x
# 7) Ex: w <- 500 
#       x <- 9000
# 8) This should show an error like the following: "Error in y + z : non-numeric argument to binary operator".  This is because R will only let you add numerical values together, and not character values.  This will be covered in more detail in the next section.
# 9) Ex: movies <- c("Pulp Fiction", "Lord of the Rings: The Fellowship of the Ring", "Highlander")

Functions & Arguments

Functions are much like verbs in a language, as they convey some sort of action to be performed. These are often (though not always) actions to be performed on an argument. We’re going to learn more about functions in the next section, but here are a couple basic functions to show you how they work.

numbers <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

mean(numbers)
## [1] 5.5

In this example, the mean function is applied to the numbers object (which in this case is the argument), and gives the mean for the series of numbers. For the sake of this session we’re not going to spend too much time on functions, but they will be discussed in more detail next session as we start getting deeper into the weeds of R.


Literate Coding

The concept of literate coding was introduced in an earlier session as a framework that provides a human-language explanation of how a script works so that people can accurately interpret and reuse the script. If you look at the script that you’ve currently got, it’s quite messy and difficult to interpret! This isn’t a huge issue because this is only a practice script, but it’s good to start developing good practices right at the start, so as you continue on your scripting journey, these principles become second nature. There are two primary ways we can start to support literate programming: commented code and object naming.

Commented Code

You may have noticed that in some of the example code blocks below, there is a # used occasionally before text blocks. This # is a very valuable tool in all coding languages, and tells the coding language to ignore everything that follows it.


Providing human-language descriptions of what a code chunk is doing

# Create an object called "numbers" that is carries the values 1-10
numbers <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

# Calculate the mean of the object "numbers"
mean(numbers)
## [1] 5.5

As you can see in the example above, you can use the # to write descriptions of what each chunk of code is doing, so that when others look at your code, or if you look at code that you wrote in the past, you can easily understand what each chunk is doing. This is an integral part of literate coding and reproducibility, and something that is practiced across all coding languages and domains.


Object naming

Looking again at the script that you’ve created, there are a lot of objects with single letters as names (w, x, y, z). While using letters as object names isn’t a problem when running small tests in practice scripts, it can get very confusing when you start working on bigger projects and have multiple objects to sift through. A much better approach, and one that is similar to file naming that we discussed in a previous session, is to give your objects short but meaningful names so that you and others can easily make sense of the objects that you’ve created.

Much like file naming, the following parameters apply:

  • Only use letters in the English alphabet, number 0-9, dashes -, and underscores _
  • Do not use spaces or special characters such as: ~!@#$%^&*()+=…
  • Separate naming elements with dashes - and underscores _

Clean up!

Now that we’ve established some best practices in literate programming, go through the script that you have current created, and utilizing commented code and object naming, try to make it easily interpretable and reusuable for others!

Save Your Work

You can save your script by selecting file > save or by clicking the flopping disk icon in the top navigation pane.

Name your script my-first-script.R.


Backup to OSF

At the end of each work session, remember to save your data as .RData and .csv, and also your RMarkdown file (.Rmd). We will upload those files to OSF.

Let’s now go to the DMP Assistant and updated the following questions:

  • Section 1: Data Collection
    • What file formats will your data be collected and saved in? Select all that apply.
    • Describe related tools and software needed to access, manipulate, and analyze the data.
  • Section 4: Preservation
    • Indicate how you will ensure your data is preservation friendly before archiving. Consider preservation-friendly file formats, anonymization and de-identification of human subjects data, long-term file integrity, and inclusion of supporting documentation.


We’ve also added a new script file to our project, and should update our README file to reflect this with a description of the file.

LS0tDQp0aXRsZTogIlNldHRpbmcgdXAgUiINCnBhZ2V0aXRsZTogIlNldHRpbmcgdXAgUiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cgIyBhbGxvd3MgdG9nZ2xpbmcgb2Ygc2hvd2luZyBhbmQgaGlkaW5nIGNvZGUuIFJlbW92ZSBpZiBub3QgdXNpbmcgY29kZS4NCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlICMgYWxsb3dzIHRoZSB1c2VyIHRvIGRvd25sb2FkIHRoZSBzb3VyY2UgLlJtZCBmaWxlLiBSZW1vdmUgaWYgbm90IHVzaW5nIGNvZGUuDQogICAgaW5jbHVkZXM6DQogICAgICBhZnRlcl9ib2R5OiBmb290ZXIuaHRtbCAjIGluY2x1ZGUgYSBjdXN0b20gZm9vdGVyLg0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogZmFsc2UNCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlDQotLS0NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZ3MgPSBGQUxTRSkNCmBgYA0KDQojIyBJbnRyb2R1Y3Rpb24gdG8gUg0KDQo6OjppbnRybw0KUlN0dWRpbyBpcyBhIHByb2dyYW0gdGhhdCBoZWxwcyB5b3Ugd3JpdGUgYW5kIHJ1biBSIGNvZGUgbW9yZSBlYXNpbHksIGVzcGVjaWFsbHkgZm9yIHdvcmtpbmcgd2l0aCBkYXRhLCBtYWtpbmcgZ3JhcGhzLCBhbmQgZG9pbmcgc3RhdGlzdGljcy4NCjo6Og0KDQpZb3Ugd2lsbCBoYXZlIGhvcGVmdWxseSBhbHJlYWR5IGRvd25sb2FkZWQgUiBhbmQgUlN0dWRpby4gIElmIG5vdCwgZm9sbG93IHRoZSBpbnN0cnVjdGlvbnMgb24gdGhpcyBwYWdlOiA8YSBocmVmPSJCbG9jazdfRVhULVJSU3R1ZGlvLmh0bWwiPlIgYW5kIFJTdHVkaW8gc2V0dXA8L2E+DQoNCg0KIyMgUlN0dWRpbyBJbnRlcmZhY2UNCg0KV2hlbiB3ZSBsYXVuY2ggUlN0dWRpbyBmb3IgdGhlIGZpcnN0IHRpbWUsIHdlIG5vdGljZSB0aHJlZSBtYWluIHBhbmVscyBvciBxdWFkcmFudHM6IA0KDQohW10oaW1hZ2VzL2RheTJfUlN0dWRpb18zcGFuZWwucG5nKQ0KDQpPbmNlIHdlIG9wZW4gYSBkb2N1bWVudCwgdGhlIGludGVyZmFjZSB3aWxsIHNob3cgZm91ciBtYWluIHBhbmVsczoNCg0KIVtdKGltYWdlcy9kYXkyX1JTdHVkaW9fNHBhbmVsLnBuZykNCg0KIyMjIDEgLSBUb3AgbGVmdCBwYW5lbA0KIyMjIyBGaWxlcyBhbmQgc2NyaXB0cyAoc291cmNlIHdpbmRvdyBvciBjb2RlIGVkaXRvcikNCg0KVGhpcyBpcyB5b3VyIGNvZGUgZWRpdG9yLCB3aGVyZSB5b3Ugd3JpdGUsIHNhdmUsIGFuZCBydW4gUiBzY3JpcHRzICguUiksIFJNYXJrZG93biBkb2N1bWVudHMgKC5SbWQpLCBvciBvdGhlciBmaWxlIHR5cGVzLg0KDQojIyMgMiAtIEJvdHRvbSBsZWZ0IHBhbmVsDQojIyMjIFIgY29uc29sZSBhbmQgdGVybWluYWwNCg0KVGhpcyBpcyB0aGUgaW50ZXJhY3RpdmUgUiBjb25zb2xlLCB3aGVyZSBjb2RlIGlzIGV4ZWN1dGVkIGltbWVkaWF0ZWx5LiBZb3UgY2FuOg0KDQogLSBUeXBlIGFuZCBydW4gY29tbWFuZHMgaW50ZXJhY3RpdmVseSAoZ3JlYXQgZm9yIHRlc3Rpbmcgc21hbGwgYml0cyBvZiBjb2RlKS4NCiAtIFZpZXcgb3V0cHV0cywgZXJyb3IgbWVzc2FnZXMsIGFuZCB3YXJuaW5ncyBpbiByZWFsIHRpbWUuDQogLSBTd2l0Y2ggdG8gdGhlIFRlcm1pbmFsIHRhYiBmb3Igc3lzdGVtLWxldmVsIGNvbW1hbmRzLg0KDQojIyMgMyAtIFRvcCByaWdodCBwYW5lbA0KIyMjIyBPYmplY3RzLCBoaXN0b3J5LCBlbnZpcm9ubWVudCwgdHV0b3JpYWwgYW5kIGNvbm5lY3Rpb25zDQoNClRoaXMgYXJlYSBsZXRzIHlvdSB0cmFjayB3aGF04oCZcyBoYXBwZW5pbmcgaW4geW91ciBSIHNlc3Npb24uDQoNCkl0IGhhcyBkaWZmZXJlbnQgdGFicyBmb3IgZGlmZmVyZW50IGFjdGlvbnM6IA0KDQogLSAqKkVudmlyb25tZW50OioqIFNlZSBhbGwgb2JqZWN0cyAobGlrZSBkYXRhIGZyYW1lcywgZnVuY3Rpb25zLCB2YXJpYWJsZXMpIGN1cnJlbnRseSBpbiBtZW1vcnkuDQogLSAqKkhpc3Rvcnk6KiogVmlldyBhbGwgY29tbWFuZHMgeW914oCZdmUgcHJldmlvdXNseSBydW4uDQogLSAqKkNvbm5lY3Rpb25zOioqIE1hbmFnZSBkYXRhYmFzZSBjb25uZWN0aW9ucy4NCiAtICoqVHV0b3JpYWw6KiogVmlldyBidWlsdC1pbiBpbnRlcmFjdGl2ZSB0dXRvcmlhbHMgKGZyb20gdGhlIGxlYXJuciBwYWNrYWdlKS4NCg0KIyMjIDQgLSBCb3R0b20gcmlnaHQgcGFuZWwNCiMjIyMgVHJlZSBvZiBmb2xkZXJzLCBwbG90cywgcGFja2FnZXMsIGhlbHAsIHZpZXdlcg0KDQpUaGlzIHBhbmVsIGNvbnRhaW5zIHZhcmlvdXMgdG9vbHMgYW5kIG91dHB1dHM6DQoNCiAtICoqRmlsZXM6KiogTmF2aWdhdGUgeW91ciBmb2xkZXIgc3RydWN0dXJlIGFuZCBvcGVuIHNjcmlwdHMuDQogLSAqKlBsb3RzOioqIFZpZXcgdmlzdWFsaXphdGlvbnMgZ2VuZXJhdGVkIGJ5IHlvdXIgY29kZS4NCiAtICoqUGFja2FnZXM6KiogSW5zdGFsbCwgbG9hZCwgb3IgdXBkYXRlIFIgcGFja2FnZXMuDQogLSAqKkhlbHA6KiogU2VhcmNoIFIgZG9jdW1lbnRhdGlvbiAoYD9mdW5jdGlvbl9uYW1lYCBzaG93cyBoZXJlKS4NCiAtICoqVmlld2VyOioqIFZpZXcgSFRNTCBjb250ZW50LCBsaWtlIFIgTWFya2Rvd24gb3V0cHV0cyBvciBTaGlueSBhcHBzLg0KDQoNCiMjIEVhc2luZyBJbnRvIFINCg0KIyMjIFIgYXMgYSBDYWxjdWxhdG9yDQoNCkEgZ29vZCBzdGFydGluZyBwbGFjZSBmb3IgbGVhcm5pbmcgUiBpcyB1dGlsaXppbmcgb25lIG9mIGl0cyBtb3N0IGJhc2ljIGZ1bmN0aW9ucywgd2hpY2ggaXMgdGhhdCBvZiBhIGNhbGN1bGF0b3IuICBBcyBtZW50aW9uZWQgYWJvdmUsIHRoZXJlIGFyZSBmb3VyIHBhbmVscyB3aXRoaW4gUlN0dWRpbywgYW5kIHRvIGJlZ2luLCBsZXQncyBsb29rIGF0IGhvdyB0aGlzIHdvcmtzIGluIHRoZSBSIENvbnNvbGUgKGJvdHRvbSBsZWZ0IHBhbmVsKS4NCg0KPGJyPg0KDQojIyMjIEFkZGluZyBOdW1iZXJzDQpZb3UgY2FuIGFkZCBudW1iZXJzIHVzaW5nIHRoZSBwbHVzIHNpZ24gYCtgOg0KYGBge3IsIHJlc3VsdHMgPSBGQUxTRX0NCjIgKyAyDQpgYGANCg0KPGJyPg0KDQojIyMjIFN1YnRyYWN0aW5nIE51bWJlcnMNCllvdSBjYW4gc3VidHJhY3QgbnVtYmVycyB1c2luZyBhIGh5cGhlbiBgLWA6DQpgYGB7ciwgcmVzdWx0cyA9IEZBTFNFfQ0KMTAgLSA0DQpgYGANCg0KPGJyPg0KDQojIyMjIERpdmlkaW5nIE51bWJlcnMNCllvdSBjYW4gZGl2aWRlIG51bWJlcnMgdXNpbmcgYSBzbGFzaCBgL2A6DQpgYGB7ciwgcmVzdWx0cyA9IEZBTFNFfQ0KMjAvNA0KYGBgDQoNCjxicj4NCg0KIyMjIyBNdWx0aXBseWluZyBOdW1iZXJzDQpZb3UgY2FuIG11bHRpcGx5IG51bWJlcnMgdXNpbmcgdGhlIHN0YXIgYCpgOg0KYGBge3IsIHJlc3VsdHMgPSBGQUxTRX0NCjEwICogMTANCmBgYA0KDQo8YnI+DQoNCjo6Om5vdGUNCg0KKipBIHF1aWNrIG5vdGUgb24gdGhlIFIgY29uc29sZSoqDQoNCkFzIHlvdSBjYW4gc2VlIGZyb20gdGhlIGFjdGlvbnMgYWJvdmUsIHRoZSBSIGNvbnNvbGUgY2FuIGJlIHVzZWQgYXMgYSBwbGFjZSB0byB0eXBlIHZlcnkgc21hbGwgY2FsY3VsYXRpb25zIG9yIGFjdGlvbnMuICBIb3dldmVyLCBhIGJpZyBkcmF3IGJhY2sgb2YgdXNpbmcgdGhlIGNvbnNvbGUgaXMgdGhhdCB5b3UgY2FuJ3Qgc2F2ZSB0aGUgY2FsY3VsYXRpb25zIHRoYXQgeW91IGFyZSBjcmVhdGluZywgYW5kIHRoZXJlIGlzIG5vIHdheSB0byBhZGQgY29tbWVudHMgdG8geW91ciBjb2RlLiAgVGhpcyBpcyB3aHkgd2UgdXNlIFIgc2NyaXB0IGZpbGVzLCBhcyB0aGV5IGFsbG93IHVzIHRvIGtlZXAgdHJhY2sgb2YgZXZlcnl0aGluZyB0aGF0IHdlJ3JlIGRvaW5nIGluIFIgd2l0aCBzdWZmaWNpZW50IGRvY3VtZW50YXRpb24gZm9yIG90aGVycyAoYW5kIHlvdXJzZWxmISkgdG8gaW50ZXJwcmV0Lg0KDQo6OjoNCg0KIyMgVHlwZXMgb2YgZmlsZXMgaW4gUg0KDQpUaGVyZSBhcmUgdHdvIG1haW4gdHlwZXMgb2YgZmlsZXMgd2UgY2FuIGNyZWF0ZSBpbiBSIHN0dWRpbyB0byBlZGl0IG91ciBjb2RlIChSIHNjcmlwdCBmaWxlcyBgLlJgIGFuZCBSTWFya2Rvd24gZmlsZXMgYC5SbWRgKQ0KDQpUaGUgUiBzY3JpcHQgZmlsZSAoYC5SYCkgaXMgYSBwbGFpbiB0ZXh0IGZpbGUgdGhhdCBjb250YWlucyBSIGNvZGUgb25seS4gVXNlIGl0IHdoZW4geW91IHdhbnQgdG8gd3JpdGUgYW5kIHJ1biBjb2RlIGxpbmUtYnktbGluZSwgc3VjaCBhcyBmb3IgZGF0YSBjbGVhbmluZywgYW5hbHlzaXMsIG9yIGZ1bmN0aW9uIGJ1aWxkaW5nLiBJdCdzIGdvb2QgZm9yIGV4cGVyaW1lbnRpbmcsIHNjcmlwdGluZywgYW5kIHJ1bm5pbmcgY29kZSBpbnRlcmFjdGl2ZWx5LiBJdCdzIGFsc28gZ29vZCBmb3Igc2hhcmluZyBjb2RlIHdpdGggb3RoZXIgcmVzZWFyY2hlcnMuDQoNClRoZSBSTWFya2Rvd24gZmlsZSAoYC5SbWRgKSBoYXMgYSBtaXggb2YgUiBjb2RlIGFuZCB3cml0dGVuIGV4cGxhbmF0aW9ucywgdXNpbmcgTWFya2Rvd24gZm9ybWF0dGluZy4gIEl0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBkeW5hbWljLCByZXByb2R1Y2libGUgcmVwb3J0cyB0aGF0IGNhbiBiZSBrbml0dGVkIGludG8gSFRNTCwgUERGLCBvciBXb3JkIGRvY3VtZW50cy5JdCdzIGdyZWF0IGZvciBob21ld29yaywgcmVzZWFyY2ggcmVwb3J0cywgZGFzaGJvYXJkcywgb3IgY29tYmluaW5nIG5hcnJhdGl2ZSB3aXRoIGNvZGUuDQoNCkZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBwcm9ncmFtIHdlJ2xsIGJlIHVzaW5nIFIgc2NyaXB0cywgYnV0IGlmIHlvdSdyZSBpbnRlcmVzdGVkIGluIGxlYXJuaW5nIG1vcmUgYWJvdXQgUk1hcmtkb3duLCBjaGVjayBvdXQ6DQoNCiogPGEgaHJlZj0iaHR0cHM6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vbGVzc29uLTguaHRtbCI+Uk1hcmtkb3duIGxlc3NvbiBmcm9tIFJTdHVkaW88L2E+DQoqIDxhIGhyZWY9Imh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi8iPlJNYXJrZG93biBkZWZpbml0aXZlIGd1aWRlPC9hPiANCg0KPGJyPg0KDQpUbyBjcmVhdGUgYW4gUiBzY3JpcHQgZmlsZSwgc2VsZWN0IEZpbGUgPiBOZXcgRmlsZSA+IFIgU2NyaXB0DQoNCiFbXShpbWFnZXMvYmxvY2szX2NyZWF0ZS1yLXNjcmlwdC5naWYpDQoNCg0KIyMgWW91ciBUdXJuISANCg0KOjo6cXVlc3Rpb24NCkNyZWF0ZSB5b3VyIGZpcnN0IFIgc2NyaXB0IGZpbGUuIA0KOjo6DQoNCiMjIyBXb3JraW5nIGluIGFuIFIgU2NyaXB0IEZpbGUNCg0KTGV0J3MgbW92ZSB0byB0aGUgUiBzY3JpcHQgZmlsZSB3ZSBoYXZlIGp1c3QgY3JlYXRlZCB0aGF0IGlzIGxvY2F0ZWQgaW4gdGhlIHRvcCBsZWZ0IHBhbmVsLiAgTGV0J3MgZmlyc3QgdHJ5IHRvIHJlLXJ1biBzb21lIG9mIHRoZSBtYXRoZW1hdGljYWwgY2FsY3VsYXRpb25zIHdlIHJhbiBhYm92ZSwgYnV0IHRoaXMgdGltZSBpbiB0aGUgc2NyaXB0Og0KDQpgYGB7ciwgcmVzdWx0cyA9IEZBTFNFfQ0KMiArIDINCjEwIC0gNA0KMjAvNA0KMTAgKiAxMA0KYGBgDQoNCkRpZCBpdCB3b3JrPw0KDQpVbmxlc3MgeW91IGhhdmUgcHJldmlvdXMgZXhwZXJpZW5jZSB3aXRoIFIsIG9yIGluIHlvdSBnb3QgcXVpdGUgY2xldmVyIHdpdGggdXNpbmcgYSBzZWFyY2ggZW5naW5lLCB5b3Ugd2lsbCBoYXZlIG5vdGljZWQgdGhhdCBSIHdvbid0IHNpbXBseSBydW4gY29tbWFuZHMgaW4gYSBzY3JpcHQgd2hlbiB5b3UgcHJlc3MgdGhlIGBlbnRlci9yZXR1cm5gIGJ1dHRvbi4gVGhpcyBpcyBiZWNhdXNlIHRoZSBSIHNjcmlwdCBpcyBhbGxvd2luZyB5b3UgdG8gZnJlZWx5IHR5cGUsIGVkaXQsIGFuZCBhZGp1c3QgeW91ciBjb2RlIGJlZm9yZSBpdCBnb2VzIGFoZWFkIGFuZCBkZXBsb3lzIGl0IChhbm90aGVyIGFkdmFudGFnZSBvdmVyIHVzaW5nIHRoZSBjb25zb2xlKS4gIA0KDQojIyMjIFJ1bm5pbmcgQ29kZSBpbiBhbiBSIFNjcmlwdA0KDQpUaGVyZSBhcmUgYSBmZXcgZGlmZmVyZW50IHdheXMgdGhhdCB5b3UgY2FuIHJ1biBjb2RlIGluIHlvdXIgUiBzY3JpcHQ6DQoNCjEpICoqUG9pbnQtYW5kLWNsaWNrKio6IEluIHRoZSB0b3AgcmlnaHQgb2YgdGhlIFJTdHVkaW8gc2NyZWVuLCB5b3Ugd2lsbCBzZWUgYSBidXR0b24gdGhhdCBzYXlzIGBSdW5gLiAgSWYgeW91IGNsaWNrIG9uIGl0LCBSU3R1ZGlvIHdpbGwgcnVuIHRoZSBsaW5lL2NodW5rIG9mIGNvZGUgd2hlcmUgeW91ciBjdXJzb3IgaXMgbG9jYXRlZC4gIElmIHlvdXIgY3Vyc29yIGlzIGFib3ZlIGEgbGluZSBvZiBjb2RlLCBpdCB3aWxsIHJ1biB0aGUgbGluZSBiZWxvdyBpdCwgYnV0IGlmIHlvdXIgY3Vyc29yIGlzIGJlbG93IHRoZSBjb2RlLCBpdCB3b24ndCBydW4gYW55dGhpbmcuICBZb3UgY2FuIGFsc28gaGlnaGxpZ2h0IG11bHRpcGxlIGxpbmVzIG9mIGNvZGUgYW5kIHByZXNzIGBSdW5gLCBhbmQgdGhleSB3aWxsIGJlIHJ1biBjb25zZWN1dGl2ZWx5IA0KDQohW10oaW1hZ2VzL2Jsb2NrM19ydW4tci1zY3JpcHQuZ2lmKQ0KDQoyKSAqKktleWJvYXJkIGNvbW1hbmRzKio6IFRoZXJlIGFyZSB0d28gbWFpbiB3YXlzIHRoYXQgeW91IGNhbiB1c2Uga2V5Ym9hcmQgY29tbWFuZHMgdG8gY29kZSBpbiBSIHNjcmlwdHM6DQoNCiAgKiBgQ3RybCArIEVudGVyYCAoV2luZG93cykgLyBgQ29tbWFuZCArIFJFVFVSTmAgKE1hYykgLSB3aWxsIHJ1biBhIHNpbmdsZSBsaW5lL2NodW5rIG9mIGNvZGUgdGhhdCB5b3VyIGN1cnNvciBpcyBvbg0KICAqIGBDdHJsICsgU2hpZnQgKyBFbnRlcmAgKFdpbmRvdykgLyBgQ29tbWFuZCArIFNoaWZ0ICsgUmV0dXJuYCAoTWFjKSAtIHdpbGwgcnVuIGFsbCB0aGUgY29kZSBpbiB5b3VyIFIgc2NyaXB0LCBiZWdpbm5pbmcgYXQgdGhlIHRvcC4NCiAgDQpHaXZlIHRoZXNlIGJvdGggYSB0cnkgd2l0aCB0aGUgY2FsY3VsYXRpb25zIGFib3ZlLCBhbmQgc3RhcnQgY29uc2lkZXJpbmcgaG93IHlvdSBtaWdodCB1c2UgdGhlc2UgYXMgeW91IG1vdmUgdGhyb3VnaCB5b3VyIGpvdXJuZXkgaW4gbGVhcm5pbmcgUiENCg0KDQojIyMgQmFzaWMgU3ludGF4IG9mIFINCg0KVGhlIG1vc3QgaW1wb3J0YW50IGNvbXBvbmVudHMgb2YgYW4gUiBzY3JpcHQgYXJlICoqb2JqZWN0cyoqIGFuZCAqKmZ1bmN0aW9ucyoqLiBPYmplY3RzIHN0b3JlIGluZm9ybWF0aW9uIGFuZCBmdW5jdGlvbnMgYXJlIHVzZWQgdG8gbWFuaXB1bGF0ZSB0aGUgZGF0YS4gDQoNCioqQXNzaWdubWVudCBvcGVyYXRvcnMqKiwgKipwaXBlcyoqIGFuZCAqKmFyZ3VtZW50cyoqIGFyZSB1c2VkIHRvIGxpbmsgb2JqZWN0cyBhbmQgZnVuY3Rpb25zIGFuZCBjb21tdW5pY2F0ZSB3aGF0IHdlIHdhbnQgdG8gZG8uDQoNCiFbXShpbWFnZXMvZGF5Ml9SU3ludGF4LnBuZykNCg0KDQo8YnI+DQoNCkl0IHNob3VsZCBiZSBub3RlZCB0aGF0IHRoaXMgZGlhZ3JhbSByZXByZXNlbnRzIHRoZSBmdWxsIHN5bnRheCBvZiBhbiBSIGNvZGUgc25pcHBldCwgd2hpY2ggaXMgdGhlIGh1bWFuIGxhbmd1YWdlIGVxdWl2YWxlbnQgb2YgYSBzZW50ZW5jZS4gIE11Y2ggbGlrZSBsZWFybmluZyBhIGh1bWFuIGxhbmd1YWdlLCB3ZSdyZSBnb2luZyB0byBzdGFydCBvZmYgYnkgbGVhcm5pbmcgYWJvdXQgaW5kaXZpZHVhbCB3b3JkcyBhbmQgcGFydHMgb2Ygc3BlZWNoIGJlZm9yZSB3ZSBqdW1wIGludG8gc2VudGVuY2VzICh3aXRoIHBhcmFncmFwaHMgYmVpbmcgdGhlIG1vcmUgYWR2YW5jZWQgbmV4dCBzdGVwKS4gIA0KDQpMZXQncyBzdGFydCBieSBicmVha2luZyBkb3duIGVhY2ggb25lIG9mIHRoZXNlIGNvbXBvbmVudHM6DQoNCiMjIyMgT2JqZWN0cyAmIEFzc2lnbm1lbnQgT3BlcmF0b3JzDQoNCkFuICoqb2JqZWN0KiogaXMgYW55dGhpbmcgeW91IGNyZWF0ZSBhbmQgbmFtZSBpbiBSLiBJdCBjYW4gYmUgYSBudW1iZXIsIGEgZGF0YXNldCwgYSBmdW5jdGlvbiwgb3IgZXZlbiBhIHBsb3QuIE9iamVjdHMgdGFrZSBvbiBjb250ZW50IGZyb20gZXZlcnl0aGluZyB0byB0aGUgcmlnaHQgb2YgdGhlIGFzc2lnbm1lbnQgb3BlcmF0b3IuIA0KDQpBbiAqKmFzc2lnbm1lbnQgb3BlcmF0b3IqKiBpcyBob3cgeW91IHN0b3JlIGEgdmFsdWUgaW4gUi4gSXTigJlzIGxpa2Ugc2F5aW5nOiDigJxMZXQgdGhpcyBuYW1lIGhvbGQgdGhpcyB2YWx1ZS7igJ0gSXQgYXNzaWducyBjb250ZW50IGZyb20gdGhlIG9iamVjdHMvZnVuY3Rpb25zL2FyZ3VtZW50cyBvbiBpdHMgcmlnaHQgdG8gdGhlIG9iamVjdCBvbiBpdHMgbGVmdC4NCg0KYGBge3J9DQphIDwtIDUgIyB4IGlzIG5vdyBhbiBvYmplY3QgdGhhdCBob2xkcyB0aGUgdmFsdWUgNQ0KYiA8LSAiQW5uYSIgIyBiIGlzIG5vdyBhbiBvYmplY3QgdGhhdCBob2xkcyB0aGUgY2hhcmFjdGVyIEFubmENCmBgYA0KDQoqKk5vdGUqKg0KDQoqIFNpbmNlIEFubmEgaXMgYSBzZXJpZXMgb2YgY2hhcmFjdGVycyAoYXMgb3Bwb3NlZCB0byBudW1iZXJzKSwgaXQgbmVlZHMgdG8gYmUgd3JhcHBlZCBpbiBxdW90YXRpb25zICh3ZSdsbCBsZWFybiBtb3JlIGFib3V0IGRhdGEgdHlwZXMgaW4gdGhlIG5leHQgc2Vzc2lvbikuDQoNCllvdSBjYW4gb3ZlcndyaXRlIGEgbmV3IHZhbHVlIHRvIHRoZSBzYW1lIG9iamVjdCBuYW1lLiAgV2hlbiB5b3UgZG8gdGhpcywgdGhlIG9yaWdpbmFsIHZhbHVlIGlzIHJlcGxhY2VkIGJ5IHRoZSBuZXcgdmFsdWUgeW91IGFzc2lnbiB0byBpdC4NCg0KYGBge3J9DQpuYW1lIDwtICJNYXJpYSIgIyBUaGUgIm5hbWUiIG9iamVjdCBub3cgaG9sZHMgdGhlIHZhbHVlICJNYXJpYSINCg0KbmFtZSA8LSAiQW5uYSIgIyBUaGUgIm5hbWUiIG9iamVjdCBub3cgaG9sZHMgdGhlIHZhbHVlICJBbm5hIiwgYW5kIG5vIGxvbmdlciBoYXMgdGhlIHZhbHVlICJNYXJpYSIuDQpgYGANCg0KKipXaHkgb3ZlcndyaXRpbmcgaXMgdXNlZnVsKioNCg0KKiBBcyB5b3VyIGFuYWx5c2lzIGJlY29tZXMgbW9yZSBjb21wbGljYXRlZCwgeW91IG9mdGVuIGJ1aWxkIHlvdXIgcmVzdWx0cyBzdGVwLWJ5LXN0ZXAuDQogDQoqIEluc3RlYWQgb2YgY3JlYXRpbmcgZG96ZW5zIG9mIGRpZmZlcmVudCBvYmplY3QgbmFtZXMsIHlvdSBjYW4gcmV1c2UgdGhlIHNhbWUgb2JqZWN0IG5hbWUgdG8gc3RvcmUgdXBkYXRlZCB2ZXJzaW9ucyBvZiB5b3VyIGRhdGEgb3IgcmVzdWx0cy4NCiANCiogVGhpcyBrZWVwcyB5b3VyIGVudmlyb25tZW50IGNsZWFuIGFuZCB5b3VyIGNvZGUgZWFzaWVyIHRvIHJlYWQuDQoNCjxicj4NCg0KT2JqZWN0cyBjYW4gYWxzbyBiZSBhc3NpZ25lZCBzZXZlcmFsIHZhbHVlcy4gIFRoaXMgaXMgZG9uZSBieSB1c2luZyB0aGUgYGMoKWAgY29tbWFuZCwgd2hpY2ggc3RhbmRzIGZvciBjb25jYXRlbmF0ZSwgYW5kIHdoZXJlIHRoZSBzdHJpbmdzIG9mIHZhbHVlcyBnbyBpbnRvIHRoZSBicmFja2V0cy4gIFlvdSBjYW4gdGhpbmsgb2YgdGhpcyBmdW5jdGlvbiBhcyAiZ2x1ZWluZyIgZWxlbWVudHMgdG9nZXRoZXIgaW50byBvbmUgZ3JvdXAuICBJdCBjYW4gYmUgdXNlZCBsaWtlIHRoaXM6DQoNCmBgYHtyfQ0KbnVtYmVycyA8LSBjKDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwKQ0KDQpzcG9ydHMgPC0gYygiQmFza2V0YmFsbCIsICJHb2xmIiwgIlNvY2NlciIsICJUZW5uaXMiKQ0KYGBgDQoNCjo6Om5vdGUNCg0KWW91J2xsIG5vdGljZSB0aGF0IHRoZSB3b3JkIHN0cmluZ3MsIG9yIHN0cmluZ3Mgb2YgY2hhcmFjdGVycywgYXJlIHN1cnJvdW5kZWQgYnkgcXVvdGF0aW9uIG1hcmtzIGAiImAuICBUaGlzIGlzIGJlY2F1c2UgUiwgYW5kIG1vc3QgY29kaW5nIGxhbmd1YWdlcywgaGFuZGxlIGNoYXJhY3RlciBzdHJpbmdzIHVuaXF1ZWx5LCBhbmQgcmVxdWlyZSBxdW90YXRpb25zIHRvIHN1cnJvdW5kIHdvcmRzIGFuZCBwaHJhc2VzLiBXZSdsbCBjb3ZlciB0aGlzIG1vcmUgaW4gdGhlIG5leHQgc2VjdGlvbiwgYnV0IGZvciBub3csIGp1c3Qga25vdyB0aGF0IGV2ZXJ5IHRpbWUgeW91IHdhbnQgdG8gdXNlIGEgY2hhcmFjdGVyIHN0cmluZyBhcyBhIHZhbHVlIGluIFIsIHlvdSBuZWVkIHRvIHVzZSBxdW90YXRpb24gbWFya3MuDQoNCjo6Og0KDQo6OjpxdWVzdGlvbg0KDQpUZXN0IHlvdXJzZWxmIQ0KDQoxKSBDcmVhdGUgYW4gb2JqZWN0IGNhbGxlZCBgd2AsIGFuZCBhc3NpZ24gaXQgYSB2YWx1ZSBvZiBgMTAwYC4NCjIpIENyZWF0ZSBhbiBvYmplY3QgY2FsbGVkIGB4YCwgYW5kIGFzc2lnbiBpdCBhIHZhbHVlIG9mIGAyNWAuDQozKSBDcmVhdGUgYW4gb2JqZWN0IGNhbGxlZCBgeWAsIGFuZCBhc3NpZ24gaXQgdGhlIHZhbHVlIG9mIGBiYXNrZXRiYWxsYC4NCjQpIENyZWF0ZSBhbiBvYmplY3QgY2FsbGVkIGB6YCwgYW5kIGFzc2lnbiBpdCB0aGUgdmFsdWUgb2YgYGJhc2ViYWxsYC4NCg0KSWYgdGhpcyBhbGwgd29ya2VkLCB5b3Ugd2lsbCBzZWUgaW4gdGhlIHRvcC1yaWdodCBgRW52aXJvbm1lbnRgIHBhbmUgdGhlIGZvdXIgbmV3IHZhbHVlcyB0aGF0IHlvdSBoYXZlIGNyZWF0ZWQuDQoNCkxldCdzIGtlZXAgcGxheWluZzoNCg0KNSkgVXNlIHRoZSBhZGRpdGlvbmFsIHN5bWJvbCBgK2AgdG8gYWRkIGB3YCBhbmQgYHhgLg0KNikgVXNlIHRoZSBkaXZpc2lvbiBzeW1ib2wgYC9gIHRvIGRpdmlkZSBgd2AgYnkgYHhgLg0KNykgUmUtd3JpdGUgb2JqZWN0cyBgd2AgYW5kIGB4YCB0byBnaXZlIHRoZW0gbmV3IHZhbHVlcyBvZiB5b3VyIGNob29zaW5nLg0KOCkgVXNlIHRoZSBhZGRpdGlvbmFsIHN5bWJvbCBgK2AgdG8gYWRkIGB5YCBhbmQgYHpgLiAgRGlkIGl0IHdvcms/ICBJZiBub3QsIHdoYXQgZG8geW91IHRoaW5rIG1pZ2h0IGhhdmUgaGFwcGVuZWQ/DQo5KSBUcnkgY3JlYXRpbmcgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgbXVsdGlwbGUgdmFsdWVzLg0KDQoqKkFuc3dlcnMqKg0KDQpgYGB7ciBjbGFzcy5zb3VyY2UgPSAnZm9sZC1oaWRlJ30NCg0KIyAxKSB3IDwtIDEwMA0KIyAyKSB4IDwtIDI1DQojIDMpIHkgPC0gImJhc2tldGJhbGwiDQojIDQpIHogPC0gImJhc2ViYWxsIg0KIyA1KSB3ICsgeA0KIyA2KSB3L3gNCiMgNykgRXg6IHcgPC0gNTAwIA0KIyAgICAgICB4IDwtIDkwMDANCiMgOCkgVGhpcyBzaG91bGQgc2hvdyBhbiBlcnJvciBsaWtlIHRoZSBmb2xsb3dpbmc6ICJFcnJvciBpbiB5ICsgeiA6IG5vbi1udW1lcmljIGFyZ3VtZW50IHRvIGJpbmFyeSBvcGVyYXRvciIuICBUaGlzIGlzIGJlY2F1c2UgUiB3aWxsIG9ubHkgbGV0IHlvdSBhZGQgbnVtZXJpY2FsIHZhbHVlcyB0b2dldGhlciwgYW5kIG5vdCBjaGFyYWN0ZXIgdmFsdWVzLiAgVGhpcyB3aWxsIGJlIGNvdmVyZWQgaW4gbW9yZSBkZXRhaWwgaW4gdGhlIG5leHQgc2VjdGlvbi4NCiMgOSkgRXg6IG1vdmllcyA8LSBjKCJQdWxwIEZpY3Rpb24iLCAiTG9yZCBvZiB0aGUgUmluZ3M6IFRoZSBGZWxsb3dzaGlwIG9mIHRoZSBSaW5nIiwgIkhpZ2hsYW5kZXIiKQ0KDQpgYGANCjo6Og0KDQojIyMjIEZ1bmN0aW9ucyAmIEFyZ3VtZW50cw0KDQpGdW5jdGlvbnMgYXJlIG11Y2ggbGlrZSB2ZXJicyBpbiBhIGxhbmd1YWdlLCBhcyB0aGV5IGNvbnZleSBzb21lIHNvcnQgb2YgYWN0aW9uIHRvIGJlIHBlcmZvcm1lZC4gIFRoZXNlIGFyZSBvZnRlbiAodGhvdWdoIG5vdCBhbHdheXMpIGFjdGlvbnMgdG8gYmUgcGVyZm9ybWVkIG9uIGFuIGFyZ3VtZW50LiBXZSdyZSBnb2luZyB0byBsZWFybiBtb3JlIGFib3V0IGZ1bmN0aW9ucyBpbiB0aGUgbmV4dCBzZWN0aW9uLCBidXQgaGVyZSBhcmUgYSBjb3VwbGUgYmFzaWMgZnVuY3Rpb25zIHRvIHNob3cgeW91IGhvdyB0aGV5IHdvcmsuDQoNCmBgYHtyfQ0KbnVtYmVycyA8LSBjKDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwKQ0KDQptZWFuKG51bWJlcnMpDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYG1lYW5gIGZ1bmN0aW9uIGlzIGFwcGxpZWQgdG8gdGhlIGBudW1iZXJzYCBvYmplY3QgKHdoaWNoIGluIHRoaXMgY2FzZSBpcyB0aGUgYGFyZ3VtZW50YCksIGFuZCBnaXZlcyB0aGUgbWVhbiBmb3IgdGhlIHNlcmllcyBvZiBudW1iZXJzLiAgRm9yIHRoZSBzYWtlIG9mIHRoaXMgc2Vzc2lvbiB3ZSdyZSBub3QgZ29pbmcgdG8gc3BlbmQgdG9vIG11Y2ggdGltZSBvbiBmdW5jdGlvbnMsIGJ1dCB0aGV5IHdpbGwgYmUgZGlzY3Vzc2VkIGluIG1vcmUgZGV0YWlsIG5leHQgc2Vzc2lvbiBhcyB3ZSBzdGFydCBnZXR0aW5nIGRlZXBlciBpbnRvIHRoZSB3ZWVkcyBvZiBSLg0KDQo8YnI+DQoNCg0KIyMjIExpdGVyYXRlIENvZGluZw0KDQpUaGUgY29uY2VwdCBvZiBsaXRlcmF0ZSBjb2Rpbmcgd2FzIGludHJvZHVjZWQgaW4gYW4gZWFybGllciBzZXNzaW9uIGFzIGEgZnJhbWV3b3JrIHRoYXQgcHJvdmlkZXMgYSBodW1hbi1sYW5ndWFnZSBleHBsYW5hdGlvbiBvZiBob3cgYSBzY3JpcHQgd29ya3Mgc28gdGhhdCBwZW9wbGUgY2FuIGFjY3VyYXRlbHkgaW50ZXJwcmV0IGFuZCByZXVzZSB0aGUgc2NyaXB0LiAgSWYgeW91IGxvb2sgYXQgdGhlIHNjcmlwdCB0aGF0IHlvdSd2ZSBjdXJyZW50bHkgZ290LCBpdCdzIHF1aXRlIG1lc3N5IGFuZCBkaWZmaWN1bHQgdG8gaW50ZXJwcmV0ISAgVGhpcyBpc24ndCBhIGh1Z2UgaXNzdWUgYmVjYXVzZSB0aGlzIGlzIG9ubHkgYSBwcmFjdGljZSBzY3JpcHQsIGJ1dCBpdCdzIGdvb2QgdG8gc3RhcnQgZGV2ZWxvcGluZyBnb29kIHByYWN0aWNlcyByaWdodCBhdCB0aGUgc3RhcnQsIHNvIGFzIHlvdSBjb250aW51ZSBvbiB5b3VyIHNjcmlwdGluZyBqb3VybmV5LCB0aGVzZSBwcmluY2lwbGVzIGJlY29tZSBzZWNvbmQgbmF0dXJlLiAgVGhlcmUgYXJlIHR3byBwcmltYXJ5IHdheXMgd2UgY2FuIHN0YXJ0IHRvIHN1cHBvcnQgbGl0ZXJhdGUgcHJvZ3JhbW1pbmc6ICoqY29tbWVudGVkIGNvZGUqKiBhbmQgKipvYmplY3QgbmFtaW5nKiouDQoNCg0KIyMjIENvbW1lbnRlZCBDb2RlDQoNCllvdSBtYXkgaGF2ZSBub3RpY2VkIHRoYXQgaW4gc29tZSBvZiB0aGUgZXhhbXBsZSBjb2RlIGJsb2NrcyBiZWxvdywgdGhlcmUgaXMgYSBgI2AgdXNlZCBvY2Nhc2lvbmFsbHkgYmVmb3JlIHRleHQgYmxvY2tzLiAgVGhpcyBgI2AgaXMgYSB2ZXJ5IHZhbHVhYmxlIHRvb2wgaW4gYWxsIGNvZGluZyBsYW5ndWFnZXMsIGFuZCB0ZWxscyB0aGUgY29kaW5nIGxhbmd1YWdlIHRvIGlnbm9yZSBldmVyeXRoaW5nIHRoYXQgZm9sbG93cyBpdC4gDQoNCjxicj4NCg0KIyMjIyBQcm92aWRpbmcgaHVtYW4tbGFuZ3VhZ2UgZGVzY3JpcHRpb25zIG9mIHdoYXQgYSBjb2RlIGNodW5rIGlzIGRvaW5nDQoNCmBgYHtyfQ0KIyBDcmVhdGUgYW4gb2JqZWN0IGNhbGxlZCAibnVtYmVycyIgdGhhdCBpcyBjYXJyaWVzIHRoZSB2YWx1ZXMgMS0xMA0KbnVtYmVycyA8LSBjKDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwKQ0KDQojIENhbGN1bGF0ZSB0aGUgbWVhbiBvZiB0aGUgb2JqZWN0ICJudW1iZXJzIg0KbWVhbihudW1iZXJzKQ0KYGBgDQoNCkFzIHlvdSBjYW4gc2VlIGluIHRoZSBleGFtcGxlIGFib3ZlLCB5b3UgY2FuIHVzZSB0aGUgYCNgIHRvIHdyaXRlIGRlc2NyaXB0aW9ucyBvZiB3aGF0IGVhY2ggY2h1bmsgb2YgY29kZSBpcyBkb2luZywgc28gdGhhdCB3aGVuIG90aGVycyBsb29rIGF0IHlvdXIgY29kZSwgb3IgaWYgeW91IGxvb2sgYXQgY29kZSB0aGF0IHlvdSB3cm90ZSBpbiB0aGUgcGFzdCwgeW91IGNhbiBlYXNpbHkgdW5kZXJzdGFuZCB3aGF0IGVhY2ggY2h1bmsgaXMgZG9pbmcuICBUaGlzIGlzIGFuIGludGVncmFsIHBhcnQgb2YgbGl0ZXJhdGUgY29kaW5nIGFuZCByZXByb2R1Y2liaWxpdHksIGFuZCBzb21ldGhpbmcgdGhhdCBpcyBwcmFjdGljZWQgYWNyb3NzIGFsbCBjb2RpbmcgbGFuZ3VhZ2VzIGFuZCBkb21haW5zLg0KDQo8YnI+DQoNCiMjIyMgT2JqZWN0IG5hbWluZw0KDQpMb29raW5nIGFnYWluIGF0IHRoZSBzY3JpcHQgdGhhdCB5b3UndmUgY3JlYXRlZCwgdGhlcmUgYXJlIGEgbG90IG9mIG9iamVjdHMgd2l0aCBzaW5nbGUgbGV0dGVycyBhcyBuYW1lcyAoYHdgLCBgeGAsIGB5YCwgYHpgKS4gIFdoaWxlIHVzaW5nIGxldHRlcnMgYXMgb2JqZWN0IG5hbWVzIGlzbid0IGEgcHJvYmxlbSB3aGVuIHJ1bm5pbmcgc21hbGwgdGVzdHMgaW4gcHJhY3RpY2Ugc2NyaXB0cywgaXQgY2FuIGdldCB2ZXJ5IGNvbmZ1c2luZyB3aGVuIHlvdSBzdGFydCB3b3JraW5nIG9uIGJpZ2dlciBwcm9qZWN0cyBhbmQgaGF2ZSBtdWx0aXBsZSBvYmplY3RzIHRvIHNpZnQgdGhyb3VnaC4gIEEgbXVjaCBiZXR0ZXIgYXBwcm9hY2gsIGFuZCBvbmUgdGhhdCBpcyBzaW1pbGFyIHRvIGZpbGUgbmFtaW5nIHRoYXQgd2UgZGlzY3Vzc2VkIGluIGEgcHJldmlvdXMgc2Vzc2lvbiwgaXMgdG8gZ2l2ZSB5b3VyIG9iamVjdHMgc2hvcnQgYnV0IG1lYW5pbmdmdWwgbmFtZXMgc28gdGhhdCB5b3UgYW5kIG90aGVycyBjYW4gZWFzaWx5IG1ha2Ugc2Vuc2Ugb2YgdGhlIG9iamVjdHMgdGhhdCB5b3UndmUgY3JlYXRlZC4NCg0KTXVjaCBsaWtlIGZpbGUgbmFtaW5nLCB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnMgYXBwbHk6DQoNCiogT25seSB1c2UgbGV0dGVycyBpbiB0aGUgRW5nbGlzaCBhbHBoYWJldCwgbnVtYmVyIDAtOSwgZGFzaGVzIC0sIGFuZCB1bmRlcnNjb3JlcyBfDQoqIERvIG5vdCB1c2Ugc3BhY2VzIG9yIHNwZWNpYWwgY2hhcmFjdGVycyBzdWNoIGFzOiB+IUAjJCVeJiooKSs9Li4uDQoqIFNlcGFyYXRlIG5hbWluZyBlbGVtZW50cyB3aXRoIGRhc2hlcyAtIGFuZCB1bmRlcnNjb3JlcyBfDQoNCg0KDQojIyMgQ2xlYW4gdXAhIA0KDQo6OjpxdWVzdGlvbg0KDQpOb3cgdGhhdCB3ZSd2ZSBlc3RhYmxpc2hlZCBzb21lIGJlc3QgcHJhY3RpY2VzIGluIGxpdGVyYXRlIHByb2dyYW1taW5nLCBnbyB0aHJvdWdoIHRoZSBzY3JpcHQgdGhhdCB5b3UgaGF2ZSBjdXJyZW50IGNyZWF0ZWQsIGFuZCB1dGlsaXppbmcgY29tbWVudGVkIGNvZGUgYW5kIG9iamVjdCBuYW1pbmcsIHRyeSB0byBtYWtlIGl0IGVhc2lseSBpbnRlcnByZXRhYmxlIGFuZCByZXVzdWFibGUgZm9yIG90aGVycyENCg0KOjo6DQoNCiMjIFNhdmUgWW91ciBXb3JrDQoNCllvdSBjYW4gc2F2ZSB5b3VyIHNjcmlwdCBieSBzZWxlY3RpbmcgYGZpbGUgPiBzYXZlYCBvciBieSBjbGlja2luZyB0aGUgZmxvcHBpbmcgZGlzayBpY29uIGluIHRoZSB0b3AgbmF2aWdhdGlvbiBwYW5lLg0KDQpOYW1lIHlvdXIgc2NyaXB0IGBteS1maXJzdC1zY3JpcHQuUmAuDQoNCjxicj4NCg0KIyMgQmFja3VwIHRvIE9TRg0KDQpBdCB0aGUgZW5kIG9mIGVhY2ggd29yayBzZXNzaW9uLCByZW1lbWJlciB0byBzYXZlIHlvdXIgZGF0YSBhcyAuUkRhdGEgYW5kIC5jc3YsIGFuZCBhbHNvIHlvdXIgUk1hcmtkb3duIGZpbGUgKC5SbWQpLiBXZSB3aWxsIHVwbG9hZCB0aG9zZSBmaWxlcyB0byBPU0YuDQoNCiFbXShpbWFnZXMvb3NmL29zZlVwbG9hZC5naWYpDQoNCjo6OnF1ZXN0aW9uDQoNCkxldCdzIG5vdyBnbyB0byB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9kbXAtcGdkLmNhLyI+RE1QIEFzc2lzdGFudDwvYT4gYW5kIHVwZGF0ZWQgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6DQoNCiogKipTZWN0aW9uIDE6IERhdGEgQ29sbGVjdGlvbioqDQogICogV2hhdCBmaWxlIGZvcm1hdHMgd2lsbCB5b3VyIGRhdGEgYmUgY29sbGVjdGVkIGFuZCBzYXZlZCBpbj8gIFNlbGVjdCBhbGwgdGhhdCBhcHBseS4NCiAgKiBEZXNjcmliZSByZWxhdGVkIHRvb2xzIGFuZCBzb2Z0d2FyZSBuZWVkZWQgdG8gYWNjZXNzLCBtYW5pcHVsYXRlLCBhbmQgYW5hbHl6ZSB0aGUgZGF0YS4NCg0KKiAqKlNlY3Rpb24gNDogUHJlc2VydmF0aW9uKioNCiAgKiBJbmRpY2F0ZSBob3cgeW91IHdpbGwgZW5zdXJlIHlvdXIgZGF0YSBpcyBwcmVzZXJ2YXRpb24gZnJpZW5kbHkgYmVmb3JlIGFyY2hpdmluZy4gQ29uc2lkZXIgcHJlc2VydmF0aW9uLWZyaWVuZGx5IGZpbGUgZm9ybWF0cywgYW5vbnltaXphdGlvbiBhbmQgZGUtaWRlbnRpZmljYXRpb24gb2YgaHVtYW4gc3ViamVjdHMgZGF0YSwgbG9uZy10ZXJtIGZpbGUgaW50ZWdyaXR5LCBhbmQgaW5jbHVzaW9uIG9mIHN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbi4NCiAgDQo8YnI+DQoNCldlJ3ZlIGFsc28gYWRkZWQgYSBuZXcgc2NyaXB0IGZpbGUgdG8gb3VyIHByb2plY3QsIGFuZCBzaG91bGQgdXBkYXRlIG91ciBSRUFETUUgZmlsZSB0byByZWZsZWN0IHRoaXMgd2l0aCBhIGRlc2NyaXB0aW9uIG9mIHRoZSBmaWxlLg0KDQo6OjogDQoNCg0KDQoNCg0KDQoNCg==