hllinas2023

1 Librerías

1.0.1 Para SEM

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

library(sem)
library(lavaan)
library(blavaan)
library(semPlot)
  • sem: corresponde a uno de los primeros paquetes desarrollados en R para la especificación y estimación de modelos de ecuaciones estructurales (SEM) mediante máxima verosimilitud. Aunque actualmente su uso es menos extendido que otros paquetes más modernos, resulta útil desde un punto de vista histórico y conceptual, ya que permite comprender la estructura básica de los modelos SEM y su relación directa con la formulación matricial clásica.

  • lavaan: desarrollado por Rossel (2012). Se utiliza para especificar y estimar modelos factoriales confirmatorios (CFA) y modelos de ecuaciones estructurales (SEM) multigrupo, permitiendo evaluar tanto la invarianza de medida (cargas, interceptos y residuos) como la invarianza estructural (regresiones, varianzas y covarianzas latentes) entre grupos. Para una introducción práctica al paquete, puede consultarse el tutorial oficial disponible en: https://lavaan.ugent.be/tutorial.

  • blavaan: extiende la sintaxis y funcionalidad de lavaan al marco bayesiano, permitiendo la estimación de modelos SEM mediante métodos MCMC. Este paquete resulta especialmente útil cuando se desean incorporar información previa, trabajar con muestras pequeñas o evaluar la incertidumbre completa de los parámetros a través de distribuciones posteriores. Su uso en el capítulo tiene un carácter introductorio y comparativo frente al enfoque clásico de máxima verosimilitud.

  • semPlot: se emplea para la representación gráfica de modelos SEM y CFA, facilitando la visualización de factores latentes, variables observadas, cargas factoriales, covarianzas y efectos estructurales. Este paquete permite generar diagramas claros y personalizables, lo cual es fundamental tanto para la interpretación sustantiva de los modelos como para la comunicación de resultados en contextos académicos y aplicados.

1.0.2 Para otros análisis

library(psych)         #Para realizar un EFA
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
library(knitr)         #Crear tablas con estilo
library(kableExtra)    #Crear tablas con estilo, pero para html

En particular:

  • psych: se utiliza para realizar análisis factorial exploratorio (EFA) y obtener diagnósticos psicométricos preliminares.

  • tidyverse: conjunto de paquetes para manipulación, transformación y visualización de datos; incluye dplyr y ggplot2.

  • stringr: facilita operaciones de manipulación y reemplazo de cadenas de texto dentro de data frames.

  • outliers: permite la detección de valores atípicos mediante pruebas estadísticas clásicas, como grubbs.test.

  • EnvStats: se emplea para la detección de outliers múltiples, especialmente mediante la prueba de Rosner (rosnerTest).

  • DMwR2: implementa métodos basados en densidad para detección de valores atípicos, como el Local Outlier Factor (LOF).

  • rgl: se utiliza para visualización gráfica tridimensional de datos, por ejemplo con plot3d.

  • corrplot: permite la visualización gráfica de matrices de correlación de forma compacta e interpretable.

  • textshape: se emplea para transformaciones estructurales de data frames, como convertir columnas en nombres de filas (column_to_rownames).

  • openxlsx: permite leer y escribir archivos de Excel sin depender de software externo.

  • knitr: se utiliza para la creación y presentación ordenada de tablas y resultados dentro de documentos R Markdown.

  • kableExtra: extiende las capacidades de knitr para generar tablas con formato avanzado, especialmente en salidas HTML.

A medida que avance el capítulo, se explicará el propósito de cada función utilizada y la interpretación de sus resultados, priorizando siempre el significado estadístico y sustantivo de los modelos sobre el uso meramente técnico del software.

2 Sintáxis con lavaan

2.0.1 Tipos de fórmulas

Utilizando cuatro tipos de fórmulas, se puede describir una gran variedad de modelos de variables latentes. El conjunto actual de tipos de fórmulas se resume en la figura 2.1.

**Tipos de fórmulas**

Figure 2.1: Tipos de fórmulas

2.0.2 Sintáxis de los modelos

  1. En lavaan, los modelos SEM pueden especificarse mediante fórmulas de modelo similares a las utilizadas en las funciones lm y glm.

  2. Sin embargo, hay algunos operadores nuevos (símbolos relacionales) que se utilizan para definir covarianzas (residuales) y variables latentes.

  3. La figura 2.2 enumera algunas expresiones comunes en la sintaxis de lavaan.

**Sintáxis de los modelos**

Figure 2.2: Sintáxis de los modelos

3 Ejemplo de aplicación: contexto

3.0.1 Contexto del estudio y objetivo analítico

En estudios educativos y psicológicos es frecuente comparar grupos definidos por características institucionales, sociales o demográficas (por ejemplo, tipo de escuela, género o nivel educativo). Sin embargo, dichas comparaciones solo son válidas si se garantiza que los instrumentos utilizados operan de forma equivalente en todos los grupos considerados.

En este ejemplo se evalúa si un conjunto de pruebas cognitivas mide los mismos constructos latentes en dos grupos de estudiantes pertenecientes a diferentes tipos de escuela. El interés central no es únicamente estimar un modelo factorial, sino verificar empíricamente la invarianza de medida, comenzando por la invarianza configural y avanzando hacia niveles más restrictivos, en particular la invarianza métrica.

3.0.2 Descripción del datasets

Se utiliza el conjunto de datos clásico de Holzinger y Swineford (1939), ampliamente empleado en la literatura metodológica para ilustrar modelos factoriales confirmatorios y análisis multigrupo.

head(HolzingerSwineford1939)
##   id sex ageyr agemo  school grade       x1   x2    x3       x4   x5        x6
## 1  1   1    13     1 Pasteur     7 3.333333 7.75 0.375 2.333333 5.75 1.2857143
## 2  2   2    13     7 Pasteur     7 5.333333 5.25 2.125 1.666667 3.00 1.2857143
## 3  3   2    13     1 Pasteur     7 4.500000 5.25 1.875 1.000000 1.75 0.4285714
## 4  4   1    13     2 Pasteur     7 5.333333 7.75 3.000 2.666667 4.50 2.4285714
## 5  5   2    12     2 Pasteur     7 4.833333 4.75 0.875 2.666667 4.00 2.5714286
## 6  6   2    14     1 Pasteur     7 5.333333 5.00 2.250 1.000000 3.00 0.8571429
##         x7   x8       x9
## 1 3.391304 5.75 6.361111
## 2 3.782609 6.25 7.916667
## 3 3.260870 3.90 4.416667
## 4 3.000000 5.30 4.861111
## 5 3.695652 6.30 5.916667
## 6 4.347826 6.65 7.500000

La vista preliminar de las primeras observaciones permite identificar el tipo general de información contenida en la base de datos, incluyendo variables demográficas, una variable de agrupación y puntuaciones en pruebas cognitivas.

El estudio original contiene puntuaciones de pruebas de capacidad mental aplicadas a 301 estudiantes de séptimo y octavo grado pertenecientes a dos escuelas distintas: Pasteur y Grant-White. En la versión completa del estudio se incluyen 26 pruebas; sin embargo, gran parte de la literatura utiliza un subconjunto reducido de 15 variables, que es el que se emplea en esta aplicación.

dim(HolzingerSwineford1939)
## [1] 301  15

La dimensión del conjunto de datos confirma que se dispone de 301 observaciones y 15 variables, lo cual resulta adecuado para ilustrar procedimientos de análisis factorial confirmatorio y evaluación de invarianza multigrupo.

Adicionalmente, el conjunto de datos presenta las siguientes características clave para el análisis de invarianza de medida:

  • Dos grupos, definidos por la variable school (Pasteur y Grant-White), que puede actuar como variable de agrupación en el análisis multigrupo.

  • Tres constructos latentes teóricamente definidos:

    • visual: habilidades de percepción visual.

    • textual: habilidades verbales.

    • speed: rapidez en tareas cognitivas.

  • Nueve indicadores observados, distribuidos equitativamente en tres ítems por cada factor latente.

3.0.3 Descripción de las variables del datasets

A continuación se muestran los nombres de todas las variables incluidas en el conjunto de datos:

names(HolzingerSwineford1939)
##  [1] "id"     "sex"    "ageyr"  "agemo"  "school" "grade"  "x1"     "x2"    
##  [9] "x3"     "x4"     "x5"     "x6"     "x7"     "x8"     "x9"

Las variables pueden agruparse conceptualmente de la siguiente forma:

  1. Variables de identificación y contexto:

    • id: identificador del estudiante.

    • school: escuela (group 1 = Pasteur o group 2 = Grant-White).

    • grade: grado escolar.

  2. Variables demográficas:

    • sex: género (1 = Male o 2 = Female).

    • ageyr: edad (parte del año).

    • agemo: edad (parte del mes).

  3. Indicadores cognitivos x1, x2, …, x9, utilizados en el modelo factorial y que fueron calculadas a través de funciones de pruebas cognitivas:

    • Factor visual: habilidades de percepción y razonamiento visual

      • x1: Visual perception (percepción visual).

      • x2: Cubes (cubos).

      • x3: Lozenges (pastillas).

    • Factor textual : habilidades verbales y de comprensión lingüística

      • x4: Paragraph comprehension (comprensión de parágrafos).

      • x5: Sentence completion (completar oraciones).

      • x6: Word meaning (significado de palabras).

    • Factor speed: rapidez en tareas cognitivas simples

      • x7: Speeded addition (adición con velocidad).

      • x8: Speeded counting of dots (conteo de puntos con velocidad).

      • x9: Speeded discrimination straight and curved capitals (discriminación acelerada de letras mayúsculas rectas y curvas). Por ejemplo: letras con trazos rectos (A, E, F, H, I, K, L, M, N, T, V, W, X, Y, Z) y letras con trazos curvos (B, C, D, G, J, O, P, Q, R, S, U).

Finalmente, se inspecciona la estructura interna del conjunto de datos para identificar el tipo de cada variable (numérica, factor, carácter), información relevante para la correcta especificación del modelo CFA multigrupo:

str(HolzingerSwineford1939)
## 'data.frame':    301 obs. of  15 variables:
##  $ id    : int  1 2 3 4 5 6 7 8 9 11 ...
##  $ sex   : int  1 2 2 1 2 2 1 2 2 2 ...
##  $ ageyr : int  13 13 13 13 12 14 12 12 13 12 ...
##  $ agemo : int  1 7 1 2 2 1 1 2 0 5 ...
##  $ school: Factor w/ 2 levels "Grant-White",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ grade : int  7 7 7 7 7 7 7 7 7 7 ...
##  $ x1    : num  3.33 5.33 4.5 5.33 4.83 ...
##  $ x2    : num  7.75 5.25 5.25 7.75 4.75 5 6 6.25 5.75 5.25 ...
##  $ x3    : num  0.375 2.125 1.875 3 0.875 ...
##  $ x4    : num  2.33 1.67 1 2.67 2.67 ...
##  $ x5    : num  5.75 3 1.75 4.5 4 3 6 4.25 5.75 5 ...
##  $ x6    : num  1.286 1.286 0.429 2.429 2.571 ...
##  $ x7    : num  3.39 3.78 3.26 3 3.7 ...
##  $ x8    : num  5.75 6.25 3.9 5.3 6.3 6.65 6.2 5.15 4.65 4.55 ...
##  $ x9    : num  6.36 7.92 4.42 4.86 5.92 ...

Esta inspección confirma la presencia de variables categóricas (por ejemplo, school) y variables numéricas correspondientes a los indicadores observados, lo cual resulta fundamental para la correcta definición del modelo de medición y de un análisis multigrupo posterior.

3.0.4 Nuestro data frame en R

datosCompleto <- lavaan::HolzingerSwineford1939
attach(datosCompleto)

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

dat <- datosCompleto[7:15]
attach(dat)
head(dat,4) 
x1 x2 x3 x4 x5 x6 x7 x8 x9
3.333333 7.75 0.375 2.333333 5.75 1.2857143 3.391304 5.75 6.361111
5.333333 5.25 2.125 1.666667 3.00 1.2857143 3.782609 6.25 7.916667
4.500000 5.25 1.875 1.000000 1.75 0.4285714 3.260870 3.90 4.416667
5.333333 7.75 3.000 2.666667 4.50 2.4285714 3.000000 5.30 4.861111

4 Ejemplo: algunos análisis exploratorios

4.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
## x1    1 301 4.94 1.17   5.00    4.96 1.24 0.67  8.50  7.83 -0.25     0.31 0.07
## x2    2 301 6.09 1.18   6.00    6.02 1.11 2.25  9.25  7.00  0.47     0.33 0.07
## x3    3 301 2.25 1.13   2.12    2.20 1.30 0.25  4.50  4.25  0.38    -0.91 0.07
## x4    4 301 3.06 1.16   3.00    3.02 0.99 0.00  6.33  6.33  0.27     0.08 0.07
## x5    5 301 4.34 1.29   4.50    4.40 1.48 1.00  7.00  6.00 -0.35    -0.55 0.07
## x6    6 301 2.19 1.10   2.00    2.09 1.06 0.14  6.14  6.00  0.86     0.82 0.06
## x7    7 301 4.19 1.09   4.09    4.16 1.10 1.30  7.43  6.13  0.25    -0.31 0.06
## x8    8 301 5.53 1.01   5.50    5.49 0.96 3.05 10.00  6.95  0.53     1.17 0.06
## x9    9 301 5.37 1.01   5.42    5.37 0.99 2.78  9.25  6.47  0.20     0.29 0.06

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)
##        x1               x2              x3              x4       
##  Min.   :0.6667   Min.   :2.250   Min.   :0.250   Min.   :0.000  
##  1st Qu.:4.1667   1st Qu.:5.250   1st Qu.:1.375   1st Qu.:2.333  
##  Median :5.0000   Median :6.000   Median :2.125   Median :3.000  
##  Mean   :4.9358   Mean   :6.088   Mean   :2.250   Mean   :3.061  
##  3rd Qu.:5.6667   3rd Qu.:6.750   3rd Qu.:3.125   3rd Qu.:3.667  
##  Max.   :8.5000   Max.   :9.250   Max.   :4.500   Max.   :6.333  
##        x5              x6               x7              x8        
##  Min.   :1.000   Min.   :0.1429   Min.   :1.304   Min.   : 3.050  
##  1st Qu.:3.500   1st Qu.:1.4286   1st Qu.:3.478   1st Qu.: 4.850  
##  Median :4.500   Median :2.0000   Median :4.087   Median : 5.500  
##  Mean   :4.341   Mean   :2.1856   Mean   :4.186   Mean   : 5.527  
##  3rd Qu.:5.250   3rd Qu.:2.7143   3rd Qu.:4.913   3rd Qu.: 6.100  
##  Max.   :7.000   Max.   :6.1429   Max.   :7.435   Max.   :10.000  
##        x9       
##  Min.   :2.778  
##  1st Qu.:4.750  
##  Median :5.417  
##  Mean   :5.374  
##  3rd Qu.:6.083  
##  Max.   :9.250

Otra tabla de frecuencias:

# Genera la tablas usando dplyr and tidyr y kable
dat %>% 
  select(x1:x9) %>% 
  gather("Variable", "value") %>% 
  group_by(Variable) %>% 
  summarise(Mean=mean(value, na.rm=TRUE), 
            SD=sd(value, na.rm=TRUE), 
            min=min(value, na.rm=TRUE), 
            max=max(value, na.rm=TRUE), 
            '% Perdidos'=100*length(which(is.na(value)))/n()) %>% 
  kable(digits=2, format="pandoc", caption="Tabla 1: Estadisticos descriptivos para las variables observadas")
Table 4.1: Tabla 1: Estadisticos descriptivos para las variables observadas
Variable Mean SD min max % Perdidos
x1 4.94 1.17 0.67 8.50 0
x2 6.09 1.18 2.25 9.25 0
x3 2.25 1.13 0.25 4.50 0
x4 3.06 1.16 0.00 6.33 0
x5 4.34 1.29 1.00 7.00 0
x6 2.19 1.10 0.14 6.14 0
x7 4.19 1.09 1.30 7.43 0
x8 5.53 1.01 3.05 10.00 0
x9 5.37 1.01 2.78 9.25 0

4.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.

4.0.3 Datos perdidos por columna

missings <- colSums(is.na(dat)) 
missings
## x1 x2 x3 x4 x5 x6 x7 x8 x9 
##  0  0  0  0  0  0  0  0  0
summary(missings) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##       0       0       0       0       0       0

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

mydata <- dat[ , missings<15]
names(mydata)
## [1] "x1" "x2" "x3" "x4" "x5" "x6" "x7" "x8" "x9"

4.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 TRUE TRUE TRUE TRUE TRUE
sum(faltante)
## [1] 301

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 301. El porcentaje de datos ausentes es 0%:

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

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.

5 Especificación del modelo

5.0.1 El modelo teórico

Un modelo CFA que se suele propuesto para estas 9 variables consta de tres variables latentes (o factores), cada una con tres indicadores:

  1. Un factor visual (visual) medido por 3 variables: x1, x2 y x3.

  2. Un factor textual (textual) medido por 3 variables: x4, x5 y x6.

  3. Un factor de velocidad (speed) medido por 3 variables: x7, x8 y x9.

La Figura 5.1 contiene una representación gráfica del modelo de tres factores.

**Modelo CFA para los datos `HolzingerSwineford1939`**

Figure 5.1: Modelo CFA para los datos HolzingerSwineford1939

5.0.2 El modelo en R

Una sintaxis de modelo lavaan completa es simplemente una combinación de estos tipos de fórmulas, encerradas entre comillas simples.

modelo <- ' 
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9 
'

En este ejemplo, la sintaxis del modelo sólo contiene tres definiciones de variables latentes. En particular,

  • El operador =~ indica una relación de medición, es decir, que un factor latente explica un conjunto de variables observadas.

  • Las variables a la izquierda de =~ representan constructos latentes.

  • Las variables a la derecha representan indicadores observados.

Por ejemplo, la expresión:

visual =~ x1 + x2 + x3

indica que el factor latente visual se mide a través de los ítems x1, x2 y x3. Las cargas factoriales asociadas a estas relaciones se estiman a partir de los datos, salvo aquellas que se fijan para garantizar la identificabilidad del modelo (por ejemplo, fijando una carga factorial a 1 en cada factor).

6 Tipos de parámetros del modelo

6.0.1 Explicación

  1. En el contexto del análisis factorial confirmatorio (CFA) con el paquete lavaan en R, el número de parámetros en el output del modelo depende de las especificaciones del modelo y los datos utilizados.

  2. El modelo que se ha indicado para los datos HolzingerSwineford1939 especifica tres factores latentes (Visual, Textual, Speed) cada uno con tres indicadores.

  3. En este sentido, identificamos dos tipos de parámetros:

  • Parámetros de medidas.

  • Parámetros estructurales.

  1. En las siguientes secciones explicaremos cada uno de estos tipos.

6.0.2 Parámetros de medidas

En un modelo CFA típico, los parámetros de medidas que se quieren estimar incluyen (véase la Figura 6.1):

1. Cargas Factoriales.

Las relaciones entre los factores latentes y sus indicadores.

\[\lambda_1, \quad \lambda_2, \quad \lambda_3, \quad \lambda_4, \quad \lambda_5, \quad \lambda_6, \quad \lambda_7, \quad \lambda_8, \quad \lambda_9\]

2. Interceptos de los Factores Latentes.

\[\tau_1, \quad \tau_2, \quad \tau_3, \quad \tau_4, \quad \tau_5, \quad \tau_6, \quad \tau_7, \quad \tau_8, \quad \tau_9\] 3. Varianzas de los Errores de Medición.

Varianzas de los términos de error asociados a cada indicador.

\[V(\varepsilon_1), \quad V(\varepsilon_2), \quad V(\varepsilon_3), \quad V(\varepsilon_4), \quad V(\varepsilon_5), \quad V(\varepsilon_6), \quad V(\varepsilon_7), \quad V(\varepsilon_8), \quad V(\varepsilon_9)\]

6.0.3 Parámetros estructurales

En un modelo CFA típico, los parámetros estructurales que se quieren estimar incluyen (véase la Figura 6.1):

4. La media de los factores.

\[\mu_1, \quad \mu_2, \quad \mu_3\]

5. Varianzas de los Factores Latentes.

Varianzas de cada factor.

\[\psi_{11}, \quad \psi_{22}, \quad \psi_{33}\]

6. Covarianzas de los Factores Latentes.

Covarianzas entre los factores.

\[\psi_{12}, \quad \psi_{13}, \quad \psi_{23}\]

6.0.4 Resumen gráfico de los tipos de parámetros

**Tipos de parámetros del modelo CFA**

Figure 6.1: Tipos de parámetros del modelo CFA

7 Estimaciones mostradas en summary() y en los diagramas SEM

Carga factorial no estandarizada

En un modelo CFA/SEM, la carga factorial estandarizada se define como:

\[ \lambda_{\text{std}} = \lambda_{\text{est}} \cdot \frac{\sigma_{\eta}}{\sigma_x}, \]

donde:

  • \(\lambda_{\text{est}}\) es la carga no estandarizada,

  • \(\sigma_{\eta}\) es la desviación estándar del factor latente y

  • \(\sigma_x\) es la desviación estándar del indicador observado.

Nota importante

Por defecto, la función summary() de lavaan presenta estimaciones no estandarizadas (columna Estimate). Estas estimaciones reflejan directamente el esquema de identificación del modelo, en el cual una carga factorial por factor suele fijarse en 1 (por ejemplo, x1 = 1, x4 = 1, x7 = 1) con el fin de definir la escala de las variables latentes.

En contraste, cuando se utiliza semPaths(..., what = "std", whatLabels = "std") del paquete semPlot, el diagrama SEM muestra coeficientes estandarizados. En este caso, las cargas factoriales fijadas a 1 en la métrica original no permanecen iguales a 1, ya que la estandarización transforma los parámetros. Por tanto, aun cuando \(\lambda_{\text{est}} = 1\), si \(\sigma_{\eta} \neq \sigma_x\), se obtiene necesariamente que

\[ \lambda_{\text{std}} \neq 1. \]

Esto explica por qué en la salida de summary() se van a observar cargas iguales a 1, mientras que en los diagramas estandarizados dichas cargas van tomar valores distintos (si no se escriben los argumentos apropiados).

Regla práctica

  • Estimaciones no estandarizadas \(\lambda_{\text{est}}\): summary() \(\Longleftrightarrow\) semPaths(..., what = "est")

  • Estimaciones estandarizadas \(\lambda_{\text{std}}\): summary(..., standardized = TRUE) \(\Longleftrightarrow\) semPaths(..., what = "std")

En este capítulo, los diagramas SEM se presentan utilizando estimaciones no estandarizadas, de modo que las cargas fijadas en \(\lambda = 1\) se mantengan explícitas y reflejen correctamente el esquema de identificación del modelo.

8 Estimación del modelo con lavaan::cfa

8.0.1 Output de cfa: ejecución

Podemos ajustar el modelo como sigue:

CFA <- lavaan::cfa(modelo, data=dat)
CFA
## lavaan 0.6-19 ended normally after 35 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000

8.0.2 Output de cfa: gráfico del modelo con R

1. El diagrama básico.

semPaths(CFA, 
         what = "path",    #Muestra las rutas con cargas, regresiones, covarianzas     
         #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
         #what = "est",    #Muestra las estimaciones no estandarizadas de las rutas 
         #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
         #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
         #what = "model",  #Muestra una representación gral del modelo
         #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
         #what = "par",    #Muestra todos los parámetros estimados del modelo
         #what = "eq",     #Muestra las ecuaciones estructurales del modelo 
         
         layout = "circle",   #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         
         title = FALSE,       #No muestra el título del gráfico
         
         edge.color = "red",  #Establece el color de los bordes (aristas) en negro
         edge.label.cex = 1   #Tamaño de las cargas factoriales
         )

2. Se puede visualizar el modelo con nodos personalizados.

semPaths(CFA, 
        what = "path",    #Muestra las rutas con cargas, regresiones, covarianzas     
        #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
        #what = "est",    #Muestra las estimaciones no estandarizadas de las rutas
        #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
        #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
        #what = "model",  #Muestra una representación gral del modelo
        #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
        #what = "par",    #Muestra todos los parámetros estimados del modelo
        #what = "eq",     #Muestra las ecuaciones estructurales del modelo
        
        style = "lisrel", #Usa un estilo predefinido similar al estilo LISREL
         #style = "ram":   #Estilo de RAM (Reticular Action Model), común en gráficos SEM
         #style = "mx":    #Estilo de Mx,  herramienta de SEM
         #style = "eqs":   #Estilo similar al software EQS

         #layout = "tree",   #Dispone nodos en una estructura jerárquica similar a un árbol
         #layout="tree2",    #Parecida a la anterior
         layout="circle",    #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         #layout = "spring", #Minimiza fuerzas de repulsión y atracción entre nodos
         #layout = "lgl",    #Algoritmo "Large Graph Layout" (útil para gráficos grandes)
         #layout = "kamada",      #Algorit. Kamada-Kawai para disposición basada en energía
         #layout = "fruchterman", #Algoritmo Fruchterman-Reingold (disposición por fuerzas)
        
        title = FALSE,             #No muestra el título del gráfico
        
        edge.color = "black",      #Establece el color de los bordes (aristas) en negro
        edge.label.cex = 1,        #Tamaño de las cargas factoriales
        
        #node.color = "blue",       #Establece el color de fondo de los nodos
        node.label.cex = 1.5,      #Tamaño del texto de las etiquetas dentro de los nodos.
        #node.shape = "rectangle", #Establece la forma de los nodos como rectángulos
        
        curvePivot=TRUE,           #Conexiones entre las variables observadas
        label.prop = 1,
        
        color = list(
                     lat = "orange",    #Color de las variables latentes
                     man = "lightgreen" #Color de las variables observadas
                     )
        )

3. Se puede visualizar el modelo con otras opciones personalizadas.

semPaths(CFA,
         #what = "path",   #Muestra las rutas con cargas, regresiones, covarianzas     
         #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
         #what = "est",    #Muestra las estimaciones no estandarizadas de las rutas
         #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
         #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
         #what = "model",  #Muestra una representación gral del modelo
         #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
         #what = "par",    #Muestra todos los parámetros estimados del modelo
         what = "eq",      #Muestra las ecuaciones estructurales del modelo 
         
         whatLabels ="est",   #Muestra estimaciones no estandarizadas de los parámetros
         #whatLabels ="std":  #Muestra estimaciones estandarizadas de los parámetros
         #whatLabels ="name": #Muestra los nombres de las relaciones o parámetros
         #whatLabels ="none": #No muestra ninguna etiqueta en las aristas
         #whatLabels ="eq":   #Muestra etiquetas de ecuaciones (usualmente en SEM).
         #whatLabels ="both": #Muestra estimaciones estandarizadas y no estandarizadas
          
         style = "lisrel", #Usa un estilo predefinido similar al estilo LISREL
         #style = "ram":   #Estilo de RAM (Reticular Action Model), común en gráficos SEM
         #style = "mx":    #Estilo de Mx,  herramienta de SEM
         #style = "eqs":   #Estilo similar al software EQS

         #layout = "tree",   #Dispone nodos en una estructura jerárquica similar a un árbol
         layout="tree2",     #Parecida a la anterior
         #layout="circle",   #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         #layout = "spring", #Minimiza fuerzas de repulsión y atracción entre nodos
         #layout = "lgl",    #Algorit. "Large Graph Layout" (útil para gráficos grandes)
         #layout = "kamada",      #Algorit. Kamada-Kawai para disposición basada en energía
         #layout = "fruchterman", #Algoritmo Fruchterman-Reingold (disposición por fuerzas)

         #rotation = 1, #Rotación de todo el diagrama
         rotation=2, 
         #rotation=3,
         
         nCharNodes = 0, #0=ajustar al número máximo de caracteres dentro de las latentes
         sizeMan = 8,    #Tamaño de los nodos que representan variables manifiestas
         sizeLat = 9,    #Tamaño de los nodos que representan variables latentes
         sizeInt = 1,    #Tamaño de los nodos que representan variables interiores
         nCharEdges = 3, #Número máximo de caracteres para etiquetas de cargas factoriales
         
         edge.label.cex = 1,      #Tamaño de las cargas factoriales
         
         #freeStyle = "blue",     #Parámetros fijos son azules
         fixedStyle = c("red",3), #Parámetros fijos son rojos y de tamaño 3
   
         #curvePivot=TRUE,  #Conexiones entre las variables observada
         intercepts=TRUE,   #Muestra u oculta los nodos de interceptos (medias) del modelo
         residuals=FALSE,   #Muestra las flechas asociadas a los términos residuales (errores)
         exoCov=FALSE,      #Muestra las covarianzas entre variables exógenas (latentes, etc.)
         
         color = list(
           lat = "orange",    #Color de las variables latentes
           man = "lightgreen" #Color de las variables observadas
           ) 
         )

8.0.3 Output de cfa: observaciones

  1. La función cfa es una función específica para establecer modelos de análisis factorial confirmatorio.

  2. El primer argumento es el modelo especificado por el usuario.

  3. El segundo argumento es el conjunto de datos que contiene las variables observadas.

  4. Los interceptos \(\tau\) de los factores representan las medias de las variables observadas (x1, x2, x3, x4, x5, x6, x7, x8, x9) cuando los factores latentes (Visual, Textual, Speed) tienen un valor de cero.

9 Output de cfa: primera parte

9.0.1 Gráfica de la primera parte

En la Figura 9.1 se resalta la primera parte del output de `lavaan.

**Primera parte del output de `lavaan` (información general)**

Figure 9.1: Primera parte del output de lavaan (información general)

9.0.2 Información general del output

1. El modelo finalizó normalmente después de 35 iteraciones.

Este mensaje indica que el proceso de estimación del modelo finalizó correctamente después de 35 iteraciones. Esto significa que el algoritmo de optimización alcanzó una solución estable dentro del número especificado de iteraciones.

2. El estimador utilizado fue el máximo verosimilitud (ML).

ML significa Maximum Likelihood (Máxima Verosimilitud). Es el estimador utilizado para ajustar el modelo. El estimador de máxima verosimilitud es uno de los métodos más comunes para estimar los parámetros del modelo en análisis factorial confirmatorio, ya que se basa en la suposición de que los datos siguen una distribución normal multivariada.

3. El método de optimización fue NLMINB.

  • La abreviatura NLMINB se refiere a “Nonlinear MINimization using Bounds”, que significa “Minimización no lineal usando límites”.

  • Específicamente, NLMINB se refiere al método de optimización usado para encontrar los valores óptimos de los parámetros del modelo.

  • NLMINB es un algoritmo de optimización que es robusto y eficiente, especialmente para problemas de minimización no linealque tienen restricciones en los parámetros o son de naturaleza no lineal.

  • En secciones siguientes, se describirán brevemente otros métodos alternativos de optimización.

4. El modelo tiene 21 parámetros.

Esta línea indica que el modelo tiene un total de 21 parámetros a estimar. Esto incluye cargas factoriales, varianzas, covarianzas y términos de error, entre otros. En secciones siguientes se va a detallar más al respecto.

5. Se utilizaron 301 observaciones en el ajuste del modelo.

Esta sección muestra que se utilizaron 301 observaciones (o casos) para ajustar el modelo. Es el tamaño de la muestra de datos.

10 Output de cfa: estimadores

10.0.1 Otros estimadores en lavaan (aparte de ML)

1. MLR (Maximum Likelihood with Robust Standard Errors).

  • Proporciona errores estándar robustos y una prueba chi-cuadrado robusta.

  • Es útil cuando los datos no cumplen con la suposición de normalidad multivariada.

2. MLM (Maximum Likelihood with Robust Standard Errors).

  • Similar a MLR pero usa la corrección de Satorra-Bentler para el estadístico chi-cuadrado.

  • Es adecuado para datos que no son normales pero que tienen desviaciones leves de la normalidad.

3. MLF (Maximum Likelihood with Robust Standard Errors and a Scaling Factor).

Similar a MLR pero incluye un factor de escalado adicional para ajustar los errores estándar.

4. WLS (Weighted Least Squares).

Utiliza las matrices de covarianza y asimetría para estimar los parámetros. Es especialmente útil para datos categóricos y ordinales.

5. WLSM (Weighted Least Squares Mean and Variance adjusted).

  • Una variante del WLS que ajusta tanto la media como la varianza, proporcionando una corrección robusta.

  • También es adecuado para datos categóricos y ordinales.

6. WLSMV (Weighted Least Squares Mean and Variance adjusted).

  • Similar a WLSM pero con una corrección adicional para la media y la varianza.

  • Es ampliamente utilizado para modelos con datos categóricos.

7. ULS (Unweighted Least Squares).

  • Minimiza las discrepancias sin ponderar las observaciones.

  • Puede ser útil en casos donde se prefieren métodos no ponderados.

8. ULSM (Unweighted Least Squares Mean and Variance adjusted).

Similar a ULS pero ajusta la media y la varianza.

9. DWLS (Diagonally Weighted Least Squares).

  • Similar a WLS pero usa solo los elementos diagonales de la matriz de covarianza.

  • Es más eficiente computacionalmente y adecuado para datos con variables categóricas.

10. PML (Pseudomaximum Likelihood).

Utilizado principalmente para datos de conteo o cuando se tiene información incompleta.

11. Bayes (Bayesian Estimation).

  • Utiliza métodos bayesianos para la estimación de parámetros.

  • Es útil cuando se desea incorporar información a priori o cuando los modelos son complejos y otros métodos fallan en converger.

10.0.2 Otros estimadores en lavaan (ejemplos)

1. A manera de ejemplo, para ajustar el modelo utilizando el estimador WLSMV, se ejecuta:

fit <- lavaan::cfa(modelo, data = dat, estimator = "WLSMV")
fit
## lavaan 0.6-19 ended normally after 44 iterations
## 
##   Estimator                                       DWLS
##   Optimization method                           NLMINB
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                               Standard      Scaled
##   Test Statistic                                43.902      79.342
##   Degrees of freedom                                24          24
##   P-value (Chi-square)                           0.008       0.000
##   Scaling correction factor                                  0.598
##   Shift parameter                                            5.867
##     simple second-order correction

2. A manera de ejemplo, para ajustar el modelo utilizando el estimador Bayes, se ejecuta:

fit <- blavaan::bcfa(modelo, data = dat, estimator = "Bayes", burnin = 100, sample = 1000)
fit
## 
## SAMPLING FOR MODEL 'stanmarg' NOW (CHAIN 1).
## Chain 1: 
## Chain 1: Gradient evaluation took 0.001585 seconds
## Chain 1: 1000 transitions using 10 leapfrog steps per transition would take 15.85 seconds.
## Chain 1: Adjust your expectations accordingly!
## Chain 1: 
## Chain 1: 
## Chain 1: WARNING: There aren't enough warmup iterations to fit the
## Chain 1:          three stages of adaptation as currently configured.
## Chain 1:          Reducing each adaptation stage to 15%/75%/10% of
## Chain 1:          the given number of warmup iterations:
## Chain 1:            init_buffer = 15
## Chain 1:            adapt_window = 75
## Chain 1:            term_buffer = 10
## Chain 1: 
## Chain 1: Iteration:    1 / 1100 [  0%]  (Warmup)
## Chain 1: Iteration:  101 / 1100 [  9%]  (Sampling)
## Chain 1: Iteration:  210 / 1100 [ 19%]  (Sampling)
## Chain 1: Iteration:  320 / 1100 [ 29%]  (Sampling)
## Chain 1: Iteration:  430 / 1100 [ 39%]  (Sampling)
## Chain 1: Iteration:  540 / 1100 [ 49%]  (Sampling)
## Chain 1: Iteration:  650 / 1100 [ 59%]  (Sampling)
## Chain 1: Iteration:  760 / 1100 [ 69%]  (Sampling)
## Chain 1: Iteration:  870 / 1100 [ 79%]  (Sampling)
## Chain 1: Iteration:  980 / 1100 [ 89%]  (Sampling)
## Chain 1: Iteration: 1090 / 1100 [ 99%]  (Sampling)
## Chain 1: Iteration: 1100 / 1100 [100%]  (Sampling)
## Chain 1: 
## Chain 1:  Elapsed Time: 0.181 seconds (Warm-up)
## Chain 1:                1.881 seconds (Sampling)
## Chain 1:                2.062 seconds (Total)
## Chain 1: 
## 
## SAMPLING FOR MODEL 'stanmarg' NOW (CHAIN 2).
## Chain 2: 
## Chain 2: Gradient evaluation took 0.000133 seconds
## Chain 2: 1000 transitions using 10 leapfrog steps per transition would take 1.33 seconds.
## Chain 2: Adjust your expectations accordingly!
## Chain 2: 
## Chain 2: 
## Chain 2: WARNING: There aren't enough warmup iterations to fit the
## Chain 2:          three stages of adaptation as currently configured.
## Chain 2:          Reducing each adaptation stage to 15%/75%/10% of
## Chain 2:          the given number of warmup iterations:
## Chain 2:            init_buffer = 15
## Chain 2:            adapt_window = 75
## Chain 2:            term_buffer = 10
## Chain 2: 
## Chain 2: Iteration:    1 / 1100 [  0%]  (Warmup)
## Chain 2: Iteration:  101 / 1100 [  9%]  (Sampling)
## Chain 2: Iteration:  210 / 1100 [ 19%]  (Sampling)
## Chain 2: Iteration:  320 / 1100 [ 29%]  (Sampling)
## Chain 2: Iteration:  430 / 1100 [ 39%]  (Sampling)
## Chain 2: Iteration:  540 / 1100 [ 49%]  (Sampling)
## Chain 2: Iteration:  650 / 1100 [ 59%]  (Sampling)
## Chain 2: Iteration:  760 / 1100 [ 69%]  (Sampling)
## Chain 2: Iteration:  870 / 1100 [ 79%]  (Sampling)
## Chain 2: Iteration:  980 / 1100 [ 89%]  (Sampling)
## Chain 2: Iteration: 1090 / 1100 [ 99%]  (Sampling)
## Chain 2: Iteration: 1100 / 1100 [100%]  (Sampling)
## Chain 2: 
## Chain 2:  Elapsed Time: 0.247 seconds (Warm-up)
## Chain 2:                1.839 seconds (Sampling)
## Chain 2:                2.086 seconds (Total)
## Chain 2: 
## 
## SAMPLING FOR MODEL 'stanmarg' NOW (CHAIN 3).
## Chain 3: 
## Chain 3: Gradient evaluation took 0.000141 seconds
## Chain 3: 1000 transitions using 10 leapfrog steps per transition would take 1.41 seconds.
## Chain 3: Adjust your expectations accordingly!
## Chain 3: 
## Chain 3: 
## Chain 3: WARNING: There aren't enough warmup iterations to fit the
## Chain 3:          three stages of adaptation as currently configured.
## Chain 3:          Reducing each adaptation stage to 15%/75%/10% of
## Chain 3:          the given number of warmup iterations:
## Chain 3:            init_buffer = 15
## Chain 3:            adapt_window = 75
## Chain 3:            term_buffer = 10
## Chain 3: 
## Chain 3: Iteration:    1 / 1100 [  0%]  (Warmup)
## Chain 3: Iteration:  101 / 1100 [  9%]  (Sampling)
## Chain 3: Iteration:  210 / 1100 [ 19%]  (Sampling)
## Chain 3: Iteration:  320 / 1100 [ 29%]  (Sampling)
## Chain 3: Iteration:  430 / 1100 [ 39%]  (Sampling)
## Chain 3: Iteration:  540 / 1100 [ 49%]  (Sampling)
## Chain 3: Iteration:  650 / 1100 [ 59%]  (Sampling)
## Chain 3: Iteration:  760 / 1100 [ 69%]  (Sampling)
## Chain 3: Iteration:  870 / 1100 [ 79%]  (Sampling)
## Chain 3: Iteration:  980 / 1100 [ 89%]  (Sampling)
## Chain 3: Iteration: 1090 / 1100 [ 99%]  (Sampling)
## Chain 3: Iteration: 1100 / 1100 [100%]  (Sampling)
## Chain 3: 
## Chain 3:  Elapsed Time: 0.196 seconds (Warm-up)
## Chain 3:                1.897 seconds (Sampling)
## Chain 3:                2.093 seconds (Total)
## Chain 3: 
## Computing post-estimation metrics (including lvs if requested)...
## blavaan 0.5.8 ended normally after 1000 iterations
## 
##   Estimator                                      BAYES
##   Optimization method                             MCMC
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
##   Statistic                                 MargLogLik         PPP
##   Value                                      -3805.507       0.000

10.0.3 Elección del Estimador

La elección del estimador depende de las características de nuestros datos y de las hipótesis subyacentes en tu modelo. Aquí hay algunas pautas generales:

  1. ML (Maximum Likelihood): Utilizado comúnmente cuando se asume que los datos siguen una distribución normal multivariada.

  2. MLR, MLM, MLF: Utilizados cuando los datos no cumplen con la normalidad multivariada.

  3. WLS, WLSM, WLSMV, DWLS: Preferidos para datos categóricos u ordinales.

  4. ULS, ULSM: Utilizados cuando se prefieren métodos no ponderados.

  5. Bayes: Útil para modelos complejos o cuando se desea incorporar información a priori.

Cada estimador tiene sus propias ventajas y desventajas, por lo que es importante considerar las características de tus datos y el objetivo de tu análisis al seleccionar el estimador adecuado.

11 Output de cfa: métodos de optimización

11.0.1 Características de NLMINB

1. Manejo de Restricciones.

NLMINB puede manejar tanto restricciones de igualdad como de desigualdad en los parámetros, lo cual es útil en muchos problemas prácticos donde ciertos parámetros deben mantenerse dentro de ciertos límites.

2. Robustez.

Es un algoritmo robusto, lo que significa que puede converger en una solución óptima en una amplia variedad de problemas, incluyendo aquellos que son difíciles de resolver para otros algoritmos de optimización.

3. Convergencia.

Funciona bien en problemas de optimización donde otros métodos podrían no converger, especialmente en presencia de restricciones complicadas.

11.0.2 Otros método de optimización en lavaan (aparte de NLMINB)

Además de NLMINB, lavaan ofrece otros métodos de optimización. Aquí hay una lista de algunas de las opciones y sus características principales:

  1. BFGS: Método Broyden-Fletcher-Goldfarb-Shanno, un algoritmo quasi-Newton que es adecuado para problemas suaves y bien comportados. No maneja restricciones explícitas tan fácilmente como NLMINB.

  2. L-BFGS-B: Una variante del BFGS que permite restricciones en los parámetros (cotas inferiores y superiores), útil en problemas donde los parámetros necesitan estar dentro de ciertos rangos.

  3. CG: Gradiente conjugado, adecuado para problemas grandes y dispersos. Es menos intensivo en memoria comparado con BFGS.

  4. SANN: Recocido simulado (Simulated Annealing), un algoritmo de optimización global que puede evitar mínimos locales, aunque es menos eficiente para encontrar soluciones precisas.

  5. Nelder-Mead: Método simplex, útil para problemas sin restricciones no lineales. Es robusto, pero puede ser menos eficiente en problemas de gran escala.

  6. solnp: Método de optimización no lineal con restricciones, útil en problemas que tienen tanto restricciones lineales como no lineales.

11.0.3 Otros método de optimización en lavaan (ejemplos)

1. A manera de ejemplo, para ajustar el modelo utilizando el método BFGS, se ejecuta:

fit <- lavaan::cfa(modelo, data = dat, optim.method = "BFGS")
fit
## lavaan 0.6-19 ended normally after 86 iterations
## 
##   Estimator                                         ML
##   Optimization method                             BFGS
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000

2. A manera de ejemplo, para ajustar el modelo utilizando el método solnp, se ejecuta:

fit <- lavaan::cfa(modelo, data = dat, optim.method = "solnp")
fit

12 Output de cfa: interceptos

12.0.1 Interpretación de los interceptos en lavaan

El paquete lavaan sigue ciertas convenciones y suposiciones en el análisis CFA que afectan la estimación y conteo de los parámetros:

1. Modelo en Escala Estándar (Standardized Solution).

  • En la solución estándar, las medias de los factores latentes se fijan a cero (\(\alpha_1=0\), \(\alpha_2=0\), \(\alpha_3=0\)).

  • Esto implica que las medias de las variables observadas se explican únicamente en términos de sus interceptos y no se requieren estimaciones adicionales de los interceptos.

2. Identificación del Modelo.

  • Para asegurar que el modelo sea identificable, a menudo se fijan ciertos parámetros a valores conocidos (por ejemplo, fijar una carga factorial a 1 y los interceptos de los factores a cero).

  • En consecuencia, los interceptos de los factores no se estiman de manera explícita en el modelo porque ya se asumen como parte del ajuste global del modelo.

12.0.2 Total de parámetros en cada grupo

Para explicar por qué el output de lavaan::cfa muestra 21 parámetros, debemos desglosar los componentes del modelo y los parámetros que se estiman.

Vamos a enumerar los parámetros para el modelo especificado:

1. Cargas Factoriales.

Cada indicador tiene una carga factorial para el factor al que está asignado:

  • Visual: x1, x2, x3.

  • Textual: x4, x5, x6.

  • Speed: x7, x8, x9.

Cada uno de estos indicadores tiene una carga factorial, sumando un total de 9 cargas factoriales.

2. Interceptos de los Factores Latentes.

Cada indicador tiene asociado un intecepto para x1, x2, x3, x4, x5, x6, x7, x8 y x9. Entonces, en total serían 9 interceptos.

3. Varianzas de los Errores de Medición:

Cada indicador tiene una varianza de error asociada para x1, x2, x3, x4, x5, x6, x7, x8 y x9. Esto suma 9 parámetros.

4. Medias de los factores.

Cada factor tiene asociada una media:

  • Media de Visual.

  • Media de Textual.

  • media de Speed.

Es decir, serían 3 parámetros.

5. Varianzas de los Factores Latentes.

Hay tres factores latentes (Visual, Textual, Speed), y se estima una varianza para cada uno:

  • Varianza de Visual.

  • Varianza de Textual.

  • Varianza de Speed.

Esto suma 3 parámetros.

6. Covarianzas entre los Factores Latentes.

Hay covarianzas entre cada par de factores latentes. Para tres factores, esto se calcula como \({3 \choose 2}=3\) covarianzas:

  • Covarianza de Visual-Textual.

  • Covarianza de Visual-Speed.

  • Covarianza de Textual-Speed.

Esto suma 3 parámetros.

12.0.3 Suma Total de Parámetros

Sumando todos los valores anteriores, tenemos (véase la Figura 12.1):

  1. Cargas factoriales: 9

  2. Interceptos de los Factores Latentes: 9

  3. Varianzas de los errores de medición: 9

  4. Medias de los factores: 3

  5. Varianzas de los factores: 3

  6. Covarianzas entre factores: 3

\[9 \;+\; 9\; +\; 9\; + \;3\; + \;3 \;+ \;3 \;=\; 36\]

En la Figura 12.1 se visualiza lo anterior.

**Total de parámetros en el modelo CFA no estándar**

Figure 12.1: Total de parámetros en el modelo CFA no estándar

12.0.4 Consideración de parámetros conocidos

  1. En muchos casos, uno de los indicadores para cada factor se fija a 1 para que el modelo sea identificable: \[\lambda_1\;=\; \lambda_4\;=\; \lambda_7\;=\; 1\]

  2. Esto significa que para cada factor, una de las cargas factoriales no se estima (ya que se fija). Dado que hay 3 factores, esto resta 3 parámetros del total

  3. Por defecto, el paquete lavaan estima un modelo en Escala Estándar. Por esta razón:

  • Las medias de los tres factores latentes se fijan a cero (o sea, debe restarse 3 parámetros del total):

\[\alpha_1 \;=\; \alpha_2 \;=\; \alpha_3 \;=\; 0\]

  • Las medias de las variables observadas se explican únicamente en términos de sus interceptos y no se requieren estimaciones adicionales de los interceptos (o sea, también debe restarse 9 parámetros del total):

\[\tau_1 \;=\; \tau_2 \;=\; \tau_3 \;=\; \tau_4 \;=\; \tau_5 \;=\; \tau_6 \;=\; \tau_7 \;=\; \tau_8 \;=\; \tau_9 \;=\; 0\]

  1. Entonces, restando estos 15 parámetros fijos, tenemos:

\[36\;−\;15\; =\; 21\]

  1. En la Figura 12.2 se visualiza lo anterior.
**Total de parámetros según `lavaan` (eliminando parámetros fijos)**

Figure 12.2: Total de parámetros según lavaan (eliminando parámetros fijos)

12.0.5 Conclusión: total definitivo de parámetros

  1. Los 21 parámetros en el output del modelo se distribuyen de la siguiente manera:
  • 6 cargas factoriales estimadas (3 factores x 3 indicadores, menos 3 fijas).

  • 0 interceptos.

  • 9 varianzas de los errores de medición.

  • 0 medias de los factores latentes.

  • 3 varianzas de los factores latentes.

  • 3 covarianzas entre los factores latentes.

  1. Esto da un total de 21 parámetros estimados en el modelo CFA utilizando los datos HolzingerSwineford1939 y el modelo especificado.

  2. En la Figura 12.3 se visualiza lo anterior.

**Número de parámetros según `lavaan`**

Figure 12.3: Número de parámetros según lavaan

13 Output de cfa: segunda parte

13.0.1 Model Test User Model en lavaan

En la Figura 12.3 se resalta la segunda parte del output de lavaan.

**Segunda parte del output de `lavaan` (`cfa`)**

Figure 13.1: Segunda parte del output de lavaan (cfa)

Estos resultados corresponden a una prueba de ajuste del modelo (Model Test). En el contexto de la prueba de ajuste del modelo (Model Test) en lavaan, las hipótesis nula y alternativa son las siguientes:

  • Hipótesis nula (H0): La hipótesis nula en este caso sería que el modelo propuesto se ajusta bien a los datos observados en la muestra. Esto significa que no hay diferencias significativas entre los datos observados y los datos esperados según el modelo.

  • Hipótesis alternativa (H1): La hipótesis alternativa sería que el modelo propuesto no se ajusta bien a los datos observados en la muestra. Esto implica que hay diferencias significativas entre los datos observados y los datos esperados según el modelo, lo que se traduce en un mal ajuste del modelo.

13.0.2 Intepretación: segunda parte

Aquí está el significado de cada uno de los elementos de la salida:

1. Test statistic (Estadístico de prueba).

Es el valor del estadístico de prueba (que tiene distribución chi-cuadrada) y calculado para evaluar el ajuste del modelo. Un valor alto generalmente indica un mal ajuste del modelo a los datos observados. En este caso, el valor es 85.306.

2.Degrees of freedom (Grados de libertad).

Representa el número de valores que son libres de variar una vez que ciertas restricciones son impuestas. En CFA, los grados de libertad se calculan como la diferencia entre el número de observaciones independientes (generalmente el número de entradas en la matriz de covarianza) y el número de parámetros estimados. En este caso, hay 24 grados de libertad.

3. P-value (Chi-square) (Valor p obtenido con la chi-cuadrada).

Es la probabilidad de obtener un valor del estadístico de prueba igual o más extremo que el valor observado, asumiendo que la hipótesis nula es verdadera. En el contexto de lavaan, un valor \(p\) bajo (\(< 0.05\)) generalmente indica un mal ajuste del modelo, lo que significa que los datos observados difieren significativamente de los datos esperados según el modelo. En este caso, el valor p es 0.000, lo que indica que el modelo no se ajusta bien a los datos, ya que la probabilidad de obtener un valor de estadístico de prueba igual o más extremo es muy baja.

14 Función summary de lavaan

14.0.1 summary: descripción

  1. Una vez que el modelo ha sido ajustado, la función summary proporciona un buen resumen del modelo ajustado.

  2. El argumento fit.measures=TRUE en la función summary indica que se desean incluir medidas de ajuste del modelo en el resumen del modelo.

14.0.2 summary: ejecución y output

Se ejecuta así:

summary(CFA, fit.measures=TRUE)
## lavaan 0.6-19 ended normally after 35 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        21
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000
## 
## Model Test Baseline Model:
## 
##   Test statistic                               918.852
##   Degrees of freedom                                36
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    0.931
##   Tucker-Lewis Index (TLI)                       0.896
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -3737.745
##   Loglikelihood unrestricted model (H1)      -3695.092
##                                                       
##   Akaike (AIC)                                7517.490
##   Bayesian (BIC)                              7595.339
##   Sample-size adjusted Bayesian (SABIC)       7528.739
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.092
##   90 Percent confidence interval - lower         0.071
##   90 Percent confidence interval - upper         0.114
##   P-value H_0: RMSEA <= 0.050                    0.001
##   P-value H_0: RMSEA >= 0.080                    0.840
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.065
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual =~                                           
##     x1                1.000                           
##     x2                0.554    0.100    5.554    0.000
##     x3                0.729    0.109    6.685    0.000
##   textual =~                                          
##     x4                1.000                           
##     x5                1.113    0.065   17.014    0.000
##     x6                0.926    0.055   16.703    0.000
##   speed =~                                            
##     x7                1.000                           
##     x8                1.180    0.165    7.152    0.000
##     x9                1.082    0.151    7.155    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual ~~                                           
##     textual           0.408    0.074    5.552    0.000
##     speed             0.262    0.056    4.660    0.000
##   textual ~~                                          
##     speed             0.173    0.049    3.518    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.549    0.114    4.833    0.000
##    .x2                1.134    0.102   11.146    0.000
##    .x3                0.844    0.091    9.317    0.000
##    .x4                0.371    0.048    7.779    0.000
##    .x5                0.446    0.058    7.642    0.000
##    .x6                0.356    0.043    8.277    0.000
##    .x7                0.799    0.081    9.823    0.000
##    .x8                0.488    0.074    6.573    0.000
##    .x9                0.566    0.071    8.003    0.000
##     visual            0.809    0.145    5.564    0.000
##     textual           0.979    0.112    8.737    0.000
##     speed             0.384    0.086    4.451    0.000

15 Output de summary: partes 1 y 2

15.0.1 Información general del modelo

  1. El modelo finalizó normalmente después de 35 iteraciones.

  2. El estimador utilizado fue el máximo verosimilitud (ML).

  3. El método de optimización fue NLMINB.

  4. El modelo tiene 21 parámetros.

  5. Se utilizaron 301 observaciones en el ajuste del modelo.

  6. En la Figura 16.1 se puede visualizar la parte No. 1 del output de lavaan::summary (es la misma que aparece en la Figura 9.1).

15.0.2 Prueba de ajuste del modelo (Model Test User Model)

  1. El estadístico de prueba es 85.306.

  2. El modelo tiene 24 grados de libertad.

  3. El valor p asociado al Chi-cuadrado es 0.000, lo que indica que el modelo no se ajusta bien a los datos (valor p significativamente menor que 0.05).

  4. En la Figura 16.1 se puede visualizar la parte No. 2 del output de lavaan::summary (es la misma que aparece en la Figura 13.1).

16 Output de summary: test modelo nulo

16.0.1 Test Baseline Model: Modelo nulo (Baseline Model)

  1. El Modelo Baseline (o modelo nulo) es un modelo muy restringido que asume que todas las variables observadas son independientes entre sí.

  2. Es decir, no hay correlaciones entre las variables.

  3. En este modelo, todas las covarianzas entre las variables observadas se establecen a cero.

16.0.2 Test Baseline Model: modelo nulo en R

Para ello se ejecuta el siguiente código:

model_null <- '
  x1 ~~ x1
  x2 ~~ x2
  x3 ~~ x3
  x4 ~~ x4
  x5 ~~ x5
  x6 ~~ x6
  x7 ~~ x7
  x8 ~~ x8
  x9 ~~ x9
'

# Ajustar el modelo nulo
fit_null <- cfa(model_null, data = dat)
fit_null
## lavaan 0.6-19 ended normally after 16 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         9
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                               918.852
##   Degrees of freedom                                36
##   P-value (Chi-square)                           0.000

16.0.3 Test Baseline Model: gráficar modelo nulo en R

Para ello, se puede ejecutar el siguiente código:

semPaths(fit_null, 
         what = "path",    #Muestra las rutas con cargas, regresiones, covarianzas     
         #what = "std",    #Muestra las estimaciones estandarizadas de las rutas 
         #what = "est",    #Muestra las estimaciones no estandarizadas de las rutas 
         #what = "col",    #Muestra matriz de varianzas-covarianzas de var. observadas
         #what = "mod",    #Muestra camino adicional que podría mejorar ajuste del modelo
         #what = "model",  #Muestra una representación gral del modelo
         #what = "all",    #Muestra todos elementos posibles (rutas y estimaciones)
         #what = "par",    #Muestra todos los parámetros estimados del modelo
         #what = "eq",     #Muestra las ecuaciones estructurales del modelo 
         
         layout = "tree",    #Dispone nodos en círculo (solo permitido si rotation= 1 o 3)
         
         title = FALSE,        #No muestra el título del gráfico
         
         edge.color = "Red", #Establece el color de los bordes (aristas) en negro
         sizeMan = 8,    #Tamaño de los nodos que representan variables manifiestas
         color = list(man = "lightgreen" #Color de las variables observadas
                     ) 
         )

16.0.4 Test Baseline Model: gráfico de parte No. 3

En la Figura 16.1 se resalta la parte No. 3 del output de lavaan::summary.
**Parte No. 3 del output de `lavaan::summary` (`Test Baseline Model`)**

Figure 16.1: Parte No. 3 del output de lavaan::summary (Test Baseline Model)

16.0.5 Test Baseline Model: hipótesis

1. La hipótesis nula (\(H_0\)) para el Model Test Baseline Model

Viene dada por:

\[H0: \;\text{El modelo nulo se ajusta bien a los datos}\]

Esto implica que las covarianzas entre las variables observadas no son significativamente diferentes de cero, es decir, que todas las variables observadas son independientes entre sí.

2. La hipótesis alternativa (\(H_1\))

Viene dad por:

\[H_1: \;\text{El modelo nulo no se ajusta bien a los datos}\] Esto implica que hay relaciones significativas entre las variables observadas, es decir, que las covarianzas entre las variables observadas son diferentes de cero.

16.0.6 Test Baseline Model: interpretaciones

1. Estadístico de Chi-Cuadrado (\(\chi^2\)).

Mide la discrepancia entre la matriz de covarianza observada y la matriz de covarianza estimada bajo el modelo nulo. En este caso, el valor del estadístico es de 918.852.

2. Grados de Libertad (df).

La distribución se ajsuta con 36 grados de libertad.

3. Valor P.

Indica si la discrepancia observada (estadístico \(\chi^2\)) es significativa. Dado que el valor \(p\) es menor que 0.05, se rechaza la hipótesis nula (\(H_0\)), indicando que el modelo nulo no se ajusta bien a los datos y que existen relaciones significativas entre las variables observadas.

17 Output de summary: user vs baseline

17.0.1 User vs Baseline: output de summary

En la Figura 17.1 se resalta la parte No. 4 del output de lavaan::summary.
**Parte No. 4 del output de `lavaan::summary` (`User vs Baseline`)**

Figure 17.1: Parte No. 4 del output de lavaan::summary (User vs Baseline)

17.0.2 User vs Baseline: descripción

  1. El User Model se refiere al modelo que el usuario ha especificado y que lavaan está analizando.

  2. El output User Model versus Baseline Model se refiere a la comparación entre el modelo especificado por el usuario (User Model) y el modelo de referencia, también conocido como modelo baseline o nulo (Baseline Model).

17.0.3 User vs Baseline: hipótesis

1. Hipótesis Nula (\(H_0\)).

  • La hipótesis nula (\(H_0\)) es que el modelo especificado por el usuario no se ajusta significativamente mejor que el modelo de referencia.

  • Es decir, no hay diferencia significativa entre el ajuste del modelo del usuario y el modelo nulo.

  • Matemáticamente, esto se podría expresar como:

\[H_0: \text{El User Model se ajusta significativamente mejor que el Baseline Model}\]

2. Hipótesis Alternativa (\(H_1\)).

  • La hipótesis alternativa (\(H_1\)) es que el modelo especificado por el usuario se ajusta significativamente mejor que el modelo de referencia.

  • Es decir, hay una diferencia significativa entre el ajuste del modelo del usuario y el modelo nulo.

  • Matemáticamente, esto se podría expresar como:

\[H_1: \text{El User Model se ajusta significativamente mejor que el Baseline Model}\]

17.0.4 User vs Baseline: CFI y TLI (generalidades)

  1. Esta comparación permite evaluar qué tan bien se ajusta el modelo propuesto por el usuario en comparación con un modelo muy simple que asume independencia completa entre las variables observadas.

  2. La comparación entre el User Model y el Baseline Model proporciona información valiosa sobre la adecuación del modelo propuesto por el usuario en relación con un modelo extremadamente simple.

  3. Esto se realiza utilizando diversos criterios de ajuste, como el Chi-cuadrado (\(\chi^2\)), el Comparative Fit Index (CFI), el Tucker-Lewis Index (TLI), entre otros.

  4. Si el modelo propuesto por el usuario se ajusta significativamente mejor que el modelo de referencia (por ejemplo, un Chi-cuadrado significativamente más bajo y/o valores más altos de CFI y TLI), indica que el modelo propuesto proporciona un mejor ajuste a los datos en comparación con el modelo de referencia.

  5. Esto sugiere que la estructura propuesta en el modelo del usuario es válida y representa la relación entre las variables de manera más precisa que el modelo nulo.

  6. Por otro lado, si el modelo propuesto por el usuario no se ajusta significativamente mejor que el modelo de referencia, podría indicar que el modelo propuesto no proporciona un mejor ajuste a los datos en comparación con el modelo nulo, lo que sugiere que la estructura propuesta puede no ser adecuada o que se necesitan ajustes adicionales para mejorar la adecuación del modelo.

17.0.5 User vs Baseline: CFI y TLI (interpretaciones)

1. Generalidad.

El Comparative Fit Index (CFI) y el Tucker-Lewis Index (TLI) son dos índices de ajuste comúnmente utilizados en el análisis factorial confirmatorio (CFA) para evaluar qué tan bien se ajusta un modelo especificado por el usuario a los datos observados en comparación con un modelo de referencia, como el modelo nulo o baseline. BAsado en los resultados encontrados (parte No. 4 del output), estos valores se puden interpretar de la siguiente manera:

2. Comparative Fit Index (CFI).

  • El CFI es un índice que evalúa qué tan bien se ajusta el modelo especificado por el usuario en comparación con el modelo nulo.

  • Un CFI cercano a 1 indica un buen ajuste del modelo, donde un valor de 1 indica un ajuste perfecto.

  • En general, un valor de CFI mayor a 0.90 se considera aceptable, aunque valores más cercanos a 0.95 o mayores indican un mejor ajuste.

  • Interpretación: Un CFI de 0.931 sugiere que el modelo especificado por el usuario explica aproximadamente el 93.1% de la varianza y la covarianza observada en los datos, en comparación con el modelo nulo.

3. Tucker-Lewis Index (TLI).

  • El TLI, también conocido como Non-Normed Fit Index (NNFI), es otro índice de ajuste que evalúa qué tan bien se ajusta el modelo especificado por el usuario en comparación con el modelo nulo.

  • Al igual que con el CFI, un valor de TLI mayor a 0.90 se considera aceptable, aunque valores más cercanos a 0.95 o mayores indican un mejor ajuste.

  • Interpretación: Un TLI de 0.896 sugiere que el modelo especificado por el usuario explica aproximadamente el 89.6% de la varianza y la covarianza observada en los datos, en comparación con el modelo nulo.

18 Output de summary: loglik and criterios

18.0.1 Loglik and Criteria: output gráfico

En la Figura 18.1 se resalta la parte No. 5 del output de lavaan::summary.
**Parte No. 5 del output de `lavaan::summary` (`Loglikelihood and Information Criteria`)**

Figure 18.1: Parte No. 5 del output de lavaan::summary (Loglikelihood and Information Criteria)

18.0.2 Loglik and Criteria: log-verosimilitud

Estos resultados pertenecen a la comparación del modelo del usuario (modelo especificado) con el modelo de referencia (modelo nulo) en términos de la función de verosimilitud logarítmica. Aquí está su interpretación:

1. Loglikelihood del modelo del usuario (\(H_0\)).

El valor de la log-verosimilitud (loglikelihood) para el modelo del usuario, que es el modelo especificado por el usuario. En este caso, el loglikelihood del modelo del usuario es -3737.745.

2. Loglikelihood del modelo no restringido (\(H_1\)).

El valor de la log-verosimilitud para el modelo no restringido, que es un modelo donde no se imponen restricciones (es decir, un modelo donde todas las covarianzas son libres de ser estimadas). En este caso, el loglikelihood del modelo no restringido es -3695.092.

18.0.3 Loglik and Criteria: criterios de Información

Estos resultados pertenecen a la comparación del modelo del usuario (modelo especificado) con el modelo de referencia (modelo nulo) en términos de varios criterios de información. Aquí está su interpretación:

1. Criterio de Información de Akaike (AIC).

Un criterio de selección de modelo que penaliza el sobreajuste del modelo al tener en cuenta el número de parámetros estimados. Se prefiere un valor de AIC más bajo, lo que indica un mejor equilibrio entre el ajuste del modelo y la complejidad del modelo. En este caso, el valor del AIC es 7517.490.

2. Criterio de Información Bayesiana (BIC).

Similar al AIC pero con una penalización más fuerte por el número de parámetros. Se prefiere un valor de BIC más bajo, lo que indica un mejor equilibrio entre el ajuste del modelo y la complejidad del modelo. En este caso, el valor del BIC es 7595.339.

3. Criterio de Información Bayesiana Ajustado por el Tamaño de la Muestra (SABIC).

Una variante del BIC que también tiene en cuenta el tamaño de la muestra. Se prefiere un valor de SABIC más bajo, lo que indica un mejor equilibrio entre el ajuste del modelo, la complejidad del modelo y el tamaño de la muestra. En este caso, el valor del SABIC es 7528.739.

18.0.4 Loglik and Criteria: Interpretaciones generales

  1. En general, se prefiere un loglikelihood más alto, ya que indica un mejor ajuste del modelo a los datos.

  2. Para los criterios de información (AIC, BIC, SABIC), se prefieren valores más bajos, lo que indica un mejor equilibrio entre el ajuste del modelo y la complejidad del modelo.

  3. En este caso, el modelo no restringido (\(H_1\)) tiene un loglikelihood más alto y valores más bajos para los criterios de información en comparación con el modelo del usuario (\(H_0\)).

  4. Esto sugiere que el modelo no restringido proporciona un mejor ajuste a los datos en comparación con el modelo del usuario.

  5. Sin embargo, la elección del modelo final debe basarse en una evaluación completa que considere tanto el ajuste del modelo como la teoría subyacente y los objetivos de investigación.

19 Output de summary: RMSEA

19.0.1 Root Mean Square: output gráfico

En la Figura 19.1 se resalta la parte No. 3 del output de lavaan::summary.
**Parte No. 6 del output de `lavaan::summary` (`Root Mean Square`)**

Figure 19.1: Parte No. 6 del output de lavaan::summary (Root Mean Square)

19.0.2 Root Mean Square: generalidades

Para interpretar el Root Mean Square Error of Approximation (RMSEA) y el Standardized Root Mean Square Residual (SRMR), se necesitan algunos detalles adicionales sobre el contexto del análisis factorial confirmatorio (CFA) y los criterios de ajuste utilizados. Estos valores se utilizan para evaluar el ajuste del modelo propuesto a los datos observados. Aquí está la interpretación:

19.0.3 Root Mean Square: RMSEA (interpretación)

  1. El RMSEA (Raíz del Error Cuadrático Medio de Aproximación) es una medida de ajuste del modelo que indica cuánto se espera que el modelo se desvíe de los datos poblacionales en términos de la medida de error cuadrático medio.

  2. Generalmente, se considera que un valor de RMSEA menor o igual a 0.05 indica un buen ajuste, valores entre 0.05 y 0.08 indican un ajuste moderado y valores superiores a 0.1 indican un ajuste deficiente.

  3. En nuestro output, \(RMSEA = 0.092\).

  4. Este valor indica que el modelo propuesto tiene un ajuste moderado a los datos.

19.0.4 Root Mean Square: RMSEA (90% IC)

  1. El intervalo de Confianza del 90% (90 Percent confidence interval) Proporciona una estimación de la precisión del RMSEA.

  2. Los límites inferior y superior del intervalo de confianza indican el rango plausible de valores de RMSEA.

  3. En este caso, el IC 90% va desde 0.071 hasta 0.114.

19.0.5 Root Mean Square: RMSEA (P-value)

1. P-value H0: RMSEA <= 0.050 = 0.001.

  • Este valor \(p\) es el resultado de una prueba de hipótesis sobre si el RMSEA es menor o igual a 0.05.

  • Un valor p bajo (por debajo del nivel de significancia común de 0.05) sugiere que el modelo no se ajusta bien a los datos, ya que el RMSEA es significativamente mayor que 0.05.

2. P-value H0: RMSEA >= 0.080 = 0.840.

  • Este valor p es el resultado de una prueba de hipótesis sobre si el RMSEA es mayor o igual a 0.08.

  • Un valor p alto (por encima del nivel de significancia común de 0.05) sugiere que el modelo se ajusta bien a los datos, ya que el RMSEA no es significativamente mayor que 0.08.

19.0.6 Root Mean Square: SRMR (interpretación)

  1. El SRMR (Residual Estandarizado del Error Cuadrático Medio de Aproximación) es una medida de ajuste del modelo que indica cuánto se espera que la matriz de covarianza de los residuos estandarizados se desvíe de la matriz de covarianza de residuos poblacionales.

  2. Generalmente, se considera que un valor de SRMR menor o igual a 0.08 indica un buen ajuste, mientras que valores superiores a 0.1 indican un ajuste deficiente.

  3. En nuestro output, \(SRMR = 0.065\).

  4. Este valor indica que el modelo propuesto tiene un ajuste moderado a los datos.

19.0.7 Root Mean Square: RMSEA y SRMR (conclusiones)

  1. En resumen, estos valores de ajuste (RMSEA y SRMR) sugieren que el modelo propuesto tiene un ajuste moderado a los datos.

  2. A pesar de lo anterior:

  • El RMSEA sugiere un ajuste algo deficiente debido a su valor cercano a 0.1.

  • Y el valor \(p\) asociado con \(RMSEA \leq 0.050\) también sugiere una mala adaptación.

20 Output de summary: estimación de parámetros

20.0.1 Estimates: output gráfico

  1. Se proporcionan estimaciones de los parámetros del modelo, como las cargas factoriales, covarianzas entre variables latentes y varianzas de las variables observadas y latentes, entre otros.

  2. Cada fila representa una relación entre variables observadas y latentes o entre variables latentes, mostrando el estimado de la relación, su error estándar, valor \(z\) y valor \(p\) asociado.

  3. En la Figura 20.1 se resalta la parte No. 6 del output de lavaan::summary.

    **Parte No. 6 del output de `lavaan::summary` (`Parameter Estimates`)**

    Figure 20.1: Parte No. 6 del output de lavaan::summary (Parameter Estimates)

20.0.2 Estimates: output gráfico (explicaciones)

En el gráfico anterior, vemos cuatro partes (explicaremos cada una de ellas en secciones siguientes):

  1. Parte 6a: Información general.

  2. Parte 6b: Estimaciones de las cargas factoriales de las variables latentes (visual, textual, speed) en las variables observadas (x1, …,x9).

  3. Parte 6c: Estimaciones de las covarianzas entre las variables latentes.

  4. Parte 6d: Estimaciones de las varianzas de las variables observadas y latentes.

21 Output de Estimate: 6a (información general)

21.0.1 Estimate: parte 6a (output gráfico)

En la Figura 21.1 se resalta la parte No. 6a del output de lavaan::summary.
**Parte No. 6a del output de `lavaan::summary` (`General information`)**

Figure 21.1: Parte No. 6a del output de lavaan::summary (General information)

22 Output de Estimate: 6a (información general)

22.0.1 Estimate: parte 6a (interpretaciones)

La sección de Parameter Estimates en el resumen de resultados de lavaan contiene información importante sobre los errores estándar y la información utilizada para calcularlos. Aquí hay una interpretación detallada de las líneas específicas que se han mencionado:

1. Standard Errors (Errores Estándar).

  • Indica que los errores estándar han sido calculados.

  • Los errores estándar son medidas de la precisión de las estimaciones de los parámetros; valores más pequeños indican estimaciones más precisas.

2. Information (Información).

  • Esta línea describe el tipo de información que se utilizó para calcular los errores estándar.

  • Existen diferentes métodos para calcular la matriz de información.

  • La elección del método puede influir en los errores estándar y, por lo tanto, en las pruebas de significancia.

3. Information Saturated (H1) Model.

  • La matriz de información del modelo saturado (también conocido como el modelo “h1”) se utiliza para calcular los errores estándar.

  • Un modelo saturado es un modelo que tiene tantos parámetros como sea posible para ajustarse perfectamente a los datos.

  • En otras palabras, es un modelo que asume que todas las variables están correlacionadas libremente.

  • La matriz de información del modelo saturado puede proporcionar una estimación robusta de la variabilidad de los parámetros del modelo.

4. Structured Information.

  • La información estructurada se refiere a la matriz de información derivada del modelo específico que se está evaluando (el modelo del usuario).

  • Esta matriz se basa en las restricciones y especificaciones del modelo del usuario. Proporciona una visión de la variabilidad de los parámetros tal como se estructura en el modelo especificado.

22.0.2 Estimate: parte 6a (interpretación general)

  1. Standard errors: Especifica que se han calculado los errores estándar para las estimaciones de los parámetros del modelo.

  2. Information: Describe que la matriz de información ha sido utilizada para calcular estos errores estándar.

  3. Information saturated (h1) model: Indica que la matriz de información del modelo saturado se ha utilizado para calcular los errores estándar. Este enfoque puede ser más robusto porque no depende de las restricciones del modelo específico.

  4. Structured Information: Se refiere a la matriz de información calculada directamente a partir del modelo del usuario, que incluye todas las especificaciones y restricciones impuestas por el usuario en el modelo.

22.0.3 Estimate: parte 6a (conclución general)

  1. En resumen, esta sección del resumen de resultados de lavaan nos informa que los errores estándar se han calculado utilizando tanto la matriz de información del modelo saturado (h1) como la matriz de información estructurada del modelo del usuario.

  2. Este enfoque proporciona una visión robusta y estructurada de la variabilidad de los parámetros del modelo y de la precisión de las estimaciones de los parámetros.

23 Output de Estimate: 6b (latent variables)

23.0.1 Estimates: parte 6b (output gráfico)

En la Figura 23.1 se resalta la parte No. 6b del output de lavaan::summary.
**Parte No. 6 del output de `lavaan::summary` (`Latent variables`)**

Figure 23.1: Parte No. 6 del output de lavaan::summary (Latent variables)

23.0.2 Estimates: parte 6b (generalidades)

  1. Se presentan las estimaciones de las cargas factoriales de las variables latentes (visual, textual, speed) en las variables observadas (x1, …,x9).

  2. Para cada relación entre una variable latente y sus variables observadas, se muestra la estimación de la carga, su error estándar, valor \(z\) y valor \(p\) asociado:

  • Estimate: Indica la estimación \(\widehat{\lambda}\) de la carga factorial (factor loading) \(\lambda\) para cada indicador en relación con su variable latente correspondiente.

  • Std.Err: Es el error estándar \(S_{\widehat{\lambda}}\) de la estimación.

  • z-value: El valor \(z\) indica cuántas desviaciones estándar está la estimación por encima o por debajo de cero. Valores absolutos más grandes indican una mayor significancia estadística.

  • P(>|z|): Es el valor \(p\) asociado con el valor \(z\). Un valor \(p\) bajo (por ejemplo, <0.05) sugiere que la estimación es significativamente diferente de cero.

  • Si \(\lambda\) es la carga factorial correspondiente, entonces, las hipótesis que se contrastan son:

\[H_0: \; \lambda = 0 \quad \text{versus} \quad H_1: \; \lambda \ne 0\]

23.0.3 Estimates: parte 6b (ejemplo)

  1. Para la variable latente visual:
  • El indicador x1 tiene una carga factorial fija en \(\widehat{\lambda}_1=1\) (por convención).

  • Mientras que x2 y x3, respectivamente, tienen cargas factoriales estimadas de

\[\widehat{\lambda}_2=0.554, \quad \widehat{\lambda}_3=0.729\]

  • Además, los errores estándares correspondientes son:

\[S_{\widehat{\lambda}_2} = 0.100, \quad S_{\widehat{\lambda}_3} = 0.109\] 3. Los valores \(z\) correspondientes a x2 y x3 son:

\[z_2= \frac{\widehat{\lambda}_2 - 0}{S_{\widehat{\lambda}_2}} = \frac{0.554 - 0}{0.100} = 5.554, \qquad z_2= \frac{\widehat{\lambda}_3 - 0}{S_{\widehat{\lambda}_3}} = \frac{0.729 - 0}{0.109} = 6.685\]

  1. Todos estos valores son significativos (P < 0.05), lo que indica que los indicadores están bien asociados con la variable latente visual:

\[\text{valor}\; p_2 = P(Z_2 > 5.554) = 0, \qquad \text{valor}\; p_3 = P(Z_3 > 6.685) = 0\]

  1. De manera similar, para las variables latentes textual y speed, los indicadores están bien asociados con sus variables latentes correspondientes, ya que todas las cargas factoriales son significativas.

24 Output de Estimate: 6c (covariances)

24.0.1 Estimates: parte 6c (output gráfico)

En la Figura 24.1 se resalta la parte No. 6c del output de lavaan::summary.
**Parte No. 6c del output de `lavaan::summary` (`Covariances`)**

Figure 24.1: Parte No. 6c del output de lavaan::summary (Covariances)

24.0.2 Estimates: parte 6c (generalidades)

  1. Se proporcionan las estimaciones de las covarianzas entre las variables latentes (visual, textual, speed).

  2. Para cada covarianza, se muestra la estimación, su error estándar, valor \(z\) y valor \(p\) asociado:

  • Estimate: Indica la estimación \(\widehat{C}_{ij} = \widehat{Cov}(F_i,F_j)\) de la covarianza \(C_{ij}\) entre las variables latentes \(F_i\) y \(F_j\).

  • Std.Err: Es el error estándar \(S_{\widehat{C}_{ij}}\) de la estimación.

  • z-value: El valor \(z\) indica cuántas desviaciones estándar está la estimación por encima o por debajo de cero. Valores absolutos más grandes indican una mayor significancia estadística.

  • P(>|z|): Es el valor \(p\) asociado con el valor \(z\). Un valor \(p\) bajo (por ejemplo, <0.05) sugiere que la estimación es significativamente diferente de cero.

  • Si \({C}_{ij}\) es la covarianza correspondiente entre \(F_i\) y \(F_j\), entonces, las hipótesis que se contrastan son:

\[H_0: \; {C}_{ij} = 0 \quad \text{versus} \quad H_1: \; {C}_{ij} \ne 0\]

24.0.3 Estimates: parte 6c (ejemplo)

  1. La covarianza entre visual y textual es de 0.408, lo que indica que estas dos variables latentes están moderadamente correlacionadas.

  2. Esta covarianza es significativa (\(P < 0.05\)), lo que sugiere una relación significativa entre las habilidades visuales y textuales.

  3. Los cálculos correspondientes son muy similares a los realizados en la parte 6b.

25 Output de Estimate: 6d (variances)

25.0.1 Estimates: parte 6d (output gráfico)

En la Figura 25.1 se resalta la parte No. 6d del output de lavaan::summary.
**Parte No. 6d del output de `lavaan::summary` (`Variances`)**

Figure 25.1: Parte No. 6d del output de lavaan::summary (Variances)

25.0.2 Estimates: parte 6c (generalidades)

  1. Se presentan las estimaciones de las varianzas de las variables observadas (x1, …, x9) y latentes (visual, textual, speed).

  2. Para cada varianza, se muestra la estimación, su error estándar, valor \(z\) y valor \(p\) asociado:

  • Estimate: Indica la estimación \(\widehat{C}_{ii}\) de la varianza \(C_{ii}\) entre las variables de interés.

  • Std.Err: Es el error estándar \(S_{\widehat{C}_{ii}}\) de la estimación.

  • z-value: El valor \(z\) indica cuántas desviaciones estándar está la estimación por encima o por debajo de cero. Valores absolutos más grandes indican una mayor significancia estadística.

  • P(>|z|): Es el valor \(p\) asociado con el valor \(z\). Un valor \(p\) bajo (por ejemplo, <0.05) sugiere que la estimación es significativamente diferente de cero.

  • Si \({C}_{ii}\) es la varianza correspondiente de la variable de interés, entonces, las hipótesis que se contrastan son:

\[H_0: \; {C}_{ii} = 0 \quad \text{versus} \quad H_1: \; {C}_{ii} \ne 0\]

25.0.3 Estimates: parte 6c (ejemplo)

  1. La varianza de la variable latente visual es de 0.809.

  2. Esto indica cuánta varianza en visual no está explicada por sus indicadores.

  3. Esta varianza es significativa (\(P < 0.05\)), lo que sugiere que la variable latente visual contribuye significativamente a la variabilidad en los datos observados.

  4. Los cálculos correspondientes son muy similares a los realizados en la parte 6b.

26 Extrayendo elementos: con inspect

26.0.1 inspect: descripción

  1. El código de abajo proporcionará una tabla que muestra los estimados de los parámetros del modelo CFA.

  2. El output incluye las cargas factoriales (\(\Lambda\)), las varianzas residuales (\(\Theta\)) y las covarianzas entre los factores (\(\Psi\)).

  3. En secciones siguientes se describirán cada una de estas matrices. En conjunto, las matrices \(\boldsymbol{\Lambda}\), \(\boldsymbol{\Theta}\) y \(\boldsymbol{\Psi}\) definen completamente la estructura del modelo CFA, permitiendo expresar la llamada matriz de covarianzas implicada como:

\[ \boldsymbol{\Sigma} = \boldsymbol{\Lambda}\boldsymbol{\Psi}\boldsymbol{\Lambda}^\top + \boldsymbol{\Theta}. \]

La matriz de covarianzas implicada en un modelo de análisis factorial confirmatorio (CFA) es la matriz de covarianzas predicha por el modelo ajustado.

26.0.2 inspect: ejecución

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

lambda #cargas factoriales
theta  #varianzas residuales (de los errores de las var. observadas)
psi    #covarianzas entre los factores

El output de inspect.

## $lambda
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082
## 
## $theta
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566
## 
## $psi
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

El output de inspect: cargas factoriales.

La matriz de cargas factoriales estimadas es:

\[ \boldsymbol{\Lambda} = \begin{pmatrix} 1.000 & 0 & 0 \\ 0.554 & 0 & 0 \\ 0.729 & 0 & 0 \\ 0 & 1.000 & 0 \\ 0 & 1.113 & 0 \\ 0 & 0.926 & 0 \\ 0 & 0 & 1.000 \\ 0 & 0 & 1.180 \\ 0 & 0 & 1.082 \end{pmatrix}, \]

donde las columnas corresponden a los factores \(\text{visual}\), \(\text{textual}\) y \(\text{speed}\), y las filas a los ítems \(x_1,\dots,x_9\).

lambda #cargas factoriales
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082

El output de inspect: varianzas residuales.

La matriz de varianzas residuales de los errores de medición es:

\[ \boldsymbol{\Theta} = \begin{pmatrix} 0.549 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1.134 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0.844 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0.371 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0.446 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0.356 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0.799 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0.488 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0.566 \end{pmatrix}. \]

Esta matriz es diagonal, lo que implica que no se permiten covarianzas entre errores de medición.

theta  #varianzas residuales (de los errores de las var. observadas)
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566

El output de inspect: covarianzas entre los factores.

La matriz de varianzas y covarianzas entre los factores latentes es:

\[ \boldsymbol{\Psi} = \begin{pmatrix} 0.809 & 0.408 & 0.262 \\ 0.408 & 0.979 & 0.173 \\ 0.262 & 0.173 & 0.384 \end{pmatrix}, \]

donde la diagonal contiene las varianzas de los factores \(\text{visual}\), \(\text{textual}\) y \(\text{speed}\), y los elementos fuera de la diagonal representan sus covarianzas.

psi  #varianzas residuales (de los errores de las var. observadas)
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

26.0.3 inspect: argumento what

Para ver cómo lavaan representa internamente un modelo, puede escribir:

El código.

inspect(fit, what="list")

El output.

##    id     lhs op     rhs user block group free ustart exo label plabel start
## 1   1  visual =~      x1    1     1     1    0      1   0         .p1. 1.000
## 2   2  visual =~      x2    1     1     1    1     NA   0         .p2. 0.778
## 3   3  visual =~      x3    1     1     1    2     NA   0         .p3. 1.107
## 4   4 textual =~      x4    1     1     1    0      1   0         .p4. 1.000
## 5   5 textual =~      x5    1     1     1    3     NA   0         .p5. 1.133
## 6   6 textual =~      x6    1     1     1    4     NA   0         .p6. 0.924
## 7   7   speed =~      x7    1     1     1    0      1   0         .p7. 1.000
## 8   8   speed =~      x8    1     1     1    5     NA   0         .p8. 1.225
## 9   9   speed =~      x9    1     1     1    6     NA   0         .p9. 0.854
## 10 10      x1 ~~      x1    0     1     1    7     NA   0        .p10. 0.679
## 11 11      x2 ~~      x2    0     1     1    8     NA   0        .p11. 0.691
## 12 12      x3 ~~      x3    0     1     1    9     NA   0        .p12. 0.637
## 13 13      x4 ~~      x4    0     1     1   10     NA   0        .p13. 0.675
## 14 14      x5 ~~      x5    0     1     1   11     NA   0        .p14. 0.830
## 15 15      x6 ~~      x6    0     1     1   12     NA   0        .p15. 0.598
## 16 16      x7 ~~      x7    0     1     1   13     NA   0        .p16. 0.592
## 17 17      x8 ~~      x8    0     1     1   14     NA   0        .p17. 0.511
## 18 18      x9 ~~      x9    0     1     1   15     NA   0        .p18. 0.508
## 19 19  visual ~~  visual    0     1     1   16     NA   0        .p19. 0.050
## 20 20 textual ~~ textual    0     1     1   17     NA   0        .p20. 0.050
## 21 21   speed ~~   speed    0     1     1   18     NA   0        .p21. 0.050
## 22 22  visual ~~ textual    0     1     1   19     NA   0        .p22. 0.000
## 23 23  visual ~~   speed    0     1     1   20     NA   0        .p23. 0.000
## 24 24 textual ~~   speed    0     1     1   21     NA   0        .p24. 0.000
##      est    se
## 1  1.000 0.000
## 2  0.554 0.100
## 3  0.729 0.109
## 4  1.000 0.000
## 5  1.113 0.065
## 6  0.926 0.055
## 7  1.000 0.000
## 8  1.180 0.165
## 9  1.082 0.151
## 10 0.549 0.114
## 11 1.134 0.102
## 12 0.844 0.091
## 13 0.371 0.048
## 14 0.446 0.058
## 15 0.356 0.043
## 16 0.799 0.081
## 17 0.488 0.074
## 18 0.566 0.071
## 19 0.809 0.145
## 20 0.979 0.112
## 21 0.384 0.086
## 22 0.408 0.074
## 23 0.262 0.056
## 24 0.173 0.049

Esto es equivalente a la función parTable. La tabla que se devuelve aquí se denomina tabla de parámetros. Se explicará en secciones siguientes.

27 Extrayendo elementos: con lavInspect

27.0.1 lavInspect: explicación

La función lavInspect acepta varios argumentos para especificar qué aspecto del modelo se desea inspeccionar. Algunos de los argumentos comunes incluyen:

1. object.

El modelo ajustado del cual se desean inspeccionar las propiedades.

2. what.

especifica qué propiedad del modelo se desea inspeccionar. Esto puede ser est para los parámetros estimados, residuals para los residuos, “cov” para las covarianzas, entre otros.

3. label.

Opcionalmente, permite especificar un nombre para etiquetar el resultado.

27.0.2 lavInspect: ejecución

  1. Por ejemplo, para inspeccionar los parámetros estimados de un modelo ajustado CFA, puedes usar lavInspect(fit, "est").

  2. Esto devolverá una tabla que muestra los parámetros estimados del modelo, incluyendo las cargas factoriales, las varianzas residuales y las covarianzas entre los factores.

  3. El output es exactamente el mismo que se obtiene con inspect.

28 Extrayendo elementos: con lavInspect: ejemplos

28.0.1 lavInspect: ejemplo 1

Por defecto, al llamar a lavInspect sobre un objeto lavaan ajustado se obtiene una lista de las matrices del modelo que se utilizan internamente para representar el modelo. Los parámetros libres son enteros distintos de cero.

El código.

lavInspect(fit)

El output.

## $lambda
##    visual textul speed
## x1      0      0     0
## x2      1      0     0
## x3      2      0     0
## x4      0      0     0
## x5      0      3     0
## x6      0      4     0
## x7      0      0     0
## x8      0      0     5
## x9      0      0     6
## 
## $theta
##    x1 x2 x3 x4 x5 x6 x7 x8 x9
## x1  7                        
## x2  0  8                     
## x3  0  0  9                  
## x4  0  0  0 10               
## x5  0  0  0  0 11            
## x6  0  0  0  0  0 12         
## x7  0  0  0  0  0  0 13      
## x8  0  0  0  0  0  0  0 14   
## x9  0  0  0  0  0  0  0  0 15
## 
## $psi
##         visual textul speed
## visual      16             
## textual     19     17      
## speed       20     21    18

A partir del modelo CFA se estiman la matriz de cargas factoriales (\(\boldsymbol{\Lambda}\)), la matriz de varianzas residuales de los errores de medición (\(\boldsymbol{\Theta}\)) y la matriz de varianzas–covarianzas de los factores latentes (\(\boldsymbol{\Psi}\)), respectivamente:

\[ \boldsymbol{\Lambda} = \begin{pmatrix} 1.000 & 0 & 0 \\ 0.554 & 0 & 0 \\ 0.729 & 0 & 0 \\ 0 & 1.000 & 0 \\ 0 & 1.113 & 0 \\ 0 & 0.926 & 0 \\ 0 & 0 & 1.000 \\ 0 & 0 & 1.180 \\ 0 & 0 & 1.082 \end{pmatrix}, \qquad \boldsymbol{\Theta} = \begin{pmatrix} 0.549 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1.134 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0.844 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0.371 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0.446 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0.356 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0.799 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0.488 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0.566 \end{pmatrix},\]

\[ \boldsymbol{\Psi} = \begin{pmatrix} 0.809 & 0.408 & 0.262 \\ 0.408 & 0.979 & 0.173 \\ 0.262 & 0.173 & 0.384 \end{pmatrix} \]

28.0.2 lavInspect: ejemplo 2

Para ver cómo lavaan representa internamente un modelo, puede escribir:

lavInspect(CFA, what = "list")
##    id     lhs op     rhs user block group free ustart exo label plabel start
## 1   1  visual =~      x1    1     1     1    0      1   0         .p1. 1.000
## 2   2  visual =~      x2    1     1     1    1     NA   0         .p2. 0.778
## 3   3  visual =~      x3    1     1     1    2     NA   0         .p3. 1.107
## 4   4 textual =~      x4    1     1     1    0      1   0         .p4. 1.000
## 5   5 textual =~      x5    1     1     1    3     NA   0         .p5. 1.133
## 6   6 textual =~      x6    1     1     1    4     NA   0         .p6. 0.924
## 7   7   speed =~      x7    1     1     1    0      1   0         .p7. 1.000
## 8   8   speed =~      x8    1     1     1    5     NA   0         .p8. 1.225
## 9   9   speed =~      x9    1     1     1    6     NA   0         .p9. 0.854
## 10 10      x1 ~~      x1    0     1     1    7     NA   0        .p10. 0.679
## 11 11      x2 ~~      x2    0     1     1    8     NA   0        .p11. 0.691
## 12 12      x3 ~~      x3    0     1     1    9     NA   0        .p12. 0.637
## 13 13      x4 ~~      x4    0     1     1   10     NA   0        .p13. 0.675
## 14 14      x5 ~~      x5    0     1     1   11     NA   0        .p14. 0.830
## 15 15      x6 ~~      x6    0     1     1   12     NA   0        .p15. 0.598
## 16 16      x7 ~~      x7    0     1     1   13     NA   0        .p16. 0.592
## 17 17      x8 ~~      x8    0     1     1   14     NA   0        .p17. 0.511
## 18 18      x9 ~~      x9    0     1     1   15     NA   0        .p18. 0.508
## 19 19  visual ~~  visual    0     1     1   16     NA   0        .p19. 0.050
## 20 20 textual ~~ textual    0     1     1   17     NA   0        .p20. 0.050
## 21 21   speed ~~   speed    0     1     1   18     NA   0        .p21. 0.050
## 22 22  visual ~~ textual    0     1     1   19     NA   0        .p22. 0.000
## 23 23  visual ~~   speed    0     1     1   20     NA   0        .p23. 0.000
## 24 24 textual ~~   speed    0     1     1   21     NA   0        .p24. 0.000
##      est    se
## 1  1.000 0.000
## 2  0.554 0.100
## 3  0.729 0.109
## 4  1.000 0.000
## 5  1.113 0.065
## 6  0.926 0.055
## 7  1.000 0.000
## 8  1.180 0.165
## 9  1.082 0.151
## 10 0.549 0.114
## 11 1.134 0.102
## 12 0.844 0.091
## 13 0.371 0.048
## 14 0.446 0.058
## 15 0.356 0.043
## 16 0.799 0.081
## 17 0.488 0.074
## 18 0.566 0.071
## 19 0.809 0.145
## 20 0.979 0.112
## 21 0.384 0.086
## 22 0.408 0.074
## 23 0.262 0.056
## 24 0.173 0.049

Esto es equivalente a la función parTable. La tabla que se devuelve aquí se denomina tabla de parámetros. Se explicará en secciones siguientes.

28.0.3 lavInspect: ejemplo 3

Estimar las cargas factoriales, las varianzas residuales y las covarianzas entre los factores carga factorial, varianza residual y covarianza entre factores. Por defecto, lavInspect(fit) devuelve las matrices internas del modelo, no con valores estimados, sino con índices enteros que identifican los parámetros libres del modelo.

Regla fundamental.

  • 0 implica un parámetro fijo (generalmente a 0 o a un valor de identificación).

  • Entero positivo implica un parámetro libre, numerado según el vector interno de parámetros de lavaan.

Es decir, lavaan está mostrando la estructura paramétrica del modelo, no sus estimaciones numéricas.

El código.

lavInspect(fit, "est")

El output.

## $lambda
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082
## 
## $theta
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566
## 
## $psi
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

28.0.4 lavInspect: ejemplo 4

La matriz de covarianzas implicada por el modelo CFA corresponde a las covarianzas poblacionales que el modelo predice entre las variables observadas. En este caso, la matriz de covarianzas implicada estimada es:

\[ \boldsymbol{\Sigma} \; = \; \boldsymbol{\Lambda}\boldsymbol{\Psi}\boldsymbol{\Lambda}^\top + \boldsymbol{\Theta} \; = \; \begin{pmatrix} 1.358 & 0.448 & 0.590 & 0.408 & 0.454 & 0.378 & 0.262 & 0.309 & 0.284 \\ 0.448 & 1.382 & 0.327 & 0.226 & 0.252 & 0.209 & 0.145 & 0.171 & 0.157 \\ 0.590 & 0.327 & 1.275 & 0.298 & 0.331 & 0.276 & 0.191 & 0.226 & 0.207 \\ 0.408 & 0.226 & 0.298 & 1.351 & 1.090 & 0.907 & 0.173 & 0.205 & 0.188 \\ 0.454 & 0.252 & 0.331 & 1.090 & 1.660 & 1.010 & 0.193 & 0.228 & 0.209 \\ 0.378 & 0.209 & 0.276 & 0.907 & 1.010 & 1.196 & 0.161 & 0.190 & 0.174 \\ 0.262 & 0.145 & 0.191 & 0.173 & 0.193 & 0.161 & 1.183 & 0.453 & 0.415 \\ 0.309 & 0.171 & 0.226 & 0.205 & 0.228 & 0.190 & 0.453 & 1.022 & 0.490 \\ 0.284 & 0.157 & 0.207 & 0.188 & 0.209 & 0.174 & 0.415 & 0.490 & 1.015 \end{pmatrix}. \]

El código.

lavInspect(CFA, "sigma")

El output.

##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

Observación.

En un modelo bien ajustado, la matriz de covarianzas implicada \(\boldsymbol{\Sigma}\) debe aproximar adecuadamente a la matriz de covarianzas observadas \(\mathbf{S}_{\text{cov}}\).

29 Extrayendo con parTable

29.0.1 parTable: explicación de la función

  1. La función se utiliza para generar una tabla que resume los parámetros estimados de un modelo ajustado.

  2. Esta tabla proporciona una visión general de los parámetros del modelo, incluyendo las cargas factoriales, las varianzas residuales, las covarianzas entre los factores y otras estadísticas relevantes.

El código.

param <- parTable(CFA)
param

El output.

##    id     lhs op     rhs user block group free ustart exo label plabel start
## 1   1  visual =~      x1    1     1     1    0      1   0         .p1. 1.000
## 2   2  visual =~      x2    1     1     1    1     NA   0         .p2. 0.778
## 3   3  visual =~      x3    1     1     1    2     NA   0         .p3. 1.107
## 4   4 textual =~      x4    1     1     1    0      1   0         .p4. 1.000
## 5   5 textual =~      x5    1     1     1    3     NA   0         .p5. 1.133
## 6   6 textual =~      x6    1     1     1    4     NA   0         .p6. 0.924
## 7   7   speed =~      x7    1     1     1    0      1   0         .p7. 1.000
## 8   8   speed =~      x8    1     1     1    5     NA   0         .p8. 1.225
## 9   9   speed =~      x9    1     1     1    6     NA   0         .p9. 0.854
## 10 10      x1 ~~      x1    0     1     1    7     NA   0        .p10. 0.679
## 11 11      x2 ~~      x2    0     1     1    8     NA   0        .p11. 0.691
## 12 12      x3 ~~      x3    0     1     1    9     NA   0        .p12. 0.637
## 13 13      x4 ~~      x4    0     1     1   10     NA   0        .p13. 0.675
## 14 14      x5 ~~      x5    0     1     1   11     NA   0        .p14. 0.830
## 15 15      x6 ~~      x6    0     1     1   12     NA   0        .p15. 0.598
## 16 16      x7 ~~      x7    0     1     1   13     NA   0        .p16. 0.592
## 17 17      x8 ~~      x8    0     1     1   14     NA   0        .p17. 0.511
## 18 18      x9 ~~      x9    0     1     1   15     NA   0        .p18. 0.508
## 19 19  visual ~~  visual    0     1     1   16     NA   0        .p19. 0.050
## 20 20 textual ~~ textual    0     1     1   17     NA   0        .p20. 0.050
## 21 21   speed ~~   speed    0     1     1   18     NA   0        .p21. 0.050
## 22 22  visual ~~ textual    0     1     1   19     NA   0        .p22. 0.000
## 23 23  visual ~~   speed    0     1     1   20     NA   0        .p23. 0.000
## 24 24 textual ~~   speed    0     1     1   21     NA   0        .p24. 0.000
##      est    se
## 1  1.000 0.000
## 2  0.554 0.100
## 3  0.729 0.109
## 4  1.000 0.000
## 5  1.113 0.065
## 6  0.926 0.055
## 7  1.000 0.000
## 8  1.180 0.165
## 9  1.082 0.151
## 10 0.549 0.114
## 11 1.134 0.102
## 12 0.844 0.091
## 13 0.371 0.048
## 14 0.446 0.058
## 15 0.356 0.043
## 16 0.799 0.081
## 17 0.488 0.074
## 18 0.566 0.071
## 19 0.809 0.145
## 20 0.979 0.112
## 21 0.384 0.086
## 22 0.408 0.074
## 23 0.262 0.056
## 24 0.173 0.049

29.0.2 parTable: descripción de cada columna de la tabla del output

A continuación se describen las columnas de parTable():

names(param)
##  [1] "id"     "lhs"    "op"     "rhs"    "user"   "block"  "group"  "free"  
##  [9] "ustart" "exo"    "label"  "plabel" "start"  "est"    "se"
  • id: identificador único de cada parámetro dentro del modelo.

  • lhs (left-hand side): variable del lado izquierdo del parámetro (por ejemplo, un factor latente como visual o una variable observada como x1).

  • op: operador que indica el tipo de relación:

    • =~ : carga factorial,

    • ~~ : varianza o covarianza,

    • ~1 : intercepto (o media latente si lhs es un factor).

  • rhs (right-hand side): variable del lado derecho del parámetro.

  • user: indica si el parámetro fue especificado explícitamente por el usuario en la sintaxis del modelo (user = 1) o si fue añadido automáticamente por lavaan para completar el modelo (user = 0).

  • block: identifica el bloque del modelo al que pertenece el parámetro. En SEM multigrupo, cada bloque corresponde a una combinación específica de grupo y tipo de ecuación utilizada internamente por lavaan. En realidad, esta columna no tiene interpretación sustantiva, sino que indica cómo lavaan organiza internamente el modelo para la estimación.Por ejemplo, en la tabla parTable() se observan filas como:

    • Parámetros del tipo visual =~ x1, visual =~ x2, visual =~ x3 con group = 1 y block = 1, los cuales pertenecen al bloque de medición del factor visual en el primer grupo.

    • Parámetros del tipo x1 ~~ x1, x2 ~~ x2 aparecen en bloques distintos, ya que corresponden a varianzas residuales de variables diferentes.

    • En el segundo grupo (group = 2), los mismos tipos de parámetros aparecen asociados a bloques diferentes, reflejando que cada grupo tiene su propia representación interna del modelo.

  • group: grupo al que pertenece el parámetro (1 = primer grupo).

  • free: indicador del estado del parámetro:

  • free=0 = parámetro fijo. Significa que el valor del parámetro no se estima con los datos o que el valor ya está impuesto por el modelo. Por ejemplo, en la tabla vemos:
visual =~ x1   free = 0   start = 1.000

Esto quiere decir que la carga de x1 sobre visual está fijada en 1.000. No se estima (por eso, free = 0).

  • free>0 = parámetro libre a estimar. Por ejemplo, si se ve free = 12, no significa que el parámetro vale 12, sino que es el parámetro libre número 12 que el algoritmo estima.
  • ustart (user start): valor inicial definido por el usuario para el parámetro de la fila correspondeinte, en caso de haberlo especificado. Si no se define, suele aparecer como NA. Por ejemplo, consideremos esta fila: visual =~ x2 ustart = NA. En este caso, el parámetro es la carga factorial de x2 sobre visual. No se indicó ningún valor inicial en la sintaxis. Por eso, lavaan asignó automáticamente un valor inicial (aparece en start). Por eso ustart = NA. Entonces, se vería visual =~ x1 ustart = 0.5si el modelo fuese:
HS.model <- 'visual =~ 0.5*x1 + x2 + x3'
  • exo: indica si la variable asociada al parámetro es tratada como exógena (exo = 1) o endógena (exo = 0). En modelos CFA estándar, la mayoría de variables observadas se tratan como endógenas.

  • label: etiqueta interna del parámetro, utilizada para imponer restricciones de igualdad entre grupos. La columna labelse usa cuando se quiere que varios parámetros compartan el mismo valor y si dos filas tienen el mismo label, lavaan las trata como un solo parámetro común. Por ejemplo, supongamos que se quiere que la carga de x2 sea igual a a:

visual =~ a*x2

En parTable() se vería algo así:

lhs     op   rhs   group   label
visual  =~   x2      1      a
  • plabel (parameter label): etiqueta interna única utilizada por lavaan para identificar el parámetro durante la estimación. A diferencia de label, esta etiqueta es siempre única, incluso cuando se imponen restricciones de igualdad. Cada fila tiene su propio plabel (incluso cuando dos parámetros son forzados a ser iguales (label igual), cada uno conserva su propio plabel). Considere este ejemplo:
lhs     op   rhs   group   label   plabel
visual  =~   x2      1       a     .p2.

Aquí label = a indica valor del parámetro y plabel = .p2., parámetro en la estructura interna.

  • start: valor inicial utilizado por el algoritmo de estimación.

  • est y se: estimación final del parámetro y su error estándar.

parTable: interpretación general de la tabla del output

En el modelo se observa que:

  • Las cargas factoriales fijadas en 1.00 (por ejemplo, visual =~ x1, textual =~ x4, speed =~ x7) cumplen la función de identificación de la escala de los factores latentes.

  • Las filas con operador ~~ corresponden a varianzas (cuando lhs \(=\) rhs) y covarianzas (cuando lhs \(\ne\) rhs).

  • Las filas con operador ~1 y lhs igual a una variable observada representan interceptos; cuando lhs es un factor latente, representan medias latentes.

parTable: nota pedagógica

La función parTable() no está pensada para la interpretación sustantiva directa, sino para entender cómo lavaan codifica internamente el modelo. Sin embargo, resulta extremadamente útil para:

  • Comprender la lógica de las restricciones de igualdad.

  • Verificar qué parámetros están fijos o libres.

  • Conectar la sintaxis del modelo con los resultados numéricos.

Por esta razón, parTable() es una herramienta clave para el estudio rigurosode la invarianza factorial y el SEM multigrupo.

30 Extrayendo cargas factoriales

30.0.1 Cargas: solo estimados (con inspect)

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

lambda #cargas factoriales
#theta  #varianzas residuales
#psi    #covarianzas entre los factores

El otuput.

## $lambda
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082
## 
## $theta
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566
## 
## $psi
##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384
##    visual textul speed
## x1  1.000  0.000 0.000
## x2  0.554  0.000 0.000
## x3  0.729  0.000 0.000
## x4  0.000  1.000 0.000
## x5  0.000  1.113 0.000
## x6  0.000  0.926 0.000
## x7  0.000  0.000 1.000
## x8  0.000  0.000 1.180
## x9  0.000  0.000 1.082

El resultado corresponde a :

\[\boldsymbol{\Lambda} = \begin{pmatrix} 1.000 & 0 & 0 \\ 0.554 & 0 & 0 \\ 0.729 & 0 & 0 \\ 0 & 1.000 & 0 \\ 0 & 1.113 & 0 \\ 0 & 0.926 & 0 \\ 0 & 0 & 1.000 \\ 0 & 0 & 1.180 \\ 0 & 0 & 1.082 \end{pmatrix}\]

30.0.2 Cargas: sin significancia

  1. En el output de abajo, el argumento standardized=TRUE indica que se deben devolver las estimaciones estandarizadas.

  2. La estimación estandarizada se ajusta por el error estándar de la variable implicada, permitiendo así la comparación entre diferentes parámetros en una escala común.

El código.

parameterEstimates(CFA, standardized=TRUE) %>%
  filter(op == "=~") %>%
  select('Factor'=lhs, 
         'Indicador'=rhs, 
         'Estimación'=est, 
         'Error std.'=se, 
         'Estimación std.'=std.all, #Estimaciones estandarizadas
         'Z'=z, 
         'p valor'= pvalue
         ) %>%
  
kable(digits = 3, align="c", format="pandoc", caption="Factor Loadings")

El output.

Table 30.1: Factor Loadings
Factor Indicador Estimación Error std. Estimación std. Z p valor
visual x1 1.000 0.000 0.772 NA NA
visual x2 0.554 0.100 0.424 5.554 0
visual x3 0.729 0.109 0.581 6.685 0
textual x4 1.000 0.000 0.852 NA NA
textual x5 1.113 0.065 0.855 17.014 0
textual x6 0.926 0.055 0.838 16.703 0
speed x7 1.000 0.000 0.570 NA NA
speed x8 1.180 0.165 0.723 7.152 0
speed x9 1.082 0.151 0.665 7.155 0

30.0.3 Cargas: con significancia

En la salida de abajo, los asteriscos indican la significancia de la estimación basada en los valores \(p\) (*** para \(p < .001\), ** para \(p < .01\), * para \(p < .05\)).

El código.

parameterEstimates(CFA, standardized=TRUE) %>%
  
  filter(op == "=~") %>%
  mutate(stars = ifelse(pvalue < .001, "***",
                        ifelse(pvalue < .01, "**",
                               ifelse(pvalue < .05, "*", "")))) %>%
  select('Factor'=lhs,
         'Indicador'=rhs,
         'Estimación'=est,
         'Error std.'=se, 
         'Z'=z,
         'Estimación std.'=std.all, #Estimaciones estandarizadas
         'p valor'= pvalue, 
         'Sig.'=stars) %>%
  
kable(digits = 3, align="c", format="pandoc", caption="Cargas factoriales")

El output.

Table 30.2: Cargas factoriales
Factor Indicador Estimación Error std. Z Estimación std. p valor Sig.
visual x1 1.000 0.000 NA 0.772 NA NA
visual x2 0.554 0.100 5.554 0.424 0 ***
visual x3 0.729 0.109 6.685 0.581 0 ***
textual x4 1.000 0.000 NA 0.852 NA NA
textual x5 1.113 0.065 17.014 0.855 0 ***
textual x6 0.926 0.055 16.703 0.838 0 ***
speed x7 1.000 0.000 NA 0.570 NA NA
speed x8 1.180 0.165 7.152 0.723 0 ***
speed x9 1.082 0.151 7.155 0.665 0 ***

31 Extrayendo varianzas residuales (de los errores)

31.0.1 Varianza residual: con inspect

Estos valores representan las desviaciones de los ítems observados de sus valores esperados basados en las cargas factoriales y la media latente del factor.

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

#lambda #cargas factoriales
theta  #varianzas residuales (de los errores de las var. observadas)
#psi    #covarianzas entre los factores

El otuput.

##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 0.549                                                
## x2 0.000 1.134                                          
## x3 0.000 0.000 0.844                                    
## x4 0.000 0.000 0.000 0.371                              
## x5 0.000 0.000 0.000 0.000 0.446                        
## x6 0.000 0.000 0.000 0.000 0.000 0.356                  
## x7 0.000 0.000 0.000 0.000 0.000 0.000 0.799            
## x8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.488      
## x9 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.566

El resultado corresponde a:

\[\boldsymbol{\Theta} = \begin{pmatrix} 0.549 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1.134 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0.844 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0.371 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0.446 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0.356 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0.799 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0.488 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0.566 \end{pmatrix}\]

32 Extrayendo matriz de covarianzas observadas

32.0.1 Covarianzas observada: explicación

  1. La matriz de covarianzas observadas \(\mathbf{S}_{\text{cov}}\) es una matriz que muestra las covarianzas entre las variables observadas en nuestros datos.

  2. Esta matriz es una representación directa de la relación entre las variables tal como se presenta en tus datos reales, sin ninguna suposición adicional o modelado.

  3. En un modelo bien ajustado, la matriz de covarianzas implicada \(\boldsymbol{\Sigma}\) debe aproximar adecuadamente a la matriz de covarianzas observadas \(\mathbf{S}_{\text{cov}}\).

32.0.2 Covarianzas observadas: con cov

Sea \(\mathbf{X} = (X_1, \ldots, X_9)^\top\) el vector de variables observadas (ítems), y sea \(N\) el tamaño muestral. La matriz de covarianzas observadas se define como:

\[ \mathbf{S}_{\text{cov}} = \operatorname{Cov}(\mathbf{X}), \]

y, para los datos analizados, toma la forma:

\[ \mathbf{S}_{\text{cov}} = \operatorname{Cov}(\mathbf{X}) = \begin{pmatrix} 1.363 & 0.409 & 0.582 & 0.507 & 0.442 & 0.456 & 0.085 & 0.265 & 0.460 \\ 0.409 & 1.386 & 0.453 & 0.210 & 0.212 & 0.248 & -0.097 & 0.110 & 0.245 \\ 0.582 & 0.453 & 1.279 & 0.209 & 0.113 & 0.245 & 0.089 & 0.213 & 0.375 \\ 0.507 & 0.210 & 0.209 & 1.355 & 1.101 & 0.899 & 0.220 & 0.126 & 0.244 \\ 0.442 & 0.212 & 0.113 & 1.101 & 1.665 & 1.018 & 0.143 & 0.181 & 0.296 \\ 0.456 & 0.248 & 0.245 & 0.899 & 1.018 & 1.200 & 0.145 & 0.166 & 0.237 \\ 0.085 & -0.097 & 0.089 & 0.220 & 0.143 & 0.145 & 1.187 & 0.537 & 0.375 \\ 0.265 & 0.110 & 0.213 & 0.126 & 0.181 & 0.166 & 0.537 & 1.025 & 0.459 \\ 0.460 & 0.245 & 0.375 & 0.244 & 0.296 & 0.237 & 0.375 & 0.459 & 1.018 \end{pmatrix}. \]

El código.

# Calcular la matriz de covarianzas observadas
S_cov <- round(cov(dat),3)

# Mostrar la matriz de covarianzas observadas
print(S_cov)

El output.

##            x1          x2         x3        x4        x5        x6          x7
## x1 1.36289774  0.40872923 0.58183232 0.5065178 0.4420843 0.4563242  0.08504799
## x2 0.40872923  1.38638981 0.45256748 0.2096198 0.2117947 0.2483697 -0.09707352
## x3 0.58183232  0.45256748 1.27911441 0.2088635 0.1126706 0.2449227  0.08863631
## x4 0.50651778  0.20961978 0.20886351 1.3551667 1.1014120 0.8985008  0.22047507
## x5 0.44208426  0.21179471 0.11267061 1.1014120 1.6653184 1.0179058  0.14347621
## x6 0.45632416  0.24836972 0.24492268 0.8985008 1.0179058 1.2003462  0.14455865
## x7 0.08504799 -0.09707352 0.08863631 0.2204751 0.1434762 0.1445587  1.18708326
## x8 0.26471714  0.11002492 0.21303038 0.1260120 0.1812072 0.1659824  0.53702937
## x9 0.45986634  0.24482282 0.37509875 0.2441739 0.2962255 0.2367836  0.37454154
##           x8        x9
## x1 0.2647171 0.4598663
## x2 0.1100249 0.2448228
## x3 0.2130304 0.3750987
## x4 0.1260120 0.2441739
## x5 0.1812072 0.2962255
## x6 0.1659824 0.2367836
## x7 0.5370294 0.3745415
## x8 1.0253894 0.4588409
## x9 0.4588409 1.0183872

Observación clave.

La función cov() calcula la covarianza usando el divisor \(N-1\):

\[ \mathbf{S}_{\text{cov}} = \frac{1}{N-1} \sum_{i=1}^{N} (\mathbf{x}_i - \bar{\mathbf{x}}) (\mathbf{x}_i - \bar{\mathbf{x}})^{\top}. \]

Esta forma produce un estimador insesgado de la covarianza poblacional bajo supuestos clásicos, y es la matriz que se utiliza habitualmente en estadística descriptiva y análisis exploratorio.

32.0.3 Covarianzas observadas: usando lavTech

Cuando se ajusta un modelo CFA mediante máxima verosimilitud (ML), lavaan no trabaja con \(\mathbf{S}_{\text{cov}}\), sino con una versión ligeramente distinta de la matriz de covarianzas muestrales, denotada aquí por \(\mathbf{S}_{\text{lav}}\). Esta matriz puede extraerse directamente desde el objeto ajustado:

El código.

S_lav <- lavTech(CFA, "sampstat")[[1]]$cov
S_lav

El output.

##             [,1]        [,2]       [,3]      [,4]      [,5]      [,6]
##  [1,] 1.35836985  0.40737133 0.57989932 0.5048350 0.4406155 0.4548081
##  [2,] 0.40737133  1.38178387 0.45106394 0.2089234 0.2110911 0.2475446
##  [3,] 0.57989932  0.45106394 1.27486486 0.2081696 0.1122963 0.2441090
##  [4,] 0.50483500  0.20892337 0.20816961 1.3506645 1.0977528 0.8955157
##  [5,] 0.44061554  0.21109108 0.11229629 1.0977528 1.6597858 1.0145240
##  [6,] 0.45480813  0.24754457 0.24410898 0.8955157 1.0145240 1.1963584
##  [7,] 0.08476543 -0.09675102 0.08834184 0.2197426 0.1429995 0.1440784
##  [8,] 0.26383768  0.10965939 0.21232264 0.1255933 0.1806052 0.1654310
##  [9,] 0.45833855  0.24400945 0.37385257 0.2433627 0.2952413 0.2359969
##              [,7]      [,8]      [,9]
##  [1,]  0.08476543 0.2638377 0.4583385
##  [2,] -0.09675102 0.1096594 0.2440095
##  [3,]  0.08834184 0.2123226 0.3738526
##  [4,]  0.21974259 0.1255933 0.2433627
##  [5,]  0.14299955 0.1806052 0.2952413
##  [6,]  0.14407839 0.1654310 0.2359969
##  [7,]  1.18313946 0.5352452 0.3732972
##  [8,]  0.53524522 1.0219828 0.4573166
##  [9,]  0.37329722 0.4573166 1.0150039

y resulta ser:

\[ \mathbf{S}_{\text{lav}}= \begin{pmatrix} 1.3584 & 0.4074 & 0.5799 & 0.5048 & 0.4406 & 0.4548 & 0.0848 & 0.2638 & 0.4583 \\ 0.4074 & 1.3818 & 0.4511 & 0.2089 & 0.2111 & 0.2475 & -0.0968 & 0.1097 & 0.2440 \\ 0.5799 & 0.4511 & 1.2749 & 0.2082 & 0.1123 & 0.2441 & 0.0883 & 0.2123 & 0.3739 \\ 0.5048 & 0.2089 & 0.2082 & 1.3507 & 1.0978 & 0.8955 & 0.2197 & 0.1256 & 0.2434 \\ 0.4406 & 0.2111 & 0.1123 & 1.0978 & 1.6598 & 1.0145 & 0.1430 & 0.1806 & 0.2952 \\ 0.4548 & 0.2475 & 0.2441 & 0.8955 & 1.0145 & 1.1964 & 0.1441 & 0.1654 & 0.2360 \\ 0.0848 & -0.0968 & 0.0883 & 0.2197 & 0.1430 & 0.1441 & 1.1831 & 0.5352 & 0.3733 \\ 0.2638 & 0.1097 & 0.2123 & 0.1256 & 0.1806 & 0.1654 & 0.5352 & 1.0220 & 0.4573 \\ 0.4583 & 0.2440 & 0.3739 & 0.2434 & 0.2952 & 0.2360 & 0.3733 & 0.4573 & 1.0150 \end{pmatrix} \]

Observación clave.

La matriz \(\mathbf{S}_{\text{lav}}\) se calcula usando el divisor \(N\), ya que está formulada para el estimador de máxima verosimilitud (ML). En particular, lavaan (con estimador ML) trabaja internamente con:

\[ \mathbf{S}_{\text{lav}} = \frac{1}{N} \sum_{i=1}^{N} (\mathbf{x}_i - \bar{\mathbf{x}}) (\mathbf{x}_i - \bar{\mathbf{x}})^{\top}, \]

Esta forma aparece de manera natural en la función de verosimilitud de la distribución normal multivariada, y por ello constituye la base teórica del estimador de máxima verosimilitud (ML). Aunque \(\mathbf{S}_{\text{lav}}\) no es un estimador insesgado, es internamente coherente con el procedimiento de estimación ML.

32.0.4 Covarianzas observadas: comparación entre \(\mathbf{S}_{\text{cov}}\) y \(\mathbf{S}_{\text{lav}}\)

Aunque ambas matrices se construyen a partir de los mismos datos, no son idénticas, ya que difieren únicamente en el divisor utilizado:

\[ \mathbf{S}_{\text{cov}} = \frac{N}{N-1} \,\mathbf{S}_{\text{lav}}. \]

Por tanto, la diferencia entre ellas es puramente un factor de escala. Cuando el tamaño muestral \(N\) es grande, esta diferencia es pequeña, pero no es exactamente cero.

32.0.5 Covarianzas observadas: consecuencia práctica en CFA y SEM

Debido a esta diferencia, no debe esperarse que coincidan exactamente las siguientes cantidades:

\[ \mathbf{S}_{\text{cov}} - \boldsymbol{\Sigma} \quad \text{y} \quad \mathbf{S}_{\text{lav}} - \boldsymbol{\Sigma}, \]

donde \(\boldsymbol{\Sigma}\) es la matriz de covarianzas implícita estimada bajo el modelo CFA. Esto explica por qué:

  • Restas manuales de matrices,

  • residuals(CFA)$cov,

  • residuals(CFA, type = "cor")$cov,

no van a producir matrices numéricamente idénticas, aun cuando todas representan discrepancias entre lo observado y lo implicado por el modelo. Esto se explicará con más detalles en las siguientes secciones.

32.0.6 Covarianzas observadas: resumen clave

  • \(\mathbf{S}_{\text{cov}}\): matriz descriptiva clásica (fuera del marco ML).

  • \(\mathbf{S}_{\text{lav}}\): matriz coherente con la teoría de máxima verosimilitud.

  • lavaan es internamente consistente: siempre compara cantidades construidas bajo el mismo criterio ML.

Por ello, las diferencias numéricas observadas son esperadas, correctas y teóricamente justificadas.

33 Extrayendo matriz de covarianzas implicada

33.0.1 Covarianzas implicada: definición y observaciones

Definición matemática.

Recordemos que

\[\Sigma \;=\; \Lambda \;\Psi\; \Lambda^{\top} \;+\; \Theta\]

Donde:

  • \(\Sigma\) representa la matriz de covarianzas estimada de las variables observadas (la llamada matriz de covarianzas implicada).

  • \(\Lambda\) es la matriz de cargas factoriales.

  • \(\Psi\) es la matriz de varianzas-covarianzas de los factores latentes.

  • \(\Theta\) es la matriz de varianzas residuales.

Observaciones importantes.

  1. La matriz de covarianzas implicada en un modelo de análisis factorial confirmatorio (CFA) es la matriz de covarianzas predicha por el modelo ajustado.

  2. Esta matriz muestra las covarianzas entre las variables observadas que el modelo supone que existirían, basado en las relaciones especificadas entre las variables latentes y observadas.

  3. Interpretación de la Matriz de Covarianzas Implicada.

  • La matriz de covarianzas implicada refleja cómo el modelo ajustado espera que las variables observadas se relacionen entre sí.

  • Es una representación matemática de las suposiciones del modelo.

  1. Comparar esta matriz con la matriz de covarianzas observada (las covarianzas reales de los datos) permite evaluar la calidad del ajuste del modelo.

33.0.2 Covarianzas implicada: con producto de matrices (primera forma)

Sigma <- lambda %*%  psi %*% t(lambda) + theta
round(Sigma, 3)
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

Es decir,

\[\boldsymbol{\Sigma} \; = \; \begin{pmatrix} 1.358 & 0.448 & 0.590 & 0.408 & 0.454 & 0.378 & 0.262 & 0.309 & 0.284 \\ 0.448 & 1.382 & 0.327 & 0.226 & 0.252 & 0.209 & 0.145 & 0.171 & 0.157 \\ 0.590 & 0.327 & 1.275 & 0.298 & 0.331 & 0.276 & 0.191 & 0.226 & 0.207 \\ 0.408 & 0.226 & 0.298 & 1.351 & 1.090 & 0.907 & 0.173 & 0.205 & 0.188 \\ 0.454 & 0.252 & 0.331 & 1.090 & 1.660 & 1.010 & 0.193 & 0.228 & 0.209 \\ 0.378 & 0.209 & 0.276 & 0.907 & 1.010 & 1.196 & 0.161 & 0.190 & 0.174 \\ 0.262 & 0.145 & 0.191 & 0.173 & 0.193 & 0.161 & 1.183 & 0.453 & 0.415 \\ 0.309 & 0.171 & 0.226 & 0.205 & 0.228 & 0.190 & 0.453 & 1.022 & 0.490 \\ 0.284 & 0.157 & 0.207 & 0.188 & 0.209 & 0.174 & 0.415 & 0.490 & 1.015 \end{pmatrix}\]

33.0.3 Covarianzas implicada: con fitted (segunda forma)

El código.

# Obtener la matriz de covarianzas implicadas
fitted_values <- fitted(CFA)
fitted_values

# Extraer la matriz de covarianzas implicadas
Sigma <- fitted_values$cov

# Mostrar la matriz de covarianzas implicadas
print(Sigma)

Explicación del código.

Se usa la función fitted(CFA) para obtener las matrices implicadas del modelo ajustado:

## $cov
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

Luego, se extrae la matriz de covarianzas implicada con ...$cov. El output correspondiente es:

##           x1        x2        x3        x4        x5        x6        x7
## x1 1.3583700 0.4479566 0.5902910 0.4082324 0.4543940 0.3780829 0.2622246
## x2 0.4479566 1.3817831 0.3267262 0.2259568 0.2515072 0.2092690 0.1451414
## x3 0.5902910 0.3267262 1.2748647 0.2977526 0.3314214 0.2757624 0.1912588
## x4 0.4082324 0.2259568 0.2977526 1.3506644 1.0902489 0.9071522 0.1734947
## x5 0.4543940 0.2515072 0.3314214 1.0902489 1.6597856 1.0097299 0.1931129
## x6 0.3780829 0.2092690 0.2757624 0.9071522 1.0097299 1.1963583 0.1606814
## x7 0.2622246 0.1451414 0.1912588 0.1734947 0.1931129 0.1606814 1.1831393
## x8 0.3094121 0.1712597 0.2256760 0.2047152 0.2278637 0.1895962 0.4528034
## x9 0.2836038 0.1569748 0.2068522 0.1876397 0.2088574 0.1737818 0.4150347
##           x8        x9
## x1 0.3094121 0.2836038
## x2 0.1712597 0.1569748
## x3 0.2256760 0.2068522
## x4 0.2047152 0.1876397
## x5 0.2278637 0.2088574
## x6 0.1895962 0.1737818
## x7 0.4528034 0.4150347
## x8 1.0219828 0.4897205
## x9 0.4897205 1.0150038
## attr(,"class")
## [1] "lavaan.matrix.symmetric" "matrix"

33.0.4 Covarianzas implicada: con fitted y unclass() (tercera forma)

Sigma <- round(unclass(fitted(CFA)$cov),3)
Sigma
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358 0.448 0.590 0.408 0.454 0.378 0.262 0.309 0.284
## x2 0.448 1.382 0.327 0.226 0.252 0.209 0.145 0.171 0.157
## x3 0.590 0.327 1.275 0.298 0.331 0.276 0.191 0.226 0.207
## x4 0.408 0.226 0.298 1.351 1.090 0.907 0.173 0.205 0.188
## x5 0.454 0.252 0.331 1.090 1.660 1.010 0.193 0.228 0.209
## x6 0.378 0.209 0.276 0.907 1.010 1.196 0.161 0.190 0.174
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183 0.453 0.415
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022 0.490
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

33.0.5 Covarianzas implicada: con lavInspect (cuarta forma)

Sigma <- lavInspect(CFA, "sigma")
Sigma
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

34 Extrayendo las matrices de correlaciones observadas e implicadas

34.0.1 Correlaciones: motivación

En análisis factorial confirmatorio (CFA) y, en general, en modelos de ecuaciones estructurales (SEM), es frecuente evaluar el ajuste del modelo en la escala de correlaciones, ya que esta escala elimina la influencia de las unidades de medida y permite comparaciones directas entre pares de variables. Antes de definir residuos en correlaciones, es fundamental distinguir con claridad entre:

  • Correlaciones observadas, obtenidas a partir de los datos, y

  • *Correlaciones implicadas por el modelo**, obtenidas a partir de la matriz de covarianzas implicada \(\boldsymbol{\Sigma}\).

34.0.2 Correlaciones: de covarianzas a correlaciones

Sea \(\mathbf{A}\) una matriz de covarianzas (muestral o implicada por un modelo). La matriz de correlaciones asociada a \(\mathbf{A}\) se obtiene mediante la transformación:

\[ \operatorname{Cor}(\mathbf{A}) = \mathbf{D}_{\mathbf{A}}^{-1/2}\, \mathbf{A}\, \mathbf{D}_{\mathbf{A}}^{-1/2}, \]

donde

\[ \mathbf{D}_{\mathbf{A}} = \operatorname{diag}(a_{11}, \ldots, a_{pp}) \]

es la matriz diagonal que contiene las varianzas de las variables observadas. Esta transformación estandariza cada variable para que tenga varianza unitaria, produciendo una matriz con unos en la diagonal y coeficientes de correlación fuera de ella.

34.0.3 Correlaciones: observadas

En CFA/SEM pueden considerarse dos versiones de la matriz de correlaciones observadas, dependiendo de la matriz de covarianzas muestrales de partida.

Correlaciones observadas descriptivas

Si se parte de la matriz de covarianzas muestral clásica,

\[ \mathbf{S}_{\text{cov}} = \frac{1}{N-1} \sum_{i=1}^{N} (\mathbf{x}_i - \bar{\mathbf{x}}) (\mathbf{x}_i - \bar{\mathbf{x}})^{\top}, \]

entonces la matriz de correlaciones observadas descriptivas se define como:

\[ \operatorname{Cor}(\mathbf{S}_{\text{cov}}) = \mathbf{D}(\mathbf{S}_{\text{cov}})^{-1/2}\, \mathbf{S}_{\text{cov}}\, \mathbf{D}(\mathbf{S}_{\text{cov}})^{-1/2}. \]

Esta es la matriz de correlaciones que se utiliza habitualmente en estadística descriptiva y análisis exploratorio.

Correlaciones observadas coherentes con ML (lavaan)

Cuando el modelo CFA se ajusta mediante máxima verosimilitud (ML), lavaan trabaja internamente con la matriz:

\[ \mathbf{S}_{\text{lav}} = \frac{1}{N} \sum_{i=1}^{N} (\mathbf{x}_i - \bar{\mathbf{x}}) (\mathbf{x}_i - \bar{\mathbf{x}})^{\top}. \]

La correspondiente matriz de correlaciones observadas, coherente con el marco ML, es:

\[ \operatorname{Cor}(\mathbf{S}_{\text{lav}}) = \mathbf{D}(\mathbf{S}_{\text{lav}})^{-1/2}\, \mathbf{S}_{\text{lav}}\, \mathbf{D}(\mathbf{S}_{\text{lav}})^{-1/2}. \]

Aunque \(\mathbf{S}_{\text{cov}}\) y \(\mathbf{S}_{\text{lav}}\) difieren por un factor de escala, sus matrices de correlaciones suelen ser muy similares, ya que el proceso de estandarización elimina gran parte de esa diferencia.

34.0.4 Correlaciones: implicadas por el modelo

Sea \(\boldsymbol{\Sigma}\) la matriz de covarianzas implicada por el modelo CFA ajustado, estimada a partir de los parámetros del modelo. La matriz de correlaciones implicadas por el modelo se obtiene estandarizando \(\boldsymbol{\Sigma}\) a varianzas unitarias:

[:

\[ \operatorname{Cor}(\boldsymbol{\Sigma}) = \mathbf{D}(\boldsymbol{\Sigma})^{-1/2}\, \boldsymbol{\Sigma}\, \mathbf{D}(\boldsymbol{\Sigma})^{-1/2}. \]

En la f´romula de arriba, la matriz \(\mathbf{D}(\boldsymbol{\Sigma})\) es la matriz diagonal de varianzas implicadas por el modelo, es decir:

\[ \mathbf{D}(\boldsymbol{\Sigma}) = \operatorname{diag}\big(\sigma_{11},\sigma_{22},\ldots,\sigma_{pp}\big). \]

Aquí:

  • \(\sigma_{ii}\) es la varianza predicha por el modelo para la variable observada \(X_i\),

  • \(\mathbf{D}(\boldsymbol{\Sigma})^{-1/2}=\operatorname{diag}\!\left(\frac{1}{\sqrt{\sigma_{11}}},\ldots,\frac{1}{\sqrt{\sigma_{pp}}}\right)\) es la matriz que estandariza cada variable dividiendo por su desviación estándar implicada por el modelo.

En consecuencia, \(\operatorname{Cor}(\boldsymbol{\Sigma})\) es la matriz que contiene las correlaciones que el modelo CFA predice. entre los ítems.

34.0.5 Correlaciones: cálculo en R

El código

En esta sección calculamos las siguientes tres matrices de correlaciones:

  • \(\operatorname{Cor}(\mathbf{S}_{\text{cov}})\): correlaciones observadas a partir de cov(dat) (divisor \(N-1\)).

  • \(\operatorname{Cor}(\mathbf{S}_{\text{lav}})\): correlaciones observadas a partir de la matriz usada por lavaan bajo ML (divisor \(N\)).

  • \(\operatorname{Cor}(\boldsymbol{\Sigma})\): correlaciones implicadas por el modelo, construidas a partir de la matriz \(\boldsymbol{\Sigma}\) ajustada.

La función cov2cor_mat() convierte una matriz de covarianzas \(\mathbf{A}\) en su matriz de correlaciones \(\operatorname{Cor}(\mathbf{A})\) mediante la transformación:

\[ \operatorname{Cor}(\mathbf{A}) = \mathbf{D}_{\mathbf{A}}^{-1/2}\, \mathbf{A}\, \mathbf{D}_{\mathbf{A}}^{-1/2}, \qquad \mathbf{D}_{\mathbf{A}}=\operatorname{diag}(a_{11},\ldots,a_{pp}). \]

Aquí:

  • \(\mathbf{D}_{\mathbf{A}}\) es la matriz diagonal que contiene las varianzas (la diagonal de \(\mathbf{A}\)).

  • \(\mathbf{D}_{\mathbf{A}}^{-1/2}\) contiene en la diagonal \(1/\sqrt{a_{jj}}\), es decir, el inverso de las desviaciones estándar.

  • Al premultiplicar y postmultiplicar por \(\mathbf{D}^{-1/2}\), se “estandarizan” las covarianzas para que la diagonal quede en 1 y el resto sean correlaciones.

# 1) Matrices de covarianzas "observadas"
S_cov <- cov(dat)                           # clásico, divisor N-1
S_lav <- lavTech(CFA, "sampstat")[[1]]$cov  # divisor N (ML)

# 2) Matriz de covarianzas implicada por el modelo
Sigma <- fitted(CFA)$cov

# 3) Función auxiliar: Cov -> Cor
cov2cor_mat <- function(A) {
  Dinvhalf <- diag(1 / sqrt(diag(A)))
  Dinvhalf %*% A %*% Dinvhalf
}

# 4) Correlaciones observadas  (clásico, dicisor N-1)
Cor_Scov <- cov2cor_mat(S_cov)
Cor_Scov 

# 4) Correlaciones observadas (coherente con ML, lavaan, divisor N)
Cor_Slav <- cov2cor_mat(S_lav)
Cor_Slav

# 4) Correlaciones implicadas por el modelo
Cor_Sigma <- cov2cor_mat(Sigma)
Cor_Sigma

Interpretación de la salida para \(\operatorname{Cor}(\mathbf{S}_{\text{cov}})\) y \(\operatorname{Cor}(\mathbf{S}_{\text{lav}})\)

Las matrices de correlaciones observadas (desde \(\mathbf{S}_{\text{cov}}\) y \(\mathbf{S}_{\text{lav}}\)) son

Cor_Scov
##             [,1]        [,2]       [,3]      [,4]       [,5]      [,6]
##  [1,] 1.00000000  0.29734551 0.44066800 0.3727063 0.29344369 0.3567702
##  [2,] 0.29734551  1.00000000 0.33984898 0.1529302 0.13938749 0.1925319
##  [3,] 0.44066800  0.33984898 1.00000000 0.1586396 0.07719823 0.1976610
##  [4,] 0.37270627  0.15293019 0.15863957 1.0000000 0.73317017 0.7044802
##  [5,] 0.29344369  0.13938749 0.07719823 0.7331702 1.00000000 0.7199555
##  [6,] 0.35677019  0.19253190 0.19766102 0.7044802 0.71995554 1.0000000
##  [7,] 0.06686392 -0.07566892 0.07193105 0.1738291 0.10204475 0.1211017
##  [8,] 0.22392677  0.09227923 0.18601263 0.1068984 0.13866998 0.1496113
##  [9,] 0.39034041  0.20604057 0.32865061 0.2078483 0.22746642 0.2141617
##              [,7]       [,8]      [,9]
##  [1,]  0.06686392 0.22392677 0.3903404
##  [2,] -0.07566892 0.09227923 0.2060406
##  [3,]  0.07193105 0.18601263 0.3286506
##  [4,]  0.17382912 0.10689838 0.2078483
##  [5,]  0.10204475 0.13866998 0.2274664
##  [6,]  0.12110170 0.14961132 0.2141617
##  [7,]  1.00000000 0.48675793 0.3406457
##  [8,]  0.48675793 1.00000000 0.4490154
##  [9,]  0.34064572 0.44901545 1.0000000
Cor_Slav
##             [,1]        [,2]       [,3]      [,4]       [,5]      [,6]
##  [1,] 1.00000000  0.29734551 0.44066800 0.3727063 0.29344369 0.3567702
##  [2,] 0.29734551  1.00000000 0.33984898 0.1529302 0.13938749 0.1925319
##  [3,] 0.44066800  0.33984898 1.00000000 0.1586396 0.07719823 0.1976610
##  [4,] 0.37270627  0.15293019 0.15863957 1.0000000 0.73317017 0.7044802
##  [5,] 0.29344369  0.13938749 0.07719823 0.7331702 1.00000000 0.7199555
##  [6,] 0.35677019  0.19253190 0.19766102 0.7044802 0.71995554 1.0000000
##  [7,] 0.06686392 -0.07566892 0.07193105 0.1738291 0.10204475 0.1211017
##  [8,] 0.22392677  0.09227923 0.18601263 0.1068984 0.13866998 0.1496113
##  [9,] 0.39034041  0.20604057 0.32865061 0.2078483 0.22746642 0.2141617
##              [,7]       [,8]      [,9]
##  [1,]  0.06686392 0.22392677 0.3903404
##  [2,] -0.07566892 0.09227923 0.2060406
##  [3,]  0.07193105 0.18601263 0.3286506
##  [4,]  0.17382912 0.10689838 0.2078483
##  [5,]  0.10204475 0.13866998 0.2274664
##  [6,]  0.12110170 0.14961132 0.2141617
##  [7,]  1.00000000 0.48675793 0.3406457
##  [8,]  0.48675793 1.00000000 0.4490154
##  [9,]  0.34064572 0.44901545 1.0000000

En estos resultados se observa que:

\[ \operatorname{Cor}(\mathbf{S}_{\text{cov}}) = \operatorname{Cor}(\mathbf{S}_{\text{lav}}) = \begin{pmatrix} 1.0000 & 0.2973 & 0.4407 & 0.3727 & 0.2934 & 0.3568 & 0.0669 & 0.2239 & 0.3903 \\ 0.2973 & 1.0000 & 0.3398 & 0.1529 & 0.1394 & 0.1925 & -0.0757 & 0.0923 & 0.2060 \\ 0.4407 & 0.3398 & 1.0000 & 0.1586 & 0.0772 & 0.1977 & 0.0719 & 0.1860 & 0.3287 \\ 0.3727 & 0.1529 & 0.1586 & 1.0000 & 0.7332 & 0.7045 & 0.1738 & 0.1069 & 0.2078 \\ 0.2934 & 0.1394 & 0.0772 & 0.7332 & 1.0000 & 0.7200 & 0.1020 & 0.1387 & 0.2275 \\ 0.3568 & 0.1925 & 0.1977 & 0.7045 & 0.7200 & 1.0000 & 0.1211 & 0.1496 & 0.2142 \\ 0.0669 & -0.0757 & 0.0719 & 0.1738 & 0.1020 & 0.1211 & 1.0000 & 0.4868 & 0.3406 \\ 0.2239 & 0.0923 & 0.1860 & 0.1069 & 0.1387 & 0.1496 & 0.4868 & 1.0000 & 0.4490 \\ 0.3903 & 0.2060 & 0.3287 & 0.2078 & 0.2275 & 0.2142 & 0.3406 & 0.4490 & 1.0000 \end{pmatrix}. \]

Esto es esperable porque \(\mathbf{S}_{\text{cov}}\) y \(\mathbf{S}_{\text{lav}}\) difieren únicamente por un factor de escala global:

\[ \mathbf{S}_{\text{cov}} = \frac{N}{N-1}\,\mathbf{S}_{\text{lav}}. \]

Al convertir covarianzas a correlaciones, ese factor se elimina automáticamente, ya que se divide por las desviaciones estándar (raíces de las varianzas en la diagonal). Por eso, aunque las covarianzas cambien levemente (por el divisor \(N-1\) vs. \(N\)), las correlaciones observadas terminan siendo iguales (salvo diferencias por redondeo).

34.0.5.1 Interpretación de la salida para \(\operatorname{Cor}(\boldsymbol{\Sigma})\)

La matriz de correlaciones implicadas por el modelo es:

Cor_Sigma
##            [,1]      [,2]      [,3]      [,4]      [,5]      [,6]      [,7]
##  [1,] 1.0000000 0.3269693 0.4485647 0.3013872 0.3026199 0.2965838 0.2068457
##  [2,] 0.3269693 1.0000000 0.2461682 0.1653986 0.1660751 0.1627625 0.1135150
##  [3,] 0.4485647 0.2461682 1.0000000 0.2269080 0.2278361 0.2232916 0.1557297
##  [4,] 0.3013872 0.1653986 0.2269080 1.0000000 0.7281585 0.7136345 0.1372444
##  [5,] 0.3026199 0.1660751 0.2278361 0.7281585 1.0000000 0.7165535 0.1378057
##  [6,] 0.2965838 0.1627625 0.2232916 0.7136345 0.7165535 1.0000000 0.1350570
##  [7,] 0.2068457 0.1135150 0.1557297 0.1372444 0.1378057 0.1350570 1.0000000
##  [8,] 0.2626071 0.1441164 0.1977113 0.1742427 0.1749554 0.1714657 0.4117844
##  [9,] 0.2415290 0.1325489 0.1818420 0.1602571 0.1609126 0.1577030 0.3787325
##            [,8]      [,9]
##  [1,] 0.2626071 0.2415290
##  [2,] 0.1441164 0.1325489
##  [3,] 0.1977113 0.1818420
##  [4,] 0.1742427 0.1602571
##  [5,] 0.1749554 0.1609126
##  [6,] 0.1714657 0.1577030
##  [7,] 0.4117844 0.3787325
##  [8,] 1.0000000 0.4808312
##  [9,] 0.4808312 1.0000000

\[ \operatorname{Cor}(\boldsymbol{\Sigma}) = \begin{pmatrix} 1.0000 & 0.3270 & 0.4486 & 0.3014 & 0.3026 & 0.2966 & 0.2068 & 0.2626 & 0.2415 \\ 0.3270 & 1.0000 & 0.2462 & 0.1654 & 0.1661 & 0.1628 & 0.1135 & 0.1441 & 0.1325 \\ 0.4486 & 0.2462 & 1.0000 & 0.2269 & 0.2278 & 0.2233 & 0.1557 & 0.1977 & 0.1818 \\ 0.3014 & 0.1654 & 0.2269 & 1.0000 & 0.7282 & 0.7136 & 0.1372 & 0.1742 & 0.1603 \\ 0.3026 & 0.1661 & 0.2278 & 0.7282 & 1.0000 & 0.7166 & 0.1378 & 0.1750 & 0.1609 \\ 0.2966 & 0.1628 & 0.2233 & 0.7136 & 0.7166 & 1.0000 & 0.1351 & 0.1715 & 0.1577 \\ 0.2068 & 0.1135 & 0.1557 & 0.1372 & 0.1378 & 0.1351 & 1.0000 & 0.4118 & 0.3787 \\ 0.2626 & 0.1441 & 0.1977 & 0.1742 & 0.1750 & 0.1715 & 0.4118 & 1.0000 & 0.4808 \\ 0.2415 & 0.1325 & 0.1818 & 0.1603 & 0.1609 & 0.1577 & 0.3787 & 0.4808 & 1.0000 \end{pmatrix}. \]

Se resalta que la matriz \(\operatorname{Cor}(\boldsymbol{\Sigma})\) no tiene por qué coincidir con las correlaciones observadas, porque resume lo que el modelo CFA implica bajo su estructura (factores, cargas, varianzas y covarianzas estimadas). Por ejemplo, en el output:

  • La correlación observada entre \(x_1\) y \(x_2\) es \(0.2973\).

  • La correlación implicada por el modelo entre \(x_1\) y \(x_2\) es \(0.3270\).

La diferencia entre ambas se interpreta luego como evidencia de misfit local en escala de correlaciones (esto será exactamente lo que capturan las matrices residuales \(\mathbf{R}_{\text{cor}}\)).

34.0.6 Observación clave

Las matrices \(\operatorname{Cor}(\mathbf{S}_{\text{cov}})\), \(\operatorname{Cor}(\mathbf{S}_{\text{lav}})\) y \(\operatorname{Cor}(\boldsymbol{\Sigma})\) constituyen los bloques fundamentales del análisis de ajuste en escala de correlaciones en CFA/SEM.

Las dos primeras representan las correlaciones observadas (obtenidas a partir de la matriz muestral clásica y de la matriz coherente con ML, respectivamente), mientras que \(\operatorname{Cor}(\boldsymbol{\Sigma})\) recoge las correlaciones implicadas por el modelo bajo sus supuestos estructurales.

En la siguiente sección, estas matrices se combinarán para construir las matrices de correlaciones residuales, las cuales cuantifican de forma directa y comparable las discrepancias entre lo observado y lo implicado por el modelo. Este contraste en escala de correlaciones es especialmente útil para el diagnóstico de misfit local, ya que elimina los efectos de escala propios de las covarianzas y permite interpretar las discrepancias en términos estandarizados.

35 Extrayendo la matriz de covarianzas residuales

35.0.1 Covarianzas residuales: escala original (no estandarizadas)

La matriz de covarianzas residuales en escala de covarianzas originales (sin estandarizar) representa las discrepancias entre las covarianzas observadas en los datos y las covarianzas implicadas por el modelo CFA ajustado. En CFA/SEM es útil distinguir dos matrices residuales en escala de covarianzas (no estandarizadas), según qué matriz muestral se tome como observada. Estas dos matrices responden a criterios muestrales distintos y, por tanto, no deben esperarse iguales en valor numérico.
  1. Residual clásico (descriptivo), basado en cov():

\[ \mathbf{R}_{\text{cov}} = \mathbf{S}_{\text{cov}}-\boldsymbol{\Sigma}, \qquad \mathbf{S}_{\text{cov}} = \frac{1}{N-1}\sum_{i=1}^N(\mathbf{x}_i-\bar{\mathbf{x}})(\mathbf{x}_i-\bar{\mathbf{x}})^\top . \]

  1. Residual coherente con ML (lavaan), basado en la matriz usada internamente por el ajuste:

\[ \mathbf{R}_{\text{lav}} = \mathbf{S}_{\text{lav}}-\boldsymbol{\Sigma}, \qquad \mathbf{S}_{\text{lav}} = \frac{1}{N}\sum_{i=1}^N(\mathbf{x}_i-\bar{\mathbf{x}})(\mathbf{x}_i-\bar{\mathbf{x}})^\top . \]

Código en R

# 1) Matriz muestral clásica (divisor N-1)
S_cov <- cov(dat)

# 2) Matriz muestral usada por lavaan bajo ML (divisor N)
S_lav <- lavTech(CFA, "sampstat")[[1]]$cov

# 3) Matriz de covarianzas implícita por el modelo (ajustada, ML)
Sigma_hat <- fitted(CFA)$cov   # equivalente a fitted.values(CFA)$cov

# 4) Dos versiones de residuales (escala covarianzas)
R_cov <- S_cov - Sigma_hat
R_cov

R_lav <- S_lav - Sigma_hat
R_lav

El output

La matriz residual basada en \(\mathbf{S}_{\text{cov}}\) es:

R_cov
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.005                                                        
## x2 -0.039  0.005                                                 
## x3 -0.008  0.126  0.004                                          
## x4  0.098 -0.016 -0.089  0.005                                   
## x5 -0.012 -0.040 -0.219  0.011  0.006                            
## x6  0.078  0.039 -0.031 -0.009  0.008  0.004                     
## x7 -0.177 -0.242 -0.103  0.047 -0.050 -0.016  0.004              
## x8 -0.045 -0.061 -0.013 -0.079 -0.047 -0.024  0.084  0.003       
## x9  0.176  0.088  0.168  0.057  0.087  0.063 -0.040 -0.031  0.003

Es decir,

\[ \mathbf{R}_{\text{cov}} = \mathbf{S}_{\text{cov}}-\boldsymbol{\Sigma}= \begin{pmatrix} 0.005 & -0.039 & -0.008 & 0.098 & -0.012 & 0.078 & -0.177 & -0.045 & 0.176 \\ -0.039 & 0.005 & 0.126 & -0.016 & -0.040 & 0.039 & -0.242 & -0.061 & 0.088 \\ -0.008 & 0.126 & 0.004 & -0.089 & -0.219 & -0.031 & -0.103 & -0.013 & 0.168 \\ 0.098 & -0.016 & -0.089 & 0.005 & 0.011 & -0.009 & 0.047 & -0.079 & 0.057 \\ -0.012 & -0.040 & -0.219 & 0.011 & 0.006 & 0.008 & -0.050 & -0.047 & 0.087 \\ 0.078 & 0.039 & -0.031 & -0.009 & 0.008 & 0.004 & -0.016 & -0.024 & 0.063 \\ -0.177 & -0.242 & -0.103 & 0.047 & -0.050 & -0.016 & 0.004 & 0.084 & -0.040 \\ -0.045 & -0.061 & -0.013 & -0.079 & -0.047 & -0.024 & 0.084 & 0.003 & -0.031 \\ 0.176 & 0.088 & 0.168 & 0.057 & 0.087 & 0.063 & -0.040 & -0.031 & 0.003 \end{pmatrix}. \]

La matriz residual basada en \(\mathbf{S}_{\text{lav}}\) es:

R_lav
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.041  0.000                                                 
## x3 -0.010  0.124  0.000                                          
## x4  0.097 -0.017 -0.090  0.000                                   
## x5 -0.014 -0.040 -0.219  0.008  0.000                            
## x6  0.077  0.038 -0.032 -0.012  0.005  0.000                     
## x7 -0.177 -0.242 -0.103  0.046 -0.050 -0.017  0.000              
## x8 -0.046 -0.062 -0.013 -0.079 -0.047 -0.024  0.082  0.000       
## x9  0.175  0.087  0.167  0.056  0.086  0.062 -0.042 -0.032  0.000

\[ \mathbf{R}_{\text{lav}} = \mathbf{S}_{\text{lav}}-\boldsymbol{\Sigma} = \begin{pmatrix} 0.000 & -0.041 & -0.010 & 0.097 & -0.014 & 0.077 & -0.177 & -0.046 & 0.175 \\ -0.041 & 0.000 & 0.124 & -0.017 & -0.040 & 0.038 & -0.242 & -0.062 & 0.087 \\ -0.010 & 0.124 & 0.000 & -0.090 & -0.219 & -0.032 & -0.103 & -0.013 & 0.167 \\ 0.097 & -0.017 & -0.090 & 0.000 & 0.008 & -0.012 & 0.046 & -0.079 & 0.056 \\ -0.014 & -0.040 & -0.219 & 0.008 & 0.000 & 0.005 & -0.050 & -0.047 & 0.086 \\ 0.077 & 0.038 & -0.032 & -0.012 & 0.005 & 0.000 & -0.017 & -0.024 & 0.062 \\ -0.177 & -0.242 & -0.103 & 0.046 & -0.050 & -0.017 & 0.000 & 0.082 & -0.042 \\ -0.046 & -0.062 & -0.013 & -0.079 & -0.047 & -0.024 & 0.082 & 0.000 & -0.032 \\ 0.175 & 0.087 & 0.167 & 0.056 & 0.086 & 0.062 & -0.042 & -0.032 & 0.000 \end{pmatrix}. \]

Mensaje clave

El paquete lavaan (con estimador de máxima verosimilitud, ML) no compara el modelo contra la covarianza descriptiva clásica, sino contra la matriz de covarianzas muestrales utilizada internamente por el estimador ML, \(\mathbf{S}_{\text{lav}}\). Por esta razón, la salida de residuals(fit)$cov coincide con \(\mathbf{R}_{\text{lav}}\) y no con \(\mathbf{R}_{\text{cov}}\).

# 5) Residuos crudos reportados por lavaan
residuals(CFA)
R_raw <- residuals(CFA)$cov

# 6) Verificación típica:
all.equal(R_lav, R_raw)   # 6a) Suele dar TRUE (o muy cercano)
all.equal(R_cov, R_raw)   # 6b) NO debe dar TRUE

La verificación esperada es:

  • all.equal(R_lav, R_raw_lavaan) debe generar TRUE (o casi TRUE), lo que confirma que lavaan define sus residuos crudos como
    \[ \mathbf{R}_{\text{raw}} = \mathbf{S}_{\text{lav}} - \boldsymbol{\Sigma}. \]
## [1] TRUE
  • all.equal(R_cov, R_raw_lavaan) no debe ser TRUE, ya que \(\mathbf{S}_{\text{cov}}\) y \(\mathbf{S}_{\text{lav}}\) utilizan divisores distintos (\(N-1\) vs. \(N\)) y, por tanto, generan residuos numéricamente diferentes.
## [1] "Mean relative difference: 0.02342357"

Observe que, en general, laS salidas de residuals(CFA) y residuals(CFA)$cov son:

residuals(CFA)
## $type
## [1] "raw"
## 
## $cov
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.041  0.000                                                 
## x3 -0.010  0.124  0.000                                          
## x4  0.097 -0.017 -0.090  0.000                                   
## x5 -0.014 -0.040 -0.219  0.008  0.000                            
## x6  0.077  0.038 -0.032 -0.012  0.005  0.000                     
## x7 -0.177 -0.242 -0.103  0.046 -0.050 -0.017  0.000              
## x8 -0.046 -0.062 -0.013 -0.079 -0.047 -0.024  0.082  0.000       
## x9  0.175  0.087  0.167  0.056  0.086  0.062 -0.042 -0.032  0.000
R_raw
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.041  0.000                                                 
## x3 -0.010  0.124  0.000                                          
## x4  0.097 -0.017 -0.090  0.000                                   
## x5 -0.014 -0.040 -0.219  0.008  0.000                            
## x6  0.077  0.038 -0.032 -0.012  0.005  0.000                     
## x7 -0.177 -0.242 -0.103  0.046 -0.050 -0.017  0.000              
## x8 -0.046 -0.062 -0.013 -0.079 -0.047 -0.024  0.082  0.000       
## x9  0.175  0.087  0.167  0.056  0.086  0.062 -0.042 -0.032  0.000

respectivamente. Observe que

\[\mathbf{R}_{\text{raw}} = \mathbf{R}_{\text{lav}} \]

Nota.

Las matrices \(\mathbf{R}_{\text{cov}}\) y \(\mathbf{R}_{\text{lav}}\) representan residuos de covarianzas calculados bajo distintos criterios muestrales. Aunque conceptualmente ambas cuantifican \(\mathbf{S} - \boldsymbol{\Sigma}\), sus valores numéricos difieren debido al uso de divisores distintos (\(N-1\) frente a \(N\)), siendo \(\mathbf{R}_{\text{lav}}\) la matriz coherente con la estimación por máxima verosimilitud utilizada internamente por lavaan.

35.0.2 Covarianzas residuales (como resta de matrices): en escala de correlaciones (no z), sin estandarizar

Idea central

En CFA/SEM, una estrategia habitual para diagnosticar misfit local consiste en evaluar las discrepancias entre lo observado y lo implicado por el modelo en la escala de correlaciones. Esta escala elimina los efectos de magnitud propios de las covarianzas y permite comparaciones directas entre pares de variables. Para cualquier matriz de covarianzas \(\mathbf{A}\), su versión en correlaciones se define como:

\[ \operatorname{Cor}(\mathbf{A}) = \mathbf{D}_{\mathbf{A}}^{-1/2}\, \mathbf{A}\, \mathbf{D}_{\mathbf{A}}^{-1/2}, \qquad \mathbf{D}_{\mathbf{A}}=\operatorname{diag}(a_{11},\ldots,a_{pp}), \]

donde \(\mathbf{D}_{\mathbf{A}}\) es la matriz diagonal que contiene las varianzas asociadas a \(\mathbf{A}\). Con esta transformación, la matriz de covarianzas residuales en escala de correlaciones se define como la diferencia entre:

  • La matriz de correlaciones observadas, obtenida a partir de una matriz de covarianzas muestrales, y

  • La matriz de correlaciones implicadas por el modelo, construida a partir de la matriz de covarianzas \(\boldsymbol{\Sigma}\) estimada bajo el modelo CFA.

Dos versiones

En particular, es útil distinguir dos versiones de esta matriz residual, dependiendo de qué matriz muestral se tome como referencia observada:

  1. Residuales en correlaciones (descriptivos). Basados en la matriz de covarianzas muestral clásica \(\mathbf{S}_{\text{cov}}\):

\[ \mathbf{R}_{\text{cor,cov}} = \operatorname{Cor}(\mathbf{S}_{\text{cov}}) - \operatorname{Cor}(\boldsymbol{\Sigma}), \qquad \mathbf{S}_{\text{cov}} = \frac{1}{N-1} \sum_{i=1}^N (\mathbf{x}_i-\bar{\mathbf{x}}) (\mathbf{x}_i-\bar{\mathbf{x}})^\top. \]

Esta versión tiene un carácter descriptivo, ya que utiliza la matriz de covarianzas clásica empleada en estadística exploratoria.

  1. Residuales en correlaciones coherentes con ML (lavaan). Basados en la matriz de covarianzas utilizada internamente por lavaan bajo máxima verosimilitud:

\[ \mathbf{R}_{\text{cor,lav}} = \operatorname{Cor}(\mathbf{S}_{\text{lav}}) - \operatorname{Cor}(\boldsymbol{\Sigma}), \qquad \mathbf{S}_{\text{lav}} = \frac{1}{N} \sum_{i=1}^N (\mathbf{x}_i-\bar{\mathbf{x}}) (\mathbf{x}_i-\bar{\mathbf{x}})^\top. \]

Esta es la versión conceptualmente coherente con el ajuste ML y, por tanto, la más alineada con los residuos que reporta lavaan cuando se solicitan resultados en escala de correlaciones.

Esta definición aclara que la matriz \(\mathbf{R}_{\text{cor, lav}}\) no corresponde a la resta directa de covarianzas \(\mathbf{R}_{\text{cov}}=\mathbf{S}_{\text{cov}} - \boldsymbol{\Sigma}\) (o \(\mathbf{R}_{\text{lav}}=\mathbf{S}_{\text{lav}} - \boldsymbol{\Sigma}\) ), sino a la discrepancia entre matrices expresadas en una escala estandarizada.

Interpretación estadística de la matriz de covarianzas residuales

Cada elemento \(r_{ij}\) de la matriz de covarianzas residuales (\(\mathbf{R}_{\text{cor, cov}}\) o \(\mathbf{R}_{\text{cor, lav}}\)) se define como:

\[ r_{ij} = \operatorname{cor}(X_i, X_j) - \operatorname{cor}_{\text{modelo}}(X_i, X_j), \]

y cuantifica la parte de la covarianza entre los ítems \(X_i\) y \(X_j\) que no es explicada por el modelo CFA ajustado. En particular:

  • Valores cercanos a 0 (\(r_{ij} \approx 0\)) implica buen ajuste local del modelo. Es decir, el modelo explica exactamente la relación entre \(X_i\) y \(X_j\).

  • Valores grandes en valor absoluto (\(r_{ij} \neq 0\)) sugieren la presencia de desajuste local (local misfit). Es decir, existe asociación entre \(X_i\) y \(X_j\) no capturada por el modelo.

  • El objetivo general del análisis CFA es que la matriz residual satisfaga \(R \approx 0\).

Con residuales estandarizados pueden emplearse criterios empíricos claros, por ejemplo:

  • Si \(\lvert r_{ij} \rvert < 0.05\), entonces, hay un ajuste local excelente.

  • Si \(0.05 \le \lvert r_{ij} \rvert < 0.10\), entonces, hay un ajuste local aceptable.

  • Si \(\lvert r_{ij} \rvert \ge 0.10\), entonces, hay un potencial problema de ajuste local. Es decir, los residuales de correlación con valores absolutos superiores a 0.10 sugieren asociaciones no explicadas por el modelo CFA y constituyen candidatos naturales para un análisis más detallado mediante índices de modificación o revisión teórica del modelo.

Este tipo de evaluación no es posible de forma directa y comparable cuando se trabaja con covarianzas no estandarizadas.

Cálculo de la matriz de correlaciones residuales en R (como resta de matrices)

En esta sección calculamos las matrices de correlaciones residuales como resta de matrices. Para pasar de covarianzas a correlaciones usamos la transformación \(\operatorname{Cor}(\mathbf{A})\) definida anteriormente. El código correspondiente es:

# 1) Matrices de covarianzas "observadas"
S_cov <- cov(dat)                           # divisor N-1
S_lav <- lavTech(CFA, "sampstat")[[1]]$cov  # divisor N (ML)

# 2) Matriz de covarianzas implicada por el modelo
Sigma <- fitted(CFA)$cov

# 3) Función auxiliar: Cov -> Cor
cov2cor_mat <- function(A) {
  Dinvhalf <- diag(1 / sqrt(diag(A)))
  Dinvhalf %*% A %*% Dinvhalf
}

# 4) Correlaciones observadas e implicadas
Cor_Scov <- cov2cor_mat(S_cov)
Cor_Slav <- cov2cor_mat(S_lav)
Cor_Sigma <- cov2cor_mat(Sigma)

# 5) Dos versiones del residual en correlaciones
R_cor_cov <- Cor_Scov - Cor_Sigma
R_cor_lav <- Cor_Slav - Cor_Sigma

R_cor_cov
R_cor_lav

Se obtienen:

R_cor_cov
##               [,1]          [,2]          [,3]          [,4]         [,5]
##  [1,]  0.000000000 -2.962380e-02 -7.896667e-03  7.131910e-02 -0.009176244
##  [2,] -0.029623801  2.220446e-16  9.368075e-02 -1.246837e-02 -0.026687592
##  [3,] -0.007896667  9.368075e-02 -3.330669e-16 -6.826841e-02 -0.150637875
##  [4,]  0.071319095 -1.246837e-02 -6.826841e-02 -2.220446e-16  0.005011633
##  [5,] -0.009176244 -2.668759e-02 -1.506379e-01  5.011633e-03  0.000000000
##  [6,]  0.060186395  2.976940e-02 -2.563060e-02 -9.154239e-03  0.003402082
##  [7,] -0.139981768 -1.891840e-01 -8.379866e-02  3.658475e-02 -0.035760980
##  [8,] -0.038680367 -5.183719e-02 -1.169869e-02 -6.734432e-02 -0.036285416
##  [9,]  0.148811459  7.349166e-02  1.468086e-01  4.759121e-02  0.066553827
##                [,6]          [,7]          [,8]          [,9]
##  [1,]  6.018640e-02 -1.399818e-01 -3.868037e-02  1.488115e-01
##  [2,]  2.976940e-02 -1.891840e-01 -5.183719e-02  7.349166e-02
##  [3,] -2.563060e-02 -8.379866e-02 -1.169869e-02  1.468086e-01
##  [4,] -9.154239e-03  3.658475e-02 -6.734432e-02  4.759121e-02
##  [5,]  3.402082e-03 -3.576098e-02 -3.628542e-02  6.655383e-02
##  [6,] -2.220446e-16 -1.395533e-02 -2.185437e-02  5.645876e-02
##  [7,] -1.395533e-02  2.220446e-16  7.497350e-02 -3.808680e-02
##  [8,] -2.185437e-02  7.497350e-02  4.440892e-16 -3.181577e-02
##  [9,]  5.645876e-02 -3.808680e-02 -3.181577e-02 -2.220446e-16
R_cor_lav
##               [,1]          [,2]         [,3]          [,4]         [,5]
##  [1,]  0.000000000 -2.962380e-02 -0.007896667  7.131910e-02 -0.009176244
##  [2,] -0.029623801  2.220446e-16  0.093680752 -1.246837e-02 -0.026687592
##  [3,] -0.007896667  9.368075e-02  0.000000000 -6.826841e-02 -0.150637875
##  [4,]  0.071319095 -1.246837e-02 -0.068268413 -2.220446e-16  0.005011633
##  [5,] -0.009176244 -2.668759e-02 -0.150637875  5.011633e-03  0.000000000
##  [6,]  0.060186395  2.976940e-02 -0.025630597 -9.154239e-03  0.003402082
##  [7,] -0.139981768 -1.891840e-01 -0.083798661  3.658475e-02 -0.035760980
##  [8,] -0.038680367 -5.183719e-02 -0.011698686 -6.734432e-02 -0.036285416
##  [9,]  0.148811459  7.349166e-02  0.146808608  4.759121e-02  0.066553827
##                [,6]          [,7]          [,8]        [,9]
##  [1,]  6.018640e-02 -1.399818e-01 -3.868037e-02  0.14881146
##  [2,]  2.976940e-02 -1.891840e-01 -5.183719e-02  0.07349166
##  [3,] -2.563060e-02 -8.379866e-02 -1.169869e-02  0.14680861
##  [4,] -9.154239e-03  3.658475e-02 -6.734432e-02  0.04759121
##  [5,]  3.402082e-03 -3.576098e-02 -3.628542e-02  0.06655383
##  [6,] -1.110223e-16 -1.395533e-02 -2.185437e-02  0.05645876
##  [7,] -1.395533e-02  2.220446e-16  7.497350e-02 -0.03808680
##  [8,] -2.185437e-02  7.497350e-02  4.440892e-16 -0.03181577
##  [9,]  5.645876e-02 -3.808680e-02 -3.181577e-02  0.00000000

En este conjunto de datos ocurre algo particular:

\[ \operatorname{Cor}(\mathbf{S}_{\text{cov}}) = \operatorname{Cor}(\mathbf{S}_{\text{lav}}). \]

Esto se debe a que \(\mathbf{S}_{\text{cov}}\) y \(\mathbf{S}_{\text{lav}}\) difieren únicamente por un factor escalar global, dado por:

\[ \mathbf{S}_{\text{cov}} = \frac{N}{N-1}\,\mathbf{S}_{\text{lav}}. \]

Al transformar una matriz de covarianzas a correlaciones, dicho factor escalar se cancela automáticamente, ya que la estandarización divide cada elemento por las desviaciones estándar correspondientes. Por esta razón, en este caso se obtiene que las matrices de correlaciones residuales coinciden:

\[ \mathbf{R}_{\text{cor,cov}} = \mathbf{R}_{\text{cor,lav}}. \]

En particular, la matriz residual en escala de correlaciones es la misma independientemente de si se parte de \(\mathbf{S}_{\text{cov}}\) o de \(\mathbf{S}_{\text{lav}}\), y corresponde a la discrepancia entre la correlaciones observadas y las correlaciones implicadas por el modelo.

\[ \mathbf{R}_{\text{cor, cov}} = \mathbf{R}_{\text{cor, lav}} = \begin{pmatrix} 0.000 & -0.030 & -0.008 & 0.071 & -0.009 & 0.060 & -0.140 & -0.039 & 0.149 \\ -0.030 & 0.000 & 0.094 & -0.012 & -0.027 & 0.030 & -0.189 & -0.052 & 0.073 \\ -0.008 & 0.094 & 0.000 & -0.068 & -0.151 & -0.026 & -0.084 & -0.012 & 0.147 \\ 0.071 & -0.012 & -0.068 & 0.000 & 0.005 & -0.009 & 0.037 & -0.067 & 0.048 \\ -0.009 & -0.027 & -0.151 & 0.005 & 0.000 & 0.003 & -0.036 & -0.036 & 0.067 \\ 0.060 & 0.030 & -0.026 & -0.009 & 0.003 & 0.000 & -0.014 & -0.022 & 0.056 \\ -0.140 & -0.189 & -0.084 & 0.037 & -0.036 & -0.014 & 0.000 & 0.075 & -0.038 \\ -0.039 & -0.052 & -0.012 & -0.067 & -0.036 & -0.022 & 0.075 & 0.000 & -0.032 \\ 0.149 & 0.073 & 0.147 & 0.048 & 0.067 & 0.056 & -0.038 & -0.032 & 0.000 \end{pmatrix}. \]

35.0.3 Covarianzas residuales: interpretación de valores residuales de la matriz

A continuación se destacan los residuales más relevantes, considerando su valor absoluto.

Residuales grandes (posible misfit local)

\[ r_{7,2} = -0.189, \qquad r_{7,1} = -0.140, \qquad r_{9,1} = 0.149, \qquad r_{9,3} = 0.147, \qquad r_{5,3} = -0.151. \]

Estos valores superan claramente el umbral de \(0.10\), lo que sugiere:

  • Asociaciones entre ítems no explicadas por los factores latentes,

  • Posibles cargas cruzadas no especificadas, o

  • La necesidad de introducir covarianzas residuales entre esos ítems.

Residuales moderados (inspeccionar)

\[ r_{3,2} = 0.094, \qquad r_{4,1} = 0.071, \qquad r_{8,7} = 0.075. \]

Estos valores no son alarmantes, pero merecen inspección, especialmente si existe una justificación teórica para una relación adicional entre los ítems involucrados.

Residuales pequeños (buen ajuste local)

La mayoría de los residuales presentan valores cercanos a cero, por ejemplo:

\[ r_{6,5} = 0.003, \qquad r_{4,5} = 0.005, \qquad r_{3,1} = -0.008. \]

Estos pares de ítems están adecuadamente explicados por el modelo CFA ajustado, lo que indica un buen ajuste local en dichas relaciones.

35.0.4 Covarianzas residuales (usando residuals): en escala de correlaciones (no z), sin estandarizar

Correlaciones residuales: la función residuals() en lavaan

Hasta ahora, las matrices de correlaciones residuales se han construido explícitamente como una resta de matrices:

\[ \mathbf{R}_{\text{cor}} = \operatorname{Cor}(\mathbf{S}) - \operatorname{Cor}(\boldsymbol{\Sigma}). \]

Sin embargo, cuando se trabaja con modelos CFA ajustados con lavaan, no es necesario realizar este cálculo manualmente. El paquete proporciona una forma directa de obtener estas discrepancias en escala de correlaciones.

Correlaciones residuales: aplicando residuals() en lavaan

La función residuals() del paquete lavaan calcula los residuos del modelo ajustado, es decir, las discrepancias entre las relaciones observadas en los datos y las relaciones implicadas por el modelo CFA. La opción type = "cor" solicita explícitamente que dichas discrepancias se expresen en escala de correlaciones y permite evaluar el ajuste local del modelo de forma comparable entre pares de ítems.. Esta es la misma escala definida anteriormente mediante la transformación: \(\operatorname{Cor}(\mathbf{A}) = \mathbf{D}_{\mathbf{A}}^{-1/2}\, \mathbf{A}\, \mathbf{D}_{\mathbf{A}}^{-1/2}\), donde \(\mathbf{D}_{\mathbf{A}}\) es la matriz diagonal que contiene las varianzas (asociadas a los elementos diagonales de \(\mathbf{A}\)).

# Correlaciones residuales reportadas directamente por lavaan
residuals(CFA, type = "cor")
## $type
## [1] "cor.bollen"
## 
## $cov
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.030  0.000                                                 
## x3 -0.008  0.094  0.000                                          
## x4  0.071 -0.012 -0.068  0.000                                   
## x5 -0.009 -0.027 -0.151  0.005  0.000                            
## x6  0.060  0.030 -0.026 -0.009  0.003  0.000                     
## x7 -0.140 -0.189 -0.084  0.037 -0.036 -0.014  0.000              
## x8 -0.039 -0.052 -0.012 -0.067 -0.036 -0.022  0.075  0.000       
## x9  0.149  0.073  0.147  0.048  0.067  0.056 -0.038 -0.032  0.000

El componente ...$cov permite extraer específicamente la matriz de covarianzas residuales a partir del objeto devuelto por residuals().

# Correlaciones residuales reportadas directamente por lavaan
R_cor <- residuals(CFA, type = "cor")$cov
R_cor
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.030  0.000                                                 
## x3 -0.008  0.094  0.000                                          
## x4  0.071 -0.012 -0.068  0.000                                   
## x5 -0.009 -0.027 -0.151  0.005  0.000                            
## x6  0.060  0.030 -0.026 -0.009  0.003  0.000                     
## x7 -0.140 -0.189 -0.084  0.037 -0.036 -0.014  0.000              
## x8 -0.039 -0.052 -0.012 -0.067 -0.036 -0.022  0.075  0.000       
## x9  0.149  0.073  0.147  0.048  0.067  0.056 -0.038 -0.032  0.000

Se observa que \(\mathbf{R}_{\text{cor}}\) es la misma matriz hallada anteriormente (\(\mathbf{R}_{\text{cor,cov}}\) y \(\mathbf{R}_{\text{cor,lav}}\)).

Importante (distinción clave): aplicando resid en lavaan

Importante (distinción clave):

Las matrices \(\mathbf{R}_{\text{cor,cov}}\) y \(\mathbf{R}_{\text{cor,lav}}\) están expresadas en escala de correlaciones (valores entre \(-1\) y \(1\)), pero no corresponden a residuos estandarizados tipo z. Los residuos tipo z, que incorporan además una normalización por la variabilidad esperada bajo el modelo, se explicarán en la sección siguiente. Estos últimos son los más apropiados cuando se desea evaluar la magnitud del misfit local en términos de desviaciones estándar.

resid(fit, type = "standardized")

35.0.5 Covarianzas residuales (usando resid): en escala de correlaciones estandarizada (normalizada)

La función resid

Las funciones resid() y residuals() en lavaan devuelven los residuos del modelo ajustado, es decir, las discrepancias entre lo observado en los datos y lo implicado por el modelo. La matriz devuelta por resid(CFA, type = "standardized") corresponde a una versión estandarizada (normalizada) de los residuos de covarianzas del modelo.

resid(CFA, type="standardized")
## $type
## [1] "standardized"
## 
## $cov
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -1.996  0.000                                                 
## x3 -0.997  2.689  0.000                                          
## x4  2.679 -0.284 -1.899  0.000                                   
## x5 -0.359 -0.591 -4.157  1.545  0.000                            
## x6  2.155  0.681 -0.711 -2.588  0.942  0.000                     
## x7 -3.773 -3.654 -1.858  0.865 -0.842 -0.326  0.000              
## x8 -1.380 -1.119 -0.300 -2.021 -1.099 -0.641  4.823  0.000       
## x9  4.077  1.606  3.518  1.225  1.701  1.423 -2.325 -4.132  0.000

En términos matriciales, puede escribirse como:

\[ \mathbf{R}_{\text{std}} = \mathbf{D}^{-1/2} \left( \mathbf{S} - \boldsymbol{\Sigma} \right) \mathbf{D}^{-1/2}, \]

donde \(\mathbf{D}\) es una matriz de escalamiento que depende de las varianzas de las variables observadas y del estimador utilizado (en este caso, máxima verosimilitud, ML). Cada elemento de \(\mathbf{R}_{\text{std}}\) indica cuántas desviaciones estándar separan la covarianza observada entre dos ítems de la covarianza predicha por el modelo.

¿Qué es la matriz \(\mathbf{D}\)?

En la expresión anterior, la matriz \(\mathbf{D}\) es una matriz de escalamiento que recoge la variabilidad esperada de las covarianzas bajo el modelo ajustado. En el caso del estimador de máxima verosimilitud (ML), \(\mathbf{D}\) se construye a partir de:

  • Las varianzas de las variables observadas, y

  • La matriz de información del modelo, de modo que cada residuo quede expresado en unidades de desviación estándar.

Por esta razón, los residuos estandarizados no son simplemente \((\mathbf{S}-\boldsymbol{\Sigma})\) divididos elemento a elemento por las varianzas, sino una normalización estadísticamente informada, coherente con el estimador utilizado.

El output de la función resid(...)$cov

En este caso, con ...$cov se obtiene la matriz de residuos estandarizados:

R_std <- resid(CFA, type="standardized")$cov
R_std
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -1.996  0.000                                                 
## x3 -0.997  2.689  0.000                                          
## x4  2.679 -0.284 -1.899  0.000                                   
## x5 -0.359 -0.591 -4.157  1.545  0.000                            
## x6  2.155  0.681 -0.711 -2.588  0.942  0.000                     
## x7 -3.773 -3.654 -1.858  0.865 -0.842 -0.326  0.000              
## x8 -1.380 -1.119 -0.300 -2.021 -1.099 -0.641  4.823  0.000       
## x9  4.077  1.606  3.518  1.225  1.701  1.423 -2.325 -4.132  0.000

\[ \mathbf{R}_{\text{std}} = \begin{pmatrix} 0.000 & -1.996 & -0.997 & 2.679 & -0.359 & 2.155 & -3.773 & -1.380 & 4.077 \\ -1.996 & 0.000 & 2.689 & -0.284 & -0.591 & 0.681 & -3.654 & -1.119 & 1.606 \\ -0.997 & 2.689 & 0.000 & -1.899 & -4.157 & -0.711 & -1.858 & -0.300 & 3.518 \\ 2.679 & -0.284 & -1.899 & 0.000 & 1.545 & -2.588 & 0.865 & -2.021 & 1.225 \\ -0.359 & -0.591 & -4.157 & 1.545 & 0.000 & 0.942 & -0.842 & -1.099 & 1.701 \\ 2.155 & 0.681 & -0.711 & -2.588 & 0.942 & 0.000 & -0.326 & -0.641 & 1.423 \\ -3.773 & -3.654 & -1.858 & 0.865 & -0.842 & -0.326 & 0.000 & 4.823 & -2.325 \\ -1.380 & -1.119 & -0.300 & -2.021 & -1.099 & -0.641 & 4.823 & 0.000 & -4.132 \\ 4.077 & 1.606 & 3.518 & 1.225 & 1.701 & 1.423 & -2.325 & -4.132 & 0.000 \end{pmatrix}. \]

35.0.6 Covarianzas residuales: aclaraciones generales

Nota pedagógica

Aunque todas estas matrices se basan en la misma discrepancia fundamental \(\mathbf{S} - \boldsymbol{\Sigma}\), cada una utiliza una escala distinta. En particular, los residuos estandarizados son especialmente útiles para el diagnóstico de misfit local, ya que permiten identificar relaciones entre ítems cuya covarianza observada se aparta del modelo en más de dos o tres desviaciones estándar. En consecuencia, \(\mathbf{R}_{\text{std}}\) permite evaluar el misfit local en una escala comparable entre pares de ítems, algo que no es posible usando directamente \(\mathbf{S}-\boldsymbol{\Sigma}\).

Regla práctica para no confundirse

Compare las cuatro matrices que se describen abajo:

  • R_std = resid(CFA, type = "standardized")$cov es la matriz \(\mathbf{R}_{\text{std}}\) que contiene residuos estandarizados (valores tipo z).
R_std
  • R_cor = residuals(CFA, type = "cor")$cov es la matriz \(\mathbf{R}_{\text{cor}}\) que contiene los residuos expresados en escala de correlaciones.
R_cor
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.030  0.000                                                 
## x3 -0.008  0.094  0.000                                          
## x4  0.071 -0.012 -0.068  0.000                                   
## x5 -0.009 -0.027 -0.151  0.005  0.000                            
## x6  0.060  0.030 -0.026 -0.009  0.003  0.000                     
## x7 -0.140 -0.189 -0.084  0.037 -0.036 -0.014  0.000              
## x8 -0.039 -0.052 -0.012 -0.067 -0.036 -0.022  0.075  0.000       
## x9  0.149  0.073  0.147  0.048  0.067  0.056 -0.038 -0.032  0.000
  • \(\mathbf{R}_{\text{cov}} = \mathbf{S}_{\text{cov}} - \boldsymbol{\Sigma}\) en escala original no es lo que devuelve type = "standardized".
R_cov
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.005                                                        
## x2 -0.039  0.005                                                 
## x3 -0.008  0.126  0.004                                          
## x4  0.098 -0.016 -0.089  0.005                                   
## x5 -0.012 -0.040 -0.219  0.011  0.006                            
## x6  0.078  0.039 -0.031 -0.009  0.008  0.004                     
## x7 -0.177 -0.242 -0.103  0.047 -0.050 -0.016  0.004              
## x8 -0.045 -0.061 -0.013 -0.079 -0.047 -0.024  0.084  0.003       
## x9  0.176  0.088  0.168  0.057  0.087  0.063 -0.040 -0.031  0.003
  • \(\mathbf{R}_{\text{lav}} = \mathbf{S}_{\text{lav}} - \boldsymbol{\Sigma}\) en escala ML no es lo que devuelve type = "standardized".
R_lav
##        x1     x2     x3     x4     x5     x6     x7     x8     x9
## x1  0.000                                                        
## x2 -0.041  0.000                                                 
## x3 -0.010  0.124  0.000                                          
## x4  0.097 -0.017 -0.090  0.000                                   
## x5 -0.014 -0.040 -0.219  0.008  0.000                            
## x6  0.077  0.038 -0.032 -0.012  0.005  0.000                     
## x7 -0.177 -0.242 -0.103  0.046 -0.050 -0.017  0.000              
## x8 -0.046 -0.062 -0.013 -0.079 -0.047 -0.024  0.082  0.000       
## x9  0.175  0.087  0.167  0.056  0.086  0.062 -0.042 -0.032  0.000

36 Extrayendo covarianzas entre factores

36.0.1 Covarianza entre los factores (con inspect)

El código.

inspect(CFA, "est")
attach(inspect(CFA, "est"))

#lambda #cargas factoriales
#theta  #varianzas residuales
psi    #covarianzas entre los factores

El otuput.

##         visual textul speed
## visual   0.809             
## textual  0.408  0.979      
## speed    0.262  0.173 0.384

En este caso, se obtiene:

\[ \boldsymbol{\Psi} = \begin{pmatrix} 0.809 & 0.408 & 0.262 \\ 0.408 & 0.979 & 0.173 \\ 0.262 & 0.173 & 0.384 \end{pmatrix} \]

36.0.2 Covarianza entre los factores (otra forma)

El código.

parameterEstimates(CFA, standardized=TRUE) %>%
  filter(op == "~~",
         lhs %in% c("visual", "textual", "speed"),
         !is.na(pvalue)) %>%
  mutate(stars = ifelse(pvalue < .001, "***",
                        ifelse(pvalue < .01, "**",
                               ifelse(pvalue < .05, "*", "")))) %>%
  select('Factor 1'=lhs,
         'Factor 2'=rhs,
         'Correlación'=est,
         'Sig.'=stars) %>%
  
  kable(digits = 3,  align="c", format="pandoc", caption="Covarianzas entre los factores")

El output.

Table 36.1: Covarianzas entre los factores
Factor 1 Factor 2 Correlación Sig.
visual visual 0.809 ***
textual textual 0.979 ***
speed speed 0.384 ***
visual textual 0.408 ***
visual speed 0.262 ***
textual speed 0.173 ***

37 Extrayendo medidas de ajuste

37.0.1 Medidas de ajuste: todas

El código.

m <- inspect(CFA, 'fit.measures'); m #1. Todas las medidas
m <- fitMeasures(CFA); m             #2. Igual que el anterior

El output.

##                  npar                  fmin                 chisq 
##                21.000                 0.142                85.306 
##                    df                pvalue        baseline.chisq 
##                24.000                 0.000               918.852 
##           baseline.df       baseline.pvalue                   cfi 
##                36.000                 0.000                 0.931 
##                   tli                  nnfi                   rfi 
##                 0.896                 0.896                 0.861 
##                   nfi                  pnfi                   ifi 
##                 0.907                 0.605                 0.931 
##                   rni                  logl     unrestricted.logl 
##                 0.931             -3737.745             -3695.092 
##                   aic                   bic                ntotal 
##              7517.490              7595.339               301.000 
##                  bic2                 rmsea        rmsea.ci.lower 
##              7528.739                 0.092                 0.071 
##        rmsea.ci.upper        rmsea.ci.level          rmsea.pvalue 
##                 0.114                 0.900                 0.001 
##        rmsea.close.h0 rmsea.notclose.pvalue     rmsea.notclose.h0 
##                 0.050                 0.840                 0.080 
##                   rmr            rmr_nomean                  srmr 
##                 0.082                 0.082                 0.065 
##          srmr_bentler   srmr_bentler_nomean                  crmr 
##                 0.065                 0.065                 0.073 
##           crmr_nomean            srmr_mplus     srmr_mplus_nomean 
##                 0.073                 0.065                 0.065 
##                 cn_05                 cn_01                   gfi 
##               129.490               152.654                 0.943 
##                  agfi                  pgfi                   mfi 
##                 0.894                 0.503                 0.903 
##                  ecvi 
##                 0.423

37.0.2 Medidas de ajuste: desde una lista

El código.

lista <- c("chisq", "df", "cfi", "rmsea", "srmr", "mfi", "bic", "nfi")
lista

ms<-fitMeasures(CFA)[lista]; ms      #3. Lista específica de medidas
ms<-fitMeasures(CFA, lista); ms      #4. Igual que el anterior
ms<-round(ms,3); ms

El output.

## [1] "chisq" "df"    "cfi"   "rmsea" "srmr"  "mfi"   "bic"   "nfi"
##    chisq       df      cfi    rmsea     srmr      mfi      bic      nfi 
##   85.306   24.000    0.931    0.092    0.065    0.903 7595.339    0.907

38 Extrayendo las medias

38.0.1 Medias: explicación

  1. En general, los modelos de ecuaciones estructurales se utilizan para modelar la matriz de covarianza de las variables observadas en un conjunto de datos.

  2. No obstante, en algunas aplicaciones, es útil incluir también las medias de las variables observadas.

  3. Para lograr esto, se pueden especificar explícitamente los interceptos en la sintaxis de lavaan.

  4. Esto se realiza incluyendo “fórmulas de intercepto” en la sintaxis del modelo. Una fórmula de intercepto tiene el siguiente formato:

variable ~ 1
  1. En esta expresión, la parte izquierda contiene el nombre de la variable observada o latente, y la parte derecha contiene el número 1, que representa el intercepto.

38.0.2 Medias: ejemplo

Por ejemplo, en el modelo de análisis factorial confirmatorio (CFA) de tres factores de Holzinger y Swineford, podemos añadir los interceptos de las variables observadas de la siguiente manera:

El modelo.

# Ejemplo de sintaxis en lavaan con interceptos
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9

x1 ~ 1
x2 ~ 1
x3 ~ 1
x4 ~ 1
x5 ~ 1
x6 ~ 1
x7 ~ 1
x8 ~ 1
x9 ~ 1

39 Extrayendo con meanstructure

39.0.1 meanstructure: explicación

A veces, es más conveniente omitir las fórmulas de intercepto en la sintaxis del modelo (a menos que desee sus valores), y añadir el argumento meanstructure = TRUE en las llamadas a las funciones cfa y sem.

39.0.2 meanstructure: ejemplo

El código.

fit <- cfa(modelo, data=dat, meanstructure=TRUE)
summary(fit)

El output.

## lavaan 0.6-19 ended normally after 35 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        30
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                                85.306
##   Degrees of freedom                                24
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual =~                                           
##     x1                1.000                           
##     x2                0.554    0.100    5.554    0.000
##     x3                0.729    0.109    6.685    0.000
##   textual =~                                          
##     x4                1.000                           
##     x5                1.113    0.065   17.014    0.000
##     x6                0.926    0.055   16.703    0.000
##   speed =~                                            
##     x7                1.000                           
##     x8                1.180    0.165    7.152    0.000
##     x9                1.082    0.151    7.155    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual ~~                                           
##     textual           0.408    0.074    5.552    0.000
##     speed             0.262    0.056    4.660    0.000
##   textual ~~                                          
##     speed             0.173    0.049    3.518    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                4.936    0.067   73.473    0.000
##    .x2                6.088    0.068   89.855    0.000
##    .x3                2.250    0.065   34.579    0.000
##    .x4                3.061    0.067   45.694    0.000
##    .x5                4.341    0.074   58.452    0.000
##    .x6                2.186    0.063   34.667    0.000
##    .x7                4.186    0.063   66.766    0.000
##    .x8                5.527    0.058   94.854    0.000
##    .x9                5.374    0.058   92.546    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.549    0.114    4.833    0.000
##    .x2                1.134    0.102   11.146    0.000
##    .x3                0.844    0.091    9.317    0.000
##    .x4                0.371    0.048    7.779    0.000
##    .x5                0.446    0.058    7.642    0.000
##    .x6                0.356    0.043    8.277    0.000
##    .x7                0.799    0.081    9.823    0.000
##    .x8                0.488    0.074    6.573    0.000
##    .x9                0.566    0.071    8.003    0.000
##     visual            0.809    0.145    5.564    0.000
##     textual           0.979    0.112    8.737    0.000
##     speed             0.384    0.086    4.451    0.000

39.0.3 meanstructure: Interpretación

  1. Como puede observar en el resultado, el modelo incluye parámetros de intercepción tanto para las variables observadas como para las latentes.

  2. Por defecto, las funciones cfa y sem fijan los interceptos de las variables latentes (que en este caso corresponden a las medias latentes) a cero.

  3. De otro modo, el modelo no sería estimable.

  4. Cabe destacar que el estadístico chi-cuadrado y el número de grados de libertad son los mismos que en el modelo original (sin estructura de medias).

  5. Esto se debe a que, aunque hemos añadido nuevos datos (un valor medio para cada una de las 9 variables observadas), también hemos introducido 9 parámetros adicionales al modelo (un intercepto para cada una de las 9 variables observadas).

  6. El resultado final es un ajuste idéntico.

  7. En la práctica, la única razón para que un usuario añada fórmulas de intercepción en la sintaxis del modelo es para especificar ciertas restricciones necesarias en el modelo.

  8. Por ejemplo, revise la situación que se indica a continuación.

39.0.4 meanstructure: fijando interceptos

Por ejemplo, supongamos que deseamos x los interceptos de las variables x1, x2, x3 y x4 a, digamos, 0.5. Escribiríamos la sintaxis del modelo como sigue:

El modelo.

# Modelo de tres factores

modelo.fix <- '
visual =~ x1 + x2 + x3
textual =~ x4 + x5 + x6
speed =~ x7 + x8 + x9

# Interceptos con valores fijos
x1 + x2 + x3 + x4 ~ 0.5*1
'

Observación.

Arriba hemos utilizado el lado izquierdo de la fórmula para «repetir» el lado derecho para cada elemento del lado izquierdo.

Ejecutando CFA.

CFA.fix <- cfa(modelo.fix, data=dat)
summary(CFA.fix)
## lavaan 0.6-19 ended normally after 113 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        26
## 
##   Number of observations                           301
## 
## Model Test User Model:
##                                                       
##   Test statistic                              1120.542
##   Degrees of freedom                                28
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual =~                                           
##     x1                1.000                           
##     x2                1.224    0.020   59.759    0.000
##     x3                0.405    0.013   30.933    0.000
##   textual =~                                          
##     x4                1.000                           
##     x5                1.065    0.020   53.504    0.000
##     x6                0.890    0.017   51.989    0.000
##   speed =~                                            
##     x7                1.000                           
##     x8                1.183    0.061   19.433    0.000
##     x9                1.050    0.058   18.154    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   visual ~~                                           
##     textual          11.800    1.007   11.720    0.000
##     speed             5.152    0.500   10.296    0.000
##   textual ~~                                          
##     speed             2.995    0.298   10.040    0.000
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.500                           
##    .x2                0.500                           
##    .x3                0.500                           
##    .x4                0.500                           
##    .x5                1.625    0.050   32.530    0.000
##    .x6               -0.083    0.043   -1.932    0.053
##    .x7                3.083    0.061   50.440    0.000
##    .x8                4.222    0.056   75.567    0.000
##    .x9                4.216    0.056   75.038    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .x1                0.442    0.105    4.214    0.000
##    .x2                1.757    0.208    8.439    0.000
##    .x3                0.964    0.083   11.677    0.000
##    .x4                0.355    0.045    7.915    0.000
##    .x5                0.463    0.055    8.479    0.000
##    .x6                0.361    0.041    8.891    0.000
##    .x7                0.791    0.076   10.380    0.000
##    .x8                0.473    0.061    7.730    0.000
##    .x9                0.582    0.062    9.389    0.000
##     visual           20.593    1.717   11.993    0.000
##     textual           7.554    0.645   11.713    0.000
##     speed             1.610    0.189    8.510    0.000

40 Extrayendo otros elementos

40.0.1 Otros: vcov

Motivación

La función vcov retorna la matriz de covarianzas estimada de los parámetros libres estimados del modelo. Formalmente:

  • No es una matriz de datos.

  • No es una matriz de covarianzas entre ítems.

  • Es la matriz de covarianzas del vector de estimadores.

Definición matemática

Si denotamos por

\[ \widehat{\boldsymbol{\theta}} = (\widehat{\theta}_1, \widehat{\theta}_2, \ldots, \widehat{\theta}_p)^\top \]

el vector de parámetros estimados del modelo (cargas factoriales, varianzas, covarianzas, entre otros), entonces la matriz de varianzas-covarianzas de los estimadores está dada por:

\[ \operatorname{vcov}(\widehat{\boldsymbol{\theta}}) = \operatorname{Var}(\widehat{\boldsymbol{\theta}}). \]

Código en R

El código.

vcov(CFA)

El output.

##                  vsl=~2 vsl=~3 txt=~5 txt=~6 spd=~8 spd=~9 x1~~x1 x2~~x2 x3~~x3
## visual=~x2        0.010                                                        
## visual=~x3        0.004  0.012                                                 
## textual=~x5       0.000  0.000  0.004                                          
## textual=~x6       0.000  0.000  0.002  0.003                                   
## speed=~x8         0.000  0.000  0.000  0.000  0.027                            
## speed=~x9         0.000  0.000  0.000  0.000  0.014  0.023                     
## x1~~x1            0.005  0.008  0.000  0.000  0.000  0.000  0.013              
## x2~~x2           -0.002 -0.001  0.000  0.000  0.000  0.000 -0.001  0.010       
## x3~~x3           -0.001 -0.004  0.000  0.000  0.000  0.000 -0.003  0.000  0.008
## x4~~x4            0.000  0.000  0.001  0.001  0.000  0.000  0.000  0.000  0.000
## x5~~x5            0.000  0.000 -0.001  0.000  0.000  0.000  0.000  0.000  0.000
## x6~~x6            0.000  0.000  0.000 -0.001  0.000  0.000  0.000  0.000  0.000
## x7~~x7            0.000  0.000  0.000  0.000  0.005  0.004  0.000  0.000  0.000
## x8~~x8            0.000  0.000  0.000  0.000 -0.006  0.001  0.000  0.000  0.000
## x9~~x9            0.000  0.000  0.000  0.000  0.001 -0.004  0.000  0.000  0.000
## visual~~visual   -0.007 -0.010  0.000  0.000  0.000  0.000 -0.011  0.001  0.003
## textual~~textual  0.000  0.000 -0.004 -0.003  0.000  0.000  0.000  0.000  0.000
## speed~~speed      0.000  0.000  0.000  0.000 -0.011 -0.009  0.000  0.000  0.000
## visual~~textual  -0.001 -0.002 -0.001 -0.001  0.000  0.000 -0.001  0.000  0.001
## visual~~speed    -0.001 -0.001  0.000  0.000 -0.004 -0.003 -0.001  0.000  0.000
## textual~~speed    0.000  0.000  0.000  0.000 -0.003 -0.002  0.000  0.000  0.000
##                  x4~~x4 x5~~x5 x6~~x6 x7~~x7 x8~~x8 x9~~x9 vsl~~v txtl~~t
## visual=~x2                                                               
## visual=~x3                                                               
## textual=~x5                                                              
## textual=~x6                                                              
## speed=~x8                                                                
## speed=~x9                                                                
## x1~~x1                                                                   
## x2~~x2                                                                   
## x3~~x3                                                                   
## x4~~x4            0.002                                                  
## x5~~x5           -0.001  0.003                                           
## x6~~x6            0.000  0.000  0.002                                    
## x7~~x7            0.000  0.000  0.000  0.007                             
## x8~~x8            0.000  0.000  0.000 -0.001  0.006                      
## x9~~x9            0.000  0.000  0.000  0.000 -0.002  0.005               
## visual~~visual    0.000  0.000  0.000  0.000  0.000  0.000  0.021        
## textual~~textual -0.001  0.001  0.000  0.000  0.000  0.000  0.001   0.013
## speed~~speed      0.000  0.000  0.000 -0.002  0.001  0.000  0.000   0.000
## visual~~textual   0.000  0.000  0.000  0.000  0.000  0.000  0.005   0.004
## visual~~speed     0.000  0.000  0.000 -0.001  0.001  0.000  0.003   0.000
## textual~~speed    0.000  0.000  0.000 -0.001  0.000  0.000  0.001   0.002
##                  spd~~s vsl~~t vsl~~s txtl~~s
## visual=~x2                                   
## visual=~x3                                   
## textual=~x5                                  
## textual=~x6                                  
## speed=~x8                                    
## speed=~x9                                    
## x1~~x1                                       
## x2~~x2                                       
## x3~~x3                                       
## x4~~x4                                       
## x5~~x5                                       
## x6~~x6                                       
## x7~~x7                                       
## x8~~x8                                       
## x9~~x9                                       
## visual~~visual                               
## textual~~textual                             
## speed~~speed      0.007                      
## visual~~textual   0.000  0.005               
## visual~~speed     0.003  0.001  0.003        
## textual~~speed    0.002  0.001  0.001   0.002

Interpretación estadística de la salida

Con respecto a la estructura de la matriz tenemos:

  • Filas y columnas: corresponden a los parámetros estimados del modelo (por ejemplo, visual=~x2, x1~~x1, visual~~textual, etc.).

  • Diagonal: contiene las varianzas de los estimadores,

\[ \operatorname{Var}(\widehat{\theta}_i), \]

cuya raíz cuadrada corresponde al error estándar del estimador:

\[ \operatorname{SE}(\widehat{\theta}_i) = \sqrt{\operatorname{Var}(\widehat{\theta}_i)}. \]

  • Fuera de la diagonal: contiene las covarianzas entre estimadores,

\[ \operatorname{Cov}(\widehat{\theta}_i, \widehat{\theta}_j), \]

las cuales indican dependencia estadística entre los estimadores, un fenómeno habitual en modelos de ecuaciones estructurales (SEM).

40.0.2 Otros: AIC y BIC

El código y la salida.

El comando de abajo extrae y presenta de forma conjunta dos criterios de información ampliamente utilizados para la comparación de modelos: el Akaike Information Criterion (AIC) y el Bayesian Information Criterion (BIC).

cbind(AIC(CFA), BIC(CFA))
##         [,1]     [,2]
## [1,] 7517.49 7595.339

Claves de interpretación

  • Valores más pequeños de AIC o BIC indican un mejor compromiso entre ajuste y parsimonia.

  • AIC penaliza la complejidad de manera más suave y es preferido cuando el objetivo es comparar modelos predictivos.

  • BIC impone una penalización más fuerte, especialmente en muestras grandes, y tiende a favorecer modelos más parsimoniosos.

  • Estos criterios no se interpretan de forma absoluta, sino relativa: solo tienen sentido al comparar dos o más modelos ajustados a los mismos datos.

Observaciones importantes

  • En este caso, los valores reportados de AIC y BIC constituyen una línea base que puede utilizarse para comparar este modelo CFA con modelos alternativos (por ejemplo, modelos con restricciones adicionales o modelos más complejos).

  • AIC y BIC permiten comparar modelos CFA considerando simultáneamente su ajuste a los datos y su complejidad, favoreciendo aquellos que explican mejor la estructura observada con el menor número de parámetros.

40.0.3 Otros: parameterEstimates

El código y la salida.

Aquí, parameterEstimates(CFA) devuelve una tabla con las estimaciones y los estadísticos de inferencia asociados a cada parámetro del modelo.

parameterEstimates(CFA)
##        lhs op     rhs   est    se      z pvalue ci.lower ci.upper
## 1   visual =~      x1 1.000 0.000     NA     NA    1.000    1.000
## 2   visual =~      x2 0.554 0.100  5.554      0    0.358    0.749
## 3   visual =~      x3 0.729 0.109  6.685      0    0.516    0.943
## 4  textual =~      x4 1.000 0.000     NA     NA    1.000    1.000
## 5  textual =~      x5 1.113 0.065 17.014      0    0.985    1.241
## 6  textual =~      x6 0.926 0.055 16.703      0    0.817    1.035
## 7    speed =~      x7 1.000 0.000     NA     NA    1.000    1.000
## 8    speed =~      x8 1.180 0.165  7.152      0    0.857    1.503
## 9    speed =~      x9 1.082 0.151  7.155      0    0.785    1.378
## 10      x1 ~~      x1 0.549 0.114  4.833      0    0.326    0.772
## 11      x2 ~~      x2 1.134 0.102 11.146      0    0.934    1.333
## 12      x3 ~~      x3 0.844 0.091  9.317      0    0.667    1.022
## 13      x4 ~~      x4 0.371 0.048  7.779      0    0.278    0.465
## 14      x5 ~~      x5 0.446 0.058  7.642      0    0.332    0.561
## 15      x6 ~~      x6 0.356 0.043  8.277      0    0.272    0.441
## 16      x7 ~~      x7 0.799 0.081  9.823      0    0.640    0.959
## 17      x8 ~~      x8 0.488 0.074  6.573      0    0.342    0.633
## 18      x9 ~~      x9 0.566 0.071  8.003      0    0.427    0.705
## 19  visual ~~  visual 0.809 0.145  5.564      0    0.524    1.094
## 20 textual ~~ textual 0.979 0.112  8.737      0    0.760    1.199
## 21   speed ~~   speed 0.384 0.086  4.451      0    0.215    0.553
## 22  visual ~~ textual 0.408 0.074  5.552      0    0.264    0.552
## 23  visual ~~   speed 0.262 0.056  4.660      0    0.152    0.373
## 24 textual ~~   speed 0.173 0.049  3.518      0    0.077    0.270

Como se indicó previamente, a continuación se describen únicamente aquellas columnas que no aparecen directamente en parTable() o que no se reportan allí como resultados inferenciales. En este output, dichas columnas son las siguientes:

  • se (standard error): corresponde al error estándar de la estimación est. Mide la incertidumbre asociada al estimador y se obtiene a partir de la matriz de varianzas–covarianzas de los estimadores:

\[ \operatorname{SE}(\widehat{\theta}_i) = \sqrt{\operatorname{Var}(\widehat{\theta}_i)}. \]

  • z: estadístico de Wald para contrastar la hipótesis nula \(H_0: \theta = 0\), definido como:

\[ z = \frac{\widehat{\theta}}{\operatorname{SE}(\widehat{\theta})}. \]

Si se = 0 (como ocurre en parámetros fijados por identificación), el valor de \(z\) no está definido y se reporta como NA.

  • pvalue: valor-\(p\) asociado al test de Wald bajo una aproximación normal. Indica la evidencia estadística contra la hipótesis nula \(H_0: \theta = 0\). Valores pequeños sugieren que el parámetro es significativamente distinto de cero.

  • ci.lower, ci.upper: límites inferior y superior del intervalo de confianza (por defecto, típicamente del 95%), que suele calcularse como:

\[ \widehat{\theta} \pm z_{0.975}\,\operatorname{SE}(\widehat{\theta}). \]

Cuando el intervalo de confianza no contiene el valor cero, el resultado es consistente con un valor-\(p\) pequeño en el test bilateral.

Notas rápidas sobre la tabla:

  • Las cargas factoriales fijadas a 1 por razones de identificación (por ejemplo, visual =~ x1) presentan se = 0, por lo que los estadísticos z y pvalue aparecen como NA, y el intervalo de confianza se reduce al valor \([1,\,1]\).

  • Para las cargas factoriales y covarianzas libres, se observan valores grandes del estadístico \(z\) y valores-\(p\) cercanos a cero, lo que indica que estos parámetros son significativamente distintos de cero.

40.0.4 Otros: standardizedSolution

El código y la salida.

La función standardizedSolution() presenta las estimaciones de los parámetros en escala estandarizada, lo que permite interpretar directamente la magnitud relativa de las relaciones del modelo, independientemente de las unidades de medida originales.

A diferencia de parameterEstimates(), el énfasis aquí recae en la columna est.std, que contiene los parámetros completamente estandarizados.

standardizedSolution(CFA)
##        lhs op     rhs est.std    se      z pvalue ci.lower ci.upper
## 1   visual =~      x1   0.772 0.055 14.041      0    0.664    0.880
## 2   visual =~      x2   0.424 0.060  7.105      0    0.307    0.540
## 3   visual =~      x3   0.581 0.055 10.539      0    0.473    0.689
## 4  textual =~      x4   0.852 0.023 37.776      0    0.807    0.896
## 5  textual =~      x5   0.855 0.022 38.273      0    0.811    0.899
## 6  textual =~      x6   0.838 0.023 35.881      0    0.792    0.884
## 7    speed =~      x7   0.570 0.053 10.714      0    0.465    0.674
## 8    speed =~      x8   0.723 0.051 14.309      0    0.624    0.822
## 9    speed =~      x9   0.665 0.051 13.015      0    0.565    0.765
## 10      x1 ~~      x1   0.404 0.085  4.763      0    0.238    0.571
## 11      x2 ~~      x2   0.821 0.051 16.246      0    0.722    0.920
## 12      x3 ~~      x3   0.662 0.064 10.334      0    0.537    0.788
## 13      x4 ~~      x4   0.275 0.038  7.157      0    0.200    0.350
## 14      x5 ~~      x5   0.269 0.038  7.037      0    0.194    0.344
## 15      x6 ~~      x6   0.298 0.039  7.606      0    0.221    0.374
## 16      x7 ~~      x7   0.676 0.061 11.160      0    0.557    0.794
## 17      x8 ~~      x8   0.477 0.073  6.531      0    0.334    0.620
## 18      x9 ~~      x9   0.558 0.068  8.208      0    0.425    0.691
## 19  visual ~~  visual   1.000 0.000     NA     NA    1.000    1.000
## 20 textual ~~ textual   1.000 0.000     NA     NA    1.000    1.000
## 21   speed ~~   speed   1.000 0.000     NA     NA    1.000    1.000
## 22  visual ~~ textual   0.459 0.064  7.189      0    0.334    0.584
## 23  visual ~~   speed   0.471 0.073  6.461      0    0.328    0.613
## 24 textual ~~   speed   0.283 0.069  4.117      0    0.148    0.418

Interpretación de la salida

  • est.std: estimación estandarizada del parámetro. En el caso de las cargas factoriales, representa la correlación entre el ítem observado y el factor latente. Valores cercanos a 1 indican una relación fuerte, mientras que valores bajos indican una contribución débil del ítem al factor.

  • Para las varianzas residuales estandarizadas (x_i ~~ x_i), est.std representa la proporción de varianza no explicada del ítem. Valores más pequeños indican que el factor explica una mayor proporción de la varianza del ítem.

  • En las covarianzas entre factores latentes, los valores estandarizados pueden interpretarse como correlaciones latentes, facilitando la comparación de la fuerza de asociación entre factores.

40.0.5 Otros: fitted.values

En lavaan, la función fitted.values() permite obtener los valores ajustados del modelo, expresados en términos de las matrices implícitas que el modelo estima internamente. En particular, cuando se aplica a un objeto de clase lavaan (como CFA), esta función devuelve una lista que incluye la matriz de covarianzas implícita del modelo ajustado.

Es importante señalar que, en el contexto de lavaan, las funciones fitted() y fitted.values() son equivalentes en su contenido: ambas devuelven los valores ajustados del modelo. En particular:

  • fitted(fit)$cov y fitted.values(fit)$cov proporcionan la misma matriz de covarianzas implícita, denotada por \({\boldsymbol{\Sigma}}\).

  • Cuando el modelo incluye medias o interceptos, los componentes fitted(fit)$mean y fitted.values(fit)$mean devuelven el vector de medias implícitas del modelo.

Esta equivalencia explica por qué, al utilizar fitted.values(CFA), se obtiene exactamente la misma matriz de covarianzas que con fitted(CFA)$cov.

El código.

fitted.values(CFA)

El output.

## $cov
##       x1    x2    x3    x4    x5    x6    x7    x8    x9
## x1 1.358                                                
## x2 0.448 1.382                                          
## x3 0.590 0.327 1.275                                    
## x4 0.408 0.226 0.298 1.351                              
## x5 0.454 0.252 0.331 1.090 1.660                        
## x6 0.378 0.209 0.276 0.907 1.010 1.196                  
## x7 0.262 0.145 0.191 0.173 0.193 0.161 1.183            
## x8 0.309 0.171 0.226 0.205 0.228 0.190 0.453 1.022      
## x9 0.284 0.157 0.207 0.188 0.209 0.174 0.415 0.490 1.015

Es decir, se obtiene la matriz de covarianzas implícita del modelo:

\[ \boldsymbol{\Sigma} = \boldsymbol{\Lambda}\boldsymbol{\Psi}\boldsymbol{\Lambda}^\top + \boldsymbol{\Theta} = \begin{pmatrix} 1.358 & 0.448 & 0.590 & 0.408 & 0.454 & 0.378 & 0.262 & 0.309 & 0.284 \\ 0.448 & 1.382 & 0.327 & 0.226 & 0.252 & 0.209 & 0.145 & 0.171 & 0.157 \\ 0.590 & 0.327 & 1.275 & 0.298 & 0.331 & 0.276 & 0.191 & 0.226 & 0.207 \\ 0.408 & 0.226 & 0.298 & 1.351 & 1.090 & 0.907 & 0.173 & 0.205 & 0.188 \\ 0.454 & 0.252 & 0.331 & 1.090 & 1.660 & 1.010 & 0.193 & 0.228 & 0.209 \\ 0.378 & 0.209 & 0.276 & 0.907 & 1.010 & 1.196 & 0.161 & 0.190 & 0.174 \\ 0.262 & 0.145 & 0.191 & 0.173 & 0.193 & 0.161 & 1.183 & 0.453 & 0.415 \\ 0.309 & 0.171 & 0.226 & 0.205 & 0.228 & 0.190 & 0.453 & 1.022 & 0.490 \\ 0.284 & 0.157 & 0.207 & 0.188 & 0.209 & 0.174 & 0.415 & 0.490 & 1.015 \end{pmatrix}. \]

Observación pedagógica.

El uso de fitted.values() en lavaan no es erróneo. Sin embargo, es importante destacar una diferencia conceptual con otros modelos en R:

  • En modelos de regresión clásicos (por ejemplo, lm o glm), fitted.values() suele devolver valores ajustados del vector respuesta \(\hat{y}\).

  • En modelos SEM implementados con lavaan, fitted.values() está definido como un método específico para objetos lavaan* y devuelve las matrices implícitas del modelo (covarianzas y, cuando corresponde, medias).

Por esta razón, aunque fitted() y fitted.values() producen el mismo resultado en este contexto, el uso explícito de fitted.values() puede resultar útil para enfatizar que se están recuperando los valores ajustados del modelo, y no predicciones individuales a nivel de observación.

41 Funciones especiales

41.0.1 Funciones de extracción para inspeccionar modelos ajustados

En la Figura 41.1 se muestra una lista de funciones para inspeccionar modelos ajustados.

**Funciones de extracción para inspeccionar modelos ajustados**

Figure 41.1: Funciones de extracción para inspeccionar modelos ajustados

41.0.2 Otras funciones especiales

En la Figura 41.2 se muestra una lista de funciones para inspeccionar modelos ajustados.

**Otras funciones especiales**

Figure 41.2: Otras funciones especiales

42 Tópicos suplementarios

Para profundizar en los temas de invarianza de medida, y en particular en la invarianza de medias latentes, se recomienda consultar los siguientes recursos, que abordan tanto la teoría como su implementación práctica.

43 Ejercicios

43.0.1 Ejercicio 1

Considere el siguiente conjunto de datos que contiene 100 observaciones y 2 variables:

  • El número de horas que se suelen dedicar a las matemáticas (MathHomework)

  • La puntuación en un test estandarizado de rendimiento de matemática (MathAchievement).

# Crear el dataframe en R
MathHmwk.data <- data.frame(
  MathHomework = c(2, 0, 4, 0, 2, 0, 1, 0, 3, 0, 4, 7, 3, 1, 1, 0, 3, 0, 1, 3, 3, 0, 2, 0, 1, 4, 1, 4, 3, 1, 1, 3, 3, 5, 2, 5, 1, 3, 2, 2, 0, 2, 5, 0, 2, 2, 1, 2, 1, 4, 0, 0, 4, 10, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 3, 2, 0, 0, 3, 2, 5, 5, 1, 0, 0, 2, 2, 3, 0, 2, 4, 0, 3, 1, 2, 3, 4, 4, 4, 2, 1, 6, 3, 5, 6, 4, 3, 2, 2, 1),
  MathAchievement = c(54, 53, 53, 56, 59, 30, 49, 54, 37, 49, 55, 50, 45, 44, 60, 36, 53, 22, 56, 54, 75, 37, 42, 64, 61, 57, 53, 63, 75, 53, 54, 64, 54, 59, 48, 65, 57, 48, 54, 62, 53, 61, 56, 32, 50, 44, 62, 39, 61, 51, 36, 38, 38, 59, 46, 55, 48, 54, 41, 61, 52, 63, 25, 64, 72, 65, 41, 29, 39, 70, 68, 38, 59, 29, 49, 39, 45, 74, 41, 53, 71, 41, 63, 34, 61, 51, 62, 55, 64, 47, 48, 47, 44, 52, 50, 48, 58, 39, 41, 51)
)
# Ver el dataframe
head(MathHmwk.data)
##   MathHomework MathAchievement
## 1            2              54
## 2            0              53
## 3            4              53
## 4            0              56
## 5            2              59
## 6            0              30

La pregunta de interés es: ¿El tiempo dedicado a los deberes de matemáticas está directamente relacionado con el rendimiento en matemáticas?

  1. Dibuje un diagrama de dispersión entre ambas variables.

  2. Realice una regresión típica estandarizado y no estandarizado, utilizando la función lm. Sugerencia: Para la no estandarizada aplique la función scale a ambos conjuntos de datos y haga la regresión.

  3. Dibuje un path model estandarizado y no estandarizado de la regresión.

  4. Realice el análisis como un path model en lavaan utilizando la función sem. Obtenga tanto los coeficientes estandarizados como los no estandarizados. Sugerencia: Para no estandarizado use el argumento meanstructure = TRUE.

  5. ¿Cómo se relacionan los resultados de los incisos (b) y (d)?

43.0.2 Ejercicio 2

Page y Keith (1981) utilizaron encuestados de los datos de 1980 High School and Beyond para investigar la siguiente pregunta: ¿Cuál es la relación entre el tipo de escuela y el rendimiento académico? Los datos aparecen en la Figura 43.1 en forma de matriz de correlaciones. En la Figura 43.2 se muestra un path model para los análisis.

El código R para la matriz es:

library(lavaan)
privSchool.cor <- c(1, 0.178, 0.23, 0.106, 0.195, 1, 0.327, 0.245, 0.356, 1, 0.183, 0.721, 1, 0.178, 1)
privSchool.cor <- lav_matrix_upper2full(privSchool.cor)
#privSchool.cor <- lav_matrix_lower2full(privSchool.cor)
dimnames(privSchool.cor) <- list(c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"), c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"))
privSchool.cor
##          Race   SES CogAbil SchTyp AcadAch
## Race    1.000 0.178   0.230  0.106   0.195
## SES     0.178 1.000   0.327  0.245   0.356
## CogAbil 0.230 0.327   1.000  0.183   0.721
## SchTyp  0.106 0.245   0.183  1.000   0.178
## AcadAch 0.195 0.356   0.721  0.178   1.000
**Correlaciones (n = 18,058)**

Figure 43.1: Correlaciones (n = 18,058)

El path model es:

**Path model**

Figure 43.2: Path model

  1. Crear el modelo de trayectorias utilizando lavaan. Asegúrese de etiquetar los mismos parámetros que en la Figura 43.2.

  2. Realizar el análisis de path model correspondiente. Interprete todos los resultados posibles.

  3. ¿Cuál es la relación entre el tipo de escuela y el rendimiento académico (es decir, camino j)?

43.0.3 Ejercicio 3

MacKinnon (2008, p. 113) proporciona un conjunto de datos de un estudio hipotético sobre las expectativas de los profesores respecto al rendimiento de los alumnos. y el rendimiento de los alumnos. Su modelo de trayectoria se muestra en la Figura Figura 43.3 y las covarianzas del modelo se indican en la Figura 43.4.

El path model es:

**Path model**

Figure 43.3: Path model

El código R para la matriz de covarianzas es:

library(lavaan)
privSchool.cor <- c(1, 0.178, 0.23, 0.106, 0.195, 1, 0.327, 0.245, 0.356, 1, 0.183, 0.721, 1, 0.178, 1)
privSchool.cor <- lav_matrix_upper2full(privSchool.cor)
#privSchool.cor <- lav_matrix_lower2full(privSchool.cor)
dimnames(privSchool.cor) <- list(c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"), c("Race", "SES", "CogAbil", "SchTyp", "AcadAch"))
privSchool.cor
##          Race   SES CogAbil SchTyp AcadAch
## Race    1.000 0.178   0.230  0.106   0.195
## SES     0.178 1.000   0.327  0.245   0.356
## CogAbil 0.230 0.327   1.000  0.183   0.721
## SchTyp  0.106 0.245   0.183  1.000   0.178
## AcadAch 0.195 0.356   0.721  0.178   1.000
**Covarianzas (n = 40)**

Figure 43.4: Covarianzas (n = 40)

  1. Introduzca las covarianzas en R.

  2. Escriba la sintaxis del modelo. Utilice el operador := para definir los dos efectos indirectos de las expectativas del profesor sobre el rendimiento del alumno: (a1)(b1) y (a2)(b2).

  3. ¿Cuáles son los efectos indirectos?

  4. Realice el análisis de path model correspondiente.

  5. Interprete todos los resultados posibles.

43.0.4 Ejercicio 4

Umstattd-Meyer, Janke y Beaujean (2013) midieron la salud psicosocial deficiente como un modelo de factor único utilizando tres facetas de ítems de un cuestionario de depresión y una medida de la actividad social. La matriz de covarianza se muestra en la Figura 43.5.

**Covarianzas (n = 6053)**

Figure 43.5: Covarianzas (n = 6053)

Además, considere el siguiente modelo.

Modelo 1.

marker.model <- '
PsychSocLV =~ Dep.1 + Dep.2 + Dep.3 + SocActivity
'

Realizar los siguientes incisos:

  1. Introduzca la matriz de covarianzas en R.

  2. Con la función cfa de lavaan (sin agregar el argumento std.lv=...) y utilizando variables latentes no estandarizadas, ajuste el modelo 1. Sugerencia: use el código habitual de cfa.

  3. Con la función cfa de lavaan (agregando el argumento std.lv=FALSE) y utilizando variables latentes no estandarizadas, ajuste el modelo 1. Sugerencia: use el código habitual de cfa con el argumento mencionado.

  4. Con la función cfa de lavaan y utilizando variables latentes estandarizadas, ajuste el modelo 1. Sugerencia: use el código habitual de cfa agregando el argumento std.lv=TRUE.

  5. Verifique que los valores resultantes de \(\chi^2\) y \(df\) son idénticos para todos los métodos. Investigue la razón.

  6. ¿Y el número de parámetros del model? ¿Son iguales en todos los modelos? Identifíquelos en cada uno de ellos.

43.0.5 Ejercicio 5

Continuación del ejercicio 4. Considere la situación del ejercicio 4 y los siguientes dos modelos (modelos 2 y 3).

Modelo 2.

Observe que, en este modelo, se utiliza Depression 1 como variable marcadora.

stdLV.model <- '
PsychSocLV =~ NA*Dep.1 + Dep.1 + Dep.2 + Dep.3 + SocActivity
PsychSocLV~~1*PsychSocLV
'

Modelo 3.

Observe que, en este modelo, se utiliza:

  • Como variable marcadora a Depression 1.

  • El método de la codificación de efectos (porque la suma de las cargas factoriales es igual al número de variables indicadoras únicas).

ec.model <- '
PsychSocLV =~ NA*Dep.1 + a*Dep.1 + b*Dep.2 + c*Dep.3 + d*SocActivity
a+b+c+d==4
'

Realizar los siguientes incisos:

  1. Con la función cfa de lavaan (sin agregar el argumento std.lv=...), ajuste el modelo 2. Sugerencia: use el código habitual de cfa.

  2. Con la función cfa de lavaan (sin agregar el argumento std.lv=...), ajuste el modelo 3. Sugerencia: use el código habitual de cfa.

  3. Verifique que los valores resultantes de \(\chi^2\) y \(df\) son idénticos para todos los métodos evaluados tanto en el ejercicio 4 como en el 5. Investigue la razón.

  4. ¿Y el número de parámetros del modelo? ¿Son iguales en todos los modelos? Identifíquelos en cada uno de ellos.

43.0.6 Ejercicio 6

El modelo del Ejercicio anterior formaba parte de un SEM más amplio, parte del cual se muestra en la Figura 43.6. La matriz de covarianza completa se muestra en la Figura 43.7.

**Path model**

Figure 43.6: Path model

La matriz de covarianzas es:

**Covarianzas (n = 6053)**

Figure 43.7: Covarianzas (n = 6053)

  1. Introduzca la matriz de covarianza en R.

  2. Ajuste el modelo SEM a los datos. ¿La salud psicosocial y la salud física predicen la movilidad personal? Sugerencia: aplique la función sem de lavaan.

43.0.7 Ejercicio 7

Graham (2008) mostró cómo el SEM puede utilizarse para analizar una variedad de modelos lineales generales. lineales generales. Su ejemplo de análisis descriptivo discriminante (DDA) utiliza variables latentes formativas. El DDA es un procedimiento que describe las diferencias entre múltiples grupos en múltiples descriptores continuos: una regresión múltiple entre dos o más grupos. En DDA, la variable latente de interés se denomina función discriminante. Un path model del DDA se muestra en la Figura 43.8 y los datos para el modelo se dan en la Figura 43.9.

El path model es:

**Path model del DDA**

Figure 43.8: Path model del DDA

La matriz de covarianzas es:

**Covarianzas (n = 288)**

Figure 43.9: Covarianzas (n = 288)

Realizar los siguientes incisos:

  1. Importe a R la matriz de covarianzas y el vector de medias.

  2. Escriba la sintaxis lavaan para la Figura 43.8. Sugerencia: el path a=1 se escribe como 1*DV1 + a*DV1 en la sintaxis de lavaan.

  3. Obtenga los coeficientes de función (coeficientes estandarizados para a y b), correlación canónica (coeficiente estandarizado para c), y \(R^2\) (coeficiente normalizado para d). Sugerencia: aplique la función sem de lavaan.

Bibliografía

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

Referencias

Graham, J. M. (2008). The general linear model as structural equation modeling. Journal of Educational and Behavioral Statistics, 33 , 485-506. doi: 10.3102/1076998607306151.

MacKinnon, D. P. (2008). Introduction to statistical mediation analysis. Mahwah, NJ: Erlbaum.

Page, E. B., & Keith, T. Z. (1981). Effects of U.S. private schools: A technical analysis of two recent claims. Educational Researcher, 10 , 7-17. doi: 10.2307/1174256.

Umstattd-Meyer, M. R., Janke, M. C., & Beaujean, A. A. (2013). Predictors of older adults’ personal and community mobility: Using a comprehensive theoretical mobility framework. The Gerontologist, Advance online publication. doi: 10.1093/geront/gnt054.

 

 
If you found any ERRORS or have SUGGESTIONS, please report them to my email. Thanks.  
LS0tDQp0aXRsZTogIk1PREVMT1MgREUgRUNVQUNJT05FUyBFU1RSVUNUVVJBTEVTIChTRU0pIg0Kc3VidGl0bGU6IDxoMT4qKkFwbGljYWNpw7NuKio8L2gxPg0KDQphdXRob3I6IA0KICAtIG5hbWUgICAgICAgICAgOiAiRHIuIHJlci4gbmF0LiBIdW1iZXJ0byBMTGluw6FzIFNvbGFubyINCiAgICBhZmZpbGlhdGlvbiAgIDogIkRlcGFydGFtZW50byBkZSBNYXRlbcOhdGljYXMgeSBFc3RhZMOtc3RpY2EsIFVuaXZlcnNpZGFkIGRlbCBOb3J0ZSAoQmFycmFucXVpbGxhLCBDb2xvbWJpYSkiDQogICAgICNjb3JyZXNwb25kaW5nIDogeWVzICAgICMgRGVmaW5lIG9ubHkgb25lIGNvcnJlc3BvbmRpbmcgYXV0aG9yDQogICAgICNhZGRyZXNzICAgICAgIDogIkRlcGFydGFtZW50byBkZSBNYXRlbcOhdGljYXMgeSBFc3RhZMOtc3RpY2EiDQogICAgZW1haWwgICAgICAgICA6IHwNCiAgICAgIGhsbGluYXNAdW5pbm9ydGUuZWR1LmNvDQogICAgICANCiAgICAgIFtCaW9ncmFwaGljYWwgc2tldGNoXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL0Jpb19Ta2V0Y2gpDQogICAgICANCiAgICAgIGByIGZvcm1hdChTeXMudGltZSgpLCAiJWQvJW0vJXkiKWAgDQogICAgICANCiAgICAgI3JvbGU6ICAgICAgICAgIyBDb250cmlidXRvcnNoaXAgcm9sZXMgKGUuZy4sIENSZWRpVCwgaHR0cHM6Ly9jYXNyYWkub3JnL2NyZWRpdC8pDQogICMgICAgLSBDb25jZXB0dWFsaXphdGlvbg0KICAjICAgIC0gV3JpdGluZyAtIE9yaWdpbmFsIERyYWZ0IFByZXBhcmF0aW9uDQogICMgICAgLSBXcml0aW5nIC0gUmV2aWV3ICYgRWRpdGluZw0KICMgLSBuYW1lICAgICAgICAgIDogIkF1dG9yIG51bWVybyAyIg0KICMgICBhZmZpbGlhdGlvbiAgIDogIjEsMiINCiAjICAgcm9sZToNCiAjICAgICAtIFdyaXRpbmcgLSBSZXZpZXcgJiBFZGl0aW5nDQogICAgICNhZmZpbGlhdGlvbjoNCiAgIy0gaWQgICAgICAgICAgICA6ICIxIg0KICAjICBpbnN0aXR1dGlvbiAgIDogIlVuaXZlcnNpZGFkIGRlbCBOb3J0ZSAoQmFycmFucXVpbGxhLCBDb2xvbWJpYSkiDQogICMhW10oaGxsaW5hcy5qcGcpe3dpZHRoPTFpbn0gDQogIA0KI2RhdGU6ICdgciBmb3JtYXQoU3lzLnRpbWUoKSwgIiVkLyVtLyV5IilgJyAgIyB2ZXIgaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvcm1hcmtkb3duLWNvb2tib29rL3VwZGF0ZS1kYXRlLmh0bWwNCm91dHB1dDogDQogICAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOiANCiAgICAgICAgICAjT0pPIFNhbGVuIGNhcGl0dWxvcywgc2VjY2lvbmVzIHkgVGVvcmVtYXMNCiAgICAjYm9va2Rvd246Omh0bWxfYm9vazoNCiAgICAgICAgICAjT0pPIEVSUk9SIFNhbGVuIHRlb3JlbWFzLCBwZXJvIG5vIHNhbGVuIGxvcyBjYXBpdHVsb3MgDQogICAgI2h0bWxfZG9jdW1lbnQ6DQogICAgICAgICAgdG9jOiB0cnVlICAgICAgIyB0YWJsZSBvZiBjb250ZW50IHRydWUNCiAgICAgICAgICB0b2NfZGVwdGg6IDQgICAjIHVwdG8gdGhyZWUgZGVwdGhzIG9mIGhlYWRpbmdzIChzcGVjaWZpZWQgYnkgIywgIyMgYW5kICMjIykNCiAgICAgICAgICB0b2NfZmxvYXQ6IHRydWUgI0NvbiB0cnVlLCB0b2Mgc2FsZSBhbCBtYXJnZW4gaXpxdWllcmRvIGRlIGxhIHDDoWdpbmE7IGRlIGxvIGNvbnRyYXJpbywgYXJyaWJhDQogICAgICAgICAgY29sbGFwc2VkOiBmYWxzZQ0KICAgICAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlDQogICAgICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlICAgIyBpZiB5b3Ugd2FudCBudW1iZXIgc2VjdGlvbnMgYXQgZWFjaCB0YWJsZSBoZWFkZXINCiAgICAgICAgICAjdGhlbWU6IHNhbmRzdG9uZQ0KICAgICAgICAgICN0aGVtZTogdW5pdGVkICAjIG1hbnkgb3B0aW9ucyBmb3IgdGhlbWUsIHRoaXMgb25lIGlzIG15IGZhdm9yaXRlLg0KICAgICAgICAgICN0aGVtZTogZmxhdGx5ICAjIA0KICAgICAgICAgICN0aGVtZTogY2VydWxlYW4gICMgDQogICAgICAgICAgI2hpZ2hsaWdodDogdGFuZ28gICMgc3BlY2lmaWVzIHRoZSBzeW50YXggaGlnaGxpZ2h0aW5nIHN0eWxlDQogICAgICAgICAgI2NzczogU2NyaXB0cyBhY2Nlc29yaW9zL2VzdGlsb2JvdG9uLmNzcw0KICAgICAgICAgICNjc3M6IG15LmNzcyAgICMgeW91IGNhbiBhZGQgeW91ciBjdXN0b20gY3NzLCBzaG91bGQgYmUgaW4gc2FtZSBmb2xkZXINCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgICAgICAgI2hpZ2hsaWdodDogdGFuZ28gICMgY2FtYmlhciBjb2xvciBkZSBsaWJyYXJ5IGVuIGF6dWwNCiAgICAjIGJvb2tkb3duOjpnaXRib29rOg0KICAgICMgICAgICBpbmNsdWRlczoNCiAgICAjICAgICAgICBpbl9oZWFkZXI6IGhlYWRlci5odG1sDQogICAgIyBib29rZG93bjo6cGRmX2Jvb2s6DQogICAgIyAgICAgICBrZWVwX3RleDogeWVzDQogICAgIyBib29rZG93bjo6aHRtbF9ib29rOg0KICAgICMgICAgICAgY3NzOiB0b2MuY3NzDQogICAgIyBib29rZG93bjo6aHRtbF9ib29rOg0KICAgICMgICAgICAgICBpbmNsdWRlczoNCiAgICAjICAgICAgICAgICBpbl9oZWFkZXI6IHN0eWxlLmNzcw0KICAgICNib29rZG93bjo6aHRtbF9kb2N1bWVudDI6IGRlZmF1bHQNCiAgICAjIGJvb2tkb3duOjpwZGZfZG9jdW1lbnQyOg0KICAgICMgICAgICBrZWVwX3RleDogdHJ1ZQ0KICAgICNiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliDQogICAgbWF0aGpheDogImh0dHA6Ly9leGFtcGxlLmNvbS9tYXRoamF4L01hdGhKYXguanM/Y29uZmlnPVRlWC1BTVMtTU1MX0hUTUxvck1NTCINCmhlYWRlci1pbmNsdWRlczoNCiAgICBcdXNlcGFja2FnZVt4MTFuYW1lc117eGNvbG9yfSANCiAgICANCmNzbDogc2NpZW5jZS5jc2wNCiNPam86IFNlIHV0aWxpemEgbGVuZ3VhamUgWUFNTA0KDQphYnN0cmFjdDogfA0KICoqRW4gW1JwdWJzOjogdG9jXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL3RvYykgc2UgcHVlZGVuIHZlciBvdHJvcyBkb2N1bWVudG9zIGRlIHBvc2libGUgaW50ZXLDqXMuKioNCiAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0iY2VudGVyIiwgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UjLA0KICAgICAgICAgICAgICAgICAgICAgICNzdHlsZSA9ICJjb2xvcjpkYXJrYmx1ZSINCiAgICAgICAgICAgICAgICAgICAgIyBjbGFzcy5zb3VyY2U9ImJnLWRhbmdlciIsIGNsYXNzLm91dHB1dD0iYmctd2FybmluZyIgICAjQ29sb3JlcyBkZW50cm8gZGVsIGNodW5rDQogICAgICAgICAgICAgICAgICAgICApDQpsaWJyYXJ5KHJnbCkNCmtuaXRyOjprbml0X2hvb2tzJHNldCh3ZWJnbCA9IGhvb2tfd2ViZ2wpDQpgYGANCg0KDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9DQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ybWFya2Rvd24vbGFuZ3VhZ2UtZW5naW5lcy5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL21hcmtkb3duLXN5bnRheC5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL2Jvb2tkb3duL2Etc2luZ2xlLWRvY3VtZW50Lmh0bWwNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vbWFya2Rvd24tZXh0ZW5zaW9ucy1ieS1ib29rZG93bi5odG1sDQoNCmh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi9ib29rZG93bi1tYXJrZG93bi5odG1sICAjIFRlb3JlbXMgYW5kIHByb29mcw0KDQpodHRwczovL2Jvb2tkb3duLm9yZy95aWh1aS9ib29rZG93bi9tYXJrZG93bi1leHRlbnNpb25zLWJ5LWJvb2tkb3duLmh0bWwjdGhlb3JlbXMNCg0KaHR0cHM6Ly9ib29rZG93bi5vcmcveWlodWkvYm9va2Rvd24vaHRtbC5odG1sDQoNCmh0dHBzOi8vd3d3LmRhdGEtdG8tdml6LmNvbS8NCiAgDQpbUnB1YnNdKGxpbmspDQogIA0KKFwjZXE6ZWMtKSwgIEVjdWFjaW9uIFxAcmVmKGVxOmVjLSksIEZpZ3VyYSBcQHJlZihmaWc6RmlnLSksIFRhYmxlIFxAcmVmKHRhYjptdGNhcnMpLCBUaGVvcmVtIFxAcmVmKHRobTpib3JpbmcpDQoNCg0KIyBUaXR1bG8geyNUaXR1bG9TZWNjaW9ufSAgIFxAcmVmKFRpdHVsb1NlY2Npb24pDQogIA0KIyBGb3IgSFRNTCwgd2UgY2FuIHNldCBjb2xvciB3aXRoIENTUywgZS5nLiwgPHNwYW4gc3R5bGU9ImNvbG9yOiByZWQ7Ij50ZXh0PC9zcGFuPg0KICANCiMgaHR0cHM6Ly9yYWRpYW50LXJzdGF0cy5naXRodWIuaW8vZG9jcy9tb2RlbC9sb2dpc3RpYy5odG1sIFNoaW5ueSBMb2dpdCAgDQogIA0KYGBgDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KI0xhIGZvdG8gdGFtYcOxbyBjw6lkdWxhDQoNCmh0bWx0b29sczo6aW1nKHNyYyA9IGtuaXRyOjppbWFnZV91cmkoZmlsZS5wYXRoKFIuaG9tZSgiZG9jIiksICJodG1sIiwgImxvZ28uanBnIikpLCANCiAgICAgICAgICAgICAgIGFsdCA9ICdobGxpbmFzJywgDQogICAgICAgICAgICAgICBzdHlsZSA9ICdwb3NpdGlvbjphYnNvbHV0ZTsgdG9wOjA7IHJpZ2h0OjA7IHBhZGRpbmc6MTBweDsnICMsDQogICAgICAgICAgICAgICB3aWR0aCA9ICIyMDBweCIpICAjIEFxdcOtIGVzcGVjaWZpY2FzIGVsIGFuY2hvIGRlc2VhZG8gZW4gcMOteGVsZXMgbyBwb3JjZW50YWplDQpgYGANCg0KDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIH0NCiMgTGEgZm90byBncmFuZGUNCg0KaHRtbHRvb2xzOjppbWcoc3JjID0ga25pdHI6OmltYWdlX3VyaSgiaGxsaW5hczIwMjMuanBnIiksIA0KICAgICAgICAgICAgICAgYWx0ID0gJ2hsbGluYXMyMDIzJywgDQogICAgICAgICAgICAgICBzdHlsZSA9ICdwb3NpdGlvbjphYnNvbHV0ZTsgdG9wOjA7IHJpZ2h0OjA7IHBhZGRpbmc6MXB4OycsDQogICAgICAgICAgICAgICB3aWR0aD0iMTUlIikNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KYGBge2NzcywgZWNobz1GQUxTRX0NCi5jb2x1bW5zIHtkaXNwbGF5OiBmbGV4O30NCmgxIHtjb2xvcjogZGFya2JsdWU7fQ0KaDMge2NvbG9yOiBkYXJrZ3JlZW47fQ0KaDQge2NvbG9yOiBncmVlbjt9DQoNCg0KLmVycm9yLWJsb2NrIHsNCiAgbWFyZ2luLWxlZnQ6IDJlbTsNCn0NCg0KLmVycm9yLWJsb2NrIHN0cm9uZyB7DQogIG1hcmdpbi1sZWZ0OiAtMWVtOw0KfQ0KDQouc2FuZ3JpYTMgew0KICBtYXJnaW4tbGVmdDogM2VtOw0KfQ0KDQouc2FuZ3JpYTQgew0KICBtYXJnaW4tbGVmdDogNGVtOw0KfQ0KDQouc2FuZ3JpYTUgew0KICBtYXJnaW4tbGVmdDogNWVtOw0KfQ0KDQouc2FuZ3JpYTYgew0KICBtYXJnaW4tbGVmdDogNmVtOw0KfQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KIyBMaWJyZXLDrWFzDQoNCiMjIyBQYXJhIFNFTQ0KDQoNCmBgYHtyLCBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyAgaHR0cHM6Ly9ycHVicy5jb20vQWxlbWEvMTAwMDU4Mg0KDQojIGh0dHBzOi8vd3d3LmdlZWtzZm9yZ2Vla3Mub3JnL2NvbnRleHR1YWwtb3V0bGllcnMvDQpgYGANCg0KRWwgc29mdHdhcmUgUiBkaXNwb25lIGRlIHZhcmlhcyBmdW5jaW9uZXMgZGUgZGlmZXJlbnRlcyBwYXF1ZXRlcyBwYXJhIGNhbGN1bGFyIEVGQToNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoc2VtKQ0KbGlicmFyeShsYXZhYW4pDQpsaWJyYXJ5KGJsYXZhYW4pDQpsaWJyYXJ5KHNlbVBsb3QpDQpgYGANCg0KDQotIGBzZW1gOiBjb3JyZXNwb25kZSBhIHVubyBkZSBsb3MgcHJpbWVyb3MgcGFxdWV0ZXMgZGVzYXJyb2xsYWRvcyBlbiBSIHBhcmEgbGEgZXNwZWNpZmljYWNpw7NuIHkgZXN0aW1hY2nDs24gZGUgbW9kZWxvcyBkZSBlY3VhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgKFNFTSkgbWVkaWFudGUgbcOheGltYSB2ZXJvc2ltaWxpdHVkLiBBdW5xdWUgYWN0dWFsbWVudGUgc3UgdXNvIGVzIG1lbm9zIGV4dGVuZGlkbyBxdWUgb3Ryb3MgcGFxdWV0ZXMgbcOhcyBtb2Rlcm5vcywgcmVzdWx0YSDDunRpbCBkZXNkZSB1biBwdW50byBkZSB2aXN0YSBoaXN0w7NyaWNvIHkgY29uY2VwdHVhbCwgeWEgcXVlIHBlcm1pdGUgY29tcHJlbmRlciBsYSBlc3RydWN0dXJhIGLDoXNpY2EgZGUgbG9zIG1vZGVsb3MgU0VNIHkgc3UgcmVsYWNpw7NuIGRpcmVjdGEgY29uIGxhIGZvcm11bGFjacOzbiBtYXRyaWNpYWwgY2zDoXNpY2EuDQoNCi0gYGxhdmFhbmA6IGRlc2Fycm9sbGFkbyBwb3IgW1Jvc3NlbCAoMjAxMildKGh0dHBzOi8vd3d3LmpzdGF0c29mdC5vcmcvYXJ0aWNsZS92aWV3L3YwNDhpMDIpLiBTZSB1dGlsaXphIHBhcmEgZXNwZWNpZmljYXIgeSBlc3RpbWFyIG1vZGVsb3MgZmFjdG9yaWFsZXMgY29uZmlybWF0b3Jpb3MgKENGQSkgeSBtb2RlbG9zIGRlIGVjdWFjaW9uZXMgZXN0cnVjdHVyYWxlcyAoU0VNKSBtdWx0aWdydXBvLCBwZXJtaXRpZW5kbyBldmFsdWFyIHRhbnRvIGxhICppbnZhcmlhbnphIGRlIG1lZGlkYSogKGNhcmdhcywgaW50ZXJjZXB0b3MgeSByZXNpZHVvcykgY29tbyBsYSAqaW52YXJpYW56YSBlc3RydWN0dXJhbCogKHJlZ3Jlc2lvbmVzLCB2YXJpYW56YXMgeSBjb3ZhcmlhbnphcyBsYXRlbnRlcykgZW50cmUgZ3J1cG9zLiBQYXJhIHVuYSBpbnRyb2R1Y2Npw7NuIHByw6FjdGljYSBhbCBwYXF1ZXRlLCBwdWVkZSBjb25zdWx0YXJzZSBlbCB0dXRvcmlhbCBvZmljaWFsIGRpc3BvbmlibGUgZW46IGh0dHBzOi8vbGF2YWFuLnVnZW50LmJlL3R1dG9yaWFsLg0KDQotIGBibGF2YWFuYDogZXh0aWVuZGUgbGEgc2ludGF4aXMgeSBmdW5jaW9uYWxpZGFkIGRlIGxhdmFhbiBhbCBtYXJjbyBiYXllc2lhbm8sIHBlcm1pdGllbmRvIGxhIGVzdGltYWNpw7NuIGRlIG1vZGVsb3MgU0VNIG1lZGlhbnRlIG3DqXRvZG9zIE1DTUMuIEVzdGUgcGFxdWV0ZSByZXN1bHRhIGVzcGVjaWFsbWVudGUgw7p0aWwgY3VhbmRvIHNlIGRlc2VhbiBpbmNvcnBvcmFyIGluZm9ybWFjacOzbiBwcmV2aWEsIHRyYWJhamFyIGNvbiBtdWVzdHJhcyBwZXF1ZcOxYXMgbyBldmFsdWFyIGxhIGluY2VydGlkdW1icmUgY29tcGxldGEgZGUgbG9zIHBhcsOhbWV0cm9zIGEgdHJhdsOpcyBkZSBkaXN0cmlidWNpb25lcyBwb3N0ZXJpb3Jlcy4gU3UgdXNvIGVuIGVsIGNhcMOtdHVsbyB0aWVuZSB1biBjYXLDoWN0ZXIgaW50cm9kdWN0b3JpbyB5IGNvbXBhcmF0aXZvIGZyZW50ZSBhbCBlbmZvcXVlIGNsw6FzaWNvIGRlIG3DoXhpbWEgdmVyb3NpbWlsaXR1ZC4NCg0KLSBgc2VtUGxvdGA6IHNlIGVtcGxlYSBwYXJhIGxhIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkZSBtb2RlbG9zIFNFTSB5IENGQSwgZmFjaWxpdGFuZG8gbGEgdmlzdWFsaXphY2nDs24gZGUgZmFjdG9yZXMgbGF0ZW50ZXMsIHZhcmlhYmxlcyBvYnNlcnZhZGFzLCBjYXJnYXMgZmFjdG9yaWFsZXMsIGNvdmFyaWFuemFzIHkgZWZlY3RvcyBlc3RydWN0dXJhbGVzLiBFc3RlIHBhcXVldGUgcGVybWl0ZSBnZW5lcmFyIGRpYWdyYW1hcyBjbGFyb3MgeSBwZXJzb25hbGl6YWJsZXMsIGxvIGN1YWwgZXMgZnVuZGFtZW50YWwgdGFudG8gcGFyYSBsYSBpbnRlcnByZXRhY2nDs24gc3VzdGFudGl2YSBkZSBsb3MgbW9kZWxvcyBjb21vIHBhcmEgbGEgY29tdW5pY2FjacOzbiBkZSByZXN1bHRhZG9zIGVuIGNvbnRleHRvcyBhY2Fkw6ltaWNvcyB5IGFwbGljYWRvcy4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KIyMjIFBhcmEgb3Ryb3MgYW7DoWxpc2lzDQoNCmBgYHtyLCAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRX0NCmxpYnJhcnkocHN5Y2gpICAgICAgICAgI1BhcmEgcmVhbGl6YXIgdW4gRUZBDQpsaWJyYXJ5KGtuaXRyKSAgICAgICAgICNFZGl0YXIgdGFibGFzIGNvbiBrYWJsZSgpDQpsaWJyYXJ5KGthYmxlRXh0cmEpICAgICNFZGl0YXIgdGFibGFzIG3DoXMgZXN0aWxpemFkYXMNCmxpYnJhcnkodGlkeXZlcnNlKSAgICAgI0luY2x1eWUgYSBkcGx5ciB5IGdncGxvdDINCmxpYnJhcnkoc3RyaW5ncikgICAgICAgI1JlZW1wbGF6YXIgY2FyYWN0ZXJlcyBlbiB1biBkYXRhIGZyYW1lDQpsaWJyYXJ5KG91dGxpZXJzKSAgICAgICNvdXRsaWVyczo6Z3J1YmJzLnRlc3QNCmxpYnJhcnkoRW52U3RhdHMpICAgICAgI0VudlN0YXRzOjpyb3NuZXJUZXN0DQpsaWJyYXJ5KERNd1IyKSAgICAgICAgICNMT0YgKExvY2FsIE91dGxpZXIgRmFjdG9yKQ0KbGlicmFyeShyZ2wpICAgICAgICAgICAjcmdsOjpwbG90M2RgDQpsaWJyYXJ5KGNvcnJwbG90KSAgICAgICNNYXRyaXogZGUgY29ycmVsYWNpb25lcw0KbGlicmFyeSh0ZXh0c2hhcGUpICAgICAjY29sdW1uX3RvX3Jvd25hbWVzDQpsaWJyYXJ5KG9wZW54bHN4KSAgICAgICNMaWJyZXLDrWEgcGFyYSBlc2NyaWJpciBhcmNoaXZvcyBkZSBFeGNlbA0KbGlicmFyeShrbml0cikgICAgICAgICAjQ3JlYXIgdGFibGFzIGNvbiBlc3RpbG8NCmxpYnJhcnkoa2FibGVFeHRyYSkgICAgI0NyZWFyIHRhYmxhcyBjb24gZXN0aWxvLCBwZXJvIHBhcmEgaHRtbA0KI29wdHNfa25pdCRzZXQoZXZhbC5hZnRlciA9ICdmaWcuY2FwJykNCmBgYA0KDQpgYGB7Y3NzLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KI2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQxMDMwNDc3L2NoYW5naW5nLWNodW5rLWJhY2tncm91bmQtY29sb3ItaW4tcm1hcmtkb3duDQoNCi5iYWRDb2RlIHsNCmJhY2tncm91bmQtY29sb3I6IHJlZDsNCn0NCmBgYA0KDQpgYGB7ciwgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGV2YWw9RkFMU0V9DQpsaWJyYXJ5KHBzeWNoKSAgICAgICAgICNQYXJhIHJlYWxpemFyIHVuIEVGQQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgICAjSW5jbHV5ZSBhIGRwbHlyIHkgZ2dwbG90Mg0KbGlicmFyeShzdHJpbmdyKSAgICAgICAjUmVlbXBsYXphciBjYXJhY3RlcmVzIGVuIHVuIGRhdGEgZnJhbWUNCmxpYnJhcnkob3V0bGllcnMpICAgICAgI291dGxpZXJzOjpncnViYnMudGVzdA0KbGlicmFyeShFbnZTdGF0cykgICAgICAjRW52U3RhdHM6OnJvc25lclRlc3QNCmxpYnJhcnkoRE13UjIpICAgICAgICAgI0xPRiAoTG9jYWwgT3V0bGllciBGYWN0b3IpDQpsaWJyYXJ5KHJnbCkgICAgICAgICAgICNyZ2w6OnBsb3QzZA0KbGlicmFyeShjb3JycGxvdCkgICAgICAjTWF0cml6IGRlIGNvcnJlbGFjaW9uZXMNCmxpYnJhcnkodGV4dHNoYXBlKSAgICAgI2NvbHVtbl90b19yb3duYW1lcw0KbGlicmFyeShvcGVueGxzeCkgICAgICAjTGlicmVyw61hIHBhcmEgZXNjcmliaXIgYXJjaGl2b3MgZGUgRXhjZWwNCmxpYnJhcnkoa25pdHIpICAgICAgICAgI0NyZWFyIHRhYmxhcyBjb24gZXN0aWxvDQpsaWJyYXJ5KGthYmxlRXh0cmEpICAgICNDcmVhciB0YWJsYXMgY29uIGVzdGlsbywgcGVybyBwYXJhIGh0bWwNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAgLS0+DQoNCkVuIHBhcnRpY3VsYXI6DQoNCi0gYHBzeWNoYDogc2UgdXRpbGl6YSBwYXJhIHJlYWxpemFyIGFuw6FsaXNpcyBmYWN0b3JpYWwgZXhwbG9yYXRvcmlvIChFRkEpIHkgb2J0ZW5lciBkaWFnbsOzc3RpY29zIHBzaWNvbcOpdHJpY29zIHByZWxpbWluYXJlcy4NCg0KLSBgdGlkeXZlcnNlYDogY29uanVudG8gZGUgcGFxdWV0ZXMgcGFyYSBtYW5pcHVsYWNpw7NuLCB0cmFuc2Zvcm1hY2nDs24geSB2aXN1YWxpemFjacOzbiBkZSBkYXRvczsgaW5jbHV5ZSBgZHBseXJgIHkgYGdncGxvdDJgLg0KDQotIGBzdHJpbmdyYDogZmFjaWxpdGEgb3BlcmFjaW9uZXMgZGUgbWFuaXB1bGFjacOzbiB5IHJlZW1wbGF6byBkZSBjYWRlbmFzIGRlIHRleHRvIGRlbnRybyBkZSBkYXRhIGZyYW1lcy4NCg0KLSBgb3V0bGllcnNgOiBwZXJtaXRlIGxhIGRldGVjY2nDs24gZGUgdmFsb3JlcyBhdMOtcGljb3MgbWVkaWFudGUgcHJ1ZWJhcyBlc3RhZMOtc3RpY2FzIGNsw6FzaWNhcywgY29tbyBgZ3J1YmJzLnRlc3RgLg0KDQotIGBFbnZTdGF0c2A6IHNlIGVtcGxlYSBwYXJhIGxhIGRldGVjY2nDs24gZGUgb3V0bGllcnMgbcO6bHRpcGxlcywgZXNwZWNpYWxtZW50ZSBtZWRpYW50ZSBsYSBwcnVlYmEgZGUgUm9zbmVyIChgcm9zbmVyVGVzdGApLg0KDQotIGBETXdSMmA6IGltcGxlbWVudGEgbcOpdG9kb3MgYmFzYWRvcyBlbiBkZW5zaWRhZCBwYXJhIGRldGVjY2nDs24gZGUgdmFsb3JlcyBhdMOtcGljb3MsIGNvbW8gZWwgKkxvY2FsIE91dGxpZXIgRmFjdG9yIChMT0YpKi4NCg0KLSBgcmdsYDogc2UgdXRpbGl6YSBwYXJhIHZpc3VhbGl6YWNpw7NuIGdyw6FmaWNhIHRyaWRpbWVuc2lvbmFsIGRlIGRhdG9zLCBwb3IgZWplbXBsbyBjb24gYHBsb3QzZGAuDQoNCi0gYGNvcnJwbG90YDogcGVybWl0ZSBsYSB2aXN1YWxpemFjacOzbiBncsOhZmljYSBkZSBtYXRyaWNlcyBkZSBjb3JyZWxhY2nDs24gZGUgZm9ybWEgY29tcGFjdGEgZSBpbnRlcnByZXRhYmxlLg0KDQotIGB0ZXh0c2hhcGVgOiBzZSBlbXBsZWEgcGFyYSB0cmFuc2Zvcm1hY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgZGUgZGF0YSBmcmFtZXMsIGNvbW8gY29udmVydGlyIGNvbHVtbmFzIGVuIG5vbWJyZXMgZGUgZmlsYXMgKGBjb2x1bW5fdG9fcm93bmFtZXNgKS4NCg0KLSBgb3Blbnhsc3hgOiBwZXJtaXRlIGxlZXIgeSBlc2NyaWJpciBhcmNoaXZvcyBkZSBFeGNlbCBzaW4gZGVwZW5kZXIgZGUgc29mdHdhcmUgZXh0ZXJuby4NCg0KLSBga25pdHJgOiBzZSB1dGlsaXphIHBhcmEgbGEgY3JlYWNpw7NuIHkgcHJlc2VudGFjacOzbiBvcmRlbmFkYSBkZSB0YWJsYXMgeSByZXN1bHRhZG9zIGRlbnRybyBkZSBkb2N1bWVudG9zIFIgTWFya2Rvd24uDQoNCi0gYGthYmxlRXh0cmFgOiBleHRpZW5kZSBsYXMgY2FwYWNpZGFkZXMgZGUgYGtuaXRyYCBwYXJhIGdlbmVyYXIgdGFibGFzIGNvbiBmb3JtYXRvIGF2YW56YWRvLCBlc3BlY2lhbG1lbnRlIGVuIHNhbGlkYXMgSFRNTC4NCg0KDQpBIG1lZGlkYSBxdWUgYXZhbmNlIGVsIGNhcMOtdHVsbywgc2UgZXhwbGljYXLDoSBlbCBwcm9ww7NzaXRvIGRlIGNhZGEgZnVuY2nDs24gdXRpbGl6YWRhIHkgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIHN1cyByZXN1bHRhZG9zLCBwcmlvcml6YW5kbyBzaWVtcHJlIGVsIHNpZ25pZmljYWRvIGVzdGFkw61zdGljbyB5IHN1c3RhbnRpdm8gZGUgbG9zIG1vZGVsb3Mgc29icmUgZWwgdXNvIG1lcmFtZW50ZSB0w6ljbmljbyBkZWwgc29mdHdhcmUuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgU2ludMOheGlzIGNvbiBgbGF2YWFuYA0KDQojIyMgVGlwb3MgZGUgZsOzcm11bGFzDQoNClV0aWxpemFuZG8gY3VhdHJvIHRpcG9zIGRlIGbDs3JtdWxhcywgc2UgcHVlZGUgZGVzY3JpYmlyIHVuYSBncmFuIHZhcmllZGFkIGRlIG1vZGVsb3MgZGUgdmFyaWFibGVzIGxhdGVudGVzLiBFbCBjb25qdW50byBhY3R1YWwgZGUgdGlwb3MgZGUgZsOzcm11bGFzIHNlIHJlc3VtZSBlbiBsYSBmaWd1cmEgXEByZWYoZmlnOmxhdmFhbjEpLg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuMSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlRpcG9zIGRlIGbDs3JtdWxhcyoqIiwgb3V0LndpZHRoID0gIjYwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgU2ludMOheGlzIGRlIGxvcyBtb2RlbG9zDQoNCjEuIEVuIGBsYXZhYW5gLCBsb3MgbW9kZWxvcyBTRU0gcHVlZGVuIGVzcGVjaWZpY2Fyc2UgbWVkaWFudGUgZsOzcm11bGFzIGRlIG1vZGVsbyBzaW1pbGFyZXMgYSBsYXMgdXRpbGl6YWRhcyBlbiBsYXMgZnVuY2lvbmVzIGBsbWAgeSBgZ2xtYC4gDQoNCjIuIFNpbiBlbWJhcmdvLCBoYXkgYWxndW5vcyBvcGVyYWRvcmVzIG51ZXZvcyAoc8OtbWJvbG9zIHJlbGFjaW9uYWxlcykgcXVlIHNlIHV0aWxpemFuIHBhcmEgZGVmaW5pciBjb3ZhcmlhbnphcyAocmVzaWR1YWxlcykgeSB2YXJpYWJsZXMgbGF0ZW50ZXMuIA0KDQozLiBMYSBmaWd1cmEgXEByZWYoZmlnOmxhdmFhbjIpIGVudW1lcmEgYWxndW5hcyBleHByZXNpb25lcyBjb211bmVzIGVuIGxhIHNpbnRheGlzIGRlIGBsYXZhYW5gLg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuMiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlNpbnTDoXhpcyBkZSBsb3MgbW9kZWxvcyoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFamVtcGxvIGRlIGFwbGljYWNpw7NuOiBjb250ZXh0bw0KDQoNCg0KDQojIyMgQ29udGV4dG8gZGVsIGVzdHVkaW8geSBvYmpldGl2byBhbmFsw610aWNvDQoNCkVuIGVzdHVkaW9zIGVkdWNhdGl2b3MgeSBwc2ljb2zDs2dpY29zIGVzIGZyZWN1ZW50ZSBjb21wYXJhciBncnVwb3MgZGVmaW5pZG9zIHBvciBjYXJhY3RlcsOtc3RpY2FzIGluc3RpdHVjaW9uYWxlcywgc29jaWFsZXMgbyBkZW1vZ3LDoWZpY2FzIChwb3IgZWplbXBsbywgdGlwbyBkZSBlc2N1ZWxhLCBnw6luZXJvIG8gbml2ZWwgZWR1Y2F0aXZvKS4gU2luIGVtYmFyZ28sIGRpY2hhcyBjb21wYXJhY2lvbmVzIHNvbG8gc29uIHbDoWxpZGFzIHNpIHNlIGdhcmFudGl6YSBxdWUgbG9zIGluc3RydW1lbnRvcyB1dGlsaXphZG9zICpvcGVyYW4gZGUgZm9ybWEgZXF1aXZhbGVudGUgZW4gdG9kb3MgbG9zIGdydXBvcyBjb25zaWRlcmFkb3MqLg0KDQpFbiBlc3RlIGVqZW1wbG8gc2UgZXZhbMO6YSBzaSB1biBjb25qdW50byBkZSBwcnVlYmFzIGNvZ25pdGl2YXMgbWlkZSBsb3MgbWlzbW9zIGNvbnN0cnVjdG9zIGxhdGVudGVzIGVuIGRvcyBncnVwb3MgZGUgZXN0dWRpYW50ZXMgcGVydGVuZWNpZW50ZXMgYSAqZGlmZXJlbnRlcyB0aXBvcyBkZSBlc2N1ZWxhKi4gRWwgaW50ZXLDqXMgY2VudHJhbCBubyBlcyDDum5pY2FtZW50ZSBlc3RpbWFyIHVuIG1vZGVsbyBmYWN0b3JpYWwsIHNpbm8gKnZlcmlmaWNhciBlbXDDrXJpY2FtZW50ZSBsYSBpbnZhcmlhbnphIGRlIG1lZGlkYSosIGNvbWVuemFuZG8gcG9yIGxhIGludmFyaWFuemEgY29uZmlndXJhbCB5IGF2YW56YW5kbyBoYWNpYSBuaXZlbGVzIG3DoXMgcmVzdHJpY3Rpdm9zLCBlbiBwYXJ0aWN1bGFyIGxhIGludmFyaWFuemEgbcOpdHJpY2EuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAgLS0+DQoNCiMjIyBEZXNjcmlwY2nDs24gZGVsIGRhdGFzZXRzDQoNClNlIHV0aWxpemEgZWwgY29uanVudG8gZGUgZGF0b3MgY2zDoXNpY28gZGUgW0hvbHppbmdlciB5IFN3aW5lZm9yZCAoMTkzOSldKGh0dHBzOi8vcHN5Y25ldC5hcGEub3JnL3JlY29yZC8xOTM5LTA0NDQ1LTAwMSksIGFtcGxpYW1lbnRlIGVtcGxlYWRvIGVuIGxhIGxpdGVyYXR1cmEgbWV0b2RvbMOzZ2ljYSBwYXJhIGlsdXN0cmFyIG1vZGVsb3MgZmFjdG9yaWFsZXMgY29uZmlybWF0b3Jpb3MgeSBhbsOhbGlzaXMgbXVsdGlncnVwby4NCg0KDQpgYGB7cn0NCmhlYWQoSG9semluZ2VyU3dpbmVmb3JkMTkzOSkNCmBgYA0KDQpMYSB2aXN0YSBwcmVsaW1pbmFyIGRlIGxhcyBwcmltZXJhcyBvYnNlcnZhY2lvbmVzIHBlcm1pdGUgaWRlbnRpZmljYXIgZWwgdGlwbyBnZW5lcmFsIGRlIGluZm9ybWFjacOzbiBjb250ZW5pZGEgZW4gbGEgYmFzZSBkZSBkYXRvcywgaW5jbHV5ZW5kbyB2YXJpYWJsZXMgZGVtb2dyw6FmaWNhcywgdW5hIHZhcmlhYmxlIGRlIGFncnVwYWNpw7NuIHkgcHVudHVhY2lvbmVzIGVuIHBydWViYXMgY29nbml0aXZhcy4NCg0KRWwgZXN0dWRpbyBvcmlnaW5hbCBjb250aWVuZSBwdW50dWFjaW9uZXMgZGUgKnBydWViYXMgZGUgY2FwYWNpZGFkIG1lbnRhbCogYXBsaWNhZGFzIGEgMzAxIGVzdHVkaWFudGVzIGRlICpzw6lwdGltbyB5IG9jdGF2byBncmFkbyogcGVydGVuZWNpZW50ZXMgYSBkb3MgZXNjdWVsYXMgZGlzdGludGFzOiAqUGFzdGV1ciogeSAqR3JhbnQtV2hpdGUqLiBFbiBsYSB2ZXJzacOzbiBjb21wbGV0YSBkZWwgZXN0dWRpbyBzZSBpbmNsdXllbiAyNiBwcnVlYmFzOyBzaW4gZW1iYXJnbywgZ3JhbiBwYXJ0ZSBkZSBsYSBsaXRlcmF0dXJhICB1dGlsaXphIHVuIHN1YmNvbmp1bnRvIHJlZHVjaWRvIGRlICoxNSB2YXJpYWJsZXMqLCBxdWUgZXMgZWwgcXVlIHNlIGVtcGxlYSBlbiBlc3RhIGFwbGljYWNpw7NuLg0KDQoNCmBgYHtyfQ0KZGltKEhvbHppbmdlclN3aW5lZm9yZDE5MzkpDQpgYGANCg0KDQpMYSBkaW1lbnNpw7NuIGRlbCBjb25qdW50byBkZSBkYXRvcyBjb25maXJtYSBxdWUgc2UgZGlzcG9uZSBkZSAzMDEgb2JzZXJ2YWNpb25lcyB5IDE1IHZhcmlhYmxlcywgbG8gY3VhbCByZXN1bHRhIGFkZWN1YWRvIHBhcmEgaWx1c3RyYXIgcHJvY2VkaW1pZW50b3MgZGUgYW7DoWxpc2lzIGZhY3RvcmlhbCBjb25maXJtYXRvcmlvIHkgZXZhbHVhY2nDs24gZGUgaW52YXJpYW56YSBtdWx0aWdydXBvLg0KDQpBZGljaW9uYWxtZW50ZSwgZWwgY29uanVudG8gZGUgZGF0b3MgcHJlc2VudGEgbGFzIHNpZ3VpZW50ZXMgY2FyYWN0ZXLDrXN0aWNhcyBjbGF2ZSBwYXJhIGVsIGFuw6FsaXNpcyBkZSBpbnZhcmlhbnphIGRlIG1lZGlkYToNCg0KLSAqRG9zIGdydXBvcyosIGRlZmluaWRvcyBwb3IgbGEgdmFyaWFibGUgYHNjaG9vbGAgKFBhc3RldXIgeSBHcmFudC1XaGl0ZSksIHF1ZSBwdWVkZSBhY3R1YXIgY29tbyB2YXJpYWJsZSBkZSBhZ3J1cGFjacOzbiBlbiBlbCBhbsOhbGlzaXMgbXVsdGlncnVwby4NCg0KLSAqVHJlcyBjb25zdHJ1Y3RvcyBsYXRlbnRlcyogdGXDs3JpY2FtZW50ZSBkZWZpbmlkb3M6DQogIA0KICAgLSBgdmlzdWFsYDogaGFiaWxpZGFkZXMgZGUgcGVyY2VwY2nDs24gdmlzdWFsLg0KICAgIA0KICAgLSBgdGV4dHVhbGA6IGhhYmlsaWRhZGVzIHZlcmJhbGVzLg0KICAgIA0KICAgLSBgc3BlZWRgOiByYXBpZGV6IGVuIHRhcmVhcyBjb2duaXRpdmFzLg0KICAgIA0KLSAqTnVldmUgaW5kaWNhZG9yZXMgb2JzZXJ2YWRvcyosIGRpc3RyaWJ1aWRvcyBlcXVpdGF0aXZhbWVudGUgZW4gdHJlcyDDrXRlbXMgcG9yIGNhZGEgZmFjdG9yIGxhdGVudGUuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBEZXNjcmlwY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBkZWwgZGF0YXNldHMNCg0KQSBjb250aW51YWNpw7NuIHNlIG11ZXN0cmFuIGxvcyBub21icmVzIGRlIHRvZGFzIGxhcyB2YXJpYWJsZXMgaW5jbHVpZGFzIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zOg0KDQpgYGB7cn0NCm5hbWVzKEhvbHppbmdlclN3aW5lZm9yZDE5MzkpDQpgYGANCg0KTGFzIHZhcmlhYmxlcyBwdWVkZW4gYWdydXBhcnNlIGNvbmNlcHR1YWxtZW50ZSBkZSBsYSBzaWd1aWVudGUgZm9ybWE6DQoNCg0KMS4gVmFyaWFibGVzIGRlIGlkZW50aWZpY2FjacOzbiB5IGNvbnRleHRvOg0KDQogICAgDQogICAtIGBpZGA6IGlkZW50aWZpY2Fkb3IgZGVsIGVzdHVkaWFudGUuICANCiAgICANCiAgIC0gYHNjaG9vbGA6IGVzY3VlbGEgKGBncm91cCAxID0gUGFzdGV1cmAgbyBgZ3JvdXAgMiA9IEdyYW50LVdoaXRlYCkuIA0KICAgIA0KICAgLSBgZ3JhZGVgOiBncmFkbyBlc2NvbGFyLiAgDQogICANCg0KMi4gVmFyaWFibGVzIGRlbW9ncsOhZmljYXM6DQoNCiAgICANCiAgIC0gYHNleGA6IGfDqW5lcm8gKGAxID0gTWFsZWAgbyBgMiA9IEZlbWFsZWApLiAgDQogICAgDQogICAtIGBhZ2V5cmA6IGVkYWQgKHBhcnRlIGRlbCBhw7FvKS4gDQogICAgDQogICAtIGBhZ2Vtb2A6IGVkYWQgKHBhcnRlIGRlbCBtZXMpLiANCiAgIA0KDQozLiBJbmRpY2Fkb3JlcyBjb2duaXRpdm9zIGB4MWAsIGB4MmAsIC4uLiwgYHg5YCwgdXRpbGl6YWRvcyBlbiBlbCBtb2RlbG8gZmFjdG9yaWFsIHkgcXVlICBmdWVyb24gY2FsY3VsYWRhcyBhIHRyYXbDqXMgZGUgZnVuY2lvbmVzIGRlIHBydWViYXMgY29nbml0aXZhczoNCg0KDQogICAtICpGYWN0b3IgdmlzdWFsKjogaGFiaWxpZGFkZXMgZGUgcGVyY2VwY2nDs24geSByYXpvbmFtaWVudG8gdmlzdWFsICANCiAgDQogICAgICAtIGB4MWA6IFZpc3VhbCBwZXJjZXB0aW9uIChwZXJjZXBjacOzbiB2aXN1YWwpLg0KICAgICAgDQogICAgICAtIGB4MmA6IEN1YmVzIChjdWJvcykuICANCiAgICAgIA0KICAgICAgLSBgeDNgOiBMb3plbmdlcyAocGFzdGlsbGFzKS4gIA0KICANCiAgICAtICpGYWN0b3IgdGV4dHVhbCogOiBoYWJpbGlkYWRlcyB2ZXJiYWxlcyB5IGRlIGNvbXByZW5zacOzbiBsaW5nw7zDrXN0aWNhIA0KICAgIA0KICAgICAgLSBgeDRgOiBQYXJhZ3JhcGggY29tcHJlaGVuc2lvbiAoY29tcHJlbnNpw7NuIGRlIHBhcsOhZ3JhZm9zKS4gIA0KICAgICAgDQogICAgICAtIGB4NWA6IFNlbnRlbmNlIGNvbXBsZXRpb24gKGNvbXBsZXRhciBvcmFjaW9uZXMpLiANCiAgICAgIA0KICAgICAgLSBgeDZgOiBXb3JkIG1lYW5pbmcgKHNpZ25pZmljYWRvIGRlIHBhbGFicmFzKS4NCiAgDQogICAgLSAqRmFjdG9yIHNwZWVkKjogcmFwaWRleiBlbiB0YXJlYXMgY29nbml0aXZhcyBzaW1wbGVzIA0KICAgIA0KICAgICAgLSBgeDdgOiBTcGVlZGVkIGFkZGl0aW9uIChhZGljacOzbiBjb24gdmVsb2NpZGFkKS4NCiAgICAgIA0KICAgICAgLSBgeDhgOiBTcGVlZGVkIGNvdW50aW5nIG9mIGRvdHMgKGNvbnRlbyBkZSBwdW50b3MgY29uIHZlbG9jaWRhZCkuDQogICAgICANCiAgICAgIC0gYHg5YDogU3BlZWRlZCBkaXNjcmltaW5hdGlvbiBzdHJhaWdodCBhbmQgY3VydmVkIGNhcGl0YWxzIChkaXNjcmltaW5hY2nDs24gYWNlbGVyYWRhIGRlIGxldHJhcyBtYXnDunNjdWxhcyByZWN0YXMgeSBjdXJ2YXMpLiBQb3IgZWplbXBsbzogKmxldHJhcyBjb24gdHJhem9zIHJlY3RvcyogKEEsIEUsIEYsIEgsIEksIEssIEwsIE0sIE4sIFQsIFYsIFcsIFgsIFksIFopIHkgICpsZXRyYXMgY29uIHRyYXpvcyBjdXJ2b3MqIChCLCBDLCBELCBHLCBKLCBPLCBQLCBRLCBSLCBTLCBVKS4NCiANCg0KDQpGaW5hbG1lbnRlLCBzZSBpbnNwZWNjaW9uYSBsYSBlc3RydWN0dXJhIGludGVybmEgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIHBhcmEgaWRlbnRpZmljYXIgZWwgdGlwbyBkZSBjYWRhIHZhcmlhYmxlIChudW3DqXJpY2EsIGZhY3RvciwgY2Fyw6FjdGVyKSwgaW5mb3JtYWNpw7NuIHJlbGV2YW50ZSBwYXJhIGxhIGNvcnJlY3RhIGVzcGVjaWZpY2FjacOzbiBkZWwgbW9kZWxvIENGQSBtdWx0aWdydXBvOg0KDQpgYGB7cn0NCnN0cihIb2x6aW5nZXJTd2luZWZvcmQxOTM5KQ0KYGBgDQoNCg0KRXN0YSBpbnNwZWNjacOzbiBjb25maXJtYSBsYSBwcmVzZW5jaWEgZGUgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyAocG9yIGVqZW1wbG8sIGBzY2hvb2xgKSB5IHZhcmlhYmxlcyBudW3DqXJpY2FzIGNvcnJlc3BvbmRpZW50ZXMgYSBsb3MgaW5kaWNhZG9yZXMgb2JzZXJ2YWRvcywgbG8gY3VhbCByZXN1bHRhIGZ1bmRhbWVudGFsIHBhcmEgbGEgY29ycmVjdGEgZGVmaW5pY2nDs24gZGVsIG1vZGVsbyBkZSBtZWRpY2nDs24geSBkZSB1biBhbsOhbGlzaXMgbXVsdGlncnVwbyBwb3N0ZXJpb3IuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBOdWVzdHJvIGRhdGEgZnJhbWUgZW4gUg0KDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0b3NDb21wbGV0byA8LSBsYXZhYW46OkhvbHppbmdlclN3aW5lZm9yZDE5MzkNCmF0dGFjaChkYXRvc0NvbXBsZXRvKQ0KYGBgDQoNClNlIHJlc2FsdGEgcXVlIHPDs2xvIGFsZ3VuYXMgZGUgZXN0YXMgdmFyaWFibGVzIHNlIHV0aWxpemFyw6FuIHBhcmEgcmVhbGl6YXIgZWwgU0VNLiANCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGF0IDwtIGRhdG9zQ29tcGxldG9bNzoxNV0NCmF0dGFjaChkYXQpDQpoZWFkKGRhdCw0KSANCmBgYA0KDQoNCg0KYGBge3IgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdCA8LSBkYXRvc0NvbXBsZXRvWzc6MTVdDQphdHRhY2goZGF0KQ0KDQprYWJsZShoZWFkKGRhdCw0KSxhbGlnbiA9ICJjY2MiKSAlPiUjIFNlIG5lY2VzaXRhIGxpYnJhcnkoa25pdHIpIA0Ka2FibGVfc3R5bGluZygpICU+JSAgICAgICAgICAgICAgICAjbGlicmFyeShrYWJsZUV4dHJhKS4uLi4gU29sbyBwYXJhIGtuaXQgdG8gaHRtbA0Ka2FibGVfY2xhc3NpY18yKGZ1bGxfd2lkdGggPSBGKSAgICNsaWJyYXJ5KGthYmxlRXh0cmEpLi4uLlNvbG8gcGFyYSBrbml0IHRvIGh0bWwNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRWplbXBsbzogYWxndW5vcyBhbsOhbGlzaXMgZXhwbG9yYXRvcmlvcw0KDQojIyMgRXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3MgYsOhc2ljb3MNCg0KUHJpbWVybywgZXMgcmVjb21lbmRhYmxlIGV4YW1pbmFyIGxvcyBkYXRvcyBhbnRlcyBkZSByZWFsaXphciBjdWFscXVpZXIgYW7DoWxpc2lzLiBDdWFscXVpZXIgcGFydGljaXBhbnRlIHF1ZSB0ZW5nYSBhbGfDum4gZGF0byBmYWx0YW50ZSBzZXLDoSBleGNsdWlkbyBwb3IgY29tcGxldG8gZGVsIGFuw6FsaXNpcy4gIFNlIHB1ZWRlbiB1dGlsaXphciBkaXZlcnNhcyBmdW5jaW9uZXMgKGNvbW8gc2UgbXVlc3RyYSBhIGNvbnRpbnVhY2nDs24pLg0KDQoNCmBgYHtyfQ0KZGVzY3JpYmUoZGF0KQ0KYGBgDQoNClNlIHJlc2FsdGEgcXVlLCBsYSBmdW5jacOzbiBgZGVzY3JpYmVgIGRlIGxhIGxpYnJlcsOtYSBgcHN5Y2hgLCBlbCBvdXRwdXQ6DQogIA0KICArIGB0aW1tZWRgIHNlIHJlZmllcmUgYSBsYSBtZWRpYW5hIHRydW5jYWRhLCBxdWUgZXMgdW5hIG1lZGlkYSBkZSB0ZW5kZW5jaWEgY2VudHJhbCByb2J1c3RhIHF1ZSBjYWxjdWxhIGxhIG1lZGlhbmEgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgZGVzcHXDqXMgZGUgZWxpbWluYXIgdW4gY2llcnRvIHBvcmNlbnRhamUgZGUgb2JzZXJ2YWNpb25lcyBtw6FzIGV4dHJlbWFzLiANCiAgDQogICsgYG1hZGAgc2lnbmlmaWNhIGRlc3ZpYWNpw7NuIGFic29sdXRhIG1lZGlhbmEsIHF1ZSBlcyB1bmEgbWVkaWRhIGRlIGRpc3BlcnNpw7NuIHF1ZSBpbmRpY2EgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBkYXRvcyBlbiByZWxhY2nDs24gY29uIGxhIG1lZGlhbmEuDQogIA0KICArIGBza2V3YCBzZSByZWZpZXJlIGEgbGEgYXNpbWV0csOtYSBkZSBsb3MgZGF0b3MsIHF1ZSBpbmRpY2Egc2kgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3MgZGF0b3MgZXMgc2ltw6l0cmljYSBvIHNpIGVzdMOhIHNlc2dhZGEgaGFjaWEgdW4gbGFkby4gVW4gdmFsb3IgcG9zaXRpdm8gaW5kaWNhIHNlc2dvIGhhY2lhIGxhIGRlcmVjaGEsIG1pZW50cmFzIHF1ZSB1biB2YWxvciBuZWdhdGl2byBpbmRpY2Egc2VzZ28gaGFjaWEgbGEgaXpxdWllcmRhLg0KICANCiAgKyBga3VydG9zaXNgIHNlIHJlZmllcmUgYSBsYSBjdXJ0b3NpcyBkZSBsb3MgZGF0b3MsIHF1ZSBpbmRpY2EgbGEgZm9ybWEgZGUgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3MgZGF0b3MgZW4gcmVsYWNpw7NuIGNvbiB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwuIFVuIHZhbG9yIGRlIGt1cnRvc2lzIG1heW9yIHF1ZSBjZXJvIGluZGljYSB1bmEgZGlzdHJpYnVjacOzbiBtw6FzIHB1bnRpYWd1ZGEgKG3DoXMgcGljb3MpIHF1ZSBsYSBkaXN0cmlidWNpw7NuIG5vcm1hbCwgbWllbnRyYXMgcXVlIHVuIHZhbG9yIG1lbm9yIHF1ZSBjZXJvIGluZGljYSB1bmEgZGlzdHJpYnVjacOzbiBtw6FzIGFjaGF0YWRhIChtZW5vcyBwaWNvcykgcXVlIGxhIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLg0KICANCiAgKyBgc2VgIHNlIHJlZmllcmUgYWwgZXJyb3IgZXN0w6FuZGFyLCBxdWUgZXMgdW5hIG1lZGlkYSBkZSBsYSBwcmVjaXNpw7NuIGRlIGxhIGVzdGltYWNpw7NuIGRlIHVuYSBlc3RhZMOtc3RpY2EgZGUgbGEgbXVlc3RyYS4gSW5kaWNhIGxhIHZhcmlhYmlsaWRhZCBlc3BlcmFkYSBlbiBsYSBlc3RpbWFjacOzbiBkZSBsYSBlc3RhZMOtc3RpY2Egc2kgc2UgbXVlc3RyZWEgcmVwZXRpZGFtZW50ZSBkZSBsYSBtaXNtYSBwb2JsYWNpw7NuLiBVbiBlcnJvciBlc3TDoW5kYXIgbcOhcyBwZXF1ZcOxbyBpbmRpY2EgdW5hIGVzdGltYWNpw7NuIG3DoXMgcHJlY2lzYSBkZSBsYSBlc3RhZMOtc3RpY2EgZGUgaW50ZXLDqXMuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KYGBge3J9DQpzdW1tYXJ5KGRhdCkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KT3RyYSB0YWJsYSBkZSBmcmVjdWVuY2lhczogDQoNCmBgYHtyfQ0KIyBHZW5lcmEgbGEgdGFibGFzIHVzYW5kbyBkcGx5ciBhbmQgdGlkeXIgeSBrYWJsZQ0KZGF0ICU+JSANCiAgc2VsZWN0KHgxOng5KSAlPiUgDQogIGdhdGhlcigiVmFyaWFibGUiLCAidmFsdWUiKSAlPiUgDQogIGdyb3VwX2J5KFZhcmlhYmxlKSAlPiUgDQogIHN1bW1hcmlzZShNZWFuPW1lYW4odmFsdWUsIG5hLnJtPVRSVUUpLCANCiAgICAgICAgICAgIFNEPXNkKHZhbHVlLCBuYS5ybT1UUlVFKSwgDQogICAgICAgICAgICBtaW49bWluKHZhbHVlLCBuYS5ybT1UUlVFKSwgDQogICAgICAgICAgICBtYXg9bWF4KHZhbHVlLCBuYS5ybT1UUlVFKSwgDQogICAgICAgICAgICAnJSBQZXJkaWRvcyc9MTAwKmxlbmd0aCh3aGljaChpcy5uYSh2YWx1ZSkpKS9uKCkpICU+JSANCiAga2FibGUoZGlnaXRzPTIsIGZvcm1hdD0icGFuZG9jIiwgY2FwdGlvbj0iVGFibGEgMTogRXN0YWRpc3RpY29zIGRlc2NyaXB0aXZvcyBwYXJhIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIERhdG9zIGZhbHRhbnRlcw0KDQpMYSBtYXlvcsOtYSBkZSBsb3MgZWxlbWVudG9zIHNvbG8gY2FyZWNlbiBkZSBkYXRvcyBlcXVpdmFsZW50ZXMgYSAyMCBvIDMwIHBhcnRpY2lwYW50ZXMsIGxvIGN1YWwgbm8gcmVwcmVzZW50YSB1biBncmFuIHByb2JsZW1hIGVuIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGNvbiAyODAwIG9ic2VydmFjaW9uZXMuIFNpbiBlbWJhcmdvLCBlcyBwb3NpYmxlIHF1ZSBhbGd1bm9zIGRlIGVzdG9zIHZhbG9yZXMgZmFsdGFudGVzIG5vIHNlIHN1cGVycG9uZ2FuLCBsbyBxdWUgc2lnbmlmaWNhIHF1ZSBwb2Ryw61hbiBmYWx0YXIgMjAgbyAzMCBpbmRpdmlkdW9zIGRpZmVyZW50ZXMgZW4gY2FkYSB1bmEgZGUgbGFzIHZhcmlhYmxlcy4gDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIERhdG9zIHBlcmRpZG9zIHBvciBjb2x1bW5hDQoNCmBgYHtyfQ0KbWlzc2luZ3MgPC0gY29sU3Vtcyhpcy5uYShkYXQpKSANCm1pc3NpbmdzDQoNCnN1bW1hcnkobWlzc2luZ3MpIA0KYGBgDQoNCkFsdGVybmF0aXZhbWVudGUsIHBvZGVtb3MgbWlyYXIgYWxndW5hcyB2YXJpYWJsZXMgY29uIGFsZ3VuYSBjb25kaWNpw7NuIHBhcmEgZWwgbsO6bWVybyBkZSBkYXRvcyBwZXJkaWRvcy4gDQoNCmBgYHtyfQ0KbXlkYXRhIDwtIGRhdFsgLCBtaXNzaW5nczwxNV0NCm5hbWVzKG15ZGF0YSkNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBGdW5jacOzbiBgY29tcGxldGUuY2FzZXNgDQoNCg0KTm8gb2JzdGFudGUsIHBvZGVtb3MgZGV0ZXJtaW5hciBlbCBuw7ptZXJvIGRlICJjYXNvcyBjb21wbGV0b3MiIGRlbnRybyBkZSBsb3MgZGF0b3MsIHF1ZSBzb24gaW5kaXZpZHVvcyBxdWUgbm8gdGllbmVuIGRhdG9zIGZhbHRhbnRlcyBlbiBhYnNvbHV0byBlbiBlbCBjdWVzdGlvbmFyaW8uDQoNCg0KYGBge3J9DQpmYWx0YW50ZSA8LSBjb21wbGV0ZS5jYXNlcyhkYXQpO3RhaWwoZmFsdGFudGUpDQoNCnN1bShmYWx0YW50ZSkNCg0KYGBgDQoNCkxhIGZ1bmNpw7NuIGBjb21wbGV0ZS5jYXNlc2AgcHJvZHVjZSB1biB2ZWN0b3IgZGUgdmFsb3JlcyBib29sZWFub3MsIGRvbmRlIGBUUlVFYCBpbmRpY2EgdW4gY2FzbyBjb21wbGV0byB5IGBGQUxTRWAgaW5kaWNhIHVuIGNhc28gY29uIHZhbG9yZXMgZmFsdGFudGVzLiBMYSBzdW1hIGRlIGVzdGUgdmVjdG9yIG5vcyBkYSBlbCB0b3RhbCBkZSBjYXNvcyBjb21wbGV0b3MsIHF1ZSBlbiBlc3RlIGNhc28gZXMgYHIgc3VtKGZhbHRhbnRlKWAuIEVsIHBvcmNlbnRhamUgZGUgZGF0b3MgYXVzZW50ZXMgZXMgYHIgKDEgLSAoc3VtKGZhbHRhbnRlKS9ucm93KGRhdCkpKSoxMDBgJTogDQoNCg0KYGBge3J9DQooMSAtIChzdW0oZmFsdGFudGUpL25yb3coZGF0KSkpKjEwMA0KDQpgYGANCg0KDQpBdW5xdWUgbm8gZXhpc3RlIHVuIHZhbG9yIGV4YWN0byBxdWUgZGV0ZXJtaW5lIHF1w6kgY2FudGlkYWQgZGUgZGF0b3MgZmFsdGFudGVzIGVzIGFjZXB0YWJsZSwgbGEgaW1wb3J0YW5jaWEgZGVsIHRhbWHDsW8gZGUgbGEgbXVlc3RyYSBlbiBlbCBhbsOhbGlzaXMgZmFjdG9yaWFsIGVzIGlubmVnYWJsZS4gU2Vnw7puIGFsZ3Vub3MgZXhwZXJ0b3MsIHNlIHJlY29taWVuZGEgY29udGFyIGNvbiBhbCBtZW5vcyAxMCBvYnNlcnZhY2lvbmVzIHBvciBjYWRhIHZhcmlhYmxlIGVuIGRpY2hvIGFuw6FsaXNpcywgbG8gcXVlIHN1Z2llcmUgcXVlIG51ZXN0cm8gdGFtYcOxbyBkZSBtdWVzdHJhIGVzIGFwcm9waWFkbyBwYXJhIG51ZXN0cm9zIG9iamV0aXZvcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFc3BlY2lmaWNhY2nDs24gZGVsIG1vZGVsbw0KDQojIyMgRWwgbW9kZWxvIHRlw7NyaWNvDQoNClVuIG1vZGVsbyBDRkEgcXVlIHNlIHN1ZWxlIHByb3B1ZXN0byBwYXJhIGVzdGFzIDkgdmFyaWFibGVzIGNvbnN0YSBkZSB0cmVzIHZhcmlhYmxlcyBsYXRlbnRlcyAobyBmYWN0b3JlcyksIGNhZGEgdW5hIGNvbiB0cmVzIGluZGljYWRvcmVzOg0KDQoxLiBVbiBmYWN0b3IgKnZpc3VhbCogKGB2aXN1YWxgKSBtZWRpZG8gcG9yIDMgdmFyaWFibGVzOiB4MSwgeDIgeSB4My4NCg0KMi4gVW4gZmFjdG9yICp0ZXh0dWFsKiAoYHRleHR1YWxgKSBtZWRpZG8gcG9yIDMgdmFyaWFibGVzOiB4NCwgeDUgeSB4Ni4NCg0KMy4gVW4gZmFjdG9yIGRlICp2ZWxvY2lkYWQqIChgc3BlZWRgKSBtZWRpZG8gcG9yIDMgdmFyaWFibGVzOiB4NywgeDggeSB4OS4NCiANCkxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMykgY29udGllbmUgdW5hIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkZWwgbW9kZWxvIGRlIHRyZXMgZmFjdG9yZXMuDQoNCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjMsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipNb2RlbG8gQ0ZBIHBhcmEgbG9zIGRhdG9zIGBIb2x6aW5nZXJTd2luZWZvcmQxOTM5YCoqIiwgb3V0LndpZHRoID0gIjYwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4zLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgRWwgbW9kZWxvIGVuIFINCg0KVW5hIHNpbnRheGlzIGRlIG1vZGVsbyBsYXZhYW4gY29tcGxldGEgZXMgc2ltcGxlbWVudGUgdW5hIGNvbWJpbmFjacOzbiBkZSBlc3RvcyB0aXBvcyBkZSBmw7NybXVsYXMsIGVuY2VycmFkYXMgZW50cmUgY29taWxsYXMgc2ltcGxlcy4NCg0KDQpgYGB7cn0NCm1vZGVsbyA8LSAnIA0KdmlzdWFsID1+IHgxICsgeDIgKyB4Mw0KdGV4dHVhbCA9fiB4NCArIHg1ICsgeDYNCnNwZWVkID1+IHg3ICsgeDggKyB4OSANCicNCmBgYA0KDQpFbiBlc3RlIGVqZW1wbG8sIGxhIHNpbnRheGlzIGRlbCBtb2RlbG8gc8OzbG8gY29udGllbmUgdHJlcyAqZGVmaW5pY2lvbmVzIGRlIHZhcmlhYmxlcyBsYXRlbnRlcyouIEVuIHBhcnRpY3VsYXIsIA0KDQoNCi0gRWwgb3BlcmFkb3IgYD1+YCBpbmRpY2EgdW5hICpyZWxhY2nDs24gZGUgbWVkaWNpw7NuKiwgZXMgZGVjaXIsIHF1ZSB1biBmYWN0b3IgbGF0ZW50ZSBleHBsaWNhIHVuIGNvbmp1bnRvIGRlIHZhcmlhYmxlcyBvYnNlcnZhZGFzLg0KDQotIExhcyB2YXJpYWJsZXMgYSBsYSBpenF1aWVyZGEgZGUgYD1+YCByZXByZXNlbnRhbiAqY29uc3RydWN0b3MgbGF0ZW50ZXMqLg0KDQotIExhcyB2YXJpYWJsZXMgYSBsYSBkZXJlY2hhIHJlcHJlc2VudGFuICppbmRpY2Fkb3JlcyBvYnNlcnZhZG9zKi4NCg0KUG9yIGVqZW1wbG8sIGxhIGV4cHJlc2nDs246DQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KdmlzdWFsID1+IHgxICsgeDIgKyB4Mw0KYGBgDQoNCg0KaW5kaWNhIHF1ZSBlbCBmYWN0b3IgbGF0ZW50ZSBgdmlzdWFsYCBzZSBtaWRlIGEgdHJhdsOpcyBkZSBsb3Mgw610ZW1zIGB4MWAsIGB4MmAgeSBgeDNgLiAgTGFzICpjYXJnYXMgZmFjdG9yaWFsZXMqIGFzb2NpYWRhcyBhIGVzdGFzIHJlbGFjaW9uZXMgc2UgZXN0aW1hbiBhIHBhcnRpciBkZSBsb3MgZGF0b3MsIHNhbHZvIGFxdWVsbGFzIHF1ZSBzZSBmaWphbiBwYXJhIGdhcmFudGl6YXIgbGEgaWRlbnRpZmljYWJpbGlkYWQgZGVsIG1vZGVsbyAocG9yIGVqZW1wbG8sIGZpamFuZG8gdW5hIGNhcmdhIGZhY3RvcmlhbCBhIDEgZW4gY2FkYSBmYWN0b3IpLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIFRpcG9zIGRlIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8NCg0KIyMjIEV4cGxpY2FjacOzbg0KDQoxLiBFbiBlbCBjb250ZXh0byBkZWwgYW7DoWxpc2lzIGZhY3RvcmlhbCBjb25maXJtYXRvcmlvIChDRkEpIGNvbiBlbCBwYXF1ZXRlIGBsYXZhYW5gIGVuIFIsIGVsIG7Dum1lcm8gZGUgcGFyw6FtZXRyb3MgZW4gZWwgb3V0cHV0IGRlbCBtb2RlbG8gZGVwZW5kZSBkZSBsYXMgZXNwZWNpZmljYWNpb25lcyBkZWwgbW9kZWxvIHkgbG9zIGRhdG9zIHV0aWxpemFkb3MuIA0KDQoyLiBFbCBtb2RlbG8gcXVlIHNlIGhhIGluZGljYWRvIHBhcmEgbG9zIGRhdG9zIGBIb2x6aW5nZXJTd2luZWZvcmQxOTM5YCBlc3BlY2lmaWNhIHRyZXMgZmFjdG9yZXMgbGF0ZW50ZXMgKGBWaXN1YWxgLCAgYFRleHR1YWxgLCAgYFNwZWVkYCkgY2FkYSB1bm8gY29uIHRyZXMgaW5kaWNhZG9yZXMuIA0KDQozLiBFbiBlc3RlIHNlbnRpZG8sIGlkZW50aWZpY2Ftb3MgZG9zIHRpcG9zIGRlIHBhcsOhbWV0cm9zOiANCiAgDQogICsgUGFyw6FtZXRyb3MgZGUgbWVkaWRhcy4NCiAgDQogICsgUGFyw6FtZXRyb3MgZXN0cnVjdHVyYWxlcy4gDQogIA0KNC4gRW4gbGFzIHNpZ3VpZW50ZXMgc2VjY2lvbmVzIGV4cGxpY2FyZW1vcyBjYWRhIHVubyBkZSBlc3RvcyB0aXBvcy4gDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQp7XGNvbG9ye1RlYWx9IFxsYW1iZGFfMiwgXDsgICBcbGFtYmRhXzMsIFw7ICAgXGxhbWJkYV80LCBcOyAgIFxsYW1iZGFfNSwgXDsgICBcbGFtYmRhXzYsIFw7ICAgXGxhbWJkYV83fVxcDQpcXA0Ke1xjb2xvcntUZWFsfSBcdGF1XzEsIFw7ICAgXHRhdV8yLCBcOyAgIFx0YXVfMywgXDsgICBcdGF1XzQsIFw7ICAgXHRhdV81LCBcOyAgIFx0YXVfNiwgXDsgICBcdGF1XzcsIFw7ICAgXHRhdV84LCBcOyAgIFx0YXVfOX1cXA0KXFwNCntcY29sb3J7VGVhbH0gXHZhcmVwc2lsb25fMSwgXDsgICBcdmFyZXBzaWxvbl8yLCBcOyAgIFx2YXJlcHNpbG9uXzMsIFw7ICAgXHZhcmVwc2lsb25fNCwgXDsgICBcdmFyZXBzaWxvbl81LCBcOyAgIFx2YXJlcHNpbG9uXzYsIFw7ICAgXHZhcmVwc2lsb25fNywgXDsgICBcdmFyZXBzaWxvbl84LCBcOyAgIFx2YXJlcHNpbG9uXzl9XFwNClxcDQp7XGNvbG9ye1RlYWx9IFxhbHBoYV8xLCBcOyAgIFxhbHBoYV8yLCBcOyAgIFxhbHBoYV8zfVxcDQpcXA0Ke1xjb2xvcntUZWFsfSBccHNpX3sxMX0sIFw7ICAgXHBzaV97MjJ9LCBcOyAgIFxwc2lfezMzfX1cXA0KXFwNCntcY29sb3J7VGVhbH0gXHBzaV97MTJ9LCBcOyAgIFxwc2lfezEzfSwgXDsgICBccHNpX3syM319DQoNCmh0dHBzOi8vcnB1YnMuY29tL0pvXy9sYXZhYW5fZWZlY3Rvc19kaXJlY3Rvcw0KaHR0cHM6Ly9zdGF0cy5vYXJjLnVjbGEuZWR1L3Ivc2VtaW5hcnMvcnNlbS8NCmh0dHBzOi8vbXNwZWVrZW5icmluay5naXRodWIuaW8vc2RhbS1yLWNvbXBhbmlvbi9zdHJ1Y3R1cmFsLWVxdWF0aW9uLW1vZGVsbGluZy13aXRoLWxhdmFhbi5odG1sDQoNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFBhcsOhbWV0cm9zIGRlIG1lZGlkYXMNCg0KRW4gdW4gbW9kZWxvIENGQSB0w61waWNvLCBsb3MgKnBhcsOhbWV0cm9zIGRlIG1lZGlkYXMqIHF1ZSBzZSBxdWllcmVuIGVzdGltYXIgaW5jbHV5ZW4gKHbDqWFzZSBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjQpKToNCg0KKioxLiBDYXJnYXMgRmFjdG9yaWFsZXMuKiogDQoNCkxhcyByZWxhY2lvbmVzIGVudHJlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcyB5IHN1cyBpbmRpY2Fkb3Jlcy4NCg0KJCRcbGFtYmRhXzEsIFxxdWFkICBcbGFtYmRhXzIsIFxxdWFkICBcbGFtYmRhXzMsIFxxdWFkICBcbGFtYmRhXzQsIFxxdWFkICBcbGFtYmRhXzUsIFxxdWFkICBcbGFtYmRhXzYsIFxxdWFkICBcbGFtYmRhXzcsIFxxdWFkICBcbGFtYmRhXzgsIFxxdWFkICBcbGFtYmRhXzkkJA0KDQoqKjIuIEludGVyY2VwdG9zIGRlIGxvcyBGYWN0b3JlcyBMYXRlbnRlcy4qKiANCg0KJCRcdGF1XzEsIFxxdWFkICBcdGF1XzIsIFxxdWFkICBcdGF1XzMsIFxxdWFkICBcdGF1XzQsIFxxdWFkICBcdGF1XzUsIFxxdWFkICBcdGF1XzYsIFxxdWFkICBcdGF1XzcsIFxxdWFkICBcdGF1XzgsIFxxdWFkICBcdGF1XzkkJA0KKiozLiBWYXJpYW56YXMgZGUgbG9zIEVycm9yZXMgZGUgTWVkaWNpw7NuLioqDQoNClZhcmlhbnphcyBkZSBsb3MgdMOpcm1pbm9zIGRlIGVycm9yIGFzb2NpYWRvcyBhIGNhZGEgaW5kaWNhZG9yLiANCg0KJCRWKFx2YXJlcHNpbG9uXzEpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzIpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzMpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzQpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzUpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzYpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzcpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzgpLCBccXVhZCBWKFx2YXJlcHNpbG9uXzkpJCQNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgUGFyw6FtZXRyb3MgZXN0cnVjdHVyYWxlcw0KDQpFbiB1biBtb2RlbG8gQ0ZBIHTDrXBpY28sIGxvcyAqcGFyw6FtZXRyb3MgZXN0cnVjdHVyYWxlcyogcXVlIHNlIHF1aWVyZW4gZXN0aW1hciBpbmNsdXllbiAodsOpYXNlIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuNCkpOg0KDQoqKjQuIExhIG1lZGlhIGRlIGxvcyBmYWN0b3Jlcy4qKg0KDQokJFxtdV8xLCBccXVhZCAgXG11XzIsIFxxdWFkICBcbXVfMyQkDQoNCioqNS4gVmFyaWFuemFzIGRlIGxvcyBGYWN0b3JlcyBMYXRlbnRlcy4qKg0KDQpWYXJpYW56YXMgZGUgY2FkYSBmYWN0b3IuDQoNCiQkXHBzaV97MTF9LCBccXVhZCAgXHBzaV97MjJ9LCBccXVhZCAgXHBzaV97MzN9JCQNCg0KKio2LiBDb3ZhcmlhbnphcyBkZSBsb3MgRmFjdG9yZXMgTGF0ZW50ZXMuKioNCg0KQ292YXJpYW56YXMgZW50cmUgbG9zIGZhY3RvcmVzLg0KDQokJFxwc2lfezEyfSwgXHF1YWQgIFxwc2lfezEzfSwgXHF1YWQgIFxwc2lfezIzfSQkDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgUmVzdW1lbiBncsOhZmljbyBkZSBsb3MgdGlwb3MgZGUgcGFyw6FtZXRyb3MNCg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuNCwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlRpcG9zIGRlIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8gQ0ZBKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW40Yi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMgRXN0aW1hY2lvbmVzIG1vc3RyYWRhcyBlbiBgc3VtbWFyeSgpYCB5IGVuIGxvcyBkaWFncmFtYXMgU0VNDQoNCiMjIyMgQ2FyZ2EgZmFjdG9yaWFsIG5vIGVzdGFuZGFyaXphZGEgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KRW4gdW4gbW9kZWxvIENGQS9TRU0sIGxhICoqY2FyZ2EgZmFjdG9yaWFsIGVzdGFuZGFyaXphZGEqKiBzZSBkZWZpbmUgY29tbzoNCg0KXFsNClxsYW1iZGFfe1x0ZXh0e3N0ZH19ID0gXGxhbWJkYV97XHRleHR7ZXN0fX0gXGNkb3QgXGZyYWN7XHNpZ21hX3tcZXRhfX17XHNpZ21hX3h9LA0KXF0NCg0KZG9uZGU6DQoNCi0gXChcbGFtYmRhX3tcdGV4dHtlc3R9fVwpIGVzIGxhIGNhcmdhIG5vIGVzdGFuZGFyaXphZGEsIA0KDQotIFwoXHNpZ21hX3tcZXRhfVwpIGVzIGxhIGRlc3ZpYWNpw7NuIGVzdMOhbmRhciBkZWwgZmFjdG9yIGxhdGVudGUgeSANCg0KLSBcKFxzaWdtYV94XCkgZXMgbGEgZGVzdmlhY2nDs24gZXN0w6FuZGFyIGRlbCBpbmRpY2Fkb3Igb2JzZXJ2YWRvLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMjIE5vdGEgaW1wb3J0YW50ZSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpQb3IgZGVmZWN0bywgbGEgZnVuY2nDs24gYHN1bW1hcnkoKWAgZGUgYGxhdmFhbmAgcHJlc2VudGEgKiplc3RpbWFjaW9uZXMgbm8gZXN0YW5kYXJpemFkYXMqKiAoY29sdW1uYSBgRXN0aW1hdGVgKS4gRXN0YXMgZXN0aW1hY2lvbmVzIHJlZmxlamFuIGRpcmVjdGFtZW50ZSBlbCBlc3F1ZW1hIGRlICppZGVudGlmaWNhY2nDs24gZGVsIG1vZGVsbyosIGVuIGVsIGN1YWwgdW5hIGNhcmdhIGZhY3RvcmlhbCBwb3IgZmFjdG9yIHN1ZWxlIGZpamFyc2UgZW4gMSAocG9yIGVqZW1wbG8sIGB4MSA9IDFgLCBgeDQgPSAxYCwgYHg3ID0gMWApIGNvbiBlbCBmaW4gZGUgZGVmaW5pciBsYSBlc2NhbGEgZGUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcy4NCg0KRW4gY29udHJhc3RlLCBjdWFuZG8gc2UgdXRpbGl6YSBgc2VtUGF0aHMoLi4uLCB3aGF0ID0gInN0ZCIsIHdoYXRMYWJlbHMgPSAic3RkIilgIGRlbCBwYXF1ZXRlIGBzZW1QbG90YCwgZWwgZGlhZ3JhbWEgU0VNIG11ZXN0cmEgKipjb2VmaWNpZW50ZXMgZXN0YW5kYXJpemFkb3MqKi4gRW4gZXN0ZSBjYXNvLCBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIGZpamFkYXMgYSAxIGVuIGxhIG3DqXRyaWNhIG9yaWdpbmFsICoqbm8gcGVybWFuZWNlbiBpZ3VhbGVzIGEgMSoqLCB5YSBxdWUgbGEgZXN0YW5kYXJpemFjacOzbiB0cmFuc2Zvcm1hIGxvcyBwYXLDoW1ldHJvcy4gIFBvciB0YW50bywgYXVuIGN1YW5kbyBcKFxsYW1iZGFfe1x0ZXh0e2VzdH19ID0gMVwpLCBzaSBcKFxzaWdtYV97XGV0YX0gXG5lcSBcc2lnbWFfeFwpLCBzZSBvYnRpZW5lIG5lY2VzYXJpYW1lbnRlIHF1ZQ0KDQpcWw0KXGxhbWJkYV97XHRleHR7c3RkfX0gXG5lcSAxLg0KXF0NCg0KRXN0byBleHBsaWNhIHBvciBxdcOpIGVuIGxhIHNhbGlkYSBkZSBgc3VtbWFyeSgpYCBzZSB2YW4gYSBvYnNlcnZhciBjYXJnYXMgaWd1YWxlcyBhIDEsIG1pZW50cmFzIHF1ZSBlbiBsb3MgZGlhZ3JhbWFzIGVzdGFuZGFyaXphZG9zIGRpY2hhcyBjYXJnYXMgdmFuIHRvbWFyIHZhbG9yZXMgZGlzdGludG9zIChzaSBubyBzZSBlc2NyaWJlbiBsb3MgYXJndW1lbnRvcyBhcHJvcGlhZG9zKS4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMjIFJlZ2xhIHByw6FjdGljYSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQotIEVzdGltYWNpb25lcyBubyBlc3RhbmRhcml6YWRhcyAkXGxhbWJkYV97XHRleHR7ZXN0fX0kOiBgc3VtbWFyeSgpYCAgIFwoXExvbmdsZWZ0cmlnaHRhcnJvd1wpIGBzZW1QYXRocyguLi4sIHdoYXQgPSAiZXN0IilgDQoNCi0gRXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzICRcbGFtYmRhX3tcdGV4dHtzdGR9fSQ6ICBgc3VtbWFyeSguLi4sIHN0YW5kYXJkaXplZCA9IFRSVUUpYCAgXChcTG9uZ2xlZnRyaWdodGFycm93XCkgYHNlbVBhdGhzKC4uLiwgd2hhdCA9ICJzdGQiKWANCg0KRW4gZXN0ZSBjYXDDrXR1bG8sIGxvcyBkaWFncmFtYXMgU0VNIHNlIHByZXNlbnRhbiB1dGlsaXphbmRvICoqZXN0aW1hY2lvbmVzIG5vIGVzdGFuZGFyaXphZGFzKiosIGRlIG1vZG8gcXVlIGxhcyBjYXJnYXMgZmlqYWRhcyBlbiBcKFxsYW1iZGEgPSAxXCkgc2UgbWFudGVuZ2FuIGV4cGzDrWNpdGFzIHkgcmVmbGVqZW4gY29ycmVjdGFtZW50ZSBlbCBlc3F1ZW1hIGRlIGlkZW50aWZpY2FjacOzbiBkZWwgbW9kZWxvLg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXN0aW1hY2nDs24gZGVsIG1vZGVsbyBjb24gYGxhdmFhbjo6Y2ZhYA0KDQojIyMgT3V0cHV0IGRlIGBjZmFgOiBlamVjdWNpw7NuDQoNClBvZGVtb3MgYWp1c3RhciBlbCBtb2RlbG8gY29tbyBzaWd1ZTogDQoNCmBgYHtyfQ0KQ0ZBIDwtIGxhdmFhbjo6Y2ZhKG1vZGVsbywgZGF0YT1kYXQpDQpDRkENCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIE91dHB1dCBkZSBgY2ZhYDogZ3LDoWZpY28gZGVsIG1vZGVsbyBjb24gUg0KDQoqKjEuIEVsIGRpYWdyYW1hIGLDoXNpY28uKioNCg0KYGBge3J9DQpzZW1QYXRocyhDRkEsIA0KICAgICAgICAgd2hhdCA9ICJwYXRoIiwgICAgI011ZXN0cmEgbGFzIHJ1dGFzIGNvbiBjYXJnYXMsIHJlZ3Jlc2lvbmVzLCBjb3ZhcmlhbnphcyAgICAgDQogICAgICAgICAjd2hhdCA9ICJzdGQiLCAgICAjTXVlc3RyYSBsYXMgZXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzIGRlIGxhcyBydXRhcyANCiAgICAgICAgICN3aGF0ID0gImVzdCIsICAgICNNdWVzdHJhIGxhcyBlc3RpbWFjaW9uZXMgbm8gZXN0YW5kYXJpemFkYXMgZGUgbGFzIHJ1dGFzIA0KICAgICAgICAgI3doYXQgPSAiY29sIiwgICAgI011ZXN0cmEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyBkZSB2YXIuIG9ic2VydmFkYXMNCiAgICAgICAgICN3aGF0ID0gIm1vZCIsICAgICNNdWVzdHJhIGNhbWlubyBhZGljaW9uYWwgcXVlIHBvZHLDrWEgbWVqb3JhciBhanVzdGUgZGVsIG1vZGVsbw0KICAgICAgICAgI3doYXQgPSAibW9kZWwiLCAgI011ZXN0cmEgdW5hIHJlcHJlc2VudGFjacOzbiBncmFsIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImFsbCIsICAgICNNdWVzdHJhIHRvZG9zIGVsZW1lbnRvcyBwb3NpYmxlcyAocnV0YXMgeSBlc3RpbWFjaW9uZXMpDQogICAgICAgICAjd2hhdCA9ICJwYXIiLCAgICAjTXVlc3RyYSB0b2RvcyBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImVxIiwgICAgICNNdWVzdHJhIGxhcyBlY3VhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgZGVsIG1vZGVsbyANCiAgICAgICAgIA0KICAgICAgICAgbGF5b3V0ID0gImNpcmNsZSIsICAgI0Rpc3BvbmUgbm9kb3MgZW4gY8OtcmN1bG8gKHNvbG8gcGVybWl0aWRvIHNpIHJvdGF0aW9uPSAxIG8gMykNCiAgICAgICAgIA0KICAgICAgICAgdGl0bGUgPSBGQUxTRSwgICAgICAgI05vIG11ZXN0cmEgZWwgdMOtdHVsbyBkZWwgZ3LDoWZpY28NCiAgICAgICAgIA0KICAgICAgICAgZWRnZS5jb2xvciA9ICJyZWQiLCAgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBsb3MgYm9yZGVzIChhcmlzdGFzKSBlbiBuZWdybw0KICAgICAgICAgZWRnZS5sYWJlbC5jZXggPSAxICAgI1RhbWHDsW8gZGUgbGFzIGNhcmdhcyBmYWN0b3JpYWxlcw0KICAgICAgICAgKQ0KYGBgDQoNCiAqKjIuIFNlIHB1ZWRlIHZpc3VhbGl6YXIgZWwgbW9kZWxvICBjb24gbm9kb3MgcGVyc29uYWxpemFkb3MuKioNCg0KYGBge3J9DQpzZW1QYXRocyhDRkEsIA0KICAgICAgICB3aGF0ID0gInBhdGgiLCAgICAjTXVlc3RyYSBsYXMgcnV0YXMgY29uIGNhcmdhcywgcmVncmVzaW9uZXMsIGNvdmFyaWFuemFzICAgICANCiAgICAgICAgI3doYXQgPSAic3RkIiwgICAgI011ZXN0cmEgbGFzIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcyBkZSBsYXMgcnV0YXMgDQogICAgICAgICN3aGF0ID0gImVzdCIsICAgICNNdWVzdHJhIGxhcyBlc3RpbWFjaW9uZXMgbm8gZXN0YW5kYXJpemFkYXMgZGUgbGFzIHJ1dGFzDQogICAgICAgICN3aGF0ID0gImNvbCIsICAgICNNdWVzdHJhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgZGUgdmFyLiBvYnNlcnZhZGFzDQogICAgICAgICN3aGF0ID0gIm1vZCIsICAgICNNdWVzdHJhIGNhbWlubyBhZGljaW9uYWwgcXVlIHBvZHLDrWEgbWVqb3JhciBhanVzdGUgZGVsIG1vZGVsbw0KICAgICAgICAjd2hhdCA9ICJtb2RlbCIsICAjTXVlc3RyYSB1bmEgcmVwcmVzZW50YWNpw7NuIGdyYWwgZGVsIG1vZGVsbw0KICAgICAgICAjd2hhdCA9ICJhbGwiLCAgICAjTXVlc3RyYSB0b2RvcyBlbGVtZW50b3MgcG9zaWJsZXMgKHJ1dGFzIHkgZXN0aW1hY2lvbmVzKQ0KICAgICAgICAjd2hhdCA9ICJwYXIiLCAgICAjTXVlc3RyYSB0b2RvcyBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8NCiAgICAgICAgI3doYXQgPSAiZXEiLCAgICAgI011ZXN0cmEgbGFzIGVjdWFjaW9uZXMgZXN0cnVjdHVyYWxlcyBkZWwgbW9kZWxvDQogICAgICAgIA0KICAgICAgICBzdHlsZSA9ICJsaXNyZWwiLCAjVXNhIHVuIGVzdGlsbyBwcmVkZWZpbmlkbyBzaW1pbGFyIGFsIGVzdGlsbyBMSVNSRUwNCiAgICAgICAgICNzdHlsZSA9ICJyYW0iOiAgICNFc3RpbG8gZGUgUkFNIChSZXRpY3VsYXIgQWN0aW9uIE1vZGVsKSwgY29tw7puIGVuIGdyw6FmaWNvcyBTRU0NCiAgICAgICAgICNzdHlsZSA9ICJteCI6ICAgICNFc3RpbG8gZGUgTXgsICBoZXJyYW1pZW50YSBkZSBTRU0NCiAgICAgICAgICNzdHlsZSA9ICJlcXMiOiAgICNFc3RpbG8gc2ltaWxhciBhbCBzb2Z0d2FyZSBFUVMNCg0KICAgICAgICAgI2xheW91dCA9ICJ0cmVlIiwgICAjRGlzcG9uZSBub2RvcyBlbiB1bmEgZXN0cnVjdHVyYSBqZXLDoXJxdWljYSBzaW1pbGFyIGEgdW4gw6FyYm9sDQogICAgICAgICAjbGF5b3V0PSJ0cmVlMiIsICAgICNQYXJlY2lkYSBhIGxhIGFudGVyaW9yDQogICAgICAgICBsYXlvdXQ9ImNpcmNsZSIsICAgICNEaXNwb25lIG5vZG9zIGVuIGPDrXJjdWxvIChzb2xvIHBlcm1pdGlkbyBzaSByb3RhdGlvbj0gMSBvIDMpDQogICAgICAgICAjbGF5b3V0ID0gInNwcmluZyIsICNNaW5pbWl6YSBmdWVyemFzIGRlIHJlcHVsc2nDs24geSBhdHJhY2Npw7NuIGVudHJlIG5vZG9zDQogICAgICAgICAjbGF5b3V0ID0gImxnbCIsICAgICNBbGdvcml0bW8gIkxhcmdlIEdyYXBoIExheW91dCIgKMO6dGlsIHBhcmEgZ3LDoWZpY29zIGdyYW5kZXMpDQogICAgICAgICAjbGF5b3V0ID0gImthbWFkYSIsICAgICAgI0FsZ29yaXQuIEthbWFkYS1LYXdhaSBwYXJhIGRpc3Bvc2ljacOzbiBiYXNhZGEgZW4gZW5lcmfDrWENCiAgICAgICAgICNsYXlvdXQgPSAiZnJ1Y2h0ZXJtYW4iLCAjQWxnb3JpdG1vIEZydWNodGVybWFuLVJlaW5nb2xkIChkaXNwb3NpY2nDs24gcG9yIGZ1ZXJ6YXMpDQogICAgICAgIA0KICAgICAgICB0aXRsZSA9IEZBTFNFLCAgICAgICAgICAgICAjTm8gbXVlc3RyYSBlbCB0w610dWxvIGRlbCBncsOhZmljbw0KICAgICAgICANCiAgICAgICAgZWRnZS5jb2xvciA9ICJibGFjayIsICAgICAgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBsb3MgYm9yZGVzIChhcmlzdGFzKSBlbiBuZWdybw0KICAgICAgICBlZGdlLmxhYmVsLmNleCA9IDEsICAgICAgICAjVGFtYcOxbyBkZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzDQogICAgICAgIA0KICAgICAgICAjbm9kZS5jb2xvciA9ICJibHVlIiwgICAgICAgI0VzdGFibGVjZSBlbCBjb2xvciBkZSBmb25kbyBkZSBsb3Mgbm9kb3MNCiAgICAgICAgbm9kZS5sYWJlbC5jZXggPSAxLjUsICAgICAgI1RhbWHDsW8gZGVsIHRleHRvIGRlIGxhcyBldGlxdWV0YXMgZGVudHJvIGRlIGxvcyBub2Rvcy4NCiAgICAgICAgI25vZGUuc2hhcGUgPSAicmVjdGFuZ2xlIiwgI0VzdGFibGVjZSBsYSBmb3JtYSBkZSBsb3Mgbm9kb3MgY29tbyByZWN0w6FuZ3Vsb3MNCiAgICAgICAgDQogICAgICAgIGN1cnZlUGl2b3Q9VFJVRSwgICAgICAgICAgICNDb25leGlvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcw0KICAgICAgICBsYWJlbC5wcm9wID0gMSwNCiAgICAgICAgDQogICAgICAgIGNvbG9yID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgIGxhdCA9ICJvcmFuZ2UiLCAgICAjQ29sb3IgZGUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcw0KICAgICAgICAgICAgICAgICAgICAgbWFuID0gImxpZ2h0Z3JlZW4iICNDb2xvciBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMNCiAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgKQ0KYGBgDQoNCg0KKiozLiBTZSBwdWVkZSB2aXN1YWxpemFyIGVsIG1vZGVsbyAgY29uIG90cmFzIG9wY2lvbmVzIHBlcnNvbmFsaXphZGFzLioqDQoNCg0KDQoNCmBgYHtyLCAgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCnNlbVBhdGhzKENGQSwNCiAgICAgICAgICN3aGF0ID0gInBhdGgiLCAgICNNdWVzdHJhIGxhcyBydXRhcyBjb24gY2FyZ2FzLCByZWdyZXNpb25lcywgY292YXJpYW56YXMgICAgIA0KICAgICAgICAgI3doYXQgPSAic3RkIiwgICAgI011ZXN0cmEgbGFzIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcyBkZSBsYXMgcnV0YXMgDQogICAgICAgICAjd2hhdCA9ICJlc3QiLCAgICAjTXVlc3RyYSBsYXMgZXN0aW1hY2lvbmVzIG5vIGVzdGFuZGFyaXphZGFzIGRlIGxhcyBydXRhcw0KICAgICAgICAgI3doYXQgPSAiY29sIiwgICAgI011ZXN0cmEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyBkZSB2YXIuIG9ic2VydmFkYXMNCiAgICAgICAgICN3aGF0ID0gIm1vZCIsICAgICNNdWVzdHJhIGNhbWlubyBhZGljaW9uYWwgcXVlIHBvZHLDrWEgbWVqb3JhciBhanVzdGUgZGVsIG1vZGVsbw0KICAgICAgICAgI3doYXQgPSAibW9kZWwiLCAgI011ZXN0cmEgdW5hIHJlcHJlc2VudGFjacOzbiBncmFsIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImFsbCIsICAgICNNdWVzdHJhIHRvZG9zIGVsZW1lbnRvcyBwb3NpYmxlcyAocnV0YXMgeSBlc3RpbWFjaW9uZXMpDQogICAgICAgICAjd2hhdCA9ICJwYXIiLCAgICAjTXVlc3RyYSB0b2RvcyBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8NCiAgICAgICAgIHdoYXQgPSAiZXEiLCAgICAgICNNdWVzdHJhIGxhcyBlY3VhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgZGVsIG1vZGVsbyANCiAgICAgICAgIA0KICAgICAgICAgd2hhdExhYmVscyA9ImVzdCIsICAgI011ZXN0cmEgZXN0aW1hY2lvbmVzIG5vIGVzdGFuZGFyaXphZGFzIGRlIGxvcyBwYXLDoW1ldHJvcw0KICAgICAgICAgI3doYXRMYWJlbHMgPSJzdGQiOiAgI011ZXN0cmEgZXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzIGRlIGxvcyBwYXLDoW1ldHJvcw0KICAgICAgICAgI3doYXRMYWJlbHMgPSJuYW1lIjogI011ZXN0cmEgbG9zIG5vbWJyZXMgZGUgbGFzIHJlbGFjaW9uZXMgbyBwYXLDoW1ldHJvcw0KICAgICAgICAgI3doYXRMYWJlbHMgPSJub25lIjogI05vIG11ZXN0cmEgbmluZ3VuYSBldGlxdWV0YSBlbiBsYXMgYXJpc3Rhcw0KICAgICAgICAgI3doYXRMYWJlbHMgPSJlcSI6ICAgI011ZXN0cmEgZXRpcXVldGFzIGRlIGVjdWFjaW9uZXMgKHVzdWFsbWVudGUgZW4gU0VNKS4NCiAgICAgICAgICN3aGF0TGFiZWxzID0iYm90aCI6ICNNdWVzdHJhIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcyB5IG5vIGVzdGFuZGFyaXphZGFzDQogICAgICAgICAgDQogICAgICAgICBzdHlsZSA9ICJsaXNyZWwiLCAjVXNhIHVuIGVzdGlsbyBwcmVkZWZpbmlkbyBzaW1pbGFyIGFsIGVzdGlsbyBMSVNSRUwNCiAgICAgICAgICNzdHlsZSA9ICJyYW0iOiAgICNFc3RpbG8gZGUgUkFNIChSZXRpY3VsYXIgQWN0aW9uIE1vZGVsKSwgY29tw7puIGVuIGdyw6FmaWNvcyBTRU0NCiAgICAgICAgICNzdHlsZSA9ICJteCI6ICAgICNFc3RpbG8gZGUgTXgsICBoZXJyYW1pZW50YSBkZSBTRU0NCiAgICAgICAgICNzdHlsZSA9ICJlcXMiOiAgICNFc3RpbG8gc2ltaWxhciBhbCBzb2Z0d2FyZSBFUVMNCg0KICAgICAgICAgI2xheW91dCA9ICJ0cmVlIiwgICAjRGlzcG9uZSBub2RvcyBlbiB1bmEgZXN0cnVjdHVyYSBqZXLDoXJxdWljYSBzaW1pbGFyIGEgdW4gw6FyYm9sDQogICAgICAgICBsYXlvdXQ9InRyZWUyIiwgICAgICNQYXJlY2lkYSBhIGxhIGFudGVyaW9yDQogICAgICAgICAjbGF5b3V0PSJjaXJjbGUiLCAgICNEaXNwb25lIG5vZG9zIGVuIGPDrXJjdWxvIChzb2xvIHBlcm1pdGlkbyBzaSByb3RhdGlvbj0gMSBvIDMpDQogICAgICAgICAjbGF5b3V0ID0gInNwcmluZyIsICNNaW5pbWl6YSBmdWVyemFzIGRlIHJlcHVsc2nDs24geSBhdHJhY2Npw7NuIGVudHJlIG5vZG9zDQogICAgICAgICAjbGF5b3V0ID0gImxnbCIsICAgICNBbGdvcml0LiAiTGFyZ2UgR3JhcGggTGF5b3V0IiAow7p0aWwgcGFyYSBncsOhZmljb3MgZ3JhbmRlcykNCiAgICAgICAgICNsYXlvdXQgPSAia2FtYWRhIiwgICAgICAjQWxnb3JpdC4gS2FtYWRhLUthd2FpIHBhcmEgZGlzcG9zaWNpw7NuIGJhc2FkYSBlbiBlbmVyZ8OtYQ0KICAgICAgICAgI2xheW91dCA9ICJmcnVjaHRlcm1hbiIsICNBbGdvcml0bW8gRnJ1Y2h0ZXJtYW4tUmVpbmdvbGQgKGRpc3Bvc2ljacOzbiBwb3IgZnVlcnphcykNCg0KICAgICAgICAgI3JvdGF0aW9uID0gMSwgI1JvdGFjacOzbiBkZSB0b2RvIGVsIGRpYWdyYW1hDQogICAgICAgICByb3RhdGlvbj0yLCANCiAgICAgICAgICNyb3RhdGlvbj0zLA0KICAgICAgICAgDQogICAgICAgICBuQ2hhck5vZGVzID0gMCwgIzA9YWp1c3RhciBhbCBuw7ptZXJvIG3DoXhpbW8gZGUgY2FyYWN0ZXJlcyBkZW50cm8gZGUgbGFzIGxhdGVudGVzDQogICAgICAgICBzaXplTWFuID0gOCwgICAgI1RhbWHDsW8gZGUgbG9zIG5vZG9zIHF1ZSByZXByZXNlbnRhbiB2YXJpYWJsZXMgbWFuaWZpZXN0YXMNCiAgICAgICAgIHNpemVMYXQgPSA5LCAgICAjVGFtYcOxbyBkZSBsb3Mgbm9kb3MgcXVlIHJlcHJlc2VudGFuIHZhcmlhYmxlcyBsYXRlbnRlcw0KICAgICAgICAgc2l6ZUludCA9IDEsICAgICNUYW1hw7FvIGRlIGxvcyBub2RvcyBxdWUgcmVwcmVzZW50YW4gdmFyaWFibGVzIGludGVyaW9yZXMNCiAgICAgICAgIG5DaGFyRWRnZXMgPSAzLCAjTsO6bWVybyBtw6F4aW1vIGRlIGNhcmFjdGVyZXMgcGFyYSBldGlxdWV0YXMgZGUgY2FyZ2FzIGZhY3RvcmlhbGVzDQogICAgICAgICANCiAgICAgICAgIGVkZ2UubGFiZWwuY2V4ID0gMSwgICAgICAjVGFtYcOxbyBkZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzDQogICAgICAgICANCiAgICAgICAgICNmcmVlU3R5bGUgPSAiYmx1ZSIsICAgICAjUGFyw6FtZXRyb3MgZmlqb3Mgc29uIGF6dWxlcw0KICAgICAgICAgZml4ZWRTdHlsZSA9IGMoInJlZCIsMyksICNQYXLDoW1ldHJvcyBmaWpvcyBzb24gcm9qb3MgeSBkZSB0YW1hw7FvIDMNCiAgIA0KICAgICAgICAgI2N1cnZlUGl2b3Q9VFJVRSwgICNDb25leGlvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhDQogICAgICAgICBpbnRlcmNlcHRzPVRSVUUsICAgI011ZXN0cmEgdSBvY3VsdGEgbG9zIG5vZG9zIGRlIGludGVyY2VwdG9zIChtZWRpYXMpIGRlbCBtb2RlbG8NCiAgICAgICAgIHJlc2lkdWFscz1GQUxTRSwgICAjTXVlc3RyYSBsYXMgZmxlY2hhcyBhc29jaWFkYXMgYSBsb3MgdMOpcm1pbm9zIHJlc2lkdWFsZXMgKGVycm9yZXMpDQogICAgICAgICBleG9Db3Y9RkFMU0UsICAgICAgI011ZXN0cmEgbGFzIGNvdmFyaWFuemFzIGVudHJlIHZhcmlhYmxlcyBleMOzZ2VuYXMgKGxhdGVudGVzLCBldGMuKQ0KICAgICAgICAgDQogICAgICAgICBjb2xvciA9IGxpc3QoDQogICAgICAgICAgIGxhdCA9ICJvcmFuZ2UiLCAgICAjQ29sb3IgZGUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcw0KICAgICAgICAgICBtYW4gPSAibGlnaHRncmVlbiIgI0NvbG9yIGRlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcw0KICAgICAgICAgICApIA0KICAgICAgICAgKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdXRwdXQgZGUgYGNmYWA6IG9ic2VydmFjaW9uZXMNCg0KMS4gTGEgZnVuY2nDs24gYGNmYWAgZXMgdW5hIGZ1bmNpw7NuIGVzcGVjw61maWNhIHBhcmEgZXN0YWJsZWNlciBtb2RlbG9zIGRlIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3Jpby4gDQoNCjIuIEVsIHByaW1lciBhcmd1bWVudG8gZXMgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpby4gDQoNCjMuIEVsIHNlZ3VuZG8gYXJndW1lbnRvIGVzIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHF1ZSBjb250aWVuZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMuDQoNCjQuIExvcyBpbnRlcmNlcHRvcyAkXHRhdSQgZGUgbG9zIGZhY3RvcmVzIHJlcHJlc2VudGFuIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIChgeDFgLCBgeDJgLCBgeDNgLCBgeDRgLCBgeDVgLCBgeDZgLCBgeDdgLCBgeDhgLCBgeDlgKSBjdWFuZG8gbG9zIGZhY3RvcmVzIGxhdGVudGVzIChgVmlzdWFsYCwgIGBUZXh0dWFsYCwgIGBTcGVlZGApIHRpZW5lbiB1biB2YWxvciBkZSBjZXJvLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYGNmYWA6IHByaW1lcmEgcGFydGUNCg0KIyMjIEdyw6FmaWNhIGRlIGxhIHByaW1lcmEgcGFydGUNCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW41KSBzZSByZXNhbHRhIGxhIHByaW1lcmEgcGFydGUgZGVsIG91dHB1dCBkZSBgbGF2YWFuLiANCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjUsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQcmltZXJhIHBhcnRlIGRlbCBvdXRwdXQgZGUgYGxhdmFhbmAgKGluZm9ybWFjacOzbiBnZW5lcmFsKSoqIiAsIG91dC53aWR0aCA9ICI3MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuNS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbmZvcm1hY2nDs24gZ2VuZXJhbCBkZWwgb3V0cHV0DQoNCioqMS4gRWwgbW9kZWxvIGZpbmFsaXrDsyBub3JtYWxtZW50ZSBkZXNwdcOpcyBkZSAzNSBpdGVyYWNpb25lcy4qKg0KDQpFc3RlIG1lbnNhamUgaW5kaWNhIHF1ZSBlbCBwcm9jZXNvIGRlIGVzdGltYWNpw7NuIGRlbCBtb2RlbG8gZmluYWxpesOzIGNvcnJlY3RhbWVudGUgZGVzcHXDqXMgZGUgMzUgaXRlcmFjaW9uZXMuIEVzdG8gc2lnbmlmaWNhIHF1ZSBlbCBhbGdvcml0bW8gZGUgb3B0aW1pemFjacOzbiBhbGNhbnrDsyB1bmEgc29sdWNpw7NuIGVzdGFibGUgZGVudHJvIGRlbCBuw7ptZXJvIGVzcGVjaWZpY2FkbyBkZSBpdGVyYWNpb25lcy4NCg0KKioyLiBFbCBlc3RpbWFkb3IgdXRpbGl6YWRvIGZ1ZSBlbCBtw6F4aW1vIHZlcm9zaW1pbGl0dWQgKE1MKS4qKg0KDQpgTUxgIHNpZ25pZmljYSAqTWF4aW11bSBMaWtlbGlob29kKiAoKk3DoXhpbWEgVmVyb3NpbWlsaXR1ZCopLiBFcyBlbCBlc3RpbWFkb3IgdXRpbGl6YWRvIHBhcmEgYWp1c3RhciBlbCBtb2RlbG8uIEVsIGVzdGltYWRvciBkZSBtw6F4aW1hIHZlcm9zaW1pbGl0dWQgZXMgdW5vIGRlIGxvcyBtw6l0b2RvcyBtw6FzIGNvbXVuZXMgcGFyYSBlc3RpbWFyIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvIGVuIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbywgeWEgcXVlIHNlIGJhc2EgZW4gbGEgc3Vwb3NpY2nDs24gZGUgcXVlIGxvcyBkYXRvcyBzaWd1ZW4gdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4NCg0KDQoqKjMuIEVsIG3DqXRvZG8gZGUgb3B0aW1pemFjacOzbiBmdWUgTkxNSU5CLioqDQoNCiAgKyBMYSBhYnJldmlhdHVyYSBgTkxNSU5CYCBzZSByZWZpZXJlIGEgIk5vbmxpbmVhciBNSU5pbWl6YXRpb24gdXNpbmcgQm91bmRzIiwgcXVlIHNpZ25pZmljYSAiTWluaW1pemFjacOzbiBubyBsaW5lYWwgdXNhbmRvIGzDrW1pdGVzIi4gDQogIA0KICArIEVzcGVjw61maWNhbWVudGUsIGBOTE1JTkJgIHNlIHJlZmllcmUgYWwgbcOpdG9kbyBkZSBvcHRpbWl6YWNpw7NuIHVzYWRvIHBhcmEgZW5jb250cmFyIGxvcyB2YWxvcmVzIMOzcHRpbW9zIGRlIGxvcyBwYXLDoW1ldHJvcyBkZWwgbW9kZWxvLiANCiAgDQogICsgYE5MTUlOQmAgZXMgdW4gYWxnb3JpdG1vIGRlIG9wdGltaXphY2nDs24gcXVlIGVzIHJvYnVzdG8geSBlZmljaWVudGUsIGVzcGVjaWFsbWVudGUgcGFyYSBwcm9ibGVtYXMgIGRlIG1pbmltaXphY2nDs24gbm8gbGluZWFscXVlIHRpZW5lbiByZXN0cmljY2lvbmVzIGVuIGxvcyBwYXLDoW1ldHJvcyBvIHNvbiBkZSBuYXR1cmFsZXphIG5vIGxpbmVhbC4NCiAgDQogICsgRW4gc2VjY2lvbmVzIHNpZ3VpZW50ZXMsIHNlIGRlc2NyaWJpcsOhbiBicmV2ZW1lbnRlIG90cm9zIG3DqXRvZG9zIGFsdGVybmF0aXZvcyBkZSBvcHRpbWl6YWNpw7NuLiANCg0KKio0LiBFbCBtb2RlbG8gdGllbmUgMjEgcGFyw6FtZXRyb3MuKioNCg0KRXN0YSBsw61uZWEgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gdGllbmUgdW4gdG90YWwgZGUgMjEgcGFyw6FtZXRyb3MgYSBlc3RpbWFyLiBFc3RvIGluY2x1eWUgY2FyZ2FzIGZhY3RvcmlhbGVzLCB2YXJpYW56YXMsIGNvdmFyaWFuemFzIHkgdMOpcm1pbm9zIGRlIGVycm9yLCBlbnRyZSBvdHJvcy4gRW4gc2VjY2lvbmVzIHNpZ3VpZW50ZXMgc2UgdmEgYSBkZXRhbGxhciBtw6FzIGFsIHJlc3BlY3RvLiANCg0KKio1LiBTZSB1dGlsaXphcm9uIDMwMSBvYnNlcnZhY2lvbmVzIGVuIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLioqDQoNCkVzdGEgc2VjY2nDs24gbXVlc3RyYSBxdWUgc2UgdXRpbGl6YXJvbiAzMDEgb2JzZXJ2YWNpb25lcyAobyBjYXNvcykgcGFyYSBhanVzdGFyIGVsIG1vZGVsby4gRXMgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhIGRlIGRhdG9zLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgY2ZhYDogZXN0aW1hZG9yZXMNCg0KIyMjIE90cm9zIGVzdGltYWRvcmVzIGVuIGBsYXZhYW5gIChhcGFydGUgZGUgYE1MYCkNCg0KKioxLiBgTUxSYCAoTWF4aW11bSBMaWtlbGlob29kIHdpdGggUm9idXN0IFN0YW5kYXJkIEVycm9ycykuKioNCiAgDQogICsgUHJvcG9yY2lvbmEgZXJyb3JlcyBlc3TDoW5kYXIgcm9idXN0b3MgeSB1bmEgcHJ1ZWJhIGNoaS1jdWFkcmFkbyByb2J1c3RhLg0KICANCiAgKyBFcyDDunRpbCBjdWFuZG8gbG9zIGRhdG9zIG5vIGN1bXBsZW4gY29uIGxhIHN1cG9zaWNpw7NuIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLg0KDQoqKjIuIGBNTE1gIChNYXhpbXVtIExpa2VsaWhvb2Qgd2l0aCBSb2J1c3QgU3RhbmRhcmQgRXJyb3JzKS4qKg0KICANCiAgKyBTaW1pbGFyIGEgTUxSIHBlcm8gdXNhIGxhIGNvcnJlY2Npw7NuIGRlIFNhdG9ycmEtQmVudGxlciBwYXJhIGVsIGVzdGFkw61zdGljbyBjaGktY3VhZHJhZG8uDQogIA0KICArIEVzIGFkZWN1YWRvIHBhcmEgZGF0b3MgcXVlIG5vIHNvbiBub3JtYWxlcyBwZXJvIHF1ZSB0aWVuZW4gZGVzdmlhY2lvbmVzIGxldmVzIGRlIGxhIG5vcm1hbGlkYWQuDQoNCioqMy4gYE1MRmAgKE1heGltdW0gTGlrZWxpaG9vZCB3aXRoIFJvYnVzdCBTdGFuZGFyZCBFcnJvcnMgYW5kIGEgU2NhbGluZyBGYWN0b3IpLioqDQoNClNpbWlsYXIgYSBNTFIgcGVybyBpbmNsdXllIHVuIGZhY3RvciBkZSBlc2NhbGFkbyBhZGljaW9uYWwgcGFyYSBhanVzdGFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhci4NCg0KDQoqKjQuIGBXTFNgIChXZWlnaHRlZCBMZWFzdCBTcXVhcmVzKS4qKg0KDQpVdGlsaXphIGxhcyBtYXRyaWNlcyBkZSBjb3ZhcmlhbnphIHkgYXNpbWV0csOtYSBwYXJhIGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zLg0KRXMgZXNwZWNpYWxtZW50ZSDDunRpbCBwYXJhIGRhdG9zIGNhdGVnw7NyaWNvcyB5IG9yZGluYWxlcy4NCg0KDQoqKjUuIGBXTFNNYCAoV2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcyBNZWFuIGFuZCBWYXJpYW5jZSBhZGp1c3RlZCkuKioNCiAgDQogICsgVW5hIHZhcmlhbnRlIGRlbCBXTFMgcXVlIGFqdXN0YSB0YW50byBsYSBtZWRpYSBjb21vIGxhIHZhcmlhbnphLCBwcm9wb3JjaW9uYW5kbyB1bmEgY29ycmVjY2nDs24gcm9idXN0YS4NCiAgDQogICsgVGFtYmnDqW4gZXMgYWRlY3VhZG8gcGFyYSBkYXRvcyBjYXRlZ8Ozcmljb3MgeSBvcmRpbmFsZXMuDQoNCioqNi4gYFdMU01WYCAoV2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcyBNZWFuIGFuZCBWYXJpYW5jZSBhZGp1c3RlZCkuKioNCiAgDQogICsgU2ltaWxhciBhIGBXTFNNYCBwZXJvIGNvbiB1bmEgY29ycmVjY2nDs24gYWRpY2lvbmFsIHBhcmEgbGEgbWVkaWEgeSBsYSB2YXJpYW56YS4NCiAgDQogICsgRXMgYW1wbGlhbWVudGUgdXRpbGl6YWRvIHBhcmEgbW9kZWxvcyBjb24gZGF0b3MgY2F0ZWfDs3JpY29zLg0KDQoNCioqNy4gYFVMU2AgKFVud2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcykuKioNCiAgDQogICsgTWluaW1pemEgbGFzIGRpc2NyZXBhbmNpYXMgc2luIHBvbmRlcmFyIGxhcyBvYnNlcnZhY2lvbmVzLg0KICANCiAgKyBQdWVkZSBzZXIgw7p0aWwgZW4gY2Fzb3MgZG9uZGUgc2UgcHJlZmllcmVuIG3DqXRvZG9zIG5vIHBvbmRlcmFkb3MuDQoNCioqOC4gYFVMU01gIChVbndlaWdodGVkIExlYXN0IFNxdWFyZXMgTWVhbiBhbmQgVmFyaWFuY2UgYWRqdXN0ZWQpLioqDQoNClNpbWlsYXIgYSBVTFMgcGVybyBhanVzdGEgbGEgbWVkaWEgeSBsYSB2YXJpYW56YS4NCg0KKio5LiBgRFdMU2AgKERpYWdvbmFsbHkgV2VpZ2h0ZWQgTGVhc3QgU3F1YXJlcykuKioNCiAgDQogICsgU2ltaWxhciBhIFdMUyBwZXJvIHVzYSBzb2xvIGxvcyBlbGVtZW50b3MgZGlhZ29uYWxlcyBkZSBsYSBtYXRyaXogZGUgY292YXJpYW56YS4NCiAgDQogICsgRXMgbcOhcyBlZmljaWVudGUgY29tcHV0YWNpb25hbG1lbnRlIHkgYWRlY3VhZG8gcGFyYSBkYXRvcyBjb24gdmFyaWFibGVzIGNhdGVnw7NyaWNhcy4NCg0KKioxMC4gYFBNTGAgKFBzZXVkb21heGltdW0gTGlrZWxpaG9vZCkuKioNCg0KVXRpbGl6YWRvIHByaW5jaXBhbG1lbnRlIHBhcmEgZGF0b3MgZGUgY29udGVvIG8gY3VhbmRvIHNlIHRpZW5lIGluZm9ybWFjacOzbiBpbmNvbXBsZXRhLg0KDQoqKjExLiBgQmF5ZXNgIChCYXllc2lhbiBFc3RpbWF0aW9uKS4qKg0KICANCiAgKyBVdGlsaXphIG3DqXRvZG9zIGJheWVzaWFub3MgcGFyYSBsYSBlc3RpbWFjacOzbiBkZSBwYXLDoW1ldHJvcy4NCiAgDQogICsgRXMgw7p0aWwgY3VhbmRvIHNlIGRlc2VhIGluY29ycG9yYXIgaW5mb3JtYWNpw7NuIGEgcHJpb3JpIG8gY3VhbmRvIGxvcyBtb2RlbG9zIHNvbiBjb21wbGVqb3MgeSBvdHJvcyBtw6l0b2RvcyBmYWxsYW4gZW4gY29udmVyZ2VyLg0KICANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvcyBlc3RpbWFkb3JlcyBlbiBgbGF2YWFuYCAoZWplbXBsb3MpDQoNCg0KKioxLiBBIG1hbmVyYSBkZSBlamVtcGxvLCBwYXJhIGFqdXN0YXIgZWwgbW9kZWxvIHV0aWxpemFuZG8gZWwgZXN0aW1hZG9yIGBXTFNNVmAsIHNlIGVqZWN1dGE6KioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpmaXQgPC0gbGF2YWFuOjpjZmEobW9kZWxvLCBkYXRhID0gZGF0LCBlc3RpbWF0b3IgPSAiV0xTTVYiKQ0KZml0DQpgYGANCg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdCA8LSBsYXZhYW46OmNmYShtb2RlbG8sIGRhdGEgPSBkYXQsIGVzdGltYXRvciA9ICJXTFNNViIpDQpmaXQNCmBgYA0KDQoNCioqMi4gQSBtYW5lcmEgZGUgZWplbXBsbywgcGFyYSBhanVzdGFyIGVsIG1vZGVsbyB1dGlsaXphbmRvIGVsIGVzdGltYWRvciBgQmF5ZXNgLCBzZSBlamVjdXRhOioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KZml0IDwtIGJsYXZhYW46OmJjZmEobW9kZWxvLCBkYXRhID0gZGF0LCBlc3RpbWF0b3IgPSAiQmF5ZXMiLCBidXJuaW4gPSAxMDAsIHNhbXBsZSA9IDEwMDApDQpmaXQNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdCA8LSBibGF2YWFuOjpiY2ZhKG1vZGVsbywgZGF0YSA9IGRhdCwgZXN0aW1hdG9yID0gIkJheWVzIiwgYnVybmluID0gMTAwLCBzYW1wbGUgPSAxMDAwKQ0KZml0DQpgYGANCg0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVsZWNjacOzbiBkZWwgRXN0aW1hZG9yDQoNCkxhIGVsZWNjacOzbiBkZWwgZXN0aW1hZG9yIGRlcGVuZGUgZGUgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgbnVlc3Ryb3MgZGF0b3MgeSBkZSBsYXMgaGlww7N0ZXNpcyBzdWJ5YWNlbnRlcyBlbiB0dSBtb2RlbG8uIEFxdcOtIGhheSBhbGd1bmFzIHBhdXRhcyBnZW5lcmFsZXM6DQogIA0KICAxLiBgTUxgIChNYXhpbXVtIExpa2VsaWhvb2QpOiBVdGlsaXphZG8gY29tw7pubWVudGUgY3VhbmRvIHNlIGFzdW1lIHF1ZSBsb3MgZGF0b3Mgc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuDQogIA0KICAyLiBgTUxSYCwgYE1MTWAsIGBNTEZgOiBVdGlsaXphZG9zIGN1YW5kbyBsb3MgZGF0b3Mgbm8gY3VtcGxlbiBjb24gbGEgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEuDQogIA0KICAzLiBgV0xTYCwgYFdMU01gLCBgV0xTTVZgLCBgRFdMU2A6IFByZWZlcmlkb3MgcGFyYSBkYXRvcyBjYXRlZ8Ozcmljb3MgdSBvcmRpbmFsZXMuDQogIA0KICA0LiBgVUxTYCwgYFVMU01gOiBVdGlsaXphZG9zIGN1YW5kbyBzZSBwcmVmaWVyZW4gbcOpdG9kb3Mgbm8gcG9uZGVyYWRvcy4NCiAgDQogIDUuIGBCYXllc2A6IMOadGlsIHBhcmEgbW9kZWxvcyBjb21wbGVqb3MgbyBjdWFuZG8gc2UgZGVzZWEgaW5jb3Jwb3JhciBpbmZvcm1hY2nDs24gYSBwcmlvcmkuDQoNCkNhZGEgZXN0aW1hZG9yIHRpZW5lIHN1cyBwcm9waWFzIHZlbnRhamFzIHkgZGVzdmVudGFqYXMsIHBvciBsbyBxdWUgZXMgaW1wb3J0YW50ZSBjb25zaWRlcmFyIGxhcyBjYXJhY3RlcsOtc3RpY2FzIGRlIHR1cyBkYXRvcyB5IGVsIG9iamV0aXZvIGRlIHR1IGFuw6FsaXNpcyBhbCBzZWxlY2Npb25hciBlbCBlc3RpbWFkb3IgYWRlY3VhZG8uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBjZmFgOiBtw6l0b2RvcyBkZSBvcHRpbWl6YWNpw7NuDQoNCiMjIyAgQ2FyYWN0ZXLDrXN0aWNhcyBkZSBgTkxNSU5CYA0KDQoqKjEuIE1hbmVqbyBkZSBSZXN0cmljY2lvbmVzLioqDQoNCmBOTE1JTkJgIHB1ZWRlIG1hbmVqYXIgdGFudG8gcmVzdHJpY2Npb25lcyBkZSBpZ3VhbGRhZCBjb21vIGRlIGRlc2lndWFsZGFkIGVuIGxvcyBwYXLDoW1ldHJvcywgbG8gY3VhbCBlcyDDunRpbCBlbiBtdWNob3MgcHJvYmxlbWFzIHByw6FjdGljb3MgZG9uZGUgY2llcnRvcyBwYXLDoW1ldHJvcyBkZWJlbiBtYW50ZW5lcnNlIGRlbnRybyBkZSBjaWVydG9zIGzDrW1pdGVzLg0KDQoqKjIuIFJvYnVzdGV6LioqIA0KDQpFcyB1biBhbGdvcml0bW8gcm9idXN0bywgbG8gcXVlIHNpZ25pZmljYSBxdWUgcHVlZGUgY29udmVyZ2VyIGVuIHVuYSBzb2x1Y2nDs24gw7NwdGltYSBlbiB1bmEgYW1wbGlhIHZhcmllZGFkIGRlIHByb2JsZW1hcywgaW5jbHV5ZW5kbyBhcXVlbGxvcyBxdWUgc29uIGRpZsOtY2lsZXMgZGUgcmVzb2x2ZXIgcGFyYSBvdHJvcyBhbGdvcml0bW9zIGRlIG9wdGltaXphY2nDs24uDQoNCioqMy4gQ29udmVyZ2VuY2lhLioqDQoNCkZ1bmNpb25hIGJpZW4gZW4gcHJvYmxlbWFzIGRlIG9wdGltaXphY2nDs24gZG9uZGUgb3Ryb3MgbcOpdG9kb3MgcG9kcsOtYW4gbm8gY29udmVyZ2VyLCBlc3BlY2lhbG1lbnRlIGVuIHByZXNlbmNpYSBkZSByZXN0cmljY2lvbmVzIGNvbXBsaWNhZGFzLg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvcyBtw6l0b2RvIGRlIG9wdGltaXphY2nDs24gZW4gYGxhdmFhbmAgKGFwYXJ0ZSBkZSBgTkxNSU5CYCkNCg0KQWRlbcOhcyBkZSBgTkxNSU5CYCwgYGxhdmFhbmAgb2ZyZWNlIG90cm9zIG3DqXRvZG9zIGRlIG9wdGltaXphY2nDs24uIEFxdcOtIGhheSB1bmEgbGlzdGEgZGUgYWxndW5hcyBkZSBsYXMgb3BjaW9uZXMgeSBzdXMgY2FyYWN0ZXLDrXN0aWNhcyBwcmluY2lwYWxlczoNCg0KMS4gYEJGR1NgOiBNw6l0b2RvIEJyb3lkZW4tRmxldGNoZXItR29sZGZhcmItU2hhbm5vLCB1biBhbGdvcml0bW8gcXVhc2ktTmV3dG9uIHF1ZSBlcyBhZGVjdWFkbyBwYXJhIHByb2JsZW1hcyBzdWF2ZXMgeSBiaWVuIGNvbXBvcnRhZG9zLiBObyBtYW5lamEgcmVzdHJpY2Npb25lcyBleHBsw61jaXRhcyB0YW4gZsOhY2lsbWVudGUgY29tbyBOTE1JTkIuIA0KDQoyLiBgTC1CRkdTLUJgOiBVbmEgdmFyaWFudGUgZGVsIEJGR1MgcXVlIHBlcm1pdGUgcmVzdHJpY2Npb25lcyBlbiBsb3MgcGFyw6FtZXRyb3MgKGNvdGFzIGluZmVyaW9yZXMgeSBzdXBlcmlvcmVzKSwgw7p0aWwgZW4gcHJvYmxlbWFzIGRvbmRlIGxvcyBwYXLDoW1ldHJvcyBuZWNlc2l0YW4gZXN0YXIgZGVudHJvIGRlIGNpZXJ0b3MgcmFuZ29zLg0KDQozLiBgQ0dgOiBHcmFkaWVudGUgY29uanVnYWRvLCBhZGVjdWFkbyBwYXJhIHByb2JsZW1hcyBncmFuZGVzIHkgZGlzcGVyc29zLiBFcyBtZW5vcyBpbnRlbnNpdm8gZW4gbWVtb3JpYSBjb21wYXJhZG8gY29uIGBCRkdTYC4NCg0KNC4gYFNBTk5gOiBSZWNvY2lkbyBzaW11bGFkbyAoU2ltdWxhdGVkIEFubmVhbGluZyksIHVuIGFsZ29yaXRtbyBkZSBvcHRpbWl6YWNpw7NuIGdsb2JhbCBxdWUgcHVlZGUgZXZpdGFyIG3DrW5pbW9zIGxvY2FsZXMsIGF1bnF1ZSBlcyBtZW5vcyBlZmljaWVudGUgcGFyYSBlbmNvbnRyYXIgc29sdWNpb25lcyBwcmVjaXNhcy4NCg0KNS4gYE5lbGRlci1NZWFkYDogTcOpdG9kbyBzaW1wbGV4LCDDunRpbCBwYXJhIHByb2JsZW1hcyBzaW4gcmVzdHJpY2Npb25lcyBubyBsaW5lYWxlcy4gRXMgcm9idXN0bywgcGVybyBwdWVkZSBzZXIgbWVub3MgZWZpY2llbnRlIGVuIHByb2JsZW1hcyBkZSBncmFuIGVzY2FsYS4NCg0KNi4gYHNvbG5wYDogTcOpdG9kbyBkZSBvcHRpbWl6YWNpw7NuIG5vIGxpbmVhbCBjb24gcmVzdHJpY2Npb25lcywgw7p0aWwgZW4gcHJvYmxlbWFzIHF1ZSB0aWVuZW4gdGFudG8gcmVzdHJpY2Npb25lcyBsaW5lYWxlcyBjb21vIG5vIGxpbmVhbGVzLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIE90cm9zIG3DqXRvZG8gZGUgb3B0aW1pemFjacOzbiBlbiBgbGF2YWFuYCAoZWplbXBsb3MpDQoNCioqMS4gQSBtYW5lcmEgZGUgZWplbXBsbywgcGFyYSBhanVzdGFyIGVsIG1vZGVsbyB1dGlsaXphbmRvIGVsIG3DqXRvZG8gYEJGR1NgLCBzZSBlamVjdXRhOioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KZml0IDwtIGxhdmFhbjo6Y2ZhKG1vZGVsbywgZGF0YSA9IGRhdCwgb3B0aW0ubWV0aG9kID0gIkJGR1MiKQ0KZml0DQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpmaXQgPC0gbGF2YWFuOjpjZmEobW9kZWxvLCBkYXRhID0gZGF0LCBvcHRpbS5tZXRob2QgPSAiQkZHUyIpDQpmaXQNCmBgYA0KDQoNCioqMi4gQSBtYW5lcmEgZGUgZWplbXBsbywgcGFyYSBhanVzdGFyIGVsIG1vZGVsbyB1dGlsaXphbmRvIGVsIG3DqXRvZG8gYHNvbG5wYCwgc2UgZWplY3V0YToqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmZpdCA8LSBsYXZhYW46OmNmYShtb2RlbG8sIGRhdGEgPSBkYXQsIG9wdGltLm1ldGhvZCA9ICJzb2xucCIpDQpmaXQNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRSwgZXZhbD1GQUxTRX0NCmZpdCA8LSBsYXZhYW46OmNmYShtb2RlbG8sIGRhdGEgPSBkYXQsIG9wdGltLm1ldGhvZCA9ICJzb2xucCIpDQpmaXQNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYGNmYWA6IGludGVyY2VwdG9zIA0KDQojIyMgSW50ZXJwcmV0YWNpw7NuIGRlIGxvcyBpbnRlcmNlcHRvcyBlbiBgbGF2YWFuYA0KDQpFbCBwYXF1ZXRlIGxhdmFhbiBzaWd1ZSBjaWVydGFzIGNvbnZlbmNpb25lcyB5IHN1cG9zaWNpb25lcyBlbiBlbCBhbsOhbGlzaXMgQ0ZBIHF1ZSBhZmVjdGFuIGxhIGVzdGltYWNpw7NuIHkgY29udGVvIGRlIGxvcyBwYXLDoW1ldHJvczoNCg0KKioxLiBNb2RlbG8gZW4gRXNjYWxhIEVzdMOhbmRhciAoU3RhbmRhcmRpemVkIFNvbHV0aW9uKS4qKg0KICANCiAgKyBFbiBsYSBzb2x1Y2nDs24gZXN0w6FuZGFyLCBsYXMgbWVkaWFzIGRlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcyBzZSBmaWphbiBhIGNlcm8gKCRcYWxwaGFfMT0wJCwgJFxhbHBoYV8yPTAkLCAkXGFscGhhXzM9MCQpLg0KICANCiAgKyBFc3RvIGltcGxpY2EgcXVlIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIHNlIGV4cGxpY2FuIMO6bmljYW1lbnRlIGVuIHTDqXJtaW5vcyBkZSBzdXMgaW50ZXJjZXB0b3MgeSBubyBzZSByZXF1aWVyZW4gZXN0aW1hY2lvbmVzIGFkaWNpb25hbGVzIGRlIGxvcyBpbnRlcmNlcHRvcy4NCiAgDQoNCioqMi4gSWRlbnRpZmljYWNpw7NuIGRlbCBNb2RlbG8uKioNCiAgDQogICsgUGFyYSBhc2VndXJhciBxdWUgZWwgbW9kZWxvIHNlYSBpZGVudGlmaWNhYmxlLCBhIG1lbnVkbyBzZSBmaWphbiBjaWVydG9zIHBhcsOhbWV0cm9zIGEgdmFsb3JlcyBjb25vY2lkb3MgKHBvciBlamVtcGxvLCBmaWphciB1bmEgY2FyZ2EgZmFjdG9yaWFsIGEgMSB5IGxvcyBpbnRlcmNlcHRvcyBkZSBsb3MgZmFjdG9yZXMgYSBjZXJvKS4NCiAgDQogICsgRW4gY29uc2VjdWVuY2lhLCBsb3MgaW50ZXJjZXB0b3MgZGUgbG9zIGZhY3RvcmVzIG5vIHNlIGVzdGltYW4gZGUgbWFuZXJhIGV4cGzDrWNpdGEgZW4gZWwgbW9kZWxvIHBvcnF1ZSB5YSBzZSBhc3VtZW4gY29tbyBwYXJ0ZSBkZWwgYWp1c3RlIGdsb2JhbCBkZWwgbW9kZWxvLg0KICANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFRvdGFsIGRlIHBhcsOhbWV0cm9zIGVuIGNhZGEgZ3J1cG8NCg0KUGFyYSBleHBsaWNhciBwb3IgcXXDqSBlbCBvdXRwdXQgZGUgYGxhdmFhbjo6Y2ZhYCAgbXVlc3RyYSAyMSBwYXLDoW1ldHJvcywgZGViZW1vcyBkZXNnbG9zYXIgbG9zIGNvbXBvbmVudGVzIGRlbCBtb2RlbG8geSBsb3MgcGFyw6FtZXRyb3MgcXVlIHNlIGVzdGltYW4uDQoNClZhbW9zIGEgZW51bWVyYXIgbG9zIHBhcsOhbWV0cm9zIHBhcmEgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbzoNCg0KICoqMS4gQ2FyZ2FzIEZhY3RvcmlhbGVzLioqDQoNCkNhZGEgaW5kaWNhZG9yIHRpZW5lIHVuYSBjYXJnYSBmYWN0b3JpYWwgcGFyYSBlbCBmYWN0b3IgYWwgcXVlIGVzdMOhIGFzaWduYWRvOg0KICAgIA0KICArIGBWaXN1YWxgOiBgeDFgLCBgeDJgLCBgeDNgLg0KICAgIA0KICArIGBUZXh0dWFsYDogYHg0YCwgYHg1YCwgYHg2YC4NCiAgICANCiAgKyBgU3BlZWRgOiAgYHg3YCwgYHg4YCwgYHg5YC4NCiAgICANCkNhZGEgdW5vIGRlIGVzdG9zIGluZGljYWRvcmVzIHRpZW5lIHVuYSBjYXJnYSBmYWN0b3JpYWwsIHN1bWFuZG8gdW4gdG90YWwgZGUgOSBjYXJnYXMgZmFjdG9yaWFsZXMuDQoNCg0KDQoqKjIuIEludGVyY2VwdG9zIGRlIGxvcyBGYWN0b3JlcyBMYXRlbnRlcy4qKg0KDQpDYWRhIGluZGljYWRvciB0aWVuZSBhc29jaWFkbyB1biBpbnRlY2VwdG8gcGFyYSBgeDFgLCBgeDJgLCBgeDNgLCBgeDRgLCBgeDVgLCBgeDZgLCBgeDdgLCBgeDhgIHkgYHg5YC4gRW50b25jZXMsIGVuIHRvdGFsIHNlcsOtYW4gOSBpbnRlcmNlcHRvcy4NCg0KKiozLiBWYXJpYW56YXMgZGUgbG9zIEVycm9yZXMgZGUgTWVkaWNpw7NuKio6IA0KDQpDYWRhIGluZGljYWRvciB0aWVuZSB1bmEgdmFyaWFuemEgZGUgZXJyb3IgYXNvY2lhZGEgcGFyYSBgeDFgLCBgeDJgLCBgeDNgLCBgeDRgLCBgeDVgLCBgeDZgLCBgeDdgLCBgeDhgIHkgYHg5YC4gRXN0byBzdW1hIDkgcGFyw6FtZXRyb3MuDQoNCioqNC4gTWVkaWFzIGRlIGxvcyBmYWN0b3Jlcy4qKg0KDQpDYWRhIGZhY3RvciB0aWVuZSBhc29jaWFkYSB1bmEgbWVkaWE6IA0KDQogDQogICsgTWVkaWEgZGUgYFZpc3VhbGAuDQogIA0KICArIE1lZGlhIGRlIGBUZXh0dWFsYC4NCiAgDQogICsgbWVkaWEgZGUgYFNwZWVkYC4NCg0KRXMgZGVjaXIsIHNlcsOtYW4gMyBwYXLDoW1ldHJvcy4gDQoNCg0KKio1LiBWYXJpYW56YXMgZGUgbG9zIEZhY3RvcmVzIExhdGVudGVzLioqDQogDQpIYXkgdHJlcyBmYWN0b3JlcyBsYXRlbnRlcyAoYFZpc3VhbGAsICBgVGV4dHVhbGAsICBgU3BlZWRgKSwgeSBzZSBlc3RpbWEgdW5hIHZhcmlhbnphIHBhcmEgY2FkYSB1bm86DQogIA0KICArIFZhcmlhbnphIGRlIGBWaXN1YWxgLg0KICANCiAgKyBWYXJpYW56YSBkZSBgVGV4dHVhbGAuDQogIA0KICArIFZhcmlhbnphIGRlIGBTcGVlZGAuDQoNCkVzdG8gc3VtYSAzIHBhcsOhbWV0cm9zLg0KDQoqKjYuIENvdmFyaWFuemFzIGVudHJlIGxvcyBGYWN0b3JlcyBMYXRlbnRlcy4qKg0KDQpIYXkgY292YXJpYW56YXMgZW50cmUgY2FkYSBwYXIgZGUgZmFjdG9yZXMgbGF0ZW50ZXMuIFBhcmEgdHJlcyBmYWN0b3JlcywgZXN0byBzZSBjYWxjdWxhIGNvbW8gDQokezMgXGNob29zZSAyfT0zJCBjb3ZhcmlhbnphczoNCg0KICANCiAgKyBDb3ZhcmlhbnphIGRlIGBWaXN1YWxgLWBUZXh0dWFsYC4NCiAgDQogICsgQ292YXJpYW56YSBkZSBgVmlzdWFsYC1gU3BlZWRgLg0KICANCiAgKyBDb3ZhcmlhbnphIGRlIGBUZXh0dWFsYC1gU3BlZWRgLg0KDQpFc3RvIHN1bWEgMyBwYXLDoW1ldHJvcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIFN1bWEgVG90YWwgZGUgUGFyw6FtZXRyb3MNCg0KU3VtYW5kbyB0b2RvcyBsb3MgdmFsb3JlcyBhbnRlcmlvcmVzLCB0ZW5lbW9zICh2w6lhc2UgbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW42KSk6DQogIA0KICAxLiBDYXJnYXMgZmFjdG9yaWFsZXM6IDkNCiAgDQogIDIuIEludGVyY2VwdG9zIGRlIGxvcyBGYWN0b3JlcyBMYXRlbnRlczogOQ0KICANCiAgMy4gVmFyaWFuemFzIGRlIGxvcyBlcnJvcmVzIGRlIG1lZGljacOzbjogOQ0KICANCiAgNC4gTWVkaWFzIGRlIGxvcyBmYWN0b3JlczogMw0KICANCiAgNS4gVmFyaWFuemFzIGRlIGxvcyBmYWN0b3JlczogMw0KICANCiAgNi4gQ292YXJpYW56YXMgZW50cmUgZmFjdG9yZXM6IDMNCiAgDQoNCiQkOSBcOytcOyA5XDsgK1w7IDlcOyArIFw7M1w7ICsgXDszIFw7KyBcOzMgXDs9XDsgMzYkJA0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjYpIHNlIHZpc3VhbGl6YSBsbyBhbnRlcmlvci4NCg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuNiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlRvdGFsIGRlIHBhcsOhbWV0cm9zIGVuIGVsIG1vZGVsbyBDRkEgbm8gZXN0w6FuZGFyKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW42Yi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ29uc2lkZXJhY2nDs24gZGUgcGFyw6FtZXRyb3MgY29ub2NpZG9zDQoNCjEuIEVuIG11Y2hvcyBjYXNvcywgdW5vIGRlIGxvcyBpbmRpY2Fkb3JlcyBwYXJhIGNhZGEgZmFjdG9yIHNlIGZpamEgYSAxIHBhcmEgcXVlIGVsIG1vZGVsbyBzZWEgaWRlbnRpZmljYWJsZToNCiQkXGxhbWJkYV8xXDs9XDsgIFxsYW1iZGFfNFw7PVw7ICBcbGFtYmRhXzdcOz1cOyAgMSQkDQoNCg0KMi4gRXN0byBzaWduaWZpY2EgcXVlIHBhcmEgY2FkYSBmYWN0b3IsIHVuYSBkZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIG5vIHNlIGVzdGltYSAoeWEgcXVlIHNlIGZpamEpLiBEYWRvIHF1ZSBoYXkgMyBmYWN0b3JlcywgZXN0byByZXN0YSAzIHBhcsOhbWV0cm9zIGRlbCB0b3RhbA0KDQoNCjMuIFBvciBkZWZlY3RvLCBlbCBwYXF1ZXRlIGBsYXZhYW5gIGVzdGltYSB1biAqbW9kZWxvIGVuIEVzY2FsYSBFc3TDoW5kYXIqLiBQb3IgZXN0YSByYXrDs246IA0KICANCiAgKyBMYXMgbWVkaWFzIGRlIGxvcyB0cmVzIGZhY3RvcmVzIGxhdGVudGVzIHNlIGZpamFuIGEgY2VybyAobyBzZWEsIGRlYmUgcmVzdGFyc2UgMyBwYXLDoW1ldHJvcyBkZWwgdG90YWwpOg0KICANCiQkXGFscGhhXzEgXDs9XDsgIFxhbHBoYV8yIFw7PVw7ICBcYWxwaGFfMyBcOz1cOyAgMCQkDQogIA0KICArIExhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIHNlIGV4cGxpY2FuIMO6bmljYW1lbnRlIGVuIHTDqXJtaW5vcyBkZSBzdXMgaW50ZXJjZXB0b3MgeSBubyBzZSByZXF1aWVyZW4gZXN0aW1hY2lvbmVzIGFkaWNpb25hbGVzIGRlIGxvcyBpbnRlcmNlcHRvcyAobyBzZWEsIHRhbWJpw6luIGRlYmUgcmVzdGFyc2UgOSBwYXLDoW1ldHJvcyBkZWwgdG90YWwpOg0KICANCiANCiQkXHRhdV8xIFw7PVw7ICBcdGF1XzIgXDs9XDsgIFx0YXVfMyBcOz1cOyAgXHRhdV80IFw7PVw7ICBcdGF1XzUgXDs9XDsgIFx0YXVfNiBcOz1cOyAgXHRhdV83IFw7PVw7ICBcdGF1XzggXDs9XDsgIFx0YXVfOSBcOz1cOyAgMCQkIA0KDQo0LiBFbnRvbmNlcywgcmVzdGFuZG8gZXN0b3MgMTUgcGFyw6FtZXRyb3MgZmlqb3MsIHRlbmVtb3M6DQoNCiQkMzZcO+KIklw7MTVcOyA9XDsgMjEkJA0KDQo1LiBFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjcpIHNlIHZpc3VhbGl6YSBsbyBhbnRlcmlvci4NCg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuNywgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlRvdGFsIGRlIHBhcsOhbWV0cm9zIHNlZ8O6biBgbGF2YWFuYCAoZWxpbWluYW5kbyBwYXLDoW1ldHJvcyBmaWpvcykqKiIsIG91dC53aWR0aCA9ICIxMDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjdiLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIENvbmNsdXNpw7NuOiB0b3RhbCBkZWZpbml0aXZvIGRlIHBhcsOhbWV0cm9zDQoNCjEuIExvcyAyMSBwYXLDoW1ldHJvcyBlbiBlbCBvdXRwdXQgZGVsIG1vZGVsbyBzZSBkaXN0cmlidXllbiBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOg0KICANCiAgKyA2IGNhcmdhcyBmYWN0b3JpYWxlcyBlc3RpbWFkYXMgKDMgZmFjdG9yZXMgeCAzIGluZGljYWRvcmVzLCAgbWVub3MgMyBmaWphcykuDQogIA0KICArIDAgaW50ZXJjZXB0b3MuDQogIA0KICArIDkgdmFyaWFuemFzIGRlIGxvcyBlcnJvcmVzIGRlIG1lZGljacOzbi4NCiAgDQogICsgMCBtZWRpYXMgZGUgbG9zIGZhY3RvcmVzIGxhdGVudGVzLiANCiAgDQogICsgMyB2YXJpYW56YXMgZGUgbG9zIGZhY3RvcmVzIGxhdGVudGVzLg0KICANCiAgKyAzIGNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3JlcyBsYXRlbnRlcy4NCiAgDQoNCjIuIEVzdG8gZGEgdW4gdG90YWwgZGUgMjEgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGVuIGVsIG1vZGVsbyBDRkEgdXRpbGl6YW5kbyBsb3MgZGF0b3MgYEhvbHppbmdlclN3aW5lZm9yZDE5MzlgIHkgZWwgbW9kZWxvIGVzcGVjaWZpY2Fkby4NCg0KDQozLiBFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjgpIHNlIHZpc3VhbGl6YSBsbyBhbnRlcmlvci4NCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCntcY29sb3J7VGVhbH0gXGxhbWJkYV8yLCBcbGFtYmRhXzMsIFxsYW1iZGFfNSwgXGxhbWJkYV82LCBcbGFtYmRhXzgsXGxhbWJkYV85fVxcDQpcXA0Ke1xjb2xvcntUZWFsfSBWKFx2YXJlcHNpbG9uXzEpLCBWKFx2YXJlcHNpbG9uXzIpLCBWKFx2YXJlcHNpbG9uXzMpLCBWKFx2YXJlcHNpbG9uXzQpLCBWKFx2YXJlcHNpbG9uXzUpLCBWKFx2YXJlcHNpbG9uXzYpLCBWKFx2YXJlcHNpbG9uXzcpLCBWKFx2YXJlcHNpbG9uXzgpLCBWKFx2YXJlcHNpbG9uXzkpfQ0KYGBgDQoNCg0KDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuOCwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKk7Dum1lcm8gZGUgcGFyw6FtZXRyb3Mgc2Vnw7puIGBsYXZhYW5gKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQoNCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjhiLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgY2ZhYDogc2VndW5kYSBwYXJ0ZQ0KDQojIyMgTW9kZWwgVGVzdCBVc2VyIE1vZGVsIGVuIGBsYXZhYW5gDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuOCkgc2UgcmVzYWx0YSBsYSBzZWd1bmRhIHBhcnRlIGRlbCBvdXRwdXQgZGUgYGxhdmFhbmAuICANCiAgDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuOSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlNlZ3VuZGEgcGFydGUgZGVsIG91dHB1dCBkZSBgbGF2YWFuYCAoYGNmYWApKioiLCBvdXQud2lkdGggPSAiNzAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjkucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gIA0KICANCg0KRXN0b3MgcmVzdWx0YWRvcyBjb3JyZXNwb25kZW4gYSB1bmEgcHJ1ZWJhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIChNb2RlbCBUZXN0KS4gRW4gZWwgY29udGV4dG8gZGUgbGEgcHJ1ZWJhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIChNb2RlbCBUZXN0KSBlbiBgbGF2YWFuYCwgbGFzIGhpcMOzdGVzaXMgbnVsYSB5IGFsdGVybmF0aXZhIHNvbiBsYXMgc2lndWllbnRlczoNCiAgICANCiAgKyAqSGlww7N0ZXNpcyBudWxhIChIMCk6KiBMYSBoaXDDs3Rlc2lzIG51bGEgZW4gZXN0ZSBjYXNvIHNlcsOtYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBzZSBhanVzdGEgYmllbiBhIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGVuIGxhIG11ZXN0cmEuIEVzdG8gc2lnbmlmaWNhIHF1ZSBubyBoYXkgZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZW50cmUgbG9zIGRhdG9zIG9ic2VydmFkb3MgeSBsb3MgZGF0b3MgZXNwZXJhZG9zIHNlZ8O6biBlbCBtb2RlbG8uIA0KICAgIA0KICArICpIaXDDs3Rlc2lzIGFsdGVybmF0aXZhIChIMSk6KiBMYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhIHNlcsOtYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBubyBzZSBhanVzdGEgYmllbiBhIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGVuIGxhIG11ZXN0cmEuIEVzdG8gaW1wbGljYSBxdWUgaGF5IGRpZmVyZW5jaWFzIHNpZ25pZmljYXRpdmFzIGVudHJlIGxvcyBkYXRvcyBvYnNlcnZhZG9zIHkgbG9zIGRhdG9zIGVzcGVyYWRvcyBzZWfDum4gZWwgbW9kZWxvLCBsbyBxdWUgc2UgdHJhZHVjZSBlbiB1biBtYWwgYWp1c3RlIGRlbCBtb2RlbG8uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBJbnRlcHJldGFjacOzbjogc2VndW5kYSBwYXJ0ZQ0KDQpBcXXDrSBlc3TDoSBlbCBzaWduaWZpY2FkbyBkZSBjYWRhIHVubyBkZSBsb3MgZWxlbWVudG9zIGRlIGxhIHNhbGlkYToNCg0KICoqMS4gVGVzdCBzdGF0aXN0aWMgKEVzdGFkw61zdGljbyBkZSBwcnVlYmEpLioqIA0KDQpFcyBlbCB2YWxvciBkZWwgZXN0YWTDrXN0aWNvIGRlIHBydWViYSAocXVlIHRpZW5lIGRpc3RyaWJ1Y2nDs24gY2hpLWN1YWRyYWRhKSB5ICBjYWxjdWxhZG8gcGFyYSBldmFsdWFyIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLiBVbiB2YWxvciBhbHRvIGdlbmVyYWxtZW50ZSBpbmRpY2EgdW4gbWFsIGFqdXN0ZSBkZWwgbW9kZWxvIGEgbG9zIGRhdG9zIG9ic2VydmFkb3MuIEVuIGVzdGUgY2FzbywgZWwgdmFsb3IgZXMgODUuMzA2Lg0KDQoqKjIuRGVncmVlcyBvZiBmcmVlZG9tIChHcmFkb3MgZGUgbGliZXJ0YWQpLioqDQoNClJlcHJlc2VudGEgZWwgbsO6bWVybyBkZSB2YWxvcmVzIHF1ZSBzb24gbGlicmVzIGRlIHZhcmlhciB1bmEgdmV6IHF1ZSBjaWVydGFzIHJlc3RyaWNjaW9uZXMgc29uIGltcHVlc3Rhcy4gRW4gQ0ZBLCBsb3MgZ3JhZG9zIGRlIGxpYmVydGFkIHNlIGNhbGN1bGFuIGNvbW8gbGEgZGlmZXJlbmNpYSBlbnRyZSBlbCBuw7ptZXJvIGRlIG9ic2VydmFjaW9uZXMgaW5kZXBlbmRpZW50ZXMgKGdlbmVyYWxtZW50ZSBlbCBuw7ptZXJvIGRlIGVudHJhZGFzIGVuIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphKSB5IGVsIG7Dum1lcm8gZGUgcGFyw6FtZXRyb3MgZXN0aW1hZG9zLiBFbiBlc3RlIGNhc28sIGhheSAyNCBncmFkb3MgZGUgbGliZXJ0YWQuDQoNCg0KKiozLiBQLXZhbHVlIChDaGktc3F1YXJlKSAoVmFsb3IgcCBvYnRlbmlkbyBjb24gbGEgY2hpLWN1YWRyYWRhKS4qKiANCg0KRXMgbGEgcHJvYmFiaWxpZGFkIGRlIG9idGVuZXIgdW4gdmFsb3IgZGVsIGVzdGFkw61zdGljbyBkZSBwcnVlYmEgaWd1YWwgbyBtw6FzIGV4dHJlbW8gcXVlIGVsIHZhbG9yIG9ic2VydmFkbywgYXN1bWllbmRvIHF1ZSBsYSBoaXDDs3Rlc2lzIG51bGEgZXMgdmVyZGFkZXJhLiBFbiBlbCBjb250ZXh0byBkZSBsYXZhYW4sIHVuIHZhbG9yICRwJCBiYWpvICgkPCAwLjA1JCkgZ2VuZXJhbG1lbnRlIGluZGljYSB1biBtYWwgYWp1c3RlIGRlbCBtb2RlbG8sIGxvIHF1ZSBzaWduaWZpY2EgcXVlIGxvcyBkYXRvcyBvYnNlcnZhZG9zIGRpZmllcmVuIHNpZ25pZmljYXRpdmFtZW50ZSBkZSBsb3MgZGF0b3MgZXNwZXJhZG9zIHNlZ8O6biBlbCBtb2RlbG8uIEVuIGVzdGUgY2FzbywgZWwgdmFsb3IgcCBlcyAwLjAwMCwgbG8gcXVlIGluZGljYSBxdWUgZWwgbW9kZWxvIG5vIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zLCB5YSBxdWUgbGEgcHJvYmFiaWxpZGFkIGRlIG9idGVuZXIgdW4gdmFsb3IgZGUgZXN0YWTDrXN0aWNvIGRlIHBydWViYSBpZ3VhbCBvIG3DoXMgZXh0cmVtbyBlcyBtdXkgYmFqYS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRnVuY2nDs24gYHN1bW1hcnlgIGRlIGBsYXZhYW5gDQoNCiMjIyBgc3VtbWFyeWA6IGRlc2NyaXBjacOzbg0KDQoxLiBVbmEgdmV6IHF1ZSBlbCBtb2RlbG8gaGEgc2lkbyBhanVzdGFkbywgbGEgZnVuY2nDs24gYHN1bW1hcnlgIHByb3BvcmNpb25hIHVuIGJ1ZW4gcmVzdW1lbiBkZWwgbW9kZWxvIGFqdXN0YWRvLiANCg0KMi4gRWwgYXJndW1lbnRvIGBmaXQubWVhc3VyZXM9VFJVRWAgZW4gbGEgZnVuY2nDs24gYHN1bW1hcnlgICBpbmRpY2EgcXVlIHNlIGRlc2VhbiBpbmNsdWlyIG1lZGlkYXMgZGUgYWp1c3RlIGRlbCBtb2RlbG8gZW4gZWwgcmVzdW1lbiBkZWwgbW9kZWxvLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYHN1bW1hcnlgOiBlamVjdWNpw7NuIHkgb3V0cHV0DQoNClNlIGVqZWN1dGEgYXPDrTogDQoNCmBgYHtyfQ0Kc3VtbWFyeShDRkEsIGZpdC5tZWFzdXJlcz1UUlVFKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBzdW1tYXJ5YDogcGFydGVzIDEgeSAyIA0KDQojIyMgSW5mb3JtYWNpw7NuIGdlbmVyYWwgZGVsIG1vZGVsbyANCg0KMS4gRWwgbW9kZWxvIGZpbmFsaXrDsyBub3JtYWxtZW50ZSBkZXNwdcOpcyBkZSAzNSBpdGVyYWNpb25lcy4NCg0KMi4gRWwgZXN0aW1hZG9yIHV0aWxpemFkbyBmdWUgZWwgbcOheGltbyB2ZXJvc2ltaWxpdHVkIChgTUxgKS4NCg0KMy4gRWwgbcOpdG9kbyBkZSBvcHRpbWl6YWNpw7NuIGZ1ZSBgTkxNSU5CYC4NCg0KNC4gRWwgbW9kZWxvIHRpZW5lIDIxIHBhcsOhbWV0cm9zLg0KDQo1LiBTZSB1dGlsaXphcm9uIDMwMSBvYnNlcnZhY2lvbmVzIGVuIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLg0KDQo2LiBFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjEwKSBzZSBwdWVkZSB2aXN1YWxpemFyIGxhIHBhcnRlIE5vLiAxIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGVzIGxhIG1pc21hIHF1ZSBhcGFyZWNlIGVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuNSkpLiAgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgUHJ1ZWJhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIChNb2RlbCBUZXN0IFVzZXIgTW9kZWwpDQoNCjEuIEVsIGVzdGFkw61zdGljbyBkZSBwcnVlYmEgZXMgODUuMzA2Lg0KDQoyLiBFbCBtb2RlbG8gdGllbmUgMjQgZ3JhZG9zIGRlIGxpYmVydGFkLg0KDQozLiBFbCB2YWxvciBwIGFzb2NpYWRvIGFsIENoaS1jdWFkcmFkbyBlcyAwLjAwMCwgbG8gcXVlIGluZGljYSBxdWUgZWwgbW9kZWxvIG5vIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zICh2YWxvciBwIHNpZ25pZmljYXRpdmFtZW50ZSBtZW5vciBxdWUgMC4wNSkuDQoNCjQuIEVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTApIHNlIHB1ZWRlIHZpc3VhbGl6YXIgbGEgcGFydGUgTm8uIDIgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoZXMgbGEgbWlzbWEgcXVlIGFwYXJlY2UgZW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW45KSkuIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgc3VtbWFyeWA6IHRlc3QgbW9kZWxvIG51bG8gIA0KDQoNCiMjIyBgVGVzdCBCYXNlbGluZSBNb2RlbGA6IE1vZGVsbyBudWxvIChCYXNlbGluZSBNb2RlbCkNCg0KMS4gRWwgKk1vZGVsbyBCYXNlbGluZSogKG8gKm1vZGVsbyBudWxvKikgZXMgdW4gbW9kZWxvIG11eSByZXN0cmluZ2lkbyBxdWUgYXN1bWUgcXVlIHRvZGFzIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBzb24gaW5kZXBlbmRpZW50ZXMgZW50cmUgc8OtLiANCg0KMi4gRXMgZGVjaXIsIG5vIGhheSBjb3JyZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMuIA0KDQozLiBFbiBlc3RlIG1vZGVsbywgdG9kYXMgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBzZSBlc3RhYmxlY2VuIGEgY2Vyby4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgVGVzdCBCYXNlbGluZSBNb2RlbGA6IG1vZGVsbyBudWxvIGVuIFINCg0KUGFyYSBlbGxvIHNlIGVqZWN1dGEgZWwgc2lndWllbnRlIGPDs2RpZ286IA0KDQpgYGB7cn0NCm1vZGVsX251bGwgPC0gJw0KICB4MSB+fiB4MQ0KICB4MiB+fiB4Mg0KICB4MyB+fiB4Mw0KICB4NCB+fiB4NA0KICB4NSB+fiB4NQ0KICB4NiB+fiB4Ng0KICB4NyB+fiB4Nw0KICB4OCB+fiB4OA0KICB4OSB+fiB4OQ0KJw0KDQojIEFqdXN0YXIgZWwgbW9kZWxvIG51bG8NCmZpdF9udWxsIDwtIGNmYShtb2RlbF9udWxsLCBkYXRhID0gZGF0KQ0KZml0X251bGwNCmBgYA0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBUZXN0IEJhc2VsaW5lIE1vZGVsYDogZ3LDoWZpY2FyIG1vZGVsbyBudWxvIGVuIFINCg0KUGFyYSBlbGxvLCBzZSBwdWVkZSBlamVjdXRhciBlbCBzaWd1aWVudGUgY8OzZGlnbzogDQoNCmBgYHtyfQ0Kc2VtUGF0aHMoZml0X251bGwsIA0KICAgICAgICAgd2hhdCA9ICJwYXRoIiwgICAgI011ZXN0cmEgbGFzIHJ1dGFzIGNvbiBjYXJnYXMsIHJlZ3Jlc2lvbmVzLCBjb3ZhcmlhbnphcyAgICAgDQogICAgICAgICAjd2hhdCA9ICJzdGQiLCAgICAjTXVlc3RyYSBsYXMgZXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzIGRlIGxhcyBydXRhcyANCiAgICAgICAgICN3aGF0ID0gImVzdCIsICAgICNNdWVzdHJhIGxhcyBlc3RpbWFjaW9uZXMgbm8gZXN0YW5kYXJpemFkYXMgZGUgbGFzIHJ1dGFzIA0KICAgICAgICAgI3doYXQgPSAiY29sIiwgICAgI011ZXN0cmEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyBkZSB2YXIuIG9ic2VydmFkYXMNCiAgICAgICAgICN3aGF0ID0gIm1vZCIsICAgICNNdWVzdHJhIGNhbWlubyBhZGljaW9uYWwgcXVlIHBvZHLDrWEgbWVqb3JhciBhanVzdGUgZGVsIG1vZGVsbw0KICAgICAgICAgI3doYXQgPSAibW9kZWwiLCAgI011ZXN0cmEgdW5hIHJlcHJlc2VudGFjacOzbiBncmFsIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImFsbCIsICAgICNNdWVzdHJhIHRvZG9zIGVsZW1lbnRvcyBwb3NpYmxlcyAocnV0YXMgeSBlc3RpbWFjaW9uZXMpDQogICAgICAgICAjd2hhdCA9ICJwYXIiLCAgICAjTXVlc3RyYSB0b2RvcyBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8NCiAgICAgICAgICN3aGF0ID0gImVxIiwgICAgICNNdWVzdHJhIGxhcyBlY3VhY2lvbmVzIGVzdHJ1Y3R1cmFsZXMgZGVsIG1vZGVsbyANCiAgICAgICAgIA0KICAgICAgICAgbGF5b3V0ID0gInRyZWUiLCAgICAjRGlzcG9uZSBub2RvcyBlbiBjw61yY3VsbyAoc29sbyBwZXJtaXRpZG8gc2kgcm90YXRpb249IDEgbyAzKQ0KICAgICAgICAgDQogICAgICAgICB0aXRsZSA9IEZBTFNFLCAgICAgICAgI05vIG11ZXN0cmEgZWwgdMOtdHVsbyBkZWwgZ3LDoWZpY28NCiAgICAgICAgIA0KICAgICAgICAgZWRnZS5jb2xvciA9ICJSZWQiLCAjRXN0YWJsZWNlIGVsIGNvbG9yIGRlIGxvcyBib3JkZXMgKGFyaXN0YXMpIGVuIG5lZ3JvDQogICAgICAgICBzaXplTWFuID0gOCwgICAgI1RhbWHDsW8gZGUgbG9zIG5vZG9zIHF1ZSByZXByZXNlbnRhbiB2YXJpYWJsZXMgbWFuaWZpZXN0YXMNCiAgICAgICAgIGNvbG9yID0gbGlzdChtYW4gPSAibGlnaHRncmVlbiIgI0NvbG9yIGRlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcw0KICAgICAgICAgICAgICAgICAgICAgKSANCiAgICAgICAgICkNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgVGVzdCBCYXNlbGluZSBNb2RlbGA6IGdyw6FmaWNvIGRlIHBhcnRlIE5vLiAzDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTApIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDMgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjEwLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDMgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoYFRlc3QgQmFzZWxpbmUgTW9kZWxgKSoqIiwgb3V0LndpZHRoID0gIjEwMCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTAucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gIA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBUZXN0IEJhc2VsaW5lIE1vZGVsYDogaGlww7N0ZXNpcw0KDQoqKjEuIExhIGhpcMOzdGVzaXMgbnVsYSAoJEhfMCQpIHBhcmEgZWwgYE1vZGVsIFRlc3QgQmFzZWxpbmUgTW9kZWxgKioNCg0KVmllbmUgZGFkYSBwb3I6DQoNCiQkSDA6IFw7XHRleHR7RWwgbW9kZWxvIG51bG8gc2UgYWp1c3RhIGJpZW4gYSBsb3MgZGF0b3N9JCQNCiAgDQpFc3RvIGltcGxpY2EgcXVlIGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgbm8gc29uIHNpZ25pZmljYXRpdmFtZW50ZSBkaWZlcmVudGVzIGRlIGNlcm8sIGVzIGRlY2lyLCBxdWUgdG9kYXMgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIHNvbiBpbmRlcGVuZGllbnRlcyBlbnRyZSBzw60uDQoNCioqMi4gTGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YSAoJEhfMSQpKiogDQoNClZpZW5lIGRhZCBwb3I6DQoNCiQkSF8xOiBcO1x0ZXh0e0VsIG1vZGVsbyBudWxvIG5vIHNlIGFqdXN0YSBiaWVuIGEgbG9zIGRhdG9zfSQkDQpFc3RvIGltcGxpY2EgcXVlIGhheSByZWxhY2lvbmVzIHNpZ25pZmljYXRpdmFzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcywgZXMgZGVjaXIsIHF1ZSBsYXMgY292YXJpYW56YXMgZW50cmUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIHNvbiBkaWZlcmVudGVzIGRlIGNlcm8uDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFRlc3QgQmFzZWxpbmUgTW9kZWxgOiBpbnRlcnByZXRhY2lvbmVzIA0KDQoqKjEuIEVzdGFkw61zdGljbyBkZSBDaGktQ3VhZHJhZG8gKCRcY2hpXjIkKS4gKioNCg0KTWlkZSBsYSBkaXNjcmVwYW5jaWEgZW50cmUgbGEgbWF0cml6IGRlIGNvdmFyaWFuemEgb2JzZXJ2YWRhIHkgbGEgbWF0cml6IGRlIGNvdmFyaWFuemEgZXN0aW1hZGEgYmFqbyBlbCBtb2RlbG8gbnVsby4gRW4gZXN0ZSBjYXNvLCBlbCB2YWxvciBkZWwgZXN0YWTDrXN0aWNvIGVzIGRlIDkxOC44NTIuDQoNCg0KKioyLiBHcmFkb3MgZGUgTGliZXJ0YWQgKGRmKS4qKg0KDQpMYSBkaXN0cmlidWNpw7NuIHNlIGFqc3V0YSBjb24gMzYgZ3JhZG9zIGRlIGxpYmVydGFkLg0KDQoNCioqMy4gVmFsb3IgUC4qKg0KDQpJbmRpY2Egc2kgbGEgZGlzY3JlcGFuY2lhIG9ic2VydmFkYSAoZXN0YWTDrXN0aWNvICRcY2hpXjIkKSBlcyBzaWduaWZpY2F0aXZhLiBEYWRvIHF1ZSBlbCB2YWxvciAkcCQgZXMgbWVub3IgcXVlIDAuMDUsIHNlIHJlY2hhemEgbGEgaGlww7N0ZXNpcyBudWxhICgkSF8wJCksIGluZGljYW5kbyBxdWUgZWwgbW9kZWxvIG51bG8gbm8gc2UgYWp1c3RhIGJpZW4gYSBsb3MgZGF0b3MgeSBxdWUgZXhpc3RlbiByZWxhY2lvbmVzIHNpZ25pZmljYXRpdmFzIGVudHJlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcy4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBzdW1tYXJ5YDogdXNlciB2cyBiYXNlbGluZQ0KDQojIyMgYFVzZXIgdnMgQmFzZWxpbmVgOiBvdXRwdXQgZGUgYHN1bW1hcnlgDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTEpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDQgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjExLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDQgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoYFVzZXIgdnMgQmFzZWxpbmVgKSoqIiwgb3V0LndpZHRoID0gIjgwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xMS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgVXNlciB2cyBCYXNlbGluZWA6IGRlc2NyaXBjacOzbg0KDQoxLiBFbCBgVXNlciBNb2RlbGAgc2UgcmVmaWVyZSBhbCBtb2RlbG8gcXVlIGVsIHVzdWFyaW8gaGEgZXNwZWNpZmljYWRvIHkgcXVlIGBsYXZhYW5gIGVzdMOhIGFuYWxpemFuZG8uDQoNCjIuIEVsIG91dHB1dCBgVXNlciBNb2RlbCB2ZXJzdXMgQmFzZWxpbmUgTW9kZWxgIHNlIHJlZmllcmUgYSBsYSBjb21wYXJhY2nDs24gZW50cmUgZWwgKm1vZGVsbyBlc3BlY2lmaWNhZG8gcG9yIGVsIHVzdWFyaW8qIChgVXNlciBNb2RlbGApIHkgZWwgKm1vZGVsbyBkZSByZWZlcmVuY2lhKiwgdGFtYmnDqW4gY29ub2NpZG8gY29tbyAqbW9kZWxvIGJhc2VsaW5lIG8gbnVsbyogKGBCYXNlbGluZSBNb2RlbGApLiANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFVzZXIgdnMgQmFzZWxpbmVgOiBoaXDDs3Rlc2lzDQoNCioqMS4gSGlww7N0ZXNpcyBOdWxhICgkSF8wJCkuKioNCiAgDQogICsgTGEgaGlww7N0ZXNpcyBudWxhICgkSF8wJCkgZXMgcXVlIGVsIG1vZGVsbyBlc3BlY2lmaWNhZG8gcG9yIGVsIHVzdWFyaW8gbm8gc2UgYWp1c3RhIHNpZ25pZmljYXRpdmFtZW50ZSBtZWpvciBxdWUgZWwgbW9kZWxvIGRlIHJlZmVyZW5jaWEuIA0KICANCiAgKyBFcyBkZWNpciwgbm8gaGF5IGRpZmVyZW5jaWEgc2lnbmlmaWNhdGl2YSBlbnRyZSBlbCBhanVzdGUgZGVsIG1vZGVsbyBkZWwgdXN1YXJpbyB5IGVsIG1vZGVsbyBudWxvLiANCiAgDQogICsgTWF0ZW3DoXRpY2FtZW50ZSwgZXN0byBzZSBwb2Ryw61hIGV4cHJlc2FyIGNvbW86DQogIA0KJCRIXzA6IFx0ZXh0e0VsIFVzZXIgTW9kZWwgc2UgYWp1c3RhIHNpZ25pZmljYXRpdmFtZW50ZSBtZWpvciBxdWUgZWwgQmFzZWxpbmUgTW9kZWx9JCQNCg0KKioyLiBIaXDDs3Rlc2lzIEFsdGVybmF0aXZhICgkSF8xJCkuKioNCiAgDQogICsgTGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YSAoJEhfMSQpIGVzIHF1ZSBlbCBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvIHNlIGFqdXN0YSBzaWduaWZpY2F0aXZhbWVudGUgbWVqb3IgcXVlIGVsIG1vZGVsbyBkZSByZWZlcmVuY2lhLiANCiAgDQogICsgRXMgZGVjaXIsIGhheSB1bmEgZGlmZXJlbmNpYSBzaWduaWZpY2F0aXZhIGVudHJlIGVsIGFqdXN0ZSBkZWwgbW9kZWxvIGRlbCB1c3VhcmlvIHkgZWwgbW9kZWxvIG51bG8uIA0KICANCiAgKyBNYXRlbcOhdGljYW1lbnRlLCBlc3RvIHNlIHBvZHLDrWEgZXhwcmVzYXIgY29tbzoNCg0KJCRIXzE6IFx0ZXh0e0VsIFVzZXIgTW9kZWwgc2UgYWp1c3RhIHNpZ25pZmljYXRpdmFtZW50ZSBtZWpvciBxdWUgZWwgQmFzZWxpbmUgTW9kZWx9JCQNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgVXNlciB2cyBCYXNlbGluZWA6IENGSSB5IFRMSSAoZ2VuZXJhbGlkYWRlcykNCg0KMS4gRXN0YSBjb21wYXJhY2nDs24gcGVybWl0ZSBldmFsdWFyIHF1w6kgdGFuIGJpZW4gc2UgYWp1c3RhIGVsIG1vZGVsbyBwcm9wdWVzdG8gcG9yIGVsIHVzdWFyaW8gZW4gY29tcGFyYWNpw7NuIGNvbiB1biBtb2RlbG8gbXV5IHNpbXBsZSBxdWUgYXN1bWUgaW5kZXBlbmRlbmNpYSBjb21wbGV0YSBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMuDQoNCjIuIExhIGNvbXBhcmFjacOzbiBlbnRyZSBlbCBgVXNlciBNb2RlbGAgeSBlbCBgQmFzZWxpbmUgTW9kZWxgIHByb3BvcmNpb25hIGluZm9ybWFjacOzbiB2YWxpb3NhIHNvYnJlIGxhIGFkZWN1YWNpw7NuIGRlbCBtb2RlbG8gcHJvcHVlc3RvIHBvciBlbCB1c3VhcmlvIGVuIHJlbGFjacOzbiBjb24gdW4gbW9kZWxvIGV4dHJlbWFkYW1lbnRlIHNpbXBsZS4gDQoNCjMuIEVzdG8gc2UgcmVhbGl6YSB1dGlsaXphbmRvIGRpdmVyc29zIGNyaXRlcmlvcyBkZSBhanVzdGUsIGNvbW8gZWwgQ2hpLWN1YWRyYWRvICgkXGNoaV4yJCksIGVsIENvbXBhcmF0aXZlIEZpdCBJbmRleCAoYENGSWApLCBlbCBUdWNrZXItTGV3aXMgSW5kZXggKGBUTElgKSwgZW50cmUgb3Ryb3MuDQoNCjQuIFNpIGVsIG1vZGVsbyBwcm9wdWVzdG8gcG9yIGVsIHVzdWFyaW8gc2UgYWp1c3RhIHNpZ25pZmljYXRpdmFtZW50ZSBtZWpvciBxdWUgZWwgbW9kZWxvIGRlIHJlZmVyZW5jaWEgKHBvciBlamVtcGxvLCB1biBDaGktY3VhZHJhZG8gc2lnbmlmaWNhdGl2YW1lbnRlIG3DoXMgYmFqbyB5L28gdmFsb3JlcyBtw6FzIGFsdG9zIGRlIGBDRklgIHkgYFRMSWApLCBpbmRpY2EgcXVlIGVsIG1vZGVsbyBwcm9wdWVzdG8gcHJvcG9yY2lvbmEgdW4gbWVqb3IgYWp1c3RlIGEgbG9zIGRhdG9zIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgbW9kZWxvIGRlIHJlZmVyZW5jaWEuIA0KDQo1LiBFc3RvIHN1Z2llcmUgcXVlIGxhIGVzdHJ1Y3R1cmEgcHJvcHVlc3RhIGVuIGVsIG1vZGVsbyBkZWwgdXN1YXJpbyBlcyB2w6FsaWRhIHkgcmVwcmVzZW50YSBsYSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcyBkZSBtYW5lcmEgbcOhcyBwcmVjaXNhIHF1ZSBlbCBtb2RlbG8gbnVsby4NCg0KNi4gUG9yIG90cm8gbGFkbywgc2kgZWwgbW9kZWxvIHByb3B1ZXN0byBwb3IgZWwgdXN1YXJpbyBubyBzZSBhanVzdGEgc2lnbmlmaWNhdGl2YW1lbnRlIG1lam9yIHF1ZSBlbCBtb2RlbG8gZGUgcmVmZXJlbmNpYSwgcG9kcsOtYSBpbmRpY2FyIHF1ZSBlbCBtb2RlbG8gcHJvcHVlc3RvIG5vIHByb3BvcmNpb25hIHVuIG1lam9yIGFqdXN0ZSBhIGxvcyBkYXRvcyBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBudWxvLCBsbyBxdWUgc3VnaWVyZSBxdWUgbGEgZXN0cnVjdHVyYSBwcm9wdWVzdGEgcHVlZGUgbm8gc2VyIGFkZWN1YWRhIG8gcXVlIHNlIG5lY2VzaXRhbiBhanVzdGVzIGFkaWNpb25hbGVzIHBhcmEgbWVqb3JhciBsYSBhZGVjdWFjacOzbiBkZWwgbW9kZWxvLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFVzZXIgdnMgQmFzZWxpbmVgOiBDRkkgeSBUTEkgKGludGVycHJldGFjaW9uZXMpDQoNCioqMS4gR2VuZXJhbGlkYWQuKioNCg0KRWwgQ29tcGFyYXRpdmUgRml0IEluZGV4IChDRkkpIHkgZWwgVHVja2VyLUxld2lzIEluZGV4IChUTEkpIHNvbiBkb3Mgw61uZGljZXMgZGUgYWp1c3RlIGNvbcO6bm1lbnRlIHV0aWxpemFkb3MgZW4gZWwgYW7DoWxpc2lzIGZhY3RvcmlhbCBjb25maXJtYXRvcmlvIChDRkEpIHBhcmEgZXZhbHVhciBxdcOpIHRhbiBiaWVuIHNlIGFqdXN0YSB1biBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvIGEgbG9zIGRhdG9zIG9ic2VydmFkb3MgZW4gY29tcGFyYWNpw7NuIGNvbiB1biBtb2RlbG8gZGUgcmVmZXJlbmNpYSwgY29tbyBlbCBtb2RlbG8gbnVsbyBvIGJhc2VsaW5lLiBCQXNhZG8gZW4gbG9zIHJlc3VsdGFkb3MgZW5jb250cmFkb3MgKHBhcnRlIE5vLiA0IGRlbCBvdXRwdXQpLCBlc3RvcyB2YWxvcmVzIHNlIHB1ZGVuIGludGVycHJldGFyIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCioqMi4gQ29tcGFyYXRpdmUgRml0IEluZGV4IChgQ0ZJYCkuKioNCiAgDQogICsgRWwgQ0ZJIGVzIHVuIMOtbmRpY2UgcXVlIGV2YWzDumEgcXXDqSB0YW4gYmllbiBzZSBhanVzdGEgZWwgbW9kZWxvIGVzcGVjaWZpY2FkbyBwb3IgZWwgdXN1YXJpbyBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBudWxvLiANCiAgDQogICsgVW4gQ0ZJIGNlcmNhbm8gYSAxIGluZGljYSB1biBidWVuIGFqdXN0ZSBkZWwgbW9kZWxvLCBkb25kZSB1biB2YWxvciBkZSAxIGluZGljYSB1biBhanVzdGUgcGVyZmVjdG8uDQogIA0KICArIEVuIGdlbmVyYWwsIHVuIHZhbG9yIGRlIENGSSBtYXlvciBhIDAuOTAgc2UgY29uc2lkZXJhIGFjZXB0YWJsZSwgYXVucXVlIHZhbG9yZXMgbcOhcyBjZXJjYW5vcyBhIDAuOTUgbyBtYXlvcmVzIGluZGljYW4gdW4gbWVqb3IgYWp1c3RlLg0KICANCiAgKyAqSW50ZXJwcmV0YWNpw7NuOiogVW4gQ0ZJIGRlIDAuOTMxIHN1Z2llcmUgcXVlIGVsIG1vZGVsbyBlc3BlY2lmaWNhZG8gcG9yIGVsIHVzdWFyaW8gZXhwbGljYSBhcHJveGltYWRhbWVudGUgZWwgOTMuMSUgZGUgbGEgdmFyaWFuemEgeSBsYSBjb3ZhcmlhbnphIG9ic2VydmFkYSBlbiBsb3MgZGF0b3MsIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgbW9kZWxvIG51bG8uIA0KICANCg0KKiozLiBUdWNrZXItTGV3aXMgSW5kZXggKGBUTElgKS4qKg0KICANCiAgKyBFbCBUTEksIHRhbWJpw6luIGNvbm9jaWRvIGNvbW8gTm9uLU5vcm1lZCBGaXQgSW5kZXggKE5ORkkpLCBlcyBvdHJvIMOtbmRpY2UgZGUgYWp1c3RlIHF1ZSBldmFsw7phIHF1w6kgdGFuIGJpZW4gc2UgYWp1c3RhIGVsIG1vZGVsbyBlc3BlY2lmaWNhZG8gcG9yIGVsIHVzdWFyaW8gZW4gY29tcGFyYWNpw7NuIGNvbiBlbCBtb2RlbG8gbnVsby4gDQogIA0KICArIEFsIGlndWFsIHF1ZSBjb24gZWwgQ0ZJLCB1biB2YWxvciBkZSBUTEkgbWF5b3IgYSAwLjkwIHNlIGNvbnNpZGVyYSBhY2VwdGFibGUsIGF1bnF1ZSB2YWxvcmVzIG3DoXMgY2VyY2Fub3MgYSAwLjk1IG8gbWF5b3JlcyBpbmRpY2FuIHVuIG1lam9yIGFqdXN0ZS4NCiAgDQogICsgKkludGVycHJldGFjacOzbjoqIFVuIFRMSSBkZSAwLjg5NiBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvIGV4cGxpY2EgYXByb3hpbWFkYW1lbnRlIGVsIDg5LjYlIGRlIGxhIHZhcmlhbnphIHkgbGEgY292YXJpYW56YSBvYnNlcnZhZGEgZW4gbG9zIGRhdG9zLCBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBudWxvLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBzdW1tYXJ5YDogbG9nbGlrIGFuZCBjcml0ZXJpb3MNCg0KIyMjIGBMb2dsaWsgYW5kIENyaXRlcmlhYDogb3V0cHV0IGdyw6FmaWNvDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTIpIHNlIHJlc2FsdGEgbGEgcGFydGUgTm8uIDUgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjEyLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDUgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YCAoYExvZ2xpa2VsaWhvb2QgYW5kIEluZm9ybWF0aW9uIENyaXRlcmlhYCkqKiIsIG91dC53aWR0aCA9ICI5MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTIucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYExvZ2xpayBhbmQgQ3JpdGVyaWFgOiBsb2ctdmVyb3NpbWlsaXR1ZA0KDQpFc3RvcyByZXN1bHRhZG9zIHBlcnRlbmVjZW4gYSBsYSBjb21wYXJhY2nDs24gZGVsIG1vZGVsbyBkZWwgdXN1YXJpbyAobW9kZWxvIGVzcGVjaWZpY2FkbykgY29uIGVsIG1vZGVsbyBkZSByZWZlcmVuY2lhIChtb2RlbG8gbnVsbykgZW4gdMOpcm1pbm9zIGRlIGxhIGZ1bmNpw7NuIGRlIHZlcm9zaW1pbGl0dWQgbG9nYXLDrXRtaWNhLiBBcXXDrSBlc3TDoSBzdSBpbnRlcnByZXRhY2nDs246DQoNCioqMS4gTG9nbGlrZWxpaG9vZCBkZWwgbW9kZWxvIGRlbCB1c3VhcmlvICgkSF8wJCkuKioNCg0KRWwgdmFsb3IgZGUgbGEgbG9nLXZlcm9zaW1pbGl0dWQgKGBsb2dsaWtlbGlob29kYCkgcGFyYSBlbCBtb2RlbG8gZGVsIHVzdWFyaW8sIHF1ZSBlcyBlbCBtb2RlbG8gZXNwZWNpZmljYWRvIHBvciBlbCB1c3VhcmlvLiBFbiBlc3RlIGNhc28sIGVsIGxvZ2xpa2VsaWhvb2QgZGVsIG1vZGVsbyBkZWwgdXN1YXJpbyBlcyAtMzczNy43NDUuDQoNCioqMi4gTG9nbGlrZWxpaG9vZCBkZWwgbW9kZWxvIG5vIHJlc3RyaW5naWRvICgkSF8xJCkuKioNCg0KRWwgdmFsb3IgZGUgbGEgbG9nLXZlcm9zaW1pbGl0dWQgcGFyYSBlbCBtb2RlbG8gbm8gcmVzdHJpbmdpZG8sIHF1ZSBlcyB1biBtb2RlbG8gZG9uZGUgbm8gc2UgaW1wb25lbiByZXN0cmljY2lvbmVzIChlcyBkZWNpciwgdW4gbW9kZWxvIGRvbmRlIHRvZGFzIGxhcyBjb3ZhcmlhbnphcyBzb24gbGlicmVzIGRlIHNlciBlc3RpbWFkYXMpLiBFbiBlc3RlIGNhc28sIGVsIGxvZ2xpa2VsaWhvb2QgZGVsIG1vZGVsbyBubyByZXN0cmluZ2lkbyBlcyAtMzY5NS4wOTIuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYExvZ2xpayBhbmQgQ3JpdGVyaWFgOiBjcml0ZXJpb3MgZGUgSW5mb3JtYWNpw7NuDQoNCkVzdG9zIHJlc3VsdGFkb3MgcGVydGVuZWNlbiBhIGxhIGNvbXBhcmFjacOzbiBkZWwgbW9kZWxvIGRlbCB1c3VhcmlvIChtb2RlbG8gZXNwZWNpZmljYWRvKSBjb24gZWwgbW9kZWxvIGRlIHJlZmVyZW5jaWEgKG1vZGVsbyBudWxvKSBlbiB0w6lybWlub3MgZGUgIHZhcmlvcyBjcml0ZXJpb3MgZGUgaW5mb3JtYWNpw7NuLiBBcXXDrSBlc3TDoSBzdSBpbnRlcnByZXRhY2nDs246DQoNCioqMS4gQ3JpdGVyaW8gZGUgSW5mb3JtYWNpw7NuIGRlIEFrYWlrZSAoQUlDKS4qKg0KDQpVbiBjcml0ZXJpbyBkZSBzZWxlY2Npw7NuIGRlIG1vZGVsbyBxdWUgcGVuYWxpemEgZWwgc29icmVhanVzdGUgZGVsIG1vZGVsbyBhbCB0ZW5lciBlbiBjdWVudGEgZWwgbsO6bWVybyBkZSBwYXLDoW1ldHJvcyBlc3RpbWFkb3MuIFNlIHByZWZpZXJlIHVuIHZhbG9yIGRlIEFJQyBtw6FzIGJham8sIGxvIHF1ZSBpbmRpY2EgdW4gbWVqb3IgZXF1aWxpYnJpbyBlbnRyZSBlbCBhanVzdGUgZGVsIG1vZGVsbyB5IGxhIGNvbXBsZWppZGFkIGRlbCBtb2RlbG8uIEVuIGVzdGUgY2FzbywgZWwgdmFsb3IgZGVsIEFJQyBlcyA3NTE3LjQ5MC4NCg0KKioyLiBDcml0ZXJpbyBkZSBJbmZvcm1hY2nDs24gQmF5ZXNpYW5hIChCSUMpLioqDQoNClNpbWlsYXIgYWwgQUlDIHBlcm8gY29uIHVuYSBwZW5hbGl6YWNpw7NuIG3DoXMgZnVlcnRlIHBvciBlbCBuw7ptZXJvIGRlIHBhcsOhbWV0cm9zLiBTZSBwcmVmaWVyZSB1biB2YWxvciBkZSBCSUMgbcOhcyBiYWpvLCBsbyBxdWUgaW5kaWNhIHVuIG1lam9yIGVxdWlsaWJyaW8gZW50cmUgZWwgYWp1c3RlIGRlbCBtb2RlbG8geSBsYSBjb21wbGVqaWRhZCBkZWwgbW9kZWxvLiBFbiBlc3RlIGNhc28sIGVsIHZhbG9yIGRlbCBCSUMgZXMgNzU5NS4zMzkuDQoNCioqMy4gQ3JpdGVyaW8gZGUgSW5mb3JtYWNpw7NuIEJheWVzaWFuYSBBanVzdGFkbyBwb3IgZWwgVGFtYcOxbyBkZSBsYSBNdWVzdHJhIChTQUJJQykuKioNCg0KVW5hIHZhcmlhbnRlIGRlbCBCSUMgcXVlIHRhbWJpw6luIHRpZW5lIGVuIGN1ZW50YSBlbCB0YW1hw7FvIGRlIGxhIG11ZXN0cmEuIFNlIHByZWZpZXJlIHVuIHZhbG9yIGRlIFNBQklDIG3DoXMgYmFqbywgbG8gcXVlIGluZGljYSB1biBtZWpvciBlcXVpbGlicmlvIGVudHJlIGVsIGFqdXN0ZSBkZWwgbW9kZWxvLCBsYSBjb21wbGVqaWRhZCBkZWwgbW9kZWxvIHkgZWwgdGFtYcOxbyBkZSBsYSBtdWVzdHJhLiBFbiBlc3RlIGNhc28sIGVsIHZhbG9yIGRlbCBTQUJJQyBlcyA3NTI4LjczOS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgTG9nbGlrIGFuZCBDcml0ZXJpYWA6IEludGVycHJldGFjaW9uZXMgZ2VuZXJhbGVzDQoNCjEuIEVuIGdlbmVyYWwsIHNlIHByZWZpZXJlIHVuIGBsb2dsaWtlbGlob29kYCBtw6FzIGFsdG8sIHlhIHF1ZSBpbmRpY2EgdW4gbWVqb3IgYWp1c3RlIGRlbCBtb2RlbG8gYSBsb3MgZGF0b3MuDQoNCjIuIFBhcmEgbG9zIGNyaXRlcmlvcyBkZSBpbmZvcm1hY2nDs24gKGBBSUNgLCBgQklDYCwgYFNBQklDYCksIHNlIHByZWZpZXJlbiB2YWxvcmVzIG3DoXMgYmFqb3MsIGxvIHF1ZSBpbmRpY2EgdW4gbWVqb3IgZXF1aWxpYnJpbyBlbnRyZSBlbCBhanVzdGUgZGVsIG1vZGVsbyB5IGxhIGNvbXBsZWppZGFkIGRlbCBtb2RlbG8uDQoNCjMuIEVuIGVzdGUgY2FzbywgZWwgbW9kZWxvIG5vIHJlc3RyaW5naWRvICgkSF8xJCkgdGllbmUgdW4gbG9nbGlrZWxpaG9vZCBtw6FzIGFsdG8geSB2YWxvcmVzIG3DoXMgYmFqb3MgcGFyYSBsb3MgY3JpdGVyaW9zIGRlIGluZm9ybWFjacOzbiBlbiBjb21wYXJhY2nDs24gY29uIGVsIG1vZGVsbyBkZWwgdXN1YXJpbyAoJEhfMCQpLiANCg0KNC4gRXN0byBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gbm8gcmVzdHJpbmdpZG8gcHJvcG9yY2lvbmEgdW4gbWVqb3IgYWp1c3RlIGEgbG9zIGRhdG9zIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgbW9kZWxvIGRlbCB1c3VhcmlvLg0KDQo1LiBTaW4gZW1iYXJnbywgbGEgZWxlY2Npw7NuIGRlbCBtb2RlbG8gZmluYWwgZGViZSBiYXNhcnNlIGVuIHVuYSBldmFsdWFjacOzbiBjb21wbGV0YSBxdWUgY29uc2lkZXJlIHRhbnRvIGVsIGFqdXN0ZSBkZWwgbW9kZWxvIGNvbW8gbGEgdGVvcsOtYSBzdWJ5YWNlbnRlIHkgbG9zIG9iamV0aXZvcyBkZSBpbnZlc3RpZ2FjacOzbi4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYHN1bW1hcnlgOiBSTVNFQQ0KDQojIyMgYFJvb3QgTWVhbiBTcXVhcmVgOiBvdXRwdXQgZ3LDoWZpY28NCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4xMykgc2UgcmVzYWx0YSBsYSBwYXJ0ZSBOby4gMyBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgLiAgDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuMTMsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQYXJ0ZSBOby4gNiBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgIChgUm9vdCBNZWFuIFNxdWFyZWApKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xMy5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgUm9vdCBNZWFuIFNxdWFyZWA6IGdlbmVyYWxpZGFkZXMNCg0KUGFyYSBpbnRlcnByZXRhciBlbCBSb290IE1lYW4gU3F1YXJlIEVycm9yIG9mIEFwcHJveGltYXRpb24gKFJNU0VBKSB5IGVsIFN0YW5kYXJkaXplZCBSb290IE1lYW4gU3F1YXJlIFJlc2lkdWFsIChTUk1SKSwgc2UgbmVjZXNpdGFuIGFsZ3Vub3MgZGV0YWxsZXMgYWRpY2lvbmFsZXMgc29icmUgZWwgY29udGV4dG8gZGVsIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbyAoQ0ZBKSB5IGxvcyBjcml0ZXJpb3MgZGUgYWp1c3RlIHV0aWxpemFkb3MuIEVzdG9zIHZhbG9yZXMgc2UgdXRpbGl6YW4gcGFyYSBldmFsdWFyIGVsIGFqdXN0ZSBkZWwgbW9kZWxvIHByb3B1ZXN0byBhIGxvcyBkYXRvcyBvYnNlcnZhZG9zLiBBcXXDrSBlc3TDoSBsYSBpbnRlcnByZXRhY2nDs246DQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFJvb3QgTWVhbiBTcXVhcmVgOiBSTVNFQSAoaW50ZXJwcmV0YWNpw7NuKQ0KDQoxLiBFbCBgUk1TRUFgICgqUmHDrXogZGVsIEVycm9yIEN1YWRyw6F0aWNvIE1lZGlvIGRlIEFwcm94aW1hY2nDs24qKSBlcyB1bmEgbWVkaWRhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIHF1ZSBpbmRpY2EgY3XDoW50byBzZSBlc3BlcmEgcXVlIGVsIG1vZGVsbyBzZSBkZXN2w61lIGRlIGxvcyBkYXRvcyBwb2JsYWNpb25hbGVzIGVuIHTDqXJtaW5vcyBkZSBsYSBtZWRpZGEgZGUgZXJyb3IgY3VhZHLDoXRpY28gbWVkaW8uDQoNCjIuIEdlbmVyYWxtZW50ZSwgc2UgY29uc2lkZXJhIHF1ZSB1biB2YWxvciBkZSBSTVNFQSBtZW5vciBvIGlndWFsIGEgMC4wNSBpbmRpY2EgdW4gYnVlbiBhanVzdGUsIHZhbG9yZXMgZW50cmUgMC4wNSB5IDAuMDggaW5kaWNhbiB1biBhanVzdGUgbW9kZXJhZG8geSB2YWxvcmVzIHN1cGVyaW9yZXMgYSAwLjEgaW5kaWNhbiB1biBhanVzdGUgZGVmaWNpZW50ZS4NCg0KMy4gRW4gbnVlc3RybyBvdXRwdXQsICRSTVNFQSA9IDAuMDkyJC4NCg0KNC4gRXN0ZSB2YWxvciBpbmRpY2EgcXVlIGVsIG1vZGVsbyBwcm9wdWVzdG8gdGllbmUgdW4gYWp1c3RlIG1vZGVyYWRvIGEgbG9zIGRhdG9zLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBSb290IE1lYW4gU3F1YXJlYDogUk1TRUEgKGA5MCUgSUNgKQ0KDQoxLiBFbCBpbnRlcnZhbG8gZGUgQ29uZmlhbnphIGRlbCA5MCUgKGA5MCBQZXJjZW50IGNvbmZpZGVuY2UgaW50ZXJ2YWxgKSAgUHJvcG9yY2lvbmEgdW5hIGVzdGltYWNpw7NuIGRlIGxhIHByZWNpc2nDs24gZGVsIFJNU0VBLiANCg0KMi4gTG9zIGzDrW1pdGVzIGluZmVyaW9yIHkgc3VwZXJpb3IgZGVsIGludGVydmFsbyBkZSBjb25maWFuemEgaW5kaWNhbiBlbCByYW5nbyBwbGF1c2libGUgZGUgdmFsb3JlcyBkZSBSTVNFQS4gDQoNCjMuIEVuIGVzdGUgY2FzbywgZWwgSUMgOTAlIHZhIGRlc2RlIDAuMDcxIGhhc3RhIDAuMTE0Lg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBSb290IE1lYW4gU3F1YXJlYDogUk1TRUEgKGBQLXZhbHVlYCkNCg0KKioxLiBQLXZhbHVlIEgwOiBSTVNFQSA8PSAwLjA1MCA9IDAuMDAxLioqDQogIA0KICArIEVzdGUgdmFsb3IgJHAkIGVzIGVsIHJlc3VsdGFkbyBkZSB1bmEgcHJ1ZWJhIGRlIGhpcMOzdGVzaXMgc29icmUgc2kgZWwgUk1TRUEgZXMgbWVub3IgbyBpZ3VhbCBhIDAuMDUuIA0KICANCiAgKyBVbiB2YWxvciBwIGJham8gKHBvciBkZWJham8gZGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgY29tw7puIGRlIDAuMDUpIHN1Z2llcmUgcXVlIGVsIG1vZGVsbyBubyBzZSBhanVzdGEgYmllbiBhIGxvcyBkYXRvcywgeWEgcXVlIGVsIFJNU0VBIGVzIHNpZ25pZmljYXRpdmFtZW50ZSBtYXlvciBxdWUgMC4wNS4NCg0KKioyLiBQLXZhbHVlIEgwOiBSTVNFQSA+PSAwLjA4MCA9IDAuODQwLioqDQogIA0KICArIEVzdGUgdmFsb3IgcCBlcyBlbCByZXN1bHRhZG8gZGUgdW5hIHBydWViYSBkZSBoaXDDs3Rlc2lzIHNvYnJlIHNpIGVsIFJNU0VBIGVzIG1heW9yIG8gaWd1YWwgYSAwLjA4LiANCiAgDQogICsgVW4gdmFsb3IgcCBhbHRvIChwb3IgZW5jaW1hIGRlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIGNvbcO6biBkZSAwLjA1KSBzdWdpZXJlIHF1ZSBlbCBtb2RlbG8gc2UgYWp1c3RhIGJpZW4gYSBsb3MgZGF0b3MsIHlhIHF1ZSBlbCBSTVNFQSBubyBlcyBzaWduaWZpY2F0aXZhbWVudGUgbWF5b3IgcXVlIDAuMDguDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgUm9vdCBNZWFuIFNxdWFyZWA6IFNSTVIgIChpbnRlcnByZXRhY2nDs24pDQoNCjEuIEVsIGBTUk1SYCAoKlJlc2lkdWFsIEVzdGFuZGFyaXphZG8gZGVsIEVycm9yIEN1YWRyw6F0aWNvIE1lZGlvIGRlIEFwcm94aW1hY2nDs24qKSBlcyB1bmEgbWVkaWRhIGRlIGFqdXN0ZSBkZWwgbW9kZWxvIHF1ZSBpbmRpY2EgY3XDoW50byBzZSBlc3BlcmEgcXVlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIGRlIGxvcyByZXNpZHVvcyBlc3RhbmRhcml6YWRvcyBzZSBkZXN2w61lIGRlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphIGRlIHJlc2lkdW9zIHBvYmxhY2lvbmFsZXMuDQoNCjIuIEdlbmVyYWxtZW50ZSwgc2UgY29uc2lkZXJhIHF1ZSB1biB2YWxvciBkZSBTUk1SIG1lbm9yIG8gaWd1YWwgYSAwLjA4IGluZGljYSB1biBidWVuIGFqdXN0ZSwgbWllbnRyYXMgcXVlIHZhbG9yZXMgc3VwZXJpb3JlcyBhIDAuMSBpbmRpY2FuIHVuIGFqdXN0ZSBkZWZpY2llbnRlLg0KDQozLiBFbiBudWVzdHJvIG91dHB1dCwgJFNSTVIgPSAwLjA2NSQuIA0KDQo0LiBFc3RlIHZhbG9yIGluZGljYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byB0aWVuZSB1biBhanVzdGUgbW9kZXJhZG8gYSBsb3MgZGF0b3MuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYFJvb3QgTWVhbiBTcXVhcmVgOiBSTVNFQSB5IFNSTVIgKGNvbmNsdXNpb25lcykgDQoNCjEuIEVuIHJlc3VtZW4sIGVzdG9zIHZhbG9yZXMgZGUgYWp1c3RlIChSTVNFQSB5IFNSTVIpIHN1Z2llcmVuIHF1ZSBlbCBtb2RlbG8gcHJvcHVlc3RvIHRpZW5lIHVuIGFqdXN0ZSBtb2RlcmFkbyBhIGxvcyBkYXRvcy4gDQoNCjIuIEEgcGVzYXIgZGUgbG8gYW50ZXJpb3I6DQogIA0KICArIEVsIFJNU0VBIHN1Z2llcmUgdW4gYWp1c3RlIGFsZ28gZGVmaWNpZW50ZSBkZWJpZG8gYSBzdSB2YWxvciBjZXJjYW5vIGEgMC4xLiANCiAgDQogICsgWSBlbCB2YWxvciAkcCQgYXNvY2lhZG8gY29uICRSTVNFQSBcbGVxIDAuMDUwJCB0YW1iacOpbiBzdWdpZXJlIHVuYSBtYWxhIGFkYXB0YWNpw7NuLg0KICANCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgc3VtbWFyeWA6IGVzdGltYWNpw7NuIGRlIHBhcsOhbWV0cm9zDQoNCiMjIyBgRXN0aW1hdGVzYDogb3V0cHV0IGdyw6FmaWNvDQoNCjEuIFNlIHByb3BvcmNpb25hbiBlc3RpbWFjaW9uZXMgZGUgbG9zIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8sIGNvbW8gbGFzIGNhcmdhcyBmYWN0b3JpYWxlcywgY292YXJpYW56YXMgZW50cmUgdmFyaWFibGVzIGxhdGVudGVzIHkgdmFyaWFuemFzIGRlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyB5IGxhdGVudGVzLCBlbnRyZSBvdHJvcy4NCg0KMi4gQ2FkYSBmaWxhIHJlcHJlc2VudGEgdW5hIHJlbGFjacOzbiBlbnRyZSB2YXJpYWJsZXMgb2JzZXJ2YWRhcyB5IGxhdGVudGVzIG8gZW50cmUgdmFyaWFibGVzIGxhdGVudGVzLCBtb3N0cmFuZG8gZWwgZXN0aW1hZG8gZGUgbGEgcmVsYWNpw7NuLCBzdSBlcnJvciBlc3TDoW5kYXIsIHZhbG9yICR6JCB5IHZhbG9yICRwJCBhc29jaWFkby4NCg0KMy4gRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4xNCkgc2UgcmVzYWx0YSBsYSBwYXJ0ZSBOby4gNiBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgLiAgDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuMTQsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQYXJ0ZSBOby4gNiBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgIChgUGFyYW1ldGVyIEVzdGltYXRlc2ApKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xNC5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBFc3RpbWF0ZXNgOiBvdXRwdXQgZ3LDoWZpY28gKGV4cGxpY2FjaW9uZXMpDQoNCkVuIGVsIGdyw6FmaWNvIGFudGVyaW9yLCB2ZW1vcyBjdWF0cm8gcGFydGVzIChleHBsaWNhcmVtb3MgY2FkYSB1bmEgZGUgZWxsYXMgZW4gc2VjY2lvbmVzIHNpZ3VpZW50ZXMpOg0KDQoxLiAqKlBhcnRlIDZhOioqIEluZm9ybWFjacOzbiBnZW5lcmFsLg0KDQoyLiAqKlBhcnRlIDZiOioqIEVzdGltYWNpb25lcyBkZSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIGRlIGxhcyB2YXJpYWJsZXMgbGF0ZW50ZXMgKGB2aXN1YWxgLCBgdGV4dHVhbGAsIGBzcGVlZGApIGVuIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyAoYHgxYCwgLi4uLGB4OWApLg0KDQoyLiAqKlBhcnRlIDZjOioqIEVzdGltYWNpb25lcyBkZSBsYXMgY292YXJpYW56YXMgZW50cmUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcy4NCg0KMi4gKipQYXJ0ZSA2ZDoqKiBFc3RpbWFjaW9uZXMgZGUgbGFzIHZhcmlhbnphcyBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgIHkgbGF0ZW50ZXMuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgT3V0cHV0IGRlIGBFc3RpbWF0ZWA6IDZhIChpbmZvcm1hY2nDs24gZ2VuZXJhbCkNCg0KIyMjIGBFc3RpbWF0ZWA6IHBhcnRlIDZhIChvdXRwdXQgZ3LDoWZpY28pDQoNCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4xNSkgc2UgcmVzYWx0YSBsYSBwYXJ0ZSBOby4gNmEgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE1LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDZhIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGBHZW5lcmFsIGluZm9ybWF0aW9uYCkqKiIsIG91dC53aWR0aCA9ICI4MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygibGF2YWFuMTUucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgRXN0aW1hdGVgOiA2YSAoYGluZm9ybWFjacOzbiBnZW5lcmFsYCkNCg0KIyMjIGBFc3RpbWF0ZWA6IHBhcnRlIDZhIChpbnRlcnByZXRhY2lvbmVzKQ0KDQpMYSBzZWNjacOzbiBkZSBgUGFyYW1ldGVyIEVzdGltYXRlc2AgZW4gZWwgcmVzdW1lbiBkZSByZXN1bHRhZG9zIGRlIGxhdmFhbiBjb250aWVuZSBpbmZvcm1hY2nDs24gaW1wb3J0YW50ZSBzb2JyZSBsb3MgZXJyb3JlcyBlc3TDoW5kYXIgeSBsYSBpbmZvcm1hY2nDs24gdXRpbGl6YWRhIHBhcmEgY2FsY3VsYXJsb3MuIEFxdcOtIGhheSB1bmEgaW50ZXJwcmV0YWNpw7NuIGRldGFsbGFkYSBkZSBsYXMgbMOtbmVhcyBlc3BlY8OtZmljYXMgcXVlIHNlIGhhbiBtZW5jaW9uYWRvOg0KDQoqKjEuIFN0YW5kYXJkIEVycm9ycyAoRXJyb3JlcyBFc3TDoW5kYXIpLioqDQogIA0KICArIEluZGljYSBxdWUgbG9zIGVycm9yZXMgZXN0w6FuZGFyIGhhbiBzaWRvIGNhbGN1bGFkb3MuDQogIA0KICArIExvcyBlcnJvcmVzIGVzdMOhbmRhciBzb24gbWVkaWRhcyBkZSBsYSBwcmVjaXNpw7NuIGRlIGxhcyBlc3RpbWFjaW9uZXMgZGUgbG9zIHBhcsOhbWV0cm9zOyB2YWxvcmVzIG3DoXMgcGVxdWXDsW9zIGluZGljYW4gZXN0aW1hY2lvbmVzIG3DoXMgcHJlY2lzYXMuDQoNCioqMi4gSW5mb3JtYXRpb24gKEluZm9ybWFjacOzbikuKioNCiAgDQogICsgRXN0YSBsw61uZWEgZGVzY3JpYmUgZWwgdGlwbyBkZSBpbmZvcm1hY2nDs24gcXVlIHNlIHV0aWxpesOzIHBhcmEgY2FsY3VsYXIgbG9zIGVycm9yZXMgZXN0w6FuZGFyLiANCiAgDQogICsgRXhpc3RlbiBkaWZlcmVudGVzIG3DqXRvZG9zIHBhcmEgY2FsY3VsYXIgbGEgbWF0cml6IGRlIGluZm9ybWFjacOzbi4NCiAgDQogICsgTGEgZWxlY2Npw7NuIGRlbCBtw6l0b2RvIHB1ZWRlIGluZmx1aXIgZW4gbG9zIGVycm9yZXMgZXN0w6FuZGFyIHksIHBvciBsbyB0YW50bywgZW4gbGFzIHBydWViYXMgZGUgc2lnbmlmaWNhbmNpYS4NCiAgDQoNCioqMy4gSW5mb3JtYXRpb24gU2F0dXJhdGVkIChIMSkgTW9kZWwuKioNCiAgDQogICsgTGEgbWF0cml6IGRlIGluZm9ybWFjacOzbiBkZWwgKm1vZGVsbyBzYXR1cmFkbyogKHRhbWJpw6luIGNvbm9jaWRvIGNvbW8gZWwgKm1vZGVsbyAiaDEiKikgc2UgdXRpbGl6YSBwYXJhIGNhbGN1bGFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhci4gDQogIA0KICArIFVuIG1vZGVsbyBzYXR1cmFkbyBlcyB1biBtb2RlbG8gcXVlIHRpZW5lIHRhbnRvcyBwYXLDoW1ldHJvcyBjb21vIHNlYSBwb3NpYmxlIHBhcmEgYWp1c3RhcnNlIHBlcmZlY3RhbWVudGUgYSBsb3MgZGF0b3MuIA0KICANCiAgKyBFbiBvdHJhcyBwYWxhYnJhcywgZXMgdW4gbW9kZWxvIHF1ZSBhc3VtZSBxdWUgdG9kYXMgbGFzIHZhcmlhYmxlcyBlc3TDoW4gY29ycmVsYWNpb25hZGFzIGxpYnJlbWVudGUuIA0KICANCiAgKyBMYSBtYXRyaXogZGUgaW5mb3JtYWNpw7NuIGRlbCBtb2RlbG8gc2F0dXJhZG8gcHVlZGUgcHJvcG9yY2lvbmFyIHVuYSBlc3RpbWFjacOzbiByb2J1c3RhIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSBsb3MgcGFyw6FtZXRyb3MgZGVsIG1vZGVsby4NCg0KKio0LiBTdHJ1Y3R1cmVkIEluZm9ybWF0aW9uLioqDQogIA0KICArIExhIGluZm9ybWFjacOzbiBlc3RydWN0dXJhZGEgc2UgcmVmaWVyZSBhIGxhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24gZGVyaXZhZGEgZGVsIG1vZGVsbyBlc3BlY8OtZmljbyBxdWUgc2UgZXN0w6EgZXZhbHVhbmRvIChlbCBtb2RlbG8gZGVsIHVzdWFyaW8pLiANCiAgDQogICsgRXN0YSBtYXRyaXogc2UgYmFzYSBlbiBsYXMgcmVzdHJpY2Npb25lcyB5IGVzcGVjaWZpY2FjaW9uZXMgZGVsIG1vZGVsbyBkZWwgdXN1YXJpby4gUHJvcG9yY2lvbmEgdW5hIHZpc2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBwYXLDoW1ldHJvcyB0YWwgY29tbyBzZSBlc3RydWN0dXJhIGVuIGVsIG1vZGVsbyBlc3BlY2lmaWNhZG8uDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYEVzdGltYXRlYDogcGFydGUgNmEgKGludGVycHJldGFjacOzbiBnZW5lcmFsKQ0KDQoxLiBTdGFuZGFyZCBlcnJvcnM6IEVzcGVjaWZpY2EgcXVlIHNlIGhhbiBjYWxjdWxhZG8gbG9zIGVycm9yZXMgZXN0w6FuZGFyIHBhcmEgbGFzIGVzdGltYWNpb25lcyBkZSBsb3MgcGFyw6FtZXRyb3MgZGVsIG1vZGVsby4NCg0KMi4gSW5mb3JtYXRpb246IERlc2NyaWJlIHF1ZSBsYSBtYXRyaXogZGUgaW5mb3JtYWNpw7NuIGhhIHNpZG8gdXRpbGl6YWRhIHBhcmEgY2FsY3VsYXIgZXN0b3MgZXJyb3JlcyBlc3TDoW5kYXIuDQoNCg0KMy4gSW5mb3JtYXRpb24gc2F0dXJhdGVkIChoMSkgbW9kZWw6IEluZGljYSBxdWUgbGEgbWF0cml6IGRlIGluZm9ybWFjacOzbiBkZWwgbW9kZWxvIHNhdHVyYWRvIHNlIGhhIHV0aWxpemFkbyBwYXJhIGNhbGN1bGFyIGxvcyBlcnJvcmVzIGVzdMOhbmRhci4gRXN0ZSBlbmZvcXVlIHB1ZWRlIHNlciBtw6FzIHJvYnVzdG8gcG9ycXVlIG5vIGRlcGVuZGUgZGUgbGFzIHJlc3RyaWNjaW9uZXMgZGVsIG1vZGVsbyBlc3BlY8OtZmljby4NCg0KNC4gU3RydWN0dXJlZCBJbmZvcm1hdGlvbjogU2UgcmVmaWVyZSBhIGxhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24gY2FsY3VsYWRhIGRpcmVjdGFtZW50ZSBhIHBhcnRpciBkZWwgbW9kZWxvIGRlbCB1c3VhcmlvLCBxdWUgaW5jbHV5ZSB0b2RhcyBsYXMgZXNwZWNpZmljYWNpb25lcyB5IHJlc3RyaWNjaW9uZXMgaW1wdWVzdGFzIHBvciBlbCB1c3VhcmlvIGVuIGVsIG1vZGVsby4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVgOiBwYXJ0ZSA2YSAoY29uY2x1Y2nDs24gZ2VuZXJhbCkNCg0KMS4gRW4gcmVzdW1lbiwgZXN0YSBzZWNjacOzbiBkZWwgcmVzdW1lbiBkZSByZXN1bHRhZG9zIGRlIGxhdmFhbiBub3MgaW5mb3JtYSBxdWUgbG9zIGVycm9yZXMgZXN0w6FuZGFyIHNlIGhhbiBjYWxjdWxhZG8gdXRpbGl6YW5kbyB0YW50byBsYSBtYXRyaXogZGUgaW5mb3JtYWNpw7NuIGRlbCBtb2RlbG8gc2F0dXJhZG8gKGgxKSBjb21vIGxhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24gZXN0cnVjdHVyYWRhIGRlbCBtb2RlbG8gZGVsIHVzdWFyaW8uIA0KDQoyLiBFc3RlIGVuZm9xdWUgcHJvcG9yY2lvbmEgdW5hIHZpc2nDs24gcm9idXN0YSB5IGVzdHJ1Y3R1cmFkYSBkZSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8geSBkZSBsYSBwcmVjaXNpw7NuIGRlIGxhcyBlc3RpbWFjaW9uZXMgZGUgbG9zIHBhcsOhbWV0cm9zLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYEVzdGltYXRlYDogNmIgKGBsYXRlbnQgdmFyaWFibGVzYCkNCg0KIyMjIGBFc3RpbWF0ZXNgOiBwYXJ0ZSA2YiAob3V0cHV0IGdyw6FmaWNvKQ0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjE2KSBzZSByZXNhbHRhIGxhIHBhcnRlIE5vLiA2YiBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgLiAgDQo8Y2VudGVyPg0KYGBge3IgbGF2YWFuMTYsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQYXJ0ZSBOby4gNiBkZWwgb3V0cHV0IGRlIGBsYXZhYW46OnN1bW1hcnlgIChgTGF0ZW50IHZhcmlhYmxlc2ApKioiLCBvdXQud2lkdGggPSAiOTAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjE2LnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+IA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmIgKGdlbmVyYWxpZGFkZXMpDQoNCjEuIFNlIHByZXNlbnRhbiBsYXMgZXN0aW1hY2lvbmVzIGRlIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMgZGUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcyAoYHZpc3VhbGAsIGB0ZXh0dWFsYCwgYHNwZWVkYCkgZW4gbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIChgeDFgLCAuLi4sYHg5YCkuDQoNCjIuIFBhcmEgY2FkYSByZWxhY2nDs24gZW50cmUgdW5hIHZhcmlhYmxlIGxhdGVudGUgeSBzdXMgdmFyaWFibGVzIG9ic2VydmFkYXMsIHNlIG11ZXN0cmEgbGEgZXN0aW1hY2nDs24gZGUgbGEgY2FyZ2EsIHN1IGVycm9yIGVzdMOhbmRhciwgdmFsb3IgJHokIHkgdmFsb3IgJHAkIGFzb2NpYWRvOg0KICANCiAgKyBgRXN0aW1hdGVgOiBJbmRpY2EgbGEgZXN0aW1hY2nDs24gJFx3aWRlaGF0e1xsYW1iZGF9JCBkZSBsYSBjYXJnYSBmYWN0b3JpYWwgIChmYWN0b3IgbG9hZGluZykgJFxsYW1iZGEkIHBhcmEgY2FkYSBpbmRpY2Fkb3IgZW4gcmVsYWNpw7NuIGNvbiBzdSB2YXJpYWJsZSBsYXRlbnRlIGNvcnJlc3BvbmRpZW50ZS4NCiAgDQogICsgYFN0ZC5FcnJgOiBFcyBlbCBlcnJvciBlc3TDoW5kYXIgJFNfe1x3aWRlaGF0e1xsYW1iZGF9fSQgZGUgbGEgZXN0aW1hY2nDs24uIA0KICANCiAgKyBgei12YWx1ZWA6IEVsIHZhbG9yICR6JCBpbmRpY2EgY3XDoW50YXMgZGVzdmlhY2lvbmVzIGVzdMOhbmRhciBlc3TDoSBsYSBlc3RpbWFjacOzbiBwb3IgZW5jaW1hIG8gcG9yIGRlYmFqbyBkZSBjZXJvLiBWYWxvcmVzIGFic29sdXRvcyBtw6FzIGdyYW5kZXMgaW5kaWNhbiB1bmEgbWF5b3Igc2lnbmlmaWNhbmNpYSBlc3RhZMOtc3RpY2EuDQogIA0KICArIGBQKD58enwpYDogRXMgZWwgdmFsb3IgJHAkIGFzb2NpYWRvIGNvbiBlbCB2YWxvciAkeiQuIFVuIHZhbG9yICRwJCBiYWpvIChwb3IgZWplbXBsbywgPDAuMDUpIHN1Z2llcmUgcXVlIGxhIGVzdGltYWNpw7NuIGVzIHNpZ25pZmljYXRpdmFtZW50ZSBkaWZlcmVudGUgZGUgY2Vyby4NCiAgDQogICsgU2kgJFxsYW1iZGEkIGVzIGxhIGNhcmdhIGZhY3RvcmlhbCBjb3JyZXNwb25kaWVudGUsIGVudG9uY2VzLCBsYXMgaGlww7N0ZXNpcyBxdWUgc2UgY29udHJhc3RhbiBzb246IA0KICANCiAgJCRIXzA6IFw7IFxsYW1iZGEgPSAwIFxxdWFkIFx0ZXh0e3ZlcnN1c30gXHF1YWQgSF8xOiBcOyBcbGFtYmRhIFxuZSAwJCQNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmIgKGVqZW1wbG8pDQoNCjEuIFBhcmEgbGEgdmFyaWFibGUgbGF0ZW50ZSBgdmlzdWFsYDogDQogIA0KICArIEVsIGluZGljYWRvciBgeDFgIHRpZW5lIHVuYSBjYXJnYSBmYWN0b3JpYWwgZmlqYSBlbiAkXHdpZGVoYXR7XGxhbWJkYX1fMT0xJCAocG9yIGNvbnZlbmNpw7NuKS4gDQogIA0KICArIE1pZW50cmFzIHF1ZSBgeDJgIHkgYHgzYCwgcmVzcGVjdGl2YW1lbnRlLCB0aWVuZW4gY2FyZ2FzIGZhY3RvcmlhbGVzIGVzdGltYWRhcyBkZQ0KICANCiAgJCRcd2lkZWhhdHtcbGFtYmRhfV8yPTAuNTU0LCBccXVhZCBcd2lkZWhhdHtcbGFtYmRhfV8zPTAuNzI5JCQgDQogIA0KICArIEFkZW3DoXMsIGxvcyBlcnJvcmVzIGVzdMOhbmRhcmVzIGNvcnJlc3BvbmRpZW50ZXMgc29uOg0KICANCiAgJCRTX3tcd2lkZWhhdHtcbGFtYmRhfV8yfSA9IDAuMTAwLCBccXVhZCBTX3tcd2lkZWhhdHtcbGFtYmRhfV8zfSA9IDAuMTA5JCQNCjMuIExvcyB2YWxvcmVzICR6JCAgY29ycmVzcG9uZGllbnRlcyBhICBgeDJgIHkgYHgzYCBzb246IA0KDQokJHpfMj0gXGZyYWN7XHdpZGVoYXR7XGxhbWJkYX1fMiAtIDB9e1Nfe1x3aWRlaGF0e1xsYW1iZGF9XzJ9fSA9IFxmcmFjezAuNTU0IC0gMH17MC4xMDB9ID0gNS41NTQsIFxxcXVhZCB6XzI9IFxmcmFje1x3aWRlaGF0e1xsYW1iZGF9XzMgLSAwfXtTX3tcd2lkZWhhdHtcbGFtYmRhfV8zfX0gPSBcZnJhY3swLjcyOSAtIDB9ezAuMTA5fSA9IDYuNjg1JCQNCg0KMy4gVG9kb3MgZXN0b3MgdmFsb3JlcyBzb24gc2lnbmlmaWNhdGl2b3MgKFAgPCAwLjA1KSwgbG8gcXVlIGluZGljYSBxdWUgbG9zIGluZGljYWRvcmVzIGVzdMOhbiBiaWVuIGFzb2NpYWRvcyBjb24gbGEgdmFyaWFibGUgbGF0ZW50ZSBgdmlzdWFsYDoNCg0KJCRcdGV4dHt2YWxvcn1cOyBwXzIgPSBQKFpfMiA+IDUuNTU0KSA9IDAsIFxxcXVhZCBcdGV4dHt2YWxvcn1cOyAgcF8zID0gUChaXzMgPiA2LjY4NSkgPSAwJCQNCg0KNC4gRGUgbWFuZXJhIHNpbWlsYXIsIHBhcmEgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcyBgdGV4dHVhbGAgeSBgc3BlZWRgLCBsb3MgaW5kaWNhZG9yZXMgZXN0w6FuIGJpZW4gYXNvY2lhZG9zIGNvbiBzdXMgdmFyaWFibGVzIGxhdGVudGVzIGNvcnJlc3BvbmRpZW50ZXMsIHlhIHF1ZSB0b2RhcyBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIHNvbiBzaWduaWZpY2F0aXZhcy4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBPdXRwdXQgZGUgYEVzdGltYXRlYDogNmMgKGBjb3ZhcmlhbmNlc2ApDQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmMgKG91dHB1dCBncsOhZmljbykNCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4xNykgc2UgcmVzYWx0YSBsYSBwYXJ0ZSBOby4gNmMgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE3LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDZjIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGBDb3ZhcmlhbmNlc2ApKioiLCBvdXQud2lkdGggPSAiOTAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImxhdmFhbjE3LnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+IA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYEVzdGltYXRlc2A6IHBhcnRlIDZjIChnZW5lcmFsaWRhZGVzKQ0KDQoxLiBTZSBwcm9wb3JjaW9uYW4gbGFzIGVzdGltYWNpb25lcyBkZSBsYXMgY292YXJpYW56YXMgZW50cmUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcyAoYHZpc3VhbGAsIGB0ZXh0dWFsYCwgYHNwZWVkYCkuDQoNCjIuIFBhcmEgY2FkYSBjb3ZhcmlhbnphLCBzZSBtdWVzdHJhIGxhIGVzdGltYWNpw7NuLCBzdSBlcnJvciBlc3TDoW5kYXIsIHZhbG9yICR6JCB5IHZhbG9yICRwJCBhc29jaWFkbzoNCg0KICArIGBFc3RpbWF0ZWA6IEluZGljYSBsYSBlc3RpbWFjacOzbiAkXHdpZGVoYXR7Q31fe2lqfSA9IFx3aWRlaGF0e0Nvdn0oRl9pLEZfaikkIGRlIGxhIGNvdmFyaWFuemEgJENfe2lqfSQgZW50cmUgbGFzIHZhcmlhYmxlcyBsYXRlbnRlcyAkRl9pJCB5ICRGX2okLg0KICANCiAgKyBgU3RkLkVycmA6IEVzIGVsIGVycm9yIGVzdMOhbmRhciAkU197XHdpZGVoYXR7Q31fe2lqfX0kIGRlIGxhIGVzdGltYWNpw7NuLiANCiAgDQogICsgYHotdmFsdWVgOiBFbCB2YWxvciAkeiQgaW5kaWNhIGN1w6FudGFzIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIgZXN0w6EgbGEgZXN0aW1hY2nDs24gcG9yIGVuY2ltYSBvIHBvciBkZWJham8gZGUgY2Vyby4gVmFsb3JlcyBhYnNvbHV0b3MgbcOhcyBncmFuZGVzIGluZGljYW4gdW5hIG1heW9yIHNpZ25pZmljYW5jaWEgZXN0YWTDrXN0aWNhLg0KICANCiAgKyBgUCg+fHp8KWA6IEVzIGVsIHZhbG9yICRwJCBhc29jaWFkbyBjb24gZWwgdmFsb3IgJHokLiBVbiB2YWxvciAkcCQgYmFqbyAocG9yIGVqZW1wbG8sIDwwLjA1KSBzdWdpZXJlIHF1ZSBsYSBlc3RpbWFjacOzbiBlcyBzaWduaWZpY2F0aXZhbWVudGUgZGlmZXJlbnRlIGRlIGNlcm8uDQogIA0KICArIFNpICR7Q31fe2lqfSQgZXMgbGEgY292YXJpYW56YSBjb3JyZXNwb25kaWVudGUgZW50cmUgJEZfaSQgeSAkRl9qJCwgZW50b25jZXMsIGxhcyBoaXDDs3Rlc2lzIHF1ZSBzZSBjb250cmFzdGFuICBzb246IA0KICANCiAgJCRIXzA6IFw7IHtDfV97aWp9ID0gMCBccXVhZCBcdGV4dHt2ZXJzdXN9IFxxdWFkIEhfMTogXDsge0N9X3tpan0gXG5lIDAkJA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBFc3RpbWF0ZXNgOiBwYXJ0ZSA2YyAoZWplbXBsbykNCg0KMS4gTGEgY292YXJpYW56YSBlbnRyZSBgdmlzdWFsYCB5IGB0ZXh0dWFsYCBlcyBkZSAwLjQwOCwgbG8gcXVlIGluZGljYSBxdWUgZXN0YXMgZG9zIHZhcmlhYmxlcyBsYXRlbnRlcyBlc3TDoW4gbW9kZXJhZGFtZW50ZSBjb3JyZWxhY2lvbmFkYXMuIA0KDQoyLiBFc3RhIGNvdmFyaWFuemEgZXMgc2lnbmlmaWNhdGl2YSAoJFAgPCAwLjA1JCksIGxvIHF1ZSBzdWdpZXJlIHVuYSByZWxhY2nDs24gc2lnbmlmaWNhdGl2YSBlbnRyZSBsYXMgaGFiaWxpZGFkZXMgdmlzdWFsZXMgeSB0ZXh0dWFsZXMuDQoNCjMuIExvcyBjw6FsY3Vsb3MgY29ycmVzcG9uZGllbnRlcyBzb24gbXV5IHNpbWlsYXJlcyBhIGxvcyByZWFsaXphZG9zIGVuIGxhIHBhcnRlIDZiLiANCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIE91dHB1dCBkZSBgRXN0aW1hdGVgOiA2ZCAoYHZhcmlhbmNlc2ApDQoNCiMjIyBgRXN0aW1hdGVzYDogcGFydGUgNmQgKG91dHB1dCBncsOhZmljbykNCg0KRW4gbGEgRmlndXJhIFxAcmVmKGZpZzpsYXZhYW4xOCkgc2UgcmVzYWx0YSBsYSBwYXJ0ZSBOby4gNmQgZGVsIG91dHB1dCBkZSBgbGF2YWFuOjpzdW1tYXJ5YC4gIA0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE4LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGFydGUgTm8uIDZkIGRlbCBvdXRwdXQgZGUgYGxhdmFhbjo6c3VtbWFyeWAgKGBWYXJpYW5jZXNgKSoqIiwgb3V0LndpZHRoID0gIjkwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xOC5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBFc3RpbWF0ZXNgOiBwYXJ0ZSA2YyAoZ2VuZXJhbGlkYWRlcykNCg0KMS4gU2UgcHJlc2VudGFuIGxhcyBlc3RpbWFjaW9uZXMgZGUgbGFzIHZhcmlhbnphcyBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgKGB4MWAsIC4uLiwgYHg5YCkgeSBsYXRlbnRlcyAoYHZpc3VhbGAsIGB0ZXh0dWFsYCwgYHNwZWVkYCkuDQoNCjIuIFBhcmEgY2FkYSB2YXJpYW56YSwgc2UgbXVlc3RyYSBsYSBlc3RpbWFjacOzbiwgc3UgZXJyb3IgZXN0w6FuZGFyLCB2YWxvciAkeiQgeSB2YWxvciAkcCQgYXNvY2lhZG86DQoNCiAgKyBgRXN0aW1hdGVgOiBJbmRpY2EgbGEgZXN0aW1hY2nDs24gJFx3aWRlaGF0e0N9X3tpaX0kIGRlIGxhIHZhcmlhbnphICRDX3tpaX0kIGVudHJlIGxhcyB2YXJpYWJsZXMgZGUgaW50ZXLDqXMuDQogIA0KICArIGBTdGQuRXJyYDogRXMgZWwgZXJyb3IgZXN0w6FuZGFyICRTX3tcd2lkZWhhdHtDfV97aWl9fSQgZGUgbGEgZXN0aW1hY2nDs24uDQogIA0KICArIGB6LXZhbHVlYDogRWwgdmFsb3IgJHokIGluZGljYSBjdcOhbnRhcyBkZXN2aWFjaW9uZXMgZXN0w6FuZGFyIGVzdMOhIGxhIGVzdGltYWNpw7NuIHBvciBlbmNpbWEgbyBwb3IgZGViYWpvIGRlIGNlcm8uIFZhbG9yZXMgYWJzb2x1dG9zIG3DoXMgZ3JhbmRlcyBpbmRpY2FuIHVuYSBtYXlvciBzaWduaWZpY2FuY2lhIGVzdGFkw61zdGljYS4NCiAgDQogICsgYFAoPnx6fClgOiBFcyBlbCB2YWxvciAkcCQgYXNvY2lhZG8gY29uIGVsIHZhbG9yICR6JC4gVW4gdmFsb3IgJHAkIGJham8gKHBvciBlamVtcGxvLCA8MC4wNSkgc3VnaWVyZSBxdWUgbGEgZXN0aW1hY2nDs24gZXMgc2lnbmlmaWNhdGl2YW1lbnRlIGRpZmVyZW50ZSBkZSBjZXJvLg0KICANCiAgKyBTaSAke0N9X3tpaX0kIGVzIGxhIHZhcmlhbnphIGNvcnJlc3BvbmRpZW50ZSBkZSBsYSB2YXJpYWJsZSBkZSBpbnRlcsOpcywgZW50b25jZXMsIGxhcyBoaXDDs3Rlc2lzIHF1ZSBzZSBjb250cmFzdGFuICBzb246IA0KICANCiAgJCRIXzA6IFw7IHtDfV97aWl9ID0gMCBccXVhZCBcdGV4dHt2ZXJzdXN9IFxxdWFkIEhfMTogXDsge0N9X3tpaX0gXG5lIDAkJA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBFc3RpbWF0ZXNgOiBwYXJ0ZSA2YyAoZWplbXBsbykNCg0KMS4gTGEgdmFyaWFuemEgZGUgbGEgdmFyaWFibGUgbGF0ZW50ZSBgdmlzdWFsYCBlcyBkZSAwLjgwOS4gDQoNCjIuIEVzdG8gaW5kaWNhIGN1w6FudGEgdmFyaWFuemEgZW4gYHZpc3VhbGAgbm8gZXN0w6EgZXhwbGljYWRhIHBvciBzdXMgaW5kaWNhZG9yZXMuIA0KDQozLiBFc3RhIHZhcmlhbnphIGVzIHNpZ25pZmljYXRpdmEgKCRQIDwgMC4wNSQpLCBsbyBxdWUgc3VnaWVyZSBxdWUgbGEgdmFyaWFibGUgbGF0ZW50ZSBgdmlzdWFsYCBjb250cmlidXllIHNpZ25pZmljYXRpdmFtZW50ZSBhIGxhIHZhcmlhYmlsaWRhZCBlbiBsb3MgZGF0b3Mgb2JzZXJ2YWRvcy4NCg0KMy4gTG9zIGPDoWxjdWxvcyBjb3JyZXNwb25kaWVudGVzIHNvbiBtdXkgc2ltaWxhcmVzIGEgbG9zIHJlYWxpemFkb3MgZW4gbGEgcGFydGUgNmIuIA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEV4dHJheWVuZG8gZWxlbWVudG9zOiBjb24gYGluc3BlY3RgDQoNCiMjIyBgaW5zcGVjdGA6IGRlc2NyaXBjacOzbg0KDQoxLiBFbCBjw7NkaWdvIGRlIGFiYWpvICBwcm9wb3JjaW9uYXLDoSB1bmEgdGFibGEgcXVlIG11ZXN0cmEgbG9zIGVzdGltYWRvcyBkZSBsb3MgcGFyw6FtZXRyb3MgZGVsIG1vZGVsbyBDRkEuDQoNCjIuIEVsIG91dHB1dCBpbmNsdXllIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMgKCRcTGFtYmRhJCksIGxhcyB2YXJpYW56YXMgcmVzaWR1YWxlcyAoJFxUaGV0YSQpIHkgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3JlcyAoJFxQc2kkKS4gDQoNCjMuIEVuIHNlY2Npb25lcyBzaWd1aWVudGVzIHNlIGRlc2NyaWJpcsOhbiBjYWRhIHVuYSBkZSBlc3RhcyBtYXRyaWNlcy4gRW4gY29uanVudG8sIGxhcyBtYXRyaWNlcyBcKFxib2xkc3ltYm9se1xMYW1iZGF9XCksIFwoXGJvbGRzeW1ib2x7XFRoZXRhfVwpIHkgXChcYm9sZHN5bWJvbHtcUHNpfVwpIGRlZmluZW4gY29tcGxldGFtZW50ZSBsYSBlc3RydWN0dXJhIGRlbCBtb2RlbG8gQ0ZBLCBwZXJtaXRpZW5kbyBleHByZXNhciBsYSBsbGFtYWRhICoqbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYSoqIGNvbW86DQoNClxbDQpcYm9sZHN5bWJvbHtcU2lnbWF9DQo9DQpcYm9sZHN5bWJvbHtcTGFtYmRhfVxib2xkc3ltYm9se1xQc2l9XGJvbGRzeW1ib2x7XExhbWJkYX1eXHRvcA0KKw0KXGJvbGRzeW1ib2x7XFRoZXRhfS4NClxdDQoNCkxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEgZW4gdW4gbW9kZWxvIGRlIGFuw6FsaXNpcyBmYWN0b3JpYWwgY29uZmlybWF0b3JpbyAoQ0ZBKSBlcyBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgcHJlZGljaGEgcG9yIGVsIG1vZGVsbyBhanVzdGFkby4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgaW5zcGVjdGA6IGVqZWN1Y2nDs24NCg0KIyMjIyBFbCBjw7NkaWdvLiAgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KYGBge3IsIGV2YWw9RkFMU0V9DQppbnNwZWN0KENGQSwgImVzdCIpDQphdHRhY2goaW5zcGVjdChDRkEsICJlc3QiKSkNCg0KbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCnRoZXRhICAjdmFyaWFuemFzIHJlc2lkdWFsZXMgKGRlIGxvcyBlcnJvcmVzIGRlIGxhcyB2YXIuIG9ic2VydmFkYXMpDQpwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgRWwgb3V0cHV0IGRlIGluc3BlY3QuICB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmluc3BlY3QoQ0ZBLCAiZXN0IikNCmF0dGFjaChpbnNwZWN0KENGQSwgImVzdCIpKQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCg0KIyMjIyBFbCBvdXRwdXQgZGUgaW5zcGVjdDogY2FyZ2FzIGZhY3RvcmlhbGVzLiAgIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkxhIG1hdHJpeiBkZSBjYXJnYXMgZmFjdG9yaWFsZXMgZXN0aW1hZGFzIGVzOg0KDQpcWw0KXGJvbGRzeW1ib2x7XExhbWJkYX0gPQ0KXGJlZ2lue3BtYXRyaXh9DQoxLjAwMCAmIDAgICAgICYgMCAgICAgXFwNCjAuNTU0ICYgMCAgICAgJiAwICAgICBcXA0KMC43MjkgJiAwICAgICAmIDAgICAgIFxcDQowICAgICAmIDEuMDAwICYgMCAgICAgXFwNCjAgICAgICYgMS4xMTMgJiAwICAgICBcXA0KMCAgICAgJiAwLjkyNiAmIDAgICAgIFxcDQowICAgICAmIDAgICAgICYgMS4wMDAgXFwNCjAgICAgICYgMCAgICAgJiAxLjE4MCBcXA0KMCAgICAgJiAwICAgICAmIDEuMDgyDQpcZW5ke3BtYXRyaXh9LA0KXF0NCg0KZG9uZGUgbGFzIGNvbHVtbmFzIGNvcnJlc3BvbmRlbiBhIGxvcyBmYWN0b3Jlcw0KXChcdGV4dHt2aXN1YWx9XCksIFwoXHRleHR7dGV4dHVhbH1cKSB5IFwoXHRleHR7c3BlZWR9XCksIHkgbGFzIGZpbGFzIGEgbG9zIMOtdGVtcw0KXCh4XzEsXGRvdHMseF85XCkuDQoNCg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmxhbWJkYSAjY2FyZ2FzIGZhY3RvcmlhbGVzDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQpsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KI3RoZXRhICAjdmFyaWFuemFzIHJlc2lkdWFsZXMgKGRlIGxvcyBlcnJvcmVzIGRlIGxhcyB2YXIuIG9ic2VydmFkYXMpDQojcHNpICAgICNjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQoNCg0KIyMjIyBFbCBvdXRwdXQgZGUgaW5zcGVjdDogdmFyaWFuemFzIHJlc2lkdWFsZXMuICAgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KTGEgbWF0cml6IGRlIHZhcmlhbnphcyByZXNpZHVhbGVzIGRlIGxvcyBlcnJvcmVzIGRlIG1lZGljacOzbiBlczoNCg0KXFsNClxib2xkc3ltYm9se1xUaGV0YX0gPQ0KXGJlZ2lue3BtYXRyaXh9DQowLjU0OSAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgXFwNCjAgICAgICYgMS4xMzQgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICBcXA0KMCAgICAgJiAwICAgICAmIDAuODQ0ICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgIFxcDQowICAgICAmIDAgICAgICYgMCAgICAgJiAwLjM3MSAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgXFwNCjAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC40NDYgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICBcXA0KMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAuMzU2ICYgMCAgICAgJiAwICAgICAmIDAgICAgIFxcDQowICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjc5OSAmIDAgICAgICYgMCAgICAgXFwNCjAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC40ODggJiAwICAgICBcXA0KMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAuNTY2DQpcZW5ke3BtYXRyaXh9Lg0KXF0NCg0KRXN0YSBtYXRyaXogZXMgZGlhZ29uYWwsIGxvIHF1ZSBpbXBsaWNhIHF1ZSBubyBzZSBwZXJtaXRlbiBjb3ZhcmlhbnphcyBlbnRyZSBlcnJvcmVzIGRlIG1lZGljacOzbi4NCg0KYGBge3IsIGV2YWw9RkFMU0V9DQp0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzIChkZSBsb3MgZXJyb3JlcyBkZSBsYXMgdmFyLiBvYnNlcnZhZGFzKQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KI2xhbWJkYSAjY2FyZ2FzIGZhY3RvcmlhbGVzDQp0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzIChkZSBsb3MgZXJyb3JlcyBkZSBsYXMgdmFyLiBvYnNlcnZhZGFzKQ0KI3BzaSAgICAjY292YXJpYW56YXMgZW50cmUgbG9zIGZhY3RvcmVzDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgRWwgb3V0cHV0IGRlIGluc3BlY3Q6IGNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcy4gIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkxhIG1hdHJpeiBkZSB2YXJpYW56YXMgeSBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgbGF0ZW50ZXMgZXM6DQoNClxbDQpcYm9sZHN5bWJvbHtcUHNpfSA9DQpcYmVnaW57cG1hdHJpeH0NCjAuODA5ICYgMC40MDggJiAwLjI2MiBcXA0KMC40MDggJiAwLjk3OSAmIDAuMTczIFxcDQowLjI2MiAmIDAuMTczICYgMC4zODQNClxlbmR7cG1hdHJpeH0sDQpcXQ0KDQpkb25kZSBsYSBkaWFnb25hbCBjb250aWVuZSBsYXMgdmFyaWFuemFzIGRlIGxvcyBmYWN0b3Jlcw0KXChcdGV4dHt2aXN1YWx9XCksIFwoXHRleHR7dGV4dHVhbH1cKSB5IFwoXHRleHR7c3BlZWR9XCksDQp5IGxvcyBlbGVtZW50b3MgZnVlcmEgZGUgbGEgZGlhZ29uYWwgcmVwcmVzZW50YW4gc3VzIGNvdmFyaWFuemFzLg0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcHNpICAjdmFyaWFuemFzIHJlc2lkdWFsZXMgKGRlIGxvcyBlcnJvcmVzIGRlIGxhcyB2YXIuIG9ic2VydmFkYXMpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQojbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCiN0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzIChkZSBsb3MgZXJyb3JlcyBkZSBsYXMgdmFyLiBvYnNlcnZhZGFzKQ0KcHNpICAgICNjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMNCmBgYA0KDQoNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGluc3BlY3RgOiBhcmd1bWVudG8gYHdoYXRgDQoNClBhcmEgdmVyIGPDs21vIGxhdmFhbiByZXByZXNlbnRhIGludGVybmFtZW50ZSB1biBtb2RlbG8sIHB1ZWRlIGVzY3JpYmlyOiANCg0KKipFbCBjw7NkaWdvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KaW5zcGVjdChmaXQsIHdoYXQ9Imxpc3QiKQ0KYGBgDQoNCioqRWwgb3V0cHV0LioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KaW5zcGVjdChmaXQsIHdoYXQ9Imxpc3QiKQ0KYGBgDQoNCg0KRXN0byBlcyBlcXVpdmFsZW50ZSBhIGxhIGZ1bmNpw7NuIGBwYXJUYWJsZWAuIExhIHRhYmxhIHF1ZSBzZSBkZXZ1ZWx2ZSBhcXXDrSBzZSBkZW5vbWluYSAqdGFibGEgZGUgcGFyw6FtZXRyb3MqLiBTZSBleHBsaWNhcsOhIGVuIHNlY2Npb25lcyBzaWd1aWVudGVzLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBlbGVtZW50b3M6IGNvbiBgbGF2SW5zcGVjdGANCg0KIyMjIGBsYXZJbnNwZWN0YDogZXhwbGljYWNpw7NuDQoNCkxhIGZ1bmNpw7NuIGBsYXZJbnNwZWN0YCBhY2VwdGEgdmFyaW9zIGFyZ3VtZW50b3MgcGFyYSBlc3BlY2lmaWNhciBxdcOpIGFzcGVjdG8gZGVsIG1vZGVsbyBzZSBkZXNlYSBpbnNwZWNjaW9uYXIuIEFsZ3Vub3MgZGUgbG9zIGFyZ3VtZW50b3MgY29tdW5lcyBpbmNsdXllbjoNCg0KKioxLiBgb2JqZWN0YC4qKg0KDQpFbCBtb2RlbG8gYWp1c3RhZG8gZGVsIGN1YWwgc2UgZGVzZWFuIGluc3BlY2Npb25hciBsYXMgcHJvcGllZGFkZXMuDQoNCioqMi4gYHdoYXRgLioqIA0KDQplc3BlY2lmaWNhIHF1w6kgcHJvcGllZGFkIGRlbCBtb2RlbG8gc2UgZGVzZWEgaW5zcGVjY2lvbmFyLiBFc3RvIHB1ZWRlIHNlciBgZXN0YCBwYXJhIGxvcyBwYXLDoW1ldHJvcyBlc3RpbWFkb3MsIGByZXNpZHVhbHNgIHBhcmEgbG9zIHJlc2lkdW9zLCAiY292IiBwYXJhIGxhcyBjb3ZhcmlhbnphcywgZW50cmUgb3Ryb3MuDQoNCioqMy4gYGxhYmVsYC4qKiANCg0KT3BjaW9uYWxtZW50ZSwgcGVybWl0ZSBlc3BlY2lmaWNhciB1biBub21icmUgcGFyYSBldGlxdWV0YXIgZWwgcmVzdWx0YWRvLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGxhdkluc3BlY3RgOiBlamVjdWNpw7NuDQoNCjEuIFBvciBlamVtcGxvLCBwYXJhIGluc3BlY2Npb25hciBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlIHVuIG1vZGVsbyBhanVzdGFkbyBgQ0ZBYCwgcHVlZGVzIHVzYXIgYGxhdkluc3BlY3QoZml0LCAiZXN0IilgLiANCg0KMi4gRXN0byBkZXZvbHZlcsOhIHVuYSB0YWJsYSBxdWUgbXVlc3RyYSBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlbCBtb2RlbG8sIGluY2x1eWVuZG8gbGFzIGNhcmdhcyBmYWN0b3JpYWxlcywgbGFzIHZhcmlhbnphcyByZXNpZHVhbGVzIHkgbGFzIGNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcy4NCg0KDQozLiBFbCBvdXRwdXQgZXMgZXhhY3RhbWVudGUgZWwgbWlzbW8gcXVlIHNlIG9idGllbmUgY29uIGBpbnNwZWN0YC4gDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBlbGVtZW50b3M6IGNvbiBgbGF2SW5zcGVjdGA6IGVqZW1wbG9zDQoNCiMjIyBgbGF2SW5zcGVjdGA6IGVqZW1wbG8gMQ0KDQpQb3IgZGVmZWN0bywgYWwgbGxhbWFyIGEgYGxhdkluc3BlY3RgICBzb2JyZSB1biBvYmpldG8gYGxhdmFhbmAgYWp1c3RhZG8gc2Ugb2J0aWVuZSB1bmEgbGlzdGEgZGUgbGFzIG1hdHJpY2VzIGRlbCBtb2RlbG8gcXVlIHNlIHV0aWxpemFuIGludGVybmFtZW50ZSBwYXJhIHJlcHJlc2VudGFyIGVsIG1vZGVsby4gTG9zIHBhcsOhbWV0cm9zIGxpYnJlcyBzb24gZW50ZXJvcyBkaXN0aW50b3MgZGUgY2Vyby4NCg0KDQoqKkVsIGPDs2RpZ28uKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpsYXZJbnNwZWN0KGZpdCkNCmBgYA0KDQoqKkVsIG91dHB1dC4qKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxhdkluc3BlY3QoZml0KQ0KYGBgDQoNCg0KQSBwYXJ0aXIgZGVsIG1vZGVsbyBDRkEgc2UgZXN0aW1hbiBsYSBtYXRyaXogZGUgY2FyZ2FzIGZhY3RvcmlhbGVzIChcKFxib2xkc3ltYm9se1xMYW1iZGF9XCkpLCBsYSBtYXRyaXogZGUgdmFyaWFuemFzIHJlc2lkdWFsZXMgZGUgbG9zIGVycm9yZXMgZGUgbWVkaWNpw7NuIChcKFxib2xkc3ltYm9se1xUaGV0YX1cKSkgeSBsYSBtYXRyaXogZGUgdmFyaWFuemFz4oCTY292YXJpYW56YXMgZGUgbG9zIGZhY3RvcmVzIGxhdGVudGVzIChcKFxib2xkc3ltYm9se1xQc2l9XCkpLCByZXNwZWN0aXZhbWVudGU6IA0KDQoNClxbDQogIFxib2xkc3ltYm9se1xMYW1iZGF9ID0NCiAgICBcYmVnaW57cG1hdHJpeH0NCiAgMS4wMDAgJiAwICAgICAmIDAgICAgIFxcDQogIDAuNTU0ICYgMCAgICAgJiAwICAgICBcXA0KICAwLjcyOSAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAxLjAwMCAmIDAgICAgIFxcDQogIDAgICAgICYgMS4xMTMgJiAwICAgICBcXA0KICAwICAgICAmIDAuOTI2ICYgMCAgICAgXFwNCiAgMCAgICAgJiAwICAgICAmIDEuMDAwIFxcDQogIDAgICAgICYgMCAgICAgJiAxLjE4MCBcXA0KICAwICAgICAmIDAgICAgICYgMS4wODINCiAgXGVuZHtwbWF0cml4fSwgXHFxdWFkIA0KICBcYm9sZHN5bWJvbHtcVGhldGF9ID0NCiAgICBcYmVnaW57cG1hdHJpeH0NCiAgMC41NDkgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgIFxcDQogIDAgICAgICYgMS4xMzQgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICBcXA0KICAwICAgICAmIDAgICAgICYgMC44NDQgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC4zNzEgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgIFxcDQogIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC40NDYgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICBcXA0KICAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC4zNTYgJiAwICAgICAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC43OTkgJiAwICAgICAmIDAgICAgIFxcDQogIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC40ODggJiAwICAgICBcXA0KICAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMC41NjYNCiAgXGVuZHtwbWF0cml4fSxcXSANCg0KXFsgIFxib2xkc3ltYm9se1xQc2l9ID0NCiAgICAgIFxiZWdpbntwbWF0cml4fQ0KICAgIDAuODA5ICYgMC40MDggJiAwLjI2MiBcXA0KICAgIDAuNDA4ICYgMC45NzkgJiAwLjE3MyBcXA0KICAgIDAuMjYyICYgMC4xNzMgJiAwLjM4NA0KICAgIFxlbmR7cG1hdHJpeH0NCiAgICBcXQ0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYGxhdkluc3BlY3RgOiBlamVtcGxvIDINCg0KUGFyYSB2ZXIgY8OzbW8gYGxhdmFhbmAgcmVwcmVzZW50YSBpbnRlcm5hbWVudGUgdW4gbW9kZWxvLCBwdWVkZSBlc2NyaWJpcjoNCg0KYGBge3J9DQpsYXZJbnNwZWN0KENGQSwgd2hhdCA9ICJsaXN0IikNCmBgYA0KRXN0byBlcyBlcXVpdmFsZW50ZSBhIGxhIGZ1bmNpw7NuIGBwYXJUYWJsZWAuIExhIHRhYmxhIHF1ZSBzZSBkZXZ1ZWx2ZSBhcXXDrSBzZSBkZW5vbWluYSAqdGFibGEgZGUgcGFyw6FtZXRyb3MqLiBTZSBleHBsaWNhcsOhIGVuIHNlY2Npb25lcyBzaWd1aWVudGVzLiANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgbGF2SW5zcGVjdGA6IGVqZW1wbG8gMw0KDQpFc3RpbWFyIGxhcyBjYXJnYXMgZmFjdG9yaWFsZXMsIGxhcyB2YXJpYW56YXMgcmVzaWR1YWxlcyB5IGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgY2FyZ2EgZmFjdG9yaWFsLCB2YXJpYW56YSByZXNpZHVhbCB5IGNvdmFyaWFuemEgZW50cmUgZmFjdG9yZXMuIFBvciBkZWZlY3RvLCBgbGF2SW5zcGVjdChmaXQpYCBkZXZ1ZWx2ZSBsYXMgbWF0cmljZXMgaW50ZXJuYXMgZGVsIG1vZGVsbywgbm8gY29uIHZhbG9yZXMgZXN0aW1hZG9zLCBzaW5vIGNvbiDDrW5kaWNlcyBlbnRlcm9zIHF1ZSBpZGVudGlmaWNhbiBsb3MgcGFyw6FtZXRyb3MgbGlicmVzIGRlbCBtb2RlbG8uDQoNCg0KKipSZWdsYSBmdW5kYW1lbnRhbC4qKg0KDQotIDAgIGltcGxpY2EgdW4gcGFyw6FtZXRybyBmaWpvIChnZW5lcmFsbWVudGUgYSAwIG8gYSB1biB2YWxvciBkZSBpZGVudGlmaWNhY2nDs24pLg0KDQotIEVudGVybyBwb3NpdGl2byBpbXBsaWNhIHVuIHBhcsOhbWV0cm8gbGlicmUsIG51bWVyYWRvIHNlZ8O6biBlbCB2ZWN0b3IgaW50ZXJubyBkZSBwYXLDoW1ldHJvcyBkZSBgbGF2YWFuYC4NCg0KRXMgZGVjaXIsIGxhdmFhbiBlc3TDoSBtb3N0cmFuZG8gbGEgZXN0cnVjdHVyYSBwYXJhbcOpdHJpY2EgZGVsIG1vZGVsbywgbm8gc3VzIGVzdGltYWNpb25lcyBudW3DqXJpY2FzLg0KDQoNCioqRWwgY8OzZGlnby4qKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmxhdkluc3BlY3QoZml0LCAiZXN0IikNCmBgYA0KDQoqKkVsIG91dHB1dC4qKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxhdkluc3BlY3QoZml0LCAiZXN0IikNCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgbGF2SW5zcGVjdGA6IGVqZW1wbG8gNA0KDQpMYSBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhIHBvciBlbCBtb2RlbG8gQ0ZBIGNvcnJlc3BvbmRlIGEgbGFzIGNvdmFyaWFuemFzIHBvYmxhY2lvbmFsZXMgcXVlIGVsIG1vZGVsbyBwcmVkaWNlIGVudHJlIGxhcyB2YXJpYWJsZXMNCm9ic2VydmFkYXMuIEVuIGVzdGUgY2FzbywgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYSBlc3RpbWFkYSBlczoNCg0KDQpcWw0KXGJvbGRzeW1ib2x7XFNpZ21hfSBcOyA9IFw7IA0KICAgIFxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XFBzaX1cYm9sZHN5bWJvbHtcTGFtYmRhfV5cdG9wDQogICsNCiAgICBcYm9sZHN5bWJvbHtcVGhldGF9IFw7ID0gXDsNClxiZWdpbntwbWF0cml4fQ0KMS4zNTggJiAwLjQ0OCAmIDAuNTkwICYgMC40MDggJiAwLjQ1NCAmIDAuMzc4ICYgMC4yNjIgJiAwLjMwOSAmIDAuMjg0IFxcDQowLjQ0OCAmIDEuMzgyICYgMC4zMjcgJiAwLjIyNiAmIDAuMjUyICYgMC4yMDkgJiAwLjE0NSAmIDAuMTcxICYgMC4xNTcgXFwNCjAuNTkwICYgMC4zMjcgJiAxLjI3NSAmIDAuMjk4ICYgMC4zMzEgJiAwLjI3NiAmIDAuMTkxICYgMC4yMjYgJiAwLjIwNyBcXA0KMC40MDggJiAwLjIyNiAmIDAuMjk4ICYgMS4zNTEgJiAxLjA5MCAmIDAuOTA3ICYgMC4xNzMgJiAwLjIwNSAmIDAuMTg4IFxcDQowLjQ1NCAmIDAuMjUyICYgMC4zMzEgJiAxLjA5MCAmIDEuNjYwICYgMS4wMTAgJiAwLjE5MyAmIDAuMjI4ICYgMC4yMDkgXFwNCjAuMzc4ICYgMC4yMDkgJiAwLjI3NiAmIDAuOTA3ICYgMS4wMTAgJiAxLjE5NiAmIDAuMTYxICYgMC4xOTAgJiAwLjE3NCBcXA0KMC4yNjIgJiAwLjE0NSAmIDAuMTkxICYgMC4xNzMgJiAwLjE5MyAmIDAuMTYxICYgMS4xODMgJiAwLjQ1MyAmIDAuNDE1IFxcDQowLjMwOSAmIDAuMTcxICYgMC4yMjYgJiAwLjIwNSAmIDAuMjI4ICYgMC4xOTAgJiAwLjQ1MyAmIDEuMDIyICYgMC40OTAgXFwNCjAuMjg0ICYgMC4xNTcgJiAwLjIwNyAmIDAuMTg4ICYgMC4yMDkgJiAwLjE3NCAmIDAuNDE1ICYgMC40OTAgJiAxLjAxNQ0KXGVuZHtwbWF0cml4fS4NClxdDQoNCg0KDQoqKkVsIGPDs2RpZ28uKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpsYXZJbnNwZWN0KENGQSwgInNpZ21hIikNCmBgYA0KDQoqKkVsIG91dHB1dC4qKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxhdkluc3BlY3QoQ0ZBLCAic2lnbWEiKQ0KYGBgDQoNCg0KKipPYnNlcnZhY2nDs24uKioNCg0KRW4gdW4gbW9kZWxvIGJpZW4gYWp1c3RhZG8sIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEgXChcYm9sZHN5bWJvbHtcU2lnbWF9XCkgZGViZSBhcHJveGltYXIgYWRlY3VhZGFtZW50ZQ0KYSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcyBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCkuDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIGNvbiBgcGFyVGFibGVgDQoNCiMjIyBgcGFyVGFibGVgOiBleHBsaWNhY2nDs24gZGUgbGEgZnVuY2nDs24gIA0KDQoxLiBMYSBmdW5jacOzbiBzZSB1dGlsaXphIHBhcmEgZ2VuZXJhciB1bmEgdGFibGEgcXVlIHJlc3VtZSBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIGRlIHVuIG1vZGVsbyBhanVzdGFkby4gDQoNCjIuIEVzdGEgdGFibGEgcHJvcG9yY2lvbmEgdW5hIHZpc2nDs24gZ2VuZXJhbCBkZSBsb3MgcGFyw6FtZXRyb3MgZGVsIG1vZGVsbywgaW5jbHV5ZW5kbyBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzLCBsYXMgdmFyaWFuemFzIHJlc2lkdWFsZXMsIGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMgeSBvdHJhcyBlc3RhZMOtc3RpY2FzIHJlbGV2YW50ZXMuDQoNCg0KKipFbCBjw7NkaWdvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcGFyYW0gPC0gcGFyVGFibGUoQ0ZBKQ0KcGFyYW0NCmBgYA0KDQoqKkVsIG91dHB1dC4qKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnBhcmFtIDwtIHBhclRhYmxlKENGQSkNCnBhcmFtDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgIC0tPg0KDQoNCiMjIyBgcGFyVGFibGVgOiBkZXNjcmlwY2nDs24gZGUgY2FkYSBjb2x1bW5hIGRlIGxhIHRhYmxhIGRlbCBvdXRwdXQgIA0KDQpBIGNvbnRpbnVhY2nDs24gc2UgZGVzY3JpYmVuIGxhcyBjb2x1bW5hcyBkZSBgcGFyVGFibGUoKWA6DQoNCmBgYHtyfQ0KbmFtZXMocGFyYW0pDQpgYGANCg0KDQotICoqYGlkYCoqOiBpZGVudGlmaWNhZG9yIMO6bmljbyBkZSBjYWRhIHBhcsOhbWV0cm8gZGVudHJvIGRlbCBtb2RlbG8uDQoNCi0gKipgbGhzYCoqICgqbGVmdC1oYW5kIHNpZGUqKTogdmFyaWFibGUgZGVsIGxhZG8gaXpxdWllcmRvIGRlbCBwYXLDoW1ldHJvIChwb3IgZWplbXBsbywgdW4gZmFjdG9yIGxhdGVudGUgY29tbyBgdmlzdWFsYCBvIHVuYSB2YXJpYWJsZSBvYnNlcnZhZGEgY29tbyBgeDFgKS4NCg0KLSAqKmBvcGAqKjogb3BlcmFkb3IgcXVlIGluZGljYSBlbCB0aXBvIGRlIHJlbGFjacOzbjoNCg0KICAtIGA9fmAgOiBjYXJnYSBmYWN0b3JpYWwsDQogIA0KICAtIGB+fmAgOiB2YXJpYW56YSBvIGNvdmFyaWFuemEsDQogIA0KICAtIGB+MWAgOiBpbnRlcmNlcHRvIChvICptZWRpYSBsYXRlbnRlKiBzaSBgbGhzYCBlcyB1biBmYWN0b3IpLg0KDQotICoqYHJoc2AqKiAoKnJpZ2h0LWhhbmQgc2lkZSopOiB2YXJpYWJsZSBkZWwgbGFkbyBkZXJlY2hvIGRlbCBwYXLDoW1ldHJvLg0KDQotICoqYHVzZXJgKio6IGluZGljYSBzaSBlbCBwYXLDoW1ldHJvIGZ1ZSAqZXNwZWNpZmljYWRvIGV4cGzDrWNpdGFtZW50ZSBwb3IgZWwgdXN1YXJpbyogZW4gbGEgc2ludGF4aXMgZGVsIG1vZGVsbyAoYHVzZXIgPSAxYCkgbyBzaSBmdWUgKmHDsWFkaWRvICAgYXV0b23DoXRpY2FtZW50ZSogcG9yIGBsYXZhYW5gIHBhcmEgY29tcGxldGFyIGVsIG1vZGVsbyAoYHVzZXIgPSAwYCkuDQoNCi0gKipgYmxvY2tgKio6IGlkZW50aWZpY2EgZWwgKmJsb3F1ZSBkZWwgbW9kZWxvKiBhbCBxdWUgcGVydGVuZWNlIGVsICBwYXLDoW1ldHJvLiBFbiBTRU0gbXVsdGlncnVwbywgY2FkYSBibG9xdWUgY29ycmVzcG9uZGUgYSB1bmEgY29tYmluYWNpw7NuICAgZXNwZWPDrWZpY2EgZGUgZ3J1cG8geSB0aXBvIGRlIGVjdWFjacOzbiB1dGlsaXphZGEgaW50ZXJuYW1lbnRlIHBvciBgbGF2YWFuYC4gRW4gcmVhbGlkYWQsIGVzdGEgY29sdW1uYSBubyB0aWVuZSBpbnRlcnByZXRhY2nDs24gc3VzdGFudGl2YSwgc2lubyBxdWUgIGluZGljYSBjw7NtbyBgbGF2YWFuYCBvcmdhbml6YSBpbnRlcm5hbWVudGUgZWwgbW9kZWxvIHBhcmEgbGEgZXN0aW1hY2nDs24uUG9yIGVqZW1wbG8sIGVuIGxhIHRhYmxhIGBwYXJUYWJsZSgpYCBzZSBvYnNlcnZhbiBmaWxhcyBjb21vOg0KICAgIA0KICAgLSBQYXLDoW1ldHJvcyBkZWwgdGlwbyBgdmlzdWFsID1+IHgxYCwgYHZpc3VhbCA9fiB4MmAsIGB2aXN1YWwgPX4geDNgIGNvbiBgZ3JvdXAgPSAxYCB5IGBibG9jayA9IDFgLCBsb3MgY3VhbGVzIHBlcnRlbmVjZW4gYWwgKmJsb3F1ZSBkZSBtZWRpY2nDs24qDQogICAgICBkZWwgZmFjdG9yIGB2aXN1YWxgIGVuIGVsIHByaW1lciBncnVwby4NCiAgICANCiAgIC0gUGFyw6FtZXRyb3MgZGVsIHRpcG8gYHgxIH5+IHgxYCwgYHgyIH5+IHgyYCBhcGFyZWNlbiBlbiAqYmxvcXVlcyBkaXN0aW50b3MqLCAgeWEgcXVlIGNvcnJlc3BvbmRlbiBhICp2YXJpYW56YXMgcmVzaWR1YWxlcyogZGUgdmFyaWFibGVzIGRpZmVyZW50ZXMuDQogICAgDQogICAtIEVuIGVsIHNlZ3VuZG8gZ3J1cG8gKGBncm91cCA9IDJgKSwgbG9zIG1pc21vcyB0aXBvcyBkZSBwYXLDoW1ldHJvcyBhcGFyZWNlbiAgYXNvY2lhZG9zIGEgKmJsb3F1ZXMgZGlmZXJlbnRlcyosIHJlZmxlamFuZG8gcXVlIGNhZGEgZ3J1cG8gdGllbmUgc3UgcHJvcGlhIHJlcHJlc2VudGFjacOzbiBpbnRlcm5hIGRlbCBtb2RlbG8uDQogICANCi0gKipgZ3JvdXBgKio6IGdydXBvIGFsIHF1ZSBwZXJ0ZW5lY2UgZWwgcGFyw6FtZXRybyAgKDEgPSBwcmltZXIgZ3J1cG8pLg0KDQotICoqYGZyZWVgKio6IGluZGljYWRvciBkZWwgZXN0YWRvIGRlbCBwYXLDoW1ldHJvOg0KDQo6OjpzYW5ncmlhMw0KICAtIGBmcmVlPTBgID0gcGFyw6FtZXRybyAqZmlqbyouIFNpZ25pZmljYSBxdWUgZWwgdmFsb3IgZGVsIHBhcsOhbWV0cm8gbm8gc2UgZXN0aW1hIGNvbiBsb3MgZGF0b3MgbyBxdWUgZWwgdmFsb3IgeWEgZXN0w6EgaW1wdWVzdG8gcG9yIGVsIG1vZGVsby4gUG9yIGVqZW1wbG8sIGVuIGxhIHRhYmxhIHZlbW9zOiANCjo6OiANCg0KOjo6c2FuZ3JpYTYNCmBgYHtyLCBldmFsPUZBTFNFfQ0KdmlzdWFsID1+IHgxICAgZnJlZSA9IDAgICBzdGFydCA9IDEuMDAwDQpgYGANCg0KRXN0byBxdWllcmUgZGVjaXIgcXVlIGxhIGNhcmdhIGRlICBgeDFgIHNvYnJlIGB2aXN1YWxgIGVzdMOhIGZpamFkYSBlbiBgMS4wMDBgLiBObyBzZSBlc3RpbWEgKHBvciBlc28sIGBmcmVlID0gMGApLg0KOjo6DQoNCjo6OnNhbmdyaWEzDQogICAtIGBmcmVlPjBgID0gcGFyw6FtZXRybyAqbGlicmUgYSBlc3RpbWFyKi4gUG9yIGVqZW1wbG8sIHNpIHNlIHZlIGBmcmVlID0gMTJgLCBubyBzaWduaWZpY2EgcXVlIGVsIHBhcsOhbWV0cm8gdmFsZSAxMiwgc2lubyBxdWUgZXMgZWwgcGFyw6FtZXRybyBsaWJyZSBuw7ptZXJvIDEyIHF1ZSBlbCBhbGdvcml0bW8gZXN0aW1hLg0KOjo6DQoNCi0gKipgdXN0YXJ0YCoqICgqdXNlciBzdGFydCopOiB2YWxvciBpbmljaWFsICpkZWZpbmlkbyBwb3IgZWwgdXN1YXJpbyogcGFyYSBlbCAgcGFyw6FtZXRybyBkZSBsYSBmaWxhIGNvcnJlc3BvbmRlaW50ZSwgZW4gY2FzbyBkZSBoYWJlcmxvIGVzcGVjaWZpY2Fkby4gU2kgbm8gc2UgZGVmaW5lLCBzdWVsZSBhcGFyZWNlciAgIGNvbW8gYE5BYC4gUG9yIGVqZW1wbG8sIGNvbnNpZGVyZW1vcyBlc3RhIGZpbGE6IGB2aXN1YWwgPX4geDIgICB1c3RhcnQgPSBOQWAuIEVuIGVzdGUgY2FzbywgZWwgcGFyw6FtZXRybyBlcyBsYSBjYXJnYSBmYWN0b3JpYWwgZGUgYHgyYCBzb2JyZSB2aXN1YWwuIE5vIHNlIGluZGljw7MgbmluZ8O6biB2YWxvciBpbmljaWFsIGVuIGxhIHNpbnRheGlzLiBQb3IgZXNvLCBgbGF2YWFuYCBhc2lnbsOzIGF1dG9tw6F0aWNhbWVudGUgdW4gdmFsb3IgaW5pY2lhbCAoYXBhcmVjZSBlbiBgc3RhcnRgKS4gUG9yIGVzbyBgdXN0YXJ0ID0gTkFgLiBFbnRvbmNlcywgc2UgdmVyw61hIGB2aXN1YWwgPX4geDEgICB1c3RhcnQgPSAwLjVgc2kgZWwgbW9kZWxvIGZ1ZXNlOg0KDQo6OjpzYW5ncmlhMw0KYGBge3IsIGV2YWw9RkFMU0V9DQpIUy5tb2RlbCA8LSAndmlzdWFsID1+IDAuNSp4MSArIHgyICsgeDMnDQpgYGANCjo6Og0KDQotICoqYGV4b2AqKjogaW5kaWNhIHNpIGxhIHZhcmlhYmxlIGFzb2NpYWRhIGFsIHBhcsOhbWV0cm8gZXMgdHJhdGFkYSBjb21vICAqZXjDs2dlbmEqIChgZXhvID0gMWApIG8gKmVuZMOzZ2VuYSogKGBleG8gPSAwYCkuIEVuIG1vZGVsb3MgQ0ZBIGVzdMOhbmRhciwgIGxhIG1heW9yw61hIGRlIHZhcmlhYmxlcyBvYnNlcnZhZGFzIHNlIHRyYXRhbiBjb21vIGVuZMOzZ2VuYXMuDQoNCi0gKipgbGFiZWxgKio6IGV0aXF1ZXRhIGludGVybmEgZGVsIHBhcsOhbWV0cm8sIHV0aWxpemFkYSBwYXJhIGltcG9uZXIgICpyZXN0cmljY2lvbmVzIGRlIGlndWFsZGFkKiBlbnRyZSBncnVwb3MuIExhIGNvbHVtbmEgYGxhYmVsIGBzZSB1c2EgY3VhbmRvIHNlIHF1aWVyZSBxdWUgdmFyaW9zIHBhcsOhbWV0cm9zIGNvbXBhcnRhbiBlbCBtaXNtbyB2YWxvciB5IHNpIGRvcyBmaWxhcyB0aWVuZW4gZWwgbWlzbW8gbGFiZWwsIGBsYXZhYW5gIGxhcyB0cmF0YSBjb21vIHVuIHNvbG8gcGFyw6FtZXRybyBjb23Dum4uIFBvciBlamVtcGxvLCBzdXBvbmdhbW9zIHF1ZSBzZSBxdWllcmUgcXVlIGxhIGNhcmdhIGRlIGB4MmAgc2VhIGlndWFsIGEgYGFgOiANCg0KOjo6c2FuZ3JpYTMNCmBgYHtyLCBldmFsPUZBTFNFfQ0KdmlzdWFsID1+IGEqeDINCmBgYA0KDQoNCkVuIGBwYXJUYWJsZSgpYCBzZSB2ZXLDrWEgYWxnbyBhc8OtOiANCg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmxocyAgICAgb3AgICByaHMgICBncm91cCAgIGxhYmVsDQp2aXN1YWwgID1+ICAgeDIgICAgICAxICAgICAgYQ0KYGBgDQo6OjoNCg0KLSAqKmBwbGFiZWxgKiogKCpwYXJhbWV0ZXIgbGFiZWwqKTogZXRpcXVldGEgaW50ZXJuYSDDum5pY2EgdXRpbGl6YWRhIHBvciBgbGF2YWFuYCBwYXJhIGlkZW50aWZpY2FyIGVsIHBhcsOhbWV0cm8gZHVyYW50ZSBsYSBlc3RpbWFjacOzbi4gQSBkaWZlcmVuY2lhIGRlIGBsYWJlbGAsIGVzdGEgZXRpcXVldGEgZXMgKnNpZW1wcmUgw7puaWNhKiwgaW5jbHVzbyBjdWFuZG8gc2UgaW1wb25lbiByZXN0cmljY2lvbmVzIGRlIGlndWFsZGFkLiBDYWRhIGZpbGEgdGllbmUgc3UgcHJvcGlvIGBwbGFiZWxgIChpbmNsdXNvIGN1YW5kbyBkb3MgcGFyw6FtZXRyb3Mgc29uIGZvcnphZG9zIGEgc2VyIGlndWFsZXMgKGBsYWJlbGAgaWd1YWwpLA0KY2FkYSB1bm8gY29uc2VydmEgc3UgcHJvcGlvIGBwbGFiZWxgKS4gQ29uc2lkZXJlIGVzdGUgZWplbXBsbzogIA0KDQo6OjpzYW5ncmlhMw0KYGBge3IsIGV2YWw9RkFMU0V9DQpsaHMgICAgIG9wICAgcmhzICAgZ3JvdXAgICBsYWJlbCAgIHBsYWJlbA0KdmlzdWFsICA9fiAgIHgyICAgICAgMSAgICAgICBhICAgICAucDIuDQpgYGANCg0KQXF1w60gYGxhYmVsID0gYWAgaW5kaWNhIHZhbG9yIGRlbCBwYXLDoW1ldHJvIHkgYHBsYWJlbCA9IC5wMi5gLCBwYXLDoW1ldHJvIGVuIGxhIGVzdHJ1Y3R1cmEgaW50ZXJuYS4NCjo6Og0KDQotICoqYHN0YXJ0YCoqOiB2YWxvciBpbmljaWFsIHV0aWxpemFkbyBwb3IgZWwgYWxnb3JpdG1vIGRlIGVzdGltYWNpw7NuLg0KDQotICoqYGVzdGAqKiB5ICoqYHNlYCoqOiBlc3RpbWFjacOzbiBmaW5hbCBkZWwgcGFyw6FtZXRybyB5IHN1IGVycm9yIGVzdMOhbmRhci4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KDQojIyMgYHBhclRhYmxlYDogaW50ZXJwcmV0YWNpw7NuIGdlbmVyYWwgZGUgbGEgdGFibGEgIGRlbCBvdXRwdXQgIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCg0KRW4gZWwgbW9kZWxvIHNlIG9ic2VydmEgcXVlOg0KDQotIExhcyBjYXJnYXMgZmFjdG9yaWFsZXMgZmlqYWRhcyBlbiBgMS4wMGAgKHBvciBlamVtcGxvLCBgdmlzdWFsID1+IHgxYCwgIGB0ZXh0dWFsID1+IHg0YCwgYHNwZWVkID1+IHg3YCkgY3VtcGxlbiBsYSBmdW5jacOzbiBkZSAqaWRlbnRpZmljYWNpw7NuIGRlIGxhICAgZXNjYWxhKiBkZSBsb3MgZmFjdG9yZXMgbGF0ZW50ZXMuDQoNCi0gTGFzIGZpbGFzIGNvbiBvcGVyYWRvciBgfn5gIGNvcnJlc3BvbmRlbiBhICp2YXJpYW56YXMqIChjdWFuZG8gYGxoc2AgJD0kIGByaHNgKSAgeSAqY292YXJpYW56YXMqIChjdWFuZG8gYGxoc2AgJFxuZSQgYHJoc2ApLg0KDQotIExhcyBmaWxhcyBjb24gb3BlcmFkb3IgYH4xYCB5IGBsaHNgIGlndWFsIGEgdW5hIHZhcmlhYmxlIG9ic2VydmFkYSByZXByZXNlbnRhbiAgKmludGVyY2VwdG9zKjsgY3VhbmRvIGBsaHNgIGVzIHVuIGZhY3RvciBsYXRlbnRlLCByZXByZXNlbnRhbiAqbWVkaWFzICBsYXRlbnRlcyouDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yICAtLT4NCg0KDQojIyMgYHBhclRhYmxlYDogbm90YSBwZWRhZ8OzZ2ljYSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpMYSBmdW5jacOzbiBgcGFyVGFibGUoKWAgbm8gZXN0w6EgcGVuc2FkYSBwYXJhIGxhIGludGVycHJldGFjacOzbiBzdXN0YW50aXZhIGRpcmVjdGEsIHNpbm8gcGFyYSBlbnRlbmRlciBjw7NtbyBgbGF2YWFuYCBjb2RpZmljYSBpbnRlcm5hbWVudGUgZWwgbW9kZWxvLiBTaW4gZW1iYXJnbywgcmVzdWx0YSBleHRyZW1hZGFtZW50ZSDDunRpbCBwYXJhOg0KDQotIENvbXByZW5kZXIgbGEgbMOzZ2ljYSBkZSBsYXMgcmVzdHJpY2Npb25lcyBkZSBpZ3VhbGRhZC4NCg0KLSBWZXJpZmljYXIgcXXDqSBwYXLDoW1ldHJvcyBlc3TDoW4gZmlqb3MgbyBsaWJyZXMuDQoNCi0gQ29uZWN0YXIgbGEgc2ludGF4aXMgZGVsIG1vZGVsbyBjb24gbG9zIHJlc3VsdGFkb3MgbnVtw6lyaWNvcy4NCg0KUG9yIGVzdGEgcmF6w7NuLCBgcGFyVGFibGUoKWAgZXMgdW5hIGhlcnJhbWllbnRhIGNsYXZlIHBhcmEgZWwgZXN0dWRpbyByaWd1cm9zb2RlIGxhIGludmFyaWFuemEgZmFjdG9yaWFsIHkgZWwgU0VNIG11bHRpZ3J1cG8uDQoNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEV4dHJheWVuZG8gY2FyZ2FzIGZhY3RvcmlhbGVzDQoNCg0KIyMjIENhcmdhczogc29sbyBlc3RpbWFkb3MgKGNvbiBgaW5zcGVjdGApDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQppbnNwZWN0KENGQSwgImVzdCIpDQphdHRhY2goaW5zcGVjdChDRkEsICJlc3QiKSkNCg0KbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCiN0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzDQojcHNpICAgICNjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMNCmBgYA0KDQoqKkVsIG90dXB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQppbnNwZWN0KENGQSwgImVzdCIpDQphdHRhY2goaW5zcGVjdChDRkEsICJlc3QiKSkNCg0KbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCiN0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzDQojcHNpICAgICNjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMNCmBgYA0KDQpFbCByZXN1bHRhZG8gY29ycmVzcG9uZGUgYSA6IA0KDQokJFxib2xkc3ltYm9se1xMYW1iZGF9ID0NCiAgICBcYmVnaW57cG1hdHJpeH0NCiAgMS4wMDAgJiAwICAgICAmIDAgICAgIFxcDQogIDAuNTU0ICYgMCAgICAgJiAwICAgICBcXA0KICAwLjcyOSAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAxLjAwMCAmIDAgICAgIFxcDQogIDAgICAgICYgMS4xMTMgJiAwICAgICBcXA0KICAwICAgICAmIDAuOTI2ICYgMCAgICAgXFwNCiAgMCAgICAgJiAwICAgICAmIDEuMDAwIFxcDQogIDAgICAgICYgMCAgICAgJiAxLjE4MCBcXA0KICAwICAgICAmIDAgICAgICYgMS4wODINCiAgXGVuZHtwbWF0cml4fSQkDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ2FyZ2FzOiBzaW4gc2lnbmlmaWNhbmNpYQ0KDQoxLiBFbiBlbCBvdXRwdXQgZGUgYWJham8sIGVsIGFyZ3VtZW50byBgc3RhbmRhcmRpemVkPVRSVUVgIGluZGljYSBxdWUgc2UgZGViZW4gZGV2b2x2ZXIgbGFzIGVzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcy4gDQoNCjIuIExhIGVzdGltYWNpw7NuIGVzdGFuZGFyaXphZGEgc2UgYWp1c3RhIHBvciBlbCBlcnJvciBlc3TDoW5kYXIgZGUgbGEgdmFyaWFibGUgaW1wbGljYWRhLCBwZXJtaXRpZW5kbyBhc8OtIGxhIGNvbXBhcmFjacOzbiBlbnRyZSBkaWZlcmVudGVzIHBhcsOhbWV0cm9zIGVuIHVuYSBlc2NhbGEgY29tw7puLg0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcGFyYW1ldGVyRXN0aW1hdGVzKENGQSwgc3RhbmRhcmRpemVkPVRSVUUpICU+JQ0KICBmaWx0ZXIob3AgPT0gIj1+IikgJT4lDQogIHNlbGVjdCgnRmFjdG9yJz1saHMsIA0KICAgICAgICAgJ0luZGljYWRvcic9cmhzLCANCiAgICAgICAgICdFc3RpbWFjacOzbic9ZXN0LCANCiAgICAgICAgICdFcnJvciBzdGQuJz1zZSwgDQogICAgICAgICAnRXN0aW1hY2nDs24gc3RkLic9c3RkLmFsbCwgI0VzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcw0KICAgICAgICAgJ1onPXosIA0KICAgICAgICAgJ3AgdmFsb3InPSBwdmFsdWUNCiAgICAgICAgICkgJT4lDQogIA0Ka2FibGUoZGlnaXRzID0gMywgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkZhY3RvciBMb2FkaW5ncyIpDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KcGFyYW1ldGVyRXN0aW1hdGVzKENGQSwgc3RhbmRhcmRpemVkPVRSVUUpICU+JQ0KICBmaWx0ZXIob3AgPT0gIj1+IikgJT4lDQogIHNlbGVjdCgnRmFjdG9yJz1saHMsIA0KICAgICAgICAgJ0luZGljYWRvcic9cmhzLCANCiAgICAgICAgICdFc3RpbWFjacOzbic9ZXN0LCANCiAgICAgICAgICdFcnJvciBzdGQuJz1zZSwgDQogICAgICAgICAnRXN0aW1hY2nDs24gc3RkLic9c3RkLmFsbCwgI0VzdGltYWNpb25lcyBlc3RhbmRhcml6YWRhcw0KICAgICAgICAgJ1onPXosIA0KICAgICAgICAgJ3AgdmFsb3InPSBwdmFsdWUNCiAgICAgICAgICkgJT4lDQogIA0Ka2FibGUoZGlnaXRzID0gMywgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkZhY3RvciBMb2FkaW5ncyIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDYXJnYXM6IGNvbiBzaWduaWZpY2FuY2lhDQoNCkVuIGxhIHNhbGlkYSBkZSBhYmFqbywgbG9zIGFzdGVyaXNjb3MgIGluZGljYW4gbGEgc2lnbmlmaWNhbmNpYSBkZSBsYSBlc3RpbWFjacOzbiBiYXNhZGEgZW4gbG9zIHZhbG9yZXMgJHAkICgqKiogcGFyYSAkcCA8IC4wMDEkLCAqKiBwYXJhICRwIDwgLjAxJCwgKiBwYXJhICRwIDwgLjA1JCkuDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpwYXJhbWV0ZXJFc3RpbWF0ZXMoQ0ZBLCBzdGFuZGFyZGl6ZWQ9VFJVRSkgJT4lDQogIA0KICBmaWx0ZXIob3AgPT0gIj1+IikgJT4lDQogIG11dGF0ZShzdGFycyA9IGlmZWxzZShwdmFsdWUgPCAuMDAxLCAiKioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdmFsdWUgPCAuMDEsICIqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB2YWx1ZSA8IC4wNSwgIioiLCAiIikpKSkgJT4lDQogIHNlbGVjdCgnRmFjdG9yJz1saHMsDQogICAgICAgICAnSW5kaWNhZG9yJz1yaHMsDQogICAgICAgICAnRXN0aW1hY2nDs24nPWVzdCwNCiAgICAgICAgICdFcnJvciBzdGQuJz1zZSwgDQogICAgICAgICAnWic9eiwNCiAgICAgICAgICdFc3RpbWFjacOzbiBzdGQuJz1zdGQuYWxsLCAjRXN0aW1hY2lvbmVzIGVzdGFuZGFyaXphZGFzDQogICAgICAgICAncCB2YWxvcic9IHB2YWx1ZSwgDQogICAgICAgICAnU2lnLic9c3RhcnMpICU+JQ0KICANCmthYmxlKGRpZ2l0cyA9IDMsIGFsaWduPSJjIiwgZm9ybWF0PSJwYW5kb2MiLCBjYXB0aW9uPSJDYXJnYXMgZmFjdG9yaWFsZXMiKQ0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEsIHN0YW5kYXJkaXplZD1UUlVFKSAlPiUNCiAgDQogIGZpbHRlcihvcCA9PSAiPX4iKSAlPiUNCiAgbXV0YXRlKHN0YXJzID0gaWZlbHNlKHB2YWx1ZSA8IC4wMDEsICIqKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHB2YWx1ZSA8IC4wMSwgIioqIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHZhbHVlIDwgLjA1LCAiKiIsICIiKSkpKSAlPiUNCiAgc2VsZWN0KCdGYWN0b3InPWxocywNCiAgICAgICAgICdJbmRpY2Fkb3InPXJocywNCiAgICAgICAgICdFc3RpbWFjacOzbic9ZXN0LA0KICAgICAgICAgJ0Vycm9yIHN0ZC4nPXNlLCANCiAgICAgICAgICdaJz16LA0KICAgICAgICAgJ0VzdGltYWNpw7NuIHN0ZC4nPXN0ZC5hbGwsICNFc3RpbWFjaW9uZXMgZXN0YW5kYXJpemFkYXMNCiAgICAgICAgICdwIHZhbG9yJz0gcHZhbHVlLCANCiAgICAgICAgICdTaWcuJz1zdGFycykgJT4lDQogIA0Ka2FibGUoZGlnaXRzID0gMywgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkNhcmdhcyBmYWN0b3JpYWxlcyIpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIEV4dHJheWVuZG8gdmFyaWFuemFzIHJlc2lkdWFsZXMgKGRlIGxvcyBlcnJvcmVzKQ0KDQojIyMgVmFyaWFuemEgcmVzaWR1YWw6IGNvbiBgaW5zcGVjdGANCg0KRXN0b3MgdmFsb3JlcyByZXByZXNlbnRhbiBsYXMgZGVzdmlhY2lvbmVzIGRlIGxvcyDDrXRlbXMgb2JzZXJ2YWRvcyBkZSBzdXMgdmFsb3JlcyBlc3BlcmFkb3MgYmFzYWRvcyBlbiBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIHkgbGEgbWVkaWEgbGF0ZW50ZSBkZWwgZmFjdG9yLg0KDQoqKkVsIGPDs2RpZ28uICoqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KaW5zcGVjdChDRkEsICJlc3QiKQ0KYXR0YWNoKGluc3BlY3QoQ0ZBLCAiZXN0IikpDQoNCiNsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCioqRWwgb3R1cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiNpbnNwZWN0KENGQSwgImVzdCIpDQojYXR0YWNoKGluc3BlY3QoQ0ZBLCAiZXN0IikpDQoNCiNsYW1iZGEgI2NhcmdhcyBmYWN0b3JpYWxlcw0KdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcyAoZGUgbG9zIGVycm9yZXMgZGUgbGFzIHZhci4gb2JzZXJ2YWRhcykNCiNwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCkVsIHJlc3VsdGFkbyBjb3JyZXNwb25kZSBhOiANCg0KDQokJFxib2xkc3ltYm9se1xUaGV0YX0gPQ0KICAgIFxiZWdpbntwbWF0cml4fQ0KICAwLjU0OSAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAxLjEzNCAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgIFxcDQogIDAgICAgICYgMCAgICAgJiAwLjg0NCAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICBcXA0KICAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjM3MSAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjQ0NiAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgIFxcDQogIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjM1NiAmIDAgICAgICYgMCAgICAgJiAwICAgICBcXA0KICAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjc5OSAmIDAgICAgICYgMCAgICAgXFwNCiAgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjQ4OCAmIDAgICAgIFxcDQogIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwICAgICAmIDAgICAgICYgMCAgICAgJiAwLjU2Ng0KICBcZW5ke3BtYXRyaXh9JCQNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBtYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcw0KDQojIyMgQ292YXJpYW56YXMgb2JzZXJ2YWRhOiBleHBsaWNhY2nDs24NCg0KMS4gTGEgKm1hdHJpeiBkZSBjb3ZhcmlhbnphcyBvYnNlcnZhZGFzKiBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCkgZXMgdW5hIG1hdHJpeiBxdWUgbXVlc3RyYSBsYXMgY292YXJpYW56YXMgZW50cmUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGVuIG51ZXN0cm9zIGRhdG9zLiANCg0KMi4gRXN0YSBtYXRyaXogZXMgdW5hIHJlcHJlc2VudGFjacOzbiBkaXJlY3RhIGRlIGxhIHJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzIHRhbCBjb21vIHNlIHByZXNlbnRhIGVuIHR1cyBkYXRvcyByZWFsZXMsIHNpbiBuaW5ndW5hIHN1cG9zaWNpw7NuIGFkaWNpb25hbCBvIG1vZGVsYWRvLg0KDQozLiBFbiB1biBtb2RlbG8gYmllbiBhanVzdGFkbywgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYSBcKFxib2xkc3ltYm9se1xTaWdtYX1cKSBkZWJlIGFwcm94aW1hciBhZGVjdWFkYW1lbnRlDQphIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBvYnNlcnZhZGFzIFwoXG1hdGhiZntTfV97XHRleHR7Y292fX1cKS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KDQojIyMgQ292YXJpYW56YXMgb2JzZXJ2YWRhczogY29uIGBjb3ZgIA0KDQpTZWEgXChcbWF0aGJme1h9ID0gKFhfMSwgXGxkb3RzLCBYXzkpXlx0b3BcKSBlbCB2ZWN0b3IgZGUgdmFyaWFibGVzIG9ic2VydmFkYXMgKMOtdGVtcyksIHkgc2VhIFwoTlwpIGVsIHRhbWHDsW8gbXVlc3RyYWwuIExhICoqbWF0cml6IGRlIGNvdmFyaWFuemFzIG9ic2VydmFkYXMqKiBzZSBkZWZpbmUgY29tbzoNCg0KXFsNClxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19ID0gXG9wZXJhdG9ybmFtZXtDb3Z9KFxtYXRoYmZ7WH0pLA0KXF0NCg0KeSwgcGFyYSBsb3MgZGF0b3MgYW5hbGl6YWRvcywgdG9tYSBsYSBmb3JtYToNCg0KDQoNClxbDQpcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fSA9IFxvcGVyYXRvcm5hbWV7Q292fShcbWF0aGJme1h9KSA9IA0KXGJlZ2lue3BtYXRyaXh9DQoxLjM2MyAmIDAuNDA5ICYgMC41ODIgJiAwLjUwNyAmIDAuNDQyICYgMC40NTYgJiAwLjA4NSAmIDAuMjY1ICYgMC40NjAgXFwNCjAuNDA5ICYgMS4zODYgJiAwLjQ1MyAmIDAuMjEwICYgMC4yMTIgJiAwLjI0OCAmIC0wLjA5NyAmIDAuMTEwICYgMC4yNDUgXFwNCjAuNTgyICYgMC40NTMgJiAxLjI3OSAmIDAuMjA5ICYgMC4xMTMgJiAwLjI0NSAmIDAuMDg5ICYgMC4yMTMgJiAwLjM3NSBcXA0KMC41MDcgJiAwLjIxMCAmIDAuMjA5ICYgMS4zNTUgJiAxLjEwMSAmIDAuODk5ICYgMC4yMjAgJiAwLjEyNiAmIDAuMjQ0IFxcDQowLjQ0MiAmIDAuMjEyICYgMC4xMTMgJiAxLjEwMSAmIDEuNjY1ICYgMS4wMTggJiAwLjE0MyAmIDAuMTgxICYgMC4yOTYgXFwNCjAuNDU2ICYgMC4yNDggJiAwLjI0NSAmIDAuODk5ICYgMS4wMTggJiAxLjIwMCAmIDAuMTQ1ICYgMC4xNjYgJiAwLjIzNyBcXA0KMC4wODUgJiAtMC4wOTcgJiAwLjA4OSAmIDAuMjIwICYgMC4xNDMgJiAwLjE0NSAmIDEuMTg3ICYgMC41MzcgJiAwLjM3NSBcXA0KMC4yNjUgJiAwLjExMCAmIDAuMjEzICYgMC4xMjYgJiAwLjE4MSAmIDAuMTY2ICYgMC41MzcgJiAxLjAyNSAmIDAuNDU5IFxcDQowLjQ2MCAmIDAuMjQ1ICYgMC4zNzUgJiAwLjI0NCAmIDAuMjk2ICYgMC4yMzcgJiAwLjM3NSAmIDAuNDU5ICYgMS4wMTgNClxlbmR7cG1hdHJpeH0uDQpcXQ0KDQoNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiMgQ2FsY3VsYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIG9ic2VydmFkYXMNClNfY292IDwtIHJvdW5kKGNvdihkYXQpLDMpDQoNCiMgTW9zdHJhciBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcw0KcHJpbnQoU19jb3YpDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyBDYWxjdWxhciBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgb2JzZXJ2YWRhcw0KU19jb3YgPC0gY292KGRhdCkNCg0KIyBNb3N0cmFyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBvYnNlcnZhZGFzDQpwcmludChTX2NvdikNCmBgYA0KDQoNCioqT2JzZXJ2YWNpw7NuIGNsYXZlLioqDQoNCkxhIGZ1bmNpw7NuIGBjb3YoKWAgY2FsY3VsYSBsYSBjb3ZhcmlhbnphIHVzYW5kbyBlbCBkaXZpc29yIFwoTi0xXCk6DQoNClxbDQpcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fQ0KPQ0KXGZyYWN7MX17Ti0xfQ0KXHN1bV97aT0xfV57Tn0NCihcbWF0aGJme3h9X2kgLSBcYmFye1xtYXRoYmZ7eH19KQ0KKFxtYXRoYmZ7eH1faSAtIFxiYXJ7XG1hdGhiZnt4fX0pXntcdG9wfS4NClxdDQoNCkVzdGEgZm9ybWEgcHJvZHVjZSB1biAqKmVzdGltYWRvciBpbnNlc2dhZG8qKiBkZSBsYSBjb3ZhcmlhbnphIHBvYmxhY2lvbmFsIGJham8NCnN1cHVlc3RvcyBjbMOhc2ljb3MsIHkgZXMgbGEgbWF0cml6IHF1ZSBzZSB1dGlsaXphIGhhYml0dWFsbWVudGUgZW4gZXN0YWTDrXN0aWNhDQpkZXNjcmlwdGl2YSB5IGFuw6FsaXNpcyBleHBsb3JhdG9yaW8uDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ292YXJpYW56YXMgb2JzZXJ2YWRhczogdXNhbmRvIGBsYXZUZWNoYA0KDQpDdWFuZG8gc2UgYWp1c3RhIHVuIG1vZGVsbyBDRkEgbWVkaWFudGUgKiptw6F4aW1hIHZlcm9zaW1pbGl0dWQgKE1MKSoqLCBgbGF2YWFuYCBubyB0cmFiYWphIGNvbiBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCksIHNpbm8gY29uIHVuYSB2ZXJzacOzbiBsaWdlcmFtZW50ZSBkaXN0aW50YSBkZSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgbXVlc3RyYWxlcywgZGVub3RhZGEgYXF1w60gcG9yIFwoXG1hdGhiZntTfV97XHRleHR7bGF2fX1cKS4gIEVzdGEgbWF0cml6IHB1ZWRlIGV4dHJhZXJzZSBkaXJlY3RhbWVudGUgZGVzZGUgZWwgb2JqZXRvIGFqdXN0YWRvOg0KDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpTX2xhdiA8LSBsYXZUZWNoKENGQSwgInNhbXBzdGF0IilbWzFdXSRjb3YNClNfbGF2DQpgYGANCg0KDQoqKkVsIG91dHB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQpTX2xhdiA8LSBsYXZUZWNoKENGQSwgInNhbXBzdGF0IilbWzFdXSRjb3YNClNfbGF2DQpgYGANCg0KDQp5IHJlc3VsdGEgc2VyOiANCg0KXFsNClxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19PSBcYmVnaW57cG1hdHJpeH0NCjEuMzU4NCAmIDAuNDA3NCAmIDAuNTc5OSAmIDAuNTA0OCAmIDAuNDQwNiAmIDAuNDU0OCAmIDAuMDg0OCAmIDAuMjYzOCAmIDAuNDU4MyBcXA0KMC40MDc0ICYgMS4zODE4ICYgMC40NTExICYgMC4yMDg5ICYgMC4yMTExICYgMC4yNDc1ICYgLTAuMDk2OCAmIDAuMTA5NyAmIDAuMjQ0MCBcXA0KMC41Nzk5ICYgMC40NTExICYgMS4yNzQ5ICYgMC4yMDgyICYgMC4xMTIzICYgMC4yNDQxICYgMC4wODgzICYgMC4yMTIzICYgMC4zNzM5IFxcDQowLjUwNDggJiAwLjIwODkgJiAwLjIwODIgJiAxLjM1MDcgJiAxLjA5NzggJiAwLjg5NTUgJiAwLjIxOTcgJiAwLjEyNTYgJiAwLjI0MzQgXFwNCjAuNDQwNiAmIDAuMjExMSAmIDAuMTEyMyAmIDEuMDk3OCAmIDEuNjU5OCAmIDEuMDE0NSAmIDAuMTQzMCAmIDAuMTgwNiAmIDAuMjk1MiBcXA0KMC40NTQ4ICYgMC4yNDc1ICYgMC4yNDQxICYgMC44OTU1ICYgMS4wMTQ1ICYgMS4xOTY0ICYgMC4xNDQxICYgMC4xNjU0ICYgMC4yMzYwIFxcDQowLjA4NDggJiAtMC4wOTY4ICYgMC4wODgzICYgMC4yMTk3ICYgMC4xNDMwICYgMC4xNDQxICYgMS4xODMxICYgMC41MzUyICYgMC4zNzMzIFxcDQowLjI2MzggJiAwLjEwOTcgJiAwLjIxMjMgJiAwLjEyNTYgJiAwLjE4MDYgJiAwLjE2NTQgJiAwLjUzNTIgJiAxLjAyMjAgJiAwLjQ1NzMgXFwNCjAuNDU4MyAmIDAuMjQ0MCAmIDAuMzczOSAmIDAuMjQzNCAmIDAuMjk1MiAmIDAuMjM2MCAmIDAuMzczMyAmIDAuNDU3MyAmIDEuMDE1MA0KXGVuZHtwbWF0cml4fQ0KXF0NCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoqKk9ic2VydmFjacOzbiBjbGF2ZS4qKg0KDQpMYSBtYXRyaXogXChcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fVwpIHNlIGNhbGN1bGEgdXNhbmRvIGVsIGRpdmlzb3IgXChOXCksIHlhIHF1ZSBlc3TDoSBmb3JtdWxhZGEgcGFyYSBlbCBlc3RpbWFkb3IgZGUgbcOheGltYSB2ZXJvc2ltaWxpdHVkIChNTCkuIEVuIHBhcnRpY3VsYXIsIGBsYXZhYW5gIChjb24gZXN0aW1hZG9yIE1MKSB0cmFiYWphIGludGVybmFtZW50ZSBjb246DQoNClxbDQpcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fQ0KPQ0KXGZyYWN7MX17Tn0NClxzdW1fe2k9MX1ee059DQooXG1hdGhiZnt4fV9pIC0gXGJhcntcbWF0aGJme3h9fSkNCihcbWF0aGJme3h9X2kgLSBcYmFye1xtYXRoYmZ7eH19KV57XHRvcH0sDQpcXQ0KDQpFc3RhIGZvcm1hIGFwYXJlY2UgZGUgbWFuZXJhIG5hdHVyYWwgZW4gbGEgKipmdW5jacOzbiBkZSB2ZXJvc2ltaWxpdHVkIGRlIGxhIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYSoqLCB5IHBvciBlbGxvIGNvbnN0aXR1eWUgbGEgYmFzZSB0ZcOzcmljYSBkZWwgZXN0aW1hZG9yIGRlICptw6F4aW1hIHZlcm9zaW1pbGl0dWQgKE1MKSouIEF1bnF1ZSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19XCkgbm8gZXMgdW4gZXN0aW1hZG9yIGluc2VzZ2FkbywgZXMgKmludGVybmFtZW50ZSBjb2hlcmVudGUqIGNvbiBlbCBwcm9jZWRpbWllbnRvIGRlIGVzdGltYWNpw7NuIE1MLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIENvdmFyaWFuemFzIG9ic2VydmFkYXM6IGNvbXBhcmFjacOzbiBlbnRyZSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCkgeSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19XCkNCg0KQXVucXVlIGFtYmFzIG1hdHJpY2VzIHNlIGNvbnN0cnV5ZW4gYSBwYXJ0aXIgZGUgbG9zIG1pc21vcyBkYXRvcywgKm5vIHNvbiBpZMOpbnRpY2FzKiwgeWEgcXVlIGRpZmllcmVuIMO6bmljYW1lbnRlIGVuIGVsIGRpdmlzb3IgdXRpbGl6YWRvOg0KDQpcWw0KXG1hdGhiZntTfV97XHRleHR7Y292fX0NCj0NClxmcmFje059e04tMX0NClwsXG1hdGhiZntTfV97XHRleHR7bGF2fX0uDQpcXQ0KDQpQb3IgdGFudG8sIGxhIGRpZmVyZW5jaWEgZW50cmUgZWxsYXMgZXMgcHVyYW1lbnRlIHVuICpmYWN0b3IgZGUgZXNjYWxhKi4gQ3VhbmRvIGVsIHRhbWHDsW8gbXVlc3RyYWwgXChOXCkgZXMgZ3JhbmRlLCBlc3RhIGRpZmVyZW5jaWEgZXMgcGVxdWXDsWEsIHBlcm8gKm5vIGVzIGV4YWN0YW1lbnRlIGNlcm8qLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIENvdmFyaWFuemFzIG9ic2VydmFkYXM6IGNvbnNlY3VlbmNpYSBwcsOhY3RpY2EgZW4gQ0ZBIHkgU0VNDQoNCkRlYmlkbyBhIGVzdGEgZGlmZXJlbmNpYSwgKm5vIGRlYmUgZXNwZXJhcnNlKiBxdWUgY29pbmNpZGFuIGV4YWN0YW1lbnRlIGxhcyBzaWd1aWVudGVzIGNhbnRpZGFkZXM6DQoNClxbDQpcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fSAtIFxib2xkc3ltYm9se1xTaWdtYX0NClxxdWFkIFx0ZXh0e3l9IFxxdWFkDQpcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSAtIFxib2xkc3ltYm9se1xTaWdtYX0sDQpcXQ0KDQpkb25kZSBcKFxib2xkc3ltYm9se1xTaWdtYX1cKSBlcyBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbMOtY2l0YSBlc3RpbWFkYSBiYWpvIGVsIG1vZGVsbyBDRkEuIEVzdG8gZXhwbGljYSBwb3IgcXXDqToNCg0KLSBSZXN0YXMgbWFudWFsZXMgZGUgbWF0cmljZXMsDQoNCi0gYHJlc2lkdWFscyhDRkEpJGNvdmAsDQoNCi0gYHJlc2lkdWFscyhDRkEsIHR5cGUgPSAiY29yIikkY292YCwNCg0KKm5vIHZhbiBhIHByb2R1Y2lyIG1hdHJpY2VzIG51bcOpcmljYW1lbnRlIGlkw6ludGljYXMqLCBhdW4gY3VhbmRvIHRvZGFzIHJlcHJlc2VudGFuIGRpc2NyZXBhbmNpYXMgZW50cmUgbG8gb2JzZXJ2YWRvIHkgbG8gaW1wbGljYWRvIHBvciBlbCBtb2RlbG8uIEVzdG8gc2UgZXhwbGljYXLDoSBjb24gbcOhcyBkZXRhbGxlcyBlbiBsYXMgc2lndWllbnRlcyBzZWNjaW9uZXMuIA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIENvdmFyaWFuemFzIG9ic2VydmFkYXM6IHJlc3VtZW4gY2xhdmUNCg0KLSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCk6IG1hdHJpeiBkZXNjcmlwdGl2YSBjbMOhc2ljYSAoZnVlcmEgZGVsIG1hcmNvIE1MKS4NCg0KLSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19XCk6IG1hdHJpeiBjb2hlcmVudGUgY29uIGxhIHRlb3LDrWEgZGUgbcOheGltYSAgIHZlcm9zaW1pbGl0dWQuDQogIA0KLSBgbGF2YWFuYCBlcyAqaW50ZXJuYW1lbnRlIGNvbnNpc3RlbnRlKjogc2llbXByZSBjb21wYXJhIGNhbnRpZGFkZXMgICBjb25zdHJ1aWRhcyBiYWpvIGVsIG1pc21vIGNyaXRlcmlvIE1MLg0KDQpQb3IgZWxsbywgbGFzIGRpZmVyZW5jaWFzIG51bcOpcmljYXMgb2JzZXJ2YWRhcyBzb24gKmVzcGVyYWRhcywgY29ycmVjdGFzIHkgdGXDs3JpY2FtZW50ZSBqdXN0aWZpY2FkYXMqLg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhDQoNCiMjIyBDb3ZhcmlhbnphcyBpbXBsaWNhZGE6IGRlZmluaWNpw7NuIHkgb2JzZXJ2YWNpb25lcw0KDQoNCioqRGVmaW5pY2nDs24gbWF0ZW3DoXRpY2EuKioNCg0KUmVjb3JkZW1vcyBxdWUNCg0KJCRcU2lnbWEgXDs9XDsgXExhbWJkYSBcO1xQc2lcOyBcTGFtYmRhXntcdG9wfSBcOytcOyBcVGhldGEkJA0KDQpEb25kZToNCiAgDQogICsgJFxTaWdtYSQgcmVwcmVzZW50YSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgZXN0aW1hZGEgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIChsYSBsbGFtYWRhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEpLg0KICAgDQogICsgJFxMYW1iZGEkIGVzIGxhIG1hdHJpeiBkZSBjYXJnYXMgZmFjdG9yaWFsZXMuDQogICAgDQogICsgJFxQc2kkIGVzIGxhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgZGUgbG9zIGZhY3RvcmVzIGxhdGVudGVzLg0KICAgIA0KICArICRcVGhldGEkIGVzIGxhIG1hdHJpeiBkZSB2YXJpYW56YXMgcmVzaWR1YWxlcy4NCiAgDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQoqKk9ic2VydmFjaW9uZXMgaW1wb3J0YW50ZXMuKioNCg0KMS4gTGEgKm1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEqIGVuIHVuIG1vZGVsbyBkZSBhbsOhbGlzaXMgZmFjdG9yaWFsIGNvbmZpcm1hdG9yaW8gKENGQSkgZXMgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIHByZWRpY2hhIHBvciBlbCBtb2RlbG8gYWp1c3RhZG8uIA0KDQoyLiBFc3RhIG1hdHJpeiBtdWVzdHJhIGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgcXVlIGVsIG1vZGVsbyBzdXBvbmUgcXVlIGV4aXN0aXLDrWFuLCBiYXNhZG8gZW4gbGFzIHJlbGFjaW9uZXMgZXNwZWNpZmljYWRhcyBlbnRyZSBsYXMgdmFyaWFibGVzIGxhdGVudGVzIHkgb2JzZXJ2YWRhcy4NCg0KMy4gKkludGVycHJldGFjacOzbiBkZSBsYSBNYXRyaXogZGUgQ292YXJpYW56YXMgSW1wbGljYWRhLiogDQogIA0KICArIExhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEgcmVmbGVqYSBjw7NtbyBlbCBtb2RlbG8gYWp1c3RhZG8gZXNwZXJhIHF1ZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgc2UgcmVsYWNpb25lbiBlbnRyZSBzw60uIA0KICANCiAgKyBFcyB1bmEgcmVwcmVzZW50YWNpw7NuIG1hdGVtw6F0aWNhIGRlIGxhcyBzdXBvc2ljaW9uZXMgZGVsIG1vZGVsby4gDQogIA0KNC4gQ29tcGFyYXIgZXN0YSBtYXRyaXogY29uIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBvYnNlcnZhZGEgKGxhcyBjb3ZhcmlhbnphcyByZWFsZXMgZGUgbG9zIGRhdG9zKSBwZXJtaXRlIGV2YWx1YXIgbGEgY2FsaWRhZCBkZWwgYWp1c3RlIGRlbCBtb2RlbG8uDQoNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ292YXJpYW56YXMgaW1wbGljYWRhOiBjb24gcHJvZHVjdG8gZGUgbWF0cmljZXMgIChwcmltZXJhIGZvcm1hKQ0KDQoNCg0KDQpgYGB7cn0NClNpZ21hIDwtIGxhbWJkYSAlKiUgIHBzaSAlKiUgdChsYW1iZGEpICsgdGhldGENCnJvdW5kKFNpZ21hLCAzKQ0KYGBgDQoNCkVzIGRlY2lyLCANCg0KJCRcYm9sZHN5bWJvbHtcU2lnbWF9IFw7ID0gXDsgDQogICAgICAgICAgXGJlZ2lue3BtYXRyaXh9DQogICAgMS4zNTggJiAwLjQ0OCAmIDAuNTkwICYgMC40MDggJiAwLjQ1NCAmIDAuMzc4ICYgMC4yNjIgJiAwLjMwOSAmIDAuMjg0IFxcDQogICAgMC40NDggJiAxLjM4MiAmIDAuMzI3ICYgMC4yMjYgJiAwLjI1MiAmIDAuMjA5ICYgMC4xNDUgJiAwLjE3MSAmIDAuMTU3IFxcDQogICAgMC41OTAgJiAwLjMyNyAmIDEuMjc1ICYgMC4yOTggJiAwLjMzMSAmIDAuMjc2ICYgMC4xOTEgJiAwLjIyNiAmIDAuMjA3IFxcDQogICAgMC40MDggJiAwLjIyNiAmIDAuMjk4ICYgMS4zNTEgJiAxLjA5MCAmIDAuOTA3ICYgMC4xNzMgJiAwLjIwNSAmIDAuMTg4IFxcDQogICAgMC40NTQgJiAwLjI1MiAmIDAuMzMxICYgMS4wOTAgJiAxLjY2MCAmIDEuMDEwICYgMC4xOTMgJiAwLjIyOCAmIDAuMjA5IFxcDQogICAgMC4zNzggJiAwLjIwOSAmIDAuMjc2ICYgMC45MDcgJiAxLjAxMCAmIDEuMTk2ICYgMC4xNjEgJiAwLjE5MCAmIDAuMTc0IFxcDQogICAgMC4yNjIgJiAwLjE0NSAmIDAuMTkxICYgMC4xNzMgJiAwLjE5MyAmIDAuMTYxICYgMS4xODMgJiAwLjQ1MyAmIDAuNDE1IFxcDQogICAgMC4zMDkgJiAwLjE3MSAmIDAuMjI2ICYgMC4yMDUgJiAwLjIyOCAmIDAuMTkwICYgMC40NTMgJiAxLjAyMiAmIDAuNDkwIFxcDQogICAgMC4yODQgJiAwLjE1NyAmIDAuMjA3ICYgMC4xODggJiAwLjIwOSAmIDAuMTc0ICYgMC40MTUgJiAwLjQ5MCAmIDEuMDE1DQogICAgXGVuZHtwbWF0cml4fSQkDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb3ZhcmlhbnphcyBpbXBsaWNhZGE6IGNvbiBgZml0dGVkYCAgKHNlZ3VuZGEgZm9ybWEpDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojIE9idGVuZXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYXMNCmZpdHRlZF92YWx1ZXMgPC0gZml0dGVkKENGQSkNCmZpdHRlZF92YWx1ZXMNCg0KIyBFeHRyYWVyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGFzDQpTaWdtYSA8LSBmaXR0ZWRfdmFsdWVzJGNvdg0KDQojIE1vc3RyYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYXMNCnByaW50KFNpZ21hKQ0KYGBgDQoNCg0KDQoqKkV4cGxpY2FjacOzbiBkZWwgY8OzZGlnby4qKg0KDQpTZSB1c2EgbGEgZnVuY2nDs24gYGZpdHRlZChDRkEpYCBwYXJhIG9idGVuZXIgbGFzIG1hdHJpY2VzIGltcGxpY2FkYXMgZGVsIG1vZGVsbyBhanVzdGFkbzoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIE9idGVuZXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYXMNCmZpdHRlZF92YWx1ZXMgPC0gZml0dGVkKENGQSkNCmZpdHRlZF92YWx1ZXMNCmBgYA0KDQpMdWVnbywgc2UgZXh0cmFlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGEgY29uIGAuLi4kY292YC4gRWwgb3V0cHV0IGNvcnJlc3BvbmRpZW50ZSBlczogDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyBPYnRlbmVyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGFzDQpmaXR0ZWRfdmFsdWVzIDwtIGZpdHRlZChDRkEpDQoNCiMgRXh0cmFlciBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhcw0KU2lnbWEgPC0gZml0dGVkX3ZhbHVlcyRjb3YNCg0KIyBNb3N0cmFyIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsaWNhZGFzDQpwcmludChTaWdtYSkNCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ292YXJpYW56YXMgaW1wbGljYWRhOiBjb24gYGZpdHRlZGAgeSBgdW5jbGFzcygpYCAgKHRlcmNlcmEgZm9ybWEpDQoNCmBgYHtyfQ0KU2lnbWEgPC0gcm91bmQodW5jbGFzcyhmaXR0ZWQoQ0ZBKSRjb3YpLDMpDQpTaWdtYQ0KYGBgDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ292YXJpYW56YXMgaW1wbGljYWRhOiBjb24gYGxhdkluc3BlY3RgIChjdWFydGEgZm9ybWEpDQoNCmBgYHtyfQ0KU2lnbWEgPC0gbGF2SW5zcGVjdChDRkEsICJzaWdtYSIpDQpTaWdtYQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBsYXMgbWF0cmljZXMgZGUgY29ycmVsYWNpb25lcyBvYnNlcnZhZGFzIGUgaW1wbGljYWRhcw0KDQojIyMgQ29ycmVsYWNpb25lczogbW90aXZhY2nDs24NCg0KRW4gYW7DoWxpc2lzIGZhY3RvcmlhbCBjb25maXJtYXRvcmlvIChDRkEpIHksIGVuIGdlbmVyYWwsIGVuIG1vZGVsb3MgZGUgZWN1YWNpb25lcyBlc3RydWN0dXJhbGVzIChTRU0pLCBlcyBmcmVjdWVudGUgZXZhbHVhciBlbCBhanVzdGUgZGVsIG1vZGVsbyAqKmVuIGxhIGVzY2FsYSBkZSBjb3JyZWxhY2lvbmVzKiosIHlhIHF1ZSBlc3RhIGVzY2FsYSBlbGltaW5hIGxhIGluZmx1ZW5jaWEgZGUgbGFzIHVuaWRhZGVzIGRlIG1lZGlkYSB5IHBlcm1pdGUgY29tcGFyYWNpb25lcyBkaXJlY3RhcyBlbnRyZSBwYXJlcyBkZSB2YXJpYWJsZXMuIEFudGVzIGRlIGRlZmluaXIgcmVzaWR1b3MgZW4gY29ycmVsYWNpb25lcywgZXMgZnVuZGFtZW50YWwgZGlzdGluZ3VpciBjb24NCmNsYXJpZGFkIGVudHJlOg0KDQotICoqQ29ycmVsYWNpb25lcyBvYnNlcnZhZGFzKiosIG9idGVuaWRhcyBhIHBhcnRpciBkZSBsb3MgZGF0b3MsIHkgIA0KDQotICpDb3JyZWxhY2lvbmVzIGltcGxpY2FkYXMgcG9yIGVsIG1vZGVsbyoqLCBvYnRlbmlkYXMgYSBwYXJ0aXIgZGUgbGEgbWF0cml6IGRlICAgY292YXJpYW56YXMgaW1wbGljYWRhIFwoXGJvbGRzeW1ib2x7XFNpZ21hfVwpLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMgQ29ycmVsYWNpb25lczogZGUgY292YXJpYW56YXMgYSBjb3JyZWxhY2lvbmVzDQoNClNlYSBcKFxtYXRoYmZ7QX1cKSB1bmEgbWF0cml6IGRlIGNvdmFyaWFuemFzIChtdWVzdHJhbCBvIGltcGxpY2FkYSBwb3IgdW4gbW9kZWxvKS4NCkxhIG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzIGFzb2NpYWRhIGEgXChcbWF0aGJme0F9XCkgc2Ugb2J0aWVuZSBtZWRpYW50ZSBsYQ0KdHJhbnNmb3JtYWNpw7NuOg0KDQpcWw0KXG9wZXJhdG9ybmFtZXtDb3J9KFxtYXRoYmZ7QX0pDQo9DQpcbWF0aGJme0R9X3tcbWF0aGJme0F9fV57LTEvMn1cLCAgDQpcbWF0aGJme0F9XCwNClxtYXRoYmZ7RH1fe1xtYXRoYmZ7QX19XnstMS8yfSwNClxdDQoNCmRvbmRlDQoNClxbDQpcbWF0aGJme0R9X3tcbWF0aGJme0F9fSA9IFxvcGVyYXRvcm5hbWV7ZGlhZ30oYV97MTF9LCBcbGRvdHMsIGFfe3BwfSkNClxdDQoNCmVzIGxhIG1hdHJpeiBkaWFnb25hbCBxdWUgY29udGllbmUgbGFzIHZhcmlhbnphcyBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMuIEVzdGEgdHJhbnNmb3JtYWNpw7NuIGVzdGFuZGFyaXphIGNhZGEgdmFyaWFibGUgcGFyYSBxdWUgdGVuZ2EgdmFyaWFuemEgdW5pdGFyaWEsIHByb2R1Y2llbmRvIHVuYSBtYXRyaXogY29uIHVub3MgZW4gbGEgZGlhZ29uYWwgeSBjb2VmaWNpZW50ZXMgZGUgY29ycmVsYWNpw7NuIGZ1ZXJhIGRlIGVsbGEuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBDb3JyZWxhY2lvbmVzOiAgb2JzZXJ2YWRhcw0KDQpFbiBDRkEvU0VNIHB1ZWRlbiBjb25zaWRlcmFyc2UgKipkb3MgdmVyc2lvbmVzKiogZGUgbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgb2JzZXJ2YWRhcywgZGVwZW5kaWVuZG8gZGUgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIG11ZXN0cmFsZXMgZGUgcGFydGlkYS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIyBDb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMgZGVzY3JpcHRpdmFzIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNClNpIHNlIHBhcnRlIGRlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBtdWVzdHJhbCBjbMOhc2ljYSwNCg0KXFsNClxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19DQo9DQpcZnJhY3sxfXtOLTF9DQpcc3VtX3tpPTF9XntOfQ0KKFxtYXRoYmZ7eH1faSAtIFxiYXJ7XG1hdGhiZnt4fX0pDQooXG1hdGhiZnt4fV9pIC0gXGJhcntcbWF0aGJme3h9fSlee1x0b3B9LA0KXF0NCg0KZW50b25jZXMgbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgb2JzZXJ2YWRhcyBkZXNjcmlwdGl2YXMgc2UgZGVmaW5lIGNvbW86DQoNClxbDQpcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7Y292fX0pDQo9DQpcbWF0aGJme0R9KFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19KV57LTEvMn1cLA0KXG1hdGhiZntTfV97XHRleHR7Y292fX1cLA0KXG1hdGhiZntEfShcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fSleey0xLzJ9Lg0KXF0NCg0KRXN0YSBlcyBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyBxdWUgc2UgdXRpbGl6YSBoYWJpdHVhbG1lbnRlIGVuIGVzdGFkw61zdGljYSBkZXNjcmlwdGl2YSB5IGFuw6FsaXNpcyBleHBsb3JhdG9yaW8uDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyMgQ29ycmVsYWNpb25lcyBvYnNlcnZhZGFzIGNvaGVyZW50ZXMgY29uIE1MIChgbGF2YWFuYCkgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KQ3VhbmRvIGVsIG1vZGVsbyBDRkEgc2UgYWp1c3RhIG1lZGlhbnRlICoqbcOheGltYSB2ZXJvc2ltaWxpdHVkIChNTCkqKiwgYGxhdmFhbmAgdHJhYmFqYSBpbnRlcm5hbWVudGUgY29uIGxhIG1hdHJpejoNCg0KXFsNClxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19DQo9DQpcZnJhY3sxfXtOfQ0KXHN1bV97aT0xfV57Tn0NCihcbWF0aGJme3h9X2kgLSBcYmFye1xtYXRoYmZ7eH19KQ0KKFxtYXRoYmZ7eH1faSAtIFxiYXJ7XG1hdGhiZnt4fX0pXntcdG9wfS4NClxdDQoNCkxhIGNvcnJlc3BvbmRpZW50ZSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyBvYnNlcnZhZGFzLCBjb2hlcmVudGUgY29uIGVsIG1hcmNvIE1MLA0KZXM6DQoNClxbDQpcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7bGF2fX0pDQo9DQpcbWF0aGJme0R9KFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19KV57LTEvMn1cLA0KXG1hdGhiZntTfV97XHRleHR7bGF2fX1cLA0KXG1hdGhiZntEfShcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSleey0xLzJ9Lg0KXF0NCg0KQXVucXVlIFwoXG1hdGhiZntTfV97XHRleHR7Y292fX1cKSB5IFwoXG1hdGhiZntTfV97XHRleHR7bGF2fX1cKSBkaWZpZXJlbiBwb3IgdW4gZmFjdG9yIGRlIGVzY2FsYSwgc3VzIG1hdHJpY2VzIGRlIGNvcnJlbGFjaW9uZXMgc3VlbGVuIHNlciAqKm11eSBzaW1pbGFyZXMqKiwgeWEgcXVlIGVsIHByb2Nlc28gZGUgZXN0YW5kYXJpemFjacOzbiBlbGltaW5hIGdyYW4gcGFydGUgZGUgZXNhIGRpZmVyZW5jaWEuDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBDb3JyZWxhY2lvbmVzOiAgaW1wbGljYWRhcyBwb3IgZWwgbW9kZWxvDQoNClNlYSBcKFxib2xkc3ltYm9se1xTaWdtYX1cKSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgKippbXBsaWNhZGEgcG9yIGVsIG1vZGVsbyBDRkEgYWp1c3RhZG8qKiwgZXN0aW1hZGEgYSBwYXJ0aXIgZGUgbG9zIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8uIExhIG1hdHJpeiBkZSAqKmNvcnJlbGFjaW9uZXMgaW1wbGljYWRhcyBwb3IgZWwgbW9kZWxvKiogc2Ugb2J0aWVuZSBlc3RhbmRhcml6YW5kbyBcKFxib2xkc3ltYm9se1xTaWdtYX1cKSBhIHZhcmlhbnphcyB1bml0YXJpYXM6DQoNClxbOg0KDQpcWw0KXG9wZXJhdG9ybmFtZXtDb3J9KFxib2xkc3ltYm9se1xTaWdtYX0pDQo9DQpcbWF0aGJme0R9KFxib2xkc3ltYm9se1xTaWdtYX0pXnstMS8yfVwsDQpcYm9sZHN5bWJvbHtcU2lnbWF9XCwNClxtYXRoYmZ7RH0oXGJvbGRzeW1ib2x7XFNpZ21hfSleey0xLzJ9Lg0KXF0NCg0KRW4gbGEgZsK0cm9tdWxhIGRlIGFycmliYSwgbGEgbWF0cml6IFwoXG1hdGhiZntEfShcYm9sZHN5bWJvbHtcU2lnbWF9KVwpIGVzIGxhICoqbWF0cml6IGRpYWdvbmFsIGRlIHZhcmlhbnphcyBpbXBsaWNhZGFzIHBvciBlbCBtb2RlbG8qKiwgZXMgZGVjaXI6DQoNClxbDQpcbWF0aGJme0R9KFxib2xkc3ltYm9se1xTaWdtYX0pDQo9DQpcb3BlcmF0b3JuYW1le2RpYWd9XGJpZyhcc2lnbWFfezExfSxcc2lnbWFfezIyfSxcbGRvdHMsXHNpZ21hX3twcH1cYmlnKS4NClxdDQoNCkFxdcOtOg0KDQotIFwoXHNpZ21hX3tpaX1cKSBlcyBsYSAqKnZhcmlhbnphIHByZWRpY2hhIHBvciBlbCBtb2RlbG8qKiBwYXJhIGxhIHZhcmlhYmxlIG9ic2VydmFkYSBcKFhfaVwpLA0KDQotIFwoXG1hdGhiZntEfShcYm9sZHN5bWJvbHtcU2lnbWF9KV57LTEvMn09XG9wZXJhdG9ybmFtZXtkaWFnfVwhXGxlZnQoXGZyYWN7MX17XHNxcnR7XHNpZ21hX3sxMX19fSxcbGRvdHMsXGZyYWN7MX17XHNxcnR7XHNpZ21hX3twcH19fVxyaWdodClcKSAgZXMgbGEgbWF0cml6IHF1ZSAqKmVzdGFuZGFyaXphKiogY2FkYSB2YXJpYWJsZSBkaXZpZGllbmRvIHBvciBzdSBkZXN2aWFjacOzbiAgIGVzdMOhbmRhciBpbXBsaWNhZGEgcG9yIGVsIG1vZGVsby4NCg0KRW4gY29uc2VjdWVuY2lhLCBcKFxvcGVyYXRvcm5hbWV7Q29yfShcYm9sZHN5bWJvbHtcU2lnbWF9KVwpIGVzIGxhIG1hdHJpeiBxdWUgY29udGllbmUgbGFzICoqY29ycmVsYWNpb25lcyBxdWUgZWwgbW9kZWxvIENGQSBwcmVkaWNlKiouICBlbnRyZSBsb3Mgw610ZW1zLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBDb3JyZWxhY2lvbmVzOiBjw6FsY3VsbyBlbiBgUmANCg0KIyMjIyBFbCBjw7NkaWdvIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCg0KRW4gZXN0YSBzZWNjacOzbiBjYWxjdWxhbW9zIGxhcyBzaWd1aWVudGVzIHRyZXMgbWF0cmljZXMgZGUgY29ycmVsYWNpb25lczoNCg0KLSBcKFxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fSlcKTogY29ycmVsYWNpb25lcyBvYnNlcnZhZGFzIGEgcGFydGlyIGRlIGBjb3YoZGF0KWAgKGRpdmlzb3IgXChOLTFcKSkuDQoNCi0gXChcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7bGF2fX0pXCk6IGNvcnJlbGFjaW9uZXMgb2JzZXJ2YWRhcyBhIHBhcnRpciBkZSBsYSBtYXRyaXogdXNhZGEgcG9yIGBsYXZhYW5gIGJham8gTUwgKGRpdmlzb3IgXChOXCkpLg0KDQotIFwoXG9wZXJhdG9ybmFtZXtDb3J9KFxib2xkc3ltYm9se1xTaWdtYX0pXCk6IGNvcnJlbGFjaW9uZXMgKmltcGxpY2FkYXMgcG9yIGVsIG1vZGVsbyosIGNvbnN0cnVpZGFzIGEgcGFydGlyIGRlIGxhIG1hdHJpeiBcKFxib2xkc3ltYm9se1xTaWdtYX1cKSBhanVzdGFkYS4NCg0KTGEgZnVuY2nDs24gYGNvdjJjb3JfbWF0KClgIGNvbnZpZXJ0ZSB1bmEgbWF0cml6IGRlICpjb3ZhcmlhbnphcyogXChcbWF0aGJme0F9XCkgZW4gc3UgbWF0cml6IGRlICpjb3JyZWxhY2lvbmVzKiBcKFxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme0F9KVwpIG1lZGlhbnRlIGxhIHRyYW5zZm9ybWFjacOzbjoNCg0KXFsNClxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme0F9KQ0KPQ0KXG1hdGhiZntEfV97XG1hdGhiZntBfX1eey0xLzJ9XCwNClxtYXRoYmZ7QX1cLA0KXG1hdGhiZntEfV97XG1hdGhiZntBfX1eey0xLzJ9LA0KXHFxdWFkDQpcbWF0aGJme0R9X3tcbWF0aGJme0F9fT1cb3BlcmF0b3JuYW1le2RpYWd9KGFfezExfSxcbGRvdHMsYV97cHB9KS4NClxdDQoNCkFxdcOtOg0KDQotIFwoXG1hdGhiZntEfV97XG1hdGhiZntBfX1cKSBlcyBsYSBtYXRyaXogZGlhZ29uYWwgcXVlIGNvbnRpZW5lIGxhcyAqdmFyaWFuemFzKiAobGEgZGlhZ29uYWwgZGUgXChcbWF0aGJme0F9XCkpLg0KDQotIFwoXG1hdGhiZntEfV97XG1hdGhiZntBfX1eey0xLzJ9XCkgY29udGllbmUgZW4gbGEgZGlhZ29uYWwgXCgxL1xzcXJ0e2Ffe2pqfX1cKSwgZXMgZGVjaXIsIGVsIGludmVyc28gZGUgbGFzICpkZXN2aWFjaW9uZXMgZXN0w6FuZGFyKi4NCg0KLSBBbCBwcmVtdWx0aXBsaWNhciB5IHBvc3RtdWx0aXBsaWNhciBwb3IgXChcbWF0aGJme0R9XnstMS8yfVwpLCBzZSDigJxlc3RhbmRhcml6YW7igJ0gbGFzIGNvdmFyaWFuemFzIHBhcmEgcXVlIGxhIGRpYWdvbmFsIHF1ZWRlIGVuIDEgeSBlbCByZXN0byBzZWFuIGNvcnJlbGFjaW9uZXMuDQoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojIDEpIE1hdHJpY2VzIGRlIGNvdmFyaWFuemFzICJvYnNlcnZhZGFzIg0KU19jb3YgPC0gY292KGRhdCkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNsw6FzaWNvLCBkaXZpc29yIE4tMQ0KU19sYXYgPC0gbGF2VGVjaChDRkEsICJzYW1wc3RhdCIpW1sxXV0kY292ICAjIGRpdmlzb3IgTiAoTUwpDQoNCiMgMikgTWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYSBwb3IgZWwgbW9kZWxvDQpTaWdtYSA8LSBmaXR0ZWQoQ0ZBKSRjb3YNCg0KIyAzKSBGdW5jacOzbiBhdXhpbGlhcjogQ292IC0+IENvcg0KY292MmNvcl9tYXQgPC0gZnVuY3Rpb24oQSkgew0KICBEaW52aGFsZiA8LSBkaWFnKDEgLyBzcXJ0KGRpYWcoQSkpKQ0KICBEaW52aGFsZiAlKiUgQSAlKiUgRGludmhhbGYNCn0NCg0KIyA0KSBDb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMgIChjbMOhc2ljbywgZGljaXNvciBOLTEpDQpDb3JfU2NvdiA8LSBjb3YyY29yX21hdChTX2NvdikNCkNvcl9TY292IA0KDQojIDQpIENvcnJlbGFjaW9uZXMgb2JzZXJ2YWRhcyAoY29oZXJlbnRlIGNvbiBNTCwgbGF2YWFuLCBkaXZpc29yIE4pDQpDb3JfU2xhdiA8LSBjb3YyY29yX21hdChTX2xhdikNCkNvcl9TbGF2DQoNCiMgNCkgQ29ycmVsYWNpb25lcyBpbXBsaWNhZGFzIHBvciBlbCBtb2RlbG8NCkNvcl9TaWdtYSA8LSBjb3YyY29yX21hdChTaWdtYSkNCkNvcl9TaWdtYQ0KYGBgDQoNCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIDEpIE1hdHJpY2VzIGRlIGNvdmFyaWFuemFzICJvYnNlcnZhZGFzIg0KU19jb3YgPC0gY292KGRhdCkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNsw6FzaWNvLCBkaXZpc29yIE4tMQ0KU19sYXYgPC0gbGF2VGVjaChDRkEsICJzYW1wc3RhdCIpW1sxXV0kY292ICAjIGRpdmlzb3IgTiAoTUwpDQoNCiMgMikgTWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYSBwb3IgZWwgbW9kZWxvDQpTaWdtYSA8LSBmaXR0ZWQoQ0ZBKSRjb3YNCg0KIyAzKSBGdW5jacOzbiBhdXhpbGlhcjogQ292IC0+IENvcg0KY292MmNvcl9tYXQgPC0gZnVuY3Rpb24oQSkgew0KICBEaW52aGFsZiA8LSBkaWFnKDEgLyBzcXJ0KGRpYWcoQSkpKQ0KICBEaW52aGFsZiAlKiUgQSAlKiUgRGludmhhbGYNCn0NCg0KIyA0KSBDb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMgIChjbMOhc2ljbywgZGljaXNvciBOLTEpDQpDb3JfU2NvdiA8LSBjb3YyY29yX21hdChTX2NvdikNCg0KIyA0KSBDb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMgKGNvaGVyZW50ZSBjb24gTUwsIGxhdmFhbiwgZGl2aXNvciBOKQ0KQ29yX1NsYXYgPC0gY292MmNvcl9tYXQoU19sYXYpDQoNCiMgNCkgQ29ycmVsYWNpb25lcyBpbXBsaWNhZGFzIHBvciBlbCBtb2RlbG8NCkNvcl9TaWdtYSA8LSBjb3YyY29yX21hdChTaWdtYSkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIyBJbnRlcnByZXRhY2nDs24gZGUgbGEgc2FsaWRhIHBhcmEgXChcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7Y292fX0pXCkgeSBcKFxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSlcKSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpMYXMgbWF0cmljZXMgZGUgY29ycmVsYWNpb25lcyBvYnNlcnZhZGFzIChkZXNkZSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCkgeSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19XCkpIHNvbiANCg0KDQpgYGB7cn0NCkNvcl9TY292DQpDb3JfU2xhdg0KYGBgDQoNCkVuIGVzdG9zIHJlc3VsdGFkb3Mgc2Ugb2JzZXJ2YSBxdWU6DQoNClxbDQpcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7Y292fX0pDQo9DQpcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7bGF2fX0pDQo9DQpcYmVnaW57cG1hdHJpeH0NCjEuMDAwMCAmIDAuMjk3MyAmIDAuNDQwNyAmIDAuMzcyNyAmIDAuMjkzNCAmIDAuMzU2OCAmIDAuMDY2OSAmIDAuMjIzOSAmIDAuMzkwMyBcXA0KMC4yOTczICYgMS4wMDAwICYgMC4zMzk4ICYgMC4xNTI5ICYgMC4xMzk0ICYgMC4xOTI1ICYgLTAuMDc1NyAmIDAuMDkyMyAmIDAuMjA2MCBcXA0KMC40NDA3ICYgMC4zMzk4ICYgMS4wMDAwICYgMC4xNTg2ICYgMC4wNzcyICYgMC4xOTc3ICYgMC4wNzE5ICYgMC4xODYwICYgMC4zMjg3IFxcDQowLjM3MjcgJiAwLjE1MjkgJiAwLjE1ODYgJiAxLjAwMDAgJiAwLjczMzIgJiAwLjcwNDUgJiAwLjE3MzggJiAwLjEwNjkgJiAwLjIwNzggXFwNCjAuMjkzNCAmIDAuMTM5NCAmIDAuMDc3MiAmIDAuNzMzMiAmIDEuMDAwMCAmIDAuNzIwMCAmIDAuMTAyMCAmIDAuMTM4NyAmIDAuMjI3NSBcXA0KMC4zNTY4ICYgMC4xOTI1ICYgMC4xOTc3ICYgMC43MDQ1ICYgMC43MjAwICYgMS4wMDAwICYgMC4xMjExICYgMC4xNDk2ICYgMC4yMTQyIFxcDQowLjA2NjkgJiAtMC4wNzU3ICYgMC4wNzE5ICYgMC4xNzM4ICYgMC4xMDIwICYgMC4xMjExICYgMS4wMDAwICYgMC40ODY4ICYgMC4zNDA2IFxcDQowLjIyMzkgJiAwLjA5MjMgJiAwLjE4NjAgJiAwLjEwNjkgJiAwLjEzODcgJiAwLjE0OTYgJiAwLjQ4NjggJiAxLjAwMDAgJiAwLjQ0OTAgXFwNCjAuMzkwMyAmIDAuMjA2MCAmIDAuMzI4NyAmIDAuMjA3OCAmIDAuMjI3NSAmIDAuMjE0MiAmIDAuMzQwNiAmIDAuNDQ5MCAmIDEuMDAwMA0KXGVuZHtwbWF0cml4fS4NClxdDQoNCkVzdG8gZXMgZXNwZXJhYmxlIHBvcnF1ZSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCkgeSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19XCkgIGRpZmllcmVuIMO6bmljYW1lbnRlIHBvciB1biAqKmZhY3RvciBkZSBlc2NhbGEgZ2xvYmFsKio6DQoNClxbDQpcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fQ0KPQ0KXGZyYWN7Tn17Ti0xfVwsXG1hdGhiZntTfV97XHRleHR7bGF2fX0uDQpcXQ0KDQpBbCBjb252ZXJ0aXIgY292YXJpYW56YXMgYSBjb3JyZWxhY2lvbmVzLCBlc2UgZmFjdG9yIHNlIGVsaW1pbmEgYXV0b23DoXRpY2FtZW50ZSwgeWEgcXVlIHNlIGRpdmlkZSBwb3IgbGFzIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIgKHJhw61jZXMgZGUgbGFzIHZhcmlhbnphcyBlbiBsYSBkaWFnb25hbCkuIFBvciBlc28sIGF1bnF1ZSBsYXMgY292YXJpYW56YXMgY2FtYmllbiBsZXZlbWVudGUgKHBvciBlbCBkaXZpc29yIFwoTi0xXCkgdnMuIFwoTlwpKSwgbGFzICpjb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMqIHRlcm1pbmFuIHNpZW5kbyBpZ3VhbGVzIChzYWx2byBkaWZlcmVuY2lhcyBwb3IgcmVkb25kZW8pLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIyBJbnRlcnByZXRhY2nDs24gZGUgbGEgc2FsaWRhIHBhcmEgXChcb3BlcmF0b3JuYW1le0Nvcn0oXGJvbGRzeW1ib2x7XFNpZ21hfSlcKQ0KDQoNCkxhIG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzIGltcGxpY2FkYXMgcG9yIGVsIG1vZGVsbyBlczogDQoNCmBgYHtyfQ0KQ29yX1NpZ21hDQpgYGANCg0KXFsNClxvcGVyYXRvcm5hbWV7Q29yfShcYm9sZHN5bWJvbHtcU2lnbWF9KQ0KPQ0KXGJlZ2lue3BtYXRyaXh9DQoxLjAwMDAgJiAwLjMyNzAgJiAwLjQ0ODYgJiAwLjMwMTQgJiAwLjMwMjYgJiAwLjI5NjYgJiAwLjIwNjggJiAwLjI2MjYgJiAwLjI0MTUgXFwNCjAuMzI3MCAmIDEuMDAwMCAmIDAuMjQ2MiAmIDAuMTY1NCAmIDAuMTY2MSAmIDAuMTYyOCAmIDAuMTEzNSAmIDAuMTQ0MSAmIDAuMTMyNSBcXA0KMC40NDg2ICYgMC4yNDYyICYgMS4wMDAwICYgMC4yMjY5ICYgMC4yMjc4ICYgMC4yMjMzICYgMC4xNTU3ICYgMC4xOTc3ICYgMC4xODE4IFxcDQowLjMwMTQgJiAwLjE2NTQgJiAwLjIyNjkgJiAxLjAwMDAgJiAwLjcyODIgJiAwLjcxMzYgJiAwLjEzNzIgJiAwLjE3NDIgJiAwLjE2MDMgXFwNCjAuMzAyNiAmIDAuMTY2MSAmIDAuMjI3OCAmIDAuNzI4MiAmIDEuMDAwMCAmIDAuNzE2NiAmIDAuMTM3OCAmIDAuMTc1MCAmIDAuMTYwOSBcXA0KMC4yOTY2ICYgMC4xNjI4ICYgMC4yMjMzICYgMC43MTM2ICYgMC43MTY2ICYgMS4wMDAwICYgMC4xMzUxICYgMC4xNzE1ICYgMC4xNTc3IFxcDQowLjIwNjggJiAwLjExMzUgJiAwLjE1NTcgJiAwLjEzNzIgJiAwLjEzNzggJiAwLjEzNTEgJiAxLjAwMDAgJiAwLjQxMTggJiAwLjM3ODcgXFwNCjAuMjYyNiAmIDAuMTQ0MSAmIDAuMTk3NyAmIDAuMTc0MiAmIDAuMTc1MCAmIDAuMTcxNSAmIDAuNDExOCAmIDEuMDAwMCAmIDAuNDgwOCBcXA0KMC4yNDE1ICYgMC4xMzI1ICYgMC4xODE4ICYgMC4xNjAzICYgMC4xNjA5ICYgMC4xNTc3ICYgMC4zNzg3ICYgMC40ODA4ICYgMS4wMDAwDQpcZW5ke3BtYXRyaXh9Lg0KXF0NCg0KDQpTZSByZXNhbHRhIHF1ZSBsYSBtYXRyaXogXChcb3BlcmF0b3JuYW1le0Nvcn0oXGJvbGRzeW1ib2x7XFNpZ21hfSlcKSAqKm5vIHRpZW5lIHBvciBxdcOpIGNvaW5jaWRpcioqIGNvbiBsYXMgY29ycmVsYWNpb25lcyBvYnNlcnZhZGFzLCBwb3JxdWUgcmVzdW1lIGxvIHF1ZSBlbCBtb2RlbG8gQ0ZBICoqaW1wbGljYSoqIGJham8gc3UgZXN0cnVjdHVyYSAoZmFjdG9yZXMsIGNhcmdhcywgdmFyaWFuemFzIHkgY292YXJpYW56YXMgZXN0aW1hZGFzKS4gUG9yIGVqZW1wbG8sIGVuIGVsIG91dHB1dDoNCg0KLSBMYSBjb3JyZWxhY2nDs24gb2JzZXJ2YWRhIGVudHJlIFwoeF8xXCkgeSBcKHhfMlwpIGVzIFwoMC4yOTczXCkuDQoNCi0gTGEgY29ycmVsYWNpw7NuIGltcGxpY2FkYSBwb3IgZWwgbW9kZWxvIGVudHJlIFwoeF8xXCkgeSBcKHhfMlwpIGVzIFwoMC4zMjcwXCkuDQoNCkxhIGRpZmVyZW5jaWEgZW50cmUgYW1iYXMgc2UgaW50ZXJwcmV0YSBsdWVnbyBjb21vIGV2aWRlbmNpYSBkZSAqbWlzZml0KiBsb2NhbCBlbiBlc2NhbGEgZGUgY29ycmVsYWNpb25lcyAoZXN0byBzZXLDoSBleGFjdGFtZW50ZSBsbyBxdWUgY2FwdHVyYW4gbGFzIG1hdHJpY2VzIHJlc2lkdWFsZXMgXChcbWF0aGJme1J9X3tcdGV4dHtjb3J9fVwpKS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPYnNlcnZhY2nDs24gY2xhdmUNCg0KTGFzIG1hdHJpY2VzICAgXChcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7Y292fX0pXCksICAgXChcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7bGF2fX0pXCkgeSAgXChcb3BlcmF0b3JuYW1le0Nvcn0oXGJvbGRzeW1ib2x7XFNpZ21hfSlcKSBjb25zdGl0dXllbiBsb3MgYmxvcXVlcyBmdW5kYW1lbnRhbGVzIGRlbCBhbsOhbGlzaXMgZGUgYWp1c3RlIGVuIGVzY2FsYSBkZSBjb3JyZWxhY2lvbmVzIGVuIENGQS9TRU0uDQoNCkxhcyBkb3MgcHJpbWVyYXMgcmVwcmVzZW50YW4gbGFzICoqY29ycmVsYWNpb25lcyBvYnNlcnZhZGFzKiogKG9idGVuaWRhcyBhIHBhcnRpciBkZSBsYSBtYXRyaXogbXVlc3RyYWwgY2zDoXNpY2EgeSBkZSBsYSBtYXRyaXogY29oZXJlbnRlIGNvbiBNTCwgcmVzcGVjdGl2YW1lbnRlKSwgbWllbnRyYXMgcXVlIFwoXG9wZXJhdG9ybmFtZXtDb3J9KFxib2xkc3ltYm9se1xTaWdtYX0pXCkgcmVjb2dlIGxhcyAqKmNvcnJlbGFjaW9uZXMgaW1wbGljYWRhcyBwb3IgZWwgbW9kZWxvKiogYmFqbyBzdXMgc3VwdWVzdG9zIGVzdHJ1Y3R1cmFsZXMuDQoNCkVuIGxhIHNpZ3VpZW50ZSBzZWNjacOzbiwgZXN0YXMgbWF0cmljZXMgc2UgY29tYmluYXLDoW4gcGFyYSBjb25zdHJ1aXIgbGFzICoqbWF0cmljZXMgZGUgY29ycmVsYWNpb25lcyByZXNpZHVhbGVzKiosIGxhcyBjdWFsZXMgY3VhbnRpZmljYW4gZGUgZm9ybWEgZGlyZWN0YSB5IGNvbXBhcmFibGUgbGFzIGRpc2NyZXBhbmNpYXMgZW50cmUgbG8gb2JzZXJ2YWRvIHkgbG8gaW1wbGljYWRvIHBvciBlbCBtb2RlbG8uIEVzdGUgY29udHJhc3RlIGVuIGVzY2FsYSBkZSBjb3JyZWxhY2lvbmVzIGVzIGVzcGVjaWFsbWVudGUgw7p0aWwgcGFyYSBlbCBkaWFnbsOzc3RpY28gZGUgKm1pc2ZpdCogbG9jYWwsIHlhIHF1ZSBlbGltaW5hIGxvcyBlZmVjdG9zIGRlIGVzY2FsYSBwcm9waW9zIGRlIGxhcyBjb3ZhcmlhbnphcyB5IHBlcm1pdGUgaW50ZXJwcmV0YXIgbGFzIGRpc2NyZXBhbmNpYXMgZW4gdMOpcm1pbm9zIGVzdGFuZGFyaXphZG9zLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyByZXNpZHVhbGVzDQoNCiMjIyBDb3ZhcmlhbnphcyByZXNpZHVhbGVzOiBlc2NhbGEgb3JpZ2luYWwgKG5vIGVzdGFuZGFyaXphZGFzKQ0KDQpMYSAqKm1hdHJpeiBkZSBjb3ZhcmlhbnphcyByZXNpZHVhbGVzIGVuIGVzY2FsYSBkZSBjb3ZhcmlhbnphcyBvcmlnaW5hbGVzIChzaW4gZXN0YW5kYXJpemFyKSoqICByZXByZXNlbnRhIGxhcyBkaXNjcmVwYW5jaWFzIGVudHJlIGxhcyBjb3ZhcmlhbnphcyBvYnNlcnZhZGFzIGVuIGxvcyBkYXRvcyB5IGxhcyBjb3ZhcmlhbnphcyBpbXBsaWNhZGFzIHBvciBlbCBtb2RlbG8gQ0ZBIGFqdXN0YWRvLiBFbiBDRkEvU0VNIGVzIMO6dGlsIGRpc3Rpbmd1aXIgKipkb3MqKiBtYXRyaWNlcyByZXNpZHVhbGVzIGVuIGVzY2FsYSBkZSBjb3ZhcmlhbnphcyAobm8gZXN0YW5kYXJpemFkYXMpLCBzZWfDum4gcXXDqSBtYXRyaXogbXVlc3RyYWwgc2UgdG9tZSBjb21vICpvYnNlcnZhZGEqLiBFc3RhcyBkb3MgbWF0cmljZXMgcmVzcG9uZGVuIGEgKipjcml0ZXJpb3MgbXVlc3RyYWxlcyBkaXN0aW50b3MqKiB5LCBwb3IgdGFudG8sIG5vIGRlYmVuIGVzcGVyYXJzZSBpZ3VhbGVzIGVuIHZhbG9yIG51bcOpcmljby4NCjoNCg0KMSkgKipSZXNpZHVhbCBjbMOhc2ljbyAoZGVzY3JpcHRpdm8pKiosIGJhc2FkbyBlbiBgY292KClgOg0KDQpcWw0KXG1hdGhiZntSfV97XHRleHR7Y292fX0NCj0NClxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19LVxib2xkc3ltYm9se1xTaWdtYX0sDQpccXF1YWQNClxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19DQo9DQpcZnJhY3sxfXtOLTF9XHN1bV97aT0xfV5OKFxtYXRoYmZ7eH1faS1cYmFye1xtYXRoYmZ7eH19KShcbWF0aGJme3h9X2ktXGJhcntcbWF0aGJme3h9fSleXHRvcCAuDQpcXQ0KDQoyKSAqKlJlc2lkdWFsIGNvaGVyZW50ZSBjb24gTUwgKGBsYXZhYW5gKSoqLCBiYXNhZG8gZW4gbGEgbWF0cml6IHVzYWRhIGludGVybmFtZW50ZSBwb3IgZWwgYWp1c3RlOg0KDQpcWw0KXG1hdGhiZntSfV97XHRleHR7bGF2fX0NCj0NClxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19LVxib2xkc3ltYm9se1xTaWdtYX0sDQpccXF1YWQNClxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19DQo9DQpcZnJhY3sxfXtOfVxzdW1fe2k9MX1eTihcbWF0aGJme3h9X2ktXGJhcntcbWF0aGJme3h9fSkoXG1hdGhiZnt4fV9pLVxiYXJ7XG1hdGhiZnt4fX0pXlx0b3AgLg0KXF0NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgQ8OzZGlnbyBlbiBSIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyAxKSBNYXRyaXogbXVlc3RyYWwgY2zDoXNpY2EgKGRpdmlzb3IgTi0xKQ0KU19jb3YgPC0gY292KGRhdCkNCg0KIyAyKSBNYXRyaXogbXVlc3RyYWwgdXNhZGEgcG9yIGxhdmFhbiBiYWpvIE1MIChkaXZpc29yIE4pDQpTX2xhdiA8LSBsYXZUZWNoKENGQSwgInNhbXBzdGF0IilbWzFdXSRjb3YNCg0KIyAzKSBNYXRyaXogZGUgY292YXJpYW56YXMgaW1wbMOtY2l0YSBwb3IgZWwgbW9kZWxvIChhanVzdGFkYSwgTUwpDQpTaWdtYV9oYXQgPC0gZml0dGVkKENGQSkkY292ICAgIyBlcXVpdmFsZW50ZSBhIGZpdHRlZC52YWx1ZXMoQ0ZBKSRjb3YNCg0KIyA0KSBEb3MgdmVyc2lvbmVzIGRlIHJlc2lkdWFsZXMgKGVzY2FsYSBjb3ZhcmlhbnphcykNClJfY292IDwtIFNfY292IC0gU2lnbWFfaGF0DQpSX2Nvdg0KDQpSX2xhdiA8LSBTX2xhdiAtIFNpZ21hX2hhdA0KUl9sYXYNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIyBFbCBvdXRwdXQgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgMSkgTWF0cml6IG11ZXN0cmFsIGNsw6FzaWNhIChkaXZpc29yIE4tMSkNClNfY292IDwtIGNvdihkYXQpDQoNCiMgMikgTWF0cml6IG11ZXN0cmFsIHVzYWRhIHBvciBsYXZhYW4gYmFqbyBNTCAoZGl2aXNvciBOKQ0KU19sYXYgPC0gbGF2VGVjaChDRkEsICJzYW1wc3RhdCIpW1sxXV0kY292DQoNCiMgMykgTWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGzDrWNpdGEgcG9yIGVsIG1vZGVsbyAoYWp1c3RhZGEpDQpTaWdtYV9oYXQgPC0gZml0dGVkKENGQSkkY292ICAgIyBlcXVpdmFsZW50ZSBhIGZpdHRlZC52YWx1ZXMoQ0ZBKSRjb3YNCg0KIyA0KSBEb3MgdmVyc2lvbmVzIGRlIHJlc2lkdWFsZXMgKGVzY2FsYSBjb3ZhcmlhbnphcykNClJfY292IDwtIFNfY292IC0gU2lnbWFfaGF0DQpSX2xhdiA8LSBTX2xhdiAtIFNpZ21hX2hhdA0KYGBgDQoNCg0KTGEgbWF0cml6IHJlc2lkdWFsIGJhc2FkYSBlbiAkXG1hdGhiZntTfV97XHRleHR7Y292fX0kIGVzOiANCiANCmBgYHtyfQ0KUl9jb3YNCmBgYA0KDQpFcyBkZWNpciwgDQoNClxbDQpcbWF0aGJme1J9X3tcdGV4dHtjb3Z9fQ0KPQ0KXG1hdGhiZntTfV97XHRleHR7Y292fX0tXGJvbGRzeW1ib2x7XFNpZ21hfT0gDQpcYmVnaW57cG1hdHJpeH0NCiAwLjAwNSAmIC0wLjAzOSAmIC0wLjAwOCAmICAwLjA5OCAmIC0wLjAxMiAmICAwLjA3OCAmIC0wLjE3NyAmIC0wLjA0NSAmICAwLjE3NiBcXA0KLTAuMDM5ICYgIDAuMDA1ICYgIDAuMTI2ICYgLTAuMDE2ICYgLTAuMDQwICYgIDAuMDM5ICYgLTAuMjQyICYgLTAuMDYxICYgIDAuMDg4IFxcDQotMC4wMDggJiAgMC4xMjYgJiAgMC4wMDQgJiAtMC4wODkgJiAtMC4yMTkgJiAtMC4wMzEgJiAtMC4xMDMgJiAtMC4wMTMgJiAgMC4xNjggXFwNCiAwLjA5OCAmIC0wLjAxNiAmIC0wLjA4OSAmICAwLjAwNSAmICAwLjAxMSAmIC0wLjAwOSAmICAwLjA0NyAmIC0wLjA3OSAmICAwLjA1NyBcXA0KLTAuMDEyICYgLTAuMDQwICYgLTAuMjE5ICYgIDAuMDExICYgIDAuMDA2ICYgIDAuMDA4ICYgLTAuMDUwICYgLTAuMDQ3ICYgIDAuMDg3IFxcDQogMC4wNzggJiAgMC4wMzkgJiAtMC4wMzEgJiAtMC4wMDkgJiAgMC4wMDggJiAgMC4wMDQgJiAtMC4wMTYgJiAtMC4wMjQgJiAgMC4wNjMgXFwNCi0wLjE3NyAmIC0wLjI0MiAmIC0wLjEwMyAmICAwLjA0NyAmIC0wLjA1MCAmIC0wLjAxNiAmICAwLjAwNCAmICAwLjA4NCAmIC0wLjA0MCBcXA0KLTAuMDQ1ICYgLTAuMDYxICYgLTAuMDEzICYgLTAuMDc5ICYgLTAuMDQ3ICYgLTAuMDI0ICYgIDAuMDg0ICYgIDAuMDAzICYgLTAuMDMxIFxcDQogMC4xNzYgJiAgMC4wODggJiAgMC4xNjggJiAgMC4wNTcgJiAgMC4wODcgJiAgMC4wNjMgJiAtMC4wNDAgJiAtMC4wMzEgJiAgMC4wMDMNClxlbmR7cG1hdHJpeH0uDQpcXQ0KDQpMYSBtYXRyaXogcmVzaWR1YWwgYmFzYWRhIGVuICRcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSQgZXM6IA0KDQpgYGB7cn0NClJfbGF2DQpgYGANCg0KXFsNClxtYXRoYmZ7Un1fe1x0ZXh0e2xhdn19DQo9IFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19LVxib2xkc3ltYm9se1xTaWdtYX0gPSANClxiZWdpbntwbWF0cml4fQ0KIDAuMDAwICYgLTAuMDQxICYgLTAuMDEwICYgIDAuMDk3ICYgLTAuMDE0ICYgIDAuMDc3ICYgLTAuMTc3ICYgLTAuMDQ2ICYgIDAuMTc1IFxcDQotMC4wNDEgJiAgMC4wMDAgJiAgMC4xMjQgJiAtMC4wMTcgJiAtMC4wNDAgJiAgMC4wMzggJiAtMC4yNDIgJiAtMC4wNjIgJiAgMC4wODcgXFwNCi0wLjAxMCAmICAwLjEyNCAmICAwLjAwMCAmIC0wLjA5MCAmIC0wLjIxOSAmIC0wLjAzMiAmIC0wLjEwMyAmIC0wLjAxMyAmICAwLjE2NyBcXA0KIDAuMDk3ICYgLTAuMDE3ICYgLTAuMDkwICYgIDAuMDAwICYgIDAuMDA4ICYgLTAuMDEyICYgIDAuMDQ2ICYgLTAuMDc5ICYgIDAuMDU2IFxcDQotMC4wMTQgJiAtMC4wNDAgJiAtMC4yMTkgJiAgMC4wMDggJiAgMC4wMDAgJiAgMC4wMDUgJiAtMC4wNTAgJiAtMC4wNDcgJiAgMC4wODYgXFwNCiAwLjA3NyAmICAwLjAzOCAmIC0wLjAzMiAmIC0wLjAxMiAmICAwLjAwNSAmICAwLjAwMCAmIC0wLjAxNyAmIC0wLjAyNCAmICAwLjA2MiBcXA0KLTAuMTc3ICYgLTAuMjQyICYgLTAuMTAzICYgIDAuMDQ2ICYgLTAuMDUwICYgLTAuMDE3ICYgIDAuMDAwICYgIDAuMDgyICYgLTAuMDQyIFxcDQotMC4wNDYgJiAtMC4wNjIgJiAtMC4wMTMgJiAtMC4wNzkgJiAtMC4wNDcgJiAtMC4wMjQgJiAgMC4wODIgJiAgMC4wMDAgJiAtMC4wMzIgXFwNCiAwLjE3NSAmICAwLjA4NyAmICAwLjE2NyAmICAwLjA1NiAmICAwLjA4NiAmICAwLjA2MiAmIC0wLjA0MiAmIC0wLjAzMiAmICAwLjAwMA0KXGVuZHtwbWF0cml4fS4NClxdDQoNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMjIE1lbnNhamUgY2xhdmUgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KRWwgcGFxdWV0ZSBgbGF2YWFuYCAoY29uIGVzdGltYWRvciBkZSBtw6F4aW1hIHZlcm9zaW1pbGl0dWQsIE1MKSAqKm5vIGNvbXBhcmEgZWwgbW9kZWxvIGNvbnRyYSBsYSBjb3ZhcmlhbnphIGRlc2NyaXB0aXZhIGNsw6FzaWNhKiosIHNpbm8gY29udHJhIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBtdWVzdHJhbGVzIHV0aWxpemFkYSBpbnRlcm5hbWVudGUgcG9yIGVsIGVzdGltYWRvciBNTCwgXChcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fVwpLiAgUG9yIGVzdGEgcmF6w7NuLCBsYSBzYWxpZGEgZGUgYHJlc2lkdWFscyhmaXQpJGNvdmAgY29pbmNpZGUgY29uIFwoXG1hdGhiZntSfV97XHRleHR7bGF2fX1cKSB5ICoqbm8qKiBjb24gXChcbWF0aGJme1J9X3tcdGV4dHtjb3Z9fVwpLg0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyA1KSBSZXNpZHVvcyBjcnVkb3MgcmVwb3J0YWRvcyBwb3IgbGF2YWFuDQpyZXNpZHVhbHMoQ0ZBKQ0KUl9yYXcgPC0gcmVzaWR1YWxzKENGQSkkY292DQoNCiMgNikgVmVyaWZpY2FjacOzbiB0w61waWNhOg0KYWxsLmVxdWFsKFJfbGF2LCBSX3JhdykgICAjIDZhKSBTdWVsZSBkYXIgVFJVRSAobyBtdXkgY2VyY2FubykNCmFsbC5lcXVhbChSX2NvdiwgUl9yYXcpICAgIyA2YikgTk8gZGViZSBkYXIgVFJVRQ0KYGBgDQoNCkxhIHZlcmlmaWNhY2nDs24gZXNwZXJhZGEgZXM6DQoNCi0gYGFsbC5lcXVhbChSX2xhdiwgUl9yYXdfbGF2YWFuKWAgZGViZSBnZW5lcmFyICpUUlVFIChvIGNhc2kgVFJVRSkqLCBsbyBxdWUgY29uZmlybWEgcXVlIGBsYXZhYW5gIGRlZmluZSBzdXMgcmVzaWR1b3MgY3J1ZG9zIGNvbW8gIA0KICBcWw0KICBcbWF0aGJme1J9X3tcdGV4dHtyYXd9fSA9IFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19IC0gXGJvbGRzeW1ib2x7XFNpZ21hfS4NCiAgXF0NCg0KOjo6c2FuZ3JpYTMNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyA1KSBMbyBxdWUgcmVwb3J0YSBsYXZhYW4gY29tbyAicmF3IHJlc2lkdWFscyINClJfcmF3IDwtIHJlc2lkdWFscyhDRkEpJGNvdg0KDQojIDYpIFZlcmlmaWNhY2nDs24gdMOtcGljYToNCmFsbC5lcXVhbChSX2xhdiwgUl9yYXcpICAgIyA2YSkgU3VlbGUgZGFyIFRSVUUgKG8gbXV5IGNlcmNhbm8pDQpgYGANCjo6Og0KDQotIGBhbGwuZXF1YWwoUl9jb3YsIFJfcmF3X2xhdmFhbilgICAqbm8gZGViZSBzZXIgVFJVRSosIHlhIHF1ZSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19XCkgeSBcKFxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19XCkgdXRpbGl6YW4gZGl2aXNvcmVzIGRpc3RpbnRvcyAgIChcKE4tMVwpIHZzLiBcKE5cKSkgeSwgcG9yIHRhbnRvLCBnZW5lcmFuIHJlc2lkdW9zIG51bcOpcmljYW1lbnRlIGRpZmVyZW50ZXMuDQogIA0KOjo6c2FuZ3JpYTMNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KYWxsLmVxdWFsKFJfY292LCBSX3JhdykgICAjIDZiKSBOTyBkZWJlIGRhciBUUlVFDQpgYGANCjo6Og0KDQpPYnNlcnZlIHF1ZSwgZW4gZ2VuZXJhbCwgbGFTIHNhbGlkYXMgZGUgIGByZXNpZHVhbHMoQ0ZBKWAgeSBgcmVzaWR1YWxzKENGQSkkY292YCBzb246IA0KDQpgYGB7cn0NCnJlc2lkdWFscyhDRkEpDQpSX3Jhdw0KYGBgDQoNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQoNClNfY292IDwtIHJvdW5kKGNvdihkYXQpLDMpDQpTX2Nvdg0KDQpTX2xhdiA8LSBsYXZJbnNwZWN0KENGQSwgInNhbXBzdGF0IikkY292DQpTX2xhdg0KU2lnbWEgPC0gbGF2SW5zcGVjdChDRkEsICJzaWdtYSIpDQpTaWdtYQ0KU19jb3YtU2lnbWENClNfbGF2LVNpZ21hDQpyZXNpZHVhbHMoQ0ZBKSRjb3YgIA0KDQpgYGANCg0KcmVzcGVjdGl2YW1lbnRlLiBPYnNlcnZlIHF1ZSANCg0KJCRcbWF0aGJme1J9X3tcdGV4dHtyYXd9fSA9IFxtYXRoYmZ7Un1fe1x0ZXh0e2xhdn19ICQkDQoNCioqTm90YS4qKg0KDQpMYXMgbWF0cmljZXMgJFxtYXRoYmZ7Un1fe1x0ZXh0e2Nvdn19JCB5ICRcbWF0aGJme1J9X3tcdGV4dHtsYXZ9fSQgcmVwcmVzZW50YW4gcmVzaWR1b3MgZGUgY292YXJpYW56YXMgY2FsY3VsYWRvcyBiYWpvIGRpc3RpbnRvcyBjcml0ZXJpb3MgbXVlc3RyYWxlcy4gQXVucXVlIGNvbmNlcHR1YWxtZW50ZSBhbWJhcyBjdWFudGlmaWNhbiAkXG1hdGhiZntTfSAtIFxib2xkc3ltYm9se1xTaWdtYX0kLCBzdXMgdmFsb3JlcyBudW3DqXJpY29zIGRpZmllcmVuIGRlYmlkbyBhbCB1c28gZGUgZGl2aXNvcmVzIGRpc3RpbnRvcyAoJE4tMSQgZnJlbnRlIGEgJE4kKSwgc2llbmRvICRcbWF0aGJme1J9X3tcdGV4dHtsYXZ9fSQgbGEgbWF0cml6IGNvaGVyZW50ZSBjb24gbGEgZXN0aW1hY2nDs24gcG9yIG3DoXhpbWEgdmVyb3NpbWlsaXR1ZCB1dGlsaXphZGEgaW50ZXJuYW1lbnRlIHBvciBgbGF2YWFuYC4NCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ292YXJpYW56YXMgcmVzaWR1YWxlcyAoY29tbyByZXN0YSBkZSBtYXRyaWNlcyk6IGVuIGVzY2FsYSBkZSBjb3JyZWxhY2lvbmVzIChubyAqeiopLCBzaW4gZXN0YW5kYXJpemFyIA0KDQojIyMjIElkZWEgY2VudHJhbCB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpFbiBDRkEvU0VNLCB1bmEgZXN0cmF0ZWdpYSBoYWJpdHVhbCBwYXJhIGRpYWdub3N0aWNhciAqbWlzZml0KiBsb2NhbCBjb25zaXN0ZSBlbiBldmFsdWFyIGxhcyBkaXNjcmVwYW5jaWFzIGVudHJlIGxvIG9ic2VydmFkbyB5IGxvIGltcGxpY2FkbyBwb3IgZWwgbW9kZWxvIGVuIGxhICoqZXNjYWxhIGRlIGNvcnJlbGFjaW9uZXMqKi4gRXN0YSBlc2NhbGEgZWxpbWluYSBsb3MgZWZlY3RvcyBkZSBtYWduaXR1ZCBwcm9waW9zIGRlIGxhcyBjb3ZhcmlhbnphcyB5IHBlcm1pdGUgY29tcGFyYWNpb25lcyBkaXJlY3RhcyBlbnRyZSBwYXJlcyBkZSB2YXJpYWJsZXMuIFBhcmEgY3VhbHF1aWVyIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBcKFxtYXRoYmZ7QX1cKSwgc3UgdmVyc2nDs24gZW4gY29ycmVsYWNpb25lcyBzZSBkZWZpbmUgY29tbzoNCg0KXFsNClxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme0F9KSANCj0NClxtYXRoYmZ7RH1fe1xtYXRoYmZ7QX19XnstMS8yfVwsDQpcbWF0aGJme0F9XCwNClxtYXRoYmZ7RH1fe1xtYXRoYmZ7QX19XnstMS8yfSwNClxxcXVhZA0KXG1hdGhiZntEfV97XG1hdGhiZntBfX09XG9wZXJhdG9ybmFtZXtkaWFnfShhX3sxMX0sXGxkb3RzLGFfe3BwfSksDQpcXQ0KDQpkb25kZSBcKFxtYXRoYmZ7RH1fe1xtYXRoYmZ7QX19XCkgZXMgbGEgbWF0cml6IGRpYWdvbmFsIHF1ZSBjb250aWVuZSBsYXMgdmFyaWFuemFzIGFzb2NpYWRhcyBhIFwoXG1hdGhiZntBfVwpLiBDb24gZXN0YSB0cmFuc2Zvcm1hY2nDs24sIGxhICoqbWF0cml6IGRlIGNvdmFyaWFuemFzIHJlc2lkdWFsZXMgZW4gZXNjYWxhIGRlIGNvcnJlbGFjaW9uZXMqKiBzZSBkZWZpbmUgY29tbyBsYSBkaWZlcmVuY2lhIGVudHJlOg0KDQotIExhIG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzICpvYnNlcnZhZGFzKiwgb2J0ZW5pZGEgYSBwYXJ0aXIgZGUgdW5hIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBtdWVzdHJhbGVzLCB5ICANCg0KLSBMYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyAqaW1wbGljYWRhcyBwb3IgZWwgbW9kZWxvKiwgY29uc3RydWlkYSBhIHBhcnRpciBkZSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgXChcYm9sZHN5bWJvbHtcU2lnbWF9XCkgZXN0aW1hZGEgYmFqbyBlbCBtb2RlbG8gQ0ZBLg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgRG9zIHZlcnNpb25lcyB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpFbiBwYXJ0aWN1bGFyLCBlcyDDunRpbCBkaXN0aW5ndWlyICoqZG9zIHZlcnNpb25lcyoqIGRlIGVzdGEgbWF0cml6IHJlc2lkdWFsLCBkZXBlbmRpZW5kbyBkZSBxdcOpIG1hdHJpeiBtdWVzdHJhbCBzZSB0b21lIGNvbW8gcmVmZXJlbmNpYSBvYnNlcnZhZGE6DQoNCjEuICoqUmVzaWR1YWxlcyBlbiBjb3JyZWxhY2lvbmVzIChkZXNjcmlwdGl2b3MpLioqIEJhc2Fkb3MgZW4gbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIG11ZXN0cmFsIGNsw6FzaWNhIFwoXG1hdGhiZntTfV97XHRleHR7Y292fX1cKToNCg0KXFsNClxtYXRoYmZ7Un1fe1x0ZXh0e2Nvcixjb3Z9fQ0KPQ0KXG9wZXJhdG9ybmFtZXtDb3J9KFxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19KQ0KLQ0KXG9wZXJhdG9ybmFtZXtDb3J9KFxib2xkc3ltYm9se1xTaWdtYX0pLA0KXHFxdWFkDQpcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fQ0KPQ0KXGZyYWN7MX17Ti0xfQ0KXHN1bV97aT0xfV5ODQooXG1hdGhiZnt4fV9pLVxiYXJ7XG1hdGhiZnt4fX0pDQooXG1hdGhiZnt4fV9pLVxiYXJ7XG1hdGhiZnt4fX0pXlx0b3AuDQpcXQ0KDQo6OjpzYW5ncmlhMw0KRXN0YSB2ZXJzacOzbiB0aWVuZSB1biBjYXLDoWN0ZXIgKipkZXNjcmlwdGl2byoqLCB5YSBxdWUgdXRpbGl6YSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgY2zDoXNpY2EgZW1wbGVhZGEgZW4gZXN0YWTDrXN0aWNhIGV4cGxvcmF0b3JpYS4gIA0KOjo6DQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoyLiAqKlJlc2lkdWFsZXMgZW4gY29ycmVsYWNpb25lcyBjb2hlcmVudGVzIGNvbiBNTCAoYGxhdmFhbmApLioqIEJhc2Fkb3MgZW4gbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIHV0aWxpemFkYSBpbnRlcm5hbWVudGUgcG9yIGBsYXZhYW5gIGJham8gbcOheGltYSB2ZXJvc2ltaWxpdHVkOg0KDQpcWw0KXG1hdGhiZntSfV97XHRleHR7Y29yLGxhdn19DQo9DQpcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntTfV97XHRleHR7bGF2fX0pDQotDQpcb3BlcmF0b3JuYW1le0Nvcn0oXGJvbGRzeW1ib2x7XFNpZ21hfSksDQpccXF1YWQNClxtYXRoYmZ7U31fe1x0ZXh0e2xhdn19DQo9DQpcZnJhY3sxfXtOfQ0KXHN1bV97aT0xfV5ODQooXG1hdGhiZnt4fV9pLVxiYXJ7XG1hdGhiZnt4fX0pDQooXG1hdGhiZnt4fV9pLVxiYXJ7XG1hdGhiZnt4fX0pXlx0b3AuDQpcXQ0KDQo6OjpzYW5ncmlhMw0KRXN0YSBlcyBsYSB2ZXJzacOzbiAqKmNvbmNlcHR1YWxtZW50ZSBjb2hlcmVudGUgY29uIGVsIGFqdXN0ZSBNTCoqIHksIHBvciB0YW50bywgbGEgbcOhcyBhbGluZWFkYSBjb24gbG9zIHJlc2lkdW9zIHF1ZSByZXBvcnRhIGBsYXZhYW5gIGN1YW5kbyBzZSBzb2xpY2l0YW4gcmVzdWx0YWRvcyBlbiBlc2NhbGEgZGUgY29ycmVsYWNpb25lcy4NCjo6Og0KDQpFc3RhIGRlZmluaWNpw7NuIGFjbGFyYSBxdWUgbGEgbWF0cml6IFwoXG1hdGhiZntSfV97XHRleHR7Y29yLCBsYXZ9fVwpICoqbm8gY29ycmVzcG9uZGUgYSBsYSByZXN0YSBkaXJlY3RhIGRlIGNvdmFyaWFuemFzKiogJFxtYXRoYmZ7Un1fe1x0ZXh0e2Nvdn19PVxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19IC0gXGJvbGRzeW1ib2x7XFNpZ21hfSQgIChvICRcbWF0aGJme1J9X3tcdGV4dHtsYXZ9fT1cbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSAtIFxib2xkc3ltYm9se1xTaWdtYX0kICksIHNpbm8gYSBsYSBkaXNjcmVwYW5jaWEgZW50cmUgbWF0cmljZXMgZXhwcmVzYWRhcyBlbiB1bmEgZXNjYWxhIGVzdGFuZGFyaXphZGEuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIyBJbnRlcnByZXRhY2nDs24gZXN0YWTDrXN0aWNhIGRlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyByZXNpZHVhbGVzIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkNhZGEgZWxlbWVudG8gXChyX3tpan1cKSBkZSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgcmVzaWR1YWxlcyAoXChcbWF0aGJme1J9X3tcdGV4dHtjb3IsIGNvdn19XCkgbyBcKFxtYXRoYmZ7Un1fe1x0ZXh0e2NvciwgbGF2fX1cKSkgc2UgZGVmaW5lIGNvbW86DQoNClxbDQpyX3tpan0gPQ0KXG9wZXJhdG9ybmFtZXtjb3J9KFhfaSwgWF9qKQ0KLQ0KXG9wZXJhdG9ybmFtZXtjb3J9X3tcdGV4dHttb2RlbG99fShYX2ksIFhfaiksDQpcXQ0KDQp5IGN1YW50aWZpY2EgbGEgcGFydGUgZGUgbGEgY292YXJpYW56YSBlbnRyZSBsb3Mgw610ZW1zIFwoWF9pXCkgeSBcKFhfalwpIHF1ZSBubyBlcyBleHBsaWNhZGEgcG9yIGVsIG1vZGVsbyBDRkEgYWp1c3RhZG8uIEVuIHBhcnRpY3VsYXI6DQoNCi0gVmFsb3JlcyBjZXJjYW5vcyBhIDAgKCRyX3tpan0gXGFwcHJveCAwJCkgaW1wbGljYSBidWVuIGFqdXN0ZSBsb2NhbCBkZWwgbW9kZWxvLiBFcyBkZWNpciwgIGVsIG1vZGVsbyBleHBsaWNhIGV4YWN0YW1lbnRlIGxhIHJlbGFjacOzbiBlbnRyZSAkWF9pJCB5ICRYX2okLg0KDQotIFZhbG9yZXMgZ3JhbmRlcyAgZW4gdmFsb3IgYWJzb2x1dG8gKCRyX3tpan0gXG5lcSAwJCkgc3VnaWVyZW4gbGEgcHJlc2VuY2lhIGRlIGRlc2FqdXN0ZSBsb2NhbCAoKmxvY2FsIG1pc2ZpdCopLiBFcyBkZWNpciwgZXhpc3RlIGFzb2NpYWNpw7NuIGVudHJlICRYX2kkIHkgJFhfaiQgIG5vIGNhcHR1cmFkYSBwb3IgZWwgbW9kZWxvLg0KDQotIEVsIG9iamV0aXZvIGdlbmVyYWwgZGVsIGFuw6FsaXNpcyBDRkEgZXMgcXVlIGxhIG1hdHJpeiByZXNpZHVhbCBzYXRpc2ZhZ2EgJFIgXGFwcHJveCAwJC4gDQoNCg0KQ29uIHJlc2lkdWFsZXMgZXN0YW5kYXJpemFkb3MgcHVlZGVuIGVtcGxlYXJzZSBjcml0ZXJpb3MgZW1ww61yaWNvcyBjbGFyb3MsIHBvcg0KZWplbXBsbzoNCg0KLSBTaSAkXGx2ZXJ0IHJfe2lqfSBccnZlcnQgPCAwLjA1JCwgZW50b25jZXMsIGhheSB1biBhanVzdGUgbG9jYWwgZXhjZWxlbnRlLg0KDQotIFNpICQwLjA1IFxsZSBcbHZlcnQgcl97aWp9IFxydmVydCA8IDAuMTAkLCBlbnRvbmNlcywgaGF5IHVuIGFqdXN0ZSBsb2NhbCBhY2VwdGFibGUuDQoNCi0gU2kgJFxsdmVydCByX3tpan0gXHJ2ZXJ0IFxnZSAwLjEwJCwgZW50b25jZXMsIGhheSB1biBwb3RlbmNpYWwgcHJvYmxlbWEgZGUgYWp1c3RlIGxvY2FsLiBFcyBkZWNpciwgbG9zIHJlc2lkdWFsZXMgZGUgY29ycmVsYWNpw7NuIGNvbiB2YWxvcmVzIGFic29sdXRvcyBzdXBlcmlvcmVzIGEgMC4xMCBzdWdpZXJlbiBhc29jaWFjaW9uZXMgbm8gZXhwbGljYWRhcyBwb3IgZWwgbW9kZWxvIENGQSB5IGNvbnN0aXR1eWVuIGNhbmRpZGF0b3MgbmF0dXJhbGVzIHBhcmEgdW4gYW7DoWxpc2lzIG3DoXMgZGV0YWxsYWRvIG1lZGlhbnRlIMOtbmRpY2VzIGRlIG1vZGlmaWNhY2nDs24gbyByZXZpc2nDs24gdGXDs3JpY2EgZGVsIG1vZGVsby4NCg0KDQpFc3RlIHRpcG8gZGUgZXZhbHVhY2nDs24gbm8gZXMgcG9zaWJsZSBkZSBmb3JtYSBkaXJlY3RhIHkgY29tcGFyYWJsZSBjdWFuZG8gc2UgdHJhYmFqYSBjb24gY292YXJpYW56YXMgbm8gZXN0YW5kYXJpemFkYXMuDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIyBDw6FsY3VsbyBkZSBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyByZXNpZHVhbGVzIGVuIFIgKGNvbW8gcmVzdGEgZGUgbWF0cmljZXMpIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkVuIGVzdGEgc2VjY2nDs24gY2FsY3VsYW1vcyBsYXMgbWF0cmljZXMgZGUgKipjb3JyZWxhY2lvbmVzIHJlc2lkdWFsZXMqKiBjb21vIHJlc3RhIGRlIG1hdHJpY2VzLiBQYXJhIHBhc2FyIGRlIGNvdmFyaWFuemFzIGEgY29ycmVsYWNpb25lcyB1c2Ftb3MgbGEgdHJhbnNmb3JtYWNpw7NuICRcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntBfSkkIGRlZmluaWRhIGFudGVyaW9ybWVudGUuICBFbCBjw7NkaWdvIGNvcnJlc3BvbmRpZW50ZSBlczogDQoNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQojIDEpIE1hdHJpY2VzIGRlIGNvdmFyaWFuemFzICJvYnNlcnZhZGFzIg0KU19jb3YgPC0gY292KGRhdCkgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGRpdmlzb3IgTi0xDQpTX2xhdiA8LSBsYXZUZWNoKENGQSwgInNhbXBzdGF0IilbWzFdXSRjb3YgICMgZGl2aXNvciBOIChNTCkNCg0KIyAyKSBNYXRyaXogZGUgY292YXJpYW56YXMgaW1wbGljYWRhIHBvciBlbCBtb2RlbG8NClNpZ21hIDwtIGZpdHRlZChDRkEpJGNvdg0KDQojIDMpIEZ1bmNpw7NuIGF1eGlsaWFyOiBDb3YgLT4gQ29yDQpjb3YyY29yX21hdCA8LSBmdW5jdGlvbihBKSB7DQogIERpbnZoYWxmIDwtIGRpYWcoMSAvIHNxcnQoZGlhZyhBKSkpDQogIERpbnZoYWxmICUqJSBBICUqJSBEaW52aGFsZg0KfQ0KDQojIDQpIENvcnJlbGFjaW9uZXMgb2JzZXJ2YWRhcyBlIGltcGxpY2FkYXMNCkNvcl9TY292IDwtIGNvdjJjb3JfbWF0KFNfY292KQ0KQ29yX1NsYXYgPC0gY292MmNvcl9tYXQoU19sYXYpDQpDb3JfU2lnbWEgPC0gY292MmNvcl9tYXQoU2lnbWEpDQoNCiMgNSkgRG9zIHZlcnNpb25lcyBkZWwgcmVzaWR1YWwgZW4gY29ycmVsYWNpb25lcw0KUl9jb3JfY292IDwtIENvcl9TY292IC0gQ29yX1NpZ21hDQpSX2Nvcl9sYXYgPC0gQ29yX1NsYXYgLSBDb3JfU2lnbWENCg0KUl9jb3JfY292DQpSX2Nvcl9sYXYNCmBgYA0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyAxKSBNYXRyaWNlcyBkZSBjb3ZhcmlhbnphcyAib2JzZXJ2YWRhcyINClNfY292IDwtIGNvdihkYXQpICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBkaXZpc29yIE4tMQ0KU19sYXYgPC0gbGF2VGVjaChDRkEsICJzYW1wc3RhdCIpW1sxXV0kY292ICAjIGRpdmlzb3IgTiAoTUwpDQoNCiMgMikgTWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGxpY2FkYSBwb3IgZWwgbW9kZWxvDQpTaWdtYSA8LSBmaXR0ZWQoQ0ZBKSRjb3YNCg0KIyAzKSBGdW5jacOzbiBhdXhpbGlhcjogQ292IC0+IENvcg0KY292MmNvcl9tYXQgPC0gZnVuY3Rpb24oQSkgew0KICBEaW52aGFsZiA8LSBkaWFnKDEgLyBzcXJ0KGRpYWcoQSkpKQ0KICBEaW52aGFsZiAlKiUgQSAlKiUgRGludmhhbGYNCn0NCg0KIyA0KSBDb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMgZSBpbXBsaWNhZGFzDQpDb3JfU2NvdiA8LSBjb3YyY29yX21hdChTX2NvdikNCkNvcl9TbGF2IDwtIGNvdjJjb3JfbWF0KFNfbGF2KQ0KQ29yX1NpZ21hIDwtIGNvdjJjb3JfbWF0KFNpZ21hKQ0KDQojIDUpIERvcyB2ZXJzaW9uZXMgZGVsIHJlc2lkdWFsIGVuIGNvcnJlbGFjaW9uZXMNClJfY29yX2NvdiA8LSBDb3JfU2NvdiAtIENvcl9TaWdtYQ0KUl9jb3JfbGF2IDwtIENvcl9TbGF2IC0gQ29yX1NpZ21hDQpgYGANCg0KU2Ugb2J0aWVuZW46IA0KDQpgYGB7cn0NClJfY29yX2Nvdg0KUl9jb3JfbGF2DQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCkVuIGVzdGUgY29uanVudG8gZGUgZGF0b3Mgb2N1cnJlIGFsZ28gcGFydGljdWxhcjoNCg0KXFsNClxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fSkNCj0NClxvcGVyYXRvcm5hbWV7Q29yfShcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSkuDQpcXQ0KDQpFc3RvIHNlIGRlYmUgYSBxdWUgXChcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fVwpIHkgXChcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fVwpICoqZGlmaWVyZW4gw7puaWNhbWVudGUgcG9yIHVuIGZhY3RvciBlc2NhbGFyIGdsb2JhbCoqLCBkYWRvIHBvcjoNCg0KXFsNClxtYXRoYmZ7U31fe1x0ZXh0e2Nvdn19DQo9DQpcZnJhY3tOfXtOLTF9XCxcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fS4NClxdDQoNCkFsIHRyYW5zZm9ybWFyIHVuYSBtYXRyaXogZGUgY292YXJpYW56YXMgYSBjb3JyZWxhY2lvbmVzLCBkaWNobyBmYWN0b3IgZXNjYWxhciAqKnNlIGNhbmNlbGEgYXV0b23DoXRpY2FtZW50ZSoqLCB5YSBxdWUgbGEgZXN0YW5kYXJpemFjacOzbiBkaXZpZGUgY2FkYSBlbGVtZW50byBwb3IgbGFzIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIgY29ycmVzcG9uZGllbnRlcy4gUG9yIGVzdGEgcmF6w7NuLCBlbiBlc3RlIGNhc28gc2Ugb2J0aWVuZSBxdWUgbGFzIG1hdHJpY2VzIGRlIGNvcnJlbGFjaW9uZXMgcmVzaWR1YWxlcyBjb2luY2lkZW46DQoNClxbDQpcbWF0aGJme1J9X3tcdGV4dHtjb3IsY292fX0NCj0NClxtYXRoYmZ7Un1fe1x0ZXh0e2NvcixsYXZ9fS4NClxdDQoNCkVuIHBhcnRpY3VsYXIsIGxhICoqbWF0cml6IHJlc2lkdWFsIGVuIGVzY2FsYSBkZSBjb3JyZWxhY2lvbmVzKiogZXMgbGEgbWlzbWEgaW5kZXBlbmRpZW50ZW1lbnRlIGRlIHNpIHNlIHBhcnRlIGRlIFwoXG1hdGhiZntTfV97XHRleHR7Y292fX1cKSBvIGRlIFwoXG1hdGhiZntTfV97XHRleHR7bGF2fX1cKSwgeSBjb3JyZXNwb25kZSBhIGxhIGRpc2NyZXBhbmNpYSBlbnRyZSBsYSBjb3JyZWxhY2lvbmVzIG9ic2VydmFkYXMgeSBsYXMgY29ycmVsYWNpb25lcyBpbXBsaWNhZGFzIHBvciBlbCBtb2RlbG8uDQoNCg0KXFsNClxtYXRoYmZ7Un1fe1x0ZXh0e2NvciwgY292fX0gPSBcbWF0aGJme1J9X3tcdGV4dHtjb3IsIGxhdn19ID0NClxiZWdpbntwbWF0cml4fQ0KIDAuMDAwICYgLTAuMDMwICYgLTAuMDA4ICYgIDAuMDcxICYgLTAuMDA5ICYgIDAuMDYwICYgLTAuMTQwICYgLTAuMDM5ICYgIDAuMTQ5IFxcDQotMC4wMzAgJiAgMC4wMDAgJiAgMC4wOTQgJiAtMC4wMTIgJiAtMC4wMjcgJiAgMC4wMzAgJiAtMC4xODkgJiAtMC4wNTIgJiAgMC4wNzMgXFwNCi0wLjAwOCAmICAwLjA5NCAmICAwLjAwMCAmIC0wLjA2OCAmIC0wLjE1MSAmIC0wLjAyNiAmIC0wLjA4NCAmIC0wLjAxMiAmICAwLjE0NyBcXA0KIDAuMDcxICYgLTAuMDEyICYgLTAuMDY4ICYgIDAuMDAwICYgIDAuMDA1ICYgLTAuMDA5ICYgIDAuMDM3ICYgLTAuMDY3ICYgIDAuMDQ4IFxcDQotMC4wMDkgJiAtMC4wMjcgJiAtMC4xNTEgJiAgMC4wMDUgJiAgMC4wMDAgJiAgMC4wMDMgJiAtMC4wMzYgJiAtMC4wMzYgJiAgMC4wNjcgXFwNCiAwLjA2MCAmICAwLjAzMCAmIC0wLjAyNiAmIC0wLjAwOSAmICAwLjAwMyAmICAwLjAwMCAmIC0wLjAxNCAmIC0wLjAyMiAmICAwLjA1NiBcXA0KLTAuMTQwICYgLTAuMTg5ICYgLTAuMDg0ICYgIDAuMDM3ICYgLTAuMDM2ICYgLTAuMDE0ICYgIDAuMDAwICYgIDAuMDc1ICYgLTAuMDM4IFxcDQotMC4wMzkgJiAtMC4wNTIgJiAtMC4wMTIgJiAtMC4wNjcgJiAtMC4wMzYgJiAtMC4wMjIgJiAgMC4wNzUgJiAgMC4wMDAgJiAtMC4wMzIgXFwNCiAwLjE0OSAmICAwLjA3MyAmICAwLjE0NyAmICAwLjA0OCAmICAwLjA2NyAmICAwLjA1NiAmIC0wLjAzOCAmIC0wLjAzMiAmICAwLjAwMA0KXGVuZHtwbWF0cml4fS4NClxdDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIENvdmFyaWFuemFzIHJlc2lkdWFsZXM6IGludGVycHJldGFjacOzbiBkZSB2YWxvcmVzIHJlc2lkdWFsZXMgZGUgbGEgbWF0cml6DQoNCkEgY29udGludWFjacOzbiBzZSBkZXN0YWNhbiBsb3MgcmVzaWR1YWxlcyBtw6FzIHJlbGV2YW50ZXMsIGNvbnNpZGVyYW5kbyBzdQ0KdmFsb3IgYWJzb2x1dG8uDQoNCiMjIyMgUmVzaWR1YWxlcyBncmFuZGVzIChwb3NpYmxlICptaXNmaXQqIGxvY2FsKSAgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KXFsNCnJfezcsMn0gPSAtMC4xODksIFxxcXVhZA0Kcl97NywxfSA9IC0wLjE0MCwgIFxxcXVhZCByX3s5LDF9ID0gMC4xNDksIFxxcXVhZA0Kcl97OSwzfSA9IDAuMTQ3LCBccXF1YWQNCnJfezUsM30gPSAtMC4xNTEuDQpcXQ0KDQpFc3RvcyB2YWxvcmVzIHN1cGVyYW4gY2xhcmFtZW50ZSBlbCB1bWJyYWwgZGUgXCgwLjEwXCksIGxvIHF1ZSBzdWdpZXJlOg0KDQotIEFzb2NpYWNpb25lcyBlbnRyZSDDrXRlbXMgbm8gZXhwbGljYWRhcyBwb3IgbG9zIGZhY3RvcmVzIGxhdGVudGVzLA0KDQotIFBvc2libGVzIGNhcmdhcyBjcnV6YWRhcyBubyBlc3BlY2lmaWNhZGFzLCBvDQoNCi0gTGEgbmVjZXNpZGFkIGRlIGludHJvZHVjaXIgY292YXJpYW56YXMgcmVzaWR1YWxlcyBlbnRyZSBlc29zIMOtdGVtcy4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCg0KIyMjIyBSZXNpZHVhbGVzIG1vZGVyYWRvcyAoaW5zcGVjY2lvbmFyKSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpcWw0Kcl97MywyfSA9IDAuMDk0LCBccXF1YWQNCnJfezQsMX0gPSAwLjA3MSwgXHFxdWFkDQpyX3s4LDd9ID0gMC4wNzUuDQpcXQ0KDQpFc3RvcyB2YWxvcmVzIG5vIHNvbiBhbGFybWFudGVzLCBwZXJvIG1lcmVjZW4gaW5zcGVjY2nDs24sIGVzcGVjaWFsbWVudGUgc2kgZXhpc3RlIHVuYSBqdXN0aWZpY2FjacOzbiB0ZcOzcmljYSBwYXJhIHVuYSByZWxhY2nDs24gYWRpY2lvbmFsIGVudHJlIGxvcyDDrXRlbXMgaW52b2x1Y3JhZG9zLg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMjIFJlc2lkdWFsZXMgcGVxdWXDsW9zIChidWVuIGFqdXN0ZSBsb2NhbCkgIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkxhIG1heW9yw61hIGRlIGxvcyByZXNpZHVhbGVzIHByZXNlbnRhbiB2YWxvcmVzIGNlcmNhbm9zIGEgY2VybywgcG9yIGVqZW1wbG86DQoNClxbDQpyX3s2LDV9ID0gMC4wMDMsIFxxcXVhZA0Kcl97NCw1fSA9IDAuMDA1LCBccXF1YWQNCnJfezMsMX0gPSAtMC4wMDguDQpcXQ0KDQpFc3RvcyBwYXJlcyBkZSDDrXRlbXMgZXN0w6FuIGFkZWN1YWRhbWVudGUgZXhwbGljYWRvcyBwb3IgZWwgbW9kZWxvIENGQSBhanVzdGFkbywgbG8gcXVlIGluZGljYSB1biBidWVuIGFqdXN0ZSBsb2NhbCBlbiBkaWNoYXMgcmVsYWNpb25lcy4NCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgQ292YXJpYW56YXMgcmVzaWR1YWxlcyAodXNhbmRvIGByZXNpZHVhbHNgKTogZW4gZXNjYWxhIGRlIGNvcnJlbGFjaW9uZXMgKG5vICp6KiksIHNpbiBlc3RhbmRhcml6YXIgDQoNCg0KIyMjIyBDb3JyZWxhY2lvbmVzIHJlc2lkdWFsZXM6IGxhIGZ1bmNpw7NuIGByZXNpZHVhbHMoKWAgZW4gYGxhdmFhbmAgey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KSGFzdGEgYWhvcmEsIGxhcyBtYXRyaWNlcyBkZSBjb3JyZWxhY2lvbmVzIHJlc2lkdWFsZXMgc2UgaGFuIGNvbnN0cnVpZG8gKmV4cGzDrWNpdGFtZW50ZSogY29tbyB1bmEgcmVzdGEgZGUgbWF0cmljZXM6DQoNClxbDQpcbWF0aGJme1J9X3tcdGV4dHtjb3J9fQ0KPQ0KXG9wZXJhdG9ybmFtZXtDb3J9KFxtYXRoYmZ7U30pDQotDQpcb3BlcmF0b3JuYW1le0Nvcn0oXGJvbGRzeW1ib2x7XFNpZ21hfSkuDQpcXQ0KDQpTaW4gZW1iYXJnbywgY3VhbmRvIHNlIHRyYWJhamEgY29uIG1vZGVsb3MgQ0ZBIGFqdXN0YWRvcyBjb24gYGxhdmFhbmAsICoqbm8gZXMgbmVjZXNhcmlvIHJlYWxpemFyIGVzdGUgY8OhbGN1bG8gbWFudWFsbWVudGUqKi4gRWwgcGFxdWV0ZSBwcm9wb3JjaW9uYSB1bmEgZm9ybWEgZGlyZWN0YSBkZSBvYnRlbmVyIGVzdGFzIGRpc2NyZXBhbmNpYXMgZW4gZXNjYWxhIGRlIGNvcnJlbGFjaW9uZXMuIA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIyBDb3JyZWxhY2lvbmVzIHJlc2lkdWFsZXM6IGFwbGljYW5kbyBgcmVzaWR1YWxzKClgIGVuIGBsYXZhYW5gIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkxhIGZ1bmNpw7NuIGByZXNpZHVhbHMoKWAgZGVsIHBhcXVldGUgYGxhdmFhbmAgY2FsY3VsYSBsb3MgKipyZXNpZHVvcyBkZWwgbW9kZWxvIGFqdXN0YWRvKiosIGVzIGRlY2lyLCBsYXMgZGlzY3JlcGFuY2lhcyBlbnRyZSBsYXMgcmVsYWNpb25lcyBvYnNlcnZhZGFzIGVuIGxvcyBkYXRvcyB5IGxhcyByZWxhY2lvbmVzIGltcGxpY2FkYXMgcG9yIGVsIG1vZGVsbyBDRkEuICBMYSBvcGNpw7NuIGB0eXBlID0gImNvciJgIHNvbGljaXRhIGV4cGzDrWNpdGFtZW50ZSBxdWUgZGljaGFzIGRpc2NyZXBhbmNpYXMgc2UgZXhwcmVzZW4gZW4gKiplc2NhbGEgZGUgY29ycmVsYWNpb25lcyoqIHkgcGVybWl0ZSBldmFsdWFyIGVsIGFqdXN0ZSBsb2NhbCBkZWwgbW9kZWxvIGRlIGZvcm1hIGNvbXBhcmFibGUgZW50cmUgcGFyZXMgZGUgw610ZW1zLi4gRXN0YSBlcyBsYSBtaXNtYSBlc2NhbGEgZGVmaW5pZGEgYW50ZXJpb3JtZW50ZSBtZWRpYW50ZSBsYSB0cmFuc2Zvcm1hY2nDs246ICRcb3BlcmF0b3JuYW1le0Nvcn0oXG1hdGhiZntBfSkgPSBcbWF0aGJme0R9X3tcbWF0aGJme0F9fV57LTEvMn1cLCBcbWF0aGJme0F9XCwgXG1hdGhiZntEfV97XG1hdGhiZntBfX1eey0xLzJ9JCwgZG9uZGUgXChcbWF0aGJme0R9X3tcbWF0aGJme0F9fVwpIGVzIGxhIG1hdHJpeiBkaWFnb25hbCBxdWUgY29udGllbmUgbGFzIHZhcmlhbnphcyAoYXNvY2lhZGFzIGEgbG9zIGVsZW1lbnRvcyBkaWFnb25hbGVzIGRlIFwoXG1hdGhiZntBfVwpKS4gIA0KDQpgYGB7cn0NCiMgQ29ycmVsYWNpb25lcyByZXNpZHVhbGVzIHJlcG9ydGFkYXMgZGlyZWN0YW1lbnRlIHBvciBsYXZhYW4NCnJlc2lkdWFscyhDRkEsIHR5cGUgPSAiY29yIikNCmBgYA0KDQogRWwgY29tcG9uZW50ZSAgYC4uLiRjb3ZgIHBlcm1pdGUgZXh0cmFlciBlc3BlY8OtZmljYW1lbnRlIGxhIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyByZXNpZHVhbGVzIGEgcGFydGlyIGRlbCBvYmpldG8gZGV2dWVsdG8gcG9yIGByZXNpZHVhbHMoKWAuDQoNCmBgYHtyfQ0KIyBDb3JyZWxhY2lvbmVzIHJlc2lkdWFsZXMgcmVwb3J0YWRhcyBkaXJlY3RhbWVudGUgcG9yIGxhdmFhbg0KUl9jb3IgPC0gcmVzaWR1YWxzKENGQSwgdHlwZSA9ICJjb3IiKSRjb3YNClJfY29yDQpgYGANCg0KDQpTZSBvYnNlcnZhIHF1ZSAkXG1hdGhiZntSfV97XHRleHR7Y29yfX0kIGVzIGxhIG1pc21hIG1hdHJpeiBoYWxsYWRhIGFudGVyaW9ybWVudGUgKFwoXG1hdGhiZntSfV97XHRleHR7Y29yLGNvdn19XCkgeSBcKFxtYXRoYmZ7Un1fe1x0ZXh0e2NvcixsYXZ9fVwpKS4gDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIyBJbXBvcnRhbnRlIChkaXN0aW5jacOzbiBjbGF2ZSk6IGFwbGljYW5kbyBgcmVzaWRgIGVuIGBsYXZhYW5gIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCg0KKipJbXBvcnRhbnRlIChkaXN0aW5jacOzbiBjbGF2ZSk6KioNCg0KTGFzIG1hdHJpY2VzIFwoXG1hdGhiZntSfV97XHRleHR7Y29yLGNvdn19XCkgeSBcKFxtYXRoYmZ7Un1fe1x0ZXh0e2NvcixsYXZ9fVwpIGVzdMOhbiBleHByZXNhZGFzIGVuICplc2NhbGEgZGUgY29ycmVsYWNpb25lcyogKHZhbG9yZXMgZW50cmUgXCgtMVwpIHkgXCgxXCkpLCBwZXJvICpubyBjb3JyZXNwb25kZW4gYSByZXNpZHVvcyBlc3RhbmRhcml6YWRvcyB0aXBvIHoqLiAgTG9zIHJlc2lkdW9zIHRpcG8gKnoqLCBxdWUgaW5jb3Jwb3JhbiBhZGVtw6FzIHVuYSBub3JtYWxpemFjacOzbiBwb3IgbGEgdmFyaWFiaWxpZGFkIGVzcGVyYWRhIGJham8gZWwgbW9kZWxvLCBzZSBleHBsaWNhcsOhbiBlbiBsYSBzZWNjacOzbiBzaWd1aWVudGUuIEVzdG9zIMO6bHRpbW9zIHNvbiBsb3MgbcOhcyBhcHJvcGlhZG9zIGN1YW5kbyBzZSBkZXNlYSBldmFsdWFyIGxhIG1hZ25pdHVkIGRlbCBtaXNmaXQgbG9jYWwgZW4gdMOpcm1pbm9zIGRlIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIuDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KcmVzaWQoZml0LCB0eXBlID0gInN0YW5kYXJkaXplZCIpDQpgYGANCg0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb3ZhcmlhbnphcyByZXNpZHVhbGVzICh1c2FuZG8gYHJlc2lkYCk6IGVuIGVzY2FsYSBkZSBjb3JyZWxhY2lvbmVzIGVzdGFuZGFyaXphZGEgKG5vcm1hbGl6YWRhKQ0KDQogDQojIyMjICBMYSBmdW5jacOzbiBgcmVzaWRgIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkxhcyBmdW5jaW9uZXMgYHJlc2lkKClgIHkgYHJlc2lkdWFscygpYCBlbiBgbGF2YWFuYCBkZXZ1ZWx2ZW4gbG9zICoqcmVzaWR1b3MgZGVsIG1vZGVsbyBhanVzdGFkbyoqLCBlcyBkZWNpciwgbGFzIGRpc2NyZXBhbmNpYXMgZW50cmUgbG8gb2JzZXJ2YWRvIGVuIGxvcyBkYXRvcyB5IGxvIGltcGxpY2FkbyBwb3IgZWwgbW9kZWxvLiBMYSBtYXRyaXogZGV2dWVsdGEgcG9yIGByZXNpZChDRkEsIHR5cGUgPSAic3RhbmRhcmRpemVkIilgIGNvcnJlc3BvbmRlIGEgdW5hIHZlcnNpw7NuICoqZXN0YW5kYXJpemFkYSAobm9ybWFsaXphZGEpKiogZGUgbG9zIHJlc2lkdW9zIGRlIGNvdmFyaWFuemFzIGRlbCBtb2RlbG8uIA0KDQoNCmBgYHtyfQ0KcmVzaWQoQ0ZBLCB0eXBlPSJzdGFuZGFyZGl6ZWQiKQ0KYGBgDQoNCg0KRW4gdMOpcm1pbm9zIG1hdHJpY2lhbGVzLCBwdWVkZSBlc2NyaWJpcnNlIGNvbW86DQoNClxbDQpcbWF0aGJme1J9X3tcdGV4dHtzdGR9fQ0KPQ0KXG1hdGhiZntEfV57LTEvMn0NClxsZWZ0KA0KXG1hdGhiZntTfSAtIFxib2xkc3ltYm9se1xTaWdtYX0NClxyaWdodCkNClxtYXRoYmZ7RH1eey0xLzJ9LA0KXF0NCg0KZG9uZGUgXChcbWF0aGJme0R9XCkgZXMgdW5hIG1hdHJpeiBkZSBlc2NhbGFtaWVudG8gcXVlIGRlcGVuZGUgZGUgbGFzIHZhcmlhbnphcyBkZSBsYXMgdmFyaWFibGVzIG9ic2VydmFkYXMgeSBkZWwgZXN0aW1hZG9yIHV0aWxpemFkbyAoZW4gZXN0ZSBjYXNvLCBtw6F4aW1hIHZlcm9zaW1pbGl0dWQsIE1MKS4gQ2FkYSBlbGVtZW50byBkZSBcKFxtYXRoYmZ7Un1fe1x0ZXh0e3N0ZH19XCkgaW5kaWNhIGN1w6FudGFzICoqZGVzdmlhY2lvbmVzIGVzdMOhbmRhcioqIHNlcGFyYW4gbGEgY292YXJpYW56YSBvYnNlcnZhZGEgZW50cmUgZG9zIMOtdGVtcyBkZSBsYSBjb3ZhcmlhbnphIHByZWRpY2hhIHBvciBlbCBtb2RlbG8uDQoNCg0KKirCv1F1w6kgZXMgbGEgbWF0cml6IFwoXG1hdGhiZntEfVwpPyoqDQoNCkVuIGxhIGV4cHJlc2nDs24gYW50ZXJpb3IsIGxhIG1hdHJpeiBcKFxtYXRoYmZ7RH1cKSBlcyB1bmEgKiptYXRyaXogZGUgZXNjYWxhbWllbnRvKiogcXVlIHJlY29nZSBsYSB2YXJpYWJpbGlkYWQgZXNwZXJhZGEgZGUgbGFzIGNvdmFyaWFuemFzIGJham8gZWwgbW9kZWxvIGFqdXN0YWRvLiBFbiBlbCBjYXNvIGRlbCBlc3RpbWFkb3IgZGUgbcOheGltYSB2ZXJvc2ltaWxpdHVkIChNTCksIFwoXG1hdGhiZntEfVwpIHNlIGNvbnN0cnV5ZSBhIHBhcnRpciBkZToNCg0KLSBMYXMgdmFyaWFuemFzIGRlIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcywgeQ0KDQotIExhIG1hdHJpeiBkZSBpbmZvcm1hY2nDs24gZGVsIG1vZGVsbywgZGUgbW9kbyBxdWUgY2FkYSByZXNpZHVvIHF1ZWRlIGV4cHJlc2FkbyBlbiAqKnVuaWRhZGVzIGRlIGRlc3ZpYWNpw7NuIGVzdMOhbmRhcioqLg0KDQpQb3IgZXN0YSByYXrDs24sIGxvcyByZXNpZHVvcyBlc3RhbmRhcml6YWRvcyBubyBzb24gc2ltcGxlbWVudGUgXCgoXG1hdGhiZntTfS1cYm9sZHN5bWJvbHtcU2lnbWF9KVwpIGRpdmlkaWRvcyBlbGVtZW50byBhIGVsZW1lbnRvIHBvciBsYXMgdmFyaWFuemFzLCBzaW5vIHVuYSAqKm5vcm1hbGl6YWNpw7NuIGVzdGFkw61zdGljYW1lbnRlIGluZm9ybWFkYSoqLCBjb2hlcmVudGUgY29uIGVsIGVzdGltYWRvciB1dGlsaXphZG8uDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgIEVsIG91dHB1dCBkZSBsYSBmdW5jacOzbiBgcmVzaWQoLi4uKSRjb3ZgIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCg0KRW4gZXN0ZSBjYXNvLCBjb24gYC4uLiRjb3ZgIHNlIG9idGllbmUgbGEgbWF0cml6IGRlIHJlc2lkdW9zIGVzdGFuZGFyaXphZG9zOg0KDQpgYGB7cn0NClJfc3RkIDwtIHJlc2lkKENGQSwgdHlwZT0ic3RhbmRhcmRpemVkIikkY292DQpSX3N0ZA0KYGBgDQoNCg0KXFsNClxtYXRoYmZ7Un1fe1x0ZXh0e3N0ZH19ID0NClxiZWdpbntwbWF0cml4fQ0KIDAuMDAwICYgLTEuOTk2ICYgLTAuOTk3ICYgIDIuNjc5ICYgLTAuMzU5ICYgIDIuMTU1ICYgLTMuNzczICYgLTEuMzgwICYgIDQuMDc3IFxcDQotMS45OTYgJiAgMC4wMDAgJiAgMi42ODkgJiAtMC4yODQgJiAtMC41OTEgJiAgMC42ODEgJiAtMy42NTQgJiAtMS4xMTkgJiAgMS42MDYgXFwNCi0wLjk5NyAmICAyLjY4OSAmICAwLjAwMCAmIC0xLjg5OSAmIC00LjE1NyAmIC0wLjcxMSAmIC0xLjg1OCAmIC0wLjMwMCAmICAzLjUxOCBcXA0KIDIuNjc5ICYgLTAuMjg0ICYgLTEuODk5ICYgIDAuMDAwICYgIDEuNTQ1ICYgLTIuNTg4ICYgIDAuODY1ICYgLTIuMDIxICYgIDEuMjI1IFxcDQotMC4zNTkgJiAtMC41OTEgJiAtNC4xNTcgJiAgMS41NDUgJiAgMC4wMDAgJiAgMC45NDIgJiAtMC44NDIgJiAtMS4wOTkgJiAgMS43MDEgXFwNCiAyLjE1NSAmICAwLjY4MSAmIC0wLjcxMSAmIC0yLjU4OCAmICAwLjk0MiAmICAwLjAwMCAmIC0wLjMyNiAmIC0wLjY0MSAmICAxLjQyMyBcXA0KLTMuNzczICYgLTMuNjU0ICYgLTEuODU4ICYgIDAuODY1ICYgLTAuODQyICYgLTAuMzI2ICYgIDAuMDAwICYgIDQuODIzICYgLTIuMzI1IFxcDQotMS4zODAgJiAtMS4xMTkgJiAtMC4zMDAgJiAtMi4wMjEgJiAtMS4wOTkgJiAtMC42NDEgJiAgNC44MjMgJiAgMC4wMDAgJiAtNC4xMzIgXFwNCiA0LjA3NyAmICAxLjYwNiAmICAzLjUxOCAmICAxLjIyNSAmICAxLjcwMSAmICAxLjQyMyAmIC0yLjMyNSAmIC00LjEzMiAmICAwLjAwMA0KXGVuZHtwbWF0cml4fS4NClxdDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb3ZhcmlhbnphcyByZXNpZHVhbGVzOiBhY2xhcmFjaW9uZXMgZ2VuZXJhbGVzDQoNCiMjIyMgIE5vdGEgcGVkYWfDs2dpY2Egey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KDQpBdW5xdWUgdG9kYXMgZXN0YXMgbWF0cmljZXMgc2UgYmFzYW4gZW4gbGEgbWlzbWEgZGlzY3JlcGFuY2lhIGZ1bmRhbWVudGFsIFwoXG1hdGhiZntTfSAtIFxib2xkc3ltYm9se1xTaWdtYX1cKSwgY2FkYSB1bmEgdXRpbGl6YSB1bmEgZXNjYWxhIGRpc3RpbnRhLiBFbiBwYXJ0aWN1bGFyLCBsb3MgcmVzaWR1b3MgZXN0YW5kYXJpemFkb3Mgc29uIGVzcGVjaWFsbWVudGUgw7p0aWxlcyBwYXJhIGVsIGRpYWduw7NzdGljbyBkZSAqbWlzZml0KiBsb2NhbCwgeWEgcXVlIHBlcm1pdGVuIGlkZW50aWZpY2FyIHJlbGFjaW9uZXMgZW50cmUgw610ZW1zIGN1eWEgY292YXJpYW56YSBvYnNlcnZhZGEgc2UgYXBhcnRhIGRlbCBtb2RlbG8gZW4gbcOhcyBkZSBkb3MgbyB0cmVzIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIuIEVuIGNvbnNlY3VlbmNpYSwgXChcbWF0aGJme1J9X3tcdGV4dHtzdGR9fVwpIHBlcm1pdGUgZXZhbHVhciBlbCAqbWlzZml0KiBsb2NhbCBlbiB1bmEgZXNjYWxhIGNvbXBhcmFibGUgZW50cmUgcGFyZXMgZGUgw610ZW1zLCBhbGdvIHF1ZSBubyBlcyBwb3NpYmxlIHVzYW5kbyBkaXJlY3RhbWVudGUgXChcbWF0aGJme1N9LVxib2xkc3ltYm9se1xTaWdtYX1cKS4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgIFJlZ2xhIHByw6FjdGljYSBwYXJhIG5vIGNvbmZ1bmRpcnNlIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkNvbXBhcmUgbGFzIGN1YXRybyBtYXRyaWNlcyBxdWUgc2UgZGVzY3JpYmVuIGFiYWpvOiANCg0KLSBgUl9zdGRgID0gYHJlc2lkKENGQSwgdHlwZSA9ICJzdGFuZGFyZGl6ZWQiKSRjb3ZgIGVzIGxhIG1hdHJpeiBcKFxtYXRoYmZ7Un1fe1x0ZXh0e3N0ZH19XCkgcXVlIGNvbnRpZW5lIHJlc2lkdW9zICplc3RhbmRhcml6YWRvcyogKHZhbG9yZXMgdGlwbyAqeiopLg0KDQoNCjo6OnNhbmdyaWEzDQpgYGB7ciwgZXZhbD1GQUxTRX0NClJfc3RkDQpgYGANCjo6Og0KDQotIGBSX2NvcmAgPSBgcmVzaWR1YWxzKENGQSwgdHlwZSA9ICJjb3IiKSRjb3ZgIGVzIGxhIG1hdHJpeiBcKFxtYXRoYmZ7Un1fe1x0ZXh0e2Nvcn19XCkgcXVlIGNvbnRpZW5lIGxvcyByZXNpZHVvcyBleHByZXNhZG9zIGVuICplc2NhbGEgZGUgY29ycmVsYWNpb25lcyouDQoNCjo6OnNhbmdyaWEzDQpgYGB7cn0NClJfY29yDQpgYGANCjo6Og0KDQotIFwoXG1hdGhiZntSfV97XHRleHR7Y292fX0gPSBcbWF0aGJme1N9X3tcdGV4dHtjb3Z9fSAtIFxib2xkc3ltYm9se1xTaWdtYX1cKSBlbiAqZXNjYWxhIG9yaWdpbmFsKiAqKm5vKiogZXMgbG8gcXVlIGRldnVlbHZlIGB0eXBlID0gInN0YW5kYXJkaXplZCJgLg0KDQo6OjpzYW5ncmlhMw0KYGBge3J9DQpSX2Nvdg0KYGBgDQo6OjoNCg0KDQotIFwoXG1hdGhiZntSfV97XHRleHR7bGF2fX0gPSBcbWF0aGJme1N9X3tcdGV4dHtsYXZ9fSAtIFxib2xkc3ltYm9se1xTaWdtYX1cKSBlbiAqZXNjYWxhIE1MKiAqKm5vKiogZXMgbG8gcXVlIGRldnVlbHZlIGB0eXBlID0gInN0YW5kYXJkaXplZCJgLg0KDQo6OjpzYW5ncmlhMw0KYGBge3J9DQpSX2xhdg0KYGBgDQo6OjoNCg0KDQoNCg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIEV4dHJheWVuZG8gY292YXJpYW56YXMgZW50cmUgZmFjdG9yZXMNCg0KIyMjIENvdmFyaWFuemEgZW50cmUgbG9zIGZhY3RvcmVzIChjb24gYGluc3BlY3RgKQ0KDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQppbnNwZWN0KENGQSwgImVzdCIpDQphdHRhY2goaW5zcGVjdChDRkEsICJlc3QiKSkNCg0KI2xhbWJkYSAjY2FyZ2FzIGZhY3RvcmlhbGVzDQojdGhldGEgICN2YXJpYW56YXMgcmVzaWR1YWxlcw0KcHNpICAgICNjb3ZhcmlhbnphcyBlbnRyZSBsb3MgZmFjdG9yZXMNCmBgYA0KDQoqKkVsIG90dXB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQojbGFtYmRhICNjYXJnYXMgZmFjdG9yaWFsZXMNCiN0aGV0YSAgI3ZhcmlhbnphcyByZXNpZHVhbGVzDQpwc2kgICAgI2NvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3Jlcw0KYGBgDQoNCkVuIGVzdGUgY2Fzbywgc2Ugb2J0aWVuZTogDQoNClxbICBcYm9sZHN5bWJvbHtcUHNpfSA9DQogICAgICBcYmVnaW57cG1hdHJpeH0NCiAgICAwLjgwOSAmIDAuNDA4ICYgMC4yNjIgXFwNCiAgICAwLjQwOCAmIDAuOTc5ICYgMC4xNzMgXFwNCiAgICAwLjI2MiAmIDAuMTczICYgMC4zODQNCiAgICBcZW5ke3BtYXRyaXh9DQogICAgXF0NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBDb3ZhcmlhbnphIGVudHJlIGxvcyBmYWN0b3JlcyAob3RyYSBmb3JtYSkNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEsIHN0YW5kYXJkaXplZD1UUlVFKSAlPiUNCiAgZmlsdGVyKG9wID09ICJ+fiIsDQogICAgICAgICBsaHMgJWluJSBjKCJ2aXN1YWwiLCAidGV4dHVhbCIsICJzcGVlZCIpLA0KICAgICAgICAgIWlzLm5hKHB2YWx1ZSkpICU+JQ0KICBtdXRhdGUoc3RhcnMgPSBpZmVsc2UocHZhbHVlIDwgLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHZhbHVlIDwgLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdmFsdWUgPCAuMDUsICIqIiwgIiIpKSkpICU+JQ0KICBzZWxlY3QoJ0ZhY3RvciAxJz1saHMsDQogICAgICAgICAnRmFjdG9yIDInPXJocywNCiAgICAgICAgICdDb3JyZWxhY2nDs24nPWVzdCwNCiAgICAgICAgICdTaWcuJz1zdGFycykgJT4lDQogIA0KICBrYWJsZShkaWdpdHMgPSAzLCAgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3JlcyIpDQpgYGANCg0KDQoqKkVsIG91dHB1dC4qKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEsIHN0YW5kYXJkaXplZD1UUlVFKSAlPiUNCiAgZmlsdGVyKG9wID09ICJ+fiIsDQogICAgICAgICBsaHMgJWluJSBjKCJ2aXN1YWwiLCAidGV4dHVhbCIsICJzcGVlZCIpLA0KICAgICAgICAgIWlzLm5hKHB2YWx1ZSkpICU+JQ0KICBtdXRhdGUoc3RhcnMgPSBpZmVsc2UocHZhbHVlIDwgLjAwMSwgIioqKiIsDQogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UocHZhbHVlIDwgLjAxLCAiKioiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShwdmFsdWUgPCAuMDUsICIqIiwgIiIpKSkpICU+JQ0KICBzZWxlY3QoJ0ZhY3RvciAxJz1saHMsDQogICAgICAgICAnRmFjdG9yIDInPXJocywNCiAgICAgICAgICdDb3JyZWxhY2nDs24nPWVzdCwNCiAgICAgICAgICdTaWcuJz1zdGFycykgJT4lDQogIA0KICBrYWJsZShkaWdpdHMgPSAzLCAgYWxpZ249ImMiLCBmb3JtYXQ9InBhbmRvYyIsIGNhcHRpb249IkNvdmFyaWFuemFzIGVudHJlIGxvcyBmYWN0b3JlcyIpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBtZWRpZGFzIGRlIGFqdXN0ZQ0KDQojIyMgTWVkaWRhcyBkZSBhanVzdGU6IHRvZGFzDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQptIDwtIGluc3BlY3QoQ0ZBLCAnZml0Lm1lYXN1cmVzJyk7IG0gIzEuIFRvZGFzIGxhcyBtZWRpZGFzDQptIDwtIGZpdE1lYXN1cmVzKENGQSk7IG0gICAgICAgICAgICAgIzIuIElndWFsIHF1ZSBlbCBhbnRlcmlvcg0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCm0gPC0gaW5zcGVjdChDRkEsICdmaXQubWVhc3VyZXMnKTsgbSAjRml0IG1lYXN1cmVzDQptIDwtIGZpdE1lYXN1cmVzKENGQSkgI0ZpdCBtZWFzdXJlcyAoaWd1YWwgcXVlIGxhIGFudGVyaW9yKQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgKE5vIG1vZGlmaWNhcikgLS0+DQoNCiMjIyBNZWRpZGFzIGRlIGFqdXN0ZTogZGVzZGUgdW5hIGxpc3RhDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpsaXN0YSA8LSBjKCJjaGlzcSIsICJkZiIsICJjZmkiLCAicm1zZWEiLCAic3JtciIsICJtZmkiLCAiYmljIiwgIm5maSIpDQpsaXN0YQ0KDQptczwtZml0TWVhc3VyZXMoQ0ZBKVtsaXN0YV07IG1zICAgICAgIzMuIExpc3RhIGVzcGVjw61maWNhIGRlIG1lZGlkYXMNCm1zPC1maXRNZWFzdXJlcyhDRkEsIGxpc3RhKTsgbXMgICAgICAjNC4gSWd1YWwgcXVlIGVsIGFudGVyaW9yDQptczwtcm91bmQobXMsMyk7IG1zDQpgYGANCg0KKipFbCBvdXRwdXQuICoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KbGlzdGEgPC0gYygiY2hpc3EiLCAiZGYiLCAiY2ZpIiwgInJtc2VhIiwgInNybXIiLCAibWZpIiwgImJpYyIsICJuZmkiKQ0KbGlzdGENCg0KbXM8LWZpdE1lYXN1cmVzKENGQSlbbGlzdGFdICAjU3BlY2lmaWMgZml0IG1lYXN1cmVzDQptczwtZml0TWVhc3VyZXMoQ0ZBLCBsaXN0YSkgICNJZ3VhbCBxdWUgZWwgYW50ZXJpb3INCm1zPC1yb3VuZChtcywzKTsgbXMNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIGxhcyBtZWRpYXMNCg0KIyMjIE1lZGlhczogZXhwbGljYWNpw7NuDQoNCjEuIEVuIGdlbmVyYWwsIGxvcyBtb2RlbG9zIGRlIGVjdWFjaW9uZXMgZXN0cnVjdHVyYWxlcyBzZSB1dGlsaXphbiBwYXJhIG1vZGVsYXIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemEgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGVuIHVuIGNvbmp1bnRvIGRlIGRhdG9zLiANCg0KMi4gTm8gb2JzdGFudGUsIGVuIGFsZ3VuYXMgYXBsaWNhY2lvbmVzLCBlcyDDunRpbCBpbmNsdWlyIHRhbWJpw6luIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzLiANCg0KMy4gUGFyYSBsb2dyYXIgZXN0bywgc2UgcHVlZGVuIGVzcGVjaWZpY2FyIGV4cGzDrWNpdGFtZW50ZSBsb3MgaW50ZXJjZXB0b3MgZW4gbGEgc2ludGF4aXMgZGUgYGxhdmFhbmAuIA0KDQozLiBFc3RvIHNlIHJlYWxpemEgaW5jbHV5ZW5kbyAiZsOzcm11bGFzIGRlIGludGVyY2VwdG8iIGVuIGxhIHNpbnRheGlzIGRlbCBtb2RlbG8uIFVuYSBmw7NybXVsYSBkZSBpbnRlcmNlcHRvIHRpZW5lIGVsIHNpZ3VpZW50ZSBmb3JtYXRvOg0KDQo6OjpzYW5ncmlhMw0KYGBge3IsIGV2YWw9RkFMU0V9DQp2YXJpYWJsZSB+IDENCmBgYA0KOjo6DQoNCg0KDQo0LiBFbiBlc3RhIGV4cHJlc2nDs24sIGxhIHBhcnRlIGl6cXVpZXJkYSBjb250aWVuZSBlbCBub21icmUgZGUgbGEgdmFyaWFibGUgb2JzZXJ2YWRhIG8gbGF0ZW50ZSwgeSBsYSBwYXJ0ZSBkZXJlY2hhIGNvbnRpZW5lIGVsIG7Dum1lcm8gMSwgcXVlIHJlcHJlc2VudGEgZWwgaW50ZXJjZXB0by4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBNZWRpYXM6IGVqZW1wbG8NCg0KUG9yIGVqZW1wbG8sIGVuIGVsIG1vZGVsbyBkZSBhbsOhbGlzaXMgZmFjdG9yaWFsIGNvbmZpcm1hdG9yaW8gKENGQSkgZGUgdHJlcyBmYWN0b3JlcyBkZSBIb2x6aW5nZXIgeSBTd2luZWZvcmQsIHBvZGVtb3MgYcOxYWRpciBsb3MgaW50ZXJjZXB0b3MgZGUgbGFzIHZhcmlhYmxlcyBvYnNlcnZhZGFzIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6DQoNCioqRWwgbW9kZWxvLioqDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KIyBFamVtcGxvIGRlIHNpbnRheGlzIGVuIGxhdmFhbiBjb24gaW50ZXJjZXB0b3MNCnZpc3VhbCA9fiB4MSArIHgyICsgeDMNCnRleHR1YWwgPX4geDQgKyB4NSArIHg2DQpzcGVlZCA9fiB4NyArIHg4ICsgeDkNCg0KeDEgfiAxDQp4MiB+IDENCngzIH4gMQ0KeDQgfiAxDQp4NSB+IDENCng2IH4gMQ0KeDcgfiAxDQp4OCB+IDENCng5IH4gMQ0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMgRXh0cmF5ZW5kbyBjb24gYG1lYW5zdHJ1Y3R1cmVgIA0KDQojIyMgYG1lYW5zdHJ1Y3R1cmVgOiBleHBsaWNhY2nDs24NCg0KQSB2ZWNlcywgZXMgbcOhcyBjb252ZW5pZW50ZSBvbWl0aXIgbGFzIGbDs3JtdWxhcyBkZSBpbnRlcmNlcHRvIGVuIGxhIHNpbnRheGlzIGRlbCBtb2RlbG8gKGEgbWVub3MgcXVlIGRlc2VlIHN1cyB2YWxvcmVzKSwgeSBhw7FhZGlyIGVsIGFyZ3VtZW50byBgbWVhbnN0cnVjdHVyZSA9IFRSVUVgIGVuIGxhcyBsbGFtYWRhcyBhIGxhcyBmdW5jaW9uZXMgYGNmYWAgeSBgc2VtYC4gDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgYG1lYW5zdHJ1Y3R1cmVgOiBlamVtcGxvDQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQpmaXQgPC0gY2ZhKG1vZGVsbywgZGF0YT1kYXQsIG1lYW5zdHJ1Y3R1cmU9VFJVRSkNCnN1bW1hcnkoZml0KQ0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdCA8LSBjZmEobW9kZWxvLCBkYXRhPWRhdCwgbWVhbnN0cnVjdHVyZT1UUlVFKQ0Kc3VtbWFyeShmaXQpDQpgYGANCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBgbWVhbnN0cnVjdHVyZWA6IEludGVycHJldGFjacOzbg0KDQoxLiBDb21vIHB1ZWRlIG9ic2VydmFyIGVuIGVsIHJlc3VsdGFkbywgZWwgbW9kZWxvIGluY2x1eWUgcGFyw6FtZXRyb3MgZGUgaW50ZXJjZXBjacOzbiB0YW50byBwYXJhIGxhcyB2YXJpYWJsZXMgb2JzZXJ2YWRhcyBjb21vIHBhcmEgbGFzIGxhdGVudGVzLiANCg0KMi4gUG9yIGRlZmVjdG8sIGxhcyBmdW5jaW9uZXMgY2ZhIHkgc2VtIGZpamFuIGxvcyBpbnRlcmNlcHRvcyBkZSBsYXMgdmFyaWFibGVzIGxhdGVudGVzIChxdWUgZW4gZXN0ZSBjYXNvIGNvcnJlc3BvbmRlbiBhIGxhcyBtZWRpYXMgbGF0ZW50ZXMpIGEgY2Vyby4gDQoNCjMuIERlIG90cm8gbW9kbywgZWwgbW9kZWxvIG5vIHNlcsOtYSBlc3RpbWFibGUuIA0KDQo0LiBDYWJlIGRlc3RhY2FyIHF1ZSBlbCBlc3RhZMOtc3RpY28gY2hpLWN1YWRyYWRvIHkgZWwgbsO6bWVybyBkZSBncmFkb3MgZGUgbGliZXJ0YWQgc29uIGxvcyBtaXNtb3MgcXVlIGVuIGVsIG1vZGVsbyBvcmlnaW5hbCAoc2luIGVzdHJ1Y3R1cmEgZGUgbWVkaWFzKS4gDQoNCjUuIEVzdG8gc2UgZGViZSBhIHF1ZSwgYXVucXVlIGhlbW9zIGHDsWFkaWRvIG51ZXZvcyBkYXRvcyAodW4gdmFsb3IgbWVkaW8gcGFyYSBjYWRhIHVuYSBkZSBsYXMgOSB2YXJpYWJsZXMgb2JzZXJ2YWRhcyksIHRhbWJpw6luIGhlbW9zIGludHJvZHVjaWRvIDkgcGFyw6FtZXRyb3MgYWRpY2lvbmFsZXMgYWwgbW9kZWxvICh1biBpbnRlcmNlcHRvIHBhcmEgY2FkYSB1bmEgZGUgbGFzIDkgdmFyaWFibGVzIG9ic2VydmFkYXMpLiANCg0KNi4gRWwgcmVzdWx0YWRvIGZpbmFsIGVzIHVuIGFqdXN0ZSBpZMOpbnRpY28uIA0KDQo3LiBFbiBsYSBwcsOhY3RpY2EsIGxhIMO6bmljYSByYXrDs24gcGFyYSBxdWUgdW4gdXN1YXJpbyBhw7FhZGEgZsOzcm11bGFzIGRlIGludGVyY2VwY2nDs24gZW4gbGEgc2ludGF4aXMgZGVsIG1vZGVsbyBlcyBwYXJhIGVzcGVjaWZpY2FyIGNpZXJ0YXMgcmVzdHJpY2Npb25lcyBuZWNlc2FyaWFzIGVuIGVsIG1vZGVsby4NCg0KOC4gUG9yIGVqZW1wbG8sIHJldmlzZSBsYSBzaXR1YWNpw7NuIHF1ZSBzZSBpbmRpY2EgYSBjb250aW51YWNpw7NuLiANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIGBtZWFuc3RydWN0dXJlYDogZmlqYW5kbyBpbnRlcmNlcHRvcw0KDQpQb3IgZWplbXBsbywgc3Vwb25nYW1vcyBxdWUgZGVzZWFtb3MgeCBsb3MgaW50ZXJjZXB0b3MgZGUgbGFzIHZhcmlhYmxlcyBgeDFgLCBgeDJgLCBgeDNgIHkgYHg0YCBhLCBkaWdhbW9zLCBgMC41YC4gRXNjcmliaXLDrWFtb3MgbGEgc2ludGF4aXMgZGVsIG1vZGVsbyBjb21vIHNpZ3VlOg0KDQoqKkVsIG1vZGVsby4gKioNCg0KYGBge3J9DQojIE1vZGVsbyBkZSB0cmVzIGZhY3RvcmVzDQoNCm1vZGVsby5maXggPC0gJw0KdmlzdWFsID1+IHgxICsgeDIgKyB4Mw0KdGV4dHVhbCA9fiB4NCArIHg1ICsgeDYNCnNwZWVkID1+IHg3ICsgeDggKyB4OQ0KDQojIEludGVyY2VwdG9zIGNvbiB2YWxvcmVzIGZpam9zDQp4MSArIHgyICsgeDMgKyB4NCB+IDAuNSoxDQonDQpgYGANCg0KKipPYnNlcnZhY2nDs24uICoqDQoNCkFycmliYSAgaGVtb3MgdXRpbGl6YWRvIGVsIGxhZG8gaXpxdWllcmRvIGRlIGxhIGbDs3JtdWxhIHBhcmEgwqtyZXBldGlywrsgZWwgbGFkbyBkZXJlY2hvIHBhcmEgY2FkYSBlbGVtZW50byBkZWwgbGFkbyBpenF1aWVyZG8uDQoNCg0KKipFamVjdXRhbmRvIENGQS4gKioNCg0KYGBge3J9DQpDRkEuZml4IDwtIGNmYShtb2RlbG8uZml4LCBkYXRhPWRhdCkNCnN1bW1hcnkoQ0ZBLmZpeCkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBFeHRyYXllbmRvIG90cm9zIGVsZW1lbnRvcw0KDQojIyMgT3Ryb3M6IGB2Y292YA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMjIE1vdGl2YWNpw7NuICB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpMYSBmdW5jacOzbiBgdmNvdmAgcmV0b3JuYSBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgZXN0aW1hZGEgZGUgbG9zIHBhcsOhbWV0cm9zIGxpYnJlcyBlc3RpbWFkb3MgZGVsIG1vZGVsby4gRm9ybWFsbWVudGU6DQoNCi0gTm8gZXMgdW5hIG1hdHJpeiBkZSBkYXRvcy4NCg0KLSBObyBlcyB1bmEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVudHJlIMOtdGVtcy4NCg0KLSBFcyBsYSBtYXRyaXogZGUgY292YXJpYW56YXMgZGVsIHZlY3RvciBkZSBlc3RpbWFkb3Jlcy4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyMgRGVmaW5pY2nDs24gbWF0ZW3DoXRpY2Egey51bmxpc3RlZCAudW5udW1iZXJlZH0NCg0KU2kgZGVub3RhbW9zIHBvcg0KDQpcWw0KXHdpZGVoYXR7XGJvbGRzeW1ib2x7XHRoZXRhfX0NCj0NCihcd2lkZWhhdHtcdGhldGF9XzEsIFx3aWRlaGF0e1x0aGV0YX1fMiwgXGxkb3RzLCBcd2lkZWhhdHtcdGhldGF9X3ApXlx0b3ANClxdDQoNCmVsIHZlY3RvciBkZSBwYXLDoW1ldHJvcyBlc3RpbWFkb3MgZGVsIG1vZGVsbyAoY2FyZ2FzIGZhY3RvcmlhbGVzLCB2YXJpYW56YXMsIGNvdmFyaWFuemFzLCBlbnRyZSBvdHJvcyksIGVudG9uY2VzIGxhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgZGUgbG9zIGVzdGltYWRvcmVzIGVzdMOhIGRhZGEgcG9yOg0KDQpcWw0KXG9wZXJhdG9ybmFtZXt2Y292fShcd2lkZWhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSkNCj0NClxvcGVyYXRvcm5hbWV7VmFyfShcd2lkZWhhdHtcYm9sZHN5bWJvbHtcdGhldGF9fSkuDQpcXQ0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyMgQ8OzZGlnbyBlbiBgUmAgIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCioqRWwgY8OzZGlnby4gKioNCg0KYGBge3IsIGV2YWw9RkFMU0V9DQp2Y292KENGQSkNCmBgYA0KDQoqKkVsIG91dHB1dC4gKioNCg0KYGBge3IsIGVjaG89RkFMU0V9DQp2Y292KENGQSkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KDQojIyMjIEludGVycHJldGFjacOzbiBlc3RhZMOtc3RpY2EgZGUgbGEgc2FsaWRhICB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KDQpDb24gcmVzcGVjdG8gYSBsYSBlc3RydWN0dXJhIGRlIGxhIG1hdHJpeiB0ZW5lbW9zOiANCg0KLSAqKkZpbGFzIHkgY29sdW1uYXMqKjogY29ycmVzcG9uZGVuIGEgbG9zIHBhcsOhbWV0cm9zIGVzdGltYWRvcyBkZWwgbW9kZWxvICAocG9yIGVqZW1wbG8sIGB2aXN1YWw9fngyYCwgYHgxfn54MWAsIGB2aXN1YWx+fnRleHR1YWxgLCBldGMuKS4NCg0KLSAqKkRpYWdvbmFsKio6IGNvbnRpZW5lIGxhcyB2YXJpYW56YXMgZGUgbG9zIGVzdGltYWRvcmVzLA0KDQpcWw0KXG9wZXJhdG9ybmFtZXtWYXJ9KFx3aWRlaGF0e1x0aGV0YX1faSksDQpcXQ0KDQo6OjpzYW5ncmlhMw0KY3V5YSByYcOteiBjdWFkcmFkYSBjb3JyZXNwb25kZSBhbCAqKmVycm9yIGVzdMOhbmRhcioqIGRlbCBlc3RpbWFkb3I6DQo6OjoNCg0KXFsNClxvcGVyYXRvcm5hbWV7U0V9KFx3aWRlaGF0e1x0aGV0YX1faSkNCj0NClxzcXJ0e1xvcGVyYXRvcm5hbWV7VmFyfShcd2lkZWhhdHtcdGhldGF9X2kpfS4NClxdDQoNCi0gKipGdWVyYSBkZSBsYSBkaWFnb25hbCoqOiBjb250aWVuZSBsYXMgY292YXJpYW56YXMgZW50cmUgZXN0aW1hZG9yZXMsDQoNClxbDQpcb3BlcmF0b3JuYW1le0Nvdn0oXHdpZGVoYXR7XHRoZXRhfV9pLCBcd2lkZWhhdHtcdGhldGF9X2opLA0KXF0NCg0KOjo6c2FuZ3JpYTMNCmxhcyBjdWFsZXMgaW5kaWNhbiAqKmRlcGVuZGVuY2lhIGVzdGFkw61zdGljYSBlbnRyZSBsb3MgZXN0aW1hZG9yZXMqKiwgdW4gZmVuw7NtZW5vIGhhYml0dWFsIGVuIG1vZGVsb3MgZGUgZWN1YWNpb25lcyBlc3RydWN0dXJhbGVzIChTRU0pLg0KOjo6DQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgT3Ryb3M6IGBBSUNgIHkgYEJJQ2ANCg0KKipFbCBjw7NkaWdvIHkgbGEgc2FsaWRhLiAqKg0KDQpFbCBjb21hbmRvIGRlIGFiYWpvIGV4dHJhZSB5IHByZXNlbnRhIGRlIGZvcm1hIGNvbmp1bnRhIGRvcyBjcml0ZXJpb3MgZGUgaW5mb3JtYWNpw7NuIGFtcGxpYW1lbnRlIHV0aWxpemFkb3MgcGFyYSBsYSBjb21wYXJhY2nDs24gZGUgbW9kZWxvczogZWwgQWthaWtlIEluZm9ybWF0aW9uIENyaXRlcmlvbiAoQUlDKSB5IGVsIEJheWVzaWFuIEluZm9ybWF0aW9uIENyaXRlcmlvbiAoQklDKS4NCg0KYGBge3J9DQpjYmluZChBSUMoQ0ZBKSwgQklDKENGQSkpDQpgYGANCg0KDQoNCioqQ2xhdmVzIGRlIGludGVycHJldGFjacOzbioqDQoNCi0gKlZhbG9yZXMgbcOhcyBwZXF1ZcOxb3MqIGRlIEFJQyBvIEJJQyBpbmRpY2FuIHVuICptZWpvciBjb21wcm9taXNvKiBlbnRyZSAgYWp1c3RlIHkgcGFyc2ltb25pYS4NCg0KLSAqQUlDKiBwZW5hbGl6YSBsYSBjb21wbGVqaWRhZCBkZSBtYW5lcmEgbcOhcyBzdWF2ZSB5IGVzIHByZWZlcmlkbyBjdWFuZG8gZWwgIG9iamV0aXZvIGVzICpjb21wYXJhciBtb2RlbG9zIHByZWRpY3Rpdm9zKi4NCg0KLSAqQklDKiBpbXBvbmUgdW5hIHBlbmFsaXphY2nDs24gbcOhcyBmdWVydGUsIGVzcGVjaWFsbWVudGUgZW4gbXVlc3RyYXMgZ3JhbmRlcywgIHkgdGllbmRlIGEgZmF2b3JlY2VyICptb2RlbG9zIG3DoXMgcGFyc2ltb25pb3NvcyouDQoNCi0gRXN0b3MgY3JpdGVyaW9zICpubyBzZSBpbnRlcnByZXRhbiBkZSBmb3JtYSBhYnNvbHV0YSosIHNpbm8gKnJlbGF0aXZhKjogICBzb2xvIHRpZW5lbiBzZW50aWRvIGFsIGNvbXBhcmFyICpkb3MgbyBtw6FzIG1vZGVsb3MgYWp1c3RhZG9zIGEgbG9zIG1pc21vcyAgZGF0b3MqLg0KDQoNCg0KKipPYnNlcnZhY2lvbmVzIGltcG9ydGFudGVzKioNCg0KLSBFbiBlc3RlIGNhc28sIGxvcyB2YWxvcmVzIHJlcG9ydGFkb3MgZGUgQUlDIHkgQklDIGNvbnN0aXR1eWVuIHVuYSBsw61uZWEgYmFzZSBxdWUgcHVlZGUgdXRpbGl6YXJzZSBwYXJhIGNvbXBhcmFyIGVzdGUgbW9kZWxvIENGQSBjb24gbW9kZWxvcyBhbHRlcm5hdGl2b3MgKHBvciBlamVtcGxvLCBtb2RlbG9zIGNvbiByZXN0cmljY2lvbmVzIGFkaWNpb25hbGVzIG8gbW9kZWxvcyBtw6FzIGNvbXBsZWpvcykuDQoNCi0gQUlDIHkgQklDIHBlcm1pdGVuIGNvbXBhcmFyIG1vZGVsb3MgQ0ZBIGNvbnNpZGVyYW5kbyBzaW11bHTDoW5lYW1lbnRlIHN1IGFqdXN0ZSBhIGxvcyBkYXRvcyB5IHN1IGNvbXBsZWppZGFkLCBmYXZvcmVjaWVuZG8gYXF1ZWxsb3MgcXVlIGV4cGxpY2FuIG1lam9yIGxhIGVzdHJ1Y3R1cmEgb2JzZXJ2YWRhIGNvbiBlbCBtZW5vciBuw7ptZXJvIGRlIHBhcsOhbWV0cm9zLg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgT3Ryb3M6IGBwYXJhbWV0ZXJFc3RpbWF0ZXNgDQoNCioqRWwgY8OzZGlnbyB5IGxhIHNhbGlkYS4gKioNCg0KQXF1w60sIGBwYXJhbWV0ZXJFc3RpbWF0ZXMoQ0ZBKWAgZGV2dWVsdmUgdW5hIHRhYmxhIGNvbiBsYXMgZXN0aW1hY2lvbmVzIHkgbG9zIGVzdGFkw61zdGljb3MgZGUgaW5mZXJlbmNpYSBhc29jaWFkb3MgYSBjYWRhIHBhcsOhbWV0cm8gZGVsIG1vZGVsby4gDQoNCg0KDQpgYGB7cn0NCnBhcmFtZXRlckVzdGltYXRlcyhDRkEpDQpgYGANCg0KDQpDb21vIHNlIGluZGljw7MgcHJldmlhbWVudGUsIGEgY29udGludWFjacOzbiBzZSBkZXNjcmliZW4gw7puaWNhbWVudGUgYXF1ZWxsYXMgY29sdW1uYXMgcXVlIG5vIGFwYXJlY2VuIGRpcmVjdGFtZW50ZSBlbiBgcGFyVGFibGUoKWAgbyBxdWUgbm8gc2UgcmVwb3J0YW4gYWxsw60gY29tbyByZXN1bHRhZG9zIGluZmVyZW5jaWFsZXMuICBFbiBlc3RlIG91dHB1dCwgZGljaGFzIGNvbHVtbmFzIHNvbiBsYXMgc2lndWllbnRlczoNCg0KLSAqKmBzZWAqKiAoKnN0YW5kYXJkIGVycm9yKik6IGNvcnJlc3BvbmRlIGFsIGVycm9yIGVzdMOhbmRhciBkZSBsYSBlc3RpbWFjacOzbiAgIGBlc3RgLiBNaWRlIGxhIGluY2VydGlkdW1icmUgYXNvY2lhZGEgYWwgZXN0aW1hZG9yIHkgc2Ugb2J0aWVuZSBhIHBhcnRpciBkZSBsYSAgIG1hdHJpeiBkZSB2YXJpYW56YXPigJNjb3ZhcmlhbnphcyBkZSBsb3MgZXN0aW1hZG9yZXM6DQoNClxbDQpcb3BlcmF0b3JuYW1le1NFfShcd2lkZWhhdHtcdGhldGF9X2kpDQo9DQpcc3FydHtcb3BlcmF0b3JuYW1le1Zhcn0oXHdpZGVoYXR7XHRoZXRhfV9pKX0uDQpcXQ0KDQotICoqYHpgKio6IGVzdGFkw61zdGljbyBkZSBXYWxkIHBhcmEgY29udHJhc3RhciBsYSBoaXDDs3Rlc2lzIG51bGEgICBcKEhfMDogXHRoZXRhID0gMFwpLCBkZWZpbmlkbyBjb21vOg0KDQpcWw0Keg0KPQ0KXGZyYWN7XHdpZGVoYXR7XHRoZXRhfX17XG9wZXJhdG9ybmFtZXtTRX0oXHdpZGVoYXR7XHRoZXRhfSl9Lg0KXF0NCg0KICBTaSBgc2UgPSAwYCAoY29tbyBvY3VycmUgZW4gcGFyw6FtZXRyb3MgZmlqYWRvcyBwb3IgaWRlbnRpZmljYWNpw7NuKSwgZWwgdmFsb3IgICBkZSBcKHpcKSBubyBlc3TDoSBkZWZpbmlkbyB5IHNlIHJlcG9ydGEgY29tbyBgTkFgLg0KDQotICoqYHB2YWx1ZWAqKjogdmFsb3ItXChwXCkgYXNvY2lhZG8gYWwgdGVzdCBkZSBXYWxkIGJham8gdW5hIGFwcm94aW1hY2nDs24gICBub3JtYWwuIEluZGljYSBsYSBldmlkZW5jaWEgZXN0YWTDrXN0aWNhIGNvbnRyYSBsYSBoaXDDs3Rlc2lzIG51bGEgICBcKEhfMDogXHRoZXRhID0gMFwpLiBWYWxvcmVzIHBlcXVlw7FvcyBzdWdpZXJlbiBxdWUgZWwgcGFyw6FtZXRybyBlcyAgIHNpZ25pZmljYXRpdmFtZW50ZSBkaXN0aW50byBkZSBjZXJvLg0KDQotICoqYGNpLmxvd2VyYCwgYGNpLnVwcGVyYCoqOiBsw61taXRlcyBpbmZlcmlvciB5IHN1cGVyaW9yIGRlbCBpbnRlcnZhbG8gZGUgICBjb25maWFuemEgKHBvciBkZWZlY3RvLCB0w61waWNhbWVudGUgZGVsIDk1JSksIHF1ZSBzdWVsZSBjYWxjdWxhcnNlIGNvbW86DQoNClxbDQpcd2lkZWhhdHtcdGhldGF9DQpccG0NCnpfezAuOTc1fVwsXG9wZXJhdG9ybmFtZXtTRX0oXHdpZGVoYXR7XHRoZXRhfSkuDQpcXQ0KDQogIEN1YW5kbyBlbCBpbnRlcnZhbG8gZGUgY29uZmlhbnphIG5vIGNvbnRpZW5lIGVsIHZhbG9yIGNlcm8sIGVsIHJlc3VsdGFkbyBlcyAgIGNvbnNpc3RlbnRlIGNvbiB1biB2YWxvci1cKHBcKSBwZXF1ZcOxbyBlbiBlbCB0ZXN0IGJpbGF0ZXJhbC4NCg0KKipOb3RhcyByw6FwaWRhcyBzb2JyZSBsYSB0YWJsYToqKg0KDQotIExhcyBjYXJnYXMgZmFjdG9yaWFsZXMgZmlqYWRhcyBhIDEgcG9yIHJhem9uZXMgZGUgaWRlbnRpZmljYWNpw7NuIChwb3IgZWplbXBsbywgICBgdmlzdWFsID1+IHgxYCkgcHJlc2VudGFuIGBzZSA9IDBgLCBwb3IgbG8gcXVlIGxvcyBlc3RhZMOtc3RpY29zIGB6YCB5IGBwdmFsdWVgICAgYXBhcmVjZW4gY29tbyBgTkFgLCB5IGVsIGludGVydmFsbyBkZSBjb25maWFuemEgc2UgcmVkdWNlIGFsIHZhbG9yICAgXChbMSxcLDFdXCkuDQoNCi0gUGFyYSBsYXMgY2FyZ2FzIGZhY3RvcmlhbGVzIHkgY292YXJpYW56YXMgbGlicmVzLCBzZSBvYnNlcnZhbiB2YWxvcmVzIGdyYW5kZXMgICBkZWwgZXN0YWTDrXN0aWNvIFwoelwpIHkgdmFsb3Jlcy1cKHBcKSBjZXJjYW5vcyBhIGNlcm8sIGxvIHF1ZSBpbmRpY2EgcXVlIGVzdG9zICAgcGFyw6FtZXRyb3Mgc29uIHNpZ25pZmljYXRpdmFtZW50ZSBkaXN0aW50b3MgZGUgY2Vyby4NCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIE90cm9zOiBgc3RhbmRhcmRpemVkU29sdXRpb25gDQoNCioqRWwgY8OzZGlnbyB5IGxhIHNhbGlkYS4gKioNCg0KTGEgZnVuY2nDs24gYHN0YW5kYXJkaXplZFNvbHV0aW9uKClgIHByZXNlbnRhIGxhcyAqZXN0aW1hY2lvbmVzIGRlIGxvcyBwYXLDoW1ldHJvcyBlbiBlc2NhbGEgZXN0YW5kYXJpemFkYSosIGxvIHF1ZSBwZXJtaXRlIGludGVycHJldGFyIGRpcmVjdGFtZW50ZSBsYSBtYWduaXR1ZCByZWxhdGl2YSBkZSBsYXMgcmVsYWNpb25lcyBkZWwgbW9kZWxvLCBpbmRlcGVuZGllbnRlbWVudGUgZGUgbGFzIHVuaWRhZGVzIGRlIG1lZGlkYSBvcmlnaW5hbGVzLg0KDQpBIGRpZmVyZW5jaWEgZGUgYHBhcmFtZXRlckVzdGltYXRlcygpYCwgZWwgw6luZmFzaXMgYXF1w60gcmVjYWUgZW4gbGEgY29sdW1uYSBgZXN0LnN0ZGAsIHF1ZSBjb250aWVuZSBsb3MgKnBhcsOhbWV0cm9zIGNvbXBsZXRhbWVudGUgZXN0YW5kYXJpemFkb3MqLg0KDQoNCg0KDQpgYGB7cn0NCnN0YW5kYXJkaXplZFNvbHV0aW9uKENGQSkNCmBgYA0KDQoNCioqSW50ZXJwcmV0YWNpw7NuIGRlIGxhIHNhbGlkYSoqDQoNCi0gKipgZXN0LnN0ZGAqKjogZXN0aW1hY2nDs24gZXN0YW5kYXJpemFkYSBkZWwgcGFyw6FtZXRyby4gIEVuIGVsIGNhc28gZGUgbGFzIGNhcmdhcyBmYWN0b3JpYWxlcywgcmVwcmVzZW50YSBsYSAqY29ycmVsYWNpw7NuKiBlbnRyZSBlbA0KICDDrXRlbSBvYnNlcnZhZG8geSBlbCBmYWN0b3IgbGF0ZW50ZS4gVmFsb3JlcyBjZXJjYW5vcyBhIDEgaW5kaWNhbiB1bmEgcmVsYWNpw7NuICAgZnVlcnRlLCBtaWVudHJhcyBxdWUgdmFsb3JlcyBiYWpvcyBpbmRpY2FuIHVuYSBjb250cmlidWNpw7NuIGTDqWJpbCBkZWwgw610ZW0gYWwgICBmYWN0b3IuDQoNCi0gUGFyYSBsYXMgKip2YXJpYW56YXMgcmVzaWR1YWxlcyBlc3RhbmRhcml6YWRhcyoqIChgeF9pIH5+IHhfaWApLCBgZXN0LnN0ZGAgICByZXByZXNlbnRhIGxhICpwcm9wb3JjacOzbiBkZSB2YXJpYW56YSBubyBleHBsaWNhZGEqIGRlbCDDrXRlbS4gVmFsb3JlcyBtw6FzICAgcGVxdWXDsW9zIGluZGljYW4gcXVlIGVsIGZhY3RvciBleHBsaWNhIHVuYSBtYXlvciBwcm9wb3JjacOzbiBkZSBsYSB2YXJpYW56YSBkZWwgICDDrXRlbS4NCg0KLSBFbiBsYXMgKipjb3ZhcmlhbnphcyBlbnRyZSBmYWN0b3JlcyBsYXRlbnRlcyoqLCBsb3MgdmFsb3JlcyBlc3RhbmRhcml6YWRvcyAgIHB1ZWRlbiBpbnRlcnByZXRhcnNlIGNvbW8gKmNvcnJlbGFjaW9uZXMgbGF0ZW50ZXMqLCBmYWNpbGl0YW5kbyBsYSAgIGNvbXBhcmFjacOzbiBkZSBsYSBmdWVyemEgZGUgYXNvY2lhY2nDs24gZW50cmUgZmFjdG9yZXMuDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBPdHJvczogYGZpdHRlZC52YWx1ZXNgDQoNCkVuIGBsYXZhYW5gLCBsYSBmdW5jacOzbiBgZml0dGVkLnZhbHVlcygpYCBwZXJtaXRlIG9idGVuZXIgbG9zICp2YWxvcmVzIGFqdXN0YWRvcyBkZWwgbW9kZWxvKiwgZXhwcmVzYWRvcyBlbiB0w6lybWlub3MgZGUgbGFzICoqbWF0cmljZXMgaW1wbMOtY2l0YXMqKiBxdWUgZWwgbW9kZWxvIGVzdGltYSBpbnRlcm5hbWVudGUuIEVuIHBhcnRpY3VsYXIsIGN1YW5kbyBzZSBhcGxpY2EgYSB1biBvYmpldG8gZGUgY2xhc2UgYGxhdmFhbmAgKGNvbW8gYENGQWApLCBlc3RhIGZ1bmNpw7NuIGRldnVlbHZlIHVuYSBsaXN0YSBxdWUgaW5jbHV5ZSBsYSAqKm1hdHJpeiBkZSBjb3ZhcmlhbnphcyBpbXBsw61jaXRhKiogZGVsIG1vZGVsbyBhanVzdGFkby4NCg0KRXMgaW1wb3J0YW50ZSBzZcOxYWxhciBxdWUsIGVuIGVsIGNvbnRleHRvIGRlIGBsYXZhYW5gLCBsYXMgZnVuY2lvbmVzIGBmaXR0ZWQoKWAgeSBgZml0dGVkLnZhbHVlcygpYCBzb24gKmVxdWl2YWxlbnRlcyBlbiBzdSBjb250ZW5pZG8qOiBhbWJhcyBkZXZ1ZWx2ZW4gbG9zIHZhbG9yZXMgYWp1c3RhZG9zIGRlbCBtb2RlbG8uIEVuIHBhcnRpY3VsYXI6DQoNCi0gYGZpdHRlZChmaXQpJGNvdmAgeSBgZml0dGVkLnZhbHVlcyhmaXQpJGNvdmAgcHJvcG9yY2lvbmFuIGxhICptaXNtYSBtYXRyaXogZGUgICBjb3ZhcmlhbnphcyBpbXBsw61jaXRhKiwgZGVub3RhZGEgcG9yIFwoe1xib2xkc3ltYm9se1xTaWdtYX19XCkuDQoNCi0gQ3VhbmRvIGVsIG1vZGVsbyBpbmNsdXllIG1lZGlhcyBvIGludGVyY2VwdG9zLCBsb3MgY29tcG9uZW50ZXMgICBgZml0dGVkKGZpdCkkbWVhbmAgeSBgZml0dGVkLnZhbHVlcyhmaXQpJG1lYW5gIGRldnVlbHZlbiBlbCAqKnZlY3RvciBkZSBtZWRpYXMgICBpbXBsw61jaXRhcyoqIGRlbCBtb2RlbG8uDQoNCkVzdGEgZXF1aXZhbGVuY2lhIGV4cGxpY2EgcG9yIHF1w6ksIGFsIHV0aWxpemFyIGBmaXR0ZWQudmFsdWVzKENGQSlgLCBzZSBvYnRpZW5lIGV4YWN0YW1lbnRlIGxhIG1pc21hIG1hdHJpeiBkZSBjb3ZhcmlhbnphcyBxdWUgY29uIGBmaXR0ZWQoQ0ZBKSRjb3ZgLg0KDQoNCg0KKipFbCBjw7NkaWdvLiAqKg0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCmZpdHRlZC52YWx1ZXMoQ0ZBKQ0KYGBgDQoNCioqRWwgb3V0cHV0LiAqKg0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCmZpdHRlZC52YWx1ZXMoQ0ZBKQ0KYGBgDQoNCg0KRXMgZGVjaXIsIHNlIG9idGllbmUgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGltcGzDrWNpdGEgZGVsIG1vZGVsbzoNCg0KXFsNClxib2xkc3ltYm9se1xTaWdtYX0NCj0NClxib2xkc3ltYm9se1xMYW1iZGF9XGJvbGRzeW1ib2x7XFBzaX1cYm9sZHN5bWJvbHtcTGFtYmRhfV5cdG9wDQorDQpcYm9sZHN5bWJvbHtcVGhldGF9DQo9DQpcYmVnaW57cG1hdHJpeH0NCjEuMzU4ICYgMC40NDggJiAwLjU5MCAmIDAuNDA4ICYgMC40NTQgJiAwLjM3OCAmIDAuMjYyICYgMC4zMDkgJiAwLjI4NCBcXA0KMC40NDggJiAxLjM4MiAmIDAuMzI3ICYgMC4yMjYgJiAwLjI1MiAmIDAuMjA5ICYgMC4xNDUgJiAwLjE3MSAmIDAuMTU3IFxcDQowLjU5MCAmIDAuMzI3ICYgMS4yNzUgJiAwLjI5OCAmIDAuMzMxICYgMC4yNzYgJiAwLjE5MSAmIDAuMjI2ICYgMC4yMDcgXFwNCjAuNDA4ICYgMC4yMjYgJiAwLjI5OCAmIDEuMzUxICYgMS4wOTAgJiAwLjkwNyAmIDAuMTczICYgMC4yMDUgJiAwLjE4OCBcXA0KMC40NTQgJiAwLjI1MiAmIDAuMzMxICYgMS4wOTAgJiAxLjY2MCAmIDEuMDEwICYgMC4xOTMgJiAwLjIyOCAmIDAuMjA5IFxcDQowLjM3OCAmIDAuMjA5ICYgMC4yNzYgJiAwLjkwNyAmIDEuMDEwICYgMS4xOTYgJiAwLjE2MSAmIDAuMTkwICYgMC4xNzQgXFwNCjAuMjYyICYgMC4xNDUgJiAwLjE5MSAmIDAuMTczICYgMC4xOTMgJiAwLjE2MSAmIDEuMTgzICYgMC40NTMgJiAwLjQxNSBcXA0KMC4zMDkgJiAwLjE3MSAmIDAuMjI2ICYgMC4yMDUgJiAwLjIyOCAmIDAuMTkwICYgMC40NTMgJiAxLjAyMiAmIDAuNDkwIFxcDQowLjI4NCAmIDAuMTU3ICYgMC4yMDcgJiAwLjE4OCAmIDAuMjA5ICYgMC4xNzQgJiAwLjQxNSAmIDAuNDkwICYgMS4wMTUNClxlbmR7cG1hdHJpeH0uDQpcXQ0KDQoqKk9ic2VydmFjacOzbiBwZWRhZ8OzZ2ljYS4qKg0KDQpFbCB1c28gZGUgYGZpdHRlZC52YWx1ZXMoKWAgZW4gYGxhdmFhbmAgbm8gZXMgZXJyw7NuZW8uIFNpbiBlbWJhcmdvLCBlcyBpbXBvcnRhbnRlIGRlc3RhY2FyIHVuYSBkaWZlcmVuY2lhIGNvbmNlcHR1YWwgY29uIG90cm9zIG1vZGVsb3MgZW4gUjoNCg0KLSBFbiBtb2RlbG9zIGRlIHJlZ3Jlc2nDs24gY2zDoXNpY29zIChwb3IgZWplbXBsbywgYGxtYCBvIGBnbG1gKSwgICBgZml0dGVkLnZhbHVlcygpYCBzdWVsZSBkZXZvbHZlciB2YWxvcmVzIGFqdXN0YWRvcyBkZWwgdmVjdG9yIHJlc3B1ZXN0YQ0KICBcKFxoYXR7eX1cKS4NCg0KLSBFbiBtb2RlbG9zIFNFTSBpbXBsZW1lbnRhZG9zIGNvbiBgbGF2YWFuYCwgYGZpdHRlZC52YWx1ZXMoKWAgZXN0w6EgZGVmaW5pZG8gY29tbyAgIHVuIG3DqXRvZG8gZXNwZWPDrWZpY28gcGFyYSBvYmpldG9zIGBsYXZhYW5gKiB5IGRldnVlbHZlIGxhcyAqKm1hdHJpY2VzICAgaW1wbMOtY2l0YXMgZGVsIG1vZGVsbyoqIChjb3ZhcmlhbnphcyB5LCBjdWFuZG8gY29ycmVzcG9uZGUsIG1lZGlhcykuDQoNClBvciBlc3RhIHJhesOzbiwgYXVucXVlIGBmaXR0ZWQoKWAgeSBgZml0dGVkLnZhbHVlcygpYCBwcm9kdWNlbiBlbCBtaXNtbyByZXN1bHRhZG8gZW4gZXN0ZSBjb250ZXh0bywgZWwgdXNvIGV4cGzDrWNpdG8gZGUgYGZpdHRlZC52YWx1ZXMoKWAgcHVlZGUgcmVzdWx0YXIgw7p0aWwgcGFyYSBlbmZhdGl6YXIgcXVlIHNlIGVzdMOhbiByZWN1cGVyYW5kbyBsb3MgKnZhbG9yZXMgYWp1c3RhZG9zIGRlbCBtb2RlbG8qLCB5IG5vIHByZWRpY2Npb25lcyBpbmRpdmlkdWFsZXMgYSBuaXZlbCBkZSBvYnNlcnZhY2nDs24uDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyBGdW5jaW9uZXMgZXNwZWNpYWxlcw0KDQojIyMgRnVuY2lvbmVzIGRlIGV4dHJhY2Npw7NuIHBhcmEgaW5zcGVjY2lvbmFyIG1vZGVsb3MgYWp1c3RhZG9zDQoNCkVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6bGF2YWFuMTkpIHNlIG11ZXN0cmEgdW5hIGxpc3RhIGRlIGZ1bmNpb25lcyBwYXJhIGluc3BlY2Npb25hciBtb2RlbG9zIGFqdXN0YWRvcy4NCg0KPGNlbnRlcj4NCmBgYHtyIGxhdmFhbjE5LCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqRnVuY2lvbmVzIGRlIGV4dHJhY2Npw7NuIHBhcmEgaW5zcGVjY2lvbmFyIG1vZGVsb3MgYWp1c3RhZG9zKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4xOS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQoNCiMjIyBPdHJhcyBmdW5jaW9uZXMgZXNwZWNpYWxlcw0KDQpFbiBsYSBGaWd1cmEgXEByZWYoZmlnOmxhdmFhbjIwKSBzZSBtdWVzdHJhIHVuYSBsaXN0YSBkZSBmdW5jaW9uZXMgcGFyYSBpbnNwZWNjaW9uYXIgbW9kZWxvcyBhanVzdGFkb3MuDQoNCjxjZW50ZXI+DQpgYGB7ciBsYXZhYW4yMCwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKk90cmFzIGZ1bmNpb25lcyBlc3BlY2lhbGVzKioiLCBvdXQud2lkdGggPSAiMTAwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJsYXZhYW4yMC5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIFTDs3BpY29zIHN1cGxlbWVudGFyaW9zIA0KDQpQYXJhIHByb2Z1bmRpemFyIGVuIGxvcyB0ZW1hcyBkZSAqKmludmFyaWFuemEgZGUgbWVkaWRhKiosIHkgZW4gcGFydGljdWxhciBlbiBsYSAqKmludmFyaWFuemEgZGUgbWVkaWFzIGxhdGVudGVzKiosIHNlIHJlY29taWVuZGEgY29uc3VsdGFyIGxvcyBzaWd1aWVudGVzIHJlY3Vyc29zLCBxdWUgYWJvcmRhbiB0YW50byBsYSB0ZW9yw61hIGNvbW8gc3UgaW1wbGVtZW50YWNpw7NuIHByw6FjdGljYS4NCg0KDQotIFRlb3LDrWE6IFtDbGljayBkZXJlY2hvIGFxdcOtXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL1JfTUlfdGVvcmlhKS4gDQoNCi0gQXBsaWNhY2nDs246IFtDbGljayBkZXJlY2hvIGFxdcOtXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL1JfTUlfYXBsaWNhY2lvbikuIA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBDYXDDrXR1bG8gRWplcmNpY2lvcyAtLT4NCg0KIyBFamVyY2ljaW9zDQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmh0dHBzOi8vbGF2YWFuLnVnZW50LmJlL3R1dG9yaWFsL2luc3BlY3QuaHRtbA0KaHR0cHM6Ly9tc3BlZWtlbmJyaW5rLmdpdGh1Yi5pby9zZGFtLXItY29tcGFuaW9uL3N0cnVjdHVyYWwtZXF1YXRpb24tbW9kZWxsaW5nLXdpdGgtbGF2YWFuLmh0bWwNCmh0dHBzOi8vcnB1YnMuY29tL0pvXy9sYXZhYW5fZWZlY3Rvc19kaXJlY3Rvcw0KaHR0cHM6Ly9zdGF0cy5vYXJjLnVjbGEuZWR1L3Ivc2VtaW5hcnMvcnNlbS8NCmBgYA0KDQoNCjwhLS0gJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCjwhLS0gU2VwYXJhZG9yIC0tPg0KDQojIyMgRWplcmNpY2lvIDENCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiMgRXMgdW4gZGF0YSBzZXRzIA0KI2h0dHBzOi8vYmxvZ3MuYmF5bG9yLmVkdS9ybGF0ZW50dmFyaWFibGUvc2FtcGxlLXBhZ2UvZGF0YS8NCiMNCiNCZWF1amVhbiwgZWplcmNpY2lvIDIuMSwgcGFnaW5hIDM0LiBTb2x1Y2lvbiBlbiBwYWdpbmEgMTcxDQpgYGANCg0KDQpDb25zaWRlcmUgZWwgc2lndWllbnRlIGNvbmp1bnRvIGRlIGRhdG9zIHF1ZSBjb250aWVuZSAxMDAgb2JzZXJ2YWNpb25lcyB5IDIgdmFyaWFibGVzOiANCiAgDQogICsgRWwgbsO6bWVybyBkZSBob3JhcyBxdWUgc2Ugc3VlbGVuIGRlZGljYXIgYSBsYXMgbWF0ZW3DoXRpY2FzIChgTWF0aEhvbWV3b3JrYCkNCiAgDQogICsgTGEgcHVudHVhY2nDs24gZW4gdW4gdGVzdCBlc3RhbmRhcml6YWRvIGRlIHJlbmRpbWllbnRvIGRlIG1hdGVtw6F0aWNhIChgTWF0aEFjaGlldmVtZW50YCkuDQoNCmBgYHtyfQ0KIyBDcmVhciBlbCBkYXRhZnJhbWUgZW4gUg0KTWF0aEhtd2suZGF0YSA8LSBkYXRhLmZyYW1lKA0KICBNYXRoSG9tZXdvcmsgPSBjKDIsIDAsIDQsIDAsIDIsIDAsIDEsIDAsIDMsIDAsIDQsIDcsIDMsIDEsIDEsIDAsIDMsIDAsIDEsIDMsIDMsIDAsIDIsIDAsIDEsIDQsIDEsIDQsIDMsIDEsIDEsIDMsIDMsIDUsIDIsIDUsIDEsIDMsIDIsIDIsIDAsIDIsIDUsIDAsIDIsIDIsIDEsIDIsIDEsIDQsIDAsIDAsIDQsIDEwLCAxLCAxLCAyLCAyLCAxLCAyLCAyLCAxLCAyLCAyLCAzLCAyLCAwLCAwLCAzLCAyLCA1LCA1LCAxLCAwLCAwLCAyLCAyLCAzLCAwLCAyLCA0LCAwLCAzLCAxLCAyLCAzLCA0LCA0LCA0LCAyLCAxLCA2LCAzLCA1LCA2LCA0LCAzLCAyLCAyLCAxKSwNCiAgTWF0aEFjaGlldmVtZW50ID0gYyg1NCwgNTMsIDUzLCA1NiwgNTksIDMwLCA0OSwgNTQsIDM3LCA0OSwgNTUsIDUwLCA0NSwgNDQsIDYwLCAzNiwgNTMsIDIyLCA1NiwgNTQsIDc1LCAzNywgNDIsIDY0LCA2MSwgNTcsIDUzLCA2MywgNzUsIDUzLCA1NCwgNjQsIDU0LCA1OSwgNDgsIDY1LCA1NywgNDgsIDU0LCA2MiwgNTMsIDYxLCA1NiwgMzIsIDUwLCA0NCwgNjIsIDM5LCA2MSwgNTEsIDM2LCAzOCwgMzgsIDU5LCA0NiwgNTUsIDQ4LCA1NCwgNDEsIDYxLCA1MiwgNjMsIDI1LCA2NCwgNzIsIDY1LCA0MSwgMjksIDM5LCA3MCwgNjgsIDM4LCA1OSwgMjksIDQ5LCAzOSwgNDUsIDc0LCA0MSwgNTMsIDcxLCA0MSwgNjMsIDM0LCA2MSwgNTEsIDYyLCA1NSwgNjQsIDQ3LCA0OCwgNDcsIDQ0LCA1MiwgNTAsIDQ4LCA1OCwgMzksIDQxLCA1MSkNCikNCiMgVmVyIGVsIGRhdGFmcmFtZQ0KaGVhZChNYXRoSG13ay5kYXRhKQ0KYGBgDQoNCkxhIHByZWd1bnRhIGRlIGludGVyw6lzIGVzOiAqwr9FbCB0aWVtcG8gZGVkaWNhZG8gYSBsb3MgZGViZXJlcyBkZSBtYXRlbcOhdGljYXMgZXN0w6EgZGlyZWN0YW1lbnRlIHJlbGFjaW9uYWRvIGNvbiBlbCByZW5kaW1pZW50byBlbiBtYXRlbcOhdGljYXM/Kg0KDQooYSkgRGlidWplIHVuIGRpYWdyYW1hIGRlIGRpc3BlcnNpw7NuIGVudHJlIGFtYmFzIHZhcmlhYmxlcy4gDQoNCihiKSBSZWFsaWNlIHVuYSByZWdyZXNpw7NuIHTDrXBpY2EgZXN0YW5kYXJpemFkbyB5IG5vIGVzdGFuZGFyaXphZG8sICB1dGlsaXphbmRvIGxhIGZ1bmNpw7NuIGBsbWAuICpTdWdlcmVuY2lhKjogUGFyYSBsYSBubyBlc3RhbmRhcml6YWRhIGFwbGlxdWUgbGEgZnVuY2nDs24gYHNjYWxlYCBhIGFtYm9zIGNvbmp1bnRvcyBkZSBkYXRvcyB5IGhhZ2EgbGEgcmVncmVzacOzbi4gDQoNCihjKSBEaWJ1amUgdW4gcGF0aCBtb2RlbCBlc3RhbmRhcml6YWRvIHkgbm8gZXN0YW5kYXJpemFkbyBkZSBsYSByZWdyZXNpw7NuLiANCg0KKGQpIFJlYWxpY2UgZWwgYW7DoWxpc2lzIGNvbW8gdW4gcGF0aCBtb2RlbCBlbiBgbGF2YWFuYCB1dGlsaXphbmRvIGxhIGZ1bmNpw7NuIGBzZW1gLiBPYnRlbmdhIHRhbnRvIGxvcyBjb2VmaWNpZW50ZXMgZXN0YW5kYXJpemFkb3MgY29tbyBsb3Mgbm8gZXN0YW5kYXJpemFkb3MuICpTdWdlcmVuY2lhKjogUGFyYSBubyBlc3RhbmRhcml6YWRvIHVzZSBlbCBhcmd1bWVudG8gYG1lYW5zdHJ1Y3R1cmUgPSBUUlVFYC4gDQoNCg0KKGUpIMK/Q8OzbW8gc2UgcmVsYWNpb25hbiBsb3MgcmVzdWx0YWRvcyBkZSBsb3MgaW5jaXNvcyAoYikgeSAoZCk/DQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCiNFeGVyY2lzZSAyLjEuYg0KIyB1bnN0YW5kYXJkaXplZCByZWdyZXNzaW9uDQptYXRoLmxtIDwtIGxtKE1hdGhBY2hpZXZlbWVudCB+IE1hdGhIb21ld29yaywgZGF0YSA9IE1hdGhIbXdrLmRhdGEpDQpzdW1tYXJ5KG1hdGgubG0pDQojIHN0YW5kYXJkaXplZCByZWdyZXNzaW9uDQptYXRoMi5sbSA8LSBsbShzY2FsZShNYXRoQWNoaWV2ZW1lbnQpIH4gc2NhbGUoTWF0aEhvbWV3b3JrKSwgZGF0YSA9IE1hdGhIbXdrLmRhdGEpDQpzdW1tYXJ5KG1hdGgyLmxtKQ0KDQojRXhlcmNpc2UgMi4xLmMNCiNUaGUgcGF0aCBtb2RlbHMgYXJlIHNob3duIGluIEZpZ3VyZSBDLjEuDQoNCiNFeGVyY2lzZSAyLjEuZA0KIyBwYXRoIG1vZGVsDQpsaWJyYXJ5KGxhdmFhbikNCm1hdGgubW9kZWwgPC0gJw0KTWF0aEFjaGlldmVtZW50IH4gTWF0aEhvbWV3b3JrDQonDQojIHVuc3RhbmRhcmRpemVkIHJlc3VsdHMgd2l0aCBhbiBpbnRlcmNlcHQNCm1hdGguZml0IDwtIHNlbShtYXRoLm1vZGVsLCBkYXRhID0gTWF0aEhtd2suZGF0YSwgbWVhbnN0cnVjdHVyZSA9IFRSVUUpDQpzdW1tYXJ5KG1hdGguZml0KQ0KDQojIHN0YW5kYXJkaXplZCByZXN1bHRzIHdpdGhvdXQgYW4gaW50ZXJjZXB0IA0KIyAoc3RhbmRhcmRpemVkIHJlc3VsdHMgYXJlIGluIHRoZSBTdGQuYWxsIGNvbHVtbikNCm1hdGgyLmZpdCA8LSBzZW0obWF0aC5tb2RlbCwgZGF0YSA9IE1hdGhIbXdrLmRhdGEpDQpzdW1tYXJ5KG1hdGgyLmZpdCwgc3RhbmRhcmRpemVkID0gVFJVRSkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyAyDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojaHR0cHM6Ly9ibG9ncy5iYXlsb3IuZWR1L3JsYXRlbnR2YXJpYWJsZS9zYW1wbGUtcGFnZS9kYXRhLw0KIw0KI0JlYXVqZWFuLCBlamVyY2ljaW8gMi4yLCBwYWdpbmEgMzQuIFNvbHVjaW9uIGVuIHBhZ2luYSAxNzINCmBgYA0KDQpQYWdlIHkgS2VpdGggKDE5ODEpIHV0aWxpemFyb24gZW5jdWVzdGFkb3MgZGUgbG9zIGRhdG9zIGRlIDE5ODAgSGlnaCBTY2hvb2wgYW5kIEJleW9uZCBwYXJhIGludmVzdGlnYXIgbGEgc2lndWllbnRlIHByZWd1bnRhOiAqwr9DdcOhbCBlcyBsYSByZWxhY2nDs24gZW50cmUgZWwgdGlwbyBkZSBlc2N1ZWxhIHkgZWwgcmVuZGltaWVudG8gYWNhZMOpbWljbz8qIExvcyBkYXRvcyBhcGFyZWNlbiBlbiBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwMkV4MmEpIGVuIGZvcm1hIGRlIG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzLiBFbiBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwMkV4MmIpIHNlIG11ZXN0cmEgdW4gcGF0aCBtb2RlbCBwYXJhIGxvcyBhbsOhbGlzaXMuIA0KDQoNCkVsIGPDs2RpZ28gUiBwYXJhIGxhIG1hdHJpeiBlczogDQoNCmBgYHtyfQ0KbGlicmFyeShsYXZhYW4pDQpwcml2U2Nob29sLmNvciA8LSBjKDEsIDAuMTc4LCAwLjIzLCAwLjEwNiwgMC4xOTUsIDEsIDAuMzI3LCAwLjI0NSwgMC4zNTYsIDEsIDAuMTgzLCAwLjcyMSwgMSwgMC4xNzgsIDEpDQpwcml2U2Nob29sLmNvciA8LSBsYXZfbWF0cml4X3VwcGVyMmZ1bGwocHJpdlNjaG9vbC5jb3IpDQojcHJpdlNjaG9vbC5jb3IgPC0gbGF2X21hdHJpeF9sb3dlcjJmdWxsKHByaXZTY2hvb2wuY29yKQ0KZGltbmFtZXMocHJpdlNjaG9vbC5jb3IpIDwtIGxpc3QoYygiUmFjZSIsICJTRVMiLCAiQ29nQWJpbCIsICJTY2hUeXAiLCAiQWNhZEFjaCIpLCBjKCJSYWNlIiwgIlNFUyIsICJDb2dBYmlsIiwgIlNjaFR5cCIsICJBY2FkQWNoIikpDQpwcml2U2Nob29sLmNvcg0KYGBgDQoNCjxjZW50ZXI+DQpgYGB7ciBCZWF1amVhbkNhcDJFeDJhLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqQ29ycmVsYWNpb25lcyAobiA9IDE4LDA1OCkqKiIsIG91dC53aWR0aCA9ICI4MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQmVhdWplYW5DYXAyRXgyYS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQoNCg0KRWwgcGF0aCBtb2RlbCBlczogDQoNCjxjZW50ZXI+DQpgYGB7ciBCZWF1amVhbkNhcDJFeDJiLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqUGF0aCBtb2RlbCoqIiwgb3V0LndpZHRoID0gIjgwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDJFeDJiLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCihhKSBDcmVhciBlbCBtb2RlbG8gZGUgdHJheWVjdG9yaWFzIHV0aWxpemFuZG8gYGxhdmFhbmAuIEFzZWfDunJlc2UgZGUgZXRpcXVldGFyIGxvcyBtaXNtb3MgcGFyw6FtZXRyb3MgcXVlIGVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6QmVhdWplYW5DYXAyRXgyYikuDQoNCihiKSBSZWFsaXphciBlbCBhbsOhbGlzaXMgZGUgcGF0aCBtb2RlbCBjb3JyZXNwb25kaWVudGUuIEludGVycHJldGUgdG9kb3MgbG9zIHJlc3VsdGFkb3MgcG9zaWJsZXMuDQoNCihjKSDCv0N1w6FsIGVzIGxhIHJlbGFjacOzbiBlbnRyZSBlbCB0aXBvIGRlIGVzY3VlbGEgeSBlbCByZW5kaW1pZW50byBhY2Fkw6ltaWNvIChlcyBkZWNpciwNCmNhbWlubyBqKT8NCg0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQojRXhlcmNpc2UgMi4yLmENCmZ1bGwubW9kZWwgPC0gJw0KQWNhZEFjaCB+IGoqU2NoVHlwICsgZypTRVMgKyBkKlJhY2UgKyBpKkNvZ0FiaWwNClNjaFR5cCB+IGYqU0VTICsgYipSYWNlICsgaCpDb2dBYmlsDQpDb2dBYmlsIH4gZSpTRVMgKyBjKlJhY2UNClNFUyB+IGEqUmFjZQ0KJw0KDQojRXhlcmNpc2UgMi4yLmINCmZ1bGwuZml0IDwtIHNlbShmdWxsLm1vZGVsLCBzYW1wbGUuY292PXByaXZTY2hvb2wuY29yLCBzYW1wbGUubm9icz0xODA1OCkNCnN1bW1hcnkoZnVsbC5maXQpDQoNCiNFeGVyY2lzZSAyLjIuYw0KcGFyYW1ldGVyRXN0aW1hdGVzKGZ1bGwuZml0KQ0KDQojRWwgY2FtaW5vIGogdGllbmUgdW4gdmFsb3IgZGUgMCwwMjIuIERhZG8gcXVlIGxhIGVudHJhZGEgZXJhIHVuYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcywgZXN0byBpbmRpY2EgcXVlLCBwb3IgdMOpcm1pbm8gbWVkaW8sIGxvcyByZXN1bHRhZG9zIGFjYWTDqW1pY29zIGRlIGxhcyBlc2N1ZWxhcyBwcml2YWRhcyBzb24gYXByb3hpbWFkYW1lbnRlIDAsMDIyIGRlc3ZpYWNpb25lcyBlc3TDoW5kYXIgbcOhcyBhbHRvcyBxdWUgbG9zIGRlIGxhcyBlc2N1ZWxhcyBww7pibGljYXMuDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyAzDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojaHR0cHM6Ly9ibG9ncy5iYXlsb3IuZWR1L3JsYXRlbnR2YXJpYWJsZS9zYW1wbGUtcGFnZS9kYXRhLw0KIw0KI0JlYXVqZWFuLCBlamVyY2ljaW8gMi4zLCBwYWdpbmEgMzQuIFNvbHVjaW9uIGVuIHBhZ2luYSAxNzINCmBgYA0KDQpNYWNLaW5ub24gKDIwMDgsIHAuIDExMykgcHJvcG9yY2lvbmEgdW4gY29uanVudG8gZGUgZGF0b3MgZGUgdW4gZXN0dWRpbyBoaXBvdMOpdGljbyBzb2JyZSBsYXMgZXhwZWN0YXRpdmFzIGRlIGxvcyBwcm9mZXNvcmVzIHJlc3BlY3RvIGFsIHJlbmRpbWllbnRvIGRlIGxvcyBhbHVtbm9zLg0KeSBlbCByZW5kaW1pZW50byBkZSBsb3MgYWx1bW5vcy4gU3UgbW9kZWxvIGRlIHRyYXllY3RvcmlhIHNlIG11ZXN0cmEgZW4gbGEgRmlndXJhIEZpZ3VyYSBcQHJlZihmaWc6QmVhdWplYW5DYXAyRXgzYSkgIHkgbGFzIGNvdmFyaWFuemFzIGRlbCBtb2RlbG8gc2UgaW5kaWNhbiBlbiBsYSBGaWd1cmEgIFxAcmVmKGZpZzpCZWF1amVhbkNhcDJFeDNiKS4NCg0KRWwgcGF0aCBtb2RlbCBlczoNCg0KPGNlbnRlcj4NCmBgYHtyIEJlYXVqZWFuQ2FwMkV4M2EsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipQYXRoIG1vZGVsKioiLCBvdXQud2lkdGggPSAiODAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwMkV4M2EucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KRWwgY8OzZGlnbyBSIHBhcmEgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVzOiANCg0KYGBge3J9DQpsaWJyYXJ5KGxhdmFhbikNCnByaXZTY2hvb2wuY29yIDwtIGMoMSwgMC4xNzgsIDAuMjMsIDAuMTA2LCAwLjE5NSwgMSwgMC4zMjcsIDAuMjQ1LCAwLjM1NiwgMSwgMC4xODMsIDAuNzIxLCAxLCAwLjE3OCwgMSkNCnByaXZTY2hvb2wuY29yIDwtIGxhdl9tYXRyaXhfdXBwZXIyZnVsbChwcml2U2Nob29sLmNvcikNCiNwcml2U2Nob29sLmNvciA8LSBsYXZfbWF0cml4X2xvd2VyMmZ1bGwocHJpdlNjaG9vbC5jb3IpDQpkaW1uYW1lcyhwcml2U2Nob29sLmNvcikgPC0gbGlzdChjKCJSYWNlIiwgIlNFUyIsICJDb2dBYmlsIiwgIlNjaFR5cCIsICJBY2FkQWNoIiksIGMoIlJhY2UiLCAiU0VTIiwgIkNvZ0FiaWwiLCAiU2NoVHlwIiwgIkFjYWRBY2giKSkNCnByaXZTY2hvb2wuY29yDQpgYGANCg0KDQoNCjxjZW50ZXI+DQpgYGB7ciBCZWF1amVhbkNhcDJFeDNiLCBlY2hvPUZBTFNFLCBmaWcuY2FwID0gIioqQ292YXJpYW56YXMgKG4gPSA0MCkqKiIsIG91dC53aWR0aCA9ICIxMDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwMkV4M2IucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KKGEpIEludHJvZHV6Y2EgbGFzIGNvdmFyaWFuemFzIGVuIFIuDQoNCihiKSBFc2NyaWJhIGxhIHNpbnRheGlzIGRlbCBtb2RlbG8uIFV0aWxpY2UgZWwgb3BlcmFkb3IgYDo9YCBwYXJhIGRlZmluaXIgbG9zIGRvcyBlZmVjdG9zIGluZGlyZWN0b3MgZGUgbGFzIGV4cGVjdGF0aXZhcyBkZWwgcHJvZmVzb3Igc29icmUgZWwgcmVuZGltaWVudG8gZGVsIGFsdW1ubzogYChhMSkoYjEpYCB5IGAoYTIpKGIyKWAuIA0KDQooYykgwr9DdcOhbGVzIHNvbiBsb3MgZWZlY3RvcyBpbmRpcmVjdG9zPw0KDQooYykgUmVhbGljZSBlbCBhbsOhbGlzaXMgZGUgcGF0aCBtb2RlbCBjb3JyZXNwb25kaWVudGUuIA0KDQooZCkgSW50ZXJwcmV0ZSB0b2RvcyBsb3MgcmVzdWx0YWRvcyBwb3NpYmxlcy4NCg0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGxhdmFhbikNCg0KI0V4ZXJjaXNlIDIuMy5hDQptYWNraW5ub24uY292IDwtIGxhdl9tYXRyaXhfbG93ZXIyZnVsbChjKDg0Ljg1LDcxLjI4LDE0MC4zNCwxOC44MywtNi4yNSw3Mi45Miw2MC4wNSw4NC41NCwzNy4xOCwgMTM5LjQ4KSkNCnJvd25hbWVzKG1hY2tpbm5vbi5jb3YpIDwtIGNvbG5hbWVzKG1hY2tpbm5vbi5jb3YpIDwtDQpjKCJUZWFjaEV4cCIsICJTb2NDbGltIiwgIk1hdENvdiIsICJTdEFjaCIpDQoNCiNFeGVyY2lzZSAyLjMuYg0KbWFja2lubm9uLm1vZGVsIDwtICcNClN0QWNoIH4gYjEqU29jQ2xpbSArIGIyKk1hdENvdiArIGMqVGVhY2hFeHANCk1hdENvdiB+IGEyKlRlYWNoRXhwDQpTb2NDbGltIH4gYTEqVGVhY2hFeHANCmluZDEgOj0gYTEqYjENCmluZDIgOj0gYTIqYjINCicNCiNFeGVyY2lzZSAyLjMuYw0KbWFja2lubm9uLmZpdCA8LSBzZW0obWFja2lubm9uLm1vZGVsLCBzYW1wbGUuY292ID0gbWFja2lubm9uLmNvdiwgc2FtcGxlLm5vYnMgPSA0MCkNCnN1bW1hcnkobWFja2lubm9uLmZpdCwgc3RhbmRhcmRpemVkID0gVFJVRSkNCg0KI0VsIGVmZWN0byBpbmRpcmVjdG8gYSB0cmF2w6lzIGRlbCBjbGltYSBzb2NpYWwgZXMgZGUgMCw0NzguIEVsIGVmZWN0byBpbmRpcmVjdG8gYSB0cmF2w6lzIGRlbCBtYXRlcmlhbCBjdWJpZXJ0byBlcyBkZSAwLDExOC4NCiMNCiNFZmVjdG8gaW5kaXJlY3RvIGEgdHJhdsOpcyBkZWwgY2xpbWEgc29jaWFsIChTb2NDbGltKToNCg0KI0VsIGVmZWN0byBpbmRpcmVjdG8gYSB0cmF2w6lzIGRlbCBjbGltYSBzb2NpYWwgZXMgZGUgMC40NzguIEVzdG8gc2lnbmlmaWNhIHF1ZSBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybyB0aWVuZSB1biBpbXBhY3RvIHBvc2l0aXZvIHNpZ25pZmljYXRpdm8gZW4gZWwgY2xpbWEgc29jaWFsIGRlIGxhIGNsYXNlLCB5IGVzdGUgY2xpbWEgc29jaWFsLCBhIHN1IHZleiwgbWVqb3JhIHNpZ25pZmljYXRpdmFtZW50ZSBlbCBsb2dybyBkZWwgZXN0dWRpYW50ZS4gRW4gdMOpcm1pbm9zIG3DoXMgY29uY3JldG9zLCBwb3IgY2FkYSB1bmlkYWQgZGUgYXVtZW50byBlbiBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybywgaGF5IHVuIGluY3JlbWVudG8gZXNwZXJhZG8gZGUgMC40NzggdW5pZGFkZXMgZW4gZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUsIG1lZGlhZG8gcG9yIGVsIGNsaW1hIHNvY2lhbC4NCg0KI0VmZWN0byBpbmRpcmVjdG8gYSB0cmF2w6lzIGRlbCBtYXRlcmlhbCBjdWJpZXJ0byAoTWF0Q292KToNCg0KI0VsIGVmZWN0byBpbmRpcmVjdG8gYSB0cmF2w6lzIGRlbCBtYXRlcmlhbCBjdWJpZXJ0byBlcyBkZSAwLjExOC4gRXN0byBzdWdpZXJlIHF1ZSBsYSBleHBlcmllbmNpYSBkZWwgbWFlc3RybyB0YW1iacOpbiBjb250cmlidXllIGEgbGEgY2FudGlkYWQgZGUgbWF0ZXJpYWwgY3ViaWVydG8gZW4gY2xhc2UsIHkgZXN0ZSBtYXRlcmlhbCBjdWJpZXJ0byBhZGljaW9uYWxtZW50ZSBtZWpvcmEgZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUuIEFzw60sIHBvciBjYWRhIHVuaWRhZCBkZSBhdW1lbnRvIGVuIGxhIGV4cGVyaWVuY2lhIGRlbCBtYWVzdHJvLCBoYXkgdW4gaW5jcmVtZW50byBlc3BlcmFkbyBkZSAwLjExOCB1bmlkYWRlcyBlbiBlbCBsb2dybyBkZWwgZXN0dWRpYW50ZSwgbWVkaWFkbyBwb3IgbGEgY2FudGlkYWQgZGUgbWF0ZXJpYWwgY3ViaWVydG8uDQoNCiNJbnRlcnByZXRhY2nDs24gZGVsIG1vZGVsbyBjb21wbGV0bzoNCg0KI0VsIG1vZGVsbyBlc3BlY2lmaWNhIHF1ZSBlbCBsb2dybyBkZWwgZXN0dWRpYW50ZSAoU3RBY2gpIGVzIGRpcmVjdGFtZW50ZSBpbmZsdWVuY2lhZG8gcG9yIGVsIGNsaW1hIHNvY2lhbCAoU29jQ2xpbSksIGxhIGNhbnRpZGFkIGRlIG1hdGVyaWFsIGN1YmllcnRvIChNYXRDb3YpIHkgbGEgZXhwZXJpZW5jaWEgZGVsIG1hZXN0cm8gKFRlYWNoRXhwKS4gQWRlbcOhcywgbGEgZXhwZXJpZW5jaWEgZGVsIG1hZXN0cm8gdGFtYmnDqW4gaW5mbHV5ZSBpbmRpcmVjdGFtZW50ZSBlbiBlbCBsb2dybyBkZWwgZXN0dWRpYW50ZSBhIHRyYXbDqXMgZGVsIGNsaW1hIHNvY2lhbCB5IGVsIG1hdGVyaWFsIGN1YmllcnRvLg0KDQojTG9zIGVmZWN0b3MgaW5kaXJlY3RvcyBwcm9wb3JjaW9uYW4gdW4gZW50ZW5kaW1pZW50byBtw6FzIGNvbXBsZXRvIGRlIGPDs21vIGxhIGV4cGVyaWVuY2lhIGRlbCBtYWVzdHJvIGltcGFjdGEgZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUsIGRlc3RhY2FuZG8gbGEgaW1wb3J0YW5jaWEgZGUgY3JlYXIgdW4gYnVlbiBjbGltYSBzb2NpYWwgeSBjdWJyaXIgYWRlY3VhZGFtZW50ZSBlbCBtYXRlcmlhbC4NCg0KI0VuIHJlc3VtZW4sIGxhIGV4cGVyaWVuY2lhIGRlbCBtYWVzdHJvIG5vIHNvbG8gdGllbmUgdW4gZWZlY3RvIGRpcmVjdG8gc29icmUgZWwgbG9ncm8gZGVsIGVzdHVkaWFudGUsIHNpbm8gcXVlIHRhbWJpw6luIHRpZW5lIGVmZWN0b3MgaW5kaXJlY3RvcyBzaWduaWZpY2F0aXZvcyBhIHRyYXbDqXMgZGUgc3UgaW5mbHVlbmNpYSBlbiBlbCBjbGltYSBzb2NpYWwgZGUgbGEgY2xhc2UgeSBsYSBjYW50aWRhZCBkZSBtYXRlcmlhbCBjdWJpZXJ0by4gRXN0b3MgaGFsbGF6Z29zIHN1YnJheWFuIGxhIGltcG9ydGFuY2lhIGRlIGxhIGV4cGVyaWVuY2lhIGRlbCBtYWVzdHJvIGVuIG1lam9yYXIgZWwgYW1iaWVudGUgZGUgYXByZW5kaXphamUgeSBlbCBjb250ZW5pZG8gZWR1Y2F0aXZvLCBsbyBxdWUgZW4gw7psdGltYSBpbnN0YW5jaWEgY29uZHVjZSBhIG1lam9yZXMgcmVzdWx0YWRvcyBhY2Fkw6ltaWNvcyBwYXJhIGxvcyBlc3R1ZGlhbnRlcy4NCg0KYGBgDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gNA0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KI2h0dHBzOi8vYmxvZ3MuYmF5bG9yLmVkdS9ybGF0ZW50dmFyaWFibGUvc2FtcGxlLXBhZ2UvZGF0YS8NCiMNCiNCZWF1amVhbiwgZWplcmNpY2lvIDMuMSwgcGFnaW5hIDUyLiBTb2x1Y2lvbiBlbiBwYWdpbmEgMTczDQpgYGANCg0KDQpVbXN0YXR0ZC1NZXllciwgSmFua2UgeSBCZWF1amVhbiAoMjAxMykgbWlkaWVyb24gbGEgc2FsdWQgcHNpY29zb2NpYWwgZGVmaWNpZW50ZSBjb21vIHVuIG1vZGVsbyBkZSBmYWN0b3Igw7puaWNvIHV0aWxpemFuZG8gdHJlcyBmYWNldGFzIGRlIMOtdGVtcyBkZSB1biBjdWVzdGlvbmFyaW8gZGUgZGVwcmVzacOzbiB5IHVuYSBtZWRpZGEgZGUgbGEgYWN0aXZpZGFkIHNvY2lhbC4gTGEgbWF0cml6IGRlIGNvdmFyaWFuemEgc2UgbXVlc3RyYSBlbiBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwM0V4MSkuDQoNCg0KPGNlbnRlcj4NCmBgYHtyIEJlYXVqZWFuQ2FwM0V4MSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKkNvdmFyaWFuemFzIChuID0gNjA1MykqKiIsIG91dC53aWR0aCA9ICIxMDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwM0V4MS5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQpBZGVtw6FzLCBjb25zaWRlcmUgZWwgc2lndWllbnRlIG1vZGVsby4NCg0KKipNb2RlbG8gMS4qKiANCg0KYGBge3J9DQptYXJrZXIubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBEZXAuMSArIERlcC4yICsgRGVwLjMgKyBTb2NBY3Rpdml0eQ0KJw0KYGBgDQoNClJlYWxpemFyIGxvcyBzaWd1aWVudGVzIGluY2lzb3M6DQoNCmEpIEludHJvZHV6Y2EgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVuIFIuDQoNCmIpIENvbiBsYSBmdW5jacOzbiBgY2ZhYCBkZSBgbGF2YWFuYCAoc2luIGFncmVnYXIgZWwgYXJndW1lbnRvIGBzdGQubHY9Li4uYCkgeSB1dGlsaXphbmRvIHZhcmlhYmxlcyBsYXRlbnRlcyBubyBlc3RhbmRhcml6YWRhcywgYWp1c3RlIGVsIG1vZGVsbyAxLiBTdWdlcmVuY2lhOiB1c2UgZWwgY8OzZGlnbyBoYWJpdHVhbCBkZSBgY2ZhYC4NCg0KDQpjKSBDb24gbGEgZnVuY2nDs24gYGNmYWAgZGUgYGxhdmFhbmAgKGFncmVnYW5kbyBlbCBhcmd1bWVudG8gYHN0ZC5sdj1GQUxTRWApIHkgdXRpbGl6YW5kbyAgdmFyaWFibGVzIGxhdGVudGVzIG5vIGVzdGFuZGFyaXphZGFzLCBhanVzdGUgZWwgbW9kZWxvIDEuICBTdWdlcmVuY2lhOiB1c2UgZWwgY8OzZGlnbyBoYWJpdHVhbCBkZSBgY2ZhYCBjb24gZWwgYXJndW1lbnRvIG1lbmNpb25hZG8uDQoNCmQpIENvbiBsYSBmdW5jacOzbiBgY2ZhYCBkZSBgbGF2YWFuYCAgeSB1dGlsaXphbmRvIHZhcmlhYmxlcyBsYXRlbnRlcyBlc3RhbmRhcml6YWRhcywgYWp1c3RlIGVsIG1vZGVsbyAxLiBTdWdlcmVuY2lhOiB1c2UgZWwgY8OzZGlnbyBoYWJpdHVhbCBkZSBgY2ZhYCBhZ3JlZ2FuZG8gZWwgYXJndW1lbnRvIGBzdGQubHY9VFJVRWAuDQoNCmUpIFZlcmlmaXF1ZSBxdWUgbG9zIHZhbG9yZXMgcmVzdWx0YW50ZXMgZGUgJFxjaGleMiQgeSAkZGYkIHNvbiBpZMOpbnRpY29zIHBhcmEgdG9kb3MgbG9zIG3DqXRvZG9zLiBJbnZlc3RpZ3VlIGxhIHJhesOzbi4gDQoNCmYpIMK/WSBlbCBuw7ptZXJvIGRlIHBhcsOhbWV0cm9zIGRlbCBtb2RlbD8gwr9Tb24gaWd1YWxlcyBlbiB0b2RvcyBsb3MgbW9kZWxvcz8gSWRlbnRpZsOtcXVlbG9zIGVuIGNhZGEgdW5vIGRlIGVsbG9zLg0KDQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgZWNobz1GQUxTRX0NCmxpYnJhcnkobGF2YWFuKQ0KDQojRXhlcmNpc2UgMy4xLmENCnBzeWNoU29jLmNvdiA8LSBjKDAuNzcsIDAuMzgsIDAuNjUsIDAuMzksIDAuMzksIDAuNjIsIC0wLjI1LCAtMC4zMiwgLTAuMjcsIDYuMDkpDQpwc3ljaFNvYy5jb3YgPC0gbGF2X21hdHJpeF9sb3dlcjJmdWxsKHBzeWNoU29jLmNvdikNCnJvd25hbWVzKHBzeWNoU29jLmNvdikgPC0gY29sbmFtZXMocHN5Y2hTb2MuY292KSA8LSBjKCJEZXAuMSIsICJEZXAuMiIsICJEZXAuMyIsICJTb2NBY3Rpdml0eSIpDQoNCiNFeGVyY2lzZSAzLjEuYg0KIyBtYXJrZXIgdmFyaWFibGUNCm1hcmtlci5tb2RlbCA8LSAnDQpQc3ljaFNvY0xWID1+IERlcC4xICsgRGVwLjIgKyBEZXAuMyArIFNvY0FjdGl2aXR5DQonDQptYXJrZXIuZml0QSA8LSBjZmEobWFya2VyLm1vZGVsLCBzYW1wbGUuY292PXBzeWNoU29jLmNvdiwgc2FtcGxlLm5vYnM9NjA1MykNCnN1bW1hcnkobWFya2VyLmZpdEEpDQoNCiNFeGVyY2lzZSAzLjEuYw0KIyBtYXJrZXIgdmFyaWFibGUNCg0KbWFya2VyLmZpdEI8LSBjZmEobWFya2VyLm1vZGVsLCBzdGQubHY9RkFMU0UsIHNhbXBsZS5jb3Y9cHN5Y2hTb2MuY292LCBzYW1wbGUubm9icz02MDUzKQ0Kc3VtbWFyeShtYXJrZXIuZml0QikNCg0KDQojRXhlcmNpc2UgMy4xLmQNCiMgc3RhbmRhcmRpemVkIGxhdGVudCB2YXJpYWJsZQ0KIyBtZXRob2QgMQ0Kc3RkTFYuZml0MSA8LSBjZmEobWFya2VyLm1vZGVsLCBzYW1wbGUuY292PXBzeWNoU29jLmNvdiwgc3RkLmx2PVRSVUUsIHNhbXBsZS5ub2JzPTYwNTMpDQpzdW1tYXJ5KHN0ZExWLmZpdDEpDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyA1DQoNCg0KYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCiNodHRwczovL2Jsb2dzLmJheWxvci5lZHUvcmxhdGVudHZhcmlhYmxlL3NhbXBsZS1wYWdlL2RhdGEvDQojDQojQmVhdWplYW4sIGVqZXJjaWNpbyAzLjEsIHBhZ2luYSA1Mi4gU29sdWNpb24gZW4gcGFnaW5hIDE3Mw0KYGBgDQoNCioqQ29udGludWFjacOzbiBkZWwgZWplcmNpY2lvIDQqKi4gQ29uc2lkZXJlIGxhIHNpdHVhY2nDs24gZGVsIGVqZXJjaWNpbyA0IHkgbG9zIHNpZ3VpZW50ZXMgZG9zIG1vZGVsb3MgKG1vZGVsb3MgMiB5IDMpLg0KDQoqKk1vZGVsbyAyLioqIA0KDQpPYnNlcnZlIHF1ZSwgZW4gZXN0ZSBtb2RlbG8sIHNlIHV0aWxpemEgYERlcHJlc3Npb24gMWAgY29tbyB2YXJpYWJsZSBtYXJjYWRvcmEuDQoNCmBgYHtyfQ0Kc3RkTFYubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBOQSpEZXAuMSArIERlcC4xICsgRGVwLjIgKyBEZXAuMyArIFNvY0FjdGl2aXR5DQpQc3ljaFNvY0xWfn4xKlBzeWNoU29jTFYNCicNCmBgYA0KDQoqKk1vZGVsbyAzLioqIA0KDQpPYnNlcnZlIHF1ZSwgZW4gZXN0ZSBtb2RlbG8sIHNlIHV0aWxpemE6DQogIA0KICArIENvbW8gdmFyaWFibGUgbWFyY2Fkb3JhIGEgYERlcHJlc3Npb24gMWAuIA0KICANCiAgKyBFbCBtw6l0b2RvIGRlIGxhIGNvZGlmaWNhY2nDs24gZGUgZWZlY3RvcyAocG9ycXVlIGxhIHN1bWEgZGUgbGFzIGNhcmdhcyBmYWN0b3JpYWxlcyBlcyBpZ3VhbCBhbCBuw7ptZXJvIGRlIHZhcmlhYmxlcyBpbmRpY2Fkb3JhcyDDum5pY2FzKS4NCg0KYGBge3J9DQplYy5tb2RlbCA8LSAnDQpQc3ljaFNvY0xWID1+IE5BKkRlcC4xICsgYSpEZXAuMSArIGIqRGVwLjIgKyBjKkRlcC4zICsgZCpTb2NBY3Rpdml0eQ0KYStiK2MrZD09NA0KJw0KYGBgDQoNClJlYWxpemFyIGxvcyBzaWd1aWVudGVzIGluY2lzb3M6DQoNCmcpIENvbiBsYSBmdW5jacOzbiBgY2ZhYCBkZSBgbGF2YWFuYCAoc2luIGFncmVnYXIgZWwgYXJndW1lbnRvIGBzdGQubHY9Li4uYCksIGFqdXN0ZSBlbCBtb2RlbG8gMi4gIFN1Z2VyZW5jaWE6IHVzZSBlbCBjw7NkaWdvIGhhYml0dWFsIGRlIGBjZmFgLg0KDQoNCmgpIENvbiBsYSBmdW5jacOzbiBgY2ZhYCBkZSBgbGF2YWFuYCAoc2luIGFncmVnYXIgZWwgYXJndW1lbnRvIGBzdGQubHY9Li4uYCksIGFqdXN0ZSBlbCBtb2RlbG8gMy4gIFN1Z2VyZW5jaWE6IHVzZSBlbCBjw7NkaWdvIGhhYml0dWFsIGRlIGBjZmFgLg0KDQppKSBWZXJpZmlxdWUgcXVlIGxvcyB2YWxvcmVzIHJlc3VsdGFudGVzIGRlICRcY2hpXjIkIHkgJGRmJCBzb24gaWTDqW50aWNvcyBwYXJhIHRvZG9zIGxvcyBtw6l0b2RvcyBldmFsdWFkb3MgdGFudG8gZW4gZWwgZWplcmNpY2lvIDQgY29tbyBlbiBlbCA1LiBJbnZlc3RpZ3VlIGxhIHJhesOzbi4gDQoNCmopIMK/WSBlbCBuw7ptZXJvIGRlIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8/IMK/U29uIGlndWFsZXMgZW4gdG9kb3MgbG9zIG1vZGVsb3M/IElkZW50aWbDrXF1ZWxvcyBlbiBjYWRhIHVubyBkZSBlbGxvcy4gDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGxhdmFhbikNCg0KI0V4ZXJjaXNlIDMuMS5hDQpwc3ljaFNvYy5jb3YgPC0gYygwLjc3LCAwLjM4LCAwLjY1LCAwLjM5LCAwLjM5LCAwLjYyLCAtMC4yNSwgLTAuMzIsIC0wLjI3LCA2LjA5KQ0KcHN5Y2hTb2MuY292IDwtIGxhdl9tYXRyaXhfbG93ZXIyZnVsbChwc3ljaFNvYy5jb3YpDQpyb3duYW1lcyhwc3ljaFNvYy5jb3YpIDwtIGNvbG5hbWVzKHBzeWNoU29jLmNvdikgPC0gYygiRGVwLjEiLCAiRGVwLjIiLCAiRGVwLjMiLCAiU29jQWN0aXZpdHkiKQ0KDQoNCiNFeGVyY2lzZSAzLjEuZw0KIyBzdGFuZGFyZGl6ZWQgbGF0ZW50IHZhcmlhYmxlDQojIyBtZXRob2QgMg0Kc3RkTFYubW9kZWwgPC0gJw0KUHN5Y2hTb2NMViA9fiBOQSpEZXAuMSArIERlcC4xICsgRGVwLjIgKyBEZXAuMyArIFNvY0FjdGl2aXR5DQpQc3ljaFNvY0xWfn4xKlBzeWNoU29jTFYNCicNCnN0ZExWLmZpdDIgPC0gY2ZhKHN0ZExWLm1vZGVsLCBzYW1wbGUuY292PXBzeWNoU29jLmNvdiwgc2FtcGxlLm5vYnM9NjA1MykNCnN1bW1hcnkoc3RkTFYuZml0MikNCg0KI0V4ZXJjaXNlIDMuMS5oDQojIGVmZmVjdHMtY29kaW5nDQplYy5tb2RlbCA8LSAnDQpQc3ljaFNvY0xWID1+IE5BKkRlcC4xICsgYSpEZXAuMSArIGIqRGVwLjIgKyBjKkRlcC4zICsgZCpTb2NBY3Rpdml0eQ0KYStiK2MrZD09NA0KJw0KZWMuZml0IDwtIGNmYShlYy5tb2RlbCwgc2FtcGxlLmNvdj1wc3ljaFNvYy5jb3YsIHNhbXBsZS5ub2JzPTYwNTMpDQpzdW1tYXJ5KGVjLmZpdCkNCmBgYA0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUgLS0+DQo8IS0tIFNlcGFyYWRvciAtLT4NCg0KIyMjIEVqZXJjaWNpbyA2DQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojaHR0cHM6Ly9ibG9ncy5iYXlsb3IuZWR1L3JsYXRlbnR2YXJpYWJsZS9zYW1wbGUtcGFnZS9kYXRhLw0KIw0KI0JlYXVqZWFuLCBlamVyY2ljaW8gMy4yLCBwYWdpbmEgNTIuIFNvbHVjaW9uIGVuIHBhZ2luYSAxNzMNCmBgYA0KDQpFbCBtb2RlbG8gZGVsIEVqZXJjaWNpbyBhbnRlcmlvciBmb3JtYWJhIHBhcnRlIGRlIHVuIFNFTSBtw6FzIGFtcGxpbywgcGFydGUgZGVsIGN1YWwgc2UgbXVlc3RyYSBlbiBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwM0V4MmEpLiBMYSBtYXRyaXogZGUgY292YXJpYW56YSBjb21wbGV0YSBzZSBtdWVzdHJhIGVuIGxhIEZpZ3VyYSBcQHJlZihmaWc6QmVhdWplYW5DYXAzRXgyYikuDQoNCg0KDQo8Y2VudGVyPg0KYGBge3IgQmVhdWplYW5DYXAzRXgyYSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhdGggbW9kZWwqKiIsIG91dC53aWR0aCA9ICIxMDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwM0V4MmEucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KDQpMYSBtYXRyaXogZGUgY292YXJpYW56YXMgZXM6IA0KDQo8Y2VudGVyPg0KYGBge3IgQmVhdWplYW5DYXAzRXgyYiwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKkNvdmFyaWFuemFzIChuID0gNjA1MykqKiIsIG91dC53aWR0aCA9ICIxMDAlIn0NCiMgZmlnLndpZHRoID0gMjAgIyBObyBmdW5jaW9uYSBlc3RhIG9wY2lvbiBlbiBlbCBjaHVuaw0KDQojaHR0cDovL3pldnJvc3MuY29tL2Jsb2cvMjAxNy8wNi8xOS90aXBzLWFuZC10cmlja3MtZm9yLXdvcmtpbmctd2l0aC1pbWFnZXMtYW5kLWZpZ3VyZXMtaW4tci1tYXJrZG93bi1kb2N1bWVudHMvDQojIFBhZ2luYSAzNTkgZGUgUjIwMTUtRnJpZW5kbHkNCg0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkJlYXVqZWFuQ2FwM0V4MmIucG5nIikNCg0KI090cmEgbWFuZXJhLCBwZXJvICBzYWxlIGVsIGNhcHRpb246DQojPGNlbnRlcj4NCiMhWygjZmlnOkZpZy1jYXB0aW9uKSBNaSBmaWd1cmFdKE5vbWJyZS5wbmcpe3dpZHRoPTQwMHB4fQ0KIzwvY2VudGVyPg0KYGBgDQo8L2NlbnRlcj4NCg0KKGEpIEludHJvZHV6Y2EgbGEgbWF0cml6IGRlIGNvdmFyaWFuemEgZW4gUi4NCg0KKGIpIEFqdXN0ZSBlbCBtb2RlbG8gU0VNIGEgbG9zIGRhdG9zLiDCv0xhIHNhbHVkIHBzaWNvc29jaWFsIHkgbGEgc2FsdWQgZsOtc2ljYSBwcmVkaWNlbiBsYSBtb3ZpbGlkYWQgcGVyc29uYWw/IFN1Z2VyZW5jaWE6IGFwbGlxdWUgbGEgZnVuY2nDs24gYHNlbWAgZGUgYGxhdmFhbmAuIA0KDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGVjaG89RkFMU0V9DQpsaWJyYXJ5KGxhdmFhbikNCg0KI0V4ZXJjaXNlIDMuMi5hDQptb2JpbGl0eS5jb3YgPC0gYygwLjc3ICwgMC4zOCAsIDAuNjUgLCAwLjM5ICwgMC4zOSAsIDAuNjIsIC0wLjI1LCAtMC4zMiwgLTAuMjcgLCA2LjA5LCAwLjMxLCAwLjI5ICwgMC4yNiwgLTAuMzYgLCA3LjY3ICwgMC4yNCAsIDAuMjUgLCAwLjE5LCAtMC4xOCwgMC41MSwgMS42OSwgLTMuMTYsIC0zLjU2LCAtMi42MyAsIDYuMDksIC0zLjEyLCAtNC41OCwgMjA0Ljc5LCAtMC45MiwgLTAuODgsIC0wLjcyICwgMC44OCwgLTEuNDksIC0xLjQxLCAxNi41MywgNy4yNCkNCm1vYmlsaXR5LmNvdiA8LSBsYXZfbWF0cml4X2xvd2VyMmZ1bGwobW9iaWxpdHkuY292KQ0Kcm93bmFtZXMobW9iaWxpdHkuY292KSA8LSBjb2xuYW1lcyhtb2JpbGl0eS5jb3YpIDwtIGMoIkRlcC4xIiwgIkRlcC4yIiwgIkRlcC4zIiwgIlNvY0FjdGl2aXR5IiwgIkZhbGxzIiwgIkNocm9uaWMiLCAiVG90QWN0aXZpdHkiLCAiUGVyc01vYmlsaXR5IikNCg0KI0V4ZXJjaXNlIDMuMi5iDQptb2JpbGl0eS5tb2RlbCA8LSAnDQpQc3ljaFNvY0xWID1+IERlcC4xICsgRGVwLjIgKyBEZXAuMyArIFNvY0FjdGl2aXR5DQpQc3lIZWFsdGhMViA9fiBGYWxscyArIENocm9uaWMgKyBUb3RBY3Rpdml0eQ0KUGVyc01vYmlsaXR5IH4gUHN5Y2hTb2NMViArIFBzeUhlYWx0aExWDQonDQptb2JpbGl0eS5maXQgPC0gc2VtKG1vYmlsaXR5Lm1vZGVsLCBzYW1wbGUuY292PW1vYmlsaXR5LmNvdiwgc2FtcGxlLm5vYnM9NjA1MykNCnN1bW1hcnkobW9iaWxpdHkuZml0LCBmaXQubWVhc3VyZXM9VFJVRSwgc3RhbmRhcmRpemVkPVRSVUUpDQoNCiNQaHlzaWNhbCBoZWFsdGggKC0wLjkxNCkgYXBwZWFycyB0byBiZSBhIHN0cm9uZ2VyIHByZWRpY3RvciBvZiBwZXJzb25hbCBtb2JpbGl0eSB0aGFuIHBzeWNob3NvY2lhbCBoZWFsdGggKDAuMTAxKS4NCmBgYA0KDQoNCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBTZXBhcmFkb3IgLS0+DQoNCiMjIyBFamVyY2ljaW8gNw0KDQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShsYXZhYW4pDQpsYXZfbWF0cml4Xw0KDQojaHR0cHM6Ly9ibG9ncy5iYXlsb3IuZWR1L3JsYXRlbnR2YXJpYWJsZS9zYW1wbGUtcGFnZS9kYXRhLw0KIw0KI0JlYXVqZWFuLCBlamVyY2ljaW8gMy4zLCBwYWdpbmEgNTQuIFNvbHVjaW9uIGVuIHBhZ2luYSAxNzQNCmBgYA0KDQoNCkdyYWhhbSAoMjAwOCkgbW9zdHLDsyBjw7NtbyBlbCBTRU0gcHVlZGUgdXRpbGl6YXJzZSBwYXJhIGFuYWxpemFyIHVuYSB2YXJpZWRhZCBkZSBtb2RlbG9zIGxpbmVhbGVzIGdlbmVyYWxlcy4gbGluZWFsZXMgZ2VuZXJhbGVzLiBTdSBlamVtcGxvIGRlIGFuw6FsaXNpcyBkZXNjcmlwdGl2byBkaXNjcmltaW5hbnRlIChEREEpIHV0aWxpemEgdmFyaWFibGVzIGxhdGVudGVzIGZvcm1hdGl2YXMuIEVsIEREQSBlcyB1biBwcm9jZWRpbWllbnRvIHF1ZSBkZXNjcmliZSBsYXMgZGlmZXJlbmNpYXMgZW50cmUgbcO6bHRpcGxlcyBncnVwb3MgZW4gbcO6bHRpcGxlcyBkZXNjcmlwdG9yZXMgY29udGludW9zOiB1bmEgcmVncmVzacOzbiBtw7psdGlwbGUgZW50cmUgZG9zIG8gbcOhcyBncnVwb3MuIEVuIEREQSwgbGEgdmFyaWFibGUgbGF0ZW50ZSBkZSBpbnRlcsOpcyBzZSBkZW5vbWluYSBmdW5jacOzbiBkaXNjcmltaW5hbnRlLiBVbiBwYXRoIG1vZGVsIGRlbCBEREEgc2UgbXVlc3RyYSBlbiBsYSBGaWd1cmEgIFxAcmVmKGZpZzpCZWF1amVhbkNhcDNFeDNhKSB5IGxvcyBkYXRvcyBwYXJhIGVsIG1vZGVsbyBzZSBkYW4gZW4gbGEgRmlndXJhICAgXEByZWYoZmlnOkJlYXVqZWFuQ2FwM0V4M2IpLg0KDQpFbCBwYXRoIG1vZGVsIGVzOg0KDQo8Y2VudGVyPg0KYGBge3IgQmVhdWplYW5DYXAzRXgzYSwgZWNobz1GQUxTRSwgZmlnLmNhcCA9ICIqKlBhdGggbW9kZWwgZGVsIEREQSoqIiwgb3V0LndpZHRoID0gIjcwJSJ9DQojIGZpZy53aWR0aCA9IDIwICMgTm8gZnVuY2lvbmEgZXN0YSBvcGNpb24gZW4gZWwgY2h1bmsNCg0KI2h0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLw0KIyBQYWdpbmEgMzU5IGRlIFIyMDE1LUZyaWVuZGx5DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJCZWF1amVhbkNhcDNFeDNhLnBuZyIpDQoNCiNPdHJhIG1hbmVyYSwgcGVybyAgc2FsZSBlbCBjYXB0aW9uOg0KIzxjZW50ZXI+DQojIVsoI2ZpZzpGaWctY2FwdGlvbikgTWkgZmlndXJhXShOb21icmUucG5nKXt3aWR0aD00MDBweH0NCiM8L2NlbnRlcj4NCmBgYA0KPC9jZW50ZXI+DQoNCg0KTGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIGVzOiANCg0KPGNlbnRlcj4NCmBgYHtyIEJlYXVqZWFuQ2FwM0V4M2IsIGVjaG89RkFMU0UsIGZpZy5jYXAgPSAiKipDb3ZhcmlhbnphcyAobiA9IDI4OCkqKiIsIG91dC53aWR0aCA9ICI0MCUifQ0KIyBmaWcud2lkdGggPSAyMCAjIE5vIGZ1bmNpb25hIGVzdGEgb3BjaW9uIGVuIGVsIGNodW5rDQoNCiNodHRwOi8vemV2cm9zcy5jb20vYmxvZy8yMDE3LzA2LzE5L3RpcHMtYW5kLXRyaWNrcy1mb3Itd29ya2luZy13aXRoLWltYWdlcy1hbmQtZmlndXJlcy1pbi1yLW1hcmtkb3duLWRvY3VtZW50cy8NCiMgUGFnaW5hIDM1OSBkZSBSMjAxNS1GcmllbmRseQ0KDQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQmVhdWplYW5DYXAzRXgzYi5wbmciKQ0KDQojT3RyYSBtYW5lcmEsIHBlcm8gIHNhbGUgZWwgY2FwdGlvbjoNCiM8Y2VudGVyPg0KIyFbKCNmaWc6RmlnLWNhcHRpb24pIE1pIGZpZ3VyYV0oTm9tYnJlLnBuZyl7d2lkdGg9NDAwcHh9DQojPC9jZW50ZXI+DQpgYGANCjwvY2VudGVyPg0KDQpSZWFsaXphciBsb3Mgc2lndWllbnRlcyBpbmNpc29zOg0KDQooYSkgSW1wb3J0ZSBhIFIgbGEgbWF0cml6IGRlIGNvdmFyaWFuemFzIHkgZWwgdmVjdG9yIGRlIG1lZGlhcy4NCg0KKGIpIEVzY3JpYmEgbGEgc2ludGF4aXMgYGxhdmFhbmAgcGFyYSBsYSBGaWd1cmEgXEByZWYoZmlnOkJlYXVqZWFuQ2FwM0V4M2EpLiBTdWdlcmVuY2lhOiBlbCBwYXRoIGBhPTFgIHNlIGVzY3JpYmUgY29tbyBgMSpEVjEgKyBhKkRWMWAgZW4gbGEgc2ludGF4aXMgZGUgYGxhdmFhbmAuDQoNCihjKSBPYnRlbmdhIGxvcyBjb2VmaWNpZW50ZXMgZGUgZnVuY2nDs24gKGNvZWZpY2llbnRlcyBlc3RhbmRhcml6YWRvcyBwYXJhIGEgeSBiKSwgY29ycmVsYWNpw7NuIGNhbsOzbmljYSAoY29lZmljaWVudGUgZXN0YW5kYXJpemFkbyBwYXJhIGMpLCB5ICRSXjIkIChjb2VmaWNpZW50ZSBub3JtYWxpemFkbyBwYXJhIGQpLiBTdWdlcmVuY2lhOiBhcGxpcXVlIGxhIGZ1bmNpw7NuIGBzZW1gIGRlIGBsYXZhYW5gLiANCg0KDQpgYGB7ciBldmFsPUZBTFNFLCBlY2hvPUZBTFNFfQ0KbGlicmFyeShsYXZhYW4pDQoNCiNFeGVyY2lzZSAzLjMuYQ0KZGRhLmNvdiA8LSBsYXZfbWF0cml4X2xvd2VyMmZ1bGwoYyg1OS42NiwgMTEuMTgsIDIyLjMsIDIuNjMsIDAuNDEsIDEpLCBkaWFnb25hbCA9IFRSVUUpDQpyb3duYW1lcyhkZGEuY292KSA8LSBjb2xuYW1lcyhkZGEuY292KSA8LSBjKCJEVjEiLCAiRFYyIiwgIkNhdDEiKQ0KZGRhLmNvdg0KDQojRXhlcmNpc2UgMy4zLmINCmRkYS5tb2RlbDwtJw0KRjEgPH4gMSpEVjEgKyBhKkRWMSArIGIqRFYyDQoNCiNSZWdyZXNpw7NuIGRlIENhdDEgc29icmUgRjE6DQpDYXQxIH4gYypGMQ0KDQojVmFyaWFuemEgZGUgQ2F0MToNCkNhdDF+fmQqQ2F0MQ0KJw0KI0V4ZXJjaXNlIDMuMy5jDQpkZGEuZml0IDwtIHNlbShkZGEubW9kZWwsIHNhbXBsZS5jb3YgPSBkZGEuY292LCBzYW1wbGUubm9icyA9IDI4OCkNCnBhcmFtZXRlckVzdGltYXRlcyhkZGEuZml0LCBzdGFuZGFyZGl6ZWQgPSBUUlVFKQ0KDQojVGhlIGZ1bmN0aW9uIGNvZWZmaWNpZW50cyBhcmUgYT0xLjAxNiAgYW5kIGI9LTAuMDU3LCB0aGUgY2Fub25pY2FsIGNvcnJlbGF0aW9uIGlzIGM9MC4zNDEsIGFuZCBSMiBpcyAwLjExNiAoaS5lLiwgMSDiiJIgMC44ODQpDQpgYGANCg0KDQoNCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBDYXDDrXR1bG8gQmlibGlvZ3JhZsOtYS0tPg0KDQoNCiMgQmlibGlvZ3JhZsOtYSB7LnVubGlzdGVkIC51bm51bWJlcmVkfQ0KICANCkNvbnN1bHRhciBlbCBkb2N1bWVudG8gW1JQdWJzIDo6IEFuw6FsaXNpcyBtdWx0aXZhcmlhZG8gKGJpYmxpb2dyYWbDrWEpXShodHRwczovL3JwdWJzLmNvbS9obGxpbmFzL1JfTXVsdGl2YXJpYWRvX0JpYmxpb2dyYWZpYSkuDQoNCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIFBhZ2luIFdlYiBkZSBCZWF1amVhbg0KIyANCiNodHRwczovL2Jsb2dzLmJheWxvci5lZHUvcmxhdGVudHZhcmlhYmxlL3NhbXBsZS1wYWdlL2RhdGEvDQpgYGANCg0KDQo8IS0tICUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlIC0tPg0KPCEtLSBDYXDDrXR1bG8gQmlibGlvZ3JhZsOtYS0tPg0KDQojIFJlZmVyZW5jaWFzIHsudW5saXN0ZWQgLnVubnVtYmVyZWR9DQoNCkdyYWhhbSwgSi4gTS4gKDIwMDgpLiBUaGUgZ2VuZXJhbCBsaW5lYXIgbW9kZWwgYXMgc3RydWN0dXJhbCBlcXVhdGlvbiBtb2RlbGluZy4gSm91cm5hbCBvZiBFZHVjYXRpb25hbCBhbmQgQmVoYXZpb3JhbCBTdGF0aXN0aWNzLCAzMyAsIDQ4NS01MDYuIGRvaTogMTAuMzEwMi8xMDc2OTk4NjA3MzA2MTUxLg0KDQpNYWNLaW5ub24sIEQuIFAuICgyMDA4KS4gSW50cm9kdWN0aW9uIHRvIHN0YXRpc3RpY2FsIG1lZGlhdGlvbiBhbmFseXNpcy4gTWFod2FoLCBOSjoNCkVybGJhdW0uDQoNClBhZ2UsIEUuIEIuLCAmIEtlaXRoLCBULiBaLiAoMTk4MSkuIEVmZmVjdHMgb2YgVS5TLiBwcml2YXRlIHNjaG9vbHM6IEEgdGVjaG5pY2FsIGFuYWx5c2lzIG9mIHR3byByZWNlbnQgY2xhaW1zLiBFZHVjYXRpb25hbCBSZXNlYXJjaGVyLCAxMCAsIDctMTcuIGRvaTogMTAuMjMwNy8xMTc0MjU2Lg0KDQpVbXN0YXR0ZC1NZXllciwgTS4gUi4sIEphbmtlLCBNLiBDLiwgJiBCZWF1amVhbiwgQS4gQS4gKDIwMTMpLiBQcmVkaWN0b3JzIG9mIG9sZGVyIGFkdWx0c+KAmSBwZXJzb25hbCBhbmQgY29tbXVuaXR5IG1vYmlsaXR5OiBVc2luZyBhIGNvbXByZWhlbnNpdmUgdGhlb3JldGljYWwgbW9iaWxpdHkNCmZyYW1ld29yay4gVGhlIEdlcm9udG9sb2dpc3QsIEFkdmFuY2Ugb25saW5lIHB1YmxpY2F0aW9uLiBkb2k6IDEwLjEwOTMvZ2Vyb250L2dudDA1NC4NCg0KPCEtLSAlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSUlJSAtLT4NCg0KJm5ic3A7DQoNCg0KJm5ic3A7DQo8Y2VudGVyPg0Kfn5+DQpJZiB5b3UgZm91bmQgYW55IEVSUk9SUyBvciBoYXZlIFNVR0dFU1RJT05TLCBwbGVhc2UgcmVwb3J0IHRoZW0gdG8gbXkgZW1haWwuIFRoYW5rcy4gIA0Kfn5+DQo8L2NlbnRlcj4NCg0KDQo=