Objetivos y Anotaciones ::Fase 1

1.1. Objetivos

Estudiar desde el punto de vista de la estadistica descriptiva multivariante (cálculos(“registrosclinicos(V1).xlsx”), visualizaciones e interpretaciones) a un conjunto de datos sobre registros clinicos de pacientes de una clínica de Colombia.

1.2. Descripción de los Datos

El conjunto de datos “Registros clínicos” recopila información sobre pacientes y aspectos socioeconómicos. Incluye variables como el número de hijos, género del paciente, tipo de asistencia médica, uso de sustancias psicoactivas, proximidad a centros médicos, estrato socioeconómico, peso, altura e ingresos mensuales. Estos datos pueden utilizarse para analizar la salud de los pacientes y cómo factores socioeconómicos pueden influir en su bienestar y acceso a la atención médica.

Fuente del conjunto de Datos

El conjunto de datos del trabajo se obtuvo casi totalmente de Kaggle : https://www.kaggle.com/

Es conveniente anotar que Kaggle es una compañia subsidiaria de Google LLC que mantiene una comunidad online de cientificos de datos y profesionales de aprendizaje automático. Esta empresa permite sus usuarios encontrar y publicar conjunto de datos, explorar y crear modelos en un entorno de ciencia de datos basados en la web, trabajar con otros cientificos de datos e ingenieros de aprendizaje automatico y participar en un curso para resolver desafios de ciencia de datos.

Contexto del conjunto de Datos

Recopila resgistros sobre la atención medica de pacientes en una clinica de Colombia este conjunto incluye datos demograficos como edad, estrato socioeconomico, peso, altura, ingreso mensul, genero, numero de hijos e información sobre procedimientos médicos y de comportamiento de pacientes. Este conjunto de datos se actualizó por última vez en el año 2022.

Descripcion del conjunto de Datos

El conjunto de datos contiene 11 campos y 4999 registros. Uno de los campos es simplemente un identificador numérico secuencial de los registros de cada paciente;otro campo es un identificador de decision;otros tres son de naturaleza politómica; y el resto son numéricos estrictamente positivos. La lista siguiente describe de izquierda a derecha, como aparecen en el rango o conjunto de datos que los contiene y se establece para cada campo, excepto el campo Codigo de paciente, el tipo de variable y su escala de medición (tipo_de_variable::escala_de_medición[ordenamiento]):

• Código de paciente (identificador): registra un número secuenciado a partir de 1 para identificar de forma única cada registro de paciente consignado en el conjunto de datos.

• Edades (cuantitativa::razón): contiene las edades de cada paciente a partir de 12 hasta 56 años de edad.

• Número de hijos (cualitativa::razón): registra la cantidad de hijos que tienen los pacientes, donde estos van desde 1 y el máximo rango va hasta 6 integrantes.

• Genero del paciente (cualitativa::nominal): registra el sexo del paciente y se categoriza por femenino y masculino.

• Asistencia privada publica (cualitativa::nominal): registro dado a partir de la asistencia a la clínica donde el paciente informa el dato sobre su atención, donde esta se clasifica en dos las cuales son privada o pública.

• Uso sustancias psicoactivas (cuantitativa:: decisión ) registra el consuma de sustancias psicoactivas por parte del paciente y se categoriza con respuesta cerrada donde solo existen dos opciones : no y si.

• Residencia cerca al centro ( cuantitativa:: decisión) registra la residencia del paciente si es cerca al centro o no.

• Estrato socioeconómico (cuantitativa:: razón ) registra los datos clasificándolos de 1 a 6.

• Peso (cuantitativa::razón): contiene el peso de cada paciente en kilogramos donde este va de 42kg a 101kg.

• Altura (cuantitativa::razón): registra la altura de cada paciente usando la escala de medición en cm

• Ingresos mensuales (cuantitativa::razón): registra los ingresos mensuales de cada paciente en pesos colombianos.

Estructura del conjunto de Datos

{r Estructura_Conjunto_de_Datos, fig.align = 'center'} str(clinic_dataset) ##conjunto de datos inicial {r str(clinic_Dataset_Initial) ##Estructura del conjunto de datos reeescrito {r str(clinic_Dataset) ##Conjunto de datos reescrito {r clinic_Dataset ### Visualizacion del conjunto de Datos

clinic_dataset
## # A tibble: 4,999 × 11
##    codigo_de_paciente edades numero_de_hijos genero_del_paciente
##                 <dbl>  <dbl>           <dbl> <chr>              
##  1               3999     51               6 masculino          
##  2               1076     42               6 masculino          
##  3               2382     41               6 masculino          
##  4                 91     51               6 femenino           
##  5                630     42               6 masculino          
##  6               4005     42               6 masculino          
##  7               3210     44               6 masculino          
##  8                216     34               6 masculino          
##  9               4215     55               6 masculino          
## 10               2927     21               6 masculino          
## # ℹ 4,989 more rows
## # ℹ 7 more variables: asistencia_privada_publica <chr>,
## #   uso_sustancias_psicoativas <chr>, residencia_cerca_al_centro <chr>,
## #   estrato_socioeconomico <chr>, `peso (kg)` <dbl>, `altura (cm)` <dbl>,
## #   `ingresos mensuales` <dbl>

1.3. Estimaciones Multivariadas

Como se menciona en (Aristizábal R., 2017) la de media, varianza y covarianza conforman un conjunto de medidas fundamentales para describir el comportamiento posicional, dispersivo y correlacional de variables aleatorias. En este sentido, el conjunto de datos de trabajo que posee cinco variables numéricas, y que está representado matricialmente, estima las medidas anteriores a partir de vectores y matrices en el estudio descriptivo multivariable. El vector de medias indica el comportamiento posicional en el sentido de valor esperado o punto medio para cada variable en relación con todos sus registros. La matriz de varianzas-covarianzas estima las dispersiones, en su diagonal principal, de cada variable del conjunto de datos respecto de cada media obtenida del vector de medias. Además, por encima o por debajo de la diagonal principal, se estiman las covarianzas entre las combinaciones de los posibles pares de variables del conjunto de datos. Para más detalles se puede consultar a (Aristizábal R., 2017). Lo anterior, para el conjunto de datos de trabajo, se desarrolla en la sección 3.2

Planteamiento del Problema

Con base en el conjunto de datos descrito en la sección 2 se calcularán e interpretarán, para las variables numéricas, el vector de medias, la matriz de varianzas-covarianzas y la matriz de correlaciones. Se recuerda que las variables numéricas son: ** estrato_socioeconomico, peso (kg), altura (cm), ingresos mensuales, numero_de_hijos.**

Desarrollo del Análisis

La navegación a través de las pestañas muestra el cálculo de los siguientes objetos: Vector de Medias x, Matriz de Varianzas-Covarianzas S y Matriz de Correlaciones R.

Vector de madias y boxplots

Para realizar un análisis mediante vectores de medidas y boxplots con los datos proporcionados, podrías considerar lo siguiente:

Vector de medias y diagramas de caja

  • Para cada variable (número de hijos, género del paciente, tipo de asistencia médica, uso de sustancias psicoactivas, proximidad de residencia al centro médico, estrato socioeconómico, peso, altura e ingresos mensuales), calcular medidas estadísticas como la media, la mediana, la desviación estándar, el mínimo, el máximo y los cuartiles.

  • Graficar boxplots para cada variable, lo que te permitirá visualizar la distribución de los datos, identificar valores atípicos y comparar la variabilidad entre diferentes grupos si es relevante (por ejemplo, comparar la distribución del peso entre pacientes de asistencia privada y pública).

apply(clinic_dataset[,-c(1,4,5,6,7,8)], 2, mean)
##             edades    numero_de_hijos          peso (kg)        altura (cm) 
##       3.934927e+01       3.312462e+00       7.038968e+01       1.637339e+00 
## ingresos mensuales 
##       5.011386e+06
clinic_dataset_Reducido = clinic_dataset[,-c(1,4,5,6,7,8)]
par(mfrow = c(1, ncol(clinic_dataset_Reducido)))
invisible(lapply(1:ncol(clinic_dataset_Reducido), function(i) boxplot(clinic_dataset_Reducido[, i])))

Matriz de varianza-covarianza

round(cov(clinic_dataset[,-c(1,4,5,6,7,8)]),2)
##                       edades numero_de_hijos  peso (kg) altura (cm)
## edades                115.14           -0.17       5.40       -0.15
## numero_de_hijos        -0.17            2.95       0.20        0.00
## peso (kg)               5.40            0.20     278.36        1.35
## altura (cm)            -0.15            0.00       1.35        0.01
## ingresos mensuales 265624.42       -44984.58 1223866.57     6488.07
##                    ingresos mensuales
## edades                   2.656244e+05
## numero_de_hijos         -4.498458e+04
## peso (kg)                1.223867e+06
## altura (cm)              6.488070e+03
## ingresos mensuales       8.404468e+12

Matriz de correlaciones

round(cor(clinic_dataset[,-c(1,4,5,6,7,8)]),2)
##                    edades numero_de_hijos peso (kg) altura (cm)
## edades               1.00           -0.01      0.03       -0.13
## numero_de_hijos     -0.01            1.00      0.01       -0.01
## peso (kg)            0.03            0.01      1.00        0.78
## altura (cm)         -0.13           -0.01      0.78        1.00
## ingresos mensuales   0.01           -0.01      0.03        0.02
##                    ingresos mensuales
## edades                           0.01
## numero_de_hijos                 -0.01
## peso (kg)                        0.03
## altura (cm)                      0.02
## ingresos mensuales               1.00

1.4. Gráficas multivariadas

En la guía de clase de ( Aristizábal R., 2017 ) se menciona que, 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 suavizan la comprensión de la Estructura de evaluación entre varias variables. En este sentido, el conjunto de datos de trabajo tendrá apoyo descriptivo gráfico a través de tres diagramas: uno conjunto que integra dispersión, distribución y correlaciones; otro basado en la renderización de polígonos, y por último, uno que recurre a las caras de Chernoff.

Planteamiento del problema

Con base en el conjunto de datos descrito en la sección 2 se calcularán e interpretarán, para las variables numéricas, las gráficas multivariadas de diagrama de correlaciones, matriz de diagrama de dispersión, diagrama de estrellas y caras de Chernoff. Se recuerda que las variables numéricas (en escalada de medición de razón) son:edades, numero de hijos,estrato socieconomico, peso, altura, ingresos mensuales.

Desarrollo del análisis {.tabset .tabset-pills}

Se observa que los puntos en el diagrama de dispersión están muy dispersos y no siguen una tendencia clara, esto nos indica una baja correlación; los cambios en una variable no están asociados con incrementos o dismininuciones predecibles en la otra variable. La falta de una fuerte correlación en un diagrama de dispersión puede deberse a la naturaleza de las variables, relaciones no lineales, factores ocultos o problemas en la medición. Los puntos que varían significativamente de la curva principal pueden ser valores atípicos o casos excepcionales; estos valores atípicos pueden afectar la correlación general y la forma de la curva.

En el segundo diagrama se dividió mediante colores la potabilidad del agua, al hacer esta diferenciacón se ve que este no es un facotr diferenciador del conjunto de datos, pues todo coninua estando muy disperso.

En el diagrama de estrellas se puede observar que la semilla tomada para el ejemplo es altamente irregular, ninguna tiende a parecerse entre sí, se podría pensar que uno de los factores que influencia este tipo de comportamiento son la gran variedad de propiedades que fueron evaluadas en dicha muestra de agua. La estrella 18 y 19 aparentemente tiene valores parecidos, y relativamente bajos en comparacion con el resto de estrellas, pero aún así sería erroneo decir que son similares, debido a que algun variables se observan diferentes.

Diagrama de conjuntos de dispersion, correlacion

library(tidyverse)
ggpairs(clinic_dataset[,-c(1,4,5,6,7)])

Diagrama de conjunto de dispersión, distribucion y correlaciones

Aquí no podemos ver la diferenciación por hombre y mujer ya que no es un factor influyente sobre nuestro conjunto de datos.

library(tidyverse)
ggpairs(clinic_dataset, columns = c(2,3,9,10,11), aes(color = genero_del_paciente, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

### Diagrama de estrella En estas gráficas podemos ver que algunas caras son similares como por ejemplo: La dos y la catorce, teniendo como proporciones casi iguales las siguientes variables: Estrato socieconomico, peso, altura, edades y numero de hijos.

set.seed(780728)
clinic_dataset_Reducido = clinic_dataset[sample(1:nrow(clinic_dataset),23),-c(1,4,5,6,7)]
stars(clinic_dataset_Reducido, len = 1, cex = 0.4, key.loc = c(10, 2), draw.segments = TRUE)

### Caras de chernoff

set.seed(780728)
clinic_dataset_Reducido = clinic_dataset[sample(1:nrow(clinic_dataset),23),-c(1,4,5,6,7,8)]
faces(clinic_dataset_Reducido)

## effect of variables:
##  modified item       Var                 
##  "height of face   " "edades"            
##  "width of face    " "numero_de_hijos"   
##  "structure of face" "peso (kg)"         
##  "height of mouth  " "altura (cm)"       
##  "width of mouth   " "ingresos mensuales"
##  "smiling          " "edades"            
##  "height of eyes   " "numero_de_hijos"   
##  "width of eyes    " "peso (kg)"         
##  "height of hair   " "altura (cm)"       
##  "width of hair   "  "ingresos mensuales"
##  "style of hair   "  "edades"            
##  "height of nose  "  "numero_de_hijos"   
##  "width of nose   "  "peso (kg)"         
##  "width of ear    "  "altura (cm)"       
##  "height of ear   "  "ingresos mensuales"

1.5. Normalidad multivariada

Como menciona (Porras C., 2016) para indagar o establecer el tipo de distribución multivariada de un conjunto de datos se puede recurrir a procedimientos descriptivos, como los gráficos, o a procedimientos inferenciales, como las pruebas estadísticas. En este sentido, se alcanza generalización de resultados al usar las estos últimos, si bien los primeros apoyan a las interpretaciones.

En este apartado se contempla el uso de procedimientos inferenciales para determinar si el conjunto de datos de trabajo, en relación con sus variables numéricas, se distribuye normal multivariado (DNM). Las pruebas de normalidad multivariada (PNM) a las que será sometido son: Mardia, Henze-Zirkler, Doornik-Hansen y Royston. Para estas pruebas de normalidad los test obedecen a un nivel de significancia α=0.05 y a las hipótesis:

                                        H0: Las variables tienen una DNM

                                       H1: Las variables NO tienen una DNM

La prueba de Mardia se basa en extensiones de asimetría y curtosis, el cuadrado de la distancia de Mahalanobis, la cantidad de variables p por tratar y la cantidad de registros n. Además, considera que la prueba estadística para la asimetría tiene una distribución χ2 y la prueba estadística para la curtosis se distirbuye aproximadamente normal. Los detalles sobre los parámetros de las distribuciones pueden consultarse en el trabajo de (Porras C., 2016). La prueba de Henze-Zirkler se basa en la distancia funcional, dado que si el conjunto de datos presenta una distribución normal multivariada, el estadístico de la prueba se distribuye aproximadamente como una lognormal, cuyos parámetros de media μ y varianza σ2 pueden ser consultados en (Porras C., 2016).

La prueba de Doornik-Hansen está basada en la asimetría y la curtosis de un conjunto de datos multivariados, que se transforma para garantizar la independencia. Es considerada más potente que la prueba de Shapiro-Wilk para casos multivariados. Su estadístico de prueba está definido como la suma de las transformaciones al cuadrado de la asimetría y la curtosis, y sigue, aproximadamente, una distribución χ2. Los detalles de la prueba pueden ser consultados en (Doornik & Hansen, 2008).

La prueba de Royston recurre a las pruebas Shapiro-Wilk o Shapiro-Francia para probar la normalidad multivariada. Así, si la curtosis es mayor que 3, la prueba de Royston usa Shapiro-Francia para distribuciones leptocurticas. Mientras que para distribuciones platicurticas usa Shapiro-Wilk. En ella los parámetros son obtenidos por aproximaciones polinomiales, esto puede ser consultado en (Porras C., 2016)

Planteamiento del problema

Con base en el conjunto de datos descrito en la sección 2 se hará una prueba estadística de normalidad multivariada, con un nivel de significancia α=0.05, para establecer si sus datos métricos provienen de una población normal multivariada. Se recuerda que las variables numéricas del conjunto de datos (en escalada de medición de razón) son: edades, numero de hijos,estrato socieconomico, peso, altura, ingresos mensuales.

Desarrollo del análisis

La navegación a través de las pestañas muestra que el conjunto de datos, en relación con sus variables numéricas,con un nivel de significancia α=0.05, para establecer si sus datos métricos provienen de una población normal multivariada. Se recuerda que las variables numéricas del conjunto de datos (en escalada de medición de razón) son:edades, numero de hijos,estrato socieconomico, peso, altura, ingresos mensuales.

Al implementar la prueba de normalidad Kolmogorov Smirnov,se observó que el valor p asociado con la prueba de Lilliefors (variante de la prueba de Kolmogorov-Smirnov) es extremadamente pequeño (p-value < 2.2e-16), lo que indica que hay evidencia significativa para rechazar la hipótesis nula de normalidad. Por lo tanto, basándonos en esta prueba, podríamos concluir que la variable AirQuality de tu conjunto de datos no sigue una distribución normal.

Con la ayuda de la prueba Shapiro-wilk nuevamente organic_carbon y turbity muestran valores mayores a 0.05 mostrando que dichas variables muestran un comportamiento normal y puede que se ajusten a una distribución normal, a diferencia del resto de varibles que dieron menores a nuestro parámetro de medida, apoyando la no normalidad. Con la ayuda de la prueba Shapiro-wilk nuevamente organic_carbon y turbity muestran valores mayores a 0.05 mostrando que dichas variables muestran un comportamiento normal y puede que se ajusten a una distribución normal, a diferencia del resto de varibles que dieron menores a nuestro parámetro de medida, apoyando la no normalidad.

Pruebas de normalidad

A continuacion se presentan las pruebas de normalidad realizadas al conjunto de datos con el fin de indentificar que variables estaban antes normalizadas. luego de revisar los resultados de normalidad se pudo observar que hay dos variables que destacan por su bajo valor de p-value, dandonos a entender que dichas variables puedieron haber sido tratadas anteriormente por otra persona, culpable de su comportamiento casi igual al de una distribución normal, dato que nos puede servir mas adelante para tomar concluciones sobre el conjunto de datos. Se muestran en las prubas en los botonoes Kolmogorov, Shapiro y Anderson.

PNM Mardia

El cuadro muestra que las variables no siguen una distribución normal, tanto de forma univariada como multivariada. Las medidas descriptivas indican la tendencia central, dispersión y forma de las distribuciones de las variables.

mvn(clinic_dataset[,-c(1,4,5,6,7,8)], mvnTest="mardia")
## $multivariateNormality
##              Test         Statistic p value Result
## 1 Mardia Skewness   3462.3589671877       0     NO
## 2 Mardia Kurtosis -10.2010931140503       0     NO
## 3             MVN              <NA>    <NA>     NO
## 
## $univariateNormality
##               Test           Variable Statistic   p value Normality
## 1 Anderson-Darling       edades        129.2280  <0.001      NO    
## 2 Anderson-Darling  numero_de_hijos    152.9438  <0.001      NO    
## 3 Anderson-Darling     peso (kg)        82.6160  <0.001      NO    
## 4 Anderson-Darling    altura (cm)      183.6962  <0.001      NO    
## 5 Anderson-Darling ingresos mensuales   59.6869  <0.001      NO    
## 
## $Descriptives
##                       n         Mean      Std.Dev     Median      Min
## edades             4999 3.934927e+01 1.073013e+01      42.00    12.00
## numero_de_hijos    4999 3.312462e+00 1.717430e+00       3.00     1.00
## peso (kg)          4999 7.038968e+01 1.668418e+01      70.00    42.00
## altura (cm)        4999 1.637339e+00 1.037203e-01       1.64     1.47
## ingresos mensuales 4999 5.011386e+06 2.899046e+06 5046744.00 12608.00
##                           Max       25th       75th         Skew   Kurtosis
## edades                  56.00      33.00      45.00 -0.605566766 -0.2834701
## numero_de_hijos          6.00       2.00       5.00  0.161060855 -1.2653672
## peso (kg)              101.00      55.00      85.00  0.261498185 -0.9856095
## altura (cm)              1.78       1.51       1.69 -0.106609250 -1.0872701
## ingresos mensuales 9999180.00 2451457.00 7511554.00 -0.002634235 -1.2193779

PNM Hense-Zirkler

El cuadro muestra que las variables no siguen una distribución normal, tanto de manera conjunta como individualmente. Además, ofrece estadísticas resumidas sobre las variables, como promedio, desviación estándar, mediana, mínimo, máximo, percentiles, asimetría y kurtosis.

mvn(clinic_dataset[,-c(1,4,5,6,7,8)], mvnTest="hz")
## $multivariateNormality
##            Test       HZ p value MVN
## 1 Henze-Zirkler 28.43863       0  NO
## 
## $univariateNormality
##               Test           Variable Statistic   p value Normality
## 1 Anderson-Darling       edades        129.2280  <0.001      NO    
## 2 Anderson-Darling  numero_de_hijos    152.9438  <0.001      NO    
## 3 Anderson-Darling     peso (kg)        82.6160  <0.001      NO    
## 4 Anderson-Darling    altura (cm)      183.6962  <0.001      NO    
## 5 Anderson-Darling ingresos mensuales   59.6869  <0.001      NO    
## 
## $Descriptives
##                       n         Mean      Std.Dev     Median      Min
## edades             4999 3.934927e+01 1.073013e+01      42.00    12.00
## numero_de_hijos    4999 3.312462e+00 1.717430e+00       3.00     1.00
## peso (kg)          4999 7.038968e+01 1.668418e+01      70.00    42.00
## altura (cm)        4999 1.637339e+00 1.037203e-01       1.64     1.47
## ingresos mensuales 4999 5.011386e+06 2.899046e+06 5046744.00 12608.00
##                           Max       25th       75th         Skew   Kurtosis
## edades                  56.00      33.00      45.00 -0.605566766 -0.2834701
## numero_de_hijos          6.00       2.00       5.00  0.161060855 -1.2653672
## peso (kg)              101.00      55.00      85.00  0.261498185 -0.9856095
## altura (cm)              1.78       1.51       1.69 -0.106609250 -1.0872701
## ingresos mensuales 9999180.00 2451457.00 7511554.00 -0.002634235 -1.2193779

PNM de Doornik-Hansen

El cuadro nos muestra que el conjunto de datos no sigue una distribución normal, tanto en un análisis multivariado como univariado. Las medidas descriptivas ofrecen información detallada sobre las variables, incluyendo tendencia central, dispersión, forma de la distribución y simetría.

mvn(clinic_dataset[,-c(1,4,5,6,7,8)], mvnTest="dh")
## $multivariateNormality
##             Test        E df p value MVN
## 1 Doornik-Hansen 92446.45 10       0  NO
## 
## $univariateNormality
##               Test           Variable Statistic   p value Normality
## 1 Anderson-Darling       edades        129.2280  <0.001      NO    
## 2 Anderson-Darling  numero_de_hijos    152.9438  <0.001      NO    
## 3 Anderson-Darling     peso (kg)        82.6160  <0.001      NO    
## 4 Anderson-Darling    altura (cm)      183.6962  <0.001      NO    
## 5 Anderson-Darling ingresos mensuales   59.6869  <0.001      NO    
## 
## $Descriptives
##                       n         Mean      Std.Dev     Median      Min
## edades             4999 3.934927e+01 1.073013e+01      42.00    12.00
## numero_de_hijos    4999 3.312462e+00 1.717430e+00       3.00     1.00
## peso (kg)          4999 7.038968e+01 1.668418e+01      70.00    42.00
## altura (cm)        4999 1.637339e+00 1.037203e-01       1.64     1.47
## ingresos mensuales 4999 5.011386e+06 2.899046e+06 5046744.00 12608.00
##                           Max       25th       75th         Skew   Kurtosis
## edades                  56.00      33.00      45.00 -0.605566766 -0.2834701
## numero_de_hijos          6.00       2.00       5.00  0.161060855 -1.2653672
## peso (kg)              101.00      55.00      85.00  0.261498185 -0.9856095
## altura (cm)              1.78       1.51       1.69 -0.106609250 -1.0872701
## ingresos mensuales 9999180.00 2451457.00 7511554.00 -0.002634235 -1.2193779

PNM de Royston

Este punto no lo llevamos acabo ya que nuestro conjunto de datos sobre-pasa el limite de cantidad de datos.

{r} mvn(clinic_dataset[,-c(1,4,5,6,7,8)], mvnTest=“royston”)

Objetivos y anotaciones :: Fase 2

2.1 Objetivos

En términos generales, esta segunda etapa de estudio mostrará cálculos, visualizaciones e interpretaciones con base en el conjunto de datos tratados en la fase 1 , pero ahora desde un enfoque de análisis de componentes principales sobre las variables cuantitativas, que incluyen: selección, calidad de representación, contribuciones e interpretación.

Recuérdese que el conjunto de datos de trabajo descrito en la sección 2 y los referentes teóricos en la sección 1 .

Por último, este trabajo fue procesado con R versión 4.2.2 (2022-10-31 ucrt) mediado por RStudio 2022.12.0 Build 353 en una plataforma x86_64-w64-mingw32.

2.2. Seleccion de componentes / Descripcion de componentes

Como es mencionado en el trabajo de (Díaz Morales & Morales Rivera, 2012) el Análisis de Componentes Principales (en adelante ACP) reestructura un conjunto de datos multivariado a través de la reducción de la cantidad de sus variables, en cuyo transfondo es innecesario asumir ninguna distribución de probabilidad de ellas. Esta reducción es lograda a través de combinaciones lineales de las variables originales, que deberán contener la mayor variabilidad posible presente en el conjunto de datos. En este sentido, el ACP logra crear nuevas variables, conocidas como componentes principales, que poseen características estadísticas de independencia (con base en el supuesto de normalidad) y no correlación.

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 varaibles de poco aporte e interpretación de los componentes resultantes en el contexto del problema del cual se obtuvieron los datos. Estas fases se desarrollan entre las secciones 7, 8, 9 y 10.

Planteamiento del problema

Con base en las variables cuantitativas del conjunto de datos descrito en la sección 2 se demanda primero establecer el porcentaje de varianza explicado por cada dimensión una vez procesado el ACP; y posteriormente, con base en el autovalor medio o usando un diagrama de sedimentación, decidir cuántos componentes retener.

Desarrollo del análisis

Para el desarrollo de algunos códidos que permiten estudiar el conjutno de datos, se calculó un subconjunto de datos llamado clinic_dataset_sin_NA en el cual todas las filas que carecian de valores en alguna de sus celadas, identificadas por R como NA, fueron imputados, haciendo uso de la función na.omit, para trabajar con un conjunto de datos completo, que funcione para los códigos que necesitamos correr.

##Matriz ACP

clinic_dataset_sin_NA<-na.omit(clinic_dataset)

get_eigenvalue(PCA(clinic_dataset_sin_NA[,-c(1,4,5,6,7,8)], ncp = 11, scale.unit = TRUE, graph = F))
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1  1.7877666        35.755332                    35.75533
## Dim.2  1.0229899        20.459798                    56.21513
## Dim.3  0.9968282        19.936564                    76.15169
## Dim.4  0.9892391        19.784782                    95.93648
## Dim.5  0.2031762         4.063524                   100.00000

##Matriz de correlaciones

round(cor(clinic_dataset[,-c(1,4,5,6,7,8)]),2)
##                    edades numero_de_hijos peso (kg) altura (cm)
## edades               1.00           -0.01      0.03       -0.13
## numero_de_hijos     -0.01            1.00      0.01       -0.01
## peso (kg)            0.03            0.01      1.00        0.78
## altura (cm)         -0.13           -0.01      0.78        1.00
## ingresos mensuales   0.01           -0.01      0.03        0.02
##                    ingresos mensuales
## edades                           0.01
## numero_de_hijos                 -0.01
## peso (kg)                        0.03
## altura (cm)                      0.02
## ingresos mensuales               1.00

##Valores y vectores propios

princomp(clinic_dataset[,-c(1,4,5,6,7,8)], cor = TRUE)$sdev^2
##    Comp.1    Comp.2    Comp.3    Comp.4    Comp.5 
## 1.7877666 1.0229899 0.9968282 0.9892391 0.2031762
princomp(clinic_dataset[,-c(1,4,5,6,7,8)], cor = TRUE)$loadings[ ,1:5]
##                          Comp.1      Comp.2     Comp.3      Comp.4       Comp.5
## edades              0.093957920  0.72429669  0.5938619  0.30444402  0.145630015
## numero_de_hijos     0.003617632 -0.43950280  0.7689037 -0.46398926  0.018036732
## peso (kg)          -0.698445543  0.10321225  0.1198727  0.06843579 -0.694599259
## altura (cm)        -0.708281954 -0.03792316 -0.0237954  0.01834392  0.704269684
## ingresos mensuales -0.040857301  0.51975057 -0.2029274 -0.82885937  0.001629892

##Correlaciones comparadas

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

##Gráfico de cattell

fviz_eig(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], scale.unit = T, graph = F), addlabels = T, ylim=c(0,90), main = "")

##Gráfico de cattell-kaiser

scree(clinic_dataset[,-c(1,4,5,6,7,8)],factors = FALSE, pc = TRUE, main ="")

2.3. Calidad de representación

Al retomar el trabajo de (Díaz Morales & Morales Rivera, 2012) se verifica que, una vez reducida la dimensionalidad del conjunto de datos y entendido que sus variables (estandarizadas) están representadas gráficamente por proyecciones de la hiperesfera de correlaciones, es necesario iniciar la interpretación de componentes a partir de dichas correlaciones, para luego la calidad de sus representaciones dada la reducción dimensional del conjunto de datos en términos de sus variables.

Planteamiento del problema

Con base en el conjunto de datos descrito en la sección 2 se demanda determinar la calidad de representación de las variables cuantitativas respecto a la cantidad de dimensiones calculadas que retienen la mayor cantidad de variabilidad, ver la sección 7.

Desarrollo del análisis

La navegación a través de las pestañas muestra que la reducción de la dimensionalidad del conjunto de datos conduce a analizar las calidades de representación en términos de la escala de contribuciones relativas basadas en un cociente de proyecciones con propiedades aditivas y de respuesta en escala continua entre0 y1 . Así, en particular:

El Círculo de Correlaciones expresa que se puede concebir un compenente tipo tamaño en el sentido de que la dimensión 1 muestra en él una correlación positiva con las seis variables de interés, además cercano a la frontera del círculo unitario y significativamente próximas al eje que la representa . Por otro lado, la dimensión 2 contrapone a las variables LOR y SOP con las demás. Otro aspecto por resaltar es la valoración mostrada entre pares de variables, que en términos del fenómeno estudiado conservan su naturaleza correlacional esperada hasta este punto del análisis. Un ejemplo resaltable es el par SOP y LOR que, en cierto sentido, están influenciados por la subjetividad, véase la sección 2 .

La Matriz de Representación , por otro lado, muestra valores significativamente cercanos a 1 del cociente de proyecciones coseno cuadrado en relación con la dimensión 1. En este sentido, los puntos proyectados están altamente asociados con este componente. Así, la estaña que muestra la Calidad de Representación indica en su escala un piso alto de0,84 de esta manera las calidades de representación, en relación con el componente 1, están encabezadas por CGPA y cierran con SOP . Cabe aclarar que la dimensión 2 sostiene una mejor representación de LOR que de SOP , por lo tanto, la calidad de representación de la primera en relación con la dimensión 1 se ve afectada.

Círculo de correlaciones

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

Matriz de representacion

(get_pca_var(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F)))$cos2
##                           Dim.1       Dim.2        Dim.3        Dim.4
## edades             1.578257e-02 0.536666335 0.3515533430 0.0916887751
## numero_de_hijos    2.339697e-05 0.197603506 0.5893376371 0.2129693619
## peso (kg)          8.721193e-01 0.010897674 0.0143238891 0.0046330597
## altura (cm)        8.968569e-01 0.001471229 0.0005644253 0.0003328783
## ingresos mensuales 2.984353e-03 0.276351160 0.0410489062 0.6796150416
##                           Dim.5
## edades             4.308981e-03
## numero_de_hijos    6.609803e-05
## peso (kg)          9.802604e-02
## altura (cm)        1.007745e-01
## ingresos mensuales 5.397471e-07

Calidad de representación

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

Coordenadas individuales

head((PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F))$ind$coord, n = 23L)
##         Dim.1      Dim.2     Dim.3       Dim.4       Dim.5
## 1  -2.0638426 -0.8519709 2.0917934 -0.91356041 -0.07755659
## 2   2.1153160 -1.2657273 1.8767544 -0.91168003 -0.20266947
## 3   0.6082646 -1.3782003 1.7433304 -0.79829627 -0.47449559
## 4  -2.0637907 -0.8513106 2.0915355 -0.91250731 -0.07755452
## 5   2.1154272 -1.2643128 1.8762021 -0.90942428 -0.20266504
## 6   2.1156129 -1.2619505 1.8752798 -0.90565707 -0.20265763
## 7  -0.1138084 -1.2584961 1.8014243 -0.81003178  0.12288241
## 8   0.3309693 -1.9321065 1.2516564 -0.53561906  0.17551764
## 9  -1.9305624 -0.5464828 2.3377576 -1.02639420 -0.18977479
## 10 -1.4366678 -2.9344446 0.3625104 -0.03319008  0.37626773
## 11  1.6714061 -1.1119521 1.9658291 -0.93486200  0.25445562
## 12 -1.8613104 -2.5811891 0.6558489 -0.15237972 -0.53995893
## 13 -2.0976341 -0.7568934 2.1497033 -0.91600132 -0.17347158
## 14  2.1170467 -1.2437114 1.8681587 -0.87657078 -0.20260043
## 15  0.3320344 -1.9185572 1.2463663 -0.51401171  0.17556013
## 16  0.3322772 -1.9154687 1.2451605 -0.50908646  0.17556982
## 17  0.7885143 -1.9286119 1.2649825 -0.51169771 -0.83101931
## 18 -0.1632812 -1.9041030 1.2301423 -0.49137031  0.53760578
## 19 -1.8602605 -2.5678332 0.6506343 -0.13108061 -0.53991705
## 20  0.7886205 -1.9272610 1.2644551 -0.50954346 -0.83101508
## 21 -2.0218896 -1.1981171 1.7592279 -0.70337628  0.26658544
## 22  1.0625115 -1.3194859 1.7394246 -0.78422816  0.85191791
## 23  1.6733625 -1.0870649 1.9561123 -0.89517377  0.25453367

2.4. Contribuciones

La navegación a través de las pestañas permite reconocer en representaciones numéricas y gráficas las contribuciones de las variables del conjunto de datos a la construcción de cada componente. Así, se entiende cuánta variabilidad explica cada variable de la variabilidad total de la componente con que esté involucrada. en particular:

La Matriz de Contribuciones muestra en términos relativos la retención de variabilidad que tiene cada variable en la construcción de cada componente Así, los diagramas de barras visualizados a través de las pestañas desde Contribuciones a D1 hasta Contribuciones a D11, muestran con base en diagramas de barras las respectivas contribuciones que hacen las variables para explicar la varianzar en cada componente; además, cada gráfico incluye una línea que ayuda a identificar la contribución media, esto ayuda a identificar con mayor facilidad a las variables que contribuyen con mayor explicación de variabilidad de los componentes que conforman.

Planteamiento del Problema

Con base en las variables cuantitativas del conjunto de datos descrito en la sección 2 se demanda determinar las contribuciones que hace cada variable a la construcción de cada componente.

Desarrollo del Análisis

(get_pca_var(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F)))$contrib

2.5. Interpretación de componentes

Con base en (Díaz Morales & Morales Rivera, 2012) se sabe que a partir de las coordenadas de los registros dimensionalmente reducidos se puede ubicar en un plano de factores para efectos de análisis e interpretación. Así, las variables reducidas son las componentes principales que se grafican como ejes en un plano, y los valores que tomen son los puntajes de las componentes. Como bien se explica en el mismo trabajo, las distancias entre los puntos definidos por los puntajes de las componentes tiene un significado relevante al ayudar a establecer semejanzas de perfiles en las observaciones hechas. Sin embargo, los valores semejantes de las variables pueden darse solo en algunas de ellas, sin esperar necesariamente a que suceda en todas. Así, se espera que las distancias en el espacio dimensional original de las observaciones queden bien representadas en el espacio reducido de las componentes.

Planteamiento del Problema

Con base en las variables cuantitativas del conjunto de datos descrito en la sección 2 se demanda definir e interpretar sus componentes principales.

Desarrollo del Análisis

La navegación a través de las pestañas permite reconocer en representaciones numéricas y gráficas las contribuciones de las variables del conjunto de datos a la construcción de cada componente. Así, se entiende cuánta variabilidad se explica cada variable de la variabilidad total de la componente con la que está involucrada. en particular:

La Matriz de Contribuciones muestra en términos relativos la retención de variabilidad que tiene cada variable en la construcción de cada componente. Así, los diagramas de barras visualizados a través de las pestañas desde Contribuciones a D1 hasta Contribuciones a D6 , muestran con base en diagramas de barras las respectivas contribuciones que hacen las variables para explicar la varianza en cada componente; Además, cada gráfico incluye una línea que ayuda a identificar la contribución media, esto ayuda a identificar con mayor facilidad a las variables que contribuyen con mayor explicación de variabilidad de los componentes que conforman.

Matriz de contribuciones

(get_pca_var(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F)))$contrib
##                           Dim.1      Dim.2       Dim.3       Dim.4        Dim.5
## edades              0.882809081 52.4605700 35.26719476  9.26861601 2.120810e+00
## numero_de_hijos     0.001308726 19.3162714 59.12128456 21.52860297 3.253237e-02
## peso (kg)          48.782617698  1.0652768  1.43694662  0.46834578 4.824681e+01
## altura (cm)        50.166332593  0.1438166  0.05662212  0.03364993 4.959958e+01
## ingresos mensuales  0.166931902 27.0140652  4.11795194 68.70078530 2.656547e-04

Contribuciones a D1

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 1, top = 10)

Contribuciones a D2

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 2, top = 10)

##Contribuciones a D3

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 3, top = 10)

##Contribuciones a D4

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 4, top = 10)

##Contribuciones a D5

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 10)

##Contribuciones a D6

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 5, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 5)

contribuciones D7

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 10)

contribuciones D8

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 5, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 15)

contribuciones D9

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 5, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 15)

contribuciones D10

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 5, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 15)

contribuciones D11

fviz_contrib(PCA(clinic_dataset[,-c(1,4,5,6,7,8)], ncp = 5, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 15)

2.4 Interpretacion de componentes

Con base en ( Díaz Morales & Morales Rivera, 2012 ) se sabe que a partir de las coordenadas de los registros dimensionalmente reducidos se puede ubicar en un plano de factores para efectos de análisis e interpretación. Así, las variables reducidas son los componentes principales que se grafican como ejes en un plano, y los valores que tomen son los puntajes de los componentes. Como bien se explica en el mismo trabajo, las distancias entre los puntos definidos por los puntajes de los componentes tiene un significado relevante al ayudar a establecer semejanzas de perfiles en las observaciones hechas. Sin embargo, los valores semejantes de las variables pueden darse solo en algunas de ellas, sin esperar necesariamente a que suceda en todas. Así, se espera que las distancias en el espacio dimensional original de las observaciones queden bien representadas en el espacio reducido de los componentes.

Planteamiento del Problema

Con base en las variables cuantitativas del conjunto de datos descritos en la sección 2 se exige definir e interpretar sus componentes principales.

Desarrollo del análisis

La navegación a través de las pestañas permite visualizar objetos gráficos y matriciales que, al incluir lo hecho en las secciones anteriores, podrian ayudar a robustecer la interpretación de las componentes calculadas, aunque los datos nuevamenten toman formas difíciles de relacionar, los datos se muestran dispersos, sin una tenedencia clara dentro de ellos.

cabe resaltar que se tuvo la necesidad de trabajar con subconjuntos de 10 a 300 registros para que el programa pudiese correr las graficas, ya que la variables cualitativas como lo son genero_del_paciente, asistencia_privada_publica y residencia_cerca_al_centro, numero_de_hijos,uso_sustancia_psicoativa, contienen registros que podrian aparecer una sola vez, lo que haria imposible graficar los bitplos.

Biplot de variables y registros [total E -> estrato_socieconomico]

data_E <- clinic_dataset[,-c(1,4,5,6,7)]
data_All <- cbind(clinic_dataset[,-c(1,4,5,6,7,8)], data_E$estrato_socioeconomico)
fviz_pca_biplot(PCA(data_All, ncp = 5, scale.unit = TRUE, graph = F, quali.sup = 6), axes = c(1, 2), repel = TRUE, habillage = 6)

Biplot de variables y registros [total A -> asistencia_privada_publica ]

data_A <- clinic_dataset[,-c(1,5,6,7)] data_All <- cbind(clinic_dataset[,-c(1,4,5,6,7)], data_A$asistencia_privada_publica) fviz_pca_biplot(PCA(data_All, ncp = 4, scale.unit = TRUE, graph = F, quali.sup = 5), axes = c(1, 2), repel = TRUE, habillage = 5)

Biplot de variables y registros [Total R->Residencia_cerca_al_centro]

set.seed(780728) data_20_ci <- clinic_dataset_sin_NA[sample(1:nrow(clinic_dataset_sin_NA),20),-c(2,3,15)] set.seed(780728) data_20 <- cbind(clinic_dataset_sin_NA[sample(1:nrow(clinic_dataset_sin_NA),20),-c(1,2,3,15)], data_R$Residencia_cerca_al_centro) fviz_pca_biplot(PCA(data_20, ncp = 11, scale.unit = T, graph = F, quali.sup = 12), axes = c(1, 2), repel = T, habillage = 11)

Coordenadas individuales [Suconjunto E]

set.seed(780728) data_61_UR <- clinic_dataset_Initial[sample(1:nrow(clinic_dataset_Initial),61),-c(1,4,5,6)] set.seed(780728) data_61 <- cbind(clinic_dataset_Initial[sample(1:nrow(clinic_dataset_Initial),61),-c(1,4,5,6,7)], data_61_UR\(Eestrato_socieconomico) head(PCA(data_61, ncp = 5, scale.unit = TRUE, graph = FALSE, quali.sup = 7)\)ind$coord, n = 61L)

Objetivos y anotaciones ::Fase 3

3.1. Objetivos

En términos generales, esta tercera etapa de estudio mostrará cálculos, visualizaciones e interpretaciones con base en el conjunto de datos tratado en la fase 1 y 2, pero ahora desde un enfoque de análisis de correspondencias simples y múltiples sobre las variables cuanlitativas, que incluirá: construcción de tablas de contingencias y disyuntivas completas, calidades de representación, contribuciones e interpretaciones.

Recuérdese que el conjunto de datos de trabajo es descrito en la sección 2 y los referentes teóricos en la sección 1.

Por último, este trabajo fue procesado con R version 4.2.2 (2022-10-31 ucrt) mediado por RStudio 2022.12.0 Build 353 en una plataforma x86_64-w64-mingw32. Además, por su naturaleza de publicación en línea y para cumplir con el requisito temporal de entrega, será actualizado, como máximo, hasta las 11:59 p.m. del domingo 5 de marzo de 2023.

3.2. Correspondencias Simples

Con base en el trabajo de ( Aldás & Uriel, 2017 ) se sabe que el análisis de correspondencias simples (ACS) busca representar en un espacio multidimensional reducido la relación que existe entre las categorías de un par de variables categóricas. En este sentido, el ACS muestra las distancia entre los niveles de dos variables categóricas y, en consecuencia, ayuda a visualizar tablas de contingencia. Además, se establece que el número máximo de dimensiones que explican la asociación entre variables fila y columna es igual a uno menos el menor número de categorías de alguna de las variables involucradas. En consecuencia, el análisis de correspondencias permite describir la proximidad existente entre los perfiles de los objetos observados. Además, el ACS, que basa sus cálculos en tablas de contingencia, puede extenderse a más de dos variables categóricas, conociéndose como análisis de correspondencias Múltiples (ACM), con base en un objeto llamado tabla disyuntiva completa.

3.3. Planteamiento del Problema

Con base en las variables cualitativas del conjunto de datos descrito en la sección 2 se demanda desarrollar el análisis de correspondencias, en principio simple, apoyado en tablas de contingencia y de frecuencias relativas y gráficos de perfiles y de puntos superpuestos en el primer plano factorial.

3.4 Desarrollo del Análisis

La navegación a través de las pestañas permite visualizar objetos matriciales y gráficos que ayudan a robustecer la interpretación del análisis de correspondencias simples (binario) entre cada par de variables categóricas del conjunto de datos: genero_del_paciente, asistencia_privada_publica y uso_sustancias_psicoativas. Por ser baja la cantidad de variables categóricas, se trabaja el ACS sobre las tres combinaciones posibles.

La pestaña AC Parejas Totales agrupa los cálculos para todas las combinaciones de parejas de variables. En particular, en Contingencias se hacen las siguientes lecturas de ejemplo de las tablas de contingencias: en la tabla de contingencias genero_del_paciente vs. uso_sustancias_psicoativas se encontró que 80 pacientes de un total de 151 de sexo femenino reportaron el uso de sustancias psicoactivas. Además, de los 181 pacientes que no reportaron uso de sustancias psicoactivas, de un total de 400, 71 son de sexo femenino y 110 de sexo masculino. En la tabla de contingencias genero_del_paciente vs. asistencia_privada_publica, se calculó que 14 pacientes de un total de 249 de sexo masculino asistieron a servicios privados; además, de los 60 pacientes que asistieron a servicios públicos, 23 eran de sexo femenino y 37 de sexo masculino. Por último, en la tabla de contingencia uso_sustancias_psicoativas vs. asistencia_privada_publica se puede determinar que 59 pacientes, de un total de 219, que reportaron el uso de sustancias psicoactivas, asistieron a servicios públicos; además, 75 pacientes, de un total de 107, que asistieron a servicios privados, no reportaron el uso de sustancias psicoactivas.

Al tomar como base las tablas de contingencia descritas antes, se presenta a través de la subpestaña Probabilidades las proporciones relativas en términos de los pares de variables examinadas. En este sentido, a nivel de ejemplo se presentan algunas lecturas de ellas: en la tabla de probabilidades genero_del_paciente vs. uso_sustancias_psicoativas, el 20.00% del total de pacientes son de sexo femenino que reportaron el uso de sustancias psicoactivas; además, el 45.25% del total de pacientes no reportaron el uso de sustancias psicoactivas, donde el 17.75% eran hombres y el 27.50% mujeres. En la tabla de probabilidades genero_del_paciente vs. asistencia_privada_publica, el 3.50% del total de pacientes fueron hombres que asistieron a servicios privados; además, del 15.00% de pacientes que asistieron a servicios públicos, el 9.25% eran hombres y el 5.75% mujeres. Por último, en la tabla de probabilidades uso_sustancias_psicoativas vs. asistencia_privada_publica, el 14.75% del total de pacientes reportó el uso de sustancias psicoactivas y asistieron a servicios públicos; además, el 18.75% del total de pacientes asistieron a servicios privados sin reportar el uso de sustancias psicoactivas.

Como ocurre con las tablas de probabilidades o proporciones, en la subpestaña Frecuencias [CPF y CPC], las frecuencias condicionadas por filas y condicionadas por columnas (respectivamente) se calcularon con base en las tablas de contingencia respectivas. Así, se pueden presentar las lecturas de ejemplo: según la matriz de frecuencias CPF de genero_del_paciente vs. uso_sustancias_psicoativas, de los pacientes de sexo femenino, el 52.98% reportó el uso de sustancias psicoactivas, mientras que entre los pacientes de sexo masculino lo hizo el 55.82%. Además, según la misma matriz pero condicionada por columnas, el 39.23% de los pacientes que no reportaron el uso de sustancias psicoactivas fueron de sexo femenino, mientras que el 60.77% fueron de sexo masculino. Ahora, según la matriz de frecuencias CPF de genero_del_paciente vs. asistencia_privada_publica, el 5.62% de los pacientes de sexo masculino asistió a servicios privados, mientras que el 7.95% de las mujeres hizo lo mismo; además, según la misma matriz pero condicionada por columnas, del total de pacientes que asistió a servicios privados, el 46.15% fueron mujeres y el 53.85% hombres. Por último, según la matriz de frecuencias CPF de uso_sustancias_psicoativas vs. asistencia_privada_publica, solo el 4.42% de los pacientes que no reportaron el uso de sustancias psicoactivas asistieron a servicios públicos, mientras que el 23.74% de los pacientes que reportaron el uso de sustancias psicoactivas asistieron a servicios privados. Complementariamente, según la misma matriz pero condicionada por columnas, el 13.33% del total de pacientes que asistieron a servicios públicos no reportaron el uso de sustancias psicoactivas, mientras que el 86.67% sí lo hizo.

Con base en las matrices de frecuencias se entienden los perfiles condicionados por filas y columnas que se exhiben en la subpestaña Perfiles [CPF y CPC]. Los gráficos de perfiles se muestran en el mismo orden de los objetos anteriormente descritos. Sin embargo, en los gráficos de perfiles se pueden cotejar las proporciones contra un individuo promedio o un perfil promedio, etiquetado con marg. En este sentido, los perfiles fila y columna que corresponden con las variables genero_del_paciente y uso_sustancias_psicoativas muestran distribuciones marginales cercanas entre sí; es decir, si son calculadas las proporciones totales serán aproximadamente iguales, por ejemplo: (perfiles fila) las proporciones de pacientes de sexo masculino y femenino que no reportaron el uso de sustancias psicoactivas fueron, respectivamente, 44.18% y 47.02%; también, (perfiles columna) la proporción de pacientes de sexo femenino que reportaron o no el uso de sustancias psicoactivas fueron, respectivamente, 36.53% y 39.23%. Asimismo, los perfiles fila y columna que corresponden con las variables genero_del_paciente y asistencia_privada_publica muestran distribuciones marginales cercanas entre sí, por ejemplo: (perfiles fila) las proporciones de pacientes de sexo masculino y femenino que asistieron a servicios públicos fueron, respectivamente, 32.13% y 35.10%; también, (perfiles columna) la proporción de pacientes de sexo femenino que asistieron a servicios públicos, privados y mixtos fueron, respectivamente, 38.33%, 39.85% y 38.32%. Por último, los perfiles fila y columna que corresponden con las variables uso_sustancias_psicoativas y asistencia_privada_publica muestran distribuciones marginales lejanas entre sí, por ejemplo: (perfiles fila) las proporciones de pacientes que no reportaron el uso de sustancias psicoactivas y que asistieron a servicios públicos fueron: 4.42% y 23.74%; también, (perfiles columna) la proporción de pacientes que reportaron el uso de sustancias psicoactivas para asistir a servicios públicos, privados y mixtos fueron, respectivamente, 86.67%, 53.38% y 29.91%.

Con base en las descripciones hechas es posible anticipar que los pares de variables categóricas genero_del_paciente vs. uso_sustancias_psicoativas y genero_del_paciente vs. asistencia_privada_publica sean independientes. Este juicio se apoya en los resultados de las pruebas de hipótesis visualizadas a través de la sub-pestaña homónima. Para estas pruebas, a un nivel de significancia α = 0.05, las hipótesis formuladas fueron: - h0: Las variables categóricas son independientes - h1: Las variables categóricas son dependientes

Asimismo, el par de variables que tuvieron las pruebas a favor de la dependencia fueron uso_sustancias_psicoativas y asistencia_privada_publica, en esta prueba el p-valor resultó menor o igual que el nivel de significancia y, comparativamente, el valor del estadístico χ2 fue grande. Por lo tanto, el par de variables que continuaron en análisis fueron estas últimas.

A través de la pestaña AC Pareja Única se despliegan las sub-pestañas relacionadas con la continuación del análisis de correspondencias entre ellas. En Contingencias y Residuales [R-UR] (R: uso_sustancias_psicoativas y UR: asistencia_privada_publica) se pueden visualizar las tablas de contingencias, valores esperados y residuales de la pareja de variables en curso. Respecto de las dos primeras, es visualizable que el recuento observado y el recuento esperado bajo la hipótesis nula respecto de cada variable son lejanos entre sí, en este sentido, la dependencia entre las variables se robustece. “Rango_observado” son los recuentos asociados con cada categoría de datos y “rango_esperado” son los recuentos

esperados para cada categoría bajo la hipótesis nula. Además, el análisis de residuos de Pearson y estandarizados muestra que las mayores desviaciones respecto a los valores esperados ocurren entre las categorías de servicios públicos, privados y mixtos. Asimismo, en la sub-pestaña Contribuciones [R-UR] puede apreciarse, comentado lo anterior, que el valor mixto de la variable asistencia_privada_publica contribuye poco en la explicación de la variabilidad del conjunto en comparación con los demás.

Por último, el resultado definitivo del análisis de correspondencias simples se muestra a través de la sub-pestaña Correspondencia Simple Unidimensional [R-UR]. En este apartado se establece que solo una dimensión absorbe toda la variabilidad de la pareja, por lo que la representación bidimensional en el plano de factores es irrealizable. Sin embargo, es posible hacer una interpretación unidimensional de los resultados. Al ser requeridos las variables de soporte del AC, primero por columnas y luego por filas, las coordenadas proyectadas de la variable asistencia_privada_publica en relación con las categorías de servicios públicos y privados se presentan del lado positivo del eje dimensional creando oposiciones binarias con, respectivamente, servicios públicos con mixtos y servicios privados con mixtos, mientras que los servicios mixtos se encuentran técnicamente en el centro del eje. Así mismo, los tipos de servicios públicos, privados y mixtos son los que más contribuyen en la configuración de la dimensión, de nuevo quedan rezagadas las categorías mixtas. Además, es determinante que la calidad de representación alcance el máximo con cada una de las variables. Un comportamiento semejante a lo expuesto puede apreciarse con la variable fila uso_sustancias_psicoativas, su calidad de representación es máxima, las coordenadas de sus categorías se yuxtaponen en el eje unidimensional y sus contribuciones son aproximadamente equilibradas. De lo mencionado se interpreta que presentan asociación relevante, positiva o negativa, entre filas y columnas, las categorías (de las respectivas variables) servicios públicos y privados con uso de sustancias psicoactivas, y mixtos con no-uso de sustancias psicoactivas.

Dado que la representación gráfica bidimensional fue irrealizable, se presenta en la sección 12 el análisis de correspondencias múltiples para lograrla.

AC Parejas Totales

addmargins(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)uso_sustancias_psicoativas))

Contingencias

addmargins(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)asistencia_privada_publica))

addmargins(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)estrato_socioeconomico))

addmargins(table(clinic_dataset\(uso_sustancias_psicoativas, registros_clinicos\)estrato_socioeconomico))

Probabilidades

addmargins(prop.table(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)uso_sustancias_psicoativas)) * 100)

addmargins(prop.table(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)estrato_socioeconomico)) * 100)

addmargins(prop.table(table(clinic_dataset\(uso_sustancias_psicoativas, Registros_Clinicos\)residencia_cerca_al_centro)) * 100

Frecuencias [CPF y CPC]

round(addmargins(prop.table(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)asistencia_privada_publica), 1)*100, 2), 2)

round(addmargins(prop.table(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)asistencia_privada_publica), 2)*100, 1), 2)

round(addmargins(prop.table(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)estrato_socioeconomico), 1)*100, 2), 2)

round(addmargins(prop.table(table(clinic_dataset\(genero_del_paciente, registros_clinicos\)estrato_socioeconomico), 2)*100, 1), 2)

round(addmargins(prop.table(table(clinic_dataset\(asistencia_privada_publica, registros_clinicos\)estrato_socioeconomico), 1)*100, 2), 2)

round(addmargins(prop.table(table(clinic_dataset\(asistencia_privada_publica, registros_clinicos\)estrato_socioeconomico), 2)*100, 1), 2)

perfiles [CPF y CPC]

plotct(table(clinic_dataset\(genero_del_paciente, Registros_Clinicos\)uso_sustancias_psicoativas),“row”)

plotct(table(clinic_dataset\(genero_del_paciente, Registros_Clinicos\)uso_sustancias_psicoativas),“col”)

plotct(table(clinic_dataset\(genero_del_paciente, Registros_Clinicos\)estrato_socioeconomico),“row”)

plotct(table(clinic_dataset\(genero_del_paciente, Registros_Clinicos\)estrato_socioeconomico),“col”)

plotct(table(clinic_dataset\(uso_sustancias_psicoactivas, Registros_Clinicos\)residencia_cerca_al_centro),“row”)

plotct(table(clinic_dataset\(uso_sustancias_psicoactivas, Registros_Clinicos\)residencia_cerca_al_centro),“col”)

prueba de hipotesis

chisq.test(table(clinic_dataset\(genero_del_paciente, Registros_Clinicos\)uso_sustancias_psicoactivas))

chisq.test(table(clinic_dataset\(genero_del_paciente, Registros_Clinicos\)estrato_socioeconomico))

chisq.test(table(clinic_dataset\(uso_sustancias_psicoactivas, Registros_Clinicos\)residencia_cerca_al_centro))

correspondencias multiples

Recuperando de nuevo el trabajo de ( Díaz Morales & Morales Rivera, 2012 ) se dice que el ACS se puede extender desde tablas de contingencia hacia tablas disyuntivas completas. En estas las filas son los objetos a los cuales se les registran características de interés a través de las columnas que compilan las modalidades de las variables categóricas estudiadas de ellos. Así, el análisis de correspondencias múltiples (ACM) es el AC aplicado a una tabla disyuntiva completa. Por lo tanto, en el ACM una variable categórica asigna a cada objeto de una población una modalidad a través de la cual los particiona exclusiva y exhaustivamente.

Esta sección es desarrollada como alternativa de completitud del análisis de correspondencias simples que en la sección 11 fue inapreciable debido a la unidimensionalidad de la representación de los datos a nivel de proyección de las variables categóricas que cumplieron la hipótesis de dependencia. Por lo tanto, del tratamiento conjunto de todas las variables categóricas se espera obtener una representación en el primer plano factorial.

Planteamiento del Problema

Con base en las variables cualitativas del conjunto de datos descritos en la sección 2 se exige desarrollar el análisis de correspondencias Múltiples para lograr una representación gráfica en el primer plano factorial, debido a la imposibilidad de lograrlo en el análisis de correspondencias simple.

Desarrollo del Análisis

La navegación a través de las pestañas permite visualizar objetos matriciales y gráficos que ayudan a desarrollar e interpretar el análisis de correspondencias múltiples (ACM) entre las variables categóricas del conjunto de datos descritos.

La pestaña ACM muestra la multidimensionalidad esperada, comparada con la unidimensionalidad del ACS de la sección 11, al trabajar conjuntamente con las tres variables categóricas del conjunto de datos: genero_del_paciente, residencia_cerca_al_centro y estrato_socioeconómico. Muestra además que las dimensiones del plano principal explican el 42.16% del conjunto (será sobre este plano que se continuará con las interpretaciones del ACM). Además, la evidente baja concentración de absorción de variación por parte de alguna o algunas dimensiones se reflejará en las distancias entre los perfiles de las variables categóricas.

En la pestaña Biplot ACM se muestran las semejanzas de perfiles entre pacientes representadas por puntos azules sobrepuestos que indican coordenadas de convergencia y las asociaciones entre algunas categorías de las variables y conjuntos de pacientes. Cabe anotar que las semejanzas entre categorías de las variables están presentadas por sus coordenadas respecto de los semiejes dimensionales, más que por sus proximidades, esto concuerda con los resultados obtenidos en la sección 11. Por ejemplo, en semejanza a nivel de categorías de las variables destacan los grupos: uso_sustancias_psicoactivas, asistencia_privada_publica, y residencia_cerca_al_centro por un lado, por otro, genero_del_paciente y estrato_socioeconómico, así como ciertos grupos evidentes de pacientes. Complementariamente, a nivel de asociación se destaca la del grupo de pacientes cercano a uso_sustancias_psicoactivas y la de otro grupo nutrido cercano a estrato_socioeconómico. En general se pueden visualizar fácilmente las asociaciones entre las categorías de las variables y los grupos de pacientes afines con ellas.

Seguidamente, la pestaña Calidad de Representación muestra que las categorías de la variable residencia_cerca_al_centro fueron las mejor representadas, en oposición a las categorías edades y numero_de_hijos. El resto quedó en un rango intermedio-alto de calidad de representación. Como la calidad de representación en subespacios de dimensión reducida se mide en porcentajes de inercia con respecto a la total la cercanía de un punto al origen del plano factorial indica una baja calidad de representación en él, por lo tanto, la categoría numero_de_hijos la presenta.

ACM

round(MCA(clinic_dataset[1:400, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE)$eig,2)

ACM biplot

fviz_mca_biplot(MCA(clinic_dataset[1:400, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), repel = TRUE)

calidad de representacion

fviz_mca_var(MCA(clinic_dataset[1:400, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), col.var =“cos2”, gradient.cols = c(“#00AFBB”, “#E7B800”, “#FC4E07”), repel = TRUE)

fviz_mca_var(MCA(clinic_Dataset_Initial[1:400, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE)\(var\)cos2

Contribuciones

fviz_contrib(MCA(clinic_dataset[1:400, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), choice = “var”, axes = 1,

fviz_contrib(MCA(clinic_dataset[1:400, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), choice = “var”, axes = 2, top = 15)

fviz_contrib(MCA(clinic_dataset[, -c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), choice = “var”, axes = 3, top = 15)

fviz_contrib(MCA(clinic_dataset[, c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), choice = “var”, axes = 4, top = 15)

fviz_contrib(MCA(clinic_dataset[, c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE), choice = “var”, axes = 5, top = 15)

Biplot con contribuciones

fviz_mca_varMCA(clinic_dataset[, c(1, 3, 4, 5, 6, 7, 10)], graph = FALSE)col.var = “contrib”, gradient.cols = c(“#00AFBB”, “#E7B800”, “#FC4E07”), repel = TRUE)

Objetivos y anotaciones ::Fase 4

4.1. Objetivos

En términos generales, la cuarta etapa de estudio mostrará cálculos, visualizaciones e interpretaciones con base en el conjunto de datos tratados en las fases 1 , 2 y 3 , pero ahora desde un enfoque de análisis de conglomerados en versión jerárquica (dendogramas) y no-. jerárquica ( K -medias).

Recuérdese que el conjunto de datos de trabajo está descrito en la sección 2 y los referentes teóricos en la sección 1 .

Por último, este trabajo fue procesado con R versión 4.2.2 (2022-10-31 ucrt) mediado por RStudio 2022.12.0 Build 353 en una plataforma x86_64-w64-mingw32. Además, por su naturaleza de publicación en línea y para cumplir con el requisito temporal de entrega, se actualizará, como máximo, hasta las 11:59 pm del domingo 12 de marzo de 2023.

Agrupacion jerarquica

Según ( Díaz Morales & Morales Rivera, 2012 ) , quienes citan el trabajo de Everitt de 1980 titulado Cluster Analysis, los conglomerados pueden concebirse como regiones continuas de un espacio que contienen una relativamente alta densidad de puntos, que a su vez están separadas por regiones. (¿continuas?) que contienen una densidad de puntos relativamente baja. Para conformar tales regiones de puntos se han propuesto, por ejemplo, métodos jerárquicos. Estos inician con el cálculo de la matriz de distancias entre los objetos tratados, con los cuales se conforman grupos por aglomeración a través de etapas que empiezan por conglomerados unitarios (el caso trivial inicial, como también el caso trivial final: un conglomerado total). Entre las opciones restantes se presentan fusiones y divisiones de grupos que especifican jerarquías por similitudes que permiten una representación gráfica conocida como dendograma.

Planteamiento del problema

Con base en las variables cuantitativas del conjunto de datos descritos en la sección 2 se exige desarrollar el análisis de conglomerados con base agrupaciones jerárquicas que se representan con dendogramas, esto implica clasificar a los objetos de trabajo con métodos aglomerativos del vecino más cercano, más lejano. y de la unión mediante el promedio, soportados en la distancia euclidiana.

Desarrollo del análisis

La navegación a través de las pestañas permite visualizar objetos matriciales y gráficos que ayudan a desarrollar e interpretar el análisis de conglomerados entre las variables cuantitativas del conjunto de datos descritos en la sección 2.

Con el fin de visualizar adecuadamente los datos, y solo con propósitos académicos, el conjunto de datos descrito en la sección 2 fue modificado de tres maneras. Primero, se le agregó una variable clasificadora categórica: Nacionalidad. Esta variable se obtuvo del Institute of International Education (Instituto de Educación Internacional) para una fecha equivalente a la del conjunto de datos inicial. La modificación consistió en agregar un campo que registre para cada paciente su nacionalidad. Como las proporciones de participación de las nacionalidades de los pacientes fueron diferentes, pero conocidas, el método de asignación fue aleatorio y ponderado con base en ellas. Cabe mencionar que la asignación se hizo directamente en el libro de cálculo. Además, el campo Nationality registra junto con la nacionalidad del paciente la posición que ocupa dicho país como aportante de pacientes extranjeros en el período de medición. Segundo, se estandarizaron en una escala todas las variables cuantitativas. Por último, se aplicó un filtro a los registros con base en la variable clasificadora y se calcularon nuevos registros promedio de las variables cuantitativas. Así, el análisis de conglomerados se hizo con base en el conjunto de datos mostrados en la pestaña “Conjunto Modificado”, lo que indica los primeros registros y la estructura del conjunto.

La pestaña “Disimilaridad” muestra visualmente los registros de proximidad entre las categorías de la variable clasificadora “Nacionalidad”. Con base en una escala de colores que indica las distancias entre las observaciones, puede observarse que ciertos valores están intensamente distantes del resto. Por ejemplo, algunos valores podrían estar más alejados debido a diferencias en variables como edad, género, o ingresos mensuales. Así, se esperaría que los valores mencionados se agruparan entre sí o formaran grupos de jerarquías propias, con distancias de aglomeración grandes en el paso correspondiente.

Complementariamente, la pestaña “Optimización de Mojena” muestra separadamente el número óptimo de conglomerados jerárquicos que deben configurarse de tal forma que las heurísticas usadas entregarán los mejores resultados posibles de intra e inter similaridad. En este sentido, la estrategia del vecino más cercano (Unión Simple) establece que ese número es tres, la del vecino más lejano (unión completa) dicta que también es tres y la de Unión Promedio muestra que es cuatro, a cada una de estas cantidades de conglomerados se le asociará su respectivo dendograma.

Efectivamente, en la pestaña “Dendogramas Optimizados” se avalan gráficamente las menciones hechas en el párrafo sobre Disimilaridad. Además de verificar con más precisión las alturas jerárquicas, en particular para el Enlace Completo y el Enlace Promedio, en estos los niveles de similitud son fácilmente apreciables y efectivamente decisivos sobre la cantidad de conglomerados óptimos precalculados. Es decir, el dendograma de Enlace Simple que se creó con base en tres conglomerados presenta distancias de aglomeración cercanas con la horizontal de corte, y en general entre otros niveles de similitud, esto hace que los conglomerados sean difícilmente discernibles. Caso contrario ocurre con el Enlace Completo y el Enlace Promedio en los cuales las distancias de aglomeración son altas y facilitan la apreciación de los conglomerados. En ambos casos, se entiende que si los dendogramas se cortan más arriba de los niveles respectivos de similitud indicados, entonces resultarían menos conglomerados finales, con niveles de similitud mayor; opuestamente, si fueron cortados más abajo, entonces los niveles de similitud serán menores, pero se obtendrán más conglomerados finales, de ahí el cálculo del número óptimo de conglomerados.

Campo clasificador

as.data.frame(clinic_dataset)[1:24,-c(4,5,6)]

Conjunto modificado

head(as.data.frame(clinic_dataset))

Disimilaridad

data_ = as.data.frame(clinic_dataset)[, -1] rownames(data_) = unclass(clinic_dataset$codigo_de_paciente) fviz_dist(get_dist(data_, stand = TRUE, method = “euclidean”), gradient = list(low = “#00AFBB”, mid = “white”, high = “#FC4E07”))

Optimización de mojena

hc_single = hclust(get_dist(data_, stand = TRUE, 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)

Dendogramas optimizados

suppressWarnings(fviz_dend(hc_single, k = 3, cex = 0.5, k_colors = “npg”, color_labels_by_k = TRUE, rect = TRUE))

Enlaces sencillos

suppressWarnings(fviz_dend(hc_single, k = 3, cex = 0.5, k_colors = “npg”,color_labels_by_k = TRUE, rect = TRUE))

Enlace completo

fviz_dend(hc_complete, k = 3, cex = 0.5, k_colors = “npg”, color_labels_by_k = TRUE, rect = TRUE)

Enlace promedio

fviz_dend(hc_average, k = 4, cex = 0.5, k_colors = “npg”, color_labels_by_k = TRUE, rect = TRUE)

Agrupacion no jerárquica

En el trabajo de ( Díaz Morales & Morales Rivera, 2012 ) se establece que, en términos generales, los métodos de aglomeración no-jerárquicos (o de partición) se implementan con base en la determinación inicial de alguna partición del conjunto de datos, que , evidentemente, genera subconjuntos de datos, es decir, otras particiones a las cuales se les calcula sus respectivos centroides; luego, las observaciones se vinculan con el conglomerado cuyo centroide esté más cercano para calcular de nuevo el centroide de los conglomerados y se hacen comparaciones voraces, para continuar recursivamente hasta que las observaciones sean irremovibles de sus respectivas particiones. Así, contrario a los métodos jerárquicos, la ubicación de una observación en un conglomerado puede variar.

El método no-jerárquico con el que se cerrará el estudio del conjunto de datos con el que se ha trabajado hasta ahora es el de K -medias. Este particiona un conjunto de objetos en grupos, lo hace al elegir los centroides de los grupos que minimizan la distancia (euclidiana) entre cada objeto y ellos, para asignar, en consecuencia, a cada individuo al conglomerado cuyo centroide esté más cercano a él. Por lo tanto, el método tiene como objetivo reubicar a los objetos en grupos tales que presenten la menor variabilidad posible.

Planteamiento del problema

Con base en las variables cuantitativas del conjunto de datos descritos en la sección 2 se demanda desarrollar el análisis de conglomerados con base agrupaciones no-jerárquicas a través del método de las K -medias y la representación gráfica diferenciada de las agrupaciones con base en códigos de colores.

Desarrollo del análisis

La navegación a través de las pestañas permite visualizar objetos matriciales y gráficos que ayudan a desarrollar e interpretar el análisis de conglomerados entre las variables cuantitativas del conjunto de datos descritos en la sección 2.

Como el método de K-medias requiere la especificación del número de conglomerados que se generarán, resulta indispensable determinarlo previamente y que además sea el mejor posible. A través de la pestaña K-óptimos se accede a las sub-pestañas de resultado de los cálculos de K-óptimos con base en los métodos de codo (Elbow), silueta (Silhouette), brecha (Gap) y mayoría (Majority Rule). El primero, ayudó a establecer que el número óptimo de agrupamientos que minimizan la variación total dentro de cada uno de los grupos es 3. El segundo, a través de la calidad de los agrupamientos (una silueta alta), comercializa que el número óptimo de agrupamientos es 2. El tercero, con base en la estimación de los conglomerados óptimos que hacen que se maximice la estadística de brecha de tal manera que la estructura de agrupamiento está muy lejos de una distribución aleatoria uniforme de puntos, determinando que tal número óptimo fuese 1. Por último, el cuarto método, que se basa en el cálculo de 30 índices para determinar el número óptimo de conglomerados al variar todas las medidas de número de conglomerados, de distancia y métodos de conglomerado, exigentes que tal número es 2. Por lo tanto, la continuación del análisis de conglomerados se continuó con la representación gráfica de los agrupamientos basados ​​en dos y tres conglomerados. Así, la pestaña Resultados K-means muestra para números óptimos de 3 y 2 agrupamientos las cantidades de observaciones, las ubicaciones de los centroides de los conglomerados, el vector de agrupamiento y la medida de la bondad de la clasificación (cohesión interna contra separación externa), que, evidentemente es más cercano a uno para el agrupamiento con base en 3 conglomerados.

Por último, la pestaña Gráficos K-means exhibe los conglomerados en términos de 3 y 2 (número óptimo) grupos en el primer plano factorial que explica el de la variabilidad de los datos. Al hacer la reasignación de 3 a 2 centroides se aprecia que el conglomerado que contiene a Colombia solo absorbe a Malasia, es decir solo aumenta una observación, en comparación con el conglomerado que contiene a China que absorbe a todo el conglomerado que contiene a Turquía. Así, puede argumentarse a favor del número óptimo de conglomerados igual a 2, porque la reasignación de centroides se reorientó a mejorar la cohesión interna con baja reducción de separación externa entre dos conglomerados que presentaban más homogeneidad. Sin embargo, las comparaciones entre los métodos tratados, jerárquicos y no-jerárquicos, generan en diferentes cantidades de grupos óptimos, pero ambos métodos coincidieron en que, en general, Indonesia y Nepal son casos por tratar con más detenimiento, por ejemplo, a través de métodos que soporten mejor la afectación que provocan valores extraños, por ejemplo, el método de K-medioides.

K-óptimos (codo)

fviz_nbclust(clinic_dataset, kmeans, method = “wss”) + geom_vline(xintercept = 3, linetype = 2)

K-óptimos (silueta)

fviz_nbclust(clinic_dataset, kmeans, method = “silhouette”)

K-óptimos (estadisticas de brecha)

fviz_nbclust(clinic_dataset, kmeans, method = “gap_stat”)

K-óptimos (Regla de la mayoría)

suppressWarnings(NbClust(data = data_, diss = NULL, distance = “euclidean”, min.nc = 2, max.nc = 10, method = “kmeans”)$Best.nc)

Resultados K-Medias (K-optimo[wws])

set.seed(780728)print(kmeans(data_, 3, nstart = 25))

Resultados K-Medias (K-optimo[sil])

set.seed(780728)print(kmeans(data_, 2, nstart = 25))

Gráficos K-Medias (K-optimo[wws])

fviz_cluster(kmeans_model, data = data_, palette = c(“#2E9FDF”, “#00AFBB”, “#E7B800”), ellipse.type = “euclid”, star.plot = TRUE, repel = TRUE, ggtheme = theme_minimal())

Gráficos K-Medias (K-optimo[sil])

fviz_cluster(kmeans_model, data = data_, palette = c(“#2E9FDF”, “#00AFBB”), ellipse.type = “euclid”, star.plot = TRUE, repel = TRUE, ggtheme = theme_minimal())

CONCLUSIONES

Escribir conclusiones finales.

LS0tDQp0aXRsZTogIkVzdHVkaW8gZGVzY3JpcHRpdm8gbXVsdGl2YXJpYW50ZSBzb2JyZSB1biBjb25qdW50byBkZSBkYXRvcyBjb24gcmVsYWNpb24gYSByZWdpc3Ryb3MgY2xpbmljb3Mgc29icmUgcGFjaWVudGVzIHBlcnRlbmVjaWVudGVzIGEgdW5hIGNsaW5pY2EgZGUgY29sb21iaWEiDQphdXRob3I6ICIgUG9yOiBHNiA6OmFuYS5jYWxsZWphcyA6OmJ1ZW5vLnl1cmkgOjpsdWlzYS5pYmFuZXogOjpAY29ycmVvdW5pdmFsbGUuZWR1LmNvIg0KZGF0ZTogIjIwMjQtMDMtMjAiDQoNCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6IHVuaXRlZA0KLS0tDQo8IS0tIENvbmZpZ3VyYXRpb24gR2xvYmFsIGRlIFIgLS0+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KDQoNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShjb3JycGxvdCkNCmxpYnJhcnkoR0dhbGx5KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShhbmRyZXdzKQ0KbGlicmFyeSh0Y2x0aykNCmxpYnJhcnkoYXBscGFjaykNCmxpYnJhcnkoZ3JhcGhpY3MpDQpsaWJyYXJ5KE1WTikNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KEZhY3RvTWluZVIpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShGYWN0b0NsYXNzKQ0KbGlicmFyeShjbHVzdGVyKQ0KbGlicmFyeShkZW5kZXh0ZW5kKQ0KbGlicmFyeShtYWdyaXR0cikNCg0KDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvPVRSVUUpDQoNCmNsaW5pY19kYXRhc2V0IDwtcmVhZF9leGNlbCgicmVnaXN0cm9zY2xpbmljb3MoVjEpLnhsc3giKQ0KVmlldyhjbGluaWNfZGF0YXNldCkNCg0KDQpgYGANCiANCiMgT2JqZXRpdm9zIHkgQW5vdGFjaW9uZXMgOjpGYXNlIDENCg0KIyMjIDEuMS4gT2JqZXRpdm9zDQoNCkVzdHVkaWFyIGRlc2RlIGVsIHB1bnRvIGRlIHZpc3RhIGRlIGxhIGVzdGFkaXN0aWNhIGRlc2NyaXB0aXZhIG11bHRpdmFyaWFudGUgKGPDoWxjdWxvcygicmVnaXN0cm9zY2xpbmljb3MoVjEpLnhsc3giKSwgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcykgYSB1biBjb25qdW50byBkZSBkYXRvcyBzb2JyZSByZWdpc3Ryb3MgY2xpbmljb3MgZGUgcGFjaWVudGVzIGRlIHVuYSBjbMOtbmljYSBkZSBDb2xvbWJpYS4NCg0KIyMjIDEuMi4gRGVzY3JpcGNpw7NuIGRlIGxvcyBEYXRvcyAgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KRWwgY29uanVudG8gZGUgZGF0b3MgIlJlZ2lzdHJvcyBjbMOtbmljb3MiIHJlY29waWxhIGluZm9ybWFjacOzbiBzb2JyZSBwYWNpZW50ZXMgeSBhc3BlY3RvcyBzb2Npb2Vjb27Ds21pY29zLiBJbmNsdXllIHZhcmlhYmxlcyBjb21vIGVsIG7Dum1lcm8gZGUgaGlqb3MsIGfDqW5lcm8gZGVsIHBhY2llbnRlLCB0aXBvIGRlIGFzaXN0ZW5jaWEgbcOpZGljYSwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzLCBwcm94aW1pZGFkIGEgY2VudHJvcyBtw6lkaWNvcywgZXN0cmF0byBzb2Npb2Vjb27Ds21pY28sIHBlc28sIGFsdHVyYSBlIGluZ3Jlc29zIG1lbnN1YWxlcy4gRXN0b3MgZGF0b3MgcHVlZGVuIHV0aWxpemFyc2UgcGFyYSBhbmFsaXphciBsYSBzYWx1ZCBkZSBsb3MgcGFjaWVudGVzIHkgY8OzbW8gZmFjdG9yZXMgc29jaW9lY29uw7NtaWNvcyBwdWVkZW4gaW5mbHVpciBlbiBzdSBiaWVuZXN0YXIgeSBhY2Nlc28gYSBsYSBhdGVuY2nDs24gbcOpZGljYS4NCg0KKipGdWVudGUgZGVsIGNvbmp1bnRvIGRlIERhdG9zKioNCg0KRWwgY29uanVudG8gZGUgZGF0b3MgZGVsIHRyYWJham8gc2Ugb2J0dXZvIGNhc2kgdG90YWxtZW50ZSBkZSAqKkthZ2dsZSoqIDogaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS8NCg0KRXMgY29udmVuaWVudGUgYW5vdGFyIHF1ZSAqKkthZ2dsZSoqIGVzIHVuYSBjb21wYcOxaWEgc3Vic2lkaWFyaWEgZGUgR29vZ2xlIExMQyBxdWUgbWFudGllbmUgdW5hIGNvbXVuaWRhZCBvbmxpbmUgZGUgY2llbnRpZmljb3MgZGUgZGF0b3MgeSBwcm9mZXNpb25hbGVzIGRlIGFwcmVuZGl6YWplIGF1dG9tw6F0aWNvLiBFc3RhIGVtcHJlc2EgcGVybWl0ZSBzdXMgdXN1YXJpb3MgZW5jb250cmFyIHkgcHVibGljYXIgY29uanVudG8gZGUgZGF0b3MsIGV4cGxvcmFyIHkgY3JlYXIgbW9kZWxvcyBlbiB1biBlbnRvcm5vIGRlIGNpZW5jaWEgZGUgZGF0b3MgYmFzYWRvcyBlbiBsYSB3ZWIsIHRyYWJhamFyIGNvbiBvdHJvcyBjaWVudGlmaWNvcyBkZSBkYXRvcyBlIGluZ2VuaWVyb3MgZGUgYXByZW5kaXphamUgYXV0b21hdGljbyB5IHBhcnRpY2lwYXIgZW4gdW4gY3Vyc28gcGFyYSByZXNvbHZlciBkZXNhZmlvcyBkZSBjaWVuY2lhIGRlIGRhdG9zLg0KDQoqKkNvbnRleHRvIGRlbCBjb25qdW50byBkZSBEYXRvcyoqDQoNClJlY29waWxhIHJlc2dpc3Ryb3Mgc29icmUgbGEgYXRlbmNpw7NuIG1lZGljYSBkZSBwYWNpZW50ZXMgZW4gdW5hIGNsaW5pY2EgZGUgQ29sb21iaWEgZXN0ZSBjb25qdW50byBpbmNsdXllIGRhdG9zIGRlbW9ncmFmaWNvcyBjb21vIGVkYWQsIGVzdHJhdG8gc29jaW9lY29ub21pY28sIHBlc28sIGFsdHVyYSwgaW5ncmVzbyBtZW5zdWwsIGdlbmVybywgbnVtZXJvIGRlIGhpam9zIGUgaW5mb3JtYWNpw7NuIHNvYnJlIHByb2NlZGltaWVudG9zIG3DqWRpY29zIHkgZGUgY29tcG9ydGFtaWVudG8gZGUgcGFjaWVudGVzLiBFc3RlIGNvbmp1bnRvIGRlIGRhdG9zIHNlIGFjdHVhbGl6w7MgcG9yIMO6bHRpbWEgdmV6IGVuIGVsIGHDsW8gMjAyMi4NCg0KKipEZXNjcmlwY2lvbiBkZWwgY29uanVudG8gZGUgRGF0b3MqKg0KDQpFbCBjb25qdW50byBkZSBkYXRvcyBjb250aWVuZSAxMSBjYW1wb3MgeSA0OTk5IHJlZ2lzdHJvcy4gVW5vIGRlIGxvcyBjYW1wb3MgZXMgc2ltcGxlbWVudGUgdW4gaWRlbnRpZmljYWRvciBudW3DqXJpY28gc2VjdWVuY2lhbCBkZSBsb3MgcmVnaXN0cm9zIGRlIGNhZGEgcGFjaWVudGU7b3RybyBjYW1wbyBlcyB1biBpZGVudGlmaWNhZG9yIGRlIGRlY2lzaW9uO290cm9zIHRyZXMgc29uIGRlIG5hdHVyYWxlemEgcG9saXTDs21pY2E7IHkgZWwgcmVzdG8gc29uIG51bcOpcmljb3MgZXN0cmljdGFtZW50ZSBwb3NpdGl2b3MuIExhIGxpc3RhIHNpZ3VpZW50ZSBkZXNjcmliZSBkZSBpenF1aWVyZGEgYSBkZXJlY2hhLCBjb21vIGFwYXJlY2VuIGVuIGVsIHJhbmdvIG8gY29uanVudG8gZGUgZGF0b3MgcXVlIGxvcyBjb250aWVuZSB5IHNlIGVzdGFibGVjZSBwYXJhIGNhZGEgY2FtcG8sIGV4Y2VwdG8gZWwgY2FtcG8gQ29kaWdvIGRlIHBhY2llbnRlLCBlbCB0aXBvIGRlIHZhcmlhYmxlIHkgc3UgZXNjYWxhIGRlIG1lZGljacOzbiAodGlwb19kZV92YXJpYWJsZTo6ZXNjYWxhX2RlX21lZGljacOzbltvcmRlbmFtaWVudG9dKToNCg0KKirigKIJQ8OzZGlnbyBkZSBwYWNpZW50ZSoqIChpZGVudGlmaWNhZG9yKTogcmVnaXN0cmEgdW4gbsO6bWVybyBzZWN1ZW5jaWFkbyBhIHBhcnRpciBkZSAxIHBhcmEgaWRlbnRpZmljYXIgZGUgZm9ybWEgw7puaWNhIGNhZGEgcmVnaXN0cm8gZGUgcGFjaWVudGUgY29uc2lnbmFkbyBlbiBlbCBjb25qdW50byBkZSBkYXRvcy4NCg0KKirigKIJRWRhZGVzKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogY29udGllbmUgbGFzIGVkYWRlcyBkZSBjYWRhIHBhY2llbnRlIGEgcGFydGlyIGRlIDEyIGhhc3RhIDU2IGHDsW9zIGRlIGVkYWQuDQoNCioq4oCiCU7Dum1lcm8gZGUgaGlqb3MqKiAoY3VhbGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGxhIGNhbnRpZGFkIGRlIGhpam9zIHF1ZSB0aWVuZW4gbG9zIHBhY2llbnRlcywgZG9uZGUgZXN0b3MgdmFuIGRlc2RlICoqKjEqKiogeSBlbCAqKiptw6F4aW1vIHJhbmdvKioqIHZhIGhhc3RhICoqKjYgaW50ZWdyYW50ZXMqKiouDQoNCioq4oCiCUdlbmVybyBkZWwgcGFjaWVudGUqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiByZWdpc3RyYSBlbCBzZXhvIGRlbCBwYWNpZW50ZSB5IHNlIGNhdGVnb3JpemEgcG9yICoqKmZlbWVuaW5vKioqIHkgKioqbWFzY3VsaW5vLioqKiANCg0KKirigKIJQXNpc3RlbmNpYSBwcml2YWRhIHB1YmxpY2EqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiByZWdpc3RybyBkYWRvIGEgcGFydGlyIGRlIGxhIGFzaXN0ZW5jaWEgYSBsYSBjbMOtbmljYSBkb25kZSBlbCBwYWNpZW50ZSBpbmZvcm1hIGVsIGRhdG8gc29icmUgc3UgYXRlbmNpw7NuLCBkb25kZSBlc3RhIHNlIGNsYXNpZmljYSBlbiBkb3MgbGFzIGN1YWxlcyBzb24gKioqcHJpdmFkYSoqKiBvICoqKnDDumJsaWNhKioqLiANCg0KKirigKIJVXNvIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzKiogKGN1YW50aXRhdGl2YTo6IGRlY2lzacOzbiAgKSByZWdpc3RyYSBlbCBjb25zdW1hIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzIHBvciBwYXJ0ZSBkZWwgcGFjaWVudGUgeSBzZSBjYXRlZ29yaXphIGNvbiByZXNwdWVzdGEgY2VycmFkYSBkb25kZSBzb2xvIGV4aXN0ZW4gZG9zIG9wY2lvbmVzIDogKioqbm8qKiogeSAqKipzaSoqKi4NCg0KKirigKIJUmVzaWRlbmNpYSBjZXJjYSBhbCBjZW50cm8qKiAoIGN1YW50aXRhdGl2YTo6IGRlY2lzacOzbikgcmVnaXN0cmEgbGEgcmVzaWRlbmNpYSBkZWwgcGFjaWVudGUgc2kgZXMgY2VyY2EgYWwgY2VudHJvIG8gbm8uDQoNCioq4oCiCUVzdHJhdG8gc29jaW9lY29uw7NtaWNvKiogKGN1YW50aXRhdGl2YTo6IHJhesOzbiApIHJlZ2lzdHJhIGxvcyBkYXRvcyBjbGFzaWZpY8OhbmRvbG9zIGRlICoqKjEqKiogYSAqKio2KioqLg0KDQoqKuKAoglQZXNvKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogY29udGllbmUgZWwgcGVzbyBkZSBjYWRhIHBhY2llbnRlIGVuIGtpbG9ncmFtb3MgZG9uZGUgZXN0ZSB2YSBkZSA0MmtnIGEgMTAxa2cuDQoNCioq4oCiCUFsdHVyYSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGxhIGFsdHVyYSBkZSBjYWRhIHBhY2llbnRlIHVzYW5kbyBsYSBlc2NhbGEgZGUgbWVkaWNpw7NuIGVuIGNtIA0KDQoqKuKAoglJbmdyZXNvcyBtZW5zdWFsZXMqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiByZWdpc3RyYSBsb3MgaW5ncmVzb3MgbWVuc3VhbGVzIGRlIGNhZGEgcGFjaWVudGUgZW4gcGVzb3MgY29sb21iaWFub3MuDQoNCg0KIyMjIEVzdHJ1Y3R1cmEgZGVsIGNvbmp1bnRvIGRlIERhdG9zDQpgYGB7ciANCkVzdHJ1Y3R1cmFfQ29uanVudG9fZGVfRGF0b3MsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kc3RyKGNsaW5pY19kYXRhc2V0KQ0KYGBgDQojI2Nvbmp1bnRvIGRlIGRhdG9zIGluaWNpYWwNCmBgYHtyDQpzdHIoY2xpbmljX0RhdGFzZXRfSW5pdGlhbCkNCmBgYA0KIyNFc3RydWN0dXJhIGRlbCBjb25qdW50byBkZSBkYXRvcyByZWVlc2NyaXRvDQpgYGB7cg0Kc3RyKGNsaW5pY19EYXRhc2V0KQ0KYGBgDQojI0Nvbmp1bnRvIGRlIGRhdG9zIHJlZXNjcml0bw0KYGBge3INCmNsaW5pY19EYXRhc2V0DQpgYGANCiMjIyBWaXN1YWxpemFjaW9uIGRlbCBjb25qdW50byBkZSBEYXRvcw0KYGBge3IgVmlzdWFsaXphY2lvbl9Db25qdW50b19EZV9EYXRvcywgZmlnLmFsaWduPSdjZW50ZXInfQ0KY2xpbmljX2RhdGFzZXQNCmBgYA0KDQojIyAxLjMuIEVzdGltYWNpb25lcyBNdWx0aXZhcmlhZGFzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkNvbW8gc2UgbWVuY2lvbmEgZW4gKEFyaXN0aXrDoWJhbCBSLiwgMjAxNykgbGEgZGUgbWVkaWEsIHZhcmlhbnphIHkgY292YXJpYW56YSBjb25mb3JtYW4gdW4gY29uanVudG8gZGUgbWVkaWRhcyBmdW5kYW1lbnRhbGVzIHBhcmEgZGVzY3JpYmlyIGVsIGNvbXBvcnRhbWllbnRvIHBvc2ljaW9uYWwsIGRpc3BlcnNpdm8geSBjb3JyZWxhY2lvbmFsIGRlIHZhcmlhYmxlcyBhbGVhdG9yaWFzLiBFbiBlc3RlIHNlbnRpZG8sIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHRyYWJham8gcXVlIHBvc2VlIGNpbmNvIHZhcmlhYmxlcyBudW3DqXJpY2FzLCB5IHF1ZSBlc3TDoSByZXByZXNlbnRhZG8gbWF0cmljaWFsbWVudGUsIGVzdGltYSBsYXMgbWVkaWRhcyBhbnRlcmlvcmVzIGEgcGFydGlyIGRlIHZlY3RvcmVzIHkgbWF0cmljZXMgZW4gZWwgZXN0dWRpbyBkZXNjcmlwdGl2byBtdWx0aXZhcmlhYmxlLg0KRWwgdmVjdG9yIGRlIG1lZGlhcyBpbmRpY2EgZWwgY29tcG9ydGFtaWVudG8gcG9zaWNpb25hbCBlbiBlbCBzZW50aWRvIGRlIHZhbG9yIGVzcGVyYWRvIG8gcHVudG8gbWVkaW8gcGFyYSBjYWRhIHZhcmlhYmxlIGVuIHJlbGFjacOzbiBjb24gdG9kb3Mgc3VzIHJlZ2lzdHJvcy4gTGEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyBlc3RpbWEgbGFzIGRpc3BlcnNpb25lcywgZW4gc3UgZGlhZ29uYWwgcHJpbmNpcGFsLCBkZSBjYWRhIHZhcmlhYmxlIGRlbCBjb25qdW50byBkZSBkYXRvcyByZXNwZWN0byBkZSBjYWRhIG1lZGlhIG9idGVuaWRhIGRlbCB2ZWN0b3IgZGUgbWVkaWFzLiBBZGVtw6FzLCBwb3IgZW5jaW1hIG8gcG9yIGRlYmFqbyBkZSBsYSBkaWFnb25hbCBwcmluY2lwYWwsIHNlIGVzdGltYW4gbGFzIGNvdmFyaWFuemFzIGVudHJlIGxhcyBjb21iaW5hY2lvbmVzIGRlIGxvcyBwb3NpYmxlcyBwYXJlcyBkZSB2YXJpYWJsZXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zLiBQYXJhIG3DoXMgZGV0YWxsZXMgc2UgcHVlZGUgY29uc3VsdGFyIGEgKEFyaXN0aXrDoWJhbCBSLiwgMjAxNykuDQpMbyBhbnRlcmlvciwgcGFyYSBlbCBjb25qdW50byBkZSBkYXRvcyBkZSB0cmFiYWpvLCBzZSBkZXNhcnJvbGxhIGVuIGxhIHNlY2Npw7NuIDMuMg0KDQoqKlBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hKioNCg0KQ29uIGJhc2UgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMiBzZSBjYWxjdWxhcsOhbiBlIGludGVycHJldGFyw6FuLCBwYXJhIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcywgZWwgdmVjdG9yIGRlIG1lZGlhcywgbGEgbWF0cml6IGRlIHZhcmlhbnphcy1jb3ZhcmlhbnphcyB5IGxhIG1hdHJpeiBkZSBjb3JyZWxhY2lvbmVzLiBTZSByZWN1ZXJkYSBxdWUgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIHNvbjogKiogZXN0cmF0b19zb2Npb2Vjb25vbWljbywgcGVzbyAoa2cpLCBhbHR1cmEgKGNtKSwgaW5ncmVzb3MgbWVuc3VhbGVzLCBudW1lcm9fZGVfaGlqb3MuKioNCg0KKipEZXNhcnJvbGxvIGRlbCBBbsOhbGlzaXMqKg0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIGVsIGPDoWxjdWxvIGRlIGxvcyBzaWd1aWVudGVzIG9iamV0b3M6ICoqVmVjdG9yIGRlIE1lZGlhcyB4LCBNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzIFMgeSBNYXRyaXogZGUgQ29ycmVsYWNpb25lcyBSLioqDQoNCioqVmVjdG9yIGRlIG1hZGlhcyB5IGJveHBsb3RzKioNCg0KUGFyYSByZWFsaXphciB1biBhbsOhbGlzaXMgbWVkaWFudGUgdmVjdG9yZXMgZGUgbWVkaWRhcyB5IGJveHBsb3RzIGNvbiBsb3MgZGF0b3MgcHJvcG9yY2lvbmFkb3MsIHBvZHLDrWFzIGNvbnNpZGVyYXIgbG8gc2lndWllbnRlOg0KDQojIyMgVmVjdG9yIGRlIG1lZGlhcyB5IGRpYWdyYW1hcyBkZSBjYWphIA0KICAgLSBQYXJhIGNhZGEgdmFyaWFibGUgKG7Dum1lcm8gZGUgaGlqb3MsIGfDqW5lcm8gZGVsIHBhY2llbnRlLCB0aXBvIGRlIGFzaXN0ZW5jaWEgbcOpZGljYSwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzLCBwcm94aW1pZGFkIGRlIHJlc2lkZW5jaWEgYWwgY2VudHJvIG3DqWRpY28sIGVzdHJhdG8gc29jaW9lY29uw7NtaWNvLCBwZXNvLCBhbHR1cmEgZSBpbmdyZXNvcyBtZW5zdWFsZXMpLCBjYWxjdWxhciBtZWRpZGFzIGVzdGFkw61zdGljYXMgY29tbyBsYSBtZWRpYSwgbGEgbWVkaWFuYSwgbGEgZGVzdmlhY2nDs24gZXN0w6FuZGFyLCBlbCBtw61uaW1vLCBlbCBtw6F4aW1vIHkgbG9zIGN1YXJ0aWxlcy4NCg0KICAgLSBHcmFmaWNhciBib3hwbG90cyBwYXJhIGNhZGEgdmFyaWFibGUsIGxvIHF1ZSB0ZSBwZXJtaXRpcsOhIHZpc3VhbGl6YXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3MgZGF0b3MsIGlkZW50aWZpY2FyIHZhbG9yZXMgYXTDrXBpY29zIHkgY29tcGFyYXIgbGEgdmFyaWFiaWxpZGFkIGVudHJlIGRpZmVyZW50ZXMgZ3J1cG9zIHNpIGVzIHJlbGV2YW50ZSAocG9yIGVqZW1wbG8sIGNvbXBhcmFyIGxhIGRpc3RyaWJ1Y2nDs24gZGVsIHBlc28gZW50cmUgcGFjaWVudGVzIGRlIGFzaXN0ZW5jaWEgcHJpdmFkYSB5IHDDumJsaWNhKS4NCmBgYHtyfQ0KYXBwbHkoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0sIDIsIG1lYW4pDQpgYGANCg0KYGBge3J9DQpjbGluaWNfZGF0YXNldF9SZWR1Y2lkbyA9IGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldDQpwYXIobWZyb3cgPSBjKDEsIG5jb2woY2xpbmljX2RhdGFzZXRfUmVkdWNpZG8pKSkNCmludmlzaWJsZShsYXBwbHkoMTpuY29sKGNsaW5pY19kYXRhc2V0X1JlZHVjaWRvKSwgZnVuY3Rpb24oaSkgYm94cGxvdChjbGluaWNfZGF0YXNldF9SZWR1Y2lkb1ssIGldKSkpDQpgYGANCg0KIyMjIE1hdHJpeiBkZSB2YXJpYW56YS1jb3ZhcmlhbnphDQoNCg0KYGBge3J9DQpyb3VuZChjb3YoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0pLDIpDQpgYGANCiMjIyBNYXRyaXogZGUgY29ycmVsYWNpb25lcw0KDQpgYGB7cn0NCnJvdW5kKGNvcihjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSksMikNCmBgYA0KDQojIyAxLjQuIEdyw6FmaWNhcyBtdWx0aXZhcmlhZGFzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpFbiBsYSBndcOtYSBkZSBjbGFzZSBkZSAoIEFyaXN0aXrDoWJhbCBSLiwgMjAxNyApIHNlIG1lbmNpb25hIHF1ZSwgZW4gZ2VuZXJhbCwgbG9zIGdyw6FmaWNvcyBtdWx0aXZhcmlhZG9zIGN1bXBsZW4gZG9zIG9iamV0aXZvcyBlc2VuY2lhbGVzOiBwcmltZXJvLCBheXVkYW4gYSBjb21wYXJhciBlbCBjb21wb3J0YW1pZW50byBkZSBwb2JsYWNpb25lcyBkZSBlc3R1ZGlvIGNvbiBiYXNlIGVuIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgeSBzdWF2aXphbiBsYSBjb21wcmVuc2nDs24gZGUgbGEgRXN0cnVjdHVyYSBkZSBldmFsdWFjacOzbiBlbnRyZSB2YXJpYXMgdmFyaWFibGVzLiBFbiBlc3RlIHNlbnRpZG8sIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHRyYWJham8gdGVuZHLDoSBhcG95byBkZXNjcmlwdGl2byBncsOhZmljbyBhIHRyYXbDqXMgZGUgdHJlcyBkaWFncmFtYXM6IHVubyBjb25qdW50byBxdWUgaW50ZWdyYSBkaXNwZXJzacOzbiwgZGlzdHJpYnVjacOzbiB5IGNvcnJlbGFjaW9uZXM7IG90cm8gYmFzYWRvIGVuIGxhIHJlbmRlcml6YWNpw7NuIGRlIHBvbMOtZ29ub3MsIHkgcG9yIMO6bHRpbW8sIHVubyBxdWUgcmVjdXJyZSBhIGxhcyBjYXJhcyBkZSBDaGVybm9mZi4NCg0KKipQbGFudGVhbWllbnRvIGRlbCBwcm9ibGVtYSoqDQoNCkNvbiBiYXNlIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIHNlY2Npw7NuIDIgc2UgY2FsY3VsYXLDoW4gZSBpbnRlcnByZXRhcsOhbiwgcGFyYSBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMsIGxhcyBncsOhZmljYXMgbXVsdGl2YXJpYWRhcyBkZSBkaWFncmFtYSBkZSBjb3JyZWxhY2lvbmVzLCBtYXRyaXogZGUgZGlhZ3JhbWEgZGUgZGlzcGVyc2nDs24sIGRpYWdyYW1hIGRlIGVzdHJlbGxhcyB5IGNhcmFzIGRlIENoZXJub2ZmLiBTZSByZWN1ZXJkYSBxdWUgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIChlbiBlc2NhbGFkYSBkZSBtZWRpY2nDs24gZGUgcmF6w7NuKSBzb246ZWRhZGVzLCBudW1lcm8gZGUgaGlqb3MsZXN0cmF0byBzb2NpZWNvbm9taWNvLCBwZXNvLCBhbHR1cmEsIGluZ3Jlc29zIG1lbnN1YWxlcy4NCg0KKipEZXNhcnJvbGxvIGRlbCBhbsOhbGlzaXMqKiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpTZSBvYnNlcnZhIHF1ZSBsb3MgcHVudG9zIGVuIGVsIGRpYWdyYW1hIGRlIGRpc3BlcnNpw7NuIGVzdMOhbiBtdXkgZGlzcGVyc29zIHkgbm8gc2lndWVuIHVuYSB0ZW5kZW5jaWEgY2xhcmEsIGVzdG8gbm9zIGluZGljYSAgdW5hIGJhamEgY29ycmVsYWNpw7NuOyBsb3MgY2FtYmlvcyBlbiB1bmEgdmFyaWFibGUgbm8gZXN0w6FuIGFzb2NpYWRvcyBjb24gaW5jcmVtZW50b3MgbyBkaXNtaW5pbnVjaW9uZXMgcHJlZGVjaWJsZXMgZW4gbGEgb3RyYSB2YXJpYWJsZS4NCkxhIGZhbHRhIGRlIHVuYSBmdWVydGUgY29ycmVsYWNpw7NuIGVuIHVuIGRpYWdyYW1hIGRlIGRpc3BlcnNpw7NuIHB1ZWRlIGRlYmVyc2UgYSBsYSBuYXR1cmFsZXphIGRlIGxhcyB2YXJpYWJsZXMsIHJlbGFjaW9uZXMgbm8gbGluZWFsZXMsIGZhY3RvcmVzIG9jdWx0b3MgbyBwcm9ibGVtYXMgZW4gbGEgbWVkaWNpw7NuLg0KTG9zIHB1bnRvcyBxdWUgdmFyw61hbiBzaWduaWZpY2F0aXZhbWVudGUgZGUgbGEgY3VydmEgcHJpbmNpcGFsIHB1ZWRlbiBzZXIgdmFsb3JlcyBhdMOtcGljb3MgbyBjYXNvcyBleGNlcGNpb25hbGVzOyBlc3RvcyB2YWxvcmVzIGF0w61waWNvcyBwdWVkZW4gYWZlY3RhciBsYSBjb3JyZWxhY2nDs24gZ2VuZXJhbCB5IGxhIGZvcm1hIGRlIGxhIGN1cnZhLg0KDQpFbiBlbCBzZWd1bmRvIGRpYWdyYW1hIHNlIGRpdmlkacOzIG1lZGlhbnRlIGNvbG9yZXMgbGEgcG90YWJpbGlkYWQgZGVsIGFndWEsIGFsIGhhY2VyIGVzdGEgZGlmZXJlbmNpYWPDs24gc2UgdmUgcXVlIGVzdGUgbm8gZXMgdW4gZmFjb3RyIGRpZmVyZW5jaWFkb3IgZGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBwdWVzIHRvZG8gY29uaW51YSBlc3RhbmRvIG11eSBkaXNwZXJzby4NCg0KRW4gZWwgZGlhZ3JhbWEgZGUgZXN0cmVsbGFzIHNlIHB1ZWRlIG9ic2VydmFyIHF1ZSBsYSBzZW1pbGxhIHRvbWFkYSBwYXJhIGVsIGVqZW1wbG8gZXMgYWx0YW1lbnRlIGlycmVndWxhciwgbmluZ3VuYSB0aWVuZGUgYSBwYXJlY2Vyc2UgZW50cmUgc8OtLCBzZSBwb2Ryw61hIHBlbnNhciBxdWUgdW5vIGRlIGxvcyBmYWN0b3JlcyBxdWUgaW5mbHVlbmNpYSBlc3RlIHRpcG8gZGUgY29tcG9ydGFtaWVudG8gc29uIGxhIGdyYW4gdmFyaWVkYWQgZGUgcHJvcGllZGFkZXMgcXVlIGZ1ZXJvbiBldmFsdWFkYXMgZW4gZGljaGEgbXVlc3RyYSBkZSBhZ3VhLg0KTGEgZXN0cmVsbGEgMTggeSAxOSBhcGFyZW50ZW1lbnRlIHRpZW5lIHZhbG9yZXMgcGFyZWNpZG9zLCB5IHJlbGF0aXZhbWVudGUgYmFqb3MgZW4gY29tcGFyYWNpb24gY29uIGVsIHJlc3RvIGRlIGVzdHJlbGxhcywgcGVybyBhw7puIGFzw60gc2Vyw61hIGVycm9uZW8gZGVjaXIgcXVlIHNvbiBzaW1pbGFyZXMsIGRlYmlkbyBhIHF1ZSBhbGd1biB2YXJpYWJsZXMgc2Ugb2JzZXJ2YW4gZGlmZXJlbnRlcy4NCg0KIyMjIERpYWdyYW1hIGRlIGNvbmp1bnRvcyBkZSBkaXNwZXJzaW9uLCBjb3JyZWxhY2lvbg0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGFpcnMoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyldKQ0KYGBgDQoNCiMjIyBEaWFncmFtYSBkZSBjb25qdW50byBkZSBkaXNwZXJzacOzbiwgZGlzdHJpYnVjaW9uIHkgY29ycmVsYWNpb25lcw0KQXF1w60gbm8gcG9kZW1vcyB2ZXIgbGEgZGlmZXJlbmNpYWNpw7NuIHBvciBob21icmUgeSBtdWplciB5YSBxdWUgbm8gZXMgdW4gZmFjdG9yIGluZmx1eWVudGUgc29icmUgbnVlc3RybyBjb25qdW50byBkZSBkYXRvcy4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3BhaXJzKGNsaW5pY19kYXRhc2V0LCBjb2x1bW5zID0gYygyLDMsOSwxMCwxMSksIGFlcyhjb2xvciA9IGdlbmVyb19kZWxfcGFjaWVudGUsIGFscGhhID0gMC41KSwgdXBwZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCJjb3IiLCBzaXplID0gMi41KSkpDQpgYGANCiMjIyBEaWFncmFtYSBkZSBlc3RyZWxsYQ0KRW4gZXN0YXMgZ3LDoWZpY2FzIHBvZGVtb3MgdmVyIHF1ZSBhbGd1bmFzIGNhcmFzIHNvbiBzaW1pbGFyZXMgY29tbyBwb3IgZWplbXBsbzogTGEgZG9zIHkgbGEgY2F0b3JjZSwgdGVuaWVuZG8gY29tbyBwcm9wb3JjaW9uZXMgY2FzaSBpZ3VhbGVzIGxhcyBzaWd1aWVudGVzIHZhcmlhYmxlczogRXN0cmF0byBzb2NpZWNvbm9taWNvLCBwZXNvLCBhbHR1cmEsIGVkYWRlcyB5IG51bWVybyBkZSBoaWpvcy4NCg0KYGBge3J9DQpzZXQuc2VlZCg3ODA3MjgpDQpjbGluaWNfZGF0YXNldF9SZWR1Y2lkbyA9IGNsaW5pY19kYXRhc2V0W3NhbXBsZSgxOm5yb3coY2xpbmljX2RhdGFzZXQpLDIzKSwtYygxLDQsNSw2LDcpXQ0Kc3RhcnMoY2xpbmljX2RhdGFzZXRfUmVkdWNpZG8sIGxlbiA9IDEsIGNleCA9IDAuNCwga2V5LmxvYyA9IGMoMTAsIDIpLCBkcmF3LnNlZ21lbnRzID0gVFJVRSkNCmBgYA0KIyMjIENhcmFzIGRlIGNoZXJub2ZmDQpgYGB7cn0NCnNldC5zZWVkKDc4MDcyOCkNCmNsaW5pY19kYXRhc2V0X1JlZHVjaWRvID0gY2xpbmljX2RhdGFzZXRbc2FtcGxlKDE6bnJvdyhjbGluaWNfZGF0YXNldCksMjMpLC1jKDEsNCw1LDYsNyw4KV0NCmZhY2VzKGNsaW5pY19kYXRhc2V0X1JlZHVjaWRvKQ0KYGBgDQoNCiMjIDEuNS4gTm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpDb21vIG1lbmNpb25hIChQb3JyYXMgQy4sIDIwMTYpIHBhcmEgaW5kYWdhciBvIGVzdGFibGVjZXIgZWwgdGlwbyBkZSBkaXN0cmlidWNpw7NuIG11bHRpdmFyaWFkYSBkZSB1biBjb25qdW50byBkZSBkYXRvcyBzZSBwdWVkZSByZWN1cnJpciBhIHByb2NlZGltaWVudG9zIGRlc2NyaXB0aXZvcywgY29tbyBsb3MgZ3LDoWZpY29zLCBvIGEgcHJvY2VkaW1pZW50b3MgaW5mZXJlbmNpYWxlcywgY29tbyBsYXMgcHJ1ZWJhcyBlc3RhZMOtc3RpY2FzLiBFbiBlc3RlIHNlbnRpZG8sIHNlIGFsY2FuemEgZ2VuZXJhbGl6YWNpw7NuIGRlIHJlc3VsdGFkb3MgYWwgdXNhciBsYXMgZXN0b3Mgw7psdGltb3MsIHNpIGJpZW4gbG9zIHByaW1lcm9zIGFwb3lhbiBhIGxhcyBpbnRlcnByZXRhY2lvbmVzLg0KDQpFbiBlc3RlIGFwYXJ0YWRvIHNlIGNvbnRlbXBsYSBlbCB1c28gZGUgcHJvY2VkaW1pZW50b3MgaW5mZXJlbmNpYWxlcyBwYXJhIGRldGVybWluYXIgc2kgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbywgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIHNlIGRpc3RyaWJ1eWUgbm9ybWFsIG11bHRpdmFyaWFkbyAoRE5NKS4gTGFzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgKFBOTSkgYSBsYXMgcXVlIHNlcsOhIHNvbWV0aWRvIHNvbjogTWFyZGlhLCBIZW56ZS1aaXJrbGVyLCBEb29ybmlrLUhhbnNlbiB5IFJveXN0b24uIFBhcmEgZXN0YXMgcHJ1ZWJhcyBkZSBub3JtYWxpZGFkIGxvcyB0ZXN0IG9iZWRlY2VuIGEgdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSAqKs6xPTAuMDUqKg0KIHkgYSBsYXMgaGlww7N0ZXNpczoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEgwOiBMYXMgdmFyaWFibGVzIHRpZW5lbiB1bmEgRE5NDQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIMTogTGFzIHZhcmlhYmxlcyBOTyB0aWVuZW4gdW5hIEROTQ0KIA0KIExhIHBydWViYSBkZSBNYXJkaWEgc2UgYmFzYSBlbiBleHRlbnNpb25lcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMsIGVsIGN1YWRyYWRvIGRlIGxhIGRpc3RhbmNpYSBkZSBNYWhhbGFub2JpcywgbGEgY2FudGlkYWQgZGUgdmFyaWFibGVzICoqcCoqIHBvciB0cmF0YXIgeSBsYSBjYW50aWRhZCBkZSByZWdpc3Ryb3MgKipuKiouIEFkZW3DoXMsIGNvbnNpZGVyYSBxdWUgbGEgcHJ1ZWJhIGVzdGFkw61zdGljYSBwYXJhIGxhIGFzaW1ldHLDrWEgdGllbmUgdW5hIGRpc3RyaWJ1Y2nDs24gKirPhzIqKiB5IGxhIHBydWViYSBlc3RhZMOtc3RpY2EgcGFyYSBsYSBjdXJ0b3NpcyBzZSBkaXN0aXJidXllIGFwcm94aW1hZGFtZW50ZSBub3JtYWwuIExvcyBkZXRhbGxlcyBzb2JyZSBsb3MgcGFyw6FtZXRyb3MgZGUgbGFzIGRpc3RyaWJ1Y2lvbmVzIHB1ZWRlbiBjb25zdWx0YXJzZSBlbiBlbCB0cmFiYWpvIGRlIChQb3JyYXMgQy4sIDIwMTYpLg0KTGEgcHJ1ZWJhIGRlIEhlbnplLVppcmtsZXIgc2UgYmFzYSBlbiBsYSBkaXN0YW5jaWEgZnVuY2lvbmFsLCBkYWRvIHF1ZSBzaSBlbCBjb25qdW50byBkZSBkYXRvcyBwcmVzZW50YSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLCBlbCBlc3RhZMOtc3RpY28gZGUgbGEgcHJ1ZWJhIHNlIGRpc3RyaWJ1eWUgYXByb3hpbWFkYW1lbnRlIGNvbW8gdW5hIGxvZ25vcm1hbCwgY3V5b3MgcGFyw6FtZXRyb3MgZGUgbWVkaWEgKirOvCoqDQogeSB2YXJpYW56YSAqKs+DMioqIHB1ZWRlbiBzZXIgY29uc3VsdGFkb3MgZW4gKFBvcnJhcyBDLiwgMjAxNikuDQogDQogTGEgcHJ1ZWJhIGRlIERvb3JuaWstSGFuc2VuIGVzdMOhIGJhc2FkYSBlbiBsYSBhc2ltZXRyw61hIHkgbGEgY3VydG9zaXMgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvcywgcXVlIHNlIHRyYW5zZm9ybWEgcGFyYSBnYXJhbnRpemFyIGxhIGluZGVwZW5kZW5jaWEuIEVzIGNvbnNpZGVyYWRhIG3DoXMgcG90ZW50ZSBxdWUgbGEgcHJ1ZWJhIGRlIFNoYXBpcm8tV2lsayBwYXJhIGNhc29zIG11bHRpdmFyaWFkb3MuIFN1IGVzdGFkw61zdGljbyBkZSBwcnVlYmEgZXN0w6EgZGVmaW5pZG8gY29tbyBsYSBzdW1hIGRlIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIGFsIGN1YWRyYWRvIGRlIGxhIGFzaW1ldHLDrWEgeSBsYSBjdXJ0b3NpcywgeSBzaWd1ZSwgYXByb3hpbWFkYW1lbnRlLCB1bmEgZGlzdHJpYnVjacOzbiAqKs+HMioqLiBMb3MgZGV0YWxsZXMgZGUgbGEgcHJ1ZWJhIHB1ZWRlbiBzZXIgY29uc3VsdGFkb3MgZW4gKERvb3JuaWsgJiBIYW5zZW4sIDIwMDgpLg0KIA0KIExhIHBydWViYSBkZSBSb3lzdG9uIHJlY3VycmUgYSBsYXMgcHJ1ZWJhcyBTaGFwaXJvLVdpbGsgbyBTaGFwaXJvLUZyYW5jaWEgcGFyYSBwcm9iYXIgbGEgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEuIEFzw60sIHNpIGxhIGN1cnRvc2lzIGVzIG1heW9yIHF1ZSAzLCBsYSBwcnVlYmEgZGUgUm95c3RvbiB1c2EgU2hhcGlyby1GcmFuY2lhIHBhcmEgZGlzdHJpYnVjaW9uZXMgbGVwdG9jdXJ0aWNhcy4gTWllbnRyYXMgcXVlIHBhcmEgICAgIGRpc3RyaWJ1Y2lvbmVzIHBsYXRpY3VydGljYXMgdXNhIFNoYXBpcm8tV2lsay4gRW4gZWxsYSBsb3MgcGFyw6FtZXRyb3Mgc29uIG9idGVuaWRvcyBwb3IgYXByb3hpbWFjaW9uZXMgcG9saW5vbWlhbGVzLCBlc3RvIHB1ZWRlIHNlciBjb25zdWx0YWRvIGVuIChQb3JyYXMgQy4sIDIwMTYpDQoNCioqUGxhbnRlYW1pZW50byBkZWwgcHJvYmxlbWEqKiANCg0KQ29uIGJhc2UgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMiBzZSBoYXLDoSB1bmEgcHJ1ZWJhIGVzdGFkw61zdGljYSBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSwgY29uIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgzrE9MC4wNSwgcGFyYSBlc3RhYmxlY2VyIHNpIHN1cyBkYXRvcyBtw6l0cmljb3MgcHJvdmllbmVuIGRlIHVuYSBwb2JsYWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEuIFNlIHJlY3VlcmRhIHF1ZSBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIChlbiBlc2NhbGFkYSBkZSBtZWRpY2nDs24gZGUgcmF6w7NuKSBzb246ICoqZWRhZGVzLCBudW1lcm8gZGUgaGlqb3MsZXN0cmF0byBzb2NpZWNvbm9taWNvLCBwZXNvLCBhbHR1cmEsIGluZ3Jlc29zIG1lbnN1YWxlcy4qKg0KDQoqKkRlc2Fycm9sbG8gZGVsIGFuw6FsaXNpcyoqDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIG11ZXN0cmEgcXVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBlbiByZWxhY2nDs24gY29uIHN1cyB2YXJpYWJsZXMgbnVtw6lyaWNhcyxjb24gdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSDOsT0wLjA1LCBwYXJhIGVzdGFibGVjZXIgc2kgc3VzIGRhdG9zIG3DqXRyaWNvcyBwcm92aWVuZW4gZGUgdW5hIHBvYmxhY2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4gU2UgcmVjdWVyZGEgcXVlIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgKGVuIGVzY2FsYWRhIGRlIG1lZGljacOzbiBkZSByYXrDs24pIHNvbjoqKmVkYWRlcywgbnVtZXJvIGRlIGhpam9zLGVzdHJhdG8gc29jaWVjb25vbWljbywgcGVzbywgYWx0dXJhLCBpbmdyZXNvcyBtZW5zdWFsZXMuKioNCg0KQWwgaW1wbGVtZW50YXIgbGEgcHJ1ZWJhIGRlIG5vcm1hbGlkYWQgS29sbW9nb3JvdiBTbWlybm92LHNlIG9ic2VydsOzIHF1ZSBlbCB2YWxvciBwIGFzb2NpYWRvIGNvbiBsYSBwcnVlYmEgZGUgTGlsbGllZm9ycyAodmFyaWFudGUgZGUgbGEgcHJ1ZWJhIGRlIEtvbG1vZ29yb3YtU21pcm5vdikgZXMgZXh0cmVtYWRhbWVudGUgcGVxdWXDsW8gKHAtdmFsdWUgPCAyLjJlLTE2KSwgbG8gcXVlIGluZGljYSBxdWUgaGF5IGV2aWRlbmNpYSBzaWduaWZpY2F0aXZhIHBhcmEgcmVjaGF6YXIgbGEgaGlww7N0ZXNpcyBudWxhIGRlIG5vcm1hbGlkYWQuIFBvciBsbyB0YW50bywgYmFzw6FuZG9ub3MgZW4gZXN0YSBwcnVlYmEsIHBvZHLDrWFtb3MgY29uY2x1aXIgcXVlIGxhIHZhcmlhYmxlIEFpclF1YWxpdHkgZGUgdHUgY29uanVudG8gZGUgZGF0b3Mgbm8gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLg0KDQpDb24gbGEgYXl1ZGEgZGUgbGEgcHJ1ZWJhIFNoYXBpcm8td2lsayBudWV2YW1lbnRlIG9yZ2FuaWNfY2FyYm9uIHkgdHVyYml0eSBtdWVzdHJhbiB2YWxvcmVzIG1heW9yZXMgYSAwLjA1IG1vc3RyYW5kbyBxdWUgZGljaGFzIHZhcmlhYmxlcyBtdWVzdHJhbiB1biBjb21wb3J0YW1pZW50byBub3JtYWwgeSBwdWVkZSBxdWUgc2UgYWp1c3RlbiBhIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCwgYSBkaWZlcmVuY2lhIGRlbCByZXN0byBkZSB2YXJpYmxlcyBxdWUgZGllcm9uIG1lbm9yZXMgYSBudWVzdHJvIHBhcsOhbWV0cm8gZGUgbWVkaWRhLCBhcG95YW5kbyBsYSBubyBub3JtYWxpZGFkLg0KQ29uIGxhIGF5dWRhIGRlIGxhIHBydWViYSBTaGFwaXJvLXdpbGsgbnVldmFtZW50ZSBvcmdhbmljX2NhcmJvbiB5IHR1cmJpdHkgbXVlc3RyYW4gdmFsb3JlcyBtYXlvcmVzIGEgMC4wNSBtb3N0cmFuZG8gcXVlIGRpY2hhcyB2YXJpYWJsZXMgbXVlc3RyYW4gdW4gY29tcG9ydGFtaWVudG8gbm9ybWFsIHkgcHVlZGUgcXVlIHNlIGFqdXN0ZW4gYSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwsIGEgZGlmZXJlbmNpYSBkZWwgcmVzdG8gZGUgdmFyaWJsZXMgcXVlIGRpZXJvbiBtZW5vcmVzIGEgbnVlc3RybyBwYXLDoW1ldHJvIGRlIG1lZGlkYSwgYXBveWFuZG8gbGEgbm8gbm9ybWFsaWRhZC4NCg0KIyMjIFBydWViYXMgZGUgbm9ybWFsaWRhZA0KQSBjb250aW51YWNpb24gc2UgcHJlc2VudGFuIGxhcyBwcnVlYmFzIGRlIG5vcm1hbGlkYWQgcmVhbGl6YWRhcyBhbCBjb25qdW50byAgZGUgZGF0b3MgY29uIGVsIGZpbiBkZSBpbmRlbnRpZmljYXIgcXVlIHZhcmlhYmxlcyBlc3RhYmFuIGFudGVzIG5vcm1hbGl6YWRhcy4NCmx1ZWdvIGRlIHJldmlzYXIgbG9zIHJlc3VsdGFkb3MgZGUgbm9ybWFsaWRhZCBzZSBwdWRvIG9ic2VydmFyIHF1ZSBoYXkgZG9zIHZhcmlhYmxlcyBxdWUgZGVzdGFjYW4gcG9yIHN1IGJham8gdmFsb3IgZGUgcC12YWx1ZSwgZGFuZG9ub3MgYSBlbnRlbmRlciBxdWUgZGljaGFzIHZhcmlhYmxlcyBwdWVkaWVyb24gaGFiZXIgc2lkbyB0cmF0YWRhcyBhbnRlcmlvcm1lbnRlIHBvciBvdHJhIHBlcnNvbmEsIGN1bHBhYmxlIGRlIHN1IGNvbXBvcnRhbWllbnRvIGNhc2kgaWd1YWwgYWwgZGUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLCBkYXRvIHF1ZSBub3MgcHVlZGUgc2VydmlyIG1hcyBhZGVsYW50ZSBwYXJhIHRvbWFyIGNvbmNsdWNpb25lcyBzb2JyZSBlbCBjb25qdW50byBkZSBkYXRvcy4gU2UgbXVlc3RyYW4gZW4gbGFzIHBydWJhcyBlbiBsb3MgYm90b25vZXMgS29sbW9nb3JvdiwgU2hhcGlybyB5IEFuZGVyc29uLg0KDQojIyMjIFBOTSBNYXJkaWENCkVsIGN1YWRybyBtdWVzdHJhIHF1ZSBsYXMgdmFyaWFibGVzIG5vIHNpZ3VlbiB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwsIHRhbnRvIGRlIGZvcm1hIHVuaXZhcmlhZGEgY29tbyBtdWx0aXZhcmlhZGEuIExhcyBtZWRpZGFzIGRlc2NyaXB0aXZhcyBpbmRpY2FuIGxhIHRlbmRlbmNpYSBjZW50cmFsLCBkaXNwZXJzacOzbiB5IGZvcm1hIGRlIGxhcyBkaXN0cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzLg0KDQpgYGB7cn0NCm12bihjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbXZuVGVzdD0ibWFyZGlhIikNCmBgYA0KDQojIyMgUE5NIEhlbnNlLVppcmtsZXINCkVsIGN1YWRybyBtdWVzdHJhIHF1ZSBsYXMgdmFyaWFibGVzIG5vIHNpZ3VlbiB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwsIHRhbnRvIGRlIG1hbmVyYSBjb25qdW50YSBjb21vIGluZGl2aWR1YWxtZW50ZS4gQWRlbcOhcywgb2ZyZWNlIGVzdGFkw61zdGljYXMgcmVzdW1pZGFzIHNvYnJlIGxhcyB2YXJpYWJsZXMsIGNvbW8gcHJvbWVkaW8sIGRlc3ZpYWNpw7NuIGVzdMOhbmRhciwgbWVkaWFuYSwgbcOtbmltbywgbcOheGltbywgcGVyY2VudGlsZXMsIGFzaW1ldHLDrWEgeSBrdXJ0b3Npcy4NCg0KYGBge3J9DQptdm4oY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0sIG12blRlc3Q9Imh6IikNCmBgYA0KDQojIyMgUE5NIGRlIERvb3JuaWstSGFuc2VuDQpFbCBjdWFkcm8gbm9zIG11ZXN0cmEgcXVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zIG5vIHNpZ3VlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCwgdGFudG8gZW4gdW4gYW7DoWxpc2lzIG11bHRpdmFyaWFkbyBjb21vIHVuaXZhcmlhZG8uIExhcyBtZWRpZGFzIGRlc2NyaXB0aXZhcyBvZnJlY2VuIGluZm9ybWFjacOzbiBkZXRhbGxhZGEgc29icmUgbGFzIHZhcmlhYmxlcywgaW5jbHV5ZW5kbyB0ZW5kZW5jaWEgY2VudHJhbCwgZGlzcGVyc2nDs24sIGZvcm1hIGRlIGxhIGRpc3RyaWJ1Y2nDs24geSBzaW1ldHLDrWEuDQpgYGB7cn0NCm12bihjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbXZuVGVzdD0iZGgiKQ0KYGBgDQojIyMgUE5NIGRlIFJveXN0b24NCkVzdGUgcHVudG8gbm8gbG8gbGxldmFtb3MgYWNhYm8geWEgcXVlIG51ZXN0cm8gY29uanVudG8gZGUgZGF0b3Mgc29icmUtcGFzYSBlbCBsaW1pdGUgZGUgY2FudGlkYWQgZGUgZGF0b3MuDQoNCntyfQ0KbXZuKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBtdm5UZXN0PSJyb3lzdG9uIikNCg0KDQojIE9iamV0aXZvcyB5IGFub3RhY2lvbmVzIDo6IEZhc2UgMiANCg0KIyMjIDIuMSBPYmpldGl2b3MNCkVuIHTDqXJtaW5vcyBnZW5lcmFsZXMsIGVzdGEgc2VndW5kYSBldGFwYSBkZSBlc3R1ZGlvIG1vc3RyYXLDoSBjw6FsY3Vsb3MsIHZpc3VhbGl6YWNpb25lcyBlIGludGVycHJldGFjaW9uZXMgY29uIGJhc2UgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgdHJhdGFkb3MgZW4gbGEgZmFzZSAxICwgcGVybyBhaG9yYSBkZXNkZSB1biBlbmZvcXVlIGRlIGFuw6FsaXNpcyBkZSBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBzb2JyZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMsIHF1ZSBpbmNsdXllbjogc2VsZWNjacOzbiwgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24sIGNvbnRyaWJ1Y2lvbmVzIGUgaW50ZXJwcmV0YWNpw7NuLg0KDQpSZWN1w6lyZGVzZSBxdWUgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbyBkZXNjcml0byBlbiBsYSBzZWNjacOzbiAyIHkgbG9zIHJlZmVyZW50ZXMgdGXDs3JpY29zIGVuIGxhIHNlY2Npw7NuIDEgLg0KDQpQb3Igw7psdGltbywgZXN0ZSB0cmFiYWpvIGZ1ZSBwcm9jZXNhZG8gY29uIFIgdmVyc2nDs24gNC4yLjIgKDIwMjItMTAtMzEgdWNydCkgbWVkaWFkbyBwb3IgUlN0dWRpbyAyMDIyLjEyLjAgQnVpbGQgMzUzIGVuIHVuYSBwbGF0YWZvcm1hIHg4Nl82NC13NjQtbWluZ3czMi4gDQoNCiMjIyAyLjIuIFNlbGVjY2lvbiBkZSBjb21wb25lbnRlcyAvIERlc2NyaXBjaW9uIGRlIGNvbXBvbmVudGVzDQoNCkNvbW8gZXMgbWVuY2lvbmFkbyBlbiBlbCB0cmFiYWpvIGRlIChEw61heiBNb3JhbGVzICYgTW9yYWxlcyBSaXZlcmEsIDIwMTIpIGVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoZW4gYWRlbGFudGUgQUNQKSByZWVzdHJ1Y3R1cmEgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvIGEgdHJhdsOpcyBkZSBsYSByZWR1Y2Npw7NuIGRlIGxhIGNhbnRpZGFkIGRlIHN1cyB2YXJpYWJsZXMsIGVuIGN1eW8gdHJhbnNmb25kbyBlcyBpbm5lY2VzYXJpbyBhc3VtaXIgbmluZ3VuYSBkaXN0cmlidWNpw7NuIGRlIHByb2JhYmlsaWRhZCBkZSBlbGxhcy4gRXN0YSByZWR1Y2Npw7NuIGVzIGxvZ3JhZGEgYSB0cmF2w6lzIGRlIGNvbWJpbmFjaW9uZXMgbGluZWFsZXMgZGUgbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzLCBxdWUgZGViZXLDoW4gY29udGVuZXIgbGEgbWF5b3IgdmFyaWFiaWxpZGFkIHBvc2libGUgcHJlc2VudGUgZW4gZWwgY29uanVudG8gZGUgZGF0b3MuIEVuIGVzdGUgc2VudGlkbywgZWwgQUNQIGxvZ3JhIGNyZWFyIG51ZXZhcyB2YXJpYWJsZXMsIGNvbm9jaWRhcyBjb21vIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLCBxdWUgcG9zZWVuIGNhcmFjdGVyw61zdGljYXMgZXN0YWTDrXN0aWNhcyBkZSBpbmRlcGVuZGVuY2lhIChjb24gYmFzZSBlbiBlbCBzdXB1ZXN0byBkZSBub3JtYWxpZGFkKSB5IG5vIGNvcnJlbGFjacOzbi4NCg0KRWwgQUNQIHNlIGxvZ3JhIGEgbG8gbGFyZ28gZGUgbGFzIHNpZ3VpZW50ZXMgZmFzZXM6IGdlbmVyYWNpw7NuIGRlIG51ZXZhcyB2YXJpYWJsZXMsIHJlZHVjY2nDs24gZGltZW5zaW9uYWwgZGVsIGVzcGFjaW8gZGUgbG9zIGRhdG9zLCBlbGltaW5hY2nDs24gZGUgdmFyYWlibGVzIGRlIHBvY28gYXBvcnRlIGUgaW50ZXJwcmV0YWNpw7NuIGRlIGxvcyBjb21wb25lbnRlcyByZXN1bHRhbnRlcyBlbiBlbCBjb250ZXh0byBkZWwgcHJvYmxlbWEgZGVsIGN1YWwgc2Ugb2J0dXZpZXJvbiBsb3MgZGF0b3MuIEVzdGFzIGZhc2VzIHNlIGRlc2Fycm9sbGFuIGVudHJlIGxhcyBzZWNjaW9uZXMgNywgOCwgOSB5IDEwLg0KDQoqKlBsYW50ZWFtaWVudG8gZGVsIHByb2JsZW1hKioNCg0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBzZWNjacOzbiAyIHNlIGRlbWFuZGEgcHJpbWVybyBlc3RhYmxlY2VyIGVsIHBvcmNlbnRhamUgZGUgdmFyaWFuemEgZXhwbGljYWRvIHBvciBjYWRhIGRpbWVuc2nDs24gdW5hIHZleiBwcm9jZXNhZG8gZWwgQUNQOyB5IHBvc3Rlcmlvcm1lbnRlLCBjb24gYmFzZSBlbiBlbCBhdXRvdmFsb3IgbWVkaW8gbyB1c2FuZG8gdW4gZGlhZ3JhbWEgZGUgc2VkaW1lbnRhY2nDs24sIGRlY2lkaXIgY3XDoW50b3MgY29tcG9uZW50ZXMgcmV0ZW5lci4NCg0KKipEZXNhcnJvbGxvIGRlbCBhbsOhbGlzaXMqKg0KDQpQYXJhIGVsIGRlc2Fycm9sbG8gZGUgYWxndW5vcyBjw7NkaWRvcyBxdWUgcGVybWl0ZW4gZXN0dWRpYXIgZWwgY29uanV0bm8gZGUgZGF0b3MsIHNlIGNhbGN1bMOzIHVuIHN1YmNvbmp1bnRvIGRlIGRhdG9zIGxsYW1hZG8gY2xpbmljX2RhdGFzZXRfc2luX05BIGVuIGVsIGN1YWwgdG9kYXMgbGFzIGZpbGFzIHF1ZSBjYXJlY2lhbiBkZSB2YWxvcmVzIGVuIGFsZ3VuYSBkZSBzdXMgY2VsYWRhcywgaWRlbnRpZmljYWRhcyBwb3IgUiBjb21vIE5BLCBmdWVyb24gaW1wdXRhZG9zLCBoYWNpZW5kbyB1c28gZGUgbGEgZnVuY2nDs24gbmEub21pdCwgcGFyYSB0cmFiYWphciBjb24gdW4gY29uanVudG8gZGUgZGF0b3MgY29tcGxldG8sIHF1ZSBmdW5jaW9uZSBwYXJhIGxvcyBjw7NkaWdvcyBxdWUgbmVjZXNpdGFtb3MgY29ycmVyLg0KDQojI01hdHJpeiBBQ1ANCg0KYGBge3J9DQpjbGluaWNfZGF0YXNldF9zaW5fTkE8LW5hLm9taXQoY2xpbmljX2RhdGFzZXQpDQoNCmdldF9laWdlbnZhbHVlKFBDQShjbGluaWNfZGF0YXNldF9zaW5fTkFbLC1jKDEsNCw1LDYsNyw4KV0sIG5jcCA9IDExLCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkNCg0KYGBgDQojI01hdHJpeiBkZSBjb3JyZWxhY2lvbmVzDQoNCmBgYHtyfQ0Kcm91bmQoY29yKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldKSwyKQ0KYGBgDQoNCiMjVmFsb3JlcyB5IHZlY3RvcmVzIHByb3Bpb3MgDQoNCmBgYHtyfQ0KDQpwcmluY29tcChjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgY29yID0gVFJVRSkkc2Rldl4yDQoNCmBgYA0KDQpgYGB7cn0NCnByaW5jb21wKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBjb3IgPSBUUlVFKSRsb2FkaW5nc1sgLDE6NV0NCmBgYA0KDQojI0NvcnJlbGFjaW9uZXMgY29tcGFyYWRhcw0KDQpgYGB7cn0NCg0KcGFyKG1mcm93PWMoMSwyKSkNCmNvcnJwbG90Ojpjb3JycGxvdChjb3IoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0pLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmNvcnJwbG90Ojpjb3JycGxvdChjb3IocHJpbmNvbXAoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0sIGNvciA9IFRSVUUpJHNjb3JlcyksIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCBudW1iZXIuY2V4ID0gMC40KQ0KYGBgDQoNCiMjR3LDoWZpY28gZGUgY2F0dGVsbA0KDQpgYGB7cn0NCmZ2aXpfZWlnKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgc2NhbGUudW5pdCA9IFQsIGdyYXBoID0gRiksIGFkZGxhYmVscyA9IFQsIHlsaW09YygwLDkwKSwgbWFpbiA9ICIiKQ0KYGBgDQoNCiMjR3LDoWZpY28gZGUgY2F0dGVsbC1rYWlzZXINCg0KYGBge3J9DQpzY3JlZShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSxmYWN0b3JzID0gRkFMU0UsIHBjID0gVFJVRSwgbWFpbiA9IiIpDQpgYGANCg0KIyMjIDIuMy4gQ2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24NCg0KQWwgcmV0b21hciBlbCB0cmFiYWpvIGRlIChEw61heiBNb3JhbGVzICYgTW9yYWxlcyBSaXZlcmEsIDIwMTIpIHNlIHZlcmlmaWNhIHF1ZSwgdW5hIHZleiByZWR1Y2lkYSBsYSBkaW1lbnNpb25hbGlkYWQgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIHkgZW50ZW5kaWRvIHF1ZSBzdXMgdmFyaWFibGVzIChlc3RhbmRhcml6YWRhcykgZXN0w6FuIHJlcHJlc2VudGFkYXMgZ3LDoWZpY2FtZW50ZSBwb3IgcHJveWVjY2lvbmVzIGRlIGxhIGhpcGVyZXNmZXJhIGRlIGNvcnJlbGFjaW9uZXMsIGVzIG5lY2VzYXJpbyBpbmljaWFyIGxhIGludGVycHJldGFjacOzbiBkZSBjb21wb25lbnRlcyBhIHBhcnRpciBkZSBkaWNoYXMgY29ycmVsYWNpb25lcywgcGFyYSBsdWVnbyBsYSBjYWxpZGFkIGRlIHN1cyByZXByZXNlbnRhY2lvbmVzIGRhZGEgbGEgcmVkdWNjacOzbiBkaW1lbnNpb25hbCBkZWwgY29uanVudG8gZGUgZGF0b3MgZW4gdMOpcm1pbm9zIGRlIHN1cyB2YXJpYWJsZXMuDQoNCioqUGxhbnRlYW1pZW50byBkZWwgcHJvYmxlbWEqKg0KDQpDb24gYmFzZSBlbiBlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBzZWNjacOzbiAyIHNlIGRlbWFuZGEgZGV0ZXJtaW5hciBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgcmVzcGVjdG8gYSBsYSBjYW50aWRhZCBkZSBkaW1lbnNpb25lcyBjYWxjdWxhZGFzIHF1ZSByZXRpZW5lbiBsYSBtYXlvciBjYW50aWRhZCBkZSB2YXJpYWJpbGlkYWQsIHZlciBsYSBzZWNjacOzbiA3Lg0KDQoqKkRlc2Fycm9sbG8gZGVsIGFuw6FsaXNpcyoqDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIG11ZXN0cmEgcXVlIGxhIHJlZHVjY2nDs24gZGUgbGEgZGltZW5zaW9uYWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcyBjb25kdWNlIGEgYW5hbGl6YXIgbGFzIGNhbGlkYWRlcyBkZSByZXByZXNlbnRhY2nDs24gZW4gdMOpcm1pbm9zIGRlIGxhIGVzY2FsYSBkZSBjb250cmlidWNpb25lcyByZWxhdGl2YXMgYmFzYWRhcyBlbiB1biBjb2NpZW50ZSBkZSBwcm95ZWNjaW9uZXMgY29uIHByb3BpZWRhZGVzIGFkaXRpdmFzIHkgZGUgcmVzcHVlc3RhIGVuIGVzY2FsYSBjb250aW51YSBlbnRyZTANCnkxDQouIEFzw60sIGVuIHBhcnRpY3VsYXI6DQoNCkVsIEPDrXJjdWxvIGRlIENvcnJlbGFjaW9uZXMgZXhwcmVzYSBxdWUgc2UgcHVlZGUgY29uY2ViaXIgdW4gY29tcGVuZW50ZSB0aXBvIHRhbWHDsW8gZW4gZWwgc2VudGlkbyBkZSBxdWUgbGEgZGltZW5zacOzbiAxIG11ZXN0cmEgZW4gw6lsIHVuYSBjb3JyZWxhY2nDs24gcG9zaXRpdmEgY29uIGxhcyBzZWlzIHZhcmlhYmxlcyBkZSBpbnRlcsOpcywgYWRlbcOhcyBjZXJjYW5vIGEgbGEgZnJvbnRlcmEgZGVsIGPDrXJjdWxvIHVuaXRhcmlvIHkgc2lnbmlmaWNhdGl2YW1lbnRlIHByw7N4aW1hcyBhbCBlamUgcXVlIGxhIHJlcHJlc2VudGEgLiBQb3Igb3RybyBsYWRvLCBsYSBkaW1lbnNpw7NuIDIgY29udHJhcG9uZSBhIGxhcyB2YXJpYWJsZXMgTE9SIHkgU09QIGNvbiBsYXMgZGVtw6FzLiBPdHJvIGFzcGVjdG8gcG9yIHJlc2FsdGFyIGVzIGxhIHZhbG9yYWNpw7NuIG1vc3RyYWRhIGVudHJlIHBhcmVzIGRlIHZhcmlhYmxlcywgcXVlIGVuIHTDqXJtaW5vcyBkZWwgZmVuw7NtZW5vIGVzdHVkaWFkbyBjb25zZXJ2YW4gc3UgbmF0dXJhbGV6YSBjb3JyZWxhY2lvbmFsIGVzcGVyYWRhIGhhc3RhIGVzdGUgcHVudG8gZGVsIGFuw6FsaXNpcy4gVW4gZWplbXBsbyByZXNhbHRhYmxlIGVzIGVsIHBhciBTT1AgeSBMT1IgcXVlLCBlbiBjaWVydG8gc2VudGlkbywgZXN0w6FuIGluZmx1ZW5jaWFkb3MgcG9yIGxhIHN1YmpldGl2aWRhZCwgdsOpYXNlIGxhIHNlY2Npw7NuIDIgLg0KDQpMYSBNYXRyaXogZGUgUmVwcmVzZW50YWNpw7NuICwgcG9yIG90cm8gbGFkbywgbXVlc3RyYSB2YWxvcmVzIHNpZ25pZmljYXRpdmFtZW50ZSBjZXJjYW5vcyBhIDEgZGVsIGNvY2llbnRlIGRlIHByb3llY2Npb25lcyBjb3Nlbm8gY3VhZHJhZG8gZW4gcmVsYWNpw7NuIGNvbiBsYSBkaW1lbnNpw7NuIDEuIEVuIGVzdGUgc2VudGlkbywgbG9zIHB1bnRvcyBwcm95ZWN0YWRvcyBlc3TDoW4gYWx0YW1lbnRlIGFzb2NpYWRvcyBjb24gZXN0ZSBjb21wb25lbnRlLiBBc8OtLCBsYSBlc3Rhw7FhIHF1ZSBtdWVzdHJhIGxhIENhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuIGluZGljYSBlbiBzdSBlc2NhbGEgdW4gcGlzbyBhbHRvIGRlMCw4NA0KZGUgZXN0YSBtYW5lcmEgbGFzIGNhbGlkYWRlcyBkZSByZXByZXNlbnRhY2nDs24sIGVuIHJlbGFjacOzbiBjb24gZWwgY29tcG9uZW50ZSAxLCBlc3TDoW4gZW5jYWJlemFkYXMgcG9yIENHUEEgeSBjaWVycmFuIGNvbiBTT1AgLiBDYWJlIGFjbGFyYXIgcXVlIGxhIGRpbWVuc2nDs24gMiBzb3N0aWVuZSB1bmEgbWVqb3IgcmVwcmVzZW50YWNpw7NuIGRlIExPUiBxdWUgZGUgU09QICwgcG9yIGxvIHRhbnRvLCBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBkZSBsYSBwcmltZXJhIGVuIHJlbGFjacOzbiBjb24gbGEgZGltZW5zacOzbiAxIHNlIHZlIGFmZWN0YWRhLg0KDQojIyBDw61yY3VsbyBkZSBjb3JyZWxhY2lvbmVzDQoNCmBgYHtyfQ0KDQpmdml6X3BjYV92YXIoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSxjb2wudmFyPSIjM0I4M0JEIiwgcmVwZWwgPSBULCBjb2wuY2lyY2xlID0gIiNDRENEQ0QiLCBnZ3RoZW1lID0gdGhlbWVfYncoKSkNCmBgYA0KDQojIyBNYXRyaXogZGUgcmVwcmVzZW50YWNpb24NCg0KYGBge3J9DQooZ2V0X3BjYV92YXIoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkpJGNvczINCmBgYA0KDQojIyBDYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbg0KDQpgYGB7cn0NCg0KZnZpel9wY2FfdmFyKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNvbC52YXI9ImNvczIiLCBncmFkaWVudC5jb2xzPWMoIiMwMEFGQkIiLCIjRTdCODAwIiwiI0ZDNEUwNyIpLCByZXBlbCA9IFRSVUUpDQpgYGANCg0KIyMgQ29vcmRlbmFkYXMgaW5kaXZpZHVhbGVzDQoNCmBgYHtyfQ0KaGVhZCgoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkkaW5kJGNvb3JkLCBuID0gMjNMKQ0KYGBgDQoNCiMjIyAyLjQuIENvbnRyaWJ1Y2lvbmVzIA0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwZXJtaXRlIHJlY29ub2NlciBlbiByZXByZXNlbnRhY2lvbmVzIG51bcOpcmljYXMgeSBncsOhZmljYXMgbGFzIGNvbnRyaWJ1Y2lvbmVzIGRlIGxhcyB2YXJpYWJsZXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGEgbGEgY29uc3RydWNjacOzbiBkZSBjYWRhIGNvbXBvbmVudGUuIEFzw60sIHNlIGVudGllbmRlIGN1w6FudGEgdmFyaWFiaWxpZGFkIGV4cGxpY2EgY2FkYSB2YXJpYWJsZSBkZSBsYSB2YXJpYWJpbGlkYWQgdG90YWwgZGUgbGEgY29tcG9uZW50ZSBjb24gcXVlIGVzdMOpIGludm9sdWNyYWRhLiBlbiBwYXJ0aWN1bGFyOg0KDQpMYSBNYXRyaXogZGUgQ29udHJpYnVjaW9uZXMgbXVlc3RyYSBlbiB0w6lybWlub3MgcmVsYXRpdm9zIGxhIHJldGVuY2nDs24gZGUgdmFyaWFiaWxpZGFkIHF1ZSB0aWVuZSBjYWRhIHZhcmlhYmxlIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgY2FkYSBjb21wb25lbnRlIEFzw60sIGxvcyBkaWFncmFtYXMgZGUgYmFycmFzIHZpc3VhbGl6YWRvcyBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBkZXNkZSBDb250cmlidWNpb25lcyBhIEQxIGhhc3RhIENvbnRyaWJ1Y2lvbmVzIGEgRDExLCBtdWVzdHJhbiBjb24gYmFzZSBlbiBkaWFncmFtYXMgZGUgYmFycmFzIGxhcyByZXNwZWN0aXZhcyBjb250cmlidWNpb25lcyBxdWUgaGFjZW4gbGFzIHZhcmlhYmxlcyBwYXJhIGV4cGxpY2FyIGxhIHZhcmlhbnphciBlbiBjYWRhIGNvbXBvbmVudGU7IGFkZW3DoXMsIGNhZGEgZ3LDoWZpY28gaW5jbHV5ZSB1bmEgbMOtbmVhIHF1ZSBheXVkYSBhIGlkZW50aWZpY2FyIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWEsIGVzdG8gYXl1ZGEgYSBpZGVudGlmaWNhciBjb24gbWF5b3IgZmFjaWxpZGFkIGEgbGFzIHZhcmlhYmxlcyBxdWUgY29udHJpYnV5ZW4gY29uIG1heW9yIGV4cGxpY2FjacOzbiBkZSB2YXJpYWJpbGlkYWQgZGUgbG9zIGNvbXBvbmVudGVzIHF1ZSBjb25mb3JtYW4uDQoNCioqUGxhbnRlYW1pZW50byBkZWwgUHJvYmxlbWEqKg0KDQpDb24gYmFzZSBlbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIHNlY2Npw7NuIDIgc2UgZGVtYW5kYSBkZXRlcm1pbmFyIGxhcyBjb250cmlidWNpb25lcyBxdWUgaGFjZSBjYWRhIHZhcmlhYmxlIGEgbGEgY29uc3RydWNjacOzbiBkZSBjYWRhIGNvbXBvbmVudGUuDQoNCioqRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzKioNCg0KKGdldF9wY2FfdmFyKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRikpKSRjb250cmliDQoNCiMjIyAyLjUuIEludGVycHJldGFjacOzbiBkZSBjb21wb25lbnRlcw0KDQpDb24gYmFzZSBlbiAoRMOtYXogTW9yYWxlcyAmIE1vcmFsZXMgUml2ZXJhLCAyMDEyKSBzZSBzYWJlIHF1ZSBhIHBhcnRpciBkZSBsYXMgY29vcmRlbmFkYXMgZGUgbG9zIHJlZ2lzdHJvcyBkaW1lbnNpb25hbG1lbnRlIHJlZHVjaWRvcyBzZSBwdWVkZSB1YmljYXIgZW4gdW4gcGxhbm8gZGUgZmFjdG9yZXMgcGFyYSBlZmVjdG9zIGRlIGFuw6FsaXNpcyBlIGludGVycHJldGFjacOzbi4gQXPDrSwgbGFzIHZhcmlhYmxlcyByZWR1Y2lkYXMgc29uIGxhcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBxdWUgc2UgZ3JhZmljYW4gY29tbyBlamVzIGVuIHVuIHBsYW5vLCB5IGxvcyB2YWxvcmVzIHF1ZSB0b21lbiBzb24gbG9zIHB1bnRhamVzIGRlIGxhcyBjb21wb25lbnRlcy4gQ29tbyBiaWVuIHNlIGV4cGxpY2EgZW4gZWwgbWlzbW8gdHJhYmFqbywgbGFzIGRpc3RhbmNpYXMgZW50cmUgbG9zIHB1bnRvcyBkZWZpbmlkb3MgcG9yIGxvcyBwdW50YWplcyBkZSBsYXMgY29tcG9uZW50ZXMgdGllbmUgdW4gc2lnbmlmaWNhZG8gcmVsZXZhbnRlIGFsIGF5dWRhciBhIGVzdGFibGVjZXIgc2VtZWphbnphcyBkZSBwZXJmaWxlcyBlbiBsYXMgb2JzZXJ2YWNpb25lcyBoZWNoYXMuIFNpbiBlbWJhcmdvLCBsb3MgdmFsb3JlcyBzZW1lamFudGVzIGRlIGxhcyB2YXJpYWJsZXMgcHVlZGVuIGRhcnNlIHNvbG8gZW4gYWxndW5hcyBkZSBlbGxhcywgc2luIGVzcGVyYXIgbmVjZXNhcmlhbWVudGUgYSBxdWUgc3VjZWRhIGVuIHRvZGFzLiBBc8OtLCBzZSBlc3BlcmEgcXVlIGxhcyBkaXN0YW5jaWFzIGVuIGVsIGVzcGFjaW8gZGltZW5zaW9uYWwgb3JpZ2luYWwgZGUgbGFzIG9ic2VydmFjaW9uZXMgcXVlZGVuIGJpZW4gcmVwcmVzZW50YWRhcyBlbiBlbCBlc3BhY2lvIHJlZHVjaWRvIGRlIGxhcyBjb21wb25lbnRlcy4NCg0KKipQbGFudGVhbWllbnRvIGRlbCBQcm9ibGVtYSoqDQoNCkNvbiBiYXNlIGVuIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMiBzZSBkZW1hbmRhIGRlZmluaXIgZSBpbnRlcnByZXRhciBzdXMgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMuDQoNCioqRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzKioNCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgcGVybWl0ZSByZWNvbm9jZXIgZW4gcmVwcmVzZW50YWNpb25lcyBudW3DqXJpY2FzIHkgZ3LDoWZpY2FzIGxhcyBjb250cmlidWNpb25lcyBkZSBsYXMgdmFyaWFibGVzIGRlbCBjb25qdW50byBkZSBkYXRvcyBhIGxhIGNvbnN0cnVjY2nDs24gZGUgY2FkYSBjb21wb25lbnRlLiBBc8OtLCBzZSBlbnRpZW5kZSBjdcOhbnRhIHZhcmlhYmlsaWRhZCBzZSBleHBsaWNhIGNhZGEgdmFyaWFibGUgZGUgbGEgdmFyaWFiaWxpZGFkIHRvdGFsIGRlIGxhIGNvbXBvbmVudGUgY29uIGxhIHF1ZSBlc3TDoSBpbnZvbHVjcmFkYS4gZW4gcGFydGljdWxhcjoNCg0KTGEgTWF0cml6IGRlIENvbnRyaWJ1Y2lvbmVzIG11ZXN0cmEgZW4gdMOpcm1pbm9zIHJlbGF0aXZvcyBsYSByZXRlbmNpw7NuIGRlIHZhcmlhYmlsaWRhZCBxdWUgdGllbmUgY2FkYSB2YXJpYWJsZSBlbiBsYSBjb25zdHJ1Y2Npw7NuIGRlIGNhZGEgY29tcG9uZW50ZS4gQXPDrSwgbG9zIGRpYWdyYW1hcyBkZSBiYXJyYXMgdmlzdWFsaXphZG9zIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIGRlc2RlIENvbnRyaWJ1Y2lvbmVzIGEgRDEgaGFzdGEgQ29udHJpYnVjaW9uZXMgYSBENiAsIG11ZXN0cmFuIGNvbiBiYXNlIGVuIGRpYWdyYW1hcyBkZSBiYXJyYXMgbGFzIHJlc3BlY3RpdmFzIGNvbnRyaWJ1Y2lvbmVzIHF1ZSBoYWNlbiBsYXMgdmFyaWFibGVzIHBhcmEgZXhwbGljYXIgbGEgdmFyaWFuemEgZW4gY2FkYSBjb21wb25lbnRlOyBBZGVtw6FzLCBjYWRhIGdyw6FmaWNvIGluY2x1eWUgdW5hIGzDrW5lYSBxdWUgYXl1ZGEgYSBpZGVudGlmaWNhciBsYSBjb250cmlidWNpw7NuIG1lZGlhLCBlc3RvIGF5dWRhIGEgaWRlbnRpZmljYXIgY29uIG1heW9yIGZhY2lsaWRhZCBhIGxhcyB2YXJpYWJsZXMgcXVlIGNvbnRyaWJ1eWVuIGNvbiBtYXlvciBleHBsaWNhY2nDs24gZGUgdmFyaWFiaWxpZGFkIGRlIGxvcyBjb21wb25lbnRlcyBxdWUgY29uZm9ybWFuLg0KDQoNCiMjIE1hdHJpeiBkZSBjb250cmlidWNpb25lcw0KDQpgYGB7cn0NCihnZXRfcGNhX3ZhcihQQ0EoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKSkkY29udHJpYg0KYGBgDQoNCiMjIENvbnRyaWJ1Y2lvbmVzIGEgRDENCg0KYGBge3J9DQpmdml6X2NvbnRyaWIoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxLCB0b3AgPSAxMCkNCmBgYA0KDQojIyBDb250cmlidWNpb25lcyBhIEQyDQoNCmBgYHtyfQ0KZnZpel9jb250cmliKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMiwgdG9wID0gMTApDQpgYGANCg0KIyNDb250cmlidWNpb25lcyBhIEQzDQoNCmBgYHtyfQ0KZnZpel9jb250cmliKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMywgdG9wID0gMTApDQpgYGANCg0KIyNDb250cmlidWNpb25lcyBhIEQ0DQoNCmBgYHtyfQ0KZnZpel9jb250cmliKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNCwgdG9wID0gMTApDQpgYGANCg0KIyNDb250cmlidWNpb25lcyBhIEQ1DQoNCmBgYHtyfQ0KZnZpel9jb250cmliKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNSwgdG9wID0gMTApDQpgYGANCg0KIyNDb250cmlidWNpb25lcyBhIEQ2DQoNCmBgYHtyfQ0KZnZpel9jb250cmliKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNSwgdG9wID0gNSkNCmBgYA0KDQojIyMgY29udHJpYnVjaW9uZXMgRDcNCg0KYGBge3J9DQpmdml6X2NvbnRyaWIoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSA1LCB0b3AgPSAxMCkNCmBgYA0KDQojIyMgY29udHJpYnVjaW9uZXMgRDgNCg0KYGBge3J9DQpmdml6X2NvbnRyaWIoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBuY3AgPSA1LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSA1LCB0b3AgPSAxNSkNCmBgYA0KDQojIyMgY29udHJpYnVjaW9uZXMgRDkNCg0KYGBge3J9DQpmdml6X2NvbnRyaWIoUENBKGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcsOCldLCBuY3AgPSA1LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSA1LCB0b3AgPSAxNSkNCmBgYA0KDQojIyMgY29udHJpYnVjaW9uZXMgRDEwDQoNCmBgYHtyfQ0KZnZpel9jb250cmliKFBDQShjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3LDgpXSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNSwgdG9wID0gMTUpDQpgYGANCg0KIyMjIGNvbnRyaWJ1Y2lvbmVzIEQxMQ0KDQpgYGB7cn0NCmZ2aXpfY29udHJpYihQQ0EoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDE1KQ0KYGBgDQoNCiMjIDIuNCBJbnRlcnByZXRhY2lvbiBkZSBjb21wb25lbnRlcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpDb24gYmFzZSBlbiAoIETDrWF6IE1vcmFsZXMgJiBNb3JhbGVzIFJpdmVyYSwgMjAxMiApIHNlIHNhYmUgcXVlIGEgcGFydGlyIGRlIGxhcyBjb29yZGVuYWRhcyBkZSBsb3MgcmVnaXN0cm9zIGRpbWVuc2lvbmFsbWVudGUgcmVkdWNpZG9zIHNlIHB1ZWRlIHViaWNhciBlbiB1biBwbGFubyBkZSBmYWN0b3JlcyBwYXJhIGVmZWN0b3MgZGUgYW7DoWxpc2lzIGUgaW50ZXJwcmV0YWNpw7NuLiBBc8OtLCBsYXMgdmFyaWFibGVzIHJlZHVjaWRhcyBzb24gbG9zIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIHF1ZSBzZSBncmFmaWNhbiBjb21vIGVqZXMgZW4gdW4gcGxhbm8sIHkgbG9zIHZhbG9yZXMgcXVlIHRvbWVuIHNvbiBsb3MgcHVudGFqZXMgZGUgbG9zIGNvbXBvbmVudGVzLiBDb21vIGJpZW4gc2UgZXhwbGljYSBlbiBlbCBtaXNtbyB0cmFiYWpvLCBsYXMgZGlzdGFuY2lhcyBlbnRyZSBsb3MgcHVudG9zIGRlZmluaWRvcyBwb3IgbG9zIHB1bnRhamVzIGRlIGxvcyBjb21wb25lbnRlcyB0aWVuZSB1biBzaWduaWZpY2FkbyByZWxldmFudGUgYWwgYXl1ZGFyIGEgZXN0YWJsZWNlciBzZW1lamFuemFzIGRlIHBlcmZpbGVzIGVuIGxhcyBvYnNlcnZhY2lvbmVzIGhlY2hhcy4gU2luIGVtYmFyZ28sIGxvcyB2YWxvcmVzIHNlbWVqYW50ZXMgZGUgbGFzIHZhcmlhYmxlcyBwdWVkZW4gZGFyc2Ugc29sbyBlbiBhbGd1bmFzIGRlIGVsbGFzLCBzaW4gZXNwZXJhciBuZWNlc2FyaWFtZW50ZSBhIHF1ZSBzdWNlZGEgZW4gdG9kYXMuIEFzw60sIHNlIGVzcGVyYSBxdWUgbGFzIGRpc3RhbmNpYXMgZW4gZWwgZXNwYWNpbyBkaW1lbnNpb25hbCBvcmlnaW5hbCBkZSBsYXMgb2JzZXJ2YWNpb25lcyBxdWVkZW4gYmllbiByZXByZXNlbnRhZGFzIGVuIGVsIGVzcGFjaW8gcmVkdWNpZG8gZGUgbG9zIGNvbXBvbmVudGVzLg0KDQoqKlBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hKioNCg0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0b3MgZW4gbGEgc2VjY2nDs24gMiBzZSBleGlnZSBkZWZpbmlyIGUgaW50ZXJwcmV0YXIgc3VzIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLg0KDQoqKkRlc2Fycm9sbG8gZGVsIGFuw6FsaXNpcyoqDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIHBlcm1pdGUgdmlzdWFsaXphciBvYmpldG9zIGdyw6FmaWNvcyB5IG1hdHJpY2lhbGVzIHF1ZSwgYWwgaW5jbHVpciBsbyBoZWNobyBlbiBsYXMgc2VjY2lvbmVzIGFudGVyaW9yZXMsIHBvZHJpYW4gYXl1ZGFyIGEgcm9idXN0ZWNlciBsYSBpbnRlcnByZXRhY2nDs24gZGUgbGFzIGNvbXBvbmVudGVzIGNhbGN1bGFkYXMsIGF1bnF1ZSBsb3MgZGF0b3MgbnVldmFtZW50ZW4gdG9tYW4gZm9ybWFzIGRpZsOtY2lsZXMgZGUgcmVsYWNpb25hciwgbG9zIGRhdG9zIHNlIG11ZXN0cmFuIGRpc3BlcnNvcywgc2luIHVuYSB0ZW5lZGVuY2lhIGNsYXJhIGRlbnRybyBkZSBlbGxvcy4NCg0KY2FiZSByZXNhbHRhciBxdWUgc2UgdHV2byBsYSBuZWNlc2lkYWQgZGUgdHJhYmFqYXIgY29uIHN1YmNvbmp1bnRvcyBkZSAxMCBhIDMwMCByZWdpc3Ryb3MgcGFyYSBxdWUgZWwgcHJvZ3JhbWEgcHVkaWVzZSBjb3JyZXIgbGFzIGdyYWZpY2FzLCB5YSBxdWUgbGEgdmFyaWFibGVzIGN1YWxpdGF0aXZhcyBjb21vIGxvIHNvbiBnZW5lcm9fZGVsX3BhY2llbnRlLCBhc2lzdGVuY2lhX3ByaXZhZGFfcHVibGljYSB5IHJlc2lkZW5jaWFfY2VyY2FfYWxfY2VudHJvLCBudW1lcm9fZGVfaGlqb3MsdXNvX3N1c3RhbmNpYV9wc2ljb2F0aXZhLCBjb250aWVuZW4gcmVnaXN0cm9zIHF1ZSBwb2RyaWFuIGFwYXJlY2VyIHVuYSBzb2xhIHZleiwgbG8gcXVlIGhhcmlhIGltcG9zaWJsZSBncmFmaWNhciBsb3MgYml0cGxvcy4NCg0KIyMgQmlwbG90IGRlIHZhcmlhYmxlcyB5IHJlZ2lzdHJvcyBbdG90YWwgRSAtPiBlc3RyYXRvX3NvY2llY29ub21pY29dDQoNCmBgYHtyfQ0KZGF0YV9FIDwtIGNsaW5pY19kYXRhc2V0WywtYygxLDQsNSw2LDcpXQ0KZGF0YV9BbGwgPC0gY2JpbmQoY2xpbmljX2RhdGFzZXRbLC1jKDEsNCw1LDYsNyw4KV0sIGRhdGFfRSRlc3RyYXRvX3NvY2lvZWNvbm9taWNvKQ0KZnZpel9wY2FfYmlwbG90KFBDQShkYXRhX0FsbCwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiwgcXVhbGkuc3VwID0gNiksIGF4ZXMgPSBjKDEsIDIpLCByZXBlbCA9IFRSVUUsIGhhYmlsbGFnZSA9IDYpDQpgYGANCg0KIyMgQmlwbG90IGRlIHZhcmlhYmxlcyB5IHJlZ2lzdHJvcyBbdG90YWwgQSAtPiBhc2lzdGVuY2lhX3ByaXZhZGFfcHVibGljYSBdDQoNCmRhdGFfQSA8LSBjbGluaWNfZGF0YXNldFssLWMoMSw1LDYsNyldDQpkYXRhX0FsbCA8LSBjYmluZChjbGluaWNfZGF0YXNldFssLWMoMSw0LDUsNiw3KV0sIGRhdGFfQSRhc2lzdGVuY2lhX3ByaXZhZGFfcHVibGljYSkNCmZ2aXpfcGNhX2JpcGxvdChQQ0EoZGF0YV9BbGwsIG5jcCA9IDQsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYsIHF1YWxpLnN1cCA9IDUpLCBheGVzID0gYygxLCAyKSwgcmVwZWwgPSBUUlVFLCBoYWJpbGxhZ2UgPSA1KQ0KDQojIyBCaXBsb3QgZGUgdmFyaWFibGVzIHkgcmVnaXN0cm9zIFtUb3RhbCBSLT5SZXNpZGVuY2lhX2NlcmNhX2FsX2NlbnRyb10NCg0KDQpzZXQuc2VlZCg3ODA3MjgpDQpkYXRhXzIwX2NpIDwtIGNsaW5pY19kYXRhc2V0X3Npbl9OQVtzYW1wbGUoMTpucm93KGNsaW5pY19kYXRhc2V0X3Npbl9OQSksMjApLC1jKDIsMywxNSldDQpzZXQuc2VlZCg3ODA3MjgpDQpkYXRhXzIwIDwtIGNiaW5kKGNsaW5pY19kYXRhc2V0X3Npbl9OQVtzYW1wbGUoMTpucm93KGNsaW5pY19kYXRhc2V0X3Npbl9OQSksMjApLC1jKDEsMiwzLDE1KV0sIGRhdGFfUiRSZXNpZGVuY2lhX2NlcmNhX2FsX2NlbnRybykNCmZ2aXpfcGNhX2JpcGxvdChQQ0EoZGF0YV8yMCwgbmNwID0gMTEsIHNjYWxlLnVuaXQgPSBULCBncmFwaCA9IEYsIHF1YWxpLnN1cCA9IDEyKSwgYXhlcyA9IGMoMSwgMiksIHJlcGVsID0gVCwgaGFiaWxsYWdlID0gMTEpDQoNCg0KIyMgQ29vcmRlbmFkYXMgaW5kaXZpZHVhbGVzIFtTdWNvbmp1bnRvIEVdDQoNCnNldC5zZWVkKDc4MDcyOCkNCmRhdGFfNjFfVVIgPC0gY2xpbmljX2RhdGFzZXRfSW5pdGlhbFtzYW1wbGUoMTpucm93KGNsaW5pY19kYXRhc2V0X0luaXRpYWwpLDYxKSwtYygxLDQsNSw2KV0NCnNldC5zZWVkKDc4MDcyOCkNCmRhdGFfNjEgPC0gY2JpbmQoY2xpbmljX2RhdGFzZXRfSW5pdGlhbFtzYW1wbGUoMTpucm93KGNsaW5pY19kYXRhc2V0X0luaXRpYWwpLDYxKSwtYygxLDQsNSw2LDcpXSwgZGF0YV82MV9VUiRFZXN0cmF0b19zb2NpZWNvbm9taWNvKQ0KaGVhZChQQ0EoZGF0YV82MSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UsIHF1YWxpLnN1cCA9IDcpJGluZCRjb29yZCwgbiA9IDYxTCkNCg0KIyBPYmpldGl2b3MgeSBhbm90YWNpb25lcyA6OkZhc2UgMyANCg0KIyMgMy4xLiBPYmpldGl2b3MNCg0KRW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgZXN0YSB0ZXJjZXJhIGV0YXBhIGRlIGVzdHVkaW8gbW9zdHJhcsOhIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcyBjb24gYmFzZSBlbiBlbCBjb25qdW50byBkZSBkYXRvcyB0cmF0YWRvIGVuIGxhIGZhc2UgMSB5IDIsIHBlcm8gYWhvcmEgZGVzZGUgdW4gZW5mb3F1ZSBkZSBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBzaW1wbGVzIHkgbcO6bHRpcGxlcyBzb2JyZSBsYXMgdmFyaWFibGVzIGN1YW5saXRhdGl2YXMsIHF1ZSBpbmNsdWlyw6E6IGNvbnN0cnVjY2nDs24gZGUgdGFibGFzIGRlIGNvbnRpbmdlbmNpYXMgeSBkaXN5dW50aXZhcyBjb21wbGV0YXMsIGNhbGlkYWRlcyBkZSByZXByZXNlbnRhY2nDs24sIGNvbnRyaWJ1Y2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcy4NCg0KUmVjdcOpcmRlc2UgcXVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHRyYWJham8gZXMgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMiB5IGxvcyByZWZlcmVudGVzIHRlw7NyaWNvcyBlbiBsYSBzZWNjacOzbiAxLg0KDQpQb3Igw7psdGltbywgZXN0ZSB0cmFiYWpvIGZ1ZSBwcm9jZXNhZG8gY29uIFIgdmVyc2lvbiA0LjIuMiAoMjAyMi0xMC0zMSB1Y3J0KSBtZWRpYWRvIHBvciBSU3R1ZGlvIDIwMjIuMTIuMCBCdWlsZCAzNTMgZW4gdW5hIHBsYXRhZm9ybWEgeDg2XzY0LXc2NC1taW5ndzMyLiBBZGVtw6FzLCBwb3Igc3UgbmF0dXJhbGV6YSBkZSBwdWJsaWNhY2nDs24gZW4gbMOtbmVhIHkgcGFyYSBjdW1wbGlyIGNvbiBlbCByZXF1aXNpdG8gdGVtcG9yYWwgZGUgZW50cmVnYSwgc2Vyw6EgYWN0dWFsaXphZG8sIGNvbW8gbcOheGltbywgaGFzdGEgbGFzIDExOjU5IHAubS4gZGVsIGRvbWluZ28gNSBkZSBtYXJ6byBkZSAyMDIzLg0KDQojIyAzLjIuIENvcnJlc3BvbmRlbmNpYXMgU2ltcGxlcw0KDQpDb24gYmFzZSBlbiBlbCB0cmFiYWpvIGRlICggQWxkw6FzICYgVXJpZWwsIDIwMTcgKSBzZSBzYWJlIHF1ZSBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBzaW1wbGVzIChBQ1MpIGJ1c2NhIHJlcHJlc2VudGFyIGVuIHVuIGVzcGFjaW8gbXVsdGlkaW1lbnNpb25hbCByZWR1Y2lkbyBsYSByZWxhY2nDs24gcXVlIGV4aXN0ZSBlbnRyZSBsYXMgY2F0ZWdvcsOtYXMgZGUgdW4gcGFyIGRlIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMuIEVuIGVzdGUgc2VudGlkbywgZWwgQUNTIG11ZXN0cmEgbGFzIGRpc3RhbmNpYSBlbnRyZSBsb3Mgbml2ZWxlcyBkZSBkb3MgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyB5LCBlbiBjb25zZWN1ZW5jaWEsIGF5dWRhIGEgdmlzdWFsaXphciB0YWJsYXMgZGUgY29udGluZ2VuY2lhLiBBZGVtw6FzLCBzZSBlc3RhYmxlY2UgcXVlIGVsIG7Dum1lcm8gbcOheGltbyBkZSBkaW1lbnNpb25lcyBxdWUgZXhwbGljYW4gbGEgYXNvY2lhY2nDs24gZW50cmUgdmFyaWFibGVzIGZpbGEgeSBjb2x1bW5hIGVzIGlndWFsIGEgdW5vIG1lbm9zIGVsIG1lbm9yIG7Dum1lcm8gZGUgY2F0ZWdvcsOtYXMgZGUgYWxndW5hIGRlIGxhcyB2YXJpYWJsZXMgaW52b2x1Y3JhZGFzLiBFbiBjb25zZWN1ZW5jaWEsIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHBlcm1pdGUgZGVzY3JpYmlyIGxhIHByb3hpbWlkYWQgZXhpc3RlbnRlIGVudHJlIGxvcyBwZXJmaWxlcyBkZSBsb3Mgb2JqZXRvcyBvYnNlcnZhZG9zLiBBZGVtw6FzLCBlbCBBQ1MsIHF1ZSBiYXNhIHN1cyBjw6FsY3Vsb3MgZW4gdGFibGFzIGRlIGNvbnRpbmdlbmNpYSwgcHVlZGUgZXh0ZW5kZXJzZSBhIG3DoXMgZGUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMsIGNvbm9jacOpbmRvc2UgY29tbyBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBNw7psdGlwbGVzIChBQ00pLCBjb24gYmFzZSBlbiB1biBvYmpldG8gbGxhbWFkbyB0YWJsYSBkaXN5dW50aXZhIGNvbXBsZXRhLg0KDQojIyAzLjMuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hIA0KDQpDb24gYmFzZSBlbiBsYXMgdmFyaWFibGVzIGN1YWxpdGF0aXZhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMiBzZSBkZW1hbmRhIGRlc2Fycm9sbGFyIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzLCBlbiBwcmluY2lwaW8gc2ltcGxlLCBhcG95YWRvIGVuIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgeSBkZSBmcmVjdWVuY2lhcyByZWxhdGl2YXMgeSBncsOhZmljb3MgZGUgcGVyZmlsZXMgeSBkZSBwdW50b3Mgc3VwZXJwdWVzdG9zIGVuIGVsIHByaW1lciBwbGFubyBmYWN0b3JpYWwuDQoNCiMjIDMuNCBEZXNhcnJvbGxvIGRlbCBBbsOhbGlzaXMNCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgcGVybWl0ZSB2aXN1YWxpemFyIG9iamV0b3MgbWF0cmljaWFsZXMgeSBncsOhZmljb3MgcXVlIGF5dWRhbiBhIHJvYnVzdGVjZXIgbGEgaW50ZXJwcmV0YWNpw7NuIGRlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBzaW1wbGVzIChiaW5hcmlvKSBlbnRyZSBjYWRhIHBhciBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIGRlbCBjb25qdW50byBkZSBkYXRvczogYGdlbmVyb19kZWxfcGFjaWVudGVgLCBgYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2FgIHkgYHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzYC4gUG9yIHNlciBiYWphIGxhIGNhbnRpZGFkIGRlIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMsIHNlIHRyYWJhamEgZWwgQUNTIHNvYnJlIGxhcyB0cmVzIGNvbWJpbmFjaW9uZXMgcG9zaWJsZXMuDQoNCkxhIHBlc3Rhw7FhICoqQUMgUGFyZWphcyBUb3RhbGVzKiogYWdydXBhIGxvcyBjw6FsY3Vsb3MgcGFyYSB0b2RhcyBsYXMgY29tYmluYWNpb25lcyBkZSBwYXJlamFzIGRlIHZhcmlhYmxlcy4gRW4gcGFydGljdWxhciwgZW4gKipDb250aW5nZW5jaWFzKiogc2UgaGFjZW4gbGFzIHNpZ3VpZW50ZXMgbGVjdHVyYXMgZGUgZWplbXBsbyBkZSBsYXMgdGFibGFzIGRlIGNvbnRpbmdlbmNpYXM6IGVuIGxhIHRhYmxhIGRlIGNvbnRpbmdlbmNpYXMgYGdlbmVyb19kZWxfcGFjaWVudGVgIHZzLiBgdXNvX3N1c3RhbmNpYXNfcHNpY29hdGl2YXNgIHNlIGVuY29udHLDsyBxdWUgODAgcGFjaWVudGVzIGRlIHVuIHRvdGFsIGRlIDE1MSBkZSBzZXhvIGZlbWVuaW5vIHJlcG9ydGFyb24gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzLiBBZGVtw6FzLCBkZSBsb3MgMTgxIHBhY2llbnRlcyBxdWUgbm8gcmVwb3J0YXJvbiB1c28gZGUgc3VzdGFuY2lhcyBwc2ljb2FjdGl2YXMsIGRlIHVuIHRvdGFsIGRlIDQwMCwgNzEgc29uIGRlIHNleG8gZmVtZW5pbm8geSAxMTAgZGUgc2V4byBtYXNjdWxpbm8uIEVuIGxhIHRhYmxhIGRlIGNvbnRpbmdlbmNpYXMgYGdlbmVyb19kZWxfcGFjaWVudGVgIHZzLiBgYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2FgLCBzZSBjYWxjdWzDsyBxdWUgMTQgcGFjaWVudGVzIGRlIHVuIHRvdGFsIGRlIDI0OSBkZSBzZXhvIG1hc2N1bGlubyBhc2lzdGllcm9uIGEgc2VydmljaW9zIHByaXZhZG9zOyBhZGVtw6FzLCBkZSBsb3MgNjAgcGFjaWVudGVzIHF1ZSBhc2lzdGllcm9uIGEgc2VydmljaW9zIHDDumJsaWNvcywgMjMgZXJhbiBkZSBzZXhvIGZlbWVuaW5vIHkgMzcgZGUgc2V4byBtYXNjdWxpbm8uIFBvciDDumx0aW1vLCBlbiBsYSB0YWJsYSBkZSBjb250aW5nZW5jaWEgYHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzYCB2cy4gYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCBzZSBwdWVkZSBkZXRlcm1pbmFyIHF1ZSA1OSBwYWNpZW50ZXMsIGRlIHVuIHRvdGFsIGRlIDIxOSwgcXVlIHJlcG9ydGFyb24gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzLCBhc2lzdGllcm9uIGEgc2VydmljaW9zIHDDumJsaWNvczsgYWRlbcOhcywgNzUgcGFjaWVudGVzLCBkZSB1biB0b3RhbCBkZSAxMDcsIHF1ZSBhc2lzdGllcm9uIGEgc2VydmljaW9zIHByaXZhZG9zLCBubyByZXBvcnRhcm9uIGVsIHVzbyBkZSBzdXN0YW5jaWFzIHBzaWNvYWN0aXZhcy4NCg0KQWwgdG9tYXIgY29tbyBiYXNlIGxhcyB0YWJsYXMgZGUgY29udGluZ2VuY2lhIGRlc2NyaXRhcyBhbnRlcywgc2UgcHJlc2VudGEgYSB0cmF2w6lzIGRlIGxhIHN1YnBlc3Rhw7FhICoqUHJvYmFiaWxpZGFkZXMqKiBsYXMgcHJvcG9yY2lvbmVzIHJlbGF0aXZhcyBlbiB0w6lybWlub3MgZGUgbG9zIHBhcmVzIGRlIHZhcmlhYmxlcyBleGFtaW5hZGFzLiBFbiBlc3RlIHNlbnRpZG8sIGEgbml2ZWwgZGUgZWplbXBsbyBzZSBwcmVzZW50YW4gYWxndW5hcyBsZWN0dXJhcyBkZSBlbGxhczogZW4gbGEgdGFibGEgZGUgcHJvYmFiaWxpZGFkZXMgYGdlbmVyb19kZWxfcGFjaWVudGVgIHZzLiBgdXNvX3N1c3RhbmNpYXNfcHNpY29hdGl2YXNgLCBlbCAyMC4wMCUgZGVsIHRvdGFsIGRlIHBhY2llbnRlcyBzb24gZGUgc2V4byBmZW1lbmlubyBxdWUgcmVwb3J0YXJvbiBlbCB1c28gZGUgc3VzdGFuY2lhcyBwc2ljb2FjdGl2YXM7IGFkZW3DoXMsIGVsIDQ1LjI1JSBkZWwgdG90YWwgZGUgcGFjaWVudGVzIG5vIHJlcG9ydGFyb24gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzLCBkb25kZSBlbCAxNy43NSUgZXJhbiBob21icmVzIHkgZWwgMjcuNTAlIG11amVyZXMuIEVuIGxhIHRhYmxhIGRlIHByb2JhYmlsaWRhZGVzIGBnZW5lcm9fZGVsX3BhY2llbnRlYCB2cy4gYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCwgZWwgMy41MCUgZGVsIHRvdGFsIGRlIHBhY2llbnRlcyBmdWVyb24gaG9tYnJlcyBxdWUgYXNpc3RpZXJvbiBhIHNlcnZpY2lvcyBwcml2YWRvczsgYWRlbcOhcywgZGVsIDE1LjAwJSBkZSBwYWNpZW50ZXMgcXVlIGFzaXN0aWVyb24gYSBzZXJ2aWNpb3MgcMO6YmxpY29zLCBlbCA5LjI1JSBlcmFuIGhvbWJyZXMgeSBlbCA1Ljc1JSBtdWplcmVzLiBQb3Igw7psdGltbywgZW4gbGEgdGFibGEgZGUgcHJvYmFiaWxpZGFkZXMgYHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzYCB2cy4gYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCwgZWwgMTQuNzUlIGRlbCB0b3RhbCBkZSBwYWNpZW50ZXMgcmVwb3J0w7MgZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzIHkgYXNpc3RpZXJvbiBhIHNlcnZpY2lvcyBww7pibGljb3M7IGFkZW3DoXMsIGVsIDE4Ljc1JSBkZWwgdG90YWwgZGUgcGFjaWVudGVzIGFzaXN0aWVyb24gYSBzZXJ2aWNpb3MgcHJpdmFkb3Mgc2luIHJlcG9ydGFyIGVsIHVzbyBkZSBzdXN0YW5jaWFzIHBzaWNvYWN0aXZhcy4NCg0KQ29tbyBvY3VycmUgY29uIGxhcyB0YWJsYXMgZGUgcHJvYmFiaWxpZGFkZXMgbyBwcm9wb3JjaW9uZXMsIGVuIGxhIHN1YnBlc3Rhw7FhICoqRnJlY3VlbmNpYXMgW0NQRiB5IENQQ10qKiwgbGFzIGZyZWN1ZW5jaWFzIGNvbmRpY2lvbmFkYXMgcG9yIGZpbGFzIHkgY29uZGljaW9uYWRhcyBwb3IgY29sdW1uYXMgKHJlc3BlY3RpdmFtZW50ZSkgc2UgY2FsY3VsYXJvbiBjb24gYmFzZSBlbiBsYXMgdGFibGFzIGRlIGNvbnRpbmdlbmNpYSByZXNwZWN0aXZhcy4gQXPDrSwgc2UgcHVlZGVuIHByZXNlbnRhciBsYXMgbGVjdHVyYXMgZGUgZWplbXBsbzogc2Vnw7puIGxhIG1hdHJpeiBkZSBmcmVjdWVuY2lhcyBDUEYgZGUgYGdlbmVyb19kZWxfcGFjaWVudGVgIHZzLiBgdXNvX3N1c3RhbmNpYXNfcHNpY29hdGl2YXNgLCBkZSBsb3MgcGFjaWVudGVzIGRlIHNleG8gZmVtZW5pbm8sIGVsIDUyLjk4JSByZXBvcnTDsyBlbCB1c28gZGUgc3VzdGFuY2lhcyBwc2ljb2FjdGl2YXMsIG1pZW50cmFzIHF1ZSBlbnRyZSBsb3MgcGFjaWVudGVzIGRlIHNleG8gbWFzY3VsaW5vIGxvIGhpem8gZWwgNTUuODIlLiBBZGVtw6FzLCBzZWfDum4gbGEgbWlzbWEgbWF0cml6IHBlcm8gY29uZGljaW9uYWRhIHBvciBjb2x1bW5hcywgZWwgMzkuMjMlIGRlIGxvcyBwYWNpZW50ZXMgcXVlIG5vIHJlcG9ydGFyb24gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzIGZ1ZXJvbiBkZSBzZXhvIGZlbWVuaW5vLCBtaWVudHJhcyBxdWUgZWwgNjAuNzclIGZ1ZXJvbiBkZSBzZXhvIG1hc2N1bGluby4gQWhvcmEsIHNlZ8O6biBsYSBtYXRyaXogZGUgZnJlY3VlbmNpYXMgQ1BGIGRlIGBnZW5lcm9fZGVsX3BhY2llbnRlYCB2cy4gYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCwgZWwgNS42MiUgZGUgbG9zIHBhY2llbnRlcyBkZSBzZXhvIG1hc2N1bGlubyBhc2lzdGnDsyBhIHNlcnZpY2lvcyBwcml2YWRvcywgbWllbnRyYXMgcXVlIGVsIDcuOTUlIGRlIGxhcyBtdWplcmVzIGhpem8gbG8gbWlzbW87IGFkZW3DoXMsIHNlZ8O6biBsYSBtaXNtYSBtYXRyaXogcGVybyBjb25kaWNpb25hZGEgcG9yIGNvbHVtbmFzLCBkZWwgdG90YWwgZGUgcGFjaWVudGVzIHF1ZSBhc2lzdGnDsyBhIHNlcnZpY2lvcyBwcml2YWRvcywgZWwgNDYuMTUlIGZ1ZXJvbiBtdWplcmVzIHkgZWwgNTMuODUlIGhvbWJyZXMuIFBvciDDumx0aW1vLCBzZWfDum4gbGEgbWF0cml6IGRlIGZyZWN1ZW5jaWFzIENQRiBkZSBgdXNvX3N1c3RhbmNpYXNfcHNpY29hdGl2YXNgIHZzLiBgYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2FgLCBzb2xvIGVsIDQuNDIlIGRlIGxvcyBwYWNpZW50ZXMgcXVlIG5vIHJlcG9ydGFyb24gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzIGFzaXN0aWVyb24gYSBzZXJ2aWNpb3MgcMO6YmxpY29zLCBtaWVudHJhcyBxdWUgZWwgMjMuNzQlIGRlIGxvcyBwYWNpZW50ZXMgcXVlIHJlcG9ydGFyb24gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzIGFzaXN0aWVyb24gYSBzZXJ2aWNpb3MgcHJpdmFkb3MuIENvbXBsZW1lbnRhcmlhbWVudGUsIHNlZ8O6biBsYSBtaXNtYSBtYXRyaXogcGVybyBjb25kaWNpb25hZGEgcG9yIGNvbHVtbmFzLCBlbCAxMy4zMyUgZGVsIHRvdGFsIGRlIHBhY2llbnRlcyBxdWUgYXNpc3RpZXJvbiBhIHNlcnZpY2lvcyBww7pibGljb3Mgbm8gcmVwb3J0YXJvbiBlbCB1c28gZGUgc3VzdGFuY2lhcyBwc2ljb2FjdGl2YXMsIG1pZW50cmFzIHF1ZSBlbCA4Ni42NyUgc8OtIGxvIGhpem8uDQoNCkNvbiBiYXNlIGVuIGxhcyBtYXRyaWNlcyBkZSBmcmVjdWVuY2lhcyBzZSBlbnRpZW5kZW4gbG9zIHBlcmZpbGVzIGNvbmRpY2lvbmFkb3MgcG9yIGZpbGFzIHkgY29sdW1uYXMgcXVlIHNlIGV4aGliZW4gZW4gbGEgc3VicGVzdGHDsWEgKipQZXJmaWxlcyBbQ1BGIHkgQ1BDXSoqLiBMb3MgZ3LDoWZpY29zIGRlIHBlcmZpbGVzIHNlIG11ZXN0cmFuIGVuIGVsIG1pc21vIG9yZGVuIGRlIGxvcyBvYmpldG9zIGFudGVyaW9ybWVudGUgZGVzY3JpdG9zLiBTaW4gZW1iYXJnbywgZW4gbG9zIGdyw6FmaWNvcyBkZSBwZXJmaWxlcyBzZSBwdWVkZW4gY290ZWphciBsYXMgcHJvcG9yY2lvbmVzIGNvbnRyYSB1biBpbmRpdmlkdW8gcHJvbWVkaW8gbyB1biBwZXJmaWwgcHJvbWVkaW8sIGV0aXF1ZXRhZG8gY29uIGBtYXJnYC4gRW4gZXN0ZSBzZW50aWRvLCBsb3MgcGVyZmlsZXMgZmlsYSB5IGNvbHVtbmEgcXVlIGNvcnJlc3BvbmRlbiBjb24gbGFzIHZhcmlhYmxlcyBgZ2VuZXJvX2RlbF9wYWNpZW50ZWAgeSBgdXNvX3N1c3RhbmNpYXNfcHNpY29hdGl2YXNgIG11ZXN0cmFuIGRpc3RyaWJ1Y2lvbmVzIG1hcmdpbmFsZXMgY2VyY2FuYXMgZW50cmUgc8OtOyBlcyBkZWNpciwgc2kgc29uIGNhbGN1bGFkYXMgbGFzIHByb3BvcmNpb25lcyB0b3RhbGVzIHNlcsOhbiBhcHJveGltYWRhbWVudGUgaWd1YWxlcywgcG9yIGVqZW1wbG86IChwZXJmaWxlcyBmaWxhKSBsYXMgcHJvcG9yY2lvbmVzIGRlIHBhY2llbnRlcyBkZSBzZXhvIG1hc2N1bGlubyB5IGZlbWVuaW5vIHF1ZSBubyByZXBvcnRhcm9uIGVsIHVzbyBkZSBzdXN0YW5jaWFzIHBzaWNvYWN0aXZhcyBmdWVyb24sIHJlc3BlY3RpdmFtZW50ZSwgNDQuMTglIHkgNDcuMDIlOyB0YW1iacOpbiwgKHBlcmZpbGVzIGNvbHVtbmEpIGxhIHByb3BvcmNpw7NuIGRlIHBhY2llbnRlcyBkZSBzZXhvIGZlbWVuaW5vIHF1ZSByZXBvcnRhcm9uIG8gbm8gZWwgdXNvIGRlIHN1c3RhbmNpYXMgcHNpY29hY3RpdmFzIGZ1ZXJvbiwgcmVzcGVjdGl2YW1lbnRlLCAzNi41MyUgeSAzOS4yMyUuIEFzaW1pc21vLCBsb3MgcGVyZmlsZXMgZmlsYSB5IGNvbHVtbmEgcXVlIGNvcnJlc3BvbmRlbiBjb24gbGFzIHZhcmlhYmxlcyBgZ2VuZXJvX2RlbF9wYWNpZW50ZWAgeSBgYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2FgIG11ZXN0cmFuIGRpc3RyaWJ1Y2lvbmVzIG1hcmdpbmFsZXMgY2VyY2FuYXMgZW50cmUgc8OtLCBwb3IgZWplbXBsbzogKHBlcmZpbGVzIGZpbGEpIGxhcyBwcm9wb3JjaW9uZXMgZGUgcGFjaWVudGVzIGRlIHNleG8gbWFzY3VsaW5vIHkgZmVtZW5pbm8gcXVlIGFzaXN0aWVyb24gYSBzZXJ2aWNpb3MgcMO6YmxpY29zIGZ1ZXJvbiwgcmVzcGVjdGl2YW1lbnRlLCAzMi4xMyUgeSAzNS4xMCU7IHRhbWJpw6luLCAocGVyZmlsZXMgY29sdW1uYSkgbGEgcHJvcG9yY2nDs24gZGUgcGFjaWVudGVzIGRlIHNleG8gZmVtZW5pbm8gcXVlIGFzaXN0aWVyb24gYSBzZXJ2aWNpb3MgcMO6YmxpY29zLCBwcml2YWRvcyB5IG1peHRvcyBmdWVyb24sIHJlc3BlY3RpdmFtZW50ZSwgMzguMzMlLCAzOS44NSUgeSAzOC4zMiUuIFBvciDDumx0aW1vLCBsb3MgcGVyZmlsZXMgZmlsYSB5IGNvbHVtbmEgcXVlIGNvcnJlc3BvbmRlbiBjb24gbGFzIHZhcmlhYmxlcyBgdXNvX3N1c3RhbmNpYXNfcHNpY29hdGl2YXNgIHkgYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCBtdWVzdHJhbiBkaXN0cmlidWNpb25lcyBtYXJnaW5hbGVzIGxlamFuYXMgZW50cmUgc8OtLCBwb3IgZWplbXBsbzogKHBlcmZpbGVzIGZpbGEpIGxhcyBwcm9wb3JjaW9uZXMgZGUgcGFjaWVudGVzIHF1ZSBubyByZXBvcnRhcm9uIGVsIHVzbyBkZSBzdXN0YW5jaWFzIHBzaWNvYWN0aXZhcyB5IHF1ZSBhc2lzdGllcm9uIGEgc2VydmljaW9zIHDDumJsaWNvcyBmdWVyb246IDQuNDIlIHkgMjMuNzQlOyB0YW1iacOpbiwgKHBlcmZpbGVzIGNvbHVtbmEpIGxhIHByb3BvcmNpw7NuIGRlIHBhY2llbnRlcyBxdWUgcmVwb3J0YXJvbiBlbCB1c28gZGUgc3VzdGFuY2lhcyBwc2ljb2FjdGl2YXMgcGFyYSBhc2lzdGlyIGEgc2VydmljaW9zIHDDumJsaWNvcywgcHJpdmFkb3MgeSBtaXh0b3MgZnVlcm9uLCByZXNwZWN0aXZhbWVudGUsIDg2LjY3JSwgNTMuMzglIHkgMjkuOTElLg0KDQpDb24gYmFzZSBlbiBsYXMgZGVzY3JpcGNpb25lcyBoZWNoYXMgZXMgcG9zaWJsZSBhbnRpY2lwYXIgcXVlIGxvcyBwYXJlcyBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIGBnZW5lcm9fZGVsX3BhY2llbnRlYCB2cy4gYHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzYCB5IGBnZW5lcm9fZGVsX3BhY2llbnRlYCB2cy4gYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCBzZWFuIGluZGVwZW5kaWVudGVzLiBFc3RlIGp1aWNpbyBzZSBhcG95YSBlbiBsb3MgcmVzdWx0YWRvcyBkZSBsYXMgcHJ1ZWJhcyBkZSBoaXDDs3Rlc2lzIHZpc3VhbGl6YWRhcyBhIHRyYXbDqXMgZGUgbGEgc3ViLXBlc3Rhw7FhIGhvbcOzbmltYS4gUGFyYSBlc3RhcyBwcnVlYmFzLCBhIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgzrEgPSAwLjA1LCBsYXMgaGlww7N0ZXNpcyBmb3JtdWxhZGFzIGZ1ZXJvbjoNCi0gaDA6IExhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHNvbiBpbmRlcGVuZGllbnRlcw0KLSBoMTogTGFzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgc29uIGRlcGVuZGllbnRlcw0KDQpBc2ltaXNtbywgZWwgcGFyIGRlIHZhcmlhYmxlcyBxdWUgdHV2aWVyb24gbGFzIHBydWViYXMgYSBmYXZvciBkZSBsYSBkZXBlbmRlbmNpYSBmdWVyb24gYHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzYCB5IGBhc2lzdGVuY2lhX3ByaXZhZGFfcHVibGljYWAsIGVuIGVzdGEgcHJ1ZWJhIGVsIHAtdmFsb3IgcmVzdWx0w7MgbWVub3IgbyBpZ3VhbCBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSB5LCBjb21wYXJhdGl2YW1lbnRlLCBlbCB2YWxvciBkZWwgZXN0YWTDrXN0aWNvIM+HMiBmdWUgZ3JhbmRlLiBQb3IgbG8gdGFudG8sIGVsIHBhciBkZSB2YXJpYWJsZXMgcXVlIGNvbnRpbnVhcm9uIGVuIGFuw6FsaXNpcyBmdWVyb24gZXN0YXMgw7psdGltYXMuDQoNCkEgdHJhdsOpcyBkZSBsYSBwZXN0YcOxYSAqKkFDIFBhcmVqYSDDmm5pY2EqKiBzZSBkZXNwbGllZ2FuIGxhcyBzdWItcGVzdGHDsWFzIHJlbGFjaW9uYWRhcyBjb24gbGEgY29udGludWFjacOzbiBkZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgZW50cmUgZWxsYXMuIEVuICoqQ29udGluZ2VuY2lhcyB5IFJlc2lkdWFsZXMgW1ItVVJdKiogKFI6IGB1c29fc3VzdGFuY2lhc19wc2ljb2F0aXZhc2AgeSBVUjogYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCkgc2UgcHVlZGVuIHZpc3VhbGl6YXIgbGFzIHRhYmxhcyBkZSBjb250aW5nZW5jaWFzLCB2YWxvcmVzIGVzcGVyYWRvcyB5IHJlc2lkdWFsZXMgZGUgbGEgcGFyZWphIGRlIHZhcmlhYmxlcyBlbiBjdXJzby4gUmVzcGVjdG8gZGUgbGFzIGRvcyBwcmltZXJhcywgZXMgdmlzdWFsaXphYmxlIHF1ZSBlbCByZWN1ZW50byBvYnNlcnZhZG8geSBlbCByZWN1ZW50byBlc3BlcmFkbyBiYWpvIGxhIGhpcMOzdGVzaXMgbnVsYSByZXNwZWN0byBkZSBjYWRhIHZhcmlhYmxlIHNvbiBsZWphbm9zIGVudHJlIHPDrSwgZW4gZXN0ZSBzZW50aWRvLCBsYSBkZXBlbmRlbmNpYSBlbnRyZSBsYXMgdmFyaWFibGVzIHNlIHJvYnVzdGVjZS4gIlJhbmdvX29ic2VydmFkbyIgc29uIGxvcyByZWN1ZW50b3MgYXNvY2lhZG9zIGNvbiBjYWRhIGNhdGVnb3LDrWEgZGUgZGF0b3MgeSAicmFuZ29fZXNwZXJhZG8iIHNvbiBsb3MgcmVjdWVudG9zDQoNCiBlc3BlcmFkb3MgcGFyYSBjYWRhIGNhdGVnb3LDrWEgYmFqbyBsYSBoaXDDs3Rlc2lzIG51bGEuIEFkZW3DoXMsIGVsIGFuw6FsaXNpcyBkZSByZXNpZHVvcyBkZSBQZWFyc29uIHkgZXN0YW5kYXJpemFkb3MgbXVlc3RyYSBxdWUgbGFzIG1heW9yZXMgZGVzdmlhY2lvbmVzIHJlc3BlY3RvIGEgbG9zIHZhbG9yZXMgZXNwZXJhZG9zIG9jdXJyZW4gZW50cmUgbGFzIGNhdGVnb3LDrWFzIGRlIHNlcnZpY2lvcyBww7pibGljb3MsIHByaXZhZG9zIHkgbWl4dG9zLiBBc2ltaXNtbywgZW4gbGEgc3ViLXBlc3Rhw7FhICoqQ29udHJpYnVjaW9uZXMgW1ItVVJdKiogcHVlZGUgYXByZWNpYXJzZSwgY29tZW50YWRvIGxvIGFudGVyaW9yLCBxdWUgZWwgdmFsb3IgbWl4dG8gZGUgbGEgdmFyaWFibGUgYGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhYCBjb250cmlidXllIHBvY28gZW4gbGEgZXhwbGljYWNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBkZWwgY29uanVudG8gZW4gY29tcGFyYWNpw7NuIGNvbiBsb3MgZGVtw6FzLg0KDQpQb3Igw7psdGltbywgZWwgcmVzdWx0YWRvIGRlZmluaXRpdm8gZGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZXMgc2UgbXVlc3RyYSBhIHRyYXbDqXMgZGUgbGEgc3ViLXBlc3Rhw7FhICoqQ29ycmVzcG9uZGVuY2lhIFNpbXBsZSBVbmlkaW1lbnNpb25hbCBbUi1VUl0qKi4gRW4gZXN0ZSBhcGFydGFkbyBzZSBlc3RhYmxlY2UgcXVlIHNvbG8gdW5hIGRpbWVuc2nDs24gYWJzb3JiZSB0b2RhIGxhIHZhcmlhYmlsaWRhZCBkZSBsYSBwYXJlamEsIHBvciBsbyBxdWUgbGEgcmVwcmVzZW50YWNpw7NuIGJpZGltZW5zaW9uYWwgZW4gZWwgcGxhbm8gZGUgZmFjdG9yZXMgZXMgaXJyZWFsaXphYmxlLiBTaW4gZW1iYXJnbywgZXMgcG9zaWJsZSBoYWNlciB1bmEgaW50ZXJwcmV0YWNpw7NuIHVuaWRpbWVuc2lvbmFsIGRlIGxvcyByZXN1bHRhZG9zLiBBbCBzZXIgcmVxdWVyaWRvcyBsYXMgdmFyaWFibGVzIGRlIHNvcG9ydGUgZGVsIEFDLCBwcmltZXJvIHBvciBjb2x1bW5hcyB5IGx1ZWdvIHBvciBmaWxhcywgbGFzIGNvb3JkZW5hZGFzIHByb3llY3RhZGFzIGRlIGxhIHZhcmlhYmxlIGBhc2lzdGVuY2lhX3ByaXZhZGFfcHVibGljYWAgZW4gcmVsYWNpw7NuIGNvbiBsYXMgY2F0ZWdvcsOtYXMgZGUgc2VydmljaW9zIHDDumJsaWNvcyB5IHByaXZhZG9zIHNlIHByZXNlbnRhbiBkZWwgbGFkbyBwb3NpdGl2byBkZWwgZWplIGRpbWVuc2lvbmFsIGNyZWFuZG8gb3Bvc2ljaW9uZXMgYmluYXJpYXMgY29uLCByZXNwZWN0aXZhbWVudGUsIHNlcnZpY2lvcyBww7pibGljb3MgY29uIG1peHRvcyB5IHNlcnZpY2lvcyBwcml2YWRvcyBjb24gbWl4dG9zLCBtaWVudHJhcyBxdWUgbG9zIHNlcnZpY2lvcyBtaXh0b3Mgc2UgZW5jdWVudHJhbiB0w6ljbmljYW1lbnRlIGVuIGVsIGNlbnRybyBkZWwgZWplLiBBc8OtIG1pc21vLCBsb3MgdGlwb3MgZGUgc2VydmljaW9zIHDDumJsaWNvcywgcHJpdmFkb3MgeSBtaXh0b3Mgc29uIGxvcyBxdWUgbcOhcyBjb250cmlidXllbiBlbiBsYSBjb25maWd1cmFjacOzbiBkZSBsYSBkaW1lbnNpw7NuLCBkZSBudWV2byBxdWVkYW4gcmV6YWdhZGFzIGxhcyBjYXRlZ29yw61hcyBtaXh0YXMuIEFkZW3DoXMsIGVzIGRldGVybWluYW50ZSBxdWUgbGEgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24gYWxjYW5jZSBlbCBtw6F4aW1vIGNvbiBjYWRhIHVuYSBkZSBsYXMgdmFyaWFibGVzLiBVbiBjb21wb3J0YW1pZW50byBzZW1lamFudGUgYSBsbyBleHB1ZXN0byBwdWVkZSBhcHJlY2lhcnNlIGNvbiBsYSB2YXJpYWJsZSBmaWxhIGB1c29fc3VzdGFuY2lhc19wc2ljb2F0aXZhc2AsIHN1IGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuIGVzIG3DoXhpbWEsIGxhcyBjb29yZGVuYWRhcyBkZSBzdXMgY2F0ZWdvcsOtYXMgc2UgeXV4dGFwb25lbiBlbiBlbCBlamUgdW5pZGltZW5zaW9uYWwgeSBzdXMgY29udHJpYnVjaW9uZXMgc29uIGFwcm94aW1hZGFtZW50ZSBlcXVpbGlicmFkYXMuIERlIGxvIG1lbmNpb25hZG8gc2UgaW50ZXJwcmV0YSBxdWUgcHJlc2VudGFuIGFzb2NpYWNpw7NuIHJlbGV2YW50ZSwgcG9zaXRpdmEgbyBuZWdhdGl2YSwgZW50cmUgZmlsYXMgeSBjb2x1bW5hcywgbGFzIGNhdGVnb3LDrWFzIChkZSBsYXMgcmVzcGVjdGl2YXMgdmFyaWFibGVzKSBzZXJ2aWNpb3MgcMO6YmxpY29zIHkgcHJpdmFkb3MgY29uIHVzbyBkZSBzdXN0YW5jaWFzIHBzaWNvYWN0aXZhcywgeSBtaXh0b3MgY29uIG5vLXVzbyBkZSBzdXN0YW5jaWFzIHBzaWNvYWN0aXZhcy4NCg0KRGFkbyBxdWUgbGEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGJpZGltZW5zaW9uYWwgZnVlIGlycmVhbGl6YWJsZSwgc2UgcHJlc2VudGEgZW4gbGEgc2VjY2nDs24gMTIgZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcO6bHRpcGxlcyBwYXJhIGxvZ3JhcmxhLg0KDQojIyMgQUMgUGFyZWphcyBUb3RhbGVzDQoNCmFkZG1hcmdpbnModGFibGUoY2xpbmljX2RhdGFzZXQkZ2VuZXJvX2RlbF9wYWNpZW50ZSwgcmVnaXN0cm9zX2NsaW5pY29zJHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzKSkNCg0KIyMjIENvbnRpbmdlbmNpYXMNCg0KYWRkbWFyZ2lucyh0YWJsZShjbGluaWNfZGF0YXNldCRnZW5lcm9fZGVsX3BhY2llbnRlLCByZWdpc3Ryb3NfY2xpbmljb3MkYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2EpKQ0KDQphZGRtYXJnaW5zKHRhYmxlKGNsaW5pY19kYXRhc2V0JGdlbmVyb19kZWxfcGFjaWVudGUsIHJlZ2lzdHJvc19jbGluaWNvcyRlc3RyYXRvX3NvY2lvZWNvbm9taWNvKSkNCg0KYWRkbWFyZ2lucyh0YWJsZShjbGluaWNfZGF0YXNldCR1c29fc3VzdGFuY2lhc19wc2ljb2F0aXZhcywgcmVnaXN0cm9zX2NsaW5pY29zJGVzdHJhdG9fc29jaW9lY29ub21pY28pKQ0KDQojIyMgUHJvYmFiaWxpZGFkZXMNCg0KYWRkbWFyZ2lucyhwcm9wLnRhYmxlKHRhYmxlKGNsaW5pY19kYXRhc2V0JGdlbmVyb19kZWxfcGFjaWVudGUsIHJlZ2lzdHJvc19jbGluaWNvcyR1c29fc3VzdGFuY2lhc19wc2ljb2F0aXZhcykpICogMTAwKQ0KDQphZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoY2xpbmljX2RhdGFzZXQkZ2VuZXJvX2RlbF9wYWNpZW50ZSwgcmVnaXN0cm9zX2NsaW5pY29zJGVzdHJhdG9fc29jaW9lY29ub21pY28pKSAqIDEwMCkNCg0KYWRkbWFyZ2lucyhwcm9wLnRhYmxlKHRhYmxlKGNsaW5pY19kYXRhc2V0JHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzLCBSZWdpc3Ryb3NfQ2xpbmljb3MkcmVzaWRlbmNpYV9jZXJjYV9hbF9jZW50cm8pKSAqIDEwMA0KDQojIyMgRnJlY3VlbmNpYXMgW0NQRiB5IENQQ10NCg0Kcm91bmQoYWRkbWFyZ2lucyhwcm9wLnRhYmxlKHRhYmxlKGNsaW5pY19kYXRhc2V0JGdlbmVyb19kZWxfcGFjaWVudGUsIHJlZ2lzdHJvc19jbGluaWNvcyRhc2lzdGVuY2lhX3ByaXZhZGFfcHVibGljYSksIDEpKjEwMCwgMiksIDIpDQoNCnJvdW5kKGFkZG1hcmdpbnMocHJvcC50YWJsZSh0YWJsZShjbGluaWNfZGF0YXNldCRnZW5lcm9fZGVsX3BhY2llbnRlLCByZWdpc3Ryb3NfY2xpbmljb3MkYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2EpLCAyKSoxMDAsIDEpLCAyKQ0KDQpyb3VuZChhZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoY2xpbmljX2RhdGFzZXQkZ2VuZXJvX2RlbF9wYWNpZW50ZSwgcmVnaXN0cm9zX2NsaW5pY29zJGVzdHJhdG9fc29jaW9lY29ub21pY28pLCAxKSoxMDAsIDIpLCAyKQ0KDQpyb3VuZChhZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoY2xpbmljX2RhdGFzZXQkZ2VuZXJvX2RlbF9wYWNpZW50ZSwgcmVnaXN0cm9zX2NsaW5pY29zJGVzdHJhdG9fc29jaW9lY29ub21pY28pLCAyKSoxMDAsIDEpLCAyKQ0KDQpyb3VuZChhZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoY2xpbmljX2RhdGFzZXQkYXNpc3RlbmNpYV9wcml2YWRhX3B1YmxpY2EsIHJlZ2lzdHJvc19jbGluaWNvcyRlc3RyYXRvX3NvY2lvZWNvbm9taWNvKSwgMSkqMTAwLCAyKSwgMikNCg0Kcm91bmQoYWRkbWFyZ2lucyhwcm9wLnRhYmxlKHRhYmxlKGNsaW5pY19kYXRhc2V0JGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhLCByZWdpc3Ryb3NfY2xpbmljb3MkZXN0cmF0b19zb2Npb2Vjb25vbWljbyksIDIpKjEwMCwgMSksIDIpDQoNCiMjIyBwZXJmaWxlcyBbQ1BGIHkgQ1BDXQ0KDQpwbG90Y3QodGFibGUoY2xpbmljX2RhdGFzZXQkZ2VuZXJvX2RlbF9wYWNpZW50ZSwgUmVnaXN0cm9zX0NsaW5pY29zJHVzb19zdXN0YW5jaWFzX3BzaWNvYXRpdmFzKSwicm93IikNCg0KcGxvdGN0KHRhYmxlKGNsaW5pY19kYXRhc2V0JGdlbmVyb19kZWxfcGFjaWVudGUsIFJlZ2lzdHJvc19DbGluaWNvcyR1c29fc3VzdGFuY2lhc19wc2ljb2F0aXZhcyksImNvbCIpDQoNCnBsb3RjdCh0YWJsZShjbGluaWNfZGF0YXNldCRnZW5lcm9fZGVsX3BhY2llbnRlLCBSZWdpc3Ryb3NfQ2xpbmljb3MkZXN0cmF0b19zb2Npb2Vjb25vbWljbyksInJvdyIpDQoNCnBsb3RjdCh0YWJsZShjbGluaWNfZGF0YXNldCRnZW5lcm9fZGVsX3BhY2llbnRlLCBSZWdpc3Ryb3NfQ2xpbmljb3MkZXN0cmF0b19zb2Npb2Vjb25vbWljbyksImNvbCIpDQoNCnBsb3RjdCh0YWJsZShjbGluaWNfZGF0YXNldCR1c29fc3VzdGFuY2lhc19wc2ljb2FjdGl2YXMsIFJlZ2lzdHJvc19DbGluaWNvcyRyZXNpZGVuY2lhX2NlcmNhX2FsX2NlbnRybyksInJvdyIpDQoNCnBsb3RjdCh0YWJsZShjbGluaWNfZGF0YXNldCR1c29fc3VzdGFuY2lhc19wc2ljb2FjdGl2YXMsIFJlZ2lzdHJvc19DbGluaWNvcyRyZXNpZGVuY2lhX2NlcmNhX2FsX2NlbnRybyksImNvbCIpDQoNCg0KIyMjIHBydWViYSBkZSBoaXBvdGVzaXMNCg0KY2hpc3EudGVzdCh0YWJsZShjbGluaWNfZGF0YXNldCRnZW5lcm9fZGVsX3BhY2llbnRlLCBSZWdpc3Ryb3NfQ2xpbmljb3MkdXNvX3N1c3RhbmNpYXNfcHNpY29hY3RpdmFzKSkNCg0KY2hpc3EudGVzdCh0YWJsZShjbGluaWNfZGF0YXNldCRnZW5lcm9fZGVsX3BhY2llbnRlLCBSZWdpc3Ryb3NfQ2xpbmljb3MkZXN0cmF0b19zb2Npb2Vjb25vbWljbykpDQoNCmNoaXNxLnRlc3QodGFibGUoY2xpbmljX2RhdGFzZXQkdXNvX3N1c3RhbmNpYXNfcHNpY29hY3RpdmFzLCBSZWdpc3Ryb3NfQ2xpbmljb3MkcmVzaWRlbmNpYV9jZXJjYV9hbF9jZW50cm8pKQ0KDQojIyBjb3JyZXNwb25kZW5jaWFzIG11bHRpcGxlcw0KDQpSZWN1cGVyYW5kbyBkZSBudWV2byBlbCB0cmFiYWpvIGRlICggRMOtYXogTW9yYWxlcyAmIE1vcmFsZXMgUml2ZXJhLCAyMDEyICkgc2UgZGljZSBxdWUgZWwgQUNTIHNlIHB1ZWRlIGV4dGVuZGVyIGRlc2RlIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgaGFjaWEgdGFibGFzIGRpc3l1bnRpdmFzIGNvbXBsZXRhcy4gRW4gZXN0YXMgbGFzIGZpbGFzIHNvbiBsb3Mgb2JqZXRvcyBhIGxvcyBjdWFsZXMgc2UgbGVzIHJlZ2lzdHJhbiBjYXJhY3RlcsOtc3RpY2FzIGRlIGludGVyw6lzIGEgdHJhdsOpcyBkZSBsYXMgY29sdW1uYXMgcXVlIGNvbXBpbGFuIGxhcyBtb2RhbGlkYWRlcyBkZSBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBlc3R1ZGlhZGFzIGRlIGVsbG9zLiBBc8OtLCBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBtw7psdGlwbGVzIChBQ00pIGVzIGVsIEFDIGFwbGljYWRvIGEgdW5hIHRhYmxhIGRpc3l1bnRpdmEgY29tcGxldGEuIFBvciBsbyB0YW50bywgZW4gZWwgQUNNIHVuYSB2YXJpYWJsZSBjYXRlZ8OzcmljYSBhc2lnbmEgYSBjYWRhIG9iamV0byBkZSB1bmEgcG9ibGFjacOzbiB1bmEgbW9kYWxpZGFkIGEgdHJhdsOpcyBkZSBsYSBjdWFsIGxvcyBwYXJ0aWNpb25hIGV4Y2x1c2l2YSB5IGV4aGF1c3RpdmFtZW50ZS4NCg0KRXN0YSBzZWNjacOzbiBlcyBkZXNhcnJvbGxhZGEgY29tbyBhbHRlcm5hdGl2YSBkZSBjb21wbGV0aXR1ZCBkZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgc2ltcGxlcyBxdWUgZW4gbGEgc2VjY2nDs24gMTEgZnVlIGluYXByZWNpYWJsZSBkZWJpZG8gYSBsYSB1bmlkaW1lbnNpb25hbGlkYWQgZGUgbGEgcmVwcmVzZW50YWNpw7NuIGRlIGxvcyBkYXRvcyBhIG5pdmVsIGRlIHByb3llY2Npw7NuIGRlIGxhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHF1ZSBjdW1wbGllcm9uIGxhIGhpcMOzdGVzaXMgZGUgZGVwZW5kZW5jaWEuIFBvciBsbyB0YW50bywgZGVsIHRyYXRhbWllbnRvIGNvbmp1bnRvIGRlIHRvZGFzIGxhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHNlIGVzcGVyYSBvYnRlbmVyIHVuYSByZXByZXNlbnRhY2nDs24gZW4gZWwgcHJpbWVyIHBsYW5vIGZhY3RvcmlhbC4NCg0KIyMgUGxhbnRlYW1pZW50byBkZWwgUHJvYmxlbWENCg0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFsaXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvcyBlbiBsYSBzZWNjacOzbiAyIHNlIGV4aWdlIGRlc2Fycm9sbGFyIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIE3Dumx0aXBsZXMgcGFyYSBsb2dyYXIgdW5hIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBlbiBlbCBwcmltZXIgcGxhbm8gZmFjdG9yaWFsLCBkZWJpZG8gYSBsYSBpbXBvc2liaWxpZGFkIGRlIGxvZ3JhcmxvIGVuIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZS4NCg0KIyMgRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzDQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIHBlcm1pdGUgdmlzdWFsaXphciBvYmpldG9zIG1hdHJpY2lhbGVzIHkgZ3LDoWZpY29zIHF1ZSBheXVkYW4gYSBkZXNhcnJvbGxhciBlIGludGVycHJldGFyIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIG3Dumx0aXBsZXMgKEFDTSkgZW50cmUgbGFzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvcy4NCg0KTGEgcGVzdGHDsWEgQUNNIG11ZXN0cmEgbGEgbXVsdGlkaW1lbnNpb25hbGlkYWQgZXNwZXJhZGEsIGNvbXBhcmFkYSBjb24gbGEgdW5pZGltZW5zaW9uYWxpZGFkIGRlbCBBQ1MgZGUgbGEgc2VjY2nDs24gMTEsIGFsIHRyYWJhamFyIGNvbmp1bnRhbWVudGUgY29uIGxhcyB0cmVzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zOiBnZW5lcm9fZGVsX3BhY2llbnRlLCByZXNpZGVuY2lhX2NlcmNhX2FsX2NlbnRybyB5IGVzdHJhdG9fc29jaW9lY29uw7NtaWNvLiBNdWVzdHJhIGFkZW3DoXMgcXVlIGxhcyBkaW1lbnNpb25lcyBkZWwgcGxhbm8gcHJpbmNpcGFsIGV4cGxpY2FuIGVsIDQyLjE2JSBkZWwgY29uanVudG8gKHNlcsOhIHNvYnJlIGVzdGUgcGxhbm8gcXVlIHNlIGNvbnRpbnVhcsOhIGNvbiBsYXMgaW50ZXJwcmV0YWNpb25lcyBkZWwgQUNNKS4gQWRlbcOhcywgbGEgZXZpZGVudGUgYmFqYSBjb25jZW50cmFjacOzbiBkZSBhYnNvcmNpw7NuIGRlIHZhcmlhY2nDs24gcG9yIHBhcnRlIGRlIGFsZ3VuYSBvIGFsZ3VuYXMgZGltZW5zaW9uZXMgc2UgcmVmbGVqYXLDoSBlbiBsYXMgZGlzdGFuY2lhcyBlbnRyZSBsb3MgcGVyZmlsZXMgZGUgbGFzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMuDQoNCkVuIGxhIHBlc3Rhw7FhIEJpcGxvdCBBQ00gc2UgbXVlc3RyYW4gbGFzIHNlbWVqYW56YXMgZGUgcGVyZmlsZXMgZW50cmUgcGFjaWVudGVzIHJlcHJlc2VudGFkYXMgcG9yIHB1bnRvcyBhenVsZXMgc29icmVwdWVzdG9zIHF1ZSBpbmRpY2FuIGNvb3JkZW5hZGFzIGRlIGNvbnZlcmdlbmNpYSB5IGxhcyBhc29jaWFjaW9uZXMgZW50cmUgYWxndW5hcyBjYXRlZ29yw61hcyBkZSBsYXMgdmFyaWFibGVzIHkgY29uanVudG9zIGRlIHBhY2llbnRlcy4gQ2FiZSBhbm90YXIgcXVlIGxhcyBzZW1lamFuemFzIGVudHJlIGNhdGVnb3LDrWFzIGRlIGxhcyB2YXJpYWJsZXMgZXN0w6FuIHByZXNlbnRhZGFzIHBvciBzdXMgY29vcmRlbmFkYXMgcmVzcGVjdG8gZGUgbG9zIHNlbWllamVzIGRpbWVuc2lvbmFsZXMsIG3DoXMgcXVlIHBvciBzdXMgcHJveGltaWRhZGVzLCBlc3RvIGNvbmN1ZXJkYSBjb24gbG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIGVuIGxhIHNlY2Npw7NuIDExLiBQb3IgZWplbXBsbywgZW4gc2VtZWphbnphIGEgbml2ZWwgZGUgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcyBkZXN0YWNhbiBsb3MgZ3J1cG9zOiB1c29fc3VzdGFuY2lhc19wc2ljb2FjdGl2YXMsIGFzaXN0ZW5jaWFfcHJpdmFkYV9wdWJsaWNhLCB5IHJlc2lkZW5jaWFfY2VyY2FfYWxfY2VudHJvIHBvciB1biBsYWRvLCBwb3Igb3RybywgZ2VuZXJvX2RlbF9wYWNpZW50ZSB5IGVzdHJhdG9fc29jaW9lY29uw7NtaWNvLCBhc8OtIGNvbW8gY2llcnRvcyBncnVwb3MgZXZpZGVudGVzIGRlIHBhY2llbnRlcy4gQ29tcGxlbWVudGFyaWFtZW50ZSwgYSBuaXZlbCBkZSBhc29jaWFjacOzbiBzZSBkZXN0YWNhIGxhIGRlbCBncnVwbyBkZSBwYWNpZW50ZXMgY2VyY2FubyBhIHVzb19zdXN0YW5jaWFzX3BzaWNvYWN0aXZhcyB5IGxhIGRlIG90cm8gZ3J1cG8gbnV0cmlkbyBjZXJjYW5vIGEgZXN0cmF0b19zb2Npb2Vjb27Ds21pY28uIEVuIGdlbmVyYWwgc2UgcHVlZGVuIHZpc3VhbGl6YXIgZsOhY2lsbWVudGUgbGFzIGFzb2NpYWNpb25lcyBlbnRyZSBsYXMgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcyB5IGxvcyBncnVwb3MgZGUgcGFjaWVudGVzIGFmaW5lcyBjb24gZWxsYXMuDQoNClNlZ3VpZGFtZW50ZSwgbGEgcGVzdGHDsWEgQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24gbXVlc3RyYSBxdWUgbGFzIGNhdGVnb3LDrWFzIGRlIGxhIHZhcmlhYmxlIHJlc2lkZW5jaWFfY2VyY2FfYWxfY2VudHJvIGZ1ZXJvbiBsYXMgbWVqb3IgcmVwcmVzZW50YWRhcywgZW4gb3Bvc2ljacOzbiBhIGxhcyBjYXRlZ29yw61hcyBlZGFkZXMgeSBudW1lcm9fZGVfaGlqb3MuIEVsIHJlc3RvIHF1ZWTDsyBlbiB1biByYW5nbyBpbnRlcm1lZGlvLWFsdG8gZGUgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24uIENvbW8gbGEgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24gZW4gc3ViZXNwYWNpb3MgZGUgZGltZW5zacOzbiByZWR1Y2lkYSBzZSBtaWRlIGVuIHBvcmNlbnRhamVzIGRlIGluZXJjaWEgY29uIHJlc3BlY3RvIGEgbGEgdG90YWwgbGEgY2VyY2Fuw61hIGRlIHVuIHB1bnRvIGFsIG9yaWdlbiBkZWwgcGxhbm8gZmFjdG9yaWFsIGluZGljYSB1bmEgYmFqYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBlbiDDqWwsIHBvciBsbyB0YW50bywgbGEgY2F0ZWdvcsOtYSBudW1lcm9fZGVfaGlqb3MgbGEgcHJlc2VudGEuDQoNCiMjIyBBQ00NCg0Kcm91bmQoTUNBKGNsaW5pY19kYXRhc2V0WzE6NDAwLCAtYygxLCAzLCA0LCA1LCA2LCA3LCAxMCldLCBncmFwaCA9IEZBTFNFKSRlaWcsMikNCg0KIyMjIEFDTSBiaXBsb3QNCg0KZnZpel9tY2FfYmlwbG90KE1DQShjbGluaWNfZGF0YXNldFsxOjQwMCwgLWMoMSwgMywgNCwgNSwgNiwgNywgMTApXSwgZ3JhcGggPSBGQUxTRSksIHJlcGVsID0gVFJVRSkNCg0KIyMjIGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpb24NCg0KZnZpel9tY2FfdmFyKE1DQShjbGluaWNfZGF0YXNldFsxOjQwMCwgLWMoMSwgMywgNCwgNSwgNiwgNywgMTApXSwgZ3JhcGggPSBGQUxTRSksIGNvbC52YXIgPSJjb3MyIiwgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IiksIHJlcGVsID0gVFJVRSkNCg0KZnZpel9tY2FfdmFyKE1DQShjbGluaWNfRGF0YXNldF9Jbml0aWFsWzE6NDAwLCAtYygxLCAzLCA0LCA1LCA2LCA3LCAxMCldLCBncmFwaCA9IEZBTFNFKSR2YXIkY29zMg0KDQojIyMgQ29udHJpYnVjaW9uZXMNCg0KZnZpel9jb250cmliKE1DQShjbGluaWNfZGF0YXNldFsxOjQwMCwgLWMoMSwgMywgNCwgNSwgNiwgNywgMTApXSwgZ3JhcGggPSBGQUxTRSksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMSwNCg0KZnZpel9jb250cmliKE1DQShjbGluaWNfZGF0YXNldFsxOjQwMCwgLWMoMSwgMywgNCwgNSwgNiwgNywgMTApXSwgZ3JhcGggPSBGQUxTRSksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMiwgdG9wID0gMTUpDQoNCmZ2aXpfY29udHJpYihNQ0EoY2xpbmljX2RhdGFzZXRbLCAtYygxLCAzLCA0LCA1LCA2LCA3LCAxMCldLCBncmFwaCA9IEZBTFNFKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAzLCB0b3AgPSAxNSkNCg0KZnZpel9jb250cmliKE1DQShjbGluaWNfZGF0YXNldFssIGMoMSwgMywgNCwgNSwgNiwgNywgMTApXSwgZ3JhcGggPSBGQUxTRSksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNCwgdG9wID0gMTUpDQoNCmZ2aXpfY29udHJpYihNQ0EoY2xpbmljX2RhdGFzZXRbLCBjKDEsIDMsIDQsIDUsIDYsIDcsIDEwKV0sIGdyYXBoID0gRkFMU0UpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDE1KQ0KDQojIyMgQmlwbG90IGNvbiBjb250cmlidWNpb25lcw0KDQpmdml6X21jYV92YXJNQ0EoY2xpbmljX2RhdGFzZXRbLCBjKDEsIDMsIDQsIDUsIDYsIDcsIDEwKV0sIGdyYXBoID0gRkFMU0UpY29sLnZhciA9ICJjb250cmliIiwgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IiksIHJlcGVsID0gVFJVRSkNCg0KDQojIE9iamV0aXZvcyB5IGFub3RhY2lvbmVzIDo6RmFzZSA0IA0KDQojIyA0LjEuIE9iamV0aXZvcw0KRW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgbGEgY3VhcnRhIGV0YXBhIGRlIGVzdHVkaW8gbW9zdHJhcsOhIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcyBjb24gYmFzZSBlbiBlbCBjb25qdW50byBkZSBkYXRvcyB0cmF0YWRvcyBlbiBsYXMgZmFzZXMgMSAsIDIgeSAzICwgcGVybyBhaG9yYSBkZXNkZSB1biBlbmZvcXVlIGRlIGFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zIGVuIHZlcnNpw7NuIGplcsOhcnF1aWNhIChkZW5kb2dyYW1hcykgeSBuby0uIGplcsOhcnF1aWNhICggSyAtbWVkaWFzKS4NCg0KUmVjdcOpcmRlc2UgcXVlIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHRyYWJham8gZXN0w6EgZGVzY3JpdG8gZW4gbGEgc2VjY2nDs24gMiB5IGxvcyByZWZlcmVudGVzIHRlw7NyaWNvcyBlbiBsYSBzZWNjacOzbiAxIC4NCg0KUG9yIMO6bHRpbW8sIGVzdGUgdHJhYmFqbyBmdWUgcHJvY2VzYWRvIGNvbiBSIHZlcnNpw7NuIDQuMi4yICgyMDIyLTEwLTMxIHVjcnQpIG1lZGlhZG8gcG9yIFJTdHVkaW8gMjAyMi4xMi4wIEJ1aWxkIDM1MyBlbiB1bmEgcGxhdGFmb3JtYSB4ODZfNjQtdzY0LW1pbmd3MzIuIEFkZW3DoXMsIHBvciBzdSBuYXR1cmFsZXphIGRlIHB1YmxpY2FjacOzbiBlbiBsw61uZWEgeSBwYXJhIGN1bXBsaXIgY29uIGVsIHJlcXVpc2l0byB0ZW1wb3JhbCBkZSBlbnRyZWdhLCBzZSBhY3R1YWxpemFyw6EsIGNvbW8gbcOheGltbywgaGFzdGEgbGFzIDExOjU5IHBtIGRlbCBkb21pbmdvIDEyIGRlIG1hcnpvIGRlIDIwMjMuDQoNCiMjIEFncnVwYWNpb24gamVyYXJxdWljYQ0KDQpTZWfDum4gKCBEw61heiBNb3JhbGVzICYgTW9yYWxlcyBSaXZlcmEsIDIwMTIgKSAsIHF1aWVuZXMgY2l0YW4gZWwgdHJhYmFqbyBkZSBFdmVyaXR0IGRlIDE5ODAgdGl0dWxhZG8gQ2x1c3RlciBBbmFseXNpcywgbG9zIGNvbmdsb21lcmFkb3MgcHVlZGVuIGNvbmNlYmlyc2UgY29tbyByZWdpb25lcyBjb250aW51YXMgZGUgdW4gZXNwYWNpbyBxdWUgY29udGllbmVuIHVuYSByZWxhdGl2YW1lbnRlIGFsdGEgZGVuc2lkYWQgZGUgcHVudG9zLCBxdWUgYSBzdSB2ZXogZXN0w6FuIHNlcGFyYWRhcyBwb3IgcmVnaW9uZXMuICjCv2NvbnRpbnVhcz8pIHF1ZSBjb250aWVuZW4gdW5hIGRlbnNpZGFkIGRlIHB1bnRvcyByZWxhdGl2YW1lbnRlIGJhamEuIFBhcmEgY29uZm9ybWFyIHRhbGVzIHJlZ2lvbmVzIGRlIHB1bnRvcyBzZSBoYW4gcHJvcHVlc3RvLCBwb3IgZWplbXBsbywgbcOpdG9kb3MgamVyw6FycXVpY29zLiBFc3RvcyBpbmljaWFuIGNvbiBlbCBjw6FsY3VsbyBkZSBsYSBtYXRyaXogZGUgZGlzdGFuY2lhcyBlbnRyZSBsb3Mgb2JqZXRvcyB0cmF0YWRvcywgY29uIGxvcyBjdWFsZXMgc2UgY29uZm9ybWFuIGdydXBvcyBwb3IgYWdsb21lcmFjacOzbiBhIHRyYXbDqXMgZGUgZXRhcGFzIHF1ZSBlbXBpZXphbiBwb3IgY29uZ2xvbWVyYWRvcyB1bml0YXJpb3MgKGVsIGNhc28gdHJpdmlhbCBpbmljaWFsLCBjb21vIHRhbWJpw6luIGVsIGNhc28gdHJpdmlhbCBmaW5hbDogdW4gY29uZ2xvbWVyYWRvIHRvdGFsKS4gRW50cmUgbGFzIG9wY2lvbmVzIHJlc3RhbnRlcyBzZSBwcmVzZW50YW4gZnVzaW9uZXMgeSBkaXZpc2lvbmVzIGRlIGdydXBvcyBxdWUgZXNwZWNpZmljYW4gamVyYXJxdcOtYXMgcG9yIHNpbWlsaXR1ZGVzIHF1ZSBwZXJtaXRlbiB1bmEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGNvbm9jaWRhIGNvbW8gZGVuZG9ncmFtYS4NCg0KIyMgUGxhbnRlYW1pZW50byBkZWwgcHJvYmxlbWENCg0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0b3MgZW4gbGEgc2VjY2nDs24gMiBzZSBleGlnZSBkZXNhcnJvbGxhciBlbCBhbsOhbGlzaXMgZGUgY29uZ2xvbWVyYWRvcyBjb24gYmFzZSBhZ3J1cGFjaW9uZXMgamVyw6FycXVpY2FzIHF1ZSBzZSByZXByZXNlbnRhbiBjb24gZGVuZG9ncmFtYXMsIGVzdG8gaW1wbGljYSBjbGFzaWZpY2FyIGEgbG9zIG9iamV0b3MgZGUgdHJhYmFqbyBjb24gbcOpdG9kb3MgYWdsb21lcmF0aXZvcyBkZWwgdmVjaW5vIG3DoXMgY2VyY2FubywgbcOhcyBsZWphbm8uIHkgZGUgbGEgdW5pw7NuIG1lZGlhbnRlIGVsIHByb21lZGlvLCBzb3BvcnRhZG9zIGVuIGxhIGRpc3RhbmNpYSBldWNsaWRpYW5hLg0KDQojIyBEZXNhcnJvbGxvIGRlbCBhbsOhbGlzaXMNCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgcGVybWl0ZSB2aXN1YWxpemFyIG9iamV0b3MgbWF0cmljaWFsZXMgeSBncsOhZmljb3MgcXVlIGF5dWRhbiBhIGRlc2Fycm9sbGFyIGUgaW50ZXJwcmV0YXIgZWwgYW7DoWxpc2lzIGRlIGNvbmdsb21lcmFkb3MgZW50cmUgbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0b3MgZW4gbGEgc2VjY2nDs24gMi4NCg0KQ29uIGVsIGZpbiBkZSB2aXN1YWxpemFyIGFkZWN1YWRhbWVudGUgbG9zIGRhdG9zLCB5IHNvbG8gY29uIHByb3DDs3NpdG9zIGFjYWTDqW1pY29zLCBlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBzZWNjacOzbiAyIGZ1ZSBtb2RpZmljYWRvIGRlIHRyZXMgbWFuZXJhcy4gUHJpbWVybywgc2UgbGUgYWdyZWfDsyB1bmEgdmFyaWFibGUgY2xhc2lmaWNhZG9yYSBjYXRlZ8OzcmljYTogTmFjaW9uYWxpZGFkLiBFc3RhIHZhcmlhYmxlIHNlIG9idHV2byBkZWwgSW5zdGl0dXRlIG9mIEludGVybmF0aW9uYWwgRWR1Y2F0aW9uIChJbnN0aXR1dG8gZGUgRWR1Y2FjacOzbiBJbnRlcm5hY2lvbmFsKSBwYXJhIHVuYSBmZWNoYSBlcXVpdmFsZW50ZSBhIGxhIGRlbCBjb25qdW50byBkZSBkYXRvcyBpbmljaWFsLiBMYSBtb2RpZmljYWNpw7NuIGNvbnNpc3Rpw7MgZW4gYWdyZWdhciB1biBjYW1wbyBxdWUgcmVnaXN0cmUgcGFyYSBjYWRhIHBhY2llbnRlIHN1IG5hY2lvbmFsaWRhZC4gQ29tbyBsYXMgcHJvcG9yY2lvbmVzIGRlIHBhcnRpY2lwYWNpw7NuIGRlIGxhcyBuYWNpb25hbGlkYWRlcyBkZSBsb3MgcGFjaWVudGVzIGZ1ZXJvbiBkaWZlcmVudGVzLCBwZXJvIGNvbm9jaWRhcywgZWwgbcOpdG9kbyBkZSBhc2lnbmFjacOzbiBmdWUgYWxlYXRvcmlvIHkgcG9uZGVyYWRvIGNvbiBiYXNlIGVuIGVsbGFzLiBDYWJlIG1lbmNpb25hciBxdWUgbGEgYXNpZ25hY2nDs24gc2UgaGl6byBkaXJlY3RhbWVudGUgZW4gZWwgbGlicm8gZGUgY8OhbGN1bG8uIEFkZW3DoXMsIGVsIGNhbXBvIE5hdGlvbmFsaXR5IHJlZ2lzdHJhIGp1bnRvIGNvbiBsYSBuYWNpb25hbGlkYWQgZGVsIHBhY2llbnRlIGxhIHBvc2ljacOzbiBxdWUgb2N1cGEgZGljaG8gcGHDrXMgY29tbyBhcG9ydGFudGUgZGUgcGFjaWVudGVzIGV4dHJhbmplcm9zIGVuIGVsIHBlcsOtb2RvIGRlIG1lZGljacOzbi4gU2VndW5kbywgc2UgZXN0YW5kYXJpemFyb24gZW4gdW5hIGVzY2FsYSB0b2RhcyBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMuIFBvciDDumx0aW1vLCBzZSBhcGxpY8OzIHVuIGZpbHRybyBhIGxvcyByZWdpc3Ryb3MgY29uIGJhc2UgZW4gbGEgdmFyaWFibGUgY2xhc2lmaWNhZG9yYSB5IHNlIGNhbGN1bGFyb24gbnVldm9zIHJlZ2lzdHJvcyBwcm9tZWRpbyBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMuIEFzw60sIGVsIGFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zIHNlIGhpem8gY29uIGJhc2UgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgbW9zdHJhZG9zIGVuIGxhIHBlc3Rhw7FhICJDb25qdW50byBNb2RpZmljYWRvIiwgbG8gcXVlIGluZGljYSBsb3MgcHJpbWVyb3MgcmVnaXN0cm9zIHkgbGEgZXN0cnVjdHVyYSBkZWwgY29uanVudG8uDQoNCkxhIHBlc3Rhw7FhICJEaXNpbWlsYXJpZGFkIiBtdWVzdHJhIHZpc3VhbG1lbnRlIGxvcyByZWdpc3Ryb3MgZGUgcHJveGltaWRhZCBlbnRyZSBsYXMgY2F0ZWdvcsOtYXMgZGUgbGEgdmFyaWFibGUgY2xhc2lmaWNhZG9yYSAiTmFjaW9uYWxpZGFkIi4gQ29uIGJhc2UgZW4gdW5hIGVzY2FsYSBkZSBjb2xvcmVzIHF1ZSBpbmRpY2EgbGFzIGRpc3RhbmNpYXMgZW50cmUgbGFzIG9ic2VydmFjaW9uZXMsIHB1ZWRlIG9ic2VydmFyc2UgcXVlIGNpZXJ0b3MgdmFsb3JlcyBlc3TDoW4gaW50ZW5zYW1lbnRlIGRpc3RhbnRlcyBkZWwgcmVzdG8uIFBvciBlamVtcGxvLCBhbGd1bm9zIHZhbG9yZXMgcG9kcsOtYW4gZXN0YXIgbcOhcyBhbGVqYWRvcyBkZWJpZG8gYSBkaWZlcmVuY2lhcyBlbiB2YXJpYWJsZXMgY29tbyBlZGFkLCBnw6luZXJvLCBvIGluZ3Jlc29zIG1lbnN1YWxlcy4gQXPDrSwgc2UgZXNwZXJhcsOtYSBxdWUgbG9zIHZhbG9yZXMgbWVuY2lvbmFkb3Mgc2UgYWdydXBhcmFuIGVudHJlIHPDrSBvIGZvcm1hcmFuIGdydXBvcyBkZSBqZXJhcnF1w61hcyBwcm9waWFzLCBjb24gZGlzdGFuY2lhcyBkZSBhZ2xvbWVyYWNpw7NuIGdyYW5kZXMgZW4gZWwgcGFzbyBjb3JyZXNwb25kaWVudGUuDQoNCkNvbXBsZW1lbnRhcmlhbWVudGUsIGxhIHBlc3Rhw7FhICJPcHRpbWl6YWNpw7NuIGRlIE1vamVuYSIgbXVlc3RyYSBzZXBhcmFkYW1lbnRlIGVsIG7Dum1lcm8gw7NwdGltbyBkZSBjb25nbG9tZXJhZG9zIGplcsOhcnF1aWNvcyBxdWUgZGViZW4gY29uZmlndXJhcnNlIGRlIHRhbCBmb3JtYSBxdWUgbGFzIGhldXLDrXN0aWNhcyB1c2FkYXMgZW50cmVnYXLDoW4gbG9zIG1lam9yZXMgcmVzdWx0YWRvcyBwb3NpYmxlcyBkZSBpbnRyYSBlIGludGVyIHNpbWlsYXJpZGFkLiBFbiBlc3RlIHNlbnRpZG8sIGxhIGVzdHJhdGVnaWEgZGVsIHZlY2lubyBtw6FzIGNlcmNhbm8gKFVuacOzbiBTaW1wbGUpIGVzdGFibGVjZSBxdWUgZXNlIG7Dum1lcm8gZXMgdHJlcywgbGEgZGVsIHZlY2lubyBtw6FzIGxlamFubyAodW5pw7NuIGNvbXBsZXRhKSBkaWN0YSBxdWUgdGFtYmnDqW4gZXMgdHJlcyB5IGxhIGRlIFVuacOzbiBQcm9tZWRpbyBtdWVzdHJhIHF1ZSBlcyBjdWF0cm8sIGEgY2FkYSB1bmEgZGUgZXN0YXMgY2FudGlkYWRlcyBkZSBjb25nbG9tZXJhZG9zIHNlIGxlIGFzb2NpYXLDoSBzdSByZXNwZWN0aXZvIGRlbmRvZ3JhbWEuDQoNCkVmZWN0aXZhbWVudGUsIGVuIGxhIHBlc3Rhw7FhICJEZW5kb2dyYW1hcyBPcHRpbWl6YWRvcyIgc2UgYXZhbGFuIGdyw6FmaWNhbWVudGUgbGFzIG1lbmNpb25lcyBoZWNoYXMgZW4gZWwgcMOhcnJhZm8gc29icmUgRGlzaW1pbGFyaWRhZC4gQWRlbcOhcyBkZSB2ZXJpZmljYXIgY29uIG3DoXMgcHJlY2lzacOzbiBsYXMgYWx0dXJhcyBqZXLDoXJxdWljYXMsIGVuIHBhcnRpY3VsYXIgcGFyYSBlbCBFbmxhY2UgQ29tcGxldG8geSBlbCBFbmxhY2UgUHJvbWVkaW8sIGVuIGVzdG9zIGxvcyBuaXZlbGVzIGRlIHNpbWlsaXR1ZCBzb24gZsOhY2lsbWVudGUgYXByZWNpYWJsZXMgeSBlZmVjdGl2YW1lbnRlIGRlY2lzaXZvcyBzb2JyZSBsYSBjYW50aWRhZCBkZSBjb25nbG9tZXJhZG9zIMOzcHRpbW9zIHByZWNhbGN1bGFkb3MuIEVzIGRlY2lyLCBlbCBkZW5kb2dyYW1hIGRlIEVubGFjZSBTaW1wbGUgcXVlIHNlIGNyZcOzIGNvbiBiYXNlIGVuIHRyZXMgY29uZ2xvbWVyYWRvcyBwcmVzZW50YSBkaXN0YW5jaWFzIGRlIGFnbG9tZXJhY2nDs24gY2VyY2FuYXMgY29uIGxhIGhvcml6b250YWwgZGUgY29ydGUsIHkgZW4gZ2VuZXJhbCBlbnRyZSBvdHJvcyBuaXZlbGVzIGRlIHNpbWlsaXR1ZCwgZXN0byBoYWNlIHF1ZSBsb3MgY29uZ2xvbWVyYWRvcyBzZWFuIGRpZsOtY2lsbWVudGUgZGlzY2VybmlibGVzLiBDYXNvIGNvbnRyYXJpbyBvY3VycmUgY29uIGVsIEVubGFjZSBDb21wbGV0byB5IGVsIEVubGFjZSBQcm9tZWRpbyBlbiBsb3MgY3VhbGVzIGxhcyBkaXN0YW5jaWFzIGRlIGFnbG9tZXJhY2nDs24gc29uIGFsdGFzIHkgZmFjaWxpdGFuIGxhIGFwcmVjaWFjacOzbiBkZSBsb3MgY29uZ2xvbWVyYWRvcy4gRW4gYW1ib3MgY2Fzb3MsIHNlIGVudGllbmRlIHF1ZSBzaSBsb3MgZGVuZG9ncmFtYXMgc2UgY29ydGFuIG3DoXMgYXJyaWJhIGRlIGxvcyBuaXZlbGVzIHJlc3BlY3Rpdm9zIGRlIHNpbWlsaXR1ZCBpbmRpY2Fkb3MsIGVudG9uY2VzIHJlc3VsdGFyw61hbiBtZW5vcyBjb25nbG9tZXJhZG9zIGZpbmFsZXMsIGNvbiBuaXZlbGVzIGRlIHNpbWlsaXR1ZCBtYXlvcjsgb3B1ZXN0YW1lbnRlLCBzaSBmdWVyb24gY29ydGFkb3MgbcOhcyBhYmFqbywgZW50b25jZXMgbG9zIG5pdmVsZXMgZGUgc2ltaWxpdHVkIHNlcsOhbiBtZW5vcmVzLCBwZXJvIHNlIG9idGVuZHLDoW4gbcOhcyBjb25nbG9tZXJhZG9zIGZpbmFsZXMsIGRlIGFow60gZWwgY8OhbGN1bG8gZGVsIG7Dum1lcm8gw7NwdGltbyBkZSBjb25nbG9tZXJhZG9zLg0KDQojIyMgIENhbXBvIGNsYXNpZmljYWRvcg0KDQphcy5kYXRhLmZyYW1lKGNsaW5pY19kYXRhc2V0KVsxOjI0LC1jKDQsNSw2KV0NCg0KIyMjIENvbmp1bnRvIG1vZGlmaWNhZG8NCg0KaGVhZChhcy5kYXRhLmZyYW1lKGNsaW5pY19kYXRhc2V0KSkNCg0KIyMjIERpc2ltaWxhcmlkYWQNCg0KZGF0YV8gPSBhcy5kYXRhLmZyYW1lKGNsaW5pY19kYXRhc2V0KVssIC0xXSByb3duYW1lcyhkYXRhXykgPSB1bmNsYXNzKGNsaW5pY19kYXRhc2V0JGNvZGlnb19kZV9wYWNpZW50ZSkgZnZpel9kaXN0KGdldF9kaXN0KGRhdGFfLCBzdGFuZCA9IFRSVUUsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgZ3JhZGllbnQgPSBsaXN0KGxvdyA9ICIjMDBBRkJCIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICIjRkM0RTA3IikpDQoNCiMjIyBPcHRpbWl6YWNpw7NuIGRlIG1vamVuYQ0KDQpoY19zaW5nbGUgPSBoY2x1c3QoZ2V0X2Rpc3QoZGF0YV8sIHN0YW5kID0gVFJVRSwgbWV0aG9kID0gImV1Y2xpZGVhbiIpLCBtZXRob2QgPSAic2luZ2xlIikNCg0KbW9qZW5hID0gZnVuY3Rpb24oaGMpew0KICBuX2hkID0gbGVuZ3RoKGhjJGhlaWdodCkNCiAgYWxwX2cgPSAwIA0KICBhbHBoYSA9IGhjJGhlaWdodFtuX2hkOjFdDQogIGZvcihpIGluIDE6KG5faGQtMSkpew0KICAgIGFscF9nW2ldID0gbWVhbihhbHBoYVsobl9oZC1pKzEpOjFdKSArIDEuMjUgKiBzZChhbHBoYVsobl9oZC1pKzEpOjFdKQ0KICB9DQogIG5vZyA9IHN1bShhbHBfZyA8PSBhbHBoYVstbl9oZF0pICsgMQ0KICBwbG90KGFscGhhWy1uX2hkXSwgcGNoPTIwLCBjb2w9KGFscF9nID4gYWxwaGFbLW5faGRdKSArIDEsIA0KICAgICAgIG1haW4gPSBwYXN0ZSgiT3B0aW1hbCBudW1iZXIgb2YgZ3JvdXBzID0iLCBub2cpLA0KICAgICAgIHlsYWIgPSBleHByZXNzaW9uKGFscGhhW2ddKSwgeGxhYiA9ICJOb2RlcyIpfQ0KDQptb2plbmEoaGNfc2luZ2xlKQ0KDQojIyMgRGVuZG9ncmFtYXMgb3B0aW1pemFkb3MNCg0Kc3VwcHJlc3NXYXJuaW5ncyhmdml6X2RlbmQoaGNfc2luZ2xlLCBrID0gMywgY2V4ID0gMC41LCBrX2NvbG9ycyA9ICJucGciLCBjb2xvcl9sYWJlbHNfYnlfayA9IFRSVUUsIHJlY3QgPSBUUlVFKSkNCg0KIyMjIEVubGFjZXMgc2VuY2lsbG9zDQoNCnN1cHByZXNzV2FybmluZ3MoZnZpel9kZW5kKGhjX3NpbmdsZSwgayA9IDMsIGNleCA9IDAuNSwga19jb2xvcnMgPSAibnBnIixjb2xvcl9sYWJlbHNfYnlfayA9IFRSVUUsIHJlY3QgPSBUUlVFKSkNCg0KIyMjIEVubGFjZSBjb21wbGV0bw0KDQpmdml6X2RlbmQoaGNfY29tcGxldGUsIGsgPSAzLCBjZXggPSAwLjUsIGtfY29sb3JzID0gIm5wZyIsIGNvbG9yX2xhYmVsc19ieV9rID0gVFJVRSwgcmVjdCA9IFRSVUUpDQoNCiMjIyBFbmxhY2UgcHJvbWVkaW8NCg0KZnZpel9kZW5kKGhjX2F2ZXJhZ2UsIGsgPSA0LCBjZXggPSAwLjUsIGtfY29sb3JzID0gIm5wZyIsIGNvbG9yX2xhYmVsc19ieV9rID0gVFJVRSwgcmVjdCA9IFRSVUUpDQoNCiMjIEFncnVwYWNpb24gbm8gamVyw6FycXVpY2ENCg0KRW4gZWwgdHJhYmFqbyBkZSAoIETDrWF6IE1vcmFsZXMgJiBNb3JhbGVzIFJpdmVyYSwgMjAxMiApIHNlIGVzdGFibGVjZSBxdWUsIGVuIHTDqXJtaW5vcyBnZW5lcmFsZXMsIGxvcyBtw6l0b2RvcyBkZSBhZ2xvbWVyYWNpw7NuIG5vLWplcsOhcnF1aWNvcyAobyBkZSBwYXJ0aWNpw7NuKSBzZSBpbXBsZW1lbnRhbiBjb24gYmFzZSBlbiBsYSBkZXRlcm1pbmFjacOzbiBpbmljaWFsIGRlIGFsZ3VuYSBwYXJ0aWNpw7NuIGRlbCBjb25qdW50byBkZSBkYXRvcywgcXVlICwgZXZpZGVudGVtZW50ZSwgZ2VuZXJhIHN1YmNvbmp1bnRvcyBkZSBkYXRvcywgZXMgZGVjaXIsIG90cmFzIHBhcnRpY2lvbmVzIGEgbGFzIGN1YWxlcyBzZSBsZXMgY2FsY3VsYSBzdXMgcmVzcGVjdGl2b3MgY2VudHJvaWRlczsgbHVlZ28sIGxhcyBvYnNlcnZhY2lvbmVzIHNlIHZpbmN1bGFuIGNvbiBlbCBjb25nbG9tZXJhZG8gY3V5byBjZW50cm9pZGUgZXN0w6kgbcOhcyBjZXJjYW5vIHBhcmEgY2FsY3VsYXIgZGUgbnVldm8gZWwgY2VudHJvaWRlIGRlIGxvcyBjb25nbG9tZXJhZG9zIHkgc2UgaGFjZW4gY29tcGFyYWNpb25lcyB2b3JhY2VzLCBwYXJhIGNvbnRpbnVhciByZWN1cnNpdmFtZW50ZSBoYXN0YSBxdWUgbGFzIG9ic2VydmFjaW9uZXMgc2VhbiBpcnJlbW92aWJsZXMgZGUgc3VzIHJlc3BlY3RpdmFzIHBhcnRpY2lvbmVzLiBBc8OtLCBjb250cmFyaW8gYSBsb3MgbcOpdG9kb3MgamVyw6FycXVpY29zLCBsYSB1YmljYWNpw7NuIGRlIHVuYSBvYnNlcnZhY2nDs24gZW4gdW4gY29uZ2xvbWVyYWRvIHB1ZWRlIHZhcmlhci4NCg0KRWwgbcOpdG9kbyBuby1qZXLDoXJxdWljbyBjb24gZWwgcXVlIHNlIGNlcnJhcsOhIGVsIGVzdHVkaW8gZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGNvbiBlbCBxdWUgc2UgaGEgdHJhYmFqYWRvIGhhc3RhIGFob3JhIGVzIGVsIGRlIEsgLW1lZGlhcy4gRXN0ZSBwYXJ0aWNpb25hIHVuIGNvbmp1bnRvIGRlIG9iamV0b3MgZW4gZ3J1cG9zLCBsbyBoYWNlIGFsIGVsZWdpciBsb3MgY2VudHJvaWRlcyBkZSBsb3MgZ3J1cG9zIHF1ZSBtaW5pbWl6YW4gbGEgZGlzdGFuY2lhIChldWNsaWRpYW5hKSBlbnRyZSBjYWRhIG9iamV0byB5IGVsbG9zLCBwYXJhIGFzaWduYXIsIGVuIGNvbnNlY3VlbmNpYSwgYSBjYWRhIGluZGl2aWR1byBhbCBjb25nbG9tZXJhZG8gY3V5byBjZW50cm9pZGUgZXN0w6kgbcOhcyBjZXJjYW5vIGEgw6lsLiBQb3IgbG8gdGFudG8sIGVsIG3DqXRvZG8gdGllbmUgY29tbyBvYmpldGl2byByZXViaWNhciBhIGxvcyBvYmpldG9zIGVuIGdydXBvcyB0YWxlcyBxdWUgcHJlc2VudGVuIGxhIG1lbm9yIHZhcmlhYmlsaWRhZCBwb3NpYmxlLg0KDQojIyBQbGFudGVhbWllbnRvIGRlbCBwcm9ibGVtYQ0KDQpDb24gYmFzZSBlbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvcyBlbiBsYSBzZWNjacOzbiAyIHNlIGRlbWFuZGEgZGVzYXJyb2xsYXIgZWwgYW7DoWxpc2lzIGRlIGNvbmdsb21lcmFkb3MgY29uIGJhc2UgYWdydXBhY2lvbmVzIG5vLWplcsOhcnF1aWNhcyBhIHRyYXbDqXMgZGVsIG3DqXRvZG8gZGUgbGFzIEsgLW1lZGlhcyB5IGxhIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkaWZlcmVuY2lhZGEgZGUgbGFzIGFncnVwYWNpb25lcyBjb24gYmFzZSBlbiBjw7NkaWdvcyBkZSBjb2xvcmVzLg0KDQojIyBEZXNhcnJvbGxvIGRlbCBhbsOhbGlzaXMNCg0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgcGVybWl0ZSB2aXN1YWxpemFyIG9iamV0b3MgbWF0cmljaWFsZXMgeSBncsOhZmljb3MgcXVlIGF5dWRhbiBhIGRlc2Fycm9sbGFyIGUgaW50ZXJwcmV0YXIgZWwgYW7DoWxpc2lzIGRlIGNvbmdsb21lcmFkb3MgZW50cmUgbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0b3MgZW4gbGEgc2VjY2nDs24gMi4NCg0KQ29tbyBlbCBtw6l0b2RvIGRlIEstbWVkaWFzIHJlcXVpZXJlIGxhIGVzcGVjaWZpY2FjacOzbiBkZWwgbsO6bWVybyBkZSBjb25nbG9tZXJhZG9zIHF1ZSBzZSBnZW5lcmFyw6FuLCByZXN1bHRhIGluZGlzcGVuc2FibGUgZGV0ZXJtaW5hcmxvIHByZXZpYW1lbnRlIHkgcXVlIGFkZW3DoXMgc2VhIGVsIG1lam9yIHBvc2libGUuIEEgdHJhdsOpcyBkZSBsYSBwZXN0YcOxYSBLLcOzcHRpbW9zIHNlIGFjY2VkZSBhIGxhcyBzdWItcGVzdGHDsWFzIGRlIHJlc3VsdGFkbyBkZSBsb3MgY8OhbGN1bG9zIGRlIEstw7NwdGltb3MgY29uIGJhc2UgZW4gbG9zIG3DqXRvZG9zIGRlIGNvZG8gKEVsYm93KSwgc2lsdWV0YSAoU2lsaG91ZXR0ZSksIGJyZWNoYSAoR2FwKSB5IG1heW9yw61hIChNYWpvcml0eSBSdWxlKS4gRWwgcHJpbWVybywgYXl1ZMOzIGEgZXN0YWJsZWNlciBxdWUgZWwgbsO6bWVybyDDs3B0aW1vIGRlIGFncnVwYW1pZW50b3MgcXVlIG1pbmltaXphbiBsYSB2YXJpYWNpw7NuIHRvdGFsIGRlbnRybyBkZSBjYWRhIHVubyBkZSBsb3MgZ3J1cG9zIGVzIDMuIEVsIHNlZ3VuZG8sIGEgdHJhdsOpcyBkZSBsYSBjYWxpZGFkIGRlIGxvcyBhZ3J1cGFtaWVudG9zICh1bmEgc2lsdWV0YSBhbHRhKSwgY29tZXJjaWFsaXphIHF1ZSBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgYWdydXBhbWllbnRvcyBlcyAyLiBFbCB0ZXJjZXJvLCBjb24gYmFzZSBlbiBsYSBlc3RpbWFjacOzbiBkZSBsb3MgY29uZ2xvbWVyYWRvcyDDs3B0aW1vcyBxdWUgaGFjZW4gcXVlIHNlIG1heGltaWNlIGxhIGVzdGFkw61zdGljYSBkZSBicmVjaGEgZGUgdGFsIG1hbmVyYSBxdWUgbGEgZXN0cnVjdHVyYSBkZSBhZ3J1cGFtaWVudG8gZXN0w6EgbXV5IGxlam9zIGRlIHVuYSBkaXN0cmlidWNpw7NuIGFsZWF0b3JpYSB1bmlmb3JtZSBkZSBwdW50b3MsIGRldGVybWluYW5kbyBxdWUgdGFsIG7Dum1lcm8gw7NwdGltbyBmdWVzZSAxLiBQb3Igw7psdGltbywgZWwgY3VhcnRvIG3DqXRvZG8sIHF1ZSBzZSBiYXNhIGVuIGVsIGPDoWxjdWxvIGRlIDMwIMOtbmRpY2VzIHBhcmEgZGV0ZXJtaW5hciBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgY29uZ2xvbWVyYWRvcyBhbCB2YXJpYXIgdG9kYXMgbGFzIG1lZGlkYXMgZGUgbsO6bWVybyBkZSBjb25nbG9tZXJhZG9zLCBkZSBkaXN0YW5jaWEgeSBtw6l0b2RvcyBkZSBjb25nbG9tZXJhZG8sIGV4aWdlbnRlcyBxdWUgdGFsIG7Dum1lcm8gZXMgMi4gUG9yIGxvIHRhbnRvLCBsYSBjb250aW51YWNpw7NuIGRlbCBhbsOhbGlzaXMgZGUgY29uZ2xvbWVyYWRvcyBzZSBjb250aW51w7MgY29uIGxhIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkZSBsb3MgYWdydXBhbWllbnRvcyBiYXNhZG9zIOKAi+KAi2VuIGRvcyB5IHRyZXMgY29uZ2xvbWVyYWRvcy4gQXPDrSwgbGEgcGVzdGHDsWEgUmVzdWx0YWRvcyBLLW1lYW5zIG11ZXN0cmEgcGFyYSBuw7ptZXJvcyDDs3B0aW1vcyBkZSAzIHkgMiBhZ3J1cGFtaWVudG9zIGxhcyBjYW50aWRhZGVzIGRlIG9ic2VydmFjaW9uZXMsIGxhcyB1YmljYWNpb25lcyBkZSBsb3MgY2VudHJvaWRlcyBkZSBsb3MgY29uZ2xvbWVyYWRvcywgZWwgdmVjdG9yIGRlIGFncnVwYW1pZW50byB5IGxhIG1lZGlkYSBkZSBsYSBib25kYWQgZGUgbGEgY2xhc2lmaWNhY2nDs24gKGNvaGVzacOzbiBpbnRlcm5hIGNvbnRyYSBzZXBhcmFjacOzbiBleHRlcm5hKSwgcXVlLCBldmlkZW50ZW1lbnRlIGVzIG3DoXMgY2VyY2FubyBhIHVubyBwYXJhIGVsIGFncnVwYW1pZW50byBjb24gYmFzZSBlbiAzIGNvbmdsb21lcmFkb3MuDQoNClBvciDDumx0aW1vLCBsYSBwZXN0YcOxYSBHcsOhZmljb3MgSy1tZWFucyBleGhpYmUgbG9zIGNvbmdsb21lcmFkb3MgZW4gdMOpcm1pbm9zIGRlIDMgeSAyIChuw7ptZXJvIMOzcHRpbW8pIGdydXBvcyBlbiBlbCBwcmltZXIgcGxhbm8gZmFjdG9yaWFsIHF1ZSBleHBsaWNhIGVsIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSBsb3MgZGF0b3MuIEFsIGhhY2VyIGxhIHJlYXNpZ25hY2nDs24gZGUgMyBhIDIgY2VudHJvaWRlcyBzZSBhcHJlY2lhIHF1ZSBlbCBjb25nbG9tZXJhZG8gcXVlIGNvbnRpZW5lIGEgQ29sb21iaWEgc29sbyBhYnNvcmJlIGEgTWFsYXNpYSwgZXMgZGVjaXIgc29sbyBhdW1lbnRhIHVuYSBvYnNlcnZhY2nDs24sIGVuIGNvbXBhcmFjacOzbiBjb24gZWwgY29uZ2xvbWVyYWRvIHF1ZSBjb250aWVuZSBhIENoaW5hIHF1ZSBhYnNvcmJlIGEgdG9kbyBlbCBjb25nbG9tZXJhZG8gcXVlIGNvbnRpZW5lIGEgVHVycXXDrWEuIEFzw60sIHB1ZWRlIGFyZ3VtZW50YXJzZSBhIGZhdm9yIGRlbCBuw7ptZXJvIMOzcHRpbW8gZGUgY29uZ2xvbWVyYWRvcyBpZ3VhbCBhIDIsIHBvcnF1ZSBsYSByZWFzaWduYWNpw7NuIGRlIGNlbnRyb2lkZXMgc2UgcmVvcmllbnTDsyBhIG1lam9yYXIgbGEgY29oZXNpw7NuIGludGVybmEgY29uIGJhamEgcmVkdWNjacOzbiBkZSBzZXBhcmFjacOzbiBleHRlcm5hIGVudHJlIGRvcyBjb25nbG9tZXJhZG9zIHF1ZSBwcmVzZW50YWJhbiBtw6FzIGhvbW9nZW5laWRhZC4gU2luIGVtYmFyZ28sIGxhcyBjb21wYXJhY2lvbmVzIGVudHJlIGxvcyBtw6l0b2RvcyB0cmF0YWRvcywgamVyw6FycXVpY29zIHkgbm8tamVyw6FycXVpY29zLCBnZW5lcmFuIGVuIGRpZmVyZW50ZXMgY2FudGlkYWRlcyBkZSBncnVwb3Mgw7NwdGltb3MsIHBlcm8gYW1ib3MgbcOpdG9kb3MgY29pbmNpZGllcm9uIGVuIHF1ZSwgZW4gZ2VuZXJhbCwgSW5kb25lc2lhIHkgTmVwYWwgc29uIGNhc29zIHBvciB0cmF0YXIgY29uIG3DoXMgZGV0ZW5pbWllbnRvLCBwb3IgZWplbXBsbywgYSB0cmF2w6lzIGRlIG3DqXRvZG9zIHF1ZSBzb3BvcnRlbiBtZWpvciBsYSBhZmVjdGFjacOzbiBxdWUgcHJvdm9jYW4gdmFsb3JlcyBleHRyYcOxb3MsIHBvciBlamVtcGxvLCBlbCBtw6l0b2RvIGRlIEstbWVkaW9pZGVzLiANCg0KIyMjIEstw7NwdGltb3MgKGNvZG8pDQoNCmZ2aXpfbmJjbHVzdChjbGluaWNfZGF0YXNldCwga21lYW5zLCBtZXRob2QgPSAid3NzIikgKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAzLCBsaW5ldHlwZSA9IDIpDQoNCiMjIyBLLcOzcHRpbW9zIChzaWx1ZXRhKQ0KDQpmdml6X25iY2x1c3QoY2xpbmljX2RhdGFzZXQsIGttZWFucywgbWV0aG9kID0gInNpbGhvdWV0dGUiKQ0KDQojIyMgSy3Ds3B0aW1vcyAoZXN0YWRpc3RpY2FzIGRlIGJyZWNoYSkNCg0KZnZpel9uYmNsdXN0KGNsaW5pY19kYXRhc2V0LCBrbWVhbnMsIG1ldGhvZCA9ICJnYXBfc3RhdCIpDQoNCiMjIyBLLcOzcHRpbW9zIChSZWdsYSBkZSBsYSBtYXlvcsOtYSkNCg0Kc3VwcHJlc3NXYXJuaW5ncyhOYkNsdXN0KGRhdGEgPSBkYXRhXywgZGlzcyA9IE5VTEwsIGRpc3RhbmNlID0gImV1Y2xpZGVhbiIsIG1pbi5uYyA9IDIsIG1heC5uYyA9IDEwLCBtZXRob2QgPSAia21lYW5zIikkQmVzdC5uYykNCg0KIyMjIFJlc3VsdGFkb3MgSy1NZWRpYXMgKEstb3B0aW1vW3d3c10pDQoNCnNldC5zZWVkKDc4MDcyOClwcmludChrbWVhbnMoZGF0YV8sIDMsIG5zdGFydCA9IDI1KSkNCg0KIyMjIFJlc3VsdGFkb3MgSy1NZWRpYXMgKEstb3B0aW1vW3NpbF0pDQoNCnNldC5zZWVkKDc4MDcyOClwcmludChrbWVhbnMoZGF0YV8sIDIsIG5zdGFydCA9IDI1KSkNCg0KIyMjIEdyw6FmaWNvcyBLLU1lZGlhcyAoSy1vcHRpbW9bd3dzXSkNCg0KZnZpel9jbHVzdGVyKGttZWFuc19tb2RlbCwgZGF0YSA9IGRhdGFfLCBwYWxldHRlID0gYygiIzJFOUZERiIsICIjMDBBRkJCIiwgIiNFN0I4MDAiKSwgZWxsaXBzZS50eXBlID0gImV1Y2xpZCIsIHN0YXIucGxvdCA9IFRSVUUsIHJlcGVsID0gVFJVRSwgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKSkNCg0KIyMjIEdyw6FmaWNvcyBLLU1lZGlhcyAoSy1vcHRpbW9bc2lsXSkNCg0KZnZpel9jbHVzdGVyKGttZWFuc19tb2RlbCwgZGF0YSA9IGRhdGFfLCBwYWxldHRlID0gYygiIzJFOUZERiIsICIjMDBBRkJCIiksIGVsbGlwc2UudHlwZSA9ICJldWNsaWQiLCBzdGFyLnBsb3QgPSBUUlVFLCByZXBlbCA9IFRSVUUsIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkpDQoNCiMjIENPTkNMVVNJT05FUw0KDQpFc2NyaWJpciBjb25jbHVzaW9uZXMgZmluYWxlcy4NCg==