Material base para a disciplina Estatística Multivariada com aplicações no R. Neste primeiro momento mostra-se as principais definições algébricas para um melhor entendimento de como uma componente principal é construída.

1 Primeiros passos no R

  • O R vem com as configurações mínimas ao ser instalado. Para realizar tarefas mais específicas pode ser necessário instalar pacotes adicionais (packages), clicando em “pacotes>>instalar pacotes”;

  • É necessário escolher o CRAN (Comprehensive R Archive Network), que são arquivos disponibilizados na rede por diversas IES do mundo inteiro, inclusive do Brasil.

  • O R é case-sensitive, isto é, ele diferencia letras minúsculas de maiúsculas;

  • O separador de casas decimais é o “.”;

  • A vírgula é usada para separar argumentos;

  • O prompt do R é o sinal de maior “>”;

  • Após instalarmos algum pacote sempre será necessário carregá-lo com o comando: library(“nome do pacote”);

  • Para verificar como citar o pacote instalado digite: citation(“nome do pacote”);

  • Para obter ajuda dos arquivos do R use o comando help(nome da função).

Exemplos:

# help(sqrt) #ajuda sobre a função raiz quadrada
# help(lm) # ajuda sobre a função linear models

1.1 Primeiros comandos

  • Algumas Demonstrações do uso do R
#demo(graphics) #pressione Enter 
#demo(persp)
#demo(image)

1.2 Criando objetos, vetores com valores numéricos

Vamos crias um vetor de notas de 10 alunos da turma. A função length(notas) fornece o número de observações (n) dentro do objeto.

OBS: o comando <- significa assinalar; o comando c significa concatenar (colocar junto).

notas = c(9,6,8,5,7,8,6,9,10,6)
print(notas)
##  [1]  9  6  8  5  7  8  6  9 10  6
length(notas)
## [1] 10

Para objetos com letras (variáveis qualitativas), basta colocar cada observação entre aspas.

Para listar quais objetos temos salvo utiliza-se a função ls().

Para remover um objeto: rm(“nome do objeto”).

letras<-c("a","b","c","d")
print(letras)
## [1] "a" "b" "c" "d"
ls()
## [1] "letras" "notas"

1.3 Gerando um sequência:

  • Pode-se usar os comandos:

1:10: sequência de 1 até 10, de um em um. seq(from = 1, to = 10, by = 2 ), isto é, sequência(de um, a dez, em intervalos de 2). Ou ainda seq(1,100,5): sequência de 1 a 100 em intervalos de 5

1:10
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(from = 1, to = 10, by = 2 )
## [1] 1 3 5 7 9
seq(1,100,5)
##  [1]  1  6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96

1.4 Gerando dados aleatórios

  • rbinom(n, size, prob): gera uma distribuição aleatória Binomial com n valores (observações), número de tentativas size e probabilidade de sucesso prob.

  • rgeom(n, prob): gera uma distribuição aleatória Geométrica com n valores e probabilidade de sucesso prob.

  • rpois(n, lambda): gera uma distribuição aleatória Poisson com n valores e vetor de médias lambda.

  • runif(n, min=0, max=1): gera uma distribuição aleatória Uniforme contínua com n valores, começando em min e terminando em max.

  • rexp(n, rate = 1): gera uma distribuição aleatória Exponencial com n valores e taxa rate.

  • rnorm(n, mean = 0, sd = 1)): gera uma distribuição aleatória Normal com n valores, média mean e desvio padrão sd.

rbinom(10, 4, 0.2)
##  [1] 1 1 0 1 1 0 2 0 0 0
rgeom(5,0.1)
## [1]  5  7  3 14  5
rpois(8,2)
## [1] 5 0 4 1 2 0 1 2
rexp(6,1)
## [1] 1.6847840 0.7725487 1.4494138 0.2872838 0.4492415 0.8446422
runif(4, 0.2,.9)
## [1] 0.5897873 0.7366440 0.8084414 0.2808867
rnorm(7)
## [1] -1.7806223 -0.3069625 -0.2735254 -1.0578858 -0.4629794  2.0556548 -1.1621014
  • Histograma da distribuição Normal
x1 = rnorm(200)
hist(x1,
     col = "lightblue",
     freq = F,
     main = "",
     xlab = "Dados de X~N(0,1)",
     ylab = "f(x): f.d.p. de X",
     breaks = 20)
curve(dnorm(x,mean = mean(x1),sd=sd(x1)),add = T)

Exemplo

sample(1:10,5) # tira 5 amostras com valores entre 1 e 10 
## [1] 8 9 4 1 5

Como não especificamos o argumento replace o padrão é considerar que a amostra é sem reposição (= FALSE).

sample(1:10,15,replace=TRUE)
##  [1]  9  9  1  3  3  4 10  2  4  4  6  6  7  7  2

Lembram dos exemplos da moeda em probabilidade? Então,

moeda = c("C","K") # primeiro criamos a moeda 
sample(moeda,10,replace=TRUE) # não podemos esquecer do TRUE
##  [1] "C" "C" "K" "C" "K" "C" "C" "C" "K" "K"

2 Escalares, vetores e matrizes

2.1 Escalar

\[ x = \boldsymbol{x}_{1,1} = x_{i} \]

2.2 Vetor coluna

\[\begin{eqnarray*}\boldsymbol{x}=\boldsymbol{x}_{n,1}=\left[ \begin{array}{c} x_{1} \\ x_{2} \\ \vdots \\ x_{n} \\ \end{array} \right] \end{eqnarray*}\]

2.3 Vetor linha

\[\begin{eqnarray*}\boldsymbol{x}^{'}=\boldsymbol{x}_{1,p}=\left[ \begin{array}{c} x_{1}, x_{2},...,x_{n} \\ \end{array} \right] \end{eqnarray*}\]

2.4 Matriz

As matrizes e os sistemas lineares têm larga aplicação em problemas práticos. Dá-se o nome de matriz a uma tabela organizada em linhas e colunas, denotadas por \(\boldsymbol{X}=[x_{ij}]_{m\times n}\), onde o par de índices \(ij\) representa a posição de cada elemento \(x_{ij}\) dentro da matriz, sendo que o índice \(i\) indica a linha e o índice \(j\) a coluna. O par de índice \(m \times n\) é chamado de dimensão da matriz e representa o seu tamanho. O índice \(m\) indica o número de linhas e \(n\), o número de colunas

\[\begin{eqnarray*}\boldsymbol{X}=\left[ \begin{array}{cccc} x_{11} & x_{12} & \dots & x_{1n}\\ x_{21} & x_{22} & \dots & x_{2n}\\ \vdots & \vdots & \ddots & \vdots\\ x_{m1} & x_{m2} & \dots & x_{mn}\\ \end{array} \right] \end{eqnarray*}\]
  • Inserindo uma matriz no R

Para inserir uma matriz no R utiliza-se a função matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL). Note que, basta colocar como argumentos o conjunto de dados e indicar o número de linhas e de colunas da matriz.

M1 = matrix(data = 1:9, nrow = 3, ncol = 3)

print(M1)
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

Observe que a matriz foi organizada por default por colunas. Entretanto, podemos mudar isso para linhas utilizando-se o argumento byrow = TRUE na função matrix.

M2 = matrix(data = 1:9, nrow = 3, ncol = 3, byrow = TRUE)

print(M2)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

Se tivermos um ou mais vetores para formar uma matriz, basta informar o número de linhas do vetor.

Exemplo: Uma seleção de 4 firmas de ração de Minas Gerais foi obtida para avaliar a venda de rações. Cada observação bivariada forneceu a quantidade de sacos de ração vendidos e a quantidade de reais de cada venda. Os dados obtidos na forma tabular são:

\[\begin{eqnarray*} \begin{array}{l|cccc}\hline \text{Váriavel 1 (reais/vendas)} & 80 & 120 & 90 & 110 \\ \hline \text{Váriavel 2 (número de sacos de ração vendidos)} & 10 & 12 & 6 & 8\\ \hline \end{array} \end{eqnarray*}\]
M_E1 = matrix(c(80,120,90,110,10,12,6,8),4,2)
print(M_E1)
##      [,1] [,2]
## [1,]   80   10
## [2,]  120   12
## [3,]   90    6
## [4,]  110    8
  • Índice das matrizes

Pode-se acessar os elementos de uma matriz usando o nome do objeto (matriz) seguido de colchetes. Para acessar o segundo elemento da variável 1, no exemplo anterior, M_E1[2,1]. Para o terceiro elemento da variável 2, M_E1[3,2]. E, para selecionar todos os elementos da variável 1, M_E1[,1].

M_E1[2,1] # segundo elemento da variável 1
## [1] 120
M_E1[3,2] # terceiro elemento da variável 2
## [1] 6
M_E1[,1] # todos os elementos da variável 1
## [1]  80 120  90 110

2.5 Operações com matrizes

2.5.1 Adição de matrizes

Dadas duas matrizes de mesma dimensão \(A=[a_{ij}]_{m\times n}\) e \(B=[b_{ij}]_{m\times n}\), temos que \(A + B = [a_{ij} + b_{ij}]\).

\[\begin{eqnarray*}\left[ \begin{array}{cc} a_{11} & a_{12} \\ a_{21} & a_{22} \\ \end{array} \right] + \left[ \begin{array}{cc} b_{11} & b_{12} \\ b_{21} & b_{22} \\ \end{array} \right] = \left[ \begin{array}{cc} a_{11} + b_{11} & a_{12} + b_{12} \\ a_{21} + b_{21} & a_{22} + b_{22} \\ \end{array} \right] \end{eqnarray*}\]

Exemplo: Dadas as matrizes

\[\begin{eqnarray*}A=\left[ \begin{array}{cccc} -1 & 2 & 10 & 8 \\ 2 & 0 & -3 & 3 \\ 0 & 5 & -8 & 1 \\ \end{array} \right] \quad \text{e}\quad B = \left[ \begin{array}{cccc} 0 & 3 & -2 & 7 \\ 3 & -4 & 9 & 2 \\ 21 & 0 & -1 & 12 \\ \end{array} \right], \text{temos que} \end{eqnarray*}\]
A = matrix(c(-1,2,10,8,2,0,-3,3,0,5,-8,1),3,4, byrow = TRUE)
print(A)
##      [,1] [,2] [,3] [,4]
## [1,]   -1    2   10    8
## [2,]    2    0   -3    3
## [3,]    0    5   -8    1
B = matrix(c(0,3,-2,7,3,-4,9,2,21,0,-1,12),3,4,byrow = TRUE)
print(B)
##      [,1] [,2] [,3] [,4]
## [1,]    0    3   -2    7
## [2,]    3   -4    9    2
## [3,]   21    0   -1   12
S_AB = A + B # soma das matrizes A e B
print(S_AB)
##      [,1] [,2] [,3] [,4]
## [1,]   -1    5    8   15
## [2,]    5   -4    6    5
## [3,]   21    5   -9   13

2.5.2 Multiplicação de uma matriz por um escalar

Dada uma matriz \(A=[a_{ij}]_{m\times n}\) e um número real \(k\), temos que \(k \times A=[k \times a_{ij}]_{m\times n}\).

\[\begin{eqnarray*}k \times A=[k \times a_{ij}]_{m\times n} = k \times \left[ \begin{array}{cc} a_{11} & a_{12} \\ a_{21} & a_{22} \\ \end{array} \right] \longrightarrow \left[ \begin{array}{cc} k \times a_{11} & k \times a_{12} \\ k \times a_{21} & k \times a_{22} \\ \end{array} \right] \end{eqnarray*}\]

Exemplo: Dada a matriz A do exemplo anterior, pode-se multiplicar essa matriz por qualquer escalar \(k\). Por exemplo, para \(k = -3\), temos

k = 3 # denifindo um escalar qualquer
A = matrix(c(-1,2,10,8,2,0,-3,3,0,5,-8,1),3,4, byrow = TRUE)
print(A)
##      [,1] [,2] [,3] [,4]
## [1,]   -1    2   10    8
## [2,]    2    0   -3    3
## [3,]    0    5   -8    1
kA = k*A
print(kA)
##      [,1] [,2] [,3] [,4]
## [1,]   -3    6   30   24
## [2,]    6    0   -9    9
## [3,]    0   15  -24    3

2.5.3 Multiplicação de matrizes

Dadas duas matrizes \(A=[a_{ij}]_{m\times n}\) e \(B=[b_{jk}]_{n\times p}\), temos que \(A\times B = C[c_{ik}]_{m\times p}\). Vale ressaltar que este produto só será possível se o número de colunas de \(A\) for igual ao número de linhas de \(B\).

Exemplo: Dadas as matrizes

\[\begin{eqnarray*} A = \left[ \begin{array}{ccc} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ \end{array} \right] \quad \text{e} \quad B= \left[ \begin{array}{cc} b_{11} & b_{12} \\ a_{21} & a_{22} \\ a_{31} & a_{32} \\ \end{array} \right] \end{eqnarray*}\]

Observe que o número de colunas da matriz \(A\) é igual ao número de linhas da matriz \(B\), portanto, por definição temos que a matriz \(C\) terá dimensão \(2\times 2\), como segue

\[\begin{eqnarray*} C = \left[ \begin{array}{cc} c_{11} & c_{12} \\ c_{21} & c_{22} \\ \end{array} \right], \quad \text{em que} \end{eqnarray*}\] \[\begin{eqnarray*} \begin{array}{cc} c_{11} = & a_{11}b_{11}+a_{12}b_{21}+a_{13}b_{31} \\ c_{12} = & a_{11}b_{12}+a_{12}b_{22}+a_{13}b_{32} \\ c_{21} = & a_{21}b_{11}+a_{22}b_{21}+a_{23}b_{31} \\ c_{22} = & a_{21}b_{12}+a_{22}b_{22}+a_{23}b_{32} \\ \end{array} \end{eqnarray*}\]

No R o produto de matrizes é feito pelo uso do operador %*%.

Exercício: Sejam as matrizes

\[\begin{eqnarray*} X = \left[ \begin{array}{cc} 2 & -1 \\ 0 & 1 \\ \end{array} \right], Y = \left[ \begin{array}{ccc} 5 & 0 & 1 \\ 2 & -1 & 3 \\ \end{array} \right] \quad \text{e} \quad Z = \left[ \begin{array}{cc} 4 & -8 \\ 1 & 0 \\ \end{array} \right] \end{eqnarray*}\]

Determine:

  1. \(2X+Y\)

  2. \(XY\)

  3. \(Y+Z\)

  4. \(YZ\)

  5. \((X-3Z)Y\)

  6. \(X^{2}\)

2.5.4 Transposta de uma matriz

Dada a matriz \(A=[a_{ij}]_{m\times n}\), sua transposta é dada por \(A^{t}=[a_{ji}]_{n\times m}\).

Exemplo: Dada a matriz

\[\begin{eqnarray*} A = \left[ \begin{array}{ccc} 1 & 2 & 7 \\ 4 & -3 & 8 \\ \end{array} \right]_{2\times 3} \quad \text{sua transposta é} \quad A^{t} = \left[ \begin{array}{rr} 1 & 4 \\ 2 & -3 \\ 7 & 8 \\ \end{array} \right]_{3\times 2} \end{eqnarray*}\]

No R utiliza-se a função t() para obter a transposta de uma matriz.

A = matrix(c(1,5,2,-3,7,8),2,3)
print(A)
##      [,1] [,2] [,3]
## [1,]    1    2    7
## [2,]    5   -3    8
A_t = t(A)
print(A_t)
##      [,1] [,2]
## [1,]    1    5
## [2,]    2   -3
## [3,]    7    8

2.5.5 Determinante de uma matriz

  • Dada a matriz \(A[a_{11}]\), temos que \(det(A) = a_{11}\).

  • Dada a matriz

\[\begin{eqnarray*} A = \left[ \begin{array}{cc} a_{11} & a_{12} \\ a_{21} & a_{22} \\ \end{array} \right], \end{eqnarray*}\]

seu determinante é:

\[\begin{eqnarray*} det(A) = \left| \begin{array}{cc} a_{11} & a_{12} \\ a_{21} & a_{22} \\ \end{array} \right| = a_{11}a_{22}-a_{12}a_{21} \end{eqnarray*}\]

Exemplo: Dada a matriz

\[\begin{eqnarray*} A = \left[ \begin{array}{rr} -3 & 2 \\ 4 & 2 \\ \end{array} \right], \end{eqnarray*}\]

seu determinante é:

\[\begin{eqnarray*} det(A) = \left| \begin{array}{rr} -3 & 2 \\ 4 & 2 \\ \end{array} \right| = (-3.2)-(2.4) = -14 \end{eqnarray*}\]

Seja a matriz \(A_{3\times 3}\),

\[\begin{eqnarray*} A = \left[ \begin{array}{ccc} a_{11} & a_{12} & a_{13}\\ a_{21} & a_{22} & a_{23}\\ a_{31} & a_{32} & a_{33}\\ \end{array} \right], \end{eqnarray*}\]

seu determinante é calculado pela regra de Sarrus da seguinte maneira

\[\begin{eqnarray*} det(A)= \left| \begin{array}{ccc|cc} a_{11} & a_{12} & a_{13} & a_{11} & a_{12}\\ a_{21} & a_{22} & a_{23} & a_{21} & a_{21}\\ a_{31} & a_{32} & a_{33} & a_{31} & a_{32}\\ \end{array} \right| \end{eqnarray*}\] \[\begin{eqnarray*} \begin{array}{c} = a_{11}a_{22}a_{33} + a_{12}a_{23}a_{31} + a_{13}a_{21}a_{32} + \\ - (a_{13}a_{22}a_{31} + a_{11}a_{23}a_{32} + a_{12}a_{21}a_{33})\\ \end{array} \end{eqnarray*}\]

Exemplo: Dada a matriz

\[\begin{eqnarray*} A = \left[ \begin{array}{rrr} 1 & 2 & 0 \\ -1 & 3 & 2 \\ 3 &-4 & 2 \\ \end{array} \right], \end{eqnarray*}\]

seu determinante é:

\[\begin{eqnarray*} det(A) = \left| \begin{array}{rrr|rr} 1 & 2 & 0 & 1 & 2 \\ -1 & 3 & 2 &-1 & 3\\ 3 &-4 & 2 & 3 &-4\\ \end{array} \right| \end{eqnarray*}\] \[\begin{eqnarray*} \begin{array}{c} = &[1.3.2+2.2.3+0.(-1).(-4)] - [0.3.3+1.2.(-4)+2.(-1).2] \\ = & (6+12+0)-(0-8-4) = 18+12 = 30\\ \end{array} \end{eqnarray*}\]

No Ro derterminante de uma matriz é calculado pela função det().

A = matrix(c(1,-1,3,2,3,-4,0,2,2),3,3)
print(A)
##      [,1] [,2] [,3]
## [1,]    1    2    0
## [2,]   -1    3    2
## [3,]    3   -4    2
det(A)
## [1] 30

2.5.6 Inversa de uma matriz

Dada uma matriz quadrada \(A_{n\times n}\), se existir uma matriz quadrada \(B\), de mesma ordem, tal que \(A.B=B.A=Id_{n}\), em que \(Id_{n}\) é a matriz identidade de mesma dimensão de \(A\), então \(B\) é a inversa de \(A\) e diz-se que \(A\) é inversível. Notação \(A^{-1}\). Se \(A\) é inversível, sua inversa é única. Se \(A\) não admite inversa, diz-se que \(A\) é singular.

No R utiliza-se a função solve() para obter a inversa de uma matriz.

A = matrix(c(1,2,3,4),2,2)
print(A)
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
A_inversa = solve(A)
print(A_inversa)
##      [,1] [,2]
## [1,]   -2  1.5
## [2,]    1 -0.5

Pode-se verificar a condição de existência

A_inversa%*%A
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1
A%*%A_inversa
##      [,1] [,2]
## [1,]    1    0
## [2,]    0    1

2.5.7 Traço de uma matriz

O traço de uma matriz \(A_{n\times n}\) é definido como a soma dos elementos de sua diagonal principal.

\[\begin{eqnarray*} \begin{array}{c} tr(A) = \sum_{i=1}^{n} a_{ii} = a_{11} + a_{22} + ...+ a_{nn} \end{array} \end{eqnarray*}\]

No R para calcular o traço de uma matriz, extrai-se os elementos da diagonal principal a partir da função diag() e a soma destes elementos a partir da função sum().

A = matrix(c(1,-1,3,2,3,-4,0,2,2),3,3)
print(A)
##      [,1] [,2] [,3]
## [1,]    1    2    0
## [2,]   -1    3    2
## [3,]    3   -4    2
diag(A) ### extraindo os elementos da diagonal principal
## [1] 1 3 2
tr_A = sum(diag(A)) #somando os elementos da diagonal principal
print(tr_A)
## [1] 6

2.5.8 Valores (raı́zes) e vetores caracterı́sticos de uma matriz (autovalores e autovetores)

As raízes características de uma matriz \(A_{n\times n}\) são as soluções da equação dada pelo determinante \(|A - \lambda I| = 0\) e são chamadas de autovalores de \(A\). O Determinante \(|A - \lambda I|\) é um polinômio na variável \(\lambda\) denominado polinômio característico e denotado por \(p(\lambda) = |A - \lambda I|\).

  • Exemplo: Seja a matriz
\[\begin{eqnarray*} A = \left[ \begin{array}{rr} 1 & 4 \\ 2 & 3 \\ \end{array} \right] \end{eqnarray*}\]

Usando a equação característica:

\[\begin{eqnarray*} \left|\left[ \begin{array}{rr} 1 & 4 \\ 2 & 3 \\ \end{array} \right]-\lambda \left[ \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right] \right| = 0 \Leftrightarrow \left| \begin{array}{cc} 1 - \lambda & 4 \\ 2 & 3 - \lambda \\ \end{array} \right| = (1-\lambda)(3-\lambda) -8 = 0 \end{eqnarray*}\]

Portanto,

\[\begin{eqnarray*} \begin{array}{c} p(\lambda) = \lambda^2 - 4\lambda - 5 = 0 \end{array}, \end{eqnarray*}\]

desta forma as raízes \(\lambda_{1} = 5\) e \(\lambda_{2} = -1\) são os autovalores da matriz \(A\).

  • Autovetores: para \(\lambda_{1} = 5\)

Determinados os autovalores \(\lambda_{i}\), pode-se encontrar os autovetores pela seguinte equação:

\[\begin{eqnarray*} \begin{array}{c} A v = \lambda v \end{array} \Leftrightarrow \begin{array}{c} (A-5 I) v = 0 \end{array} \Leftrightarrow \left\{\left[ \begin{array}{rr} 1 & 4 \\ 2 & 3 \\ \end{array} \right]-5 \left[ \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ \end{array} \right] \right\} \left[ \begin{array}{c} v_{1} \\ v_{2} \\ \end{array} \right] = \left[ \begin{array}{c} 0 \\ 0 \\ \end{array} \right] \end{eqnarray*}\] \[\begin{eqnarray*}\Leftrightarrow \left[ \begin{array}{rr} -4 & 4 \\ 2 & -2 \\ \end{array} \right] \left[ \begin{array}{c} v_{1} \\ v_{2} \\ \end{array} \right] = \left[ \begin{array}{c} 0 \\ 0 \\ \end{array} \right] \Leftrightarrow \left\{ \begin{array}{r} -4v_{1} + 4v_{2} = 0 \\ 2v_{1} - 2v_{2} = 0 \\ \end{array} \right. \Leftrightarrow v_{1} = v_{2} = r \Leftrightarrow \boldsymbol{v} = \left[ \begin{array}{c} r \\ r \\ \end{array} \right], r \in \mathbb{R} \end{eqnarray*}\] \[\begin{eqnarray*} \Rightarrow \lambda_{1} = 5 \Leftrightarrow \boldsymbol{v} = r \left[ \begin{array}{c} 1 \\ 1 \\ \end{array} \right] \end{eqnarray*}\]

No R utiliza-se a função eigen() para obter os autovalores e autovetores de uma matriz.

  • Os autovetores são normalizados no R.
A = matrix(c(1,2,4,3),2,2) 
print(A)
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    3
eigen(A)
## eigen() decomposition
## $values
## [1]  5 -1
## 
## $vectors
##            [,1]       [,2]
## [1,] -0.7071068 -0.8944272
## [2,] -0.7071068  0.4472136

3 Principais definições da análise multivariada

  • Vetor aleatório: Seja \(X\) um vetor contendo \(n\) componentes, onde cada componente é uma variável aleatória (v.a.), isto é, \(\boldsymbol{X}_{i}\) é uma v.a., \(\forall\) \(i=1,2,...,p\). Então \(X\) é chamado de vetor aleatório e é denominado por:
\[\begin{eqnarray*}\boldsymbol{X}=\left[ \begin{array}{c} \boldsymbol{X}_{1} \\ \boldsymbol{X}_{2} \\ \vdots \\ \boldsymbol{X}_{p} \\ \end{array} \right] \end{eqnarray*}\]

Vetor transposto: \(\boldsymbol{X}^{'} = [\boldsymbol{X}_{1} \boldsymbol{X}_{2}\dots\boldsymbol{X}_{p}]\).

Exemplo: Considere uma empresa de minério de ferro. Algumas variáveis importantes para avaliação da qualidade do minério são: \(X_{1}\) - teor de ferro (em %); \(X_{2}\) - teor de umidade e \(X_{3}\) - granulometria do minério, que são v.a.

Então \(\boldsymbol{X} = [\boldsymbol{X}_{1}\boldsymbol{X}_{2}\boldsymbol{X}_{3}]^{'}\) é um vetor com \(p = 3\).

Exemplo: Uma seleção de 4 firmas de ração de Minas Gerais foi obtida para avaliar a venda de rações. Cada observação bivariada forneceu a quantidade de sacos de ração vendidos e a quantidade de reais de cada venda. Os dados obtidos na forma tabular são:

\[\begin{eqnarray*} \begin{array}{l|cccc}\hline \text{Váriavel 1 (reais/vendas)} & 80 & 120 & 90 & 110 \\ \hline \text{Váriavel 2 (número de sacos de ração vendidos)} & 10 & 12 & 6 & 8\\ \hline \end{array} \end{eqnarray*}\]

Pode-se escrever estes dados na forma matricial.

\[\begin{eqnarray*}\boldsymbol{X}=\left[ \begin{array}{cc} X_{11} & X_{12} \\ X_{21} & X_{22} \\ X_{31} & X_{32} \\ X_{41} & X_{42} \\ \end{array} \right] = \left[ \begin{array}{rr} 80 & 10 \\ 120 & 12 \\ 90 & 6 \\ 110 & 8 \\ \end{array} \right] \end{eqnarray*}\]
  • Escrevendo os dados na forma de matriz no R.
M1 = matrix(c(80,120,90,110,10,12,6,8),4,2,byrow = FALSE)
M1
##      [,1] [,2]
## [1,]   80   10
## [2,]  120   12
## [3,]   90    6
## [4,]  110    8
  • Vetor de médias: Seja \(\boldsymbol{X}\) um vetor aleatório. O vetor \(\boldsymbol{\mu} = E(\boldsymbol{X})\) é chamado de vetor de médias do vetor \(\boldsymbol{X}=[\boldsymbol{X}_{1}\boldsymbol{X}_{1}\dots\boldsymbol{X}_{p}]^{'}\), sendo
\[\begin{eqnarray*}\boldsymbol{\mu}=E(\boldsymbol{X})=\left[ \begin{array}{c} E(\boldsymbol{X}_{1}) \\ E(\boldsymbol{X}_{2}) \\ \vdots \\ E(\boldsymbol{X}_{p}) \\ \end{array} \right] = \left[ \begin{array}{c} \boldsymbol{\mu}_{1} \\ \boldsymbol{\mu}_{2} \\ \vdots \\ \boldsymbol{\mu}_{p} \\ \end{array} \right] \end{eqnarray*}\]

em que \(\mu_{i}=E(X_{i})\) é a média ou esperança da v.a. \(X_{i}\), \(i=1,2,...,p\).

3.1 Medidas descritivas

3.1.1 Média amostral

\[\begin{eqnarray*} \bar{X}_{j}= \dfrac{\displaystyle\sum_{i=1}^{p} X_{ij}}{n}, \text{com j=1,2,...,p.} \end{eqnarray*}\]

3.1.2 Variância amostral

\[\begin{eqnarray*} S^{2}_{j}= S_{jj} = \dfrac{\displaystyle\sum_{i=1}^{p} (X_{ij}-\bar{X}_{j})^{2}}{n-1}, \text{com j=1,2,...,p.} \end{eqnarray*}\]

3.1.3 Covariância amostral

A covariância amostral entre duas variáveis \(X_{j}\) e \(X_{j^{'}}\), que mede o grau de relacionamento linear entre elas, é dada por:

\[\begin{eqnarray*} S_{jj^{'}} = \dfrac{\displaystyle\sum_{i=1}^{p} (X_{ij}-\bar{X}_{j})(X_{ij^{'}}-\bar{X}_{j^{'}})}{n-1}, \text{com j=j$^{'}$=1,2,...,p.} \end{eqnarray*}\]

3.1.4 Correlação amostral

O grau de correlação entre \(X_{j}\) e \(X_{j^{'}}\) é dada por:

\[\begin{eqnarray*} r_{jj^{'}} = \dfrac{S_{jj^{'}}}{\sqrt{S_{jj}}\sqrt{S_{jj'}}} = \dfrac{\displaystyle\sum_{i=1}^{n} (X_{ij}-\bar{X}_{j})(X_{ij^{'}}-\bar{X}_{j^{'}})}{\sqrt{\displaystyle\sum_{i=1}^{n} (X_{ij}-\bar{X}_{j})^{2}}\sqrt{\displaystyle\sum_{i=1}^{n}(X_{ij^{'}}-\bar{X}_{j^{'}}} )^{2}} \end{eqnarray*}\]

3.1.5 Matriz de covariância amostral

\[\begin{eqnarray*}\boldsymbol{S}=\left[ \begin{array}{cccc} S_{11} & S_{12} & \dots & S_{1p}\\ S_{21} & S_{22} & \dots & S_{2p}\\ \vdots & \vdots & \ddots & \vdots\\ S_{p1} & S_{p2} & \dots & S_{pp}\\ \end{array} \right] \end{eqnarray*}\]

3.1.6 Matriz de correlação amostral

\[\begin{eqnarray*}\boldsymbol{R}=\left[ \begin{array}{cccc} 1 & r_{12} & \dots & r_{1p}\\ r_{21} & 1 & \dots & r_{2p}\\ \vdots & \vdots & \ddots & \vdots\\ r_{p1} & r_{p2} & \dots & 1\\ \end{array} \right] \end{eqnarray*}\]

Voltando ao exemplo anterior, temos:

\[\begin{eqnarray*} \bar{X}_{1} = \dfrac{\displaystyle \sum_{i=1}^{4} X_{i1}}{4} = \dfrac{80 + 120 + 90 + 110}{4} = 100 \end{eqnarray*}\] \[\begin{eqnarray*} \bar{X}_{2} = \dfrac{\displaystyle \sum_{i=1}^{4} X_{i2}}{4} = \dfrac{10 + 12 + 6 + 8}{4} = 9 \end{eqnarray*}\]

Portanto, o vetor de médias é:

\[\begin{eqnarray*}\boldsymbol{\bar{X}}=\left[ \begin{array}{c} \bar{X}_{1} \\ \bar{X}_{2} \\ \end{array} \right] = \left[ \begin{array}{c} 100 \\ 9 \\ \end{array} \right] \end{eqnarray*}\]

Agora, calculando as covariâncias

\[\begin{eqnarray*} \begin{array}{ll} S_{11} = & \dfrac{\left[ (80-100) ^{2} + (120-100)^{2} + (90-100)^{2} + (110-100)^{2}\right] }{3} = 333,333 \\ S_{22} = & \dfrac{\left[ (10-9) ^{2} + (12-9)^{2} + (6-9)^{2} + (8-9)^{2}\right] }{3} = 6,667 \\ S_{12} =& [(80-100)(10-9)+(120-100)(12-9) \\ & +(90-100)(6-9)+(110-100)(8-9)]/3 = 20 \\ S_{21} = S_{12} & = 20 \\ \end{array} \end{eqnarray*}\]

Matriz de covariância

\[\begin{eqnarray*}\boldsymbol{S}=\left[ \begin{array}{cc} S_{11} & S_{12} \\ S_{21} & S_{22} \\ \end{array} \right] = \left[ \begin{array}{cc} 333,333 & 20,000 \\ 20,000 & 6,667 \\ \end{array} \right] \end{eqnarray*}\]

Calculando as correlações

\[\begin{eqnarray*} r_{12} = \dfrac{S_{12}}{\sqrt{S_{11}}\sqrt{S_{12}}} = \dfrac{20}{\sqrt{333,333}\sqrt{6,667}} = 0,4243, \end{eqnarray*}\]

Matriz de correlação

como \(r_{21}=r_{12} = 0,4243\), temos

\[\begin{eqnarray*}\boldsymbol{R}=\left[ \begin{array}{cc} r_{11} & r_{12} \\ r_{21} & r_{22} \\ \end{array} \right] = \left[ \begin{array}{cc} 1,0000 & 0,4243 \\ 0,4243 & 1,0000 \\ \end{array} \right] \end{eqnarray*}\]

Soluções no R

M1 = matrix(c(80,120,90,110,10,12,6,8),4,2,byrow = FALSE)
print(M1)
##      [,1] [,2]
## [1,]   80   10
## [2,]  120   12
## [3,]   90    6
## [4,]  110    8
  • Calculando o vetor de médias
med_x1 = mean(M1[,1])
med_x1
## [1] 100
med_x2 = mean(M1[,2])
med_x2
## [1] 9
rbind(med_x1,med_x2)
##        [,1]
## med_x1  100
## med_x2    9
  • Calculando a matriz de covariância
S = var(M1)
S
##          [,1]      [,2]
## [1,] 333.3333 20.000000
## [2,]  20.0000  6.666667
  • Calculando o coeficiente de correlação
R = cor(M1)
R
##           [,1]      [,2]
## [1,] 1.0000000 0.4242641
## [2,] 0.4242641 1.0000000
  • Variância total

A variância total do vetor aleatório \(\boldsymbol{X}\) é definida como:

\[\begin{eqnarray*} \begin{array}{c} \text{traço} (\boldsymbol{S}_{p\times p}) = tr(\boldsymbol{S}_{p\times p}) = S_{11}+S_{22} + ...+ S_{pp} \end{array} \end{eqnarray*}\]
  • Variância generalizada

É definida como o determinante da matriz \(\boldsymbol{S}_{p\times p}\), ou seja, \(|\boldsymbol{S}_{p\times p}|\). Ao contrário da variância total, ela é influenciada pelas covariâncias (ou correlações) entre as variáveis \(X_{i}\), \(i=1,2,...,p\).

Exemplo: Coletou-se uma amostra de 12 rochas de uma determinada região. Para cada rocha, tem-se as porcentagens de quartzo (\(X_{1}\)) e feldspato (\(X_{2}\)), além do valor de um índice que mede a sua cor (\(X_{3}\)).

\[\begin{eqnarray*} \begin{array}{cccc}\hline \text{Rocha} & \text{Quartzo (%)} & \text{Feldspato (%)} & \text{Cor} \\ \hline 1 & 39,6 & 73,0 & 3,6 \\ 2 & 38,9 & 57,4 & 2,7 \\ 3 & 4,9 & 74,3 & 18,8 \\ 4 & 4,5 & 63,9 & 30,5 \\ 5 & 13,7 & 64,0 & 21,2 \\ 6 & 30,9 & 65,1 & 1,2 \\ 7 & 27,9 & 69,1 & 5,6 \\ 8 & 23,7 & 76,0 & 3,4 \\ 9 & 20,1 & 74,1 & 8,9 \\ 10 & 16,4 & 61,7 & 35,9 \\ 11 & 15,0 & 65,6 & 16,6 \\ 12 & 18,4 & 62,5 & 14,2 \\ \hline \end{array} \end{eqnarray*}\]
  1. O vetor de médias.
  2. Faça um gráfico de dispersão entre as variáveis. Você diria que há correlação entre elas?
  3. Faça um box-plot.
  4. Encontre a matriz de covariância.
  5. Encontre a matriz de correlação. Quais suas conclusões?
  6. Qual a variância total e generalizada ?
  7. Encontre os autovalores e autovetores.
LS0tDQp0aXRsZTogJ0VzdGF0w61zdGljYSBNdWx0aXZhcmlhZGEgQXBsaWNhZGEgLSBQYXJ0ZSBJOiBpbnRyb2R1w6fDo28gYSDDoWxnZWJyYSBtYXRyaWNpYWwnDQphdXRob3I6DQotIG5hbWU6IFVOSVZFUlNJREFERSBGRURFUkFMIERPIE9FU1RFIERPIFBBUsOBDQotIG5hbWU6IENFTlRSTyBERSBGT1JNQcOHw4NPIElOVEVSRElTQ0lQTElOQVINCi0gbmFtZTogUFJPR1JBTUEgREUgUMOTUyBHUkFEVUHDh8ODTyBFTSBTQcOaREUgRSBRVUFMSURBREUgREUgVklEQQ0KLSBuYW1lOiBQUk9GLiBEUi4gREVOTklTT04gQ0FSVkFMSE8NCmRhdGU6ICIyMDIyLTA3LTAzIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA2DQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiB5ZXMNCiAgICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIGtlZXBfbWQ6IHllcw0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAnNicNCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiAnNicNCiAgICBiaWJsaW9ncmFwaHk6IHJlZl9tdWx0LmJpYg0KICAgIGxhbmc6ICJwdC1CUiINCiAgICBjaXRlY29sb3I6IHJlZA0KICAgIGxpbmstY2l0YXRpb25zOiB5ZXMNCiAgICBsaW5rY29sb3I6IGJsdWUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQoNCjxzdHlsZT4NCmJvZHl7dGV4dC1hbGlnbjoganVzdGlmeX0NCjwvc3R5bGU+DQoNCjxkaXYgY2xhc3MgPSAicHJvZ3Jlc3MiPg0KICA8ZGl2IGNsYXNzID0gInByb2dyZXNzLWJhciIgc3R5bGUgPSAid2lkdGg6IDEwMCU7Ij4gPC9kaXY+DQo8L2Rpdj4NCg0KKipNYXRlcmlhbCBiYXNlIHBhcmEgYSBkaXNjaXBsaW5hIEVzdGF0w61zdGljYSBNdWx0aXZhcmlhZGEgY29tIGFwbGljYcOnw7VlcyBubyBgUmAuIE5lc3RlIHByaW1laXJvIG1vbWVudG8gbW9zdHJhLXNlIGFzIHByaW5jaXBhaXMgZGVmaW5pw6fDtWVzIGFsZ8OpYnJpY2FzIHBhcmEgdW0gbWVsaG9yIGVudGVuZGltZW50byBkZSBjb21vIHVtYSBjb21wb25lbnRlIHByaW5jaXBhbCDDqSBjb25zdHJ1w61kYS4qKg0KDQo8c3R5bGU+DQpib2R5e3RleHQtYWxpZ246IGp1c3RpZnl9DQo8L3N0eWxlPg0KDQo8ZGl2IGNsYXNzID0gInByb2dyZXNzIj4NCiAgPGRpdiBjbGFzcyA9ICJwcm9ncmVzcy1iYXIiIHN0eWxlID0gIndpZHRoOiAxMDAlOyI+IDwvZGl2Pg0KPC9kaXY+DQoNCiMgUHJpbWVpcm9zIHBhc3NvcyBubyBgUmANCg0KKiBPIFIgdmVtIGNvbSBhcyBjb25maWd1cmHDp8O1ZXMgbcOtbmltYXMgYW8gc2VyIGluc3RhbGFkby4gUGFyYSByZWFsaXphciB0YXJlZmFzIG1haXMgZXNwZWPDrWZpY2FzIHBvZGUgc2VyIG5lY2Vzc8OhcmlvIGluc3RhbGFyICBwYWNvdGVzIGFkaWNpb25haXMgKHBhY2thZ2VzKSwgY2xpY2FuZG8gZW0g4oCccGFjb3Rlcz4+aW5zdGFsYXIgcGFjb3Rlc+KAnTsNCg0KKiDDiSBuZWNlc3PDoXJpbyBlc2NvbGhlciBvIENSQU4gKENvbXByZWhlbnNpdmUgUiBBcmNoaXZlIE5ldHdvcmspLCBxdWUgc8OjbyBhcnF1aXZvcyBkaXNwb25pYmlsaXphZG9zIG5hIHJlZGUgcG9yIGRpdmVyc2FzIElFUyBkbyBtdW5kbyBpbnRlaXJvLCBpbmNsdXNpdmUgZG8gQnJhc2lsLg0KDQoqIE8gUiDDqSBjYXNlLXNlbnNpdGl2ZSwgaXN0byDDqSwgZWxlIGRpZmVyZW5jaWEgbGV0cmFzIG1pbsO6c2N1bGFzIGRlIG1hacO6c2N1bGFzOw0KDQoqIE8gc2VwYXJhZG9yIGRlIGNhc2FzIGRlY2ltYWlzIMOpIG8g4oCcLuKAnTsNCiogQSB2w61yZ3VsYSDDqSB1c2FkYSBwYXJhIHNlcGFyYXIgYXJndW1lbnRvczsNCg0KKiBPIHByb21wdCBkbyBgUmAgw6kgbyBzaW5hbCBkZSBtYWlvciDigJw+4oCdOw0KDQoqIEFww7NzIGluc3RhbGFybW9zIGFsZ3VtIHBhY290ZSBzZW1wcmUgc2Vyw6EgbmVjZXNzw6FyaW8gY2FycmVnw6EtbG8gY29tIG8gY29tYW5kbzogYGBsaWJyYXJ5KOKAnG5vbWUgZG8gcGFjb3Rl4oCdKWBgOw0KDQoqIFBhcmEgdmVyaWZpY2FyIGNvbW8gY2l0YXIgbyBwYWNvdGUgaW5zdGFsYWRvIGRpZ2l0ZTogYGBjaXRhdGlvbijigJxub21lIGRvIHBhY290ZeKAnSlgYDsNCg0KKiBQYXJhIG9idGVyIGFqdWRhIGRvcyBhcnF1aXZvcyBkbyBgUmAgdXNlIG8gY29tYW5kbyBgYGhlbHAobm9tZSBkYSBmdW7Dp8OjbylgYC4NCg0KKipFeGVtcGxvczoqKg0KDQpgYGB7cn0NCiMgaGVscChzcXJ0KSAjYWp1ZGEgc29icmUgYSBmdW7Dp8OjbyByYWl6IHF1YWRyYWRhDQojIGhlbHAobG0pICMgYWp1ZGEgc29icmUgYSBmdW7Dp8OjbyBsaW5lYXIgbW9kZWxzDQpgYGANCg0KIyMgUHJpbWVpcm9zIGNvbWFuZG9zDQoNCiogQWxndW1hcyBEZW1vbnN0cmHDp8O1ZXMgZG8gdXNvIGRvIGBSYCAgIA0KDQoNCmBgYHtyfQ0KI2RlbW8oZ3JhcGhpY3MpICNwcmVzc2lvbmUgRW50ZXIgDQojZGVtbyhwZXJzcCkNCiNkZW1vKGltYWdlKQ0KYGBgDQoNCiMjIENyaWFuZG8gb2JqZXRvcywgdmV0b3JlcyBjb20gdmFsb3JlcyBudW3DqXJpY29zDQoNClZhbW9zIGNyaWFzIHVtIHZldG9yIGRlIG5vdGFzIGRlIDEwIGFsdW5vcyBkYSB0dXJtYS4gQSBmdW7Dp8OjbyBgYGxlbmd0aChub3RhcylgYCBmb3JuZWNlIG8gbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIChuKSBkZW50cm8gZG8gb2JqZXRvLg0KDQoNCioqT0JTOiBvIGNvbWFuZG8gYGA8LWBgIHNpZ25pZmljYSBhc3NpbmFsYXI7IG8gY29tYW5kbyBgYGNgYCBzaWduaWZpY2EgY29uY2F0ZW5hciAoY29sb2NhciBqdW50bykuKioNCg0KYGBge3J9DQpub3RhcyA9IGMoOSw2LDgsNSw3LDgsNiw5LDEwLDYpDQpwcmludChub3RhcykNCmxlbmd0aChub3RhcykNCmBgYA0KDQpQYXJhIG9iamV0b3MgY29tIGxldHJhcyAodmFyacOhdmVpcyBxdWFsaXRhdGl2YXMpLCBiYXN0YSBjb2xvY2FyIGNhZGEgb2JzZXJ2YcOnw6NvIGVudHJlIGFzcGFzLg0KDQpQYXJhIGxpc3RhciBxdWFpcyBvYmpldG9zIHRlbW9zIHNhbHZvIHV0aWxpemEtc2UgYSBmdW7Dp8OjbyBgYGxzKClgYC4NCg0KUGFyYSByZW1vdmVyIHVtIG9iamV0bzogYGBybSjigJxub21lIGRvIG9iamV0b+KAnSlgYC4NCg0KYGBge3J9DQpsZXRyYXM8LWMoImEiLCJiIiwiYyIsImQiKQ0KcHJpbnQobGV0cmFzKQ0KbHMoKQ0KYGBgDQoNCiMjIEdlcmFuZG8gdW0gc2VxdcOqbmNpYToNCg0KKiBQb2RlLXNlIHVzYXIgb3MgY29tYW5kb3M6IA0KDQpgYDE6MTBgYDogc2VxdcOqbmNpYSBkZSAxIGF0w6kgMTAsIGRlIHVtIGVtIHVtLg0KYGBzZXEoZnJvbSA9IDEsIHRvID0gMTAsIGJ5ID0gMiApYGAsIGlzdG8gw6ksIHNlcXXDqm5jaWEoZGUgdW0sIGEgZGV6LCBlbSBpbnRlcnZhbG9zIGRlIDIpLiBPdSBhaW5kYQ0KYGBzZXEoMSwxMDAsNSlgYDogc2VxdcOqbmNpYSBkZSAxIGEgMTAwIGVtIGludGVydmFsb3MgZGUgNQ0KDQpgYGB7cn0NCjE6MTANCnNlcShmcm9tID0gMSwgdG8gPSAxMCwgYnkgPSAyICkNCnNlcSgxLDEwMCw1KQ0KYGBgDQoNCiMjIEdlcmFuZG8gZGFkb3MgYWxlYXTDs3Jpb3MNCg0KKiBgYHJiaW5vbShuLCBzaXplLCBwcm9iKWBgOiBnZXJhIHVtYSBkaXN0cmlidWnDp8OjbyBhbGVhdMOzcmlhIEJpbm9taWFsIGNvbSBgYG5gYCB2YWxvcmVzIChvYnNlcnZhw6fDtWVzKSwgbsO6bWVybyBkZSB0ZW50YXRpdmFzIGBgc2l6ZWBgIGUgcHJvYmFiaWxpZGFkZSBkZSBzdWNlc3NvIGBgcHJvYmBgLg0KDQoqIGBgcmdlb20obiwgcHJvYilgYDogZ2VyYSB1bWEgZGlzdHJpYnVpw6fDo28gYWxlYXTDs3JpYSBHZW9tw6l0cmljYSBjb20gYGBuYGAgdmFsb3JlcyBlIHByb2JhYmlsaWRhZGUgZGUgc3VjZXNzbyBgYHByb2JgYC4NCg0KKiBgYHJwb2lzKG4sIGxhbWJkYSlgYDogZ2VyYSB1bWEgZGlzdHJpYnVpw6fDo28gYWxlYXTDs3JpYSBQb2lzc29uIGNvbSBgYG5gYCB2YWxvcmVzIGUgdmV0b3IgZGUgbcOpZGlhcyBgYGxhbWJkYWBgLg0KDQoqIGBgcnVuaWYobiwgbWluPTAsIG1heD0xKWBgOiBnZXJhIHVtYSBkaXN0cmlidWnDp8OjbyBhbGVhdMOzcmlhIFVuaWZvcm1lIGNvbnTDrW51YSBjb20gYGBuYGAgdmFsb3JlcywgY29tZcOnYW5kbyBlbSBgYG1pbmBgIGUgdGVybWluYW5kbyBlbSBgYG1heGBgLg0KDQoqIGBgcmV4cChuLCByYXRlID0gMSlgYDogZ2VyYSB1bWEgZGlzdHJpYnVpw6fDo28gYWxlYXTDs3JpYSBFeHBvbmVuY2lhbCBjb20gYGBuYGAgdmFsb3JlcyBlIHRheGEgYGByYXRlYGAuDQoNCiogYGBybm9ybShuLCBtZWFuID0gMCwgc2QgPSAxKSlgYDogZ2VyYSB1bWEgZGlzdHJpYnVpw6fDo28gYWxlYXTDs3JpYSBOb3JtYWwgY29tIGBgbmBgIHZhbG9yZXMsIG3DqWRpYSBgYG1lYW5gYCBlIGRlc3ZpbyBwYWRyw6NvIGBgc2RgYC4NCg0KDQpgYGB7cn0NCnJiaW5vbSgxMCwgNCwgMC4yKQ0Kcmdlb20oNSwwLjEpDQpycG9pcyg4LDIpDQpyZXhwKDYsMSkNCnJ1bmlmKDQsIDAuMiwuOSkNCnJub3JtKDcpDQpgYGANCg0KKiBIaXN0b2dyYW1hIGRhIGRpc3RyaWJ1acOnw6NvIE5vcm1hbA0KDQpgYGB7cn0NCngxID0gcm5vcm0oMjAwKQ0KaGlzdCh4MSwNCiAgICAgY29sID0gImxpZ2h0Ymx1ZSIsDQogICAgIGZyZXEgPSBGLA0KICAgICBtYWluID0gIiIsDQogICAgIHhsYWIgPSAiRGFkb3MgZGUgWH5OKDAsMSkiLA0KICAgICB5bGFiID0gImYoeCk6IGYuZC5wLiBkZSBYIiwNCiAgICAgYnJlYWtzID0gMjApDQpjdXJ2ZShkbm9ybSh4LG1lYW4gPSBtZWFuKHgxKSxzZD1zZCh4MSkpLGFkZCA9IFQpDQpgYGANCg0KKipFeGVtcGxvKioNCg0KYGBge3J9DQpzYW1wbGUoMToxMCw1KSAjIHRpcmEgNSBhbW9zdHJhcyBjb20gdmFsb3JlcyBlbnRyZSAxIGUgMTAgDQpgYGANCg0KKkNvbW8gbsOjbyBlc3BlY2lmaWNhbW9zIG8gYXJndW1lbnRvIHJlcGxhY2UgbyBwYWRyw6NvIMOpIGNvbnNpZGVyYXIgcXVlIGEgYW1vc3RyYSDDqSBzZW0gcmVwb3Npw6fDo28gKD0gRkFMU0UpLioNCg0KYGBge3J9DQpzYW1wbGUoMToxMCwxNSxyZXBsYWNlPVRSVUUpDQpgYGANCg0KTGVtYnJhbSBkb3MgZXhlbXBsb3MgZGEgbW9lZGEgZW0gcHJvYmFiaWxpZGFkZT8gRW50w6NvLA0KDQpgYGB7cn0NCm1vZWRhID0gYygiQyIsIksiKSAjIHByaW1laXJvIGNyaWFtb3MgYSBtb2VkYSANCnNhbXBsZShtb2VkYSwxMCxyZXBsYWNlPVRSVUUpICMgbsOjbyBwb2RlbW9zIGVzcXVlY2VyIGRvIFRSVUUNCmBgYA0KDQoNCiMgRXNjYWxhcmVzLCB2ZXRvcmVzIGUgbWF0cml6ZXMNCg0KIyMgRXNjYWxhcg0KDQokJCB4ID0gXGJvbGRzeW1ib2x7eH1fezEsMX0gPSB4X3tpfSAgJCQNCg0KIyMgVmV0b3IgY29sdW5hDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn1cYm9sZHN5bWJvbHt4fT1cYm9sZHN5bWJvbHt4fV97biwxfT1cbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjfQ0KICAgICAgICB4X3sxfSBcXA0KICAgICAgICB4X3syfSBcXA0KICAgICAgICBcdmRvdHMgXFwNCiAgICAgICAgeF97bn0gXFwgICAgICAgIA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0gDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KIyMgVmV0b3IgbGluaGENCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfVxib2xkc3ltYm9se3h9XnsnfT1cYm9sZHN5bWJvbHt4fV97MSxwfT1cbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjfQ0KICAgICAgICB4X3sxfSwgeF97Mn0sLi4uLHhfe259IFxcICAgICAgIA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0gDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KIyMgTWF0cml6DQoNCkFzIG1hdHJpemVzIGUgb3Mgc2lzdGVtYXMgbGluZWFyZXMgdMOqbSBsYXJnYSBhcGxpY2HDp8OjbyBlbSBwcm9ibGVtYXMgcHLDoXRpY29zLiBEw6Etc2UgbyBub21lIGRlIG1hdHJpeiBhIHVtYSB0YWJlbGEgb3JnYW5pemFkYSBlbSBsaW5oYXMgZSBjb2x1bmFzLCBkZW5vdGFkYXMgcG9yICRcYm9sZHN5bWJvbHtYfT1beF97aWp9XV97bVx0aW1lcyBufSQsIG9uZGUgbyBwYXIgZGUgw61uZGljZXMgJGlqJCByZXByZXNlbnRhIGEgcG9zacOnw6NvIGRlIGNhZGEgZWxlbWVudG8gJHhfe2lqfSQgZGVudHJvIGRhIG1hdHJpeiwgc2VuZG8gcXVlIG8gw61uZGljZSAkaSQgaW5kaWNhIGEgbGluaGEgZSBvIMOtbmRpY2UgJGokIGEgY29sdW5hLiBPIHBhciBkZSDDrW5kaWNlICRtIFx0aW1lcyBuJCDDqSBjaGFtYWRvIGRlIGRpbWVuc8OjbyBkYSBtYXRyaXogZSByZXByZXNlbnRhIG8gc2V1IHRhbWFuaG8uIE8gw61uZGljZSAkbSQgaW5kaWNhIG8gbsO6bWVybyBkZSBsaW5oYXMgZSAkbiQsIG8gbsO6bWVybyBkZSBjb2x1bmFzDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn1cYm9sZHN5bWJvbHtYfT1cbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjY2NjfQ0KICAgICAgICB4X3sxMX0gJiAgICB4X3sxMn0gJiBcZG90cyAmICAgIHhfezFufVxcDQogICAgICAgIHhfezIxfSAmICAgIHhfezIyfSAmIFxkb3RzICYgICAgeF97Mm59XFwNCiAgICAgICAgXHZkb3RzICYgICAgXHZkb3RzICYgXGRkb3RzICYgICBcdmRvdHNcXA0KICAgICAgICB4X3ttMX0gJiAgICB4X3ttMn0gJiBcZG90cyAmIHhfe21ufVxcICAgICAgIA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0gDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KLSAgICoqSW5zZXJpbmRvIHVtYSBtYXRyaXogbm8gUioqDQoNClBhcmEgaW5zZXJpciB1bWEgbWF0cml6IG5vIGBSYCB1dGlsaXphLXNlIGEgZnVuw6fDo28gYG1hdHJpeChkYXRhID0gTkEsIG5yb3cgPSAxLCBuY29sID0gMSwgYnlyb3cgPSBGQUxTRSwgZGltbmFtZXMgPSBOVUxMKWAuIE5vdGUgcXVlLCBiYXN0YSBjb2xvY2FyIGNvbW8gYXJndW1lbnRvcyBvIGNvbmp1bnRvIGRlIGRhZG9zIGUgaW5kaWNhciBvIG7Dum1lcm8gZGUgbGluaGFzIGUgZGUgY29sdW5hcyBkYSBtYXRyaXouDQoNCmBgYHtyfQ0KTTEgPSBtYXRyaXgoZGF0YSA9IDE6OSwgbnJvdyA9IDMsIG5jb2wgPSAzKQ0KDQpwcmludChNMSkNCmBgYA0KDQpPYnNlcnZlIHF1ZSBhIG1hdHJpeiBmb2kgb3JnYW5pemFkYSBwb3IgKmRlZmF1bHQqIHBvciBjb2x1bmFzLiBFbnRyZXRhbnRvLCBwb2RlbW9zIG11ZGFyIGlzc28gcGFyYSBsaW5oYXMgdXRpbGl6YW5kby1zZSBvIGFyZ3VtZW50byBgYnlyb3cgPSBUUlVFYCBuYSBmdW7Dp8OjbyBgbWF0cml4YC4NCg0KYGBge3J9DQpNMiA9IG1hdHJpeChkYXRhID0gMTo5LCBucm93ID0gMywgbmNvbCA9IDMsIGJ5cm93ID0gVFJVRSkNCg0KcHJpbnQoTTIpDQpgYGANCg0KU2UgdGl2ZXJtb3MgdW0gb3UgbWFpcyB2ZXRvcmVzIHBhcmEgZm9ybWFyIHVtYSBtYXRyaXosIGJhc3RhIGluZm9ybWFyIG8gbsO6bWVybyBkZSBsaW5oYXMgZG8gdmV0b3IuDQoNCioqRXhlbXBsbyoqOiBVbWEgc2VsZcOnw6NvIGRlIDQgZmlybWFzIGRlIHJhw6fDo28gZGUgTWluYXMgR2VyYWlzIGZvaSBvYnRpZGEgcGFyYSBhdmFsaWFyIGEgdmVuZGEgZGUgcmHDp8O1ZXMuIENhZGEgb2JzZXJ2YcOnw6NvIGJpdmFyaWFkYSBmb3JuZWNldSBhIHF1YW50aWRhZGUgZGUgc2Fjb3MgZGUgcmHDp8OjbyB2ZW5kaWRvcyBlIGEgcXVhbnRpZGFkZSBkZSByZWFpcyBkZSBjYWRhIHZlbmRhLiBPcyBkYWRvcyBvYnRpZG9zIG5hIGZvcm1hIHRhYnVsYXIgc8OjbzoNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSANCiAgICBcYmVnaW57YXJyYXl9e2x8Y2NjY31caGxpbmUNCiAgICAgICAgXHRleHR7VsOhcmlhdmVsIDEgKHJlYWlzL3ZlbmRhcyl9ICYgODAgJiAxMjAgJiA5MCAmIDExMCBcXCBcaGxpbmUNCiAgICAgICAgXHRleHR7VsOhcmlhdmVsIDIgKG7Dum1lcm8gZGUgc2Fjb3MgZGUgcmHDp8OjbyB2ZW5kaWRvcyl9ICYgMTAgJiAxMiAmIDYgJiA4XFwgXGhsaW5lDQogICAgXGVuZHthcnJheX0gDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KYGBge3J9DQpNX0UxID0gbWF0cml4KGMoODAsMTIwLDkwLDExMCwxMCwxMiw2LDgpLDQsMikNCnByaW50KE1fRTEpDQpgYGANCg0KLSAgICoqw41uZGljZSBkYXMgbWF0cml6ZXMqKg0KDQpQb2RlLXNlIGFjZXNzYXIgb3MgZWxlbWVudG9zIGRlIHVtYSBtYXRyaXogdXNhbmRvIG8gbm9tZSBkbyBvYmpldG8gKG1hdHJpeikgc2VndWlkbyBkZSBjb2xjaGV0ZXMuIFBhcmEgYWNlc3NhciBvIHNlZ3VuZG8gZWxlbWVudG8gZGEgdmFyacOhdmVsIDEsIG5vIGV4ZW1wbG8gYW50ZXJpb3IsIGBNX0UxWzIsMV1gLiBQYXJhIG8gdGVyY2Vpcm8gZWxlbWVudG8gZGEgdmFyacOhdmVsIDIsIGBNX0UxWzMsMl1gLiBFLCBwYXJhIHNlbGVjaW9uYXIgdG9kb3Mgb3MgZWxlbWVudG9zIGRhIHZhcmnDoXZlbCAxLCBgTV9FMVssMV1gLg0KDQpgYGB7cn0NCk1fRTFbMiwxXSAjIHNlZ3VuZG8gZWxlbWVudG8gZGEgdmFyacOhdmVsIDENCk1fRTFbMywyXSAjIHRlcmNlaXJvIGVsZW1lbnRvIGRhIHZhcmnDoXZlbCAyDQpNX0UxWywxXSAjIHRvZG9zIG9zIGVsZW1lbnRvcyBkYSB2YXJpw6F2ZWwgMQ0KYGBgDQoNCiMjIE9wZXJhw6fDtWVzIGNvbSBtYXRyaXplcw0KDQojIyMgQWRpw6fDo28gZGUgbWF0cml6ZXMNCg0KRGFkYXMgZHVhcyBtYXRyaXplcyBkZSBtZXNtYSBkaW1lbnPDo28gJEE9W2Ffe2lqfV1fe21cdGltZXMgbn0kIGUgJEI9W2Jfe2lqfV1fe21cdGltZXMgbn0kLCB0ZW1vcyBxdWUgJEEgKyBCID0gW2Ffe2lqfSArIGJfe2lqfV0kLg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9XGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogICAgYV97MTF9ICYgYV97MTJ9IFxcICAgDQogICAgYV97MjF9ICYgYV97MjJ9IFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSArIFxsZWZ0Ww0KICAgICAgICBcYmVnaW57YXJyYXl9e2NjfQ0KICAgIGJfezExfSAmIGJfezEyfSBcXCAgIA0KICAgIGJfezIxfSAmIGJfezIyfSBcXCAgICAgICANCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdID0gXGxlZnRbDQogICAgICAgIFxiZWdpbnthcnJheX17Y2N9DQphX3sxMX0gKyBiX3sxMX0gJiBhX3sxMn0gKyBiX3sxMn0gXFwgICAgIA0KYV97MjF9ICsgYl97MjF9ICYgYV97MjJ9ICsgYl97MjJ9IFxcICAgICAgICAgDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XQ0KXGVuZHtlcW5hcnJheSp9DQpgYGANCioqRXhlbXBsbyoqOiBEYWRhcyBhcyBtYXRyaXplcw0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9QT1cbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjY2NjfQ0KICAgICAgICAtMSAmIDIgJiAxMCAmIDggXFwNCiAgICAgICAgIDIgJiAwICYgLTMgJiAzIFxcDQogICAgIDAgJiA1ICYgLTggJiAxIFxcICAgICAgIA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0gXHF1YWQgXHRleHR7ZX1ccXVhZCBCID0gXGxlZnRbDQogICAgICAgIFxiZWdpbnthcnJheX17Y2NjY30NCiAgICAgICAgMCAmIDMgJiAtMiAmIDcgXFwNCiAgICAgICAgIDMgJiAtNCAmIDkgJiAyIFxcDQogICAgIDIxICYgMCAmIC0xICYgMTIgXFwgICAgICAgICANCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdLCBcdGV4dHt0ZW1vcyBxdWV9DQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KYGBge3J9DQpBID0gbWF0cml4KGMoLTEsMiwxMCw4LDIsMCwtMywzLDAsNSwtOCwxKSwzLDQsIGJ5cm93ID0gVFJVRSkNCnByaW50KEEpDQpCID0gbWF0cml4KGMoMCwzLC0yLDcsMywtNCw5LDIsMjEsMCwtMSwxMiksMyw0LGJ5cm93ID0gVFJVRSkNCnByaW50KEIpDQpTX0FCID0gQSArIEIgIyBzb21hIGRhcyBtYXRyaXplcyBBIGUgQg0KcHJpbnQoU19BQikNCmBgYA0KDQojIyMgTXVsdGlwbGljYcOnw6NvIGRlIHVtYSBtYXRyaXogcG9yIHVtIGVzY2FsYXINCg0KRGFkYSB1bWEgbWF0cml6ICRBPVthX3tpan1dX3ttXHRpbWVzIG59JCBlIHVtIG7Dum1lcm8gcmVhbCAkayQsIHRlbW9zIHF1ZSAkayBcdGltZXMgQT1bayBcdGltZXMgYV97aWp9XV97bVx0aW1lcyBufSQuDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn1rIFx0aW1lcyBBPVtrIFx0aW1lcyBhX3tpan1dX3ttXHRpbWVzIG59ID0gayBcdGltZXMgXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogICAgYV97MTF9ICYgYV97MTJ9IFxcICAgDQogICAgYV97MjF9ICYgYV97MjJ9IFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSBcbG9uZ3JpZ2h0YXJyb3cgXGxlZnRbDQogICAgICAgIFxiZWdpbnthcnJheX17Y2N9DQogICAgayBcdGltZXMgYV97MTF9ICYgayBcdGltZXMgYV97MTJ9IFxcICAgICANCiAgICBrIFx0aW1lcyBhX3syMX0gJiBrIFx0aW1lcyBhX3syMn0gXFwgICAgICAgICANCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdIA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCioqRXhlbXBsbyoqOiBEYWRhIGEgbWF0cml6IEEgZG8gZXhlbXBsbyBhbnRlcmlvciwgcG9kZS1zZSBtdWx0aXBsaWNhciBlc3NhIG1hdHJpeiBwb3IgcXVhbHF1ZXIgZXNjYWxhciAkayQuIFBvciBleGVtcGxvLCBwYXJhICRrID0gLTMkLCB0ZW1vcw0KDQpgYGB7cn0NCmsgPSAzICMgZGVuaWZpbmRvIHVtIGVzY2FsYXIgcXVhbHF1ZXINCkEgPSBtYXRyaXgoYygtMSwyLDEwLDgsMiwwLC0zLDMsMCw1LC04LDEpLDMsNCwgYnlyb3cgPSBUUlVFKQ0KcHJpbnQoQSkNCmtBID0gaypBDQpwcmludChrQSkNCmBgYA0KDQojIyMgTXVsdGlwbGljYcOnw6NvIGRlIG1hdHJpemVzDQoNCkRhZGFzIGR1YXMgbWF0cml6ZXMgJEE9W2Ffe2lqfV1fe21cdGltZXMgbn0kIGUgJEI9W2Jfe2prfV1fe25cdGltZXMgcH0kLCB0ZW1vcyBxdWUgJEFcdGltZXMgQiA9IENbY197aWt9XV97bVx0aW1lcyBwfSQuIFZhbGUgcmVzc2FsdGFyIHF1ZSBlc3RlIHByb2R1dG8gc8OzIHNlcsOhIHBvc3PDrXZlbCBzZSBvIG7Dum1lcm8gZGUgY29sdW5hcyBkZSAkQSQgZm9yIGlndWFsIGFvIG7Dum1lcm8gZGUgbGluaGFzIGRlICRCJC4NCg0KKipFeGVtcGxvKio6IERhZGFzIGFzIG1hdHJpemVzDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0gQSA9IFxsZWZ0WyANCiAgICBcYmVnaW57YXJyYXl9e2NjY30NCiAgICBhX3sxMX0gJiBhX3sxMn0gJiBhX3sxM31cXCAgIA0KICAgIGFfezIxfSAmIGFfezIyfSAmIGFfezIzfVxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSBccXVhZCBcdGV4dHtlfSBccXVhZCBCPSBcbGVmdFsNCiAgICAgICAgXGJlZ2lue2FycmF5fXtjY30NCiAgICBiX3sxMX0gJiBiX3sxMn0gXFwgICANCiAgICBhX3syMX0gJiBhX3syMn0gXFwNCiAgICBhX3szMX0gJiBhX3szMn0gXFwgICAgICAgDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpPYnNlcnZlIHF1ZSBvIG7Dum1lcm8gZGUgY29sdW5hcyBkYSBtYXRyaXogJEEkIMOpIGlndWFsIGFvIG7Dum1lcm8gZGUgbGluaGFzIGRhIG1hdHJpeiAkQiQsIHBvcnRhbnRvLCBwb3IgZGVmaW5pw6fDo28gdGVtb3MgcXVlIGEgbWF0cml6ICRDJCB0ZXLDoSBkaW1lbnPDo28gJDJcdGltZXMgMiQsIGNvbW8gc2VndWUNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSBDID0gXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogICAgY197MTF9ICYgY197MTJ9IFxcICAgDQogICAgY197MjF9ICYgY197MjJ9IFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSwgXHF1YWQgXHRleHR7ZW0gcXVlfQ0KXGVuZHtlcW5hcnJheSp9DQpgYGANCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0gDQogICAgXGJlZ2lue2FycmF5fXtjY30NCiAgICBjX3sxMX0gPSAmIGFfezExfWJfezExfSthX3sxMn1iX3syMX0rYV97MTN9Yl97MzF9IFxcICAgICANCiAgICBjX3sxMn0gPSAmIGFfezExfWJfezEyfSthX3sxMn1iX3syMn0rYV97MTN9Yl97MzJ9IFxcICAgIA0KICAgIGNfezIxfSA9ICYgYV97MjF9Yl97MTF9K2FfezIyfWJfezIxfSthX3syM31iX3szMX0gXFwgICAgICAgIA0KICAgIGNfezIyfSA9ICYgYV97MjF9Yl97MTJ9K2FfezIyfWJfezIyfSthX3syM31iX3szMn0gXFwgICAgDQogICAgICAgIFxlbmR7YXJyYXl9IA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCk5vIGBSYCBvIHByb2R1dG8gZGUgbWF0cml6ZXMgw6kgZmVpdG8gcGVsbyB1c28gZG8gb3BlcmFkb3IgYCUqJWAuDQoNCioqRXhlcmPDrWNpbyoqOiBTZWphbSBhcyBtYXRyaXplcw0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9IFggPSBcbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjY30NCiAgMiAmIC0xIFxcICANCiAgICAwICYgMSBcXA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0sIFkgPSBcbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjY2N9DQogIDUgJiAwICYgMSBcXCAgIA0KICAgIDIgJiAtMSAmIDMgXFwNCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdIFxxdWFkIFx0ZXh0e2V9IFxxdWFkIFogPSBcbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjY30NCiAgNCAmIC04IFxcICANCiAgICAxICYgMCBcXA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0NClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpEZXRlcm1pbmU6DQoNCjEuICAkMlgrWSQNCg0KMi4gICRYWSQNCg0KMy4gICRZK1okDQoNCjQuICAkWVokDQoNCjUuICAkKFgtM1opWSQNCg0KNi4gICRYXnsyfSQNCg0KIyMjIFRyYW5zcG9zdGEgZGUgdW1hIG1hdHJpeg0KDQpEYWRhIGEgbWF0cml6ICRBPVthX3tpan1dX3ttXHRpbWVzIG59JCwgc3VhIHRyYW5zcG9zdGEgw6kgZGFkYSBwb3IgJEFee3R9PVthX3tqaX1dX3tuXHRpbWVzIG19JC4NCg0KKipFeGVtcGxvKio6IERhZGEgYSBtYXRyaXoNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSBBID0gXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2NjfQ0KICAxICYgMiAmIDcgXFwgICANCiAgICA0ICYgLTMgJiA4IFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XV97Mlx0aW1lcyAzfSBccXVhZCBcdGV4dHtzdWEgdHJhbnNwb3N0YSDDqX0gXHF1YWQNCiAgICBBXnt0fSA9IFxsZWZ0WyANCiAgICBcYmVnaW57YXJyYXl9e3JyfQ0KICAxICYgNCAgXFwgIA0KICAgIDIgJiAtMyBcXA0KICAgIDcgJiA4IFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XV97M1x0aW1lcyAyfQ0KXGVuZHtlcW5hcnJheSp9DQpgYGANCk5vIGBSYCB1dGlsaXphLXNlIGEgZnVuw6fDo28gYHQoKWAgcGFyYSBvYnRlciBhIHRyYW5zcG9zdGEgZGUgdW1hIG1hdHJpei4NCg0KYGBge3J9DQpBID0gbWF0cml4KGMoMSw1LDIsLTMsNyw4KSwyLDMpDQpwcmludChBKQ0KQV90ID0gdChBKQ0KcHJpbnQoQV90KQ0KYGBgDQoNCiMjIyBEZXRlcm1pbmFudGUgZGUgdW1hIG1hdHJpeg0KDQotICAgRGFkYSBhIG1hdHJpeiAkQVthX3sxMX1dJCwgdGVtb3MgcXVlICRkZXQoQSkgPSBhX3sxMX0kLg0KDQotICAgRGFkYSBhIG1hdHJpeg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9IEEgPSBcbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjY30NCiAgYV97MTF9ICYgYV97MTJ9IFxcICAgICANCiAgICBhX3syMX0gJiBhX3syMn0gXFwNCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdLA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCnNldSBkZXRlcm1pbmFudGUgw6k6DQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0gZGV0KEEpID0gXGxlZnR8IA0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogIGFfezExfSAmIGFfezEyfSBcXCAgICAgDQogICAgYV97MjF9ICYgYV97MjJ9IFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0fCA9IGFfezExfWFfezIyfS1hX3sxMn1hX3syMX0NClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQoqKkV4ZW1wbG8qKjogRGFkYSBhIG1hdHJpeg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9IEEgPSBcbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtycn0NCiAtMyAmIDIgXFwNCiAgICA0ICYgMiBcXA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0sDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0Kc2V1IGRldGVybWluYW50ZSDDqToNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSBkZXQoQSkgPSBcbGVmdHwgDQogICAgXGJlZ2lue2FycmF5fXtycn0NCiAtMyAmIDIgXFwNCiAgICA0ICYgMiBcXA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodHwgPSAoLTMuMiktKDIuNCkgPSAtMTQNClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpTZWphIGEgbWF0cml6ICRBX3szXHRpbWVzIDN9JCwNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSBBID0gXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2NjfQ0KICAgIGFfezExfSAmIGFfezEyfSAmIGFfezEzfVxcICAgDQogICAgYV97MjF9ICYgYV97MjJ9ICYgYV97MjN9XFwNCiAgICBhX3szMX0gJiBhX3szMn0gJiBhX3szM31cXA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0sDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0Kc2V1IGRldGVybWluYW50ZSDDqSBjYWxjdWxhZG8gcGVsYSByZWdyYSBkZSBTYXJydXMgZGEgc2VndWludGUgbWFuZWlyYQ0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9IGRldChBKT0gXGxlZnR8DQogICAgXGJlZ2lue2FycmF5fXtjY2N8Y2N9DQogICAgYV97MTF9ICYgYV97MTJ9ICYgYV97MTN9ICYgYV97MTF9ICYgYV97MTJ9XFwgICAgIA0KICAgIGFfezIxfSAmIGFfezIyfSAmIGFfezIzfSAmIGFfezIxfSAmIGFfezIxfVxcDQogICAgYV97MzF9ICYgYV97MzJ9ICYgYV97MzN9ICYgYV97MzF9ICYgYV97MzJ9XFwgICAgIA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodHwNClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgXGJlZ2lue2FycmF5fXtjfQ0KPSAgYV97MTF9YV97MjJ9YV97MzN9ICsgYV97MTJ9YV97MjN9YV97MzF9ICsgYV97MTN9YV97MjF9YV97MzJ9ICsgXFwNCi0gKGFfezEzfWFfezIyfWFfezMxfSArIGFfezExfWFfezIzfWFfezMyfSArIGFfezEyfWFfezIxfWFfezMzfSlcXA0KICAgIFxlbmR7YXJyYXl9IA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCioqRXhlbXBsbyoqOiBEYWRhIGEgbWF0cml6DQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0gQSA9IFxsZWZ0WyANCiAgICBcYmVnaW57YXJyYXl9e3Jycn0NCiAxICYgMiAmIDAgXFwNCi0xICYgMyAmIDIgXFwNCiAzICYtNCAmIDIgXFwNCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdLA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCnNldSBkZXRlcm1pbmFudGUgw6k6DQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0gZGV0KEEpID0gXGxlZnR8IA0KICAgIFxiZWdpbnthcnJheX17cnJyfHJyfQ0KIDEgJiAyICYgMCAmIDEgJiAyIFxcDQotMSAmIDMgJiAyICYtMSAmIDNcXA0KIDMgJi00ICYgMiAmIDMgJi00XFwNCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHR8IA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0NCiAgICBcYmVnaW57YXJyYXl9e2N9DQo9ICAmWzEuMy4yKzIuMi4zKzAuKC0xKS4oLTQpXSAtIFswLjMuMysxLjIuKC00KSsyLigtMSkuMl0gXFwNCj0gJiAoNisxMiswKS0oMC04LTQpID0gMTgrMTIgPSAzMFxcDQogICAgXGVuZHthcnJheX0gDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KTm8gYFJgbyBkZXJ0ZXJtaW5hbnRlIGRlIHVtYSBtYXRyaXogw6kgY2FsY3VsYWRvIHBlbGEgZnVuw6fDo28gYGRldCgpYC4NCg0KYGBge3J9DQpBID0gbWF0cml4KGMoMSwtMSwzLDIsMywtNCwwLDIsMiksMywzKQ0KcHJpbnQoQSkNCmRldChBKQ0KYGBgDQoNCiMjIyBJbnZlcnNhIGRlIHVtYSBtYXRyaXoNCg0KRGFkYSB1bWEgbWF0cml6IHF1YWRyYWRhICRBX3tuXHRpbWVzIG59JCwgc2UgZXhpc3RpciB1bWEgbWF0cml6IHF1YWRyYWRhICRCJCwgZGUgbWVzbWEgb3JkZW0sIHRhbCBxdWUgJEEuQj1CLkE9SWRfe259JCwgZW0gcXVlICRJZF97bn0kIMOpIGEgbWF0cml6IGlkZW50aWRhZGUgZGUgbWVzbWEgZGltZW5zw6NvIGRlICRBJCwgZW50w6NvICRCJCDDqSBhIGludmVyc2EgZGUgJEEkIGUgZGl6LXNlIHF1ZSAkQSQgw6kgaW52ZXJzw612ZWwuICoqTm90YcOnw6NvKiogJEFeey0xfSQuIFNlICRBJCDDqSBpbnZlcnPDrXZlbCwgc3VhIGludmVyc2Egw6kgw7puaWNhLiBTZSAkQSQgbsOjbyBhZG1pdGUgaW52ZXJzYSwgZGl6LXNlIHF1ZSAkQSQgw6kgc2luZ3VsYXIuDQoNCk5vIGBSYCB1dGlsaXphLXNlIGEgZnVuw6fDo28gYHNvbHZlKClgIHBhcmEgb2J0ZXIgYSBpbnZlcnNhIGRlIHVtYSBtYXRyaXouDQoNCmBgYHtyfQ0KQSA9IG1hdHJpeChjKDEsMiwzLDQpLDIsMikNCnByaW50KEEpDQpBX2ludmVyc2EgPSBzb2x2ZShBKQ0KcHJpbnQoQV9pbnZlcnNhKQ0KYGBgDQoNClBvZGUtc2UgdmVyaWZpY2FyIGEgY29uZGnDp8OjbyBkZSBleGlzdMOqbmNpYQ0KDQpgYGB7cn0NCkFfaW52ZXJzYSUqJUENCkElKiVBX2ludmVyc2ENCmBgYA0KDQojIyMgVHJhw6dvIGRlIHVtYSBtYXRyaXoNCg0KTyB0cmHDp28gZGUgdW1hIG1hdHJpeiAkQV97blx0aW1lcyBufSQgw6kgZGVmaW5pZG8gY29tbyBhIHNvbWEgZG9zIGVsZW1lbnRvcyBkZSBzdWEgZGlhZ29uYWwgcHJpbmNpcGFsLg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgXGJlZ2lue2FycmF5fXtjfQ0KdHIoQSkgPSBcc3VtX3tpPTF9XntufSBhX3tpaX0gPSBhX3sxMX0gKyBhX3syMn0gKyAuLi4rIGFfe25ufQ0KICAgIFxlbmR7YXJyYXl9IA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCk5vIGBSYCBwYXJhIGNhbGN1bGFyIG8gdHJhw6dvIGRlIHVtYSBtYXRyaXosIGV4dHJhaS1zZSBvcyBlbGVtZW50b3MgZGEgZGlhZ29uYWwgcHJpbmNpcGFsIGEgcGFydGlyIGRhIGZ1bsOnw6NvIGBkaWFnKClgIGUgYSBzb21hIGRlc3RlcyBlbGVtZW50b3MgYSBwYXJ0aXIgZGEgZnVuw6fDo28gYHN1bSgpYC4NCg0KYGBge3J9DQpBID0gbWF0cml4KGMoMSwtMSwzLDIsMywtNCwwLDIsMiksMywzKQ0KcHJpbnQoQSkNCmRpYWcoQSkgIyMjIGV4dHJhaW5kbyBvcyBlbGVtZW50b3MgZGEgZGlhZ29uYWwgcHJpbmNpcGFsDQp0cl9BID0gc3VtKGRpYWcoQSkpICNzb21hbmRvIG9zIGVsZW1lbnRvcyBkYSBkaWFnb25hbCBwcmluY2lwYWwNCnByaW50KHRyX0EpDQpgYGANCg0KIyMjIFZhbG9yZXMgKHJhxLHMgXplcykgZSB2ZXRvcmVzIGNhcmFjdGVyxLHMgXN0aWNvcyBkZSB1bWEgbWF0cml6IChhdXRvdmFsb3JlcyBlIGF1dG92ZXRvcmVzKQ0KDQpBcyByYcOtemVzIGNhcmFjdGVyw61zdGljYXMgZGUgdW1hIG1hdHJpeiAkQV97blx0aW1lcyBufSQgc8OjbyBhcyBzb2x1w6fDtWVzIGRhIGVxdWHDp8OjbyBkYWRhIHBlbG8gZGV0ZXJtaW5hbnRlICR8QSAtIFxsYW1iZGEgSXwgPSAwJCBlIHPDo28gY2hhbWFkYXMgZGUgYXV0b3ZhbG9yZXMgZGUgJEEkLiBPIERldGVybWluYW50ZSAkfEEgLSBcbGFtYmRhIEl8JCDDqSB1bSBwb2xpbsO0bWlvIG5hIHZhcmnDoXZlbCAkXGxhbWJkYSQgZGVub21pbmFkbyBwb2xpbsO0bWlvIGNhcmFjdGVyw61zdGljbyBlIGRlbm90YWRvIHBvciAkcChcbGFtYmRhKSA9IHxBIC0gXGxhbWJkYSBJfCQuDQoNCi0gICAqKkV4ZW1wbG8qKjogU2VqYSBhIG1hdHJpeg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9IEEgPSBcbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e3JyfQ0KICAxICYgNCBcXA0KICAgIDIgJiAzIFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XQ0KXGVuZHtlcW5hcnJheSp9DQpgYGANClVzYW5kbyBhIGVxdWHDp8OjbyBjYXJhY3RlcsOtc3RpY2E6DQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0gXGxlZnR8XGxlZnRbDQogICAgXGJlZ2lue2FycmF5fXtycn0NCiAgMSAmIDQgXFwNCiAgICAyICYgMyBcXA0KICAgIFxlbmR7YXJyYXl9DQogICAgXHJpZ2h0XS1cbGFtYmRhDQogICAgXGxlZnRbDQogICAgXGJlZ2lue2FycmF5fXtycn0NCiAgMSAmIDAgXFwNCiAgICAwICYgMSBcXA0KICAgIFxlbmR7YXJyYXl9DQogICAgXHJpZ2h0XQ0KICAgIFxyaWdodHwgPSAwIFxMZWZ0cmlnaHRhcnJvdyANClxsZWZ0fA0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogIDEgLSBcbGFtYmRhICYgNCBcXA0KICAgIDIgJiAzIC0gXGxhbWJkYSBcXA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodHwgPSAoMS1cbGFtYmRhKSgzLVxsYW1iZGEpIC04ID0gMA0KXGVuZHtlcW5hcnJheSp9DQpgYGANClBvcnRhbnRvLA0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgXGJlZ2lue2FycmF5fXtjfQ0KICBwKFxsYW1iZGEpID0gXGxhbWJkYV4yIC0gNFxsYW1iZGEgLSA1ID0gMA0KICAgIFxlbmR7YXJyYXl9LCANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpkZXN0YSBmb3JtYSBhcyByYcOtemVzICRcbGFtYmRhX3sxfSA9IDUkIGUgJFxsYW1iZGFfezJ9ID0gLTEkIHPDo28gb3MgYXV0b3ZhbG9yZXMgZGEgbWF0cml6ICRBJC4NCg0KLSAgICoqKkF1dG92ZXRvcmVzKioqOiBwYXJhICRcbGFtYmRhX3sxfSA9IDUkDQoNCkRldGVybWluYWRvcyBvcyBhdXRvdmFsb3JlcyAkXGxhbWJkYV97aX0kLCBwb2RlLXNlIGVuY29udHJhciBvcyBhdXRvdmV0b3JlcyBwZWxhIHNlZ3VpbnRlIGVxdWHDp8OjbzoNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfQ0KICAgIFxiZWdpbnthcnJheX17Y30NCiAgQSB2ID0gXGxhbWJkYSB2DQogICAgXGVuZHthcnJheX0gXExlZnRyaWdodGFycm93IA0KXGJlZ2lue2FycmF5fXtjfQ0KICAoQS01IEkpIHYgPSAwDQogICAgXGVuZHthcnJheX0gIFxMZWZ0cmlnaHRhcnJvdyANCiAgICBcbGVmdFx7XGxlZnRbDQogICAgXGJlZ2lue2FycmF5fXtycn0NCiAgMSAmIDQgXFwNCiAgICAyICYgMyBcXA0KICAgIFxlbmR7YXJyYXl9DQogICAgXHJpZ2h0XS01DQogICAgXGxlZnRbDQogICAgXGJlZ2lue2FycmF5fXtycn0NCiAgMSAmIDAgXFwNCiAgICAwICYgMSBcXA0KICAgIFxlbmR7YXJyYXl9DQogICAgXHJpZ2h0XQ0KICAgIFxyaWdodFx9ICBcbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e2N9DQogIHZfezF9IFxcDQogICAgdl97Mn0gXFwNCiAgICBcZW5ke2FycmF5fQ0KICAgIFxyaWdodF0gPSBcbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e2N9DQogICAwIFxcDQogICAgIDAgXFwNCiAgICBcZW5ke2FycmF5fQ0KICAgIFxyaWdodF0NClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9XExlZnRyaWdodGFycm93IFxsZWZ0Ww0KICAgIFxiZWdpbnthcnJheX17cnJ9DQogLTQgJiA0IFxcDQogICAgMiAmIC0yIFxcDQogICAgXGVuZHthcnJheX0gXHJpZ2h0XSBcbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e2N9DQogIHZfezF9IFxcDQogICAgdl97Mn0gXFwNCiAgICBcZW5ke2FycmF5fQ0KICAgIFxyaWdodF0gPSBcbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e2N9DQogICAwIFxcDQogICAgIDAgXFwNCiAgICBcZW5ke2FycmF5fQ0KICAgIFxyaWdodF0gXExlZnRyaWdodGFycm93IFxsZWZ0XHsNCiAgICBcYmVnaW57YXJyYXl9e3J9DQogICAtNHZfezF9ICsgNHZfezJ9ICA9ICAwIFxcDQogICAgICAydl97MX0gLSAydl97Mn0gID0gIDAgXFwNCiAgICBcZW5ke2FycmF5fQ0KICAgIFxyaWdodC4gIFxMZWZ0cmlnaHRhcnJvdyB2X3sxfSA9IHZfezJ9ID0gciBcTGVmdHJpZ2h0YXJyb3cgXGJvbGRzeW1ib2x7dn0gPSBcbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e2N9DQogICByIFxcDQogICByIFxcDQogICAgXGVuZHthcnJheX0NCiAgICBccmlnaHRdLCByIFxpbiBcbWF0aGJie1J9DQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSBcUmlnaHRhcnJvdyBcbGFtYmRhX3sxfSA9IDUgXExlZnRyaWdodGFycm93ICBcYm9sZHN5bWJvbHt2fSA9IHIgXGxlZnRbDQogICAgXGJlZ2lue2FycmF5fXtjfQ0KICAgMSBcXA0KICAgMSBcXA0KICAgIFxlbmR7YXJyYXl9DQogICAgXHJpZ2h0XQ0KXGVuZHtlcW5hcnJheSp9DQpgYGANCk5vIGBSYCB1dGlsaXphLXNlIGEgZnVuw6fDo28gYGVpZ2VuKClgIHBhcmEgb2J0ZXIgb3MgYXV0b3ZhbG9yZXMgZSBhdXRvdmV0b3JlcyBkZSB1bWEgbWF0cml6Lg0KDQotICAgKk9zIGF1dG92ZXRvcmVzIHPDo28gbm9ybWFsaXphZG9zIG5vIGBSYC4qDQoNCmBgYHtyfQ0KQSA9IG1hdHJpeChjKDEsMiw0LDMpLDIsMikgDQpwcmludChBKQ0KZWlnZW4oQSkNCmBgYA0KDQojIFByaW5jaXBhaXMgZGVmaW5pw6fDtWVzIGRhIGFuw6FsaXNlIG11bHRpdmFyaWFkYQ0KDQotICAgKipWZXRvciBhbGVhdMOzcmlvKio6IFNlamEgJFgkIHVtIHZldG9yIGNvbnRlbmRvICRuJCBjb21wb25lbnRlcywgb25kZSBjYWRhIGNvbXBvbmVudGUgw6kgdW1hIHZhcmnDoXZlbCBhbGVhdMOzcmlhICh2LmEuKSwgaXN0byDDqSwgJFxib2xkc3ltYm9se1h9X3tpfSQgw6kgdW1hIHYuYS4sICRcZm9yYWxsJCAkaT0xLDIsLi4uLHAkLiBFbnTDo28gJFgkIMOpIGNoYW1hZG8gZGUgdmV0b3IgYWxlYXTDs3JpbyBlIMOpIGRlbm9taW5hZG8gcG9yOg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9XGJvbGRzeW1ib2x7WH09XGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y30NCiAgICAgICAgXGJvbGRzeW1ib2x7WH1fezF9ICAgICAgXFwNCiAgICAgICAgXGJvbGRzeW1ib2x7WH1fezJ9ICAgICAgXFwNCiAgICAgICAgXHZkb3RzICBcXA0KICAgICAgICBcYm9sZHN5bWJvbHtYfV97cH0gICAgICBcXA0KICAgICAgICANCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdIA0KXGVuZHtlcW5hcnJheSp9DQpgYGANClZldG9yIHRyYW5zcG9zdG86ICRcYm9sZHN5bWJvbHtYfV57J30gPSBbXGJvbGRzeW1ib2x7WH1fezF9IFxib2xkc3ltYm9se1h9X3syfVxkb3RzXGJvbGRzeW1ib2x7WH1fe3B9XSQuDQoNCioqRXhlbXBsbyoqOiBDb25zaWRlcmUgdW1hIGVtcHJlc2EgZGUgbWluw6lyaW8gZGUgZmVycm8uIEFsZ3VtYXMgdmFyacOhdmVpcyBpbXBvcnRhbnRlcyBwYXJhIGF2YWxpYcOnw6NvIGRhIHF1YWxpZGFkZSBkbyBtaW7DqXJpbyBzw6NvOiAkWF97MX0kIC0gdGVvciBkZSBmZXJybyAoZW0gJSk7ICRYX3syfSQgLSB0ZW9yIGRlIHVtaWRhZGUgZSAkWF97M30kIC0gZ3JhbnVsb21ldHJpYSBkbyBtaW7DqXJpbywgcXVlIHPDo28gdi5hLg0KDQpFbnTDo28gJFxib2xkc3ltYm9se1h9ID0gW1xib2xkc3ltYm9se1h9X3sxfVxib2xkc3ltYm9se1h9X3syfVxib2xkc3ltYm9se1h9X3szfV1eeyd9JCDDqSB1bSB2ZXRvciBjb20gJHAgPSAzJC4NCg0KKipFeGVtcGxvKio6IFVtYSBzZWxlw6fDo28gZGUgNCBmaXJtYXMgZGUgcmHDp8OjbyBkZSBNaW5hcyBHZXJhaXMgZm9pIG9idGlkYSBwYXJhIGF2YWxpYXIgYSB2ZW5kYSBkZSByYcOnw7Vlcy4gQ2FkYSBvYnNlcnZhw6fDo28gYml2YXJpYWRhIGZvcm5lY2V1IGEgcXVhbnRpZGFkZSBkZSBzYWNvcyBkZSByYcOnw6NvIHZlbmRpZG9zIGUgYSBxdWFudGlkYWRlIGRlIHJlYWlzIGRlIGNhZGEgdmVuZGEuIE9zIGRhZG9zIG9idGlkb3MgbmEgZm9ybWEgdGFidWxhciBzw6NvOg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9IA0KICAgIFxiZWdpbnthcnJheX17bHxjY2NjfVxobGluZQ0KICAgICAgICBcdGV4dHtWw6FyaWF2ZWwgMSAocmVhaXMvdmVuZGFzKX0gJiA4MCAmIDEyMCAmIDkwICYgMTEwIFxcIFxobGluZQ0KICAgICAgICBcdGV4dHtWw6FyaWF2ZWwgMiAobsO6bWVybyBkZSBzYWNvcyBkZSByYcOnw6NvIHZlbmRpZG9zKX0gJiAxMCAmIDEyICYgNiAmIDhcXCBcaGxpbmUNCiAgICBcZW5ke2FycmF5fSANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpQb2RlLXNlIGVzY3JldmVyIGVzdGVzIGRhZG9zIG5hIGZvcm1hIG1hdHJpY2lhbC4NCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfVxib2xkc3ltYm9se1h9PVxsZWZ0WyANCiAgICBcYmVnaW57YXJyYXl9e2NjfQ0KICAgICAgICBYX3sxMX0gJiAgICBYX3sxMn0gIFxcDQogICAgICAgIFhfezIxfSAmICAgIFhfezIyfSAgXFwNCiAgICAgICAgWF97MzF9ICYgICAgWF97MzJ9ICBcXA0KICAgICAgICBYX3s0MX0gJiAgICBYX3s0Mn0gIFxcDQogICAgICAgIA0KICAgIFxlbmR7YXJyYXl9IA0KICAgIFxyaWdodF0gDQo9IFxsZWZ0WyANCiAgICBcYmVnaW57YXJyYXl9e3JyfQ0KODAgICYgMTAgICAgXFwNCjEyMCAmIDEyICAgIFxcDQo5MCAgJiA2ICAgICBcXA0KMTEwICYgOCAgICAgICAgIFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQotICAgRXNjcmV2ZW5kbyBvcyBkYWRvcyBuYSBmb3JtYSBkZSBtYXRyaXogbm8gYFJgLg0KDQpgYGB7cn0NCk0xID0gbWF0cml4KGMoODAsMTIwLDkwLDExMCwxMCwxMiw2LDgpLDQsMixieXJvdyA9IEZBTFNFKQ0KTTENCmBgYA0KDQotICAgKipWZXRvciBkZSBtw6lkaWFzKio6IFNlamEgJFxib2xkc3ltYm9se1h9JCB1bSB2ZXRvciBhbGVhdMOzcmlvLiBPIHZldG9yICRcYm9sZHN5bWJvbHtcbXV9ID0gRShcYm9sZHN5bWJvbHtYfSkkIMOpIGNoYW1hZG8gZGUgdmV0b3IgZGUgbcOpZGlhcyBkbyB2ZXRvciAkXGJvbGRzeW1ib2x7WH09W1xib2xkc3ltYm9se1h9X3sxfVxib2xkc3ltYm9se1h9X3sxfVxkb3RzXGJvbGRzeW1ib2x7WH1fe3B9XV57J30kLCBzZW5kbw0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9XGJvbGRzeW1ib2x7XG11fT1FKFxib2xkc3ltYm9se1h9KT1cbGVmdFsgDQogICAgXGJlZ2lue2FycmF5fXtjfQ0KICAgICAgICBFKFxib2xkc3ltYm9se1h9X3sxfSkgICAgICAgXFwNCiAgICAgICAgRShcYm9sZHN5bWJvbHtYfV97Mn0pICAgICAgIFxcDQogICAgICAgIFx2ZG90cyAgXFwNCiAgICAgICAgRShcYm9sZHN5bWJvbHtYfV97cH0pICAgICAgIFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSANCj0gXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y30NCiAgICBcYm9sZHN5bWJvbHtcbXV9X3sxfSBcXA0KICAgIFxib2xkc3ltYm9se1xtdX1fezJ9IFxcDQogICAgXHZkb3RzIFxcDQogICAgXGJvbGRzeW1ib2x7XG11fV97cH0gXFwNCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdIA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCmVtIHF1ZSAkXG11X3tpfT1FKFhfe2l9KSQgw6kgYSBtw6lkaWEgb3UgZXNwZXJhbsOnYSBkYSB2LmEuICRYX3tpfSQsICRpPTEsMiwuLi4scCQuDQoNCiMjIE1lZGlkYXMgZGVzY3JpdGl2YXMNCg0KIyMjIE3DqWRpYSBhbW9zdHJhbA0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgXGJhcntYfV97an09ICBcZGZyYWN7XGRpc3BsYXlzdHlsZVxzdW1fe2k9MX1ee3B9IFhfe2lqfX17bn0sIFx0ZXh0e2NvbSBqPTEsMiwuLi4scC59DQogICAgXGVuZHtlcW5hcnJheSp9DQpgYGANCiMjIyBWYXJpw6JuY2lhIGFtb3N0cmFsDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0NCiAgICAgICAgU157Mn1fe2p9PSBTX3tqan0gPSBcZGZyYWN7XGRpc3BsYXlzdHlsZVxzdW1fe2k9MX1ee3B9IChYX3tpan0tXGJhcntYfV97an0pXnsyfX17bi0xfSwgXHRleHR7Y29tIGo9MSwyLC4uLixwLn0NClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQojIyMgQ292YXJpw6JuY2lhIGFtb3N0cmFsDQoNCkEgY292YXJpw6JuY2lhIGFtb3N0cmFsIGVudHJlIGR1YXMgdmFyacOhdmVpcyAkWF97an0kIGUgJFhfe2peeyd9fSQsIHF1ZSBtZWRlIG8gZ3JhdSBkZSByZWxhY2lvbmFtZW50byBsaW5lYXIgZW50cmUgZWxhcywgw6kgZGFkYSBwb3I6DQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0NCiAgICBTX3tqal57J319ID0gXGRmcmFje1xkaXNwbGF5c3R5bGVcc3VtX3tpPTF9XntwfSAoWF97aWp9LVxiYXJ7WH1fe2p9KShYX3tpal57J319LVxiYXJ7WH1fe2peeyd9fSl9e24tMX0sIFx0ZXh0e2NvbSBqPWokXnsnfSQ9MSwyLC4uLixwLn0NClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQojIyMgQ29ycmVsYcOnw6NvIGFtb3N0cmFsDQoNCk8gZ3JhdSBkZSBjb3JyZWxhw6fDo28gZW50cmUgJFhfe2p9JCBlICRYX3tqXnsnfX0kIMOpIGRhZGEgcG9yOg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgICAgICAgICByX3tqal57J319ID0gXGRmcmFje1Nfe2pqXnsnfX19e1xzcXJ0e1Nfe2pqfX1cc3FydHtTX3tqaid9fX0gPSAgXGRmcmFje1xkaXNwbGF5c3R5bGVcc3VtX3tpPTF9XntufSAoWF97aWp9LVxiYXJ7WH1fe2p9KShYX3tpal57J319LVxiYXJ7WH1fe2peeyd9fSl9e1xzcXJ0e1xkaXNwbGF5c3R5bGVcc3VtX3tpPTF9XntufSAoWF97aWp9LVxiYXJ7WH1fe2p9KV57Mn19XHNxcnR7XGRpc3BsYXlzdHlsZVxzdW1fe2k9MX1ee259KFhfe2lqXnsnfX0tXGJhcntYfV97al57J319fSApXnsyfX0NClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQojIyMgTWF0cml6IGRlIGNvdmFyacOibmNpYSBhbW9zdHJhbA0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9XGJvbGRzeW1ib2x7U309XGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2NjY30NCiAgICAgICAgU197MTF9ICYgICAgU197MTJ9ICYgXGRvdHMgJiAgICBTX3sxcH1cXA0KICAgICAgICBTX3syMX0gJiAgICBTX3syMn0gJiBcZG90cyAmICAgIFNfezJwfVxcDQogICAgICAgIFx2ZG90cyAmICAgIFx2ZG90cyAmIFxkZG90cyAmICAgXHZkb3RzXFwNCiAgICAgICAgU197cDF9ICYgICAgU197cDJ9ICYgXGRvdHMgJiBTX3twcH1cXCAgICAgICANCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdIA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCiMjIyBNYXRyaXogZGUgY29ycmVsYcOnw6NvIGFtb3N0cmFsDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn1cYm9sZHN5bWJvbHtSfT1cbGVmdFsgDQogICAgICAgIFxiZWdpbnthcnJheX17Y2NjY30NCiAgICAgICAgICAgIDEgJiByX3sxMn0gJiBcZG90cyAmICAgIHJfezFwfVxcDQogICAgICAgICAgICByX3syMX0gJiAgICAxICYgXGRvdHMgJiByX3sycH1cXA0KICAgICAgICAgICAgXHZkb3RzICYgICAgXHZkb3RzICYgXGRkb3RzICYgICBcdmRvdHNcXA0KICAgICAgICAgICAgcl97cDF9ICYgICAgcl97cDJ9ICYgXGRvdHMgJiAxXFwgICAgICAgIA0KICAgICAgICBcZW5ke2FycmF5fSANCiAgICAgICAgXHJpZ2h0XSANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpWb2x0YW5kbyBhbyBleGVtcGxvIGFudGVyaW9yLCB0ZW1vczoNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfQ0KIFxiYXJ7WH1fezF9ID0gXGRmcmFje1xkaXNwbGF5c3R5bGUgXHN1bV97aT0xfV57NH0gWF97aTF9fXs0fSA9IFxkZnJhY3s4MCArIDEyMCArIDkwICsgMTEwfXs0fSA9IDEwMA0KICAgIFxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgXGJhcntYfV97Mn0gPSBcZGZyYWN7XGRpc3BsYXlzdHlsZSBcc3VtX3tpPTF9Xns0fSBYX3tpMn19ezR9ID0gXGRmcmFjezEwICsgMTIgKyA2ICsgOH17NH0gPSA5DQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KUG9ydGFudG8sIG8gdmV0b3IgZGUgbcOpZGlhcyDDqToNCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfVxib2xkc3ltYm9se1xiYXJ7WH19PVxsZWZ0WyANCiAgICBcYmVnaW57YXJyYXl9e2N9DQogICAgICAgIFxiYXJ7WH1fezF9ICAgICBcXA0KICAgICAgICBcYmFye1h9X3syfSAgICAgXFwNCiAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdIA0KICAgID0gXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y30NCiAgICAgICAgMTAwICAgICBcXA0KICAgICAgICA5ICAgICAgIFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQpBZ29yYSwgY2FsY3VsYW5kbyBhcyBjb3ZhcmnDom5jaWFzDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0NClxiZWdpbnthcnJheX17bGx9ICAgDQpTX3sxMX0gPSAmIFxkZnJhY3tcbGVmdFsgKDgwLTEwMCkgXnsyfSArICgxMjAtMTAwKV57Mn0gKyAoOTAtMTAwKV57Mn0gKyAoMTEwLTEwMCleezJ9XHJpZ2h0XSB9ezN9ID0gMzMzLDMzMyBcXA0KICAgIFNfezIyfSA9ICYgXGRmcmFje1xsZWZ0WyAoMTAtOSkgXnsyfSArICgxMi05KV57Mn0gKyAoNi05KV57Mn0gKyAoOC05KV57Mn1ccmlnaHRdIH17M30gPSA2LDY2NyBcXCANClNfezEyfSA9JiAgWyg4MC0xMDApKDEwLTkpKygxMjAtMTAwKSgxMi05KSAgXFwNCiYgKyg5MC0xMDApKDYtOSkrKDExMC0xMDApKDgtOSldLzMgID0gMjAgICAgXFwNCiAgICBTX3syMX0gPSBTX3sxMn0gJiAgPSAyMCBcXA0KXGVuZHthcnJheX0gDQpcZW5ke2VxbmFycmF5Kn0NCmBgYA0KKioqTWF0cml6IGRlIGNvdmFyacOibmNpYSoqKg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9XGJvbGRzeW1ib2x7U309XGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2N9IA0KICAgIFNfezExfSAmIFNfezEyfSAgICAgXFwNCiAgICBTX3syMX0gJiBTX3syMn0gICAgIFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSANCiAgICA9IFxsZWZ0Ww0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogICAgICAgIDMzMywzMzMgJiAyMCwwMDAgICAgICAgIFxcDQogICAgICAgIDIwLDAwMCAgJiA2LDY2NyAgICAgICAgIFxcDQogICAgXGVuZHthcnJheX0gDQogICAgXHJpZ2h0XSANCiAgICBcZW5ke2VxbmFycmF5Kn0NCmBgYA0KQ2FsY3VsYW5kbyBhcyBjb3JyZWxhw6fDtWVzDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn0NCnJfezEyfSA9IFxkZnJhY3tTX3sxMn19e1xzcXJ0e1NfezExfX1cc3FydHtTX3sxMn19fSA9IFxkZnJhY3syMH17XHNxcnR7MzMzLDMzM31cc3FydHs2LDY2N319ID0gMCw0MjQzLA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCioqKk1hdHJpeiBkZSBjb3JyZWxhw6fDo28qKioNCg0KY29tbyAkcl97MjF9PXJfezEyfSA9IDAsNDI0MyQsIHRlbW9zDQoNCmBgYHs9dGV4fQ0KXGJlZ2lue2VxbmFycmF5Kn1cYm9sZHN5bWJvbHtSfT1cbGVmdFsNCiAgICBcYmVnaW57YXJyYXl9e2NjfQ0KICAgIHJfezExfSAmIHJfezEyfSAgICAgXFwNCiAgICByX3syMX0gJiByX3syMn0gICAgIFxcDQogICAgICAgICAgICBcZW5ke2FycmF5fSANCiAgICBccmlnaHRdID0gXGxlZnRbIA0KICAgIFxiZWdpbnthcnJheX17Y2N9DQogICAgMSwwMDAwICYgMCw0MjQzIFxcDQogICAgMCw0MjQzICAmICAxLDAwMDAgICBcXA0KICAgIFxlbmR7YXJyYXl9DQogICAgXHJpZ2h0XSANClxlbmR7ZXFuYXJyYXkqfQ0KYGBgDQoqU29sdcOnw7VlcyBubyBgUmAqDQoNCmBgYHtyfQ0KTTEgPSBtYXRyaXgoYyg4MCwxMjAsOTAsMTEwLDEwLDEyLDYsOCksNCwyLGJ5cm93ID0gRkFMU0UpDQpwcmludChNMSkNCmBgYA0KDQotICAgQ2FsY3VsYW5kbyBvIHZldG9yIGRlIG3DqWRpYXMNCg0KYGBge3J9DQptZWRfeDEgPSBtZWFuKE0xWywxXSkNCm1lZF94MQ0KbWVkX3gyID0gbWVhbihNMVssMl0pDQptZWRfeDINCg0KcmJpbmQobWVkX3gxLG1lZF94MikNCmBgYA0KDQotICAgQ2FsY3VsYW5kbyBhIG1hdHJpeiBkZSBjb3ZhcmnDom5jaWENCg0KYGBge3J9DQpTID0gdmFyKE0xKQ0KUw0KYGBgDQoNCi0gICBDYWxjdWxhbmRvIG8gY29lZmljaWVudGUgZGUgY29ycmVsYcOnw6NvDQoNCmBgYHtyfQ0KUiA9IGNvcihNMSkNClINCmBgYA0KDQotICAgKipWYXJpw6JuY2lhIHRvdGFsKioNCg0KQSB2YXJpw6JuY2lhIHRvdGFsIGRvIHZldG9yIGFsZWF0w7NyaW8gJFxib2xkc3ltYm9se1h9JCDDqSBkZWZpbmlkYSBjb21vOg0KDQpgYGB7PXRleH0NClxiZWdpbntlcW5hcnJheSp9DQogICAgXGJlZ2lue2FycmF5fXtjfQ0KICAgIFx0ZXh0e3RyYcOnb30gKFxib2xkc3ltYm9se1N9X3twXHRpbWVzIHB9KSA9IHRyKFxib2xkc3ltYm9se1N9X3twXHRpbWVzIHB9KSA9IFNfezExfStTX3syMn0gKyAuLi4rIFNfe3BwfQ0KICAgIFxlbmR7YXJyYXl9IA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCi0gICAqKlZhcmnDom5jaWEgZ2VuZXJhbGl6YWRhKioNCg0Kw4kgZGVmaW5pZGEgY29tbyBvIGRldGVybWluYW50ZSBkYSBtYXRyaXogJFxib2xkc3ltYm9se1N9X3twXHRpbWVzIHB9JCwgb3Ugc2VqYSwgJHxcYm9sZHN5bWJvbHtTfV97cFx0aW1lcyBwfXwkLiBBbyBjb250csOhcmlvIGRhIHZhcmnDom5jaWEgdG90YWwsIGVsYSDDqSBpbmZsdWVuY2lhZGEgcGVsYXMgY292YXJpw6JuY2lhcyAob3UgY29ycmVsYcOnw7VlcykgZW50cmUgYXMgdmFyacOhdmVpcyAkWF97aX0kLCAkaT0xLDIsLi4uLHAkLg0KDQoqKkV4ZW1wbG8qKjogQ29sZXRvdS1zZSB1bWEgYW1vc3RyYSBkZSAxMiByb2NoYXMgZGUgdW1hIGRldGVybWluYWRhIHJlZ2nDo28uIFBhcmEgY2FkYSByb2NoYSwgdGVtLXNlIGFzIHBvcmNlbnRhZ2VucyBkZSBxdWFydHpvICgkWF97MX0kKSBlIGZlbGRzcGF0byAoJFhfezJ9JCksIGFsw6ltIGRvIHZhbG9yIGRlIHVtIMOtbmRpY2UgcXVlIG1lZGUgYSBzdWEgY29yICgkWF97M30kKS4NCg0KYGBgez10ZXh9DQpcYmVnaW57ZXFuYXJyYXkqfSANCiAgICBcYmVnaW57YXJyYXl9e2NjY2N9XGhsaW5lDQogICAgICAgIFx0ZXh0e1JvY2hhfSAmIFx0ZXh0e1F1YXJ0em8gKCUpfSAmIFx0ZXh0e0ZlbGRzcGF0byAoJSl9ICYgXHRleHR7Q29yfSBcXCBcaGxpbmUNCiANCjEgICAmICAgMzksNiAgICAmICAgNzMsMCAgICAmICAgMyw2IFxcDQoyICAgJiAgIDM4LDkgICAgJiAgIDU3LDQgICAgJiAgIDIsNyBcXA0KMyAgICYgICA0LDkgJiAgIDc0LDMgICAgJiAgIDE4LDggICAgXFwNCjQgICAmICAgNCw1ICYgICA2Myw5ICAgICYgICAzMCw1ICAgIFxcDQo1ICAgJiAgIDEzLDcgICAgJiAgIDY0LDAgICAgJiAgIDIxLDIgICAgXFwNCjYgICAmICAgMzAsOSAgICAmICAgNjUsMSAgICAmICAgMSwyIFxcDQo3ICAgJiAgIDI3LDkgICAgJiAgIDY5LDEgICAgJiAgIDUsNiBcXA0KOCAgICYgICAyMyw3ICAgICYgICA3NiwwICAgICYgICAzLDQgXFwNCjkgICAmICAgMjAsMSAgICAmICAgNzQsMSAgICAmICAgOCw5IFxcDQoxMCAgJiAgIDE2LDQgICAgJiAgIDYxLDcgICAgJiAgIDM1LDkgICAgXFwNCjExICAmICAgMTUsMCAgICAmICAgNjUsNiAgICAmICAgMTYsNiAgICBcXA0KMTIgICYgICAxOCw0ICAgICYgICA2Miw1ICAgICYgICAxNCwyICAgIA0KICAgIFxcIFxobGluZQ0KICAgIFxlbmR7YXJyYXl9IA0KXGVuZHtlcW5hcnJheSp9DQpgYGANCjEuICBPIHZldG9yIGRlIG3DqWRpYXMuDQoyLiAgRmHDp2EgdW0gZ3LDoWZpY28gZGUgZGlzcGVyc8OjbyBlbnRyZSBhcyB2YXJpw6F2ZWlzLiBWb2PDqiBkaXJpYSBxdWUgaMOhIGNvcnJlbGHDp8OjbyBlbnRyZSBlbGFzPw0KMy4gIEZhw6dhIHVtIGJveC1wbG90Lg0KNC4gIEVuY29udHJlIGEgbWF0cml6IGRlIGNvdmFyacOibmNpYS4NCjUuICBFbmNvbnRyZSBhIG1hdHJpeiBkZSBjb3JyZWxhw6fDo28uIFF1YWlzIHN1YXMgY29uY2x1c8O1ZXM/DQo2LiAgUXVhbCBhIHZhcmnDom5jaWEgdG90YWwgZSBnZW5lcmFsaXphZGEgPw0KNy4gIEVuY29udHJlIG9zIGF1dG92YWxvcmVzIGUgYXV0b3ZldG9yZXMuDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KI3NldHdkKCIvaG9tZS9kZW5uaXNvbi9Eb2N1bWVudG9zL1VGT1BBXzIwMTlfMi9QUEdTQVEiKQ0KI2RhZG9zX3JvY2hhIDwtIHJlYWQudGFibGUoZmlsZT0icm9jaGEudHh0IiwgZGVjID0gIiwiLGhlYWRlcj1UKQ0KI2F0dGFjaChkYWRvc19yb2NoYSkNCiNoZWFkKGRhZG9zX3JvY2hhKQ0KYGBgDQoNCg0KDQoNCg==