0. Establecer idioma y directorio de trabajo

Al comenzar siempre es importante establecer el idioma adecuado para que el programa reconozca caracteres especiales. En el caso de definir al idioma español, la instrucción a utilizar es:

Sys.setlocale("LC_ALL", "Spanish")
## Warning in Sys.setlocale("LC_ALL", "Spanish"): OS reports request to set locale
## to "Spanish" cannot be honored
## [1] ""
Sys.setlocale("LC_ALL", "es_MX")
## Warning in Sys.setlocale("LC_ALL", "es_MX"): OS reports request to set locale
## to "es_MX" cannot be honored
## [1] ""
Sys.setenv(LANG = "Spanish")

También es importante instalar las librerías que se utilizarán posteriormente, que consistirán en: tidyverse, moments, ggplot2, dplyr, ggrepel. Es importante recordar que la librería de tidyverse incluye otros dos paquetes que serán utilizados: dplyr y ggplot2.

Para abrirlas de manera simultánea, primero se crea un objeto con el nombre de estas librerías:

paquetes <- c("tidyverse", "moments", "ggrepel")

Posteriormente se activa la librería easypackages() para la apertura simultánea:

library(easypackages)
libraries(paquetes)
## Loading required package: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.2     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.2     ✔ tidyr     1.3.0
## ✔ purrr     1.0.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## Loading required package: moments
## 
## Loading required package: ggrepel
## Warning in library(package, lib.loc = lib.loc, character.only = TRUE,
## logical.return = TRUE, : there is no package called 'ggrepel'
## 
## --------------------------------------------------
## The following packages did not load successfully:

Además es muy relevante establecer la ubicación del directorio de trabajo, con el fin que el programa identifique el archivo del que extraerá y, también, guardará la información solicitada.

getwd() ##directorio actual
## [1] "/Users/gustavo/Dropbox/R/Rmarkdown"
setwd("~/Dropbox/R") ##Esta permite cambiar y definir el directorio deseado
list.files() ##Esta permite enlistar los archivos dentro del directorio
##  [1] "1-Estudio-Berumen-30mayo-6junio.PDF"                  
##  [2] "200613COVID19MEXICO.csv"                              
##  [3] "Base Voto x Mujeres Experimento 1 copia.csv"          
##  [4] "Base_datos_Informe_Pais.xlsx"                         
##  [5] "Bertrand_data.dta"                                    
##  [6] "Clase 2 DGAPA.xlsx"                                   
##  [7] "Clase 4 DGAPA.xlsx"                                   
##  [8] "Componente principal SPP.jpeg"                        
##  [9] "Concentrado_Elecciones_Federales_1976_2018 copia.csv" 
## [10] "Copia de factorial 3x2x2.csv"                         
## [11] "Curso Intro a R I y II"                               
## [12] "Diferencia_votos_DIP_FED_2015.csv"                    
## [13] "Encuesta_Gea.dta"                                     
## [14] "ICI_2018.xlsx"                                        
## [15] "Latinobarometro_2018_Esp_Spss_v20190303.sav"          
## [16] "Latinobarometro_2018_Esp_Stata_v20190303.dta"         
## [17] "Latinobarometro_2020_Esp_Rdata_v1_0.rdata"            
## [18] "Mi_Exportación.xlsx"                                  
## [19] "Principal Component Analysis R Program and Output.pdf"
## [20] "Rmarkdown"                                            
## [21] "SDEMT319.dta"                                         
## [22] "SDEMT319_10.dta"                                      
## [23] "Tabasco_votos_dip_loc_2018_dif.csv"                   
## [24] "TiposErrores.png"                                     
## [25] "V-Dem-CY-Core-v12.csv"                                
## [26] "alumnos_political_compass.csv"                        
## [27] "autoestima.csv"                                       
## [28] "base_alternancias.csv"                                
## [29] "base_municipios_final_datos_01.csv"                   
## [30] "base_voto_mujeres_2012_2018.csv"                      
## [31] "base_votos_2015_2018.csv"                             
## [32] "berumen_encuesta_6_junio.sav"                         
## [33] "conejos.csv"                                          
## [34] "confidence_intervals_Coursera.rmd"                    
## [35] "copia_semillas.csv"                                   
## [36] "cuadro_latino.csv"                                    
## [37] "data_clientelismo.csv"                                
## [38] "data_clientelismo.dta"                                
## [39] "datos_2_fac_aleat.csv"                                
## [40] "datos_computos_distritos_diputado.txt"                
## [41] "datos_covid1.txt"                                     
## [42] "datos_covid2.csv"                                     
## [43] "datos_covid3.xlsx"                                    
## [44] "datos_gc.csv"                                         
## [45] "datos_morena_frag.xlsx"                               
## [46] "datos_pp1.csv"                                        
## [47] "datos_pp2.csv"                                        
## [48] "datos_repeticiones.csv"                               
## [49] "datos_telas.csv"                                      
## [50] "diccionario_datos_covid19"                            
## [51] "diminish.txt"                                         
## [52] "encuesta_abierta_morena.csv"                          
## [53] "encuesta_abierta_morena_2020.xlsx"                    
## [54] "encuesta_nina_w_ 2016"                                
## [55] "encuesta_nueva_morena.csv"                            
## [56] "enpol_sec7_1.csv"                                     
## [57] "enpol_sec8_9_10.csv"                                  
## [58] "enpol_sec_5_6.csv"                                    
## [59] "experim_azucar.csv"                                   
## [60] "guia_ponencia_morena.docx"                            
## [61] "idh_mpio_2000_2005.csv"                               
## [62] "idh_mpio_2000_2005.xls"                               
## [63] "indices_spp_subnacional_1980_2018.xlsx"               
## [64] "intro_to_data_Coursera.html"                          
## [65] "jerarquico_cruzado.csv"                               
## [66] "mediciones_repetidas.csv"                             
## [67] "modelo_jerarquico.csv"                                
## [68] "morena-basedatos-integrada-vf-1.csv"                  
## [69] "morena-bd-integrada-estimación-empresas.xlsx"         
## [70] "morena_nueva_encuesta_2020.xlsx"                      
## [71] "partylevel_20130907.csv"                              
## [72] "presid06computo.dta"                                  
## [73] "resultados_diputadosfederales_2018.csv"               
## [74] "scripts"                                              
## [75] "sdemt319_10.sav"                                      
## [76] "syllabus.Rmd"                                         
## [77] "syllabus.log"                                         
## [78] "syllabus.tex"                                         
## [79] "tarea_hipertension.csv"                               
## [80] "voto_cand_socioec_2012.csv"                           
## [81] "voto_cand_socioec_2015.csv"                           
## [82] "voto_cand_socioec_2018.csv"                           
## [83] "votos_diputados_2015.csv"                             
## [84] "votos_mujeres_2012_2018.csv"                          
## [85] "votos_mujeres_2012_2018_copia.csv"                    
## [86] "~$datos_morena_frag.xlsx"                             
## [87] "~$ia_ponencia_morena.docx"                            
## [88] "~$morena_nueva_encuesta_2020.xlsx"

Una vez establecido el directorio de trabajo, se debe cargar la base de datos o data frame en el ambiente del programa, con el que se analizará la información. Para ello habrá que “cargar” la información sobre los pacientes infectados por COVID-19 reportados por la Secretaría de Salud del gobierno federal mexicano.

datos_covid <- read.csv("~/Dropbox/R/200613COVID19MEXICO.csv", header = TRUE) #ruta de acceso a los datos, 'header = TRUE' en caso de que el archivo cuente con nombres de las variables.

1. Estadística descriptiva

El principal objetivo de describir una variable de manera estadística consiste en identificar el comportamiento de la distribución de ésta. Y para lograrlo se debe presentar información sobre dos dimensiones de interés: 1. el punto de concentración de los datos y 2. la variabilidad o dispersión de los datos de la variable analizada. Para ello existen dos grandes maneras de hacerlo: i. una consiste en una descripción basada en estadísticos y ii. otra consiste en la descripción basada en métodos gráficos.

1.1. Descripción basada en estadísticos

La descripción basada en estadísticos consiste en la aplicación de ciertas funciones algebráicas para procesar los datos y “reducirlos” a valores indicativos que, posteriormente, serán interpretados sobre algunos aspectos importantes de la distribución de una o varias variables. Dichas funciones buscan identificar dos aspectos básicos de la distribución de la variable: a. la centralidad de la distribución a través de las Medidas de Tendencia Central (MTC) y, b. la dispersión de los datos respecto de su centralidad mediante las Medidas de Dispersión (MD).

1.1.1. Medidas de Tendencia Central (MTC)

La identificación de la centralidad de la distribución de una variable se logra a partir de ubicar las MTC. Éstas se refieren a un conjunto de funciones, las que su pertinencia dependerá del tipo de escala de medición de la variable.

  • En el caso de las variables discretas o categóricas (nominales un ordinales), las MTC principales consisten en la moda y la mediana . Este tipo de variables discretas o categóricas usualmente son reconocidas por el programa como variables tipo “factor”, y de esta forma descarta que su comportamiento sea continuo.

El estadístico de la mediana se refiere al valor que adquiere el caso que se ubica a la mitad de la distribucion de todos los casos en una muestra. Esto es, dicho caso permite partir en dos grupos con la misma cantidad de casos al total de la muestra para una variable. Para su cálculo se utiliza el comando median() de la siguiente forma:

median(datos_covid$SECTOR) #Solicitud de MEDIANA
## [1] 12

Pregunta: ¿Cuál es la categoría en la que se encuentra el caso que ocupa la posición mediana de la distribución?

R no computa la moda de manera directa, por lo que en ocasiones es pertinente identificarla utilizando otros métodos. Una manera para hacerlo consiste en solicitar un tabulado o tabla de frecuencias de las categorías y, así, ubicar el atributo más frecuente.

table(datos_covid$SECTOR)
## 
##      1      2      3      4      6      7      8      9     10     11     12 
##     28    125   8229 111072  15608    390   4104  15525   2334   3082 238512 
##     13     99 
##    381   2365

Pregunta: ¿Cuál categoría del SECTOR ocupa la moda de la distribución?

  • En el caso de contar con una variable continua (de razón o intervalar), la media es el estadístico más pertinente a calcular con el fin de ubicar el punto de concentración de la distribución de los datos. Aquí es importante recordar que este estadístico es susceptible a valore extremos, pues en la medida en que estos se presenten entonces hará que su valor se “corra” o tienda a moverse hacia dichos extremos.
mean(datos_covid $ EDAD) #solicitud para la media de una variable continua
## [1] 42.57663

Pregunta: ¿Cuál es la edad promedio de las personas registrdas con síntomas de COVID-19?

Aquí es importante recordar que este estadístico es susceptible a valore extremos, pues en la medida en que estos se presenten entonces hará que su valor se “corra” o tienda a moverse hacia dichos extremos. Por ello, cuando esto ocurre es pertinente calcular el valor de la mediana para contrastar la pertinentencia de la media.

median(datos_covid $ EDAD)
## [1] 41

El programa R cuenta con otras opciones para calcular algunos estadísticos descriptivos en un solo script, por ejemplo:

summary(datos_covid $ EDAD) #script para varios estadísticos de MTC
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   31.00   41.00   42.58   53.00  120.00

Este script arroja diversos estadísticos descriptivos: valor mínimo, valor máximo, media, mediana, valor del 1er y 3er cuartil. Con estos podemos darnos una idea más completa sobre el punto de concentración de las variables continuas.

Preguntas: ¿Cuál es el tamaño del rango de edad de los casos registrados? ¿Cuál es el tamaño del rango intercuartil en el que se ubica el 50% de los casos alrededor de la mediana?

En el caso de solicitar el cálculo de diversos estadísticos en un mismo script, se puede hacer uso de las funciones de dplyr:

datos_covid %>%  #se llama al Data Frame
  group_by(SEXO) %>%  #se pide que los datos se agrupen por SEXO
  summarise(media_edad = mean(EDAD, na.rm = TRUE),#se solicitan estadísticos 
            mediana_edad = median(EDAD, na.rm = TRUE),
            n())
## # A tibble: 2 × 4
##    SEXO media_edad mediana_edad  `n()`
##   <int>      <dbl>        <dbl>  <int>
## 1     1       42.0           40 197301
## 2     2       43.2           42 204454

1.1.2. Medidas de Dispersión (MD)

Las Medidas de Dispersión (MD) son otro tipo de información relevante para conocer la forma de la distribución de los datos. Estas medidas ayudan a entender la amplitud de la distancia de los datos respecto del punto de concentración de la variable de interés. Existen diversas medidas de tendencia central pero su pertinencia varía según el tipo de variable o su escala de medición.

  • En el caso de las variables categóricas (en escala nominal u ordinal), las MD más pertinentes son las proporciones de frecuencias para cada una de los atributos categóricos o valores posibles de cada variable (Vilalta, 2016: 69). Para ello, el caso de este tipo de variables categóricas es pertinente observar la manera en que los casos se distribuyen entre las distintas categorías.
prop.table(table(datos_covid $ SECTOR))
## 
##            1            2            3            4            6            7 
## 6.969422e-05 3.111349e-04 2.048263e-02 2.764670e-01 3.884955e-02 9.707409e-04 
##            8            9           10           11           12           13 
## 1.021518e-02 3.864295e-02 5.809511e-03 7.671342e-03 5.936752e-01 9.483392e-04 
##           99 
## 5.886672e-03

En la tabla de proporciones se observan los valores arrojados en notación “científica”, lo que puede ocasionar dificultad inicial para interpretarlos. Esto ocurre porque en algunos casos, los valores pueden contener decimales pequeños. Otro elemento que arroja dicha tabla es la presencia de los casos codificados con el valor de 99, y que sabemos -como analistas- que se refieren los casos perdidos. De manera que al dejarlos como tal, harán que las proporciones varíen pues también se les incluye en el cálculo. Para evitar que sesguen los resultados, deben ser excluidos del análisis. Para lo que será importante tratarlos como datos perdidos, y ello debemos hacérselo saber a R.

A continuación se le solicitará a R que cambie la notación en que se presentan los resultados decimales, para ello se usará el comando options(scipen = 999), y también se asignarán los valores perdidos usando el comando na_if() de la siguiente manera:

options(scipen = 999) #permite cambiar la notación de científica a decimal
datos_covid <- datos_covid %>%
  mutate(SECTOR_R = na_if(SECTOR, 99)) #transformación de los valores 99 a NA

Y ahora se vuelve a solicitar la tabla de proporciones:

prop.table(table(datos_covid$SECTOR_R)) #en valores de proporción
## 
##             1             2             3             4             6 
## 0.00007010691 0.00031297729 0.02060392098 0.27810410877 0.03907959638 
##             7             8             9            10            11 
## 0.00097648915 0.01027567040 0.03887177946 0.00584391197 0.00771676807 
##            12            13 
## 0.59719071584 0.00095395478
prop.table(table(datos_covid$SECTOR_R)) * 100 #porcentaje de casos atentidos en cada tipo de SECTOR excluyendo los NA
## 
##            1            2            3            4            6            7 
##  0.007010691  0.031297729  2.060392098 27.810410877  3.907959638  0.097648915 
##            8            9           10           11           12           13 
##  1.027567040  3.887177946  0.584391197  0.771676807 59.719071584  0.095395478

Pregunta: ¿Cuál es el sector hospitalario con mayor porcentaje de casos registrados, descontando los casos sin registro?

  • En el caso de las variables continuas (de razón o intervalo) existen otros estadísticos que permiten observar distintas medidas de dispersión.

El Rango de los datos, que consiste en la distancia entre el valor mínimo y el mvalor máximo de los datos registrados. Este estadístico no se preocupa por ubicar el punto de concentración o la centralidad de la distribución.

range(datos_covid$EDAD)
## [1]   0 120

Los estadísticos más útiles para evaluar la dispersión de los datos respecto del valor de la media son: la desviación estándar o típica y la varianza.

datos_covid %>%
  summarise(desviación_típica = sd(EDAD, na.rm = TRUE), #`sd()` calcula la desviación estándar
            varianza_edad = var(EDAD, na.rm = TRUE)) #`var()`calcula la varianza
##   desviación_típica varianza_edad
## 1          16.69569      278.7459

Otras MD consisten en la identificación de los cuantiles, a partir de ubicar los valores que sirven de puntos de corte para formar grupos con la misma cantidad de casos en su interior. Por default, el script quantile() crea 4 grupos con el 25% de los casos en cada uno. Estos grupos se llaman cuartiles.

quantile(datos_covid$EDAD)
##   0%  25%  50%  75% 100% 
##    0   31   41   53  120

En el caso de buscar la división de la muestra en otra cantidad de grupo que contengan la misma cantidad de casos (ya sea en 10 grupos o deciles, o en 100 grupos o percentiles), también se puede utilizar el script quantile(), pero se debe incluir el criterio de agrupación.

quantile(datos_covid $ EDAD, probs = seq(0, 1, 0.10), na.rm = FALSE)
##   0%  10%  20%  30%  40%  50%  60%  70%  80%  90% 100% 
##    0   24   29   33   37   41   46   50   56   65  120

¿Entre cuáles edades se encuentra el 30% de los casos más jóvenes con síntomas covid-19?

A partir de los estadísticos sobre la asimetría y curtosis se puede conocer el sesgo de la distribución de la variable. Para ello se debe instalar la paquetería “moments”, que permite llamar a dichos estadísticos.

library(moments)
datos_covid %>%
  summarise(asimetría_edad = skewness(datos_covid $ EDAD), #arroja el sesgo (izquierda / derecha) de la distribución.
            curtosis_edad = kurtosis(datos_covid $ EDAD)) #nos da el achatamiento de la distribucion de los datos de la variable.
##   asimetría_edad curtosis_edad
## 1      0.2852141       3.15635

Dado que tales valores están expresados en la unidad de medida de la variable en cuestión, no son útiles para comparar variables de diferentes unidades de medición. Es por eso que se calculan los coeficientes de simetría y curtosis estandarizados: para ello, se divide la simetría calculada, por la raíz cuadrada del valor 6 (este número es una constante en la fórmula) dividido en la cantidad de casos de la variable (401755).

datos_covid %>%
  summarise(asimetría_edad = skewness(datos_covid $ EDAD) / sqrt(6 / 401755), #arroja el sesgo estandaizado de la distribución.
            curtosis_edad = kurtosis(datos_covid $ EDAD) / sqrt(6 / 401755)) #nos da el achatamiento de la distribucion estandarizada de los datos de la variable.
##   asimetría_edad curtosis_edad
## 1       73.80335      816.7519

Un criterio general para determinar si los coeficientes de simetría y curtosis reflejan una variable semejante a una distribución normal es que ambos valores se encuentren entre -2 y 2. Como puede observarse en los resultados, ambos coeficientes escapan a tal rango por lo que se observa una distribución poco similar a una normal.

El coeficiente de variación puede calcularse de manera sencilla, ejecutando una división simple entre la desviación estándar y la media de la variable de interés, y nos informa sobre la dispersión relativa de una variable. Y se utiliza para comparar conjuntos de datos pertenecientes a poblaciones distintas. Si atendemos a su fórmula, vemos que este tiene en cuenta el valor de la media, por lo que el coeficiente de variación nos permite tener una medida de dispersión que elimina las posibles distorsiones de las medias de dos o más poblaciones. A medida que el valor del coeficiente se aleja de 0, la variación es mayor.

sd(datos_covid $ EDAD) / mean(datos_covid $ EDAD)
## [1] 0.3921327

Finalmente, la forma más certera para evaluar si la distribución de datos de una variable se comporta según los parámetros que asume una distribución normal es aplicando un test estadístico específicamente orientado a tal evaluación. Para ello, se diferencia el test de Shapiro Wilkinson y el de Kolmogorov Smirnoff. El primero es aplicable a muestras pequeñas (usualmente se refiere a muestras menores a 50 casos, pero soporta hasta 2500 casos), mientras que el segundo sirve para muestras de grandes (por encima de 2500 casos).

Creación de submuestra con 50 casos:

set.seed(1357)
submuestra_50 <- datos_covid %>%
  sample_n(50, replace = FALSE)

Evaluación de prueba de normalidad con prueba Shapiro - W.:

#Prueba de Shapiro Wilk (muestras pequeñas)
shapiro.test(submuestra_50$EDAD)
## 
##  Shapiro-Wilk normality test
## 
## data:  submuestra_50$EDAD
## W = 0.96462, p-value = 0.1388

Creación de submuestra con 500 casos:

set.seed(1357)
submuestra_500 <- datos_covid %>%
  sample_n(500, replace = TRUE)

Prueba Kolmogorov Smirnoff:

#Prueba Kolmogorov Smirnov (muestras grandes)
ks.test(submuestra_500$EDAD, "pnorm", mean(submuestra_500$EDAD, na.rm = T), sd(submuestra_500$EDAD, na.rm = T))
## Warning in ks.test.default(submuestra_500$EDAD, "pnorm",
## mean(submuestra_500$EDAD, : ties should not be present for the
## Kolmogorov-Smirnov test
## 
##  Asymptotic one-sample Kolmogorov-Smirnov test
## 
## data:  submuestra_500$EDAD
## D = 0.067354, p-value = 0.02142
## alternative hypothesis: two-sided

Dichas pruebas estadísticas sirven para evaluar inferencias del investigador o -formalmente- hipótesis. En este caso, suelen trabajar sobre una hipótesis nula (H0) que, para el caso de ambas muestras plantea que la variable evaluada se distribuye como si fuera una distribución normal. Para determinar normalidad univariada se busca un valor p mayor a 0.05 para no rechazar la hipótesis nula, que establece la igualdad entre la distribución normal teórica y la distribución empírica de los datos que estamos evaluado. Si el p-value calculado en la prueba es mayor a 0.05 entonces no se puede rechazar la H0, que establece que la distribución de la variable se parece a la de una normal. Si el caso fuera el contrario (p-value < 0.05), entonces se rechaza la H0 y, por tanto, se rechaza la normalidad de la distribución de la variable analizada.

1.2. Descripción basada en gráficos

El uso de métodos gráficos para la descripción de las variables es otra manera muy útil de identificar las formas de distribución de las mismas. Si bien existen diversos tipos de gráficas para mostrar diversas características de la distribución de las variables, es importante tener en cuenta que no todos los tipos de gráficas sirven por igual para analizarlas. De manera que el tipo de método gráfico a utilizar depende del tipo (o escala de medición) de las variables, así como del aspecto (estadístico) que se desea resaltar.

1.2.1. Gráficos básicos para variables categóricas

En el caso del uso de variables discretas (nominales u ordinales), las gráficas más sencillas (pero no por ello menos útiles) son las que permiten describir la frecuencia para cada uno de sus atributos. En este caso, las dos formas básicas consisten en: i. el gráfico de pie y ii. la gráfica de barras.

    1. Los gráficos de pie o pastel son útiles para identificar el tamaño de los atributos o categorías que integran a una variable, y de esa manera permiten identificar la moda de la distribución. Es importante notar que las gráficas de variables categóricas trabajan a través de tablas de frecuencia de las variable de interés, y no trabajan directamente sobre la variable misma.

Desde el sistema base de R se pueden diseñar dichos gráficos:

mytable <- table(datos_covid $ SECTOR_R) #crear objeto tipo tabla
lbls <- paste(names(mytable), "\n", mytable, sep="") #definir las etiquetas
pie(mytable, labels = lbls, 
    main = "Sector de hospitalización \n (con cantidades absolutas)") #crear gráfica

    1. Los gráficos de barras son otra forma útil para mostrar la distribución de una variable discreta y, en ocasiones, esta es más útil para identificar y comparar las frecuencias de los distintos atributos. Para ello, desde el sistema base de R la gráfica se construye de la siguiente manera:
barplot(mytable,
        main = "Sector de Hospitalización",
        xlab = "Tipo de Sector",
        ylab = "Cantidad",
        border = "red",
        col = "blue",
        density = 10)

Otra forma de construir las gráficas proviene desde la librería ggplot2, que es parte del paquete tidyverse, y que permite integrar gráficos con mejor calidad y diseño. En el caso de la construcción de un gráfico de barras, primero se debe instalar la librería de ggplot. Para ello hay dos opciones básicas: 1. instalar la librería tidyverse

library(tidyverse) #esta librería incluye a **ggplot2**

Otra manera consiste en llamar directamente a la librería de ggplot2.

library(ggplot2)

Una vez abierta dicha librería, la manera de construir una gráfica de barras para mostrar la distribución de una variable categórica es la siguiente desde la estructura del script de `ggplot()´es:

ggplot(data = datos_covid, aes(SECTOR)) + #esto permite diseñar el lienzo
  geom_bar() #esto permite representar los datos como barras

Al revisar la gráfica, se observa que se incluye el valor de 99, que se corresponde con datos “perdidos”. En caso de desear excluirlos de la representación, entonces se pueden utilizar los pipes previamente a la graficación, de la siguiente manera:

datos_covid %>% ##aquí se definen el data frame a utilizar
    filter(SECTOR != 99) %>% ##aquí se filtran los datos para excluir a los casos etiquetados con "99" por ser datos perdidos
    ggplot(aes(SECTOR)) + ##aquí se define la variable con la que se establece el tamaño del lienzo de la gráfica
    geom_bar() + ##aquí se define la forma en que se representarán los datos
  labs(title = "Sector de Hospitalización",
       x = "Tipo de sector", 
       y = "Cantidad")

1.2.2. Gráficos básicos para variables continuas

La distribución de las variables continuas puede ser graficada de una gran cantidad de maneras. Aquí se revisarán algunas formas básicas: i. histograma, ii. gráfica de densidad y iii. gráfica de caja (boxplot).

    1. El histograma permite identificar la distribución de una variable continua a partir de graficar el área cúbica que ésta ocupa. Para ello se hace uso de barras contiguas que contienen a un conjunto de valores, según el tamaño definido por el investigador.

En el programa base, la manera de construir un histograma es la siguiente:

hist(datos_covid $ EDAD, ##aquí se define la variable a graficar 
     main = "Distribución de la edad", ##aquí se define el título de la gráfica
     breaks = 6, ##aquí se define la cantidad de barras para agrupar datos, a mayor cantidad es más fina la interpretación
     xlab = "Edad", ##define el título del eje x
     ylab = "Frecuencia", ##define el título del eje y
     col = "grey") ##define el color de relleno de las barras

En el programa ggplot, la manera de construir el histograma -usando pipes- es la siguiente:

datos_covid %>%
  ggplot(aes(EDAD)) + #lienzo
  geom_histogram(bins = 6, na.rm = TRUE) + #representación geométrica
  labs(title = "Distribución de edad", #etiquetas de la gráfica
       x = "Edad",
       y = "Cantidad")

    1. Los gráficos de densidad son otra de las maneras para graficar la distribución de dichas variables. Estas consisten en curvas suavizadas que siguen la forma de un histograma, pero también permite evaluar la probabilidad existente debajo de cada punto de la curva.

La construcción de una gráfica de densidad en el sistema base de R es:

plot(density(datos_covid $ EDAD),
     main = "Distribución de la edad",
     xlab = "Edad",
     ylab = "Densidad") #la instrucción de gráficación se ejecuta indirectamente sobre los datos, primero se debe solicitar la densidad de los datos mismos

La construcción de un gráfico de densidad en el sistema ggplot es:

datos_covid %>%
  ggplot(aes(EDAD)) +
  geom_density() +
  labs(title = "Distribución de la edad",
       x = "Edad",
       y = "Probabilidad")

    1. Las gráficas de cajas con otra forma de presentar la distribución de una variable continua. Estas tienen la característica de representar diversos estadísticos descriptivos dentro del mismo gráfico, como lo son: el rango intercuartil (Q3 - Q1), la posición de la mediana, la ubicación de valores atípicos (outliers), el sesgo de la distribución.

La manera de elaborar un diagrama de caja en el sistema base es:

boxplot(datos_covid $ EDAD,
        main = "Distribución de la edad",
        xlab = "Edad",
        ylab = "Cantidad")

En el caso de la librería ggplot, la manera para construir un diagrama de boxplot, y mediante pipes es:

datos_covid %>%
  ggplot(aes(y = EDAD)) +
  geom_boxplot(na.rm = TRUE) +
  labs(title = "Distribución de la edad",
       x = "Edad", 
       y = "Cantidad")

2. Ejercicio

  1. Construye una muestra de 2000 casos a partir de la matriz de datos sobre covid-19.
  2. Calcula la moda para la variable de casos infectado de covid-19 (variable: RESULTADO), excluyendo los casos “perdido” (NA).
  3. Calcula la media y la desviación estándar para la variable EDAD.
  4. Grafica la distribución de la variable RESULTADO.
  5. Grafica la distribución de la variable EDAD.
LS0tCnRpdGxlOiAiRXN0YWTDrXN0aWNhIGRlc2NyaXB0aXZhIgphdXRob3I6ICJHdXN0YXZvIE1hcnTDrW5lei1WYWxkZXMiCmRhdGU6ICIyMDIzLTA3LTEyIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogVFJVRQogICAgdG9jX2RlcHRoOiA1CiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIG51bWJlcl9zZWN0aW9uOiBGQUxTRQogICAgdGhlbWU6ICJjb3NtbyIKICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMjIDAuIEVzdGFibGVjZXIgaWRpb21hIHkgZGlyZWN0b3JpbyBkZSB0cmFiYWpvCgpBbCBjb21lbnphciBzaWVtcHJlIGVzIGltcG9ydGFudGUgZXN0YWJsZWNlciBlbCBpZGlvbWEgYWRlY3VhZG8gcGFyYSBxdWUgZWwgcHJvZ3JhbWEgcmVjb25vemNhIGNhcmFjdGVyZXMgZXNwZWNpYWxlcy4gRW4gZWwgY2FzbyBkZSBkZWZpbmlyIGFsIGlkaW9tYSBlc3Bhw7FvbCwgbGEgaW5zdHJ1Y2Npw7NuIGEgdXRpbGl6YXIgZXM6CgpgYGB7cn0KU3lzLnNldGxvY2FsZSgiTENfQUxMIiwgIlNwYW5pc2giKQpTeXMuc2V0bG9jYWxlKCJMQ19BTEwiLCAiZXNfTVgiKQpTeXMuc2V0ZW52KExBTkcgPSAiU3BhbmlzaCIpCmBgYAoKVGFtYmnDqW4gZXMgaW1wb3J0YW50ZSBpbnN0YWxhciBsYXMgbGlicmVyw61hcyBxdWUgc2UgdXRpbGl6YXLDoW4gcG9zdGVyaW9ybWVudGUsIHF1ZSBjb25zaXN0aXLDoW4gZW46IHRpZHl2ZXJzZSwgbW9tZW50cywgZ2dwbG90MiwgZHBseXIsIGdncmVwZWwuIEVzIGltcG9ydGFudGUgcmVjb3JkYXIgcXVlIGxhIGxpYnJlcsOtYSBkZSB0aWR5dmVyc2UgaW5jbHV5ZSBvdHJvcyBkb3MgcGFxdWV0ZXMgcXVlIHNlcsOhbiB1dGlsaXphZG9zOiBkcGx5ciB5IGdncGxvdDIuCgpQYXJhIGFicmlybGFzIGRlIG1hbmVyYSBzaW11bHTDoW5lYSwgcHJpbWVybyBzZSBjcmVhIHVuIG9iamV0byBjb24gZWwgbm9tYnJlIGRlIGVzdGFzIGxpYnJlcsOtYXM6CgpgYGB7ciBwYXF1ZXRlc30KcGFxdWV0ZXMgPC0gYygidGlkeXZlcnNlIiwgIm1vbWVudHMiLCAiZ2dyZXBlbCIpCmBgYAoKUG9zdGVyaW9ybWVudGUgc2UgYWN0aXZhIGxhIGxpYnJlcsOtYSBgZWFzeXBhY2thZ2VzKClgIHBhcmEgbGEgYXBlcnR1cmEgc2ltdWx0w6FuZWE6CgpgYGAge3IgZWFzeXBhY2thZ2VzfQpsaWJyYXJ5KGVhc3lwYWNrYWdlcykKbGlicmFyaWVzKHBhcXVldGVzKQpgYGAKCkFkZW3DoXMgZXMgbXV5IHJlbGV2YW50ZSBlc3RhYmxlY2VyIGxhIHViaWNhY2nDs24gZGVsIGRpcmVjdG9yaW8gZGUgdHJhYmFqbywgY29uIGVsIGZpbiBxdWUgZWwgcHJvZ3JhbWEgaWRlbnRpZmlxdWUgZWwgYXJjaGl2byBkZWwgcXVlIGV4dHJhZXLDoSB5LCB0YW1iacOpbiwgZ3VhcmRhcsOhIGxhIGluZm9ybWFjacOzbiBzb2xpY2l0YWRhLgoKYGBge3IgZGlyZWN0b3JpaW99CmdldHdkKCkgIyNkaXJlY3RvcmlvIGFjdHVhbApzZXR3ZCgifi9Ecm9wYm94L1IiKSAjI0VzdGEgcGVybWl0ZSBjYW1iaWFyIHkgZGVmaW5pciBlbCBkaXJlY3RvcmlvIGRlc2VhZG8KbGlzdC5maWxlcygpICMjRXN0YSBwZXJtaXRlIGVubGlzdGFyIGxvcyBhcmNoaXZvcyBkZW50cm8gZGVsIGRpcmVjdG9yaW8KYGBgCgpVbmEgdmV6IGVzdGFibGVjaWRvIGVsIGRpcmVjdG9yaW8gZGUgdHJhYmFqbywgc2UgZGViZSBjYXJnYXIgbGEgYmFzZSBkZSBkYXRvcyBvIGRhdGEgZnJhbWUgZW4gZWwgYW1iaWVudGUgZGVsIHByb2dyYW1hLCBjb24gZWwgcXVlIHNlIGFuYWxpemFyw6EgbGEgaW5mb3JtYWNpw7NuLiBQYXJhIGVsbG8gaGFicsOhIHF1ZSAiY2FyZ2FyIiBsYSBpbmZvcm1hY2nDs24gc29icmUgbG9zIHBhY2llbnRlcyBpbmZlY3RhZG9zIHBvciBDT1ZJRC0xOSByZXBvcnRhZG9zIHBvciBsYSBTZWNyZXRhcsOtYSBkZSBTYWx1ZCBkZWwgZ29iaWVybm8gZmVkZXJhbCBtZXhpY2Fuby4KCmBgYHtyIGRhdG9zfQpkYXRvc19jb3ZpZCA8LSByZWFkLmNzdigifi9Ecm9wYm94L1IvMjAwNjEzQ09WSUQxOU1FWElDTy5jc3YiLCBoZWFkZXIgPSBUUlVFKSAjcnV0YSBkZSBhY2Nlc28gYSBsb3MgZGF0b3MsICdoZWFkZXIgPSBUUlVFJyBlbiBjYXNvIGRlIHF1ZSBlbCBhcmNoaXZvIGN1ZW50ZSBjb24gbm9tYnJlcyBkZSBsYXMgdmFyaWFibGVzLgpgYGAKCgojIyAxLiBFc3RhZMOtc3RpY2EgZGVzY3JpcHRpdmEKCkVsIHByaW5jaXBhbCBvYmpldGl2byBkZSBkZXNjcmliaXIgdW5hIHZhcmlhYmxlIGRlIG1hbmVyYSBlc3RhZMOtc3RpY2EgY29uc2lzdGUgZW4gaWRlbnRpZmljYXIgZWwgY29tcG9ydGFtaWVudG8gZGUgbGEgZGlzdHJpYnVjacOzbiBkZSDDqXN0YS4gWSBwYXJhIGxvZ3JhcmxvIHNlIGRlYmUgcHJlc2VudGFyIGluZm9ybWFjacOzbiBzb2JyZSBkb3MgZGltZW5zaW9uZXMgZGUgaW50ZXLDqXM6IDEuIGVsIHB1bnRvIGRlIGNvbmNlbnRyYWNpw7NuIGRlIGxvcyBkYXRvcyB5IDIuIGxhIHZhcmlhYmlsaWRhZCBvIGRpc3BlcnNpw7NuIGRlIGxvcyBkYXRvcyBkZSBsYSB2YXJpYWJsZSBhbmFsaXphZGEuClBhcmEgZWxsbyBleGlzdGVuIGRvcyBncmFuZGVzIG1hbmVyYXMgZGUgaGFjZXJsbzogaS4gdW5hIGNvbnNpc3RlIGVuIHVuYSBkZXNjcmlwY2nDs24gYmFzYWRhIGVuIGVzdGFkw61zdGljb3MgeSBpaS4gb3RyYSBjb25zaXN0ZSBlbiBsYSBkZXNjcmlwY2nDs24gYmFzYWRhIGVuIG3DqXRvZG9zIGdyw6FmaWNvcy4KCiMjIyAxLjEuIERlc2NyaXBjacOzbiBiYXNhZGEgZW4gZXN0YWTDrXN0aWNvcwoKTGEgZGVzY3JpcGNpw7NuIGJhc2FkYSBlbiBlc3RhZMOtc3RpY29zIGNvbnNpc3RlIGVuIGxhIGFwbGljYWNpw7NuIGRlIGNpZXJ0YXMgZnVuY2lvbmVzIGFsZ2VicsOhaWNhcyBwYXJhIHByb2Nlc2FyIGxvcyBkYXRvcyB5ICJyZWR1Y2lybG9zIiBhIHZhbG9yZXMgaW5kaWNhdGl2b3MgcXVlLCBwb3N0ZXJpb3JtZW50ZSwgc2Vyw6FuIGludGVycHJldGFkb3Mgc29icmUgYWxndW5vcyBhc3BlY3RvcyBpbXBvcnRhbnRlcyBkZSBsYSBkaXN0cmlidWNpw7NuIGRlIHVuYSBvIHZhcmlhcyB2YXJpYWJsZXMuCkRpY2hhcyBmdW5jaW9uZXMgYnVzY2FuIGlkZW50aWZpY2FyIGRvcyBhc3BlY3RvcyBiw6FzaWNvcyBkZSBsYSBkaXN0cmlidWNpw7NuIGRlIGxhIHZhcmlhYmxlOiBhLiBsYSBjZW50cmFsaWRhZCBkZSBsYSBkaXN0cmlidWNpw7NuIGEgdHJhdsOpcyBkZSBsYXMgTWVkaWRhcyBkZSBUZW5kZW5jaWEgQ2VudHJhbCAoTVRDKSB5LCBiLiBsYSBkaXNwZXJzacOzbiBkZSBsb3MgZGF0b3MgcmVzcGVjdG8gZGUgc3UgY2VudHJhbGlkYWQgbWVkaWFudGUgbGFzIE1lZGlkYXMgZGUgRGlzcGVyc2nDs24gKE1EKS4KCiMjIyMgMS4xLjEuIE1lZGlkYXMgZGUgVGVuZGVuY2lhIENlbnRyYWwgKE1UQykKCkxhIGlkZW50aWZpY2FjacOzbiBkZSBsYSBjZW50cmFsaWRhZCBkZSBsYSBkaXN0cmlidWNpw7NuIGRlIHVuYSB2YXJpYWJsZSBzZSBsb2dyYSBhIHBhcnRpciBkZSB1YmljYXIgbGFzIE1UQy4gw4lzdGFzIHNlIHJlZmllcmVuIGEgdW4gY29uanVudG8gZGUgZnVuY2lvbmVzLCBsYXMgcXVlIHN1IHBlcnRpbmVuY2lhIGRlcGVuZGVyw6EgZGVsIHRpcG8gZGUgZXNjYWxhIGRlIG1lZGljacOzbiBkZSBsYSB2YXJpYWJsZS4KCisgRW4gZWwgY2FzbyBkZSBsYXMgKip2YXJpYWJsZXMgZGlzY3JldGFzIG8gY2F0ZWfDs3JpY2FzIChub21pbmFsZXMgdW4gb3JkaW5hbGVzKSoqLCBsYXMgTVRDIHByaW5jaXBhbGVzIGNvbnNpc3RlbiBlbiBsYSAqKm1vZGEqKiB5IGxhICoqbWVkaWFuYSoqIC4gRXN0ZSB0aXBvIGRlIHZhcmlhYmxlcyBkaXNjcmV0YXMgbyBjYXRlZ8OzcmljYXMgdXN1YWxtZW50ZSBzb24gcmVjb25vY2lkYXMgcG9yIGVsIHByb2dyYW1hIGNvbW8gdmFyaWFibGVzIHRpcG8gImZhY3RvciIsIHkgZGUgZXN0YSBmb3JtYSBkZXNjYXJ0YSBxdWUgc3UgY29tcG9ydGFtaWVudG8gc2VhIGNvbnRpbnVvLgoKRWwgZXN0YWTDrXN0aWNvIGRlIGxhICoqbWVkaWFuYSoqIHNlIHJlZmllcmUgYWwgdmFsb3IgcXVlIGFkcXVpZXJlIGVsIGNhc28gcXVlIHNlIHViaWNhIGEgbGEgbWl0YWQgZGUgbGEgZGlzdHJpYnVjaW9uIGRlIHRvZG9zIGxvcyBjYXNvcyBlbiB1bmEgbXVlc3RyYS4gRXN0byBlcywgZGljaG8gY2FzbyBwZXJtaXRlIHBhcnRpciBlbiBkb3MgZ3J1cG9zIGNvbiBsYSBtaXNtYSBjYW50aWRhZCBkZSBjYXNvcyBhbCB0b3RhbCBkZSBsYSBtdWVzdHJhIHBhcmEgdW5hIHZhcmlhYmxlLgpQYXJhIHN1IGPDoWxjdWxvIHNlIHV0aWxpemEgZWwgY29tYW5kbyBgbWVkaWFuKClgIGRlIGxhIHNpZ3VpZW50ZSBmb3JtYToKCmBgYHtyIG1lZGlhbmF9Cm1lZGlhbihkYXRvc19jb3ZpZCRTRUNUT1IpICNTb2xpY2l0dWQgZGUgTUVESUFOQQpgYGAKClByZWd1bnRhOgrCv0N1w6FsIGVzIGxhIGNhdGVnb3LDrWEgZW4gbGEgcXVlIHNlIGVuY3VlbnRyYSBlbCBjYXNvIHF1ZSBvY3VwYSBsYSBwb3NpY2nDs24gbWVkaWFuYSBkZSBsYSBkaXN0cmlidWNpw7NuPwoKUiBubyBjb21wdXRhIGxhICoqbW9kYSoqIGRlIG1hbmVyYSBkaXJlY3RhLCBwb3IgbG8gcXVlIGVuIG9jYXNpb25lcyBlcyBwZXJ0aW5lbnRlIGlkZW50aWZpY2FybGEgdXRpbGl6YW5kbyBvdHJvcyBtw6l0b2Rvcy4gVW5hIG1hbmVyYSBwYXJhIGhhY2VybG8gY29uc2lzdGUgZW4gc29saWNpdGFyIHVuIHRhYnVsYWRvIG8gdGFibGEgZGUgZnJlY3VlbmNpYXMgZGUgbGFzIGNhdGVnb3LDrWFzIHksIGFzw60sIHViaWNhciBlbCBhdHJpYnV0byBtw6FzIGZyZWN1ZW50ZS4KCmBgYHtyIHRhYmxhfQp0YWJsZShkYXRvc19jb3ZpZCRTRUNUT1IpCmBgYAoKUHJlZ3VudGE6CsK/Q3XDoWwgY2F0ZWdvcsOtYSBkZWwgU0VDVE9SIG9jdXBhIGxhIG1vZGEgZGUgbGEgZGlzdHJpYnVjacOzbj8KCisgRW4gZWwgY2FzbyBkZSBjb250YXIgY29uIHVuYSAqKnZhcmlhYmxlIGNvbnRpbnVhIChkZSByYXrDs24gbyBpbnRlcnZhbGFyKSoqLCBsYSAqKm1lZGlhKiogZXMgZWwgZXN0YWTDrXN0aWNvIG3DoXMgcGVydGluZW50ZSBhIGNhbGN1bGFyIGNvbiBlbCBmaW4gZGUgdWJpY2FyIGVsIHB1bnRvIGRlIGNvbmNlbnRyYWNpw7NuIGRlIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbG9zIGRhdG9zLgpBcXXDrSBlcyBpbXBvcnRhbnRlIHJlY29yZGFyIHF1ZSBlc3RlIGVzdGFkw61zdGljbyBlcyBzdXNjZXB0aWJsZSBhIHZhbG9yZSBleHRyZW1vcywgcHVlcyBlbiBsYSBtZWRpZGEgZW4gcXVlIGVzdG9zIHNlIHByZXNlbnRlbiBlbnRvbmNlcyBoYXLDoSBxdWUgc3UgdmFsb3Igc2UgImNvcnJhIiBvIHRpZW5kYSBhIG1vdmVyc2UgaGFjaWEgZGljaG9zIGV4dHJlbW9zLgoKYGBge3IgbWVkaWF9Cm1lYW4oZGF0b3NfY292aWQgJCBFREFEKSAjc29saWNpdHVkIHBhcmEgbGEgbWVkaWEgZGUgdW5hIHZhcmlhYmxlIGNvbnRpbnVhCmBgYAoKUHJlZ3VudGE6CsK/Q3XDoWwgZXMgbGEgZWRhZCBwcm9tZWRpbyBkZSBsYXMgcGVyc29uYXMgcmVnaXN0cmRhcyBjb24gc8OtbnRvbWFzIGRlIENPVklELTE5PwoKQXF1w60gZXMgaW1wb3J0YW50ZSByZWNvcmRhciBxdWUgZXN0ZSBlc3RhZMOtc3RpY28gZXMgc3VzY2VwdGlibGUgYSB2YWxvcmUgZXh0cmVtb3MsIHB1ZXMgZW4gbGEgbWVkaWRhIGVuIHF1ZSBlc3RvcyBzZSBwcmVzZW50ZW4gZW50b25jZXMgaGFyw6EgcXVlIHN1IHZhbG9yIHNlICJjb3JyYSIgbyB0aWVuZGEgYSBtb3ZlcnNlIGhhY2lhIGRpY2hvcyBleHRyZW1vcy4gUG9yIGVsbG8sIGN1YW5kbyBlc3RvIG9jdXJyZSBlcyBwZXJ0aW5lbnRlIGNhbGN1bGFyIGVsIHZhbG9yIGRlIGxhICoqbWVkaWFuYSoqIHBhcmEgY29udHJhc3RhciBsYSBwZXJ0aW5lbnRlbmNpYSBkZSBsYSAqKm1lZGlhKiouCgpgYGB7ciBtZWRpYW5hX2NvbnR9Cm1lZGlhbihkYXRvc19jb3ZpZCAkIEVEQUQpCmBgYAoKCkVsIHByb2dyYW1hIFIgY3VlbnRhIGNvbiBvdHJhcyBvcGNpb25lcyBwYXJhIGNhbGN1bGFyIGFsZ3Vub3MgZXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3MgZW4gdW4gc29sbyBzY3JpcHQsIHBvciBlamVtcGxvOgoKYGBge3Igc3VtbWFyeX0Kc3VtbWFyeShkYXRvc19jb3ZpZCAkIEVEQUQpICNzY3JpcHQgcGFyYSB2YXJpb3MgZXN0YWTDrXN0aWNvcyBkZSBNVEMKYGBgCgpFc3RlIHNjcmlwdCBhcnJvamEgZGl2ZXJzb3MgZXN0YWTDrXN0aWNvcyBkZXNjcmlwdGl2b3M6IHZhbG9yIG3DrW5pbW8sIHZhbG9yIG3DoXhpbW8sIG1lZGlhLCBtZWRpYW5hLCB2YWxvciBkZWwgMWVyIHkgM2VyIGN1YXJ0aWwuIENvbiBlc3RvcyBwb2RlbW9zIGRhcm5vcyB1bmEgaWRlYSBtw6FzIGNvbXBsZXRhIHNvYnJlIGVsIHB1bnRvIGRlIGNvbmNlbnRyYWNpw7NuIGRlIGxhcyB2YXJpYWJsZXMgY29udGludWFzLgoKUHJlZ3VudGFzOgrCv0N1w6FsIGVzIGVsIHRhbWHDsW8gZGVsIHJhbmdvIGRlIGVkYWQgZGUgbG9zIGNhc29zIHJlZ2lzdHJhZG9zPyAKwr9DdcOhbCBlcyBlbCB0YW1hw7FvIGRlbCByYW5nbyBpbnRlcmN1YXJ0aWwgZW4gZWwgcXVlIHNlIHViaWNhIGVsIDUwJSBkZSBsb3MgY2Fzb3MgYWxyZWRlZG9yIGRlIGxhIG1lZGlhbmE/CgpFbiBlbCBjYXNvIGRlIHNvbGljaXRhciBlbCBjw6FsY3VsbyBkZSBkaXZlcnNvcyBlc3RhZMOtc3RpY29zIGVuIHVuIG1pc21vIHNjcmlwdCwgc2UgcHVlZGUgaGFjZXIgdXNvIGRlIGxhcyBmdW5jaW9uZXMgZGUgKipkcGx5cioqOgoKYGBge3IgbWVkaWFfbWVkaWFuYX0KZGF0b3NfY292aWQgJT4lICAjc2UgbGxhbWEgYWwgRGF0YSBGcmFtZQogIGdyb3VwX2J5KFNFWE8pICU+JSAgI3NlIHBpZGUgcXVlIGxvcyBkYXRvcyBzZSBhZ3J1cGVuIHBvciBTRVhPCiAgc3VtbWFyaXNlKG1lZGlhX2VkYWQgPSBtZWFuKEVEQUQsIG5hLnJtID0gVFJVRSksI3NlIHNvbGljaXRhbiBlc3RhZMOtc3RpY29zIAogICAgICAgICAgICBtZWRpYW5hX2VkYWQgPSBtZWRpYW4oRURBRCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgbigpKQpgYGAKCgojIyMjIDEuMS4yLiBNZWRpZGFzIGRlIERpc3BlcnNpw7NuIChNRCkKCkxhcyBNZWRpZGFzIGRlIERpc3BlcnNpw7NuIChNRCkgc29uIG90cm8gdGlwbyBkZSBpbmZvcm1hY2nDs24gcmVsZXZhbnRlIHBhcmEgY29ub2NlciBsYSBmb3JtYSBkZSBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBkYXRvcy4gRXN0YXMgbWVkaWRhcyBheXVkYW4gYSBlbnRlbmRlciBsYSBhbXBsaXR1ZCBkZSBsYSBkaXN0YW5jaWEgZGUgbG9zIGRhdG9zIHJlc3BlY3RvIGRlbCBwdW50byBkZSBjb25jZW50cmFjacOzbiBkZSBsYSB2YXJpYWJsZSBkZSBpbnRlcsOpcy4KRXhpc3RlbiBkaXZlcnNhcyBtZWRpZGFzIGRlIHRlbmRlbmNpYSBjZW50cmFsIHBlcm8gc3UgcGVydGluZW5jaWEgdmFyw61hIHNlZ8O6biBlbCB0aXBvIGRlIHZhcmlhYmxlIG8gc3UgZXNjYWxhIGRlIG1lZGljacOzbi4KCisgRW4gZWwgY2FzbyBkZSBsYXMgKip2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIChlbiBlc2NhbGEgbm9taW5hbCB1IG9yZGluYWwpKiosIGxhcyBNRCBtw6FzIHBlcnRpbmVudGVzIHNvbiBsYXMgKipwcm9wb3JjaW9uZXMqKiBkZSBmcmVjdWVuY2lhcyBwYXJhIGNhZGEgdW5hIGRlIGxvcyBhdHJpYnV0b3MgY2F0ZWfDs3JpY29zIG8gdmFsb3JlcyBwb3NpYmxlcyBkZSBjYWRhIHZhcmlhYmxlIChWaWxhbHRhLCAyMDE2OiA2OSkuClBhcmEgZWxsbywgZWwgY2FzbyBkZSBlc3RlIHRpcG8gZGUgdmFyaWFibGVzIGNhdGVnw7NyaWNhcyBlcyBwZXJ0aW5lbnRlIG9ic2VydmFyIGxhIG1hbmVyYSBlbiBxdWUgbG9zIGNhc29zIHNlIGRpc3RyaWJ1eWVuIGVudHJlIGxhcyBkaXN0aW50YXMgY2F0ZWdvcsOtYXMuCgpgYGB7ciBwcm9wX3RhYmxlX3NpbXBsZX0KcHJvcC50YWJsZSh0YWJsZShkYXRvc19jb3ZpZCAkIFNFQ1RPUikpCmBgYAoKRW4gbGEgdGFibGEgZGUgcHJvcG9yY2lvbmVzIHNlIG9ic2VydmFuIGxvcyB2YWxvcmVzIGFycm9qYWRvcyBlbiBub3RhY2nDs24gImNpZW50w61maWNhIiwgbG8gcXVlIHB1ZWRlIG9jYXNpb25hciBkaWZpY3VsdGFkIGluaWNpYWwgcGFyYSBpbnRlcnByZXRhcmxvcy4gRXN0byBvY3VycmUgcG9ycXVlIGVuIGFsZ3Vub3MgY2Fzb3MsIGxvcyB2YWxvcmVzIHB1ZWRlbiBjb250ZW5lciBkZWNpbWFsZXMgcGVxdWXDsW9zLgpPdHJvIGVsZW1lbnRvIHF1ZSBhcnJvamEgZGljaGEgdGFibGEgZXMgbGEgcHJlc2VuY2lhIGRlIGxvcyBjYXNvcyBjb2RpZmljYWRvcyBjb24gZWwgdmFsb3IgZGUgOTksIHkgcXVlIHNhYmVtb3MgLWNvbW8gYW5hbGlzdGFzLSBxdWUgc2UgcmVmaWVyZW4gbG9zIGNhc29zICpwZXJkaWRvcyouIERlIG1hbmVyYSBxdWUgYWwgZGVqYXJsb3MgY29tbyB0YWwsIGhhcsOhbiBxdWUgbGFzIHByb3BvcmNpb25lcyB2YXLDrWVuIHB1ZXMgdGFtYmnDqW4gc2UgbGVzIGluY2x1eWUgZW4gZWwgY8OhbGN1bG8uIFBhcmEgZXZpdGFyIHF1ZSBzZXNndWVuIGxvcyByZXN1bHRhZG9zLCBkZWJlbiBzZXIgZXhjbHVpZG9zIGRlbCBhbsOhbGlzaXMuIFBhcmEgbG8gcXVlIHNlcsOhIGltcG9ydGFudGUgdHJhdGFybG9zIGNvbW8gZGF0b3MgcGVyZGlkb3MsIHkgZWxsbyBkZWJlbW9zIGhhY8OpcnNlbG8gc2FiZXIgYSBSLgoKQSBjb250aW51YWNpw7NuIHNlIGxlIHNvbGljaXRhcsOhIGEgUiBxdWUgY2FtYmllIGxhIG5vdGFjacOzbiBlbiBxdWUgc2UgcHJlc2VudGFuIGxvcyByZXN1bHRhZG9zIGRlY2ltYWxlcywgcGFyYSBlbGxvIHNlIHVzYXLDoSBlbCBjb21hbmRvIGBvcHRpb25zKHNjaXBlbiA9IDk5OSlgLCB5IHRhbWJpw6luIHNlIGFzaWduYXLDoW4gbG9zIHZhbG9yZXMgcGVyZGlkb3MgdXNhbmRvIGVsIGNvbWFuZG8gYG5hX2lmKClgIGRlIGxhIHNpZ3VpZW50ZSBtYW5lcmE6CgpgYGB7ciB0cmFuc2ZfbmF9Cm9wdGlvbnMoc2NpcGVuID0gOTk5KSAjcGVybWl0ZSBjYW1iaWFyIGxhIG5vdGFjacOzbiBkZSBjaWVudMOtZmljYSBhIGRlY2ltYWwKZGF0b3NfY292aWQgPC0gZGF0b3NfY292aWQgJT4lCiAgbXV0YXRlKFNFQ1RPUl9SID0gbmFfaWYoU0VDVE9SLCA5OSkpICN0cmFuc2Zvcm1hY2nDs24gZGUgbG9zIHZhbG9yZXMgOTkgYSBOQQpgYGAKClkgYWhvcmEgc2UgdnVlbHZlIGEgc29saWNpdGFyIGxhIHRhYmxhIGRlIHByb3BvcmNpb25lczoKCmBgYHtyIHByb3BfdGFibGVfc2luX25hfQpwcm9wLnRhYmxlKHRhYmxlKGRhdG9zX2NvdmlkJFNFQ1RPUl9SKSkgI2VuIHZhbG9yZXMgZGUgcHJvcG9yY2nDs24KYGBgCgpgYGAge3IgcHJvcF90YWJsZV9zaW5fbmFfcG9yY2VufQpwcm9wLnRhYmxlKHRhYmxlKGRhdG9zX2NvdmlkJFNFQ1RPUl9SKSkgKiAxMDAgI3BvcmNlbnRhamUgZGUgY2Fzb3MgYXRlbnRpZG9zIGVuIGNhZGEgdGlwbyBkZSBTRUNUT1IgZXhjbHV5ZW5kbyBsb3MgTkEKYGBgCgpQcmVndW50YToKwr9DdcOhbCBlcyBlbCBzZWN0b3IgaG9zcGl0YWxhcmlvIGNvbiBtYXlvciBwb3JjZW50YWplIGRlIGNhc29zIHJlZ2lzdHJhZG9zLCBkZXNjb250YW5kbyBsb3MgY2Fzb3Mgc2luIHJlZ2lzdHJvPwoKKyBFbiBlbCBjYXNvIGRlIGxhcyAqKnZhcmlhYmxlcyBjb250aW51YXMgKGRlIHJhesOzbiBvIGludGVydmFsbykqKiBleGlzdGVuIG90cm9zIGVzdGFkw61zdGljb3MgcXVlIHBlcm1pdGVuIG9ic2VydmFyIGRpc3RpbnRhcyBtZWRpZGFzIGRlIGRpc3BlcnNpw7NuLgoKRWwgKipSYW5nbyoqIGRlIGxvcyBkYXRvcywgcXVlIGNvbnNpc3RlIGVuIGxhIGRpc3RhbmNpYSBlbnRyZSBlbCB2YWxvciBtw61uaW1vIHkgZWwgbXZhbG9yIG3DoXhpbW8gZGUgbG9zIGRhdG9zIHJlZ2lzdHJhZG9zLiBFc3RlIGVzdGFkw61zdGljbyBubyBzZSBwcmVvY3VwYSBwb3IgdWJpY2FyIGVsIHB1bnRvIGRlIGNvbmNlbnRyYWNpw7NuIG8gbGEgY2VudHJhbGlkYWQgZGUgbGEgZGlzdHJpYnVjacOzbi4KCmBgYCB7ciByYW5nb30KcmFuZ2UoZGF0b3NfY292aWQkRURBRCkKYGBgCgpMb3MgZXN0YWTDrXN0aWNvcyBtw6FzIMO6dGlsZXMgcGFyYSBldmFsdWFyIGxhIGRpc3BlcnNpw7NuIGRlIGxvcyBkYXRvcyByZXNwZWN0byBkZWwgdmFsb3IgZGUgbGEgbWVkaWEgc29uOiBsYSBkZXN2aWFjacOzbiBlc3TDoW5kYXIgbyB0w61waWNhIHkgbGEgdmFyaWFuemEuCgpgYGB7ciBkZXN2X2VzdF92YXJ9CmRhdG9zX2NvdmlkICU+JQogIHN1bW1hcmlzZShkZXN2aWFjacOzbl90w61waWNhID0gc2QoRURBRCwgbmEucm0gPSBUUlVFKSwgI2BzZCgpYCBjYWxjdWxhIGxhIGRlc3ZpYWNpw7NuIGVzdMOhbmRhcgogICAgICAgICAgICB2YXJpYW56YV9lZGFkID0gdmFyKEVEQUQsIG5hLnJtID0gVFJVRSkpICNgdmFyKClgY2FsY3VsYSBsYSB2YXJpYW56YQpgYGAKCk90cmFzIE1EIGNvbnNpc3RlbiBlbiBsYSBpZGVudGlmaWNhY2nDs24gZGUgbG9zIGN1YW50aWxlcywgYSBwYXJ0aXIgZGUgdWJpY2FyIGxvcyB2YWxvcmVzIHF1ZSBzaXJ2ZW4gZGUgcHVudG9zIGRlIGNvcnRlIHBhcmEgZm9ybWFyIGdydXBvcyBjb24gbGEgbWlzbWEgY2FudGlkYWQgZGUgY2Fzb3MgZW4gc3UgaW50ZXJpb3IuIFBvciBkZWZhdWx0LCBlbCBzY3JpcHQgYHF1YW50aWxlKClgIGNyZWEgNCBncnVwb3MgY29uIGVsIDI1JSBkZSBsb3MgY2Fzb3MgZW4gY2FkYSB1bm8uIEVzdG9zIGdydXBvcyBzZSBsbGFtYW4gKipjdWFydGlsZXMqKi4KCmBgYHtyIGN1YXJ0aWxlc30KcXVhbnRpbGUoZGF0b3NfY292aWQkRURBRCkKYGBgCgpFbiBlbCBjYXNvIGRlIGJ1c2NhciBsYSBkaXZpc2nDs24gZGUgbGEgbXVlc3RyYSBlbiBvdHJhIGNhbnRpZGFkIGRlIGdydXBvIHF1ZSBjb250ZW5nYW4gbGEgbWlzbWEgY2FudGlkYWQgZGUgY2Fzb3MgKHlhIHNlYSBlbiAxMCBncnVwb3MgbyBkZWNpbGVzLCBvIGVuIDEwMCBncnVwb3MgbyBwZXJjZW50aWxlcyksIHRhbWJpw6luIHNlIHB1ZWRlIHV0aWxpemFyIGVsIHNjcmlwdCBgcXVhbnRpbGUoKWAsIHBlcm8gc2UgZGViZSBpbmNsdWlyIGVsIGNyaXRlcmlvIGRlIGFncnVwYWNpw7NuLgoKYGBge3IgZGVjaWxlc30KcXVhbnRpbGUoZGF0b3NfY292aWQgJCBFREFELCBwcm9icyA9IHNlcSgwLCAxLCAwLjEwKSwgbmEucm0gPSBGQUxTRSkKYGBgCgrCv0VudHJlIGN1w6FsZXMgZWRhZGVzIHNlIGVuY3VlbnRyYSBlbCAzMCUgZGUgbG9zIGNhc29zIG3DoXMgasOzdmVuZXMgY29uIHPDrW50b21hcyBjb3ZpZC0xOT8KCkEgcGFydGlyIGRlIGxvcyBlc3RhZMOtc3RpY29zIHNvYnJlIGxhICoqYXNpbWV0csOtYSoqIHkgKipjdXJ0b3NpcyoqIHNlIHB1ZWRlIGNvbm9jZXIgZWwgc2VzZ28gZGUgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSB2YXJpYWJsZS4KUGFyYSBlbGxvIHNlIGRlYmUgaW5zdGFsYXIgbGEgcGFxdWV0ZXLDrWEgIm1vbWVudHMiLCBxdWUgcGVybWl0ZSBsbGFtYXIgYSBkaWNob3MgZXN0YWTDrXN0aWNvcy4KCmBgYHtyIGFzaW1ldHJpYV9rdXJ0fQpsaWJyYXJ5KG1vbWVudHMpCmRhdG9zX2NvdmlkICU+JQogIHN1bW1hcmlzZShhc2ltZXRyw61hX2VkYWQgPSBza2V3bmVzcyhkYXRvc19jb3ZpZCAkIEVEQUQpLCAjYXJyb2phIGVsIHNlc2dvIChpenF1aWVyZGEgLyBkZXJlY2hhKSBkZSBsYSBkaXN0cmlidWNpw7NuLgogICAgICAgICAgICBjdXJ0b3Npc19lZGFkID0ga3VydG9zaXMoZGF0b3NfY292aWQgJCBFREFEKSkgI25vcyBkYSBlbCBhY2hhdGFtaWVudG8gZGUgbGEgZGlzdHJpYnVjaW9uIGRlIGxvcyBkYXRvcyBkZSBsYSB2YXJpYWJsZS4KYGBgCgpEYWRvIHF1ZSB0YWxlcyB2YWxvcmVzIGVzdMOhbiBleHByZXNhZG9zIGVuIGxhIHVuaWRhZCBkZSBtZWRpZGEgZGUgbGEgdmFyaWFibGUgZW4gY3Vlc3Rpw7NuLCBubyBzb24gw7p0aWxlcyBwYXJhIGNvbXBhcmFyIHZhcmlhYmxlcyBkZSBkaWZlcmVudGVzIHVuaWRhZGVzIGRlIG1lZGljacOzbi4gRXMgcG9yIGVzbyBxdWUgc2UgY2FsY3VsYW4gbG9zIGNvZWZpY2llbnRlcyBkZSBzaW1ldHLDrWEgeSBjdXJ0b3NpcyBlc3RhbmRhcml6YWRvczogcGFyYSBlbGxvLCBzZSBkaXZpZGUgbGEgc2ltZXRyw61hIGNhbGN1bGFkYSwgcG9yIGxhIHJhw616IGN1YWRyYWRhIGRlbCB2YWxvciA2IChlc3RlIG7Dum1lcm8gZXMgdW5hIGNvbnN0YW50ZSBlbiBsYSBmw7NybXVsYSkgZGl2aWRpZG8gZW4gbGEgY2FudGlkYWQgZGUgY2Fzb3MgZGUgbGEgdmFyaWFibGUgKDQwMTc1NSkuCgpgYGB7ciBhc2ltX2t1cnR9CmRhdG9zX2NvdmlkICU+JQogIHN1bW1hcmlzZShhc2ltZXRyw61hX2VkYWQgPSBza2V3bmVzcyhkYXRvc19jb3ZpZCAkIEVEQUQpIC8gc3FydCg2IC8gNDAxNzU1KSwgI2Fycm9qYSBlbCBzZXNnbyBlc3RhbmRhaXphZG8gZGUgbGEgZGlzdHJpYnVjacOzbi4KICAgICAgICAgICAgY3VydG9zaXNfZWRhZCA9IGt1cnRvc2lzKGRhdG9zX2NvdmlkICQgRURBRCkgLyBzcXJ0KDYgLyA0MDE3NTUpKSAjbm9zIGRhIGVsIGFjaGF0YW1pZW50byBkZSBsYSBkaXN0cmlidWNpb24gZXN0YW5kYXJpemFkYSBkZSBsb3MgZGF0b3MgZGUgbGEgdmFyaWFibGUuCmBgYAoKVW4gY3JpdGVyaW8gZ2VuZXJhbCBwYXJhIGRldGVybWluYXIgc2kgbG9zIGNvZWZpY2llbnRlcyBkZSBzaW1ldHLDrWEgeSBjdXJ0b3NpcyByZWZsZWphbiB1bmEgdmFyaWFibGUgc2VtZWphbnRlIGEgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIGVzIHF1ZSBhbWJvcyB2YWxvcmVzIHNlIGVuY3VlbnRyZW4gZW50cmUgLTIgeSAyLiBDb21vIHB1ZWRlIG9ic2VydmFyc2UgZW4gbG9zIHJlc3VsdGFkb3MsIGFtYm9zIGNvZWZpY2llbnRlcyBlc2NhcGFuIGEgdGFsIHJhbmdvIHBvciBsbyBxdWUgc2Ugb2JzZXJ2YSB1bmEgZGlzdHJpYnVjacOzbiBwb2NvIHNpbWlsYXIgYSB1bmEgbm9ybWFsLgoKRWwgY29lZmljaWVudGUgZGUgdmFyaWFjacOzbiBwdWVkZSBjYWxjdWxhcnNlIGRlIG1hbmVyYSBzZW5jaWxsYSwgZWplY3V0YW5kbyB1bmEgZGl2aXNpw7NuIHNpbXBsZSBlbnRyZSBsYSBkZXN2aWFjacOzbiBlc3TDoW5kYXIgeSBsYSBtZWRpYSBkZSBsYSB2YXJpYWJsZSBkZSBpbnRlcsOpcywgeSBub3MgaW5mb3JtYSBzb2JyZSBsYSBkaXNwZXJzacOzbiByZWxhdGl2YSBkZSB1bmEgdmFyaWFibGUuIFkgc2UgdXRpbGl6YSBwYXJhIGNvbXBhcmFyIGNvbmp1bnRvcyBkZSBkYXRvcyBwZXJ0ZW5lY2llbnRlcyBhIHBvYmxhY2lvbmVzIGRpc3RpbnRhcy4gU2kgYXRlbmRlbW9zIGEgc3UgZsOzcm11bGEsIHZlbW9zIHF1ZSBlc3RlIHRpZW5lIGVuIGN1ZW50YSBlbCB2YWxvciBkZSBsYSBtZWRpYSwgcG9yIGxvIHF1ZSBlbCBjb2VmaWNpZW50ZSBkZSB2YXJpYWNpw7NuIG5vcyBwZXJtaXRlIHRlbmVyIHVuYSBtZWRpZGEgZGUgZGlzcGVyc2nDs24gcXVlIGVsaW1pbmEgbGFzIHBvc2libGVzIGRpc3RvcnNpb25lcyBkZSBsYXMgbWVkaWFzIGRlIGRvcyBvIG3DoXMgcG9ibGFjaW9uZXMuCkEgbWVkaWRhIHF1ZSBlbCB2YWxvciBkZWwgY29lZmljaWVudGUgc2UgYWxlamEgZGUgMCwgbGEgdmFyaWFjacOzbiBlcyBtYXlvci4KCmBgYHtyIGNvZWZfdmFyfQpzZChkYXRvc19jb3ZpZCAkIEVEQUQpIC8gbWVhbihkYXRvc19jb3ZpZCAkIEVEQUQpCmBgYAoKCkZpbmFsbWVudGUsIGxhIGZvcm1hIG3DoXMgY2VydGVyYSBwYXJhIGV2YWx1YXIgc2kgbGEgZGlzdHJpYnVjacOzbiBkZSBkYXRvcyBkZSB1bmEgdmFyaWFibGUgc2UgY29tcG9ydGEgc2Vnw7puIGxvcyBwYXLDoW1ldHJvcyBxdWUgYXN1bWUgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIGVzIGFwbGljYW5kbyB1biB0ZXN0IGVzdGFkw61zdGljbyBlc3BlY8OtZmljYW1lbnRlIG9yaWVudGFkbyBhIHRhbCBldmFsdWFjacOzbi4gUGFyYSBlbGxvLCBzZSBkaWZlcmVuY2lhIGVsIHRlc3QgZGUgU2hhcGlybyBXaWxraW5zb24geSBlbCBkZSBLb2xtb2dvcm92IFNtaXJub2ZmLiBFbCBwcmltZXJvIGVzIGFwbGljYWJsZSBhIG11ZXN0cmFzIHBlcXVlw7FhcyAodXN1YWxtZW50ZSBzZSByZWZpZXJlIGEgbXVlc3RyYXMgbWVub3JlcyBhIDUwIGNhc29zLCBwZXJvIHNvcG9ydGEgaGFzdGEgMjUwMCBjYXNvcyksIG1pZW50cmFzIHF1ZSBlbCBzZWd1bmRvIHNpcnZlIHBhcmEgbXVlc3RyYXMgZGUgZ3JhbmRlcyAocG9yIGVuY2ltYSBkZSAyNTAwIGNhc29zKS4KCkNyZWFjacOzbiBkZSBzdWJtdWVzdHJhIGNvbiA1MCBjYXNvczogCgpgYGB7ciBzdWJtdWVzdHJhXzUwfQpzZXQuc2VlZCgxMzU3KQpzdWJtdWVzdHJhXzUwIDwtIGRhdG9zX2NvdmlkICU+JQogIHNhbXBsZV9uKDUwLCByZXBsYWNlID0gRkFMU0UpCmBgYAoKRXZhbHVhY2nDs24gZGUgcHJ1ZWJhIGRlIG5vcm1hbGlkYWQgY29uIHBydWViYSBTaGFwaXJvIC0gVy46CgpgYGB7ciBzaGFwaXJvfQojUHJ1ZWJhIGRlIFNoYXBpcm8gV2lsayAobXVlc3RyYXMgcGVxdWXDsWFzKQpzaGFwaXJvLnRlc3Qoc3VibXVlc3RyYV81MCRFREFEKQpgYGAKCkNyZWFjacOzbiBkZSBzdWJtdWVzdHJhIGNvbiA1MDAgY2Fzb3M6CgpgYGB7ciBzdWJtdWVzdHJhXzUwMH0Kc2V0LnNlZWQoMTM1NykKc3VibXVlc3RyYV81MDAgPC0gZGF0b3NfY292aWQgJT4lCiAgc2FtcGxlX24oNTAwLCByZXBsYWNlID0gVFJVRSkKYGBgCgpQcnVlYmEgS29sbW9nb3JvdiBTbWlybm9mZjoKCmBgYHtyIGtvbG1vZ29yb3Z9CiNQcnVlYmEgS29sbW9nb3JvdiBTbWlybm92IChtdWVzdHJhcyBncmFuZGVzKQprcy50ZXN0KHN1Ym11ZXN0cmFfNTAwJEVEQUQsICJwbm9ybSIsIG1lYW4oc3VibXVlc3RyYV81MDAkRURBRCwgbmEucm0gPSBUKSwgc2Qoc3VibXVlc3RyYV81MDAkRURBRCwgbmEucm0gPSBUKSkKYGBgCgpEaWNoYXMgcHJ1ZWJhcyBlc3RhZMOtc3RpY2FzIHNpcnZlbiBwYXJhIGV2YWx1YXIgaW5mZXJlbmNpYXMgZGVsIGludmVzdGlnYWRvciBvIC1mb3JtYWxtZW50ZS0gKipoaXDDs3Rlc2lzKiouIEVuIGVzdGUgY2Fzbywgc3VlbGVuIHRyYWJhamFyIHNvYnJlIHVuYSAqaGlww7N0ZXNpcyBudWxhKiAoSDApIHF1ZSwgcGFyYSBlbCBjYXNvIGRlIGFtYmFzIG11ZXN0cmFzIHBsYW50ZWEgcXVlICpsYSB2YXJpYWJsZSBldmFsdWFkYSBzZSBkaXN0cmlidXllIGNvbW8gc2kgZnVlcmEgdW5hIGRpc3RyaWJ1Y2nDs24gbm9ybWFsKi4KUGFyYSBkZXRlcm1pbmFyIG5vcm1hbGlkYWQgdW5pdmFyaWFkYSBzZSBidXNjYSB1biAqKnZhbG9yIHAqKiAqbWF5b3IgYSAwLjA1KiBwYXJhIG5vIHJlY2hhemFyIGxhIGhpcMOzdGVzaXMgbnVsYSwgKnF1ZSBlc3RhYmxlY2UgbGEgaWd1YWxkYWQgZW50cmUgbGEgZGlzdHJpYnVjacOzbiBub3JtYWwgdGXDs3JpY2EgeSBsYSBkaXN0cmlidWNpw7NuIGVtcMOtcmljYSBkZSBsb3MgZGF0b3MgcXVlIGVzdGFtb3MgZXZhbHVhZG8qLiBTaSBlbCAqKnAtdmFsdWUqKiBjYWxjdWxhZG8gZW4gbGEgcHJ1ZWJhIGVzIG1heW9yIGEgMC4wNSBlbnRvbmNlcyBubyBzZSBwdWVkZSByZWNoYXphciBsYSBIMCwgcXVlIGVzdGFibGVjZSBxdWUgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSB2YXJpYWJsZSBzZSBwYXJlY2UgYSBsYSBkZSB1bmEgbm9ybWFsLiBTaSBlbCBjYXNvIGZ1ZXJhIGVsIGNvbnRyYXJpbyAocC12YWx1ZSA8IDAuMDUpLCBlbnRvbmNlcyBzZSByZWNoYXphIGxhIEgwIHksIHBvciB0YW50bywgc2UgcmVjaGF6YSBsYSBub3JtYWxpZGFkIGRlIGxhIGRpc3RyaWJ1Y2nDs24gZGUgbGEgdmFyaWFibGUgYW5hbGl6YWRhLgoKIyMjIDEuMi4gRGVzY3JpcGNpw7NuIGJhc2FkYSBlbiBncsOhZmljb3MKCkVsIHVzbyBkZSBtw6l0b2RvcyBncsOhZmljb3MgcGFyYSBsYSBkZXNjcmlwY2nDs24gZGUgbGFzIHZhcmlhYmxlcyBlcyBvdHJhIG1hbmVyYSBtdXkgw7p0aWwgZGUgaWRlbnRpZmljYXIgbGFzIGZvcm1hcyBkZSBkaXN0cmlidWNpw7NuIGRlIGxhcyBtaXNtYXMuClNpIGJpZW4gZXhpc3RlbiBkaXZlcnNvcyB0aXBvcyBkZSBncsOhZmljYXMgcGFyYSBtb3N0cmFyIGRpdmVyc2FzIGNhcmFjdGVyw61zdGljYXMgZGUgbGEgZGlzdHJpYnVjacOzbiBkZSBsYXMgdmFyaWFibGVzLCBlcyBpbXBvcnRhbnRlIHRlbmVyIGVuIGN1ZW50YSBxdWUgbm8gdG9kb3MgbG9zIHRpcG9zIGRlIGdyw6FmaWNhcyBzaXJ2ZW4gcG9yIGlndWFsIHBhcmEgYW5hbGl6YXJsYXMuIERlIG1hbmVyYSBxdWUgZWwgdGlwbyBkZSBtw6l0b2RvIGdyw6FmaWNvIGEgdXRpbGl6YXIgZGVwZW5kZSBkZWwgdGlwbyAobyBlc2NhbGEgZGUgbWVkaWNpw7NuKSBkZSBsYXMgdmFyaWFibGVzLCBhc8OtIGNvbW8gZGVsIGFzcGVjdG8gKGVzdGFkw61zdGljbykgcXVlIHNlIGRlc2VhIHJlc2FsdGFyLgoKIyMjIyAxLjIuMS4gR3LDoWZpY29zIGLDoXNpY29zIHBhcmEgdmFyaWFibGVzIGNhdGVnw7NyaWNhcwpFbiBlbCBjYXNvIGRlbCB1c28gZGUgdmFyaWFibGVzIGRpc2NyZXRhcyAobm9taW5hbGVzIHUgb3JkaW5hbGVzKSwgbGFzIGdyw6FmaWNhcyBtw6FzIHNlbmNpbGxhcyAocGVybyBubyBwb3IgZWxsbyBtZW5vcyDDunRpbGVzKSBzb24gbGFzIHF1ZSBwZXJtaXRlbiBkZXNjcmliaXIgbGEgZnJlY3VlbmNpYSBwYXJhIGNhZGEgdW5vIGRlIHN1cyBhdHJpYnV0b3MuIEVuIGVzdGUgY2FzbywgbGFzIGRvcyBmb3JtYXMgYsOhc2ljYXMgY29uc2lzdGVuIGVuOiBpLiBlbCBncsOhZmljbyBkZSBwaWUgeSBpaS4gbGEgZ3LDoWZpY2EgZGUgYmFycmFzLgoKKyBpLiBMb3MgZ3LDoWZpY29zIGRlIHBpZSBvIHBhc3RlbCBzb24gw7p0aWxlcyBwYXJhIGlkZW50aWZpY2FyIGVsIHRhbWHDsW8gZGUgbG9zIGF0cmlidXRvcyBvIGNhdGVnb3LDrWFzIHF1ZSBpbnRlZ3JhbiBhIHVuYSB2YXJpYWJsZSwgeSBkZSBlc2EgbWFuZXJhIHBlcm1pdGVuIGlkZW50aWZpY2FyIGxhIG1vZGEgZGUgbGEgZGlzdHJpYnVjacOzbi4gRXMgaW1wb3J0YW50ZSBub3RhciBxdWUgbGFzIGdyw6FmaWNhcyBkZSB2YXJpYWJsZXMgY2F0ZWfDs3JpY2FzIHRyYWJhamFuIGEgdHJhdsOpcyBkZSAqdGFibGFzIGRlIGZyZWN1ZW5jaWEqIGRlIGxhcyB2YXJpYWJsZSBkZSBpbnRlcsOpcywgeSBubyB0cmFiYWphbiBkaXJlY3RhbWVudGUgc29icmUgbGEgdmFyaWFibGUgbWlzbWEuCgpEZXNkZSBlbCBzaXN0ZW1hIGJhc2UgZGUgUiBzZSBwdWVkZW4gZGlzZcOxYXIgZGljaG9zIGdyw6FmaWNvczoKCmBgYHtyIGdyYWZfcGllfQpteXRhYmxlIDwtIHRhYmxlKGRhdG9zX2NvdmlkICQgU0VDVE9SX1IpICNjcmVhciBvYmpldG8gdGlwbyB0YWJsYQpsYmxzIDwtIHBhc3RlKG5hbWVzKG15dGFibGUpLCAiXG4iLCBteXRhYmxlLCBzZXA9IiIpICNkZWZpbmlyIGxhcyBldGlxdWV0YXMKcGllKG15dGFibGUsIGxhYmVscyA9IGxibHMsIAogICAgbWFpbiA9ICJTZWN0b3IgZGUgaG9zcGl0YWxpemFjacOzbiBcbiAoY29uIGNhbnRpZGFkZXMgYWJzb2x1dGFzKSIpICNjcmVhciBncsOhZmljYQpgYGAKCisgaWkuIExvcyBncsOhZmljb3MgZGUgYmFycmFzIHNvbiBvdHJhIGZvcm1hIMO6dGlsIHBhcmEgbW9zdHJhciBsYSBkaXN0cmlidWNpw7NuIGRlIHVuYSB2YXJpYWJsZSBkaXNjcmV0YSB5LCBlbiBvY2FzaW9uZXMsIGVzdGEgZXMgbcOhcyDDunRpbCBwYXJhIGlkZW50aWZpY2FyIHkgY29tcGFyYXIgbGFzIGZyZWN1ZW5jaWFzIGRlIGxvcyBkaXN0aW50b3MgYXRyaWJ1dG9zLgpQYXJhIGVsbG8sIGRlc2RlIGVsIHNpc3RlbWEgYmFzZSBkZSBSIGxhIGdyw6FmaWNhIHNlIGNvbnN0cnV5ZSBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOgoKYGBge3IgZ3JhZl9iYXJyYV9iYXNlfQpiYXJwbG90KG15dGFibGUsCiAgICAgICAgbWFpbiA9ICJTZWN0b3IgZGUgSG9zcGl0YWxpemFjacOzbiIsCiAgICAgICAgeGxhYiA9ICJUaXBvIGRlIFNlY3RvciIsCiAgICAgICAgeWxhYiA9ICJDYW50aWRhZCIsCiAgICAgICAgYm9yZGVyID0gInJlZCIsCiAgICAgICAgY29sID0gImJsdWUiLAogICAgICAgIGRlbnNpdHkgPSAxMCkKYGBgCgpPdHJhIGZvcm1hIGRlIGNvbnN0cnVpciBsYXMgZ3LDoWZpY2FzIHByb3ZpZW5lIGRlc2RlIGxhIGxpYnJlcsOtYSAqKmdncGxvdDIqKiwgcXVlIGVzIHBhcnRlIGRlbCBwYXF1ZXRlICoqdGlkeXZlcnNlKiosIHkgcXVlIHBlcm1pdGUgaW50ZWdyYXIgZ3LDoWZpY29zIGNvbiBtZWpvciBjYWxpZGFkIHkgZGlzZcOxby4KRW4gZWwgY2FzbyBkZSBsYSBjb25zdHJ1Y2Npw7NuIGRlIHVuIGdyw6FmaWNvIGRlIGJhcnJhcywgcHJpbWVybyBzZSBkZWJlIGluc3RhbGFyIGxhIGxpYnJlcsOtYSBkZSBnZ3Bsb3QuIFBhcmEgZWxsbyBoYXkgZG9zIG9wY2lvbmVzIGLDoXNpY2FzOiAxLiBpbnN0YWxhciBsYSBsaWJyZXLDrWEgKip0aWR5dmVyc2UqKgoKYGBge3IgbGlicmVyaWFfdGlkeX0KbGlicmFyeSh0aWR5dmVyc2UpICNlc3RhIGxpYnJlcsOtYSBpbmNsdXllIGEgKipnZ3Bsb3QyKioKYGBgCgpPdHJhIG1hbmVyYSBjb25zaXN0ZSBlbiBsbGFtYXIgZGlyZWN0YW1lbnRlIGEgbGEgbGlicmVyw61hIGRlICoqZ2dwbG90MioqLgoKYGBge3IgbGlicmVyaWFfZ2dwbG90fQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKVW5hIHZleiBhYmllcnRhIGRpY2hhIGxpYnJlcsOtYSwgbGEgbWFuZXJhIGRlIGNvbnN0cnVpciB1bmEgZ3LDoWZpY2EgZGUgYmFycmFzIHBhcmEgbW9zdHJhciBsYSBkaXN0cmlidWNpw7NuIGRlIHVuYSB2YXJpYWJsZSBjYXRlZ8OzcmljYSBlcyBsYSBzaWd1aWVudGUgZGVzZGUgbGEgZXN0cnVjdHVyYSBkZWwgc2NyaXB0IGRlIGBnZ3Bsb3QoKcK0ZXM6CgpgYGB7ciBncmFmX2JhcnJhX2dncGxvdH0KZ2dwbG90KGRhdGEgPSBkYXRvc19jb3ZpZCwgYWVzKFNFQ1RPUikpICsgI2VzdG8gcGVybWl0ZSBkaXNlw7FhciBlbCBsaWVuem8KICBnZW9tX2JhcigpICNlc3RvIHBlcm1pdGUgcmVwcmVzZW50YXIgbG9zIGRhdG9zIGNvbW8gYmFycmFzCmBgYAoKQWwgcmV2aXNhciBsYSBncsOhZmljYSwgc2Ugb2JzZXJ2YSBxdWUgc2UgaW5jbHV5ZSBlbCB2YWxvciBkZSA5OSwgcXVlIHNlIGNvcnJlc3BvbmRlIGNvbiBkYXRvcyAicGVyZGlkb3MiLiBFbiBjYXNvIGRlIGRlc2VhciBleGNsdWlybG9zIGRlIGxhIHJlcHJlc2VudGFjacOzbiwgZW50b25jZXMgc2UgcHVlZGVuIHV0aWxpemFyIGxvcyAqcGlwZXMqIHByZXZpYW1lbnRlIGEgbGEgZ3JhZmljYWNpw7NuLCBkZSBsYSBzaWd1aWVudGUgbWFuZXJhOgoKYGBge3J9CmRhdG9zX2NvdmlkICU+JSAjI2FxdcOtIHNlIGRlZmluZW4gZWwgZGF0YSBmcmFtZSBhIHV0aWxpemFyCiAgICBmaWx0ZXIoU0VDVE9SICE9IDk5KSAlPiUgIyNhcXXDrSBzZSBmaWx0cmFuIGxvcyBkYXRvcyBwYXJhIGV4Y2x1aXIgYSBsb3MgY2Fzb3MgZXRpcXVldGFkb3MgY29uICI5OSIgcG9yIHNlciBkYXRvcyBwZXJkaWRvcwogICAgZ2dwbG90KGFlcyhTRUNUT1IpKSArICMjYXF1w60gc2UgZGVmaW5lIGxhIHZhcmlhYmxlIGNvbiBsYSBxdWUgc2UgZXN0YWJsZWNlIGVsIHRhbWHDsW8gZGVsIGxpZW56byBkZSBsYSBncsOhZmljYQogICAgZ2VvbV9iYXIoKSArICMjYXF1w60gc2UgZGVmaW5lIGxhIGZvcm1hIGVuIHF1ZSBzZSByZXByZXNlbnRhcsOhbiBsb3MgZGF0b3MKICBsYWJzKHRpdGxlID0gIlNlY3RvciBkZSBIb3NwaXRhbGl6YWNpw7NuIiwKICAgICAgIHggPSAiVGlwbyBkZSBzZWN0b3IiLCAKICAgICAgIHkgPSAiQ2FudGlkYWQiKQpgYGAKCiMjIyMgMS4yLjIuIEdyw6FmaWNvcyBiw6FzaWNvcyBwYXJhIHZhcmlhYmxlcyBjb250aW51YXMKCkxhIGRpc3RyaWJ1Y2nDs24gZGUgbGFzIHZhcmlhYmxlcyBjb250aW51YXMgcHVlZGUgc2VyIGdyYWZpY2FkYSBkZSB1bmEgZ3JhbiBjYW50aWRhZCBkZSBtYW5lcmFzLiBBcXXDrSBzZSByZXZpc2Fyw6FuIGFsZ3VuYXMgZm9ybWFzIGLDoXNpY2FzOiBpLiBoaXN0b2dyYW1hLCBpaS4gZ3LDoWZpY2EgZGUgZGVuc2lkYWQgeSBpaWkuIGdyw6FmaWNhIGRlIGNhamEgKGJveHBsb3QpLgoKKyBpLiBFbCAqKmhpc3RvZ3JhbWEqKiBwZXJtaXRlIGlkZW50aWZpY2FyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgdW5hIHZhcmlhYmxlIGNvbnRpbnVhIGEgcGFydGlyIGRlIGdyYWZpY2FyIGVsIMOhcmVhIGPDumJpY2EgcXVlIMOpc3RhIG9jdXBhLiBQYXJhIGVsbG8gc2UgaGFjZSB1c28gZGUgYmFycmFzIGNvbnRpZ3VhcyBxdWUgY29udGllbmVuIGEgdW4gY29uanVudG8gZGUgdmFsb3Jlcywgc2Vnw7puIGVsIHRhbWHDsW8gZGVmaW5pZG8gcG9yIGVsIGludmVzdGlnYWRvci4KCkVuIGVsIHByb2dyYW1hIGJhc2UsIGxhIG1hbmVyYSBkZSBjb25zdHJ1aXIgdW4gaGlzdG9ncmFtYSBlcyBsYSBzaWd1aWVudGU6CgpgYGB7cn0KaGlzdChkYXRvc19jb3ZpZCAkIEVEQUQsICMjYXF1w60gc2UgZGVmaW5lIGxhIHZhcmlhYmxlIGEgZ3JhZmljYXIgCiAgICAgbWFpbiA9ICJEaXN0cmlidWNpw7NuIGRlIGxhIGVkYWQiLCAjI2FxdcOtIHNlIGRlZmluZSBlbCB0w610dWxvIGRlIGxhIGdyw6FmaWNhCiAgICAgYnJlYWtzID0gNiwgIyNhcXXDrSBzZSBkZWZpbmUgbGEgY2FudGlkYWQgZGUgYmFycmFzIHBhcmEgYWdydXBhciBkYXRvcywgYSBtYXlvciBjYW50aWRhZCBlcyBtw6FzIGZpbmEgbGEgaW50ZXJwcmV0YWNpw7NuCiAgICAgeGxhYiA9ICJFZGFkIiwgIyNkZWZpbmUgZWwgdMOtdHVsbyBkZWwgZWplIHgKICAgICB5bGFiID0gIkZyZWN1ZW5jaWEiLCAjI2RlZmluZSBlbCB0w610dWxvIGRlbCBlamUgeQogICAgIGNvbCA9ICJncmV5IikgIyNkZWZpbmUgZWwgY29sb3IgZGUgcmVsbGVubyBkZSBsYXMgYmFycmFzCmBgYAoKRW4gZWwgcHJvZ3JhbWEgZ2dwbG90LCBsYSBtYW5lcmEgZGUgY29uc3RydWlyIGVsIGhpc3RvZ3JhbWEgLXVzYW5kbyAqcGlwZXMqLSBlcyBsYSBzaWd1aWVudGU6CgpgYGB7cn0KZGF0b3NfY292aWQgJT4lCiAgZ2dwbG90KGFlcyhFREFEKSkgKyAjbGllbnpvCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDYsIG5hLnJtID0gVFJVRSkgKyAjcmVwcmVzZW50YWNpw7NuIGdlb23DqXRyaWNhCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIGVkYWQiLCAjZXRpcXVldGFzIGRlIGxhIGdyw6FmaWNhCiAgICAgICB4ID0gIkVkYWQiLAogICAgICAgeSA9ICJDYW50aWRhZCIpCmBgYAoKKyBpaS4gTG9zIGdyw6FmaWNvcyBkZSBkZW5zaWRhZCBzb24gb3RyYSBkZSBsYXMgbWFuZXJhcyBwYXJhIGdyYWZpY2FyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgZGljaGFzIHZhcmlhYmxlcy4gRXN0YXMgY29uc2lzdGVuIGVuIGN1cnZhcyBzdWF2aXphZGFzIHF1ZSBzaWd1ZW4gbGEgZm9ybWEgZGUgdW4gaGlzdG9ncmFtYSwgcGVybyB0YW1iacOpbiBwZXJtaXRlIGV2YWx1YXIgbGEgcHJvYmFiaWxpZGFkIGV4aXN0ZW50ZSBkZWJham8gZGUgY2FkYSBwdW50byBkZSBsYSBjdXJ2YS4KCkxhIGNvbnN0cnVjY2nDs24gZGUgdW5hIGdyw6FmaWNhIGRlIGRlbnNpZGFkIGVuIGVsIHNpc3RlbWEgYmFzZSBkZSBSIGVzOgpgYGB7cn0KcGxvdChkZW5zaXR5KGRhdG9zX2NvdmlkICQgRURBRCksCiAgICAgbWFpbiA9ICJEaXN0cmlidWNpw7NuIGRlIGxhIGVkYWQiLAogICAgIHhsYWIgPSAiRWRhZCIsCiAgICAgeWxhYiA9ICJEZW5zaWRhZCIpICNsYSBpbnN0cnVjY2nDs24gZGUgZ3LDoWZpY2FjacOzbiBzZSBlamVjdXRhIGluZGlyZWN0YW1lbnRlIHNvYnJlIGxvcyBkYXRvcywgcHJpbWVybyBzZSBkZWJlIHNvbGljaXRhciBsYSBkZW5zaWRhZCBkZSBsb3MgZGF0b3MgbWlzbW9zCmBgYAoKTGEgY29uc3RydWNjacOzbiBkZSB1biBncsOhZmljbyBkZSBkZW5zaWRhZCBlbiBlbCBzaXN0ZW1hIGdncGxvdCBlczoKCmBgYHtyfQpkYXRvc19jb3ZpZCAlPiUKICBnZ3Bsb3QoYWVzKEVEQUQpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnVjacOzbiBkZSBsYSBlZGFkIiwKICAgICAgIHggPSAiRWRhZCIsCiAgICAgICB5ID0gIlByb2JhYmlsaWRhZCIpCmBgYAoKKyBpaWkuIExhcyBncsOhZmljYXMgZGUgY2FqYXMgY29uIG90cmEgZm9ybWEgZGUgcHJlc2VudGFyIGxhIGRpc3RyaWJ1Y2nDs24gZGUgdW5hIHZhcmlhYmxlIGNvbnRpbnVhLiBFc3RhcyB0aWVuZW4gbGEgY2FyYWN0ZXLDrXN0aWNhIGRlIHJlcHJlc2VudGFyIGRpdmVyc29zIGVzdGFkw61zdGljb3MgZGVzY3JpcHRpdm9zIGRlbnRybyBkZWwgbWlzbW8gZ3LDoWZpY28sIGNvbW8gbG8gc29uOiBlbCByYW5nbyBpbnRlcmN1YXJ0aWwgKFEzIC0gUTEpLCBsYSBwb3NpY2nDs24gZGUgbGEgbWVkaWFuYSwgbGEgdWJpY2FjacOzbiBkZSB2YWxvcmVzIGF0w61waWNvcyAob3V0bGllcnMpLCBlbCBzZXNnbyBkZSBsYSBkaXN0cmlidWNpw7NuLgoKTGEgbWFuZXJhIGRlIGVsYWJvcmFyIHVuIGRpYWdyYW1hIGRlIGNhamEgZW4gZWwgc2lzdGVtYSBiYXNlIGVzOgoKYGBge3J9CmJveHBsb3QoZGF0b3NfY292aWQgJCBFREFELAogICAgICAgIG1haW4gPSAiRGlzdHJpYnVjacOzbiBkZSBsYSBlZGFkIiwKICAgICAgICB4bGFiID0gIkVkYWQiLAogICAgICAgIHlsYWIgPSAiQ2FudGlkYWQiKQpgYGAKCkVuIGVsIGNhc28gZGUgbGEgbGlicmVyw61hIGdncGxvdCwgbGEgbWFuZXJhIHBhcmEgY29uc3RydWlyIHVuIGRpYWdyYW1hIGRlIGJveHBsb3QsIHkgbWVkaWFudGUgcGlwZXMgZXM6CgpgYGB7cn0KZGF0b3NfY292aWQgJT4lCiAgZ2dwbG90KGFlcyh5ID0gRURBRCkpICsKICBnZW9tX2JveHBsb3QobmEucm0gPSBUUlVFKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIGxhIGVkYWQiLAogICAgICAgeCA9ICJFZGFkIiwgCiAgICAgICB5ID0gIkNhbnRpZGFkIikKYGBgCgojIyAyLiBFamVyY2ljaW8KMS4gQ29uc3RydXllIHVuYSBtdWVzdHJhIGRlIDIwMDAgY2Fzb3MgYSBwYXJ0aXIgZGUgbGEgbWF0cml6IGRlIGRhdG9zIHNvYnJlIGNvdmlkLTE5LgoyLiBDYWxjdWxhIGxhIG1vZGEgcGFyYSBsYSB2YXJpYWJsZSBkZSBjYXNvcyBpbmZlY3RhZG8gZGUgY292aWQtMTkgKHZhcmlhYmxlOiBSRVNVTFRBRE8pLCBleGNsdXllbmRvIGxvcyBjYXNvcyAicGVyZGlkbyIgKE5BKS4KMy4gQ2FsY3VsYSBsYSBtZWRpYSB5IGxhIGRlc3ZpYWNpw7NuIGVzdMOhbmRhciBwYXJhIGxhIHZhcmlhYmxlIEVEQUQuCjQuIEdyYWZpY2EgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSB2YXJpYWJsZSBSRVNVTFRBRE8uCjUuIEdyYWZpY2EgbGEgZGlzdHJpYnVjacOzbiBkZSBsYSB2YXJpYWJsZSBFREFELg==