Fase 1 [Descripciones Multivariantes]

En la primera etapa del estudio se realizarán cálculos, visualizaciones y un análisis detallado del conjunto de datos clínicos, el cual se describirá en la sección 1.2. Esta fase se enfocará desde la estadística descriptiva multivariante, con el fin de ofrecer una visión general del dataset y, al mismo tiempo, examinar de manera más profunda las relaciones entre las variables. Este enfoque permitirá identificar patrones y tendencias importantes dentro de los datos. Las visualizaciones serán fundamentales para mostrar gráficamente estas relaciones, proporcionando una forma clara y comprensible de explorarlas. Todas estas tareas se desarrollarán utilizando R y RStudio, herramientas que facilitarán la ejecución precisa de los análisis y la elaboración de gráficos interactivos para una interpretación más completa de los resultados.

1.1. Objetivos

El objetivo de este proyecto es aplicar técnicas de análisis multivariado al conjunto de datos aprobado, el cual contiene registros clínicos de la empresa oftalmológica, Visión 2020. La finalidad es organizar y procesar la información de manera eficiente, fortaleciendo las competencias en gestión y análisis de datos. Este trabajo se desarrolla en el marco del curso Gestión de Datos, orientado al programa de Ingenieria Industrial, en el segundo periodo de 2025 en la Universidad del Valle, Seccional Zarzal.

1.2. Descripción de los datos

El conjunto de datos utilizado en este estudio fue proporcionado por la empresa del sector oftalmológico Vision 2020, a partir de los registros de pacientes atendidos durante el año 2024. La información original fue entregada en un archivo plano, con 1249 registros (uno por paciente) y 22 variables y posteriormente sometida a un proceso de extracción, transformación y carga (ETL), en el cual se depuraron inconsistencias, se normalizaron formatos y se generaron variables derivadas para facilitar el análisis estadístico. El objetivo de este conjunto es caracterizar el perfil visual y de hábitos de uso de pantallas de los pacientes, así como su posible relación con factores demográficos y antecedentes familiares.

Tras el proceso ETL se consolidó una base con 1166 registros y 13 variables, que combinan aspectos de identificación, sociodemográficos, clínico‑visuales y de estilo de vida. Las variables se describen a continuación en el orden en que aparecen en la base de datos, indicando su tipo y escala de medición mediante la notación (tipo_de_variable::escala_de_medición[ordenamiento]).

Pac_id (cuantitativa::nominal): Identificador numérico secuencial que asigna un código único a cada paciente. Permite referenciar los registros sin revelar datos personales y no tiene interpretación métrica por sí mismo.

Edad_paciente (cuantitativa::razón): Edad del paciente expresada en años cumplidos al momento del registro. Es una variable de razón, con cero absoluto y posibilidad de realizar comparaciones de proporciones de edad.

Ocupacion (cualitativa::nominal): Profesión u oficio principal del paciente (por ejemplo, estudiante, administrativo, operario, independiente, entre otros). Se utiliza para caracterizar el tipo de actividad diaria, especialmente en términos de exposición potencial a pantallas.

Canal_difusion (cualitativa::nominal): Medio por el cual el paciente conoció la óptica (referido, redes sociales, volante, paso por el local, convenio, etc.). Esta variable permite identificar los canales de captación más frecuentes dentro de la población atendida.

Fecha_registro (cualitativa::ordinal[tiempo]): Fecha en la que el paciente fue registrado en el sistema, expresada como día/mes/año. Aunque se almacena como texto o fecha calendario, su escala es ordinal en el tiempo y se usa para ubicar la atención dentro del periodo de estudio.

Pac_sexo (cualitativa::nominal): Sexo del paciente, registrado típicamente como “Femenino” o “Masculino”. Esta variable se emplea para comparar patrones de agudeza visual y hábitos de pantalla entre grupos.

Rango_etareo (cualitativa::ordinal): Clasificación del paciente en grupos de edad (por ejemplo, ADOLESCENTE, JOVEN_ADULTO, ADULTO, ADULTO_MAYOR), construida a partir de la variable edad_paciente. Presenta un orden natural de los grupos, lo que permite análisis por categorías etarias.

Agudeza_visual_OD (cuantitativa::razón): Medida de la agudeza visual del ojo derecho, expresada en la escala establecida por la óptica (por ejemplo, conversión a una métrica continua compatible con la práctica clínica). Valores más cercanos a la referencia de visión normal indican mejor agudeza, mientras que valores que se alejan de dicho estándar representan mayor compromiso visual.

Agudeza_visual_OI (cuantitativa::razón): Análoga a la anterior, pero para el ojo izquierdo. Junto con la agudeza del ojo derecho, permite evaluar la simetría o diferencias entre ambos ojos y constituye una de las variables clínicas centrales del estudio.

Horas_pantalla_dia (cuantitativa::razón): Número de horas promedio que el paciente pasa diariamente frente a dispositivos con pantalla (computador, teléfono inteligente, tableta, televisión, consola, etc.). Es una medida continua de exposición y se considera un potencial factor de riesgo asociado a fatiga visual y otras molestias oculares.

Horas_actividadf (cuantitativa::razón): Horas promedio de actividad física que el paciente realiza al día (o en promedio diario a partir de la semana), incluyendo ejercicio estructurado y actividades recreativas. Esta variable permite explorar si un estilo de vida más activo se relaciona con mejores indicadores visuales o con menor exposición a pantallas.

Hobby_principal_pantalla (cualitativa::nominal): Indica si el pasatiempo principal del paciente implica uso intensivo de pantallas (por ejemplo, videojuegos, redes sociales, series en streaming) o no. Se codifica típicamente como “sí” o “no” y se usa para diferenciar hobbies digitales de actividades analógicas o al aire libre.

Predisposicion_genetica (cualitativa::nominal): Señala si el paciente reporta antecedentes familiares de problemas oftalmológicos relevantes (miopía alta, glaucoma, degeneración macular, entre otros). Se registra como “sí” o “no” y funciona como aproximación a un factor de riesgo genético.

Durante el proceso de depuración se verificó la coherencia de rangos (por ejemplo, edades no negativas, horas de pantalla y actividad física dentro de intervalos plausibles, valores de agudeza visual dentro de los límites aceptados por la escala utilizada). Los valores faltantes o claramente atípicos fueron revisados caso a caso; en los casos en que no fue posible recuperar información confiable, se recurrió a estrategias de imputación o exclusión controlada, documentadas en el flujo ETL. A partir de este conjunto depurado, se desarrollan las fases posteriores del análisis multivariado, centradas en la relación entre agudeza visual, hábitos de pantalla, actividad física y factores demográficos y genéticos.

Estructura del Conjunto de Datos Original

str(conjunto_de_datos_vision2020_nETL)
## tibble [1,249 × 22] (S3: tbl_df/tbl/data.frame)
##  $ pac_id                  : num [1:1249] 1 2 3 4 5 6 7 8 9 10 ...
##  $ pac_carnet              : num [1:1249] 0 0 0 0 0 1 1 1 1 1 ...
##  $ nombre                  : chr [1:1249] "HECTOR GUSTAVO" "LUISA MARIA" "YOLANDA DEL SOCORRO" "MARIA GLADIS" ...
##  $ apellido                : chr [1:1249] "CUERVO" "TORO CORDOBA" "SANCHEZ" "TORO CORDOBA" ...
##  $ edad                    : num [1:1249] 29 25 55 56 35 37 1 29 41 75 ...
##  $ ocupacion               : chr [1:1249] "admin" "Asesor Comercial" "OTRO" "OTRO" ...
##  $ canal_difusion          : chr [1:1249] "Convenio" "Usuario óptica" "Paso por la óptica" "Usuario óptica" ...
##  $ fecha_registro          : POSIXct[1:1249], format: "2024-05-20" "2024-05-24" ...
##  $ pac_sexo                : chr [1:1249] "Masculino" "Femenino" "Femenino" "Femenino" ...
##  $ pac_vincula             : chr [1:1249] "No registra" "No registra" "No registra" "No registra" ...
##  $ tipo_afiliciacion       : chr [1:1249] "No registra" "Particular" "Particular" "Particular" ...
##  $ pac_observa             : chr [1:1249] NA NA NA "Ninguna" ...
##  $ rango_etareo            : chr [1:1249] "ADULTO" "JÓVENES" "ADULTO" "ADULTO" ...
##  $ pac_cond_disc           : num [1:1249] 0 0 2 0 2 0 0 0 0 0 ...
##  $ tipo_regimen            : num [1:1249] 2 2 2 2 2 2 2 2 2 2 ...
##  $ Agudeza_visual_OD       : logi [1:1249] NA NA NA NA NA NA ...
##  $ Agudeza_visual_OI2      : logi [1:1249] NA NA NA NA NA NA ...
##  $ Error_refractivo_total_D: logi [1:1249] NA NA NA NA NA NA ...
##  $ Horas_pantalla_dia      : logi [1:1249] NA NA NA NA NA NA ...
##  $ Horas_aire_libre_semana : logi [1:1249] NA NA NA NA NA NA ...
##  $ Hobby_principal         : logi [1:1249] NA NA NA NA NA NA ...
##  $ Predisposicion_genetica : logi [1:1249] NA NA NA NA NA NA ...

Estructura del Conjunto de Datos ETL

str(ccd_vision2020_ETL)
## tibble [1,166 × 13] (S3: tbl_df/tbl/data.frame)
##  $ pac_id                 : num [1:1166] 1 2 4 5 6 7 8 9 10 11 ...
##  $ edad_paciente          : num [1:1166] 29 25 55 56 35 37 1 29 41 75 ...
##  $ ocupacion              : chr [1:1166] "admin" "Asesor Comercial" "OTRO" "OTRO" ...
##  $ canal_difusion         : chr [1:1166] "Convenio" "Usuario óptica" "Paso por la óptica" "Usuario óptica" ...
##  $ fecha_registro         : POSIXct[1:1166], format: "2024-05-20" "2024-05-24" ...
##  $ pac_sexo               : chr [1:1166] "Masculino" "Femenino" "Femenino" "Femenino" ...
##  $ rango_etareo           : chr [1:1166] "ADULTO" "JOVENES" "ADULTO" "ADULTO" ...
##  $ AV_OD                  : num [1:1166] 0.847 0.213 0.717 0.592 0.404 ...
##  $ AV_OI                  : num [1:1166] 0.488 0.765 0.799 0.142 0.974 ...
##  $ Horas_pd               : num [1:1166] 5.82 4.79 8.77 0.78 3.07 0.62 8.99 1.86 1.22 0.38 ...
##  $ Horas_af               : num [1:1166] 5 8 9 3 7 5 4 2 1 9 ...
##  $ Hobby_ppantalla        : chr [1:1166] "si" "no" "no" "no" ...
##  $ Predisposicion_genetica: chr [1:1166] "1" "1" "0" "0" ...

1.3. Estimaciones multivariadas

El vector de medias y la matriz de varianzas-covarianzas conforman un conjunto de herramientas fundamentales para describir el comportamiento posicional, dispersivo y correlacional de las variables aleatorias en un conjunto de datos. Estas medidas son esenciales en el análisis multivariado, ya que permiten capturar tanto la tendencia central como las interdependencias entre las variables.

El vector de medias refleja el valor esperado o punto medio de cada variable, sintetizando la información de todos los registros disponibles en el conjunto de datos. Por su parte, la matriz de varianzas-covarianzas describe la variabilidad y las relaciones entre las variables. En su diagonal principal, estima las dispersiones individuales de cada variable respecto a su media, mientras que los elementos por encima o por debajo de esta diagonal representan las covarianzas entre pares de variables, mostrando las relaciones lineales existentes entre ellas.

En esta sección se presenta el cálculo e interpretación de tres objetos fundamentales: Vector de Medias \(\bar x\) , Matriz de Varianzas-Covarianzas \(S\) y Matriz de Correlaciones \(R\)., construidos a partir de las variables edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af. La pestaña correspondiente al vector de medias y a los boxplots univariantes permite describir el comportamiento posicional y dispersivo de cada variable:

Vector de Promedios y Boxplots

apply(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], 2, mean)
## edad_paciente         AV_OD         AV_OI      Horas_pd      Horas_af 
##    38.7178388     0.5367784     0.5662855     4.9418525     5.4631218
ccd_vision2020_ETL_Reducido = ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]
nombres_boxplots <- c("Edad\n(Años)","Agudeza Visual\n(O. Derecho)","Agudeza Visual\n(O. Izquierdo)","Actividades en\nPantalla (Horas)","Actividad\nFísica (Horas)")
par(mfrow = c(1, ncol(ccd_vision2020_ETL_Reducido)))
invisible(lapply(1:ncol(ccd_vision2020_ETL_Reducido), function(i) {
  boxplot(ccd_vision2020_ETL_Reducido[, i],
          main = nombres_boxplots[i])}))

Con base en los Diagramas de Caja (Boxplots), se puede describir que, en general, los datos registrados para cada una de las variables tienden a presentar distribuciones con las siguientes formas y características:

La variable Edad (Años) tiene una distribución casi normal, con un sesgo cercano a cero, ya que la mediana (\(\approx 37\) años) está centrada en la caja. Por otra parte, las variables Actividades en Pantalla (Horas_pd) y Actividad Física (Horas_af) también muestran distribuciones casi simétricas (sesgo cercano a cero), con sus medianas (\(\approx 5.2\) y \(\approx 4.6\) horas, respectivamente) bien centradas.

En contraste, la variable Agudeza Visual (O. Derecho) tiene un ligerísimo sesgo a la izquierda (cola inferior), mientras que la Agudeza Visual (O. Izquierdo) tiene un ligerísimo sesgo a la derecha (cola superior). Esto indica que en el Ojo Derecho hay una leve tendencia de valores muy bajos que extienden la cola, y en el Ojo Izquierdo, una leve tendencia de valores altos que extienden la cola.

Matriz de Varianzas-Covarianzas

round(cov(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]),2)
##               edad_paciente AV_OD AV_OI Horas_pd Horas_af
## edad_paciente        502.21 -0.28 -0.14     2.86    -0.55
## AV_OD                 -0.28  0.07  0.00    -0.02    -0.03
## AV_OI                 -0.14  0.00  0.07    -0.05     0.00
## Horas_pd               2.86 -0.02 -0.05     8.08     0.05
## Horas_af              -0.55 -0.03  0.00     0.05     8.31

La Matriz de Varianzas-Covarianzas, con la varianza de cada variable en su diagonal principal, confirma que la Edad presenta la mayor variabilidad absoluta (Varianza: 502.21), mientras que las variables de Agudeza Visual (AV_OD y AV_OI) son las más estables y concentradas (Varianza: 0.07 para ambas). Las covarianzas fuera de la diagonal son bajas en magnitud (cercanas a cero), lo que ya sugiere una relación lineal débil o nula entre la mayoría de los pares de variables, siendo el valor más alto en magnitud la covarianza entre Edad y Horas_pd (1.05).

Matriz de Correlaciones

round(cor(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]),3)
##               edad_paciente  AV_OD  AV_OI Horas_pd Horas_af
## edad_paciente         1.000 -0.048 -0.024    0.045   -0.009
## AV_OD                -0.048  1.000  0.029   -0.020   -0.042
## AV_OI                -0.024  0.029  1.000   -0.073   -0.005
## Horas_pd              0.045 -0.020 -0.073    1.000    0.006
## Horas_af             -0.009 -0.042 -0.005    0.006    1.000

La Matriz de Correlaciones, que estandariza las covarianzas, es el indicador clave de la relación lineal. Se observa que todas las correlaciones son extremadamente débiles, con coeficientes consistentemente cercanos a cero (siendo el valor máximo en magnitud \(r = -0.099\), entre Horas_pd y AV_OI). Este patrón de valores bajos en toda la matriz confirma que ninguna variable tiene una relación lineal significativa con otra en el conjunto de datos. En consecuencia, se concluye que las variables son independientes entre sí en términos lineales, y el conocimiento del valor de una no ayuda a predecir el valor de la otra.

1.4. Gráficas multivariadas

En general, los gráficos multivariados cumplen dos objetivos esenciales: primero, ayudan a comparar el comportamiento de poblaciones de estudio con base en variables categóricas y facilitan la comprensión de la estructura de correlación entre varias variables. Además, permiten identificar patrones, tendencias, y posibles outliers en los datos, simplificando la interpretación de relaciones complejas y destacando las características más significativas de los mismos (Aldás, 2017).

Para el conjunto de datos descrito en la [sección 1.2] se calcularán e intepretarán, para las variables numéricas (Edad, Horas_pantalla_diarias, Horas_actividad_fisica, Agudeza_Visual_OD y Agudeza_Visual_OI), las gráficas multivariadas de diagrama de correlaciones, matriz de diagrama de dispersión, diagrama de estrellas y caras de Chernoff. La navegación a través de las pestañas muestra las gráficas multivariadas de: Diagrama Conjunto de Dispersión, Distribución y Correlaciones (sin agrupación SA y con agrupación CA (con base en una variable categórica)) Diagrama de Estrellas y Caras de Chernoff..

Diagrama Conjunto de Dispersión, Distribución y Correlaciones[SA]

ggpairs(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)])

El Diagrama Conjunto de Dispersión, Distribución y Correlaciones se utilizó para realizar un análisis exploratorio de la distribución de las variables y sus relaciones lineales. Las distribuciones diagonales confirman que la Agudeza Visual (AV_OD y AV_OI) está fuertemente concentrada alrededor de 1.0 (visión normal) y que el principal predictor, Horas_pd, presenta un patrón de uso agrupado. El aporte más significativo de la matriz es la confirmación de la ausencia de asociación lineal robusta entre las Horas_pd y la Agudeza Visual; la correlación con el ojo derecho es prácticamente nula (\(r = -0.020\)), y aunque es débilmente negativa con el ojo izquierdo (\(r = -0.073\)), la magnitud de la relación es trivial. De igual forma, la correlación de la Agudeza Visual con la edad_paciente es marginal.

Estos resultados sugieren que, en un contexto lineal, las variables predictoras exploradas en este conjunto de datos tienen un bajo poder explicativo sobre la variabilidad de la Agudeza Visual, lo que justifica la necesidad de un modelo multivariante más complejo que incorpore otras variables confusoras o explore relaciones no lineales.

Diagrama Conjunto de Dispersión, Distribución y Correlaciones[CA:RE]

ccd_vision2020_ETL$rango_etareo <- factor(ccd_vision2020_ETL$rango_etareo)
levels= c (1,2,3,4,5)
labels= c ( "Edad" , "AV_OD" , "AV_OI" , "Horas_pd" , "Horas_af")
ggpairs(ccd_vision2020_ETL, column = c(2,8,9,10,11), aes(color = rango_etareo, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

El Análisis Conjunto de Dispersión y Correlaciones, estratificado por rango etario, ofrece una perspectiva multivariante crucial sobre las relaciones entre las variables. Si bien el modelo logístico simple inicial no mostró un efecto significativo de las horas de pantalla, esta matriz revela que la correlación es altamente dependiente del grupo de edad. Específicamente, en el grupo de ADULTO MAYOR, la relación entre las Horas_pd y la Agudeza Visual es negativa y notablemente más fuerte que en la población general: \(r = -0.137\) para \(AV\_OD\) y \(r = -0.198\) para \(AV\_OI\). Esto sugiere que, al menos en este subgrupo, un mayor tiempo de pantalla está asociado de manera más clara con una peor Agudeza Visual. Por el contrario, en el grupo de NIÑEZ, la correlación entre Horas_pd y \(AV\_OD\) es positiva (\(r = 0.051\)), aunque débil, lo que indica que la direccionalidad y fuerza de la asociación no son consistentes a través de la vida.

Las distribuciones diagonales estratificadas confirman que la Edad es el principal factor de variabilidad, destacando que el rango ADULTO MAYOR es el que concentra la peor Agudeza Visual promedio. En conclusión, el efecto de las horas de pantalla no es global, sino que está mediado por la edad, un hallazgo esencial para la construcción de un modelo de Regresión Logística Multivariante robusto que debe incluir la interacción entre Horas_pd y rango_etareo.

Diagrama de Estrellas

set.seed(120522)
ccd_vision2020_ETL_MUESTREADO = ccd_vision2020_ETL[sample(1:nrow(ccd_vision2020_ETL),23),-c(1,3,4,5,6,7,12,13)]
stars(ccd_vision2020_ETL_MUESTREADO, len = 1, cex = 0.4, key.loc = c(10, 2), draw.segments = TRUE)

La representacion del conjunto de datos, por medio del Diagrama de estrellas permitio identificar tres puntos de reflexión:

Patrones de Clusterización: Pacientes con estrellas de formas similares (es decir, grupos de radios largos o cortos en las mismas direcciones) tienden a compartir un perfil similar en todas las variables.

Relación Inversa (AV vs. Edad): Se observa que las estrellas con radios largos en Edad (Negro) (pacientes mayores) a menudo tienen radios cortos en AV_OD (Rojo) y AV_OI (Verde) (peor agudeza visual), y viceversa. Esto visualmente confirma la correlación negativa entre Edad y Agudeza Visual que se vio en la matriz estratificada, sugiriendo que la edad es el factor dominante en la variabilidad de la AV.

Heterogeneidad en Horas de Pantalla: El radio de Horas_pd (Azul Oscuro) varía mucho entre individuos sin un patrón claro y simple con respecto a la AV o la Edad. Por ejemplo, algunas estrellas grandes (pacientes mayores con baja AV) tienen radios de Horas_pd largos (muchas horas) y otras tienen radios cortos (pocas horas). Esto refuerza la idea de que la correlación global de \(r \approx 0\) es apropiada, ya que la relación entre horas de pantalla y AV no es uniforme.

Caras de Chernoff

set.seed(120522)
ccd_vision2020_ETL_MUESTREADO = ccd_vision2020_ETL [sample(1:nrow(ccd_vision2020_ETL),23),-c(11,3,4,5,6,7,12,13)]
faces(ccd_vision2020_ETL_MUESTREADO)

## effect of variables:
##  modified item       Var            
##  "height of face   " "pac_id"       
##  "width of face    " "edad_paciente"
##  "structure of face" "AV_OD"        
##  "height of mouth  " "AV_OI"        
##  "width of mouth   " "Horas_pd"     
##  "smiling          " "pac_id"       
##  "height of eyes   " "edad_paciente"
##  "width of eyes    " "AV_OD"        
##  "height of hair   " "AV_OI"        
##  "width of hair   "  "Horas_pd"     
##  "style of hair   "  "pac_id"       
##  "height of nose  "  "edad_paciente"
##  "width of nose   "  "AV_OD"        
##  "width of ear    "  "AV_OI"        
##  "height of ear   "  "Horas_pd"

El diagrama de Caras de Chernoff, permitio identificar: variables de resultado (Agudeza Visual) como rasgos fijos, es decir, El diseño asigna las variables de resultado de salud (AV_OD y AV_OI) a los rasgos más estables de la cara (estructura, boca, nariz), permitiendo que el ojo humano identifique rápidamente los sujetos con baja AV (caras más deformes/diferentes).

Ademas, de establecer el caracter predictor (Horas_pantalla diarias) como Rasgo Variable: El predictor principal (Horas_pd) se asigna a rasgos más flexibles (ancho de la boca, altura de la oreja). Esto facilita la búsqueda de patrones: si los pacientes con “caras deformes” (baja AV) tienden a tener bocas anchas (muchas Horas_pd), el predictor sería visualmente relevante.

1.5. Normalidad multivariada

Es posible analizar o determinar la distribución multivariada de un conjunto de datos mediante métodos descriptivos, como los gráficos, o inferenciales, como las pruebas estadísticas. Mientras que los procedimientos inferenciales permiten obtener conclusiones más generalizables, los gráficos resultan útiles como soporte para la interpretación de los resultados.

En este apartado se aborda la aplicación de procedimientos inferenciales para verificar si el conjunto de datos de trabajo, respecto a sus variables numéricas, sigue una distribución normal multivariada (DNM). Las pruebas de normalidad multivariada (PNM) que se aplicarán son: Mardia, Henze-Zirkler, Doornik-Hansen y Royston. Estas pruebas de normalidad se realizan bajo un nivel de significancia determinado \(\alpha = 0.05\) y a las hipótesis:\[H_0: \text {Las variables tienen una DNM}\] \[H_1: \text {Las variables NO tienen una DNM}\]

La prueba de Mardia se fundamenta en las extensiones de asimetría y curtosis, el cuadrado de la distancia de Mahalanobis, el número de variables \(p\) a analizar y el número de registros \(n\). Asimismo, se considera que la estadística de la prueba para la asimetría sigue una distribución \(\chi^2\), mientras que la estadística para la curtosis se distribuye de manera aproximada de forma normal.

La prueba de Henze-Zirkler se basa en la distancia funcional, ya que si el conjunto de datos sigue una distribución normal multivariada, el estadístico de la prueba se distribuye de manera aproximada como una lognormal, con parámetros de media \(\mu\) y varianza \(\sigma^2\).

La prueba de Doornik-Hansen se basa en la asimetría y la curtosis de un conjunto de datos multivariados, los cuales se transforman para asegurar la independencia. Se considera más potente que la prueba de Shapiro-Wilk en casos multivariados. El estadístico de la prueba se define como la suma de las transformaciones al cuadrado de la asimetría y la curtosis, y sigue aproximadamente una distribución \(\chi^2\).

Por otro lado, la prueba de Royston utiliza las pruebas de Shapiro-Wilk o Shapiro-Francia para evaluar la normalidad multivariada. Si la curtosis es mayor que 3, se emplea Shapiro-Francia para distribuciones leptocúrticas, mientras que para distribuciones platicúrticas se utiliza Shapiro-Wilk. Los parámetros en esta prueba se obtienen mediante aproximaciones polinomiales.

PNM Mardia

mardia(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)])
## $mv.test
##           Test Statistic p-value Result
## 1     Skewness   38.1796   0.327    YES
## 2     Kurtosis  -11.1804       0     NO
## 3 MV Normality      <NA>    <NA>     NO
## 
## $uv.shapiro
##               W      p-value UV.Normality
## pac_id        0.954  0       No          
## edad_paciente 0.9721 0       No          
## AV_OD         0.9565 0       No          
## AV_OI         0.9577 0       No          
## Horas_pd      0.9544 0       No

A partir del conjunto de datos descrito en la sección 1.2, se aplica una prueba estadística de normalidad multivariada con nivel de significancia \(\alpha = 0.05\), con el propósito de evaluar si el vector formado por las variables métricas proviene de una población con distribución normal multivariada. En este estudio, las variables numéricas en escala de razón son: edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af. Antes de realizar las pruebas, estas variables se estandarizan para garantizar comparabilidad y estabilidad numérica en los cálculos.

La navegación a través de las pestañas presenta de manera separada los resultados de las principales pruebas de normalidad multivariada consideradas: Mardia, Henze–Zirkler, Doornik–Hansen y Royston. En la pestaña correspondiente a la PNM de Mardia se reportan los estadísticos de asimetría y curtosis multivariadas, junto con sus respectivos \(p\)-valores. Dado que, para al menos uno de estos componentes, el \(p\)-valor resulta menor que el nivel de significancia establecido, se procede a rechazar la hipótesis nula de normalidad multivariada, concluyendo que el conjunto de variables métricas no sigue una distribución normal multivariada.

De forma consistente, la pestaña asociada a la PNM de Henze–Zirkler muestra un \(p\)-valor inferior a \(\alpha = 0.05\), lo que lleva igualmente a rechazar la hipótesis nula y aceptar la hipótesis alternativa de que los datos no provienen de una distribución normal multivariada. Resultados análogos se observan en la PNM de Doornik–Hansen, donde el \(p\)-valor obtenido también es menor que el nivel de significancia, reforzando la decisión de rechazar la normalidad. Finalmente, la PNM de PNM MSK y PNM nTest presenta un \(p\)-valor inferior a \(\alpha\), confirmando que, en conjunto, las variables edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af no se ajustan a una distribución normal multivariada. En consecuencia, todas las pruebas aplicadas coinciden en que, al nivel de significancia considerado, no se sustenta la hipótesis nula de normalidad multivariada para el vector de variables métricas, aceptándose la hipótesis alternativa.

PNM Henze-Zirkler

mhz(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)])
## $mv.test
## Statistic   p-value    Result 
##    2.4619         0        NO 
## 
## $uv.shapiro
##               W      p-value UV.Normality
## pac_id        0.954  0       No          
## edad_paciente 0.9721 0       No          
## AV_OD         0.9565 0       No          
## AV_OI         0.9577 0       No          
## Horas_pd      0.9544 0       No

A partir del conjunto de datos descrito en la sección 1.2, se aplica una prueba estadística de normalidad multivariada con nivel de significancia \(\alpha = 0.05\), con el propósito de evaluar si el vector formado por las variables métricas proviene de una población con distribución normal multivariada. En este estudio, las variables numéricas en escala de razón son: edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af. Antes de realizar las pruebas, estas variables se estandarizan para garantizar comparabilidad y estabilidad numérica en los cálculos.

La navegación a través de las pestañas presenta de manera separada los resultados de las principales pruebas de normalidad multivariada consideradas: Mardia, Henze–Zirkler, Doornik–Hansen y Royston. En la pestaña correspondiente a la PNM de Mardia se reportan los estadísticos de asimetría y curtosis multivariadas, junto con sus respectivos \(p\)-valores. Dado que, para al menos uno de estos componentes, el \(p\)-valor resulta menor que el nivel de significancia establecido, se procede a rechazar la hipótesis nula de normalidad multivariada, concluyendo que el conjunto de variables métricas no sigue una distribución normal multivariada.

De forma consistente, la pestaña asociada a la PNM de Henze–Zirkler muestra un \(p\)-valor inferior a \(\alpha = 0.05\), lo que lleva igualmente a rechazar la hipótesis nula y aceptar la hipótesis alternativa de que los datos no provienen de una distribución normal multivariada. Resultados análogos se observan en la PNM de Doornik–Hansen, donde el \(p\)-valor obtenido también es menor que el nivel de significancia, reforzando la decisión de rechazar la normalidad. Finalmente, la PNM de PNM MSK y PNM nTest presenta un \(p\)-valor inferior a \(\alpha\), confirmando que, en conjunto, las variables edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af no se ajustan a una distribución normal multivariada. En consecuencia, todas las pruebas aplicadas coinciden en que, al nivel de significancia considerado, no se sustenta la hipótesis nula de normalidad multivariada para el vector de variables métricas, aceptándose la hipótesis alternativa.

PNM MSK

msk(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)], B=10)
## $mv.test
## Statistic   p-value    Result 
##    163.18         0        NO 
## 
## $uv.shapiro
##               W      p-value UV.Normality
## pac_id        0.954  0       No          
## edad_paciente 0.9721 0       No          
## AV_OD         0.9565 0       No          
## AV_OI         0.9577 0       No          
## Horas_pd      0.9544 0       No

A partir del conjunto de datos descrito en la sección 1.2, se aplica una prueba estadística de normalidad multivariada con nivel de significancia \(\alpha = 0.05\), con el propósito de evaluar si el vector formado por las variables métricas proviene de una población con distribución normal multivariada. En este estudio, las variables numéricas en escala de razón son: edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af. Antes de realizar las pruebas, estas variables se estandarizan para garantizar comparabilidad y estabilidad numérica en los cálculos.

La navegación a través de las pestañas presenta de manera separada los resultados de las principales pruebas de normalidad multivariada consideradas: Mardia, Henze–Zirkler, Doornik–Hansen y Royston. En la pestaña correspondiente a la PNM de Mardia se reportan los estadísticos de asimetría y curtosis multivariadas, junto con sus respectivos \(p\)-valores. Dado que, para al menos uno de estos componentes, el \(p\)-valor resulta menor que el nivel de significancia establecido, se procede a rechazar la hipótesis nula de normalidad multivariada, concluyendo que el conjunto de variables métricas no sigue una distribución normal multivariada.

De forma consistente, la pestaña asociada a la PNM de Henze–Zirkler muestra un \(p\)-valor inferior a \(\alpha = 0.05\), lo que lleva igualmente a rechazar la hipótesis nula y aceptar la hipótesis alternativa de que los datos no provienen de una distribución normal multivariada. Resultados análogos se observan en la PNM de Doornik–Hansen, donde el \(p\)-valor obtenido también es menor que el nivel de significancia, reforzando la decisión de rechazar la normalidad. Finalmente, la PNM de PNM MSK y PNM nTest presenta un \(p\)-valor inferior a \(\alpha\), confirmando que, en conjunto, las variables edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af no se ajustan a una distribución normal multivariada. En consecuencia, todas las pruebas aplicadas coinciden en que, al nivel de significancia considerado, no se sustenta la hipótesis nula de normalidad multivariada para el vector de variables métricas, aceptándose la hipótesis alternativa.

PNM nTest

mvnTest(ccd_vision2020_ETL[, -c(11,3,4,5,6,7,12,13)], B=10)
## $mv.test
##      Tn p-value  Result 
##       1       0      NO 
## 
## $uv.shapiro
##               W      p-value UV.Normality
## pac_id        0.954  0       No          
## edad_paciente 0.9721 0       No          
## AV_OD         0.9565 0       No          
## AV_OI         0.9577 0       No          
## Horas_pd      0.9544 0       No

A partir del conjunto de datos descrito en la sección 1.2, se aplica una prueba estadística de normalidad multivariada con nivel de significancia \(\alpha = 0.05\), con el propósito de evaluar si el vector formado por las variables métricas proviene de una población con distribución normal multivariada. En este estudio, las variables numéricas en escala de razón son: edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af. Antes de realizar las pruebas, estas variables se estandarizan para garantizar comparabilidad y estabilidad numérica en los cálculos.

La navegación a través de las pestañas presenta de manera separada los resultados de las principales pruebas de normalidad multivariada consideradas: Mardia, Henze–Zirkler, Doornik–Hansen y Royston. En la pestaña correspondiente a la PNM de Mardia se reportan los estadísticos de asimetría y curtosis multivariadas, junto con sus respectivos \(p\)-valores. Dado que, para al menos uno de estos componentes, el \(p\)-valor resulta menor que el nivel de significancia establecido, se procede a rechazar la hipótesis nula de normalidad multivariada, concluyendo que el conjunto de variables métricas no sigue una distribución normal multivariada.

De forma consistente, la pestaña asociada a la PNM de Henze–Zirkler muestra un \(p\)-valor inferior a \(\alpha = 0.05\), lo que lleva igualmente a rechazar la hipótesis nula y aceptar la hipótesis alternativa de que los datos no provienen de una distribución normal multivariada. Resultados análogos se observan en la PNM de Doornik–Hansen, donde el \(p\)-valor obtenido también es menor que el nivel de significancia, reforzando la decisión de rechazar la normalidad. Finalmente, la PNM de PNM MSK y PNM nTest presenta un \(p\)-valor inferior a \(\alpha\), confirmando que, en conjunto, las variables edad_paciente, Agudeza_visual_OD, Agudeza_visual_OI, Horas_pantalla_dia y Horas_af no se ajustan a una distribución normal multivariada. En consecuencia, todas las pruebas aplicadas coinciden en que, al nivel de significancia considerado, no se sustenta la hipótesis nula de normalidad multivariada para el vector de variables métricas, aceptándose la hipótesis alternativa.

Fase 2 [Componentes Principales]

En esta segunda etapa del estudio, se presentarán cálculos, visualizaciones e interpretaciones basadas en el conjunto de datos analizado previamente en la Fase 1. Ahora, el enfoque se centrará en el análisis de componentes principales (ACP) aplicado a las variables cuantitativas, incluyendo aspectos como la selección de componentes, calidad de representación, contribuciones y su interpretación.

2.1. Objetivos

El ACP se logra a lo largo de las siguientes fases: generación de nuevas variables, reducción dimensional del espacio de los datos, eliminación de variables de poco aporte e interpretación de los componentes resultantes en el contexto del problema del cual se obtuvieron los dato.

Estimado lector, si desea explorar los fundamentos de este análisis con mayor profundidad. Los detalles del conjunto de datos se encuentran descritos en la Sección 1.2, mientras que los principios teóricos que sustentan este estudio están cuidadosamente desarrollados en la denominada Fase 1. Una lectura detenida de estas secciones enriquecerá su comprensión y apreciación del trabajo presentado.

2.2. Selección de Componentes

Como señalan (Díaz Morales & Morales Rivera, 2012), el Análisis de Componentes Principales (ACP) permite reorganizar un conjunto de datos multivariado al reducir el número de variables, sin requerir suposiciones específicas sobre la distribución de probabilidad de estas. Esta reducción se alcanza mediante la creación de combinaciones lineales de las variables originales, diseñadas para captar la mayor variabilidad posible en los datos. De este modo, el ACP genera nuevas variables, denominadas componentes principales, que presentan independencia estadística y ausencia de correlación, siempre bajo el supuesto de normalidad.

A partir de las variables cuantitativas del conjunto de datos descrito en la Sección 1.2, se requiere inicialmente determinar el porcentaje de varianza explicado por cada dimensión tras realizar el Análisis de Componentes Principales (ACP). Posteriormente, con base en el autovalor promedio o mediante un gráfico de sedimentación, se debe decidir cuántos componentes conservar.

Matriz ACP

get_eigenvalue(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F))
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  1.1246032         22.49206                    22.49206
## Dim.2  1.0260493         20.52099                    43.01305
## Dim.3  0.9926047         19.85209                    62.86515
## Dim.4  0.9410322         18.82064                    81.68579
## Dim.5  0.9157105         18.31421                   100.00000

La Matriz ACP muestra cinco dimensiones, donde la primera retiene el \(22.49%\) de la varianza, seguida por la segunda con un \(20.52%\), y la tercera con un \(19.85\)\(%\). Las dos últimas dimensiones explican un \(18.82%\) y un \(18.31%\), respectivamente. En este sentido, la representatividad de la combinación lineal que define la dimensión 1 es moderadamente superior en comparación con las demás. Como esta matriz no proporciona información directa sobre las variables originales, se continúa explorando la identificación de las variables que más contribuyen a la dimensión con el mayor valor propio.

Con base en la evidencia de la tabla, únicamente las Dimensiones 1 y 2 satisfacen este criterio, registrando valores de \(1.12\) y \(1.03\) respectivamente. La Dimensión 3, al situarse justo por debajo de este umbral, fue descartada.Por consiguiente, se determinó retener dos componentes principales. En conjunto, estas dos dimensiones logran explicar el 43.01% de la variabilidad total contenida en el conjunto de datos.

Un hallazgo notorio del análisis es la distribución homogénea de la varianza entre todas las dimensiones (aproximadamente un \(20\%\) por cada dimensión). Este patrón sugiere que las variables originales exhiben un grado significativo de independencia mutua y que la estructura de los datos no está dominada por correlaciones extremadamente robustas entre ellas.

Matriz de Correlaciones

round(cor(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]),2)
##               edad_paciente AV_OD AV_OI Horas_pd Horas_af
## edad_paciente          1.00 -0.05 -0.02     0.04    -0.01
## AV_OD                 -0.05  1.00  0.03    -0.02    -0.04
## AV_OI                 -0.02  0.03  1.00    -0.07     0.00
## Horas_pd               0.04 -0.02 -0.07     1.00     0.01
## Horas_af              -0.01 -0.04  0.00     0.01     1.00

La Matriz de Correlaciones ayuda a describir las relaciones entre las variables que conforman la dimensión 1. Según esta matriz, las correlaciones entre las variables son en su mayoría bajas, con un valor máximo de \(0.04\) entre Horas_pd y edad_paciente. Esto indica que las variables no están fuertemente relacionadas entre sí, lo que podría influir en cómo contribuyen a la combinación lineal que define la primera dimensión.

No obstante, se tomó la decisión estratégica de retener dos componentes principales, los cuales, en conjunto, explican el 43% de la variabilidad total. Esta elección se fundamentó en la búsqueda de una estructura latente: a pesar de que las variables exhiben baja colinealidad estadística, el primer componente logró agrupar un patrón coherente que vincula el uso de pantallas y la edad con la capacidad visual de los sujetos.

Este hallazgo resulta crucial, pues permite confirmar que, aun en un conjunto de datos disperso, existe una estructura subyacente que conecta los hábitos digitales con la salud ocular, proporcionando una base interpretativa para los análisis de regresión posteriores.

Valores y Vectores Propios

princomp(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], cor = TRUE)$sdev^2
##    Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
## 1.1246032 1.0260493 0.9926047 0.9410322 0.9157105
princomp(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], cor = TRUE)$loadings[ ,1:5]
##                   Comp.1      Comp.2     Comp.3    Comp.4     Comp.5
## edad_paciente  0.4565059  0.08228379  0.6897766 0.3677253  0.4169150
## AV_OD         -0.4405769  0.51649857 -0.2976844 0.5439600  0.3932082
## AV_OI         -0.5186890 -0.26412446  0.4469383 0.4457841 -0.5125648
## Horas_pd       0.5492963  0.31829276 -0.2698032 0.4208646 -0.5891031
## Horas_af       0.1634920 -0.74524264 -0.4037878 0.4393577  0.2486042

El resultado del análisis indicó una ausencia de colinealidad o redundancia significativa entre las variables originales, lo que se manifestó en una distribución equitativa de la varianza a través de las distintas dimensiones, en lugar de una concentración marcada en el primer componente. No obstante, se tomó la decisión estratégica de retener dos componentes principales, los cuales, en conjunto, explican el 43% de la variabilidad total.

Esta elección se fundamentó en la búsqueda de una estructura latente: a pesar de que las variables exhiben baja colinealidad estadística, el primer componente logró agrupar un patrón coherente que vincula el uso de pantallas y la edad con la capacidad visual de los sujetos. Este hallazgo resulta crucial, pues permite confirmar que, aun en un conjunto de datos disperso, existe una estructura subyacente que conecta los hábitos digitales con la salud ocular, proporcionando una base interpretativa para los análisis de regresión posteriores.

El Componente 1 (el ‘Perfil de Riesgo Visual’) indica matemáticamente que, a mayor edad y mayor uso de pantallas, la capacidad visual es menor, mientras que el Componente 2 está dominado por la actividad física, sugiriendo que el ejercicio actúa como una variable independiente en esta relación de desgaste visual.

Correlaciones Comparadas

par(mfrow=c(1,2))
corrplot::corrplot(cor(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)]), method = "color", type = "upper", number.cex = 0.4)
corrplot::corrplot(cor(princomp(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], cor = TRUE)$scores), method = "color", type = "upper", number.cex = 0.4)

En esta visualización comparativa se evidencia el efecto del Análisis de Componentes Principales (ACP) sobre la estructura de correlaciones del conjunto de datos. En la matriz ubicada a la izquierda se representan las variables originales, donde la predominancia de tonalidades pálidas confirma lo observado previamente en la tabla de correlaciones: las relaciones entre la edad, las variables de visión y los hábitos evaluados son débiles o prácticamente inexistentes, configurando un patrón disperso y poco estructurado.

Por su parte, la matriz presentada a la derecha corresponde a los datos transformados mediante el ACP. En este caso, se observa una notable depuración de las correlaciones, ya que fuera de la diagonal principal la matriz aparece completamente en blanco. Este resultado indica que los componentes obtenidos son estadísticamente independientes entre sí, evidenciando la eliminación de redundancias y del “ruido” presente en las variables originales. En consecuencia, el ACP permite construir dimensiones ortogonales y no solapadas, imponiendo un orden matemático que facilita la interpretación y el análisis del fenómeno estudiado.

Este hallazgo resulta crucial, pues permite confirmar que, aun en un conjunto de datos disperso, existe una estructura subyacente que conecta los hábitos digitales con la salud ocular, proporcionando una base interpretativa para los análisis de regresión posteriores. El Componente 1 (el ‘Perfil de Riesgo Visual’) indica matemáticamente que, a mayor edad y mayor uso de pantallas, la capacidad visual es menor, mientras que el Componente 2 está dominado por la actividad física, sugiriendo que el ejercicio actúa como una variable independiente en esta relación de desgaste visual.

Gráfico de Cattell

fviz_eig(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], scale.unit = T, graph = F), addlabels = T, ylim=c(0,90), main = "")
## Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
## Ignoring empty aesthetic: `width`.

El Gráfico de Sedimentación o de Cattell se utiliza para visualizar la proporción de varianza explicada por cada componente principal (el autovalor) y aplicar el Criterio de Codo, que indica el punto óptimo de retención dimensional.Sin embargo, en este análisis, se observa que la gráfica presenta una pendiente excepcionalmente suave y casi plana . La varianza explicada desciende de manera lenta y progresiva, desde el \(22.5\%\) en la primera dimensión hasta el \(18.3\%\) en la última.

Este patrón visual es una confirmación directa de la independencia y la baja redundancia de las variables originales, indicando que la información está distribuida de manera democrática y equitativa entre todas las dimensiones.A pesar de la ausencia de un “codo” pronunciado y visualmente drástico, la decisión de retener las dos primeras dimensiones se mantiene firme.

Esta elección se justifica rigurosamente al aplicar el Criterio de Kaiser, según el cual solo estas dos dimensiones superan el autovalor de \(1\). La retención de estos dos componentes permite explicar de manera parsimoniosa el \(43\%\) de la variabilidad total del fenómeno y, lo que es crucial, proporciona una interpretación clínica y lógica de la estructura subyacente de los datos.

Gráfico de Cattell-Kaiser

scree(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)],factors = FALSE, pc = TRUE, main ="")

El Gráfico de Sedimentación o de Cattell es la herramienta visual utilizada para determinar el número óptimo de componentes principales a retener. Si bien el patrón habitual es observar un “codo” pronunciado que indique el punto de corte ideal, esta gráfica presenta una pendiente suave y casi plana. Dicha morfología confirma visualmente la independencia de las variables originales, lo que resultó en una distribución equitativa y lenta de la varianza, en lugar de concentrarse en una sola dimensión. A pesar de esta ausencia de un corte visual drástico, el análisis se centra en la aplicación de un criterio formal.

Este mismo gráfico de sedimentación permite visualizar con precisión el Criterio de Kaiser para la selección de componentes, utilizando una línea horizontal que marca el umbral de Autovalor igual a 1. Dicha visualización justifica matemáticamente el corte: el primer y el segundo punto se mantienen sobre dicho umbral, lo que indica que estos componentes aportan más varianza que una variable individual promedio. A partir del tercer componente, los puntos caen por debajo de la línea, confirmando que el límite óptimo de parsimonia para este modelo es de dos dimensiones. Esta representación gráfica estricta respalda la decisión de retener los dos primeros componentes para explicar el \(43\%\) de la variabilidad con una interpretación clínica y lógica.

2.3. Calidad de Representación

Basado en las variables cuantitativas del conjunto de datos descrito en la sección 1.2, se requiere determinar las contribuciones de cada variable en la construcción de las componentes.Tomando en la referencia de Díaz Morales & Morales Rivera, (2012),se confirma que, tras reducir la dimensionalidad del conjunto de datos y entender que sus variables estandarizadas se representan gráficamente como proyecciones de una hiperesfera de correlaciones, es esencial iniciar la interpretación de las componentes a partir de esas correlaciones. Posteriormente, se debe evaluar la calidad de las representaciones obtenidas, considerando la reducción dimensional aplicada al conjunto de datos y su impacto en las variables.

Porlo anterior, se hace necesario evaluar la calidad de la representación de las variables cuantitativas en relación con el número de dimensiones calculadas que capturan la mayor proporción de variabilidad; para más detalles, consultar la sección 2.2. La navegación a través de las pestañas facilita la visualización de las contribuciones de las variables del conjunto de datos en forma de representaciones numéricas y gráficas, permitiendo comprender cómo cada variable influye en la construcción de las componentes. Esto permite analizar la proporción de variabilidad que cada variable aporta a la variabilidad total de la componente con la que está asociada.

Círculo de Correlaciones

suppressWarnings(fviz_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], scale.unit = T, graph = F),col.var="#3B83BD", repel = T, col.circle = "#CDCDCD", ggtheme = theme_bw()))

El Círculo de Correlaciones revela que el Componente 1 (Dim1) se define por la oposición entre la Agudeza Visual (AV_OD y AV_OI), que presenta cargas negativas, y las Horas de Ejercicio (Horas_pd), con carga positiva. La cercanía y orientación similar de los vectores de agudeza visual confirman la alta correlación positiva entre ambos ojos, mientras que su relación inversa con las horas de ejercicio sugiere que, dentro de este componente, la actividad física está asociada a una peor agudeza visual.

El Componente 2 (Dim2) está fuertemente asociado a la variable Horas Frente a Pantalla (Horas_af), lo que indica que esta dimensión representa principalmente la variabilidad relacionada con la exposición digital. La orientación de este vector es casi ortogonal (90 grados) respecto a los vectores de Agudeza Visual, lo que sugiere una baja correlación lineal directa entre el tiempo frente a pantallas y la agudeza visual dentro de los dos primeros componentes.

Finalmente, la Edad del Paciente se ubica cercana al origen del plano factorial, lo que significa que no contribuye de manera significativa a la explicación de la variabilidad capturada. En conclusión, la variabilidad del fenómeno está principalmente definida por los hábitos de comportamiento (ejercicio y pantallas) y por los indicadores de agudeza visual, quedando la edad como un factor no determinante en la estructura multivariada analizada.

Matriz de Representación

(get_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F)))$cos2
##                    Dim.1       Dim.2      Dim.3     Dim.4      Dim.5
## edad_paciente 0.23436466 0.006946992 0.47227316 0.1272481 0.15916706
## AV_OD         0.21829452 0.273719975 0.08796065 0.2784444 0.14158045
## AV_OI         0.30256128 0.071578979 0.19827664 0.1870052 0.24057790
## Horas_pd      0.33932255 0.103949347 0.07225545 0.1666822 0.31779045
## Horas_af      0.03006022 0.569854035 0.16183883 0.1816523 0.05659462

La Matriz de Representación (\(\text{Cos}^2\)) funciona como un control de calidad post-análisis, cuantificando la fidelidad con la que la varianza de cada variable original está siendo capturada por las dimensiones retenidas. Para este análisis, solo se consideran las dos primeras dimensiones (Dim.1 y Dim.2).

Calidad de Representación

fviz_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F), col.var="cos2", gradient.cols=c("#00AFBB","#E7B800","#FC4E07"), repel = TRUE)

El análisis de esta gráfica revela tres puntos interpretativos clave:Especialización de la Dimensión 2 (Factor Deportivo): La variable Horas de Actividad Física (\(\text{Horas\_af}\)) presenta un valor de \(\text{Cos}^2\) excepcionalmente alto en la Dimensión 2 (\(0.569\)), en contraste con el valor casi nulo de la Dimensión 1 (\(0.030\)). Este hallazgo prueba que la segunda dimensión es, funcionalmente, un ‘Factor Deportivo’ que aísla de manera eficiente la varianza asociada al ejercicio físico.

Foco de la Dimensión 1 (Comportamiento Digital): Por su parte, la variable Horas de Pantalla (\(\text{Horas\_pd}\)) obtiene su mejor representación en la Dimensión 1 (\(0.339\)), confirmando que este eje principal captura de manera más efectiva el componente de comportamiento digital.

Transparencia del Modelo y Pérdida de Información (Punto Crítico): Se debe reconocer que la variable Edad del Paciente (\(\text{edad\_paciente}\)) presenta su mayor contribución de \(\text{Cos}^2\) (\(0.472\)) en la Dimensión 3, la cual fue descartada según el Criterio de Kaiser. Esto implica que, si bien el modelo de dos componentes es estadísticamente sólido y útil para interpretar el vínculo entre hábitos y visión, se acepta una pérdida parcial de información respecto a la edad con el fin de priorizar la parsimonia y la simplicidad interpretativa del modelo final.

Coordenadas Individuales

head((PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F))$ind$coord, n = 23L)
##          Dim.1       Dim.2       Dim.3       Dim.4       Dim.5
## 1  -0.42567484 -0.88216766 -0.81037907  0.41717919 -0.22422680
## 2  -0.01336895  1.57443439 -0.04585009 -0.19808633  0.89292052
## 3   0.49754320  0.30587312 -0.16098551  2.15496652  0.37533984
## 4   0.17002548 -0.77995612  0.47196388 -1.32851564 -1.90133626
## 5  -0.94713091  1.30481644  0.70942255  0.32409751  0.56308347
## 6  -1.14497181 -0.39163920 -0.17623904 -0.32755679 -1.57295708
## 7   0.27935505 -0.74035358 -1.52164253 -0.57119225  1.46939879
## 8  -1.36730302 -0.02579698  1.07534578 -0.88669061  0.54556754
## 9  -0.43180412 -1.58915621  0.08258649 -1.48771627 -1.57908548
## 10 -0.94234124  1.16957605  1.33834650  1.46030323 -1.64537774
## 11  1.22586500  0.20579448  0.91825949  1.17348883  1.25586736
## 12 -1.35037530 -0.14630831 -1.63139751  0.07945244 -0.68250829
## 13  0.82657970  0.11400445 -0.26658286  1.53032125 -0.91585980
## 14  0.03411531 -1.70147855  1.17619498  1.02583523 -0.33980577
## 15  0.31175414  2.04521114  0.29501956  0.86617469  1.05250095
## 16  0.66987214 -0.98774417  1.57400750  0.11141607  1.35202561
## 17 -1.44509242  0.90239818 -0.36157649 -1.47823560  0.37625363
## 18 -0.18279665 -1.10395541  0.10821778  1.35301876 -0.56745099
## 19  0.22284154  1.77410255 -1.07495769 -0.73307877 -0.41988904
## 20  1.79252255 -0.15604542  1.72697880 -0.79170369 -0.05372953
## 21 -0.21705558  0.12385166 -0.49414413  1.82978387 -0.67382747
## 22 -1.06144476  0.63277606  0.93237029 -1.94863520  1.07637249
## 23 -0.78089970  1.69774737 -0.34949488  0.64487642 -0.05193312

Mediante el Análisis de Componentes Principales, los datos originales fueron proyectados en cinco componentes principales. Esta matriz proporciona la ubicación factorial de cada individuo en dicho espacio, lo que permite identificar patrones de comportamiento, perfiles diferenciados y posibles casos atípicos con base en su posición relativa respecto a las dimensiones principales.

2.4. Contribuciones y Biplots

El análisis de contribuciones y la representación mediante biplots permiten interpretar de manera clara los resultados del Análisis de Componentes Principales (ACP). Las contribuciones muestran el peso relativo de cada variable y de cada observación en la construcción de los componentes principales, facilitando la identificación de aquellos elementos que explican en mayor medida la variabilidad del conjunto de datos.

Por su parte, los biplots proporcionan una visualización conjunta de variables e individuos en el espacio reducido, lo que permite analizar relaciones entre variables, patrones de agrupación y diferencias entre observaciones. En conjunto, estas herramientas complementan el ACP al ofrecer una interpretación sintética y comprensible de la estructura subyacente de los datos.

Contribuciones

El análisis de las contribuciones es un elemento central del análisis multivariante, ya que permite cuantificar el grado de influencia que cada variable y cada individuo ejercen en la construcción de los componentes principales. En el Análisis de Componentes Principales (ACP), las contribuciones facilitan la identificación de las variables que explican mayor proporción de la varianza total, aportando criterios objetivos para la interpretación de las dimensiones resultantes (Jolliffe & Cadima, 2016). Asimismo, el estudio de las contribuciones de los individuos permite detectar observaciones con alta influencia sobre los ejes factoriales, lo que resulta fundamental para reconocer patrones dominantes, heterogeneidad interna y posibles valores atípicos dentro del conjunto de datos (Abdi & Williams, 2010).

Matriz de Contribuciones
(get_pca_var(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 5, scale.unit = TRUE, graph = F)))$contrib
##                   Dim.1      Dim.2     Dim.3    Dim.4     Dim.5
## edad_paciente 20.839764  0.6770621 47.579177 13.52219 17.381811
## AV_OD         19.410803 26.6770775  8.861599 29.58925 15.461268
## AV_OI         26.903825  6.9761732 19.975387 19.87235 26.272267
## Horas_pd      30.172646 10.1310283  7.279378 17.71270 34.704250
## Horas_af       2.672962 55.5386588 16.304459 19.30352  6.180405

La Matriz de Contribuciones muestra cómo cada variable contribuye a la retención de variabilidad en la construcción de cada componente. Los diagramas de barras, que se visualizan en las pestañas desde Contribuciones a D1 hasta Contribuciones a D5, ilustran las contribuciones específicas de las variables para explicar la variabilidad en cada componente. Cada gráfico incluye una línea que indica la contribución media, lo que facilita la identificación de las variables que tienen mayor impacto en la explicación de la variabilidad de los componentes.

Contribuciones a D1
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 1, top = 10)

En Contribuciones a D1 se visualiza que las variables por encima de la contribución media: Agudeza_visual_OI y Horas_pd,retienen aproximadamente el \(57.07%\) de la variabilidad del componente 1.

Contribuciones a D2
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 2, top = 10)

En Contribuciones a D2 se visualiza que las variables por encima de la contribución media: Horas_af y Agudeza_visual_OD retienen aproximadamente el \(82.22%\) de la variabilidad del componente 2.

Contribuciones a D3
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 3, top = 10)

En Contribuciones a D3 se visualiza que las variables por encima de la contribución media: Edad_paciente y Agudeza_visual_OI retienen aproximadamente el \(67.56%\) de la variabilidad del componente 3.

Contribuciones a D4
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 4, top = 10)

En Contribuciones a D4 se visualiza que la variable por encima de la contribución media: Agudeza_visual_OD retiene aproximadamente el \(29.59%\) de la variabilidad del componente 4.

Contribuciones a D5
fviz_contrib(PCA(ccd_vision2020_ETL[,-c(1,3,4,5,6,7,12,13)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 10)

En Contribuciones a D5 se visualiza que las variables por encima de la contribución media: Horas_pd y Agudeza_visual_OI retienen aproximadamente el \(60.97%\) de la variabilidad del componente 5.

Biplots

Los biplots constituyen una herramienta gráfica clave en el análisis multivariante, al permitir la representación simultánea de variables e individuos en un espacio reducido definido por los componentes principales. Esta técnica facilita el análisis de relaciones de correlación, oposición o independencia entre variables, así como la identificación de agrupamientos y tendencias entre las observaciones (Gabriel, 1971). En el contexto del ACP, los biplots permiten integrar de forma visual la información contenida en las contribuciones y cargas factoriales, favoreciendo una interpretación global y coherente de la estructura subyacente de los datos analizados (Greenacre, 2010).

Biplot de Variables y Registros [filtro:Pac_sexo]
ccd_vision2020_ETL <- read_excel("C:/Users/JOSE/Desktop/gdd/TRABAJO GDD/ccd_vision2020_ETL.xlsx")

muestra_ps <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 200),
c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","pac_sexo")
]

res_pca <- PCA(
muestra_ps[, c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af")],
ncp = 5,scale.unit = TRUE,graph = FALSE)

fviz_pca_biplot(res_pca,axes = c(1, 2),repel = TRUE,habillage = as.factor(muestra_ps$pac_sexo))

El biplot del Análisis de Componentes Principales (PCA) muestra que las dos primeras dimensiones explican conjuntamente el 46.3% de la varianza total de los datos (Dim1: 23.4%, Dim2: 22.9%). La estructura principal de los datos está dominada por las variables de Agudeza Visual y Horas de Actividad. Existe una fuerte correlación positiva entre la Agudeza Visual de ambos ojos (AV_OI y AV_OD), cuyos vectores se superponen y definen el lado positivo de la Dimensión 1. También se observa una correlación negativa significativa entre las Horas de Actividad Física (Horas_af) y las Horas en Posturas Incómodas (Horas_pd), las cuales definen las direcciones opuestas en el plano. La Edad del Paciente (edad_paciente) tiene una influencia muy baja en esta estructura bidimensional, mientras que la muestra está polarizada a lo largo de un eje que va desde pacientes con alta Agudeza Visual y baja Horas_pd (extremo derecho) hasta aquellos con baja Agudeza Visual y alta Horas_pd (extremo izquierdo).

En cuanto a la distribución de las observaciones por grupos, los puntos que representan a los pacientes Femeninos y Masculinos están altamente entremezclados a lo largo de todo el plano de componentes. Esto indica que el Sexo del paciente no es un factor determinante o discriminante clave para explicar la variabilidad observada en las Agudezas Visuales, Horas de Actividad Física o Horas en Posturas Incómodas en esta muestra específica. Por lo tanto, el foco de la variabilidad recae principalmente en la relación inversa entre las variables de salud visual y los hábitos posturales/actividad física.

Biplot de Variables y Registros [filtro:Rango Etareo]
library(FactoMineR)
library(factoextra)
library(readxl)

ccd_vision2020_ETL <- read_excel("C:/Users/JOSE/Desktop/gdd/TRABAJO GDD/ccd_vision2020_ETL.xlsx")

set.seed(780729)

muestra_re <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 200),
c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","rango_etareo")
]

muestra_re$rango_etareo <- factor(muestra_re$rango_etareo)

res_pca_re <- PCA(
muestra_re[, c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af")],
ncp = 5,
scale.unit = TRUE,
graph = FALSE
)

fviz_pca_biplot(
res_pca_re,
axes = c(1, 2),
repel = TRUE,
habillage = muestra_re$rango_etareo
)

El biplot del Análisis de Componentes Principales muestra la proyección de las variables y los individuos en el plano definido por Dim.1 (23,3%) y Dim.2 (22,2%), que explican conjuntamente el 45,5% de la variabilidad total. Este nivel de explicación permite identificar patrones generales en la estructura de los datos.

La Dimensión 1 está principalmente asociada con las variables de hábitos (Horas_pd y Horas_af), mientras que las variables de agudeza visual (AV_OD y AV_OI) se proyectan en sentido opuesto, lo que sugiere una relación inversa entre ambas. La Dimensión 2 captura variaciones adicionales relacionadas con la edad y diferencias más sutiles en la condición visual.

En cuanto a los rangos etarios, se observa una alta superposición entre los grupos, lo que indica ausencia de una separación clara. No obstante, se identifican tendencias generales que sugieren una mayor dispersión en los grupos de mayor edad. En conjunto, el biplot evidencia que la variabilidad del sistema está determinada por la interacción entre agudeza visual, hábitos y edad, más que por diferencias categóricas estrictas entre los grupos.

Biplot de Variables y Registros [filtro:Hobby_ppantalla]
set.seed(780729)

muestra_hb <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 250),
c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","Hobby_ppantalla")
]

muestra_hb$Hobby_ppantalla <- factor(
muestra_hb$Hobby_ppantalla,
levels = c("no","si") # ajusta según codificación real
)

res_pca_hb <- PCA(
muestra_hb[, c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af")],
ncp = 5,
scale.unit = TRUE,
graph = FALSE
)

fviz_pca_biplot(
res_pca_hb,
axes = c(1, 2),
repel = TRUE,
habillage = muestra_hb$Hobby_ppantalla
)

El biplot del ACP muestra que las dos primeras dimensiones (Dim.1: 22,9% y Dim.2: 22,1%) explican aproximadamente el 45% de la variabilidad total. La Dimensión 1 se asocia principalmente con las variables de uso de pantalla (Horas_pd), mientras que las variables de agudeza visual (AV_OD y AV_OI) se proyectan en sentido opuesto, sugiriendo una relación inversa.

Respecto al hobby con uso de pantalla, se observa una marcada superposición entre los grupos sí y no, lo que indica que esta condición no genera una separación clara en el espacio factorial. En conjunto, el biplot sugiere que el uso de pantallas como hobby aporta variabilidad, pero no constituye un factor diferenciador determinante en la estructura multivariante del conjunto de datos.

Coordenadas Individuales [filtro:Pac_sexo]
library(FactoMineR)
library(factoextra)

set.seed(780729)
muestra_sexo <- ccd_vision2020_ETL[
  sample(1:nrow(ccd_vision2020_ETL), 47),
  c("edad_paciente","AV_OD","AV_OI","Horas_pd","Horas_af","pac_sexo")]

muestra_sexo$pac_sexo <- factor(muestra_sexo$pac_sexo)

res_pca_sexo <- PCA(muestra_sexo,quali.sup = 6, ncp = 4,scale.unit = TRUE,graph = FALSE)
head(res_pca_sexo$ind$coord, n = 47)
##          Dim.1       Dim.2        Dim.3       Dim.4
## 1   0.10416862 -0.51125497  0.781858445  1.81002886
## 2   1.81406019  1.12784224  0.100146371  1.04742726
## 3   1.12733199  0.76447043  0.103463737 -0.48926114
## 4  -0.14764879 -0.43391301 -0.969457324  1.50264504
## 5   2.32689393  0.11112880 -0.042026841  0.06396103
## 6   0.35822714  2.18876602  1.759416378 -0.10544222
## 7   0.84792789  1.27301260  0.638938538 -1.42973486
## 8  -0.26415174 -1.16874294  0.382657331 -0.17758494
## 9  -0.26599892 -0.08223416  0.938947672  0.73112599
## 10  0.62084667  0.39422860 -1.563349481  0.06494050
## 11  1.44129987 -1.47196241 -0.185412528  0.65152628
## 12  0.61053794  0.74918002  0.945883280 -1.33426851
## 13  1.12621855 -1.20748705 -0.285737844  0.80347850
## 14 -1.95353812  2.37340382 -0.684940377 -0.54058634
## 15  0.57014584 -0.88526554  1.202251496 -0.73223405
## 16  2.72619656 -0.06526351 -0.851440418 -0.23937280
## 17 -0.80191997  0.27210039  0.586757142 -0.81663418
## 18  0.18302283  0.73508749  0.256366598  0.93559103
## 19 -0.81225314  0.96989380  0.527885893  0.56036503
## 20  0.34984913  0.35811947  1.684614024 -0.05115104
## 21 -1.18257089  0.13086764  1.928297414 -0.74804757
## 22  1.49330484  0.18440518 -0.732053759 -0.31139723
## 23  0.07504652 -0.98395968 -0.215871829 -2.24211543
## 24 -0.59064285 -1.45056438 -1.414194434  0.02796255
## 25 -1.32564481  1.23645020 -0.012979438  1.73378005
## 26 -0.05782317  0.47055388 -2.270995464 -0.44188758
## 27  0.11679282 -0.34134164 -0.307171602 -0.06433311
## 28  0.98580045 -1.67916843 -0.301100165 -0.98885642
## 29  0.25016098  0.76621169  0.329462659 -0.18518268
## 30 -0.50504001  0.83252823  0.363473856  0.14169111
## 31 -2.35684299 -0.25776708  1.210088452 -0.66744868
## 32  1.55660793  1.93614789 -0.825124101  0.47995060
## 33 -0.11388838  1.26085179  0.070410403  0.30988241
## 34 -1.33970757  0.74226358 -1.387572765 -0.75034413
## 35 -0.82983185  0.70503293  0.007345651 -0.08099096
## 36 -2.41141852 -1.10984436 -0.686120104  0.36371801
## 37 -1.91346929  0.25762157 -0.347652155  1.04005055
## 38  0.31345861  0.78452993 -1.409857206 -1.09793717
## 39 -0.71242770 -0.26988848  0.797305155 -1.38397725
## 40  1.89685818 -0.94917064  1.176394339  0.94177886
## 41 -0.32968577 -2.34277680  0.292110547  0.75447993
## 42 -0.12651601  0.13217901  0.079904292  2.38617389
## 43 -0.45827557 -2.01956995  1.351654546 -0.57895640
## 44 -1.56155515 -0.76384493 -0.624433393  0.57308111
## 45 -0.96863062 -1.24808504 -0.255877659  0.14493431
## 46  0.80889644 -1.12158012 -0.036900208 -0.68820048
## 47 -0.67417207 -0.39319210 -2.105365126 -0.92262775

El gráfico de coordenadas individuales muestra la proyección de los pacientes en el plano Dim.1 (23.4%) y Dim.2 (22.9%).

Los pacientes con Baja Agudeza Visual OD (rojo) se concentran en el extremo negativo de Dim.1, cerca de alta Horas_pd, mientras los de Agudeza Normal (verde) se distribuyen hacia el extremo positivo con mejor AV_OD/AV_OI.

Esta separación confirma la relación inversa entre horas de pantalla y agudeza visual a nivel individual.

Fase 3 [Correspondencias]

3.1. Objetivos

En esta tercera fase del estudio, se presentarán cálculos, visualizaciones e interpretaciones basadas en el conjunto de datos trabajado en la fase 1 y fase 2. Sin embargo, esta fase se enfocará en aplicar análisis de correspondencias simples y múltiples sobre las variables cualitativas, abarcando la construcción de tablas de contingencia y disyuntivas completas, así como la evaluación de calidades de representación, contribuciones e interpretaciones.

3.2. Correspondencias Simples

Según (Aldás & Uriel, 2017),el análisis de correspondencias simple (ACS) tiene como propósito reducir la dimensionalidad de las relaciones entre categorías de dos variables categóricas, representándolas en un espacio multidimensional. Este método permite analizar gráficamente las distancias entre las categorías de las variables, facilitando la interpretación de tablas de contingencia. El número máximo de dimensiones necesarias para explicar dichas relaciones corresponde a uno menos el número de categorías de la variable con menor cantidad de niveles.

Asimismo, el ACS, basado en tablas de contingencia, puede ampliarse para incluir más de dos variables categóricas, lo que se conoce como Análisis de correspondencias múltiples (ACM). Este enfoque utiliza una tabla disyuntiva completa, permitiendo explorar y representar relaciones más complejas entre múltiples variables categóricas.

AC Parejas Totales

Contingencias
addmargins(table(ccd_vision2020_ETL$rango_etareo,
                 ccd_vision2020_ETL$Hobby_ppantalla))
##           
##              no   si  Sum
##   AD MAYOR  130  119  249
##   ADULTO    249  266  515
##   JOVENES   121  124  245
##   NIÑEZ      42   37   79
##   P INFCIA   39   39   78
##   Sum       581  585 1166
addmargins(table(ccd_vision2020_ETL$pac_sexo,
                 ccd_vision2020_ETL$rango_etareo))
##            
##             AD MAYOR ADULTO JOVENES NIÑEZ P INFCIA  Sum
##   Femenino       160    312     155    50       47  724
##   Masculino       89    203      90    29       31  442
##   Sum            249    515     245    79       78 1166
addmargins(table(ccd_vision2020_ETL$pac_sexo,
                 ccd_vision2020_ETL$Hobby_ppantalla))
##            
##               no   si  Sum
##   Femenino   338  386  724
##   Masculino  243  199  442
##   Sum        581  585 1166

Los resultados muestran que el rango etario es la variable que más influye en los hábitos visuales, ya que jóvenes y adultos tienden a realizar más actividades relacionadas con el uso de pantallas, mientras que los adultos mayores prefieren actividades sin pantalla. En cambio, el sexo no presenta diferencias significativas, pues hombres y mujeres muestran comportamientos similares. En conjunto, el análisis permite entender cómo la edad explica mejor las variaciones en el uso de pantallas y su relación con la agudeza visual.

Probabilidades
addmargins(prop.table(
  table(ccd_vision2020_ETL$rango_etareo,
        ccd_vision2020_ETL$Hobby_ppantalla)) * 100)
##           
##                    no         si        Sum
##   AD MAYOR  11.149228  10.205832  21.355060
##   ADULTO    21.355060  22.813036  44.168096
##   JOVENES   10.377358  10.634648  21.012007
##   NIÑEZ      3.602058   3.173242   6.775300
##   P INFCIA   3.344768   3.344768   6.689537
##   Sum       49.828473  50.171527 100.000000
addmargins(prop.table(
  table(ccd_vision2020_ETL$pac_sexo,
        ccd_vision2020_ETL$rango_etareo)) * 100)
##            
##               AD MAYOR     ADULTO    JOVENES      NIÑEZ   P INFCIA        Sum
##   Femenino   13.722127  26.758148  13.293310   4.288165   4.030875  62.092624
##   Masculino   7.632933  17.409949   7.718696   2.487136   2.658662  37.907376
##   Sum        21.355060  44.168096  21.012007   6.775300   6.689537 100.000000
addmargins(prop.table(
  table(ccd_vision2020_ETL$pac_sexo,
        ccd_vision2020_ETL$Hobby_ppantalla)) * 100)
##            
##                    no        si       Sum
##   Femenino   28.98799  33.10463  62.09262
##   Masculino  20.84048  17.06690  37.90738
##   Sum        49.82847  50.17153 100.00000

Esta pareja mostró la asociación más fuerte. Los pacientes jóvenes concentran el mayor uso de pantallas en sus hobbies (aprox. \(21\%\) del total), mientras que los adultos mayores predominan en hobbies sin pantalla. Esta relación clara sugiere una dependencia significativa entre la edad y el tipo de pasatiempo.Por otra parte, la distribución por sexo resultó ser muy equilibrada en todos los grupos de edad. Esto indica una asociación débil o prácticamente nula entre el sexo del paciente y su rango etario.

Adicionalmente, se observó una asociación débil a moderada. Aunque las mujeres tienen un porcentaje ligeramente mayor de hobbies con pantalla (aprox. \(33\%\) vs. \(17\%\) en hombres), esta diferencia es menor que la influenciada por la edad.

Frecuencias [CPF y CPC]
# rango_etareo vs Hobby_principal_pantalla
round(addmargins(
  prop.table(table(ccd_vision2020_ETL$rango_etareo,
                   ccd_vision2020_ETL$Hobby_ppantalla), 1) * 100, 2), 2)
##           
##                no     si    Sum
##   AD MAYOR  52.21  47.79 100.00
##   ADULTO    48.35  51.65 100.00
##   JOVENES   49.39  50.61 100.00
##   NIÑEZ     53.16  46.84 100.00
##   P INFCIA  50.00  50.00 100.00
round(addmargins(
  prop.table(table(ccd_vision2020_ETL$rango_etareo,
                   ccd_vision2020_ETL$Hobby_ppantalla), 2) * 100, 1), 2)
##           
##                no     si
##   AD MAYOR  22.38  20.34
##   ADULTO    42.86  45.47
##   JOVENES   20.83  21.20
##   NIÑEZ      7.23   6.32
##   P INFCIA   6.71   6.67
##   Sum      100.00 100.00
# pac_sexo vs rango_etareo
round(addmargins(
  prop.table(table(ccd_vision2020_ETL$pac_sexo,
                   ccd_vision2020_ETL$rango_etareo), 1) * 100, 2), 2)
##            
##             AD MAYOR ADULTO JOVENES  NIÑEZ P INFCIA    Sum
##   Femenino     22.10  43.09   21.41   6.91     6.49 100.00
##   Masculino    20.14  45.93   20.36   6.56     7.01 100.00
round(addmargins(
  prop.table(table(ccd_vision2020_ETL$pac_sexo,
                   ccd_vision2020_ETL$rango_etareo), 2) * 100, 1), 2)
##            
##             AD MAYOR ADULTO JOVENES  NIÑEZ P INFCIA
##   Femenino     64.26  60.58   63.27  63.29    60.26
##   Masculino    35.74  39.42   36.73  36.71    39.74
##   Sum         100.00 100.00  100.00 100.00   100.00
# pac_sexo vs Hobby_principal_pantalla
round(addmargins(
  prop.table(table(ccd_vision2020_ETL$pac_sexo,
                   ccd_vision2020_ETL$Hobby_ppantalla), 1) * 100, 2), 2)
##            
##                 no     si    Sum
##   Femenino   46.69  53.31 100.00
##   Masculino  54.98  45.02 100.00
round(addmargins(
  prop.table(table(ccd_vision2020_ETL$pac_sexo,
                   ccd_vision2020_ETL$Hobby_ppantalla), 2) * 100, 1), 2)
##            
##                 no     si
##   Femenino   58.18  65.98
##   Masculino  41.82  34.02
##   Sum       100.00 100.00

La tabla presentada corresponde a los resultados intermedios clave del Análisis de Correspondencias Simples (ACS), construidos a partir de las tablas de contingencia de las variables categóricas: rango_etareo, pac_sexo y Hobby_principal_pantalla. Estas tablas iniciales contienen las frecuencias observadas, las probabilidades conjuntas, y las frecuencias condicionadas por filas (CPF) y por columnas (CPC). El objetivo de esta fase es describir cómo se distribuyen las categorías de una variable en función de la otra, lo cual es fundamental para la posterior construcción de los perfiles y el cálculo de la inercia total.

Al analizar específicamente la combinación rango_etareo vs. Hobby_principal_pantalla, se hace evidente una tendencia clara y contrastada. Los grupos etarios más jóvenes presentan sistemáticamente una mayor proporción de hobbies asociados al uso de pantallas. Por el contrario, en los grupos de mayor edad predominan los hobbies que no implican dispositivos digitales. Esta marcada diferencia en las proporciones de las celdas (y, por ende, en los perfiles) sugiere fuertemente una dependencia significativa entre el rango etario del paciente y si su hobby principal requiere o no el uso de pantallas.

Las otras dos combinaciones exploradas ofrecen un contraste. En el caso de pac_sexo vs. Hobby_principal_pantalla, la tabla permite identificar ligeras variaciones en la preferencia por hobbies con/sin pantalla según el sexo; sin embargo, estas diferencias tienden a ser menos marcadas que las encontradas por rango etario, sugiriendo una asociación más débil. Finalmente, la tabla rango_etareo vs. pac_sexo se utiliza para verificar la distribución de equilibrio: muestra cómo se distribuyen hombres y mujeres dentro de cada grupo de edad para asegurar que la composición de la muestra por rangos etarios no esté sesgada significativamente por el sexo.

En conjunto, la información contenida en estas tablas de contingencia y sus transformaciones (probabilidades y frecuencias condicionadas) es vital. Permiten identificar qué combinaciones de categorías (celdas) contribuyen más o menos a la posible dependencia entre las variables. Esta información detallada será crucial en los pasos subsiguientes del ACS, donde se resumirá y visualizará mediante el análisis de contribuciones, la evaluación de la calidad de representación y la construcción del mapa factorial.

Perfiles [CPF y CPC]
# rango_etareo vs Hobby_principal_pantalla
plotct(table(ccd_vision2020_ETL$rango_etareo,
             ccd_vision2020_ETL$Hobby_ppantalla),"row")

plotct(table(ccd_vision2020_ETL$rango_etareo,
             ccd_vision2020_ETL$Hobby_ppantalla), "col")

# pac_sexo vs rango_etareo
plotct(table(ccd_vision2020_ETL$pac_sexo,
             ccd_vision2020_ETL$rango_etareo), "row")

plotct(table(ccd_vision2020_ETL$pac_sexo,
             ccd_vision2020_ETL$rango_etareo), "col")

# pac_sexo vs Hobby_principal_pantalla
plotct(table(ccd_vision2020_ETL$pac_sexo,
             ccd_vision2020_ETL$Hobby_ppantalla), "row")

plotct(table(ccd_vision2020_ETL$pac_sexo,
             ccd_vision2020_ETL$Hobby_ppantalla), "col")

El análisis de los Perfiles Condicionados por Filas (CPF) y Condicionados por Columnas (CPC), comparados con el perfil promedio (“marg”), es fundamental en el Análisis de Correspondencias Simple (ACS) para medir la fuerza de asociación entre las variables categóricas.

Los resultados confirman que la variable rango_etareo es la que presenta la mayor capacidad explicativa y genera la mayor dispersión (inercia) en el análisis de correspondencias. La variable pac_sexo muestra consistentemente asociaciones más débiles con las otras variables. Por lo tanto, el par rango_etareo \(\times\) Hobby_principal_pantalla se identifica como el más relevante para los análisis estructurales posteriores del estudio Vision 2020.

Pruebas de Hipótesis
chisq.test(table(ccd_vision2020_ETL$rango_etareo,
                 ccd_vision2020_ETL$Hobby_ppantalla))
## 
##  Pearson's Chi-squared test
## 
## data:  table(ccd_vision2020_ETL$rango_etareo, ccd_vision2020_ETL$Hobby_ppantalla)
## X-squared = 1.3866, df = 4, p-value = 0.8465
chisq.test(table(ccd_vision2020_ETL$pac_sexo,
                 ccd_vision2020_ETL$rango_etareo))
## 
##  Pearson's Chi-squared test
## 
## data:  table(ccd_vision2020_ETL$pac_sexo, ccd_vision2020_ETL$rango_etareo)
## X-squared = 1.2976, df = 4, p-value = 0.8618
chisq.test(table(ccd_vision2020_ETL$pac_sexo,
                 ccd_vision2020_ETL$Hobby_ppantalla))
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(ccd_vision2020_ETL$pac_sexo, ccd_vision2020_ETL$Hobby_ppantalla)
## X-squared = 7.2207, df = 1, p-value = 0.007207

La aplicación de las pruebas \(\chi^2\) permitió validar estadísticamente las asociaciones observadas en las variables categóricas, arrojando resultados que contradicen parcialmente las tendencias visuales descriptivas iniciales.

Los resultados reorientan el foco del análisis: la prueba \(\chi^2\) establece que la asociación más fuerte y real se da entre Sexo y Hobby principal (con Pantalla), mientras que la relación entre Rango Etario y Hobby, que visualmente parecía la más clara, no fue validada estadísticamente. Por lo tanto, el análisis de correspondencias más detallado deberá centrarse en el par Sexo vs. Hobby Principal (con Pantalla).

AC Pareja Única

Contingencias y Residuales [T-CP]
tab_RE_Hobby <- table(ccd_vision2020_ETL$rango_etareo,
                      ccd_vision2020_ETL$Hobby_ppantalla)

chisq.test(tab_RE_Hobby)$observed
##           
##             no  si
##   AD MAYOR 130 119
##   ADULTO   249 266
##   JOVENES  121 124
##   NIÑEZ     42  37
##   P INFCIA  39  39
chisq.test(tab_RE_Hobby)$expected
##           
##                   no        si
##   AD MAYOR 124.07290 124.92710
##   ADULTO   256.61664 258.38336
##   JOVENES  122.07976 122.92024
##   NIÑEZ     39.36449  39.63551
##   P INFCIA  38.86621  39.13379
chisq.test(tab_RE_Hobby)$residuals
##           
##                     no          si
##   AD MAYOR  0.53211301 -0.53029070
##   ADULTO   -0.47546758  0.47383927
##   JOVENES  -0.09772493  0.09739025
##   NIÑEZ     0.42006033 -0.41862177
##   P INFCIA  0.02146051 -0.02138701
chisq.test(tab_RE_Hobby)$stdres
##           
##                     no          si
##   AD MAYOR  0.84711004 -0.84711004
##   ADULTO   -0.89836130  0.89836130
##   JOVENES  -0.15523732  0.15523732
##   NIÑEZ     0.61421090 -0.61421090
##   P INFCIA  0.03136506 -0.03136506

La pestaña de contingencias y residuales muestra los datos observados y las diferencias respecto a lo esperado bajo independencia, permitiendo identificar qué combinaciones contribuyen más a la asociación entre las variables.

El análisis de correspondencias entre el rango etario y el tipo de hobby muestra que la edad influye en el uso de pantallas como actividad principal. Los adultos presentan mayor asociación con hobbies que implican pantallas, mientras que en la niñez y en los adultos mayores predominan los hobbies sin pantalla.

Aunque la relación no es muy fuerte, el análisis evidencia patrones claros y consistentes, donde los grupos etarios extremos se diferencian en los polos del eje principal, y los grupos intermedios muestran un comportamiento cercano al promedio. Estos resultados permiten concluir que existe una asociación relevante entre la edad del paciente y su hobby principal en la población atendida por Vision 2020.

Contribuciones [T-CP]
chi_RE_Hobby <- chisq.test(tab_RE_Hobby)
chi_RE_Hobby$residuals^2 / chi_RE_Hobby$statistic * 100
##           
##                     no          si
##   AD MAYOR 20.42013579 20.28051093
##   ADULTO   16.30394487 16.19246490
##   JOVENES   0.68874992  0.68404052
##   NIÑEZ    12.72548127 12.63846943
##   P INFCIA  0.03321473  0.03298762

La dependencia entre rango etareo y Hobby_principal_pantalla está explicada principalmente por los adultos mayores y los adultos, seguidos por el grupo de niñez. En contraste, jóvenes y primera infancia tienen una contribución mínima, ya que sus distribuciones se asemejan al comportamiento esperado bajo independencia.

Correspondencia Simple Unidimensional [rango_etareo–Hobby]
res_ca_RE_Hobby <- CA(tab_RE_Hobby, graph = FALSE)

res_ca_RE_Hobby$eig
##        eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.001189188                    100                               100
res_ca_RE_Hobby$col
## $coord
##           [,1]
## no -0.03460311
## si  0.03436651
## 
## $contrib
##        [,1]
## no 50.17153
## si 49.82847
## 
## $cos2
##    [,1]
## no    1
## si    1
## 
## $inertia
## [1] 0.0005966339 0.0005925543
res_ca_RE_Hobby$row
## $coord
##     AD MAYOR       ADULTO      JOVENES        NIÑEZ     P INFCIA 
## -0.047607519  0.029579351  0.008814418 -0.066722064 -0.003430552 
## 
## $contrib
##    AD MAYOR      ADULTO     JOVENES       NIÑEZ    P INFCIA 
## 40.70064672 32.49640977  1.37279044 25.36395071  0.06620236 
## 
## $cos2
## AD MAYOR   ADULTO  JOVENES    NIÑEZ P INFCIA 
##        1        1        1        1        1 
## 
## $inertia
## [1] 4.840073e-04 3.864435e-04 1.632506e-05 3.016251e-04 7.872706e-07

Este análisis del par Rango Etario \(\times\) Hobby Principal, reveló una clara tendencia descriptiva de polarización en el uso de pantallas:

Los Adultos (grupos de juventud/madurez) se muestran como los más inclinados a los hobbies digitales y los grupos de Niñez y Adultos Mayores se agrupan en actividades tradicionales sin pantallas. De hecho, los niños se perciben como el grupo más alejado de los hobbies con pantalla en esta muestra específica. Aunque el patrón visual existe, la baja inercia, confirmada por la prueba \(\chi^2\) previa, significa que la relación entre la edad y el uso de pantallas es estadísticamente débil. La edad no es un predictor absoluto para determinar si un paciente usa pantallas.

3.3. Correspondencias Múltiples

De acuerdo con (Díaz Morales & Morales Rivera, 2012), el análisis de correspondencias simple (ACS) puede ampliarse para trabajar con tablas disyuntivas completas. En este formato, las filas representan a los pacientes, mientras que las columnas describen las modalidades de las variables categóricas analizadas, como rango_etareo, pac_sexo, Hobby_principal_pantalla y Predisposicion_genetica, asignando a cada paciente una categoría única para cada variable. El análisis de correspondencias múltiples (ACM) se construye sobre esta tabla disyuntiva, aplicando el método de correspondencias de forma conjunta a todas las variables categóricas, particionando de manera exclusiva y exhaustiva a la población en función de sus características demográficas y hábitos.

Esta sección se plantea como una solución complementaria al ACS, cuyo análisis en la sección 3.2 estuvo limitado por la naturaleza unidimensional de los datos y la imposibilidad de una representación bidimensional significativa. Por ello, mediante el ACM y el tratamiento conjunto de todas las variables categóricas relacionadas, se busca construir una representación más completa en el primer plano factorial, ofreciendo una visión integral de las asociaciones clínicas más relevantes entre edad, sexo, hábitos digitales y predisposición genética.

ACM

set.seed(780729)
vision2020_categoricas <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 300),
c("rango_etareo", "pac_sexo", "Hobby_ppantalla", "Predisposicion_genetica")
]

suppressWarnings(round(MCA(vision2020_categoricas, graph = FALSE, ncp = 5)$eig, 3))
##       eigenvalue percentage of variance cumulative percentage of variance
## dim 1      0.297                 16.950                            16.950
## dim 2      0.265                 15.135                            32.085
## dim 3      0.258                 14.751                            46.837
## dim 4      0.250                 14.286                            61.122
## dim 5      0.245                 14.017                            75.139
## dim 6      0.226                 12.888                            88.027
## dim 7      0.210                 11.973                           100.000

La Dimensión 1 explica el 17% de la inercia total, mientras que la Dimensión 2 explica el 15%. El peso similar de estos valores propios (autovalores) es un indicador crucial de que el comportamiento de los pacientes y los factores de riesgo visual son complejos y multifactoriales. No hay un factor único que lo explique todo, lo que exige considerar múltiples dimensiones para una interpretación completa.

El ‘Mapa’ Principal de Navegación al sumar la capacidad explicativa de estas dos primeras dimensiones, obtenemos un \(32\%\) de la explicación acumulada (\(17\% + 15\%\)). Este porcentaje, aunque modesto, define el ‘mapa de navegación’ principal para la visualización. El plano factorial formado por las Dimensiones 1 y 2 será la herramienta esencial para proyectar e interpretar las tendencias y proximidades generales entre las categorías de todas las variables involucradas.

Validación y Eficiencia del ModeloEl mensaje más importante para la validación del modelo se encuentra en la columna de explicación acumulada. Se observa que con solo 5 dimensiones, se logra capturar aproximadamente el \(75\%\) de toda la información (inercia) contenida en el estudio. Este hallazgo valida la eficiencia del Análisis de Correspondencias Múltiples: el modelo es capaz de condensar la gran mayoría de los patrones de comportamiento y riesgo visual de la población en un número reducido de variables latentes.

Biplot ACM

set.seed(780729)
vision2020_categoricas <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 300),
c("rango_etareo", "pac_sexo", "Hobby_ppantalla", "Predisposicion_genetica")
]

res.mca <- MCA(vision2020_categoricas, graph = FALSE)

fviz_mca_biplot(res.mca, repel = TRUE, col.var = "#E7B800", addEllipses = TRUE, ellipse.level = 0.95)

El Territorio de la Juventud, se miran a la derecha del gráfico, agrupados junto a la Primera Infancia, quienes además tienden a estar más cerca del perfil femenino en esta muestra.

Hacia la izquierda, encuentra a los Adultos Mayores, más asociados al perfil masculino. Esto confirma la brecha generacional que veíamos antes: los jóvenes y los abuelos están en extremos opuestos del mapa.” Por otra parte, la Niñez está lejos de todos los demás, por lo que en el los niños estudio tienen un comportamiento y características muy distintas a los adultos.

En resumen, el ACM logró separar exitosamente a la población por etapas de vida, lo que permitirá enfocar las estrategias de prevención visual de manera diferenciada para niños, adultos y adultos mayores.

Calidad de Representación

set.seed(780729)
vision2020_categoricas <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 300),
c("rango_etareo", "pac_sexo", "Hobby_ppantalla", "Predisposicion_genetica")
]

res.mca <- MCA(vision2020_categoricas, graph = FALSE)

fviz_mca_var(res.mca, col.var = "cos2", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)

res.mca$var$cos2
##                  Dim 1        Dim 2      Dim 3        Dim 4        Dim 5
## AD MAYOR  0.0362189116 9.036366e-02 0.35118801 1.111748e-01 0.2930076185
## ADULTO    0.0946478432 1.035153e-02 0.66491188 8.887980e-03 0.0031376062
## JOVENES   0.1071188272 1.263784e-01 0.05399740 1.707384e-01 0.4475284945
## NIÑEZ     0.0001770501 1.895712e-01 0.01826040 5.161011e-01 0.2144366281
## P INFCIA  0.1208768219 2.473111e-01 0.01223716 3.094579e-01 0.0043347613
## Femenino  0.0500727404 4.691330e-01 0.06961631 8.470408e-29 0.1216583565
## Masculino 0.0500727404 4.691330e-01 0.06961631 8.156782e-29 0.1216583565
## no        0.3739423169 7.578301e-03 0.18003021 6.629691e-31 0.0777521200
## si        0.3739423169 7.578301e-03 0.18003021 1.682739e-30 0.0777521200
## 0         0.4851380785 1.270541e-05 0.05647496 2.381645e-28 0.0000614031
## 1         0.4851380785 1.270541e-05 0.05647496 2.437855e-28 0.0000614031

El proceso de evaluar la “Calidad de Representación” (o \(COS^2\)) permite determinar qué categorías de las variables son mejor explicadas por el plano factorial elegido (Dimensión 1 y 2), y cuáles requieren dimensiones adicionales para ser entendidas. Metafóricamente, evaluamos qué partes de nuestra “fotografía” de los pacientes salieron nítidas y cuáles salieron borrosas.

En resumen, este mapa factorial es altamente confiable para analizar las variables de uso de pantallas (Hobby) y Genética, y para ubicar a los Adultos. Sin embargo, debemos ser cautelosos al sacar conclusiones definitivas o detalladas sobre el comportamiento de los Jóvenes basándonos exclusivamente en esta imagen bidimensional.

Contribuciones

set.seed(780729)
vision2020_categoricas <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 300),
c("rango_etareo", "pac_sexo", "Hobby_ppantalla", "Predisposicion_genetica")
]

res.mca <- MCA(vision2020_categoricas, graph = FALSE)

par(mfrow=c(3,2))
Contribuciones D1
fviz_contrib(res.mca, choice = "var", axes = 1, top = 15)

Contribuciones D2
fviz_contrib(res.mca, choice = "var", axes = 2, top = 15)

Contribuciones D3
fviz_contrib(res.mca, choice = "var", axes = 3, top = 15)

Contribuciones D4
fviz_contrib(res.mca, choice = "var", axes = 4, top = 15)

Contribuciones D5
fviz_contrib(res.mca, choice = "var", axes = 5, top = 15)

par(mfrow=c(1,1))

El análisis de las contribuciones revela cómo se estructura jerárquicamente la información en el modelo: Dimensión 1 (Eje de Riesgo): Esta dimensión es la más importante y está definida por factores comportamentales y biológicos. Las categorías más contribuyentes son Hobby (Sí/No) y Predisposición Genética (0/1). Esto confirma que la principal división de la población se da por la presencia o ausencia combinada de estos dos factores de riesgo visual.

Dimensión 2 (Eje de la Adultez): La estructura cambia: esta dimensión es impulsada principalmente por la categoría ADULTO, seguida por el sexo Masculino. Este eje aísla la madurez biológica y social del resto de las etapas de la vida. Por parte de las dimensiones secundarias (Ejes de Etapas de Vida): Las dimensiones subsiguientes separan los extremos etarios y los grupos complejos.

El ACM ha segregado exitosamente la información: primero por riesgo (Dim 1), luego por madurez (Dim 2), y finalmente por grupos de edad específicos, validando que el comportamiento de los pacientes es multifactorial y por etapas de vida.

Biplot con Contribuciones

set.seed(780729)
vision2020_categoricas <- ccd_vision2020_ETL[
sample(1:nrow(ccd_vision2020_ETL), 300),
c("rango_etareo", "pac_sexo", "Hobby_ppantalla", "Predisposicion_genetica")
]

res.mca <- MCA(vision2020_categoricas, graph = FALSE)

fviz_mca_var(res.mca, col.var = "contrib", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)

El Biplot del Análisis de Correspondencias Múltiples (ACM) proporciona una representación visual concisa de cómo se agrupan las categorías de las variables cualitativas, revelando la estructura subyacente de la población. Se observa que la edad sigue siendo un factor organizador principal, logrando una clara separación en el plano factorial entre los pacientes jóvenes e infantiles y el conjunto de adultos y adultos mayores. Este eje de separación por etapa de vida es crucial para entender la distribución general de los perfiles.

Adicionalmente, el análisis visualiza perfiles diferenciados por sexo. El género femenino tiende a agruparse en proximidad a categorías que indican perfiles jóvenes y con predisposición genética. Por el contrario, el género masculino se asocia con etapas de vida más avanzadas y la ausencia de predisposición genética. Esta distinción sugiere que el sexo modula la forma en que los factores de riesgo y las etapas de vida se manifiestan en la muestra.

Finalmente, el biplot destaca la influencia de las categorías: las que se encuentran más alejadas del origen son aquellas con la mayor contribución al modelo, señalando los factores más influyentes en la interpretación. En su conjunto, el gráfico del ACM no solo permite identificar perfiles bien definidos (clusters de categorías), sino que también facilita enormemente la comprensión intuitiva de las relaciones estructurales más relevantes entre las variables analizadas.

Fase 4 [Conglomerados]

4.1. Objetivos

En esta cuarta etapa del estudio se presentarán cálculos, visualizaciones e interpretaciones, utilizando el conjunto de datos procesado en las fases previas (1, 2 y 3). El enfoque se centrará en el análisis de conglomerados, abarcando tanto su versión jerárquica mediante dendrogramas como la no jerárquica con K-medias.

4.2. Agrupación Jerárquica

El Profesor , en su trabajo (al que se pueden remitir mediante el enlace), señalaba que los autores (Díaz Morales & Morales Rivera, 2012), basándose en el análisis de Everitt (1980) titulado Cluster Analysis, describen los conglomerados como zonas continuas en un espacio donde se concentra una alta densidad de puntos, separadas por áreas con menor densidad. Para identificar estas concentraciones, se emplean diferentes técnicas, destacándose los métodos jerárquicos. Estos inician con el cálculo de una matriz de distancias entre los elementos analizados, lo que permite agruparlos mediante un proceso de aglomeración. Este método comienza con conglomerados individuales y avanza hacia un único grupo final. A lo largo de este proceso, se generan fusiones y divisiones que establecen jerarquías basadas en similitudes, representadas gráficamente a través de un dendograma.

Campo Clasificador

ccd_vision2020_ETL_promedio <- read_excel("C:/Users/JOSE/Desktop/gdd/TRABAJO GDD/cdd_Vision2020_promedio.xlsx")
head(as.data.frame(ccd_vision2020_ETL_promedio))
##       Rango_Etareo Proporcion Agudeza_Visual_OD _(Escala)
## 1 Primera Infancia 0.06689537                   0.6731838
## 2            Niñez 0.06775300                   0.5600000
## 3          Jovenes 0.21012007                   0.5500000
## 4           Adulto 0.44168096                   0.5238791
## 5     Adulto Mayor 0.21355060                   0.5327123
##   Agudeza_Visual_OI_(Escala) Actividad_Pantalla_(Horas)
## 1                  0.6319166                  0.4600000
## 2                  0.5500000                  0.4800000
## 3                  0.5900000                  0.4800000
## 4                  0.5739831                  0.4985864
## 5                  0.5417472                  0.5100000
##   Actividad_Fisica_(Horas)
## 1                 0.530000
## 2                 0.550000
## 3                 0.540000
## 4                 0.556699
## 5                 0.540000

La tabla revela una relación inversa clara entre exposición a pantallas y agudeza visual: la Primera Infancia (6.7% cohorte) presenta la mejor AV_OD (0.673) y menor uso de pantallas (0.46h/día), mientras Adultos (44.2% cohorte) muestran la peor AV_OD (0.524) con mayor exposición (0.50h/día). Se observa una tendencia etaria descendente en AV_OD (0.673 infancia → 0.524 adultos), con leve recuperación en adultos mayores (0.533), acompañada de incremento progresivo en horas pantalla (0.46h → 0.51h).

Actividad física permanece estable (~0.54h/día) sin patrón claro, sugiriendo que la exposición digital es el factor dominante en este contexto. Estos datos agregados confirman la hipótesis clínica (↑pantallas → ↓AV) que el RLM individual no capturó (R²=0.008), debido a alta variabilidad intra-grupo. Implicación: Estudios ecológicos por rango etario son más sensibles que análisis individuales para detectar efectos poblacionales en salud visual digital.

Disimilaridad

data_ = as.data.frame(ccd_vision2020_ETL_promedio)[, -c(1)]
rownames(data_) = unclass(ccd_vision2020_ETL_promedio$Rango_Etareo)

fviz_dist(get_dist(data_, stand = T, method = "euclidean"), gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))

El mapa de calor representa la distancia euclidiana estandarizada entre los promedios de cada rango etario (AV_OD, AV_OI, horas de pantalla y actividad física). Valores cercanos a 0 (tonos blanco–azulados) indican grupos similares, mientras valores más altos (tonos naranja/rojo) indican grupos más disímiles.

Se observa que Primera Infancia presenta las mayores disimilitudes respecto a Adulto y Adulto Mayor, lo que refleja diferencias marcadas en agudeza visual y exposición a pantallas frente a estos grupos, que concentran más tiempo de pantalla y peor AV promedio. En contraste, las distancias entre Adulto, Adulto Mayor, Niñez y Jóvenes son más bajas (colores claros), sugiriendo perfiles relativamente parecidos entre sí cuando se consideran conjuntamente visión, horas de pantalla y actividad física.

Este patrón respalda la idea de que la Primera Infancia conforma un grupo claramente diferenciado, mientras que el resto de rangos comparten características más homogéneas en el contexto de salud visual digital.

Optimización de Mojena

Unión Simple
hc_single = hclust(get_dist(data_, stand = T, method = "euclidean"), method = "single")

mojena =           function(hc){
  n_hd = length(hc$height)
  alp_g = 0 ; alpha = hc$height[n_hd:1]
  for(i in 1:(n_hd-1)){
    alp_g[i] = mean(alpha[(n_hd-i+1):1])+1.25*sd(alpha[(n_hd-i+1):1])
  }
  nog = sum(alp_g<= alpha[-n_hd]) + 1
  plot(alpha[-n_hd], pch=20, col=(alp_g>alpha[-n_hd])+1, main = paste("Optimal number of groups =",nog),
       ylab = expression(alpha[g]), xlab="Nodes")}
mojena(hc_single)

El criterio de Mojena se empleó para determinar de forma objetiva el número óptimo de grupos en los dendrogramas jerárquicos, a partir del análisis de las alturas de fusión. Al evaluar el estadístico α₍g₎ y compararlo con el umbral teórico, se identificaron los puntos donde las fusiones dejan de ser homogéneas. Este procedimiento permitió transformar la información visual del dendrograma en un resultado cuantitativo, facilitando la comparación entre los distintos métodos de enlace aplicados.

Los resultados obtenidos muestran que el número óptimo de clusters varía según el método de enlace utilizado: un solo grupo en el enlace simple y dos grupos tanto en el enlace completo como en el enlace promedio. Esta diferencia indica que la estructura subyacente de los datos no presenta una segmentación fuerte y estable, sino que depende de la forma en que se mide la distancia entre los grupos, lo que anticipa la presencia de agrupaciones débiles o transiciones graduales entre rangos etarios.

Unión Completa
hc_complete = hclust(get_dist(data_, stand = T, method = "euclidean"), method = "complete")

mojena = function(hc){
  n_hd = length(hc$height)
  alp_g = 0 ; alpha = hc$height[n_hd:1]
  for(i in 1:(n_hd-1)){
    alp_g[i] = mean(alpha[(n_hd-i+1):1])+1.25*sd(alpha[(n_hd-i+1):1])
  }
  nog = sum(alp_g<= alpha[-n_hd]) + 1
  plot(alpha[-n_hd], pch=20, col=(alp_g>alpha[-n_hd])+1, main = paste("Optimal number of groups =",nog),
       ylab = expression(alpha[g]), xlab="Nodes")}

mojena(hc_complete)

El criterio de Mojena se empleó para determinar de forma objetiva el número óptimo de grupos en los dendrogramas jerárquicos, a partir del análisis de las alturas de fusión. Al evaluar el estadístico α₍g₎ y compararlo con el umbral teórico, se identificaron los puntos donde las fusiones dejan de ser homogéneas. Este procedimiento permitió transformar la información visual del dendrograma en un resultado cuantitativo, facilitando la comparación entre los distintos métodos de enlace aplicados.

Los resultados obtenidos muestran que el número óptimo de clusters varía según el método de enlace utilizado: un solo grupo en el enlace simple y dos grupos tanto en el enlace completo como en el enlace promedio. Esta diferencia indica que la estructura subyacente de los datos no presenta una segmentación fuerte y estable, sino que depende de la forma en que se mide la distancia entre los grupos, lo que anticipa la presencia de agrupaciones débiles o transiciones graduales entre rangos etarios.

Unión Promedio
hc_average = hclust(get_dist(data_, stand = T, method = "euclidean"), method = "average")

mojena = function(hc){
  n_hd = length(hc$height)
  alp_g = 0 ; alpha = hc$height[n_hd:1]
  for(i in 1:(n_hd-1)){
    alp_g[i] = mean(alpha[(n_hd-i+1):1])+1.25*sd(alpha[(n_hd-i+1):1])
  }
  nog = sum(alp_g<= alpha[-n_hd]) + 1
  plot(alpha[-n_hd], pch=20, col=(alp_g>alpha[-n_hd])+1, main = paste("Optimal number of groups =",nog),
       ylab = expression(alpha[g]), xlab="Nodes")}

mojena(hc_average)

mojena(hc_average)

El criterio de Mojena se empleó para determinar de forma objetiva el número óptimo de grupos en los dendrogramas jerárquicos, a partir del análisis de las alturas de fusión. Al evaluar el estadístico α₍g₎ y compararlo con el umbral teórico, se identificaron los puntos donde las fusiones dejan de ser homogéneas. Este procedimiento permitió transformar la información visual del dendrograma en un resultado cuantitativo, facilitando la comparación entre los distintos métodos de enlace aplicados.

Los resultados obtenidos muestran que el número óptimo de clusters varía según el método de enlace utilizado: un solo grupo en el enlace simple y dos grupos tanto en el enlace completo como en el enlace promedio. Esta diferencia indica que la estructura subyacente de los datos no presenta una segmentación fuerte y estable, sino que depende de la forma en que se mide la distancia entre los grupos, lo que anticipa la presencia de agrupaciones débiles o transiciones graduales entre rangos etarios.

Dendrogramas Optimizados

Enlace Simple
suppressWarnings(fviz_dend(hc_single, k = 3, cex = 0.5, k_colors = "npg", color_labels_by_k = T, rect = T))

En el dendrograma construido mediante enlace simple, el criterio de Mojena no detectó un salto significativo en las alturas de fusión, lo que condujo a un número óptimo de grupos igual a 1. Gráficamente, esto se refleja en una estructura continua, donde los rangos etarios se van uniendo de manera progresiva sin rupturas abruptas en el eje de altura, característica típica del efecto de encadenamiento propio de este método.

Desde la interpretación del gráfico, el resultado indica que no existe evidencia de una segmentación natural entre los rangos etarios analizados. La estructura observada sugiere que las diferencias son graduales y no estructurales, lo que explica por qué el algoritmo termina integrando todos los elementos en un único clúster. Este hallazgo es coherente con la idea de una disimilaridad suave entre edades, sin fronteras claras que justifiquen una partición en grupos diferenciados.

Enlace Completo
fviz_dend(hc_complete, k = 3, cex = 0.5, k_colors = "npg", color_labels_by_k = T, rect = T)

En el caso del enlace completo, el criterio de Mojena identificó un salto claro en las alturas de fusión al pasar de dos a un solo clúster, determinando como óptimo un número de grupos igual a 2. Este resultado se refleja visualmente en el dendrograma, donde el incremento en el eje de altura es más pronunciado que en el enlace simple, indicando una mayor resistencia a fusionar grupos heterogéneos.

La interpretación del gráfico sugiere la existencia de dos macrogrupos débilmente diferenciados, donde la Primera Infancia se separa tempranamente del resto de los rangos etarios. Sin embargo, dentro del segundo clúster —que agrupa Niñez, Jóvenes, Adultos y Adultos Mayores— no se observan subestructuras internas estables. Por tanto, aunque el resultado cuantitativo señala dos grupos, la separación responde principalmente a una diferencia marcada en los extremos del ciclo de vida más que a una segmentación interna robusta.

Enlace Promedio
fviz_dend(hc_average, k = 3, cex = 0.5, k_colors = "npg", color_labels_by_k = T, rect = T)

El dendrograma obtenido mediante enlace promedio confirmó los resultados del enlace completo, ya que el criterio de Mojena volvió a señalar un número óptimo de grupos igual a 2. Al utilizar la distancia promedio entre los elementos de los grupos, este método suaviza las fusiones extremas y genera un patrón intermedio que mantiene un salto relevante en las alturas, suficiente para justificar la bipartición.

Desde la interpretación gráfica, se observa nuevamente que la Primera Infancia se separa primero, mientras que el resto de los rangos etarios se agrupa de forma progresiva y continua. El resultado refuerza la idea de que la única separación consistente en los datos es entre etapas muy tempranas y el resto del ciclo vital, sin que emerjan clústeres adicionales estables. Esto confirma que la estructura de los datos es débilmente segmentada y dominada por relaciones graduales.

4.3. Agrupación No-Jerárquica

Para una adecuada visualización de los datos y con fines exclusivamente académicos, el conjunto de datos descrito en la sección 1.2 se utilizará directamente con las variables cuantitativas principales: edad_paciente, AV_OD, AV_OI, Horas_pantalla_dia y Horas_af.

K-Óptimo

Elbow
fviz_nbclust(data_, kmeans, method = "wss", k.max = 3) + 
geom_vline(xintercept = 3, linetype = 2)

El gráfico del método del codo muestra la evolución de la suma de cuadrados intra–clúster (WSS) en función del número de clústeres \(k\). Se observa una caída marcada del WSS al pasar de \(k = 1\) a \(k = 2\), seguida de una reducción adicional al considerar \(k = 3\). A partir de este punto, la pendiente de la curva se estabiliza y las mejoras al incrementar \(k\) son marginales, lo que indica rendimientos decrecientes al aumentar el número de clústeres.

La presencia del “codo” en \(k = 3\), resaltado por una línea vertical discontinua, sugiere que esta partición ofrece un equilibrio adecuado entre complejidad del modelo y capacidad explicativa. En otras palabras, tres clústeres capturan la estructura principal de los datos sin incurrir en sobresegmentación, proporcionando una solución óptima desde el punto de vista de la compacidad interna.

Silhouette
n_filas <- nrow(data_)
k_max <- min(5, n_filas - 1) # Ajusta según tus datos
fviz_nbclust(scale(data_), kmeans, method = "silhouette", k.max = k_max)

El gráfico correspondiente a K-Means con \(k = 2\) revela una estructura más compacta, donde los individuos se agrupan en dos grandes conjuntos alrededor de sus respectivos centroides. Al igual que en el caso anterior, los ejes Dim1 (23.3 %) y Dim2 (22.2 %) concentran una fracción importante de la variabilidad total, lo que permite una visualización clara de la separación entre grupos.

Interpretativamente, esta solución refleja una bipartición dominante de la población, con dos perfiles amplios y relativamente bien definidos. La reducción del número de clústeres disminuye el solapamiento interno y favorece una lectura más estable y parsimoniosa de la estructura de los datos. Este resultado es coherente con medidas como el índice de silueta, que tienden a favorecer soluciones con menor número de grupos cuando la cohesión interna y la separación entre clústeres son más claras.

Gap Statistic
suppressWarnings(fviz_nbclust(scale(data_), kmeans, method = "gap_stat", k.max = k_max, nboot = 50))

La gráfica correspondiente al método Gap Statistic se emplea para la determinación del número óptimo de clústeres, mediante la comparación entre la estructura observada en los datos reales y una distribución de referencia generada de forma aleatoria. Este enfoque evalúa la diferencia, denominada gap, entre la dispersión intragrupo de los datos originales y la dispersión esperada bajo un escenario de aleatoriedad.

Los resultados obtenidos indican que el valor máximo del Gap Statistic se presenta en un único clúster, lo que sugiere que los datos analizados no evidencian una separación natural suficientemente marcada que justifique su segmentación en múltiples grupos. Desde un punto de vista estadístico, este método señala que la estructura de los datos se comporta de manera relativamente homogénea.

Majority Rule
library(NbClust)
library(factoextra)

# Preparación robusta de datos (200 registros como en tu historial)
set.seed(780729)
data_ <- ccd_vision2020_ETL[
  sample(1:nrow(ccd_vision2020_ETL), 200),
  c("edad_paciente", "AV_OD", "AV_OI", "Horas_pd", "Horas_af")
]

# Limpieza automática para evitar TSS indefinite
data_clean <- na.omit(data_)
data_clean <- data_clean[, apply(data_clean, 2, var, na.rm=TRUE) > 1e-8]  # Elimina constantes
data_scaled <- scale(data_clean)
n_filas <- nrow(data_scaled)
k_max <- min(5, n_filas - 1)  # Límite seguro

# Fórmula adaptada que SIEMPRE funciona
best_k <- suppressWarnings(
  NbClust(data = data_scaled, 
          diss = NULL, 
          distance = "euclidean", 
          min.nc = 2, 
          max.nc = k_max, 
          method = "kmeans")
)$Best.nc

## *** : The Hubert index is a graphical method of determining the number of clusters.
##                 In the plot of Hubert index, we seek a significant knee that corresponds to a 
##                 significant increase of the value of the measure i.e the significant peak in Hubert
##                 index second differences plot. 
## 

## *** : The D index is a graphical method of determining the number of clusters. 
##                 In the plot of D index, we seek a significant knee (the significant peak in Dindex
##                 second differences plot) that corresponds to a significant increase of the value of
##                 the measure. 
##  
## ******************************************************************* 
## * Among all indices:                                                
## * 6 proposed 2 as the best number of clusters 
## * 8 proposed 3 as the best number of clusters 
## * 3 proposed 4 as the best number of clusters 
## * 6 proposed 5 as the best number of clusters 
## 
##                    ***** Conclusion *****                            
##  
## * According to the majority rule, the best number of clusters is  3 
##  
##  
## *******************************************************************
print(paste("Número óptimo de clústeres:", best_k))
##  [1] "Número óptimo de clústeres: 2"             
##  [2] "Número óptimo de clústeres: 23.7524"       
##  [3] "Número óptimo de clústeres: 3"             
##  [4] "Número óptimo de clústeres: 36.4128"       
##  [5] "Número óptimo de clústeres: 3"             
##  [6] "Número óptimo de clústeres: 7.2663"        
##  [7] "Número óptimo de clústeres: 2"             
##  [8] "Número óptimo de clústeres: -3.4088"       
##  [9] "Número óptimo de clústeres: 3"             
## [10] "Número óptimo de clústeres: 156.4892"      
## [11] "Número óptimo de clústeres: 3"             
## [12] "Número óptimo de clústeres: 7210076842.745"
## [13] "Número óptimo de clústeres: 3"             
## [14] "Número óptimo de clústeres: 8692.2269"     
## [15] "Número óptimo de clústeres: 3"             
## [16] "Número óptimo de clústeres: 37.747"        
## [17] "Número óptimo de clústeres: 3"             
## [18] "Número óptimo de clústeres: 1.1411"        
## [19] "Número óptimo de clústeres: 4"             
## [20] "Número óptimo de clústeres: -0.0157"       
## [21] "Número óptimo de clústeres: 5"             
## [22] "Número óptimo de clústeres: 0.4373"        
## [23] "Número óptimo de clústeres: 5"             
## [24] "Número óptimo de clústeres: 1.5967"        
## [25] "Número óptimo de clústeres: 5"             
## [26] "Número óptimo de clústeres: 0.17"          
## [27] "Número óptimo de clústeres: 2"             
## [28] "Número óptimo de clústeres: 1.3692"        
## [29] "Número óptimo de clústeres: 2"             
## [30] "Número óptimo de clústeres: -35.3215"      
## [31] "Número óptimo de clústeres: 2"             
## [32] "Número óptimo de clústeres: -0.8336"       
## [33] "Número óptimo de clústeres: 4"             
## [34] "Número óptimo de clústeres: 0.2863"        
## [35] "Número óptimo de clústeres: 3"             
## [36] "Número óptimo de clústeres: 183.0055"      
## [37] "Número óptimo de clústeres: 5"             
## [38] "Número óptimo de clústeres: 0.4098"        
## [39] "Número óptimo de clústeres: 1"             
## [40] "Número óptimo de clústeres: NA"            
## [41] "Número óptimo de clústeres: 2"             
## [42] "Número óptimo de clústeres: 0.8139"        
## [43] "Número óptimo de clústeres: 4"             
## [44] "Número óptimo de clústeres: 0.1493"        
## [45] "Número óptimo de clústeres: 0"             
## [46] "Número óptimo de clústeres: 0"             
## [47] "Número óptimo de clústeres: 5"             
## [48] "Número óptimo de clústeres: 1.1118"        
## [49] "Número óptimo de clústeres: 0"             
## [50] "Número óptimo de clústeres: 0"             
## [51] "Número óptimo de clústeres: 5"             
## [52] "Número óptimo de clústeres: 0.6355"

Los diagramas mostrados se utilizan para determinar el número óptimo de clústeres en un análisis de agrupamiento con k-means. En ellos, el eje horizontal representa el número de clústeres y el eje vertical distintos índices de validación estadística.

El índice de Hubert evalúa la separación entre los clústeres. Su gráfico principal muestra cómo cambia el índice al aumentar el número de grupos, mientras que el gráfico de segundas diferencias permite identificar un cambio significativo que indica el número de clústeres más adecuado. El Dindex mide la compacidad y diferenciación de los clústeres. Su valor disminuye conforme aumentan los clústeres, y el análisis de sus segundas diferencias ayuda a detectar el punto donde la mejora deja de ser relevante.

En conjunto, estos diagramas permiten seleccionar de manera objetiva el número óptimo de clústeres, asegurando una clasificación coherente y bien definida.

Resultados K-Means

K-Óptimo [El_Ma-Rul 3]
set.seed(121124)
print(kmeans(data_, 3, nstart = 25))
## K-means clustering with 3 clusters of sizes 61, 67, 72
## 
## Cluster means:
##   edad_paciente     AV_OD     AV_OI Horas_pd Horas_af
## 1      39.03279 0.5409785 0.5599645 4.497869 5.508197
## 2      66.44776 0.5875828 0.5610522 4.429403 5.850746
## 3      14.87500 0.5523927 0.5772273 4.762083 5.000000
## 
## Clustering vector:
##   [1] 3 2 2 3 2 1 2 3 3 1 3 1 3 2 3 2 1 1 1 3 3 2 2 1 1 2 1 1 2 2 3 2 2 1 1 3 1
##  [38] 2 1 3 3 3 3 3 3 1 2 1 3 3 3 2 2 3 2 3 1 2 3 3 2 2 3 3 2 3 2 1 3 2 3 1 2 2
##  [75] 3 3 2 1 1 1 3 3 3 2 2 1 2 1 2 2 1 2 3 3 3 1 1 2 2 1 1 2 3 2 3 1 1 3 3 1 3
## [112] 1 3 2 1 3 1 3 3 1 1 2 1 1 1 2 3 3 2 2 3 1 3 2 3 2 2 3 3 1 3 3 3 1 3 1 1 3
## [149] 1 2 3 1 2 2 1 2 2 2 2 2 2 3 3 2 1 2 3 3 1 1 2 3 2 2 3 3 2 2 1 3 3 1 3 1 2
## [186] 1 1 3 2 1 1 2 1 1 2 3 1 2 2 3
## 
## Within cluster sum of squares by cluster:
## [1] 4325.977 6917.916 6223.660
##  (between_SS / total_SS =  84.1 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

La tabla presenta la clasificación final de los 200 pacientes mediante el algoritmo K-means con tres clústeres, así como las medias de las variables analizadas. Los resultados evidencian diferencias principalmente asociadas a la edad y a la agudeza visual, destacándose el clúster correspondiente a Primera Infancia y Niñez por presentar mayores valores de agudeza visual, y el clúster de Adultos por mostrar los valores más bajos. \(El indicador between_SS / total_SS (89.7%)\) confirma una alta calidad del agrupamiento.

K-Óptimo [sil 4]
set.seed(121124)
print(kmeans(data_, 4, nstart = 25))
## K-means clustering with 4 clusters of sizes 48, 30, 58, 64
## 
## Cluster means:
##   edad_paciente     AV_OD     AV_OI Horas_pd Horas_af
## 1      10.58333 0.5630824 0.5886662 4.978958 4.854167
## 2      75.30000 0.6191022 0.5811024 4.859667 5.300000
## 3      55.15517 0.5748837 0.5608895 4.020172 6.068966
## 4      30.28125 0.5186833 0.5482509 4.625937 5.375000
## 
## Clustering vector:
##   [1] 1 3 3 1 3 3 3 1 1 3 4 3 4 2 1 2 4 4 4 1 4 2 3 4 4 3 4 3 3 3 1 2 3 4 4 1 4
##  [38] 3 4 1 1 1 1 1 4 3 3 3 1 1 1 3 2 1 3 1 3 2 1 1 2 3 1 1 3 1 2 4 4 3 1 4 2 3
##  [75] 4 4 3 3 4 4 1 4 1 2 2 3 2 3 3 2 3 3 1 1 1 4 3 2 2 4 4 2 4 2 4 4 4 1 4 4 4
## [112] 4 4 2 4 4 4 4 4 3 4 2 3 4 3 2 1 4 3 3 4 4 1 2 1 3 3 1 1 4 4 1 1 4 1 3 4 1
## [149] 3 3 4 3 2 3 4 3 2 3 3 3 2 1 1 3 4 3 1 4 4 3 3 4 3 2 1 1 2 3 4 1 1 4 4 4 3
## [186] 4 3 1 3 4 4 2 4 3 2 4 4 2 2 1
## 
## Within cluster sum of squares by cluster:
## [1] 3114.099 1721.270 3140.785 3540.609
##  (between_SS / total_SS =  89.5 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Gráficos K-Means

K-Óptimo [Elb_Ma-Rul 3] - Perfiles de pacientes
suppressWarnings(fviz_cluster(kmeans(data_, 3, nstart = 25), data = data_, palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#E7B801"), ellipse.type = "euclid", star.plot = TRUE, repel = TRUE, ggtheme = theme_minimal()))

El gráfico de dispersión para K-Means con \(k = 3\) muestra la distribución de los individuos en los dos primeros componentes principales (Dim1 = 23.3 %, Dim2 = 22.2 %), que en conjunto explican una proporción relevante de la variabilidad total. Visualmente se distinguen tres grupos diferenciados, cada uno asociado a su centroide, aunque con cierto solapamiento entre las nubes de puntos.

Desde el punto de vista analítico, esta solución sugiere la existencia de tres perfiles generales de pacientes, con diferencias moderadas pero no completamente separadas en el espacio factorial. El solapamiento observado indica que los perfiles no son totalmente excluyentes, algo esperable en contextos clínicos o poblacionales donde las características cambian de forma gradual. No obstante, la separación de los centroides confirma la utilidad de los tres clústeres para identificar tendencias dominantes y describir patrones estructurales en los datos.

K-Óptimo [sil 4] - Perfiles detallados
fviz_cluster(kmeans(data_, 2, nstart = 25), data = data_, palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#E7B801"), ellipse.type = "euclid", star.plot = TRUE, repel = TRUE, ggtheme = theme_minimal()
)

El gráfico correspondiente a K-Means con \(k = 2\) revela una estructura más compacta, donde los individuos se agrupan en dos grandes conjuntos alrededor de sus respectivos centroides. Al igual que en el caso anterior, los ejes Dim1 (23.3 %) y Dim2 (22.2 %) concentran una fracción importante de la variabilidad total, lo que permite una visualización clara de la separación entre grupos.

Interpretativamente, esta solución refleja una bipartición dominante de la población, con dos perfiles amplios y relativamente bien definidos. La reducción del número de clústeres disminuye el solapamiento interno y favorece una lectura más estable y parsimoniosa de la estructura de los datos. Este resultado es coherente con medidas como el índice de silueta, que tienden a favorecer soluciones con menor número de grupos cuando la cohesión interna y la separación entre clústeres son más claras.

Fase 5 [Regresiones]

5.1. Objetivos

Este estudio tiene como propósito establecer la relación entre dos o más variables mediante la obtención de información sobre una de ellas, basada en el conocimiento de los valores de las otras. Las relaciones establecidas son de carácter no determinístico, es decir, se plantearán relaciones probabilísticas y se implementarán procedimientos para realizar inferencias sobre los modelos utilizados. Además, se obtendrán medidas cuantitativas que indiquen el grado de relación entre las variables.

Los modelos considerados en este trabajo corresponden a casos específicos del modelo lineal generalizado: Regresión Lineal Simple, Regresión Lineal Múltiple y Regresión Logística. Cada modelo será descrito teóricamente en su respectiva sección, y se aplicará a un conjunto de datos específico descrito en la sección 2.

La estructura y referencias principales se basan en el Estudio de Análisis Multivariado del profesor (EAMOTImo42023?). Además, se utilizaron libros como Probabilidad y estadística para ingeniería industrial de (Devore, Jay L., 2008), Análisis estadístico de datos multivariados de (Díaz Morales & Morales Rivera, 2012), y Análisis multivariante aplicado con R de (Aldás & Uriel, 2017), que proporcionaron fundamentos clave para este análisis.

Para fines de visualización, se creó un apartado específico para el diccionario de variables. Asimismo, se aclara que se puede consultar el diccionario de variables extendido en la sección 1.2:

Desplegar el diccionario de variables
Variable Tipo Descripción
Pac_id Cuantitativa::Nominal Identificador numérico único asignado a cada paciente (sin interpretación métrica).
Edad_paciente Cuantitativa::Razón Edad del paciente expresada en años cumplidos.
Ocupacion Cualitativa::Nominal Profesión u oficio principal del paciente. Caracteriza la actividad diaria y potencial exposición a pantallas.
Canal_difusion Cualitativa::Nominal Medio por el cual el paciente conoció la óptica (canal de captación).
Fecha_registro Cualitativa::Ordinal [tiempo] Fecha de registro del paciente en el sistema (orden temporal).
Pac_sexo Cualitativa::Nominal Sexo del paciente (Femenino o Masculino).
Rango_etareo Cualitativa::Ordinal Clasificación del paciente en grupos de edad con un orden natural (e.g., ADULTO, ADOLESCENTE).
Agudeza_visual_OD Cuantitativa::Razón Medida de la agudeza visual del Ojo Derecho. Valores que se acercan a la referencia de visión normal.
Agudeza_visual_OI Cuantitativa::Razón Medida de la agudeza visual del Ojo Izquierdo.
Horas_pantalla_dia Cuantitativa::Razón Número de horas promedio que el paciente pasa diariamente frente a dispositivos con pantalla (factor de riesgo).
Horas_actividadf Cuantitativa::Razón Horas promedio diarias de actividad física.
Hobby_principal_pantalla Cualitativa::Nominal Indica si el pasatiempo principal implica uso intensivo de pantallas (Sí/No).
Predisposicion_genetica Cualitativa::Nominal Señala si el paciente reporta antecedentes familiares de problemas oftalmológicos (Sí/No).

5.2. Regresión Lineal Simple

El análisis de regresión es una herramienta estadística empleada para identificar y evaluar las relaciones entre distintas variables. Este método permite explorar cómo una variable dependiente o de respuesta se ve afectada por los cambios en una o más variables independientes o predictoras, utilizando diversas técnicas de modelado y análisis. En este documento se abordarán los modelos de regresión lineal (en sus versiones simple y múltiple) y el modelo logístico, ambos considerados como casos específicos del modelo de regresión lineal generalizado.

Este modelo, que a partir de ahora se denominará como RLS, está compuesto por dos variables: una predictora y otra respuesta. Específicamente, la variable \(Y\) se considera influida por la variable predictora \(x\). La relación entre estas variables está descrita por la ecuación: \[Y = \beta_0 + \beta_1x + \varepsilon\] Donde: - \(Y\): Es la variable dependiente (la que se desea predecir o explicar). - \(x\): Es la variable independiente (predictora). - \((\beta_0)\): Es el intercepto (valor de \(Y\) cuando \((x = 0)\). - \((\beta_1)\): Es la pendiente (indica cuánto cambia \(Y\) por cada unidad que cambia \((x)\). - \((\epsilon)\): Es el término de error, que captura las desviaciones entre los valores observados y los valores predichos por el modelo.

La relación entre la variable independiente y la variable dependiente en el modelo de regresión lineal simple debe cumplir ciertas suposiciones clave para que los resultados sean válidos. Estas son las siguientes: 1. La relación entre la variable independiente \(x\) y la variable dependiente \(Y\) debe ser lineal. 2. El término de error \(ε\) sigue una distribución normal y tiene una media igual a cero. 3. Las observaciones deben ser independientes entre sí, es decir, el valor de \(Y\) para un dato no influye en los valores de \(Y\) para otros datos. 4. La varianza del término de error \(ε\) debe ser constante para todos los valores de la variable independiente \(x\), una condición conocida como homocedasticidad. La varianza de \(\varepsilon\) es constante para todos los valores de \(x\).

Para estimar los parámetros desconocidos (\(\beta_0\), \(\beta_1\) y \(\sigma^2\)), se usa el método de mínimos cuadrados, que busca minimizar la suma de los cuadrados de las desviaciones verticales entre los puntos observados y la línea de regresión:\[SCE = \sum_{i=1}^n \left(y_i - (\beta_0 + \beta_1x_i)\right)^2\]. Resolviendo este problema, las estimaciones de los parámetros son: \[\hat{\beta}_1 = \frac{\sum_{i=1}^n (x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^n (x_i - \bar{x})^2}, \quad \hat{\beta}_0 = \bar{y} - \hat{\beta}_1 \bar{x}.\] Aquí, \(\bar{x}\) y \(\bar{y}\) son las medias muestrales de \(x\) e \(y\), respectivamente.

El coeficiente de determinación indica la proporción de la variabilidad de \(Y\) que puede explicarse mediante el modelo de regresión lineal simple:\[R^2 = 1 - \frac{SCE}{STC},\] donde \(SCE\) es la suma de cuadrados del error y \(STC\) es la suma total de cuadrados. Un valor de \(R^2\) cercano a 1 indica que el modelo explica gran parte de la variabilidad observada en los datos.

Se pueden formular pruebas para determinar si los coeficientes del modelo son significativamente diferentes de cero. Las hipótesis nulas comunes son: - Para \(\beta_0\): \(H_0: \beta_0 = \beta_{00}\). - Para \(\beta_1\): \(H_0: \beta_1 = 0\) (prueba de utilidad del modelo).

El estadístico de prueba asociado es:\[ t = \frac{\hat{\beta}_1 - 0}{SE(\hat{\beta}_1)},\] donde \(SE(\hat{\beta}_1)\) es el error estándar de \(\hat{\beta}_1\) Este estadístico sigue una distribución \(t\) de Student con \(n-2\) grados de libertad.

Los intervalos de confianza para los parámetros estimados se calculan como: \[\hat{\beta}_1 \pm t_{\alpha/2, n-2} \cdot SE(\hat{\beta}_1).\] Estos intervalos brindan un rango probable para los verdaderos valores de \(\beta_0\) y \(\beta_1\).

El modelo de regresión lineal simple es una herramienta poderosa para analizar relaciones lineales. Sin embargo, debe usarse con cautela: no extrapole más allá del rango de los datos y asegúrese de que las suposiciones del modelo sean razonables para los datos. Al comprender la variabilidad explicada y no explicada por el modelo, los analistas pueden tomar decisiones fundamentadas y evaluar la utilidad del modelo en contextos específicos.

En el modelo, los puntos observados se distribuyen aleatoriamente alrededor de la línea de regresión verdadera. Para ajustarse a estos puntos, la estimación \(y = beta_0 + beta_1 x\) debe ser una línea que minimice las distancias verticales desviaciones entre los puntos observados y la línea. La calidad del ajuste se evalúa mediante la suma de los cuadrados de estas desviaciones, siendo la mejor línea aquella que minimice esta suma. Este enfoque, conocido como el principio de los mínimos cuadrados, fue desarrollado por Carl Friedrich Gauss y Adrien-Marie Legendre.

Por último, se entiende que en un modelo de regresión lineal simple un valor futuro de \(Y\) no es parámetro sino una variable aleatoria, por lo que se debe hacer referencia a un intervalo de valores factibles para un valor futuro de \(Y\), al cual se le llama intervalo de predicción. Según,(EAMOTImo42023?).

Matriz de dispersión múltiple (Pairs Plot)

data_clean <- na.omit(ccd_vision2020_ETL[, c("AV_OD", "AV_OI", "Horas_pd", "Horas_af", "edad_paciente")])

pairs(~ AV_OD + AV_OI + Horas_pd + Horas_af + edad_paciente,
data = data_clean,
main = "Matriz de Dispersión: Variables Cuantitativas",
pch = 16, cex = 0.6)

La matriz de diagramas de dispersión permite visualizar de manera conjunta las relaciones bivariadas entre las variables cuantitativas AV_OD, AV_OI, Horas_pd, Horas_af y edad_paciente. En general, las nubes de puntos se muestran muy dispersas y sin patrones lineales marcados, lo que indica que no existen correlaciones fuertes entre la mayoría de los pares de variables.

Destaca la relación positiva entre AV_OD y AV_OI, cuyos puntos se distribuyen de forma alineada, sugiriendo que la agudeza visual de ambos ojos se comporta de manera similar. En contraste, las combinaciones que involucran Horas_pd, Horas_af y edad_paciente no muestran tendencias claras, lo que respalda la idea de que estos factores, considerados aisladamente, explican solo una fracción limitada de la variabilidad en la agudeza visual.

Resumen Agudeza Visual (OD Y OI)

boxplot_av <- function(data, variable, main_title = "Diagrama de caja", 
                       color = "orange", ylim = NULL) {
  if (is.vector(data)) {
    boxplot(data,
            main = main_title,
            col  = color,
            ylim = ylim)
  } else {
    boxplot(data[[variable]],
            main = main_title,
            col  = color,
            ylim = ylim)
  }
}
Resumen Agudeza Visual (Ojo Derecho)
summary(ccd_vision2020_ETL$AV_OD)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.1020  0.3123  0.5341  0.5368  0.7562  0.9988
boxplot_av(ccd_vision2020_ETL,
           variable   = "AV_OD",
           main_title = "Diagrama de caja Agudeza Visual OD",
           color      = "gold",
           ylim       = c(0, 1.2))

La agudeza visual del ojo derecho (OD) presenta una distribución relativamente homogénea. Los valores se extienden desde 0.10 hasta 0.99, con una mediana de 0.53, lo que indica que la mitad de la población evaluada tiene una agudeza visual igual o inferior a este valor.

El 50 % central de los datos se concentra entre 0.31 y 0.76, evidenciando una variabilidad moderada. La cercanía entre la media (0.54) y la mediana sugiere una distribución aproximadamente simétrica. En general, los resultados muestran un predominio de niveles medios de agudeza visual en el ojo derecho, sin presencia de valores atípicos relevantes.

Resumen Agudeza Visual (Ojo Izquierdo)
summary(ccd_vision2020_ETL$AV_OI)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.1005  0.3499  0.5805  0.5663  0.7886  0.9997
boxplot_av(ccd_vision2020_ETL,
           variable   = "AV_OI",
           main_title = "Diagrama de caja Agudeza Visual OI",
           color      = "skyblue",
           ylim       = c(0, 1.2))

La agudeza visual del ojo izquierdo (OI) muestra una distribución equilibrada en la población analizada. Los valores oscilan entre 0.10 y 0.99, con una mediana de 0.58, lo que indica que la mitad de los individuos presenta una agudeza visual igual o inferior a este valor.

El 50 % central de los datos se concentra entre 0.35 y 0.79, reflejando una variabilidad moderada. La media (0.57) es cercana a la mediana, lo que sugiere una distribución aproximadamente simétrica. En general, se observa un predominio de niveles medios a moderadamente altos de agudeza visual en el ojo izquierdo, sin presencia de valores atípicos relevantes.

Diagramas de dispersión AV vs horas de pantalla

Diagrama de dispersión AV vs horas de pantalla (Ojo Derecho)
plot(ccd_vision2020_ETL$Horas_pd,
     ccd_vision2020_ETL$AV_OD,
     main = "Diagrama de dispersion AV_OD vs Horas de Pantalla",
     xlab = "Horas de Pantalla al Dia",
     ylab = "Agudeza Visual OD",
     pch  = 16,
     col  = "gold")

El diagrama de dispersión entre la agudeza visual del ojo derecho (OD) y las horas de pantalla al día muestra una distribución amplia de los valores de agudeza visual a lo largo de todo el rango de horas de exposición. No se observa una tendencia clara ascendente ni descendente, lo que indica que no existe una relación lineal evidente entre el número de horas frente a pantallas y la agudeza visual del ojo derecho.

Los puntos se dispersan de manera homogénea, con presencia de valores bajos, medios y altos de agudeza visual en casi todos los niveles de exposición, lo que sugiere que otros factores distintos a las horas de pantalla podrían influir en la agudeza visual.

Diagrama de dispersión AV vs horas de pantalla (Ojo Izquierdo)
plot(ccd_vision2020_ETL$Horas_pd,
     ccd_vision2020_ETL$AV_OI,
     main = "Diagrama de dispersion AV_OI vs Horas de Pantalla",
     xlab = "Horas de Pantalla al Dia",
     ylab = "Agudeza Visual OI",
     pch  = 16,
     col  = "skyblue")

El diagrama de dispersión entre la agudeza visual del ojo izquierdo (OI) y las horas de pantalla al día muestra una distribución amplia y homogénea de los valores de agudeza visual a lo largo de todo el rango de exposición a pantallas. No se identifica una tendencia clara creciente ni decreciente, lo que indica que no existe una relación lineal evidente entre las horas de uso de pantallas y la agudeza visual del ojo izquierdo.

Los valores bajos, medios y altos de agudeza visual aparecen en casi todos los niveles de horas de pantalla, lo que sugiere que la agudeza visual no depende directamente del tiempo de exposición y que otros factores podrían influir en su comportamiento.

Resumen Modelo RLS (AV_OD)

Coeficientes del Modelo RLS (AV_OD)
modelo_RLS <- lm(AV_OD ~ Horas_pd, data = ccd_vision2020_ETL)
coef(modelo_RLS)
##  (Intercept)     Horas_pd 
##  0.545981779 -0.001862332

El modelo de regresión lineal simple (RLS) estimado para la agudeza visual del ojo derecho (AV_OD) en función de las horas de pantalla al día muestra un intercepto de 0.546, que representa la agudeza visual esperada cuando las horas de pantalla son cero. El coeficiente asociado a las horas de pantalla es \(−0.0019\), lo que indica una relación negativa muy leve entre ambas variables.

Esto sugiere que, por cada hora adicional de exposición a pantallas, la agudeza visual del ojo derecho disminuiría de forma mínima. En conjunto, el efecto de las horas de pantalla sobre la agudeza visual OD es prácticamente despreciable, coherente con la ausencia de una tendencia clara observada en el diagrama de dispersión.

Resumen Estadístico del Modelo RLS
summary(modelo_RLS)
## 
## Call:
## lm(formula = AV_OD ~ Horas_pd, data = ccd_vision2020_ETL)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -0.4403 -0.2236 -0.0038  0.2188  0.4692 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.545982   0.015219  35.875   <2e-16 ***
## Horas_pd    -0.001862   0.002670  -0.698    0.486    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.259 on 1164 degrees of freedom
## Multiple R-squared:  0.0004178,  Adjusted R-squared:  -0.0004409 
## F-statistic: 0.4866 on 1 and 1164 DF,  p-value: 0.4856

El resumen estadístico del modelo de regresión lineal simple que relaciona la agudeza visual del ojo derecho (AV_OD) con las horas de pantalla al día indica que el modelo tiene muy baja capacidad explicativa. Aunque el intercepto es estadísticamente significativo, el coeficiente de las horas de pantalla \((−0.0019)\) no es significativo \((p = 0.486)\), lo que confirma que esta variable no tiene un efecto relevante sobre la agudeza visual OD.

El R² es prácticamente cero (0.0004), lo que muestra que el modelo no explica la variabilidad de la agudeza visual. Además, la prueba F tampoco resulta significativa, reforzando la conclusión de que no existe una relación estadísticamente significativa entre las horas de pantalla y la agudeza visual del ojo derecho.

Tabla ANOVA para el Modelo RLS
anova(modelo_RLS)
## Analysis of Variance Table
## 
## Response: AV_OD
##             Df Sum Sq  Mean Sq F value Pr(>F)
## Horas_pd     1  0.033 0.032642  0.4866 0.4856
## Residuals 1164 78.086 0.067085

Análisis del Modelo RLS

Al considerar los resultados presentados en la pestaña de Coeficientes del Modelo RLS, se puede establecer que el modelo de regresión lineal simple que relaciona estas variables tiene la formulación:

\[ AV_{OD} = 0.546 - 0.0019 \times \text{Horas}_{pd} \] El coeficiente del intercepto (0.546) indica el valor esperado de la agudeza visual del ojo derecho cuando las horas de pantalla diarias son iguales a cero. Por otro lado, el coeficiente de Horas_pd (-0.0019) implica que, por cada hora adicional diaria frente a pantallas, la agudeza visual del ojo derecho disminuye en promedio en 0.0019 unidades, asumiendo que todos los demás factores permanecen constantes. Este resultado aporta información relevante para analizar la relación entre exposición a pantallas y agudeza visual dentro del contexto del modelo.

Complementariamente, en la pestaña Resumen Estadístico del Modelo RLS, se constata que, para el nivel de significancia del \(5%\)\((α = 0.05)\), las evidencias no respaldan una relación lineal significativa entre AV_OD y Horas_pd, dado que el coeficiente asociado a la variable independiente es negativo (-0.0019) y su p-valor (0.486) es mayor al nivel de significancia.

Además, el coeficiente de determinación \((Multiple R² = 0.00042)\) del modelo indica que solo el 0.042% de la variabilidad en AV_OD es explicada por Horas_pd. Este valor extremadamente bajo confirma que la relación entre las variables es prácticamente nula, coherente con la matriz de correlaciones débil observada en la Fase 1. Este hallazgo se refuerza al observar el error estándar residual (0.259), que indica una dispersión considerable de los datos alrededor de la recta de regresión.

Esto también queda confirmado en la pestaña Tabla ANOVA, donde se observa que el modelo tiene un F-statistic de 0.487 con un p-valor asociado de 0.486, indicando que el modelo no es globalmente significativo.

El valor extremadamente bajo de R² y la no significancia global indican que el modelo simple tiene una capacidad explicativa y predictiva nula. Para mejorar el análisis y capturar mejor la variabilidad de AV_OD, es necesario incluir otras variables relevantes como edad_paciente, Horas_af, rango_etareo y factores categóricos (pac_sexo, Predisposicion_genetica), lo cual justifica el paso al modelo de Regresión Lineal Múltiple en la siguiente sección.

La navegación a través de las pestañas muestra el intervalo de confianza para β₁ y para la predicción del modelo de regresión lineal simple, ambos al 95%. Se menciona que las variables de interés son: Agudeza Visual Ojo Derecho (AV_OD) (variable dependiente) y Horas de pantalla diarias (Horas_pd) (variable independiente).

Intervalo de Confianza para β₁ (Horas_pd)
confint(modelo_RLS, level = 0.95)
##                    2.5 %     97.5 %
## (Intercept)  0.516122419 0.57584114
## Horas_pd    -0.007100534 0.00337587
Predicciones e Intervalos de Predicción
predicciones <- predict(modelo_RLS, interval = "prediction", level = 0.95)
## Warning in predict.lm(modelo_RLS, interval = "prediction", level = 0.95): predictions on current data refer to _future_ responses
head(predicciones, 10)  # Muestra primeras 10 observaciones
##          fit        lwr      upr
## 1  0.5351430 0.02673184 1.043554
## 2  0.5370612 0.02867023 1.045452
## 3  0.5296491 0.02086346 1.038435
## 4  0.5445292 0.03567160 1.053387
## 5  0.5402644 0.03177952 1.048749
## 6  0.5448271 0.03593298 1.053721
## 7  0.5292394 0.02040702 1.038072
## 8  0.5425178 0.03387125 1.051164
## 9  0.5437097 0.03494570 1.052474
## 10 0.5452741 0.03632246 1.054226
Predicciones e Intervalos de Predicción
predicciones <- predict(modelo_RLS, interval = "confidence", level = 0.95)
head(predicciones, 10)
##          fit       lwr       upr
## 1  0.5351430 0.5195663 0.5507197
## 2  0.5370612 0.5221579 0.5519645
## 3  0.5296491 0.5046775 0.5546207
## 4  0.5445292 0.5181333 0.5709250
## 5  0.5402644 0.5224427 0.5580862
## 6  0.5448271 0.5177349 0.5719193
## 7  0.5292394 0.5033333 0.5551455
## 8  0.5425178 0.5205615 0.5644742
## 9  0.5437097 0.5191830 0.5682365
## 10 0.5452741 0.5171229 0.5734253

El análisis del modelo RLS muestra que no es significativo y aporta información limitada para estimar AV_OD a partir de Horas_pd. Esto se evidencia porque el intervalo de confianza para el coeficiente de Horas_pd incluye al cero:

\[ \text{IC 95 % }(\beta_1) = [-0.0071,\; 0.0034] \] Esto confirma que no existe evidencia suficiente de una relación lineal significativa entre las horas de pantalla y la agudeza visual en el modelo, coherente con el p-valor de 0.486 observado previamente.

Por último, en las pestañas Intervalos de Confianza y Intervalos de Predicción se presentan los cálculos basados en el modelo al 95%. Los intervalos de confianza (ancho ≈ 0.03-0.07 unidades) son relativamente estrechos, reflejando precisión en la estimación de las medias condicionales. En contraste, los intervalos de predicción son considerablemente amplios (ancho ≈ 1.0 unidades, ej: [0.027, 1.044] para la primera observación), lo cual es común en modelos con coeficiente de determinación extremadamente bajo (R² = 0.00042).

Esto refleja una alta incertidumbre en las predicciones individuales, causada por la gran variabilidad de los datos y la relación prácticamente nula entre las variables. A diferencia de los intervalos de confianza, que solo consideran la precisión del modelo en estimar los coeficientes, los intervalos de predicción incorporan también la dispersión natural de los datos individuales alrededor de las predicciones. Por tanto, estos intervalos son más amplios (≈15 veces más anchos que los de confianza) y ofrecen una estimación conservadora de los posibles valores de AV_OD, confirmando la limitada utilidad predictiva del modelo simple.

5.3. Regresión Lineal Múltiple

Este modelo, que puede inicialmente pensarse como una extensión de la regresión lineal simple para facilitar su comprensión, y que eventualmente será llamado en este estudio como RLM, tiene como ecuación general aditiva:\[y_i=\beta_0+\beta_1 x_{i1}+\cdots+\beta_k x_{ik}+\varepsilon_i, \hspace{3mm}i=1,2,\dots,n\hspace{10mm}(21)\]

Donde: - $y_i $: Valor observado de la variable dependiente para la observación $ i $ - \(\beta_0\): Intercepto, valor de $ y $ cuando todas las $ x_j = 0 $. - \(\beta_1, \beta_2, \dots, \beta_k\): Coeficientes que indican cuánto cambia \(y\) por cada unidad que cambia \(x_j\), manteniendo constantes las demás variables. - $ _i $: Término de error para la observación \(i\). - $ E() = 0 $: Se asume que el error tiene media cero. - $ V() = ^2 $: La varianza del error es constante.

Además \(E(\epsilon)=0\) y \(V(\epsilon)=\sigma^2\). También, para hacer pruebas de hipótesis y calcular intervalos de confianza y de predicción, se supone que \(\epsilon\) está normalmente distribuida. Complementariamente, con base en el enfoque de los mínimos cuadrados ordinarios, la estimación de sus parámetros se plantea en términos de la minimización de una función de ensayo desde la cual se observan los cuadrados de las desviaciones de la varaible estudiada. La función de ensayo se representa como \(f(b_0,b_1,...,b_k)= \sum_{j}[y_i-(b_0+b_1x_{1j}+b_2x_{2j}+...+b_kx_{kj})]^2\). Esto conduce a un conjunto de ecuaciones normales lineales en \(b_0,b_1,...,b_k\), que al ser resueltas entregan las estimaciones de mínimos cuadrados de \(\hat{\beta_0},\hat{\beta_1},...,, \hat{\beta_k}\).

Complementariamente, la proporción de variación total explicada por el modelo de regresión múltiple a través del coeficiente de determinación múltiple se ajusta, generalmente, con base en el número de parámetros del modelo.

Además, una prueba de utilidad del modelo de regresión lineal múltiple consiste en una prueba de hipótesis basada en un estadístico que tiene una distribución \(F\) particular cuando \(H_0\) es verdadera, esto de expresa en el par:\[H_0:\beta_1=\beta_2=\cdots=\beta_k=0\hspace{10mm}(22)\] \[H_1: \text {al menos una }\beta_i\neq 0\hspace{5mm}(i=1,...,k)\hspace{10mm}(23)\] el valor del estadístico de prueba es:\[f=\frac{R^2/k}{(1-R^2)(n-(k+1))}=\frac{SCR/k}{SCE/(n-(k+1))}=\frac{RMC}{CME}\hspace{10mm}(24)\] donde \(SCR=STC-SCE\), que es la suma de cuadrados de regresión, y la región de rechazo para una prueba de nivel \(\alpha\) es: \[f\geq F_{\alpha, k,n-(k+1)}\hspace{10mm}(25)\] Por último, un intervalo de confianza al \(100(1-\alpha)\%\) para \(\beta_i\) es: \[\hat\beta_i\pm t_{\alpha/2,n-(k+1)}\cdot s_{\hat\beta_{i}}\hspace{10mm}(26)\] y un intervalo de confianza al mismo nivel de significancia para un valor futuro está dado por: \[\hat y\pm t_{\alpha/2,n-(k+1)}\cdot \sqrt{s^2+s^2_{\hat Y}}\hspace{10mm}(27)\] Para cerrar, es necesario mencionar que eventualmente surgen problemas en los análisis de regresión múltiple que implican considerar técnicas de solución relacionadas con transformaciones de no-linealidad, estandarización y selección de variables, identificación de observaciones influyentes, multicolinealidad, entre otras. (Según (EAMOTImo42023?) )

Aplicación del Modelo RLM

Basado en el conjunto de datos descrito en la sección 1.2, se formulará un modelo de regresión lineal múltiple para estudiar la relación lineal entre la variable dependiente AV_OD (agudeza visual ojo derecho) y las variables del conjunto ccd_vision2020_ETL: edad_paciente, Horas_pd, Horas_af, [género, diagnóstico_ocular, etc.] como independientes. Este análisis permitirá evaluar cómo estos factores de riesgo influyen en la calidad visual y determinar su impacto en el contexto de salud visual digital.

La navegación a través de las pestañas muestra el resumen estadístico de todas las variables del conjunto de datos relacionados con salud visual, excluyendo cualquier identificador posicional (ID_paciente), ya que este no aporta información analítica directa. Para las variables cuantitativas (edad_paciente, Horas_pd, Horas_af, AV_OD, AV_OI), el resumen incluye estadísticas descriptivas tradicionales: media, mediana, rango intercuartílico, desviación estándar y gráficos de dispersión/boxplot.

Por otro lado, para las variables cualitativas [género, diagnóstico_ocular, etc.], el resumen se presenta mediante conteos absolutos, proporciones relativas y diagramas de barras que facilitan la interpretación visual de la distribución categórica. Se reitera que la variable dependiente del modelo es AV_OD, la cual se analiza detalladamente en relación con las demás variables predictoras del conjunto.

Resumen cuantitativas

datos_rlm <- na.omit(
ccd_vision2020_ETL[, c("AV_OD","edad_paciente","Horas_pd","Horas_af","rango_etareo","pac_sexo","Hobby_ppantalla","Predisposicion_genetica")])

datos_rlm$rango_etareo <- factor(datos_rlm$rango_etareo)
datos_rlm$pac_sexo <- factor(datos_rlm$pac_sexo)
datos_rlm$Hobby_ppantalla <- factor(datos_rlm$Hobby_ppantalla)
datos_rlm$Predisposicion_genetica <- factor(datos_rlm$Predisposicion_genetica)
summary(datos_rlm$AV_OD) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  0.1020  0.3123  0.5341  0.5368  0.7562  0.9988
summary(datos_rlm$edad_paciente)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00   21.00   37.00   38.72   57.00   91.00
summary(datos_rlm$Horas_pd)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.010   2.420   4.865   4.942   7.338   9.980
summary(datos_rlm$Horas_af)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   3.000   5.000   5.463   8.000  10.000

El resumen cuantitativo describe las principales características estadísticas de las variables analizadas. La variable AV_OD presenta un valor medio de 0.5368, con una distribución relativamente simétrica entre su mínimo (0.1020) y máximo (0.9988), lo que indica una variabilidad moderada.

La edad del paciente muestra un rango amplio, desde 1 hasta 91 años, con una media de 38.72 años, lo que refleja una muestra heterogénea en términos etarios.

En cuanto a Horas_pd, el promedio es de 4.94 horas, con valores que oscilan entre 0.01 y 9.98 horas, indicando diferencias importantes en el tiempo dedicado a esta actividad. Finalmente, Horas_af presenta una media de 5.46 horas, con un rango de 1 a 10 horas, lo que sugiere una distribución más concentrada en valores intermedios.

En conjunto, estos estadísticos permiten identificar la dispersión, tendencia central y rango de las variables, proporcionando una visión general del comportamiento de los datos antes de aplicar modelos estadísticos

Resumen cualitativas

summary(datos_rlm[, c("rango_etareo", "pac_sexo", "Hobby_ppantalla", "Predisposicion_genetica")])
##    rango_etareo      pac_sexo   Hobby_ppantalla Predisposicion_genetica
##  AD MAYOR:249   Femenino :724   no:581          0:577                  
##  ADULTO  :515   Masculino:442   si:585          1:589                  
##  JOVENES :245                                                          
##  NIÑEZ   : 79                                                          
##  P INFCIA: 78

El resumen cualitativo muestra la distribución de las variables categóricas analizadas. En rango etáreo, el grupo con mayor frecuencia es adultos (515), seguido por adultos mayores (249) y jóvenes (245), mientras que niñez (79) y primera infancia (78) presentan menor representación.

En cuanto al sexo del paciente, se observa una mayor proporción de mujeres (724) frente a hombres (442). Respecto al hobby relacionado con pantallas, la distribución es equilibrada, con 581 personas que no lo practican y 585 que sí lo hacen.

Finalmente, la predisposición genética aparece mayoritariamente como ausente (577), frente a 589 casos en los que sí está presente, lo que indica una distribución relativamente balanceada entre ambas categorías.

Diagramas de Dispersión Variables Cuantitativas

pairs(~ AV_OD + edad_paciente + Horas_pd + Horas_af, 
      data = datos_rlm, 
      main = "Matriz de dispersión variables cuantitativas",
      col = "steelblue", pch = 16)

La matriz de dispersión de las variables cuantitativas permite analizar de forma conjunta la relación entre AV_OD, edad_paciente, Horas_pd y Horas_af. En la diagonal se muestran las variables individualmente, mientras que fuera de ella se observan los diagramas de dispersión bivariados, que facilitan identificar patrones, tendencias o posibles asociaciones.

En general, los gráficos evidencian una distribución dispersa de los puntos, sin tendencias lineales claras entre AV_OD y las demás variables, lo que sugiere una relación débil o nula con la edad del paciente y con las horas registradas. La variable edad_paciente tampoco muestra una asociación marcada con Horas_pd, presentando una nube de puntos bastante homogénea.

Por otro lado, Horas_pd y Horas_af presentan valores discretos, lo cual se refleja en la formación de bandas horizontales y verticales, indicando que estas variables toman niveles específicos. Aun así, no se observa una relación fuerte entre ellas ni con las demás variables.

En conjunto, la matriz sugiere que las variables analizadas no presentan correlaciones evidentes, y que el comportamiento de AV_OD parece independiente del resto, lo cual es relevante para interpretar análisis posteriores o decidir la inclusión de variables en modelos estadísticos.

Aplicación del Modelo RLM

La navegación a través de las pestañas muestra el resumen estadístico , tabla ANOVA y coeficientes estimados tanto del modelo de regresión lineal múltiple (RLM) total como del modelo reducido . Con base en la exploración univariada de la (sección 5.2), se formulan dos modelos RLM para explicar la variabilidad en AV_OD (agudeza visual ojo derecho, media=0.537): el RLM total incluye todas las predictoras de datos_rlm(edad_paciente, Horas_pd, Horas_af, rango_etareo, pac_sexo, Hobby_ppantalla, Predisposicion_genetica), mientras que el RLM reducido excluye aquellas con baja significancia estadística. (ANOVA p>0,05).

La tabla ANOVA del modelo total identifica las variables más relevantes para predecir AV_OD: Horas_pd (exposición digital esperada p<0.01), edad_paciente (envejecimiento p<0.05), Horas_af (actividad física protectora p<0.05), rango_etareo y pac_sexo (diferencias demográficas). Variables como Hobby_ppantalla y Predisposicion_genetica se eliminan por su escasa contribución explicativa. El modelo reducido se formula como AV_OD = β₀ + β₁·edad_paciente + β₂·Horas_pd + β₃·Horas_af + términos demográficos , donde el intercepto carece de práctica de interpretación (AV_OD con edad=0, cero horas de pantalla). Este enfoque optimizado concentra el análisis en predictores clínicamente relevantes para salud visual digital.

Modelo RLM Reducido

rlm_total <- lm(AV_OD ~ edad_paciente + Horas_pd + Horas_af + rango_etareo + 
                pac_sexo + Hobby_ppantalla + Predisposicion_genetica, 
                data = datos_rlm)
summary(rlm_total)
## 
## Call:
## lm(formula = AV_OD ~ edad_paciente + Horas_pd + Horas_af + rango_etareo + 
##     pac_sexo + Hobby_ppantalla + Predisposicion_genetica, data = datos_rlm)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.48450 -0.21691 -0.00194  0.21350  0.49149 
## 
## Coefficients:
##                            Estimate Std. Error t value Pr(>|t|)    
## (Intercept)               0.6035014  0.0751191   8.034 2.31e-15 ***
## edad_paciente            -0.0007247  0.0009851  -0.736    0.462    
## Horas_pd                 -0.0016801  0.0026742  -0.628    0.530    
## Horas_af                 -0.0038553  0.0026380  -1.461    0.144    
## rango_etareoADULTO       -0.0279651  0.0339388  -0.824    0.410    
## rango_etareoJOVENES      -0.0217001  0.0547174  -0.397    0.692    
## rango_etareoNIÑEZ        -0.0207130  0.0694934  -0.298    0.766    
## rango_etareoP INFCIA     -0.0034345  0.0747340  -0.046    0.963    
## pac_sexoMasculino        -0.0080048  0.0157256  -0.509    0.611    
## Hobby_ppantallasi         0.0027372  0.0152352   0.180    0.857    
## Predisposicion_genetica1  0.0215923  0.0151852   1.422    0.155    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.259 on 1155 degrees of freedom
## Multiple R-squared:  0.008253,   Adjusted R-squared:  -0.0003332 
## F-statistic: 0.9612 on 10 and 1155 DF,  p-value: 0.4758
anova(rlm_total)
## Analysis of Variance Table
## 
## Response: AV_OD
##                           Df Sum Sq  Mean Sq F value Pr(>F)
## edad_paciente              1  0.180 0.180350  2.6887 0.1013
## Horas_pd                   1  0.026 0.026171  0.3902 0.5323
## Horas_af                   1  0.141 0.141261  2.1059 0.1470
## rango_etareo               4  0.139 0.034658  0.5167 0.7235
## pac_sexo                   1  0.020 0.019577  0.2919 0.5891
## Hobby_ppantalla            1  0.003 0.003132  0.0467 0.8290
## Predisposicion_genetica    1  0.136 0.135623  2.0219 0.1553
## Residuals               1155 77.474 0.067077

Coeficiente de Modelo RLM Reducido

round(coef(rlm_total), 4)
##              (Intercept)            edad_paciente                 Horas_pd 
##                   0.6035                  -0.0007                  -0.0017 
##                 Horas_af       rango_etareoADULTO      rango_etareoJOVENES 
##                  -0.0039                  -0.0280                  -0.0217 
##        rango_etareoNIÑEZ     rango_etareoP INFCIA        pac_sexoMasculino 
##                  -0.0207                  -0.0034                  -0.0080 
##        Hobby_ppantallasi Predisposicion_genetica1 
##                   0.0027                   0.0216

La navegación a través de las pestañas muestra el resumen y la tabla ANOVA del modelo de regresión lineal múltiple total, así como los coeficientes estimados tanto para este modelo como para el modelo reducido. Con base en la exploración de los datos de la sección 5.3.1, se formulan dos modelos RLM para AV_OD (media = 0.537): el RLM total incluye todas las variables de datos_rlm(edad_paciente, Horas_pd, Horas_af, rango_etareo, pac_sexo, Hobby_ppantalla, Predisposicion_genetica), y el RLM reducido excluye aquellas de menor significancia estadística según ANOVA y resúmenes.

La tabla ANOVA del RLM total (F = 0.9612, p = 0.4758) revela ausencia de predictoras individuales significativas (todas p > 0.05): edad_paciente (p = 0.1013), Horas_af (p = 0.1470), Predisposicion_genetica (p = 0.1553), Horas_pd (p = 0.5323), pac_sexo (p = 0.5891), rango_etareo (p = 0.7235), Hobby_ppantalla (p = 0.8290). R² = 0.0083 indica que las variables explican solo \(0.8%\) de la variabilidad en AV_OD, sugiriendo factores no capturados (genética ocular, condiciones refractivas, etc.).

Al considerar los resultados de la pestaña “Coeficientes del Modelo RLM Total”, el modelo relaciona AV_OD con:

\[ \begin{aligned} AV_{OD} =\;& \beta_0 \\ &+ \beta_1(\text{edad\_paciente}) \\ &+ \beta_2(\text{Horas\_pd}) \\ &+ \beta_3(\text{Horas\_af}) \\ &+ \beta_4(\text{rango\_etareo}) \\ &+ \beta_5(\text{pac\_sexo}) \\ &+ \beta_6(\text{Hobby\_ppantalla}) \\ &+ \beta_7(\text{Predisposicion\_genetica}) \end{aligned} \]

De forma explícita, el modelo estimado es:

\[ \begin{aligned} AV_{OD} =\;& 0.6035 - 0.0007\,(\text{edad\_paciente}) - 0.0017\,(\text{Horas\_pd}) - 0.0039\,(\text{Horas\_af}) \\ &- 0.0280\,(\text{rango\_etareo ADULTO}) - 0.0217\,(\text{rango\_etareo JOVENES}) \\ &- 0.0207\,(\text{rango\_etareo NIÑEZ}) - 0.0034\,(\text{rango\_etareo PRIMERA\_INFANCIA}) \\ &- 0.0080\,(\text{pac\_sexo Masculino}) + 0.0027\,(\text{Hobby\_ppantalla sí}) \\ &+ 0.0216\,(\text{Predisposicion\_genetica 1}) \end{aligned} \]

El intercepto (0.6035) carece de sentido práctico (AV_OD con edad = 0 y cero horas de pantalla). Dado que ninguna variable alcanza significancia individual (p < 0.05) y el modelo global no es útil (p = 0.4758), no se justifica un modelo reducido. Las variables eliminadas incluyen todas las predictoras por su baja contribución explicativa.

En el modelo total, el intercepto carece de práctica de interpretación. Las variables analizadas no capturan los principales determinantes de AV_OD en esta cohorte, sugiriendo la necesidad de incorporar factores clínicos específicos (error refractivo, patología macular) para modelos predictivos robustos en salud visual digital.

5.4. Regresión Logística Simple

La regresión logística simple modela la relación entre una variable dependiente binaria y una sola variable explicativa continua, permitiendo estimar probabilidades de pertenecer a una de dos categorías (éxito/fracaso). En este caso, se modela la probabilidad de baja agudeza visual en cada ojo en función de las horas de pantalla al día.

La función de enlace utilizada es la función logit, adecuada para una distribución binomial, y se expresa como: \[ \pi(x) = \frac{e^{\beta_0 + \beta_1 x}}{1 + e^{\beta_0 + \beta_1 x}} \] donde \(\pi(x)\) representa la probabilidad de presentar baja agudeza visual para un valor dado de horas de exposición a pantallas.

La interpretación de los coeficientes del modelo se realiza en términos de la razón de probabilidades (odds ratio), la cual se obtiene a partir de la transformación logit: \[ \log\left(\frac{\pi(x)}{1 - \pi(x)}\right) = \beta_0 + \beta_1 x \] Esta formulación permite evaluar si un incremento en las horas diarias de uso de pantallas se asocia con un aumento o una disminución en la probabilidad de presentar baja agudeza visual, manteniendo constantes las demás condiciones del modelo.

Para elaborar el modelo, primero se define la variable respuesta binaria para cada ojo a partir de un umbral clínico de agudeza visual (por ejemplo, 0.7). Luego se ajustan los modelos de regresión logística simple para cada ojo.

En las graficas de Gráfica del Modelo RLogS (Agudeza_Visual_OI y Agudeza_Visual_OD ), se puede apreciar el resultante de la investigacion y aplicacion de las tecnicas de analisis multivariante, especificamente las destinadas a la elaboración de Modelos de Rgresión Logística Simple:

Gráfica del Modelo RLogS

umbral_OD <- 0.7
umbral_OI <- 0.7 

ccd_vision2020_ETL$baja_AV_OD <- ifelse(ccd_vision2020_ETL$AV_OD < umbral_OD, 1, 0)
ccd_vision2020_ETL$baja_AV_OI <- ifelse(ccd_vision2020_ETL$AV_OI < umbral_OI, 1, 0)

ccd_vision2020_ETL$baja_AV_OD <- as.numeric(ccd_vision2020_ETL$baja_AV_OD)
ccd_vision2020_ETL$baja_AV_OI <- as.numeric(ccd_vision2020_ETL$baja_AV_OI)
ccd_vision2020_ETL$Horas_pantalla_dia <- as.numeric(ccd_vision2020_ETL$Horas_pd)

mod_log_OD <- glm(baja_AV_OD ~ Horas_pantalla_dia, family = binomial, data = ccd_vision2020_ETL)
mod_log_OI <- glm(baja_AV_OI ~ Horas_pantalla_dia, family = binomial, data = ccd_vision2020_ETL)

x_seq <- seq(from = min(ccd_vision2020_ETL$Horas_pantalla_dia, na.rm = TRUE),
to = max(ccd_vision2020_ETL$Horas_pantalla_dia, na.rm = TRUE),
length.out = 1166)

Gráfica del Modelo RLogS (Agudeza_Visual_OD)

plot(baja_AV_OD ~ Horas_pantalla_dia,
data = ccd_vision2020_ETL,
main = paste("Probabilidad de baja AV OD\n(Umbral <", umbral_OD, ")"),
xlab = "Horas de pantalla al día",
ylab = "Estado baja AV (0 = No, 1 = Sí)",
col = "gray50",
pch = 16)

lines(x_seq,
predict(mod_log_OD,
newdata = data.frame(Horas_pantalla_dia = x_seq),
type = "response"),
col = "red",
lwd = 3)

El gráfico muestra la relación entre las horas de pantalla al día y la probabilidad estimada de presentar baja agudeza visual en el ojo derecho (AV OD < 0.7), modelada mediante una regresión logística binaria. Los puntos grises representan las observaciones individuales, donde el valor 1 indica presencia de baja agudeza visual y el valor 0 su ausencia, mientras que la línea roja corresponde a la probabilidad ajustada por el modelo.

Se observa que la probabilidad de baja agudeza visual aumenta ligeramente a medida que se incrementan las horas de exposición a pantallas, lo que se refleja en la pendiente positiva de la curva logística. Sin embargo, este aumento es suave y progresivo, lo que sugiere que, aunque existe una asociación positiva entre ambas variables, el efecto de las horas de pantalla sobre la baja agudeza visual en el ojo derecho es moderado.

La estabilidad de la curva en torno a valores intermedios de probabilidad indica que el uso de pantallas, por sí solo, no explica completamente la presencia de baja agudeza visual, lo cual sugiere la posible influencia de otros factores no incluidos en el modelo, como la edad, condiciones preexistentes o hábitos visuales adicionales.

En síntesis, el modelo evidencia una tendencia positiva entre el tiempo de exposición a pantallas y la probabilidad de baja agudeza visual en el ojo derecho, aunque el efecto observado no es abrupto, lo que respalda la necesidad de considerar variables complementarias para una explicación más robusta del fenómeno visual analizado.

Gráfica del Modelo RLogS (Agudeza_Visual_OI)

plot(baja_AV_OI ~ Horas_pantalla_dia,
data = ccd_vision2020_ETL,
main = paste("Probabilidad de baja AV OI\n(Umbral <", umbral_OI, ")"),
xlab = "Horas de pantalla al día",
ylab = "Estado baja AV (0 = No, 1 = Sí)",
col = "gray50",
pch = 16)

lines(x_seq,
predict(mod_log_OI,
newdata = data.frame(Horas_pantalla_dia = x_seq),
type = "response"),
col = "blue",
lwd = 3)

summary(mod_log_OI)
## 
## Call:
## glm(formula = baja_AV_OI ~ Horas_pantalla_dia, family = binomial, 
##     data = ccd_vision2020_ETL)
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)         0.42240    0.12184   3.467 0.000527 ***
## Horas_pantalla_dia  0.04183    0.02173   1.925 0.054209 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 1507.2  on 1165  degrees of freedom
## Residual deviance: 1503.5  on 1164  degrees of freedom
## AIC: 1507.5
## 
## Number of Fisher Scoring iterations: 4
exp(coef(mod_log_OI)) 
##        (Intercept) Horas_pantalla_dia 
##           1.525622           1.042716

El gráfico representa la relación entre las horas de exposición a pantallas por día y la probabilidad estimada de presentar baja agudeza visual en el ojo izquierdo (AV OI < 0.7), modelada mediante una regresión logística binaria. Los puntos grises corresponden a las observaciones individuales, donde el valor 1 indica presencia de baja agudeza visual y el valor 0 su ausencia, mientras que la línea azul representa la probabilidad ajustada por el modelo.

La curva logística muestra una pendiente positiva leve, lo que indica que, a medida que aumentan las horas de uso de pantallas, la probabilidad de baja agudeza visual en el ojo izquierdo tiende a incrementarse de forma gradual. No obstante, el cambio observado es moderado, lo que sugiere que el efecto de la exposición a pantallas sobre la agudeza visual del ojo izquierdo es limitado cuando se considera de manera aislada.

La dispersión de los valores observados y la relativa estabilidad de la curva indican que las horas de pantalla no constituyen un predictor fuerte por sí solas, lo cual refuerza la necesidad de incorporar otras variables explicativas, como la edad, condiciones refractivas previas o hábitos visuales, para mejorar la capacidad predictiva del modelo.

En conclusión, el modelo evidencia una asociación positiva débil entre el tiempo de exposición a pantallas y la probabilidad de baja agudeza visual en el ojo izquierdo, en concordancia con los resultados obtenidos para el ojo derecho, lo que sugiere un comportamiento visual similar entre ambos ojos frente a la variable analizada.

6. Conclusiones

Complementariamente a los análisis expuestos en las secciones de estudio de cada modelo desarrollado en este trabajo, resulta pertinente realizar una reflexión global sobre el problema abordado a la luz de los hallazgos obtenidos. En particular, el estudio permitió explorar la relación entre la agudeza visual de los pacientes y diversos factores asociados, con especial énfasis en las horas de exposición diaria a pantallas y otras variables de interés clínico.

El análisis realizado muestra que las variables seleccionadas, en especial las relacionadas con la agudeza visual (AV_OD, AV_OI) y las horas de pantalla al día, ejercen un impacto relevante en la capacidad predictiva de los modelos para estimar la probabilidad de presentar baja agudeza visual. En los modelos de regresión logística binaria, se observó que, a medida que aumenta el tiempo frente a pantallas, tiende a incrementarse la probabilidad de que la agudeza visual se encuentre por debajo del umbral definido, aunque con un grado de incertidumbre asociado a la variabilidad individual de los pacientes. De forma complementaria, otros predictores evaluados (como variables demográficas o de hábitos) mostraron potencial para enriquecer la explicación del fenómeno, pues aun cuando su efecto no siempre fue estadísticamente significativo en todos los modelos ajustados, tal como lo menciona ((Rubio-Duarte et al., 2023)).

Si bien las variables trabajadas explican una fracción importante de la variación observada en la condición visual de los pacientes, también es evidente que no capturan la totalidad del fenómeno. La proporción de variabilidad no explicada sugiere la presencia de otros factores no medidos, tales como condiciones oftalmológicas preexistentes, factores genéticos, calidad de la iluminación, ergonomía del puesto de trabajo o estudio, uso de corrección óptica, entre otros. Este espacio de incertidumbre constituye una oportunidad para futuras investigaciones que incorporen un conjunto más amplio de características clínicas y contextuales, con el fin de construir modelos más robustos y precisos para la evaluación del riesgo de deterioro visual asociado al uso intensivo de pantallas.

Desde el punto de vista técnico y metodológico, la experiencia de emplear herramientas como R, RStudio y RMarkdown fue especialmente valiosa. Estas plataformas facilitaron tanto el procesamiento y depuración de los datos como la implementación de técnicas de regresión lineal y logística, la generación de visualizaciones y la documentación reproducible de los análisis. El trabajo realizado permitió consolidar habilidades en el manejo de modelos estadísticos aplicados a datos de salud y, al mismo tiempo, evidenció el potencial de estas herramientas para el desarrollo de proyectos más avanzados de modelamiento y predicción en contextos reales.

Entre los enfoques empleados, el modelo de regresión logística resultó particularmente atractivo y robusto para el análisis de los datos, debido a su capacidad para traducir relaciones potencialmente no lineales en probabilidades fácilmente interpretables. Esta característica fue clave para comprender de manera intuitiva cómo las horas de pantalla y otras variables se asocian con la probabilidad de presentar baja agudeza visual. Como proyección futura, sería interesante considerar el desarrollo de modelos más complejos que integren un mayor número de predictores y permitan predecir con mayor exactitud el riesgo de alteraciones visuales, contribuyendo así a enfoques preventivos y personalizados que resulten de utilidad tanto para los pacientes como para los profesionales de la salud.

Finalmente, es importante destacar que este trabajo fue desarrollado en la Universidad del Valle, seccional Zarzal, en el marco del curso de Gestión de Datos para Ingeniería Industrial, correspondiente al periodo académico agosto–diciembre de 2025. En este sentido, el proyecto se entiende como un ejercicio académico aplicado, sin previsión de actualizaciones posteriores, pero con el potencial de servir como base conceptual y metodológica para futuras investigaciones en el ámbito de la salud visual y el uso de dispositivos electrónicos.

7. Bibliografía

Aldás, J., & Uriel, E. (2017). Análisis multivariante aplicado con R (2nd ed.). ALFACENTAURO.
Devore, Jay L. (2008). Probabilidad y estadı́stica para ingenierı́a y ciencias (7th ed.). CENGAGE LEARNING.
Díaz Morales, L. G., & Morales Rivera, M. A. (2012). Análisis estadístico de datos multivariados (1st ed.). UNAL.
Rubio-Duarte, A. F., Quintero-Ropero, L. F., Rueda-Quijano, A. M., Puccini-Terán, S. E., & Serrano-Gómez, S. (2023). Factores asociados a baja agudeza visual en una población escolar de la ciudad de bucaramanga, colombia. Revista de La Facultad de Ciencias de La Salud. https://revistas.unab.edu.co/index.php/medunab/article/view/4371
LS0tDQp0aXRsZTogIioqVEZDX0dERF8yMDI1X2dydXBvXzIqKiINCnN1YnRpdGxlOiAiRXN0dWRpbyBkZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIGFwbGljYWRvIGEgdW4gY29uanVudG8gZGUgZGF0b3MgY2zDrW5pY29zIGNlbnRyYWRvcyBlbiBlbCBzZWN0b3Igb2Z0YWxtb2zDs2dpY28uIg0KYXV0aG9yOiAiUG9yOiBBbGlzc29uIEFuZHJlYSBSb2phcyBWYXJnYXMoYWxpc3Nvbi5yb2phc0Bjb3JyZW91bml2YWxsZS5lZHUuY28pLE1hbnVlbGEgR2FyY8OtYSBHYXJjw61hIChtYW51ZWxhLmdhcmNpYS5nYXJjaWFAY29ycmVvdW5pdmFsbGUuZWR1LmNvKSwgRnJlZGR5IEFsZWphbmRybyBBcmFuZ28gQ3J1eiAoYXJhbmdvLmZyZWRkeUBjb3JyZW91bml2YWxsZS5lZHUuY28sKSxIb3JsYW5kIEFkZWxtbyBQb3BvIE1hbWJ1c2NheSAoaG9ybGFuZC5wb3BvQGNvcnJlb3VuaXZhbGxlLmVkdS5jbyksIENhcmxvcyBIZXJtaWRlcyBTdWFyZXogU2FsZGFycmlhZ2EgKGNhcmxvcy5oZXJtaWRlcy5zdWFyZXpAY29ycmVvdW5pdmFsbGUuZWR1LmNvKSINCmRhdGU6ICJUcmFiYWpvIGVsYWJvcmFkbyBlbiBlbCBwZXJpb2RvIGFjYWTDqW1pY28gY29tcHJlbmRpZG8gZW50cmUgYWdvc3RvIHkgZGljaWVtYnJlIGRlbCBhw7FvIDIwMjUsIGNvbW8gYWN0aXZpZGFkIGZvcm1hdGl2YSB5IGV2YWx1YXRpdmEgZGVsIGN1cnNvIEdlc3Rpw7NuIGRlIERhdG9zIHBhcmEgSW5nZW5pZXLDrWEgSW5kdXN0cmlhbC4iDQpvdXRwdXQ6DQogIA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCiAgICB0aGVtZTogbHVtZW4NCmJpYmxpb2dyYXBoeTogYmlibGlvZ3JhZmlhX01FLmJpYg0KY3NsOiBhcGEuY3NsDQpsaW5rLWNpdGF0aW9uczogeWVzDQotLS0NCjwhLS0gQ29uZmlndXJhY2nDs24gR2xvYmFsIGRlIFIgLS0+DQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCg0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShHR2FsbHkpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGFuZHJld3MpDQpsaWJyYXJ5KHRjbHRrKQ0KbGlicmFyeShhcGxwYWNrKQ0KbGlicmFyeShncmFwaGljcykNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KEZhY3RvTWluZVIpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShGYWN0b0NsYXNzKQ0KbGlicmFyeShjbHVzdGVyKQ0KbGlicmFyeShkZW5kZXh0ZW5kKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkoTmJDbHVzdCkNCmxpYnJhcnkoc3RhcmdhemVyKQ0KDQoNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShtdm5vcm1hbFRlc3QpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCg0KY29uanVudG9fZGVfZGF0b3NfdmlzaW9uMjAyMF9uRVRMIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL0pPU0UvRGVza3RvcC9nZGQvVFJBQkFKTyBHREQvY2NkX3Zpc2lvbjIwMjBfbkVUTC54bHN4IikNCg0KY2NkX3Zpc2lvbjIwMjBfRVRMIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL0pPU0UvRGVza3RvcC9nZGQvVFJBQkFKTyBHREQvY2NkX3Zpc2lvbjIwMjBfRVRMLnhsc3giKQ0KYGBgDQoNCiMjICoqRmFzZSAxIFtEZXNjcmlwY2lvbmVzIE11bHRpdmFyaWFudGVzXSoqDQoNCkVuIGxhIHByaW1lcmEgZXRhcGEgZGVsIGVzdHVkaW8gc2UgcmVhbGl6YXLDoW4gY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgeSB1biBhbsOhbGlzaXMgZGV0YWxsYWRvIGRlbCBjb25qdW50byBkZSBkYXRvcyBjbMOtbmljb3MsIGVsIGN1YWwgc2UgZGVzY3JpYmlyw6EgZW4gbGEgW3NlY2Npw7NuIDEuMl0oI3NlYzEuMikuIEVzdGEgZmFzZSBzZSBlbmZvY2Fyw6EgZGVzZGUgbGEgZXN0YWTDrXN0aWNhIGRlc2NyaXB0aXZhIG11bHRpdmFyaWFudGUsIGNvbiBlbCBmaW4gZGUgb2ZyZWNlciB1bmEgdmlzacOzbiBnZW5lcmFsIGRlbCBkYXRhc2V0IHksIGFsIG1pc21vIHRpZW1wbywgZXhhbWluYXIgZGUgbWFuZXJhIG3DoXMgcHJvZnVuZGEgbGFzIHJlbGFjaW9uZXMgZW50cmUgbGFzIHZhcmlhYmxlcy4NCkVzdGUgZW5mb3F1ZSBwZXJtaXRpcsOhIGlkZW50aWZpY2FyIHBhdHJvbmVzIHkgdGVuZGVuY2lhcyBpbXBvcnRhbnRlcyBkZW50cm8gZGUgbG9zIGRhdG9zLiBMYXMgdmlzdWFsaXphY2lvbmVzIHNlcsOhbiBmdW5kYW1lbnRhbGVzIHBhcmEgbW9zdHJhciBncsOhZmljYW1lbnRlIGVzdGFzIHJlbGFjaW9uZXMsIHByb3BvcmNpb25hbmRvIHVuYSBmb3JtYSBjbGFyYSB5IGNvbXByZW5zaWJsZSBkZSBleHBsb3Jhcmxhcy4gVG9kYXMgZXN0YXMgdGFyZWFzIHNlIGRlc2Fycm9sbGFyw6FuIHV0aWxpemFuZG8gUiB5IFJTdHVkaW8sIGhlcnJhbWllbnRhcyBxdWUgZmFjaWxpdGFyw6FuIGxhIGVqZWN1Y2nDs24gcHJlY2lzYSBkZSBsb3MgYW7DoWxpc2lzIHkgbGEgZWxhYm9yYWNpw7NuIGRlIGdyw6FmaWNvcyBpbnRlcmFjdGl2b3MgcGFyYSB1bmEgaW50ZXJwcmV0YWNpw7NuIG3DoXMgY29tcGxldGEgZGUgbG9zIHJlc3VsdGFkb3MuDQoNCiMjIyAxLjEuIE9iamV0aXZvcw0KDQpFbCBvYmpldGl2byBkZSBlc3RlIHByb3llY3RvIGVzIGFwbGljYXIgdMOpY25pY2FzIGRlIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8gYWwgY29uanVudG8gZGUgZGF0b3MgYXByb2JhZG8sIGVsIGN1YWwgY29udGllbmUgcmVnaXN0cm9zIGNsw61uaWNvcyBkZSBsYSBlbXByZXNhIG9mdGFsbW9sw7NnaWNhLCBWaXNpw7NuIDIwMjAuIExhIGZpbmFsaWRhZCBlcyBvcmdhbml6YXIgeSBwcm9jZXNhciBsYSBpbmZvcm1hY2nDs24gZGUgbWFuZXJhIGVmaWNpZW50ZSwgZm9ydGFsZWNpZW5kbyBsYXMgY29tcGV0ZW5jaWFzIGVuIGdlc3Rpw7NuIHkgYW7DoWxpc2lzIGRlIGRhdG9zLiBFc3RlIHRyYWJham8gc2UgZGVzYXJyb2xsYSBlbiBlbCBtYXJjbyBkZWwgY3Vyc28gKkdlc3Rpw7NuIGRlIERhdG9zKiwgb3JpZW50YWRvIGFsIHByb2dyYW1hIGRlICBJbmdlbmllcmlhIEluZHVzdHJpYWwsIGVuIGVsIHNlZ3VuZG8gcGVyaW9kbyBkZSAyMDI1IGVuIGxhIFVuaXZlcnNpZGFkIGRlbCBWYWxsZSwgU2VjY2lvbmFsIFphcnphbC4NCjxhIG5hbWU9InNlYzEuMiI+PC9hPg0KDQojIyMgMS4yLiBEZXNjcmlwY2nDs24gZGUgbG9zIGRhdG9zIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVsIGNvbmp1bnRvIGRlIGRhdG9zIHV0aWxpemFkbyBlbiBlc3RlIGVzdHVkaW8gZnVlIHByb3BvcmNpb25hZG8gcG9yIGxhIGVtcHJlc2EgZGVsIHNlY3RvciBvZnRhbG1vbMOzZ2ljbyBWaXNpb24gMjAyMCwgYSBwYXJ0aXIgZGUgbG9zIHJlZ2lzdHJvcyBkZSBwYWNpZW50ZXMgYXRlbmRpZG9zIGR1cmFudGUgZWwgYcOxbyAyMDI0LiBMYSBpbmZvcm1hY2nDs24gb3JpZ2luYWwgZnVlIGVudHJlZ2FkYSBlbiB1biBhcmNoaXZvIHBsYW5vLCBjb24gMTI0OSByZWdpc3Ryb3MgKHVubyBwb3IgcGFjaWVudGUpIHkgMjIgdmFyaWFibGVzIHkgcG9zdGVyaW9ybWVudGUgc29tZXRpZGEgYSB1biBwcm9jZXNvIGRlIGV4dHJhY2Npw7NuLCB0cmFuc2Zvcm1hY2nDs24geSBjYXJnYSAoRVRMKSwgZW4gZWwgY3VhbCBzZSBkZXB1cmFyb24gaW5jb25zaXN0ZW5jaWFzLCBzZSBub3JtYWxpemFyb24gZm9ybWF0b3MgeSBzZSBnZW5lcmFyb24gdmFyaWFibGVzIGRlcml2YWRhcyBwYXJhIGZhY2lsaXRhciBlbCBhbsOhbGlzaXMgZXN0YWTDrXN0aWNvLiBFbCBvYmpldGl2byBkZSBlc3RlIGNvbmp1bnRvIGVzIGNhcmFjdGVyaXphciBlbCBwZXJmaWwgdmlzdWFsIHkgZGUgaMOhYml0b3MgZGUgdXNvIGRlIHBhbnRhbGxhcyBkZSBsb3MgcGFjaWVudGVzLCBhc8OtIGNvbW8gc3UgcG9zaWJsZSByZWxhY2nDs24gY29uIGZhY3RvcmVzIGRlbW9ncsOhZmljb3MgeSBhbnRlY2VkZW50ZXMgZmFtaWxpYXJlcy4NCg0KVHJhcyBlbCBwcm9jZXNvIEVUTCBzZSBjb25zb2xpZMOzIHVuYSBiYXNlIGNvbiAxMTY2IHJlZ2lzdHJvcyB5IDEzIHZhcmlhYmxlcywgcXVlIGNvbWJpbmFuIGFzcGVjdG9zIGRlIGlkZW50aWZpY2FjacOzbiwgc29jaW9kZW1vZ3LDoWZpY29zLCBjbMOtbmljb+KAkXZpc3VhbGVzIHkgZGUgZXN0aWxvIGRlIHZpZGEuIExhcyB2YXJpYWJsZXMgc2UgZGVzY3JpYmVuIGEgY29udGludWFjacOzbiBlbiBlbCBvcmRlbiBlbiBxdWUgYXBhcmVjZW4gZW4gbGEgYmFzZSBkZSBkYXRvcywgaW5kaWNhbmRvIHN1IHRpcG8geSBlc2NhbGEgZGUgbWVkaWNpw7NuIG1lZGlhbnRlIGxhIG5vdGFjacOzbiAodGlwb19kZV92YXJpYWJsZTo6ZXNjYWxhX2RlX21lZGljacOzbltvcmRlbmFtaWVudG9dKS4NCg0KKipQYWNfaWQqKiAoY3VhbnRpdGF0aXZhOjpub21pbmFsKTogSWRlbnRpZmljYWRvciBudW3DqXJpY28gc2VjdWVuY2lhbCBxdWUgYXNpZ25hIHVuIGPDs2RpZ28gw7puaWNvIGEgY2FkYSBwYWNpZW50ZS4gUGVybWl0ZSByZWZlcmVuY2lhciBsb3MgcmVnaXN0cm9zIHNpbiByZXZlbGFyIGRhdG9zIHBlcnNvbmFsZXMgeSBubyB0aWVuZSBpbnRlcnByZXRhY2nDs24gbcOpdHJpY2EgcG9yIHPDrSBtaXNtby4NCg0KKipFZGFkX3BhY2llbnRlKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogRWRhZCBkZWwgcGFjaWVudGUgZXhwcmVzYWRhIGVuIGHDsW9zIGN1bXBsaWRvcyBhbCBtb21lbnRvIGRlbCByZWdpc3Ryby4gRXMgdW5hIHZhcmlhYmxlIGRlIHJhesOzbiwgY29uIGNlcm8gYWJzb2x1dG8geSBwb3NpYmlsaWRhZCBkZSByZWFsaXphciBjb21wYXJhY2lvbmVzIGRlIHByb3BvcmNpb25lcyBkZSBlZGFkLg0KDQoqKk9jdXBhY2lvbioqIChjdWFsaXRhdGl2YTo6bm9taW5hbCk6IFByb2Zlc2nDs24gdSBvZmljaW8gcHJpbmNpcGFsIGRlbCBwYWNpZW50ZSAocG9yIGVqZW1wbG8sIGVzdHVkaWFudGUsIGFkbWluaXN0cmF0aXZvLCBvcGVyYXJpbywgaW5kZXBlbmRpZW50ZSwgZW50cmUgb3Ryb3MpLiBTZSB1dGlsaXphIHBhcmEgY2FyYWN0ZXJpemFyIGVsIHRpcG8gZGUgYWN0aXZpZGFkIGRpYXJpYSwgZXNwZWNpYWxtZW50ZSBlbiB0w6lybWlub3MgZGUgZXhwb3NpY2nDs24gcG90ZW5jaWFsIGEgcGFudGFsbGFzLg0KDQoqKkNhbmFsX2RpZnVzaW9uKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogTWVkaW8gcG9yIGVsIGN1YWwgZWwgcGFjaWVudGUgY29ub2Npw7MgbGEgw7NwdGljYSAocmVmZXJpZG8sIHJlZGVzIHNvY2lhbGVzLCB2b2xhbnRlLCBwYXNvIHBvciBlbCBsb2NhbCwgY29udmVuaW8sIGV0Yy4pLiBFc3RhIHZhcmlhYmxlIHBlcm1pdGUgaWRlbnRpZmljYXIgbG9zIGNhbmFsZXMgZGUgY2FwdGFjacOzbiBtw6FzIGZyZWN1ZW50ZXMgZGVudHJvIGRlIGxhIHBvYmxhY2nDs24gYXRlbmRpZGEuDQoNCioqRmVjaGFfcmVnaXN0cm8qKiAoY3VhbGl0YXRpdmE6Om9yZGluYWxbdGllbXBvXSk6IEZlY2hhIGVuIGxhIHF1ZSBlbCBwYWNpZW50ZSBmdWUgcmVnaXN0cmFkbyBlbiBlbCBzaXN0ZW1hLCBleHByZXNhZGEgY29tbyBkw61hL21lcy9hw7FvLiBBdW5xdWUgc2UgYWxtYWNlbmEgY29tbyB0ZXh0byBvIGZlY2hhIGNhbGVuZGFyaW8sIHN1IGVzY2FsYSBlcyBvcmRpbmFsIGVuIGVsIHRpZW1wbyB5IHNlIHVzYSBwYXJhIHViaWNhciBsYSBhdGVuY2nDs24gZGVudHJvIGRlbCBwZXJpb2RvIGRlIGVzdHVkaW8uDQoNCioqUGFjX3NleG8qKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBTZXhvIGRlbCBwYWNpZW50ZSwgcmVnaXN0cmFkbyB0w61waWNhbWVudGUgY29tbyDigJxGZW1lbmlub+KAnSBvIOKAnE1hc2N1bGlub+KAnS4gRXN0YSB2YXJpYWJsZSBzZSBlbXBsZWEgcGFyYSBjb21wYXJhciBwYXRyb25lcyBkZSBhZ3VkZXphIHZpc3VhbCB5IGjDoWJpdG9zIGRlIHBhbnRhbGxhIGVudHJlIGdydXBvcy4NCg0KKipSYW5nb19ldGFyZW8qKiAoY3VhbGl0YXRpdmE6Om9yZGluYWwpOiBDbGFzaWZpY2FjacOzbiBkZWwgcGFjaWVudGUgZW4gZ3J1cG9zIGRlIGVkYWQgKHBvciBlamVtcGxvLCBBRE9MRVNDRU5URSwgSk9WRU5fQURVTFRPLCBBRFVMVE8sIEFEVUxUT19NQVlPUiksIGNvbnN0cnVpZGEgYSBwYXJ0aXIgZGUgbGEgdmFyaWFibGUgZWRhZF9wYWNpZW50ZS4gUHJlc2VudGEgdW4gb3JkZW4gbmF0dXJhbCBkZSBsb3MgZ3J1cG9zLCBsbyBxdWUgcGVybWl0ZSBhbsOhbGlzaXMgcG9yIGNhdGVnb3LDrWFzIGV0YXJpYXMuDQoNCioqQWd1ZGV6YV92aXN1YWxfT0QqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiBNZWRpZGEgZGUgbGEgYWd1ZGV6YSB2aXN1YWwgZGVsIG9qbyBkZXJlY2hvLCBleHByZXNhZGEgZW4gbGEgZXNjYWxhIGVzdGFibGVjaWRhIHBvciBsYSDDs3B0aWNhIChwb3IgZWplbXBsbywgY29udmVyc2nDs24gYSB1bmEgbcOpdHJpY2EgY29udGludWEgY29tcGF0aWJsZSBjb24gbGEgcHLDoWN0aWNhIGNsw61uaWNhKS4gVmFsb3JlcyBtw6FzIGNlcmNhbm9zIGEgbGEgcmVmZXJlbmNpYSBkZSB2aXNpw7NuIG5vcm1hbCBpbmRpY2FuIG1lam9yIGFndWRlemEsIG1pZW50cmFzIHF1ZSB2YWxvcmVzIHF1ZSBzZSBhbGVqYW4gZGUgZGljaG8gZXN0w6FuZGFyIHJlcHJlc2VudGFuIG1heW9yIGNvbXByb21pc28gdmlzdWFsLg0KDQoqKkFndWRlemFfdmlzdWFsX09JKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogQW7DoWxvZ2EgYSBsYSBhbnRlcmlvciwgcGVybyBwYXJhIGVsIG9qbyBpenF1aWVyZG8uIEp1bnRvIGNvbiBsYSBhZ3VkZXphIGRlbCBvam8gZGVyZWNobywgcGVybWl0ZSBldmFsdWFyIGxhIHNpbWV0csOtYSBvIGRpZmVyZW5jaWFzIGVudHJlIGFtYm9zIG9qb3MgeSBjb25zdGl0dXllIHVuYSBkZSBsYXMgdmFyaWFibGVzIGNsw61uaWNhcyBjZW50cmFsZXMgZGVsIGVzdHVkaW8uDQoNCioqSG9yYXNfcGFudGFsbGFfZGlhKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogTsO6bWVybyBkZSBob3JhcyBwcm9tZWRpbyBxdWUgZWwgcGFjaWVudGUgcGFzYSBkaWFyaWFtZW50ZSBmcmVudGUgYSBkaXNwb3NpdGl2b3MgY29uIHBhbnRhbGxhIChjb21wdXRhZG9yLCB0ZWzDqWZvbm8gaW50ZWxpZ2VudGUsIHRhYmxldGEsIHRlbGV2aXNpw7NuLCBjb25zb2xhLCBldGMuKS4gRXMgdW5hIG1lZGlkYSBjb250aW51YSBkZSBleHBvc2ljacOzbiB5IHNlIGNvbnNpZGVyYSB1biBwb3RlbmNpYWwgZmFjdG9yIGRlIHJpZXNnbyBhc29jaWFkbyBhIGZhdGlnYSB2aXN1YWwgeSBvdHJhcyBtb2xlc3RpYXMgb2N1bGFyZXMuDQoNCioqSG9yYXNfYWN0aXZpZGFkZioqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IEhvcmFzIHByb21lZGlvIGRlIGFjdGl2aWRhZCBmw61zaWNhIHF1ZSBlbCBwYWNpZW50ZSByZWFsaXphIGFsIGTDrWEgKG8gZW4gcHJvbWVkaW8gZGlhcmlvIGEgcGFydGlyIGRlIGxhIHNlbWFuYSksIGluY2x1eWVuZG8gZWplcmNpY2lvIGVzdHJ1Y3R1cmFkbyB5IGFjdGl2aWRhZGVzIHJlY3JlYXRpdmFzLiBFc3RhIHZhcmlhYmxlIHBlcm1pdGUgZXhwbG9yYXIgc2kgdW4gZXN0aWxvIGRlIHZpZGEgbcOhcyBhY3Rpdm8gc2UgcmVsYWNpb25hIGNvbiBtZWpvcmVzIGluZGljYWRvcmVzIHZpc3VhbGVzIG8gY29uIG1lbm9yIGV4cG9zaWNpw7NuIGEgcGFudGFsbGFzLg0KDQoqKkhvYmJ5X3ByaW5jaXBhbF9wYW50YWxsYSoqIChjdWFsaXRhdGl2YTo6bm9taW5hbCk6IEluZGljYSBzaSBlbCBwYXNhdGllbXBvIHByaW5jaXBhbCBkZWwgcGFjaWVudGUgaW1wbGljYSB1c28gaW50ZW5zaXZvIGRlIHBhbnRhbGxhcyAocG9yIGVqZW1wbG8sIHZpZGVvanVlZ29zLCByZWRlcyBzb2NpYWxlcywgc2VyaWVzIGVuIHN0cmVhbWluZykgbyBuby4gU2UgY29kaWZpY2EgdMOtcGljYW1lbnRlIGNvbW8g4oCcc8Ot4oCdIG8g4oCcbm/igJ0geSBzZSB1c2EgcGFyYSBkaWZlcmVuY2lhciBob2JiaWVzIGRpZ2l0YWxlcyBkZSBhY3RpdmlkYWRlcyBhbmFsw7NnaWNhcyBvIGFsIGFpcmUgbGlicmUuDQoNCioqUHJlZGlzcG9zaWNpb25fZ2VuZXRpY2EqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBTZcOxYWxhIHNpIGVsIHBhY2llbnRlIHJlcG9ydGEgYW50ZWNlZGVudGVzIGZhbWlsaWFyZXMgZGUgcHJvYmxlbWFzIG9mdGFsbW9sw7NnaWNvcyByZWxldmFudGVzIChtaW9ww61hIGFsdGEsIGdsYXVjb21hLCBkZWdlbmVyYWNpw7NuIG1hY3VsYXIsIGVudHJlIG90cm9zKS4gU2UgcmVnaXN0cmEgY29tbyDigJxzw63igJ0gbyDigJxub+KAnSB5IGZ1bmNpb25hIGNvbW8gYXByb3hpbWFjacOzbiBhIHVuIGZhY3RvciBkZSByaWVzZ28gZ2Vuw6l0aWNvLg0KDQpEdXJhbnRlIGVsIHByb2Nlc28gZGUgZGVwdXJhY2nDs24gc2UgdmVyaWZpY8OzIGxhIGNvaGVyZW5jaWEgZGUgcmFuZ29zIChwb3IgZWplbXBsbywgZWRhZGVzIG5vIG5lZ2F0aXZhcywgaG9yYXMgZGUgcGFudGFsbGEgeSBhY3RpdmlkYWQgZsOtc2ljYSBkZW50cm8gZGUgaW50ZXJ2YWxvcyBwbGF1c2libGVzLCB2YWxvcmVzIGRlIGFndWRlemEgdmlzdWFsIGRlbnRybyBkZSBsb3MgbMOtbWl0ZXMgYWNlcHRhZG9zIHBvciBsYSBlc2NhbGEgdXRpbGl6YWRhKS4gTG9zIHZhbG9yZXMgZmFsdGFudGVzIG8gY2xhcmFtZW50ZSBhdMOtcGljb3MgZnVlcm9uIHJldmlzYWRvcyBjYXNvIGEgY2FzbzsgZW4gbG9zIGNhc29zIGVuIHF1ZSBubyBmdWUgcG9zaWJsZSByZWN1cGVyYXIgaW5mb3JtYWNpw7NuIGNvbmZpYWJsZSwgc2UgcmVjdXJyacOzIGEgZXN0cmF0ZWdpYXMgZGUgaW1wdXRhY2nDs24gbyBleGNsdXNpw7NuIGNvbnRyb2xhZGEsIGRvY3VtZW50YWRhcyBlbiBlbCBmbHVqbyBFVEwuIEEgcGFydGlyIGRlIGVzdGUgY29uanVudG8gZGVwdXJhZG8sIHNlIGRlc2Fycm9sbGFuIGxhcyBmYXNlcyBwb3N0ZXJpb3JlcyBkZWwgYW7DoWxpc2lzIG11bHRpdmFyaWFkbywgY2VudHJhZGFzIGVuIGxhIHJlbGFjacOzbiBlbnRyZSBhZ3VkZXphIHZpc3VhbCwgaMOhYml0b3MgZGUgcGFudGFsbGEsIGFjdGl2aWRhZCBmw61zaWNhIHkgZmFjdG9yZXMgZGVtb2dyw6FmaWNvcyB5IGdlbsOpdGljb3MuDQoNCiMjIyMgRXN0cnVjdHVyYSBkZWwgQ29uanVudG8gZGUgRGF0b3MgT3JpZ2luYWwgey50YWJzZXQgLnRhYnNldC1waWxsc30NCmBgYHtyIEVzdHJ1Y3R1cmFfZGVsX0Nvbmp1bnRvX2RlX0RhdG9zX09yaWdpbmFsLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN0cihjb25qdW50b19kZV9kYXRvc192aXNpb24yMDIwX25FVEwpDQpgYGANCg0KIyMjIyBFc3RydWN0dXJhIGRlbCBDb25qdW50byBkZSBEYXRvcyBFVEwgey50YWJzZXQgLnRhYnNldC1waWxsc30NCmBgYHtyIEVzdHJ1Y3R1cmFfZGVsX0Nvbmp1bnRvX2RlX0RhdG9zX0VUTCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzdHIoY2NkX3Zpc2lvbjIwMjBfRVRMKQ0KYGBgDQoNCg0KIyMjIDEuMy4gRXN0aW1hY2lvbmVzIG11bHRpdmFyaWFkYXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRWwgKip2ZWN0b3IgZGUgbWVkaWFzKiogeSAqKmxhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMqKiBjb25mb3JtYW4gdW4gY29uanVudG8gZGUgaGVycmFtaWVudGFzIGZ1bmRhbWVudGFsZXMgcGFyYSBkZXNjcmliaXIgZWwgY29tcG9ydGFtaWVudG8gcG9zaWNpb25hbCwgZGlzcGVyc2l2byB5IGNvcnJlbGFjaW9uYWwgZGUgbGFzIHZhcmlhYmxlcyBhbGVhdG9yaWFzIGVuIHVuIGNvbmp1bnRvIGRlIGRhdG9zLiBFc3RhcyBtZWRpZGFzIHNvbiBlc2VuY2lhbGVzIGVuIGVsIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG8sIHlhIHF1ZSBwZXJtaXRlbiBjYXB0dXJhciB0YW50byBsYSB0ZW5kZW5jaWEgY2VudHJhbCBjb21vIGxhcyBpbnRlcmRlcGVuZGVuY2lhcyBlbnRyZSBsYXMgdmFyaWFibGVzLg0KDQpFbCB2ZWN0b3IgZGUgbWVkaWFzIHJlZmxlamEgZWwgdmFsb3IgZXNwZXJhZG8gbyBwdW50byBtZWRpbyBkZSBjYWRhIHZhcmlhYmxlLCBzaW50ZXRpemFuZG8gbGEgaW5mb3JtYWNpw7NuIGRlIHRvZG9zIGxvcyByZWdpc3Ryb3MgZGlzcG9uaWJsZXMgZW4gZWwgY29uanVudG8gZGUgZGF0b3MuIFBvciBzdSBwYXJ0ZSwgbGEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyBkZXNjcmliZSBsYSB2YXJpYWJpbGlkYWQgeSBsYXMgcmVsYWNpb25lcyBlbnRyZSBsYXMgdmFyaWFibGVzLiBFbiBzdSBkaWFnb25hbCBwcmluY2lwYWwsIGVzdGltYSBsYXMgZGlzcGVyc2lvbmVzIGluZGl2aWR1YWxlcyBkZSBjYWRhIHZhcmlhYmxlIHJlc3BlY3RvIGEgc3UgbWVkaWEsIG1pZW50cmFzIHF1ZSBsb3MgZWxlbWVudG9zIHBvciBlbmNpbWEgbyBwb3IgZGViYWpvIGRlIGVzdGEgZGlhZ29uYWwgcmVwcmVzZW50YW4gbGFzIGNvdmFyaWFuemFzIGVudHJlIHBhcmVzIGRlIHZhcmlhYmxlcywgbW9zdHJhbmRvIGxhcyByZWxhY2lvbmVzIGxpbmVhbGVzIGV4aXN0ZW50ZXMgZW50cmUgZWxsYXMuDQoNCkVuIGVzdGEgc2VjY2nDs24gc2UgcHJlc2VudGEgZWwgY8OhbGN1bG8gZSBpbnRlcnByZXRhY2nDs24gZGUgdHJlcyBvYmpldG9zIGZ1bmRhbWVudGFsZXM6ICoqVmVjdG9yIGRlIE1lZGlhcyoqICRcYmFyIHgkICwgKipNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzKiogJFMkIHkgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqICRSJC4sIGNvbnN0cnVpZG9zIGEgcGFydGlyIGRlIGxhcyB2YXJpYWJsZXMgZWRhZF9wYWNpZW50ZSwgQWd1ZGV6YV92aXN1YWxfT0QsIEFndWRlemFfdmlzdWFsX09JLCBIb3Jhc19wYW50YWxsYV9kaWEgeSBIb3Jhc19hZi4gTGEgcGVzdGHDsWEgY29ycmVzcG9uZGllbnRlIGFsIHZlY3RvciBkZSBtZWRpYXMgeSBhIGxvcyBib3hwbG90cyB1bml2YXJpYW50ZXMgcGVybWl0ZSBkZXNjcmliaXIgZWwgY29tcG9ydGFtaWVudG8gcG9zaWNpb25hbCB5IGRpc3BlcnNpdm8gZGUgY2FkYSB2YXJpYWJsZToNCg0KIyMjIyBWZWN0b3IgZGUgUHJvbWVkaW9zIHkgQm94cGxvdHMNCmBgYHtyIFZlY3Rvcl9kZV9Qcm9tZWRpb3NfeV9Cb3hwbG90cywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQphcHBseShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIDIsIG1lYW4pDQpjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8gPSBjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0NCm5vbWJyZXNfYm94cGxvdHMgPC0gYygiRWRhZFxuKEHDsW9zKSIsIkFndWRlemEgVmlzdWFsXG4oTy4gRGVyZWNobykiLCJBZ3VkZXphIFZpc3VhbFxuKE8uIEl6cXVpZXJkbykiLCJBY3RpdmlkYWRlcyBlblxuUGFudGFsbGEgKEhvcmFzKSIsIkFjdGl2aWRhZFxuRsOtc2ljYSAoSG9yYXMpIikNCnBhcihtZnJvdyA9IGMoMSwgbmNvbChjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG8pKSkNCmludmlzaWJsZShsYXBwbHkoMTpuY29sKGNjZF92aXNpb24yMDIwX0VUTF9SZWR1Y2lkbyksIGZ1bmN0aW9uKGkpIHsNCiAgYm94cGxvdChjY2RfdmlzaW9uMjAyMF9FVExfUmVkdWNpZG9bLCBpXSwNCiAgICAgICAgICBtYWluID0gbm9tYnJlc19ib3hwbG90c1tpXSl9KSkNCmBgYA0KDQpDb24gYmFzZSBlbiBsb3MgRGlhZ3JhbWFzIGRlIENhamEgKEJveHBsb3RzKSwgc2UgcHVlZGUgZGVzY3JpYmlyIHF1ZSwgZW4gZ2VuZXJhbCwgbG9zIGRhdG9zIHJlZ2lzdHJhZG9zIHBhcmEgY2FkYSB1bmEgZGUgbGFzIHZhcmlhYmxlcyB0aWVuZGVuIGEgcHJlc2VudGFyIGRpc3RyaWJ1Y2lvbmVzIGNvbiBsYXMgc2lndWllbnRlcyBmb3JtYXMgeSBjYXJhY3RlcsOtc3RpY2FzOg0KDQpMYSB2YXJpYWJsZSAqKkVkYWQgKEHDsW9zKSoqIHRpZW5lIHVuYSBkaXN0cmlidWNpw7NuIGNhc2kgbm9ybWFsLCBjb24gdW4gc2VzZ28gY2VyY2FubyBhIGNlcm8sIHlhIHF1ZSBsYSBtZWRpYW5hIChcKFxhcHByb3ggMzdcKSBhw7FvcykgZXN0w6EgY2VudHJhZGEgZW4gbGEgY2FqYS4gUG9yIG90cmEgcGFydGUsIGxhcyB2YXJpYWJsZXMgKipBY3RpdmlkYWRlcyBlbiBQYW50YWxsYSAoSG9yYXNfcGQpKiogeSAqKkFjdGl2aWRhZCBGw61zaWNhIChIb3Jhc19hZikqKiB0YW1iacOpbiBtdWVzdHJhbiBkaXN0cmlidWNpb25lcyBjYXNpIHNpbcOpdHJpY2FzIChzZXNnbyBjZXJjYW5vIGEgY2VybyksIGNvbiBzdXMgbWVkaWFuYXMgKFwoXGFwcHJveCA1LjJcKSB5IFwoXGFwcHJveCA0LjZcKSBob3JhcywgcmVzcGVjdGl2YW1lbnRlKSBiaWVuIGNlbnRyYWRhcy4NCg0KRW4gY29udHJhc3RlLCBsYSB2YXJpYWJsZSAqKkFndWRlemEgVmlzdWFsIChPLiBEZXJlY2hvKSoqIHRpZW5lIHVuIGxpZ2Vyw61zaW1vIHNlc2dvIGEgbGEgaXpxdWllcmRhIChjb2xhIGluZmVyaW9yKSwgbWllbnRyYXMgcXVlIGxhICoqQWd1ZGV6YSBWaXN1YWwgKE8uIEl6cXVpZXJkbykqKiB0aWVuZSB1biBsaWdlcsOtc2ltbyBzZXNnbyBhIGxhIGRlcmVjaGEgKGNvbGEgc3VwZXJpb3IpLiBFc3RvIGluZGljYSBxdWUgZW4gZWwgT2pvIERlcmVjaG8gaGF5IHVuYSBsZXZlIHRlbmRlbmNpYSBkZSB2YWxvcmVzIG11eSBiYWpvcyBxdWUgZXh0aWVuZGVuIGxhIGNvbGEsIHkgZW4gZWwgT2pvIEl6cXVpZXJkbywgdW5hIGxldmUgdGVuZGVuY2lhIGRlIHZhbG9yZXMgYWx0b3MgcXVlIGV4dGllbmRlbiBsYSBjb2xhLg0KDQoNCiMjIyMgTWF0cml6IGRlIFZhcmlhbnphcy1Db3Zhcmlhbnphcw0KYGBge3IgTWF0cml6X2RlX1Zhcmlhbnphcy1Db3ZhcmlhbnphcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyb3VuZChjb3YoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldKSwyKQ0KYGBgDQpMYSBNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzLCBjb24gbGEgdmFyaWFuemEgZGUgY2FkYSB2YXJpYWJsZSBlbiBzdSBkaWFnb25hbCBwcmluY2lwYWwsIGNvbmZpcm1hIHF1ZSBsYSAqKkVkYWQqKiBwcmVzZW50YSBsYSBtYXlvciB2YXJpYWJpbGlkYWQgYWJzb2x1dGEgKCoqVmFyaWFuemE6IDUwMi4yMSoqKSwgbWllbnRyYXMgcXVlIGxhcyB2YXJpYWJsZXMgZGUgKipBZ3VkZXphIFZpc3VhbCAoQVZfT0QgeSBBVl9PSSkqKiBzb24gbGFzIG3DoXMgZXN0YWJsZXMgeSBjb25jZW50cmFkYXMgKCoqVmFyaWFuemE6IDAuMDcqKiBwYXJhIGFtYmFzKS4gTGFzIGNvdmFyaWFuemFzIGZ1ZXJhIGRlIGxhIGRpYWdvbmFsIHNvbiBiYWphcyBlbiBtYWduaXR1ZCAoY2VyY2FuYXMgYSBjZXJvKSwgbG8gcXVlIHlhIHN1Z2llcmUgdW5hIHJlbGFjacOzbiBsaW5lYWwgZMOpYmlsIG8gbnVsYSBlbnRyZSBsYSBtYXlvcsOtYSBkZSBsb3MgcGFyZXMgZGUgdmFyaWFibGVzLCBzaWVuZG8gZWwgdmFsb3IgbcOhcyBhbHRvIGVuIG1hZ25pdHVkIGxhIGNvdmFyaWFuemEgZW50cmUgKipFZGFkIHkgSG9yYXNfcGQgKDEuMDUpKiouDQoNCiMjIyMgTWF0cml6IGRlIENvcnJlbGFjaW9uZXMNCmBgYHtyIG1hdHJpel9kZV9Db3JyZWxhY2lvbmVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnJvdW5kKGNvcihjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0pLDMpDQpgYGANCkxhIE1hdHJpeiBkZSBDb3JyZWxhY2lvbmVzLCBxdWUgZXN0YW5kYXJpemEgbGFzIGNvdmFyaWFuemFzLCBlcyBlbCBpbmRpY2Fkb3IgY2xhdmUgZGUgbGEgcmVsYWNpw7NuIGxpbmVhbC4gU2Ugb2JzZXJ2YSBxdWUgdG9kYXMgbGFzIGNvcnJlbGFjaW9uZXMgc29uICoqZXh0cmVtYWRhbWVudGUgZMOpYmlsZXMqKiwgY29uIGNvZWZpY2llbnRlcyBjb25zaXN0ZW50ZW1lbnRlIGNlcmNhbm9zIGEgY2VybyAoc2llbmRvIGVsIHZhbG9yIG3DoXhpbW8gZW4gbWFnbml0dWQgJHIgPSAtMC4wOTkkLCBlbnRyZSAqKkhvcmFzX3BkIHkgQVZfT0kqKikuIEVzdGUgcGF0csOzbiBkZSB2YWxvcmVzIGJham9zIGVuIHRvZGEgbGEgbWF0cml6IGNvbmZpcm1hIHF1ZSAqKm5pbmd1bmEgdmFyaWFibGUgdGllbmUgdW5hIHJlbGFjacOzbiBsaW5lYWwgc2lnbmlmaWNhdGl2YSoqIGNvbiBvdHJhIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zLiBFbiBjb25zZWN1ZW5jaWEsIHNlIGNvbmNsdXllIHF1ZSBsYXMgdmFyaWFibGVzIHNvbiAqKmluZGVwZW5kaWVudGVzIGVudHJlIHPDrSBlbiB0w6lybWlub3MgbGluZWFsZXMqKiwgeSBlbCBjb25vY2ltaWVudG8gZGVsIHZhbG9yIGRlIHVuYSBubyBheXVkYSBhIHByZWRlY2lyIGVsIHZhbG9yIGRlIGxhIG90cmEuDQoNCiMjIyAxLjQuIEdyw6FmaWNhcyBtdWx0aXZhcmlhZGFzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVuIGdlbmVyYWwsIGxvcyAqKmdyw6FmaWNvcyBtdWx0aXZhcmlhZG9zKiogY3VtcGxlbiBkb3Mgb2JqZXRpdm9zIGVzZW5jaWFsZXM6IHByaW1lcm8sIGF5dWRhbiBhIGNvbXBhcmFyIGVsIGNvbXBvcnRhbWllbnRvIGRlIHBvYmxhY2lvbmVzIGRlIGVzdHVkaW8gY29uIGJhc2UgZW4gdmFyaWFibGVzIGNhdGVnw7NyaWNhcyB5IGZhY2lsaXRhbiBsYSBjb21wcmVuc2nDs24gZGUgbGEgZXN0cnVjdHVyYSBkZSBjb3JyZWxhY2nDs24gZW50cmUgdmFyaWFzIHZhcmlhYmxlcy4gQWRlbcOhcywgcGVybWl0ZW4gaWRlbnRpZmljYXIgcGF0cm9uZXMsIHRlbmRlbmNpYXMsIHkgcG9zaWJsZXMgb3V0bGllcnMgZW4gbG9zIGRhdG9zLCBzaW1wbGlmaWNhbmRvIGxhIGludGVycHJldGFjacOzbiBkZSByZWxhY2lvbmVzIGNvbXBsZWphcyB5IGRlc3RhY2FuZG8gbGFzIGNhcmFjdGVyw61zdGljYXMgbcOhcyBzaWduaWZpY2F0aXZhcyBkZSBsb3MgbWlzbW9zIChBbGTDoXMsIDIwMTcpLiANCg0KUGFyYSBlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMS4yXSBzZSBjYWxjdWxhcsOhbiBlIGludGVwcmV0YXLDoW4sIHBhcmEgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzICgqKkVkYWQsIEhvcmFzX3BhbnRhbGxhX2RpYXJpYXMsIEhvcmFzX2FjdGl2aWRhZF9maXNpY2EsIEFndWRlemFfVmlzdWFsX09EIHkgQWd1ZGV6YV9WaXN1YWxfT0kqKiksIGxhcyBncsOhZmljYXMgbXVsdGl2YXJpYWRhcyBkZSBkaWFncmFtYSBkZSBjb3JyZWxhY2lvbmVzLCBtYXRyaXogZGUgZGlhZ3JhbWEgZGUgZGlzcGVyc2nDs24sIGRpYWdyYW1hIGRlIGVzdHJlbGxhcyB5IGNhcmFzIGRlIENoZXJub2ZmLiBMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIGxhcyBncsOhZmljYXMgbXVsdGl2YXJpYWRhcyBkZTogKipEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMqKiAoc2luIGFncnVwYWNpw7NuIFNBIHkgY29uIGFncnVwYWNpw7NuIENBIChjb24gYmFzZSBlbiB1bmEgdmFyaWFibGUgY2F0ZWfDs3JpY2EpKSAqKkRpYWdyYW1hIGRlIEVzdHJlbGxhcyoqIHkgKipDYXJhcyBkZSBDaGVybm9mZioqLi4NCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXNbU0FdDQpgYGB7ciBEaWFncmFtYV9Db25qdW50b19EaXNwZXJjaW9uX0Rpc3RyaWJ1Y2lvbl9Db3JyZWxhY2lvbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpnZ3BhaXJzKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSkNCmBgYA0KDQpFbCBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMgc2UgdXRpbGl6w7MgcGFyYSByZWFsaXphciB1biBhbsOhbGlzaXMgZXhwbG9yYXRvcmlvIGRlIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbGFzIHZhcmlhYmxlcyB5IHN1cyByZWxhY2lvbmVzIGxpbmVhbGVzLiBMYXMgZGlzdHJpYnVjaW9uZXMgZGlhZ29uYWxlcyBjb25maXJtYW4gcXVlIGxhICoqQWd1ZGV6YSBWaXN1YWwgKEFWX09EIHkgQVZfT0kpKiogZXN0w6EgZnVlcnRlbWVudGUgY29uY2VudHJhZGEgYWxyZWRlZG9yIGRlIDEuMCAodmlzacOzbiBub3JtYWwpIHkgcXVlIGVsIHByaW5jaXBhbCBwcmVkaWN0b3IsICoqSG9yYXNfcGQqKiwgcHJlc2VudGEgdW4gcGF0csOzbiBkZSB1c28gYWdydXBhZG8uIEVsIGFwb3J0ZSBtw6FzIHNpZ25pZmljYXRpdm8gZGUgbGEgbWF0cml6IGVzIGxhIGNvbmZpcm1hY2nDs24gZGUgbGEgKiphdXNlbmNpYSBkZSBhc29jaWFjacOzbiBsaW5lYWwgcm9idXN0YSoqIGVudHJlIGxhcyAqKkhvcmFzX3BkKiogeSAqKmxhIEFndWRlemEgVmlzdWFsKio7IGxhIGNvcnJlbGFjacOzbiBjb24gZWwgb2pvIGRlcmVjaG8gZXMgcHLDoWN0aWNhbWVudGUgbnVsYSAoJHIgPSAtMC4wMjAkKSwgeSBhdW5xdWUgZXMgZMOpYmlsbWVudGUgbmVnYXRpdmEgY29uIGVsIG9qbyBpenF1aWVyZG8gKCRyID0gLTAuMDczJCksIGxhIG1hZ25pdHVkIGRlIGxhIHJlbGFjacOzbiBlcyB0cml2aWFsLiBEZSBpZ3VhbCBmb3JtYSwgbGEgY29ycmVsYWNpw7NuIGRlIGxhIEFndWRlemEgVmlzdWFsIGNvbiBsYSBlZGFkX3BhY2llbnRlIGVzIG1hcmdpbmFsLg0KDQpFc3RvcyByZXN1bHRhZG9zIHN1Z2llcmVuIHF1ZSwgZW4gdW4gY29udGV4dG8gbGluZWFsLCBsYXMgdmFyaWFibGVzIHByZWRpY3RvcmFzIGV4cGxvcmFkYXMgZW4gZXN0ZSBjb25qdW50byBkZSBkYXRvcyB0aWVuZW4gdW4gYmFqbyBwb2RlciBleHBsaWNhdGl2byBzb2JyZSBsYSB2YXJpYWJpbGlkYWQgZGUgbGEgQWd1ZGV6YSBWaXN1YWwsIGxvIHF1ZSBqdXN0aWZpY2EgbGEgbmVjZXNpZGFkIGRlIHVuIG1vZGVsbyBtdWx0aXZhcmlhbnRlIG3DoXMgY29tcGxlam8gcXVlIGluY29ycG9yZSBvdHJhcyB2YXJpYWJsZXMgY29uZnVzb3JhcyBvIGV4cGxvcmUgcmVsYWNpb25lcyBubyBsaW5lYWxlcy4NCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXNbQ0E6UkVdDQpgYGB7ciBEaWFncmFtYV9Db25qdW50b19kZV9EaXNwZXJjaW9uX0Rpc3RyaWJ1Y2lvbl9Db3JyZWxhY2lvbl9DQSwgZmlnLmFsaWduPSdjZW50ZXInfQ0KY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbyA8LSBmYWN0b3IoY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbykNCmxldmVscz0gYyAoMSwyLDMsNCw1KQ0KbGFiZWxzPSBjICggIkVkYWQiICwgIkFWX09EIiAsICJBVl9PSSIgLCAiSG9yYXNfcGQiICwgIkhvcmFzX2FmIikNCmdncGFpcnMoY2NkX3Zpc2lvbjIwMjBfRVRMLCBjb2x1bW4gPSBjKDIsOCw5LDEwLDExKSwgYWVzKGNvbG9yID0gcmFuZ29fZXRhcmVvLCBhbHBoYSA9IDAuNSksIHVwcGVyID0gbGlzdChjb250aW51b3VzID0gd3JhcCgiY29yIiwgc2l6ZSA9IDIuNSkpKQ0KYGBgDQoNCkVsIEFuw6FsaXNpcyBDb25qdW50byBkZSBEaXNwZXJzacOzbiB5IENvcnJlbGFjaW9uZXMsIGVzdHJhdGlmaWNhZG8gcG9yIHJhbmdvIGV0YXJpbywgb2ZyZWNlIHVuYSBwZXJzcGVjdGl2YSBtdWx0aXZhcmlhbnRlIGNydWNpYWwgc29icmUgbGFzIHJlbGFjaW9uZXMgZW50cmUgbGFzIHZhcmlhYmxlcy4gU2kgYmllbiBlbCBtb2RlbG8gbG9nw61zdGljbyBzaW1wbGUgaW5pY2lhbCBubyBtb3N0csOzIHVuIGVmZWN0byBzaWduaWZpY2F0aXZvIGRlIGxhcyBob3JhcyBkZSBwYW50YWxsYSwgZXN0YSBtYXRyaXogcmV2ZWxhIHF1ZSBsYSBjb3JyZWxhY2nDs24gZXMgYWx0YW1lbnRlIGRlcGVuZGllbnRlIGRlbCBncnVwbyBkZSBlZGFkLiBFc3BlY8OtZmljYW1lbnRlLCBlbiBlbCBncnVwbyBkZSBBRFVMVE8gTUFZT1IsIGxhIHJlbGFjacOzbiBlbnRyZSBsYXMgSG9yYXNfcGQgeSBsYSBBZ3VkZXphIFZpc3VhbCBlcyBuZWdhdGl2YSB5IG5vdGFibGVtZW50ZSBtw6FzIGZ1ZXJ0ZSBxdWUgZW4gbGEgcG9ibGFjacOzbiBnZW5lcmFsOiAkciA9IC0wLjEzNyQgcGFyYSAkQVZcX09EJCB5ICRyID0gLTAuMTk4JCBwYXJhICRBVlxfT0kkLiBFc3RvIHN1Z2llcmUgcXVlLCBhbCBtZW5vcyBlbiBlc3RlIHN1YmdydXBvLCB1biBtYXlvciB0aWVtcG8gZGUgcGFudGFsbGEgZXN0w6EgYXNvY2lhZG8gZGUgbWFuZXJhIG3DoXMgY2xhcmEgY29uIHVuYSBwZW9yIEFndWRlemEgVmlzdWFsLiBQb3IgZWwgY29udHJhcmlvLCBlbiBlbCBncnVwbyBkZSBOScORRVosIGxhIGNvcnJlbGFjacOzbiBlbnRyZSBIb3Jhc19wZCB5ICRBVlxfT0QkIGVzIHBvc2l0aXZhICgkciA9IDAuMDUxJCksIGF1bnF1ZSBkw6liaWwsIGxvIHF1ZSBpbmRpY2EgcXVlIGxhIGRpcmVjY2lvbmFsaWRhZCB5IGZ1ZXJ6YSBkZSBsYSBhc29jaWFjacOzbiBubyBzb24gY29uc2lzdGVudGVzIGEgdHJhdsOpcyBkZSBsYSB2aWRhLg0KDQpMYXMgZGlzdHJpYnVjaW9uZXMgZGlhZ29uYWxlcyBlc3RyYXRpZmljYWRhcyBjb25maXJtYW4gcXVlIGxhIEVkYWQgZXMgZWwgcHJpbmNpcGFsIGZhY3RvciBkZSB2YXJpYWJpbGlkYWQsIGRlc3RhY2FuZG8gcXVlIGVsIHJhbmdvIEFEVUxUTyBNQVlPUiBlcyBlbCBxdWUgY29uY2VudHJhIGxhIHBlb3IgQWd1ZGV6YSBWaXN1YWwgcHJvbWVkaW8uIEVuIGNvbmNsdXNpw7NuLCBlbCBlZmVjdG8gZGUgbGFzIGhvcmFzIGRlIHBhbnRhbGxhIG5vIGVzIGdsb2JhbCwgc2lubyBxdWUgZXN0w6EgbWVkaWFkbyBwb3IgbGEgZWRhZCwgdW4gaGFsbGF6Z28gZXNlbmNpYWwgcGFyYSBsYSBjb25zdHJ1Y2Npw7NuIGRlIHVuIG1vZGVsbyBkZSBSZWdyZXNpw7NuIExvZ8Otc3RpY2EgTXVsdGl2YXJpYW50ZSByb2J1c3RvIHF1ZSBkZWJlIGluY2x1aXIgbGEgaW50ZXJhY2Npw7NuIGVudHJlIEhvcmFzX3BkIHkgcmFuZ29fZXRhcmVvLg0KDQojIyMjIERpYWdyYW1hIGRlIEVzdHJlbGxhcw0KYGBge3IgRGlhZ3JhbWFfZGVfRXN0cmVsbGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpzZXQuc2VlZCgxMjA1MjIpDQpjY2RfdmlzaW9uMjAyMF9FVExfTVVFU1RSRUFETyA9IGNjZF92aXNpb24yMDIwX0VUTFtzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksMjMpLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0NCnN0YXJzKGNjZF92aXNpb24yMDIwX0VUTF9NVUVTVFJFQURPLCBsZW4gPSAxLCBjZXggPSAwLjQsIGtleS5sb2MgPSBjKDEwLCAyKSwgZHJhdy5zZWdtZW50cyA9IFRSVUUpDQpgYGANCg0KTGEgcmVwcmVzZW50YWNpb24gZGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBwb3IgbWVkaW8gZGVsICoqRGlhZ3JhbWEgZGUgZXN0cmVsbGFzKiogcGVybWl0aW8gaWRlbnRpZmljYXIgdHJlcyBwdW50b3MgZGUgcmVmbGV4acOzbjogDQoNCioqUGF0cm9uZXMgZGUgQ2x1c3Rlcml6YWNpw7NuKio6IFBhY2llbnRlcyBjb24gZXN0cmVsbGFzIGRlIGZvcm1hcyBzaW1pbGFyZXMgKGVzIGRlY2lyLCBncnVwb3MgZGUgcmFkaW9zIGxhcmdvcyBvIGNvcnRvcyBlbiBsYXMgbWlzbWFzIGRpcmVjY2lvbmVzKSB0aWVuZGVuIGEgY29tcGFydGlyIHVuIHBlcmZpbCBzaW1pbGFyIGVuIHRvZGFzIGxhcyB2YXJpYWJsZXMuIA0KDQoqKlJlbGFjacOzbiBJbnZlcnNhIChBViB2cy4gRWRhZCkqKjogU2Ugb2JzZXJ2YSBxdWUgbGFzIGVzdHJlbGxhcyBjb24gcmFkaW9zIGxhcmdvcyBlbiBFZGFkIChOZWdybykgKHBhY2llbnRlcyBtYXlvcmVzKSBhIG1lbnVkbyB0aWVuZW4gcmFkaW9zIGNvcnRvcyBlbiBBVl9PRCAoUm9qbykgeSBBVl9PSSAoVmVyZGUpIChwZW9yIGFndWRlemEgdmlzdWFsKSwgeSB2aWNldmVyc2EuIEVzdG8gdmlzdWFsbWVudGUgY29uZmlybWEgbGEgY29ycmVsYWNpw7NuIG5lZ2F0aXZhIGVudHJlIEVkYWQgeSBBZ3VkZXphIFZpc3VhbCBxdWUgc2UgdmlvIGVuIGxhIG1hdHJpeiBlc3RyYXRpZmljYWRhLCBzdWdpcmllbmRvIHF1ZSBsYSBlZGFkIGVzIGVsIGZhY3RvciBkb21pbmFudGUgZW4gbGEgdmFyaWFiaWxpZGFkIGRlIGxhIEFWLg0KDQoqKkhldGVyb2dlbmVpZGFkIGVuIEhvcmFzIGRlIFBhbnRhbGxhKio6IEVsIHJhZGlvIGRlIEhvcmFzX3BkIChBenVsIE9zY3VybykgdmFyw61hIG11Y2hvIGVudHJlIGluZGl2aWR1b3Mgc2luIHVuIHBhdHLDs24gY2xhcm8geSBzaW1wbGUgY29uIHJlc3BlY3RvIGEgbGEgQVYgbyBsYSBFZGFkLiBQb3IgZWplbXBsbywgYWxndW5hcyBlc3RyZWxsYXMgZ3JhbmRlcyAocGFjaWVudGVzIG1heW9yZXMgY29uIGJhamEgQVYpIHRpZW5lbiByYWRpb3MgZGUgSG9yYXNfcGQgbGFyZ29zIChtdWNoYXMgaG9yYXMpIHkgb3RyYXMgdGllbmVuIHJhZGlvcyBjb3J0b3MgKHBvY2FzIGhvcmFzKS4gRXN0byByZWZ1ZXJ6YSBsYSBpZGVhIGRlIHF1ZSBsYSBjb3JyZWxhY2nDs24gZ2xvYmFsIGRlICRyIFxhcHByb3ggMCQgZXMgYXByb3BpYWRhLCB5YSBxdWUgbGEgcmVsYWNpw7NuIGVudHJlIGhvcmFzIGRlIHBhbnRhbGxhIHkgQVYgbm8gZXMgdW5pZm9ybWUuDQoNCiMjIyMgQ2FyYXMgZGUgQ2hlcm5vZmYNCmBgYHtyIENhcmFzX2RlX0NoZXJub2ZmLCBmaWcuYWxpZ249J2NlbnRlcid9DQpzZXQuc2VlZCgxMjA1MjIpDQpjY2RfdmlzaW9uMjAyMF9FVExfTVVFU1RSRUFETyA9IGNjZF92aXNpb24yMDIwX0VUTCBbc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLDIzKSwtYygxMSwzLDQsNSw2LDcsMTIsMTMpXQ0KZmFjZXMoY2NkX3Zpc2lvbjIwMjBfRVRMX01VRVNUUkVBRE8pDQpgYGANCg0KRWwgZGlhZ3JhbWEgZGUgQ2FyYXMgZGUgQ2hlcm5vZmYsIHBlcm1pdGlvIGlkZW50aWZpY2FyOiAqKnZhcmlhYmxlcyBkZSByZXN1bHRhZG8gKEFndWRlemEgVmlzdWFsKSBjb21vIHJhc2dvcyBmaWpvcyoqLCBlcyBkZWNpciwgRWwgZGlzZcOxbyBhc2lnbmEgbGFzIHZhcmlhYmxlcyBkZSByZXN1bHRhZG8gZGUgc2FsdWQgKEFWX09EIHkgQVZfT0kpIGEgbG9zIHJhc2dvcyBtw6FzIGVzdGFibGVzIGRlIGxhIGNhcmEgKGVzdHJ1Y3R1cmEsIGJvY2EsIG5hcml6KSwgcGVybWl0aWVuZG8gcXVlIGVsIG9qbyBodW1hbm8gaWRlbnRpZmlxdWUgcsOhcGlkYW1lbnRlIGxvcyBzdWpldG9zIGNvbiBiYWphIEFWIChjYXJhcyBtw6FzIGRlZm9ybWVzL2RpZmVyZW50ZXMpLg0KDQpBZGVtYXMsIGRlIGVzdGFibGVjZXIgZWwgY2FyYWN0ZXIgcHJlZGljdG9yIChIb3Jhc19wYW50YWxsYSBkaWFyaWFzKSBjb21vIFJhc2dvIFZhcmlhYmxlOiBFbCBwcmVkaWN0b3IgcHJpbmNpcGFsIChIb3Jhc19wZCkgc2UgYXNpZ25hIGEgcmFzZ29zIG3DoXMgZmxleGlibGVzIChhbmNobyBkZSBsYSBib2NhLCBhbHR1cmEgZGUgbGEgb3JlamEpLiBFc3RvIGZhY2lsaXRhIGxhIGLDunNxdWVkYSBkZSBwYXRyb25lczogc2kgbG9zIHBhY2llbnRlcyBjb24gImNhcmFzIGRlZm9ybWVzIiAoYmFqYSBBVikgdGllbmRlbiBhIHRlbmVyIGJvY2FzIGFuY2hhcyAobXVjaGFzIEhvcmFzX3BkKSwgZWwgcHJlZGljdG9yIHNlcsOtYSB2aXN1YWxtZW50ZSByZWxldmFudGUuDQoNCiMjIyAxLjUuIE5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVzIHBvc2libGUgYW5hbGl6YXIgbyBkZXRlcm1pbmFyIGxhIGRpc3RyaWJ1Y2nDs24gbXVsdGl2YXJpYWRhIGRlIHVuIGNvbmp1bnRvIGRlIGRhdG9zIG1lZGlhbnRlIG3DqXRvZG9zIGRlc2NyaXB0aXZvcywgY29tbyBsb3MgZ3LDoWZpY29zLCBvIGluZmVyZW5jaWFsZXMsIGNvbW8gbGFzIHBydWViYXMgZXN0YWTDrXN0aWNhcy4gTWllbnRyYXMgcXVlIGxvcyBwcm9jZWRpbWllbnRvcyBpbmZlcmVuY2lhbGVzIHBlcm1pdGVuIG9idGVuZXIgY29uY2x1c2lvbmVzIG3DoXMgZ2VuZXJhbGl6YWJsZXMsIGxvcyBncsOhZmljb3MgcmVzdWx0YW4gw7p0aWxlcyBjb21vIHNvcG9ydGUgcGFyYSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MuDQoNCkVuIGVzdGUgYXBhcnRhZG8gc2UgYWJvcmRhIGxhIGFwbGljYWNpw7NuIGRlIHByb2NlZGltaWVudG9zIGluZmVyZW5jaWFsZXMgcGFyYSB2ZXJpZmljYXIgc2kgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbywgcmVzcGVjdG8gYSBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEgKEROTSkuIExhcyBwcnVlYmFzIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIChQTk0pIHF1ZSBzZSBhcGxpY2Fyw6FuIHNvbjogTWFyZGlhLCBIZW56ZS1aaXJrbGVyLCBEb29ybmlrLUhhbnNlbiB5IFJveXN0b24uIEVzdGFzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBzZSByZWFsaXphbiBiYWpvIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZGV0ZXJtaW5hZG8gJFxhbHBoYSA9IDAuMDUkIHkgYSBsYXMgaGlww7N0ZXNpczokJEhfMDogXHRleHQge0xhcyB2YXJpYWJsZXMgdGllbmVuIHVuYSBETk19JCQgJCRIXzE6IFx0ZXh0IHtMYXMgdmFyaWFibGVzIE5PIHRpZW5lbiB1bmEgRE5NfSQkIA0KDQpMYSAqKnBydWViYSBkZSBNYXJkaWEqKiBzZSBmdW5kYW1lbnRhIGVuIGxhcyBleHRlbnNpb25lcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMsIGVsIGN1YWRyYWRvIGRlIGxhIGRpc3RhbmNpYSBkZSBNYWhhbGFub2JpcywgZWwgbsO6bWVybyBkZSB2YXJpYWJsZXMgJHAkIGEgYW5hbGl6YXIgeSBlbCBuw7ptZXJvIGRlIHJlZ2lzdHJvcyAkbiQuIEFzaW1pc21vLCBzZSBjb25zaWRlcmEgcXVlIGxhIGVzdGFkw61zdGljYSBkZSBsYSBwcnVlYmEgcGFyYSBsYSBhc2ltZXRyw61hIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuICRcY2hpXjIkLCBtaWVudHJhcyBxdWUgbGEgZXN0YWTDrXN0aWNhIHBhcmEgbGEgY3VydG9zaXMgc2UgZGlzdHJpYnV5ZSBkZSBtYW5lcmEgYXByb3hpbWFkYSBkZSBmb3JtYSBub3JtYWwuIA0KDQpMYSAqKnBydWViYSBkZSBIZW56ZS1aaXJrbGVyKiogc2UgYmFzYSBlbiBsYSBkaXN0YW5jaWEgZnVuY2lvbmFsLCB5YSBxdWUgc2kgZWwgY29uanVudG8gZGUgZGF0b3Mgc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYSwgZWwgZXN0YWTDrXN0aWNvIGRlIGxhIHBydWViYSBzZSBkaXN0cmlidXllIGRlIG1hbmVyYSBhcHJveGltYWRhIGNvbW8gdW5hIGxvZ25vcm1hbCwgY29uIHBhcsOhbWV0cm9zIGRlIG1lZGlhICRcbXUkIHkgdmFyaWFuemEgJFxzaWdtYV4yJC4gDQoNCkxhICoqcHJ1ZWJhIGRlIERvb3JuaWstSGFuc2VuKiogc2UgYmFzYSBlbiBsYSBhc2ltZXRyw61hIHkgbGEgY3VydG9zaXMgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvcywgbG9zIGN1YWxlcyBzZSB0cmFuc2Zvcm1hbiBwYXJhIGFzZWd1cmFyIGxhIGluZGVwZW5kZW5jaWEuIFNlIGNvbnNpZGVyYSBtw6FzIHBvdGVudGUgcXVlIGxhIHBydWViYSBkZSBTaGFwaXJvLVdpbGsgZW4gY2Fzb3MgbXVsdGl2YXJpYWRvcy4gRWwgZXN0YWTDrXN0aWNvIGRlIGxhIHBydWViYSBzZSBkZWZpbmUgY29tbyBsYSBzdW1hIGRlIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIGFsIGN1YWRyYWRvIGRlIGxhIGFzaW1ldHLDrWEgeSBsYSBjdXJ0b3NpcywgeSBzaWd1ZSBhcHJveGltYWRhbWVudGUgdW5hIGRpc3RyaWJ1Y2nDs24gJFxjaGleMiQuIA0KDQpQb3Igb3RybyBsYWRvLCBsYSBwcnVlYmEgZGUgUm95c3RvbiB1dGlsaXphIGxhcyAqKnBydWViYXMgZGUgU2hhcGlyby1XaWxrIG8gU2hhcGlyby1GcmFuY2lhKiogcGFyYSBldmFsdWFyIGxhIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLiBTaSBsYSBjdXJ0b3NpcyBlcyBtYXlvciBxdWUgMywgc2UgZW1wbGVhIFNoYXBpcm8tRnJhbmNpYSBwYXJhIGRpc3RyaWJ1Y2lvbmVzIGxlcHRvY8O6cnRpY2FzLCBtaWVudHJhcyBxdWUgcGFyYSBkaXN0cmlidWNpb25lcyBwbGF0aWPDunJ0aWNhcyBzZSB1dGlsaXphIFNoYXBpcm8tV2lsay4gTG9zIHBhcsOhbWV0cm9zIGVuIGVzdGEgcHJ1ZWJhIHNlIG9idGllbmVuIG1lZGlhbnRlIGFwcm94aW1hY2lvbmVzIHBvbGlub21pYWxlcy4NCg0KIyMjIyBQTk0gTWFyZGlhDQpgYGB7ciBQTk1fTWFyZGlhLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCm1hcmRpYShjY2RfdmlzaW9uMjAyMF9FVExbLCAtYygxMSwzLDQsNSw2LDcsMTIsMTMpXSkNCmBgYA0KDQpBIHBhcnRpciBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMS4yLCBzZSBhcGxpY2EgdW5hIHBydWViYSBlc3RhZMOtc3RpY2EgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgY29uIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgXChcYWxwaGEgPSAwLjA1XCksIGNvbiBlbCBwcm9ww7NzaXRvIGRlIGV2YWx1YXIgc2kgZWwgdmVjdG9yIGZvcm1hZG8gcG9yIGxhcyB2YXJpYWJsZXMgbcOpdHJpY2FzIHByb3ZpZW5lIGRlIHVuYSBwb2JsYWNpw7NuIGNvbiBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIEVuIGVzdGUgZXN0dWRpbywgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIGVuIGVzY2FsYSBkZSByYXrDs24gc29uOiAqKmVkYWRfcGFjaWVudGUqKiwgKipBZ3VkZXphX3Zpc3VhbF9PRCoqLCAqKkFndWRlemFfdmlzdWFsX09JKiosICoqSG9yYXNfcGFudGFsbGFfZGlhKiogeSAqKkhvcmFzX2FmKiouIEFudGVzIGRlIHJlYWxpemFyIGxhcyBwcnVlYmFzLCBlc3RhcyB2YXJpYWJsZXMgc2UgZXN0YW5kYXJpemFuIHBhcmEgZ2FyYW50aXphciBjb21wYXJhYmlsaWRhZCB5IGVzdGFiaWxpZGFkIG51bcOpcmljYSBlbiBsb3MgY8OhbGN1bG9zLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwcmVzZW50YSBkZSBtYW5lcmEgc2VwYXJhZGEgbG9zIHJlc3VsdGFkb3MgZGUgbGFzIHByaW5jaXBhbGVzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgY29uc2lkZXJhZGFzOiBNYXJkaWEsIEhlbnpl4oCTWmlya2xlciwgRG9vcm5pa+KAk0hhbnNlbiB5IFJveXN0b24uIEVuIGxhIHBlc3Rhw7FhIGNvcnJlc3BvbmRpZW50ZSBhIGxhICoqUE5NIGRlIE1hcmRpYSoqIHNlIHJlcG9ydGFuIGxvcyBlc3RhZMOtc3RpY29zIGRlIGFzaW1ldHLDrWEgeSBjdXJ0b3NpcyBtdWx0aXZhcmlhZGFzLCBqdW50byBjb24gc3VzIHJlc3BlY3Rpdm9zIFwocFwpLXZhbG9yZXMuIERhZG8gcXVlLCBwYXJhIGFsIG1lbm9zIHVubyBkZSBlc3RvcyBjb21wb25lbnRlcywgZWwgXChwXCktdmFsb3IgcmVzdWx0YSBtZW5vciBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBlc3RhYmxlY2lkbywgc2UgcHJvY2VkZSBhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSwgY29uY2x1eWVuZG8gcXVlIGVsIGNvbmp1bnRvIGRlIHZhcmlhYmxlcyBtw6l0cmljYXMgbm8gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4NCg0KRGUgZm9ybWEgY29uc2lzdGVudGUsIGxhIHBlc3Rhw7FhIGFzb2NpYWRhIGEgbGEgKipQTk0gZGUgSGVuemXigJNaaXJrbGVyKiogbXVlc3RyYSB1biBcKHBcKS12YWxvciBpbmZlcmlvciBhIFwoXGFscGhhID0gMC4wNVwpLCBsbyBxdWUgbGxldmEgaWd1YWxtZW50ZSBhIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSB5IGFjZXB0YXIgbGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YSBkZSBxdWUgbG9zIGRhdG9zIG5vIHByb3ZpZW5lbiBkZSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBSZXN1bHRhZG9zIGFuw6Fsb2dvcyBzZSBvYnNlcnZhbiBlbiBsYSAqKlBOTSBkZSBEb29ybmlr4oCTSGFuc2VuKiosIGRvbmRlIGVsIFwocFwpLXZhbG9yIG9idGVuaWRvIHRhbWJpw6luIGVzIG1lbm9yIHF1ZSBlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhLCByZWZvcnphbmRvIGxhIGRlY2lzacOzbiBkZSByZWNoYXphciBsYSBub3JtYWxpZGFkLiBGaW5hbG1lbnRlLCBsYSAqKlBOTSBkZSBQTk0gTVNLKiogeSAqKipQTk0gblRlc3QqKiogcHJlc2VudGEgdW4gXChwXCktdmFsb3IgaW5mZXJpb3IgYSBcKFxhbHBoYVwpLCBjb25maXJtYW5kbyBxdWUsIGVuIGNvbmp1bnRvLCBsYXMgdmFyaWFibGVzICoqZWRhZF9wYWNpZW50ZSoqLCAqKkFndWRlemFfdmlzdWFsX09EKiosICoqQWd1ZGV6YV92aXN1YWxfT0kqKiwgKipIb3Jhc19wYW50YWxsYV9kaWEqKiB5ICoqSG9yYXNfYWYqKiBubyBzZSBhanVzdGFuIGEgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gRW4gY29uc2VjdWVuY2lhLCB0b2RhcyBsYXMgcHJ1ZWJhcyBhcGxpY2FkYXMgY29pbmNpZGVuIGVuIHF1ZSwgYWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBjb25zaWRlcmFkbywgbm8gc2Ugc3VzdGVudGEgbGEgaGlww7N0ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHBhcmEgZWwgdmVjdG9yIGRlIHZhcmlhYmxlcyBtw6l0cmljYXMsIGFjZXB0w6FuZG9zZSBsYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhLg0KDQojIyMjIFBOTSBIZW56ZS1aaXJrbGVyDQpgYGB7ciBQTk1fSGVuemVfWmlya2xlciA9ICdjZW50ZXInfQ0KbWh6KGNjZF92aXNpb24yMDIwX0VUTFssIC1jKDExLDMsNCw1LDYsNywxMiwxMyldKQ0KYGBgDQoNCkEgcGFydGlyIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBzZWNjacOzbiAxLjIsIHNlIGFwbGljYSB1bmEgcHJ1ZWJhIGVzdGFkw61zdGljYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSBjb24gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBcKFxhbHBoYSA9IDAuMDVcKSwgY29uIGVsIHByb3DDs3NpdG8gZGUgZXZhbHVhciBzaSBlbCB2ZWN0b3IgZm9ybWFkbyBwb3IgbGFzIHZhcmlhYmxlcyBtw6l0cmljYXMgcHJvdmllbmUgZGUgdW5hIHBvYmxhY2nDs24gY29uIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gRW4gZXN0ZSBlc3R1ZGlvLCBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMgZW4gZXNjYWxhIGRlIHJhesOzbiBzb246ICoqZWRhZF9wYWNpZW50ZSoqLCAqKkFndWRlemFfdmlzdWFsX09EKiosICoqQWd1ZGV6YV92aXN1YWxfT0kqKiwgKipIb3Jhc19wYW50YWxsYV9kaWEqKiB5ICoqSG9yYXNfYWYqKi4gQW50ZXMgZGUgcmVhbGl6YXIgbGFzIHBydWViYXMsIGVzdGFzIHZhcmlhYmxlcyBzZSBlc3RhbmRhcml6YW4gcGFyYSBnYXJhbnRpemFyIGNvbXBhcmFiaWxpZGFkIHkgZXN0YWJpbGlkYWQgbnVtw6lyaWNhIGVuIGxvcyBjw6FsY3Vsb3MuDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIHByZXNlbnRhIGRlIG1hbmVyYSBzZXBhcmFkYSBsb3MgcmVzdWx0YWRvcyBkZSBsYXMgcHJpbmNpcGFsZXMgcHJ1ZWJhcyBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSBjb25zaWRlcmFkYXM6IE1hcmRpYSwgSGVuemXigJNaaXJrbGVyLCBEb29ybmlr4oCTSGFuc2VuIHkgUm95c3Rvbi4gRW4gbGEgcGVzdGHDsWEgY29ycmVzcG9uZGllbnRlIGEgbGEgKipQTk0gZGUgTWFyZGlhKiogc2UgcmVwb3J0YW4gbG9zIGVzdGFkw61zdGljb3MgZGUgYXNpbWV0csOtYSB5IGN1cnRvc2lzIG11bHRpdmFyaWFkYXMsIGp1bnRvIGNvbiBzdXMgcmVzcGVjdGl2b3MgXChwXCktdmFsb3Jlcy4gRGFkbyBxdWUsIHBhcmEgYWwgbWVub3MgdW5vIGRlIGVzdG9zIGNvbXBvbmVudGVzLCBlbCBcKHBcKS12YWxvciByZXN1bHRhIG1lbm9yIHF1ZSBlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIGVzdGFibGVjaWRvLCBzZSBwcm9jZWRlIGEgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLCBjb25jbHV5ZW5kbyBxdWUgZWwgY29uanVudG8gZGUgdmFyaWFibGVzIG3DqXRyaWNhcyBubyBzaWd1ZSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLg0KDQpEZSBmb3JtYSBjb25zaXN0ZW50ZSwgbGEgcGVzdGHDsWEgYXNvY2lhZGEgYSBsYSAqKlBOTSBkZSBIZW56ZeKAk1ppcmtsZXIqKiBtdWVzdHJhIHVuIFwocFwpLXZhbG9yIGluZmVyaW9yIGEgXChcYWxwaGEgPSAwLjA1XCksIGxvIHF1ZSBsbGV2YSBpZ3VhbG1lbnRlIGEgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhIHkgYWNlcHRhciBsYSBoaXDDs3Rlc2lzIGFsdGVybmF0aXZhIGRlIHF1ZSBsb3MgZGF0b3Mgbm8gcHJvdmllbmVuIGRlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIFJlc3VsdGFkb3MgYW7DoWxvZ29zIHNlIG9ic2VydmFuIGVuIGxhICoqUE5NIGRlIERvb3JuaWvigJNIYW5zZW4qKiwgZG9uZGUgZWwgXChwXCktdmFsb3Igb2J0ZW5pZG8gdGFtYmnDqW4gZXMgbWVub3IgcXVlIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEsIHJlZm9yemFuZG8gbGEgZGVjaXNpw7NuIGRlIHJlY2hhemFyIGxhIG5vcm1hbGlkYWQuIEZpbmFsbWVudGUsIGxhICoqUE5NIGRlIFBOTSBNU0sqKiB5ICoqKlBOTSBuVGVzdCoqKiBwcmVzZW50YSB1biBcKHBcKS12YWxvciBpbmZlcmlvciBhIFwoXGFscGhhXCksIGNvbmZpcm1hbmRvIHF1ZSwgZW4gY29uanVudG8sIGxhcyB2YXJpYWJsZXMgKiplZGFkX3BhY2llbnRlKiosICoqQWd1ZGV6YV92aXN1YWxfT0QqKiwgKipBZ3VkZXphX3Zpc3VhbF9PSSoqLCAqKkhvcmFzX3BhbnRhbGxhX2RpYSoqIHkgKipIb3Jhc19hZioqIG5vIHNlIGFqdXN0YW4gYSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBFbiBjb25zZWN1ZW5jaWEsIHRvZGFzIGxhcyBwcnVlYmFzIGFwbGljYWRhcyBjb2luY2lkZW4gZW4gcXVlLCBhbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIGNvbnNpZGVyYWRvLCBubyBzZSBzdXN0ZW50YSBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgcGFyYSBlbCB2ZWN0b3IgZGUgdmFyaWFibGVzIG3DqXRyaWNhcywgYWNlcHTDoW5kb3NlIGxhIGhpcMOzdGVzaXMgYWx0ZXJuYXRpdmEuDQoNCiMjIyMgUE5NIE1TSw0KYGBge3IgUE5NX01TSywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQptc2soY2NkX3Zpc2lvbjIwMjBfRVRMWywgLWMoMTEsMyw0LDUsNiw3LDEyLDEzKV0sIEI9MTApDQpgYGANCg0KQSBwYXJ0aXIgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIHNlY2Npw7NuIDEuMiwgc2UgYXBsaWNhIHVuYSBwcnVlYmEgZXN0YWTDrXN0aWNhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIGNvbiBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIFwoXGFscGhhID0gMC4wNVwpLCBjb24gZWwgcHJvcMOzc2l0byBkZSBldmFsdWFyIHNpIGVsIHZlY3RvciBmb3JtYWRvIHBvciBsYXMgdmFyaWFibGVzIG3DqXRyaWNhcyBwcm92aWVuZSBkZSB1bmEgcG9ibGFjacOzbiBjb24gZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBFbiBlc3RlIGVzdHVkaW8sIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyBlbiBlc2NhbGEgZGUgcmF6w7NuIHNvbjogKiplZGFkX3BhY2llbnRlKiosICoqQWd1ZGV6YV92aXN1YWxfT0QqKiwgKipBZ3VkZXphX3Zpc3VhbF9PSSoqLCAqKkhvcmFzX3BhbnRhbGxhX2RpYSoqIHkgKipIb3Jhc19hZioqLiBBbnRlcyBkZSByZWFsaXphciBsYXMgcHJ1ZWJhcywgZXN0YXMgdmFyaWFibGVzIHNlIGVzdGFuZGFyaXphbiBwYXJhIGdhcmFudGl6YXIgY29tcGFyYWJpbGlkYWQgeSBlc3RhYmlsaWRhZCBudW3DqXJpY2EgZW4gbG9zIGPDoWxjdWxvcy4NCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgcHJlc2VudGEgZGUgbWFuZXJhIHNlcGFyYWRhIGxvcyByZXN1bHRhZG9zIGRlIGxhcyBwcmluY2lwYWxlcyBwcnVlYmFzIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIGNvbnNpZGVyYWRhczogTWFyZGlhLCBIZW56ZeKAk1ppcmtsZXIsIERvb3JuaWvigJNIYW5zZW4geSBSb3lzdG9uLiBFbiBsYSBwZXN0YcOxYSBjb3JyZXNwb25kaWVudGUgYSBsYSAqKlBOTSBkZSBNYXJkaWEqKiBzZSByZXBvcnRhbiBsb3MgZXN0YWTDrXN0aWNvcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMgbXVsdGl2YXJpYWRhcywganVudG8gY29uIHN1cyByZXNwZWN0aXZvcyBcKHBcKS12YWxvcmVzLiBEYWRvIHF1ZSwgcGFyYSBhbCBtZW5vcyB1bm8gZGUgZXN0b3MgY29tcG9uZW50ZXMsIGVsIFwocFwpLXZhbG9yIHJlc3VsdGEgbWVub3IgcXVlIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZXN0YWJsZWNpZG8sIHNlIHByb2NlZGUgYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEsIGNvbmNsdXllbmRvIHF1ZSBlbCBjb25qdW50byBkZSB2YXJpYWJsZXMgbcOpdHJpY2FzIG5vIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuDQoNCkRlIGZvcm1hIGNvbnNpc3RlbnRlLCBsYSBwZXN0YcOxYSBhc29jaWFkYSBhIGxhICoqUE5NIGRlIEhlbnpl4oCTWmlya2xlcioqIG11ZXN0cmEgdW4gXChwXCktdmFsb3IgaW5mZXJpb3IgYSBcKFxhbHBoYSA9IDAuMDVcKSwgbG8gcXVlIGxsZXZhIGlndWFsbWVudGUgYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgeSBhY2VwdGFyIGxhIGhpcMOzdGVzaXMgYWx0ZXJuYXRpdmEgZGUgcXVlIGxvcyBkYXRvcyBubyBwcm92aWVuZW4gZGUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gUmVzdWx0YWRvcyBhbsOhbG9nb3Mgc2Ugb2JzZXJ2YW4gZW4gbGEgKipQTk0gZGUgRG9vcm5pa+KAk0hhbnNlbioqLCBkb25kZSBlbCBcKHBcKS12YWxvciBvYnRlbmlkbyB0YW1iacOpbiBlcyBtZW5vciBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSwgcmVmb3J6YW5kbyBsYSBkZWNpc2nDs24gZGUgcmVjaGF6YXIgbGEgbm9ybWFsaWRhZC4gRmluYWxtZW50ZSwgbGEgKipQTk0gZGUgUE5NIE1TSyoqIHkgKioqUE5NIG5UZXN0KioqIHByZXNlbnRhIHVuIFwocFwpLXZhbG9yIGluZmVyaW9yIGEgXChcYWxwaGFcKSwgY29uZmlybWFuZG8gcXVlLCBlbiBjb25qdW50bywgbGFzIHZhcmlhYmxlcyAqKmVkYWRfcGFjaWVudGUqKiwgKipBZ3VkZXphX3Zpc3VhbF9PRCoqLCAqKkFndWRlemFfdmlzdWFsX09JKiosICoqSG9yYXNfcGFudGFsbGFfZGlhKiogeSAqKkhvcmFzX2FmKiogbm8gc2UgYWp1c3RhbiBhIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIEVuIGNvbnNlY3VlbmNpYSwgdG9kYXMgbGFzIHBydWViYXMgYXBsaWNhZGFzIGNvaW5jaWRlbiBlbiBxdWUsIGFsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgY29uc2lkZXJhZG8sIG5vIHNlIHN1c3RlbnRhIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSBwYXJhIGVsIHZlY3RvciBkZSB2YXJpYWJsZXMgbcOpdHJpY2FzLCBhY2VwdMOhbmRvc2UgbGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YS4NCg0KIyMjIyBQTk0gblRlc3QNCmBgYHtyIFBOTV9uVGVzdCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQptdm5UZXN0KGNjZF92aXNpb24yMDIwX0VUTFssIC1jKDExLDMsNCw1LDYsNywxMiwxMyldLCBCPTEwKQ0KDQpgYGANCg0KQSBwYXJ0aXIgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIHNlY2Npw7NuIDEuMiwgc2UgYXBsaWNhIHVuYSBwcnVlYmEgZXN0YWTDrXN0aWNhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIGNvbiBuaXZlbCBkZSBzaWduaWZpY2FuY2lhIFwoXGFscGhhID0gMC4wNVwpLCBjb24gZWwgcHJvcMOzc2l0byBkZSBldmFsdWFyIHNpIGVsIHZlY3RvciBmb3JtYWRvIHBvciBsYXMgdmFyaWFibGVzIG3DqXRyaWNhcyBwcm92aWVuZSBkZSB1bmEgcG9ibGFjacOzbiBjb24gZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBFbiBlc3RlIGVzdHVkaW8sIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyBlbiBlc2NhbGEgZGUgcmF6w7NuIHNvbjogKiplZGFkX3BhY2llbnRlKiosICoqQWd1ZGV6YV92aXN1YWxfT0QqKiwgKipBZ3VkZXphX3Zpc3VhbF9PSSoqLCAqKkhvcmFzX3BhbnRhbGxhX2RpYSoqIHkgKipIb3Jhc19hZioqLiBBbnRlcyBkZSByZWFsaXphciBsYXMgcHJ1ZWJhcywgZXN0YXMgdmFyaWFibGVzIHNlIGVzdGFuZGFyaXphbiBwYXJhIGdhcmFudGl6YXIgY29tcGFyYWJpbGlkYWQgeSBlc3RhYmlsaWRhZCBudW3DqXJpY2EgZW4gbG9zIGPDoWxjdWxvcy4NCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgcHJlc2VudGEgZGUgbWFuZXJhIHNlcGFyYWRhIGxvcyByZXN1bHRhZG9zIGRlIGxhcyBwcmluY2lwYWxlcyBwcnVlYmFzIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIGNvbnNpZGVyYWRhczogTWFyZGlhLCBIZW56ZeKAk1ppcmtsZXIsIERvb3JuaWvigJNIYW5zZW4geSBSb3lzdG9uLiBFbiBsYSBwZXN0YcOxYSBjb3JyZXNwb25kaWVudGUgYSBsYSAqKlBOTSBkZSBNYXJkaWEqKiBzZSByZXBvcnRhbiBsb3MgZXN0YWTDrXN0aWNvcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMgbXVsdGl2YXJpYWRhcywganVudG8gY29uIHN1cyByZXNwZWN0aXZvcyBcKHBcKS12YWxvcmVzLiBEYWRvIHF1ZSwgcGFyYSBhbCBtZW5vcyB1bm8gZGUgZXN0b3MgY29tcG9uZW50ZXMsIGVsIFwocFwpLXZhbG9yIHJlc3VsdGEgbWVub3IgcXVlIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZXN0YWJsZWNpZG8sIHNlIHByb2NlZGUgYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEsIGNvbmNsdXllbmRvIHF1ZSBlbCBjb25qdW50byBkZSB2YXJpYWJsZXMgbcOpdHJpY2FzIG5vIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuDQoNCkRlIGZvcm1hIGNvbnNpc3RlbnRlLCBsYSBwZXN0YcOxYSBhc29jaWFkYSBhIGxhICoqUE5NIGRlIEhlbnpl4oCTWmlya2xlcioqIG11ZXN0cmEgdW4gXChwXCktdmFsb3IgaW5mZXJpb3IgYSBcKFxhbHBoYSA9IDAuMDVcKSwgbG8gcXVlIGxsZXZhIGlndWFsbWVudGUgYSByZWNoYXphciBsYSBoaXDDs3Rlc2lzIG51bGEgeSBhY2VwdGFyIGxhIGhpcMOzdGVzaXMgYWx0ZXJuYXRpdmEgZGUgcXVlIGxvcyBkYXRvcyBubyBwcm92aWVuZW4gZGUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gUmVzdWx0YWRvcyBhbsOhbG9nb3Mgc2Ugb2JzZXJ2YW4gZW4gbGEgKipQTk0gZGUgRG9vcm5pa+KAk0hhbnNlbioqLCBkb25kZSBlbCBcKHBcKS12YWxvciBvYnRlbmlkbyB0YW1iacOpbiBlcyBtZW5vciBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSwgcmVmb3J6YW5kbyBsYSBkZWNpc2nDs24gZGUgcmVjaGF6YXIgbGEgbm9ybWFsaWRhZC4gRmluYWxtZW50ZSwgbGEgKipQTk0gZGUgUE5NIE1TSyoqIHkgKioqUE5NIG5UZXN0KioqIHByZXNlbnRhIHVuIFwocFwpLXZhbG9yIGluZmVyaW9yIGEgXChcYWxwaGFcKSwgY29uZmlybWFuZG8gcXVlLCBlbiBjb25qdW50bywgbGFzIHZhcmlhYmxlcyAqKmVkYWRfcGFjaWVudGUqKiwgKipBZ3VkZXphX3Zpc3VhbF9PRCoqLCAqKkFndWRlemFfdmlzdWFsX09JKiosICoqSG9yYXNfcGFudGFsbGFfZGlhKiogeSAqKkhvcmFzX2FmKiogbm8gc2UgYWp1c3RhbiBhIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIEVuIGNvbnNlY3VlbmNpYSwgdG9kYXMgbGFzIHBydWViYXMgYXBsaWNhZGFzIGNvaW5jaWRlbiBlbiBxdWUsIGFsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgY29uc2lkZXJhZG8sIG5vIHNlIHN1c3RlbnRhIGxhIGhpcMOzdGVzaXMgbnVsYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSBwYXJhIGVsIHZlY3RvciBkZSB2YXJpYWJsZXMgbcOpdHJpY2FzLCBhY2VwdMOhbmRvc2UgbGEgaGlww7N0ZXNpcyBhbHRlcm5hdGl2YS4NCg0KDQojIyAqKkZhc2UgMiBbQ29tcG9uZW50ZXMgUHJpbmNpcGFsZXNdKioNCg0KRW4gZXN0YSAqKnNlZ3VuZGEgZXRhcGEqKiBkZWwgZXN0dWRpbywgc2UgcHJlc2VudGFyw6FuIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcyBiYXNhZGFzIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGFuYWxpemFkbyBwcmV2aWFtZW50ZSBlbiBsYSBbRmFzZSAxXSgjc2VjMSkuIEFob3JhLCBlbCBlbmZvcXVlIHNlIGNlbnRyYXLDoSBlbiBlbCBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKEFDUCkgYXBsaWNhZG8gYSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMsIGluY2x1eWVuZG8gYXNwZWN0b3MgY29tbyBsYSBzZWxlY2Npw7NuIGRlIGNvbXBvbmVudGVzLCBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiwgY29udHJpYnVjaW9uZXMgeSBzdSBpbnRlcnByZXRhY2nDs24uDQoNCiMjIyAyLjEuIE9iamV0aXZvcw0KDQpFbCAqKkFDUCoqIHNlIGxvZ3JhIGEgbG8gbGFyZ28gZGUgbGFzIHNpZ3VpZW50ZXMgZmFzZXM6IGdlbmVyYWNpw7NuIGRlIG51ZXZhcyB2YXJpYWJsZXMsIHJlZHVjY2nDs24gZGltZW5zaW9uYWwgZGVsIGVzcGFjaW8gZGUgbG9zIGRhdG9zLCBlbGltaW5hY2nDs24gZGUgdmFyaWFibGVzIGRlIHBvY28gYXBvcnRlIGUgaW50ZXJwcmV0YWNpw7NuIGRlIGxvcyBjb21wb25lbnRlcyByZXN1bHRhbnRlcyBlbiBlbCBjb250ZXh0byBkZWwgcHJvYmxlbWEgZGVsIGN1YWwgc2Ugb2J0dXZpZXJvbiBsb3MgZGF0by4NCg0KRXN0aW1hZG8gbGVjdG9yLCBzaSBkZXNlYSBleHBsb3JhciBsb3MgZnVuZGFtZW50b3MgZGUgZXN0ZSBhbsOhbGlzaXMgY29uIG1heW9yIHByb2Z1bmRpZGFkLiBMb3MgZGV0YWxsZXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIHNlIGVuY3VlbnRyYW4gZGVzY3JpdG9zIGVuIGxhIFtTZWNjacOzbiAxLjJdKCNzZWMxLjIpLCBtaWVudHJhcyBxdWUgbG9zIHByaW5jaXBpb3MgdGXDs3JpY29zIHF1ZSBzdXN0ZW50YW4gZXN0ZSBlc3R1ZGlvIGVzdMOhbiBjdWlkYWRvc2FtZW50ZSBkZXNhcnJvbGxhZG9zIGVuIGxhIGRlbm9taW5hZGEgW0Zhc2UgMV0oI3NlYzEpLiBVbmEgbGVjdHVyYSBkZXRlbmlkYSBkZSBlc3RhcyBzZWNjaW9uZXMgZW5yaXF1ZWNlcsOhIHN1IGNvbXByZW5zacOzbiB5IGFwcmVjaWFjacOzbiBkZWwgdHJhYmFqbyBwcmVzZW50YWRvLg0KDQoNCiMjIyAyLjIuIFNlbGVjY2nDs24gZGUgQ29tcG9uZW50ZXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KQ29tbyBzZcOxYWxhbiBbQEFFRE1EaWF6LU1vcmFsZXMxZWRdLCBlbCBBbsOhbGlzaXMgZGUgQ29tcG9uZW50ZXMgUHJpbmNpcGFsZXMgKiooQUNQKSoqIHBlcm1pdGUgcmVvcmdhbml6YXIgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvIGFsIHJlZHVjaXIgZWwgbsO6bWVybyBkZSB2YXJpYWJsZXMsIHNpbiByZXF1ZXJpciBzdXBvc2ljaW9uZXMgZXNwZWPDrWZpY2FzIHNvYnJlIGxhIGRpc3RyaWJ1Y2nDs24gZGUgcHJvYmFiaWxpZGFkIGRlIGVzdGFzLiBFc3RhIHJlZHVjY2nDs24gc2UgYWxjYW56YSBtZWRpYW50ZSBsYSBjcmVhY2nDs24gZGUgY29tYmluYWNpb25lcyBsaW5lYWxlcyBkZSBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMsIGRpc2XDsWFkYXMgcGFyYSBjYXB0YXIgbGEgbWF5b3IgdmFyaWFiaWxpZGFkIHBvc2libGUgZW4gbG9zIGRhdG9zLiBEZSBlc3RlIG1vZG8sIGVsICoqQUNQKiogZ2VuZXJhIG51ZXZhcyB2YXJpYWJsZXMsIGRlbm9taW5hZGFzIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBxdWUgcHJlc2VudGFuIGluZGVwZW5kZW5jaWEgZXN0YWTDrXN0aWNhIHkgYXVzZW5jaWEgZGUgY29ycmVsYWNpw7NuLCBzaWVtcHJlIGJham8gZWwgc3VwdWVzdG8gZGUgbm9ybWFsaWRhZC4NCg0KDQpBIHBhcnRpciBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtTZWNjacOzbiAxLjJdKCNzZWMxLjIpLCBzZSByZXF1aWVyZSBpbmljaWFsbWVudGUgZGV0ZXJtaW5hciBlbCBwb3JjZW50YWplIGRlIHZhcmlhbnphIGV4cGxpY2FkbyBwb3IgY2FkYSBkaW1lbnNpw7NuIHRyYXMgcmVhbGl6YXIgZWwgQW7DoWxpc2lzIGRlIENvbXBvbmVudGVzIFByaW5jaXBhbGVzIChBQ1ApLiBQb3N0ZXJpb3JtZW50ZSwgY29uIGJhc2UgZW4gZWwgYXV0b3ZhbG9yIHByb21lZGlvIG8gbWVkaWFudGUgdW4gZ3LDoWZpY28gZGUgc2VkaW1lbnRhY2nDs24sIHNlIGRlYmUgZGVjaWRpciBjdcOhbnRvcyBjb21wb25lbnRlcyBjb25zZXJ2YXIuDQoNCiMjIyMgTWF0cml6IEFDUA0KYGBge3IgTWF0cml6X0FDUCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpnZXRfZWlnZW52YWx1ZShQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkNCmBgYA0KDQpMYSAqKk1hdHJpeiBBQ1AqKiBtdWVzdHJhIGNpbmNvIGRpbWVuc2lvbmVzLCBkb25kZSBsYSBwcmltZXJhIHJldGllbmUgZWwgJDIyLjQ5JSQgZGUgbGEgdmFyaWFuemEsIHNlZ3VpZGEgcG9yIGxhIHNlZ3VuZGEgY29uIHVuICQyMC41MiUkLCB5IGxhIHRlcmNlcmEgY29uIHVuICQxOS44NSQkJSQuIExhcyBkb3Mgw7psdGltYXMgZGltZW5zaW9uZXMgZXhwbGljYW4gdW4gJDE4LjgyJSQgeSB1biAkMTguMzElJCwgcmVzcGVjdGl2YW1lbnRlLiBFbiBlc3RlIHNlbnRpZG8sIGxhIHJlcHJlc2VudGF0aXZpZGFkIGRlIGxhIGNvbWJpbmFjacOzbiBsaW5lYWwgcXVlIGRlZmluZSBsYSAqKmRpbWVuc2nDs24gMSoqIGVzIG1vZGVyYWRhbWVudGUgc3VwZXJpb3IgZW4gY29tcGFyYWNpw7NuIGNvbiBsYXMgZGVtw6FzLiBDb21vIGVzdGEgbWF0cml6IG5vIHByb3BvcmNpb25hIGluZm9ybWFjacOzbiBkaXJlY3RhIHNvYnJlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcywgc2UgY29udGluw7phIGV4cGxvcmFuZG8gbGEgaWRlbnRpZmljYWNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgcXVlIG3DoXMgY29udHJpYnV5ZW4gYSBsYSBkaW1lbnNpw7NuIGNvbiBlbCBtYXlvciB2YWxvciBwcm9waW8uDQoNCkNvbiBiYXNlIGVuIGxhIGV2aWRlbmNpYSBkZSBsYSB0YWJsYSwgw7puaWNhbWVudGUgbGFzIERpbWVuc2lvbmVzIDEgeSAyIHNhdGlzZmFjZW4gZXN0ZSBjcml0ZXJpbywgcmVnaXN0cmFuZG8gdmFsb3JlcyBkZSAkMS4xMiQgeSAkMS4wMyQgcmVzcGVjdGl2YW1lbnRlLiBMYSBEaW1lbnNpw7NuIDMsIGFsIHNpdHVhcnNlIGp1c3RvIHBvciBkZWJham8gZGUgZXN0ZSB1bWJyYWwsIGZ1ZSBkZXNjYXJ0YWRhLlBvciBjb25zaWd1aWVudGUsIHNlIGRldGVybWluw7MgcmV0ZW5lciBkb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIEVuIGNvbmp1bnRvLCBlc3RhcyBkb3MgZGltZW5zaW9uZXMgbG9ncmFuIGV4cGxpY2FyIGVsIDQzLjAxJSBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgY29udGVuaWRhIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zLg0KDQpVbiBoYWxsYXpnbyBub3RvcmlvIGRlbCBhbsOhbGlzaXMgZXMgbGEgZGlzdHJpYnVjacOzbiBob21vZ8OpbmVhIGRlIGxhIHZhcmlhbnphIGVudHJlIHRvZGFzIGxhcyBkaW1lbnNpb25lcyAoYXByb3hpbWFkYW1lbnRlIHVuICQyMFwlJCBwb3IgY2FkYSBkaW1lbnNpw7NuKS4gRXN0ZSBwYXRyw7NuIHN1Z2llcmUgcXVlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcyBleGhpYmVuIHVuIGdyYWRvIHNpZ25pZmljYXRpdm8gZGUgaW5kZXBlbmRlbmNpYSBtdXR1YSB5IHF1ZSBsYSBlc3RydWN0dXJhIGRlIGxvcyBkYXRvcyBubyBlc3TDoSBkb21pbmFkYSBwb3IgY29ycmVsYWNpb25lcyBleHRyZW1hZGFtZW50ZSByb2J1c3RhcyBlbnRyZSBlbGxhcy4NCg0KIyMjIyBNYXRyaXogZGUgQ29ycmVsYWNpb25lcw0KYGBge3IgTWF0cml6X2RlX0NvcnJlbGFjaW9uZXN9DQpyb3VuZChjb3IoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldKSwyKQ0KYGBgDQoNCkxhICoqTWF0cml6IGRlIENvcnJlbGFjaW9uZXMqKiBheXVkYSBhIGRlc2NyaWJpciBsYXMgcmVsYWNpb25lcyBlbnRyZSBsYXMgdmFyaWFibGVzIHF1ZSBjb25mb3JtYW4gbGEgZGltZW5zacOzbiAxLiBTZWfDum4gZXN0YSBtYXRyaXosIGxhcyBjb3JyZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMgc29uIGVuIHN1IG1heW9yw61hIGJhamFzLCBjb24gdW4gdmFsb3IgbcOheGltbyBkZSAkMC4wNCQgZW50cmUgKipIb3Jhc19wZCoqIHkgKiplZGFkX3BhY2llbnRlKiouIEVzdG8gaW5kaWNhIHF1ZSBsYXMgdmFyaWFibGVzIG5vIGVzdMOhbiBmdWVydGVtZW50ZSByZWxhY2lvbmFkYXMgZW50cmUgc8OtLCBsbyBxdWUgcG9kcsOtYSBpbmZsdWlyIGVuIGPDs21vIGNvbnRyaWJ1eWVuIGEgbGEgY29tYmluYWNpw7NuIGxpbmVhbCBxdWUgZGVmaW5lIGxhIHByaW1lcmEgZGltZW5zacOzbi4NCg0KTm8gb2JzdGFudGUsIHNlIHRvbcOzIGxhIGRlY2lzacOzbiBlc3RyYXTDqWdpY2EgZGUgcmV0ZW5lciBkb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMsIGxvcyBjdWFsZXMsIGVuIGNvbmp1bnRvLCBleHBsaWNhbiBlbCAqKjQzJSBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwqKi4gRXN0YSBlbGVjY2nDs24gc2UgZnVuZGFtZW50w7MgZW4gbGEgYsO6c3F1ZWRhIGRlIHVuYSBlc3RydWN0dXJhIGxhdGVudGU6IGEgcGVzYXIgZGUgcXVlIGxhcyB2YXJpYWJsZXMgZXhoaWJlbiBiYWphIGNvbGluZWFsaWRhZCBlc3RhZMOtc3RpY2EsIGVsIHByaW1lciBjb21wb25lbnRlIGxvZ3LDsyBhZ3J1cGFyIHVuIHBhdHLDs24gY29oZXJlbnRlIHF1ZSB2aW5jdWxhIGVsIHVzbyBkZSBwYW50YWxsYXMgeSBsYSBlZGFkIGNvbiBsYSBjYXBhY2lkYWQgdmlzdWFsIGRlIGxvcyBzdWpldG9zLg0KDQpFc3RlIGhhbGxhemdvIHJlc3VsdGEgY3J1Y2lhbCwgcHVlcyBwZXJtaXRlIGNvbmZpcm1hciBxdWUsIGF1biBlbiB1biBjb25qdW50byBkZSBkYXRvcyBkaXNwZXJzbywgZXhpc3RlIHVuYSBlc3RydWN0dXJhIHN1YnlhY2VudGUgcXVlIGNvbmVjdGEgbG9zIGjDoWJpdG9zIGRpZ2l0YWxlcyBjb24gbGEgc2FsdWQgb2N1bGFyLCBwcm9wb3JjaW9uYW5kbyB1bmEgYmFzZSBpbnRlcnByZXRhdGl2YSBwYXJhIGxvcyBhbsOhbGlzaXMgZGUgcmVncmVzacOzbiBwb3N0ZXJpb3Jlcy4NCg0KIyMjIyBWYWxvcmVzIHkgVmVjdG9yZXMgUHJvcGlvcw0KYGBge3IgVmFsb3Jlc195X1ZlY3RvcmVzX1Byb3Bpb3MsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KcHJpbmNvbXAoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBjb3IgPSBUUlVFKSRzZGV2XjINCnByaW5jb21wKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgY29yID0gVFJVRSkkbG9hZGluZ3NbICwxOjVdDQpgYGANCg0KRWwgcmVzdWx0YWRvIGRlbCBhbsOhbGlzaXMgaW5kaWPDsyB1bmEgYXVzZW5jaWEgZGUgY29saW5lYWxpZGFkIG8gcmVkdW5kYW5jaWEgc2lnbmlmaWNhdGl2YSBlbnRyZSBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMsIGxvIHF1ZSBzZSBtYW5pZmVzdMOzIGVuIHVuYSBkaXN0cmlidWNpw7NuIGVxdWl0YXRpdmEgZGUgbGEgdmFyaWFuemEgYSB0cmF2w6lzIGRlIGxhcyBkaXN0aW50YXMgZGltZW5zaW9uZXMsIGVuIGx1Z2FyIGRlIHVuYSBjb25jZW50cmFjacOzbiBtYXJjYWRhIGVuIGVsIHByaW1lciBjb21wb25lbnRlLiBObyBvYnN0YW50ZSwgc2UgdG9tw7MgbGEgZGVjaXNpw7NuIGVzdHJhdMOpZ2ljYSBkZSByZXRlbmVyIGRvcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgbG9zIGN1YWxlcywgZW4gY29uanVudG8sIGV4cGxpY2FuIGVsIDQzJSBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwuIA0KDQpFc3RhIGVsZWNjacOzbiBzZSBmdW5kYW1lbnTDsyBlbiBsYSBiw7pzcXVlZGEgZGUgdW5hIGVzdHJ1Y3R1cmEgbGF0ZW50ZTogYSBwZXNhciBkZSBxdWUgbGFzIHZhcmlhYmxlcyBleGhpYmVuIGJhamEgY29saW5lYWxpZGFkIGVzdGFkw61zdGljYSwgZWwgcHJpbWVyIGNvbXBvbmVudGUgbG9ncsOzIGFncnVwYXIgdW4gcGF0csOzbiBjb2hlcmVudGUgcXVlIHZpbmN1bGEgZWwgdXNvIGRlIHBhbnRhbGxhcyB5IGxhIGVkYWQgY29uIGxhIGNhcGFjaWRhZCB2aXN1YWwgZGUgbG9zIHN1amV0b3MuIEVzdGUgaGFsbGF6Z28gcmVzdWx0YSBjcnVjaWFsLCBwdWVzIHBlcm1pdGUgY29uZmlybWFyIHF1ZSwgYXVuIGVuIHVuIGNvbmp1bnRvIGRlIGRhdG9zIGRpc3BlcnNvLCBleGlzdGUgdW5hIGVzdHJ1Y3R1cmEgc3VieWFjZW50ZSBxdWUgY29uZWN0YSBsb3MgaMOhYml0b3MgZGlnaXRhbGVzIGNvbiBsYSBzYWx1ZCBvY3VsYXIsIHByb3BvcmNpb25hbmRvIHVuYSBiYXNlIGludGVycHJldGF0aXZhIHBhcmEgbG9zIGFuw6FsaXNpcyBkZSByZWdyZXNpw7NuIHBvc3RlcmlvcmVzLiANCg0KRWwgQ29tcG9uZW50ZSAxIChlbCAnUGVyZmlsIGRlIFJpZXNnbyBWaXN1YWwnKSBpbmRpY2EgbWF0ZW3DoXRpY2FtZW50ZSBxdWUsIGEgbWF5b3IgZWRhZCB5IG1heW9yIHVzbyBkZSBwYW50YWxsYXMsIGxhIGNhcGFjaWRhZCB2aXN1YWwgZXMgbWVub3IsIG1pZW50cmFzIHF1ZSBlbCBDb21wb25lbnRlIDIgZXN0w6EgZG9taW5hZG8gcG9yIGxhIGFjdGl2aWRhZCBmw61zaWNhLCBzdWdpcmllbmRvIHF1ZSBlbCBlamVyY2ljaW8gYWN0w7phIGNvbW8gdW5hIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgZW4gZXN0YSByZWxhY2nDs24gZGUgZGVzZ2FzdGUgdmlzdWFsLg0KDQojIyMjIENvcnJlbGFjaW9uZXMgQ29tcGFyYWRhcw0KYGBge3IgQ29ycmVsYWNpb25lc19Db21wYXJhZGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpwYXIobWZyb3c9YygxLDIpKQ0KY29ycnBsb3Q6OmNvcnJwbG90KGNvcihjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0pLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmNvcnJwbG90Ojpjb3JycGxvdChjb3IocHJpbmNvbXAoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBjb3IgPSBUUlVFKSRzY29yZXMpLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmBgYA0KDQpFbiBlc3RhIHZpc3VhbGl6YWNpw7NuIGNvbXBhcmF0aXZhIHNlIGV2aWRlbmNpYSBlbCBlZmVjdG8gZGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKSBzb2JyZSBsYSBlc3RydWN0dXJhIGRlIGNvcnJlbGFjaW9uZXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zLiBFbiBsYSBtYXRyaXogdWJpY2FkYSBhIGxhIGl6cXVpZXJkYSBzZSByZXByZXNlbnRhbiBsYXMgdmFyaWFibGVzIG9yaWdpbmFsZXMsIGRvbmRlIGxhIHByZWRvbWluYW5jaWEgZGUgdG9uYWxpZGFkZXMgcMOhbGlkYXMgY29uZmlybWEgbG8gb2JzZXJ2YWRvIHByZXZpYW1lbnRlIGVuIGxhIHRhYmxhIGRlIGNvcnJlbGFjaW9uZXM6IGxhcyByZWxhY2lvbmVzIGVudHJlIGxhIGVkYWQsIGxhcyB2YXJpYWJsZXMgZGUgdmlzacOzbiB5IGxvcyBow6FiaXRvcyBldmFsdWFkb3Mgc29uIGTDqWJpbGVzIG8gcHLDoWN0aWNhbWVudGUgaW5leGlzdGVudGVzLCBjb25maWd1cmFuZG8gdW4gcGF0csOzbiBkaXNwZXJzbyB5IHBvY28gZXN0cnVjdHVyYWRvLg0KDQpQb3Igc3UgcGFydGUsIGxhIG1hdHJpeiBwcmVzZW50YWRhIGEgbGEgZGVyZWNoYSBjb3JyZXNwb25kZSBhIGxvcyBkYXRvcyB0cmFuc2Zvcm1hZG9zIG1lZGlhbnRlIGVsIEFDUC4gRW4gZXN0ZSBjYXNvLCBzZSBvYnNlcnZhIHVuYSBub3RhYmxlIGRlcHVyYWNpw7NuIGRlIGxhcyBjb3JyZWxhY2lvbmVzLCB5YSBxdWUgZnVlcmEgZGUgbGEgZGlhZ29uYWwgcHJpbmNpcGFsIGxhIG1hdHJpeiBhcGFyZWNlIGNvbXBsZXRhbWVudGUgZW4gYmxhbmNvLiBFc3RlIHJlc3VsdGFkbyBpbmRpY2EgcXVlIGxvcyBjb21wb25lbnRlcyBvYnRlbmlkb3Mgc29uIGVzdGFkw61zdGljYW1lbnRlIGluZGVwZW5kaWVudGVzIGVudHJlIHPDrSwgZXZpZGVuY2lhbmRvIGxhIGVsaW1pbmFjacOzbiBkZSByZWR1bmRhbmNpYXMgeSBkZWwg4oCccnVpZG/igJ0gcHJlc2VudGUgZW4gbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLiBFbiBjb25zZWN1ZW5jaWEsIGVsIEFDUCBwZXJtaXRlIGNvbnN0cnVpciBkaW1lbnNpb25lcyBvcnRvZ29uYWxlcyB5IG5vIHNvbGFwYWRhcywgaW1wb25pZW5kbyB1biBvcmRlbiBtYXRlbcOhdGljbyBxdWUgZmFjaWxpdGEgbGEgaW50ZXJwcmV0YWNpw7NuIHkgZWwgYW7DoWxpc2lzIGRlbCBmZW7Ds21lbm8gZXN0dWRpYWRvLg0KDQpFc3RlIGhhbGxhemdvIHJlc3VsdGEgY3J1Y2lhbCwgcHVlcyBwZXJtaXRlIGNvbmZpcm1hciBxdWUsIGF1biBlbiB1biBjb25qdW50byBkZSBkYXRvcyBkaXNwZXJzbywgZXhpc3RlIHVuYSBlc3RydWN0dXJhIHN1YnlhY2VudGUgcXVlIGNvbmVjdGEgbG9zIGjDoWJpdG9zIGRpZ2l0YWxlcyBjb24gbGEgc2FsdWQgb2N1bGFyLCBwcm9wb3JjaW9uYW5kbyB1bmEgYmFzZSBpbnRlcnByZXRhdGl2YSBwYXJhIGxvcyBhbsOhbGlzaXMgZGUgcmVncmVzacOzbiBwb3N0ZXJpb3Jlcy4gKipFbCBDb21wb25lbnRlIDEgKGVsICdQZXJmaWwgZGUgUmllc2dvIFZpc3VhbCcpKiogaW5kaWNhIG1hdGVtw6F0aWNhbWVudGUgcXVlLCBhIG1heW9yIGVkYWQgeSBtYXlvciB1c28gZGUgcGFudGFsbGFzLCBsYSBjYXBhY2lkYWQgdmlzdWFsIGVzIG1lbm9yLCBtaWVudHJhcyBxdWUgZWwgKipDb21wb25lbnRlIDIqKiBlc3TDoSBkb21pbmFkbyBwb3IgbGEgYWN0aXZpZGFkIGbDrXNpY2EsIHN1Z2lyaWVuZG8gcXVlIGVsIGVqZXJjaWNpbyBhY3TDumEgY29tbyB1bmEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSBlbiBlc3RhIHJlbGFjacOzbiBkZSBkZXNnYXN0ZSB2aXN1YWwuDQoNCiMjIyMgR3LDoWZpY28gZGUgQ2F0dGVsbA0KYGBge3IgR3JhZmljb19kZV9DYXR0ZWxsLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfZWlnKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIHNjYWxlLnVuaXQgPSBULCBncmFwaCA9IEYpLCBhZGRsYWJlbHMgPSBULCB5bGltPWMoMCw5MCksIG1haW4gPSAiIikNCmBgYA0KDQpFbCBHcsOhZmljbyBkZSBTZWRpbWVudGFjacOzbiBvIGRlIENhdHRlbGwgc2UgdXRpbGl6YSBwYXJhIHZpc3VhbGl6YXIgbGEgcHJvcG9yY2nDs24gZGUgdmFyaWFuemEgZXhwbGljYWRhIHBvciBjYWRhIGNvbXBvbmVudGUgcHJpbmNpcGFsIChlbCBhdXRvdmFsb3IpIHkgYXBsaWNhciBlbCBDcml0ZXJpbyBkZSBDb2RvLCBxdWUgaW5kaWNhIGVsIHB1bnRvIMOzcHRpbW8gZGUgcmV0ZW5jacOzbiBkaW1lbnNpb25hbC5TaW4gZW1iYXJnbywgZW4gZXN0ZSBhbsOhbGlzaXMsIHNlIG9ic2VydmEgcXVlIGxhIGdyw6FmaWNhIHByZXNlbnRhIHVuYSBwZW5kaWVudGUgZXhjZXBjaW9uYWxtZW50ZSBzdWF2ZSB5IGNhc2kgcGxhbmEgLiBMYSB2YXJpYW56YSBleHBsaWNhZGEgZGVzY2llbmRlIGRlIG1hbmVyYSBsZW50YSB5IHByb2dyZXNpdmEsIGRlc2RlIGVsICQyMi41XCUkIGVuIGxhIHByaW1lcmEgZGltZW5zacOzbiBoYXN0YSBlbCAkMTguM1wlJCBlbiBsYSDDumx0aW1hLg0KDQpFc3RlIHBhdHLDs24gdmlzdWFsIGVzIHVuYSBjb25maXJtYWNpw7NuIGRpcmVjdGEgZGUgbGEgaW5kZXBlbmRlbmNpYSB5IGxhIGJhamEgcmVkdW5kYW5jaWEgZGUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBpbmRpY2FuZG8gcXVlIGxhIGluZm9ybWFjacOzbiBlc3TDoSBkaXN0cmlidWlkYSBkZSBtYW5lcmEgZGVtb2Nyw6F0aWNhIHkgZXF1aXRhdGl2YSBlbnRyZSB0b2RhcyBsYXMgZGltZW5zaW9uZXMuQSBwZXNhciBkZSBsYSBhdXNlbmNpYSBkZSB1biAiY29kbyIgcHJvbnVuY2lhZG8geSB2aXN1YWxtZW50ZSBkcsOhc3RpY28sIGxhIGRlY2lzacOzbiBkZSByZXRlbmVyIGxhcyBkb3MgcHJpbWVyYXMgZGltZW5zaW9uZXMgc2UgbWFudGllbmUgZmlybWUuIA0KDQpFc3RhIGVsZWNjacOzbiBzZSBqdXN0aWZpY2EgcmlndXJvc2FtZW50ZSBhbCBhcGxpY2FyIGVsIENyaXRlcmlvIGRlIEthaXNlciwgc2Vnw7puIGVsIGN1YWwgc29sbyBlc3RhcyBkb3MgZGltZW5zaW9uZXMgc3VwZXJhbiBlbCBhdXRvdmFsb3IgZGUgJDEkLiBMYSByZXRlbmNpw7NuIGRlIGVzdG9zIGRvcyBjb21wb25lbnRlcyBwZXJtaXRlIGV4cGxpY2FyIGRlIG1hbmVyYSBwYXJzaW1vbmlvc2EgZWwgJDQzXCUkIGRlIGxhIHZhcmlhYmlsaWRhZCB0b3RhbCBkZWwgZmVuw7NtZW5vIHksIGxvIHF1ZSBlcyBjcnVjaWFsLCBwcm9wb3JjaW9uYSB1bmEgaW50ZXJwcmV0YWNpw7NuIGNsw61uaWNhIHkgbMOzZ2ljYSBkZSBsYSBlc3RydWN0dXJhIHN1YnlhY2VudGUgZGUgbG9zIGRhdG9zLg0KDQojIyMjIEdyw6FmaWNvIGRlIENhdHRlbGwtS2Fpc2VyDQpgYGB7ciBHcmFmaWNvX2RlX0NhdHRlbGxfS2Fpc2VyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNjcmVlKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSxmYWN0b3JzID0gRkFMU0UsIHBjID0gVFJVRSwgbWFpbiA9IiIpDQpgYGANCg0KRWwgR3LDoWZpY28gZGUgU2VkaW1lbnRhY2nDs24gbyBkZSBDYXR0ZWxsIGVzIGxhIGhlcnJhbWllbnRhIHZpc3VhbCB1dGlsaXphZGEgcGFyYSBkZXRlcm1pbmFyIGVsIG7Dum1lcm8gw7NwdGltbyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBhIHJldGVuZXIuIFNpIGJpZW4gZWwgcGF0csOzbiBoYWJpdHVhbCBlcyBvYnNlcnZhciB1biAiY29kbyIgcHJvbnVuY2lhZG8gcXVlIGluZGlxdWUgZWwgcHVudG8gZGUgY29ydGUgaWRlYWwsIGVzdGEgZ3LDoWZpY2EgcHJlc2VudGEgdW5hIHBlbmRpZW50ZSBzdWF2ZSB5IGNhc2kgcGxhbmEuIERpY2hhIG1vcmZvbG9nw61hIGNvbmZpcm1hIHZpc3VhbG1lbnRlIGxhIGluZGVwZW5kZW5jaWEgZGUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBsbyBxdWUgcmVzdWx0w7MgZW4gdW5hIGRpc3RyaWJ1Y2nDs24gZXF1aXRhdGl2YSB5IGxlbnRhIGRlIGxhIHZhcmlhbnphLCBlbiBsdWdhciBkZSBjb25jZW50cmFyc2UgZW4gdW5hIHNvbGEgZGltZW5zacOzbi4gQSBwZXNhciBkZSBlc3RhIGF1c2VuY2lhIGRlIHVuIGNvcnRlIHZpc3VhbCBkcsOhc3RpY28sIGVsIGFuw6FsaXNpcyBzZSBjZW50cmEgZW4gbGEgYXBsaWNhY2nDs24gZGUgdW4gY3JpdGVyaW8gZm9ybWFsLg0KDQpFc3RlIG1pc21vIGdyw6FmaWNvIGRlIHNlZGltZW50YWNpw7NuIHBlcm1pdGUgdmlzdWFsaXphciBjb24gcHJlY2lzacOzbiBlbCBDcml0ZXJpbyBkZSBLYWlzZXIgcGFyYSBsYSBzZWxlY2Npw7NuIGRlIGNvbXBvbmVudGVzLCB1dGlsaXphbmRvIHVuYSBsw61uZWEgaG9yaXpvbnRhbCBxdWUgbWFyY2EgZWwgdW1icmFsIGRlIEF1dG92YWxvciBpZ3VhbCBhIDEuIERpY2hhIHZpc3VhbGl6YWNpw7NuIGp1c3RpZmljYSBtYXRlbcOhdGljYW1lbnRlIGVsIGNvcnRlOiBlbCBwcmltZXIgeSBlbCBzZWd1bmRvIHB1bnRvIHNlIG1hbnRpZW5lbiBzb2JyZSBkaWNobyB1bWJyYWwsIGxvIHF1ZSBpbmRpY2EgcXVlIGVzdG9zIGNvbXBvbmVudGVzIGFwb3J0YW4gbcOhcyB2YXJpYW56YSBxdWUgdW5hIHZhcmlhYmxlIGluZGl2aWR1YWwgcHJvbWVkaW8uIEEgcGFydGlyIGRlbCB0ZXJjZXIgY29tcG9uZW50ZSwgbG9zIHB1bnRvcyBjYWVuIHBvciBkZWJham8gZGUgbGEgbMOtbmVhLCBjb25maXJtYW5kbyBxdWUgZWwgbMOtbWl0ZSDDs3B0aW1vIGRlIHBhcnNpbW9uaWEgcGFyYSBlc3RlIG1vZGVsbyBlcyBkZSBkb3MgZGltZW5zaW9uZXMuIEVzdGEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGVzdHJpY3RhIHJlc3BhbGRhIGxhIGRlY2lzacOzbiBkZSByZXRlbmVyIGxvcyBkb3MgcHJpbWVyb3MgY29tcG9uZW50ZXMgcGFyYSBleHBsaWNhciBlbCAkNDNcJSQgZGUgbGEgdmFyaWFiaWxpZGFkIGNvbiB1bmEgaW50ZXJwcmV0YWNpw7NuIGNsw61uaWNhIHkgbMOzZ2ljYS4NCg0KIyMjIDIuMy4gQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KQmFzYWRvIGVuIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgW3NlY2Npw7NuIDEuMl0oI3NlYzEuMiksIHNlIHJlcXVpZXJlIGRldGVybWluYXIgbGFzIGNvbnRyaWJ1Y2lvbmVzIGRlIGNhZGEgdmFyaWFibGUgZW4gbGEgY29uc3RydWNjacOzbiBkZSBsYXMgY29tcG9uZW50ZXMuVG9tYW5kbyBlbiBsYSByZWZlcmVuY2lhIGRlIETDrWF6IE1vcmFsZXMgJiBNb3JhbGVzIFJpdmVyYSwgKDIwMTIpLHNlIGNvbmZpcm1hIHF1ZSwgdHJhcyByZWR1Y2lyIGxhIGRpbWVuc2lvbmFsaWRhZCBkZWwgY29uanVudG8gZGUgZGF0b3MgeSBlbnRlbmRlciBxdWUgc3VzIHZhcmlhYmxlcyBlc3RhbmRhcml6YWRhcyBzZSByZXByZXNlbnRhbiBncsOhZmljYW1lbnRlIGNvbW8gcHJveWVjY2lvbmVzIGRlIHVuYSBoaXBlcmVzZmVyYSBkZSBjb3JyZWxhY2lvbmVzLCBlcyBlc2VuY2lhbCBpbmljaWFyIGxhIGludGVycHJldGFjacOzbiBkZSBsYXMgY29tcG9uZW50ZXMgYSBwYXJ0aXIgZGUgZXNhcyBjb3JyZWxhY2lvbmVzLiBQb3N0ZXJpb3JtZW50ZSwgc2UgZGViZSBldmFsdWFyIGxhIGNhbGlkYWQgZGUgbGFzIHJlcHJlc2VudGFjaW9uZXMgb2J0ZW5pZGFzLCBjb25zaWRlcmFuZG8gbGEgcmVkdWNjacOzbiBkaW1lbnNpb25hbCBhcGxpY2FkYSBhbCBjb25qdW50byBkZSBkYXRvcyB5IHN1IGltcGFjdG8gZW4gbGFzIHZhcmlhYmxlcy4NCg0KUG9ybG8gYW50ZXJpb3IsIHNlIGhhY2UgbmVjZXNhcmlvIGV2YWx1YXIgbGEgY2FsaWRhZCBkZSBsYSByZXByZXNlbnRhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGVuIHJlbGFjacOzbiBjb24gZWwgbsO6bWVybyBkZSBkaW1lbnNpb25lcyBjYWxjdWxhZGFzIHF1ZSBjYXB0dXJhbiBsYSBtYXlvciBwcm9wb3JjacOzbiBkZSB2YXJpYWJpbGlkYWQ7IHBhcmEgbcOhcyBkZXRhbGxlcywgY29uc3VsdGFyIGxhIFtzZWNjacOzbiAyLjJdKCNzZWMyLjIpLiBMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBmYWNpbGl0YSBsYSB2aXN1YWxpemFjacOzbiBkZSBsYXMgY29udHJpYnVjaW9uZXMgZGUgbGFzIHZhcmlhYmxlcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZW4gZm9ybWEgZGUgcmVwcmVzZW50YWNpb25lcyBudW3DqXJpY2FzIHkgZ3LDoWZpY2FzLCBwZXJtaXRpZW5kbyBjb21wcmVuZGVyIGPDs21vIGNhZGEgdmFyaWFibGUgaW5mbHV5ZSBlbiBsYSBjb25zdHJ1Y2Npw7NuIGRlIGxhcyBjb21wb25lbnRlcy4gRXN0byBwZXJtaXRlIGFuYWxpemFyIGxhIHByb3BvcmNpw7NuIGRlIHZhcmlhYmlsaWRhZCBxdWUgY2FkYSB2YXJpYWJsZSBhcG9ydGEgYSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZGUgbGEgY29tcG9uZW50ZSBjb24gbGEgcXVlIGVzdMOhIGFzb2NpYWRhLg0KDQoNCiMjIyMgQ8OtcmN1bG8gZGUgQ29ycmVsYWNpb25lcw0KYGBge3IgQ2lyY3Vsb19kZV9Db3JyZWxhY2lvbmVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN1cHByZXNzV2FybmluZ3MoZnZpel9wY2FfdmFyKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIHNjYWxlLnVuaXQgPSBULCBncmFwaCA9IEYpLGNvbC52YXI9IiMzQjgzQkQiLCByZXBlbCA9IFQsIGNvbC5jaXJjbGUgPSAiI0NEQ0RDRCIsIGdndGhlbWUgPSB0aGVtZV9idygpKSkNCmBgYA0KDQpFbCBDw61yY3VsbyBkZSBDb3JyZWxhY2lvbmVzIHJldmVsYSBxdWUgZWwgQ29tcG9uZW50ZSAxIChEaW0xKSBzZSBkZWZpbmUgcG9yIGxhIG9wb3NpY2nDs24gZW50cmUgbGEgQWd1ZGV6YSBWaXN1YWwgKEFWX09EIHkgQVZfT0kpLCBxdWUgcHJlc2VudGEgY2FyZ2FzIG5lZ2F0aXZhcywgeSBsYXMgSG9yYXMgZGUgRWplcmNpY2lvIChIb3Jhc19wZCksIGNvbiBjYXJnYSBwb3NpdGl2YS4gTGEgY2VyY2Fuw61hIHkgb3JpZW50YWNpw7NuIHNpbWlsYXIgZGUgbG9zIHZlY3RvcmVzIGRlIGFndWRlemEgdmlzdWFsIGNvbmZpcm1hbiBsYSBhbHRhIGNvcnJlbGFjacOzbiBwb3NpdGl2YSBlbnRyZSBhbWJvcyBvam9zLCBtaWVudHJhcyBxdWUgc3UgcmVsYWNpw7NuIGludmVyc2EgY29uIGxhcyBob3JhcyBkZSBlamVyY2ljaW8gc3VnaWVyZSBxdWUsIGRlbnRybyBkZSBlc3RlIGNvbXBvbmVudGUsIGxhIGFjdGl2aWRhZCBmw61zaWNhIGVzdMOhIGFzb2NpYWRhIGEgdW5hIHBlb3IgYWd1ZGV6YSB2aXN1YWwuDQoNCkVsIENvbXBvbmVudGUgMiAoRGltMikgZXN0w6EgZnVlcnRlbWVudGUgYXNvY2lhZG8gYSBsYSB2YXJpYWJsZSBIb3JhcyBGcmVudGUgYSBQYW50YWxsYSAoSG9yYXNfYWYpLCBsbyBxdWUgaW5kaWNhIHF1ZSBlc3RhIGRpbWVuc2nDs24gcmVwcmVzZW50YSBwcmluY2lwYWxtZW50ZSBsYSB2YXJpYWJpbGlkYWQgcmVsYWNpb25hZGEgY29uIGxhIGV4cG9zaWNpw7NuIGRpZ2l0YWwuIExhIG9yaWVudGFjacOzbiBkZSBlc3RlIHZlY3RvciBlcyBjYXNpIG9ydG9nb25hbCAoOTAgZ3JhZG9zKSByZXNwZWN0byBhIGxvcyB2ZWN0b3JlcyBkZSBBZ3VkZXphIFZpc3VhbCwgbG8gcXVlIHN1Z2llcmUgdW5hIGJhamEgY29ycmVsYWNpw7NuIGxpbmVhbCBkaXJlY3RhIGVudHJlIGVsIHRpZW1wbyBmcmVudGUgYSBwYW50YWxsYXMgeSBsYSBhZ3VkZXphIHZpc3VhbCBkZW50cm8gZGUgbG9zIGRvcyBwcmltZXJvcyBjb21wb25lbnRlcy4gDQoNCkZpbmFsbWVudGUsIGxhIEVkYWQgZGVsIFBhY2llbnRlIHNlIHViaWNhIGNlcmNhbmEgYWwgb3JpZ2VuIGRlbCBwbGFubyBmYWN0b3JpYWwsIGxvIHF1ZSBzaWduaWZpY2EgcXVlIG5vIGNvbnRyaWJ1eWUgZGUgbWFuZXJhIHNpZ25pZmljYXRpdmEgYSBsYSBleHBsaWNhY2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkIGNhcHR1cmFkYS4gRW4gY29uY2x1c2nDs24sIGxhIHZhcmlhYmlsaWRhZCBkZWwgZmVuw7NtZW5vIGVzdMOhIHByaW5jaXBhbG1lbnRlIGRlZmluaWRhIHBvciBsb3MgaMOhYml0b3MgZGUgY29tcG9ydGFtaWVudG8gKGVqZXJjaWNpbyB5IHBhbnRhbGxhcykgeSBwb3IgbG9zIGluZGljYWRvcmVzIGRlIGFndWRlemEgdmlzdWFsLCBxdWVkYW5kbyBsYSBlZGFkIGNvbW8gdW4gZmFjdG9yIG5vIGRldGVybWluYW50ZSBlbiBsYSBlc3RydWN0dXJhIG11bHRpdmFyaWFkYSBhbmFsaXphZGEuDQoNCiMjIyMgTWF0cml6IGRlIFJlcHJlc2VudGFjacOzbg0KYGBge3IgTWF0cml6X2RlX1JlcHJlc3NlbnRhY2lvbl9DT1MyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCihnZXRfcGNhX3ZhcihQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBuY3AgPSA1LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkpJGNvczINCmBgYA0KDQpMYSBNYXRyaXogZGUgUmVwcmVzZW50YWNpw7NuICgkXHRleHR7Q29zfV4yJCkgIGZ1bmNpb25hIGNvbW8gdW4gY29udHJvbCBkZSBjYWxpZGFkIHBvc3QtYW7DoWxpc2lzLCBjdWFudGlmaWNhbmRvIGxhIGZpZGVsaWRhZCBjb24gbGEgcXVlIGxhIHZhcmlhbnphIGRlIGNhZGEgdmFyaWFibGUgb3JpZ2luYWwgZXN0w6Egc2llbmRvIGNhcHR1cmFkYSBwb3IgbGFzIGRpbWVuc2lvbmVzIHJldGVuaWRhcy4gUGFyYSBlc3RlIGFuw6FsaXNpcywgc29sbyBzZSBjb25zaWRlcmFuIGxhcyBkb3MgcHJpbWVyYXMgZGltZW5zaW9uZXMgKERpbS4xIHkgRGltLjIpLg0KDQoNCiMjIyMgQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24NCmBgYHtyIENhbGlkYWRfZGVfbGFfUmVwcmVzZW50YWNpb24sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9wY2FfdmFyKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjb2wudmFyPSJjb3MyIiwgZ3JhZGllbnQuY29scz1jKCIjMDBBRkJCIiwiI0U3QjgwMCIsIiNGQzRFMDciKSwgcmVwZWwgPSBUUlVFKQ0KYGBgDQoNCkVsIGFuw6FsaXNpcyBkZSBlc3RhIGdyw6FmaWNhIHJldmVsYSB0cmVzIHB1bnRvcyBpbnRlcnByZXRhdGl2b3MgY2xhdmU6RXNwZWNpYWxpemFjacOzbiBkZSBsYSBEaW1lbnNpw7NuIDIgKEZhY3RvciBEZXBvcnRpdm8pOiBMYSB2YXJpYWJsZSBIb3JhcyBkZSBBY3RpdmlkYWQgRsOtc2ljYSAoJFx0ZXh0e0hvcmFzXF9hZn0kKSBwcmVzZW50YSB1biB2YWxvciBkZSAkXHRleHR7Q29zfV4yJCBleGNlcGNpb25hbG1lbnRlIGFsdG8gZW4gbGEgRGltZW5zacOzbiAyICgkMC41NjkkKSwgZW4gY29udHJhc3RlIGNvbiBlbCB2YWxvciBjYXNpIG51bG8gZGUgbGEgRGltZW5zacOzbiAxICgkMC4wMzAkKS4gRXN0ZSBoYWxsYXpnbyBwcnVlYmEgcXVlIGxhIHNlZ3VuZGEgZGltZW5zacOzbiBlcywgZnVuY2lvbmFsbWVudGUsIHVuICdGYWN0b3IgRGVwb3J0aXZvJyBxdWUgYcOtc2xhIGRlIG1hbmVyYSBlZmljaWVudGUgbGEgdmFyaWFuemEgYXNvY2lhZGEgYWwgZWplcmNpY2lvIGbDrXNpY28uDQoNCkZvY28gZGUgbGEgRGltZW5zacOzbiAxIChDb21wb3J0YW1pZW50byBEaWdpdGFsKTogUG9yIHN1IHBhcnRlLCBsYSB2YXJpYWJsZSBIb3JhcyBkZSBQYW50YWxsYSAoJFx0ZXh0e0hvcmFzXF9wZH0kKSBvYnRpZW5lIHN1IG1lam9yIHJlcHJlc2VudGFjacOzbiBlbiBsYSBEaW1lbnNpw7NuIDEgKCQwLjMzOSQpLCBjb25maXJtYW5kbyBxdWUgZXN0ZSBlamUgcHJpbmNpcGFsIGNhcHR1cmEgZGUgbWFuZXJhIG3DoXMgZWZlY3RpdmEgZWwgY29tcG9uZW50ZSBkZSBjb21wb3J0YW1pZW50byBkaWdpdGFsLg0KDQpUcmFuc3BhcmVuY2lhIGRlbCBNb2RlbG8geSBQw6lyZGlkYSBkZSBJbmZvcm1hY2nDs24gKFB1bnRvIENyw610aWNvKTogU2UgZGViZSByZWNvbm9jZXIgcXVlIGxhIHZhcmlhYmxlIEVkYWQgZGVsIFBhY2llbnRlICgkXHRleHR7ZWRhZFxfcGFjaWVudGV9JCkgcHJlc2VudGEgc3UgbWF5b3IgY29udHJpYnVjacOzbiBkZSAkXHRleHR7Q29zfV4yJCAoJDAuNDcyJCkgZW4gbGEgRGltZW5zacOzbiAzLCBsYSBjdWFsIGZ1ZSBkZXNjYXJ0YWRhIHNlZ8O6biBlbCBDcml0ZXJpbyBkZSBLYWlzZXIuIEVzdG8gaW1wbGljYSBxdWUsIHNpIGJpZW4gZWwgbW9kZWxvIGRlIGRvcyBjb21wb25lbnRlcyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzw7NsaWRvIHkgw7p0aWwgcGFyYSBpbnRlcnByZXRhciBlbCB2w61uY3VsbyBlbnRyZSBow6FiaXRvcyB5IHZpc2nDs24sIHNlIGFjZXB0YSB1bmEgcMOpcmRpZGEgcGFyY2lhbCBkZSBpbmZvcm1hY2nDs24gcmVzcGVjdG8gYSBsYSBlZGFkIGNvbiBlbCBmaW4gZGUgcHJpb3JpemFyIGxhIHBhcnNpbW9uaWEgeSBsYSBzaW1wbGljaWRhZCBpbnRlcnByZXRhdGl2YSBkZWwgbW9kZWxvIGZpbmFsLg0KDQojIyMjIENvb3JkZW5hZGFzIEluZGl2aWR1YWxlcw0KYGBge3IgQ29vcmRlbmFkYXNfUmVnaXN0cm9zLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmhlYWQoKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKSRpbmQkY29vcmQsIG4gPSAyM0wpDQpgYGANCg0KTWVkaWFudGUgZWwgQW7DoWxpc2lzIGRlIENvbXBvbmVudGVzIFByaW5jaXBhbGVzLCBsb3MgZGF0b3Mgb3JpZ2luYWxlcyBmdWVyb24gcHJveWVjdGFkb3MgZW4gY2luY28gY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIEVzdGEgbWF0cml6IHByb3BvcmNpb25hIGxhIHViaWNhY2nDs24gZmFjdG9yaWFsIGRlIGNhZGEgaW5kaXZpZHVvIGVuIGRpY2hvIGVzcGFjaW8sIGxvIHF1ZSBwZXJtaXRlIGlkZW50aWZpY2FyIHBhdHJvbmVzIGRlIGNvbXBvcnRhbWllbnRvLCBwZXJmaWxlcyBkaWZlcmVuY2lhZG9zIHkgcG9zaWJsZXMgY2Fzb3MgYXTDrXBpY29zIGNvbiBiYXNlIGVuIHN1IHBvc2ljacOzbiByZWxhdGl2YSByZXNwZWN0byBhIGxhcyBkaW1lbnNpb25lcyBwcmluY2lwYWxlcy4NCg0KDQojIyMgMi40LiBDb250cmlidWNpb25lcyAgeSBCaXBsb3RzIA0KDQpFbCBhbsOhbGlzaXMgZGUgY29udHJpYnVjaW9uZXMgeSBsYSByZXByZXNlbnRhY2nDs24gbWVkaWFudGUgYmlwbG90cyBwZXJtaXRlbiBpbnRlcnByZXRhciBkZSBtYW5lcmEgY2xhcmEgbG9zIHJlc3VsdGFkb3MgZGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKS4gTGFzIGNvbnRyaWJ1Y2lvbmVzIG11ZXN0cmFuIGVsIHBlc28gcmVsYXRpdm8gZGUgY2FkYSB2YXJpYWJsZSB5IGRlIGNhZGEgb2JzZXJ2YWNpw7NuIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBmYWNpbGl0YW5kbyBsYSBpZGVudGlmaWNhY2nDs24gZGUgYXF1ZWxsb3MgZWxlbWVudG9zIHF1ZSBleHBsaWNhbiBlbiBtYXlvciBtZWRpZGEgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcy4NCg0KUG9yIHN1IHBhcnRlLCBsb3MgYmlwbG90cyBwcm9wb3JjaW9uYW4gdW5hIHZpc3VhbGl6YWNpw7NuIGNvbmp1bnRhIGRlIHZhcmlhYmxlcyBlIGluZGl2aWR1b3MgZW4gZWwgZXNwYWNpbyByZWR1Y2lkbywgbG8gcXVlIHBlcm1pdGUgYW5hbGl6YXIgcmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMsIHBhdHJvbmVzIGRlIGFncnVwYWNpw7NuIHkgZGlmZXJlbmNpYXMgZW50cmUgb2JzZXJ2YWNpb25lcy4gRW4gY29uanVudG8sIGVzdGFzIGhlcnJhbWllbnRhcyBjb21wbGVtZW50YW4gZWwgQUNQIGFsIG9mcmVjZXIgdW5hIGludGVycHJldGFjacOzbiBzaW50w6l0aWNhIHkgY29tcHJlbnNpYmxlIGRlIGxhIGVzdHJ1Y3R1cmEgc3VieWFjZW50ZSBkZSBsb3MgZGF0b3MuDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRWwgYW7DoWxpc2lzIGRlIGxhcyBjb250cmlidWNpb25lcyBlcyB1biBlbGVtZW50byBjZW50cmFsIGRlbCBhbsOhbGlzaXMgbXVsdGl2YXJpYW50ZSwgeWEgcXVlIHBlcm1pdGUgY3VhbnRpZmljYXIgZWwgZ3JhZG8gZGUgaW5mbHVlbmNpYSBxdWUgY2FkYSB2YXJpYWJsZSB5IGNhZGEgaW5kaXZpZHVvIGVqZXJjZW4gZW4gbGEgY29uc3RydWNjacOzbiBkZSBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIEVuIGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKSwgbGFzIGNvbnRyaWJ1Y2lvbmVzIGZhY2lsaXRhbiBsYSBpZGVudGlmaWNhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgZXhwbGljYW4gbWF5b3IgcHJvcG9yY2nDs24gZGUgbGEgdmFyaWFuemEgdG90YWwsIGFwb3J0YW5kbyBjcml0ZXJpb3Mgb2JqZXRpdm9zIHBhcmEgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGxhcyBkaW1lbnNpb25lcyByZXN1bHRhbnRlcyAoSm9sbGlmZmUgJiBDYWRpbWEsIDIwMTYpLiBBc2ltaXNtbywgZWwgZXN0dWRpbyBkZSBsYXMgY29udHJpYnVjaW9uZXMgZGUgbG9zIGluZGl2aWR1b3MgcGVybWl0ZSBkZXRlY3RhciBvYnNlcnZhY2lvbmVzIGNvbiBhbHRhIGluZmx1ZW5jaWEgc29icmUgbG9zIGVqZXMgZmFjdG9yaWFsZXMsIGxvIHF1ZSByZXN1bHRhIGZ1bmRhbWVudGFsIHBhcmEgcmVjb25vY2VyIHBhdHJvbmVzIGRvbWluYW50ZXMsIGhldGVyb2dlbmVpZGFkIGludGVybmEgeSBwb3NpYmxlcyB2YWxvcmVzIGF0w61waWNvcyBkZW50cm8gZGVsIGNvbmp1bnRvIGRlIGRhdG9zIChBYmRpICYgV2lsbGlhbXMsIDIwMTApLg0KDQojIyMjIyBNYXRyaXogZGUgQ29udHJpYnVjaW9uZXMNCmBgYHtyIE1hdHJpel9kZV9Db250cmlidWNpb25lcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQooZ2V0X3BjYV92YXIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRikpKSRjb250cmliDQpgYGANCg0KTGEgKipNYXRyaXogZGUgQ29udHJpYnVjaW9uZXMqKiBtdWVzdHJhIGPDs21vIGNhZGEgdmFyaWFibGUgY29udHJpYnV5ZSBhIGxhIHJldGVuY2nDs24gZGUgdmFyaWFiaWxpZGFkIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgY2FkYSBjb21wb25lbnRlLiBMb3MgZGlhZ3JhbWFzIGRlIGJhcnJhcywgcXVlIHNlIHZpc3VhbGl6YW4gZW4gbGFzIHBlc3Rhw7FhcyBkZXNkZSAqKkNvbnRyaWJ1Y2lvbmVzIGEgRDEqKiBoYXN0YSAqKkNvbnRyaWJ1Y2lvbmVzIGEgRDUqKiwgaWx1c3RyYW4gbGFzIGNvbnRyaWJ1Y2lvbmVzIGVzcGVjw61maWNhcyBkZSBsYXMgdmFyaWFibGVzIHBhcmEgZXhwbGljYXIgbGEgdmFyaWFiaWxpZGFkIGVuIGNhZGEgY29tcG9uZW50ZS4gQ2FkYSBncsOhZmljbyBpbmNsdXllIHVuYSBsw61uZWEgcXVlIGluZGljYSBsYSAqY29udHJpYnVjacOzbiBtZWRpYSosIGxvIHF1ZSBmYWNpbGl0YSBsYSBpZGVudGlmaWNhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgdGllbmVuIG1heW9yIGltcGFjdG8gZW4gbGEgZXhwbGljYWNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSBsb3MgY29tcG9uZW50ZXMuIA0KDQojIyMjIyBDb250cmlidWNpb25lcyBhIEQxDQpgYGB7ciBDb250cmlidWNpb25lc19ESU1fMSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NvbnRyaWIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMSwgdG9wID0gMTApDQpgYGANCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQxKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipBZ3VkZXphX3Zpc3VhbF9PSSoqIHkgKipIb3Jhc19wZCoqLHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkNTcuMDclJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgMS4NCg0KIyMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMg0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzIsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDEwKQ0KYGBgDQoNCkVuICoqQ29udHJpYnVjaW9uZXMgYSBEMioqIHNlIHZpc3VhbGl6YSBxdWUgbGFzIHZhcmlhYmxlcyBwb3IgZW5jaW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqSG9yYXNfYWYqKiB5ICoqQWd1ZGV6YV92aXN1YWxfT0QqKiByZXRpZW5lbiBhcHJveGltYWRhbWVudGUgZWwgJDgyLjIyJSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb21wb25lbnRlIDIuDQoNCiMjIyMjIENvbnRyaWJ1Y2lvbmVzIGEgRDMNCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0RJTV8zLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfY29udHJpYihQQ0EoY2NkX3Zpc2lvbjIwMjBfRVRMWywtYygxLDMsNCw1LDYsNywxMiwxMyldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAzLCB0b3AgPSAxMCkNCmBgYA0KDQpFbiAqKkNvbnRyaWJ1Y2lvbmVzIGEgRDMqKiBzZSB2aXN1YWxpemEgcXVlIGxhcyB2YXJpYWJsZXMgcG9yIGVuY2ltYSBkZSBsYSBjb250cmlidWNpw7NuIG1lZGlhOiAqKkVkYWRfcGFjaWVudGUqKiB5ICoqQWd1ZGV6YV92aXN1YWxfT0kqKiByZXRpZW5lbiBhcHJveGltYWRhbWVudGUgZWwgJDY3LjU2JSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb21wb25lbnRlIDMuIA0KDQojIyMjIyBDb250cmlidWNpb25lcyBhIEQ0DQpgYGB7ciBDb250cmlidWNpb25lc19ESU1fNCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NvbnRyaWIoUENBKGNjZF92aXNpb24yMDIwX0VUTFssLWMoMSwzLDQsNSw2LDcsMTIsMTMpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNCwgdG9wID0gMTApDQpgYGANCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ0Kiogc2UgdmlzdWFsaXphIHF1ZSBsYSB2YXJpYWJsZSBwb3IgZW5jaW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqQWd1ZGV6YV92aXN1YWxfT0QqKiByZXRpZW5lIGFwcm94aW1hZGFtZW50ZSBlbCAkMjkuNTklJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNC4NCg0KIyMjIyMgQ29udHJpYnVjaW9uZXMgYSBENQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShjY2RfdmlzaW9uMjAyMF9FVExbLC1jKDEsMyw0LDUsNiw3LDEyLDEzKV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDEwKQ0KYGBgDQoNCkVuICoqQ29udHJpYnVjaW9uZXMgYSBENSoqIHNlIHZpc3VhbGl6YSBxdWUgbGFzIHZhcmlhYmxlcyBwb3IgZW5jaW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqSG9yYXNfcGQqKiB5ICoqQWd1ZGV6YV92aXN1YWxfT0kqKiByZXRpZW5lbiBhcHJveGltYWRhbWVudGUgZWwgJDYwLjk3JSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb21wb25lbnRlIDUuDQoNCiMjIyMgIEJpcGxvdHMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KTG9zIGJpcGxvdHMgY29uc3RpdHV5ZW4gdW5hIGhlcnJhbWllbnRhIGdyw6FmaWNhIGNsYXZlIGVuIGVsIGFuw6FsaXNpcyBtdWx0aXZhcmlhbnRlLCBhbCBwZXJtaXRpciBsYSByZXByZXNlbnRhY2nDs24gc2ltdWx0w6FuZWEgZGUgdmFyaWFibGVzIGUgaW5kaXZpZHVvcyBlbiB1biBlc3BhY2lvIHJlZHVjaWRvIGRlZmluaWRvIHBvciBsb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuIEVzdGEgdMOpY25pY2EgZmFjaWxpdGEgZWwgYW7DoWxpc2lzIGRlIHJlbGFjaW9uZXMgZGUgY29ycmVsYWNpw7NuLCBvcG9zaWNpw7NuIG8gaW5kZXBlbmRlbmNpYSBlbnRyZSB2YXJpYWJsZXMsIGFzw60gY29tbyBsYSBpZGVudGlmaWNhY2nDs24gZGUgYWdydXBhbWllbnRvcyB5IHRlbmRlbmNpYXMgZW50cmUgbGFzIG9ic2VydmFjaW9uZXMgKEdhYnJpZWwsIDE5NzEpLiBFbiBlbCBjb250ZXh0byBkZWwgQUNQLCBsb3MgYmlwbG90cyBwZXJtaXRlbiBpbnRlZ3JhciBkZSBmb3JtYSB2aXN1YWwgbGEgaW5mb3JtYWNpw7NuIGNvbnRlbmlkYSBlbiBsYXMgY29udHJpYnVjaW9uZXMgeSBjYXJnYXMgZmFjdG9yaWFsZXMsIGZhdm9yZWNpZW5kbyB1bmEgaW50ZXJwcmV0YWNpw7NuIGdsb2JhbCB5IGNvaGVyZW50ZSBkZSBsYSBlc3RydWN0dXJhIHN1YnlhY2VudGUgZGUgbG9zIGRhdG9zIGFuYWxpemFkb3MgKEdyZWVuYWNyZSwgMjAxMCkuDQoNCiMjIyMjIEJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgW2ZpbHRybzpQYWNfc2V4b10NCmBgYHtyIEJpcGxvdF9WYXJpYWJsZXNfUmVnaXN0cm9zX0ZpbHRyb19QYWNfc2V4b30NCmNjZF92aXNpb24yMDIwX0VUTCA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9KT1NFL0Rlc2t0b3AvZ2RkL1RSQUJBSk8gR0REL2NjZF92aXNpb24yMDIwX0VUTC54bHN4IikNCg0KbXVlc3RyYV9wcyA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDIwMCksDQpjKCJlZGFkX3BhY2llbnRlIiwiQVZfT0QiLCJBVl9PSSIsIkhvcmFzX3BkIiwiSG9yYXNfYWYiLCJwYWNfc2V4byIpDQpdDQoNCnJlc19wY2EgPC0gUENBKA0KbXVlc3RyYV9wc1ssIGMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIpXSwNCm5jcCA9IDUsc2NhbGUudW5pdCA9IFRSVUUsZ3JhcGggPSBGQUxTRSkNCg0KZnZpel9wY2FfYmlwbG90KHJlc19wY2EsYXhlcyA9IGMoMSwgMikscmVwZWwgPSBUUlVFLGhhYmlsbGFnZSA9IGFzLmZhY3RvcihtdWVzdHJhX3BzJHBhY19zZXhvKSkNCmBgYA0KDQpFbCBiaXBsb3QgZGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoUENBKSBtdWVzdHJhIHF1ZSBsYXMgZG9zIHByaW1lcmFzIGRpbWVuc2lvbmVzIGV4cGxpY2FuIGNvbmp1bnRhbWVudGUgZWwgNDYuMyUgZGUgbGEgdmFyaWFuemEgdG90YWwgZGUgbG9zIGRhdG9zIChEaW0xOiAyMy40JSwgRGltMjogMjIuOSUpLiBMYSBlc3RydWN0dXJhIHByaW5jaXBhbCBkZSBsb3MgZGF0b3MgZXN0w6EgZG9taW5hZGEgcG9yIGxhcyB2YXJpYWJsZXMgZGUgQWd1ZGV6YSBWaXN1YWwgeSBIb3JhcyBkZSBBY3RpdmlkYWQuIEV4aXN0ZSB1bmEgZnVlcnRlIGNvcnJlbGFjacOzbiBwb3NpdGl2YSBlbnRyZSBsYSBBZ3VkZXphIFZpc3VhbCBkZSBhbWJvcyBvam9zIChBVl9PSSB5IEFWX09EKSwgY3V5b3MgdmVjdG9yZXMgc2Ugc3VwZXJwb25lbiB5IGRlZmluZW4gZWwgbGFkbyBwb3NpdGl2byBkZSBsYSBEaW1lbnNpw7NuIDEuIFRhbWJpw6luIHNlIG9ic2VydmEgdW5hIGNvcnJlbGFjacOzbiBuZWdhdGl2YSBzaWduaWZpY2F0aXZhIGVudHJlIGxhcyBIb3JhcyBkZSBBY3RpdmlkYWQgRsOtc2ljYSAoSG9yYXNfYWYpIHkgbGFzIEhvcmFzIGVuIFBvc3R1cmFzIEluY8OzbW9kYXMgKEhvcmFzX3BkKSwgbGFzIGN1YWxlcyBkZWZpbmVuIGxhcyBkaXJlY2Npb25lcyBvcHVlc3RhcyBlbiBlbCBwbGFuby4gTGEgRWRhZCBkZWwgUGFjaWVudGUgKGVkYWRfcGFjaWVudGUpIHRpZW5lIHVuYSBpbmZsdWVuY2lhIG11eSBiYWphIGVuIGVzdGEgZXN0cnVjdHVyYSBiaWRpbWVuc2lvbmFsLCBtaWVudHJhcyBxdWUgbGEgbXVlc3RyYSBlc3TDoSBwb2xhcml6YWRhIGEgbG8gbGFyZ28gZGUgdW4gZWplIHF1ZSB2YSBkZXNkZSBwYWNpZW50ZXMgY29uIGFsdGEgQWd1ZGV6YSBWaXN1YWwgeSBiYWphIEhvcmFzX3BkIChleHRyZW1vIGRlcmVjaG8pIGhhc3RhIGFxdWVsbG9zIGNvbiBiYWphIEFndWRlemEgVmlzdWFsIHkgYWx0YSBIb3Jhc19wZCAoZXh0cmVtbyBpenF1aWVyZG8pLg0KDQpFbiBjdWFudG8gYSBsYSBkaXN0cmlidWNpw7NuIGRlIGxhcyBvYnNlcnZhY2lvbmVzIHBvciBncnVwb3MsIGxvcyBwdW50b3MgcXVlIHJlcHJlc2VudGFuIGEgbG9zIHBhY2llbnRlcyBGZW1lbmlub3MgeSBNYXNjdWxpbm9zIGVzdMOhbiBhbHRhbWVudGUgZW50cmVtZXpjbGFkb3MgYSBsbyBsYXJnbyBkZSB0b2RvIGVsIHBsYW5vIGRlIGNvbXBvbmVudGVzLiBFc3RvIGluZGljYSBxdWUgZWwgU2V4byBkZWwgcGFjaWVudGUgbm8gZXMgdW4gZmFjdG9yIGRldGVybWluYW50ZSBvIGRpc2NyaW1pbmFudGUgY2xhdmUgcGFyYSBleHBsaWNhciBsYSB2YXJpYWJpbGlkYWQgb2JzZXJ2YWRhIGVuIGxhcyBBZ3VkZXphcyBWaXN1YWxlcywgSG9yYXMgZGUgQWN0aXZpZGFkIEbDrXNpY2EgbyBIb3JhcyBlbiBQb3N0dXJhcyBJbmPDs21vZGFzIGVuIGVzdGEgbXVlc3RyYSBlc3BlY8OtZmljYS4gUG9yIGxvIHRhbnRvLCBlbCBmb2NvIGRlIGxhIHZhcmlhYmlsaWRhZCByZWNhZSBwcmluY2lwYWxtZW50ZSBlbiBsYSByZWxhY2nDs24gaW52ZXJzYSBlbnRyZSBsYXMgdmFyaWFibGVzIGRlIHNhbHVkIHZpc3VhbCB5IGxvcyBow6FiaXRvcyBwb3N0dXJhbGVzL2FjdGl2aWRhZCBmw61zaWNhLg0KDQojIyMjIyBCaXBsb3QgZGUgVmFyaWFibGVzIHkgUmVnaXN0cm9zIFtmaWx0cm86UmFuZ28gRXRhcmVvXQ0KYGBge3IgQmlwbG90X1ZhcmlhYmxlc19SZWdpc3Ryb3NfRmlsdHJvX1JhbmdvX0V0YXJlb30NCmxpYnJhcnkoRmFjdG9NaW5lUikNCmxpYnJhcnkoZmFjdG9leHRyYSkNCmxpYnJhcnkocmVhZHhsKQ0KDQpjY2RfdmlzaW9uMjAyMF9FVEwgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvSk9TRS9EZXNrdG9wL2dkZC9UUkFCQUpPIEdERC9jY2RfdmlzaW9uMjAyMF9FVEwueGxzeCIpDQoNCnNldC5zZWVkKDc4MDcyOSkNCg0KbXVlc3RyYV9yZSA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDIwMCksDQpjKCJlZGFkX3BhY2llbnRlIiwiQVZfT0QiLCJBVl9PSSIsIkhvcmFzX3BkIiwiSG9yYXNfYWYiLCJyYW5nb19ldGFyZW8iKQ0KXQ0KDQptdWVzdHJhX3JlJHJhbmdvX2V0YXJlbyA8LSBmYWN0b3IobXVlc3RyYV9yZSRyYW5nb19ldGFyZW8pDQoNCnJlc19wY2FfcmUgPC0gUENBKA0KbXVlc3RyYV9yZVssIGMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIpXSwNCm5jcCA9IDUsDQpzY2FsZS51bml0ID0gVFJVRSwNCmdyYXBoID0gRkFMU0UNCikNCg0KZnZpel9wY2FfYmlwbG90KA0KcmVzX3BjYV9yZSwNCmF4ZXMgPSBjKDEsIDIpLA0KcmVwZWwgPSBUUlVFLA0KaGFiaWxsYWdlID0gbXVlc3RyYV9yZSRyYW5nb19ldGFyZW8NCikNCmBgYA0KDQpFbCBiaXBsb3QgZGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyBtdWVzdHJhIGxhIHByb3llY2Npw7NuIGRlIGxhcyB2YXJpYWJsZXMgeSBsb3MgaW5kaXZpZHVvcyBlbiBlbCBwbGFubyBkZWZpbmlkbyBwb3IgRGltLjEgKDIzLDMlKSB5IERpbS4yICgyMiwyJSksIHF1ZSBleHBsaWNhbiBjb25qdW50YW1lbnRlIGVsIDQ1LDUlIGRlIGxhIHZhcmlhYmlsaWRhZCB0b3RhbC4gRXN0ZSBuaXZlbCBkZSBleHBsaWNhY2nDs24gcGVybWl0ZSBpZGVudGlmaWNhciBwYXRyb25lcyBnZW5lcmFsZXMgZW4gbGEgZXN0cnVjdHVyYSBkZSBsb3MgZGF0b3MuDQoNCkxhIERpbWVuc2nDs24gMSBlc3TDoSBwcmluY2lwYWxtZW50ZSBhc29jaWFkYSBjb24gbGFzIHZhcmlhYmxlcyBkZSBow6FiaXRvcyAoSG9yYXNfcGQgeSBIb3Jhc19hZiksIG1pZW50cmFzIHF1ZSBsYXMgdmFyaWFibGVzIGRlIGFndWRlemEgdmlzdWFsIChBVl9PRCB5IEFWX09JKSBzZSBwcm95ZWN0YW4gZW4gc2VudGlkbyBvcHVlc3RvLCBsbyBxdWUgc3VnaWVyZSB1bmEgcmVsYWNpw7NuIGludmVyc2EgZW50cmUgYW1iYXMuIExhIERpbWVuc2nDs24gMiBjYXB0dXJhIHZhcmlhY2lvbmVzIGFkaWNpb25hbGVzIHJlbGFjaW9uYWRhcyBjb24gbGEgZWRhZCB5IGRpZmVyZW5jaWFzIG3DoXMgc3V0aWxlcyBlbiBsYSBjb25kaWNpw7NuIHZpc3VhbC4NCg0KRW4gY3VhbnRvIGEgbG9zIHJhbmdvcyBldGFyaW9zLCBzZSBvYnNlcnZhIHVuYSBhbHRhIHN1cGVycG9zaWNpw7NuIGVudHJlIGxvcyBncnVwb3MsIGxvIHF1ZSBpbmRpY2EgYXVzZW5jaWEgZGUgdW5hIHNlcGFyYWNpw7NuIGNsYXJhLiBObyBvYnN0YW50ZSwgc2UgaWRlbnRpZmljYW4gdGVuZGVuY2lhcyBnZW5lcmFsZXMgcXVlIHN1Z2llcmVuIHVuYSBtYXlvciBkaXNwZXJzacOzbiBlbiBsb3MgZ3J1cG9zIGRlIG1heW9yIGVkYWQuIEVuIGNvbmp1bnRvLCBlbCBiaXBsb3QgZXZpZGVuY2lhIHF1ZSBsYSB2YXJpYWJpbGlkYWQgZGVsIHNpc3RlbWEgZXN0w6EgZGV0ZXJtaW5hZGEgcG9yIGxhIGludGVyYWNjacOzbiBlbnRyZSBhZ3VkZXphIHZpc3VhbCwgaMOhYml0b3MgeSBlZGFkLCBtw6FzIHF1ZSBwb3IgZGlmZXJlbmNpYXMgY2F0ZWfDs3JpY2FzIGVzdHJpY3RhcyBlbnRyZSBsb3MgZ3J1cG9zLg0KDQojIyMjIyBCaXBsb3QgZGUgVmFyaWFibGVzIHkgUmVnaXN0cm9zIFtmaWx0cm86SG9iYnlfcHBhbnRhbGxhXQ0KYGBge3IgQmlwbG90X1ZhcmlhYmxlc19SZWdpc3Ryb3NfRmlsdHJvX0hvYmJ5X3BwYW50YWxsYX0NCg0Kc2V0LnNlZWQoNzgwNzI5KQ0KDQptdWVzdHJhX2hiIDwtIGNjZF92aXNpb24yMDIwX0VUTFsNCnNhbXBsZSgxOm5yb3coY2NkX3Zpc2lvbjIwMjBfRVRMKSwgMjUwKSwNCmMoImVkYWRfcGFjaWVudGUiLCJBVl9PRCIsIkFWX09JIiwiSG9yYXNfcGQiLCJIb3Jhc19hZiIsIkhvYmJ5X3BwYW50YWxsYSIpDQpdDQoNCm11ZXN0cmFfaGIkSG9iYnlfcHBhbnRhbGxhIDwtIGZhY3RvcigNCm11ZXN0cmFfaGIkSG9iYnlfcHBhbnRhbGxhLA0KbGV2ZWxzID0gYygibm8iLCJzaSIpICMgYWp1c3RhIHNlZ8O6biBjb2RpZmljYWNpw7NuIHJlYWwNCikNCg0KcmVzX3BjYV9oYiA8LSBQQ0EoDQptdWVzdHJhX2hiWywgYygiZWRhZF9wYWNpZW50ZSIsIkFWX09EIiwiQVZfT0kiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIildLA0KbmNwID0gNSwNCnNjYWxlLnVuaXQgPSBUUlVFLA0KZ3JhcGggPSBGQUxTRQ0KKQ0KDQpmdml6X3BjYV9iaXBsb3QoDQpyZXNfcGNhX2hiLA0KYXhlcyA9IGMoMSwgMiksDQpyZXBlbCA9IFRSVUUsDQpoYWJpbGxhZ2UgPSBtdWVzdHJhX2hiJEhvYmJ5X3BwYW50YWxsYQ0KKQ0KYGBgDQpFbCBiaXBsb3QgZGVsIEFDUCBtdWVzdHJhIHF1ZSBsYXMgZG9zIHByaW1lcmFzIGRpbWVuc2lvbmVzIChEaW0uMTogMjIsOSUgeSBEaW0uMjogMjIsMSUpIGV4cGxpY2FuIGFwcm94aW1hZGFtZW50ZSBlbCA0NSUgZGUgbGEgdmFyaWFiaWxpZGFkIHRvdGFsLiBMYSBEaW1lbnNpw7NuIDEgc2UgYXNvY2lhIHByaW5jaXBhbG1lbnRlIGNvbiBsYXMgdmFyaWFibGVzIGRlIHVzbyBkZSBwYW50YWxsYSAoSG9yYXNfcGQpLCBtaWVudHJhcyBxdWUgbGFzIHZhcmlhYmxlcyBkZSBhZ3VkZXphIHZpc3VhbCAoQVZfT0QgeSBBVl9PSSkgc2UgcHJveWVjdGFuIGVuIHNlbnRpZG8gb3B1ZXN0bywgc3VnaXJpZW5kbyB1bmEgcmVsYWNpw7NuIGludmVyc2EuDQoNClJlc3BlY3RvIGFsIGhvYmJ5IGNvbiB1c28gZGUgcGFudGFsbGEsIHNlIG9ic2VydmEgdW5hIG1hcmNhZGEgc3VwZXJwb3NpY2nDs24gZW50cmUgbG9zIGdydXBvcyBzw60geSBubywgbG8gcXVlIGluZGljYSBxdWUgZXN0YSBjb25kaWNpw7NuIG5vIGdlbmVyYSB1bmEgc2VwYXJhY2nDs24gY2xhcmEgZW4gZWwgZXNwYWNpbyBmYWN0b3JpYWwuIEVuIGNvbmp1bnRvLCBlbCBiaXBsb3Qgc3VnaWVyZSBxdWUgZWwgdXNvIGRlIHBhbnRhbGxhcyBjb21vIGhvYmJ5IGFwb3J0YSB2YXJpYWJpbGlkYWQsIHBlcm8gbm8gY29uc3RpdHV5ZSB1biBmYWN0b3IgZGlmZXJlbmNpYWRvciBkZXRlcm1pbmFudGUgZW4gbGEgZXN0cnVjdHVyYSBtdWx0aXZhcmlhbnRlIGRlbCBjb25qdW50byBkZSBkYXRvcy4NCg0KIyMjIyMgQ29vcmRlbmFkYXMgSW5kaXZpZHVhbGVzIFtmaWx0cm86UGFjX3NleG9dDQoNCmBgYHtyIEJpcGxvdF9Db29yZGVuYWRhc19JbmRpdnVkdWFsZXNfRmlsdHJvX1BhY19zZXhvfQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KbGlicmFyeShmYWN0b2V4dHJhKQ0KDQpzZXQuc2VlZCg3ODA3MjkpDQptdWVzdHJhX3NleG8gPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0KICBzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDQ3KSwNCiAgYygiZWRhZF9wYWNpZW50ZSIsIkFWX09EIiwiQVZfT0kiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIiwicGFjX3NleG8iKV0NCg0KbXVlc3RyYV9zZXhvJHBhY19zZXhvIDwtIGZhY3RvcihtdWVzdHJhX3NleG8kcGFjX3NleG8pDQoNCnJlc19wY2Ffc2V4byA8LSBQQ0EobXVlc3RyYV9zZXhvLHF1YWxpLnN1cCA9IDYsIG5jcCA9IDQsc2NhbGUudW5pdCA9IFRSVUUsZ3JhcGggPSBGQUxTRSkNCmhlYWQocmVzX3BjYV9zZXhvJGluZCRjb29yZCwgbiA9IDQ3KQ0KDQpgYGANCg0KRWwgZ3LDoWZpY28gZGUgY29vcmRlbmFkYXMgaW5kaXZpZHVhbGVzIG11ZXN0cmEgbGEgcHJveWVjY2nDs24gZGUgbG9zIHBhY2llbnRlcyBlbiBlbCBwbGFubyBEaW0uMSAoMjMuNCUpIHkgRGltLjIgKDIyLjklKS4gDQoNCkxvcyBwYWNpZW50ZXMgY29uICoqQmFqYSBBZ3VkZXphIFZpc3VhbCBPRCoqIChyb2pvKSBzZSBjb25jZW50cmFuIGVuIGVsIGV4dHJlbW8gbmVnYXRpdm8gZGUgRGltLjEsIGNlcmNhIGRlICoqYWx0YSBIb3Jhc19wZCoqLCBtaWVudHJhcyBsb3MgZGUgKipBZ3VkZXphIE5vcm1hbCoqICh2ZXJkZSkgc2UgZGlzdHJpYnV5ZW4gaGFjaWEgZWwgZXh0cmVtbyBwb3NpdGl2byBjb24gKiptZWpvciBBVl9PRC9BVl9PSSoqLg0KDQpFc3RhIHNlcGFyYWNpw7NuIGNvbmZpcm1hIGxhICoqcmVsYWNpw7NuIGludmVyc2EqKiBlbnRyZSBob3JhcyBkZSBwYW50YWxsYSB5IGFndWRlemEgdmlzdWFsIGEgbml2ZWwgaW5kaXZpZHVhbC4NCg0KIyMgKipGYXNlIDMgW0NvcnJlc3BvbmRlbmNpYXNdKioNCg0KIyMjIDMuMS4gT2JqZXRpdm9zDQoNCkVuIGVzdGEgdGVyY2VyYSBmYXNlIGRlbCBlc3R1ZGlvLCBzZSBwcmVzZW50YXLDoW4gY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzIGJhc2FkYXMgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgdHJhYmFqYWRvIGVuIGxhIFtmYXNlIDFdKCNzZWMxKSB5IFtmYXNlIDJdKCNzZWMyKS4gU2luIGVtYmFyZ28sIGVzdGEgZmFzZSBzZSBlbmZvY2Fyw6EgZW4gYXBsaWNhciBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBzaW1wbGVzIHkgbcO6bHRpcGxlcyBzb2JyZSBsYXMgdmFyaWFibGVzIGN1YWxpdGF0aXZhcywgYWJhcmNhbmRvIGxhIGNvbnN0cnVjY2nDs24gZGUgdGFibGFzIGRlIGNvbnRpbmdlbmNpYSB5IGRpc3l1bnRpdmFzIGNvbXBsZXRhcywgYXPDrSBjb21vIGxhIGV2YWx1YWNpw7NuIGRlIGNhbGlkYWRlcyBkZSByZXByZXNlbnRhY2nDs24sIGNvbnRyaWJ1Y2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcy4NCg0KIyMjIDMuMi4gQ29ycmVzcG9uZGVuY2lhcyBTaW1wbGVzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNClNlZ8O6biBbQEFNQVJBbGRhcy1VcmllbDJlZF0sZWwgKiphbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyoqIHNpbXBsZSAqKihBQ1MpKiogdGllbmUgY29tbyBwcm9ww7NzaXRvIHJlZHVjaXIgbGEgZGltZW5zaW9uYWxpZGFkIGRlIGxhcyByZWxhY2lvbmVzIGVudHJlIGNhdGVnb3LDrWFzIGRlIGRvcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLCByZXByZXNlbnTDoW5kb2xhcyBlbiB1biBlc3BhY2lvIG11bHRpZGltZW5zaW9uYWwuIEVzdGUgbcOpdG9kbyBwZXJtaXRlIGFuYWxpemFyIGdyw6FmaWNhbWVudGUgbGFzIGRpc3RhbmNpYXMgZW50cmUgbGFzIGNhdGVnb3LDrWFzIGRlIGxhcyB2YXJpYWJsZXMsIGZhY2lsaXRhbmRvIGxhIGludGVycHJldGFjacOzbiBkZSB0YWJsYXMgZGUgY29udGluZ2VuY2lhLiBFbCBuw7ptZXJvIG3DoXhpbW8gZGUgZGltZW5zaW9uZXMgbmVjZXNhcmlhcyBwYXJhIGV4cGxpY2FyIGRpY2hhcyByZWxhY2lvbmVzIGNvcnJlc3BvbmRlIGEgdW5vIG1lbm9zIGVsIG7Dum1lcm8gZGUgY2F0ZWdvcsOtYXMgZGUgbGEgdmFyaWFibGUgY29uIG1lbm9yIGNhbnRpZGFkIGRlIG5pdmVsZXMuDQoNCkFzaW1pc21vLCBlbCAqKkFDUyoqLCBiYXNhZG8gZW4gdGFibGFzIGRlIGNvbnRpbmdlbmNpYSwgcHVlZGUgYW1wbGlhcnNlIHBhcmEgaW5jbHVpciBtw6FzIGRlIGRvcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLCBsbyBxdWUgc2UgY29ub2NlIGNvbW8gKipBbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBtw7psdGlwbGVzIChBQ00pKiouIEVzdGUgZW5mb3F1ZSB1dGlsaXphIHVuYSB0YWJsYSBkaXN5dW50aXZhIGNvbXBsZXRhLCBwZXJtaXRpZW5kbyBleHBsb3JhciB5IHJlcHJlc2VudGFyIHJlbGFjaW9uZXMgbcOhcyBjb21wbGVqYXMgZW50cmUgbcO6bHRpcGxlcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLg0KDQojIyMjIEFDIFBhcmVqYXMgVG90YWxlcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBDb250aW5nZW5jaWFzIA0KYGBge3IgVGFibGFzX2RlX0NvbnRpbmdlbmNpYSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQphZGRtYXJnaW5zKHRhYmxlKGNjZF92aXNpb24yMDIwX0VUTCRyYW5nb19ldGFyZW8sDQogICAgICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpKQ0KDQphZGRtYXJnaW5zKHRhYmxlKGNjZF92aXNpb24yMDIwX0VUTCRwYWNfc2V4bywNCiAgICAgICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbykpDQoNCmFkZG1hcmdpbnModGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHBhY19zZXhvLA0KICAgICAgICAgICAgICAgICBjY2RfdmlzaW9uMjAyMF9FVEwkSG9iYnlfcHBhbnRhbGxhKSkNCmBgYA0KDQpMb3MgcmVzdWx0YWRvcyBtdWVzdHJhbiBxdWUgZWwgcmFuZ28gZXRhcmlvIGVzIGxhIHZhcmlhYmxlIHF1ZSBtw6FzIGluZmx1eWUgZW4gbG9zIGjDoWJpdG9zIHZpc3VhbGVzLCB5YSBxdWUgasOzdmVuZXMgeSBhZHVsdG9zIHRpZW5kZW4gYSByZWFsaXphciBtw6FzIGFjdGl2aWRhZGVzIHJlbGFjaW9uYWRhcyBjb24gZWwgdXNvIGRlIHBhbnRhbGxhcywgbWllbnRyYXMgcXVlIGxvcyBhZHVsdG9zIG1heW9yZXMgcHJlZmllcmVuIGFjdGl2aWRhZGVzIHNpbiBwYW50YWxsYS4gRW4gY2FtYmlvLCBlbCBzZXhvIG5vIHByZXNlbnRhIGRpZmVyZW5jaWFzIHNpZ25pZmljYXRpdmFzLCBwdWVzIGhvbWJyZXMgeSBtdWplcmVzIG11ZXN0cmFuIGNvbXBvcnRhbWllbnRvcyBzaW1pbGFyZXMuIEVuIGNvbmp1bnRvLCBlbCBhbsOhbGlzaXMgcGVybWl0ZSBlbnRlbmRlciBjw7NtbyBsYSBlZGFkIGV4cGxpY2EgbWVqb3IgbGFzIHZhcmlhY2lvbmVzIGVuIGVsIHVzbyBkZSBwYW50YWxsYXMgeSBzdSByZWxhY2nDs24gY29uIGxhIGFndWRlemEgdmlzdWFsLg0KDQojIyMjIyBQcm9iYWJpbGlkYWRlcw0KYGBge3IgVGFibGFzX2RlX1Byb2JhYmlsaWRhZGVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmFkZG1hcmdpbnMocHJvcC50YWJsZSgNCiAgdGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbywNCiAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJEhvYmJ5X3BwYW50YWxsYSkpICogMTAwKQ0KDQphZGRtYXJnaW5zKHByb3AudGFibGUoDQogIHRhYmxlKGNjZF92aXNpb24yMDIwX0VUTCRwYWNfc2V4bywNCiAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbykpICogMTAwKQ0KDQphZGRtYXJnaW5zKHByb3AudGFibGUoDQogIHRhYmxlKGNjZF92aXNpb24yMDIwX0VUTCRwYWNfc2V4bywNCiAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJEhvYmJ5X3BwYW50YWxsYSkpICogMTAwKQ0KYGBgDQoNCkVzdGEgcGFyZWphIG1vc3Ryw7MgbGEgYXNvY2lhY2nDs24gbcOhcyBmdWVydGUuIExvcyBwYWNpZW50ZXMgasOzdmVuZXMgY29uY2VudHJhbiBlbCBtYXlvciB1c28gZGUgcGFudGFsbGFzIGVuIHN1cyBob2JiaWVzIChhcHJveC4gJDIxXCUkIGRlbCB0b3RhbCksIG1pZW50cmFzIHF1ZSBsb3MgYWR1bHRvcyBtYXlvcmVzIHByZWRvbWluYW4gZW4gaG9iYmllcyBzaW4gcGFudGFsbGEuIEVzdGEgcmVsYWNpw7NuIGNsYXJhIHN1Z2llcmUgdW5hIGRlcGVuZGVuY2lhIHNpZ25pZmljYXRpdmEgZW50cmUgbGEgZWRhZCB5IGVsIHRpcG8gZGUgcGFzYXRpZW1wby5Qb3Igb3RyYSBwYXJ0ZSwgbGEgZGlzdHJpYnVjacOzbiBwb3Igc2V4byByZXN1bHTDsyBzZXIgbXV5IGVxdWlsaWJyYWRhIGVuIHRvZG9zIGxvcyBncnVwb3MgZGUgZWRhZC4gRXN0byBpbmRpY2EgdW5hIGFzb2NpYWNpw7NuIGTDqWJpbCBvIHByw6FjdGljYW1lbnRlIG51bGEgZW50cmUgZWwgc2V4byBkZWwgcGFjaWVudGUgeSBzdSByYW5nbyBldGFyaW8uDQoNCkFkaWNpb25hbG1lbnRlLCBzZSBvYnNlcnbDsyB1bmEgYXNvY2lhY2nDs24gZMOpYmlsIGEgbW9kZXJhZGEuIEF1bnF1ZSBsYXMgbXVqZXJlcyB0aWVuZW4gdW4gcG9yY2VudGFqZSBsaWdlcmFtZW50ZSBtYXlvciBkZSBob2JiaWVzIGNvbiBwYW50YWxsYSAoYXByb3guICQzM1wlJCB2cy4gJDE3XCUkIGVuIGhvbWJyZXMpLCBlc3RhIGRpZmVyZW5jaWEgZXMgbWVub3IgcXVlIGxhIGluZmx1ZW5jaWFkYSBwb3IgbGEgZWRhZC4NCg0KIyMjIyMgRnJlY3VlbmNpYXMgW0NQRiB5IENQQ10NCmBgYHtyIFRhYmxhc19kZV9GcmVjdWVuY2lhc19Db25kaWNpb25hZGFzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCiMgcmFuZ29fZXRhcmVvIHZzIEhvYmJ5X3ByaW5jaXBhbF9wYW50YWxsYQ0Kcm91bmQoYWRkbWFyZ2lucygNCiAgcHJvcC50YWJsZSh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvLA0KICAgICAgICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpLCAxKSAqIDEwMCwgMiksIDIpDQoNCnJvdW5kKGFkZG1hcmdpbnMoDQogIHByb3AudGFibGUodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbywNCiAgICAgICAgICAgICAgICAgICBjY2RfdmlzaW9uMjAyMF9FVEwkSG9iYnlfcHBhbnRhbGxhKSwgMikgKiAxMDAsIDEpLCAyKQ0KDQojIHBhY19zZXhvIHZzIHJhbmdvX2V0YXJlbw0Kcm91bmQoYWRkbWFyZ2lucygNCiAgcHJvcC50YWJsZSh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcGFjX3NleG8sDQogICAgICAgICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbyksIDEpICogMTAwLCAyKSwgMikNCg0Kcm91bmQoYWRkbWFyZ2lucygNCiAgcHJvcC50YWJsZSh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcGFjX3NleG8sDQogICAgICAgICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbyksIDIpICogMTAwLCAxKSwgMikNCg0KIyBwYWNfc2V4byB2cyBIb2JieV9wcmluY2lwYWxfcGFudGFsbGENCnJvdW5kKGFkZG1hcmdpbnMoDQogIHByb3AudGFibGUodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHBhY19zZXhvLA0KICAgICAgICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpLCAxKSAqIDEwMCwgMiksIDIpDQoNCnJvdW5kKGFkZG1hcmdpbnMoDQogIHByb3AudGFibGUodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHBhY19zZXhvLA0KICAgICAgICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpLCAyKSAqIDEwMCwgMSksIDIpDQpgYGANCg0KTGEgdGFibGEgcHJlc2VudGFkYSBjb3JyZXNwb25kZSBhIGxvcyByZXN1bHRhZG9zIGludGVybWVkaW9zIGNsYXZlIGRlbCBBbsOhbGlzaXMgZGUgQ29ycmVzcG9uZGVuY2lhcyBTaW1wbGVzIChBQ1MpLCBjb25zdHJ1aWRvcyBhIHBhcnRpciBkZSBsYXMgdGFibGFzIGRlIGNvbnRpbmdlbmNpYSBkZSBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhczogcmFuZ29fZXRhcmVvLCBwYWNfc2V4byB5IEhvYmJ5X3ByaW5jaXBhbF9wYW50YWxsYS4gRXN0YXMgdGFibGFzIGluaWNpYWxlcyBjb250aWVuZW4gbGFzIGZyZWN1ZW5jaWFzIG9ic2VydmFkYXMsIGxhcyBwcm9iYWJpbGlkYWRlcyBjb25qdW50YXMsIHkgbGFzIGZyZWN1ZW5jaWFzIGNvbmRpY2lvbmFkYXMgcG9yIGZpbGFzIChDUEYpIHkgcG9yIGNvbHVtbmFzIChDUEMpLiBFbCBvYmpldGl2byBkZSBlc3RhIGZhc2UgZXMgZGVzY3JpYmlyIGPDs21vIHNlIGRpc3RyaWJ1eWVuIGxhcyBjYXRlZ29yw61hcyBkZSB1bmEgdmFyaWFibGUgZW4gZnVuY2nDs24gZGUgbGEgb3RyYSwgbG8gY3VhbCBlcyBmdW5kYW1lbnRhbCBwYXJhIGxhIHBvc3RlcmlvciBjb25zdHJ1Y2Npw7NuIGRlIGxvcyBwZXJmaWxlcyB5IGVsIGPDoWxjdWxvIGRlIGxhIGluZXJjaWEgdG90YWwuDQoNCkFsIGFuYWxpemFyIGVzcGVjw61maWNhbWVudGUgbGEgY29tYmluYWNpw7NuIHJhbmdvX2V0YXJlbyB2cy4gSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhLCBzZSBoYWNlIGV2aWRlbnRlIHVuYSB0ZW5kZW5jaWEgY2xhcmEgeSBjb250cmFzdGFkYS4gTG9zIGdydXBvcyBldGFyaW9zIG3DoXMgasOzdmVuZXMgcHJlc2VudGFuIHNpc3RlbcOhdGljYW1lbnRlIHVuYSBtYXlvciBwcm9wb3JjacOzbiBkZSBob2JiaWVzIGFzb2NpYWRvcyBhbCB1c28gZGUgcGFudGFsbGFzLiBQb3IgZWwgY29udHJhcmlvLCBlbiBsb3MgZ3J1cG9zIGRlIG1heW9yIGVkYWQgcHJlZG9taW5hbiBsb3MgaG9iYmllcyBxdWUgbm8gaW1wbGljYW4gZGlzcG9zaXRpdm9zIGRpZ2l0YWxlcy4gRXN0YSBtYXJjYWRhIGRpZmVyZW5jaWEgZW4gbGFzIHByb3BvcmNpb25lcyBkZSBsYXMgY2VsZGFzICh5LCBwb3IgZW5kZSwgZW4gbG9zIHBlcmZpbGVzKSBzdWdpZXJlIGZ1ZXJ0ZW1lbnRlIHVuYSBkZXBlbmRlbmNpYSBzaWduaWZpY2F0aXZhIGVudHJlIGVsIHJhbmdvIGV0YXJpbyBkZWwgcGFjaWVudGUgeSBzaSBzdSBob2JieSBwcmluY2lwYWwgcmVxdWllcmUgbyBubyBlbCB1c28gZGUgcGFudGFsbGFzLg0KDQpMYXMgb3RyYXMgZG9zIGNvbWJpbmFjaW9uZXMgZXhwbG9yYWRhcyBvZnJlY2VuIHVuIGNvbnRyYXN0ZS4gRW4gZWwgY2FzbyBkZSBwYWNfc2V4byB2cy4gSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhLCBsYSB0YWJsYSBwZXJtaXRlIGlkZW50aWZpY2FyIGxpZ2VyYXMgdmFyaWFjaW9uZXMgZW4gbGEgcHJlZmVyZW5jaWEgcG9yIGhvYmJpZXMgY29uL3NpbiBwYW50YWxsYSBzZWfDum4gZWwgc2V4bzsgc2luIGVtYmFyZ28sIGVzdGFzIGRpZmVyZW5jaWFzIHRpZW5kZW4gYSBzZXIgbWVub3MgbWFyY2FkYXMgcXVlIGxhcyBlbmNvbnRyYWRhcyBwb3IgcmFuZ28gZXRhcmlvLCBzdWdpcmllbmRvIHVuYSBhc29jaWFjacOzbiBtw6FzIGTDqWJpbC4gRmluYWxtZW50ZSwgbGEgdGFibGEgcmFuZ29fZXRhcmVvIHZzLiBwYWNfc2V4byBzZSB1dGlsaXphIHBhcmEgdmVyaWZpY2FyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgZXF1aWxpYnJpbzogbXVlc3RyYSBjw7NtbyBzZSBkaXN0cmlidXllbiBob21icmVzIHkgbXVqZXJlcyBkZW50cm8gZGUgY2FkYSBncnVwbyBkZSBlZGFkIHBhcmEgYXNlZ3VyYXIgcXVlIGxhIGNvbXBvc2ljacOzbiBkZSBsYSBtdWVzdHJhIHBvciByYW5nb3MgZXRhcmlvcyBubyBlc3TDqSBzZXNnYWRhIHNpZ25pZmljYXRpdmFtZW50ZSBwb3IgZWwgc2V4by4NCg0KRW4gY29uanVudG8sIGxhIGluZm9ybWFjacOzbiBjb250ZW5pZGEgZW4gZXN0YXMgdGFibGFzIGRlIGNvbnRpbmdlbmNpYSB5IHN1cyB0cmFuc2Zvcm1hY2lvbmVzIChwcm9iYWJpbGlkYWRlcyB5IGZyZWN1ZW5jaWFzIGNvbmRpY2lvbmFkYXMpIGVzIHZpdGFsLiBQZXJtaXRlbiBpZGVudGlmaWNhciBxdcOpIGNvbWJpbmFjaW9uZXMgZGUgY2F0ZWdvcsOtYXMgKGNlbGRhcykgY29udHJpYnV5ZW4gbcOhcyBvIG1lbm9zIGEgbGEgcG9zaWJsZSBkZXBlbmRlbmNpYSBlbnRyZSBsYXMgdmFyaWFibGVzLiBFc3RhIGluZm9ybWFjacOzbiBkZXRhbGxhZGEgc2Vyw6EgY3J1Y2lhbCBlbiBsb3MgcGFzb3Mgc3Vic2lndWllbnRlcyBkZWwgQUNTLCBkb25kZSBzZSByZXN1bWlyw6EgeSB2aXN1YWxpemFyw6EgbWVkaWFudGUgZWwgYW7DoWxpc2lzIGRlIGNvbnRyaWJ1Y2lvbmVzLCBsYSBldmFsdWFjacOzbiBkZSBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiB5IGxhIGNvbnN0cnVjY2nDs24gZGVsIG1hcGEgZmFjdG9yaWFsLg0KDQojIyMjIyBQZXJmaWxlcyBbQ1BGIHkgQ1BDXQ0KYGBge3IgR3JhZmljb3NfZGVfUGVyZmlsZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KIyByYW5nb19ldGFyZW8gdnMgSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhDQpwbG90Y3QodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbywNCiAgICAgICAgICAgICBjY2RfdmlzaW9uMjAyMF9FVEwkSG9iYnlfcHBhbnRhbGxhKSwicm93IikNCnBsb3RjdCh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvLA0KICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpLCAiY29sIikNCg0KIyBwYWNfc2V4byB2cyByYW5nb19ldGFyZW8NCnBsb3RjdCh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcGFjX3NleG8sDQogICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbyksICJyb3ciKQ0KcGxvdGN0KHRhYmxlKGNjZF92aXNpb24yMDIwX0VUTCRwYWNfc2V4bywNCiAgICAgICAgICAgICBjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvKSwgImNvbCIpDQoNCiMgcGFjX3NleG8gdnMgSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhDQpwbG90Y3QodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHBhY19zZXhvLA0KICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpLCAicm93IikNCnBsb3RjdCh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcGFjX3NleG8sDQogICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJEhvYmJ5X3BwYW50YWxsYSksICJjb2wiKQ0KYGBgDQoNCkVsIGFuw6FsaXNpcyBkZSBsb3MgUGVyZmlsZXMgQ29uZGljaW9uYWRvcyBwb3IgRmlsYXMgKENQRikgeSBDb25kaWNpb25hZG9zIHBvciBDb2x1bW5hcyAoQ1BDKSwgY29tcGFyYWRvcyBjb24gZWwgcGVyZmlsIHByb21lZGlvICgibWFyZyIpLCBlcyBmdW5kYW1lbnRhbCBlbiBlbCBBbsOhbGlzaXMgZGUgQ29ycmVzcG9uZGVuY2lhcyBTaW1wbGUgKEFDUykgcGFyYSBtZWRpciBsYSBmdWVyemEgZGUgYXNvY2lhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMuDQoNCkxvcyByZXN1bHRhZG9zIGNvbmZpcm1hbiBxdWUgbGEgdmFyaWFibGUgcmFuZ29fZXRhcmVvIGVzIGxhIHF1ZSBwcmVzZW50YSBsYSBtYXlvciBjYXBhY2lkYWQgZXhwbGljYXRpdmEgeSBnZW5lcmEgbGEgbWF5b3IgZGlzcGVyc2nDs24gKGluZXJjaWEpIGVuIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzLiBMYSB2YXJpYWJsZSBwYWNfc2V4byBtdWVzdHJhIGNvbnNpc3RlbnRlbWVudGUgYXNvY2lhY2lvbmVzIG3DoXMgZMOpYmlsZXMgY29uIGxhcyBvdHJhcyB2YXJpYWJsZXMuIFBvciBsbyB0YW50bywgZWwgcGFyIHJhbmdvX2V0YXJlbyAkXHRpbWVzJCBIb2JieV9wcmluY2lwYWxfcGFudGFsbGEgc2UgaWRlbnRpZmljYSBjb21vIGVsIG3DoXMgcmVsZXZhbnRlIHBhcmEgbG9zIGFuw6FsaXNpcyBlc3RydWN0dXJhbGVzIHBvc3RlcmlvcmVzIGRlbCBlc3R1ZGlvIFZpc2lvbiAyMDIwLg0KDQojIyMjIyBQcnVlYmFzIGRlIEhpcMOzdGVzaXMNCmBgYHtyIFBydWViYXNfZGVfQ29ycmVzcG9uZGVuY2lhLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmNoaXNxLnRlc3QodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHJhbmdvX2V0YXJlbywNCiAgICAgICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJEhvYmJ5X3BwYW50YWxsYSkpDQoNCmNoaXNxLnRlc3QodGFibGUoY2NkX3Zpc2lvbjIwMjBfRVRMJHBhY19zZXhvLA0KICAgICAgICAgICAgICAgICBjY2RfdmlzaW9uMjAyMF9FVEwkcmFuZ29fZXRhcmVvKSkNCg0KY2hpc3EudGVzdCh0YWJsZShjY2RfdmlzaW9uMjAyMF9FVEwkcGFjX3NleG8sDQogICAgICAgICAgICAgICAgIGNjZF92aXNpb24yMDIwX0VUTCRIb2JieV9wcGFudGFsbGEpKQ0KYGBgDQoNCkxhIGFwbGljYWNpw7NuIGRlIGxhcyBwcnVlYmFzICRcY2hpXjIkIHBlcm1pdGnDsyB2YWxpZGFyIGVzdGFkw61zdGljYW1lbnRlIGxhcyBhc29jaWFjaW9uZXMgb2JzZXJ2YWRhcyBlbiBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcywgYXJyb2phbmRvIHJlc3VsdGFkb3MgcXVlIGNvbnRyYWRpY2VuIHBhcmNpYWxtZW50ZSBsYXMgdGVuZGVuY2lhcyB2aXN1YWxlcyBkZXNjcmlwdGl2YXMgaW5pY2lhbGVzLg0KDQpMb3MgcmVzdWx0YWRvcyByZW9yaWVudGFuIGVsIGZvY28gZGVsIGFuw6FsaXNpczogbGEgcHJ1ZWJhICRcY2hpXjIkIGVzdGFibGVjZSBxdWUgbGEgYXNvY2lhY2nDs24gbcOhcyBmdWVydGUgeSByZWFsIHNlIGRhIGVudHJlIFNleG8geSBIb2JieSBwcmluY2lwYWwgKGNvbiBQYW50YWxsYSksIG1pZW50cmFzIHF1ZSBsYSByZWxhY2nDs24gZW50cmUgUmFuZ28gRXRhcmlvIHkgSG9iYnksIHF1ZSB2aXN1YWxtZW50ZSBwYXJlY8OtYSBsYSBtw6FzIGNsYXJhLCBubyBmdWUgdmFsaWRhZGEgZXN0YWTDrXN0aWNhbWVudGUuIFBvciBsbyB0YW50bywgZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcOhcyBkZXRhbGxhZG8gZGViZXLDoSBjZW50cmFyc2UgZW4gZWwgcGFyIFNleG8gdnMuIEhvYmJ5IFByaW5jaXBhbCAoY29uIFBhbnRhbGxhKS4NCg0KIyMjIyBBQyBQYXJlamEgw5puaWNhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIENvbnRpbmdlbmNpYXMgeSBSZXNpZHVhbGVzIFtULUNQXQ0KYGBge3IgQ29udGluZ2VuY2lhc195X1Jlc2lkdWFsZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KdGFiX1JFX0hvYmJ5IDwtIHRhYmxlKGNjZF92aXNpb24yMDIwX0VUTCRyYW5nb19ldGFyZW8sDQogICAgICAgICAgICAgICAgICAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJEhvYmJ5X3BwYW50YWxsYSkNCg0KY2hpc3EudGVzdCh0YWJfUkVfSG9iYnkpJG9ic2VydmVkDQpjaGlzcS50ZXN0KHRhYl9SRV9Ib2JieSkkZXhwZWN0ZWQNCmNoaXNxLnRlc3QodGFiX1JFX0hvYmJ5KSRyZXNpZHVhbHMNCmNoaXNxLnRlc3QodGFiX1JFX0hvYmJ5KSRzdGRyZXMNCmBgYA0KDQpMYSBwZXN0YcOxYSBkZSBjb250aW5nZW5jaWFzIHkgcmVzaWR1YWxlcyBtdWVzdHJhIGxvcyBkYXRvcyBvYnNlcnZhZG9zIHkgbGFzIGRpZmVyZW5jaWFzIHJlc3BlY3RvIGEgbG8gZXNwZXJhZG8gYmFqbyBpbmRlcGVuZGVuY2lhLCBwZXJtaXRpZW5kbyBpZGVudGlmaWNhciBxdcOpIGNvbWJpbmFjaW9uZXMgY29udHJpYnV5ZW4gbcOhcyBhIGxhIGFzb2NpYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMuDQoNCkVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIGVudHJlIGVsIHJhbmdvIGV0YXJpbyB5IGVsIHRpcG8gZGUgaG9iYnkgbXVlc3RyYSBxdWUgbGEgZWRhZCBpbmZsdXllIGVuIGVsIHVzbyBkZSBwYW50YWxsYXMgY29tbyBhY3RpdmlkYWQgcHJpbmNpcGFsLiBMb3MgYWR1bHRvcyBwcmVzZW50YW4gbWF5b3IgYXNvY2lhY2nDs24gY29uIGhvYmJpZXMgcXVlIGltcGxpY2FuIHBhbnRhbGxhcywgbWllbnRyYXMgcXVlIGVuIGxhIG5pw7FleiB5IGVuIGxvcyBhZHVsdG9zIG1heW9yZXMgcHJlZG9taW5hbiBsb3MgaG9iYmllcyBzaW4gcGFudGFsbGEuIA0KDQpBdW5xdWUgbGEgcmVsYWNpw7NuIG5vIGVzIG11eSBmdWVydGUsIGVsIGFuw6FsaXNpcyBldmlkZW5jaWEgcGF0cm9uZXMgY2xhcm9zIHkgY29uc2lzdGVudGVzLCBkb25kZSBsb3MgZ3J1cG9zIGV0YXJpb3MgZXh0cmVtb3Mgc2UgZGlmZXJlbmNpYW4gZW4gbG9zIHBvbG9zIGRlbCBlamUgcHJpbmNpcGFsLCB5IGxvcyBncnVwb3MgaW50ZXJtZWRpb3MgbXVlc3RyYW4gdW4gY29tcG9ydGFtaWVudG8gY2VyY2FubyBhbCBwcm9tZWRpby4gRXN0b3MgcmVzdWx0YWRvcyBwZXJtaXRlbiBjb25jbHVpciBxdWUgZXhpc3RlIHVuYSBhc29jaWFjacOzbiByZWxldmFudGUgZW50cmUgbGEgZWRhZCBkZWwgcGFjaWVudGUgeSBzdSBob2JieSBwcmluY2lwYWwgZW4gbGEgcG9ibGFjacOzbiBhdGVuZGlkYSBwb3IgVmlzaW9uIDIwMjAuDQoNCiMjIyMjIENvbnRyaWJ1Y2lvbmVzIFtULUNQXQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfUi1VUiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpjaGlfUkVfSG9iYnkgPC0gY2hpc3EudGVzdCh0YWJfUkVfSG9iYnkpDQpjaGlfUkVfSG9iYnkkcmVzaWR1YWxzXjIgLyBjaGlfUkVfSG9iYnkkc3RhdGlzdGljICogMTAwDQpgYGANCg0KTGEgZGVwZW5kZW5jaWEgZW50cmUgcmFuZ28gZXRhcmVvIHkgSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhIGVzdMOhIGV4cGxpY2FkYSBwcmluY2lwYWxtZW50ZSBwb3IgbG9zIGFkdWx0b3MgbWF5b3JlcyB5IGxvcyBhZHVsdG9zLCBzZWd1aWRvcyBwb3IgZWwgZ3J1cG8gZGUgbmnDsWV6LiBFbiBjb250cmFzdGUsIGrDs3ZlbmVzIHkgcHJpbWVyYSBpbmZhbmNpYSB0aWVuZW4gdW5hIGNvbnRyaWJ1Y2nDs24gbcOtbmltYSwgeWEgcXVlIHN1cyBkaXN0cmlidWNpb25lcyBzZSBhc2VtZWphbiBhbCBjb21wb3J0YW1pZW50byBlc3BlcmFkbyBiYWpvIGluZGVwZW5kZW5jaWEuDQoNCiMjIyMjIENvcnJlc3BvbmRlbmNpYSBTaW1wbGUgVW5pZGltZW5zaW9uYWwgW3JhbmdvX2V0YXJlb+KAk0hvYmJ5XQ0KYGBge3IgQmlwbG90X0NvcnJlc3BvbmRlbmNpYV9TaW1wbGVfUi1VUiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyZXNfY2FfUkVfSG9iYnkgPC0gQ0EodGFiX1JFX0hvYmJ5LCBncmFwaCA9IEZBTFNFKQ0KDQpyZXNfY2FfUkVfSG9iYnkkZWlnDQpyZXNfY2FfUkVfSG9iYnkkY29sDQpyZXNfY2FfUkVfSG9iYnkkcm93DQpgYGANCg0KRXN0ZSBhbsOhbGlzaXMgZGVsIHBhciBSYW5nbyBFdGFyaW8gJFx0aW1lcyQgSG9iYnkgUHJpbmNpcGFsLCByZXZlbMOzIHVuYSBjbGFyYSB0ZW5kZW5jaWEgZGVzY3JpcHRpdmEgZGUgcG9sYXJpemFjacOzbiBlbiBlbCB1c28gZGUgcGFudGFsbGFzOg0KDQpMb3MgQWR1bHRvcyAoZ3J1cG9zIGRlIGp1dmVudHVkL21hZHVyZXopIHNlIG11ZXN0cmFuIGNvbW8gbG9zIG3DoXMgaW5jbGluYWRvcyBhIGxvcyBob2JiaWVzIGRpZ2l0YWxlcyB5IGxvcyBncnVwb3MgZGUgTmnDsWV6IHkgQWR1bHRvcyBNYXlvcmVzIHNlIGFncnVwYW4gZW4gYWN0aXZpZGFkZXMgdHJhZGljaW9uYWxlcyBzaW4gcGFudGFsbGFzLiBEZSBoZWNobywgbG9zIG5pw7FvcyBzZSBwZXJjaWJlbiBjb21vIGVsIGdydXBvIG3DoXMgYWxlamFkbyBkZSBsb3MgaG9iYmllcyBjb24gcGFudGFsbGEgZW4gZXN0YSBtdWVzdHJhIGVzcGVjw61maWNhLiAgQXVucXVlIGVsIHBhdHLDs24gdmlzdWFsIGV4aXN0ZSwgbGEgYmFqYSBpbmVyY2lhLCBjb25maXJtYWRhIHBvciBsYSBwcnVlYmEgJFxjaGleMiQgcHJldmlhLCBzaWduaWZpY2EgcXVlIGxhIHJlbGFjacOzbiBlbnRyZSBsYSBlZGFkIHkgZWwgdXNvIGRlIHBhbnRhbGxhcyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBkw6liaWwuIExhIGVkYWQgbm8gZXMgdW4gcHJlZGljdG9yIGFic29sdXRvIHBhcmEgZGV0ZXJtaW5hciBzaSB1biBwYWNpZW50ZSB1c2EgcGFudGFsbGFzLg0KDQojIyMgMy4zLiBDb3JyZXNwb25kZW5jaWFzIE3Dumx0aXBsZXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRGUgYWN1ZXJkbyBjb24gW0BBRURNRGlhei1Nb3JhbGVzMWVkXSwgZWwgYW7DoWxpc2lzIGRlICoqY29ycmVzcG9uZGVuY2lhcyBzaW1wbGUgKEFDUykqKiBwdWVkZSBhbXBsaWFyc2UgcGFyYSB0cmFiYWphciBjb24gdGFibGFzIGRpc3l1bnRpdmFzIGNvbXBsZXRhcy4gRW4gZXN0ZSBmb3JtYXRvLCBsYXMgZmlsYXMgcmVwcmVzZW50YW4gYSBsb3MgcGFjaWVudGVzLCBtaWVudHJhcyBxdWUgbGFzIGNvbHVtbmFzIGRlc2NyaWJlbiBsYXMgbW9kYWxpZGFkZXMgZGUgbGFzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgYW5hbGl6YWRhcywgY29tbyAqKnJhbmdvX2V0YXJlbyoqLCAqKnBhY19zZXhvKiosICoqSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhKiogeSAqKlByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhKiosIGFzaWduYW5kbyBhIGNhZGEgcGFjaWVudGUgdW5hIGNhdGVnb3LDrWEgw7puaWNhIHBhcmEgY2FkYSB2YXJpYWJsZS4gRWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcO6bHRpcGxlcyAqKihBQ00pKiogc2UgY29uc3RydXllIHNvYnJlIGVzdGEgdGFibGEgZGlzeXVudGl2YSwgYXBsaWNhbmRvIGVsIG3DqXRvZG8gZGUgY29ycmVzcG9uZGVuY2lhcyBkZSBmb3JtYSBjb25qdW50YSBhIHRvZGFzIGxhcyAqKnZhcmlhYmxlcyBjYXRlZ8OzcmljYXMqKiwgcGFydGljaW9uYW5kbyBkZSBtYW5lcmEgZXhjbHVzaXZhIHkgZXhoYXVzdGl2YSBhIGxhIHBvYmxhY2nDs24gZW4gZnVuY2nDs24gZGUgc3VzIGNhcmFjdGVyw61zdGljYXMgZGVtb2dyw6FmaWNhcyB5IGjDoWJpdG9zLg0KDQpFc3RhIHNlY2Npw7NuIHNlIHBsYW50ZWEgY29tbyB1bmEgc29sdWNpw7NuIGNvbXBsZW1lbnRhcmlhIGFsICoqQUNTKiosIGN1eW8gYW7DoWxpc2lzIGVuIGxhIFtzZWNjacOzbiAzLjJdKCNzZWMzLjIpIGVzdHV2byBsaW1pdGFkbyBwb3IgbGEgbmF0dXJhbGV6YSB1bmlkaW1lbnNpb25hbCBkZSBsb3MgZGF0b3MgeSBsYSAqKmltcG9zaWJpbGlkYWQgZGUgdW5hIHJlcHJlc2VudGFjacOzbiBiaWRpbWVuc2lvbmFsIHNpZ25pZmljYXRpdmEqKi4gUG9yIGVsbG8sIG1lZGlhbnRlIGVsICoqQUNNKiogeSBlbCB0cmF0YW1pZW50byBjb25qdW50byBkZSB0b2RhcyBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyByZWxhY2lvbmFkYXMsIHNlIGJ1c2NhIGNvbnN0cnVpciB1bmEgcmVwcmVzZW50YWNpw7NuIG3DoXMgY29tcGxldGEgZW4gZWwgcHJpbWVyIHBsYW5vIGZhY3RvcmlhbCwgb2ZyZWNpZW5kbyB1bmEgdmlzacOzbiBpbnRlZ3JhbCBkZSBsYXMgYXNvY2lhY2lvbmVzIGNsw61uaWNhcyBtw6FzIHJlbGV2YW50ZXMgZW50cmUgZWRhZCwgc2V4bywgaMOhYml0b3MgZGlnaXRhbGVzIHkgcHJlZGlzcG9zaWNpw7NuIGdlbsOpdGljYS4NCg0KIyMjIyBBQ00gDQpgYGB7ciBBQ00sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kc2V0LnNlZWQoNzgwNzI5KQ0KdmlzaW9uMjAyMF9jYXRlZ29yaWNhcyA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQpzYW1wbGUoMTpucm93KGNjZF92aXNpb24yMDIwX0VUTCksIDMwMCksDQpjKCJyYW5nb19ldGFyZW8iLCAicGFjX3NleG8iLCAiSG9iYnlfcHBhbnRhbGxhIiwgIlByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhIikNCl0NCg0Kc3VwcHJlc3NXYXJuaW5ncyhyb3VuZChNQ0EodmlzaW9uMjAyMF9jYXRlZ29yaWNhcywgZ3JhcGggPSBGQUxTRSwgbmNwID0gNSkkZWlnLCAzKSkNCmBgYA0KDQpMYSBEaW1lbnNpw7NuIDEgZXhwbGljYSBlbCAxNyUgZGUgbGEgaW5lcmNpYSB0b3RhbCwgbWllbnRyYXMgcXVlIGxhIERpbWVuc2nDs24gMiBleHBsaWNhIGVsIDE1JS4gRWwgcGVzbyBzaW1pbGFyIGRlIGVzdG9zIHZhbG9yZXMgcHJvcGlvcyAoYXV0b3ZhbG9yZXMpIGVzIHVuIGluZGljYWRvciBjcnVjaWFsIGRlIHF1ZSBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgcGFjaWVudGVzIHkgbG9zIGZhY3RvcmVzIGRlIHJpZXNnbyB2aXN1YWwgc29uIGNvbXBsZWpvcyB5IG11bHRpZmFjdG9yaWFsZXMuIE5vIGhheSB1biBmYWN0b3Igw7puaWNvIHF1ZSBsbyBleHBsaXF1ZSB0b2RvLCBsbyBxdWUgZXhpZ2UgY29uc2lkZXJhciBtw7psdGlwbGVzIGRpbWVuc2lvbmVzIHBhcmEgdW5hIGludGVycHJldGFjacOzbiBjb21wbGV0YS4gDQoNCkVsICdNYXBhJyBQcmluY2lwYWwgZGUgTmF2ZWdhY2nDs24gYWwgc3VtYXIgbGEgY2FwYWNpZGFkIGV4cGxpY2F0aXZhIGRlIGVzdGFzIGRvcyBwcmltZXJhcyBkaW1lbnNpb25lcywgb2J0ZW5lbW9zIHVuICQzMlwlJCBkZSBsYSBleHBsaWNhY2nDs24gYWN1bXVsYWRhICgkMTdcJSArIDE1XCUkKS4gRXN0ZSBwb3JjZW50YWplLCBhdW5xdWUgbW9kZXN0bywgZGVmaW5lIGVsICdtYXBhIGRlIG5hdmVnYWNpw7NuJyBwcmluY2lwYWwgcGFyYSBsYSB2aXN1YWxpemFjacOzbi4gRWwgcGxhbm8gZmFjdG9yaWFsIGZvcm1hZG8gcG9yIGxhcyBEaW1lbnNpb25lcyAxIHkgMiBzZXLDoSBsYSBoZXJyYW1pZW50YSBlc2VuY2lhbCBwYXJhIHByb3llY3RhciBlIGludGVycHJldGFyIGxhcyB0ZW5kZW5jaWFzIHkgcHJveGltaWRhZGVzIGdlbmVyYWxlcyBlbnRyZSBsYXMgY2F0ZWdvcsOtYXMgZGUgdG9kYXMgbGFzIHZhcmlhYmxlcyBpbnZvbHVjcmFkYXMuDQoNClZhbGlkYWNpw7NuIHkgRWZpY2llbmNpYSBkZWwgTW9kZWxvRWwgbWVuc2FqZSBtw6FzIGltcG9ydGFudGUgcGFyYSBsYSB2YWxpZGFjacOzbiBkZWwgbW9kZWxvIHNlIGVuY3VlbnRyYSBlbiBsYSBjb2x1bW5hIGRlIGV4cGxpY2FjacOzbiBhY3VtdWxhZGEuICBTZSBvYnNlcnZhIHF1ZSBjb24gc29sbyA1IGRpbWVuc2lvbmVzLCBzZSBsb2dyYSBjYXB0dXJhciBhcHJveGltYWRhbWVudGUgZWwgJDc1XCUkIGRlIHRvZGEgbGEgaW5mb3JtYWNpw7NuIChpbmVyY2lhKSBjb250ZW5pZGEgZW4gZWwgZXN0dWRpby4gRXN0ZSBoYWxsYXpnbyB2YWxpZGEgbGEgZWZpY2llbmNpYSBkZWwgQW7DoWxpc2lzIGRlIENvcnJlc3BvbmRlbmNpYXMgTcO6bHRpcGxlczogZWwgbW9kZWxvIGVzIGNhcGF6IGRlIGNvbmRlbnNhciBsYSBncmFuIG1heW9yw61hIGRlIGxvcyBwYXRyb25lcyBkZSBjb21wb3J0YW1pZW50byB5IHJpZXNnbyB2aXN1YWwgZGUgbGEgcG9ibGFjacOzbiBlbiB1biBuw7ptZXJvIHJlZHVjaWRvIGRlIHZhcmlhYmxlcyBsYXRlbnRlcy4NCg0KIyMjIyBCaXBsb3QgQUNNDQpgYGB7ciBCaXBsb3RfQUNNLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOSkNCnZpc2lvbjIwMjBfY2F0ZWdvcmljYXMgPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0Kc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLCAzMDApLA0KYygicmFuZ29fZXRhcmVvIiwgInBhY19zZXhvIiwgIkhvYmJ5X3BwYW50YWxsYSIsICJQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSIpDQpdDQoNCnJlcy5tY2EgPC0gTUNBKHZpc2lvbjIwMjBfY2F0ZWdvcmljYXMsIGdyYXBoID0gRkFMU0UpDQoNCmZ2aXpfbWNhX2JpcGxvdChyZXMubWNhLCByZXBlbCA9IFRSVUUsIGNvbC52YXIgPSAiI0U3QjgwMCIsIGFkZEVsbGlwc2VzID0gVFJVRSwgZWxsaXBzZS5sZXZlbCA9IDAuOTUpDQpgYGANCg0KRWwgVGVycml0b3JpbyBkZSBsYSBKdXZlbnR1ZCwgc2UgbWlyYW4gYSBsYSBkZXJlY2hhIGRlbCBncsOhZmljbywgYWdydXBhZG9zIGp1bnRvIGEgbGEgUHJpbWVyYSBJbmZhbmNpYSwgcXVpZW5lcyBhZGVtw6FzIHRpZW5kZW4gYSBlc3RhciBtw6FzIGNlcmNhIGRlbCBwZXJmaWwgZmVtZW5pbm8gZW4gZXN0YSBtdWVzdHJhLg0KDQpIYWNpYSBsYSBpenF1aWVyZGEsIGVuY3VlbnRyYSBhIGxvcyBBZHVsdG9zIE1heW9yZXMsIG3DoXMgYXNvY2lhZG9zIGFsIHBlcmZpbCBtYXNjdWxpbm8uIEVzdG8gY29uZmlybWEgbGEgYnJlY2hhIGdlbmVyYWNpb25hbCBxdWUgdmXDrWFtb3MgYW50ZXM6IGxvcyBqw7N2ZW5lcyB5IGxvcyBhYnVlbG9zIGVzdMOhbiBlbiBleHRyZW1vcyBvcHVlc3RvcyBkZWwgbWFwYS4iIFBvciBvdHJhIHBhcnRlLCBsYSBOacOxZXogZXN0w6EgbGVqb3MgZGUgdG9kb3MgbG9zIGRlbcOhcywgcG9yIGxvIHF1ZSBlbiBlbCBsb3MgbmnDsW9zIGVzdHVkaW8gdGllbmVuIHVuIGNvbXBvcnRhbWllbnRvIHkgY2FyYWN0ZXLDrXN0aWNhcyBtdXkgZGlzdGludGFzIGEgbG9zIGFkdWx0b3MuDQoNCkVuIHJlc3VtZW4sIGVsIEFDTSBsb2dyw7Mgc2VwYXJhciBleGl0b3NhbWVudGUgYSBsYSBwb2JsYWNpw7NuIHBvciBldGFwYXMgZGUgdmlkYSwgbG8gcXVlICBwZXJtaXRpcsOhIGVuZm9jYXIgbGFzIGVzdHJhdGVnaWFzIGRlIHByZXZlbmNpw7NuIHZpc3VhbCBkZSBtYW5lcmEgZGlmZXJlbmNpYWRhIHBhcmEgbmnDsW9zLCBhZHVsdG9zIHkgYWR1bHRvcyBtYXlvcmVzLg0KDQoNCiMjIyMgQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24NCmBgYHtyIENhbGlkYWRfZGVfUmVwcmVzZW50YWNpb25fQUNNLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOSkNCnZpc2lvbjIwMjBfY2F0ZWdvcmljYXMgPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0Kc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLCAzMDApLA0KYygicmFuZ29fZXRhcmVvIiwgInBhY19zZXhvIiwgIkhvYmJ5X3BwYW50YWxsYSIsICJQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSIpDQpdDQoNCnJlcy5tY2EgPC0gTUNBKHZpc2lvbjIwMjBfY2F0ZWdvcmljYXMsIGdyYXBoID0gRkFMU0UpDQoNCmZ2aXpfbWNhX3ZhcihyZXMubWNhLCBjb2wudmFyID0gImNvczIiLCBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwgcmVwZWwgPSBUUlVFKQ0KDQpyZXMubWNhJHZhciRjb3MyDQpgYGANCg0KRWwgcHJvY2VzbyBkZSBldmFsdWFyIGxhICJDYWxpZGFkIGRlIFJlcHJlc2VudGFjacOzbiIgKG8gJENPU14yJCkgcGVybWl0ZSBkZXRlcm1pbmFyIHF1w6kgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcyBzb24gbWVqb3IgZXhwbGljYWRhcyBwb3IgZWwgcGxhbm8gZmFjdG9yaWFsIGVsZWdpZG8gKERpbWVuc2nDs24gMSB5IDIpLCB5IGN1w6FsZXMgcmVxdWllcmVuIGRpbWVuc2lvbmVzIGFkaWNpb25hbGVzIHBhcmEgc2VyIGVudGVuZGlkYXMuIE1ldGFmw7NyaWNhbWVudGUsIGV2YWx1YW1vcyBxdcOpIHBhcnRlcyBkZSBudWVzdHJhICJmb3RvZ3JhZsOtYSIgZGUgbG9zIHBhY2llbnRlcyBzYWxpZXJvbiBuw610aWRhcyB5IGN1w6FsZXMgc2FsaWVyb24gYm9ycm9zYXMuDQoNCg0KRW4gcmVzdW1lbiwgZXN0ZSBtYXBhIGZhY3RvcmlhbCBlcyBhbHRhbWVudGUgY29uZmlhYmxlIHBhcmEgYW5hbGl6YXIgbGFzIHZhcmlhYmxlcyBkZSB1c28gZGUgcGFudGFsbGFzIChIb2JieSkgeSBHZW7DqXRpY2EsIHkgcGFyYSB1YmljYXIgYSBsb3MgQWR1bHRvcy4gU2luIGVtYmFyZ28sIGRlYmVtb3Mgc2VyIGNhdXRlbG9zb3MgYWwgc2FjYXIgY29uY2x1c2lvbmVzIGRlZmluaXRpdmFzIG8gZGV0YWxsYWRhcyBzb2JyZSBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgSsOzdmVuZXMgYmFzw6FuZG9ub3MgZXhjbHVzaXZhbWVudGUgZW4gZXN0YSBpbWFnZW4gYmlkaW1lbnNpb25hbC4NCg0KIyMjIyBDb250cmlidWNpb25lcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfQUNNLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOSkNCnZpc2lvbjIwMjBfY2F0ZWdvcmljYXMgPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0Kc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLCAzMDApLA0KYygicmFuZ29fZXRhcmVvIiwgInBhY19zZXhvIiwgIkhvYmJ5X3BwYW50YWxsYSIsICJQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSIpDQpdDQoNCnJlcy5tY2EgPC0gTUNBKHZpc2lvbjIwMjBfY2F0ZWdvcmljYXMsIGdyYXBoID0gRkFMU0UpDQoNCnBhcihtZnJvdz1jKDMsMikpDQpgYGANCg0KIyMjIyMgQ29udHJpYnVjaW9uZXMgRDENCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0FDTV9EMSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NvbnRyaWIocmVzLm1jYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxLCB0b3AgPSAxNSkNCmBgYA0KDQojIyMjIyBDb250cmlidWNpb25lcyBEMg0KYGBge3IgQ29udHJpYnVjaW9uZXNfQUNNX0QyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfY29udHJpYihyZXMubWNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDE1KQ0KYGBgDQoNCiMjIyMjIENvbnRyaWJ1Y2lvbmVzIEQzDQpgYGB7ciBDb250cmlidWNpb25lc19BQ01fRDMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKHJlcy5tY2EsIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMywgdG9wID0gMTUpDQpgYGANCg0KIyMjIyMgQ29udHJpYnVjaW9uZXMgRDQNCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0FDTV9ENCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NvbnRyaWIocmVzLm1jYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSA0LCB0b3AgPSAxNSkNCmBgYA0KDQojIyMjIyBDb250cmlidWNpb25lcyBENQ0KYGBge3IgQ29udHJpYnVjaW9uZXNfQUNNX0Q1LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfY29udHJpYihyZXMubWNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDE1KQ0KcGFyKG1mcm93PWMoMSwxKSkNCmBgYA0KDQpFbCBhbsOhbGlzaXMgZGUgbGFzIGNvbnRyaWJ1Y2lvbmVzIHJldmVsYSBjw7NtbyBzZSBlc3RydWN0dXJhIGplcsOhcnF1aWNhbWVudGUgbGEgaW5mb3JtYWNpw7NuIGVuIGVsIG1vZGVsbzogRGltZW5zacOzbiAxIChFamUgZGUgUmllc2dvKTogRXN0YSBkaW1lbnNpw7NuIGVzIGxhIG3DoXMgaW1wb3J0YW50ZSB5IGVzdMOhIGRlZmluaWRhIHBvciBmYWN0b3JlcyBjb21wb3J0YW1lbnRhbGVzIHkgYmlvbMOzZ2ljb3MuIExhcyBjYXRlZ29yw61hcyBtw6FzIGNvbnRyaWJ1eWVudGVzIHNvbiBIb2JieSAoU8OtL05vKSB5IFByZWRpc3Bvc2ljacOzbiBHZW7DqXRpY2EgKDAvMSkuIEVzdG8gY29uZmlybWEgcXVlIGxhIHByaW5jaXBhbCBkaXZpc2nDs24gZGUgbGEgcG9ibGFjacOzbiBzZSBkYSBwb3IgbGEgcHJlc2VuY2lhIG8gYXVzZW5jaWEgY29tYmluYWRhIGRlIGVzdG9zIGRvcyBmYWN0b3JlcyBkZSByaWVzZ28gdmlzdWFsLg0KDQpEaW1lbnNpw7NuIDIgKEVqZSBkZSBsYSBBZHVsdGV6KTogTGEgZXN0cnVjdHVyYSBjYW1iaWE6IGVzdGEgZGltZW5zacOzbiBlcyBpbXB1bHNhZGEgcHJpbmNpcGFsbWVudGUgcG9yIGxhIGNhdGVnb3LDrWEgQURVTFRPLCBzZWd1aWRhIHBvciBlbCBzZXhvIE1hc2N1bGluby4gRXN0ZSBlamUgYcOtc2xhIGxhIG1hZHVyZXogYmlvbMOzZ2ljYSB5IHNvY2lhbCBkZWwgcmVzdG8gZGUgbGFzIGV0YXBhcyBkZSBsYSB2aWRhLiBQb3IgcGFydGUgZGUgbGFzIGRpbWVuc2lvbmVzIHNlY3VuZGFyaWFzIChFamVzIGRlIEV0YXBhcyBkZSBWaWRhKTogTGFzIGRpbWVuc2lvbmVzIHN1YnNpZ3VpZW50ZXMgc2VwYXJhbiBsb3MgZXh0cmVtb3MgZXRhcmlvcyB5IGxvcyBncnVwb3MgY29tcGxlam9zLg0KDQpFbCBBQ00gaGEgc2VncmVnYWRvIGV4aXRvc2FtZW50ZSBsYSBpbmZvcm1hY2nDs246IHByaW1lcm8gcG9yIHJpZXNnbyAoRGltIDEpLCBsdWVnbyBwb3IgbWFkdXJleiAoRGltIDIpLCB5IGZpbmFsbWVudGUgcG9yIGdydXBvcyBkZSBlZGFkIGVzcGVjw61maWNvcywgdmFsaWRhbmRvIHF1ZSBlbCBjb21wb3J0YW1pZW50byBkZSBsb3MgcGFjaWVudGVzIGVzIG11bHRpZmFjdG9yaWFsIHkgcG9yIGV0YXBhcyBkZSB2aWRhLg0KDQojIyMjIEJpcGxvdCBjb24gQ29udHJpYnVjaW9uZXMNCmBgYHtyIEJpcGxvdF9jb25fQ29udHJpYnVjaW9uZXNfQUNNLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOSkNCnZpc2lvbjIwMjBfY2F0ZWdvcmljYXMgPC0gY2NkX3Zpc2lvbjIwMjBfRVRMWw0Kc2FtcGxlKDE6bnJvdyhjY2RfdmlzaW9uMjAyMF9FVEwpLCAzMDApLA0KYygicmFuZ29fZXRhcmVvIiwgInBhY19zZXhvIiwgIkhvYmJ5X3BwYW50YWxsYSIsICJQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSIpDQpdDQoNCnJlcy5tY2EgPC0gTUNBKHZpc2lvbjIwMjBfY2F0ZWdvcmljYXMsIGdyYXBoID0gRkFMU0UpDQoNCmZ2aXpfbWNhX3ZhcihyZXMubWNhLCBjb2wudmFyID0gImNvbnRyaWIiLCBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwgcmVwZWwgPSBUUlVFKQ0KDQpgYGANCkVsIEJpcGxvdCBkZWwgQW7DoWxpc2lzIGRlIENvcnJlc3BvbmRlbmNpYXMgTcO6bHRpcGxlcyAoQUNNKSBwcm9wb3JjaW9uYSB1bmEgcmVwcmVzZW50YWNpw7NuIHZpc3VhbCBjb25jaXNhIGRlIGPDs21vIHNlIGFncnVwYW4gbGFzIGNhdGVnb3LDrWFzIGRlIGxhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzLCByZXZlbGFuZG8gbGEgZXN0cnVjdHVyYSBzdWJ5YWNlbnRlIGRlIGxhIHBvYmxhY2nDs24uIFNlIG9ic2VydmEgcXVlIGxhIGVkYWQgc2lndWUgc2llbmRvIHVuIGZhY3RvciBvcmdhbml6YWRvciBwcmluY2lwYWwsIGxvZ3JhbmRvIHVuYSBjbGFyYSBzZXBhcmFjacOzbiBlbiBlbCBwbGFubyBmYWN0b3JpYWwgZW50cmUgbG9zIHBhY2llbnRlcyBqw7N2ZW5lcyBlIGluZmFudGlsZXMgeSBlbCBjb25qdW50byBkZSBhZHVsdG9zIHkgYWR1bHRvcyBtYXlvcmVzLiBFc3RlIGVqZSBkZSBzZXBhcmFjacOzbiBwb3IgZXRhcGEgZGUgdmlkYSBlcyBjcnVjaWFsIHBhcmEgZW50ZW5kZXIgbGEgZGlzdHJpYnVjacOzbiBnZW5lcmFsIGRlIGxvcyBwZXJmaWxlcy4NCg0KQWRpY2lvbmFsbWVudGUsIGVsIGFuw6FsaXNpcyB2aXN1YWxpemEgcGVyZmlsZXMgZGlmZXJlbmNpYWRvcyBwb3Igc2V4by4gRWwgZ8OpbmVybyBmZW1lbmlubyB0aWVuZGUgYSBhZ3J1cGFyc2UgZW4gcHJveGltaWRhZCBhIGNhdGVnb3LDrWFzIHF1ZSBpbmRpY2FuIHBlcmZpbGVzIGrDs3ZlbmVzIHkgY29uIHByZWRpc3Bvc2ljacOzbiBnZW7DqXRpY2EuIFBvciBlbCBjb250cmFyaW8sIGVsIGfDqW5lcm8gbWFzY3VsaW5vIHNlIGFzb2NpYSBjb24gZXRhcGFzIGRlIHZpZGEgbcOhcyBhdmFuemFkYXMgeSBsYSBhdXNlbmNpYSBkZSBwcmVkaXNwb3NpY2nDs24gZ2Vuw6l0aWNhLiBFc3RhIGRpc3RpbmNpw7NuIHN1Z2llcmUgcXVlIGVsIHNleG8gbW9kdWxhIGxhIGZvcm1hIGVuIHF1ZSBsb3MgZmFjdG9yZXMgZGUgcmllc2dvIHkgbGFzIGV0YXBhcyBkZSB2aWRhIHNlIG1hbmlmaWVzdGFuIGVuIGxhIG11ZXN0cmEuDQoNCkZpbmFsbWVudGUsIGVsIGJpcGxvdCBkZXN0YWNhIGxhIGluZmx1ZW5jaWEgZGUgbGFzIGNhdGVnb3LDrWFzOiBsYXMgcXVlIHNlIGVuY3VlbnRyYW4gbcOhcyBhbGVqYWRhcyBkZWwgb3JpZ2VuIHNvbiBhcXVlbGxhcyBjb24gbGEgbWF5b3IgY29udHJpYnVjacOzbiBhbCBtb2RlbG8sIHNlw7FhbGFuZG8gbG9zIGZhY3RvcmVzIG3DoXMgaW5mbHV5ZW50ZXMgZW4gbGEgaW50ZXJwcmV0YWNpw7NuLiBFbiBzdSBjb25qdW50bywgZWwgZ3LDoWZpY28gZGVsIEFDTSBubyBzb2xvIHBlcm1pdGUgaWRlbnRpZmljYXIgcGVyZmlsZXMgYmllbiBkZWZpbmlkb3MgKGNsdXN0ZXJzIGRlIGNhdGVnb3LDrWFzKSwgc2lubyBxdWUgdGFtYmnDqW4gZmFjaWxpdGEgZW5vcm1lbWVudGUgbGEgY29tcHJlbnNpw7NuIGludHVpdGl2YSBkZSBsYXMgcmVsYWNpb25lcyBlc3RydWN0dXJhbGVzIG3DoXMgcmVsZXZhbnRlcyBlbnRyZSBsYXMgdmFyaWFibGVzIGFuYWxpemFkYXMuDQoNCiMjICoqRmFzZSA0IFtDb25nbG9tZXJhZG9zXSoqDQoNCiMjIyA0LjEuIE9iamV0aXZvcw0KDQpFbiBlc3RhICoqY3VhcnRhIGV0YXBhKiogZGVsIGVzdHVkaW8gc2UgcHJlc2VudGFyw6FuIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcywgdXRpbGl6YW5kbyBlbCBjb25qdW50byBkZSBkYXRvcyBwcm9jZXNhZG8gZW4gbGFzIGZhc2VzIHByZXZpYXMgKiooMSwgMiB5IDMpKiouIEVsIGVuZm9xdWUgc2UgY2VudHJhcsOhIGVuIGVsICoqYW7DoWxpc2lzIGRlIGNvbmdsb21lcmFkb3MqKiwgYWJhcmNhbmRvIHRhbnRvIHN1IHZlcnNpw7NuIGplcsOhcnF1aWNhIG1lZGlhbnRlIGRlbmRyb2dyYW1hcyBjb21vIGxhIG5vIGplcsOhcnF1aWNhIGNvbiBLLW1lZGlhcy4NCg0KIyMjIDQuMi4gQWdydXBhY2nDs24gSmVyw6FycXVpY2Egey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRWwgUHJvZmVzb3IgLCBlbiBzdSB0cmFiYWpvIChhbCBxdWUgc2UgcHVlZGVuIHJlbWl0aXIgbWVkaWFudGUgZWwgZW5sYWNlKSwgc2XDsWFsYWJhIHF1ZSBsb3MgYXV0b3JlcyBbQEFFRE1EaWF6LU1vcmFsZXMxZWRdLCBiYXPDoW5kb3NlIGVuIGVsIGFuw6FsaXNpcyBkZSAqRXZlcml0dCAoMTk4MCkqIHRpdHVsYWRvICoqQ2x1c3RlciBBbmFseXNpcyoqLCBkZXNjcmliZW4gbG9zIGNvbmdsb21lcmFkb3MgY29tbyAqKnpvbmFzIGNvbnRpbnVhcyoqIGVuIHVuIGVzcGFjaW8gZG9uZGUgc2UgY29uY2VudHJhIHVuYSBhbHRhIGRlbnNpZGFkIGRlIHB1bnRvcywgc2VwYXJhZGFzIHBvciDDoXJlYXMgY29uIG1lbm9yIGRlbnNpZGFkLiBQYXJhIGlkZW50aWZpY2FyIGVzdGFzIGNvbmNlbnRyYWNpb25lcywgc2UgZW1wbGVhbiBkaWZlcmVudGVzIHTDqWNuaWNhcywgZGVzdGFjw6FuZG9zZSBsb3MgbcOpdG9kb3MgamVyw6FycXVpY29zLiBFc3RvcyBpbmljaWFuIGNvbiBlbCAqKmPDoWxjdWxvIGRlIHVuYSBtYXRyaXogZGUgZGlzdGFuY2lhcyoqIGVudHJlIGxvcyBlbGVtZW50b3MgYW5hbGl6YWRvcywgbG8gcXVlIHBlcm1pdGUgYWdydXBhcmxvcyBtZWRpYW50ZSB1biBwcm9jZXNvIGRlICoqYWdsb21lcmFjacOzbioqLiBFc3RlIG3DqXRvZG8gY29taWVuemEgY29uICoqY29uZ2xvbWVyYWRvcyBpbmRpdmlkdWFsZXMqKiB5IGF2YW56YSBoYWNpYSB1biAqKsO6bmljbyBncnVwbyBmaW5hbCoqLiBBIGxvIGxhcmdvIGRlIGVzdGUgcHJvY2Vzbywgc2UgZ2VuZXJhbiBmdXNpb25lcyB5IGRpdmlzaW9uZXMgcXVlIGVzdGFibGVjZW4gamVyYXJxdcOtYXMgYmFzYWRhcyBlbiBzaW1pbGl0dWRlcywgcmVwcmVzZW50YWRhcyBncsOhZmljYW1lbnRlIGEgdHJhdsOpcyBkZSB1biAqKmRlbmRvZ3JhbWEqKi4NCg0KIyMjIyBDYW1wbyBDbGFzaWZpY2Fkb3INCg0KYGBge3IgQ2FtcG9fQ2xhc2lmaWNhZG9yLCBmaWcuYWxpZ249J2NlbnRlcid9DQpjY2RfdmlzaW9uMjAyMF9FVExfcHJvbWVkaW8gPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvSk9TRS9EZXNrdG9wL2dkZC9UUkFCQUpPIEdERC9jZGRfVmlzaW9uMjAyMF9wcm9tZWRpby54bHN4IikNCmhlYWQoYXMuZGF0YS5mcmFtZShjY2RfdmlzaW9uMjAyMF9FVExfcHJvbWVkaW8pKQ0KYGBgDQoNCkxhIHRhYmxhIHJldmVsYSB1bmEgcmVsYWNpw7NuIGludmVyc2EgY2xhcmEgZW50cmUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMgeSBhZ3VkZXphIHZpc3VhbDogbGEgKipQcmltZXJhIEluZmFuY2lhICg2LjclIGNvaG9ydGUpKiogcHJlc2VudGEgbGEgbWVqb3IgQVZfT0QgKDAuNjczKSB5IG1lbm9yIHVzbyBkZSBwYW50YWxsYXMgKiooMC40NmgvZMOtYSkqKiwgbWllbnRyYXMgQWR1bHRvcyAoNDQuMiUgY29ob3J0ZSkgbXVlc3RyYW4gbGEgcGVvciAqKkFWX09EICgwLjUyNCkqKiBjb24gbWF5b3IgZXhwb3NpY2nDs24gKiooMC41MGgvZMOtYSkqKi4gU2Ugb2JzZXJ2YSB1bmEgdGVuZGVuY2lhIGV0YXJpYSBkZXNjZW5kZW50ZSBlbiAqKkFWX09EICgwLjY3MyBpbmZhbmNpYSDihpIgMC41MjQgYWR1bHRvcykqKiwgY29uIGxldmUgcmVjdXBlcmFjacOzbiBlbiBhZHVsdG9zIG1heW9yZXMgKiooMC41MzMpKiosIGFjb21wYcOxYWRhIGRlIGluY3JlbWVudG8gcHJvZ3Jlc2l2byBlbiBob3JhcyBwYW50YWxsYSAqKigwLjQ2aCDihpIgMC41MWgpKiouDQoNCkFjdGl2aWRhZCBmw61zaWNhIHBlcm1hbmVjZSBlc3RhYmxlICoqKH4wLjU0aC9kw61hKSoqIHNpbiBwYXRyw7NuIGNsYXJvLCBzdWdpcmllbmRvIHF1ZSBsYSBleHBvc2ljacOzbiBkaWdpdGFsIGVzIGVsIGZhY3RvciBkb21pbmFudGUgZW4gZXN0ZSBjb250ZXh0by4gRXN0b3MgZGF0b3MgYWdyZWdhZG9zIGNvbmZpcm1hbiBsYSBoaXDDs3Rlc2lzIGNsw61uaWNhICoqKOKGkXBhbnRhbGxhcyDihpIg4oaTQVYpKiogcXVlIGVsIFJMTSBpbmRpdmlkdWFsIG5vIGNhcHR1csOzICoqKFLCsj0wLjAwOCkqKiwgZGViaWRvIGEgYWx0YSB2YXJpYWJpbGlkYWQgaW50cmEtZ3J1cG8uIEltcGxpY2FjacOzbjogRXN0dWRpb3MgZWNvbMOzZ2ljb3MgcG9yIHJhbmdvIGV0YXJpbyBzb24gbcOhcyBzZW5zaWJsZXMgcXVlIGFuw6FsaXNpcyBpbmRpdmlkdWFsZXMgcGFyYSBkZXRlY3RhciBlZmVjdG9zIHBvYmxhY2lvbmFsZXMgZW4gc2FsdWQgdmlzdWFsIGRpZ2l0YWwuDQoNCiMjIyMgRGlzaW1pbGFyaWRhZA0KYGBge3IgRGlzaW1pbGFyaWRhZCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KZGF0YV8gPSBhcy5kYXRhLmZyYW1lKGNjZF92aXNpb24yMDIwX0VUTF9wcm9tZWRpbylbLCAtYygxKV0NCnJvd25hbWVzKGRhdGFfKSA9IHVuY2xhc3MoY2NkX3Zpc2lvbjIwMjBfRVRMX3Byb21lZGlvJFJhbmdvX0V0YXJlbykNCg0KZnZpel9kaXN0KGdldF9kaXN0KGRhdGFfLCBzdGFuZCA9IFQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgZ3JhZGllbnQgPSBsaXN0KGxvdyA9ICIjMDBBRkJCIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICIjRkM0RTA3IikpDQpgYGANCg0KRWwgbWFwYSBkZSBjYWxvciByZXByZXNlbnRhIGxhIGRpc3RhbmNpYSBldWNsaWRpYW5hIGVzdGFuZGFyaXphZGEgZW50cmUgbG9zIHByb21lZGlvcyBkZSBjYWRhIHJhbmdvIGV0YXJpbyAoQVZfT0QsIEFWX09JLCBob3JhcyBkZSBwYW50YWxsYSB5IGFjdGl2aWRhZCBmw61zaWNhKS4gVmFsb3JlcyBjZXJjYW5vcyBhIDAgKHRvbm9zIGJsYW5jb+KAk2F6dWxhZG9zKSBpbmRpY2FuIGdydXBvcyBzaW1pbGFyZXMsIG1pZW50cmFzIHZhbG9yZXMgbcOhcyBhbHRvcyAodG9ub3MgbmFyYW5qYS9yb2pvKSBpbmRpY2FuIGdydXBvcyBtw6FzIGRpc8OtbWlsZXMuDQoNClNlIG9ic2VydmEgcXVlIFByaW1lcmEgSW5mYW5jaWEgcHJlc2VudGEgbGFzIG1heW9yZXMgZGlzaW1pbGl0dWRlcyByZXNwZWN0byBhIEFkdWx0byB5IEFkdWx0byBNYXlvciwgbG8gcXVlIHJlZmxlamEgZGlmZXJlbmNpYXMgbWFyY2FkYXMgZW4gYWd1ZGV6YSB2aXN1YWwgeSBleHBvc2ljacOzbiBhIHBhbnRhbGxhcyBmcmVudGUgYSBlc3RvcyBncnVwb3MsIHF1ZSBjb25jZW50cmFuIG3DoXMgdGllbXBvIGRlIHBhbnRhbGxhIHkgcGVvciBBViBwcm9tZWRpby4gRW4gY29udHJhc3RlLCBsYXMgZGlzdGFuY2lhcyBlbnRyZSBBZHVsdG8sIEFkdWx0byBNYXlvciwgTmnDsWV6IHkgSsOzdmVuZXMgc29uIG3DoXMgYmFqYXMgKGNvbG9yZXMgY2xhcm9zKSwgc3VnaXJpZW5kbyBwZXJmaWxlcyByZWxhdGl2YW1lbnRlIHBhcmVjaWRvcyBlbnRyZSBzw60gY3VhbmRvIHNlIGNvbnNpZGVyYW4gY29uanVudGFtZW50ZSB2aXNpw7NuLCBob3JhcyBkZSBwYW50YWxsYSB5IGFjdGl2aWRhZCBmw61zaWNhLiANCg0KRXN0ZSBwYXRyw7NuIHJlc3BhbGRhIGxhIGlkZWEgZGUgcXVlIGxhIFByaW1lcmEgSW5mYW5jaWEgY29uZm9ybWEgdW4gZ3J1cG8gY2xhcmFtZW50ZSBkaWZlcmVuY2lhZG8sIG1pZW50cmFzIHF1ZSBlbCByZXN0byBkZSByYW5nb3MgY29tcGFydGVuIGNhcmFjdGVyw61zdGljYXMgbcOhcyBob21vZ8OpbmVhcyBlbiBlbCBjb250ZXh0byBkZSBzYWx1ZCB2aXN1YWwgZGlnaXRhbC4NCg0KIyMjIyBPcHRpbWl6YWNpw7NuIGRlIE1vamVuYSB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBVbmnDs24gU2ltcGxlDQpgYGB7ciBVbmlvbl9zaW1wbGUsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmhjX3NpbmdsZSA9IGhjbHVzdChnZXRfZGlzdChkYXRhXywgc3RhbmQgPSBULCBtZXRob2QgPSAiZXVjbGlkZWFuIiksIG1ldGhvZCA9ICJzaW5nbGUiKQ0KDQptb2plbmEgPSAgICAgICAgICAgZnVuY3Rpb24oaGMpew0KICBuX2hkID0gbGVuZ3RoKGhjJGhlaWdodCkNCiAgYWxwX2cgPSAwIDsgYWxwaGEgPSBoYyRoZWlnaHRbbl9oZDoxXQ0KICBmb3IoaSBpbiAxOihuX2hkLTEpKXsNCiAgICBhbHBfZ1tpXSA9IG1lYW4oYWxwaGFbKG5faGQtaSsxKToxXSkrMS4yNSpzZChhbHBoYVsobl9oZC1pKzEpOjFdKQ0KICB9DQogIG5vZyA9IHN1bShhbHBfZzw9IGFscGhhWy1uX2hkXSkgKyAxDQogIHBsb3QoYWxwaGFbLW5faGRdLCBwY2g9MjAsIGNvbD0oYWxwX2c+YWxwaGFbLW5faGRdKSsxLCBtYWluID0gcGFzdGUoIk9wdGltYWwgbnVtYmVyIG9mIGdyb3VwcyA9Iixub2cpLA0KICAgICAgIHlsYWIgPSBleHByZXNzaW9uKGFscGhhW2ddKSwgeGxhYj0iTm9kZXMiKX0NCm1vamVuYShoY19zaW5nbGUpDQpgYGANCg0KRWwgY3JpdGVyaW8gZGUgTW9qZW5hIHNlIGVtcGxlw7MgcGFyYSBkZXRlcm1pbmFyIGRlIGZvcm1hIG9iamV0aXZhIGVsIG7Dum1lcm8gw7NwdGltbyBkZSBncnVwb3MgZW4gbG9zIGRlbmRyb2dyYW1hcyBqZXLDoXJxdWljb3MsIGEgcGFydGlyIGRlbCBhbsOhbGlzaXMgZGUgbGFzIGFsdHVyYXMgZGUgZnVzacOzbi4gQWwgZXZhbHVhciBlbCBlc3RhZMOtc3RpY28gzrHigo1n4oKOIHkgY29tcGFyYXJsbyBjb24gZWwgdW1icmFsIHRlw7NyaWNvLCBzZSBpZGVudGlmaWNhcm9uIGxvcyBwdW50b3MgZG9uZGUgbGFzIGZ1c2lvbmVzIGRlamFuIGRlIHNlciBob21vZ8OpbmVhcy4gRXN0ZSBwcm9jZWRpbWllbnRvIHBlcm1pdGnDsyB0cmFuc2Zvcm1hciBsYSBpbmZvcm1hY2nDs24gdmlzdWFsIGRlbCBkZW5kcm9ncmFtYSBlbiB1biByZXN1bHRhZG8gY3VhbnRpdGF0aXZvLCBmYWNpbGl0YW5kbyBsYSBjb21wYXJhY2nDs24gZW50cmUgbG9zIGRpc3RpbnRvcyBtw6l0b2RvcyBkZSBlbmxhY2UgYXBsaWNhZG9zLg0KDQpMb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MgbXVlc3RyYW4gcXVlIGVsIG7Dum1lcm8gw7NwdGltbyBkZSBjbHVzdGVycyB2YXLDrWEgc2Vnw7puIGVsIG3DqXRvZG8gZGUgZW5sYWNlIHV0aWxpemFkbzogdW4gc29sbyBncnVwbyBlbiBlbCBlbmxhY2Ugc2ltcGxlIHkgZG9zIGdydXBvcyB0YW50byBlbiBlbCBlbmxhY2UgY29tcGxldG8gY29tbyBlbiBlbCBlbmxhY2UgcHJvbWVkaW8uIEVzdGEgZGlmZXJlbmNpYSBpbmRpY2EgcXVlIGxhIGVzdHJ1Y3R1cmEgc3VieWFjZW50ZSBkZSBsb3MgZGF0b3Mgbm8gcHJlc2VudGEgdW5hIHNlZ21lbnRhY2nDs24gZnVlcnRlIHkgZXN0YWJsZSwgc2lubyBxdWUgZGVwZW5kZSBkZSBsYSBmb3JtYSBlbiBxdWUgc2UgbWlkZSBsYSBkaXN0YW5jaWEgZW50cmUgbG9zIGdydXBvcywgbG8gcXVlIGFudGljaXBhIGxhIHByZXNlbmNpYSBkZSBhZ3J1cGFjaW9uZXMgZMOpYmlsZXMgbyB0cmFuc2ljaW9uZXMgZ3JhZHVhbGVzIGVudHJlIHJhbmdvcyBldGFyaW9zLg0KDQojIyMjIyBVbmnDs24gQ29tcGxldGENCmBgYHtyIFVuaW9uX0NvbXBsZXRhLCBmaWcuYWxpZ249J2NlbnRlcid9DQpoY19jb21wbGV0ZSA9IGhjbHVzdChnZXRfZGlzdChkYXRhXywgc3RhbmQgPSBULCBtZXRob2QgPSAiZXVjbGlkZWFuIiksIG1ldGhvZCA9ICJjb21wbGV0ZSIpDQoNCm1vamVuYSA9IGZ1bmN0aW9uKGhjKXsNCiAgbl9oZCA9IGxlbmd0aChoYyRoZWlnaHQpDQogIGFscF9nID0gMCA7IGFscGhhID0gaGMkaGVpZ2h0W25faGQ6MV0NCiAgZm9yKGkgaW4gMToobl9oZC0xKSl7DQogICAgYWxwX2dbaV0gPSBtZWFuKGFscGhhWyhuX2hkLWkrMSk6MV0pKzEuMjUqc2QoYWxwaGFbKG5faGQtaSsxKToxXSkNCiAgfQ0KICBub2cgPSBzdW0oYWxwX2c8PSBhbHBoYVstbl9oZF0pICsgMQ0KICBwbG90KGFscGhhWy1uX2hkXSwgcGNoPTIwLCBjb2w9KGFscF9nPmFscGhhWy1uX2hkXSkrMSwgbWFpbiA9IHBhc3RlKCJPcHRpbWFsIG51bWJlciBvZiBncm91cHMgPSIsbm9nKSwNCiAgICAgICB5bGFiID0gZXhwcmVzc2lvbihhbHBoYVtnXSksIHhsYWI9Ik5vZGVzIil9DQoNCm1vamVuYShoY19jb21wbGV0ZSkNCmBgYA0KDQpFbCBjcml0ZXJpbyBkZSBNb2plbmEgc2UgZW1wbGXDsyBwYXJhIGRldGVybWluYXIgZGUgZm9ybWEgb2JqZXRpdmEgZWwgbsO6bWVybyDDs3B0aW1vIGRlIGdydXBvcyBlbiBsb3MgZGVuZHJvZ3JhbWFzIGplcsOhcnF1aWNvcywgYSBwYXJ0aXIgZGVsIGFuw6FsaXNpcyBkZSBsYXMgYWx0dXJhcyBkZSBmdXNpw7NuLiBBbCBldmFsdWFyIGVsIGVzdGFkw61zdGljbyDOseKCjWfigo4geSBjb21wYXJhcmxvIGNvbiBlbCB1bWJyYWwgdGXDs3JpY28sIHNlIGlkZW50aWZpY2Fyb24gbG9zIHB1bnRvcyBkb25kZSBsYXMgZnVzaW9uZXMgZGVqYW4gZGUgc2VyIGhvbW9nw6luZWFzLiBFc3RlIHByb2NlZGltaWVudG8gcGVybWl0acOzIHRyYW5zZm9ybWFyIGxhIGluZm9ybWFjacOzbiB2aXN1YWwgZGVsIGRlbmRyb2dyYW1hIGVuIHVuIHJlc3VsdGFkbyBjdWFudGl0YXRpdm8sIGZhY2lsaXRhbmRvIGxhIGNvbXBhcmFjacOzbiBlbnRyZSBsb3MgZGlzdGludG9zIG3DqXRvZG9zIGRlIGVubGFjZSBhcGxpY2Fkb3MuDQoNCkxvcyByZXN1bHRhZG9zIG9idGVuaWRvcyBtdWVzdHJhbiBxdWUgZWwgbsO6bWVybyDDs3B0aW1vIGRlIGNsdXN0ZXJzIHZhcsOtYSBzZWfDum4gZWwgbcOpdG9kbyBkZSBlbmxhY2UgdXRpbGl6YWRvOiB1biBzb2xvIGdydXBvIGVuIGVsIGVubGFjZSBzaW1wbGUgeSBkb3MgZ3J1cG9zIHRhbnRvIGVuIGVsIGVubGFjZSBjb21wbGV0byBjb21vIGVuIGVsIGVubGFjZSBwcm9tZWRpby4gRXN0YSBkaWZlcmVuY2lhIGluZGljYSBxdWUgbGEgZXN0cnVjdHVyYSBzdWJ5YWNlbnRlIGRlIGxvcyBkYXRvcyBubyBwcmVzZW50YSB1bmEgc2VnbWVudGFjacOzbiBmdWVydGUgeSBlc3RhYmxlLCBzaW5vIHF1ZSBkZXBlbmRlIGRlIGxhIGZvcm1hIGVuIHF1ZSBzZSBtaWRlIGxhIGRpc3RhbmNpYSBlbnRyZSBsb3MgZ3J1cG9zLCBsbyBxdWUgYW50aWNpcGEgbGEgcHJlc2VuY2lhIGRlIGFncnVwYWNpb25lcyBkw6liaWxlcyBvIHRyYW5zaWNpb25lcyBncmFkdWFsZXMgZW50cmUgcmFuZ29zIGV0YXJpb3MuDQoNCiMjIyMjIFVuacOzbiBQcm9tZWRpbw0KYGBge3IgVW5pb25fUHJvbWVkaW8sIGZpZy5hbGlnbj0nY2VudGVyJ30NCmhjX2F2ZXJhZ2UgPSBoY2x1c3QoZ2V0X2Rpc3QoZGF0YV8sIHN0YW5kID0gVCwgbWV0aG9kID0gImV1Y2xpZGVhbiIpLCBtZXRob2QgPSAiYXZlcmFnZSIpDQoNCm1vamVuYSA9IGZ1bmN0aW9uKGhjKXsNCiAgbl9oZCA9IGxlbmd0aChoYyRoZWlnaHQpDQogIGFscF9nID0gMCA7IGFscGhhID0gaGMkaGVpZ2h0W25faGQ6MV0NCiAgZm9yKGkgaW4gMToobl9oZC0xKSl7DQogICAgYWxwX2dbaV0gPSBtZWFuKGFscGhhWyhuX2hkLWkrMSk6MV0pKzEuMjUqc2QoYWxwaGFbKG5faGQtaSsxKToxXSkNCiAgfQ0KICBub2cgPSBzdW0oYWxwX2c8PSBhbHBoYVstbl9oZF0pICsgMQ0KICBwbG90KGFscGhhWy1uX2hkXSwgcGNoPTIwLCBjb2w9KGFscF9nPmFscGhhWy1uX2hkXSkrMSwgbWFpbiA9IHBhc3RlKCJPcHRpbWFsIG51bWJlciBvZiBncm91cHMgPSIsbm9nKSwNCiAgICAgICB5bGFiID0gZXhwcmVzc2lvbihhbHBoYVtnXSksIHhsYWI9Ik5vZGVzIil9DQoNCm1vamVuYShoY19hdmVyYWdlKQ0KDQptb2plbmEoaGNfYXZlcmFnZSkNCg0KYGBgDQoNCkVsIGNyaXRlcmlvIGRlIE1vamVuYSBzZSBlbXBsZcOzIHBhcmEgZGV0ZXJtaW5hciBkZSBmb3JtYSBvYmpldGl2YSBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgZ3J1cG9zIGVuIGxvcyBkZW5kcm9ncmFtYXMgamVyw6FycXVpY29zLCBhIHBhcnRpciBkZWwgYW7DoWxpc2lzIGRlIGxhcyBhbHR1cmFzIGRlIGZ1c2nDs24uIEFsIGV2YWx1YXIgZWwgZXN0YWTDrXN0aWNvIM6x4oKNZ+KCjiB5IGNvbXBhcmFybG8gY29uIGVsIHVtYnJhbCB0ZcOzcmljbywgc2UgaWRlbnRpZmljYXJvbiBsb3MgcHVudG9zIGRvbmRlIGxhcyBmdXNpb25lcyBkZWphbiBkZSBzZXIgaG9tb2fDqW5lYXMuIEVzdGUgcHJvY2VkaW1pZW50byBwZXJtaXRpw7MgdHJhbnNmb3JtYXIgbGEgaW5mb3JtYWNpw7NuIHZpc3VhbCBkZWwgZGVuZHJvZ3JhbWEgZW4gdW4gcmVzdWx0YWRvIGN1YW50aXRhdGl2bywgZmFjaWxpdGFuZG8gbGEgY29tcGFyYWNpw7NuIGVudHJlIGxvcyBkaXN0aW50b3MgbcOpdG9kb3MgZGUgZW5sYWNlIGFwbGljYWRvcy4NCg0KTG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIG11ZXN0cmFuIHF1ZSBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgY2x1c3RlcnMgdmFyw61hIHNlZ8O6biBlbCBtw6l0b2RvIGRlIGVubGFjZSB1dGlsaXphZG86IHVuIHNvbG8gZ3J1cG8gZW4gZWwgZW5sYWNlIHNpbXBsZSB5IGRvcyBncnVwb3MgdGFudG8gZW4gZWwgZW5sYWNlIGNvbXBsZXRvIGNvbW8gZW4gZWwgZW5sYWNlIHByb21lZGlvLiBFc3RhIGRpZmVyZW5jaWEgaW5kaWNhIHF1ZSBsYSBlc3RydWN0dXJhIHN1YnlhY2VudGUgZGUgbG9zIGRhdG9zIG5vIHByZXNlbnRhIHVuYSBzZWdtZW50YWNpw7NuIGZ1ZXJ0ZSB5IGVzdGFibGUsIHNpbm8gcXVlIGRlcGVuZGUgZGUgbGEgZm9ybWEgZW4gcXVlIHNlIG1pZGUgbGEgZGlzdGFuY2lhIGVudHJlIGxvcyBncnVwb3MsIGxvIHF1ZSBhbnRpY2lwYSBsYSBwcmVzZW5jaWEgZGUgYWdydXBhY2lvbmVzIGTDqWJpbGVzIG8gdHJhbnNpY2lvbmVzIGdyYWR1YWxlcyBlbnRyZSByYW5nb3MgZXRhcmlvcy4NCg0KIyMjIyBEZW5kcm9ncmFtYXMgT3B0aW1pemFkb3Mgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgRW5sYWNlIFNpbXBsZQ0KYGBge3IgRW5sYWNlX1NpbXBsZSwgZmlnLmFsaWduPSdjZW50ZXInfQ0Kc3VwcHJlc3NXYXJuaW5ncyhmdml6X2RlbmQoaGNfc2luZ2xlLCBrID0gMywgY2V4ID0gMC41LCBrX2NvbG9ycyA9ICJucGciLCBjb2xvcl9sYWJlbHNfYnlfayA9IFQsIHJlY3QgPSBUKSkNCg0KYGBgDQpFbiBlbCBkZW5kcm9ncmFtYSBjb25zdHJ1aWRvIG1lZGlhbnRlIGVubGFjZSBzaW1wbGUsIGVsIGNyaXRlcmlvIGRlIE1vamVuYSBubyBkZXRlY3TDsyB1biBzYWx0byBzaWduaWZpY2F0aXZvIGVuIGxhcyBhbHR1cmFzIGRlIGZ1c2nDs24sIGxvIHF1ZSBjb25kdWpvIGEgdW4gbsO6bWVybyDDs3B0aW1vIGRlIGdydXBvcyBpZ3VhbCBhIDEuIEdyw6FmaWNhbWVudGUsIGVzdG8gc2UgcmVmbGVqYSBlbiB1bmEgZXN0cnVjdHVyYSBjb250aW51YSwgZG9uZGUgbG9zIHJhbmdvcyBldGFyaW9zIHNlIHZhbiB1bmllbmRvIGRlIG1hbmVyYSBwcm9ncmVzaXZhIHNpbiBydXB0dXJhcyBhYnJ1cHRhcyBlbiBlbCBlamUgZGUgYWx0dXJhLCBjYXJhY3RlcsOtc3RpY2EgdMOtcGljYSBkZWwgZWZlY3RvIGRlIGVuY2FkZW5hbWllbnRvIHByb3BpbyBkZSBlc3RlIG3DqXRvZG8uDQoNCkRlc2RlIGxhIGludGVycHJldGFjacOzbiBkZWwgZ3LDoWZpY28sIGVsIHJlc3VsdGFkbyBpbmRpY2EgcXVlIG5vIGV4aXN0ZSBldmlkZW5jaWEgZGUgdW5hIHNlZ21lbnRhY2nDs24gbmF0dXJhbCBlbnRyZSBsb3MgcmFuZ29zIGV0YXJpb3MgYW5hbGl6YWRvcy4gTGEgZXN0cnVjdHVyYSBvYnNlcnZhZGEgc3VnaWVyZSBxdWUgbGFzIGRpZmVyZW5jaWFzIHNvbiBncmFkdWFsZXMgeSBubyBlc3RydWN0dXJhbGVzLCBsbyBxdWUgZXhwbGljYSBwb3IgcXXDqSBlbCBhbGdvcml0bW8gdGVybWluYSBpbnRlZ3JhbmRvIHRvZG9zIGxvcyBlbGVtZW50b3MgZW4gdW4gw7puaWNvIGNsw7pzdGVyLiBFc3RlIGhhbGxhemdvIGVzIGNvaGVyZW50ZSBjb24gbGEgaWRlYSBkZSB1bmEgZGlzaW1pbGFyaWRhZCBzdWF2ZSBlbnRyZSBlZGFkZXMsIHNpbiBmcm9udGVyYXMgY2xhcmFzIHF1ZSBqdXN0aWZpcXVlbiB1bmEgcGFydGljacOzbiBlbiBncnVwb3MgZGlmZXJlbmNpYWRvcy4NCg0KIyMjIyMgRW5sYWNlIENvbXBsZXRvDQpgYGB7ciBFbmxhY2VfQ29tcGxldG8sIGZpZy5hbGlnbj0nY2VudGVyJ30NCmZ2aXpfZGVuZChoY19jb21wbGV0ZSwgayA9IDMsIGNleCA9IDAuNSwga19jb2xvcnMgPSAibnBnIiwgY29sb3JfbGFiZWxzX2J5X2sgPSBULCByZWN0ID0gVCkNCg0KYGBgDQpFbiBlbCBjYXNvIGRlbCBlbmxhY2UgY29tcGxldG8sIGVsIGNyaXRlcmlvIGRlIE1vamVuYSBpZGVudGlmaWPDsyB1biBzYWx0byBjbGFybyBlbiBsYXMgYWx0dXJhcyBkZSBmdXNpw7NuIGFsIHBhc2FyIGRlIGRvcyBhIHVuIHNvbG8gY2zDunN0ZXIsIGRldGVybWluYW5kbyBjb21vIMOzcHRpbW8gdW4gbsO6bWVybyBkZSBncnVwb3MgaWd1YWwgYSAyLiBFc3RlIHJlc3VsdGFkbyBzZSByZWZsZWphIHZpc3VhbG1lbnRlIGVuIGVsIGRlbmRyb2dyYW1hLCBkb25kZSBlbCBpbmNyZW1lbnRvIGVuIGVsIGVqZSBkZSBhbHR1cmEgZXMgbcOhcyBwcm9udW5jaWFkbyBxdWUgZW4gZWwgZW5sYWNlIHNpbXBsZSwgaW5kaWNhbmRvIHVuYSBtYXlvciByZXNpc3RlbmNpYSBhIGZ1c2lvbmFyIGdydXBvcyBoZXRlcm9nw6luZW9zLg0KDQpMYSBpbnRlcnByZXRhY2nDs24gZGVsIGdyw6FmaWNvIHN1Z2llcmUgbGEgZXhpc3RlbmNpYSBkZSBkb3MgbWFjcm9ncnVwb3MgZMOpYmlsbWVudGUgZGlmZXJlbmNpYWRvcywgZG9uZGUgbGEgUHJpbWVyYSBJbmZhbmNpYSBzZSBzZXBhcmEgdGVtcHJhbmFtZW50ZSBkZWwgcmVzdG8gZGUgbG9zIHJhbmdvcyBldGFyaW9zLiBTaW4gZW1iYXJnbywgZGVudHJvIGRlbCBzZWd1bmRvIGNsw7pzdGVyIOKAlHF1ZSBhZ3J1cGEgTmnDsWV6LCBKw7N2ZW5lcywgQWR1bHRvcyB5IEFkdWx0b3MgTWF5b3Jlc+KAlCBubyBzZSBvYnNlcnZhbiBzdWJlc3RydWN0dXJhcyBpbnRlcm5hcyBlc3RhYmxlcy4gUG9yIHRhbnRvLCBhdW5xdWUgZWwgcmVzdWx0YWRvIGN1YW50aXRhdGl2byBzZcOxYWxhIGRvcyBncnVwb3MsIGxhIHNlcGFyYWNpw7NuIHJlc3BvbmRlIHByaW5jaXBhbG1lbnRlIGEgdW5hIGRpZmVyZW5jaWEgbWFyY2FkYSBlbiBsb3MgZXh0cmVtb3MgZGVsIGNpY2xvIGRlIHZpZGEgbcOhcyBxdWUgYSB1bmEgc2VnbWVudGFjacOzbiBpbnRlcm5hIHJvYnVzdGEuDQoNCiMjIyMjIEVubGFjZSBQcm9tZWRpbw0KYGBge3IgRW5sYWNlX1Byb21lZGlvLCBmaWcuYWxpZ249J2NlbnRlcid9DQpmdml6X2RlbmQoaGNfYXZlcmFnZSwgayA9IDMsIGNleCA9IDAuNSwga19jb2xvcnMgPSAibnBnIiwgY29sb3JfbGFiZWxzX2J5X2sgPSBULCByZWN0ID0gVCkNCmBgYA0KRWwgZGVuZHJvZ3JhbWEgb2J0ZW5pZG8gbWVkaWFudGUgZW5sYWNlIHByb21lZGlvIGNvbmZpcm3DsyBsb3MgcmVzdWx0YWRvcyBkZWwgZW5sYWNlIGNvbXBsZXRvLCB5YSBxdWUgZWwgY3JpdGVyaW8gZGUgTW9qZW5hIHZvbHZpw7MgYSBzZcOxYWxhciB1biBuw7ptZXJvIMOzcHRpbW8gZGUgZ3J1cG9zIGlndWFsIGEgMi4gQWwgdXRpbGl6YXIgbGEgZGlzdGFuY2lhIHByb21lZGlvIGVudHJlIGxvcyBlbGVtZW50b3MgZGUgbG9zIGdydXBvcywgZXN0ZSBtw6l0b2RvIHN1YXZpemEgbGFzIGZ1c2lvbmVzIGV4dHJlbWFzIHkgZ2VuZXJhIHVuIHBhdHLDs24gaW50ZXJtZWRpbyBxdWUgbWFudGllbmUgdW4gc2FsdG8gcmVsZXZhbnRlIGVuIGxhcyBhbHR1cmFzLCBzdWZpY2llbnRlIHBhcmEganVzdGlmaWNhciBsYSBiaXBhcnRpY2nDs24uDQoNCkRlc2RlIGxhIGludGVycHJldGFjacOzbiBncsOhZmljYSwgc2Ugb2JzZXJ2YSBudWV2YW1lbnRlIHF1ZSBsYSBQcmltZXJhIEluZmFuY2lhIHNlIHNlcGFyYSBwcmltZXJvLCBtaWVudHJhcyBxdWUgZWwgcmVzdG8gZGUgbG9zIHJhbmdvcyBldGFyaW9zIHNlIGFncnVwYSBkZSBmb3JtYSBwcm9ncmVzaXZhIHkgY29udGludWEuIEVsIHJlc3VsdGFkbyByZWZ1ZXJ6YSBsYSBpZGVhIGRlIHF1ZSBsYSDDum5pY2Egc2VwYXJhY2nDs24gY29uc2lzdGVudGUgZW4gbG9zIGRhdG9zIGVzIGVudHJlIGV0YXBhcyBtdXkgdGVtcHJhbmFzIHkgZWwgcmVzdG8gZGVsIGNpY2xvIHZpdGFsLCBzaW4gcXVlIGVtZXJqYW4gY2zDunN0ZXJlcyBhZGljaW9uYWxlcyBlc3RhYmxlcy4gRXN0byBjb25maXJtYSBxdWUgbGEgZXN0cnVjdHVyYSBkZSBsb3MgZGF0b3MgZXMgZMOpYmlsbWVudGUgc2VnbWVudGFkYSB5IGRvbWluYWRhIHBvciByZWxhY2lvbmVzIGdyYWR1YWxlcy4NCg0KIyMjIDQuMy4gQWdydXBhY2nDs24gTm8tSmVyw6FycXVpY2Egey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KUGFyYSB1bmEgYWRlY3VhZGEgdmlzdWFsaXphY2nDs24gZGUgbG9zIGRhdG9zIHkgY29uIGZpbmVzIGV4Y2x1c2l2YW1lbnRlIGFjYWTDqW1pY29zLCBlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMS4yXSgjc2VjMS4yKSBzZSB1dGlsaXphcsOhIGRpcmVjdGFtZW50ZSBjb24gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIHByaW5jaXBhbGVzOiAqKmVkYWRfcGFjaWVudGUqKiwgKipBVl9PRCoqLCAqKkFWX09JKiosICoqSG9yYXNfcGFudGFsbGFfZGlhKiogeSAqKkhvcmFzX2FmKiouDQoNCg0KIyMjIyBLLcOTcHRpbW8gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgRWxib3cNCmBgYHtyIEVsYm93LCBmaWcuYWxpZ249J2NlbnRlcid9DQpmdml6X25iY2x1c3QoZGF0YV8sIGttZWFucywgbWV0aG9kID0gIndzcyIsIGsubWF4ID0gMykgKyANCmdlb21fdmxpbmUoeGludGVyY2VwdCA9IDMsIGxpbmV0eXBlID0gMikNCmBgYA0KRWwgZ3LDoWZpY28gZGVsIG3DqXRvZG8gZGVsIGNvZG8gbXVlc3RyYSBsYSBldm9sdWNpw7NuIGRlIGxhICoqc3VtYSBkZSBjdWFkcmFkb3MgaW50cmHigJNjbMO6c3RlciAoV1NTKSoqIGVuIGZ1bmNpw7NuIGRlbCBuw7ptZXJvIGRlIGNsw7pzdGVyZXMgXChrXCkuIFNlIG9ic2VydmEgdW5hIGNhw61kYSBtYXJjYWRhIGRlbCBXU1MgYWwgcGFzYXIgZGUgXChrID0gMVwpIGEgXChrID0gMlwpLCBzZWd1aWRhIGRlIHVuYSByZWR1Y2Npw7NuIGFkaWNpb25hbCBhbCBjb25zaWRlcmFyIFwoayA9IDNcKS4gQSBwYXJ0aXIgZGUgZXN0ZSBwdW50bywgbGEgcGVuZGllbnRlIGRlIGxhIGN1cnZhIHNlIGVzdGFiaWxpemEgeSBsYXMgbWVqb3JhcyBhbCBpbmNyZW1lbnRhciBcKGtcKSBzb24gbWFyZ2luYWxlcywgbG8gcXVlIGluZGljYSByZW5kaW1pZW50b3MgZGVjcmVjaWVudGVzIGFsIGF1bWVudGFyIGVsIG7Dum1lcm8gZGUgY2zDunN0ZXJlcy4NCg0KTGEgcHJlc2VuY2lhIGRlbCDigJxjb2Rv4oCdIGVuIFwoayA9IDNcKSwgcmVzYWx0YWRvIHBvciB1bmEgbMOtbmVhIHZlcnRpY2FsIGRpc2NvbnRpbnVhLCBzdWdpZXJlIHF1ZSBlc3RhIHBhcnRpY2nDs24gb2ZyZWNlIHVuICoqZXF1aWxpYnJpbyBhZGVjdWFkbyBlbnRyZSBjb21wbGVqaWRhZCBkZWwgbW9kZWxvIHkgY2FwYWNpZGFkIGV4cGxpY2F0aXZhKiouIEVuIG90cmFzIHBhbGFicmFzLCAqKnRyZXMgY2zDunN0ZXJlcyBjYXB0dXJhbiBsYSBlc3RydWN0dXJhIHByaW5jaXBhbCBkZSBsb3MgZGF0b3Mgc2luIGluY3VycmlyIGVuIHNvYnJlc2VnbWVudGFjacOzbioqLCBwcm9wb3JjaW9uYW5kbyB1bmEgc29sdWNpw7NuIMOzcHRpbWEgZGVzZGUgZWwgcHVudG8gZGUgdmlzdGEgZGUgbGEgY29tcGFjaWRhZCBpbnRlcm5hLg0KDQojIyMjIyBTaWxob3VldHRlDQpgYGB7ciBTaWxob3VldHRlLGZpZy5hbGlnbj0nY2VudGVyJ30NCm5fZmlsYXMgPC0gbnJvdyhkYXRhXykNCmtfbWF4IDwtIG1pbig1LCBuX2ZpbGFzIC0gMSkgIyBBanVzdGEgc2Vnw7puIHR1cyBkYXRvcw0KZnZpel9uYmNsdXN0KHNjYWxlKGRhdGFfKSwga21lYW5zLCBtZXRob2QgPSAic2lsaG91ZXR0ZSIsIGsubWF4ID0ga19tYXgpDQpgYGANCg0KRWwgZ3LDoWZpY28gY29ycmVzcG9uZGllbnRlIGEgSy1NZWFucyBjb24gXChrID0gMlwpIHJldmVsYSB1bmEgZXN0cnVjdHVyYSBtw6FzIGNvbXBhY3RhLCBkb25kZSBsb3MgaW5kaXZpZHVvcyBzZSBhZ3J1cGFuIGVuICoqZG9zIGdyYW5kZXMgY29uanVudG9zKiogYWxyZWRlZG9yIGRlIHN1cyByZXNwZWN0aXZvcyBjZW50cm9pZGVzLiBBbCBpZ3VhbCBxdWUgZW4gZWwgY2FzbyBhbnRlcmlvciwgbG9zIGVqZXMgRGltMSAoMjMuMyAlKSB5IERpbTIgKDIyLjIgJSkgY29uY2VudHJhbiB1bmEgZnJhY2Npw7NuIGltcG9ydGFudGUgZGUgbGEgdmFyaWFiaWxpZGFkIHRvdGFsLCBsbyBxdWUgcGVybWl0ZSB1bmEgdmlzdWFsaXphY2nDs24gY2xhcmEgZGUgbGEgc2VwYXJhY2nDs24gZW50cmUgZ3J1cG9zLg0KDQpJbnRlcnByZXRhdGl2YW1lbnRlLCBlc3RhIHNvbHVjacOzbiByZWZsZWphIHVuYSAqKmJpcGFydGljacOzbiBkb21pbmFudGUgZGUgbGEgcG9ibGFjacOzbioqLCBjb24gZG9zIHBlcmZpbGVzIGFtcGxpb3MgeSByZWxhdGl2YW1lbnRlIGJpZW4gZGVmaW5pZG9zLiBMYSByZWR1Y2Npw7NuIGRlbCBuw7ptZXJvIGRlIGNsw7pzdGVyZXMgZGlzbWludXllIGVsIHNvbGFwYW1pZW50byBpbnRlcm5vIHkgZmF2b3JlY2UgdW5hIGxlY3R1cmEgbcOhcyBlc3RhYmxlIHkgcGFyc2ltb25pb3NhIGRlIGxhIGVzdHJ1Y3R1cmEgZGUgbG9zIGRhdG9zLiBFc3RlIHJlc3VsdGFkbyBlcyBjb2hlcmVudGUgY29uIG1lZGlkYXMgY29tbyBlbCAqKsOtbmRpY2UgZGUgc2lsdWV0YSoqLCBxdWUgdGllbmRlbiBhIGZhdm9yZWNlciBzb2x1Y2lvbmVzIGNvbiBtZW5vciBuw7ptZXJvIGRlIGdydXBvcyBjdWFuZG8gbGEgY29oZXNpw7NuIGludGVybmEgeSBsYSBzZXBhcmFjacOzbiBlbnRyZSBjbMO6c3RlcmVzIHNvbiBtw6FzIGNsYXJhcy4NCg0KIyMjIyMgR2FwIFN0YXRpc3RpYw0KYGBge3IgR2FwX1N0YXRpc3RpYyxmaWcuYWxpZ249J2NlbnRlcid9DQpzdXBwcmVzc1dhcm5pbmdzKGZ2aXpfbmJjbHVzdChzY2FsZShkYXRhXyksIGttZWFucywgbWV0aG9kID0gImdhcF9zdGF0Iiwgay5tYXggPSBrX21heCwgbmJvb3QgPSA1MCkpDQpgYGANCkxhIGdyw6FmaWNhIGNvcnJlc3BvbmRpZW50ZSBhbCBtw6l0b2RvIEdhcCBTdGF0aXN0aWMgc2UgZW1wbGVhIHBhcmEgbGEgZGV0ZXJtaW5hY2nDs24gZGVsIG7Dum1lcm8gw7NwdGltbyBkZSBjbMO6c3RlcmVzLCBtZWRpYW50ZSBsYSBjb21wYXJhY2nDs24gZW50cmUgbGEgZXN0cnVjdHVyYSBvYnNlcnZhZGEgZW4gbG9zIGRhdG9zIHJlYWxlcyB5IHVuYSBkaXN0cmlidWNpw7NuIGRlIHJlZmVyZW5jaWEgZ2VuZXJhZGEgZGUgZm9ybWEgYWxlYXRvcmlhLiBFc3RlIGVuZm9xdWUgZXZhbMO6YSBsYSBkaWZlcmVuY2lhLCBkZW5vbWluYWRhIGdhcCwgZW50cmUgbGEgZGlzcGVyc2nDs24gaW50cmFncnVwbyBkZSBsb3MgZGF0b3Mgb3JpZ2luYWxlcyB5IGxhIGRpc3BlcnNpw7NuIGVzcGVyYWRhIGJham8gdW4gZXNjZW5hcmlvIGRlIGFsZWF0b3JpZWRhZC4NCg0KTG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIGluZGljYW4gcXVlIGVsIHZhbG9yIG3DoXhpbW8gZGVsIEdhcCBTdGF0aXN0aWMgc2UgcHJlc2VudGEgZW4gdW4gw7puaWNvIGNsw7pzdGVyLCBsbyBxdWUgc3VnaWVyZSBxdWUgbG9zIGRhdG9zIGFuYWxpemFkb3Mgbm8gZXZpZGVuY2lhbiB1bmEgc2VwYXJhY2nDs24gbmF0dXJhbCBzdWZpY2llbnRlbWVudGUgbWFyY2FkYSBxdWUganVzdGlmaXF1ZSBzdSBzZWdtZW50YWNpw7NuIGVuIG3Dumx0aXBsZXMgZ3J1cG9zLiBEZXNkZSB1biBwdW50byBkZSB2aXN0YSBlc3RhZMOtc3RpY28sIGVzdGUgbcOpdG9kbyBzZcOxYWxhIHF1ZSBsYSBlc3RydWN0dXJhIGRlIGxvcyBkYXRvcyBzZSBjb21wb3J0YSBkZSBtYW5lcmEgcmVsYXRpdmFtZW50ZSBob21vZ8OpbmVhLg0KDQojIyMjIyBNYWpvcml0eSBSdWxlDQpgYGB7ciBNYWpvcml0eV9SdWxlLCBmaWcuYWxpZ249J2NlbnRlcid9DQpsaWJyYXJ5KE5iQ2x1c3QpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQoNCiMgUHJlcGFyYWNpw7NuIHJvYnVzdGEgZGUgZGF0b3MgKDIwMCByZWdpc3Ryb3MgY29tbyBlbiB0dSBoaXN0b3JpYWwpDQpzZXQuc2VlZCg3ODA3MjkpDQpkYXRhXyA8LSBjY2RfdmlzaW9uMjAyMF9FVExbDQogIHNhbXBsZSgxOm5yb3coY2NkX3Zpc2lvbjIwMjBfRVRMKSwgMjAwKSwNCiAgYygiZWRhZF9wYWNpZW50ZSIsICJBVl9PRCIsICJBVl9PSSIsICJIb3Jhc19wZCIsICJIb3Jhc19hZiIpDQpdDQoNCiMgTGltcGllemEgYXV0b23DoXRpY2EgcGFyYSBldml0YXIgVFNTIGluZGVmaW5pdGUNCmRhdGFfY2xlYW4gPC0gbmEub21pdChkYXRhXykNCmRhdGFfY2xlYW4gPC0gZGF0YV9jbGVhblssIGFwcGx5KGRhdGFfY2xlYW4sIDIsIHZhciwgbmEucm09VFJVRSkgPiAxZS04XSAgIyBFbGltaW5hIGNvbnN0YW50ZXMNCmRhdGFfc2NhbGVkIDwtIHNjYWxlKGRhdGFfY2xlYW4pDQpuX2ZpbGFzIDwtIG5yb3coZGF0YV9zY2FsZWQpDQprX21heCA8LSBtaW4oNSwgbl9maWxhcyAtIDEpICAjIEzDrW1pdGUgc2VndXJvDQoNCiMgRsOzcm11bGEgYWRhcHRhZGEgcXVlIFNJRU1QUkUgZnVuY2lvbmENCmJlc3RfayA8LSBzdXBwcmVzc1dhcm5pbmdzKA0KICBOYkNsdXN0KGRhdGEgPSBkYXRhX3NjYWxlZCwgDQogICAgICAgICAgZGlzcyA9IE5VTEwsIA0KICAgICAgICAgIGRpc3RhbmNlID0gImV1Y2xpZGVhbiIsIA0KICAgICAgICAgIG1pbi5uYyA9IDIsIA0KICAgICAgICAgIG1heC5uYyA9IGtfbWF4LCANCiAgICAgICAgICBtZXRob2QgPSAia21lYW5zIikNCikkQmVzdC5uYw0KDQpwcmludChwYXN0ZSgiTsO6bWVybyDDs3B0aW1vIGRlIGNsw7pzdGVyZXM6IiwgYmVzdF9rKSkNCg0KYGBgDQoNCkxvcyBkaWFncmFtYXMgbW9zdHJhZG9zIHNlIHV0aWxpemFuIHBhcmEgZGV0ZXJtaW5hciBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgY2zDunN0ZXJlcyBlbiB1biBhbsOhbGlzaXMgZGUgYWdydXBhbWllbnRvIGNvbiBrLW1lYW5zLiBFbiBlbGxvcywgZWwgZWplIGhvcml6b250YWwgcmVwcmVzZW50YSBlbCBuw7ptZXJvIGRlIGNsw7pzdGVyZXMgeSBlbCBlamUgdmVydGljYWwgZGlzdGludG9zIMOtbmRpY2VzIGRlIHZhbGlkYWNpw7NuIGVzdGFkw61zdGljYS4NCg0KRWwgw61uZGljZSBkZSBIdWJlcnQgZXZhbMO6YSBsYSBzZXBhcmFjacOzbiBlbnRyZSBsb3MgY2zDunN0ZXJlcy4gU3UgZ3LDoWZpY28gcHJpbmNpcGFsIG11ZXN0cmEgY8OzbW8gY2FtYmlhIGVsIMOtbmRpY2UgYWwgYXVtZW50YXIgZWwgbsO6bWVybyBkZSBncnVwb3MsIG1pZW50cmFzIHF1ZSBlbCBncsOhZmljbyBkZSBzZWd1bmRhcyBkaWZlcmVuY2lhcyBwZXJtaXRlIGlkZW50aWZpY2FyIHVuIGNhbWJpbyBzaWduaWZpY2F0aXZvIHF1ZSBpbmRpY2EgZWwgbsO6bWVybyBkZSBjbMO6c3RlcmVzIG3DoXMgYWRlY3VhZG8uIEVsIERpbmRleCBtaWRlIGxhIGNvbXBhY2lkYWQgeSBkaWZlcmVuY2lhY2nDs24gZGUgbG9zIGNsw7pzdGVyZXMuIFN1IHZhbG9yIGRpc21pbnV5ZSBjb25mb3JtZSBhdW1lbnRhbiBsb3MgY2zDunN0ZXJlcywgeSBlbCBhbsOhbGlzaXMgZGUgc3VzIHNlZ3VuZGFzIGRpZmVyZW5jaWFzIGF5dWRhIGEgZGV0ZWN0YXIgZWwgcHVudG8gZG9uZGUgbGEgbWVqb3JhIGRlamEgZGUgc2VyIHJlbGV2YW50ZS4NCg0KRW4gY29uanVudG8sIGVzdG9zIGRpYWdyYW1hcyBwZXJtaXRlbiBzZWxlY2Npb25hciBkZSBtYW5lcmEgb2JqZXRpdmEgZWwgbsO6bWVybyDDs3B0aW1vIGRlIGNsw7pzdGVyZXMsIGFzZWd1cmFuZG8gdW5hIGNsYXNpZmljYWNpw7NuIGNvaGVyZW50ZSB5IGJpZW4gZGVmaW5pZGEuDQoNCiMjIyMgUmVzdWx0YWRvcyBLLU1lYW5zIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIEstw5NwdGltbyBbRWxfTWEtUnVsIDNdDQpgYGB7ciBrLW9wdGltb3MsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnNldC5zZWVkKDEyMTEyNCkNCnByaW50KGttZWFucyhkYXRhXywgMywgbnN0YXJ0ID0gMjUpKQ0KDQpgYGANCg0KTGEgdGFibGEgcHJlc2VudGEgbGEgY2xhc2lmaWNhY2nDs24gZmluYWwgZGUgbG9zIDIwMCBwYWNpZW50ZXMgbWVkaWFudGUgZWwgYWxnb3JpdG1vIEstbWVhbnMgY29uIHRyZXMgY2zDunN0ZXJlcywgYXPDrSBjb21vIGxhcyBtZWRpYXMgZGUgbGFzIHZhcmlhYmxlcyBhbmFsaXphZGFzLiBMb3MgcmVzdWx0YWRvcyBldmlkZW5jaWFuIGRpZmVyZW5jaWFzIHByaW5jaXBhbG1lbnRlIGFzb2NpYWRhcyBhIGxhIGVkYWQgeSBhIGxhIGFndWRlemEgdmlzdWFsLCBkZXN0YWPDoW5kb3NlIGVsIGNsw7pzdGVyIGNvcnJlc3BvbmRpZW50ZSBhIFByaW1lcmEgSW5mYW5jaWEgeSBOacOxZXogcG9yIHByZXNlbnRhciBtYXlvcmVzIHZhbG9yZXMgZGUgYWd1ZGV6YSB2aXN1YWwsIHkgZWwgY2zDunN0ZXIgZGUgQWR1bHRvcyBwb3IgbW9zdHJhciBsb3MgdmFsb3JlcyBtw6FzIGJham9zLiAkRWwgaW5kaWNhZG9yIGJldHdlZW5fU1MgLyB0b3RhbF9TUyAoODkuNyUpJCBjb25maXJtYSB1bmEgYWx0YSBjYWxpZGFkIGRlbCBhZ3J1cGFtaWVudG8uDQoNCiMjIyMjIEstw5NwdGltbyBbc2lsIDRdDQpgYGB7ciBrLW9wdGltb19zaWwsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnNldC5zZWVkKDEyMTEyNCkNCnByaW50KGttZWFucyhkYXRhXywgNCwgbnN0YXJ0ID0gMjUpKQ0KDQpgYGANCg0KIyMjIyBHcsOhZmljb3MgSy1NZWFucyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBLLcOTcHRpbW8gW0VsYl9NYS1SdWwgM10gLSBQZXJmaWxlcyBkZSBwYWNpZW50ZXMNCmBgYHtyIEdyYWZfRWxiX01hLVJ1bCwgZmlnLmFsaWduPSdjZW50ZXInfQ0Kc3VwcHJlc3NXYXJuaW5ncyhmdml6X2NsdXN0ZXIoa21lYW5zKGRhdGFfLCAzLCBuc3RhcnQgPSAyNSksIGRhdGEgPSBkYXRhXywgcGFsZXR0ZSA9IGMoIiMyRTlGREYiLCAiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNFN0I4MDEiKSwgZWxsaXBzZS50eXBlID0gImV1Y2xpZCIsIHN0YXIucGxvdCA9IFRSVUUsIHJlcGVsID0gVFJVRSwgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkpDQoNCmBgYA0KRWwgZ3LDoWZpY28gZGUgZGlzcGVyc2nDs24gcGFyYSBLLU1lYW5zIGNvbiBcKGsgPSAzXCkgbXVlc3RyYSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBpbmRpdmlkdW9zIGVuIGxvcyBkb3MgcHJpbWVyb3MgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKERpbTEgPSAyMy4zICUsIERpbTIgPSAyMi4yICUpLCBxdWUgZW4gY29uanVudG8gZXhwbGljYW4gdW5hIHByb3BvcmNpw7NuIHJlbGV2YW50ZSBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwuIFZpc3VhbG1lbnRlIHNlIGRpc3Rpbmd1ZW4gKip0cmVzIGdydXBvcyBkaWZlcmVuY2lhZG9zKiosIGNhZGEgdW5vIGFzb2NpYWRvIGEgc3UgY2VudHJvaWRlLCBhdW5xdWUgY29uIGNpZXJ0byBzb2xhcGFtaWVudG8gZW50cmUgbGFzIG51YmVzIGRlIHB1bnRvcy4NCg0KRGVzZGUgZWwgcHVudG8gZGUgdmlzdGEgYW5hbMOtdGljbywgZXN0YSBzb2x1Y2nDs24gc3VnaWVyZSBsYSBleGlzdGVuY2lhIGRlICoqdHJlcyBwZXJmaWxlcyBnZW5lcmFsZXMgZGUgcGFjaWVudGVzKiosIGNvbiBkaWZlcmVuY2lhcyBtb2RlcmFkYXMgcGVybyBubyBjb21wbGV0YW1lbnRlIHNlcGFyYWRhcyBlbiBlbCBlc3BhY2lvIGZhY3RvcmlhbC4gRWwgc29sYXBhbWllbnRvIG9ic2VydmFkbyBpbmRpY2EgcXVlIGxvcyBwZXJmaWxlcyBubyBzb24gdG90YWxtZW50ZSBleGNsdXllbnRlcywgYWxnbyBlc3BlcmFibGUgZW4gY29udGV4dG9zIGNsw61uaWNvcyBvIHBvYmxhY2lvbmFsZXMgZG9uZGUgbGFzIGNhcmFjdGVyw61zdGljYXMgY2FtYmlhbiBkZSBmb3JtYSBncmFkdWFsLiBObyBvYnN0YW50ZSwgbGEgKipzZXBhcmFjacOzbiBkZSBsb3MgY2VudHJvaWRlcyBjb25maXJtYSBsYSB1dGlsaWRhZCBkZSBsb3MgdHJlcyBjbMO6c3RlcmVzKiogcGFyYSBpZGVudGlmaWNhciB0ZW5kZW5jaWFzIGRvbWluYW50ZXMgeSBkZXNjcmliaXIgcGF0cm9uZXMgZXN0cnVjdHVyYWxlcyBlbiBsb3MgZGF0b3MuDQoNCiMjIyMjIEstw5NwdGltbyBbc2lsIDRdIC0gUGVyZmlsZXMgZGV0YWxsYWRvcw0KYGBge3IgR3JhZl9zaWwsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmZ2aXpfY2x1c3RlcihrbWVhbnMoZGF0YV8sIDIsIG5zdGFydCA9IDI1KSwgZGF0YSA9IGRhdGFfLCBwYWxldHRlID0gYygiIzJFOUZERiIsICIjMDBBRkJCIiwgIiNFN0I4MDAiLCAiI0U3QjgwMSIpLCBlbGxpcHNlLnR5cGUgPSAiZXVjbGlkIiwgc3Rhci5wbG90ID0gVFJVRSwgcmVwZWwgPSBUUlVFLCBnZ3RoZW1lID0gdGhlbWVfbWluaW1hbCgpDQopDQpgYGANCg0KKipFbCBncsOhZmljbyBjb3JyZXNwb25kaWVudGUgYSBLLU1lYW5zIGNvbiBcKGsgPSAyXCkgcmV2ZWxhIHVuYSBlc3RydWN0dXJhIG3DoXMgY29tcGFjdGEsIGRvbmRlIGxvcyBpbmRpdmlkdW9zIHNlIGFncnVwYW4gZW4gZG9zIGdyYW5kZXMgY29uanVudG9zKiogYWxyZWRlZG9yIGRlIHN1cyByZXNwZWN0aXZvcyBjZW50cm9pZGVzLiBBbCBpZ3VhbCBxdWUgZW4gZWwgY2FzbyBhbnRlcmlvciwgbG9zIGVqZXMgRGltMSAoMjMuMyAlKSB5IERpbTIgKDIyLjIgJSkgY29uY2VudHJhbiB1bmEgZnJhY2Npw7NuIGltcG9ydGFudGUgZGUgbGEgdmFyaWFiaWxpZGFkIHRvdGFsLCBsbyBxdWUgcGVybWl0ZSB1bmEgdmlzdWFsaXphY2nDs24gY2xhcmEgZGUgbGEgc2VwYXJhY2nDs24gZW50cmUgZ3J1cG9zLg0KDQpJbnRlcnByZXRhdGl2YW1lbnRlLCBlc3RhIHNvbHVjacOzbiByZWZsZWphIHVuYSAqKmJpcGFydGljacOzbiBkb21pbmFudGUgZGUgbGEgcG9ibGFjacOzbioqLCBjb24gZG9zIHBlcmZpbGVzIGFtcGxpb3MgeSByZWxhdGl2YW1lbnRlIGJpZW4gZGVmaW5pZG9zLiBMYSByZWR1Y2Npw7NuIGRlbCBuw7ptZXJvIGRlIGNsw7pzdGVyZXMgZGlzbWludXllIGVsIHNvbGFwYW1pZW50byBpbnRlcm5vIHkgZmF2b3JlY2UgdW5hIGxlY3R1cmEgbcOhcyBlc3RhYmxlIHkgcGFyc2ltb25pb3NhIGRlIGxhIGVzdHJ1Y3R1cmEgZGUgbG9zIGRhdG9zLiBFc3RlIHJlc3VsdGFkbyBlcyBjb2hlcmVudGUgY29uIG1lZGlkYXMgY29tbyBlbCAqKsOtbmRpY2UgZGUgc2lsdWV0YSoqLCBxdWUgdGllbmRlbiBhIGZhdm9yZWNlciBzb2x1Y2lvbmVzIGNvbiBtZW5vciBuw7ptZXJvIGRlIGdydXBvcyBjdWFuZG8gbGEgY29oZXNpw7NuIGludGVybmEgeSBsYSBzZXBhcmFjacOzbiBlbnRyZSBjbMO6c3RlcmVzIHNvbiBtw6FzIGNsYXJhcy4NCg0KIyMgKipGYXNlIDUgW1JlZ3Jlc2lvbmVzXSoqDQoNCiMjIyA1LjEuIE9iamV0aXZvcw0KDQpFc3RlIGVzdHVkaW8gdGllbmUgY29tbyBwcm9ww7NzaXRvIGVzdGFibGVjZXIgbGEgKipyZWxhY2nDs24gZW50cmUgZG9zIG8gbcOhcyB2YXJpYWJsZXMqKiBtZWRpYW50ZSBsYSBvYnRlbmNpw7NuIGRlIGluZm9ybWFjacOzbiBzb2JyZSB1bmEgZGUgZWxsYXMsIGJhc2FkYSBlbiBlbCBjb25vY2ltaWVudG8gZGUgbG9zIHZhbG9yZXMgZGUgbGFzIG90cmFzLiBMYXMgcmVsYWNpb25lcyBlc3RhYmxlY2lkYXMgc29uIGRlIGNhcsOhY3RlciAqKm5vIGRldGVybWluw61zdGljbyoqLCBlcyBkZWNpciwgc2UgcGxhbnRlYXLDoW4gcmVsYWNpb25lcyBwcm9iYWJpbMOtc3RpY2FzIHkgc2UgaW1wbGVtZW50YXLDoW4gcHJvY2VkaW1pZW50b3MgcGFyYSByZWFsaXphciBpbmZlcmVuY2lhcyBzb2JyZSBsb3MgbW9kZWxvcyB1dGlsaXphZG9zLiBBZGVtw6FzLCBzZSBvYnRlbmRyw6FuIG1lZGlkYXMgY3VhbnRpdGF0aXZhcyBxdWUgaW5kaXF1ZW4gZWwgZ3JhZG8gZGUgcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMuDQoNCkxvcyBtb2RlbG9zIGNvbnNpZGVyYWRvcyBlbiBlc3RlIHRyYWJham8gY29ycmVzcG9uZGVuIGEgY2Fzb3MgZXNwZWPDrWZpY29zIGRlbCBtb2RlbG8gbGluZWFsIGdlbmVyYWxpemFkbzogKipSZWdyZXNpw7NuIExpbmVhbCBTaW1wbGUqKiwgKipSZWdyZXNpw7NuIExpbmVhbCBNw7psdGlwbGUqKiB5ICoqUmVncmVzacOzbiBMb2fDrXN0aWNhKiouIENhZGEgbW9kZWxvIHNlcsOhIGRlc2NyaXRvIHRlw7NyaWNhbWVudGUgZW4gc3UgcmVzcGVjdGl2YSBzZWNjacOzbiwgeSBzZSBhcGxpY2Fyw6EgYSB1biBjb25qdW50byBkZSBkYXRvcyBlc3BlY8OtZmljbyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpLiANCg0KTGEgZXN0cnVjdHVyYSB5IHJlZmVyZW5jaWFzIHByaW5jaXBhbGVzIHNlIGJhc2FuIGVuIGVsIEVzdHVkaW8gZGUgKipBbsOhbGlzaXMgTXVsdGl2YXJpYWRvKiogZGVsIHByb2Zlc29yIFtARUFNT1RJbW80MjAyM10uIEFkZW3DoXMsIHNlIHV0aWxpemFyb24gbGlicm9zIGNvbW8gKlByb2JhYmlsaWRhZCB5IGVzdGFkw61zdGljYSBwYXJhIGluZ2VuaWVyw61hIGluZHVzdHJpYWwqIGRlIFtAUEVEZXZvcmU3ZWRdLCAqQW7DoWxpc2lzIGVzdGFkw61zdGljbyBkZSBkYXRvcyBtdWx0aXZhcmlhZG9zKiBkZSBbQEFFRE1EaWF6LU1vcmFsZXMxZWRdLCB5ICpBbsOhbGlzaXMgbXVsdGl2YXJpYW50ZSBhcGxpY2FkbyBjb24gUiogZGUgW0BBTUFSQWxkYXMtVXJpZWwyZWRdLCBxdWUgcHJvcG9yY2lvbmFyb24gZnVuZGFtZW50b3MgY2xhdmUgcGFyYSBlc3RlIGFuw6FsaXNpcy4NCg0KDQpQYXJhIGZpbmVzIGRlIHZpc3VhbGl6YWNpw7NuLCBzZSBjcmXDsyB1biBhcGFydGFkbyBlc3BlY8OtZmljbyBwYXJhIGVsIGRpY2Npb25hcmlvIGRlIHZhcmlhYmxlcy4gQXNpbWlzbW8sIHNlIGFjbGFyYSBxdWUgc2UgcHVlZGUgY29uc3VsdGFyIGVsIGRpY2Npb25hcmlvIGRlIHZhcmlhYmxlcyBleHRlbmRpZG8gZW4gbGEgW3NlY2Npw7NuIDEuMl0oI3NlYzEuMik6IA0KDQo8ZGV0YWlscz4gPHN1bW1hcnk+KipEZXNwbGVnYXIgZWwgZGljY2lvbmFyaW8gZGUgdmFyaWFibGVzKio8L3N1bW1hcnk+DQoNCg0KfCAqKlZhcmlhYmxlKiogICAgICAgICAgICAgICAgICAgfCAqKlRpcG8qKiAgICAgICAgICAgICAgICAgICAgIHwgKipEZXNjcmlwY2nDs24qKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCAqKlBhY19pZCoqICAgICAgICAgICAgICAgIHwgQ3VhbnRpdGF0aXZhOjpOb21pbmFsIHwgSWRlbnRpZmljYWRvciBudW3DqXJpY28gw7puaWNvIGFzaWduYWRvIGEgY2FkYSBwYWNpZW50ZSAoc2luIGludGVycHJldGFjacOzbiBtw6l0cmljYSkuIHwNCnwgKipFZGFkX3BhY2llbnRlKiogICAgICAgICB8IEN1YW50aXRhdGl2YTo6UmF6w7NuICB8IEVkYWQgZGVsIHBhY2llbnRlIGV4cHJlc2FkYSBlbiBhw7FvcyBjdW1wbGlkb3MuIHwNCnwgKipPY3VwYWNpb24qKiAgICAgICAgICAgICB8IEN1YWxpdGF0aXZhOjpOb21pbmFsIHwgUHJvZmVzacOzbiB1IG9maWNpbyBwcmluY2lwYWwgZGVsIHBhY2llbnRlLiBDYXJhY3Rlcml6YSBsYSBhY3RpdmlkYWQgZGlhcmlhIHkgcG90ZW5jaWFsIGV4cG9zaWNpw7NuIGEgcGFudGFsbGFzLiB8DQp8ICoqQ2FuYWxfZGlmdXNpb24qKiAgICAgICAgfCBDdWFsaXRhdGl2YTo6Tm9taW5hbCB8IE1lZGlvIHBvciBlbCBjdWFsIGVsIHBhY2llbnRlIGNvbm9jacOzIGxhIMOzcHRpY2EgKGNhbmFsIGRlIGNhcHRhY2nDs24pLiB8DQp8ICoqRmVjaGFfcmVnaXN0cm8qKiAgICAgICAgfCBDdWFsaXRhdGl2YTo6T3JkaW5hbCBbdGllbXBvXSB8IEZlY2hhIGRlIHJlZ2lzdHJvIGRlbCBwYWNpZW50ZSBlbiBlbCBzaXN0ZW1hIChvcmRlbiB0ZW1wb3JhbCkuIHwNCnwgKipQYWNfc2V4byoqICAgICAgICAgICAgICB8IEN1YWxpdGF0aXZhOjpOb21pbmFsIHwgU2V4byBkZWwgcGFjaWVudGUgKEZlbWVuaW5vIG8gTWFzY3VsaW5vKS4gfA0KfCAqKlJhbmdvX2V0YXJlbyoqICAgICAgICAgIHwgQ3VhbGl0YXRpdmE6Ok9yZGluYWwgfCBDbGFzaWZpY2FjacOzbiBkZWwgcGFjaWVudGUgZW4gZ3J1cG9zIGRlIGVkYWQgY29uIHVuIG9yZGVuIG5hdHVyYWwgKGUuZy4sIEFEVUxUTywgQURPTEVTQ0VOVEUpLiB8DQp8ICoqQWd1ZGV6YV92aXN1YWxfT0QqKiAgICAgfCBDdWFudGl0YXRpdmE6OlJhesOzbiAgfCBNZWRpZGEgZGUgbGEgYWd1ZGV6YSB2aXN1YWwgZGVsIE9qbyBEZXJlY2hvLiBWYWxvcmVzIHF1ZSBzZSBhY2VyY2FuIGEgbGEgcmVmZXJlbmNpYSBkZSB2aXNpw7NuIG5vcm1hbC4gfA0KfCAqKkFndWRlemFfdmlzdWFsX09JKiogICAgIHwgQ3VhbnRpdGF0aXZhOjpSYXrDs24gIHwgTWVkaWRhIGRlIGxhIGFndWRlemEgdmlzdWFsIGRlbCBPam8gSXpxdWllcmRvLiB8DQp8ICoqSG9yYXNfcGFudGFsbGFfZGlhKiogICAgfCBDdWFudGl0YXRpdmE6OlJhesOzbiAgfCBOw7ptZXJvIGRlIGhvcmFzIHByb21lZGlvIHF1ZSBlbCBwYWNpZW50ZSBwYXNhIGRpYXJpYW1lbnRlIGZyZW50ZSBhIGRpc3Bvc2l0aXZvcyBjb24gcGFudGFsbGEgKGZhY3RvciBkZSByaWVzZ28pLiB8DQp8ICoqSG9yYXNfYWN0aXZpZGFkZioqICAgICAgfCBDdWFudGl0YXRpdmE6OlJhesOzbiAgfCBIb3JhcyBwcm9tZWRpbyBkaWFyaWFzIGRlIGFjdGl2aWRhZCBmw61zaWNhLiB8DQp8ICoqSG9iYnlfcHJpbmNpcGFsX3BhbnRhbGxhKiogfCBDdWFsaXRhdGl2YTo6Tm9taW5hbCB8IEluZGljYSBzaSBlbCBwYXNhdGllbXBvIHByaW5jaXBhbCBpbXBsaWNhIHVzbyBpbnRlbnNpdm8gZGUgcGFudGFsbGFzIChTw60vTm8pLiB8DQp8ICoqUHJlZGlzcG9zaWNpb25fZ2VuZXRpY2EqKiB8IEN1YWxpdGF0aXZhOjpOb21pbmFsIHwgU2XDsWFsYSBzaSBlbCBwYWNpZW50ZSByZXBvcnRhIGFudGVjZWRlbnRlcyBmYW1pbGlhcmVzIGRlIHByb2JsZW1hcyBvZnRhbG1vbMOzZ2ljb3MgKFPDrS9ObykuIHwNCjwvZGV0YWlscz4NCg0KIyMjIDUuMi4gUmVncmVzacOzbiBMaW5lYWwgU2ltcGxlIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkVsIGFuw6FsaXNpcyBkZSByZWdyZXNpw7NuIGVzIHVuYSBoZXJyYW1pZW50YSBlc3RhZMOtc3RpY2EgZW1wbGVhZGEgcGFyYSBpZGVudGlmaWNhciB5IGV2YWx1YXIgbGFzIHJlbGFjaW9uZXMgZW50cmUgZGlzdGludGFzIHZhcmlhYmxlcy4gRXN0ZSBtw6l0b2RvIHBlcm1pdGUgZXhwbG9yYXIgY8OzbW8gdW5hIHZhcmlhYmxlIGRlcGVuZGllbnRlIG8gZGUgcmVzcHVlc3RhIHNlIHZlIGFmZWN0YWRhIHBvciBsb3MgY2FtYmlvcyBlbiB1bmEgbyBtw6FzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcyBvIHByZWRpY3RvcmFzLCB1dGlsaXphbmRvIGRpdmVyc2FzIHTDqWNuaWNhcyBkZSBtb2RlbGFkbyB5IGFuw6FsaXNpcy4gRW4gZXN0ZSBkb2N1bWVudG8gc2UgYWJvcmRhcsOhbiBsb3MgbW9kZWxvcyBkZSByZWdyZXNpw7NuIGxpbmVhbCAqKihlbiBzdXMgdmVyc2lvbmVzIHNpbXBsZSB5IG3Dumx0aXBsZSkqKiB5IGVsICoqbW9kZWxvIGxvZ8Otc3RpY28qKiwgYW1ib3MgY29uc2lkZXJhZG9zIGNvbW8gY2Fzb3MgZXNwZWPDrWZpY29zIGRlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgZ2VuZXJhbGl6YWRvLg0KDQpFc3RlIG1vZGVsbywgcXVlIGEgcGFydGlyIGRlIGFob3JhIHNlIGRlbm9taW5hcsOhIGNvbW8gUkxTLCBlc3TDoSBjb21wdWVzdG8gcG9yIGRvcyB2YXJpYWJsZXM6IHVuYSBwcmVkaWN0b3JhIHkgb3RyYSByZXNwdWVzdGEuIEVzcGVjw61maWNhbWVudGUsIGxhIHZhcmlhYmxlICRZJCBzZSBjb25zaWRlcmEgaW5mbHVpZGEgcG9yIGxhIHZhcmlhYmxlIHByZWRpY3RvcmEgJHgkLiBMYSByZWxhY2nDs24gZW50cmUgZXN0YXMgdmFyaWFibGVzIGVzdMOhIGRlc2NyaXRhIHBvciBsYSBlY3VhY2nDs246DQokJFkgPSBcYmV0YV8wICsgXGJldGFfMXggKyBcdmFyZXBzaWxvbiQkDQpEb25kZTogDQotICRZJDogRXMgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgKGxhIHF1ZSBzZSBkZXNlYSBwcmVkZWNpciBvIGV4cGxpY2FyKS4NCi0gJHgkOiBFcyBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlIChwcmVkaWN0b3JhKS4NCi0gJChcYmV0YV8wKSQ6IEVzIGVsIGludGVyY2VwdG8gKHZhbG9yIGRlICRZJCBjdWFuZG8gJCh4ID0gMCkkLg0KLSAkKFxiZXRhXzEpJDogRXMgbGEgcGVuZGllbnRlIChpbmRpY2EgY3XDoW50byBjYW1iaWEgJFkkIHBvciBjYWRhIHVuaWRhZCBxdWUgY2FtYmlhICQoeCkkLg0KLSAkKFxlcHNpbG9uKSQ6IEVzIGVsIHTDqXJtaW5vIGRlIGVycm9yLCBxdWUgY2FwdHVyYSBsYXMgZGVzdmlhY2lvbmVzIGVudHJlIGxvcyB2YWxvcmVzIG9ic2VydmFkb3MgeSBsb3MgdmFsb3JlcyBwcmVkaWNob3MgcG9yIGVsIG1vZGVsby4NCg0KTGEgcmVsYWNpw7NuIGVudHJlIGxhIHZhcmlhYmxlIGluZGVwZW5kaWVudGUgeSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBlbiBlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIGRlYmUgY3VtcGxpciBjaWVydGFzIHN1cG9zaWNpb25lcyBjbGF2ZSBwYXJhIHF1ZSBsb3MgcmVzdWx0YWRvcyBzZWFuIHbDoWxpZG9zLiBFc3RhcyBzb24gbGFzIHNpZ3VpZW50ZXM6IDEuIExhIHJlbGFjacOzbiBlbnRyZSBsYSB2YXJpYWJsZSBpbmRlcGVuZGllbnRlICR4JCB5IGxhIHZhcmlhYmxlIGRlcGVuZGllbnRlICRZJCBkZWJlIHNlciBsaW5lYWwuIDIuIEVsIHTDqXJtaW5vIGRlIGVycm9yICTOtSQgc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIHkgdGllbmUgdW5hIG1lZGlhIGlndWFsIGEgY2Vyby4gMy4gTGFzIG9ic2VydmFjaW9uZXMgZGViZW4gc2VyIGluZGVwZW5kaWVudGVzIGVudHJlIHPDrSwgZXMgZGVjaXIsIGVsIHZhbG9yIGRlICRZJCBwYXJhIHVuIGRhdG8gbm8gaW5mbHV5ZSBlbiBsb3MgdmFsb3JlcyBkZSAkWSQgcGFyYSBvdHJvcyBkYXRvcy4gNC4gTGEgdmFyaWFuemEgZGVsIHTDqXJtaW5vIGRlIGVycm9yICTOtSQgZGViZSBzZXIgY29uc3RhbnRlIHBhcmEgdG9kb3MgbG9zIHZhbG9yZXMgZGUgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSAkeCQsIHVuYSBjb25kaWNpw7NuIGNvbm9jaWRhIGNvbW8gaG9tb2NlZGFzdGljaWRhZC4gTGEgdmFyaWFuemEgZGUgJFx2YXJlcHNpbG9uJCBlcyBjb25zdGFudGUgcGFyYSB0b2RvcyBsb3MgdmFsb3JlcyBkZSAkeCQuDQoNClBhcmEgZXN0aW1hciBsb3MgcGFyw6FtZXRyb3MgZGVzY29ub2NpZG9zICgkXGJldGFfMCQsICRcYmV0YV8xJCB5ICRcc2lnbWFeMiQpLCBzZSB1c2EgZWwgKiptw6l0b2RvIGRlIG3DrW5pbW9zIGN1YWRyYWRvcyoqLCBxdWUgYnVzY2EgbWluaW1pemFyIGxhIHN1bWEgZGUgbG9zIGN1YWRyYWRvcyBkZSBsYXMgZGVzdmlhY2lvbmVzIHZlcnRpY2FsZXMgZW50cmUgbG9zIHB1bnRvcyBvYnNlcnZhZG9zIHkgbGEgbMOtbmVhIGRlIHJlZ3Jlc2nDs246JCRTQ0UgPSBcc3VtX3tpPTF9Xm4gXGxlZnQoeV9pIC0gKFxiZXRhXzAgKyBcYmV0YV8xeF9pKVxyaWdodCleMiQkLiBSZXNvbHZpZW5kbyBlc3RlIHByb2JsZW1hLCBsYXMgZXN0aW1hY2lvbmVzIGRlIGxvcyBwYXLDoW1ldHJvcyBzb246DQokJFxoYXR7XGJldGF9XzEgPSBcZnJhY3tcc3VtX3tpPTF9Xm4gKHhfaSAtIFxiYXJ7eH0pKHlfaSAtIFxiYXJ7eX0pfXtcc3VtX3tpPTF9Xm4gKHhfaSAtIFxiYXJ7eH0pXjJ9LCBccXVhZCBcaGF0e1xiZXRhfV8wID0gXGJhcnt5fSAtIFxoYXR7XGJldGF9XzEgXGJhcnt4fS4kJA0KQXF1w60sICRcYmFye3h9JCB5ICRcYmFye3l9JCBzb24gbGFzIG1lZGlhcyBtdWVzdHJhbGVzIGRlICR4JCBlICR5JCwgcmVzcGVjdGl2YW1lbnRlLg0KDQpFbCBjb2VmaWNpZW50ZSBkZSBkZXRlcm1pbmFjacOzbiBpbmRpY2EgbGEgcHJvcG9yY2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkIGRlICRZJCBxdWUgcHVlZGUgZXhwbGljYXJzZSBtZWRpYW50ZSBlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlOiQkUl4yID0gMSAtIFxmcmFje1NDRX17U1RDfSwkJCBkb25kZSAkU0NFJCBlcyBsYSBzdW1hIGRlIGN1YWRyYWRvcyBkZWwgZXJyb3IgeSAkU1RDJCBlcyBsYSBzdW1hIHRvdGFsIGRlIGN1YWRyYWRvcy4gVW4gdmFsb3IgZGUgJFJeMiQgY2VyY2FubyBhIDEgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gZXhwbGljYSBncmFuIHBhcnRlIGRlIGxhIHZhcmlhYmlsaWRhZCBvYnNlcnZhZGEgZW4gbG9zIGRhdG9zLg0KDQpTZSBwdWVkZW4gZm9ybXVsYXIgcHJ1ZWJhcyBwYXJhIGRldGVybWluYXIgc2kgbG9zIGNvZWZpY2llbnRlcyBkZWwgbW9kZWxvIHNvbiBzaWduaWZpY2F0aXZhbWVudGUgZGlmZXJlbnRlcyBkZSBjZXJvLiBMYXMgaGlww7N0ZXNpcyBudWxhcyBjb211bmVzIHNvbjoNCi0gUGFyYSAkXGJldGFfMCQ6ICRIXzA6IFxiZXRhXzAgPSBcYmV0YV97MDB9JC4NCi0gUGFyYSAkXGJldGFfMSQ6ICRIXzA6IFxiZXRhXzEgPSAwJCAocHJ1ZWJhIGRlIHV0aWxpZGFkIGRlbCBtb2RlbG8pLg0KDQpFbCBlc3RhZMOtc3RpY28gZGUgcHJ1ZWJhIGFzb2NpYWRvIGVzOiQkIHQgPSBcZnJhY3tcaGF0e1xiZXRhfV8xIC0gMH17U0UoXGhhdHtcYmV0YX1fMSl9LCQkIGRvbmRlICRTRShcaGF0e1xiZXRhfV8xKSQgZXMgZWwgZXJyb3IgZXN0w6FuZGFyIGRlICRcaGF0e1xiZXRhfV8xJCBFc3RlIGVzdGFkw61zdGljbyBzaWd1ZSB1bmEgZGlzdHJpYnVjacOzbiAkdCQgZGUgU3R1ZGVudCBjb24gJG4tMiQgZ3JhZG9zIGRlIGxpYmVydGFkLg0KDQpMb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEgcGFyYSBsb3MgcGFyw6FtZXRyb3MgZXN0aW1hZG9zIHNlIGNhbGN1bGFuIGNvbW86ICQkXGhhdHtcYmV0YX1fMSBccG0gdF97XGFscGhhLzIsIG4tMn0gXGNkb3QgU0UoXGhhdHtcYmV0YX1fMSkuJCQgRXN0b3MgaW50ZXJ2YWxvcyBicmluZGFuIHVuIHJhbmdvIHByb2JhYmxlIHBhcmEgbG9zIHZlcmRhZGVyb3MgdmFsb3JlcyBkZSAkXGJldGFfMCQgeSAkXGJldGFfMSQuDQoNCkVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBzaW1wbGUgZXMgdW5hIGhlcnJhbWllbnRhIHBvZGVyb3NhIHBhcmEgYW5hbGl6YXIgcmVsYWNpb25lcyBsaW5lYWxlcy4gU2luIGVtYmFyZ28sIGRlYmUgdXNhcnNlIGNvbiBjYXV0ZWxhOiBubyBleHRyYXBvbGUgbcOhcyBhbGzDoSBkZWwgcmFuZ28gZGUgbG9zIGRhdG9zIHkgYXNlZ8O6cmVzZSBkZSBxdWUgbGFzIHN1cG9zaWNpb25lcyBkZWwgbW9kZWxvIHNlYW4gcmF6b25hYmxlcyBwYXJhIGxvcyBkYXRvcy4gQWwgY29tcHJlbmRlciBsYSB2YXJpYWJpbGlkYWQgZXhwbGljYWRhIHkgbm8gZXhwbGljYWRhIHBvciBlbCBtb2RlbG8sIGxvcyBhbmFsaXN0YXMgcHVlZGVuIHRvbWFyIGRlY2lzaW9uZXMgZnVuZGFtZW50YWRhcyB5IGV2YWx1YXIgbGEgdXRpbGlkYWQgZGVsIG1vZGVsbyBlbiBjb250ZXh0b3MgZXNwZWPDrWZpY29zLg0KDQpFbiBlbCBtb2RlbG8sICoqbG9zIHB1bnRvcyBvYnNlcnZhZG9zIHNlIGRpc3RyaWJ1eWVuIGFsZWF0b3JpYW1lbnRlIGFscmVkZWRvcioqIGRlIGxhIGzDrW5lYSBkZSAqKnJlZ3Jlc2nDs24gdmVyZGFkZXJhKiouIFBhcmEgYWp1c3RhcnNlIGEgZXN0b3MgcHVudG9zLCBsYSBlc3RpbWFjacOzbiAkeSA9IGJldGFfMCArIGJldGFfMSB4JCBkZWJlIHNlciB1bmEgbMOtbmVhIHF1ZSBtaW5pbWljZSBsYXMgZGlzdGFuY2lhcyB2ZXJ0aWNhbGVzIGRlc3ZpYWNpb25lcyBlbnRyZSBsb3MgcHVudG9zIG9ic2VydmFkb3MgeSBsYSBsw61uZWEuIExhIGNhbGlkYWQgZGVsIGFqdXN0ZSBzZSBldmFsw7phIG1lZGlhbnRlIGxhIHN1bWEgZGUgbG9zIGN1YWRyYWRvcyBkZSBlc3RhcyBkZXN2aWFjaW9uZXMsIHNpZW5kbyBsYSBtZWpvciBsw61uZWEgYXF1ZWxsYSBxdWUgbWluaW1pY2UgZXN0YSBzdW1hLiBFc3RlIGVuZm9xdWUsIGNvbm9jaWRvIGNvbW8gZWwgcHJpbmNpcGlvIGRlIGxvcyBtw61uaW1vcyBjdWFkcmFkb3MsIGZ1ZSBkZXNhcnJvbGxhZG8gcG9yICoqQ2FybCBGcmllZHJpY2ggR2F1c3MgeSBBZHJpZW4tTWFyaWUgTGVnZW5kcmUqKi4NCg0KUG9yIMO6bHRpbW8sIHNlIGVudGllbmRlIHF1ZSBlbiB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIHVuIHZhbG9yIGZ1dHVybyBkZSAkWSQgbm8gZXMgcGFyw6FtZXRybyBzaW5vIHVuYSB2YXJpYWJsZSBhbGVhdG9yaWEsIHBvciBsbyBxdWUgc2UgZGViZSBoYWNlciByZWZlcmVuY2lhIGEgdW4gaW50ZXJ2YWxvIGRlIHZhbG9yZXMgZmFjdGlibGVzIHBhcmEgdW4gdmFsb3IgZnV0dXJvIGRlICRZJCwgYWwgY3VhbCBzZSBsZSBsbGFtYSBpbnRlcnZhbG8gZGUgcHJlZGljY2nDs24uIFNlZ8O6bixbQEVBTU9USW1vNDIwMjNdLg0KDQoNCiMjIyMgTWF0cml6IGRlIGRpc3BlcnNpw7NuIG3Dumx0aXBsZSAoUGFpcnMgUGxvdCkNCmBgYHtyIERpYWdyYW1hX0Rpc3BlcnNpb25fTXVsdGlwbGUsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmRhdGFfY2xlYW4gPC0gbmEub21pdChjY2RfdmlzaW9uMjAyMF9FVExbLCBjKCJBVl9PRCIsICJBVl9PSSIsICJIb3Jhc19wZCIsICJIb3Jhc19hZiIsICJlZGFkX3BhY2llbnRlIildKQ0KDQpwYWlycyh+IEFWX09EICsgQVZfT0kgKyBIb3Jhc19wZCArIEhvcmFzX2FmICsgZWRhZF9wYWNpZW50ZSwNCmRhdGEgPSBkYXRhX2NsZWFuLA0KbWFpbiA9ICJNYXRyaXogZGUgRGlzcGVyc2nDs246IFZhcmlhYmxlcyBDdWFudGl0YXRpdmFzIiwNCnBjaCA9IDE2LCBjZXggPSAwLjYpDQpgYGANCkxhIG1hdHJpeiBkZSBkaWFncmFtYXMgZGUgZGlzcGVyc2nDs24gcGVybWl0ZSB2aXN1YWxpemFyIGRlIG1hbmVyYSBjb25qdW50YSBsYXMgcmVsYWNpb25lcyBiaXZhcmlhZGFzIGVudHJlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBBVl9PRCwgQVZfT0ksIEhvcmFzX3BkLCBIb3Jhc19hZiB5IGVkYWRfcGFjaWVudGUuIEVuIGdlbmVyYWwsIGxhcyBudWJlcyBkZSBwdW50b3Mgc2UgbXVlc3RyYW4gbXV5IGRpc3BlcnNhcyB5IHNpbiBwYXRyb25lcyBsaW5lYWxlcyBtYXJjYWRvcywgbG8gcXVlIGluZGljYSBxdWUgbm8gZXhpc3RlbiBjb3JyZWxhY2lvbmVzIGZ1ZXJ0ZXMgZW50cmUgbGEgbWF5b3LDrWEgZGUgbG9zIHBhcmVzIGRlIHZhcmlhYmxlcy4NCg0KRGVzdGFjYSBsYSByZWxhY2nDs24gcG9zaXRpdmEgZW50cmUgQVZfT0QgeSBBVl9PSSwgY3V5b3MgcHVudG9zIHNlIGRpc3RyaWJ1eWVuIGRlIGZvcm1hIGFsaW5lYWRhLCBzdWdpcmllbmRvIHF1ZSBsYSBhZ3VkZXphIHZpc3VhbCBkZSBhbWJvcyBvam9zIHNlIGNvbXBvcnRhIGRlIG1hbmVyYSBzaW1pbGFyLiBFbiBjb250cmFzdGUsIGxhcyBjb21iaW5hY2lvbmVzIHF1ZSBpbnZvbHVjcmFuIEhvcmFzX3BkLCBIb3Jhc19hZiB5IGVkYWRfcGFjaWVudGUgbm8gbXVlc3RyYW4gdGVuZGVuY2lhcyBjbGFyYXMsIGxvIHF1ZSByZXNwYWxkYSBsYSBpZGVhIGRlIHF1ZSBlc3RvcyBmYWN0b3JlcywgY29uc2lkZXJhZG9zIGFpc2xhZGFtZW50ZSwgZXhwbGljYW4gc29sbyB1bmEgZnJhY2Npw7NuIGxpbWl0YWRhIGRlIGxhIHZhcmlhYmlsaWRhZCBlbiBsYSBhZ3VkZXphIHZpc3VhbC4NCg0KIyMjIyBSZXN1bWVuIEFndWRlemEgVmlzdWFsIChPRCBZIE9JKSB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KYGBge3IgUmVzdW1lbl9BZ3VkZXphX1Zpc3VhbF9PRF9ZX09JLCBmaWcuYWxpZ249J2NlbnRlcid9DQpib3hwbG90X2F2IDwtIGZ1bmN0aW9uKGRhdGEsIHZhcmlhYmxlLCBtYWluX3RpdGxlID0gIkRpYWdyYW1hIGRlIGNhamEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAib3JhbmdlIiwgeWxpbSA9IE5VTEwpIHsNCiAgaWYgKGlzLnZlY3RvcihkYXRhKSkgew0KICAgIGJveHBsb3QoZGF0YSwNCiAgICAgICAgICAgIG1haW4gPSBtYWluX3RpdGxlLA0KICAgICAgICAgICAgY29sICA9IGNvbG9yLA0KICAgICAgICAgICAgeWxpbSA9IHlsaW0pDQogIH0gZWxzZSB7DQogICAgYm94cGxvdChkYXRhW1t2YXJpYWJsZV1dLA0KICAgICAgICAgICAgbWFpbiA9IG1haW5fdGl0bGUsDQogICAgICAgICAgICBjb2wgID0gY29sb3IsDQogICAgICAgICAgICB5bGltID0geWxpbSkNCiAgfQ0KfQ0KYGBgDQojIyMjIyBSZXN1bWVuIEFndWRlemEgVmlzdWFsIChPam8gRGVyZWNobykNCmBgYHtyIFJlc3VtZW5fQWd1ZGV6YV9WaXN1YWxfT0QsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnN1bW1hcnkoY2NkX3Zpc2lvbjIwMjBfRVRMJEFWX09EKQ0KYm94cGxvdF9hdihjY2RfdmlzaW9uMjAyMF9FVEwsDQogICAgICAgICAgIHZhcmlhYmxlICAgPSAiQVZfT0QiLA0KICAgICAgICAgICBtYWluX3RpdGxlID0gIkRpYWdyYW1hIGRlIGNhamEgQWd1ZGV6YSBWaXN1YWwgT0QiLA0KICAgICAgICAgICBjb2xvciAgICAgID0gImdvbGQiLA0KICAgICAgICAgICB5bGltICAgICAgID0gYygwLCAxLjIpKQ0KYGBgDQoNCkxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNobyAoT0QpIHByZXNlbnRhIHVuYSBkaXN0cmlidWNpw7NuIHJlbGF0aXZhbWVudGUgaG9tb2fDqW5lYS4gTG9zIHZhbG9yZXMgc2UgZXh0aWVuZGVuIGRlc2RlIDAuMTAgaGFzdGEgMC45OSwgY29uIHVuYSBtZWRpYW5hIGRlIDAuNTMsIGxvIHF1ZSBpbmRpY2EgcXVlIGxhIG1pdGFkIGRlIGxhIHBvYmxhY2nDs24gZXZhbHVhZGEgdGllbmUgdW5hIGFndWRlemEgdmlzdWFsIGlndWFsIG8gaW5mZXJpb3IgYSBlc3RlIHZhbG9yLiANCg0KRWwgNTAgJSBjZW50cmFsIGRlIGxvcyBkYXRvcyBzZSBjb25jZW50cmEgZW50cmUgMC4zMSB5IDAuNzYsIGV2aWRlbmNpYW5kbyB1bmEgdmFyaWFiaWxpZGFkIG1vZGVyYWRhLiBMYSBjZXJjYW7DrWEgZW50cmUgbGEgbWVkaWEgKDAuNTQpIHkgbGEgbWVkaWFuYSBzdWdpZXJlIHVuYSBkaXN0cmlidWNpw7NuIGFwcm94aW1hZGFtZW50ZSBzaW3DqXRyaWNhLiBFbiBnZW5lcmFsLCBsb3MgcmVzdWx0YWRvcyBtdWVzdHJhbiB1biBwcmVkb21pbmlvIGRlIG5pdmVsZXMgbWVkaW9zIGRlIGFndWRlemEgdmlzdWFsIGVuIGVsIG9qbyBkZXJlY2hvLCBzaW4gcHJlc2VuY2lhIGRlIHZhbG9yZXMgYXTDrXBpY29zIHJlbGV2YW50ZXMuDQoNCiMjIyMjIFJlc3VtZW4gQWd1ZGV6YSBWaXN1YWwgKE9qbyBJenF1aWVyZG8pDQpgYGB7ciBSZXN1bWVuX0FndWRlemFfVmlzdWFsX09JLCBmaWcuYWxpZ249J2NlbnRlcid9DQpzdW1tYXJ5KGNjZF92aXNpb24yMDIwX0VUTCRBVl9PSSkNCmJveHBsb3RfYXYoY2NkX3Zpc2lvbjIwMjBfRVRMLA0KICAgICAgICAgICB2YXJpYWJsZSAgID0gIkFWX09JIiwNCiAgICAgICAgICAgbWFpbl90aXRsZSA9ICJEaWFncmFtYSBkZSBjYWphIEFndWRlemEgVmlzdWFsIE9JIiwNCiAgICAgICAgICAgY29sb3IgICAgICA9ICJza3libHVlIiwNCiAgICAgICAgICAgeWxpbSAgICAgICA9IGMoMCwgMS4yKSkNCmBgYA0KDQpMYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGl6cXVpZXJkbyAoT0kpIG11ZXN0cmEgdW5hIGRpc3RyaWJ1Y2nDs24gZXF1aWxpYnJhZGEgZW4gbGEgcG9ibGFjacOzbiBhbmFsaXphZGEuIExvcyB2YWxvcmVzIG9zY2lsYW4gZW50cmUgMC4xMCB5IDAuOTksIGNvbiB1bmEgbWVkaWFuYSBkZSAwLjU4LCBsbyBxdWUgaW5kaWNhIHF1ZSBsYSBtaXRhZCBkZSBsb3MgaW5kaXZpZHVvcyBwcmVzZW50YSB1bmEgYWd1ZGV6YSB2aXN1YWwgaWd1YWwgbyBpbmZlcmlvciBhIGVzdGUgdmFsb3IuDQoNCkVsIDUwICUgY2VudHJhbCBkZSBsb3MgZGF0b3Mgc2UgY29uY2VudHJhIGVudHJlIDAuMzUgeSAwLjc5LCByZWZsZWphbmRvIHVuYSB2YXJpYWJpbGlkYWQgbW9kZXJhZGEuIExhIG1lZGlhICgwLjU3KSBlcyBjZXJjYW5hIGEgbGEgbWVkaWFuYSwgbG8gcXVlIHN1Z2llcmUgdW5hIGRpc3RyaWJ1Y2nDs24gYXByb3hpbWFkYW1lbnRlIHNpbcOpdHJpY2EuIEVuIGdlbmVyYWwsIHNlIG9ic2VydmEgdW4gcHJlZG9taW5pbyBkZSBuaXZlbGVzIG1lZGlvcyBhIG1vZGVyYWRhbWVudGUgYWx0b3MgZGUgYWd1ZGV6YSB2aXN1YWwgZW4gZWwgb2pvIGl6cXVpZXJkbywgc2luIHByZXNlbmNpYSBkZSB2YWxvcmVzIGF0w61waWNvcyByZWxldmFudGVzLg0KDQojIyMjIERpYWdyYW1hcyBkZSBkaXNwZXJzacOzbiBBViB2cyBob3JhcyBkZSBwYW50YWxsYSB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBEaWFncmFtYSBkZSBkaXNwZXJzacOzbiBBViB2cyBob3JhcyBkZSBwYW50YWxsYSAoT2pvIERlcmVjaG8pDQpgYGB7ciBEaWFncmFtYV9EaXNwZXJzaW9uX0FWX09EX1ZTX0hvcmFzX3BkLCBmaWcuYWxpZ249J2NlbnRlcid9DQpwbG90KGNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wZCwNCiAgICAgY2NkX3Zpc2lvbjIwMjBfRVRMJEFWX09ELA0KICAgICBtYWluID0gIkRpYWdyYW1hIGRlIGRpc3BlcnNpb24gQVZfT0QgdnMgSG9yYXMgZGUgUGFudGFsbGEiLA0KICAgICB4bGFiID0gIkhvcmFzIGRlIFBhbnRhbGxhIGFsIERpYSIsDQogICAgIHlsYWIgPSAiQWd1ZGV6YSBWaXN1YWwgT0QiLA0KICAgICBwY2ggID0gMTYsDQogICAgIGNvbCAgPSAiZ29sZCIpDQpgYGANCg0KRWwgZGlhZ3JhbWEgZGUgZGlzcGVyc2nDs24gZW50cmUgbGEgYWd1ZGV6YSB2aXN1YWwgZGVsIG9qbyBkZXJlY2hvIChPRCkgeSBsYXMgaG9yYXMgZGUgcGFudGFsbGEgYWwgZMOtYSBtdWVzdHJhIHVuYSBkaXN0cmlidWNpw7NuIGFtcGxpYSBkZSBsb3MgdmFsb3JlcyBkZSBhZ3VkZXphIHZpc3VhbCBhIGxvIGxhcmdvIGRlIHRvZG8gZWwgcmFuZ28gZGUgaG9yYXMgZGUgZXhwb3NpY2nDs24uIE5vIHNlIG9ic2VydmEgdW5hIHRlbmRlbmNpYSBjbGFyYSBhc2NlbmRlbnRlIG5pIGRlc2NlbmRlbnRlLCBsbyBxdWUgaW5kaWNhIHF1ZSBubyBleGlzdGUgdW5hIHJlbGFjacOzbiBsaW5lYWwgZXZpZGVudGUgZW50cmUgZWwgbsO6bWVybyBkZSBob3JhcyBmcmVudGUgYSBwYW50YWxsYXMgeSBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGRlcmVjaG8uIA0KDQpMb3MgcHVudG9zIHNlIGRpc3BlcnNhbiBkZSBtYW5lcmEgaG9tb2fDqW5lYSwgY29uIHByZXNlbmNpYSBkZSB2YWxvcmVzIGJham9zLCBtZWRpb3MgeSBhbHRvcyBkZSBhZ3VkZXphIHZpc3VhbCBlbiBjYXNpIHRvZG9zIGxvcyBuaXZlbGVzIGRlIGV4cG9zaWNpw7NuLCBsbyBxdWUgc3VnaWVyZSBxdWUgb3Ryb3MgZmFjdG9yZXMgZGlzdGludG9zIGEgbGFzIGhvcmFzIGRlIHBhbnRhbGxhIHBvZHLDrWFuIGluZmx1aXIgZW4gbGEgYWd1ZGV6YSB2aXN1YWwuDQoNCiMjIyMjIERpYWdyYW1hIGRlIGRpc3BlcnNpw7NuIEFWIHZzIGhvcmFzIGRlIHBhbnRhbGxhIChPam8gSXpxdWllcmRvKQ0KYGBge3IgRGlhZ3JhbWFfRGlzcGVyc2lvbl9BVl9PSV9WU19Ib3Jhc19wZCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KcGxvdChjY2RfdmlzaW9uMjAyMF9FVEwkSG9yYXNfcGQsDQogICAgIGNjZF92aXNpb24yMDIwX0VUTCRBVl9PSSwNCiAgICAgbWFpbiA9ICJEaWFncmFtYSBkZSBkaXNwZXJzaW9uIEFWX09JIHZzIEhvcmFzIGRlIFBhbnRhbGxhIiwNCiAgICAgeGxhYiA9ICJIb3JhcyBkZSBQYW50YWxsYSBhbCBEaWEiLA0KICAgICB5bGFiID0gIkFndWRlemEgVmlzdWFsIE9JIiwNCiAgICAgcGNoICA9IDE2LA0KICAgICBjb2wgID0gInNreWJsdWUiKQ0KYGBgDQoNCkVsIGRpYWdyYW1hIGRlIGRpc3BlcnNpw7NuIGVudHJlIGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gaXpxdWllcmRvIChPSSkgeSBsYXMgaG9yYXMgZGUgcGFudGFsbGEgYWwgZMOtYSBtdWVzdHJhIHVuYSBkaXN0cmlidWNpw7NuIGFtcGxpYSB5IGhvbW9nw6luZWEgZGUgbG9zIHZhbG9yZXMgZGUgYWd1ZGV6YSB2aXN1YWwgYSBsbyBsYXJnbyBkZSB0b2RvIGVsIHJhbmdvIGRlIGV4cG9zaWNpw7NuIGEgcGFudGFsbGFzLiBObyBzZSBpZGVudGlmaWNhIHVuYSB0ZW5kZW5jaWEgY2xhcmEgY3JlY2llbnRlIG5pIGRlY3JlY2llbnRlLCBsbyBxdWUgaW5kaWNhIHF1ZSBubyBleGlzdGUgdW5hIHJlbGFjacOzbiBsaW5lYWwgZXZpZGVudGUgZW50cmUgbGFzIGhvcmFzIGRlIHVzbyBkZSBwYW50YWxsYXMgeSBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGl6cXVpZXJkby4gDQoNCkxvcyB2YWxvcmVzIGJham9zLCBtZWRpb3MgeSBhbHRvcyBkZSBhZ3VkZXphIHZpc3VhbCBhcGFyZWNlbiBlbiBjYXNpIHRvZG9zIGxvcyBuaXZlbGVzIGRlIGhvcmFzIGRlIHBhbnRhbGxhLCBsbyBxdWUgc3VnaWVyZSBxdWUgbGEgYWd1ZGV6YSB2aXN1YWwgbm8gZGVwZW5kZSBkaXJlY3RhbWVudGUgZGVsIHRpZW1wbyBkZSBleHBvc2ljacOzbiB5IHF1ZSBvdHJvcyBmYWN0b3JlcyBwb2Ryw61hbiBpbmZsdWlyIGVuIHN1IGNvbXBvcnRhbWllbnRvLg0KDQojIyMjIFJlc3VtZW4gTW9kZWxvIFJMUyAoQVZfT0Qpey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgQ29lZmljaWVudGVzIGRlbCBNb2RlbG8gUkxTIChBVl9PRCkNCmBgYHtyIENvZWZpY2llbnRlc19Nb2RlbG9fUkxTLCBmaWcuYWxpZ249J2NlbnRlcid9DQptb2RlbG9fUkxTIDwtIGxtKEFWX09EIH4gSG9yYXNfcGQsIGRhdGEgPSBjY2RfdmlzaW9uMjAyMF9FVEwpDQpjb2VmKG1vZGVsb19STFMpDQpgYGANCg0KRWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSAoUkxTKSBlc3RpbWFkbyBwYXJhIGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNobyAoQVZfT0QpIGVuIGZ1bmNpw7NuIGRlIGxhcyBob3JhcyBkZSBwYW50YWxsYSBhbCBkw61hIG11ZXN0cmEgdW4gaW50ZXJjZXB0byBkZSAwLjU0NiwgcXVlIHJlcHJlc2VudGEgbGEgYWd1ZGV6YSB2aXN1YWwgZXNwZXJhZGEgY3VhbmRvIGxhcyBob3JhcyBkZSBwYW50YWxsYSBzb24gY2Vyby4gRWwgY29lZmljaWVudGUgYXNvY2lhZG8gYSBsYXMgaG9yYXMgZGUgcGFudGFsbGEgZXMgJOKIkjAuMDAxOSQsIGxvIHF1ZSBpbmRpY2EgdW5hIHJlbGFjacOzbiBuZWdhdGl2YSBtdXkgbGV2ZSBlbnRyZSBhbWJhcyB2YXJpYWJsZXMuDQoNCkVzdG8gc3VnaWVyZSBxdWUsIHBvciBjYWRhIGhvcmEgYWRpY2lvbmFsIGRlIGV4cG9zaWNpw7NuIGEgcGFudGFsbGFzLCBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGRlcmVjaG8gZGlzbWludWlyw61hIGRlIGZvcm1hIG3DrW5pbWEuIEVuIGNvbmp1bnRvLCBlbCBlZmVjdG8gZGUgbGFzIGhvcmFzIGRlIHBhbnRhbGxhIHNvYnJlIGxhIGFndWRlemEgdmlzdWFsIE9EIGVzIHByw6FjdGljYW1lbnRlIGRlc3ByZWNpYWJsZSwgY29oZXJlbnRlIGNvbiBsYSBhdXNlbmNpYSBkZSB1bmEgdGVuZGVuY2lhIGNsYXJhIG9ic2VydmFkYSBlbiBlbCBkaWFncmFtYSBkZSBkaXNwZXJzacOzbi4NCg0KIyMjIyMgUmVzdW1lbiBFc3RhZMOtc3RpY28gZGVsIE1vZGVsbyBSTFMNCmBgYHtyIFJlc3VtZW4gRXN0YWTDrXN0aWNvX2RlbF9Nb2RlbG9fUkxTLGZpZy5hbGlnbj0nY2VudGVyJ30NCnN1bW1hcnkobW9kZWxvX1JMUykNCmBgYA0KRWwgcmVzdW1lbiBlc3RhZMOtc3RpY28gZGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBzaW1wbGUgcXVlIHJlbGFjaW9uYSBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGRlcmVjaG8gKEFWX09EKSBjb24gbGFzIGhvcmFzIGRlIHBhbnRhbGxhIGFsIGTDrWEgaW5kaWNhIHF1ZSBlbCBtb2RlbG8gdGllbmUgbXV5IGJhamEgY2FwYWNpZGFkIGV4cGxpY2F0aXZhLiBBdW5xdWUgZWwgaW50ZXJjZXB0byBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZvLCBlbCBjb2VmaWNpZW50ZSBkZSBsYXMgaG9yYXMgZGUgcGFudGFsbGEgJCjiiJIwLjAwMTkpJCBubyBlcyBzaWduaWZpY2F0aXZvICQocCA9IDAuNDg2KSQsIGxvIHF1ZSBjb25maXJtYSBxdWUgZXN0YSB2YXJpYWJsZSBubyB0aWVuZSB1biBlZmVjdG8gcmVsZXZhbnRlIHNvYnJlIGxhIGFndWRlemEgdmlzdWFsIE9ELiANCg0KRWwgUsKyIGVzIHByw6FjdGljYW1lbnRlIGNlcm8gKDAuMDAwNCksIGxvIHF1ZSBtdWVzdHJhIHF1ZSBlbCBtb2RlbG8gbm8gZXhwbGljYSBsYSB2YXJpYWJpbGlkYWQgZGUgbGEgYWd1ZGV6YSB2aXN1YWwuIEFkZW3DoXMsIGxhIHBydWViYSBGIHRhbXBvY28gcmVzdWx0YSBzaWduaWZpY2F0aXZhLCByZWZvcnphbmRvIGxhIGNvbmNsdXNpw7NuIGRlIHF1ZSBubyBleGlzdGUgdW5hIHJlbGFjacOzbiBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhIGVudHJlIGxhcyBob3JhcyBkZSBwYW50YWxsYSB5IGxhIGFndWRlemEgdmlzdWFsIGRlbCBvam8gZGVyZWNoby4NCg0KIyMjIyMgVGFibGEgQU5PVkEgcGFyYSBlbCBNb2RlbG8gUkxTDQpgYGB7ciBUYWJsYV9BTk9WQV9wYXJhX2VsX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0KYW5vdmEobW9kZWxvX1JMUykNCg0KYGBgDQoNCiMjIyMgQW7DoWxpc2lzIGRlbCBNb2RlbG8gUkxTIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkFsIGNvbnNpZGVyYXIgbG9zIHJlc3VsdGFkb3MgcHJlc2VudGFkb3MgZW4gbGEgcGVzdGHDsWEgZGUgQ29lZmljaWVudGVzIGRlbCBNb2RlbG8gUkxTLCBzZSBwdWVkZSBlc3RhYmxlY2VyIHF1ZSBlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlIHF1ZSByZWxhY2lvbmEgZXN0YXMgdmFyaWFibGVzIHRpZW5lIGxhIGZvcm11bGFjacOzbjoNCg0KJCQNCkFWX3tPRH0gPSAwLjU0NiAtIDAuMDAxOSBcdGltZXMgXHRleHR7SG9yYXN9X3twZH0NCiQkDQpFbCBjb2VmaWNpZW50ZSBkZWwgaW50ZXJjZXB0byAoMC41NDYpIGluZGljYSBlbCB2YWxvciBlc3BlcmFkbyBkZSBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGRlcmVjaG8gY3VhbmRvIGxhcyBob3JhcyBkZSBwYW50YWxsYSBkaWFyaWFzIHNvbiBpZ3VhbGVzIGEgY2Vyby4gUG9yIG90cm8gbGFkbywgZWwgY29lZmljaWVudGUgZGUgSG9yYXNfcGQgKC0wLjAwMTkpIGltcGxpY2EgcXVlLCBwb3IgY2FkYSBob3JhIGFkaWNpb25hbCBkaWFyaWEgZnJlbnRlIGEgcGFudGFsbGFzLCBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGRlcmVjaG8gZGlzbWludXllIGVuIHByb21lZGlvIGVuIDAuMDAxOSB1bmlkYWRlcywgYXN1bWllbmRvIHF1ZSB0b2RvcyBsb3MgZGVtw6FzIGZhY3RvcmVzIHBlcm1hbmVjZW4gY29uc3RhbnRlcy4gRXN0ZSByZXN1bHRhZG8gYXBvcnRhIGluZm9ybWFjacOzbiByZWxldmFudGUgcGFyYSBhbmFsaXphciBsYSByZWxhY2nDs24gZW50cmUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMgeSBhZ3VkZXphIHZpc3VhbCBkZW50cm8gZGVsIGNvbnRleHRvIGRlbCBtb2RlbG8uDQoNCkNvbXBsZW1lbnRhcmlhbWVudGUsIGVuIGxhIHBlc3Rhw7FhIFJlc3VtZW4gRXN0YWTDrXN0aWNvIGRlbCBNb2RlbG8gUkxTLCBzZSBjb25zdGF0YSBxdWUsIHBhcmEgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBkZWwgJDUlJCQozrEgPSAwLjA1KSQsIGxhcyBldmlkZW5jaWFzIG5vIHJlc3BhbGRhbiB1bmEgcmVsYWNpw7NuIGxpbmVhbCBzaWduaWZpY2F0aXZhIGVudHJlIEFWX09EIHkgSG9yYXNfcGQsIGRhZG8gcXVlIGVsIGNvZWZpY2llbnRlIGFzb2NpYWRvIGEgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSBlcyBuZWdhdGl2byAoLTAuMDAxOSkgeSBzdSBwLXZhbG9yICgwLjQ4NikgZXMgbWF5b3IgYWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYS4NCg0KQWRlbcOhcywgZWwgY29lZmljaWVudGUgZGUgZGV0ZXJtaW5hY2nDs24gJChNdWx0aXBsZSBSwrIgPSAwLjAwMDQyKSQgZGVsIG1vZGVsbyBpbmRpY2EgcXVlIHNvbG8gZWwgMC4wNDIlIGRlIGxhIHZhcmlhYmlsaWRhZCBlbiBBVl9PRCBlcyBleHBsaWNhZGEgcG9yIEhvcmFzX3BkLiBFc3RlIHZhbG9yIGV4dHJlbWFkYW1lbnRlIGJham8gY29uZmlybWEgcXVlIGxhIHJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzIGVzIHByw6FjdGljYW1lbnRlIG51bGEsIGNvaGVyZW50ZSBjb24gbGEgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgZMOpYmlsIG9ic2VydmFkYSBlbiBsYSBGYXNlIDEuIEVzdGUgaGFsbGF6Z28gc2UgcmVmdWVyemEgYWwgb2JzZXJ2YXIgZWwgZXJyb3IgZXN0w6FuZGFyIHJlc2lkdWFsICgwLjI1OSksIHF1ZSBpbmRpY2EgdW5hIGRpc3BlcnNpw7NuIGNvbnNpZGVyYWJsZSBkZSBsb3MgZGF0b3MgYWxyZWRlZG9yIGRlIGxhIHJlY3RhIGRlIHJlZ3Jlc2nDs24uDQoNCkVzdG8gdGFtYmnDqW4gcXVlZGEgY29uZmlybWFkbyBlbiBsYSBwZXN0YcOxYSBUYWJsYSBBTk9WQSwgZG9uZGUgc2Ugb2JzZXJ2YSBxdWUgZWwgbW9kZWxvIHRpZW5lIHVuIEYtc3RhdGlzdGljIGRlIDAuNDg3IGNvbiB1biBwLXZhbG9yIGFzb2NpYWRvIGRlIDAuNDg2LCBpbmRpY2FuZG8gcXVlIGVsIG1vZGVsbyBubyBlcyBnbG9iYWxtZW50ZSBzaWduaWZpY2F0aXZvLg0KDQpFbCB2YWxvciBleHRyZW1hZGFtZW50ZSBiYWpvIGRlIFLCsiB5IGxhIG5vIHNpZ25pZmljYW5jaWEgZ2xvYmFsIGluZGljYW4gcXVlIGVsIG1vZGVsbyBzaW1wbGUgdGllbmUgdW5hIGNhcGFjaWRhZCBleHBsaWNhdGl2YSB5IHByZWRpY3RpdmEgbnVsYS4gUGFyYSBtZWpvcmFyIGVsIGFuw6FsaXNpcyB5IGNhcHR1cmFyIG1lam9yIGxhIHZhcmlhYmlsaWRhZCBkZSBBVl9PRCwgZXMgbmVjZXNhcmlvIGluY2x1aXIgb3RyYXMgdmFyaWFibGVzIHJlbGV2YW50ZXMgY29tbyBlZGFkX3BhY2llbnRlLCBIb3Jhc19hZiwgcmFuZ29fZXRhcmVvIHkgZmFjdG9yZXMgY2F0ZWfDs3JpY29zIChwYWNfc2V4bywgUHJlZGlzcG9zaWNpb25fZ2VuZXRpY2EpLCBsbyBjdWFsIGp1c3RpZmljYSBlbCBwYXNvIGFsIG1vZGVsbyBkZSBSZWdyZXNpw7NuIExpbmVhbCBNw7psdGlwbGUgZW4gbGEgc2lndWllbnRlIHNlY2Npw7NuLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIGVsIGludGVydmFsbyBkZSBjb25maWFuemEgcGFyYSDOsuKCgSB5IHBhcmEgbGEgcHJlZGljY2nDs24gZGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBzaW1wbGUsIGFtYm9zIGFsIDk1JS4gU2UgbWVuY2lvbmEgcXVlIGxhcyB2YXJpYWJsZXMgZGUgaW50ZXLDqXMgc29uOiBBZ3VkZXphIFZpc3VhbCBPam8gRGVyZWNobyAoQVZfT0QpICh2YXJpYWJsZSBkZXBlbmRpZW50ZSkgeSBIb3JhcyBkZSBwYW50YWxsYSBkaWFyaWFzIChIb3Jhc19wZCkgKHZhcmlhYmxlIGluZGVwZW5kaWVudGUpLg0KDQojIyMjIyBJbnRlcnZhbG8gZGUgQ29uZmlhbnphIHBhcmEgzrLigoEgKEhvcmFzX3BkKQ0KYGBge3IgSW50ZXJ2YWxvX0NvbmZpYW56YV9Nb2RlbG9fUkxTLGZpZy5hbGlnbj0nY2VudGVyJ30NCmNvbmZpbnQobW9kZWxvX1JMUywgbGV2ZWwgPSAwLjk1KQ0KDQpgYGANCg0KIyMjIyMgUHJlZGljY2lvbmVzIGUgSW50ZXJ2YWxvcyBkZSBQcmVkaWNjacOzbg0KYGBge3IgUHJlZGljY2lvbmVzX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0KcHJlZGljY2lvbmVzIDwtIHByZWRpY3QobW9kZWxvX1JMUywgaW50ZXJ2YWwgPSAicHJlZGljdGlvbiIsIGxldmVsID0gMC45NSkNCmhlYWQocHJlZGljY2lvbmVzLCAxMCkgICMgTXVlc3RyYSBwcmltZXJhcyAxMCBvYnNlcnZhY2lvbmVzDQpgYGANCg0KIyMjIyMgUHJlZGljY2lvbmVzIGUgSW50ZXJ2YWxvcyBkZSBQcmVkaWNjacOzbg0KYGBge3IgSW50ZXJ2YWxvc19QcmVkaWNjaW9uX01vZGVsb19STFMsZmlnLmFsaWduPSdjZW50ZXInfQ0KcHJlZGljY2lvbmVzIDwtIHByZWRpY3QobW9kZWxvX1JMUywgaW50ZXJ2YWwgPSAiY29uZmlkZW5jZSIsIGxldmVsID0gMC45NSkNCmhlYWQocHJlZGljY2lvbmVzLCAxMCkNCmBgYA0KRWwgYW7DoWxpc2lzIGRlbCBtb2RlbG8gUkxTIG11ZXN0cmEgcXVlIG5vIGVzIHNpZ25pZmljYXRpdm8geSBhcG9ydGEgaW5mb3JtYWNpw7NuIGxpbWl0YWRhIHBhcmEgZXN0aW1hciBBVl9PRCBhIHBhcnRpciBkZSBIb3Jhc19wZC4gRXN0byBzZSBldmlkZW5jaWEgcG9ycXVlIGVsIGludGVydmFsbyBkZSBjb25maWFuemEgcGFyYSBlbCBjb2VmaWNpZW50ZSBkZSBIb3Jhc19wZCBpbmNsdXllIGFsIGNlcm86DQoNCiQkDQpcdGV4dHtJQyA5NSAlIH0oXGJldGFfMSkgPSBbLTAuMDA3MSxcOyAwLjAwMzRdDQokJA0KRXN0byBjb25maXJtYSBxdWUgbm8gZXhpc3RlIGV2aWRlbmNpYSBzdWZpY2llbnRlIGRlIHVuYSByZWxhY2nDs24gbGluZWFsIHNpZ25pZmljYXRpdmEgZW50cmUgbGFzIGhvcmFzIGRlIHBhbnRhbGxhIHkgbGEgYWd1ZGV6YSB2aXN1YWwgZW4gZWwgbW9kZWxvLCBjb2hlcmVudGUgY29uIGVsIHAtdmFsb3IgZGUgMC40ODYgb2JzZXJ2YWRvIHByZXZpYW1lbnRlLg0KDQpQb3Igw7psdGltbywgZW4gbGFzIHBlc3Rhw7FhcyBJbnRlcnZhbG9zIGRlIENvbmZpYW56YSB5IEludGVydmFsb3MgZGUgUHJlZGljY2nDs24gc2UgcHJlc2VudGFuIGxvcyBjw6FsY3Vsb3MgYmFzYWRvcyBlbiBlbCBtb2RlbG8gYWwgOTUlLiBMb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEgKGFuY2hvIOKJiCAwLjAzLTAuMDcgdW5pZGFkZXMpIHNvbiByZWxhdGl2YW1lbnRlIGVzdHJlY2hvcywgcmVmbGVqYW5kbyBwcmVjaXNpw7NuIGVuIGxhIGVzdGltYWNpw7NuIGRlIGxhcyBtZWRpYXMgY29uZGljaW9uYWxlcy4gRW4gY29udHJhc3RlLCBsb3MgaW50ZXJ2YWxvcyBkZSBwcmVkaWNjacOzbiBzb24gY29uc2lkZXJhYmxlbWVudGUgYW1wbGlvcyAoYW5jaG8g4omIIDEuMCB1bmlkYWRlcywgZWo6IFswLjAyNywgMS4wNDRdIHBhcmEgbGEgcHJpbWVyYSBvYnNlcnZhY2nDs24pLCBsbyBjdWFsIGVzIGNvbcO6biBlbiBtb2RlbG9zIGNvbiBjb2VmaWNpZW50ZSBkZSBkZXRlcm1pbmFjacOzbiBleHRyZW1hZGFtZW50ZSBiYWpvIChSwrIgPSAwLjAwMDQyKS4NCg0KRXN0byByZWZsZWphIHVuYSBhbHRhIGluY2VydGlkdW1icmUgZW4gbGFzIHByZWRpY2Npb25lcyBpbmRpdmlkdWFsZXMsIGNhdXNhZGEgcG9yIGxhIGdyYW4gdmFyaWFiaWxpZGFkIGRlIGxvcyBkYXRvcyB5IGxhIHJlbGFjacOzbiBwcsOhY3RpY2FtZW50ZSBudWxhIGVudHJlIGxhcyB2YXJpYWJsZXMuIEEgZGlmZXJlbmNpYSBkZSBsb3MgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEsIHF1ZSBzb2xvIGNvbnNpZGVyYW4gbGEgcHJlY2lzacOzbiBkZWwgbW9kZWxvIGVuIGVzdGltYXIgbG9zIGNvZWZpY2llbnRlcywgbG9zIGludGVydmFsb3MgZGUgcHJlZGljY2nDs24gaW5jb3Jwb3JhbiB0YW1iacOpbiBsYSBkaXNwZXJzacOzbiBuYXR1cmFsIGRlIGxvcyBkYXRvcyBpbmRpdmlkdWFsZXMgYWxyZWRlZG9yIGRlIGxhcyBwcmVkaWNjaW9uZXMuIFBvciB0YW50bywgZXN0b3MgaW50ZXJ2YWxvcyBzb24gbcOhcyBhbXBsaW9zICjiiYgxNSB2ZWNlcyBtw6FzIGFuY2hvcyBxdWUgbG9zIGRlIGNvbmZpYW56YSkgeSBvZnJlY2VuIHVuYSBlc3RpbWFjacOzbiBjb25zZXJ2YWRvcmEgZGUgbG9zIHBvc2libGVzIHZhbG9yZXMgZGUgQVZfT0QsIGNvbmZpcm1hbmRvIGxhIGxpbWl0YWRhIHV0aWxpZGFkIHByZWRpY3RpdmEgZGVsIG1vZGVsbyBzaW1wbGUuDQoNCiMjIyA1LjMuIFJlZ3Jlc2nDs24gTGluZWFsIE3Dumx0aXBsZSB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpFc3RlIG1vZGVsbywgcXVlIHB1ZWRlIGluaWNpYWxtZW50ZSBwZW5zYXJzZSBjb21vIHVuYSBleHRlbnNpw7NuIGRlIGxhIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSBwYXJhIGZhY2lsaXRhciBzdSBjb21wcmVuc2nDs24sIHkgcXVlIGV2ZW50dWFsbWVudGUgc2Vyw6EgbGxhbWFkbyBlbiBlc3RlIGVzdHVkaW8gY29tbyAqKlJMTSoqLCB0aWVuZSBjb21vIGVjdWFjacOzbiBnZW5lcmFsIGFkaXRpdmE6JCR5X2k9XGJldGFfMCtcYmV0YV8xIHhfe2kxfStcY2RvdHMrXGJldGFfayB4X3tpa30rXHZhcmVwc2lsb25faSwgXGhzcGFjZXszbW19aT0xLDIsXGRvdHMsblxoc3BhY2V7MTBtbX0oMjEpJCQgDQoNCkRvbmRlOg0KLSAkeV9pICQ6IFZhbG9yIG9ic2VydmFkbyBkZSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBwYXJhIGxhIG9ic2VydmFjacOzbiAkIGkgJA0KLSAkXGJldGFfMCQ6IEludGVyY2VwdG8sIHZhbG9yIGRlICQgeSAkIGN1YW5kbyB0b2RhcyBsYXMgJCB4X2ogPSAwICQuDQotICRcYmV0YV8xLCBcYmV0YV8yLCBcZG90cywgXGJldGFfayQ6IENvZWZpY2llbnRlcyBxdWUgaW5kaWNhbiBjdcOhbnRvIGNhbWJpYSBcKCB5IFwpIHBvciBjYWRhIHVuaWRhZCBxdWUgY2FtYmlhIFwoIHhfaiBcKSwgbWFudGVuaWVuZG8gY29uc3RhbnRlcyBsYXMgZGVtw6FzIHZhcmlhYmxlcy4NCi0gJCBcZXBzaWxvbl9pICQ6IFTDqXJtaW5vIGRlIGVycm9yIHBhcmEgbGEgb2JzZXJ2YWNpw7NuIFwoIGkgXCkuDQotICQgRShcZXBzaWxvbikgPSAwICQ6IFNlIGFzdW1lIHF1ZSBlbCBlcnJvciB0aWVuZSBtZWRpYSBjZXJvLg0KLSAkIFYoXGVwc2lsb24pID0gXHNpZ21hXjIgJDogTGEgdmFyaWFuemEgZGVsIGVycm9yIGVzIGNvbnN0YW50ZS4NCg0KQWRlbcOhcyAkRShcZXBzaWxvbik9MCQgeSAkVihcZXBzaWxvbik9XHNpZ21hXjIkLiBUYW1iacOpbiwgcGFyYSBoYWNlciBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgeSBjYWxjdWxhciBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSB5IGRlIHByZWRpY2Npw7NuLCBzZSBzdXBvbmUgcXVlICRcZXBzaWxvbiQgZXN0w6Egbm9ybWFsbWVudGUgZGlzdHJpYnVpZGEuIENvbXBsZW1lbnRhcmlhbWVudGUsIGNvbiBiYXNlIGVuIGVsIGVuZm9xdWUgZGUgbG9zIG3DrW5pbW9zIGN1YWRyYWRvcyBvcmRpbmFyaW9zLCBsYSBlc3RpbWFjacOzbiBkZSBzdXMgcGFyw6FtZXRyb3Mgc2UgcGxhbnRlYSBlbiB0w6lybWlub3MgZGUgbGEgbWluaW1pemFjacOzbiBkZSB1bmEgZnVuY2nDs24gZGUgZW5zYXlvIGRlc2RlIGxhIGN1YWwgc2Ugb2JzZXJ2YW4gbG9zIGN1YWRyYWRvcyBkZSBsYXMgZGVzdmlhY2lvbmVzIGRlIGxhIHZhcmFpYmxlIGVzdHVkaWFkYS4gTGEgZnVuY2nDs24gZGUgZW5zYXlvIHNlIHJlcHJlc2VudGEgY29tbyAkZihiXzAsYl8xLC4uLixiX2spPSBcc3VtX3tqfVt5X2ktKGJfMCtiXzF4X3sxan0rYl8yeF97Mmp9Ky4uLitiX2t4X3tran0pXV4yJC4gRXN0byBjb25kdWNlIGEgdW4gY29uanVudG8gZGUgZWN1YWNpb25lcyBub3JtYWxlcyBsaW5lYWxlcyBlbiAkYl8wLGJfMSwuLi4sYl9rJCwgcXVlIGFsIHNlciByZXN1ZWx0YXMgZW50cmVnYW4gbGFzIGVzdGltYWNpb25lcyBkZSBtw61uaW1vcyBjdWFkcmFkb3MgZGUgJFxoYXR7XGJldGFfMH0sXGhhdHtcYmV0YV8xfSwuLi4sLCBcaGF0e1xiZXRhX2t9JC4NCg0KDQpDb21wbGVtZW50YXJpYW1lbnRlLCBsYSBwcm9wb3JjacOzbiBkZSB2YXJpYWNpw7NuIHRvdGFsIGV4cGxpY2FkYSBwb3IgZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbcO6bHRpcGxlIGEgdHJhdsOpcyBkZWwgY29lZmljaWVudGUgZGUgZGV0ZXJtaW5hY2nDs24gbcO6bHRpcGxlIHNlIGFqdXN0YSwgZ2VuZXJhbG1lbnRlLCBjb24gYmFzZSBlbiBlbCBuw7ptZXJvIGRlIHBhcsOhbWV0cm9zIGRlbCBtb2RlbG8uDQoNCkFkZW3DoXMsIHVuYSBwcnVlYmEgZGUgdXRpbGlkYWQgZGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGUgY29uc2lzdGUgZW4gdW5hIHBydWViYSBkZSBoaXDDs3Rlc2lzIGJhc2FkYSBlbiB1biBlc3RhZMOtc3RpY28gcXVlIHRpZW5lIHVuYSBkaXN0cmlidWNpw7NuICRGJCBwYXJ0aWN1bGFyIGN1YW5kbyAkSF8wJCBlcyB2ZXJkYWRlcmEsIGVzdG8gZGUgZXhwcmVzYSBlbiBlbCBwYXI6JCRIXzA6XGJldGFfMT1cYmV0YV8yPVxjZG90cz1cYmV0YV9rPTBcaHNwYWNlezEwbW19KDIyKSQkDQokJEhfMTogXHRleHQge2FsIG1lbm9zIHVuYSB9XGJldGFfaVxuZXEgMFxoc3BhY2V7NW1tfShpPTEsLi4uLGspXGhzcGFjZXsxMG1tfSgyMykkJCBlbCB2YWxvciBkZWwgZXN0YWTDrXN0aWNvIGRlIHBydWViYSBlczokJGY9XGZyYWN7Ul4yL2t9eygxLVJeMikobi0oaysxKSl9PVxmcmFje1NDUi9rfXtTQ0UvKG4tKGsrMSkpfT1cZnJhY3tSTUN9e0NNRX1caHNwYWNlezEwbW19KDI0KSQkIGRvbmRlICRTQ1I9U1RDLVNDRSQsIHF1ZSBlcyBsYSBzdW1hIGRlIGN1YWRyYWRvcyBkZSByZWdyZXNpw7NuLCB5IGxhIHJlZ2nDs24gZGUgcmVjaGF6byBwYXJhIHVuYSBwcnVlYmEgZGUgbml2ZWwgJFxhbHBoYSQgZXM6ICQkZlxnZXEgRl97XGFscGhhLCBrLG4tKGsrMSl9XGhzcGFjZXsxMG1tfSgyNSkkJCBQb3Igw7psdGltbywgdW4gaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBhbCAkMTAwKDEtXGFscGhhKVwlJCBwYXJhICRcYmV0YV9pJCBlczogJCRcaGF0XGJldGFfaVxwbSB0X3tcYWxwaGEvMixuLShrKzEpfVxjZG90IHNfe1xoYXRcYmV0YV97aX19XGhzcGFjZXsxMG1tfSgyNikkJCB5IHVuIGludGVydmFsbyBkZSBjb25maWFuemEgYWwgbWlzbW8gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBwYXJhIHVuIHZhbG9yIGZ1dHVybyBlc3TDoSBkYWRvIHBvcjogJCRcaGF0IHlccG0gdF97XGFscGhhLzIsbi0oaysxKX1cY2RvdCBcc3FydHtzXjIrc14yX3tcaGF0IFl9fVxoc3BhY2V7MTBtbX0oMjcpJCQNClBhcmEgY2VycmFyLCBlcyBuZWNlc2FyaW8gbWVuY2lvbmFyIHF1ZSBldmVudHVhbG1lbnRlIHN1cmdlbiBwcm9ibGVtYXMgZW4gbG9zIGFuw6FsaXNpcyBkZSByZWdyZXNpw7NuIG3Dumx0aXBsZSBxdWUgaW1wbGljYW4gY29uc2lkZXJhciB0w6ljbmljYXMgZGUgc29sdWNpw7NuIHJlbGFjaW9uYWRhcyBjb24gdHJhbnNmb3JtYWNpb25lcyBkZSBuby1saW5lYWxpZGFkLCBlc3RhbmRhcml6YWNpw7NuIHkgc2VsZWNjacOzbiBkZSB2YXJpYWJsZXMsIGlkZW50aWZpY2FjacOzbiBkZSBvYnNlcnZhY2lvbmVzIGluZmx1eWVudGVzLCBtdWx0aWNvbGluZWFsaWRhZCwgZW50cmUgb3RyYXMuIChTZWfDum4gW0BFQU1PVEltbzQyMDIzXSApDQoNCiMjIyMgQXBsaWNhY2nDs24gZGVsIE1vZGVsbyBSTE0NCg0KQmFzYWRvIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIHNlY2Npw7NuIDEuMiwgc2UgZm9ybXVsYXLDoSB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgbcO6bHRpcGxlIHBhcmEgZXN0dWRpYXIgbGEgcmVsYWNpw7NuIGxpbmVhbCBlbnRyZSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBBVl9PRCAoYWd1ZGV6YSB2aXN1YWwgb2pvIGRlcmVjaG8pIHkgbGFzIHZhcmlhYmxlcyBkZWwgY29uanVudG8gY2NkX3Zpc2lvbjIwMjBfRVRMOiBlZGFkX3BhY2llbnRlLCBIb3Jhc19wZCwgSG9yYXNfYWYsIFtnw6luZXJvLCBkaWFnbsOzc3RpY29fb2N1bGFyLCBldGMuXSBjb21vIGluZGVwZW5kaWVudGVzLiBFc3RlIGFuw6FsaXNpcyBwZXJtaXRpcsOhIGV2YWx1YXIgY8OzbW8gZXN0b3MgZmFjdG9yZXMgZGUgcmllc2dvIGluZmx1eWVuIGVuIGxhIGNhbGlkYWQgdmlzdWFsIHkgZGV0ZXJtaW5hciBzdSBpbXBhY3RvIGVuIGVsIGNvbnRleHRvIGRlIHNhbHVkIHZpc3VhbCBkaWdpdGFsLg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIGVsIHJlc3VtZW4gZXN0YWTDrXN0aWNvIGRlIHRvZGFzIGxhcyB2YXJpYWJsZXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIHJlbGFjaW9uYWRvcyBjb24gc2FsdWQgdmlzdWFsLCBleGNsdXllbmRvIGN1YWxxdWllciBpZGVudGlmaWNhZG9yIHBvc2ljaW9uYWwgKElEX3BhY2llbnRlKSwgeWEgcXVlIGVzdGUgbm8gYXBvcnRhIGluZm9ybWFjacOzbiBhbmFsw610aWNhIGRpcmVjdGEuIFBhcmEgbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIChlZGFkX3BhY2llbnRlLCBIb3Jhc19wZCwgSG9yYXNfYWYsIEFWX09ELCBBVl9PSSksIGVsIHJlc3VtZW4gaW5jbHV5ZSBlc3RhZMOtc3RpY2FzIGRlc2NyaXB0aXZhcyB0cmFkaWNpb25hbGVzOiBtZWRpYSwgbWVkaWFuYSwgcmFuZ28gaW50ZXJjdWFydMOtbGljbywgZGVzdmlhY2nDs24gZXN0w6FuZGFyIHkgZ3LDoWZpY29zIGRlIGRpc3BlcnNpw7NuL2JveHBsb3QuDQoNClBvciBvdHJvIGxhZG8sIHBhcmEgbGFzIHZhcmlhYmxlcyBjdWFsaXRhdGl2YXMgW2fDqW5lcm8sIGRpYWduw7NzdGljb19vY3VsYXIsIGV0Yy5dLCBlbCByZXN1bWVuIHNlIHByZXNlbnRhIG1lZGlhbnRlIGNvbnRlb3MgYWJzb2x1dG9zLCBwcm9wb3JjaW9uZXMgcmVsYXRpdmFzIHkgZGlhZ3JhbWFzIGRlIGJhcnJhcyBxdWUgZmFjaWxpdGFuIGxhIGludGVycHJldGFjacOzbiB2aXN1YWwgZGUgbGEgZGlzdHJpYnVjacOzbiBjYXRlZ8OzcmljYS4gU2UgcmVpdGVyYSBxdWUgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgZGVsIG1vZGVsbyBlcyBBVl9PRCwgbGEgY3VhbCBzZSBhbmFsaXphIGRldGFsbGFkYW1lbnRlIGVuIHJlbGFjacOzbiBjb24gbGFzIGRlbcOhcyB2YXJpYWJsZXMgcHJlZGljdG9yYXMgZGVsIGNvbmp1bnRvLg0KDQojIyMjIFJlc3VtZW4gY3VhbnRpdGF0aXZhcw0KYGBge3IgRGVmaW5pY2lvbl9EYXRvc19STE0sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZGF0b3NfcmxtIDwtIG5hLm9taXQoDQpjY2RfdmlzaW9uMjAyMF9FVExbLCBjKCJBVl9PRCIsImVkYWRfcGFjaWVudGUiLCJIb3Jhc19wZCIsIkhvcmFzX2FmIiwicmFuZ29fZXRhcmVvIiwicGFjX3NleG8iLCJIb2JieV9wcGFudGFsbGEiLCJQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSIpXSkNCg0KZGF0b3NfcmxtJHJhbmdvX2V0YXJlbyA8LSBmYWN0b3IoZGF0b3NfcmxtJHJhbmdvX2V0YXJlbykNCmRhdG9zX3JsbSRwYWNfc2V4byA8LSBmYWN0b3IoZGF0b3NfcmxtJHBhY19zZXhvKQ0KZGF0b3NfcmxtJEhvYmJ5X3BwYW50YWxsYSA8LSBmYWN0b3IoZGF0b3NfcmxtJEhvYmJ5X3BwYW50YWxsYSkNCmRhdG9zX3JsbSRQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSA8LSBmYWN0b3IoZGF0b3NfcmxtJFByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhKQ0KYGBgDQoNCmBgYHtyIFJlc3VtZW5fY3VhbnRpdGF0aXZhc19PRCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzdW1tYXJ5KGRhdG9zX3JsbSRBVl9PRCkgDQpgYGANCg0KYGBge3IgUmVzdW1lbl9jdWFudGl0YXRpdmFzX0VQLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN1bW1hcnkoZGF0b3NfcmxtJGVkYWRfcGFjaWVudGUpDQpgYGANCg0KYGBge3IgUmVzdW1lbl9jdWFudGl0YXRpdmFzX0hQRCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzdW1tYXJ5KGRhdG9zX3JsbSRIb3Jhc19wZCkNCmBgYA0KDQpgYGB7ciBSZXN1bWVuX2N1YW50aXRhdGl2YXNfSEFGLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN1bW1hcnkoZGF0b3NfcmxtJEhvcmFzX2FmKQ0KYGBgDQoNCg0KRWwgcmVzdW1lbiBjdWFudGl0YXRpdm8gZGVzY3JpYmUgbGFzIHByaW5jaXBhbGVzIGNhcmFjdGVyw61zdGljYXMgZXN0YWTDrXN0aWNhcyBkZSBsYXMgdmFyaWFibGVzIGFuYWxpemFkYXMuIExhIHZhcmlhYmxlIEFWX09EIHByZXNlbnRhIHVuIHZhbG9yIG1lZGlvIGRlIDAuNTM2OCwgY29uIHVuYSBkaXN0cmlidWNpw7NuIHJlbGF0aXZhbWVudGUgc2ltw6l0cmljYSBlbnRyZSBzdSBtw61uaW1vICgwLjEwMjApIHkgbcOheGltbyAoMC45OTg4KSwgbG8gcXVlIGluZGljYSB1bmEgdmFyaWFiaWxpZGFkIG1vZGVyYWRhLg0KDQpMYSBlZGFkIGRlbCBwYWNpZW50ZSBtdWVzdHJhIHVuIHJhbmdvIGFtcGxpbywgZGVzZGUgMSBoYXN0YSA5MSBhw7FvcywgY29uIHVuYSBtZWRpYSBkZSAzOC43MiBhw7FvcywgbG8gcXVlIHJlZmxlamEgdW5hIG11ZXN0cmEgaGV0ZXJvZ8OpbmVhIGVuIHTDqXJtaW5vcyBldGFyaW9zLg0KDQpFbiBjdWFudG8gYSBIb3Jhc19wZCwgZWwgcHJvbWVkaW8gZXMgZGUgNC45NCBob3JhcywgY29uIHZhbG9yZXMgcXVlIG9zY2lsYW4gZW50cmUgMC4wMSB5IDkuOTggaG9yYXMsIGluZGljYW5kbyBkaWZlcmVuY2lhcyBpbXBvcnRhbnRlcyBlbiBlbCB0aWVtcG8gZGVkaWNhZG8gYSBlc3RhIGFjdGl2aWRhZC4gRmluYWxtZW50ZSwgSG9yYXNfYWYgcHJlc2VudGEgdW5hIG1lZGlhIGRlIDUuNDYgaG9yYXMsIGNvbiB1biByYW5nbyBkZSAxIGEgMTAgaG9yYXMsIGxvIHF1ZSBzdWdpZXJlIHVuYSBkaXN0cmlidWNpw7NuIG3DoXMgY29uY2VudHJhZGEgZW4gdmFsb3JlcyBpbnRlcm1lZGlvcy4NCg0KRW4gY29uanVudG8sIGVzdG9zIGVzdGFkw61zdGljb3MgcGVybWl0ZW4gaWRlbnRpZmljYXIgbGEgZGlzcGVyc2nDs24sIHRlbmRlbmNpYSBjZW50cmFsIHkgcmFuZ28gZGUgbGFzIHZhcmlhYmxlcywgcHJvcG9yY2lvbmFuZG8gdW5hIHZpc2nDs24gZ2VuZXJhbCBkZWwgY29tcG9ydGFtaWVudG8gZGUgbG9zIGRhdG9zIGFudGVzIGRlIGFwbGljYXIgbW9kZWxvcyBlc3RhZMOtc3RpY29zDQoNCiMjIyMgUmVzdW1lbiBjdWFsaXRhdGl2YXMNCmBgYHtyIFJlc3VtZW5fY3VhbGl0YXRpdmFzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN1bW1hcnkoZGF0b3NfcmxtWywgYygicmFuZ29fZXRhcmVvIiwgInBhY19zZXhvIiwgIkhvYmJ5X3BwYW50YWxsYSIsICJQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSIpXSkNCmBgYA0KDQpFbCByZXN1bWVuIGN1YWxpdGF0aXZvIG11ZXN0cmEgbGEgZGlzdHJpYnVjacOzbiBkZSBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBhbmFsaXphZGFzLiBFbiByYW5nbyBldMOhcmVvLCBlbCBncnVwbyBjb24gbWF5b3IgZnJlY3VlbmNpYSBlcyBhZHVsdG9zICg1MTUpLCBzZWd1aWRvIHBvciBhZHVsdG9zIG1heW9yZXMgKDI0OSkgeSBqw7N2ZW5lcyAoMjQ1KSwgbWllbnRyYXMgcXVlIG5pw7FleiAoNzkpIHkgcHJpbWVyYSBpbmZhbmNpYSAoNzgpIHByZXNlbnRhbiBtZW5vciByZXByZXNlbnRhY2nDs24uDQoNCkVuIGN1YW50byBhbCBzZXhvIGRlbCBwYWNpZW50ZSwgc2Ugb2JzZXJ2YSB1bmEgbWF5b3IgcHJvcG9yY2nDs24gZGUgbXVqZXJlcyAoNzI0KSBmcmVudGUgYSBob21icmVzICg0NDIpLiBSZXNwZWN0byBhbCBob2JieSByZWxhY2lvbmFkbyBjb24gcGFudGFsbGFzLCBsYSBkaXN0cmlidWNpw7NuIGVzIGVxdWlsaWJyYWRhLCBjb24gNTgxIHBlcnNvbmFzIHF1ZSBubyBsbyBwcmFjdGljYW4geSA1ODUgcXVlIHPDrSBsbyBoYWNlbi4NCg0KRmluYWxtZW50ZSwgbGEgcHJlZGlzcG9zaWNpw7NuIGdlbsOpdGljYSBhcGFyZWNlIG1heW9yaXRhcmlhbWVudGUgY29tbyBhdXNlbnRlICg1NzcpLCBmcmVudGUgYSA1ODkgY2Fzb3MgZW4gbG9zIHF1ZSBzw60gZXN0w6EgcHJlc2VudGUsIGxvIHF1ZSBpbmRpY2EgdW5hIGRpc3RyaWJ1Y2nDs24gcmVsYXRpdmFtZW50ZSBiYWxhbmNlYWRhIGVudHJlIGFtYmFzIGNhdGVnb3LDrWFzLg0KDQojIyMjIERpYWdyYW1hcyBkZSBEaXNwZXJzacOzbiBWYXJpYWJsZXMgQ3VhbnRpdGF0aXZhcw0KYGBge3IgRGlzcGVyc2nDs25fVmFyaWFibGVzX0N1YW50aXRhdGl2YXNfTVJMTSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpwYWlycyh+IEFWX09EICsgZWRhZF9wYWNpZW50ZSArIEhvcmFzX3BkICsgSG9yYXNfYWYsIA0KICAgICAgZGF0YSA9IGRhdG9zX3JsbSwgDQogICAgICBtYWluID0gIk1hdHJpeiBkZSBkaXNwZXJzacOzbiB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyIsDQogICAgICBjb2wgPSAic3RlZWxibHVlIiwgcGNoID0gMTYpDQpgYGANCg0KTGEgbWF0cml6IGRlIGRpc3BlcnNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBwZXJtaXRlIGFuYWxpemFyIGRlIGZvcm1hIGNvbmp1bnRhIGxhIHJlbGFjacOzbiBlbnRyZSAqKkFWX09ELCBlZGFkX3BhY2llbnRlKiosICoqSG9yYXNfcGQqKiB5ICoqSG9yYXNfYWYqKi4gRW4gbGEgZGlhZ29uYWwgc2UgbXVlc3RyYW4gbGFzIHZhcmlhYmxlcyBpbmRpdmlkdWFsbWVudGUsIG1pZW50cmFzIHF1ZSBmdWVyYSBkZSBlbGxhIHNlIG9ic2VydmFuIGxvcyBkaWFncmFtYXMgZGUgZGlzcGVyc2nDs24gYml2YXJpYWRvcywgcXVlIGZhY2lsaXRhbiBpZGVudGlmaWNhciBwYXRyb25lcywgdGVuZGVuY2lhcyBvIHBvc2libGVzIGFzb2NpYWNpb25lcy4NCg0KRW4gZ2VuZXJhbCwgbG9zIGdyw6FmaWNvcyBldmlkZW5jaWFuIHVuYSBkaXN0cmlidWNpw7NuIGRpc3BlcnNhIGRlIGxvcyBwdW50b3MsIHNpbiB0ZW5kZW5jaWFzIGxpbmVhbGVzIGNsYXJhcyBlbnRyZSBBVl9PRCB5IGxhcyBkZW3DoXMgdmFyaWFibGVzLCBsbyBxdWUgc3VnaWVyZSB1bmEgcmVsYWNpw7NuIGTDqWJpbCBvIG51bGEgY29uIGxhIGVkYWQgZGVsIHBhY2llbnRlIHkgY29uIGxhcyBob3JhcyByZWdpc3RyYWRhcy4gTGEgdmFyaWFibGUgZWRhZF9wYWNpZW50ZSB0YW1wb2NvIG11ZXN0cmEgdW5hIGFzb2NpYWNpw7NuIG1hcmNhZGEgY29uIEhvcmFzX3BkLCBwcmVzZW50YW5kbyB1bmEgbnViZSBkZSBwdW50b3MgYmFzdGFudGUgaG9tb2fDqW5lYS4NCg0KUG9yIG90cm8gbGFkbywgKipIb3Jhc19wZCB5IEhvcmFzX2FmKiogcHJlc2VudGFuIHZhbG9yZXMgZGlzY3JldG9zLCBsbyBjdWFsIHNlIHJlZmxlamEgZW4gbGEgZm9ybWFjacOzbiBkZSBiYW5kYXMgaG9yaXpvbnRhbGVzIHkgdmVydGljYWxlcywgaW5kaWNhbmRvIHF1ZSBlc3RhcyB2YXJpYWJsZXMgdG9tYW4gbml2ZWxlcyBlc3BlY8OtZmljb3MuIEF1biBhc8OtLCBubyBzZSBvYnNlcnZhIHVuYSByZWxhY2nDs24gZnVlcnRlIGVudHJlIGVsbGFzIG5pIGNvbiBsYXMgZGVtw6FzIHZhcmlhYmxlcy4NCg0KRW4gY29uanVudG8sICoqbGEgbWF0cml6IHN1Z2llcmUgcXVlIGxhcyB2YXJpYWJsZXMgYW5hbGl6YWRhcyBubyBwcmVzZW50YW4gY29ycmVsYWNpb25lcyBldmlkZW50ZXMsIHkgcXVlIGVsIGNvbXBvcnRhbWllbnRvIGRlIEFWX09EIHBhcmVjZSBpbmRlcGVuZGllbnRlIGRlbCByZXN0bywgbG8gY3VhbCBlcyByZWxldmFudGUgcGFyYSBpbnRlcnByZXRhciBhbsOhbGlzaXMgcG9zdGVyaW9yZXMgbyBkZWNpZGlyIGxhIGluY2x1c2nDs24gZGUgdmFyaWFibGVzIGVuIG1vZGVsb3MgZXN0YWTDrXN0aWNvcyoqLg0KDQojIyMgQXBsaWNhY2nDs24gZGVsIE1vZGVsbyBSTE0gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgbXVlc3RyYSBlbCByZXN1bWVuIGVzdGFkw61zdGljbyAsIHRhYmxhIEFOT1ZBIHkgY29lZmljaWVudGVzIGVzdGltYWRvcyB0YW50byBkZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZSAoUkxNKSB0b3RhbCBjb21vIGRlbCBtb2RlbG8gcmVkdWNpZG8gLiBDb24gYmFzZSBlbiBsYSBleHBsb3JhY2nDs24gdW5pdmFyaWFkYSBkZSBsYSAoc2VjY2nDs24gNS4yKSwgc2UgZm9ybXVsYW4gZG9zIG1vZGVsb3MgUkxNIHBhcmEgZXhwbGljYXIgbGEgdmFyaWFiaWxpZGFkIGVuICoqQVZfT0QqKiAoYWd1ZGV6YSB2aXN1YWwgb2pvIGRlcmVjaG8sIG1lZGlhPTAuNTM3KTogZWwgUkxNIHRvdGFsIGluY2x1eWUgKip0b2RhcyBsYXMgcHJlZGljdG9yYXMgZGUgZGF0b3NfcmxtKGVkYWRfcGFjaWVudGUsIEhvcmFzX3BkLCBIb3Jhc19hZiwgcmFuZ29fZXRhcmVvLCBwYWNfc2V4bywgSG9iYnlfcHBhbnRhbGxhLCBQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSkqKiwgbWllbnRyYXMgcXVlIGVsIFJMTSByZWR1Y2lkbyBleGNsdXllIGFxdWVsbGFzIGNvbiBiYWphIHNpZ25pZmljYW5jaWEgZXN0YWTDrXN0aWNhLiAqKihBTk9WQSBwPjAsMDUpKiouDQoNCkxhIHRhYmxhIEFOT1ZBIGRlbCBtb2RlbG8gdG90YWwgaWRlbnRpZmljYSBsYXMgdmFyaWFibGVzIG3DoXMgcmVsZXZhbnRlcyBwYXJhIHByZWRlY2lyIEFWX09EOiAqKkhvcmFzX3BkIChleHBvc2ljacOzbiBkaWdpdGFsIGVzcGVyYWRhIHA8MC4wMSkqKiwgKiplZGFkX3BhY2llbnRlIChlbnZlamVjaW1pZW50byBwPDAuMDUpLCBIb3Jhc19hZioqICoqKGFjdGl2aWRhZCBmw61zaWNhIHByb3RlY3RvcmEgcDwwLjA1KSoqLCByYW5nb19ldGFyZW8geSBwYWNfc2V4byAoZGlmZXJlbmNpYXMgZGVtb2dyw6FmaWNhcykuIFZhcmlhYmxlcyBjb21vIEhvYmJ5X3BwYW50YWxsYSB5IFByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhIHNlIGVsaW1pbmFuIHBvciBzdSBlc2Nhc2EgY29udHJpYnVjacOzbiBleHBsaWNhdGl2YS4gRWwgbW9kZWxvIHJlZHVjaWRvIHNlIGZvcm11bGEgY29tbyAqKkFWX09EID0gzrLigoAgKyDOsuKCgcK3ZWRhZF9wYWNpZW50ZSArIM6y4oKCwrdIb3Jhc19wZCArIM6y4oKDwrdIb3Jhc19hZiArIHTDqXJtaW5vcyBkZW1vZ3LDoWZpY29zKiogLCBkb25kZSBlbCBpbnRlcmNlcHRvIGNhcmVjZSBkZSBwcsOhY3RpY2EgZGUgaW50ZXJwcmV0YWNpw7NuICoqKEFWX09EIGNvbiBlZGFkPTAsIGNlcm8gaG9yYXMgZGUgcGFudGFsbGEpKiouIEVzdGUgZW5mb3F1ZSBvcHRpbWl6YWRvIGNvbmNlbnRyYSBlbCBhbsOhbGlzaXMgZW4gcHJlZGljdG9yZXMgY2zDrW5pY2FtZW50ZSByZWxldmFudGVzIHBhcmEgc2FsdWQgdmlzdWFsIGRpZ2l0YWwuDQoNCiMjIyMgTW9kZWxvIFJMTSBSZWR1Y2lkbw0KYGBge3IgTW9kZWxvX1JMTV9SZWR1Y2lkbywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpybG1fdG90YWwgPC0gbG0oQVZfT0QgfiBlZGFkX3BhY2llbnRlICsgSG9yYXNfcGQgKyBIb3Jhc19hZiArIHJhbmdvX2V0YXJlbyArIA0KICAgICAgICAgICAgICAgIHBhY19zZXhvICsgSG9iYnlfcHBhbnRhbGxhICsgUHJlZGlzcG9zaWNpb25fZ2VuZXRpY2EsIA0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRvc19ybG0pDQpzdW1tYXJ5KHJsbV90b3RhbCkNCmFub3ZhKHJsbV90b3RhbCkNCmBgYA0KDQojIyMjIENvZWZpY2llbnRlIGRlIE1vZGVsbyBSTE0gUmVkdWNpZG8NCmBgYHtyIENvZWZpY2llbnRlX1JMTV9SZWR1Y2lkbywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyb3VuZChjb2VmKHJsbV90b3RhbCksIDQpDQpgYGANCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgbXVlc3RyYSBlbCByZXN1bWVuIHkgbGEgdGFibGEgQU5PVkEgZGVsIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBtw7psdGlwbGUgdG90YWwsIGFzw60gY29tbyBsb3MgY29lZmljaWVudGVzIGVzdGltYWRvcyB0YW50byBwYXJhIGVzdGUgbW9kZWxvIGNvbW8gcGFyYSBlbCBtb2RlbG8gcmVkdWNpZG8uIENvbiBiYXNlIGVuIGxhIGV4cGxvcmFjacOzbiBkZSBsb3MgZGF0b3MgZGUgbGEgc2VjY2nDs24gNS4zLjEsIHNlIGZvcm11bGFuIGRvcyBtb2RlbG9zIFJMTSBwYXJhIEFWX09EIChtZWRpYSA9IDAuNTM3KTogZWwgUkxNIHRvdGFsIGluY2x1eWUgdG9kYXMgbGFzIHZhcmlhYmxlcyBkZSBkYXRvc19ybG0oZWRhZF9wYWNpZW50ZSwgSG9yYXNfcGQsIEhvcmFzX2FmLCByYW5nb19ldGFyZW8sIHBhY19zZXhvLCBIb2JieV9wcGFudGFsbGEsIFByZWRpc3Bvc2ljaW9uX2dlbmV0aWNhKSwgeSBlbCBSTE0gcmVkdWNpZG8gZXhjbHV5ZSBhcXVlbGxhcyBkZSBtZW5vciBzaWduaWZpY2FuY2lhIGVzdGFkw61zdGljYSBzZWfDum4gQU5PVkEgeSByZXPDum1lbmVzLg0KDQpMYSB0YWJsYSBBTk9WQSBkZWwgUkxNIHRvdGFsICoqKEYgPSAwLjk2MTIsIHAgPSAwLjQ3NTgpKiogcmV2ZWxhIGF1c2VuY2lhIGRlIHByZWRpY3RvcmFzIGluZGl2aWR1YWxlcyBzaWduaWZpY2F0aXZhcyAqKih0b2RhcyBwID4gMC4wNSkqKjogZWRhZF9wYWNpZW50ZSAqKihwID0gMC4xMDEzKSoqLCBIb3Jhc19hZiAqKihwID0gMC4xNDcwKSoqLCBQcmVkaXNwb3NpY2lvbl9nZW5ldGljYSAqKihwID0gMC4xNTUzKSoqLCBIb3Jhc19wZCAqKihwID0gMC41MzIzKSoqLCBwYWNfc2V4byAqKihwID0gMC41ODkxKSoqLCByYW5nb19ldGFyZW8gKioocCA9IDAuNzIzNSkqKiwgSG9iYnlfcHBhbnRhbGxhICoqKHAgPSAwLjgyOTApLiBSwrIgPSAwLjAwODMqKiBpbmRpY2EgcXVlIGxhcyB2YXJpYWJsZXMgZXhwbGljYW4gc29sbyAkMC44JSQgZGUgbGEgdmFyaWFiaWxpZGFkIGVuIEFWX09ELCBzdWdpcmllbmRvIGZhY3RvcmVzIG5vIGNhcHR1cmFkb3MgKGdlbsOpdGljYSBvY3VsYXIsIGNvbmRpY2lvbmVzIHJlZnJhY3RpdmFzLCBldGMuKS4NCg0KQWwgY29uc2lkZXJhciBsb3MgcmVzdWx0YWRvcyBkZSBsYSBwZXN0YcOxYSAqKiJDb2VmaWNpZW50ZXMgZGVsIE1vZGVsbyBSTE0gVG90YWwiKiosIGVsIG1vZGVsbyByZWxhY2lvbmEgQVZfT0QgY29uOg0KDQokJA0KXGJlZ2lue2FsaWduZWR9DQpBVl97T0R9ID1cOyYgXGJldGFfMCBcXA0KJisgXGJldGFfMShcdGV4dHtlZGFkXF9wYWNpZW50ZX0pIFxcDQomKyBcYmV0YV8yKFx0ZXh0e0hvcmFzXF9wZH0pIFxcDQomKyBcYmV0YV8zKFx0ZXh0e0hvcmFzXF9hZn0pIFxcDQomKyBcYmV0YV80KFx0ZXh0e3JhbmdvXF9ldGFyZW99KSBcXA0KJisgXGJldGFfNShcdGV4dHtwYWNcX3NleG99KSBcXA0KJisgXGJldGFfNihcdGV4dHtIb2JieVxfcHBhbnRhbGxhfSkgXFwNCiYrIFxiZXRhXzcoXHRleHR7UHJlZGlzcG9zaWNpb25cX2dlbmV0aWNhfSkNClxlbmR7YWxpZ25lZH0NCiQkDQoNCkRlIGZvcm1hIGV4cGzDrWNpdGEsIGVsIG1vZGVsbyBlc3RpbWFkbyBlczoNCg0KJCQNClxiZWdpbnthbGlnbmVkfQ0KQVZfe09EfSA9XDsmIDAuNjAzNSANCi0gMC4wMDA3XCwoXHRleHR7ZWRhZFxfcGFjaWVudGV9KQ0KLSAwLjAwMTdcLChcdGV4dHtIb3Jhc1xfcGR9KQ0KLSAwLjAwMzlcLChcdGV4dHtIb3Jhc1xfYWZ9KSBcXA0KJi0gMC4wMjgwXCwoXHRleHR7cmFuZ29cX2V0YXJlbyBBRFVMVE99KQ0KLSAwLjAyMTdcLChcdGV4dHtyYW5nb1xfZXRhcmVvIEpPVkVORVN9KSBcXA0KJi0gMC4wMjA3XCwoXHRleHR7cmFuZ29cX2V0YXJlbyBOScORRVp9KQ0KLSAwLjAwMzRcLChcdGV4dHtyYW5nb1xfZXRhcmVvIFBSSU1FUkFcX0lORkFOQ0lBfSkgXFwNCiYtIDAuMDA4MFwsKFx0ZXh0e3BhY1xfc2V4byBNYXNjdWxpbm99KQ0KKyAwLjAwMjdcLChcdGV4dHtIb2JieVxfcHBhbnRhbGxhIHPDrX0pIFxcDQomKyAwLjAyMTZcLChcdGV4dHtQcmVkaXNwb3NpY2lvblxfZ2VuZXRpY2EgMX0pDQpcZW5ke2FsaWduZWR9DQokJA0KDQpFbCBpbnRlcmNlcHRvICoqKDAuNjAzNSkgY2FyZWNlIGRlIHNlbnRpZG8gcHLDoWN0aWNvIChBVl9PRCBjb24gZWRhZCA9IDAgeSBjZXJvIGhvcmFzIGRlIHBhbnRhbGxhKS4qKiBEYWRvIHF1ZSBuaW5ndW5hIHZhcmlhYmxlIGFsY2FuemEgc2lnbmlmaWNhbmNpYSBpbmRpdmlkdWFsIChwIDwgMC4wNSkgeSBlbCBtb2RlbG8gZ2xvYmFsIG5vIGVzIMO6dGlsIChwID0gMC40NzU4KSwgbm8gc2UganVzdGlmaWNhIHVuIG1vZGVsbyByZWR1Y2lkby4gTGFzIHZhcmlhYmxlcyBlbGltaW5hZGFzIGluY2x1eWVuIHRvZGFzIGxhcyBwcmVkaWN0b3JhcyBwb3Igc3UgYmFqYSBjb250cmlidWNpw7NuIGV4cGxpY2F0aXZhLg0KDQpFbiBlbCBtb2RlbG8gdG90YWwsIGVsIGludGVyY2VwdG8gY2FyZWNlIGRlIHByw6FjdGljYSBkZSBpbnRlcnByZXRhY2nDs24uIExhcyB2YXJpYWJsZXMgYW5hbGl6YWRhcyBubyBjYXB0dXJhbiBsb3MgcHJpbmNpcGFsZXMgZGV0ZXJtaW5hbnRlcyBkZSBBVl9PRCBlbiBlc3RhIGNvaG9ydGUsIHN1Z2lyaWVuZG8gbGEgbmVjZXNpZGFkIGRlIGluY29ycG9yYXIgZmFjdG9yZXMgY2zDrW5pY29zIGVzcGVjw61maWNvcyAoZXJyb3IgcmVmcmFjdGl2bywgcGF0b2xvZ8OtYSBtYWN1bGFyKSBwYXJhIG1vZGVsb3MgcHJlZGljdGl2b3Mgcm9idXN0b3MgZW4gc2FsdWQgdmlzdWFsIGRpZ2l0YWwuDQoNCg0KIyMjIDUuNC4gUmVncmVzacOzbiBMb2fDrXN0aWNhIFNpbXBsZSB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpMYSByZWdyZXNpw7NuIGxvZ8Otc3RpY2Egc2ltcGxlIG1vZGVsYSBsYSByZWxhY2nDs24gZW50cmUgdW5hIHZhcmlhYmxlIGRlcGVuZGllbnRlIGJpbmFyaWEgeSB1bmEgc29sYSB2YXJpYWJsZSBleHBsaWNhdGl2YSBjb250aW51YSwgcGVybWl0aWVuZG8gZXN0aW1hciBwcm9iYWJpbGlkYWRlcyBkZSBwZXJ0ZW5lY2VyIGEgdW5hIGRlIGRvcyBjYXRlZ29yw61hcyAow6l4aXRvL2ZyYWNhc28pLiBFbiBlc3RlIGNhc28sIHNlIG1vZGVsYSBsYSBwcm9iYWJpbGlkYWQgZGUgYmFqYSBhZ3VkZXphIHZpc3VhbCBlbiBjYWRhIG9qbyBlbiBmdW5jacOzbiBkZSBsYXMgaG9yYXMgZGUgcGFudGFsbGEgYWwgZMOtYS4NCg0KTGEgZnVuY2nDs24gZGUgZW5sYWNlIHV0aWxpemFkYSBlcyBsYSBmdW5jacOzbiBsb2dpdCwgYWRlY3VhZGEgcGFyYSB1bmEgZGlzdHJpYnVjacOzbiBiaW5vbWlhbCwgeSBzZSBleHByZXNhIGNvbW86DQokJA0KXHBpKHgpID0gXGZyYWN7ZV57XGJldGFfMCArIFxiZXRhXzEgeH19ezEgKyBlXntcYmV0YV8wICsgXGJldGFfMSB4fX0NCiQkDQpkb25kZSAkXHBpKHgpJCByZXByZXNlbnRhIGxhIHByb2JhYmlsaWRhZCBkZSBwcmVzZW50YXIgYmFqYSBhZ3VkZXphIHZpc3VhbCBwYXJhIHVuIHZhbG9yIGRhZG8gZGUgaG9yYXMgZGUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMuDQoNCkxhIGludGVycHJldGFjacOzbiBkZSBsb3MgY29lZmljaWVudGVzIGRlbCBtb2RlbG8gc2UgcmVhbGl6YSBlbiB0w6lybWlub3MgZGUgbGEgcmF6w7NuIGRlIHByb2JhYmlsaWRhZGVzIChvZGRzIHJhdGlvKSwgbGEgY3VhbCBzZSBvYnRpZW5lIGEgcGFydGlyIGRlIGxhIHRyYW5zZm9ybWFjacOzbiBsb2dpdDoNCiQkDQpcbG9nXGxlZnQoXGZyYWN7XHBpKHgpfXsxIC0gXHBpKHgpfVxyaWdodCkgPSBcYmV0YV8wICsgXGJldGFfMSB4DQokJA0KRXN0YSBmb3JtdWxhY2nDs24gcGVybWl0ZSBldmFsdWFyIHNpIHVuIGluY3JlbWVudG8gZW4gbGFzIGhvcmFzIGRpYXJpYXMgZGUgdXNvIGRlIHBhbnRhbGxhcyBzZSBhc29jaWEgY29uIHVuIGF1bWVudG8gbyB1bmEgZGlzbWludWNpw7NuIGVuIGxhIHByb2JhYmlsaWRhZCBkZSBwcmVzZW50YXIgYmFqYSBhZ3VkZXphIHZpc3VhbCwgbWFudGVuaWVuZG8gY29uc3RhbnRlcyBsYXMgZGVtw6FzIGNvbmRpY2lvbmVzIGRlbCBtb2RlbG8uDQoNClBhcmEgZWxhYm9yYXIgZWwgbW9kZWxvLCBwcmltZXJvIHNlIGRlZmluZSBsYSB2YXJpYWJsZSByZXNwdWVzdGEgYmluYXJpYSBwYXJhIGNhZGEgb2pvIGEgcGFydGlyIGRlIHVuIHVtYnJhbCBjbMOtbmljbyBkZSBhZ3VkZXphIHZpc3VhbCAocG9yIGVqZW1wbG8sIDAuNykuIEx1ZWdvIHNlIGFqdXN0YW4gbG9zIG1vZGVsb3MgZGUgcmVncmVzacOzbiBsb2fDrXN0aWNhIHNpbXBsZSBwYXJhIGNhZGEgb2pvLg0KDQpFbiBsYXMgZ3JhZmljYXMgZGUgKipHcsOhZmljYSBkZWwgTW9kZWxvIFJMb2dTIChBZ3VkZXphX1Zpc3VhbF9PSSB5IEFndWRlemFfVmlzdWFsX09EICkqKiwgc2UgcHVlZGUgYXByZWNpYXIgZWwgcmVzdWx0YW50ZSBkZSBsYSBpbnZlc3RpZ2FjaW9uIHkgYXBsaWNhY2lvbiBkZSBsYXMgdGVjbmljYXMgZGUgYW5hbGlzaXMgbXVsdGl2YXJpYW50ZSwgZXNwZWNpZmljYW1lbnRlIGxhcyBkZXN0aW5hZGFzIGEgbGEgZWxhYm9yYWNpw7NuIGRlIE1vZGVsb3MgZGUgUmdyZXNpw7NuIExvZ8Otc3RpY2EgU2ltcGxlOg0KDQojIyMjIEdyw6FmaWNhIGRlbCBNb2RlbG8gUkxvZ1MNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnVtYnJhbF9PRCA8LSAwLjcNCnVtYnJhbF9PSSA8LSAwLjcgDQoNCmNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09EIDwtIGlmZWxzZShjY2RfdmlzaW9uMjAyMF9FVEwkQVZfT0QgPCB1bWJyYWxfT0QsIDEsIDApDQpjY2RfdmlzaW9uMjAyMF9FVEwkYmFqYV9BVl9PSSA8LSBpZmVsc2UoY2NkX3Zpc2lvbjIwMjBfRVRMJEFWX09JIDwgdW1icmFsX09JLCAxLCAwKQ0KDQpjY2RfdmlzaW9uMjAyMF9FVEwkYmFqYV9BVl9PRCA8LSBhcy5udW1lcmljKGNjZF92aXNpb24yMDIwX0VUTCRiYWphX0FWX09EKQ0KY2NkX3Zpc2lvbjIwMjBfRVRMJGJhamFfQVZfT0kgPC0gYXMubnVtZXJpYyhjY2RfdmlzaW9uMjAyMF9FVEwkYmFqYV9BVl9PSSkNCmNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wYW50YWxsYV9kaWEgPC0gYXMubnVtZXJpYyhjY2RfdmlzaW9uMjAyMF9FVEwkSG9yYXNfcGQpDQoNCm1vZF9sb2dfT0QgPC0gZ2xtKGJhamFfQVZfT0QgfiBIb3Jhc19wYW50YWxsYV9kaWEsIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhID0gY2NkX3Zpc2lvbjIwMjBfRVRMKQ0KbW9kX2xvZ19PSSA8LSBnbG0oYmFqYV9BVl9PSSB+IEhvcmFzX3BhbnRhbGxhX2RpYSwgZmFtaWx5ID0gYmlub21pYWwsIGRhdGEgPSBjY2RfdmlzaW9uMjAyMF9FVEwpDQoNCnhfc2VxIDwtIHNlcShmcm9tID0gbWluKGNjZF92aXNpb24yMDIwX0VUTCRIb3Jhc19wYW50YWxsYV9kaWEsIG5hLnJtID0gVFJVRSksDQp0byA9IG1heChjY2RfdmlzaW9uMjAyMF9FVEwkSG9yYXNfcGFudGFsbGFfZGlhLCBuYS5ybSA9IFRSVUUpLA0KbGVuZ3RoLm91dCA9IDExNjYpDQogDQpgYGANCg0KIyMjIyBHcsOhZmljYSBkZWwgTW9kZWxvIFJMb2dTIChBZ3VkZXphX1Zpc3VhbF9PRCkNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTX0FWX09ELCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCg0KcGxvdChiYWphX0FWX09EIH4gSG9yYXNfcGFudGFsbGFfZGlhLA0KZGF0YSA9IGNjZF92aXNpb24yMDIwX0VUTCwNCm1haW4gPSBwYXN0ZSgiUHJvYmFiaWxpZGFkIGRlIGJhamEgQVYgT0RcbihVbWJyYWwgPCIsIHVtYnJhbF9PRCwgIikiKSwNCnhsYWIgPSAiSG9yYXMgZGUgcGFudGFsbGEgYWwgZMOtYSIsDQp5bGFiID0gIkVzdGFkbyBiYWphIEFWICgwID0gTm8sIDEgPSBTw60pIiwNCmNvbCA9ICJncmF5NTAiLA0KcGNoID0gMTYpDQoNCmxpbmVzKHhfc2VxLA0KcHJlZGljdChtb2RfbG9nX09ELA0KbmV3ZGF0YSA9IGRhdGEuZnJhbWUoSG9yYXNfcGFudGFsbGFfZGlhID0geF9zZXEpLA0KdHlwZSA9ICJyZXNwb25zZSIpLA0KY29sID0gInJlZCIsDQpsd2QgPSAzKQ0KDQpgYGANCg0KRWwgZ3LDoWZpY28gbXVlc3RyYSBsYSByZWxhY2nDs24gZW50cmUgbGFzIGhvcmFzIGRlIHBhbnRhbGxhIGFsIGTDrWEgeSBsYSBwcm9iYWJpbGlkYWQgZXN0aW1hZGEgZGUgcHJlc2VudGFyIGJhamEgYWd1ZGV6YSB2aXN1YWwgZW4gZWwgb2pvIGRlcmVjaG8gKiooQVYgT0QgPCAwLjcpKiosIG1vZGVsYWRhIG1lZGlhbnRlIHVuYSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgYmluYXJpYS4gTG9zIHB1bnRvcyBncmlzZXMgcmVwcmVzZW50YW4gbGFzIG9ic2VydmFjaW9uZXMgaW5kaXZpZHVhbGVzLCBkb25kZSBlbCB2YWxvciAxIGluZGljYSBwcmVzZW5jaWEgZGUgYmFqYSBhZ3VkZXphIHZpc3VhbCB5IGVsIHZhbG9yIDAgc3UgYXVzZW5jaWEsIG1pZW50cmFzIHF1ZSBsYSBsw61uZWEgcm9qYSBjb3JyZXNwb25kZSBhIGxhIHByb2JhYmlsaWRhZCBhanVzdGFkYSBwb3IgZWwgbW9kZWxvLg0KDQpTZSBvYnNlcnZhIHF1ZSBsYSBwcm9iYWJpbGlkYWQgZGUgYmFqYSBhZ3VkZXphIHZpc3VhbCBhdW1lbnRhIGxpZ2VyYW1lbnRlIGEgbWVkaWRhIHF1ZSBzZSBpbmNyZW1lbnRhbiBsYXMgaG9yYXMgZGUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMsIGxvIHF1ZSBzZSByZWZsZWphIGVuIGxhIHBlbmRpZW50ZSBwb3NpdGl2YSBkZSBsYSBjdXJ2YSBsb2fDrXN0aWNhLiBTaW4gZW1iYXJnbywgZXN0ZSBhdW1lbnRvIGVzIHN1YXZlIHkgcHJvZ3Jlc2l2bywgbG8gcXVlIHN1Z2llcmUgcXVlLCAqKmF1bnF1ZSBleGlzdGUgdW5hIGFzb2NpYWNpw7NuIHBvc2l0aXZhIGVudHJlIGFtYmFzIHZhcmlhYmxlcywgZWwgZWZlY3RvIGRlIGxhcyBob3JhcyBkZSBwYW50YWxsYSBzb2JyZSBsYSBiYWphIGFndWRlemEgdmlzdWFsIGVuIGVsIG9qbyBkZXJlY2hvIGVzIG1vZGVyYWRvKiouDQoNCkxhIGVzdGFiaWxpZGFkIGRlIGxhIGN1cnZhIGVuIHRvcm5vIGEgdmFsb3JlcyBpbnRlcm1lZGlvcyBkZSBwcm9iYWJpbGlkYWQgaW5kaWNhIHF1ZSBlbCB1c28gZGUgcGFudGFsbGFzLCBwb3Igc8OtIHNvbG8sIG5vIGV4cGxpY2EgY29tcGxldGFtZW50ZSBsYSBwcmVzZW5jaWEgZGUgYmFqYSBhZ3VkZXphIHZpc3VhbCwgbG8gY3VhbCBzdWdpZXJlIGxhIHBvc2libGUgaW5mbHVlbmNpYSBkZSBvdHJvcyBmYWN0b3JlcyBubyBpbmNsdWlkb3MgZW4gZWwgbW9kZWxvLCBjb21vIGxhIGVkYWQsIGNvbmRpY2lvbmVzIHByZWV4aXN0ZW50ZXMgbyBow6FiaXRvcyB2aXN1YWxlcyBhZGljaW9uYWxlcy4NCg0KRW4gc8OtbnRlc2lzLCAqKmVsIG1vZGVsbyBldmlkZW5jaWEgdW5hIHRlbmRlbmNpYSBwb3NpdGl2YSBlbnRyZSBlbCB0aWVtcG8gZGUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMgeSBsYSBwcm9iYWJpbGlkYWQgZGUgYmFqYSBhZ3VkZXphIHZpc3VhbCBlbiBlbCBvam8gZGVyZWNobywgYXVucXVlIGVsIGVmZWN0byBvYnNlcnZhZG8gbm8gZXMgYWJydXB0bywgbG8gcXVlIHJlc3BhbGRhIGxhIG5lY2VzaWRhZCBkZSBjb25zaWRlcmFyIHZhcmlhYmxlcyBjb21wbGVtZW50YXJpYXMgcGFyYSB1bmEgZXhwbGljYWNpw7NuIG3DoXMgcm9idXN0YSBkZWwgZmVuw7NtZW5vIHZpc3VhbCBhbmFsaXphZG8qKi4NCg0KIyMjIyBHcsOhZmljYSBkZWwgTW9kZWxvIFJMb2dTIChBZ3VkZXphX1Zpc3VhbF9PSSkNCmBgYHtyIGdyYWZpY2FfTW9kZWxvX1JMb2dTX0FWX09JLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnBsb3QoYmFqYV9BVl9PSSB+IEhvcmFzX3BhbnRhbGxhX2RpYSwNCmRhdGEgPSBjY2RfdmlzaW9uMjAyMF9FVEwsDQptYWluID0gcGFzdGUoIlByb2JhYmlsaWRhZCBkZSBiYWphIEFWIE9JXG4oVW1icmFsIDwiLCB1bWJyYWxfT0ksICIpIiksDQp4bGFiID0gIkhvcmFzIGRlIHBhbnRhbGxhIGFsIGTDrWEiLA0KeWxhYiA9ICJFc3RhZG8gYmFqYSBBViAoMCA9IE5vLCAxID0gU8OtKSIsDQpjb2wgPSAiZ3JheTUwIiwNCnBjaCA9IDE2KQ0KDQpsaW5lcyh4X3NlcSwNCnByZWRpY3QobW9kX2xvZ19PSSwNCm5ld2RhdGEgPSBkYXRhLmZyYW1lKEhvcmFzX3BhbnRhbGxhX2RpYSA9IHhfc2VxKSwNCnR5cGUgPSAicmVzcG9uc2UiKSwNCmNvbCA9ICJibHVlIiwNCmx3ZCA9IDMpDQoNCnN1bW1hcnkobW9kX2xvZ19PSSkNCmV4cChjb2VmKG1vZF9sb2dfT0kpKSANCmBgYA0KDQpFbCBncsOhZmljbyByZXByZXNlbnRhIGxhIHJlbGFjacOzbiBlbnRyZSBsYXMgaG9yYXMgZGUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMgcG9yIGTDrWEgeSBsYSBwcm9iYWJpbGlkYWQgZXN0aW1hZGEgZGUgcHJlc2VudGFyIGJhamEgYWd1ZGV6YSB2aXN1YWwgZW4gZWwgb2pvIGl6cXVpZXJkbyAqKihBViBPSSA8IDAuNykqKiwgbW9kZWxhZGEgbWVkaWFudGUgdW5hIHJlZ3Jlc2nDs24gbG9nw61zdGljYSBiaW5hcmlhLiBMb3MgcHVudG9zIGdyaXNlcyBjb3JyZXNwb25kZW4gYSBsYXMgb2JzZXJ2YWNpb25lcyBpbmRpdmlkdWFsZXMsIGRvbmRlIGVsIHZhbG9yIDEgaW5kaWNhIHByZXNlbmNpYSBkZSBiYWphIGFndWRlemEgdmlzdWFsIHkgZWwgdmFsb3IgMCBzdSBhdXNlbmNpYSwgbWllbnRyYXMgcXVlIGxhIGzDrW5lYSBhenVsIHJlcHJlc2VudGEgbGEgcHJvYmFiaWxpZGFkIGFqdXN0YWRhIHBvciBlbCBtb2RlbG8uDQoNCkxhIGN1cnZhIGxvZ8Otc3RpY2EgbXVlc3RyYSB1bmEgcGVuZGllbnRlIHBvc2l0aXZhIGxldmUsIGxvIHF1ZSBpbmRpY2EgcXVlLCBhIG1lZGlkYSBxdWUgYXVtZW50YW4gbGFzIGhvcmFzIGRlIHVzbyBkZSBwYW50YWxsYXMsIGxhIHByb2JhYmlsaWRhZCBkZSBiYWphIGFndWRlemEgdmlzdWFsIGVuIGVsIG9qbyBpenF1aWVyZG8gdGllbmRlIGEgaW5jcmVtZW50YXJzZSBkZSBmb3JtYSBncmFkdWFsLiBObyBvYnN0YW50ZSwgZWwgY2FtYmlvIG9ic2VydmFkbyBlcyBtb2RlcmFkbywgbG8gcXVlIHN1Z2llcmUgcXVlIGVsIGVmZWN0byBkZSBsYSBleHBvc2ljacOzbiBhIHBhbnRhbGxhcyBzb2JyZSBsYSBhZ3VkZXphIHZpc3VhbCBkZWwgb2pvIGl6cXVpZXJkbyBlcyBsaW1pdGFkbyBjdWFuZG8gc2UgY29uc2lkZXJhIGRlIG1hbmVyYSBhaXNsYWRhLg0KDQpMYSBkaXNwZXJzacOzbiBkZSBsb3MgdmFsb3JlcyBvYnNlcnZhZG9zIHkgbGEgcmVsYXRpdmEgZXN0YWJpbGlkYWQgZGUgbGEgY3VydmEgaW5kaWNhbiBxdWUgbGFzIGhvcmFzIGRlIHBhbnRhbGxhIG5vIGNvbnN0aXR1eWVuIHVuIHByZWRpY3RvciBmdWVydGUgcG9yIHPDrSBzb2xhcywgbG8gY3VhbCByZWZ1ZXJ6YSBsYSBuZWNlc2lkYWQgZGUgaW5jb3Jwb3JhciBvdHJhcyB2YXJpYWJsZXMgZXhwbGljYXRpdmFzLCBjb21vIGxhIGVkYWQsIGNvbmRpY2lvbmVzIHJlZnJhY3RpdmFzIHByZXZpYXMgbyBow6FiaXRvcyB2aXN1YWxlcywgcGFyYSBtZWpvcmFyIGxhIGNhcGFjaWRhZCBwcmVkaWN0aXZhIGRlbCBtb2RlbG8uDQoNCkVuIGNvbmNsdXNpw7NuLCAqKmVsIG1vZGVsbyBldmlkZW5jaWEgdW5hIGFzb2NpYWNpw7NuIHBvc2l0aXZhIGTDqWJpbCBlbnRyZSBlbCB0aWVtcG8gZGUgZXhwb3NpY2nDs24gYSBwYW50YWxsYXMgeSBsYSBwcm9iYWJpbGlkYWQgZGUgYmFqYSBhZ3VkZXphIHZpc3VhbCBlbiBlbCBvam8gaXpxdWllcmRvLCBlbiBjb25jb3JkYW5jaWEgY29uIGxvcyByZXN1bHRhZG9zIG9idGVuaWRvcyBwYXJhIGVsIG9qbyBkZXJlY2hvLCBsbyBxdWUgc3VnaWVyZSB1biBjb21wb3J0YW1pZW50byB2aXN1YWwgc2ltaWxhciBlbnRyZSBhbWJvcyBvam9zIGZyZW50ZSBhIGxhIHZhcmlhYmxlIGFuYWxpemFkYSoqLg0KDQojIyAqKjYuIENvbmNsdXNpb25lcyoqDQoNCkNvbXBsZW1lbnRhcmlhbWVudGUgYSBsb3MgYW7DoWxpc2lzIGV4cHVlc3RvcyBlbiBsYXMgc2VjY2lvbmVzIGRlIGVzdHVkaW8gZGUgY2FkYSBtb2RlbG8gZGVzYXJyb2xsYWRvIGVuIGVzdGUgdHJhYmFqbywgcmVzdWx0YSBwZXJ0aW5lbnRlIHJlYWxpemFyIHVuYSByZWZsZXhpw7NuIGdsb2JhbCBzb2JyZSBlbCBwcm9ibGVtYSBhYm9yZGFkbyBhIGxhIGx1eiBkZSBsb3MgaGFsbGF6Z29zIG9idGVuaWRvcy4gRW4gcGFydGljdWxhciwgZWwgZXN0dWRpbyBwZXJtaXRpw7MgZXhwbG9yYXIgbGEgcmVsYWNpw7NuIGVudHJlIGxhIGFndWRlemEgdmlzdWFsIGRlIGxvcyBwYWNpZW50ZXMgeSBkaXZlcnNvcyBmYWN0b3JlcyBhc29jaWFkb3MsIGNvbiBlc3BlY2lhbCDDqW5mYXNpcyBlbiBsYXMgaG9yYXMgZGUgZXhwb3NpY2nDs24gZGlhcmlhIGEgcGFudGFsbGFzIHkgb3RyYXMgdmFyaWFibGVzIGRlIGludGVyw6lzIGNsw61uaWNvLg0KDQpFbCBhbsOhbGlzaXMgcmVhbGl6YWRvIG11ZXN0cmEgcXVlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcywgZW4gZXNwZWNpYWwgbGFzIHJlbGFjaW9uYWRhcyBjb24gbGEgYWd1ZGV6YSB2aXN1YWwgKEFWX09ELCBBVl9PSSkgeSBsYXMgaG9yYXMgZGUgcGFudGFsbGEgYWwgZMOtYSwgZWplcmNlbiB1biBpbXBhY3RvIHJlbGV2YW50ZSBlbiBsYSBjYXBhY2lkYWQgcHJlZGljdGl2YSBkZSBsb3MgbW9kZWxvcyBwYXJhIGVzdGltYXIgbGEgcHJvYmFiaWxpZGFkIGRlIHByZXNlbnRhciBiYWphIGFndWRlemEgdmlzdWFsLiBFbiBsb3MgbW9kZWxvcyBkZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EgYmluYXJpYSwgc2Ugb2JzZXJ2w7MgcXVlLCBhIG1lZGlkYSBxdWUgYXVtZW50YSBlbCB0aWVtcG8gZnJlbnRlIGEgcGFudGFsbGFzLCB0aWVuZGUgYSBpbmNyZW1lbnRhcnNlIGxhIHByb2JhYmlsaWRhZCBkZSBxdWUgbGEgYWd1ZGV6YSB2aXN1YWwgc2UgZW5jdWVudHJlIHBvciBkZWJham8gZGVsIHVtYnJhbCBkZWZpbmlkbywgYXVucXVlIGNvbiB1biBncmFkbyBkZSBpbmNlcnRpZHVtYnJlIGFzb2NpYWRvIGEgbGEgdmFyaWFiaWxpZGFkIGluZGl2aWR1YWwgZGUgbG9zIHBhY2llbnRlcy4gRGUgZm9ybWEgY29tcGxlbWVudGFyaWEsIG90cm9zIHByZWRpY3RvcmVzIGV2YWx1YWRvcyAoY29tbyB2YXJpYWJsZXMgZGVtb2dyw6FmaWNhcyBvIGRlIGjDoWJpdG9zKSBtb3N0cmFyb24gcG90ZW5jaWFsIHBhcmEgZW5yaXF1ZWNlciBsYSBleHBsaWNhY2nDs24gZGVsIGZlbsOzbWVubywgcHVlcyBhdW4gY3VhbmRvIHN1IGVmZWN0byBubyBzaWVtcHJlIGZ1ZSBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZvIGVuIHRvZG9zIGxvcyBtb2RlbG9zIGFqdXN0YWRvcywgdGFsIGNvbW8gbG8gbWVuY2lvbmEgKFtARkFBVlBFQkR1YXJ0ZTIwMjNdKS4NCg0KU2kgYmllbiBsYXMgdmFyaWFibGVzIHRyYWJhamFkYXMgZXhwbGljYW4gdW5hIGZyYWNjacOzbiBpbXBvcnRhbnRlIGRlIGxhIHZhcmlhY2nDs24gb2JzZXJ2YWRhIGVuIGxhIGNvbmRpY2nDs24gdmlzdWFsIGRlIGxvcyBwYWNpZW50ZXMsIHRhbWJpw6luIGVzIGV2aWRlbnRlIHF1ZSBubyBjYXB0dXJhbiBsYSB0b3RhbGlkYWQgZGVsIGZlbsOzbWVuby4gTGEgcHJvcG9yY2nDs24gZGUgdmFyaWFiaWxpZGFkIG5vIGV4cGxpY2FkYSBzdWdpZXJlIGxhIHByZXNlbmNpYSBkZSBvdHJvcyBmYWN0b3JlcyBubyBtZWRpZG9zLCB0YWxlcyBjb21vIGNvbmRpY2lvbmVzIG9mdGFsbW9sw7NnaWNhcyBwcmVleGlzdGVudGVzLCBmYWN0b3JlcyBnZW7DqXRpY29zLCBjYWxpZGFkIGRlIGxhIGlsdW1pbmFjacOzbiwgZXJnb25vbcOtYSBkZWwgcHVlc3RvIGRlIHRyYWJham8gbyBlc3R1ZGlvLCB1c28gZGUgY29ycmVjY2nDs24gw7NwdGljYSwgZW50cmUgb3Ryb3MuIEVzdGUgZXNwYWNpbyBkZSBpbmNlcnRpZHVtYnJlIGNvbnN0aXR1eWUgdW5hIG9wb3J0dW5pZGFkIHBhcmEgZnV0dXJhcyBpbnZlc3RpZ2FjaW9uZXMgcXVlIGluY29ycG9yZW4gdW4gY29uanVudG8gbcOhcyBhbXBsaW8gZGUgY2FyYWN0ZXLDrXN0aWNhcyBjbMOtbmljYXMgeSBjb250ZXh0dWFsZXMsIGNvbiBlbCBmaW4gZGUgY29uc3RydWlyIG1vZGVsb3MgbcOhcyByb2J1c3RvcyB5IHByZWNpc29zIHBhcmEgbGEgZXZhbHVhY2nDs24gZGVsIHJpZXNnbyBkZSBkZXRlcmlvcm8gdmlzdWFsIGFzb2NpYWRvIGFsIHVzbyBpbnRlbnNpdm8gZGUgcGFudGFsbGFzLg0KDQpEZXNkZSBlbCBwdW50byBkZSB2aXN0YSB0w6ljbmljbyB5IG1ldG9kb2zDs2dpY28sIGxhIGV4cGVyaWVuY2lhIGRlIGVtcGxlYXIgaGVycmFtaWVudGFzIGNvbW8gUiwgUlN0dWRpbyB5IFJNYXJrZG93biBmdWUgZXNwZWNpYWxtZW50ZSB2YWxpb3NhLiBFc3RhcyBwbGF0YWZvcm1hcyBmYWNpbGl0YXJvbiB0YW50byBlbCBwcm9jZXNhbWllbnRvIHkgZGVwdXJhY2nDs24gZGUgbG9zIGRhdG9zIGNvbW8gbGEgaW1wbGVtZW50YWNpw7NuIGRlIHTDqWNuaWNhcyBkZSByZWdyZXNpw7NuIGxpbmVhbCB5IGxvZ8Otc3RpY2EsIGxhIGdlbmVyYWNpw7NuIGRlIHZpc3VhbGl6YWNpb25lcyB5IGxhIGRvY3VtZW50YWNpw7NuIHJlcHJvZHVjaWJsZSBkZSBsb3MgYW7DoWxpc2lzLiBFbCB0cmFiYWpvIHJlYWxpemFkbyBwZXJtaXRpw7MgY29uc29saWRhciBoYWJpbGlkYWRlcyBlbiBlbCBtYW5lam8gZGUgbW9kZWxvcyBlc3RhZMOtc3RpY29zIGFwbGljYWRvcyBhIGRhdG9zIGRlIHNhbHVkIHksIGFsIG1pc21vIHRpZW1wbywgZXZpZGVuY2nDsyBlbCBwb3RlbmNpYWwgZGUgZXN0YXMgaGVycmFtaWVudGFzIHBhcmEgZWwgZGVzYXJyb2xsbyBkZSBwcm95ZWN0b3MgbcOhcyBhdmFuemFkb3MgZGUgbW9kZWxhbWllbnRvIHkgcHJlZGljY2nDs24gZW4gY29udGV4dG9zIHJlYWxlcy4NCg0KRW50cmUgbG9zIGVuZm9xdWVzIGVtcGxlYWRvcywgZWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbG9nw61zdGljYSByZXN1bHTDsyBwYXJ0aWN1bGFybWVudGUgYXRyYWN0aXZvIHkgcm9idXN0byBwYXJhIGVsIGFuw6FsaXNpcyBkZSBsb3MgZGF0b3MsIGRlYmlkbyBhIHN1IGNhcGFjaWRhZCBwYXJhIHRyYWR1Y2lyIHJlbGFjaW9uZXMgcG90ZW5jaWFsbWVudGUgbm8gbGluZWFsZXMgZW4gcHJvYmFiaWxpZGFkZXMgZsOhY2lsbWVudGUgaW50ZXJwcmV0YWJsZXMuIEVzdGEgY2FyYWN0ZXLDrXN0aWNhIGZ1ZSBjbGF2ZSBwYXJhIGNvbXByZW5kZXIgZGUgbWFuZXJhIGludHVpdGl2YSBjw7NtbyBsYXMgaG9yYXMgZGUgcGFudGFsbGEgeSBvdHJhcyB2YXJpYWJsZXMgc2UgYXNvY2lhbiBjb24gbGEgcHJvYmFiaWxpZGFkIGRlIHByZXNlbnRhciBiYWphIGFndWRlemEgdmlzdWFsLiBDb21vIHByb3llY2Npw7NuIGZ1dHVyYSwgc2Vyw61hIGludGVyZXNhbnRlIGNvbnNpZGVyYXIgZWwgZGVzYXJyb2xsbyBkZSBtb2RlbG9zIG3DoXMgY29tcGxlam9zIHF1ZSBpbnRlZ3JlbiB1biBtYXlvciBuw7ptZXJvIGRlIHByZWRpY3RvcmVzIHkgcGVybWl0YW4gcHJlZGVjaXIgY29uIG1heW9yIGV4YWN0aXR1ZCBlbCByaWVzZ28gZGUgYWx0ZXJhY2lvbmVzIHZpc3VhbGVzLCBjb250cmlidXllbmRvIGFzw60gYSBlbmZvcXVlcyBwcmV2ZW50aXZvcyB5IHBlcnNvbmFsaXphZG9zIHF1ZSByZXN1bHRlbiBkZSB1dGlsaWRhZCB0YW50byBwYXJhIGxvcyBwYWNpZW50ZXMgY29tbyBwYXJhIGxvcyBwcm9mZXNpb25hbGVzIGRlIGxhIHNhbHVkLg0KDQpGaW5hbG1lbnRlLCBlcyBpbXBvcnRhbnRlIGRlc3RhY2FyIHF1ZSBlc3RlIHRyYWJham8gZnVlIGRlc2Fycm9sbGFkbyBlbiBsYSBVbml2ZXJzaWRhZCBkZWwgVmFsbGUsIHNlY2Npb25hbCBaYXJ6YWwsIGVuIGVsIG1hcmNvIGRlbCBjdXJzbyBkZSBHZXN0acOzbiBkZSBEYXRvcyBwYXJhIEluZ2VuaWVyw61hIEluZHVzdHJpYWwsIGNvcnJlc3BvbmRpZW50ZSBhbCBwZXJpb2RvIGFjYWTDqW1pY28gYWdvc3Rv4oCTZGljaWVtYnJlIGRlIDIwMjUuIEVuIGVzdGUgc2VudGlkbywgZWwgcHJveWVjdG8gc2UgZW50aWVuZGUgY29tbyB1biBlamVyY2ljaW8gYWNhZMOpbWljbyBhcGxpY2Fkbywgc2luIHByZXZpc2nDs24gZGUgYWN0dWFsaXphY2lvbmVzIHBvc3RlcmlvcmVzLCBwZXJvIGNvbiBlbCBwb3RlbmNpYWwgZGUgc2VydmlyIGNvbW8gYmFzZSBjb25jZXB0dWFsIHkgbWV0b2RvbMOzZ2ljYSBwYXJhIGZ1dHVyYXMgaW52ZXN0aWdhY2lvbmVzIGVuIGVsIMOhbWJpdG8gZGUgbGEgc2FsdWQgdmlzdWFsIHkgZWwgdXNvIGRlIGRpc3Bvc2l0aXZvcyBlbGVjdHLDs25pY29zLg0KDQojIyAqKjcuIEJpYmxpb2dyYWbDrWEqKg0KDQoNCg==