Simulación moneda

  • En este caso estamos interesados en conocer la verdadera probabilidad de obtener cara al lanzar una moneda al aire.
  • ¿Realmente la probabilida de obtener “cara” es 0.5?
# Opciones de la moneda
moneda <- c("cara", "sello")

# Un lanzamiento al aire de la moneda
set.seed(1) # semilla que garantiza la replicabilidad
sample(x = moneda, size = 1)
## [1] "cara"
  • Vamos a lanzar la moneda 10 veces al aire y observamos (contamos) cuántas “caras” obtenemos
set.seed(1)
lanzamientos_10 <- replicate(n = 10, expr = sample(x = moneda, size = 1))
lanzamientos_10
##  [1] "cara"  "sello" "cara"  "cara"  "sello" "cara"  "cara"  "cara"  "sello"
## [10] "sello"
  • Ahora calculamos la proporción de “caras” en los 10 lanzamientos:
prop.table(table(lanzamientos_10))[1]
## cara 
##  0.6

100 lanzamientos

  • Vamos a replicar el experimento anterior desde 1 hasta 100 lanzamientos
resultados <- c()

set.seed(1)
for (i in 1:100) {
  muestra <- replicate(n = i, expr = sample(x = moneda, size = 1))
  resultados[i] = prop.table(table(muestra))[1]
}

resultados
##   [1] 1.0000000 0.5000000 0.6666667 0.5000000 1.0000000 0.3333333 0.8571429
##   [8] 0.5000000 0.2222222 0.4000000 0.2727273 0.4166667 0.5384615 0.5000000
##  [15] 0.5333333 0.5625000 0.4705882 0.5555556 0.5789474 0.4500000 0.5238095
##  [22] 0.4545455 0.6086957 0.2083333 0.7200000 0.3461538 0.5185185 0.6428571
##  [29] 0.6551724 0.4000000 0.5806452 0.6562500 0.4545455 0.4705882 0.5428571
##  [36] 0.3611111 0.4324324 0.5000000 0.5641026 0.6000000 0.3414634 0.5238095
##  [43] 0.4186047 0.4545455 0.5555556 0.4347826 0.4893617 0.4791667 0.4693878
##  [50] 0.5200000 0.4509804 0.4423077 0.5471698 0.4814815 0.5272727 0.6428571
##  [57] 0.5789474 0.5344828 0.5423729 0.4833333 0.4098361 0.4516129 0.5873016
##  [64] 0.4062500 0.4923077 0.4545455 0.4776119 0.4264706 0.5217391 0.5428571
##  [71] 0.5211268 0.4722222 0.5068493 0.5540541 0.5600000 0.4210526 0.5194805
##  [78] 0.4487179 0.5063291 0.4500000 0.4567901 0.5121951 0.4939759 0.5000000
##  [85] 0.5058824 0.5930233 0.5402299 0.4772727 0.3820225 0.4888889 0.5494505
##  [92] 0.4239130 0.5053763 0.4468085 0.4947368 0.4687500 0.3711340 0.4591837
##  [99] 0.4040404 0.5400000
  • Gráficamos el resultado anterior:
plot(resultados, type = "l")
abline(h = 0.5, col = "red")

  • También podemos graficar con ggplot2:
library(tidyverse)
resultados %>% 
  enframe(name = "lanzamiento", value = "proporcion") %>% 
  ggplot(aes(x = lanzamiento, y = proporcion)) +
  geom_line() +
  geom_hline(yintercept = 0.5, color = "red")

2000 lanzamientos

resultados2 <- c()

set.seed(1)
for (i in 1:2000) {
  muestra2 <- replicate(n = i, expr = sample(x = moneda, size = 1))
  resultados2[i] = prop.table(table(muestra2))[1]
}

resultados2 %>% 
  enframe(name = "lanzamiento", value = "proporcion") %>% 
  ggplot(aes(x = lanzamiento, y = proporcion)) +
  geom_line() +
  geom_hline(yintercept = 0.5, color = "red")

  • Graficamos la distribución:
resultados2 %>% 
  enframe(name = "lanzamiento", value = "proporcion") %>% 
  ggplot(aes(x = proporcion)) +
  geom_density() +
  geom_vline(xintercept = 0.5, color = "red")

Ejemplo dado

2000 lanzamientos

  • Primero generamos el espacio muestral del dado:
dado <- c(1, 2, 3, 4, 5, 6)
  • Ahora lanzamos 2000 veces el dado y calculamos la probabilidad de una de las opciones:
resultados_dado <- c()

set.seed(1)
for (i in 1:2000) {
  muestra_dado <- replicate(n = i, expr = sample(x = dado, size = 1))
  resultados_dado[i] = prop.table(table(muestra_dado))[1]
}

resultados_dado %>% 
  enframe(name = "lanzamiento", value = "proporcion") %>% 
  ggplot(aes(x = lanzamiento, y = proporcion)) +
  geom_line() +
  geom_hline(yintercept = 1/6, color = "red")

  • Graficamos la distribución:
resultados_dado %>% 
  enframe(name = "lanzamiento", value = "proporcion") %>% 
  ggplot(aes(x = proporcion)) +
  geom_density() +
  geom_vline(xintercept = 1/6, color = "red")

Encuesta

Promedio académico

library(tidyverse)
library(readxl)
encuesta <- read_excel("encuesta_depurada_excel.xlsx")
encuesta
  • Veamos la distribución del promedio académico:
encuesta %>% 
  ggplot(aes(x = promedio_academico)) +
  geom_density()

  • ¿Cuál es el promedio y la desviación estándar?
encuesta %>% 
  summarise(promedio = mean(promedio_academico),
            desv = sd(promedio_academico))
  • ¿Existe la normalidad? ¿Realmente la variable se distribuye de forma gaussiana? Rta: Gráfico cuantil-cuantil o Q-Q Norm
encuesta %>% 
  ggplot(aes(sample = promedio_academico)) +
  geom_qq() +
  geom_qq_line()

  • Podemos mejorar la interpretación del gráfico anterior con el paquete ggpubr:
library(ggpubr)
ggqqplot(encuesta$promedio_academico)

  • Promedio - 1DE:
3.906207 - 0.2472479
## [1] 3.658959
  • Promedio + 1DE:
3.906207 + 0.2472479
## [1] 4.153455
  • Promedio - 2DE:
3.906207 - (0.2472479 * 2)
## [1] 3.411711
  • Promedio + 2DE:
3.906207 + (0.2472479 * 2)
## [1] 4.400703
  • Promedio - 3DE:
3.906207 - (0.2472479 * 3)
## [1] 3.164463
  • Promedio + 3DE:
3.906207 + (0.2472479 * 3)
## [1] 4.647951
  • ¿Puedo simular 100 estudiantes de la Universidad de Antioquia con las dos métricas anteriores?
set.seed(1)
estud_sim <- rnorm(n = 1000000, mean = 3.906207, sd = 0.2472479)

estud_sim %>% head()
## [1] 3.751318 3.951612 3.699600 4.300637 3.987677 3.703348
  • ¿Puedo usar estos valores simulados para hacer inferencias estadísticas? ¿Puedo calcular probabilidades?
pnorm(q = 4.1, mean = 3.906207, sd = 0.2472479, lower.tail = TRUE)
## [1] 0.7834214
  • ¿Puedo obtener un valor similar con los datos simulados anteriormente? Parece que no 😨😨😨.
prop.table(table(estud_sim <= 4.1))
## 
##    FALSE     TRUE 
## 0.216743 0.783257
  • ¿Qué pasa si incrementamos el número de estudiantes simulados? 🤔🤔🤔

  • ¿Cuál es la probabilidad de encontrar un estudiante con promedio académico entre 3.14 y 3.47?

prop.table(table(estud_sim >= 3.14 & estud_sim  <= 3.47))
## 
##    FALSE     TRUE 
## 0.961721 0.038279

Anexo: depuración de encuesta

mis_nombres <- c(
  "promedio_academico",
  "tiempo_casa_u",
  "distancia_casa_u",
  "abandonar_universidad",
  "medio_transporte",
  "electivas",
  "numero_azar",
  "trabajo",
  "matematicas",
  "pregunta_tiempo",
  "sistema_educativo"
)

encuesta <- read_excel("Encuesta-Respuestas.xlsx") %>% 
  set_names(mis_nombres) %>% 
  mutate(
    promedio_academico = as.numeric(promedio_academico),
    tiempo_casa_u = str_extract_all(
      string = tiempo_casa_u,
      pattern = "[0-9]+",
      simplify = TRUE
    ),
    tiempo_casa_u = as.numeric(tiempo_casa_u),
    distancia_casa_u = str_replace_all(distancia_casa_u,
                                       pattern = "km",
                                       replacement = ""),
    distancia_casa_u = str_replace_all(distancia_casa_u,
                                       pattern = ",",
                                       replacement = "."),
    distancia_casa_u = as.numeric(distancia_casa_u),
    matematicas = as.numeric(matematicas),
    velocidad = distancia_casa_u / tiempo_casa_u
  ) 

writexl::write_xlsx(x = encuesta, path = "encuesta_depurada.xlsx")
LS0tDQp0aXRsZTogIlByb2JhYmlsaWRhZGVzIg0Kc3VidGl0bGU6ICJTaW11bGFjaW9uZXMiDQphdXRob3I6ICJFZGltZXIgRGF2aWQgSmFyYW1pbGxvIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIHRoZW1lOiBjb3Ntbw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpDQpgYGANCg0KIyBTaW11bGFjacOzbiBtb25lZGENCg0KLSBFbiBlc3RlIGNhc28gZXN0YW1vcyBpbnRlcmVzYWRvcyBlbiBjb25vY2VyIGxhIHZlcmRhZGVyYSBwcm9iYWJpbGlkYWQgZGUgb2J0ZW5lciBjYXJhIGFsIGxhbnphciB1bmEgbW9uZWRhIGFsIGFpcmUuDQotIMK/UmVhbG1lbnRlIGxhIHByb2JhYmlsaWRhIGRlIG9idGVuZXIgImNhcmEiIGVzIDAuNT8NCg0KYGBge3J9DQojIE9wY2lvbmVzIGRlIGxhIG1vbmVkYQ0KbW9uZWRhIDwtIGMoImNhcmEiLCAic2VsbG8iKQ0KDQojIFVuIGxhbnphbWllbnRvIGFsIGFpcmUgZGUgbGEgbW9uZWRhDQpzZXQuc2VlZCgxKSAjIHNlbWlsbGEgcXVlIGdhcmFudGl6YSBsYSByZXBsaWNhYmlsaWRhZA0Kc2FtcGxlKHggPSBtb25lZGEsIHNpemUgPSAxKQ0KYGBgDQoNCi0gVmFtb3MgYSBsYW56YXIgbGEgbW9uZWRhIDEwIHZlY2VzIGFsIGFpcmUgeSBvYnNlcnZhbW9zIChjb250YW1vcykgY3XDoW50YXMgImNhcmFzIiBvYnRlbmVtb3MNCg0KYGBge3J9DQpzZXQuc2VlZCgxKQ0KbGFuemFtaWVudG9zXzEwIDwtIHJlcGxpY2F0ZShuID0gMTAsIGV4cHIgPSBzYW1wbGUoeCA9IG1vbmVkYSwgc2l6ZSA9IDEpKQ0KbGFuemFtaWVudG9zXzEwDQpgYGANCg0KLSBBaG9yYSBjYWxjdWxhbW9zIGxhIHByb3BvcmNpw7NuIGRlICJjYXJhcyIgZW4gbG9zIDEwIGxhbnphbWllbnRvczoNCg0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmxlKGxhbnphbWllbnRvc18xMCkpWzFdDQpgYGANCg0KDQojIyAxMDAgbGFuemFtaWVudG9zDQoNCi0gVmFtb3MgYSByZXBsaWNhciBlbCBleHBlcmltZW50byBhbnRlcmlvciBkZXNkZSAxIGhhc3RhIDEwMCBsYW56YW1pZW50b3MNCg0KYGBge3J9DQpyZXN1bHRhZG9zIDwtIGMoKQ0KDQpzZXQuc2VlZCgxKQ0KZm9yIChpIGluIDE6MTAwKSB7DQogIG11ZXN0cmEgPC0gcmVwbGljYXRlKG4gPSBpLCBleHByID0gc2FtcGxlKHggPSBtb25lZGEsIHNpemUgPSAxKSkNCiAgcmVzdWx0YWRvc1tpXSA9IHByb3AudGFibGUodGFibGUobXVlc3RyYSkpWzFdDQp9DQoNCnJlc3VsdGFkb3MNCmBgYA0KDQotIEdyw6FmaWNhbW9zIGVsIHJlc3VsdGFkbyBhbnRlcmlvcjoNCg0KYGBge3J9DQpwbG90KHJlc3VsdGFkb3MsIHR5cGUgPSAibCIpDQphYmxpbmUoaCA9IDAuNSwgY29sID0gInJlZCIpDQpgYGANCg0KLSBUYW1iacOpbiBwb2RlbW9zIGdyYWZpY2FyIGNvbiBnZ3Bsb3QyOg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KcmVzdWx0YWRvcyAlPiUgDQogIGVuZnJhbWUobmFtZSA9ICJsYW56YW1pZW50byIsIHZhbHVlID0gInByb3BvcmNpb24iKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGxhbnphbWllbnRvLCB5ID0gcHJvcG9yY2lvbikpICsNCiAgZ2VvbV9saW5lKCkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLjUsIGNvbG9yID0gInJlZCIpDQpgYGANCg0KIyMgMjAwMCBsYW56YW1pZW50b3MNCg0KYGBge3J9DQpyZXN1bHRhZG9zMiA8LSBjKCkNCg0Kc2V0LnNlZWQoMSkNCmZvciAoaSBpbiAxOjIwMDApIHsNCiAgbXVlc3RyYTIgPC0gcmVwbGljYXRlKG4gPSBpLCBleHByID0gc2FtcGxlKHggPSBtb25lZGEsIHNpemUgPSAxKSkNCiAgcmVzdWx0YWRvczJbaV0gPSBwcm9wLnRhYmxlKHRhYmxlKG11ZXN0cmEyKSlbMV0NCn0NCg0KcmVzdWx0YWRvczIgJT4lIA0KICBlbmZyYW1lKG5hbWUgPSAibGFuemFtaWVudG8iLCB2YWx1ZSA9ICJwcm9wb3JjaW9uIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBsYW56YW1pZW50bywgeSA9IHByb3BvcmNpb24pKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC41LCBjb2xvciA9ICJyZWQiKQ0KYGBgDQoNCi0gR3JhZmljYW1vcyBsYSBkaXN0cmlidWNpw7NuOg0KDQpgYGB7cn0NCnJlc3VsdGFkb3MyICU+JSANCiAgZW5mcmFtZShuYW1lID0gImxhbnphbWllbnRvIiwgdmFsdWUgPSAicHJvcG9yY2lvbiIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcHJvcG9yY2lvbikpICsNCiAgZ2VvbV9kZW5zaXR5KCkgKw0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLjUsIGNvbG9yID0gInJlZCIpDQpgYGANCg0KIyBFamVtcGxvIGRhZG8NCg0KIyMgMjAwMCBsYW56YW1pZW50b3MNCg0KLSBQcmltZXJvIGdlbmVyYW1vcyBlbCBlc3BhY2lvIG11ZXN0cmFsIGRlbCBkYWRvOg0KDQpgYGB7cn0NCmRhZG8gPC0gYygxLCAyLCAzLCA0LCA1LCA2KQ0KYGBgDQoNCi0gQWhvcmEgbGFuemFtb3MgMjAwMCB2ZWNlcyBlbCBkYWRvIHkgY2FsY3VsYW1vcyBsYSBwcm9iYWJpbGlkYWQgZGUgdW5hIGRlIGxhcyBvcGNpb25lczoNCg0KYGBge3J9DQpyZXN1bHRhZG9zX2RhZG8gPC0gYygpDQoNCnNldC5zZWVkKDEpDQpmb3IgKGkgaW4gMToyMDAwKSB7DQogIG11ZXN0cmFfZGFkbyA8LSByZXBsaWNhdGUobiA9IGksIGV4cHIgPSBzYW1wbGUoeCA9IGRhZG8sIHNpemUgPSAxKSkNCiAgcmVzdWx0YWRvc19kYWRvW2ldID0gcHJvcC50YWJsZSh0YWJsZShtdWVzdHJhX2RhZG8pKVsxXQ0KfQ0KDQpyZXN1bHRhZG9zX2RhZG8gJT4lIA0KICBlbmZyYW1lKG5hbWUgPSAibGFuemFtaWVudG8iLCB2YWx1ZSA9ICJwcm9wb3JjaW9uIikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBsYW56YW1pZW50bywgeSA9IHByb3BvcmNpb24pKSArDQogIGdlb21fbGluZSgpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMS82LCBjb2xvciA9ICJyZWQiKQ0KYGBgDQoNCi0gR3JhZmljYW1vcyBsYSBkaXN0cmlidWNpw7NuOg0KDQpgYGB7cn0NCnJlc3VsdGFkb3NfZGFkbyAlPiUgDQogIGVuZnJhbWUobmFtZSA9ICJsYW56YW1pZW50byIsIHZhbHVlID0gInByb3BvcmNpb24iKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IHByb3BvcmNpb24pKSArDQogIGdlb21fZGVuc2l0eSgpICsNCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMS82LCBjb2xvciA9ICJyZWQiKQ0KYGBgDQoNCg0KIyBFbmN1ZXN0YQ0KDQojIyBQcm9tZWRpbyBhY2Fkw6ltaWNvDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHJlYWR4bCkNCmVuY3Vlc3RhIDwtIHJlYWRfZXhjZWwoImVuY3Vlc3RhX2RlcHVyYWRhX2V4Y2VsLnhsc3giKQ0KZW5jdWVzdGENCmBgYA0KDQotIFZlYW1vcyBsYSBkaXN0cmlidWNpw7NuIGRlbCBwcm9tZWRpbyBhY2Fkw6ltaWNvOg0KDQpgYGB7cn0NCmVuY3Vlc3RhICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gcHJvbWVkaW9fYWNhZGVtaWNvKSkgKw0KICBnZW9tX2RlbnNpdHkoKQ0KYGBgDQoNCi0gwr9DdcOhbCBlcyBlbCBwcm9tZWRpbyB5IGxhIGRlc3ZpYWNpw7NuIGVzdMOhbmRhcj8NCg0KYGBge3J9DQplbmN1ZXN0YSAlPiUgDQogIHN1bW1hcmlzZShwcm9tZWRpbyA9IG1lYW4ocHJvbWVkaW9fYWNhZGVtaWNvKSwNCiAgICAgICAgICAgIGRlc3YgPSBzZChwcm9tZWRpb19hY2FkZW1pY28pKQ0KYGBgDQoNCg0KLSDCv0V4aXN0ZSBsYSBub3JtYWxpZGFkPyDCv1JlYWxtZW50ZSBsYSB2YXJpYWJsZSBzZSBkaXN0cmlidXllIGRlIGZvcm1hIGdhdXNzaWFuYT8gUnRhOiBHcsOhZmljbyBjdWFudGlsLWN1YW50aWwgbyBRLVEgTm9ybQ0KDQpgYGB7cn0NCmVuY3Vlc3RhICU+JSANCiAgZ2dwbG90KGFlcyhzYW1wbGUgPSBwcm9tZWRpb19hY2FkZW1pY28pKSArDQogIGdlb21fcXEoKSArDQogIGdlb21fcXFfbGluZSgpDQpgYGANCg0KLSBQb2RlbW9zIG1lam9yYXIgbGEgaW50ZXJwcmV0YWNpw7NuIGRlbCBncsOhZmljbyBhbnRlcmlvciBjb24gZWwgcGFxdWV0ZSBnZ3B1YnI6DQoNCmBgYHtyfQ0KbGlicmFyeShnZ3B1YnIpDQpnZ3FxcGxvdChlbmN1ZXN0YSRwcm9tZWRpb19hY2FkZW1pY28pDQpgYGANCg0KLSBQcm9tZWRpbyAtIDFERToNCg0KYGBge3J9DQozLjkwNjIwNyAtIDAuMjQ3MjQ3OQ0KYGBgDQotIFByb21lZGlvICsgMURFOg0KDQpgYGB7cn0NCjMuOTA2MjA3ICsgMC4yNDcyNDc5DQpgYGANCg0KLSBQcm9tZWRpbyAtIDJERToNCg0KYGBge3J9DQozLjkwNjIwNyAtICgwLjI0NzI0NzkgKiAyKQ0KYGBgDQotIFByb21lZGlvICsgMkRFOg0KDQpgYGB7cn0NCjMuOTA2MjA3ICsgKDAuMjQ3MjQ3OSAqIDIpDQpgYGANCg0KLSBQcm9tZWRpbyAtIDNERToNCg0KYGBge3J9DQozLjkwNjIwNyAtICgwLjI0NzI0NzkgKiAzKQ0KYGBgDQoNCi0gUHJvbWVkaW8gKyAzREU6DQoNCmBgYHtyfQ0KMy45MDYyMDcgKyAoMC4yNDcyNDc5ICogMykNCmBgYA0KDQotIMK/UHVlZG8gc2ltdWxhciAxMDAgZXN0dWRpYW50ZXMgZGUgbGEgVW5pdmVyc2lkYWQgZGUgQW50aW9xdWlhIGNvbiBsYXMgZG9zIG3DqXRyaWNhcyBhbnRlcmlvcmVzPw0KDQo8Y2VudGVyPg0KPGltZyBzcmMgPSAiaHR0cHM6Ly93aWtpbWVkaWEub3JnL2FwaS9yZXN0X3YxL21lZGlhL21hdGgvcmVuZGVyL3N2Zy9jMzVkZTgzNzU3ZjJlNGI2YmY2Y2M1NzBhZGE3MmFkYTIxNzA1YjIzIiAvPg0KPC9jZW50ZXI+DQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMSkNCmVzdHVkX3NpbSA8LSBybm9ybShuID0gMTAwMDAwMCwgbWVhbiA9IDMuOTA2MjA3LCBzZCA9IDAuMjQ3MjQ3OSkNCg0KZXN0dWRfc2ltICU+JSBoZWFkKCkNCmBgYA0KDQotIMK/UHVlZG8gdXNhciBlc3RvcyB2YWxvcmVzIHNpbXVsYWRvcyBwYXJhIGhhY2VyIGluZmVyZW5jaWFzIGVzdGFkw61zdGljYXM/IMK/UHVlZG8gY2FsY3VsYXIgcHJvYmFiaWxpZGFkZXM/DQoNCmBgYHtyfQ0KcG5vcm0ocSA9IDQuMSwgbWVhbiA9IDMuOTA2MjA3LCBzZCA9IDAuMjQ3MjQ3OSwgbG93ZXIudGFpbCA9IFRSVUUpDQpgYGANCg0KLSDCv1B1ZWRvIG9idGVuZXIgdW4gdmFsb3Igc2ltaWxhciBjb24gbG9zIGRhdG9zIHNpbXVsYWRvcyBhbnRlcmlvcm1lbnRlPyBQYXJlY2UgcXVlIG5vIPCfmKjwn5io8J+YqC4NCg0KYGBge3J9DQpwcm9wLnRhYmxlKHRhYmxlKGVzdHVkX3NpbSA8PSA0LjEpKQ0KYGBgDQoNCi0gwr9RdcOpIHBhc2Egc2kgaW5jcmVtZW50YW1vcyBlbCBuw7ptZXJvIGRlIGVzdHVkaWFudGVzIHNpbXVsYWRvcz8g8J+klPCfpJTwn6SUDQoNCi0gwr9DdcOhbCBlcyBsYSBwcm9iYWJpbGlkYWQgZGUgZW5jb250cmFyIHVuIGVzdHVkaWFudGUgY29uIHByb21lZGlvIGFjYWTDqW1pY28gZW50cmUgMy4xNCB5IDMuNDc/DQoNCmBgYHtyfQ0KcHJvcC50YWJsZSh0YWJsZShlc3R1ZF9zaW0gPj0gMy4xNCAmIGVzdHVkX3NpbSAgPD0gMy40NykpDQpgYGANCg0KDQojIEFuZXhvOiBkZXB1cmFjacOzbiBkZSBlbmN1ZXN0YQ0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCm1pc19ub21icmVzIDwtIGMoDQogICJwcm9tZWRpb19hY2FkZW1pY28iLA0KICAidGllbXBvX2Nhc2FfdSIsDQogICJkaXN0YW5jaWFfY2FzYV91IiwNCiAgImFiYW5kb25hcl91bml2ZXJzaWRhZCIsDQogICJtZWRpb190cmFuc3BvcnRlIiwNCiAgImVsZWN0aXZhcyIsDQogICJudW1lcm9fYXphciIsDQogICJ0cmFiYWpvIiwNCiAgIm1hdGVtYXRpY2FzIiwNCiAgInByZWd1bnRhX3RpZW1wbyIsDQogICJzaXN0ZW1hX2VkdWNhdGl2byINCikNCg0KZW5jdWVzdGEgPC0gcmVhZF9leGNlbCgiRW5jdWVzdGEtUmVzcHVlc3Rhcy54bHN4IikgJT4lIA0KICBzZXRfbmFtZXMobWlzX25vbWJyZXMpICU+JSANCiAgbXV0YXRlKA0KICAgIHByb21lZGlvX2FjYWRlbWljbyA9IGFzLm51bWVyaWMocHJvbWVkaW9fYWNhZGVtaWNvKSwNCiAgICB0aWVtcG9fY2FzYV91ID0gc3RyX2V4dHJhY3RfYWxsKA0KICAgICAgc3RyaW5nID0gdGllbXBvX2Nhc2FfdSwNCiAgICAgIHBhdHRlcm4gPSAiWzAtOV0rIiwNCiAgICAgIHNpbXBsaWZ5ID0gVFJVRQ0KICAgICksDQogICAgdGllbXBvX2Nhc2FfdSA9IGFzLm51bWVyaWModGllbXBvX2Nhc2FfdSksDQogICAgZGlzdGFuY2lhX2Nhc2FfdSA9IHN0cl9yZXBsYWNlX2FsbChkaXN0YW5jaWFfY2FzYV91LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybiA9ICJrbSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9ICIiKSwNCiAgICBkaXN0YW5jaWFfY2FzYV91ID0gc3RyX3JlcGxhY2VfYWxsKGRpc3RhbmNpYV9jYXNhX3UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXR0ZXJuID0gIiwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSAiLiIpLA0KICAgIGRpc3RhbmNpYV9jYXNhX3UgPSBhcy5udW1lcmljKGRpc3RhbmNpYV9jYXNhX3UpLA0KICAgIG1hdGVtYXRpY2FzID0gYXMubnVtZXJpYyhtYXRlbWF0aWNhcyksDQogICAgdmVsb2NpZGFkID0gZGlzdGFuY2lhX2Nhc2FfdSAvIHRpZW1wb19jYXNhX3UNCiAgKSANCg0Kd3JpdGV4bDo6d3JpdGVfeGxzeCh4ID0gZW5jdWVzdGEsIHBhdGggPSAiZW5jdWVzdGFfZGVwdXJhZGEueGxzeCIpDQpgYGANCg0K