packages

if(!require(tidyverse)){install.packages("tidyverse")}
if(!require(googlesheets4)){install.packages("googlesheets4")}
if(!require(googledrive)){install.packages("googledrive")}
if(!require(vioplot)){install.packages("vioplot")}
##
library(vioplot)
library(tidyverse)
library(googlesheets4)
library(googledrive)

Reading Data

ss <- "https://docs.google.com/spreadsheets/d/180rJU7y7aXlAqwSLtKdrlkLgFjwCwI76l6Uf7kii31U/edit?usp=sharing"
hoja = 1
rango = "C3:I48"
datos <- read_sheet(ss,
                sheet=hoja,
                range= rango,
                col_names = TRUE,
                col_types = "c")

Tipos de variable: Leyendo las columnas

str(datos)
tibble [45 × 7] (S3: tbl_df/tbl/data.frame)
 $ altura : chr [1:45] "165" "173" "170" "177" ...
 $ lbs    : chr [1:45] "175" "140" "130" "175" ...
 $ calzado: chr [1:45] "39" "39" "43" "40" ...
 $ mano   : chr [1:45] "18" "16" "17.5" "19.2" ...
 $ brazo  : chr [1:45] "25" "24" "28" "29.1" ...
 $ cuello : chr [1:45] "36" "33" "32" "40.2" ...
 $ sex    : chr [1:45] "Hombre" "Mujer" "Hombre" "Hombre" ...
datos[,c(1:6)] <- datos[,c(1:6)] %>%
  sapply(as.numeric)

datos <-  datos %>%
  mutate_if(is.character, as.factor)

str(datos)
tibble [45 × 7] (S3: tbl_df/tbl/data.frame)
 $ altura : num [1:45] 165 173 170 177 167 157 152 172 165 165 ...
 $ lbs    : num [1:45] 175 140 130 175 146 110 125 142 220 140 ...
 $ calzado: num [1:45] 39 39 43 40 40 36 37 39.5 41.5 39 ...
 $ mano   : num [1:45] 18 16 17.5 19.2 17.5 17 16 18 19 17 ...
 $ brazo  : num [1:45] 25 24 28 29.1 26 23 22 26 26 25 ...
 $ cuello : num [1:45] 36 33 32 40.2 35 35 35 39 44 40 ...
 $ sex    : Factor w/ 2 levels "Hombre","Mujer": 1 2 1 1 1 2 2 1 1 1 ...

Exploración gráfica

Aquí utilizamos el paquete básico (“base”) de R. Más adelante veremos más argumentos y otros comandos de otros paquetes (e.g., “ggplot2”) para modificar etiquetas, títulos, etc.

prom.altura <- mean(datos$altura) #promedio
mediana.altura <- median(datos$altura) #mediana
desv.estandar <- sd(datos$altura)
prom.altura
[1] 168.5889
desv.estandar
[1] 7.710153
par(mfrow=c(1,2)) #parámetros para mostrar figuras en dos columnas
plot(datos$altura, pch= 19) #el color según el sexo del individuo
abline(h= prom.altura, lty= 4, lwd= 2, col= "red3") #el promedio en rojo
#abline(h= prom.altura + desv.estandar, lty= 4, lwd=1) #promedio + desviación típica 
#abline(h= prom.altura - desv.estandar, lty= 4, lwd=1) #promedio - desviación típica 
#Histograma
hist(datos$altura, breaks = 10, labels = TRUE, 
     ylim= c(0,14)) #distribución de frecuencias
abline(v= prom.altura, lty= 4, lwd=2, col= "red3") #el promedio en rojo
abline(v= mediana.altura, lty= 2, lwd=2) #le mediana en negro

#abline(v= prom.altura + desv.estandar, lty= 4, lwd=1) #promedio + desviación típica 
#abline(v= prom.altura - desv.estandar, lty= 4, lwd=1) #promedio - desviación típica 

En el primer gráfico mostramos gráficamente el promedio en línea de color rojo. En el histograma vemos la distribución de frecuencias, el promedio en rojo y la mediana en negro.

Visualizando la desviación típica

Si la definimos como “el promedio de las diferencias que existe entre los valores de la variable y su promedio”.

par(mfrow=c(1,2)) #parámetros para mostrar figuras en dos columnas

plot(datos$altura, pch= 19, 
     main= "Diferencias" ) 
abline(h= prom.altura, lty= 4, lwd= 2, col= "red3") #el promedio en rojo
segments(x0= seq_along(datos$altura), 
         y0= datos$altura, 
         x1= seq_along(datos$altura), 
         y1= mean(datos$altura))

plot(datos$altura, pch= 19,
     main = "Promedio +/- d.e." )
abline(h= prom.altura, lty= 4, lwd= 2, col= "red3")
abline(h= prom.altura + desv.estandar, lty= 4, lwd=1) #promedio + desviación típica 
abline(h= prom.altura - desv.estandar, lty= 4, lwd=1) #promedio - desviación típica

Promedio de las diferencias

par(mfrow=c(1,2)) #parámetros para mostrar figuras en dos columnas

plot(datos$altura, pch= 19)
abline(h= prom.altura, lty= 4, lwd= 2, col= "red3")
abline(h= prom.altura + desv.estandar, lty= 4, lwd=1) #promedio + desviación típica 
abline(h= prom.altura - desv.estandar, lty= 4, lwd=1) #promedio - desviación típica



plot(x= seq_along(datos$altura)[datos$altura>prom.altura],
     y=datos$altura[datos$altura>prom.altura], pch= 19, 
     ylim = c(150,185), xlab = "Index", ylab = "altura",
     col= "gray") 
points(x= seq_along(datos$altura)[datos$altura<prom.altura],
     y=datos$altura[datos$altura<prom.altura], pch= 19,
     col= "gray") 
segments(x0= seq_along(datos$altura)[datos$altura>prom.altura], 
         y0= datos$altura[datos$altura>prom.altura], 
         x1= seq_along(datos$altura)[datos$altura>prom.altura], 
         y1= mean(datos$altura) + desv.estandar)
segments(x0= seq_along(datos$altura)[datos$altura<prom.altura], 
         y0= datos$altura[datos$altura<prom.altura], 
         x1= seq_along(datos$altura)[datos$altura<prom.altura], 
         y1= mean(datos$altura) - desv.estandar)
abline(h= prom.altura, lty= 4, lwd= 2, col= "red3") #el promedio en rojo
abline(h= prom.altura + desv.estandar, lty= 4, lwd=1) #promedio + desviación típica 
abline(h= prom.altura - desv.estandar, lty= 4, lwd=1) #promedio - desviación típica

par(mfrow=c(1,2)) #parámetros para mostrar figuras en dos columnas

plot(x= seq_along(datos$altura)[datos$altura>prom.altura],
     y=datos$altura[datos$altura>prom.altura], pch= 19, 
     ylim = c(150,185), xlab= "Index", ylab = "altura",
     col= "gray") 
points(x= seq_along(datos$altura)[datos$altura<prom.altura],
     y=datos$altura[datos$altura<prom.altura], pch= 19,
     col= "gray") 
segments(x0= seq_along(datos$altura)[datos$altura>prom.altura], 
         y0= datos$altura[datos$altura>prom.altura], 
         x1= seq_along(datos$altura)[datos$altura>prom.altura], 
         y1= mean(datos$altura) + desv.estandar)
segments(x0= seq_along(datos$altura)[datos$altura<prom.altura], 
         y0= datos$altura[datos$altura<prom.altura], 
         x1= seq_along(datos$altura)[datos$altura<prom.altura], 
         y1= mean(datos$altura) - desv.estandar)
abline(h= prom.altura, lty= 4, lwd= 2, col= "red3") #el promedio en rojo
abline(h= prom.altura + desv.estandar, lty= 4, lwd=3) #promedio + desviación típica 
abline(h= prom.altura - desv.estandar, lty= 4, lwd=3) #promedio - desviación típica

###################
plot(x= seq_along(datos$altura)[datos$altura>prom.altura],
     y=datos$altura[datos$altura>prom.altura], pch= 19, 
     ylim = c(150,185), xlab = "Index", ylab = "altura",
     type = "n") 

abline(h= prom.altura, lty= 4, lwd= 2, col= "red3") #el promedio en rojo
abline(h= prom.altura + desv.estandar, lwd= 3, lty= 3, ) #promedio + desviación típica 
abline(h= prom.altura - desv.estandar, lty= 3, lwd= 3) #promedio - desviación típica
text(x= 20, y= prom.altura+2, 
     labels = paste("promedio = ",as.character(round(prom.altura ,1))) 
      )
text(x= 20, y= prom.altura + desv.estandar +2, 
     labels = paste(as.character(round(prom.altura + desv.estandar,1))) 
      )
text(x= 20, y= prom.altura - desv.estandar +2, 
     labels = paste(as.character(round(prom.altura - desv.estandar,1))) 
      )

El promedio de un grupo usualmente se expresa como el promedio +/- d.e.. En este caso, 168.6 +/- 7.7

LS0tDQp0aXRsZTogIkRpc3BlcnNpw7NuIg0KYXV0aG9yOiAiRmVkZXJpY28gSi4gVmlsbGF0b3JvIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgZmlnX2hlaWdodDogNg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShmbGV4ZGFzaGJvYXJkKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBlY2hvID0gVFJVRSwNCgltZXNzYWdlID0gRkFMU0UsDQogIHdhcm5pbmcgPSBGQUxTRSwNCglpbmNsdWRlID0gVFJVRQ0KKQ0KYGBgICANCg0KIyMjIyBwYWNrYWdlcw0KDQpgYGB7ciBwYWNrYWdlcywgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0KaWYoIXJlcXVpcmUodGlkeXZlcnNlKSl7aW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIil9DQppZighcmVxdWlyZShnb29nbGVzaGVldHM0KSl7aW5zdGFsbC5wYWNrYWdlcygiZ29vZ2xlc2hlZXRzNCIpfQ0KaWYoIXJlcXVpcmUoZ29vZ2xlZHJpdmUpKXtpbnN0YWxsLnBhY2thZ2VzKCJnb29nbGVkcml2ZSIpfQ0KaWYoIXJlcXVpcmUodmlvcGxvdCkpe2luc3RhbGwucGFja2FnZXMoInZpb3Bsb3QiKX0NCiMjDQpsaWJyYXJ5KHZpb3Bsb3QpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ29vZ2xlc2hlZXRzNCkNCmxpYnJhcnkoZ29vZ2xlZHJpdmUpDQpgYGAgIA0KDQojIyMgUmVhZGluZyBEYXRhDQoNCmBgYHtyIGluY2x1ZGU9IEZBTFNFfQ0KDQpvcHRpb25zKGdhcmdsZV9vYXV0aF9lbWFpbCA9ICJ2aWxsYXRvcm9wYXpmakBkYXRhYW5hbHlzaXNsYWIuY29tIikNCmBgYCAgDQoNCmBgYHtyIGVjaG89VFJVRX0NCnNzIDwtICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xODBySlU3eTdhWGxBcXdTTHRLZHJsa0xnRmp3Q3dJNzZsNlVmN2tpaTMxVS9lZGl0P3VzcD1zaGFyaW5nIg0KaG9qYSA9IDENCnJhbmdvID0gIkMzOkk0OCINCmRhdG9zIDwtIHJlYWRfc2hlZXQoc3MsDQogICAgICAgICAgICAgICAgc2hlZXQ9aG9qYSwNCiAgICAgICAgICAgICAgICByYW5nZT0gcmFuZ28sDQogICAgICAgICAgICAgICAgY29sX25hbWVzID0gVFJVRSwNCiAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSAiYyIpDQoNCmBgYCAgDQoNCiMjIyBUaXBvcyBkZSB2YXJpYWJsZTogTGV5ZW5kbyBsYXMgY29sdW1uYXMNCg0KYGBge3J9DQpzdHIoZGF0b3MpDQoNCmRhdG9zWyxjKDE6NildIDwtIGRhdG9zWyxjKDE6NildICU+JQ0KICBzYXBwbHkoYXMubnVtZXJpYykNCg0KZGF0b3MgPC0gIGRhdG9zICU+JQ0KICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLCBhcy5mYWN0b3IpDQoNCnN0cihkYXRvcykNCg0KYGBgICANCg0KIyMjIEV4cGxvcmFjacOzbiBncsOhZmljYQ0KQXF1w60gdXRpbGl6YW1vcyBlbCBwYXF1ZXRlIGLDoXNpY28gKCJiYXNlIikgZGUgUi4gTcOhcyBhZGVsYW50ZSB2ZXJlbW9zIG3DoXMgYXJndW1lbnRvcyB5IG90cm9zIGNvbWFuZG9zIGRlIG90cm9zIHBhcXVldGVzIChlLmcuLCAiZ2dwbG90MiIpIHBhcmEgbW9kaWZpY2FyIGV0aXF1ZXRhcywgdMOtdHVsb3MsIGV0Yy4NCg0KYGBge3J9DQpwcm9tLmFsdHVyYSA8LSBtZWFuKGRhdG9zJGFsdHVyYSkgI3Byb21lZGlvDQptZWRpYW5hLmFsdHVyYSA8LSBtZWRpYW4oZGF0b3MkYWx0dXJhKSAjbWVkaWFuYQ0KZGVzdi5lc3RhbmRhciA8LSBzZChkYXRvcyRhbHR1cmEpDQpgYGAgIA0KDQpgYGB7ciBlY2hvPVRSVUV9DQpwcm9tLmFsdHVyYQ0KZGVzdi5lc3RhbmRhcg0KYGBgICANCg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKSAjcGFyw6FtZXRyb3MgcGFyYSBtb3N0cmFyIGZpZ3VyYXMgZW4gZG9zIGNvbHVtbmFzDQpwbG90KGRhdG9zJGFsdHVyYSwgcGNoPSAxOSkgDQphYmxpbmUoaD0gcHJvbS5hbHR1cmEsIGx0eT0gNCwgbHdkPSAyLCBjb2w9ICJyZWQzIikgI2VsIHByb21lZGlvIGVuIHJvam8NCg0KI0hpc3RvZ3JhbWENCmhpc3QoZGF0b3MkYWx0dXJhLCBicmVha3MgPSAxMCwgbGFiZWxzID0gVFJVRSwgDQogICAgIHlsaW09IGMoMCwxNCkpICNkaXN0cmlidWNpw7NuIGRlIGZyZWN1ZW5jaWFzDQphYmxpbmUodj0gcHJvbS5hbHR1cmEsIGx0eT0gNCwgbHdkPTIsIGNvbD0gInJlZDMiKSAjZWwgcHJvbWVkaW8gZW4gcm9qbw0KYWJsaW5lKHY9IG1lZGlhbmEuYWx0dXJhLCBsdHk9IDIsIGx3ZD0yKSAjbGUgbWVkaWFuYSBlbiBuZWdybw0KYGBgICANCkVuIGVsIHByaW1lciBncsOhZmljbyBtb3N0cmFtb3MgZ3LDoWZpY2FtZW50ZSBlbCBwcm9tZWRpbyBlbiBsw61uZWEgZGUgY29sb3Igcm9qby4gRW4gZWwgaGlzdG9ncmFtYSB2ZW1vcyBsYSBkaXN0cmlidWNpw7NuIGRlIGZyZWN1ZW5jaWFzLCBlbCBwcm9tZWRpbyBlbiByb2pvIHkgbGEgbWVkaWFuYSBlbiBuZWdyby4NCg0KDQojIyMgVmlzdWFsaXphbmRvIGxhIGRlc3ZpYWNpw7NuIHTDrXBpY2EgDQoNClNpIGxhIGRlZmluaW1vcyBjb21vICoqImVsIHByb21lZGlvIGRlIGxhcyBkaWZlcmVuY2lhcyBxdWUgZXhpc3RlIGVudHJlIGxvcyB2YWxvcmVzIGRlIGxhIHZhcmlhYmxlIHkgc3UgcHJvbWVkaW8iKiouDQoNCg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKSAjcGFyw6FtZXRyb3MgcGFyYSBtb3N0cmFyIGZpZ3VyYXMgZW4gZG9zIGNvbHVtbmFzDQoNCnBsb3QoZGF0b3MkYWx0dXJhLCBwY2g9IDE5LCANCiAgICAgbWFpbj0gIkRpZmVyZW5jaWFzIiApIA0KYWJsaW5lKGg9IHByb20uYWx0dXJhLCBsdHk9IDQsIGx3ZD0gMiwgY29sPSAicmVkMyIpICNlbCBwcm9tZWRpbyBlbiByb2pvDQpzZWdtZW50cyh4MD0gc2VxX2Fsb25nKGRhdG9zJGFsdHVyYSksIA0KICAgICAgICAgeTA9IGRhdG9zJGFsdHVyYSwgDQogICAgICAgICB4MT0gc2VxX2Fsb25nKGRhdG9zJGFsdHVyYSksIA0KICAgICAgICAgeTE9IG1lYW4oZGF0b3MkYWx0dXJhKSkNCg0KcGxvdChkYXRvcyRhbHR1cmEsIHBjaD0gMTksDQogICAgIG1haW4gPSAiUHJvbWVkaW8gKy8tIGQuZS4iICkNCmFibGluZShoPSBwcm9tLmFsdHVyYSwgbHR5PSA0LCBsd2Q9IDIsIGNvbD0gInJlZDMiKQ0KYWJsaW5lKGg9IHByb20uYWx0dXJhICsgZGVzdi5lc3RhbmRhciwgbHR5PSA0LCBsd2Q9MSkgI3Byb21lZGlvICsgZGVzdmlhY2nDs24gdMOtcGljYSANCmFibGluZShoPSBwcm9tLmFsdHVyYSAtIGRlc3YuZXN0YW5kYXIsIGx0eT0gNCwgbHdkPTEpICNwcm9tZWRpbyAtIGRlc3ZpYWNpw7NuIHTDrXBpY2ENCmBgYCAgDQojIyMgUHJvbWVkaW8gZGUgbGFzIGRpZmVyZW5jaWFzDQoNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkgI3BhcsOhbWV0cm9zIHBhcmEgbW9zdHJhciBmaWd1cmFzIGVuIGRvcyBjb2x1bW5hcw0KDQpwbG90KGRhdG9zJGFsdHVyYSwgcGNoPSAxOSkNCmFibGluZShoPSBwcm9tLmFsdHVyYSwgbHR5PSA0LCBsd2Q9IDIsIGNvbD0gInJlZDMiKQ0KYWJsaW5lKGg9IHByb20uYWx0dXJhICsgZGVzdi5lc3RhbmRhciwgbHR5PSA0LCBsd2Q9MSkgI3Byb21lZGlvICsgZGVzdmlhY2nDs24gdMOtcGljYSANCmFibGluZShoPSBwcm9tLmFsdHVyYSAtIGRlc3YuZXN0YW5kYXIsIGx0eT0gNCwgbHdkPTEpICNwcm9tZWRpbyAtIGRlc3ZpYWNpw7NuIHTDrXBpY2ENCg0KcGxvdCh4PSBzZXFfYWxvbmcoZGF0b3MkYWx0dXJhKVtkYXRvcyRhbHR1cmE+cHJvbS5hbHR1cmFdLA0KICAgICB5PWRhdG9zJGFsdHVyYVtkYXRvcyRhbHR1cmE+cHJvbS5hbHR1cmFdLCBwY2g9IDE5LCANCiAgICAgeWxpbSA9IGMoMTUwLDE4NSksIHhsYWIgPSAiSW5kZXgiLCB5bGFiID0gImFsdHVyYSIsDQogICAgIGNvbD0gImdyYXkiKSANCnBvaW50cyh4PSBzZXFfYWxvbmcoZGF0b3MkYWx0dXJhKVtkYXRvcyRhbHR1cmE8cHJvbS5hbHR1cmFdLA0KICAgICB5PWRhdG9zJGFsdHVyYVtkYXRvcyRhbHR1cmE8cHJvbS5hbHR1cmFdLCBwY2g9IDE5LA0KICAgICBjb2w9ICJncmF5IikgDQpzZWdtZW50cyh4MD0gc2VxX2Fsb25nKGRhdG9zJGFsdHVyYSlbZGF0b3MkYWx0dXJhPnByb20uYWx0dXJhXSwgDQogICAgICAgICB5MD0gZGF0b3MkYWx0dXJhW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sIA0KICAgICAgICAgeDE9IHNlcV9hbG9uZyhkYXRvcyRhbHR1cmEpW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sIA0KICAgICAgICAgeTE9IG1lYW4oZGF0b3MkYWx0dXJhKSArIGRlc3YuZXN0YW5kYXIpDQpzZWdtZW50cyh4MD0gc2VxX2Fsb25nKGRhdG9zJGFsdHVyYSlbZGF0b3MkYWx0dXJhPHByb20uYWx0dXJhXSwgDQogICAgICAgICB5MD0gZGF0b3MkYWx0dXJhW2RhdG9zJGFsdHVyYTxwcm9tLmFsdHVyYV0sIA0KICAgICAgICAgeDE9IHNlcV9hbG9uZyhkYXRvcyRhbHR1cmEpW2RhdG9zJGFsdHVyYTxwcm9tLmFsdHVyYV0sIA0KICAgICAgICAgeTE9IG1lYW4oZGF0b3MkYWx0dXJhKSAtIGRlc3YuZXN0YW5kYXIpDQphYmxpbmUoaD0gcHJvbS5hbHR1cmEsIGx0eT0gNCwgbHdkPSAyLCBjb2w9ICJyZWQzIikgI2VsIHByb21lZGlvIGVuIHJvam8NCmFibGluZShoPSBwcm9tLmFsdHVyYSArIGRlc3YuZXN0YW5kYXIsIGx0eT0gNCwgbHdkPTEpICNwcm9tZWRpbyArIGRlc3ZpYWNpw7NuIHTDrXBpY2EgDQphYmxpbmUoaD0gcHJvbS5hbHR1cmEgLSBkZXN2LmVzdGFuZGFyLCBsdHk9IDQsIGx3ZD0xKSAjcHJvbWVkaW8gLSBkZXN2aWFjacOzbiB0w61waWNhDQpgYGAgIA0KDQoNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkgI3BhcsOhbWV0cm9zIHBhcmEgbW9zdHJhciBmaWd1cmFzIGVuIGRvcyBjb2x1bW5hcw0KDQpwbG90KHg9IHNlcV9hbG9uZyhkYXRvcyRhbHR1cmEpW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sDQogICAgIHk9ZGF0b3MkYWx0dXJhW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sIHBjaD0gMTksIA0KICAgICB5bGltID0gYygxNTAsMTg1KSwgeGxhYj0gIkluZGV4IiwgeWxhYiA9ICJhbHR1cmEiLA0KICAgICBjb2w9ICJncmF5IikgDQpwb2ludHMoeD0gc2VxX2Fsb25nKGRhdG9zJGFsdHVyYSlbZGF0b3MkYWx0dXJhPHByb20uYWx0dXJhXSwNCiAgICAgeT1kYXRvcyRhbHR1cmFbZGF0b3MkYWx0dXJhPHByb20uYWx0dXJhXSwgcGNoPSAxOSwNCiAgICAgY29sPSAiZ3JheSIpIA0Kc2VnbWVudHMoeDA9IHNlcV9hbG9uZyhkYXRvcyRhbHR1cmEpW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sIA0KICAgICAgICAgeTA9IGRhdG9zJGFsdHVyYVtkYXRvcyRhbHR1cmE+cHJvbS5hbHR1cmFdLCANCiAgICAgICAgIHgxPSBzZXFfYWxvbmcoZGF0b3MkYWx0dXJhKVtkYXRvcyRhbHR1cmE+cHJvbS5hbHR1cmFdLCANCiAgICAgICAgIHkxPSBtZWFuKGRhdG9zJGFsdHVyYSkgKyBkZXN2LmVzdGFuZGFyKQ0Kc2VnbWVudHMoeDA9IHNlcV9hbG9uZyhkYXRvcyRhbHR1cmEpW2RhdG9zJGFsdHVyYTxwcm9tLmFsdHVyYV0sIA0KICAgICAgICAgeTA9IGRhdG9zJGFsdHVyYVtkYXRvcyRhbHR1cmE8cHJvbS5hbHR1cmFdLCANCiAgICAgICAgIHgxPSBzZXFfYWxvbmcoZGF0b3MkYWx0dXJhKVtkYXRvcyRhbHR1cmE8cHJvbS5hbHR1cmFdLCANCiAgICAgICAgIHkxPSBtZWFuKGRhdG9zJGFsdHVyYSkgLSBkZXN2LmVzdGFuZGFyKQ0KYWJsaW5lKGg9IHByb20uYWx0dXJhLCBsdHk9IDQsIGx3ZD0gMiwgY29sPSAicmVkMyIpICNlbCBwcm9tZWRpbyBlbiByb2pvDQphYmxpbmUoaD0gcHJvbS5hbHR1cmEgKyBkZXN2LmVzdGFuZGFyLCBsdHk9IDQsIGx3ZD0zKSAjcHJvbWVkaW8gKyBkZXN2aWFjacOzbiB0w61waWNhIA0KYWJsaW5lKGg9IHByb20uYWx0dXJhIC0gZGVzdi5lc3RhbmRhciwgbHR5PSA0LCBsd2Q9MykgI3Byb21lZGlvIC0gZGVzdmlhY2nDs24gdMOtcGljYQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjDQpwbG90KHg9IHNlcV9hbG9uZyhkYXRvcyRhbHR1cmEpW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sDQogICAgIHk9ZGF0b3MkYWx0dXJhW2RhdG9zJGFsdHVyYT5wcm9tLmFsdHVyYV0sIHBjaD0gMTksIA0KICAgICB5bGltID0gYygxNTAsMTg1KSwgeGxhYiA9ICJJbmRleCIsIHlsYWIgPSAiYWx0dXJhIiwNCiAgICAgdHlwZSA9ICJuIikgDQoNCmFibGluZShoPSBwcm9tLmFsdHVyYSwgbHR5PSA0LCBsd2Q9IDIsIGNvbD0gInJlZDMiKSAjZWwgcHJvbWVkaW8gZW4gcm9qbw0KYWJsaW5lKGg9IHByb20uYWx0dXJhICsgZGVzdi5lc3RhbmRhciwgbHdkPSAzLCBsdHk9IDMsICkgI3Byb21lZGlvICsgZGVzdmlhY2nDs24gdMOtcGljYSANCmFibGluZShoPSBwcm9tLmFsdHVyYSAtIGRlc3YuZXN0YW5kYXIsIGx0eT0gMywgbHdkPSAzKSAjcHJvbWVkaW8gLSBkZXN2aWFjacOzbiB0w61waWNhDQp0ZXh0KHg9IDIwLCB5PSBwcm9tLmFsdHVyYSsyLCANCiAgICAgbGFiZWxzID0gcGFzdGUoInByb21lZGlvID0gIixhcy5jaGFyYWN0ZXIocm91bmQocHJvbS5hbHR1cmEgLDEpKSkgDQogICAgICApDQp0ZXh0KHg9IDIwLCB5PSBwcm9tLmFsdHVyYSArIGRlc3YuZXN0YW5kYXIgKzIsIA0KICAgICBsYWJlbHMgPSBwYXN0ZShhcy5jaGFyYWN0ZXIocm91bmQocHJvbS5hbHR1cmEgKyBkZXN2LmVzdGFuZGFyLDEpKSkgDQogICAgICApDQp0ZXh0KHg9IDIwLCB5PSBwcm9tLmFsdHVyYSAtIGRlc3YuZXN0YW5kYXIgKzIsIA0KICAgICBsYWJlbHMgPSBwYXN0ZShhcy5jaGFyYWN0ZXIocm91bmQocHJvbS5hbHR1cmEgLSBkZXN2LmVzdGFuZGFyLDEpKSkgDQogICAgICApDQpgYGANCkVsIHByb21lZGlvIGRlIHVuIGdydXBvIHVzdWFsbWVudGUgc2UgZXhwcmVzYSBjb21vIGVsICoqcHJvbWVkaW8gKy8tIGQuZS4qKi4gRW4gZXN0ZSBjYXNvLCAqKmByIHJvdW5kKHByb20uYWx0dXJhLDEpYCArLy0gYHIgcm91bmQoZGVzdi5lc3RhbmRhciwxKWAqKg==