Markdown & Notebooks provide interactive documents for more effective data communication

Impetus

In current data analytics and communication, there are a wide variety of platforms on which we can provide summaries and insights regarding our work. Each of these end points requires a non-insignificant amount of effort to learn these systems. Moreover, they all are cul de sacs in that all the effort you exert to learn one will not allow you to get the benefits of any other platform than the one you just learned.

This is stupid. - R. Dyer

Enter Pandoc, the universal document converter. Some really smart programmers have put together a set of software that allows you to convert from or two (and hence between) different document types given that most documents are regularly structured. With Pandoc, it does not matter if you do or do not have Word or Powerpoint or EPub or LaTeX or whatever, as long as you can create one of the supported types, you can convert that input into a huge variety of output types.

Pandoc Supported Conversions

Conversion Formats

This is critical for us because Code is just text. Once it is evaluated, it can replaced with:

  • Numerical values from one or more calculations,
  • Textual content from analyses or manipulation, or
  • Graphical content from plots.

As such, we can embed R code within raw text to create our analyses and documents.

Markdown

For maximum usability, the document that we embed our code into should be as widely available as possible—unhindered by the necessity of having a particular program just to view the content. For this, R uses Markdown, created by John Gruber & Aaron Swartz in 2004. Markdown was created so that people are enabled “…to write using an easy-to-read and easy-to-write plain text format…”

Because everything is text, it is easy share and collaborate using Markdown, and for R, it is how we can make a wide array of output document types including (but not limited to):

Text Markup

When we make a document, presentation, or any other output, there are only a finite set of different text components we can put into the document. The document itself does not need to be heavy or bloated, it is just text (though surprisingly, a blank Word document on my laptop with nothing in the document itself is still 12KB in size!). Common elements include:

  • Headers & Titles
  • Typography such as italic, bold, underline, strike through
  • Lists (numbered or as bullets)
  • Pictures and links
  • Page numbers, tables of contents, etc.

What Markdown does is allows you to type these components and use ‘marking’ around the elements to make them different from regular text. It is really, amazingly simple.

Title and headers are created by prepending a hashtag

# Header 1
## Header 2
### Header 3
#### Header 4

are knit into the following headers styles.

Header 1

Header 2

Header 3

Header 4

The actual appearance of the headers are determined by where it is being presented (e.g., in Word it will take the default typography and font attributes, etc.).

In text markdown examples are shown below and are contained within paragraphs of text. Individual paragraphs are delimited by either a blank line between them or two spaces at the end of the sentence.

Markdown Rendered As
plain text plain text
*italic* italic
**bold** bold
~~strike through~~ strike through

You can also embed links and images. Both of these are configured in two parts. For links, you need to specify the text that can be clicked upon and it must be surrounded in square brackets. The link to the web or file or image is right next to the square brackets and is contained within parentheses. The difference between link and image is that images have alternative text (or at times captions) and the whole thing has an exclamation mark in front of it. Here are some examples.

Markdown Rendered As
[CES](https://ces.vcu.edu) CES
![Goat](https://bit.ly/3fRVlfl) alt text

Lists (both numbered and unordered) are created using dashes or asterisks.

- Bullet 1
- Bullet 2
- Bullet 3

Will be turned into an unordered list as:

  • Bullet 1
  • Bullet 2
  • Bullet 3

Whereas the following raw text.1

0. First
1. Second
2. Third

Will be rendered in list format as:

  1. First
  2. Second
  3. Third

Actually, you can just use 1. in front of every line if you like, it will auto-number them for you when it makes a list. Helpful if you are making a numbered list that you are moving things around in.

Code & Text

On of the strengths of RMarkdown is the ability to mix code and text together in one place. This allows us to bring all of our analyses and data as close to one another as possible, helping with reproducibility and error reduction.

Inline Code

You can easily integrate code, into the text, either to be displayed OR to be evaluated. For example, in R you get the value of \(\pi\) by the constant pi. Type that into the console and it will return 3.1415927.

If you look at the RMarkdown for that paragraph above, it looks like the following before knitting:

You can easily integrate code, into the text, either to be displayed *OR* to be evaluated.  For example, in `R` you get the value of $\pi$ by the constant `pi`. Type that into the console and it will return 3.1415927.

Notice the following parts:

  • Symbols: The \(\pi\) symbol is created by the name of the symbol surrounded by dollar signs. $\pi$. There are a ton of symbols and equations you can use, all borrowed from LaTeX, so if you need complicated equations or symbols, this is not a problem.
  • Text rendered as code (in typography) but not evaluated: Both the `R` and the `pi` are examples here. Nothing is evaluated, but it looks like code.
  • Evaluated R Code: Any code between `r and ` will be evaluated as R code within the text. When you knit the document, it will be run and the contents between the `r and ` are replaced by the output of the R code. The example here was `pi` at the end of the last sentence.

Code Chunks

In addition to code within the text, RMarkdown supports code chunks, which can be one or many lines of raw R code. This code is executed and the results are merged into the markdown in the document (text, graphical, interactive widgets, whatever) before knitting.

Each chunk is enclosed within boundary rows, the top row must contain three acute accents (back ticks - `) followed by the letter r in curly brackets ```{r}. The end of the chunk is indicated by three back ticks on their own line such as ```. Everything between these two enclosing lines is treated as R code and is subject to evaluation when you re-knit the document.

Here is what a chunk looks like in markdown that prints out a simple message "This is text from a chunk.

```{r}
print(“This is text from a chunk”)
```

When it is evaluated, the R interpreter removes the first and last rows, and executes the code within them. By default, the code is presented as a box in the output as well as any output that is produced from the code.

print("This is text from a chunk")
[1] "This is text from a chunk"

The first line in the chunk can also be used to modify the behavior of the code. There are several options that you can place within the curly brackets, including:

  • {r eval=FALSE}: Will not evaluate (e.g., run) the code. The default value is TRUE.
  • {r echo=FALSE}: Will not show the code in the document. This is great for our final version of our analyses, we want the output but not the code chunks showing. The default value is TRUE.
  • {r message=FALSE, warning=FALSE, error=FALSE}: These suppress the messages that R prints out on occasion.

See the reference guide for several more options you can put into the header of each chunk.

Code Chunks in Document

There are some very fundamental issues regarding chunks, the R environment, and documents that should be pointed out here.

  1. The R environment (see tab labeled Environment in the RStudio interface) has all the variables and new functions that you have created listed and available for use.
  2. An R Markdown document is not a ‘living’ environment. If you make a change in a chunk, you must rerun that chunk to have the output available and inserted into the Environment. It does not do it automagically.
  3. When you knit a document, the only data it has is what is actually in the document itself. It does not look to the general Environment for variables and functions. This means that if you create a variable or load data using the Console and then reference it in the Document, it will fail when you try to knit the document.
  4. All the code and variables in a document (if they are not within a chunk with eval=FALSE) is visible to everything in the document below where it was defined.
  5. Chunks are evaluated from the top of the document to the bottom of the document.
  6. The options for each chunk are available from the setup menu on the top right of the chunk itself (the gear icon). Additional options include a button to run all the chunks prior to this one as well as running this particular chunk (see image).

Option buttons for each chunk include a quick menu for optoins (gear), the ability to run all the chunks above this one (triangle and line button in the middle), and run this particular chunk (play button).

Document Types

RMarkdown can be converted easily into a variety of document types. Let’s take a look at how the base Markdown document can be converted into a wide variety of output types.

RMarkdown Document

In RStudio, select File \(\to\) New File \(\to\) R Markdown… and you should see the following dialog.

New R Markdown Dialog from RStudio

For most of this class, we will be using HTML output. This creates a stand-alone document, with all the content embedded within it as a self-contained HTML web page. This is preferable at this point because it we will be working with interactive graphics, included maps, overlays, graphics, dynamic data tables, etc. None of these components can be embedded within PDF or Word documents, though you could take a picture of them and use that… But that would defeat the purpose and utility of interactive graphics and output now wouldn’t it?

The raw document in RStudio looks like this:

Base R Markdown There are a couple different parts to this document itself that need to be highlighted.

  1. The meta data: The part at the top of the document, lines 1-6, are meta data that summarize the document and specify how it would be converted into a final document. The process of converting the markdown to a final document type is called knitting (and there is a knit button above the document). For manuscripts and web pages and presentations, the values of title author and date are used for the top of the document.

  2. Code Chunks: Raw code (R or other languages) that is to be evaluated when we knit the document is enclosed within chunks. These chunks are delimited by three back ticks (the tick is found on the key just to the left of the ‘1’ key on English (USA) keyboards). The first and last line must have these three ticks and everything contained within them will be evaluated as R code when you knit the document.

  3. Chunk Options: On the first line of each code chunk, there is a curly bracket with r and potentially other items within it. The r specifies that the code will be R code and the other components are either an alias to for the chunk (e.g., the setup, cars and pressure on lines 8, 18 & 26) or options that apply to the overall chunk (the rest of the stuff between the curly brackets on the same lines). The names allow you to refer to the chunk from the text (such as referencing a Figure whose number will be automatically determined when knit) and the options allow you to determine the behavior of the chunk (figure size, orientation, showing, evaluating, suppressing warnings, etc.).

RStudio Interface Components

Surrounding the markdown document are several components of the RStudio IDE that help you be more productive. Here is a quick tour.

The Knit button at the top left of the window allows you to knit the docuemnt into different output types. This will default to the kind of document you selected in the original document dialog. If you change it, the value in the markdown meta data after output will change between html_document, pdf_document, and word_document.

In addition to R code, the insert menu on the top right of the interface lets you insert a chunk for R and some other programming languages. Mostly in this class, we will focus on R code and there is a keyboard shortcut to insert a chunk.

The Run menu allows you to execute code within the document at various levels of specificity. At the most granular, you can run the current line of code that the cursor is sitting on. Above that, you can run chunks individually or as a group.
Please go back and read about code chunks and restrictions within documents (above).

The document structure menu at the bottom left of the window shows you the structure of the document you are making based upon headers and sections within it.

R Notebooks

An R Notebook is a special kind of Markdown document, which we will be using in this class. It adds a bit of interactivity to the normal Markdown documents. The differences are:

  1. Instead of a Knit button at the top of the page, there is a Preview button.
  2. Every time you save the document, an HTML version of the document will be rendered in the Viewer tab of the RStudio interface.
  3. The output of code chunks within the Viewer for the document will show exactly the same output as is rendered in the raw markdown document. This means if you have code and the output has not been run, it will not show that in the Viewer.
  4. You can show and hide all the code in a notebook using the button at the top of the page or on a per-chunk basis.
  5. The HTML output of the notebook also contains a copy of the rmd file within it. This means that we can post a notebook online and a viewer can download the raw markdown for that document to their own computer and run it (at the top right of this very document is a button that has an option to Download Rmd).

For these reasons, we will be using notebooks for this class.


  1. This is a footnote and is defined by enclosing square brackets and a carat symbol (^) where you want to put the footnote in the text (e.g., [^1]) and then at the bottom of the document add the text (this part) prepended by [^1]:. The linking to the footnote and back to the place you put it will be automagically inserted.↩︎

LS0tCnRpdGxlOiAiTWFya2Rvd24gJiBOb3RlYm9va3MiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIGNzczogWyJodHRwczovL2R5ZXJsYWIuZ2l0aHViLmlvL0VOVlMtTGVjdHVyZXMvbmFycmF0aXZlX3N0eWxlLmNzcyJdCi0tLQoKPiBNYXJrZG93biAmIE5vdGVib29rcyBwcm92aWRlIGludGVyYWN0aXZlIGRvY3VtZW50cyBmb3IgbW9yZSBlZmZlY3RpdmUgZGF0YSBjb21tdW5pY2F0aW9uCgojIEltcGV0dXMKCkluIGN1cnJlbnQgZGF0YSBhbmFseXRpY3MgYW5kIGNvbW11bmljYXRpb24sIHRoZXJlIGFyZSBhIHdpZGUgdmFyaWV0eSBvZiBwbGF0Zm9ybXMgb24gd2hpY2ggd2UgY2FuIHByb3ZpZGUgc3VtbWFyaWVzIGFuZCBpbnNpZ2h0cyByZWdhcmRpbmcgb3VyIHdvcmsuICBFYWNoIG9mIHRoZXNlIGVuZCBwb2ludHMgcmVxdWlyZXMgYSBub24taW5zaWduaWZpY2FudCBhbW91bnQgb2YgZWZmb3J0IHRvIGxlYXJuIHRoZXNlIHN5c3RlbXMuICBNb3Jlb3ZlciwgdGhleSBhbGwgYXJlICpjdWwgZGUgc2FjcyogaW4gdGhhdCBhbGwgdGhlIGVmZm9ydCB5b3UgZXhlcnQgdG8gbGVhcm4gb25lIHdpbGwgbm90IGFsbG93IHlvdSB0byBnZXQgdGhlIGJlbmVmaXRzIG9mIGFueSBvdGhlciBwbGF0Zm9ybSB0aGFuIHRoZSBvbmUgeW91IGp1c3QgbGVhcm5lZC4KCj4gVGhpcyBpcyBzdHVwaWQuICAtIFIuIER5ZXIKCkVudGVyIFtQYW5kb2NdKGh0dHBzOi8vcGFuZG9jLm9yZyksIHRoZSB1bml2ZXJzYWwgZG9jdW1lbnQgY29udmVydGVyLiAgU29tZSByZWFsbHkgc21hcnQgcHJvZ3JhbW1lcnMgaGF2ZSBwdXQgdG9nZXRoZXIgYSBzZXQgb2Ygc29mdHdhcmUgdGhhdCBhbGxvd3MgeW91IHRvIGNvbnZlcnQgZnJvbSBvciB0d28gKGFuZCBoZW5jZSBiZXR3ZWVuKSBkaWZmZXJlbnQgZG9jdW1lbnQgdHlwZXMgZ2l2ZW4gdGhhdCBtb3N0IGRvY3VtZW50cyBhcmUgcmVndWxhcmx5IHN0cnVjdHVyZWQuICBXaXRoIFBhbmRvYywgaXQgZG9lcyBub3QgbWF0dGVyIGlmIHlvdSBkbyBvciBkbyBub3QgaGF2ZSBXb3JkIG9yIFBvd2VycG9pbnQgb3IgRVB1YiBvciBMYVRlWCBvciB3aGF0ZXZlciwgYXMgbG9uZyBhcyB5b3UgY2FuIGNyZWF0ZSBvbmUgb2YgdGhlIHN1cHBvcnRlZCB0eXBlcywgeW91IGNhbiBjb252ZXJ0IHRoYXQgaW5wdXQgaW50byBhIGh1Z2UgdmFyaWV0eSBvZiBvdXRwdXQgdHlwZXMuCgojIyBQYW5kb2MgU3VwcG9ydGVkIENvbnZlcnNpb25zCgohW0NvbnZlcnNpb24gRm9ybWF0c10oaHR0cHM6Ly9saXZlLnN0YXRpY2ZsaWNrci5jb20vNjU1MzUvNTAxNTkxNzAwMDZfNDViOGVkMzVhMF9jX2QuanBnKQoKVGhpcyBpcyBjcml0aWNhbCBmb3IgdXMgYmVjYXVzZSBDb2RlIGlzIGp1c3QgdGV4dC4gIE9uY2UgaXQgaXMgZXZhbHVhdGVkLCBpdCBjYW4gcmVwbGFjZWQgd2l0aDogIAoKICAtIE51bWVyaWNhbCB2YWx1ZXMgZnJvbSBvbmUgb3IgbW9yZSBjYWxjdWxhdGlvbnMsCiAgLSBUZXh0dWFsIGNvbnRlbnQgZnJvbSBhbmFseXNlcyBvciBtYW5pcHVsYXRpb24sIG9yIAogIC0gR3JhcGhpY2FsIGNvbnRlbnQgZnJvbSBwbG90cy4KCkFzIHN1Y2gsIHdlIGNhbiBlbWJlZCBSIGNvZGUgd2l0aGluIHJhdyB0ZXh0IHRvIGNyZWF0ZSBvdXIgYW5hbHlzZXMgYW5kIGRvY3VtZW50cy4gIAoKIyBNYXJrZG93bgoKRm9yIG1heGltdW0gdXNhYmlsaXR5LCB0aGUgZG9jdW1lbnQgdGhhdCB3ZSBlbWJlZCBvdXIgY29kZSBpbnRvIHNob3VsZCBiZSBhcyB3aWRlbHkgYXZhaWxhYmxlIGFzIHBvc3NpYmxl4oCUdW5oaW5kZXJlZCBieSB0aGUgbmVjZXNzaXR5IG9mIGhhdmluZyBhIHBhcnRpY3VsYXIgcHJvZ3JhbSBqdXN0IHRvIHZpZXcgdGhlIGNvbnRlbnQuICAgRm9yIHRoaXMsIFIgdXNlcyBbTWFya2Rvd25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01hcmtkb3duKSwgY3JlYXRlZCBieSBKb2huIEdydWJlciAmIEFhcm9uIFN3YXJ0eiBpbiAyMDA0LiAgTWFya2Rvd24gd2FzIGNyZWF0ZWQgc28gdGhhdCBwZW9wbGUgYXJlIGVuYWJsZWQgIi4uLnRvIHdyaXRlIHVzaW5nIGFuIGVhc3ktdG8tcmVhZCBhbmQgZWFzeS10by13cml0ZSBwbGFpbiB0ZXh0IGZvcm1hdC4uLiIKCkJlY2F1c2UgZXZlcnl0aGluZyBpcyB0ZXh0LCBpdCBpcyBlYXN5IHNoYXJlIGFuZCBjb2xsYWJvcmF0ZSB1c2luZyBNYXJrZG93biwgYW5kIGZvciBSLCBpdCBpcyBob3cgd2UgY2FuIG1ha2UgYSB3aWRlIGFycmF5IG9mIG91dHB1dCBkb2N1bWVudCB0eXBlcyBpbmNsdWRpbmcgKGJ1dCBub3QgbGltaXRlZCB0byk6ICAKCi0gQ29udmVudGlvbmFsIGRvY3VtZW50cyAoUERGLCBXb3JkLCBSVEYsIGV0Yy4pCi0gSFRNTCBwYWdlcyB3aXRoIGludGVyYWN0aXZlIGVsZW1lbnRzICh0aGlzIGRvY3VtZW50IGhlcmUgaXMgYW4gaW50ZXJhY3RpdmUgaHRtbCBkb2N1bWVudCkuCi0gUHJlc2VudGF0aW9ucyAoTGFUZVgsIFBvd2VycG9pbnQsIEphdmFTY3JpcHQsIGV0Yy4pCi0gRGFzaGJvYXJkcyB3aXRoIGludGVyYWN0aXZlIGNvbnRlbnQuCgojIyBUZXh0IE1hcmt1cAoKV2hlbiB3ZSBtYWtlIGEgZG9jdW1lbnQsIHByZXNlbnRhdGlvbiwgb3IgYW55IG90aGVyIG91dHB1dCwgdGhlcmUgYXJlIG9ubHkgYSBmaW5pdGUgc2V0IG9mIGRpZmZlcmVudCB0ZXh0IGNvbXBvbmVudHMgd2UgY2FuIHB1dCBpbnRvIHRoZSBkb2N1bWVudC4gIFRoZSBkb2N1bWVudCBpdHNlbGYgZG9lcyBub3QgbmVlZCB0byBiZSBoZWF2eSBvciBibG9hdGVkLCBpdCBpcyBqdXN0IHRleHQgKHRob3VnaCBzdXJwcmlzaW5nbHksIGEgYmxhbmsgV29yZCBkb2N1bWVudCBvbiBteSBsYXB0b3Agd2l0aCBub3RoaW5nIGluIHRoZSBkb2N1bWVudCBpdHNlbGYgaXMgc3RpbGwgMTJLQiBpbiBzaXplISkuICBDb21tb24gZWxlbWVudHMgaW5jbHVkZToKCi0gSGVhZGVycyAmIFRpdGxlcwotIFR5cG9ncmFwaHkgc3VjaCBhcyBpdGFsaWMsIGJvbGQsIHVuZGVybGluZSwgc3RyaWtlIHRocm91Z2gKLSBMaXN0cyAobnVtYmVyZWQgb3IgYXMgYnVsbGV0cykKLSBQaWN0dXJlcyBhbmQgbGlua3MKLSBQYWdlIG51bWJlcnMsIHRhYmxlcyBvZiBjb250ZW50cywgZXRjLgoKV2hhdCBNYXJrZG93biBkb2VzIGlzIGFsbG93cyB5b3UgdG8gdHlwZSB0aGVzZSBjb21wb25lbnRzIGFuZCB1c2UgJ21hcmtpbmcnIGFyb3VuZCB0aGUgZWxlbWVudHMgdG8gbWFrZSB0aGVtIGRpZmZlcmVudCBmcm9tIHJlZ3VsYXIgdGV4dC4gIEl0IGlzIHJlYWxseSwgYW1hemluZ2x5IHNpbXBsZS4gIAoKVGl0bGUgYW5kIGhlYWRlcnMgYXJlIGNyZWF0ZWQgYnkgcHJlcGVuZGluZyBhIGhhc2h0YWcKCiYjMzU7IEhlYWRlciAxICAKJiMzNTsmIzM1OyBIZWFkZXIgMiAgCiYjMzU7JiMzNTsmIzM1OyBIZWFkZXIgMyAgCiYjMzU7JiMzNTsmIzM1OyYjMzU7IEhlYWRlciA0ICAKCmFyZSBrbml0IGludG8gdGhlIGZvbGxvd2luZyBoZWFkZXJzIHN0eWxlcy4KCiMgSGVhZGVyIDEKIyMgSGVhZGVyIDIKIyMjIEhlYWRlciAzCiMjIyMgSGVhZGVyIDQKClRoZSBhY3R1YWwgYXBwZWFyYW5jZSBvZiB0aGUgaGVhZGVycyBhcmUgZGV0ZXJtaW5lZCBieSB3aGVyZSBpdCBpcyBiZWluZyBwcmVzZW50ZWQgKGUuZy4sIGluIFdvcmQgaXQgd2lsbCB0YWtlIHRoZSBkZWZhdWx0IHR5cG9ncmFwaHkgYW5kIGZvbnQgYXR0cmlidXRlcywgZXRjLikuCgpJbiB0ZXh0IG1hcmtkb3duIGV4YW1wbGVzIGFyZSBzaG93biBiZWxvdyBhbmQgYXJlIGNvbnRhaW5lZCB3aXRoaW4gcGFyYWdyYXBocyBvZiB0ZXh0LiAgSW5kaXZpZHVhbCBwYXJhZ3JhcGhzIGFyZSBkZWxpbWl0ZWQgYnkgZWl0aGVyIGEgYmxhbmsgbGluZSBiZXR3ZWVuIHRoZW0gb3IgdHdvIHNwYWNlcyBhdCB0aGUgZW5kIG9mIHRoZSBzZW50ZW5jZS4gICAgCgpNYXJrZG93biAgICAgICB8ICBSZW5kZXJlZCBBcwotLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tCnBsYWluIHRleHQgICAgIHwgIHBsYWluIHRleHQKJiM0MjtpdGFsaWMmIzQyOyB8ICppdGFsaWMqCiYjNDI7JiM0Mjtib2xkJiM0MjsmIzQyOyB8ICoqYm9sZCoqIAomIzEyNjsmIzEyNjtzdHJpa2UgdGhyb3VnaCYjMTI2OyYjMTI2OyAgfCB+fnN0cmlrZSB0aHJvdWdofn4gCgpZb3UgY2FuIGFsc28gZW1iZWQgbGlua3MgYW5kIGltYWdlcy4gIEJvdGggb2YgdGhlc2UgYXJlIGNvbmZpZ3VyZWQgaW4gdHdvIHBhcnRzLiAgRm9yIGxpbmtzLCB5b3UgbmVlZCB0byBzcGVjaWZ5IHRoZSB0ZXh0IHRoYXQgY2FuIGJlIGNsaWNrZWQgdXBvbiBhbmQgaXQgKm11c3QqIGJlIHN1cnJvdW5kZWQgaW4gKnNxdWFyZSBicmFja2V0cyouIFRoZSBsaW5rIHRvIHRoZSB3ZWIgb3IgZmlsZSBvciBpbWFnZSBpcyByaWdodCBuZXh0IHRvIHRoZSBzcXVhcmUgYnJhY2tldHMgYW5kIGlzIGNvbnRhaW5lZCB3aXRoaW4gKnBhcmVudGhlc2VzKi4gIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gbGluayBhbmQgaW1hZ2UgaXMgdGhhdCBpbWFnZXMgaGF2ZSBhbHRlcm5hdGl2ZSB0ZXh0IChvciBhdCB0aW1lcyBjYXB0aW9ucykgYW5kIHRoZSB3aG9sZSB0aGluZyBoYXMgYW4gZXhjbGFtYXRpb24gbWFyayBpbiBmcm9udCBvZiBpdC4gIEhlcmUgYXJlIHNvbWUgZXhhbXBsZXMuCgpNYXJrZG93biAgICAgICB8ICBSZW5kZXJlZCBBcwotLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tCiYjOTE7Q0VTJiM5MzsmIzQwO2h0dHBzJiM1ODsmIzQ3OyYjNDc7Y2VzLnZjdS5lZHUmIzQxOyB8IFtDRVNdKGh0dHBzOi8vY2VzLnZjdS5lZHUpCiEmIzkxO0dvYXQmIzkzOyYjNDA7aHR0cHMmIzU4OyYjNDc7JiM0NztiaXQubHkvM2ZSVmxmbCYjNDE7fCAhW2FsdCB0ZXh0XShodHRwczovL2JpdC5seS8zZlJWbGZsKQoKCkxpc3RzIChib3RoIG51bWJlcmVkIGFuZCB1bm9yZGVyZWQpIGFyZSBjcmVhdGVkIHVzaW5nIGRhc2hlcyBvciBhc3Rlcmlza3MuCgoKJiM0NTsgQnVsbGV0IDEgIAomIzQ1OyBCdWxsZXQgMiAgCiYjNDU7IEJ1bGxldCAzICAKCldpbGwgYmUgdHVybmVkIGludG8gYW4gdW5vcmRlcmVkIGxpc3QgYXM6CgotIEJ1bGxldCAxICAKLSBCdWxsZXQgMiAgCi0gQnVsbGV0IDMgCgpXaGVyZWFzIHRoZSBmb2xsb3dpbmcgcmF3IHRleHQuW14xXQoKJiM0ODsmIzQ2OyBGaXJzdCAgCiYjNDk7JiM0NjsgU2Vjb25kICAKJiM1MDsmIzQ2OyBUaGlyZCAgCgpXaWxsIGJlIHJlbmRlcmVkIGluIGxpc3QgZm9ybWF0IGFzOgoKMS4gRmlyc3QgIAoxLiBTZWNvbmQgICAKMS4gVGhpcmQKCkFjdHVhbGx5LCB5b3UgKmNhbioganVzdCB1c2UgYDEuYCBpbiBmcm9udCBvZiBldmVyeSBsaW5lIGlmIHlvdSBsaWtlLCBpdCB3aWxsIGF1dG8tbnVtYmVyIHRoZW0gZm9yIHlvdSB3aGVuIGl0IG1ha2VzIGEgbGlzdC4gIEhlbHBmdWwgaWYgeW91IGFyZSBtYWtpbmcgYSBudW1iZXJlZCBsaXN0IHRoYXQgeW91IGFyZSBtb3ZpbmcgdGhpbmdzIGFyb3VuZCBpbi4KCgoKCiMjIENvZGUgJiBUZXh0CgpPbiBvZiB0aGUgc3RyZW5ndGhzIG9mIFJNYXJrZG93biBpcyB0aGUgYWJpbGl0eSB0byBtaXggY29kZSBhbmQgdGV4dCB0b2dldGhlciBpbiBvbmUgcGxhY2UuICBUaGlzIGFsbG93cyB1cyB0byBicmluZyBhbGwgb2Ygb3VyIGFuYWx5c2VzICphbmQqIGRhdGEgYXMgY2xvc2UgdG8gb25lIGFub3RoZXIgYXMgcG9zc2libGUsIGhlbHBpbmcgd2l0aCByZXByb2R1Y2liaWxpdHkgYW5kIGVycm9yIHJlZHVjdGlvbi4KCiMjIyBJbmxpbmUgQ29kZQoKCllvdSBjYW4gZWFzaWx5IGludGVncmF0ZSBjb2RlLCBpbnRvIHRoZSB0ZXh0LCBlaXRoZXIgdG8gYmUgZGlzcGxheWVkICpPUiogdG8gYmUgZXZhbHVhdGVkLiAgRm9yIGV4YW1wbGUsIGluIGBSYCB5b3UgZ2V0IHRoZSB2YWx1ZSBvZiAkXHBpJCBieSB0aGUgY29uc3RhbnQgYHBpYC4gVHlwZSB0aGF0IGludG8gdGhlIGNvbnNvbGUgYW5kIGl0IHdpbGwgcmV0dXJuIGByIHBpYC4KCklmIHlvdSBsb29rIGF0IHRoZSBSTWFya2Rvd24gZm9yIHRoYXQgcGFyYWdyYXBoIGFib3ZlLCBpdCBsb29rcyBsaWtlIHRoZSBmb2xsb3dpbmcgYmVmb3JlIGtuaXR0aW5nOgoKYGBgCllvdSBjYW4gZWFzaWx5IGludGVncmF0ZSBjb2RlLCBpbnRvIHRoZSB0ZXh0LCBlaXRoZXIgdG8gYmUgZGlzcGxheWVkICpPUiogdG8gYmUgZXZhbHVhdGVkLiAgRm9yIGV4YW1wbGUsIGluIGBSYCB5b3UgZ2V0IHRoZSB2YWx1ZSBvZiAkXHBpJCBieSB0aGUgY29uc3RhbnQgYHBpYC4gVHlwZSB0aGF0IGludG8gdGhlIGNvbnNvbGUgYW5kIGl0IHdpbGwgcmV0dXJuIGByIHBpYC4KYGBgCgpOb3RpY2UgdGhlIGZvbGxvd2luZyBwYXJ0czogIAoKLSBTeW1ib2xzOiBUaGUgJFxwaSQgc3ltYm9sIGlzIGNyZWF0ZWQgYnkgdGhlIG5hbWUgb2YgdGhlIHN5bWJvbCBzdXJyb3VuZGVkIGJ5IGRvbGxhciBzaWducy4gICYjMzY7JiN4NWM7cGkmIzM2Oy4gIFRoZXJlIGFyZSBhIHRvbiBvZiBzeW1ib2xzIGFuZCBlcXVhdGlvbnMgeW91IGNhbiB1c2UsIGFsbCBib3Jyb3dlZCBmcm9tIExhVGVYLCBzbyBpZiB5b3UgbmVlZCBjb21wbGljYXRlZCBlcXVhdGlvbnMgb3Igc3ltYm9scywgdGhpcyBpcyBub3QgYSBwcm9ibGVtLgotIFRleHQgcmVuZGVyZWQgYXMgY29kZSAoaW4gdHlwb2dyYXBoeSkgYnV0IG5vdCBldmFsdWF0ZWQ6ICBCb3RoIHRoZSAmZ3JhdmU7UiZncmF2ZTsgYW5kIHRoZSAmZ3JhdmU7cGkmZ3JhdmU7IGFyZSBleGFtcGxlcyBoZXJlLiAgTm90aGluZyBpcyBldmFsdWF0ZWQsIGJ1dCBpdCAqbG9va3MqIGxpa2UgY29kZS4KLSBFdmFsdWF0ZWQgUiBDb2RlOiAgQW55IGNvZGUgYmV0d2VlbiAmZ3JhdmU7ciBhbmQgJmdyYXZlOyB3aWxsIGJlIGV2YWx1YXRlZCBhcyBSIGNvZGUgd2l0aGluIHRoZSB0ZXh0LiAgV2hlbiB5b3Uga25pdCB0aGUgZG9jdW1lbnQsIGl0IHdpbGwgYmUgcnVuIGFuZCB0aGUgY29udGVudHMgYmV0d2VlbiB0aGUgJmdyYXZlO3IgYW5kICZncmF2ZTsgYXJlIHJlcGxhY2VkIGJ5IHRoZSBvdXRwdXQgb2YgdGhlIGBSYCBjb2RlLiAgVGhlIGV4YW1wbGUgaGVyZSB3YXMgJmdyYXZlO3BpJmdyYXZlOyBhdCB0aGUgZW5kIG9mIHRoZSBsYXN0IHNlbnRlbmNlLgoKCiMjIyBDb2RlIENodW5rcwoKSW4gYWRkaXRpb24gdG8gY29kZSB3aXRoaW4gdGhlIHRleHQsIFJNYXJrZG93biBzdXBwb3J0cyAqY29kZSBjaHVua3MqLCB3aGljaCBjYW4gYmUgb25lIG9yIG1hbnkgbGluZXMgb2YgcmF3IGBSYCBjb2RlLiAgVGhpcyBjb2RlIGlzIGV4ZWN1dGVkIGFuZCB0aGUgcmVzdWx0cyBhcmUgbWVyZ2VkIGludG8gdGhlIG1hcmtkb3duIGluIHRoZSBkb2N1bWVudCAodGV4dCwgZ3JhcGhpY2FsLCBpbnRlcmFjdGl2ZSB3aWRnZXRzLCB3aGF0ZXZlcikgYmVmb3JlIGtuaXR0aW5nLgoKRWFjaCBjaHVuayBpcyBlbmNsb3NlZCB3aXRoaW4gYm91bmRhcnkgcm93cywgdGhlIHRvcCByb3cgKiptdXN0KiogY29udGFpbiB0aHJlZSBhY3V0ZSBhY2NlbnRzIChiYWNrIHRpY2tzIC0gJmdyYXZlOykgZm9sbG93ZWQgYnkgdGhlIGxldHRlciByIGluIGN1cmx5IGJyYWNrZXRzICYjOTY7JiM5NjsmIzk2O3tyfS4gIFRoZSBlbmQgb2YgdGhlIGNodW5rIGlzIGluZGljYXRlZCBieSB0aHJlZSBiYWNrIHRpY2tzIG9uIHRoZWlyIG93biBsaW5lIHN1Y2ggYXMgJiM5NjsmIzk2OyYjOTY7LiAgRXZlcnl0aGluZyBiZXR3ZWVuIHRoZXNlIHR3byBlbmNsb3NpbmcgbGluZXMgaXMgdHJlYXRlZCBhcyBgUmAgY29kZSBhbmQgaXMgc3ViamVjdCB0byBldmFsdWF0aW9uIHdoZW4geW91IHJlLWtuaXQgdGhlIGRvY3VtZW50LiAgCgpIZXJlIGlzIHdoYXQgYSBjaHVuayBsb29rcyBsaWtlIGluIG1hcmtkb3duIHRoYXQgcHJpbnRzIG91dCBhIHNpbXBsZSBtZXNzYWdlICJUaGlzIGlzIHRleHQgZnJvbSBhIGNodW5rLgoKJiM5NjsmIzk2OyYjOTY7e3J9ICAKcHJpbnQoIlRoaXMgaXMgdGV4dCBmcm9tIGEgY2h1bmsiKSAgCiYjOTY7JiM5NjsmIzk2OwoKV2hlbiBpdCBpcyBldmFsdWF0ZWQsIHRoZSBgUmAgaW50ZXJwcmV0ZXIgcmVtb3ZlcyB0aGUgZmlyc3QgYW5kIGxhc3Qgcm93cywgYW5kIGV4ZWN1dGVzIHRoZSBjb2RlIHdpdGhpbiB0aGVtLiAgQnkgZGVmYXVsdCwgdGhlIGNvZGUgaXMgcHJlc2VudGVkIGFzIGEgYm94IGluIHRoZSBvdXRwdXQgYXMgd2VsbCBhcyBhbnkgb3V0cHV0IHRoYXQgaXMgcHJvZHVjZWQgZnJvbSB0aGUgY29kZS4gIAoKYGBge3J9CnByaW50KCJUaGlzIGlzIHRleHQgZnJvbSBhIGNodW5rIikKYGBgCgpUaGUgZmlyc3QgbGluZSBpbiB0aGUgY2h1bmsgY2FuIGFsc28gYmUgdXNlZCB0byBtb2RpZnkgdGhlIGJlaGF2aW9yIG9mIHRoZSBjb2RlLiAgVGhlcmUgYXJlIHNldmVyYWwgb3B0aW9ucyB0aGF0IHlvdSBjYW4gcGxhY2Ugd2l0aGluIHRoZSBjdXJseSBicmFja2V0cywgaW5jbHVkaW5nOiAgCgotIGB7ciBldmFsPUZBTFNFfWA6IFdpbGwgbm90IGV2YWx1YXRlIChlLmcuLCBydW4pIHRoZSBjb2RlLiAgVGhlIGRlZmF1bHQgdmFsdWUgaXMgYFRSVUVgLiAgCi0gYHtyIGVjaG89RkFMU0V9YDogV2lsbCBub3Qgc2hvdyB0aGUgY29kZSBpbiB0aGUgZG9jdW1lbnQuICBUaGlzIGlzIGdyZWF0IGZvciBvdXIgZmluYWwgdmVyc2lvbiBvZiBvdXIgYW5hbHlzZXMsIHdlIHdhbnQgdGhlIG91dHB1dCBidXQgbm90IHRoZSBjb2RlIGNodW5rcyBzaG93aW5nLiAgVGhlIGRlZmF1bHQgdmFsdWUgaXMgYFRSVUVgLiAgCi0gYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVycm9yPUZBTFNFfWA6IFRoZXNlIHN1cHByZXNzIHRoZSBtZXNzYWdlcyB0aGF0IGBSYCBwcmludHMgb3V0IG9uIG9jY2FzaW9uLgoKU2VlIHRoZSByZWZlcmVuY2UgZ3VpZGUgZm9yIHNldmVyYWwgbW9yZSBvcHRpb25zIHlvdSBjYW4gcHV0IGludG8gdGhlIGhlYWRlciBvZiBlYWNoIGNodW5rLgoKCgojIyBDb2RlIENodW5rcyBpbiBEb2N1bWVudAoKVGhlcmUgYXJlIHNvbWUgdmVyeSAqZnVuZGFtZW50YWwqIGlzc3VlcyByZWdhcmRpbmcgY2h1bmtzLCB0aGUgYFJgIGVudmlyb25tZW50LCBhbmQgZG9jdW1lbnRzIHRoYXQgc2hvdWxkIGJlIHBvaW50ZWQgb3V0IGhlcmUuICAgCgoxLiBUaGUgYFJgIGVudmlyb25tZW50IChzZWUgdGFiIGxhYmVsZWQgKipFbnZpcm9ubWVudCoqIGluIHRoZSBSU3R1ZGlvIGludGVyZmFjZSkgaGFzIGFsbCB0aGUgdmFyaWFibGVzIGFuZCBuZXcgZnVuY3Rpb25zIHRoYXQgeW91IGhhdmUgY3JlYXRlZCBsaXN0ZWQgYW5kIGF2YWlsYWJsZSBmb3IgdXNlLgoxLiBBbiBgUmAgTWFya2Rvd24gZG9jdW1lbnQgaXMgbm90IGEgJ2xpdmluZycgZW52aXJvbm1lbnQuICAgSWYgeW91IG1ha2UgYSBjaGFuZ2UgaW4gYSBjaHVuaywgeW91ICptdXN0KiByZXJ1biB0aGF0IGNodW5rIHRvIGhhdmUgdGhlIG91dHB1dCBhdmFpbGFibGUgYW5kIGluc2VydGVkIGludG8gdGhlICoqRW52aXJvbm1lbnQqKi4gIEl0IGRvZXMgbm90IGRvIGl0IGF1dG9tYWdpY2FsbHkuCjEuIFdoZW4geW91IGtuaXQgYSBkb2N1bWVudCwgdGhlICoqb25seSoqIGRhdGEgaXQgaGFzIGlzIHdoYXQgaXMgYWN0dWFsbHkgaW4gdGhlIGRvY3VtZW50IGl0c2VsZi4gIEl0IGRvZXMgbm90IGxvb2sgdG8gdGhlIGdlbmVyYWwgKipFbnZpcm9ubWVudCoqIGZvciB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9ucy4gIFRoaXMgbWVhbnMgdGhhdCBpZiB5b3UgY3JlYXRlIGEgdmFyaWFibGUgb3IgbG9hZCBkYXRhIHVzaW5nIHRoZSBDb25zb2xlIGFuZCB0aGVuIHJlZmVyZW5jZSBpdCBpbiB0aGUgRG9jdW1lbnQsIGl0IHdpbGwgZmFpbCB3aGVuIHlvdSB0cnkgdG8ga25pdCB0aGUgZG9jdW1lbnQuIAoxLiBBbGwgdGhlIGNvZGUgYW5kIHZhcmlhYmxlcyBpbiBhIGRvY3VtZW50IChpZiB0aGV5IGFyZSBub3Qgd2l0aGluIGEgY2h1bmsgd2l0aCBgZXZhbD1GQUxTRWApIGlzIHZpc2libGUgdG8gZXZlcnl0aGluZyBpbiB0aGUgZG9jdW1lbnQgYmVsb3cgd2hlcmUgaXQgd2FzIGRlZmluZWQuICAKMS4gQ2h1bmtzIGFyZSBldmFsdWF0ZWQgZnJvbSB0aGUgdG9wIG9mIHRoZSBkb2N1bWVudCB0byB0aGUgYm90dG9tIG9mIHRoZSBkb2N1bWVudC4gIAoxLiBUaGUgb3B0aW9ucyBmb3IgZWFjaCBjaHVuayBhcmUgYXZhaWxhYmxlIGZyb20gdGhlIHNldHVwIG1lbnUgb24gdGhlIHRvcCByaWdodCBvZiB0aGUgY2h1bmsgaXRzZWxmICh0aGUgZ2VhciBpY29uKS4gIEFkZGl0aW9uYWwgb3B0aW9ucyBpbmNsdWRlIGEgYnV0dG9uIHRvIHJ1biBhbGwgdGhlIGNodW5rcyBwcmlvciB0byB0aGlzIG9uZSBhcyB3ZWxsIGFzIHJ1bm5pbmcgdGhpcyBwYXJ0aWN1bGFyIGNodW5rIChzZWUgaW1hZ2UpLgoKIVtPcHRpb24gYnV0dG9ucyBmb3IgZWFjaCBjaHVuayBpbmNsdWRlIGEgcXVpY2sgbWVudSBmb3Igb3B0b2lucyAoZ2VhciksIHRoZSBhYmlsaXR5IHRvIHJ1biBhbGwgdGhlIGNodW5rcyBhYm92ZSB0aGlzIG9uZSAodHJpYW5nbGUgYW5kIGxpbmUgYnV0dG9uIGluIHRoZSBtaWRkbGUpLCBhbmQgcnVuIHRoaXMgcGFydGljdWxhciBjaHVuayAocGxheSBidXR0b24pLl0oaHR0cHM6Ly9saXZlLnN0YXRpY2ZsaWNrci5jb20vNjU1MzUvNTAxNjIxMzA3NzNfODZmNTQ1Y2IyOF9jX2QuanBnKQoKCiMjIERvY3VtZW50IFR5cGVzCgpSTWFya2Rvd24gY2FuIGJlIGNvbnZlcnRlZCBlYXNpbHkgaW50byBhIHZhcmlldHkgb2YgZG9jdW1lbnQgdHlwZXMuIExldCdzIHRha2UgYSBsb29rIGF0IGhvdyB0aGUgYmFzZSBNYXJrZG93biBkb2N1bWVudCBjYW4gYmUgY29udmVydGVkIGludG8gYSB3aWRlIHZhcmlldHkgb2Ygb3V0cHV0IHR5cGVzLgoKIyMjIFJNYXJrZG93biBEb2N1bWVudAoKSW4gUlN0dWRpbywgc2VsZWN0ICpGaWxlICRcdG8kIE5ldyBGaWxlICRcdG8kIFIgTWFya2Rvd24uLi4qIGFuZCB5b3Ugc2hvdWxkIHNlZSB0aGUgZm9sbG93aW5nIGRpYWxvZy4KCiFbTmV3IFIgTWFya2Rvd24gRGlhbG9nIGZyb20gUlN0dWRpb10oaHR0cHM6Ly9saXZlLnN0YXRpY2ZsaWNrci5jb20vNjU1MzUvNTAxNTk1NDMyMTdfMmZmMDI4MzRjYl9jX2QuanBnKQoKRm9yIG1vc3Qgb2YgdGhpcyBjbGFzcywgd2Ugd2lsbCBiZSB1c2luZyBIVE1MIG91dHB1dC4gIFRoaXMgY3JlYXRlcyBhIHN0YW5kLWFsb25lIGRvY3VtZW50LCB3aXRoIGFsbCB0aGUgY29udGVudCBlbWJlZGRlZCB3aXRoaW4gaXQgYXMgYSBzZWxmLWNvbnRhaW5lZCBIVE1MIHdlYiBwYWdlLiAgVGhpcyBpcyBwcmVmZXJhYmxlIGF0IHRoaXMgcG9pbnQgYmVjYXVzZSBpdCB3ZSB3aWxsIGJlIHdvcmtpbmcgd2l0aCBpbnRlcmFjdGl2ZSBncmFwaGljcywgaW5jbHVkZWQgbWFwcywgb3ZlcmxheXMsIGdyYXBoaWNzLCBkeW5hbWljIGRhdGEgdGFibGVzLCBldGMuICBOb25lIG9mIHRoZXNlIGNvbXBvbmVudHMgY2FuIGJlIGVtYmVkZGVkIHdpdGhpbiBQREYgb3IgV29yZCBkb2N1bWVudHMsIHRob3VnaCB5b3UgY291bGQgdGFrZSBhIHBpY3R1cmUgb2YgdGhlbSBhbmQgdXNlIHRoYXQuLi4gIEJ1dCB0aGF0IHdvdWxkIGRlZmVhdCB0aGUgcHVycG9zZSBhbmQgdXRpbGl0eSBvZiBpbnRlcmFjdGl2ZSBncmFwaGljcyBhbmQgb3V0cHV0IG5vdyB3b3VsZG4ndCBpdD8gIAoKVGhlIHJhdyBkb2N1bWVudCBpbiBSU3R1ZGlvIGxvb2tzIGxpa2UgdGhpczoKCiFbQmFzZSBSIE1hcmtkb3duXShodHRwczovL2xpdmUuc3RhdGljZmxpY2tyLmNvbS82NTUzNS81MDE1OTU2NDY3N19iMTgzOWJhNDEwX2NfZC5qcGcpClRoZXJlIGFyZSBhIGNvdXBsZSBkaWZmZXJlbnQgcGFydHMgdG8gdGhpcyBkb2N1bWVudCBpdHNlbGYgdGhhdCBuZWVkIHRvIGJlIGhpZ2hsaWdodGVkLiAgCgoxLiAqVGhlIG1ldGEgZGF0YToqICBUaGUgcGFydCBhdCB0aGUgdG9wIG9mIHRoZSBkb2N1bWVudCwgbGluZXMgMS02LCBhcmUgbWV0YSBkYXRhIHRoYXQgc3VtbWFyaXplIHRoZSBkb2N1bWVudCBhbmQgc3BlY2lmeSBob3cgaXQgd291bGQgYmUgY29udmVydGVkIGludG8gYSBmaW5hbCBkb2N1bWVudC4gIFRoZSBwcm9jZXNzIG9mIGNvbnZlcnRpbmcgdGhlIG1hcmtkb3duIHRvIGEgZmluYWwgZG9jdW1lbnQgdHlwZSBpcyBjYWxsZWQgKmtuaXR0aW5nKiAoYW5kIHRoZXJlIGlzIGEgKmtuaXQqIGJ1dHRvbiBhYm92ZSB0aGUgZG9jdW1lbnQpLiAgRm9yIG1hbnVzY3JpcHRzIGFuZCB3ZWIgcGFnZXMgYW5kIHByZXNlbnRhdGlvbnMsIHRoZSB2YWx1ZXMgb2YgdGl0bGUgYXV0aG9yIGFuZCBkYXRlIGFyZSB1c2VkIGZvciB0aGUgdG9wIG9mIHRoZSBkb2N1bWVudC4gIAoKMi4gKkNvZGUgQ2h1bmtzOiogIFJhdyBjb2RlIChSIG9yIG90aGVyIGxhbmd1YWdlcykgdGhhdCBpcyB0byBiZSBldmFsdWF0ZWQgd2hlbiB3ZSBrbml0IHRoZSBkb2N1bWVudCBpcyBlbmNsb3NlZCB3aXRoaW4gKmNodW5rcyouICBUaGVzZSBjaHVua3MgYXJlIGRlbGltaXRlZCBieSB0aHJlZSBiYWNrIHRpY2tzICh0aGUgdGljayBpcyBmb3VuZCBvbiB0aGUga2V5IGp1c3QgdG8gdGhlIGxlZnQgb2YgdGhlICcxJyBrZXkgb24gRW5nbGlzaCAoVVNBKSBrZXlib2FyZHMpLiAgVGhlIGZpcnN0IGFuZCBsYXN0IGxpbmUgKiptdXN0KiogaGF2ZSB0aGVzZSB0aHJlZSB0aWNrcyBhbmQgKmV2ZXJ5dGhpbmcqIGNvbnRhaW5lZCB3aXRoaW4gdGhlbSB3aWxsIGJlIGV2YWx1YXRlZCBhcyBgUmAgY29kZSB3aGVuIHlvdSBrbml0IHRoZSBkb2N1bWVudC4gIAoKMy4gKkNodW5rIE9wdGlvbnM6KiAgT24gdGhlIGZpcnN0IGxpbmUgb2YgZWFjaCBjb2RlIGNodW5rLCB0aGVyZSBpcyBhIGN1cmx5IGJyYWNrZXQgd2l0aCBgcmAgYW5kIHBvdGVudGlhbGx5IG90aGVyIGl0ZW1zIHdpdGhpbiBpdC4gIFRoZSBgcmAgc3BlY2lmaWVzIHRoYXQgdGhlIGNvZGUgd2lsbCBiZSBgUmAgY29kZSBhbmQgdGhlIG90aGVyIGNvbXBvbmVudHMgYXJlIGVpdGhlciBhbiBhbGlhcyB0byBmb3IgdGhlIGNodW5rIChlLmcuLCB0aGUgYHNldHVwYCwgYGNhcnNgIGFuZCBgcHJlc3N1cmVgIG9uIGxpbmVzIDgsIDE4ICYgMjYpIG9yIG9wdGlvbnMgdGhhdCBhcHBseSB0byB0aGUgb3ZlcmFsbCBjaHVuayAodGhlIHJlc3Qgb2YgdGhlIHN0dWZmIGJldHdlZW4gdGhlIGN1cmx5IGJyYWNrZXRzIG9uIHRoZSBzYW1lIGxpbmVzKS4gIFRoZSBuYW1lcyBhbGxvdyB5b3UgdG8gcmVmZXIgdG8gdGhlIGNodW5rIGZyb20gdGhlIHRleHQgKHN1Y2ggYXMgcmVmZXJlbmNpbmcgYSBGaWd1cmUgd2hvc2UgbnVtYmVyIHdpbGwgYmUgYXV0b21hdGljYWxseSBkZXRlcm1pbmVkIHdoZW4ga25pdCkgYW5kIHRoZSBvcHRpb25zIGFsbG93IHlvdSB0byBkZXRlcm1pbmUgdGhlIGJlaGF2aW9yIG9mIHRoZSBjaHVuayAoZmlndXJlIHNpemUsIG9yaWVudGF0aW9uLCBzaG93aW5nLCBldmFsdWF0aW5nLCBzdXBwcmVzc2luZyB3YXJuaW5ncywgZXRjLikuIAoKCiMjIyBSU3R1ZGlvIEludGVyZmFjZSBDb21wb25lbnRzCgpTdXJyb3VuZGluZyB0aGUgbWFya2Rvd24gZG9jdW1lbnQgYXJlIHNldmVyYWwgY29tcG9uZW50cyBvZiB0aGUgUlN0dWRpbyBJREUgdGhhdCBoZWxwIHlvdSBiZSBtb3JlIHByb2R1Y3RpdmUuICBIZXJlIGlzIGEgcXVpY2sgdG91ci4KCiFbVGhlIEtuaXQgYnV0dG9uIGF0IHRoZSB0b3AgbGVmdCBvZiB0aGUgd2luZG93IGFsbG93cyB5b3UgdG8ga25pdCB0aGUgZG9jdWVtbnQgaW50byBkaWZmZXJlbnQgb3V0cHV0IHR5cGVzLiAgVGhpcyB3aWxsIGRlZmF1bHQgdG8gdGhlIGtpbmQgb2YgZG9jdW1lbnQgeW91IHNlbGVjdGVkIGluIHRoZSBvcmlnaW5hbCBkb2N1bWVudCBkaWFsb2cuICBJZiB5b3UgY2hhbmdlIGl0LCB0aGUgdmFsdWUgaW4gdGhlIG1hcmtkb3duIG1ldGEgZGF0YSBhZnRlciBgb3V0cHV0YCB3aWxsIGNoYW5nZSBiZXR3ZWVuIGBodG1sX2RvY3VtZW50YCwgYHBkZl9kb2N1bWVudGAsIGFuZCBgd29yZF9kb2N1bWVudGAuXShodHRwczovL2xpdmUuc3RhdGljZmxpY2tyLmNvbS82NTUzNS81MDE2MjA1MTUyM185N2IyMjljNmEwX29fZC5wbmcpCgoKIVtJbiBhZGRpdGlvbiB0byBSIGNvZGUsIHRoZSBpbnNlcnQgbWVudSBvbiB0aGUgdG9wIHJpZ2h0IG9mIHRoZSBpbnRlcmZhY2UgbGV0cyB5b3UgaW5zZXJ0IGEgY2h1bmsgZm9yICBgUmAgYW5kIHNvbWUgb3RoZXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLiAgTW9zdGx5IGluIHRoaXMgY2xhc3MsIHdlIHdpbGwgZm9jdXMgb24gYFJgIGNvZGUgYW5kIHRoZXJlIGlzIGEga2V5Ym9hcmQgc2hvcnRjdXQgdG8gaW5zZXJ0IGEgY2h1bmsuXShodHRwczovL2xpdmUuc3RhdGljZmxpY2tyLmNvbS82NTUzNS81MDE2MjgzNzMxN19mNDhmNmEzNjljX29fZC5wbmcpCgohW1RoZSBSdW4gbWVudSBhbGxvd3MgeW91IHRvIGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIGRvY3VtZW50IGF0IHZhcmlvdXMgbGV2ZWxzIG9mIHNwZWNpZmljaXR5LiAgQXQgdGhlIG1vc3QgZ3JhbnVsYXIsIHlvdSBjYW4gcnVuIHRoZSBjdXJyZW50IGxpbmUgb2YgY29kZSB0aGF0IHRoZSBjdXJzb3IgaXMgc2l0dGluZyBvbi4gIEFib3ZlIHRoYXQsIHlvdSBjYW4gcnVuIGNodW5rcyBpbmRpdmlkdWFsbHkgb3IgYXMgYSBncm91cC5dKGh0dHBzOi8vbGl2ZS5zdGF0aWNmbGlja3IuY29tLzY1NTM1LzUwMTYyNTg5NzAxX2FjMjY1YzRlMmRfb19kLnBuZykKPGRpdiBjbGFzcz0iYm94LXJlZCI+UGxlYXNlIGdvIGJhY2sgYW5kIHJlYWQgYWJvdXQgY29kZSBjaHVua3MgYW5kIHJlc3RyaWN0aW9ucyB3aXRoaW4gZG9jdW1lbnRzIChhYm92ZSkuPC9kaXY+CgoKIVtUaGUgZG9jdW1lbnQgc3RydWN0dXJlIG1lbnUgYXQgdGhlIGJvdHRvbSBsZWZ0IG9mIHRoZSB3aW5kb3cgc2hvd3MgeW91IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGRvY3VtZW50IHlvdSBhcmUgbWFraW5nIGJhc2VkIHVwb24gaGVhZGVycyBhbmQgc2VjdGlvbnMgd2l0aGluIGl0Ll0oaHR0cHM6Ly9saXZlLnN0YXRpY2ZsaWNrci5jb20vNjU1MzUvNTAxNjI4MzczNzdfMGU3NDhjNjliMF9vX2QucG5nKQoKCgojIyMgUiBOb3RlYm9va3MKCkFuIGBSIE5vdGVib29rYCBpcyBhIHNwZWNpYWwga2luZCBvZiBNYXJrZG93biBkb2N1bWVudCwgd2hpY2ggd2Ugd2lsbCBiZSB1c2luZyBpbiB0aGlzIGNsYXNzLiAgSXQgYWRkcyAqYSBiaXQqIG9mIGludGVyYWN0aXZpdHkgdG8gdGhlIG5vcm1hbCBNYXJrZG93biBkb2N1bWVudHMuICBUaGUgZGlmZmVyZW5jZXMgYXJlOiAgCgoxLiBJbnN0ZWFkIG9mIGEgKktuaXQqIGJ1dHRvbiBhdCB0aGUgdG9wIG9mIHRoZSBwYWdlLCB0aGVyZSBpcyBhICpQcmV2aWV3KiBidXR0b24uICAKMS4gRXZlcnkgdGltZSB5b3Ugc2F2ZSB0aGUgZG9jdW1lbnQsIGFuIEhUTUwgdmVyc2lvbiBvZiB0aGUgZG9jdW1lbnQgd2lsbCBiZSByZW5kZXJlZCBpbiB0aGUgKipWaWV3ZXIqKiB0YWIgb2YgdGhlIFJTdHVkaW8gaW50ZXJmYWNlLiAgCjEuIFRoZSBvdXRwdXQgb2YgY29kZSBjaHVua3Mgd2l0aGluIHRoZSAqKlZpZXdlcioqIGZvciB0aGUgZG9jdW1lbnQgd2lsbCBzaG93IGV4YWN0bHkgdGhlIHNhbWUgb3V0cHV0IGFzIGlzIHJlbmRlcmVkIGluIHRoZSByYXcgbWFya2Rvd24gZG9jdW1lbnQuICBUaGlzIG1lYW5zIGlmIHlvdSBoYXZlIGNvZGUgYW5kIHRoZSBvdXRwdXQgaGFzIG5vdCBiZWVuIHJ1biwgaXQgd2lsbCBub3Qgc2hvdyB0aGF0IGluIHRoZSAqKlZpZXdlcioqLgoxLiBZb3UgY2FuIHNob3cgYW5kIGhpZGUgYWxsIHRoZSBjb2RlIGluIGEgbm90ZWJvb2sgdXNpbmcgdGhlIGJ1dHRvbiBhdCB0aGUgdG9wIG9mIHRoZSBwYWdlIG9yIG9uIGEgcGVyLWNodW5rIGJhc2lzLgoxLiBUaGUgSFRNTCBvdXRwdXQgb2YgdGhlIG5vdGVib29rIGFsc28gY29udGFpbnMgKmEgY29weSBvZiB0aGUgcm1kIGZpbGUqIHdpdGhpbiBpdC4gIFRoaXMgbWVhbnMgdGhhdCB3ZSBjYW4gcG9zdCBhIG5vdGVib29rIG9ubGluZSBhbmQgYSB2aWV3ZXIgY2FuIGRvd25sb2FkIHRoZSByYXcgbWFya2Rvd24gZm9yIHRoYXQgZG9jdW1lbnQgdG8gdGhlaXIgb3duIGNvbXB1dGVyIGFuZCBydW4gaXQgKGF0IHRoZSB0b3AgcmlnaHQgb2YgdGhpcyB2ZXJ5IGRvY3VtZW50IGlzIGEgYnV0dG9uIHRoYXQgaGFzIGFuIG9wdGlvbiB0byAqRG93bmxvYWQgUm1kKikuCgpGb3IgdGhlc2UgcmVhc29ucywgd2Ugd2lsbCBiZSB1c2luZyBub3RlYm9va3MgZm9yIHRoaXMgY2xhc3MuICAKCgoKW14xXTogVGhpcyBpcyBhIGZvb3Rub3RlIGFuZCBpcyBkZWZpbmVkIGJ5IGVuY2xvc2luZyBzcXVhcmUgYnJhY2tldHMgYW5kIGEgY2FyYXQgc3ltYm9sICgmIzk0Oykgd2hlcmUgeW91IHdhbnQgdG8gcHV0IHRoZSBmb290bm90ZSBpbiB0aGUgdGV4dCAoZS5nLiwgJiM5MTsmIzk0OzEmIzkzOykgYW5kIHRoZW4gYXQgdGhlIGJvdHRvbSBvZiB0aGUgZG9jdW1lbnQgYWRkIHRoZSB0ZXh0ICh0aGlzIHBhcnQpIHByZXBlbmRlZCBieSAmIzkxOyYjOTQ7MSYjOTM7JiM1ODsuICBUaGUgbGlua2luZyB0byB0aGUgZm9vdG5vdGUgYW5kIGJhY2sgdG8gdGhlIHBsYWNlIHlvdSBwdXQgaXQgd2lsbCBiZSBhdXRvbWFnaWNhbGx5IGluc2VydGVkLgo=