Fase 1 [Descripciones Multivariantes]

En la primera etapa del estudio, se llevarán a cabo cálculos, visualizaciones y un análisis detallado del conjunto de datos sobre videojuegos, que será descrito en la sección 1.2. Este proceso se abordará desde una perspectiva de estadística descriptiva multivariante, lo que permitirá no solo una visión general de los datos, sino también un análisis más enriquecido de las relaciones entre las diferentes variables involucradas, tales como género, plataforma, año de lanzamiento, ventas globales por región y puntuaciones de usuarios y críticos.

Este enfoque facilitará una comprensión más profunda de las relaciones entre las variables, ayudando a identificar patrones y tendencias relevantes en la industria de los videojuegos. Las visualizaciones jugarán un papel clave en la representación gráfica de estas relaciones, brindando una forma clara y accesible de explorar los datos y facilitar su comprensión. Todo esto se llevará a cabo utilizando las herramientas R y RStudio, que permitirán una ejecución eficiente y precisa de los cálculos y la creación de gráficos interactivos para una interpretación más completa de los resultados.

1.1. Objetivos

El objetivo de este proyecto es aplicar técnicas de análisis multivariado para gestionar el conjunto de datos aprobado, correspondiente a registros de videojuegos que incluyen información sobre títulos, géneros, plataformas, años de lanzamiento, ventas globales y puntuaciones de usuarios. El propósito es organizar y procesar eficazmente la información, desarrollando habilidades en la gestión y análisis de datos mediante la implementación de métodos estadísticos avanzados como análisis de componentes principales, correspondencias, conglomerados y regresión. Este trabajo se enmarca dentro del curso de Gestión de Datos, dictado por el Profesor Giancarlo Libreros Londoño en la Universidad del Valle.

1.2. Descripción de los datos

El conjunto de datos fue obtenido en su totalidad desde la plataforma Kaggle:(https://www.kaggle.com/datasets/isaacmenard/playstation-games-info-2152025).Kaggle, es una plataforma en línea especializada en ciencia de datos y aprendizaje automático, propiedad de Google LLC. Se destaca por facilitar la participación en competencias en las que empresas e instituciones publican conjuntos de datos y problemas reales, permitiendo a los usuarios desarrollar modelos predictivos y poner a prueba sus habilidades analíticas. Además, la plataforma proporciona herramientas como notebooks interactivos en Python y R, una amplia biblioteca de conjuntos de datos de libre acceso y una sección educativa denominada Kaggle Learn, dedicada a la formación en programación, análisis y visualización de datos. El conjunto de datos seleccionado, fue elaborado por Isaac Menard (https://www.kaggle.com/isaacmenard), que recopila información detallada sobre diversos videojuegos de PlayStation.

En el contexto del analisis de conjuntos de datos, este estudio se relaciona con las siguientes areas de la ingenieria industrial. En el area 2. Investigación de Operaciones y Análisis,(Operations research & analysis) devido a que los datos de ventas y calificaciones sirven para aplicar modelos matemáticos orientados a la toma de decisiones estratégicas en la industria del entretenimiento digital; en el area 3. Análisis Económico de la Ingeniería,(Enginnering economic analysis) porque se consideran aspectos financieros mediante variables como el precio de venta o el modelo de negocio; en el area 13. Diseño y Desarrollo de Productos(Desing & manufacturing engineering), porque el estudio de variables como el género y la plataforma permite identificar tendencias de innovación y evolución en los videojuegos, reflejando la influencia de las preferencias de los usuarios y los avances tecnológicos en su diseño y mejora continua.

El conjunto de datos está compuesto por 12 campos y 3,526 registros que recopilan información sobre videojuegos de la marca PlayStation. Incluye variables relacionadas con el título, desarrollador, plataforma, género, precio, ventas y calificaciones, lo que permite analizar aspectos técnicos, comerciales y de preferencia del consumidor dentro de la industria del entretenimiento digital. La lista siguiente presenta las variables del conjunto de datos en el mismo orden en que aparecen en el archivo original, indicando para cada una su tipo de variable y escala de medición, siguiendo la nomenclatura (tipo_de_variable::escala_de_medición [ordenamiento]):

  • nombre_juego (cualitativa::nominal): es la denominación oficial del videojuego registrada en la PlayStation Store. Esta variable identifica de manera única cada título y se presenta en formato de texto, respetando la ortografía y estilo original establecido por la distribuidora.

  • precio_mas_alto (cuantitativa::razón): indica el Valor monetario máximo alcanzado por el videojuego dentro de la PlayStation Store, expresado en euros (€).

  • lanzamiento (cuantitativa::intervalo): indica la fecha o año correspondiente al estreno oficial del videojuego en el mercado. Esta variable permite establecer comparaciones temporales y analizar tendencias de lanzamiento a lo largo del tiempo.

  • genero (cualitativa::nominal):es la clasificación temática o tipológica del videojuego según su dinámica y estilo de juego (acción, aventura, rol, deportes, entre otros). Facilita la segmentación y el análisis comparativo entre distintos tipos de experiencias interactivas.

  • empresa_creadora (cualitativa::nominal): registra el nombre de la compañía desarrolladora o distribuidora responsable de la producción del videojuego. Esta variable permite identificar el origen empresarial y analizar la participación de distintas marcas dentro del mercado de PlayStation.

  • plataforma (cualitativa::nominal): señala el sistema o consola de la línea PlayStation en la cual fue lanzado el videojuego (ps3, ps4 o ps5). Su inclusión posibilita el estudio de la compatibilidad, la evolución tecnológica y las diferencias generacionales entre consolas.

  • metacritic_score (cuantitativa::razón):representa la puntuacion promedio ponderado de las calificaciones otorgadas por críticos especializados en el videojuego, en una escala de 0 a 100.

  • metacritic_rating_count (cuantitativa::razón): muestra el número total de reseñas profesionales recopiladas por Metacritic. Refleja el nivel de cobertura mediática y el grado de atención recibida por parte de la prensa especializada.

  • metacritic_user_score (cuantitativa::razón): registra el promedio de las valoraciones emitidas por los usuarios en la plataforma Metacritic, expresado en una escala de 0 a 10. Este indicador representa la percepción y satisfacción general del público.

  • Metacritic_user_rating_count (Cuantitativa::razón): indica el número de valoraciones emitidas por los usuarios. Mide la participación y popularidad del juego.

  • playstation_score (cuantitativa::razón): muestra la valoracion promedio de las puntuaciones otorgadas por los usuarios en la PlayStation Store, en una escala de 0 a 5. Constituye una medida directa de la valoración interna dentro de la plataforma oficial de Sony.

  • playstation_rating_count (cuantitativa::razón): refleja la cantidad total de reseñas o calificaciones emitidas por los usuarios en la PlayStation Store. Indica el nivel de interacción, aceptación y visibilidad del videojuego dentro del entorno digital de la consola.

Cabe resaltar que durante el proceso de depuración del conjunto de datos de reseñas de videojuegos se realizaron ajustes orientados a garantizar la coherencia y aprovechamiento máximo de la información disponible. En primer lugar, se eliminaron registros con datos en blanco cuando la ausencia de información afectaba variables clave, y en otros casos se procedió a completar valores faltantes mediante criterios consistentes con el comportamiento del resto de la muestra, con el fin de no reducir innecesariamente el tamaño del dataset. Además, la variable fecha_lanzamiento se estandarizó pasando de formatos como “Feb 15, 2012” a un formato de fecha homogéneo tipo “15/02/2012”, lo que facilita el ordenamiento cronológico y el uso de funciones de tiempo en el análisis. Adicionalmente, se corrigieron algunos valores atípicamente elevados en la variable Precio_mas_alto, revisando su magnitud y ajustándolos a rangos más realistas para evitar distorsiones en los análisis posteriores. Finalmente, se incorporó una variable de decisión que clasifica a los videojuegos según el nivel de participación o exposición publicitaria, lo cual permite estudiar de manera más precisa cómo la visibilidad comercial se relaciona con las puntuaciones de críticos, usuarios y el desempeño dentro de la PlayStation Store.

Estructura del conjunto de Datos Original

str(resenas_juegos_electronicos)
## tibble [3,526 × 12] (S3: tbl_df/tbl/data.frame)
##  $ nombre_juego                : chr [1:3526] "Grand Theft Auto IV" "Red Dead Redemption 2" "Red Dead Online" "Grand Theft Auto 3" ...
##  $ precio_mas_alto             : chr [1:3526] "€24.99" "€59.99" "€69.99" "€9.99" ...
##  $ lanzamiento                 : chr [1:3526] "Feb 15, 2012" "Oct 26, 2018" "Oct 29, 2018" "Oct 4, 2012" ...
##  $ genero                      : chr [1:3526] "Action / Shooter / Racing" "Action / Adventure / Unique" "Action / Adventure" "--" ...
##  $ empresa_creadora            : chr [1:3526] "Rockstar" "Rockstar Games" "Rockstar Games" "Rockstar Games" ...
##  $ plataforma                  : chr [1:3526] "PS3" "PS4" "PS4" "PS3" ...
##  $ metacritic_score            : num [1:3526] 98 97 97 97 97 97 96 96 96 96 ...
##  $ metacritic_rating_count     : num [1:3526] 86 99 99 56 66 66 112 86 105 98 ...
##  $ metacritic_user_score       : num [1:3526] 8.3 8.9 8.9 8 8.5 8.5 9.2 8.3 8.9 8.9 ...
##  $ metacritic_user_rating_count: num [1:3526] 5541 31932 31932 2079 14322 ...
##  $ playstation_score           : chr [1:3526] "4.32" "4.74" "4.74" "4.59" ...
##  $ playstation_rating_count    : num [1:3526] 48904 379257 379346 1437 40895 ...

Conjunto de Datos Original

resenas_juegos_electronicos
## # A tibble: 3,526 × 12
##    nombre_juego   precio_mas_alto lanzamiento genero empresa_creadora plataforma
##    <chr>          <chr>           <chr>       <chr>  <chr>            <chr>     
##  1 Grand Theft A… €24.99          Feb 15, 20… Actio… Rockstar         PS3       
##  2 Red Dead Rede… €59.99          Oct 26, 20… Actio… Rockstar Games   PS4       
##  3 Red Dead Onli… €69.99          Oct 29, 20… Actio… Rockstar Games   PS4       
##  4 Grand Theft A… €9.99           Oct 4, 2012 --     Rockstar Games   PS3       
##  5 Grand Theft A… €69.99          Sep 17, 20… Actio… Rockstar Games   PS3       
##  6 Grand Theft A… €69.99          Nov 18, 20… Actio… Rockstar Games   PS4       
##  7 Baldur's Gate… €69.99          Sep 6, 2023 Role … Larian Studios … PS5 / PS4 
##  8 ELDEN RING PS… €69.99          Feb 25, 20… Role … BANDAI NAMCO EN… PS5 / PS4 
##  9 Uncharted 2: … <NA>            Oct 15, 20… --     Sony Interactiv… PS3       
## 10 Mass Effect™ 2 €14.99          Jan 21, 20… Role … EA Swiss Sarl    PS3       
## # ℹ 3,516 more rows
## # ℹ 6 more variables: metacritic_score <dbl>, metacritic_rating_count <dbl>,
## #   metacritic_user_score <dbl>, metacritic_user_rating_count <dbl>,
## #   playstation_score <chr>, playstation_rating_count <dbl>

Estructura del conjunto de Datos ETL

str(resenas_de_juegos_electronicos_depurados)
## tibble [3,457 × 14] (S3: tbl_df/tbl/data.frame)
##  $ nombre_juego           : chr [1:3457] "Grand Theft Auto IV" "Red Dead Redemption 2" "Red Dead Online" "Grand Theft Auto 3" ...
##  $ Precio_mas_alto        : num [1:3457] 24.99 59.99 69.99 9.99 69.99 ...
##  $ fecha_lanzamiento      : Date[1:3457], format: "2012-02-15" "2018-10-26" ...
##  $ genero_juego           : chr [1:3457] "Action / Shooter / Racing" "Action / Adventure / Unique" "Action / Adventure" "Action/Adventure" ...
##  $ empresa_creadora       : chr [1:3457] "Rockstar" "Rockstar Games" "Rockstar Games" "Rockstar Games" ...
##  $ plataforma_ps          : chr [1:3457] "PS3" "PS4" "PS4" "PS3" ...
##  $ punt_criticos_meta     : num [1:3457] 98 97 97 97 97 97 96 96 96 96 ...
##  $ n_criticos_meta        : num [1:3457] 86 99 99 56 66 66 112 86 115 98 ...
##  $ punt_usuarios_meta     : num [1:3457] 8.3 8.9 8.9 8 8.5 8.5 9.2 8.3 8.9 8.9 ...
##  $ n_usuarios_meta        : num [1:3457] 5541 31932 31932 2179 14322 ...
##  $ calif_ps_store         : num [1:3457] 4.32 4.74 4.74 4.59 4.65 4.48 1 1 4.14 4.81 ...
##  $ n_total_store          : num [1:3457] 48914 379257 379346 1437 41895 ...
##  $ participacion_publi_cat: num [1:3457] 2 2 2 1 2 2 2 2 2 1 ...
##  $ alto                   : num [1:3457] 24.99 59.99 69.99 9.99 69.99 ...

Conjunto de Datos Original Depurado

resenas_de_juegos_electronicos_depurados
## # A tibble: 3,457 × 14
##    nombre_juego  Precio_mas_alto fecha_lanzamiento genero_juego empresa_creadora
##    <chr>                   <dbl> <date>            <chr>        <chr>           
##  1 Grand Theft …           25.0  2012-02-15        Action / Sh… Rockstar        
##  2 Red Dead Red…           60.0  2018-10-26        Action / Ad… Rockstar Games  
##  3 Red Dead Onl…           70.0  2018-10-29        Action / Ad… Rockstar Games  
##  4 Grand Theft …            9.99 2012-10-04        Action/Adve… Rockstar Games  
##  5 Grand Theft …           70.0  2013-09-17        Action / Ad… Rockstar Games  
##  6 Grand Theft …           70.0  2014-11-18        Action / Ad… Rockstar Games  
##  7 Baldur's Gat…           70.0  2023-09-06        Role playin… Larian Studios …
##  8 ELDEN RING P…           70.0  2022-02-25        Role playin… BANDAI NAMCO EN…
##  9 Uncharted 2:…           40.0  2009-10-15        Action/Adve… Sony Interactiv…
## 10 Mass Effect™…           65.0  2011-01-21        Action/Role… EA Swiss Sarl   
## # ℹ 3,447 more rows
## # ℹ 9 more variables: plataforma_ps <chr>, punt_criticos_meta <dbl>,
## #   n_criticos_meta <dbl>, punt_usuarios_meta <dbl>, n_usuarios_meta <dbl>,
## #   calif_ps_store <dbl>, n_total_store <dbl>, participacion_publi_cat <dbl>,
## #   alto <dbl>

El conjunto original resenas_juegos_electronicos_Original contiene 3.526 videojuegos y 12 variables, con precios y fechas almacenados como texto y algunos registros con información incompleta. Representa la base tal como fue obtenida de las fuentes, útil para describir el origen y la estructura inicial de los datos antes de cualquier tratamiento.

El conjunto depurado resenas_de_juegos_electronicos_depurados reduce a 3.457 registros y amplía a 13 variables, luego de eliminar observaciones con datos críticos en blanco, convertir el precio máximo a numérico (alto), estandarizar la fecha de lanzamiento y crear la variable part_publi sobre participación publicitaria. Esta versión ofrece una matriz de datos más limpia y homogénea, adecuada para las descripciones multivariantes y los análisis estadísticos aplicados al mercado de videojuegos.

1.3. Estimaciones multivariadas

El vector de medias y la matriz de varianzas-covarianzas son elementos fundamentales del análisis estadístico multivariado, pues permiten caracterizar el comportamiento central, la dispersión y las relaciones de dependencia entre las variables de un conjunto de datos. Estas herramientas facilitan la comprensión global de la estructura interna de la información analizada. El vector de medias resume el promedio o valor esperado de cada variable, representando el punto de equilibrio alrededor del cual se distribuyen los datos. Por otro lado, la matriz de varianzas-covarianzas proporciona una medida conjunta de la variabilidad y de las relaciones lineales entre las variables. En su diagonal principal se encuentran las varianzas, que reflejan la dispersión individual de cada variable, mientras que los elementos fuera de la diagonal expresan las covarianzas, es decir, el grado en que dos variables tienden a variar simultáneamente.

Vector de Medias y Boxplots

El siguiente conjunto de boxplots resume la distribución de cuatro variables cuantitativas clave del mercado de videojuegos analizado: el Precio_mas_alto registrado en la PS Store, la puntuación de críticos en Metacritic (punt_criticos_meta), el número de críticas de Metacritic (n_criticos_meta) y la puntuación de usuarios (punt_usuarios_meta). El gráfico de cajas es especialmente adecuado en esta fase exploratoria porque sintetiza en una sola figura la mediana, el rango intercuartílico y los valores atípicos de cada variable, permitiendo comparar de forma visual la dispersión, la simetría y la presencia de outliers entre indicadores que están en escalas diferentes. De esta manera, se obtiene una visión compacta del comportamiento central de los precios y de las evaluaciones críticas y de usuarios, lo que facilita detectar variables muy heterogéneas o con concentraciones extremas de valores antes de aplicar técnicas analíticas más avanzadas.

apply(resenas_de_juegos_electronicos_depurados[,-c(1,3,4,5,6,9,10,11,12,13)], 2, mean, na.rm = TRUE) 
##    Precio_mas_alto punt_criticos_meta    n_criticos_meta               alto 
##          29.802898          20.282904           9.257159          29.802898
resenas_juegos_electronicos_reducido = resenas_de_juegos_electronicos_depurados[,-c(1,3,4,5,6,9,10,11,12,13)]
nombres_boxplots <- c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta")

par(mfrow = c(1, ncol(resenas_juegos_electronicos_reducido)))
invisible(lapply(1:ncol(resenas_juegos_electronicos_reducido), function(i) {
  boxplot(resenas_juegos_electronicos_reducido[[i]],
    main = nombres_boxplots[i],
    ylim = quantile(resenas_juegos_electronicos_reducido[[i]], c(0.02, 0.99), na.rm = TRUE),
    na.rm = TRUE)}))

En el boxplot de Precio_mas_alto se observa que la mediana del precio de los juegos se sitúa alrededor de un rango intermedio, mientras que el rango intercuartílico es relativamente estrecho, indicando que la mayoría de títulos se concentran en un intervalo de precios bastante homogéneo; sin embargo, la presencia de algunos valores atípicos hacia la parte alta revela juegos premium con precios sensiblemente superiores al resto, que representan ofertas de gama alta dentro del catálogo. En el caso de punt_criticos_meta y punt_usuarios_meta, las cajas se ubican mayoritariamente en rangos altos de la escala de puntuación, lo que sugiere que el conjunto de juegos reseñados presenta, en general, una calidad percibida buena o muy buena tanto para la crítica profesional como para los usuarios, aunque se aprecia cierta dispersión y algunos outliers que corresponden a títulos excepcionalmente valorados o, en menor medida, peor evaluados. Finalmente, el boxplot de n_criticos_meta muestra una gran asimetría y una concentración de valores bajos con una cola larga hacia la derecha, lo que indica que muchos juegos cuentan con pocas reseñas de críticos mientras que un grupo reducido acumula un número muy elevado de críticas, reflejando una visibilidad desigual donde unos pocos títulos concentran la atención mediática del mercado.

Vector de Medias y Boxplots 2.

El conjunto de boxplots mostrado resume la distribución de tres variables relacionadas con la participación de los usuarios en las reseñas: el número de reseñas de usuarios en Metacritic (n_usuarios_meta), la calificación media en la PlayStation Store (calif_ps_store) y el número total de valoraciones en la tienda (n_total_store). El gráfico de cajas es especialmente adecuado para estos indicadores porque permite comparar, en una misma figura, la tendencia central (mediana), la dispersión (rango intercuartílico) y la presencia de valores atípicos, revelando de manera sintética si la interacción de los jugadores con cada título está concentrada en unos pocos niveles o si, por el contrario, existe una gran heterogeneidad en el volumen de reseñas y en las puntuaciones asignadas.

apply(resenas_de_juegos_electronicos_depurados[,-c(1,2,3,4,5,6,7,8,9,13)], 2, mean, na.rm = TRUE) 
## n_usuarios_meta  calif_ps_store   n_total_store            alto 
##       270.29534         3.43149      5470.31386        29.80290
resenas_juegos_electronicos_reducido = resenas_de_juegos_electronicos_depurados[,-c(1,2,3,4,5,6,7,8,9,13)]
nombres_boxplots <- c("n_usuarios_meta","calif_ps_store","n_total_store")

par(mfrow = c(1, ncol(resenas_juegos_electronicos_reducido)))
invisible(lapply(1:ncol(resenas_juegos_electronicos_reducido), function(i) {
  boxplot(resenas_juegos_electronicos_reducido[[i]],
    main = nombres_boxplots[i],
    ylim = quantile(resenas_juegos_electronicos_reducido[[i]], c(0.02, 0.99), na.rm = TRUE),
    na.rm = TRUE)}))

En el boxplot de n_usuarios_meta se aprecia una distribución fuertemente asimétrica: la mayoría de juegos acumula un número relativamente bajo de reseñas de usuarios, mientras que una pequeña fracción presenta valores extremadamente altos, visibles como una larga cola de outliers hacia la parte superior. Esto indica que sólo ciertos títulos alcanzan un nivel de notoriedad suficiente como para generar miles de opiniones, concentrando buena parte de la conversación de la comunidad. En contraste, el boxplot de calif_ps_store muestra una caja estrecha y situada en valores altos

Matriz de Varianzas-Covarianzas

La siguiente tabla presenta la matriz de varianzas y covarianzas de las principales variables cuantitativas del estudio: Precio_mas_alto, punt_criticos_meta, n_criticos_meta, punt_usuarios_meta, n_usuarios_meta, calif_ps_store, n_total_store y alto (precio reescalado). La diagonal recoge las varianzas de cada variable, que miden su dispersión respecto a la media, mientras que los elementos fuera de la diagonal representan las covarianzas entre pares de variables, es decir, cómo tienden a variar conjuntamente en el mercado de videojuegos analizado. Esta matriz es un insumo fundamental en análisis multivariados, ya que resume la estructura de dependencia entre precio, puntuaciones y niveles de participación de usuarios y críticos, y sirve de base para técnicas posteriores como componentes principales, pruebas de normalidad multivariada y detección de outliers.

round(cov(resenas_de_juegos_electronicos_depurados[,-c(1,3,4,5,6,13)]),2)
##                    Precio_mas_alto punt_criticos_meta n_criticos_meta
## Precio_mas_alto             323.88              27.20           64.35
## punt_criticos_meta           27.20            1126.42          506.25
## n_criticos_meta              64.35             506.25          415.05
## punt_usuarios_meta            2.74              85.13           41.61
## n_usuarios_meta            5444.91           18776.60        21620.69
## calif_ps_store               -3.41              -0.21            0.67
## n_total_store             89034.89           71242.60        99376.00
## alto                        323.88              27.20           64.35
##                    punt_usuarios_meta n_usuarios_meta calif_ps_store
## Precio_mas_alto                  2.74         5444.91          -3.41
## punt_criticos_meta              85.13        18776.60          -0.21
## n_criticos_meta                 41.61        21620.69           0.67
## punt_usuarios_meta               7.38         1418.71           0.12
## n_usuarios_meta               1418.71     10194373.38         104.52
## calif_ps_store                   0.12          104.52           2.39
## n_total_store                 6083.61     27618456.67        5451.33
## alto                             2.74         5444.91          -3.41
##                    n_total_store     alto
## Precio_mas_alto         89034.89   323.88
## punt_criticos_meta      71242.60    27.20
## n_criticos_meta         99376.00    64.35
## punt_usuarios_meta       6083.61     2.74
## n_usuarios_meta      27618456.67  5444.91
## calif_ps_store           5451.33    -3.41
## n_total_store       715143353.92 89034.89
## alto                    89034.89   323.88

Las varianzas muestran que n_usuarios_meta y n_total_store presentan una dispersión extremadamente elevada frente al resto de variables, lo que confirma que el volumen de reseñas de usuarios y de valoraciones en la tienda está muy concentrado en unos pocos títulos con altísima visibilidad, mientras que la mayoría de juegos recibe un número relativamente bajo de interacciones. Las covarianzas positivas entre Precio_mas_alto y las medidas de participación (n_usuarios_meta y n_total_store) sugieren que los juegos con precios más altos tienden a estar asociados a productos con mayor exposición y más reseñados, aunque esta relación deberá evaluarse con medidas estandarizadas como las correlaciones. Asimismo, las covarianzas elevadas entre punt_criticos_meta, punt_usuarios_meta y calif_ps_store indican que las distintas métricas de calidad percibida se mueven en la misma dirección, lo que respalda la idea de coherencia entre la valoración de la crítica, la opinión de los usuarios y la calificación agregada en la PS Store para los videojuegos del conjunto de datos.

Matriz de Correlaciones

La siguiente matriz de correlaciones muestra la intensidad y dirección de la relación lineal entre las variables cuantitativas del estudio (Precio_mas_alto, punt_criticos_meta, n_criticos_meta, punt_usuarios_meta, n_usuarios_meta, calif_ps_store, n_total_store y alto). Cada coeficiente toma valores entre -1 y 1, donde valores cercanos a 1 indican asociación positiva fuerte, valores cercanos a -1 asociación negativa fuerte y valores próximos a 0 ausencia de relación lineal apreciable.

round(cor(resenas_de_juegos_electronicos_depurados[,-c(1,3,4,5,6,13)]),3)
##                    Precio_mas_alto punt_criticos_meta n_criticos_meta
## Precio_mas_alto              1.000              0.045           0.176
## punt_criticos_meta           0.045              1.000           0.740
## n_criticos_meta              0.176              0.740           1.000
## punt_usuarios_meta           0.056              0.933           0.752
## n_usuarios_meta              0.095              0.175           0.332
## calif_ps_store              -0.123             -0.004           0.021
## n_total_store                0.185              0.079           0.182
## alto                         1.000              0.045           0.176
##                    punt_usuarios_meta n_usuarios_meta calif_ps_store
## Precio_mas_alto                 0.056           0.095         -0.123
## punt_criticos_meta              0.933           0.175         -0.004
## n_criticos_meta                 0.752           0.332          0.021
## punt_usuarios_meta              1.000           0.164          0.030
## n_usuarios_meta                 0.164           1.000          0.021
## calif_ps_store                  0.030           0.021          1.000
## n_total_store                   0.084           0.323          0.132
## alto                            0.056           0.095         -0.123
##                    n_total_store   alto
## Precio_mas_alto            0.185  1.000
## punt_criticos_meta         0.079  0.045
## n_criticos_meta            0.182  0.176
## punt_usuarios_meta         0.084  0.056
## n_usuarios_meta            0.323  0.095
## calif_ps_store             0.132 -0.123
## n_total_store              1.000  0.185
## alto                       0.185  1.000

Se observa una correlación muy alta entre punt_criticos_meta y punt_usuarios_meta, así como entre estas puntuaciones y el número de críticas (n_criticos_meta), lo que indica que los juegos mejor valorados tienden también a recibir más reseñas y a ser bien evaluados por ambos grupos. Por el contrario, el Precio_mas_alto y la calif_ps_store presentan correlaciones bajas o incluso ligeramente negativas con el resto de variables, sugiriendo que ni el precio ni la valoración agregada en la tienda se relacionan de forma lineal fuerte con la popularidad o el volumen de reseñas de los videojuegos analizados.

1.4. Gráficas multivariadas

El vector de medias y la matriz de varianzas-covarianzas son elementos fundamentales del análisis estadístico multivariado, pues permiten caracterizar el comportamiento central, la dispersión y las relaciones de dependencia entre las variables de un conjunto de datos. Estas herramientas facilitan la comprensión global de la estructura interna de la información analizada.

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

El siguiente diagrama conjunto generado con ggpairs combina, en una sola figura, los histogramas univariados de cada variable numérica (precio, puntuaciones, número de críticas y valoraciones totales) con los diagramas de dispersión bivariados y los coeficientes de correlación entre todas ellas. Este tipo de visualización es especialmente útil en análisis multivariado porque permite, de un vistazo, explorar la forma de las distribuciones individuales, detectar posibles relaciones lineales o no lineales entre pares de variables y evaluar la fuerza de dichas relaciones mediante los coeficientes de correlación mostrados en la parte superior de cada panel.

ggpairs(resenas_de_juegos_electronicos_depurados[,-c(1,3,4,5,6,13)]) 

En los paneles se observa una correlación fuerte y positiva entre punt_criticos_meta, punt_usuarios_meta y n_criticos_meta, lo que indica que los juegos mejor valorados tienden a recibir más reseñas y que existe coherencia entre la opinión de críticos y usuarios. También se aprecia que variables como Precio_mas_alto y calif_ps_store presentan nubes de puntos muy dispersas y coeficientes de correlación bajos respecto al resto, lo que sugiere que ni el precio máximo ni la calificación agregada en la PS Store guardan una relación lineal clara con la popularidad medida por el número de reseñas o con las puntuaciones de Metacritic.

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

El siguiente diagrama ggpairs muestra, de forma conjunta, las distribuciones, los diagramas de dispersión y los coeficientes de correlación de las variables numéricas relacionadas con evaluaciones y participación de usuarios (Precio_mas_alto, punt_criticos_meta, n_criticos_meta, punt_usuarios_meta, n_usuarios_meta y calif_ps_store), diferenciando dos grupos según la variable categórica part_publi que clasifica la participación publicitaria de los juegos en niveles bajo (B) y medio (M). El coloreo por grupos permite comparar si la estructura de relaciones entre precio, puntuaciones y volumen de reseñas cambia según el nivel de inversión o visibilidad publicitaria.

resenas_de_juegos_electronicos_depurados$part_publi <- factor(
  resenas_de_juegos_electronicos_depurados$participacion_publi_cat,
  levels = c(1, 2),
  labels = c("B", "M"))
ggpairs(resenas_de_juegos_electronicos_depurados,columns = c(2, 7, 8, 9, 10, 11),      aes(color = part_publi, alpha = 0.5), upper = list(continuous = wrap("cor", size = 2.5)))

En los paneles de dispersión se observa que los juegos con mayor participación publicitaria (grupo M) tienden a concentrarse en rangos más altos de n_criticos_meta, n_usuarios_meta y n_total_store, lo que sugiere que la publicidad se asocia con una mayor visibilidad y número de reseñas tanto críticas como de usuarios. Sin embargo, las correlaciones entre puntuaciones (punt_criticos_meta, punt_usuarios_meta, calif_ps_store) y el precio parecen similares en ambos grupos, lo que indica que la publicidad influye más en el volumen de interacción que en la valoración media de los juegos, la cual sigue determinada principalmente por la calidad percibida del producto.

Diagrama de Estrellas

El diagrama de estrellas presenta el perfil multivariado de 20 videojuegos seleccionados aleatoriamente, usando como radios las variables numéricas Precio_mas_alto, punt_criticos_meta, n_criticos_meta, punt_usuarios_meta, n_usuarios_meta, calif_ps_store y n_total_store. Cada estrella resume simultáneamente el nivel de precio, las puntuaciones y el volumen de reseñas, permitiendo comparar de forma visual qué títulos destacan en determinadas dimensiones del mercado.

resenas_de_juegos_electronicos_depurados$alto <- NULL
set.seed(120522)
resenas_de_juegos_electronicos_depurados_Muestreado = resenas_de_juegos_electronicos_depurados[sample(1:nrow(resenas_de_juegos_electronicos_depurados),20),-c(1,3,4,5,6,13)]
stars(resenas_de_juegos_electronicos_depurados_Muestreado, len = 1, cex = 0.4, key.loc = c(12, 2), draw.segments = TRUE)

Las estrellas con segmentos más largos en n_usuarios_meta y n_total_store corresponden a juegos con gran popularidad y alta participación de la comunidad, mientras que aquellas con radios cortos en estas variables representan títulos con baja visibilidad. Algunas estrellas muestran combinaciones de precio elevado y participación moderada, indicando productos de gama alta aún en consolidación, mientras que otras presentan perfiles más equilibrados, propios de juegos con precios y evaluaciones intermedias en el catálogo analizado.

Caras de Chernoff

El siguiente gráfico de caras de Chernoff representa 23 videojuegos seleccionados aleatoriamente a partir de las variables numéricas del conjunto de datos (Precio_mas_alto, puntuaciones y conteos de reseñas), transformando cada vector de valores en un rostro con rasgos faciales distintos. La forma y el tamaño de elementos como ojos, boca, orejas o cabeza codifican combinaciones de las variables, de modo que diferencias en la expresión de las caras reflejan patrones multivariados diferenciados entre los juegos analizados.

set.seed(120522)
no_numericas <- which(!sapply(resenas_de_juegos_electronicos_depurados, is.numeric))
resenas_de_juegos_electronicos_depurados_1_Muestreado =resenas_de_juegos_electronicos_depurados[
    sample(1:nrow(resenas_de_juegos_electronicos_depurados), 23),-no_numericas]
faces(resenas_de_juegos_electronicos_depurados_1_Muestreado)

## effect of variables:
##  modified item       Var                      
##  "height of face   " "Precio_mas_alto"        
##  "width of face    " "punt_criticos_meta"     
##  "structure of face" "n_criticos_meta"        
##  "height of mouth  " "punt_usuarios_meta"     
##  "width of mouth   " "n_usuarios_meta"        
##  "smiling          " "calif_ps_store"         
##  "height of eyes   " "n_total_store"          
##  "width of eyes    " "participacion_publi_cat"
##  "height of hair   " "Precio_mas_alto"        
##  "width of hair   "  "punt_criticos_meta"     
##  "style of hair   "  "n_criticos_meta"        
##  "height of nose  "  "punt_usuarios_meta"     
##  "width of nose   "  "n_usuarios_meta"        
##  "width of ear    "  "calif_ps_store"         
##  "height of ear   "  "n_total_store"

Las caras más “extremas”, con cabezas más grandes, ojos más abiertos u orejas más alargadas, corresponden a títulos con valores altos simultáneamente en varias dimensiones, típicamente juegos con precios elevados, altas puntuaciones y gran número de reseñas, que se distinguen visualmente del resto. En cambio, los rostros más homogéneos y pequeños representan videojuegos con perfiles más modestos en precio, calidad percibida y participación de usuarios, lo que indica que el mercado incluye tanto productos estrella claramente diferenciados como una mayoría de títulos con características medias o bajas.

1.5. Normalidad multivariada

PNM Mardia

La prueba de normalidad multivariada de Mardia evalúa si el vector formado por las variables cuantitativas del estudio (precio_mas_alto, punt_criticos, n_criticos, punt_usuarios, n_usuarios, calif_ps y n_ps) puede considerarse procedente de una distribución normal conjunta. Para ello calcula dos estadísticas, una asociada al sesgo (skewness) y otra a la curtosis, y contrasta hipótesis de normalidad tanto a nivel multivariado como de forma univariante para cada variable.

library(MVN)
datos_mvn <- resenas_de_juegos_electronicos_depurados[
  , c("Precio_mas_alto", "punt_criticos_meta", "n_criticos_meta",
      "punt_usuarios_meta", "n_usuarios_meta", "calif_ps_store",
      "n_total_store", "participacion_publi_cat")]
datos_mvn <- na.omit(datos_mvn)
mvn_result <- mvn(data      = datos_mvn,mvn_test  = "mardia")
print(mvn_result)
## $multivariate_normality
##              Test  Statistic p.value     Method          MVN
## 1 Mardia Skewness 1642898.81  <0.001 asymptotic ✗ Not normal
## 2 Mardia Kurtosis    7632.91  <0.001 asymptotic ✗ Not normal
## 
## $univariate_normality
##               Test                Variable Statistic p.value    Normality
## 1 Anderson-Darling         Precio_mas_alto   101.852  <0.001 ✗ Not normal
## 2 Anderson-Darling      punt_criticos_meta   758.520  <0.001 ✗ Not normal
## 3 Anderson-Darling         n_criticos_meta   768.379  <0.001 ✗ Not normal
## 4 Anderson-Darling      punt_usuarios_meta   795.200  <0.001 ✗ Not normal
## 5 Anderson-Darling         n_usuarios_meta  1172.159  <0.001 ✗ Not normal
## 6 Anderson-Darling          calif_ps_store   435.598  <0.001 ✗ Not normal
## 7 Anderson-Darling           n_total_store   956.080  <0.001 ✗ Not normal
## 8 Anderson-Darling participacion_publi_cat  1312.857  <0.001 ✗ Not normal
## 
## $descriptives
##                  Variable    n     Mean   Std.Dev Median Min      Max  25th
## 1         Precio_mas_alto 3457   29.803    17.997  24.99   0    100.0 15.99
## 2      punt_criticos_meta 3457   20.283    33.562   1.00   1     98.0  1.00
## 3         n_criticos_meta 3457    9.257    20.373   1.00   1    145.0  1.00
## 4      punt_usuarios_meta 3457    2.446     2.717   1.00   1      9.5  1.00
## 5         n_usuarios_meta 3457  270.295  3192.863   1.00   1 165959.0  1.00
## 6          calif_ps_store 3457    3.431     1.546   4.22   1      5.0  1.00
## 7           n_total_store 3457 5470.314 26742.164 127.00   1 854788.0  1.00
## 8 participacion_publi_cat 3457    1.016     0.125   1.00   1      2.0  1.00
##      75th   Skew Kurtosis
## 1   39.99  1.015    3.594
## 2   65.00  1.208    2.557
## 3    4.00  3.063   12.726
## 4    1.00  1.419    3.155
## 5    1.00 41.801 2109.524
## 6    4.56 -0.845    1.887
## 7 1577.00 14.849  354.212
## 8    1.00  7.738   60.871
## 
## $data
## # A tibble: 3,457 × 8
##    Precio_mas_alto punt_criticos_meta n_criticos_meta punt_usuarios_meta
##              <dbl>              <dbl>           <dbl>              <dbl>
##  1           25.0                  98              86                8.3
##  2           60.0                  97              99                8.9
##  3           70.0                  97              99                8.9
##  4            9.99                 97              56                8  
##  5           70.0                  97              66                8.5
##  6           70.0                  97              66                8.5
##  7           70.0                  96             112                9.2
##  8           70.0                  96              86                8.3
##  9           40.0                  96             115                8.9
## 10           65.0                  96              98                8.9
## # ℹ 3,447 more rows
## # ℹ 4 more variables: n_usuarios_meta <dbl>, calif_ps_store <dbl>,
## #   n_total_store <dbl>, participacion_publi_cat <dbl>
## 
## $subset
## NULL
## 
## $outlierMethod
## [1] "none"
## 
## attr(,"class")
## [1] "mvn"

Los valores obtenidos para Mardia (sesgo = 1 394 600.419 y curtosis = 7 583.488, con p‑valores < 0.001) llevan a rechazar claramente la normalidad multivariada, indicando que el conjunto de variables, incluido precio_mas_alto, presenta una estructura muy alejada de la distribución normal. De forma consistente, las pruebas univariantes de Anderson‑Darling muestran que cada variable por separado tampoco es normal (p‑valores < 0.001), con asimetrías y curtosis especialmente extremas en n_usuarios y n_ps, donde unos pocos videojuegos concentran valores muy altos de reseñas o ventas mientras la mayoría se mantiene en niveles bajos.

PNM Henze-Zirkler

La prueba de Henze–Zirkler es un contraste global de normalidad multivariada que evalúa si el vector formado por precio_mas_alto, punt_criticos, n_criticos, punt_usuarios, n_usuarios, calif_ps y n_ps puede considerarse procedente de una distribución normal conjunta. Se basa en una medida de distancia entre la distribución empírica de los datos y la distribución normal teórica equivalente, generando una estadística H Z y un valor p asociado.

mvn(resenas_de_juegos_electronicos_depurados[, -c(1, 3, 4, 5, 6, 13)], mvn_test = "hz")
## Warning in hz(data, use_population = use_population, tol = tol, bootstrap =
## bootstrap, : Dropping non-numeric columns: part_publi
## Warning in test_univariate_normality(data, test = "AD"): Dropping non-numeric
## columns: part_publi
## Warning in descriptives(data): Dropping non-numeric columns: part_publi
## $multivariate_normality
##            Test Statistic p.value     Method          MVN
## 1 Henze-Zirkler   380.187  <0.001 asymptotic ✗ Not normal
## 
## $univariate_normality
##               Test           Variable Statistic p.value    Normality
## 1 Anderson-Darling    Precio_mas_alto   101.852  <0.001 ✗ Not normal
## 2 Anderson-Darling punt_criticos_meta   758.520  <0.001 ✗ Not normal
## 3 Anderson-Darling    n_criticos_meta   768.379  <0.001 ✗ Not normal
## 4 Anderson-Darling punt_usuarios_meta   795.200  <0.001 ✗ Not normal
## 5 Anderson-Darling    n_usuarios_meta  1172.159  <0.001 ✗ Not normal
## 6 Anderson-Darling     calif_ps_store   435.598  <0.001 ✗ Not normal
## 7 Anderson-Darling      n_total_store   956.080  <0.001 ✗ Not normal
## 
## $descriptives
##             Variable    n     Mean   Std.Dev Median Min      Max  25th    75th
## 1    Precio_mas_alto 3457   29.803    17.997  24.99   0    100.0 15.99   39.99
## 2 punt_criticos_meta 3457   20.283    33.562   1.00   1     98.0  1.00   65.00
## 3    n_criticos_meta 3457    9.257    20.373   1.00   1    145.0  1.00    4.00
## 4 punt_usuarios_meta 3457    2.446     2.717   1.00   1      9.5  1.00    1.00
## 5    n_usuarios_meta 3457  270.295  3192.863   1.00   1 165959.0  1.00    1.00
## 6     calif_ps_store 3457    3.431     1.546   4.22   1      5.0  1.00    4.56
## 7      n_total_store 3457 5470.314 26742.164 127.00   1 854788.0  1.00 1577.00
##     Skew Kurtosis
## 1  1.015    3.594
## 2  1.208    2.557
## 3  3.063   12.726
## 4  1.419    3.155
## 5 41.801 2109.524
## 6 -0.845    1.887
## 7 14.849  354.212
## 
## $data
## # A tibble: 3,457 × 8
##    Precio_mas_alto punt_criticos_meta n_criticos_meta punt_usuarios_meta
##              <dbl>              <dbl>           <dbl>              <dbl>
##  1           25.0                  98              86                8.3
##  2           60.0                  97              99                8.9
##  3           70.0                  97              99                8.9
##  4            9.99                 97              56                8  
##  5           70.0                  97              66                8.5
##  6           70.0                  97              66                8.5
##  7           70.0                  96             112                9.2
##  8           70.0                  96              86                8.3
##  9           40.0                  96             115                8.9
## 10           65.0                  96              98                8.9
## # ℹ 3,447 more rows
## # ℹ 4 more variables: n_usuarios_meta <dbl>, calif_ps_store <dbl>,
## #   n_total_store <dbl>, part_publi <fct>
## 
## $subset
## NULL
## 
## $outlierMethod
## [1] "none"
## 
## attr(,"class")
## [1] "mvn"

La estadística de Henze–Zirkler obtenida es 380.187, con un p‑valor < 0.001, por lo que se rechaza la hipótesis de normalidad multivariada para el conjunto de variables, confirmando el resultado observado previamente con la prueba de Mardia. De nuevo, las pruebas univariantes de Anderson–Darling muestran que cada variable por separado, incluido precio_mas_alto, se desvía significativamente de la normalidad, con fuertes asimetrías y curtosis muy elevadas en n_usuarios y n_ps, lo que refleja la presencia de colas largas y valores extremos característicos del mercado de videojuegos.

PNM Doornik-Hansen

mvn(resenas_de_juegos_electronicos_depurados[, -c(1, 3, 4, 5, 6, 13)], mvn_test = "doornik_hansen")
## Warning in doornik_hansen(data, bootstrap = bootstrap, B = B, cores = cores):
## Dropping non-numeric columns: part_publi
## Warning in test_univariate_normality(data, test = "AD"): Dropping non-numeric
## columns: part_publi
## Warning in descriptives(data): Dropping non-numeric columns: part_publi
## $multivariate_normality
##             Test Statistic df p.value     Method          MVN
## 1 Doornik-Hansen  88299.04 14  <0.001 asymptotic ✗ Not normal
## 
## $univariate_normality
##               Test           Variable Statistic p.value    Normality
## 1 Anderson-Darling    Precio_mas_alto   101.852  <0.001 ✗ Not normal
## 2 Anderson-Darling punt_criticos_meta   758.520  <0.001 ✗ Not normal
## 3 Anderson-Darling    n_criticos_meta   768.379  <0.001 ✗ Not normal
## 4 Anderson-Darling punt_usuarios_meta   795.200  <0.001 ✗ Not normal
## 5 Anderson-Darling    n_usuarios_meta  1172.159  <0.001 ✗ Not normal
## 6 Anderson-Darling     calif_ps_store   435.598  <0.001 ✗ Not normal
## 7 Anderson-Darling      n_total_store   956.080  <0.001 ✗ Not normal
## 
## $descriptives
##             Variable    n     Mean   Std.Dev Median Min      Max  25th    75th
## 1    Precio_mas_alto 3457   29.803    17.997  24.99   0    100.0 15.99   39.99
## 2 punt_criticos_meta 3457   20.283    33.562   1.00   1     98.0  1.00   65.00
## 3    n_criticos_meta 3457    9.257    20.373   1.00   1    145.0  1.00    4.00
## 4 punt_usuarios_meta 3457    2.446     2.717   1.00   1      9.5  1.00    1.00
## 5    n_usuarios_meta 3457  270.295  3192.863   1.00   1 165959.0  1.00    1.00
## 6     calif_ps_store 3457    3.431     1.546   4.22   1      5.0  1.00    4.56
## 7      n_total_store 3457 5470.314 26742.164 127.00   1 854788.0  1.00 1577.00
##     Skew Kurtosis
## 1  1.015    3.594
## 2  1.208    2.557
## 3  3.063   12.726
## 4  1.419    3.155
## 5 41.801 2109.524
## 6 -0.845    1.887
## 7 14.849  354.212
## 
## $data
## # A tibble: 3,457 × 8
##    Precio_mas_alto punt_criticos_meta n_criticos_meta punt_usuarios_meta
##              <dbl>              <dbl>           <dbl>              <dbl>
##  1           25.0                  98              86                8.3
##  2           60.0                  97              99                8.9
##  3           70.0                  97              99                8.9
##  4            9.99                 97              56                8  
##  5           70.0                  97              66                8.5
##  6           70.0                  97              66                8.5
##  7           70.0                  96             112                9.2
##  8           70.0                  96              86                8.3
##  9           40.0                  96             115                8.9
## 10           65.0                  96              98                8.9
## # ℹ 3,447 more rows
## # ℹ 4 more variables: n_usuarios_meta <dbl>, calif_ps_store <dbl>,
## #   n_total_store <dbl>, part_publi <fct>
## 
## $subset
## NULL
## 
## $outlierMethod
## [1] "none"
## 
## attr(,"class")
## [1] "mvn"

PNM Royston

datos_limpios <- na.omit(resenas_de_juegos_electronicos_depurados[, -c(1,3,4,5,6,13)])
datos_royston <- datos_limpios[1:2000, ]
mvn(datos_royston, mvn_test = "royston")
## Warning in royston(data, tol = tol, bootstrap = bootstrap, B = B, cores =
## cores): Dropping non-numeric columns: part_publi
## Warning in test_univariate_normality(data, test = "AD"): Dropping non-numeric
## columns: part_publi
## Warning in descriptives(data): Dropping non-numeric columns: part_publi
## $multivariate_normality
##      Test Statistic p.value     Method          MVN
## 1 Royston  1451.886  <0.001 asymptotic ✗ Not normal
## 
## $univariate_normality
##               Test           Variable Statistic p.value    Normality
## 1 Anderson-Darling    Precio_mas_alto    67.914  <0.001 ✗ Not normal
## 2 Anderson-Darling punt_criticos_meta   473.579  <0.001 ✗ Not normal
## 3 Anderson-Darling    n_criticos_meta   452.923  <0.001 ✗ Not normal
## 4 Anderson-Darling punt_usuarios_meta   474.064  <0.001 ✗ Not normal
## 5 Anderson-Darling    n_usuarios_meta   653.439  <0.001 ✗ Not normal
## 6 Anderson-Darling     calif_ps_store   276.139  <0.001 ✗ Not normal
## 7 Anderson-Darling      n_total_store   532.648  <0.001 ✗ Not normal
## 
## $descriptives
##             Variable    n     Mean   Std.Dev Median Min      Max  25th    75th
## 1    Precio_mas_alto 2000   29.982    18.737  24.99   0    100.0 14.99   39.99
## 2 punt_criticos_meta 2000   20.656    35.627   1.00   1     98.0  1.00    1.00
## 3    n_criticos_meta 2000   11.213    24.150   1.00   1    145.0  1.00    1.00
## 4 punt_usuarios_meta 2000    2.532     2.881   1.00   1      9.2  1.00    1.00
## 5    n_usuarios_meta 2000  432.748  4179.334   1.00   1 165959.0  1.00    1.00
## 6     calif_ps_store 2000    3.480     1.585   4.33   1      5.0  1.00    4.62
## 7      n_total_store 2000 7372.048 33040.661 192.50   1 854788.0  1.00 2478.00
##     Skew Kurtosis
## 1  1.012    3.419
## 2  1.274    2.656
## 3  2.649    9.557
## 4  1.390    3.015
## 5 32.103 1237.580
## 6 -0.860    1.867
## 7 12.934  257.141
## 
## $data
## # A tibble: 2,000 × 8
##    Precio_mas_alto punt_criticos_meta n_criticos_meta punt_usuarios_meta
##              <dbl>              <dbl>           <dbl>              <dbl>
##  1           25.0                  98              86                8.3
##  2           60.0                  97              99                8.9
##  3           70.0                  97              99                8.9
##  4            9.99                 97              56                8  
##  5           70.0                  97              66                8.5
##  6           70.0                  97              66                8.5
##  7           70.0                  96             112                9.2
##  8           70.0                  96              86                8.3
##  9           40.0                  96             115                8.9
## 10           65.0                  96              98                8.9
## # ℹ 1,990 more rows
## # ℹ 4 more variables: n_usuarios_meta <dbl>, calif_ps_store <dbl>,
## #   n_total_store <dbl>, part_publi <fct>
## 
## $subset
## NULL
## 
## $outlierMethod
## [1] "none"
## 
## attr(,"class")
## [1] "mvn"

Fase 2 [Componentes Principales]

El Análisis de Componentes Principales (ACP) tiene como finalidad transformar el conjunto original de variables numéricas en un nuevo conjunto de componentes que concentren la mayor parte de la información contenida en los datos. En el presente estudio, el ACP se aplica sobre un grupo de variables cuantitativas que describen el desempeño y la recepción de los videojuegos, tales como las puntuaciones otorgadas por críticos y usuarios, así como la cantidad de reseñas registradas en diferentes plataformas. Mediante este procedimiento estadístico, se busca reducir la complejidad del conjunto de datos, identificando las combinaciones lineales de variables que mejor explican la variabilidad total observada. De esta manera, el ACP facilita una interpretación más clara de las relaciones entre las distintas medidas de valoración, permitiendo representar la información en un espacio de menor dimensión sin perder la esencia del comportamiento general de los datos.

2.1. Objetivos

El Análisis de Componentes Principales (ACP) se desarrolla a través de distintas etapas que incluyen la construcción de nuevas variables, la reducción de la dimensionalidad del conjunto de datos, la identificación y eliminación de variables con baja relevancia, y la interpretación de los componentes obtenidos dentro del contexto del problema analizado.

Estimado lector, si desea profundizar en los fundamentos teóricos que respaldan este análisis, los detalles del conjunto de datos se encuentran expuestos en la Sección 1.2,mientras que los principios conceptuales sobre los que se apoya este estudio se desarrollan con detalle en la Fase 1.

2.2. Selección de Componentes

Matriz ACP

datos_pca <- resenas_de_juegos_electronicos_depurados[,
c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store")]
res.pca <- PCA(datos_pca, ncp = 6, scale.unit = TRUE, graph = FALSE)
get_eigenvalue(res.pca)
##       eigenvalue variance.percent cumulative.variance.percent
## Dim.1 2.72428898        45.404816                    45.40482
## Dim.2 1.13244757        18.874126                    64.27894
## Dim.3 0.97778641        16.296440                    80.57538
## Dim.4 0.83202932        13.867155                    94.44254
## Dim.5 0.26801775         4.466962                    98.90950
## Dim.6 0.06542997         1.090499                   100.00000

Matriz de Correlaciones

datos_cor <- resenas_de_juegos_electronicos_depurados[,
c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store", "n_total_store")]
round(cor(datos_cor, use = "pairwise.complete.obs"), 2)
##                    Precio_mas_alto punt_criticos_meta n_criticos_meta
## Precio_mas_alto               1.00               0.05            0.18
## punt_criticos_meta            0.05               1.00            0.74
## n_criticos_meta               0.18               0.74            1.00
## punt_usuarios_meta            0.06               0.93            0.75
## n_usuarios_meta               0.09               0.18            0.33
## calif_ps_store               -0.12               0.00            0.02
## n_total_store                 0.19               0.08            0.18
##                    punt_usuarios_meta n_usuarios_meta calif_ps_store
## Precio_mas_alto                  0.06            0.09          -0.12
## punt_criticos_meta               0.93            0.18           0.00
## n_criticos_meta                  0.75            0.33           0.02
## punt_usuarios_meta               1.00            0.16           0.03
## n_usuarios_meta                  0.16            1.00           0.02
## calif_ps_store                   0.03            0.02           1.00
## n_total_store                    0.08            0.32           0.13
##                    n_total_store
## Precio_mas_alto             0.19
## punt_criticos_meta          0.08
## n_criticos_meta             0.18
## punt_usuarios_meta          0.08
## n_usuarios_meta             0.32
## calif_ps_store              0.13
## n_total_store               1.00

Valores y Vectores Propios

datos_pca <- resenas_de_juegos_electronicos_depurados[,
c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_pca <- na.omit(datos_pca)
datos_pca <- datos_pca[is.finite(rowSums(datos_pca)), ]
valores_propios <- princomp(datos_pca, cor = TRUE)$sdev^2
vectores_propios <- princomp(datos_pca, cor = TRUE)$loadings[, 1:5]
print(round(valores_propios, 2))
## Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6 Comp.7 
##   2.77   1.32   1.12   0.83   0.62   0.27   0.07
print(round(vectores_propios, 3))
##                    Comp.1 Comp.2 Comp.3 Comp.4 Comp.5
## Precio_mas_alto     0.114  0.394  0.580  0.621  0.305
## punt_criticos_meta  0.551 -0.249 -0.012  0.029 -0.098
## n_criticos_meta     0.539 -0.016  0.029  0.011  0.098
## punt_usuarios_meta  0.553 -0.245 -0.031  0.069 -0.087
## n_usuarios_meta     0.243  0.514 -0.065 -0.605  0.517
## calif_ps_store      0.022  0.134 -0.797  0.491  0.321
## n_total_store       0.164  0.663 -0.148  0.037 -0.714

Correlaciones Comparadas

datos_num <- resenas_de_juegos_electronicos_depurados[,
c("Precio_mas_alto",
"punt_criticos_meta",
"n_criticos_meta",
"punt_usuarios_meta",
"n_usuarios_meta",
"calif_ps_store",
"n_total_store")]
datos_num <- na.omit(datos_num)
resultado_pca <- princomp(datos_num, cor = TRUE)
corrplot(cor(datos_num), method = "color", type = "upper", number.cex = 0.4)

Gráfico de Cattell

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto",
    "punt_criticos_meta",
    "n_criticos_meta",
    "punt_usuarios_meta",
    "n_usuarios_meta",
    "calif_ps_store",
    "n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 8, scale.unit = TRUE, graph = FALSE)
fviz_eig(res.pca, addlabels = TRUE, ylim = c(0, 90), main = "")
## Warning in geom_bar(stat = "identity", fill = barfill, color = barcolor, :
## Ignoring empty aesthetic: `width`.

Gráfico de Cattell-Kaiser

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
scree(datos_num, factors = FALSE, pc = TRUE, main = "")

2.3. Calidad de Representación

Círculo de Correlaciones

datos_num <- resenas_de_juegos_electronicos_depurados[,
c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 8, scale.unit = TRUE, graph = FALSE)
fviz_pca_var(res.pca,col.var = "#3B83BD",repel = TRUE,col.circle = "#CDCDCD",ggtheme = theme_bw())
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the ggpubr package.
##   Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## ℹ The deprecated feature was likely used in the factoextra package.
##   Please report the issue at <https://github.com/kassambara/factoextra/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
fviz_contrib(
  res.pca,
  choice = "var",
  axes   = 1,
  top    = 10
)

Matriz de Representación

datos_num <- resenas_de_juegos_electronicos_depurados[,
c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 5, scale.unit = TRUE, graph = FALSE)
var <- get_pca_var(res.pca)
var$cos2 
##                          Dim.1        Dim.2        Dim.3        Dim.4
## Precio_mas_alto    0.035736414 0.2058008399 0.3747099919 3.211479e-01
## punt_criticos_meta 0.841850201 0.0823035291 0.0001672585 6.958026e-04
## n_criticos_meta    0.805611206 0.0003232891 0.0009637689 9.592625e-05
## punt_usuarios_meta 0.848544659 0.0794190332 0.0011047883 3.964005e-03
## n_usuarios_meta    0.163740585 0.3493399831 0.0047036441 3.052284e-01
## calif_ps_store     0.001308774 0.0238563614 0.7095483582 2.006934e-01
## n_total_store      0.074737166 0.5813662436 0.0245942349 1.140365e-03
##                          Dim.5
## Precio_mas_alto    0.058049952
## punt_criticos_meta 0.006045692
## n_criticos_meta    0.005960149
## punt_usuarios_meta 0.004769527
## n_usuarios_meta    0.166558921
## calif_ps_store     0.064332038
## n_total_store      0.318154575

Calidad de Representación

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 5, scale.unit = TRUE, graph = FALSE)
fviz_pca_var( res.pca, col.var       = "cos2",
  gradient.cols = c("#D7263D", "#1A1AFF", "#FF9800"),repel         = TRUE)

Coordenadas Individuales

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 5, scale.unit = TRUE, graph = FALSE)
head(res.pca$ind$coord, n = 20L)
##        Dim.1       Dim.2       Dim.3       Dim.4       Dim.5
## 1   5.150071  0.73285400  0.94724318 -0.56722259  -0.2523484
## 2   9.864860 13.92062745  2.39554983 -3.75196976  -4.0770507
## 3   9.928512 14.14207054  2.07399092 -3.40677406  -3.9099061
## 4   3.640097 -1.23360693  1.27706999 -0.45157345   0.1419571
## 5   5.559100  2.99251765 -0.16132201 -0.59067556   2.0882738
## 6  10.549097 23.13547503  4.26458955  0.48022360 -19.6576221
## 7   6.983748  2.36929899 -2.23157903 -2.73688630   3.4782081
## 8   6.307049  2.88227475 -2.15246537 -3.25848143   3.7964336
## 9   5.967017  0.12758991  0.10906654 -0.56471987   1.7541407
## 10  5.360400  0.11128124 -0.39610930  1.37769007   1.3817204
## 11  5.138079  0.26925069 -0.57647960  1.40010389   1.5810868
## 12  5.289006  0.36018270 -2.29333562 -0.61508191   1.3206736
## 13  5.126060 -0.58329644  0.68118514 -0.07517554   1.0466558
## 14  4.615794 -0.19868033 -1.74099535 -0.98128092   0.7468456
## 15  6.417290  2.20077331 -0.54352333 -1.11511968   3.6238097
## 16  6.362353  2.03115567  0.04333922 -1.35144880   3.4949006
## 17  4.320887 -0.49511706 -2.15903441  0.03370713   0.3701613
## 18  5.266380 -0.01536507  0.74931298 -0.07425578   0.3874144
## 19  8.507616 12.93327327  2.86640457 -2.08083730  -7.1832280
## 20  6.096352  3.10701329 -0.26346761 -1.96969181   4.2415091

2.4. Contribuciones y Biplots

Los autores (Díaz Morales & Morales Rivera, 2012) destacan que la interpretación de los resultados en el análisis de componentes principales depende estrechamente del cálculo de elementos como coordenadas, contribuciones y cosenos cuadrados. En el contexto de los datos sobre videojuegos, es fundamental que variables como las puntuaciones de críticos, número de reseñas, calificaciones de usuarios, géneros o cifras de ventas estén correctamente conceptualizadas y contextualizadas para una comprensión clara y precisa.

2.4.1 Matriz de Contribuciones

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

En Contribuciones a D1 se observa que las variables punt_usuarios, punt_criticos y n_criticos presentan una contribución claramente superior a la media, reteniendo aproximadamente el \(90%\) de la variabilidad explicada por el primer componente principal.

Matriz de Contribuciones

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
var <- get_pca_var(res.pca)
var$contrib
##                          Dim.1       Dim.2       Dim.3       Dim.4      Dim.5
## Precio_mas_alto     1.28941152 15.56256774 33.58242189 38.55475082  9.3048027
## punt_criticos_meta 30.37493742  6.22375617  0.01499012  0.08353316  0.9690615
## n_criticos_meta    29.06739222  0.02444698  0.08637532  0.01151623  0.9553499
## punt_usuarios_meta 30.61648126  6.00563187  0.09901382  0.47589049  0.7645055
## n_usuarios_meta     5.90795133 26.41693374  0.42155204 36.64356886 26.6976602
## calif_ps_store      0.04722211  1.80400741 63.59145160 24.09383621 10.3117556
## n_total_store       2.69660414 43.96265609  2.20419522  0.13690422 50.9968646
##                           Dim.6
## Precio_mas_alto     1.697481080
## punt_criticos_meta 13.897510624
## n_criticos_meta    69.772133603
## punt_usuarios_meta 10.665913603
## n_usuarios_meta     3.884337666
## calif_ps_store      0.079859268
## n_total_store       0.002764156

Contribuciones a D1

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
fviz_contrib(res.pca, choice = "var", axes = 1, top = 10)

Contribuciones a D2

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
fviz_contrib(res.pca, choice = "var", axes = 2, top = 10)

Contribuciones a D3

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
fviz_contrib(res.pca, choice = "var", axes = 3, top = 10)

Contribuciones a D4

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
fviz_contrib(res.pca, choice = "var", axes = 4, top = 10)

Contribuciones a D5

datos_num <- resenas_de_juegos_electronicos_depurados[, 
  c("Precio_mas_alto","punt_criticos_meta","n_criticos_meta","punt_usuarios_meta","n_usuarios_meta","calif_ps_store","n_total_store")]
datos_num <- na.omit(datos_num)
res.pca <- PCA(datos_num, ncp = 6, scale.unit = TRUE, graph = FALSE)
fviz_contrib(res.pca, choice = "var", axes = 5, top = 10)

2.4.2 Planteamiento y Desarrollo

Biplot de Variables y Registros [filtro:ChestPain]

resenas_de_juegos_electronicos_depurados <- read_excel ("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados.xlsx")

resenas_de_juegos_electronicos_depurados_Muestreado <- resenas_de_juegos_electronicos_depurados[
  sample(1:nrow(resenas_de_juegos_electronicos_depurados), 100),
  -c(1,3,4,5,6,13)]

resenas_de_juegos_electronicos_depurados_Muestreado$punt_usuarios_cat <- cut(
  resenas_de_juegos_electronicos_depurados_Muestreado$punt_usuarios_meta,
  breaks = c(-Inf, 3, 5, 7.5, Inf),  
  labels = c("Muy Malo", "Malo", "Bueno", "Muy Bueno"))

fviz_pca_biplot(PCA(resenas_de_juegos_electronicos_depurados_Muestreado[,], ncp = 5, scale.unit = TRUE, graph = FALSE, quali.sup = "punt_usuarios_cat"),axes = c(1, 2),repel = TRUE, habillage = "punt_usuarios_cat")

Biplot de Variables y Registros [filtro:N.of Major Vessels]

resenas_de_juegos_electronicos_depurados <- read_excel("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados.xlsx")

set.seed(780729)
resenas_de_juegos_electronicos_depurados_Muestreado <- resenas_de_juegos_electronicos_depurados[ sample(1:nrow(resenas_de_juegos_electronicos_depurados), 150), -c(1,3,4,5,6,13)]

resenas_de_juegos_electronicos_depurados_Muestreado$calif_ps_cat <- cut(
  resenas_de_juegos_electronicos_depurados_Muestreado$calif_ps_store,
  breaks = c(-Inf, 3, 4.5, Inf),
  labels = c("Baja", "Media", "Alta"))

num_cols <- sapply(resenas_de_juegos_electronicos_depurados_Muestreado, is.numeric)
df_pca <- resenas_de_juegos_electronicos_depurados_Muestreado[, num_cols]
df_pca$calif_ps_cat <- resenas_de_juegos_electronicos_depurados_Muestreado$calif_ps_cat
pca_result <- PCA(df_pca,ncp = 5,scale.unit = TRUE,graph = FALSE,quali.sup = which(names(df_pca) == "calif_ps_cat"))

fviz_pca_biplot(pca_result,axes = c(1,2),repel = TRUE,habillage = "calif_ps_cat")

Coordenadas Individuales [ChestPain]

set.seed(220512)
resenas_de_juegos_electronicos_depurados_Muestreado= resenas_de_juegos_electronicos_depurados[sample(1:nrow(resenas_de_juegos_electronicos_depurados),47),-c(1,3,4,5,6,13)]

resenas_de_juegos_electronicos_depurados_Muestreado$n_usuarios_cat <- cut(
resenas_de_juegos_electronicos_depurados_Muestreado$n_usuarios_meta,
breaks = c(-Inf, 5, 50, Inf),
labels = c("Bajo", "Medio", "Alto"))

head(PCA(resenas_de_juegos_electronicos_depurados_Muestreado,ncp = 4,scale.unit = TRUE,graph = FALSE, quali.sup = "n_usuarios_cat")$ind$coord, n = 40L)
##         Dim.1       Dim.2        Dim.3        Dim.4
## 1  -1.2428635  3.86894018  0.270585598 -2.475409417
## 2   5.0730916  0.54313785 -0.941729960  0.292716756
## 3  -0.8111002 -0.33540899 -1.692038724  0.029698083
## 4  -1.3152366  3.63260229  1.499014606 -0.813583675
## 5   0.2819718 -1.11196812  0.924598534 -0.471241978
## 6   3.3370721 -1.08748939  1.097537744 -0.777513845
## 7   1.2097552 -0.58005126 -0.635030743 -0.511254107
## 8  -1.1297920 -0.42233260  1.513870768  0.543677514
## 9  -0.9568925  0.14408247 -0.297688616  0.656916282
## 10 -1.0128424 -1.03013145  0.426523988 -0.127618548
## 11  5.6885726  1.53862635 -0.154030084  2.192174662
## 12 -0.9660626 -1.27325099 -0.008414724 -0.396136972
## 13  2.7977246 -1.17282744  0.973039869 -0.779084055
## 14 -1.0128424 -1.03013145  0.426523988 -0.127618548
## 15 -0.9148832  0.28442827 -0.865080830  0.225537079
## 16 -0.9959701  0.84863093 -0.021457369  1.196970258
## 17 -1.0150290  0.93725707  0.079490979  1.016157896
## 18 -0.7918780 -0.42725153 -1.891945714 -0.147465280
## 19 -1.0362323 -0.90857168  0.643993344  0.006640665
## 20 -1.0128424 -1.03013145  0.426523988 -0.127618548
## 21 -0.8702366 -0.06622178 -1.138280707  0.335337889
## 22  1.5794809 -1.16665961  1.104074807 -0.736121191
## 23 -0.8666117 -0.37627324 -1.128649145  0.104841769
## 24 -1.0260919  0.80514184  0.218222052  0.970954870
## 25 -0.9894525 -1.15169122  0.209054632 -0.261877760
## 26 -0.8643552 -0.09168414 -1.219838914  0.210357883
## 27 -0.9312686  0.15253182 -0.588282995  0.498149964
## 28 -1.0262650  1.54769696 -0.501343164 -0.713439343
## 29 -0.8421838 -0.16889033 -1.408077346  0.196075505
## 30  4.6948415  1.94694645 -0.216208655 -0.052614630
## 31 -0.9904699  0.58278060 -0.044862240  0.967038639
## 32 -1.2233516  0.06390649  2.383748192  1.080714363
## 33 -0.9988085 -1.10306731  0.296042374 -0.208174075
## 34 -0.9183162 -0.16167003 -0.645179432  0.343376280
## 35 -1.2701315  0.30702603  2.818686905  1.349232788
## 36 -0.9660626 -1.27325099 -0.008414724 -0.396136972
## 37 -0.8352924 -0.30382198 -1.488911986 -0.029347565
## 38  1.4532819 -1.55890618  0.557526269 -1.194667051
## 39 -1.1181251  0.90632470  0.848351965  0.204203624
## 40  1.2736905 -0.37123673 -0.566416101 -0.392759648

Fase 3 [Correspondencias]

El análisis de correspondencias se emplea para estudiar la asociación entre variables categóricas, como puede ser género y plataforma, o género y región de ventas. Este enfoque permite visualizar en un plano reducido la relación entre categorías, facilitando la interpretación de cómo se vinculan los diferentes grupos dentro del dataset. Así, por ejemplo, se puede identificar si ciertos géneros son preferidos en determinadas plataformas o regiones, descubriendo patrones relevantes en el consumo de videojuegos.

3.1. Objetivos

En esta tercera fase del estudio se presentarán los cálculos, visualizaciones e interpretaciones correspondientes al análisis de las variables cualitativas del conjunto de datos previamente trabajado en la fase 1 y fase 2. El propósito de esta etapa es aplicar el Análisis de Correspondencias Simples y Múltiples (ACS y ACM), con el fin de explorar las relaciones entre categorías y representar gráficamente las asociaciones existentes.Para ello, se llevará a cabo la construcción de tablas de contingencia y tablas disyuntivas completas, así como la evaluación de la calidad de representación, las contribuciones y la interpretación de los ejes factoriales obtenidos.

3.2. Correspondencias Simples

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

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

3.2.1 Planteamiento y Desarrollo

AC Parejas Totales

3.3. Correspondencias Múltiples

ACM

resenas_de_juegos_electronicos_depurados_V2 <- read_excel("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados_V2.xlsx")
resenas_de_juegos_electronicos_depurados_V2$lanzamiento <- as.Date(resenas_de_juegos_electronicos_depurados_V2$lanzamiento, origin = "1899-12-30")

set.seed(780729)
resenas_de_juegos_electronicos_depurados_V2.active<-resenas_de_juegos_electronicos_depurados_V2[sample(1:nrow(resenas_de_juegos_electronicos_depurados_V2),15), 1:5]


suppressWarnings(round(MCA(resenas_de_juegos_electronicos_depurados_V2.active, graph = FALSE, ncp = 5)$eig, 3))
##        eigenvalue percentage of variance cumulative percentage of variance
## dim 1       1.000                  8.929                             8.929
## dim 2       0.982                  8.765                            17.693
## dim 3       0.800                  7.143                            24.836
## dim 4       0.800                  7.143                            31.979
## dim 5       0.800                  7.143                            39.122
## dim 6       0.800                  7.143                            46.265
## dim 7       0.800                  7.143                            53.408
## dim 8       0.800                  7.143                            60.551
## dim 9       0.800                  7.143                            67.693
## dim 10      0.800                  7.143                            74.836
## dim 11      0.800                  7.143                            81.979
## dim 12      0.800                  7.143                            89.122
## dim 13      0.618                  5.521                            94.643
## dim 14      0.600                  5.357                           100.000

Biplot ACM

resenas_de_juegos_electronicos_depurados_V2 <- read_excel("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados_V2.xlsx")
resenas_de_juegos_electronicos_depurados_V2$lanzamiento <- as.Date(resenas_de_juegos_electronicos_depurados_V2$lanzamiento, origin = "1899-12-30")

set.seed(780729)
resenas_de_juegos_electronicos_depurados_V2.active<-resenas_de_juegos_electronicos_depurados_V2[sample(1:nrow(resenas_de_juegos_electronicos_depurados_V2),100), 1:5]

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

#resenas_de_juegos_electronicos_depurados$genero <- as.factor(resenas_de_juegos_electronicos_depurados$genero)

#habillage = "genero",

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

Calidad de Representación

resenas_de_juegos_electronicos_depurados_V2 <- read_excel("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados_V2.xlsx")
resenas_de_juegos_electronicos_depurados_V2$lanzamiento <- as.Date(resenas_de_juegos_electronicos_depurados_V2$lanzamiento, origin = "1899-12-30")

set.seed(780729)
resenas_de_juegos_electronicos_depurados_V2.active<-resenas_de_juegos_electronicos_depurados_V2[sample(1:nrow(resenas_de_juegos_electronicos_depurados_V2),50), 1:5]

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

#resenas_de_juegos_electronicos_depurados_V2$genero <- as.factor(resenas_de_juegos_electronicos_depurados_V2$genero)

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

res.mca$var$cos2
##                                                             Dim 1        Dim 2
## Batman™: Arkham VR                                   0.0004164931 3.757682e-03
## Battle Princess Madelyn                              0.0004164931 3.757682e-03
## Before We Leave                                      0.0004164931 8.384742e-03
## Blackguards 2                                        0.0004164931 6.026689e-04
## Blue Prince                                          0.0004164931 1.166176e-01
## Conarium                                             0.0004164931 6.026689e-04
## DEADCRAFT                                            0.0004164931 1.184052e-02
## Dragon Age™: Inquisition                             0.0004164931 2.359591e-03
## DRAGON QUEST BUILDERS™                               0.0004164931 4.406076e-03
## Earth Atlantis                                       0.0004164931 5.501176e-03
## Fabledom                                             0.0004164931 1.166176e-01
## Fall of Porcupine                                    0.0004164931 1.166176e-01
## Flinthook                                            0.0004164931 3.757682e-03
## Genesis Alpha One                                    0.0004164931 5.262675e-03
## HARDCORE MECHA                                       0.0004164931 5.617038e-03
## Hellblade: Senua’s Sacrifice                         0.0004164931 3.757682e-03
## Help Will Come Tomorrow                              0.0004164931 5.501176e-03
## Hoa                                                  0.0004164931 3.757682e-03
## HOT WHEELS UNLEASHED™                                0.0004164931 1.307665e-04
## LOST SPHEAR                                          0.0004164931 5.620523e-03
## Magicka 2                                            0.0004164931 5.661506e-03
## Monster Energy Supercross - The Official Videogame 2 0.0004164931 1.307665e-04
## Monster Energy Supercross - The Official Videogame 4 0.0004164931 3.842487e-02
## Monster Truck Championship                           0.0004164931 3.757682e-03
## Nano Assault NEO-X                                   0.0004164931 3.757682e-03
## NOBUNAGA'S AMBITION: Sphere of Influence - Ascension 0.0004164931 6.204651e-03
## Pillars of Eternity II: Deadfire - Ultimate Edition  0.0004164931 3.757682e-03
## Please Fix The Road                                  0.0004164931 1.166176e-01
## Raiden IV x MIKADO remix                             0.0004164931 1.113768e-02
## Resistance: Fall of Man™                             0.0004164931 1.092093e-02
## REVEIL                                               0.0004164931 2.883022e-02
## River City: Rival Showdown                           0.0004164931 3.757682e-03
## Russian Subway Dogs                                  1.0000000000 5.428848e-28
## SAMURAI WARRIORS 4                                   0.0004164931 1.173451e-02
## Shadowrun: Dragonfall - Director's Cut               0.0004164931 9.767908e-03
## SILENT HILL 2                                        0.0004164931 1.166176e-01
## SILT                                                 0.0004164931 1.184052e-02
## Sophstar                                             0.0004164931 9.205287e-03
## Soulstice                                            0.0004164931 3.427864e-02
## Splasher                                             0.0004164931 5.501176e-03
## STAR WARS Jedi: Fallen Order™                        0.0004164931 7.315840e-04
## STAR WARS™ Republic Commando™                        0.0004164931 5.617038e-03
## Strayed Lights                                       0.0004164931 3.109284e-07
## Styx: Shards of Darkness                             0.0004164931 3.757682e-03
## The Legend of Heroes: Trails of Cold Steel II        0.0004164931 1.138280e-02
## The Office Quest                                     0.0004164931 3.757682e-03
## ULTIMATE MARVEL VS, CAPCOM 3                         0.0004164931 3.757682e-03
## Unbound: Worlds Apart                                0.0004164931 9.205287e-03
## Unplugged - Air Guitar                               0.0004164931 1.166176e-01
## Weedcraft Inc                                        0.0004164931 9.205287e-03
## 2014-04-16                                           0.0004164931 1.092093e-02
## 2014-10-29                                           0.0004164931 3.757682e-03
## 2014-11-19                                           0.0004164931 1.173451e-02
## 2014-11-20                                           0.0004164931 2.359591e-03
## 2015-05-26                                           0.0004164931 5.661506e-03
## 2016-10-13                                           0.0004164931 3.757682e-03
## 2016-11-11                                           0.0004164931 1.138280e-02
## 2016-11-15                                           0.0004164931 4.406076e-03
## 2016-11-25                                           0.0004164931 6.204651e-03
## 2016-12-04                                           0.0004164931 3.757682e-03
## 2017-03-14                                           0.0004164931 3.757682e-03
## 2017-04-18                                           0.0004164931 3.757682e-03
## 2017-08-08                                           0.0004164931 3.757682e-03
## 2017-09-15                                           0.0004164931 6.026689e-04
## 2017-09-27                                           0.0004164931 5.501176e-03
## 2018-01-23                                           0.0004164931 5.620523e-03
## 2018-06-01                                           0.0004164931 5.501176e-03
## 2019-01-29                                           0.0004164931 5.262675e-03
## 2019-02-08                                           0.0004164931 1.307665e-04
## 2019-02-12                                           0.0004164931 6.026689e-04
## 2019-10-18                                           0.0004164931 3.757682e-03
## 2020-01-14                                           0.0004164931 5.617038e-03
## 2020-01-28                                           0.0004164931 3.757682e-03
## 2020-04-21                                           0.0004164931 5.501176e-03
## 2020-06-03                                           0.0004164931 3.757682e-03
## 2020-10-15                                           0.0004164931 3.757682e-03
## 2021-03-11                                           0.0004164931 3.842487e-02
## 2021-04-06                                           0.0004164931 5.617038e-03
## 2021-06-11                                           0.0004164931 7.315840e-04
## 2021-09-27                                           0.0004164931 3.757682e-03
## 2021-09-30                                           0.0004164931 1.307665e-04
## 2022-02-09                                           0.0004164931 9.205287e-03
## 2022-04-05                                           0.0004164931 8.384742e-03
## 2022-05-19                                           0.0004164931 1.184052e-02
## 2022-06-01                                           0.0004164931 1.184052e-02
## 2022-06-21                                           0.0004164931 9.767908e-03
## 2022-09-20                                           0.0004164931 3.427864e-02
## 2022-10-28                                           0.0004164931 9.205287e-03
## 2023-02-03                                           0.0004164931 1.113768e-02
## 2023-02-22                                           0.0004164931 1.166176e-01
## 2023-04-25                                           0.0004164931 3.109284e-07
## 2023-06-15                                           0.0004164931 1.166176e-01
## 2023-06-28                                           1.0000000000 5.511377e-28
## 2023-10-12                                           0.0004164931 3.757682e-03
## 2023-11-18                                           0.0004164931 9.205287e-03
## 2024-03-06                                           0.0004164931 2.883022e-02
## 2024-05-16                                           0.0004164931 1.166176e-01
## 2024-09-12                                           0.0004164931 1.166176e-01
## 2024-10-08                                           0.0004164931 1.166176e-01
## 2025-04-10                                           0.0004164931 1.166176e-01
## Action / Adventure / Arcade                          0.0004164931 3.757682e-03
## Action / Shooter / Arcade                            0.0004164931 3.757682e-03
## Action/Adventure                                     0.0013026487 8.747481e-03
## Action/Adventure/Co-op                               0.0004164931 5.661506e-03
## Action/Adventure/Strategy                            0.0004164931 1.173451e-02
## Action/Adventure/VR                                  0.0004164931 3.757682e-03
## Action/Beat'em up/RPG                                0.0004164931 3.757682e-03
## Action/Horror/Survival                               0.0004164931 1.166176e-01
## Action/Platformer                                    0.0008503401 1.477085e-02
## Action/Platformer/Roguelike                          0.0004164931 3.757682e-03
## Action/Role playing games                            0.0004164931 1.166176e-01
## Action/Shooter                                       0.0017746229 3.187449e-02
## Action/Shooter/Adventure                             0.0004164931 2.359591e-03
## Action/Shooter/Arcade                                0.0008503401 1.477085e-02
## Action/Stealth/Adventure                             0.0004164931 3.757682e-03
## Action/Survival/RPG                                  0.0004164931 1.184052e-02
## Adventure                                            0.0008503401 2.131819e-02
## Adventure/Horror                                     0.0004164931 1.166176e-01
## Adventure/Narrative/Puzzle                           0.0004164931 1.166176e-01
## Arcade/Action                                        1.0000000000 5.511377e-28
## Aventura/Narrativa/Misterio                          0.0004164931 3.757682e-03
## Fighting                                             0.0004164931 3.757682e-03
## Horror/Adventure                                     0.0008503401 1.927822e-02
## Music/rhythm                                         0.0004164931 1.166176e-01
## Platformer/Puzzle/Adventure                          0.0004164931 3.757682e-03
## Puzzle                                               0.0004164931 1.166176e-01
## Puzzle/Adventure/Comedy                              0.0004164931 3.757682e-03
## Puzzle/Adventure/Horror                              0.0004164931 1.184052e-02
## Racing                                               0.0004164931 3.842487e-02
## Racing/Arcade                                        0.0004164931 1.307665e-04
## Role playing games                                   0.0004164931 3.757682e-03
## Role playing games/JRPG                              0.0008503401 1.684399e-02
## Shooter                                              0.0004164931 5.262675e-03
## Simulación/Estrategia                                0.0004164931 9.205287e-03
## Simulación/Estrategia/Supervivencia                  0.0004164931 5.501176e-03
## Simulation/Role playing games                        0.0004164931 4.406076e-03
## Sports/Racing                                        0.0004164931 1.307665e-04
## Strategy/Card game/Role playing games                0.0004164931 3.757682e-03
## Strategy/Role playing games                          0.0004164931 6.026689e-04
## Strategy/Simulation                                  0.0004164931 6.204651e-03
## 11 Sheep                                             0.0004164931 3.757682e-03
## Arc System Works Co                                  0.0004164931 3.757682e-03
## ASPYR MEDIA                                          0.0004164931 5.617038e-03
## ASSEMBLE ENTERTAINMENT GMBH                          0.0004164931 1.166176e-01
## CE EUROPE LIMITED                                    0.0004164931 3.757682e-03
## DAEDALIC ENTERTAINMENT                               0.0008503401 1.927822e-02
## Dear Villagers                                       0.0004164931 1.166176e-01
## DIGERATI DISTRIBUTION                                0.0004164931 9.205287e-03
## EA Swiss Sarl                                        0.0008503401 2.919024e-03
## Embers SAS                                           0.0004164931 3.109284e-07
## Fireshine Games                                      0.0004164931 1.184052e-02
## HEADUP GAMES                                         0.0004164931 5.501176e-03
## ICEBERG INTERACTIVE BV                               0.0004164931 6.026689e-04
## KLABATER                                             0.0008503401 1.477085e-02
## Koei Tecmo Europe Ltd                                0.0008503401 1.786700e-02
## Konami                                               0.0004164931 1.166176e-01
## Marvelous Europe Limited                             0.0004164931 1.184052e-02
## Maximum Entertainment                                0.0004164931 3.427864e-02
## Microsoft Corporation                                0.0004164931 3.757682e-03
## MILESTONE SRL                                        0.0013026487 1.665106e-02
## Monster Bath Studios Inc,                            0.0004164931 3.757682e-03
## NACON SA                                             0.0008503401 7.671933e-03
## NINJA THEORY LIMITED                                 0.0004164931 3.757682e-03
## NIS America                                          0.0008503401 2.298897e-02
## PARADOX INTERACTIVE AB                               0.0008503401 1.546682e-02
## Plug In Digital                                      0.0004164931 5.501176e-03
## PM Studios                                           0.0004164931 3.757682e-03
## RAW FURY                                             0.0004164931 1.166176e-01
## RED ART GAMES                                        0.0004164931 9.205287e-03
## ROCKETPUNCH (BEIJING) TECHNOLOGY CO,, LTD,           0.0004164931 5.617038e-03
## SHIN EN MULTIMEDIA GMBH                              0.0004164931 3.757682e-03
## SILESIA GAMES SP, Z O,O,                             0.0004164931 1.166176e-01
## Sony Interactive Entertainment Europe                0.0004164931 1.092093e-02
## SPOOKY SQUID GAMES INC,                              1.0000000000 5.511377e-28
## Square Enix LTD                                      0.0008503401 1.019781e-02
## Team 17 Digital LTD                                  0.0008503401 1.374701e-02
## TRIBUTE GAMES                                        0.0004164931 3.757682e-03
## VERTIGO GAMES                                        0.0004164931 1.166176e-01
## WARNER BROS, INTERACTIVE                             0.0004164931 3.757682e-03
## PS Vita                                              0.0004164931 1.138280e-02
## PS3                                                  0.0008503401 2.311996e-02
## PS4                                                  0.0259740260 1.676960e-01
## PS4 / PS Vita                                        1.0000000000 5.511377e-28
## PS5                                                  0.0044798407 8.976149e-01
## PS5 / PS4                                            0.0044798407 9.113747e-02
##                                                             Dim 3        Dim 4
## Batman™: Arkham VR                                   1.161946e-02 1.659836e-02
## Battle Princess Madelyn                              1.161946e-02 1.659836e-02
## Before We Leave                                      3.301019e-03 1.578115e-02
## Blackguards 2                                        5.599192e-03 7.309122e-03
## Blue Prince                                          1.132089e-03 2.457674e-03
## Conarium                                             5.599192e-03 7.309122e-03
## DEADCRAFT                                            1.291787e-01 1.958373e-02
## Dragon Age™: Inquisition                             2.398067e-06 3.299366e-03
## DRAGON QUEST BUILDERS™                               3.213232e-03 1.232366e-02
## Earth Atlantis                                       1.169172e-03 1.813790e-03
## Fabledom                                             1.132089e-03 2.457674e-03
## Fall of Porcupine                                    1.132089e-03 2.457674e-03
## Flinthook                                            1.161946e-02 1.659836e-02
## Genesis Alpha One                                    1.270833e-03 7.400969e-05
## HARDCORE MECHA                                       9.503417e-03 5.243133e-03
## Hellblade: Senua’s Sacrifice                         1.161946e-02 1.659836e-02
## Help Will Come Tomorrow                              1.169172e-03 1.813790e-03
## Hoa                                                  1.161946e-02 1.659836e-02
## HOT WHEELS UNLEASHED™                                6.262725e-03 8.220835e-03
## LOST SPHEAR                                          8.593298e-05 8.301926e-03
## Magicka 2                                            1.952625e-03 1.739620e-03
## Monster Energy Supercross - The Official Videogame 2 6.262725e-03 8.220835e-03
## Monster Energy Supercross - The Official Videogame 4 5.600756e-04 7.159216e-04
## Monster Truck Championship                           1.161946e-02 1.659836e-02
## Nano Assault NEO-X                                   1.161946e-02 1.659836e-02
## NOBUNAGA'S AMBITION: Sphere of Influence - Ascension 4.294797e-02 5.107057e-02
## Pillars of Eternity II: Deadfire - Ultimate Edition  1.161946e-02 1.659836e-02
## Please Fix The Road                                  1.132089e-03 2.457674e-03
## Raiden IV x MIKADO remix                             7.995688e-02 3.436210e-03
## Resistance: Fall of Man™                             5.099470e-02 2.195214e-01
## REVEIL                                               1.042333e-03 1.376969e-03
## River City: Rival Showdown                           1.161946e-02 1.659836e-02
## Russian Subway Dogs                                  2.106809e-29 6.243453e-30
## SAMURAI WARRIORS 4                                   1.126096e-01 3.870204e-01
## Shadowrun: Dragonfall - Director's Cut               5.775470e-02 3.086694e-03
## SILENT HILL 2                                        1.132089e-03 2.457674e-03
## SILT                                                 1.291787e-01 1.958373e-02
## Sophstar                                             4.727478e-02 2.883247e-03
## Soulstice                                            2.446919e-03 2.392509e-04
## Splasher                                             1.169172e-03 1.813790e-03
## STAR WARS Jedi: Fallen Order™                        1.837681e-02 4.956982e-04
## STAR WARS™ Republic Commando™                        9.503417e-03 5.243133e-03
## Strayed Lights                                       3.606153e-05 2.346857e-03
## Styx: Shards of Darkness                             1.161946e-02 1.659836e-02
## The Legend of Heroes: Trails of Cold Steel II        5.121008e-02 8.472618e-04
## The Office Quest                                     1.161946e-02 1.659836e-02
## ULTIMATE MARVEL VS, CAPCOM 3                         1.161946e-02 1.659836e-02
## Unbound: Worlds Apart                                4.727478e-02 2.883247e-03
## Unplugged - Air Guitar                               1.132089e-03 2.457674e-03
## Weedcraft Inc                                        4.727478e-02 2.883247e-03
## 2014-04-16                                           5.099470e-02 2.195214e-01
## 2014-10-29                                           1.161946e-02 1.659836e-02
## 2014-11-19                                           1.126096e-01 3.870204e-01
## 2014-11-20                                           2.398067e-06 3.299366e-03
## 2015-05-26                                           1.952625e-03 1.739620e-03
## 2016-10-13                                           1.161946e-02 1.659836e-02
## 2016-11-11                                           5.121008e-02 8.472618e-04
## 2016-11-15                                           3.213232e-03 1.232366e-02
## 2016-11-25                                           4.294797e-02 5.107057e-02
## 2016-12-04                                           1.161946e-02 1.659836e-02
## 2017-03-14                                           1.161946e-02 1.659836e-02
## 2017-04-18                                           1.161946e-02 1.659836e-02
## 2017-08-08                                           1.161946e-02 1.659836e-02
## 2017-09-15                                           5.599192e-03 7.309122e-03
## 2017-09-27                                           1.169172e-03 1.813790e-03
## 2018-01-23                                           8.593298e-05 8.301926e-03
## 2018-06-01                                           1.169172e-03 1.813790e-03
## 2019-01-29                                           1.270833e-03 7.400969e-05
## 2019-02-08                                           6.262725e-03 8.220835e-03
## 2019-02-12                                           5.599192e-03 7.309122e-03
## 2019-10-18                                           1.161946e-02 1.659836e-02
## 2020-01-14                                           9.503417e-03 5.243133e-03
## 2020-01-28                                           1.161946e-02 1.659836e-02
## 2020-04-21                                           1.169172e-03 1.813790e-03
## 2020-06-03                                           1.161946e-02 1.659836e-02
## 2020-10-15                                           1.161946e-02 1.659836e-02
## 2021-03-11                                           5.600756e-04 7.159216e-04
## 2021-04-06                                           9.503417e-03 5.243133e-03
## 2021-06-11                                           1.837681e-02 4.956982e-04
## 2021-09-27                                           1.161946e-02 1.659836e-02
## 2021-09-30                                           6.262725e-03 8.220835e-03
## 2022-02-09                                           4.727478e-02 2.883247e-03
## 2022-04-05                                           3.301019e-03 1.578115e-02
## 2022-05-19                                           1.291787e-01 1.958373e-02
## 2022-06-01                                           1.291787e-01 1.958373e-02
## 2022-06-21                                           5.775470e-02 3.086694e-03
## 2022-09-20                                           2.446919e-03 2.392509e-04
## 2022-10-28                                           4.727478e-02 2.883247e-03
## 2023-02-03                                           7.995688e-02 3.436210e-03
## 2023-02-22                                           1.132089e-03 2.457674e-03
## 2023-04-25                                           3.606153e-05 2.346857e-03
## 2023-06-15                                           1.132089e-03 2.457674e-03
## 2023-06-28                                           2.183756e-29 5.851492e-30
## 2023-10-12                                           1.161946e-02 1.659836e-02
## 2023-11-18                                           4.727478e-02 2.883247e-03
## 2024-03-06                                           1.042333e-03 1.376969e-03
## 2024-05-16                                           1.132089e-03 2.457674e-03
## 2024-09-12                                           1.132089e-03 2.457674e-03
## 2024-10-08                                           1.132089e-03 2.457674e-03
## 2025-04-10                                           1.132089e-03 2.457674e-03
## Action / Adventure / Arcade                          1.161946e-02 1.659836e-02
## Action / Shooter / Arcade                            1.161946e-02 1.659836e-02
## Action/Adventure                                     1.113759e-02 3.987920e-05
## Action/Adventure/Co-op                               1.952625e-03 1.739620e-03
## Action/Adventure/Strategy                            1.126096e-01 3.870204e-01
## Action/Adventure/VR                                  1.161946e-02 1.659836e-02
## Action/Beat'em up/RPG                                1.161946e-02 1.659836e-02
## Action/Horror/Survival                               1.132089e-03 2.457674e-03
## Action/Platformer                                    3.231602e-02 6.297065e-05
## Action/Platformer/Roguelike                          1.161946e-02 1.659836e-02
## Action/Role playing games                            1.132089e-03 2.457674e-03
## Action/Shooter                                       3.515574e-02 1.454238e-01
## Action/Shooter/Adventure                             2.398067e-06 3.299366e-03
## Action/Shooter/Arcade                                3.231602e-02 6.297065e-05
## Action/Stealth/Adventure                             1.161946e-02 1.659836e-02
## Action/Survival/RPG                                  1.291787e-01 1.958373e-02
## Adventure                                            1.396610e-01 6.654014e-03
## Adventure/Horror                                     1.132089e-03 2.457674e-03
## Adventure/Narrative/Puzzle                           1.132089e-03 2.457674e-03
## Arcade/Action                                        2.183756e-29 5.851492e-30
## Aventura/Narrativa/Misterio                          1.161946e-02 1.659836e-02
## Fighting                                             1.161946e-02 1.659836e-02
## Horror/Adventure                                     5.856102e-03 7.672068e-03
## Music/rhythm                                         1.132089e-03 2.457674e-03
## Platformer/Puzzle/Adventure                          1.161946e-02 1.659836e-02
## Puzzle                                               1.132089e-03 2.457674e-03
## Puzzle/Adventure/Comedy                              1.161946e-02 1.659836e-02
## Puzzle/Adventure/Horror                              1.291787e-01 1.958373e-02
## Racing                                               5.600756e-04 7.159216e-04
## Racing/Arcade                                        6.262725e-03 8.220835e-03
## Role playing games                                   1.161946e-02 1.659836e-02
## Role playing games/JRPG                              2.832381e-02 7.377302e-03
## Shooter                                              1.270833e-03 7.400969e-05
## Simulación/Estrategia                                4.727478e-02 2.883247e-03
## Simulación/Estrategia/Supervivencia                  1.169172e-03 1.813790e-03
## Simulation/Role playing games                        3.213232e-03 1.232366e-02
## Sports/Racing                                        6.262725e-03 8.220835e-03
## Strategy/Card game/Role playing games                1.161946e-02 1.659836e-02
## Strategy/Role playing games                          5.599192e-03 7.309122e-03
## Strategy/Simulation                                  4.294797e-02 5.107057e-02
## 11 Sheep                                             1.161946e-02 1.659836e-02
## Arc System Works Co                                  1.161946e-02 1.659836e-02
## ASPYR MEDIA                                          9.503417e-03 5.243133e-03
## ASSEMBLE ENTERTAINMENT GMBH                          1.132089e-03 2.457674e-03
## CE EUROPE LIMITED                                    1.161946e-02 1.659836e-02
## DAEDALIC ENTERTAINMENT                               5.856102e-03 7.672068e-03
## Dear Villagers                                       1.132089e-03 2.457674e-03
## DIGERATI DISTRIBUTION                                4.727478e-02 2.883247e-03
## EA Swiss Sarl                                        9.166753e-03 6.315583e-04
## Embers SAS                                           3.606153e-05 2.346857e-03
## Fireshine Games                                      1.291787e-01 1.958373e-02
## HEADUP GAMES                                         1.169172e-03 1.813790e-03
## ICEBERG INTERACTIVE BV                               5.599192e-03 7.309122e-03
## KLABATER                                             3.231602e-02 6.297065e-05
## Koei Tecmo Europe Ltd                                1.503919e-01 3.671272e-01
## Konami                                               1.132089e-03 2.457674e-03
## Marvelous Europe Limited                             1.291787e-01 1.958373e-02
## Maximum Entertainment                                2.446919e-03 2.392509e-04
## Microsoft Corporation                                1.161946e-02 1.659836e-02
## MILESTONE SRL                                        1.150367e-02 1.504865e-02
## Monster Bath Studios Inc,                            1.161946e-02 1.659836e-02
## NACON SA                                             2.372307e-02 3.388833e-02
## NINJA THEORY LIMITED                                 1.161946e-02 1.659836e-02
## NIS America                                          1.322720e-01 4.445344e-04
## PARADOX INTERACTIVE AB                               4.131633e-02 9.789911e-05
## Plug In Digital                                      1.169172e-03 1.813790e-03
## PM Studios                                           1.161946e-02 1.659836e-02
## RAW FURY                                             1.132089e-03 2.457674e-03
## RED ART GAMES                                        4.727478e-02 2.883247e-03
## ROCKETPUNCH (BEIJING) TECHNOLOGY CO,, LTD,           9.503417e-03 5.243133e-03
## SHIN EN MULTIMEDIA GMBH                              1.161946e-02 1.659836e-02
## SILESIA GAMES SP, Z O,O,                             1.132089e-03 2.457674e-03
## Sony Interactive Entertainment Europe                5.099470e-02 2.195214e-01
## SPOOKY SQUID GAMES INC,                              2.183756e-29 5.851492e-30
## Square Enix LTD                                      1.147528e-03 2.085322e-02
## Team 17 Digital LTD                                  2.426985e-04 6.989502e-03
## TRIBUTE GAMES                                        1.161946e-02 1.659836e-02
## VERTIGO GAMES                                        1.132089e-03 2.457674e-03
## WARNER BROS, INTERACTIVE                             1.161946e-02 1.659836e-02
## PS Vita                                              5.121008e-02 8.472618e-04
## PS3                                                  1.608643e-01 6.071392e-01
## PS4                                                  3.017006e-01 3.225309e-01
## PS4 / PS Vita                                        2.183756e-29 5.851492e-30
## PS5                                                  5.069840e-03 8.236705e-03
## PS5 / PS4                                            5.785014e-01 6.563338e-02
##                                                             Dim 5
## Batman™: Arkham VR                                   7.734375e-04
## Battle Princess Madelyn                              7.734375e-04
## Before We Leave                                      3.899842e-03
## Blackguards 2                                        2.424820e-04
## Blue Prince                                          3.278831e-04
## Conarium                                             2.424820e-04
## DEADCRAFT                                            3.854145e-02
## Dragon Age™: Inquisition                             3.747282e-03
## DRAGON QUEST BUILDERS™                               3.370787e-02
## Earth Atlantis                                       7.929197e-03
## Fabledom                                             3.278831e-04
## Fall of Porcupine                                    3.278831e-04
## Flinthook                                            7.734375e-04
## Genesis Alpha One                                    2.264162e-03
## HARDCORE MECHA                                       4.757778e-04
## Hellblade: Senua’s Sacrifice                         7.734375e-04
## Help Will Come Tomorrow                              7.929197e-03
## Hoa                                                  7.734375e-04
## HOT WHEELS UNLEASHED™                                2.784371e-04
## LOST SPHEAR                                          1.173332e-01
## Magicka 2                                            1.025487e-04
## Monster Energy Supercross - The Official Videogame 2 2.784371e-04
## Monster Energy Supercross - The Official Videogame 4 1.714852e-05
## Monster Truck Championship                           7.734375e-04
## Nano Assault NEO-X                                   7.734375e-04
## NOBUNAGA'S AMBITION: Sphere of Influence - Ascension 1.462004e-03
## Pillars of Eternity II: Deadfire - Ultimate Edition  7.734375e-04
## Please Fix The Road                                  3.278831e-04
## Raiden IV x MIKADO remix                             5.945189e-02
## Resistance: Fall of Man™                             7.752660e-04
## REVEIL                                               4.058041e-05
## River City: Rival Showdown                           7.734375e-04
## Russian Subway Dogs                                  2.668043e-31
## SAMURAI WARRIORS 4                                   7.725020e-03
## Shadowrun: Dragonfall - Director's Cut               1.493747e-03
## SILENT HILL 2                                        3.278831e-04
## SILT                                                 3.854145e-02
## Sophstar                                             1.824781e-02
## Soulstice                                            1.359542e-03
## Splasher                                             7.929197e-03
## STAR WARS Jedi: Fallen Order™                        7.452757e-03
## STAR WARS™ Republic Commando™                        4.757778e-04
## Strayed Lights                                       2.442072e-03
## Styx: Shards of Darkness                             7.734375e-04
## The Legend of Heroes: Trails of Cold Steel II        6.082774e-01
## The Office Quest                                     7.734375e-04
## ULTIMATE MARVEL VS, CAPCOM 3                         7.734375e-04
## Unbound: Worlds Apart                                1.824781e-02
## Unplugged - Air Guitar                               3.278831e-04
## Weedcraft Inc                                        1.824781e-02
## 2014-04-16                                           7.752660e-04
## 2014-10-29                                           7.734375e-04
## 2014-11-19                                           7.725020e-03
## 2014-11-20                                           3.747282e-03
## 2015-05-26                                           1.025487e-04
## 2016-10-13                                           7.734375e-04
## 2016-11-11                                           6.082774e-01
## 2016-11-15                                           3.370787e-02
## 2016-11-25                                           1.462004e-03
## 2016-12-04                                           7.734375e-04
## 2017-03-14                                           7.734375e-04
## 2017-04-18                                           7.734375e-04
## 2017-08-08                                           7.734375e-04
## 2017-09-15                                           2.424820e-04
## 2017-09-27                                           7.929197e-03
## 2018-01-23                                           1.173332e-01
## 2018-06-01                                           7.929197e-03
## 2019-01-29                                           2.264162e-03
## 2019-02-08                                           2.784371e-04
## 2019-02-12                                           2.424820e-04
## 2019-10-18                                           7.734375e-04
## 2020-01-14                                           4.757778e-04
## 2020-01-28                                           7.734375e-04
## 2020-04-21                                           7.929197e-03
## 2020-06-03                                           7.734375e-04
## 2020-10-15                                           7.734375e-04
## 2021-03-11                                           1.714852e-05
## 2021-04-06                                           4.757778e-04
## 2021-06-11                                           7.452757e-03
## 2021-09-27                                           7.734375e-04
## 2021-09-30                                           2.784371e-04
## 2022-02-09                                           1.824781e-02
## 2022-04-05                                           3.899842e-03
## 2022-05-19                                           3.854145e-02
## 2022-06-01                                           3.854145e-02
## 2022-06-21                                           1.493747e-03
## 2022-09-20                                           1.359542e-03
## 2022-10-28                                           1.824781e-02
## 2023-02-03                                           5.945189e-02
## 2023-02-22                                           3.278831e-04
## 2023-04-25                                           2.442072e-03
## 2023-06-15                                           3.278831e-04
## 2023-06-28                                           3.081585e-31
## 2023-10-12                                           7.734375e-04
## 2023-11-18                                           1.824781e-02
## 2024-03-06                                           4.058041e-05
## 2024-05-16                                           3.278831e-04
## 2024-09-12                                           3.278831e-04
## 2024-10-08                                           3.278831e-04
## 2025-04-10                                           3.278831e-04
## Action / Adventure / Arcade                          7.734375e-04
## Action / Shooter / Arcade                            7.734375e-04
## Action/Adventure                                     1.035506e-02
## Action/Adventure/Co-op                               1.025487e-04
## Action/Adventure/Strategy                            7.725020e-03
## Action/Adventure/VR                                  7.734375e-04
## Action/Beat'em up/RPG                                7.734375e-04
## Action/Horror/Survival                               3.278831e-04
## Action/Platformer                                    2.564052e-02
## Action/Platformer/Roguelike                          7.734375e-04
## Action/Role playing games                            3.278831e-04
## Action/Shooter                                       1.629755e-03
## Action/Shooter/Adventure                             3.747282e-03
## Action/Shooter/Arcade                                2.564052e-02
## Action/Stealth/Adventure                             7.734375e-04
## Action/Survival/RPG                                  3.854145e-02
## Adventure                                            4.072770e-02
## Adventure/Horror                                     3.278831e-04
## Adventure/Narrative/Puzzle                           3.278831e-04
## Arcade/Action                                        3.081585e-31
## Aventura/Narrativa/Misterio                          7.734375e-04
## Fighting                                             7.734375e-04
## Horror/Adventure                                     2.457433e-04
## Music/rhythm                                         3.278831e-04
## Platformer/Puzzle/Adventure                          7.734375e-04
## Puzzle                                               3.278831e-04
## Puzzle/Adventure/Comedy                              7.734375e-04
## Puzzle/Adventure/Horror                              3.854145e-02
## Racing                                               1.714852e-05
## Racing/Arcade                                        2.784371e-04
## Role playing games                                   7.734375e-04
## Role playing games/JRPG                              6.430832e-01
## Shooter                                              2.264162e-03
## Simulación/Estrategia                                1.824781e-02
## Simulación/Estrategia/Supervivencia                  7.929197e-03
## Simulation/Role playing games                        3.370787e-02
## Sports/Racing                                        2.784371e-04
## Strategy/Card game/Role playing games                7.734375e-04
## Strategy/Role playing games                          2.424820e-04
## Strategy/Simulation                                  1.462004e-03
## 11 Sheep                                             7.734375e-04
## Arc System Works Co                                  7.734375e-04
## ASPYR MEDIA                                          4.757778e-04
## ASSEMBLE ENTERTAINMENT GMBH                          3.278831e-04
## CE EUROPE LIMITED                                    7.734375e-04
## DAEDALIC ENTERTAINMENT                               2.457433e-04
## Dear Villagers                                       3.278831e-04
## DIGERATI DISTRIBUTION                                1.824781e-02
## EA Swiss Sarl                                        1.111144e-02
## Embers SAS                                           2.442072e-03
## Fireshine Games                                      3.854145e-02
## HEADUP GAMES                                         7.929197e-03
## ICEBERG INTERACTIVE BV                               2.424820e-04
## KLABATER                                             2.564052e-02
## Koei Tecmo Europe Ltd                                8.119880e-03
## Konami                                               3.278831e-04
## Marvelous Europe Limited                             3.854145e-02
## Maximum Entertainment                                1.359542e-03
## Microsoft Corporation                                7.734375e-04
## MILESTONE SRL                                        4.890603e-04
## Monster Bath Studios Inc,                            7.734375e-04
## NACON SA                                             1.579101e-03
## NINJA THEORY LIMITED                                 7.734375e-04
## NIS America                                          5.349483e-01
## PARADOX INTERACTIVE AB                               1.214314e-03
## Plug In Digital                                      7.929197e-03
## PM Studios                                           7.734375e-04
## RAW FURY                                             3.278831e-04
## RED ART GAMES                                        1.824781e-02
## ROCKETPUNCH (BEIJING) TECHNOLOGY CO,, LTD,           4.757778e-04
## SHIN EN MULTIMEDIA GMBH                              7.734375e-04
## SILESIA GAMES SP, Z O,O,                             3.278831e-04
## Sony Interactive Entertainment Europe                7.752660e-04
## SPOOKY SQUID GAMES INC,                              3.081585e-31
## Square Enix LTD                                      1.412933e-01
## Team 17 Digital LTD                                  6.179627e-03
## TRIBUTE GAMES                                        7.734375e-04
## VERTIGO GAMES                                        3.278831e-04
## WARNER BROS, INTERACTIVE                             7.734375e-04
## PS Vita                                              6.082774e-01
## PS3                                                  6.836904e-03
## PS4                                                  6.816069e-03
## PS4 / PS Vita                                        3.081585e-31
## PS5                                                  4.983691e-04
## PS5 / PS4                                            5.858144e-02

Contribuciones

resenas_de_juegos_electronicos_depurados_V2 <- read_excel("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados_V2.xlsx")
resenas_de_juegos_electronicos_depurados_V2$lanzamiento <- as.Date(resenas_de_juegos_electronicos_depurados_V2$lanzamiento, origin = "1899-12-30")

set.seed(780729)
resenas_de_juegos_electronicos_depurados_V2.active<-resenas_de_juegos_electronicos_depurados_V2[sample(1:nrow(resenas_de_juegos_electronicos_depurados_V2), 1000), 1:5]

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

fviz_contrib(res.mca, choice = "var", axes = 1, top = 15)

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

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

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

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

Biplot con Contribuciones

resenas_de_juegos_electronicos_depurados_V2 <- read_excel("C:/Users/juane_xt82f/OneDrive/Escritorio/GSD_6/resenas_de_juegos_electronicos_depurados_V2.xlsx")
resenas_de_juegos_electronicos_depurados_V2$lanzamiento <- as.Date(resenas_de_juegos_electronicos_depurados_V2$lanzamiento, origin = "1899-12-30")

set.seed(780729)
resenas_de_juegos_electronicos_depurados_V2.active<-resenas_de_juegos_electronicos_depurados_V2[sample(1:nrow(resenas_de_juegos_electronicos_depurados_V2),20), 1:5]

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

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

Fase 4 [Conglomerados]

El análisis de conglomerados busca agrupar los videojuegos en subconjuntos homogéneos según sus características multivariantes, como puntuación, ventas, género y plataforma. Utilizando algoritmos como K-means o jerárquicos, se identifican grupos de títulos que comparten similitudes, lo cual ayuda a entender la segmentación del mercado, identificar nichos o establecer perfiles de videojuegos más exitosos. Los conglomerados pueden usarse para enfocar estrategias de desarrollo o mercadeo según los grupos detectados.

4.1. Objetivos

En esta cuarta etapa del estudio se llevarán a cabo cálculos, representaciones gráficas e interpretaciones empleando el conjunto de datos previamente procesado en las Fases (1, 2 y 3). El objetivo principal de esta etapa es aplicar el Análisis de Conglomerados, tanto en su modalidad jerárquica, a través de la construcción e interpretación de dendrogramas, como en su versión no jerárquica, mediante la aplicación del método de K-medias, con el propósito de identificar grupos homogéneos dentro del conjunto de observaciones.

4.2. Agrupación Jerárquica

Campo Clasificador

Optimización de Mojena

Unión Simple
Unión Completa
Unión Promedio

Dendogramas Optimizados

Enlace Simple
Enlace Completo
Enlace Promedio

4.3. Agrupación No-Jerárquica

K-Óptimo

Elbow
Silhouette
Gap Statistic
Majority Rule

Resultados K-Means

K-Óptimo [El_Ma-Rul 3]
K-Óptimo [sil 4]

Gráficos K-Means

K-Óptimo [Elb_Ma-Rul 3]
K-Óptimo [sil 4]

Fase 5 [Regresiones]

El análisis de regresión se emplea para modelar las relaciones entre una variable dependiente y una o varias variables independientes dentro del conjunto de datos. En el contexto de videojuegos, es común intentar predecir las ventas en función de variables como el año de lanzamiento, la puntuación de usuarios, la plataforma, o el género. Se interpreta qué factores tienen más influencia sobre el éxito comercial del videojuego y cómo pueden usarse estos hallazgos para la toma de decisiones en la industria.

5.1. Objetivos

Este estudio tiene como propósito establecer la relación entre dos o más variables mediante la obtención de información sobre una de ellas, basada en el conocimiento de los valores de las otras. Las relaciones establecidas son de carácter no determinístico, es decir, se plantearán relaciones probabilísticas y se implementarán procedimientos para realizar inferencias sobre los modelos utilizados. Además, se obtendrán medidas cuantitativas que indiquen el grado de relación entre las variables. Los modelos considerados en este trabajo corresponden a casos específicos del modelo lineal generalizado: Regresión Lineal Simple, Regresión Lineal Múltiple* y Regresión Logística. Cada modelo será descrito teóricamente en su respectiva sección, y se aplicará a un conjunto de datos específico descrito en la sección 2.

5.2. Regresión Lineal Simple

Resumen Frecuencia cardiaca máxima
Resumen de Colesterol Sérico
Diagrama de Dispersión: Frecuencia y Colesterol
Diagramas Totales de Dispersión

5.2.2 Formulación del modelo de RLS entre las variables de estudio.

Coeficientes del Modelo RLS
Resumen Estadístico del Modelo RLS
Tabla ANOVA para el Modelo RLS

5.2.3. Análisis del modelo RLS.

Intervalo de Confianza para B1
Predicciones y sus Intervalos de Predicción
Predicciones y sus Intervalos de Confianza

5.3. Regresión Lineal Múltiple

5.3.1. Resumen estadístico de las variables de estudio

5.3.2 Formulación del modelo de RLM entre las variables de estudio.

5.4. Regresión Logística Simple

5.4.1 Planteamiento y desarrollo

Resumen y Boxplot Colesterol Sérico
Histograma de Colesterol Sérico
Resumen y Diagrama de Barras de Target
Resumen y Diagrama de Cajas Conjunto

5.4.2. Formulación del modelo de RLogS entre las variables de estudio

Coeficientes del Modelo RLogS
Resumen Estadístico del Modelo RLogS

5.4.3. Análisis del modelo RLogS

Variable Predictora igual a Cero
Probabilidades Estimadas
Gráfica del Modelo RLogS

5.5. Ajuste de Varianza

6. Conclusiones

7. Bibliografía

Aldás, J., & Uriel, E. (2017). Análisis multivariante aplicado con R (2nd ed.). ALFACENTAURO.
LS0tDQp0aXRsZTogIioqVEZDX0dERF8yMDI1XzJfR1JVUE9fNioqIg0Kc3VidGl0bGU6ICJFc3R1ZGlvIGRlIEFuw6FsaXNpcyBNdWx0aXZhcmlhZG8gY29uIGJhc2UgZW4gdW4gY29uanVudG8gZGUgZGF0b3Mgc29icmUgcmVnaXN0cm9zIGRlIHZpZGVvanVlZ29zIHJlbGFjaW9uYWRvcyBhIFBsYXlTdGF0aW9uLiINCmF1dGhvcjogIlBvcjogSnVhbiBFc3RlYmFuIExvYWl6YSBHb256YWxleiAoanVhbi5lLmxvYWl6YUBjb3JyZW91bml2YWxsZS5lZHUuY28pDQpTdGVwaGFuaSBDb3JyZWEgTWVzYSAoc3RlcGhhbmkuY29ycmVhQGNvcnJlb3VuaXZhbGxlLmVkdS5jbykgTHVuYSBTb2ZpYSBCZXJtdWRleiAobHVuYS5iZXJtdWRlekBjb3JyZW91bml2YWxsZS5lZHUuY28pDQpKb2hhbiBDYXJkZW5hcyBUcnVqaWxsbyAoY2FyZGVuYXMuam9oYW5AY29ycmVvdW5pdmFsbGUuZWR1LmNvKSBKdWFuIE1hbnVlbCBIdXJ0YWRvIEZyYW5jbyAoanVhbi5odXJ0YWRvLmZyYW5jb0Bjb3JyZW91bml2YWxsZS5lZHUuY28pIg0KZGF0ZTogIlRyYWJham8gZWxhYm9yYWRvIGVuIGVsIHBlcmlvZG8gYWNhZMOpbWljbyBjb21wcmVuZGlkbyBlbnRyZSBhZ29zdG8geSBkaWNpZW1icmUgZGVsIGHDsW8gMjAyNSwgY29tbyBhY3RpdmlkYWQgZm9ybWF0aXZhIHkgZXZhbHVhdGl2YSBkZWwgY3Vyc28gR2VzdGnDs24gZGUgRGF0b3MgcGFyYSBpbmdlbmllcsOtYSBJbmR1c3RyaWFsLiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6IGx1bWVuDQpiaWJsaW9ncmFwaHk6IGJpYmxpb2dyYWZpYV9NRS5iaWINCmNzbDogYXBhLmNzbA0KbGluay1jaXRhdGlvbnM6IHllcw0KLS0tDQo8IS0tIENvbmZpZ3VyYWNpw7NuIEdsb2JhbCBkZSBSIC0tPg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KEdHYWxseSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoYW5kcmV3cykNCmxpYnJhcnkodGNsdGspDQpsaWJyYXJ5KGFwbHBhY2spDQpsaWJyYXJ5KGdyYXBoaWNzKQ0KbGlicmFyeShNVk4pDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeShGYWN0b01pbmVSKQ0KbGlicmFyeShmYWN0b2V4dHJhKQ0KbGlicmFyeShwc3ljaCkNCmxpYnJhcnkoRmFjdG9DbGFzcykNCmxpYnJhcnkoY2x1c3RlcikNCmxpYnJhcnkoZGVuZGV4dGVuZCkNCmxpYnJhcnkobWFncml0dHIpDQpsaWJyYXJ5KE5iQ2x1c3QpDQpsaWJyYXJ5KHN0YXJnYXplcikNCg0KbGlicmFyeShyZWFkeGwpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCg0KcmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL2p1YW5lX3h0ODJmL09uZURyaXZlL0VzY3JpdG9yaW8vR1NEXzYvcmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zLnhsc3giKQ0KDQoNCmxpYnJhcnkocmVhZHhsKQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcyA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9qdWFuZV94dDgyZi9PbmVEcml2ZS9Fc2NyaXRvcmlvL0dTRF82L3Jlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MueGxzeCIpDQoNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MkZmVjaGFfbGFuemFtaWVudG8gPC0NCiAgYXMuRGF0ZShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zJGZlY2hhX2xhbnphbWllbnRvLA0KICAgICAgICAgIGZvcm1hdCA9ICIlbS8lZC8leSIpICAgDQoNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MkYWx0byA8LQ0KICBhcy5udW1lcmljKGdzdWIoIiwiLCAiLiIsIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MkUHJlY2lvX21hc19hbHRvKSkNCiMgRGF0b3MgbnVtw6lyaWNvcyBiYXNlIHBhcmEgdG9kb3MgbG9zIGFuw6FsaXNpcyBtdWx0aXZhcmlhbnRlcw0KZGF0b3NfbnVtIDwtIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbLCANCiAgYygiUHJlY2lvX21hc19hbHRvIiwNCiAgICAicHVudF9jcml0aWNvc19tZXRhIiwNCiAgICAibl9jcml0aWNvc19tZXRhIiwNCiAgICAicHVudF91c3Vhcmlvc19tZXRhIiwNCiAgICAibl91c3Vhcmlvc19tZXRhIiwNCiAgICAiY2FsaWZfcHNfc3RvcmUiLA0KICAgICJuX3RvdGFsX3N0b3JlIiwNCiAgICAicGFydGljaXBhY2lvbl9wdWJsaV9jYXQiKV0NCg0KZGF0b3NfbnVtIDwtIG5hLm9taXQoZGF0b3NfbnVtKQ0KDQpgYGANCg0KIyMgKipGYXNlIDEgW0Rlc2NyaXBjaW9uZXMgTXVsdGl2YXJpYW50ZXNdKioNCkVuIGxhIHByaW1lcmEgZXRhcGEgZGVsIGVzdHVkaW8sIHNlIGxsZXZhcsOhbiBhIGNhYm8gY8OhbGN1bG9zLCB2aXN1YWxpemFjaW9uZXMgeSB1biBhbsOhbGlzaXMgZGV0YWxsYWRvIGRlbCBjb25qdW50byBkZSBkYXRvcyBzb2JyZSB2aWRlb2p1ZWdvcywgcXVlIHNlcsOhIGRlc2NyaXRvIGVuIGxhIHNlY2Npw7NuIDEuMi4gRXN0ZSBwcm9jZXNvIHNlIGFib3JkYXLDoSBkZXNkZSB1bmEgcGVyc3BlY3RpdmEgZGUgZXN0YWTDrXN0aWNhIGRlc2NyaXB0aXZhIG11bHRpdmFyaWFudGUsIGxvIHF1ZSBwZXJtaXRpcsOhIG5vIHNvbG8gdW5hIHZpc2nDs24gZ2VuZXJhbCBkZSBsb3MgZGF0b3MsIHNpbm8gdGFtYmnDqW4gdW4gYW7DoWxpc2lzIG3DoXMgZW5yaXF1ZWNpZG8gZGUgbGFzIHJlbGFjaW9uZXMgZW50cmUgbGFzIGRpZmVyZW50ZXMgdmFyaWFibGVzIGludm9sdWNyYWRhcywgdGFsZXMgY29tbyBnw6luZXJvLCBwbGF0YWZvcm1hLCBhw7FvIGRlIGxhbnphbWllbnRvLCB2ZW50YXMgZ2xvYmFsZXMgcG9yIHJlZ2nDs24geSBwdW50dWFjaW9uZXMgZGUgdXN1YXJpb3MgeSBjcsOtdGljb3MuDQoNCkVzdGUgZW5mb3F1ZSBmYWNpbGl0YXLDoSB1bmEgY29tcHJlbnNpw7NuIG3DoXMgcHJvZnVuZGEgZGUgbGFzIHJlbGFjaW9uZXMgZW50cmUgbGFzIHZhcmlhYmxlcywgYXl1ZGFuZG8gYSBpZGVudGlmaWNhciBwYXRyb25lcyB5IHRlbmRlbmNpYXMgcmVsZXZhbnRlcyBlbiBsYSBpbmR1c3RyaWEgZGUgbG9zIHZpZGVvanVlZ29zLiBMYXMgdmlzdWFsaXphY2lvbmVzIGp1Z2Fyw6FuIHVuIHBhcGVsIGNsYXZlIGVuIGxhIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBkZSBlc3RhcyByZWxhY2lvbmVzLCBicmluZGFuZG8gdW5hIGZvcm1hIGNsYXJhIHkgYWNjZXNpYmxlIGRlIGV4cGxvcmFyIGxvcyBkYXRvcyB5IGZhY2lsaXRhciBzdSBjb21wcmVuc2nDs24uIFRvZG8gZXN0byBzZSBsbGV2YXLDoSBhIGNhYm8gdXRpbGl6YW5kbyBsYXMgaGVycmFtaWVudGFzIFIgeSBSU3R1ZGlvLCBxdWUgcGVybWl0aXLDoW4gdW5hIGVqZWN1Y2nDs24gZWZpY2llbnRlIHkgcHJlY2lzYSBkZSBsb3MgY8OhbGN1bG9zIHkgbGEgY3JlYWNpw7NuIGRlIGdyw6FmaWNvcyBpbnRlcmFjdGl2b3MgcGFyYSB1bmEgaW50ZXJwcmV0YWNpw7NuIG3DoXMgY29tcGxldGEgZGUgbG9zIHJlc3VsdGFkb3MuDQoNCiMjIyAxLjEuIE9iamV0aXZvcw0KRWwgb2JqZXRpdm8gZGUgZXN0ZSBwcm95ZWN0byBlcyBhcGxpY2FyIHTDqWNuaWNhcyBkZSBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIHBhcmEgZ2VzdGlvbmFyIGVsIGNvbmp1bnRvIGRlIGRhdG9zIGFwcm9iYWRvLCBjb3JyZXNwb25kaWVudGUgYSByZWdpc3Ryb3MgZGUgdmlkZW9qdWVnb3MgcXVlIGluY2x1eWVuIGluZm9ybWFjacOzbiBzb2JyZSB0w610dWxvcywgZ8OpbmVyb3MsIHBsYXRhZm9ybWFzLCBhw7FvcyBkZSBsYW56YW1pZW50bywgdmVudGFzIGdsb2JhbGVzIHkgcHVudHVhY2lvbmVzIGRlIHVzdWFyaW9zLiBFbCBwcm9ww7NzaXRvIGVzIG9yZ2FuaXphciB5IHByb2Nlc2FyIGVmaWNhem1lbnRlIGxhIGluZm9ybWFjacOzbiwgZGVzYXJyb2xsYW5kbyBoYWJpbGlkYWRlcyBlbiBsYSBnZXN0acOzbiB5IGFuw6FsaXNpcyBkZSBkYXRvcyBtZWRpYW50ZSBsYSBpbXBsZW1lbnRhY2nDs24gZGUgbcOpdG9kb3MgZXN0YWTDrXN0aWNvcyBhdmFuemFkb3MgY29tbyBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMsIGNvcnJlc3BvbmRlbmNpYXMsIGNvbmdsb21lcmFkb3MgeSByZWdyZXNpw7NuLiBFc3RlIHRyYWJham8gc2UgZW5tYXJjYSBkZW50cm8gZGVsIGN1cnNvIGRlIEdlc3Rpw7NuIGRlIERhdG9zLCBkaWN0YWRvIHBvciBlbCBQcm9mZXNvciBHaWFuY2FybG8gTGlicmVyb3MgTG9uZG/DsW8gZW4gbGEgVW5pdmVyc2lkYWQgZGVsIFZhbGxlLg0KDQojIyMgMS4yLiBEZXNjcmlwY2nDs24gZGUgbG9zIGRhdG9zIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQpFbCBjb25qdW50byBkZSBkYXRvcyBmdWUgb2J0ZW5pZG8gZW4gc3UgdG90YWxpZGFkIGRlc2RlIGxhIHBsYXRhZm9ybWEgS2FnZ2xlOihodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2lzYWFjbWVuYXJkL3BsYXlzdGF0aW9uLWdhbWVzLWluZm8tMjE1MjAyNSkuS2FnZ2xlLCBlcyB1bmEgcGxhdGFmb3JtYSBlbiBsw61uZWEgZXNwZWNpYWxpemFkYSBlbiBjaWVuY2lhIGRlIGRhdG9zIHkgYXByZW5kaXphamUgYXV0b23DoXRpY28sIHByb3BpZWRhZCBkZSBHb29nbGUgTExDLiBTZSBkZXN0YWNhIHBvciBmYWNpbGl0YXIgbGEgcGFydGljaXBhY2nDs24gZW4gY29tcGV0ZW5jaWFzIGVuIGxhcyBxdWUgZW1wcmVzYXMgZSBpbnN0aXR1Y2lvbmVzIHB1YmxpY2FuIGNvbmp1bnRvcyBkZSBkYXRvcyB5IHByb2JsZW1hcyByZWFsZXMsIHBlcm1pdGllbmRvIGEgbG9zIHVzdWFyaW9zIGRlc2Fycm9sbGFyIG1vZGVsb3MgcHJlZGljdGl2b3MgeSBwb25lciBhIHBydWViYSBzdXMgaGFiaWxpZGFkZXMgYW5hbMOtdGljYXMuIEFkZW3DoXMsIGxhIHBsYXRhZm9ybWEgcHJvcG9yY2lvbmEgaGVycmFtaWVudGFzIGNvbW8gbm90ZWJvb2tzIGludGVyYWN0aXZvcyBlbiBQeXRob24geSBSLCB1bmEgYW1wbGlhIGJpYmxpb3RlY2EgZGUgY29uanVudG9zIGRlIGRhdG9zIGRlIGxpYnJlIGFjY2VzbyB5IHVuYSBzZWNjacOzbiBlZHVjYXRpdmEgZGVub21pbmFkYSBLYWdnbGUgTGVhcm4sIGRlZGljYWRhIGEgbGEgZm9ybWFjacOzbiBlbiBwcm9ncmFtYWNpw7NuLCBhbsOhbGlzaXMgeSB2aXN1YWxpemFjacOzbiBkZSBkYXRvcy4gRWwgY29uanVudG8gZGUgZGF0b3Mgc2VsZWNjaW9uYWRvLCBmdWUgZWxhYm9yYWRvIHBvciBJc2FhYyBNZW5hcmQgKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vaXNhYWNtZW5hcmQpLCBxdWUgcmVjb3BpbGEgaW5mb3JtYWNpw7NuIGRldGFsbGFkYSBzb2JyZSBkaXZlcnNvcyB2aWRlb2p1ZWdvcyBkZSBQbGF5U3RhdGlvbi4NCg0KRW4gZWwgY29udGV4dG8gZGVsIGFuYWxpc2lzIGRlIGNvbmp1bnRvcyBkZSBkYXRvcywgZXN0ZSBlc3R1ZGlvIHNlIHJlbGFjaW9uYSBjb24gbGFzIHNpZ3VpZW50ZXMgYXJlYXMgZGUgbGEgaW5nZW5pZXJpYSBpbmR1c3RyaWFsLiBFbiBlbCBhcmVhICAqKjIuIEludmVzdGlnYWNpw7NuIGRlIE9wZXJhY2lvbmVzIHkgQW7DoWxpc2lzLCoqKE9wZXJhdGlvbnMgcmVzZWFyY2ggJiBhbmFseXNpcykgZGV2aWRvIGEgcXVlIGxvcyBkYXRvcyBkZSB2ZW50YXMgeSBjYWxpZmljYWNpb25lcyBzaXJ2ZW4gcGFyYSBhcGxpY2FyIG1vZGVsb3MgbWF0ZW3DoXRpY29zIG9yaWVudGFkb3MgYSBsYSB0b21hIGRlIGRlY2lzaW9uZXMgZXN0cmF0w6lnaWNhcyBlbiBsYSBpbmR1c3RyaWEgZGVsIGVudHJldGVuaW1pZW50byBkaWdpdGFsOyBlbiBlbCBhcmVhICoqMy4gQW7DoWxpc2lzIEVjb27Ds21pY28gZGUgbGEgSW5nZW5pZXLDrWEsKiooRW5naW5uZXJpbmcgZWNvbm9taWMgYW5hbHlzaXMpIHBvcnF1ZSBzZSBjb25zaWRlcmFuIGFzcGVjdG9zIGZpbmFuY2llcm9zIG1lZGlhbnRlIHZhcmlhYmxlcyBjb21vIGVsIHByZWNpbyBkZSB2ZW50YSBvIGVsIG1vZGVsbyBkZSBuZWdvY2lvOyBlbiBlbCBhcmVhICoqMTMuIERpc2XDsW8geSBEZXNhcnJvbGxvIGRlIFByb2R1Y3RvcyoqKERlc2luZyAmIG1hbnVmYWN0dXJpbmcgZW5naW5lZXJpbmcpLCBwb3JxdWUgZWwgZXN0dWRpbyBkZSB2YXJpYWJsZXMgY29tbyBlbCBnw6luZXJvIHkgbGEgcGxhdGFmb3JtYSBwZXJtaXRlIGlkZW50aWZpY2FyIHRlbmRlbmNpYXMgZGUgaW5ub3ZhY2nDs24geSBldm9sdWNpw7NuIGVuIGxvcyB2aWRlb2p1ZWdvcywgcmVmbGVqYW5kbyBsYSBpbmZsdWVuY2lhIGRlIGxhcyBwcmVmZXJlbmNpYXMgZGUgbG9zIHVzdWFyaW9zIHkgbG9zIGF2YW5jZXMgdGVjbm9sw7NnaWNvcyBlbiBzdSBkaXNlw7FvIHkgbWVqb3JhIGNvbnRpbnVhLg0KDQpFbCBjb25qdW50byBkZSBkYXRvcyBlc3TDoSBjb21wdWVzdG8gcG9yIDEyIGNhbXBvcyB5IDMsNTI2IHJlZ2lzdHJvcyBxdWUgcmVjb3BpbGFuIGluZm9ybWFjacOzbiBzb2JyZSB2aWRlb2p1ZWdvcyBkZSBsYSBtYXJjYSBQbGF5U3RhdGlvbi4gSW5jbHV5ZSB2YXJpYWJsZXMgcmVsYWNpb25hZGFzIGNvbiBlbCB0w610dWxvLCBkZXNhcnJvbGxhZG9yLCBwbGF0YWZvcm1hLCBnw6luZXJvLCBwcmVjaW8sIHZlbnRhcyB5IGNhbGlmaWNhY2lvbmVzLCBsbyBxdWUgcGVybWl0ZSBhbmFsaXphciBhc3BlY3RvcyB0w6ljbmljb3MsIGNvbWVyY2lhbGVzIHkgZGUgcHJlZmVyZW5jaWEgZGVsIGNvbnN1bWlkb3IgZGVudHJvIGRlIGxhIGluZHVzdHJpYSBkZWwgZW50cmV0ZW5pbWllbnRvIGRpZ2l0YWwuIExhIGxpc3RhIHNpZ3VpZW50ZSBwcmVzZW50YSBsYXMgdmFyaWFibGVzIGRlbCBjb25qdW50byBkZSBkYXRvcyBlbiBlbCBtaXNtbyBvcmRlbiBlbiBxdWUgYXBhcmVjZW4gZW4gZWwgYXJjaGl2byBvcmlnaW5hbCwgaW5kaWNhbmRvIHBhcmEgY2FkYSB1bmEgc3UgdGlwbyBkZSB2YXJpYWJsZSB5IGVzY2FsYSBkZSBtZWRpY2nDs24sIHNpZ3VpZW5kbyBsYSBub21lbmNsYXR1cmEgKHRpcG9fZGVfdmFyaWFibGU6OmVzY2FsYV9kZV9tZWRpY2nDs24gW29yZGVuYW1pZW50b10pOg0KDQotICoqbm9tYnJlX2p1ZWdvKiogKGN1YWxpdGF0aXZhOjpub21pbmFsKTogZXMgbGEgZGVub21pbmFjacOzbiBvZmljaWFsIGRlbCB2aWRlb2p1ZWdvIHJlZ2lzdHJhZGEgZW4gbGEgUGxheVN0YXRpb24gU3RvcmUuIEVzdGEgdmFyaWFibGUgaWRlbnRpZmljYSBkZSBtYW5lcmEgw7puaWNhIGNhZGEgdMOtdHVsbyB5IHNlIHByZXNlbnRhIGVuIGZvcm1hdG8gZGUgdGV4dG8sIHJlc3BldGFuZG8gbGEgb3J0b2dyYWbDrWEgeSBlc3RpbG8gb3JpZ2luYWwgZXN0YWJsZWNpZG8gcG9yIGxhIGRpc3RyaWJ1aWRvcmEuDQoNCi0gKipwcmVjaW9fbWFzX2FsdG8qKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiBpbmRpY2EgZWwgVmFsb3IgbW9uZXRhcmlvIG3DoXhpbW8gYWxjYW56YWRvIHBvciBlbCB2aWRlb2p1ZWdvIGRlbnRybyBkZSBsYSBQbGF5U3RhdGlvbiBTdG9yZSwgZXhwcmVzYWRvIGVuIGV1cm9zICjigqwpLg0KDQotICoqbGFuemFtaWVudG8qKiAoY3VhbnRpdGF0aXZhOjppbnRlcnZhbG8pOiBpbmRpY2EgbGEgZmVjaGEgbyBhw7FvIGNvcnJlc3BvbmRpZW50ZSBhbCBlc3RyZW5vIG9maWNpYWwgZGVsIHZpZGVvanVlZ28gZW4gZWwgbWVyY2Fkby4gRXN0YSB2YXJpYWJsZSBwZXJtaXRlIGVzdGFibGVjZXIgY29tcGFyYWNpb25lcyB0ZW1wb3JhbGVzIHkgYW5hbGl6YXIgdGVuZGVuY2lhcyBkZSBsYW56YW1pZW50byBhIGxvIGxhcmdvIGRlbCB0aWVtcG8uDQoNCi0gKipnZW5lcm8qKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOmVzIGxhIGNsYXNpZmljYWNpw7NuIHRlbcOhdGljYSBvIHRpcG9sw7NnaWNhIGRlbCB2aWRlb2p1ZWdvIHNlZ8O6biBzdSBkaW7DoW1pY2EgeSBlc3RpbG8gZGUganVlZ28gKGFjY2nDs24sIGF2ZW50dXJhLCByb2wsIGRlcG9ydGVzLCBlbnRyZSBvdHJvcykuIEZhY2lsaXRhIGxhIHNlZ21lbnRhY2nDs24geSBlbCBhbsOhbGlzaXMgY29tcGFyYXRpdm8gZW50cmUgZGlzdGludG9zIHRpcG9zIGRlIGV4cGVyaWVuY2lhcyBpbnRlcmFjdGl2YXMuIA0KDQotICoqZW1wcmVzYV9jcmVhZG9yYSoqIChjdWFsaXRhdGl2YTo6bm9taW5hbCk6IHJlZ2lzdHJhIGVsIG5vbWJyZSBkZSBsYSBjb21wYcOxw61hIGRlc2Fycm9sbGFkb3JhIG8gZGlzdHJpYnVpZG9yYSByZXNwb25zYWJsZSBkZSBsYSBwcm9kdWNjacOzbiBkZWwgdmlkZW9qdWVnby4gRXN0YSB2YXJpYWJsZSBwZXJtaXRlIGlkZW50aWZpY2FyIGVsIG9yaWdlbiBlbXByZXNhcmlhbCB5IGFuYWxpemFyIGxhIHBhcnRpY2lwYWNpw7NuIGRlIGRpc3RpbnRhcyBtYXJjYXMgZGVudHJvIGRlbCBtZXJjYWRvIGRlIFBsYXlTdGF0aW9uLiANCg0KLSAqKnBsYXRhZm9ybWEqKiAoY3VhbGl0YXRpdmE6Om5vbWluYWwpOiBzZcOxYWxhIGVsIHNpc3RlbWEgbyBjb25zb2xhIGRlIGxhIGzDrW5lYSBQbGF5U3RhdGlvbiBlbiBsYSBjdWFsIGZ1ZSBsYW56YWRvIGVsIHZpZGVvanVlZ28gKHBzMywgcHM0IG8gcHM1KS4gU3UgaW5jbHVzacOzbiBwb3NpYmlsaXRhIGVsIGVzdHVkaW8gZGUgbGEgY29tcGF0aWJpbGlkYWQsIGxhIGV2b2x1Y2nDs24gdGVjbm9sw7NnaWNhIHkgbGFzIGRpZmVyZW5jaWFzIGdlbmVyYWNpb25hbGVzIGVudHJlIGNvbnNvbGFzLg0KIA0KLSAqKm1ldGFjcml0aWNfc2NvcmUqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOnJlcHJlc2VudGEgbGEgcHVudHVhY2lvbiBwcm9tZWRpbyBwb25kZXJhZG8gZGUgbGFzIGNhbGlmaWNhY2lvbmVzIG90b3JnYWRhcyBwb3IgY3LDrXRpY29zIGVzcGVjaWFsaXphZG9zIGVuIGVsIHZpZGVvanVlZ28sIGVuIHVuYSBlc2NhbGEgZGUgMCBhIDEwMC4gDQoNCi0gKiptZXRhY3JpdGljX3JhdGluZ19jb3VudCoqIChjdWFudGl0YXRpdmE6OnJhesOzbik6IG11ZXN0cmEgZWwgbsO6bWVybyB0b3RhbCBkZSByZXNlw7FhcyBwcm9mZXNpb25hbGVzIHJlY29waWxhZGFzIHBvciBNZXRhY3JpdGljLiBSZWZsZWphIGVsIG5pdmVsIGRlIGNvYmVydHVyYSBtZWRpw6F0aWNhIHkgZWwgZ3JhZG8gZGUgYXRlbmNpw7NuIHJlY2liaWRhIHBvciBwYXJ0ZSBkZSBsYSBwcmVuc2EgZXNwZWNpYWxpemFkYS4gDQoNCi0gKiptZXRhY3JpdGljX3VzZXJfc2NvcmUqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiByZWdpc3RyYSBlbCBwcm9tZWRpbyBkZSBsYXMgdmFsb3JhY2lvbmVzIGVtaXRpZGFzIHBvciBsb3MgdXN1YXJpb3MgZW4gbGEgcGxhdGFmb3JtYSBNZXRhY3JpdGljLCBleHByZXNhZG8gZW4gdW5hIGVzY2FsYSBkZSAwIGEgMTAuIEVzdGUgaW5kaWNhZG9yIHJlcHJlc2VudGEgbGEgcGVyY2VwY2nDs24geSBzYXRpc2ZhY2Npw7NuIGdlbmVyYWwgZGVsIHDDumJsaWNvLg0KDQotICoqTWV0YWNyaXRpY191c2VyX3JhdGluZ19jb3VudCoqIChDdWFudGl0YXRpdmE6OnJhesOzbik6IGluZGljYSBlbCBuw7ptZXJvIGRlIHZhbG9yYWNpb25lcyBlbWl0aWRhcyBwb3IgbG9zIHVzdWFyaW9zLiBNaWRlIGxhIHBhcnRpY2lwYWNpw7NuIHkgcG9wdWxhcmlkYWQgZGVsIGp1ZWdvLg0KDQotICoqcGxheXN0YXRpb25fc2NvcmUqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiBtdWVzdHJhIGxhIHZhbG9yYWNpb24gcHJvbWVkaW8gZGUgbGFzIHB1bnR1YWNpb25lcyBvdG9yZ2FkYXMgcG9yIGxvcyB1c3VhcmlvcyBlbiBsYSBQbGF5U3RhdGlvbiBTdG9yZSwgZW4gdW5hIGVzY2FsYSBkZSAwIGEgNS4gQ29uc3RpdHV5ZSB1bmEgbWVkaWRhIGRpcmVjdGEgZGUgbGEgdmFsb3JhY2nDs24gaW50ZXJuYSBkZW50cm8gZGUgbGEgcGxhdGFmb3JtYSBvZmljaWFsIGRlIFNvbnkuDQoNCi0gKipwbGF5c3RhdGlvbl9yYXRpbmdfY291bnQqKiAoY3VhbnRpdGF0aXZhOjpyYXrDs24pOiByZWZsZWphIGxhIGNhbnRpZGFkIHRvdGFsIGRlIHJlc2XDsWFzIG8gY2FsaWZpY2FjaW9uZXMgZW1pdGlkYXMgcG9yIGxvcyB1c3VhcmlvcyBlbiBsYSBQbGF5U3RhdGlvbiBTdG9yZS4gSW5kaWNhIGVsIG5pdmVsIGRlIGludGVyYWNjacOzbiwgYWNlcHRhY2nDs24geSB2aXNpYmlsaWRhZCBkZWwgdmlkZW9qdWVnbyBkZW50cm8gZGVsIGVudG9ybm8gZGlnaXRhbCBkZSBsYSBjb25zb2xhLiANCg0KQ2FiZSByZXNhbHRhciBxdWUgZHVyYW50ZSBlbCBwcm9jZXNvIGRlIGRlcHVyYWNpw7NuIGRlbCBjb25qdW50byBkZSBkYXRvcyBkZSByZXNlw7FhcyBkZSB2aWRlb2p1ZWdvcyBzZSByZWFsaXphcm9uIGFqdXN0ZXMgb3JpZW50YWRvcyBhIGdhcmFudGl6YXIgbGEgY29oZXJlbmNpYSB5IGFwcm92ZWNoYW1pZW50byBtw6F4aW1vIGRlIGxhIGluZm9ybWFjacOzbiBkaXNwb25pYmxlLiBFbiBwcmltZXIgbHVnYXIsIHNlIGVsaW1pbmFyb24gcmVnaXN0cm9zIGNvbiBkYXRvcyBlbiBibGFuY28gY3VhbmRvIGxhIGF1c2VuY2lhIGRlIGluZm9ybWFjacOzbiBhZmVjdGFiYSB2YXJpYWJsZXMgY2xhdmUsIHkgZW4gb3Ryb3MgY2Fzb3Mgc2UgcHJvY2VkacOzIGEgY29tcGxldGFyIHZhbG9yZXMgZmFsdGFudGVzIG1lZGlhbnRlIGNyaXRlcmlvcyBjb25zaXN0ZW50ZXMgY29uIGVsIGNvbXBvcnRhbWllbnRvIGRlbCByZXN0byBkZSBsYSBtdWVzdHJhLCBjb24gZWwgZmluIGRlIG5vIHJlZHVjaXIgaW5uZWNlc2FyaWFtZW50ZSBlbCB0YW1hw7FvIGRlbCBkYXRhc2V0LiBBZGVtw6FzLCBsYSB2YXJpYWJsZSBmZWNoYV9sYW56YW1pZW50byBzZSBlc3RhbmRhcml6w7MgcGFzYW5kbyBkZSBmb3JtYXRvcyBjb21vIOKAnEZlYiAxNSwgMjAxMuKAnSBhIHVuIGZvcm1hdG8gZGUgZmVjaGEgaG9tb2fDqW5lbyB0aXBvIOKAnDE1LzAyLzIwMTLigJ0sIGxvIHF1ZSBmYWNpbGl0YSBlbCBvcmRlbmFtaWVudG8gY3Jvbm9sw7NnaWNvIHkgZWwgdXNvIGRlIGZ1bmNpb25lcyBkZSB0aWVtcG8gZW4gZWwgYW7DoWxpc2lzLiBBZGljaW9uYWxtZW50ZSwgc2UgY29ycmlnaWVyb24gYWxndW5vcyB2YWxvcmVzIGF0w61waWNhbWVudGUgZWxldmFkb3MgZW4gbGEgdmFyaWFibGUgUHJlY2lvX21hc19hbHRvLCByZXZpc2FuZG8gc3UgbWFnbml0dWQgeSBhanVzdMOhbmRvbG9zIGEgcmFuZ29zIG3DoXMgcmVhbGlzdGFzIHBhcmEgZXZpdGFyIGRpc3RvcnNpb25lcyBlbiBsb3MgYW7DoWxpc2lzIHBvc3RlcmlvcmVzLiBGaW5hbG1lbnRlLCBzZSBpbmNvcnBvcsOzIHVuYSB2YXJpYWJsZSBkZSBkZWNpc2nDs24gcXVlIGNsYXNpZmljYSBhIGxvcyB2aWRlb2p1ZWdvcyBzZWfDum4gZWwgbml2ZWwgZGUgcGFydGljaXBhY2nDs24gbyBleHBvc2ljacOzbiBwdWJsaWNpdGFyaWEsIGxvIGN1YWwgcGVybWl0ZSBlc3R1ZGlhciBkZSBtYW5lcmEgbcOhcyBwcmVjaXNhIGPDs21vIGxhIHZpc2liaWxpZGFkIGNvbWVyY2lhbCBzZSByZWxhY2lvbmEgY29uIGxhcyBwdW50dWFjaW9uZXMgZGUgY3LDrXRpY29zLCB1c3VhcmlvcyB5IGVsIGRlc2VtcGXDsW8gZGVudHJvIGRlIGxhIFBsYXlTdGF0aW9uIFN0b3JlLg0KDQoNCiMjIyMgRXN0cnVjdHVyYSBkZWwgY29uanVudG8gZGUgRGF0b3MgT3JpZ2luYWwNCmBgYHtyIEVzdHJ1Y3R1cmFfZGVsX2Nvbmp1bnRvX2RlX0RhdG9zX09yaWdpbmFsLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN0cihyZXNlbmFzX2p1ZWdvc19lbGVjdHJvbmljb3MpDQpgYGANCiMjIyMgQ29uanVudG8gZGUgRGF0b3MgT3JpZ2luYWwNCmBgYHtyIENvbmp1bnRvX2RlX0RhdG9zX09yaWdpbmFsLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnJlc2VuYXNfanVlZ29zX2VsZWN0cm9uaWNvcw0KYGBgDQojIyMjIEVzdHJ1Y3R1cmEgZGVsIGNvbmp1bnRvIGRlIERhdG9zIEVUTA0KYGBge3IgRXN0cnVjdHVyYV9kZWxfY29uanVudG9fZGVfRGF0b3NfRVRMLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnN0cihyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zKQ0KYGBgDQojIyMjIENvbmp1bnRvIGRlIERhdG9zIE9yaWdpbmFsIERlcHVyYWRvDQpgYGB7ciBDb25qdW50b19kZV9EYXRvc19EZXB1cmFkbywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zDQpgYGANCg0KDQoNCkVsIGNvbmp1bnRvIG9yaWdpbmFsIHJlc2VuYXNfanVlZ29zX2VsZWN0cm9uaWNvc19PcmlnaW5hbCBjb250aWVuZSAzLjUyNiB2aWRlb2p1ZWdvcyB5IDEyIHZhcmlhYmxlcywgY29uIHByZWNpb3MgeSBmZWNoYXMgYWxtYWNlbmFkb3MgY29tbyB0ZXh0byB5IGFsZ3Vub3MgcmVnaXN0cm9zIGNvbiBpbmZvcm1hY2nDs24gaW5jb21wbGV0YS4gUmVwcmVzZW50YSBsYSBiYXNlIHRhbCBjb21vIGZ1ZSBvYnRlbmlkYSBkZSBsYXMgZnVlbnRlcywgw7p0aWwgcGFyYSBkZXNjcmliaXIgZWwgb3JpZ2VuIHkgbGEgZXN0cnVjdHVyYSBpbmljaWFsIGRlIGxvcyBkYXRvcyBhbnRlcyBkZSBjdWFscXVpZXIgdHJhdGFtaWVudG8uDQoNCkVsIGNvbmp1bnRvIGRlcHVyYWRvIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MgcmVkdWNlIGEgMy40NTcgcmVnaXN0cm9zIHkgYW1wbMOtYSBhIDEzIHZhcmlhYmxlcywgbHVlZ28gZGUgZWxpbWluYXIgb2JzZXJ2YWNpb25lcyBjb24gZGF0b3MgY3LDrXRpY29zIGVuIGJsYW5jbywgY29udmVydGlyIGVsIHByZWNpbyBtw6F4aW1vIGEgbnVtw6lyaWNvIChhbHRvKSwgZXN0YW5kYXJpemFyIGxhIGZlY2hhIGRlIGxhbnphbWllbnRvIHkgY3JlYXIgbGEgdmFyaWFibGUgcGFydF9wdWJsaSBzb2JyZSBwYXJ0aWNpcGFjacOzbiBwdWJsaWNpdGFyaWEuIEVzdGEgdmVyc2nDs24gb2ZyZWNlIHVuYSBtYXRyaXogZGUgZGF0b3MgbcOhcyBsaW1waWEgeSBob21vZ8OpbmVhLCBhZGVjdWFkYSBwYXJhIGxhcyBkZXNjcmlwY2lvbmVzIG11bHRpdmFyaWFudGVzIHkgbG9zIGFuw6FsaXNpcyBlc3RhZMOtc3RpY29zIGFwbGljYWRvcyBhbCBtZXJjYWRvIGRlIHZpZGVvanVlZ29zLg0KDQojIyMgMS4zLiBFc3RpbWFjaW9uZXMgbXVsdGl2YXJpYWRhcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KRWwgdmVjdG9yIGRlIG1lZGlhcyB5IGxhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgc29uIGVsZW1lbnRvcyBmdW5kYW1lbnRhbGVzIGRlbCBhbsOhbGlzaXMgZXN0YWTDrXN0aWNvIG11bHRpdmFyaWFkbywgcHVlcyBwZXJtaXRlbiBjYXJhY3Rlcml6YXIgZWwgY29tcG9ydGFtaWVudG8gY2VudHJhbCwgbGEgZGlzcGVyc2nDs24geSBsYXMgcmVsYWNpb25lcyBkZSBkZXBlbmRlbmNpYSBlbnRyZSBsYXMgdmFyaWFibGVzIGRlIHVuIGNvbmp1bnRvIGRlIGRhdG9zLiBFc3RhcyBoZXJyYW1pZW50YXMgZmFjaWxpdGFuIGxhIGNvbXByZW5zacOzbiBnbG9iYWwgZGUgbGEgZXN0cnVjdHVyYSBpbnRlcm5hIGRlIGxhIGluZm9ybWFjacOzbiBhbmFsaXphZGEuIEVsIHZlY3RvciBkZSBtZWRpYXMgcmVzdW1lIGVsIHByb21lZGlvIG8gdmFsb3IgZXNwZXJhZG8gZGUgY2FkYSB2YXJpYWJsZSwgcmVwcmVzZW50YW5kbyBlbCBwdW50byBkZSBlcXVpbGlicmlvIGFscmVkZWRvciBkZWwgY3VhbCBzZSBkaXN0cmlidXllbiBsb3MgZGF0b3MuIFBvciBvdHJvIGxhZG8sIGxhIG1hdHJpeiBkZSB2YXJpYW56YXMtY292YXJpYW56YXMgcHJvcG9yY2lvbmEgdW5hIG1lZGlkYSBjb25qdW50YSBkZSBsYSB2YXJpYWJpbGlkYWQgeSBkZSBsYXMgcmVsYWNpb25lcyBsaW5lYWxlcyBlbnRyZSBsYXMgdmFyaWFibGVzLiBFbiBzdSBkaWFnb25hbCBwcmluY2lwYWwgc2UgZW5jdWVudHJhbiBsYXMgdmFyaWFuemFzLCBxdWUgcmVmbGVqYW4gbGEgZGlzcGVyc2nDs24gaW5kaXZpZHVhbCBkZSBjYWRhIHZhcmlhYmxlLCBtaWVudHJhcyBxdWUgbG9zIGVsZW1lbnRvcyBmdWVyYSBkZSBsYSBkaWFnb25hbCBleHByZXNhbiBsYXMgY292YXJpYW56YXMsIGVzIGRlY2lyLCBlbCBncmFkbyBlbiBxdWUgZG9zIHZhcmlhYmxlcyB0aWVuZGVuIGEgdmFyaWFyIHNpbXVsdMOhbmVhbWVudGUuDQoNCiMjIyMgVmVjdG9yIGRlIE1lZGlhcyB5IEJveHBsb3RzDQpFbCBzaWd1aWVudGUgY29uanVudG8gZGUgYm94cGxvdHMgcmVzdW1lIGxhIGRpc3RyaWJ1Y2nDs24gZGUgY3VhdHJvIHZhcmlhYmxlcyBjdWFudGl0YXRpdmFzIGNsYXZlIGRlbCBtZXJjYWRvIGRlIHZpZGVvanVlZ29zIGFuYWxpemFkbzogZWwgUHJlY2lvX21hc19hbHRvIHJlZ2lzdHJhZG8gZW4gbGEgUFMgU3RvcmUsIGxhIHB1bnR1YWNpw7NuIGRlIGNyw610aWNvcyBlbiBNZXRhY3JpdGljIChwdW50X2NyaXRpY29zX21ldGEpLCBlbCBuw7ptZXJvIGRlIGNyw610aWNhcyBkZSBNZXRhY3JpdGljIChuX2NyaXRpY29zX21ldGEpIHkgbGEgcHVudHVhY2nDs24gZGUgdXN1YXJpb3MgKHB1bnRfdXN1YXJpb3NfbWV0YSkuIEVsIGdyw6FmaWNvIGRlIGNhamFzIGVzIGVzcGVjaWFsbWVudGUgYWRlY3VhZG8gZW4gZXN0YSBmYXNlIGV4cGxvcmF0b3JpYSBwb3JxdWUgc2ludGV0aXphIGVuIHVuYSBzb2xhIGZpZ3VyYSBsYSBtZWRpYW5hLCBlbCByYW5nbyBpbnRlcmN1YXJ0w61saWNvIHkgbG9zIHZhbG9yZXMgYXTDrXBpY29zIGRlIGNhZGEgdmFyaWFibGUsIHBlcm1pdGllbmRvIGNvbXBhcmFyIGRlIGZvcm1hIHZpc3VhbCBsYSBkaXNwZXJzacOzbiwgbGEgc2ltZXRyw61hIHkgbGEgcHJlc2VuY2lhIGRlIG91dGxpZXJzIGVudHJlIGluZGljYWRvcmVzIHF1ZSBlc3TDoW4gZW4gZXNjYWxhcyBkaWZlcmVudGVzLiBEZSBlc3RhIG1hbmVyYSwgc2Ugb2J0aWVuZSB1bmEgdmlzacOzbiBjb21wYWN0YSBkZWwgY29tcG9ydGFtaWVudG8gY2VudHJhbCBkZSBsb3MgcHJlY2lvcyB5IGRlIGxhcyBldmFsdWFjaW9uZXMgY3LDrXRpY2FzIHkgZGUgdXN1YXJpb3MsIGxvIHF1ZSBmYWNpbGl0YSBkZXRlY3RhciB2YXJpYWJsZXMgbXV5IGhldGVyb2fDqW5lYXMgbyBjb24gY29uY2VudHJhY2lvbmVzIGV4dHJlbWFzIGRlIHZhbG9yZXMgYW50ZXMgZGUgYXBsaWNhciB0w6ljbmljYXMgYW5hbMOtdGljYXMgbcOhcyBhdmFuemFkYXMuDQoNCmBgYHtyIFZlY3Rvcl9kZV9NZWRpYXNfeV9Cb3hwbG90cywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQphcHBseShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywtYygxLDMsNCw1LDYsOSwxMCwxMSwxMiwxMyldLCAyLCBtZWFuLCBuYS5ybSA9IFRSVUUpIA0KcmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zX3JlZHVjaWRvID0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssLWMoMSwzLDQsNSw2LDksMTAsMTEsMTIsMTMpXQ0Kbm9tYnJlc19ib3hwbG90cyA8LSBjKCJQcmVjaW9fbWFzX2FsdG8iLCJwdW50X2NyaXRpY29zX21ldGEiLCJuX2NyaXRpY29zX21ldGEiLCJwdW50X3VzdWFyaW9zX21ldGEiKQ0KDQpwYXIobWZyb3cgPSBjKDEsIG5jb2wocmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zX3JlZHVjaWRvKSkpDQppbnZpc2libGUobGFwcGx5KDE6bmNvbChyZXNlbmFzX2p1ZWdvc19lbGVjdHJvbmljb3NfcmVkdWNpZG8pLCBmdW5jdGlvbihpKSB7DQogIGJveHBsb3QocmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zX3JlZHVjaWRvW1tpXV0sDQogICAgbWFpbiA9IG5vbWJyZXNfYm94cGxvdHNbaV0sDQogICAgeWxpbSA9IHF1YW50aWxlKHJlc2VuYXNfanVlZ29zX2VsZWN0cm9uaWNvc19yZWR1Y2lkb1tbaV1dLCBjKDAuMDIsIDAuOTkpLCBuYS5ybSA9IFRSVUUpLA0KICAgIG5hLnJtID0gVFJVRSl9KSkNCmBgYA0KDQpFbiBlbCBib3hwbG90IGRlIFByZWNpb19tYXNfYWx0byBzZSBvYnNlcnZhIHF1ZSBsYSBtZWRpYW5hIGRlbCBwcmVjaW8gZGUgbG9zIGp1ZWdvcyBzZSBzaXTDumEgYWxyZWRlZG9yIGRlIHVuIHJhbmdvIGludGVybWVkaW8sIG1pZW50cmFzIHF1ZSBlbCByYW5nbyBpbnRlcmN1YXJ0w61saWNvIGVzIHJlbGF0aXZhbWVudGUgZXN0cmVjaG8sIGluZGljYW5kbyBxdWUgbGEgbWF5b3LDrWEgZGUgdMOtdHVsb3Mgc2UgY29uY2VudHJhbiBlbiB1biBpbnRlcnZhbG8gZGUgcHJlY2lvcyBiYXN0YW50ZSBob21vZ8OpbmVvOyBzaW4gZW1iYXJnbywgbGEgcHJlc2VuY2lhIGRlIGFsZ3Vub3MgdmFsb3JlcyBhdMOtcGljb3MgaGFjaWEgbGEgcGFydGUgYWx0YSByZXZlbGEganVlZ29zIHByZW1pdW0gY29uIHByZWNpb3Mgc2Vuc2libGVtZW50ZSBzdXBlcmlvcmVzIGFsIHJlc3RvLCBxdWUgcmVwcmVzZW50YW4gb2ZlcnRhcyBkZSBnYW1hIGFsdGEgZGVudHJvIGRlbCBjYXTDoWxvZ28uIEVuIGVsIGNhc28gZGUgcHVudF9jcml0aWNvc19tZXRhIHkgcHVudF91c3Vhcmlvc19tZXRhLCBsYXMgY2FqYXMgc2UgdWJpY2FuIG1heW9yaXRhcmlhbWVudGUgZW4gcmFuZ29zIGFsdG9zIGRlIGxhIGVzY2FsYSBkZSBwdW50dWFjacOzbiwgbG8gcXVlIHN1Z2llcmUgcXVlIGVsIGNvbmp1bnRvIGRlIGp1ZWdvcyByZXNlw7FhZG9zIHByZXNlbnRhLCBlbiBnZW5lcmFsLCB1bmEgY2FsaWRhZCBwZXJjaWJpZGEgYnVlbmEgbyBtdXkgYnVlbmEgdGFudG8gcGFyYSBsYSBjcsOtdGljYSBwcm9mZXNpb25hbCBjb21vIHBhcmEgbG9zIHVzdWFyaW9zLCBhdW5xdWUgc2UgYXByZWNpYSBjaWVydGEgZGlzcGVyc2nDs24geSBhbGd1bm9zIG91dGxpZXJzIHF1ZSBjb3JyZXNwb25kZW4gYSB0w610dWxvcyBleGNlcGNpb25hbG1lbnRlIHZhbG9yYWRvcyBvLCBlbiBtZW5vciBtZWRpZGEsIHBlb3IgZXZhbHVhZG9zLiBGaW5hbG1lbnRlLCBlbCBib3hwbG90IGRlIG5fY3JpdGljb3NfbWV0YSBtdWVzdHJhIHVuYSBncmFuIGFzaW1ldHLDrWEgeSB1bmEgY29uY2VudHJhY2nDs24gZGUgdmFsb3JlcyBiYWpvcyBjb24gdW5hIGNvbGEgbGFyZ2EgaGFjaWEgbGEgZGVyZWNoYSwgbG8gcXVlIGluZGljYSBxdWUgbXVjaG9zIGp1ZWdvcyBjdWVudGFuIGNvbiBwb2NhcyByZXNlw7FhcyBkZSBjcsOtdGljb3MgbWllbnRyYXMgcXVlIHVuIGdydXBvIHJlZHVjaWRvIGFjdW11bGEgdW4gbsO6bWVybyBtdXkgZWxldmFkbyBkZSBjcsOtdGljYXMsIHJlZmxlamFuZG8gdW5hIHZpc2liaWxpZGFkIGRlc2lndWFsIGRvbmRlIHVub3MgcG9jb3MgdMOtdHVsb3MgY29uY2VudHJhbiBsYSBhdGVuY2nDs24gbWVkacOhdGljYSBkZWwgbWVyY2Fkby4NCg0KDQoNCiMjIyMgVmVjdG9yIGRlIE1lZGlhcyB5IEJveHBsb3RzIDIuIA0KDQpFbCBjb25qdW50byBkZSBib3hwbG90cyBtb3N0cmFkbyByZXN1bWUgbGEgZGlzdHJpYnVjacOzbiBkZSB0cmVzIHZhcmlhYmxlcyByZWxhY2lvbmFkYXMgY29uIGxhIHBhcnRpY2lwYWNpw7NuIGRlIGxvcyB1c3VhcmlvcyBlbiBsYXMgcmVzZcOxYXM6IGVsIG7Dum1lcm8gZGUgcmVzZcOxYXMgZGUgdXN1YXJpb3MgZW4gTWV0YWNyaXRpYyAobl91c3Vhcmlvc19tZXRhKSwgbGEgY2FsaWZpY2FjacOzbiBtZWRpYSBlbiBsYSBQbGF5U3RhdGlvbiBTdG9yZSAoY2FsaWZfcHNfc3RvcmUpIHkgZWwgbsO6bWVybyB0b3RhbCBkZSB2YWxvcmFjaW9uZXMgZW4gbGEgdGllbmRhIChuX3RvdGFsX3N0b3JlKS4gRWwgZ3LDoWZpY28gZGUgY2FqYXMgZXMgZXNwZWNpYWxtZW50ZSBhZGVjdWFkbyBwYXJhIGVzdG9zIGluZGljYWRvcmVzIHBvcnF1ZSBwZXJtaXRlIGNvbXBhcmFyLCBlbiB1bmEgbWlzbWEgZmlndXJhLCBsYSB0ZW5kZW5jaWEgY2VudHJhbCAobWVkaWFuYSksIGxhIGRpc3BlcnNpw7NuIChyYW5nbyBpbnRlcmN1YXJ0w61saWNvKSB5IGxhIHByZXNlbmNpYSBkZSB2YWxvcmVzIGF0w61waWNvcywgcmV2ZWxhbmRvIGRlIG1hbmVyYSBzaW50w6l0aWNhIHNpIGxhIGludGVyYWNjacOzbiBkZSBsb3MganVnYWRvcmVzIGNvbiBjYWRhIHTDrXR1bG8gZXN0w6EgY29uY2VudHJhZGEgZW4gdW5vcyBwb2NvcyBuaXZlbGVzIG8gc2ksIHBvciBlbCBjb250cmFyaW8sIGV4aXN0ZSB1bmEgZ3JhbiBoZXRlcm9nZW5laWRhZCBlbiBlbCB2b2x1bWVuIGRlIHJlc2XDsWFzIHkgZW4gbGFzIHB1bnR1YWNpb25lcyBhc2lnbmFkYXMuDQoNCmBgYHtyIFZlY3Rvcl9kZV9NZWRpYXNfeV9Cb3hwbG90cyAyLiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQphcHBseShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywtYygxLDIsMyw0LDUsNiw3LDgsOSwxMyldLCAyLCBtZWFuLCBuYS5ybSA9IFRSVUUpIA0KcmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zX3JlZHVjaWRvID0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssLWMoMSwyLDMsNCw1LDYsNyw4LDksMTMpXQ0Kbm9tYnJlc19ib3hwbG90cyA8LSBjKCJuX3VzdWFyaW9zX21ldGEiLCJjYWxpZl9wc19zdG9yZSIsIm5fdG90YWxfc3RvcmUiKQ0KDQpwYXIobWZyb3cgPSBjKDEsIG5jb2wocmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zX3JlZHVjaWRvKSkpDQppbnZpc2libGUobGFwcGx5KDE6bmNvbChyZXNlbmFzX2p1ZWdvc19lbGVjdHJvbmljb3NfcmVkdWNpZG8pLCBmdW5jdGlvbihpKSB7DQogIGJveHBsb3QocmVzZW5hc19qdWVnb3NfZWxlY3Ryb25pY29zX3JlZHVjaWRvW1tpXV0sDQogICAgbWFpbiA9IG5vbWJyZXNfYm94cGxvdHNbaV0sDQogICAgeWxpbSA9IHF1YW50aWxlKHJlc2VuYXNfanVlZ29zX2VsZWN0cm9uaWNvc19yZWR1Y2lkb1tbaV1dLCBjKDAuMDIsIDAuOTkpLCBuYS5ybSA9IFRSVUUpLA0KICAgIG5hLnJtID0gVFJVRSl9KSkNCmBgYA0KDQpFbiBlbCBib3hwbG90IGRlIG5fdXN1YXJpb3NfbWV0YSBzZSBhcHJlY2lhIHVuYSBkaXN0cmlidWNpw7NuIGZ1ZXJ0ZW1lbnRlIGFzaW3DqXRyaWNhOiBsYSBtYXlvcsOtYSBkZSBqdWVnb3MgYWN1bXVsYSB1biBuw7ptZXJvIHJlbGF0aXZhbWVudGUgYmFqbyBkZSByZXNlw7FhcyBkZSB1c3VhcmlvcywgbWllbnRyYXMgcXVlIHVuYSBwZXF1ZcOxYSBmcmFjY2nDs24gcHJlc2VudGEgdmFsb3JlcyBleHRyZW1hZGFtZW50ZSBhbHRvcywgdmlzaWJsZXMgY29tbyB1bmEgbGFyZ2EgY29sYSBkZSBvdXRsaWVycyBoYWNpYSBsYSBwYXJ0ZSBzdXBlcmlvci4gRXN0byBpbmRpY2EgcXVlIHPDs2xvIGNpZXJ0b3MgdMOtdHVsb3MgYWxjYW56YW4gdW4gbml2ZWwgZGUgbm90b3JpZWRhZCBzdWZpY2llbnRlIGNvbW8gcGFyYSBnZW5lcmFyIG1pbGVzIGRlIG9waW5pb25lcywgY29uY2VudHJhbmRvIGJ1ZW5hIHBhcnRlIGRlIGxhIGNvbnZlcnNhY2nDs24gZGUgbGEgY29tdW5pZGFkLiBFbiBjb250cmFzdGUsIGVsIGJveHBsb3QgZGUgY2FsaWZfcHNfc3RvcmUgbXVlc3RyYSB1bmEgY2FqYSBlc3RyZWNoYSB5IHNpdHVhZGEgZW4gdmFsb3JlcyBhbHRvcw0KDQoNCg0KIyMjIyBNYXRyaXogZGUgVmFyaWFuemFzLUNvdmFyaWFuemFzDQpMYSBzaWd1aWVudGUgdGFibGEgcHJlc2VudGEgbGEgbWF0cml6IGRlIHZhcmlhbnphcyB5IGNvdmFyaWFuemFzIGRlIGxhcyBwcmluY2lwYWxlcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBkZWwgZXN0dWRpbzogUHJlY2lvX21hc19hbHRvLCBwdW50X2NyaXRpY29zX21ldGEsIG5fY3JpdGljb3NfbWV0YSwgcHVudF91c3Vhcmlvc19tZXRhLCBuX3VzdWFyaW9zX21ldGEsIGNhbGlmX3BzX3N0b3JlLCBuX3RvdGFsX3N0b3JlIHkgYWx0byAocHJlY2lvIHJlZXNjYWxhZG8pLiBMYSBkaWFnb25hbCByZWNvZ2UgbGFzIHZhcmlhbnphcyBkZSBjYWRhIHZhcmlhYmxlLCBxdWUgbWlkZW4gc3UgZGlzcGVyc2nDs24gcmVzcGVjdG8gYSBsYSBtZWRpYSwgbWllbnRyYXMgcXVlIGxvcyBlbGVtZW50b3MgZnVlcmEgZGUgbGEgZGlhZ29uYWwgcmVwcmVzZW50YW4gbGFzIGNvdmFyaWFuemFzIGVudHJlIHBhcmVzIGRlIHZhcmlhYmxlcywgZXMgZGVjaXIsIGPDs21vIHRpZW5kZW4gYSB2YXJpYXIgY29uanVudGFtZW50ZSBlbiBlbCBtZXJjYWRvIGRlIHZpZGVvanVlZ29zIGFuYWxpemFkby4gRXN0YSBtYXRyaXogZXMgdW4gaW5zdW1vIGZ1bmRhbWVudGFsIGVuIGFuw6FsaXNpcyBtdWx0aXZhcmlhZG9zLCB5YSBxdWUgcmVzdW1lIGxhIGVzdHJ1Y3R1cmEgZGUgZGVwZW5kZW5jaWEgZW50cmUgcHJlY2lvLCBwdW50dWFjaW9uZXMgeSBuaXZlbGVzIGRlIHBhcnRpY2lwYWNpw7NuIGRlIHVzdWFyaW9zIHkgY3LDrXRpY29zLCB5IHNpcnZlIGRlIGJhc2UgcGFyYSB0w6ljbmljYXMgcG9zdGVyaW9yZXMgY29tbyBjb21wb25lbnRlcyBwcmluY2lwYWxlcywgcHJ1ZWJhcyBkZSBub3JtYWxpZGFkIG11bHRpdmFyaWFkYSB5IGRldGVjY2nDs24gZGUgb3V0bGllcnMuDQpgYGB7ciBtYXRyaXpfZGVfVmFyaWFuemFzX0NvdmFyaWFuemFzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnJvdW5kKGNvdihyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywtYygxLDMsNCw1LDYsMTMpXSksMikNCmBgYA0KTGFzIHZhcmlhbnphcyBtdWVzdHJhbiBxdWUgbl91c3Vhcmlvc19tZXRhIHkgbl90b3RhbF9zdG9yZSBwcmVzZW50YW4gdW5hIGRpc3BlcnNpw7NuIGV4dHJlbWFkYW1lbnRlIGVsZXZhZGEgZnJlbnRlIGFsIHJlc3RvIGRlIHZhcmlhYmxlcywgbG8gcXVlIGNvbmZpcm1hIHF1ZSBlbCB2b2x1bWVuIGRlIHJlc2XDsWFzIGRlIHVzdWFyaW9zIHkgZGUgdmFsb3JhY2lvbmVzIGVuIGxhIHRpZW5kYSBlc3TDoSBtdXkgY29uY2VudHJhZG8gZW4gdW5vcyBwb2NvcyB0w610dWxvcyBjb24gYWx0w61zaW1hIHZpc2liaWxpZGFkLCBtaWVudHJhcyBxdWUgbGEgbWF5b3LDrWEgZGUganVlZ29zIHJlY2liZSB1biBuw7ptZXJvIHJlbGF0aXZhbWVudGUgYmFqbyBkZSBpbnRlcmFjY2lvbmVzLiBMYXMgY292YXJpYW56YXMgcG9zaXRpdmFzIGVudHJlIFByZWNpb19tYXNfYWx0byB5IGxhcyBtZWRpZGFzIGRlIHBhcnRpY2lwYWNpw7NuIChuX3VzdWFyaW9zX21ldGEgeSBuX3RvdGFsX3N0b3JlKSBzdWdpZXJlbiBxdWUgbG9zIGp1ZWdvcyBjb24gcHJlY2lvcyBtw6FzIGFsdG9zIHRpZW5kZW4gYSBlc3RhciBhc29jaWFkb3MgYSBwcm9kdWN0b3MgY29uIG1heW9yIGV4cG9zaWNpw7NuIHkgbcOhcyByZXNlw7FhZG9zLCBhdW5xdWUgZXN0YSByZWxhY2nDs24gZGViZXLDoSBldmFsdWFyc2UgY29uIG1lZGlkYXMgZXN0YW5kYXJpemFkYXMgY29tbyBsYXMgY29ycmVsYWNpb25lcy4gQXNpbWlzbW8sIGxhcyBjb3ZhcmlhbnphcyBlbGV2YWRhcyBlbnRyZSBwdW50X2NyaXRpY29zX21ldGEsIHB1bnRfdXN1YXJpb3NfbWV0YSB5IGNhbGlmX3BzX3N0b3JlIGluZGljYW4gcXVlIGxhcyBkaXN0aW50YXMgbcOpdHJpY2FzIGRlIGNhbGlkYWQgcGVyY2liaWRhIHNlIG11ZXZlbiBlbiBsYSBtaXNtYSBkaXJlY2Npw7NuLCBsbyBxdWUgcmVzcGFsZGEgbGEgaWRlYSBkZSBjb2hlcmVuY2lhIGVudHJlIGxhIHZhbG9yYWNpw7NuIGRlIGxhIGNyw610aWNhLCBsYSBvcGluacOzbiBkZSBsb3MgdXN1YXJpb3MgeSBsYSBjYWxpZmljYWNpw7NuIGFncmVnYWRhIGVuIGxhIFBTIFN0b3JlIHBhcmEgbG9zIHZpZGVvanVlZ29zIGRlbCBjb25qdW50byBkZSBkYXRvcy4NCg0KDQojIyMjIE1hdHJpeiBkZSBDb3JyZWxhY2lvbmVzDQpMYSBzaWd1aWVudGUgbWF0cml6IGRlIGNvcnJlbGFjaW9uZXMgbXVlc3RyYSBsYSBpbnRlbnNpZGFkIHkgZGlyZWNjacOzbiBkZSBsYSByZWxhY2nDs24gbGluZWFsIGVudHJlIGxhcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBkZWwgZXN0dWRpbyAoUHJlY2lvX21hc19hbHRvLCBwdW50X2NyaXRpY29zX21ldGEsIG5fY3JpdGljb3NfbWV0YSwgcHVudF91c3Vhcmlvc19tZXRhLCBuX3VzdWFyaW9zX21ldGEsIGNhbGlmX3BzX3N0b3JlLCBuX3RvdGFsX3N0b3JlIHkgYWx0bykuIENhZGEgY29lZmljaWVudGUgdG9tYSB2YWxvcmVzIGVudHJlIC0xIHkgMSwgZG9uZGUgdmFsb3JlcyBjZXJjYW5vcyBhIDEgaW5kaWNhbiBhc29jaWFjacOzbiBwb3NpdGl2YSBmdWVydGUsIHZhbG9yZXMgY2VyY2Fub3MgYSAtMSBhc29jaWFjacOzbiBuZWdhdGl2YSBmdWVydGUgeSB2YWxvcmVzIHByw7N4aW1vcyBhIDAgYXVzZW5jaWEgZGUgcmVsYWNpw7NuIGxpbmVhbCBhcHJlY2lhYmxlLg0KYGBge3IgbWF0cml6X2RlX0NvcnJlbGFjaW9uZXMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0Kcm91bmQoY29yKHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbLC1jKDEsMyw0LDUsNiwxMyldKSwzKQ0KYGBgDQoNClNlIG9ic2VydmEgdW5hIGNvcnJlbGFjacOzbiBtdXkgYWx0YSBlbnRyZSBwdW50X2NyaXRpY29zX21ldGEgeSBwdW50X3VzdWFyaW9zX21ldGEsIGFzw60gY29tbyBlbnRyZSBlc3RhcyBwdW50dWFjaW9uZXMgeSBlbCBuw7ptZXJvIGRlIGNyw610aWNhcyAobl9jcml0aWNvc19tZXRhKSwgbG8gcXVlIGluZGljYSBxdWUgbG9zIGp1ZWdvcyBtZWpvciB2YWxvcmFkb3MgdGllbmRlbiB0YW1iacOpbiBhIHJlY2liaXIgbcOhcyByZXNlw7FhcyB5IGEgc2VyIGJpZW4gZXZhbHVhZG9zIHBvciBhbWJvcyBncnVwb3MuIFBvciBlbCBjb250cmFyaW8sIGVsIFByZWNpb19tYXNfYWx0byB5IGxhIGNhbGlmX3BzX3N0b3JlIHByZXNlbnRhbiBjb3JyZWxhY2lvbmVzIGJhamFzIG8gaW5jbHVzbyBsaWdlcmFtZW50ZSBuZWdhdGl2YXMgY29uIGVsIHJlc3RvIGRlIHZhcmlhYmxlcywgc3VnaXJpZW5kbyBxdWUgbmkgZWwgcHJlY2lvIG5pIGxhIHZhbG9yYWNpw7NuIGFncmVnYWRhIGVuIGxhIHRpZW5kYSBzZSByZWxhY2lvbmFuIGRlIGZvcm1hIGxpbmVhbCBmdWVydGUgY29uIGxhIHBvcHVsYXJpZGFkIG8gZWwgdm9sdW1lbiBkZSByZXNlw7FhcyBkZSBsb3MgdmlkZW9qdWVnb3MgYW5hbGl6YWRvcy4NCg0KIyMjIDEuNC4gR3LDoWZpY2FzIG11bHRpdmFyaWFkYXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCkVsIHZlY3RvciBkZSBtZWRpYXMgeSBsYSBtYXRyaXogZGUgdmFyaWFuemFzLWNvdmFyaWFuemFzIHNvbiBlbGVtZW50b3MgZnVuZGFtZW50YWxlcyBkZWwgYW7DoWxpc2lzIGVzdGFkw61zdGljbyBtdWx0aXZhcmlhZG8sIHB1ZXMgcGVybWl0ZW4gY2FyYWN0ZXJpemFyIGVsIGNvbXBvcnRhbWllbnRvIGNlbnRyYWwsIGxhIGRpc3BlcnNpw7NuIHkgbGFzIHJlbGFjaW9uZXMgZGUgZGVwZW5kZW5jaWEgZW50cmUgbGFzIHZhcmlhYmxlcyBkZSB1biBjb25qdW50byBkZSBkYXRvcy4gRXN0YXMgaGVycmFtaWVudGFzIGZhY2lsaXRhbiBsYSBjb21wcmVuc2nDs24gZ2xvYmFsIGRlIGxhIGVzdHJ1Y3R1cmEgaW50ZXJuYSBkZSBsYSBpbmZvcm1hY2nDs24gYW5hbGl6YWRhLiANCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMgW1NBXQ0KRWwgc2lndWllbnRlIGRpYWdyYW1hIGNvbmp1bnRvIGdlbmVyYWRvIGNvbiBnZ3BhaXJzIGNvbWJpbmEsIGVuIHVuYSBzb2xhIGZpZ3VyYSwgbG9zIGhpc3RvZ3JhbWFzIHVuaXZhcmlhZG9zIGRlIGNhZGEgdmFyaWFibGUgbnVtw6lyaWNhIChwcmVjaW8sIHB1bnR1YWNpb25lcywgbsO6bWVybyBkZSBjcsOtdGljYXMgeSB2YWxvcmFjaW9uZXMgdG90YWxlcykgY29uIGxvcyBkaWFncmFtYXMgZGUgZGlzcGVyc2nDs24gYml2YXJpYWRvcyB5IGxvcyBjb2VmaWNpZW50ZXMgZGUgY29ycmVsYWNpw7NuIGVudHJlIHRvZGFzIGVsbGFzLiBFc3RlIHRpcG8gZGUgdmlzdWFsaXphY2nDs24gZXMgZXNwZWNpYWxtZW50ZSDDunRpbCBlbiBhbsOhbGlzaXMgbXVsdGl2YXJpYWRvIHBvcnF1ZSBwZXJtaXRlLCBkZSB1biB2aXN0YXpvLCBleHBsb3JhciBsYSBmb3JtYSBkZSBsYXMgZGlzdHJpYnVjaW9uZXMgaW5kaXZpZHVhbGVzLCBkZXRlY3RhciBwb3NpYmxlcyByZWxhY2lvbmVzIGxpbmVhbGVzIG8gbm8gbGluZWFsZXMgZW50cmUgcGFyZXMgZGUgdmFyaWFibGVzIHkgZXZhbHVhciBsYSBmdWVyemEgZGUgZGljaGFzIHJlbGFjaW9uZXMgbWVkaWFudGUgbG9zIGNvZWZpY2llbnRlcyBkZSBjb3JyZWxhY2nDs24gbW9zdHJhZG9zIGVuIGxhIHBhcnRlIHN1cGVyaW9yIGRlIGNhZGEgcGFuZWwuDQoNCmBgYHtyIERpYWdyYW1hX3ZpZGVvanVlZ29zLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmdncGFpcnMocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssLWMoMSwzLDQsNSw2LDEzKV0pIA0KYGBgDQpFbiBsb3MgcGFuZWxlcyBzZSBvYnNlcnZhIHVuYSBjb3JyZWxhY2nDs24gZnVlcnRlIHkgcG9zaXRpdmEgZW50cmUgcHVudF9jcml0aWNvc19tZXRhLCBwdW50X3VzdWFyaW9zX21ldGEgeSBuX2NyaXRpY29zX21ldGEsIGxvIHF1ZSBpbmRpY2EgcXVlIGxvcyBqdWVnb3MgbWVqb3IgdmFsb3JhZG9zIHRpZW5kZW4gYSByZWNpYmlyIG3DoXMgcmVzZcOxYXMgeSBxdWUgZXhpc3RlIGNvaGVyZW5jaWEgZW50cmUgbGEgb3BpbmnDs24gZGUgY3LDrXRpY29zIHkgdXN1YXJpb3MuIFRhbWJpw6luIHNlIGFwcmVjaWEgcXVlIHZhcmlhYmxlcyBjb21vIFByZWNpb19tYXNfYWx0byB5IGNhbGlmX3BzX3N0b3JlIHByZXNlbnRhbiBudWJlcyBkZSBwdW50b3MgbXV5IGRpc3BlcnNhcyB5IGNvZWZpY2llbnRlcyBkZSBjb3JyZWxhY2nDs24gYmFqb3MgcmVzcGVjdG8gYWwgcmVzdG8sIGxvIHF1ZSBzdWdpZXJlIHF1ZSBuaSBlbCBwcmVjaW8gbcOheGltbyBuaSBsYSBjYWxpZmljYWNpw7NuIGFncmVnYWRhIGVuIGxhIFBTIFN0b3JlIGd1YXJkYW4gdW5hIHJlbGFjacOzbiBsaW5lYWwgY2xhcmEgY29uIGxhIHBvcHVsYXJpZGFkIG1lZGlkYSBwb3IgZWwgbsO6bWVybyBkZSByZXNlw7FhcyBvIGNvbiBsYXMgcHVudHVhY2lvbmVzIGRlIE1ldGFjcml0aWMuDQoNCg0KIyMjIyBEaWFncmFtYSBDb25qdW50byBkZSBEaXNwZXJzacOzbiwgRGlzdHJpYnVjacOzbiB5IENvcnJlbGFjaW9uZXMgW0NBOkdFXQ0KRWwgc2lndWllbnRlIGRpYWdyYW1hIGdncGFpcnMgbXVlc3RyYSwgZGUgZm9ybWEgY29uanVudGEsIGxhcyBkaXN0cmlidWNpb25lcywgbG9zIGRpYWdyYW1hcyBkZSBkaXNwZXJzacOzbiB5IGxvcyBjb2VmaWNpZW50ZXMgZGUgY29ycmVsYWNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyByZWxhY2lvbmFkYXMgY29uIGV2YWx1YWNpb25lcyB5IHBhcnRpY2lwYWNpw7NuIGRlIHVzdWFyaW9zIChQcmVjaW9fbWFzX2FsdG8sIHB1bnRfY3JpdGljb3NfbWV0YSwgbl9jcml0aWNvc19tZXRhLCBwdW50X3VzdWFyaW9zX21ldGEsIG5fdXN1YXJpb3NfbWV0YSB5IGNhbGlmX3BzX3N0b3JlKSwgZGlmZXJlbmNpYW5kbyBkb3MgZ3J1cG9zIHNlZ8O6biBsYSB2YXJpYWJsZSBjYXRlZ8OzcmljYSBwYXJ0X3B1YmxpIHF1ZSBjbGFzaWZpY2EgbGEgcGFydGljaXBhY2nDs24gcHVibGljaXRhcmlhIGRlIGxvcyBqdWVnb3MgZW4gbml2ZWxlcyBiYWpvIChCKSB5IG1lZGlvIChNKS4gRWwgY29sb3JlbyBwb3IgZ3J1cG9zIHBlcm1pdGUgY29tcGFyYXIgc2kgbGEgZXN0cnVjdHVyYSBkZSByZWxhY2lvbmVzIGVudHJlIHByZWNpbywgcHVudHVhY2lvbmVzIHkgdm9sdW1lbiBkZSByZXNlw7FhcyBjYW1iaWEgc2Vnw7puIGVsIG5pdmVsIGRlIGludmVyc2nDs24gbyB2aXNpYmlsaWRhZCBwdWJsaWNpdGFyaWEuDQoNCmBgYHtyIERpYWdyYW1hX2Rpc3BlcnNpb25fcGFydF9wdWJsaSwgZmlnLmFsaWduPSdjZW50ZXInfQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcyRwYXJ0X3B1YmxpIDwtIGZhY3RvcigNCiAgcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcyRwYXJ0aWNpcGFjaW9uX3B1YmxpX2NhdCwNCiAgbGV2ZWxzID0gYygxLCAyKSwNCiAgbGFiZWxzID0gYygiQiIsICJNIikpDQpnZ3BhaXJzKHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MsY29sdW1ucyA9IGMoMiwgNywgOCwgOSwgMTAsIDExKSwgICAgICBhZXMoY29sb3IgPSBwYXJ0X3B1YmxpLCBhbHBoYSA9IDAuNSksIHVwcGVyID0gbGlzdChjb250aW51b3VzID0gd3JhcCgiY29yIiwgc2l6ZSA9IDIuNSkpKQ0KYGBgDQpFbiBsb3MgcGFuZWxlcyBkZSBkaXNwZXJzacOzbiBzZSBvYnNlcnZhIHF1ZSBsb3MganVlZ29zIGNvbiBtYXlvciBwYXJ0aWNpcGFjacOzbiBwdWJsaWNpdGFyaWEgKGdydXBvIE0pIHRpZW5kZW4gYSBjb25jZW50cmFyc2UgZW4gcmFuZ29zIG3DoXMgYWx0b3MgZGUgbl9jcml0aWNvc19tZXRhLCBuX3VzdWFyaW9zX21ldGEgeSBuX3RvdGFsX3N0b3JlLCBsbyBxdWUgc3VnaWVyZSBxdWUgbGEgcHVibGljaWRhZCBzZSBhc29jaWEgY29uIHVuYSBtYXlvciB2aXNpYmlsaWRhZCB5IG7Dum1lcm8gZGUgcmVzZcOxYXMgdGFudG8gY3LDrXRpY2FzIGNvbW8gZGUgdXN1YXJpb3MuIFNpbiBlbWJhcmdvLCBsYXMgY29ycmVsYWNpb25lcyBlbnRyZSBwdW50dWFjaW9uZXMgKHB1bnRfY3JpdGljb3NfbWV0YSwgcHVudF91c3Vhcmlvc19tZXRhLCBjYWxpZl9wc19zdG9yZSkgeSBlbCBwcmVjaW8gcGFyZWNlbiBzaW1pbGFyZXMgZW4gYW1ib3MgZ3J1cG9zLCBsbyBxdWUgaW5kaWNhIHF1ZSBsYSBwdWJsaWNpZGFkIGluZmx1eWUgbcOhcyBlbiBlbCB2b2x1bWVuIGRlIGludGVyYWNjacOzbiBxdWUgZW4gbGEgdmFsb3JhY2nDs24gbWVkaWEgZGUgbG9zIGp1ZWdvcywgbGEgY3VhbCBzaWd1ZSBkZXRlcm1pbmFkYSBwcmluY2lwYWxtZW50ZSBwb3IgbGEgY2FsaWRhZCBwZXJjaWJpZGEgZGVsIHByb2R1Y3RvLg0KDQoNCiMjIyMgRGlhZ3JhbWEgZGUgRXN0cmVsbGFzDQpFbCBkaWFncmFtYSBkZSBlc3RyZWxsYXMgcHJlc2VudGEgZWwgcGVyZmlsIG11bHRpdmFyaWFkbyBkZSAyMCB2aWRlb2p1ZWdvcyBzZWxlY2Npb25hZG9zIGFsZWF0b3JpYW1lbnRlLCB1c2FuZG8gY29tbyByYWRpb3MgbGFzIHZhcmlhYmxlcyBudW3DqXJpY2FzIFByZWNpb19tYXNfYWx0bywgcHVudF9jcml0aWNvc19tZXRhLCBuX2NyaXRpY29zX21ldGEsIHB1bnRfdXN1YXJpb3NfbWV0YSwgbl91c3Vhcmlvc19tZXRhLCBjYWxpZl9wc19zdG9yZSB5IG5fdG90YWxfc3RvcmUuIENhZGEgZXN0cmVsbGEgcmVzdW1lIHNpbXVsdMOhbmVhbWVudGUgZWwgbml2ZWwgZGUgcHJlY2lvLCBsYXMgcHVudHVhY2lvbmVzIHkgZWwgdm9sdW1lbiBkZSByZXNlw7FhcywgcGVybWl0aWVuZG8gY29tcGFyYXIgZGUgZm9ybWEgdmlzdWFsIHF1w6kgdMOtdHVsb3MgZGVzdGFjYW4gZW4gZGV0ZXJtaW5hZGFzIGRpbWVuc2lvbmVzIGRlbCBtZXJjYWRvLg0KYGBge3IgZGlhZ3JhbWFfZGVfRXN0cmVsbGFzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MkYWx0byA8LSBOVUxMDQpzZXQuc2VlZCgxMjA1MjIpDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG8gPSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zW3NhbXBsZSgxOm5yb3cocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcyksMjApLC1jKDEsMyw0LDUsNiwxMyldDQpzdGFycyhyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG8sIGxlbiA9IDEsIGNleCA9IDAuNCwga2V5LmxvYyA9IGMoMTIsIDIpLCBkcmF3LnNlZ21lbnRzID0gVFJVRSkNCmBgYA0KTGFzIGVzdHJlbGxhcyBjb24gc2VnbWVudG9zIG3DoXMgbGFyZ29zIGVuIG5fdXN1YXJpb3NfbWV0YSB5IG5fdG90YWxfc3RvcmUgY29ycmVzcG9uZGVuIGEganVlZ29zIGNvbiBncmFuIHBvcHVsYXJpZGFkIHkgYWx0YSBwYXJ0aWNpcGFjacOzbiBkZSBsYSBjb211bmlkYWQsIG1pZW50cmFzIHF1ZSBhcXVlbGxhcyBjb24gcmFkaW9zIGNvcnRvcyBlbiBlc3RhcyB2YXJpYWJsZXMgcmVwcmVzZW50YW4gdMOtdHVsb3MgY29uIGJhamEgdmlzaWJpbGlkYWQuIEFsZ3VuYXMgZXN0cmVsbGFzIG11ZXN0cmFuIGNvbWJpbmFjaW9uZXMgZGUgcHJlY2lvIGVsZXZhZG8geSBwYXJ0aWNpcGFjacOzbiBtb2RlcmFkYSwgaW5kaWNhbmRvIHByb2R1Y3RvcyBkZSBnYW1hIGFsdGEgYcO6biBlbiBjb25zb2xpZGFjacOzbiwgbWllbnRyYXMgcXVlIG90cmFzIHByZXNlbnRhbiBwZXJmaWxlcyBtw6FzIGVxdWlsaWJyYWRvcywgcHJvcGlvcyBkZSBqdWVnb3MgY29uIHByZWNpb3MgeSBldmFsdWFjaW9uZXMgaW50ZXJtZWRpYXMgZW4gZWwgY2F0w6Fsb2dvIGFuYWxpemFkby4NCg0KDQojIyMjIENhcmFzIGRlIENoZXJub2ZmDQpFbCBzaWd1aWVudGUgZ3LDoWZpY28gZGUgY2FyYXMgZGUgQ2hlcm5vZmYgcmVwcmVzZW50YSAyMyB2aWRlb2p1ZWdvcyBzZWxlY2Npb25hZG9zIGFsZWF0b3JpYW1lbnRlIGEgcGFydGlyIGRlIGxhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgKFByZWNpb19tYXNfYWx0bywgcHVudHVhY2lvbmVzIHkgY29udGVvcyBkZSByZXNlw7FhcyksIHRyYW5zZm9ybWFuZG8gY2FkYSB2ZWN0b3IgZGUgdmFsb3JlcyBlbiB1biByb3N0cm8gY29uIHJhc2dvcyBmYWNpYWxlcyBkaXN0aW50b3MuIExhIGZvcm1hIHkgZWwgdGFtYcOxbyBkZSBlbGVtZW50b3MgY29tbyBvam9zLCBib2NhLCBvcmVqYXMgbyBjYWJlemEgY29kaWZpY2FuIGNvbWJpbmFjaW9uZXMgZGUgbGFzIHZhcmlhYmxlcywgZGUgbW9kbyBxdWUgZGlmZXJlbmNpYXMgZW4gbGEgZXhwcmVzacOzbiBkZSBsYXMgY2FyYXMgcmVmbGVqYW4gcGF0cm9uZXMgbXVsdGl2YXJpYWRvcyBkaWZlcmVuY2lhZG9zIGVudHJlIGxvcyBqdWVnb3MgYW5hbGl6YWRvcy4NCmBgYHtyIGNhcmFzX2RlX0NoZXJub2ZmLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCnNldC5zZWVkKDEyMDUyMikNCm5vX251bWVyaWNhcyA8LSB3aGljaCghc2FwcGx5KHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MsIGlzLm51bWVyaWMpKQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc18xX011ZXN0cmVhZG8gPXJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbDQogICAgc2FtcGxlKDE6bnJvdyhyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zKSwgMjMpLC1ub19udW1lcmljYXNdDQpmYWNlcyhyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zXzFfTXVlc3RyZWFkbykNCmBgYA0KTGFzIGNhcmFzIG3DoXMg4oCcZXh0cmVtYXPigJ0sIGNvbiBjYWJlemFzIG3DoXMgZ3JhbmRlcywgb2pvcyBtw6FzIGFiaWVydG9zIHUgb3JlamFzIG3DoXMgYWxhcmdhZGFzLCBjb3JyZXNwb25kZW4gYSB0w610dWxvcyBjb24gdmFsb3JlcyBhbHRvcyBzaW11bHTDoW5lYW1lbnRlIGVuIHZhcmlhcyBkaW1lbnNpb25lcywgdMOtcGljYW1lbnRlIGp1ZWdvcyBjb24gcHJlY2lvcyBlbGV2YWRvcywgYWx0YXMgcHVudHVhY2lvbmVzIHkgZ3JhbiBuw7ptZXJvIGRlIHJlc2XDsWFzLCBxdWUgc2UgZGlzdGluZ3VlbiB2aXN1YWxtZW50ZSBkZWwgcmVzdG8uIEVuIGNhbWJpbywgbG9zIHJvc3Ryb3MgbcOhcyBob21vZ8OpbmVvcyB5IHBlcXVlw7FvcyByZXByZXNlbnRhbiB2aWRlb2p1ZWdvcyBjb24gcGVyZmlsZXMgbcOhcyBtb2Rlc3RvcyBlbiBwcmVjaW8sIGNhbGlkYWQgcGVyY2liaWRhIHkgcGFydGljaXBhY2nDs24gZGUgdXN1YXJpb3MsIGxvIHF1ZSBpbmRpY2EgcXVlIGVsIG1lcmNhZG8gaW5jbHV5ZSB0YW50byBwcm9kdWN0b3MgZXN0cmVsbGEgY2xhcmFtZW50ZSBkaWZlcmVuY2lhZG9zIGNvbW8gdW5hIG1heW9yw61hIGRlIHTDrXR1bG9zIGNvbiBjYXJhY3RlcsOtc3RpY2FzIG1lZGlhcyBvIGJhamFzLg0KDQoNCiMjIyAxLjUuIE5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMgUE5NIE1hcmRpYQ0KTGEgcHJ1ZWJhIGRlIG5vcm1hbGlkYWQgbXVsdGl2YXJpYWRhIGRlIE1hcmRpYSBldmFsw7phIHNpIGVsIHZlY3RvciBmb3JtYWRvIHBvciBsYXMgdmFyaWFibGVzIGN1YW50aXRhdGl2YXMgZGVsIGVzdHVkaW8gKHByZWNpb19tYXNfYWx0bywgcHVudF9jcml0aWNvcywgbl9jcml0aWNvcywgcHVudF91c3Vhcmlvcywgbl91c3VhcmlvcywgY2FsaWZfcHMgeSBuX3BzKSBwdWVkZSBjb25zaWRlcmFyc2UgcHJvY2VkZW50ZSBkZSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwgY29uanVudGEuIFBhcmEgZWxsbyBjYWxjdWxhIGRvcyBlc3RhZMOtc3RpY2FzLCB1bmEgYXNvY2lhZGEgYWwgc2VzZ28gKHNrZXduZXNzKSB5IG90cmEgYSBsYSBjdXJ0b3NpcywgeSBjb250cmFzdGEgaGlww7N0ZXNpcyBkZSBub3JtYWxpZGFkIHRhbnRvIGEgbml2ZWwgbXVsdGl2YXJpYWRvIGNvbW8gZGUgZm9ybWEgdW5pdmFyaWFudGUgcGFyYSBjYWRhIHZhcmlhYmxlLg0KYGBge3IgUE5NX01hcmRpYSwgZmlnLmFsaWduPSdjZW50ZXInfQ0KbGlicmFyeShNVk4pDQpkYXRvc19tdm4gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1sNCiAgLCBjKCJQcmVjaW9fbWFzX2FsdG8iLCAicHVudF9jcml0aWNvc19tZXRhIiwgIm5fY3JpdGljb3NfbWV0YSIsDQogICAgICAicHVudF91c3Vhcmlvc19tZXRhIiwgIm5fdXN1YXJpb3NfbWV0YSIsICJjYWxpZl9wc19zdG9yZSIsDQogICAgICAibl90b3RhbF9zdG9yZSIsICJwYXJ0aWNpcGFjaW9uX3B1YmxpX2NhdCIpXQ0KZGF0b3NfbXZuIDwtIG5hLm9taXQoZGF0b3NfbXZuKQ0KbXZuX3Jlc3VsdCA8LSBtdm4oZGF0YSAgICAgID0gZGF0b3NfbXZuLG12bl90ZXN0ICA9ICJtYXJkaWEiKQ0KcHJpbnQobXZuX3Jlc3VsdCkNCmBgYA0KTG9zIHZhbG9yZXMgb2J0ZW5pZG9zIHBhcmEgTWFyZGlhIChzZXNnbyA9IDEgMzk0IDYwMC40MTkgeSBjdXJ0b3NpcyA9IDcgNTgzLjQ4OCwgY29uIHDigJF2YWxvcmVzIDwgMC4wMDEpIGxsZXZhbiBhIHJlY2hhemFyIGNsYXJhbWVudGUgbGEgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEsIGluZGljYW5kbyBxdWUgZWwgY29uanVudG8gZGUgdmFyaWFibGVzLCBpbmNsdWlkbyBwcmVjaW9fbWFzX2FsdG8sIHByZXNlbnRhIHVuYSBlc3RydWN0dXJhIG11eSBhbGVqYWRhIGRlIGxhIGRpc3RyaWJ1Y2nDs24gbm9ybWFsLiBEZSBmb3JtYSBjb25zaXN0ZW50ZSwgbGFzIHBydWViYXMgdW5pdmFyaWFudGVzIGRlIEFuZGVyc29u4oCRRGFybGluZyBtdWVzdHJhbiBxdWUgY2FkYSB2YXJpYWJsZSBwb3Igc2VwYXJhZG8gdGFtcG9jbyBlcyBub3JtYWwgKHDigJF2YWxvcmVzIDwgMC4wMDEpLCBjb24gYXNpbWV0csOtYXMgeSBjdXJ0b3NpcyBlc3BlY2lhbG1lbnRlIGV4dHJlbWFzIGVuIG5fdXN1YXJpb3MgeSBuX3BzLCBkb25kZSB1bm9zIHBvY29zIHZpZGVvanVlZ29zIGNvbmNlbnRyYW4gdmFsb3JlcyBtdXkgYWx0b3MgZGUgcmVzZcOxYXMgbyB2ZW50YXMgbWllbnRyYXMgbGEgbWF5b3LDrWEgc2UgbWFudGllbmUgZW4gbml2ZWxlcyBiYWpvcy4NCg0KDQojIyMjIFBOTSBIZW56ZS1aaXJrbGVyDQpMYSBwcnVlYmEgZGUgSGVuemXigJNaaXJrbGVyIGVzIHVuIGNvbnRyYXN0ZSBnbG9iYWwgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgcXVlIGV2YWzDumEgc2kgZWwgdmVjdG9yIGZvcm1hZG8gcG9yIHByZWNpb19tYXNfYWx0bywgcHVudF9jcml0aWNvcywgbl9jcml0aWNvcywgcHVudF91c3Vhcmlvcywgbl91c3VhcmlvcywgY2FsaWZfcHMgeSBuX3BzIHB1ZWRlIGNvbnNpZGVyYXJzZSBwcm9jZWRlbnRlIGRlIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbCBjb25qdW50YS4gU2UgYmFzYSBlbiB1bmEgbWVkaWRhIGRlIGRpc3RhbmNpYSBlbnRyZSBsYSBkaXN0cmlidWNpw7NuIGVtcMOtcmljYSBkZSBsb3MgZGF0b3MgeSBsYSBkaXN0cmlidWNpw7NuIG5vcm1hbCB0ZcOzcmljYSBlcXVpdmFsZW50ZSwgZ2VuZXJhbmRvIHVuYSBlc3RhZMOtc3RpY2EgSCBaIHkgdW4gdmFsb3IgcCBhc29jaWFkby4NCmBgYHtyIFBOTV9IZW56ZV9aaXJrbGVyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCm12bihyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywgLWMoMSwgMywgNCwgNSwgNiwgMTMpXSwgbXZuX3Rlc3QgPSAiaHoiKQ0KYGBgDQpMYSBlc3RhZMOtc3RpY2EgZGUgSGVuemXigJNaaXJrbGVyIG9idGVuaWRhIGVzIDM4MC4xODcsIGNvbiB1biBw4oCRdmFsb3IgPCAwLjAwMSwgcG9yIGxvIHF1ZSBzZSByZWNoYXphIGxhIGhpcMOzdGVzaXMgZGUgbm9ybWFsaWRhZCBtdWx0aXZhcmlhZGEgcGFyYSBlbCBjb25qdW50byBkZSB2YXJpYWJsZXMsIGNvbmZpcm1hbmRvIGVsIHJlc3VsdGFkbyBvYnNlcnZhZG8gcHJldmlhbWVudGUgY29uIGxhIHBydWViYSBkZSBNYXJkaWEuIERlIG51ZXZvLCBsYXMgcHJ1ZWJhcyB1bml2YXJpYW50ZXMgZGUgQW5kZXJzb27igJNEYXJsaW5nIG11ZXN0cmFuIHF1ZSBjYWRhIHZhcmlhYmxlIHBvciBzZXBhcmFkbywgaW5jbHVpZG8gcHJlY2lvX21hc19hbHRvLCBzZSBkZXN2w61hIHNpZ25pZmljYXRpdmFtZW50ZSBkZSBsYSBub3JtYWxpZGFkLCBjb24gZnVlcnRlcyBhc2ltZXRyw61hcyB5IGN1cnRvc2lzIG11eSBlbGV2YWRhcyBlbiBuX3VzdWFyaW9zIHkgbl9wcywgbG8gcXVlIHJlZmxlamEgbGEgcHJlc2VuY2lhIGRlIGNvbGFzIGxhcmdhcyB5IHZhbG9yZXMgZXh0cmVtb3MgY2FyYWN0ZXLDrXN0aWNvcyBkZWwgbWVyY2FkbyBkZSB2aWRlb2p1ZWdvcy4NCg0KIyMjIyBQTk0gRG9vcm5pay1IYW5zZW4NCmBgYHtyIFBOTV9Eb29ybmlrX0hhbnNlbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQptdm4ocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIC1jKDEsIDMsIDQsIDUsIDYsIDEzKV0sIG12bl90ZXN0ID0gImRvb3JuaWtfaGFuc2VuIikNCmBgYA0KDQojIyMjIFBOTSBSb3lzdG9uDQpgYGB7ciBQTk1fUm95c3RvbiwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19saW1waW9zIDwtIG5hLm9taXQocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIC1jKDEsMyw0LDUsNiwxMyldKQ0KZGF0b3Nfcm95c3RvbiA8LSBkYXRvc19saW1waW9zWzE6MjAwMCwgXQ0KbXZuKGRhdG9zX3JveXN0b24sIG12bl90ZXN0ID0gInJveXN0b24iKQ0KYGBgDQoNCg0KIyMgKipGYXNlIDIgW0NvbXBvbmVudGVzIFByaW5jaXBhbGVzXSoqIA0KDQoqRWwgQW7DoWxpc2lzIGRlIENvbXBvbmVudGVzIFByaW5jaXBhbGVzIChBQ1ApKiB0aWVuZSBjb21vIGZpbmFsaWRhZCB0cmFuc2Zvcm1hciBlbCBjb25qdW50byBvcmlnaW5hbCBkZSB2YXJpYWJsZXMgbnVtw6lyaWNhcyBlbiB1biBudWV2byBjb25qdW50byBkZSBjb21wb25lbnRlcyBxdWUgY29uY2VudHJlbiBsYSBtYXlvciBwYXJ0ZSBkZSBsYSBpbmZvcm1hY2nDs24gY29udGVuaWRhIGVuIGxvcyBkYXRvcy4gRW4gZWwgcHJlc2VudGUgZXN0dWRpbywgZWwgQUNQIHNlIGFwbGljYSBzb2JyZSB1biBncnVwbyBkZSB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBxdWUgZGVzY3JpYmVuIGVsIGRlc2VtcGXDsW8geSBsYSByZWNlcGNpw7NuIGRlIGxvcyB2aWRlb2p1ZWdvcywgdGFsZXMgY29tbyBsYXMgcHVudHVhY2lvbmVzIG90b3JnYWRhcyBwb3IgY3LDrXRpY29zIHkgdXN1YXJpb3MsIGFzw60gY29tbyBsYSBjYW50aWRhZCBkZSByZXNlw7FhcyByZWdpc3RyYWRhcyBlbiBkaWZlcmVudGVzIHBsYXRhZm9ybWFzLiBNZWRpYW50ZSBlc3RlIHByb2NlZGltaWVudG8gZXN0YWTDrXN0aWNvLCBzZSBidXNjYSByZWR1Y2lyIGxhIGNvbXBsZWppZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcywgaWRlbnRpZmljYW5kbyBsYXMgY29tYmluYWNpb25lcyBsaW5lYWxlcyBkZSB2YXJpYWJsZXMgcXVlIG1lam9yIGV4cGxpY2FuIGxhIHZhcmlhYmlsaWRhZCB0b3RhbCBvYnNlcnZhZGEuIERlIGVzdGEgbWFuZXJhLCBlbCBBQ1AgZmFjaWxpdGEgdW5hIGludGVycHJldGFjacOzbiBtw6FzIGNsYXJhIGRlIGxhcyByZWxhY2lvbmVzIGVudHJlIGxhcyBkaXN0aW50YXMgbWVkaWRhcyBkZSB2YWxvcmFjacOzbiwgcGVybWl0aWVuZG8gcmVwcmVzZW50YXIgbGEgaW5mb3JtYWNpw7NuIGVuIHVuIGVzcGFjaW8gZGUgbWVub3IgZGltZW5zacOzbiBzaW4gcGVyZGVyIGxhIGVzZW5jaWEgZGVsIGNvbXBvcnRhbWllbnRvIGdlbmVyYWwgZGUgbG9zIGRhdG9zLg0KDQojIyMgMi4xLiBPYmpldGl2b3MNCkVsIEFuw6FsaXNpcyBkZSBDb21wb25lbnRlcyBQcmluY2lwYWxlcyAoQUNQKSBzZSBkZXNhcnJvbGxhIGEgdHJhdsOpcyBkZSBkaXN0aW50YXMgZXRhcGFzIHF1ZSBpbmNsdXllbiBsYSBjb25zdHJ1Y2Npw7NuIGRlIG51ZXZhcyB2YXJpYWJsZXMsIGxhIHJlZHVjY2nDs24gZGUgbGEgZGltZW5zaW9uYWxpZGFkIGRlbCBjb25qdW50byBkZSBkYXRvcywgbGEgaWRlbnRpZmljYWNpw7NuIHkgZWxpbWluYWNpw7NuIGRlIHZhcmlhYmxlcyBjb24gYmFqYSByZWxldmFuY2lhLCB5IGxhIGludGVycHJldGFjacOzbiBkZSBsb3MgY29tcG9uZW50ZXMgb2J0ZW5pZG9zIGRlbnRybyBkZWwgY29udGV4dG8gZGVsIHByb2JsZW1hIGFuYWxpemFkby4NCg0KRXN0aW1hZG8gbGVjdG9yLCBzaSBkZXNlYSBwcm9mdW5kaXphciBlbiBsb3MgZnVuZGFtZW50b3MgdGXDs3JpY29zIHF1ZSByZXNwYWxkYW4gZXN0ZSBhbsOhbGlzaXMsIGxvcyBkZXRhbGxlcyBkZWwgY29uanVudG8gZGUgZGF0b3Mgc2UgZW5jdWVudHJhbiBleHB1ZXN0b3MgZW4gbGEgW1NlY2Npw7NuIDEuMl0oI3NlYzEuMiksbWllbnRyYXMgcXVlIGxvcyBwcmluY2lwaW9zIGNvbmNlcHR1YWxlcyBzb2JyZSBsb3MgcXVlIHNlIGFwb3lhIGVzdGUgZXN0dWRpbyBzZSBkZXNhcnJvbGxhbiBjb24gZGV0YWxsZSBlbiBsYSBbRmFzZSAxXSgjc2VjMSkuDQoNCiMjIyAyLjIuIFNlbGVjY2nDs24gZGUgQ29tcG9uZW50ZXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyBNYXRyaXogQUNQDQpgYGB7ciBNYXRyaXpfQUNQLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX3BjYSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywNCmMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIildDQpyZXMucGNhIDwtIFBDQShkYXRvc19wY2EsIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFKQ0KZ2V0X2VpZ2VudmFsdWUocmVzLnBjYSkNCmBgYA0KDQojIyMjIE1hdHJpeiBkZSBDb3JyZWxhY2lvbmVzDQpgYGB7ciBNYXRyaXpfZGVfQ29ycmVsYWNpb25lc30NCmRhdG9zX2NvciA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywNCmMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwgIm5fdG90YWxfc3RvcmUiKV0NCnJvdW5kKGNvcihkYXRvc19jb3IsIHVzZSA9ICJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKSwgMikNCmBgYA0KDQojIyMjIFZhbG9yZXMgeSBWZWN0b3JlcyBQcm9waW9zDQpgYGB7ciBWYWxvcmVzX3lfVmVjdG9yZXNfUHJvcGlvcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19wY2EgPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssDQpjKCJQcmVjaW9fbWFzX2FsdG8iLCJwdW50X2NyaXRpY29zX21ldGEiLCJuX2NyaXRpY29zX21ldGEiLCJwdW50X3VzdWFyaW9zX21ldGEiLCJuX3VzdWFyaW9zX21ldGEiLCJjYWxpZl9wc19zdG9yZSIsIm5fdG90YWxfc3RvcmUiKV0NCmRhdG9zX3BjYSA8LSBuYS5vbWl0KGRhdG9zX3BjYSkNCmRhdG9zX3BjYSA8LSBkYXRvc19wY2FbaXMuZmluaXRlKHJvd1N1bXMoZGF0b3NfcGNhKSksIF0NCnZhbG9yZXNfcHJvcGlvcyA8LSBwcmluY29tcChkYXRvc19wY2EsIGNvciA9IFRSVUUpJHNkZXZeMg0KdmVjdG9yZXNfcHJvcGlvcyA8LSBwcmluY29tcChkYXRvc19wY2EsIGNvciA9IFRSVUUpJGxvYWRpbmdzWywgMTo1XQ0KcHJpbnQocm91bmQodmFsb3Jlc19wcm9waW9zLCAyKSkNCnByaW50KHJvdW5kKHZlY3RvcmVzX3Byb3Bpb3MsIDMpKQ0KDQpgYGANCg0KIyMjIyBDb3JyZWxhY2lvbmVzIENvbXBhcmFkYXMNCmBgYHtyIENvcnJlbGFjaW9uZXNfQ29tcGFyYWRhcywgZmlnLmFsaWduPSdjZW50ZXInfQ0KZGF0b3NfbnVtIDwtIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbLA0KYygiUHJlY2lvX21hc19hbHRvIiwNCiJwdW50X2NyaXRpY29zX21ldGEiLA0KIm5fY3JpdGljb3NfbWV0YSIsDQoicHVudF91c3Vhcmlvc19tZXRhIiwNCiJuX3VzdWFyaW9zX21ldGEiLA0KImNhbGlmX3BzX3N0b3JlIiwNCiJuX3RvdGFsX3N0b3JlIildDQpkYXRvc19udW0gPC0gbmEub21pdChkYXRvc19udW0pDQpyZXN1bHRhZG9fcGNhIDwtIHByaW5jb21wKGRhdG9zX251bSwgY29yID0gVFJVRSkNCmNvcnJwbG90KGNvcihkYXRvc19udW0pLCBtZXRob2QgPSAiY29sb3IiLCB0eXBlID0gInVwcGVyIiwgbnVtYmVyLmNleCA9IDAuNCkNCmBgYA0KDQojIyMjIEdyw6FmaWNvIGRlIENhdHRlbGwNCmBgYHtyIEdyYWZpY29fZGVfQ2F0dGVsbCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19udW0gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIA0KICBjKCJQcmVjaW9fbWFzX2FsdG8iLA0KICAgICJwdW50X2NyaXRpY29zX21ldGEiLA0KICAgICJuX2NyaXRpY29zX21ldGEiLA0KICAgICJwdW50X3VzdWFyaW9zX21ldGEiLA0KICAgICJuX3VzdWFyaW9zX21ldGEiLA0KICAgICJjYWxpZl9wc19zdG9yZSIsDQogICAgIm5fdG90YWxfc3RvcmUiKV0NCmRhdG9zX251bSA8LSBuYS5vbWl0KGRhdG9zX251bSkNCnJlcy5wY2EgPC0gUENBKGRhdG9zX251bSwgbmNwID0gOCwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UpDQpmdml6X2VpZyhyZXMucGNhLCBhZGRsYWJlbHMgPSBUUlVFLCB5bGltID0gYygwLCA5MCksIG1haW4gPSAiIikNCmBgYA0KDQojIyMjIEdyw6FmaWNvIGRlIENhdHRlbGwtS2Fpc2VyDQpgYGB7ciBHcmFmaWNvX2RlX0NhdHRlbGxfS2Fpc2VyLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX251bSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywgDQogIGMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwibl90b3RhbF9zdG9yZSIpXQ0Kc2NyZWUoZGF0b3NfbnVtLCBmYWN0b3JzID0gRkFMU0UsIHBjID0gVFJVRSwgbWFpbiA9ICIiKQ0KYGBgDQoNCiMjIyAyLjMuIENhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMgQ8OtcmN1bG8gZGUgQ29ycmVsYWNpb25lcw0KYGBge3IgQ2lyY3Vsb19kZV9Db3JyZWxhY2lvbmVzLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX251bSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywNCmMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwibl90b3RhbF9zdG9yZSIpXQ0KZGF0b3NfbnVtIDwtIG5hLm9taXQoZGF0b3NfbnVtKQ0KcmVzLnBjYSA8LSBQQ0EoZGF0b3NfbnVtLCBuY3AgPSA4LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGQUxTRSkNCmZ2aXpfcGNhX3ZhcihyZXMucGNhLGNvbC52YXIgPSAiIzNCODNCRCIscmVwZWwgPSBUUlVFLGNvbC5jaXJjbGUgPSAiI0NEQ0RDRCIsZ2d0aGVtZSA9IHRoZW1lX2J3KCkpDQpgYGANCg0KYGBge3IgdW5kZWZpbmVkLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX251bSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywgDQogIGMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwibl90b3RhbF9zdG9yZSIpXQ0KZGF0b3NfbnVtIDwtIG5hLm9taXQoZGF0b3NfbnVtKQ0KcmVzLnBjYSA8LSBQQ0EoZGF0b3NfbnVtLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGQUxTRSkNCmZ2aXpfY29udHJpYigNCiAgcmVzLnBjYSwNCiAgY2hvaWNlID0gInZhciIsDQogIGF4ZXMgICA9IDEsDQogIHRvcCAgICA9IDEwDQopDQpgYGANCg0KIyMjIyBNYXRyaXogZGUgUmVwcmVzZW50YWNpw7NuDQpgYGB7ciBNYXRyaXpfZGVfUmVwcmVzc2VudGFjaW9uX0NPUzIsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZGF0b3NfbnVtIDwtIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbLA0KYygiUHJlY2lvX21hc19hbHRvIiwicHVudF9jcml0aWNvc19tZXRhIiwibl9jcml0aWNvc19tZXRhIiwicHVudF91c3Vhcmlvc19tZXRhIiwibl91c3Vhcmlvc19tZXRhIiwiY2FsaWZfcHNfc3RvcmUiLCJuX3RvdGFsX3N0b3JlIildDQpkYXRvc19udW0gPC0gbmEub21pdChkYXRvc19udW0pDQpyZXMucGNhIDwtIFBDQShkYXRvc19udW0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFKQ0KdmFyIDwtIGdldF9wY2FfdmFyKHJlcy5wY2EpDQp2YXIkY29zMiANCmBgYA0KDQojIyMjIENhbGlkYWQgZGUgUmVwcmVzZW50YWNpw7NuDQpgYGB7ciBDYWxpZGFkX2RlX2xhX1JlcHJlc2VudGFjaW9uLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX251bSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywgDQogIGMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwibl90b3RhbF9zdG9yZSIpXQ0KZGF0b3NfbnVtIDwtIG5hLm9taXQoZGF0b3NfbnVtKQ0KcmVzLnBjYSA8LSBQQ0EoZGF0b3NfbnVtLCBuY3AgPSA1LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGQUxTRSkNCmZ2aXpfcGNhX3ZhciggcmVzLnBjYSwgY29sLnZhciAgICAgICA9ICJjb3MyIiwNCiAgZ3JhZGllbnQuY29scyA9IGMoIiNENzI2M0QiLCAiIzFBMUFGRiIsICIjRkY5ODAwIikscmVwZWwgICAgICAgICA9IFRSVUUpDQpgYGANCg0KIyMjIyBDb29yZGVuYWRhcyBJbmRpdmlkdWFsZXMNCmBgYHtyIENvb3JkZW5hZGFzX1JlZ2lzdHJvcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19udW0gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIA0KICBjKCJQcmVjaW9fbWFzX2FsdG8iLCJwdW50X2NyaXRpY29zX21ldGEiLCJuX2NyaXRpY29zX21ldGEiLCJwdW50X3VzdWFyaW9zX21ldGEiLCJuX3VzdWFyaW9zX21ldGEiLCJjYWxpZl9wc19zdG9yZSIsIm5fdG90YWxfc3RvcmUiKV0NCmRhdG9zX251bSA8LSBuYS5vbWl0KGRhdG9zX251bSkNCnJlcy5wY2EgPC0gUENBKGRhdG9zX251bSwgbmNwID0gNSwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UpDQpoZWFkKHJlcy5wY2EkaW5kJGNvb3JkLCBuID0gMjBMKQ0KYGBgDQoNCiMjIyAyLjQuIENvbnRyaWJ1Y2lvbmVzIHkgQmlwbG90cyANCkxvcyBhdXRvcmVzIChEw61heiBNb3JhbGVzICYgTW9yYWxlcyBSaXZlcmEsIDIwMTIpIGRlc3RhY2FuIHF1ZSBsYSBpbnRlcnByZXRhY2nDs24gZGUgbG9zIHJlc3VsdGFkb3MgZW4gZWwgYW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIGRlcGVuZGUgZXN0cmVjaGFtZW50ZSBkZWwgY8OhbGN1bG8gZGUgZWxlbWVudG9zIGNvbW8gY29vcmRlbmFkYXMsIGNvbnRyaWJ1Y2lvbmVzIHkgY29zZW5vcyBjdWFkcmFkb3MuIEVuIGVsIGNvbnRleHRvIGRlIGxvcyBkYXRvcyBzb2JyZSB2aWRlb2p1ZWdvcywgZXMgZnVuZGFtZW50YWwgcXVlIHZhcmlhYmxlcyBjb21vIGxhcyBwdW50dWFjaW9uZXMgZGUgY3LDrXRpY29zLCBuw7ptZXJvIGRlIHJlc2XDsWFzLCBjYWxpZmljYWNpb25lcyBkZSB1c3VhcmlvcywgZ8OpbmVyb3MgbyBjaWZyYXMgZGUgdmVudGFzIGVzdMOpbiBjb3JyZWN0YW1lbnRlIGNvbmNlcHR1YWxpemFkYXMgeSBjb250ZXh0dWFsaXphZGFzIHBhcmEgdW5hIGNvbXByZW5zacOzbiBjbGFyYSB5IHByZWNpc2EuDQoNCg0KIyMjIDIuNC4xICBNYXRyaXogZGUgQ29udHJpYnVjaW9uZXMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KTGEgKipNYXRyaXogZGUgQ29udHJpYnVjaW9uZXMqKiBtdWVzdHJhIGPDs21vIGNhZGEgdmFyaWFibGUgY29udHJpYnV5ZSBhIGxhIHJldGVuY2nDs24gZGUgdmFyaWFiaWxpZGFkIGVuIGxhIGNvbnN0cnVjY2nDs24gZGUgY2FkYSBjb21wb25lbnRlLiBMb3MgZGlhZ3JhbWFzIGRlIGJhcnJhcywgcXVlIHNlIHZpc3VhbGl6YW4gZW4gbGFzIHBlc3Rhw7FhcyBkZXNkZSAqKkNvbnRyaWJ1Y2lvbmVzIGEgRDEqKiBoYXN0YSAqKkNvbnRyaWJ1Y2lvbmVzIGEgRDUqKiwgaWx1c3RyYW4gbGFzIGNvbnRyaWJ1Y2lvbmVzIGVzcGVjw61maWNhcyBkZSBsYXMgdmFyaWFibGVzIHBhcmEgZXhwbGljYXIgbGEgdmFyaWFiaWxpZGFkIGVuIGNhZGEgY29tcG9uZW50ZS4gQ2FkYSBncsOhZmljbyBpbmNsdXllIHVuYSBsw61uZWEgcXVlIGluZGljYSBsYSAqY29udHJpYnVjacOzbiBtZWRpYSosIGxvIHF1ZSBmYWNpbGl0YSBsYSBpZGVudGlmaWNhY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBxdWUgdGllbmVuIG1heW9yIGltcGFjdG8gZW4gbGEgZXhwbGljYWNpw7NuIGRlIGxhIHZhcmlhYmlsaWRhZCBkZSBsb3MgY29tcG9uZW50ZXMuDQoNCg0KRW4gKipDb250cmlidWNpb25lcyBhIEQxKiogc2Ugb2JzZXJ2YSBxdWUgbGFzIHZhcmlhYmxlcyAqKnB1bnRfdXN1YXJpb3MsKiogKipwdW50X2NyaXRpY29zKiogeSAqKm5fY3JpdGljb3MqKiBwcmVzZW50YW4gdW5hIGNvbnRyaWJ1Y2nDs24gY2xhcmFtZW50ZSBzdXBlcmlvciBhIGxhIG1lZGlhLCByZXRlbmllbmRvIGFwcm94aW1hZGFtZW50ZSBlbCAkOTAlJCBkZSBsYSB2YXJpYWJpbGlkYWQgZXhwbGljYWRhIHBvciBlbCBwcmltZXIgY29tcG9uZW50ZSBwcmluY2lwYWwuDQoNCg0KIyMjIyBNYXRyaXogZGUgQ29udHJpYnVjaW9uZXMNCmBgYHtyIE1hdHJpel9kZV9Db250cmlidWNpb25lcywgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19udW0gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIA0KICBjKCJQcmVjaW9fbWFzX2FsdG8iLCJwdW50X2NyaXRpY29zX21ldGEiLCJuX2NyaXRpY29zX21ldGEiLCJwdW50X3VzdWFyaW9zX21ldGEiLCJuX3VzdWFyaW9zX21ldGEiLCJjYWxpZl9wc19zdG9yZSIsIm5fdG90YWxfc3RvcmUiKV0NCmRhdG9zX251bSA8LSBuYS5vbWl0KGRhdG9zX251bSkNCnJlcy5wY2EgPC0gUENBKGRhdG9zX251bSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UpDQp2YXIgPC0gZ2V0X3BjYV92YXIocmVzLnBjYSkNCnZhciRjb250cmliDQpgYGANCg0KIyMjIyBDb250cmlidWNpb25lcyBhIEQxDQpgYGB7ciBDb250cmlidWNpb25lc19ESU1fMSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19udW0gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIA0KICBjKCJQcmVjaW9fbWFzX2FsdG8iLCJwdW50X2NyaXRpY29zX21ldGEiLCJuX2NyaXRpY29zX21ldGEiLCJwdW50X3VzdWFyaW9zX21ldGEiLCJuX3VzdWFyaW9zX21ldGEiLCJjYWxpZl9wc19zdG9yZSIsIm5fdG90YWxfc3RvcmUiKV0NCmRhdG9zX251bSA8LSBuYS5vbWl0KGRhdG9zX251bSkNCnJlcy5wY2EgPC0gUENBKGRhdG9zX251bSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UpDQpmdml6X2NvbnRyaWIocmVzLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAxLCB0b3AgPSAxMCkNCmBgYA0KDQojIyMjIENvbnRyaWJ1Y2lvbmVzIGEgRDINCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0RJTV8yLCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX251bSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywgDQogIGMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwibl90b3RhbF9zdG9yZSIpXQ0KZGF0b3NfbnVtIDwtIG5hLm9taXQoZGF0b3NfbnVtKQ0KcmVzLnBjYSA8LSBQQ0EoZGF0b3NfbnVtLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGQUxTRSkNCmZ2aXpfY29udHJpYihyZXMucGNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDIsIHRvcCA9IDEwKQ0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMgYSBEMw0KYGBge3IgQ29udHJpYnVjaW9uZXNfRElNXzMsIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KZGF0b3NfbnVtIDwtIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbLCANCiAgYygiUHJlY2lvX21hc19hbHRvIiwicHVudF9jcml0aWNvc19tZXRhIiwibl9jcml0aWNvc19tZXRhIiwicHVudF91c3Vhcmlvc19tZXRhIiwibl91c3Vhcmlvc19tZXRhIiwiY2FsaWZfcHNfc3RvcmUiLCJuX3RvdGFsX3N0b3JlIildDQpkYXRvc19udW0gPC0gbmEub21pdChkYXRvc19udW0pDQpyZXMucGNhIDwtIFBDQShkYXRvc19udW0sIG5jcCA9IDYsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFKQ0KZnZpel9jb250cmliKHJlcy5wY2EsIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMywgdG9wID0gMTApDQpgYGANCg0KIyMjIyBDb250cmlidWNpb25lcyBhIEQ0DQpgYGB7ciBDb250cmlidWNpb25lc19ESU1fNCwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpkYXRvc19udW0gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1ssIA0KICBjKCJQcmVjaW9fbWFzX2FsdG8iLCJwdW50X2NyaXRpY29zX21ldGEiLCJuX2NyaXRpY29zX21ldGEiLCJwdW50X3VzdWFyaW9zX21ldGEiLCJuX3VzdWFyaW9zX21ldGEiLCJjYWxpZl9wc19zdG9yZSIsIm5fdG90YWxfc3RvcmUiKV0NCmRhdG9zX251bSA8LSBuYS5vbWl0KGRhdG9zX251bSkNCnJlcy5wY2EgPC0gUENBKGRhdG9zX251bSwgbmNwID0gNiwgc2NhbGUudW5pdCA9IFRSVUUsIGdyYXBoID0gRkFMU0UpDQpmdml6X2NvbnRyaWIocmVzLnBjYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSA0LCB0b3AgPSAxMCkNCmBgYA0KDQojIyMjIENvbnRyaWJ1Y2lvbmVzIGEgRDUNCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0RJTV81LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30NCmRhdG9zX251bSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zWywgDQogIGMoIlByZWNpb19tYXNfYWx0byIsInB1bnRfY3JpdGljb3NfbWV0YSIsIm5fY3JpdGljb3NfbWV0YSIsInB1bnRfdXN1YXJpb3NfbWV0YSIsIm5fdXN1YXJpb3NfbWV0YSIsImNhbGlmX3BzX3N0b3JlIiwibl90b3RhbF9zdG9yZSIpXQ0KZGF0b3NfbnVtIDwtIG5hLm9taXQoZGF0b3NfbnVtKQ0KcmVzLnBjYSA8LSBQQ0EoZGF0b3NfbnVtLCBuY3AgPSA2LCBzY2FsZS51bml0ID0gVFJVRSwgZ3JhcGggPSBGQUxTRSkNCmZ2aXpfY29udHJpYihyZXMucGNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDUsIHRvcCA9IDEwKQ0KYGBgDQoNCg0KIyMjIDIuNC4yICBQbGFudGVhbWllbnRvIHkgRGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIEJpcGxvdCBkZSBWYXJpYWJsZXMgeSBSZWdpc3Ryb3MgW2ZpbHRybzpDaGVzdFBhaW5dDQpgYGB7ciBCaXBsb3RfVmFyaWFibGVzX1JlZ2lzdHJvc19GaWx0cm9fY2hlc3RwYWlufQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcyA8LSByZWFkX2V4Y2VsICgiQzovVXNlcnMvanVhbmVfeHQ4MmYvT25lRHJpdmUvRXNjcml0b3Jpby9HU0RfNi9yZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zLnhsc3giKQ0KDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG8gPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1sNCiAgc2FtcGxlKDE6bnJvdyhyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zKSwgMTAwKSwNCiAgLWMoMSwzLDQsNSw2LDEzKV0NCg0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19NdWVzdHJlYWRvJHB1bnRfdXN1YXJpb3NfY2F0IDwtIGN1dCgNCiAgcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19NdWVzdHJlYWRvJHB1bnRfdXN1YXJpb3NfbWV0YSwNCiAgYnJlYWtzID0gYygtSW5mLCAzLCA1LCA3LjUsIEluZiksICANCiAgbGFiZWxzID0gYygiTXV5IE1hbG8iLCAiTWFsbyIsICJCdWVubyIsICJNdXkgQnVlbm8iKSkNCg0KZnZpel9wY2FfYmlwbG90KFBDQShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG9bLF0sIG5jcCA9IDUsIHNjYWxlLnVuaXQgPSBUUlVFLCBncmFwaCA9IEZBTFNFLCBxdWFsaS5zdXAgPSAicHVudF91c3Vhcmlvc19jYXQiKSxheGVzID0gYygxLCAyKSxyZXBlbCA9IFRSVUUsIGhhYmlsbGFnZSA9ICJwdW50X3VzdWFyaW9zX2NhdCIpDQpgYGANCg0KIyMjIyBCaXBsb3QgZGUgVmFyaWFibGVzIHkgUmVnaXN0cm9zIFtmaWx0cm86Ti5vZiBNYWpvciBWZXNzZWxzXQ0KYGBge3IgQmlwbG90X2RlX1ZhcmlhYmxlc195X1JlZ2lzdHJvc19maWx0cm9fcmVzdGluZ2VsZWN0cm99DQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL2p1YW5lX3h0ODJmL09uZURyaXZlL0VzY3JpdG9yaW8vR1NEXzYvcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcy54bHN4IikNCg0Kc2V0LnNlZWQoNzgwNzI5KQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19NdWVzdHJlYWRvIDwtIHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NbIHNhbXBsZSgxOm5yb3cocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvcyksIDE1MCksIC1jKDEsMyw0LDUsNiwxMyldDQoNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfTXVlc3RyZWFkbyRjYWxpZl9wc19jYXQgPC0gY3V0KA0KICByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG8kY2FsaWZfcHNfc3RvcmUsDQogIGJyZWFrcyA9IGMoLUluZiwgMywgNC41LCBJbmYpLA0KICBsYWJlbHMgPSBjKCJCYWphIiwgIk1lZGlhIiwgIkFsdGEiKSkNCg0KbnVtX2NvbHMgPC0gc2FwcGx5KHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfTXVlc3RyZWFkbywgaXMubnVtZXJpYykNCmRmX3BjYSA8LSByZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG9bLCBudW1fY29sc10NCmRmX3BjYSRjYWxpZl9wc19jYXQgPC0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19NdWVzdHJlYWRvJGNhbGlmX3BzX2NhdA0KcGNhX3Jlc3VsdCA8LSBQQ0EoZGZfcGNhLG5jcCA9IDUsc2NhbGUudW5pdCA9IFRSVUUsZ3JhcGggPSBGQUxTRSxxdWFsaS5zdXAgPSB3aGljaChuYW1lcyhkZl9wY2EpID09ICJjYWxpZl9wc19jYXQiKSkNCg0KZnZpel9wY2FfYmlwbG90KHBjYV9yZXN1bHQsYXhlcyA9IGMoMSwyKSxyZXBlbCA9IFRSVUUsaGFiaWxsYWdlID0gImNhbGlmX3BzX2NhdCIpDQpgYGANCg0KIyMjIyBDb29yZGVuYWRhcyBJbmRpdmlkdWFsZXMgW0NoZXN0UGFpbl0NCmBgYHtyIGNvb3JkZW5hZGFzX2luZGl2aWR1YWxlc30NCnNldC5zZWVkKDIyMDUxMikNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfTXVlc3RyZWFkbz0gcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc1tzYW1wbGUoMTpucm93KHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MpLDQ3KSwtYygxLDMsNCw1LDYsMTMpXQ0KDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX011ZXN0cmVhZG8kbl91c3Vhcmlvc19jYXQgPC0gY3V0KA0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19NdWVzdHJlYWRvJG5fdXN1YXJpb3NfbWV0YSwNCmJyZWFrcyA9IGMoLUluZiwgNSwgNTAsIEluZiksDQpsYWJlbHMgPSBjKCJCYWpvIiwgIk1lZGlvIiwgIkFsdG8iKSkNCg0KaGVhZChQQ0EocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19NdWVzdHJlYWRvLG5jcCA9IDQsc2NhbGUudW5pdCA9IFRSVUUsZ3JhcGggPSBGQUxTRSwgcXVhbGkuc3VwID0gIm5fdXN1YXJpb3NfY2F0IikkaW5kJGNvb3JkLCBuID0gNDBMKQ0KYGBgDQoNCg0KPGEgbmFtZT0ic2VjMyI+PC9hPg0KDQojIyAqKkZhc2UgMyBbQ29ycmVzcG9uZGVuY2lhc10qKg0KDQpFbCBhbsOhbGlzaXMgZGUgY29ycmVzcG9uZGVuY2lhcyBzZSBlbXBsZWEgcGFyYSBlc3R1ZGlhciBsYSBhc29jaWFjacOzbiBlbnRyZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzLCBjb21vIHB1ZWRlIHNlciBnw6luZXJvIHkgcGxhdGFmb3JtYSwgbyBnw6luZXJvIHkgcmVnacOzbiBkZSB2ZW50YXMuIEVzdGUgZW5mb3F1ZSBwZXJtaXRlIHZpc3VhbGl6YXIgZW4gdW4gcGxhbm8gcmVkdWNpZG8gbGEgcmVsYWNpw7NuIGVudHJlIGNhdGVnb3LDrWFzLCBmYWNpbGl0YW5kbyBsYSBpbnRlcnByZXRhY2nDs24gZGUgY8OzbW8gc2UgdmluY3VsYW4gbG9zIGRpZmVyZW50ZXMgZ3J1cG9zIGRlbnRybyBkZWwgZGF0YXNldC4gQXPDrSwgcG9yIGVqZW1wbG8sIHNlIHB1ZWRlIGlkZW50aWZpY2FyIHNpIGNpZXJ0b3MgZ8OpbmVyb3Mgc29uIHByZWZlcmlkb3MgZW4gZGV0ZXJtaW5hZGFzIHBsYXRhZm9ybWFzIG8gcmVnaW9uZXMsIGRlc2N1YnJpZW5kbyBwYXRyb25lcyByZWxldmFudGVzIGVuIGVsIGNvbnN1bW8gZGUgdmlkZW9qdWVnb3MuDQoNCiMjIyAzLjEuIE9iamV0aXZvcw0KDQpFbiBlc3RhIHRlcmNlcmEgZmFzZSBkZWwgZXN0dWRpbyBzZSBwcmVzZW50YXLDoW4gbG9zIGPDoWxjdWxvcywgdmlzdWFsaXphY2lvbmVzIGUgaW50ZXJwcmV0YWNpb25lcyBjb3JyZXNwb25kaWVudGVzIGFsIGFuw6FsaXNpcyBkZSBsYXMgdmFyaWFibGVzIGN1YWxpdGF0aXZhcyBkZWwgY29uanVudG8gZGUgZGF0b3MgcHJldmlhbWVudGUgdHJhYmFqYWRvIGVuIGxhIFtmYXNlIDFdKCNzZWMxKSB5IFtmYXNlIDJdKCNzZWMyKS4gRWwgcHJvcMOzc2l0byBkZSBlc3RhIGV0YXBhIGVzIGFwbGljYXIgZWwgQW7DoWxpc2lzIGRlIENvcnJlc3BvbmRlbmNpYXMgU2ltcGxlcyB5IE3Dumx0aXBsZXMgKEFDUyB5IEFDTSksIGNvbiBlbCBmaW4gZGUgZXhwbG9yYXIgbGFzIHJlbGFjaW9uZXMgZW50cmUgY2F0ZWdvcsOtYXMgeSByZXByZXNlbnRhciBncsOhZmljYW1lbnRlIGxhcyBhc29jaWFjaW9uZXMgZXhpc3RlbnRlcy5QYXJhIGVsbG8sIHNlIGxsZXZhcsOhIGEgY2FibyBsYSBjb25zdHJ1Y2Npw7NuIGRlIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgeSB0YWJsYXMgZGlzeXVudGl2YXMgY29tcGxldGFzLCBhc8OtIGNvbW8gbGEgZXZhbHVhY2nDs24gZGUgbGEgY2FsaWRhZCBkZSByZXByZXNlbnRhY2nDs24sIGxhcyBjb250cmlidWNpb25lcyB5IGxhIGludGVycHJldGFjacOzbiBkZSBsb3MgZWplcyBmYWN0b3JpYWxlcyBvYnRlbmlkb3MuDQoNCiMjIyAzLjIuIENvcnJlc3BvbmRlbmNpYXMgU2ltcGxlcyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQpTZWfDum4gW0BBTUFSQWxkYXMtVXJpZWwyZWRdLGVsICoqYW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMqKiBzaW1wbGUgKiooQUNTKSoqIHRpZW5lIGNvbW8gcHJvcMOzc2l0byByZWR1Y2lyIGxhIGRpbWVuc2lvbmFsaWRhZCBkZSBsYXMgcmVsYWNpb25lcyBlbnRyZSBjYXRlZ29yw61hcyBkZSBkb3MgdmFyaWFibGVzIGNhdGVnw7NyaWNhcywgcmVwcmVzZW50w6FuZG9sYXMgZW4gdW4gZXNwYWNpbyBtdWx0aWRpbWVuc2lvbmFsLiBFc3RlIG3DqXRvZG8gcGVybWl0ZSBhbmFsaXphciBncsOhZmljYW1lbnRlIGxhcyBkaXN0YW5jaWFzIGVudHJlIGxhcyBjYXRlZ29yw61hcyBkZSBsYXMgdmFyaWFibGVzLCBmYWNpbGl0YW5kbyBsYSBpbnRlcnByZXRhY2nDs24gZGUgdGFibGFzIGRlIGNvbnRpbmdlbmNpYS4gRWwgbsO6bWVybyBtw6F4aW1vIGRlIGRpbWVuc2lvbmVzIG5lY2VzYXJpYXMgcGFyYSBleHBsaWNhciBkaWNoYXMgcmVsYWNpb25lcyBjb3JyZXNwb25kZSBhIHVubyBtZW5vcyBlbCBuw7ptZXJvIGRlIGNhdGVnb3LDrWFzIGRlIGxhIHZhcmlhYmxlIGNvbiBtZW5vciBjYW50aWRhZCBkZSBuaXZlbGVzLg0KDQpBc2ltaXNtbywgZWwgKipBQ1MqKiwgYmFzYWRvIGVuIHRhYmxhcyBkZSBjb250aW5nZW5jaWEsIHB1ZWRlIGFtcGxpYXJzZSBwYXJhIGluY2x1aXIgbcOhcyBkZSBkb3MgdmFyaWFibGVzIGNhdGVnw7NyaWNhcywgbG8gcXVlIHNlIGNvbm9jZSBjb21vICoqQW7DoWxpc2lzIGRlIGNvcnJlc3BvbmRlbmNpYXMgbcO6bHRpcGxlcyAoQUNNKSoqLiBFc3RlIGVuZm9xdWUgdXRpbGl6YSB1bmEgdGFibGEgZGlzeXVudGl2YSBjb21wbGV0YSwgcGVybWl0aWVuZG8gZXhwbG9yYXIgeSByZXByZXNlbnRhciByZWxhY2lvbmVzIG3DoXMgY29tcGxlamFzIGVudHJlIG3Dumx0aXBsZXMgdmFyaWFibGVzIGNhdGVnw7NyaWNhcy4NCg0KDQojIyMgMy4yLjEgUGxhbnRlYW1pZW50byB5IERlc2Fycm9sbG8gDQoNCiMjIyMgQUMgUGFyZWphcyBUb3RhbGVzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCg0KIyMjIDMuMy4gQ29ycmVzcG9uZGVuY2lhcyBNw7psdGlwbGVzIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMgQUNNDQpgYGB7ciBBQ00sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9qdWFuZV94dDgyZi9PbmVEcml2ZS9Fc2NyaXRvcmlvL0dTRF82L3Jlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIueGxzeCIpDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyJGxhbnphbWllbnRvIDwtIGFzLkRhdGUocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiRsYW56YW1pZW50bywgb3JpZ2luID0gIjE4OTktMTItMzAiKQ0KDQpzZXQuc2VlZCg3ODA3MjkpDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyLmFjdGl2ZTwtcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMltzYW1wbGUoMTpucm93KHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIpLDE1KSwgMTo1XQ0KDQoNCnN1cHByZXNzV2FybmluZ3Mocm91bmQoTUNBKHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIuYWN0aXZlLCBncmFwaCA9IEZBTFNFLCBuY3AgPSA1KSRlaWcsIDMpKQ0KYGBgDQoNCiMjIyMgQmlwbG90IEFDTQ0KYGBge3IgQmlwbG90X0FDTSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL2p1YW5lX3h0ODJmL09uZURyaXZlL0VzY3JpdG9yaW8vR1NEXzYvcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMi54bHN4IikNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIkbGFuemFtaWVudG8gPC0gYXMuRGF0ZShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyJGxhbnphbWllbnRvLCBvcmlnaW4gPSAiMTg5OS0xMi0zMCIpDQoNCnNldC5zZWVkKDc4MDcyOSkNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIuYWN0aXZlPC1yZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyW3NhbXBsZSgxOm5yb3cocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiksMTAwKSwgMTo1XQ0KDQpyZXMubWNhIDwtIE1DQShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyLmFjdGl2ZSwgZ3JhcGggPSBGQUxTRSkNCg0KI3Jlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3MkZ2VuZXJvIDwtIGFzLmZhY3RvcihyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zJGdlbmVybykNCg0KI2hhYmlsbGFnZSA9ICJnZW5lcm8iLA0KDQpmdml6X21jYV9iaXBsb3QocmVzLm1jYSwgcmVwZWwgPSBUUlVFLCBjb2wudmFyID0gIiNFN0I4MDAiLCBhZGRFbGxpcHNlcyA9IFRSVUUsIGVsbGlwc2UubGV2ZWwgPSAwLjk1KQ0KYGBgDQoNCg0KIyMjIyBDYWxpZGFkIGRlIFJlcHJlc2VudGFjacOzbg0KYGBge3IgQ2FsaWRhZF9kZV9SZXByZXNlbnRhY2lvbl9BQ00sIGZpZy5hbGlnbiA9ICdjZW50ZXInfQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9qdWFuZV94dDgyZi9PbmVEcml2ZS9Fc2NyaXRvcmlvL0dTRF82L3Jlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIueGxzeCIpDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyJGxhbnphbWllbnRvIDwtIGFzLkRhdGUocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiRsYW56YW1pZW50bywgb3JpZ2luID0gIjE4OTktMTItMzAiKQ0KDQpzZXQuc2VlZCg3ODA3MjkpDQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyLmFjdGl2ZTwtcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMltzYW1wbGUoMTpucm93KHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIpLDUwKSwgMTo1XQ0KDQpyZXMubWNhIDwtIE1DQShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyLmFjdGl2ZSwgZ3JhcGggPSBGQUxTRSkNCg0KI3Jlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIkZ2VuZXJvIDwtIGFzLmZhY3RvcihyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyJGdlbmVybykNCg0KZnZpel9tY2FfdmFyKHJlcy5tY2EsIGNvbC52YXIgPSJjb3MyIiwgZ3JhZGllbnQuY29scyA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIsICIjRkM0RTA3IiksIHJlcGVsID0gVFJVRSkNCg0KcmVzLm1jYSR2YXIkY29zMg0KYGBgDQoNCiMjIyMgQ29udHJpYnVjaW9uZXMNCmBgYHtyIENvbnRyaWJ1Y2lvbmVzX0FDTSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQoNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvanVhbmVfeHQ4MmYvT25lRHJpdmUvRXNjcml0b3Jpby9HU0RfNi9yZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyLnhsc3giKQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiRsYW56YW1pZW50byA8LSBhcy5EYXRlKHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIkbGFuemFtaWVudG8sIG9yaWdpbiA9ICIxODk5LTEyLTMwIikNCg0Kc2V0LnNlZWQoNzgwNzI5KQ0KcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMi5hY3RpdmU8LXJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjJbc2FtcGxlKDE6bnJvdyhyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyKSwgMTAwMCksIDE6NV0NCg0KcmVzLm1jYSA8LSBNQ0EocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMi5hY3RpdmUsIGdyYXBoID0gRkFMU0UpDQoNCmZ2aXpfY29udHJpYihyZXMubWNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDEsIHRvcCA9IDE1KQ0KZnZpel9jb250cmliKHJlcy5tY2EsIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gMiwgdG9wID0gMTUpDQpmdml6X2NvbnRyaWIocmVzLm1jYSwgY2hvaWNlID0gInZhciIsIGF4ZXMgPSAzLCB0b3AgPSAxNSkNCmZ2aXpfY29udHJpYihyZXMubWNhLCBjaG9pY2UgPSAidmFyIiwgYXhlcyA9IDQsIHRvcCA9IDE1KQ0KZnZpel9jb250cmliKHJlcy5tY2EsIGNob2ljZSA9ICJ2YXIiLCBheGVzID0gNSwgdG9wID0gMTUpDQpgYGANCg0KIyMjIyBCaXBsb3QgY29uIENvbnRyaWJ1Y2lvbmVzDQpgYGB7ciBCaXBsb3RfY29uX0NvbnRyaWJ1Y2lvbmVzX0FDTSwgZmlnLmFsaWduID0gJ2NlbnRlcid9DQpyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL2p1YW5lX3h0ODJmL09uZURyaXZlL0VzY3JpdG9yaW8vR1NEXzYvcmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMi54bHN4IikNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIkbGFuemFtaWVudG8gPC0gYXMuRGF0ZShyZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyJGxhbnphbWllbnRvLCBvcmlnaW4gPSAiMTg5OS0xMi0zMCIpDQoNCnNldC5zZWVkKDc4MDcyOSkNCnJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIuYWN0aXZlPC1yZXNlbmFzX2RlX2p1ZWdvc19lbGVjdHJvbmljb3NfZGVwdXJhZG9zX1YyW3NhbXBsZSgxOm5yb3cocmVzZW5hc19kZV9qdWVnb3NfZWxlY3Ryb25pY29zX2RlcHVyYWRvc19WMiksMjApLCAxOjVdDQoNCnJlcy5tY2EgPC0gTUNBKHJlc2VuYXNfZGVfanVlZ29zX2VsZWN0cm9uaWNvc19kZXB1cmFkb3NfVjIuYWN0aXZlLCBncmFwaCA9IEZBTFNFKQ0KDQpmdml6X21jYV92YXIocmVzLm1jYSwgY29sLnZhciA9ImNvbnRyaWIiLCBncmFkaWVudC5jb2xzID0gYygiIzAwQUZCQiIsICIjRTdCODAwIiwgIiNGQzRFMDciKSwgcmVwZWwgPSBUUlVFKQ0KYGBgDQoNCg0KIyMgKipGYXNlICA0IFtDb25nbG9tZXJhZG9zXSoqDQpFbCBhbsOhbGlzaXMgZGUgY29uZ2xvbWVyYWRvcyBidXNjYSBhZ3J1cGFyIGxvcyB2aWRlb2p1ZWdvcyBlbiBzdWJjb25qdW50b3MgaG9tb2fDqW5lb3Mgc2Vnw7puIHN1cyBjYXJhY3RlcsOtc3RpY2FzIG11bHRpdmFyaWFudGVzLCBjb21vIHB1bnR1YWNpw7NuLCB2ZW50YXMsIGfDqW5lcm8geSBwbGF0YWZvcm1hLiBVdGlsaXphbmRvIGFsZ29yaXRtb3MgY29tbyBLLW1lYW5zIG8gamVyw6FycXVpY29zLCBzZSBpZGVudGlmaWNhbiBncnVwb3MgZGUgdMOtdHVsb3MgcXVlIGNvbXBhcnRlbiBzaW1pbGl0dWRlcywgbG8gY3VhbCBheXVkYSBhIGVudGVuZGVyIGxhIHNlZ21lbnRhY2nDs24gZGVsIG1lcmNhZG8sIGlkZW50aWZpY2FyIG5pY2hvcyBvIGVzdGFibGVjZXIgcGVyZmlsZXMgZGUgdmlkZW9qdWVnb3MgbcOhcyBleGl0b3Nvcy4gTG9zIGNvbmdsb21lcmFkb3MgcHVlZGVuIHVzYXJzZSBwYXJhIGVuZm9jYXIgZXN0cmF0ZWdpYXMgZGUgZGVzYXJyb2xsbyBvIG1lcmNhZGVvIHNlZ8O6biBsb3MgZ3J1cG9zIGRldGVjdGFkb3MuDQoNCiMjIyA0LjEuIE9iamV0aXZvcw0KRW4gZXN0YSAqY3VhcnRhIGV0YXBhKiBkZWwgZXN0dWRpbyBzZSBsbGV2YXLDoW4gYSBjYWJvIGPDoWxjdWxvcywgcmVwcmVzZW50YWNpb25lcyBncsOhZmljYXMgZSBpbnRlcnByZXRhY2lvbmVzIGVtcGxlYW5kbyBlbCBjb25qdW50byBkZSBkYXRvcyBwcmV2aWFtZW50ZSBwcm9jZXNhZG8gZW4gbGFzIEZhc2VzICooMSwgMiB5IDMpLioNCkVsIG9iamV0aXZvIHByaW5jaXBhbCBkZSBlc3RhIGV0YXBhIGVzIGFwbGljYXIgZWwgKkFuw6FsaXNpcyBkZSBDb25nbG9tZXJhZG9zKiwgdGFudG8gZW4gc3UgbW9kYWxpZGFkIGplcsOhcnF1aWNhLCBhIHRyYXbDqXMgZGUgbGEgY29uc3RydWNjacOzbiBlIGludGVycHJldGFjacOzbiBkZSBkZW5kcm9ncmFtYXMsIGNvbW8gZW4gc3UgdmVyc2nDs24gbm8gamVyw6FycXVpY2EsIG1lZGlhbnRlIGxhIGFwbGljYWNpw7NuIGRlbCBtw6l0b2RvIGRlIEstbWVkaWFzLCBjb24gZWwgcHJvcMOzc2l0byBkZSBpZGVudGlmaWNhciBncnVwb3MgaG9tb2fDqW5lb3MgZGVudHJvIGRlbCBjb25qdW50byBkZSBvYnNlcnZhY2lvbmVzLg0KDQoNCiMjIyA0LjIuIEFncnVwYWNpw7NuIEplcsOhcnF1aWNhDQoNCiMjIyMgQ2FtcG8gQ2xhc2lmaWNhZG9yDQpgYGB7ciBDYW1wb19DbGFzaWZpY2Fkb3IsIGZpZy5hbGlnbj0nY2VudGVyJ30NCmBgYA0KDQojIyMjIE9wdGltaXphY2nDs24gZGUgTW9qZW5hIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIFVuacOzbiBTaW1wbGUNCg0KDQojIyMjIyBVbmnDs24gQ29tcGxldGENCg0KDQojIyMjIyBVbmnDs24gUHJvbWVkaW8NCg0KDQojIyMjIERlbmRvZ3JhbWFzIE9wdGltaXphZG9zIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIEVubGFjZSBTaW1wbGUNCg0KIyMjIyMgRW5sYWNlIENvbXBsZXRvDQoNCg0KIyMjIyMgRW5sYWNlIFByb21lZGlvDQoNCg0KIyMjIDQuMy4gQWdydXBhY2nDs24gTm8tSmVyw6FycXVpY2ENCg0KIyMjIyBLLcOTcHRpbW8gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIyMgRWxib3cNCg0KDQojIyMjIyBTaWxob3VldHRlDQoNCg0KIyMjIyMgR2FwIFN0YXRpc3RpYw0KDQoNCiMjIyMjIE1ham9yaXR5IFJ1bGUNCg0KDQojIyMjIFJlc3VsdGFkb3MgSy1NZWFuc3sudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIEstw5NwdGltbyBbRWxfTWEtUnVsIDNdDQoNCiMjIyMjIEstw5NwdGltbyBbc2lsIDRdDQoNCiMjIyMgR3LDoWZpY29zIEstTWVhbnN7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBLLcOTcHRpbW8gW0VsYl9NYS1SdWwgM10NCg0KDQojIyMjIyBLLcOTcHRpbW8gIFtzaWwgNF0NCg0KDQojIyAqKkZhc2UgNSBbUmVncmVzaW9uZXNdKioNCkVsIGFuw6FsaXNpcyBkZSByZWdyZXNpw7NuIHNlIGVtcGxlYSBwYXJhIG1vZGVsYXIgbGFzIHJlbGFjaW9uZXMgZW50cmUgdW5hIHZhcmlhYmxlIGRlcGVuZGllbnRlIHkgdW5hIG8gdmFyaWFzIHZhcmlhYmxlcyBpbmRlcGVuZGllbnRlcyBkZW50cm8gZGVsIGNvbmp1bnRvIGRlIGRhdG9zLiBFbiBlbCBjb250ZXh0byBkZSB2aWRlb2p1ZWdvcywgZXMgY29tw7puIGludGVudGFyIHByZWRlY2lyIGxhcyB2ZW50YXMgZW4gZnVuY2nDs24gZGUgdmFyaWFibGVzIGNvbW8gZWwgYcOxbyBkZSBsYW56YW1pZW50bywgbGEgcHVudHVhY2nDs24gZGUgdXN1YXJpb3MsIGxhIHBsYXRhZm9ybWEsIG8gZWwgZ8OpbmVyby4gU2UgaW50ZXJwcmV0YSBxdcOpIGZhY3RvcmVzIHRpZW5lbiBtw6FzIGluZmx1ZW5jaWEgc29icmUgZWwgw6l4aXRvIGNvbWVyY2lhbCBkZWwgdmlkZW9qdWVnbyB5IGPDs21vIHB1ZWRlbiB1c2Fyc2UgZXN0b3MgaGFsbGF6Z29zIHBhcmEgbGEgdG9tYSBkZSBkZWNpc2lvbmVzIGVuIGxhIGluZHVzdHJpYS4NCg0KIyMjIDUuMS4gT2JqZXRpdm9zDQpFc3RlIGVzdHVkaW8gdGllbmUgY29tbyBwcm9ww7NzaXRvIGVzdGFibGVjZXIgbGEgKnJlbGFjacOzbiBlbnRyZSBkb3MgbyBtw6FzIHZhcmlhYmxlcyogbWVkaWFudGUgbGEgb2J0ZW5jacOzbiBkZSBpbmZvcm1hY2nDs24gc29icmUgdW5hIGRlIGVsbGFzLCBiYXNhZGEgZW4gZWwgY29ub2NpbWllbnRvIGRlIGxvcyB2YWxvcmVzIGRlIGxhcyBvdHJhcy4gTGFzIHJlbGFjaW9uZXMgZXN0YWJsZWNpZGFzIHNvbiBkZSBjYXLDoWN0ZXIgbm8gZGV0ZXJtaW7DrXN0aWNvLCBlcyBkZWNpciwgc2UgcGxhbnRlYXLDoW4gcmVsYWNpb25lcyBwcm9iYWJpbMOtc3RpY2FzIHkgc2UgaW1wbGVtZW50YXLDoW4gcHJvY2VkaW1pZW50b3MgcGFyYSByZWFsaXphciBpbmZlcmVuY2lhcyBzb2JyZSBsb3MgbW9kZWxvcyB1dGlsaXphZG9zLiBBZGVtw6FzLCBzZSBvYnRlbmRyw6FuIG1lZGlkYXMgY3VhbnRpdGF0aXZhcyBxdWUgaW5kaXF1ZW4gZWwgZ3JhZG8gZGUgcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMuIExvcyBtb2RlbG9zIGNvbnNpZGVyYWRvcyBlbiBlc3RlIHRyYWJham8gY29ycmVzcG9uZGVuIGEgY2Fzb3MgZXNwZWPDrWZpY29zIGRlbCBtb2RlbG8gbGluZWFsIGdlbmVyYWxpemFkbzogKipSZWdyZXNpw7NuIExpbmVhbCBTaW1wbGUsICoqUmVncmVzacOzbiBMaW5lYWwgTcO6bHRpcGxlKiB5ICpSZWdyZXNpw7NuIExvZ8Otc3RpY2EqLiBDYWRhIG1vZGVsbyBzZXLDoSBkZXNjcml0byB0ZcOzcmljYW1lbnRlIGVuIHN1IHJlc3BlY3RpdmEgc2VjY2nDs24sIHkgc2UgYXBsaWNhcsOhIGEgdW4gY29uanVudG8gZGUgZGF0b3MgZXNwZWPDrWZpY28gZGVzY3JpdG8gZW4gbGEgW3NlY2Npw7NuIDJdKCNzZWMyKS4NCg0KIyMjIDUuMi4gUmVncmVzacOzbiBMaW5lYWwgU2ltcGxlDQoNCg0KIyMjIyMgUmVzdW1lbiBGcmVjdWVuY2lhIGNhcmRpYWNhIG3DoXhpbWENCg0KDQojIyMjIyBSZXN1bWVuIGRlIENvbGVzdGVyb2wgU8Opcmljbw0KDQoNCiMjIyMjIERpYWdyYW1hIGRlIERpc3BlcnNpw7NuOiBGcmVjdWVuY2lhIHkgQ29sZXN0ZXJvbA0KDQojIyMjIyBEaWFncmFtYXMgVG90YWxlcyBkZSBEaXNwZXJzacOzbg0KDQojIyMjIDUuMi4yIEZvcm11bGFjacOzbiBkZWwgbW9kZWxvIGRlIFJMUyBlbnRyZSBsYXMgdmFyaWFibGVzIGRlIGVzdHVkaW8uIHsudGFic2V0IC50YWJzZXQtcGlsbHN9DQoNCiMjIyMjIENvZWZpY2llbnRlcyBkZWwgTW9kZWxvIFJMUw0KDQoNCiMjIyMjIFJlc3VtZW4gRXN0YWTDrXN0aWNvIGRlbCBNb2RlbG8gUkxTDQoNCg0KIyMjIyMgVGFibGEgQU5PVkEgcGFyYSBlbCBNb2RlbG8gUkxTDQoNCg0KIyMjIyA1LjIuMy4gQW7DoWxpc2lzIGRlbCBtb2RlbG8gUkxTLiB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBJbnRlcnZhbG8gZGUgQ29uZmlhbnphIHBhcmEgQjEgDQoNCg0KIyMjIyMgUHJlZGljY2lvbmVzIHkgc3VzIEludGVydmFsb3MgZGUgUHJlZGljY2nDs24NCg0KDQojIyMjIyBQcmVkaWNjaW9uZXMgeSBzdXMgSW50ZXJ2YWxvcyBkZSBDb25maWFuemENCg0KDQojIyMgNS4zLiBSZWdyZXNpw7NuIExpbmVhbCBNw7psdGlwbGUNCiMjIyMgNS4zLjEuIFJlc3VtZW4gZXN0YWTDrXN0aWNvIGRlIGxhcyB2YXJpYWJsZXMgZGUgZXN0dWRpbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQoNCiMjIyMgNS4zLjIgRm9ybXVsYWNpw7NuIGRlbCBtb2RlbG8gZGUgUkxNIGVudHJlIGxhcyB2YXJpYWJsZXMgZGUgZXN0dWRpby4gey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KIyMjIDUuNC4gUmVncmVzacOzbiBMb2fDrXN0aWNhIFNpbXBsZQ0KIyMjIyA1LjQuMSBQbGFudGVhbWllbnRvIHkgZGVzYXJyb2xsbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBSZXN1bWVuIHkgQm94cGxvdCBDb2xlc3Rlcm9sIFPDqXJpY28NCg0KIyMjIyMgSGlzdG9ncmFtYSBkZSBDb2xlc3Rlcm9sIFPDqXJpY28NCg0KDQojIyMjIyBSZXN1bWVuIHkgRGlhZ3JhbWEgZGUgQmFycmFzIGRlIFRhcmdldA0KDQoNCiMjIyMjIFJlc3VtZW4geSBEaWFncmFtYSBkZSBDYWphcyBDb25qdW50bw0KDQoNCiMjIyMgNS40LjIuIEZvcm11bGFjacOzbiBkZWwgbW9kZWxvIGRlIFJMb2dTIGVudHJlIGxhcyB2YXJpYWJsZXMgZGUgZXN0dWRpbyB7LnRhYnNldCAudGFic2V0LXBpbGxzfQ0KDQojIyMjIyBDb2VmaWNpZW50ZXMgZGVsIE1vZGVsbyBSTG9nUw0KDQoNCiMjIyMjIyBSZXN1bWVuIEVzdGFkw61zdGljbyBkZWwgTW9kZWxvIFJMb2dTDQoNCg0KIyMjIyA1LjQuMy4gQW7DoWxpc2lzIGRlbCBtb2RlbG8gUkxvZ1Mgey50YWJzZXQgLnRhYnNldC1waWxsc30NCiMjIyMjIFZhcmlhYmxlIFByZWRpY3RvcmEgaWd1YWwgYSBDZXJvDQoNCg0KIyMjIyMgUHJvYmFiaWxpZGFkZXMgRXN0aW1hZGFzDQoNCg0KIyMjIyMgR3LDoWZpY2EgZGVsIE1vZGVsbyBSTG9nUw0KDQoNCg0KIyMjIDUuNS4gQWp1c3RlIGRlIFZhcmlhbnphDQoNCiMjICoqNi4gQ29uY2x1c2lvbmVzKioNCg0KIyMgKio3LiBCaWJsaW9ncmFmw61hKioNCg0KDQo=