hllinas2023

1 Librerías

1.0.1 Para EFA

El software R dispone de varias funciones de diferentes paquetes para calcular EFA:

library(psych)
library(GPArotation)

1.0.2 Para otros análisis

library(aplore3)       #Base de datos para los ejemplos
library(lsm)           #Base de datos para ejemplos y estimaciones del Log-verosimilitud
library(tidyverse)     #Incluye a dplyr y ggplot2
library(stringr)       #Reemplazar caracteres en un data frame
library(outliers)      #outliers::grubbs.test
library(EnvStats)      #EnvStats::rosnerTest
library(DMwR2)         #LOF (Local Outlier Factor)
library(rgl)           #rgl::plot3d
library(corrplot)      #Matriz de correlaciones
library(textshape)     #column_to_rownames
library(openxlsx)  # Librería para escribir archivos de Excel

2 Ejemplo: Enunciado

Vamos a utilizar un conjunto de datos llamado bfi para llevar a cabo un EFA el cual proviene del paquete psych. Este conjunto de datos consiste en 25 ítems de personalidad autoreportados del International Personality Item Pool y otras variables como gender (género), education level (nivel educativo) y age (edad) de 2800 sujetos, utilizado en la Synthetic Aperture Personality Assessment (SAPA project, Evaluación de Personalidad de Apertura Sintética). Los ítems de personalidad se dividen en 5 categorías:

  • A = Agreeableness (Amabilidad).

  • C = Conscientiousness (Responsabilidad).

  • E = Extraversion (Extraversión).

  • N = Neuroticism (Neuroticismo).

  • O = Openness (Apertura).

Cada ítem fue respondido en una escala de seis puntos:

  • 1 = Very Inaccurate (Muy Inexacto).

  • 2 = Moderately Inaccurate (Moderadamente Inexacto).

  • 3 = Slightly Inaccurate (Ligeramente Inexacto).

  • 4 = Slightly Accurate (Ligeramente Preciso).

  • 5 = Moderately Accurate (Moderadamente Preciso).

  • 6 = Very Accurate (Muy Preciso).

datosCompleto <- psych::bfi
attach(datosCompleto)
names(datosCompleto)
##  [1] "A1"        "A2"        "A3"        "A4"        "A5"        "C1"       
##  [7] "C2"        "C3"        "C4"        "C5"        "E1"        "E2"       
## [13] "E3"        "E4"        "E5"        "N1"        "N2"        "N3"       
## [19] "N4"        "N5"        "O1"        "O2"        "O3"        "O4"       
## [25] "O5"        "gender"    "education" "age"

Se resalta que sólo algunas de estas variables se utilizarán para realizar el EFA.

dat <- datosCompleto[1:25]
attach(dat)
head(dat,4) 
A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 E1 E2 E3 E4 E5 N1 N2 N3 N4 N5 O1 O2 O3 O4 O5
61617 2 4 3 4 4 2 3 3 4 4 3 3 3 4 4 3 4 2 2 3 3 6 3 4 3
61618 2 4 5 2 5 5 4 4 3 4 1 1 6 4 3 3 3 3 5 5 4 2 4 3 3
61620 5 4 5 4 4 4 5 4 2 5 2 4 4 4 5 4 5 4 2 3 4 2 5 5 2
61621 4 4 6 5 5 4 4 3 5 5 5 3 4 4 4 2 5 2 4 1 3 3 4 3 5

3 Ejemplo: Solución

3.0.1 Estadísticos descriptivos básicos

Primero, es recomendable examinar los datos antes de realizar cualquier análisis. Cualquier participante que tenga algún dato faltante será excluido por completo del análisis. Se pueden utilizar diversas funciones (como se muestra a continuación).

describe(dat)
##    vars    n mean   sd median trimmed  mad min max range  skew kurtosis   se
## A1    1 2784 2.41 1.41      2    2.23 1.48   1   6     5  0.83    -0.31 0.03
## A2    2 2773 4.80 1.17      5    4.98 1.48   1   6     5 -1.12     1.05 0.02
## A3    3 2774 4.60 1.30      5    4.79 1.48   1   6     5 -1.00     0.44 0.02
## A4    4 2781 4.70 1.48      5    4.93 1.48   1   6     5 -1.03     0.04 0.03
## A5    5 2784 4.56 1.26      5    4.71 1.48   1   6     5 -0.85     0.16 0.02
## C1    6 2779 4.50 1.24      5    4.64 1.48   1   6     5 -0.85     0.30 0.02
## C2    7 2776 4.37 1.32      5    4.50 1.48   1   6     5 -0.74    -0.14 0.03
## C3    8 2780 4.30 1.29      5    4.42 1.48   1   6     5 -0.69    -0.13 0.02
## C4    9 2774 2.55 1.38      2    2.41 1.48   1   6     5  0.60    -0.62 0.03
## C5   10 2784 3.30 1.63      3    3.25 1.48   1   6     5  0.07    -1.22 0.03
## E1   11 2777 2.97 1.63      3    2.86 1.48   1   6     5  0.37    -1.09 0.03
## E2   12 2784 3.14 1.61      3    3.06 1.48   1   6     5  0.22    -1.15 0.03
## E3   13 2775 4.00 1.35      4    4.07 1.48   1   6     5 -0.47    -0.47 0.03
## E4   14 2791 4.42 1.46      5    4.59 1.48   1   6     5 -0.82    -0.30 0.03
## E5   15 2779 4.42 1.33      5    4.56 1.48   1   6     5 -0.78    -0.09 0.03
## N1   16 2778 2.93 1.57      3    2.82 1.48   1   6     5  0.37    -1.01 0.03
## N2   17 2779 3.51 1.53      4    3.51 1.48   1   6     5 -0.08    -1.05 0.03
## N3   18 2789 3.22 1.60      3    3.16 1.48   1   6     5  0.15    -1.18 0.03
## N4   19 2764 3.19 1.57      3    3.12 1.48   1   6     5  0.20    -1.09 0.03
## N5   20 2771 2.97 1.62      3    2.85 1.48   1   6     5  0.37    -1.06 0.03
## O1   21 2778 4.82 1.13      5    4.96 1.48   1   6     5 -0.90     0.43 0.02
## O2   22 2800 2.71 1.57      2    2.56 1.48   1   6     5  0.59    -0.81 0.03
## O3   23 2772 4.44 1.22      5    4.56 1.48   1   6     5 -0.77     0.30 0.02
## O4   24 2786 4.89 1.22      5    5.10 1.48   1   6     5 -1.22     1.08 0.02
## O5   25 2780 2.49 1.33      2    2.34 1.48   1   6     5  0.74    -0.24 0.03

Se resalta que, la función describe de la librería psych, el output:

  • timmed se refiere a la mediana truncada, que es una medida de tendencia central robusta que calcula la mediana de un conjunto de datos después de eliminar un cierto porcentaje de observaciones más extremas.

  • mad significa desviación absoluta mediana, que es una medida de dispersión que indica la variabilidad de los datos en relación con la mediana.

  • skew se refiere a la asimetría de los datos, que indica si la distribución de los datos es simétrica o si está sesgada hacia un lado. Un valor positivo indica sesgo hacia la derecha, mientras que un valor negativo indica sesgo hacia la izquierda.

  • kurtosis se refiere a la curtosis de los datos, que indica la forma de la distribución de los datos en relación con una distribución normal. Un valor de kurtosis mayor que cero indica una distribución más puntiaguda (más picos) que la distribución normal, mientras que un valor menor que cero indica una distribución más achatada (menos picos) que la distribución normal.

  • se se refiere al error estándar, que es una medida de la precisión de la estimación de una estadística de la muestra. Indica la variabilidad esperada en la estimación de la estadística si se muestrea repetidamente de la misma población. Un error estándar más pequeño indica una estimación más precisa de la estadística de interés.

summary(dat)
##        A1              A2              A3              A4            A5      
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.0   Min.   :1.00  
##  1st Qu.:1.000   1st Qu.:4.000   1st Qu.:4.000   1st Qu.:4.0   1st Qu.:4.00  
##  Median :2.000   Median :5.000   Median :5.000   Median :5.0   Median :5.00  
##  Mean   :2.413   Mean   :4.802   Mean   :4.604   Mean   :4.7   Mean   :4.56  
##  3rd Qu.:3.000   3rd Qu.:6.000   3rd Qu.:6.000   3rd Qu.:6.0   3rd Qu.:5.00  
##  Max.   :6.000   Max.   :6.000   Max.   :6.000   Max.   :6.0   Max.   :6.00  
##  NA's   :16      NA's   :27      NA's   :26      NA's   :19    NA's   :16    
##        C1              C2             C3              C4              C5       
##  Min.   :1.000   Min.   :1.00   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:4.000   1st Qu.:4.00   1st Qu.:4.000   1st Qu.:1.000   1st Qu.:2.000  
##  Median :5.000   Median :5.00   Median :5.000   Median :2.000   Median :3.000  
##  Mean   :4.502   Mean   :4.37   Mean   :4.304   Mean   :2.553   Mean   :3.297  
##  3rd Qu.:5.000   3rd Qu.:5.00   3rd Qu.:5.000   3rd Qu.:4.000   3rd Qu.:5.000  
##  Max.   :6.000   Max.   :6.00   Max.   :6.000   Max.   :6.000   Max.   :6.000  
##  NA's   :21      NA's   :24     NA's   :20      NA's   :26      NA's   :16     
##        E1              E2              E3              E4       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:2.000   1st Qu.:3.000   1st Qu.:4.000  
##  Median :3.000   Median :3.000   Median :4.000   Median :5.000  
##  Mean   :2.974   Mean   :3.142   Mean   :4.001   Mean   :4.422  
##  3rd Qu.:4.000   3rd Qu.:4.000   3rd Qu.:5.000   3rd Qu.:6.000  
##  Max.   :6.000   Max.   :6.000   Max.   :6.000   Max.   :6.000  
##  NA's   :23      NA's   :16      NA's   :25      NA's   :9      
##        E5              N1              N2              N3       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:4.000   1st Qu.:2.000   1st Qu.:2.000   1st Qu.:2.000  
##  Median :5.000   Median :3.000   Median :4.000   Median :3.000  
##  Mean   :4.416   Mean   :2.929   Mean   :3.508   Mean   :3.217  
##  3rd Qu.:5.000   3rd Qu.:4.000   3rd Qu.:5.000   3rd Qu.:4.000  
##  Max.   :6.000   Max.   :6.000   Max.   :6.000   Max.   :6.000  
##  NA's   :21      NA's   :22      NA's   :21      NA's   :11     
##        N4              N5             O1              O2              O3       
##  Min.   :1.000   Min.   :1.00   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:2.000   1st Qu.:2.00   1st Qu.:4.000   1st Qu.:1.000   1st Qu.:4.000  
##  Median :3.000   Median :3.00   Median :5.000   Median :2.000   Median :5.000  
##  Mean   :3.186   Mean   :2.97   Mean   :4.816   Mean   :2.713   Mean   :4.438  
##  3rd Qu.:4.000   3rd Qu.:4.00   3rd Qu.:6.000   3rd Qu.:4.000   3rd Qu.:5.000  
##  Max.   :6.000   Max.   :6.00   Max.   :6.000   Max.   :6.000   Max.   :6.000  
##  NA's   :36      NA's   :29     NA's   :22                      NA's   :28     
##        O4              O5      
##  Min.   :1.000   Min.   :1.00  
##  1st Qu.:4.000   1st Qu.:1.00  
##  Median :5.000   Median :2.00  
##  Mean   :4.892   Mean   :2.49  
##  3rd Qu.:6.000   3rd Qu.:3.00  
##  Max.   :6.000   Max.   :6.00  
##  NA's   :14      NA's   :20

3.0.2 Datos faltantes

La mayoría de los elementos solo carecen de datos equivalentes a 20 o 30 participantes, lo cual no representa un gran problema en un conjunto de datos con 2800 observaciones. Sin embargo, es posible que algunos de estos valores faltantes no se superpongan, lo que significa que podrían faltar 20 o 30 individuos diferentes en cada una de las variables.

3.0.3 Datos perdidos por columna

missings <- colSums(is.na(dat)) 
missings
## A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 E1 E2 E3 E4 E5 N1 N2 N3 N4 N5 O1 O2 O3 O4 O5 
## 16 27 26 19 16 21 24 20 26 16 23 16 25  9 21 22 21 11 36 29 22  0 28 14 20
summary(missings) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   16.00   21.00   20.32   25.00   36.00

Alternativamente, podemos mirar algunas variables con alguna condición para el número de datos perdidos.

mydata <- dat[ , missings<15]
names(mydata)
## [1] "E4" "N3" "O2" "O4"

3.0.4 Función complete.cases

No obstante, podemos determinar el número de “casos completos” dentro de los datos, que son individuos que no tienen datos faltantes en absoluto en el cuestionario.

faltante <- complete.cases(dat);tail(faltante)
## [1]  TRUE FALSE FALSE  TRUE  TRUE  TRUE
sum(faltante)
## [1] 2436

La función complete.cases produce un vector de valores booleanos, donde TRUE indica un caso completo y FALSE indica un caso con valores faltantes. La suma de este vector nos da el total de casos completos, que en este caso es 2436. El porcentaje de datos ausentes es 13%:

(1 - (sum(faltante)/nrow(dat)))*100
## [1] 13

Aunque no existe un valor exacto que determine qué cantidad de datos faltantes es aceptable, la importancia del tamaño de la muestra en el análisis factorial es innegable. Según algunos expertos, se recomienda contar con al menos 10 observaciones por cada variable en dicho análisis, lo que sugiere que nuestro tamaño de muestra es apropiado para nuestros objetivos.

4 Verificación de supuestos

4.0.1 Condiciones

Antes de proceder con el EFA, debemos evaluar la “factorizabilidad” de nuestros datos. En este sentido, la idea es reponder la siguiente pregunta: ¿hay factores latentes significativos que se puedan encontrar dentro de los datos?

Para ello, podemos verificar dos condicioness:

  1. La prueba de esfericidad de Bartlett.

  2. La medida de adecuación muestral de Kaiser-Meyer-Olkin.

4.0.2 Pueba de esfericidad de Barlett

Esta prueba evalúa si las variables se correlacionan entre sí, comparando la matriz de correlación observada con una “matriz identidad”: \[H_0:\; \text{Correlación = Identidad}\]

Si este test no es estadísticamente significativo, no se debería aplicar un EFA.

cortest.bartlett(dat)
## $chisq
## [1] 20163.79
## 
## $p.value
## [1] 0
## 
## $df
## [1] 300

El test de Bartlett dio un resultado estadísticamente significativo (\(P\)-valor \(< 0.05\)), lo que indica que la matriz de correlación observada entre los elementos no es una matriz de identidad. Sin embargo, esto no es realmente una indicación particularmente poderosa de que se tiene un conjunto de datos factibles, ya que lo único que realmente te dice es que al menos algunas de las variables están correlacionadas entre sí.

4.0.3 Pueba de Kaiser-Meyer-Olkin (KMO)

  1. El KMO determina si las correlaciones parciales dentro de los datos son cercanas a cero, lo que sugiere la presencia de al menos un factor latente en tus variables.

  2. El índice KMO varía entre 0 y 1.

  3. El valor mínimo aceptable es 0.50, aunque la mayoría de los autores sugieren un valor de al menos 0.60 antes de realizar un análisis factorial.

  4. La función KMO en el paquete psych proporciona una medida general de adecuación de muestreo (MSA, como se indica en la salida) y una MSA para cada ítem.

  5. En teoría, si el MSA global es muy bajo, se puede examinar las MSA de los ítems y eliminar aquellos que sean demasiado bajos. Sin embargo, esto debe hacerse con cuidado, como ocurre con cualquier método empírico de selección de ítems.

4.0.4 Valores del KMO

La medida puede ser interpretada con las siguientes directrices:

  • Si \(KMO \geq 0.8\): perfecto para realizar un análisis factorial (AF).

  • Si \(KMO\) está entre 0.6 a 0.7: adecuado. Hay correlación y, por lo tanto, el AF es apropiado.

  • Si \(KMO\) está entre 0.4 a 0.5: aceptable. Se puede implementar un AF. Sin embargo se sugiere verificar el estado de las variables.

  • \(KMO\) menores a 0.4: no se recomienda un AF.

KMO(dat)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = dat)
## Overall MSA =  0.85
## MSA for each item = 
##   A1   A2   A3   A4   A5   C1   C2   C3   C4   C5   E1   E2   E3   E4   E5   N1 
## 0.74 0.84 0.87 0.87 0.90 0.83 0.79 0.85 0.82 0.86 0.83 0.88 0.89 0.87 0.89 0.78 
##   N2   N3   N4   N5   O1   O2   O3   O4   O5 
## 0.78 0.86 0.88 0.86 0.85 0.78 0.84 0.76 0.76

El índice KMO general de nuestros datos es de 0.846, lo cual es muy bueno. Esto indica que podemos aplicar el EFA.

4.0.5 Variables con KMO > 0.5

Se pueden obtener así:

mydat <- dat[, KMO(dat)$MSAi>0.50] 

names(mydat)
##  [1] "A1" "A2" "A3" "A4" "A5" "C1" "C2" "C3" "C4" "C5" "E1" "E2" "E3" "E4" "E5"
## [16] "N1" "N2" "N3" "N4" "N5" "O1" "O2" "O3" "O4" "O5"

5 Número de factores

La primera decisión que debemos tomar tiene que ver con el número de factores que necesitaremos extraer para lograr la estructura de factores más parsimoniosa y aún interpretable. Recordemos que hay varios métodos que podríamos usar, pero los dos más comúnmente empleados son el scree plot (gráfico de codo o de sedimentación o de escombro) y el parallel analysis (análisis paralelo).

5.0.1 Scree plot: FA y PC

Cosideremos el scree plot para los datos de nuestro ejemplo.

scree(dat)

  1. El método del scree plot implica trazar una línea recta a través de los valores propios representados, empezando por el más grande. El último punto que toca esta línea representa el último factor que extraes, con la idea de que más allá de este punto, la cantidad adicional de varianza explicada no es significativa.

  2. La palabra scree (traducido: “escombro”) se refiere a las piedras sueltas alrededor de la base de la montaña. Un scree plot busca ayudar a diferenciar entre los puntos que representan “montaña” y los que representan “escombro”.

  3. Sin importar si se usa una extracción de componentes principales o de ejes principales, hay un primer factor muy grande en estos datos.

  4. Si se traza la línea recta desde este punto, probablemente concluiríamos que hay solo tres factores en el conjunto de datos.

  5. Si, en cambio, se comienza la línea en el segundo punto del scree plot, probablemente concluiríamos que hay cinco factores en los datos.

  6. Esta última interpretación probablemente sea más cercana a la verdad. Pero, si solo se considera esta evidencia al determinar el número de factores a extraer, sería necesario examinar ambas soluciones de factores.

5.0.2 Scree plot: solo FA

Si solo quiero que muestre el EFA:

scree(dat, pc=FALSE)

5.0.3 Parallel Analysis: FA y PC

Una mejor manera de evaluar el scree plot es mediante un parallel analysis (análisis paralelo). Aparte de graficar los autovalores de nuestro EFA (ya sea basado en la extracción de ejes principales o componentes principales), el parallel analysis implica:

  1. Generar matrices de correlación aleatorias.

  2. Utilizarlas como datos en el EFA.

  3. comparar los autovalores resultantes con los del conjunto de datos observados.

La idea detrás de este método es que los autovalores observados que son más altos que sus equivalentes aleatorios son más propensos a ser “factores significativos” en comparación con los autovalores observados que son más bajos que sus equivalentes aleatorios.

fa.parallel(dat)

## Parallel analysis suggests that the number of factors =  6  and the number of components =  6

Al revisar los gráficos de parallel analysis de los scree plots, hay dos áreas de interés dependiendo del tipo de análisis factorial que se quiera realizar.

  1. Las dos líneas azules muestran los autovalores observados, que deberían ser similares a las gráficas de escala generadas por la función de escala. Las líneas rojas punteadas representan los autovalores aleatorios o la línea de datos simulados.

  2. Cada punto en la línea azul que esté por encima de la línea de datos simulados correspondiente indica un factor o componente a extraer.

  3. En este análisis, se observa que 6 factores en el parallel analysis de “FA” superan la línea de datos simulados correspondiente, al igual que 6 componentes en el parallel analysis de “PC”.

  4. Sin embargo, en nuestro caso, el último factor/componente está muy próximo a la línea, tanto para la extracción de componentes principales como para la extracción de ejes principales. Por ende, sería conveniente comparar las soluciones de 6 factores y 5 factores para determinar cuál es más interpretable.

5.0.4 Parallel Analysis: solo FA

fa.parallel(dat, fa="fa")

## Parallel analysis suggests that the number of factors =  6  and the number of components =  NA

6 EFA con 6 factores

6.0.1 La función fa con 6 factores

La función fa utiliza ciertos parámetros al ser invocada:

  1. Se proporcionan las variables que se usarán en el análisis factorial (objeto dat).

  2. Se especifica el número de factores que se extraerán (6).

  3. Se elige el tipo de análisis factorial a emplear (en este caso, pa es el factoring del eje principal).

  4. Se determina el número de iteraciones o intentos para encontrar la solución “óptima” (50 es el valor por defecto, pero lo hemos cambiado a 100).

  5. Se selecciona el tipo de rotación a aplicar (comenzaremos con oblimin).

Nfac <- 6  #Este es el número de factores

res.efa6 <- psych::fa(dat,
              nfactors = Nfac,
              fm="pa",
              max.iter = 100,
              rotate = "oblimin")
res.efa6
## Factor Analysis using method =  pa
## Call: psych::fa(r = dat, nfactors = Nfac, rotate = "oblimin", max.iter = 100, 
##     fm = "pa")
## Standardized loadings (pattern matrix) based upon correlation matrix
##      PA2   PA1   PA3   PA5   PA4   PA6   h2   u2 com
## A1  0.09 -0.09  0.08 -0.56  0.06  0.30 0.34 0.66 1.7
## A2  0.04 -0.04  0.08  0.68  0.00 -0.05 0.50 0.50 1.1
## A3 -0.02 -0.12  0.03  0.61  0.07  0.11 0.51 0.49 1.2
## A4 -0.07 -0.06  0.19  0.39 -0.10  0.15 0.28 0.72 2.1
## A5 -0.16 -0.19  0.01  0.45  0.13  0.21 0.47 0.53 2.3
## C1  0.01  0.06  0.54 -0.06  0.19  0.07 0.34 0.66 1.3
## C2  0.07  0.14  0.67  0.02  0.11  0.17 0.49 0.51 1.3
## C3  0.01  0.06  0.55  0.08 -0.04  0.06 0.31 0.69 1.1
## C4  0.06  0.09 -0.64 -0.06  0.07  0.30 0.57 0.43 1.5
## C5  0.15  0.18 -0.54 -0.01  0.11  0.05 0.43 0.57 1.5
## E1 -0.13  0.59  0.11 -0.12 -0.08  0.09 0.39 0.61 1.3
## E2  0.05  0.70 -0.02 -0.07 -0.06  0.03 0.56 0.44 1.0
## E3  0.00 -0.34  0.00  0.15  0.40  0.21 0.48 0.52 2.8
## E4 -0.05 -0.53  0.03  0.20  0.04  0.29 0.55 0.45 1.9
## E5  0.15 -0.40  0.27  0.05  0.23  0.01 0.40 0.60 2.8
## N1  0.84 -0.10  0.01 -0.07 -0.05  0.00 0.68 0.32 1.0
## N2  0.83 -0.06  0.02 -0.04 -0.01 -0.07 0.66 0.34 1.0
## N3  0.67  0.13 -0.03  0.07  0.05  0.08 0.54 0.46 1.1
## N4  0.43  0.42 -0.13  0.08  0.10  0.05 0.49 0.51 2.4
## N5  0.44  0.23  0.00  0.18 -0.10  0.16 0.35 0.65 2.4
## O1 -0.05 -0.04  0.07 -0.05  0.57  0.03 0.35 0.65 1.1
## O2  0.11  0.00 -0.07  0.09 -0.36  0.36 0.29 0.71 2.4
## O3 -0.02 -0.09  0.02  0.03  0.65 -0.02 0.48 0.52 1.1
## O4  0.09  0.35 -0.02  0.15  0.37 -0.04 0.25 0.75 2.5
## O5  0.03 -0.04 -0.02 -0.04 -0.44  0.41 0.37 0.63 2.0
## 
##                        PA2  PA1  PA3  PA5  PA4  PA6
## SS loadings           2.48 2.17 2.05 1.88 1.68 0.82
## Proportion Var        0.10 0.09 0.08 0.08 0.07 0.03
## Cumulative Var        0.10 0.19 0.27 0.34 0.41 0.44
## Proportion Explained  0.22 0.20 0.18 0.17 0.15 0.07
## Cumulative Proportion 0.22 0.42 0.60 0.77 0.93 1.00
## 
##  With factor correlations of 
##       PA2   PA1   PA3   PA5   PA4   PA6
## PA2  1.00  0.25 -0.18 -0.10  0.02  0.16
## PA1  0.25  1.00 -0.21 -0.30 -0.20 -0.08
## PA3 -0.18 -0.21  1.00  0.19  0.19 -0.02
## PA5 -0.10 -0.30  0.19  1.00  0.25  0.14
## PA4  0.02 -0.20  0.19  0.25  1.00  0.02
## PA6  0.16 -0.08 -0.02  0.14  0.02  1.00
## 
## Mean item complexity =  1.7
## Test of the hypothesis that 6 factors are sufficient.
## 
## df null model =  300  with the objective function =  7.23 with Chi Square =  20163.79
## df of  the model are 165  and the objective function was  0.37 
## 
## The root mean square of the residuals (RMSR) is  0.02 
## The df corrected root mean square of the residuals is  0.03 
## 
## The harmonic n.obs is  2762 with the empirical chi square  639.92  with prob <  4.1e-57 
## The total n.obs was  2800  with Likelihood Chi Square =  1032.5  with prob <  1.8e-125 
## 
## Tucker Lewis Index of factoring reliability =  0.92
## RMSEA index =  0.043  and the 90 % confidence intervals are  0.041 0.046
## BIC =  -277.17
## Fit based upon off diagonal values = 0.99
## Measures of factor score adequacy             
##                                                    PA2  PA1  PA3  PA5  PA4  PA6
## Correlation of (regression) scores with factors   0.93 0.89 0.88 0.87 0.86 0.77
## Multiple R square of scores with factors          0.86 0.79 0.78 0.76 0.73 0.59
## Minimum correlation of possible factor scores     0.72 0.59 0.57 0.53 0.46 0.17

La matriz de correlaciones indica que las correlaciones son bastante bajas. Por tanto, estaría justificado pasar a probar con otra rotación o disminuir el número de factores.

6.0.2 fa con 6 factores: otros argumentos

A continuación, otra forma de presentar los resultados. En el código de abajo:

  • digits=2: Este argumento especifica el número de dígitos que se mostrarán después del punto decimal. En este caso, se establece en 2, lo que significa que los valores numéricos se mostrarán con dos dígitos después del punto decimal.

  • cutoff=0.3: Este argumento es un valor de corte para los resultados mostrados. Por ejemplo, si hay valores por debajo de 0.3, pueden no mostrarse en la impresión.

  • sort=TRUE: Este argumento determina si los resultados deben ordenarse antes de imprimirse. Cuando se establece en TRUE, los resultados se ordenarán de manera predeterminada antes de la impresión.

print(res.efa6, digits=2, cutoff=0.3, sort=TRUE)
## Factor Analysis using method =  pa
## Call: psych::fa(r = dat, nfactors = Nfac, rotate = "oblimin", max.iter = 100, 
##     fm = "pa")
## Standardized loadings (pattern matrix) based upon correlation matrix
##    item   PA2   PA1   PA3   PA5   PA4   PA6   h2   u2 com
## N1   16  0.84 -0.10  0.01 -0.07 -0.05  0.00 0.68 0.32 1.0
## N2   17  0.83 -0.06  0.02 -0.04 -0.01 -0.07 0.66 0.34 1.0
## N3   18  0.67  0.13 -0.03  0.07  0.05  0.08 0.54 0.46 1.1
## N5   20  0.44  0.23  0.00  0.18 -0.10  0.16 0.35 0.65 2.4
## N4   19  0.43  0.42 -0.13  0.08  0.10  0.05 0.49 0.51 2.4
## E2   12  0.05  0.70 -0.02 -0.07 -0.06  0.03 0.56 0.44 1.0
## E1   11 -0.13  0.59  0.11 -0.12 -0.08  0.09 0.39 0.61 1.3
## E4   14 -0.05 -0.53  0.03  0.20  0.04  0.29 0.55 0.45 1.9
## E5   15  0.15 -0.40  0.27  0.05  0.23  0.01 0.40 0.60 2.8
## C2    7  0.07  0.14  0.67  0.02  0.11  0.17 0.49 0.51 1.3
## C4    9  0.06  0.09 -0.64 -0.06  0.07  0.30 0.57 0.43 1.5
## C3    8  0.01  0.06  0.55  0.08 -0.04  0.06 0.31 0.69 1.1
## C5   10  0.15  0.18 -0.54 -0.01  0.11  0.05 0.43 0.57 1.5
## C1    6  0.01  0.06  0.54 -0.06  0.19  0.07 0.34 0.66 1.3
## A2    2  0.04 -0.04  0.08  0.68  0.00 -0.05 0.50 0.50 1.1
## A3    3 -0.02 -0.12  0.03  0.61  0.07  0.11 0.51 0.49 1.2
## A1    1  0.09 -0.09  0.08 -0.56  0.06  0.30 0.34 0.66 1.7
## A5    5 -0.16 -0.19  0.01  0.45  0.13  0.21 0.47 0.53 2.3
## A4    4 -0.07 -0.06  0.19  0.39 -0.10  0.15 0.28 0.72 2.1
## O3   23 -0.02 -0.09  0.02  0.03  0.65 -0.02 0.48 0.52 1.1
## O1   21 -0.05 -0.04  0.07 -0.05  0.57  0.03 0.35 0.65 1.1
## O5   25  0.03 -0.04 -0.02 -0.04 -0.44  0.41 0.37 0.63 2.0
## E3   13  0.00 -0.34  0.00  0.15  0.40  0.21 0.48 0.52 2.8
## O4   24  0.09  0.35 -0.02  0.15  0.37 -0.04 0.25 0.75 2.5
## O2   22  0.11  0.00 -0.07  0.09 -0.36  0.36 0.29 0.71 2.4
## 
##                        PA2  PA1  PA3  PA5  PA4  PA6
## SS loadings           2.48 2.17 2.05 1.88 1.68 0.82
## Proportion Var        0.10 0.09 0.08 0.08 0.07 0.03
## Cumulative Var        0.10 0.19 0.27 0.34 0.41 0.44
## Proportion Explained  0.22 0.20 0.18 0.17 0.15 0.07
## Cumulative Proportion 0.22 0.42 0.60 0.77 0.93 1.00
## 
##  With factor correlations of 
##       PA2   PA1   PA3   PA5   PA4   PA6
## PA2  1.00  0.25 -0.18 -0.10  0.02  0.16
## PA1  0.25  1.00 -0.21 -0.30 -0.20 -0.08
## PA3 -0.18 -0.21  1.00  0.19  0.19 -0.02
## PA5 -0.10 -0.30  0.19  1.00  0.25  0.14
## PA4  0.02 -0.20  0.19  0.25  1.00  0.02
## PA6  0.16 -0.08 -0.02  0.14  0.02  1.00
## 
## Mean item complexity =  1.7
## Test of the hypothesis that 6 factors are sufficient.
## 
## df null model =  300  with the objective function =  7.23 0.3 with Chi Square =  20163.79
## df of  the model are 165  and the objective function was  0.37 
##  0.3
## The root mean square of the residuals (RMSR) is  0.02 
## The df corrected root mean square of the residuals is  0.03 
##  0.3
## The harmonic n.obs is  2762 with the empirical chi square  639.92  with prob <  4.1e-57 
##  0.3The total n.obs was  2800  with Likelihood Chi Square =  1032.5  with prob <  1.8e-125 
##  0.3
## Tucker Lewis Index of factoring reliability =  0.92
## RMSEA index =  0.043  and the 90 % confidence intervals are  0.041 0.046 0.3
## BIC =  -277.17
## Fit based upon off diagonal values = 0.99
## Measures of factor score adequacy             
##                                                    PA2  PA1  PA3  PA5  PA4  PA6
## Correlation of (regression) scores with factors   0.93 0.89 0.88 0.87 0.86 0.77
## Multiple R square of scores with factors          0.86 0.79 0.78 0.76 0.73 0.59
## Minimum correlation of possible factor scores     0.72 0.59 0.57 0.53 0.46 0.17

6.0.3 Plot Factor 1 by Factor 2

load <- res.efa6$loadings[,1:2]
plot(load,type="n") # configurar el plot
text(load,labels=names(dat),cex=.7)

6.0.4 La función fa.diagram

Se puede ver rápidamente tu solución de factores rotados y decidir si es comprensible utilizando la función fa.diagram.

fa.diagram(res.efa6)

Como se puede ver aquí, el sexto factor tiene solo una carga variable en él: el segundo ítem de la escala de apertura a openness (experiencia). Por lo tanto, esto probablemente representa una sobreextracción.

6.0.5 fa.diagram: más opciones

Para simplificar aún más la interpretación, puede reducir el número de factores.

loads2 <- res.efa6$loadings[,1:2]
fa.diagram(loads2)

loads3 <- res.efa6$loadings[,3:4]
fa.diagram(loads3)

7 Evaluando lo encontrado

De los resultados anteriores, necesitaremos considerar algunos aspectos.

Primero. ¿La rotación que seleccionaste fue apropiada?

Si utilizamos una rotación oblicua:

  • ¿Hay suficientes correlaciones bastante sustanciales (r>0.30) para justificar la suposición de que los factores están interrelacionados?

  • De lo contrario, podríamos considerar cambiar a una rotación ortogonal.

Si usaste una rotación ortogonal:

  • ¿Las variables se cargan en los factores de manera limpia?

  • Si no es así, podrías considerar cambiar a la rotación oblicua. ¿Los factores lucen estables y distintos?

Segundo. ¿Se cargan todas las variables en los factores lo suficiente? (|cargas factoriales| > 0.30)

  • Si las cargas factoriales no son suficientes, es posible que necesites probar el método de extracción de factores, un número diferente de factores o decidir si retener las variables que no se cargan en un factor.

Tercero. Número de factores.

  • ¿Tienen todos los factores al menos tres - o, mejor aún, cuatro - o más variables cargando en ellos?

  • De lo contrario, es posible que necesites disminuir el número de factores.

Cuarto. ¿Cargas cruzadas?

  • ¿Hay muchas cargas cruzadas (variables que se cargan en más de un factor con valores que están dentro de 0.05 uno del otro)?

  • Esto puede ser inevitable. Pero, en general, la mejor solución minimizará el número de cargas cruzadas.

Quinto. ¿Factores interpretables?

  • ¿Son interpretables cada uno de los factores?

  • ¿Las variables que se cargan en cada factor tienen al menos un tema bastante claro (basado en las definiciones de las variables)? En última instancia, esto es lo que estás tratando de producir.

8 EFA con 5 factores

8.0.1 La función fa con 5 factores

Veamos ahora la solución de cinco factores y su gráfico.

res.efa5 <- psych::fa(dat,
              nfactors = 5,
              fm="pa",
              max.iter = 100,
              rotate = "oblimin")
res.efa5
## Factor Analysis using method =  pa
## Call: psych::fa(r = dat, nfactors = 5, rotate = "oblimin", max.iter = 100, 
##     fm = "pa")
## Standardized loadings (pattern matrix) based upon correlation matrix
##      PA2   PA1   PA3   PA5   PA4   h2   u2 com
## A1  0.21  0.17  0.07 -0.41 -0.06 0.19 0.81 2.0
## A2 -0.02  0.00  0.08  0.64  0.03 0.45 0.55 1.0
## A3 -0.03  0.12  0.02  0.66  0.03 0.52 0.48 1.1
## A4 -0.06  0.06  0.19  0.43 -0.15 0.28 0.72 1.7
## A5 -0.11  0.23  0.01  0.53  0.04 0.46 0.54 1.5
## C1  0.07 -0.03  0.55 -0.02  0.15 0.33 0.67 1.2
## C2  0.15 -0.09  0.67  0.08  0.04 0.45 0.55 1.2
## C3  0.03 -0.06  0.57  0.09 -0.07 0.32 0.68 1.1
## C4  0.17  0.00 -0.61  0.04 -0.05 0.45 0.55 1.2
## C5  0.19 -0.14 -0.55  0.02  0.09 0.43 0.57 1.4
## E1 -0.06 -0.56  0.11 -0.08 -0.10 0.35 0.65 1.2
## E2  0.10 -0.68 -0.02 -0.05 -0.06 0.54 0.46 1.1
## E3  0.08  0.42  0.00  0.25  0.28 0.44 0.56 2.6
## E4  0.01  0.59  0.02  0.29 -0.08 0.53 0.47 1.5
## E5  0.15  0.42  0.27  0.05  0.21 0.40 0.60 2.6
## N1  0.81  0.10  0.00 -0.11 -0.05 0.65 0.35 1.1
## N2  0.78  0.04  0.01 -0.09  0.01 0.60 0.40 1.0
## N3  0.71 -0.10 -0.04  0.08  0.02 0.55 0.45 1.1
## N4  0.47 -0.39 -0.14  0.09  0.08 0.49 0.51 2.3
## N5  0.49 -0.20  0.00  0.21 -0.15 0.35 0.65 2.0
## O1  0.02  0.10  0.07  0.02  0.51 0.31 0.69 1.1
## O2  0.19  0.06 -0.08  0.16 -0.46 0.26 0.74 1.7
## O3  0.03  0.15  0.02  0.08  0.61 0.46 0.54 1.2
## O4  0.13 -0.32 -0.02  0.17  0.37 0.25 0.75 2.7
## O5  0.13  0.10 -0.02  0.04 -0.54 0.30 0.70 1.2
## 
##                        PA2  PA1  PA3  PA5  PA4
## SS loadings           2.57 2.20 2.03 1.98 1.59
## Proportion Var        0.10 0.09 0.08 0.08 0.06
## Cumulative Var        0.10 0.19 0.27 0.35 0.41
## Proportion Explained  0.25 0.21 0.20 0.19 0.15
## Cumulative Proportion 0.25 0.46 0.66 0.85 1.00
## 
##  With factor correlations of 
##       PA2   PA1   PA3   PA5   PA4
## PA2  1.00 -0.21 -0.19 -0.04 -0.01
## PA1 -0.21  1.00  0.23  0.33  0.17
## PA3 -0.19  0.23  1.00  0.20  0.19
## PA5 -0.04  0.33  0.20  1.00  0.19
## PA4 -0.01  0.17  0.19  0.19  1.00
## 
## Mean item complexity =  1.5
## Test of the hypothesis that 5 factors are sufficient.
## 
## df null model =  300  with the objective function =  7.23 with Chi Square =  20163.79
## df of  the model are 185  and the objective function was  0.65 
## 
## The root mean square of the residuals (RMSR) is  0.03 
## The df corrected root mean square of the residuals is  0.04 
## 
## The harmonic n.obs is  2762 with the empirical chi square  1392.16  with prob <  5.6e-184 
## The total n.obs was  2800  with Likelihood Chi Square =  1809.1  with prob <  4e-264 
## 
## Tucker Lewis Index of factoring reliability =  0.867
## RMSEA index =  0.056  and the 90 % confidence intervals are  0.054 0.058
## BIC =  340.68
## Fit based upon off diagonal values = 0.98
## Measures of factor score adequacy             
##                                                    PA2  PA1  PA3  PA5  PA4
## Correlation of (regression) scores with factors   0.92 0.89 0.88 0.88 0.84
## Multiple R square of scores with factors          0.85 0.79 0.77 0.77 0.71
## Minimum correlation of possible factor scores     0.70 0.59 0.54 0.54 0.42

El gráfico.

fa.diagram(res.efa5)

La solución con cinco factores es más fácil de entender, de hecho, parece reproducir bien la estructura de factores esperada.

9 Comunalidades

La comunalidad de cada variable representa el porcentaje de variabilidad que los factores retenidos pueden explicar. Es preferible que estos factores retenidos expliquen una mayor proporción de la variabilidad en cada variable.

res.efa5$communality
##        A1        A2        A3        A4        A5        C1        C2        C3 
## 0.1917679 0.4472702 0.5226804 0.2800492 0.4638037 0.3301446 0.4502136 0.3182264 
##        C4        C5        E1        E2        E3        E4        E5        N1 
## 0.4506858 0.4272571 0.3479662 0.5432814 0.4389546 0.5313933 0.4026775 0.6517914 
##        N2        N3        N4        N5        O1        O2        O3        O4 
## 0.6000981 0.5471437 0.4881259 0.3496557 0.3126709 0.2575010 0.4639493 0.2512316 
##        O5 
## 0.3002371

En otras palabras, la principal distinción entre cómo se realiza el análisis factorial y el análisis de componentes principales tiene que ver con la forma de las respectivas matrices de varianzas-covarianzas entre los datos y las componentes (o factores).

  1. En EFA, esta matriz viene dada por:
    \[Cov (X, F^T) \;=\; \Lambda\]

  2. En PCA, esta matriz tiene elementos que depende de las coordenadas de los autovalores y autovectores: \[Cov (X_k, F_j) \;=\; a_{jk} \lambda_j\]

10 Autovalores

Los autovalores derivados en la solución de factores extraída se encuentran guardados en e.values. Estos son los valores característicos que se mostraron en los scree plots que examinamos al inicio de este procedimiento.

res.efa5$e.values[1:10]
##  [1] 5.0369025 2.7440855 2.1076322 1.8318415 1.5356864 1.1131589 0.8462367
##  [8] 0.8114075 0.7349482 0.6956449

Si se quiere obtener los autovalores dela solución rotada, se accede values.

res.efa5$values[1:10]
##  [1] 4.49282572 2.24858178 1.50519272 1.18783326 0.93434310 0.49165683
##  [7] 0.23969558 0.19018461 0.09985585 0.09761160

11 Porcentaje de varianza explicada

Podemos emplear los valores propios para determinar el porcentaje de variabilidad explicada por cada factor. Dado que la suma máxima de estos valores siempre será igual al número total de variables en el análisis, podemos calcular el porcentaje dividiendo cada valor propio por el número total de variables. En nuestro caso, que es 25.

total <- length(res.efa5$e.values)
100*res.efa5$e.values[1:10]/total
##  [1] 20.147610 10.976342  8.430529  7.327366  6.142746  4.452636  3.384947
##  [8]  3.245630  2.939793  2.782580

Para obtener el porcentaje de variabilidad explicada por la solución rotada, se usarían los valores propios almacenados en values en lugar de e.values.

totalrot <- length(res.efa5$values)
100*res.efa5$values[1:10]/totalrot
##  [1] 17.9713029  8.9943271  6.0207709  4.7513330  3.7373724  1.9666273
##  [7]  0.9587823  0.7607384  0.3994234  0.3904464

12 Solución rotada

Ya hemos revisado los elementos con las cargas más altas para cada factor (usando fa.diagram), pero esto solo nos dice cuál es la carga más grande para cada elemento. Sin embargo, cada elemento se cargará en cada uno de los factores en mayor o menor medida, y eventualmente querremos ver la matriz completa de cargas factoriales. La matriz de cargas factoriales nos muestra las cargas factoriales para cada variable, después de haber sido rotadas a una “estructura simple”. Básicamente, estamos aprovechando el hecho de que hay varias soluciones de factores que son igualmente aceptables a la solución “óptima” que se encontró dentro de nuestra extracción inicial (es decir, que son matemáticamente equivalentes), y rotando los factores para que sean más fácilmente interpretados. Debido a que hemos utilizado una rotación de factores oblicua (oblimin), esto a veces se llama matriz de patrones.

print(res.efa5$loadings, cutoff=0, digits=3)
## 
## Loadings:
##    PA2    PA1    PA3    PA5    PA4   
## A1  0.213  0.166  0.067 -0.414 -0.058
## A2 -0.023 -0.002  0.077  0.640  0.032
## A3 -0.029  0.116  0.025  0.660  0.031
## A4 -0.057  0.065  0.193  0.433 -0.148
## A5 -0.112  0.234  0.006  0.532  0.044
## C1  0.069 -0.027  0.546 -0.023  0.148
## C2  0.149 -0.085  0.666  0.081  0.039
## C3  0.034 -0.061  0.567  0.092 -0.068
## C4  0.174  0.002 -0.614  0.040 -0.048
## C5  0.189 -0.142 -0.553  0.018  0.092
## E1 -0.059 -0.557  0.106 -0.083 -0.102
## E2  0.099 -0.676 -0.016 -0.048 -0.058
## E3  0.083  0.418 -0.001  0.245  0.283
## E4  0.013  0.591  0.024  0.287 -0.077
## E5  0.152  0.421  0.272  0.052  0.206
## N1  0.814  0.103  0.004 -0.111 -0.047
## N2  0.777  0.040  0.011 -0.094  0.015
## N3  0.707 -0.100 -0.035  0.079  0.023
## N4  0.474 -0.386 -0.135  0.095  0.080
## N5  0.486 -0.202 -0.004  0.207 -0.150
## O1  0.018  0.103  0.073  0.015  0.508
## O2  0.195  0.057 -0.078  0.163 -0.456
## O3  0.031  0.152  0.017  0.083  0.609
## O4  0.126 -0.323 -0.024  0.174  0.371
## O5  0.132  0.098 -0.025  0.043 -0.542
## 
##                  PA2   PA1   PA3   PA5   PA4
## SS loadings    2.499 1.964 1.913 1.804 1.511
## Proportion Var 0.100 0.079 0.077 0.072 0.060
## Cumulative Var 0.100 0.179 0.255 0.327 0.388

13 Matriz de estructuras

También podemos examinar la llamada matriz de estructura, que es esencialmente el resultado de multiplicar la matriz de patrones por la matriz de intercorrelación de factores. De este modo, estos valores reflejan las correlaciones entre las variables y los factores, lo cual puede resultar más fácil de interpretar intuitivamente.

print(res.efa5$Structure, cutoff=0, digits=3)
## 
## Loadings:
##    PA2    PA1    PA3    PA5    PA4   
## A1  0.181 -0.010 -0.030 -0.365 -0.100
## A2 -0.061  0.237  0.217  0.662  0.171
## A3 -0.083  0.350  0.197  0.710  0.183
## A4 -0.121  0.239  0.277  0.467 -0.016
## A5 -0.183  0.441  0.197  0.622  0.188
## C1 -0.028  0.100  0.551  0.105  0.244
## C2  0.039  0.070  0.643  0.191  0.168
## C3 -0.062  0.081  0.552  0.173  0.050
## C4  0.287 -0.171 -0.647 -0.100 -0.162
## C5  0.321 -0.288 -0.600 -0.131 -0.038
## E1  0.044 -0.564 -0.047 -0.262 -0.190
## E2  0.248 -0.726 -0.211 -0.289 -0.184
## E3 -0.018  0.528  0.185  0.434  0.399
## E4 -0.127  0.675  0.201  0.471  0.081
## E5  0.007  0.502  0.390  0.280  0.337
## N1  0.796 -0.114 -0.156 -0.116 -0.059
## N2  0.770 -0.152 -0.141 -0.105 -0.003
## N3  0.731 -0.229 -0.170  0.016  0.007
## N4  0.577 -0.474 -0.278 -0.062  0.003
## N5  0.524 -0.263 -0.128  0.092 -0.149
## O1 -0.023  0.205  0.195  0.161  0.542
## O2  0.196 -0.025 -0.157  0.070 -0.432
## O3 -0.014  0.278  0.182  0.253  0.653
## O4  0.189 -0.237 -0.015  0.129  0.345
## O5  0.120 -0.012 -0.124 -0.039 -0.524
## 
##                  PA2   PA1   PA3   PA5   PA4
## SS loadings    2.821 2.956 2.554 2.577 1.902
## Proportion Var 0.113 0.118 0.102 0.103 0.076
## Cumulative Var 0.113 0.231 0.333 0.436 0.512

14 Extrayendo las cargas factoriales

Para describir los factores con mayor claridad y presentar los resultados, puede ser útil exportar todas las cargas factoriales. Exportar las cargas en formato CSV hará mucho más fácil reportar los resultados. Sin embargo, este proceso no mantendrá el orden que actualmente se ve en la salida. En este sentido, se deben ordenar las columnas por nuestra cuenta.

Por alguna razón, el paquete psych omite algunas cargas si simplemente se llama a las cargas usando res.efa5$loadings. Para resolver esto, es necesario especificar qué variables estamos incluyendo en la salida.

Por lo tanto, primero debemos verificar cuántas variables hay en la salida y luego especifícarlas al extraer las cargas. También es útil redondear la salida, por ejemplo, a tres dígitos después del punto decimal.

dim(res.efa5$loadings)
## [1] 25  5

Hay 25 variables y 5 factores.

nvar <- dim(res.efa5$loadings)[1] 
FactorLoad <- round(res.efa5$loadings[1:nvar,], 3)
FactorLoad
##       PA2    PA1    PA3    PA5    PA4
## A1  0.213  0.166  0.067 -0.414 -0.058
## A2 -0.023 -0.002  0.077  0.640  0.032
## A3 -0.029  0.116  0.025  0.660  0.031
## A4 -0.057  0.065  0.193  0.433 -0.148
## A5 -0.112  0.234  0.006  0.532  0.044
## C1  0.069 -0.027  0.546 -0.023  0.148
## C2  0.149 -0.085  0.666  0.081  0.039
## C3  0.034 -0.061  0.567  0.092 -0.068
## C4  0.174  0.002 -0.614  0.040 -0.048
## C5  0.189 -0.142 -0.553  0.018  0.092
## E1 -0.059 -0.557  0.106 -0.083 -0.102
## E2  0.099 -0.676 -0.016 -0.048 -0.058
## E3  0.083  0.418 -0.001  0.245  0.283
## E4  0.013  0.591  0.024  0.287 -0.077
## E5  0.152  0.421  0.272  0.052  0.206
## N1  0.814  0.103  0.004 -0.111 -0.047
## N2  0.777  0.040  0.011 -0.094  0.015
## N3  0.707 -0.100 -0.035  0.079  0.023
## N4  0.474 -0.386 -0.135  0.095  0.080
## N5  0.486 -0.202 -0.004  0.207 -0.150
## O1  0.018  0.103  0.073  0.015  0.508
## O2  0.195  0.057 -0.078  0.163 -0.456
## O3  0.031  0.152  0.017  0.083  0.609
## O4  0.126 -0.323 -0.024  0.174  0.371
## O5  0.132  0.098 -0.025  0.043 -0.542

El objeto se salva en un archivo de excel (o en formato csv) de la forma siguiente:

library(openxlsx)  # Librería para escribir archivos de Excel

write.xlsx(FactorLoad, "FactorLoad_excel.xls", sheetName = "Cargas", rowNames = FALSE)
write.csv2(FactorLoad, file="FactorLoad_pc.csv") # csv con punto y coma
write.csv(FactorLoad, file="FactorLoad_c.csv")   # csv con coma

Una vez generado el archivo CSV, puede determinar si algunas variables no se ajustan adecuadamente a ninguno de los factores (|carga| < 0.40). En este caso específico, no encontramos ninguna variable que no se adapte suficientemente a alguno de los factores. Sin embargo, si las hubiera, podríamos eliminar esas variables siguiendo los pasos mencionados anteriormente.

Es importante tener en cuenta que al eliminar variables es probable que las cargas cambien, por lo que sería necesario volver a ejecutar el análisis factorial con el conjunto de datos modificado antes de realizar cualquier interpretación final o elaborar un informe.

15 Extrayendo los puntajes de los factores

15.0.1 Scores: opciones

Se puede extraer los puntajes de los factores utilizando algunas de los dos opciones siguientes:

  • A través de res.efa5$scores.

  • La función factor.scores del mismo paquete psych.

Estas opciones calculan los puntajes de factores para cada observación en tu conjunto de datos original.

15.0.2 Scores: res.efa5$scores

head(res.efa5$scores)
##               PA2        PA1         PA3         PA5        PA4
## 61617 -0.21429864 0.06866200 -1.33215114 -0.85349374 -1.5809669
## 61618  0.14994681 0.48095597 -0.59953429 -0.08500211 -0.1875012
## 61620  0.62823220 0.10995265 -0.04812899 -0.55682240  0.2501126
## 61621 -0.09336466 0.03847091 -1.05097714 -0.10479813 -1.1004252
## 61622 -0.16330768 0.44219091 -0.10510915 -0.71859254 -0.6613389
## 61623  0.19011409 1.08449521  1.40738329  0.39234699  0.6220493

15.0.3 Scores: factor.scores

1. factor.scores: métodos

  • Con esta opción, hay que asegurarse de que tanto fa como factor.scores estén utilizando la misma técnica para la estimación de los puntajes de factores.

  • La función factor.scores tiene varios métodos, como Thurstone, tenBerge, Anderson, Bartlett, etc.

  • Si no se especifica un método, podría estar usando uno predeterminado que difiere del utilizado en fa.

  • En este caso, el que usa fa es el método de regresión o de Thurstone (method = "regression" o method = "Thurstone").

2. factor.scores: argumentos de fa.

Aquí está la parte relevante de la documentación de fa:

Argument:

the default="regression" finds factor scores using regression. Alternatives for estimating factor scores include simple regression ("Thurstone"), correlaton preserving ("tenBerge") as well as "Anderson" and "Bartlett" using the appropriate algorithms ( factor.scores). Although scores="tenBerge" is probably preferred for most solutions, it will lead to problems with some improper correlation matrices.

3. factor.scores: extrayendo los puntajes.

Con method = "regression":

factor_scores_r <- factor.scores(dat, res.efa5, method = "regression")
head(factor_scores_r$scores)
##               PA2        PA1         PA3         PA5        PA4
## 61617 -0.21429864 0.06866200 -1.33215114 -0.85349374 -1.5809669
## 61618  0.14994681 0.48095597 -0.59953429 -0.08500211 -0.1875012
## 61620  0.62823220 0.10995265 -0.04812899 -0.55682240  0.2501126
## 61621 -0.09336466 0.03847091 -1.05097714 -0.10479813 -1.1004252
## 61622 -0.16330768 0.44219091 -0.10510915 -0.71859254 -0.6613389
## 61623  0.19011409 1.08449521  1.40738329  0.39234699  0.6220493

Con method = "Thurstone":

factor_scores_T <- factor.scores(dat, res.efa5, method = "Thurstone")
head(factor_scores_T$scores)
##               PA2        PA1         PA3         PA5        PA4
## 61617 -0.21429864 0.06866200 -1.33215114 -0.85349374 -1.5809669
## 61618  0.14994681 0.48095597 -0.59953429 -0.08500211 -0.1875012
## 61620  0.62823220 0.10995265 -0.04812899 -0.55682240  0.2501126
## 61621 -0.09336466 0.03847091 -1.05097714 -0.10479813 -1.1004252
## 61622 -0.16330768 0.44219091 -0.10510915 -0.71859254 -0.6613389
## 61623  0.19011409 1.08449521  1.40738329  0.39234699  0.6220493

Con method = "tenBerge":

factor_scores_t <- factor.scores(dat, res.efa5, method = "tenBerge")
head(factor_scores_t$scores)
##              PA2        PA1         PA3         PA5        PA4
## 61617 -0.2470174 0.20155076 -1.49101744 -0.94433657 -1.8421037
## 61618  0.1652495 0.59269094 -0.69988278 -0.12183133 -0.2198948
## 61620  0.6886329 0.18742429 -0.03357888 -0.68063210  0.3100818
## 61621 -0.1148109 0.09767983 -1.19382274 -0.07412927 -1.2916478
## 61622 -0.1652867 0.58463511 -0.09792970 -0.86737962 -0.7911181
## 61623  0.2536901 1.20723761  1.59279585  0.32578492  0.6496251

Con method = "Bartlett":

factor_scores_B <- factor.scores(dat, res.efa5, method = "Bartlett")
head(factor_scores_B$scores)
##              PA2       PA1         PA3           PA5        PA4
## 61617 -0.2686324 0.3661345 -1.66618809 -1.061791e+00 -2.1591752
## 61618  0.1538734 0.7233457 -0.81461366 -1.511627e-01 -0.2399381
## 61620  0.7901091 0.2975239 -0.01509769 -8.649441e-01  0.3790919
## 61621 -0.1242307 0.1629675 -1.35779025 -9.953746e-05 -1.5162828
## 61622 -0.1970329 0.7649929 -0.08198089 -1.012403e+00 -0.9515680
## 61623  0.3511166 1.3494382  1.81882386  2.085022e-01  0.6638929

4. Revisión de resultados

Vamos a compara los puntajes obtenidos con los puntajes dentro del modelo fa asegurándonos de que los métodos y parámetros coincidan. Por ejemplo,

all.equal(factor_scores_r$scores, res.efa5$scores)
## [1] TRUE
all.equal(factor_scores_T$scores, res.efa5$scores)
## [1] TRUE

16 Extrayendo las medias de los factores latentes

Una vez que tengamos los puntajes de los factores, podemos calcular las medias de los factores latentes utilizando la función colMeans.

Primera forma.

factor_means <- colMeans(res.efa5$scores, na.rm = TRUE)
factor_means
##           PA2           PA1           PA3           PA5           PA4 
##  0.0068790849 -0.0158154399  0.0001602402 -0.0069550686  0.0131220000

Segunda forma.

factor_means_T <- colMeans(factor_scores_T$scores, na.rm = TRUE)
factor_means_T
##           PA2           PA1           PA3           PA5           PA4 
##  0.0068790849 -0.0158154399  0.0001602402 -0.0069550686  0.0131220000

17 Tópicos sumplementarios

No hacer click aquí: Pendiente

18 Ejercicios

18.0.1 Ejercicio 1

La información en la tabla siguiente está relacionada con la población, situación socioeconómica e indicadores comerciales y económicos. Las observaciones son las cincuenta capitales de provincias españaolas. Se desea investigar si existe una estructura de correlación entre las variables. Si ese fuese el caso, se esta interesado en saber ¿cómo esos ejes factoriales y las variables originales están relacionados?

data <- matrix(c(
  37212.78, 17190.34, 17447.69, 490.61, 261.79, 231.99, 262.42, 154.03, 400.6,
  38893.57, 10711.05, 17210.87, 428.6, 243.36, 169.27, 130.3, 132.22, 303.4,
  36326.54, 13300.91, 14846.77, 316.29, 159.11, 170.76, 101.55, 105.11, 212.8,
  37570.81, 18944.99, 16793.17, 523.91, 264.75, 200.57, 182.08, 145.45, 353.35,
  35284.45, 15689.25, 20029.81, 336.41, 234.72, 199.2, 153.23, 149.75, 342.68,
  37399.21, 15437.96, 17996.12, 395.09, 221.71, 221.71, 180.97, 175.28, 401.72,
  39035.86, 16264.57, 17635.03, 424.47, 311.08, 203.97, 248.18, 135.86, 345.4,
  45678.27, 14409.49, 16802.08, 384.21, 266.57, 215.22, 170.45, 135.48, 402.49,
  41009.96, 12356.56, 11007.16, 497.78, 257.89, 239.89, 197.91, 209.91, 555.76,
  43179.77, 10291.65, 11462.77, 393.6, 219.38, 222.61, 203.25, 109.69, 441.99,
  45557.38, 13491.03, 10866.36, 496.91, 314.29, 263.67, 215.49, 185.55, 456.54,
  49481.52, 15860.11, 10756, 493.14, 332.2, 236.23, 193.91, 188.49, 421.77,
  61153.99, 24203.87, 13726.77, 830.81, 414.43, 323.38, 382.35, 253.07, 608.2,
  39543.01, 19537.56, 12116.33, 431.85, 252.22, 224.2, 180.43, 229.27, 515.12,
  45173.3, 17233.58, 12980.4, 591.75, 265.14, 252.12, 235.97, 263.58, 575.08,
  48717.16, 16586.09, 12006.67, 484.51, 286.28, 226.04, 222.95, 150.86, 399.55,
  38690.14, 12023.74, 13387.34, 573.51, 238.63, 242.64, 188.5, 160.42, 447.18,
  40056.95, 12080.06, 12208.84, 462.55, 233.93, 234.52, 177.81, 163.64, 383.39,
  43068.3, 14554.59, 12977.37, 587.27, 350.72, 296.71, 269.36, 181.17, 451.9,
  39335.82, 13262.93, 12978.45, 559.18, 286.92, 257.62, 184.36, 172.15, 405.35,
  36772.01, 13709.73, 11465.01, 420.99, 273.67, 185.49, 181.19, 137.1, 302.16,
  42378.11, 12274.6, 12372.77, 380.62, 182.56, 179.12, 86.11, 103.34, 254.9,
  43710.48, 13307.36, 11935.41, 513.78, 273.83, 304.88, 256.89, 149.62, 443.2,
  39923.36, 12048.35, 12602.13, 373.34, 192.9, 185.95, 135.26, 138.74, 321.21,
  40833.11, 16259.05, 13223.95, 543.97, 288.85, 312.31, 231.66, 178.88, 501.45,
  36511.77, 12569.1, 15116.95, 467.37, 231.83, 276.41, 187.99, 183.53, 417.58,
  40199.87, 13590.63, 14154.25, 457.62, 186.75, 230.49, 183.38, 159.83, 516.5,
  39990.4, 13279.24, 12254.07, 274.83, 222.48, 196.31, 89.43, 80.7, 259.56,
  38776.88, 13940.93, 14382.86, 485.08, 223.2, 233.61, 172.61, 148.8, 464.25,
  44762.27, 14257.84, 16361.43, 516.06, 298.94, 258.03, 243.87, 165.2, 534.94,
  67254.52, 21987.93, 12374.01, 767.98, 403.77, 293.19, 231.19, 238.51, 698.29,
  71404, 33762.64, 17736.19, 882.55, 466.7, 477.17, 480.17, 282.71, 912.46,
  46120.99, 17352.96, 12411.15, 620.98, 342.38, 310.49, 223.22, 231.61, 625.17,
  47365.85, 18373.8, 15603.39, 537.04, 324, 306.24, 252.1, 193.51, 553.02,
  51851.44, 19419.38, 13249.63, 458.02, 297.1, 230.3, 205.2, 150.58, 399.7,
  44084.65, 16334.68, 13364.28, 552.9, 301.19, 272.09, 289.55, 172.42, 509.25,
  50402.55, 16850.46, 10806.54, 524.17, 405.83, 241.31, 180.47, 183.55, 510.92,
  33745.96, 11322.14, 15029.64, 452.45, 275.17, 238.94, 153.39, 158.01, 420.08,
  37276.96, 12084.9, 13311.61, 395.27, 227.99, 225.52, 120.19, 172.23, 405.18,
  48463.45, 15073.88, 15078.26, 638.17, 371.61, 245.88, 249.46, 197.34, 502.5,
  40698.02, 14951.7, 15526.68, 631.32, 275.99, 264.49, 356.49, 175.94, 560.03,
  44849.74, 12509.44, 17704.92, 800.95, 319.82, 269.47, 337.54, 197.67, 471.81,
  39591.71, 15496.53, 18553.35, 531.74, 239.15, 244.49, 284.57, 141.62, 382.1,
  62420.13, 21489.32, 9828.63, 427.1, 301.01, 223.48, 186.12, 157.51, 458.73,
  38674.8, 14742.95, 14458.62, 402.32, 248.45, 229.29, 239.63, 147.49, 391.98,
  45706.18, 17161.14, 11581.69, 391.92, 267.91, 192.03, 88.95, 110.41, 312.91,
  45569.57, 13573.92, 13382.62, 323.63, 242.61, 86.3, 101.17, 147.67, 331.78,
  58575.7, 18285.03, 13371.68, 524.63, 282.98, 218.12, 114.8, 168.75, 458.04,
  48907.32, 20248.71, 12265.8, 288.01, 188.9, 140.7, 81.97, 130.91, 256.93,
  43960.24, 13578.42, 12255.44, 708.43, 341.59, 292.68, 298.99, 235.88, 515.15
), ncol = 9, byrow = TRUE)

df <- as.data.frame(data)

print(df)
##          V1       V2       V3     V4     V5     V6     V7     V8     V9
## 1  37212.78 17190.34 17447.69 490.61 261.79 231.99 262.42 154.03 400.60
## 2  38893.57 10711.05 17210.87 428.60 243.36 169.27 130.30 132.22 303.40
## 3  36326.54 13300.91 14846.77 316.29 159.11 170.76 101.55 105.11 212.80
## 4  37570.81 18944.99 16793.17 523.91 264.75 200.57 182.08 145.45 353.35
## 5  35284.45 15689.25 20029.81 336.41 234.72 199.20 153.23 149.75 342.68
## 6  37399.21 15437.96 17996.12 395.09 221.71 221.71 180.97 175.28 401.72
## 7  39035.86 16264.57 17635.03 424.47 311.08 203.97 248.18 135.86 345.40
## 8  45678.27 14409.49 16802.08 384.21 266.57 215.22 170.45 135.48 402.49
## 9  41009.96 12356.56 11007.16 497.78 257.89 239.89 197.91 209.91 555.76
## 10 43179.77 10291.65 11462.77 393.60 219.38 222.61 203.25 109.69 441.99
## 11 45557.38 13491.03 10866.36 496.91 314.29 263.67 215.49 185.55 456.54
## 12 49481.52 15860.11 10756.00 493.14 332.20 236.23 193.91 188.49 421.77
## 13 61153.99 24203.87 13726.77 830.81 414.43 323.38 382.35 253.07 608.20
## 14 39543.01 19537.56 12116.33 431.85 252.22 224.20 180.43 229.27 515.12
## 15 45173.30 17233.58 12980.40 591.75 265.14 252.12 235.97 263.58 575.08
## 16 48717.16 16586.09 12006.67 484.51 286.28 226.04 222.95 150.86 399.55
## 17 38690.14 12023.74 13387.34 573.51 238.63 242.64 188.50 160.42 447.18
## 18 40056.95 12080.06 12208.84 462.55 233.93 234.52 177.81 163.64 383.39
## 19 43068.30 14554.59 12977.37 587.27 350.72 296.71 269.36 181.17 451.90
## 20 39335.82 13262.93 12978.45 559.18 286.92 257.62 184.36 172.15 405.35
## 21 36772.01 13709.73 11465.01 420.99 273.67 185.49 181.19 137.10 302.16
## 22 42378.11 12274.60 12372.77 380.62 182.56 179.12  86.11 103.34 254.90
## 23 43710.48 13307.36 11935.41 513.78 273.83 304.88 256.89 149.62 443.20
## 24 39923.36 12048.35 12602.13 373.34 192.90 185.95 135.26 138.74 321.21
## 25 40833.11 16259.05 13223.95 543.97 288.85 312.31 231.66 178.88 501.45
## 26 36511.77 12569.10 15116.95 467.37 231.83 276.41 187.99 183.53 417.58
## 27 40199.87 13590.63 14154.25 457.62 186.75 230.49 183.38 159.83 516.50
## 28 39990.40 13279.24 12254.07 274.83 222.48 196.31  89.43  80.70 259.56
## 29 38776.88 13940.93 14382.86 485.08 223.20 233.61 172.61 148.80 464.25
## 30 44762.27 14257.84 16361.43 516.06 298.94 258.03 243.87 165.20 534.94
## 31 67254.52 21987.93 12374.01 767.98 403.77 293.19 231.19 238.51 698.29
## 32 71404.00 33762.64 17736.19 882.55 466.70 477.17 480.17 282.71 912.46
## 33 46120.99 17352.96 12411.15 620.98 342.38 310.49 223.22 231.61 625.17
## 34 47365.85 18373.80 15603.39 537.04 324.00 306.24 252.10 193.51 553.02
## 35 51851.44 19419.38 13249.63 458.02 297.10 230.30 205.20 150.58 399.70
## 36 44084.65 16334.68 13364.28 552.90 301.19 272.09 289.55 172.42 509.25
## 37 50402.55 16850.46 10806.54 524.17 405.83 241.31 180.47 183.55 510.92
## 38 33745.96 11322.14 15029.64 452.45 275.17 238.94 153.39 158.01 420.08
## 39 37276.96 12084.90 13311.61 395.27 227.99 225.52 120.19 172.23 405.18
## 40 48463.45 15073.88 15078.26 638.17 371.61 245.88 249.46 197.34 502.50
## 41 40698.02 14951.70 15526.68 631.32 275.99 264.49 356.49 175.94 560.03
## 42 44849.74 12509.44 17704.92 800.95 319.82 269.47 337.54 197.67 471.81
## 43 39591.71 15496.53 18553.35 531.74 239.15 244.49 284.57 141.62 382.10
## 44 62420.13 21489.32  9828.63 427.10 301.01 223.48 186.12 157.51 458.73
## 45 38674.80 14742.95 14458.62 402.32 248.45 229.29 239.63 147.49 391.98
## 46 45706.18 17161.14 11581.69 391.92 267.91 192.03  88.95 110.41 312.91
## 47 45569.57 13573.92 13382.62 323.63 242.61  86.30 101.17 147.67 331.78
## 48 58575.70 18285.03 13371.68 524.63 282.98 218.12 114.80 168.75 458.04
## 49 48907.32 20248.71 12265.80 288.01 188.90 140.70  81.97 130.91 256.93
## 50 43960.24 13578.42 12255.44 708.43 341.59 292.68 298.99 235.88 515.15

18.0.2 Ejercicio 2

Los datos de la tabla de la figura 18.1 proceden de un registro de lactantes tratados quirúrgicamente junto con mediciones de varios marcadores genéticos relacionados con la enfermedad. La edad, medida en días, es la edad edad del niño en el momento de la intervención quirúrgica. La edad, por tanto, representa el tiempoestuvo expuesto al tumor. La hipótesis era que la exposición a la magnitud de la expresión de algunos de estos genes a lo largo del tiempo. genes a lo largo del tiempo.

data <- data.frame(
  Age = c(81, 95, 95, 165, 286, 299, 380, 418, 420, 547, 590, 635, 752, 760, 1171, 1277, 1520, 2138, 3626),
  RB = c(2.0, 6.5, 3.6, 1.9, 2.6, 2.9, 1.9, 7.1, 6.4, 6.4, 1.8, 6.7, 1.8, 7.3, 1.8, 1.3, 4.0, 0.5, 4.2),
  p16 = c(3.07, 1.90, 3.82, 3.74, 5.17, 5.76, 2.40, 3.38, 3.37, 4.05, 5.15, 2.67, 3.28, 0.92, 6.56, 0.05, 2.79, 0.00, 4.24),
  DLK = c(308975, 70988, 153061, 596992, 369601, 1119258, 214071, 69511, 81457, 64348, 164881, 126016, 567858, 43438, 716260, 94, 31125, 2331, 560208),
  Nanog = c(94, 382, 237, 88, 282, 177, 45, 265, 659, 336, 2012, 3072, 127, 698, 392, 15, 454, 33, 340),
  C_Myc = c(6.49, 1.00, 0.00, 0.00, 12.23, 8.76, 5.76, 1.17, 1.88, 0.78, 35.65, 0.00, 4.13, 1.77, 12.92, 0.36, 0.62, 0.03, 5.43),
  EZH2 = c(2.76, 7.09, 5.57, 2.47, 1.63, 3.51, 1.41, 3.07, 3.87, 4.76, 9.45, 4.35, 1.00, 3.32, 2.90, 3.83, 2.33, 0.17, 1.36),
  IGF_2 = c(11176, 5340, 6310, 7009, 7104, 9342, 3726, 8039, 12583, 6505, 32722, 11763, 10283, 11518, 13264, 30, 1163, 66, 21174)
)
**Edad, en días, y expresión de los marcadores genéticos de los lactantes que fueron tratados quirúrgicamente por hemangioma**

Figure 18.1: Edad, en días, y expresión de los marcadores genéticos de los lactantes que fueron tratados quirúrgicamente por hemangioma

18.0.3 Ejercicio 3

Dado el modelo factorial \[X = \Lambda f + u,\]

donde \(X = (X_1, X_2, X_3, X_4)\) tiene media cero y varianzas \((1, 2, 1, 7)\). Suponga, además, que

\[\Lambda = \begin{pmatrix} 0.8 & 1 & 0 & 2 \end{pmatrix}^T, \qquad Var(f) = 1\]

Realizar lo siguiente:

  1. Calcular las covarianzas entre las variables y el factor.

  2. Calcular las correlaciones entre las variables y el factor.

  3. Escribir el modelo como un modelo unifactorial con un factor de varianza igual a 5.

18.0.4 Ejercicio 4

Indicar si es posible el siguiente modelo factorial:

\[X = \Lambda f + u,\] donde \(X = (X_1, X_2, X_3)\) tiene media cero y varianzas \((3, 2, 1)\) y, además,

\[\Lambda = \begin{pmatrix} 3 & 0 & 3 \end{pmatrix}^T, \qquad Var(f) = 1\]

Bibliografía

Consultar el documento RPubs :: Análisis multivariado (bibliografía).

 

 
If you found any ERRORS or have SUGGESTIONS, please report them to my email. Thanks.  
LS0tDQp0aXRsZTogIkFOw4FMSVNJUyBGQUNUT1JJQUwgKEVGQSkiDQpzdWJ0aXRsZTogPGgxPioqQXBsaWNhY2nDs24qKjwvaDE+DQoNCmF1dGhvcjogDQogIC0gbmFtZSAgICAgICAgICA6ICJEci4gcmVyLiBuYXQuIEh1bWJlcnRvIExMaW7DoXMgU29sYW5vIg0KICAgIGFmZmlsaWF0aW9uICAgOiAiRGVwYXJ0YW1lbnRvIGRlIE1hdGVtw6F0aWNhcyB5IEVzdGFkw61zdGljYSwgVW5pdmVyc2lkYWQgZGVsIE5vcnRlIChCYXJyYW5xdWlsbGEsIENvbG9tYmlhKSINCiAgICAgI2NvcnJlc3BvbmRpbmcgOiB5ZXMgICAgIyBEZWZpbmUgb25seSBvbmUgY29ycmVzcG9uZGluZyBhdXRob3INCiAgICAgI2FkZHJlc3MgICAgICAgOiAiRGVwYXJ0YW1lbnRvIGRlIE1hdGVtw6F0aWNhcyB5IEVzdGFkw61zdGljYSINCiAgICBlbWFpbCAgICAgICAgIDogfA0KICAgICAgaGxsaW5hc0B1bmlub3J0ZS5lZHUuY28NCiAgICAgIA0KICAgICAgW0Jpb2dyYXBoaWNhbCBza2V0Y2hdKGh0dHBzOi8vcnB1YnMuY29tL2hsbGluYXMvQmlvX1NrZXRjaCkNCiAgICAgIA0KICAgICAgYHIgZm9ybWF0KFN5cy50aW1lKCksICIlZC8lbS8leSIpYCANCiAgICAgIA0KICAgICAjcm9sZTogICAgICAgICAjIENvbnRyaWJ1dG9yc2hpcCByb2xlcyAoZS5nLiwgQ1JlZGlULCBodHRwczovL2Nhc3JhaS5vcmcvY3JlZGl0LykNCiAgIyAgICAtIENvbmNlcHR1YWxpemF0aW9uDQogICMgICAgLSBXcml0aW5nIC0gT3JpZ2luYWwgRHJhZnQgUHJlcGFyYXRpb24NCiAgIyAgICAtIFdyaXRpbmcgLSBSZXZpZXcgJiBFZGl0aW5nDQogIyAtIG5hbWUgICAgICAgICAgOiAiQXV0b3IgbnVtZXJvIDIiDQogIyAgIGFmZmlsaWF0aW9uICAgOiAiMSwyIg0KICMgICByb2xlOg0KICMgICAgIC0gV3JpdGluZyAtIFJldmlldyAmIEVkaXRpbmcNCiAgICAgI2FmZmlsaWF0aW9uOg0KICAjLSBpZCAgICAgICAgICAgIDogIjEiDQogICMgIGluc3RpdHV0aW9uICAgOiAiVW5pdmVyc2lkYWQgZGVsIE5vcnRlIChCYXJyYW5xdWlsbGEsIENvbG9tYmlhKSINCiAgIyFbXShobGxpbmFzLmpwZyl7d2lkdGg9MWlufSANCiAgDQojZGF0ZTogJ2ByIGZvcm1hdChTeXMudGltZSgpLCAiJWQvJW0vJXkiKWAnICAjIHZlciBodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ybWFya2Rvd24tY29va2Jvb2svdXBkYXRlLWRhdGUuaHRtbA0Kb3V0cHV0OiANCiAgICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6IA0KICAgICAgICAgICNPSk8gU2FsZW4gY2FwaXR1bG9zLCBzZWNjaW9uZXMgeSBUZW9yZW1hcw0KICAgICNib29rZG93bjo6aHRtbF9ib29rOg0KICAgICAgICAgICNPSk8gRVJST1IgU2FsZW4gdGVvcmVtYXMsIHBlcm8gbm8gc2FsZW4gbG9zIGNhcGl0dWxvcyANCiAgICAjaHRtbF9kb2N1bWVudDoNCiAgICAgICAgICB0b2M6IHRydWUgICAgICAjIHRhYmxlIG9mIGNvbnRlbnQgdHJ1ZQ0KICAgICAgICAgIHRvY19kZXB0aDogNCAgICMgdXB0byB0aHJlZSBkZXB0aHMgb2YgaGVhZGluZ3MgKHNwZWNpZmllZCBieSAjLCAjIyBhbmQgIyMjKQ0KICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZSAjQ29uIHRydWUsIHRvYyBzYWxlIGFsIG1hcmdlbiBpenF1aWVyZG8gZGUgbGEgcMOhZ2luYTsgZGUgbG8gY29udHJhcmlvLCBhcnJpYmENCiAgICAgICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UNCiAgICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUgICAjIGlmIHlvdSB3YW50IG51bWJlciBzZWN0aW9ucyBhdCBlYWNoIHRhYmxlIGhlYWRlcg0KICAgICAgICAgICN0aGVtZTogc2FuZHN0b25lDQogICAgICAgICAgI3RoZW1lOiB1bml0ZWQgICMgbWFueSBvcHRpb25zIGZvciB0aGVtZSwgdGhpcyBvbmUgaXMgbXkgZmF2b3JpdGUuDQogICAgICAgICAgI3RoZW1lOiBmbGF0bHkgICMgDQogICAgICAgICAgI3RoZW1lOiBjZXJ1bGVhbiAgIyANCiAgICAgICAgICAjaGlnaGxpZ2h0OiB0YW5nbyAgIyBzcGVjaWZpZXMgdGhlIHN5bnRheCBoaWdobGlnaHRpbmcgc3R5bGUNCiAgICAgICAgICAjY3NzOiBTY3JpcHRzIGFjY2Vzb3Jpb3MvZXN0aWxvYm90b24uY3NzDQogICAgICAgICAgI2NzczogbXkuY3NzICAgIyB5b3UgY2FuIGFkZCB5b3VyIGN1c3RvbSBjc3MsIHNob3VsZCBiZSBpbiBzYW1lIGZvbGRlcg0KICAgICAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAgICAgICAjaGlnaGxpZ2h0OiB0YW5nbyAgIyBjYW1iaWFyIGNvbG9yIGRlIGxpYnJhcnkgZW4gYXp1bA0KICAgICMgYm9va2Rvd246OmdpdGJvb2s6DQogICAgIyAgICAgIGluY2x1ZGVzOg0KICAgICMgICAgICAgIGluX2hlYWRlcjogaGVhZGVyLmh0bWwNCiAgICAjIGJvb2tkb3duOjpwZGZfYm9vazoNCiAgICAjICAgICAgIGtlZXBfdGV4OiB5ZXMNCiAgICAjIGJvb2tkb3duOjpodG1sX2Jvb2s6DQogICAgIyAgICAgICBjc3M6IHRvYy5jc3MNCiAgICAjIGJvb2tkb3duOjpodG1sX2Jvb2s6DQogICAgIyAgICAgICAgIGluY2x1ZGVzOg0KICAgICMgICAgICAgICAgIGluX2hlYWRlcjogc3R5bGUuY3NzDQogICAgI2Jvb2tkb3duOjpodG1sX2RvY3VtZW50MjogZGVmYXVsdA0KICAgICMgYm9va2Rvd246OnBkZl9kb2N1bWVudDI6DQogICAgIyAgICAgIGtlZXBfdGV4OiB0cnVlDQogICAgI2JpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWINCiAgICBtYXRoamF4OiAiaHR0cDovL2V4YW1wbGUuY29tL21hdGhqYXgvTWF0aEpheC5qcz9jb25maWc9VGVYLUFNUy1NTUxfSFRNTG9yTU1MIg0KaGVhZGVyLWluY2x1ZGVzOg0KICAgIFx1c2VwYWNrYWdlW3gxMW5hbWVzXXt4Y29sb3J9IA0KICAgIA0KY3NsOiBzY2llbmNlLmNzbA0KI09qbzogU2UgdXRpbGl6YSBsZW5ndWFqZSBZQU1MDQoNCmFic3RyYWN0OiB8DQogKipFbiBbUnB1YnM6OiB0b2NdKGh0dHBzOi8vcnB1YnMuY29tL2hsbGluYXMvdG9jKSBzZSBwdWVkZW4gdmVyIG90cm9zIGRvY3VtZW50b3MgZGUgcG9zaWJsZSBpbnRlcsOpcy4qKg0KICANCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgZmlnLmFsaWduPSJjZW50ZXIiLCAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSMsDQogICAgICAgICAgICAgICAgICAgICAgI3N0eWxlID0gImNvbG9yOmRhcmtibHVlIg0KICAgICAgICAgICAgICAgICAgICAjIGNsYXNzLnNvdXJjZT0iYmctZGFuZ2VyIiwgY2xhc3Mub3V0cHV0PSJiZy13YXJuaW5nIiAgICNDb2xvcmVzIGRlbnRybyBkZWwgY2h1bmsNCiAgICAgICAgICAgICAgICAgICAgICkNCmxpYnJhcnkocmdsKQ0Ka25pdHI6OmtuaXRfaG9va3Mkc2V0KHdlYmdsID0gaG9va193ZWJnbCkNCmBgYA0KDQoNCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0NCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9sYW5ndWFnZS1lbmdpbmVzLmh0bWwNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vbWFya2Rvd24tc3ludGF4Lmh0bWwNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vYS1zaW5nbGUtZG9jdW1lbnQuaHRtbA0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi9tYXJrZG93bi1leHRlbnNpb25zLWJ5LWJvb2tkb3duLmh0bWwNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duL2Jvb2tkb3duLW1hcmtkb3duLmh0bWwgICMgVGVvcmVtcyBhbmQgcHJvb2ZzDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL21hcmtkb3duLWV4dGVuc2lvbnMtYnktYm9va2Rvd24uaHRtbCN0aGVvcmVtcw0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi9odG1sLmh0bWwNCg0KaHR0cHM6Ly93d3cuZGF0YS10by12aXouY29tLw0KICANCltScHVic10obGluaykNCiAgDQooXCNlcTplYy0pLCAgRWN1YWNpb24gXEByZWYoZXE6ZWMtKSwgRmlndXJhIFxAcmVmKGZpZzpGaWctKSwgVGFibGUgXEByZWYodGFiOm10Y2FycyksIFRoZW9yZW0gXEByZWYodGhtOmJvcmluZykNCg0KDQojIFRpdHVsbyB7I1RpdHVsb1NlY2Npb259ICAgXEByZWYoVGl0dWxvU2VjY2lvbikNCiAgDQojIEZvciBIVE1MLCB3ZSBjYW4gc2V0IGNvbG9yIHdpdGggQ1NTLCBlLmcuLCA8c3BhbiBzdHlsZT0iY29sb3I6IHJlZDsiPnRleHQ8L3NwYW4+DQogIA0KIyBodHRwczovL3JhZGlhbnQtcnN0YXRzLmdpdGh1Yi5pby9kb2NzL21vZGVsL2xvZ2lzdGljLmh0bWwgU2hpbm55IExvZ2l0ICANCiAgDQpgYGANCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQojTGEgZm90byB0YW1hw7FvIGPDqWR1bGENCg0KaHRtbHRvb2xzOjppbWcoc3JjID0ga25pdHI6OmltYWdlX3VyaShmaWxlLnBhdGgoUi5ob21lKCJkb2MiKSwgImh0bWwiLCAibG9nby5qcGciKSksIA0KICAgICAgICAgICAgICAgYWx0ID0gJ2hsbGluYXMnLCANCiAgICAgICAgICAgICAgIHN0eWxlID0gJ3Bvc2l0aW9uOmFic29sdXRlOyB0b3A6MDsgcmlnaHQ6MDsgcGFkZGluZzoxMHB4OycgIywNCiAgICAgICAgICAgICAgIHdpZHRoID0gIjIwMHB4IikgICMgQXF1w60gZXNwZWNpZmljYXMgZWwgYW5jaG8gZGVzZWFkbyBlbiBww614ZWxlcyBvIHBvcmNlbnRhamUNCmBgYA0KDQoNCg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgfQ0KIyBMYSBmb3RvIGdyYW5kZQ0KDQpodG1sdG9vbHM6OmltZyhzcmMgPSBrbml0cjo6aW1hZ2VfdXJpKCJobGxpbmFzMjAyMy5qcGciKSwgDQogICAgICAgICAgICAgICBhbHQgPSAnaGxsaW5hczIwMjMnLCANCiAgICAgICAgICAgICAgIHN0eWxlID0gJ3Bvc2l0aW9uOmFic29sdXRlOyB0b3A6MDsgcmlnaHQ6MDsgcGFkZGluZzoxcHg7JywNCiAgICAgICAgICAgICAgIHdpZHRoPSIxNSUiKQ0KYGBgDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgIC0tPg0KDQpgYGB7Y3NzLCBlY2hvPUZBTFNFfQ0KLmNvbHVtbnMge2Rpc3BsYXk6IGZsZXg7fQ0KaDEge2NvbG9yOiBkYXJrYmx1ZTt9DQpoMyB7Y29sb3I6IGRhcmtncmVlbjt9DQpoNCB7Y29sb3I6IGdyZWVuO30NCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAgLS0+DQoNCiMgTGlicmVyw61hcw0KDQojIyMgUGFyYSBFRkENCg0KDQpgYGB7ciwgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCiMgIGh0dHBzOi8vcnB1YnMuY29tL0FsZW1hLzEwMDA1ODINCg0KIyBodHRwczovL3d3dy5nZWVrc2ZvcmdlZWtzLm9yZy9jb250ZXh0dWFsLW91dGxpZXJzLw0KYGBgDQoNCkVsIHNvZnR3YXJlIFIgZGlzcG9uZSBkZSB2YXJpYXMgZnVuY2lvbmVzIGRlIGRpZmVyZW50ZXMgcGFxdWV0ZXMgcGFyYSBjYWxjdWxhciBFRkE6DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShHUEFyb3RhdGlvbikNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgIC0tPg0KDQojIyMgUGFyYSBvdHJvcyBhbsOhbGlzaXMNCg0KYGBge3IsICBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShhcGxvcmUzKSAgICAgICAjQmFzZSBkZSBkYXRvcyBwYXJhIGxvcyBlamVtcGxvcw0KbGlicmFyeShsc20pICAgICAgICAgICAjQmFzZSBkZSBkYXRvcyBwYXJhIGVqZW1wbG9zIHkgZXN0aW1hY2lvbmVzIGRlbCBMb2ctdmVyb3NpbWlsaXR1ZA0KbGlicmFyeShrbml0cikgICAgICAgICAjRWRpdGFyIHRhYmxhcyBjb24ga2FibGUoKQ0KbGlicmFyeShrYWJsZUV4dHJhKSAgICAjRWRpdGFyIHRhYmxhcyBtw6FzIGVzdGlsaXphZGFzDQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgICNJbmNsdXllIGEgZHBseXIgeSBnZ3Bsb3QyDQpsaWJyYXJ5KHN0cmluZ3IpICAgICAgICNSZWVtcGxhemFyIGNhcmFjdGVyZXMgZW4gdW4gZGF0YSBmcmFtZQ0KbGlicmFyeShvdXRsaWVycykgICAgICAjb3V0bGllcnM6OmdydWJicy50ZXN0DQpsaWJyYXJ5KEVudlN0YXRzKSAgICAgICNFbnZTdGF0czo6cm9zbmVyVGVzdA0KbGlicmFyeShETXdSMikgICAgICAgICAjTE9GIChMb2NhbCBPdXRsaWVyIEZhY3RvcikNCmxpYnJhcnkocmdsKSAgICAgICAgICAgI3JnbDo6cGxvdDNkYA0KbGlicmFyeShjb3JycGxvdCkgICAgICAjTWF0cml6IGRlIGNvcnJlbGFjaW9uZXMNCmxpYnJhcnkodGV4dHNoYXBlKSAgICAgI2NvbHVtbl90b19yb3duYW1lcw0KbGlicmFyeShvcGVueGxzeCkgICMgTGlicmVyw61hIHBhcmEgZXNjcmliaXIgYXJjaGl2b3MgZGUgRXhjZWwNCiNvcHRzX2tuaXQkc2V0KGV2YWwuYWZ0ZXIgPSAnZmlnLmNhcCcpDQpgYGANCg0KYGBge2NzcywgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0NCiNodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MTAzMDQ3Ny9jaGFuZ2luZy1jaHVuay1iYWNrZ3JvdW5kLWNvbG9yLWluLXJtYXJrZG93bg0KDQouYmFkQ29kZSB7DQpiYWNrZ3JvdW5kLWNvbG9yOiByZWQ7DQp9DQpgYGANCg0KYGBge3IsICBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBldmFsPUZBTFNFfQ0KbGlicmFyeShhcGxvcmUzKSAgICAgICAjQmFzZSBkZSBkYXRvcyBwYXJhIGxvcyBlamVtcGxvcw0KbGlicmFyeShsc20pICAgICAgICAgICAjQmFzZSBkZSBkYXRvcyBwYXJhIGVqZW1wbG9zIHkgZXN0aW1hY2lvbmVzIGRlbCBMb2ctdmVyb3NpbWlsaXR1ZA0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAjSW5jbHV5ZSBhIGRwbHlyIHkgZ2dwbG90Mg0KbGlicmFyeShzdHJpbmdyKSAgICAgICAjUmVlbXBsYXphciBjYXJhY3RlcmVzIGVuIHVuIGRhdGEgZnJhbWUNCmxpYnJhcnkob3V0bGllcnMpICAgICAgI291dGxpZXJzOjpncnViYnMudGVzdA0KbGlicmFyeShFbnZTdGF0cykgICAgICAjRW52U3RhdHM6OnJvc25lclRlc3QNCmxpYnJhcnkoRE13UjIpICAgICAgICAgI0xPRiAoTG9jYWwgT3V0bGllciBGYWN0b3IpDQpsaWJyYXJ5KHJnbCkgICAgICAgICAgICNyZ2w6OnBsb3QzZA0KbGlicmFyeShjb3JycGxvdCkgICAgICAjTWF0cml6IGRlIGNvcnJlbGFjaW9uZXMNCmxpYnJhcnkodGV4dHNoYXBlKSAgICAgI2NvbHVtbl90b19yb3duYW1lcw0KbGlicmFyeShvcGVueGxzeCkgICMgTGlicmVyw61hIHBhcmEgZXNjcmliaXIgYXJjaGl2b3MgZGUgRXhjZWwNCmBgYA0KDQoNCg0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFamVtcGxvOiBFbnVuY2lhZG8NCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpMb3MgZGF0b3MgdXRpbGl6YWRvcyBlbiBlc3RlIGVqZW1wbG8gZGVzY3JpYmVuIGVsIHJlbmRpbWllbnRvIGRlIGxvcyBhdGxldGFzIGR1cmFudGUgZG9zIGV2ZW50b3MgZGVwb3J0aXZvcyAoRGVzY3RhciB5IE9seW1waWNHKS4gQ29udGllbmUgMjcgaW5kaXZpZHVvcyAoYXRsZXRhcykgZGVzY3JpdG9zIG1lZGlhbnRlIDEzIHZhcmlhYmxlcy4gQ29uIGVzdG9zIGRhdG9zIGxsZXZhcmVtb3MgYSBjYWJvIHVuIFBDQS4gDQoNCg0KI2BgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0b3NDb21wbGV0byA8LSBmYWN0b2V4dHJhOjpkZWNhdGhsb24yDQphdHRhY2goZGF0b3NDb21wbGV0bykNCiNgYGANCg0KDQojYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuYW1lcyhkYXRvc0NvbXBsZXRvKQ0KI2BgYA0KDQpTZSByZXNhbHRhIHF1ZSBzw7NsbyBhbGd1bm9zIGRlIGVzdG9zIGluZGl2aWR1b3MgeSB2YXJpYWJsZXMgc2UgdXRpbGl6YXLDoW4gcGFyYSByZWFsaXphciBlbCBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIA0KDQojYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIDE6MTBdDQphdHRhY2goZGF0KQ0KaGVhZChkYXQsNCkpIA0KI2BgYA0KDQojYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjMsIDE6MTBdDQphdHRhY2goZGF0KQ0Ka2FibGUoaGVhZChkYXQsNCksYWxpZ24gPSAiY2NjIikgJT4lIyBTZSBuZWNlc2l0YSBsaWJyYXJ5KGtuaXRyKSANCmthYmxlX3N0eWxpbmcoKSAlPiUgICAgICAgICAgICAgICAgI2xpYnJhcnkoa2FibGVFeHRyYSkuLi4uIFNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmthYmxlX2NsYXNzaWNfMihmdWxsX3dpZHRoID0gRikgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi5Tb2xvIHBhcmEga25pdCB0byBodG1sDQojYGBgDQoNCg0KYGBgDQoNCg0KDQoNCg0KVmFtb3MgYSB1dGlsaXphciB1biBjb25qdW50byBkZSBkYXRvcyBsbGFtYWRvIGBiZmlgIHBhcmEgbGxldmFyIGEgY2FibyB1biBFRkEgZWwgY3VhbCBwcm92aWVuZSBkZWwgcGFxdWV0ZSBgcHN5Y2hgLiBFc3RlIGNvbmp1bnRvIGRlIGRhdG9zIGNvbnNpc3RlIGVuIDI1IMOtdGVtcyBkZSBwZXJzb25hbGlkYWQgYXV0b3JlcG9ydGFkb3MgZGVsIFtJbnRlcm5hdGlvbmFsIFBlcnNvbmFsaXR5IEl0ZW0gUG9vbF0oaHR0cHM6Ly9pcGlwLm9yaS5vcmcvKSB5IG90cmFzIHZhcmlhYmxlcyBjb21vIGBnZW5kZXJgIChnw6luZXJvKSwgYGVkdWNhdGlvbiBsZXZlbGAgKG5pdmVsIGVkdWNhdGl2bykgeSBgYWdlYCAoZWRhZCkgZGUgMjgwMCBzdWpldG9zLCB1dGlsaXphZG8gZW4gbGEgW1N5bnRoZXRpYyBBcGVydHVyZSBQZXJzb25hbGl0eSBBc3Nlc3NtZW50XShodHRwczovL3d3dy5zYXBhLXByb2plY3Qub3JnLykgKFNBUEEgcHJvamVjdCwgRXZhbHVhY2nDs24gZGUgUGVyc29uYWxpZGFkIGRlIEFwZXJ0dXJhIFNpbnTDqXRpY2EpLiBMb3Mgw610ZW1zIGRlIHBlcnNvbmFsaWRhZCBzZSBkaXZpZGVuIGVuIDUgY2F0ZWdvcsOtYXM6IA0KICANCiAgKyBgQWAgPSBBZ3JlZWFibGVuZXNzIChBbWFiaWxpZGFkKS4gDQogIA0KICArIGBDYCA9IENvbnNjaWVudGlvdXNuZXNzIChSZXNwb25zYWJpbGlkYWQpLiANCiAgDQogICsgYEVgID0gRXh0cmF2ZXJzaW9uIChFeHRyYXZlcnNpw7NuKS4gDQogIA0KICArIGBOYCA9IE5ldXJvdGljaXNtIChOZXVyb3RpY2lzbW8pLiANCiAgDQogICsgYE9gID0gT3Blbm5lc3MgKEFwZXJ0dXJhKS4gDQogIA0KDQpDYWRhIMOtdGVtIGZ1ZSByZXNwb25kaWRvIGVuIHVuYSBlc2NhbGEgZGUgc2VpcyBwdW50b3M6IA0KDQorIGAxYCA9IFZlcnkgSW5hY2N1cmF0ZSAoTXV5IEluZXhhY3RvKS4gDQoNCisgYDJgID0gTW9kZXJhdGVseSBJbmFjY3VyYXRlIChNb2RlcmFkYW1lbnRlIEluZXhhY3RvKS4NCg0KKyBgM2AgPSBTbGlnaHRseSBJbmFjY3VyYXRlIChMaWdlcmFtZW50ZSBJbmV4YWN0bykuIA0KDQorIGA0YCA9IFNsaWdodGx5IEFjY3VyYXRlIChMaWdlcmFtZW50ZSBQcmVjaXNvKS4NCg0KKyBgNWAgPSBNb2RlcmF0ZWx5IEFjY3VyYXRlIChNb2RlcmFkYW1lbnRlIFByZWNpc28pLiANCg0KKyBgNmAgPSBWZXJ5IEFjY3VyYXRlIChNdXkgUHJlY2lzbykuDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpkYXRvc0NvbXBsZXRvIDwtIHBzeWNoOjpiZmkNCmF0dGFjaChkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpuYW1lcyhkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNClNlIHJlc2FsdGEgcXVlIHPDs2xvIGFsZ3VuYXMgZGUgZXN0YXMgdmFyaWFibGVzIHNlIHV0aWxpemFyw6FuIHBhcmEgcmVhbGl6YXIgZWwgRUZBLiANCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0IDwtIGRhdG9zQ29tcGxldG9bMToyNV0NCmF0dGFjaChkYXQpDQpoZWFkKGRhdCw0KSANCmBgYA0KDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzE6MjVdDQphdHRhY2goZGF0KQ0KDQprYWJsZShoZWFkKGRhdCw0KSxhbGlnbiA9ICJjY2MiKSAlPiUjIFNlIG5lY2VzaXRhIGxpYnJhcnkoa25pdHIpIA0Ka2FibGVfc3R5bGluZygpICU+JSAgICAgICAgICAgICAgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi4gU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0Ka2FibGVfY2xhc3NpY18yKGZ1bGxfd2lkdGggPSBGKSAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLlNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogU29sdWNpw7NuDQoNCiMjIyBFc3RhZMOtc3RpY29zIGRlc2NyaXB0aXZvcyBiw6FzaWNvcw0KDQpQcmltZXJvLCBlcyByZWNvbWVuZGFibGUgZXhhbWluYXIgbG9zIGRhdG9zIGFudGVzIGRlIHJlYWxpemFyIGN1YWxxdWllciBhbsOhbGlzaXMuIEN1YWxxdWllciBwYXJ0aWNpcGFudGUgcXVlIHRlbmdhIGFsZ8O6biBkYXRvIGZhbHRhbnRlIHNlcsOhIGV4Y2x1aWRvIHBvciBjb21wbGV0byBkZWwgYW7DoWxpc2lzLiAgU2UgcHVlZGVuIHV0aWxpemFyIGRpdmVyc2FzIGZ1bmNpb25lcyAoY29tbyBzZSBtdWVzdHJhIGEgY29udGludWFjacOzbikuDQoNCg0KYGBge3J9DQpkZXNjcmliZShkYXQpDQpgYGANCg0KU2UgcmVzYWx0YSBxdWUsIGxhIGZ1bmNpw7NuIGBkZXNjcmliZWAgZGUgbGEgbGlicmVyw61hIGBwc3ljaGAsIGVsIG91dHB1dDoNCiAgDQogICsgYHRpbW1lZGAgc2UgcmVmaWVyZSBhIGxhIG1lZGlhbmEgdHJ1bmNhZGEsIHF1ZSBlcyB1bmEgbWVkaWRhIGRlIHRlbmRlbmNpYSBjZW50cmFsIHJvYnVzdGEgcXVlIGNhbGN1bGEgbGEgbWVkaWFuYSBkZSB1biBjb25qdW50byBkZSBkYXRvcyBkZXNwdcOpcyBkZSBlbGltaW5hciB1biBjaWVydG8gcG9yY2VudGFqZSBkZSBvYnNlcnZhY2lvbmVzIG3DoXMgZXh0cmVtYXMuIA0KICANCiAgKyBgbWFkYCBzaWduaWZpY2EgZGVzdmlhY2nDs24gYWJzb2x1dGEgbWVkaWFuYSwgcXVlIGVzIHVuYSBtZWRpZGEgZGUgZGlzcGVyc2nDs24gcXVlIGluZGljYSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIGRhdG9zIGVuIHJlbGFjacOzbiBjb24gbGEgbWVkaWFuYS4NCiAgDQogICsgYHNrZXdgIHNlIHJlZmllcmUgYSBsYSBhc2ltZXRyw61hIGRlIGxvcyBkYXRvcywgcXVlIGluZGljYSBzaSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBkYXRvcyBlcyBzaW3DqXRyaWNhIG8gc2kgZXN0w6Egc2VzZ2FkYSBoYWNpYSB1biBsYWRvLiBVbiB2YWxvciBwb3NpdGl2byBpbmRpY2Egc2VzZ28gaGFjaWEgbGEgZGVyZWNoYSwgbWllbnRyYXMgcXVlIHVuIHZhbG9yIG5lZ2F0aXZvIGluZGljYSBzZXNnbyBoYWNpYSBsYSBpenF1aWVyZGEuDQogIA0KICArIGBrdXJ0b3Npc2Agc2UgcmVmaWVyZSBhIGxhIGN1cnRvc2lzIGRlIGxvcyBkYXRvcywgcXVlIGluZGljYSBsYSBmb3JtYSBkZSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBkYXRvcyBlbiByZWxhY2nDs24gY29uIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbC4gVW4gdmFsb3IgZGUga3VydG9zaXMgbWF5b3IgcXVlIGNlcm8gaW5kaWNhIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgcHVudGlhZ3VkYSAobcOhcyBwaWNvcykgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLCBtaWVudHJhcyBxdWUgdW4gdmFsb3IgbWVub3IgcXVlIGNlcm8gaW5kaWNhIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgYWNoYXRhZGEgKG1lbm9zIHBpY29zKSBxdWUgbGEgZGlzdHJpYnVjacOzbiBub3JtYWwuDQogIA0KICArIGBzZWAgc2UgcmVmaWVyZSBhbCBlcnJvciBlc3TDoW5kYXIsIHF1ZSBlcyB1bmEgbWVkaWRhIGRlIGxhIHByZWNpc2nDs24gZGUgbGEgZXN0aW1hY2nDs24gZGUgdW5hIGVzdGFkw61zdGljYSBkZSBsYSBtdWVzdHJhLiBJbmRpY2EgbGEgdmFyaWFiaWxpZGFkIGVzcGVyYWRhIGVuIGxhIGVzdGltYWNpw7NuIGRlIGxhIGVzdGFkw61zdGljYSBzaSBzZSBtdWVzdHJlYSByZXBldGlkYW1lbnRlIGRlIGxhIG1pc21hIHBvYmxhY2nDs24uIFVuIGVycm9yIGVzdMOhbmRhciBtw6FzIHBlcXVlw7FvIGluZGljYSB1bmEgZXN0aW1hY2nDs24gbcOhcyBwcmVjaXNhIGRlIGxhIGVzdGFkw61zdGljYSBkZSBpbnRlcsOpcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQpgYGB7cn0NCnN1bW1hcnkoZGF0KQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBEYXRvcyBmYWx0YW50ZXMNCg0KTGEgbWF5b3LDrWEgZGUgbG9zIGVsZW1lbnRvcyBzb2xvIGNhcmVjZW4gZGUgZGF0b3MgZXF1aXZhbGVudGVzIGEgMjAgbyAzMCBwYXJ0aWNpcGFudGVzLCBsbyBjdWFsIG5vIHJlcHJlc2VudGEgdW4gZ3JhbiBwcm9ibGVtYSBlbiB1biBjb25qdW50byBkZSBkYXRvcyBjb24gMjgwMCBvYnNlcnZhY2lvbmVzLiBTaW4gZW1iYXJnbywgZXMgcG9zaWJsZSBxdWUgYWxndW5vcyBkZSBlc3RvcyB2YWxvcmVzIGZhbHRhbnRlcyBubyBzZSBzdXBlcnBvbmdhbiwgbG8gcXVlIHNpZ25pZmljYSBxdWUgcG9kcsOtYW4gZmFsdGFyIDIwIG8gMzAgaW5kaXZpZHVvcyBkaWZlcmVudGVzIGVuIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMuIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBEYXRvcyBwZXJkaWRvcyBwb3IgY29sdW1uYQ0KDQpgYGB7cn0NCm1pc3NpbmdzIDwtIGNvbFN1bXMoaXMubmEoZGF0KSkgDQptaXNzaW5ncw0KDQpzdW1tYXJ5KG1pc3NpbmdzKSANCmBgYA0KDQpBbHRlcm5hdGl2YW1lbnRlLCBwb2RlbW9zIG1pcmFyIGFsZ3VuYXMgdmFyaWFibGVzIGNvbiBhbGd1bmEgY29uZGljacOzbiBwYXJhIGVsIG7Dum1lcm8gZGUgZGF0b3MgcGVyZGlkb3MuIA0KDQpgYGB7cn0NCm15ZGF0YSA8LSBkYXRbICwgbWlzc2luZ3M8MTVdDQpuYW1lcyhteWRhdGEpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgRnVuY2nDs24gYGNvbXBsZXRlLmNhc2VzYA0KDQoNCk5vIG9ic3RhbnRlLCBwb2RlbW9zIGRldGVybWluYXIgZWwgbsO6bWVybyBkZSAiY2Fzb3MgY29tcGxldG9zIiBkZW50cm8gZGUgbG9zIGRhdG9zLCBxdWUgc29uIGluZGl2aWR1b3MgcXVlIG5vIHRpZW5lbiBkYXRvcyBmYWx0YW50ZXMgZW4gYWJzb2x1dG8gZW4gZWwgY3Vlc3Rpb25hcmlvLg0KDQoNCmBgYHtyfQ0KZmFsdGFudGUgPC0gY29tcGxldGUuY2FzZXMoZGF0KTt0YWlsKGZhbHRhbnRlKQ0KDQpzdW0oZmFsdGFudGUpDQoNCmBgYA0KDQpMYSBmdW5jacOzbiBgY29tcGxldGUuY2FzZXNgIHByb2R1Y2UgdW4gdmVjdG9yIGRlIHZhbG9yZXMgYm9vbGVhbm9zLCBkb25kZSBgVFJVRWAgaW5kaWNhIHVuIGNhc28gY29tcGxldG8geSBgRkFMU0VgIGluZGljYSB1biBjYXNvIGNvbiB2YWxvcmVzIGZhbHRhbnRlcy4gTGEgc3VtYSBkZSBlc3RlIHZlY3RvciBub3MgZGEgZWwgdG90YWwgZGUgY2Fzb3MgY29tcGxldG9zLCBxdWUgZW4gZXN0ZSBjYXNvIGVzIGByIHN1bShmYWx0YW50ZSlgLiBFbCBwb3JjZW50YWplIGRlIGRhdG9zIGF1c2VudGVzIGVzIGByICgxIC0gKHN1bShmYWx0YW50ZSkvbnJvdyhkYXQpKSkqMTAwYCU6IA0KDQoNCmBgYHtyfQ0KKDEgLSAoc3VtKGZhbHRhbnRlKS9ucm93KGRhdCkpKSoxMDANCg0KYGBgDQoNCg0KQXVucXVlIG5vIGV4aXN0ZSB1biB2YWxvciBleGFjdG8gcXVlIGRldGVybWluZSBxdcOpIGNhbnRpZGFkIGRlIGRhdG9zIGZhbHRhbnRlcyBlcyBhY2VwdGFibGUsIGxhIGltcG9ydGFuY2lhIGRlbCB0YW1hw7FvIGRlIGxhIG11ZXN0cmEgZW4gZWwgYW7DoWxpc2lzIGZhY3RvcmlhbCBlcyBpbm5lZ2FibGUuIFNlZ8O6biBhbGd1bm9zIGV4cGVydG9zLCBzZSByZWNvbWllbmRhIGNvbnRhciBjb24gYWwgbWVub3MgMTAgb2JzZXJ2YWNpb25lcyBwb3IgY2FkYSB2YXJpYWJsZSBlbiBkaWNobyBhbsOhbGlzaXMsIGxvIHF1ZSBzdWdpZXJlIHF1ZSBudWVzdHJvIHRhbWHDsW8gZGUgbXVlc3RyYSBlcyBhcHJvcGlhZG8gcGFyYSBudWVzdHJvcyBvYmpldGl2b3MuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgVmVyaWZpY2FjacOzbiBkZSBzdXB1ZXN0b3MNCg0KIyMjIENvbmRpY2lvbmVzDQoNCkFudGVzIGRlIHByb2NlZGVyIGNvbiBlbCBFRkEsIGRlYmVtb3MgZXZhbHVhciBsYSAiZmFjdG9yaXphYmlsaWRhZCIgZGUgbnVlc3Ryb3MgZGF0b3MuIEVuIGVzdGUgc2VudGlkbywgbGEgaWRlYSBlcyByZXBvbmRlciBsYSBzaWd1aWVudGUgcHJlZ3VudGE6ICDCv2hheSBmYWN0b3JlcyBsYXRlbnRlcyBzaWduaWZpY2F0aXZvcyBxdWUgc2UgcHVlZGFuIGVuY29udHJhciBkZW50cm8gZGUgbG9zIGRhdG9zPyANCg0KDQpQYXJhIGVsbG8sIHBvZGVtb3MgdmVyaWZpY2FyIGRvcyBjb25kaWNpb25lc3M6IA0KICANCiAgMS4gTGEgcHJ1ZWJhIGRlIGVzZmVyaWNpZGFkIGRlIEJhcnRsZXR0Lg0KICANCiAgMi4gTGEgbWVkaWRhIGRlIGFkZWN1YWNpw7NuIG11ZXN0cmFsIGRlIEthaXNlci1NZXllci1PbGtpbi4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFB1ZWJhIGRlIGVzZmVyaWNpZGFkIGRlIEJhcmxldHQNCg0KDQpFc3RhIHBydWViYSBldmFsw7phIHNpIGxhcyB2YXJpYWJsZXMgc2UgY29ycmVsYWNpb25hbiBlbnRyZSBzw60sIGNvbXBhcmFuZG8gbGEgbWF0cml6IGRlIGNvcnJlbGFjacOzbiBvYnNlcnZhZGEgY29uIHVuYSAibWF0cml6IGlkZW50aWRhZCI6ICQkSF8wOlw7IFx0ZXh0e0NvcnJlbGFjacOzbiA9IElkZW50aWRhZH0kJA0KDQpTaSBlc3RlIHRlc3Qgbm8gZXMgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2bywgbm8gc2UgZGViZXLDrWEgYXBsaWNhciB1biBFRkEuDQoNCmBgYHtyfQ0KY29ydGVzdC5iYXJ0bGV0dChkYXQpDQpgYGANCg0KRWwgdGVzdCBkZSBCYXJ0bGV0dCBkaW8gdW4gcmVzdWx0YWRvIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdm8gKCRQJC12YWxvciAkPCAwLjA1JCksIGxvIHF1ZSBpbmRpY2EgcXVlIGxhIG1hdHJpeiBkZSBjb3JyZWxhY2nDs24gb2JzZXJ2YWRhIGVudHJlIGxvcyBlbGVtZW50b3Mgbm8gZXMgdW5hIG1hdHJpeiBkZSBpZGVudGlkYWQuIFNpbiBlbWJhcmdvLCBlc3RvIG5vIGVzIHJlYWxtZW50ZSB1bmEgaW5kaWNhY2nDs24gcGFydGljdWxhcm1lbnRlIHBvZGVyb3NhIGRlIHF1ZSBzZSB0aWVuZSB1biBjb25qdW50byBkZSBkYXRvcyBmYWN0aWJsZXMsIHlhIHF1ZSBsbyDDum5pY28gcXVlIHJlYWxtZW50ZSB0ZSBkaWNlIGVzIHF1ZSAqYWwgbWVub3MgYWxndW5hcyogZGUgbGFzIHZhcmlhYmxlcyBlc3TDoW4gY29ycmVsYWNpb25hZGFzIGVudHJlIHPDrS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBQdWViYSBkZSBLYWlzZXItTWV5ZXItT2xraW4gKEtNTykNCiAgDQogIDEuIEVsIEtNTyBkZXRlcm1pbmEgc2kgbGFzIGNvcnJlbGFjaW9uZXMgcGFyY2lhbGVzIGRlbnRybyBkZSBsb3MgZGF0b3Mgc29uIGNlcmNhbmFzIGEgY2VybywgbG8gcXVlIHN1Z2llcmUgbGEgcHJlc2VuY2lhIGRlIGFsIG1lbm9zIHVuIGZhY3RvciBsYXRlbnRlIGVuIHR1cyB2YXJpYWJsZXMuDQogIA0KICAyLiBFbCDDrW5kaWNlIEtNTyB2YXLDrWEgZW50cmUgMCB5IDEuIA0KICANCiAgMy4gRWwgdmFsb3IgbcOtbmltbyBhY2VwdGFibGUgZXMgMC41MCwgYXVucXVlIGxhIG1heW9yw61hIGRlIGxvcyBhdXRvcmVzIHN1Z2llcmVuIHVuIHZhbG9yIGRlIGFsIG1lbm9zIDAuNjAgYW50ZXMgZGUgcmVhbGl6YXIgdW4gYW7DoWxpc2lzIGZhY3RvcmlhbC4gDQogIA0KICA0LiBMYSBmdW5jacOzbiBLTU8gZW4gZWwgcGFxdWV0ZSBgcHN5Y2hgIHByb3BvcmNpb25hIHVuYSBtZWRpZGEgZ2VuZXJhbCBkZSBhZGVjdWFjacOzbiBkZSBtdWVzdHJlbyAoTVNBLCBjb21vIHNlIGluZGljYSBlbiBsYSBzYWxpZGEpIHkgdW5hIE1TQSBwYXJhIGNhZGEgw610ZW0uIA0KICANCiAgNS4gRW4gdGVvcsOtYSwgc2kgZWwgTVNBIGdsb2JhbCBlcyBtdXkgYmFqbywgc2UgcHVlZGUgZXhhbWluYXIgbGFzIE1TQSBkZSBsb3Mgw610ZW1zIHkgZWxpbWluYXIgYXF1ZWxsb3MgcXVlIHNlYW4gZGVtYXNpYWRvIGJham9zLiBTaW4gZW1iYXJnbywgZXN0byBkZWJlIGhhY2Vyc2UgY29uIGN1aWRhZG8sIGNvbW8gb2N1cnJlIGNvbiBjdWFscXVpZXIgbcOpdG9kbyBlbXDDrXJpY28gZGUgc2VsZWNjacOzbiBkZSDDrXRlbXMuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgVmFsb3JlcyBkZWwgS01PDQoNCkxhIG1lZGlkYSBwdWVkZSBzZXIgaW50ZXJwcmV0YWRhIGNvbiBsYXMgc2lndWllbnRlcyBkaXJlY3RyaWNlczoNCiAgDQogICsgU2kgJEtNTyBcZ2VxIDAuOCQ6ICBwZXJmZWN0byBwYXJhIHJlYWxpemFyIHVuIGFuw6FsaXNpcyBmYWN0b3JpYWwgKEFGKS4NCiAgDQogICsgU2kgJEtNTyQgZXN0w6EgZW50cmUgMC42IGEgMC43OiAgYWRlY3VhZG8uIEhheSBjb3JyZWxhY2nDs24geSwgcG9yIGxvIHRhbnRvLCBlbCBBRiBlcyBhcHJvcGlhZG8uDQogIA0KICArIFNpICRLTU8kIGVzdMOhIGVudHJlIDAuNCBhIDAuNTogIGFjZXB0YWJsZS4gU2UgcHVlZGUgaW1wbGVtZW50YXIgdW4gQUYuIFNpbiBlbWJhcmdvIHNlIHN1Z2llcmUgdmVyaWZpY2FyIGVsIGVzdGFkbyBkZSBsYXMgdmFyaWFibGVzLg0KICANCiAgKyAkS01PJCBtZW5vcmVzIGEgMC40OiAgbm8gc2UgcmVjb21pZW5kYSB1biBBRi4NCg0KYGBge3IsIGVjaG89RkFMU0V9DQprbW8gPC0gS01PKGRhdCkNCmBgYA0KDQpgYGB7cn0NCktNTyhkYXQpDQpgYGANCkVsIMOtbmRpY2UgS01PIGdlbmVyYWwgZGUgbnVlc3Ryb3MgZGF0b3MgZXMgZGUgYHIgcm91bmQoa21vJE1TQSwgMylgLCBsbyBjdWFsIGVzIG11eSBidWVuby4gRXN0byBpbmRpY2EgcXVlIHBvZGVtb3MgYXBsaWNhciBlbCBFRkEuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBWYXJpYWJsZXMgY29uIEtNTyA+IDAuNQ0KDQpTZSBwdWVkZW4gb2J0ZW5lciBhc8OtOiANCg0KYGBge3J9DQpteWRhdCA8LSBkYXRbLCBLTU8oZGF0KSRNU0FpPjAuNTBdIA0KDQpuYW1lcyhteWRhdCkNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgTsO6bWVybyBkZSBmYWN0b3Jlcw0KDQpMYSBwcmltZXJhIGRlY2lzacOzbiBxdWUgZGViZW1vcyB0b21hciB0aWVuZSBxdWUgdmVyIGNvbiBlbCBuw7ptZXJvIGRlIGZhY3RvcmVzIHF1ZSBuZWNlc2l0YXJlbW9zIGV4dHJhZXIgcGFyYSBsb2dyYXIgbGEgZXN0cnVjdHVyYSBkZSBmYWN0b3JlcyBtw6FzIHBhcnNpbW9uaW9zYSB5IGHDum4gaW50ZXJwcmV0YWJsZS4gUmVjb3JkZW1vcyBxdWUgaGF5IHZhcmlvcyBtw6l0b2RvcyBxdWUgcG9kcsOtYW1vcyB1c2FyLCBwZXJvIGxvcyBkb3MgbcOhcyBjb23Dum5tZW50ZSBlbXBsZWFkb3Mgc29uIGVsIGBzY3JlZSBwbG90YCAoZ3LDoWZpY28gZGUgY29kbyAgbyBkZSBzZWRpbWVudGFjacOzbiBvIGRlIGVzY29tYnJvKSB5IGVsIGBwYXJhbGxlbCBhbmFseXNpc2AgKGFuw6FsaXNpcyBwYXJhbGVsbykuIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgU2NyZWUgcGxvdDogRkEgeSBQQw0KDQpDb3NpZGVyZW1vcyBlbCBgc2NyZWUgcGxvdGAgcGFyYSBsb3MgZGF0b3MgZGUgbnVlc3RybyBlamVtcGxvLiANCg0KYGBge3J9DQpzY3JlZShkYXQpDQpgYGANCg0KMS4gRWwgbcOpdG9kbyBkZWwgYHNjcmVlIHBsb3RgIGltcGxpY2EgdHJhemFyIHVuYSBsw61uZWEgcmVjdGEgYSB0cmF2w6lzIGRlIGxvcyB2YWxvcmVzIHByb3Bpb3MgcmVwcmVzZW50YWRvcywgZW1wZXphbmRvIHBvciBlbCBtw6FzIGdyYW5kZS4gRWwgw7psdGltbyBwdW50byBxdWUgdG9jYSBlc3RhIGzDrW5lYSByZXByZXNlbnRhIGVsIMO6bHRpbW8gZmFjdG9yIHF1ZSBleHRyYWVzLCBjb24gbGEgaWRlYSBkZSBxdWUgbcOhcyBhbGzDoSBkZSBlc3RlIHB1bnRvLCBsYSBjYW50aWRhZCBhZGljaW9uYWwgZGUgdmFyaWFuemEgZXhwbGljYWRhIG5vIGVzIHNpZ25pZmljYXRpdmEuIA0KDQoyLiBMYSBwYWxhYnJhIGBzY3JlZWAgKHRyYWR1Y2lkbzogImVzY29tYnJvIikgc2UgcmVmaWVyZSBhIGxhcyBwaWVkcmFzIHN1ZWx0YXMgYWxyZWRlZG9yIGRlIGxhIGJhc2UgZGUgbGEgbW9udGHDsWEuIFVuIGBzY3JlZSBwbG90YCBidXNjYSBheXVkYXIgYSBkaWZlcmVuY2lhciBlbnRyZSBsb3MgcHVudG9zIHF1ZSByZXByZXNlbnRhbiAibW9udGHDsWEiIHkgbG9zIHF1ZSByZXByZXNlbnRhbiAiZXNjb21icm8iLiANCg0KMy4gU2luIGltcG9ydGFyIHNpIHNlIHVzYSB1bmEgZXh0cmFjY2nDs24gZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgbyBkZSBlamVzIHByaW5jaXBhbGVzLCBoYXkgdW4gcHJpbWVyIGZhY3RvciBtdXkgZ3JhbmRlIGVuIGVzdG9zIGRhdG9zLiANCg0KNC4gU2kgc2UgdHJhemEgbGEgbMOtbmVhIHJlY3RhIGRlc2RlIGVzdGUgcHVudG8sIHByb2JhYmxlbWVudGUgY29uY2x1aXLDrWFtb3MgcXVlIGhheSBzb2xvIHRyZXMgZmFjdG9yZXMgZW4gZWwgY29uanVudG8gZGUgZGF0b3MuIA0KDQo1LiBTaSwgZW4gY2FtYmlvLCBzZSBjb21pZW56YSBsYSBsw61uZWEgZW4gZWwgc2VndW5kbyBwdW50byBkZWwgYHNjcmVlIHBsb3RgLCBwcm9iYWJsZW1lbnRlIGNvbmNsdWlyw61hbW9zIHF1ZSBoYXkgY2luY28gZmFjdG9yZXMgZW4gbG9zIGRhdG9zLiANCg0KNi4gRXN0YSDDumx0aW1hIGludGVycHJldGFjacOzbiBwcm9iYWJsZW1lbnRlIHNlYSBtw6FzIGNlcmNhbmEgYSBsYSB2ZXJkYWQuIFBlcm8sIHNpIHNvbG8gc2UgY29uc2lkZXJhIGVzdGEgZXZpZGVuY2lhIGFsIGRldGVybWluYXIgZWwgbsO6bWVybyBkZSBmYWN0b3JlcyBhIGV4dHJhZXIsIHNlcsOtYSBuZWNlc2FyaW8gZXhhbWluYXIgYW1iYXMgc29sdWNpb25lcyBkZSBmYWN0b3Jlcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFNjcmVlIHBsb3Q6IHNvbG8gRkENCg0KDQpTaSBzb2xvIHF1aWVybyBxdWUgbXVlc3RyZSBlbCBFRkE6IA0KDQpgYGB7cn0NCnNjcmVlKGRhdCwgcGM9RkFMU0UpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBQYXJhbGxlbCBBbmFseXNpczogRkEgeSBQQw0KDQoNClVuYSBtZWpvciBtYW5lcmEgZGUgZXZhbHVhciBlbCBgc2NyZWUgcGxvdGAgZXMgbWVkaWFudGUgdW4gYHBhcmFsbGVsIGFuYWx5c2lzYCAoYW7DoWxpc2lzIHBhcmFsZWxvKS4gQXBhcnRlIGRlIGdyYWZpY2FyIGxvcyBhdXRvdmFsb3JlcyBkZSBudWVzdHJvIEVGQSAoeWEgc2VhIGJhc2FkbyBlbiBsYSBleHRyYWNjacOzbiBkZSBlamVzIHByaW5jaXBhbGVzIG8gY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMpLCBlbCBgcGFyYWxsZWwgYW5hbHlzaXNgIGltcGxpY2E6DQogIA0KICAxLiBHZW5lcmFyIG1hdHJpY2VzIGRlIGNvcnJlbGFjacOzbiBhbGVhdG9yaWFzLg0KICANCiAgMi4gVXRpbGl6YXJsYXMgY29tbyBkYXRvcyBlbiBlbCBFRkEuIA0KICANCiAgMy4gY29tcGFyYXIgbG9zIGF1dG92YWxvcmVzIHJlc3VsdGFudGVzIGNvbiBsb3MgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIG9ic2VydmFkb3MuIA0KDQpMYSBpZGVhIGRldHLDoXMgZGUgZXN0ZSBtw6l0b2RvIGVzIHF1ZSBsb3MgYXV0b3ZhbG9yZXMgb2JzZXJ2YWRvcyBxdWUgc29uIG3DoXMgYWx0b3MgcXVlIHN1cyBlcXVpdmFsZW50ZXMgYWxlYXRvcmlvcyBzb24gbcOhcyBwcm9wZW5zb3MgYSBzZXIgImZhY3RvcmVzIHNpZ25pZmljYXRpdm9zIiBlbiBjb21wYXJhY2nDs24gY29uIGxvcyBhdXRvdmFsb3JlcyBvYnNlcnZhZG9zIHF1ZSBzb24gbcOhcyBiYWpvcyBxdWUgc3VzIGVxdWl2YWxlbnRlcyBhbGVhdG9yaW9zLg0KDQoNCmBgYHtyfQ0KZmEucGFyYWxsZWwoZGF0KQ0KDQpgYGANCg0KQWwgcmV2aXNhciBsb3MgZ3LDoWZpY29zIGRlIGBwYXJhbGxlbCBhbmFseXNpc2AgZGUgbG9zIGBzY3JlZSBwbG90c2AsIGhheSBkb3Mgw6FyZWFzIGRlIGludGVyw6lzIGRlcGVuZGllbmRvIGRlbCB0aXBvIGRlIGFuw6FsaXNpcyBmYWN0b3JpYWwgcXVlIHNlIHF1aWVyYSByZWFsaXphci4gDQogIA0KICAxLiBMYXMgZG9zIGzDrW5lYXMgYXp1bGVzIG11ZXN0cmFuIGxvcyBhdXRvdmFsb3JlcyBvYnNlcnZhZG9zLCBxdWUgZGViZXLDrWFuIHNlciBzaW1pbGFyZXMgYSBsYXMgZ3LDoWZpY2FzIGRlIGVzY2FsYSBnZW5lcmFkYXMgcG9yIGxhIGZ1bmNpw7NuIGRlIGVzY2FsYS4gTGFzIGzDrW5lYXMgcm9qYXMgcHVudGVhZGFzIHJlcHJlc2VudGFuIGxvcyBhdXRvdmFsb3JlcyBhbGVhdG9yaW9zIG8gbGEgbMOtbmVhIGRlIGRhdG9zIHNpbXVsYWRvcy4gDQogIA0KICAyLiBDYWRhIHB1bnRvIGVuIGxhIGzDrW5lYSBhenVsIHF1ZSBlc3TDqSBwb3IgZW5jaW1hIGRlIGxhIGzDrW5lYSBkZSBkYXRvcyBzaW11bGFkb3MgY29ycmVzcG9uZGllbnRlIGluZGljYSB1biBmYWN0b3IgbyBjb21wb25lbnRlIGEgZXh0cmFlci4gDQogIA0KMy4gRW4gZXN0ZSBhbsOhbGlzaXMsIHNlIG9ic2VydmEgcXVlIDYgZmFjdG9yZXMgZW4gZWwgYHBhcmFsbGVsIGFuYWx5c2lzYCBkZSAiRkEiIHN1cGVyYW4gbGEgbMOtbmVhIGRlIGRhdG9zIHNpbXVsYWRvcyBjb3JyZXNwb25kaWVudGUsIGFsIGlndWFsIHF1ZSA2IGNvbXBvbmVudGVzIGVuIGVsIGBwYXJhbGxlbCBhbmFseXNpc2AgZGUgIlBDIi4NCg0KNC4gU2luIGVtYmFyZ28sIGVuIG51ZXN0cm8gY2FzbywgZWwgw7psdGltbyBmYWN0b3IvY29tcG9uZW50ZSBlc3TDoSBtdXkgcHLDs3hpbW8gYSBsYSBsw61uZWEsIHRhbnRvIHBhcmEgbGEgZXh0cmFjY2nDs24gZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgY29tbyBwYXJhIGxhIGV4dHJhY2Npw7NuIGRlIGVqZXMgcHJpbmNpcGFsZXMuIFBvciBlbmRlLCBzZXLDrWEgY29udmVuaWVudGUgY29tcGFyYXIgbGFzIHNvbHVjaW9uZXMgZGUgNiBmYWN0b3JlcyB5IDUgZmFjdG9yZXMgcGFyYSBkZXRlcm1pbmFyIGN1w6FsIGVzIG3DoXMgaW50ZXJwcmV0YWJsZS4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFBhcmFsbGVsIEFuYWx5c2lzOiBzb2xvIEZBDQoNCg0KYGBge3J9DQpmYS5wYXJhbGxlbChkYXQsIGZhPSJmYSIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRUZBIGNvbiA2IGZhY3RvcmVzDQoNCiMjIyBMYSBmdW5jacOzbiBgZmFgIGNvbiA2IGZhY3RvcmVzDQoNCkxhIGZ1bmNpw7NuIGBmYWAgdXRpbGl6YSBjaWVydG9zIHBhcsOhbWV0cm9zIGFsIHNlciBpbnZvY2FkYToNCiAgDQogIDEuIFNlIHByb3BvcmNpb25hbiBsYXMgdmFyaWFibGVzIHF1ZSBzZSB1c2Fyw6FuIGVuIGVsIGFuw6FsaXNpcyBmYWN0b3JpYWwgKG9iamV0byBgZGF0YCkuDQogIA0KICAyLiBTZSBlc3BlY2lmaWNhIGVsIG7Dum1lcm8gZGUgZmFjdG9yZXMgcXVlIHNlIGV4dHJhZXLDoW4gKGA2YCkuDQogIA0KICAzLiBTZSBlbGlnZSBlbCB0aXBvIGRlIGFuw6FsaXNpcyBmYWN0b3JpYWwgYSBlbXBsZWFyIChlbiBlc3RlIGNhc28sIGBwYWAgZXMgZWwgZmFjdG9yaW5nIGRlbCBlamUgcHJpbmNpcGFsKS4NCiAgDQogIDQuIFNlIGRldGVybWluYSBlbCBuw7ptZXJvIGRlIGl0ZXJhY2lvbmVzIG8gaW50ZW50b3MgcGFyYSBlbmNvbnRyYXIgbGEgc29sdWNpw7NuICLDs3B0aW1hIiAoNTAgZXMgZWwgdmFsb3IgcG9yIGRlZmVjdG8sIHBlcm8gbG8gaGVtb3MgY2FtYmlhZG8gYSAxMDApLg0KICANCiAgNS4gU2Ugc2VsZWNjaW9uYSBlbCB0aXBvIGRlIHJvdGFjacOzbiBhIGFwbGljYXIgKGNvbWVuemFyZW1vcyBjb24gYG9ibGltaW5gKS4NCiAgDQoNCmBgYHtyfQ0KTmZhYyA8LSA2ICAjRXN0ZSBlcyBlbCBuw7ptZXJvIGRlIGZhY3RvcmVzDQoNCnJlcy5lZmE2IDwtIHBzeWNoOjpmYShkYXQsDQogICAgICAgICAgICAgIG5mYWN0b3JzID0gTmZhYywNCiAgICAgICAgICAgICAgZm09InBhIiwNCiAgICAgICAgICAgICAgbWF4Lml0ZXIgPSAxMDAsDQogICAgICAgICAgICAgIHJvdGF0ZSA9ICJvYmxpbWluIikNCnJlcy5lZmE2DQpgYGANCkxhIG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzIGluZGljYSBxdWUgbGFzIGNvcnJlbGFjaW9uZXMgc29uIGJhc3RhbnRlIGJhamFzLiBQb3IgdGFudG8sIGVzdGFyw61hIGp1c3RpZmljYWRvIHBhc2FyIGEgcHJvYmFyIGNvbiBvdHJhIHJvdGFjacOzbiBvIGRpc21pbnVpciBlbCBuw7ptZXJvIGRlIGZhY3RvcmVzLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBgZmFgIGNvbiA2IGZhY3RvcmVzOiBvdHJvcyBhcmd1bWVudG9zDQoNCkEgY29udGludWFjacOzbiwgb3RyYSBmb3JtYSBkZSBwcmVzZW50YXIgbG9zIHJlc3VsdGFkb3MuIEVuIGVsIGPDs2RpZ28gZGUgYWJham86IA0KICANCiAgKyBgZGlnaXRzPTJgOiBFc3RlIGFyZ3VtZW50byBlc3BlY2lmaWNhIGVsIG7Dum1lcm8gZGUgZMOtZ2l0b3MgcXVlIHNlIG1vc3RyYXLDoW4gZGVzcHXDqXMgZGVsIHB1bnRvIGRlY2ltYWwuIEVuIGVzdGUgY2Fzbywgc2UgZXN0YWJsZWNlIGVuIDIsIGxvIHF1ZSBzaWduaWZpY2EgcXVlIGxvcyB2YWxvcmVzIG51bcOpcmljb3Mgc2UgbW9zdHJhcsOhbiBjb24gZG9zIGTDrWdpdG9zIGRlc3B1w6lzIGRlbCBwdW50byBkZWNpbWFsLg0KICANCiAgKyBgY3V0b2ZmPTAuM2A6IEVzdGUgYXJndW1lbnRvIGVzIHVuIHZhbG9yIGRlIGNvcnRlIHBhcmEgbG9zIHJlc3VsdGFkb3MgbW9zdHJhZG9zLiBQb3IgZWplbXBsbywgc2kgaGF5IHZhbG9yZXMgcG9yIGRlYmFqbyBkZSAwLjMsIHB1ZWRlbiBubyBtb3N0cmFyc2UgZW4gbGEgaW1wcmVzacOzbi4NCiAgDQogICsgYHNvcnQ9VFJVRWA6IEVzdGUgYXJndW1lbnRvIGRldGVybWluYSBzaSBsb3MgcmVzdWx0YWRvcyBkZWJlbiBvcmRlbmFyc2UgYW50ZXMgZGUgaW1wcmltaXJzZS4gQ3VhbmRvIHNlIGVzdGFibGVjZSBlbiBgVFJVRWAsIGxvcyByZXN1bHRhZG9zIHNlIG9yZGVuYXLDoW4gZGUgbWFuZXJhIHByZWRldGVybWluYWRhIGFudGVzIGRlIGxhIGltcHJlc2nDs24uDQoNCmBgYHtyfQ0KcHJpbnQocmVzLmVmYTYsIGRpZ2l0cz0yLCBjdXRvZmY9MC4zLCBzb3J0PVRSVUUpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgUGxvdCBGYWN0b3IgMSBieSBGYWN0b3IgMg0KDQpgYGB7cn0NCmxvYWQgPC0gcmVzLmVmYTYkbG9hZGluZ3NbLDE6Ml0NCnBsb3QobG9hZCx0eXBlPSJuIikgIyBjb25maWd1cmFyIGVsIHBsb3QNCnRleHQobG9hZCxsYWJlbHM9bmFtZXMoZGF0KSxjZXg9LjcpDQpgYGANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBMYSBmdW5jacOzbiBgZmEuZGlhZ3JhbWANCg0KDQpTZSBwdWVkZSB2ZXIgcsOhcGlkYW1lbnRlIHR1IHNvbHVjacOzbiBkZSBmYWN0b3JlcyByb3RhZG9zIHkgZGVjaWRpciBzaSBlcyBjb21wcmVuc2libGUgdXRpbGl6YW5kbyBsYSBmdW5jacOzbiBgZmEuZGlhZ3JhbWAuDQoNCmBgYHtyfQ0KZmEuZGlhZ3JhbShyZXMuZWZhNikNCmBgYA0KQ29tbyBzZSBwdWVkZSB2ZXIgYXF1w60sIGVsIHNleHRvIGZhY3RvciB0aWVuZSBzb2xvIHVuYSBjYXJnYSB2YXJpYWJsZSBlbiDDqWw6IGVsIHNlZ3VuZG8gw610ZW0gZGUgbGEgZXNjYWxhIGRlIGFwZXJ0dXJhIGEgYG9wZW5uZXNzYCAoZXhwZXJpZW5jaWEpLiBQb3IgbG8gdGFudG8sIGVzdG8gcHJvYmFibGVtZW50ZSByZXByZXNlbnRhIHVuYSBzb2JyZWV4dHJhY2Npw7NuLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgYGZhLmRpYWdyYW1gOiBtw6FzIG9wY2lvbmVzDQoNClBhcmEgc2ltcGxpZmljYXIgYcO6biBtw6FzIGxhIGludGVycHJldGFjacOzbiwgcHVlZGUgcmVkdWNpciBlbCBuw7ptZXJvIGRlIGZhY3RvcmVzLg0KDQpgYGB7cn0NCmxvYWRzMiA8LSByZXMuZWZhNiRsb2FkaW5nc1ssMToyXQ0KZmEuZGlhZ3JhbShsb2FkczIpDQoNCmxvYWRzMyA8LSByZXMuZWZhNiRsb2FkaW5nc1ssMzo0XQ0KZmEuZGlhZ3JhbShsb2FkczMpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCiMgRXZhbHVhbmRvIGxvIGVuY29udHJhZG8NCg0KRGUgbG9zIHJlc3VsdGFkb3MgYW50ZXJpb3JlcywgbmVjZXNpdGFyZW1vcyBjb25zaWRlcmFyIGFsZ3Vub3MgYXNwZWN0b3MuIA0KDQoqKlByaW1lcm8uICDCv0xhIHJvdGFjacOzbiBxdWUgc2VsZWNjaW9uYXN0ZSBmdWUgYXByb3BpYWRhPyoqIA0KDQoqU2kgdXRpbGl6YW1vcyB1bmEgcm90YWNpw7NuIG9ibGljdWE6ICoNCg0KICArIMK/SGF5IHN1ZmljaWVudGVzIGNvcnJlbGFjaW9uZXMgYmFzdGFudGUgc3VzdGFuY2lhbGVzIChyPjAuMzApIHBhcmEganVzdGlmaWNhciBsYSBzdXBvc2ljacOzbiBkZSBxdWUgbG9zIGZhY3RvcmVzIGVzdMOhbiBpbnRlcnJlbGFjaW9uYWRvcz8gDQoNCiAgKyBEZSBsbyBjb250cmFyaW8sIHBvZHLDrWFtb3MgY29uc2lkZXJhciBjYW1iaWFyIGEgdW5hIHJvdGFjacOzbiBvcnRvZ29uYWwuIA0KDQoqU2kgdXNhc3RlIHVuYSByb3RhY2nDs24gb3J0b2dvbmFsOioNCiAgDQogICsgwr9MYXMgdmFyaWFibGVzIHNlIGNhcmdhbiBlbiBsb3MgZmFjdG9yZXMgZGUgbWFuZXJhIGxpbXBpYT8gDQogIA0KICArIFNpIG5vIGVzIGFzw60sIHBvZHLDrWFzIGNvbnNpZGVyYXIgY2FtYmlhciBhIGxhIHJvdGFjacOzbiBvYmxpY3VhLiDCv0xvcyBmYWN0b3JlcyBsdWNlbiBlc3RhYmxlcyB5IGRpc3RpbnRvcz8NCg0KDQoqKlNlZ3VuZG8uIMK/U2UgY2FyZ2FuIHRvZGFzIGxhcyB2YXJpYWJsZXMgZW4gbG9zIGZhY3RvcmVzIGxvIHN1ZmljaWVudGU/ICh8Y2FyZ2FzIGZhY3RvcmlhbGVzfCA+IDAuMzApICoqDQogIA0KICArIFNpIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMgbm8gc29uIHN1ZmljaWVudGVzLCBlcyBwb3NpYmxlIHF1ZSBuZWNlc2l0ZXMgcHJvYmFyIGVsIG3DqXRvZG8gZGUgZXh0cmFjY2nDs24gZGUgZmFjdG9yZXMsIHVuIG7Dum1lcm8gZGlmZXJlbnRlIGRlIGZhY3RvcmVzIG8gZGVjaWRpciBzaSByZXRlbmVyIGxhcyB2YXJpYWJsZXMgcXVlIG5vIHNlIGNhcmdhbiBlbiB1biBmYWN0b3IuIA0KDQoqKlRlcmNlcm8uIE7Dum1lcm8gZGUgZmFjdG9yZXMuKioNCiAgDQogICsgwr9UaWVuZW4gdG9kb3MgbG9zIGZhY3RvcmVzIGFsIG1lbm9zIHRyZXMgLSBvLCBtZWpvciBhw7puLCBjdWF0cm8gLSBvIG3DoXMgdmFyaWFibGVzIGNhcmdhbmRvIGVuIGVsbG9zPyANCiAgDQogICsgRGUgbG8gY29udHJhcmlvLCBlcyBwb3NpYmxlIHF1ZSBuZWNlc2l0ZXMgZGlzbWludWlyIGVsIG7Dum1lcm8gZGUgZmFjdG9yZXMuIA0KDQoqKkN1YXJ0by4gwr9DYXJnYXMgY3J1emFkYXM/KioNCiAgDQogICsgwr9IYXkgbXVjaGFzIGNhcmdhcyBjcnV6YWRhcyAodmFyaWFibGVzIHF1ZSBzZSBjYXJnYW4gZW4gbcOhcyBkZSB1biBmYWN0b3IgY29uIHZhbG9yZXMgcXVlIGVzdMOhbiBkZW50cm8gZGUgMC4wNSB1bm8gZGVsIG90cm8pPyANCiAgDQogICsgRXN0byBwdWVkZSBzZXIgaW5ldml0YWJsZS4gUGVybywgZW4gZ2VuZXJhbCwgbGEgbWVqb3Igc29sdWNpw7NuIG1pbmltaXphcsOhIGVsIG7Dum1lcm8gZGUgY2FyZ2FzIGNydXphZGFzLiANCiAgDQoNCioqUXVpbnRvLiDCv0ZhY3RvcmVzIGludGVycHJldGFibGVzPyoqDQogIA0KICArIMK/U29uIGludGVycHJldGFibGVzIGNhZGEgdW5vIGRlIGxvcyBmYWN0b3Jlcz8gDQogIA0KICArIMK/TGFzIHZhcmlhYmxlcyBxdWUgc2UgY2FyZ2FuIGVuIGNhZGEgZmFjdG9yIHRpZW5lbiBhbCBtZW5vcyB1biB0ZW1hIGJhc3RhbnRlIGNsYXJvIChiYXNhZG8gZW4gbGFzIGRlZmluaWNpb25lcyBkZSBsYXMgdmFyaWFibGVzKT8gRW4gw7psdGltYSBpbnN0YW5jaWEsIGVzdG8gZXMgbG8gcXVlIGVzdMOhcyB0cmF0YW5kbyBkZSBwcm9kdWNpci4NCiAgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEVGQSBjb24gNSBmYWN0b3Jlcw0KDQoNCiMjIyBMYSBmdW5jacOzbiBgZmFgIGNvbiA1IGZhY3RvcmVzDQoNClZlYW1vcyBhaG9yYSBsYSBzb2x1Y2nDs24gZGUgY2luY28gZmFjdG9yZXMgeSBzdSBncsOhZmljby4NCg0KYGBge3J9DQpyZXMuZWZhNSA8LSBwc3ljaDo6ZmEoZGF0LA0KICAgICAgICAgICAgICBuZmFjdG9ycyA9IDUsDQogICAgICAgICAgICAgIGZtPSJwYSIsDQogICAgICAgICAgICAgIG1heC5pdGVyID0gMTAwLA0KICAgICAgICAgICAgICByb3RhdGUgPSAib2JsaW1pbiIpDQpyZXMuZWZhNQ0KYGBgDQoNCkVsIGdyw6FmaWNvLg0KDQpgYGB7cn0NCmZhLmRpYWdyYW0ocmVzLmVmYTUpDQpgYGANCkxhIHNvbHVjacOzbiBjb24gY2luY28gZmFjdG9yZXMgZXMgbcOhcyBmw6FjaWwgZGUgZW50ZW5kZXIsIGRlIGhlY2hvLCBwYXJlY2UgcmVwcm9kdWNpciBiaWVuIGxhIGVzdHJ1Y3R1cmEgZGUgZmFjdG9yZXMgZXNwZXJhZGEuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyBDb211bmFsaWRhZGVzDQoNCkxhIGNvbXVuYWxpZGFkIGRlIGNhZGEgdmFyaWFibGUgcmVwcmVzZW50YSBlbCBwb3JjZW50YWplIGRlIHZhcmlhYmlsaWRhZCBxdWUgbG9zIGZhY3RvcmVzIHJldGVuaWRvcyBwdWVkZW4gZXhwbGljYXIuIEVzIHByZWZlcmlibGUgcXVlIGVzdG9zIGZhY3RvcmVzIHJldGVuaWRvcyBleHBsaXF1ZW4gdW5hIG1heW9yIHByb3BvcmNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBlbiBjYWRhIHZhcmlhYmxlLg0KDQoNCmBgYHtyfQ0KcmVzLmVmYTUkY29tbXVuYWxpdHkNCmBgYA0KDQpFbiBvdHJhcyBwYWxhYnJhcywgbGEgcHJpbmNpcGFsIGRpc3RpbmNpw7NuIGVudHJlIGPDs21vIHNlIHJlYWxpemEgZWwgYW7DoWxpc2lzIGZhY3RvcmlhbCB5IGVsIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyB0aWVuZSBxdWUgdmVyIGNvbiBsYSBmb3JtYSBkZSBsYXMgcmVzcGVjdGl2YXMgbWF0cmljZXMgZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzIGVudHJlIGxvcyBkYXRvcyB5IGxhcyBjb21wb25lbnRlcyAobyBmYWN0b3JlcykuICAgDQoNCjEuIEVuIEVGQSwgZXN0YSBtYXRyaXogdmllbmUgZGFkYSBwb3I6ICANCiQkQ292IChYLCBGXlQpIFw7PVw7ICAgXExhbWJkYSQkDQoNCjIuIEVuIFBDQSwgZXN0YSBtYXRyaXogdGllbmUgZWxlbWVudG9zIHF1ZSBkZXBlbmRlIGRlIGxhcyBjb29yZGVuYWRhcyBkZSBsb3MgYXV0b3ZhbG9yZXMgeSBhdXRvdmVjdG9yZXM6IA0KJCRDb3YgKFhfaywgRl9qKSBcOz1cOyAgIGFfe2prfSBcbGFtYmRhX2okJA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIEF1dG92YWxvcmVzDQoNCkxvcyBhdXRvdmFsb3JlcyBkZXJpdmFkb3MgZW4gbGEgc29sdWNpw7NuIGRlIGZhY3RvcmVzIGV4dHJhw61kYSBzZSBlbmN1ZW50cmFuIGd1YXJkYWRvcyBlbiBgZS52YWx1ZXNgLiBFc3RvcyBzb24gbG9zIHZhbG9yZXMgY2FyYWN0ZXLDrXN0aWNvcyBxdWUgc2UgbW9zdHJhcm9uIGVuIGxvcyBgc2NyZWUgcGxvdHNgIHF1ZSBleGFtaW5hbW9zIGFsIGluaWNpbyBkZSBlc3RlIHByb2NlZGltaWVudG8uDQoNCg0KYGBge3J9DQpyZXMuZWZhNSRlLnZhbHVlc1sxOjEwXQ0KYGBgDQpTaSBzZSBxdWllcmUgb2J0ZW5lciBsb3MgYXV0b3ZhbG9yZXMgZGVsYSBzb2x1Y2nDs24gcm90YWRhLCBzZSBhY2NlZGUgYHZhbHVlc2AuDQoNCmBgYHtyfQ0KcmVzLmVmYTUkdmFsdWVzWzE6MTBdDQpgYGANCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMgUG9yY2VudGFqZSBkZSB2YXJpYW56YSBleHBsaWNhZGENCg0KDQpQb2RlbW9zIGVtcGxlYXIgbG9zIHZhbG9yZXMgcHJvcGlvcyBwYXJhIGRldGVybWluYXIgZWwgcG9yY2VudGFqZSBkZSB2YXJpYWJpbGlkYWQgZXhwbGljYWRhIHBvciBjYWRhIGZhY3Rvci4gRGFkbyBxdWUgbGEgc3VtYSBtw6F4aW1hIGRlIGVzdG9zIHZhbG9yZXMgc2llbXByZSBzZXLDoSBpZ3VhbCBhbCBuw7ptZXJvIHRvdGFsIGRlIHZhcmlhYmxlcyBlbiBlbCBhbsOhbGlzaXMsIHBvZGVtb3MgY2FsY3VsYXIgZWwgcG9yY2VudGFqZSBkaXZpZGllbmRvIGNhZGEgdmFsb3IgcHJvcGlvIHBvciBlbCBuw7ptZXJvIHRvdGFsIGRlIHZhcmlhYmxlcy4gRW4gbnVlc3RybyBjYXNvLCBxdWUgZXMgYHIgbGVuZ3RoKHJlcy5lZmE1JGUudmFsdWVzKWAuDQoNCmBgYHtyfQ0KdG90YWwgPC0gbGVuZ3RoKHJlcy5lZmE1JGUudmFsdWVzKQ0KMTAwKnJlcy5lZmE1JGUudmFsdWVzWzE6MTBdL3RvdGFsDQpgYGANCg0KDQpQYXJhIG9idGVuZXIgZWwgcG9yY2VudGFqZSBkZSB2YXJpYWJpbGlkYWQgZXhwbGljYWRhIHBvciBsYSBzb2x1Y2nDs24gcm90YWRhLCBzZSB1c2Fyw61hbiBsb3MgdmFsb3JlcyBwcm9waW9zIGFsbWFjZW5hZG9zIGVuIGB2YWx1ZXNgIGVuIGx1Z2FyIGRlIGBlLnZhbHVlc2AuDQoNCg0KYGBge3J9DQp0b3RhbHJvdCA8LSBsZW5ndGgocmVzLmVmYTUkdmFsdWVzKQ0KMTAwKnJlcy5lZmE1JHZhbHVlc1sxOjEwXS90b3RhbHJvdA0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMgU29sdWNpw7NuIHJvdGFkYQ0KDQpZYSBoZW1vcyByZXZpc2FkbyBsb3MgZWxlbWVudG9zIGNvbiBsYXMgY2FyZ2FzIG3DoXMgYWx0YXMgcGFyYSBjYWRhIGZhY3RvciAodXNhbmRvIGBmYS5kaWFncmFtYCksIHBlcm8gZXN0byBzb2xvIG5vcyBkaWNlIGN1w6FsIGVzIGxhIGNhcmdhIG3DoXMgZ3JhbmRlIHBhcmEgY2FkYSBlbGVtZW50by4gU2luIGVtYmFyZ28sIGNhZGEgZWxlbWVudG8gc2UgY2FyZ2Fyw6EgZW4gY2FkYSB1bm8gZGUgbG9zIGZhY3RvcmVzIGVuIG1heW9yIG8gbWVub3IgbWVkaWRhLCB5IGV2ZW50dWFsbWVudGUgcXVlcnJlbW9zIHZlciBsYSBtYXRyaXogY29tcGxldGEgZGUgY2FyZ2FzIGZhY3RvcmlhbGVzLiBMYSBtYXRyaXogZGUgY2FyZ2FzIGZhY3RvcmlhbGVzIG5vcyBtdWVzdHJhIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMgcGFyYSBjYWRhIHZhcmlhYmxlLCBkZXNwdcOpcyBkZSBoYWJlciBzaWRvIHJvdGFkYXMgYSB1bmEgImVzdHJ1Y3R1cmEgc2ltcGxlIi4gQsOhc2ljYW1lbnRlLCBlc3RhbW9zIGFwcm92ZWNoYW5kbyBlbCBoZWNobyBkZSBxdWUgaGF5IHZhcmlhcyBzb2x1Y2lvbmVzIGRlIGZhY3RvcmVzIHF1ZSBzb24gaWd1YWxtZW50ZSBhY2VwdGFibGVzIGEgbGEgc29sdWNpw7NuICLDs3B0aW1hIiBxdWUgc2UgZW5jb250csOzIGRlbnRybyBkZSBudWVzdHJhIGV4dHJhY2Npw7NuIGluaWNpYWwgKGVzIGRlY2lyLCBxdWUgc29uIG1hdGVtw6F0aWNhbWVudGUgZXF1aXZhbGVudGVzKSwgeSByb3RhbmRvIGxvcyBmYWN0b3JlcyBwYXJhIHF1ZSBzZWFuIG3DoXMgZsOhY2lsbWVudGUgaW50ZXJwcmV0YWRvcy4gRGViaWRvIGEgcXVlIGhlbW9zIHV0aWxpemFkbyB1bmEgcm90YWNpw7NuIGRlIGZhY3RvcmVzIG9ibGljdWEgKGBvYmxpbWluYCksIGVzdG8gYSB2ZWNlcyBzZSBsbGFtYSAqbWF0cml6IGRlIHBhdHJvbmVzKi4NCg0KYGBge3J9DQpwcmludChyZXMuZWZhNSRsb2FkaW5ncywgY3V0b2ZmPTAsIGRpZ2l0cz0zKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMgTWF0cml6IGRlIGVzdHJ1Y3R1cmFzDQoNClRhbWJpw6luIHBvZGVtb3MgZXhhbWluYXIgbGEgbGxhbWFkYSAqbWF0cml6IGRlIGVzdHJ1Y3R1cmEqLCBxdWUgZXMgZXNlbmNpYWxtZW50ZSBlbCByZXN1bHRhZG8gZGUgbXVsdGlwbGljYXIgbGEgbWF0cml6IGRlIHBhdHJvbmVzIHBvciBsYSBtYXRyaXogZGUgaW50ZXJjb3JyZWxhY2nDs24gZGUgZmFjdG9yZXMuIERlIGVzdGUgbW9kbywgZXN0b3MgdmFsb3JlcyByZWZsZWphbiBsYXMgY29ycmVsYWNpb25lcyBlbnRyZSBsYXMgdmFyaWFibGVzIHkgbG9zIGZhY3RvcmVzLCBsbyBjdWFsIHB1ZWRlIHJlc3VsdGFyIG3DoXMgZsOhY2lsIGRlIGludGVycHJldGFyIGludHVpdGl2YW1lbnRlLg0KDQoNCmBgYHtyfQ0KcHJpbnQocmVzLmVmYTUkU3RydWN0dXJlLCBjdXRvZmY9MCwgZGlnaXRzPTMpDQpgYGANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMgRXh0cmF5ZW5kbyBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzDQoNClBhcmEgZGVzY3JpYmlyIGxvcyBmYWN0b3JlcyBjb24gbWF5b3IgY2xhcmlkYWQgeSBwcmVzZW50YXIgbG9zIHJlc3VsdGFkb3MsIHB1ZWRlIHNlciDDunRpbCBleHBvcnRhciB0b2RhcyBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzLiBFeHBvcnRhciBsYXMgY2FyZ2FzIGVuIGZvcm1hdG8gYENTVmAgaGFyw6EgbXVjaG8gbcOhcyBmw6FjaWwgcmVwb3J0YXIgbG9zIHJlc3VsdGFkb3MuIFNpbiBlbWJhcmdvLCBlc3RlIHByb2Nlc28gbm8gbWFudGVuZHLDoSBlbCBvcmRlbiBxdWUgYWN0dWFsbWVudGUgc2UgdmUgZW4gbGEgc2FsaWRhLiBFbiBlc3RlIHNlbnRpZG8sIHNlIGRlYmVuIG9yZGVuYXIgbGFzIGNvbHVtbmFzIHBvciBudWVzdHJhIGN1ZW50YS4NCg0KUG9yIGFsZ3VuYSByYXrDs24sIGVsIHBhcXVldGUgYHBzeWNoYCBvbWl0ZSBhbGd1bmFzIGNhcmdhcyBzaSBzaW1wbGVtZW50ZSBzZSBsbGFtYSBhIGxhcyBjYXJnYXMgdXNhbmRvIGByZXMuZWZhNSRsb2FkaW5nc2AuIFBhcmEgcmVzb2x2ZXIgZXN0bywgZXMgbmVjZXNhcmlvIGVzcGVjaWZpY2FyIHF1w6kgdmFyaWFibGVzIGVzdGFtb3MgaW5jbHV5ZW5kbyBlbiBsYSBzYWxpZGEuDQoNClBvciBsbyB0YW50bywgcHJpbWVybyBkZWJlbW9zIHZlcmlmaWNhciBjdcOhbnRhcyB2YXJpYWJsZXMgaGF5IGVuIGxhIHNhbGlkYSB5IGx1ZWdvIGVzcGVjaWbDrWNhcmxhcyBhbCBleHRyYWVyIGxhcyBjYXJnYXMuIFRhbWJpw6luIGVzIMO6dGlsIHJlZG9uZGVhciBsYSBzYWxpZGEsIHBvciBlamVtcGxvLCBhIHRyZXMgZMOtZ2l0b3MgZGVzcHXDqXMgZGVsIHB1bnRvIGRlY2ltYWwuIA0KDQoNCmBgYHtyfQ0KZGltKHJlcy5lZmE1JGxvYWRpbmdzKQ0KYGBgDQoNCkhheSBgciBkaW0ocmVzLmVmYTUkbG9hZGluZ3MpWzFdYCB2YXJpYWJsZXMgeSBgciBkaW0ocmVzLmVmYTUkbG9hZGluZ3MpWzJdYCBmYWN0b3Jlcy4NCg0KYGBge3J9DQpudmFyIDwtIGRpbShyZXMuZWZhNSRsb2FkaW5ncylbMV0gDQpGYWN0b3JMb2FkIDwtIHJvdW5kKHJlcy5lZmE1JGxvYWRpbmdzWzE6bnZhcixdLCAzKQ0KRmFjdG9yTG9hZA0KYGBgDQoNCkVsIG9iamV0byBzZSBzYWx2YSBlbiB1biBhcmNoaXZvIGRlIGV4Y2VsIChvIGVuIGZvcm1hdG8gY3N2KSBkZSBsYSBmb3JtYSBzaWd1aWVudGU6IA0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KbGlicmFyeShvcGVueGxzeCkgICMgTGlicmVyw61hIHBhcmEgZXNjcmliaXIgYXJjaGl2b3MgZGUgRXhjZWwNCg0Kd3JpdGUueGxzeChGYWN0b3JMb2FkLCAiRmFjdG9yTG9hZF9leGNlbC54bHMiLCBzaGVldE5hbWUgPSAiQ2FyZ2FzIiwgcm93TmFtZXMgPSBGQUxTRSkNCndyaXRlLmNzdjIoRmFjdG9yTG9hZCwgZmlsZT0iRmFjdG9yTG9hZF9wYy5jc3YiKSAjIGNzdiBjb24gcHVudG8geSBjb21hDQp3cml0ZS5jc3YoRmFjdG9yTG9hZCwgZmlsZT0iRmFjdG9yTG9hZF9jLmNzdiIpICAgIyBjc3YgY29uIGNvbWENCmBgYA0KDQpVbmEgdmV6IGdlbmVyYWRvIGVsIGFyY2hpdm8gQ1NWLCBwdWVkZSBkZXRlcm1pbmFyIHNpIGFsZ3VuYXMgdmFyaWFibGVzIG5vIHNlIGFqdXN0YW4gYWRlY3VhZGFtZW50ZSBhIG5pbmd1bm8gZGUgbG9zIGZhY3RvcmVzICh8Y2FyZ2F8IDwgMC40MCkuIEVuIGVzdGUgY2FzbyBlc3BlY8OtZmljbywgbm8gZW5jb250cmFtb3MgbmluZ3VuYSB2YXJpYWJsZSBxdWUgbm8gc2UgYWRhcHRlIHN1ZmljaWVudGVtZW50ZSBhIGFsZ3VubyBkZSBsb3MgZmFjdG9yZXMuIFNpbiBlbWJhcmdvLCBzaSBsYXMgaHViaWVyYSwgcG9kcsOtYW1vcyBlbGltaW5hciBlc2FzIHZhcmlhYmxlcyBzaWd1aWVuZG8gbG9zIHBhc29zIG1lbmNpb25hZG9zIGFudGVyaW9ybWVudGUuDQoNCkVzIGltcG9ydGFudGUgdGVuZXIgZW4gY3VlbnRhIHF1ZSBhbCBlbGltaW5hciB2YXJpYWJsZXMgZXMgcHJvYmFibGUgcXVlIGxhcyBjYXJnYXMgY2FtYmllbiwgcG9yIGxvIHF1ZSBzZXLDrWEgbmVjZXNhcmlvIHZvbHZlciBhIGVqZWN1dGFyIGVsIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uIGVsIGNvbmp1bnRvIGRlIGRhdG9zIG1vZGlmaWNhZG8gYW50ZXMgZGUgcmVhbGl6YXIgY3VhbHF1aWVyIGludGVycHJldGFjacOzbiBmaW5hbCBvIGVsYWJvcmFyIHVuIGluZm9ybWUuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMgRXh0cmF5ZW5kbyBsb3MgcHVudGFqZXMgZGUgbG9zIGZhY3RvcmVzDQoNCiMjIyBTY29yZXM6IG9wY2lvbmVzDQoNClNlIHB1ZWRlIGV4dHJhZXIgbG9zIHB1bnRhamVzIGRlIGxvcyBmYWN0b3JlcyB1dGlsaXphbmRvIGFsZ3VuYXMgZGUgbG9zIGRvcyBvcGNpb25lcyBzaWd1aWVudGVzOg0KICANCiAgKyBBIHRyYXbDqXMgZGUgYHJlcy5lZmE1JHNjb3Jlc2AuIA0KICANCiAgKyBMYSBmdW5jacOzbiBgZmFjdG9yLnNjb3Jlc2AgZGVsIG1pc21vIHBhcXVldGUgYHBzeWNoYC4NCiAgDQpFc3RhcyBvcGNpb25lcyBjYWxjdWxhbiBsb3MgcHVudGFqZXMgZGUgZmFjdG9yZXMgcGFyYSBjYWRhIG9ic2VydmFjacOzbiBlbiB0dSBjb25qdW50byBkZSBkYXRvcyBvcmlnaW5hbC4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBTY29yZXM6IGByZXMuZWZhNSRzY29yZXNgDQoNCmBgYHtyfQ0KaGVhZChyZXMuZWZhNSRzY29yZXMpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBTY29yZXM6IGBmYWN0b3Iuc2NvcmVzYA0KDQoqKjEuIGBmYWN0b3Iuc2NvcmVzYDogbcOpdG9kb3MgKioNCg0KKyBDb24gZXN0YSBvcGNpw7NuLCBoYXkgcXVlIGFzZWd1cmFyc2UgZGUgcXVlIHRhbnRvIGBmYWAgY29tbyBgZmFjdG9yLnNjb3Jlc2AgZXN0w6luIHV0aWxpemFuZG8gbGEgbWlzbWEgdMOpY25pY2EgcGFyYSBsYSBlc3RpbWFjacOzbiBkZSBsb3MgcHVudGFqZXMgZGUgZmFjdG9yZXMuDQoNCisgTGEgZnVuY2nDs24gYGZhY3Rvci5zY29yZXNgIHRpZW5lIHZhcmlvcyBtw6l0b2RvcywgY29tbyBgVGh1cnN0b25lYCwgYHRlbkJlcmdlYCwgYEFuZGVyc29uYCwgYEJhcnRsZXR0YCwgZXRjLiANCg0KKyBTaSBubyBzZSBlc3BlY2lmaWNhIHVuIG3DqXRvZG8sIHBvZHLDrWEgZXN0YXIgdXNhbmRvIHVubyBwcmVkZXRlcm1pbmFkbyBxdWUgZGlmaWVyZSBkZWwgdXRpbGl6YWRvIGVuIGBmYWAuIA0KDQorIEVuIGVzdGUgY2FzbywgZWwgcXVlIHVzYSBgZmFgIGVzIGVsIG3DqXRvZG8gZGUgcmVncmVzacOzbiAgbyBkZSBUaHVyc3RvbmUgKGBtZXRob2QgPSAicmVncmVzc2lvbiJgIG8gYG1ldGhvZCA9ICJUaHVyc3RvbmUiYCkuIA0KDQoNCg0KKioyLiBgZmFjdG9yLnNjb3Jlc2A6IGFyZ3VtZW50b3MgZGUgYGZhYC4qKg0KDQpBcXXDrSBlc3TDoSBsYSBwYXJ0ZSByZWxldmFudGUgZGUgbGEgZG9jdW1lbnRhY2nDs24gZGUgYGZhYDoNCg0KYGBge3IsZXZhbD1GQUxTRX0NCkFyZ3VtZW50Og0KDQp0aGUgZGVmYXVsdD0icmVncmVzc2lvbiIgZmluZHMgZmFjdG9yIHNjb3JlcyB1c2luZyByZWdyZXNzaW9uLiBBbHRlcm5hdGl2ZXMgZm9yIGVzdGltYXRpbmcgZmFjdG9yIHNjb3JlcyBpbmNsdWRlIHNpbXBsZSByZWdyZXNzaW9uICgiVGh1cnN0b25lIiksIGNvcnJlbGF0b24gcHJlc2VydmluZyAoInRlbkJlcmdlIikgYXMgd2VsbCBhcyAiQW5kZXJzb24iIGFuZCAiQmFydGxldHQiIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSBhbGdvcml0aG1zICggZmFjdG9yLnNjb3JlcykuIEFsdGhvdWdoIHNjb3Jlcz0idGVuQmVyZ2UiIGlzIHByb2JhYmx5IHByZWZlcnJlZCBmb3IgbW9zdCBzb2x1dGlvbnMsIGl0IHdpbGwgbGVhZCB0byBwcm9ibGVtcyB3aXRoIHNvbWUgaW1wcm9wZXIgY29ycmVsYXRpb24gbWF0cmljZXMuDQpgYGANCg0KKiozLiBgZmFjdG9yLnNjb3Jlc2A6IGV4dHJheWVuZG8gbG9zIHB1bnRhamVzLioqDQoNCkNvbiBgbWV0aG9kID0gInJlZ3Jlc3Npb24iYDoNCg0KYGBge3J9DQpmYWN0b3Jfc2NvcmVzX3IgPC0gZmFjdG9yLnNjb3JlcyhkYXQsIHJlcy5lZmE1LCBtZXRob2QgPSAicmVncmVzc2lvbiIpDQpoZWFkKGZhY3Rvcl9zY29yZXNfciRzY29yZXMpDQpgYGANCg0KQ29uIGBtZXRob2QgPSAiVGh1cnN0b25lImA6DQoNCmBgYHtyfQ0KZmFjdG9yX3Njb3Jlc19UIDwtIGZhY3Rvci5zY29yZXMoZGF0LCByZXMuZWZhNSwgbWV0aG9kID0gIlRodXJzdG9uZSIpDQpoZWFkKGZhY3Rvcl9zY29yZXNfVCRzY29yZXMpDQpgYGANCg0KQ29uIGBtZXRob2QgPSAidGVuQmVyZ2UiYDoNCg0KDQpgYGB7cn0NCmZhY3Rvcl9zY29yZXNfdCA8LSBmYWN0b3Iuc2NvcmVzKGRhdCwgcmVzLmVmYTUsIG1ldGhvZCA9ICJ0ZW5CZXJnZSIpDQpoZWFkKGZhY3Rvcl9zY29yZXNfdCRzY29yZXMpDQpgYGANCg0KDQoNCg0KQ29uIGBtZXRob2QgPSAiQmFydGxldHQiYDoNCg0KYGBge3J9DQpmYWN0b3Jfc2NvcmVzX0IgPC0gZmFjdG9yLnNjb3JlcyhkYXQsIHJlcy5lZmE1LCBtZXRob2QgPSAiQmFydGxldHQiKQ0KaGVhZChmYWN0b3Jfc2NvcmVzX0Ikc2NvcmVzKQ0KYGBgDQoNCg0KKio0LiBSZXZpc2nDs24gZGUgcmVzdWx0YWRvcyoqDQoNClZhbW9zIGEgY29tcGFyYSBsb3MgcHVudGFqZXMgb2J0ZW5pZG9zIGNvbiBsb3MgcHVudGFqZXMgZGVudHJvIGRlbCBtb2RlbG8gYGZhYCBhc2VndXLDoW5kb25vcyBkZSBxdWUgbG9zIG3DqXRvZG9zIHkgcGFyw6FtZXRyb3MgY29pbmNpZGFuLiBQb3IgZWplbXBsbywgDQoNCmBgYHtyfQ0KYWxsLmVxdWFsKGZhY3Rvcl9zY29yZXNfciRzY29yZXMsIHJlcy5lZmE1JHNjb3JlcykNCmBgYA0KDQpgYGB7cn0NCmFsbC5lcXVhbChmYWN0b3Jfc2NvcmVzX1Qkc2NvcmVzLCByZXMuZWZhNSRzY29yZXMpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIEV4dHJheWVuZG8gbGFzIG1lZGlhcyBkZSBsb3MgZmFjdG9yZXMgbGF0ZW50ZXMNCg0KVW5hIHZleiBxdWUgdGVuZ2Ftb3MgbG9zIHB1bnRhamVzIGRlIGxvcyBmYWN0b3JlcywgcG9kZW1vcyBjYWxjdWxhciBsYXMgbWVkaWFzIGRlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcyB1dGlsaXphbmRvIGxhIGZ1bmNpw7NuIGBjb2xNZWFuc2AuDQoNCioqUHJpbWVyYSBmb3JtYS4qKg0KDQpgYGB7cn0NCmZhY3Rvcl9tZWFucyA8LSBjb2xNZWFucyhyZXMuZWZhNSRzY29yZXMsIG5hLnJtID0gVFJVRSkNCmZhY3Rvcl9tZWFucw0KYGBgDQoNCioqU2VndW5kYSBmb3JtYS4qKg0KDQpgYGB7cn0NCmZhY3Rvcl9tZWFuc19UIDwtIGNvbE1lYW5zKGZhY3Rvcl9zY29yZXNfVCRzY29yZXMsIG5hLnJtID0gVFJVRSkNCmZhY3Rvcl9tZWFuc19UDQpgYGANCg0KDQoNCg0KYGBge3IsIGV2YWw9IEZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBDb25zaXN0ZW5jaWEgaW50ZXJuYT8NCiMgaHR0cHM6Ly9ycHVicy5jb20vcGptdXJwaHkvNzU4MjY1DQoNCiNQYXJhIG51ZXN0cm9zIHByb3DDs3NpdG9zLCBlc3RhbW9zIGNvbnRlbnRvcyBjb24gZWwgbW9kZWxvIGFjdHVhbCB5IHBvZGVtb3MgYXZhbnphciBhIGV2YWx1YXIgbGEgY29uc2lzdGVuY2lhIGludGVybmEgZGUgbnVlc3Ryb3MgZmFjdG9yZXMuDQoNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIFTDs3BpY29zIHN1bXBsZW1lbnRhcmlvcyANCg0KDQoNCltObyBoYWNlciBjbGljayBhcXXDrV0oT0pPSk9KTyk6IFBlbmRpZW50ZQ0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIENhcMOtdHVsbyBFamVyY2ljaW9zIC0tPg0KDQojIEVqZXJjaWNpb3MNCg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gMQ0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBFamVtcGxvIDMuOC4gZGVsIGxpYnJvIGRlIE1hcnTDrW4gRMOtYXosIHBhZ2luYSA2NA0KYGBgDQpMYSBpbmZvcm1hY2nDs24gZW4gbGEgdGFibGEgc2lndWllbnRlIGVzdMOhIHJlbGFjaW9uYWRhIGNvbiBsYSBwb2JsYWNpw7NuLCBzaXR1YWNpw7NuIHNvY2lvZWNvbsOzbWljYSBlIGluZGljYWRvcmVzDQpjb21lcmNpYWxlcyB5IGVjb27Ds21pY29zLiBMYXMgb2JzZXJ2YWNpb25lcyBzb24gbGFzIGNpbmN1ZW50YSBjYXBpdGFsZXMgZGUgcHJvdmluY2lhcyBlc3Bhw7Fhb2xhcy4NClNlIGRlc2VhIGludmVzdGlnYXIgc2kgZXhpc3RlIHVuYSBlc3RydWN0dXJhIGRlIGNvcnJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzLiBTaSBlc2UgZnVlc2UgZWwgY2Fzbywgc2UgZXN0YSBpbnRlcmVzYWRvDQplbiBzYWJlciDCv2PDs21vIGVzb3MgZWplcyBmYWN0b3JpYWxlcyB5IGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcyBlc3TDoW4gcmVsYWNpb25hZG9zPw0KDQpgYGB7cn0NCmRhdGEgPC0gbWF0cml4KGMoDQogIDM3MjEyLjc4LCAxNzE5MC4zNCwgMTc0NDcuNjksIDQ5MC42MSwgMjYxLjc5LCAyMzEuOTksIDI2Mi40MiwgMTU0LjAzLCA0MDAuNiwNCiAgMzg4OTMuNTcsIDEwNzExLjA1LCAxNzIxMC44NywgNDI4LjYsIDI0My4zNiwgMTY5LjI3LCAxMzAuMywgMTMyLjIyLCAzMDMuNCwNCiAgMzYzMjYuNTQsIDEzMzAwLjkxLCAxNDg0Ni43NywgMzE2LjI5LCAxNTkuMTEsIDE3MC43NiwgMTAxLjU1LCAxMDUuMTEsIDIxMi44LA0KICAzNzU3MC44MSwgMTg5NDQuOTksIDE2NzkzLjE3LCA1MjMuOTEsIDI2NC43NSwgMjAwLjU3LCAxODIuMDgsIDE0NS40NSwgMzUzLjM1LA0KICAzNTI4NC40NSwgMTU2ODkuMjUsIDIwMDI5LjgxLCAzMzYuNDEsIDIzNC43MiwgMTk5LjIsIDE1My4yMywgMTQ5Ljc1LCAzNDIuNjgsDQogIDM3Mzk5LjIxLCAxNTQzNy45NiwgMTc5OTYuMTIsIDM5NS4wOSwgMjIxLjcxLCAyMjEuNzEsIDE4MC45NywgMTc1LjI4LCA0MDEuNzIsDQogIDM5MDM1Ljg2LCAxNjI2NC41NywgMTc2MzUuMDMsIDQyNC40NywgMzExLjA4LCAyMDMuOTcsIDI0OC4xOCwgMTM1Ljg2LCAzNDUuNCwNCiAgNDU2NzguMjcsIDE0NDA5LjQ5LCAxNjgwMi4wOCwgMzg0LjIxLCAyNjYuNTcsIDIxNS4yMiwgMTcwLjQ1LCAxMzUuNDgsIDQwMi40OSwNCiAgNDEwMDkuOTYsIDEyMzU2LjU2LCAxMTAwNy4xNiwgNDk3Ljc4LCAyNTcuODksIDIzOS44OSwgMTk3LjkxLCAyMDkuOTEsIDU1NS43NiwNCiAgNDMxNzkuNzcsIDEwMjkxLjY1LCAxMTQ2Mi43NywgMzkzLjYsIDIxOS4zOCwgMjIyLjYxLCAyMDMuMjUsIDEwOS42OSwgNDQxLjk5LA0KICA0NTU1Ny4zOCwgMTM0OTEuMDMsIDEwODY2LjM2LCA0OTYuOTEsIDMxNC4yOSwgMjYzLjY3LCAyMTUuNDksIDE4NS41NSwgNDU2LjU0LA0KICA0OTQ4MS41MiwgMTU4NjAuMTEsIDEwNzU2LCA0OTMuMTQsIDMzMi4yLCAyMzYuMjMsIDE5My45MSwgMTg4LjQ5LCA0MjEuNzcsDQogIDYxMTUzLjk5LCAyNDIwMy44NywgMTM3MjYuNzcsIDgzMC44MSwgNDE0LjQzLCAzMjMuMzgsIDM4Mi4zNSwgMjUzLjA3LCA2MDguMiwNCiAgMzk1NDMuMDEsIDE5NTM3LjU2LCAxMjExNi4zMywgNDMxLjg1LCAyNTIuMjIsIDIyNC4yLCAxODAuNDMsIDIyOS4yNywgNTE1LjEyLA0KICA0NTE3My4zLCAxNzIzMy41OCwgMTI5ODAuNCwgNTkxLjc1LCAyNjUuMTQsIDI1Mi4xMiwgMjM1Ljk3LCAyNjMuNTgsIDU3NS4wOCwNCiAgNDg3MTcuMTYsIDE2NTg2LjA5LCAxMjAwNi42NywgNDg0LjUxLCAyODYuMjgsIDIyNi4wNCwgMjIyLjk1LCAxNTAuODYsIDM5OS41NSwNCiAgMzg2OTAuMTQsIDEyMDIzLjc0LCAxMzM4Ny4zNCwgNTczLjUxLCAyMzguNjMsIDI0Mi42NCwgMTg4LjUsIDE2MC40MiwgNDQ3LjE4LA0KICA0MDA1Ni45NSwgMTIwODAuMDYsIDEyMjA4Ljg0LCA0NjIuNTUsIDIzMy45MywgMjM0LjUyLCAxNzcuODEsIDE2My42NCwgMzgzLjM5LA0KICA0MzA2OC4zLCAxNDU1NC41OSwgMTI5NzcuMzcsIDU4Ny4yNywgMzUwLjcyLCAyOTYuNzEsIDI2OS4zNiwgMTgxLjE3LCA0NTEuOSwNCiAgMzkzMzUuODIsIDEzMjYyLjkzLCAxMjk3OC40NSwgNTU5LjE4LCAyODYuOTIsIDI1Ny42MiwgMTg0LjM2LCAxNzIuMTUsIDQwNS4zNSwNCiAgMzY3NzIuMDEsIDEzNzA5LjczLCAxMTQ2NS4wMSwgNDIwLjk5LCAyNzMuNjcsIDE4NS40OSwgMTgxLjE5LCAxMzcuMSwgMzAyLjE2LA0KICA0MjM3OC4xMSwgMTIyNzQuNiwgMTIzNzIuNzcsIDM4MC42MiwgMTgyLjU2LCAxNzkuMTIsIDg2LjExLCAxMDMuMzQsIDI1NC45LA0KICA0MzcxMC40OCwgMTMzMDcuMzYsIDExOTM1LjQxLCA1MTMuNzgsIDI3My44MywgMzA0Ljg4LCAyNTYuODksIDE0OS42MiwgNDQzLjIsDQogIDM5OTIzLjM2LCAxMjA0OC4zNSwgMTI2MDIuMTMsIDM3My4zNCwgMTkyLjksIDE4NS45NSwgMTM1LjI2LCAxMzguNzQsIDMyMS4yMSwNCiAgNDA4MzMuMTEsIDE2MjU5LjA1LCAxMzIyMy45NSwgNTQzLjk3LCAyODguODUsIDMxMi4zMSwgMjMxLjY2LCAxNzguODgsIDUwMS40NSwNCiAgMzY1MTEuNzcsIDEyNTY5LjEsIDE1MTE2Ljk1LCA0NjcuMzcsIDIzMS44MywgMjc2LjQxLCAxODcuOTksIDE4My41MywgNDE3LjU4LA0KICA0MDE5OS44NywgMTM1OTAuNjMsIDE0MTU0LjI1LCA0NTcuNjIsIDE4Ni43NSwgMjMwLjQ5LCAxODMuMzgsIDE1OS44MywgNTE2LjUsDQogIDM5OTkwLjQsIDEzMjc5LjI0LCAxMjI1NC4wNywgMjc0LjgzLCAyMjIuNDgsIDE5Ni4zMSwgODkuNDMsIDgwLjcsIDI1OS41NiwNCiAgMzg3NzYuODgsIDEzOTQwLjkzLCAxNDM4Mi44NiwgNDg1LjA4LCAyMjMuMiwgMjMzLjYxLCAxNzIuNjEsIDE0OC44LCA0NjQuMjUsDQogIDQ0NzYyLjI3LCAxNDI1Ny44NCwgMTYzNjEuNDMsIDUxNi4wNiwgMjk4Ljk0LCAyNTguMDMsIDI0My44NywgMTY1LjIsIDUzNC45NCwNCiAgNjcyNTQuNTIsIDIxOTg3LjkzLCAxMjM3NC4wMSwgNzY3Ljk4LCA0MDMuNzcsIDI5My4xOSwgMjMxLjE5LCAyMzguNTEsIDY5OC4yOSwNCiAgNzE0MDQsIDMzNzYyLjY0LCAxNzczNi4xOSwgODgyLjU1LCA0NjYuNywgNDc3LjE3LCA0ODAuMTcsIDI4Mi43MSwgOTEyLjQ2LA0KICA0NjEyMC45OSwgMTczNTIuOTYsIDEyNDExLjE1LCA2MjAuOTgsIDM0Mi4zOCwgMzEwLjQ5LCAyMjMuMjIsIDIzMS42MSwgNjI1LjE3LA0KICA0NzM2NS44NSwgMTgzNzMuOCwgMTU2MDMuMzksIDUzNy4wNCwgMzI0LCAzMDYuMjQsIDI1Mi4xLCAxOTMuNTEsIDU1My4wMiwNCiAgNTE4NTEuNDQsIDE5NDE5LjM4LCAxMzI0OS42MywgNDU4LjAyLCAyOTcuMSwgMjMwLjMsIDIwNS4yLCAxNTAuNTgsIDM5OS43LA0KICA0NDA4NC42NSwgMTYzMzQuNjgsIDEzMzY0LjI4LCA1NTIuOSwgMzAxLjE5LCAyNzIuMDksIDI4OS41NSwgMTcyLjQyLCA1MDkuMjUsDQogIDUwNDAyLjU1LCAxNjg1MC40NiwgMTA4MDYuNTQsIDUyNC4xNywgNDA1LjgzLCAyNDEuMzEsIDE4MC40NywgMTgzLjU1LCA1MTAuOTIsDQogIDMzNzQ1Ljk2LCAxMTMyMi4xNCwgMTUwMjkuNjQsIDQ1Mi40NSwgMjc1LjE3LCAyMzguOTQsIDE1My4zOSwgMTU4LjAxLCA0MjAuMDgsDQogIDM3Mjc2Ljk2LCAxMjA4NC45LCAxMzMxMS42MSwgMzk1LjI3LCAyMjcuOTksIDIyNS41MiwgMTIwLjE5LCAxNzIuMjMsIDQwNS4xOCwNCiAgNDg0NjMuNDUsIDE1MDczLjg4LCAxNTA3OC4yNiwgNjM4LjE3LCAzNzEuNjEsIDI0NS44OCwgMjQ5LjQ2LCAxOTcuMzQsIDUwMi41LA0KICA0MDY5OC4wMiwgMTQ5NTEuNywgMTU1MjYuNjgsIDYzMS4zMiwgMjc1Ljk5LCAyNjQuNDksIDM1Ni40OSwgMTc1Ljk0LCA1NjAuMDMsDQogIDQ0ODQ5Ljc0LCAxMjUwOS40NCwgMTc3MDQuOTIsIDgwMC45NSwgMzE5LjgyLCAyNjkuNDcsIDMzNy41NCwgMTk3LjY3LCA0NzEuODEsDQogIDM5NTkxLjcxLCAxNTQ5Ni41MywgMTg1NTMuMzUsIDUzMS43NCwgMjM5LjE1LCAyNDQuNDksIDI4NC41NywgMTQxLjYyLCAzODIuMSwNCiAgNjI0MjAuMTMsIDIxNDg5LjMyLCA5ODI4LjYzLCA0MjcuMSwgMzAxLjAxLCAyMjMuNDgsIDE4Ni4xMiwgMTU3LjUxLCA0NTguNzMsDQogIDM4Njc0LjgsIDE0NzQyLjk1LCAxNDQ1OC42MiwgNDAyLjMyLCAyNDguNDUsIDIyOS4yOSwgMjM5LjYzLCAxNDcuNDksIDM5MS45OCwNCiAgNDU3MDYuMTgsIDE3MTYxLjE0LCAxMTU4MS42OSwgMzkxLjkyLCAyNjcuOTEsIDE5Mi4wMywgODguOTUsIDExMC40MSwgMzEyLjkxLA0KICA0NTU2OS41NywgMTM1NzMuOTIsIDEzMzgyLjYyLCAzMjMuNjMsIDI0Mi42MSwgODYuMywgMTAxLjE3LCAxNDcuNjcsIDMzMS43OCwNCiAgNTg1NzUuNywgMTgyODUuMDMsIDEzMzcxLjY4LCA1MjQuNjMsIDI4Mi45OCwgMjE4LjEyLCAxMTQuOCwgMTY4Ljc1LCA0NTguMDQsDQogIDQ4OTA3LjMyLCAyMDI0OC43MSwgMTIyNjUuOCwgMjg4LjAxLCAxODguOSwgMTQwLjcsIDgxLjk3LCAxMzAuOTEsIDI1Ni45MywNCiAgNDM5NjAuMjQsIDEzNTc4LjQyLCAxMjI1NS40NCwgNzA4LjQzLCAzNDEuNTksIDI5Mi42OCwgMjk4Ljk5LCAyMzUuODgsIDUxNS4xNQ0KKSwgbmNvbCA9IDksIGJ5cm93ID0gVFJVRSkNCg0KZGYgPC0gYXMuZGF0YS5mcmFtZShkYXRhKQ0KDQpwcmludChkZikNCg0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gMg0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBFamVtcGxvIHRhYmxhIDguMiwgc2VjY2lvbiA4LjUuIGRlbCBsaWJybyBkZSBSMjAxNSBaZWx0ZXJtYW4sIHBhZ2luYSAyMTcNCmBgYA0KDQpMb3MgZGF0b3MgZGUgbGEgdGFibGEgZGUgbGEgZmlndXJhIFxAcmVmKGZpZzpGaWd1cmFQYWcyMjApIHByb2NlZGVuIGRlIHVuIHJlZ2lzdHJvIGRlIGxhY3RhbnRlcyB0cmF0YWRvcyBxdWlyw7pyZ2ljYW1lbnRlIGp1bnRvIGNvbiBtZWRpY2lvbmVzIGRlIHZhcmlvcyBtYXJjYWRvcmVzIGdlbsOpdGljb3MgcmVsYWNpb25hZG9zIGNvbiBsYSBlbmZlcm1lZGFkLiBMYSBlZGFkLCBtZWRpZGEgZW4gZMOtYXMsIGVzIGxhIGVkYWQgZWRhZCBkZWwgbmnDsW8gZW4gZWwgbW9tZW50byBkZSBsYSBpbnRlcnZlbmNpw7NuIHF1aXLDunJnaWNhLiBMYSBlZGFkLCBwb3IgdGFudG8sIHJlcHJlc2VudGEgZWwgdGllbXBvZXN0dXZvIGV4cHVlc3RvIGFsIHR1bW9yLiBMYSBoaXDDs3Rlc2lzIGVyYSBxdWUgbGEgZXhwb3NpY2nDs24gYSBsYSBtYWduaXR1ZCBkZSBsYSBleHByZXNpw7NuIGRlIGFsZ3Vub3MgZGUgZXN0b3MgZ2VuZXMgYSBsbyBsYXJnbyBkZWwgdGllbXBvLiBnZW5lcyBhIGxvIGxhcmdvIGRlbCB0aWVtcG8uIA0KDQoNCg0KYGBge3J9DQpkYXRhIDwtIGRhdGEuZnJhbWUoDQogIEFnZSA9IGMoODEsIDk1LCA5NSwgMTY1LCAyODYsIDI5OSwgMzgwLCA0MTgsIDQyMCwgNTQ3LCA1OTAsIDYzNSwgNzUyLCA3NjAsIDExNzEsIDEyNzcsIDE1MjAsIDIxMzgsIDM2MjYpLA0KICBSQiA9IGMoMi4wLCA2LjUsIDMuNiwgMS45LCAyLjYsIDIuOSwgMS45LCA3LjEsIDYuNCwgNi40LCAxLjgsIDYuNywgMS44LCA3LjMsIDEuOCwgMS4zLCA0LjAsIDAuNSwgNC4yKSwNCiAgcDE2ID0gYygzLjA3LCAxLjkwLCAzLjgyLCAzLjc0LCA1LjE3LCA1Ljc2LCAyLjQwLCAzLjM4LCAzLjM3LCA0LjA1LCA1LjE1LCAyLjY3LCAzLjI4LCAwLjkyLCA2LjU2LCAwLjA1LCAyLjc5LCAwLjAwLCA0LjI0KSwNCiAgRExLID0gYygzMDg5NzUsIDcwOTg4LCAxNTMwNjEsIDU5Njk5MiwgMzY5NjAxLCAxMTE5MjU4LCAyMTQwNzEsIDY5NTExLCA4MTQ1NywgNjQzNDgsIDE2NDg4MSwgMTI2MDE2LCA1Njc4NTgsIDQzNDM4LCA3MTYyNjAsIDk0LCAzMTEyNSwgMjMzMSwgNTYwMjA4KSwNCiAgTmFub2cgPSBjKDk0LCAzODIsIDIzNywgODgsIDI4MiwgMTc3LCA0NSwgMjY1LCA2NTksIDMzNiwgMjAxMiwgMzA3MiwgMTI3LCA2OTgsIDM5MiwgMTUsIDQ1NCwgMzMsIDM0MCksDQogIENfTXljID0gYyg2LjQ5LCAxLjAwLCAwLjAwLCAwLjAwLCAxMi4yMywgOC43NiwgNS43NiwgMS4xNywgMS44OCwgMC43OCwgMzUuNjUsIDAuMDAsIDQuMTMsIDEuNzcsIDEyLjkyLCAwLjM2LCAwLjYyLCAwLjAzLCA1LjQzKSwNCiAgRVpIMiA9IGMoMi43NiwgNy4wOSwgNS41NywgMi40NywgMS42MywgMy41MSwgMS40MSwgMy4wNywgMy44NywgNC43NiwgOS40NSwgNC4zNSwgMS4wMCwgMy4zMiwgMi45MCwgMy44MywgMi4zMywgMC4xNywgMS4zNiksDQogIElHRl8yID0gYygxMTE3NiwgNTM0MCwgNjMxMCwgNzAwOSwgNzEwNCwgOTM0MiwgMzcyNiwgODAzOSwgMTI1ODMsIDY1MDUsIDMyNzIyLCAxMTc2MywgMTAyODMsIDExNTE4LCAxMzI2NCwgMzAsIDExNjMsIDY2LCAyMTE3NCkNCikNCmBgYA0KDQogICANCg0KDQo8Y2VudGVyPg0KYGBge3IgRmlndXJhUGFnMjIwLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqRWRhZCwgZW4gZMOtYXMsIHkgZXhwcmVzacOzbiBkZSBsb3MgbWFyY2Fkb3JlcyBnZW7DqXRpY29zIGRlIGxvcyBsYWN0YW50ZXMgcXVlIGZ1ZXJvbiB0cmF0YWRvcyBxdWlyw7pyZ2ljYW1lbnRlIHBvciBoZW1hbmdpb21hKioiLCBvdXQud2lkdGggPSAiNzAlIn0NCg0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiVGFibGE4XzJfcDIyMF9SMjAxNV9aZWx0ZXJtYW4ucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gMw0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyBFamVyY2ljaW8gMTIuMSBkZWwgbGlicm8gZGUgcGXDsWEsIHBhZ2luYSAzODkNCmBgYA0KDQoNCkRhZG8gZWwgbW9kZWxvIGZhY3RvcmlhbCANCiQkWCA9IFxMYW1iZGEgZiArIHUsJCQNCg0KZG9uZGUgJFggPSAoWF8xLCBYXzIsIFhfMywgWF80KSQgdGllbmUgbWVkaWEgY2VybyB5IHZhcmlhbnphcyAkKDEsIDIsIDEsIDcpJC4gU3Vwb25nYSwgYWRlbcOhcywgIHF1ZQ0KDQokJFxMYW1iZGEgPSBcYmVnaW57cG1hdHJpeH0gMC44ICYgMSAmIDAgJiAyIFxlbmR7cG1hdHJpeH1eVCwgXHFxdWFkIFZhcihmKSA9IDEkJA0KDQpSZWFsaXphciBsbyBzaWd1aWVudGU6DQoNCihhKSAgQ2FsY3VsYXIgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyB2YXJpYWJsZXMgeSBlbCBmYWN0b3IuDQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojICRDb3YoeF9pLCBmKSA9IFxMYW1iZGFfaSBcc3FydHtWYXIoZil9ID0gXExhbWJkYV9pJCwgZG9uZGUgJFxMYW1iZGFfaSQgc29uIGxvcyBlbGVtZW50b3MgZGUgJFxMYW1iZGEkLg0KYGBgDQoNCg0KKGIpICBDYWxjdWxhciBsYXMgY29ycmVsYWNpb25lcyBlbnRyZSBsYXMgdmFyaWFibGVzIHkgZWwgZmFjdG9yLg0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojICRDb3JyKHhfaSwgZikgPSBcZnJhY3tDb3YoeF9pLCBmKX17XHNxcnR7VmFyKHhfaSkgXGNkb3QgVmFyKGYpfX0gPSBcZnJhY3tcTGFtYmRhX2l9e1xzcXJ0e1Zhcih4X2kpIFxjZG90IFZhcihmKX19JA0KYGBgDQoNCihjKSBFc2NyaWJpciBlbCBtb2RlbG8gY29tbyB1biBtb2RlbG8gdW5pZmFjdG9yaWFsIGNvbiB1biBmYWN0b3IgZGUgdmFyaWFuemEgaWd1YWwgYSA1Lg0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyAkeCA9IFxzcXJ0ezV9IFwsIGYgKyB1JA0KYGBgDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyA0DQoNCmBgYHtyIGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQojIEVqZXJjaWNpbyAxMi4yIGRlbCBsaWJybyBkZSBwZcOxYSwgcGFnaW5hIDM4OQ0KYGBgDQoNCkluZGljYXIgc2kgZXMgcG9zaWJsZSBlbCBzaWd1aWVudGUgbW9kZWxvIGZhY3RvcmlhbDoNCg0KDQokJFggPSBcTGFtYmRhIGYgKyB1LCQkDQpkb25kZSAkWCA9IChYXzEsIFhfMiwgWF8zKSQgdGllbmUgbWVkaWEgY2VybyB5IHZhcmlhbnphcyAkKDMsIDIsIDEpJCB5LCBhZGVtw6FzLCANCg0KJCRcTGFtYmRhID0gXGJlZ2lue3BtYXRyaXh9IDMgJiAgMCAmIDMgXGVuZHtwbWF0cml4fV5ULCBccXF1YWQgVmFyKGYpID0gMSQkDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCiMgRWplcmNpY2lvIDEyLjMgZGVsIGxpYnJvIGRlIHBlw7FhLCBwYWdpbmEgMzg5DQoNCiMjIyBFamVyY2ljaW8gNQ0KDQpTZWEgZGFkbyB1biBtb2RlbG8gZmFjdG9yaWFsIGRvbmRlICRYID0gKFhfMSwgWF8yLCBYXzMsIFhfNCwgWF81LCBYXzYpJCB0aWVuZSBtZWRpYSBjZXJvIHkgDQoNCiQkXExhbWJkYSA9IFxiZWdpbntwbWF0cml4fSBcbGFtYmRhXzEgJiBcbGFtYmRhXzIgXGVuZHtwbWF0cml4fV5ULCBccXF1YWQgXGxhbWJkYV8xID0gXGJlZ2lue3BtYXRyaXh9IDEmIDEmMSAmMCYwJjAgXGVuZHtwbWF0cml4fV5ULCBccXF1YWQgXGxhbWJkYV8yID0gXGJlZ2lue3BtYXRyaXh9IDAmMSAmIDAmMSYwJjEgXGVuZHtwbWF0cml4fV5UJCQNCg0KJCRWYXIoZikgID0gXGJlZ2lue3BtYXRyaXh9IDEmMC41XFwgMC41JjIgXGVuZHtwbWF0cml4fSQkDQoNCkF2ZXJpZ3VhciBjw7NtbyBlc2NyaWJpcmxvIGVuIGZvcm1hIGVzdMOhbmRhciBjb24gbGEgbm9ybWFsaXphY2nDs24gJFxMYW1iZGFeVFxMYW1iZGEgPSBEaWFnb25hbCQuIA0KDQoNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCg0KPCEtLSBDYXDDrXR1bG8gQmlibGlvZ3JhZsOtYS0tPg0KDQoNCiMgQmlibGlvZ3JhZsOtYSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KICANCkNvbnN1bHRhciBlbCBkb2N1bWVudG8gW1JQdWJzIDo6IEFuw6FsaXNpcyBtdWx0aXZhcmlhZG8gKGJpYmxpb2dyYWbDrWEpXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL1JfTXVsdGl2YXJpYWRvX0JpYmxpb2dyYWZpYSkuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQoNCiZuYnNwOw0KDQoNCiZuYnNwOw0KPGNlbnRlcj4NCn5+fg0KSWYgeW91IGZvdW5kIGFueSBFUlJPUlMgb3IgaGF2ZSBTVUdHRVNUSU9OUywgcGxlYXNlIHJlcG9ydCB0aGVtIHRvIG15IGVtYWlsLiBUaGFua3MuICANCn5+fg0KPC9jZW50ZXI+DQoNCg0K