Diagramas de Barras

El diagrama de barras (Bar Chart) es un gráfico estadístico que nos permite representar la distribución de frecuencias de variables cualitativas y cuantitativas discretas; nuestro objetivo es pasar del lápiz y papel al uso de los lenguajes de programación R version 4.2.1 (2022-06-23 ucrt)(R Core Team, 2022) y Python 3.9.7(Van Rossum & Drake Jr, 1995), recomendamos la lectura del libro El Arte de Programar en R(Santana Sepúlveda et al., 2014); compartimos la siguiente imagen como referencia.

Data Set - mtcars

mtcars es un data set que ya viene precargado al momento de instalar el lenguaje de programación R en nuestro sistema, haremos uso de dicho data set para la creación de distintos diagramas de barras, de las 11 variables y 32 observaciones que lo componen nos enfocaremos en las variables cyl (cilindro) y gear (engranajes) como se muestra a continuación.

mtcar

summary(mtcars)
##       mpg             cyl             disp             hp       
##  Min.   :10.40   Min.   :4.000   Min.   : 71.1   Min.   : 52.0  
##  1st Qu.:15.43   1st Qu.:4.000   1st Qu.:120.8   1st Qu.: 96.5  
##  Median :19.20   Median :6.000   Median :196.3   Median :123.0  
##  Mean   :20.09   Mean   :6.188   Mean   :230.7   Mean   :146.7  
##  3rd Qu.:22.80   3rd Qu.:8.000   3rd Qu.:326.0   3rd Qu.:180.0  
##  Max.   :33.90   Max.   :8.000   Max.   :472.0   Max.   :335.0  
##       drat             wt             qsec             vs        
##  Min.   :2.760   Min.   :1.513   Min.   :14.50   Min.   :0.0000  
##  1st Qu.:3.080   1st Qu.:2.581   1st Qu.:16.89   1st Qu.:0.0000  
##  Median :3.695   Median :3.325   Median :17.71   Median :0.0000  
##  Mean   :3.597   Mean   :3.217   Mean   :17.85   Mean   :0.4375  
##  3rd Qu.:3.920   3rd Qu.:3.610   3rd Qu.:18.90   3rd Qu.:1.0000  
##  Max.   :4.930   Max.   :5.424   Max.   :22.90   Max.   :1.0000  
##        am              gear            carb      
##  Min.   :0.0000   Min.   :3.000   Min.   :1.000  
##  1st Qu.:0.0000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :0.0000   Median :4.000   Median :2.000  
##  Mean   :0.4062   Mean   :3.688   Mean   :2.812  
##  3rd Qu.:1.0000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :1.0000   Max.   :5.000   Max.   :8.000

var_cyl

summary(mtcars$cyl)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   4.000   4.000   6.000   6.188   8.000   8.000
cyl_table <- sqldf("select cyl,count(cyl) as cantidad from mtcars group by cyl")

cyl_table
##   cyl cantidad
## 1   4       11
## 2   6        7
## 3   8       14

var_gear

summary(mtcars$gear)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.000   3.000   4.000   3.688   4.000   5.000
gear_table <- sqldf("select gear,count(gear) as cantidad from mtcars group by gear")

gear_table
##   gear cantidad
## 1    3       15
## 2    4       12
## 3    5        5

var_carb

summary(mtcars$carb)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   2.000   2.812   4.000   8.000
carb_table <- sqldf("select carb,count(carb) as cantidad from mtcars group by carb")

carb_table
##   carb cantidad
## 1    1        7
## 2    2       10
## 3    3        3
## 4    4       10
## 5    6        1
## 6    8        1

Bar Chart - barplot()

La función barplot() nos permite crear diagramas de barras (Bar Charts) en el lenguaje de programación R, utilizaremos la variable cyl (cilindros) para crear el gráfico estadístico respectivo, como se muestra en la siguiente imagen.

x <- table(mtcars$cyl)

colores <- c("orange","blue","purple")

barplot(x,xlab="Cilindros",ylab="Frecuencias",main="Número de Cilindros",col=colores)

Bar Chart - ggplot2

ggplot2(Wickham, 2016) es un paquete del lenguaje de programación que nos permite crear gráficos estadísticos de gran calidad, haremos uso de la variable cyl (cilindros) para la creación del gráfico estadístico respectivo, como se muestra a continuación.

ggplot(mtcars,aes(cyl)) + geom_bar(fill=colores) + labs(x="Cillindros",y="Frecuencias",title="Número de Cilindros") + theme_dark()

Bar Chart - Lattice

Lattice(Sarkar, 2008) es un paquete del lenguaje de programación R, que nos permite crear gráficos estadísticos de muy buena calidad, nos enfocaremos en la variable cyl (cilindros) para la creación del gráfico estadístico respectivo, como se muestra a continuación.

barchart(x,xlab="Cilindros",ylab="Frecuencias",main="Número de Cilindros",col=colores,horizontal=FALSE)

mtcars - cyl & gear

A continuación, mostramos como unir dos diagramas de barras (Bar Charts) en un solo gráfico, tomando como base el data set mtcars, así como sus variables cyl (cilindros) y gear (engranajes).

y <- table(mtcars$gear)

par(mfrow=c(1,2))

barplot(x,xlab="Cilindros",ylab="Frecuencias",main="Número de Cilindros",col=colores)

barplot(y,xlab="Engranajes",ylab="Frecuencias",main="Número de Engranajes",col=rainbow(3))

gapminder - Bar Chart

gapminder(Bryan, 2017) es un paquete del lenguaje de programación R, que contiene data proporcionada por gapminder, que contiene un data set de 142 países; conformado por información de expectativas de vida;PBI per capita y población cada cinco años entre 1952 y 2007.

grafico_edad_promedio <- gapminder %>%
  filter(year == 2007) %>%
  group_by(continent) %>%
  summarise(promedio = mean(lifeExp))

ggplot(grafico_edad_promedio, aes(x = continent, y = promedio, fill = continent)) +
  geom_col() +
  labs(title = "Life expectancy (mean) by continent in 2007", 
       x = NULL, 
       y = "Life Expectancy")

Bar Charts - Matplotlib

Matplotlib(Hunter, 2007) es una librería del lenguaje de programación Python, que nos permite crear gráficos estadísticos de gran calidad, RMarkdown(Allaire et al., 2022) nos permite trabajar con otros lenguajes de programación tales como C++, SQL, Julia, entre muchos otros; a continuación mostramos un diagrama de barras (Bar Chart) creado con Matplotlib.


eje_x = ['Python', 'R', 'Node.js', 'PHP']
 

eje_y = [50,20,35,47]
 

plt.bar(eje_x, eje_y)
 
plt.ylabel('Cantidad de usuarios')
 

plt.xlabel('Lenguajes de programación')
 

plt.title('Usuarios de lenguajes de programación')
 

plt.show()

Bar Charts - Seaborn

Seaborn(Waskom et al., 2017) es una librería de Python que nos permite crear gráficos estadísticos de gran calidad, fue creada tomando como base Matplotlib.



eje_x = [4,6,8]

eje_y = [11,7,14]

sns.barplot(x=eje_x,y=eje_y)

plt.title("Número de cilindros")

plt.xlabel("Cilindros")

plt.ylabel("Frecuencias")

plt.show()

YouTube - Tutorial

Compartimos el siguiente tutorial tomado de la plataforma YouTube que muestra como crear diagramas de barras (Bar Charts) en el lenguaje de programación Python, utilizando las librerías Matplotlib y Seaborn.

embed_url("https://www.youtube.com/watch?v=EkxRj02iaLk&t=6s") %>% 
  use_align("center")

Referencias Bibliográficas

Allaire, J., Xie, Y., McPherson, J., Luraschi, J., Ushey, K., Atkins, A., Wickham, H., Cheng, J., Chang, W., & Iannone, R. (2022). Rmarkdown: Dynamic documents for r. https://github.com/rstudio/rmarkdown
Bryan, J. (2017). Gapminder: Data from gapminder. https://CRAN.R-project.org/package=gapminder
Hunter, J. D. (2007). Matplotlib: A 2D graphics environment. Computing in Science & Engineering, 9(3), 90–95. https://doi.org/10.1109/MCSE.2007.55
R Core Team. (2022). R: A language and environment for statistical computing. R Foundation for Statistical Computing. https://www.R-project.org/
Santana Sepúlveda, S., Mateos Farfán, E., et al. (2014). El arte de programar en r: Un lenguaje para la estadı́stica. México: Instituto Mexicano de Tecnologı́a del Agua. UNESCO. Comité Nacional ….
Sarkar, D. (2008). Lattice: Multivariate data visualization with r. Springer. http://lmdvr.r-forge.r-project.org
Van Rossum, G., & Drake Jr, F. L. (1995). Python reference manual. Centrum voor Wiskunde en Informatica Amsterdam.
Waskom, M., Botvinnik, O., O’Kane, D., Hobson, P., Lukauskas, S., Gemperline, D. C., Augspurger, T., Halchenko, Y., Cole, J. B., Warmenhoven, J., Ruiter, J. de, Pye, C., Hoyer, S., Vanderplas, J., Villalba, S., Kunter, G., Quintero, E., Bachant, P., Martin, M., … Qalieh, A. (2017). Mwaskom/seaborn: v0.8.1 (september 2017) (Version v0.8.1) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.883859
Wickham, H. (2016). ggplot2: Elegant graphics for data analysis. Springer-Verlag New York. https://ggplot2.tidyverse.org
LS0tDQp0aXRsZTogIkJhciBDaGFydHMgLSBSIg0KYXV0aG9yOiAiUmVuem8gQ8OhY2VyZXMgUm9zc2kiDQpkYXRlOiAiMjAyMi8xMC8xMCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IGZsYXRseQ0KICBwZGZfZG9jdW1lbnQ6DQogICAgbGF0ZXhfZW5naW5lOiB4ZWxhdGV4DQogICAgdG9jOiB5ZXMNCnN1YnRpdGxlOiAiYmFycGxvdCgpIC0gZ2dwbG90MiAtIGxhdHRpY2UiDQpiaWJsaW9ncmFwaHk6IGJpYmxpb18wMDIuYmliDQpjc2w6IGFwYS5jc2wNCmxpbmstY2l0YXRpb25zOiB5ZXMNCmFsd2F5c19hbGxvd19odG1sOiB0cnVlDQotLS0NCg0KPCEtLSBBw7FhZGlyIGNvbWVudGFyaW9zIGEgbnVlc3RybyBkb2N1bWVudG8gUk1hcmtkb3duIC0tPg0KDQpgYGB7ciBzZXR1cCxpbmNsdWRlPUZBTFNFfQ0KDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmxpYnJhcnkobGF0dGljZSkNCg0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCmxpYnJhcnkoZ2FwbWluZGVyKQ0KDQpsaWJyYXJ5KHJldGljdWxhdGUpDQoNCmxpYnJhcnkoc3FsZGYpDQoNCmxpYnJhcnkodmVtYmVkcikNCg0KDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvPVRSVUUpDQpgYGANCg0KDQpgYGB7cHl0aG9uLGluY2x1ZGU9RkFMU0V9DQoNCmZyb20gcGxhdGZvcm0gaW1wb3J0IHB5dGhvbl92ZXJzaW9uDQoNCnZlcnNpb249cHl0aG9uX3ZlcnNpb24oKQ0KDQppbXBvcnQgbWF0cGxvdGxpYi5weXBsb3QgYXMgcGx0DQoNCmltcG9ydCBzZWFib3JuIGFzIHNucw0KDQpgYGANCg0KDQojIyBEaWFncmFtYXMgZGUgQmFycmFzIA0KDQpFbCBkaWFncmFtYSBkZSBiYXJyYXMgKCoqQmFyIENoYXJ0KiopIGVzIHVuIGdyw6FmaWNvIGVzdGFkw61zdGljbyBxdWUgbm9zIHBlcm1pdGUgcmVwcmVzZW50YXIgbGEgZGlzdHJpYnVjacOzbiBkZSBmcmVjdWVuY2lhcyBkZSB2YXJpYWJsZXMgY3VhbGl0YXRpdmFzIHkgY3VhbnRpdGF0aXZhcyBkaXNjcmV0YXM7IG51ZXN0cm8gb2JqZXRpdm8gZXMgcGFzYXIgZGVsIGzDoXBpeiB5IHBhcGVsIGFsIHVzbyBkZSBsb3MgbGVuZ3VhamVzIGRlIHByb2dyYW1hY2nDs24gYHIgUi52ZXJzaW9uLnN0cmluZ2BbQFJwcm9ncmFtbWluZ10geSBQeXRob24gYHIgcHkkdmVyc2lvbmBbQHZhbjE5OTVweXRob25dLCByZWNvbWVuZGFtb3MgbGEgbGVjdHVyYSBkZWwgbGlicm8gRWwgQXJ0ZSBkZSBQcm9ncmFtYXIgZW4gUltAc2FudGFuYTIwMTRhcnRlXTsgY29tcGFydGltb3MgbGEgc2lndWllbnRlIGltYWdlbiBjb21vIHJlZmVyZW5jaWEuDQoNCg0KPGNlbnRlcj4NCg0KDQohW10oZGlhZ3JhbWFfYmFycmFzX2FtYW5vLmpwZyl7d2lkdGg9NDAwfQ0KDQoNCjwvY2VudGVyPg0KDQoNCg0KIyMgRGF0YSBTZXQgLSBtdGNhcnMgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KKiptdGNhcnMqKiBlcyB1biBkYXRhIHNldCBxdWUgeWEgdmllbmUgcHJlY2FyZ2FkbyBhbCBtb21lbnRvIGRlIGluc3RhbGFyIGVsICoqbGVuZ3VhamUgZGUgcHJvZ3JhbWFjacOzbiBSKiogZW4gbnVlc3RybyBzaXN0ZW1hLCBoYXJlbW9zIHVzbyBkZSBkaWNobyBkYXRhIHNldCBwYXJhIGxhIGNyZWFjacOzbiBkZSBkaXN0aW50b3MgZGlhZ3JhbWFzIGRlIGJhcnJhcywgZGUgbGFzIDExIHZhcmlhYmxlcyB5IDMyIG9ic2VydmFjaW9uZXMgcXVlIGxvIGNvbXBvbmVuIG5vcyBlbmZvY2FyZW1vcyBlbiBsYXMgdmFyaWFibGVzICoqY3lsKiogKGNpbGluZHJvKSB5ICoqZ2VhcioqIChlbmdyYW5hamVzKSBjb21vIHNlIG11ZXN0cmEgYSBjb250aW51YWNpw7NuLg0KDQoNCiMjIyBtdGNhcg0KDQpgYGB7cn0NCg0Kc3VtbWFyeShtdGNhcnMpDQoNCmBgYA0KDQoNCg0KDQojIyMgdmFyX2N5bA0KDQpgYGB7cn0NCg0Kc3VtbWFyeShtdGNhcnMkY3lsKQ0KDQpjeWxfdGFibGUgPC0gc3FsZGYoInNlbGVjdCBjeWwsY291bnQoY3lsKSBhcyBjYW50aWRhZCBmcm9tIG10Y2FycyBncm91cCBieSBjeWwiKQ0KDQpjeWxfdGFibGUNCg0KYGBgDQoNCg0KDQojIyMgdmFyX2dlYXINCg0KYGBge3J9DQoNCnN1bW1hcnkobXRjYXJzJGdlYXIpDQoNCmdlYXJfdGFibGUgPC0gc3FsZGYoInNlbGVjdCBnZWFyLGNvdW50KGdlYXIpIGFzIGNhbnRpZGFkIGZyb20gbXRjYXJzIGdyb3VwIGJ5IGdlYXIiKQ0KDQpnZWFyX3RhYmxlDQoNCmBgYA0KDQoNCg0KIyMjIHZhcl9jYXJiDQoNCmBgYHtyfQ0Kc3VtbWFyeShtdGNhcnMkY2FyYikNCg0KY2FyYl90YWJsZSA8LSBzcWxkZigic2VsZWN0IGNhcmIsY291bnQoY2FyYikgYXMgY2FudGlkYWQgZnJvbSBtdGNhcnMgZ3JvdXAgYnkgY2FyYiIpDQoNCmNhcmJfdGFibGUNCg0KYGBgDQoNCg0KIyMgQmFyIENoYXJ0IC0gYmFycGxvdCgpDQoNCkxhIGZ1bmNpw7NuICBgYmFycGxvdCgpYCBub3MgcGVybWl0ZSBjcmVhciBkaWFncmFtYXMgZGUgYmFycmFzICgqKkJhciBDaGFydHMqKikgZW4gZWwgbGVuZ3VhamUgZGUgcHJvZ3JhbWFjacOzbiBSLCB1dGlsaXphcmVtb3MgbGEgdmFyaWFibGUgY3lsICgqKmNpbGluZHJvcyoqKSBwYXJhIGNyZWFyIGVsIGdyw6FmaWNvIGVzdGFkw61zdGljbyByZXNwZWN0aXZvLCBjb21vIHNlIG11ZXN0cmEgZW4gbGEgc2lndWllbnRlIGltYWdlbi4NCg0KDQpgYGB7ciBiYXJwbG90LGZpZy5hbGlnbj0nY2VudGVyJ30NCg0KeCA8LSB0YWJsZShtdGNhcnMkY3lsKQ0KDQpjb2xvcmVzIDwtIGMoIm9yYW5nZSIsImJsdWUiLCJwdXJwbGUiKQ0KDQpiYXJwbG90KHgseGxhYj0iQ2lsaW5kcm9zIix5bGFiPSJGcmVjdWVuY2lhcyIsbWFpbj0iTsO6bWVybyBkZSBDaWxpbmRyb3MiLGNvbD1jb2xvcmVzKQ0KDQoNCmBgYA0KDQoNCiMjIEJhciBDaGFydCAtIGdncGxvdDINCg0KKipnZ3Bsb3QyKipbQGdncGxvdDJdIGVzIHVuIHBhcXVldGUgZGVsIGxlbmd1YWplIGRlIHByb2dyYW1hY2nDs24gcXVlIG5vcyBwZXJtaXRlIGNyZWFyIGdyw6FmaWNvcyBlc3RhZMOtc3RpY29zIGRlIGdyYW4gY2FsaWRhZCwgaGFyZW1vcyB1c28gZGUgbGEgdmFyaWFibGUgY3lsICgqKmNpbGluZHJvcyoqKSBwYXJhIGxhIGNyZWFjacOzbiBkZWwgZ3LDoWZpY28gZXN0YWTDrXN0aWNvIHJlc3BlY3Rpdm8sIGNvbW8gc2UgbXVlc3RyYSBhIGNvbnRpbnVhY2nDs24uDQoNCmBgYHtyIGdncGxvdDIsZmlnLmFsaWduPSdjZW50ZXInfQ0KDQpnZ3Bsb3QobXRjYXJzLGFlcyhjeWwpKSArIGdlb21fYmFyKGZpbGw9Y29sb3JlcykgKyBsYWJzKHg9IkNpbGxpbmRyb3MiLHk9IkZyZWN1ZW5jaWFzIix0aXRsZT0iTsO6bWVybyBkZSBDaWxpbmRyb3MiKSArIHRoZW1lX2RhcmsoKQ0KDQoNCmBgYA0KDQoNCg0KIyMgQmFyIENoYXJ0IC0gTGF0dGljZQ0KDQoqKkxhdHRpY2UqKltAbGF0dGljZV0gZXMgdW4gcGFxdWV0ZSBkZWwgbGVuZ3VhamUgZGUgcHJvZ3JhbWFjacOzbiBSLCBxdWUgbm9zIHBlcm1pdGUgY3JlYXIgZ3LDoWZpY29zIGVzdGFkw61zdGljb3MgZGUgbXV5IGJ1ZW5hIGNhbGlkYWQsIG5vcyBlbmZvY2FyZW1vcyBlbiBsYSB2YXJpYWJsZSBjeWwgKCoqY2lsaW5kcm9zKiopIHBhcmEgbGEgY3JlYWNpw7NuIGRlbCBncsOhZmljbyBlc3RhZMOtc3RpY28gcmVzcGVjdGl2bywgY29tbyBzZSBtdWVzdHJhIGEgY29udGludWFjacOzbi4NCg0KDQpgYGB7ciBsYXR0aWNlLGZpZy5hbGlnbj0nY2VudGVyJ30NCg0KYmFyY2hhcnQoeCx4bGFiPSJDaWxpbmRyb3MiLHlsYWI9IkZyZWN1ZW5jaWFzIixtYWluPSJOw7ptZXJvIGRlIENpbGluZHJvcyIsY29sPWNvbG9yZXMsaG9yaXpvbnRhbD1GQUxTRSkNCg0KDQpgYGANCg0KDQojIyBtdGNhcnMgLSBjeWwgJiBnZWFyDQoNCkEgY29udGludWFjacOzbiwgbW9zdHJhbW9zIGNvbW8gdW5pciBkb3MgZGlhZ3JhbWFzIGRlIGJhcnJhcyAoKipCYXIgQ2hhcnRzKiopIGVuIHVuIHNvbG8gZ3LDoWZpY28sIHRvbWFuZG8gY29tbyBiYXNlIGVsIGRhdGEgc2V0ICoqbXRjYXJzKiosIGFzw60gY29tbyBzdXMgdmFyaWFibGVzICoqY3lsKiogKGNpbGluZHJvcykgeSAqKmdlYXIqKiAoZW5ncmFuYWplcykuDQoNCmBgYHtyIGN5bF9nZWFyLGZpZy5hbGlnbj0nY2VudGVyJ30NCg0KeSA8LSB0YWJsZShtdGNhcnMkZ2VhcikNCg0KcGFyKG1mcm93PWMoMSwyKSkNCg0KYmFycGxvdCh4LHhsYWI9IkNpbGluZHJvcyIseWxhYj0iRnJlY3VlbmNpYXMiLG1haW49Ik7Dum1lcm8gZGUgQ2lsaW5kcm9zIixjb2w9Y29sb3JlcykNCg0KYmFycGxvdCh5LHhsYWI9IkVuZ3JhbmFqZXMiLHlsYWI9IkZyZWN1ZW5jaWFzIixtYWluPSJOw7ptZXJvIGRlIEVuZ3JhbmFqZXMiLGNvbD1yYWluYm93KDMpKQ0KDQoNCg0KYGBgDQoNCg0KDQojIyBnYXBtaW5kZXIgLSBCYXIgQ2hhcnQNCg0KDQoqKmdhcG1pbmRlcioqW0BnYXBtaW5kZXJdIGVzIHVuIHBhcXVldGUgZGVsIGxlbmd1YWplIGRlIHByb2dyYW1hY2nDs24gUiwgcXVlIGNvbnRpZW5lIGRhdGEgcHJvcG9yY2lvbmFkYSBwb3IgW2dhcG1pbmRlcl0oaHR0cDovL2dhcG1pbmRlci5vcmcpe3RhcmdldD1fYmxhbmt9LCBxdWUgY29udGllbmUgdW4gZGF0YSBzZXQgZGUgMTQyIHBhw61zZXM7IGNvbmZvcm1hZG8gcG9yIGluZm9ybWFjacOzbiBkZSBleHBlY3RhdGl2YXMgZGUgdmlkYTtQQkkgcGVyIGNhcGl0YSB5IHBvYmxhY2nDs24gY2FkYSBjaW5jbyBhw7FvcyBlbnRyZSAxOTUyIHkgMjAwNy4NCg0KYGBge3IgZ2FwbWluZGVyLGZpZy5hbGlnbj0nY2VudGVyJ30NCg0KZ3JhZmljb19lZGFkX3Byb21lZGlvIDwtIGdhcG1pbmRlciAlPiUNCiAgZmlsdGVyKHllYXIgPT0gMjAwNykgJT4lDQogIGdyb3VwX2J5KGNvbnRpbmVudCkgJT4lDQogIHN1bW1hcmlzZShwcm9tZWRpbyA9IG1lYW4obGlmZUV4cCkpDQoNCmdncGxvdChncmFmaWNvX2VkYWRfcHJvbWVkaW8sIGFlcyh4ID0gY29udGluZW50LCB5ID0gcHJvbWVkaW8sIGZpbGwgPSBjb250aW5lbnQpKSArDQogIGdlb21fY29sKCkgKw0KICBsYWJzKHRpdGxlID0gIkxpZmUgZXhwZWN0YW5jeSAobWVhbikgYnkgY29udGluZW50IGluIDIwMDciLCANCiAgICAgICB4ID0gTlVMTCwgDQogICAgICAgeSA9ICJMaWZlIEV4cGVjdGFuY3kiKQ0KDQpgYGANCg0KDQojIyBCYXIgQ2hhcnRzIC0gTWF0cGxvdGxpYg0KDQoqKk1hdHBsb3RsaWIqKltASHVudGVyOjIwMDddIGVzIHVuYSBsaWJyZXLDrWEgZGVsIGxlbmd1YWplIGRlIHByb2dyYW1hY2nDs24gUHl0aG9uLCBxdWUgbm9zIHBlcm1pdGUgY3JlYXIgZ3LDoWZpY29zIGVzdGFkw61zdGljb3MgZGUgZ3JhbiBjYWxpZGFkLCAqKlJNYXJrZG93bioqW0BSTWFya2Rvd25dIG5vcyBwZXJtaXRlIHRyYWJhamFyIGNvbiBvdHJvcyBsZW5ndWFqZXMgZGUgcHJvZ3JhbWFjacOzbiB0YWxlcyBjb21vICoqQysrLCBTUUwsIEp1bGlhKiosIGVudHJlIG11Y2hvcyBvdHJvczsgYSBjb250aW51YWNpw7NuIG1vc3RyYW1vcyB1biBkaWFncmFtYSBkZSBiYXJyYXMgKCoqQmFyIENoYXJ0KiopIGNyZWFkbyBjb24gTWF0cGxvdGxpYi4NCg0KYGBge3B5dGhvbixyZXN1bHRzPSdoaWRlJyxjb2xsYXBzZT1UUlVFLGZpZy5hbGlnbj0iY2VudGVyIn0NCg0KZWplX3ggPSBbJ1B5dGhvbicsICdSJywgJ05vZGUuanMnLCAnUEhQJ10NCiANCg0KZWplX3kgPSBbNTAsMjAsMzUsNDddDQogDQoNCnBsdC5iYXIoZWplX3gsIGVqZV95KQ0KIA0KDQpwbHQueWxhYmVsKCdDYW50aWRhZCBkZSB1c3VhcmlvcycpDQogDQoNCnBsdC54bGFiZWwoJ0xlbmd1YWplcyBkZSBwcm9ncmFtYWNpw7NuJykNCiANCg0KcGx0LnRpdGxlKCdVc3VhcmlvcyBkZSBsZW5ndWFqZXMgZGUgcHJvZ3JhbWFjacOzbicpDQogDQoNCnBsdC5zaG93KCkNCg0KDQpgYGANCg0KDQoNCiMjIEJhciBDaGFydHMgLSBTZWFib3JuDQoNCioqU2VhYm9ybioqW0BtaWNoYWVsX3dhc2tvbV8yMDE3Xzg4Mzg1OV0gZXMgdW5hIGxpYnJlcsOtYSBkZSBQeXRob24gcXVlIG5vcyBwZXJtaXRlIGNyZWFyIGdyw6FmaWNvcyBlc3RhZMOtc3RpY29zIGRlIGdyYW4gY2FsaWRhZCwgZnVlIGNyZWFkYSB0b21hbmRvIGNvbW8gYmFzZSAqKk1hdHBsb3RsaWIqKi4NCg0KYGBge3B5dGhvbiBzZWFib3JuLGZpZy5hbGlnbj0iY2VudGVyIixyZXN1bHRzPSdoaWRlJyxjb2xsYXBzZT1UUlVFfQ0KDQoNCmVqZV94ID0gWzQsNiw4XQ0KDQplamVfeSA9IFsxMSw3LDE0XQ0KDQpzbnMuYmFycGxvdCh4PWVqZV94LHk9ZWplX3kpDQoNCnBsdC50aXRsZSgiTsO6bWVybyBkZSBjaWxpbmRyb3MiKQ0KDQpwbHQueGxhYmVsKCJDaWxpbmRyb3MiKQ0KDQpwbHQueWxhYmVsKCJGcmVjdWVuY2lhcyIpDQoNCnBsdC5zaG93KCkNCg0KDQpgYGANCg0KDQoNCiMjIFlvdVR1YmUgLSBUdXRvcmlhbA0KDQpDb21wYXJ0aW1vcyBlbCBzaWd1aWVudGUgdHV0b3JpYWwgdG9tYWRvIGRlIGxhIHBsYXRhZm9ybWEgKipZb3VUdWJlKiogcXVlIG11ZXN0cmEgY29tbyBjcmVhciBkaWFncmFtYXMgZGUgYmFycmFzICgqKkJhciBDaGFydHMqKikgZW4gZWwgbGVuZ3VhamUgZGUgcHJvZ3JhbWFjacOzbiBQeXRob24sIHV0aWxpemFuZG8gbGFzIGxpYnJlcsOtYXMgKipNYXRwbG90bGliKiogeSAqKlNlYWJvcm4qKi4NCg0KYGBge3IgdmVtYmVkcn0NCmVtYmVkX3VybCgiaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1Fa3hSajAyaWFMayZ0PTZzIikgJT4lIA0KICB1c2VfYWxpZ24oImNlbnRlciIpDQoNCmBgYA0KDQoNCiMjIFJlZmVyZW5jaWFzIEJpYmxpb2dyw6FmaWNhcw0KDQoNCg0KDQoNCg0KPGRpdiBjbGFzcz0idG9jaWZ5LWV4dGVuZC1wYWdlIiBkYXRhLXVuaXF1ZT0idG9jaWZ5LWV4dGVuZC1wYWdlIiBzdHlsZT0iaGVpZ2h0OiAwOyI+PC9kaXY+DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==