Learning Outcomes

By the end of this lesson, you should be able to:

  • Understand and use basic set theory notation and terminology.
  • Perform common set operations and understand their properties.
  • Apply set theory concepts to solve mathematical and real-world problems.
  • Appreciate the role of functions and relations in set theory.
  • Be able to explain the concept of cardinality and its implications in mathematics.

Introduction

This lesson introduces sets in the context of discrete mathematics. It is an introduction only. We will start by defining what a set is. “Discrete Mathematics” is a branch of mathematics that deals with discrete elements, meaning it involves structures that are countable or otherwise distinctly separable. This is in contrast to continuous mathematics, which deals with objects that can vary smoothly and have no gaps or interruptions.

Learning about sets and set theory (i.e., set mathematics) is important for several reasons, particularly in the fields of discrete mathematics, computer science, relational theory, and a number of other disciplines. Here are some key reasons why sets and set theory are useful to learn:

  1. Foundation of Modern Mathematics: Set theory provides the foundational language and framework for nearly all areas of modern mathematics. It offers a unifying structure for understanding and exploring mathematical concepts, allowing various branches of mathematics to be expressed in a common language.

  2. Critical in Computer Science: In computer science, set theory is fundamental for understanding data structures, relational databases, relational algebra and calculus, algorithms, and network theory. It helps in modeling complex relationships and structures, which are essential for algorithm design, problem-solving, reasoning, and programming.

  3. Logical Reasoning and Proof: Sets are essential for developing skills in logical reasoning and mathematical proof. Understanding set operations, relations, and functions is crucial in formulating and proving mathematical arguments rigorously.

  4. Understanding Functions and Relations: Since functions and relations are defined in terms of sets, a strong grasp of set theory is essential for understanding these key mathematical concepts. This understanding is critical in advanced mathematics, including calculus and abstract algebra.

  5. Applications in Various Fields: Set theory is not limited to mathematics and computer science; it finds applications in fields like economics, statistics, linguistics, and philosophy. It helps in structuring and analyzing complex systems and theories in these disciplines.

  6. Problem Solving and Analysis: Learning about sets enhances problem-solving and analytical skills. It provides tools for abstract thinking and simplifying complex problems by breaking them down into manageable sets of elements.

  7. Foundation for Further Mathematical Study: For students and researchers, a thorough understanding of set theory is often a prerequisite for studying more advanced topics in mathematics and related fields.

  8. Real-world Modeling: Sets are used to model real-world situations and problems, such as grouping different objects, organizing data, and understanding relationships between different entities.

  9. Abstract Thinking and Generalization: Set theory encourages abstract thinking and generalization, which are important skills in scientific inquiry and research.

  10. Basis for Further Theoretical Developments: In mathematics, set theory has been the basis for further theoretical developments, including topology, measure theory, and more abstract fields like category theory.

In short, sets and set mathematics form the foundation of modern mathematics and computer science, providing essential tools and frameworks for understanding, modeling, and solving a wide range of theoretical and practical problems. Besides their practical value, their study also cultivates abstract thinking, logical reasoning, and a deeper understanding of the structures underlying various scientific and mathematical disciplines.

Key Concepts

Set

Sets are one of the most fundamental concepts in mathematics.

A set is a collection of distinct objects, considered as an object in its own right.

The objects in a set are called the elements, or members, of the set. Sets do not allow duplicates;although in some areas of computer science, we prefer the concept of a multiset or a bag which does allow duplicates.

A set can be defined by simply listing its members inside curly braces, although there are other ways to define sets, as we will see soon. For example, the set of natural numbers less than 4 can be written as {1, 2, 3}.

Sets can contain other sets making them a recursive structure. For example, a set containing sets is {{23,7},{12,14},{1,4},{30,8,67},{2}}.

The Cardinality of a set refers to the number of elements in a set. For example, the cardinality of the set {1, 2, 3} is 3.

Set Operations

  1. Subsets: A set A is a subset of a set B if all elements of A are also elements of B. For instance, {1, 2} is a subset of {1, 2, 3}.

  2. Union: The union of two sets A and B, written as A ∪ B, is the set of elements which are in A, in B, or in both A and B. For example, if A = {1, 2} and B = {2, 3}, then A ∪ B = {1, 2, 3}.

  3. Intersection: The intersection of two sets A and B, written as A ∩ B, is the set of all objects that are members of both A and B. For example, if A = {1, 2} and B = {2, 3}, then A ∩ B = {2}.

  4. Difference: The difference of two sets A and B, written as A - B, is the set of elements that are in A but not in B. For example, if A = {1, 2, 3} and B = {2, 3, 4}, then A - B = {1}.

  5. Complement: The complement of a set A refers to elements not in A. If we’re considering sets within a universal set U, the complement of A is the set of elements in U that are not in A.

Types of Sets and Subsets

Empty Set

This is a set with no elements, denoted by ∅ or {}.

Power Set

The “power set” of a given set is a fundamental concept in set theory. It refers to the set of all possible subsets of that set, including both the empty set and the set itself. The power set is denoted as \(\mathcal{P}(S)\) for a set \(S\).

Key Characteristics of the Power Set:

  1. Inclusion of All Subsets: The power set of \(S\) contains every subset of \(S\), including the subsets that have fewer elements than \(S\), as well as the empty set (∅) and \(S\) itself.

  2. Cardinality: If a set \(S\) has \(n\) elements, then the power set of \(S\) will have \(2^n\) elements. This is because each element of \(S\) can either be included or not included in each subset, leading to \(2^n\) combinations.

  3. Higher Order Set: The power set is a set of sets. Each of its elements is a set itself.

Example:

Consider a set \(A = \{1, 2\}\). The power set of \(A\) would include all the subsets of \(A\), which are:

  • The empty set: \(\{\}\) or \(\emptyset\)
  • The set containing only 1: \(\{1\}\)
  • The set containing only 2: \(\{2\}\)
  • The set containing both 1 and 2: \(\{1, 2\}\)

So, the power set of \(A\), denoted as \(\mathcal{P}(A)\), is \(\{ \emptyset, \{1\}, \{2\}, \{1, 2\} \}\).

Notation:

  • The power set is denoted by \(\mathcal{P}(S)\), where \(S\) is the original set.
  • Some texts may also use the notation \(2^S\) to denote the power set.

Importance in Mathematics:

  • Theory: The concept of the power set is important in various areas of mathematics, including combinatorics, algebra, and topology.
  • Applications: In computer science, the power set concept is used in algorithms, data structures, and database theory. It helps to understand computational complexity and algorithmic solutions that involve all possible combinations of a given set of elements.
  • Logical and Theoretical Foundations: Power sets are also crucial in the foundations of mathematics, particularly in set theory and logic.

Understanding power sets is vital for grasping the nature of set operations and the relationships between sets. It provides a more profound insight into the structure and properties of sets, which is essential in advanced mathematical studies and various applications in computer science.

Proper Subset

A “proper subset” is a concept in set theory that describes a specific relationship between two sets. Given two sets, A and B, we say that A is a proper subset of B if every element of A is also in B, and there is at least one element in B that is not in A, i.e.,

\(A \subset B \iff \exists x | x \in B \land x \notin A\).

This relationship is denoted by A ⊂ B. The above says that A is a proper subset of B if and only if there exists at least on element x in B that is not an element in A.

Key Characteristics of a Proper Subset:

  1. Inclusion of All Elements: For A to be a proper subset of B, every element in A must also be a member of B. This is similar to the condition for a subset.

  2. At Least One Exclusive Element in the Superset: The set B must contain at least one element that is not in A. This is what differentiates a proper subset from a subset.

  3. A is not Equal to B: If A were equal to B, then A would be a subset but not a proper subset of B. For A to be a proper subset, there must be an element in B that is not in A.

Examples:

  1. Consider two sets A = {1, 2} and B = {1, 2, 3}. Here, A is a proper subset of B because every element of A is in B, and B has an additional element, 3, that is not in A.

  2. If A = {1, 2, 3} and B = {1, 2, 3}, then A is not a proper subset of B. A is a subset of B, but since there are no extra elements in B that are not in A, it’s not a proper subset.

Notation:

The notation A ⊂ B is used to indicate that A is a proper subset of B. It’s important to note that some texts use this symbol to mean subset (including the possibility of A being equal to B), but the most common use is to denote a proper subset.

Comparison with Subset:

The term “subset” includes the possibility that the two sets are equal (i.e., A can be equal to B). In contrast, “proper subset” explicitly excludes the possibility of the sets being equal. So, every proper subset is a subset, but not every subset is a proper subset.

Understanding the concept of proper subsets is important for analyzing set relations and is a fundamental part of set theory, with applications in various areas of mathematics, logic, and computer science.

Finite vs Infinite Sets

The difference between finite and infinite sets is a fundamental concept in set theory, distinguishing between sets based on the number of elements they contain.

Finite Sets

A set is considered finite if it contains a countable number of elements, and it’s possible to list all elements in the set. The key characteristic of a finite set is that there is a specific, finite number of elements in the set.

  • Example: The set of all fingers on a human hand, \(\{ thumb, index, middle, ring, little \}\), is a finite set because we can count and list each element, and there are exactly five elements in this set.

Infinite Sets

An infinite set, on the other hand, is a set that has an unlimited, or infinite, number of elements. It’s not possible to list all the elements of an infinite set, as there is no “last” element.

  • Example: The set of all natural numbers \(\mathbb{N} = \{1, 2, 3, 4, 5, \ldots\}\) is an infinite set. No matter how high you count, there is always another number that follows, making the set endless.

Key Differences

  1. Number of Elements:
    • Finite sets have a specific number of elements (which can be zero in the case of the empty set).
    • Infinite sets do not have a specific number of elements, and their size is not countable in a practical sense.
  2. Listability:
    • In a finite set, it is possible to list all the elements.
    • In an infinite set, you cannot list all elements, as they continue indefinitely.
  3. End Element:
    • Finite sets have a definite, last element when listed.
    • Infinite sets do not have an end element.
  4. Cardinality:
    • The cardinality (or size) of a finite set is a non-negative integer.
    • Infinite sets have a cardinality that is not representable by a standard integer. In mathematics, different sizes of infinity, such as countable and uncountable infinity, are studied.
  5. Examples in Mathematics:
    • Common examples of finite sets include the set of students in a classroom, the set of letters in a word, etc.
    • Examples of infinite sets include the set of natural numbers, the set of real numbers, and the set of points on a line.

Understanding the distinction between finite and infinite sets is crucial in many areas of mathematics and computer science, especially in the study of algorithms, number theory, and combinatorics. Infinite sets introduce the concept of infinity, which is a fundamental and intriguing aspect of higher mathematics.

Set Definition Methods

Sets can be defined in several ways, each catering to different contexts and requirements in mathematics. Here are some common methods of defining sets:

  1. Roster or Tabular Form: In this method, all the members (elements) of the set are listed, usually enclosed in curly braces. The order of elements does not matter, and each element is listed only once. For example, the set of vowels in the English alphabet can be defined as \(A = \{ a, e, i, o, u \}\).

  2. Set Builder Notation: This is a more concise way of defining sets, especially useful when the set is too large to list all elements or when the set is defined by a property shared by its members. It typically involves a variable, a condition, and curly braces. For example, the set of all positive even numbers can be defined as \(B = \{ x \mid x \text{ is a positive even number} \}\), where \(x\) is an element of the set, and the condition is that \(x\) must be a positive even number.

  3. Intervals: This method is used for sets of numbers and is especially useful for continuous sets. Intervals can be closed (including the endpoints) or open (excluding the endpoints). For example, the set of all real numbers between 1 and 3 can be defined as \((1, 3)\) for an open interval, or \([1, 3]\) for a closed interval.

  4. Description or Rule Method: Here, a set is defined by a clear description or a rule. This method is used when listing elements or using set-builder notation is not efficient. For example, the set of all planets in the solar system can be defined as “the set of all celestial bodies orbiting the sun that are recognized as planets by the International Astronomical Union.”

  5. Using Venn Diagrams: While this is more of a visual representation than a definition per se, Venn diagrams are often used to depict sets, especially to show relationships among different sets like intersections, unions, and differences.

  6. Predicate Notation: In more advanced contexts, sets can be defined using predicates, which are logical statements that return true or false. For example, \(C = \{ x \in \mathbb{Z}^{+} \mid P(x) \}\), where \(\mathbb{Z}^{+}\) is the set of positive integers, and \(P(x)\) is a predicate or property that elements of the set must satisfy.

  7. Recursive Definition: Some sets, particularly in computer science, are defined recursively. This means that the definition of the set refers back to itself. This is common in defining sequences, trees, and other structures in theoretical computer science.

Each of these methods has its own place and utility depending on the nature of the elements of the set and the context in which the set is being used.

Predicates

In the context of set theory and discrete mathematics, a predicate is a logical expression that describes a property or condition and can be evaluated as true or false for each element in a set. Essentially, predicates are functions that return a Boolean value (true or false) and are used to test whether a given condition holds for elements of a set.

Here are some key points about predicates in this context:

  1. Formulation: A predicate is often formulated as a statement or formula involving variables. For example, the predicate \(P(x)\) might represent the statement “x is an even number.” When we substitute a specific value for \(x\), the predicate becomes a statement that can be judged as true or false.

  2. Usage in Set Builder Notation: Predicates are commonly used in set builder notation to define sets. For example, the set of all even integers greater than 10 can be defined as \(\{ x \in \mathbb{Z} \mid x > 10 \text{ and } P(x) \}\), where \(P(x)\) is the predicate “x is an even number,” and \(\mathbb{Z}\) represents the set of all integers.

  3. Role in Logic and Mathematics: Predicates play a crucial role in mathematical logic and form the basis of predicate logic. They are used to express more complex logical formulations, such as implications, equivalences, and quantified statements.

  4. Quantifiers: In conjunction with predicates, quantifiers like “for all” (denoted by \(\forall\)) and “there exists” (denoted by \(\exists\)) are used. For example, \(\forall x \in \mathbb{N}, P(x)\) means “for all natural numbers \(x\), \(P(x)\) is true,” whereas \(\exists x \in \mathbb{N}\) such that \(P(x)\) means “there exists at least one natural number \(x\) for which \(P(x)\) is true.”

  5. Application in Proofs: In mathematical proofs, especially in discrete mathematics, predicates are often used to formalize statements that need to be proved or disproved. They help in structuring arguments logically and precisely.

In short, predicates are fundamental in set theory and discrete mathematics, providing a way to express properties and conditions for set elements, formulating logical statements, and facilitating rigorous mathematical reasoning and proofs.

Special Sets in Mathematics

Natural Numbers

The set of natural numbers, denoted by the symbol \(\mathbb{N}\) is the set of positive integers starting from 1 and continuing indefinitely in an increasing manner. Can alternatively be defined as \(\mathbb{N} = \{1,2,3,4, \ldots\}\).

Natural numbers are the basic counting numbers used in everyday life and are a fundamental part of mathematics. They are the set of positive integers starting from 1 and continuing indefinitely in an increasing manner. The set of natural numbers is usually denoted by the symbol \(\mathbb{N}\).

Key Characteristics of Natural Numbers:

  1. Starting Point: Natural numbers start from 1 (1, 2, 3, 4, 5, …). Some mathematical definitions include 0 in the set of natural numbers, but traditionally it starts from 1.

  2. Positive Integers: They are all positive and do not include negative numbers, fractions, or decimals.

  3. Counting: Natural numbers are used for counting objects. For instance, when you count the number of books on a shelf, you use natural numbers.

  4. Infinity: The set of natural numbers is infinite; it has no upper limit.

  5. Discreteness: Natural numbers are discrete, meaning there are no fractions or decimals between them.

  6. Fundamental in Mathematics: They form the basis for more complex number systems, including integers, rational numbers, and real numbers.

In mathematical notation, the set of natural numbers is often represented as follows:

\[ \mathbb{N} = \{1, 2, 3, 4, 5, \ldots\} \]

Natural numbers are foundational in various branches of mathematics, including arithmetic, number theory, and are widely used in everyday life for counting and ordering objects.

Integers

The set of integers, denoted by (**\(\mathbb{Z}\)), including positive, negative, and zero. The symbol comes from the German word for numbers: Zahlen.

Rational Numbers

Rational numbers are numbers that can be expressed as the quotient or fraction \(\frac{p}{q}\) of two integers, where the numerator \(p\) is an integer and the denominator \(q\) is a non-zero integer. Essentially, a rational number represents a ratio between two integers.

Key Characteristics of Rational Numbers:

  1. Fractional Form: They can always be expressed as fractions.

  2. Include Integers: All integers are rational numbers since any integer \(z\) can be expressed as \(\frac{z}{1}\).

  3. Decimal Representation: Rational numbers can be represented as either terminating decimals or repeating decimals.

  4. Density: Between any two rational numbers, there’s another rational number. This property is known as the density of rational numbers.

  5. Negative Numbers: The set of rational numbers includes both positive and negative numbers, as well as zero.

Symbol for Rational Numbers:

The set of rational numbers is denoted by the symbol \(\mathbb{Q}\). The letter “Q” stands for “quotient,” reflecting the fact that any rational number represents the quotient of two integers.

Examples:

  • \(\frac{1}{2}\), \(\frac{5}{3}\), and \(-\frac{4}{7}\) are rational numbers.
  • All integers are rational numbers, for example, 7 (which is the same as \(\frac{7}{1}\)).
  • Numbers like 0.75 (which is \(\frac{3}{4}\)) and 0.333… (which is \(\frac{1}{3}\)) are also rational.

In mathematical notation, the set of rational numbers can be represented as:

\[ \mathbb{Q} = \left\{ \frac{p}{q} \mid p, q \in \mathbb{Z}, q \neq 0 \right\} \]

Where \(\mathbb{Z}\) denotes the set of all integers. Rational numbers play a crucial role in mathematics, bridging the gap between integers and the more comprehensive set of real numbers.

Irrational Numbers

Irrational numbers are a type of real number that cannot be expressed as a simple fraction - that is, the ratio of two integers. The defining characteristic of an irrational number is that its decimal representation is non-terminating and non-repeating. This means it goes on forever without repeating a pattern.

Key Characteristics of Irrational Numbers:

  1. Non-representable as Fractions: Unlike rational numbers, you cannot express irrational numbers as a fraction of two integers.

  2. Non-terminating, Non-repeating Decimals: In decimal form, these numbers never end and do not display a repeating pattern of digits.

  3. Cannot be Exactly Calculated: The exact value of an irrational number cannot be precisely calculated or written down in decimal form.

  4. Examples: Famous examples include:

    • Pi (π), the ratio of the circumference of a circle to its diameter.
    • Euler’s number (e), the base of natural logarithms.
    • The square root of a non-perfect square number (like √2, √3, etc.).
  5. Real Numbers: All irrational numbers are real numbers but they are not rational numbers.

Symbol for Irrational Numbers:

There is no standard symbol universally used to denote the set of all irrational numbers. However, sometimes the set is represented as the set difference of the real numbers and the rational numbers, which can be notated as \(\mathbb{R} \setminus \mathbb{Q}\). This notation reflects that irrational numbers include all real numbers that are not rational.

Inclusion in the Number System:

Irrational numbers, along with rational numbers, make up the real numbers, \(\mathbb{R}\). The discovery of irrational numbers was significant in mathematics as it expanded the understanding of numerical concepts beyond the simple ratios of integers.

Significance:

Irrational numbers are essential in various areas of mathematics and applied sciences. They often appear in formulas, geometric measurements, and calculations where exact precision is required beyond the limitation of rational numbers. They are fundamental in understanding the continuum of real numbers and play a crucial role in advanced mathematics, including calculus and mathematical analysis.

Real Numbers

Real numbers are the set of numbers that include both the rational numbers (such as integers and fractions) and the irrational numbers (such as \(\sqrt{2}\), \(\pi\), and \(e\)). They form a continuum of numbers that can represent any quantity along a continuous line, known as the number line.

Key Characteristics of Real Numbers:

  1. Inclusivity: The set of real numbers includes:

    • All rational numbers, which can be expressed as fractions or decimals that either terminate or repeat.
    • All irrational numbers, which cannot be expressed as fractions and have non-terminating, non-repeating decimal representations.
  2. Representation on the Number Line: Every point on the number line corresponds to a unique real number. This includes both positive and negative numbers, as well as zero.

  3. Complete and Continuous: The real numbers are complete, meaning they contain all the limit points, and are continuous, with no gaps between the numbers.

  4. Decimal Expansion: Every real number can be expressed as an infinite decimal expansion.

  5. Arithmetic Operations: The set of real numbers is closed under addition, subtraction, multiplication, and division (except division by zero).

Symbol for Real Numbers:

The set of real numbers is denoted by the symbol \(\mathbb{R}\).

Examples:

  • Rational numbers like \(-3\), \(\frac{1}{2}\), and \(4.75\) are real numbers.
  • Irrational numbers like \(\sqrt{2}\), \(\pi\), and \(e\) are also real numbers.
  • All integers and natural numbers are included in the set of real numbers.

Importance:

Real numbers are fundamental in mathematics and are used to measure continuous quantities such as distance, time, and temperature. They form the basis of calculus and analysis and are essential for describing the physical world in sciences and engineering. The concept of real numbers allows for precise and comprehensive descriptions of quantities in a wide range of mathematical, physical, and practical applications.

Tutorial

None yet.

Practice Questions

Question 1

What are the cardinalities of the following sets:

  1. {A,F,G,X}
  2. {‘Goldwasser’,‘Knuth’,‘Codd’}
  3. \(\{ x \in \mathbb{Z}^{+} \mid (x \% 2 = 0) \}\) where % is the modulus operator
  4. {{33,2},{334,{p,q,r}}}
  5. {}

Question 2

Define the set of all real positive numbers.

Question 3

Define a set that includes four digit whole numbers that are greater than 0.


Files & Resources

All Files for Lesson 101.110

References

None yet.

Errata

Let us know.

LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIHRoZSBNYXRoZW1hdGljcyBvZiBTZXRzIgpwYXJhbXM6CiAgdHlwZTogbGVzc29uCiAgY2F0ZWdvcnk6IDEwMQogIG51bWJlcjogMTEwCiAgdGltZTogIjkwIG1pbiIKICBsZXZlbDogYmVnaW5uZXIKICB0YWdzOiBzZXRzLHVuaW9uLHNldCBvcGVyYXRpb25zCiAgZGVzY3JpcHRpb246ICJJbnRyb2R1Y2VzIHRoZSBtYXRoZW1hdGljcyBvZiBzZXRzLgogICAgICAgICAgICAgICAgIgpkYXRlOiAiPHNtYWxsPmByIFN5cy5EYXRlKClgPC9zbWFsbD4iCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiIKZW1haWw6ICJtLnNjaGVkbGJhdWVyQG5ldS5lZHUiCmFmZmlsaXRhdGlvbjogIk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogYm9vdHN0cmFwCiAgICBoaWdobGlnaHQ6IHRhbmdvCi0tLQoKLS0tCnRpdGxlOiAiPHNtYWxsPmByIHBhcmFtcyRjYXRlZ29yeWAuYHIgcGFyYW1zJG51bWJlcmA8L3NtYWxsPjxici8+PHNwYW4gc3R5bGU9J2NvbG9yOiAjMkU0MDUzOyBmb250LXNpemU6IDAuOWVtJz5gciBybWFya2Rvd246Om1ldGFkYXRhJHRpdGxlYDwvc3Bhbj4iCi0tLQoKYGBge3IgY29kZT14ZnVuOjpyZWFkX3V0ZjgocGFzdGUwKGhlcmU6OmhlcmUoKSwnL1IvX2luc2VydDJEQi5SJykpLCBpbmNsdWRlID0gRkFMU0V9CmBgYAoKIyMgTGVhcm5pbmcgT3V0Y29tZXMKCkJ5IHRoZSBlbmQgb2YgdGhpcyBsZXNzb24sIHlvdSBzaG91bGQgYmUgYWJsZSB0bzoKCi0gICBVbmRlcnN0YW5kIGFuZCB1c2UgYmFzaWMgc2V0IHRoZW9yeSBub3RhdGlvbiBhbmQgdGVybWlub2xvZ3kuCi0gICBQZXJmb3JtIGNvbW1vbiBzZXQgb3BlcmF0aW9ucyBhbmQgdW5kZXJzdGFuZCB0aGVpciBwcm9wZXJ0aWVzLgotICAgQXBwbHkgc2V0IHRoZW9yeSBjb25jZXB0cyB0byBzb2x2ZSBtYXRoZW1hdGljYWwgYW5kIHJlYWwtd29ybGQgcHJvYmxlbXMuCi0gICBBcHByZWNpYXRlIHRoZSByb2xlIG9mIGZ1bmN0aW9ucyBhbmQgcmVsYXRpb25zIGluIHNldCB0aGVvcnkuCi0gICBCZSBhYmxlIHRvIGV4cGxhaW4gdGhlIGNvbmNlcHQgb2YgY2FyZGluYWxpdHkgYW5kIGl0cyBpbXBsaWNhdGlvbnMgaW4gbWF0aGVtYXRpY3MuCgojIyBJbnRyb2R1Y3Rpb24KClRoaXMgbGVzc29uIGludHJvZHVjZXMgc2V0cyBpbiB0aGUgY29udGV4dCBvZiBkaXNjcmV0ZSBtYXRoZW1hdGljcy4gSXQgaXMgYW4gaW50cm9kdWN0aW9uIG9ubHkuIFdlIHdpbGwgc3RhcnQgYnkgZGVmaW5pbmcgd2hhdCBhIHNldCBpcy4gIkRpc2NyZXRlIE1hdGhlbWF0aWNzIiBpcyBhIGJyYW5jaCBvZiBtYXRoZW1hdGljcyB0aGF0IGRlYWxzIHdpdGggZGlzY3JldGUgZWxlbWVudHMsIG1lYW5pbmcgaXQgaW52b2x2ZXMgc3RydWN0dXJlcyB0aGF0IGFyZSBjb3VudGFibGUgb3Igb3RoZXJ3aXNlIGRpc3RpbmN0bHkgc2VwYXJhYmxlLiBUaGlzIGlzIGluIGNvbnRyYXN0IHRvIGNvbnRpbnVvdXMgbWF0aGVtYXRpY3MsIHdoaWNoIGRlYWxzIHdpdGggb2JqZWN0cyB0aGF0IGNhbiB2YXJ5IHNtb290aGx5IGFuZCBoYXZlIG5vIGdhcHMgb3IgaW50ZXJydXB0aW9ucy4KCkxlYXJuaW5nIGFib3V0IHNldHMgYW5kIHNldCB0aGVvcnkgKCppLmUuKiwgc2V0IG1hdGhlbWF0aWNzKSBpcyBpbXBvcnRhbnQgZm9yIHNldmVyYWwgcmVhc29ucywgcGFydGljdWxhcmx5IGluIHRoZSBmaWVsZHMgb2YgZGlzY3JldGUgbWF0aGVtYXRpY3MsIGNvbXB1dGVyIHNjaWVuY2UsIHJlbGF0aW9uYWwgdGhlb3J5LCBhbmQgYSBudW1iZXIgb2Ygb3RoZXIgZGlzY2lwbGluZXMuIEhlcmUgYXJlIHNvbWUga2V5IHJlYXNvbnMgd2h5IHNldHMgYW5kIHNldCB0aGVvcnkgYXJlIHVzZWZ1bCB0byBsZWFybjoKCjEuICAqKkZvdW5kYXRpb24gb2YgTW9kZXJuIE1hdGhlbWF0aWNzKio6IFNldCB0aGVvcnkgcHJvdmlkZXMgdGhlIGZvdW5kYXRpb25hbCBsYW5ndWFnZSBhbmQgZnJhbWV3b3JrIGZvciBuZWFybHkgYWxsIGFyZWFzIG9mIG1vZGVybiBtYXRoZW1hdGljcy4gSXQgb2ZmZXJzIGEgdW5pZnlpbmcgc3RydWN0dXJlIGZvciB1bmRlcnN0YW5kaW5nIGFuZCBleHBsb3JpbmcgbWF0aGVtYXRpY2FsIGNvbmNlcHRzLCBhbGxvd2luZyB2YXJpb3VzIGJyYW5jaGVzIG9mIG1hdGhlbWF0aWNzIHRvIGJlIGV4cHJlc3NlZCBpbiBhIGNvbW1vbiBsYW5ndWFnZS4KCjIuICAqKkNyaXRpY2FsIGluIENvbXB1dGVyIFNjaWVuY2UqKjogSW4gY29tcHV0ZXIgc2NpZW5jZSwgc2V0IHRoZW9yeSBpcyBmdW5kYW1lbnRhbCBmb3IgdW5kZXJzdGFuZGluZyBkYXRhIHN0cnVjdHVyZXMsIHJlbGF0aW9uYWwgZGF0YWJhc2VzLCByZWxhdGlvbmFsIGFsZ2VicmEgYW5kIGNhbGN1bHVzLCBhbGdvcml0aG1zLCBhbmQgbmV0d29yayB0aGVvcnkuIEl0IGhlbHBzIGluIG1vZGVsaW5nIGNvbXBsZXggcmVsYXRpb25zaGlwcyBhbmQgc3RydWN0dXJlcywgd2hpY2ggYXJlIGVzc2VudGlhbCBmb3IgYWxnb3JpdGhtIGRlc2lnbiwgcHJvYmxlbS1zb2x2aW5nLCByZWFzb25pbmcsIGFuZCBwcm9ncmFtbWluZy4KCjMuICAqKkxvZ2ljYWwgUmVhc29uaW5nIGFuZCBQcm9vZioqOiBTZXRzIGFyZSBlc3NlbnRpYWwgZm9yIGRldmVsb3Bpbmcgc2tpbGxzIGluIGxvZ2ljYWwgcmVhc29uaW5nIGFuZCBtYXRoZW1hdGljYWwgcHJvb2YuIFVuZGVyc3RhbmRpbmcgc2V0IG9wZXJhdGlvbnMsIHJlbGF0aW9ucywgYW5kIGZ1bmN0aW9ucyBpcyBjcnVjaWFsIGluIGZvcm11bGF0aW5nIGFuZCBwcm92aW5nIG1hdGhlbWF0aWNhbCBhcmd1bWVudHMgcmlnb3JvdXNseS4KCjQuICAqKlVuZGVyc3RhbmRpbmcgRnVuY3Rpb25zIGFuZCBSZWxhdGlvbnMqKjogU2luY2UgZnVuY3Rpb25zIGFuZCByZWxhdGlvbnMgYXJlIGRlZmluZWQgaW4gdGVybXMgb2Ygc2V0cywgYSBzdHJvbmcgZ3Jhc3Agb2Ygc2V0IHRoZW9yeSBpcyBlc3NlbnRpYWwgZm9yIHVuZGVyc3RhbmRpbmcgdGhlc2Uga2V5IG1hdGhlbWF0aWNhbCBjb25jZXB0cy4gVGhpcyB1bmRlcnN0YW5kaW5nIGlzIGNyaXRpY2FsIGluIGFkdmFuY2VkIG1hdGhlbWF0aWNzLCBpbmNsdWRpbmcgY2FsY3VsdXMgYW5kIGFic3RyYWN0IGFsZ2VicmEuCgo1LiAgKipBcHBsaWNhdGlvbnMgaW4gVmFyaW91cyBGaWVsZHMqKjogU2V0IHRoZW9yeSBpcyBub3QgbGltaXRlZCB0byBtYXRoZW1hdGljcyBhbmQgY29tcHV0ZXIgc2NpZW5jZTsgaXQgZmluZHMgYXBwbGljYXRpb25zIGluIGZpZWxkcyBsaWtlIGVjb25vbWljcywgc3RhdGlzdGljcywgbGluZ3Vpc3RpY3MsIGFuZCBwaGlsb3NvcGh5LiBJdCBoZWxwcyBpbiBzdHJ1Y3R1cmluZyBhbmQgYW5hbHl6aW5nIGNvbXBsZXggc3lzdGVtcyBhbmQgdGhlb3JpZXMgaW4gdGhlc2UgZGlzY2lwbGluZXMuCgo2LiAgKipQcm9ibGVtIFNvbHZpbmcgYW5kIEFuYWx5c2lzKio6IExlYXJuaW5nIGFib3V0IHNldHMgZW5oYW5jZXMgcHJvYmxlbS1zb2x2aW5nIGFuZCBhbmFseXRpY2FsIHNraWxscy4gSXQgcHJvdmlkZXMgdG9vbHMgZm9yIGFic3RyYWN0IHRoaW5raW5nIGFuZCBzaW1wbGlmeWluZyBjb21wbGV4IHByb2JsZW1zIGJ5IGJyZWFraW5nIHRoZW0gZG93biBpbnRvIG1hbmFnZWFibGUgc2V0cyBvZiBlbGVtZW50cy4KCjcuICAqKkZvdW5kYXRpb24gZm9yIEZ1cnRoZXIgTWF0aGVtYXRpY2FsIFN0dWR5Kio6IEZvciBzdHVkZW50cyBhbmQgcmVzZWFyY2hlcnMsIGEgdGhvcm91Z2ggdW5kZXJzdGFuZGluZyBvZiBzZXQgdGhlb3J5IGlzIG9mdGVuIGEgcHJlcmVxdWlzaXRlIGZvciBzdHVkeWluZyBtb3JlIGFkdmFuY2VkIHRvcGljcyBpbiBtYXRoZW1hdGljcyBhbmQgcmVsYXRlZCBmaWVsZHMuCgo4LiAgKipSZWFsLXdvcmxkIE1vZGVsaW5nKio6IFNldHMgYXJlIHVzZWQgdG8gbW9kZWwgcmVhbC13b3JsZCBzaXR1YXRpb25zIGFuZCBwcm9ibGVtcywgc3VjaCBhcyBncm91cGluZyBkaWZmZXJlbnQgb2JqZWN0cywgb3JnYW5pemluZyBkYXRhLCBhbmQgdW5kZXJzdGFuZGluZyByZWxhdGlvbnNoaXBzIGJldHdlZW4gZGlmZmVyZW50IGVudGl0aWVzLgoKOS4gICoqQWJzdHJhY3QgVGhpbmtpbmcgYW5kIEdlbmVyYWxpemF0aW9uKio6IFNldCB0aGVvcnkgZW5jb3VyYWdlcyBhYnN0cmFjdCB0aGlua2luZyBhbmQgZ2VuZXJhbGl6YXRpb24sIHdoaWNoIGFyZSBpbXBvcnRhbnQgc2tpbGxzIGluIHNjaWVudGlmaWMgaW5xdWlyeSBhbmQgcmVzZWFyY2guCgoxMC4gKipCYXNpcyBmb3IgRnVydGhlciBUaGVvcmV0aWNhbCBEZXZlbG9wbWVudHMqKjogSW4gbWF0aGVtYXRpY3MsIHNldCB0aGVvcnkgaGFzIGJlZW4gdGhlIGJhc2lzIGZvciBmdXJ0aGVyIHRoZW9yZXRpY2FsIGRldmVsb3BtZW50cywgaW5jbHVkaW5nIHRvcG9sb2d5LCBtZWFzdXJlIHRoZW9yeSwgYW5kIG1vcmUgYWJzdHJhY3QgZmllbGRzIGxpa2UgY2F0ZWdvcnkgdGhlb3J5LgoKSW4gc2hvcnQsIHNldHMgYW5kIHNldCBtYXRoZW1hdGljcyBmb3JtIHRoZSBmb3VuZGF0aW9uIG9mIG1vZGVybiBtYXRoZW1hdGljcyBhbmQgY29tcHV0ZXIgc2NpZW5jZSwgcHJvdmlkaW5nIGVzc2VudGlhbCB0b29scyBhbmQgZnJhbWV3b3JrcyBmb3IgdW5kZXJzdGFuZGluZywgbW9kZWxpbmcsIGFuZCBzb2x2aW5nIGEgd2lkZSByYW5nZSBvZiB0aGVvcmV0aWNhbCBhbmQgcHJhY3RpY2FsIHByb2JsZW1zLiBCZXNpZGVzIHRoZWlyIHByYWN0aWNhbCB2YWx1ZSwgdGhlaXIgc3R1ZHkgYWxzbyBjdWx0aXZhdGVzIGFic3RyYWN0IHRoaW5raW5nLCBsb2dpY2FsIHJlYXNvbmluZywgYW5kIGEgZGVlcGVyIHVuZGVyc3RhbmRpbmcgb2YgdGhlIHN0cnVjdHVyZXMgdW5kZXJseWluZyB2YXJpb3VzIHNjaWVudGlmaWMgYW5kIG1hdGhlbWF0aWNhbCBkaXNjaXBsaW5lcy4KCiMjIEtleSBDb25jZXB0cwoKIyMjIFNldAoKU2V0cyBhcmUgb25lIG9mIHRoZSBtb3N0IGZ1bmRhbWVudGFsIGNvbmNlcHRzIGluIG1hdGhlbWF0aWNzLgoKPiBBIHNldCBpcyBhIGNvbGxlY3Rpb24gb2YgZGlzdGluY3Qgb2JqZWN0cywgY29uc2lkZXJlZCBhcyBhbiBvYmplY3QgaW4gaXRzIG93biByaWdodC4KClRoZSBvYmplY3RzIGluIGEgc2V0IGFyZSBjYWxsZWQgdGhlIGVsZW1lbnRzLCBvciBtZW1iZXJzLCBvZiB0aGUgc2V0LiBTZXRzIGRvIG5vdCBhbGxvdyBkdXBsaWNhdGVzO2FsdGhvdWdoIGluIHNvbWUgYXJlYXMgb2YgY29tcHV0ZXIgc2NpZW5jZSwgd2UgcHJlZmVyIHRoZSBjb25jZXB0IG9mIGEgKm11bHRpc2V0KiBvciBhICpiYWcqIHdoaWNoIGRvZXMgYWxsb3cgZHVwbGljYXRlcy4KCkEgc2V0IGNhbiBiZSBkZWZpbmVkIGJ5IHNpbXBseSBsaXN0aW5nIGl0cyBtZW1iZXJzIGluc2lkZSBjdXJseSBicmFjZXMsIGFsdGhvdWdoIHRoZXJlIGFyZSBvdGhlciB3YXlzIHRvIGRlZmluZSBzZXRzLCBhcyB3ZSB3aWxsIHNlZSBzb29uLiBGb3IgZXhhbXBsZSwgdGhlIHNldCBvZiBuYXR1cmFsIG51bWJlcnMgbGVzcyB0aGFuIDQgY2FuIGJlIHdyaXR0ZW4gYXMgKnsxLCAyLCAzfSouCgpTZXRzIGNhbiBjb250YWluIG90aGVyIHNldHMgbWFraW5nIHRoZW0gYSByZWN1cnNpdmUgc3RydWN0dXJlLiBGb3IgZXhhbXBsZSwgYSBzZXQgY29udGFpbmluZyBzZXRzIGlzIHt7MjMsN30sezEyLDE0fSx7MSw0fSx7MzAsOCw2N30sezJ9fS4KClRoZSAqKkNhcmRpbmFsaXR5Kiogb2YgYSBzZXQgcmVmZXJzIHRvIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gYSBzZXQuIEZvciBleGFtcGxlLCB0aGUgY2FyZGluYWxpdHkgb2YgdGhlIHNldCAqezEsIDIsIDN9KiBpcyAzLgoKIyMjIFNldCBPcGVyYXRpb25zCgoyLiAgKipTdWJzZXRzKio6IEEgc2V0IEEgaXMgYSBzdWJzZXQgb2YgYSBzZXQgQiBpZiBhbGwgZWxlbWVudHMgb2YgQSBhcmUgYWxzbyBlbGVtZW50cyBvZiBCLiBGb3IgaW5zdGFuY2UsICp7MSwgMn0qIGlzIGEgc3Vic2V0IG9mICp7MSwgMiwgM30qLgoKMy4gICoqVW5pb24qKjogVGhlIHVuaW9uIG9mIHR3byBzZXRzIEEgYW5kIEIsIHdyaXR0ZW4gYXMgQSDiiKogQiwgaXMgdGhlIHNldCBvZiBlbGVtZW50cyB3aGljaCBhcmUgaW4gQSwgaW4gQiwgb3IgaW4gYm90aCBBIGFuZCBCLiBGb3IgZXhhbXBsZSwgaWYgKkEgPSB7MSwgMn0qIGFuZCAqQiA9IHsyLCAzfSosIHRoZW4gKkEg4oiqIEIgPSB7MSwgMiwgM30qLgoKNC4gICoqSW50ZXJzZWN0aW9uKio6IFRoZSBpbnRlcnNlY3Rpb24gb2YgdHdvIHNldHMgKkEqIGFuZCAqQiosIHdyaXR0ZW4gYXMgKkEg4oipIEIqLCBpcyB0aGUgc2V0IG9mIGFsbCBvYmplY3RzIHRoYXQgYXJlIG1lbWJlcnMgb2YgYm90aCAqQSogYW5kICpCKi4gRm9yIGV4YW1wbGUsIGlmICpBID0gezEsIDJ9KiBhbmQgKkIgPSB7MiwgM30qLCB0aGVuICpBIOKIqSBCID0gezJ9Ki4KCjUuICAqKkRpZmZlcmVuY2UqKjogVGhlIGRpZmZlcmVuY2Ugb2YgdHdvIHNldHMgQSBhbmQgQiwgd3JpdHRlbiBhcyBBIC0gQiwgaXMgdGhlIHNldCBvZiBlbGVtZW50cyB0aGF0IGFyZSBpbiBBIGJ1dCBub3QgaW4gQi4gRm9yIGV4YW1wbGUsIGlmICpBID0gezEsIDIsIDN9KiBhbmQgKkIgPSB7MiwgMywgNH0qLCB0aGVuICpBIC0gQiA9IHsxfSouCgo2LiAgKipDb21wbGVtZW50Kio6IFRoZSBjb21wbGVtZW50IG9mIGEgc2V0IEEgcmVmZXJzIHRvIGVsZW1lbnRzIG5vdCBpbiBBLiBJZiB3ZSdyZSBjb25zaWRlcmluZyBzZXRzIHdpdGhpbiBhIHVuaXZlcnNhbCBzZXQgVSwgdGhlIGNvbXBsZW1lbnQgb2YgQSBpcyB0aGUgc2V0IG9mIGVsZW1lbnRzIGluIFUgdGhhdCBhcmUgbm90IGluIEEuCgojIyBUeXBlcyBvZiBTZXRzIGFuZCBTdWJzZXRzCgojIyMgKipFbXB0eSBTZXQqKgoKVGhpcyBpcyBhIHNldCB3aXRoIG5vIGVsZW1lbnRzLCBkZW5vdGVkIGJ5IOKIhSBvciB7fS4KCiMjIyAqKlBvd2VyIFNldCoqCgpUaGUgInBvd2VyIHNldCIgb2YgYSBnaXZlbiBzZXQgaXMgYSBmdW5kYW1lbnRhbCBjb25jZXB0IGluIHNldCB0aGVvcnkuIEl0IHJlZmVycyB0byB0aGUgc2V0IG9mIGFsbCBwb3NzaWJsZSBzdWJzZXRzIG9mIHRoYXQgc2V0LCBpbmNsdWRpbmcgYm90aCB0aGUgZW1wdHkgc2V0IGFuZCB0aGUgc2V0IGl0c2VsZi4gVGhlIHBvd2VyIHNldCBpcyBkZW5vdGVkIGFzICRcbWF0aGNhbHtQfShTKSQgZm9yIGEgc2V0ICRTJC4KCiMjIyMgS2V5IENoYXJhY3RlcmlzdGljcyBvZiB0aGUgUG93ZXIgU2V0OgoKMS4gICoqSW5jbHVzaW9uIG9mIEFsbCBTdWJzZXRzKio6IFRoZSBwb3dlciBzZXQgb2YgJFMkIGNvbnRhaW5zIGV2ZXJ5IHN1YnNldCBvZiAkUyQsIGluY2x1ZGluZyB0aGUgc3Vic2V0cyB0aGF0IGhhdmUgZmV3ZXIgZWxlbWVudHMgdGhhbiAkUyQsIGFzIHdlbGwgYXMgdGhlIGVtcHR5IHNldCAo4oiFKSBhbmQgJFMkIGl0c2VsZi4KCjIuICAqKkNhcmRpbmFsaXR5Kio6IElmIGEgc2V0ICRTJCBoYXMgJG4kIGVsZW1lbnRzLCB0aGVuIHRoZSBwb3dlciBzZXQgb2YgJFMkIHdpbGwgaGF2ZSAkMl5uJCBlbGVtZW50cy4gVGhpcyBpcyBiZWNhdXNlIGVhY2ggZWxlbWVudCBvZiAkUyQgY2FuIGVpdGhlciBiZSBpbmNsdWRlZCBvciBub3QgaW5jbHVkZWQgaW4gZWFjaCBzdWJzZXQsIGxlYWRpbmcgdG8gJDJebiQgY29tYmluYXRpb25zLgoKMy4gICoqSGlnaGVyIE9yZGVyIFNldCoqOiBUaGUgcG93ZXIgc2V0IGlzIGEgc2V0IG9mIHNldHMuIEVhY2ggb2YgaXRzIGVsZW1lbnRzIGlzIGEgc2V0IGl0c2VsZi4KCiMjIyMgRXhhbXBsZToKCkNvbnNpZGVyIGEgc2V0ICRBID0gXHsxLCAyXH0kLiBUaGUgcG93ZXIgc2V0IG9mICRBJCB3b3VsZCBpbmNsdWRlIGFsbCB0aGUgc3Vic2V0cyBvZiAkQSQsIHdoaWNoIGFyZToKCi0gICBUaGUgZW1wdHkgc2V0OiAkXHtcfSQgb3IgJFxlbXB0eXNldCQKLSAgIFRoZSBzZXQgY29udGFpbmluZyBvbmx5IDE6ICRcezFcfSQKLSAgIFRoZSBzZXQgY29udGFpbmluZyBvbmx5IDI6ICRcezJcfSQKLSAgIFRoZSBzZXQgY29udGFpbmluZyBib3RoIDEgYW5kIDI6ICRcezEsIDJcfSQKClNvLCB0aGUgcG93ZXIgc2V0IG9mICRBJCwgZGVub3RlZCBhcyAkXG1hdGhjYWx7UH0oQSkkLCBpcyAkXHsgXGVtcHR5c2V0LCBcezFcfSwgXHsyXH0sIFx7MSwgMlx9IFx9JC4KCiMjIyMgTm90YXRpb246CgotICAgVGhlIHBvd2VyIHNldCBpcyBkZW5vdGVkIGJ5ICRcbWF0aGNhbHtQfShTKSQsIHdoZXJlICRTJCBpcyB0aGUgb3JpZ2luYWwgc2V0LgotICAgU29tZSB0ZXh0cyBtYXkgYWxzbyB1c2UgdGhlIG5vdGF0aW9uICQyXlMkIHRvIGRlbm90ZSB0aGUgcG93ZXIgc2V0LgoKIyMjIyBJbXBvcnRhbmNlIGluIE1hdGhlbWF0aWNzOgoKLSAgICoqVGhlb3J5Kio6IFRoZSBjb25jZXB0IG9mIHRoZSBwb3dlciBzZXQgaXMgaW1wb3J0YW50IGluIHZhcmlvdXMgYXJlYXMgb2YgbWF0aGVtYXRpY3MsIGluY2x1ZGluZyBjb21iaW5hdG9yaWNzLCBhbGdlYnJhLCBhbmQgdG9wb2xvZ3kuCi0gICAqKkFwcGxpY2F0aW9ucyoqOiBJbiBjb21wdXRlciBzY2llbmNlLCB0aGUgcG93ZXIgc2V0IGNvbmNlcHQgaXMgdXNlZCBpbiBhbGdvcml0aG1zLCBkYXRhIHN0cnVjdHVyZXMsIGFuZCBkYXRhYmFzZSB0aGVvcnkuIEl0IGhlbHBzIHRvIHVuZGVyc3RhbmQgY29tcHV0YXRpb25hbCBjb21wbGV4aXR5IGFuZCBhbGdvcml0aG1pYyBzb2x1dGlvbnMgdGhhdCBpbnZvbHZlIGFsbCBwb3NzaWJsZSBjb21iaW5hdGlvbnMgb2YgYSBnaXZlbiBzZXQgb2YgZWxlbWVudHMuCi0gICAqKkxvZ2ljYWwgYW5kIFRoZW9yZXRpY2FsIEZvdW5kYXRpb25zKio6IFBvd2VyIHNldHMgYXJlIGFsc28gY3J1Y2lhbCBpbiB0aGUgZm91bmRhdGlvbnMgb2YgbWF0aGVtYXRpY3MsIHBhcnRpY3VsYXJseSBpbiBzZXQgdGhlb3J5IGFuZCBsb2dpYy4KClVuZGVyc3RhbmRpbmcgcG93ZXIgc2V0cyBpcyB2aXRhbCBmb3IgZ3Jhc3BpbmcgdGhlIG5hdHVyZSBvZiBzZXQgb3BlcmF0aW9ucyBhbmQgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBzZXRzLiBJdCBwcm92aWRlcyBhIG1vcmUgcHJvZm91bmQgaW5zaWdodCBpbnRvIHRoZSBzdHJ1Y3R1cmUgYW5kIHByb3BlcnRpZXMgb2Ygc2V0cywgd2hpY2ggaXMgZXNzZW50aWFsIGluIGFkdmFuY2VkIG1hdGhlbWF0aWNhbCBzdHVkaWVzIGFuZCB2YXJpb3VzIGFwcGxpY2F0aW9ucyBpbiBjb21wdXRlciBzY2llbmNlLgoKIyMjICoqUHJvcGVyIFN1YnNldCoqCgpBICJwcm9wZXIgc3Vic2V0IiBpcyBhIGNvbmNlcHQgaW4gc2V0IHRoZW9yeSB0aGF0IGRlc2NyaWJlcyBhIHNwZWNpZmljIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBzZXRzLiBHaXZlbiB0d28gc2V0cywgKkEqIGFuZCAqQiosIHdlIHNheSB0aGF0ICpBKiBpcyBhIHByb3BlciBzdWJzZXQgb2YgKkIqIGlmIGV2ZXJ5IGVsZW1lbnQgb2YgKkEqIGlzIGFsc28gaW4gKkIqLCBhbmQgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGVsZW1lbnQgaW4gKkIqIHRoYXQgaXMgbm90IGluICpBKiwgKmkuZS4qLAoKJEEgXHN1YnNldCBCIFxpZmYgXGV4aXN0cyB4IHwgeCBcaW4gQiBcbGFuZCB4IFxub3RpbiBBJC4KClRoaXMgcmVsYXRpb25zaGlwIGlzIGRlbm90ZWQgYnkgKkEg4oqCIEIqLiBUaGUgYWJvdmUgc2F5cyB0aGF0ICpBKiBpcyBhIHByb3BlciBzdWJzZXQgb2YgKkIqIGlmIGFuZCBvbmx5IGlmIHRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbiBlbGVtZW50ICp4KiBpbiAqQiogdGhhdCBpcyBub3QgYW4gZWxlbWVudCBpbiAqQSouCgojIyMjIEtleSBDaGFyYWN0ZXJpc3RpY3Mgb2YgYSBQcm9wZXIgU3Vic2V0OgoKMS4gICoqSW5jbHVzaW9uIG9mIEFsbCBFbGVtZW50cyoqOiBGb3IgKkEqIHRvIGJlIGEgcHJvcGVyIHN1YnNldCBvZiAqQiosIGV2ZXJ5IGVsZW1lbnQgaW4gKkEqIG11c3QgYWxzbyBiZSBhIG1lbWJlciBvZiAqQiouIFRoaXMgaXMgc2ltaWxhciB0byB0aGUgY29uZGl0aW9uIGZvciBhIHN1YnNldC4KCjIuICAqKkF0IExlYXN0IE9uZSBFeGNsdXNpdmUgRWxlbWVudCBpbiB0aGUgU3VwZXJzZXQqKjogVGhlIHNldCAqQiogbXVzdCBjb250YWluIGF0IGxlYXN0IG9uZSBlbGVtZW50IHRoYXQgaXMgbm90IGluICpBKi4gVGhpcyBpcyB3aGF0IGRpZmZlcmVudGlhdGVzIGEgcHJvcGVyIHN1YnNldCBmcm9tIGEgc3Vic2V0LgoKMy4gICoqKkEqKiogKippcyBub3QgRXF1YWwgdG8gKkIqKio6IElmICpBKiB3ZXJlIGVxdWFsIHRvICpCKiwgdGhlbiAqQSogd291bGQgYmUgYSBzdWJzZXQgYnV0IG5vdCBhIHByb3BlciBzdWJzZXQgb2YgQi4gRm9yICpBKiB0byBiZSBhIHByb3BlciBzdWJzZXQsIHRoZXJlIG11c3QgYmUgYW4gZWxlbWVudCBpbiAqQiogdGhhdCBpcyBub3QgaW4gKkEqLgoKIyMjIyBFeGFtcGxlczoKCjEuICBDb25zaWRlciB0d28gc2V0cyBBID0gezEsIDJ9IGFuZCBCID0gezEsIDIsIDN9LiBIZXJlLCBBIGlzIGEgcHJvcGVyIHN1YnNldCBvZiBCIGJlY2F1c2UgZXZlcnkgZWxlbWVudCBvZiBBIGlzIGluIEIsIGFuZCBCIGhhcyBhbiBhZGRpdGlvbmFsIGVsZW1lbnQsIDMsIHRoYXQgaXMgbm90IGluIEEuCgoyLiAgSWYgQSA9IHsxLCAyLCAzfSBhbmQgQiA9IHsxLCAyLCAzfSwgdGhlbiBBIGlzIG5vdCBhIHByb3BlciBzdWJzZXQgb2YgQi4gQSBpcyBhIHN1YnNldCBvZiBCLCBidXQgc2luY2UgdGhlcmUgYXJlIG5vIGV4dHJhIGVsZW1lbnRzIGluIEIgdGhhdCBhcmUgbm90IGluIEEsIGl0J3Mgbm90IGEgcHJvcGVyIHN1YnNldC4KCiMjIyMgTm90YXRpb246CgpUaGUgbm90YXRpb24gQSDiioIgQiBpcyB1c2VkIHRvIGluZGljYXRlIHRoYXQgQSBpcyBhIHByb3BlciBzdWJzZXQgb2YgQi4gSXQncyBpbXBvcnRhbnQgdG8gbm90ZSB0aGF0IHNvbWUgdGV4dHMgdXNlIHRoaXMgc3ltYm9sIHRvIG1lYW4gc3Vic2V0IChpbmNsdWRpbmcgdGhlIHBvc3NpYmlsaXR5IG9mIEEgYmVpbmcgZXF1YWwgdG8gQiksIGJ1dCB0aGUgbW9zdCBjb21tb24gdXNlIGlzIHRvIGRlbm90ZSBhIHByb3BlciBzdWJzZXQuCgojIyMjIENvbXBhcmlzb24gd2l0aCBTdWJzZXQ6CgpUaGUgdGVybSAic3Vic2V0IiBpbmNsdWRlcyB0aGUgcG9zc2liaWxpdHkgdGhhdCB0aGUgdHdvIHNldHMgYXJlIGVxdWFsIChpLmUuLCBBIGNhbiBiZSBlcXVhbCB0byBCKS4gSW4gY29udHJhc3QsICJwcm9wZXIgc3Vic2V0IiBleHBsaWNpdGx5IGV4Y2x1ZGVzIHRoZSBwb3NzaWJpbGl0eSBvZiB0aGUgc2V0cyBiZWluZyBlcXVhbC4gU28sIGV2ZXJ5IHByb3BlciBzdWJzZXQgaXMgYSBzdWJzZXQsIGJ1dCBub3QgZXZlcnkgc3Vic2V0IGlzIGEgcHJvcGVyIHN1YnNldC4KClVuZGVyc3RhbmRpbmcgdGhlIGNvbmNlcHQgb2YgcHJvcGVyIHN1YnNldHMgaXMgaW1wb3J0YW50IGZvciBhbmFseXppbmcgc2V0IHJlbGF0aW9ucyBhbmQgaXMgYSBmdW5kYW1lbnRhbCBwYXJ0IG9mIHNldCB0aGVvcnksIHdpdGggYXBwbGljYXRpb25zIGluIHZhcmlvdXMgYXJlYXMgb2YgbWF0aGVtYXRpY3MsIGxvZ2ljLCBhbmQgY29tcHV0ZXIgc2NpZW5jZS4KCiMjIEZpbml0ZSB2cyBJbmZpbml0ZSBTZXRzCgpUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGZpbml0ZSBhbmQgaW5maW5pdGUgc2V0cyBpcyBhIGZ1bmRhbWVudGFsIGNvbmNlcHQgaW4gc2V0IHRoZW9yeSwgZGlzdGluZ3Vpc2hpbmcgYmV0d2VlbiBzZXRzIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdGhleSBjb250YWluLgoKIyMjIEZpbml0ZSBTZXRzCgpBIHNldCBpcyBjb25zaWRlcmVkIGZpbml0ZSBpZiBpdCBjb250YWlucyBhIGNvdW50YWJsZSBudW1iZXIgb2YgZWxlbWVudHMsIGFuZCBpdCdzIHBvc3NpYmxlIHRvIGxpc3QgYWxsIGVsZW1lbnRzIGluIHRoZSBzZXQuIFRoZSBrZXkgY2hhcmFjdGVyaXN0aWMgb2YgYSBmaW5pdGUgc2V0IGlzIHRoYXQgdGhlcmUgaXMgYSBzcGVjaWZpYywgZmluaXRlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgc2V0LgoKLSAgICoqRXhhbXBsZSoqOiBUaGUgc2V0IG9mIGFsbCBmaW5nZXJzIG9uIGEgaHVtYW4gaGFuZCwgJFx7IHRodW1iLCBpbmRleCwgbWlkZGxlLCByaW5nLCBsaXR0bGUgXH0kLCBpcyBhIGZpbml0ZSBzZXQgYmVjYXVzZSB3ZSBjYW4gY291bnQgYW5kIGxpc3QgZWFjaCBlbGVtZW50LCBhbmQgdGhlcmUgYXJlIGV4YWN0bHkgZml2ZSBlbGVtZW50cyBpbiB0aGlzIHNldC4KCiMjIyBJbmZpbml0ZSBTZXRzCgpBbiBpbmZpbml0ZSBzZXQsIG9uIHRoZSBvdGhlciBoYW5kLCBpcyBhIHNldCB0aGF0IGhhcyBhbiB1bmxpbWl0ZWQsIG9yIGluZmluaXRlLCBudW1iZXIgb2YgZWxlbWVudHMuIEl0J3Mgbm90IHBvc3NpYmxlIHRvIGxpc3QgYWxsIHRoZSBlbGVtZW50cyBvZiBhbiBpbmZpbml0ZSBzZXQsIGFzIHRoZXJlIGlzIG5vICJsYXN0IiBlbGVtZW50LgoKLSAgICoqRXhhbXBsZSoqOiBUaGUgc2V0IG9mIGFsbCBuYXR1cmFsIG51bWJlcnMgJFxtYXRoYmJ7Tn0gPSBcezEsIDIsIDMsIDQsIDUsIFxsZG90c1x9JCBpcyBhbiBpbmZpbml0ZSBzZXQuIE5vIG1hdHRlciBob3cgaGlnaCB5b3UgY291bnQsIHRoZXJlIGlzIGFsd2F5cyBhbm90aGVyIG51bWJlciB0aGF0IGZvbGxvd3MsIG1ha2luZyB0aGUgc2V0IGVuZGxlc3MuCgojIyMgS2V5IERpZmZlcmVuY2VzCgoxLiAgKipOdW1iZXIgb2YgRWxlbWVudHMqKjoKICAgIC0gICBGaW5pdGUgc2V0cyBoYXZlIGEgc3BlY2lmaWMgbnVtYmVyIG9mIGVsZW1lbnRzICh3aGljaCBjYW4gYmUgemVybyBpbiB0aGUgY2FzZSBvZiB0aGUgZW1wdHkgc2V0KS4KICAgIC0gICBJbmZpbml0ZSBzZXRzIGRvIG5vdCBoYXZlIGEgc3BlY2lmaWMgbnVtYmVyIG9mIGVsZW1lbnRzLCBhbmQgdGhlaXIgc2l6ZSBpcyBub3QgY291bnRhYmxlIGluIGEgcHJhY3RpY2FsIHNlbnNlLgoyLiAgKipMaXN0YWJpbGl0eSoqOgogICAgLSAgIEluIGEgZmluaXRlIHNldCwgaXQgaXMgcG9zc2libGUgdG8gbGlzdCBhbGwgdGhlIGVsZW1lbnRzLgogICAgLSAgIEluIGFuIGluZmluaXRlIHNldCwgeW91IGNhbm5vdCBsaXN0IGFsbCBlbGVtZW50cywgYXMgdGhleSBjb250aW51ZSBpbmRlZmluaXRlbHkuCjMuICAqKkVuZCBFbGVtZW50Kio6CiAgICAtICAgRmluaXRlIHNldHMgaGF2ZSBhIGRlZmluaXRlLCBsYXN0IGVsZW1lbnQgd2hlbiBsaXN0ZWQuCiAgICAtICAgSW5maW5pdGUgc2V0cyBkbyBub3QgaGF2ZSBhbiBlbmQgZWxlbWVudC4KNC4gICoqQ2FyZGluYWxpdHkqKjoKICAgIC0gICBUaGUgY2FyZGluYWxpdHkgKG9yIHNpemUpIG9mIGEgZmluaXRlIHNldCBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLgogICAgLSAgIEluZmluaXRlIHNldHMgaGF2ZSBhIGNhcmRpbmFsaXR5IHRoYXQgaXMgbm90IHJlcHJlc2VudGFibGUgYnkgYSBzdGFuZGFyZCBpbnRlZ2VyLiBJbiBtYXRoZW1hdGljcywgZGlmZmVyZW50IHNpemVzIG9mIGluZmluaXR5LCBzdWNoIGFzIGNvdW50YWJsZSBhbmQgdW5jb3VudGFibGUgaW5maW5pdHksIGFyZSBzdHVkaWVkLgo1LiAgKipFeGFtcGxlcyBpbiBNYXRoZW1hdGljcyoqOgogICAgLSAgIENvbW1vbiBleGFtcGxlcyBvZiBmaW5pdGUgc2V0cyBpbmNsdWRlIHRoZSBzZXQgb2Ygc3R1ZGVudHMgaW4gYSBjbGFzc3Jvb20sIHRoZSBzZXQgb2YgbGV0dGVycyBpbiBhIHdvcmQsIGV0Yy4KICAgIC0gICBFeGFtcGxlcyBvZiBpbmZpbml0ZSBzZXRzIGluY2x1ZGUgdGhlIHNldCBvZiBuYXR1cmFsIG51bWJlcnMsIHRoZSBzZXQgb2YgcmVhbCBudW1iZXJzLCBhbmQgdGhlIHNldCBvZiBwb2ludHMgb24gYSBsaW5lLgoKVW5kZXJzdGFuZGluZyB0aGUgZGlzdGluY3Rpb24gYmV0d2VlbiBmaW5pdGUgYW5kIGluZmluaXRlIHNldHMgaXMgY3J1Y2lhbCBpbiBtYW55IGFyZWFzIG9mIG1hdGhlbWF0aWNzIGFuZCBjb21wdXRlciBzY2llbmNlLCBlc3BlY2lhbGx5IGluIHRoZSBzdHVkeSBvZiBhbGdvcml0aG1zLCBudW1iZXIgdGhlb3J5LCBhbmQgY29tYmluYXRvcmljcy4gSW5maW5pdGUgc2V0cyBpbnRyb2R1Y2UgdGhlIGNvbmNlcHQgb2YgaW5maW5pdHksIHdoaWNoIGlzIGEgZnVuZGFtZW50YWwgYW5kIGludHJpZ3VpbmcgYXNwZWN0IG9mIGhpZ2hlciBtYXRoZW1hdGljcy4KCiMjIFNldCBEZWZpbml0aW9uIE1ldGhvZHMKClNldHMgY2FuIGJlIGRlZmluZWQgaW4gc2V2ZXJhbCB3YXlzLCBlYWNoIGNhdGVyaW5nIHRvIGRpZmZlcmVudCBjb250ZXh0cyBhbmQgcmVxdWlyZW1lbnRzIGluIG1hdGhlbWF0aWNzLiBIZXJlIGFyZSBzb21lIGNvbW1vbiBtZXRob2RzIG9mIGRlZmluaW5nIHNldHM6CgoxLiAgKipSb3N0ZXIgb3IgVGFidWxhciBGb3JtKio6IEluIHRoaXMgbWV0aG9kLCBhbGwgdGhlIG1lbWJlcnMgKGVsZW1lbnRzKSBvZiB0aGUgc2V0IGFyZSBsaXN0ZWQsIHVzdWFsbHkgZW5jbG9zZWQgaW4gY3VybHkgYnJhY2VzLiBUaGUgb3JkZXIgb2YgZWxlbWVudHMgZG9lcyBub3QgbWF0dGVyLCBhbmQgZWFjaCBlbGVtZW50IGlzIGxpc3RlZCBvbmx5IG9uY2UuIEZvciBleGFtcGxlLCB0aGUgc2V0IG9mIHZvd2VscyBpbiB0aGUgRW5nbGlzaCBhbHBoYWJldCBjYW4gYmUgZGVmaW5lZCBhcyAkQSA9IFx7IGEsIGUsIGksIG8sIHUgXH0kLgoKMi4gICoqU2V0IEJ1aWxkZXIgTm90YXRpb24qKjogVGhpcyBpcyBhIG1vcmUgY29uY2lzZSB3YXkgb2YgZGVmaW5pbmcgc2V0cywgZXNwZWNpYWxseSB1c2VmdWwgd2hlbiB0aGUgc2V0IGlzIHRvbyBsYXJnZSB0byBsaXN0IGFsbCBlbGVtZW50cyBvciB3aGVuIHRoZSBzZXQgaXMgZGVmaW5lZCBieSBhIHByb3BlcnR5IHNoYXJlZCBieSBpdHMgbWVtYmVycy4gSXQgdHlwaWNhbGx5IGludm9sdmVzIGEgdmFyaWFibGUsIGEgY29uZGl0aW9uLCBhbmQgY3VybHkgYnJhY2VzLiBGb3IgZXhhbXBsZSwgdGhlIHNldCBvZiBhbGwgcG9zaXRpdmUgZXZlbiBudW1iZXJzIGNhbiBiZSBkZWZpbmVkIGFzICRCID0gXHsgeCBcbWlkIHggXHRleHR7IGlzIGEgcG9zaXRpdmUgZXZlbiBudW1iZXJ9IFx9JCwgd2hlcmUgJHgkIGlzIGFuIGVsZW1lbnQgb2YgdGhlIHNldCwgYW5kIHRoZSBjb25kaXRpb24gaXMgdGhhdCAkeCQgbXVzdCBiZSBhIHBvc2l0aXZlIGV2ZW4gbnVtYmVyLgoKMy4gICoqSW50ZXJ2YWxzKio6IFRoaXMgbWV0aG9kIGlzIHVzZWQgZm9yIHNldHMgb2YgbnVtYmVycyBhbmQgaXMgZXNwZWNpYWxseSB1c2VmdWwgZm9yIGNvbnRpbnVvdXMgc2V0cy4gSW50ZXJ2YWxzIGNhbiBiZSBjbG9zZWQgKGluY2x1ZGluZyB0aGUgZW5kcG9pbnRzKSBvciBvcGVuIChleGNsdWRpbmcgdGhlIGVuZHBvaW50cykuIEZvciBleGFtcGxlLCB0aGUgc2V0IG9mIGFsbCByZWFsIG51bWJlcnMgYmV0d2VlbiAxIGFuZCAzIGNhbiBiZSBkZWZpbmVkIGFzICQoMSwgMykkIGZvciBhbiBvcGVuIGludGVydmFsLCBvciAkWzEsIDNdJCBmb3IgYSBjbG9zZWQgaW50ZXJ2YWwuCgo0LiAgKipEZXNjcmlwdGlvbiBvciBSdWxlIE1ldGhvZCoqOiBIZXJlLCBhIHNldCBpcyBkZWZpbmVkIGJ5IGEgY2xlYXIgZGVzY3JpcHRpb24gb3IgYSBydWxlLiBUaGlzIG1ldGhvZCBpcyB1c2VkIHdoZW4gbGlzdGluZyBlbGVtZW50cyBvciB1c2luZyBzZXQtYnVpbGRlciBub3RhdGlvbiBpcyBub3QgZWZmaWNpZW50LiBGb3IgZXhhbXBsZSwgdGhlIHNldCBvZiBhbGwgcGxhbmV0cyBpbiB0aGUgc29sYXIgc3lzdGVtIGNhbiBiZSBkZWZpbmVkIGFzICJ0aGUgc2V0IG9mIGFsbCBjZWxlc3RpYWwgYm9kaWVzIG9yYml0aW5nIHRoZSBzdW4gdGhhdCBhcmUgcmVjb2duaXplZCBhcyBwbGFuZXRzIGJ5IHRoZSBJbnRlcm5hdGlvbmFsIEFzdHJvbm9taWNhbCBVbmlvbi4iCgo1LiAgKipVc2luZyBWZW5uIERpYWdyYW1zKio6IFdoaWxlIHRoaXMgaXMgbW9yZSBvZiBhIHZpc3VhbCByZXByZXNlbnRhdGlvbiB0aGFuIGEgZGVmaW5pdGlvbiBwZXIgc2UsIFZlbm4gZGlhZ3JhbXMgYXJlIG9mdGVuIHVzZWQgdG8gZGVwaWN0IHNldHMsIGVzcGVjaWFsbHkgdG8gc2hvdyByZWxhdGlvbnNoaXBzIGFtb25nIGRpZmZlcmVudCBzZXRzIGxpa2UgaW50ZXJzZWN0aW9ucywgdW5pb25zLCBhbmQgZGlmZmVyZW5jZXMuCgo2LiAgKipQcmVkaWNhdGUgTm90YXRpb24qKjogSW4gbW9yZSBhZHZhbmNlZCBjb250ZXh0cywgc2V0cyBjYW4gYmUgZGVmaW5lZCB1c2luZyBwcmVkaWNhdGVzLCB3aGljaCBhcmUgbG9naWNhbCBzdGF0ZW1lbnRzIHRoYXQgcmV0dXJuIHRydWUgb3IgZmFsc2UuIEZvciBleGFtcGxlLCAkQyA9IFx7IHggXGluIFxtYXRoYmJ7Wn1eeyt9IFxtaWQgUCh4KSBcfSQsIHdoZXJlICRcbWF0aGJie1p9XnsrfSQgaXMgdGhlIHNldCBvZiBwb3NpdGl2ZSBpbnRlZ2VycywgYW5kICRQKHgpJCBpcyBhIHByZWRpY2F0ZSBvciBwcm9wZXJ0eSB0aGF0IGVsZW1lbnRzIG9mIHRoZSBzZXQgbXVzdCBzYXRpc2Z5LgoKNy4gICoqUmVjdXJzaXZlIERlZmluaXRpb24qKjogU29tZSBzZXRzLCBwYXJ0aWN1bGFybHkgaW4gY29tcHV0ZXIgc2NpZW5jZSwgYXJlIGRlZmluZWQgcmVjdXJzaXZlbHkuIFRoaXMgbWVhbnMgdGhhdCB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgc2V0IHJlZmVycyBiYWNrIHRvIGl0c2VsZi4gVGhpcyBpcyBjb21tb24gaW4gZGVmaW5pbmcgc2VxdWVuY2VzLCB0cmVlcywgYW5kIG90aGVyIHN0cnVjdHVyZXMgaW4gdGhlb3JldGljYWwgY29tcHV0ZXIgc2NpZW5jZS4KCkVhY2ggb2YgdGhlc2UgbWV0aG9kcyBoYXMgaXRzIG93biBwbGFjZSBhbmQgdXRpbGl0eSBkZXBlbmRpbmcgb24gdGhlIG5hdHVyZSBvZiB0aGUgZWxlbWVudHMgb2YgdGhlIHNldCBhbmQgdGhlIGNvbnRleHQgaW4gd2hpY2ggdGhlIHNldCBpcyBiZWluZyB1c2VkLgoKIyMgUHJlZGljYXRlcwoKSW4gdGhlIGNvbnRleHQgb2Ygc2V0IHRoZW9yeSBhbmQgZGlzY3JldGUgbWF0aGVtYXRpY3MsIGEgcHJlZGljYXRlIGlzIGEgbG9naWNhbCBleHByZXNzaW9uIHRoYXQgZGVzY3JpYmVzIGEgcHJvcGVydHkgb3IgY29uZGl0aW9uIGFuZCBjYW4gYmUgZXZhbHVhdGVkIGFzIHRydWUgb3IgZmFsc2UgZm9yIGVhY2ggZWxlbWVudCBpbiBhIHNldC4gRXNzZW50aWFsbHksIHByZWRpY2F0ZXMgYXJlIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBhIEJvb2xlYW4gdmFsdWUgKHRydWUgb3IgZmFsc2UpIGFuZCBhcmUgdXNlZCB0byB0ZXN0IHdoZXRoZXIgYSBnaXZlbiBjb25kaXRpb24gaG9sZHMgZm9yIGVsZW1lbnRzIG9mIGEgc2V0LgoKSGVyZSBhcmUgc29tZSBrZXkgcG9pbnRzIGFib3V0IHByZWRpY2F0ZXMgaW4gdGhpcyBjb250ZXh0OgoKMS4gICoqRm9ybXVsYXRpb24qKjogQSBwcmVkaWNhdGUgaXMgb2Z0ZW4gZm9ybXVsYXRlZCBhcyBhIHN0YXRlbWVudCBvciBmb3JtdWxhIGludm9sdmluZyB2YXJpYWJsZXMuIEZvciBleGFtcGxlLCB0aGUgcHJlZGljYXRlICRQKHgpJCBtaWdodCByZXByZXNlbnQgdGhlIHN0YXRlbWVudCAieCBpcyBhbiBldmVuIG51bWJlci4iIFdoZW4gd2Ugc3Vic3RpdHV0ZSBhIHNwZWNpZmljIHZhbHVlIGZvciAkeCQsIHRoZSBwcmVkaWNhdGUgYmVjb21lcyBhIHN0YXRlbWVudCB0aGF0IGNhbiBiZSBqdWRnZWQgYXMgdHJ1ZSBvciBmYWxzZS4KCjIuICAqKlVzYWdlIGluIFNldCBCdWlsZGVyIE5vdGF0aW9uKio6IFByZWRpY2F0ZXMgYXJlIGNvbW1vbmx5IHVzZWQgaW4gc2V0IGJ1aWxkZXIgbm90YXRpb24gdG8gZGVmaW5lIHNldHMuIEZvciBleGFtcGxlLCB0aGUgc2V0IG9mIGFsbCBldmVuIGludGVnZXJzIGdyZWF0ZXIgdGhhbiAxMCBjYW4gYmUgZGVmaW5lZCBhcyAkXHsgeCBcaW4gXG1hdGhiYntafSBcbWlkIHggPiAxMCBcdGV4dHsgYW5kIH0gUCh4KSBcfSQsIHdoZXJlICRQKHgpJCBpcyB0aGUgcHJlZGljYXRlICJ4IGlzIGFuIGV2ZW4gbnVtYmVyLCIgYW5kICRcbWF0aGJie1p9JCByZXByZXNlbnRzIHRoZSBzZXQgb2YgYWxsIGludGVnZXJzLgoKMy4gICoqUm9sZSBpbiBMb2dpYyBhbmQgTWF0aGVtYXRpY3MqKjogUHJlZGljYXRlcyBwbGF5IGEgY3J1Y2lhbCByb2xlIGluIG1hdGhlbWF0aWNhbCBsb2dpYyBhbmQgZm9ybSB0aGUgYmFzaXMgb2YgcHJlZGljYXRlIGxvZ2ljLiBUaGV5IGFyZSB1c2VkIHRvIGV4cHJlc3MgbW9yZSBjb21wbGV4IGxvZ2ljYWwgZm9ybXVsYXRpb25zLCBzdWNoIGFzIGltcGxpY2F0aW9ucywgZXF1aXZhbGVuY2VzLCBhbmQgcXVhbnRpZmllZCBzdGF0ZW1lbnRzLgoKNC4gICoqUXVhbnRpZmllcnMqKjogSW4gY29uanVuY3Rpb24gd2l0aCBwcmVkaWNhdGVzLCBxdWFudGlmaWVycyBsaWtlICJmb3IgYWxsIiAoZGVub3RlZCBieSAkXGZvcmFsbCQpIGFuZCAidGhlcmUgZXhpc3RzIiAoZGVub3RlZCBieSAkXGV4aXN0cyQpIGFyZSB1c2VkLiBGb3IgZXhhbXBsZSwgJFxmb3JhbGwgeCBcaW4gXG1hdGhiYntOfSwgUCh4KSQgbWVhbnMgImZvciBhbGwgbmF0dXJhbCBudW1iZXJzICR4JCwgJFAoeCkkIGlzIHRydWUsIiB3aGVyZWFzICRcZXhpc3RzIHggXGluIFxtYXRoYmJ7Tn0kIHN1Y2ggdGhhdCAkUCh4KSQgbWVhbnMgInRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbmUgbmF0dXJhbCBudW1iZXIgJHgkIGZvciB3aGljaCAkUCh4KSQgaXMgdHJ1ZS4iCgo1LiAgKipBcHBsaWNhdGlvbiBpbiBQcm9vZnMqKjogSW4gbWF0aGVtYXRpY2FsIHByb29mcywgZXNwZWNpYWxseSBpbiBkaXNjcmV0ZSBtYXRoZW1hdGljcywgcHJlZGljYXRlcyBhcmUgb2Z0ZW4gdXNlZCB0byBmb3JtYWxpemUgc3RhdGVtZW50cyB0aGF0IG5lZWQgdG8gYmUgcHJvdmVkIG9yIGRpc3Byb3ZlZC4gVGhleSBoZWxwIGluIHN0cnVjdHVyaW5nIGFyZ3VtZW50cyBsb2dpY2FsbHkgYW5kIHByZWNpc2VseS4KCkluIHNob3J0LCBwcmVkaWNhdGVzIGFyZSBmdW5kYW1lbnRhbCBpbiBzZXQgdGhlb3J5IGFuZCBkaXNjcmV0ZSBtYXRoZW1hdGljcywgcHJvdmlkaW5nIGEgd2F5IHRvIGV4cHJlc3MgcHJvcGVydGllcyBhbmQgY29uZGl0aW9ucyBmb3Igc2V0IGVsZW1lbnRzLCBmb3JtdWxhdGluZyBsb2dpY2FsIHN0YXRlbWVudHMsIGFuZCBmYWNpbGl0YXRpbmcgcmlnb3JvdXMgbWF0aGVtYXRpY2FsIHJlYXNvbmluZyBhbmQgcHJvb2ZzLgoKIyMgU3BlY2lhbCBTZXRzIGluIE1hdGhlbWF0aWNzCgojIyMgKipOYXR1cmFsIE51bWJlcnMqKgoKVGhlIHNldCBvZiBuYXR1cmFsIG51bWJlcnMsIGRlbm90ZWQgYnkgdGhlIHN5bWJvbCAkXG1hdGhiYntOfSQgaXMgdGhlIHNldCBvZiBwb3NpdGl2ZSBpbnRlZ2VycyBzdGFydGluZyBmcm9tIDEgYW5kIGNvbnRpbnVpbmcgaW5kZWZpbml0ZWx5IGluIGFuIGluY3JlYXNpbmcgbWFubmVyLiBDYW4gYWx0ZXJuYXRpdmVseSBiZSBkZWZpbmVkIGFzICRcbWF0aGJie059ID0gXHsxLDIsMyw0LCBcbGRvdHNcfSQuCgpOYXR1cmFsIG51bWJlcnMgYXJlIHRoZSBiYXNpYyBjb3VudGluZyBudW1iZXJzIHVzZWQgaW4gZXZlcnlkYXkgbGlmZSBhbmQgYXJlIGEgZnVuZGFtZW50YWwgcGFydCBvZiBtYXRoZW1hdGljcy4gVGhleSBhcmUgdGhlIHNldCBvZiBwb3NpdGl2ZSBpbnRlZ2VycyBzdGFydGluZyBmcm9tIDEgYW5kIGNvbnRpbnVpbmcgaW5kZWZpbml0ZWx5IGluIGFuIGluY3JlYXNpbmcgbWFubmVyLiBUaGUgc2V0IG9mIG5hdHVyYWwgbnVtYmVycyBpcyB1c3VhbGx5IGRlbm90ZWQgYnkgdGhlIHN5bWJvbCAkXG1hdGhiYntOfSQuCgojIyMjIEtleSBDaGFyYWN0ZXJpc3RpY3Mgb2YgTmF0dXJhbCBOdW1iZXJzOgoKMS4gICoqU3RhcnRpbmcgUG9pbnQqKjogTmF0dXJhbCBudW1iZXJzIHN0YXJ0IGZyb20gMSAoMSwgMiwgMywgNCwgNSwgLi4uKS4gU29tZSBtYXRoZW1hdGljYWwgZGVmaW5pdGlvbnMgaW5jbHVkZSAwIGluIHRoZSBzZXQgb2YgbmF0dXJhbCBudW1iZXJzLCBidXQgdHJhZGl0aW9uYWxseSBpdCBzdGFydHMgZnJvbSAxLgoKMi4gICoqUG9zaXRpdmUgSW50ZWdlcnMqKjogVGhleSBhcmUgYWxsIHBvc2l0aXZlIGFuZCBkbyBub3QgaW5jbHVkZSBuZWdhdGl2ZSBudW1iZXJzLCBmcmFjdGlvbnMsIG9yIGRlY2ltYWxzLgoKMy4gICoqQ291bnRpbmcqKjogTmF0dXJhbCBudW1iZXJzIGFyZSB1c2VkIGZvciBjb3VudGluZyBvYmplY3RzLiBGb3IgaW5zdGFuY2UsIHdoZW4geW91IGNvdW50IHRoZSBudW1iZXIgb2YgYm9va3Mgb24gYSBzaGVsZiwgeW91IHVzZSBuYXR1cmFsIG51bWJlcnMuCgo0LiAgKipJbmZpbml0eSoqOiBUaGUgc2V0IG9mIG5hdHVyYWwgbnVtYmVycyBpcyBpbmZpbml0ZTsgaXQgaGFzIG5vIHVwcGVyIGxpbWl0LgoKNS4gICoqRGlzY3JldGVuZXNzKio6IE5hdHVyYWwgbnVtYmVycyBhcmUgZGlzY3JldGUsIG1lYW5pbmcgdGhlcmUgYXJlIG5vIGZyYWN0aW9ucyBvciBkZWNpbWFscyBiZXR3ZWVuIHRoZW0uCgo2LiAgKipGdW5kYW1lbnRhbCBpbiBNYXRoZW1hdGljcyoqOiBUaGV5IGZvcm0gdGhlIGJhc2lzIGZvciBtb3JlIGNvbXBsZXggbnVtYmVyIHN5c3RlbXMsIGluY2x1ZGluZyBpbnRlZ2VycywgcmF0aW9uYWwgbnVtYmVycywgYW5kIHJlYWwgbnVtYmVycy4KCkluIG1hdGhlbWF0aWNhbCBub3RhdGlvbiwgdGhlIHNldCBvZiBuYXR1cmFsIG51bWJlcnMgaXMgb2Z0ZW4gcmVwcmVzZW50ZWQgYXMgZm9sbG93czoKCiQkIFxtYXRoYmJ7Tn0gPSBcezEsIDIsIDMsIDQsIDUsIFxsZG90c1x9ICQkCgpOYXR1cmFsIG51bWJlcnMgYXJlIGZvdW5kYXRpb25hbCBpbiB2YXJpb3VzIGJyYW5jaGVzIG9mIG1hdGhlbWF0aWNzLCBpbmNsdWRpbmcgYXJpdGhtZXRpYywgbnVtYmVyIHRoZW9yeSwgYW5kIGFyZSB3aWRlbHkgdXNlZCBpbiBldmVyeWRheSBsaWZlIGZvciBjb3VudGluZyBhbmQgb3JkZXJpbmcgb2JqZWN0cy4KCiMjIyAqKkludGVnZXJzKioKClRoZSBzZXQgb2YgaW50ZWdlcnMsIGRlbm90ZWQgYnkgKFwqXCokXG1hdGhiYntafSQpLCBpbmNsdWRpbmcgcG9zaXRpdmUsIG5lZ2F0aXZlLCBhbmQgemVyby4gVGhlIHN5bWJvbCBjb21lcyBmcm9tIHRoZSBHZXJtYW4gd29yZCBmb3IgbnVtYmVyczogWmFobGVuLgoKIyMjICoqUmF0aW9uYWwgTnVtYmVycyoqCgpSYXRpb25hbCBudW1iZXJzIGFyZSBudW1iZXJzIHRoYXQgY2FuIGJlIGV4cHJlc3NlZCBhcyB0aGUgcXVvdGllbnQgb3IgZnJhY3Rpb24gJFxmcmFje3B9e3F9JCBvZiB0d28gaW50ZWdlcnMsIHdoZXJlIHRoZSBudW1lcmF0b3IgJHAkIGlzIGFuIGludGVnZXIgYW5kIHRoZSBkZW5vbWluYXRvciAkcSQgaXMgYSBub24temVybyBpbnRlZ2VyLiBFc3NlbnRpYWxseSwgYSByYXRpb25hbCBudW1iZXIgcmVwcmVzZW50cyBhIHJhdGlvIGJldHdlZW4gdHdvIGludGVnZXJzLgoKIyMjIyBLZXkgQ2hhcmFjdGVyaXN0aWNzIG9mIFJhdGlvbmFsIE51bWJlcnM6CgoxLiAgKipGcmFjdGlvbmFsIEZvcm0qKjogVGhleSBjYW4gYWx3YXlzIGJlIGV4cHJlc3NlZCBhcyBmcmFjdGlvbnMuCgoyLiAgKipJbmNsdWRlIEludGVnZXJzKio6IEFsbCBpbnRlZ2VycyBhcmUgcmF0aW9uYWwgbnVtYmVycyBzaW5jZSBhbnkgaW50ZWdlciAkeiQgY2FuIGJlIGV4cHJlc3NlZCBhcyAkXGZyYWN7en17MX0kLgoKMy4gICoqRGVjaW1hbCBSZXByZXNlbnRhdGlvbioqOiBSYXRpb25hbCBudW1iZXJzIGNhbiBiZSByZXByZXNlbnRlZCBhcyBlaXRoZXIgdGVybWluYXRpbmcgZGVjaW1hbHMgb3IgcmVwZWF0aW5nIGRlY2ltYWxzLgoKNC4gICoqRGVuc2l0eSoqOiBCZXR3ZWVuIGFueSB0d28gcmF0aW9uYWwgbnVtYmVycywgdGhlcmUncyBhbm90aGVyIHJhdGlvbmFsIG51bWJlci4gVGhpcyBwcm9wZXJ0eSBpcyBrbm93biBhcyB0aGUgZGVuc2l0eSBvZiByYXRpb25hbCBudW1iZXJzLgoKNS4gICoqTmVnYXRpdmUgTnVtYmVycyoqOiBUaGUgc2V0IG9mIHJhdGlvbmFsIG51bWJlcnMgaW5jbHVkZXMgYm90aCBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgbnVtYmVycywgYXMgd2VsbCBhcyB6ZXJvLgoKIyMjIyBTeW1ib2wgZm9yIFJhdGlvbmFsIE51bWJlcnM6CgpUaGUgc2V0IG9mIHJhdGlvbmFsIG51bWJlcnMgaXMgZGVub3RlZCBieSB0aGUgc3ltYm9sICRcbWF0aGJie1F9JC4gVGhlIGxldHRlciAiUSIgc3RhbmRzIGZvciAicXVvdGllbnQsIiByZWZsZWN0aW5nIHRoZSBmYWN0IHRoYXQgYW55IHJhdGlvbmFsIG51bWJlciByZXByZXNlbnRzIHRoZSBxdW90aWVudCBvZiB0d28gaW50ZWdlcnMuCgojIyMjIEV4YW1wbGVzOgoKLSAgICRcZnJhY3sxfXsyfSQsICRcZnJhY3s1fXszfSQsIGFuZCAkLVxmcmFjezR9ezd9JCBhcmUgcmF0aW9uYWwgbnVtYmVycy4KLSAgIEFsbCBpbnRlZ2VycyBhcmUgcmF0aW9uYWwgbnVtYmVycywgZm9yIGV4YW1wbGUsIDcgKHdoaWNoIGlzIHRoZSBzYW1lIGFzICRcZnJhY3s3fXsxfSQpLgotICAgTnVtYmVycyBsaWtlIDAuNzUgKHdoaWNoIGlzICRcZnJhY3szfXs0fSQpIGFuZCAwLjMzMy4uLiAod2hpY2ggaXMgJFxmcmFjezF9ezN9JCkgYXJlIGFsc28gcmF0aW9uYWwuCgpJbiBtYXRoZW1hdGljYWwgbm90YXRpb24sIHRoZSBzZXQgb2YgcmF0aW9uYWwgbnVtYmVycyBjYW4gYmUgcmVwcmVzZW50ZWQgYXM6CgokJCBcbWF0aGJie1F9ID0gXGxlZnRceyBcZnJhY3twfXtxfSBcbWlkIHAsIHEgXGluIFxtYXRoYmJ7Wn0sIHEgXG5lcSAwIFxyaWdodFx9ICQkCgpXaGVyZSAkXG1hdGhiYntafSQgZGVub3RlcyB0aGUgc2V0IG9mIGFsbCBpbnRlZ2Vycy4gUmF0aW9uYWwgbnVtYmVycyBwbGF5IGEgY3J1Y2lhbCByb2xlIGluIG1hdGhlbWF0aWNzLCBicmlkZ2luZyB0aGUgZ2FwIGJldHdlZW4gaW50ZWdlcnMgYW5kIHRoZSBtb3JlIGNvbXByZWhlbnNpdmUgc2V0IG9mIHJlYWwgbnVtYmVycy4KCiMjIyAqKklycmF0aW9uYWwgTnVtYmVycyoqCgpJcnJhdGlvbmFsIG51bWJlcnMgYXJlIGEgdHlwZSBvZiByZWFsIG51bWJlciB0aGF0IGNhbm5vdCBiZSBleHByZXNzZWQgYXMgYSBzaW1wbGUgZnJhY3Rpb24gLSB0aGF0IGlzLCB0aGUgcmF0aW8gb2YgdHdvIGludGVnZXJzLiBUaGUgZGVmaW5pbmcgY2hhcmFjdGVyaXN0aWMgb2YgYW4gaXJyYXRpb25hbCBudW1iZXIgaXMgdGhhdCBpdHMgZGVjaW1hbCByZXByZXNlbnRhdGlvbiBpcyBub24tdGVybWluYXRpbmcgYW5kIG5vbi1yZXBlYXRpbmcuIFRoaXMgbWVhbnMgaXQgZ29lcyBvbiBmb3JldmVyIHdpdGhvdXQgcmVwZWF0aW5nIGEgcGF0dGVybi4KCiMjIyMgS2V5IENoYXJhY3RlcmlzdGljcyBvZiBJcnJhdGlvbmFsIE51bWJlcnM6CgoxLiAgKipOb24tcmVwcmVzZW50YWJsZSBhcyBGcmFjdGlvbnMqKjogVW5saWtlIHJhdGlvbmFsIG51bWJlcnMsIHlvdSBjYW5ub3QgZXhwcmVzcyBpcnJhdGlvbmFsIG51bWJlcnMgYXMgYSBmcmFjdGlvbiBvZiB0d28gaW50ZWdlcnMuCgoyLiAgKipOb24tdGVybWluYXRpbmcsIE5vbi1yZXBlYXRpbmcgRGVjaW1hbHMqKjogSW4gZGVjaW1hbCBmb3JtLCB0aGVzZSBudW1iZXJzIG5ldmVyIGVuZCBhbmQgZG8gbm90IGRpc3BsYXkgYSByZXBlYXRpbmcgcGF0dGVybiBvZiBkaWdpdHMuCgozLiAgKipDYW5ub3QgYmUgRXhhY3RseSBDYWxjdWxhdGVkKio6IFRoZSBleGFjdCB2YWx1ZSBvZiBhbiBpcnJhdGlvbmFsIG51bWJlciBjYW5ub3QgYmUgcHJlY2lzZWx5IGNhbGN1bGF0ZWQgb3Igd3JpdHRlbiBkb3duIGluIGRlY2ltYWwgZm9ybS4KCjQuICAqKkV4YW1wbGVzKio6IEZhbW91cyBleGFtcGxlcyBpbmNsdWRlOgoKICAgIC0gICBQaSAoz4ApLCB0aGUgcmF0aW8gb2YgdGhlIGNpcmN1bWZlcmVuY2Ugb2YgYSBjaXJjbGUgdG8gaXRzIGRpYW1ldGVyLgogICAgLSAgIEV1bGVyJ3MgbnVtYmVyIChlKSwgdGhlIGJhc2Ugb2YgbmF0dXJhbCBsb2dhcml0aG1zLgogICAgLSAgIFRoZSBzcXVhcmUgcm9vdCBvZiBhIG5vbi1wZXJmZWN0IHNxdWFyZSBudW1iZXIgKGxpa2Ug4oiaMiwg4oiaMywgZXRjLikuCgo1LiAgKipSZWFsIE51bWJlcnMqKjogQWxsIGlycmF0aW9uYWwgbnVtYmVycyBhcmUgcmVhbCBudW1iZXJzIGJ1dCB0aGV5IGFyZSBub3QgcmF0aW9uYWwgbnVtYmVycy4KCiMjIyMgU3ltYm9sIGZvciBJcnJhdGlvbmFsIE51bWJlcnM6CgpUaGVyZSBpcyBubyBzdGFuZGFyZCBzeW1ib2wgdW5pdmVyc2FsbHkgdXNlZCB0byBkZW5vdGUgdGhlIHNldCBvZiBhbGwgaXJyYXRpb25hbCBudW1iZXJzLiBIb3dldmVyLCBzb21ldGltZXMgdGhlIHNldCBpcyByZXByZXNlbnRlZCBhcyB0aGUgc2V0IGRpZmZlcmVuY2Ugb2YgdGhlIHJlYWwgbnVtYmVycyBhbmQgdGhlIHJhdGlvbmFsIG51bWJlcnMsIHdoaWNoIGNhbiBiZSBub3RhdGVkIGFzICRcbWF0aGJie1J9IFxzZXRtaW51cyBcbWF0aGJie1F9JC4gVGhpcyBub3RhdGlvbiByZWZsZWN0cyB0aGF0IGlycmF0aW9uYWwgbnVtYmVycyBpbmNsdWRlIGFsbCByZWFsIG51bWJlcnMgdGhhdCBhcmUgbm90IHJhdGlvbmFsLgoKIyMjIyBJbmNsdXNpb24gaW4gdGhlIE51bWJlciBTeXN0ZW06CgpJcnJhdGlvbmFsIG51bWJlcnMsIGFsb25nIHdpdGggcmF0aW9uYWwgbnVtYmVycywgbWFrZSB1cCB0aGUgcmVhbCBudW1iZXJzLCAkXG1hdGhiYntSfSQuIFRoZSBkaXNjb3Zlcnkgb2YgaXJyYXRpb25hbCBudW1iZXJzIHdhcyBzaWduaWZpY2FudCBpbiBtYXRoZW1hdGljcyBhcyBpdCBleHBhbmRlZCB0aGUgdW5kZXJzdGFuZGluZyBvZiBudW1lcmljYWwgY29uY2VwdHMgYmV5b25kIHRoZSBzaW1wbGUgcmF0aW9zIG9mIGludGVnZXJzLgoKIyMjIyBTaWduaWZpY2FuY2U6CgpJcnJhdGlvbmFsIG51bWJlcnMgYXJlIGVzc2VudGlhbCBpbiB2YXJpb3VzIGFyZWFzIG9mIG1hdGhlbWF0aWNzIGFuZCBhcHBsaWVkIHNjaWVuY2VzLiBUaGV5IG9mdGVuIGFwcGVhciBpbiBmb3JtdWxhcywgZ2VvbWV0cmljIG1lYXN1cmVtZW50cywgYW5kIGNhbGN1bGF0aW9ucyB3aGVyZSBleGFjdCBwcmVjaXNpb24gaXMgcmVxdWlyZWQgYmV5b25kIHRoZSBsaW1pdGF0aW9uIG9mIHJhdGlvbmFsIG51bWJlcnMuIFRoZXkgYXJlIGZ1bmRhbWVudGFsIGluIHVuZGVyc3RhbmRpbmcgdGhlIGNvbnRpbnV1bSBvZiByZWFsIG51bWJlcnMgYW5kIHBsYXkgYSBjcnVjaWFsIHJvbGUgaW4gYWR2YW5jZWQgbWF0aGVtYXRpY3MsIGluY2x1ZGluZyBjYWxjdWx1cyBhbmQgbWF0aGVtYXRpY2FsIGFuYWx5c2lzLgoKIyMjICoqUmVhbCBOdW1iZXJzKioKClJlYWwgbnVtYmVycyBhcmUgdGhlIHNldCBvZiBudW1iZXJzIHRoYXQgaW5jbHVkZSBib3RoIHRoZSByYXRpb25hbCBudW1iZXJzIChzdWNoIGFzIGludGVnZXJzIGFuZCBmcmFjdGlvbnMpIGFuZCB0aGUgaXJyYXRpb25hbCBudW1iZXJzIChzdWNoIGFzICRcc3FydHsyfSQsICRccGkkLCBhbmQgJGUkKS4gVGhleSBmb3JtIGEgY29udGludXVtIG9mIG51bWJlcnMgdGhhdCBjYW4gcmVwcmVzZW50IGFueSBxdWFudGl0eSBhbG9uZyBhIGNvbnRpbnVvdXMgbGluZSwga25vd24gYXMgdGhlIG51bWJlciBsaW5lLgoKIyMjIyBLZXkgQ2hhcmFjdGVyaXN0aWNzIG9mIFJlYWwgTnVtYmVyczoKCjEuICAqKkluY2x1c2l2aXR5Kio6IFRoZSBzZXQgb2YgcmVhbCBudW1iZXJzIGluY2x1ZGVzOgoKICAgIC0gICBBbGwgcmF0aW9uYWwgbnVtYmVycywgd2hpY2ggY2FuIGJlIGV4cHJlc3NlZCBhcyBmcmFjdGlvbnMgb3IgZGVjaW1hbHMgdGhhdCBlaXRoZXIgdGVybWluYXRlIG9yIHJlcGVhdC4KICAgIC0gICBBbGwgaXJyYXRpb25hbCBudW1iZXJzLCB3aGljaCBjYW5ub3QgYmUgZXhwcmVzc2VkIGFzIGZyYWN0aW9ucyBhbmQgaGF2ZSBub24tdGVybWluYXRpbmcsIG5vbi1yZXBlYXRpbmcgZGVjaW1hbCByZXByZXNlbnRhdGlvbnMuCgoyLiAgKipSZXByZXNlbnRhdGlvbiBvbiB0aGUgTnVtYmVyIExpbmUqKjogRXZlcnkgcG9pbnQgb24gdGhlIG51bWJlciBsaW5lIGNvcnJlc3BvbmRzIHRvIGEgdW5pcXVlIHJlYWwgbnVtYmVyLiBUaGlzIGluY2x1ZGVzIGJvdGggcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIG51bWJlcnMsIGFzIHdlbGwgYXMgemVyby4KCjMuICAqKkNvbXBsZXRlIGFuZCBDb250aW51b3VzKio6IFRoZSByZWFsIG51bWJlcnMgYXJlIGNvbXBsZXRlLCBtZWFuaW5nIHRoZXkgY29udGFpbiBhbGwgdGhlIGxpbWl0IHBvaW50cywgYW5kIGFyZSBjb250aW51b3VzLCB3aXRoIG5vIGdhcHMgYmV0d2VlbiB0aGUgbnVtYmVycy4KCjQuICAqKkRlY2ltYWwgRXhwYW5zaW9uKio6IEV2ZXJ5IHJlYWwgbnVtYmVyIGNhbiBiZSBleHByZXNzZWQgYXMgYW4gaW5maW5pdGUgZGVjaW1hbCBleHBhbnNpb24uCgo1LiAgKipBcml0aG1ldGljIE9wZXJhdGlvbnMqKjogVGhlIHNldCBvZiByZWFsIG51bWJlcnMgaXMgY2xvc2VkIHVuZGVyIGFkZGl0aW9uLCBzdWJ0cmFjdGlvbiwgbXVsdGlwbGljYXRpb24sIGFuZCBkaXZpc2lvbiAoZXhjZXB0IGRpdmlzaW9uIGJ5IHplcm8pLgoKIyMjIyBTeW1ib2wgZm9yIFJlYWwgTnVtYmVyczoKClRoZSBzZXQgb2YgcmVhbCBudW1iZXJzIGlzIGRlbm90ZWQgYnkgdGhlIHN5bWJvbCAkXG1hdGhiYntSfSQuCgojIyMjIEV4YW1wbGVzOgoKLSAgIFJhdGlvbmFsIG51bWJlcnMgbGlrZSAkLTMkLCAkXGZyYWN7MX17Mn0kLCBhbmQgJDQuNzUkIGFyZSByZWFsIG51bWJlcnMuCi0gICBJcnJhdGlvbmFsIG51bWJlcnMgbGlrZSAkXHNxcnR7Mn0kLCAkXHBpJCwgYW5kICRlJCBhcmUgYWxzbyByZWFsIG51bWJlcnMuCi0gICBBbGwgaW50ZWdlcnMgYW5kIG5hdHVyYWwgbnVtYmVycyBhcmUgaW5jbHVkZWQgaW4gdGhlIHNldCBvZiByZWFsIG51bWJlcnMuCgojIyMjIEltcG9ydGFuY2U6CgpSZWFsIG51bWJlcnMgYXJlIGZ1bmRhbWVudGFsIGluIG1hdGhlbWF0aWNzIGFuZCBhcmUgdXNlZCB0byBtZWFzdXJlIGNvbnRpbnVvdXMgcXVhbnRpdGllcyBzdWNoIGFzIGRpc3RhbmNlLCB0aW1lLCBhbmQgdGVtcGVyYXR1cmUuIFRoZXkgZm9ybSB0aGUgYmFzaXMgb2YgY2FsY3VsdXMgYW5kIGFuYWx5c2lzIGFuZCBhcmUgZXNzZW50aWFsIGZvciBkZXNjcmliaW5nIHRoZSBwaHlzaWNhbCB3b3JsZCBpbiBzY2llbmNlcyBhbmQgZW5naW5lZXJpbmcuIFRoZSBjb25jZXB0IG9mIHJlYWwgbnVtYmVycyBhbGxvd3MgZm9yIHByZWNpc2UgYW5kIGNvbXByZWhlbnNpdmUgZGVzY3JpcHRpb25zIG9mIHF1YW50aXRpZXMgaW4gYSB3aWRlIHJhbmdlIG9mIG1hdGhlbWF0aWNhbCwgcGh5c2ljYWwsIGFuZCBwcmFjdGljYWwgYXBwbGljYXRpb25zLgoKIyMgVHV0b3JpYWwKCk5vbmUgeWV0LgoKIyMgUHJhY3RpY2UgUXVlc3Rpb25zCgojIyMjIFF1ZXN0aW9uIDEKCldoYXQgYXJlIHRoZSBjYXJkaW5hbGl0aWVzIG9mIHRoZSBmb2xsb3dpbmcgc2V0czoKCjEuICB7QSxGLEcsWH0KMi4gIHsnR29sZHdhc3NlcicsJ0tudXRoJywnQ29kZCd9CjMuICAkXHsgeCBcaW4gXG1hdGhiYntafV57K30gXG1pZCAoeCBcJSAyID0gMCkgXH0kIHdoZXJlICUgaXMgdGhlIG1vZHVsdXMgb3BlcmF0b3IKNC4gIHt7MzMsMn0sezMzNCx7cCxxLHJ9fX0KNS4gIHt9CgojIyMjIFF1ZXN0aW9uIDIKCkRlZmluZSB0aGUgc2V0IG9mIGFsbCByZWFsIHBvc2l0aXZlIG51bWJlcnMuCgojIyMjIFF1ZXN0aW9uIDMKCkRlZmluZSBhIHNldCB0aGF0IGluY2x1ZGVzIGZvdXIgZGlnaXQgd2hvbGUgbnVtYmVycyB0aGF0IGFyZSBncmVhdGVyIHRoYW4gMC4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlsZXMgJiBSZXNvdXJjZXMKCmBgYHtyIHppcEZpbGVzLCBlY2hvPUZBTFNFfQp6aXBOYW1lID0gc3ByaW50ZigiTGVzc29uRmlsZXMtJXMtJXMuemlwIiwgCiAgICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LAogICAgICAgICAgICAgICAgIHBhcmFtcyRudW1iZXIpCgp0ZXh0QUxpbmsgPSBwYXN0ZTAoIkFsbCBGaWxlcyBmb3IgTGVzc29uICIsIAogICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksIi4iLHBhcmFtcyRudW1iZXIpCgojIGRvd25sb2FkRmlsZXNMaW5rKCkgaXMgaW5jbHVkZWQgZnJvbSBfaW5zZXJ0MkRCLlIKa25pdHI6OnJhd19odG1sKGRvd25sb2FkRmlsZXNMaW5rKCIuIiwgemlwTmFtZSwgdGV4dEFMaW5rKSkKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIFJlZmVyZW5jZXMKCk5vbmUgeWV0LgoKIyMgRXJyYXRhCgpbTGV0IHVzIGtub3ddKGh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS8yMTIxODcwNzI3ODQxNTcpe3RhcmdldD0iX2JsYW5rIn0uCg==