Section 1: The Process of Programming
A program doesn’t magically appear and run. It follows a systematic life cycle that begins with an idea and ends with execution. Let’s break this down step by step.
Programming Lifecycle
Think of a program as a recipe you want to cook. Just like you start by deciding what to cook, gathering ingredients, and then following the steps to prepare a dish, a program follows a similar life cycle:
Problem Definition: This is where you define the task you want the program to accomplish. For example, you might decide, “I want to calculate the average score of students in my class.”
Design: Here, you plan the structure of the program. This involves deciding the steps required to solve the problem. For our example, the steps might be:
- Collect the scores.
- Add all the scores together.
- Divide the total by the number of scores to find the average.
Programming: You write the program using a programming language like R. This is akin to writing down the recipe. Programming is also often referred to as “development” or as “coding”.
Execution: After coding the solution, you run the program. This is like cooking the recipe and seeing if the dish turns out as expected. Of course, execution is often very fast.
Testing and Debugging: Sometimes, the program doesn’t work perfectly the first time. You check for errors (bugs) and fix them. Imagine you forgot to add salt to your dish; you would taste it and adjust. You then return back to steps 2 and 3 and make adjustment and try again. Programming involves lots of experimentation and “trial and error”. It is an iterative process and not linear.
Maintenance: After the program works, you might need to update it or add features over time, just like modifying a recipe to improve it or adapt it to new ingredients.
Documentation: You need to document your program and how it works so it can be modified by others (which includes your future you in six months, a year, or in several years).
Programming Tools
Programming tools help you move through the life cycle efficiently. Let’s explore the main tools and their roles, using everyday analogies and visualizations.
Text Editor
A text editor is where you write your code. It’s like a notebook where you draft your ideas. While you could use any basic editor like Notepad on Windows or TextEdit on MacOS, specialized editors for programming provide helpful features, such as syntax highlighting (color-coding of your code) and error detection. Some of the common editors include Sublime, Notepad++, Vim, Visual Studio Code, and even fully terminal-based editors like emacs and vi.
In R, the Script Editor in RStudio is an example of a specialized text editor. When you write code in the Script Editor, you can save it, run it, and reuse it later. This editor is part of an integrated development environment (IDE) that includes tools for managing the files that are part of a project, tracking code changes, assisting with debugging, among many other useful features. Most modern programming is done within an IDE rather than just a text editor.
Execution
Execution is the process of running your code to see the results. When you write instructions in the Script Editor in RStudio, you need to have your computer execute them. There are two different ways this is done:
- compilation
- interpretation
In a “compiled” programming language like Java or C++, the code that is written in the editor (the “source code”) must first be compiled. Compilation is done by a special program called a compiler. Its purpose is to translate the source code into binary machine language instructions suitable for execution by the computer’s CPU. The machine language instructions are then linked together with libraries of operating system functions into an “executable” which can then be run (“executed”). The executable is specific for a particular operating system and CPU. For example, if you write a program in C++ using Notepad++, then compile it with the gcc compiler on your Mac having an M2 Apple CPU, the executable can only be run on that operating system with that type of CPU; you could not run that executable on a Windows computer with an Intel i7 CPU. Of course, you could take the C++ source code and compile it with a C++ compiler on Windows and get a Windows/Intel executable. The benefit of compiled programs and compiled language is that they run much faster. Most production data analytics and machine learning code is written in C++ or Java and compiled for Linux or specialized vector CPU’s such as those made Nvidia.
An alternative to compiled languages are interpreted languages. In an interpreted language, the code you write is “interpreted” and run line by line within an “interpreter”. Every language has its own interpreter. For R, you can download the interpreter from <r-project.org>. The benefit of an interpreted language is that is doesn’t require the compilation step and that you can experiment with the code. Development is often much faster, but the code executes much slower. Often, data analytics, experimenting, and algorithm development are done in R or Python and production code is then written in Java or C++.
For example, when you write the R code:
x <- 10
y <- 5
result <- x + y
print(result)
and click “Run,” each line is executed one by one. In fact, within the RStudio IDE you can explicitly run each line one by one. This very helpful for program development as you can see the intermediary results and inspect the values of variables. This makes programming much faster.
Tutorial / Installing R and Running R Scripts
The tutorial below shows how to install R (the programming language) and edit and execute simple R programs (aka scripts). In a later section, we will explain how to use an integrated development environment to make writing R programs simpler.
The R Programming Language
Let’s take a brief detour and talk a bit more about R – of course, lots more later, but it’s worthwhile to put R in perspective so the tutorials below will make more sense.
R is a programming language and software environment specifically designed for statistical computing, data analysis, and graphical representation of data. If you are venturing into the world of data analytics, R is one of the most powerful and versatile tools available, alongside Python.
R is both a language and a programming environment. As a language, it provides syntax and functions to perform complex statistical operations, create visualizations, and manipulate data. As a programming environment, it includes tools and resources, such as data handling capabilities and visualization libraries, that make data analysis more intuitive and efficient.
R was developed in the early 1990s by Ross Ihaka and Robert Gentleman at the University of Auckland. It was inspired by the S language, which was developed at Bell Laboratories. Unlike S, which was proprietary, R is open-source, meaning it’s free to use, and anyone can contribute to its development. This collaborative nature has helped R evolve rapidly, keeping it at the forefront of data analytics.
Think of R as a specialized toolkit for working with data. Just as a carpenter would use a hammer, saw, and chisel for woodwork, data analysts use R to process and interpret data. It’s designed with data in mind, so it excels at tasks like:
- Performing statistical calculations.
- Creating high-quality data visualizations.
- Handling large datasets with ease.
- Generating reproducible reports.
- Interacting with databases.
Unlike general-purpose programming languages like Python or Java, R is specifically built for statistical analysis, data analytics, data management, data visualization, machine learning, and data mining. This focus makes it particularly appealing to statisticians, data scientists, and researchers.
For example, imagine you have data on the sales performance of several products over a year. Using R, you can:
- Summarize the data to find the total sales for each product.
- Create a line chart to visualize sales trends over time.
- Perform a statistical test to determine whether sales increased significantly in the second half of the year.
All of this can be done efficiently using R’s built-in functions and packages.
Key Features of R
Statistical Power: R includes built-in functions for statistical operations like regression analysis, hypothesis testing, and clustering. For example, if you want to calculate the mean of a dataset, you can simply use:
data <- c(5, 10, 15, 20)
mean(data) # Output: 12.5
Data Visualization: R provides tools to create a wide variety of plots, from simple bar charts to complex multi-dimensional visualizations. Using the ggplot2
package, you can create elegant and informative graphs with minimal effort.
Extensive Package Ecosystem: R has thousands of user-contributed packages that extend its capabilities. For instance, the dplyr
package simplifies data manipulation, while shiny
allows you to build interactive web applications.
Reproducibility: With R, you can write scripts to automate data analysis tasks, ensuring consistency and reproducibility. This is particularly useful in research, where transparency and repeatability are essential.
Installing R and RStudio
To start using R, you need two main tools:
- R: The language itself. You can download it for free from CRAN, the Comprehensive R Archive Network. This is the “interpreter” that lets you run R code. It does include a simple user interface, but it’s really just the language run-time environment. To do actual programming, you need RStudio, but you must install R before installing the RStudio IDE.
- RStudio: A user-friendly interface (Integrated Development Environment or IDE) that makes working with R much easier. You can download RStudio Desktop for free from its [official website](https://posit.co/download/rstudio-desktop/. It is now called Posit because it supports more than just R; it also supports programming in Python and a number of other programming languages.
While R is the engine, RStudio is the dashboard that lets you interact with R more conveniently. Think of RStudio as a smartphone that makes the raw computing power of R accessible through a user-friendly interface.
The tutorial below guides you through the process of installing R and RStudio. As an alternative to installing the R programming language and the RStudio IDE, you can also create an account on the cloud service for RStudio: posit.cloud. Posit is run by RStudio and there are free plans available as well as inexpensive monthly educational subscriptions.
The RStudio Interface
When you open RStudio, you’ll notice several key panels:
- Console: This is where R executes commands. If you type
2 + 2
in the Console and press Enter, R will immediately output 4
.
- Script Editor: This is where you write and save longer pieces of code. For instance, if you want to analyze a dataset repeatedly, you can write a script in this panel and save it for future use.
- Environment: This panel shows all the variables, data, and objects currently in use. For example, if you create a dataset called
sales_data
, it will appear here.
- Plots Panel: When you create visualizations, they will appear in this panel. For example, if you plot a line graph of sales over time, you can view and export the graph here.
The tutorial below provides an overview of RStudio and its capabilities.
The real strength of R lies in its community. Thousands of developers and analysts contribute to its ecosystem, creating packages and resources that make it easier to tackle any data analysis challenge. Whether you’re performing simple descriptive statistics or building a predictive model, R has the tools to help you succeed.
Learning R may seem challenging at first, but it’s a skill that pays off immensely in the world of data analytics. With practice, you’ll find that R is not just a programming language — it’s a partner that empowers you to turn raw data into actionable insights. You will find R is easier to learn than most other programming languages and becoming proficient at R takes comparatively little time.
Tutorial I: Programming Lifecycle
The tutorial below by Khoury Boston’s Prof. Schedlbauer, demonstrates the program development lifecycle using a text editor and executing code written in R.
Integrated Development Environment (IDE)
An Integrated Development Environment (IDE) combines several tools into one interface to make programming easier. RStudio is an IDE specifically for R. It integrates a text editor, execution environment, debugging tools, and visualization panels in a single workspace.
Illustration: An IDE is like a fully equipped kitchen. Instead of having the oven, fridge, and sink scattered across different rooms, an IDE brings everything together in one space for convenience. RStudio’s Console, Script Editor, Environment panel, and Plots panel are like your oven, chopping board, spice rack, and serving area—everything you need to “cook” a program.
To summarize, programming follows a structured lifecycle: problem definition, design, coding, execution, testing, maintenance, and documentation. The lifecycle is not linear but rather iterative. It involves frequent trial-and-error. A text editor is where you write your code. Execution happens when a compiled program is executed or an interpreter carries out each instruction. An IDE like RStudio combines all tools (editor, execution, debugging, and program output) into one convenient workspace.
“Code is like humor. When you have to explain it, it’s bad.” – Cory House
Section 2: Introduction to Programming
Programming is the art and science of instructing a computer to perform specific tasks. At its core, it involves writing a set of instructions in a language the computer can understand. These instructions, collectively called a program, are executed by the computer to solve a problem or perform an action. Let’s explore this idea in detail, step by step. This form of programming is generally called procedural programming; it is one of many programming styles. Other programming styles and ways to organize program code are object-oriented programming, functional programming, and logic programming. Machine learning is considered a newer form of programming where an algorithm derives a pattern from data to make a prediction and produce a result rather than a programmer writing the instructions to arrive at the result.
Imagine you are teaching a robot to make a cup of tea. You can’t simply say, “Make tea” and expect the robot to understand. Instead, you would need to break down the task into a series of small, precise steps, perhaps such as these:
- Pick up the kettle.
- Fill it with water.
- Place the kettle on the stove.
- Turn on the stove.
- Wait for the water to boil.
Similarly, procedural programming is about breaking down a problem into logical, clear steps and expressing these steps in a language that the computer understands. Computers, unlike humans, cannot infer what you mean—they only do exactly what you tell them to do.
In this way, programming is like writing a recipe or an instruction manual: you are describing how to achieve a specific outcome using a sequence of precisely defined and ordered actions.
Programming is essential because computers are incredibly fast, accurate, and consistent, but only when given precise instructions. For example, imagine you have a dataset containing the sales figures for thousands of stores over a year, and you want to calculate the total revenue. Doing this manually would take days or weeks. With a program, this calculation can be completed in seconds.
For data analytics, programming is invaluable because it allows us to:
- Automate repetitive tasks, like cleaning data or generating reports.
- Analyze large datasets quickly and accurately.
- Create reproducible workflows, ensuring that results are consistent and can be verified.
Programming doesn’t just save time — it enables us to do things that would otherwise be impossible.
“I don’t need to program; I could just do it manually. But where’s the fun in not spending three hours writing a program to save ten minutes?” – Every Programmer
The R Programming Language
R is a programming language specifically designed for statistical computing and data visualization. It is widely used in data analytics because it simplifies many tasks that would be complex in other languages. For instance, R has built-in functions for calculating statistics, creating charts, and manipulating data, which makes it a perfect tool for beginners in data analytics.
Think of R as a specialized toolkit. Just as a carpenter has tools designed for woodwork, R provides tools tailored for working with data. These tools include functions for calculating averages, plotting trends, and summarizing datasets—all tasks that are central to the work of a data analyst.
Many data analytics professionals use R alongside Python as well as numerous specialized programming tools.
R originated as an open-source implementation of the S language, which was developed in the 1970s at Bell Laboratories (also known as AT&T Labs) by John Chambers and his team. The S language was designed for statistical computing and data analysis, but it was proprietary, limiting its accessibility.
In the early 1990s, Ross Ihaka and Robert Gentleman, two statisticians from the University of Auckland in New Zealand, began developing R as a free alternative to S. Their goal was to create a programming language that retained the flexibility and statistical power of S while being open-source and freely available to the academic community.
The first version of R was released to the public in 1995, and its popularity grew quickly among statisticians and data scientists. In 1997, the R Development Core Team was established to oversee its continued development, ensuring that R remained a collaborative, community-driven project.
Today, R is a global standard for statistical computing and data visualization, widely used in academia, industry, and government. Its open-source nature and extensive package ecosystem make it an indispensable tool for data analysis, research, experimentation, and discovery.
How Does Programming Work?
The process of programming involves writing, testing, and running code. Let’s explore this process through an analogy: Imagine you are designing a set of instructions for a delivery robot. Your goal is to program the robot to deliver a package to a specific address. The steps might look something like this:
- Write the instructions: “Leave the warehouse, walk straight for 500 meters, turn left, and stop at house number 25.”
- Test the instructions: Follow them yourself to ensure they are correct.
- Run the program: Give the instructions to the robot and observe its behavior.
If the robot delivers the package successfully, your program works. If it ends up at the wrong house, you would need to review and correct the instructions.
This same process applies to programming in R. You write code (the instructions), test it by running small parts of it, and then execute the full program to see the results. If it doesn’t deliver the correct result, you find where the error is (well, more likely errors), fix them (hopefully), and run the program again. Observe again, a repeat the process until the program provides the desired result and meets the needs (requirements) of its intended users. To be fair, no program is without any defects: every program contains bugs; the question really is how many defects are we willing to live with and tolerate.
Breaking Down a Simple Example
Let’s look at a simple programming example in R:
# Define numbers
x <- 10
y <- 5
# Calculate the sum
result <- x + y
# Print the result
print(result)
Here’s what happens step by step:
- Define numbers: The variables
x
and y
are like labeled containers that store the numbers 10 and 5, respectively.
- Calculate the sum: The program tells R to add the values in
x
and y
and store the result in a new variable called result
.
- Print the result: The program outputs the value stored in
result
, which is 15
.
Note that in R we can simply use a variable and that defines it and we got a container for values. Whatever value you assign to it determines what the “type” of the variable is, i.e., what kinds of things it can hold: text, numbers, dates, etc. Other programming languages have different rules for variables and how to define them; these are the rules for R.
Programming is Problem Solving
At its heart, programming is about solving problems. The computer acts as a tool to execute your solution. A simple problem might be, “How many hours are there in a week?” You could solve this manually, but in R, you would write:
# Calculate hours in a week
hours_per_day <- 24
days_per_week <- 7
hours_per_week <- hours_per_day * days_per_week
print(hours_per_week)
Here, the program calculates the answer (168
) for you. This process demonstrates how programming allows you to focus on defining the solution while the computer handles the drudgery of the calculations. Of course, this is a super trivial example, but imagine if the calculation involved many more numbers and was much more complicated – then you’d really appreciate having a computer do the drudgery of the calculations for you. Of course, until recently, “computers” were people (applied mathematicians, to be more precise) who were really good at numerical methods for doing complex calculations.
Why Do Errors Happen?
Errors, or “defects” or simply “bugs”, are a common part of programming: frustrating, but common They occur when the instructions are incomplete, ambiguous, or incorrect. For example, if you accidentally wrote:
hours_per_day <- 24
days_per_week <- 7
hours_per_week <- hours_per_day + days_per_week
print(hours_per_week)
The program would calculate 31
instead of 168
. This mistake highlights the importance of precision in programming. Debugging, or finding and fixing errors, is an essential skill that you will develop as you practice. It is being a sleuth: some programmers love debugging; they love the hunt and the dopamine shot one gets from finding an error – others abhor the process of debugging and come to hate the hours of wasted time finding some “stupid” typo or fault in logic.
It’s a Journey
In fact, programming is not just about writing code — it’s about thinking logically and solving problems systematically and methodically. As you begin your journey with programming and with R, remember that every program you write is an opportunity to learn. Mistakes are part of the process, and with practice, programming will become a powerful tool in your data analytics toolkit. Embrace the challenge, and enjoy the satisfaction that comes from making the computer do exactly what you want. You’ll also come to appreciate the beauty of well-written code and you will marvel at code written by “masters” of their craft. It is also neat to see code in different programming languages: find some and just try to decipher it.
“Learning to program is like learning to play an instrument: at first, it sounds terrible, but with practice, you’ll create something amazing.”
LS0tCnRpdGxlOiAiRnVuZGFtZW50YWxzIG9mIFByb2dyYW1taW5nOiBBbiBJbnRyb2R1Y3Rpb24gVXNpbmcgUiIKcGFyYW1zOgogIGNhdGVnb3J5OiAxCiAgbnVtYmVyOiAxMDAKICB0aW1lOiAxMjAKICBsZXZlbDogYmVnaW5uZXIKICB0YWdzOiAicixwcmltZXIscHJvZ3JhbW1pbmciCiAgZGVzY3JpcHRpb246ICJJbnRyb2R1Y2VzIGZvdWRhdGlvbnMgb2YgcHJvZ3JhbW1pbmcgdXNpbmcgUiBhcyB0aGUKICAgICAgICAgICAgICAgIHByb2dyYW1taW5nIGxhbmd1YWdlLCBhbHRob3VnaCBjb25jZXB0cyBjYW4gYmUgYXBwbGllZAogICAgICAgICAgICAgICAgdG8gYW55IHByb2dyYW1taW5nIGxhbmd1YWdlLiBGb2N1c2VzIG9uIHByb2NlZHVyYWwgcHJvZ3JhbW1pbmcKICAgICAgICAgICAgICAgIGJ1dCBkb2VzIGFsbHVkZSB0byBvdGhlciBzdHlsZXMgb2YgcHJvZ3JhbW1pbmcuIgpkYXRlOiAiPHNtYWxsPmByIFN5cy5EYXRlKClgPC9zbWFsbD4iCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiIKZW1haWw6ICJtLnNjaGVkbGJhdWVyQG5ldS5lZHUiCmFmZmlsaXRhdGlvbjogIk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogc3BhY2VsYWIKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgotLS0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiIKLS0tCgpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRX0KYGBgCgo+ICJUaGUgb25seSB3YXkgdG8gbGVhcm4gYSBuZXcgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgaXMgYnkgd3JpdGluZyBwcm9ncmFtcyBpbiBpdC4iIOKAkyBEZW5uaXMgUml0Y2hpZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBMZWFybmluZyBPdXRjb21lcwoKQnkgdGhlIGVuZCBvZiB0aGlzIGxlc3NvbiwgbGVhcm5lcnMgd2lsbCBiZSBhYmxlIHRvOgoKMS4gICoqVW5kZXJzdGFuZCBQcm9ncmFtbWluZyBGdW5kYW1lbnRhbHMqKgogICAgLSAgIERlc2NyaWJlIHRoZSBwdXJwb3NlIG9mIHByb2dyYW1taW5nIGluIGRhdGEgYW5hbHl0aWNzIGFuZCBleHBsYWluIHRoZSByb2xlIG9mIFIgYXMgYSBzdGF0aXN0aWNhbCBwcm9ncmFtbWluZyBsYW5ndWFnZS4KICAgIC0gICBOYXZpZ2F0ZSB0aGUgUlN0dWRpbyBpbnRlcmZhY2UsIGluY2x1ZGluZyB0aGUgQ29uc29sZSwgU2NyaXB0IEVkaXRvciwgRW52aXJvbm1lbnQsIGFuZCBQbG90cyBwYW5lcy4KMi4gICoqQXBwbHkgQmFzaWMgUiBTeW50YXgqKgogICAgLSAgIFBlcmZvcm0gYXJpdGhtZXRpYyBvcGVyYXRpb25zIGFuZCB1c2UgdGhlIGFzc2lnbm1lbnQgb3BlcmF0b3IgKGA8LWApIHRvIHN0b3JlIGFuZCBtYW5pcHVsYXRlIHZhbHVlcy4KICAgIC0gICBQcmludCBvdXRwdXQgYW5kIGV4ZWN1dGUgY29tbWFuZHMgaW50ZXJhY3RpdmVseSBpbiB0aGUgUiBjb25zb2xlLgozLiAgKipXb3JrIHdpdGggRGF0YSBUeXBlcyBhbmQgU3RydWN0dXJlcyoqCiAgICAtICAgSWRlbnRpZnkgYW5kIHdvcmsgd2l0aCBiYXNpYyBkYXRhIHR5cGVzIGluIFIsIGluY2x1ZGluZyBudW1lcmljLCBjaGFyYWN0ZXIsIGxvZ2ljYWwsIGFuZCBmYWN0b3IgdHlwZXMuCiAgICAtICAgQ29uc3RydWN0IGFuZCBtYW5pcHVsYXRlIGZ1bmRhbWVudGFsIGRhdGEgc3RydWN0dXJlcywgc3VjaCBhcyB2ZWN0b3JzLCBtYXRyaWNlcywgZGF0YSBmcmFtZXMsIGFuZCBsaXN0cy4KNC4gICoqQWNjZXNzIGFuZCBNb2RpZnkgRGF0YSoqCiAgICAtICAgVXNlIGluZGV4aW5nIHRvIGFjY2VzcyBlbGVtZW50cyBpbiB2ZWN0b3JzLCBtYXRyaWNlcywgYW5kIGRhdGEgZnJhbWVzLgogICAgLSAgIEVtcGxveSBjb2x1bW4gbmFtZXMgKGAkYCkgdG8gYWNjZXNzIGFuZCBtb2RpZnkgZGF0YSBpbiBkYXRhIGZyYW1lcy4KNS4gICoqSW1wbGVtZW50IENvbnRyb2wgU3RydWN0dXJlcyoqCiAgICAtICAgV3JpdGUgYW5kIGV4ZWN1dGUgY29uZGl0aW9uYWwgc3RhdGVtZW50cyAoYGlmYCwgYGVsc2VgKSB0byBtYWtlIGRlY2lzaW9ucyBpbiBjb2RlLgogICAgLSAgIFVzZSBsb29wcyAoYGZvcmAsIGB3aGlsZWApIHRvIGl0ZXJhdGUgb3ZlciBlbGVtZW50cyBpbiBkYXRhIHN0cnVjdHVyZXMuCjYuICAqKkNyZWF0ZSBhbmQgVXNlIEZ1bmN0aW9ucyoqCiAgICAtICAgRXhwbGFpbiB0aGUgcHVycG9zZSBvZiBmdW5jdGlvbnMgaW4gcHJvZ3JhbW1pbmcuCiAgICAtICAgVXRpbGl6ZSBidWlsdC1pbiBSIGZ1bmN0aW9ucyBmb3IgYmFzaWMgb3BlcmF0aW9ucyBhbmQgd3JpdGUgY3VzdG9tIGZ1bmN0aW9ucyB0byBwZXJmb3JtIHNwZWNpZmljIHRhc2tzLgo3LiAgKipJbXBvcnQsIEV4cG9ydCwgYW5kIE1hbmlwdWxhdGUgRGF0YSoqCiAgICAtICAgTG9hZCBkYXRhIGZyb20gZXh0ZXJuYWwgZmlsZXMgKGUuZy4sIENTVikgdXNpbmcgYHJlYWQuY3N2KClgIGFuZCBzYXZlIGRhdGEgdXNpbmcgYHdyaXRlLmNzdigpYC4KICAgIC0gICBQZXJmb3JtIGJhc2ljIGRhdGEgbWFuaXB1bGF0aW9ucyB1c2luZyBidWlsdC1pbiBmdW5jdGlvbnMgYW5kIHRoZSBgZHBseXJgIHBhY2thZ2UuCjguICAqKlZpc3VhbGl6ZSBEYXRhKioKICAgIC0gICBHZW5lcmF0ZSBiYXNpYyBwbG90cyB1c2luZyBgcGxvdCgpYCB0byBleHBsb3JlIHJlbGF0aW9uc2hpcHMgaW4gZGF0YS4KICAgIC0gICBDcmVhdGUgc2ltcGxlIHZpc3VhbGl6YXRpb25zIHdpdGggYGdncGxvdDJgLCBzdWNoIGFzIHNjYXR0ZXIgcGxvdHMsIHdoaWxlIGN1c3RvbWl6aW5nIGF4ZXMgYW5kIHRpdGxlcy4KOS4gICoqQXBwbHkgUHJvZ3JhbW1pbmcgU2tpbGxzIHRvIEFuYWx5dGljcyBQcm9ibGVtcyoqCiAgICAtICAgQ29tYmluZSBwcm9ncmFtbWluZyBjb25zdHJ1Y3RzIHRvIHNvbHZlIHNtYWxsLXNjYWxlIGRhdGEgYW5hbHl0aWNzIHRhc2tzLCBzdWNoIGFzIGZpbHRlcmluZyBkYXRhIG9yIHN1bW1hcml6aW5nIHN0YXRpc3RpY3MuCjEwLiAqKkRlbW9uc3RyYXRlIFByZXBhcmVkbmVzcyBmb3IgQWR2YW5jZWQgVG9waWNzKioKICAgIC0gICBFeGhpYml0IHJlYWRpbmVzcyB0byBhZHZhbmNlIHRvIG1vcmUgY29tcGxleCBwcm9ncmFtbWluZyBjb25jZXB0cywgaW5jbHVkaW5nIHN0YXRpc3RpY2FsIG1vZGVsaW5nLCBhZHZhbmNlZCBkYXRhIHdyYW5nbGluZywgYW5kIGludGVyYWN0aXZlIHZpc3VhbGl6YXRpb25zLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBPdmVydmlldwoKVGhpcyBpbnRyb2R1Y3RvcnkgbGVzc29uIGlzIGludGVuZGVkIHRvIHByZXBhcmUgbGVhcm5lcnMsIHdobyBoYXZlIG5vIHByaW9yIHByb2dyYW1taW5nIGV4cGVyaWVuY2UsIGZvciBjb21wdXRhdGlvbmFsIGRhdGEgYW5hbHl0aWNzIC4gVGhlIGxlc3NvbiB1c2VzIFIgYXMgdGhlIHByaW1hcnkgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UsIHByb3ZpZGluZyBmb3VuZGF0aW9uYWwgc2tpbGxzIHRoYXQgd2lsbCBzdXBwb3J0IG1vcmUgYWR2YW5jZWQgbGVzc29ucyBvbiBwcm9ncmFtbWluZyBhbmQgUi4gVGhlIGZvY3VzIHdpbGwgYmUgb24gdW5kZXJzdGFuZGluZyBwcm9ncmFtbWluZyBjb25jZXB0cywgdXNpbmcgUiBzeW50YXgsIGFuZCBhcHBseWluZyBiYXNpYyBza2lsbHMgdG8gc29sdmUgc2ltcGxlIGRhdGEgYW5hbHl0aWNzIHByb2JsZW1zIG1ha2luZyB0aGUgc2tpbGxzIGFjcXVpcmVkIHRyYW5zZmVycmFibGUgdG8gb3RoZXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIHN1Y2ggYXMgUHl0aG9uLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBTZWN0aW9uIDE6IFRoZSBQcm9jZXNzIG9mIFByb2dyYW1taW5nCgpBIHByb2dyYW0gZG9lc27igJl0IG1hZ2ljYWxseSBhcHBlYXIgYW5kIHJ1bi4gSXQgZm9sbG93cyBhIHN5c3RlbWF0aWMgKipsaWZlIGN5Y2xlKiogdGhhdCBiZWdpbnMgd2l0aCBhbiBpZGVhIGFuZCBlbmRzIHdpdGggZXhlY3V0aW9uLiBMZXTigJlzIGJyZWFrIHRoaXMgZG93biBzdGVwIGJ5IHN0ZXAuCgojIyMgUHJvZ3JhbW1pbmcgTGlmZWN5Y2xlCgpUaGluayBvZiBhIHByb2dyYW0gYXMgYSByZWNpcGUgeW91IHdhbnQgdG8gY29vay4gSnVzdCBsaWtlIHlvdSBzdGFydCBieSBkZWNpZGluZyB3aGF0IHRvIGNvb2ssIGdhdGhlcmluZyBpbmdyZWRpZW50cywgYW5kIHRoZW4gZm9sbG93aW5nIHRoZSBzdGVwcyB0byBwcmVwYXJlIGEgZGlzaCwgYSBwcm9ncmFtIGZvbGxvd3MgYSBzaW1pbGFyIGxpZmUgY3ljbGU6CgoxLiAgKipQcm9ibGVtIERlZmluaXRpb24qKjogVGhpcyBpcyB3aGVyZSB5b3UgZGVmaW5lIHRoZSB0YXNrIHlvdSB3YW50IHRoZSBwcm9ncmFtIHRvIGFjY29tcGxpc2guIEZvciBleGFtcGxlLCB5b3UgbWlnaHQgZGVjaWRlLCAiSSB3YW50IHRvIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBzY29yZSBvZiBzdHVkZW50cyBpbiBteSBjbGFzcy4iCgoyLiAgKipEZXNpZ24qKjogSGVyZSwgeW91IHBsYW4gdGhlIHN0cnVjdHVyZSBvZiB0aGUgcHJvZ3JhbS4gVGhpcyBpbnZvbHZlcyBkZWNpZGluZyB0aGUgc3RlcHMgcmVxdWlyZWQgdG8gc29sdmUgdGhlIHByb2JsZW0uIEZvciBvdXIgZXhhbXBsZSwgdGhlIHN0ZXBzIG1pZ2h0IGJlOgoKICAgIC0gICBDb2xsZWN0IHRoZSBzY29yZXMuCiAgICAtICAgQWRkIGFsbCB0aGUgc2NvcmVzIHRvZ2V0aGVyLgogICAgLSAgIERpdmlkZSB0aGUgdG90YWwgYnkgdGhlIG51bWJlciBvZiBzY29yZXMgdG8gZmluZCB0aGUgYXZlcmFnZS4KCjMuICAqKlByb2dyYW1taW5nKio6IFlvdSB3cml0ZSB0aGUgcHJvZ3JhbSB1c2luZyBhIHByb2dyYW1taW5nIGxhbmd1YWdlIGxpa2UgUi4gVGhpcyBpcyBha2luIHRvIHdyaXRpbmcgZG93biB0aGUgcmVjaXBlLiBQcm9ncmFtbWluZyBpcyBhbHNvIG9mdGVuIHJlZmVycmVkIHRvIGFzICJkZXZlbG9wbWVudCIgb3IgYXMgImNvZGluZyIuCgo0LiAgKipFeGVjdXRpb24qKjogQWZ0ZXIgY29kaW5nIHRoZSBzb2x1dGlvbiwgeW91IHJ1biB0aGUgcHJvZ3JhbS4gVGhpcyBpcyBsaWtlIGNvb2tpbmcgdGhlIHJlY2lwZSBhbmQgc2VlaW5nIGlmIHRoZSBkaXNoIHR1cm5zIG91dCBhcyBleHBlY3RlZC4gT2YgY291cnNlLCBleGVjdXRpb24gaXMgb2Z0ZW4gdmVyeSBmYXN0LgoKNS4gICoqVGVzdGluZyBhbmQgRGVidWdnaW5nKio6IFNvbWV0aW1lcywgdGhlIHByb2dyYW0gZG9lc27igJl0IHdvcmsgcGVyZmVjdGx5IHRoZSBmaXJzdCB0aW1lLiBZb3UgY2hlY2sgZm9yIGVycm9ycyAoYnVncykgYW5kIGZpeCB0aGVtLiBJbWFnaW5lIHlvdSBmb3Jnb3QgdG8gYWRkIHNhbHQgdG8geW91ciBkaXNoOyB5b3Ugd291bGQgdGFzdGUgaXQgYW5kIGFkanVzdC4gWW91IHRoZW4gcmV0dXJuIGJhY2sgdG8gc3RlcHMgMiBhbmQgMyBhbmQgbWFrZSBhZGp1c3RtZW50IGFuZCB0cnkgYWdhaW4uIFByb2dyYW1taW5nIGludm9sdmVzIGxvdHMgb2YgZXhwZXJpbWVudGF0aW9uIGFuZCAidHJpYWwgYW5kIGVycm9yIi4gSXQgaXMgYW4gaXRlcmF0aXZlIHByb2Nlc3MgYW5kIG5vdCBsaW5lYXIuCgo2LiAgKipNYWludGVuYW5jZSoqOiBBZnRlciB0aGUgcHJvZ3JhbSB3b3JrcywgeW91IG1pZ2h0IG5lZWQgdG8gdXBkYXRlIGl0IG9yIGFkZCBmZWF0dXJlcyBvdmVyIHRpbWUsIGp1c3QgbGlrZSBtb2RpZnlpbmcgYSByZWNpcGUgdG8gaW1wcm92ZSBpdCBvciBhZGFwdCBpdCB0byBuZXcgaW5ncmVkaWVudHMuCgo3LiAgKipEb2N1bWVudGF0aW9uKio6IFlvdSBuZWVkIHRvIGRvY3VtZW50IHlvdXIgcHJvZ3JhbSBhbmQgaG93IGl0IHdvcmtzIHNvIGl0IGNhbiBiZSBtb2RpZmllZCBieSBvdGhlcnMgKHdoaWNoIGluY2x1ZGVzIHlvdXIgZnV0dXJlIHlvdSBpbiBzaXggbW9udGhzLCBhIHllYXIsIG9yIGluIHNldmVyYWwgeWVhcnMpLgoKIyMjIFByb2dyYW1taW5nIFRvb2xzCgpQcm9ncmFtbWluZyB0b29scyBoZWxwIHlvdSBtb3ZlIHRocm91Z2ggdGhlIGxpZmUgY3ljbGUgZWZmaWNpZW50bHkuIExldOKAmXMgZXhwbG9yZSB0aGUgbWFpbiB0b29scyBhbmQgdGhlaXIgcm9sZXMsIHVzaW5nIGV2ZXJ5ZGF5IGFuYWxvZ2llcyBhbmQgdmlzdWFsaXphdGlvbnMuCgoqKlRleHQgRWRpdG9yKioKCkEgKip0ZXh0IGVkaXRvcioqIGlzIHdoZXJlIHlvdSB3cml0ZSB5b3VyIGNvZGUuIEl04oCZcyBsaWtlIGEgbm90ZWJvb2sgd2hlcmUgeW91IGRyYWZ0IHlvdXIgaWRlYXMuIFdoaWxlIHlvdSBjb3VsZCB1c2UgYW55IGJhc2ljIGVkaXRvciBsaWtlIE5vdGVwYWQgb24gV2luZG93cyBvciBUZXh0RWRpdCBvbiBNYWNPUywgc3BlY2lhbGl6ZWQgZWRpdG9ycyBmb3IgcHJvZ3JhbW1pbmcgcHJvdmlkZSBoZWxwZnVsIGZlYXR1cmVzLCBzdWNoIGFzIHN5bnRheCBoaWdobGlnaHRpbmcgKGNvbG9yLWNvZGluZyBvZiB5b3VyIGNvZGUpIGFuZCBlcnJvciBkZXRlY3Rpb24uIFNvbWUgb2YgdGhlIGNvbW1vbiBlZGl0b3JzIGluY2x1ZGUgKlN1YmxpbWUqLCAqTm90ZXBhZCsrKiwgKlZpbSosICpWaXN1YWwgU3R1ZGlvIENvZGUqLCBhbmQgZXZlbiBmdWxseSB0ZXJtaW5hbC1iYXNlZCBlZGl0b3JzIGxpa2UgKmVtYWNzKiBhbmQgKnZpKi4KCkluIFIsIHRoZSBTY3JpcHQgRWRpdG9yIGluIFJTdHVkaW8gaXMgYW4gZXhhbXBsZSBvZiBhIHNwZWNpYWxpemVkIHRleHQgZWRpdG9yLiBXaGVuIHlvdSB3cml0ZSBjb2RlIGluIHRoZSBTY3JpcHQgRWRpdG9yLCB5b3UgY2FuIHNhdmUgaXQsIHJ1biBpdCwgYW5kIHJldXNlIGl0IGxhdGVyLiBUaGlzIGVkaXRvciBpcyBwYXJ0IG9mIGFuIGludGVncmF0ZWQgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnQgKElERSkgdGhhdCBpbmNsdWRlcyB0b29scyBmb3IgbWFuYWdpbmcgdGhlIGZpbGVzIHRoYXQgYXJlIHBhcnQgb2YgYSBwcm9qZWN0LCB0cmFja2luZyBjb2RlIGNoYW5nZXMsIGFzc2lzdGluZyB3aXRoIGRlYnVnZ2luZywgYW1vbmcgbWFueSBvdGhlciB1c2VmdWwgZmVhdHVyZXMuIE1vc3QgbW9kZXJuIHByb2dyYW1taW5nIGlzIGRvbmUgd2l0aGluIGFuIElERSByYXRoZXIgdGhhbiBqdXN0IGEgdGV4dCBlZGl0b3IuCgoqKkV4ZWN1dGlvbioqCgpFeGVjdXRpb24gaXMgdGhlIHByb2Nlc3Mgb2YgcnVubmluZyB5b3VyIGNvZGUgdG8gc2VlIHRoZSByZXN1bHRzLiBXaGVuIHlvdSB3cml0ZSBpbnN0cnVjdGlvbnMgaW4gdGhlIFNjcmlwdCBFZGl0b3IgaW4gUlN0dWRpbywgeW91IG5lZWQgdG8gaGF2ZSB5b3VyIGNvbXB1dGVyIGV4ZWN1dGUgdGhlbS4gVGhlcmUgYXJlIHR3byBkaWZmZXJlbnQgd2F5cyB0aGlzIGlzIGRvbmU6CgotICAgY29tcGlsYXRpb24KLSAgIGludGVycHJldGF0aW9uCgpJbiBhICJjb21waWxlZCIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgbGlrZSBKYXZhIG9yIEMrKywgdGhlIGNvZGUgdGhhdCBpcyB3cml0dGVuIGluIHRoZSBlZGl0b3IgKHRoZSAic291cmNlIGNvZGUiKSBtdXN0IGZpcnN0IGJlICpjb21waWxlZCouIENvbXBpbGF0aW9uIGlzIGRvbmUgYnkgYSBzcGVjaWFsIHByb2dyYW0gY2FsbGVkIGEgKmNvbXBpbGVyKi4gSXRzIHB1cnBvc2UgaXMgdG8gdHJhbnNsYXRlIHRoZSBzb3VyY2UgY29kZSBpbnRvIGJpbmFyeSBtYWNoaW5lIGxhbmd1YWdlIGluc3RydWN0aW9ucyBzdWl0YWJsZSBmb3IgZXhlY3V0aW9uIGJ5IHRoZSBjb21wdXRlcidzICpDUFUqLiBUaGUgbWFjaGluZSBsYW5ndWFnZSBpbnN0cnVjdGlvbnMgYXJlIHRoZW4gbGlua2VkIHRvZ2V0aGVyIHdpdGggbGlicmFyaWVzIG9mIG9wZXJhdGluZyBzeXN0ZW0gZnVuY3Rpb25zIGludG8gYW4gImV4ZWN1dGFibGUiIHdoaWNoIGNhbiB0aGVuIGJlIHJ1biAoImV4ZWN1dGVkIikuIFRoZSBleGVjdXRhYmxlIGlzIHNwZWNpZmljIGZvciBhIHBhcnRpY3VsYXIgb3BlcmF0aW5nIHN5c3RlbSBhbmQgQ1BVLiBGb3IgZXhhbXBsZSwgaWYgeW91IHdyaXRlIGEgcHJvZ3JhbSBpbiBDKysgdXNpbmcgTm90ZXBhZCsrLCB0aGVuIGNvbXBpbGUgaXQgd2l0aCB0aGUgKmdjYyogY29tcGlsZXIgb24geW91ciBNYWMgaGF2aW5nIGFuIE0yIEFwcGxlIENQVSwgdGhlIGV4ZWN1dGFibGUgY2FuIG9ubHkgYmUgcnVuIG9uIHRoYXQgb3BlcmF0aW5nIHN5c3RlbSB3aXRoIHRoYXQgdHlwZSBvZiBDUFU7IHlvdSBjb3VsZCBub3QgcnVuIHRoYXQgZXhlY3V0YWJsZSBvbiBhIFdpbmRvd3MgY29tcHV0ZXIgd2l0aCBhbiBJbnRlbCBpNyBDUFUuIE9mIGNvdXJzZSwgeW91IGNvdWxkIHRha2UgdGhlIEMrKyBzb3VyY2UgY29kZSBhbmQgY29tcGlsZSBpdCB3aXRoIGEgQysrIGNvbXBpbGVyIG9uIFdpbmRvd3MgYW5kIGdldCBhIFdpbmRvd3MvSW50ZWwgZXhlY3V0YWJsZS4gVGhlIGJlbmVmaXQgb2YgY29tcGlsZWQgcHJvZ3JhbXMgYW5kIGNvbXBpbGVkIGxhbmd1YWdlIGlzIHRoYXQgdGhleSBydW4gbXVjaCBmYXN0ZXIuIE1vc3QgcHJvZHVjdGlvbiBkYXRhIGFuYWx5dGljcyBhbmQgbWFjaGluZSBsZWFybmluZyBjb2RlIGlzIHdyaXR0ZW4gaW4gQysrIG9yIEphdmEgYW5kIGNvbXBpbGVkIGZvciBMaW51eCBvciBzcGVjaWFsaXplZCB2ZWN0b3IgQ1BVJ3Mgc3VjaCBhcyB0aG9zZSBtYWRlIE52aWRpYS4KCkFuIGFsdGVybmF0aXZlIHRvIGNvbXBpbGVkIGxhbmd1YWdlcyBhcmUgaW50ZXJwcmV0ZWQgbGFuZ3VhZ2VzLiBJbiBhbiBpbnRlcnByZXRlZCBsYW5ndWFnZSwgdGhlIGNvZGUgeW91IHdyaXRlIGlzICJpbnRlcnByZXRlZCIgYW5kIHJ1biBsaW5lIGJ5IGxpbmUgd2l0aGluIGFuICJpbnRlcnByZXRlciIuIEV2ZXJ5IGxhbmd1YWdlIGhhcyBpdHMgb3duIGludGVycHJldGVyLiBGb3IgUiwgeW91IGNhbiBkb3dubG9hZCB0aGUgaW50ZXJwcmV0ZXIgZnJvbSBcPHItcHJvamVjdC5vcmdcPi4gVGhlIGJlbmVmaXQgb2YgYW4gaW50ZXJwcmV0ZWQgbGFuZ3VhZ2UgaXMgdGhhdCBpcyBkb2Vzbid0IHJlcXVpcmUgdGhlIGNvbXBpbGF0aW9uIHN0ZXAgYW5kIHRoYXQgeW91IGNhbiBleHBlcmltZW50IHdpdGggdGhlIGNvZGUuIERldmVsb3BtZW50IGlzIG9mdGVuIG11Y2ggZmFzdGVyLCBidXQgdGhlIGNvZGUgZXhlY3V0ZXMgbXVjaCBzbG93ZXIuIE9mdGVuLCBkYXRhIGFuYWx5dGljcywgZXhwZXJpbWVudGluZywgYW5kIGFsZ29yaXRobSBkZXZlbG9wbWVudCBhcmUgZG9uZSBpbiBSIG9yIFB5dGhvbiBhbmQgcHJvZHVjdGlvbiBjb2RlIGlzIHRoZW4gd3JpdHRlbiBpbiBKYXZhIG9yIEMrKy4KCkZvciBleGFtcGxlLCB3aGVuIHlvdSB3cml0ZSB0aGUgUiBjb2RlOgoKYGBgIHIKeCA8LSAxMAp5IDwtIDUKcmVzdWx0IDwtIHggKyB5CnByaW50KHJlc3VsdCkKYGBgCgphbmQgY2xpY2sgIlJ1biwiIGVhY2ggbGluZSBpcyBleGVjdXRlZCBvbmUgYnkgb25lLiBJbiBmYWN0LCB3aXRoaW4gdGhlIFJTdHVkaW8gSURFIHlvdSBjYW4gZXhwbGljaXRseSBydW4gZWFjaCBsaW5lIG9uZSBieSBvbmUuIFRoaXMgdmVyeSBoZWxwZnVsIGZvciBwcm9ncmFtIGRldmVsb3BtZW50IGFzIHlvdSBjYW4gc2VlIHRoZSBpbnRlcm1lZGlhcnkgcmVzdWx0cyBhbmQgaW5zcGVjdCB0aGUgdmFsdWVzIG9mIHZhcmlhYmxlcy4gVGhpcyBtYWtlcyBwcm9ncmFtbWluZyBtdWNoIGZhc3Rlci4KCiMjIyMgVHV0b3JpYWwgLyBJbnN0YWxsaW5nIFIgYW5kIFJ1bm5pbmcgUiBTY3JpcHRzCgpUaGUgdHV0b3JpYWwgYmVsb3cgc2hvd3MgaG93IHRvIGluc3RhbGwgUiAodGhlIHByb2dyYW1taW5nIGxhbmd1YWdlKSBhbmQgZWRpdCBhbmQgZXhlY3V0ZSBzaW1wbGUgUiBwcm9ncmFtcyAoKmFrYSogc2NyaXB0cykuIEluIGEgbGF0ZXIgc2VjdGlvbiwgd2Ugd2lsbCBleHBsYWluIGhvdyB0byB1c2UgYW4gaW50ZWdyYXRlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCB0byBtYWtlIHdyaXRpbmcgUiBwcm9ncmFtcyBzaW1wbGVyLgoKOjo6IHtzdHlsZT0icGFkZGluZzo3Mi4wNSUgMCAwIDA7cG9zaXRpb246cmVsYXRpdmU7In0KPGlmcmFtZSBzcmM9Imh0dHBzOi8vcGxheWVyLnZpbWVvLmNvbS92aWRlby85ODk2MTA0NjA/YmFkZ2U9MCZhbXA7YXV0b3BhdXNlPTAmYW1wO3BsYXllcl9pZD0wJmFtcDthcHBfaWQ9NTg0NzkiIGZyYW1lYm9yZGVyPSIwIiBhbGxvdz0iYXV0b3BsYXk7IGZ1bGxzY3JlZW47IHBpY3R1cmUtaW4tcGljdHVyZTsgY2xpcGJvYXJkLXdyaXRlIiBzdHlsZT0icG9zaXRpb246YWJzb2x1dGU7dG9wOjA7bGVmdDowO3dpZHRoOjEwMCU7aGVpZ2h0OjEwMCU7IiB0aXRsZT0iSW5zdGFsbCBSLCBSIENvbnNvbGUsIFNjcmlwdHMiPgoKPC9pZnJhbWU+Cjo6OgoKPHNjcmlwdCBzcmM9Imh0dHBzOi8vcGxheWVyLnZpbWVvLmNvbS9hcGkvcGxheWVyLmpzIj48L3NjcmlwdD4KCiMjIyBUaGUgUiBQcm9ncmFtbWluZyBMYW5ndWFnZQoKTGV0J3MgdGFrZSBhIGJyaWVmIGRldG91ciBhbmQgdGFsayBhIGJpdCBtb3JlIGFib3V0IFIgLS0gb2YgY291cnNlLCBsb3RzIG1vcmUgbGF0ZXIsIGJ1dCBpdCdzIHdvcnRod2hpbGUgdG8gcHV0IFIgaW4gcGVyc3BlY3RpdmUgc28gdGhlIHR1dG9yaWFscyBiZWxvdyB3aWxsIG1ha2UgbW9yZSBzZW5zZS4KClIgaXMgYSBwcm9ncmFtbWluZyBsYW5ndWFnZSBhbmQgc29mdHdhcmUgZW52aXJvbm1lbnQgc3BlY2lmaWNhbGx5IGRlc2lnbmVkIGZvciBzdGF0aXN0aWNhbCBjb21wdXRpbmcsIGRhdGEgYW5hbHlzaXMsIGFuZCBncmFwaGljYWwgcmVwcmVzZW50YXRpb24gb2YgZGF0YS4gSWYgeW91IGFyZSB2ZW50dXJpbmcgaW50byB0aGUgd29ybGQgb2YgZGF0YSBhbmFseXRpY3MsIFIgaXMgb25lIG9mIHRoZSBtb3N0IHBvd2VyZnVsIGFuZCB2ZXJzYXRpbGUgdG9vbHMgYXZhaWxhYmxlLCBhbG9uZ3NpZGUgUHl0aG9uLgoKUiBpcyBib3RoIGEgbGFuZ3VhZ2UgYW5kIGEgcHJvZ3JhbW1pbmcgZW52aXJvbm1lbnQuIEFzIGEgKipsYW5ndWFnZSoqLCBpdCBwcm92aWRlcyBzeW50YXggYW5kIGZ1bmN0aW9ucyB0byBwZXJmb3JtIGNvbXBsZXggc3RhdGlzdGljYWwgb3BlcmF0aW9ucywgY3JlYXRlIHZpc3VhbGl6YXRpb25zLCBhbmQgbWFuaXB1bGF0ZSBkYXRhLiBBcyBhICoqcHJvZ3JhbW1pbmcgZW52aXJvbm1lbnQqKiwgaXQgaW5jbHVkZXMgdG9vbHMgYW5kIHJlc291cmNlcywgc3VjaCBhcyBkYXRhIGhhbmRsaW5nIGNhcGFiaWxpdGllcyBhbmQgdmlzdWFsaXphdGlvbiBsaWJyYXJpZXMsIHRoYXQgbWFrZSBkYXRhIGFuYWx5c2lzIG1vcmUgaW50dWl0aXZlIGFuZCBlZmZpY2llbnQuCgpSIHdhcyBkZXZlbG9wZWQgaW4gdGhlIGVhcmx5IDE5OTBzIGJ5IFJvc3MgSWhha2EgYW5kIFJvYmVydCBHZW50bGVtYW4gYXQgdGhlIFVuaXZlcnNpdHkgb2YgQXVja2xhbmQuIEl0IHdhcyBpbnNwaXJlZCBieSB0aGUgUyBsYW5ndWFnZSwgd2hpY2ggd2FzIGRldmVsb3BlZCBhdCBCZWxsIExhYm9yYXRvcmllcy4gVW5saWtlIFMsIHdoaWNoIHdhcyBwcm9wcmlldGFyeSwgUiBpcyBvcGVuLXNvdXJjZSwgbWVhbmluZyBpdOKAmXMgZnJlZSB0byB1c2UsIGFuZCBhbnlvbmUgY2FuIGNvbnRyaWJ1dGUgdG8gaXRzIGRldmVsb3BtZW50LiBUaGlzIGNvbGxhYm9yYXRpdmUgbmF0dXJlIGhhcyBoZWxwZWQgUiBldm9sdmUgcmFwaWRseSwga2VlcGluZyBpdCBhdCB0aGUgZm9yZWZyb250IG9mIGRhdGEgYW5hbHl0aWNzLgoKVGhpbmsgb2YgUiBhcyBhIHNwZWNpYWxpemVkIHRvb2xraXQgZm9yIHdvcmtpbmcgd2l0aCBkYXRhLiBKdXN0IGFzIGEgY2FycGVudGVyIHdvdWxkIHVzZSBhIGhhbW1lciwgc2F3LCBhbmQgY2hpc2VsIGZvciB3b29kd29yaywgZGF0YSBhbmFseXN0cyB1c2UgUiB0byBwcm9jZXNzIGFuZCBpbnRlcnByZXQgZGF0YS4gSXTigJlzIGRlc2lnbmVkIHdpdGggZGF0YSBpbiBtaW5kLCBzbyBpdCBleGNlbHMgYXQgdGFza3MgbGlrZToKCi0gICBQZXJmb3JtaW5nIHN0YXRpc3RpY2FsIGNhbGN1bGF0aW9ucy4KLSAgIENyZWF0aW5nIGhpZ2gtcXVhbGl0eSBkYXRhIHZpc3VhbGl6YXRpb25zLgotICAgSGFuZGxpbmcgbGFyZ2UgZGF0YXNldHMgd2l0aCBlYXNlLgotICAgR2VuZXJhdGluZyByZXByb2R1Y2libGUgcmVwb3J0cy4KLSAgIEludGVyYWN0aW5nIHdpdGggZGF0YWJhc2VzLgoKVW5saWtlIGdlbmVyYWwtcHVycG9zZSBwcm9ncmFtbWluZyBsYW5ndWFnZXMgbGlrZSBQeXRob24gb3IgSmF2YSwgUiBpcyBzcGVjaWZpY2FsbHkgYnVpbHQgZm9yIHN0YXRpc3RpY2FsIGFuYWx5c2lzLCBkYXRhIGFuYWx5dGljcywgZGF0YSBtYW5hZ2VtZW50LCBkYXRhIHZpc3VhbGl6YXRpb24sIG1hY2hpbmUgbGVhcm5pbmcsIGFuZCBkYXRhIG1pbmluZy4gVGhpcyBmb2N1cyBtYWtlcyBpdCBwYXJ0aWN1bGFybHkgYXBwZWFsaW5nIHRvIHN0YXRpc3RpY2lhbnMsIGRhdGEgc2NpZW50aXN0cywgYW5kIHJlc2VhcmNoZXJzLgoKRm9yIGV4YW1wbGUsIGltYWdpbmUgeW91IGhhdmUgZGF0YSBvbiB0aGUgc2FsZXMgcGVyZm9ybWFuY2Ugb2Ygc2V2ZXJhbCBwcm9kdWN0cyBvdmVyIGEgeWVhci4gVXNpbmcgUiwgeW91IGNhbjoKCjEuICBTdW1tYXJpemUgdGhlIGRhdGEgdG8gZmluZCB0aGUgdG90YWwgc2FsZXMgZm9yIGVhY2ggcHJvZHVjdC4KMi4gIENyZWF0ZSBhIGxpbmUgY2hhcnQgdG8gdmlzdWFsaXplIHNhbGVzIHRyZW5kcyBvdmVyIHRpbWUuCjMuICBQZXJmb3JtIGEgc3RhdGlzdGljYWwgdGVzdCB0byBkZXRlcm1pbmUgd2hldGhlciBzYWxlcyBpbmNyZWFzZWQgc2lnbmlmaWNhbnRseSBpbiB0aGUgc2Vjb25kIGhhbGYgb2YgdGhlIHllYXIuCgpBbGwgb2YgdGhpcyBjYW4gYmUgZG9uZSBlZmZpY2llbnRseSB1c2luZyBS4oCZcyBidWlsdC1pbiBmdW5jdGlvbnMgYW5kIHBhY2thZ2VzLgoKIyMjIyBLZXkgRmVhdHVyZXMgb2YgUgoKMS4gICoqU3RhdGlzdGljYWwgUG93ZXIqKjogUiBpbmNsdWRlcyBidWlsdC1pbiBmdW5jdGlvbnMgZm9yIHN0YXRpc3RpY2FsIG9wZXJhdGlvbnMgbGlrZSByZWdyZXNzaW9uIGFuYWx5c2lzLCBoeXBvdGhlc2lzIHRlc3RpbmcsIGFuZCBjbHVzdGVyaW5nLiBGb3IgZXhhbXBsZSwgaWYgeW91IHdhbnQgdG8gY2FsY3VsYXRlIHRoZSBtZWFuIG9mIGEgZGF0YXNldCwgeW91IGNhbiBzaW1wbHkgdXNlOgoKICAgIGBgYCByCiAgICBkYXRhIDwtIGMoNSwgMTAsIDE1LCAyMCkKICAgIG1lYW4oZGF0YSkgICMgT3V0cHV0OiAxMi41CiAgICBgYGAKCjIuICAqKkRhdGEgVmlzdWFsaXphdGlvbioqOiBSIHByb3ZpZGVzIHRvb2xzIHRvIGNyZWF0ZSBhIHdpZGUgdmFyaWV0eSBvZiBwbG90cywgZnJvbSBzaW1wbGUgYmFyIGNoYXJ0cyB0byBjb21wbGV4IG11bHRpLWRpbWVuc2lvbmFsIHZpc3VhbGl6YXRpb25zLiBVc2luZyB0aGUgYGdncGxvdDJgIHBhY2thZ2UsIHlvdSBjYW4gY3JlYXRlIGVsZWdhbnQgYW5kIGluZm9ybWF0aXZlIGdyYXBocyB3aXRoIG1pbmltYWwgZWZmb3J0LgoKMy4gICoqRXh0ZW5zaXZlIFBhY2thZ2UgRWNvc3lzdGVtKio6IFIgaGFzIHRob3VzYW5kcyBvZiB1c2VyLWNvbnRyaWJ1dGVkIHBhY2thZ2VzIHRoYXQgZXh0ZW5kIGl0cyBjYXBhYmlsaXRpZXMuIEZvciBpbnN0YW5jZSwgdGhlIGBkcGx5cmAgcGFja2FnZSBzaW1wbGlmaWVzIGRhdGEgbWFuaXB1bGF0aW9uLCB3aGlsZSBgc2hpbnlgIGFsbG93cyB5b3UgdG8gYnVpbGQgaW50ZXJhY3RpdmUgd2ViIGFwcGxpY2F0aW9ucy4KCjQuICAqKlJlcHJvZHVjaWJpbGl0eSoqOiBXaXRoIFIsIHlvdSBjYW4gd3JpdGUgc2NyaXB0cyB0byBhdXRvbWF0ZSBkYXRhIGFuYWx5c2lzIHRhc2tzLCBlbnN1cmluZyBjb25zaXN0ZW5jeSBhbmQgcmVwcm9kdWNpYmlsaXR5LiBUaGlzIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgaW4gcmVzZWFyY2gsIHdoZXJlIHRyYW5zcGFyZW5jeSBhbmQgcmVwZWF0YWJpbGl0eSBhcmUgZXNzZW50aWFsLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjIEluc3RhbGxpbmcgUiBhbmQgUlN0dWRpbwoKVG8gc3RhcnQgdXNpbmcgUiwgeW91IG5lZWQgdHdvIG1haW4gdG9vbHM6CgoxLiAgKipSKio6IFRoZSBsYW5ndWFnZSBpdHNlbGYuIFlvdSBjYW4gZG93bmxvYWQgaXQgZm9yIGZyZWUgZnJvbSBbQ1JBTl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvKSwgdGhlIENvbXByZWhlbnNpdmUgUiBBcmNoaXZlIE5ldHdvcmsuIFRoaXMgaXMgdGhlICJpbnRlcnByZXRlciIgdGhhdCBsZXRzIHlvdSBydW4gUiBjb2RlLiBJdCBkb2VzIGluY2x1ZGUgYSBzaW1wbGUgdXNlciBpbnRlcmZhY2UsIGJ1dCBpdCdzIHJlYWxseSBqdXN0IHRoZSBsYW5ndWFnZSBydW4tdGltZSBlbnZpcm9ubWVudC4gVG8gZG8gYWN0dWFsIHByb2dyYW1taW5nLCB5b3UgbmVlZCAqKlJTdHVkaW8qKiwgYnV0IHlvdSBtdXN0IGluc3RhbGwgUiBiZWZvcmUgaW5zdGFsbGluZyB0aGUgUlN0dWRpbyBJREUuCjIuICAqKlJTdHVkaW8qKjogQSB1c2VyLWZyaWVuZGx5IGludGVyZmFjZSAoSW50ZWdyYXRlZCBEZXZlbG9wbWVudCBFbnZpcm9ubWVudCBvciBJREUpIHRoYXQgbWFrZXMgd29ya2luZyB3aXRoIFIgbXVjaCBlYXNpZXIuIFlvdSBjYW4gZG93bmxvYWQgUlN0dWRpbyBEZXNrdG9wIGZvciBmcmVlIGZyb20gaXRzIFtvZmZpY2lhbCB3ZWJzaXRlXSg8aHR0cHM6Ly9wb3NpdC5jby9kb3dubG9hZC9yc3R1ZGlvLWRlc2t0b3AvPi4gSXQgaXMgbm93IGNhbGxlZCAqKlBvc2l0KiogYmVjYXVzZSBpdCBzdXBwb3J0cyBtb3JlIHRoYW4ganVzdCBSOyBpdCBhbHNvIHN1cHBvcnRzIHByb2dyYW1taW5nIGluIFB5dGhvbiBhbmQgYSBudW1iZXIgb2Ygb3RoZXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLgoKV2hpbGUgUiBpcyB0aGUgZW5naW5lLCBSU3R1ZGlvIGlzIHRoZSBkYXNoYm9hcmQgdGhhdCBsZXRzIHlvdSBpbnRlcmFjdCB3aXRoIFIgbW9yZSBjb252ZW5pZW50bHkuIFRoaW5rIG9mIFJTdHVkaW8gYXMgYSBzbWFydHBob25lIHRoYXQgbWFrZXMgdGhlIHJhdyBjb21wdXRpbmcgcG93ZXIgb2YgUiBhY2Nlc3NpYmxlIHRocm91Z2ggYSB1c2VyLWZyaWVuZGx5IGludGVyZmFjZS4KClRoZSB0dXRvcmlhbCBiZWxvdyBndWlkZXMgeW91IHRocm91Z2ggdGhlIHByb2Nlc3Mgb2YgaW5zdGFsbGluZyBSIGFuZCBSU3R1ZGlvLiBBcyBhbiBhbHRlcm5hdGl2ZSB0byBpbnN0YWxsaW5nIHRoZSBSIHByb2dyYW1taW5nIGxhbmd1YWdlIGFuZCB0aGUgUlN0dWRpbyBJREUsIHlvdSBjYW4gYWxzbyBjcmVhdGUgYW4gYWNjb3VudCBvbiB0aGUgY2xvdWQgc2VydmljZSBmb3IgUlN0dWRpbzogW3Bvc2l0LmNsb3VkXShodHRwOi8vcG9zaXQuY2xvdWQpLiBQb3NpdCBpcyBydW4gYnkgUlN0dWRpbyBhbmQgdGhlcmUgYXJlIGZyZWUgcGxhbnMgYXZhaWxhYmxlIGFzIHdlbGwgYXMgaW5leHBlbnNpdmUgbW9udGhseSBlZHVjYXRpb25hbCBzdWJzY3JpcHRpb25zLgoKPFRVVE9SSUFMIE9OIElOU1RBTExJTkcgUi9SU1RVRElPPgoKIyMjIyAqKlRoZSBSU3R1ZGlvIEludGVyZmFjZSoqCgpXaGVuIHlvdSBvcGVuIFJTdHVkaW8sIHlvdeKAmWxsIG5vdGljZSBzZXZlcmFsIGtleSBwYW5lbHM6CgoxLiAgKipDb25zb2xlKio6IFRoaXMgaXMgd2hlcmUgUiBleGVjdXRlcyBjb21tYW5kcy4gSWYgeW91IHR5cGUgYDIgKyAyYCBpbiB0aGUgQ29uc29sZSBhbmQgcHJlc3MgRW50ZXIsIFIgd2lsbCBpbW1lZGlhdGVseSBvdXRwdXQgYDRgLgoyLiAgKipTY3JpcHQgRWRpdG9yKio6IFRoaXMgaXMgd2hlcmUgeW91IHdyaXRlIGFuZCBzYXZlIGxvbmdlciBwaWVjZXMgb2YgY29kZS4gRm9yIGluc3RhbmNlLCBpZiB5b3Ugd2FudCB0byBhbmFseXplIGEgZGF0YXNldCByZXBlYXRlZGx5LCB5b3UgY2FuIHdyaXRlIGEgc2NyaXB0IGluIHRoaXMgcGFuZWwgYW5kIHNhdmUgaXQgZm9yIGZ1dHVyZSB1c2UuCjMuICAqKkVudmlyb25tZW50Kio6IFRoaXMgcGFuZWwgc2hvd3MgYWxsIHRoZSB2YXJpYWJsZXMsIGRhdGEsIGFuZCBvYmplY3RzIGN1cnJlbnRseSBpbiB1c2UuIEZvciBleGFtcGxlLCBpZiB5b3UgY3JlYXRlIGEgZGF0YXNldCBjYWxsZWQgYHNhbGVzX2RhdGFgLCBpdCB3aWxsIGFwcGVhciBoZXJlLgo0LiAgKipQbG90cyBQYW5lbCoqOiBXaGVuIHlvdSBjcmVhdGUgdmlzdWFsaXphdGlvbnMsIHRoZXkgd2lsbCBhcHBlYXIgaW4gdGhpcyBwYW5lbC4gRm9yIGV4YW1wbGUsIGlmIHlvdSBwbG90IGEgbGluZSBncmFwaCBvZiBzYWxlcyBvdmVyIHRpbWUsIHlvdSBjYW4gdmlldyBhbmQgZXhwb3J0IHRoZSBncmFwaCBoZXJlLgoKVGhlIHR1dG9yaWFsIGJlbG93IHByb3ZpZGVzIGFuIG92ZXJ2aWV3IG9mIFJTdHVkaW8gYW5kIGl0cyBjYXBhYmlsaXRpZXMuCgo8VFVUT1JJQUw+CgpUaGUgcmVhbCBzdHJlbmd0aCBvZiBSIGxpZXMgaW4gaXRzIGNvbW11bml0eS4gVGhvdXNhbmRzIG9mIGRldmVsb3BlcnMgYW5kIGFuYWx5c3RzIGNvbnRyaWJ1dGUgdG8gaXRzIGVjb3N5c3RlbSwgY3JlYXRpbmcgcGFja2FnZXMgYW5kIHJlc291cmNlcyB0aGF0IG1ha2UgaXQgZWFzaWVyIHRvIHRhY2tsZSBhbnkgZGF0YSBhbmFseXNpcyBjaGFsbGVuZ2UuIFdoZXRoZXIgeW914oCZcmUgcGVyZm9ybWluZyBzaW1wbGUgZGVzY3JpcHRpdmUgc3RhdGlzdGljcyBvciBidWlsZGluZyBhIHByZWRpY3RpdmUgbW9kZWwsIFIgaGFzIHRoZSB0b29scyB0byBoZWxwIHlvdSBzdWNjZWVkLgoKTGVhcm5pbmcgUiBtYXkgc2VlbSBjaGFsbGVuZ2luZyBhdCBmaXJzdCwgYnV0IGl04oCZcyBhIHNraWxsIHRoYXQgcGF5cyBvZmYgaW1tZW5zZWx5IGluIHRoZSB3b3JsZCBvZiBkYXRhIGFuYWx5dGljcy4gV2l0aCBwcmFjdGljZSwgeW914oCZbGwgZmluZCB0aGF0IFIgaXMgbm90IGp1c3QgYSBwcm9ncmFtbWluZyBsYW5ndWFnZSDigJQgaXTigJlzIGEgcGFydG5lciB0aGF0IGVtcG93ZXJzIHlvdSB0byB0dXJuIHJhdyBkYXRhIGludG8gYWN0aW9uYWJsZSBpbnNpZ2h0cy4gWW91IHdpbGwgZmluZCBSIGlzIGVhc2llciB0byBsZWFybiB0aGFuIG1vc3Qgb3RoZXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIGFuZCBiZWNvbWluZyBwcm9maWNpZW50IGF0IFIgdGFrZXMgY29tcGFyYXRpdmVseSBsaXR0bGUgdGltZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjIFR1dG9yaWFsIEk6IFByb2dyYW1taW5nIExpZmVjeWNsZQoKVGhlIHR1dG9yaWFsIGJlbG93IGJ5IEtob3VyeSBCb3N0b24ncyBQcm9mLiBTY2hlZGxiYXVlciwgZGVtb25zdHJhdGVzIHRoZSBwcm9ncmFtIGRldmVsb3BtZW50IGxpZmVjeWNsZSB1c2luZyBhIHRleHQgZWRpdG9yIGFuZCBleGVjdXRpbmcgY29kZSB3cml0dGVuIGluIFIuCgo8VHV0b3JpYWw+CgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCioqSW50ZWdyYXRlZCBEZXZlbG9wbWVudCBFbnZpcm9ubWVudCAoSURFKSoqCgpBbiAqKkludGVncmF0ZWQgRGV2ZWxvcG1lbnQgRW52aXJvbm1lbnQgKElERSkqKiBjb21iaW5lcyBzZXZlcmFsIHRvb2xzIGludG8gb25lIGludGVyZmFjZSB0byBtYWtlIHByb2dyYW1taW5nIGVhc2llci4gUlN0dWRpbyBpcyBhbiBJREUgc3BlY2lmaWNhbGx5IGZvciBSLiBJdCBpbnRlZ3JhdGVzIGEgdGV4dCBlZGl0b3IsIGV4ZWN1dGlvbiBlbnZpcm9ubWVudCwgZGVidWdnaW5nIHRvb2xzLCBhbmQgdmlzdWFsaXphdGlvbiBwYW5lbHMgaW4gYSBzaW5nbGUgd29ya3NwYWNlLgoKKklsbHVzdHJhdGlvbio6IEFuIElERSBpcyBsaWtlIGEgZnVsbHkgZXF1aXBwZWQga2l0Y2hlbi4gSW5zdGVhZCBvZiBoYXZpbmcgdGhlIG92ZW4sIGZyaWRnZSwgYW5kIHNpbmsgc2NhdHRlcmVkIGFjcm9zcyBkaWZmZXJlbnQgcm9vbXMsIGFuIElERSBicmluZ3MgZXZlcnl0aGluZyB0b2dldGhlciBpbiBvbmUgc3BhY2UgZm9yIGNvbnZlbmllbmNlLiBSU3R1ZGlv4oCZcyBDb25zb2xlLCBTY3JpcHQgRWRpdG9yLCBFbnZpcm9ubWVudCBwYW5lbCwgYW5kIFBsb3RzIHBhbmVsIGFyZSBsaWtlIHlvdXIgb3ZlbiwgY2hvcHBpbmcgYm9hcmQsIHNwaWNlIHJhY2ssIGFuZCBzZXJ2aW5nIGFyZWHigJRldmVyeXRoaW5nIHlvdSBuZWVkIHRvICJjb29rIiBhIHByb2dyYW0uCgpUbyBzdW1tYXJpemUsIHByb2dyYW1taW5nIGZvbGxvd3MgYSBzdHJ1Y3R1cmVkIGxpZmVjeWNsZTogcHJvYmxlbSBkZWZpbml0aW9uLCBkZXNpZ24sIGNvZGluZywgZXhlY3V0aW9uLCB0ZXN0aW5nLCBtYWludGVuYW5jZSwgYW5kIGRvY3VtZW50YXRpb24uIFRoZSBsaWZlY3ljbGUgaXMgbm90IGxpbmVhciBidXQgcmF0aGVyIGl0ZXJhdGl2ZS4gSXQgaW52b2x2ZXMgZnJlcXVlbnQgdHJpYWwtYW5kLWVycm9yLiBBIHRleHQgZWRpdG9yIGlzIHdoZXJlIHlvdSB3cml0ZSB5b3VyIGNvZGUuIEV4ZWN1dGlvbiBoYXBwZW5zIHdoZW4gYSBjb21waWxlZCBwcm9ncmFtIGlzIGV4ZWN1dGVkIG9yIGFuIGludGVycHJldGVyIGNhcnJpZXMgb3V0IGVhY2ggaW5zdHJ1Y3Rpb24uIEFuIElERSBsaWtlIFJTdHVkaW8gY29tYmluZXMgYWxsIHRvb2xzIChlZGl0b3IsIGV4ZWN1dGlvbiwgZGVidWdnaW5nLCBhbmQgcHJvZ3JhbSBvdXRwdXQpIGludG8gb25lIGNvbnZlbmllbnQgd29ya3NwYWNlLgoKPiAiQ29kZSBpcyBsaWtlIGh1bW9yLiBXaGVuIHlvdSBoYXZlIHRvIGV4cGxhaW4gaXQsIGl04oCZcyBiYWQuIiDigJMgQ29yeSBIb3VzZQoKIyMgU2VjdGlvbiAyOiBJbnRyb2R1Y3Rpb24gdG8gUHJvZ3JhbW1pbmcKClByb2dyYW1taW5nIGlzIHRoZSBhcnQgYW5kIHNjaWVuY2Ugb2YgaW5zdHJ1Y3RpbmcgYSBjb21wdXRlciB0byBwZXJmb3JtIHNwZWNpZmljIHRhc2tzLiBBdCBpdHMgY29yZSwgaXQgaW52b2x2ZXMgd3JpdGluZyBhIHNldCBvZiBpbnN0cnVjdGlvbnMgaW4gYSBsYW5ndWFnZSB0aGUgY29tcHV0ZXIgY2FuIHVuZGVyc3RhbmQuIFRoZXNlIGluc3RydWN0aW9ucywgY29sbGVjdGl2ZWx5IGNhbGxlZCBhIHByb2dyYW0sIGFyZSBleGVjdXRlZCBieSB0aGUgY29tcHV0ZXIgdG8gc29sdmUgYSBwcm9ibGVtIG9yIHBlcmZvcm0gYW4gYWN0aW9uLiBMZXTigJlzIGV4cGxvcmUgdGhpcyBpZGVhIGluIGRldGFpbCwgc3RlcCBieSBzdGVwLiBUaGlzIGZvcm0gb2YgcHJvZ3JhbW1pbmcgaXMgZ2VuZXJhbGx5IGNhbGxlZCAqcHJvY2VkdXJhbCBwcm9ncmFtbWluZyo7IGl0IGlzIG9uZSBvZiBtYW55IHByb2dyYW1taW5nIHN0eWxlcy4gT3RoZXIgcHJvZ3JhbW1pbmcgc3R5bGVzIGFuZCB3YXlzIHRvIG9yZ2FuaXplIHByb2dyYW0gY29kZSBhcmUgKm9iamVjdC1vcmllbnRlZCBwcm9ncmFtbWluZyosICpmdW5jdGlvbmFsIHByb2dyYW1taW5nKiwgYW5kICpsb2dpYyBwcm9ncmFtbWluZyouIE1hY2hpbmUgbGVhcm5pbmcgaXMgY29uc2lkZXJlZCBhIG5ld2VyIGZvcm0gb2YgcHJvZ3JhbW1pbmcgd2hlcmUgYW4gYWxnb3JpdGhtIGRlcml2ZXMgYSBwYXR0ZXJuIGZyb20gZGF0YSB0byBtYWtlIGEgcHJlZGljdGlvbiBhbmQgcHJvZHVjZSBhIHJlc3VsdCByYXRoZXIgdGhhbiBhIHByb2dyYW1tZXIgd3JpdGluZyB0aGUgaW5zdHJ1Y3Rpb25zIHRvIGFycml2ZSBhdCB0aGUgcmVzdWx0LgoKSW1hZ2luZSB5b3UgYXJlIHRlYWNoaW5nIGEgcm9ib3QgdG8gbWFrZSBhIGN1cCBvZiB0ZWEuIFlvdSBjYW7igJl0IHNpbXBseSBzYXksICJNYWtlIHRlYSIgYW5kIGV4cGVjdCB0aGUgcm9ib3QgdG8gdW5kZXJzdGFuZC4gSW5zdGVhZCwgeW91IHdvdWxkIG5lZWQgdG8gYnJlYWsgZG93biB0aGUgdGFzayBpbnRvIGEgc2VyaWVzIG9mIHNtYWxsLCBwcmVjaXNlIHN0ZXBzLCBwZXJoYXBzIHN1Y2ggYXMgdGhlc2U6CgoxLiAgUGljayB1cCB0aGUga2V0dGxlLgoyLiAgRmlsbCBpdCB3aXRoIHdhdGVyLgozLiAgUGxhY2UgdGhlIGtldHRsZSBvbiB0aGUgc3RvdmUuCjQuICBUdXJuIG9uIHRoZSBzdG92ZS4KNS4gIFdhaXQgZm9yIHRoZSB3YXRlciB0byBib2lsLgoKU2ltaWxhcmx5LCBwcm9jZWR1cmFsIHByb2dyYW1taW5nIGlzIGFib3V0IGJyZWFraW5nIGRvd24gYSBwcm9ibGVtIGludG8gbG9naWNhbCwgY2xlYXIgc3RlcHMgYW5kIGV4cHJlc3NpbmcgdGhlc2Ugc3RlcHMgaW4gYSBsYW5ndWFnZSB0aGF0IHRoZSBjb21wdXRlciB1bmRlcnN0YW5kcy4gQ29tcHV0ZXJzLCB1bmxpa2UgaHVtYW5zLCBjYW5ub3QgaW5mZXIgd2hhdCB5b3UgbWVhbuKAlHRoZXkgb25seSBkbyBleGFjdGx5IHdoYXQgeW91IHRlbGwgdGhlbSB0byBkby4KCkluIHRoaXMgd2F5LCBwcm9ncmFtbWluZyBpcyBsaWtlIHdyaXRpbmcgYSByZWNpcGUgb3IgYW4gaW5zdHJ1Y3Rpb24gbWFudWFsOiB5b3UgYXJlIGRlc2NyaWJpbmcgaG93IHRvIGFjaGlldmUgYSBzcGVjaWZpYyBvdXRjb21lIHVzaW5nIGEgc2VxdWVuY2Ugb2YgcHJlY2lzZWx5IGRlZmluZWQgYW5kIG9yZGVyZWQgYWN0aW9ucy4KClByb2dyYW1taW5nIGlzIGVzc2VudGlhbCBiZWNhdXNlIGNvbXB1dGVycyBhcmUgaW5jcmVkaWJseSBmYXN0LCBhY2N1cmF0ZSwgYW5kIGNvbnNpc3RlbnQsIGJ1dCBvbmx5IHdoZW4gZ2l2ZW4gcHJlY2lzZSBpbnN0cnVjdGlvbnMuIEZvciBleGFtcGxlLCBpbWFnaW5lIHlvdSBoYXZlIGEgZGF0YXNldCBjb250YWluaW5nIHRoZSBzYWxlcyBmaWd1cmVzIGZvciB0aG91c2FuZHMgb2Ygc3RvcmVzIG92ZXIgYSB5ZWFyLCBhbmQgeW91IHdhbnQgdG8gY2FsY3VsYXRlIHRoZSB0b3RhbCByZXZlbnVlLiBEb2luZyB0aGlzIG1hbnVhbGx5IHdvdWxkIHRha2UgZGF5cyBvciB3ZWVrcy4gV2l0aCBhIHByb2dyYW0sIHRoaXMgY2FsY3VsYXRpb24gY2FuIGJlIGNvbXBsZXRlZCBpbiBzZWNvbmRzLgoKRm9yIGRhdGEgYW5hbHl0aWNzLCBwcm9ncmFtbWluZyBpcyBpbnZhbHVhYmxlIGJlY2F1c2UgaXQgYWxsb3dzIHVzIHRvOgoKLSAgIEF1dG9tYXRlIHJlcGV0aXRpdmUgdGFza3MsIGxpa2UgY2xlYW5pbmcgZGF0YSBvciBnZW5lcmF0aW5nIHJlcG9ydHMuCi0gICBBbmFseXplIGxhcmdlIGRhdGFzZXRzIHF1aWNrbHkgYW5kIGFjY3VyYXRlbHkuCi0gICBDcmVhdGUgcmVwcm9kdWNpYmxlIHdvcmtmbG93cywgZW5zdXJpbmcgdGhhdCByZXN1bHRzIGFyZSBjb25zaXN0ZW50IGFuZCBjYW4gYmUgdmVyaWZpZWQuCgpQcm9ncmFtbWluZyBkb2VzbuKAmXQganVzdCBzYXZlIHRpbWUg4oCUIGl0IGVuYWJsZXMgdXMgdG8gZG8gdGhpbmdzIHRoYXQgd291bGQgb3RoZXJ3aXNlIGJlIGltcG9zc2libGUuCgo+ICJJIGRvbid0IG5lZWQgdG8gcHJvZ3JhbTsgSSBjb3VsZCBqdXN0IGRvIGl0IG1hbnVhbGx5LiBCdXQgd2hlcmUncyB0aGUgZnVuIGluIG5vdCBzcGVuZGluZyB0aHJlZSBob3VycyB3cml0aW5nIGEgcHJvZ3JhbSB0byBzYXZlIHRlbiBtaW51dGVzPyIg4oCTIEV2ZXJ5IFByb2dyYW1tZXIKCiMjIyBUaGUgUiBQcm9ncmFtbWluZyBMYW5ndWFnZQoKUiBpcyBhIHByb2dyYW1taW5nIGxhbmd1YWdlIHNwZWNpZmljYWxseSBkZXNpZ25lZCBmb3Igc3RhdGlzdGljYWwgY29tcHV0aW5nIGFuZCBkYXRhIHZpc3VhbGl6YXRpb24uIEl0IGlzIHdpZGVseSB1c2VkIGluIGRhdGEgYW5hbHl0aWNzIGJlY2F1c2UgaXQgc2ltcGxpZmllcyBtYW55IHRhc2tzIHRoYXQgd291bGQgYmUgY29tcGxleCBpbiBvdGhlciBsYW5ndWFnZXMuIEZvciBpbnN0YW5jZSwgUiBoYXMgYnVpbHQtaW4gZnVuY3Rpb25zIGZvciBjYWxjdWxhdGluZyBzdGF0aXN0aWNzLCBjcmVhdGluZyBjaGFydHMsIGFuZCBtYW5pcHVsYXRpbmcgZGF0YSwgd2hpY2ggbWFrZXMgaXQgYSBwZXJmZWN0IHRvb2wgZm9yIGJlZ2lubmVycyBpbiBkYXRhIGFuYWx5dGljcy4KClRoaW5rIG9mIFIgYXMgYSBzcGVjaWFsaXplZCB0b29sa2l0LiBKdXN0IGFzIGEgY2FycGVudGVyIGhhcyB0b29scyBkZXNpZ25lZCBmb3Igd29vZHdvcmssIFIgcHJvdmlkZXMgdG9vbHMgdGFpbG9yZWQgZm9yIHdvcmtpbmcgd2l0aCBkYXRhLiBUaGVzZSB0b29scyBpbmNsdWRlIGZ1bmN0aW9ucyBmb3IgY2FsY3VsYXRpbmcgYXZlcmFnZXMsIHBsb3R0aW5nIHRyZW5kcywgYW5kIHN1bW1hcml6aW5nIGRhdGFzZXRz4oCUYWxsIHRhc2tzIHRoYXQgYXJlIGNlbnRyYWwgdG8gdGhlIHdvcmsgb2YgYSBkYXRhIGFuYWx5c3QuCgpNYW55IGRhdGEgYW5hbHl0aWNzIHByb2Zlc3Npb25hbHMgdXNlIFIgYWxvbmdzaWRlIFB5dGhvbiBhcyB3ZWxsIGFzIG51bWVyb3VzIHNwZWNpYWxpemVkIHByb2dyYW1taW5nIHRvb2xzLgoKUiBvcmlnaW5hdGVkIGFzIGFuIG9wZW4tc291cmNlIGltcGxlbWVudGF0aW9uIG9mIHRoZSBTIGxhbmd1YWdlLCB3aGljaCB3YXMgZGV2ZWxvcGVkIGluIHRoZSAxOTcwcyBhdCBCZWxsIExhYm9yYXRvcmllcyAoYWxzbyBrbm93biBhcyBBVCZUIExhYnMpIGJ5IEpvaG4gQ2hhbWJlcnMgYW5kIGhpcyB0ZWFtLiBUaGUgUyBsYW5ndWFnZSB3YXMgZGVzaWduZWQgZm9yIHN0YXRpc3RpY2FsIGNvbXB1dGluZyBhbmQgZGF0YSBhbmFseXNpcywgYnV0IGl0IHdhcyBwcm9wcmlldGFyeSwgbGltaXRpbmcgaXRzIGFjY2Vzc2liaWxpdHkuCgpJbiB0aGUgZWFybHkgMTk5MHMsIFJvc3MgSWhha2EgYW5kIFJvYmVydCBHZW50bGVtYW4sIHR3byBzdGF0aXN0aWNpYW5zIGZyb20gdGhlIFVuaXZlcnNpdHkgb2YgQXVja2xhbmQgaW4gTmV3IFplYWxhbmQsIGJlZ2FuIGRldmVsb3BpbmcgUiBhcyBhIGZyZWUgYWx0ZXJuYXRpdmUgdG8gUy4gVGhlaXIgZ29hbCB3YXMgdG8gY3JlYXRlIGEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgdGhhdCByZXRhaW5lZCB0aGUgZmxleGliaWxpdHkgYW5kIHN0YXRpc3RpY2FsIHBvd2VyIG9mIFMgd2hpbGUgYmVpbmcgb3Blbi1zb3VyY2UgYW5kIGZyZWVseSBhdmFpbGFibGUgdG8gdGhlIGFjYWRlbWljIGNvbW11bml0eS4KClRoZSBmaXJzdCB2ZXJzaW9uIG9mIFIgd2FzIHJlbGVhc2VkIHRvIHRoZSBwdWJsaWMgaW4gMTk5NSwgYW5kIGl0cyBwb3B1bGFyaXR5IGdyZXcgcXVpY2tseSBhbW9uZyBzdGF0aXN0aWNpYW5zIGFuZCBkYXRhIHNjaWVudGlzdHMuIEluIDE5OTcsIHRoZSBSIERldmVsb3BtZW50IENvcmUgVGVhbSB3YXMgZXN0YWJsaXNoZWQgdG8gb3ZlcnNlZSBpdHMgY29udGludWVkIGRldmVsb3BtZW50LCBlbnN1cmluZyB0aGF0IFIgcmVtYWluZWQgYSBjb2xsYWJvcmF0aXZlLCBjb21tdW5pdHktZHJpdmVuIHByb2plY3QuCgpUb2RheSwgUiBpcyBhIGdsb2JhbCBzdGFuZGFyZCBmb3Igc3RhdGlzdGljYWwgY29tcHV0aW5nIGFuZCBkYXRhIHZpc3VhbGl6YXRpb24sIHdpZGVseSB1c2VkIGluIGFjYWRlbWlhLCBpbmR1c3RyeSwgYW5kIGdvdmVybm1lbnQuIEl0cyBvcGVuLXNvdXJjZSBuYXR1cmUgYW5kIGV4dGVuc2l2ZSBwYWNrYWdlIGVjb3N5c3RlbSBtYWtlIGl0IGFuIGluZGlzcGVuc2FibGUgdG9vbCBmb3IgZGF0YSBhbmFseXNpcywgcmVzZWFyY2gsIGV4cGVyaW1lbnRhdGlvbiwgYW5kIGRpc2NvdmVyeS4KCiMjIyBIb3cgRG9lcyBQcm9ncmFtbWluZyBXb3JrPwoKVGhlIHByb2Nlc3Mgb2YgcHJvZ3JhbW1pbmcgaW52b2x2ZXMgd3JpdGluZywgdGVzdGluZywgYW5kIHJ1bm5pbmcgY29kZS4gTGV04oCZcyBleHBsb3JlIHRoaXMgcHJvY2VzcyB0aHJvdWdoIGFuIGFuYWxvZ3k6IEltYWdpbmUgeW91IGFyZSBkZXNpZ25pbmcgYSBzZXQgb2YgaW5zdHJ1Y3Rpb25zIGZvciBhIGRlbGl2ZXJ5IHJvYm90LiBZb3VyIGdvYWwgaXMgdG8gcHJvZ3JhbSB0aGUgcm9ib3QgdG8gZGVsaXZlciBhIHBhY2thZ2UgdG8gYSBzcGVjaWZpYyBhZGRyZXNzLiBUaGUgc3RlcHMgbWlnaHQgbG9vayBzb21ldGhpbmcgbGlrZSB0aGlzOgoKMS4gIFdyaXRlIHRoZSBpbnN0cnVjdGlvbnM6ICJMZWF2ZSB0aGUgd2FyZWhvdXNlLCB3YWxrIHN0cmFpZ2h0IGZvciA1MDAgbWV0ZXJzLCB0dXJuIGxlZnQsIGFuZCBzdG9wIGF0IGhvdXNlIG51bWJlciAyNS4iCjIuICBUZXN0IHRoZSBpbnN0cnVjdGlvbnM6IEZvbGxvdyB0aGVtIHlvdXJzZWxmIHRvIGVuc3VyZSB0aGV5IGFyZSBjb3JyZWN0LgozLiAgUnVuIHRoZSBwcm9ncmFtOiBHaXZlIHRoZSBpbnN0cnVjdGlvbnMgdG8gdGhlIHJvYm90IGFuZCBvYnNlcnZlIGl0cyBiZWhhdmlvci4KCklmIHRoZSByb2JvdCBkZWxpdmVycyB0aGUgcGFja2FnZSBzdWNjZXNzZnVsbHksIHlvdXIgcHJvZ3JhbSB3b3Jrcy4gSWYgaXQgZW5kcyB1cCBhdCB0aGUgd3JvbmcgaG91c2UsIHlvdSB3b3VsZCBuZWVkIHRvIHJldmlldyBhbmQgY29ycmVjdCB0aGUgaW5zdHJ1Y3Rpb25zLgoKVGhpcyBzYW1lIHByb2Nlc3MgYXBwbGllcyB0byBwcm9ncmFtbWluZyBpbiBSLiBZb3Ugd3JpdGUgY29kZSAodGhlIGluc3RydWN0aW9ucyksIHRlc3QgaXQgYnkgcnVubmluZyBzbWFsbCBwYXJ0cyBvZiBpdCwgYW5kIHRoZW4gZXhlY3V0ZSB0aGUgZnVsbCBwcm9ncmFtIHRvIHNlZSB0aGUgcmVzdWx0cy4gSWYgaXQgZG9lc24ndCBkZWxpdmVyIHRoZSBjb3JyZWN0IHJlc3VsdCwgeW91IGZpbmQgd2hlcmUgdGhlIGVycm9yIGlzICh3ZWxsLCBtb3JlIGxpa2VseSBlcnJvcioqcyoqKSwgZml4IHRoZW0gKGhvcGVmdWxseSksIGFuZCBydW4gdGhlIHByb2dyYW0gYWdhaW4uIE9ic2VydmUgYWdhaW4sIGEgcmVwZWF0IHRoZSBwcm9jZXNzIHVudGlsIHRoZSBwcm9ncmFtIHByb3ZpZGVzIHRoZSBkZXNpcmVkIHJlc3VsdCBhbmQgbWVldHMgdGhlIG5lZWRzIChyZXF1aXJlbWVudHMpIG9mIGl0cyBpbnRlbmRlZCB1c2Vycy4gVG8gYmUgZmFpciwgbm8gcHJvZ3JhbSBpcyB3aXRob3V0IGFueSBkZWZlY3RzOiBldmVyeSBwcm9ncmFtIGNvbnRhaW5zIGJ1Z3M7IHRoZSBxdWVzdGlvbiByZWFsbHkgaXMgaG93IG1hbnkgZGVmZWN0cyBhcmUgd2Ugd2lsbGluZyB0byBsaXZlIHdpdGggYW5kIHRvbGVyYXRlLgoKIyMjIEJyZWFraW5nIERvd24gYSBTaW1wbGUgRXhhbXBsZQoKTGV04oCZcyBsb29rIGF0IGEgc2ltcGxlIHByb2dyYW1taW5nIGV4YW1wbGUgaW4gUjoKCmBgYCByCiMgRGVmaW5lIG51bWJlcnMKeCA8LSAxMAp5IDwtIDUKCiMgQ2FsY3VsYXRlIHRoZSBzdW0KcmVzdWx0IDwtIHggKyB5CgojIFByaW50IHRoZSByZXN1bHQKcHJpbnQocmVzdWx0KQpgYGAKCkhlcmXigJlzIHdoYXQgaGFwcGVucyBzdGVwIGJ5IHN0ZXA6CgoxLiAgKipEZWZpbmUgbnVtYmVycyoqOiBUaGUgdmFyaWFibGVzIGB4YCBhbmQgYHlgIGFyZSBsaWtlIGxhYmVsZWQgY29udGFpbmVycyB0aGF0IHN0b3JlIHRoZSBudW1iZXJzIDEwIGFuZCA1LCByZXNwZWN0aXZlbHkuCjIuICAqKkNhbGN1bGF0ZSB0aGUgc3VtKio6IFRoZSBwcm9ncmFtIHRlbGxzIFIgdG8gYWRkIHRoZSB2YWx1ZXMgaW4gYHhgIGFuZCBgeWAgYW5kIHN0b3JlIHRoZSByZXN1bHQgaW4gYSBuZXcgdmFyaWFibGUgY2FsbGVkIGByZXN1bHRgLgozLiAgKipQcmludCB0aGUgcmVzdWx0Kio6IFRoZSBwcm9ncmFtIG91dHB1dHMgdGhlIHZhbHVlIHN0b3JlZCBpbiBgcmVzdWx0YCwgd2hpY2ggaXMgYDE1YC4KCk5vdGUgdGhhdCBpbiBSIHdlIGNhbiBzaW1wbHkgdXNlIGEgdmFyaWFibGUgYW5kIHRoYXQgZGVmaW5lcyBpdCBhbmQgd2UgZ290IGEgY29udGFpbmVyIGZvciB2YWx1ZXMuIFdoYXRldmVyIHZhbHVlIHlvdSBhc3NpZ24gdG8gaXQgZGV0ZXJtaW5lcyB3aGF0IHRoZSAidHlwZSIgb2YgdGhlIHZhcmlhYmxlIGlzLCAqaS5lLiosIHdoYXQga2luZHMgb2YgdGhpbmdzIGl0IGNhbiBob2xkOiB0ZXh0LCBudW1iZXJzLCBkYXRlcywgKmV0YyouIE90aGVyIHByb2dyYW1taW5nIGxhbmd1YWdlcyBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgdmFyaWFibGVzIGFuZCBob3cgdG8gZGVmaW5lIHRoZW07IHRoZXNlIGFyZSB0aGUgcnVsZXMgZm9yIFIuCgojIyMgUHJvZ3JhbW1pbmcgaXMgUHJvYmxlbSBTb2x2aW5nCgpBdCBpdHMgaGVhcnQsIHByb2dyYW1taW5nIGlzIGFib3V0IHNvbHZpbmcgcHJvYmxlbXMuIFRoZSBjb21wdXRlciBhY3RzIGFzIGEgdG9vbCB0byBleGVjdXRlIHlvdXIgc29sdXRpb24uIEEgc2ltcGxlIHByb2JsZW0gbWlnaHQgYmUsICJIb3cgbWFueSBob3VycyBhcmUgdGhlcmUgaW4gYSB3ZWVrPyIgWW91IGNvdWxkIHNvbHZlIHRoaXMgbWFudWFsbHksIGJ1dCBpbiBSLCB5b3Ugd291bGQgd3JpdGU6CgpgYGAgcgojIENhbGN1bGF0ZSBob3VycyBpbiBhIHdlZWsKaG91cnNfcGVyX2RheSA8LSAyNApkYXlzX3Blcl93ZWVrIDwtIDcKaG91cnNfcGVyX3dlZWsgPC0gaG91cnNfcGVyX2RheSAqIGRheXNfcGVyX3dlZWsKcHJpbnQoaG91cnNfcGVyX3dlZWspCmBgYAoKSGVyZSwgdGhlIHByb2dyYW0gY2FsY3VsYXRlcyB0aGUgYW5zd2VyIChgMTY4YCkgZm9yIHlvdS4gVGhpcyBwcm9jZXNzIGRlbW9uc3RyYXRlcyBob3cgcHJvZ3JhbW1pbmcgYWxsb3dzIHlvdSB0byBmb2N1cyBvbiBkZWZpbmluZyB0aGUgc29sdXRpb24gd2hpbGUgdGhlIGNvbXB1dGVyIGhhbmRsZXMgdGhlIGRydWRnZXJ5IG9mIHRoZSBjYWxjdWxhdGlvbnMuIE9mIGNvdXJzZSwgdGhpcyBpcyBhIHN1cGVyIHRyaXZpYWwgZXhhbXBsZSwgYnV0IGltYWdpbmUgaWYgdGhlIGNhbGN1bGF0aW9uIGludm9sdmVkIG1hbnkgbW9yZSBudW1iZXJzIGFuZCB3YXMgbXVjaCBtb3JlIGNvbXBsaWNhdGVkIC0tIHRoZW4geW91J2QgcmVhbGx5IGFwcHJlY2lhdGUgaGF2aW5nIGEgY29tcHV0ZXIgZG8gdGhlIGRydWRnZXJ5IG9mIHRoZSBjYWxjdWxhdGlvbnMgZm9yIHlvdS4gT2YgY291cnNlLCB1bnRpbCByZWNlbnRseSwgImNvbXB1dGVycyIgd2VyZSBwZW9wbGUgKGFwcGxpZWQgbWF0aGVtYXRpY2lhbnMsIHRvIGJlIG1vcmUgcHJlY2lzZSkgd2hvIHdlcmUgcmVhbGx5IGdvb2QgYXQgbnVtZXJpY2FsIG1ldGhvZHMgZm9yIGRvaW5nIGNvbXBsZXggY2FsY3VsYXRpb25zW14xXS4KClteMV06IEZvciBzb21lIGNvb2wgc2NlbmVzIG9uIHdoYXQgcmVhbC1saWZlICJjb21wdXRlcnMiIG9yICJjYWxjdWxhdG9ycyIgZGlkLCB3YXRjaCB0aGUgbW92aWUgIkhpZGRlbiBGaWd1cmVzIi4KCiMjIyBXaHkgRG8gRXJyb3JzIEhhcHBlbj8KCkVycm9ycywgb3IgImRlZmVjdHMiIG9yIHNpbXBseSAiYnVncyIsIGFyZSBhIGNvbW1vbiBwYXJ0IG9mIHByb2dyYW1taW5nOiBmcnVzdHJhdGluZywgYnV0IGNvbW1vbiBUaGV5IG9jY3VyIHdoZW4gdGhlIGluc3RydWN0aW9ucyBhcmUgaW5jb21wbGV0ZSwgYW1iaWd1b3VzLCBvciBpbmNvcnJlY3QuIEZvciBleGFtcGxlLCBpZiB5b3UgYWNjaWRlbnRhbGx5IHdyb3RlOgoKYGBgIHIKaG91cnNfcGVyX2RheSA8LSAyNApkYXlzX3Blcl93ZWVrIDwtIDcKaG91cnNfcGVyX3dlZWsgPC0gaG91cnNfcGVyX2RheSArIGRheXNfcGVyX3dlZWsKcHJpbnQoaG91cnNfcGVyX3dlZWspCmBgYAoKVGhlIHByb2dyYW0gd291bGQgY2FsY3VsYXRlIGAzMWAgaW5zdGVhZCBvZiBgMTY4YC4gVGhpcyBtaXN0YWtlIGhpZ2hsaWdodHMgdGhlIGltcG9ydGFuY2Ugb2YgcHJlY2lzaW9uIGluIHByb2dyYW1taW5nLiBEZWJ1Z2dpbmcsIG9yIGZpbmRpbmcgYW5kIGZpeGluZyBlcnJvcnMsIGlzIGFuIGVzc2VudGlhbCBza2lsbCB0aGF0IHlvdSB3aWxsIGRldmVsb3AgYXMgeW91IHByYWN0aWNlLiBJdCBpcyBiZWluZyBhIHNsZXV0aDogc29tZSBwcm9ncmFtbWVycyBsb3ZlIGRlYnVnZ2luZzsgdGhleSBsb3ZlIHRoZSBodW50IGFuZCB0aGUgZG9wYW1pbmUgc2hvdCBvbmUgZ2V0cyBmcm9tIGZpbmRpbmcgYW4gZXJyb3IgLS0gb3RoZXJzIGFiaG9yIHRoZSBwcm9jZXNzIG9mIGRlYnVnZ2luZyBhbmQgY29tZSB0byBoYXRlIHRoZSBob3VycyBvZiB3YXN0ZWQgdGltZSBmaW5kaW5nIHNvbWUgInN0dXBpZCIgdHlwbyBvciBmYXVsdCBpbiBsb2dpYy4KCiMjIyBJdCdzIGEgSm91cm5leQoKSW4gZmFjdCwgcHJvZ3JhbW1pbmcgaXMgbm90IGp1c3QgYWJvdXQgd3JpdGluZyBjb2RlIOKAlCBpdOKAmXMgYWJvdXQgdGhpbmtpbmcgbG9naWNhbGx5IGFuZCBzb2x2aW5nIHByb2JsZW1zIHN5c3RlbWF0aWNhbGx5IGFuZCBtZXRob2RpY2FsbHkuIEFzIHlvdSBiZWdpbiB5b3VyIGpvdXJuZXkgd2l0aCBwcm9ncmFtbWluZyBhbmQgd2l0aCBSLCByZW1lbWJlciB0aGF0IGV2ZXJ5IHByb2dyYW0geW91IHdyaXRlIGlzIGFuIG9wcG9ydHVuaXR5IHRvIGxlYXJuLiBNaXN0YWtlcyBhcmUgcGFydCBvZiB0aGUgcHJvY2VzcywgYW5kIHdpdGggcHJhY3RpY2UsIHByb2dyYW1taW5nIHdpbGwgYmVjb21lIGEgcG93ZXJmdWwgdG9vbCBpbiB5b3VyIGRhdGEgYW5hbHl0aWNzIHRvb2xraXQuIEVtYnJhY2UgdGhlIGNoYWxsZW5nZSwgYW5kIGVuam95IHRoZSBzYXRpc2ZhY3Rpb24gdGhhdCBjb21lcyBmcm9tIG1ha2luZyB0aGUgY29tcHV0ZXIgZG8gZXhhY3RseSB3aGF0IHlvdSB3YW50LiBZb3UnbGwgYWxzbyBjb21lIHRvIGFwcHJlY2lhdGUgdGhlIGJlYXV0eSBvZiB3ZWxsLXdyaXR0ZW4gY29kZSBhbmQgeW91IHdpbGwgbWFydmVsIGF0IGNvZGUgd3JpdHRlbiBieSAibWFzdGVycyIgb2YgdGhlaXIgY3JhZnQuIEl0IGlzIGFsc28gbmVhdCB0byBzZWUgY29kZSBpbiBkaWZmZXJlbnQgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzOiBmaW5kIHNvbWUgYW5kIGp1c3QgdHJ5IHRvIGRlY2lwaGVyIGl0LgoKPiAiTGVhcm5pbmcgdG8gcHJvZ3JhbSBpcyBsaWtlIGxlYXJuaW5nIHRvIHBsYXkgYW4gaW5zdHJ1bWVudDogYXQgZmlyc3QsIGl0IHNvdW5kcyB0ZXJyaWJsZSwgYnV0IHdpdGggcHJhY3RpY2UsIHlvdSdsbCBjcmVhdGUgc29tZXRoaW5nIGFtYXppbmcuIgoKIyMgU3VtbWFyeQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyBGaWxlcyAmIFJlc291cmNlcwoKYGBge3IgemlwRmlsZXMsIGVjaG89RkFMU0V9CnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCAKICAgICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksCiAgICAgICAgICAgICAgICAgcGFyYW1zJG51bWJlcikKCnRleHRBTGluayA9IHBhc3RlMCgiQWxsIEZpbGVzIGZvciBMZXNzb24gIiwgCiAgICAgICAgICAgICAgIHBhcmFtcyRjYXRlZ29yeSwiLiIscGFyYW1zJG51bWJlcikKCiMgZG93bmxvYWRGaWxlc0xpbmsoKSBpcyBpbmNsdWRlZCBmcm9tIF9pbnNlcnQyREIuUgprbml0cjo6cmF3X2h0bWwoZG93bmxvYWRGaWxlc0xpbmsoIi4iLCB6aXBOYW1lLCB0ZXh0QUxpbmspKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgUmVmZXJlbmNlcwoKTm8gcmVmZXJlbmNlcy4KCiMjIEVycmF0YQoKW0xldCB1cyBrbm93XShodHRwczovL2Zvcm0uam90Zm9ybS5jb20vMjEyMTg3MDcyNzg0MTU3KXt0YXJnZXQ9Il9ibGFuayJ9Lgo=