Introduction
What is Make?
make
is a powerful and widely used build automation tool in software development, especially for C and C++, but also Java and many other programming languages. It is designed to help programmers manage complex projects by automating the process of building executable files, libraries, or other artifacts from source code. Make is particularly valuable when you have multiple source files, dependencies, and compilation steps in your project.
The make program is a standard utility for Unix/Linux and is also available on MacOS as part of xcode. For other platforms, there are many open source versions of make.
Interpreted languages such as Python or R do not require a facility similar to make. This tutorial focuses on GNU make which has become the standard. We will explain the key elements of building a “makefile” which are standard across most Linux systems (and MacOS). Many integrated development environments (such as Eclipse) use some version of a make facility although they often use XML to specify dependencies rather than a traditional makefile, often using the utility ant rather than make.
Why Use Make?
There are many reasons why make is so widely used. We will take a look at a few reasons below.
Dependency Management
One of the primary reasons for using make
is its ability to manage dependencies efficiently. In a typical software project, you have source files that depend on each other, configuration files, libraries, and other resources. make
tracks these dependencies and ensures that only the necessary parts of your project are rebuilt when something changes. This feature saves time and prevents unnecessary recompilation.
Automation
Make automates repetitive and error-prone tasks involved in the build process. Instead of manually typing out long compilation commands, linking steps, and other tasks, you define rules and let make
handle the details. This not only reduces the chances of human error but also makes your build process consistent and reproducible.
Portability
make
is platform-independent, which means you can use the same Makefile (the configuration file for make
) on different operating systems. This portability makes it an attractive choice for cross-platform development.
Customization
Make is highly customizable. You can tailor your build process to suit your project’s specific requirements. Define variables, rules, and targets in your Makefile to accommodate different build configurations, development environments, or deployment platforms.
When to Use Make
You should consider using make
when:
- You’re working on a project with multiple source files that need to be compiled and linked.
- You want to automate repetitive tasks such as building, testing, and cleaning your project.
- You need a tool that manages dependencies and ensures that only necessary parts of the project are rebuilt.
- Your project needs to be cross-platform, and you want a build system that works consistently on different operating systems.
- You value a high degree of customization and control over the build process.
In short, make
is a fundamental tool for programmers and software developers. It streamlines the build process, manages dependencies, and automates tasks, ultimately leading to more efficient and maintainable software development projects. In the following sections of this tutorial, we will dive deeper into how to use make
effectively to manage your projects.
Makefiles
Makefiles are an important element of programming, especially in C and C++ on Unix, although they can be found on other platforms and for other purposes as well. Essentially, makefiles are text files containing the rules on how an executable program is created from its source files and included libraries. A makefile serves as the input to the make program which read the rules in the makefile and produces an executable (well, a target, to be specific, which is most often an executable but doesn’t have to be). make applies the rules and only compiles what has changed since the last “build” of the executable. This is ideal when a project consists of many source files and a change in one would not require compiling all. Unfortunately, makefiles are a bit esoteric and the rules can be a bit baffling nowadays – after all, they were developed over fifty years ago when development tools were quite different.
Makefiles contain targets and dependency rules. If any source file’s dependencies change then the source file will get re-compiled and the new executable is linked.
A Simple Example
Running ‘make’
The ‘make’ command is run from the terminal (aka a shell).
% make target
When ‘make’ is run, it looks for a file named Makefile in the current folder. Note the capitalization of the file – it is important.
Let’s do the classic “Hello World” program as a makefile. Below is the contents of a really simple makefile (called Makefile).
hello:
echo "Hello, World"
Important: Rules must be indented by a TAB and not spaces. So, hit the TAB
key in your keyboard and do not type spaces with the spacebar on your keyboard. This is one of the most common mistakes that beginners run into.
Once you have the makefile, “execute it” by running the make
program.
% make
Not specifying a target for make
means that it builds the first target it finds.
Try it out for yourself
Go to the terminal, create a folder in which you can do this lesson, and use a text editor (e.g., vi) to create a file called Makefile and add the above.
Simple Build File Example
Makefiles are build files for projects and they contains all command to compile, link, copy, or move files and run scripts. Below is a simple example.
all: multithread
multithread: multithread.c
gcc -o multithread multithread.c
Again, just as a reminder: the indent before gcc is a TAB and not spaces.
Generally makefiles contain a target named all that builds the entire project. It includes all of the sub targets, such as individual executables, test drivers, installation scripts, and so forth.
So, in the above example, all depends on multithread to be up-to-date, which, in turn, depends on multithread.c. So, if multithread.c changes, then it forces the rules to be applied and any commands below that rule are run. In the above example, that would be the compilation and linking with gcc.
To initiate the full build, call make all
or simply make
as all is the first target.
Makefile Structure and Syntax
A Makefile consists of a set of rules. A rule generally looks like this:
target: prerequisites
command
command
command
The commands are the steps required to build the target. These need to start with a tab
character and not spaces. The prerequisites are generally file names, separated by spaces. These files need to exist before the commands for the target are run. They define dependencies.
Target ‘clean’
Most makefiles includes a rule for a target named clean that is invoked with make clean
. It’s purpose is to clean up your development environment remove the output of other targets. Note that is should not be the first target as it would then be the default target; the default target should be all.
Here is an example of a clean target for a simple project.
clean:
rm -f multithread
touch multithread.c
The rule removes the executable and updates the time stamp of last modification of the source file to the present time, which would force a recompile the next time you invoked make all
.
Certainly, let’s expand on the second section, “Basic Makefile Structure,” to provide a more detailed explanation of the components of a Makefile and how they work together.
Basic Makefile Structure
A “Makefile” is a text file with the name Makefile (spelled just like that with a capital ‘M’) that contains instructions for the make
utility on how to build a project. It consists of rules and targets, which are the building blocks of the Makefile. In this section, we will delve into the basic structure of a Makefile and explain how it works.
Rules and Targets
Targets
A target in a Makefile represents an output file or an action that make
should perform. Targets are the goals of your build process, such as executables, object files, or other artifacts. Each target corresponds to a specific task that make
can execute.
For example, in a C or C++ project, you might have targets like:
my_program
: To build the final executable.
main.o
, util.o
: To compile individual source files into object files.
clean
: To remove generated files and clean up the project.
Rules
A rule defines how to create a target from its dependencies. It consists of a target, a colon (:
), and a list of dependencies. Below the rule, you specify the commands needed to build the target from its dependencies. These commands are typically indented using tabs.
Here’s a basic rule structure:
target: dependencies
[commands]
- Target: The name of the target you want to build.
- Dependencies: The files or targets that the current target depends on. These represent the prerequisites for building the target.
- Commands: The shell commands to be executed when
make
builds the target. These commands are indented with tabs.
Example Makefile
Let’s create a simple Makefile to compile a “Hello, World!” program written in C.
# Define the target and its dependencies
my_program: main.o
# Compile the program
main.o: main.c
gcc -o main.o -c main.c
# Clean up generated files
clean:
rm -f my_program main.o
In this Makefile:
my_program
is the target, and it depends on main.o
.
main.o
is another target, which depends on main.c
.
- The
gcc
command is used to compile main.c
into an object file (main.o
).
- The
clean
target is used to remove the generated files when you run make clean
.
How make
Works
When you run make
in the command line without specifying a target, it looks for a special target called the default target. By convention, this is often named all
. If you have an all
target in your Makefile, make
will execute the commands associated with that target.
For example:
all: my_program
When you run make
without arguments, it will execute the all
target, which depends on my_program
. Thus, it will build my_program
and its dependencies.
To summarize, a Makefile consists of rules and targets. Rules specify how to build targets from their dependencies. When you run make
, it reads the Makefile, determines which targets need to be built or rebuilt based on file timestamps and dependencies, and then executes the corresponding commands. Understanding this basic structure is crucial for creating more complex and efficient Makefiles for your projects.
Certainly, let’s expand on the third section, “Makefile Rules and Targets,” to provide a more detailed explanation of rules, targets, and their practical usage in Makefiles.
3. Makefile Rules and Targets
In the context of make
, rules and targets are fundamental concepts that define how your project’s build process works. Understanding how to structure and use them effectively in Makefiles is crucial for automating tasks and managing dependencies.
3.1 Targets
Targets in a Makefile represent the artifacts or actions that you want to create or perform. Targets are the focal points of your build process, and they can include:
- Executable programs.
- Object files (compiled source files).
- Documentation.
- Distribution packages.
- Custom tasks like cleaning or testing.
Each target corresponds to a specific task or output that make
should generate. Targets can be created by defining their names in your Makefile.
3.1.1 Example Targets
In a C/C++ project, you might define targets like:
my_program
: To build the final executable.
main.o
, util.o
: To compile individual source files into object files.
clean
: To remove generated files and clean up the project.
3.2 Rules
Rules in a Makefile define how to create a target from its dependencies. A rule consists of three main parts:
- Target: The name of the target that you want to build.
- Dependencies: The files or targets that the current target depends on. These represent the prerequisites for building the target.
- Commands: The shell commands to be executed when
make
builds the target from its dependencies. These commands are typically indented with tabs.
3.2.1 Example Rule Structure
Here’s the structure of a rule:
target: dependencies
[commands]
3.2.2 Example Rule
Consider a simple rule to compile a C source file into an object file:
main.o: main.c
gcc -o main.o -c main.c
In this rule:
main.o
is the target we want to build.
main.c
is the dependency (source file) that main.o
depends on.
- The command
gcc -o main.o -c main.c
is executed to build main.o
from main.c
.
3.3 Practical Usage
Makefiles become powerful when you have multiple rules and targets, and they help you automate complex build processes. Here are some practical tips:
3.3.1 Building All Targets
By convention, you can create an all
target that depends on all the main targets in your project. When you run make
, it builds the all
target, which in turn builds everything else. For example:
all: my_program
my_program: main.o util.o
gcc -o my_program main.o util.o
main.o: main.c
gcc -o main.o -c main.c
util.o: util.c
gcc -o util.o -c util.c
3.3.2 Cleaning Up
A clean
target is handy for removing generated files and cleaning up your project. For example:
clean:
rm -f my_program main.o util.o
3.3.3 Default Target
You can specify a default target by including it at the beginning of your Makefile. For example:
.DEFAULT_GOAL := all
This sets the all
target as the default, so running make
without any arguments will build all
.
3.3.4 Phony Targets
Phony targets are targets that don’t represent actual files. They are used for tasks like cleaning, testing, or documentation generation. To declare a target as phony, use the .PHONY
special target. For example:
.PHONY: clean test docs
clean:
rm -f my_program main.o util.o
test:
./run_tests.sh
docs:
doxygen
In this example, clean
, test
, and docs
are phony targets.
3.4 Summary
In summary, Makefiles are composed of rules and targets. Rules specify how to build targets from their dependencies, and targets represent the artifacts or actions you want to create or perform. Understanding the structure and usage of rules and targets is essential for effectively automating tasks and managing dependencies in your software projects.
Certainly, let’s expand on the fourth section, “Variables in Makefiles,” to provide a more detailed explanation of variables and their practical usage in Makefiles.
4. Variables in Makefiles
Variables play a crucial role in Makefiles by allowing you to define reusable values that can be used throughout the file. They enhance the readability, maintainability, and flexibility of your Makefiles. In this section, we will explore how to declare and use variables effectively.
4.1 Declaring Variables
In a Makefile, you can declare variables using the following syntax:
VARIABLE_NAME = value
VARIABLE_NAME
: This is the name of the variable, which should be written in uppercase letters by convention.
value
: This is the value assigned to the variable. It can be a string, a command, or another variable.
4.2 Using Variables
You can use variables by enclosing their names in $(...)
or ${...}
. For example:
CC = gcc
CFLAGS = -Wall -O2
my_program: main.c
$(CC) $(CFLAGS) -o my_program main.c
In this example, CC
and CFLAGS
are variables, and their values are substituted when the my_program
target is built.
4.3 Variable Types
4.3.1 Simple Variables
Simple variables are defined using =
as shown above. They can be overridden if redefined later in the Makefile.
4.3.2 Recursive Variables
Recursive variables are defined using :=
. They are evaluated only when used, which means changes to their values do not affect previous usages.
VAR := initial_value
VAR := new_value # Does not affect previous usages of VAR
4.3.3 Conditional Variables
Conditional variables are defined using ?=
. They are set only if the variable is not already defined. This is useful for providing default values.
VAR ?= default_value # VAR is set to default_value if VAR is not already defined
4.4 Practical Usage
Variables are beneficial in Makefiles for various reasons:
4.4.1 Compiler and Flags
You can use variables to store the compiler and compilation flags, making it easy to change them globally in your Makefile:
CC = gcc
CFLAGS = -Wall -O2
my_program: main.c
$(CC) $(CFLAGS) -o my_program main.c
4.4.2 File Lists
Variables are useful for defining lists of files, especially when there are many source files:
SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)
my_program: $(OBJECTS)
$(CC) $(CFLAGS) -o my_program $(OBJECTS)
Here, OBJECTS
is generated from SOURCES
, converting .c
to .o
.
4.4.3 Conditional Compilation
Variables enable conditional compilation based on build configurations or target platforms:
# Build a debug version when DEBUG is defined
ifdef DEBUG
CFLAGS += -g
endif
my_program: main.c
$(CC) $(CFLAGS) -o my_program main.c
4.4.4 Versioning
You can define version numbers or project information as variables for easy updates:
VERSION = 1.0
PROJECT_NAME = my_project
my_program: main.c
$(CC) $(CFLAGS) -o $(PROJECT_NAME)_$(VERSION) main.c
4.5 Conclusion
Variables in Makefiles provide flexibility and maintainability. They allow you to define values once and use them throughout your Makefile, making it easier to manage build configurations and adapt to different scenarios. Using variables effectively can simplify the maintenance of complex projects and make your Makefiles more readable.
Certainly, let’s expand on the fifth section, “Automatic Variables,” to provide a more detailed explanation of automatic variables and their practical usage in Makefiles.
5. Automatic Variables in Makefiles
Automatic variables are a set of predefined variables in Makefiles that simplify the construction of rules by providing information about the target and dependencies being processed. They help avoid redundancy in your Makefile and make it more concise. In this section, we’ll explore common automatic variables and how to use them effectively.
5.1 Common Automatic Variables
5.1.1 $@
- The Target
$@
represents the target of the rule being executed. It’s particularly useful when you have multiple rules with similar patterns, as it allows you to reference the target without repeating its name.
Example:
my_program: main.o util.o
$(CC) $(CFLAGS) -o $@ $^
Here, $@
is replaced with my_program
, and $^
with main.o util.o
.
5.1.2 $^
- All Dependencies
$^
represents all the dependencies of the rule being executed. This is handy when you want to include all prerequisites in a command.
5.1.3 $<
- The First Dependency
$<
stands for the first dependency in the list of prerequisites. It’s often used when there’s only one dependency and you want to reference it directly.
Example:
main.o: main.c
$(CC) $(CFLAGS) -o $@ $<
Here, $<
is replaced with main.c
.
5.1.4 $?
- Out-of-Date Dependencies
$?
represents all the dependencies that are out-of-date concerning the target. It’s useful when you want to process only the files that have changed since the last build.
5.2 Practical Usage
Automatic variables simplify Makefile rules, making them more concise and less error-prone. Here are some practical examples of how to use them:
5.2.1 Building Multiple Targets
Automatic variables are especially useful when building multiple targets from a single rule:
objects = main.o util.o
all: my_program
my_program: $(objects)
$(CC) $(CFLAGS) -o $@ $^
$(objects): %.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
In this example, $@
and $^
are used to specify the target and dependencies for the my_program
rule, as well as for the pattern rule that compiles .c
files into .o
files.
5.2.2 Conditional Compilation
Automatic variables can be used to simplify conditional compilation based on build configurations or target platforms:
DEBUG ?= 0
ifeq ($(DEBUG), 1)
CFLAGS += -g
endif
my_program: main.c
$(CC) $(CFLAGS) -o $@ $<
Here, $<
represents the first dependency, which is main.c
. If DEBUG
is defined as 1
, the -g
flag is added to the compilation command.
5.2.3 Out-of-Date Dependencies
Automatic variables like $?
are useful when you want to process only the dependencies that have changed since the last build. For example, in a custom build script:
generate_resources: resource_generator
./resource_generator -o $@ $?
resource_generator: resource_generator.c
$(CC) $(CFLAGS) -o $@ $<
In this example, generate_resources
depends on the resource_generator
program and all the out-of-date resource files ($?
) to generate new resources.
5.3 Conclusion
Automatic variables in Makefiles simplify rule construction and reduce redundancy in your build scripts. By using variables like $@
, $^
, $<
, and $?
, you can create more concise and maintainable Makefiles that adapt to changes in your project without the need for extensive manual editing. Understanding and utilizing these automatic variables effectively can significantly enhance your Makefile-writing skills.
Certainly, let’s expand on the sixth section, “Phony Targets,” to provide a more detailed explanation of phony targets and their practical usage in Makefiles.
6. Phony Targets in Makefiles
In Makefiles, phony targets are targets that don’t represent files or artifacts but rather serve as labels for specific actions or tasks that need to be executed. Phony targets are essential for tasks such as cleaning, testing, or generating documentation. In this section, we will explore what phony targets are and how to use them effectively.
6.1 What Are Phony Targets?
Phony targets are used to define actions or tasks that make
should perform when explicitly requested, but they don’t correspond to actual files in the file system. They are declared in a Makefile to provide convenient names for common development and maintenance tasks, allowing you to execute these tasks using the make
command.
Typically, phony targets have no prerequisites or dependencies because their purpose is to execute a specific action, not to build a file based on dependencies.
6.2 Declaring Phony Targets
To declare a target as phony, you use the .PHONY
special target in your Makefile, followed by a list of phony target names. For example:
.PHONY: clean test docs
In this example, we’ve declared three phony targets: clean
, test
, and docs
. These targets represent common development tasks such as cleaning up generated files, running tests, and generating documentation.
6.3 Practical Usage
Phony targets are valuable for automating various development and maintenance tasks. Here are some common use cases and practical examples of phony targets:
6.3.1 Cleaning
A clean
phony target is used to remove generated files and artifacts to ensure a clean project directory. It’s especially important when you want to rebuild your project from scratch or before archiving or distributing it.
.PHONY: clean
clean:
rm -f my_program main.o util.o
Running make clean
will remove the executable my_program
and the object files (main.o
and util.o
) from the project directory.
6.3.2 Testing
A test
phony target is used to run your project’s test suite. This is especially helpful for continuous integration (CI) workflows.
.PHONY: test
test:
./run_tests.sh
Here, run_tests.sh
is a script that executes your project’s test cases. Running make test
will trigger this script and execute the tests.
6.3.3 Generating Documentation
A docs
phony target is used to generate project documentation. For example, if you use Doxygen for documentation generation:
.PHONY: docs
docs:
doxygen
Running make docs
will generate documentation using Doxygen or any other documentation generation tool you prefer.
6.3.4 Dependency Analysis
You can use phony targets to analyze dependencies in your project, such as generating dependency files for C/C++ code. For instance, using the GCC -M
flag to generate dependency files:
.PHONY: depend
depend:
gcc -M *.c > dependencies
Running make depend
will update the dependencies
file with the latest dependency information for your project.
6.4 Conclusion
Phony targets in Makefiles provide a way to define and automate common development and maintenance tasks. By declaring phony targets, you can use the make
command to execute these tasks conveniently without worrying about file dependencies. This helps streamline your development workflow, making it easier to clean, test, and document your projects efficiently.
Certainly, let’s expand on the seventh section, “Dependency Management,” to provide a more detailed explanation of how dependency management works in Makefiles and its practical usage.
7. Dependency Management in Makefiles
Dependency management is a critical aspect of Makefiles, as it ensures that make
rebuilds only those targets that are out-of-date based on changes in their dependencies. In this section, we will delve deeper into how dependency management works and provide practical examples.
7.1 Defining Dependencies
In a Makefile, dependencies are specified in the rules for each target. A target depends on one or more files or other targets, known as prerequisites. When make
encounters a rule, it checks if the target is older than any of its prerequisites. If a prerequisite is newer than the target or if the target doesn’t exist, make
rebuilds the target.
Here’s the basic structure of a rule with dependencies:
target: dependencies
[commands]
7.2 How make
Determines What to Build
When you run make
, it follows these steps to determine what needs to be built:
- It reads the Makefile to build a dependency graph that shows how targets and dependencies are related.
- It checks the timestamps of targets and their dependencies.
- If a target is older than any of its dependencies, or if the target doesn’t exist,
make
executes the commands associated with that target to rebuild it.
- It recursively builds any prerequisites that are out-of-date before building the target.
7.3 Practical Usage
Let’s look at practical examples of how dependency management works in Makefiles.
7.3.1 C/C++ Compilation
Consider a simple C/C++ project with multiple source files and header files:
CC = gcc
CFLAGS = -Wall -O2
my_program: main.o util.o
$(CC) $(CFLAGS) -o my_program main.o util.o
main.o: main.c util.h
$(CC) $(CFLAGS) -c -o main.o main.c
util.o: util.c util.h
$(CC) $(CFLAGS) -c -o util.o util.c
In this example:
my_program
depends on main.o
and util.o
.
main.o
depends on main.c
and util.h
.
util.o
depends on util.c
and util.h
.
If you modify main.c
or util.c
, running make
will rebuild only the affected object files and then re-link the program. The dependencies ensure that only the necessary parts of the project are rebuilt.
7.3.2 Automatic Dependency Generation
Make can also generate dependency information automatically using tools like gcc -M
. For example:
CC = gcc
CFLAGS = -Wall -O2
SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)
my_program: $(OBJECTS)
$(CC) $(CFLAGS) -o my_program $(OBJECTS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
# Automatically generate dependencies
%.d: %.c
$(CC) -M -MP -MF $@ -MT $(@:.d=.o) $<
In this example, the %.d
rule generates dependency files (*.d
) that contain information about the header file dependencies of each source file. These dependency files are then included in the Makefile, ensuring that changes in header files trigger recompilation.
To include the generated dependency files in your Makefile, add this line:
-include $(SOURCES:.c=.d)
This line tells make
to include the generated .d
files.
7.4 Conclusion
Dependency management is a fundamental aspect of Makefiles, enabling efficient and automated builds. By specifying dependencies for each target, you can ensure that make
rebuilds only what is necessary, reducing build times and ensuring consistency in your projects. Understanding how dependency management works and how to use it effectively is essential for efficient software development workflows.
Certainly, let’s expand on the eighth section, “Conditional Statements in Makefiles,” to provide a more detailed explanation of conditional statements and their practical usage in Makefiles.
8. Conditional Statements in Makefiles
Conditional statements in Makefiles allow you to create rules and targets that vary depending on specific conditions or variables. These statements enable you to customize your build process, adapt to different environments, or handle various build configurations. In this section, we’ll explore the use of conditional statements in Makefiles and provide practical examples.
8.1 Conditional Directives
Makefiles use conditional directives to define rules, targets, and variables based on conditions. Common conditional directives include ifeq
, ifneq
, ifdef
, and ifndef
. These directives allow you to check for equality, inequality, or variable existence.
The basic structure of conditional directives is as follows:
conditional_directive
# Condition
[commands]
else
# Alternative commands
endif
8.2 Practical Usage
Let’s explore some practical examples of how conditional statements can be used in Makefiles.
8.2.1 Conditional Compilation
Conditional compilation is a common use case for conditional statements in Makefiles. You can use conditionals to include or exclude specific source files or compiler flags based on build configurations.
DEBUG ?= 0
ifeq ($(DEBUG), 1)
CFLAGS += -g
endif
my_program: main.c
$(CC) $(CFLAGS) -o my_program main.c
In this example, the -g
flag is added to CFLAGS
if the DEBUG
variable is set to 1
. This allows you to control whether debugging information is included in the compiled binary.
8.2.3 Variable Assignment
Conditional statements can also be used for variable assignment. For example, you might want to set a variable differently depending on whether a specific tool is available:
ifdef TOOL_EXISTS
COMPILER = $(TOOL_EXISTS)
else
COMPILER = gcc
endif
my_program: main.c
$(COMPILER) -o my_program main.c
In this case, if the TOOL_EXISTS
variable is defined, it will be used as the compiler; otherwise, gcc
is used as the default.
8.3 Nested Conditionals
You can nest conditional statements to handle more complex scenarios:
DEBUG ?= 0
TARGET ?= linux
ifeq ($(DEBUG), 1)
CFLAGS += -g
else
ifeq ($(TARGET), windows)
CFLAGS += -O2
else
CFLAGS += -O3
endif
endif
my_program: main.c
$(CC) $(CFLAGS) -o my_program main.c
In this example, the build configuration depends on both the DEBUG
variable and the TARGET
variable. Depending on these conditions, different optimization flags (-g
, -O2
, or -O3
) are used.
8.4 Conclusion
Conditional statements in Makefiles provide flexibility and adaptability to your build process. They allow you to customize rules, targets, and variables based on conditions, making your Makefiles more versatile and suitable for various build scenarios. Understanding how to use conditional statements effectively can help you manage complex projects and accommodate different environments and configurations.
Certainly, let’s expand on the ninth section, “Pattern Rules and Automatic Prerequisites,” to provide a more detailed explanation of pattern rules, automatic prerequisites, and their practical usage in Makefiles.
9. Pattern Rules and Automatic Prerequisites in Makefiles
Pattern rules are a powerful feature in Makefiles that allow you to define generic rules for building multiple targets with similar patterns. Automatic prerequisites extend this concept by automatically generating dependency information for source files. In this section, we will explore how to use pattern rules and automatic prerequisites effectively in Makefiles.
9.1 Pattern Rules
Pattern rules in Makefiles define a general rule for building targets that match a specific pattern. They are a way to avoid writing multiple similar rules for targets with a common structure. The syntax for a pattern rule is:
%.out: %.c
[commands]
%.out
: The target pattern that matches any target ending with .out
.
%.c
: The prerequisite pattern that matches any source file ending with .c
.
[commands]
: The commands to build the target from the prerequisite.
For example, if you have multiple C source files and want to create executables from them, you can use a pattern rule like this:
%.out: %.c
gcc -o $@ $<
Now, make
can build any target with a .out
extension from the corresponding .c
source file.
9.2 Automatic Prerequisites
Automatic prerequisites are an extension of pattern rules that automatically generate dependency information for source files. This is particularly useful when you want to track changes in header files and automatically rebuild targets when header files change.
To enable automatic prerequisites, you can use the -M
flag with the gcc
or g++
compiler to generate dependency information. For example:
%.o: %.c
gcc -MMD -MP -MF $*.d -c -o $@ $<
-MMD
: Generate dependency information.
-MP
: Generate phony targets for missing headers.
-MF $*.d
: Specify the dependency file to be generated (e.g., main.d
for main.c
).
-c -o $@ $<
: Compile the source file into an object file.
Additionally, you can include the generated dependency files in your Makefile to ensure accurate tracking of header file changes:
-include $(wildcard *.d)
This line tells make
to include all .d
files in the current directory.
9.3 Practical Usage
Let’s look at practical examples of how pattern rules and automatic prerequisites can be used in Makefiles.
9.3.1 Building Multiple Targets
Pattern rules are excellent for building multiple targets from similar source files. Suppose you have several C source files (file1.c
, file2.c
, etc.) that you want to compile into executables (file1.out
, file2.out
, etc.). You can use the following pattern rule:
%.out: %.c
gcc -o $@ $<
Now, make file1.out
will compile file1.c
into file1.out
, and the same rule applies to other source files.
9.3.2 Automatic Prerequisites for C/C++ Projects
Automatic prerequisites simplify dependency tracking in C/C++ projects. Consider this Makefile for a C project:
CC = gcc
CFLAGS = -Wall -O2
SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)
-include $(wildcard *.d)
%.o: %.c
$(CC) -MMD -MP -MF $*.d $(CFLAGS) -c -o $@ $<
my_program: $(OBJECTS)
$(CC) $(CFLAGS) -o my_program $(OBJECTS)
With this setup, the Makefile automatically generates dependency files (.d
) for each source file and includes them. If a header file changes, only the affected source files are rebuilt, saving compilation time.
9.3.3 Generic Rules for Build Systems
Pattern rules are especially useful in build systems that need to handle various source files and targets. For example, in a build system for a scripting language interpreter:
%.o: %.c
$(CC) -MMD -MP -MF $*.d $(CFLAGS) -c -o $@ $<
interpreter: $(OBJECTS)
$(CC) $(CFLAGS) -o interpreter $(OBJECTS)
This pattern rule and target allow you to compile any .c
source file into an object file and then link them to create the interpreter.
9.4 Conclusion
Pattern rules and automatic prerequisites in Makefiles provide a powerful way to streamline the build process for projects with multiple source files and dependencies. By defining generic rules for building targets and automatically generating dependency information, you can save time and ensure accurate tracking of changes in source files and headers. Understanding how to use pattern rules and automatic prerequisites effectively is essential for efficient software development workflows.
Certainly, let’s expand on the tenth section, “Managing Libraries and Linking,” to provide a more detailed explanation of how to manage libraries and linking in Makefiles.
10. Managing Libraries and Linking in Makefiles
Libraries are an essential part of software development, and in Makefiles, managing libraries and linking them to your programs is crucial. In this section, we will explore how to include and link libraries effectively in Makefiles.
10.1 Including Libraries
Including libraries in your Makefile involves specifying the necessary libraries that your program depends on. You typically use the -l
flag followed by the library name when invoking the linker (e.g., gcc
or g++
).
Here’s an example of how to include the math library in a Makefile:
my_program: main.c
gcc -o my_program main.c -lm
In this example, the -lm
flag tells the linker to include the math library.
10.2 Specifying Library Directories
Sometimes, the libraries you need may be located in non-standard directories. You can specify library directories using the -L
flag and then include the libraries using the -l
flag.
my_program: main.c
gcc -o my_program main.c -L/path/to/libdir -lmylib
In this case, /path/to/libdir
is the directory containing the libmylib.a
or libmylib.so
library file.
10.3 Practical Usage
Let’s explore some practical examples of managing libraries and linking them in Makefiles.
10.3.1 Linking with Multiple Libraries
If your program depends on multiple libraries, you can specify them by separating them with space after the -l
flag:
my_program: main.c
gcc -o my_program main.c -lm -lpthread -lmylib
In this example, we’re linking with the math library (-lm
), the pthread library (-lpthread
), and a custom library (-lmylib
).
10.3.2 Using Variables for Libraries
To make your Makefile more maintainable, you can use variables to store library flags:
LIBS = -lm -lpthread -lmylib
my_program: main.c
gcc -o my_program main.c $(LIBS)
By using variables, it’s easier to add or remove libraries from your project without changing every occurrence in your Makefile.
10.3.3 Conditional Linking
You can use conditional statements in your Makefile to handle different build configurations and link libraries accordingly. For example, you might want to link with a debugging library when debugging is enabled:
DEBUG ?= 0
LIBS = -lm -lpthread
ifeq ($(DEBUG), 1)
LIBS += -ldebug
endif
my_program: main.c
gcc -o my_program main.c $(LIBS)
In this example, the -ldebug
library is included in the LIBS
variable only if the DEBUG
variable is set to 1
.
10.3.4 Automatic Dependency Tracking
If your project has header file dependencies, you can use automatic prerequisites (as discussed in section 9) to automatically track changes in header files and recompile the program when needed. This ensures that your program is rebuilt when any of its dependencies change.
CC = gcc
CFLAGS = -Wall -O2
SOURCES = main.c util.c
OBJECTS = $(SOURCES:.c=.o)
-include $(wildcard *.d)
%.o: %.c
$(CC) -MMD -MP -MF $*.d $(CFLAGS) -c -o $@ $<
my_program: $(OBJECTS)
$(CC) $(CFLAGS) -o my_program $(OBJECTS) -lm -lpthread -lmylib
In this example, we include libraries as well as dependencies generated for source files.
10.4 Conclusion
Managing libraries and linking in Makefiles is essential for building complex software projects. By specifying libraries, library directories, and using variables and conditional statements, you can create Makefiles that handle library management efficiently. Additionally, automatic dependency tracking ensures that your program is rebuilt when necessary, keeping your build process up-to-date and reliable. Understanding these concepts is crucial for effective software development workflows using Makefiles.
Certainly, let’s expand on the eleventh section, “Cleaning and Maintenance,” to provide a more detailed explanation of cleaning targets, maintaining Makefiles, and other aspects related to cleaning and maintaining your project with Makefiles.
11. Cleaning and Maintenance in Makefiles
Cleaning and maintaining a project is a crucial part of software development. Makefiles provide several features to help you manage these tasks efficiently. In this section, we will explore how to create cleaning targets, handle project maintenance, and other related aspects in Makefiles.
11.1 Cleaning Targets
Cleaning targets are used to remove generated files and artifacts, ensuring a clean project directory for rebuilding or distribution. A common cleaning target in a Makefile is clean
. To create a clean
target, you can use the following rule:
.PHONY: clean
clean:
rm -f my_program *.o
In this example, the clean
target removes the my_program
executable and all object files (*.o
) from the project directory when you run make clean
.
11.2 Maintenance Targets
Maintenance targets are used to perform tasks related to project maintenance, such as generating documentation, running tests, or checking code formatting. Here are some examples:
11.2.1 Generating Documentation
You can create a target called docs
to generate project documentation. For instance, if you use Doxygen for documentation generation:
.PHONY: docs
docs:
doxygen
Running make docs
will execute the doxygen
command to generate documentation.
11.2.2 Running Tests
To run your project’s test suite, you can create a target called test
:
.PHONY: test
test:
./run_tests.sh
In this example, the test
target executes a script (run_tests.sh
) that runs your project’s test cases.
11.3 Automating Dependency Cleanup
If your Makefile generates dependency files (as discussed in section 9), you can create a target to clean up these files when no longer needed:
.PHONY: clean-deps
clean-deps:
rm -f *.d
The clean-deps
target removes all generated dependency files (*.d
) from the project directory.
11.4 Conditional Maintenance Targets
You can use conditional statements to control when maintenance targets should be executed. For example, you might want to generate documentation only for specific build configurations:
DEBUG ?= 0
ifeq ($(DEBUG), 1)
.PHONY: docs
docs:
doxygen
endif
In this example, the docs
target is defined and marked as phony only if the DEBUG
variable is set to 1
, ensuring that documentation is generated only for debugging builds.
11.5 Conclusion
Cleaning and maintaining a project are essential aspects of software development, and Makefiles offer convenient ways to automate these tasks. By creating cleaning and maintenance targets, you can keep your project directory organized and up-to-date. Additionally, using conditional statements allows you to control when these targets are executed, ensuring they align with your project’s needs and build configurations. Understanding and effectively utilizing these features in Makefiles is crucial for managing complex software projects efficiently.
Certainly, let’s expand on the twelfth section, “Advanced Techniques and Best Practices,” to provide a more detailed explanation of advanced Makefile techniques and best practices that can help you create efficient and maintainable build systems.
Advanced Techniques and Best Practices in Makefiles
Advanced techniques and best practices in Makefiles can significantly improve the efficiency and maintainability of your build system. In this section, we’ll explore some advanced techniques and best practices that can elevate your Makefile skills.
Use Variables for Compiler and Flags
Using variables to store compiler and flag settings in your Makefile makes it more maintainable and adaptable. For example:
CC = gcc
CFLAGS = -Wall -O2
By defining these variables, you can easily change the compiler or compiler flags in one place, making it less error-prone and more flexible.
Phony Targets
Always mark targets that don’t correspond to actual files (e.g., clean
, all
, test
, docs
) as phony using the .PHONY
special target. This helps prevent conflicts with files of the same name and ensures that the target is always executed, even if a file with the same name exists.
.PHONY: clean test docs
Use Wildcards for Source Files
Instead of listing all source files manually, you can use wildcards to automatically detect source files in a directory. For example, to compile all .c
files in the current directory:
SOURCES = $(wildcard *.c)
This approach is more maintainable as it automatically adapts to changes in the directory.
Generating Dependency Files Automatically
Automatically generating dependency files for C/C++ projects using tools like gcc -M
(as discussed in section 9) is a powerful technique. It ensures that your Makefile accurately tracks header file dependencies, reducing the risk of broken builds.
-include $(wildcard *.d)
Conditional Compilation
Conditional compilation (as discussed in section 8) allows you to adapt your build process to different configurations or platforms. This can be useful for enabling or disabling features, setting compiler flags conditionally, or specifying different build paths.
Separate Directories for Object Files
Organizing object files in a separate directory (e.g., obj/
) instead of cluttering the source directory can make your project structure cleaner and avoid conflicts between object files and source files with the same names.
OBJ_DIR = obj
OBJECTS = $(addprefix $(OBJ_DIR)/, $(SOURCES:.c=.o))
$(OBJ_DIR)/%.o: %.c
$(CC) -MMD -MP -MF $(OBJ_DIR)/$*.d $(CFLAGS) -c -o $@ $<
Target-Specific Variables
You can set variables that are specific to a particular target. This allows you to customize compilation flags or settings for specific source files or targets.
my_program: main.c
$(CC) $(CFLAGS) -o my_program main.c
special_target: special.c
$(CC) $(CFLAGS_SPECIAL) -o special_target special.c
Here, CFLAGS_SPECIAL
is used only for the special_target
.
Parallel Builds
You can use the -j
flag with the make
command to enable parallel builds, which can significantly reduce build times on multi-core systems. For example, make -j4
will run up to four jobs concurrently.
Version Control Integration
If you’re using a version control system like Git, consider adding a .gitignore
file to ignore generated files, object files, and build artifacts. This keeps your repository clean and avoids tracking unnecessary files.
Continuous Integration
Integrate your Makefile with a continuous integration (CI) system like Jenkins, Travis CI, or GitHub Actions. This ensures that your project is automatically built and tested on every push to the repository, helping catch issues early.
Debugging Makefiles
When debugging Makefiles, you can use the -n
or --just-print
flag with make
to see the commands that would be executed without actually running them. This can help identify issues in your rules and dependencies. A common mistake is not starting a line for a command with the TAB or using an editor which replaces TAB with 4 or 8 spaces.
Testing and Validation
Regularly test and validate your Makefiles with various build configurations and platforms to ensure they work correctly in different scenarios. Automated testing of the build process can be invaluable in catching regressions.
Modularization
For complex projects, consider modularizing your Makefile by splitting it into multiple smaller Makefiles or including separate Makefiles for specific components or subsystems. This can make the build system more manageable.
Build Targets
Define clear and specific build targets (e.g., all
, clean
, test
, docs
, install
) to standardize the build process across your projects and make it easier for team members to understand and use the Makefile.
Error Handling
Implement error handling in your Makefile to detect and report errors during the build process. You can use constructs like ||
to execute commands conditionally based on the success of previous commands.
Continuous Learning
Keep exploring advanced Makefile techniques, best practices, and new features as you continue to work on different projects. Makefiles are a versatile tool, and there’s always more to learn.
Conclusion
Advanced techniques and best practices in Makefiles can significantly enhance the efficiency, reliability, and maintainability of your build systems. By applying these practices, you can create robust and adaptable Makefiles that streamline the development and deployment of your software projects. Continuously improving your Makefile skills is a valuable asset in software development.
Summary
In this tutorial on make for programmers, we covered a wide range of topics to help you understand and effectively use Makefiles in your software development projects. Here’s a summary of the key points covered in the sections:
Basic Makefile Structure: The fundamental structure of a Makefile, including rules, targets, and commands.
Target Rules and Dependencies: How to define targets and their dependencies, ensuring that Make knows when to rebuild a target.
Implicit Rules and Variables: Implicit rules that Make uses by default and how to override them using variables.
User-Defined Variables: How to define your own variables in Makefiles to make them more flexible and maintainable.
Phony Targets: The concept of phony targets for defining actions or tasks that don’t produce files, and their practical usage.
Dependency Management: How Make manages dependencies and automatically rebuilds targets when dependencies change.
Conditional Statements: Using conditional statements to create rules and targets that adapt to different conditions or configurations.
Pattern Rules and Automatic Prerequisites: How to use pattern rules to build targets with similar patterns and automatically generate dependency information.
Managing Libraries and Linking: Including libraries in your Makefile, specifying library directories, and handling advanced linking.
Cleaning and Maintenance: Creating cleaning and maintenance targets, handling project maintenance, and automating dependency cleanup.
Advanced Techniques and Best Practices: Advanced techniques and best practices for more efficient and maintainable Makefiles, including using variables, phony targets, wildcards, and version control integration.
By understanding and applying the concepts and techniques discussed in this tutorial, you can create robust and efficient Makefiles to automate your build processes, manage dependencies, and maintain your software projects effectively. Makefiles are a valuable tool in the arsenal of any developer, helping to streamline the development workflow and ensure consistent, reliable builds.
LS0tDQp0aXRsZTogIlRoZSAnbWFrZScgVXRpbGl0eSBhbmQgV3JpdGluZyBNYWtlZmlsZXMiDQpwYXJhbXM6DQogIGNhdGVnb3J5OiAxDQogIG51bWJlcjogOTAxDQogIHRpbWU6ICI2MCBtaW4iDQogIGxldmVsOiBiZWdpbm5lcg0KICB0YWdzOiBtYWtlLG1ha2VmaWxlLEMsQysrLFVuaXgscHJvZ3JhbW1pbmcNCiAgZGVzY3JpcHRpb246ICJJbnRyb2R1Y2VzIG1ha2VmaWxlcyBhbmQgdGhlaXIgdXNlIGluIGJ1aWxkaW5nDQogICAgICAgICAgICAgICAgcHJvZ3JhbXMsIHByaW1hcmlseSBmb3IgQyBhbmQgQysrLiINCmRhdGU6ICI8c21hbGw+YHIgU3lzLkRhdGUoKWA8L3NtYWxsPiINCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiINCmVtYWlsOiAibS5zY2hlZGxiYXVlckBuZXUuZWR1Ig0KYWZmaWxpdGF0aW9uOiAiTm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHkiDQpvdXRwdXQ6IA0KICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHNwYWNlbGFiDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KLS0tDQoNCi0tLQ0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiINCi0tLQ0KDQpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRX0NCmBgYA0KDQojIyBJbnRyb2R1Y3Rpb24NCg0KIyMjIFdoYXQgaXMgTWFrZT8NCg0KYG1ha2VgIGlzIGEgcG93ZXJmdWwgYW5kIHdpZGVseSB1c2VkIGJ1aWxkIGF1dG9tYXRpb24gdG9vbCBpbiBzb2Z0d2FyZSBkZXZlbG9wbWVudCwgZXNwZWNpYWxseSBmb3IgQyBhbmQgQysrLCBidXQgYWxzbyBKYXZhIGFuZCBtYW55IG90aGVyIHByb2dyYW1taW5nIGxhbmd1YWdlcy4gSXQgaXMgZGVzaWduZWQgdG8gaGVscCBwcm9ncmFtbWVycyBtYW5hZ2UgY29tcGxleCBwcm9qZWN0cyBieSBhdXRvbWF0aW5nIHRoZSBwcm9jZXNzIG9mIGJ1aWxkaW5nIGV4ZWN1dGFibGUgZmlsZXMsIGxpYnJhcmllcywgb3Igb3RoZXIgYXJ0aWZhY3RzIGZyb20gc291cmNlIGNvZGUuIE1ha2UgaXMgcGFydGljdWxhcmx5IHZhbHVhYmxlIHdoZW4geW91IGhhdmUgbXVsdGlwbGUgc291cmNlIGZpbGVzLCBkZXBlbmRlbmNpZXMsIGFuZCBjb21waWxhdGlvbiBzdGVwcyBpbiB5b3VyIHByb2plY3QuDQoNClRoZSAqbWFrZSogcHJvZ3JhbSBpcyBhIHN0YW5kYXJkIHV0aWxpdHkgZm9yIFVuaXgvTGludXggYW5kIGlzIGFsc28gYXZhaWxhYmxlIG9uIE1hY09TIGFzIHBhcnQgb2YgeGNvZGUuIEZvciBvdGhlciBwbGF0Zm9ybXMsIHRoZXJlIGFyZSBtYW55IG9wZW4gc291cmNlIHZlcnNpb25zIG9mICptYWtlKi4NCg0KSW50ZXJwcmV0ZWQgbGFuZ3VhZ2VzIHN1Y2ggYXMgUHl0aG9uIG9yIFIgZG8gbm90IHJlcXVpcmUgYSBmYWNpbGl0eSBzaW1pbGFyIHRvICptYWtlKi4gVGhpcyB0dXRvcmlhbCBmb2N1c2VzIG9uIEdOVSAqbWFrZSogd2hpY2ggaGFzIGJlY29tZSB0aGUgc3RhbmRhcmQuIFdlIHdpbGwgZXhwbGFpbiB0aGUga2V5IGVsZW1lbnRzIG9mIGJ1aWxkaW5nIGEgIm1ha2VmaWxlIiB3aGljaCBhcmUgc3RhbmRhcmQgYWNyb3NzIG1vc3QgTGludXggc3lzdGVtcyAoYW5kIE1hY09TKS4gTWFueSBpbnRlZ3JhdGVkIGRldmVsb3BtZW50IGVudmlyb25tZW50cyAoc3VjaCBhcyBFY2xpcHNlKSB1c2Ugc29tZSB2ZXJzaW9uIG9mIGEgKm1ha2UqIGZhY2lsaXR5IGFsdGhvdWdoIHRoZXkgb2Z0ZW4gdXNlIFhNTCB0byBzcGVjaWZ5IGRlcGVuZGVuY2llcyByYXRoZXIgdGhhbiBhIHRyYWRpdGlvbmFsIG1ha2VmaWxlLCBvZnRlbiB1c2luZyB0aGUgdXRpbGl0eSAqYW50KiByYXRoZXIgdGhhbiAqbWFrZSouDQoNCiMjIyBXaHkgVXNlIE1ha2U/DQoNClRoZXJlIGFyZSBtYW55IHJlYXNvbnMgd2h5ICptYWtlKiBpcyBzbyB3aWRlbHkgdXNlZC4gV2Ugd2lsbCB0YWtlIGEgbG9vayBhdCBhIGZldyByZWFzb25zIGJlbG93Lg0KDQojIyMjIERlcGVuZGVuY3kgTWFuYWdlbWVudA0KDQpPbmUgb2YgdGhlIHByaW1hcnkgcmVhc29ucyBmb3IgdXNpbmcgYG1ha2VgIGlzIGl0cyBhYmlsaXR5IHRvIG1hbmFnZSBkZXBlbmRlbmNpZXMgZWZmaWNpZW50bHkuIEluIGEgdHlwaWNhbCBzb2Z0d2FyZSBwcm9qZWN0LCB5b3UgaGF2ZSBzb3VyY2UgZmlsZXMgdGhhdCBkZXBlbmQgb24gZWFjaCBvdGhlciwgY29uZmlndXJhdGlvbiBmaWxlcywgbGlicmFyaWVzLCBhbmQgb3RoZXIgcmVzb3VyY2VzLiBgbWFrZWAgdHJhY2tzIHRoZXNlIGRlcGVuZGVuY2llcyBhbmQgZW5zdXJlcyB0aGF0IG9ubHkgdGhlIG5lY2Vzc2FyeSBwYXJ0cyBvZiB5b3VyIHByb2plY3QgYXJlIHJlYnVpbHQgd2hlbiBzb21ldGhpbmcgY2hhbmdlcy4gVGhpcyBmZWF0dXJlIHNhdmVzIHRpbWUgYW5kIHByZXZlbnRzIHVubmVjZXNzYXJ5IHJlY29tcGlsYXRpb24uDQoNCiMjIyMgQXV0b21hdGlvbg0KDQpNYWtlIGF1dG9tYXRlcyByZXBldGl0aXZlIGFuZCBlcnJvci1wcm9uZSB0YXNrcyBpbnZvbHZlZCBpbiB0aGUgYnVpbGQgcHJvY2Vzcy4gSW5zdGVhZCBvZiBtYW51YWxseSB0eXBpbmcgb3V0IGxvbmcgY29tcGlsYXRpb24gY29tbWFuZHMsIGxpbmtpbmcgc3RlcHMsIGFuZCBvdGhlciB0YXNrcywgeW91IGRlZmluZSBydWxlcyBhbmQgbGV0IGBtYWtlYCBoYW5kbGUgdGhlIGRldGFpbHMuIFRoaXMgbm90IG9ubHkgcmVkdWNlcyB0aGUgY2hhbmNlcyBvZiBodW1hbiBlcnJvciBidXQgYWxzbyBtYWtlcyB5b3VyIGJ1aWxkIHByb2Nlc3MgY29uc2lzdGVudCBhbmQgcmVwcm9kdWNpYmxlLg0KDQojIyMjIFBvcnRhYmlsaXR5DQoNCmBtYWtlYCBpcyBwbGF0Zm9ybS1pbmRlcGVuZGVudCwgd2hpY2ggbWVhbnMgeW91IGNhbiB1c2UgdGhlIHNhbWUgTWFrZWZpbGUgKHRoZSBjb25maWd1cmF0aW9uIGZpbGUgZm9yIGBtYWtlYCkgb24gZGlmZmVyZW50IG9wZXJhdGluZyBzeXN0ZW1zLiBUaGlzIHBvcnRhYmlsaXR5IG1ha2VzIGl0IGFuIGF0dHJhY3RpdmUgY2hvaWNlIGZvciBjcm9zcy1wbGF0Zm9ybSBkZXZlbG9wbWVudC4NCg0KIyMjIyBDdXN0b21pemF0aW9uDQoNCk1ha2UgaXMgaGlnaGx5IGN1c3RvbWl6YWJsZS4gWW91IGNhbiB0YWlsb3IgeW91ciBidWlsZCBwcm9jZXNzIHRvIHN1aXQgeW91ciBwcm9qZWN0J3Mgc3BlY2lmaWMgcmVxdWlyZW1lbnRzLiBEZWZpbmUgdmFyaWFibGVzLCBydWxlcywgYW5kIHRhcmdldHMgaW4geW91ciBNYWtlZmlsZSB0byBhY2NvbW1vZGF0ZSBkaWZmZXJlbnQgYnVpbGQgY29uZmlndXJhdGlvbnMsIGRldmVsb3BtZW50IGVudmlyb25tZW50cywgb3IgZGVwbG95bWVudCBwbGF0Zm9ybXMuDQoNCiMjIyBXaGVuIHRvIFVzZSBNYWtlDQoNCllvdSBzaG91bGQgY29uc2lkZXIgdXNpbmcgYG1ha2VgIHdoZW46DQoNCi0gICBZb3UncmUgd29ya2luZyBvbiBhIHByb2plY3Qgd2l0aCBtdWx0aXBsZSBzb3VyY2UgZmlsZXMgdGhhdCBuZWVkIHRvIGJlIGNvbXBpbGVkIGFuZCBsaW5rZWQuDQotICAgWW91IHdhbnQgdG8gYXV0b21hdGUgcmVwZXRpdGl2ZSB0YXNrcyBzdWNoIGFzIGJ1aWxkaW5nLCB0ZXN0aW5nLCBhbmQgY2xlYW5pbmcgeW91ciBwcm9qZWN0Lg0KLSAgIFlvdSBuZWVkIGEgdG9vbCB0aGF0IG1hbmFnZXMgZGVwZW5kZW5jaWVzIGFuZCBlbnN1cmVzIHRoYXQgb25seSBuZWNlc3NhcnkgcGFydHMgb2YgdGhlIHByb2plY3QgYXJlIHJlYnVpbHQuDQotICAgWW91ciBwcm9qZWN0IG5lZWRzIHRvIGJlIGNyb3NzLXBsYXRmb3JtLCBhbmQgeW91IHdhbnQgYSBidWlsZCBzeXN0ZW0gdGhhdCB3b3JrcyBjb25zaXN0ZW50bHkgb24gZGlmZmVyZW50IG9wZXJhdGluZyBzeXN0ZW1zLg0KLSAgIFlvdSB2YWx1ZSBhIGhpZ2ggZGVncmVlIG9mIGN1c3RvbWl6YXRpb24gYW5kIGNvbnRyb2wgb3ZlciB0aGUgYnVpbGQgcHJvY2Vzcy4NCg0KSW4gc2hvcnQsIGBtYWtlYCBpcyBhIGZ1bmRhbWVudGFsIHRvb2wgZm9yIHByb2dyYW1tZXJzIGFuZCBzb2Z0d2FyZSBkZXZlbG9wZXJzLiBJdCBzdHJlYW1saW5lcyB0aGUgYnVpbGQgcHJvY2VzcywgbWFuYWdlcyBkZXBlbmRlbmNpZXMsIGFuZCBhdXRvbWF0ZXMgdGFza3MsIHVsdGltYXRlbHkgbGVhZGluZyB0byBtb3JlIGVmZmljaWVudCBhbmQgbWFpbnRhaW5hYmxlIHNvZnR3YXJlIGRldmVsb3BtZW50IHByb2plY3RzLiBJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb25zIG9mIHRoaXMgdHV0b3JpYWwsIHdlIHdpbGwgZGl2ZSBkZWVwZXIgaW50byBob3cgdG8gdXNlIGBtYWtlYCBlZmZlY3RpdmVseSB0byBtYW5hZ2UgeW91ciBwcm9qZWN0cy4NCg0KIyMjIE1ha2VmaWxlcw0KDQpNYWtlZmlsZXMgYXJlIGFuIGltcG9ydGFudCBlbGVtZW50IG9mIHByb2dyYW1taW5nLCBlc3BlY2lhbGx5IGluIEMgYW5kIEMrKyBvbiBVbml4LCBhbHRob3VnaCB0aGV5IGNhbiBiZSBmb3VuZCBvbiBvdGhlciBwbGF0Zm9ybXMgYW5kIGZvciBvdGhlciBwdXJwb3NlcyBhcyB3ZWxsLiBFc3NlbnRpYWxseSwgbWFrZWZpbGVzIGFyZSB0ZXh0IGZpbGVzIGNvbnRhaW5pbmcgdGhlIHJ1bGVzIG9uIGhvdyBhbiBleGVjdXRhYmxlIHByb2dyYW0gaXMgY3JlYXRlZCBmcm9tIGl0cyBzb3VyY2UgZmlsZXMgYW5kIGluY2x1ZGVkIGxpYnJhcmllcy4gQSBtYWtlZmlsZSBzZXJ2ZXMgYXMgdGhlIGlucHV0IHRvIHRoZSAqbWFrZSogcHJvZ3JhbSB3aGljaCByZWFkIHRoZSBydWxlcyBpbiB0aGUgbWFrZWZpbGUgYW5kIHByb2R1Y2VzIGFuIGV4ZWN1dGFibGUgKHdlbGwsIGEgdGFyZ2V0LCB0byBiZSBzcGVjaWZpYywgd2hpY2ggaXMgbW9zdCBvZnRlbiBhbiBleGVjdXRhYmxlIGJ1dCBkb2Vzbid0IGhhdmUgdG8gYmUpLiAqbWFrZSogYXBwbGllcyB0aGUgcnVsZXMgYW5kIG9ubHkgY29tcGlsZXMgd2hhdCBoYXMgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCAiYnVpbGQiIG9mIHRoZSBleGVjdXRhYmxlLiBUaGlzIGlzIGlkZWFsIHdoZW4gYSBwcm9qZWN0IGNvbnNpc3RzIG9mIG1hbnkgc291cmNlIGZpbGVzIGFuZCBhIGNoYW5nZSBpbiBvbmUgd291bGQgbm90IHJlcXVpcmUgY29tcGlsaW5nIGFsbC4gVW5mb3J0dW5hdGVseSwgbWFrZWZpbGVzIGFyZSBhIGJpdCBlc290ZXJpYyBhbmQgdGhlIHJ1bGVzIGNhbiBiZSBhIGJpdCBiYWZmbGluZyBub3dhZGF5cyAtLSBhZnRlciBhbGwsIHRoZXkgd2VyZSBkZXZlbG9wZWQgb3ZlciBmaWZ0eSB5ZWFycyBhZ28gd2hlbiBkZXZlbG9wbWVudCB0b29scyB3ZXJlIHF1aXRlIGRpZmZlcmVudC4NCg0KTWFrZWZpbGVzIGNvbnRhaW4gdGFyZ2V0cyBhbmQgZGVwZW5kZW5jeSBydWxlcy4gSWYgYW55IHNvdXJjZSBmaWxlJ3MgZGVwZW5kZW5jaWVzIGNoYW5nZSB0aGVuIHRoZSBzb3VyY2UgZmlsZSB3aWxsIGdldCByZS1jb21waWxlZCBhbmQgdGhlIG5ldyBleGVjdXRhYmxlIGlzIGxpbmtlZC4NCg0KIyMgQSBTaW1wbGUgRXhhbXBsZQ0KDQojIyMgUnVubmluZyAnbWFrZScNCg0KVGhlICdtYWtlJyBjb21tYW5kIGlzIHJ1biBmcm9tIHRoZSB0ZXJtaW5hbCAoKmFrYSogYSBzaGVsbCkuDQoNCmBgYCAgICAgICAgIA0KJSBtYWtlIHRhcmdldA0KYGBgDQoNCldoZW4gJ21ha2UnIGlzIHJ1biwgaXQgbG9va3MgZm9yIGEgZmlsZSBuYW1lZCAqTWFrZWZpbGUqIGluIHRoZSBjdXJyZW50IGZvbGRlci4gTm90ZSB0aGUgY2FwaXRhbGl6YXRpb24gb2YgdGhlIGZpbGUgLS0gaXQgaXMgaW1wb3J0YW50Lg0KDQpMZXQncyBkbyB0aGUgY2xhc3NpYyAiSGVsbG8gV29ybGQiIHByb2dyYW0gYXMgYSBtYWtlZmlsZS4gQmVsb3cgaXMgdGhlIGNvbnRlbnRzIG9mIGEgcmVhbGx5IHNpbXBsZSBtYWtlZmlsZSAoY2FsbGVkICpNYWtlZmlsZSopLg0KDQpgYGAgICAgICAgICANCmhlbGxvOg0KICAgIGVjaG8gIkhlbGxvLCBXb3JsZCINCmBgYA0KDQoqKkltcG9ydGFudCoqOiBSdWxlcyBtdXN0IGJlIGluZGVudGVkIGJ5IGEgVEFCIGFuZCBub3Qgc3BhY2VzLiBTbywgaGl0IHRoZSBgVEFCYCBrZXkgaW4geW91ciBrZXlib2FyZCBhbmQgZG8gbm90IHR5cGUgc3BhY2VzIHdpdGggdGhlIHNwYWNlYmFyIG9uIHlvdXIga2V5Ym9hcmQuIFRoaXMgaXMgb25lIG9mIHRoZSBtb3N0IGNvbW1vbiBtaXN0YWtlcyB0aGF0IGJlZ2lubmVycyBydW4gaW50by4NCg0KT25jZSB5b3UgaGF2ZSB0aGUgbWFrZWZpbGUsICJleGVjdXRlIGl0IiBieSBydW5uaW5nIHRoZSBgbWFrZWAgcHJvZ3JhbS4NCg0KYGBgICAgICAgICAgDQolIG1ha2UNCmBgYA0KDQpOb3Qgc3BlY2lmeWluZyBhIHRhcmdldCBmb3IgYG1ha2VgIG1lYW5zIHRoYXQgaXQgYnVpbGRzIHRoZSBmaXJzdCB0YXJnZXQgaXQgZmluZHMuDQoNCiMjIyMgVHJ5IGl0IG91dCBmb3IgeW91cnNlbGYNCg0KR28gdG8gdGhlIHRlcm1pbmFsLCBjcmVhdGUgYSBmb2xkZXIgaW4gd2hpY2ggeW91IGNhbiBkbyB0aGlzIGxlc3NvbiwgYW5kIHVzZSBhIHRleHQgZWRpdG9yICgqZS5nLiosICp2aSopIHRvIGNyZWF0ZSBhIGZpbGUgY2FsbGVkICpNYWtlZmlsZSogYW5kIGFkZCB0aGUgYWJvdmUuDQoNCiMjIyBTaW1wbGUgQnVpbGQgRmlsZSBFeGFtcGxlDQoNCk1ha2VmaWxlcyBhcmUgYnVpbGQgZmlsZXMgZm9yIHByb2plY3RzIGFuZCB0aGV5IGNvbnRhaW5zIGFsbCBjb21tYW5kIHRvIGNvbXBpbGUsIGxpbmssIGNvcHksIG9yIG1vdmUgZmlsZXMgYW5kIHJ1biBzY3JpcHRzLiBCZWxvdyBpcyBhIHNpbXBsZSBleGFtcGxlLg0KDQpgYGAge2F0dHIuc291cmNlPSIubnVtYmVyTGluZXMifQ0KYWxsOiBtdWx0aXRocmVhZA0KDQptdWx0aXRocmVhZDogbXVsdGl0aHJlYWQuYw0KICAgIGdjYyAtbyBtdWx0aXRocmVhZCBtdWx0aXRocmVhZC5jDQpgYGANCg0KQWdhaW4sIGp1c3QgYXMgYSByZW1pbmRlcjogdGhlIGluZGVudCBiZWZvcmUgKmdjYyogaXMgYSBUQUIgYW5kIG5vdCBzcGFjZXMuDQoNCkdlbmVyYWxseSBtYWtlZmlsZXMgY29udGFpbiBhIHRhcmdldCBuYW1lZCAqYWxsKiB0aGF0IGJ1aWxkcyB0aGUgZW50aXJlIHByb2plY3QuIEl0IGluY2x1ZGVzIGFsbCBvZiB0aGUgc3ViIHRhcmdldHMsIHN1Y2ggYXMgaW5kaXZpZHVhbCBleGVjdXRhYmxlcywgdGVzdCBkcml2ZXJzLCBpbnN0YWxsYXRpb24gc2NyaXB0cywgYW5kIHNvIGZvcnRoLg0KDQpTbywgaW4gdGhlIGFib3ZlIGV4YW1wbGUsICphbGwqIGRlcGVuZHMgb24gKm11bHRpdGhyZWFkKiB0byBiZSB1cC10by1kYXRlLCB3aGljaCwgaW4gdHVybiwgZGVwZW5kcyBvbiAqbXVsdGl0aHJlYWQuYyouIFNvLCBpZiAqbXVsdGl0aHJlYWQuYyogY2hhbmdlcywgdGhlbiBpdCBmb3JjZXMgdGhlIHJ1bGVzIHRvIGJlIGFwcGxpZWQgYW5kIGFueSBjb21tYW5kcyBiZWxvdyB0aGF0IHJ1bGUgYXJlIHJ1bi4gSW4gdGhlIGFib3ZlIGV4YW1wbGUsIHRoYXQgd291bGQgYmUgdGhlIGNvbXBpbGF0aW9uIGFuZCBsaW5raW5nIHdpdGggKmdjYyouDQoNClRvIGluaXRpYXRlIHRoZSBmdWxsIGJ1aWxkLCBjYWxsIGBtYWtlIGFsbGAgb3Igc2ltcGx5IGBtYWtlYCBhcyAqYWxsKiBpcyB0aGUgZmlyc3QgdGFyZ2V0Lg0KDQojIyMgTWFrZWZpbGUgU3RydWN0dXJlIGFuZCBTeW50YXgNCg0KQSBNYWtlZmlsZSBjb25zaXN0cyBvZiBhIHNldCBvZiBydWxlcy4gQSBydWxlIGdlbmVyYWxseSBsb29rcyBsaWtlIHRoaXM6DQoNCmBgYCAgICAgICAgIA0KdGFyZ2V0OiBwcmVyZXF1aXNpdGVzDQogICAgY29tbWFuZA0KICAgIGNvbW1hbmQNCiAgICBjb21tYW5kDQpgYGANCg0KVGhlIGNvbW1hbmRzIGFyZSB0aGUgc3RlcHMgcmVxdWlyZWQgdG8gYnVpbGQgdGhlIHRhcmdldC4gVGhlc2UgbmVlZCB0byBzdGFydCB3aXRoIGEgYHRhYmAgY2hhcmFjdGVyIGFuZCBub3Qgc3BhY2VzLiBUaGUgcHJlcmVxdWlzaXRlcyBhcmUgZ2VuZXJhbGx5IGZpbGUgbmFtZXMsIHNlcGFyYXRlZCBieSBzcGFjZXMuIFRoZXNlIGZpbGVzIG5lZWQgdG8gZXhpc3QgYmVmb3JlIHRoZSBjb21tYW5kcyBmb3IgdGhlIHRhcmdldCBhcmUgcnVuLiBUaGV5IGRlZmluZSBkZXBlbmRlbmNpZXMuDQoNCiMjIyBUYXJnZXQgJ2NsZWFuJw0KDQpNb3N0IG1ha2VmaWxlcyBpbmNsdWRlcyBhIHJ1bGUgZm9yIGEgdGFyZ2V0IG5hbWVkICpjbGVhbiogdGhhdCBpcyBpbnZva2VkIHdpdGggYG1ha2UgY2xlYW5gLiBJdCdzIHB1cnBvc2UgaXMgdG8gY2xlYW4gdXAgeW91ciBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCByZW1vdmUgdGhlIG91dHB1dCBvZiBvdGhlciB0YXJnZXRzLiBOb3RlIHRoYXQgaXMgc2hvdWxkIG5vdCBiZSB0aGUgZmlyc3QgdGFyZ2V0IGFzIGl0IHdvdWxkIHRoZW4gYmUgdGhlIGRlZmF1bHQgdGFyZ2V0OyB0aGUgZGVmYXVsdCB0YXJnZXQgc2hvdWxkIGJlICphbGwqLg0KDQpIZXJlIGlzIGFuIGV4YW1wbGUgb2YgYSAqY2xlYW4qIHRhcmdldCBmb3IgYSBzaW1wbGUgcHJvamVjdC4NCg0KYGBgICAgICAgICAgDQpjbGVhbjoNCiAgICBybSAtZiBtdWx0aXRocmVhZA0KICAgIHRvdWNoIG11bHRpdGhyZWFkLmMNCmBgYA0KDQpUaGUgcnVsZSByZW1vdmVzIHRoZSBleGVjdXRhYmxlIGFuZCB1cGRhdGVzIHRoZSB0aW1lIHN0YW1wIG9mIGxhc3QgbW9kaWZpY2F0aW9uIG9mIHRoZSBzb3VyY2UgZmlsZSB0byB0aGUgcHJlc2VudCB0aW1lLCB3aGljaCB3b3VsZCBmb3JjZSBhIHJlY29tcGlsZSB0aGUgbmV4dCB0aW1lIHlvdSBpbnZva2VkIGBtYWtlIGFsbGAuDQoNCiMjIENlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBzZWNvbmQgc2VjdGlvbiwgIkJhc2ljIE1ha2VmaWxlIFN0cnVjdHVyZSwiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIHRoZSBjb21wb25lbnRzIG9mIGEgTWFrZWZpbGUgYW5kIGhvdyB0aGV5IHdvcmsgdG9nZXRoZXIuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyBCYXNpYyBNYWtlZmlsZSBTdHJ1Y3R1cmUNCg0KQSAiTWFrZWZpbGUiIGlzIGEgdGV4dCBmaWxlIHdpdGggdGhlIG5hbWUgKk1ha2VmaWxlKiAoc3BlbGxlZCBqdXN0IGxpa2UgdGhhdCB3aXRoIGEgY2FwaXRhbCAnTScpIHRoYXQgY29udGFpbnMgaW5zdHJ1Y3Rpb25zIGZvciB0aGUgYG1ha2VgIHV0aWxpdHkgb24gaG93IHRvIGJ1aWxkIGEgcHJvamVjdC4gSXQgY29uc2lzdHMgb2YgcnVsZXMgYW5kIHRhcmdldHMsIHdoaWNoIGFyZSB0aGUgYnVpbGRpbmcgYmxvY2tzIG9mIHRoZSBNYWtlZmlsZS4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGRlbHZlIGludG8gdGhlIGJhc2ljIHN0cnVjdHVyZSBvZiBhIE1ha2VmaWxlIGFuZCBleHBsYWluIGhvdyBpdCB3b3Jrcy4NCg0KIyMjIFJ1bGVzIGFuZCBUYXJnZXRzDQoNCiMjIyMgVGFyZ2V0cw0KDQpBICoqdGFyZ2V0KiogaW4gYSBNYWtlZmlsZSByZXByZXNlbnRzIGFuIG91dHB1dCBmaWxlIG9yIGFuIGFjdGlvbiB0aGF0IGBtYWtlYCBzaG91bGQgcGVyZm9ybS4gVGFyZ2V0cyBhcmUgdGhlIGdvYWxzIG9mIHlvdXIgYnVpbGQgcHJvY2Vzcywgc3VjaCBhcyBleGVjdXRhYmxlcywgb2JqZWN0IGZpbGVzLCBvciBvdGhlciBhcnRpZmFjdHMuIEVhY2ggdGFyZ2V0IGNvcnJlc3BvbmRzIHRvIGEgc3BlY2lmaWMgdGFzayB0aGF0IGBtYWtlYCBjYW4gZXhlY3V0ZS4NCg0KRm9yIGV4YW1wbGUsIGluIGEgQyBvciBDKysgcHJvamVjdCwgeW91IG1pZ2h0IGhhdmUgdGFyZ2V0cyBsaWtlOg0KDQotICAgYG15X3Byb2dyYW1gOiBUbyBidWlsZCB0aGUgZmluYWwgZXhlY3V0YWJsZS4NCi0gICBgbWFpbi5vYCwgYHV0aWwub2A6IFRvIGNvbXBpbGUgaW5kaXZpZHVhbCBzb3VyY2UgZmlsZXMgaW50byBvYmplY3QgZmlsZXMuDQotICAgYGNsZWFuYDogVG8gcmVtb3ZlIGdlbmVyYXRlZCBmaWxlcyBhbmQgY2xlYW4gdXAgdGhlIHByb2plY3QuDQoNCiMjIyMgUnVsZXMNCg0KQSAqKnJ1bGUqKiBkZWZpbmVzIGhvdyB0byBjcmVhdGUgYSB0YXJnZXQgZnJvbSBpdHMgZGVwZW5kZW5jaWVzLiBJdCBjb25zaXN0cyBvZiBhIHRhcmdldCwgYSBjb2xvbiAoYDpgKSwgYW5kIGEgbGlzdCBvZiBkZXBlbmRlbmNpZXMuIEJlbG93IHRoZSBydWxlLCB5b3Ugc3BlY2lmeSB0aGUgY29tbWFuZHMgbmVlZGVkIHRvIGJ1aWxkIHRoZSB0YXJnZXQgZnJvbSBpdHMgZGVwZW5kZW5jaWVzLiBUaGVzZSBjb21tYW5kcyBhcmUgdHlwaWNhbGx5IGluZGVudGVkIHVzaW5nIHRhYnMuDQoNCkhlcmUncyBhIGJhc2ljIHJ1bGUgc3RydWN0dXJlOg0KDQpgYGAgbWFrZQ0KdGFyZ2V0OiBkZXBlbmRlbmNpZXMNCiAgICBbY29tbWFuZHNdDQpgYGANCg0KLSAgICoqVGFyZ2V0Kio6IFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgeW91IHdhbnQgdG8gYnVpbGQuDQotICAgKipEZXBlbmRlbmNpZXMqKjogVGhlIGZpbGVzIG9yIHRhcmdldHMgdGhhdCB0aGUgY3VycmVudCB0YXJnZXQgZGVwZW5kcyBvbi4gVGhlc2UgcmVwcmVzZW50IHRoZSBwcmVyZXF1aXNpdGVzIGZvciBidWlsZGluZyB0aGUgdGFyZ2V0Lg0KLSAgICoqQ29tbWFuZHMqKjogVGhlIHNoZWxsIGNvbW1hbmRzIHRvIGJlIGV4ZWN1dGVkIHdoZW4gYG1ha2VgIGJ1aWxkcyB0aGUgdGFyZ2V0LiBUaGVzZSBjb21tYW5kcyBhcmUgaW5kZW50ZWQgd2l0aCB0YWJzLg0KDQojIyMgRXhhbXBsZSBNYWtlZmlsZQ0KDQpMZXQncyBjcmVhdGUgYSBzaW1wbGUgTWFrZWZpbGUgdG8gY29tcGlsZSBhICJIZWxsbywgV29ybGQhIiBwcm9ncmFtIHdyaXR0ZW4gaW4gQy4NCg0KYGBgIG1ha2UNCiMgRGVmaW5lIHRoZSB0YXJnZXQgYW5kIGl0cyBkZXBlbmRlbmNpZXMNCm15X3Byb2dyYW06IG1haW4ubw0KDQojIENvbXBpbGUgdGhlIHByb2dyYW0NCm1haW4ubzogbWFpbi5jDQogICAgZ2NjIC1vIG1haW4ubyAtYyBtYWluLmMNCg0KIyBDbGVhbiB1cCBnZW5lcmF0ZWQgZmlsZXMNCmNsZWFuOg0KICAgIHJtIC1mIG15X3Byb2dyYW0gbWFpbi5vDQpgYGANCg0KSW4gdGhpcyBNYWtlZmlsZToNCg0KLSAgIGBteV9wcm9ncmFtYCBpcyB0aGUgdGFyZ2V0LCBhbmQgaXQgZGVwZW5kcyBvbiBgbWFpbi5vYC4NCi0gICBgbWFpbi5vYCBpcyBhbm90aGVyIHRhcmdldCwgd2hpY2ggZGVwZW5kcyBvbiBgbWFpbi5jYC4NCi0gICBUaGUgYGdjY2AgY29tbWFuZCBpcyB1c2VkIHRvIGNvbXBpbGUgYG1haW4uY2AgaW50byBhbiBvYmplY3QgZmlsZSAoYG1haW4ub2ApLg0KLSAgIFRoZSBgY2xlYW5gIHRhcmdldCBpcyB1c2VkIHRvIHJlbW92ZSB0aGUgZ2VuZXJhdGVkIGZpbGVzIHdoZW4geW91IHJ1biBgbWFrZSBjbGVhbmAuDQoNCiMjIyBIb3cgYG1ha2VgIFdvcmtzDQoNCldoZW4geW91IHJ1biBgbWFrZWAgaW4gdGhlIGNvbW1hbmQgbGluZSB3aXRob3V0IHNwZWNpZnlpbmcgYSB0YXJnZXQsIGl0IGxvb2tzIGZvciBhIHNwZWNpYWwgdGFyZ2V0IGNhbGxlZCB0aGUgKipkZWZhdWx0IHRhcmdldCoqLiBCeSBjb252ZW50aW9uLCB0aGlzIGlzIG9mdGVuIG5hbWVkIGBhbGxgLiBJZiB5b3UgaGF2ZSBhbiBgYWxsYCB0YXJnZXQgaW4geW91ciBNYWtlZmlsZSwgYG1ha2VgIHdpbGwgZXhlY3V0ZSB0aGUgY29tbWFuZHMgYXNzb2NpYXRlZCB3aXRoIHRoYXQgdGFyZ2V0Lg0KDQpGb3IgZXhhbXBsZToNCg0KYGBgIG1ha2UNCmFsbDogbXlfcHJvZ3JhbQ0KYGBgDQoNCldoZW4geW91IHJ1biBgbWFrZWAgd2l0aG91dCBhcmd1bWVudHMsIGl0IHdpbGwgZXhlY3V0ZSB0aGUgYGFsbGAgdGFyZ2V0LCB3aGljaCBkZXBlbmRzIG9uIGBteV9wcm9ncmFtYC4gVGh1cywgaXQgd2lsbCBidWlsZCBgbXlfcHJvZ3JhbWAgYW5kIGl0cyBkZXBlbmRlbmNpZXMuDQoNClRvIHN1bW1hcml6ZSwgYSBNYWtlZmlsZSBjb25zaXN0cyBvZiBydWxlcyBhbmQgdGFyZ2V0cy4gUnVsZXMgc3BlY2lmeSBob3cgdG8gYnVpbGQgdGFyZ2V0cyBmcm9tIHRoZWlyIGRlcGVuZGVuY2llcy4gV2hlbiB5b3UgcnVuIGBtYWtlYCwgaXQgcmVhZHMgdGhlIE1ha2VmaWxlLCBkZXRlcm1pbmVzIHdoaWNoIHRhcmdldHMgbmVlZCB0byBiZSBidWlsdCBvciByZWJ1aWx0IGJhc2VkIG9uIGZpbGUgdGltZXN0YW1wcyBhbmQgZGVwZW5kZW5jaWVzLCBhbmQgdGhlbiBleGVjdXRlcyB0aGUgY29ycmVzcG9uZGluZyBjb21tYW5kcy4gVW5kZXJzdGFuZGluZyB0aGlzIGJhc2ljIHN0cnVjdHVyZSBpcyBjcnVjaWFsIGZvciBjcmVhdGluZyBtb3JlIGNvbXBsZXggYW5kIGVmZmljaWVudCBNYWtlZmlsZXMgZm9yIHlvdXIgcHJvamVjdHMuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSB0aGlyZCBzZWN0aW9uLCAiTWFrZWZpbGUgUnVsZXMgYW5kIFRhcmdldHMsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBydWxlcywgdGFyZ2V0cywgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyAzLiBNYWtlZmlsZSBSdWxlcyBhbmQgVGFyZ2V0cw0KDQpJbiB0aGUgY29udGV4dCBvZiBgbWFrZWAsIHJ1bGVzIGFuZCB0YXJnZXRzIGFyZSBmdW5kYW1lbnRhbCBjb25jZXB0cyB0aGF0IGRlZmluZSBob3cgeW91ciBwcm9qZWN0J3MgYnVpbGQgcHJvY2VzcyB3b3Jrcy4gVW5kZXJzdGFuZGluZyBob3cgdG8gc3RydWN0dXJlIGFuZCB1c2UgdGhlbSBlZmZlY3RpdmVseSBpbiBNYWtlZmlsZXMgaXMgY3J1Y2lhbCBmb3IgYXV0b21hdGluZyB0YXNrcyBhbmQgbWFuYWdpbmcgZGVwZW5kZW5jaWVzLg0KDQojIyMgMy4xIFRhcmdldHMNCg0KKipUYXJnZXRzKiogaW4gYSBNYWtlZmlsZSByZXByZXNlbnQgdGhlIGFydGlmYWN0cyBvciBhY3Rpb25zIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIG9yIHBlcmZvcm0uIFRhcmdldHMgYXJlIHRoZSBmb2NhbCBwb2ludHMgb2YgeW91ciBidWlsZCBwcm9jZXNzLCBhbmQgdGhleSBjYW4gaW5jbHVkZToNCg0KLSAgIEV4ZWN1dGFibGUgcHJvZ3JhbXMuDQotICAgT2JqZWN0IGZpbGVzIChjb21waWxlZCBzb3VyY2UgZmlsZXMpLg0KLSAgIERvY3VtZW50YXRpb24uDQotICAgRGlzdHJpYnV0aW9uIHBhY2thZ2VzLg0KLSAgIEN1c3RvbSB0YXNrcyBsaWtlIGNsZWFuaW5nIG9yIHRlc3RpbmcuDQoNCkVhY2ggdGFyZ2V0IGNvcnJlc3BvbmRzIHRvIGEgc3BlY2lmaWMgdGFzayBvciBvdXRwdXQgdGhhdCBgbWFrZWAgc2hvdWxkIGdlbmVyYXRlLiBUYXJnZXRzIGNhbiBiZSBjcmVhdGVkIGJ5IGRlZmluaW5nIHRoZWlyIG5hbWVzIGluIHlvdXIgTWFrZWZpbGUuDQoNCiMjIyMgMy4xLjEgRXhhbXBsZSBUYXJnZXRzDQoNCkluIGEgQy9DKysgcHJvamVjdCwgeW91IG1pZ2h0IGRlZmluZSB0YXJnZXRzIGxpa2U6DQoNCi0gICBgbXlfcHJvZ3JhbWA6IFRvIGJ1aWxkIHRoZSBmaW5hbCBleGVjdXRhYmxlLg0KLSAgIGBtYWluLm9gLCBgdXRpbC5vYDogVG8gY29tcGlsZSBpbmRpdmlkdWFsIHNvdXJjZSBmaWxlcyBpbnRvIG9iamVjdCBmaWxlcy4NCi0gICBgY2xlYW5gOiBUbyByZW1vdmUgZ2VuZXJhdGVkIGZpbGVzIGFuZCBjbGVhbiB1cCB0aGUgcHJvamVjdC4NCg0KIyMjIDMuMiBSdWxlcw0KDQoqKlJ1bGVzKiogaW4gYSBNYWtlZmlsZSBkZWZpbmUgaG93IHRvIGNyZWF0ZSBhIHRhcmdldCBmcm9tIGl0cyBkZXBlbmRlbmNpZXMuIEEgcnVsZSBjb25zaXN0cyBvZiB0aHJlZSBtYWluIHBhcnRzOg0KDQoxLiAgKipUYXJnZXQqKjogVGhlIG5hbWUgb2YgdGhlIHRhcmdldCB0aGF0IHlvdSB3YW50IHRvIGJ1aWxkLg0KMi4gICoqRGVwZW5kZW5jaWVzKio6IFRoZSBmaWxlcyBvciB0YXJnZXRzIHRoYXQgdGhlIGN1cnJlbnQgdGFyZ2V0IGRlcGVuZHMgb24uIFRoZXNlIHJlcHJlc2VudCB0aGUgcHJlcmVxdWlzaXRlcyBmb3IgYnVpbGRpbmcgdGhlIHRhcmdldC4NCjMuICAqKkNvbW1hbmRzKio6IFRoZSBzaGVsbCBjb21tYW5kcyB0byBiZSBleGVjdXRlZCB3aGVuIGBtYWtlYCBidWlsZHMgdGhlIHRhcmdldCBmcm9tIGl0cyBkZXBlbmRlbmNpZXMuIFRoZXNlIGNvbW1hbmRzIGFyZSB0eXBpY2FsbHkgaW5kZW50ZWQgd2l0aCB0YWJzLg0KDQojIyMjIDMuMi4xIEV4YW1wbGUgUnVsZSBTdHJ1Y3R1cmUNCg0KSGVyZSdzIHRoZSBzdHJ1Y3R1cmUgb2YgYSBydWxlOg0KDQpgYGAgbWFrZQ0KdGFyZ2V0OiBkZXBlbmRlbmNpZXMNCiAgICBbY29tbWFuZHNdDQpgYGANCg0KIyMjIyAzLjIuMiBFeGFtcGxlIFJ1bGUNCg0KQ29uc2lkZXIgYSBzaW1wbGUgcnVsZSB0byBjb21waWxlIGEgQyBzb3VyY2UgZmlsZSBpbnRvIGFuIG9iamVjdCBmaWxlOg0KDQpgYGAgbWFrZQ0KbWFpbi5vOiBtYWluLmMNCiAgICBnY2MgLW8gbWFpbi5vIC1jIG1haW4uYw0KYGBgDQoNCkluIHRoaXMgcnVsZToNCg0KLSAgICoqYG1haW4ub2AqKiBpcyB0aGUgdGFyZ2V0IHdlIHdhbnQgdG8gYnVpbGQuDQotICAgKipgbWFpbi5jYCoqIGlzIHRoZSBkZXBlbmRlbmN5IChzb3VyY2UgZmlsZSkgdGhhdCBgbWFpbi5vYCBkZXBlbmRzIG9uLg0KLSAgIFRoZSBjb21tYW5kIGBnY2MgLW8gbWFpbi5vIC1jIG1haW4uY2AgaXMgZXhlY3V0ZWQgdG8gYnVpbGQgYG1haW4ub2AgZnJvbSBgbWFpbi5jYC4NCg0KIyMjIDMuMyBQcmFjdGljYWwgVXNhZ2UNCg0KTWFrZWZpbGVzIGJlY29tZSBwb3dlcmZ1bCB3aGVuIHlvdSBoYXZlIG11bHRpcGxlIHJ1bGVzIGFuZCB0YXJnZXRzLCBhbmQgdGhleSBoZWxwIHlvdSBhdXRvbWF0ZSBjb21wbGV4IGJ1aWxkIHByb2Nlc3Nlcy4gSGVyZSBhcmUgc29tZSBwcmFjdGljYWwgdGlwczoNCg0KIyMjIyAzLjMuMSBCdWlsZGluZyBBbGwgVGFyZ2V0cw0KDQpCeSBjb252ZW50aW9uLCB5b3UgY2FuIGNyZWF0ZSBhbiBgYWxsYCB0YXJnZXQgdGhhdCBkZXBlbmRzIG9uIGFsbCB0aGUgbWFpbiB0YXJnZXRzIGluIHlvdXIgcHJvamVjdC4gV2hlbiB5b3UgcnVuIGBtYWtlYCwgaXQgYnVpbGRzIHRoZSBgYWxsYCB0YXJnZXQsIHdoaWNoIGluIHR1cm4gYnVpbGRzIGV2ZXJ5dGhpbmcgZWxzZS4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQphbGw6IG15X3Byb2dyYW0NCg0KbXlfcHJvZ3JhbTogbWFpbi5vIHV0aWwubw0KICAgIGdjYyAtbyBteV9wcm9ncmFtIG1haW4ubyB1dGlsLm8NCg0KbWFpbi5vOiBtYWluLmMNCiAgICBnY2MgLW8gbWFpbi5vIC1jIG1haW4uYw0KDQp1dGlsLm86IHV0aWwuYw0KICAgIGdjYyAtbyB1dGlsLm8gLWMgdXRpbC5jDQpgYGANCg0KIyMjIyAzLjMuMiBDbGVhbmluZyBVcA0KDQpBIGBjbGVhbmAgdGFyZ2V0IGlzIGhhbmR5IGZvciByZW1vdmluZyBnZW5lcmF0ZWQgZmlsZXMgYW5kIGNsZWFuaW5nIHVwIHlvdXIgcHJvamVjdC4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQpjbGVhbjoNCiAgICBybSAtZiBteV9wcm9ncmFtIG1haW4ubyB1dGlsLm8NCmBgYA0KDQojIyMjIDMuMy4zIERlZmF1bHQgVGFyZ2V0DQoNCllvdSBjYW4gc3BlY2lmeSBhIGRlZmF1bHQgdGFyZ2V0IGJ5IGluY2x1ZGluZyBpdCBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgTWFrZWZpbGUuIEZvciBleGFtcGxlOg0KDQpgYGAgbWFrZQ0KLkRFRkFVTFRfR09BTCA6PSBhbGwNCmBgYA0KDQpUaGlzIHNldHMgdGhlIGBhbGxgIHRhcmdldCBhcyB0aGUgZGVmYXVsdCwgc28gcnVubmluZyBgbWFrZWAgd2l0aG91dCBhbnkgYXJndW1lbnRzIHdpbGwgYnVpbGQgYGFsbGAuDQoNCiMjIyMgMy4zLjQgUGhvbnkgVGFyZ2V0cw0KDQpQaG9ueSB0YXJnZXRzIGFyZSB0YXJnZXRzIHRoYXQgZG9uJ3QgcmVwcmVzZW50IGFjdHVhbCBmaWxlcy4gVGhleSBhcmUgdXNlZCBmb3IgdGFza3MgbGlrZSBjbGVhbmluZywgdGVzdGluZywgb3IgZG9jdW1lbnRhdGlvbiBnZW5lcmF0aW9uLiBUbyBkZWNsYXJlIGEgdGFyZ2V0IGFzIHBob255LCB1c2UgdGhlIGAuUEhPTllgIHNwZWNpYWwgdGFyZ2V0LiBGb3IgZXhhbXBsZToNCg0KYGBgIG1ha2UNCi5QSE9OWTogY2xlYW4gdGVzdCBkb2NzDQoNCmNsZWFuOg0KICAgIHJtIC1mIG15X3Byb2dyYW0gbWFpbi5vIHV0aWwubw0KDQp0ZXN0Og0KICAgIC4vcnVuX3Rlc3RzLnNoDQoNCmRvY3M6DQogICAgZG94eWdlbg0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgYGNsZWFuYCwgYHRlc3RgLCBhbmQgYGRvY3NgIGFyZSBwaG9ueSB0YXJnZXRzLg0KDQojIyMgMy40IFN1bW1hcnkNCg0KSW4gc3VtbWFyeSwgTWFrZWZpbGVzIGFyZSBjb21wb3NlZCBvZiBydWxlcyBhbmQgdGFyZ2V0cy4gUnVsZXMgc3BlY2lmeSBob3cgdG8gYnVpbGQgdGFyZ2V0cyBmcm9tIHRoZWlyIGRlcGVuZGVuY2llcywgYW5kIHRhcmdldHMgcmVwcmVzZW50IHRoZSBhcnRpZmFjdHMgb3IgYWN0aW9ucyB5b3Ugd2FudCB0byBjcmVhdGUgb3IgcGVyZm9ybS4gVW5kZXJzdGFuZGluZyB0aGUgc3RydWN0dXJlIGFuZCB1c2FnZSBvZiBydWxlcyBhbmQgdGFyZ2V0cyBpcyBlc3NlbnRpYWwgZm9yIGVmZmVjdGl2ZWx5IGF1dG9tYXRpbmcgdGFza3MgYW5kIG1hbmFnaW5nIGRlcGVuZGVuY2llcyBpbiB5b3VyIHNvZnR3YXJlIHByb2plY3RzLg0KDQpDZXJ0YWlubHksIGxldCdzIGV4cGFuZCBvbiB0aGUgZm91cnRoIHNlY3Rpb24sICJWYXJpYWJsZXMgaW4gTWFrZWZpbGVzLCIgdG8gcHJvdmlkZSBhIG1vcmUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb2YgdmFyaWFibGVzIGFuZCB0aGVpciBwcmFjdGljYWwgdXNhZ2UgaW4gTWFrZWZpbGVzLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgNC4gVmFyaWFibGVzIGluIE1ha2VmaWxlcw0KDQpWYXJpYWJsZXMgcGxheSBhIGNydWNpYWwgcm9sZSBpbiBNYWtlZmlsZXMgYnkgYWxsb3dpbmcgeW91IHRvIGRlZmluZSByZXVzYWJsZSB2YWx1ZXMgdGhhdCBjYW4gYmUgdXNlZCB0aHJvdWdob3V0IHRoZSBmaWxlLiBUaGV5IGVuaGFuY2UgdGhlIHJlYWRhYmlsaXR5LCBtYWludGFpbmFiaWxpdHksIGFuZCBmbGV4aWJpbGl0eSBvZiB5b3VyIE1ha2VmaWxlcy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGV4cGxvcmUgaG93IHRvIGRlY2xhcmUgYW5kIHVzZSB2YXJpYWJsZXMgZWZmZWN0aXZlbHkuDQoNCiMjIyA0LjEgRGVjbGFyaW5nIFZhcmlhYmxlcw0KDQpJbiBhIE1ha2VmaWxlLCB5b3UgY2FuIGRlY2xhcmUgdmFyaWFibGVzIHVzaW5nIHRoZSBmb2xsb3dpbmcgc3ludGF4Og0KDQpgYGAgbWFrZQ0KVkFSSUFCTEVfTkFNRSA9IHZhbHVlDQpgYGANCg0KLSAgIGBWQVJJQUJMRV9OQU1FYDogVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGUsIHdoaWNoIHNob3VsZCBiZSB3cml0dGVuIGluIHVwcGVyY2FzZSBsZXR0ZXJzIGJ5IGNvbnZlbnRpb24uDQotICAgYHZhbHVlYDogVGhpcyBpcyB0aGUgdmFsdWUgYXNzaWduZWQgdG8gdGhlIHZhcmlhYmxlLiBJdCBjYW4gYmUgYSBzdHJpbmcsIGEgY29tbWFuZCwgb3IgYW5vdGhlciB2YXJpYWJsZS4NCg0KIyMjIDQuMiBVc2luZyBWYXJpYWJsZXMNCg0KWW91IGNhbiB1c2UgdmFyaWFibGVzIGJ5IGVuY2xvc2luZyB0aGVpciBuYW1lcyBpbiBgJCguLi4pYCBvciBgJHsuLi59YC4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQpDQyA9IGdjYw0KQ0ZMQUdTID0gLVdhbGwgLU8yDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtIG1haW4uYw0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgYENDYCBhbmQgYENGTEFHU2AgYXJlIHZhcmlhYmxlcywgYW5kIHRoZWlyIHZhbHVlcyBhcmUgc3Vic3RpdHV0ZWQgd2hlbiB0aGUgYG15X3Byb2dyYW1gIHRhcmdldCBpcyBidWlsdC4NCg0KIyMjIDQuMyBWYXJpYWJsZSBUeXBlcw0KDQojIyMjIDQuMy4xIFNpbXBsZSBWYXJpYWJsZXMNCg0KU2ltcGxlIHZhcmlhYmxlcyBhcmUgZGVmaW5lZCB1c2luZyBgPWAgYXMgc2hvd24gYWJvdmUuIFRoZXkgY2FuIGJlIG92ZXJyaWRkZW4gaWYgcmVkZWZpbmVkIGxhdGVyIGluIHRoZSBNYWtlZmlsZS4NCg0KIyMjIyA0LjMuMiBSZWN1cnNpdmUgVmFyaWFibGVzDQoNClJlY3Vyc2l2ZSB2YXJpYWJsZXMgYXJlIGRlZmluZWQgdXNpbmcgYDo9YC4gVGhleSBhcmUgZXZhbHVhdGVkIG9ubHkgd2hlbiB1c2VkLCB3aGljaCBtZWFucyBjaGFuZ2VzIHRvIHRoZWlyIHZhbHVlcyBkbyBub3QgYWZmZWN0IHByZXZpb3VzIHVzYWdlcy4NCg0KYGBgIG1ha2UNClZBUiA6PSBpbml0aWFsX3ZhbHVlDQpWQVIgOj0gbmV3X3ZhbHVlICAjIERvZXMgbm90IGFmZmVjdCBwcmV2aW91cyB1c2FnZXMgb2YgVkFSDQpgYGANCg0KIyMjIyA0LjMuMyBDb25kaXRpb25hbCBWYXJpYWJsZXMNCg0KQ29uZGl0aW9uYWwgdmFyaWFibGVzIGFyZSBkZWZpbmVkIHVzaW5nIGA/PWAuIFRoZXkgYXJlIHNldCBvbmx5IGlmIHRoZSB2YXJpYWJsZSBpcyBub3QgYWxyZWFkeSBkZWZpbmVkLiBUaGlzIGlzIHVzZWZ1bCBmb3IgcHJvdmlkaW5nIGRlZmF1bHQgdmFsdWVzLg0KDQpgYGAgbWFrZQ0KVkFSID89IGRlZmF1bHRfdmFsdWUgICMgVkFSIGlzIHNldCB0byBkZWZhdWx0X3ZhbHVlIGlmIFZBUiBpcyBub3QgYWxyZWFkeSBkZWZpbmVkDQpgYGANCg0KIyMjIDQuNCBQcmFjdGljYWwgVXNhZ2UNCg0KVmFyaWFibGVzIGFyZSBiZW5lZmljaWFsIGluIE1ha2VmaWxlcyBmb3IgdmFyaW91cyByZWFzb25zOg0KDQojIyMjIDQuNC4xIENvbXBpbGVyIGFuZCBGbGFncw0KDQpZb3UgY2FuIHVzZSB2YXJpYWJsZXMgdG8gc3RvcmUgdGhlIGNvbXBpbGVyIGFuZCBjb21waWxhdGlvbiBmbGFncywgbWFraW5nIGl0IGVhc3kgdG8gY2hhbmdlIHRoZW0gZ2xvYmFsbHkgaW4geW91ciBNYWtlZmlsZToNCg0KYGBgIG1ha2UNCkNDID0gZ2NjDQpDRkxBR1MgPSAtV2FsbCAtTzINCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KIyMjIyA0LjQuMiBGaWxlIExpc3RzDQoNClZhcmlhYmxlcyBhcmUgdXNlZnVsIGZvciBkZWZpbmluZyBsaXN0cyBvZiBmaWxlcywgZXNwZWNpYWxseSB3aGVuIHRoZXJlIGFyZSBtYW55IHNvdXJjZSBmaWxlczoNCg0KYGBgIG1ha2UNClNPVVJDRVMgPSBtYWluLmMgdXRpbC5jDQpPQkpFQ1RTID0gJChTT1VSQ0VTOi5jPS5vKQ0KDQpteV9wcm9ncmFtOiAkKE9CSkVDVFMpDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gJChPQkpFQ1RTKQ0KYGBgDQoNCkhlcmUsIGBPQkpFQ1RTYCBpcyBnZW5lcmF0ZWQgZnJvbSBgU09VUkNFU2AsIGNvbnZlcnRpbmcgYC5jYCB0byBgLm9gLg0KDQojIyMjIDQuNC4zIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNClZhcmlhYmxlcyBlbmFibGUgY29uZGl0aW9uYWwgY29tcGlsYXRpb24gYmFzZWQgb24gYnVpbGQgY29uZmlndXJhdGlvbnMgb3IgdGFyZ2V0IHBsYXRmb3JtczoNCg0KYGBgIG1ha2UNCiMgQnVpbGQgYSBkZWJ1ZyB2ZXJzaW9uIHdoZW4gREVCVUcgaXMgZGVmaW5lZA0KaWZkZWYgREVCVUcNCiAgICBDRkxBR1MgKz0gLWcNCmVuZGlmDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtIG1haW4uYw0KYGBgDQoNCiMjIyMgNC40LjQgVmVyc2lvbmluZw0KDQpZb3UgY2FuIGRlZmluZSB2ZXJzaW9uIG51bWJlcnMgb3IgcHJvamVjdCBpbmZvcm1hdGlvbiBhcyB2YXJpYWJsZXMgZm9yIGVhc3kgdXBkYXRlczoNCg0KYGBgIG1ha2UNClZFUlNJT04gPSAxLjANClBST0pFQ1RfTkFNRSA9IG15X3Byb2plY3QNCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vICQoUFJPSkVDVF9OQU1FKV8kKFZFUlNJT04pIG1haW4uYw0KYGBgDQoNCiMjIyA0LjUgQ29uY2x1c2lvbg0KDQpWYXJpYWJsZXMgaW4gTWFrZWZpbGVzIHByb3ZpZGUgZmxleGliaWxpdHkgYW5kIG1haW50YWluYWJpbGl0eS4gVGhleSBhbGxvdyB5b3UgdG8gZGVmaW5lIHZhbHVlcyBvbmNlIGFuZCB1c2UgdGhlbSB0aHJvdWdob3V0IHlvdXIgTWFrZWZpbGUsIG1ha2luZyBpdCBlYXNpZXIgdG8gbWFuYWdlIGJ1aWxkIGNvbmZpZ3VyYXRpb25zIGFuZCBhZGFwdCB0byBkaWZmZXJlbnQgc2NlbmFyaW9zLiBVc2luZyB2YXJpYWJsZXMgZWZmZWN0aXZlbHkgY2FuIHNpbXBsaWZ5IHRoZSBtYWludGVuYW5jZSBvZiBjb21wbGV4IHByb2plY3RzIGFuZCBtYWtlIHlvdXIgTWFrZWZpbGVzIG1vcmUgcmVhZGFibGUuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBmaWZ0aCBzZWN0aW9uLCAiQXV0b21hdGljIFZhcmlhYmxlcywiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIGF1dG9tYXRpYyB2YXJpYWJsZXMgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA1LiBBdXRvbWF0aWMgVmFyaWFibGVzIGluIE1ha2VmaWxlcw0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGFyZSBhIHNldCBvZiBwcmVkZWZpbmVkIHZhcmlhYmxlcyBpbiBNYWtlZmlsZXMgdGhhdCBzaW1wbGlmeSB0aGUgY29uc3RydWN0aW9uIG9mIHJ1bGVzIGJ5IHByb3ZpZGluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdGFyZ2V0IGFuZCBkZXBlbmRlbmNpZXMgYmVpbmcgcHJvY2Vzc2VkLiBUaGV5IGhlbHAgYXZvaWQgcmVkdW5kYW5jeSBpbiB5b3VyIE1ha2VmaWxlIGFuZCBtYWtlIGl0IG1vcmUgY29uY2lzZS4gSW4gdGhpcyBzZWN0aW9uLCB3ZSdsbCBleHBsb3JlIGNvbW1vbiBhdXRvbWF0aWMgdmFyaWFibGVzIGFuZCBob3cgdG8gdXNlIHRoZW0gZWZmZWN0aXZlbHkuDQoNCiMjIyA1LjEgQ29tbW9uIEF1dG9tYXRpYyBWYXJpYWJsZXMNCg0KIyMjIyA1LjEuMSBgJEBgIC0gVGhlIFRhcmdldA0KDQpgJEBgIHJlcHJlc2VudHMgdGhlIHRhcmdldCBvZiB0aGUgcnVsZSBiZWluZyBleGVjdXRlZC4gSXQncyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IGhhdmUgbXVsdGlwbGUgcnVsZXMgd2l0aCBzaW1pbGFyIHBhdHRlcm5zLCBhcyBpdCBhbGxvd3MgeW91IHRvIHJlZmVyZW5jZSB0aGUgdGFyZ2V0IHdpdGhvdXQgcmVwZWF0aW5nIGl0cyBuYW1lLg0KDQpFeGFtcGxlOg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5vIHV0aWwubw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyAkQCAkXg0KYGBgDQoNCkhlcmUsIGAkQGAgaXMgcmVwbGFjZWQgd2l0aCBgbXlfcHJvZ3JhbWAsIGFuZCBgJF5gIHdpdGggYG1haW4ubyB1dGlsLm9gLg0KDQojIyMjIDUuMS4yIGAkXmAgLSBBbGwgRGVwZW5kZW5jaWVzDQoNCmAkXmAgcmVwcmVzZW50cyBhbGwgdGhlIGRlcGVuZGVuY2llcyBvZiB0aGUgcnVsZSBiZWluZyBleGVjdXRlZC4gVGhpcyBpcyBoYW5keSB3aGVuIHlvdSB3YW50IHRvIGluY2x1ZGUgYWxsIHByZXJlcXVpc2l0ZXMgaW4gYSBjb21tYW5kLg0KDQojIyMjIDUuMS4zIGAkPGAgLSBUaGUgRmlyc3QgRGVwZW5kZW5jeQ0KDQpgJDxgIHN0YW5kcyBmb3IgdGhlIGZpcnN0IGRlcGVuZGVuY3kgaW4gdGhlIGxpc3Qgb2YgcHJlcmVxdWlzaXRlcy4gSXQncyBvZnRlbiB1c2VkIHdoZW4gdGhlcmUncyBvbmx5IG9uZSBkZXBlbmRlbmN5IGFuZCB5b3Ugd2FudCB0byByZWZlcmVuY2UgaXQgZGlyZWN0bHkuDQoNCkV4YW1wbGU6DQoNCmBgYCBtYWtlDQptYWluLm86IG1haW4uYw0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyAkQCAkPA0KYGBgDQoNCkhlcmUsIGAkPGAgaXMgcmVwbGFjZWQgd2l0aCBgbWFpbi5jYC4NCg0KIyMjIyA1LjEuNCBgJD9gIC0gT3V0LW9mLURhdGUgRGVwZW5kZW5jaWVzDQoNCmAkP2AgcmVwcmVzZW50cyBhbGwgdGhlIGRlcGVuZGVuY2llcyB0aGF0IGFyZSBvdXQtb2YtZGF0ZSBjb25jZXJuaW5nIHRoZSB0YXJnZXQuIEl0J3MgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gcHJvY2VzcyBvbmx5IHRoZSBmaWxlcyB0aGF0IGhhdmUgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBidWlsZC4NCg0KIyMjIDUuMiBQcmFjdGljYWwgVXNhZ2UNCg0KQXV0b21hdGljIHZhcmlhYmxlcyBzaW1wbGlmeSBNYWtlZmlsZSBydWxlcywgbWFraW5nIHRoZW0gbW9yZSBjb25jaXNlIGFuZCBsZXNzIGVycm9yLXByb25lLiBIZXJlIGFyZSBzb21lIHByYWN0aWNhbCBleGFtcGxlcyBvZiBob3cgdG8gdXNlIHRoZW06DQoNCiMjIyMgNS4yLjEgQnVpbGRpbmcgTXVsdGlwbGUgVGFyZ2V0cw0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGFyZSBlc3BlY2lhbGx5IHVzZWZ1bCB3aGVuIGJ1aWxkaW5nIG11bHRpcGxlIHRhcmdldHMgZnJvbSBhIHNpbmdsZSBydWxlOg0KDQpgYGAgbWFrZQ0Kb2JqZWN0cyA9IG1haW4ubyB1dGlsLm8NCg0KYWxsOiBteV9wcm9ncmFtDQoNCm15X3Byb2dyYW06ICQob2JqZWN0cykNCiAgICAkKENDKSAkKENGTEFHUykgLW8gJEAgJF4NCg0KJChvYmplY3RzKTogJS5vOiAlLmMNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gJEAgJDwNCmBgYA0KDQpJbiB0aGlzIGV4YW1wbGUsIGAkQGAgYW5kIGAkXmAgYXJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgdGFyZ2V0IGFuZCBkZXBlbmRlbmNpZXMgZm9yIHRoZSBgbXlfcHJvZ3JhbWAgcnVsZSwgYXMgd2VsbCBhcyBmb3IgdGhlIHBhdHRlcm4gcnVsZSB0aGF0IGNvbXBpbGVzIGAuY2AgZmlsZXMgaW50byBgLm9gIGZpbGVzLg0KDQojIyMjIDUuMi4yIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNCkF1dG9tYXRpYyB2YXJpYWJsZXMgY2FuIGJlIHVzZWQgdG8gc2ltcGxpZnkgY29uZGl0aW9uYWwgY29tcGlsYXRpb24gYmFzZWQgb24gYnVpbGQgY29uZmlndXJhdGlvbnMgb3IgdGFyZ2V0IHBsYXRmb3JtczoNCg0KYGBgIG1ha2UNCkRFQlVHID89IDANCg0KaWZlcSAoJChERUJVRyksIDEpDQogICAgQ0ZMQUdTICs9IC1nDQplbmRpZg0KDQpteV9wcm9ncmFtOiBtYWluLmMNCiAgICAkKENDKSAkKENGTEFHUykgLW8gJEAgJDwNCmBgYA0KDQpIZXJlLCBgJDxgIHJlcHJlc2VudHMgdGhlIGZpcnN0IGRlcGVuZGVuY3ksIHdoaWNoIGlzIGBtYWluLmNgLiBJZiBgREVCVUdgIGlzIGRlZmluZWQgYXMgYDFgLCB0aGUgYC1nYCBmbGFnIGlzIGFkZGVkIHRvIHRoZSBjb21waWxhdGlvbiBjb21tYW5kLg0KDQojIyMjIDUuMi4zIE91dC1vZi1EYXRlIERlcGVuZGVuY2llcw0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGxpa2UgYCQ/YCBhcmUgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gcHJvY2VzcyBvbmx5IHRoZSBkZXBlbmRlbmNpZXMgdGhhdCBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgYnVpbGQuIEZvciBleGFtcGxlLCBpbiBhIGN1c3RvbSBidWlsZCBzY3JpcHQ6DQoNCmBgYCBtYWtlDQpnZW5lcmF0ZV9yZXNvdXJjZXM6IHJlc291cmNlX2dlbmVyYXRvcg0KICAgIC4vcmVzb3VyY2VfZ2VuZXJhdG9yIC1vICRAICQ/DQoNCnJlc291cmNlX2dlbmVyYXRvcjogcmVzb3VyY2VfZ2VuZXJhdG9yLmMNCiAgICAkKENDKSAkKENGTEFHUykgLW8gJEAgJDwNCmBgYA0KDQpJbiB0aGlzIGV4YW1wbGUsIGBnZW5lcmF0ZV9yZXNvdXJjZXNgIGRlcGVuZHMgb24gdGhlIGByZXNvdXJjZV9nZW5lcmF0b3JgIHByb2dyYW0gYW5kIGFsbCB0aGUgb3V0LW9mLWRhdGUgcmVzb3VyY2UgZmlsZXMgKGAkP2ApIHRvIGdlbmVyYXRlIG5ldyByZXNvdXJjZXMuDQoNCiMjIyA1LjMgQ29uY2x1c2lvbg0KDQpBdXRvbWF0aWMgdmFyaWFibGVzIGluIE1ha2VmaWxlcyBzaW1wbGlmeSBydWxlIGNvbnN0cnVjdGlvbiBhbmQgcmVkdWNlIHJlZHVuZGFuY3kgaW4geW91ciBidWlsZCBzY3JpcHRzLiBCeSB1c2luZyB2YXJpYWJsZXMgbGlrZSBgJEBgLCBgJF5gLCBgJDxgLCBhbmQgYCQ/YCwgeW91IGNhbiBjcmVhdGUgbW9yZSBjb25jaXNlIGFuZCBtYWludGFpbmFibGUgTWFrZWZpbGVzIHRoYXQgYWRhcHQgdG8gY2hhbmdlcyBpbiB5b3VyIHByb2plY3Qgd2l0aG91dCB0aGUgbmVlZCBmb3IgZXh0ZW5zaXZlIG1hbnVhbCBlZGl0aW5nLiBVbmRlcnN0YW5kaW5nIGFuZCB1dGlsaXppbmcgdGhlc2UgYXV0b21hdGljIHZhcmlhYmxlcyBlZmZlY3RpdmVseSBjYW4gc2lnbmlmaWNhbnRseSBlbmhhbmNlIHlvdXIgTWFrZWZpbGUtd3JpdGluZyBza2lsbHMuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBzaXh0aCBzZWN0aW9uLCAiUGhvbnkgVGFyZ2V0cywiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIHBob255IHRhcmdldHMgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA2LiBQaG9ueSBUYXJnZXRzIGluIE1ha2VmaWxlcw0KDQpJbiBNYWtlZmlsZXMsICoqcGhvbnkgdGFyZ2V0cyoqIGFyZSB0YXJnZXRzIHRoYXQgZG9uJ3QgcmVwcmVzZW50IGZpbGVzIG9yIGFydGlmYWN0cyBidXQgcmF0aGVyIHNlcnZlIGFzIGxhYmVscyBmb3Igc3BlY2lmaWMgYWN0aW9ucyBvciB0YXNrcyB0aGF0IG5lZWQgdG8gYmUgZXhlY3V0ZWQuIFBob255IHRhcmdldHMgYXJlIGVzc2VudGlhbCBmb3IgdGFza3Mgc3VjaCBhcyBjbGVhbmluZywgdGVzdGluZywgb3IgZ2VuZXJhdGluZyBkb2N1bWVudGF0aW9uLiBJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgZXhwbG9yZSB3aGF0IHBob255IHRhcmdldHMgYXJlIGFuZCBob3cgdG8gdXNlIHRoZW0gZWZmZWN0aXZlbHkuDQoNCiMjIyA2LjEgV2hhdCBBcmUgUGhvbnkgVGFyZ2V0cz8NCg0KUGhvbnkgdGFyZ2V0cyBhcmUgdXNlZCB0byBkZWZpbmUgYWN0aW9ucyBvciB0YXNrcyB0aGF0IGBtYWtlYCBzaG91bGQgcGVyZm9ybSB3aGVuIGV4cGxpY2l0bHkgcmVxdWVzdGVkLCBidXQgdGhleSBkb24ndCBjb3JyZXNwb25kIHRvIGFjdHVhbCBmaWxlcyBpbiB0aGUgZmlsZSBzeXN0ZW0uIFRoZXkgYXJlIGRlY2xhcmVkIGluIGEgTWFrZWZpbGUgdG8gcHJvdmlkZSBjb252ZW5pZW50IG5hbWVzIGZvciBjb21tb24gZGV2ZWxvcG1lbnQgYW5kIG1haW50ZW5hbmNlIHRhc2tzLCBhbGxvd2luZyB5b3UgdG8gZXhlY3V0ZSB0aGVzZSB0YXNrcyB1c2luZyB0aGUgYG1ha2VgIGNvbW1hbmQuDQoNClR5cGljYWxseSwgcGhvbnkgdGFyZ2V0cyBoYXZlIG5vIHByZXJlcXVpc2l0ZXMgb3IgZGVwZW5kZW5jaWVzIGJlY2F1c2UgdGhlaXIgcHVycG9zZSBpcyB0byBleGVjdXRlIGEgc3BlY2lmaWMgYWN0aW9uLCBub3QgdG8gYnVpbGQgYSBmaWxlIGJhc2VkIG9uIGRlcGVuZGVuY2llcy4NCg0KIyMjIDYuMiBEZWNsYXJpbmcgUGhvbnkgVGFyZ2V0cw0KDQpUbyBkZWNsYXJlIGEgdGFyZ2V0IGFzIHBob255LCB5b3UgdXNlIHRoZSBgLlBIT05ZYCBzcGVjaWFsIHRhcmdldCBpbiB5b3VyIE1ha2VmaWxlLCBmb2xsb3dlZCBieSBhIGxpc3Qgb2YgcGhvbnkgdGFyZ2V0IG5hbWVzLiBGb3IgZXhhbXBsZToNCg0KYGBgIG1ha2UNCi5QSE9OWTogY2xlYW4gdGVzdCBkb2NzDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB3ZSd2ZSBkZWNsYXJlZCB0aHJlZSBwaG9ueSB0YXJnZXRzOiBgY2xlYW5gLCBgdGVzdGAsIGFuZCBgZG9jc2AuIFRoZXNlIHRhcmdldHMgcmVwcmVzZW50IGNvbW1vbiBkZXZlbG9wbWVudCB0YXNrcyBzdWNoIGFzIGNsZWFuaW5nIHVwIGdlbmVyYXRlZCBmaWxlcywgcnVubmluZyB0ZXN0cywgYW5kIGdlbmVyYXRpbmcgZG9jdW1lbnRhdGlvbi4NCg0KIyMjIDYuMyBQcmFjdGljYWwgVXNhZ2UNCg0KUGhvbnkgdGFyZ2V0cyBhcmUgdmFsdWFibGUgZm9yIGF1dG9tYXRpbmcgdmFyaW91cyBkZXZlbG9wbWVudCBhbmQgbWFpbnRlbmFuY2UgdGFza3MuIEhlcmUgYXJlIHNvbWUgY29tbW9uIHVzZSBjYXNlcyBhbmQgcHJhY3RpY2FsIGV4YW1wbGVzIG9mIHBob255IHRhcmdldHM6DQoNCiMjIyMgNi4zLjEgQ2xlYW5pbmcNCg0KQSBgY2xlYW5gIHBob255IHRhcmdldCBpcyB1c2VkIHRvIHJlbW92ZSBnZW5lcmF0ZWQgZmlsZXMgYW5kIGFydGlmYWN0cyB0byBlbnN1cmUgYSBjbGVhbiBwcm9qZWN0IGRpcmVjdG9yeS4gSXQncyBlc3BlY2lhbGx5IGltcG9ydGFudCB3aGVuIHlvdSB3YW50IHRvIHJlYnVpbGQgeW91ciBwcm9qZWN0IGZyb20gc2NyYXRjaCBvciBiZWZvcmUgYXJjaGl2aW5nIG9yIGRpc3RyaWJ1dGluZyBpdC4NCg0KYGBgIG1ha2UNCi5QSE9OWTogY2xlYW4NCg0KY2xlYW46DQogICAgcm0gLWYgbXlfcHJvZ3JhbSBtYWluLm8gdXRpbC5vDQpgYGANCg0KUnVubmluZyBgbWFrZSBjbGVhbmAgd2lsbCByZW1vdmUgdGhlIGV4ZWN1dGFibGUgYG15X3Byb2dyYW1gIGFuZCB0aGUgb2JqZWN0IGZpbGVzIChgbWFpbi5vYCBhbmQgYHV0aWwub2ApIGZyb20gdGhlIHByb2plY3QgZGlyZWN0b3J5Lg0KDQojIyMjIDYuMy4yIFRlc3RpbmcNCg0KQSBgdGVzdGAgcGhvbnkgdGFyZ2V0IGlzIHVzZWQgdG8gcnVuIHlvdXIgcHJvamVjdCdzIHRlc3Qgc3VpdGUuIFRoaXMgaXMgZXNwZWNpYWxseSBoZWxwZnVsIGZvciBjb250aW51b3VzIGludGVncmF0aW9uIChDSSkgd29ya2Zsb3dzLg0KDQpgYGAgbWFrZQ0KLlBIT05ZOiB0ZXN0DQoNCnRlc3Q6DQogICAgLi9ydW5fdGVzdHMuc2gNCmBgYA0KDQpIZXJlLCBgcnVuX3Rlc3RzLnNoYCBpcyBhIHNjcmlwdCB0aGF0IGV4ZWN1dGVzIHlvdXIgcHJvamVjdCdzIHRlc3QgY2FzZXMuIFJ1bm5pbmcgYG1ha2UgdGVzdGAgd2lsbCB0cmlnZ2VyIHRoaXMgc2NyaXB0IGFuZCBleGVjdXRlIHRoZSB0ZXN0cy4NCg0KIyMjIyA2LjMuMyBHZW5lcmF0aW5nIERvY3VtZW50YXRpb24NCg0KQSBgZG9jc2AgcGhvbnkgdGFyZ2V0IGlzIHVzZWQgdG8gZ2VuZXJhdGUgcHJvamVjdCBkb2N1bWVudGF0aW9uLiBGb3IgZXhhbXBsZSwgaWYgeW91IHVzZSBEb3h5Z2VuIGZvciBkb2N1bWVudGF0aW9uIGdlbmVyYXRpb246DQoNCmBgYCBtYWtlDQouUEhPTlk6IGRvY3MNCg0KZG9jczoNCiAgICBkb3h5Z2VuDQpgYGANCg0KUnVubmluZyBgbWFrZSBkb2NzYCB3aWxsIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gdXNpbmcgRG94eWdlbiBvciBhbnkgb3RoZXIgZG9jdW1lbnRhdGlvbiBnZW5lcmF0aW9uIHRvb2wgeW91IHByZWZlci4NCg0KIyMjIyA2LjMuNCBEZXBlbmRlbmN5IEFuYWx5c2lzDQoNCllvdSBjYW4gdXNlIHBob255IHRhcmdldHMgdG8gYW5hbHl6ZSBkZXBlbmRlbmNpZXMgaW4geW91ciBwcm9qZWN0LCBzdWNoIGFzIGdlbmVyYXRpbmcgZGVwZW5kZW5jeSBmaWxlcyBmb3IgQy9DKysgY29kZS4gRm9yIGluc3RhbmNlLCB1c2luZyB0aGUgR0NDIGAtTWAgZmxhZyB0byBnZW5lcmF0ZSBkZXBlbmRlbmN5IGZpbGVzOg0KDQpgYGAgbWFrZQ0KLlBIT05ZOiBkZXBlbmQNCg0KZGVwZW5kOg0KICAgIGdjYyAtTSAqLmMgPiBkZXBlbmRlbmNpZXMNCmBgYA0KDQpSdW5uaW5nIGBtYWtlIGRlcGVuZGAgd2lsbCB1cGRhdGUgdGhlIGBkZXBlbmRlbmNpZXNgIGZpbGUgd2l0aCB0aGUgbGF0ZXN0IGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gZm9yIHlvdXIgcHJvamVjdC4NCg0KIyMjIDYuNCBDb25jbHVzaW9uDQoNClBob255IHRhcmdldHMgaW4gTWFrZWZpbGVzIHByb3ZpZGUgYSB3YXkgdG8gZGVmaW5lIGFuZCBhdXRvbWF0ZSBjb21tb24gZGV2ZWxvcG1lbnQgYW5kIG1haW50ZW5hbmNlIHRhc2tzLiBCeSBkZWNsYXJpbmcgcGhvbnkgdGFyZ2V0cywgeW91IGNhbiB1c2UgdGhlIGBtYWtlYCBjb21tYW5kIHRvIGV4ZWN1dGUgdGhlc2UgdGFza3MgY29udmVuaWVudGx5IHdpdGhvdXQgd29ycnlpbmcgYWJvdXQgZmlsZSBkZXBlbmRlbmNpZXMuIFRoaXMgaGVscHMgc3RyZWFtbGluZSB5b3VyIGRldmVsb3BtZW50IHdvcmtmbG93LCBtYWtpbmcgaXQgZWFzaWVyIHRvIGNsZWFuLCB0ZXN0LCBhbmQgZG9jdW1lbnQgeW91ciBwcm9qZWN0cyBlZmZpY2llbnRseS4NCg0KQ2VydGFpbmx5LCBsZXQncyBleHBhbmQgb24gdGhlIHNldmVudGggc2VjdGlvbiwgIkRlcGVuZGVuY3kgTWFuYWdlbWVudCwiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIGhvdyBkZXBlbmRlbmN5IG1hbmFnZW1lbnQgd29ya3MgaW4gTWFrZWZpbGVzIGFuZCBpdHMgcHJhY3RpY2FsIHVzYWdlLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgNy4gRGVwZW5kZW5jeSBNYW5hZ2VtZW50IGluIE1ha2VmaWxlcw0KDQpEZXBlbmRlbmN5IG1hbmFnZW1lbnQgaXMgYSBjcml0aWNhbCBhc3BlY3Qgb2YgTWFrZWZpbGVzLCBhcyBpdCBlbnN1cmVzIHRoYXQgYG1ha2VgIHJlYnVpbGRzIG9ubHkgdGhvc2UgdGFyZ2V0cyB0aGF0IGFyZSBvdXQtb2YtZGF0ZSBiYXNlZCBvbiBjaGFuZ2VzIGluIHRoZWlyIGRlcGVuZGVuY2llcy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGRlbHZlIGRlZXBlciBpbnRvIGhvdyBkZXBlbmRlbmN5IG1hbmFnZW1lbnQgd29ya3MgYW5kIHByb3ZpZGUgcHJhY3RpY2FsIGV4YW1wbGVzLg0KDQojIyMgNy4xIERlZmluaW5nIERlcGVuZGVuY2llcw0KDQpJbiBhIE1ha2VmaWxlLCBkZXBlbmRlbmNpZXMgYXJlIHNwZWNpZmllZCBpbiB0aGUgcnVsZXMgZm9yIGVhY2ggdGFyZ2V0LiBBIHRhcmdldCBkZXBlbmRzIG9uIG9uZSBvciBtb3JlIGZpbGVzIG9yIG90aGVyIHRhcmdldHMsIGtub3duIGFzIHByZXJlcXVpc2l0ZXMuIFdoZW4gYG1ha2VgIGVuY291bnRlcnMgYSBydWxlLCBpdCBjaGVja3MgaWYgdGhlIHRhcmdldCBpcyBvbGRlciB0aGFuIGFueSBvZiBpdHMgcHJlcmVxdWlzaXRlcy4gSWYgYSBwcmVyZXF1aXNpdGUgaXMgbmV3ZXIgdGhhbiB0aGUgdGFyZ2V0IG9yIGlmIHRoZSB0YXJnZXQgZG9lc24ndCBleGlzdCwgYG1ha2VgIHJlYnVpbGRzIHRoZSB0YXJnZXQuDQoNCkhlcmUncyB0aGUgYmFzaWMgc3RydWN0dXJlIG9mIGEgcnVsZSB3aXRoIGRlcGVuZGVuY2llczoNCg0KYGBgIG1ha2UNCnRhcmdldDogZGVwZW5kZW5jaWVzDQogICAgW2NvbW1hbmRzXQ0KYGBgDQoNCiMjIyA3LjIgSG93IGBtYWtlYCBEZXRlcm1pbmVzIFdoYXQgdG8gQnVpbGQNCg0KV2hlbiB5b3UgcnVuIGBtYWtlYCwgaXQgZm9sbG93cyB0aGVzZSBzdGVwcyB0byBkZXRlcm1pbmUgd2hhdCBuZWVkcyB0byBiZSBidWlsdDoNCg0KMS4gIEl0IHJlYWRzIHRoZSBNYWtlZmlsZSB0byBidWlsZCBhIGRlcGVuZGVuY3kgZ3JhcGggdGhhdCBzaG93cyBob3cgdGFyZ2V0cyBhbmQgZGVwZW5kZW5jaWVzIGFyZSByZWxhdGVkLg0KMi4gIEl0IGNoZWNrcyB0aGUgdGltZXN0YW1wcyBvZiB0YXJnZXRzIGFuZCB0aGVpciBkZXBlbmRlbmNpZXMuDQozLiAgSWYgYSB0YXJnZXQgaXMgb2xkZXIgdGhhbiBhbnkgb2YgaXRzIGRlcGVuZGVuY2llcywgb3IgaWYgdGhlIHRhcmdldCBkb2Vzbid0IGV4aXN0LCBgbWFrZWAgZXhlY3V0ZXMgdGhlIGNvbW1hbmRzIGFzc29jaWF0ZWQgd2l0aCB0aGF0IHRhcmdldCB0byByZWJ1aWxkIGl0Lg0KNC4gIEl0IHJlY3Vyc2l2ZWx5IGJ1aWxkcyBhbnkgcHJlcmVxdWlzaXRlcyB0aGF0IGFyZSBvdXQtb2YtZGF0ZSBiZWZvcmUgYnVpbGRpbmcgdGhlIHRhcmdldC4NCg0KIyMjIDcuMyBQcmFjdGljYWwgVXNhZ2UNCg0KTGV0J3MgbG9vayBhdCBwcmFjdGljYWwgZXhhbXBsZXMgb2YgaG93IGRlcGVuZGVuY3kgbWFuYWdlbWVudCB3b3JrcyBpbiBNYWtlZmlsZXMuDQoNCiMjIyMgNy4zLjEgQy9DKysgQ29tcGlsYXRpb24NCg0KQ29uc2lkZXIgYSBzaW1wbGUgQy9DKysgcHJvamVjdCB3aXRoIG11bHRpcGxlIHNvdXJjZSBmaWxlcyBhbmQgaGVhZGVyIGZpbGVzOg0KDQpgYGAgbWFrZQ0KQ0MgPSBnY2MNCkNGTEFHUyA9IC1XYWxsIC1PMg0KDQpteV9wcm9ncmFtOiBtYWluLm8gdXRpbC5vDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5vIHV0aWwubw0KDQptYWluLm86IG1haW4uYyB1dGlsLmgNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gbWFpbi5vIG1haW4uYw0KDQp1dGlsLm86IHV0aWwuYyB1dGlsLmgNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gdXRpbC5vIHV0aWwuYw0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZToNCg0KLSAgIGBteV9wcm9ncmFtYCBkZXBlbmRzIG9uIGBtYWluLm9gIGFuZCBgdXRpbC5vYC4NCi0gICBgbWFpbi5vYCBkZXBlbmRzIG9uIGBtYWluLmNgIGFuZCBgdXRpbC5oYC4NCi0gICBgdXRpbC5vYCBkZXBlbmRzIG9uIGB1dGlsLmNgIGFuZCBgdXRpbC5oYC4NCg0KSWYgeW91IG1vZGlmeSBgbWFpbi5jYCBvciBgdXRpbC5jYCwgcnVubmluZyBgbWFrZWAgd2lsbCByZWJ1aWxkIG9ubHkgdGhlIGFmZmVjdGVkIG9iamVjdCBmaWxlcyBhbmQgdGhlbiByZS1saW5rIHRoZSBwcm9ncmFtLiBUaGUgZGVwZW5kZW5jaWVzIGVuc3VyZSB0aGF0IG9ubHkgdGhlIG5lY2Vzc2FyeSBwYXJ0cyBvZiB0aGUgcHJvamVjdCBhcmUgcmVidWlsdC4NCg0KIyMjIyA3LjMuMiBBdXRvbWF0aWMgRGVwZW5kZW5jeSBHZW5lcmF0aW9uDQoNCk1ha2UgY2FuIGFsc28gZ2VuZXJhdGUgZGVwZW5kZW5jeSBpbmZvcm1hdGlvbiBhdXRvbWF0aWNhbGx5IHVzaW5nIHRvb2xzIGxpa2UgYGdjYyAtTWAuIEZvciBleGFtcGxlOg0KDQpgYGAgbWFrZQ0KQ0MgPSBnY2MNCkNGTEFHUyA9IC1XYWxsIC1PMg0KDQpTT1VSQ0VTID0gbWFpbi5jIHV0aWwuYw0KT0JKRUNUUyA9ICQoU09VUkNFUzouYz0ubykNCg0KbXlfcHJvZ3JhbTogJChPQkpFQ1RTKQ0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtICQoT0JKRUNUUykNCg0KJS5vOiAlLmMNCiAgICAkKENDKSAkKENGTEFHUykgLWMgLW8gJEAgJDwNCg0KIyBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlIGRlcGVuZGVuY2llcw0KJS5kOiAlLmMNCiAgICAkKENDKSAtTSAtTVAgLU1GICRAIC1NVCAkKEA6LmQ9Lm8pICQ8DQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYCUuZGAgcnVsZSBnZW5lcmF0ZXMgZGVwZW5kZW5jeSBmaWxlcyAoYCouZGApIHRoYXQgY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgaGVhZGVyIGZpbGUgZGVwZW5kZW5jaWVzIG9mIGVhY2ggc291cmNlIGZpbGUuIFRoZXNlIGRlcGVuZGVuY3kgZmlsZXMgYXJlIHRoZW4gaW5jbHVkZWQgaW4gdGhlIE1ha2VmaWxlLCBlbnN1cmluZyB0aGF0IGNoYW5nZXMgaW4gaGVhZGVyIGZpbGVzIHRyaWdnZXIgcmVjb21waWxhdGlvbi4NCg0KVG8gaW5jbHVkZSB0aGUgZ2VuZXJhdGVkIGRlcGVuZGVuY3kgZmlsZXMgaW4geW91ciBNYWtlZmlsZSwgYWRkIHRoaXMgbGluZToNCg0KYGBgIG1ha2UNCi1pbmNsdWRlICQoU09VUkNFUzouYz0uZCkNCmBgYA0KDQpUaGlzIGxpbmUgdGVsbHMgYG1ha2VgIHRvIGluY2x1ZGUgdGhlIGdlbmVyYXRlZCBgLmRgIGZpbGVzLg0KDQojIyMgNy40IENvbmNsdXNpb24NCg0KRGVwZW5kZW5jeSBtYW5hZ2VtZW50IGlzIGEgZnVuZGFtZW50YWwgYXNwZWN0IG9mIE1ha2VmaWxlcywgZW5hYmxpbmcgZWZmaWNpZW50IGFuZCBhdXRvbWF0ZWQgYnVpbGRzLiBCeSBzcGVjaWZ5aW5nIGRlcGVuZGVuY2llcyBmb3IgZWFjaCB0YXJnZXQsIHlvdSBjYW4gZW5zdXJlIHRoYXQgYG1ha2VgIHJlYnVpbGRzIG9ubHkgd2hhdCBpcyBuZWNlc3NhcnksIHJlZHVjaW5nIGJ1aWxkIHRpbWVzIGFuZCBlbnN1cmluZyBjb25zaXN0ZW5jeSBpbiB5b3VyIHByb2plY3RzLiBVbmRlcnN0YW5kaW5nIGhvdyBkZXBlbmRlbmN5IG1hbmFnZW1lbnQgd29ya3MgYW5kIGhvdyB0byB1c2UgaXQgZWZmZWN0aXZlbHkgaXMgZXNzZW50aWFsIGZvciBlZmZpY2llbnQgc29mdHdhcmUgZGV2ZWxvcG1lbnQgd29ya2Zsb3dzLg0KDQpDZXJ0YWlubHksIGxldCdzIGV4cGFuZCBvbiB0aGUgZWlnaHRoIHNlY3Rpb24sICJDb25kaXRpb25hbCBTdGF0ZW1lbnRzIGluIE1ha2VmaWxlcywiIHRvIHByb3ZpZGUgYSBtb3JlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9mIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA4LiBDb25kaXRpb25hbCBTdGF0ZW1lbnRzIGluIE1ha2VmaWxlcw0KDQpDb25kaXRpb25hbCBzdGF0ZW1lbnRzIGluIE1ha2VmaWxlcyBhbGxvdyB5b3UgdG8gY3JlYXRlIHJ1bGVzIGFuZCB0YXJnZXRzIHRoYXQgdmFyeSBkZXBlbmRpbmcgb24gc3BlY2lmaWMgY29uZGl0aW9ucyBvciB2YXJpYWJsZXMuIFRoZXNlIHN0YXRlbWVudHMgZW5hYmxlIHlvdSB0byBjdXN0b21pemUgeW91ciBidWlsZCBwcm9jZXNzLCBhZGFwdCB0byBkaWZmZXJlbnQgZW52aXJvbm1lbnRzLCBvciBoYW5kbGUgdmFyaW91cyBidWlsZCBjb25maWd1cmF0aW9ucy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSdsbCBleHBsb3JlIHRoZSB1c2Ugb2YgY29uZGl0aW9uYWwgc3RhdGVtZW50cyBpbiBNYWtlZmlsZXMgYW5kIHByb3ZpZGUgcHJhY3RpY2FsIGV4YW1wbGVzLg0KDQojIyMgOC4xIENvbmRpdGlvbmFsIERpcmVjdGl2ZXMNCg0KTWFrZWZpbGVzIHVzZSBjb25kaXRpb25hbCBkaXJlY3RpdmVzIHRvIGRlZmluZSBydWxlcywgdGFyZ2V0cywgYW5kIHZhcmlhYmxlcyBiYXNlZCBvbiBjb25kaXRpb25zLiBDb21tb24gY29uZGl0aW9uYWwgZGlyZWN0aXZlcyBpbmNsdWRlIGBpZmVxYCwgYGlmbmVxYCwgYGlmZGVmYCwgYW5kIGBpZm5kZWZgLiBUaGVzZSBkaXJlY3RpdmVzIGFsbG93IHlvdSB0byBjaGVjayBmb3IgZXF1YWxpdHksIGluZXF1YWxpdHksIG9yIHZhcmlhYmxlIGV4aXN0ZW5jZS4NCg0KVGhlIGJhc2ljIHN0cnVjdHVyZSBvZiBjb25kaXRpb25hbCBkaXJlY3RpdmVzIGlzIGFzIGZvbGxvd3M6DQoNCmBgYCBtYWtlDQpjb25kaXRpb25hbF9kaXJlY3RpdmUNCiAgICAjIENvbmRpdGlvbg0KICAgIFtjb21tYW5kc10NCmVsc2UNCiAgICAjIEFsdGVybmF0aXZlIGNvbW1hbmRzDQplbmRpZg0KYGBgDQoNCiMjIyA4LjIgUHJhY3RpY2FsIFVzYWdlDQoNCkxldCdzIGV4cGxvcmUgc29tZSBwcmFjdGljYWwgZXhhbXBsZXMgb2YgaG93IGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgY2FuIGJlIHVzZWQgaW4gTWFrZWZpbGVzLg0KDQojIyMjIDguMi4xIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNCkNvbmRpdGlvbmFsIGNvbXBpbGF0aW9uIGlzIGEgY29tbW9uIHVzZSBjYXNlIGZvciBjb25kaXRpb25hbCBzdGF0ZW1lbnRzIGluIE1ha2VmaWxlcy4gWW91IGNhbiB1c2UgY29uZGl0aW9uYWxzIHRvIGluY2x1ZGUgb3IgZXhjbHVkZSBzcGVjaWZpYyBzb3VyY2UgZmlsZXMgb3IgY29tcGlsZXIgZmxhZ3MgYmFzZWQgb24gYnVpbGQgY29uZmlndXJhdGlvbnMuDQoNCmBgYCBtYWtlDQpERUJVRyA/PSAwDQoNCmlmZXEgKCQoREVCVUcpLCAxKQ0KICAgIENGTEFHUyArPSAtZw0KZW5kaWYNCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYC1nYCBmbGFnIGlzIGFkZGVkIHRvIGBDRkxBR1NgIGlmIHRoZSBgREVCVUdgIHZhcmlhYmxlIGlzIHNldCB0byBgMWAuIFRoaXMgYWxsb3dzIHlvdSB0byBjb250cm9sIHdoZXRoZXIgZGVidWdnaW5nIGluZm9ybWF0aW9uIGlzIGluY2x1ZGVkIGluIHRoZSBjb21waWxlZCBiaW5hcnkuDQoNCiMjIyMgOC4yLjIgUGxhdGZvcm0tU3BlY2lmaWMgUnVsZXMNCg0KWW91IGNhbiB1c2UgY29uZGl0aW9uYWxzIHRvIGRlZmluZSBwbGF0Zm9ybS1zcGVjaWZpYyBydWxlcyBvciB2YXJpYWJsZXMuIEZvciBpbnN0YW5jZSwgeW91IG1pZ2h0IGhhdmUgZGlmZmVyZW50IGNvbXBpbGF0aW9uIHNldHRpbmdzIGZvciBXaW5kb3dzIGFuZCBMaW51eDoNCg0KYGBgIG1ha2UNClVOQU1FX1MgOj0gJChzaGVsbCB1bmFtZSAtcykNCg0KaWZlcSAoJChVTkFNRV9TKSxMaW51eCkNCiAgICBDQyA9IGdjYw0KICAgIENGTEFHUyA9IC1XYWxsIC1PMg0KZW5kaWYNCg0KaWZlcSAoJChVTkFNRV9TKSxXaW5kb3dzX05UKQ0KICAgIENDID0gY2wNCiAgICBDRkxBR1MgPSAvVzQgL08yDQplbmRpZg0KDQpteV9wcm9ncmFtOiBtYWluLmMNCiAgICAkKENDKSAkKENGTEFHUykgLW8gbXlfcHJvZ3JhbSBtYWluLmMNCmBgYA0KDQpIZXJlLCB0aGUgTWFrZWZpbGUgc2V0cyB0aGUgY29tcGlsZXIgKGBDQ2ApIGFuZCBjb21waWxlciBmbGFncyAoYENGTEFHU2ApIGJhc2VkIG9uIHRoZSBob3N0IG9wZXJhdGluZyBzeXN0ZW0uDQoNCiMjIyMgOC4yLjMgVmFyaWFibGUgQXNzaWdubWVudA0KDQpDb25kaXRpb25hbCBzdGF0ZW1lbnRzIGNhbiBhbHNvIGJlIHVzZWQgZm9yIHZhcmlhYmxlIGFzc2lnbm1lbnQuIEZvciBleGFtcGxlLCB5b3UgbWlnaHQgd2FudCB0byBzZXQgYSB2YXJpYWJsZSBkaWZmZXJlbnRseSBkZXBlbmRpbmcgb24gd2hldGhlciBhIHNwZWNpZmljIHRvb2wgaXMgYXZhaWxhYmxlOg0KDQpgYGAgbWFrZQ0KaWZkZWYgVE9PTF9FWElTVFMNCiAgICBDT01QSUxFUiA9ICQoVE9PTF9FWElTVFMpDQplbHNlDQogICAgQ09NUElMRVIgPSBnY2MNCmVuZGlmDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgICQoQ09NUElMRVIpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KSW4gdGhpcyBjYXNlLCBpZiB0aGUgYFRPT0xfRVhJU1RTYCB2YXJpYWJsZSBpcyBkZWZpbmVkLCBpdCB3aWxsIGJlIHVzZWQgYXMgdGhlIGNvbXBpbGVyOyBvdGhlcndpc2UsIGBnY2NgIGlzIHVzZWQgYXMgdGhlIGRlZmF1bHQuDQoNCiMjIyA4LjMgTmVzdGVkIENvbmRpdGlvbmFscw0KDQpZb3UgY2FuIG5lc3QgY29uZGl0aW9uYWwgc3RhdGVtZW50cyB0byBoYW5kbGUgbW9yZSBjb21wbGV4IHNjZW5hcmlvczoNCg0KYGBgIG1ha2UNCkRFQlVHID89IDANClRBUkdFVCA/PSBsaW51eA0KDQppZmVxICgkKERFQlVHKSwgMSkNCiAgICBDRkxBR1MgKz0gLWcNCmVsc2UNCiAgICBpZmVxICgkKFRBUkdFVCksIHdpbmRvd3MpDQogICAgICAgIENGTEFHUyArPSAtTzINCiAgICBlbHNlDQogICAgICAgIENGTEFHUyArPSAtTzMNCiAgICBlbmRpZg0KZW5kaWYNCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYnVpbGQgY29uZmlndXJhdGlvbiBkZXBlbmRzIG9uIGJvdGggdGhlIGBERUJVR2AgdmFyaWFibGUgYW5kIHRoZSBgVEFSR0VUYCB2YXJpYWJsZS4gRGVwZW5kaW5nIG9uIHRoZXNlIGNvbmRpdGlvbnMsIGRpZmZlcmVudCBvcHRpbWl6YXRpb24gZmxhZ3MgKGAtZ2AsIGAtTzJgLCBvciBgLU8zYCkgYXJlIHVzZWQuDQoNCiMjIyA4LjQgQ29uY2x1c2lvbg0KDQpDb25kaXRpb25hbCBzdGF0ZW1lbnRzIGluIE1ha2VmaWxlcyBwcm92aWRlIGZsZXhpYmlsaXR5IGFuZCBhZGFwdGFiaWxpdHkgdG8geW91ciBidWlsZCBwcm9jZXNzLiBUaGV5IGFsbG93IHlvdSB0byBjdXN0b21pemUgcnVsZXMsIHRhcmdldHMsIGFuZCB2YXJpYWJsZXMgYmFzZWQgb24gY29uZGl0aW9ucywgbWFraW5nIHlvdXIgTWFrZWZpbGVzIG1vcmUgdmVyc2F0aWxlIGFuZCBzdWl0YWJsZSBmb3IgdmFyaW91cyBidWlsZCBzY2VuYXJpb3MuIFVuZGVyc3RhbmRpbmcgaG93IHRvIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnRzIGVmZmVjdGl2ZWx5IGNhbiBoZWxwIHlvdSBtYW5hZ2UgY29tcGxleCBwcm9qZWN0cyBhbmQgYWNjb21tb2RhdGUgZGlmZmVyZW50IGVudmlyb25tZW50cyBhbmQgY29uZmlndXJhdGlvbnMuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSBuaW50aCBzZWN0aW9uLCAiUGF0dGVybiBSdWxlcyBhbmQgQXV0b21hdGljIFByZXJlcXVpc2l0ZXMsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBwYXR0ZXJuIHJ1bGVzLCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcywgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZSBpbiBNYWtlZmlsZXMuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyA5LiBQYXR0ZXJuIFJ1bGVzIGFuZCBBdXRvbWF0aWMgUHJlcmVxdWlzaXRlcyBpbiBNYWtlZmlsZXMNCg0KUGF0dGVybiBydWxlcyBhcmUgYSBwb3dlcmZ1bCBmZWF0dXJlIGluIE1ha2VmaWxlcyB0aGF0IGFsbG93IHlvdSB0byBkZWZpbmUgZ2VuZXJpYyBydWxlcyBmb3IgYnVpbGRpbmcgbXVsdGlwbGUgdGFyZ2V0cyB3aXRoIHNpbWlsYXIgcGF0dGVybnMuIEF1dG9tYXRpYyBwcmVyZXF1aXNpdGVzIGV4dGVuZCB0aGlzIGNvbmNlcHQgYnkgYXV0b21hdGljYWxseSBnZW5lcmF0aW5nIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gZm9yIHNvdXJjZSBmaWxlcy4gSW4gdGhpcyBzZWN0aW9uLCB3ZSB3aWxsIGV4cGxvcmUgaG93IHRvIHVzZSBwYXR0ZXJuIHJ1bGVzIGFuZCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBlZmZlY3RpdmVseSBpbiBNYWtlZmlsZXMuDQoNCiMjIyA5LjEgUGF0dGVybiBSdWxlcw0KDQpQYXR0ZXJuIHJ1bGVzIGluIE1ha2VmaWxlcyBkZWZpbmUgYSBnZW5lcmFsIHJ1bGUgZm9yIGJ1aWxkaW5nIHRhcmdldHMgdGhhdCBtYXRjaCBhIHNwZWNpZmljIHBhdHRlcm4uIFRoZXkgYXJlIGEgd2F5IHRvIGF2b2lkIHdyaXRpbmcgbXVsdGlwbGUgc2ltaWxhciBydWxlcyBmb3IgdGFyZ2V0cyB3aXRoIGEgY29tbW9uIHN0cnVjdHVyZS4gVGhlIHN5bnRheCBmb3IgYSBwYXR0ZXJuIHJ1bGUgaXM6DQoNCmBgYCBtYWtlDQolLm91dDogJS5jDQogICAgW2NvbW1hbmRzXQ0KYGBgDQoNCi0gICBgJS5vdXRgOiBUaGUgdGFyZ2V0IHBhdHRlcm4gdGhhdCBtYXRjaGVzIGFueSB0YXJnZXQgZW5kaW5nIHdpdGggYC5vdXRgLg0KLSAgIGAlLmNgOiBUaGUgcHJlcmVxdWlzaXRlIHBhdHRlcm4gdGhhdCBtYXRjaGVzIGFueSBzb3VyY2UgZmlsZSBlbmRpbmcgd2l0aCBgLmNgLg0KLSAgIGBbY29tbWFuZHNdYDogVGhlIGNvbW1hbmRzIHRvIGJ1aWxkIHRoZSB0YXJnZXQgZnJvbSB0aGUgcHJlcmVxdWlzaXRlLg0KDQpGb3IgZXhhbXBsZSwgaWYgeW91IGhhdmUgbXVsdGlwbGUgQyBzb3VyY2UgZmlsZXMgYW5kIHdhbnQgdG8gY3JlYXRlIGV4ZWN1dGFibGVzIGZyb20gdGhlbSwgeW91IGNhbiB1c2UgYSBwYXR0ZXJuIHJ1bGUgbGlrZSB0aGlzOg0KDQpgYGAgbWFrZQ0KJS5vdXQ6ICUuYw0KICAgIGdjYyAtbyAkQCAkPA0KYGBgDQoNCk5vdywgYG1ha2VgIGNhbiBidWlsZCBhbnkgdGFyZ2V0IHdpdGggYSBgLm91dGAgZXh0ZW5zaW9uIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgYC5jYCBzb3VyY2UgZmlsZS4NCg0KIyMjIDkuMiBBdXRvbWF0aWMgUHJlcmVxdWlzaXRlcw0KDQpBdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBhcmUgYW4gZXh0ZW5zaW9uIG9mIHBhdHRlcm4gcnVsZXMgdGhhdCBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24gZm9yIHNvdXJjZSBmaWxlcy4gVGhpcyBpcyBwYXJ0aWN1bGFybHkgdXNlZnVsIHdoZW4geW91IHdhbnQgdG8gdHJhY2sgY2hhbmdlcyBpbiBoZWFkZXIgZmlsZXMgYW5kIGF1dG9tYXRpY2FsbHkgcmVidWlsZCB0YXJnZXRzIHdoZW4gaGVhZGVyIGZpbGVzIGNoYW5nZS4NCg0KVG8gZW5hYmxlIGF1dG9tYXRpYyBwcmVyZXF1aXNpdGVzLCB5b3UgY2FuIHVzZSB0aGUgYC1NYCBmbGFnIHdpdGggdGhlIGBnY2NgIG9yIGBnKytgIGNvbXBpbGVyIHRvIGdlbmVyYXRlIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24uIEZvciBleGFtcGxlOg0KDQpgYGAgbWFrZQ0KJS5vOiAlLmMNCiAgICBnY2MgLU1NRCAtTVAgLU1GICQqLmQgLWMgLW8gJEAgJDwNCmBgYA0KDQotICAgYC1NTURgOiBHZW5lcmF0ZSBkZXBlbmRlbmN5IGluZm9ybWF0aW9uLg0KLSAgIGAtTVBgOiBHZW5lcmF0ZSBwaG9ueSB0YXJnZXRzIGZvciBtaXNzaW5nIGhlYWRlcnMuDQotICAgYC1NRiAkKi5kYDogU3BlY2lmeSB0aGUgZGVwZW5kZW5jeSBmaWxlIHRvIGJlIGdlbmVyYXRlZCAoZS5nLiwgYG1haW4uZGAgZm9yIGBtYWluLmNgKS4NCi0gICBgLWMgLW8gJEAgJDxgOiBDb21waWxlIHRoZSBzb3VyY2UgZmlsZSBpbnRvIGFuIG9iamVjdCBmaWxlLg0KDQpBZGRpdGlvbmFsbHksIHlvdSBjYW4gaW5jbHVkZSB0aGUgZ2VuZXJhdGVkIGRlcGVuZGVuY3kgZmlsZXMgaW4geW91ciBNYWtlZmlsZSB0byBlbnN1cmUgYWNjdXJhdGUgdHJhY2tpbmcgb2YgaGVhZGVyIGZpbGUgY2hhbmdlczoNCg0KYGBgIG1ha2UNCi1pbmNsdWRlICQod2lsZGNhcmQgKi5kKQ0KYGBgDQoNClRoaXMgbGluZSB0ZWxscyBgbWFrZWAgdG8gaW5jbHVkZSBhbGwgYC5kYCBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQoNCiMjIyA5LjMgUHJhY3RpY2FsIFVzYWdlDQoNCkxldCdzIGxvb2sgYXQgcHJhY3RpY2FsIGV4YW1wbGVzIG9mIGhvdyBwYXR0ZXJuIHJ1bGVzIGFuZCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBjYW4gYmUgdXNlZCBpbiBNYWtlZmlsZXMuDQoNCiMjIyMgOS4zLjEgQnVpbGRpbmcgTXVsdGlwbGUgVGFyZ2V0cw0KDQpQYXR0ZXJuIHJ1bGVzIGFyZSBleGNlbGxlbnQgZm9yIGJ1aWxkaW5nIG11bHRpcGxlIHRhcmdldHMgZnJvbSBzaW1pbGFyIHNvdXJjZSBmaWxlcy4gU3VwcG9zZSB5b3UgaGF2ZSBzZXZlcmFsIEMgc291cmNlIGZpbGVzIChgZmlsZTEuY2AsIGBmaWxlMi5jYCwgZXRjLikgdGhhdCB5b3Ugd2FudCB0byBjb21waWxlIGludG8gZXhlY3V0YWJsZXMgKGBmaWxlMS5vdXRgLCBgZmlsZTIub3V0YCwgZXRjLikuIFlvdSBjYW4gdXNlIHRoZSBmb2xsb3dpbmcgcGF0dGVybiBydWxlOg0KDQpgYGAgbWFrZQ0KJS5vdXQ6ICUuYw0KICAgIGdjYyAtbyAkQCAkPA0KYGBgDQoNCk5vdywgYG1ha2UgZmlsZTEub3V0YCB3aWxsIGNvbXBpbGUgYGZpbGUxLmNgIGludG8gYGZpbGUxLm91dGAsIGFuZCB0aGUgc2FtZSBydWxlIGFwcGxpZXMgdG8gb3RoZXIgc291cmNlIGZpbGVzLg0KDQojIyMjIDkuMy4yIEF1dG9tYXRpYyBQcmVyZXF1aXNpdGVzIGZvciBDL0MrKyBQcm9qZWN0cw0KDQpBdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBzaW1wbGlmeSBkZXBlbmRlbmN5IHRyYWNraW5nIGluIEMvQysrIHByb2plY3RzLiBDb25zaWRlciB0aGlzIE1ha2VmaWxlIGZvciBhIEMgcHJvamVjdDoNCg0KYGBgIG1ha2UNCkNDID0gZ2NjDQpDRkxBR1MgPSAtV2FsbCAtTzINCg0KU09VUkNFUyA9IG1haW4uYyB1dGlsLmMNCk9CSkVDVFMgPSAkKFNPVVJDRVM6LmM9Lm8pDQoNCi1pbmNsdWRlICQod2lsZGNhcmQgKi5kKQ0KDQolLm86ICUuYw0KICAgICQoQ0MpIC1NTUQgLU1QIC1NRiAkKi5kICQoQ0ZMQUdTKSAtYyAtbyAkQCAkPA0KDQpteV9wcm9ncmFtOiAkKE9CSkVDVFMpDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gJChPQkpFQ1RTKQ0KYGBgDQoNCldpdGggdGhpcyBzZXR1cCwgdGhlIE1ha2VmaWxlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVzIGRlcGVuZGVuY3kgZmlsZXMgKGAuZGApIGZvciBlYWNoIHNvdXJjZSBmaWxlIGFuZCBpbmNsdWRlcyB0aGVtLiBJZiBhIGhlYWRlciBmaWxlIGNoYW5nZXMsIG9ubHkgdGhlIGFmZmVjdGVkIHNvdXJjZSBmaWxlcyBhcmUgcmVidWlsdCwgc2F2aW5nIGNvbXBpbGF0aW9uIHRpbWUuDQoNCiMjIyMgOS4zLjMgR2VuZXJpYyBSdWxlcyBmb3IgQnVpbGQgU3lzdGVtcw0KDQpQYXR0ZXJuIHJ1bGVzIGFyZSBlc3BlY2lhbGx5IHVzZWZ1bCBpbiBidWlsZCBzeXN0ZW1zIHRoYXQgbmVlZCB0byBoYW5kbGUgdmFyaW91cyBzb3VyY2UgZmlsZXMgYW5kIHRhcmdldHMuIEZvciBleGFtcGxlLCBpbiBhIGJ1aWxkIHN5c3RlbSBmb3IgYSBzY3JpcHRpbmcgbGFuZ3VhZ2UgaW50ZXJwcmV0ZXI6DQoNCmBgYCBtYWtlDQolLm86ICUuYw0KICAgICQoQ0MpIC1NTUQgLU1QIC1NRiAkKi5kICQoQ0ZMQUdTKSAtYyAtbyAkQCAkPA0KDQppbnRlcnByZXRlcjogJChPQkpFQ1RTKQ0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBpbnRlcnByZXRlciAkKE9CSkVDVFMpDQpgYGANCg0KVGhpcyBwYXR0ZXJuIHJ1bGUgYW5kIHRhcmdldCBhbGxvdyB5b3UgdG8gY29tcGlsZSBhbnkgYC5jYCBzb3VyY2UgZmlsZSBpbnRvIGFuIG9iamVjdCBmaWxlIGFuZCB0aGVuIGxpbmsgdGhlbSB0byBjcmVhdGUgdGhlIGludGVycHJldGVyLg0KDQojIyMgOS40IENvbmNsdXNpb24NCg0KUGF0dGVybiBydWxlcyBhbmQgYXV0b21hdGljIHByZXJlcXVpc2l0ZXMgaW4gTWFrZWZpbGVzIHByb3ZpZGUgYSBwb3dlcmZ1bCB3YXkgdG8gc3RyZWFtbGluZSB0aGUgYnVpbGQgcHJvY2VzcyBmb3IgcHJvamVjdHMgd2l0aCBtdWx0aXBsZSBzb3VyY2UgZmlsZXMgYW5kIGRlcGVuZGVuY2llcy4gQnkgZGVmaW5pbmcgZ2VuZXJpYyBydWxlcyBmb3IgYnVpbGRpbmcgdGFyZ2V0cyBhbmQgYXV0b21hdGljYWxseSBnZW5lcmF0aW5nIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24sIHlvdSBjYW4gc2F2ZSB0aW1lIGFuZCBlbnN1cmUgYWNjdXJhdGUgdHJhY2tpbmcgb2YgY2hhbmdlcyBpbiBzb3VyY2UgZmlsZXMgYW5kIGhlYWRlcnMuIFVuZGVyc3RhbmRpbmcgaG93IHRvIHVzZSBwYXR0ZXJuIHJ1bGVzIGFuZCBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyBlZmZlY3RpdmVseSBpcyBlc3NlbnRpYWwgZm9yIGVmZmljaWVudCBzb2Z0d2FyZSBkZXZlbG9wbWVudCB3b3JrZmxvd3MuDQoNCkNlcnRhaW5seSwgbGV0J3MgZXhwYW5kIG9uIHRoZSB0ZW50aCBzZWN0aW9uLCAiTWFuYWdpbmcgTGlicmFyaWVzIGFuZCBMaW5raW5nLCIgdG8gcHJvdmlkZSBhIG1vcmUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb2YgaG93IHRvIG1hbmFnZSBsaWJyYXJpZXMgYW5kIGxpbmtpbmcgaW4gTWFrZWZpbGVzLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgMTAuIE1hbmFnaW5nIExpYnJhcmllcyBhbmQgTGlua2luZyBpbiBNYWtlZmlsZXMNCg0KTGlicmFyaWVzIGFyZSBhbiBlc3NlbnRpYWwgcGFydCBvZiBzb2Z0d2FyZSBkZXZlbG9wbWVudCwgYW5kIGluIE1ha2VmaWxlcywgbWFuYWdpbmcgbGlicmFyaWVzIGFuZCBsaW5raW5nIHRoZW0gdG8geW91ciBwcm9ncmFtcyBpcyBjcnVjaWFsLiBJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgZXhwbG9yZSBob3cgdG8gaW5jbHVkZSBhbmQgbGluayBsaWJyYXJpZXMgZWZmZWN0aXZlbHkgaW4gTWFrZWZpbGVzLg0KDQojIyMgMTAuMSBJbmNsdWRpbmcgTGlicmFyaWVzDQoNCkluY2x1ZGluZyBsaWJyYXJpZXMgaW4geW91ciBNYWtlZmlsZSBpbnZvbHZlcyBzcGVjaWZ5aW5nIHRoZSBuZWNlc3NhcnkgbGlicmFyaWVzIHRoYXQgeW91ciBwcm9ncmFtIGRlcGVuZHMgb24uIFlvdSB0eXBpY2FsbHkgdXNlIHRoZSBgLWxgIGZsYWcgZm9sbG93ZWQgYnkgdGhlIGxpYnJhcnkgbmFtZSB3aGVuIGludm9raW5nIHRoZSBsaW5rZXIgKGUuZy4sIGBnY2NgIG9yIGBnKytgKS4NCg0KSGVyZSdzIGFuIGV4YW1wbGUgb2YgaG93IHRvIGluY2x1ZGUgdGhlIG1hdGggbGlicmFyeSBpbiBhIE1ha2VmaWxlOg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jIC1sbQ0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgdGhlIGAtbG1gIGZsYWcgdGVsbHMgdGhlIGxpbmtlciB0byBpbmNsdWRlIHRoZSBtYXRoIGxpYnJhcnkuDQoNCiMjIyAxMC4yIFNwZWNpZnlpbmcgTGlicmFyeSBEaXJlY3Rvcmllcw0KDQpTb21ldGltZXMsIHRoZSBsaWJyYXJpZXMgeW91IG5lZWQgbWF5IGJlIGxvY2F0ZWQgaW4gbm9uLXN0YW5kYXJkIGRpcmVjdG9yaWVzLiBZb3UgY2FuIHNwZWNpZnkgbGlicmFyeSBkaXJlY3RvcmllcyB1c2luZyB0aGUgYC1MYCBmbGFnIGFuZCB0aGVuIGluY2x1ZGUgdGhlIGxpYnJhcmllcyB1c2luZyB0aGUgYC1sYCBmbGFnLg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jIC1ML3BhdGgvdG8vbGliZGlyIC1sbXlsaWINCmBgYA0KDQpJbiB0aGlzIGNhc2UsIGAvcGF0aC90by9saWJkaXJgIGlzIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgYGxpYm15bGliLmFgIG9yIGBsaWJteWxpYi5zb2AgbGlicmFyeSBmaWxlLg0KDQojIyMgMTAuMyBQcmFjdGljYWwgVXNhZ2UNCg0KTGV0J3MgZXhwbG9yZSBzb21lIHByYWN0aWNhbCBleGFtcGxlcyBvZiBtYW5hZ2luZyBsaWJyYXJpZXMgYW5kIGxpbmtpbmcgdGhlbSBpbiBNYWtlZmlsZXMuDQoNCiMjIyMgMTAuMy4xIExpbmtpbmcgd2l0aCBNdWx0aXBsZSBMaWJyYXJpZXMNCg0KSWYgeW91ciBwcm9ncmFtIGRlcGVuZHMgb24gbXVsdGlwbGUgbGlicmFyaWVzLCB5b3UgY2FuIHNwZWNpZnkgdGhlbSBieSBzZXBhcmF0aW5nIHRoZW0gd2l0aCBzcGFjZSBhZnRlciB0aGUgYC1sYCBmbGFnOg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jIC1sbSAtbHB0aHJlYWQgLWxteWxpYg0KYGBgDQoNCkluIHRoaXMgZXhhbXBsZSwgd2UncmUgbGlua2luZyB3aXRoIHRoZSBtYXRoIGxpYnJhcnkgKGAtbG1gKSwgdGhlIHB0aHJlYWQgbGlicmFyeSAoYC1scHRocmVhZGApLCBhbmQgYSBjdXN0b20gbGlicmFyeSAoYC1sbXlsaWJgKS4NCg0KIyMjIyAxMC4zLjIgVXNpbmcgVmFyaWFibGVzIGZvciBMaWJyYXJpZXMNCg0KVG8gbWFrZSB5b3VyIE1ha2VmaWxlIG1vcmUgbWFpbnRhaW5hYmxlLCB5b3UgY2FuIHVzZSB2YXJpYWJsZXMgdG8gc3RvcmUgbGlicmFyeSBmbGFnczoNCg0KYGBgIG1ha2UNCkxJQlMgPSAtbG0gLWxwdGhyZWFkIC1sbXlsaWINCg0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgZ2NjIC1vIG15X3Byb2dyYW0gbWFpbi5jICQoTElCUykNCmBgYA0KDQpCeSB1c2luZyB2YXJpYWJsZXMsIGl0J3MgZWFzaWVyIHRvIGFkZCBvciByZW1vdmUgbGlicmFyaWVzIGZyb20geW91ciBwcm9qZWN0IHdpdGhvdXQgY2hhbmdpbmcgZXZlcnkgb2NjdXJyZW5jZSBpbiB5b3VyIE1ha2VmaWxlLg0KDQojIyMjIDEwLjMuMyBDb25kaXRpb25hbCBMaW5raW5nDQoNCllvdSBjYW4gdXNlIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgaW4geW91ciBNYWtlZmlsZSB0byBoYW5kbGUgZGlmZmVyZW50IGJ1aWxkIGNvbmZpZ3VyYXRpb25zIGFuZCBsaW5rIGxpYnJhcmllcyBhY2NvcmRpbmdseS4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCB3YW50IHRvIGxpbmsgd2l0aCBhIGRlYnVnZ2luZyBsaWJyYXJ5IHdoZW4gZGVidWdnaW5nIGlzIGVuYWJsZWQ6DQoNCmBgYCBtYWtlDQpERUJVRyA/PSAwDQpMSUJTID0gLWxtIC1scHRocmVhZA0KDQppZmVxICgkKERFQlVHKSwgMSkNCiAgICBMSUJTICs9IC1sZGVidWcNCmVuZGlmDQoNCm15X3Byb2dyYW06IG1haW4uYw0KICAgIGdjYyAtbyBteV9wcm9ncmFtIG1haW4uYyAkKExJQlMpDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYC1sZGVidWdgIGxpYnJhcnkgaXMgaW5jbHVkZWQgaW4gdGhlIGBMSUJTYCB2YXJpYWJsZSBvbmx5IGlmIHRoZSBgREVCVUdgIHZhcmlhYmxlIGlzIHNldCB0byBgMWAuDQoNCiMjIyMgMTAuMy40IEF1dG9tYXRpYyBEZXBlbmRlbmN5IFRyYWNraW5nDQoNCklmIHlvdXIgcHJvamVjdCBoYXMgaGVhZGVyIGZpbGUgZGVwZW5kZW5jaWVzLCB5b3UgY2FuIHVzZSBhdXRvbWF0aWMgcHJlcmVxdWlzaXRlcyAoYXMgZGlzY3Vzc2VkIGluIHNlY3Rpb24gOSkgdG8gYXV0b21hdGljYWxseSB0cmFjayBjaGFuZ2VzIGluIGhlYWRlciBmaWxlcyBhbmQgcmVjb21waWxlIHRoZSBwcm9ncmFtIHdoZW4gbmVlZGVkLiBUaGlzIGVuc3VyZXMgdGhhdCB5b3VyIHByb2dyYW0gaXMgcmVidWlsdCB3aGVuIGFueSBvZiBpdHMgZGVwZW5kZW5jaWVzIGNoYW5nZS4NCg0KYGBgIG1ha2UNCkNDID0gZ2NjDQpDRkxBR1MgPSAtV2FsbCAtTzINClNPVVJDRVMgPSBtYWluLmMgdXRpbC5jDQpPQkpFQ1RTID0gJChTT1VSQ0VTOi5jPS5vKQ0KDQotaW5jbHVkZSAkKHdpbGRjYXJkICouZCkNCg0KJS5vOiAlLmMNCiAgICAkKENDKSAtTU1EIC1NUCAtTUYgJCouZCAkKENGTEFHUykgLWMgLW8gJEAgJDwNCg0KbXlfcHJvZ3JhbTogJChPQkpFQ1RTKQ0KICAgICQoQ0MpICQoQ0ZMQUdTKSAtbyBteV9wcm9ncmFtICQoT0JKRUNUUykgLWxtIC1scHRocmVhZCAtbG15bGliDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB3ZSBpbmNsdWRlIGxpYnJhcmllcyBhcyB3ZWxsIGFzIGRlcGVuZGVuY2llcyBnZW5lcmF0ZWQgZm9yIHNvdXJjZSBmaWxlcy4NCg0KIyMjIDEwLjQgQ29uY2x1c2lvbg0KDQpNYW5hZ2luZyBsaWJyYXJpZXMgYW5kIGxpbmtpbmcgaW4gTWFrZWZpbGVzIGlzIGVzc2VudGlhbCBmb3IgYnVpbGRpbmcgY29tcGxleCBzb2Z0d2FyZSBwcm9qZWN0cy4gQnkgc3BlY2lmeWluZyBsaWJyYXJpZXMsIGxpYnJhcnkgZGlyZWN0b3JpZXMsIGFuZCB1c2luZyB2YXJpYWJsZXMgYW5kIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMsIHlvdSBjYW4gY3JlYXRlIE1ha2VmaWxlcyB0aGF0IGhhbmRsZSBsaWJyYXJ5IG1hbmFnZW1lbnQgZWZmaWNpZW50bHkuIEFkZGl0aW9uYWxseSwgYXV0b21hdGljIGRlcGVuZGVuY3kgdHJhY2tpbmcgZW5zdXJlcyB0aGF0IHlvdXIgcHJvZ3JhbSBpcyByZWJ1aWx0IHdoZW4gbmVjZXNzYXJ5LCBrZWVwaW5nIHlvdXIgYnVpbGQgcHJvY2VzcyB1cC10by1kYXRlIGFuZCByZWxpYWJsZS4gVW5kZXJzdGFuZGluZyB0aGVzZSBjb25jZXB0cyBpcyBjcnVjaWFsIGZvciBlZmZlY3RpdmUgc29mdHdhcmUgZGV2ZWxvcG1lbnQgd29ya2Zsb3dzIHVzaW5nIE1ha2VmaWxlcy4NCg0KQ2VydGFpbmx5LCBsZXQncyBleHBhbmQgb24gdGhlIGVsZXZlbnRoIHNlY3Rpb24sICJDbGVhbmluZyBhbmQgTWFpbnRlbmFuY2UsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBjbGVhbmluZyB0YXJnZXRzLCBtYWludGFpbmluZyBNYWtlZmlsZXMsIGFuZCBvdGhlciBhc3BlY3RzIHJlbGF0ZWQgdG8gY2xlYW5pbmcgYW5kIG1haW50YWluaW5nIHlvdXIgcHJvamVjdCB3aXRoIE1ha2VmaWxlcy4NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIDExLiBDbGVhbmluZyBhbmQgTWFpbnRlbmFuY2UgaW4gTWFrZWZpbGVzDQoNCkNsZWFuaW5nIGFuZCBtYWludGFpbmluZyBhIHByb2plY3QgaXMgYSBjcnVjaWFsIHBhcnQgb2Ygc29mdHdhcmUgZGV2ZWxvcG1lbnQuIE1ha2VmaWxlcyBwcm92aWRlIHNldmVyYWwgZmVhdHVyZXMgdG8gaGVscCB5b3UgbWFuYWdlIHRoZXNlIHRhc2tzIGVmZmljaWVudGx5LiBJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgZXhwbG9yZSBob3cgdG8gY3JlYXRlIGNsZWFuaW5nIHRhcmdldHMsIGhhbmRsZSBwcm9qZWN0IG1haW50ZW5hbmNlLCBhbmQgb3RoZXIgcmVsYXRlZCBhc3BlY3RzIGluIE1ha2VmaWxlcy4NCg0KIyMjIDExLjEgQ2xlYW5pbmcgVGFyZ2V0cw0KDQpDbGVhbmluZyB0YXJnZXRzIGFyZSB1c2VkIHRvIHJlbW92ZSBnZW5lcmF0ZWQgZmlsZXMgYW5kIGFydGlmYWN0cywgZW5zdXJpbmcgYSBjbGVhbiBwcm9qZWN0IGRpcmVjdG9yeSBmb3IgcmVidWlsZGluZyBvciBkaXN0cmlidXRpb24uIEEgY29tbW9uIGNsZWFuaW5nIHRhcmdldCBpbiBhIE1ha2VmaWxlIGlzIGBjbGVhbmAuIFRvIGNyZWF0ZSBhIGBjbGVhbmAgdGFyZ2V0LCB5b3UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIHJ1bGU6DQoNCmBgYCBtYWtlDQouUEhPTlk6IGNsZWFuDQoNCmNsZWFuOg0KICAgIHJtIC1mIG15X3Byb2dyYW0gKi5vDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYGNsZWFuYCB0YXJnZXQgcmVtb3ZlcyB0aGUgYG15X3Byb2dyYW1gIGV4ZWN1dGFibGUgYW5kIGFsbCBvYmplY3QgZmlsZXMgKGAqLm9gKSBmcm9tIHRoZSBwcm9qZWN0IGRpcmVjdG9yeSB3aGVuIHlvdSBydW4gYG1ha2UgY2xlYW5gLg0KDQojIyMgMTEuMiBNYWludGVuYW5jZSBUYXJnZXRzDQoNCk1haW50ZW5hbmNlIHRhcmdldHMgYXJlIHVzZWQgdG8gcGVyZm9ybSB0YXNrcyByZWxhdGVkIHRvIHByb2plY3QgbWFpbnRlbmFuY2UsIHN1Y2ggYXMgZ2VuZXJhdGluZyBkb2N1bWVudGF0aW9uLCBydW5uaW5nIHRlc3RzLCBvciBjaGVja2luZyBjb2RlIGZvcm1hdHRpbmcuIEhlcmUgYXJlIHNvbWUgZXhhbXBsZXM6DQoNCiMjIyMgMTEuMi4xIEdlbmVyYXRpbmcgRG9jdW1lbnRhdGlvbg0KDQpZb3UgY2FuIGNyZWF0ZSBhIHRhcmdldCBjYWxsZWQgYGRvY3NgIHRvIGdlbmVyYXRlIHByb2plY3QgZG9jdW1lbnRhdGlvbi4gRm9yIGluc3RhbmNlLCBpZiB5b3UgdXNlIERveHlnZW4gZm9yIGRvY3VtZW50YXRpb24gZ2VuZXJhdGlvbjoNCg0KYGBgIG1ha2UNCi5QSE9OWTogZG9jcw0KDQpkb2NzOg0KICAgIGRveHlnZW4NCmBgYA0KDQpSdW5uaW5nIGBtYWtlIGRvY3NgIHdpbGwgZXhlY3V0ZSB0aGUgYGRveHlnZW5gIGNvbW1hbmQgdG8gZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbi4NCg0KIyMjIyAxMS4yLjIgUnVubmluZyBUZXN0cw0KDQpUbyBydW4geW91ciBwcm9qZWN0J3MgdGVzdCBzdWl0ZSwgeW91IGNhbiBjcmVhdGUgYSB0YXJnZXQgY2FsbGVkIGB0ZXN0YDoNCg0KYGBgIG1ha2UNCi5QSE9OWTogdGVzdA0KDQp0ZXN0Og0KICAgIC4vcnVuX3Rlc3RzLnNoDQpgYGANCg0KSW4gdGhpcyBleGFtcGxlLCB0aGUgYHRlc3RgIHRhcmdldCBleGVjdXRlcyBhIHNjcmlwdCAoYHJ1bl90ZXN0cy5zaGApIHRoYXQgcnVucyB5b3VyIHByb2plY3QncyB0ZXN0IGNhc2VzLg0KDQojIyMjIDExLjIuMyBDb2RlIEZvcm1hdHRpbmcNCg0KWW91IGNhbiBhbHNvIGNyZWF0ZSBhIHRhcmdldCB0byBjaGVjayBvciBmb3JtYXQgeW91ciBjb2RlIHVzaW5nIHRvb2xzIGxpa2UgYGNsYW5nLWZvcm1hdGA6DQoNCmBgYCBtYWtlDQouUEhPTlk6IGZvcm1hdA0KDQpmb3JtYXQ6DQogICAgY2xhbmctZm9ybWF0IC1pICouYw0KYGBgDQoNClJ1bm5pbmcgYG1ha2UgZm9ybWF0YCB3b3VsZCBhcHBseSBjb2RlIGZvcm1hdHRpbmcgdG8gYWxsIGAuY2Agc291cmNlIGZpbGVzLg0KDQojIyMgMTEuMyBBdXRvbWF0aW5nIERlcGVuZGVuY3kgQ2xlYW51cA0KDQpJZiB5b3VyIE1ha2VmaWxlIGdlbmVyYXRlcyBkZXBlbmRlbmN5IGZpbGVzIChhcyBkaXNjdXNzZWQgaW4gc2VjdGlvbiA5KSwgeW91IGNhbiBjcmVhdGUgYSB0YXJnZXQgdG8gY2xlYW4gdXAgdGhlc2UgZmlsZXMgd2hlbiBubyBsb25nZXIgbmVlZGVkOg0KDQpgYGAgbWFrZQ0KLlBIT05ZOiBjbGVhbi1kZXBzDQoNCmNsZWFuLWRlcHM6DQogICAgcm0gLWYgKi5kDQpgYGANCg0KVGhlIGBjbGVhbi1kZXBzYCB0YXJnZXQgcmVtb3ZlcyBhbGwgZ2VuZXJhdGVkIGRlcGVuZGVuY3kgZmlsZXMgKGAqLmRgKSBmcm9tIHRoZSBwcm9qZWN0IGRpcmVjdG9yeS4NCg0KIyMjIDExLjQgQ29uZGl0aW9uYWwgTWFpbnRlbmFuY2UgVGFyZ2V0cw0KDQpZb3UgY2FuIHVzZSBjb25kaXRpb25hbCBzdGF0ZW1lbnRzIHRvIGNvbnRyb2wgd2hlbiBtYWludGVuYW5jZSB0YXJnZXRzIHNob3VsZCBiZSBleGVjdXRlZC4gRm9yIGV4YW1wbGUsIHlvdSBtaWdodCB3YW50IHRvIGdlbmVyYXRlIGRvY3VtZW50YXRpb24gb25seSBmb3Igc3BlY2lmaWMgYnVpbGQgY29uZmlndXJhdGlvbnM6DQoNCmBgYCBtYWtlDQpERUJVRyA/PSAwDQoNCmlmZXEgKCQoREVCVUcpLCAxKQ0KICAgIC5QSE9OWTogZG9jcw0KDQogICAgZG9jczoNCiAgICAgICAgZG94eWdlbg0KZW5kaWYNCmBgYA0KDQpJbiB0aGlzIGV4YW1wbGUsIHRoZSBgZG9jc2AgdGFyZ2V0IGlzIGRlZmluZWQgYW5kIG1hcmtlZCBhcyBwaG9ueSBvbmx5IGlmIHRoZSBgREVCVUdgIHZhcmlhYmxlIGlzIHNldCB0byBgMWAsIGVuc3VyaW5nIHRoYXQgZG9jdW1lbnRhdGlvbiBpcyBnZW5lcmF0ZWQgb25seSBmb3IgZGVidWdnaW5nIGJ1aWxkcy4NCg0KIyMjIDExLjUgQ29uY2x1c2lvbg0KDQpDbGVhbmluZyBhbmQgbWFpbnRhaW5pbmcgYSBwcm9qZWN0IGFyZSBlc3NlbnRpYWwgYXNwZWN0cyBvZiBzb2Z0d2FyZSBkZXZlbG9wbWVudCwgYW5kIE1ha2VmaWxlcyBvZmZlciBjb252ZW5pZW50IHdheXMgdG8gYXV0b21hdGUgdGhlc2UgdGFza3MuIEJ5IGNyZWF0aW5nIGNsZWFuaW5nIGFuZCBtYWludGVuYW5jZSB0YXJnZXRzLCB5b3UgY2FuIGtlZXAgeW91ciBwcm9qZWN0IGRpcmVjdG9yeSBvcmdhbml6ZWQgYW5kIHVwLXRvLWRhdGUuIEFkZGl0aW9uYWxseSwgdXNpbmcgY29uZGl0aW9uYWwgc3RhdGVtZW50cyBhbGxvd3MgeW91IHRvIGNvbnRyb2wgd2hlbiB0aGVzZSB0YXJnZXRzIGFyZSBleGVjdXRlZCwgZW5zdXJpbmcgdGhleSBhbGlnbiB3aXRoIHlvdXIgcHJvamVjdCdzIG5lZWRzIGFuZCBidWlsZCBjb25maWd1cmF0aW9ucy4gVW5kZXJzdGFuZGluZyBhbmQgZWZmZWN0aXZlbHkgdXRpbGl6aW5nIHRoZXNlIGZlYXR1cmVzIGluIE1ha2VmaWxlcyBpcyBjcnVjaWFsIGZvciBtYW5hZ2luZyBjb21wbGV4IHNvZnR3YXJlIHByb2plY3RzIGVmZmljaWVudGx5Lg0KDQpDZXJ0YWlubHksIGxldCdzIGV4cGFuZCBvbiB0aGUgdHdlbGZ0aCBzZWN0aW9uLCAiQWR2YW5jZWQgVGVjaG5pcXVlcyBhbmQgQmVzdCBQcmFjdGljZXMsIiB0byBwcm92aWRlIGEgbW9yZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvZiBhZHZhbmNlZCBNYWtlZmlsZSB0ZWNobmlxdWVzIGFuZCBiZXN0IHByYWN0aWNlcyB0aGF0IGNhbiBoZWxwIHlvdSBjcmVhdGUgZWZmaWNpZW50IGFuZCBtYWludGFpbmFibGUgYnVpbGQgc3lzdGVtcy4NCg0KIyMgQWR2YW5jZWQgVGVjaG5pcXVlcyBhbmQgQmVzdCBQcmFjdGljZXMgaW4gTWFrZWZpbGVzDQoNCkFkdmFuY2VkIHRlY2huaXF1ZXMgYW5kIGJlc3QgcHJhY3RpY2VzIGluIE1ha2VmaWxlcyBjYW4gc2lnbmlmaWNhbnRseSBpbXByb3ZlIHRoZSBlZmZpY2llbmN5IGFuZCBtYWludGFpbmFiaWxpdHkgb2YgeW91ciBidWlsZCBzeXN0ZW0uIEluIHRoaXMgc2VjdGlvbiwgd2UnbGwgZXhwbG9yZSBzb21lIGFkdmFuY2VkIHRlY2huaXF1ZXMgYW5kIGJlc3QgcHJhY3RpY2VzIHRoYXQgY2FuIGVsZXZhdGUgeW91ciBNYWtlZmlsZSBza2lsbHMuDQoNCiMjIyBVc2UgVmFyaWFibGVzIGZvciBDb21waWxlciBhbmQgRmxhZ3MNCg0KVXNpbmcgdmFyaWFibGVzIHRvIHN0b3JlIGNvbXBpbGVyIGFuZCBmbGFnIHNldHRpbmdzIGluIHlvdXIgTWFrZWZpbGUgbWFrZXMgaXQgbW9yZSBtYWludGFpbmFibGUgYW5kIGFkYXB0YWJsZS4gRm9yIGV4YW1wbGU6DQoNCmBgYCBtYWtlDQpDQyA9IGdjYw0KQ0ZMQUdTID0gLVdhbGwgLU8yDQpgYGANCg0KQnkgZGVmaW5pbmcgdGhlc2UgdmFyaWFibGVzLCB5b3UgY2FuIGVhc2lseSBjaGFuZ2UgdGhlIGNvbXBpbGVyIG9yIGNvbXBpbGVyIGZsYWdzIGluIG9uZSBwbGFjZSwgbWFraW5nIGl0IGxlc3MgZXJyb3ItcHJvbmUgYW5kIG1vcmUgZmxleGlibGUuDQoNCiMjIyBQaG9ueSBUYXJnZXRzDQoNCkFsd2F5cyBtYXJrIHRhcmdldHMgdGhhdCBkb24ndCBjb3JyZXNwb25kIHRvIGFjdHVhbCBmaWxlcyAoZS5nLiwgYGNsZWFuYCwgYGFsbGAsIGB0ZXN0YCwgYGRvY3NgKSBhcyBwaG9ueSB1c2luZyB0aGUgYC5QSE9OWWAgc3BlY2lhbCB0YXJnZXQuIFRoaXMgaGVscHMgcHJldmVudCBjb25mbGljdHMgd2l0aCBmaWxlcyBvZiB0aGUgc2FtZSBuYW1lIGFuZCBlbnN1cmVzIHRoYXQgdGhlIHRhcmdldCBpcyBhbHdheXMgZXhlY3V0ZWQsIGV2ZW4gaWYgYSBmaWxlIHdpdGggdGhlIHNhbWUgbmFtZSBleGlzdHMuDQoNCmBgYCBtYWtlDQouUEhPTlk6IGNsZWFuIHRlc3QgZG9jcw0KYGBgDQoNCiMjIyBVc2UgV2lsZGNhcmRzIGZvciBTb3VyY2UgRmlsZXMNCg0KSW5zdGVhZCBvZiBsaXN0aW5nIGFsbCBzb3VyY2UgZmlsZXMgbWFudWFsbHksIHlvdSBjYW4gdXNlIHdpbGRjYXJkcyB0byBhdXRvbWF0aWNhbGx5IGRldGVjdCBzb3VyY2UgZmlsZXMgaW4gYSBkaXJlY3RvcnkuIEZvciBleGFtcGxlLCB0byBjb21waWxlIGFsbCBgLmNgIGZpbGVzIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeToNCg0KYGBgIG1ha2UNClNPVVJDRVMgPSAkKHdpbGRjYXJkICouYykNCmBgYA0KDQpUaGlzIGFwcHJvYWNoIGlzIG1vcmUgbWFpbnRhaW5hYmxlIGFzIGl0IGF1dG9tYXRpY2FsbHkgYWRhcHRzIHRvIGNoYW5nZXMgaW4gdGhlIGRpcmVjdG9yeS4NCg0KIyMjIEdlbmVyYXRpbmcgRGVwZW5kZW5jeSBGaWxlcyBBdXRvbWF0aWNhbGx5DQoNCkF1dG9tYXRpY2FsbHkgZ2VuZXJhdGluZyBkZXBlbmRlbmN5IGZpbGVzIGZvciBDL0MrKyBwcm9qZWN0cyB1c2luZyB0b29scyBsaWtlIGBnY2MgLU1gIChhcyBkaXNjdXNzZWQgaW4gc2VjdGlvbiA5KSBpcyBhIHBvd2VyZnVsIHRlY2huaXF1ZS4gSXQgZW5zdXJlcyB0aGF0IHlvdXIgTWFrZWZpbGUgYWNjdXJhdGVseSB0cmFja3MgaGVhZGVyIGZpbGUgZGVwZW5kZW5jaWVzLCByZWR1Y2luZyB0aGUgcmlzayBvZiBicm9rZW4gYnVpbGRzLg0KDQpgYGAgbWFrZQ0KLWluY2x1ZGUgJCh3aWxkY2FyZCAqLmQpDQpgYGANCg0KIyMjIENvbmRpdGlvbmFsIENvbXBpbGF0aW9uDQoNCkNvbmRpdGlvbmFsIGNvbXBpbGF0aW9uIChhcyBkaXNjdXNzZWQgaW4gc2VjdGlvbiA4KSBhbGxvd3MgeW91IHRvIGFkYXB0IHlvdXIgYnVpbGQgcHJvY2VzcyB0byBkaWZmZXJlbnQgY29uZmlndXJhdGlvbnMgb3IgcGxhdGZvcm1zLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIGVuYWJsaW5nIG9yIGRpc2FibGluZyBmZWF0dXJlcywgc2V0dGluZyBjb21waWxlciBmbGFncyBjb25kaXRpb25hbGx5LCBvciBzcGVjaWZ5aW5nIGRpZmZlcmVudCBidWlsZCBwYXRocy4NCg0KIyMjIFNlcGFyYXRlIERpcmVjdG9yaWVzIGZvciBPYmplY3QgRmlsZXMNCg0KT3JnYW5pemluZyBvYmplY3QgZmlsZXMgaW4gYSBzZXBhcmF0ZSBkaXJlY3RvcnkgKGUuZy4sIGBvYmovYCkgaW5zdGVhZCBvZiBjbHV0dGVyaW5nIHRoZSBzb3VyY2UgZGlyZWN0b3J5IGNhbiBtYWtlIHlvdXIgcHJvamVjdCBzdHJ1Y3R1cmUgY2xlYW5lciBhbmQgYXZvaWQgY29uZmxpY3RzIGJldHdlZW4gb2JqZWN0IGZpbGVzIGFuZCBzb3VyY2UgZmlsZXMgd2l0aCB0aGUgc2FtZSBuYW1lcy4NCg0KYGBgIG1ha2UNCk9CSl9ESVIgPSBvYmoNCk9CSkVDVFMgPSAkKGFkZHByZWZpeCAkKE9CSl9ESVIpLywgJChTT1VSQ0VTOi5jPS5vKSkNCg0KJChPQkpfRElSKS8lLm86ICUuYw0KICAgICQoQ0MpIC1NTUQgLU1QIC1NRiAkKE9CSl9ESVIpLyQqLmQgJChDRkxBR1MpIC1jIC1vICRAICQ8DQpgYGANCg0KIyMjIFRhcmdldC1TcGVjaWZpYyBWYXJpYWJsZXMNCg0KWW91IGNhbiBzZXQgdmFyaWFibGVzIHRoYXQgYXJlIHNwZWNpZmljIHRvIGEgcGFydGljdWxhciB0YXJnZXQuIFRoaXMgYWxsb3dzIHlvdSB0byBjdXN0b21pemUgY29tcGlsYXRpb24gZmxhZ3Mgb3Igc2V0dGluZ3MgZm9yIHNwZWNpZmljIHNvdXJjZSBmaWxlcyBvciB0YXJnZXRzLg0KDQpgYGAgbWFrZQ0KbXlfcHJvZ3JhbTogbWFpbi5jDQogICAgJChDQykgJChDRkxBR1MpIC1vIG15X3Byb2dyYW0gbWFpbi5jDQoNCnNwZWNpYWxfdGFyZ2V0OiBzcGVjaWFsLmMNCiAgICAkKENDKSAkKENGTEFHU19TUEVDSUFMKSAtbyBzcGVjaWFsX3RhcmdldCBzcGVjaWFsLmMNCmBgYA0KDQpIZXJlLCBgQ0ZMQUdTX1NQRUNJQUxgIGlzIHVzZWQgb25seSBmb3IgdGhlIGBzcGVjaWFsX3RhcmdldGAuDQoNCiMjIyBQYXJhbGxlbCBCdWlsZHMNCg0KWW91IGNhbiB1c2UgdGhlIGAtamAgZmxhZyB3aXRoIHRoZSBgbWFrZWAgY29tbWFuZCB0byBlbmFibGUgcGFyYWxsZWwgYnVpbGRzLCB3aGljaCBjYW4gc2lnbmlmaWNhbnRseSByZWR1Y2UgYnVpbGQgdGltZXMgb24gbXVsdGktY29yZSBzeXN0ZW1zLiBGb3IgZXhhbXBsZSwgYG1ha2UgLWo0YCB3aWxsIHJ1biB1cCB0byBmb3VyIGpvYnMgY29uY3VycmVudGx5Lg0KDQojIyMgQ29tbWVudHMgYW5kIERvY3VtZW50YXRpb24NCg0KQWRkaW5nIGNvbW1lbnRzIHRvIHlvdXIgTWFrZWZpbGUgaGVscHMgZG9jdW1lbnQgaXRzIHN0cnVjdHVyZSBhbmQgcHVycG9zZS4gSXQncyBhbHNvIGEgZ29vZCBwcmFjdGljZSB0byBpbmNsdWRlIGEgc2VjdGlvbiBhdCB0aGUgYmVnaW5uaW5nIG9mIHlvdXIgTWFrZWZpbGUgdGhhdCBleHBsYWlucyBpdHMgdXNhZ2UsIGRlcGVuZGVuY2llcywgYW5kIGFueSBzcGVjaWFsIGluc3RydWN0aW9ucyBmb3IgYnVpbGRpbmcgdGhlIHByb2plY3QuDQoNCiMjIyBWZXJzaW9uIENvbnRyb2wgSW50ZWdyYXRpb24NCg0KSWYgeW91J3JlIHVzaW5nIGEgdmVyc2lvbiBjb250cm9sIHN5c3RlbSBsaWtlIEdpdCwgY29uc2lkZXIgYWRkaW5nIGEgYC5naXRpZ25vcmVgIGZpbGUgdG8gaWdub3JlIGdlbmVyYXRlZCBmaWxlcywgb2JqZWN0IGZpbGVzLCBhbmQgYnVpbGQgYXJ0aWZhY3RzLiBUaGlzIGtlZXBzIHlvdXIgcmVwb3NpdG9yeSBjbGVhbiBhbmQgYXZvaWRzIHRyYWNraW5nIHVubmVjZXNzYXJ5IGZpbGVzLg0KDQojIyMgQ29udGludW91cyBJbnRlZ3JhdGlvbg0KDQpJbnRlZ3JhdGUgeW91ciBNYWtlZmlsZSB3aXRoIGEgY29udGludW91cyBpbnRlZ3JhdGlvbiAoQ0kpIHN5c3RlbSBsaWtlIEplbmtpbnMsIFRyYXZpcyBDSSwgb3IgR2l0SHViIEFjdGlvbnMuIFRoaXMgZW5zdXJlcyB0aGF0IHlvdXIgcHJvamVjdCBpcyBhdXRvbWF0aWNhbGx5IGJ1aWx0IGFuZCB0ZXN0ZWQgb24gZXZlcnkgcHVzaCB0byB0aGUgcmVwb3NpdG9yeSwgaGVscGluZyBjYXRjaCBpc3N1ZXMgZWFybHkuDQoNCiMjIyBEZWJ1Z2dpbmcgTWFrZWZpbGVzDQoNCldoZW4gZGVidWdnaW5nIE1ha2VmaWxlcywgeW91IGNhbiB1c2UgdGhlIGAtbmAgb3IgYC0tanVzdC1wcmludGAgZmxhZyB3aXRoIGBtYWtlYCB0byBzZWUgdGhlIGNvbW1hbmRzIHRoYXQgd291bGQgYmUgZXhlY3V0ZWQgd2l0aG91dCBhY3R1YWxseSBydW5uaW5nIHRoZW0uIFRoaXMgY2FuIGhlbHAgaWRlbnRpZnkgaXNzdWVzIGluIHlvdXIgcnVsZXMgYW5kIGRlcGVuZGVuY2llcy4gQSBjb21tb24gbWlzdGFrZSBpcyBub3Qgc3RhcnRpbmcgYSBsaW5lIGZvciBhIGNvbW1hbmQgd2l0aCB0aGUgVEFCIG9yIHVzaW5nIGFuIGVkaXRvciB3aGljaCByZXBsYWNlcyBUQUIgd2l0aCA0IG9yIDggc3BhY2VzLg0KDQojIyMgVGVzdGluZyBhbmQgVmFsaWRhdGlvbg0KDQpSZWd1bGFybHkgdGVzdCBhbmQgdmFsaWRhdGUgeW91ciBNYWtlZmlsZXMgd2l0aCB2YXJpb3VzIGJ1aWxkIGNvbmZpZ3VyYXRpb25zIGFuZCBwbGF0Zm9ybXMgdG8gZW5zdXJlIHRoZXkgd29yayBjb3JyZWN0bHkgaW4gZGlmZmVyZW50IHNjZW5hcmlvcy4gQXV0b21hdGVkIHRlc3Rpbmcgb2YgdGhlIGJ1aWxkIHByb2Nlc3MgY2FuIGJlIGludmFsdWFibGUgaW4gY2F0Y2hpbmcgcmVncmVzc2lvbnMuDQoNCiMjIyBNb2R1bGFyaXphdGlvbg0KDQpGb3IgY29tcGxleCBwcm9qZWN0cywgY29uc2lkZXIgbW9kdWxhcml6aW5nIHlvdXIgTWFrZWZpbGUgYnkgc3BsaXR0aW5nIGl0IGludG8gbXVsdGlwbGUgc21hbGxlciBNYWtlZmlsZXMgb3IgaW5jbHVkaW5nIHNlcGFyYXRlIE1ha2VmaWxlcyBmb3Igc3BlY2lmaWMgY29tcG9uZW50cyBvciBzdWJzeXN0ZW1zLiBUaGlzIGNhbiBtYWtlIHRoZSBidWlsZCBzeXN0ZW0gbW9yZSBtYW5hZ2VhYmxlLg0KDQojIyMgUGVyZm9ybWFuY2UgT3B0aW1pemF0aW9uDQoNClByb2ZpbGUgYW5kIG9wdGltaXplIHlvdXIgYnVpbGQgcHJvY2VzcywgZXNwZWNpYWxseSBmb3IgbGFyZ2UgcHJvamVjdHMuIElkZW50aWZ5aW5nIGFuZCBlbGltaW5hdGluZyBib3R0bGVuZWNrcyBjYW4gc2lnbmlmaWNhbnRseSBpbXByb3ZlIGJ1aWxkIHRpbWVzIGFuZCBkZXZlbG9wZXIgcHJvZHVjdGl2aXR5Lg0KDQojIyMgQnVpbGQgVGFyZ2V0cw0KDQpEZWZpbmUgY2xlYXIgYW5kIHNwZWNpZmljIGJ1aWxkIHRhcmdldHMgKGUuZy4sIGBhbGxgLCBgY2xlYW5gLCBgdGVzdGAsIGBkb2NzYCwgYGluc3RhbGxgKSB0byBzdGFuZGFyZGl6ZSB0aGUgYnVpbGQgcHJvY2VzcyBhY3Jvc3MgeW91ciBwcm9qZWN0cyBhbmQgbWFrZSBpdCBlYXNpZXIgZm9yIHRlYW0gbWVtYmVycyB0byB1bmRlcnN0YW5kIGFuZCB1c2UgdGhlIE1ha2VmaWxlLg0KDQojIyMgRXJyb3IgSGFuZGxpbmcNCg0KSW1wbGVtZW50IGVycm9yIGhhbmRsaW5nIGluIHlvdXIgTWFrZWZpbGUgdG8gZGV0ZWN0IGFuZCByZXBvcnQgZXJyb3JzIGR1cmluZyB0aGUgYnVpbGQgcHJvY2Vzcy4gWW91IGNhbiB1c2UgY29uc3RydWN0cyBsaWtlIGB8fGAgdG8gZXhlY3V0ZSBjb21tYW5kcyBjb25kaXRpb25hbGx5IGJhc2VkIG9uIHRoZSBzdWNjZXNzIG9mIHByZXZpb3VzIGNvbW1hbmRzLg0KDQojIyMgQ29udGludW91cyBMZWFybmluZw0KDQpLZWVwIGV4cGxvcmluZyBhZHZhbmNlZCBNYWtlZmlsZSB0ZWNobmlxdWVzLCBiZXN0IHByYWN0aWNlcywgYW5kIG5ldyBmZWF0dXJlcyBhcyB5b3UgY29udGludWUgdG8gd29yayBvbiBkaWZmZXJlbnQgcHJvamVjdHMuIE1ha2VmaWxlcyBhcmUgYSB2ZXJzYXRpbGUgdG9vbCwgYW5kIHRoZXJlJ3MgYWx3YXlzIG1vcmUgdG8gbGVhcm4uDQoNCiMjIyBDb25jbHVzaW9uDQoNCkFkdmFuY2VkIHRlY2huaXF1ZXMgYW5kIGJlc3QgcHJhY3RpY2VzIGluIE1ha2VmaWxlcyBjYW4gc2lnbmlmaWNhbnRseSBlbmhhbmNlIHRoZSBlZmZpY2llbmN5LCByZWxpYWJpbGl0eSwgYW5kIG1haW50YWluYWJpbGl0eSBvZiB5b3VyIGJ1aWxkIHN5c3RlbXMuIEJ5IGFwcGx5aW5nIHRoZXNlIHByYWN0aWNlcywgeW91IGNhbiBjcmVhdGUgcm9idXN0IGFuZCBhZGFwdGFibGUgTWFrZWZpbGVzIHRoYXQgc3RyZWFtbGluZSB0aGUgZGV2ZWxvcG1lbnQgYW5kIGRlcGxveW1lbnQgb2YgeW91ciBzb2Z0d2FyZSBwcm9qZWN0cy4gQ29udGludW91c2x5IGltcHJvdmluZyB5b3VyIE1ha2VmaWxlIHNraWxscyBpcyBhIHZhbHVhYmxlIGFzc2V0IGluIHNvZnR3YXJlIGRldmVsb3BtZW50Lg0KDQojIyBTdW1tYXJ5DQoNCkluIHRoaXMgdHV0b3JpYWwgb24gKm1ha2UqIGZvciBwcm9ncmFtbWVycywgd2UgY292ZXJlZCBhIHdpZGUgcmFuZ2Ugb2YgdG9waWNzIHRvIGhlbHAgeW91IHVuZGVyc3RhbmQgYW5kIGVmZmVjdGl2ZWx5IHVzZSBNYWtlZmlsZXMgaW4geW91ciBzb2Z0d2FyZSBkZXZlbG9wbWVudCBwcm9qZWN0cy4gSGVyZSdzIGEgc3VtbWFyeSBvZiB0aGUga2V5IHBvaW50cyBjb3ZlcmVkIGluIHRoZSBzZWN0aW9uczoNCg0KMi4gICoqQmFzaWMgTWFrZWZpbGUgU3RydWN0dXJlKio6IFRoZSBmdW5kYW1lbnRhbCBzdHJ1Y3R1cmUgb2YgYSBNYWtlZmlsZSwgaW5jbHVkaW5nIHJ1bGVzLCB0YXJnZXRzLCBhbmQgY29tbWFuZHMuDQoNCjMuICAqKlRhcmdldCBSdWxlcyBhbmQgRGVwZW5kZW5jaWVzKio6IEhvdyB0byBkZWZpbmUgdGFyZ2V0cyBhbmQgdGhlaXIgZGVwZW5kZW5jaWVzLCBlbnN1cmluZyB0aGF0IE1ha2Uga25vd3Mgd2hlbiB0byByZWJ1aWxkIGEgdGFyZ2V0Lg0KDQo0LiAgKipJbXBsaWNpdCBSdWxlcyBhbmQgVmFyaWFibGVzKio6IEltcGxpY2l0IHJ1bGVzIHRoYXQgTWFrZSB1c2VzIGJ5IGRlZmF1bHQgYW5kIGhvdyB0byBvdmVycmlkZSB0aGVtIHVzaW5nIHZhcmlhYmxlcy4NCg0KNS4gICoqVXNlci1EZWZpbmVkIFZhcmlhYmxlcyoqOiBIb3cgdG8gZGVmaW5lIHlvdXIgb3duIHZhcmlhYmxlcyBpbiBNYWtlZmlsZXMgdG8gbWFrZSB0aGVtIG1vcmUgZmxleGlibGUgYW5kIG1haW50YWluYWJsZS4NCg0KNi4gICoqUGhvbnkgVGFyZ2V0cyoqOiBUaGUgY29uY2VwdCBvZiBwaG9ueSB0YXJnZXRzIGZvciBkZWZpbmluZyBhY3Rpb25zIG9yIHRhc2tzIHRoYXQgZG9uJ3QgcHJvZHVjZSBmaWxlcywgYW5kIHRoZWlyIHByYWN0aWNhbCB1c2FnZS4NCg0KNy4gICoqRGVwZW5kZW5jeSBNYW5hZ2VtZW50Kio6IEhvdyBNYWtlIG1hbmFnZXMgZGVwZW5kZW5jaWVzIGFuZCBhdXRvbWF0aWNhbGx5IHJlYnVpbGRzIHRhcmdldHMgd2hlbiBkZXBlbmRlbmNpZXMgY2hhbmdlLg0KDQo4LiAgKipDb25kaXRpb25hbCBTdGF0ZW1lbnRzKio6IFVzaW5nIGNvbmRpdGlvbmFsIHN0YXRlbWVudHMgdG8gY3JlYXRlIHJ1bGVzIGFuZCB0YXJnZXRzIHRoYXQgYWRhcHQgdG8gZGlmZmVyZW50IGNvbmRpdGlvbnMgb3IgY29uZmlndXJhdGlvbnMuDQoNCjkuICAqKlBhdHRlcm4gUnVsZXMgYW5kIEF1dG9tYXRpYyBQcmVyZXF1aXNpdGVzKio6IEhvdyB0byB1c2UgcGF0dGVybiBydWxlcyB0byBidWlsZCB0YXJnZXRzIHdpdGggc2ltaWxhciBwYXR0ZXJucyBhbmQgYXV0b21hdGljYWxseSBnZW5lcmF0ZSBkZXBlbmRlbmN5IGluZm9ybWF0aW9uLg0KDQoxMC4gKipNYW5hZ2luZyBMaWJyYXJpZXMgYW5kIExpbmtpbmcqKjogSW5jbHVkaW5nIGxpYnJhcmllcyBpbiB5b3VyIE1ha2VmaWxlLCBzcGVjaWZ5aW5nIGxpYnJhcnkgZGlyZWN0b3JpZXMsIGFuZCBoYW5kbGluZyBhZHZhbmNlZCBsaW5raW5nLg0KDQoxMS4gKipDbGVhbmluZyBhbmQgTWFpbnRlbmFuY2UqKjogQ3JlYXRpbmcgY2xlYW5pbmcgYW5kIG1haW50ZW5hbmNlIHRhcmdldHMsIGhhbmRsaW5nIHByb2plY3QgbWFpbnRlbmFuY2UsIGFuZCBhdXRvbWF0aW5nIGRlcGVuZGVuY3kgY2xlYW51cC4NCg0KMTIuICoqQWR2YW5jZWQgVGVjaG5pcXVlcyBhbmQgQmVzdCBQcmFjdGljZXMqKjogQWR2YW5jZWQgdGVjaG5pcXVlcyBhbmQgYmVzdCBwcmFjdGljZXMgZm9yIG1vcmUgZWZmaWNpZW50IGFuZCBtYWludGFpbmFibGUgTWFrZWZpbGVzLCBpbmNsdWRpbmcgdXNpbmcgdmFyaWFibGVzLCBwaG9ueSB0YXJnZXRzLCB3aWxkY2FyZHMsIGFuZCB2ZXJzaW9uIGNvbnRyb2wgaW50ZWdyYXRpb24uDQoNCkJ5IHVuZGVyc3RhbmRpbmcgYW5kIGFwcGx5aW5nIHRoZSBjb25jZXB0cyBhbmQgdGVjaG5pcXVlcyBkaXNjdXNzZWQgaW4gdGhpcyB0dXRvcmlhbCwgeW91IGNhbiBjcmVhdGUgcm9idXN0IGFuZCBlZmZpY2llbnQgTWFrZWZpbGVzIHRvIGF1dG9tYXRlIHlvdXIgYnVpbGQgcHJvY2Vzc2VzLCBtYW5hZ2UgZGVwZW5kZW5jaWVzLCBhbmQgbWFpbnRhaW4geW91ciBzb2Z0d2FyZSBwcm9qZWN0cyBlZmZlY3RpdmVseS4gTWFrZWZpbGVzIGFyZSBhIHZhbHVhYmxlIHRvb2wgaW4gdGhlIGFyc2VuYWwgb2YgYW55IGRldmVsb3BlciwgaGVscGluZyB0byBzdHJlYW1saW5lIHRoZSBkZXZlbG9wbWVudCB3b3JrZmxvdyBhbmQgZW5zdXJlIGNvbnNpc3RlbnQsIHJlbGlhYmxlIGJ1aWxkcy4NCg0KIyMjIFR1dG9yaWFsDQoNCk5vbmUgeWV0Lg0KDQojIyBGaWxlcyAmIFJlc291cmNlcw0KDQpgYGB7ciB6aXBGaWxlcywgZWNobz1GQUxTRX0NCnppcE5hbWUgPSBzcHJpbnRmKCJMZXNzb25GaWxlcy0lcy0lcy56aXAiLCANCiAgICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LA0KICAgICAgICAgICAgICAgICBwYXJhbXMkbnVtYmVyKQ0KDQp0ZXh0QUxpbmsgPSBwYXN0ZTAoIkFsbCBGaWxlcyBmb3IgTGVzc29uICIsIA0KICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LCIuIixwYXJhbXMkbnVtYmVyKQ0KDQojIGRvd25sb2FkRmlsZXNMaW5rKCkgaXMgaW5jbHVkZWQgZnJvbSBfaW5zZXJ0MkRCLlINCmtuaXRyOjpyYXdfaHRtbChkb3dubG9hZEZpbGVzTGluaygiLiIsIHppcE5hbWUsIHRleHRBTGluaykpDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIFJlZmVyZW5jZXMNCg0KW0xlYXJuIE1ha2VmaWxlc10oaHR0cHM6Ly9tYWtlZmlsZXR1dG9yaWFsLmNvbS8pDQoNCiMjIEVycmF0YQ0KDQpbTGV0IHVzIGtub3ddKGh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS8yMTIxODcwNzI3ODQxNTcpe3RhcmdldD0iX2JsYW5rIn0uDQoNCg==
Comments and Documentation
Adding comments to your Makefile helps document its structure and purpose. It’s also a good practice to include a section at the beginning of your Makefile that explains its usage, dependencies, and any special instructions for building the project.