Bootstrapping sencillo

####Primer Ejemplo####
#Cargar librería necesaria
library(boot)


#Datos originales
salarios <- c(2000, 2500, 2800, 3200, 4000, 4500, 5000, 6000, 6500, 7000)

#Función para calcular la media (para el bootstrap)
bootstrap_media <- function(data, indices) {
  return(mean(data[indices]))  # Calcula la media de la muestra remuestreada
}

#Aplicar Bootstrap con 1000 repeticiones
set.seed(616)  # Fijamos seed para reproducibilidad
bootstrap_result <- boot(data = salarios, statistic = bootstrap_media, R = 1000)

#Mostrar resumen de resultados
print(bootstrap_result)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = salarios, statistic = bootstrap_media, R = 1000)
## 
## 
## Bootstrap Statistics :
##     original  bias    std. error
## t1*     4350   -6.14    513.2681
#Calcular Intervalo de Confianza del 95%
intervalo_confianza <- boot.ci(bootstrap_result, type = "perc")
print(intervalo_confianza)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (3380, 5379 )  
## Calculations and Intervals on Original Scale
hist(bootstrap_result$t, main = "Distribución Bootstrap de la Media",
     xlab = "Media Remuestreada", col = "lightblue", border = "black")

bootstrap_result2 <- boot(data = bootstrap_result$t, statistic = bootstrap_media, R = 1000)

intervalo_confianza2 <- boot.ci(bootstrap_result2, type = "perc")
print(intervalo_confianza2)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result2, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (4313, 4375 )  
## Calculations and Intervals on Original Scale
####Dos grupos####
#Cargar librería necesaria
library(boot)

#Datos de salarios por departamento
salarios_A <- c(2500, 2800, 3000, 3500, 4000, 4200, 4500, 4800, 5000, 5500)
salarios_B <- c(2800, 3200, 3600, 4000, 4500, 4700, 5000, 5500, 6000, 6500)

#Función para calcular la diferencia de medias
bootstrap_diff_means <- function(data, indices) {
  datos_A <- data[indices[1:10]]  # Primeros 10 valores son del grupo A
  datos_B <- data[indices[11:20]] # Últimos 10 valores son del grupo B
  return(mean(datos_B) - mean(datos_A))  # Diferencia de medias
}

#Unir datos en un solo vector
datos_combinados <- c(salarios_A, salarios_B)

#Aplicar Bootstrap con 1000 repeticiones
set.seed(616)  # Fijamos semilla para reproducibilidad
bootstrap_result <- boot(data = datos_combinados, statistic = bootstrap_diff_means, R = 1000)

#Mostrar resumen de resultados
print(bootstrap_result)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = datos_combinados, statistic = bootstrap_diff_means, 
##     R = 1000)
## 
## 
## Bootstrap Statistics :
##     original  bias    std. error
## t1*      600  -578.5    511.1703
#Calcular Intervalo de Confianza del 95%
intervalo_confianza <- boot.ci(bootstrap_result, type = "perc")
print(intervalo_confianza)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (-910.0, 1099.7 )  
## Calculations and Intervals on Original Scale
hist(bootstrap_result$t, main = "Distribución Bootstrap de la Diferencia de Medias",
     xlab = "Diferencia de Medias", col = "lightblue", border = "black")

bootstrap_result2 <- boot(data = bootstrap_result$t, statistic = bootstrap_diff_means, R = 1000)

#Mostrar resumen de resultados
print(bootstrap_result2)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = bootstrap_result$t, statistic = bootstrap_diff_means, 
##     R = 1000)
## 
## 
## Bootstrap Statistics :
##     original  bias    std. error
## t1*     -276 273.935    231.7484
#Calcular Intervalo de Confianza del 95%
intervalo_confianza2 <- boot.ci(bootstrap_result2, type = "perc")
print(intervalo_confianza2)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result2, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (-451.9,  456.9 )  
## Calculations and Intervals on Original Scale

Actividad 1:

####Ejercicio hotel Mirage ####
#Cargar librería necesaria
library(boot)

#Datos originales (Ocupación mensual del Hotel Mirage, en %)
ocupacion <- c(78, 82, 75, 80, 85, 88, 92, 90, 86, 84, 80, 83)

#Función para calcular la media (para el bootstrap)
bootstrap_media <- function(data, indices) {
  return(mean(data[indices]))  # Calcula la media de la muestra remuestreada
}

#Aplicar Bootstrap con 1000 repeticiones
set.seed(616)  # Fijamos seed para reproducibilidad
bootstrap_result <- boot(data = ocupacion, statistic = bootstrap_media, R = 1000)

#Mostrar resumen de resultados
print(bootstrap_result)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = ocupacion, statistic = bootstrap_media, R = 1000)
## 
## 
## Bootstrap Statistics :
##     original     bias    std. error
## t1* 83.58333 0.07033333    1.358444
#Calcular Intervalo de Confianza del 95%
intervalo_confianza <- boot.ci(bootstrap_result, type = "perc")
print(intervalo_confianza)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (81.00, 86.42 )  
## Calculations and Intervals on Original Scale
#Histograma de medias remuestreadas
hist(bootstrap_result$t, main = "Distribución Bootstrap de la Ocupación Media",
     xlab = "Ocupación remuestreada (%)", col = "lightblue", border = "black")

#(igual que en el ejemplo original) Bootstrap sobre el vector de estadísticas
bootstrap_result2 <- boot(data = bootstrap_result$t, statistic = bootstrap_media, R = 1000)

intervalo_confianza2 <- boot.ci(bootstrap_result2, type = "perc")
print(intervalo_confianza2)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result2, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (83.57, 83.74 )  
## Calculations and Intervals on Original Scale
####Dos grupos####
#Cargar librería necesaria
library(boot)

#Datos de ocupación por “semestre” (enero–junio vs. julio–diciembre)
ocupacion_A <- c(78, 82, 75, 80, 85, 88)      # Primeros 6 meses
ocupacion_B <- c(92, 90, 86, 84, 80, 83)      # Últimos 6 meses

#Función para calcular la diferencia de medias
bootstrap_diff_means <- function(data, indices) {
  datos_A <- data[indices[1:6]]   # Primeros 6 valores son del grupo A
  datos_B <- data[indices[7:12]]  # Últimos 6 valores son del grupo B
  return(mean(datos_B) - mean(datos_A))  # Diferencia de medias
}

#Unir datos en un solo vector
datos_combinados <- c(ocupacion_A, ocupacion_B)

#Aplicar Bootstrap con 1000 repeticiones
set.seed(616)  # Fijamos semilla para reproducibilidad
bootstrap_result <- boot(data = datos_combinados, statistic = bootstrap_diff_means, R = 1000)

#Mostrar resumen de resultados
print(bootstrap_result)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = datos_combinados, statistic = bootstrap_diff_means, 
##     R = 1000)
## 
## 
## Bootstrap Statistics :
##     original    bias    std. error
## t1*      4.5 -4.368333    2.791358
#Calcular Intervalo de Confianza del 95%
intervalo_confianza <- boot.ci(bootstrap_result, type = "perc")
print(intervalo_confianza)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (-5.496,  5.662 )  
## Calculations and Intervals on Original Scale
#Histograma de diferencias de medias
hist(bootstrap_result$t, main = "Distribución Bootstrap de la Diferencia de Ocupación",
     xlab = "Diferencia de medias (B - A) en puntos porcentuales",
     col = "lightblue", border = "black")

#(igual que en el ejemplo original) Bootstrap sobre las estadísticas
bootstrap_result2 <- boot(data = bootstrap_result$t, statistic = bootstrap_media, R = 1000)

#Mostrar resumen de resultados
print(bootstrap_result2)
## 
## ORDINARY NONPARAMETRIC BOOTSTRAP
## 
## 
## Call:
## boot(data = bootstrap_result$t, statistic = bootstrap_media, 
##     R = 1000)
## 
## 
## Bootstrap Statistics :
##      original      bias    std. error
## t1* 0.1316667 0.001644833  0.08861677
#Calcular Intervalo de Confianza del 95%
intervalo_confianza2 <- boot.ci(bootstrap_result2, type = "perc")
print(intervalo_confianza2)
## BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
## Based on 1000 bootstrap replicates
## 
## CALL : 
## boot.ci(boot.out = bootstrap_result2, type = "perc")
## 
## Intervals : 
## Level     Percentile     
## 95%   (-0.0468,  0.3072 )  
## Calculations and Intervals on Original Scale

Recomendaciones si la ocupación cae 80%

precios dinámicos y paquetes (noches extra, desayuno/spa) en días valle;

más visibilidad en OTAs + campañas locales;

atraer segmentos alternos (corporativo local, grupos, “staycations”, trabajo remoto);

campañas a clientes previos (beneficios: upgrade/late checkout);

empujar reservas directas con mejores condiciones;

mejorar experiencia clave (wifi, limpieza, check‑in) para subir reviews y conversión.

LS0tDQp0aXRsZTogIkJvb3RzdHJhcHBpbmciDQphdXRob3I6ICJMdWlzIEZlbGlwZSBGcmFuY28gUm9kcsOtZ3VleiINCmRhdGU6ICIyMDI1LTA4LTE4Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCi0tLQ0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpuYXZ5OyI+IEJvb3RzdHJhcHBpbmcgc2VuY2lsbG8gPC9zcGFuPiANCg0KYGBge3J9DQojIyMjUHJpbWVyIEVqZW1wbG8jIyMjDQojQ2FyZ2FyIGxpYnJlcsOtYSBuZWNlc2FyaWENCmxpYnJhcnkoYm9vdCkNCg0KDQojRGF0b3Mgb3JpZ2luYWxlcw0Kc2FsYXJpb3MgPC0gYygyMDAwLCAyNTAwLCAyODAwLCAzMjAwLCA0MDAwLCA0NTAwLCA1MDAwLCA2MDAwLCA2NTAwLCA3MDAwKQ0KDQojRnVuY2nDs24gcGFyYSBjYWxjdWxhciBsYSBtZWRpYSAocGFyYSBlbCBib290c3RyYXApDQpib290c3RyYXBfbWVkaWEgPC0gZnVuY3Rpb24oZGF0YSwgaW5kaWNlcykgew0KICByZXR1cm4obWVhbihkYXRhW2luZGljZXNdKSkgICMgQ2FsY3VsYSBsYSBtZWRpYSBkZSBsYSBtdWVzdHJhIHJlbXVlc3RyZWFkYQ0KfQ0KDQojQXBsaWNhciBCb290c3RyYXAgY29uIDEwMDAgcmVwZXRpY2lvbmVzDQpzZXQuc2VlZCg2MTYpICAjIEZpamFtb3Mgc2VlZCBwYXJhIHJlcHJvZHVjaWJpbGlkYWQNCmJvb3RzdHJhcF9yZXN1bHQgPC0gYm9vdChkYXRhID0gc2FsYXJpb3MsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWRpYSwgUiA9IDEwMDApDQoNCiNNb3N0cmFyIHJlc3VtZW4gZGUgcmVzdWx0YWRvcw0KcHJpbnQoYm9vdHN0cmFwX3Jlc3VsdCkNCg0KI0NhbGN1bGFyIEludGVydmFsbyBkZSBDb25maWFuemEgZGVsIDk1JQ0KaW50ZXJ2YWxvX2NvbmZpYW56YSA8LSBib290LmNpKGJvb3RzdHJhcF9yZXN1bHQsIHR5cGUgPSAicGVyYyIpDQpwcmludChpbnRlcnZhbG9fY29uZmlhbnphKQ0KDQoNCmhpc3QoYm9vdHN0cmFwX3Jlc3VsdCR0LCBtYWluID0gIkRpc3RyaWJ1Y2nDs24gQm9vdHN0cmFwIGRlIGxhIE1lZGlhIiwNCiAgICAgeGxhYiA9ICJNZWRpYSBSZW11ZXN0cmVhZGEiLCBjb2wgPSAibGlnaHRibHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KDQpib290c3RyYXBfcmVzdWx0MiA8LSBib290KGRhdGEgPSBib290c3RyYXBfcmVzdWx0JHQsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWRpYSwgUiA9IDEwMDApDQoNCmludGVydmFsb19jb25maWFuemEyIDwtIGJvb3QuY2koYm9vdHN0cmFwX3Jlc3VsdDIsIHR5cGUgPSAicGVyYyIpDQpwcmludChpbnRlcnZhbG9fY29uZmlhbnphMikNCg0KIyMjI0RvcyBncnVwb3MjIyMjDQojQ2FyZ2FyIGxpYnJlcsOtYSBuZWNlc2FyaWENCmxpYnJhcnkoYm9vdCkNCg0KI0RhdG9zIGRlIHNhbGFyaW9zIHBvciBkZXBhcnRhbWVudG8NCnNhbGFyaW9zX0EgPC0gYygyNTAwLCAyODAwLCAzMDAwLCAzNTAwLCA0MDAwLCA0MjAwLCA0NTAwLCA0ODAwLCA1MDAwLCA1NTAwKQ0Kc2FsYXJpb3NfQiA8LSBjKDI4MDAsIDMyMDAsIDM2MDAsIDQwMDAsIDQ1MDAsIDQ3MDAsIDUwMDAsIDU1MDAsIDYwMDAsIDY1MDApDQoNCiNGdW5jacOzbiBwYXJhIGNhbGN1bGFyIGxhIGRpZmVyZW5jaWEgZGUgbWVkaWFzDQpib290c3RyYXBfZGlmZl9tZWFucyA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIGRhdG9zX0EgPC0gZGF0YVtpbmRpY2VzWzE6MTBdXSAgIyBQcmltZXJvcyAxMCB2YWxvcmVzIHNvbiBkZWwgZ3J1cG8gQQ0KICBkYXRvc19CIDwtIGRhdGFbaW5kaWNlc1sxMToyMF1dICMgw5psdGltb3MgMTAgdmFsb3JlcyBzb24gZGVsIGdydXBvIEINCiAgcmV0dXJuKG1lYW4oZGF0b3NfQikgLSBtZWFuKGRhdG9zX0EpKSAgIyBEaWZlcmVuY2lhIGRlIG1lZGlhcw0KfQ0KDQojVW5pciBkYXRvcyBlbiB1biBzb2xvIHZlY3Rvcg0KZGF0b3NfY29tYmluYWRvcyA8LSBjKHNhbGFyaW9zX0EsIHNhbGFyaW9zX0IpDQoNCiNBcGxpY2FyIEJvb3RzdHJhcCBjb24gMTAwMCByZXBldGljaW9uZXMNCnNldC5zZWVkKDYxNikgICMgRmlqYW1vcyBzZW1pbGxhIHBhcmEgcmVwcm9kdWNpYmlsaWRhZA0KYm9vdHN0cmFwX3Jlc3VsdCA8LSBib290KGRhdGEgPSBkYXRvc19jb21iaW5hZG9zLCBzdGF0aXN0aWMgPSBib290c3RyYXBfZGlmZl9tZWFucywgUiA9IDEwMDApDQoNCiNNb3N0cmFyIHJlc3VtZW4gZGUgcmVzdWx0YWRvcw0KcHJpbnQoYm9vdHN0cmFwX3Jlc3VsdCkNCg0KI0NhbGN1bGFyIEludGVydmFsbyBkZSBDb25maWFuemEgZGVsIDk1JQ0KaW50ZXJ2YWxvX2NvbmZpYW56YSA8LSBib290LmNpKGJvb3RzdHJhcF9yZXN1bHQsIHR5cGUgPSAicGVyYyIpDQpwcmludChpbnRlcnZhbG9fY29uZmlhbnphKQ0KDQpoaXN0KGJvb3RzdHJhcF9yZXN1bHQkdCwgbWFpbiA9ICJEaXN0cmlidWNpw7NuIEJvb3RzdHJhcCBkZSBsYSBEaWZlcmVuY2lhIGRlIE1lZGlhcyIsDQogICAgIHhsYWIgPSAiRGlmZXJlbmNpYSBkZSBNZWRpYXMiLCBjb2wgPSAibGlnaHRibHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KYm9vdHN0cmFwX3Jlc3VsdDIgPC0gYm9vdChkYXRhID0gYm9vdHN0cmFwX3Jlc3VsdCR0LCBzdGF0aXN0aWMgPSBib290c3RyYXBfZGlmZl9tZWFucywgUiA9IDEwMDApDQoNCiNNb3N0cmFyIHJlc3VtZW4gZGUgcmVzdWx0YWRvcw0KcHJpbnQoYm9vdHN0cmFwX3Jlc3VsdDIpDQoNCiNDYWxjdWxhciBJbnRlcnZhbG8gZGUgQ29uZmlhbnphIGRlbCA5NSUNCmludGVydmFsb19jb25maWFuemEyIDwtIGJvb3QuY2koYm9vdHN0cmFwX3Jlc3VsdDIsIHR5cGUgPSAicGVyYyIpDQpwcmludChpbnRlcnZhbG9fY29uZmlhbnphMikNCmBgYA0KIyA8c3BhbiBzdHlsZT0iY29sb3I6bmF2eTsiPiBBY3RpdmlkYWQgMTogPC9zcGFuPiANCmBgYHtyfQ0KIyMjI0VqZXJjaWNpbyBob3RlbCBNaXJhZ2UgIyMjIw0KI0NhcmdhciBsaWJyZXLDrWEgbmVjZXNhcmlhDQpsaWJyYXJ5KGJvb3QpDQoNCiNEYXRvcyBvcmlnaW5hbGVzIChPY3VwYWNpw7NuIG1lbnN1YWwgZGVsIEhvdGVsIE1pcmFnZSwgZW4gJSkNCm9jdXBhY2lvbiA8LSBjKDc4LCA4MiwgNzUsIDgwLCA4NSwgODgsIDkyLCA5MCwgODYsIDg0LCA4MCwgODMpDQoNCiNGdW5jacOzbiBwYXJhIGNhbGN1bGFyIGxhIG1lZGlhIChwYXJhIGVsIGJvb3RzdHJhcCkNCmJvb3RzdHJhcF9tZWRpYSA8LSBmdW5jdGlvbihkYXRhLCBpbmRpY2VzKSB7DQogIHJldHVybihtZWFuKGRhdGFbaW5kaWNlc10pKSAgIyBDYWxjdWxhIGxhIG1lZGlhIGRlIGxhIG11ZXN0cmEgcmVtdWVzdHJlYWRhDQp9DQoNCiNBcGxpY2FyIEJvb3RzdHJhcCBjb24gMTAwMCByZXBldGljaW9uZXMNCnNldC5zZWVkKDYxNikgICMgRmlqYW1vcyBzZWVkIHBhcmEgcmVwcm9kdWNpYmlsaWRhZA0KYm9vdHN0cmFwX3Jlc3VsdCA8LSBib290KGRhdGEgPSBvY3VwYWNpb24sIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWRpYSwgUiA9IDEwMDApDQoNCiNNb3N0cmFyIHJlc3VtZW4gZGUgcmVzdWx0YWRvcw0KcHJpbnQoYm9vdHN0cmFwX3Jlc3VsdCkNCg0KI0NhbGN1bGFyIEludGVydmFsbyBkZSBDb25maWFuemEgZGVsIDk1JQ0KaW50ZXJ2YWxvX2NvbmZpYW56YSA8LSBib290LmNpKGJvb3RzdHJhcF9yZXN1bHQsIHR5cGUgPSAicGVyYyIpDQpwcmludChpbnRlcnZhbG9fY29uZmlhbnphKQ0KDQojSGlzdG9ncmFtYSBkZSBtZWRpYXMgcmVtdWVzdHJlYWRhcw0KaGlzdChib290c3RyYXBfcmVzdWx0JHQsIG1haW4gPSAiRGlzdHJpYnVjacOzbiBCb290c3RyYXAgZGUgbGEgT2N1cGFjacOzbiBNZWRpYSIsDQogICAgIHhsYWIgPSAiT2N1cGFjacOzbiByZW11ZXN0cmVhZGEgKCUpIiwgY29sID0gImxpZ2h0Ymx1ZSIsIGJvcmRlciA9ICJibGFjayIpDQoNCiMoaWd1YWwgcXVlIGVuIGVsIGVqZW1wbG8gb3JpZ2luYWwpIEJvb3RzdHJhcCBzb2JyZSBlbCB2ZWN0b3IgZGUgZXN0YWTDrXN0aWNhcw0KYm9vdHN0cmFwX3Jlc3VsdDIgPC0gYm9vdChkYXRhID0gYm9vdHN0cmFwX3Jlc3VsdCR0LCBzdGF0aXN0aWMgPSBib290c3RyYXBfbWVkaWEsIFIgPSAxMDAwKQ0KDQppbnRlcnZhbG9fY29uZmlhbnphMiA8LSBib290LmNpKGJvb3RzdHJhcF9yZXN1bHQyLCB0eXBlID0gInBlcmMiKQ0KcHJpbnQoaW50ZXJ2YWxvX2NvbmZpYW56YTIpDQoNCg0KIyMjI0RvcyBncnVwb3MjIyMjDQojQ2FyZ2FyIGxpYnJlcsOtYSBuZWNlc2FyaWENCmxpYnJhcnkoYm9vdCkNCg0KI0RhdG9zIGRlIG9jdXBhY2nDs24gcG9yIOKAnHNlbWVzdHJl4oCdIChlbmVyb+KAk2p1bmlvIHZzLiBqdWxpb+KAk2RpY2llbWJyZSkNCm9jdXBhY2lvbl9BIDwtIGMoNzgsIDgyLCA3NSwgODAsIDg1LCA4OCkgICAgICAjIFByaW1lcm9zIDYgbWVzZXMNCm9jdXBhY2lvbl9CIDwtIGMoOTIsIDkwLCA4NiwgODQsIDgwLCA4MykgICAgICAjIMOabHRpbW9zIDYgbWVzZXMNCg0KI0Z1bmNpw7NuIHBhcmEgY2FsY3VsYXIgbGEgZGlmZXJlbmNpYSBkZSBtZWRpYXMNCmJvb3RzdHJhcF9kaWZmX21lYW5zIDwtIGZ1bmN0aW9uKGRhdGEsIGluZGljZXMpIHsNCiAgZGF0b3NfQSA8LSBkYXRhW2luZGljZXNbMTo2XV0gICAjIFByaW1lcm9zIDYgdmFsb3JlcyBzb24gZGVsIGdydXBvIEENCiAgZGF0b3NfQiA8LSBkYXRhW2luZGljZXNbNzoxMl1dICAjIMOabHRpbW9zIDYgdmFsb3JlcyBzb24gZGVsIGdydXBvIEINCiAgcmV0dXJuKG1lYW4oZGF0b3NfQikgLSBtZWFuKGRhdG9zX0EpKSAgIyBEaWZlcmVuY2lhIGRlIG1lZGlhcw0KfQ0KDQojVW5pciBkYXRvcyBlbiB1biBzb2xvIHZlY3Rvcg0KZGF0b3NfY29tYmluYWRvcyA8LSBjKG9jdXBhY2lvbl9BLCBvY3VwYWNpb25fQikNCg0KI0FwbGljYXIgQm9vdHN0cmFwIGNvbiAxMDAwIHJlcGV0aWNpb25lcw0Kc2V0LnNlZWQoNjE2KSAgIyBGaWphbW9zIHNlbWlsbGEgcGFyYSByZXByb2R1Y2liaWxpZGFkDQpib290c3RyYXBfcmVzdWx0IDwtIGJvb3QoZGF0YSA9IGRhdG9zX2NvbWJpbmFkb3MsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9kaWZmX21lYW5zLCBSID0gMTAwMCkNCg0KI01vc3RyYXIgcmVzdW1lbiBkZSByZXN1bHRhZG9zDQpwcmludChib290c3RyYXBfcmVzdWx0KQ0KDQojQ2FsY3VsYXIgSW50ZXJ2YWxvIGRlIENvbmZpYW56YSBkZWwgOTUlDQppbnRlcnZhbG9fY29uZmlhbnphIDwtIGJvb3QuY2koYm9vdHN0cmFwX3Jlc3VsdCwgdHlwZSA9ICJwZXJjIikNCnByaW50KGludGVydmFsb19jb25maWFuemEpDQoNCiNIaXN0b2dyYW1hIGRlIGRpZmVyZW5jaWFzIGRlIG1lZGlhcw0KaGlzdChib290c3RyYXBfcmVzdWx0JHQsIG1haW4gPSAiRGlzdHJpYnVjacOzbiBCb290c3RyYXAgZGUgbGEgRGlmZXJlbmNpYSBkZSBPY3VwYWNpw7NuIiwNCiAgICAgeGxhYiA9ICJEaWZlcmVuY2lhIGRlIG1lZGlhcyAoQiAtIEEpIGVuIHB1bnRvcyBwb3JjZW50dWFsZXMiLA0KICAgICBjb2wgPSAibGlnaHRibHVlIiwgYm9yZGVyID0gImJsYWNrIikNCg0KIyhpZ3VhbCBxdWUgZW4gZWwgZWplbXBsbyBvcmlnaW5hbCkgQm9vdHN0cmFwIHNvYnJlIGxhcyBlc3RhZMOtc3RpY2FzDQpib290c3RyYXBfcmVzdWx0MiA8LSBib290KGRhdGEgPSBib290c3RyYXBfcmVzdWx0JHQsIHN0YXRpc3RpYyA9IGJvb3RzdHJhcF9tZWRpYSwgUiA9IDEwMDApDQoNCiNNb3N0cmFyIHJlc3VtZW4gZGUgcmVzdWx0YWRvcw0KcHJpbnQoYm9vdHN0cmFwX3Jlc3VsdDIpDQoNCiNDYWxjdWxhciBJbnRlcnZhbG8gZGUgQ29uZmlhbnphIGRlbCA5NSUNCmludGVydmFsb19jb25maWFuemEyIDwtIGJvb3QuY2koYm9vdHN0cmFwX3Jlc3VsdDIsIHR5cGUgPSAicGVyYyIpDQpwcmludChpbnRlcnZhbG9fY29uZmlhbnphMikNCmBgYA0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOm5hdnk7Ij4gUmVjb21lbmRhY2lvbmVzIHNpIGxhIG9jdXBhY2nDs24gY2FlIDgwJSA8L3NwYW4+DQoNCnByZWNpb3MgZGluw6FtaWNvcyB5IHBhcXVldGVzIChub2NoZXMgZXh0cmEsIGRlc2F5dW5vL3NwYSkgZW4gZMOtYXMgdmFsbGU7DQoNCm3DoXMgdmlzaWJpbGlkYWQgZW4gT1RBcyArIGNhbXBhw7FhcyBsb2NhbGVzOw0KDQphdHJhZXIgc2VnbWVudG9zIGFsdGVybm9zIChjb3Jwb3JhdGl2byBsb2NhbCwgZ3J1cG9zLCDigJxzdGF5Y2F0aW9uc+KAnSwgdHJhYmFqbyByZW1vdG8pOw0KDQpjYW1wYcOxYXMgYSBjbGllbnRlcyBwcmV2aW9zIChiZW5lZmljaW9zOiB1cGdyYWRlL2xhdGUgY2hlY2tvdXQpOw0KDQplbXB1amFyIHJlc2VydmFzIGRpcmVjdGFzIGNvbiBtZWpvcmVzIGNvbmRpY2lvbmVzOw0KDQptZWpvcmFyIGV4cGVyaWVuY2lhIGNsYXZlICh3aWZpLCBsaW1waWV6YSwgY2hlY2vigJFpbikgcGFyYSBzdWJpciByZXZpZXdzIHkgY29udmVyc2nDs24uDQo=