Objetivo y Anotaciones :: Fase 1
[Descripciones Multivariantes]
En términos generales, esta primera etapa de estudio mostrará
cálculos, visualizaciones e interpretaciones con base en un conjunto de
datos desde un enfoque de estadística descriptiva multivariante; además,
de incluir una prueba estadística de normalidad multivariada sobre
ellos.
El conjunto de datos de trabajo es descrito en la sección 2. Cabe anotar que los fundamentos teóricos
provienen de notas de clase del curso Análisis
Multivariante dictado por el profesor Juan Carlos Rubriche
Cárdenas para la Especialización en Estadística Aplicada, modalidad
virtual (cohorte 2022-4), de la Fundación Universitaria Los
Libertadores; y de los libros: Análisis Multivariante Aplicado con R
(Aldás & Uriel, 2017) de Joaquín
Aldás y Ezequiel Uriel, Análisis Multivariante de Joseph Hair, Rolph
Anderson, Ronald Tatham y William Black (Hair et al.,
1999), Análisis Estadístico de Datos Multivariados de Luis
Guillermo Díaz Monroy y Mario Alfonso Morales Rivera (Díaz Morales & Morales Rivera,
2012), Introducción a la Teoría Matemática de las
Probabilidades y a la Estadística de Howard Tucker (Tucker, 1973) y Análisis Multivariado:
Estadística Multivariada Descriptiva de William David Aristizábal
Rodríguez (Aristizábal R., 2017).
Este trabajo continúa el hecho en el curso Análisis de
Regresión dictado por el profesor Dagoberto Bermúdez para la
Especialización en Estadística Aplicada, modalidad virtual (cohorte
2022-4), de la Fundación Universitaria Los Libertadores. En este la
bibliografía consultada fue: probabilidad y estadística de Jay L. Devore
(Devore, Jay L., 2008), Bioestadística de
Wayne W. Daniel (Daniel, Wayne W., 2013), Métodos
Matemáticos de Estadística de Harald Cramer (Cramer, Harald,
1953); motivo por el cual se incluyen en las referencias. El
trabajo hecho en Análisis de Regresión que puede ser consultado
temporalmente a través de: https://rpubs.com/glibrerosl/Applied-Statistics-FULL.
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 lunes 13 de febrero
de 2023.
2. Descripción de los Datos
2.1. Fuente del Conjunto de Datos
El conjunto de datos de trabajo se obtuvo casi totalmente de
Kaggle: https://www.kaggle.com/akshaydattatraykhare. Es
conveniente anotar que Kaggle es una compañía
subsidiaria de Google LLC que mantiene una comunidad online de
científicos de datos y profesionales del aprendizaje automático. Esta
empresa permite a sus usuarios encontrar y publicar conjuntos de datos,
explorar y crear modelos en un entorno de ciencia de datos basado en la
web, trabajar con otros científicos de datos e ingenieros de aprendizaje
automático y participar en concursos para resolver desafíos de ciencia
de datos.
2.2. Contexto del Conjunto de Datos
El conjunto de datos incluye métricas académicas obtenidas por
estudiantes extranjeros para aspirar a acceder a universidades de EE.UU.
Este conjunto de datos se actualizó por última vez en julio de 2022.
2.3. Descripción del Conjunto de
Datos
El conjunto de datos contiene 10 campos y 400 registros. Uno de los
campos es simplemente un identificador numérico secuencial de los
registros; otros tres son de naturaleza politómica; y el resto son
numéricos estrictamente positivos. La lista siguiente los describe en el
mismo orden, de izquierdda a derecha, como aparecen en el rango de datos
que los contiene y se establece para cada campo, excepto el campo
Serial, el tipo de variable y su escala de medición con
base en la nomenclatura
(tipo_de_variable::escala_de_medición[ordenamiento]):
Serial (identificador): registra un número
secuenciado a partir de 1 para identificar de forma única cada registro
consignado en el conjunto de datos.
Gender (cualitativa::nominal): registra el sexo
del estudiante del cual se registraron los datos: 1 corresponde con un
estudiante de sexo masculino, 0 con un estudiante de sexo
femenino.
GRE Score (cuantitativa::razón): registra el
puntaje total GRE (examen de acceso a la universidad) obtenido por el
estudiante. GRE es un componente común del proceso de admisión a
colegios o universidades en EE.UU. que mide el razonamiento verbal,
cuantitativo, la escritura analítica y las habilidades de pensamiento
crítico que se han adquirido a lo largo de un extenso período de tiempo
y que no están relacionados con campo específicos de estudio. El campo
solo registra dos de los tres componentes de la evaluación: razonamiento
verbal y cuantitativo, en una escala desde 260 hasta 340 puntos. El
resultado ausente del puntaje corresponde con el componente de escritura
analítica: calificado entre 0 y 6 puntos.
TOEFL Score (cuantitativa::razón): registra el
puntaje total TOEFL (prueba de inglés como idioma extranjero) obtenido
por el estudiante. TOEFL es un componente común del proceso de admisión
a colegios o universidades en EE.UU. por parte de estudiantes
extranjeros que mide las competencias en comprensión escrita,
comprensión oral, expresión oral y expresión escrita, en una escala
desde 0 hasta 120 puntos.
SOP (cuantitativa::razón): registra el puntaje
total SOP (ensayo de declaración de propósitos o de admisión) obtenido
por el estudiante. SOP es un componente común del proceso de admisión a
colegios o universidades en EE.UU. que consiste en un ensayo de
solicitud de ingreso escrito por el estudiante en el cual debe hacer una
descripción general de quién es, en quién quiere convertirse y hasta qué
punto está preparado para seguir un determinado curso en la institución
educativa a la cual aspira ingresar. Este ensayo se califica con un
puntaje entre 0 y 5.
LOR (cuantitativa::razón): registra el puntaje
total LOR (carta de recomendación) obtenido por el estudiante. LOR es un
componente común del proceso de admisión a colegios o universidades en
EE.UU. que consiste en una recomendación escrita, generalmente por un
profesor, en la cual el redactor evalúa las cualidades, características
y capacidades del estudiante recomendado en relación con su aptitud para
seguir un curso en la institución educativa a la cual el estudiante
aspira a ingresar. Esta carta se califica con un puntaje entre 0 y
5.
CGPA (cuantitativa::razón): registra el puntaje
total CGPA (promedio de calificaciones acumulativo) obtenido por el
estudiante. CGPA es un componente común del proceso de admisión a
colegios o universidades en EE.UU. que mide el desempeño promedio del
estudiante en su escolaridad previa a la solicitud de ingreso a la
institución educativa siguiente de su preferencia. Este puntaje se mide
entre 0 y 4; sin embargo, en el conjunto de datos fue convertido en una
escala entre 0 y 10.
Research (cualitativa::nominal): registra la
experiencia en investigación que posee el estudiante: 1 corresponde con
que el estudiante argumenta experiencia investigativa, 0 corresponde con
que no-argumenta experiencia investigativa.
University Rating
(cualitativa::nominal(ordenada)): registra valoración de la universidad
a la cual aspira a ingresar el estudiante. Esta valoración se hace en
una escala entre 1 y 5 estrellas, cinco estrellas indica la mejor
valoración.
Chance of Admit (cuantitativa::razón): registra
la probabilidad de que el estudiante sea admitido en la universidad de
su preferencia con base en los datos registrados a su nombre, salvo su
sexo. Esta probrabilidad se mide entre 0 y 1.
Por último, es necesario aclarar que en el conjunto de datos los
registros de las variables cualitativas fueron reescritos, según los
casos, por números enteros positivos, incluido el cero. Así, los sexos
en la variable Gender fueron reescritos como
0:female y
1:male; en Research
el evidenciar o no-evidenciar investigaciones fue reescrito como
0:no-research y
1:research; y en University
Rating la valoración de la universidad fue reescrita como
1:one_star,
2:two_stars,
3:three_stars,
4:four_stars y
5:five_stars.
Estructura del Conjunto de Datos Inicial
str(Admission_Dataset_Initial)
## tibble [400 × 10] (S3: tbl_df/tbl/data.frame)
## $ Serial : num [1:400] 1 2 3 4 5 6 7 8 9 10 ...
## $ Gender : chr [1:400] "M" "F" "M" "M" ...
## $ GRE_Score : num [1:400] 337 324 316 322 314 330 321 308 302 323 ...
## $ TOEFL_Score : num [1:400] 118 107 104 110 103 115 109 101 102 108 ...
## $ SOP : num [1:400] 4.5 4 3 3.5 2 4.5 3 3 2 3.5 ...
## $ LOR : num [1:400] 4.5 4.5 3.5 2.5 3 3 4 4 1.5 3 ...
## $ CGPA : num [1:400] 9.65 8.87 8 8.67 8.21 9.34 8.2 7.9 8 8.6 ...
## $ Research : chr [1:400] "research" "research" "research" "research" ...
## $ University_Rating: chr [1:400] "four_stars" "four_stars" "three_stars" "three_stars" ...
## $ Chance_of_Admit : num [1:400] 0.92 0.76 0.72 0.8 0.65 0.9 0.75 0.68 0.5 0.45 ...
Conjunto de Datos Inicial
Admission_Dataset_Initial
## # A tibble: 400 × 10
## Serial Gender GRE_Score TOEFL_Score SOP LOR CGPA Resea…¹ Unive…² Chanc…³
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl>
## 1 1 M 337 118 4.5 4.5 9.65 resear… four_s… 0.92
## 2 2 F 324 107 4 4.5 8.87 resear… four_s… 0.76
## 3 3 M 316 104 3 3.5 8 resear… three_… 0.72
## 4 4 M 322 110 3.5 2.5 8.67 resear… three_… 0.8
## 5 5 M 314 103 2 3 8.21 no-res… two_st… 0.65
## 6 6 M 330 115 4.5 3 9.34 resear… five_s… 0.9
## 7 7 M 321 109 3 4 8.2 resear… three_… 0.75
## 8 8 M 308 101 3 4 7.9 no-res… two_st… 0.68
## 9 9 F 302 102 2 1.5 8 no-res… one_st… 0.5
## 10 10 F 323 108 3.5 3 8.6 no-res… three_… 0.45
## # … with 390 more rows, and abbreviated variable names ¹Research,
## # ²University_Rating, ³Chance_of_Admit
Estructura del Conjunto de Datos Reescrito
str(Admission_Dataset)
## tibble [400 × 10] (S3: tbl_df/tbl/data.frame)
## $ Serial : num [1:400] 1 2 3 4 5 6 7 8 9 10 ...
## $ Gender : num [1:400] 1 0 1 1 1 1 1 1 0 0 ...
## $ GRE_Score : num [1:400] 337 324 316 322 314 330 321 308 302 323 ...
## $ TOEFL_Score : num [1:400] 118 107 104 110 103 115 109 101 102 108 ...
## $ SOP : num [1:400] 4.5 4 3 3.5 2 4.5 3 3 2 3.5 ...
## $ LOR : num [1:400] 4.5 4.5 3.5 2.5 3 3 4 4 1.5 3 ...
## $ CGPA : num [1:400] 9.65 8.87 8 8.67 8.21 9.34 8.2 7.9 8 8.6 ...
## $ Research : num [1:400] 1 1 1 1 0 1 1 0 0 0 ...
## $ University_Rating: num [1:400] 4 4 3 3 2 5 3 2 1 3 ...
## $ Chance_of_Admit : num [1:400] 0.92 0.76 0.72 0.8 0.65 0.9 0.75 0.68 0.5 0.45 ...
Conjunto de Datos Reescrito
Admission_Dataset
## # A tibble: 400 × 10
## Serial Gender GRE_Score TOEFL_Score SOP LOR CGPA Resea…¹ Unive…² Chanc…³
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 1 337 118 4.5 4.5 9.65 1 4 0.92
## 2 2 0 324 107 4 4.5 8.87 1 4 0.76
## 3 3 1 316 104 3 3.5 8 1 3 0.72
## 4 4 1 322 110 3.5 2.5 8.67 1 3 0.8
## 5 5 1 314 103 2 3 8.21 0 2 0.65
## 6 6 1 330 115 4.5 3 9.34 1 5 0.9
## 7 7 1 321 109 3 4 8.2 1 3 0.75
## 8 8 1 308 101 3 4 7.9 0 2 0.68
## 9 9 0 302 102 2 1.5 8 0 1 0.5
## 10 10 0 323 108 3.5 3 8.6 0 3 0.45
## # … with 390 more rows, and abbreviated variable names ¹Research,
## # ²University_Rating, ³Chance_of_Admit
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 describir el
comportamiento posicional, dispersivo y correlacional de variables
aleatorias. En este sentido, el conjunto de datos de trabajo que posee
cinco variables aleatorias 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.
3.1. Planteamiento del Problema
Con base en el conjunto de datos descrito en la sección 2 se calcularán e intepretará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 (en escalada de medición de razón) son: GRE
Score, TOEFL Score, SOP,
LOR, CGPA y Chance of
Admit.
3.2. 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 \(\bar x\), Matriz de
Varianzas-Covarianzas \(S\) y
Matriz de Correlaciones \(R\).
Con base en la pestaña Vector de Medias y Boxplots
se puede describir que en general los datos registrados para cada una de
las variables tienden a tener colas izquierdas en su distribuciones,
así, las medias estimadas tienden a ser altas. Adicionalmente, en
relación con la mediana, solo la variable SOP muestra
un sesgo notorio en comparación con las demás. Además, todos los casos
atípicos son de extremo inferior. Si se revisan los rangos de las
variables estudiadas se puede constatar que las medias son altas
compradas con los extremos superiores de cada rango.
Con base en la pestaña Matriz de
Varianzas-Covarianzas se interpreta que, en general, y como se
espera que pase, las relaciones entre las variables, estudiadas por
pares, tienden a ser de proporcionalidad directa. Para el caso, se
pueden observar la gráfica multivariada mostrada en la pestaña
Diagrama Conjunto de Dispersión, Distribución y Correlaciones
[SA] de la sección 4.2.
Con base en la pestaña Matriz de Correlaciones y al
considerar la Matriz de Varianzas-Covarianzas es
verificable que la intensidad de las corelaciones es más alta y siempre
positiva entre las variables: TOEFL_Score,
GRE_Score, CGPA y
Chance_of_Admit, que es esperado en relación con el
fenómeno estudiado, esto se puede revisar con más detalles en la sección 4.2.
Matriz de Varianzas-Covarianzas
round(cov(Admission_Dataset[,-c(1,2,8,9)]),2)
## GRE_Score TOEFL_Score SOP LOR CGPA Chance_of_Admit
## GRE_Score 131.64 58.22 7.08 5.75 5.70 1.31
## TOEFL_Score 58.22 36.84 4.02 3.10 3.00 0.69
## SOP 7.08 4.02 1.01 0.66 0.43 0.10
## LOR 5.75 3.10 0.66 0.81 0.36 0.09
## CGPA 5.70 3.00 0.43 0.36 0.36 0.07
## Chance_of_Admit 1.31 0.69 0.10 0.09 0.07 0.02
Matriz de Correlaciones
round(cor(Admission_Dataset[,-c(1,2,8,9)]),2)
## GRE_Score TOEFL_Score SOP LOR CGPA Chance_of_Admit
## GRE_Score 1.00 0.84 0.61 0.56 0.83 0.80
## TOEFL_Score 0.84 1.00 0.66 0.57 0.83 0.79
## SOP 0.61 0.66 1.00 0.73 0.72 0.68
## LOR 0.56 0.57 0.73 1.00 0.67 0.67
## CGPA 0.83 0.83 0.72 0.67 1.00 0.87
## Chance_of_Admit 0.80 0.79 0.68 0.67 0.87 1.00
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 correlación
entre varias variables. En este sentido, el conjunto de datos de trabajo
tendrá apoyo descritivo 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.
4.1. Planteamiento del Problema
Con base en el conjunto de datos descrito en la sección 2 se calcularán e intepretará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: GRE Score, TOEFL
Score, SOP, LOR,
CGPA y Chance of Admit.
4.2. Desarrollo del Análisis
La navegación a través de las pestañas muestra las gráficas
multivariadas de: Diagrama Conjunto de Dispersión, Distribución
y Correlaciones (sin agrupación SA y con agrupación CA (con
base en las tres variables categóricas: Gender:GE, Research:RE,
University_Rating:UR)), Diagrama de Estrellas y
Caras de Chernoff.
Con base en la pestaña Diagrama Conjunto de Dispersión,
Distribución y Correlaciones [SA] se puede describir que las
correlaciones más altas, mayores que \(0.8\), se dan entre variables esperadas
como: TOEFL_Score, GRE_Score,
CGPA y Chance_of_Admit. Estas
variables, según las definiciones dadas en la sección
2 de descripción de datos, son nucleares en el fenómeno estudiado,
porque están involucradas con el historial de rendimiento académico del
estudiante, su desempeño en la prueba de ingreso a la universidad, su
nivel de dominio certificado del idioma inglés y sus índice de
probabilidad de ingreso a la universidad a la cual aspira. Sin embargo,
ninguna de ellas es descollantemente explicativa. Para más detalles
puede consultarse el trabajo de análisis de regrresión formulado sobre
el mismo conjunto de datos a través de: https://rpubs.com/glibrerosl/Applied-Statistics-FULL.
Complementariamente, con base en las pestañas Diagrama
Conjunto de Dispersión, Distribución y Correlaciones en sus
versiones basadas en grupos a partir de las variables categóricas:
Gender, Research y
University_Rating, se puede apreciar que
comparativamente la diferenciación basada en Gender no
muestra relevancia para elevar la probabilidad de acceso a la
universidad de su elección, contrario a lo que sucede con la variable
agrupadora Research que muestra diferenciadamente lo
contrario. Es decir, que un estudiante pertenezca al grupo de aquellos
que evidencia trabajo en investigación al momento de presentar su
solicitud de acceso, resulta para él en una característica
significativamente a favor de sus pretensiones. Por otro lado, la
variable clasificadora University_Rating, que aporta
cinco grupos, muestra que las universidades de dos y cuatro estrellas en
todos los casos visualizados en el diagrama son significativas a nivel
de correlación, pero, como es esperado, las de mejor rating, atraen a
los mejores talentos.
Con base en la pestaña Diagrama de Estrellas se
interpreta que hay una variedad notoria de estudiantes en términos de
desempeños asociados con las variables numéricas estudiadas, incluso con
la que mide el examen de proficiencia en lengua extranjera, para el caso
inglés: TOEFL_Score. Pero, también es notoria la
presencia de grupos de estudiantes con desempeños aproximadamente
homogéneos en todas las variables estudiadas, aunque sus escalas de
desempeño varian.
Complementariamente a los diagramas de estrellas, la pestaña
Caras de Chernoff muestra que la variedad de
estudiantes es sensible de establecer. Con relativa claridad, las
Caras de Chernoff número 1, 10, 21 y 8, 19, 22, pueden
conformar un par de grupos de estudiantes que muestran desempeños
significativos en las variables medidas, aunque con cambios de escala;
es decir, los del segundo grupo se desempeñan mejor que los del primero
considerando todas las variables estudiadas. Esto compagina con lo
mostrado en el Diagrama de Estrellas.
Por último, es relevante mencionar que las evidencias descriptivas
expuestas en este apartado estén en contra de considerar que el conjunto
de datos limitado a las variables numéricas tenga una distribución
normal multivariada. Esto se estudia en la sección
5.
Diagrama Conjunto de Dispersión, Distribución y Correlaciones
[SA]
ggpairs(Admission_Dataset[,-c(1,2,8,9)])

Diagrama Conjunto de Dispersión, Distribución y Correlaciones
[CA:GE]
ggpairs(Admission_Dataset_Initial, columns = c(3:7,10), aes(color = Gender, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

Diagrama Conjunto de Dispersión, Distribución y Correlaciones
[CA:RE]
ggpairs(Admission_Dataset_Initial, columns = c(3:7,10), aes(color = Research, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

Diagrama Conjunto de Dispersión, Distribución y Correlaciones
[CA:UR]
ggpairs(Admission_Dataset_Initial, columns = c(3:7,10), aes(color = University_Rating, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

Diagrama de Estrellas
set.seed(780728)
Admission_Dataset_Muestreado = Admission_Dataset[sample(1:nrow(Admission_Dataset),23),-c(1,2,8,9)]
stars(Admission_Dataset_Muestreado, len = 1, cex = 0.4, key.loc = c(10, 2), draw.segments = TRUE)

Caras de Chernoff
set.seed(780728)
Admission_Dataset_Muestreado = Admission_Dataset[sample(1:nrow(Admission_Dataset),23),-c(1,2,8,9)]
faces(Admission_Dataset_Muestreado)

## effect of variables:
## modified item Var
## "height of face " "GRE_Score"
## "width of face " "TOEFL_Score"
## "structure of face" "SOP"
## "height of mouth " "LOR"
## "width of mouth " "CGPA"
## "smiling " "Chance_of_Admit"
## "height of eyes " "GRE_Score"
## "width of eyes " "TOEFL_Score"
## "height of hair " "SOP"
## "width of hair " "LOR"
## "style of hair " "CGPA"
## "height of nose " "Chance_of_Admit"
## "width of nose " "GRE_Score"
## "width of ear " "TOEFL_Score"
## "height of ear " "SOP"
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 \(\alpha = 0.05\) y a las hipótesis:\[H_0: \text {Las variables tienen una
DNM}\] \[H_1: \text {Las variables NO
tienen una DNM}\]
La prueba de Mardia se 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 \(\chi^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 \(\mu\) y varianza \(\sigma^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
\(\chi^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).
5.1. 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 \(\alpha=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: GRE Score, TOEFL Score,
SOP, LOR, CGPA y
Chance of Admit.
5.2. 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, no se distribuye normal
multivariado. En particular:
La PNM de Mardia establece que si ambas pruebas
(para asimetría y curtosis) indican una normalidad multivariante, los
datos siguen una DNM con un nivel de significancia \(\alpha=0.05\); sin embargo, el caso tratado
es contrario a esto. Obsérvese a través de la pestaña PNM
Mardia que los \(p-value\)
para la asimetría (Skewness) y curtoris (Kurtosis) son mayores que el
nivel de significancia. Por lo tanto, las evidencias no apoyan una
hipótesis de normalidad multivariada para el conjunto de datos
restringido a sus variables numéricas.
La PNM de PNM Henze-Zirkler establece que el
estadístico de prueba no se distribuye aproximadamente como lognormal
dado que su \(p-value\) es menor que el
nivel de significancia \(\alpha=0.05\),
obsérvese esto a través de la pestaña PNM
Henze-Zirkler. Así, por contrarrecíproco de la implicación
formulada en la descripción de la prueba en la sección
5, el conjunto de datos no está apoyado por las evidencias para
seguir una distribución normal multivariada.
La PNM de Doornik-Hansen establece que su
estadístico de prueba no sigue una distribución aproximadamente \(\chi^2\) dado que su \(p-value\) es menor que el nivel de
significancia \(\alpha=0.05\),
obsérvese esto a través de la pestaña PNM
Doornik-Hansen. Por lo tanto, las evidencias están lejos de
apoyar que el conjunto de datos sigue una DNM.
La PNM de Royston establece que el conjunto de datos
reducido a sus variables numéricas no sigue una DNM, dado que su \(p-value\) es menor que el nivel de
significancia \(\alpha=0.05\).
Obsérvese esto a través de la pestaña PNM Royston.
En general, pudo constatarse que para un nivel de significancia \(\alpha=0.05\) el conjunto de datos reducido
a sus variabls numéricas no sigue una distribución normal
multivariada.
PNM Mardia
mvn(Admission_Dataset[,-c(1,2,8,9)], mvnTest="mardia")
## $multivariateNormality
## Test Statistic p value Result
## 1 Mardia Skewness 271.779505720825 4.34632487808584e-30 NO
## 2 Mardia Kurtosis 4.02256608402635 5.75674947702609e-05 NO
## 3 MVN <NA> <NA> NO
##
## $univariateNormality
## Test Variable Statistic p value Normality
## 1 Anderson-Darling GRE_Score 1.1168 0.0063 NO
## 2 Anderson-Darling TOEFL_Score 1.1416 0.0055 NO
## 3 Anderson-Darling SOP 5.4710 <0.001 NO
## 4 Anderson-Darling LOR 5.9416 <0.001 NO
## 5 Anderson-Darling CGPA 0.5320 0.1729 YES
## 6 Anderson-Darling Chance_of_Admit 1.5949 4e-04 NO
##
## $Descriptives
## n Mean Std.Dev Median Min Max 25th 75th
## GRE_Score 400 316.807500 11.4736461 317.00 290.00 340.00 308.00 325.0000
## TOEFL_Score 400 107.410000 6.0695138 107.00 92.00 120.00 103.00 112.0000
## SOP 400 3.400000 1.0068686 3.50 1.00 5.00 2.50 4.0000
## LOR 400 3.452500 0.8984775 3.50 1.00 5.00 3.00 4.0000
## CGPA 400 8.598925 0.5963171 8.61 6.80 9.92 8.17 9.0625
## Chance_of_Admit 400 0.724350 0.1426093 0.73 0.34 0.97 0.64 0.8300
## Skew Kurtosis
## GRE_Score -0.06242254 -0.7181786
## TOEFL_Score 0.05678751 -0.5985838
## SOP -0.27369641 -0.6937320
## LOR -0.10619038 -0.6808341
## CGPA -0.06549644 -0.4803728
## Chance_of_Admit -0.35080166 -0.4122290
PNM Henze-Zirkler
mvn(Admission_Dataset[,-c(1,2,8,9)], mvnTest="hz")
## $multivariateNormality
## Test HZ p value MVN
## 1 Henze-Zirkler 1.675143 0 NO
##
## $univariateNormality
## Test Variable Statistic p value Normality
## 1 Anderson-Darling GRE_Score 1.1168 0.0063 NO
## 2 Anderson-Darling TOEFL_Score 1.1416 0.0055 NO
## 3 Anderson-Darling SOP 5.4710 <0.001 NO
## 4 Anderson-Darling LOR 5.9416 <0.001 NO
## 5 Anderson-Darling CGPA 0.5320 0.1729 YES
## 6 Anderson-Darling Chance_of_Admit 1.5949 4e-04 NO
##
## $Descriptives
## n Mean Std.Dev Median Min Max 25th 75th
## GRE_Score 400 316.807500 11.4736461 317.00 290.00 340.00 308.00 325.0000
## TOEFL_Score 400 107.410000 6.0695138 107.00 92.00 120.00 103.00 112.0000
## SOP 400 3.400000 1.0068686 3.50 1.00 5.00 2.50 4.0000
## LOR 400 3.452500 0.8984775 3.50 1.00 5.00 3.00 4.0000
## CGPA 400 8.598925 0.5963171 8.61 6.80 9.92 8.17 9.0625
## Chance_of_Admit 400 0.724350 0.1426093 0.73 0.34 0.97 0.64 0.8300
## Skew Kurtosis
## GRE_Score -0.06242254 -0.7181786
## TOEFL_Score 0.05678751 -0.5985838
## SOP -0.27369641 -0.6937320
## LOR -0.10619038 -0.6808341
## CGPA -0.06549644 -0.4803728
## Chance_of_Admit -0.35080166 -0.4122290
PNM Doornik-Hansen
mvn(Admission_Dataset[,-c(1,2,8,9)], mvnTest="dh")
## $multivariateNormality
## Test E df p value MVN
## 1 Doornik-Hansen 1844.957 12 0 NO
##
## $univariateNormality
## Test Variable Statistic p value Normality
## 1 Anderson-Darling GRE_Score 1.1168 0.0063 NO
## 2 Anderson-Darling TOEFL_Score 1.1416 0.0055 NO
## 3 Anderson-Darling SOP 5.4710 <0.001 NO
## 4 Anderson-Darling LOR 5.9416 <0.001 NO
## 5 Anderson-Darling CGPA 0.5320 0.1729 YES
## 6 Anderson-Darling Chance_of_Admit 1.5949 4e-04 NO
##
## $Descriptives
## n Mean Std.Dev Median Min Max 25th 75th
## GRE_Score 400 316.807500 11.4736461 317.00 290.00 340.00 308.00 325.0000
## TOEFL_Score 400 107.410000 6.0695138 107.00 92.00 120.00 103.00 112.0000
## SOP 400 3.400000 1.0068686 3.50 1.00 5.00 2.50 4.0000
## LOR 400 3.452500 0.8984775 3.50 1.00 5.00 3.00 4.0000
## CGPA 400 8.598925 0.5963171 8.61 6.80 9.92 8.17 9.0625
## Chance_of_Admit 400 0.724350 0.1426093 0.73 0.34 0.97 0.64 0.8300
## Skew Kurtosis
## GRE_Score -0.06242254 -0.7181786
## TOEFL_Score 0.05678751 -0.5985838
## SOP -0.27369641 -0.6937320
## LOR -0.10619038 -0.6808341
## CGPA -0.06549644 -0.4803728
## Chance_of_Admit -0.35080166 -0.4122290
PNM Royston
mvn(Admission_Dataset[,-c(1,2,8,9)], mvnTest="royston")
## $multivariateNormality
## Test H p value MVN
## 1 Royston 83.73469 4.306446e-17 NO
##
## $univariateNormality
## Test Variable Statistic p value Normality
## 1 Anderson-Darling GRE_Score 1.1168 0.0063 NO
## 2 Anderson-Darling TOEFL_Score 1.1416 0.0055 NO
## 3 Anderson-Darling SOP 5.4710 <0.001 NO
## 4 Anderson-Darling LOR 5.9416 <0.001 NO
## 5 Anderson-Darling CGPA 0.5320 0.1729 YES
## 6 Anderson-Darling Chance_of_Admit 1.5949 4e-04 NO
##
## $Descriptives
## n Mean Std.Dev Median Min Max 25th 75th
## GRE_Score 400 316.807500 11.4736461 317.00 290.00 340.00 308.00 325.0000
## TOEFL_Score 400 107.410000 6.0695138 107.00 92.00 120.00 103.00 112.0000
## SOP 400 3.400000 1.0068686 3.50 1.00 5.00 2.50 4.0000
## LOR 400 3.452500 0.8984775 3.50 1.00 5.00 3.00 4.0000
## CGPA 400 8.598925 0.5963171 8.61 6.80 9.92 8.17 9.0625
## Chance_of_Admit 400 0.724350 0.1426093 0.73 0.34 0.97 0.64 0.8300
## Skew Kurtosis
## GRE_Score -0.06242254 -0.7181786
## TOEFL_Score 0.05678751 -0.5985838
## SOP -0.27369641 -0.6937320
## LOR -0.10619038 -0.6808341
## CGPA -0.06549644 -0.4803728
## Chance_of_Admit -0.35080166 -0.4122290
Objetivo y Anotaciones :: Fase 2
[Componentes Principales]
En términos generales, esta segunda etapa de estudio mostrará
cálculos, visualizaciones e interpretaciones con base en el conjunto de
datos tratado en la fase 1, pero ahora desde un
enfoque de análisis de componentes principales sobre las variables
cuantitativas, que incluirá: selección, calidad de representación,
contribuciones e interpretación.
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 26 de febrero
de 2023.
7. Selección 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.
7.1. 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.
7.2. 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, puede ser representado
por un conjuto de variables más pequeño que retiene el \(77.05\) \(\%\) de la variabilidad del conjunto. En
particular:
La Matriz ACP muestra seis dimensiones donde solo la
primera retiene el \(77.05\) \(\%\), la siguiente el \(10.33\) \(\%\) y las demás solo porcentajes con parte
entera de una cifra. En este sentido, la representatividad de la
combinación lineal que define a la dimensión 1 es significativamente
alta en comparación con las demás. Como esta matriz es muda en relación
con las variables originales se sigue indagando la identificación de las
variables que más contribuyan a la dimensión de valor propio más
alto.
La Matriz de Correlaciones permite continuar con las
descripciones de las combinaciones lineales que conforman a la dimensión
de mayor interés: la dimensión 1. Así, esta matriz, como se mostró en la
sección 3.2., ayuda a verificar que la intensidad
de las corelaciones es más alta y siempre positiva entre las variables:
TOEFL_Score, GRE_Score, CGPA y Chance_of_Admit, asunto esperado en
relación con el fenómeno estudiado, por lo tanto, se podría esperar que
estas variables participaran en la combinación lineal que define a la
dimensión 1.
La pestaña de Valores y Vectores Propios muestra
estos objetos calculados a partir de la matriz de correlaciones del
conjunto de datos. En este sentido, se garantiza que la suma de los
valores propios sea igual a la dimensión de dicha matriz y a la
variabilidad total del conjunto, por lo cual las proporciones de
retención de variabilidad son de cálculo inmediato. Además, la matriz de
vectores propios define para cada componente, en relación con cada
variable del conjunto de datos, los coeficientes de la combinación
lineal que la conforman, por ejemplo, con un ajuste a dos cifras
decimales, la componente 1 estaría representada por la combinación
lineal (donde \(G\) es GRE_Score, \(T\) es TOEFL_Score, \(S\) es SOP, \(L\) es LOR, \(CG\) es CGPA y \(CA\) es Chance_of_Admit y además, son
variables estandarizadas):\[Componente_1 =
0.41*G+0.42*T+0.39*S+0.37*L+0.44*CG+0.43*CA\]Hasta este punto, se
puede observar que se dispone de un número de dimensiones igual al
número de variables tratadas, con la salvedad que las variables nuevas
son incorreladas entre sí, ver la pestaña Correlaciones
Comparadas.
Por último, el Gráfico de Cattell y el
Gráfico de Cattell-Kaiser, de codo y sedimentación,
inducen a la elección de una componente en la reducción de dimensión que
retiene la cantidad de variabilidad suficiente para tratar el problema.
Sin embargo, debe resaltarse que se propone elegir con base en criterios
más usados, a cambio de criterios de aceptación universal. El
Gráfico de Cattell muestra que los cambios en la
pendiente indican que la capacidad explicativa de la dimensión 1 es alta
comparada con el resto. Así, el de Cattell-Kaiser al
conjugar el instrumento gráfico anterior con el criterio de Kaiser en la
misma gráfica apoya que la cantidad de dimensiones suficientes por
retener es una, aclarando que esta elección retenga un porcentaje de
variabilidad adecuado para estudiar el problema.
Matriz ACP
get_eigenvalue(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F))
## eigenvalue variance.percent cumulative.variance.percent
## Dim.1 4.6229170 77.048617 77.04862
## Dim.2 0.6197827 10.329711 87.37833
## Dim.3 0.2820316 4.700527 92.07885
## Dim.4 0.1992199 3.320332 95.39919
## Dim.5 0.1581864 2.636441 98.03563
## Dim.6 0.1178624 1.964373 100.00000
Matriz de Correlaciones
round(cor(Admission_Dataset[,-c(1,2,8,9)]),2)
## GRE_Score TOEFL_Score SOP LOR CGPA Chance_of_Admit
## GRE_Score 1.00 0.84 0.61 0.56 0.83 0.80
## TOEFL_Score 0.84 1.00 0.66 0.57 0.83 0.79
## SOP 0.61 0.66 1.00 0.73 0.72 0.68
## LOR 0.56 0.57 0.73 1.00 0.67 0.67
## CGPA 0.83 0.83 0.72 0.67 1.00 0.87
## Chance_of_Admit 0.80 0.79 0.68 0.67 0.87 1.00
Valores y Vectores Propios
princomp(Admission_Dataset[,-c(1,2,8,9)], cor = TRUE)$sdev^2
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6
## 4.6229170 0.6197827 0.2820316 0.1992199 0.1581864 0.1178624
princomp(Admission_Dataset[,-c(1,2,8,9)], cor = TRUE)$loadings[ ,1:6]
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
## GRE_Score 0.4127781 0.4077294 0.02539719 0.3509029 0.72123826
## TOEFL_Score 0.4160056 0.3397387 -0.24669025 0.4574809 -0.65951168
## SOP 0.3855091 -0.4887667 -0.73602577 -0.1872366 0.15066692
## LOR 0.3662513 -0.6631878 0.52149384 0.3899370 -0.03811828
## CGPA 0.4372217 0.1447341 0.08859141 -0.3349520 -0.01437723
## Chance_of_Admit 0.4273564 0.1366578 0.34199519 -0.6068585 -0.14317642
## Comp.6
## GRE_Score 0.13931437
## TOEFL_Score 0.08010298
## SOP 0.11400812
## LOR -0.02412840
## CGPA -0.81709316
## Chance_of_Admit 0.54125202
Correlaciones Comparadas
par(mfrow=c(1,2))
corrplot::corrplot(cor(Admission_Dataset[,-c(1,2,8,9)]), method = "color", type = "upper", number.cex = 0.4)
corrplot::corrplot(cor(princomp(Admission_Dataset[,-c(1,2,8,9)], cor = TRUE)$scores), method = "color", type = "upper", number.cex = 0.4)

Gráfico de Cattell
fviz_eig(PCA(Admission_Dataset[,-c(1,2,8,9)], scale.unit = T, graph = F), addlabels = T, ylim=c(0,90), main = "")

Gráfico de Cattell-Kaiser
scree(Admission_Dataset[,-c(1,2,8,9)],factors = FALSE, pc = TRUE, main ="")

8. 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.
8.1. 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.
8.2. 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 analizar las calidades de
representación en términos de la escala de contribuciones relativas
basada en un cociente de proyecciones con propiedades aditivas y de
respuesta en escala continua entre \(0\) y \(1\). Así, en particular:
El Círculo de Correlaciones expresa que se puede
concebir una 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 cercanas 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
correlació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 influidas 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 de \(0.84\) de esta manera las calidades de
representación, en relación con la 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.
Por último, las Coordenadas Individuales ayudan,
aunque de manera menos digestiva, a identificar a nivel de observaciones
a los perfiles de los registros, en este caso estudiantes, en relación
con las, por lo menos, dimensiones más importantes de retención de
variabilidad: las componentes 1 y 2. Por ejemplo, al observar los
registros 1, 9, 23, se manifiestan las semejanzas entre 1 y 23 en
oposición de ambos con 9, incluso al considerar a la variable peor
representada SOP.
Círculo de Correlaciones
fviz_pca_var(PCA(Admission_Dataset[,-c(1,2,8,9)], scale.unit = T, graph = F),col.var="#3B83BD", repel = T, col.circle = "#CDCDCD", ggtheme = theme_bw())

Matriz de Representación
(get_pca_var(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F)))$cos2
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## GRE_Score 0.7876792 0.10303471 0.0001819152 0.024530510 8.228615e-02
## TOEFL_Score 0.8000450 0.07153678 0.0171633381 0.041694489 6.880409e-02
## SOP 0.6870452 0.14806169 0.1527860873 0.006984159 3.590915e-03
## LOR 0.6201182 0.27259164 0.0767001373 0.030291557 2.298454e-04
## CGPA 0.8837298 0.01298318 0.0022135076 0.022351052 3.269787e-05
## Chance_of_Admit 0.8442996 0.01157466 0.0329866161 0.073368148 3.242741e-03
## Dim.6
## GRE_Score 2.287532e-03
## TOEFL_Score 7.562625e-04
## SOP 1.531958e-03
## LOR 6.861706e-05
## CGPA 7.868979e-02
## Chance_of_Admit 3.452823e-02
Calidad de Representación
fviz_pca_var(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), col.var="cos2", gradient.cols=c("#00AFBB","#E7B800","#FC4E07"), repel = TRUE)

Coordenadas Individuales
head((PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F))$ind$coord, n = 23L)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6
## 1 3.66199019 -0.44632765 -0.04355921 0.24316486 0.017016882 -0.21656303
## 2 1.19446218 0.73276087 -0.32814709 0.22842243 0.500315331 -0.11454589
## 3 -0.84979414 0.21025529 -0.35781782 0.16841716 0.277052946 0.70366065
## 4 0.29352000 -1.07510412 0.52840810 -0.44035081 0.022712146 0.32426628
## 5 -1.63376006 -0.50197420 -0.69858584 0.18077296 0.196680136 0.01208760
## 6 2.30415785 -1.04317671 0.81572439 -0.58984239 -0.005863787 0.04832797
## 7 0.11435288 0.04426511 -0.55778114 0.67583330 -0.008454658 0.65668699
## 8 -1.33319919 1.09523940 -0.64182557 0.14097961 0.121311282 0.53850632
## 9 -3.35109245 -0.93258034 0.55044116 -0.15675362 -0.230221499 -0.38858777
## 10 -0.70518251 -0.27624655 1.00503641 1.18722583 0.635525284 -0.93744778
## 11 -0.29903917 0.48517068 0.19973837 1.34630477 0.870978323 -0.42605295
## 12 1.91250151 0.29349042 -0.38344367 0.20818908 0.170392628 0.10043733
## 13 1.91053416 0.23513132 -0.21577217 0.51368146 0.182435980 -0.23939216
## 14 -0.95161415 0.46272070 1.12821047 0.29277119 -0.561789232 0.40712161
## 15 -1.63366474 -0.42045583 1.12531747 -0.37340051 0.206735944 0.04749185
## 16 -1.38952108 -0.17085741 1.02199451 0.25321293 0.333470659 -0.31946818
## 17 -0.09475078 0.01051262 0.82448700 -0.11605999 0.228086329 -0.30609341
## 18 -0.63522387 0.17510274 0.90749587 0.30600586 0.489710926 0.62737017
## 19 0.13054730 -0.18871990 1.00151472 0.21254670 -0.007618938 -0.50549162
## 20 -1.40069985 0.63282752 0.41187500 -0.54609747 -0.138958575 -0.47666697
## 21 -1.71366787 -0.82306966 0.85181743 0.01762092 -0.154540513 0.56819308
## 22 -0.21792196 -1.85700802 0.88942803 0.40713293 -0.170286359 0.36076889
## 23 3.54618997 0.61579548 -0.05532575 -0.06004547 -0.294653496 -0.02737099
9. Contribuciones
Según el trabajo de (Díaz Morales &
Morales Rivera, 2012) la interpretación de resultados está
vinculada con el cálculo de coordenadas, contribuciones, cosenos
cuadrados, etc, por lo tanto, la conceptualización de las variables debe
ser clara para establecerla con la mayor claridad posible, es decir, los
datos deben ponerse en contexto. En este sentido, la contribución de una
variable a una componente allana el camino de la interpretación de
resultados. Esto se hace en este apartado en el sentido de calcular lor
aportes con que cada variable participa para definir a cada componente
generada.
9.1. 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.
9.2. 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 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 D6, 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.
En Contribuciones a D1 se visualiza que las
variables por enciama de la contribución media: CGPA,
Chance_of_Admit, TOEFL_Score y
GRE_Score retienen aproximadamente el \(71.72\) \(\%\) de la variabilidad del componente
1.
En Contribuciones a D2 se visualiza que las
variables por enciama de la contribución media: LOR y
SOP retienen aproximadamente el \(67.87\) \(\%\) de la variabilidad del componente
2.
En Contribuciones a D3 se visualiza que las
variables por enciama de la contribución media: SOP y
LOR retienen aproximadamente el \(81.37\) \(\%\) de la variabilidad del componente
3.
En Contribuciones a D4 se visualiza que las
variables por enciama de la contribución media:
Chance_of_Admit y TOEFL_Score retienen
aproximadamente el \(57.76\) \(\%\) de la variabilidad del componente
4.
En Contribuciones a D5 se visualiza que las
variables por enciama de la contribución media:
GRE_Score y TOEFL_Score retienen
aproximadamente el \(95.51\) \(\%\) de la variabilidad del componente
5.
Por último, en Contribuciones a D6 se visualiza que
las variables por enciama de la contribución media:
CGPA y Chance_of_Admit retienen
aproximadamente el \(96.06\) \(\%\) de la variabilidad del componente
6.
Con los datos procesados hasta ahora se puede proceder con la
intepretación de los componentes.
Matriz de Contribuciones
(get_pca_var(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F)))$contrib
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## GRE_Score 17.03858 16.624329 0.06450171 12.313282 52.01846278
## TOEFL_Score 17.30607 11.542236 6.08560812 20.928876 43.49556571
## SOP 14.86172 23.889292 54.17339277 3.505753 2.27005215
## LOR 13.41400 43.981812 27.19558265 15.205085 0.14530029
## CGPA 19.11628 2.094796 0.78484383 11.219286 0.02067047
## Chance_of_Admit 18.26335 1.867535 11.69607091 36.827718 2.04994861
## Dim.6
## GRE_Score 1.94084948
## TOEFL_Score 0.64164873
## SOP 1.29978503
## LOR 0.05821794
## CGPA 66.76412347
## Chance_of_Admit 29.29537534
Contribuciones a D1
fviz_contrib(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 1, top = 10)

Contribuciones a D2
fviz_contrib(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 2, top = 10)

Contribuciones a D3
fviz_contrib(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 3, top = 10)

Contribuciones a D4
fviz_contrib(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 4, top = 10)

Contribuciones a D5
fviz_contrib(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 5, top = 10)

Contribuciones a D6
fviz_contrib(PCA(Admission_Dataset[,-c(1,2,8,9)], ncp = 6, scale.unit = TRUE, graph = F), choice = "var", axes = 6, top = 10)

10. Interpretación
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.
10.1. 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.
10.2. 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, ayudan a robustecer la interpretación de las componentes
calculadas. Como se mostró en la sección 7, la
cantidad de componentes seleccionadas se redujo (según el criterio de
Kaiser) a una y se estableció que la componente 1 retiene el \(77.05\) \(\%\) de la variabilidad de los datos. Así,
en el círculo de correlaciones de la sección 8 se
aprecia que la representación de las variables conjugadas en la
componente 1 la configuran como una de tipo tamaño, lo que puede
interpretarse como una especie de índice de proporcionalidad directa.
Esto también se apoya con base en el hecho de que todas las variables
presentan calidades de representación entre \(0.62\) y \(0.88\). En consecuencia, cuanto mayor sea
el valor las variables mayor será el estado de favorabilidad de que el
estudiante sea admitido por la univrsidad de su preferencia. Así, dada
la naturaleza de las variables esta componente puede representar para un
estudiante su medida de competitividad formativa. Al
respecto:
Las pestañas Biplot de Variables y Registros Totales
en UR (University Rating), G (Gender)
y R (Research), muestran, con base en las agrupaciones
que estas variables categóricas pueden establecer, la representación en
dimensionalidad reducida en el plano de factores de registros y
dimensiones con base en los puntajes por componentes. En este sentido,
es posible apreciar que las agrupaciones con base en
University_Rating y Research capturan
diferencias acentuadas en la distribuciones de las observaciones,
contrario a la agrupación con base en Gender.
Por último, para facilitar la verificación de la ubicación de
puntajes en el plano de componentes (en particular, siempre conformado
por las componentes 1 y 2 por el interés que sucitan) y, asimismo, las
semejanzas de perfiles y las correlaciones entre variables, se dispuso
de las pestañas Coordenadas Individuales [Subconjunto
UR] y Biplot de Variables y Registros [Subconjunto
UR]. Estas muestran, con base en un subconjuto de 61 registros
muestrado aleatorio simple, los puntajes por componentes y el biplot de
ese subconjunto, con base en la agrupación provista por la varaible
categórica University_Rating, sin pérdida significativa
de detalles. Esto, se insiste, solo tiene fines didácticos, debido a la
dificultad de identificación visual que presenta el conjunto original
que contiene 400 registros.
Biplot de Variables y Registros [Total UR]
data_UR <- Admission_Dataset_Initial[,-c(1,2,8)]
data_All <- cbind(Admission_Dataset_Initial[,-c(1,2,8,9)], data_UR$University_Rating)
fviz_pca_biplot(PCA(data_All, ncp = 6, scale.unit = TRUE, graph = F, quali.sup = 7), axes = c(1, 2), repel = TRUE, habillage = 7)

Biplot de Variables y Registros [Total G]
data_UR <- Admission_Dataset_Initial[,-c(1,8,9)]
data_All <- cbind(Admission_Dataset_Initial[,-c(1,2,8,9)], data_UR$Gender)
fviz_pca_biplot(PCA(data_All, ncp = 6, scale.unit = TRUE, graph = F, quali.sup = 7), axes = c(1, 2), repel = TRUE, habillage = 7)

Biplot de Variables y Registros [Total R]
data_UR <- Admission_Dataset_Initial[,-c(1,2,9)]
data_All <- cbind(Admission_Dataset_Initial[,-c(1,2,8,9)], data_UR$Research)
fviz_pca_biplot(PCA(data_All, ncp = 6, scale.unit = TRUE, graph = F, quali.sup = 7), axes = c(1, 2), repel = TRUE, habillage = 7)

Coordenadas Individuales [Subconjunto UR]
set.seed(780728)
data_61_UR <- Admission_Dataset_Initial[sample(1:nrow(Admission_Dataset_Initial),61),-c(1,2,8)]
set.seed(780728)
data_61 <- cbind(Admission_Dataset_Initial[sample(1:nrow(Admission_Dataset_Initial),61),-c(1,2,8,9)], data_61_UR$University_Rating)
head(PCA(data_61, ncp = 6, scale.unit = T, graph = F, quali.sup = 7)$ind$coord, n = 61L)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6
## 1 2.68761751 0.02450021 -0.174588047 -0.3744681469 0.20243105 0.09714639
## 2 -0.68733407 0.09559234 -0.429878544 0.3006483758 0.55882375 -0.41539839
## 3 -2.66688446 0.99297045 -0.154631808 0.2955375778 0.91070623 -0.54643606
## 4 -2.60547963 0.90034536 -0.019614410 -0.0213467292 -0.11686267 0.21276009
## 5 1.08112756 0.40126269 0.092843433 0.0881547303 -0.54870098 0.12868982
## 6 1.84519346 0.73863622 0.122725654 0.3044756351 -0.25870078 -0.29131881
## 7 -0.58747951 -0.02256539 0.456341153 -1.2163134978 -0.01333260 -0.94317535
## 8 4.01404297 0.07462346 0.109467778 -0.6287994639 0.60476060 -0.09211162
## 9 -0.91086676 0.33014131 -0.213824989 -0.4796112753 -0.27321962 0.17828584
## 10 1.99972822 -0.51428654 -0.239308944 -0.1615319470 0.04151905 -0.01116718
## 11 -0.95952733 -0.26982240 -0.628357160 -0.2695572128 -0.41111602 0.24409785
## 12 -0.19766524 -0.28396958 -0.159860979 -0.1187760407 -0.35433595 0.16222254
## 13 -0.11229774 0.04922496 -0.520651363 -0.2764481615 -0.23244849 0.60623579
## 14 1.31908921 -0.83063861 0.459124717 0.0260651127 -0.26542984 -0.06860382
## 15 0.72561624 0.69347072 0.441628837 -0.4125443603 1.09108940 0.54905112
## 16 -3.05518824 -1.00327852 -0.517772977 0.0169673161 0.11745016 -0.48627516
## 17 -0.32128795 1.31505890 -0.334220920 0.5188724696 -0.63373067 -0.31543233
## 18 0.59398643 1.05012623 0.823718459 0.0006562314 0.39817645 0.37906406
## 19 4.31763412 -0.76639535 0.305614507 0.3514348648 0.06165635 0.10729655
## 20 -2.66850653 -0.88007178 -1.150343969 0.4998803377 0.64189881 0.47161684
## 21 2.49833145 0.33680478 -0.497108151 -0.1493167937 0.73518345 -0.01616226
## 22 4.42861912 -1.19651010 -0.065398012 -0.0662251616 -0.12480678 -0.21829986
## 23 -0.10138583 0.26657454 1.025802277 0.1844089350 -0.23952973 0.21237382
## 24 0.77832836 0.51483734 -0.586749977 -0.3660228511 -0.22881809 0.03093306
## 25 -3.34603035 -0.73197519 0.572679946 -0.2522335792 0.45386536 0.58574083
## 26 -1.12156436 0.47009460 0.710676700 -0.2693120533 0.03905343 0.28650198
## 27 1.12573128 -0.17577080 -0.100141703 -0.1546231843 -0.24919779 -0.45040087
## 28 3.07067126 0.35323879 0.757028987 0.4247162580 -0.12499666 -0.09729370
## 29 -2.92576647 0.11991747 0.250445228 -0.2299849763 0.13108636 0.13961852
## 30 -1.57082897 0.82519550 0.448043093 -0.0817267972 -0.19123476 -0.01806606
## 31 3.88893564 0.20786100 0.370786584 0.4214452559 -0.27081769 0.18277722
## 32 -0.09514144 0.11557851 0.021320640 0.6302141984 0.72768874 -0.64366773
## 33 0.08471986 1.61655715 -0.188909993 -0.7008855995 0.13920525 -0.02845328
## 34 -0.59184199 -0.22876447 -0.926126623 -0.2235325185 -0.17851703 0.48899087
## 35 -3.27720201 -0.87836770 0.823764048 -0.3562505606 0.97461197 0.27193935
## 36 -1.00907062 -0.60981916 -0.366548178 -0.0095160479 -0.74853286 -0.07287862
## 37 -3.44740002 0.09518884 -0.279026284 1.2727724524 -0.29958247 -0.03048890
## 38 -0.61814715 1.35139235 -0.147464086 0.5287327428 -0.26151384 0.23159263
## 39 -0.95360489 0.60765498 -0.840617577 0.0538599827 -0.37791331 0.27308231
## 40 -0.50218812 -0.31602204 -0.856741467 -0.2330804793 -0.02917330 0.27512267
## 41 2.10626250 -1.04424439 -0.963150163 0.3392035768 0.31987492 0.03821925
## 42 1.28322709 -0.62926111 0.441965914 -0.3562454098 -0.40127799 0.01056439
## 43 2.86084387 -0.97743658 -0.189055903 -0.3257769792 -0.24103693 -0.02533912
## 44 0.11095420 0.09104799 0.329152682 -0.2503309611 -0.05860961 -0.31122317
## 45 0.86048677 -1.06837705 1.669752773 0.7807790722 -0.18776456 0.15605708
## 46 -2.01348062 -0.35196960 0.153198506 -0.2101122481 -0.33640760 -0.24733626
## 47 0.49914560 0.99619621 0.203342566 -0.6055245095 -0.15223639 -0.39848712
## 48 -0.18678673 0.07290830 0.277304278 0.2073225308 -0.11177696 0.50750739
## 49 0.53103836 0.64282486 -0.737406584 0.0797141721 0.64352663 0.29279878
## 50 -3.35949243 -0.44687930 0.006172428 -0.0045161417 -0.38323628 -0.43416026
## 51 -1.76561250 -0.71357365 0.119940618 0.3131484601 -0.39483497 -0.13067773
## 52 -0.61646599 0.78723572 0.792587313 0.0458368814 -0.47170228 -0.07547270
## 53 -1.13208355 0.23098651 0.334020200 -0.9375383689 -0.14012116 -0.18977532
## 54 -0.27645335 1.39981251 -0.625640992 0.8891418808 -0.14251466 -0.21940402
## 55 2.88576942 1.38441807 -0.193040456 0.1296641060 -0.02106329 0.03478427
## 56 -5.04977695 -0.90629264 0.026357340 -0.5769148808 0.38735732 -0.21288001
## 57 1.92705611 -0.90735952 -0.718194109 -0.2719132197 -0.22644798 -0.26096780
## 58 3.43755620 -1.17933752 -0.453693737 -0.0563528841 0.04013918 0.18174093
## 59 0.07536328 -0.43227807 0.549529614 0.5870839780 0.36357097 0.78670503
## 60 0.69062813 -0.65223897 0.232067290 1.0279357809 0.99227537 -0.88356806
## 61 -2.99486239 -1.13477288 0.350664541 0.3286601252 -0.87440821 0.01140428
Biplot de Variables y Registros [Subconjunto UR]
set.seed(780728)
data_61_UR <- Admission_Dataset_Initial[sample(1:nrow(Admission_Dataset_Initial),61),-c(1,2,8)]
set.seed(780728)
data_61 <- cbind(Admission_Dataset_Initial[sample(1:nrow(Admission_Dataset_Initial),61),-c(1,2,8,9)], data_61_UR$University_Rating)
fviz_pca_biplot(PCA(data_61, ncp = 6, scale.unit = T, graph = F, quali.sup = 7), axes = c(1, 2), repel = T, habillage = 7)

Objetivo y Anotaciones :: Fase 3
[Correspondencias]
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.
11. Correspondencias Simples
Con base en el trabajo de (Aldás & Uriel,
2017) se sabe que el análisis de correspondencias simple
(ACS) busca representar en un espacio multidimensional reducido la
relación que exista 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 expliquen 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áslisis de correspondencias
múltiples (ACM), con base en una objeto llamado tabla disyuntiva
completa.
Esta sección trata el análisis de correspondecias simple con base en
pares de variables categóricas del conjunto de datos descrito en la sección 2. Complementariamente, la sección 12 muestra el análisis de correspondencias
múltiples con base en las varaibles categóricas del mismo conjunto de
datos.
11.1. 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.
11.2. 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 simple (binario) entre cada par de
varaibles categóricas del conjunto de datos: Gender,
Research y University_Rating. 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
Gender vs. Research se encontró que 80
estudiantes de un total de 151 de sexo femenino adjuntaron evidencias de
participación en actividades de investigación; además, de los 181
estudiantes que no argumentaron investigación, de un total de 400
postulados, 71 son de sexo femenino y 110 de sexo masculino. En la tabla
de contingencias Gender
vs. University_Rating se calculó que 14 estudiantes de
un total de 249 de sexo masculino presentaron aspiraciones de ingreso a
unna universidad de una estrella; además, de los 60 estudiantes que
presentaron solicitudes de ingreso a universidades de cinco estrellas,
23 eran de sexo femenino y 37 de sexo masculino. Por último, en la tabla
de contingencia Research
vs. University_Rating se puede determinar que 59
estudiantes, de un total de 219, que presentaron evidencias de haber
participado en procesos de investigación, presentaron sus aspiraciones
de ingreso en universidades de cuatro estrellas; además, 75 estudiantes,
de un total de 107, que se postularon en universidades de dos estrellas,
lo hicieron sin evidenciar participación en procesos de
investigación.
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
examininados. En este sentido, a nivel de ejemplo se presentan algunas
lecturas de ellas: en la tabla de probabilidades Gender
vs. Research el \(20.00\) \(\%\) del total de estudiantes son de sexo
femenino que presentaron evidencias en su aplicación de haber
participado en procesos de investigación; además, el \(45.25\) \(\%\) del total de estudiantes no argumentó
en su postulación haber participado en procesos de investigación, donde
el \(17.75\) \(\%\) eran hombres y el \(27.50\) \(\%\) mujeres. En la tabla de probabilidades
Gender vs. University_Rating que el
\(3.50\) \(\%\) del total de estudiantes fueron
hombres que presentaron sus postulaciones a universidades de una
estrella; además, del \(15.00\) \(\%\) de postulados a universidades de cinco
estrellas, aditivamente el \(9.25\)
\(\%\) eran hombres y el \(5.75\) \(\%\) mujeres. Por último, en la tabla de
probabilidades Research
vs. University_Rating el \(14.75\) \(\%\) del total de estudiantes presentaron
evidencias de participación en procesos investigativos y se postularon a
universidades de cuatro estrellas; además, el \(18.75\) \(\%\) del total de estudiantes se postularon
para ingresar a universidades de dos estrellas sin presentar evidencias
de haber participado en procesos de investigación.
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 siguientes lecturas de ejemplo: según la matriz
de frecuencias CPF de Gender
vs. Research de los estudiantes de sexo femenino el
\(52.98\) \(\%\) se postuló presentando evidencias de
haber participado en procesos de investigación, por otro lado, entre los
estudiantes de sexo masculino lo hizo el \(55.82\) \(\%\); además, según la misma matriz pero
condicionada por columnas, el \(39.23\)
\(\%\) de los estudiantes que no
presentaron evidencias de haber participado en procesos de investigación
fueron de sexo femenino, mientras que el \(60.77\) \(\%\) eran de sexo masculino. Ahora, según
la matriz de frecuencias CPF de Gender
vs. University_Rating el \(5.62\) \(\%\) de los estudiantes de sexo masculino
se postuló a universidades de una estrella, 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
estudiantes que se presentaron a universidades de una estrella el \(46.15\) \(\%\) fueron mujeres y el \(53.85\) \(\%\) hombres. Por último, según la matriz
de frecuencias CPF de Research
vs. University_Rating solo el \(4.42\) \(\%\) de los estudiantes que no evidenciaron
participaciones en procesos de investigación se postularon para
universidades de cinco estrellas, mientras que a ellas se presentaron el
\(23.74\) \(\%\) de estudiantes que sí tenían
evidencias de participación en dichos procesos. Complementariamente,
según la misma matriz pero condicionada por columnas, el \(13.33\) \(\%\) del total de estudiantes que se
presentaron a universidades de cinco estrellas estos no argumentaron
haber participado en procesos de investigación, 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 Gender y
Research 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 estudiantes de sexo masculino y femenino que se postularon sin
credenciales investigativas fueron, respectivamente, \(44.18\) \(\%\) y \(47.02\) \(\%\); también, (perfiles columna) la
proporción de estudiantes de sexo femenino que se postularon con o sin
credenciales fueron, respectivamente, \(36.53\) \(\%\) y \(39.23\) \(\%\). Asimismo, los perfiles fila y columna
que corresponden con las variables Gender y
University_Rating muestran distribuciones marginales
cercanas entre sí, por ejemplo: (perfiles fila) las proporciones de
estudiantes de sexo masculino y femenino que se postularon a
universidades de tres estrellas fueron, respectivamente, \(32.13\) \(\%\) y \(35.10\) \(\%\); también, (perfiles columna) la
proporción de estudiantes de sexo femenino que se presentaron a
universidades de cinco, tres y dos estrellas fueron, respectivamente,
\(38.33\) \(\%\), \(39.85\) \(\%\) y \(38.32\) \(\%\). Por último, los perfiles fila y
columna que corresponden con las variables Research y
University_Rating muestran distribuciones marginales
lejanas entre sí, por ejemplo: (perfiles fila) las proporciones de
estudiantes que se presentaron sin o con credenciales de investigación a
universidades de cinco estrellas fueron: \(4.42\) \(\%\) y \(23.74\) \(\%\); también, (perfiles columna) la
proporción de estudiantes que presentaron credenciales de investigación
para postularse en universidades de cinco, tres y dos estrellas 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 Gender
vs. Research y Gender
vs. University_Rating 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 \(\alpha = 0.05\), las
hipótesis formuladas fueron:\[H_0: \text {Las
variables categóricas son independientes}\] \[H_1: \text {las variables categóricas son
dependientes}\]Asimismo, el par de variables que tuvo las pruebas
a favor de la dependencia fueron Research y
University_Rating, en esta prueba el \(p-valor\) resultó menor o igual que el
nivel de significancia y, comparativamente, el valor del estadístico
\(\chi^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: Research y UR: University_Rating) 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 residuales de Pearson y
estandarizados muestran que las mayores desviaciones respecto a los
valores esperados ocurren entre las universidades de cinco, cuatro, dos
y una estrella. Asimismo, en la sub-pestaña Contribuciones
[R-UR] puede apreciarse, comentado lo anterior, que el valor
tres estrellas de la variable University_Rating
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
simple 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 palno de factores es irrealizable.
Sin embargo, es posible hacer una interpretación unidimensional de los
resultados. Al ser requeridas las variables de soporte del AC, primero
por columnas y luego por filas, las coordenadas proyectadas de la
variable University_Rating en relación con las
categorías de cinco y cuatro estrellas se presentan del lado positivo
del eje dimensional creando oposiciones binarias con, respectivamente,
cinco estrellas con una estrella y cuatro estrellas con dos estrellas,
mientras que las universidades de tres estrellas se enccuentra
técnicamente en el centro del eje. Así mismo, los tipos de universidades
cinco, cuatro, dos y de una estrella, son las que más contribuyen en la
configuración de la dimensión, de nuevo quedan rezagadas las
universidades de tres estrellas. Además, es determinante que la calidad
de representación alcanza el máximo con cada una de las variables. Un
comportamiento semejante a lo expuesto puede apreciarse con la variable
fila Research, 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, postiva o negativa,
entre filas y columnas, las categorías (de las respectivas variables)
cinco y cuatro estrellas con research, y una y dos estrellas con
no-research.
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
Contingencias
addmargins(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research))
##
## no-research research Sum
## F 71 80 151
## M 110 139 249
## Sum 181 219 400
addmargins(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating))
##
## five_stars four_stars one_star three_stars two_stars Sum
## F 23 22 12 53 41 151
## M 37 52 14 80 66 249
## Sum 60 74 26 133 107 400
addmargins(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))
##
## five_stars four_stars one_star three_stars two_stars Sum
## no-research 8 15 21 62 75 181
## research 52 59 5 71 32 219
## Sum 60 74 26 133 107 400
Probabilidades
addmargins(prop.table(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research))*100)
##
## no-research research Sum
## F 17.75 20.00 37.75
## M 27.50 34.75 62.25
## Sum 45.25 54.75 100.00
addmargins(prop.table(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating))*100)
##
## five_stars four_stars one_star three_stars two_stars Sum
## F 5.75 5.50 3.00 13.25 10.25 37.75
## M 9.25 13.00 3.50 20.00 16.50 62.25
## Sum 15.00 18.50 6.50 33.25 26.75 100.00
addmargins(prop.table(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))*100)
##
## five_stars four_stars one_star three_stars two_stars Sum
## no-research 2.00 3.75 5.25 15.50 18.75 45.25
## research 13.00 14.75 1.25 17.75 8.00 54.75
## Sum 15.00 18.50 6.50 33.25 26.75 100.00
Frecuencias [CPF y CPC]
round(addmargins(prop.table(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research), 1)*100, 2), 2)
##
## no-research research Sum
## F 47.02 52.98 100.00
## M 44.18 55.82 100.00
round(addmargins(prop.table(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research), 2)*100, 1), 2)
##
## no-research research
## F 39.23 36.53
## M 60.77 63.47
## Sum 100.00 100.00
round(addmargins(prop.table(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating), 1)*100, 2), 2)
##
## five_stars four_stars one_star three_stars two_stars Sum
## F 15.23 14.57 7.95 35.10 27.15 100.00
## M 14.86 20.88 5.62 32.13 26.51 100.00
round(addmargins(prop.table(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating), 2)*100, 1), 2)
##
## five_stars four_stars one_star three_stars two_stars
## F 38.33 29.73 46.15 39.85 38.32
## M 61.67 70.27 53.85 60.15 61.68
## Sum 100.00 100.00 100.00 100.00 100.00
round(addmargins(prop.table(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating), 1)*100, 2), 2)
##
## five_stars four_stars one_star three_stars two_stars Sum
## no-research 4.42 8.29 11.60 34.25 41.44 100.00
## research 23.74 26.94 2.28 32.42 14.61 100.00
round(addmargins(prop.table(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating), 2)*100, 1), 2)
##
## five_stars four_stars one_star three_stars two_stars
## no-research 13.33 20.27 80.77 46.62 70.09
## research 86.67 79.73 19.23 53.38 29.91
## Sum 100.00 100.00 100.00 100.00 100.00
Perfiles [CPF y CPC]
plotct(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research),"row")

plotct(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research),"col")

plotct(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating),"row")

plotct(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating),"col")

plotct(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating),"row")

plotct(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating),"col")

Pruebas de Hipótesis
chisq.test(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research))
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$Research)
## X-squared = 0.20268, df = 1, p-value = 0.6526
chisq.test(table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating))
##
## Pearson's Chi-squared test
##
## data: table(Admission_Dataset_Initial$Gender, Admission_Dataset_Initial$University_Rating)
## X-squared = 3.0799, df = 4, p-value = 0.5445
chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))
##
## Pearson's Chi-squared test
##
## data: table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating)
## X-squared = 83.306, df = 4, p-value < 2.2e-16
AC Pareja Única
Contingencias y Residuales [R-UR]
chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))$observed
##
## five_stars four_stars one_star three_stars two_stars
## no-research 8 15 21 62 75
## research 52 59 5 71 32
chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))$expected
##
## five_stars four_stars one_star three_stars two_stars
## no-research 27.15 33.485 11.765 60.1825 48.4175
## research 32.85 40.515 14.235 72.8175 58.5825
chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))$residuals
##
## five_stars four_stars one_star three_stars two_stars
## no-research -3.6752244 -3.1944368 2.6924084 0.2342822 3.8202751
## research 3.3411894 2.9040998 -2.4476999 -0.2129887 -3.4730567
chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))$stdres
##
## five_stars four_stars one_star three_stars two_stars
## no-research -5.3874386 -4.7821527 3.7630767 0.3875445 6.0325199
## research 5.3874386 4.7821527 -3.7630767 -0.3875445 -6.0325199
Contribuciones [R-UR]
chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))$residuals^2/chisq.test(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating))$statistic*100
##
## five_stars four_stars one_star three_stars two_stars
## no-research 16.21400512 12.24929770 8.70170691 0.06588722 17.51910304
## research 13.40061611 10.12384879 7.19182169 0.05445474 14.47925868
Correspondencia Simple Unidimensional [R-UR]
CA(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating), graph = FALSE)$eig
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.2082655 100 100
CA(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating), graph = FALSE)$col
## $coord
## [,1]
## five_stars 0.6412335
## four_stars 0.5018644
## one_star -0.7136121
## three_stars -0.0274550
## two_stars -0.4991266
##
## $contrib
## [,1]
## five_stars 29.614621
## four_stars 22.373146
## one_star 15.893529
## three_stars 0.120342
## two_stars 31.998362
##
## $cos2
## [,1]
## five_stars 1
## four_stars 1
## one_star 1
## three_stars 1
## two_stars 1
##
## $inertia
## [1] 0.0616770521 0.0465955553 0.0331007438 0.0002506308 0.0666415622
CA(table(Admission_Dataset_Initial$Research, Admission_Dataset_Initial$University_Rating), graph = FALSE)$row
## $coord
## no-research research
## -0.5019859 0.4148833
##
## $contrib
## no-research research
## 54.75 45.25
##
## $cos2
## no-research research
## 1 1
##
## $inertia
## [1] 0.11402539 0.09424016
12. Correspondencias Múltiples
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últiple (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 varaibles categóricas se espera
obtener una representación en el primer plano factorial.
12.1. 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 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.
12.2. 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últiple (ACM) entre las variables
categóricas del conjunto de datos descrito en la sección
2.
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: Gender,
University_Rating y Research. 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 varianza 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 estudiantes representados por puntos azules
sobrepuestos que indican coordenadas de convergencia y las asociaciones
entre algunas categorías de las variables y conjuntos de estudiantes.
Cabe anotar que las semejanzas entre categoría de las variables están
presentadas por sus coordenas 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:
one_stars, two_stars, F y no-research por un lado, por otro, five_stars,
four_stars, M y research, así como ciertos grupos evidentes de
estudiantes. Complementariamente, a nivel de asociación se destaca la
del grupo de estudiantes cercanos a two_stars y la de otro grupo nutrido
cercano a four_stars. En general se pueden visualizar fácilmente las
asociaciones entre las categorías de las variables y los grupos de
estudiantes afines con ellas.
Seguidamente, la pestaña Calidad de Representación
muestra que las categorías de la variable Research
fueron las mejor representadas, en oposición a las categorías one_star y
three_strars de la variable University_Rating. 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 three_stars la
presenta. La matriz de calidad de representación evidencia numéricamente
la situación mencionada: para ella la suma de los cosenos cuadrados en
las dimensiones del primer plano plano factorial solo ascienden a \(0.09\), seguida de one_star que suma \(0.18\).
Complementariamente, la pestaña Contribuciones
muestra que para las dimensiones del primer plano factorial, y en
concordancia con lo expresado en el párrafo anterior, las categorías de
la variable University_Rating: one_star y three_stars,
en ambas dimensiones quedan por debajop de la línea media de
contribución, mientras que las categorías de la misma variable:
four_stars y five_stars, aportan en ambos casos por enncima de la línea
media. En este sentido, en la pestaña Biplot con
Contribuciones se ´visualiza una representación en el primer
plano factorial semejante a la obtenida en la pestaña calidad de
Representación.
ACM
round(MCA(Admission_Dataset_Initial[1:400, -c(1,3,4,5,6,7,10)], graph = FALSE)$eig,2)
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.49 24.39 24.39
## dim 2 0.36 17.77 42.16
## dim 3 0.33 16.67 58.83
## dim 4 0.33 16.67 75.50
## dim 5 0.31 15.46 90.95
## dim 6 0.18 9.05 100.00
Biplot ACM
fviz_mca_biplot(MCA(Admission_Dataset_Initial[1:400, -c(1,3,4,5,6,7,10)], graph = FALSE), repel = TRUE)

Calidad de Representación
fviz_mca_var(MCA(Admission_Dataset_Initial[1:400, -c(1,3,4,5,6,7,10)], graph = FALSE), col.var ="cos2", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)

MCA(Admission_Dataset_Initial[1:400, -c(1,3,4,5,6,7,10)], graph = FALSE)$var$cos2
## Dim 1 Dim 2 Dim 3 Dim 4 Dim 5
## F 0.022900818 0.498308895 2.554960e-29 4.720861e-39 0.47790244
## M 0.022900818 0.498308895 2.787969e-29 1.349092e-31 0.47790244
## no-research 0.716530767 0.008125276 4.802834e-29 2.529855e-31 0.00571241
## research 0.716530767 0.008125276 4.969681e-29 6.103069e-31 0.00571241
## five_stars 0.240330906 0.177277183 3.799446e-01 1.101815e-03 0.10790338
## four_stars 0.213771791 0.265633197 5.310651e-02 1.393417e-01 0.25154509
## one_star 0.128521905 0.053547982 1.386161e-02 6.998290e-01 0.05726901
## three_stars 0.002057811 0.089900789 5.691895e-01 2.649186e-01 0.07335710
## two_stars 0.305912712 0.112570001 3.288337e-01 7.416609e-02 0.06078939
Contribuciones
fviz_contrib(MCA(Admission_Dataset_Initial[1:400, -c(1,3,4,5,6,7,10)], graph = FALSE), choice = "var", axes = 1, top = 15)

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

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

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

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

Biplot con Contribuciones
fviz_mca_var(MCA(Admission_Dataset_Initial[1:400, -c(1,3,4,5,6,7,10)], graph = FALSE), col.var ="contrib", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)

Objetivo y Anotaciones :: Fase 4
[Conglomerados]
En términos generales, esta cuarta etapa de estudio mostrará
cálculos, visualizaciones e interpretaciones con base en el conjunto de
datos tratado 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 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 12 de marzo
de 2023.
13. Agrupación Jerárquica
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 relativamente baja densidad de puntos. 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 similaridades que
permiten una representación gráfica conocida como dendograma.
13.1. Planteamiento del Problema
Con base en las variables cuantitativas del conjunto de datos
descrito en la sección 2 se demanda desarrollar el
análisis de conglomerados con base agrupaciones jerárquicas que se
representen 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.
13.2. 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 descrito en la sección 2.
Con el fin de visualar 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
categórica clasificadora: Nationality. 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 registrase para cada
estudante extranjero su nacionalidad. Como las proporciones de
participación de las nacionalidades de los estudiantes fueron
diferentes, pero conocidas, el método de asignación fue aleatorio y
ponderado con base en ellas (véase la pestaña Campo
Clasificador). Cabe mencionar que la asignación se hizo
directamente en el libro de cálculo con base en la fórmula
=INDICE([RANGO_DE_ETIQUETAS];
CONTAR.SI([RANGO_DE_PROPORCIONES_ACUMULADAS]; “<=” & ALEATORIO())
+ 1) para 400 registros. Además, el campo
Nationality registra junto con la nacionalidad del
estudiante la posición que ocupa dicho país como aportante de
estudiantes extranjeros en el periodo de medición. Segundo, se
estandarizaron en una escala de \(0\) a
\(1\) 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 mostrado en la pestaña
Conjunto Modificado, esta 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 Nationality. Con base en una escala de
colores que indica las distancias entre las observaciones, puede
observarse que valores como: Taiwán, Alemania e Indonesia están
intensamente distantes del resto. También, por ejemplo, en oposición a
los valores mencionados, Tailandia, Malasia y Colombia son menos
disímiles. 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 deberían configurarse de tal forma que las heurísticas
usadas entregaran 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 (por ejemplo, la similaridad entre los
valores de Tailandia y Malasia por un lado, y Alemanania y Taiwan por
otro, a conglomerarse), 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
decisorios sobre la cantidad de conglomerados óptimos precalculados. Es
decir, el dendograma de Enlace Simple que se creó con
base en tres conglomerados a un nivel de similitud de aproximadamente
\(2.3\) 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 el primero, a un nivel de similitud de
aproximadamente \(5.0\) se visualizan
tres conglomerados de 7, 1, y 16 observaciones, contadas de izquierda a
derecha; en el segundo, a un nivel de similitud superior a \(3.5\) se aprecian cuatro conglomerados
conformados por 1, 2, 1 y 20 observaciones, contadas de izquierda a
derecha. En ambos casos, se entiende que si los dendogramas se cortaran
más arriba de los respectivos niveles de similitud indicados, entonces
resultarían menos conglomerados finales, con niveles de similitud mayor;
opuestamente, si fuesen cortados más abajo, entonces los niveles de
similitud serían menores, pero serían obtenidos más conglomerados
finales, de ahí el cálculo del núemro óptimo de conglomerados.
Campo Clasificador
as.data.frame(Nationalities)[1:24,-c(4,5,6)]
## Nationality Ratio Cumulative_Ratio
## 1 1. China 0.353 0.353
## 2 2. India 0.183 0.536
## 3 3. Corea del Sur 0.058 0.594
## 4 4. Arabia Saudita 0.035 0.629
## 5 5. Canadá 0.031 0.660
## 6 6. Vietnam 0.025 0.685
## 7 7. Brasil 0.023 0.708
## 8 8. Taiwán 0.021 0.729
## 9 9. Japón 0.018 0.747
## 10 10. México 0.016 0.763
## 11 11. Nepal 0.014 0.777
## 12 12. Irán 0.013 0.790
## 13 13. Turquía 0.012 0.802
## 14 14. Colombia 0.012 0.814
## 15 15. Nigeria 0.010 0.824
## 16 16. Tailandia 0.009 0.833
## 17 17. Indonesia 0.009 0.842
## 18 18. Francia 0.009 0.851
## 19 19. Malasia 0.008 0.859
## 20 20. Filipinas 0.008 0.867
## 21 21. Pakistán 0.008 0.875
## 22 22. Alemania 0.007 0.882
## 23 23. Reino Unido 0.007 0.889
## 24 24. Otros países 0.111 1.000
Conjunto Modificado
head(as.data.frame(Admission_Dataset_Initial_Nat_Average))
## Nationality Average_GRE_Score_S01 Average_TOEFL_Score_S01 Average_SOP_S01
## 1 1. China 0.7237676 0.9003521 0.6838028
## 2 10. México 0.7652778 0.9055556 0.7555556
## 3 11. Nepal 0.7500000 0.9145833 0.7750000
## 4 12. Irán 0.6714286 0.8833333 0.6714286
## 5 13. Turquía 0.7875000 0.8976190 0.6714286
## 6 14. Colombia 0.5875000 0.8854167 0.5750000
## Average_LOR _S01 Average_CGPA_S01 Average_Chance_of_Admit _S01
## 1 0.6978873 0.8635141 0.7395070
## 2 0.7333333 0.8705556 0.7622222
## 3 0.8500000 0.8907500 0.7550000
## 4 0.7285714 0.8457143 0.7314286
## 5 0.7000000 0.8664286 0.7742857
## 6 0.6500000 0.8435000 0.6975000
str(as.data.frame(Admission_Dataset_Initial_Nat_Average))
## 'data.frame': 24 obs. of 7 variables:
## $ Nationality : chr "1. China" "10. México" "11. Nepal" "12. Irán" ...
## $ Average_GRE_Score_S01 : num 0.724 0.765 0.75 0.671 0.787 ...
## $ Average_TOEFL_Score_S01 : num 0.9 0.906 0.915 0.883 0.898 ...
## $ Average_SOP_S01 : num 0.684 0.756 0.775 0.671 0.671 ...
## $ Average_LOR _S01 : num 0.698 0.733 0.85 0.729 0.7 ...
## $ Average_CGPA_S01 : num 0.864 0.871 0.891 0.846 0.866 ...
## $ Average_Chance_of_Admit _S01: num 0.74 0.762 0.755 0.731 0.774 ...
Disimilaridad
data_ = as.data.frame(Admission_Dataset_Initial_Nat_Average)[, -c(1)]
rownames(data_) = unclass(Admission_Dataset_Initial_Nat_Average$Nationality)
fviz_dist(get_dist(data_, stand = T, method = "euclidean"), gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))

Optimización de Mojena
Unión Simple
hc_single = hclust(get_dist(data_, stand = T, method = "euclidean"), method = "single")
mojena = function(hc){
n_hd = length(hc$height)
alp_g = 0 ; alpha = hc$height[n_hd:1]
for(i in 1:(n_hd-1)){
alp_g[i] = mean(alpha[(n_hd-i+1):1])+1.25*sd(alpha[(n_hd-i+1):1])
}
nog = sum(alp_g<= alpha[-n_hd]) + 1
plot(alpha[-n_hd], pch=20, col=(alp_g>alpha[-n_hd])+1, main = paste("Optimal number of groups =",nog),
ylab = expression(alpha[g]), xlab="Nodes")}
mojena(hc_single)

Unión Completa
hc_complete = hclust(get_dist(data_, stand = T, method = "euclidean"), method = "complete")
mojena = function(hc){
n_hd = length(hc$height)
alp_g = 0 ; alpha = hc$height[n_hd:1]
for(i in 1:(n_hd-1)){
alp_g[i] = mean(alpha[(n_hd-i+1):1])+1.25*sd(alpha[(n_hd-i+1):1])
}
nog = sum(alp_g<= alpha[-n_hd]) + 1
plot(alpha[-n_hd], pch=20, col=(alp_g>alpha[-n_hd])+1, main = paste("Optimal number of groups =",nog),
ylab = expression(alpha[g]), xlab="Nodes")}
mojena(hc_complete)

Unión Promedio
hc_average = hclust(get_dist(data_, stand = T, method = "euclidean"), method = "average")
mojena = function(hc){
n_hd = length(hc$height)
alp_g = 0 ; alpha = hc$height[n_hd:1]
for(i in 1:(n_hd-1)){
alp_g[i] = mean(alpha[(n_hd-i+1):1])+1.25*sd(alpha[(n_hd-i+1):1])
}
nog = sum(alp_g<= alpha[-n_hd]) + 1
plot(alpha[-n_hd], pch=20, col=(alp_g>alpha[-n_hd])+1, main = paste("Optimal number of groups =",nog),
ylab = expression(alpha[g]), xlab="Nodes")}
mojena(hc_average)

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

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

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

14. Agrupación 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 \(n\) objetos en \(k\) grupos, lo hace al escoger 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.
14.1. Planteamiento del Problema
Con base en las variables cuantitativas del conjunto de datos
descrito 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.
14.2. 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 descrito 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),
determinó 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, estableció 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 combinaciones de
número de conglomerados, medidas de distancia y métodos de conglomerado,
determinó 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 cercana 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 \(85.4\)
\(\%\) 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
contenía a China que absorbe a todo el conglomerado que contenía 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, generaron 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
Elbow
fviz_nbclust(data_, kmeans, method = "wss") + geom_vline(xintercept = 3, linetype = 2)

Silhouette
fviz_nbclust(data_, kmeans, method = "silhouette")

Gap Statistic
fviz_nbclust(data_, kmeans, method = "gap_stat")

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

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

## *** : The D index is a graphical method of determining the number of clusters.
## In the plot of D index, we seek a significant knee (the significant peak in Dindex
## second differences plot) that corresponds to a significant increase of the value of
## the measure.
##
## *******************************************************************
## * Among all indices:
## * 9 proposed 2 as the best number of clusters
## * 1 proposed 3 as the best number of clusters
## * 3 proposed 4 as the best number of clusters
## * 1 proposed 5 as the best number of clusters
## * 2 proposed 6 as the best number of clusters
## * 2 proposed 7 as the best number of clusters
## * 6 proposed 10 as the best number of clusters
##
## ***** Conclusion *****
##
## * According to the majority rule, the best number of clusters is 2
##
##
## *******************************************************************
## KL CH Hartigan CCC Scott Marriot TrCovW TraceW
## Number_clusters 7.0000 2.0000 6.0000 2.0000 10.0000 4 5e+00 4.0000
## Value_Index 19.5453 16.2126 4.0447 20.8994 41.2452 0 7e-04 0.0218
## Friedman Rubin Cindex DB Silhouette Duda PseudoT2
## Number_clusters 10.00 7.0000 10.000 10.000 2.0000 2.0000 2.0000
## Value_Index 11400.81 -128.9452 0.042 0.724 0.3989 0.8208 3.2753
## Beale Ratkowsky Ball PtBiserial Frey McClain Dunn
## Number_clusters 2.0000 2.000 3.0000 4.0000 2.0000 2.000 10.0000
## Value_Index 0.7906 0.437 0.0487 0.5674 5.8425 0.366 0.2686
## Hubert SDindex Dindex SDbw
## Number_clusters 0 6.0000 0 10.0000
## Value_Index 0 27.7721 0 0.0927
Resultados K-means
K-óptimo [wws]
set.seed(780728)
print(kmeans(data_, 3, nstart = 25))
## K-means clustering with 3 clusters of sizes 5, 14, 5
##
## Cluster means:
## Average_GRE_Score_S01 Average_TOEFL_Score_S01 Average_SOP_S01
## 1 0.6057500 0.8748333 0.5880000
## 2 0.6908445 0.8863805 0.6788959
## 3 0.7669444 0.9082429 0.7226190
## Average_LOR _S01 Average_CGPA_S01 Average_Chance_of_Admit _S01
## 1 0.5815000 0.8282300 0.6591000
## 2 0.6821275 0.8537663 0.7090436
## 3 0.7166667 0.8844579 0.7872275
##
## Clustering vector:
## 1. China 10. México 11. Nepal 12. Irán
## 2 3 3 2
## 13. Turquía 14. Colombia 15. Nigeria 16. Tailandia
## 3 1 2 1
## 17. Indonesia 18. Francia 19. Malasia 2. India
## 3 2 2 2
## 20. Filipinas 21. Pakistán 22. Alemania 23. Reino Unido
## 2 2 1 1
## 24. Otros países 3. Corea del Sur 4. Arabia Saudita 5. Canadá
## 3 2 2 2
## 6. Vietnam 7. Brasil 8. Taiwán 9. Japón
## 2 2 1 2
##
## Within cluster sum of squares by cluster:
## [1] 0.05248085 0.05772177 0.05814394
## (between_SS / total_SS = 56.5 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
K-óptimo [sil]
set.seed(780728)
print(kmeans(data_, 2, nstart = 25))
## K-means clustering with 2 clusters of sizes 6, 18
##
## Cluster means:
## Average_GRE_Score_S01 Average_TOEFL_Score_S01 Average_SOP_S01
## 1 0.6157292 0.8759028 0.5983333
## 2 0.7133845 0.8927385 0.6926466
## Average_LOR _S01 Average_CGPA_S01 Average_Chance_of_Admit _S01
## 1 0.5887500 0.8301083 0.6596667
## 2 0.6948955 0.8630843 0.7333471
##
## Clustering vector:
## 1. China 10. México 11. Nepal 12. Irán
## 2 2 2 2
## 13. Turquía 14. Colombia 15. Nigeria 16. Tailandia
## 2 1 2 1
## 17. Indonesia 18. Francia 19. Malasia 2. India
## 2 2 1 2
## 20. Filipinas 21. Pakistán 22. Alemania 23. Reino Unido
## 2 2 1 1
## 24. Otros países 3. Corea del Sur 4. Arabia Saudita 5. Canadá
## 2 2 2 2
## 6. Vietnam 7. Brasil 8. Taiwán 9. Japón
## 2 2 1 2
##
## Within cluster sum of squares by cluster:
## [1] 0.06039836 0.16247254
## (between_SS / total_SS = 42.4 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
Gráficos K-means
K-óptimo [wws]
fviz_cluster(kmeans(data_, 3, nstart = 25), data = data_, palette = c("#2E9FDF", "#00AFBB", "#E7B800", "#E7B801"), ellipse.type = "euclid", star.plot = TRUE, repel = TRUE, ggtheme = theme_minimal()
)

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

Conclusiones
Complementariamente a los análisis que fueron expuestos en las
secciones de estudio es importante hacer una mención global sobre el
problema considerado a la luz de lo obtenido.
Como se menciona en el trabajo hecho en el curso Análisis de
Regresión (que puede ser consultado temporalmente a través de: https://rpubs.com/glibrerosl/Applied-Statistics-FULL),
las aspiraciones de un estudiante extranjero para ingresar a una
universidad norteamericana se enfrentan a un elevado grado de
competición. Además, se constata, desde la perspectiva de estudio
multivariable, que, por lo menos descriptivamente, una variable
clasificadora categórica como el sexo, resulta muy poco significativa
formar grupos diferenciados entre los estudiantes con aspiraciones de
ingreso, asunto que contrasta con los relatos socio-populistas basados
en falacias ad hominem. El dato, si es fino, siempre será
objetivo.
Complementariamente, todas las pruebas de normalidad multivariante
resultaron negativas, salvo que a nivel univariado la variable
CGPA presentó distribución normal en todas ellas. Así,
el deterioro de las propiedades de independencia lineal juegan a favor
de la síntesis de información a través de la estimación de componentes
principales. Este pudo describir una medida de competitividad
formativa que conjuga, con una retención de \(77.05\) \(\%\) la variabilidad del conjunto de datos,
la naturaleza interpretativa del fenómeno estudiado. Así, cuanto mayor
sea el valor de las variables que registra un estudiante para aplicar a
una plaza en una universidad de su elección, mayor será el estado de
favorabilidad de que el estudiante sea admitido por la universidad de su
preferencia.
Asimismo, el análisis de correspondencias, simple y múltiple, mostró
que las universidades de mejor calificación, en particular, las de tres
y cuatro estrellas tienden a captar a los estudiantes de mejor
medida de competitividad formativa, algo esperado dada
la naturaleza del fenómeno estudiado. Además, la variable categórica
Research juega un papel determinante en la
selectividad, mientras que la varaible Gender es
indeterminante estadísticamente para aumentar las probabilidades de
ingreso de un estudiante a una universidad de su preferencia.
Adicionalmente, el análisis de conglomerados muestró que
efectivamente existían en el conjunto de datos registros
significativamente homogéneos entre sí y a su vez se parados de otros.
En este sentido, los métodos de aglomeración jerárquicos y
no-jerárquicos ayudaron a comprender cómo estaban dispuestos esos grupos
y los valores extraños por reevaluar. Así, es relevante la semejanza de
perfiles de estudiantes que por nacionalidad abarcan el cercano, medio y
lejano oriente al conformar un conglomerado de alta masa, aunque las
nacionalidades de Japón, Indonesia y Nepal tomen distancia de su
centroide, tales que pudiesen conformar jerárquicamente conglomerados
por sí mismos. Por otro lado, el conglomerado al cual pertenece Colombia
podría interpretarse como uno que recoge estudiantes muy comprometidos
con su formación, dado que son reconocidas las diferencias de los
sistemas educativos en vigor en las nacionalidades que lo conforman.
Por último, es importante resaltar el aspecto técnico relacionado con
el procesamiento estadístico hecho en este estudio a nivel de robustez,
eficiencia e integración que R, RStudio y RMarkdown ofrecen al usuario
para que este se pueda enfocar en él sin pasar mayores inconvenientes
con el soporte documental para presentarlo.
Referencias
Aldás, J., & Uriel, E. (2017).
Análisis
multivariante aplicado con R (2nd ed.).
ALFACENTAURO.
Aristizábal R., W. D. (2017).
Análisis
multivariado unidad 1 estadística descriptiva multivariada. In
Fundación Universitaria Los Libertadores.
Cramer, Harald. (1953).
Métodos
matemáticos de estadística (1st ed.).
AGUILAR.
Díaz Morales, L. G., & Morales Rivera, M. A. (2012).
Análisis estadístico de datos
multivariados (1st ed.). UNAL.
Doornik, J. A., & Hansen, H. (2008). An omnibus test for univariate
and multivariate normality.
Oxford Bulletin of Economics and
Statistics.
https://doi.org/10.1111/j.1468-0084.2008.00537.x
Hair, J. F., Anderson, R. E., Tatham, R. L., & Black, W. C. (1999).
Análisis multivariante (5th ed.).
PRENTICE HALL.
Porras C., J. C. (2016). Comparison test mutivariate normal.
Anales
Científicos.
https://dialnet.unirioja.es/descarga/articulo/6171231.pdf
LS0tDQp0aXRsZTogIioqQWRtaXNpw7NuIGVuIGxhIFVuaXZlcnNpZGFkKioiDQpzdWJ0aXRsZTogIkVzdHVkaW8gZGUgQW7DoWxpc2lzIE11bHRpdmFyaWFkbyBjb24gYmFzZSBlbiB1biBjb25qdW50byBkZSBkYXRvcyBkZSBhc3BpcmFudGVzIGV4dHJhbmplcm9zIHBhcmEgc2VyIGFkbWl0aWRvcyBlbiBlc3R1ZGlvcyBzdXBlcmlvcmVzIGVuIEVFLlVVLiINCmF1dGhvcjogIlBvcjogR2lhbmNhcmxvIExpYnJlcm9zIExvbmRvw7FvOjpnbGlicmVyb3NsQGxpYmVydGFkb3Jlcy5lZHUuY28iDQpkYXRlOiAiRXN0dWRpbyBNdWx0aXZhcmlhbnRlIEVsYWJvcmFkbyBlbnRyZSBmZWJyZXJvIHkgbWFyem8gZGUgMjAyMyBjb21vIGFjdGl2aWRhZCBmb3JtYXRpdmEgeSBldmFsdWF0aXZhIGRlbCBjdXJzbyBBbsOhbGlzaXMgTXVsdGl2YXJpYW50ZSBkZSBsYSBlc3BlY2lhbGl6YWNpw7NuIGVuIEVzdGFkw61zdGljYSBBcGxpY2FkYSAobW9kYWxpZGFkIHZpcnR1YWwpLiAqQ2llcnJlIGRlIEFjdHVhbGl6YWNpb25lcyBbVDE6IDE0OjMzIDE2LWZlYi0yMDIzXSBbVDI6IDExOjU5IDI2LWZlYi0yMDIzXSBbVDM6IDExOjU5IDUtbWFyLTIwMjNdIFtUNDogMTE6NTkgMTItbWFyLTIwMjNdKi4iDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiBsdW1lbg0KYmlibGlvZ3JhcGh5OiBiaWJsaW9ncmFmaWFfTUUuYmliDQpjc2w6IGFwYS5jc2wNCmxpbmstY2l0YXRpb25zOiB5ZXMNCi0tLQ0KPCEtLSBDb25maWd1cmFjacOzbiBHbG9iYWwgZGUgUiAtLT4NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShHR2FsbHkpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGFuZHJld3MpDQpsaWJyYXJ5KHRjbHRrKQ0KbGlicmFyeShhcGxwYWNrKQ0KbGlicmFyeShncmFwaGljcykNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KE1WTikNCmxpYnJhcnkocmVzaGFwZTIpDQpsaWJyYXJ5KEZhY3RvTWluZVIpDQpsaWJyYXJ5KGZhY3RvZXh0cmEpDQpsaWJyYXJ5KHBzeWNoKQ0KbGlicmFyeShGYWN0b0NsYXNzKQ0KbGlicmFyeShjbHVzdGVyKQ0KbGlicmFyeShkZW5kZXh0ZW5kKQ0KbGlicmFyeShtYWdyaXR0cikNCmxpYnJhcnkoTmJDbHVzdCkNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSkNCg0KQWRtaXNzaW9uX0RhdGFzZXQgPC0gcmVhZF9leGNlbCgiRDovWkIvWzJdIEFjYWRlbWljYXMvWzEwLjFdIEVzcGVjaWFsaXphY2lvbi9bMF0gQ3Vyc29zL1szXSBBbnNfTXVsdGl2YXJpYW50ZS9UYXJlYXMvQWRtaXNzaW9uX0RhdGFzZXQueGxzeCIpDQpBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsIDwtIHJlYWRfZXhjZWwoIkQ6L1pCL1syXSBBY2FkZW1pY2FzL1sxMC4xXSBFc3BlY2lhbGl6YWNpb24vWzBdIEN1cnNvcy9bM10gQW5zX011bHRpdmFyaWFudGUvVGFyZWFzL0FkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwueGxzeCIpDQpOYXRpb25hbGl0aWVzIDwtIHJlYWRfZXhjZWwoIkQ6L1pCL1syXSBBY2FkZW1pY2FzL1sxMC4xXSBFc3BlY2lhbGl6YWNpb24vWzBdIEN1cnNvcy9bM10gQW5zX011bHRpdmFyaWFudGUvVGFyZWFzL05hdGlvbmFsaXRpZXMueGxzeCIpDQpBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsX05hdCA8LSByZWFkX2V4Y2VsKCJEOi9aQi9bMl0gQWNhZGVtaWNhcy9bMTAuMV0gRXNwZWNpYWxpemFjaW9uL1swXSBDdXJzb3MvWzNdIEFuc19NdWx0aXZhcmlhbnRlL1RhcmVhcy9BZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsX05hdC54bHN4IikNCkFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxfTmF0X0F2ZXJhZ2UgPC0gcmVhZF9leGNlbCgiRDovWkIvWzJdIEFjYWRlbWljYXMvWzEwLjFdIEVzcGVjaWFsaXphY2lvbi9bMF0gQ3Vyc29zL1szXSBBbnNfTXVsdGl2YXJpYW50ZS9UYXJlYXMvQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbF9OYXRfQXZlcmFnZS54bHN4IikNCmBgYA0KDQo8YSBuYW1lPSJzZWMxIj48L2E+DQoNCiMjICoqT2JqZXRpdm8geSBBbm90YWNpb25lcyA6OiBGYXNlIDEqKg0KIyMgKipbRGVzY3JpcGNpb25lcyBNdWx0aXZhcmlhbnRlc10qKg0KRW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgZXN0YSBwcmltZXJhIGV0YXBhIGRlIGVzdHVkaW8gbW9zdHJhcsOhIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcyBjb24gYmFzZSBlbiB1biBjb25qdW50byBkZSBkYXRvcyBkZXNkZSB1biBlbmZvcXVlIGRlIGVzdGFkw61zdGljYSBkZXNjcmlwdGl2YSBtdWx0aXZhcmlhbnRlOyBhZGVtw6FzLCBkZSBpbmNsdWlyIHVuYSBwcnVlYmEgZXN0YWTDrXN0aWNhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHNvYnJlIGVsbG9zLg0KDQpFbCBjb25qdW50byBkZSBkYXRvcyBkZSB0cmFiYWpvIGVzIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikuIENhYmUgYW5vdGFyIHF1ZSBsb3MgZnVuZGFtZW50b3MgdGXDs3JpY29zIHByb3ZpZW5lbiBkZSBub3RhcyBkZSBjbGFzZSBkZWwgY3Vyc28gKipBbsOhbGlzaXMgTXVsdGl2YXJpYW50ZSoqIGRpY3RhZG8gcG9yIGVsIHByb2Zlc29yIEp1YW4gQ2FybG9zIFJ1YnJpY2hlIEPDoXJkZW5hcyBwYXJhIGxhIEVzcGVjaWFsaXphY2nDs24gZW4gRXN0YWTDrXN0aWNhIEFwbGljYWRhLCBtb2RhbGlkYWQgdmlydHVhbCAoY29ob3J0ZSAyMDIyLTQpLCBkZSBsYSBGdW5kYWNpw7NuIFVuaXZlcnNpdGFyaWEgTG9zIExpYmVydGFkb3JlczsgeSBkZSBsb3MgbGlicm9zOiBBbsOhbGlzaXMgTXVsdGl2YXJpYW50ZSBBcGxpY2FkbyBjb24gUiBbQEFNQVJBbGRhcy1VcmllbDJlZF0gZGUgSm9hcXXDrW4gQWxkw6FzIHkgRXplcXVpZWwgVXJpZWwsIEFuw6FsaXNpcyBNdWx0aXZhcmlhbnRlIGRlIEpvc2VwaCBIYWlyLCBSb2xwaCBBbmRlcnNvbiwgUm9uYWxkIFRhdGhhbSB5IFdpbGxpYW0gQmxhY2sgW0BBTUhhaXItZXRBbDVlZF0sIEFuw6FsaXNpcyBFc3RhZMOtc3RpY28gZGUgRGF0b3MgTXVsdGl2YXJpYWRvcyBkZSBMdWlzIEd1aWxsZXJtbyBEw61heiBNb25yb3kgeSBNYXJpbyBBbGZvbnNvIE1vcmFsZXMgUml2ZXJhIFtAQUVETURpYXotTW9yYWxlczFlZF0sIEludHJvZHVjY2nDs24gYSBsYSBUZW9yw61hIE1hdGVtw6F0aWNhIGRlIGxhcyBQcm9iYWJpbGlkYWRlcyB5IGEgbGEgRXN0YWTDrXN0aWNhIGRlIEhvd2FyZCBUdWNrZXIgW0BJVE1QRVR1Y2tlcjFlZF0geSBBbsOhbGlzaXMgTXVsdGl2YXJpYWRvOiBFc3RhZMOtc3RpY2EgTXVsdGl2YXJpYWRhIERlc2NyaXB0aXZhIGRlIFdpbGxpYW0gRGF2aWQgQXJpc3RpesOhYmFsIFJvZHLDrWd1ZXogW0BBTUVEQXJpc3RpemFiYWwyMDE3XS4NCg0KRXN0ZSB0cmFiYWpvIGNvbnRpbsO6YSBlbCBoZWNobyBlbiBlbCBjdXJzbyAqKkFuw6FsaXNpcyBkZSBSZWdyZXNpw7NuKiogZGljdGFkbyBwb3IgZWwgcHJvZmVzb3IgRGFnb2JlcnRvIEJlcm3DumRleiBwYXJhIGxhIEVzcGVjaWFsaXphY2nDs24gZW4gRXN0YWTDrXN0aWNhIEFwbGljYWRhLCBtb2RhbGlkYWQgdmlydHVhbCAoY29ob3J0ZSAyMDIyLTQpLCBkZSBsYSBGdW5kYWNpw7NuIFVuaXZlcnNpdGFyaWEgTG9zIExpYmVydGFkb3Jlcy4gRW4gZXN0ZSBsYSBiaWJsaW9ncmFmw61hIGNvbnN1bHRhZGEgZnVlOiBwcm9iYWJpbGlkYWQgeSBlc3RhZMOtc3RpY2EgZGUgSmF5IEwuIERldm9yZSBbQFBFRGV2b3JlN2VkXSwgQmlvZXN0YWTDrXN0aWNhIGRlIFdheW5lIFcuIERhbmllbCBbQEJFRGFuaWVsNGVkXSwgTcOpdG9kb3MgTWF0ZW3DoXRpY29zIGRlIEVzdGFkw61zdGljYSBkZSBIYXJhbGQgQ3JhbWVyIFtATU1FQ3JhbWVyMWVkXTsgbW90aXZvIHBvciBlbCBjdWFsIHNlIGluY2x1eWVuIGVuIGxhcyByZWZlcmVuY2lhcy4gRWwgdHJhYmFqbyBoZWNobyBlbiBBbsOhbGlzaXMgZGUgUmVncmVzacOzbiBxdWUgcHVlZGUgc2VyIGNvbnN1bHRhZG8gdGVtcG9yYWxtZW50ZSBhIHRyYXbDqXMgZGU6IGh0dHBzOi8vcnB1YnMuY29tL2dsaWJyZXJvc2wvQXBwbGllZC1TdGF0aXN0aWNzLUZVTEwuDQoNClBvciDDumx0aW1vLCBlc3RlIHRyYWJham8gZnVlIHByb2Nlc2FkbyBjb24gYHIgUi52ZXJzaW9uLnN0cmluZ2AgbWVkaWFkbyBwb3IgUlN0dWRpbyAyMDIyLjEyLjAgQnVpbGQgMzUzIGVuIHVuYSBwbGF0YWZvcm1hIHg4Nl82NC13NjQtbWluZ3czMi4gQWRlbcOhcywgcG9yIHN1IG5hdHVyYWxlemEgZGUgcHVibGljYWNpw7NuIGVuIGzDrW5lYSB5IHBhcmEgY3VtcGxpciBjb24gZWwgcmVxdWlzaXRvIHRlbXBvcmFsIGRlIGVudHJlZ2EsIHNlcsOhIGFjdHVhbGl6YWRvLCBjb21vIG3DoXhpbW8sIGhhc3RhIGxhcyAxMTo1OSBwLm0uIGRlbCBsdW5lcyAxMyBkZSBmZWJyZXJvIGRlIDIwMjMuDQoNCjxhIG5hbWU9InNlYzIiPjwvYT4NCg0KIyMgKioyLiBEZXNjcmlwY2nDs24gZGUgbG9zIERhdG9zKioNCg0KIyMjIDIuMS4gRnVlbnRlIGRlbCBDb25qdW50byBkZSBEYXRvcw0KRWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbyBzZSBvYnR1dm8gY2FzaSB0b3RhbG1lbnRlIGRlICoqS2FnZ2xlKio6IGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vYWtzaGF5ZGF0dGF0cmF5a2hhcmUuIEVzIGNvbnZlbmllbnRlIGFub3RhciBxdWUgKipLYWdnbGUqKiBlcyB1bmEgY29tcGHDscOtYSBzdWJzaWRpYXJpYSBkZSBHb29nbGUgTExDIHF1ZSBtYW50aWVuZSB1bmEgY29tdW5pZGFkIG9ubGluZSBkZSBjaWVudMOtZmljb3MgZGUgZGF0b3MgeSBwcm9mZXNpb25hbGVzIGRlbCBhcHJlbmRpemFqZSBhdXRvbcOhdGljby4gRXN0YSBlbXByZXNhIHBlcm1pdGUgYSBzdXMgdXN1YXJpb3MgZW5jb250cmFyIHkgcHVibGljYXIgY29uanVudG9zIGRlIGRhdG9zLCBleHBsb3JhciB5IGNyZWFyIG1vZGVsb3MgZW4gdW4gZW50b3JubyBkZSBjaWVuY2lhIGRlIGRhdG9zIGJhc2FkbyBlbiBsYSB3ZWIsIHRyYWJhamFyIGNvbiBvdHJvcyBjaWVudMOtZmljb3MgZGUgZGF0b3MgZSBpbmdlbmllcm9zIGRlIGFwcmVuZGl6YWplIGF1dG9tw6F0aWNvIHkgcGFydGljaXBhciBlbiBjb25jdXJzb3MgcGFyYSByZXNvbHZlciBkZXNhZsOtb3MgZGUgY2llbmNpYSBkZSBkYXRvcy4NCg0KIyMjIDIuMi4gQ29udGV4dG8gZGVsIENvbmp1bnRvIGRlIERhdG9zDQpFbCBjb25qdW50byBkZSBkYXRvcyBpbmNsdXllIG3DqXRyaWNhcyBhY2Fkw6ltaWNhcyBvYnRlbmlkYXMgcG9yIGVzdHVkaWFudGVzIGV4dHJhbmplcm9zIHBhcmEgYXNwaXJhciBhIGFjY2VkZXIgYSB1bml2ZXJzaWRhZGVzIGRlIEVFLlVVLiBFc3RlIGNvbmp1bnRvIGRlIGRhdG9zIHNlIGFjdHVhbGl6w7MgcG9yIMO6bHRpbWEgdmV6IGVuIGp1bGlvIGRlIDIwMjIuDQoNCiMjIyAyLjMuIERlc2NyaXBjacOzbiBkZWwgQ29uanVudG8gZGUgRGF0b3Mgey50YWJzZXQgLnRhYnNldC1waWxsc30NCkVsIGNvbmp1bnRvIGRlIGRhdG9zIGNvbnRpZW5lIDEwIGNhbXBvcyB5IDQwMCByZWdpc3Ryb3MuIFVubyBkZSBsb3MgY2FtcG9zIGVzIHNpbXBsZW1lbnRlIHVuIGlkZW50aWZpY2Fkb3IgbnVtw6lyaWNvIHNlY3VlbmNpYWwgZGUgbG9zIHJlZ2lzdHJvczsgb3Ryb3MgdHJlcyBzb24gZGUgbmF0dXJhbGV6YSBwb2xpdMOzbWljYTsgeSBlbCByZXN0byBzb24gbnVtw6lyaWNvcyBlc3RyaWN0YW1lbnRlIHBvc2l0aXZvcy4gTGEgbGlzdGEgc2lndWllbnRlIGxvcyBkZXNjcmliZSBlbiBlbCBtaXNtbyBvcmRlbiwgZGUgaXpxdWllcmRkYSBhIGRlcmVjaGEsIGNvbW8gYXBhcmVjZW4gZW4gZWwgcmFuZ28gZGUgZGF0b3MgcXVlIGxvcyBjb250aWVuZSB5IHNlIGVzdGFibGVjZSBwYXJhIGNhZGEgY2FtcG8sIGV4Y2VwdG8gZWwgY2FtcG8gKipTZXJpYWwqKiwgZWwgdGlwbyBkZSB2YXJpYWJsZSB5IHN1IGVzY2FsYSBkZSBtZWRpY2nDs24gY29uIGJhc2UgZW4gbGEgbm9tZW5jbGF0dXJhICh0aXBvX2RlX3ZhcmlhYmxlOjplc2NhbGFfZGVfbWVkaWNpw7NuW29yZGVuYW1pZW50b10pOg0KDQotICoqU2VyaWFsKiogKGlkZW50aWZpY2Fkb3IpOiByZWdpc3RyYSB1biBuw7ptZXJvIHNlY3VlbmNpYWRvIGEgcGFydGlyIGRlIDEgcGFyYSBpZGVudGlmaWNhciBkZSBmb3JtYSDDum5pY2EgY2FkYSByZWdpc3RybyBjb25zaWduYWRvIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zLg0KDQotICoqR2VuZGVyKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogcmVnaXN0cmEgZWwgc2V4byBkZWwgZXN0dWRpYW50ZSBkZWwgY3VhbCBzZSByZWdpc3RyYXJvbiBsb3MgZGF0b3M6IDEgY29ycmVzcG9uZGUgY29uIHVuIGVzdHVkaWFudGUgZGUgc2V4byBtYXNjdWxpbm8sIDAgY29uIHVuIGVzdHVkaWFudGUgZGUgc2V4byBmZW1lbmluby4NCg0KLSAqKkdSRSBTY29yZSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGVsIHB1bnRhamUgdG90YWwgR1JFIChleGFtZW4gZGUgYWNjZXNvIGEgbGEgdW5pdmVyc2lkYWQpIG9idGVuaWRvIHBvciBlbCBlc3R1ZGlhbnRlLiBHUkUgZXMgdW4gY29tcG9uZW50ZSBjb23Dum4gZGVsIHByb2Nlc28gZGUgYWRtaXNpw7NuIGEgY29sZWdpb3MgbyB1bml2ZXJzaWRhZGVzIGVuIEVFLlVVLiBxdWUgbWlkZSBlbCByYXpvbmFtaWVudG8gdmVyYmFsLCBjdWFudGl0YXRpdm8sIGxhIGVzY3JpdHVyYSBhbmFsw610aWNhIHkgbGFzIGhhYmlsaWRhZGVzIGRlIHBlbnNhbWllbnRvIGNyw610aWNvIHF1ZSBzZSBoYW4gYWRxdWlyaWRvIGEgbG8gbGFyZ28gZGUgdW4gZXh0ZW5zbyBwZXLDrW9kbyBkZSB0aWVtcG8geSBxdWUgbm8gZXN0w6FuIHJlbGFjaW9uYWRvcyBjb24gY2FtcG8gZXNwZWPDrWZpY29zIGRlIGVzdHVkaW8uIEVsIGNhbXBvIHNvbG8gcmVnaXN0cmEgZG9zIGRlIGxvcyB0cmVzIGNvbXBvbmVudGVzIGRlIGxhIGV2YWx1YWNpw7NuOiByYXpvbmFtaWVudG8gdmVyYmFsIHkgY3VhbnRpdGF0aXZvLCBlbiB1bmEgZXNjYWxhIGRlc2RlIDI2MCBoYXN0YSAzNDAgcHVudG9zLiBFbCByZXN1bHRhZG8gYXVzZW50ZSBkZWwgcHVudGFqZSBjb3JyZXNwb25kZSBjb24gZWwgY29tcG9uZW50ZSBkZSBlc2NyaXR1cmEgYW5hbMOtdGljYTogY2FsaWZpY2FkbyBlbnRyZSAwIHkgNiBwdW50b3MuDQoNCi0gKipUT0VGTCBTY29yZSoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGVsIHB1bnRhamUgdG90YWwgVE9FRkwgKHBydWViYSBkZSBpbmdsw6lzIGNvbW8gaWRpb21hIGV4dHJhbmplcm8pIG9idGVuaWRvIHBvciBlbCBlc3R1ZGlhbnRlLiBUT0VGTCBlcyB1biBjb21wb25lbnRlIGNvbcO6biBkZWwgcHJvY2VzbyBkZSBhZG1pc2nDs24gYSBjb2xlZ2lvcyBvIHVuaXZlcnNpZGFkZXMgZW4gRUUuVVUuIHBvciBwYXJ0ZSBkZSBlc3R1ZGlhbnRlcyBleHRyYW5qZXJvcyBxdWUgbWlkZSBsYXMgY29tcGV0ZW5jaWFzIGVuIGNvbXByZW5zacOzbiBlc2NyaXRhLCBjb21wcmVuc2nDs24gb3JhbCwgZXhwcmVzacOzbiBvcmFsIHkgZXhwcmVzacOzbiBlc2NyaXRhLCBlbiB1bmEgZXNjYWxhIGRlc2RlIDAgaGFzdGEgMTIwIHB1bnRvcy4NCg0KLSAqKlNPUCoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGVsIHB1bnRhamUgdG90YWwgU09QIChlbnNheW8gZGUgZGVjbGFyYWNpw7NuIGRlIHByb3DDs3NpdG9zIG8gZGUgYWRtaXNpw7NuKSBvYnRlbmlkbyBwb3IgZWwgZXN0dWRpYW50ZS4gU09QIGVzIHVuIGNvbXBvbmVudGUgY29tw7puIGRlbCBwcm9jZXNvIGRlIGFkbWlzacOzbiBhIGNvbGVnaW9zIG8gdW5pdmVyc2lkYWRlcyBlbiBFRS5VVS4gcXVlIGNvbnNpc3RlIGVuIHVuIGVuc2F5byBkZSBzb2xpY2l0dWQgZGUgaW5ncmVzbyBlc2NyaXRvIHBvciBlbCBlc3R1ZGlhbnRlIGVuIGVsIGN1YWwgZGViZSBoYWNlciB1bmEgZGVzY3JpcGNpw7NuIGdlbmVyYWwgZGUgcXVpw6luIGVzLCBlbiBxdWnDqW4gcXVpZXJlIGNvbnZlcnRpcnNlIHkgaGFzdGEgcXXDqSBwdW50byBlc3TDoSBwcmVwYXJhZG8gcGFyYSBzZWd1aXIgdW4gZGV0ZXJtaW5hZG8gY3Vyc28gZW4gbGEgaW5zdGl0dWNpw7NuIGVkdWNhdGl2YSBhIGxhIGN1YWwgYXNwaXJhIGluZ3Jlc2FyLiBFc3RlIGVuc2F5byBzZSBjYWxpZmljYSBjb24gdW4gcHVudGFqZSBlbnRyZSAwIHkgNS4NCg0KLSAqKkxPUioqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGVsIHB1bnRhamUgdG90YWwgTE9SIChjYXJ0YSBkZSByZWNvbWVuZGFjacOzbikgb2J0ZW5pZG8gcG9yIGVsIGVzdHVkaWFudGUuIExPUiBlcyB1biBjb21wb25lbnRlIGNvbcO6biBkZWwgcHJvY2VzbyBkZSBhZG1pc2nDs24gYSBjb2xlZ2lvcyBvIHVuaXZlcnNpZGFkZXMgZW4gRUUuVVUuIHF1ZSBjb25zaXN0ZSBlbiB1bmEgcmVjb21lbmRhY2nDs24gZXNjcml0YSwgZ2VuZXJhbG1lbnRlIHBvciB1biBwcm9mZXNvciwgZW4gbGEgY3VhbCBlbCByZWRhY3RvciBldmFsw7phIGxhcyBjdWFsaWRhZGVzLCBjYXJhY3RlcsOtc3RpY2FzIHkgY2FwYWNpZGFkZXMgZGVsIGVzdHVkaWFudGUgcmVjb21lbmRhZG8gZW4gcmVsYWNpw7NuIGNvbiBzdSBhcHRpdHVkIHBhcmEgc2VndWlyIHVuIGN1cnNvIGVuIGxhIGluc3RpdHVjacOzbiBlZHVjYXRpdmEgYSBsYSBjdWFsIGVsIGVzdHVkaWFudGUgYXNwaXJhIGEgaW5ncmVzYXIuIEVzdGEgY2FydGEgc2UgY2FsaWZpY2EgY29uIHVuIHB1bnRhamUgZW50cmUgMCB5IDUuDQoNCi0gKipDR1BBKiogKGN1YW50aXRhdGl2YTo6cmF6w7NuKTogcmVnaXN0cmEgZWwgcHVudGFqZSB0b3RhbCBDR1BBIChwcm9tZWRpbyBkZSBjYWxpZmljYWNpb25lcyBhY3VtdWxhdGl2bykgb2J0ZW5pZG8gcG9yIGVsIGVzdHVkaWFudGUuIENHUEEgZXMgdW4gY29tcG9uZW50ZSBjb23Dum4gZGVsIHByb2Nlc28gZGUgYWRtaXNpw7NuIGEgY29sZWdpb3MgbyB1bml2ZXJzaWRhZGVzIGVuIEVFLlVVLiBxdWUgbWlkZSBlbCBkZXNlbXBlw7FvIHByb21lZGlvIGRlbCBlc3R1ZGlhbnRlIGVuIHN1IGVzY29sYXJpZGFkIHByZXZpYSBhIGxhIHNvbGljaXR1ZCBkZSBpbmdyZXNvIGEgbGEgaW5zdGl0dWNpw7NuIGVkdWNhdGl2YSBzaWd1aWVudGUgZGUgc3UgcHJlZmVyZW5jaWEuIEVzdGUgcHVudGFqZSBzZSBtaWRlIGVudHJlIDAgeSA0OyBzaW4gZW1iYXJnbywgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgZnVlIGNvbnZlcnRpZG8gZW4gdW5hIGVzY2FsYSBlbnRyZSAwIHkgMTAuDQoNCi0gKipSZXNlYXJjaCoqIChjdWFsaXRhdGl2YTo6bm9taW5hbCk6IHJlZ2lzdHJhIGxhIGV4cGVyaWVuY2lhIGVuIGludmVzdGlnYWNpw7NuIHF1ZSBwb3NlZSBlbCBlc3R1ZGlhbnRlOiAxIGNvcnJlc3BvbmRlIGNvbiBxdWUgZWwgZXN0dWRpYW50ZSBhcmd1bWVudGEgZXhwZXJpZW5jaWEgaW52ZXN0aWdhdGl2YSwgMCBjb3JyZXNwb25kZSBjb24gcXVlIG5vLWFyZ3VtZW50YSBleHBlcmllbmNpYSBpbnZlc3RpZ2F0aXZhLg0KDQotICoqVW5pdmVyc2l0eSBSYXRpbmcqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwob3JkZW5hZGEpKTogcmVnaXN0cmEgdmFsb3JhY2nDs24gZGUgbGEgdW5pdmVyc2lkYWQgYSBsYSBjdWFsIGFzcGlyYSBhIGluZ3Jlc2FyIGVsIGVzdHVkaWFudGUuIEVzdGEgdmFsb3JhY2nDs24gc2UgaGFjZSBlbiB1bmEgZXNjYWxhIGVudHJlIDEgeSA1IGVzdHJlbGxhcywgY2luY28gZXN0cmVsbGFzIGluZGljYSBsYSBtZWpvciB2YWxvcmFjacOzbi4NCg0KLSAqKkNoYW5jZSBvZiBBZG1pdCoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IHJlZ2lzdHJhIGxhIHByb2JhYmlsaWRhZCBkZSBxdWUgZWwgZXN0dWRpYW50ZSBzZWEgYWRtaXRpZG8gZW4gbGEgdW5pdmVyc2lkYWQgZGUgc3UgcHJlZmVyZW5jaWEgY29uIGJhc2UgZW4gbG9zIGRhdG9zIHJlZ2lzdHJhZG9zIGEgc3Ugbm9tYnJlLCBzYWx2byBzdSBzZXhvLiBFc3RhIHByb2JyYWJpbGlkYWQgc2UgbWlkZSBlbnRyZSAwIHkgMS4NCg0KUG9yIMO6bHRpbW8sIGVzIG5lY2VzYXJpbyBhY2xhcmFyIHF1ZSBlbiBlbCBjb25qdW50byBkZSBkYXRvcyBsb3MgcmVnaXN0cm9zIGRlIGxhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIGZ1ZXJvbiByZWVzY3JpdG9zLCBzZWfDum4gbG9zIGNhc29zLCBwb3IgbsO6bWVyb3MgZW50ZXJvcyBwb3NpdGl2b3MsIGluY2x1aWRvIGVsIGNlcm8uIEFzw60sIGxvcyBzZXhvcyBlbiBsYSB2YXJpYWJsZSAqKkdlbmRlcioqIGZ1ZXJvbiByZWVzY3JpdG9zIGNvbW8gKiowKio6KipmZW1hbGUqKiB5ICoqMSoqOioqbWFsZSoqOyBlbiAqKlJlc2VhcmNoKiogZWwgZXZpZGVuY2lhciBvIG5vLWV2aWRlbmNpYXIgaW52ZXN0aWdhY2lvbmVzIGZ1ZSByZWVzY3JpdG8gY29tbyAqKjAqKjoqKm5vLXJlc2VhcmNoKiogeSAqKjEqKjoqKnJlc2VhcmNoKio7IHkgZW4gKipVbml2ZXJzaXR5IFJhdGluZyoqIGxhIHZhbG9yYWNpw7NuIGRlIGxhIHVuaXZlcnNpZGFkIGZ1ZSByZWVzY3JpdGEgY29tbyAqKjEqKjoqKm9uZV9zdGFyKiosICoqMioqOioqdHdvX3N0YXJzKiosICoqMyoqOioqdGhyZWVfc3RhcnMqKiwgKio0Kio6Kipmb3VyX3N0YXJzKiogeSAqKjUqKjoqKmZpdmVfc3RhcnMqKi4NCg0KIyMjIyBFc3RydWN0dXJhIGRlbCBDb25qdW50byBkZSBEYXRvcyBJbmljaWFsDQpgYGB7ciBFc3RydWN0dXJhX0Nvbmp1bnRvX2RlX0RhdG9zX0luaWNpYWwsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kc3RyKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwpDQpgYGANCg0KIyMjIyBDb25qdW50byBkZSBEYXRvcyBJbmljaWFsDQpgYGB7ciBDb25qdW50b19kZV9EYXRvc19JbmljaWFsLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCkFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwNCmBgYA0KDQojIyMjIEVzdHJ1Y3R1cmEgZGVsIENvbmp1bnRvIGRlIERhdG9zIFJlZXNjcml0bw0KYGBge3IgRXN0cnVjdHVyYV9Db25qdW50b19kZV9EYXRvc19SZWVzY3JpdG8sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kc3RyKEFkbWlzc2lvbl9EYXRhc2V0KQ0KYGBgDQoNCiMjIyMgQ29uanVudG8gZGUgRGF0b3MgUmVlc2NyaXRvDQpgYGB7ciBDb25qdW50b19kZV9EYXRvc19SZWVzY3JpdG8sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KQWRtaXNzaW9uX0RhdGFzZXQNCmBgYA0KDQojIyAqKjMuIEVzdGltYWNpb25lcyBNdWx0aXZhcmlhZGFzKioNCkNvbW8gc2UgbWVuY2lvbmEgZW4gW0BBTUVEQXJpc3RpemFiYWwyMDE3XSBsYSBkZSBtZWRpYSwgdmFyaWFuemEgeSBjb3ZhcmlhbnphIGNvbmZvcm1hbiB1biBjb25qdW50byBkZSBtZWRpZGFzIGZ1bmRhbWVudGFsZXMgcGFyYSBkZXNjcmliaXIgZGVzY3JpYmlyIGVsIGNvbXBvcnRhbWllbnRvCXBvc2ljaW9uYWwsIGRpc3BlcnNpdm8geSBjb3JyZWxhY2lvbmFsIGRlCXZhcmlhYmxlcwlhbGVhdG9yaWFzLiBFbiBlc3RlIHNlbnRpZG8sIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHRyYWJham8gcXVlIHBvc2VlIGNpbmNvIHZhcmlhYmxlcyBhbGVhdG9yaWFzIG51bcOpcmljYXMsIHkgcXVlIGVzdMOhIHJlcHJlc2VudGFkbyBtYXRyaWNpYWxtZW50ZSwgZXN0aW1hIGxhcyBtZWRpZGFzIGFudGVyaW9yZXMgYSBwYXJ0aXIgZGUgdmVjdG9yZXMgeSBtYXRyaWNlcyBlbiBlbCBlc3R1ZGlvIGRlc2NyaXB0aXZvIG11bHRpdmFyaWFibGUuDQoNCkVsIHZlY3RvciBkZSBtZWRpYXMgaW5kaWNhIGVsIGNvbXBvcnRhbWllbnRvIHBvc2ljaW9uYWwgZW4gZWwgc2VudGlkbyBkZSB2YWxvciBlc3BlcmFkbyBvIHB1bnRvIG1lZGlvIHBhcmEgY2FkYSB2YXJpYWJsZSBlbiByZWxhY2nDs24gY29uIHRvZG9zIHN1cyByZWdpc3Ryb3MuIExhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgZXN0aW1hIGxhcyBkaXNwZXJzaW9uZXMsIGVuIHN1IGRpYWdvbmFsIHByaW5jaXBhbCwgZGUgY2FkYSB2YXJpYWJsZSBkZWwgY29uanVudG8gZGUgZGF0b3MgcmVzcGVjdG8gZGUgY2FkYSBtZWRpYSBvYnRlbmlkYSBkZWwgdmVjdG9yIGRlIG1lZGlhcy4gQWRlbcOhcywgcG9yIGVuY2ltYSBvIHBvciBkZWJham8gZGUgbGEgZGlhZ29uYWwgcHJpbmNpcGFsLCBzZSBlc3RpbWFuIGxhcyBjb3ZhcmlhbnphcyBlbnRyZSBsYXMgY29tYmluYWNpb25lcyBkZSBsb3MgcG9zaWJsZXMgcGFyZXMgZGUgdmFyaWFibGVzIGRlbCBjb25qdW50byBkZSBkYXRvcy4gUGFyYSBtw6FzIGRldGFsbGVzIHNlIHB1ZWRlIGNvbnN1bHRhciBhIFtAQU1FREFyaXN0aXphYmFsMjAxN10uDQoNCkxvIGFudGVyaW9yLCBwYXJhIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlIHRyYWJham8sIHNlIGRlc2Fycm9sbGEgZW4gbGEgW3NlY2Npw7NuIDMuMi5dKCNzZWMzXzIpDQoNCiMjIyAzLjEuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hDQpDb24gYmFzZSBlbiBlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHNlIGNhbGN1bGFyw6FuIGUgaW50ZXByZXRhcsOhbiwgcGFyYSBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMsIGVsIHZlY3RvciBkZSBtZWRpYXMsIGxhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgeSBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcy4gU2UgcmVjdWVyZGEgcXVlIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyAoZW4gZXNjYWxhZGEgZGUgbWVkaWNpw7NuIGRlIHJhesOzbikgc29uOiAqKkdSRSBTY29yZSoqLCAqKlRPRUZMIFNjb3JlKiosICoqU09QKiosICoqTE9SKiosICoqQ0dQQSoqIHkgKipDaGFuY2Ugb2YgQWRtaXQqKi4NCg0KPGEgbmFtZT0ic2VjM18yIj48L2E+DQoNCiMjIyAzLjIuIERlc2Fycm9sbG8gZGVsIEFuw6FsaXNpcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIGVsIGPDoWxjdWxvIGRlIGxvcyBzaWd1aWVudGVzIG9iamV0b3M6ICoqVmVjdG9yIGRlIE1lZGlhcyoqICRcYmFyIHgkLCAqKk1hdHJpeiBkZSBWYXJpYW56YXMtQ292YXJpYW56YXMqKiAkUyQgeSAqKk1hdHJpeiBkZSBDb3JyZWxhY2lvbmVzKiogJFIkLg0KDQpDb24gYmFzZSBlbiBsYSBwZXN0YcOxYSAqKlZlY3RvciBkZSBNZWRpYXMgeSBCb3hwbG90cyoqIHNlIHB1ZWRlIGRlc2NyaWJpciBxdWUgZW4gZ2VuZXJhbCBsb3MgZGF0b3MgcmVnaXN0cmFkb3MgcGFyYSBjYWRhIHVuYSBkZSBsYXMgdmFyaWFibGVzIHRpZW5kZW4gYSB0ZW5lciBjb2xhcyBpenF1aWVyZGFzIGVuIHN1IGRpc3RyaWJ1Y2lvbmVzLCBhc8OtLCBsYXMgbWVkaWFzIGVzdGltYWRhcyB0aWVuZGVuIGEgc2VyIGFsdGFzLiBBZGljaW9uYWxtZW50ZSwgZW4gcmVsYWNpw7NuIGNvbiBsYSBtZWRpYW5hLCBzb2xvIGxhIHZhcmlhYmxlICoqU09QKiogbXVlc3RyYSB1biBzZXNnbyBub3RvcmlvIGVuIGNvbXBhcmFjacOzbiBjb24gbGFzIGRlbcOhcy4gQWRlbcOhcywgdG9kb3MgbG9zIGNhc29zIGF0w61waWNvcyBzb24gZGUgZXh0cmVtbyBpbmZlcmlvci4gU2kgc2UgcmV2aXNhbiBsb3MgcmFuZ29zIGRlIGxhcyB2YXJpYWJsZXMgZXN0dWRpYWRhcyBzZSBwdWVkZSBjb25zdGF0YXIgcXVlIGxhcyBtZWRpYXMgc29uIGFsdGFzIGNvbXByYWRhcyBjb24gbG9zIGV4dHJlbW9zIHN1cGVyaW9yZXMgZGUgY2FkYSByYW5nby4NCg0KQ29uIGJhc2UgZW4gbGEgcGVzdGHDsWEgKipNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzKiogc2UgaW50ZXJwcmV0YSBxdWUsIGVuIGdlbmVyYWwsIHkgY29tbyBzZSBlc3BlcmEgcXVlIHBhc2UsIGxhcyByZWxhY2lvbmVzIGVudHJlIGxhcyB2YXJpYWJsZXMsIGVzdHVkaWFkYXMgcG9yIHBhcmVzLCB0aWVuZGVuIGEgc2VyIGRlIHByb3BvcmNpb25hbGlkYWQgZGlyZWN0YS4gUGFyYSBlbCBjYXNvLCBzZSBwdWVkZW4gb2JzZXJ2YXIgbGEgZ3LDoWZpY2EgbXVsdGl2YXJpYWRhIG1vc3RyYWRhIGVuIGxhIHBlc3Rhw7FhICoqRGlhZ3JhbWEgQ29uanVudG8gZGUgRGlzcGVyc2nDs24sIERpc3RyaWJ1Y2nDs24geSBDb3JyZWxhY2lvbmVzIFtTQV0qKiBkZSBsYSBbc2VjY2nDs24gNC4yLl0oI3NlYzRfMikNCg0KQ29uIGJhc2UgZW4gbGEgcGVzdGHDsWEgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqIHkgYWwgY29uc2lkZXJhciBsYSAqKk1hdHJpeiBkZSBWYXJpYW56YXMtQ292YXJpYW56YXMqKiBlcyB2ZXJpZmljYWJsZSBxdWUgbGEgaW50ZW5zaWRhZCBkZSBsYXMgY29yZWxhY2lvbmVzIGVzIG3DoXMgYWx0YSB5IHNpZW1wcmUgcG9zaXRpdmEgZW50cmUgbGFzIHZhcmlhYmxlczogKipUT0VGTF9TY29yZSoqLCAqKkdSRV9TY29yZSoqLCAqKkNHUEEqKiB5ICoqQ2hhbmNlX29mX0FkbWl0KiosIHF1ZSBlcyBlc3BlcmFkbyBlbiByZWxhY2nDs24gY29uIGVsIGZlbsOzbWVubyBlc3R1ZGlhZG8sIGVzdG8gc2UgcHVlZGUgcmV2aXNhciBjb24gbcOhcyBkZXRhbGxlcyBlbiBsYSBbc2VjY2nDs24gNC4yLl0oI3NlYzRfMikNCg0KIyMjIyBWZWN0b3IgZGUgTWVkaWFzIHkgQm94cGxvdHMNCmBgYHtyIFZlY3Rvcl9kZV9NZWRpYXNfeV9Cb3hwbG90cywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQphcHBseShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCAyLCBtZWFuKQ0KQWRtaXNzaW9uX0RhdGFzZXRfUmVkdWNpZG8gPSBBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldDQpwYXIobWZyb3cgPSBjKDEsIG5jb2woQWRtaXNzaW9uX0RhdGFzZXRfUmVkdWNpZG8pKSkNCmludmlzaWJsZShsYXBwbHkoMTpuY29sKEFkbWlzc2lvbl9EYXRhc2V0X1JlZHVjaWRvKSwgZnVuY3Rpb24oaSkgYm94cGxvdChBZG1pc3Npb25fRGF0YXNldF9SZWR1Y2lkb1ssIGldKSkpDQpgYGANCg0KIyMjIyBNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzDQpgYGB7ciBtYXRyaXpfZGVfVmFyaWFuemFzX0NvdmFyaWFuemFzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnJvdW5kKGNvdihBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldKSwyKQ0KYGBgDQoNCiMjIyMgTWF0cml6IGRlIENvcnJlbGFjaW9uZXMNCmBgYHtyIG1hdHJpel9kZV9Db3JyZWxhY2lvbmVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnJvdW5kKGNvcihBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldKSwyKQ0KYGBgDQoNCiMjICoqNC4gR3LDoWZpY2FzIE11bHRpdmFyaWFkYXMqKg0KRW4gbGEgZ3XDrWEgZGUgY2xhc2UgZGUgW0BBTUVEQXJpc3RpemFiYWwyMDE3XSBzZSBtZW5jaW9uYSBxdWUsIGVuIGdlbmVyYWwsIGxvcyBncsOhZmljb3MgbXVsdGl2YXJpYWRvcyBjdW1wbGVuIGRvcyBvYmpldGl2b3MgZXNlbmNpYWxlczogcHJpbWVybywgYXl1ZGFuIGEgY29tcGFyYXIJZWwJY29tcG9ydGFtaWVudG8JZGUJcG9ibGFjaW9uZXMgZGUgZXN0dWRpbyBjb24gYmFzZSBlbiB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHkgc3Vhdml6YW4gbGEgY29tcHJlbnNpw7NuIGRlIGxhIGVzdHJ1Y3R1cmEgZGUgY29ycmVsYWNpw7NuIGVudHJlCXZhcmlhcyB2YXJpYWJsZXMuIEVuIGVzdGUgc2VudGlkbywgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbyB0ZW5kcsOhIGFwb3lvIGRlc2NyaXRpdm8gZ3LDoWZpY28gYSB0cmF2w6lzIGRlIHRyZXMgZGlhZ3JhbWFzOiB1bm8gY29uanVudG8gcXVlIGludGVncmEgZGlzcGVyc2nDs24sIGRpc3RyaWJ1Y2nDs24geSBjb3JyZWxhY2lvbmVzOyBvdHJvIGJhc2FkbyBlbiBsYSByZW5kZXJpemFjacOzbiBkZSBwb2zDrWdvbm9zLCB5IHBvciDDumx0aW1vLCB1bm8gcXVlIHJlY3VycmUgYSBsYXMgY2FyYXMgZGUgQ2hlcm5vZmYuDQoNCiMjIyA0LjEuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hDQpDb24gYmFzZSBlbiBlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHNlIGNhbGN1bGFyw6FuIGUgaW50ZXByZXRhcsOhbiwgcGFyYSBsYXMgdmFyaWFibGVzIG51bcOpcmljYXMsIGxhcyBncsOhZmljYXMgbXVsdGl2YXJpYWRhcyBkZSBkaWFncmFtYSBkZSBjb3JyZWxhY2lvbmVzLCBtYXRyaXogZGUgZGlhZ3JhbWEgZGUgZGlzcGVyc2nDs24sIGRpYWdyYW1hIGRlIGVzdHJlbGxhcyB5IGNhcmFzIGRlIENoZXJub2ZmLiBTZSByZWN1ZXJkYSBxdWUgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIChlbiBlc2NhbGFkYSBkZSBtZWRpY2nDs24gZGUgcmF6w7NuKSBzb246ICoqR1JFIFNjb3JlKiosICoqVE9FRkwgU2NvcmUqKiwgKipTT1AqKiwgKipMT1IqKiwgKipDR1BBKiogeSAqKkNoYW5jZSBvZiBBZG1pdCoqLg0KDQo8YSBuYW1lPSJzZWM0XzIiPjwvYT4NCg0KIyMjIDQuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIGxhcyBncsOhZmljYXMgbXVsdGl2YXJpYWRhcyBkZTogKipEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMqKiAoc2luIGFncnVwYWNpw7NuIFNBIHkgY29uIGFncnVwYWNpw7NuIENBIChjb24gYmFzZSBlbiBsYXMgdHJlcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzOiBHZW5kZXI6R0UsIFJlc2VhcmNoOlJFLCBVbml2ZXJzaXR5X1JhdGluZzpVUikpLCAqKkRpYWdyYW1hIGRlIEVzdHJlbGxhcyoqIHkgKipDYXJhcyBkZSBDaGVybm9mZioqLg0KDQpDb24gYmFzZSBlbiBsYSBwZXN0YcOxYSAqKkRpYWdyYW1hIENvbmp1bnRvIGRlIERpc3BlcnNpw7NuLCBEaXN0cmlidWNpw7NuIHkgQ29ycmVsYWNpb25lcyBbU0FdKiogc2UgcHVlZGUgZGVzY3JpYmlyIHF1ZSBsYXMgY29ycmVsYWNpb25lcyBtw6FzIGFsdGFzLCBtYXlvcmVzIHF1ZSAkMC44JCwgc2UgZGFuIGVudHJlIHZhcmlhYmxlcyBlc3BlcmFkYXMgY29tbzogKipUT0VGTF9TY29yZSoqLCAqKkdSRV9TY29yZSoqLCAqKkNHUEEqKiB5ICoqQ2hhbmNlX29mX0FkbWl0KiouIEVzdGFzIHZhcmlhYmxlcywgc2Vnw7puIGxhcyBkZWZpbmljaW9uZXMgZGFkYXMgZW4gbGEgW3NlY2Npw7NuIDJdKCNzZWMyKSBkZSBkZXNjcmlwY2nDs24gZGUgZGF0b3MsIHNvbiBudWNsZWFyZXMgZW4gZWwgZmVuw7NtZW5vIGVzdHVkaWFkbywgcG9ycXVlIGVzdMOhbiBpbnZvbHVjcmFkYXMgY29uIGVsIGhpc3RvcmlhbCBkZSByZW5kaW1pZW50byBhY2Fkw6ltaWNvIGRlbCBlc3R1ZGlhbnRlLCBzdSBkZXNlbXBlw7FvIGVuIGxhIHBydWViYSBkZSBpbmdyZXNvIGEgbGEgdW5pdmVyc2lkYWQsIHN1IG5pdmVsIGRlIGRvbWluaW8gY2VydGlmaWNhZG8gZGVsIGlkaW9tYSBpbmdsw6lzIHkgc3VzIMOtbmRpY2UgZGUgcHJvYmFiaWxpZGFkIGRlIGluZ3Jlc28gYSBsYSB1bml2ZXJzaWRhZCBhIGxhIGN1YWwgYXNwaXJhLiBTaW4gZW1iYXJnbywgbmluZ3VuYSBkZSBlbGxhcyBlcyBkZXNjb2xsYW50ZW1lbnRlIGV4cGxpY2F0aXZhLiBQYXJhIG3DoXMgZGV0YWxsZXMgcHVlZGUgY29uc3VsdGFyc2UgZWwgdHJhYmFqbyBkZSBhbsOhbGlzaXMgZGUgcmVncnJlc2nDs24gZm9ybXVsYWRvIHNvYnJlIGVsIG1pc21vIGNvbmp1bnRvIGRlIGRhdG9zIGEgdHJhdsOpcyBkZTogaHR0cHM6Ly9ycHVicy5jb20vZ2xpYnJlcm9zbC9BcHBsaWVkLVN0YXRpc3RpY3MtRlVMTC4NCg0KQ29tcGxlbWVudGFyaWFtZW50ZSwgY29uIGJhc2UgZW4gbGFzIHBlc3Rhw7FhcyAqKkRpYWdyYW1hIENvbmp1bnRvIGRlIERpc3BlcnNpw7NuLCBEaXN0cmlidWNpw7NuIHkgQ29ycmVsYWNpb25lcyoqIGVuIHN1cyB2ZXJzaW9uZXMgYmFzYWRhcyBlbiBncnVwb3MgYSBwYXJ0aXIgZGUgbGFzIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXM6ICoqR2VuZGVyKiosICoqUmVzZWFyY2gqKiB5ICoqVW5pdmVyc2l0eV9SYXRpbmcqKiwgc2UgcHVlZGUgYXByZWNpYXIgcXVlIGNvbXBhcmF0aXZhbWVudGUgbGEgZGlmZXJlbmNpYWNpw7NuIGJhc2FkYSBlbiAqKkdlbmRlcioqIG5vIG11ZXN0cmEgcmVsZXZhbmNpYSBwYXJhIGVsZXZhciBsYSBwcm9iYWJpbGlkYWQgZGUgYWNjZXNvIGEgbGEgdW5pdmVyc2lkYWQgZGUgc3UgZWxlY2Npw7NuLCBjb250cmFyaW8gYSBsbyBxdWUgc3VjZWRlIGNvbiBsYSB2YXJpYWJsZSBhZ3J1cGFkb3JhICoqUmVzZWFyY2gqKiBxdWUgbXVlc3RyYSBkaWZlcmVuY2lhZGFtZW50ZSBsbyBjb250cmFyaW8uIEVzIGRlY2lyLCBxdWUgdW4gZXN0dWRpYW50ZSBwZXJ0ZW5lemNhIGFsIGdydXBvIGRlIGFxdWVsbG9zIHF1ZSBldmlkZW5jaWEgdHJhYmFqbyBlbiBpbnZlc3RpZ2FjacOzbiBhbCBtb21lbnRvIGRlIHByZXNlbnRhciBzdSBzb2xpY2l0dWQgZGUgYWNjZXNvLCByZXN1bHRhIHBhcmEgw6lsIGVuIHVuYSBjYXJhY3RlcsOtc3RpY2Egc2lnbmlmaWNhdGl2YW1lbnRlIGEgZmF2b3IgZGUgc3VzIHByZXRlbnNpb25lcy4gUG9yIG90cm8gbGFkbywgbGEgdmFyaWFibGUgY2xhc2lmaWNhZG9yYSAqKlVuaXZlcnNpdHlfUmF0aW5nKiosIHF1ZSBhcG9ydGEgY2luY28gZ3J1cG9zLCBtdWVzdHJhIHF1ZSBsYXMgdW5pdmVyc2lkYWRlcyBkZSBkb3MgeSBjdWF0cm8gZXN0cmVsbGFzIGVuIHRvZG9zIGxvcyBjYXNvcyB2aXN1YWxpemFkb3MgZW4gZWwgZGlhZ3JhbWEgc29uIHNpZ25pZmljYXRpdmFzIGEgbml2ZWwgZGUgY29ycmVsYWNpw7NuLCBwZXJvLCBjb21vIGVzIGVzcGVyYWRvLCBsYXMgZGUgbWVqb3IgcmF0aW5nLCBhdHJhZW4gYSBsb3MgbWVqb3JlcyB0YWxlbnRvcy4NCg0KQ29uIGJhc2UgZW4gbGEgcGVzdGHDsWEgKipEaWFncmFtYSBkZSBFc3RyZWxsYXMqKiBzZSBpbnRlcnByZXRhIHF1ZSBoYXkgdW5hIHZhcmllZGFkIG5vdG9yaWEgZGUgZXN0dWRpYW50ZXMgZW4gdMOpcm1pbm9zIGRlIGRlc2VtcGXDsW9zIGFzb2NpYWRvcyBjb24gbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIGVzdHVkaWFkYXMsIGluY2x1c28gY29uIGxhIHF1ZSBtaWRlIGVsIGV4YW1lbiBkZSBwcm9maWNpZW5jaWEgZW4gbGVuZ3VhIGV4dHJhbmplcmEsIHBhcmEgZWwgY2FzbyBpbmdsw6lzOiAqKlRPRUZMX1Njb3JlKiouIFBlcm8sIHRhbWJpw6luIGVzIG5vdG9yaWEgbGEgcHJlc2VuY2lhIGRlIGdydXBvcyBkZSBlc3R1ZGlhbnRlcyBjb24gZGVzZW1wZcOxb3MgYXByb3hpbWFkYW1lbnRlIGhvbW9nw6luZW9zIGVuIHRvZGFzIGxhcyB2YXJpYWJsZXMgZXN0dWRpYWRhcywgYXVucXVlIHN1cyBlc2NhbGFzIGRlIGRlc2VtcGXDsW8gdmFyaWFuLg0KDQpDb21wbGVtZW50YXJpYW1lbnRlIGEgbG9zIGRpYWdyYW1hcyBkZSBlc3RyZWxsYXMsIGxhIHBlc3Rhw7FhICoqQ2FyYXMgZGUgQ2hlcm5vZmYqKiBtdWVzdHJhIHF1ZSBsYSB2YXJpZWRhZCBkZSBlc3R1ZGlhbnRlcyBlcyBzZW5zaWJsZSBkZSBlc3RhYmxlY2VyLiBDb24gcmVsYXRpdmEgY2xhcmlkYWQsIGxhcyAqKkNhcmFzIGRlIENoZXJub2ZmKiogbsO6bWVybyAxLCAxMCwgMjEgeSA4LCAxOSwgMjIsIHB1ZWRlbiBjb25mb3JtYXIgdW4gcGFyIGRlIGdydXBvcyBkZSBlc3R1ZGlhbnRlcyBxdWUgbXVlc3RyYW4gZGVzZW1wZcOxb3Mgc2lnbmlmaWNhdGl2b3MgZW4gbGFzIHZhcmlhYmxlcyBtZWRpZGFzLCBhdW5xdWUgY29uIGNhbWJpb3MgZGUgZXNjYWxhOyBlcyBkZWNpciwgbG9zIGRlbCBzZWd1bmRvIGdydXBvIHNlIGRlc2VtcGXDsWFuIG1lam9yIHF1ZSBsb3MgZGVsIHByaW1lcm8gY29uc2lkZXJhbmRvIHRvZGFzIGxhcyB2YXJpYWJsZXMgZXN0dWRpYWRhcy4gRXN0byBjb21wYWdpbmEgY29uIGxvIG1vc3RyYWRvIGVuIGVsICoqRGlhZ3JhbWEgZGUgRXN0cmVsbGFzKiouDQoNClBvciDDumx0aW1vLCBlcyByZWxldmFudGUgbWVuY2lvbmFyIHF1ZSBsYXMgZXZpZGVuY2lhcyBkZXNjcmlwdGl2YXMgZXhwdWVzdGFzIGVuIGVzdGUgYXBhcnRhZG8gZXN0w6luIGVuIGNvbnRyYSBkZSBjb25zaWRlcmFyIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcyBsaW1pdGFkbyBhIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyB0ZW5nYSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBFc3RvIHNlIGVzdHVkaWEgZW4gbGEgW3NlY2Npw7NuIDVdKCNzZWM1KS4NCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMgW1NBXQ0KYGBge3IgRGlhZ3JhbWFfQ29uanVudG9fRERDX1NBLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmdncGFpcnMoQWRtaXNzaW9uX0RhdGFzZXRbLC1jKDEsMiw4LDkpXSkNCmBgYA0KDQojIyMjIERpYWdyYW1hIENvbmp1bnRvIGRlIERpc3BlcnNpw7NuLCBEaXN0cmlidWNpw7NuIHkgQ29ycmVsYWNpb25lcyBbQ0E6R0VdDQpgYGB7ciBEaWFncmFtYV9Db25qdW50b19ERENfQ0FfR0UsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZ2dwYWlycyhBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsLCBjb2x1bW5zID0gYygzOjcsMTApLCBhZXMoY29sb3IgPSBHZW5kZXIsIGFscGhhID0gMC41KSwgdXBwZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCJjb3IiLCBzaXplID0gMi41KSkpDQpgYGANCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMgW0NBOlJFXQ0KYGBge3IgRGlhZ3JhbWFfQ29uanVudG9fRERDX0NBX1JFLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmdncGFpcnMoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCwgY29sdW1ucyA9IGMoMzo3LDEwKSwgYWVzKGNvbG9yID0gUmVzZWFyY2gsIGFscGhhID0gMC41KSwgdXBwZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCJjb3IiLCBzaXplID0gMi41KSkpDQpgYGANCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMgW0NBOlVSXQ0KYGBge3IgRGlhZ3JhbWFfQ29uanVudG9fRERDX0NBX1VSLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmdncGFpcnMoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCwgY29sdW1ucyA9IGMoMzo3LDEwKSwgYWVzKGNvbG9yID0gVW5pdmVyc2l0eV9SYXRpbmcsIGFscGhhID0gMC41KSwgdXBwZXIgPSBsaXN0KGNvbnRpbnVvdXMgPSB3cmFwKCJjb3IiLCBzaXplID0gMi41KSkpDQpgYGANCg0KIyMjIyBEaWFncmFtYSBkZSBFc3RyZWxsYXMNCmBgYHtyIGRpYWdyYW1hX2RlX0VzdHJlbGxhcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzZXQuc2VlZCg3ODA3MjgpDQpBZG1pc3Npb25fRGF0YXNldF9NdWVzdHJlYWRvID0gQWRtaXNzaW9uX0RhdGFzZXRbc2FtcGxlKDE6bnJvdyhBZG1pc3Npb25fRGF0YXNldCksMjMpLC1jKDEsMiw4LDkpXQ0Kc3RhcnMoQWRtaXNzaW9uX0RhdGFzZXRfTXVlc3RyZWFkbywgbGVuID0gMSwgY2V4ID0gMC40LCBrZXkubG9jID0gYygxMCwgMiksIGRyYXcuc2VnbWVudHMgPSBUUlVFKQ0KYGBgDQoNCiMjIyMgQ2FyYXMgZGUgQ2hlcm5vZmYNCmBgYHtyIGNhcmFzX2RlX0NoZXJub2ZmLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOCkNCkFkbWlzc2lvbl9EYXRhc2V0X011ZXN0cmVhZG8gPSBBZG1pc3Npb25fRGF0YXNldFtzYW1wbGUoMTpucm93KEFkbWlzc2lvbl9EYXRhc2V0KSwyMyksLWMoMSwyLDgsOSldDQpmYWNlcyhBZG1pc3Npb25fRGF0YXNldF9NdWVzdHJlYWRvKQ0KYGBgDQoNCjxhIG5hbWU9InNlYzUiPjwvYT4NCg0KIyMgKio1LiBOb3JtYWxpZGFkIE11bHRpdmFyaWFkYSoqDQpDb21vIG1lbmNpb25hIFtAQ1BFTVBvcnJhczIwMTZdIHBhcmEgaW5kYWdhciBvIGVzdGFibGVjZXIgZWwgdGlwbyBkZSBkaXN0cmlidWNpw7NuIG11bHRpdmFyaWFkYSBkZSB1biBjb25qdW50byBkZSBkYXRvcyBzZSBwdWVkZSByZWN1cnJpciBhIHByb2NlZGltaWVudG9zIGRlc2NyaXB0aXZvcywgY29tbyBsb3MgZ3LDoWZpY29zLCBvIGEgcHJvY2VkaW1pZW50b3MgaW5mZXJlbmNpYWxlcywgY29tbyBsYXMgcHJ1ZWJhcyBlc3RhZMOtc3RpY2FzLiBFbiBlc3RlIHNlbnRpZG8sIHNlIGFsY2FuemEgZ2VuZXJhbGl6YWNpw7NuIGRlIHJlc3VsdGFkb3MgYWwgdXNhciBsYXMgZXN0b3Mgw7psdGltb3MsIHNpIGJpZW4gbG9zIHByaW1lcm9zIGFwb3lhbiBhIGxhcyBpbnRlcnByZXRhY2lvbmVzLg0KDQpFbiBlc3RlIGFwYXJ0YWRvIHNlIGNvbnRlbXBsYSBlbCB1c28gZGUgcHJvY2VkaW1pZW50b3MgaW5mZXJlbmNpYWxlcyBwYXJhIGRldGVybWluYXIgc2kgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbywgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIHNlIGRpc3RyaWJ1eWUgbm9ybWFsIG11bHRpdmFyaWFkbyAoRE5NKS4gTGFzIHBydWViYXMgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgKFBOTSkgYSBsYXMgcXVlIHNlcsOhIHNvbWV0aWRvIHNvbjogTWFyZGlhLCBIZW56ZS1aaXJrbGVyLCBEb29ybmlrLUhhbnNlbiB5IFJveXN0b24uIFBhcmEgZXN0YXMgcHJ1ZWJhcyBkZSBub3JtYWxpZGFkIGxvcyB0ZXN0IG9iZWRlY2VuIGEgdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSAkXGFscGhhID0gMC4wNSQgeSBhIGxhcyBoaXDDs3Rlc2lzOiQkSF8wOiBcdGV4dCB7TGFzIHZhcmlhYmxlcyB0aWVuZW4gdW5hIEROTX0kJCAkJEhfMTogXHRleHQge0xhcyB2YXJpYWJsZXMgTk8gdGllbmVuIHVuYSBETk19JCQgDQoNCkxhIHBydWViYSBkZSBNYXJkaWEgc2UgYmFzYSBlbiBleHRlbnNpb25lcyBkZSBhc2ltZXRyw61hIHkgY3VydG9zaXMsIGVsIGN1YWRyYWRvIGRlIGxhIGRpc3RhbmNpYSBkZSBNYWhhbGFub2JpcywgbGEgY2FudGlkYWQgZGUgdmFyaWFibGVzICRwJCBwb3IgdHJhdGFyIHkgbGEgY2FudGlkYWQgZGUgcmVnaXN0cm9zICRuJC4gQWRlbcOhcywgY29uc2lkZXJhIHF1ZSBsYSBwcnVlYmEgZXN0YWTDrXN0aWNhIHBhcmEgbGEgYXNpbWV0csOtYSB0aWVuZSB1bmEgZGlzdHJpYnVjacOzbiAkXGNoaV4yJCB5IGxhIHBydWViYSBlc3RhZMOtc3RpY2EgcGFyYSBsYSBjdXJ0b3NpcyBzZSBkaXN0aXJidXllIGFwcm94aW1hZGFtZW50ZSBub3JtYWwuIExvcyBkZXRhbGxlcyBzb2JyZSBsb3MgcGFyw6FtZXRyb3MgZGUgbGFzIGRpc3RyaWJ1Y2lvbmVzIHB1ZWRlbiBjb25zdWx0YXJzZSBlbiBlbCB0cmFiYWpvIGRlIFtAQ1BFTVBvcnJhczIwMTZdLg0KDQpMYSBwcnVlYmEgZGUgSGVuemUtWmlya2xlciBzZSBiYXNhIGVuIGxhIGRpc3RhbmNpYSBmdW5jaW9uYWwsIGRhZG8gcXVlIHNpIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHByZXNlbnRhIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBtdWx0aXZhcmlhZGEsIGVsIGVzdGFkw61zdGljbyBkZSBsYSBwcnVlYmEgc2UgZGlzdHJpYnV5ZSBhcHJveGltYWRhbWVudGUgY29tbyB1bmEgbG9nbm9ybWFsLCBjdXlvcyBwYXLDoW1ldHJvcyBkZSBtZWRpYSAkXG11JCB5IHZhcmlhbnphICRcc2lnbWFeMiQgcHVlZGVuIHNlciBjb25zdWx0YWRvcyBlbiBbQENQRU1Qb3JyYXMyMDE2XS4NCg0KTGEgcHJ1ZWJhIGRlIERvb3JuaWstSGFuc2VuIGVzdMOhIGJhc2FkYSBlbiBsYSBhc2ltZXRyw61hIHkgbGEgY3VydG9zaXMgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgbXVsdGl2YXJpYWRvcywgcXVlIHNlIHRyYW5zZm9ybWEgcGFyYSBnYXJhbnRpemFyIGxhIGluZGVwZW5kZW5jaWEuIEVzIGNvbnNpZGVyYWRhIG3DoXMgcG90ZW50ZSBxdWUgbGEgcHJ1ZWJhIGRlIFNoYXBpcm8tV2lsayBwYXJhIGNhc29zIG11bHRpdmFyaWFkb3MuIFN1IGVzdGFkw61zdGljbyBkZSBwcnVlYmEgZXN0w6EgZGVmaW5pZG8gY29tbyBsYSBzdW1hIGRlIGxhcyB0cmFuc2Zvcm1hY2lvbmVzIGFsIGN1YWRyYWRvIGRlIGxhIGFzaW1ldHLDrWEgeSBsYSBjdXJ0b3NpcywgeSBzaWd1ZSwgYXByb3hpbWFkYW1lbnRlLCB1bmEgZGlzdHJpYnVjacOzbiAkXGNoaV4yJC4gTG9zIGRldGFsbGVzIGRlIGxhIHBydWViYSBwdWVkZW4gc2VyIGNvbnN1bHRhZG9zIGVuIFtAT1RVTU5Eb29ybmlrX0hhbnNlbjIwMDhdLg0KDQpMYSBwcnVlYmEgZGUgUm95c3RvbiByZWN1cnJlIGEgbGFzIHBydWViYXMgU2hhcGlyby1XaWxrIG8gU2hhcGlyby1GcmFuY2lhIHBhcmEgcHJvYmFyIGxhIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhLiBBc8OtLCBzaSAgbGEgY3VydG9zaXMgZXMgbWF5b3IgcXVlIDMsIGxhIHBydWViYSBkZSBSb3lzdG9uIHVzYSBTaGFwaXJvLUZyYW5jaWEgcGFyYSBkaXN0cmlidWNpb25lcyBsZXB0b2N1cnRpY2FzLiBNaWVudHJhcyBxdWUgcGFyYSBkaXN0cmlidWNpb25lcyBwbGF0aWN1cnRpY2FzIHVzYSBTaGFwaXJvLVdpbGsuIEVuIGVsbGEgbG9zIHBhcsOhbWV0cm9zIHNvbiBvYnRlbmlkb3MgcG9yIGFwcm94aW1hY2lvbmVzIHBvbGlub21pYWxlcywgZXN0byBwdWVkZSBzZXIgY29uc3VsdGFkbyBlbiBbQENQRU1Qb3JyYXMyMDE2XS4NCg0KIyMjIDUuMS4gUGxhbnRlYW1pZW50byBkZWwgUHJvYmxlbWENCkNvbiBiYXNlIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikgc2UgaGFyw6EgdW5hIHBydWViYSBlc3RhZMOtc3RpY2EgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEsIGNvbiB1biBuaXZlbCBkZSBzaWduaWZpY2FuY2lhICRcYWxwaGE9MC4wNSQsIHBhcmEgZXN0YWJsZWNlciBzaSBzdXMgZGF0b3MgbcOpdHJpY29zIHByb3ZpZW5lbiBkZSB1bmEgcG9ibGFjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLiBTZSByZWN1ZXJkYSBxdWUgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIGRlbCBjb25qdW50byBkZSBkYXRvcyAoZW4gZXNjYWxhZGEgZGUgbWVkaWNpw7NuIGRlIHJhesOzbikgc29uOiAqKkdSRSBTY29yZSoqLCAqKlRPRUZMIFNjb3JlKiosICoqU09QKiosICoqTE9SKiosICoqQ0dQQSoqIHkgKipDaGFuY2Ugb2YgQWRtaXQqKi4NCg0KIyMjIDUuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcywgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIG5vIHNlIGRpc3RyaWJ1eWUgbm9ybWFsIG11bHRpdmFyaWFkby4gRW4gcGFydGljdWxhcjoNCg0KTGEgKipQTk0gZGUgTWFyZGlhKiogZXN0YWJsZWNlIHF1ZSBzaSBhbWJhcyBwcnVlYmFzIChwYXJhIGFzaW1ldHLDrWEgeSBjdXJ0b3NpcykgaW5kaWNhbiB1bmEgbm9ybWFsaWRhZCBtdWx0aXZhcmlhbnRlLCBsb3MgZGF0b3Mgc2lndWVuIHVuYSBETk0gY29uIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgJFxhbHBoYT0wLjA1JDsgc2luIGVtYmFyZ28sIGVsIGNhc28gdHJhdGFkbyBlcyBjb250cmFyaW8gYSBlc3RvLiBPYnPDqXJ2ZXNlIGEgdHJhdsOpcyBkZSBsYSBwZXN0YcOxYSAqKlBOTSBNYXJkaWEqKiBxdWUgbG9zICRwLXZhbHVlJCBwYXJhIGxhIGFzaW1ldHLDrWEgKFNrZXduZXNzKSB5IGN1cnRvcmlzIChLdXJ0b3Npcykgc29uIG1heW9yZXMgcXVlIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEuIFBvciBsbyB0YW50bywgbGFzIGV2aWRlbmNpYXMgbm8gYXBveWFuIHVuYSBoaXDDs3Rlc2lzIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHBhcmEgZWwgY29uanVudG8gZGUgZGF0b3MgcmVzdHJpbmdpZG8gYSBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMuDQoNCkxhICoqUE5NIGRlIFBOTSBIZW56ZS1aaXJrbGVyKiogZXN0YWJsZWNlIHF1ZSBlbCBlc3RhZMOtc3RpY28gZGUgcHJ1ZWJhIG5vIHNlIGRpc3RyaWJ1eWUgYXByb3hpbWFkYW1lbnRlIGNvbW8gbG9nbm9ybWFsIGRhZG8gcXVlIHN1ICRwLXZhbHVlJCBlcyBtZW5vciBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSAkXGFscGhhPTAuMDUkLCBvYnPDqXJ2ZXNlIGVzdG8gYSB0cmF2w6lzIGRlIGxhIHBlc3Rhw7FhICoqUE5NIEhlbnplLVppcmtsZXIqKi4gQXPDrSwgcG9yIGNvbnRyYXJyZWPDrXByb2NvIGRlIGxhIGltcGxpY2FjacOzbiBmb3JtdWxhZGEgZW4gbGEgZGVzY3JpcGNpw7NuIGRlIGxhIHBydWViYSBlbiBsYSBbc2VjY2nDs24gNV0oI3NlYzUpLCBlbCBjb25qdW50byBkZSBkYXRvcyBubyBlc3TDoSBhcG95YWRvIHBvciBsYXMgZXZpZGVuY2lhcyBwYXJhIHNlZ3VpciB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgbXVsdGl2YXJpYWRhLg0KDQpMYSAqKlBOTSBkZSBEb29ybmlrLUhhbnNlbioqIGVzdGFibGVjZSBxdWUgc3UgZXN0YWTDrXN0aWNvIGRlIHBydWViYSBubyBzaWd1ZSB1bmEgZGlzdHJpYnVjacOzbiBhcHJveGltYWRhbWVudGUgJFxjaGleMiQgZGFkbyBxdWUgc3UgJHAtdmFsdWUkIGVzIG1lbm9yIHF1ZSBlbCBuaXZlbCBkZSBzaWduaWZpY2FuY2lhICRcYWxwaGE9MC4wNSQsIG9ic8OpcnZlc2UgZXN0byBhIHRyYXbDqXMgZGUgbGEgcGVzdGHDsWEgKipQTk0gRG9vcm5pay1IYW5zZW4qKi4gUG9yIGxvIHRhbnRvLCBsYXMgZXZpZGVuY2lhcyBlc3TDoW4gbGVqb3MgZGUgYXBveWFyIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcyBzaWd1ZSB1bmEgRE5NLg0KDQpMYSAqKlBOTSBkZSBSb3lzdG9uKiogZXN0YWJsZWNlIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcyByZWR1Y2lkbyBhIHN1cyB2YXJpYWJsZXMgbnVtw6lyaWNhcyBubyBzaWd1ZSB1bmEgRE5NLCBkYWRvIHF1ZSBzdSAkcC12YWx1ZSQgZXMgbWVub3IgcXVlIGVsIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgJFxhbHBoYT0wLjA1JC4gT2Jzw6lydmVzZSBlc3RvIGEgdHJhdsOpcyBkZSBsYSBwZXN0YcOxYSAqKlBOTSBSb3lzdG9uKiouDQoNCkVuIGdlbmVyYWwsIHB1ZG8gY29uc3RhdGFyc2UgcXVlIHBhcmEgdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSAkXGFscGhhPTAuMDUkIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHJlZHVjaWRvIGEgc3VzIHZhcmlhYmxzIG51bcOpcmljYXMgbm8gc2lndWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIG11bHRpdmFyaWFkYS4NCg0KIyMjIyBQTk0gTWFyZGlhDQpgYGB7ciBQTk1fTWFyZGlhLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCm12bihBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBtdm5UZXN0PSJtYXJkaWEiKQ0KYGBgDQoNCiMjIyMgUE5NIEhlbnplLVppcmtsZXINCmBgYHtyIFBOTV9IZW56ZV9aaXJrbGVyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCm12bihBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBtdm5UZXN0PSJoeiIpDQpgYGANCg0KIyMjIyBQTk0gRG9vcm5pay1IYW5zZW4NCmBgYHtyIFBOTV9Eb29ybmlrX0hhbnNlbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQptdm4oQWRtaXNzaW9uX0RhdGFzZXRbLC1jKDEsMiw4LDkpXSwgbXZuVGVzdD0iZGgiKQ0KYGBgDQoNCiMjIyMgUE5NIFJveXN0b24NCmBgYHtyIFBOTV9Sb3lzdG9uLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCm12bihBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBtdm5UZXN0PSJyb3lzdG9uIikNCmBgYA0KDQo8YSBuYW1lPSJmYXNlMiI+PC9hPg0KDQojIyAqKk9iamV0aXZvIHkgQW5vdGFjaW9uZXMgOjogRmFzZSAyKioNCiMjICoqW0NvbXBvbmVudGVzIFByaW5jaXBhbGVzXSoqDQpFbiB0w6lybWlub3MgZ2VuZXJhbGVzLCBlc3RhIHNlZ3VuZGEgZXRhcGEgZGUgZXN0dWRpbyBtb3N0cmFyw6EgY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzIGNvbiBiYXNlIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHRyYXRhZG8gZW4gbGEgZmFzZSBbMV0oI3NlYzEpLCBwZXJvIGFob3JhIGRlc2RlIHVuIGVuZm9xdWUgZGUgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIHNvYnJlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcywgcXVlIGluY2x1aXLDoTogc2VsZWNjacOzbiwgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24sIGNvbnRyaWJ1Y2lvbmVzIGUgaW50ZXJwcmV0YWNpw7NuLg0KDQpSZWN1w6lyZGVzZSBxdWUgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbyBlcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHkgbG9zIHJlZmVyZW50ZXMgdGXDs3JpY29zIGVuIGxhIFtzZWNjacOzbiAxXSgjc2VjMSkuDQoNClBvciDDumx0aW1vLCBlc3RlIHRyYWJham8gZnVlIHByb2Nlc2FkbyBjb24gYHIgUi52ZXJzaW9uLnN0cmluZ2AgbWVkaWFkbyBwb3IgUlN0dWRpbyAyMDIyLjEyLjAgQnVpbGQgMzUzIGVuIHVuYSBwbGF0YWZvcm1hIHg4Nl82NC13NjQtbWluZ3czMi4gQWRlbcOhcywgcG9yIHN1IG5hdHVyYWxlemEgZGUgcHVibGljYWNpw7NuIGVuIGzDrW5lYSB5IHBhcmEgY3VtcGxpciBjb24gZWwgcmVxdWlzaXRvIHRlbXBvcmFsIGRlIGVudHJlZ2EsIHNlcsOhIGFjdHVhbGl6YWRvLCBjb21vIG3DoXhpbW8sIGhhc3RhIGxhcyAxMTo1OSBwLm0uIGRlbCBkb21pbmdvIDI2IGRlIGZlYnJlcm8gZGUgMjAyMy4NCg0KPGEgbmFtZT0ic2VjNyI+PC9hPg0KDQojIyAqKjcuIFNlbGVjY2nDs24gZGUgQ29tcG9uZW50ZXMqKg0KQ29tbyBlcyBtZW5jaW9uYWRvIGVuIGVsIHRyYWJham8gZGUgW0BBRURNRGlhei1Nb3JhbGVzMWVkXSBlbCBBbsOhbGlzaXMgZGUgQ29tcG9uZW50ZXMgUHJpbmNpcGFsZXMgKGVuIGFkZWxhbnRlIEFDUCkgcmVlc3RydWN0dXJhIHVuIGNvbmp1bnRvIGRlIGRhdG9zIG11bHRpdmFyaWFkbyBhIHRyYXbDqXMgZGUgbGEgcmVkdWNjacOzbiBkZSBsYSBjYW50aWRhZCBkZSBzdXMgdmFyaWFibGVzLCBlbiBjdXlvIHRyYW5zZm9uZG8gZXMgaW5uZWNlc2FyaW8gYXN1bWlyIG5pbmd1bmEgZGlzdHJpYnVjacOzbiBkZSBwcm9iYWJpbGlkYWQgZGUgZWxsYXMuIEVzdGEgcmVkdWNjacOzbiBlcyBsb2dyYWRhIGEgdHJhdsOpcyBkZSBjb21iaW5hY2lvbmVzIGxpbmVhbGVzIGRlIGxhcyB2YXJpYWJsZXMgb3JpZ2luYWxlcywgcXVlIGRlYmVyw6FuIGNvbnRlbmVyIGxhIG1heW9yIHZhcmlhYmlsaWRhZCBwb3NpYmxlIHByZXNlbnRlIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zLiBFbiBlc3RlIHNlbnRpZG8sIGVsIEFDUCBsb2dyYSBjcmVhciBudWV2YXMgdmFyaWFibGVzLCBjb25vY2lkYXMgY29tbyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgcXVlIHBvc2VlbiBjYXJhY3RlcsOtc3RpY2FzIGVzdGFkw61zdGljYXMgZGUgaW5kZXBlbmRlbmNpYSAoY29uIGJhc2UgZW4gZWwgc3VwdWVzdG8gZGUgbm9ybWFsaWRhZCkgeSBubyBjb3JyZWxhY2nDs24uDQoNCkVsIEFDUCBzZSBsb2dyYSBhIGxvIGxhcmdvIGRlIGxhcyBzaWd1aWVudGVzIGZhc2VzOiBnZW5lcmFjacOzbiBkZSBudWV2YXMgdmFyaWFibGVzLCByZWR1Y2Npw7NuIGRpbWVuc2lvbmFsIGRlbCBlc3BhY2lvIGRlIGxvcyBkYXRvcywgZWxpbWluYWNpw7NuIGRlIHZhcmFpYmxlcyBkZSBwb2NvIGFwb3J0ZSBlIGludGVycHJldGFjacOzbiBkZSBsb3MgY29tcG9uZW50ZXMgcmVzdWx0YW50ZXMgZW4gZWwgY29udGV4dG8gZGVsIHByb2JsZW1hIGRlbCBjdWFsIHNlIG9idHV2aWVyb24gbG9zIGRhdG9zLiBFc3RhcyBmYXNlcyBzZSBkZXNhcnJvbGxhbiBlbnRyZSBsYXMgc2VjY2lvbmVzIFs3XSgjc2VjNyksIFs4XSgjc2VjOCksIFs5XSgjc2VjOSkgeSBbMTBdKCNzZWMxMCkuDQoNCiMjIyA3LjEuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hDQpDb24gYmFzZSBlbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikgc2UgZGVtYW5kYSBwcmltZXJvIGVzdGFibGVjZXIgZWwgcG9yY2VudGFqZSBkZSB2YXJpYW56YSBleHBsaWNhZG8gcG9yIGNhZGEgZGltZW5zacOzbiB1bmEgdmV6IHByb2Nlc2FkbyBlbCBBQ1A7IHkgcG9zdGVyaW9ybWVudGUsIGNvbiBiYXNlIGVuIGVsIGF1dG92YWxvciBtZWRpbyBvIHVzYW5kbyB1biBkaWFncmFtYSBkZSBzZWRpbWVudGFjacOzbiwgZGVjaWRpciBjdcOhbnRvcyBjb21wb25lbnRlcyByZXRlbmVyLiANCg0KIyMjIDcuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBtdWVzdHJhIHF1ZSBlbCBjb25qdW50byBkZSBkYXRvcywgZW4gcmVsYWNpw7NuIGNvbiBzdXMgdmFyaWFibGVzIG51bcOpcmljYXMsIHB1ZWRlIHNlciByZXByZXNlbnRhZG8gcG9yIHVuIGNvbmp1dG8gZGUgdmFyaWFibGVzIG3DoXMgcGVxdWXDsW8gcXVlIHJldGllbmUgZWwgJDc3LjA1JCAkXCUkIGRlIGxhIHZhcmlhYmlsaWRhZCBkZWwgY29uanVudG8uIEVuIHBhcnRpY3VsYXI6DQoNCkxhICoqTWF0cml6IEFDUCoqIG11ZXN0cmEgc2VpcyBkaW1lbnNpb25lcyBkb25kZSBzb2xvIGxhIHByaW1lcmEgcmV0aWVuZSBlbCAkNzcuMDUkICRcJSQsIGxhIHNpZ3VpZW50ZSBlbCAkMTAuMzMkICRcJSQgeSBsYXMgZGVtw6FzIHNvbG8gcG9yY2VudGFqZXMgY29uIHBhcnRlIGVudGVyYSBkZSB1bmEgY2lmcmEuIEVuIGVzdGUgc2VudGlkbywgbGEgcmVwcmVzZW50YXRpdmlkYWQgZGUgbGEgY29tYmluYWNpw7NuIGxpbmVhbCBxdWUgZGVmaW5lIGEgbGEgZGltZW5zacOzbiAxIGVzIHNpZ25pZmljYXRpdmFtZW50ZSBhbHRhIGVuIGNvbXBhcmFjacOzbiBjb24gbGFzIGRlbcOhcy4gQ29tbyBlc3RhIG1hdHJpeiBlcyBtdWRhIGVuIHJlbGFjacOzbiBjb24gbGFzIHZhcmlhYmxlcyBvcmlnaW5hbGVzIHNlIHNpZ3VlIGluZGFnYW5kbyBsYSBpZGVudGlmaWNhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgbcOhcyBjb250cmlidXlhbiBhIGxhIGRpbWVuc2nDs24gZGUgdmFsb3IgcHJvcGlvIG3DoXMgYWx0by4NCg0KTGEgKipNYXRyaXogZGUgQ29ycmVsYWNpb25lcyoqIHBlcm1pdGUgY29udGludWFyIGNvbiBsYXMgZGVzY3JpcGNpb25lcyBkZSBsYXMgY29tYmluYWNpb25lcyBsaW5lYWxlcyBxdWUgY29uZm9ybWFuIGEgbGEgZGltZW5zacOzbiBkZSBtYXlvciBpbnRlcsOpczogbGEgZGltZW5zacOzbiAxLiBBc8OtLCBlc3RhIG1hdHJpeiwgY29tbyBzZSBtb3N0csOzIGVuIGxhIFtzZWNjacOzbiAzLjIuXSgjc2VjM18yKSwgIGF5dWRhIGEgdmVyaWZpY2FyIHF1ZSBsYSBpbnRlbnNpZGFkIGRlIGxhcyBjb3JlbGFjaW9uZXMgZXMgbcOhcyBhbHRhIHkgc2llbXByZSBwb3NpdGl2YSBlbnRyZSBsYXMgdmFyaWFibGVzOiBUT0VGTF9TY29yZSwgR1JFX1Njb3JlLCBDR1BBIHkgQ2hhbmNlX29mX0FkbWl0LCBhc3VudG8gZXNwZXJhZG8gZW4gcmVsYWNpw7NuIGNvbiBlbCBmZW7Ds21lbm8gZXN0dWRpYWRvLCBwb3IgbG8gdGFudG8sIHNlIHBvZHLDrWEgZXNwZXJhciBxdWUgZXN0YXMgdmFyaWFibGVzIHBhcnRpY2lwYXJhbiBlbiBsYSBjb21iaW5hY2nDs24gbGluZWFsIHF1ZSBkZWZpbmUgYSBsYSBkaW1lbnNpw7NuIDEuDQoNCkxhIHBlc3Rhw7FhIGRlICoqVmFsb3JlcyB5IFZlY3RvcmVzIFByb3Bpb3MqKiBtdWVzdHJhIGVzdG9zIG9iamV0b3MgY2FsY3VsYWRvcyBhIHBhcnRpciBkZSBsYSBtYXRyaXogZGUgY29ycmVsYWNpb25lcyBkZWwgY29uanVudG8gZGUgZGF0b3MuIEVuIGVzdGUgc2VudGlkbywgc2UgZ2FyYW50aXphIHF1ZSBsYSBzdW1hIGRlIGxvcyB2YWxvcmVzIHByb3Bpb3Mgc2VhIGlndWFsIGEgbGEgZGltZW5zacOzbiBkZSBkaWNoYSBtYXRyaXogeSBhIGxhIHZhcmlhYmlsaWRhZCB0b3RhbCBkZWwgY29uanVudG8sIHBvciBsbyBjdWFsIGxhcyBwcm9wb3JjaW9uZXMgZGUgcmV0ZW5jacOzbiBkZSB2YXJpYWJpbGlkYWQgc29uIGRlIGPDoWxjdWxvIGlubWVkaWF0by4gQWRlbcOhcywgbGEgbWF0cml6IGRlIHZlY3RvcmVzIHByb3Bpb3MgZGVmaW5lIHBhcmEgY2FkYSBjb21wb25lbnRlLCBlbiByZWxhY2nDs24gY29uIGNhZGEgdmFyaWFibGUgZGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBsb3MgY29lZmljaWVudGVzIGRlIGxhIGNvbWJpbmFjacOzbiBsaW5lYWwgcXVlIGxhIGNvbmZvcm1hbiwgcG9yIGVqZW1wbG8sIGNvbiB1biBhanVzdGUgYSBkb3MgY2lmcmFzIGRlY2ltYWxlcywgbGEgY29tcG9uZW50ZSAxIGVzdGFyw61hIHJlcHJlc2VudGFkYSBwb3IgbGEgY29tYmluYWNpw7NuIGxpbmVhbCAoZG9uZGUgJEckIGVzIEdSRV9TY29yZSwgJFQkIGVzIFRPRUZMX1Njb3JlLCAkUyQgZXMgU09QLCAkTCQgZXMgTE9SLCAkQ0ckIGVzIENHUEEgeSAkQ0EkIGVzIENoYW5jZV9vZl9BZG1pdCB5IGFkZW3DoXMsIHNvbiB2YXJpYWJsZXMgZXN0YW5kYXJpemFkYXMpOiQkQ29tcG9uZW50ZV8xID0gMC40MSpHKzAuNDIqVCswLjM5KlMrMC4zNypMKzAuNDQqQ0crMC40MypDQSQkSGFzdGEgZXN0ZSBwdW50bywgc2UgcHVlZGUgb2JzZXJ2YXIgcXVlIHNlIGRpc3BvbmUgZGUgdW4gbsO6bWVybyBkZSBkaW1lbnNpb25lcyBpZ3VhbCBhbCBuw7ptZXJvIGRlIHZhcmlhYmxlcyB0cmF0YWRhcywgY29uIGxhIHNhbHZlZGFkIHF1ZSBsYXMgdmFyaWFibGVzIG51ZXZhcyBzb24gaW5jb3JyZWxhZGFzIGVudHJlIHPDrSwgdmVyIGxhIHBlc3Rhw7FhICoqQ29ycmVsYWNpb25lcyBDb21wYXJhZGFzKiouDQoNClBvciDDumx0aW1vLCBlbCAqKkdyw6FmaWNvIGRlIENhdHRlbGwqKiB5IGVsICoqR3LDoWZpY28gZGUgQ2F0dGVsbC1LYWlzZXIqKiwgZGUgY29kbyB5IHNlZGltZW50YWNpw7NuLCBpbmR1Y2VuIGEgbGEgZWxlY2Npw7NuIGRlIHVuYSBjb21wb25lbnRlIGVuIGxhIHJlZHVjY2nDs24gZGUgZGltZW5zacOzbiBxdWUgcmV0aWVuZSBsYSBjYW50aWRhZCBkZSB2YXJpYWJpbGlkYWQgc3VmaWNpZW50ZSBwYXJhIHRyYXRhciBlbCBwcm9ibGVtYS4gU2luIGVtYmFyZ28sIGRlYmUgcmVzYWx0YXJzZSBxdWUgc2UgcHJvcG9uZSBlbGVnaXIgY29uIGJhc2UgZW4gY3JpdGVyaW9zIG3DoXMgdXNhZG9zLCBhIGNhbWJpbyBkZSBjcml0ZXJpb3MgZGUgYWNlcHRhY2nDs24gdW5pdmVyc2FsLiBFbCAqKkdyw6FmaWNvIGRlIENhdHRlbGwqKiBtdWVzdHJhIHF1ZSBsb3MgY2FtYmlvcyBlbiBsYSBwZW5kaWVudGUgaW5kaWNhbiBxdWUgbGEgY2FwYWNpZGFkIGV4cGxpY2F0aXZhIGRlIGxhIGRpbWVuc2nDs24gMSBlcyBhbHRhIGNvbXBhcmFkYSBjb24gZWwgcmVzdG8uIEFzw60sIGVsIGRlICoqQ2F0dGVsbC1LYWlzZXIqKiBhbCBjb25qdWdhciBlbCBpbnN0cnVtZW50byBncsOhZmljbyBhbnRlcmlvciBjb24gZWwgY3JpdGVyaW8gZGUgS2Fpc2VyIGVuIGxhIG1pc21hIGdyw6FmaWNhIGFwb3lhIHF1ZSBsYSBjYW50aWRhZCBkZSBkaW1lbnNpb25lcyBzdWZpY2llbnRlcyBwb3IgcmV0ZW5lciBlcyB1bmEsIGFjbGFyYW5kbyBxdWUgZXN0YSBlbGVjY2nDs24gcmV0ZW5nYSB1biBwb3JjZW50YWplIGRlIHZhcmlhYmlsaWRhZCBhZGVjdWFkbyBwYXJhIGVzdHVkaWFyIGVsIHByb2JsZW1hLg0KDQojIyMjIE1hdHJpeiBBQ1ANCmBgYHtyIE1hdHJpel9BQ1AsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZ2V0X2VpZ2VudmFsdWUoUENBKEFkbWlzc2lvbl9EYXRhc2V0WywtYygxLDIsOCw5KV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKQ0KYGBgDQoNCiMjIyMgTWF0cml6IGRlIENvcnJlbGFjaW9uZXMNCmBgYHtyIE1hdHJpel9kZV9Db3JyZWxhY2lvbmVzfQ0Kcm91bmQoY29yKEFkbWlzc2lvbl9EYXRhc2V0WywtYygxLDIsOCw5KV0pLDIpDQpgYGANCg0KIyMjIyBWYWxvcmVzIHkgVmVjdG9yZXMgUHJvcGlvcw0KYGBge3IgVmFsb3Jlc195X1ZlY3RvcmVzX1Byb3Bpb3MsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KcHJpbmNvbXAoQWRtaXNzaW9uX0RhdGFzZXRbLC1jKDEsMiw4LDkpXSwgY29yID0gVFJVRSkkc2Rldl4yDQpwcmluY29tcChBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBjb3IgPSBUUlVFKSRsb2FkaW5nc1sgLDE6Nl0NCmBgYA0KDQojIyMjIENvcnJlbGFjaW9uZXMgQ29tcGFyYWRhcw0KYGBge3IgQ29ycmVsYWNpb25lc19Db21wYXJhZGFzLCBmaWcuYWxpZ249J2NlbnRlcid9DQpwYXIobWZyb3c9YygxLDIpKQ0KY29ycnBsb3Q6OmNvcnJwbG90KGNvcihBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldKSwgbWV0aG9kID0gImNvbG9yIiwgdHlwZSA9ICJ1cHBlciIsIG51bWJlci5jZXggPSAwLjQpDQpjb3JycGxvdDo6Y29ycnBsb3QoY29yKHByaW5jb21wKEFkbWlzc2lvbl9EYXRhc2V0WywtYygxLDIsOCw5KV0sIGNvciA9IFRSVUUpJHNjb3JlcyksIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCBudW1iZXIuY2V4ID0gMC40KQ0KYGBgDQoNCiMjIyMgR3LDoWZpY28gZGUgQ2F0dGVsbA0KYGBge3IgR3JhZmljb19kZV9DYXR0ZWxsLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfZWlnKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSwgYWRkbGFiZWxzID0gVCwgeWxpbT1jKDAsOTApLCBtYWluID0gIiIpDQpgYGANCg0KIyMjIyBHcsOhZmljbyBkZSBDYXR0ZWxsLUthaXNlcg0KYGBge3IgR3JhZmljb19kZV9DYXR0ZWxsX0thaXNlciwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzY3JlZShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLGZhY3RvcnMgPSBGQUxTRSwgcGMgPSBUUlVFLCBtYWluID0iIikNCmBgYA0KDQo8YSBuYW1lPSJzZWM4Ij48L2E+DQoNCiMjICoqOC4gQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24qKg0KQWwgcmV0b21hciBlbCB0cmFiYWpvIGRlIFtAQUVETURpYXotTW9yYWxlczFlZF0gc2UgdmVyaWZpY2EgcXVlLCB1bmEgdmV6IHJlZHVjaWRhIGxhIGRpbWVuc2lvbmFsaWRhZCBkZWwgY29uanVudG8gZGUgZGF0b3MgeSBlbnRlbmRpZG8gcXVlIHN1cyB2YXJpYWJsZXMgKGVzdGFuZGFyaXphZGFzKSBlc3TDoW4gcmVwcmVzZW50YWRhcyBncsOhZmljYW1lbnRlIHBvciBwcm95ZWNjaW9uZXMgZGUgbGEgaGlwZXJlc2ZlcmEgZGUgY29ycmVsYWNpb25lcywgZXMgbmVjZXNhcmlvIGluaWNpYXIgbGEgaW50ZXJwcmV0YWNpw7NuIGRlIGNvbXBvbmVudGVzIGEgcGFydGlyIGRlIGRpY2hhcyBjb3JyZWxhY2lvbmVzLCBwYXJhIGx1ZWdvIGxhIGNhbGlkYWQgZGUgc3VzIHJlcHJlc2VudGFjaW9uZXMgZGFkYSBsYSByZWR1Y2Npw7NuIGRpbWVuc2lvbmFsIGRlbCBjb25qdW50byBkZSBkYXRvcyBlbiB0w6lybWlub3MgZGUgc3VzIHZhcmlhYmxlcy4NCg0KIyMjIDguMS4gUGxhbnRlYW1pZW50byBkZWwgUHJvYmxlbWENCkNvbiBiYXNlIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikgc2UgZGVtYW5kYSBkZXRlcm1pbmFyIGxhIGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyByZXNwZWN0byBhIGxhIGNhbnRpZGFkIGRlIGRpbWVuc2lvbmVzIGNhbGN1bGFkYXMgcXVlIHJldGllbmVuIGxhIG1heW9yIGNhbnRpZGFkIGRlIHZhcmlhYmlsaWRhZCwgdmVyIGxhIFtzZWNjacOzbiA3XSgjc2VjNykuDQoNCiMjIyA4LjIuIERlc2Fycm9sbG8gZGVsIEFuw6FsaXNpcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KTGEgbmF2ZWdhY2nDs24gYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgbXVlc3RyYSBxdWUgbGEgcmVkdWNjacOzbiBkZSBsYSBkaW1lbnNpb25hbGlkYWQgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGNvbmR1Y2UgYW5hbGl6YXIgbGFzIGNhbGlkYWRlcyBkZSByZXByZXNlbnRhY2nDs24gZW4gdMOpcm1pbm9zIGRlIGxhIGVzY2FsYSBkZSBjb250cmlidWNpb25lcyByZWxhdGl2YXMgYmFzYWRhIGVuIHVuIGNvY2llbnRlIGRlIHByb3llY2Npb25lcyBjb24gcHJvcGllZGFkZXMgYWRpdGl2YXMgeSBkZSByZXNwdWVzdGEgZW4gZXNjYWxhIGNvbnRpbnVhIGVudHJlICQwJCB5ICQxJC4gQXPDrSwgZW4gcGFydGljdWxhcjoNCg0KRWwgKipDw61yY3VsbyBkZSBDb3JyZWxhY2lvbmVzKiogZXhwcmVzYSBxdWUgc2UgcHVlZGUgY29uY2ViaXIgdW5hIGNvbXBlbmVudGUgdGlwbyB0YW1hw7FvIGVuIGVsIHNlbnRpZG8gZGUgcXVlIGxhIGRpbWVuc2nDs24gMSBtdWVzdHJhIGVuIMOpbCB1bmEgY29ycmVsYWNpw7NuIHBvc2l0aXZhIGNvbiBsYXMgc2VpcyB2YXJpYWJsZXMgZGUgaW50ZXLDqXMsIGFkZW3DoXMgY2VyY2FuYXMgYSBsYSBmcm9udGVyYSBkZWwgY8OtcmN1bG8gdW5pdGFyaW8geSBzaWduaWZpY2F0aXZhbWVudGUgcHLDs3hpbWFzIGFsIGVqZSBxdWUgbGEgcmVwcmVzZW50YS4gUG9yIG90cm8gbGFkbywgbGEgZGltZW5zacOzbiAyIGNvbnRyYXBvbmUgYSBsYXMgdmFyaWFibGVzICoqTE9SKiogeSAqKlNPUCoqIGNvbiBsYXMgZGVtw6FzLiBPdHJvIGFzcGVjdG8gcG9yIHJlc2FsdGFyIGVzIGxhIGNvcnJlbGFjacOzbiBtb3N0cmFkYSBlbnRyZSBwYXJlcyBkZSB2YXJpYWJsZXMsIHF1ZSBlbiB0w6lybWlub3MgZGVsIGZlbsOzbWVubyBlc3R1ZGlhZG8gY29uc2VydmFuIHN1IG5hdHVyYWxlemEgY29ycmVsYWNpb25hbCBlc3BlcmFkYSBoYXN0YSBlc3RlIHB1bnRvIGRlbCBhbsOhbGlzaXMuIFVuIGVqZW1wbG8gcmVzYWx0YWJsZSBlcyBlbCBwYXIgKipTT1AqKiB5ICoqTE9SKiogcXVlLCBlbiBjaWVydG8gc2VudGlkbywgZXN0w6FuIGluZmx1aWRhcyBwb3IgbGEgc3ViamV0aXZpZGFkLCB2w6lhc2UgbGEgW3NlY2Npw7NuIDJdKCNzZWMyKS4NCg0KTGEgKipNYXRyaXogZGUgUmVwcmVzZW50YWNpw7NuKiosIHBvciBvdHJvIGxhZG8sIG11ZXN0cmEgdmFsb3JlcyBzaWduaWZpY2F0aXZhbWVudGUgY2VyY2Fub3MgYSAxIGRlbCBjb2NpZW50ZSBkZSBwcm95ZWNjaW9uZXMgY29zZW5vIGN1YWRyYWRvIGVuIHJlbGFjacOzbiBjb24gbGEgZGltZW5zacOzbiAxLiBFbiBlc3RlIHNlbnRpZG8sIGxvcyBwdW50b3MgcHJveWVjdGFkb3MgZXN0w6FuIGFsdGFtZW50ZSBhc29jaWFkb3MgY29uIGVzdGUgY29tcG9uZW50ZS4gQXPDrSwgbGEgZXN0YcOxYSBxdWUgbXVlc3RyYSBsYSAqKkNhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuKiogaW5kaWNhIGVuIHN1IGVzY2FsYSB1biBwaXNvIGFsdG8gZGUgJDAuODQkIGRlIGVzdGEgbWFuZXJhIGxhcyBjYWxpZGFkZXMgZGUgcmVwcmVzZW50YWNpw7NuLCBlbiByZWxhY2nDs24gY29uIGxhIGNvbXBvbmVudGUgMSwgZXN0w6FuIGVuY2FiZXphZGFzIHBvciAqKkNHUEEqKiB5IGNpZXJyYW4gY29uICoqU09QKiouIENhYmUgYWNsYXJhciBxdWUgbGEgZGltZW5zacOzbiAyIHNvc3RpZW5lIHVuYSBtZWpvciByZXByZXNlbnRhY2nDs24gZGUgKipMT1IqKiBxdWUgZGUgKipTT1AqKiwgcG9yIGxvIHRhbnRvLCBsYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBkZSBsYSBwcmltZXJhIGVuIHJlbGFjacOzbiBjb24gbGEgZGltZW5zacOzbiAxIHNlIHZlIGFmZWN0YWRhLg0KDQpQb3Igw7psdGltbywgbGFzICoqQ29vcmRlbmFkYXMgSW5kaXZpZHVhbGVzKiogYXl1ZGFuLCBhdW5xdWUgZGUgbWFuZXJhIG1lbm9zIGRpZ2VzdGl2YSwgYSBpZGVudGlmaWNhciBhIG5pdmVsIGRlIG9ic2VydmFjaW9uZXMgYSBsb3MgcGVyZmlsZXMgZGUgbG9zIHJlZ2lzdHJvcywgZW4gZXN0ZSBjYXNvIGVzdHVkaWFudGVzLCBlbiByZWxhY2nDs24gY29uIGxhcywgcG9yIGxvIG1lbm9zLCBkaW1lbnNpb25lcyBtw6FzIGltcG9ydGFudGVzIGRlIHJldGVuY2nDs24gZGUgdmFyaWFiaWxpZGFkOiBsYXMgY29tcG9uZW50ZXMgMSB5IDIuIFBvciBlamVtcGxvLCBhbCBvYnNlcnZhciBsb3MgcmVnaXN0cm9zIDEsIDksIDIzLCBzZSBtYW5pZmllc3RhbiBsYXMgc2VtZWphbnphcyBlbnRyZSAxIHkgMjMgZW4gb3Bvc2ljacOzbiBkZSBhbWJvcyBjb24gOSwgaW5jbHVzbyBhbCBjb25zaWRlcmFyIGEgbGEgdmFyaWFibGUgcGVvciByZXByZXNlbnRhZGEgKipTT1AqKi4NCg0KIyMjIyBDw61yY3VsbyBkZSBDb3JyZWxhY2lvbmVzDQpgYGB7ciBDaXJjdWxvX2RlX0NvcnJlbGFjaW9uZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9wY2FfdmFyKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGKSxjb2wudmFyPSIjM0I4M0JEIiwgcmVwZWwgPSBULCBjb2wuY2lyY2xlID0gIiNDRENEQ0QiLCBnZ3RoZW1lID0gdGhlbWVfYncoKSkNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBSZXByZXNlbnRhY2nDs24NCmBgYHtyIE1hdHJpel9kZV9SZXByZXNzZW50YWNpb25fQ09TMiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQooZ2V0X3BjYV92YXIoUENBKEFkbWlzc2lvbl9EYXRhc2V0WywtYygxLDIsOCw5KV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpKSkkY29zMg0KYGBgDQoNCiMjIyMgQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24NCmBgYHtyIENhbGlkYWRfZGVfbGFfUmVwcmVzZW50YWNpb24sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9wY2FfdmFyKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY29sLnZhcj0iY29zMiIsIGdyYWRpZW50LmNvbHM9YygiIzAwQUZCQiIsIiNFN0I4MDAiLCIjRkM0RTA3IiksIHJlcGVsID0gVFJVRSkNCmBgYA0KDQojIyMjIENvb3JkZW5hZGFzIEluZGl2aWR1YWxlcw0KYGBge3IgQ29vcmRlbmFkYXNfUmVnaXN0cm9zLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmhlYWQoKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkkaW5kJGNvb3JkLCBuID0gMjNMKQ0KYGBgDQoNCjxhIG5hbWU9InNlYzkiPjwvYT4NCg0KIyMgKio5LiBDb250cmlidWNpb25lcyoqDQpTZWfDum4gZWwgdHJhYmFqbyBkZSBbQEFFRE1EaWF6LU1vcmFsZXMxZWRdIGxhIGludGVycHJldGFjacOzbiBkZSByZXN1bHRhZG9zIGVzdMOhIHZpbmN1bGFkYSBjb24gZWwgY8OhbGN1bG8gZGUgY29vcmRlbmFkYXMsIGNvbnRyaWJ1Y2lvbmVzLCBjb3Nlbm9zIGN1YWRyYWRvcywgZXRjLCBwb3IgbG8gdGFudG8sIGxhIGNvbmNlcHR1YWxpemFjacOzbiBkZSBsYXMgdmFyaWFibGVzIGRlYmUgc2VyIGNsYXJhIHBhcmEgZXN0YWJsZWNlcmxhIGNvbiBsYSBtYXlvciBjbGFyaWRhZCBwb3NpYmxlLCBlcyBkZWNpciwgbG9zIGRhdG9zIGRlYmVuIHBvbmVyc2UgZW4gY29udGV4dG8uIEVuIGVzdGUgc2VudGlkbywgbGEgY29udHJpYnVjacOzbiBkZSB1bmEgdmFyaWFibGUgYSB1bmEgY29tcG9uZW50ZSBhbGxhbmEgZWwgY2FtaW5vIGRlIGxhIGludGVycHJldGFjacOzbiBkZSByZXN1bHRhZG9zLiBFc3RvIHNlIGhhY2UgZW4gZXN0ZSBhcGFydGFkbyBlbiBlbCBzZW50aWRvIGRlIGNhbGN1bGFyIGxvciBhcG9ydGVzIGNvbiBxdWUgY2FkYSB2YXJpYWJsZSBwYXJ0aWNpcGEgcGFyYSBkZWZpbmlyIGEgY2FkYSBjb21wb25lbnRlIGdlbmVyYWRhLg0KDQojIyMgOS4xLiBQbGFudGVhbWllbnRvIGRlbCBQcm9ibGVtYQ0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHNlIGRlbWFuZGEgZGV0ZXJtaW5hciBsYXMgY29udHJpYnVjaW9uZXMgcXVlIGhhY2UgY2FkYSB2YXJpYWJsZSBhIGxhIGNvbnN0cnVjY2nDs24gZGUgY2FkYSBjb21wb25lbnRlLg0KDQojIyMgOS4yLiBEZXNhcnJvbGxvIGRlbCBBbsOhbGlzaXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIHBlcm1pdGUgcmVjb25vY2VyIGVuIHJlcHJlc2VudGFjaW9uZXMgbnVtw6lyaWNhcyB5IGdyw6FmaWNhcyBsYXMgY29udHJpYnVjaW9uZXMgZGUgbGFzIHZhcmlhYmxlcyBkZWwgY29uanVudG8gZGUgZGF0b3MgYSBsYSBjb25zdHJ1Y2Npw7NuIGRlIGNhZGEgY29tcG9uZW50ZS4gQXPDrSwgc2UgZW50aWVuZGUgY3XDoW50YSB2YXJpYWJpbGlkYWQgZXhwbGljYSBjYWRhIHZhcmlhYmxlIGRlIGxhIHZhcmlhYmlsaWRhZCB0b3RhbCBkZSBsYSBjb21wb25lbnRlIGNvbiBxdWUgZXN0w6kgaW52b2x1Y3JhZGEuIGVuIHBhcnRpY3VsYXI6DQoNCkxhICoqTWF0cml6IGRlIENvbnRyaWJ1Y2lvbmVzKiogbXVlc3RyYSBlbiB0w6lybWlub3MgcmVsYXRpdm9zIGxhIHJldGVuY2nDs24gZGUgdmFyaWFiaWxpZGFkIHF1ZSB0aWVuZSBjYWRhIHZhcmlhYmxlIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgY2FkYSBjb21wb25lbnRlLiBBc8OtLCBsb3MgZGlhZ3JhbWFzIGRlIGJhcnJhcyB2aXN1YWxpemFkb3MgYSB0cmF2w6lzIGRlIGxhcyBwZXN0YcOxYXMgZGVzZGUgKipDb250cmlidWNpb25lcyBhIEQxKiogaGFzdGEgKipDb250cmlidWNpb25lcyBhIEQ2KiosIG11ZXN0cmFuIGNvbiBiYXNlIGVuIGRpYWdyYW1hcyBkZSBiYXJyYXMgbGFzIHJlc3BlY3RpdmFzIGNvbnRyaWJ1Y2lvbmVzIHF1ZSBoYWNlbiBsYXMgdmFyaWFibGVzIHBhcmEgZXhwbGljYXIgbGEgdmFyaWFuemFyIGVuIGNhZGEgY29tcG9uZW50ZTsgYWRlbcOhcywgY2FkYSBncsOhZmljbyBpbmNsdXllIHVuYSBsw61uZWEgcXVlIGF5dWRhIGEgaWRlbnRpZmljYXIgbGEgY29udHJpYnVjacOzbiBtZWRpYSwgZXN0byBheXVkYSBhIGlkZW50aWZpY2FyIGNvbiBtYXlvciBmYWNpbGlkYWQgYSBsYXMgdmFyaWFibGVzIHF1ZSBjb250cmlidXllbiBjb24gbWF5b3IgZXhwbGljYWNpw7NuIGRlIHZhcmlhYmlsaWRhZCBkZSBsb3MgY29tcG9uZW50ZXMgcXVlIGNvbmZvcm1hbi4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQxKiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpYW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqQ0dQQSoqLCAqKkNoYW5jZV9vZl9BZG1pdCoqLCAqKlRPRUZMX1Njb3JlKiogeSAqKkdSRV9TY29yZSoqIHJldGllbmVuIGFwcm94aW1hZGFtZW50ZSBlbCAkNzEuNzIkICRcJSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb21wb25lbnRlIDEuDQoNCkVuICoqQ29udHJpYnVjaW9uZXMgYSBEMioqIHNlIHZpc3VhbGl6YSBxdWUgbGFzIHZhcmlhYmxlcyBwb3IgZW5jaWFtYSBkZSBsYSBjb250cmlidWNpw7NuIG1lZGlhOiAqKkxPUioqIHkgKipTT1AqKiByZXRpZW5lbiBhcHJveGltYWRhbWVudGUgZWwgJDY3Ljg3JCAkXCUkIGRlIGxhIHZhcmlhYmlsaWRhZCBkZWwgY29tcG9uZW50ZSAyLg0KDQpFbiAqKkNvbnRyaWJ1Y2lvbmVzIGEgRDMqKiBzZSB2aXN1YWxpemEgcXVlIGxhcyB2YXJpYWJsZXMgcG9yIGVuY2lhbWEgZGUgbGEgY29udHJpYnVjacOzbiBtZWRpYTogKipTT1AqKiB5ICoqTE9SKiogcmV0aWVuZW4gYXByb3hpbWFkYW1lbnRlIGVsICQ4MS4zNyQgJFwlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgMy4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ0Kiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpYW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqQ2hhbmNlX29mX0FkbWl0KiogeSAqKlRPRUZMX1Njb3JlKiogcmV0aWVuZW4gYXByb3hpbWFkYW1lbnRlIGVsICQ1Ny43NiQgJFwlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNC4NCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQ1Kiogc2UgdmlzdWFsaXphIHF1ZSBsYXMgdmFyaWFibGVzIHBvciBlbmNpYW1hIGRlIGxhIGNvbnRyaWJ1Y2nDs24gbWVkaWE6ICoqR1JFX1Njb3JlKiogeSAqKlRPRUZMX1Njb3JlKiogcmV0aWVuZW4gYXByb3hpbWFkYW1lbnRlIGVsICQ5NS41MSQgJFwlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNS4NCg0KUG9yIMO6bHRpbW8sIGVuICoqQ29udHJpYnVjaW9uZXMgYSBENioqIHNlIHZpc3VhbGl6YSBxdWUgbGFzIHZhcmlhYmxlcyBwb3IgZW5jaWFtYSBkZSBsYSBjb250cmlidWNpw7NuIG1lZGlhOiAqKkNHUEEqKiB5ICoqQ2hhbmNlX29mX0FkbWl0KiogcmV0aWVuZW4gYXByb3hpbWFkYW1lbnRlIGVsICQ5Ni4wNiQgJFwlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbXBvbmVudGUgNi4NCg0KQ29uIGxvcyBkYXRvcyBwcm9jZXNhZG9zIGhhc3RhIGFob3JhIHNlIHB1ZWRlIHByb2NlZGVyIGNvbiBsYSBpbnRlcHJldGFjacOzbiBkZSBsb3MgY29tcG9uZW50ZXMuDQoNCiMjIyMgTWF0cml6IGRlIENvbnRyaWJ1Y2lvbmVzDQpgYGB7ciBNYXRyaXpfZGVfQ29udHJpYnVjaW9uZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KKGdldF9wY2FfdmFyKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSkpJGNvbnRyaWINCmBgYA0KDQojIyMjIENvbnRyaWJ1Y2lvbmVzIGEgRDENCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0RJTV8xLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfY29udHJpYihQQ0EoQWRtaXNzaW9uX0RhdGFzZXRbLC1jKDEsMiw4LDkpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMSwgdG9wID0gMTApDQpgYGANCg0KIyMjIyBDb250cmlidWNpb25lcyBhIEQyDQpgYGB7ciBDb250cmlidWNpb25lc19ESU1fMiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NvbnRyaWIoUENBKEFkbWlzc2lvbl9EYXRhc2V0WywtYygxLDIsOCw5KV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMw0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAzLCB0b3AgPSAxMCkNCmBgYA0KDQojIyMjIENvbnRyaWJ1Y2lvbmVzIGEgRDQNCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0RJTV80LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfY29udHJpYihQQ0EoQWRtaXNzaW9uX0RhdGFzZXRbLC1jKDEsMiw4LDkpXSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNCwgdG9wID0gMTApDQpgYGANCg0KIyMjIyBDb250cmlidWNpb25lcyBhIEQ1DQpgYGB7ciBDb250cmlidWNpb25lc19ESU1fNSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NvbnRyaWIoUENBKEFkbWlzc2lvbl9EYXRhc2V0WywtYygxLDIsOCw5KV0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEYpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBENg0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzYsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jb250cmliKFBDQShBZG1pc3Npb25fRGF0YXNldFssLWMoMSwyLDgsOSldLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSA2LCB0b3AgPSAxMCkNCmBgYA0KDQo8YSBuYW1lPSJzZWMxMCI+PC9hPg0KDQojIyAqKjEwLiBJbnRlcnByZXRhY2nDs24qKg0KQ29uIGJhc2UgZW4gW0BBRURNRGlhei1Nb3JhbGVzMWVkXSBzZSBzYWJlIHF1ZSBhIHBhcnRpciBkZSBsYXMgY29vcmRlbmFkYXMgZGUgbG9zIHJlZ2lzdHJvcyBkaW1lbnNpb25hbG1lbnRlIHJlZHVjaWRvcyBzZSBwdWVkZSB1YmljYXIgZW4gdW4gcGxhbm8gZGUgZmFjdG9yZXMgcGFyYSBlZmVjdG9zIGRlIGFuw6FsaXNpcyBlIGludGVycHJldGFjacOzbi4gQXPDrSwgbGFzIHZhcmlhYmxlcyByZWR1Y2lkYXMgc29uIGxhcyBjb21wb25lbnRlcyBwcmluY2lwYWxlcyBxdWUgc2UgZ3JhZmljYW4gY29tbyBlamVzIGVuIHVuIHBsYW5vLCB5IGxvcyB2YWxvcmVzIHF1ZSB0b21lbiBzb24gbG9zIHB1bnRhamVzIGRlIGxhcyBjb21wb25lbnRlcy4gQ29tbyBiaWVuIHNlIGV4cGxpY2EgZW4gZWwgbWlzbW8gdHJhYmFqbywgbGFzIGRpc3RhbmNpYXMgZW50cmUgbG9zIHB1bnRvcyBkZWZpbmlkb3MgcG9yIGxvcyBwdW50YWplcyBkZSBsYXMgY29tcG9uZW50ZXMgdGllbmUgdW4gc2lnbmlmaWNhZG8gcmVsZXZhbnRlIGFsIGF5dWRhciBhIGVzdGFibGVjZXIgc2VtZWphbnphcyBkZSBwZXJmaWxlcyBlbiBsYXMgb2JzZXJ2YWNpb25lcyBoZWNoYXMuIFNpbiBlbWJhcmdvLCBsb3MgdmFsb3JlcyBzZW1lamFudGVzIGRlIGxhcyB2YXJpYWJsZXMgcHVlZGVuIGRhcnNlIHNvbG8gZW4gYWxndW5hcyBkZSBlbGxhcywgc2luIGVzcGVyYXIgbmVjZXNhcmlhbWVudGUgYSBxdWUgc3VjZWRhIGVuIHRvZGFzLiBBc8OtLCBzZSBlc3BlcmEgcXVlIGxhcyBkaXN0YW5jaWFzIGVuIGVsIGVzcGFjaW8gZGltZW5zaW9uYWwgb3JpZ2luYWwgZGUgbGFzIG9ic2VydmFjaW9uZXMgcXVlZGVuIGJpZW4gcmVwcmVzZW50YWRhcyBlbiBlbCBlc3BhY2lvIHJlZHVjaWRvIGRlIGxhcyBjb21wb25lbnRlcy4NCg0KIyMjIDEwLjEuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hDQpDb24gYmFzZSBlbiBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikgc2UgZGVtYW5kYSBkZWZpbmlyIGUgaW50ZXJwcmV0YXIgc3VzIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLg0KDQojIyMgMTAuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwZXJtaXRlIHZpc3VhbGl6YXIgb2JqZXRvcyBncsOhZmljb3MgeSBtYXRyaWNpYWxlcyBxdWUsIGFsIGluY2x1aXIgbG8gaGVjaG8gZW4gbGFzIHNlY2Npb25lcyBhbnRlcmlvcmVzLCBheXVkYW4gYSByb2J1c3RlY2VyIGxhIGludGVycHJldGFjacOzbiBkZSBsYXMgY29tcG9uZW50ZXMgY2FsY3VsYWRhcy4gQ29tbyBzZSBtb3N0csOzIGVuIGxhIFtzZWNjacOzbiA3XSgjc2VjNyksIGxhIGNhbnRpZGFkIGRlIGNvbXBvbmVudGVzIHNlbGVjY2lvbmFkYXMgc2UgcmVkdWpvIChzZWfDum4gZWwgY3JpdGVyaW8gZGUgS2Fpc2VyKSBhIHVuYSB5IHNlIGVzdGFibGVjacOzIHF1ZSBsYSBjb21wb25lbnRlIDEgcmV0aWVuZSBlbCAkNzcuMDUkICRcJSQgZGUgbGEgdmFyaWFiaWxpZGFkIGRlIGxvcyBkYXRvcy4gQXPDrSwgZW4gZWwgY8OtcmN1bG8gZGUgY29ycmVsYWNpb25lcyBkZSBsYSBbc2VjY2nDs24gOF0oI3NlYzgpIHNlIGFwcmVjaWEgcXVlIGxhIHJlcHJlc2VudGFjacOzbiBkZSBsYXMgdmFyaWFibGVzIGNvbmp1Z2FkYXMgZW4gbGEgY29tcG9uZW50ZSAxIGxhIGNvbmZpZ3VyYW4gY29tbyB1bmEgZGUgdGlwbyB0YW1hw7FvLCBsbyBxdWUgcHVlZGUgaW50ZXJwcmV0YXJzZSBjb21vIHVuYSBlc3BlY2llIGRlIMOtbmRpY2UgZGUgcHJvcG9yY2lvbmFsaWRhZCBkaXJlY3RhLiBFc3RvIHRhbWJpw6luIHNlIGFwb3lhIGNvbiBiYXNlIGVuIGVsIGhlY2hvIGRlIHF1ZSB0b2RhcyBsYXMgdmFyaWFibGVzIHByZXNlbnRhbiBjYWxpZGFkZXMgZGUgcmVwcmVzZW50YWNpw7NuIGVudHJlICQwLjYyJCB5ICQwLjg4JC4gRW4gY29uc2VjdWVuY2lhLCBjdWFudG8gbWF5b3Igc2VhIGVsIHZhbG9yIGxhcyB2YXJpYWJsZXMgbWF5b3Igc2Vyw6EgZWwgZXN0YWRvIGRlIGZhdm9yYWJpbGlkYWQgZGUgcXVlIGVsIGVzdHVkaWFudGUgc2VhIGFkbWl0aWRvIHBvciBsYSB1bml2cnNpZGFkIGRlIHN1IHByZWZlcmVuY2lhLiBBc8OtLCBkYWRhIGxhIG5hdHVyYWxlemEgZGUgbGFzIHZhcmlhYmxlcyBlc3RhIGNvbXBvbmVudGUgcHVlZGUgcmVwcmVzZW50YXIgcGFyYSB1biBlc3R1ZGlhbnRlIHN1ICoqbWVkaWRhIGRlIGNvbXBldGl0aXZpZGFkIGZvcm1hdGl2YSoqLiBBbCByZXNwZWN0bzoNCg0KTGFzIHBlc3Rhw7FhcyAqKkJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgVG90YWxlcyoqIGVuICoqVVIqKiAoVW5pdmVyc2l0eSBSYXRpbmcpLCAqKkcqKiAoR2VuZGVyKSB5ICoqUioqIChSZXNlYXJjaCksIG11ZXN0cmFuLCBjb24gYmFzZSBlbiBsYXMgYWdydXBhY2lvbmVzIHF1ZSBlc3RhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHB1ZWRlbiBlc3RhYmxlY2VyLCBsYSByZXByZXNlbnRhY2nDs24gZW4gZGltZW5zaW9uYWxpZGFkIHJlZHVjaWRhIGVuIGVsIHBsYW5vIGRlIGZhY3RvcmVzIGRlIHJlZ2lzdHJvcyB5IGRpbWVuc2lvbmVzIGNvbiBiYXNlIGVuIGxvcyBwdW50YWplcyBwb3IgY29tcG9uZW50ZXMuIEVuIGVzdGUgc2VudGlkbywgZXMgcG9zaWJsZSBhcHJlY2lhciBxdWUgbGFzIGFncnVwYWNpb25lcyBjb24gYmFzZSBlbiAqKlVuaXZlcnNpdHlfUmF0aW5nKiogeSAqKlJlc2VhcmNoKiogY2FwdHVyYW4gZGlmZXJlbmNpYXMgYWNlbnR1YWRhcyBlbiBsYSBkaXN0cmlidWNpb25lcyBkZSBsYXMgb2JzZXJ2YWNpb25lcywgY29udHJhcmlvIGEgbGEgYWdydXBhY2nDs24gY29uIGJhc2UgZW4gKipHZW5kZXIqKi4NCg0KUG9yIMO6bHRpbW8sIHBhcmEgZmFjaWxpdGFyIGxhIHZlcmlmaWNhY2nDs24gZGUgbGEgdWJpY2FjacOzbiBkZSBwdW50YWplcyBlbiBlbCBwbGFubyBkZSBjb21wb25lbnRlcyAoZW4gcGFydGljdWxhciwgc2llbXByZSBjb25mb3JtYWRvIHBvciBsYXMgY29tcG9uZW50ZXMgMSB5IDIgcG9yIGVsIGludGVyw6lzIHF1ZSBzdWNpdGFuKSB5LCBhc2ltaXNtbywgbGFzIHNlbWVqYW56YXMgZGUgcGVyZmlsZXMgeSBsYXMgY29ycmVsYWNpb25lcyBlbnRyZSB2YXJpYWJsZXMsIHNlIGRpc3B1c28gZGUgbGFzIHBlc3Rhw7FhcyAqKkNvb3JkZW5hZGFzIEluZGl2aWR1YWxlcyBbU3ViY29uanVudG8gVVJdKiogeSAqKkJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgW1N1YmNvbmp1bnRvIFVSXSoqLiBFc3RhcyBtdWVzdHJhbiwgY29uIGJhc2UgZW4gdW4gc3ViY29uanV0byBkZSA2MSByZWdpc3Ryb3MgbXVlc3RyYWRvIGFsZWF0b3JpbyBzaW1wbGUsIGxvcyBwdW50YWplcyBwb3IgY29tcG9uZW50ZXMgeSBlbCBiaXBsb3QgZGUgZXNlIHN1YmNvbmp1bnRvLCBjb24gYmFzZSBlbiBsYSBhZ3J1cGFjacOzbiBwcm92aXN0YSBwb3IgbGEgdmFyYWlibGUgY2F0ZWfDs3JpY2EgKipVbml2ZXJzaXR5X1JhdGluZyoqLCBzaW4gcMOpcmRpZGEgc2lnbmlmaWNhdGl2YSBkZSBkZXRhbGxlcy4gRXN0bywgc2UgaW5zaXN0ZSwgc29sbyB0aWVuZSBmaW5lcyBkaWTDoWN0aWNvcywgZGViaWRvIGEgbGEgZGlmaWN1bHRhZCBkZSBpZGVudGlmaWNhY2nDs24gdmlzdWFsIHF1ZSBwcmVzZW50YSBlbCBjb25qdW50byBvcmlnaW5hbCBxdWUgY29udGllbmUgNDAwIHJlZ2lzdHJvcy4NCg0KIyMjIyBCaXBsb3QgZGUgVmFyaWFibGVzIHkgUmVnaXN0cm9zIFtUb3RhbCBVUl0NCmBgYHtyIEJpcGxvdF9kZV9WYXJpYWJsZXNfeV9SZWdpc3Ryb3NfVG90YWxfVVIsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZGF0YV9VUiA8LSBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWywtYygxLDIsOCldDQpkYXRhX0FsbCA8LSBjYmluZChBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWywtYygxLDIsOCw5KV0sIGRhdGFfVVIkVW5pdmVyc2l0eV9SYXRpbmcpDQpmdml6X3BjYV9iaXBsb3QoUENBKGRhdGFfQWxsLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGLCBxdWFsaS5zdXAgPSA3KSwgYXhlcyA9IGMoMSwgMiksIHJlcGVsID0gVFJVRSwgaGFiaWxsYWdlID0gNykNCmBgYA0KDQojIyMjIEJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgW1RvdGFsIEddDQpgYGB7ciBCaXBsb3RfZGVfVmFyaWFibGVzX3lfUmVnaXN0cm9zX1RvdGFsX0csIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZGF0YV9VUiA8LSBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWywtYygxLDgsOSldDQpkYXRhX0FsbCA8LSBjYmluZChBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWywtYygxLDIsOCw5KV0sIGRhdGFfVVIkR2VuZGVyKQ0KZnZpel9wY2FfYmlwbG90KFBDQShkYXRhX0FsbCwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiwgcXVhbGkuc3VwID0gNyksIGF4ZXMgPSBjKDEsIDIpLCByZXBlbCA9IFRSVUUsIGhhYmlsbGFnZSA9IDcpDQpgYGANCg0KIyMjIyBCaXBsb3QgZGUgVmFyaWFibGVzIHkgUmVnaXN0cm9zIFtUb3RhbCBSXQ0KYGBge3IgQmlwbG90X2RlX1ZhcmlhYmxlc195X1JlZ2lzdHJvc19Ub3RhbF9SLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdGFfVVIgPC0gQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbFssLWMoMSwyLDkpXQ0KZGF0YV9BbGwgPC0gY2JpbmQoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbFssLWMoMSwyLDgsOSldLCBkYXRhX1VSJFJlc2VhcmNoKQ0KZnZpel9wY2FfYmlwbG90KFBDQShkYXRhX0FsbCwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRiwgcXVhbGkuc3VwID0gNyksIGF4ZXMgPSBjKDEsIDIpLCByZXBlbCA9IFRSVUUsIGhhYmlsbGFnZSA9IDcpDQpgYGANCg0KIyMjIyBDb29yZGVuYWRhcyBJbmRpdmlkdWFsZXMgW1N1YmNvbmp1bnRvIFVSXQ0KYGBge3IgQ29vcmRlbmFkYXNfSW5kaXZpZHVhbGVzX1N1YmNvbmp1bnRvLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOCkNCmRhdGFfNjFfVVIgPC0gQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbFtzYW1wbGUoMTpucm93KEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwpLDYxKSwtYygxLDIsOCldDQpzZXQuc2VlZCg3ODA3MjgpDQpkYXRhXzYxIDwtIGNiaW5kKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbc2FtcGxlKDE6bnJvdyhBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsKSw2MSksLWMoMSwyLDgsOSldLCBkYXRhXzYxX1VSJFVuaXZlcnNpdHlfUmF0aW5nKQ0KaGVhZChQQ0EoZGF0YV82MSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFQsIGdyYXBoID0gRiwgcXVhbGkuc3VwID0gNykkaW5kJGNvb3JkLCBuID0gNjFMKQ0KYGBgDQoNCiMjIyMgQmlwbG90IGRlIFZhcmlhYmxlcyB5IFJlZ2lzdHJvcyBbU3ViY29uanVudG8gVVJdDQpgYGB7ciBCaXBsb3RfZGVfVmFyaWFibGVzX3lfUmVnaXN0cm9zX1N1YmNvbmp1bnRvLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDc4MDcyOCkNCmRhdGFfNjFfVVIgPC0gQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbFtzYW1wbGUoMTpucm93KEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwpLDYxKSwtYygxLDIsOCldDQpzZXQuc2VlZCg3ODA3MjgpDQpkYXRhXzYxIDwtIGNiaW5kKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbc2FtcGxlKDE6bnJvdyhBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsKSw2MSksLWMoMSwyLDgsOSldLCBkYXRhXzYxX1VSJFVuaXZlcnNpdHlfUmF0aW5nKQ0KZnZpel9wY2FfYmlwbG90KFBDQShkYXRhXzYxLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVCwgZ3JhcGggPSBGLCBxdWFsaS5zdXAgPSA3KSwgYXhlcyA9IGMoMSwgMiksIHJlcGVsID0gVCwgaGFiaWxsYWdlID0gNykNCmBgYA0KDQo8YSBuYW1lPSJmYXNlMyI+PC9hPg0KDQojIyAqKk9iamV0aXZvIHkgQW5vdGFjaW9uZXMgOjogRmFzZSAzKioNCiMjICoqW0NvcnJlc3BvbmRlbmNpYXNdKioNCkVuIHTDqXJtaW5vcyBnZW5lcmFsZXMsIGVzdGEgdGVyY2VyYSBldGFwYSBkZSBlc3R1ZGlvIG1vc3RyYXLDoSBjw6FsY3Vsb3MsIHZpc3VhbGl6YWNpb25lcyBlIGludGVycHJldGFjaW9uZXMgY29uIGJhc2UgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgdHJhdGFkbyBlbiBsYSBmYXNlIFsxXSgjc2VjMSkgeSBbMl0oI2Zhc2UyKSwgcGVybyBhaG9yYSBkZXNkZSB1biBlbmZvcXVlIGRlIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZXMgeSBtw7psdGlwbGVzIHNvYnJlIGxhcyB2YXJpYWJsZXMgY3VhbmxpdGF0aXZhcywgcXVlIGluY2x1aXLDoTogY29uc3RydWNjacOzbiBkZSB0YWJsYXMgZGUgY29udGluZ2VuY2lhcyB5IGRpc3l1bnRpdmFzIGNvbXBsZXRhcywgY2FsaWRhZGVzIGRlIHJlcHJlc2VudGFjacOzbiwgY29udHJpYnVjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzLg0KDQpSZWN1w6lyZGVzZSBxdWUgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbyBlcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHkgbG9zIHJlZmVyZW50ZXMgdGXDs3JpY29zIGVuIGxhIFtzZWNjacOzbiAxXSgjc2VjMSkuDQoNClBvciDDumx0aW1vLCBlc3RlIHRyYWJham8gZnVlIHByb2Nlc2FkbyBjb24gYHIgUi52ZXJzaW9uLnN0cmluZ2AgbWVkaWFkbyBwb3IgUlN0dWRpbyAyMDIyLjEyLjAgQnVpbGQgMzUzIGVuIHVuYSBwbGF0YWZvcm1hIHg4Nl82NC13NjQtbWluZ3czMi4gQWRlbcOhcywgcG9yIHN1IG5hdHVyYWxlemEgZGUgcHVibGljYWNpw7NuIGVuIGzDrW5lYSB5IHBhcmEgY3VtcGxpciBjb24gZWwgcmVxdWlzaXRvIHRlbXBvcmFsIGRlIGVudHJlZ2EsIHNlcsOhIGFjdHVhbGl6YWRvLCBjb21vIG3DoXhpbW8sIGhhc3RhIGxhcyAxMTo1OSBwLm0uIGRlbCBkb21pbmdvIDUgZGUgbWFyem8gZGUgMjAyMy4NCg0KPGEgbmFtZT0ic2VjMTEiPjwvYT4NCg0KIyMgKioxMS4gQ29ycmVzcG9uZGVuY2lhcyBTaW1wbGVzKioNCkNvbiBiYXNlIGVuIGVsIHRyYWJham8gZGUgW0BBTUFSQWxkYXMtVXJpZWwyZWRdIHNlIHNhYmUgcXVlIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZSAoQUNTKSBidXNjYSByZXByZXNlbnRhciBlbiB1biBlc3BhY2lvIG11bHRpZGltZW5zaW9uYWwgcmVkdWNpZG8gbGEgcmVsYWNpw7NuIHF1ZSBleGlzdGEgZW50cmUgbGFzIGNhdGVnb3LDrWFzIGRlIHVuIHBhciBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLiBFbiBlc3RlIHNlbnRpZG8sIGVsIEFDUyBtdWVzdHJhIGxhcyBkaXN0YW5jaWEgZW50cmUgbG9zIG5pdmVsZXMgZGUgZG9zIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgeSwgZW4gY29uc2VjdWVuY2lhLCBheXVkYSBhIHZpc3VhbGl6YXIgdGFibGFzIGRlIGNvbnRpbmdlbmNpYS4gQWRlbcOhcywgc2UgZXN0YWJsZWNlIHF1ZSBlbCBuw7ptZXJvIG3DoXhpbW8gZGUgZGltZW5zaW9uZXMgcXVlIGV4cGxpcXVlbiBsYSBhc29jaWFjacOzbiBlbnRyZSB2YXJpYWJsZXMgZmlsYSB5IGNvbHVtbmEgZXMgaWd1YWwgYSB1bm8gbWVub3MgZWwgbWVub3IgbsO6bWVybyBkZSBjYXRlZ29yw61hcyBkZSBhbGd1bmEgZGUgbGFzIHZhcmlhYmxlcyBpbnZvbHVjcmFkYXMuIEVuIGNvbnNlY3VlbmNpYSwgZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgcGVybWl0ZSBkZXNjcmliaXIgbGEgcHJveGltaWRhZCBleGlzdGVudGUgZW50cmUgbG9zIHBlcmZpbGVzIGRlIGxvcyBvYmpldG9zIG9ic2VydmFkb3MuIEFkZW3DoXMsIGVsIEFDUywgcXVlIGJhc2Egc3VzIGPDoWxjdWxvcyBlbiB0YWJsYXMgZGUgY29udGluZ2VuY2lhLCBwdWVkZSBleHRlbmRlcnNlIGEgbcOhcyBkZSBkb3MgdmFyaWFibGVzIGNhdGVnw7NyaWNhcywgY29ub2Npw6luZG9zZSBjb21vIGFuw6FzbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBtw7psdGlwbGVzIChBQ00pLCBjb24gYmFzZSBlbiB1bmEgb2JqZXRvIGxsYW1hZG8gdGFibGEgZGlzeXVudGl2YSBjb21wbGV0YS4NCg0KRXN0YSBzZWNjacOzbiB0cmF0YSBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVjaWFzIHNpbXBsZSBjb24gYmFzZSBlbiBwYXJlcyBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpLiBDb21wbGVtZW50YXJpYW1lbnRlLCBsYSBbc2VjY2nDs24gMTJdKCNzZWMxMikgbXVlc3RyYSBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBtw7psdGlwbGVzIGNvbiBiYXNlIGVuIGxhcyB2YXJhaWJsZXMgY2F0ZWfDs3JpY2FzIGRlbCBtaXNtbyBjb25qdW50byBkZSBkYXRvcy4NCg0KIyMjIDExLjEuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hDQpDb24gYmFzZSBlbiBsYXMgdmFyaWFibGVzIGN1YWxpdGF0aXZhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgW3NlY2Npw7NuIDJdKCNzZWMyKSBzZSBkZW1hbmRhIGRlc2Fycm9sbGFyIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzLCBlbiBwcmluY2lwaW8gc2ltcGxlLCBhcG95YWRvIGVuIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgeSBkZSBmcmVjdWVuY2lhcyByZWxhdGl2YXMgeSBncsOhZmljb3MgZGUgcGVyZmlsZXMgeSBkZSBwdW50b3Mgc3VwZXJwdWVzdG9zIGVuIGVsIHByaW1lciBwbGFubyBmYWN0b3JpYWwuIA0KDQojIyMgMTEuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwZXJtaXRlIHZpc3VhbGl6YXIgb2JqZXRvcyBtYXRyaWNpYWxlcyB5IGdyw6FmaWNvcyBxdWUgYXl1ZGFuIGEgcm9idXN0ZWNlciBsYSBpbnRlcnByZXRhY2nDs24gZGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIHNpbXBsZSAoYmluYXJpbykgZW50cmUgY2FkYSBwYXIgZGUgdmFyYWlibGVzIGNhdGVnw7NyaWNhcyBkZWwgY29uanVudG8gZGUgZGF0b3M6ICoqR2VuZGVyKiosICoqUmVzZWFyY2gqKiB5ICoqVW5pdmVyc2l0eV9SYXRpbmcqKi4gUG9yIHNlciBiYWphIGxhIGNhbnRpZGFkIGRlIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgc2UgdHJhYmFqYSBlbCBBQ1Mgc29icmUgbGFzIHRyZXMgY29tYmluYWNpb25lcyBwb3NpYmxlcy4NCg0KTGEgcGVzdGHDsWEgKipBQyBQYXJlamFzIFRvdGFsZXMqKiBhZ3J1cGEgbG9zIGPDoWxjdWxvcyBwYXJhIHRvZGFzIGxhcyBjb21iaW5hY2lvbmVzIGRlIHBhcmVqYXMgZGUgdmFyaWFibGVzLiBFbiBwYXJ0aWN1bGFyLCBlbiAqKkNvbnRpbmdlbmNpYXMqKiBzZSBoYWNlbiBsYXMgc2lndWllbnRlcyBsZWN0dXJhcyBkZSBlamVtcGxvIGRlIGxhcyB0YWJsYXMgZGUgY29udGluZ2VuY2lhczogZW4gbGEgdGFibGEgZGUgY29udGluZ2VuY2lhcyAqKkdlbmRlcioqIHZzLiAqKlJlc2VhcmNoKiogc2UgZW5jb250csOzIHF1ZSA4MCBlc3R1ZGlhbnRlcyBkZSB1biB0b3RhbCBkZSAxNTEgZGUgc2V4byBmZW1lbmlubyBhZGp1bnRhcm9uIGV2aWRlbmNpYXMgZGUgcGFydGljaXBhY2nDs24gZW4gYWN0aXZpZGFkZXMgZGUgaW52ZXN0aWdhY2nDs247IGFkZW3DoXMsIGRlIGxvcyAxODEgZXN0dWRpYW50ZXMgcXVlIG5vIGFyZ3VtZW50YXJvbiBpbnZlc3RpZ2FjacOzbiwgZGUgdW4gdG90YWwgZGUgNDAwIHBvc3R1bGFkb3MsIDcxIHNvbiBkZSBzZXhvIGZlbWVuaW5vIHkgMTEwIGRlIHNleG8gbWFzY3VsaW5vLiBFbiBsYSB0YWJsYSBkZSBjb250aW5nZW5jaWFzICoqR2VuZGVyKiogdnMuICoqVW5pdmVyc2l0eV9SYXRpbmcqKiBzZSBjYWxjdWzDsyBxdWUgMTQgZXN0dWRpYW50ZXMgZGUgdW4gdG90YWwgZGUgMjQ5IGRlIHNleG8gbWFzY3VsaW5vIHByZXNlbnRhcm9uIGFzcGlyYWNpb25lcyBkZSBpbmdyZXNvIGEgdW5uYSB1bml2ZXJzaWRhZCBkZSB1bmEgZXN0cmVsbGE7IGFkZW3DoXMsIGRlIGxvcyA2MCBlc3R1ZGlhbnRlcyBxdWUgcHJlc2VudGFyb24gc29saWNpdHVkZXMgZGUgaW5ncmVzbyBhIHVuaXZlcnNpZGFkZXMgZGUgY2luY28gZXN0cmVsbGFzLCAyMyBlcmFuIGRlIHNleG8gZmVtZW5pbm8geSAzNyBkZSBzZXhvIG1hc2N1bGluby4gUG9yIMO6bHRpbW8sIGVuIGxhIHRhYmxhIGRlIGNvbnRpbmdlbmNpYSAqKlJlc2VhcmNoKiogdnMuICoqVW5pdmVyc2l0eV9SYXRpbmcqKiBzZSBwdWVkZSBkZXRlcm1pbmFyIHF1ZSA1OSBlc3R1ZGlhbnRlcywgZGUgdW4gdG90YWwgZGUgMjE5LCBxdWUgcHJlc2VudGFyb24gZXZpZGVuY2lhcyBkZSBoYWJlciBwYXJ0aWNpcGFkbyBlbiBwcm9jZXNvcyBkZSBpbnZlc3RpZ2FjacOzbiwgcHJlc2VudGFyb24gc3VzIGFzcGlyYWNpb25lcyBkZSBpbmdyZXNvIGVuIHVuaXZlcnNpZGFkZXMgZGUgY3VhdHJvIGVzdHJlbGxhczsgYWRlbcOhcywgNzUgZXN0dWRpYW50ZXMsIGRlIHVuIHRvdGFsIGRlIDEwNywgcXVlIHNlIHBvc3R1bGFyb24gZW4gdW5pdmVyc2lkYWRlcyBkZSBkb3MgZXN0cmVsbGFzLCBsbyBoaWNpZXJvbiBzaW4gZXZpZGVuY2lhciBwYXJ0aWNpcGFjacOzbiBlbiBwcm9jZXNvcyBkZSBpbnZlc3RpZ2FjacOzbi4NCg0KQWwgdG9tYXIgY29tbyBiYXNlIGxhcyB0YWJsYXMgZGUgY29udGluZ2VuY2lhIGRlc2NyaXRhcyBhbnRlcywgc2UgcHJlc2VudGEgYSB0cmF2w6lzIGRlIGxhIHN1YnBlc3Rhw7FhICoqUHJvYmFiaWxpZGFkZXMqKiBsYXMgcHJvcG9yY2lvbmVzIHJlbGF0aXZhcyBlbiB0w6lybWlub3MgZGUgbG9zIHBhcmVzIGRlIHZhcmlhYmxlcyBleGFtaW5pbmFkb3MuIEVuIGVzdGUgc2VudGlkbywgYSBuaXZlbCBkZSBlamVtcGxvIHNlIHByZXNlbnRhbiBhbGd1bmFzIGxlY3R1cmFzIGRlIGVsbGFzOiBlbiBsYSB0YWJsYSBkZSBwcm9iYWJpbGlkYWRlcyAqKkdlbmRlcioqIHZzLiAqKlJlc2VhcmNoKiogZWwgJDIwLjAwJCAkXCUkIGRlbCB0b3RhbCBkZSBlc3R1ZGlhbnRlcyBzb24gZGUgc2V4byBmZW1lbmlubyBxdWUgcHJlc2VudGFyb24gZXZpZGVuY2lhcyBlbiBzdSBhcGxpY2FjacOzbiBkZSBoYWJlciBwYXJ0aWNpcGFkbyBlbiBwcm9jZXNvcyBkZSBpbnZlc3RpZ2FjacOzbjsgYWRlbcOhcywgZWwgJDQ1LjI1JCAkXCUkIGRlbCB0b3RhbCBkZSBlc3R1ZGlhbnRlcyBubyBhcmd1bWVudMOzIGVuIHN1IHBvc3R1bGFjacOzbiBoYWJlciBwYXJ0aWNpcGFkbyBlbiBwcm9jZXNvcyBkZSBpbnZlc3RpZ2FjacOzbiwgZG9uZGUgZWwgJDE3Ljc1JCAkXCUkIGVyYW4gaG9tYnJlcyB5IGVsICQyNy41MCQgJFwlJCBtdWplcmVzLiBFbiBsYSB0YWJsYSBkZSBwcm9iYWJpbGlkYWRlcyAqKkdlbmRlcioqIHZzLiAqKlVuaXZlcnNpdHlfUmF0aW5nKiogcXVlIGVsICQzLjUwJCAkXCUkIGRlbCB0b3RhbCBkZSBlc3R1ZGlhbnRlcyBmdWVyb24gaG9tYnJlcyBxdWUgcHJlc2VudGFyb24gc3VzIHBvc3R1bGFjaW9uZXMgYSB1bml2ZXJzaWRhZGVzIGRlIHVuYSBlc3RyZWxsYTsgYWRlbcOhcywgZGVsICQxNS4wMCQgJFwlJCBkZSBwb3N0dWxhZG9zIGEgdW5pdmVyc2lkYWRlcyBkZSBjaW5jbyBlc3RyZWxsYXMsIGFkaXRpdmFtZW50ZSBlbCAkOS4yNSQgJFwlJCBlcmFuIGhvbWJyZXMgeSBlbCAkNS43NSQgJFwlJCBtdWplcmVzLiBQb3Igw7psdGltbywgZW4gbGEgdGFibGEgZGUgcHJvYmFiaWxpZGFkZXMgKipSZXNlYXJjaCoqIHZzLiAqKlVuaXZlcnNpdHlfUmF0aW5nKiogZWwgJDE0Ljc1JCAkXCUkIGRlbCB0b3RhbCBkZSBlc3R1ZGlhbnRlcyBwcmVzZW50YXJvbiBldmlkZW5jaWFzIGRlIHBhcnRpY2lwYWNpw7NuIGVuIHByb2Nlc29zIGludmVzdGlnYXRpdm9zIHkgc2UgcG9zdHVsYXJvbiBhIHVuaXZlcnNpZGFkZXMgZGUgY3VhdHJvIGVzdHJlbGxhczsgYWRlbcOhcywgZWwgJDE4Ljc1JCAkXCUkIGRlbCB0b3RhbCBkZSBlc3R1ZGlhbnRlcyBzZSBwb3N0dWxhcm9uIHBhcmEgaW5ncmVzYXIgYSB1bml2ZXJzaWRhZGVzIGRlIGRvcyBlc3RyZWxsYXMgc2luIHByZXNlbnRhciBldmlkZW5jaWFzIGRlIGhhYmVyIHBhcnRpY2lwYWRvIGVuIHByb2Nlc29zIGRlIGludmVzdGlnYWNpw7NuLg0KDQpDb21vIG9jdXJyZSBjb24gbGFzIHRhYmxhcyBkZSBwcm9iYWJpbGlkYWRlcyBvIHByb3BvcmNpb25lcywgZW4gbGEgc3VicGVzdGHDsWEgKipGcmVjdWVuY2lhcyBbQ1BGIHkgQ1BDXSoqLCBsYXMgZnJlY3VlbmNpYXMgY29uZGljaW9uYWRhcyBwb3IgZmlsYXMgeSBjb25kaWNpb25hZGFzIHBvciBjb2x1bW5hcyAocmVzcGVjdGl2YW1lbnRlKSBzZSBjYWxjdWxhcm9uIGNvbiBiYXNlIGVuIGxhcyB0YWJsYXMgZGUgY29udGluZ2VuY2lhIHJlc3BlY3RpdmFzLiBBc8OtLCBzZSBwdWVkZW4gcHJlc2VudGFyIGxhcyBzaWd1aWVudGVzIGxlY3R1cmFzIGRlIGVqZW1wbG86IHNlZ8O6biBsYSBtYXRyaXogZGUgZnJlY3VlbmNpYXMgQ1BGIGRlICoqR2VuZGVyKiogdnMuICoqUmVzZWFyY2gqKiBkZSBsb3MgZXN0dWRpYW50ZXMgZGUgc2V4byBmZW1lbmlubyBlbCAkNTIuOTgkICRcJSQgc2UgcG9zdHVsw7MgcHJlc2VudGFuZG8gZXZpZGVuY2lhcyBkZSBoYWJlciBwYXJ0aWNpcGFkbyBlbiBwcm9jZXNvcyBkZSBpbnZlc3RpZ2FjacOzbiwgcG9yIG90cm8gbGFkbywgZW50cmUgbG9zIGVzdHVkaWFudGVzIGRlIHNleG8gbWFzY3VsaW5vIGxvIGhpem8gZWwgJDU1LjgyJCAkXCUkOyBhZGVtw6FzLCBzZWfDum4gbGEgbWlzbWEgbWF0cml6IHBlcm8gY29uZGljaW9uYWRhIHBvciBjb2x1bW5hcywgZWwgJDM5LjIzJCAkXCUkIGRlIGxvcyBlc3R1ZGlhbnRlcyBxdWUgbm8gcHJlc2VudGFyb24gZXZpZGVuY2lhcyBkZSBoYWJlciBwYXJ0aWNpcGFkbyBlbiBwcm9jZXNvcyBkZSBpbnZlc3RpZ2FjacOzbiBmdWVyb24gZGUgc2V4byBmZW1lbmlubywgbWllbnRyYXMgcXVlIGVsICQ2MC43NyQgJFwlJCBlcmFuIGRlIHNleG8gbWFzY3VsaW5vLiBBaG9yYSwgc2Vnw7puIGxhIG1hdHJpeiBkZSBmcmVjdWVuY2lhcyBDUEYgZGUgKipHZW5kZXIqKiB2cy4gKipVbml2ZXJzaXR5X1JhdGluZyoqIGVsICQ1LjYyJCAkXCUkIGRlIGxvcyBlc3R1ZGlhbnRlcyBkZSBzZXhvIG1hc2N1bGlubyBzZSBwb3N0dWzDsyBhIHVuaXZlcnNpZGFkZXMgZGUgdW5hIGVzdHJlbGxhLCBtaWVudHJhcyBxdWUgZWwgJDcuOTUkICRcJSQgZGUgbGFzIG11amVyZXMgaGl6byBsbyBtaXNtbzsgYWRlbcOhcywgc2Vnw7puIGxhIG1pc21hIG1hdHJpeiBwZXJvIGNvbmRpY2lvbmFkYSBwb3IgY29sdW1uYXMsIGRlbCB0b3RhbCBkZSBlc3R1ZGlhbnRlcyBxdWUgc2UgcHJlc2VudGFyb24gYSB1bml2ZXJzaWRhZGVzIGRlIHVuYSBlc3RyZWxsYSBlbCAkNDYuMTUkICRcJSQgZnVlcm9uIG11amVyZXMgeSBlbCAkNTMuODUkICRcJSQgaG9tYnJlcy4gUG9yIMO6bHRpbW8sIHNlZ8O6biBsYSBtYXRyaXogZGUgZnJlY3VlbmNpYXMgQ1BGIGRlICoqUmVzZWFyY2gqKiB2cy4gKipVbml2ZXJzaXR5X1JhdGluZyoqIHNvbG8gZWwgJDQuNDIkICRcJSQgZGUgbG9zIGVzdHVkaWFudGVzIHF1ZSBubyBldmlkZW5jaWFyb24gcGFydGljaXBhY2lvbmVzIGVuIHByb2Nlc29zIGRlIGludmVzdGlnYWNpw7NuIHNlIHBvc3R1bGFyb24gcGFyYSB1bml2ZXJzaWRhZGVzIGRlIGNpbmNvIGVzdHJlbGxhcywgbWllbnRyYXMgcXVlIGEgZWxsYXMgc2UgcHJlc2VudGFyb24gZWwgJDIzLjc0JCAkXCUkIGRlIGVzdHVkaWFudGVzIHF1ZSBzw60gdGVuw61hbiBldmlkZW5jaWFzIGRlIHBhcnRpY2lwYWNpw7NuIGVuIGRpY2hvcyBwcm9jZXNvcy4gQ29tcGxlbWVudGFyaWFtZW50ZSwgc2Vnw7puIGxhIG1pc21hIG1hdHJpeiBwZXJvIGNvbmRpY2lvbmFkYSBwb3IgY29sdW1uYXMsIGVsICQxMy4zMyQgJFwlJCBkZWwgdG90YWwgZGUgZXN0dWRpYW50ZXMgcXVlIHNlIHByZXNlbnRhcm9uIGEgdW5pdmVyc2lkYWRlcyBkZSBjaW5jbyBlc3RyZWxsYXMgZXN0b3Mgbm8gYXJndW1lbnRhcm9uIGhhYmVyIHBhcnRpY2lwYWRvIGVuIHByb2Nlc29zIGRlIGludmVzdGlnYWNpw7NuLCBtaWVudHJhcyBxdWUgZWwgJDg2LjY3JCAkXCUkIHPDrSBsbyBoaXpvLg0KDQpDb24gYmFzZSBlbiBsYXMgbWF0cmljZXMgZGUgZnJlY3VlbmNpYXMgc2UgZW50aWVuZGVuIGxvcyBwZXJmaWxlcyBjb25kaWNpb25hZG9zIHBvciBmaWxhcyB5IGNvbHVtbmFzIHF1ZSBzZSBleGhpYmVuIGVuIGxhIHN1YnBlc3Rhw7FhICoqUGVyZmlsZXMgW0NQRiB5IENQQ10qKi4gTG9zIGdyw6FmaWNvcyBkZSBwZXJmaWxlcyBzZSBtdWVzdHJhbiBlbiBlbCBtaXNtbyBvcmRlbiBkZSBsb3Mgb2JqZXRvcyBhbnRlcmlvcm1lbnRlIGRlc2NyaXRvcy4gU2luIGVtYmFyZ28sIGVuIGxvcyBncsOhZmljb3MgZGUgcGVyZmlsZXMgc2UgcHVlZGVuIGNvdGVqYXIgbGFzIHByb3BvcmNpb25lcyBjb250cmEgdW4gaW5kaXZpZHVvIHByb21lZGlvIG8gdW4gcGVyZmlsIHByb21lZGlvLCBldGlxdWV0YWRvIGNvbiAqKm1hcmcqKi4gRW4gZXN0ZSBzZW50aWRvLCBsb3MgcGVyZmlsZXMgZmlsYSB5IGNvbHVtbmEgcXVlIGNvcnJlc3BvbmRlbiBjb24gbGFzIHZhcmlhYmxlcyAqKkdlbmRlcioqIHkgKipSZXNlYXJjaCoqIG11ZXN0cmFuIGRpc3RyaWJ1Y2lvbmVzIG1hcmdpbmFsZXMgY2VyY2FuYXMgZW50cmUgc8OtOyBlcyBkZWNpciwgc2kgc29uIGNhbGN1bGFkYXMgbGFzIHByb3BvcmNpb25lcyB0b3RhbGVzIHNlcsOhbiBhcHJveGltYWRhbWVudGUgaWd1YWxlcywgcG9yIGVqZW1wbG86IChwZXJmaWxlcyBmaWxhKSBsYXMgcHJvcG9yY2lvbmVzIGRlIGVzdHVkaWFudGVzIGRlIHNleG8gbWFzY3VsaW5vIHkgZmVtZW5pbm8gcXVlIHNlIHBvc3R1bGFyb24gc2luIGNyZWRlbmNpYWxlcyBpbnZlc3RpZ2F0aXZhcyBmdWVyb24sIHJlc3BlY3RpdmFtZW50ZSwgJDQ0LjE4JCAkXCUkIHkgJDQ3LjAyJCAkXCUkOyB0YW1iacOpbiwgKHBlcmZpbGVzIGNvbHVtbmEpIGxhIHByb3BvcmNpw7NuIGRlIGVzdHVkaWFudGVzIGRlIHNleG8gZmVtZW5pbm8gcXVlIHNlIHBvc3R1bGFyb24gY29uIG8gc2luIGNyZWRlbmNpYWxlcyBmdWVyb24sIHJlc3BlY3RpdmFtZW50ZSwgJDM2LjUzJCAkXCUkIHkgJDM5LjIzJCAkXCUkLiBBc2ltaXNtbywgbG9zIHBlcmZpbGVzIGZpbGEgeSBjb2x1bW5hIHF1ZSBjb3JyZXNwb25kZW4gY29uIGxhcyB2YXJpYWJsZXMgKipHZW5kZXIqKiB5ICoqVW5pdmVyc2l0eV9SYXRpbmcqKiBtdWVzdHJhbiBkaXN0cmlidWNpb25lcyBtYXJnaW5hbGVzIGNlcmNhbmFzIGVudHJlIHPDrSwgcG9yIGVqZW1wbG86IChwZXJmaWxlcyBmaWxhKSBsYXMgcHJvcG9yY2lvbmVzIGRlIGVzdHVkaWFudGVzIGRlIHNleG8gbWFzY3VsaW5vIHkgZmVtZW5pbm8gcXVlIHNlIHBvc3R1bGFyb24gYSB1bml2ZXJzaWRhZGVzIGRlIHRyZXMgZXN0cmVsbGFzIGZ1ZXJvbiwgcmVzcGVjdGl2YW1lbnRlLCAkMzIuMTMkICRcJSQgeSAkMzUuMTAkICRcJSQ7IHRhbWJpw6luLCAocGVyZmlsZXMgY29sdW1uYSkgbGEgcHJvcG9yY2nDs24gZGUgZXN0dWRpYW50ZXMgZGUgc2V4byBmZW1lbmlubyBxdWUgc2UgcHJlc2VudGFyb24gYSB1bml2ZXJzaWRhZGVzIGRlIGNpbmNvLCB0cmVzIHkgZG9zIGVzdHJlbGxhcyBmdWVyb24sIHJlc3BlY3RpdmFtZW50ZSwgJDM4LjMzJCAkXCUkLCAkMzkuODUkICRcJSQgeSAkMzguMzIkICRcJSQuIFBvciDDumx0aW1vLCBsb3MgcGVyZmlsZXMgZmlsYSB5IGNvbHVtbmEgcXVlIGNvcnJlc3BvbmRlbiBjb24gbGFzIHZhcmlhYmxlcyAqKlJlc2VhcmNoKiogeSAqKlVuaXZlcnNpdHlfUmF0aW5nKiogbXVlc3RyYW4gZGlzdHJpYnVjaW9uZXMgbWFyZ2luYWxlcyBsZWphbmFzIGVudHJlIHPDrSwgcG9yIGVqZW1wbG86IChwZXJmaWxlcyBmaWxhKSBsYXMgcHJvcG9yY2lvbmVzIGRlIGVzdHVkaWFudGVzIHF1ZSBzZSBwcmVzZW50YXJvbiBzaW4gbyBjb24gY3JlZGVuY2lhbGVzIGRlIGludmVzdGlnYWNpw7NuIGEgdW5pdmVyc2lkYWRlcyBkZSBjaW5jbyBlc3RyZWxsYXMgZnVlcm9uOiAkNC40MiQgJFwlJCB5ICQyMy43NCQgJFwlJDsgdGFtYmnDqW4sIChwZXJmaWxlcyBjb2x1bW5hKSBsYSBwcm9wb3JjacOzbiBkZSBlc3R1ZGlhbnRlcyBxdWUgcHJlc2VudGFyb24gY3JlZGVuY2lhbGVzIGRlIGludmVzdGlnYWNpw7NuIHBhcmEgcG9zdHVsYXJzZSBlbiB1bml2ZXJzaWRhZGVzIGRlIGNpbmNvLCB0cmVzIHkgZG9zIGVzdHJlbGxhcyBmdWVyb24sIHJlc3BlY3RpdmFtZW50ZSwgJDg2LjY3JCAkXCUkLCAkNTMuMzgkICRcJSQgeSAkMjkuOTEkICRcJSQuDQoNCmNvbiBiYXNlIGVuIGxhcyBkZXNjcmlwY2lvbmVzIGhlY2hhcyBlcyBwb3NpYmxlIGFudGljaXBhciBxdWUgbG9zIHBhcmVzIGRlIHZhcmlhYmxlcyBjYXRlZ8OzcmljYXMgKipHZW5kZXIqKiB2cy4gKipSZXNlYXJjaCoqIHkgKipHZW5kZXIqKiB2cy4gKipVbml2ZXJzaXR5X1JhdGluZyoqIHNlYW4gaW5kZXBlbmRpZW50ZXMuIEVzdGUganVpY2lvIHNlIGFwb3lhIGVuIGxvcyByZXN1bHRhZG9zIGRlIGxhcyBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgdmlzdWFsaXphZGFzIGEgdHJhdsOpcyBkZSBsYSBzdWItcGVzdGHDsWEgaG9tw7NuaW1hLlBhcmEgZXN0YXMgcHJ1ZWJhcywgYSB1biBuaXZlbCBkZSBzaWduaWZpY2FuY2lhICRcYWxwaGEgPSAwLjA1JCwgbGFzIGhpcMOzdGVzaXMgZm9ybXVsYWRhcyBmdWVyb246JCRIXzA6IFx0ZXh0IHtMYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBzb24gaW5kZXBlbmRpZW50ZXN9JCQgJCRIXzE6IFx0ZXh0IHtsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBzb24gZGVwZW5kaWVudGVzfSQkQXNpbWlzbW8sIGVsIHBhciBkZSB2YXJpYWJsZXMgcXVlIHR1dm8gbGFzIHBydWViYXMgYSBmYXZvciBkZSBsYSBkZXBlbmRlbmNpYSBmdWVyb24gKipSZXNlYXJjaCoqIHkgKipVbml2ZXJzaXR5X1JhdGluZyoqLCBlbiBlc3RhIHBydWViYSBlbCAkcC12YWxvciQgcmVzdWx0w7MgbWVub3IgbyBpZ3VhbCBxdWUgZWwgbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSB5LCBjb21wYXJhdGl2YW1lbnRlLCBlbCB2YWxvciBkZWwgZXN0YWTDrXN0aWNvICRcY2hpXjIkIGZ1ZSBncmFuZGUuIFBvciBsbyB0YW50bywgZWwgcGFyIGRlIHZhcmlhYmxlcyBxdWUgY29udGludWFyb24gZW4gYW7DoWxpc2lzIGZ1ZXJvbiBlc3RhcyDDumx0aW1hcy4NCg0KQSB0cmF2w6lzIGRlIGxhIHBlc3Rhw7FhICoqQUMgUGFyZWphIMOabmljYSoqIHNlIGRlc3BsaWVnYW4gbGFzIHN1Yi1wZXN0YcOxYXMgcmVsYWNpb25hZGFzIGNvbiBsYSBjb250aW51YWNpw7NuIGRlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBlbnRyZSBlbGxhcy4gRW4gKipDb250aW5nZW5jaWFzIHkgUmVzaWR1YWxlcyBbUi1VUl0qKiAoUjogUmVzZWFyY2ggeSBVUjogVW5pdmVyc2l0eV9SYXRpbmcpIHNlIHB1ZWRlbiB2aXN1YWxpemFyIGxhcyB0YWJsYXMgZGUgY29udGluZ2VuY2lhcywgdmFsb3JlcyBlc3BlcmFkb3MgeSByZXNpZHVhbGVzIGRlIGxhIHBhcmVqYSBkZSB2YXJpYWJsZXMgZW4gY3Vyc28uIFJlc3BlY3RvIGRlIGxhcyBkb3MgcHJpbWVyYXMgZXMgdmlzdWFsaXphYmxlIHF1ZSBlbCByZWN1ZW50byBvYnNlcnZhZG8geSBlbCByZWN1ZW50byBlc3BlcmFkbyBiYWpvIGxhIGhpcMOzdGVzaXMgbnVsYSByZXNwZWN0byBkZSBjYWRhIHZhcmlhYmxlIHNvbiBsZWphbm9zIGVudHJlIHPDrSwgZW4gZXN0ZSBzZW50aWRvLCBsYSBkZXBlbmRlbmNpYSBlbnRyZSBsYXMgdmFyaWFibGVzIHNlIHJvYnVzdGVjZS4gICJyYW5nb19vYnNlcnZhZG8iIHNvbiBsb3MgcmVjdWVudG9zIGFzb2NpYWRvcyBjb24gY2FkYSBjYXRlZ29yw61hIGRlIGRhdG9zIHkgInJhbmdvX2VzcGVyYWRvIiBzb24gbG9zIHJlY3VlbnRvcyBlc3BlcmFkb3MgcGFyYSBjYWRhIGNhdGVnb3LDrWEgYmFqbyBsYSBoaXDDs3Rlc2lzIG51bGEuIEFkZW3DoXMsIGVsIGFuw6FsaXNpcyBkZSByZXNpZHVhbGVzIGRlIFBlYXJzb24geSBlc3RhbmRhcml6YWRvcyBtdWVzdHJhbiBxdWUgbGFzIG1heW9yZXMgZGVzdmlhY2lvbmVzIHJlc3BlY3RvIGEgbG9zIHZhbG9yZXMgZXNwZXJhZG9zIG9jdXJyZW4gZW50cmUgbGFzIHVuaXZlcnNpZGFkZXMgZGUgY2luY28sIGN1YXRybywgZG9zIHkgdW5hIGVzdHJlbGxhLiBBc2ltaXNtbywgZW4gbGEgc3ViLXBlc3Rhw7FhICoqQ29udHJpYnVjaW9uZXMgW1ItVVJdKiogcHVlZGUgYXByZWNpYXJzZSwgY29tZW50YWRvIGxvIGFudGVyaW9yLCBxdWUgZWwgdmFsb3IgdHJlcyBlc3RyZWxsYXMgZGUgbGEgdmFyaWFibGUgKipVbml2ZXJzaXR5X1JhdGluZyoqIGNvbnRyaWJ1eWUgcG9jbyBlbiBsYSBleHBsaWNhY2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkIGRlbCBjb25qdW50byBlbiBjb21wYXJhY2nDs24gY29uIGxvcyBkZW3DoXMuDQoNClBvciDDumx0aW1vLCBlbCByZXN1bHRhZG8gZGVmaW5pdGl2byBkZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgc2ltcGxlIHNlIG11ZXN0cmEgYSB0cmF2w6lzIGRlIGxhIHN1Yi1wZXN0YcOxYSAqKkNvcnJlc3BvbmRlbmNpYSBTaW1wbGUgVW5pZGltZW5zaW9uYWwgW1ItVVJdKiouIEVuIGVzdGUgYXBhcnRhZG8gc2UgZXN0YWJsZWNlIHF1ZSBzb2xvIHVuYSBkaW1lbnNpw7NuIGFic29yYmUgdG9kYSBsYSB2YXJpYWJpbGlkYWQgZGUgbGEgcGFyZWphLCBwb3IgbG8gcXVlIGxhIHJlcHJlc2VudGFjacOzbiBiaWRpbWVuc2lvbmFsIGVuIGVsIHBhbG5vIGRlIGZhY3RvcmVzIGVzIGlycmVhbGl6YWJsZS4gU2luIGVtYmFyZ28sICBlcyBwb3NpYmxlIGhhY2VyIHVuYSBpbnRlcnByZXRhY2nDs24gdW5pZGltZW5zaW9uYWwgZGUgbG9zIHJlc3VsdGFkb3MuIEFsIHNlciByZXF1ZXJpZGFzIGxhcyB2YXJpYWJsZXMgZGUgc29wb3J0ZSBkZWwgQUMsIHByaW1lcm8gcG9yIGNvbHVtbmFzIHkgbHVlZ28gcG9yIGZpbGFzLCBsYXMgY29vcmRlbmFkYXMgcHJveWVjdGFkYXMgZGUgbGEgdmFyaWFibGUgKipVbml2ZXJzaXR5X1JhdGluZyoqIGVuIHJlbGFjacOzbiBjb24gbGFzIGNhdGVnb3LDrWFzIGRlIGNpbmNvIHkgY3VhdHJvIGVzdHJlbGxhcyBzZSBwcmVzZW50YW4gZGVsIGxhZG8gcG9zaXRpdm8gZGVsIGVqZSBkaW1lbnNpb25hbCBjcmVhbmRvIG9wb3NpY2lvbmVzIGJpbmFyaWFzIGNvbiwgcmVzcGVjdGl2YW1lbnRlLCBjaW5jbyBlc3RyZWxsYXMgY29uIHVuYSBlc3RyZWxsYSB5IGN1YXRybyBlc3RyZWxsYXMgY29uIGRvcyBlc3RyZWxsYXMsIG1pZW50cmFzIHF1ZSBsYXMgdW5pdmVyc2lkYWRlcyBkZSB0cmVzIGVzdHJlbGxhcyBzZSBlbmNjdWVudHJhIHTDqWNuaWNhbWVudGUgZW4gZWwgY2VudHJvIGRlbCBlamUuIEFzw60gbWlzbW8sIGxvcyB0aXBvcyBkZSB1bml2ZXJzaWRhZGVzIGNpbmNvLCBjdWF0cm8sIGRvcyB5IGRlIHVuYSBlc3RyZWxsYSwgc29uIGxhcyBxdWUgbcOhcyBjb250cmlidXllbiBlbiBsYSBjb25maWd1cmFjacOzbiBkZSBsYSBkaW1lbnNpw7NuLCBkZSBudWV2byBxdWVkYW4gcmV6YWdhZGFzIGxhcyB1bml2ZXJzaWRhZGVzIGRlIHRyZXMgZXN0cmVsbGFzLiBBZGVtw6FzLCBlcyBkZXRlcm1pbmFudGUgcXVlIGxhIGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuIGFsY2FuemEgZWwgbcOheGltbyBjb24gY2FkYSB1bmEgZGUgbGFzIHZhcmlhYmxlcy4gVW4gY29tcG9ydGFtaWVudG8gc2VtZWphbnRlIGEgbG8gZXhwdWVzdG8gcHVlZGUgYXByZWNpYXJzZSBjb24gbGEgdmFyaWFibGUgZmlsYSAqKlJlc2VhcmNoKiosIHN1IGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuIGVzIG3DoXhpbWEsIGxhcyBjb29yZGVuYWRhcyBkZSBzdXMgY2F0ZWdvcsOtYXMgc2UgeXV4dGFwb25lbiBlbiBlbCBlamUgdW5pZGltZW5zaW9uYWwgeSBzdXMgY29udHJpYnVjaW9uZXMgc29uIGFwcm94aW1hZGFtZW50ZSBlcXVpbGlicmFkYXMuIERlIGxvIG1lbmNpb25hZG8gc2UgaW50ZXJwcmV0YSBxdWUgcHJlc2VudGFuIGFzb2NpYWNpw7NuIHJlbGV2YW50ZSwgcG9zdGl2YSBvIG5lZ2F0aXZhLCBlbnRyZSBmaWxhcyB5IGNvbHVtbmFzLCBsYXMgY2F0ZWdvcsOtYXMgKGRlIGxhcyByZXNwZWN0aXZhcyB2YXJpYWJsZXMpIGNpbmNvIHkgY3VhdHJvIGVzdHJlbGxhcyBjb24gcmVzZWFyY2gsIHkgdW5hIHkgZG9zIGVzdHJlbGxhcyBjb24gbm8tcmVzZWFyY2guDQoNCkRhZG8gcXVlIGxhIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBiaWRpbWVuc2lvbmFsIGZ1ZSBpcnJlYWxpemFibGUsIHNlIHByZXNlbnRhIGVuIGxhIFtzZWNjacOzbiAxMl0oI3NlYzEyKSBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBtw7psdGlwbGVzIHBhcmEgbG9ncmFybGEuDQoNCiMjIyMgQUMgUGFyZWphcyBUb3RhbGVzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIENvbnRpbmdlbmNpYXMNCmBgYHtyIFRhYmxhc19kZV9Db250aW5nZW5jaWEsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KYWRkbWFyZ2lucyh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJEdlbmRlciwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCkpDQphZGRtYXJnaW5zKHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkR2VuZGVyLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSkNCmFkZG1hcmdpbnModGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZykpDQpgYGANCg0KIyMjIyMgUHJvYmFiaWxpZGFkZXMNCmBgYHtyIFRhYmxhc19kZV9Qcm9iYWJpbGlkYWRlcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQphZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRHZW5kZXIsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gpKSoxMDApDQphZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRHZW5kZXIsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpKSoxMDApDQphZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZykpKjEwMCkNCmBgYA0KDQojIyMjIyBGcmVjdWVuY2lhcyBbQ1BGIHkgQ1BDXQ0KYGBge3IgVGFibGFzX2RlX0ZyZWN1ZW5jaWFzX0NvbmRpY2lvbmFkYXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kcm91bmQoYWRkbWFyZ2lucyhwcm9wLnRhYmxlKHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkR2VuZGVyLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFJlc2VhcmNoKSwgMSkqMTAwLCAyKSwgMikNCnJvdW5kKGFkZG1hcmdpbnMocHJvcC50YWJsZSh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJEdlbmRlciwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCksIDIpKjEwMCwgMSksIDIpDQoNCnJvdW5kKGFkZG1hcmdpbnMocHJvcC50YWJsZSh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJEdlbmRlciwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZyksIDEpKjEwMCwgMiksIDIpDQpyb3VuZChhZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRHZW5kZXIsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCAyKSoxMDAsIDEpLCAyKQ0KDQpyb3VuZChhZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZyksIDEpKjEwMCwgMiksIDIpDQpyb3VuZChhZGRtYXJnaW5zKHByb3AudGFibGUodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZyksIDIpKjEwMCwgMSksIDIpDQpgYGANCg0KIyMjIyMgUGVyZmlsZXMgW0NQRiB5IENQQ10NCmBgYHtyIEdyYWZpY29zX2RlX1BlcmZpbGVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnBsb3RjdCh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJEdlbmRlciwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCksInJvdyIpDQpwbG90Y3QodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRHZW5kZXIsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gpLCJjb2wiKQ0KDQpwbG90Y3QodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRHZW5kZXIsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCJyb3ciKQ0KcGxvdGN0KHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkR2VuZGVyLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSwiY29sIikNCg0KcGxvdGN0KHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCJyb3ciKQ0KcGxvdGN0KHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCJjb2wiKQ0KYGBgDQoNCiMjIyMjIFBydWViYXMgZGUgSGlww7N0ZXNpcw0KYGBge3IgUHJ1ZWJhc19kZV9Db3JyZXNwb25kZW5jaWEsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KY2hpc3EudGVzdCh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJEdlbmRlciwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCkpDQpjaGlzcS50ZXN0KHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkR2VuZGVyLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSkNCmNoaXNxLnRlc3QodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZykpDQpgYGANCg0KIyMjIyBBQyBQYXJlamEgw5puaWNhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIENvbnRpbmdlbmNpYXMgeSBSZXNpZHVhbGVzIFtSLVVSXQ0KYGBge3IgQ29udGluZ2VuY2lhc195X1Jlc2lkdWFsZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KY2hpc3EudGVzdCh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFJlc2VhcmNoLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSkkb2JzZXJ2ZWQNCmNoaXNxLnRlc3QodGFibGUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRSZXNlYXJjaCwgQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbCRVbml2ZXJzaXR5X1JhdGluZykpJGV4cGVjdGVkIA0KY2hpc3EudGVzdCh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFJlc2VhcmNoLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSkkcmVzaWR1YWxzDQpjaGlzcS50ZXN0KHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpKSRzdGRyZXMNCmBgYA0KDQojIyMjIyBDb250cmlidWNpb25lcyBbUi1VUl0NCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX1ItVVIsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KY2hpc3EudGVzdCh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFJlc2VhcmNoLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSkkcmVzaWR1YWxzXjIvY2hpc3EudGVzdCh0YWJsZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFJlc2VhcmNoLCBBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsJFVuaXZlcnNpdHlfUmF0aW5nKSkkc3RhdGlzdGljKjEwMA0KYGBgDQoNCiMjIyMjIENvcnJlc3BvbmRlbmNpYSBTaW1wbGUgVW5pZGltZW5zaW9uYWwgW1ItVVJdDQpgYGB7ciBCaXBsb3RfQ29ycmVzcG9uZGVuY2lhX1NpbXBsZV9SLVVSLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCkNBKHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCBncmFwaCA9IEZBTFNFKSRlaWcNCkNBKHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCBncmFwaCA9IEZBTFNFKSRjb2wNCkNBKHRhYmxlKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkUmVzZWFyY2gsIEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWwkVW5pdmVyc2l0eV9SYXRpbmcpLCBncmFwaCA9IEZBTFNFKSRyb3cNCmBgYA0KDQo8YSBuYW1lPSJzZWMxMiI+PC9hPg0KDQojIyAqKjEyLiBDb3JyZXNwb25kZW5jaWFzIE3Dumx0aXBsZXMqKg0KDQpSZWN1cGVyYW5kbyBkZSBudWV2byBlbCB0cmFiYWpvIGRlIFtAQUVETURpYXotTW9yYWxlczFlZF0gc2UgZGljZSBxdWUgZWwgQUNTIHNlIHB1ZWRlIGV4dGVuZGVyIGRlc2RlIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgaGFjaWEgdGFibGFzIGRpc3l1bnRpdmFzIGNvbXBsZXRhcy4gRW4gZXN0YXMgbGFzIGZpbGFzIHNvbiBsb3Mgb2JqZXRvcyBhIGxvcyBjdWFsZXMgc2UgbGVzIHJlZ2lzdHJhbiBjYXJhY3RlcsOtc3RpY2FzIGRlIGludGVyw6lzIGEgdHJhdsOpcyBkZSBsYXMgY29sdW1uYXMgcXVlIGNvbXBpbGFuIGxhcyBtb2RhbGlkYWRlcyBkZSBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBlc3R1ZGlhZGFzIGRlIGVsbG9zLiBBc8OtLCBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBtw7psdGlwbGUgKEFDTSkgZXMgZWwgQUMgYXBsaWNhZG8gYSB1bmEgdGFibGEgZGlzeXVudGl2YSBjb21wbGV0YS4gUG9yIGxvIHRhbnRvLCBlbiBlbCBBQ00gdW5hIHZhcmlhYmxlIGNhdGVnw7NyaWNhIGFzaWduYSBhIGNhZGEgb2JqZXRvIGRlIHVuYSBwb2JsYWNpw7NuIHVuYSBtb2RhbGlkYWQgYSB0cmF2w6lzIGRlIGxhIGN1YWwgbG9zIHBhcnRpY2lvbmEgZXhjbHVzaXZhIHkgZXhoYXVzdGl2YW1lbnRlLg0KDQpFc3RhIHNlY2Npw7NuIGVzIGRlc2Fycm9sbGFkYSBjb21vIGFsdGVybmF0aXZhIGRlIGNvbXBsZXRpdHVkIGRlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBzaW1wbGVzIHF1ZSBlbiBsYSBbc2VjY2nDs24gMTFdKCNzZWMxMSkgZnVlIGluYXByZWNpYWJsZSBkZWJpZG8gYSBsYSB1bmlkaW1lbnNpb25hbGlkYWQgZGUgbGEgcmVwcmVzZW50YWNpw7NuIGRlIGxvcyBkYXRvcyBhIG5pdmVsIGRlIHByb3llY2Npw7NuIGRlIGxhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHF1ZSBjdW1wbGllcm9uIGxhIGhpcMOzdGVzaXMgZGUgZGVwZW5kZW5jaWEuIFBvciBsbyB0YW50bywgZGVsIHRyYXRhbWllbnRvIGNvbmp1bnRvIGRlIHRvZGFzIGxhcyB2YXJhaWJsZXMgY2F0ZWfDs3JpY2FzIHNlIGVzcGVyYSBvYnRlbmVyIHVuYSByZXByZXNlbnRhY2nDs24gZW4gZWwgcHJpbWVyIHBsYW5vIGZhY3RvcmlhbC4NCg0KIyMjIDEyLjEuIFBsYW50ZWFtaWVudG8gZGVsIFByb2JsZW1hDQoNCkNvbiBiYXNlIGVuIGxhcyB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHNlIGRlbWFuZGEgZGVzYXJyb2xsYXIgZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcO6bHRpcGxlcyBwYXJhIGxvZ3JhciB1bmEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGVuIGVsIHByaW1lciBwbGFubyBmYWN0b3JpYWwsIGRlYmlkbyBhIGxhIGltcG9zaWJpbGlkYWQgZGUgbG9ncmFybG8gZW4gZWwgYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgc2ltcGxlLg0KDQojIyMgMTIuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIHBlcm1pdGUgdmlzdWFsaXphciBvYmpldG9zIG1hdHJpY2lhbGVzIHkgZ3LDoWZpY29zIHF1ZSBheXVkYW4gYSBkZXNhcnJvbGxhciBlIGludGVycHJldGFyIGVsIGFuw6FsaXNpcyBkZSBjb3JyZXNwb25kZW5jaWFzIG3Dumx0aXBsZSAoQUNNKSBlbnRyZSBsYXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgW3NlY2Npw7NuIDJdKCNzZWMyKS4NCg0KTGEgcGVzdGHDsWEgKipBQ00qKiBtdWVzdHJhIGxhIG11bHRpZGltZW5zaW9uYWxpZGFkIGVzcGVyYWRhLCBjb21wYXJhZGEgY29uIGxhIHVuaWRpbWVuc2lvbmFsaWRhZCBkZWwgQUNTIGRlIGxhIFtzZWNjacOzbiAxMV0oI3NlYzExKSwgYWwgdHJhYmFqYXIgY29uanVudGFtZW50ZSBjb24gbGFzIHRyZXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBkZWwgY29uanVudG8gZGUgZGF0b3M6ICoqR2VuZGVyKiosICoqVW5pdmVyc2l0eV9SYXRpbmcqKiB5ICoqUmVzZWFyY2gqKi4gTXVlc3RyYSBhZGVtw6FzIHF1ZSBsYXMgZGltZW5zaW9uZXMgZGVsIHBsYW5vIHByaW5jaXBhbCBleHBsaWNhbiBlbCAkNDIuMTYkICQlJCBkZWwgY29uanVudG8gKHNlcsOhIHNvYnJlIGVzdGUgcGxhbm8gcXVlIHNlIGNvbnRpbnVhcsOhIGNvbiBsYXMgaW50ZXJwcmV0YWNpb25lcyBkZWwgQUNNKS4gQWRlbcOhcywgbGEgZXZpZGVudGUgYmFqYSBjb25jZW50cmFjacOzbiBkZSBhYnNvcmNpw7NuIGRlIHZhcmlhbnphIHBvciBwYXJ0ZSBkZSBhbGd1bmEgbyBhbGd1bmFzIGRpbWVuc2lvbmVzIHNlIHJlZmxlamFyw6EgZW4gbGFzIGRpc3RhbmNpYXMgZW50cmUgbG9zIHBlcmZpbGVzIGRlIGxhcyB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLg0KDQpFbiBsYSBwZXN0YcOxYSAqKkJpcGxvdCBBQ00qKiBzZSBtdWVzdHJhbiBsYXMgc2VtZWphbnphcyBkZSBwZXJmaWxlcyBlbnRyZSBlc3R1ZGlhbnRlcyByZXByZXNlbnRhZG9zIHBvciBwdW50b3MgYXp1bGVzIHNvYnJlcHVlc3RvcyBxdWUgaW5kaWNhbiBjb29yZGVuYWRhcyBkZSBjb252ZXJnZW5jaWEgeSBsYXMgYXNvY2lhY2lvbmVzIGVudHJlIGFsZ3VuYXMgY2F0ZWdvcsOtYXMgZGUgbGFzIHZhcmlhYmxlcyB5IGNvbmp1bnRvcyBkZSBlc3R1ZGlhbnRlcy4gQ2FiZSBhbm90YXIgcXVlIGxhcyBzZW1lamFuemFzIGVudHJlIGNhdGVnb3LDrWEgZGUgbGFzIHZhcmlhYmxlcyBlc3TDoW4gcHJlc2VudGFkYXMgcG9yIHN1cyBjb29yZGVuYXMgcmVzcGVjdG8gZGUgbG9zIHNlbWllamVzIGRpbWVuc2lvbmFsZXMsIG3DoXMgcXVlIHBvciBzdXMgcHJveGltaWRhZGVzLCBlc3RvIGNvbmN1ZXJkYSBjb24gbG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIGVuIGxhIFtzZWNjacOzbiAxMV0oI3NlYzExKS4gUG9yIGVqZW1wbG8sIGVuIHNlbWVqYW56YSBhIG5pdmVsIGRlIGNhdGVnb3LDrWFzIGRlIGxhcyB2YXJpYWJsZXMgZGVzdGFjYW4gbG9zIGdydXBvczogb25lX3N0YXJzLCB0d29fc3RhcnMsIEYgeSBuby1yZXNlYXJjaCBwb3IgdW4gbGFkbywgcG9yIG90cm8sIGZpdmVfc3RhcnMsIGZvdXJfc3RhcnMsIE0geSByZXNlYXJjaCwgYXPDrSBjb21vIGNpZXJ0b3MgZ3J1cG9zIGV2aWRlbnRlcyBkZSBlc3R1ZGlhbnRlcy4gQ29tcGxlbWVudGFyaWFtZW50ZSwgYSBuaXZlbCBkZSBhc29jaWFjacOzbiBzZSBkZXN0YWNhIGxhIGRlbCBncnVwbyBkZSBlc3R1ZGlhbnRlcyBjZXJjYW5vcyBhIHR3b19zdGFycyB5IGxhIGRlIG90cm8gZ3J1cG8gbnV0cmlkbyBjZXJjYW5vIGEgZm91cl9zdGFycy4gRW4gZ2VuZXJhbCBzZSBwdWVkZW4gdmlzdWFsaXphciBmw6FjaWxtZW50ZSBsYXMgYXNvY2lhY2lvbmVzIGVudHJlIGxhcyBjYXRlZ29yw61hcyBkZSBsYXMgdmFyaWFibGVzIHkgbG9zIGdydXBvcyBkZSBlc3R1ZGlhbnRlcyBhZmluZXMgY29uIGVsbGFzLg0KDQpTZWd1aWRhbWVudGUsIGxhIHBlc3Rhw7FhICoqQ2FsaWRhZCBkZSBSZXByZXNlbnRhY2nDs24qKiBtdWVzdHJhIHF1ZSBsYXMgY2F0ZWdvcsOtYXMgZGUgbGEgdmFyaWFibGUgKipSZXNlYXJjaCoqIGZ1ZXJvbiBsYXMgbWVqb3IgcmVwcmVzZW50YWRhcywgZW4gb3Bvc2ljacOzbiBhIGxhcyBjYXRlZ29yw61hcyBvbmVfc3RhciB5IHRocmVlX3N0cmFycyBkZSBsYSB2YXJpYWJsZSAqKlVuaXZlcnNpdHlfUmF0aW5nKiouIEVsIHJlc3RvIHF1ZWTDsyBlbiB1biByYW5nbyBpbnRlcm1lZGlvLWFsdG8gZGUgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24uIENvbW8gbGEgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24gZW4gc3ViZXNwYWNpb3MgZGUgZGltZW5zacOzbiByZWR1Y2lkYSBzZSBtaWRlIGVuIHBvcmNlbnRhamVzIGRlIGluZXJjaWEgY29uIHJlc3BlY3RvIGEgbGEgdG90YWwgbGEgY2VyY2Fuw61hIGRlIHVuIHB1bnRvIGFsIG9yaWdlbiBkZWwgcGxhbm8gZmFjdG9yaWFsIGluZGljYSB1bmEgYmFqYSBjYWxpZGFkIGRlIHJlcHJlc2VudGFjacOzbiBlbiDDqWwsIHBvciBsbyB0YW50bywgbGEgY2F0ZWdvcsOtYSB0aHJlZV9zdGFycyBsYSBwcmVzZW50YS4gTGEgbWF0cml6IGRlIGNhbGlkYWQgZGUgcmVwcmVzZW50YWNpw7NuIGV2aWRlbmNpYSBudW3DqXJpY2FtZW50ZSBsYSBzaXR1YWNpw7NuIG1lbmNpb25hZGE6IHBhcmEgZWxsYSBsYSBzdW1hIGRlIGxvcyBjb3Nlbm9zIGN1YWRyYWRvcyBlbiBsYXMgZGltZW5zaW9uZXMgZGVsIHByaW1lciBwbGFubyBwbGFubyBmYWN0b3JpYWwgc29sbyBhc2NpZW5kZW4gYSAkMC4wOSQsIHNlZ3VpZGEgZGUgb25lX3N0YXIgcXVlIHN1bWEgJDAuMTgkLg0KDQpDb21wbGVtZW50YXJpYW1lbnRlLCBsYSBwZXN0YcOxYSAqKkNvbnRyaWJ1Y2lvbmVzKiogbXVlc3RyYSBxdWUgcGFyYSBsYXMgZGltZW5zaW9uZXMgZGVsIHByaW1lciBwbGFubyBmYWN0b3JpYWwsIHkgZW4gY29uY29yZGFuY2lhIGNvbiBsbyBleHByZXNhZG8gZW4gZWwgcMOhcnJhZm8gYW50ZXJpb3IsIGxhcyBjYXRlZ29yw61hcyBkZSBsYSB2YXJpYWJsZSAqKlVuaXZlcnNpdHlfUmF0aW5nKio6IG9uZV9zdGFyIHkgdGhyZWVfc3RhcnMsIGVuIGFtYmFzIGRpbWVuc2lvbmVzIHF1ZWRhbiBwb3IgZGViYWpvcCBkZSBsYSBsw61uZWEgbWVkaWEgZGUgY29udHJpYnVjacOzbiwgbWllbnRyYXMgcXVlIGxhcyBjYXRlZ29yw61hcyBkZSBsYSBtaXNtYSB2YXJpYWJsZTogZm91cl9zdGFycyB5IGZpdmVfc3RhcnMsIGFwb3J0YW4gZW4gYW1ib3MgY2Fzb3MgcG9yIGVubmNpbWEgZGUgbGEgbMOtbmVhIG1lZGlhLiBFbiBlc3RlIHNlbnRpZG8sIGVuIGxhIHBlc3Rhw7FhICoqQmlwbG90IGNvbiBDb250cmlidWNpb25lcyoqIHNlIMK0dmlzdWFsaXphIHVuYSByZXByZXNlbnRhY2nDs24gZW4gZWwgcHJpbWVyIHBsYW5vIGZhY3RvcmlhbCBzZW1lamFudGUgYSBsYSBvYnRlbmlkYSBlbiBsYSBwZXN0YcOxYSAqKmNhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuKiouDQoNCiMjIyMgQUNNDQpgYGB7ciBBQ00sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kcm91bmQoTUNBKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbMTo0MDAsIC1jKDEsMyw0LDUsNiw3LDEwKV0sIGdyYXBoID0gRkFMU0UpJGVpZywyKQ0KYGBgDQoNCiMjIyMgQmlwbG90IEFDTQ0KYGBge3IgQmlwbG90X0FDTSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X21jYV9iaXBsb3QoTUNBKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbMTo0MDAsIC1jKDEsMyw0LDUsNiw3LDEwKV0sIGdyYXBoID0gRkFMU0UpLCByZXBlbCA9IFRSVUUpDQpgYGANCg0KIyMjIyBDYWxpZGFkIGRlIFJlcHJlc2VudGFjacOzbg0KYGBge3IgQ2FsaWRhZF9kZV9SZXByZXNlbnRhY2lvbl9BQ00sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9tY2FfdmFyKE1DQShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWzE6NDAwLCAtYygxLDMsNCw1LDYsNywxMCldLCBncmFwaCA9IEZBTFNFKSwgY29sLnZhciA9ImNvczIiLCBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwgcmVwZWwgPSBUUlVFKQ0KTUNBKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbMTo0MDAsIC1jKDEsMyw0LDUsNiw3LDEwKV0sIGdyYXBoID0gRkFMU0UpJHZhciRjb3MyDQpgYGANCg0KIyMjIyBDb250cmlidWNpb25lcw0KYGBge3IgQ29udHJpYnVjaW9uZXNfQUNNLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmZ2aXpfY29udHJpYihNQ0EoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbFsxOjQwMCwgLWMoMSwzLDQsNSw2LDcsMTApXSwgZ3JhcGggPSBGQUxTRSksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMSwgdG9wID0gMTUpDQpmdml6X2NvbnRyaWIoTUNBKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbMTo0MDAsIC1jKDEsMyw0LDUsNiw3LDEwKV0sIGdyYXBoID0gRkFMU0UpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDE1KQ0KZnZpel9jb250cmliKE1DQShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWzE6NDAwLCAtYygxLDMsNCw1LDYsNywxMCldLCBncmFwaCA9IEZBTFNFKSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAzLCB0b3AgPSAxNSkNCmZ2aXpfY29udHJpYihNQ0EoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbFsxOjQwMCwgLWMoMSwzLDQsNSw2LDcsMTApXSwgZ3JhcGggPSBGQUxTRSksIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNCwgdG9wID0gMTUpDQpmdml6X2NvbnRyaWIoTUNBKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxbMTo0MDAsIC1jKDEsMyw0LDUsNiw3LDEwKV0sIGdyYXBoID0gRkFMU0UpLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDE1KQ0KYGBgDQoNCiMjIyMgQmlwbG90IGNvbiBDb250cmlidWNpb25lcw0KYGBge3IgQmlwbG90X2Nvbl9Db250cmlidWNpb25lc19BQ00sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9tY2FfdmFyKE1DQShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsWzE6NDAwLCAtYygxLDMsNCw1LDYsNywxMCldLCBncmFwaCA9IEZBTFNFKSwgY29sLnZhciA9ImNvbnRyaWIiLCBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwgcmVwZWwgPSBUUlVFKQ0KYGBgDQoNCiMjICoqT2JqZXRpdm8geSBBbm90YWNpb25lcyA6OiBGYXNlIDQqKg0KIyMgKipbQ29uZ2xvbWVyYWRvc10qKg0KRW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgZXN0YSBjdWFydGEgZXRhcGEgZGUgZXN0dWRpbyBtb3N0cmFyw6EgY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgZSBpbnRlcnByZXRhY2lvbmVzIGNvbiBiYXNlIGVuIGVsIGNvbmp1bnRvIGRlIGRhdG9zIHRyYXRhZG8gZW4gbGFzIGZhc2VzIFsxXSgjc2VjMSksIFsyXSgjZmFzZTIpIHkgWzNdKCNmYXNlMyksIHBlcm8gYWhvcmEgZGVzZGUgdW4gZW5mb3F1ZSBkZSBhbsOhbGlzaXMgZGUgY29uZ2xvbWVyYWRvcyBlbiB2ZXJzacOzbiBqZXLDoXJxdWljYSAoZGVuZG9ncmFtYXMpIHkgbm8tamVyw6FycXVpY2EgKCpLKi1tZWRpYXMpLg0KDQpSZWN1w6lyZGVzZSBxdWUgZWwgY29uanVudG8gZGUgZGF0b3MgZGUgdHJhYmFqbyBlc3TDoSBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHkgbG9zIHJlZmVyZW50ZXMgdGXDs3JpY29zIGVuIGxhIFtzZWNjacOzbiAxXSgjc2VjMSkuDQoNClBvciDDumx0aW1vLCBlc3RlIHRyYWJham8gZnVlIHByb2Nlc2FkbyBjb24gYHIgUi52ZXJzaW9uLnN0cmluZ2AgbWVkaWFkbyBwb3IgUlN0dWRpbyAyMDIyLjEyLjAgQnVpbGQgMzUzIGVuIHVuYSBwbGF0YWZvcm1hIHg4Nl82NC13NjQtbWluZ3czMi4gQWRlbcOhcywgcG9yIHN1IG5hdHVyYWxlemEgZGUgcHVibGljYWNpw7NuIGVuIGzDrW5lYSB5IHBhcmEgY3VtcGxpciBjb24gZWwgcmVxdWlzaXRvIHRlbXBvcmFsIGRlIGVudHJlZ2EsIHNlcsOhIGFjdHVhbGl6YWRvLCBjb21vIG3DoXhpbW8sIGhhc3RhIGxhcyAxMTo1OSBwLm0uIGRlbCBkb21pbmdvIDEyIGRlIG1hcnpvIGRlIDIwMjMuDQoNCjxhIG5hbWU9InNlYzEzIj48L2E+DQoNCiMjICoqMTMuIEFncnVwYWNpw7NuIEplcsOhcnF1aWNhKioNCg0KU2Vnw7puIFtAQUVETURpYXotTW9yYWxlczFlZF0sIHF1aWVuZXMgY2l0YW4gZWwgdHJhYmFqbyBkZSBFdmVyaXR0IGRlIDE5ODAgdGl0dWxhZG8gQ2x1c3RlciBBbmFseXNpcywgbG9zIGNvbmdsb21lcmFkb3MgcHVlZGVuIGNvbmNlYmlyc2UgY29tbyByZWdpb25lcyBjb250aW51YXMgZGUgdW4gZXNwYWNpbyBxdWUgY29udGllbmVuIHVuYSByZWxhdGl2YW1lbnRlIGFsdGEgZGVuc2lkYWQgZGUgcHVudG9zLCBxdWUgYSBzdSB2ZXogZXN0w6FuIHNlcGFyYWRhcyBwb3IgcmVnaW9uZXMgKMK/Y29udGludWFzPykgcXVlIGNvbnRpZW5lbiB1bmEgcmVsYXRpdmFtZW50ZSBiYWphIGRlbnNpZGFkIGRlIHB1bnRvcy4gUGFyYSBjb25mb3JtYXIgdGFsZXMgcmVnaW9uZXMgZGUgcHVudG9zIHNlIGhhbiBwcm9wdWVzdG8sIHBvciBlamVtcGxvLCBtw6l0b2RvcyBqZXLDoXJxdWljb3MuIEVzdG9zIGluaWNpYW4gY29uIGVsIGPDoWxjdWxvIGRlIGxhIG1hdHJpeiBkZSBkaXN0YW5jaWFzIGVudHJlIGxvcyBvYmpldG9zIHRyYXRhZG9zLCBjb24gbG9zIGN1YWxlcyBzZSBjb25mb3JtYW4gZ3J1cG9zIHBvciBhZ2xvbWVyYWNpw7NuIGEgdHJhdsOpcyBkZSBldGFwYXMgcXVlIGVtcGllemFuIHBvciBjb25nbG9tZXJhZG9zIHVuaXRhcmlvcyAoZWwgY2FzbyB0cml2aWFsIGluaWNpYWwsIGNvbW8gdGFtYmnDqW4gZWwgY2FzbyB0cml2aWFsIGZpbmFsOiB1biBjb25nbG9tZXJhZG8gdG90YWwpLiBFbnRyZSBsYXMgb3BjaW9uZXMgcmVzdGFudGVzIHNlIHByZXNlbnRhbiBmdXNpb25lcyB5IGRpdmlzaW9uZXMgZGUgZ3J1cG9zIHF1ZSBlc3BlY2lmaWNhbiBqZXJhcnF1w61hcyBwb3Igc2ltaWxhcmlkYWRlcyBxdWUgIHBlcm1pdGVuIHVuYSByZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgY29ub2NpZGEgY29tbyBkZW5kb2dyYW1hLg0KDQojIyMgMTMuMS4gUGxhbnRlYW1pZW50byBkZWwgUHJvYmxlbWENCg0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHNlIGRlbWFuZGEgZGVzYXJyb2xsYXIgZWwgYW7DoWxpc2lzIGRlIGNvbmdsb21lcmFkb3MgY29uIGJhc2UgYWdydXBhY2lvbmVzIGplcsOhcnF1aWNhcyBxdWUgc2UgcmVwcmVzZW50ZW4gY29uIGRlbmRvZ3JhbWFzLCBlc3RvIGltcGxpY2EgY2xhc2lmaWNhciBhIGxvcyBvYmpldG9zIGRlIHRyYWJham8gY29uIG3DqXRvZG9zIGFnbG9tZXJhdGl2b3MgZGVsIHZlY2lubyBtw6FzIGNlcmNhbm8sIG3DoXMgbGVqYW5vIHkgZGUgbGEgdW5pw7NuIG1lZGlhbnRlIGVsIHByb21lZGlvLCBzb3BvcnRhZG9zIGVuIGxhIGRpc3RhbmNpYSBldWNsaWRpYW5hLg0KDQojIyMgMTMuMi4gRGVzYXJyb2xsbyBkZWwgQW7DoWxpc2lzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCkxhIG5hdmVnYWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgcGVzdGHDsWFzIHBlcm1pdGUgdmlzdWFsaXphciBvYmpldG9zIG1hdHJpY2lhbGVzIHkgZ3LDoWZpY29zIHF1ZSBheXVkYW4gYSBkZXNhcnJvbGxhciBlIGludGVycHJldGFyIGVsIGFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zIGVudHJlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgW3NlY2Npw7NuIDJdKCNzZWMyKS4NCg0KQ29uIGVsIGZpbiBkZSB2aXN1YWxhciBhZGVjdWFkYW1lbnRlIGxvcyBkYXRvcywgeSBzb2xvIGNvbiBwcm9ww7NzaXRvcyBhY2Fkw6ltaWNvcywgZWwgY29uanVudG8gZGUgZGF0b3MgZGVzY3JpdG8gZW4gbGEgW3NlY2Npw7NuIDJdKCNzZWMyKSBmdWUgbW9kaWZpY2FkbyBkZSB0cmVzIG1hbmVyYXMuIFByaW1lcm8sIHNlIGxlIGFncmVnw7MgdW5hIHZhcmlhYmxlIGNhdGVnw7NyaWNhIGNsYXNpZmljYWRvcmE6ICoqTmF0aW9uYWxpdHkqKi4gRXN0YSB2YXJpYWJsZSBzZSBvYnR1dm8gZGVsIDxhIGhyZWYgPSAiaHR0cHM6Ly93d3cuaWllLm9yZy8iIHRpdGxlID0gIkluc3RpdHV0ZSBvZiBJbnRlcm5hdGlvbmFsIEVkdWNhdGlvbiIgdGFyZ2V0ID0gIl9ibGFuayIgcmVsID0gIm5vb3BlbmVyIG5vcmVmZXJyZXIiPkluc3RpdHV0ZSBvZiBJbnRlcm5hdGlvbmFsIEVkdWNhdGlvbjwvYT4gKEluc3RpdHV0byBkZSBFZHVjYWNpw7NuIEludGVybmFjaW9uYWwpIHBhcmEgdW5hIGZlY2hhIGVxdWl2YWxlbnRlIGEgbGEgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGluaWNpYWwuIExhIG1vZGlmaWNhY2nDs24gY29uc2lzdGnDsyBlbiBhZ3JlZ2FyIHVuIGNhbXBvIHF1ZSByZWdpc3RyYXNlIHBhcmEgY2FkYSBlc3R1ZGFudGUgZXh0cmFuamVybyBzdSBuYWNpb25hbGlkYWQuIENvbW8gbGFzIHByb3BvcmNpb25lcyBkZSBwYXJ0aWNpcGFjacOzbiBkZSBsYXMgbmFjaW9uYWxpZGFkZXMgZGUgbG9zIGVzdHVkaWFudGVzIGZ1ZXJvbiBkaWZlcmVudGVzLCBwZXJvIGNvbm9jaWRhcywgZWwgbcOpdG9kbyBkZSBhc2lnbmFjacOzbiBmdWUgYWxlYXRvcmlvIHkgcG9uZGVyYWRvIGNvbiBiYXNlIGVuIGVsbGFzICh2w6lhc2UgbGEgcGVzdGHDsWEgKipDYW1wbyBDbGFzaWZpY2Fkb3IqKikuIENhYmUgbWVuY2lvbmFyIHF1ZSBsYSBhc2lnbmFjacOzbiBzZSBoaXpvIGRpcmVjdGFtZW50ZSBlbiBlbCBsaWJybyBkZSBjw6FsY3VsbyBjb24gYmFzZSBlbiBsYSBmw7NybXVsYSAqPUlORElDRShbUkFOR09fREVfRVRJUVVFVEFTXTsgQ09OVEFSLlNJKFtSQU5HT19ERV9QUk9QT1JDSU9ORVNfQUNVTVVMQURBU107ICI8PSIgJiBBTEVBVE9SSU8oKSkgKyAxKSogcGFyYSA0MDAgcmVnaXN0cm9zLiBBZGVtw6FzLCBlbCBjYW1wbyAqKk5hdGlvbmFsaXR5KiogcmVnaXN0cmEganVudG8gY29uIGxhIG5hY2lvbmFsaWRhZCBkZWwgZXN0dWRpYW50ZSBsYSBwb3NpY2nDs24gcXVlIG9jdXBhIGRpY2hvIHBhw61zIGNvbW8gYXBvcnRhbnRlIGRlIGVzdHVkaWFudGVzIGV4dHJhbmplcm9zIGVuIGVsIHBlcmlvZG8gZGUgbWVkaWNpw7NuLiBTZWd1bmRvLCBzZSBlc3RhbmRhcml6YXJvbiBlbiB1bmEgZXNjYWxhIGRlICQwJCBhICQxJCB0b2RhcyBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMuIFBvciDDumx0aW1vLCBzZSBhcGxpY8OzIHVuIGZpbHRybyBhIGxvcyByZWdpc3Ryb3MgY29uIGJhc2UgZW4gbGEgdmFyaWFibGUgY2xhc2lmaWNhZG9yYSB5IHNlIGNhbGN1bGFyb24gbnVldm9zIHJlZ2lzdHJvcyBwcm9tZWRpbyBkZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMuIEFzw60sIGVsIGFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zIHNlIGhpem8gY29uIGJhc2UgZW4gZWwgY29uanVudG8gZGUgZGF0b3MgbW9zdHJhZG8gZW4gbGEgcGVzdGHDsWEgKipDb25qdW50byBNb2RpZmljYWRvKiosIGVzdGEgaW5kaWNhIGxvcyBwcmltZXJvcyByZWdpc3Ryb3MgeSBsYSBlc3RydWN0dXJhIGRlbCBjb25qdW50by4NCg0KTGEgcGVzdGHDsWEgKipEaXNpbWlsYXJpZGFkKiogbXVlc3RyYSB2aXN1YWxtZW50ZSBsb3MgcmVnaXN0cm9zIGRlIHByb3hpbWlkYWQgZW50cmUgbGFzIGNhdGVnb3LDrWFzIGRlIGxhIHZhcmlhYmxlIGNsYXNpZmljYWRvcmEgKipOYXRpb25hbGl0eSoqLiBDb24gYmFzZSBlbiB1bmEgZXNjYWxhIGRlIGNvbG9yZXMgcXVlIGluZGljYSBsYXMgZGlzdGFuY2lhcyBlbnRyZSBsYXMgb2JzZXJ2YWNpb25lcywgcHVlZGUgb2JzZXJ2YXJzZSBxdWUgdmFsb3JlcyBjb21vOiBUYWl3w6FuLCBBbGVtYW5pYSBlIEluZG9uZXNpYSBlc3TDoW4gaW50ZW5zYW1lbnRlIGRpc3RhbnRlcyBkZWwgcmVzdG8uIFRhbWJpw6luLCBwb3IgZWplbXBsbywgZW4gb3Bvc2ljacOzbiBhIGxvcyB2YWxvcmVzIG1lbmNpb25hZG9zLCBUYWlsYW5kaWEsIE1hbGFzaWEgeSBDb2xvbWJpYSBzb24gbWVub3MgZGlzw61taWxlcy4gQXPDrSwgc2UgZXNwZXJhcsOtYSBxdWUgbG9zIHZhbG9yZXMgbWVuY2lvbmFkb3Mgc2UgYWdydXBhcmFuIGVudHJlIHPDrSBvIGZvcm1hcmFuIGdydXBvcyBkZSBqZXJhcnF1w61hcyBwcm9waWFzLCBjb24gZGlzdGFuY2lhcyBkZSBhZ2xvbWVyYWNpw7NuIGdyYW5kZXMgZW4gZWwgcGFzbyBjb3JyZXNwb25kaWVudGUuDQoNCkNvbXBsZW1lbnRhcmlhbWVudGUsIGxhIHBlc3Rhw7FhICoqT3B0aW1pemFjacOzbiBkZSBNb2plbmEqKiBtdWVzdHJhIHNlcGFyYWRhbWVudGUgZWwgbsO6bWVybyDDs3B0aW1vIGRlIGNvbmdsb21lcmFkb3MgamVyw6FycXVpY29zIHF1ZSBkZWJlcsOtYW4gY29uZmlndXJhcnNlIGRlIHRhbCBmb3JtYSBxdWUgbGFzIGhldXLDrXN0aWNhcyB1c2FkYXMgZW50cmVnYXJhbiBsb3MgbWVqb3JlcyByZXN1bHRhZG9zIHBvc2libGVzIGRlIGludHJhIGUgaW50ZXIgc2ltaWxhcmlkYWQuIEVuIGVzdGUgc2VudGlkbywgbGEgZXN0cmF0ZWdpYSBkZWwgdmVjaW5vIG3DoXMgY2VyY2FubyAoKipVbmnDs24gU2ltcGxlKiopIGVzdGFibGVjZSBxdWUgZXNlIG7Dum1lcm8gZXMgdHJlcywgbGEgZGVsIHZlY2lubyBtw6FzIGxlamFubyAoKip1bmnDs24gY29tcGxldGEqKikgZGljdGEgcXVlIHRhbWJpw6luIGVzIHRyZXMgeSBsYSBkZSAqKlVuacOzbiBQcm9tZWRpbyoqIG11ZXN0cmEgcXVlIGVzIGN1YXRybywgYSBjYWRhIHVuYSBkZSBlc3RhcyBjYW50aWRhZGVzIGRlIGNvbmdsb21lcmFkb3Mgc2UgbGUgYXNvY2lhcsOhIHN1IHJlc3BlY3Rpdm8gZGVuZG9ncmFtYS4NCg0KRWZlY3RpdmFtZW50ZSwgZW4gbGEgcGVzdGHDsWEgKipEZW5kb2dyYW1hcyBPcHRpbWl6YWRvcyoqIHNlIGF2YWxhbiBncsOhZmljYW1lbnRlIGxhcyBtZW5jaW9uZXMgaGVjaGFzIGVuIGVsIHDDoXJyYWZvIHNvYnJlICoqRGlzaW1pbGFyaWRhZCoqIChwb3IgZWplbXBsbywgbGEgc2ltaWxhcmlkYWQgZW50cmUgbG9zIHZhbG9yZXMgZGUgVGFpbGFuZGlhIHkgTWFsYXNpYSBwb3IgdW4gbGFkbywgeSBBbGVtYW5hbmlhIHkgVGFpd2FuIHBvciBvdHJvLCBhIGNvbmdsb21lcmFyc2UpLCBhZGVtw6FzIGRlIHZlcmlmaWNhciBjb24gbcOhcyBwcmVjaXNpw7NuIGxhcyBhbHR1cmFzIGplcsOhcnF1aWNhcywgZW4gcGFydGljdWxhciBwYXJhIGVsICoqRW5sYWNlIENvbXBsZXRvKiogeSBlbCAqKkVubGFjZSBQcm9tZWRpbyoqLCBlbiBlc3RvcyBsb3Mgbml2ZWxlcyBkZSBzaW1pbGl0dWQgc29uIGbDoWNpbG1lbnRlIGFwcmVjaWFibGVzIHkgZWZlY3RpdmFtZW50ZSBkZWNpc29yaW9zIHNvYnJlIGxhIGNhbnRpZGFkIGRlIGNvbmdsb21lcmFkb3Mgw7NwdGltb3MgcHJlY2FsY3VsYWRvcy4gRXMgZGVjaXIsIGVsIGRlbmRvZ3JhbWEgZGUgKipFbmxhY2UgU2ltcGxlKiogcXVlIHNlIGNyZcOzIGNvbiBiYXNlIGVuIHRyZXMgY29uZ2xvbWVyYWRvcyBhIHVuIG5pdmVsIGRlIHNpbWlsaXR1ZCBkZSBhcHJveGltYWRhbWVudGUgJDIuMyQgcHJlc2VudGEgZGlzdGFuY2lhcyBkZSBhZ2xvbWVyYWNpw7NuIGNlcmNhbmFzIGNvbiBsYSBob3Jpem9udGFsIGRlIGNvcnRlLCB5IGVuIGdlbmVyYWwgZW50cmUgb3Ryb3Mgbml2ZWxlcyBkZSBzaW1pbGl0dWQsIGVzdG8gaGFjZSBxdWUgbG9zIGNvbmdsb21lcmFkb3Mgc2VhbiBkaWbDrWNpbG1lbnRlIGRpc2Nlcm5pYmxlcy4gQ2FzbyBjb250cmFyaW8gb2N1cnJlIGNvbiBlbCAqKkVubGFjZSBDb21wbGV0byoqIHkgZWwgKipFbmxhY2UgUHJvbWVkaW8qKiBlbiBsb3MgY3VhbGVzIGxhcyBkaXN0YW5jaWFzIGRlIGFnbG9tZXJhY2nDs24gc29uIGFsdGFzIHkgZmFjaWxpdGFuIGxhIGFwcmVjaWFjacOzbiBkZSBsb3MgY29uZ2xvbWVyYWRvcywgZW4gZWwgcHJpbWVybywgYSB1biBuaXZlbCBkZSBzaW1pbGl0dWQgZGUgYXByb3hpbWFkYW1lbnRlICQ1LjAkIHNlIHZpc3VhbGl6YW4gdHJlcyBjb25nbG9tZXJhZG9zIGRlIDcsIDEsIHkgMTYgb2JzZXJ2YWNpb25lcywgY29udGFkYXMgZGUgaXpxdWllcmRhIGEgZGVyZWNoYTsgZW4gZWwgc2VndW5kbywgYSB1biBuaXZlbCBkZSBzaW1pbGl0dWQgc3VwZXJpb3IgYSAkMy41JCBzZSBhcHJlY2lhbiBjdWF0cm8gY29uZ2xvbWVyYWRvcyBjb25mb3JtYWRvcyBwb3IgMSwgMiwgMSB5IDIwIG9ic2VydmFjaW9uZXMsIGNvbnRhZGFzIGRlIGl6cXVpZXJkYSBhIGRlcmVjaGEuIEVuIGFtYm9zIGNhc29zLCBzZSBlbnRpZW5kZSBxdWUgc2kgbG9zIGRlbmRvZ3JhbWFzIHNlIGNvcnRhcmFuIG3DoXMgYXJyaWJhIGRlIGxvcyByZXNwZWN0aXZvcyBuaXZlbGVzIGRlIHNpbWlsaXR1ZCBpbmRpY2Fkb3MsIGVudG9uY2VzIHJlc3VsdGFyw61hbiBtZW5vcyBjb25nbG9tZXJhZG9zIGZpbmFsZXMsIGNvbiBuaXZlbGVzIGRlIHNpbWlsaXR1ZCBtYXlvcjsgb3B1ZXN0YW1lbnRlLCBzaSBmdWVzZW4gY29ydGFkb3MgbcOhcyBhYmFqbywgZW50b25jZXMgbG9zIG5pdmVsZXMgZGUgc2ltaWxpdHVkIHNlcsOtYW4gbWVub3JlcywgcGVybyBzZXLDrWFuIG9idGVuaWRvcyBtw6FzIGNvbmdsb21lcmFkb3MgZmluYWxlcywgZGUgYWjDrSBlbCBjw6FsY3VsbyBkZWwgbsO6ZW1ybyDDs3B0aW1vIGRlIGNvbmdsb21lcmFkb3MuDQoNCiMjIyMgQ2FtcG8gQ2xhc2lmaWNhZG9yDQpgYGB7ciBDYW1wb19DbGFzaWZpY2Fkb3IsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KYXMuZGF0YS5mcmFtZShOYXRpb25hbGl0aWVzKVsxOjI0LC1jKDQsNSw2KV0NCmBgYA0KDQojIyMjIENvbmp1bnRvIE1vZGlmaWNhZG8NCmBgYHtyIENvbmp1bnRvX01vZGlmaWNhZG8sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KaGVhZChhcy5kYXRhLmZyYW1lKEFkbWlzc2lvbl9EYXRhc2V0X0luaXRpYWxfTmF0X0F2ZXJhZ2UpKQ0Kc3RyKGFzLmRhdGEuZnJhbWUoQWRtaXNzaW9uX0RhdGFzZXRfSW5pdGlhbF9OYXRfQXZlcmFnZSkpDQpgYGANCg0KIyMjIyBEaXNpbWlsYXJpZGFkDQpgYGB7ciBEaXNpbWlsYXJpZGFkLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdGFfID0gYXMuZGF0YS5mcmFtZShBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsX05hdF9BdmVyYWdlKVssIC1jKDEpXQ0Kcm93bmFtZXMoZGF0YV8pID0gdW5jbGFzcyhBZG1pc3Npb25fRGF0YXNldF9Jbml0aWFsX05hdF9BdmVyYWdlJE5hdGlvbmFsaXR5KQ0KZnZpel9kaXN0KGdldF9kaXN0KGRhdGFfLCBzdGFuZCA9IFQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgZ3JhZGllbnQgPSBsaXN0KGxvdyA9ICIjMDBBRkJCIiwgbWlkID0gIndoaXRlIiwgaGlnaCA9ICIjRkM0RTA3IikpDQpgYGANCg0KIyMjIyBPcHRpbWl6YWNpw7NuIGRlIE1vamVuYSAgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgVW5pw7NuIFNpbXBsZQ0KYGBge3IgT3B0aW1pemFjaW9uX01vamVuYV9TaW1wbGUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KaGNfc2luZ2xlID0gaGNsdXN0KGdldF9kaXN0KGRhdGFfLCBzdGFuZCA9IFQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgbWV0aG9kID0gInNpbmdsZSIpDQoNCm1vamVuYSA9IGZ1bmN0aW9uKGhjKXsNCiAgbl9oZCA9IGxlbmd0aChoYyRoZWlnaHQpDQogIGFscF9nID0gMCA7IGFscGhhID0gaGMkaGVpZ2h0W25faGQ6MV0NCiAgZm9yKGkgaW4gMToobl9oZC0xKSl7DQogICAgYWxwX2dbaV0gPSBtZWFuKGFscGhhWyhuX2hkLWkrMSk6MV0pKzEuMjUqc2QoYWxwaGFbKG5faGQtaSsxKToxXSkNCiAgfQ0KICBub2cgPSBzdW0oYWxwX2c8PSBhbHBoYVstbl9oZF0pICsgMQ0KICBwbG90KGFscGhhWy1uX2hkXSwgcGNoPTIwLCBjb2w9KGFscF9nPmFscGhhWy1uX2hkXSkrMSwgbWFpbiA9IHBhc3RlKCJPcHRpbWFsIG51bWJlciBvZiBncm91cHMgPSIsbm9nKSwNCiAgICAgICB5bGFiID0gZXhwcmVzc2lvbihhbHBoYVtnXSksIHhsYWI9Ik5vZGVzIil9DQoNCm1vamVuYShoY19zaW5nbGUpDQpgYGANCg0KIyMjIyMgVW5pw7NuIENvbXBsZXRhDQpgYGB7ciBPcHRpbWl6YWNpb25fTW9qZW5hX0NvbXBsZXRvLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmhjX2NvbXBsZXRlID0gaGNsdXN0KGdldF9kaXN0KGRhdGFfLCBzdGFuZCA9IFQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgbWV0aG9kID0gImNvbXBsZXRlIikNCg0KbW9qZW5hID0gZnVuY3Rpb24oaGMpew0KICBuX2hkID0gbGVuZ3RoKGhjJGhlaWdodCkNCiAgYWxwX2cgPSAwIDsgYWxwaGEgPSBoYyRoZWlnaHRbbl9oZDoxXQ0KICBmb3IoaSBpbiAxOihuX2hkLTEpKXsNCiAgICBhbHBfZ1tpXSA9IG1lYW4oYWxwaGFbKG5faGQtaSsxKToxXSkrMS4yNSpzZChhbHBoYVsobl9oZC1pKzEpOjFdKQ0KICB9DQogIG5vZyA9IHN1bShhbHBfZzw9IGFscGhhWy1uX2hkXSkgKyAxDQogIHBsb3QoYWxwaGFbLW5faGRdLCBwY2g9MjAsIGNvbD0oYWxwX2c+YWxwaGFbLW5faGRdKSsxLCBtYWluID0gcGFzdGUoIk9wdGltYWwgbnVtYmVyIG9mIGdyb3VwcyA9Iixub2cpLA0KICAgICAgIHlsYWIgPSBleHByZXNzaW9uKGFscGhhW2ddKSwgeGxhYj0iTm9kZXMiKX0NCg0KbW9qZW5hKGhjX2NvbXBsZXRlKQ0KYGBgDQoNCiMjIyMjIFVuacOzbiBQcm9tZWRpbw0KYGBge3IgT3B0aW1pemFjaW9uX01vamVuYV9Qcm9tZWRpbywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpoY19hdmVyYWdlID0gaGNsdXN0KGdldF9kaXN0KGRhdGFfLCBzdGFuZCA9IFQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgbWV0aG9kID0gImF2ZXJhZ2UiKQ0KDQptb2plbmEgPSBmdW5jdGlvbihoYyl7DQogIG5faGQgPSBsZW5ndGgoaGMkaGVpZ2h0KQ0KICBhbHBfZyA9IDAgOyBhbHBoYSA9IGhjJGhlaWdodFtuX2hkOjFdDQogIGZvcihpIGluIDE6KG5faGQtMSkpew0KICAgIGFscF9nW2ldID0gbWVhbihhbHBoYVsobl9oZC1pKzEpOjFdKSsxLjI1KnNkKGFscGhhWyhuX2hkLWkrMSk6MV0pDQogIH0NCiAgbm9nID0gc3VtKGFscF9nPD0gYWxwaGFbLW5faGRdKSArIDENCiAgcGxvdChhbHBoYVstbl9oZF0sIHBjaD0yMCwgY29sPShhbHBfZz5hbHBoYVstbl9oZF0pKzEsIG1haW4gPSBwYXN0ZSgiT3B0aW1hbCBudW1iZXIgb2YgZ3JvdXBzID0iLG5vZyksDQogICAgICAgeWxhYiA9IGV4cHJlc3Npb24oYWxwaGFbZ10pLCB4bGFiPSJOb2RlcyIpfQ0KDQptb2plbmEoaGNfYXZlcmFnZSkNCmBgYA0KDQojIyMjIERlbmRvZ3JhbWFzIE9wdGltaXphZG9zIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIEVubGFjZSBTaW1wbGUNCmBgYHtyIERlbmRvZ3JhbWFfRW5sYWNlX1NpbXBsZSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzdXBwcmVzc1dhcm5pbmdzKGZ2aXpfZGVuZChoY19zaW5nbGUsIGsgPSAzLCBjZXggPSAwLjUsIGtfY29sb3JzID0gIm5wZyIsIGNvbG9yX2xhYmVsc19ieV9rID0gVCwgcmVjdCA9IFQpKQ0KYGBgDQoNCiMjIyMjIEVubGFjZSBDb21wbGV0bw0KYGBge3IgRGVuZG9ncmFtYV9FbmxhY2VfQ29tcGxldG8sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9kZW5kKGhjX2NvbXBsZXRlLCBrID0gMywgY2V4ID0gMC41LCBrX2NvbG9ycyA9ICJucGciLCBjb2xvcl9sYWJlbHNfYnlfayA9IFQsIHJlY3QgPSBUKQ0KYGBgDQoNCiMjIyMjIEVubGFjZSBQcm9tZWRpbw0KYGBge3IgRGVuZG9ncmFtYV9FbmxhY2VfUHJvbWVkaW8sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9kZW5kKGhjX2F2ZXJhZ2UsIGsgPSA0LCBjZXggPSAwLjUsIGtfY29sb3JzID0gIm5wZyIsIGNvbG9yX2xhYmVsc19ieV9rID0gVCwgcmVjdCA9IFQpDQpgYGANCg0KPGEgbmFtZT0ic2VjMTQiPjwvYT4NCg0KIyMgKioxNC4gQWdydXBhY2nDs24gbm8tSmVyw6FycXVpY2EqKg0KDQpFbiBlbCB0cmFiYWpvIGRlIFtAQUVETURpYXotTW9yYWxlczFlZF0gc2UgZXN0YWJsZWNlIHF1ZSwgZW4gdMOpcm1pbm9zIGdlbmVyYWxlcywgbG9zIG3DqXRvZG9zIGRlIGFnbG9tZXJhY2nDs24gbm8tamVyw6FycXVpY29zIChvIGRlIHBhcnRpY2nDs24pIHNlIGltcGxlbWVudGFuIGNvbiBiYXNlIGVuIGxhIGRldGVybWluYWNpw7NuIGluaWNpYWwgZGUgYWxndW5hIHBhcnRpY2nDs24gZGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBxdWUsIGV2aWRlbnRlbWVudGUsIGdlbmVyYSBzdWJjb25qdW50b3MgZGUgZGF0b3MsIGVzIGRlY2lyLCBvdHJhcyBwYXJ0aWNpb25lcyBhIGxhcyBjdWFsZXMgc2UgbGVzIGNhbGN1bGEgc3VzIHJlc3BlY3Rpdm9zIGNlbnRyb2lkZXM7IGx1ZWdvLCBsYXMgb2JzZXJ2YWNpb25lcyBzZSB2aW5jdWxhbiBjb24gZWwgY29uZ2xvbWVyYWRvIGN1eW8gY2VudHJvaWRlIGVzdMOpIG3DoXMgY2VyY2FubyBwYXJhIGNhbGN1bGFyIGRlIG51ZXZvIGVsIGNlbnRyb2lkZSBkZSBsb3MgY29uZ2xvbWVyYWRvcyB5IHNlIGhhY2VuIGNvbXBhcmFjaW9uZXMgdm9yYWNlcywgcGFyYSBjb250aW51YXIgcmVjdXJzaXZhbWVudGUgaGFzdGEgcXVlIGxhcyBvYnNlcnZhY2lvbmVzIHNlYW4gaXJyZW1vdmlibGVzIGRlIHN1cyByZXNwZWN0aXZhcyBwYXJ0aWNpb25lcy4gQXPDrSwgY29udHJhcmlvIGEgbG9zIG3DqXRvZG9zIGplcsOhcnF1aWNvcywgbGEgdWJpY2FjacOzbiBkZSB1bmEgb2JzZXJ2YWNpw7NuIGVuIHVuIGNvbmdsb21lcmFkbyBwdWVkZSB2YXJpYXIuDQoNCkVsIG3DqXRvZG8gbm8tamVyw6FycXVpY28gY29uIGVsIHF1ZSBzZSBjZXJyYXLDoSBlbCBlc3R1ZGlvIGRlbCBjb25qdW50byBkZSBkYXRvcyBjb24gZWwgcXVlIHNlIGhhIHRyYWJhamFkbyBoYXN0YSBhaG9yYSBlcyBlbCBkZSAqSyotbWVkaWFzLiBFc3RlIHBhcnRpY2lvbmEgdW4gY29uanVudG8gZGUgJG4kIG9iamV0b3MgZW4gJGskIGdydXBvcywgbG8gaGFjZSBhbCBlc2NvZ2VyIGxvcyBjZW50cm9pZGVzIGRlIGxvcyBncnVwb3MgcXVlIG1pbmltaXphbiBsYSBkaXN0YW5jaWEgKGV1Y2xpZGlhbmEpIGVudHJlIGNhZGEgb2JqZXRvICB5IGVsbG9zLCBwYXJhIGFzaWduYXIsIGVuIGNvbnNlY3VlbmNpYSwgYSBjYWRhIGluZGl2aWR1byBhbCBjb25nbG9tZXJhZG8gY3V5byBjZW50cm9pZGUgZXN0w6kgbcOhcyBjZXJjYW5vIGEgw6lsLiBQb3IgbG8gdGFudG8sIGVsIG3DqXRvZG8gdGllbmUgY29tbyBvYmpldGl2byByZXViaWNhciBhIGxvcyBvYmpldG9zIGVuIGdydXBvcyB0YWxlcyBxdWUgcHJlc2VudGVuIGxhIG1lbm9yIHZhcmlhYmlsaWRhZCBwb3NpYmxlLg0KDQojIyMgMTQuMS4gUGxhbnRlYW1pZW50byBkZWwgUHJvYmxlbWENCg0KQ29uIGJhc2UgZW4gbGFzIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZXNjcml0byBlbiBsYSBbc2VjY2nDs24gMl0oI3NlYzIpIHNlIGRlbWFuZGEgZGVzYXJyb2xsYXIgZWwgYW7DoWxpc2lzIGRlIGNvbmdsb21lcmFkb3MgY29uIGJhc2UgYWdydXBhY2lvbmVzIG5vLWplcsOhcnF1aWNhcyBhIHRyYXbDqXMgZGVsIG3DqXRvZG8gZGUgbGFzICpLKi1tZWRpYXMgeSBsYSByZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgZGlmZXJlbmNpYWRhIGRlIGxhcyBhZ3J1cGFjaW9uZXMgY29uIGJhc2UgZW4gY8OzZGlnb3MgZGUgY29sb3Jlcy4NCg0KIyMjIDE0LjIuIERlc2Fycm9sbG8gZGVsIEFuw6FsaXNpcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpMYSBuYXZlZ2FjacOzbiBhIHRyYXbDqXMgZGUgbGFzIHBlc3Rhw7FhcyBwZXJtaXRlIHZpc3VhbGl6YXIgb2JqZXRvcyBtYXRyaWNpYWxlcyB5IGdyw6FmaWNvcyBxdWUgYXl1ZGFuIGEgZGVzYXJyb2xsYXIgZSBpbnRlcnByZXRhciBlbCBhbsOhbGlzaXMgZGUgY29uZ2xvbWVyYWRvcyBlbnRyZSBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGNvbmp1bnRvIGRlIGRhdG9zIGRlc2NyaXRvIGVuIGxhIFtzZWNjacOzbiAyXSgjc2VjMikuDQoNCkNvbW8gZWwgbcOpdG9kbyBkZSAqSyotbWVkaWFzIHJlcXVpZXJlIGxhIGVzcGVjaWZpY2FjacOzbiBkZWwgbsO6bWVybyBkZSBjb25nbG9tZXJhZG9zIHF1ZSBzZSBnZW5lcmFyw6FuLCByZXN1bHRhIGluZGlzcGVuc2FibGUgZGV0ZXJtaW5hcmxvIHByZXZpYW1lbnRlIHkgcXVlIGFkZW3DoXMgc2VhIGVsIG1lam9yIHBvc2libGUuIEEgdHJhdsOpcyBkZSBsYSBwZXN0YcOxYSAqKkstw7NwdGltb3MqKiBzZSBhY2NlZGUgYSBsYXMgc3ViLXBlc3Rhw7FhcyBkZSByZXN1bHRhZG8gZGUgbG9zIGPDoWxjdWxvcyBkZSBLLcOzcHRpbW9zIGNvbiBiYXNlIGVuIGxvcyBtw6l0b2RvcyBkZSBjb2RvICgqKkVsYm93KiopLCBzaWx1ZXRhICgqKlNpbGhvdWV0dGUqKiksIGJyZWNoYSAoKipHYXAqKikgeSBtYXlvcsOtYSAoKipNYWpvcml0eSBSdWxlKiopLiBFbCBwcmltZXJvLCBheXVkw7MgYSBlc3RhYmxlY2VyIHF1ZSBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgYWdydXBhbWllbnRvcyBxdWUgbWluaW1pemFuIGxhIHZhcmlhY2nDs24gdG90YWwgZGVudHJvIGRlIGNhZGEgdW5vIGRlIGxvcyBncnVwb3MgZXMgMy4gRWwgc2VndW5kbywgYSB0cmF2w6lzIGRlIGxhIGNhbGlkYWQgZGUgbG9zIGFncnVwYW1pZW50b3MgKHVuYSBzaWx1ZXRhIGFsdGEpLCBkZXRlcm1pbsOzIHF1ZSBlbCBuw7ptZXJvIMOzcHRpbW8gZGUgYWdydXBhbWllbnRvcyBlcyAyLiBFbCB0ZXJjZXJvLCBjb24gYmFzZSBlbiBsYSBlc3RpbWFjacOzbiBkZSBsb3MgY29uZ2xvbWVyYWRvcyDDs3B0aW1vcyBxdWUgaGFjZW4gcXVlIHNlIG1heGltaWNlIGxhIGVzdGFkw61zdGljYSBkZSBicmVjaGEgZGUgdGFsIG1hbmVyYSBxdWUgbGEgZXN0cnVjdHVyYSBkZSBhZ3J1cGFtaWVudG8gZXN0w6EgbXV5IGxlam9zIGRlIHVuYSBkaXN0cmlidWNpw7NuIGFsZWF0b3JpYSB1bmlmb3JtZSBkZSBwdW50b3MsIGVzdGFibGVjacOzIHF1ZSB0YWwgbsO6bWVybyDDs3B0aW1vIGZ1ZXNlIDEuIFBvciDDumx0aW1vLCBlbCBjdWFydG8gbcOpdG9kbywgcXVlIHNlIGJhc2EgZW4gZWwgY8OhbGN1bG8gZGUgMzAgw61uZGljZXMgcGFyYSBkZXRlcm1pbmFyIGVsIG7Dum1lcm8gw7NwdGltbyBkZSBjb25nbG9tZXJhZG9zIGFsIHZhcmlhciB0b2RhcyBsYXMgY29tYmluYWNpb25lcyBkZSBuw7ptZXJvIGRlIGNvbmdsb21lcmFkb3MsIG1lZGlkYXMgZGUgZGlzdGFuY2lhIHkgbcOpdG9kb3MgZGUgY29uZ2xvbWVyYWRvLCBkZXRlcm1pbsOzIHF1ZSB0YWwgbsO6bWVybyBlcyAyLiBQb3IgbG8gdGFudG8sIGxhIGNvbnRpbnVhY2nDs24gZGVsIGFuw6FsaXNpcyBkZSBjb25nbG9tZXJhZG9zIHNlIGNvbnRpbnXDsyBjb24gbGEgcmVwcmVzZW50YWNpw7NuIGdyw6FmaWNhIGRlIGxvcyBhZ3J1cGFtaWVudG9zIGJhc2Fkb3MgZW4gZG9zIHkgdHJlcyBjb25nbG9tZXJhZG9zLiBBc8OtLCBsYSBwZXN0YcOxYSAqKlJlc3VsdGFkb3MgSy1tZWFucyoqIG11ZXN0cmEgcGFyYSBuw7ptZXJvcyDDs3B0aW1vcyBkZSAzIHkgMiBhZ3J1cGFtaWVudG9zIGxhcyBjYW50aWRhZGVzIGRlIG9ic2VydmFjaW9uZXMsIGxhcyB1YmljYWNpb25lcyBkZSBsb3MgY2VudHJvaWRlcyBkZSBsb3MgY29uZ2xvbWVyYWRvcywgZWwgdmVjdG9yIGRlIGFncnVwYW1pZW50byB5IGxhIG1lZGlkYSBkZSBsYSBib25kYWQgZGUgbGEgY2xhc2lmaWNhY2nDs24gKGNvaGVzacOzbiBpbnRlcm5hIGNvbnRyYSBzZXBhcmFjacOzbiBleHRlcm5hKSwgcXVlLCBldmlkZW50ZW1lbnRlIGVzIG3DoXMgY2VyY2FuYSBhIHVubyBwYXJhIGVsIGFncnVwYW1pZW50byBjb24gYmFzZSBlbiAzIGNvbmdsb21lcmFkb3MuDQoNClBvciDDumx0aW1vLCBsYSBwZXN0YcOxYSAqKkdyw6FmaWNvcyBLLW1lYW5zKiogZXhoaWJlIGxvcyBjb25nbG9tZXJhZG9zIGVuIHTDqXJtaW5vcyBkZSAzIHkgMiAobsO6bWVybyDDs3B0aW1vKSBncnVwb3MgZW4gZWwgcHJpbWVyIHBsYW5vIGZhY3RvcmlhbCBxdWUgZXhwbGljYSBlbCAkODUuNCQgJFwlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZGUgbG9zIGRhdG9zLiBBbCBoYWNlciBsYSByZWFzaWduYWNpw7NuIGRlIDMgYSAyIGNlbnRyb2lkZXMgc2UgYXByZWNpYSBxdWUgZWwgY29uZ2xvbWVyYWRvIHF1ZSBjb250aWVuZSBhIENvbG9tYmlhIHNvbG8gYWJzb3JiZSBhIE1hbGFzaWEsIGVzIGRlY2lyIHNvbG8gYXVtZW50YSB1bmEgb2JzZXJ2YWNpw7NuLCBlbiBjb21wYXJhY2nDs24gY29uIGVsIGNvbmdsb21lcmFkbyBxdWUgY29udGVuw61hIGEgQ2hpbmEgcXVlIGFic29yYmUgYSB0b2RvIGVsIGNvbmdsb21lcmFkbyBxdWUgY29udGVuw61hIGEgVHVycXXDrWEuIEFzw60sIHB1ZWRlIGFyZ3VtZW50YXJzZSBhIGZhdm9yIGRlbCBuw7ptZXJvIMOzcHRpbW8gZGUgY29uZ2xvbWVyYWRvcyBpZ3VhbCBhIDIsIHBvcnF1ZSBsYSByZWFzaWduYWNpw7NuIGRlIGNlbnRyb2lkZXMgc2UgcmVvcmllbnTDsyBhIG1lam9yYXIgbGEgY29oZXNpw7NuIGludGVybmEgY29uIGJhamEgcmVkdWNjacOzbiBkZSBzZXBhcmFjacOzbiBleHRlcm5hIGVudHJlIGRvcyBjb25nbG9tZXJhZG9zIHF1ZSBwcmVzZW50YWJhbiBtw6FzIGhvbW9nZW5laWRhZC4gU2luIGVtYmFyZ28sIGxhcyBjb21wYXJhY2lvbmVzIGVudHJlIGxvcyBtw6l0b2RvcyB0cmF0YWRvcywgamVyw6FycXVpY29zIHkgbm8tamVyw6FycXVpY29zLCBnZW5lcmFyb24gZGlmZXJlbnRlcyBjYW50aWRhZGVzIGRlIGdydXBvcyDDs3B0aW1vcywgcGVybyBhbWJvcyBtw6l0b2RvcyBjb2luY2lkaWVyb24gZW4gcXVlLCBlbiBnZW5lcmFsLCBJbmRvbmVzaWEgeSBOZXBhbCBzb24gY2Fzb3MgcG9yIHRyYXRhciBjb24gbcOhcyBkZXRlbmltaWVudG8sIHBvciBlamVtcGxvLCBhIHRyYXbDqXMgZGUgbcOpdG9kb3MgcXVlIHNvcG9ydGVuIG1lam9yIGxhIGFmZWN0YWNpw7NuIHF1ZSBwcm92b2NhbiB2YWxvcmVzIGV4dHJhw7FvcywgcG9yIGVqZW1wbG8sIGVsIG3DqXRvZG8gZGUgSy1tZWRpb2lkZXMuIA0KDQojIyMjIEstw7NwdGltb3Mgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgRWxib3cNCmBgYHtyIFdTUywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X25iY2x1c3QoZGF0YV8sIGttZWFucywgbWV0aG9kID0gIndzcyIpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMywgbGluZXR5cGUgPSAyKQ0KYGBgDQoNCiMjIyMjIFNpbGhvdWV0dGUNCmBgYHtyIFNpbGhvdWV0dGUsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9uYmNsdXN0KGRhdGFfLCBrbWVhbnMsIG1ldGhvZCA9ICJzaWxob3VldHRlIikNCmBgYA0KDQojIyMjIyBHYXAgU3RhdGlzdGljDQpgYGB7ciBHQVBfU1RBVCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X25iY2x1c3QoZGF0YV8sIGttZWFucywgbWV0aG9kID0gImdhcF9zdGF0IikNCmBgYA0KDQojIyMjIyBNYWpvcml0eSBSdWxlDQpgYGB7ciBNYWpvcml0eV9SdWxlLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN1cHByZXNzV2FybmluZ3MoTmJDbHVzdChkYXRhID0gZGF0YV8sIGRpc3MgPSBOVUxMLCBkaXN0YW5jZSA9ICJldWNsaWRlYW4iLCBtaW4ubmMgPSAyLCBtYXgubmMgPSAxMCwgbWV0aG9kID0gImttZWFucyIpJEJlc3QubmMpDQpgYGANCg0KIyMjIyBSZXN1bHRhZG9zIEstbWVhbnMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgSy3Ds3B0aW1vIFt3d3NdDQpgYGB7ciBLX1dTUywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzZXQuc2VlZCg3ODA3MjgpDQpwcmludChrbWVhbnMoZGF0YV8sIDMsIG5zdGFydCA9IDI1KSkNCmBgYA0KDQojIyMjIyBLLcOzcHRpbW8gW3NpbF0NCmBgYHtyIEtfU2lsaG91ZXR0ZSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpzZXQuc2VlZCg3ODA3MjgpDQpwcmludChrbWVhbnMoZGF0YV8sIDIsIG5zdGFydCA9IDI1KSkNCmBgYA0KDQojIyMjIEdyw6FmaWNvcyBLLW1lYW5zIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIEstw7NwdGltbyBbd3dzXQ0KYGBge3IgR19XU1MsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZnZpel9jbHVzdGVyKGttZWFucyhkYXRhXywgMywgbnN0YXJ0ID0gMjUpLCBkYXRhID0gZGF0YV8sIHBhbGV0dGUgPSBjKCIjMkU5RkRGIiwgIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRTdCODAxIiksIGVsbGlwc2UudHlwZSA9ICJldWNsaWQiLCBzdGFyLnBsb3QgPSBUUlVFLCByZXBlbCA9IFRSVUUsIGdndGhlbWUgPSB0aGVtZV9taW5pbWFsKCkNCikNCmBgYA0KDQojIyMjIyBLLcOzcHRpbW8gW3NpbF0NCmBgYHtyIEdfU2lsaG91ZXR0ZSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpmdml6X2NsdXN0ZXIoa21lYW5zKGRhdGFfLCAyLCBuc3RhcnQgPSAyNSksIGRhdGEgPSBkYXRhXywgcGFsZXR0ZSA9IGMoIiMyRTlGREYiLCAiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNFN0I4MDEiKSwgZWxsaXBzZS50eXBlID0gImV1Y2xpZCIsIHN0YXIucGxvdCA9IFRSVUUsIHJlcGVsID0gVFJVRSwgZ2d0aGVtZSA9IHRoZW1lX21pbmltYWwoKQ0KKQ0KYGBgDQoNCiMjICoqQ29uY2x1c2lvbmVzKioNCkNvbXBsZW1lbnRhcmlhbWVudGUgYSBsb3MgYW7DoWxpc2lzIHF1ZSBmdWVyb24gZXhwdWVzdG9zIGVuIGxhcyBzZWNjaW9uZXMgZGUgZXN0dWRpbyBlcyBpbXBvcnRhbnRlIGhhY2VyIHVuYSBtZW5jacOzbiBnbG9iYWwgc29icmUgZWwgcHJvYmxlbWEgY29uc2lkZXJhZG8gYSBsYSBsdXogZGUgbG8gb2J0ZW5pZG8uDQoNCkNvbW8gc2UgbWVuY2lvbmEgZW4gZWwgdHJhYmFqbyBoZWNobyBlbiBlbCBjdXJzbyBBbsOhbGlzaXMgZGUgUmVncmVzacOzbiAocXVlIHB1ZWRlIHNlciBjb25zdWx0YWRvIHRlbXBvcmFsbWVudGUgYSB0cmF2w6lzIGRlOiBodHRwczovL3JwdWJzLmNvbS9nbGlicmVyb3NsL0FwcGxpZWQtU3RhdGlzdGljcy1GVUxMKSwgbGFzIGFzcGlyYWNpb25lcyBkZSB1biBlc3R1ZGlhbnRlIGV4dHJhbmplcm8gcGFyYSBpbmdyZXNhciBhIHVuYSB1bml2ZXJzaWRhZCBub3J0ZWFtZXJpY2FuYSBzZSBlbmZyZW50YW4gYSB1biBlbGV2YWRvIGdyYWRvIGRlIGNvbXBldGljacOzbi4gQWRlbcOhcywgc2UgY29uc3RhdGEsIGRlc2RlIGxhIHBlcnNwZWN0aXZhIGRlIGVzdHVkaW8gbXVsdGl2YXJpYWJsZSwgcXVlLCBwb3IgbG8gbWVub3MgZGVzY3JpcHRpdmFtZW50ZSwgdW5hIHZhcmlhYmxlIGNsYXNpZmljYWRvcmEgY2F0ZWfDs3JpY2EgY29tbyBlbCBzZXhvLCByZXN1bHRhIG11eSBwb2NvIHNpZ25pZmljYXRpdmEgZm9ybWFyIGdydXBvcyBkaWZlcmVuY2lhZG9zIGVudHJlIGxvcyBlc3R1ZGlhbnRlcyBjb24gYXNwaXJhY2lvbmVzIGRlIGluZ3Jlc28sIGFzdW50byBxdWUgY29udHJhc3RhIGNvbiBsb3MgcmVsYXRvcyBzb2Npby1wb3B1bGlzdGFzIGJhc2Fkb3MgZW4gZmFsYWNpYXMgX2FkIGhvbWluZW1fLiBFbCBkYXRvLCBzaSBlcyBmaW5vLCBzaWVtcHJlIHNlcsOhIG9iamV0aXZvLg0KDQpDb21wbGVtZW50YXJpYW1lbnRlLCB0b2RhcyBsYXMgcHJ1ZWJhcyBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFudGUgcmVzdWx0YXJvbiBuZWdhdGl2YXMsIHNhbHZvIHF1ZSBhIG5pdmVsIHVuaXZhcmlhZG8gbGEgdmFyaWFibGUgKipDR1BBKiogcHJlc2VudMOzIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIGVuIHRvZGFzIGVsbGFzLiBBc8OtLCBlbCBkZXRlcmlvcm8gZGUgbGFzIHByb3BpZWRhZGVzIGRlIGluZGVwZW5kZW5jaWEgbGluZWFsIGp1ZWdhbiBhIGZhdm9yIGRlIGxhIHPDrW50ZXNpcyBkZSBpbmZvcm1hY2nDs24gYSB0cmF2w6lzIGRlIGxhIGVzdGltYWNpw7NuIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzLiBFc3RlIHB1ZG8gZGVzY3JpYmlyIHVuYSAqKm1lZGlkYSBkZSBjb21wZXRpdGl2aWRhZCBmb3JtYXRpdmEqKiBxdWUgY29uanVnYSwgY29uIHVuYSByZXRlbmNpw7NuIGRlICQ3Ny4wNSQgJFwlJCBsYSB2YXJpYWJpbGlkYWQgZGVsIGNvbmp1bnRvIGRlIGRhdG9zLCBsYSBuYXR1cmFsZXphIGludGVycHJldGF0aXZhIGRlbCBmZW7Ds21lbm8gZXN0dWRpYWRvLiBBc8OtLCBjdWFudG8gbWF5b3Igc2VhIGVsIHZhbG9yIGRlIGxhcyB2YXJpYWJsZXMgcXVlIHJlZ2lzdHJhIHVuIGVzdHVkaWFudGUgcGFyYSBhcGxpY2FyIGEgdW5hIHBsYXphIGVuIHVuYSB1bml2ZXJzaWRhZCBkZSBzdSBlbGVjY2nDs24sIG1heW9yIHNlcsOhIGVsIGVzdGFkbyBkZSBmYXZvcmFiaWxpZGFkIGRlIHF1ZSBlbCBlc3R1ZGlhbnRlIHNlYSBhZG1pdGlkbyBwb3IgbGEgdW5pdmVyc2lkYWQgZGUgc3UgcHJlZmVyZW5jaWEuDQoNCkFzaW1pc21vLCBlbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcywgc2ltcGxlIHkgbcO6bHRpcGxlLCBtb3N0csOzIHF1ZSBsYXMgdW5pdmVyc2lkYWRlcyBkZSBtZWpvciBjYWxpZmljYWNpw7NuLCBlbiBwYXJ0aWN1bGFyLCBsYXMgZGUgdHJlcyB5IGN1YXRybyBlc3RyZWxsYXMgdGllbmRlbiBhIGNhcHRhciBhIGxvcyBlc3R1ZGlhbnRlcyBkZSBtZWpvciAqKm1lZGlkYSBkZSBjb21wZXRpdGl2aWRhZCBmb3JtYXRpdmEqKiwgYWxnbyBlc3BlcmFkbyBkYWRhIGxhIG5hdHVyYWxlemEgZGVsIGZlbsOzbWVubyBlc3R1ZGlhZG8uIEFkZW3DoXMsIGxhIHZhcmlhYmxlIGNhdGVnw7NyaWNhICoqUmVzZWFyY2gqKiBqdWVnYSB1biBwYXBlbCBkZXRlcm1pbmFudGUgZW4gbGEgc2VsZWN0aXZpZGFkLCBtaWVudHJhcyBxdWUgbGEgdmFyYWlibGUgKipHZW5kZXIqKiBlcyBpbmRldGVybWluYW50ZSBlc3RhZMOtc3RpY2FtZW50ZSBwYXJhIGF1bWVudGFyIGxhcyBwcm9iYWJpbGlkYWRlcyBkZSBpbmdyZXNvIGRlIHVuIGVzdHVkaWFudGUgYSB1bmEgdW5pdmVyc2lkYWQgZGUgc3UgcHJlZmVyZW5jaWEuDQoNCkFkaWNpb25hbG1lbnRlLCBlbCBhbsOhbGlzaXMgZGUgY29uZ2xvbWVyYWRvcyBtdWVzdHLDsyBxdWUgZWZlY3RpdmFtZW50ZSBleGlzdMOtYW4gZW4gZWwgY29uanVudG8gZGUgZGF0b3MgcmVnaXN0cm9zIHNpZ25pZmljYXRpdmFtZW50ZSBob21vZ8OpbmVvcyBlbnRyZSBzw60geSBhIHN1IHZleiBzZSBwYXJhZG9zIGRlIG90cm9zLiBFbiBlc3RlIHNlbnRpZG8sIGxvcyBtw6l0b2RvcyBkZSBhZ2xvbWVyYWNpw7NuIGplcsOhcnF1aWNvcyB5IG5vLWplcsOhcnF1aWNvcyBheXVkYXJvbiBhIGNvbXByZW5kZXIgY8OzbW8gZXN0YWJhbiBkaXNwdWVzdG9zIGVzb3MgZ3J1cG9zIHkgbG9zIHZhbG9yZXMgZXh0cmHDsW9zIHBvciByZWV2YWx1YXIuIEFzw60sIGVzIHJlbGV2YW50ZSBsYSBzZW1lamFuemEgZGUgcGVyZmlsZXMgZGUgZXN0dWRpYW50ZXMgcXVlIHBvciBuYWNpb25hbGlkYWQgYWJhcmNhbiBlbCBjZXJjYW5vLCBtZWRpbyB5IGxlamFubyBvcmllbnRlIGFsIGNvbmZvcm1hciB1biBjb25nbG9tZXJhZG8gZGUgYWx0YSBtYXNhLCBhdW5xdWUgbGFzIG5hY2lvbmFsaWRhZGVzIGRlIEphcMOzbiwgSW5kb25lc2lhIHkgTmVwYWwgdG9tZW4gZGlzdGFuY2lhIGRlIHN1IGNlbnRyb2lkZSwgdGFsZXMgcXVlIHB1ZGllc2VuIGNvbmZvcm1hciBqZXLDoXJxdWljYW1lbnRlIGNvbmdsb21lcmFkb3MgcG9yIHPDrSBtaXNtb3MuIFBvciBvdHJvIGxhZG8sIGVsIGNvbmdsb21lcmFkbyBhbCBjdWFsIHBlcnRlbmVjZSBDb2xvbWJpYSBwb2Ryw61hIGludGVycHJldGFyc2UgY29tbyB1bm8gcXVlIHJlY29nZSBlc3R1ZGlhbnRlcyBtdXkgY29tcHJvbWV0aWRvcyBjb24gc3UgZm9ybWFjacOzbiwgZGFkbyBxdWUgc29uIHJlY29ub2NpZGFzIGxhcyBkaWZlcmVuY2lhcyBkZSBsb3Mgc2lzdGVtYXMgZWR1Y2F0aXZvcyBlbiB2aWdvciBlbiBsYXMgbmFjaW9uYWxpZGFkZXMgcXVlIGxvIGNvbmZvcm1hbi4NCg0KUG9yIMO6bHRpbW8sIGVzIGltcG9ydGFudGUgcmVzYWx0YXIgZWwgYXNwZWN0byB0w6ljbmljbyByZWxhY2lvbmFkbyBjb24gZWwgcHJvY2VzYW1pZW50byBlc3RhZMOtc3RpY28gaGVjaG8gZW4gZXN0ZSBlc3R1ZGlvIGEgbml2ZWwgZGUgcm9idXN0ZXosIGVmaWNpZW5jaWEgZSBpbnRlZ3JhY2nDs24gcXVlIFIsIFJTdHVkaW8geSBSTWFya2Rvd24gb2ZyZWNlbiBhbCB1c3VhcmlvIHBhcmEgcXVlIGVzdGUgc2UgcHVlZGEgZW5mb2NhciBlbiDDqWwgc2luIHBhc2FyIG1heW9yZXMgaW5jb252ZW5pZW50ZXMgY29uIGVsIHNvcG9ydGUgZG9jdW1lbnRhbCBwYXJhIHByZXNlbnRhcmxvLg0KDQojIyAqKlJlZmVyZW5jaWFzKio=