View the
latest recording of this lecture
While the use of matrix notation may seem unnecessarily complicated
at first, there are good reasons for learning about it:
Many results for linear models are much more easily derived and
understood using matrix notation than without it.
Matrix formulation of linear models is the norm in some areas of
science, so will help you understand the literature.
In this lecture we will cover the necessary terminology and matrix
algebra.
even if you have a good understanding of matrices, you will see
how various matrix operations are done using R.
you do not need to remember all R commands presented here. There
is always time to come back and find them if you need
something.
What you need to know before we start is that matrix algebra is the
way that R does practically all the calculations needed for fitting
linear models, no matter what kind of linear model we are fitting. The
linear model work comes in the next lecture.
What is a Matrix?
A matrix is a collection of numbers arranged in a rectangular
array.
Matrices are often denoted using capital letters, but notation is
far from consistent due to changes in preference and typesetting
technology.
If a matrix has r rows and c columns then the
matrix is r by c.
\[X =
\left [
\begin{array}{cccccc}
x_{11} & x_{12} & \cdots & x_{1j} & \cdots & x_{1c}
\\
x_{21} & x_{22} & \cdots & x_{2j} & \cdots & x_{2c}
\\
\vdots & \vdots & \ddots & \vdots & \ddots & \vdots
\\
x_{i1} & x_{i2} & \cdots & x_{ij} & \cdots & x_{ic}
\\
\vdots & \vdots & \ddots & \vdots & \ddots & \vdots
\\
x_{r1} & x_{r2} & \cdots & x_{rj} & \cdots & x_{rc}
\end{array}
\right ]
\label{eq:matrix1}\]
- xij denotes the i,jth element
of the matrix X.
A Simple Matrix
Consider matrix A defined by \[A
= \left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ].\]
A.mat = matrix(c(3, 4, 2, 2, 4, 1), nrow = 3, byrow = TRUE)
Its first row is (3,4) and its second column is
(4,2,1).
The 1,2 element, a12, is
4.
[1] 3 4
[1] 4 2 1
[1] 4
Types of matrices
Square Matrices
Matrix with same number of rows as columns is
square.
Square matrices have some nice properties, like having an
inverse (coming soon).
The matrix A defined by \[A =
\left [
\begin{array}{cc}
1.74 & 4.11 \\
3.11 & 3.16 \\
\end{array}
\right ]\] is a square matrix. The main diagonal of this matrix
contains the elements 1.74 and 3.16.
A.mat = matrix(c(1.74, 4.11, 3.11, 3.16), nrow = 2, byrow = TRUE)
diag(A.mat)
[1] 1.74 3.16
Symmetric Matrices
Matrix with elements that can be defined as xij =
xji for all i and j is called
symmetric.
The matrix A defined by \[A =
\left [
\begin{array}{ccc}
3 & -2 & 0 \\
-2 & 1 & 4 \\
0 & 4 & 5 \\
\end{array}
\right ]\] is a symmetric matrix.
Diagonal Matrices
The matrix with zero entries everywhere away from the main/leading
diagonal (top left to bottom right) is called
diagonal.
The matrix A defined by \[A =
\left [
\begin{array}{ccc}
3 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 5 \\
\end{array}
\right ]\] is a diagonal matrix.
D.mat <- diag(c(3, 1, 5))
D.mat
[,1] [,2] [,3]
[1,] 3 0 0
[2,] 0 1 0
[3,] 0 0 5
Identity Matrices
The matrix with ones along the main diagonal and zero elements
everywhere else is called the identity matrix.
The identity matrix In is said to be of
size (or order) n, with
dimensions \(n \times n\).
- Identity matrices can be thought of as the “units” in matrix
algebra, in that they play much the same role as the number 1 in
standard multiplication.
The matrix \[I_3 =
\left [
\begin{array}{ccc}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1 \\
\end{array}
\right ]\] is the identity matrix of order 3.
Vectors
A matrix with a single column is a column vector.
A matrix with a single row is a row vector.
Vectors typically assumed to be column vectors unless explicitly
stated otherwise.
Vectors are a special type of matrix, and have their own
notation. Specifically, vectors are usually denoted by a bold, lower
case character, with elements specified by a single subscript.
R stores single column or single rows as matrices; R’s vectors
don’t know about direction.
The vector \[\boldsymbol{x} =
\left [
\begin{array}{c}
x_1 \\
x_2 \\
x_3 \\
\end{array}
\right ]
=
\left [
\begin{array}{c}
1.4 \\
0.5 \\
-0.3 \\
\end{array}
\right ]\] is a column vector. The vector \(\boldsymbol{v} = (4.2, 5.0)\) is a row
vector.
Matrix operations
Matrix Addition and Subtraction
An example of addition: \[\left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ]
+
\left [
\begin{array}{cc}
1 & 6 \\
4 & 2 \\
1 & 2 \\
\end{array}
\right ]
=
\left [
\begin{array}{cc}
4 & 10 \\
6 & 4 \\
5 & 3 \\
\end{array}
\right ].\] An example of subtraction: \[\left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ]
-
\left [
\begin{array}{cc}
1 & 6 \\
4 & 2 \\
1 & 2 \\
\end{array}
\right ]
=
\left [
\begin{array}{cc}
2 & -2 \\
-2 & 0 \\
3 & -1 \\
\end{array}
\right ].\]
Multiplication by a Scalar
Multiplication of a matrix by a scalar (i.e. a single number) is
achieved by multiplying each element of the matrix by that scalar.
If \[A = \left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ]\] then \[4A = \left [
\begin{array}{cc}
12 & 16 \\
8 & 8 \\
16 & 4 \\
\end{array}
\right ].\]
Matrix by Matrix Multiplication
For matrices A and B we can evaluate the
product AB only if the number of columns of A is the
same as the number of rows of B.
If the matrices are conformable in this way, then the
i,jth element of the product C=AB is given by \[c_{ij} = \sum_{k} a_{ik}
b_{kj}.\]
A Simple Matrix Product
Define \[A =
\left [
\begin{array}{ccc}
2 & 1 & 3\\
1 & 3 & 4 \\
\end{array}
\right ]\] and \[B =
\left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ]\]
Then \[AB =
\left [
\begin{array}{ccc}
2 & 1 & 3\\
1 & 3 & 4 \\
\end{array}
\right ]
\left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ]
=
\left [
\begin{array}{cc}
20 & 13 \\
25 & 14 \\
\end{array}
\right ].\]
A.mat = matrix(c(2, 1, 3, 1, 3, 4), nrow = 2, byrow = TRUE)
B.mat = matrix(c(3, 4, 2, 2, 4, 1), nrow = 3, byrow = TRUE)
A.mat %*% B.mat # do not use a single star here!
[,1] [,2]
[1,] 20 13
[2,] 25 14
N.B. You might see what happens if you don’t use the correct operator
%*%
in this last calculation.
Consider the matrices from the previous example. We will now compute
the product BA. We have
\[BA =
\left [
\begin{array}{cc}
3 & 4 \\
2 & 2 \\
4 & 1 \\
\end{array}
\right ]
\left [
\begin{array}{ccc}
2 & 1 & 3\\
1 & 3 & 4 \\
\end{array}
\right ]
=
\left [
\begin{array}{ccc}
10 & 15 & 25 \\
6 & 8 & 14 \\
9 & 7 & 16 \\
\end{array}
\right ]\]
B.mat %*% A.mat # do not use a single star
[,1] [,2] [,3]
[1,] 10 15 25
[2,] 6 8 14
[3,] 9 7 16
\(AB \ne BA\). In general matrix
multiplication is non-commutative; that is, the order
matters.
Product of Matrix by Vector
This follows exactly the same rules as for matrix by matrix
multiplication.
But if we use the single subscript notation for elements of
vectors, then the equations look a bit different.
Let A be an \(r \times
c\) matrix, and let \(\boldsymbol{v}\) be a column vector with
c elements.
Then if \(A\boldsymbol{v} =
\boldsymbol{x}\), we find that \(\boldsymbol{x}\) is also a column vector
but with r elements, defined by \[x_i = \sum_{j=1}^c a_{ij}v_j.\]
A Simple Product
Let \(A = \left [
\begin{array}{ccc}
2 & 1 & 3\\
1 & 3 & 4 \\
\end{array}
\right ]\) and \(\boldsymbol{v} = \left
[
\begin{array}{c}
4\\
0\\
2\\
\end{array}
\right ]\)
Then
\[A\boldsymbol{v} =
\left [
\begin{array}{ccc}
2 & 1 & 3\\
1 & 3 & 4\\
\end{array}
\right ]
\left [
\begin{array}{c}
4\\
0\\
2\\
\end{array}
\right ] = \left [
\begin{array}{c}
14\\
12\\
\end{array}
\right ] = \boldsymbol{x} \]
Operations specific to matrices
Matrix Transpose
The transpose of a matrix is obtained by
interchanging rows and columns.
- The transpose of \(\boldsymbol{A}\)
is denoted \(\boldsymbol{A}^T\) or
sometimes \(\boldsymbol{A}^t\) or \(\boldsymbol{A}^\prime\).
Using B as defined above, its transpose is given by \(\boldsymbol{B}^T = \left [
\begin{array}{ccc}
3 & 2 & 4\\
4 & 2 & 1\\
\end{array}
\right ]\).
[,1] [,2] [,3]
[1,] 3 2 4
[2,] 4 2 1
Properties of Transposition
There are numerous matrix manipulations that are used by software to
make calculations more efficient.
As an example, \((\boldsymbol{A}
\boldsymbol{B})^T = \boldsymbol{B}^T \boldsymbol{A}^T\).
Matrix/vector transposition proves useful in computing sums of
squares in statistics.
\(\boldsymbol{v}^T \boldsymbol{v} = \left [
v_1, v_2, \ldots, v_n \right ] \left [ \begin{array}{c}
v_1 \\ v_2 \\ \vdots \\ v_n \\
\end{array} \right ]
= v_1 \times v_1 + v_2 \times v_2 + \cdots v_n \times v_n =
\sum_{i=1}^{n} {v_i^2}\)
Matrix Inverse
For a given matrix A, the inverse matrix is denoted
A-1 and satisfies AA-1 = I =
A-1 A.
Only square matrices can have inverses, and even some square
matrices will be uninvertible or
singular.
A Simple Matrix and Its Inverse
Consider the matrix A defined by
\(A = \left [
\begin{array}{cc}
3 & 2 \\
1 & 2 \\
\end{array} \right ]\)
The inverse of this matrix is \(A^{-1}
= \left [ \begin{array}{cc}
\tfrac{1}{2} & -\tfrac{1}{2} \\
-\tfrac{1}{4} & \tfrac{3}{4} \\
\end{array} \right ]\)
A = matrix(c(3, 2, 1, 2), nrow = 2, byrow = TRUE)
solve(A)
[,1] [,2]
[1,] 0.50 -0.50
[2,] -0.25 0.75
As an exercise you should perform the matrix multiplication to
confirm that
\[A A^{-1} = \left [
\begin{array}{cc}
3 & 2 \\
1 & 2 \\
\end{array}
\right ]
\left [
\begin{array}{cc}
\tfrac{1}{2} & -\tfrac{1}{2} \\
-\tfrac{1}{4} & \tfrac{3}{4} \\
\end{array} \right ] = \left [
\begin{array}{cc}
1 & 0 \\
0 & 1 \\
\end{array} \right ] = I\]
and (or)
\[A^{-1} A = \left [ \begin{array}{cc}
\tfrac{1}{2} & -\tfrac{1}{2} \\
-\tfrac{1}{4} & \tfrac{3}{4} \\
\end{array} \right ] \left [ \begin{array}{cc}
3 & 2 \\
1 & 2 \\
\end{array} \right ]
= \left [ \begin{array}{cc}
1 & 0 \\
0 & 1 \\
\end{array} \right ]
= I.\]
Inverse of a 2 by 2 Matrix
In general evaluation of a matrix inverse is a tedious matter that is
best left to a computer. However, the calculation of the inverse of a 2
by 2 matrix is easy to do by hand.
The inverse of \(\left [ \begin{array}{cc}
a & b \\
c & d \\
\end{array} \right ]^{-1}
= \frac{1}{ad-bc} \left [ \begin{array}{cc}
d & -b \\
-c & a \\
\end{array} \right ]\), as long as \(ad-bc \ne 0\) (ad-bc=0 is very
unusual).
Exercise
confirm that this formula produces the inverse
A-1 in the previous Example.
LS0tDQp0aXRsZTogIkxlY3R1cmUgMTI6IEJhc2ljIE1hdHJpeCBBbGdlYnJhIg0Kc3VidGl0bGU6IDE2MS4yNTEgUmVncmVzc2lvbiBNb2RlbGxpbmcNCmF1dGhvcjogIlByZXNlbnRlZCBieSBKb25hdGhhbiBHb2RmcmV5IDxhLmouZ29kZnJleUBtYXNzZXkuYWMubno+IiAgDQpkYXRlOiAiV2VlayA0IG9mIFNlbWVzdGVyIDIsIGByIGx1YnJpZGF0ZTo6eWVhcihsdWJyaWRhdGU6Om5vdygpKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRoZW1lOiB5ZXRpDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICBodG1sX25vdGVib29rOg0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaW9zbGlkZXNfcHJlc2VudGF0aW9uOg0KICAgIHdpZGVzY3JlZW46IHRydWUNCiAgICBzbWFsbGVyOiB0cnVlDQogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgc2xpZHlfcHJlc2VudGF0aW9uOiANCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KDQoNCg0KDQpbVmlldyB0aGUgbGF0ZXN0IHJlY29yZGluZyBvZiB0aGlzIGxlY3R1cmVdKGh0dHBzOi8vUi1SZXNvdXJjZXMubWFzc2V5LmFjLm56L3ZpZGVvcy8yNTFMMTIubXA0KQ0KPCEtLS0gRGF0YSBpcyBvbg0KaHR0cHM6Ly9yLXJlc291cmNlcy5tYXNzZXkuYWMubnovZGF0YS8xNjEyNTEvDQotLS0+DQoNCmBgYHtyIHNldHVwLCBwdXJsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCm9wdHNfY2h1bmskc2V0KGRldj1jKCJwbmciLCAicGRmIikpDQpvcHRzX2NodW5rJHNldChmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD03LCBmaWcucGF0aD0iRmlndXJlcy8iLCBmaWcuYWx0PSJ1bmxhYmVsbGVkIikNCm9wdHNfY2h1bmskc2V0KGNvbW1lbnQ9IiIsIGZpZy5hbGlnbj0iY2VudGVyIiwgdGlkeT1UUlVFKQ0Kb3B0aW9ucyhrbml0ci5rYWJsZS5OQSA9ICcnKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGJyb29tKQ0KYGBgDQoNCg0KPCEtLS0gRG8gbm90IGVkaXQgYW55dGhpbmcgYWJvdmUgdGhpcyBsaW5lLiAtLS0+DQoNCldoaWxlIHRoZSB1c2Ugb2YgbWF0cml4IG5vdGF0aW9uIG1heSBzZWVtIHVubmVjZXNzYXJpbHkgY29tcGxpY2F0ZWQgIGF0IGZpcnN0LCB0aGVyZSBhcmUgZ29vZCByZWFzb25zIGZvciBsZWFybmluZyBhYm91dCBpdDoNCiAgICANCi0gTWFueSByZXN1bHRzIGZvciBsaW5lYXIgbW9kZWxzIGFyZSBtdWNoIG1vcmUgZWFzaWx5IGRlcml2ZWQgYW5kDQogICAgICAgIHVuZGVyc3Rvb2QgdXNpbmcgbWF0cml4IG5vdGF0aW9uIHRoYW4gd2l0aG91dCBpdC4NCiAgICANCi0gTWF0cml4IGZvcm11bGF0aW9uIG9mIGxpbmVhciBtb2RlbHMgaXMgdGhlIG5vcm0gaW4gc29tZSBhcmVhcyBvZg0KICAgICAgICBzY2llbmNlLCBzbyB3aWxsIGhlbHAgeW91IHVuZGVyc3RhbmQgdGhlIGxpdGVyYXR1cmUuDQoNCkluIHRoaXMgbGVjdHVyZSB3ZSB3aWxsIGNvdmVyIHRoZSBuZWNlc3NhcnkgdGVybWlub2xvZ3kgYW5kIG1hdHJpeCBhbGdlYnJhLg0KDQotIGV2ZW4gaWYgeW91IGhhdmUgYSBnb29kIHVuZGVyc3RhbmRpbmcgb2YgbWF0cmljZXMsIHlvdSB3aWxsIHNlZSBob3cgdmFyaW91cyBtYXRyaXggb3BlcmF0aW9ucyBhcmUgZG9uZSB1c2luZyBSLg0KDQotIHlvdSBkbyBub3QgbmVlZCB0byByZW1lbWJlciBhbGwgUiBjb21tYW5kcyBwcmVzZW50ZWQgaGVyZS4gVGhlcmUgaXMgYWx3YXlzIHRpbWUgdG8gY29tZSBiYWNrIGFuZCBmaW5kIHRoZW0gaWYgeW91IG5lZWQgc29tZXRoaW5nLg0KDQpXaGF0IHlvdSBuZWVkIHRvIGtub3cgYmVmb3JlIHdlIHN0YXJ0IGlzIHRoYXQgIG1hdHJpeCBhbGdlYnJhICBpcyB0aGUgd2F5IHRoYXQgUiBkb2VzIHByYWN0aWNhbGx5IGFsbCB0aGUgY2FsY3VsYXRpb25zIG5lZWRlZCAgZm9yIGZpdHRpbmcgbGluZWFyIG1vZGVscywgbm8gbWF0dGVyIHdoYXQga2luZCBvZiBsaW5lYXIgbW9kZWwgd2UgYXJlIGZpdHRpbmcuIFRoZSBsaW5lYXIgbW9kZWwgd29yayBjb21lcyBpbiB0aGUgbmV4dCBsZWN0dXJlLg0KDQoNCiMjIFdoYXQgaXMgYSBNYXRyaXg/DQoNCi0gQSBtYXRyaXggaXMgYSBjb2xsZWN0aW9uIG9mIG51bWJlcnMgYXJyYW5nZWQgaW4gYSByZWN0YW5ndWxhciBhcnJheS4NCg0KLSBNYXRyaWNlcyBhcmUgb2Z0ZW4gZGVub3RlZCB1c2luZyBjYXBpdGFsIGxldHRlcnMsIGJ1dCBub3RhdGlvbiBpcyBmYXIgZnJvbSBjb25zaXN0ZW50IGR1ZSB0byBjaGFuZ2VzIGluIHByZWZlcmVuY2UgYW5kIHR5cGVzZXR0aW5nIHRlY2hub2xvZ3kuDQoNCi0gSWYgYSBtYXRyaXggaGFzICpyKiByb3dzIGFuZCAqYyogY29sdW1ucyB0aGVuIHRoZSBtYXRyaXggaXMgKnIqIGJ5DQogICAgKmMqLg0KDQokJFggPSANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2NjY2NjfQ0KeF97MTF9ICYgeF97MTJ9ICYgXGNkb3RzICYgeF97MWp9ICYgXGNkb3RzICYgeF97MWN9IFxcDQp4X3syMX0gJiB4X3syMn0gJiBcY2RvdHMgJiB4X3syan0gJiBcY2RvdHMgJiB4X3syY30gXFwNClx2ZG90cyAmIFx2ZG90cyAmIFxkZG90cyAmIFx2ZG90cyAmIFxkZG90cyAmIFx2ZG90cyBcXA0KeF97aTF9ICYgeF97aTJ9ICYgXGNkb3RzICYgeF97aWp9ICYgXGNkb3RzICYgeF97aWN9IFxcDQpcdmRvdHMgJiBcdmRvdHMgJiBcZGRvdHMgJiBcdmRvdHMgJiBcZGRvdHMgJiBcdmRvdHMgXFwNCnhfe3IxfSAmIHhfe3IyfSAmIFxjZG90cyAmIHhfe3JqfSAmIFxjZG90cyAmIHhfe3JjfQ0KXGVuZHthcnJheX0NClxyaWdodCBdDQpcbGFiZWx7ZXE6bWF0cml4MX0kJA0KDQotICp4fmlqfiogZGVub3RlcyB0aGUgKmksaip0aCAqZWxlbWVudCogb2YgdGhlDQogICAgbWF0cml4ICpYKi4NCg0KIyMjIEEgU2ltcGxlIE1hdHJpeA0KDQpDb25zaWRlciBtYXRyaXggKkEqIGRlZmluZWQgYnkgJCRBID0gXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY30NCjMgJiA0IFxcDQoyICYgMiBcXA0KNCAmIDEgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXS4kJA0KDQotIFRoaXMgaXMgYSAzIGJ5IDIgbWF0cml4Lg0KDQpgYGB7ciBtYXRyaXhJbn0NCkEubWF0ID0gbWF0cml4KGMoMywgNCwgMiAsIDIgLCA0ICwgMSksIG5yb3c9MywgYnlyb3c9VFJVRSkNCmBgYA0KDQotIEl0cyBmaXJzdCByb3cgaXMgKigzLDQpKiBhbmQgaXRzIHNlY29uZCBjb2x1bW4gaXMgKig0LDIsMSkqLg0KDQoNCg0KLSBUaGUgKjEsMiogZWxlbWVudCwgKmF+MTJ+KiwgaXMgKjQqLg0KDQpgYGB7ciBmZXRjaEVsZW1lbnRzfQ0KQS5tYXRbMSxdDQpBLm1hdFssMl0NCkEubWF0WzEsMl0NCmBgYA0KDQoNCiMjIFR5cGVzIG9mIG1hdHJpY2VzDQoNCiMjIyBTcXVhcmUgTWF0cmljZXMNCg0KLSBNYXRyaXggd2l0aCBzYW1lIG51bWJlciBvZiByb3dzIGFzIGNvbHVtbnMgaXMgKipzcXVhcmUqKi4NCg0KLSBTcXVhcmUgbWF0cmljZXMgaGF2ZSBzb21lIG5pY2UgcHJvcGVydGllcywgbGlrZSBoYXZpbmcgYW4gKippbnZlcnNlKiogKGNvbWluZyBzb29uKS4NCg0KDQoNClRoZSBtYXRyaXggKkEqIGRlZmluZWQgYnkgJCRBID0gXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY30NCjEuNzQgJiA0LjExIFxcDQozLjExICYgMy4xNiBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdJCQgaXMgYSBzcXVhcmUgbWF0cml4LiBUaGUgbWFpbiBkaWFnb25hbCBvZiB0aGlzDQptYXRyaXggY29udGFpbnMgdGhlIGVsZW1lbnRzICoxLjc0KiBhbmQgKjMuMTYqLg0KDQpgYGB7ciBtYXRyaXhTcXVhcmV9DQpBLm1hdCA9IG1hdHJpeChjKDEuNzQsIDQuMTEsIDMuMTEsIDMuMTYpLCBucm93PTIsIGJ5cm93PVRSVUUpDQpkaWFnKEEubWF0KQ0KYGBgDQoNCg0KIyMjIFN5bW1ldHJpYyBNYXRyaWNlcw0KDQpNYXRyaXggd2l0aCBlbGVtZW50cyB0aGF0IGNhbiBiZSBkZWZpbmVkIGFzICp4fmlqfiA9IHh+aml+KiBmb3IgYWxsDQoqaSogYW5kICpqKiBpcyBjYWxsZWQgKipzeW1tZXRyaWMqKi4NCg0KDQoNClRoZSBtYXRyaXggKkEqIGRlZmluZWQgYnkgJCRBID0gXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY2N9DQozICYgLTIgJiAwIFxcDQotMiAmIDEgJiA0IFxcDQowICYgNCAmIDUgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSQkIGlzIGEgc3ltbWV0cmljIG1hdHJpeC4NCg0KIyMjIERpYWdvbmFsIE1hdHJpY2VzDQoNClRoZSBtYXRyaXggd2l0aCB6ZXJvIGVudHJpZXMgZXZlcnl3aGVyZSBhd2F5IGZyb20gdGhlIG1haW4vbGVhZGluZyBkaWFnb25hbCAodG9wIGxlZnQgdG8gYm90dG9tIHJpZ2h0KSBpcyBjYWxsZWQgKipkaWFnb25hbCoqLg0KDQoNCg0KVGhlIG1hdHJpeCAqQSogZGVmaW5lZCBieSAkJEEgPSBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjY30NCjMgJiAwICYgMCBcXA0KMCAmIDEgJiAwIFxcDQowICYgMCAmIDUgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSQkIGlzIGEgZGlhZ29uYWwgbWF0cml4Lg0KDQpgYGB7ciBEaWFnTWF0cml4fQ0KRC5tYXQgPC0gZGlhZyhjKDMsMSw1KSkNCkQubWF0DQpgYGANCg0KIyMjIElkZW50aXR5IE1hdHJpY2VzDQoNClRoZSBtYXRyaXggd2l0aCBvbmVzIGFsb25nIHRoZSBtYWluIGRpYWdvbmFsIGFuZCB6ZXJvIGVsZW1lbnRzDQogICAgZXZlcnl3aGVyZSBlbHNlIGlzIGNhbGxlZCB0aGUgKippZGVudGl0eSoqIG1hdHJpeC4NCg0KVGhlIGlkZW50aXR5IG1hdHJpeCAqSX5ufiogaXMgc2FpZCB0byBiZSBvZiAqKnNpemUqKiAob3IgKipvcmRlcioqKSAqbiosDQogICAgd2l0aCBkaW1lbnNpb25zICRuIFx0aW1lcyBuJC4NCg0KLSBJZGVudGl0eSBtYXRyaWNlcyBjYW4gYmUgdGhvdWdodCBvZiBhcyB0aGUgInVuaXRzIiBpbiBtYXRyaXgNCiAgICBhbGdlYnJhLCBpbiB0aGF0IHRoZXkgcGxheSBtdWNoIHRoZSBzYW1lIHJvbGUgYXMgdGhlIG51bWJlciAxIGluDQogICAgc3RhbmRhcmQgbXVsdGlwbGljYXRpb24uDQoNCg0KDQpUaGUgbWF0cml4ICQkSV8zID0gDQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjY30NCjEgJiAwICYgMCBcXA0KMCAmIDEgJiAwIFxcDQowICYgMCAmIDEgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSQkIGlzIHRoZSBpZGVudGl0eSBtYXRyaXggb2Ygb3JkZXIgKjMqLg0KDQojIyMgVmVjdG9ycw0KDQotIEEgbWF0cml4IHdpdGggYSBzaW5nbGUgY29sdW1uIGlzIGEgY29sdW1uIHZlY3Rvci4NCg0KLSBBIG1hdHJpeCB3aXRoIGEgc2luZ2xlIHJvdyBpcyBhIHJvdyB2ZWN0b3IuDQoNCi0gVmVjdG9ycyB0eXBpY2FsbHkgYXNzdW1lZCB0byBiZSBjb2x1bW4gdmVjdG9ycyB1bmxlc3MgZXhwbGljaXRseQ0KICAgIHN0YXRlZCBvdGhlcndpc2UuDQoNCi0gVmVjdG9ycyBhcmUgYSBzcGVjaWFsIHR5cGUgb2YgbWF0cml4LCBhbmQgaGF2ZSB0aGVpciBvd24gbm90YXRpb24uDQogICAgU3BlY2lmaWNhbGx5LCB2ZWN0b3JzIGFyZSB1c3VhbGx5IGRlbm90ZWQgYnkgYSBib2xkLCBsb3dlciBjYXNlDQogICAgY2hhcmFjdGVyLCB3aXRoIGVsZW1lbnRzIHNwZWNpZmllZCBieSBhIHNpbmdsZSBzdWJzY3JpcHQuDQoNCi0gUiBzdG9yZXMgc2luZ2xlIGNvbHVtbiBvciBzaW5nbGUgcm93cyBhcyBtYXRyaWNlczsgUidzIHZlY3RvcnMgZG9uJ3Qga25vdyBhYm91dCBkaXJlY3Rpb24uDQoNCg0KDQpUaGUgdmVjdG9yICQkXGJvbGRzeW1ib2x7eH0gPSANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y30NCiB4XzEgXFwNCiB4XzIgXFwNCiB4XzMgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXQ0KPQ0KXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjfQ0KIDEuNCBcXA0KIDAuNSBcXA0KLTAuMyBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdJCQgaXMgYSBjb2x1bW4gdmVjdG9yLiBUaGUgdmVjdG9yICRcYm9sZHN5bWJvbHt2fSA9ICg0LjIsIDUuMCkkIGlzIGEgcm93DQp2ZWN0b3IuDQoNCg0KIyMgTWF0cml4IG9wZXJhdGlvbnMNCg0KIyMjIE1hdHJpeCBBZGRpdGlvbiBhbmQgU3VidHJhY3Rpb24NCg0KLSBPbmx5IG1hdHJpY2VzIG9mIHRoZSBzYW1lIHNpemUgY2FuIGJlIGFkZGVkIG9yIHN1YnRyYWN0ZWQuDQoNCi0gQWRkaXRpb24gYW5kIHN1YnRyYWN0aW9uIGFyZSB0aGVuIGRvbmUgZWxlbWVudCBieSBlbGVtZW50Lg0KDQoNCg0KQW4gZXhhbXBsZSBvZiBhZGRpdGlvbjogJCRcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMyAmIDQgXFwNCjIgJiAyIFxcDQo0ICYgMSBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdIA0KKyANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQoxICYgNiBcXA0KNCAmIDIgXFwNCjEgJiAyIFxcDQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF0NCj0NClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQo0ICYgMTAgXFwNCjYgJiA0IFxcDQo1ICYgMyBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdLiQkIEFuIGV4YW1wbGUgb2Ygc3VidHJhY3Rpb246ICQkXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY30NCjMgJiA0IFxcDQoyICYgMiBcXA0KNCAmIDEgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSANCi0NClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQoxICYgNiBcXA0KNCAmIDIgXFwNCjEgJiAyIFxcDQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF0NCj0NClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQoyICYgLTIgXFwNCi0yICYgMCBcXA0KMyAmIC0xIFxcDQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF0uJCQNCg0KIyMjIE11bHRpcGxpY2F0aW9uIGJ5IGEgU2NhbGFyDQoNCk11bHRpcGxpY2F0aW9uIG9mIGEgbWF0cml4IGJ5IGEgc2NhbGFyIChpLmUuIGEgc2luZ2xlIG51bWJlcikgaXMNCiAgICBhY2hpZXZlZCBieSBtdWx0aXBseWluZyBlYWNoIGVsZW1lbnQgb2YgdGhlIG1hdHJpeCBieSB0aGF0IHNjYWxhci4NCg0KDQpJZiAkJEEgPSBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMyAmIDQgXFwNCjIgJiAyIFxcDQo0ICYgMSBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdJCQgdGhlbiAkJDRBID0gXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY30NCjEyICYgMTYgXFwNCjggJiA4IFxcDQoxNiAmIDQgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXS4kJA0KDQojIyMgTWF0cml4IGJ5IE1hdHJpeCBNdWx0aXBsaWNhdGlvbg0KDQotIEZvciBtYXRyaWNlcyAqQSogYW5kICpCKiB3ZSBjYW4gZXZhbHVhdGUgdGhlIHByb2R1Y3QgKkFCKiBvbmx5DQogICAgaWYgdGhlIG51bWJlciBvZiBjb2x1bW5zIG9mICpBKiBpcyB0aGUgc2FtZSBhcyB0aGUgbnVtYmVyIG9mIHJvd3MNCiAgICBvZiAqQiouDQoNCi0gSWYgdGhlIG1hdHJpY2VzIGFyZSBjb25mb3JtYWJsZSBpbiB0aGlzIHdheSwgdGhlbiB0aGUgKmksaip0aA0KICAgIGVsZW1lbnQgb2YgdGhlIHByb2R1Y3QgKkM9QUIqIGlzIGdpdmVuIGJ5DQogICAgJCRjX3tpan0gPSBcc3VtX3trfSBhX3tpa30gYl97a2p9LiQkDQoNCiMjIyBBIFNpbXBsZSBNYXRyaXggUHJvZHVjdA0KDQpEZWZpbmUgJCRBID0gDQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjY30NCjIgJiAxICYgM1xcDQoxICYgMyAmIDQgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSQkIGFuZCAkJEIgPSANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQozICYgNCBcXA0KMiAmIDIgXFwNCjQgJiAxIFxcDQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF0kJA0KDQpUaGVuICQkQUIgPSANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2NjfQ0KMiAmIDEgJiAzXFwNCjEgJiAzICYgNCBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdDQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMyAmIDQgXFwNCjIgJiAyIFxcDQo0ICYgMSBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdDQo9DQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMjAgJiAxMyBcXA0KMjUgJiAxNCBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdLiQkDQoNCg0KYGBge3IgTWF0cml4UHJvZDF9DQpBLm1hdCA9IG1hdHJpeChjKDIsMSwzLDEsMyw0KSwgbnJvdz0yLCBieXJvdz1UUlVFKQ0KQi5tYXQgPSBtYXRyaXgoYygzLDQsMiwyLDQsMSksIG5yb3c9MywgYnlyb3c9VFJVRSkNCkEubWF0JSolQi5tYXQgIyBkbyBub3QgdXNlIGEgc2luZ2xlIHN0YXIgaGVyZSENCmBgYA0KDQpOLkIuIFlvdSBtaWdodCBzZWUgd2hhdCBoYXBwZW5zIGlmIHlvdSBkb24ndCB1c2UgdGhlIGNvcnJlY3Qgb3BlcmF0b3IgYCUqJWAgaW4gdGhpcyBsYXN0IGNhbGN1bGF0aW9uLg0KDQoNCkNvbnNpZGVyIHRoZSBtYXRyaWNlcyBmcm9tIHRoZSBwcmV2aW91cyBleGFtcGxlLiBXZSB3aWxsIG5vdyBjb21wdXRlIHRoZQ0KcHJvZHVjdCAqQkEqLiBXZSBoYXZlIA0KDQokJEJBID0gDQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMyAmIDQgXFwNCjIgJiAyIFxcDQo0ICYgMSBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdDQpcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjY30NCjIgJiAxICYgM1xcDQoxICYgMyAmIDQgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXQ0KPQ0KXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY2N9DQoxMCAmIDE1ICYgMjUgXFwNCiA2ICYgOCAmIDE0IFxcDQogOSAmIDcgJiAxNiBcXA0KXGVuZHthcnJheX0NClxyaWdodCBdJCQNCg0KYGBge3IgTWF0cml4UHJvZDJ9DQpCLm1hdCUqJUEubWF0ICMgZG8gbm90IHVzZSBhIHNpbmdsZSBzdGFyDQpgYGANCg0KDQokQUIgXG5lIEJBJC4gSW4gZ2VuZXJhbCBtYXRyaXggbXVsdGlwbGljYXRpb24gaXMgKipub24tY29tbXV0YXRpdmUqKjsgdGhhdCBpcywgdGhlIG9yZGVyIG1hdHRlcnMuDQoNCiMjIyBQcm9kdWN0IG9mIE1hdHJpeCBieSBWZWN0b3INCg0KVGhpcyBmb2xsb3dzIGV4YWN0bHkgdGhlIHNhbWUgcnVsZXMgYXMgZm9yIG1hdHJpeCBieSBtYXRyaXggbXVsdGlwbGljYXRpb24uDQoNCi0gQnV0IGlmIHdlIHVzZSB0aGUgc2luZ2xlIHN1YnNjcmlwdCBub3RhdGlvbiBmb3IgZWxlbWVudHMgb2YgdmVjdG9ycywgICAgIHRoZW4gdGhlIGVxdWF0aW9ucyBsb29rIGEgYml0IGRpZmZlcmVudC4NCg0KLSBMZXQgKkEqIGJlIGFuICRyIFx0aW1lcyBjJCBtYXRyaXgsIGFuZCBsZXQgJFxib2xkc3ltYm9se3Z9JCBiZQ0KICAgIGEgY29sdW1uIHZlY3RvciB3aXRoICpjKiBlbGVtZW50cy4NCg0KLSBUaGVuIGlmICRBXGJvbGRzeW1ib2x7dn0gPSBcYm9sZHN5bWJvbHt4fSQsIHdlIGZpbmQgdGhhdCAkXGJvbGRzeW1ib2x7eH0kIGlzIGFsc28gYSBjb2x1bW4gdmVjdG9yDQogICAgYnV0IHdpdGggKnIqIGVsZW1lbnRzLCBkZWZpbmVkIGJ5DQogICAgJCR4X2kgPSBcc3VtX3tqPTF9XmMgYV97aWp9dl9qLiQkDQoNCiMjIyBBIFNpbXBsZSBQcm9kdWN0DQoNCkxldCAgJEEgPSBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjY30NCjIgJiAxICYgM1xcDQoxICYgMyAmIDQgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSQgYW5kICAkXGJvbGRzeW1ib2x7dn0gPSBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2N9DQo0XFwNCjBcXA0KMlxcDQpcZW5ke2FycmF5fQ0KXHJpZ2h0IF0kIA0KDQpUaGVuIA0KDQokJEFcYm9sZHN5bWJvbHt2fSA9IA0KXGxlZnQgWw0KXGJlZ2lue2FycmF5fXtjY2N9DQoyICYgMSAmIDNcXA0KMSAmIDMgJiA0XFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSANClxsZWZ0IFsNClxiZWdpbnthcnJheX17Y30NCjRcXA0KMFxcDQoyXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSA9IFxsZWZ0IFsNClxiZWdpbnthcnJheX17Y30NCjE0XFwNCjEyXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXSA9IFxib2xkc3ltYm9se3h9ICQkDQoNCiMjIE9wZXJhdGlvbnMgc3BlY2lmaWMgdG8gbWF0cmljZXMNCg0KIyMjIE1hdHJpeCBUcmFuc3Bvc2UNCg0KVGhlICoqdHJhbnNwb3NlKiogb2YgYSBtYXRyaXggaXMgb2J0YWluZWQgYnkgaW50ZXJjaGFuZ2luZyByb3dzIGFuZA0KICAgIGNvbHVtbnMuDQoNCi0gVGhlIHRyYW5zcG9zZSBvZiAkXGJvbGRzeW1ib2x7QX0kIGlzIGRlbm90ZWQgJFxib2xkc3ltYm9se0F9XlQkIG9yIHNvbWV0aW1lcyAkXGJvbGRzeW1ib2x7QX1edCQgb3IgJFxib2xkc3ltYm9se0F9XlxwcmltZSQuDQoNCg0KVXNpbmcgKkIqIGFzIGRlZmluZWQgYWJvdmUsIGl0cyB0cmFuc3Bvc2UgaXMgZ2l2ZW4gYnkgJFxib2xkc3ltYm9se0J9XlQgPSBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjY30NCjMgJiAyICYgNFxcDQo0ICYgMiAmIDFcXCANClxlbmR7YXJyYXl9DQpccmlnaHQgXSQuDQoNCmBgYHtyIHRyYW5zcG9zZX0NCnQoQi5tYXQpDQpgYGANCg0KIyMjIFByb3BlcnRpZXMgb2YgVHJhbnNwb3NpdGlvbg0KDQpUaGVyZSBhcmUgbnVtZXJvdXMgbWF0cml4IG1hbmlwdWxhdGlvbnMgdGhhdCBhcmUgdXNlZCBieSBzb2Z0d2FyZSB0byBtYWtlIGNhbGN1bGF0aW9ucyBtb3JlIGVmZmljaWVudC4NCg0KQXMgYW4gZXhhbXBsZSwgJChcYm9sZHN5bWJvbHtBfSBcYm9sZHN5bWJvbHtCfSleVCA9IFxib2xkc3ltYm9se0J9XlQgXGJvbGRzeW1ib2x7QX1eVCQuDQoNCk1hdHJpeC92ZWN0b3IgdHJhbnNwb3NpdGlvbiBwcm92ZXMgdXNlZnVsIGluIGNvbXB1dGluZyBzdW1zIG9mIHNxdWFyZXMgaW4NCiAgICBzdGF0aXN0aWNzLiANCg0KJFxib2xkc3ltYm9se3Z9XlQgXGJvbGRzeW1ib2x7dn0gPSBcbGVmdCBbIHZfMSwgdl8yLCBcbGRvdHMsIHZfbiBccmlnaHQgXSAgICAgXGxlZnQgWyAgICAgXGJlZ2lue2FycmF5fXtjfQ0KICAgICB2XzEgXFwgICAgICB2XzIgXFwgICAgICBcdmRvdHMgXFwgICAgICB2X24gXFwNCiAgICBcZW5ke2FycmF5fSAgICAgXHJpZ2h0IF0NCiAgICA9IHZfMSBcdGltZXMgdl8xICsgdl8yIFx0aW1lcyB2XzIgKyBcY2RvdHMgdl9uIFx0aW1lcyB2X24gPSBcc3VtX3tpPTF9XntufSB7dl9pXjJ9JA0KDQojIyMgTWF0cml4IEludmVyc2UNCg0KLSBGb3IgYSBnaXZlbiBtYXRyaXggKkEqLCB0aGUgaW52ZXJzZSBtYXRyaXggaXMgZGVub3RlZCAqQV4tMV4qDQogICAgYW5kIHNhdGlzZmllcyAqQUFeLTFeID0gSSA9IEFeLTFeIEEqLg0KDQotIE9ubHkgc3F1YXJlIG1hdHJpY2VzIGNhbiBoYXZlIGludmVyc2VzLCBhbmQgZXZlbiBzb21lIHNxdWFyZQ0KICAgIG1hdHJpY2VzIHdpbGwgYmUgKip1bmludmVydGlibGUqKiBvciAqKnNpbmd1bGFyKiouDQoNCiMjIyBBIFNpbXBsZSBNYXRyaXggYW5kIEl0cyBJbnZlcnNlDQoNCkNvbnNpZGVyIHRoZSBtYXRyaXggKkEqIGRlZmluZWQgYnkgDQoNCiRBID0gIFxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQozICYgMiBcXA0KMSAmIDIgXFwNClxlbmR7YXJyYXl9IFxyaWdodCBdJCANCg0KVGhlIGludmVyc2Ugb2YgdGhpcyBtYXRyaXggaXMgICRBXnstMX0gPSAgXGxlZnQgWyBcYmVnaW57YXJyYXl9e2NjfQ0KXHRmcmFjezF9ezJ9ICYgLVx0ZnJhY3sxfXsyfSBcXA0KLVx0ZnJhY3sxfXs0fSAmIFx0ZnJhY3szfXs0fSBcXA0KXGVuZHthcnJheX0gXHJpZ2h0IF0kIA0KDQoNCmBgYHtyIE1hdHJpeEFuZEludmVyc2V9DQpBID0gbWF0cml4KGMoMywyLDEsMiksIG5yb3c9MiwgYnlyb3c9VFJVRSkNCnNvbHZlKEEpDQpgYGANCg0KQXMgYW4gZXhlcmNpc2UgeW91IHNob3VsZCBwZXJmb3JtIHRoZSBtYXRyaXggbXVsdGlwbGljYXRpb24NCnRvIGNvbmZpcm0gdGhhdCANCg0KJCRBIEFeey0xfSA9IFxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQozICYgMiBcXA0KMSAmIDIgXFwNClxlbmR7YXJyYXl9DQpccmlnaHQgXQ0KIFxsZWZ0IFsNClxiZWdpbnthcnJheX17Y2N9DQpcdGZyYWN7MX17Mn0gJiAtXHRmcmFjezF9ezJ9IFxcDQotXHRmcmFjezF9ezR9ICYgXHRmcmFjezN9ezR9IFxcDQpcZW5ke2FycmF5fSBccmlnaHQgXSA9ICBcbGVmdCBbDQpcYmVnaW57YXJyYXl9e2NjfQ0KMSAmIDAgXFwNCjAgJiAxIFxcDQpcZW5ke2FycmF5fSBccmlnaHQgXSA9IEkkJCANCg0KYW5kIChvcikgDQoNCiQkQV57LTF9IEEgPSAgIFxsZWZ0IFsgXGJlZ2lue2FycmF5fXtjY30NClx0ZnJhY3sxfXsyfSAmIC1cdGZyYWN7MX17Mn0gXFwNCi1cdGZyYWN7MX17NH0gJiBcdGZyYWN7M317NH0gXFwNClxlbmR7YXJyYXl9IFxyaWdodCBdICBcbGVmdCBbIFxiZWdpbnthcnJheX17Y2N9DQozICYgMiBcXA0KMSAmIDIgXFwNClxlbmR7YXJyYXl9IFxyaWdodCBdDQo9ICBcbGVmdCBbIFxiZWdpbnthcnJheX17Y2N9DQoxICYgMCBcXA0KMCAmIDEgXFwNClxlbmR7YXJyYXl9IFxyaWdodCBdDQo9IEkuJCQNCg0KIyMjIEludmVyc2Ugb2YgYSAyIGJ5IDIgTWF0cml4DQoNCkluIGdlbmVyYWwgZXZhbHVhdGlvbiBvZiBhIG1hdHJpeCBpbnZlcnNlIGlzIGEgdGVkaW91cyBtYXR0ZXIgdGhhdCBpcw0KYmVzdCBsZWZ0IHRvIGEgY29tcHV0ZXIuIEhvd2V2ZXIsIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgaW52ZXJzZSBvZiBhIDINCmJ5IDIgbWF0cml4IGlzIGVhc3kgdG8gZG8gYnkgaGFuZC4NCg0KVGhlIGludmVyc2Ugb2YgJFxsZWZ0IFsgXGJlZ2lue2FycmF5fXtjY30NCmEgJiBiIFxcDQpjICYgZCBcXA0KXGVuZHthcnJheX0gXHJpZ2h0IF1eey0xfQ0KPSBcZnJhY3sxfXthZC1iY30gXGxlZnQgWyBcYmVnaW57YXJyYXl9e2NjfQ0KZCAmIC1iIFxcDQotYyAmIGEgXFwNClxlbmR7YXJyYXl9IFxyaWdodCBdJCwgYXMgbG9uZyBhcyAkYWQtYmMgXG5lIDAkICgqYWQtYmM9MCogaXMgIHZlcnkgdW51c3VhbCkuDQoNCg0KIyMjIEV4ZXJjaXNlDQoNCiBjb25maXJtIHRoYXQgdGhpcyBmb3JtdWxhIHByb2R1Y2VzIHRoZSBpbnZlcnNlICpBXi0xXiogaW4gdGhlIHByZXZpb3VzIEV4YW1wbGUuDQoNCg==