Ejercicio 3. Vintage Restaurant
Karen necesita pronosticar las ventas mensuales del restaurante con
un año de anticipación. Tengo las ventas mensuales (miles de $) de los
tres primeros años.
# Tabla 18.26 – ventas mensuales (miles $), enero a diciembre por año
vintage <- c(242,235,232,178,184,140,145,152,110,130,152,206, # Año 1
263,238,247,193,193,149,157,161,122,130,167,230, # Año 2
282,255,265,205,210,160,166,174,126,148,173,235) # Año 3
n <- length(vintage)
t <- 1:n
mes <- rep(1:12, times = 3)
1. Gráfica de la serie de tiempo
plot(t, vintage, type = "o", pch = 16, col = "steelblue",
xlab = "Mes (t)", ylab = "Ventas (miles $)",
main = "Vintage Restaurant: ventas mensuales (3 años)")
grid()

Se nota un patrón que se repite cada año (picos en enero y diciembre,
caídas fuertes en verano) y una tendencia que sube poco a poco de un año
al otro.
2. Índices estacionales
d <- descomp_mult(vintage, mes_inicio = 1)
IE <- d$IE
tabla_ie <- data.frame(Mes = month.name, Indice = round(as.numeric(IE), 4))
knitr::kable(tabla_ie, caption = "Índices estacionales")
Índices estacionales
| Mes |
Indice |
| January |
1.4436 |
| February |
1.2997 |
| March |
1.3441 |
| April |
1.0412 |
| May |
1.0494 |
| June |
0.8004 |
| July |
0.8283 |
| August |
0.8530 |
| September |
0.6280 |
| October |
0.7003 |
| November |
0.8528 |
| December |
1.1593 |
La temporada alta es de enero a marzo y diciembre (índices por arriba
de 1; enero ≈ 1.44, o sea 44% arriba del promedio) y la baja es en
verano, con septiembre como el mes más flojo (≈ 0.63). Sí tiene sentido:
es un restaurante en una isla turística de Florida, y en invierno llega
más gente.
3. Serie desestacionalizada y tendencia
plot(t, d$desest, type = "o", pch = 16, col = "darkgreen",
xlab = "Mes (t)", ylab = "Ventas desestacionalizadas",
main = "Serie desestacionalizada y tendencia")
abline(d$tend, col = "red", lwd = 2)
grid()

coef(d$tend)
## (Intercept) t
## 169.349401 1.021297
Al quitar la estacionalidad sí queda una tendencia creciente, con una
pendiente de aprox. 1.021 miles por mes.
4. Pronóstico Año 4 – método de
descomposición
t_fut <- 37:48
pron_desc <- as.numeric(pron_descomp(t_fut, mes_inicio = 1, tend = d$tend, IE = IE))
5. Pronóstico Año 4 – regresión con
variables ficticias
mesf <- factor(mes, levels = 1:12, labels = month.abb)
mod_reg <- lm(vintage ~ t + mesf)
nuevos <- data.frame(t = 37:48, mesf = factor(1:12, levels = 1:12, labels = month.abb))
pron_reg <- as.numeric(predict(mod_reg, newdata = nuevos))
6. Tablas resumen y gráficas
resumen <- data.frame(
Mes = month.name,
Descomposicion = round(pron_desc, 2),
Regresion = round(pron_reg, 2)
)
knitr::kable(resumen, caption = "Pronóstico de ventas Año 4 (miles $)")
Pronóstico de ventas Año 4 (miles $)
| Mes |
Descomposicion |
Regresion |
| January |
299.02 |
286.75 |
| February |
270.54 |
267.08 |
| March |
281.16 |
272.42 |
| April |
218.86 |
216.42 |
| May |
221.65 |
220.08 |
| June |
169.88 |
174.08 |
| July |
176.65 |
180.42 |
| August |
182.78 |
186.75 |
| September |
135.21 |
143.75 |
| October |
151.50 |
160.42 |
| November |
185.35 |
188.42 |
| December |
253.15 |
248.08 |
plot(1:48, c(vintage, rep(NA, 12)), type = "o", pch = 16, col = "gray40",
xlab = "Mes (t)", ylab = "Ventas (miles $)", ylim = c(100, 320),
main = "Histórico y pronósticos del Año 4")
lines(37:48, pron_desc, type = "o", pch = 17, col = "blue")
lines(37:48, pron_reg, type = "o", pch = 15, col = "red")
legend("topright", c("Histórico", "Descomposición", "Regresión"),
col = c("gray40", "blue", "red"), pch = c(16, 17, 15), bty = "n")
grid()

Error de pronóstico de enero. Si en enero del Año 4
las ventas reales fueron $295,000 (295 miles):
real_ene <- 295
data.frame(Metodo = c("Descomposición", "Regresión"),
Pronostico = round(c(pron_desc[1], pron_reg[1]), 2),
Error = round(c(real_ene - pron_desc[1], real_ene - pron_reg[1]), 2))
## Metodo Pronostico Error
## 1 Descomposición 299.02 -4.02
## 2 Regresión 286.75 8.25
El error de la descomposición es de solo -4.02 miles (alrededor de
1.4%), así que es chico y no debería confundir a Karen. Para manejar
mejor la incertidumbre se puede calcular medidas de error como MAD, MSE
o MAPE, usar intervalos de confianza en vez de un solo número, y
reestimar el modelo conforme llegan datos nuevos.
Conclusión
Las ventas de Vintage tienen una estacionalidad fuerte (alta en
invierno, baja en verano) sobre una tendencia creciente. Los dos métodos
dan pronósticos muy parecidos y el de enero prácticamente coincide con
el real ($299 mil vs $295 mil), así que el procedimiento es confiable.
La recomendación para Karen es planear personal e inventario según los
índices: reforzar de diciembre a marzo y aligerar en verano.
Ejercicio 4. Carlson Department Store
Un huracán azotó el 21 de agosto y Carlson cerró de septiembre a
diciembre. Hay que estimar cuánto habría vendido la tienda y el condado
sin el huracán, la pérdida de Carlson, y si hubo un exceso de ventas por
el huracán. Tengo 48 meses previos al cierre (de septiembre del Año 1 a
agosto del Año 5).
# Tabla 18.27 – ventas Carlson ($ millones), desde Sep Año1
carlson <- c(1.71,1.90,2.74,4.20, # Año1 Sep-Dic
1.45,1.80,2.03,1.99,2.32,2.20,2.13,2.43,1.90,2.13,2.56,4.16, # Año2
2.31,1.89,2.02,2.23,2.39,2.14,2.27,2.21,1.89,2.29,2.83,4.04, # Año3
2.31,1.99,2.42,2.45,2.57,2.42,2.40,2.50,2.09,2.54,2.97,4.35, # Año4
2.56,2.28,2.69,2.48,2.73,2.37,2.31,2.23) # Año5 Ene-Ago
# Tabla 18.28 – ventas del condado ($ millones), mismos 48 meses
condado <- c(55.80,56.40,71.40,117.60,
46.80,48.00,60.00,57.60,61.80,58.20,56.40,63.00,57.60,53.40,71.40,114.00,
46.80,48.60,59.40,58.20,60.60,55.20,51.00,58.80,49.80,54.60,65.40,102.00,
43.80,45.60,57.60,53.40,56.40,52.80,54.00,60.60,47.40,54.60,67.80,100.20,
48.00,51.60,57.60,58.20,60.00,57.00,57.60,61.80)
# Ventas reales del condado durante el cierre (Sep-Dic Año5)
condado_real <- c(69.00, 75.00, 85.20, 121.80)
1 y 2. Ventas estimadas sin huracán
dC <- descomp_mult(carlson, mes_inicio = 9) # empieza en septiembre
dK <- descomp_mult(condado, mes_inicio = 9)
t_cierre <- 49:52 # Sep, Oct, Nov, Dic del Año 5
pron_carlson <- as.numeric(pron_descomp(t_cierre, 9, dC$tend, dC$IE))
pron_condado <- as.numeric(pron_descomp(t_cierre, 9, dK$tend, dK$IE))
tabla_c <- data.frame(
Mes = c("Septiembre","Octubre","Noviembre","Diciembre"),
Carlson_estimado = round(pron_carlson, 3),
Condado_estimado = round(pron_condado, 2),
Condado_real = condado_real
)
knitr::kable(tabla_c, caption = "Estimado sin huracán vs real del condado ($ millones)")
Estimado sin huracán vs real del condado ($ millones)
| Mes |
Carlson_estimado |
Condado_estimado |
Condado_real |
| Septiembre |
2.158 |
50.55 |
69.0 |
| Octubre |
2.544 |
53.20 |
75.0 |
| Noviembre |
3.056 |
66.78 |
85.2 |
| Diciembre |
4.600 |
103.11 |
121.8 |
3. Pérdida de ventas de Carlson
perdida <- sum(pron_carlson)
perdida
## [1] 12.3579
La pérdida de ventas de Carlson de septiembre a diciembre es de
aprox. $12.36 millones.
4. Exceso de ventas por el huracán
exceso_condado <- sum(condado_real) - sum(pron_condado)
particip <- mean(carlson / condado)
exceso_carlson <- particip * exceso_condado
data.frame(
Condado_estimado = round(sum(pron_condado), 2),
Condado_real = sum(condado_real),
Exceso_condado = round(exceso_condado, 2),
Particip_Carlson = round(particip, 4),
Exceso_Carlson = round(exceso_carlson, 3)
)
## Condado_estimado Condado_real Exceso_condado Particip_Carlson Exceso_Carlson
## 1 273.64 351 77.36 0.0405 3.135
Las ventas reales del condado durante el cierre ($351 millones) son
mucho mayores que las esperadas sin huracán ($273.64 millones), un
exceso de aprox. $77.36 millones por la ayuda federal y los seguros.
Como Carlson representa en promedio el 4.05% del condado, le habría
tocado una parte de ese exceso: alrededor de $3.135
millones.
Conclusión
Con los 48 meses previos estimo que Carlson perdió cerca de $12.4
millones durante el cierre. Además, el condado vendió alrededor de $77
millones por encima de lo normal después del huracán, y como Carlson
participaba con ~4% del condado, tiene bases para reclamar unos $3.1
millones más por el exceso que habría capturado si hubiera estado
abierta. Le conviene sustentar ambas cifras ante la aseguradora.
LS0tCnRpdGxlOiAnQWN0aXZpZGFkIDI6IE1vZGVsb3MgZGUgcHJvbsOzc3RpY29zIGVuIHNlcmllcyBkZSB0aWVtcG8nCmF1dGhvcjogIkx1aXMgQWd1aWxhciIKZGF0ZTogIjIwMjYtMDgtMjYiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogVFJVRQogICAgdG9jX2Zsb2F0OiBUUlVFCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCiAgICB0aGVtZTogeWV0aQotLS0KCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBUZW9yw61hIDwvc3Bhbj4KClVuYSBzZXJpZSBkZSB0aWVtcG8gc29uIGxhcyBvYnNlcnZhY2lvbmVzIGRlIHVuYSB2YXJpYWJsZSBvcmRlbmFkYXMgZW4gZWwgdGllbXBvLiBFbiBlc3RvcyBlamVyY2ljaW9zIHRyYWJham8gY29uIHNlcmllcyBtZW5zdWFsZXMgcXVlIHRpZW5lbiB0ZW5kZW5jaWEgeSBlc3RhY2lvbmFsaWRhZCwgeSB1c28gZG9zIG3DqXRvZG9zIHBhcmEgcHJvbm9zdGljYXI6CgotICoqRGVzY29tcG9zaWNpw7NuIG11bHRpcGxpY2F0aXZhOioqIHNlcGFybyBsYSBzZXJpZSBlbiB0ZW5kZW5jaWEsIGVzdGFjaW9uYWxpZGFkIGUgaXJyZWd1bGFyICgkWV90ID0gVF90IFx0aW1lcyBTX3QgXHRpbWVzIElfdCQpLiBQYXJhIGVzdGltYXIgZWwgw61uZGljZSBlc3RhY2lvbmFsIGRlIGNhZGEgbWVzIGRpdmlkbyBlbCBkYXRvIHJlYWwgZW50cmUgdW4gcHJvbWVkaW8gbcOzdmlsIGNlbnRyYWRvIGRlIG9yZGVuIDEyLCBsdWVnbyBkZXNlc3RhY2lvbmFsaXpvLCBsZSBhanVzdG8gdW5hIHRlbmRlbmNpYSBsaW5lYWwgeSBlbCBwcm9uw7NzdGljbyBlcyAkKGJfMCArIGJfMSB0KSQgcG9yIGVsIMOtbmRpY2UgZGVsIG1lcy4KLSAqKlJlZ3Jlc2nDs24gY29uIHZhcmlhYmxlcyBmaWN0aWNpYXM6KiogYWp1c3RvICRZX3QgPSBcYmV0YV8wICsgXGJldGFfMSB0ICsgXHN1bSBcZ2FtbWFfbSBEX20kLCBkb25kZSAkdCQgZXMgbGEgdGVuZGVuY2lhIHkgbGFzIDExIGR1bW1pZXMgY2FwdHVyYW4gZWwgbWVzLgoKUGFyYSB2ZXIgcXXDqSB0YW4gYnVlbm8gZXMgdW4gcHJvbsOzc3RpY28gY29tcGFybyBlbCB2YWxvciByZWFsIGNvbnRyYSBlbCBwcm9ub3N0aWNhZG8uCgpgYGB7ciBzZXR1cCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KIyBEZXNjb21wb3NpY2nDs24gbXVsdGlwbGljYXRpdmEgY2zDoXNpY2EKZGVzY29tcF9tdWx0IDwtIGZ1bmN0aW9uKHksIG1lc19pbmljaW8pIHsKICBuICAgPC0gbGVuZ3RoKHkpCiAgbWVzIDwtICgobWVzX2luaWNpbyAtIDEgKyAwOihuIC0gMSkpICUlIDEyKSArIDEgICAjIG1lcyBjYWxlbmRhcmlvIGRlIGNhZGEgdAogICMgUHJvbWVkaW8gbcOzdmlsIGNlbnRyYWRvIGRlIG9yZGVuIDEyCiAgY21hIDwtIHJlcChOQSwgbikKICBmb3IgKGkgaW4gNzoobiAtIDYpKSB7CiAgICBjbWFbaV0gPC0gKDAuNSp5W2ktNl0gKyBzdW0oeVsoaS01KTooaSs1KV0pICsgMC41KnlbaSs2XSkgLyAxMgogIH0KICByYXpvbiAgPC0geSAvIGNtYQogIGNydWRvICA8LSB0YXBwbHkocmF6b24sIG1lcywgbWVhbiwgbmEucm0gPSBUUlVFKSAgICMgcHJvbWVkaW8gZGUgcmF6b25lcyBwb3IgbWVzCiAgSUUgICAgIDwtIGNydWRvICogMTIgLyBzdW0oY3J1ZG8pICAgICAgICAgICAgICAgICAgIyBxdWUgc3VtZW4gMTIKICBkZXNlc3QgPC0geSAvIElFW2FzLmNoYXJhY3RlcihtZXMpXQogIHQgPC0gMTpuCiAgdGVuZCA8LSBsbShkZXNlc3QgfiB0KQogIGxpc3QobWVzID0gbWVzLCBJRSA9IElFLCBkZXNlc3QgPSBkZXNlc3QsIHRlbmQgPSB0ZW5kKQp9CgojIFByb27Ds3N0aWNvIHBvciBkZXNjb21wb3NpY2nDs24KcHJvbl9kZXNjb21wIDwtIGZ1bmN0aW9uKHRfZnV0LCBtZXNfaW5pY2lvLCB0ZW5kLCBJRSkgewogIGIgICAgICAgPC0gY29lZih0ZW5kKQogIG1lc19mdXQgPC0gKChtZXNfaW5pY2lvIC0gMSArICh0X2Z1dCAtIDEpKSAlJSAxMikgKyAxCiAgKGJbMV0gKyBiWzJdKnRfZnV0KSAqIElFW2FzLmNoYXJhY3RlcihtZXNfZnV0KV0KfQpgYGAKCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiBFamVyY2ljaW8gMy4gVmludGFnZSBSZXN0YXVyYW50IDwvc3Bhbj4KCkthcmVuIG5lY2VzaXRhIHByb25vc3RpY2FyIGxhcyB2ZW50YXMgbWVuc3VhbGVzIGRlbCByZXN0YXVyYW50ZSBjb24gdW4gYcOxbyBkZSBhbnRpY2lwYWNpw7NuLiBUZW5nbyBsYXMgdmVudGFzIG1lbnN1YWxlcyAobWlsZXMgZGUgJCkgZGUgbG9zIHRyZXMgcHJpbWVyb3MgYcOxb3MuCgpgYGB7ciB2aW50YWdlLWRhdG9zfQojIFRhYmxhIDE4LjI2IOKAkyB2ZW50YXMgbWVuc3VhbGVzIChtaWxlcyAkKSwgZW5lcm8gYSBkaWNpZW1icmUgcG9yIGHDsW8KdmludGFnZSA8LSBjKDI0MiwyMzUsMjMyLDE3OCwxODQsMTQwLDE0NSwxNTIsMTEwLDEzMCwxNTIsMjA2LCAgIyBBw7FvIDEKICAgICAgICAgICAgIDI2MywyMzgsMjQ3LDE5MywxOTMsMTQ5LDE1NywxNjEsMTIyLDEzMCwxNjcsMjMwLCAgIyBBw7FvIDIKICAgICAgICAgICAgIDI4MiwyNTUsMjY1LDIwNSwyMTAsMTYwLDE2NiwxNzQsMTI2LDE0OCwxNzMsMjM1KSAgIyBBw7FvIDMKbiAgIDwtIGxlbmd0aCh2aW50YWdlKQp0ICAgPC0gMTpuCm1lcyA8LSByZXAoMToxMiwgdGltZXMgPSAzKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gMS4gR3LDoWZpY2EgZGUgbGEgc2VyaWUgZGUgdGllbXBvIDwvc3Bhbj4KCmBgYHtyIHZpbnRhZ2Utc2VyaWV9CnBsb3QodCwgdmludGFnZSwgdHlwZSA9ICJvIiwgcGNoID0gMTYsIGNvbCA9ICJzdGVlbGJsdWUiLAogICAgIHhsYWIgPSAiTWVzICh0KSIsIHlsYWIgPSAiVmVudGFzIChtaWxlcyAkKSIsCiAgICAgbWFpbiA9ICJWaW50YWdlIFJlc3RhdXJhbnQ6IHZlbnRhcyBtZW5zdWFsZXMgKDMgYcOxb3MpIikKZ3JpZCgpCmBgYAoKU2Ugbm90YSB1biBwYXRyw7NuIHF1ZSBzZSByZXBpdGUgY2FkYSBhw7FvIChwaWNvcyBlbiBlbmVybyB5IGRpY2llbWJyZSwgY2HDrWRhcyBmdWVydGVzIGVuIHZlcmFubykgeSB1bmEgdGVuZGVuY2lhIHF1ZSBzdWJlIHBvY28gYSBwb2NvIGRlIHVuIGHDsW8gYWwgb3Ryby4KCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gMi4gw41uZGljZXMgZXN0YWNpb25hbGVzIDwvc3Bhbj4KCmBgYHtyIHZpbnRhZ2UtaWV9CmQgIDwtIGRlc2NvbXBfbXVsdCh2aW50YWdlLCBtZXNfaW5pY2lvID0gMSkKSUUgPC0gZCRJRQp0YWJsYV9pZSA8LSBkYXRhLmZyYW1lKE1lcyA9IG1vbnRoLm5hbWUsIEluZGljZSA9IHJvdW5kKGFzLm51bWVyaWMoSUUpLCA0KSkKa25pdHI6OmthYmxlKHRhYmxhX2llLCBjYXB0aW9uID0gIsONbmRpY2VzIGVzdGFjaW9uYWxlcyIpCmBgYAoKTGEgdGVtcG9yYWRhIGFsdGEgZXMgZGUgZW5lcm8gYSBtYXJ6byB5IGRpY2llbWJyZSAow61uZGljZXMgcG9yIGFycmliYSBkZSAxOyBlbmVybyDiiYggMS40NCwgbyBzZWEgNDQlIGFycmliYSBkZWwgcHJvbWVkaW8pIHkgbGEgYmFqYSBlcyBlbiB2ZXJhbm8sIGNvbiBzZXB0aWVtYnJlIGNvbW8gZWwgbWVzIG3DoXMgZmxvam8gKOKJiCAwLjYzKS4gU8OtIHRpZW5lIHNlbnRpZG86IGVzIHVuIHJlc3RhdXJhbnRlIGVuIHVuYSBpc2xhIHR1csOtc3RpY2EgZGUgRmxvcmlkYSwgeSBlbiBpbnZpZXJubyBsbGVnYSBtw6FzIGdlbnRlLgoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiAzLiBTZXJpZSBkZXNlc3RhY2lvbmFsaXphZGEgeSB0ZW5kZW5jaWEgPC9zcGFuPgoKYGBge3IgdmludGFnZS1kZXNlc3R9CnBsb3QodCwgZCRkZXNlc3QsIHR5cGUgPSAibyIsIHBjaCA9IDE2LCBjb2wgPSAiZGFya2dyZWVuIiwKICAgICB4bGFiID0gIk1lcyAodCkiLCB5bGFiID0gIlZlbnRhcyBkZXNlc3RhY2lvbmFsaXphZGFzIiwKICAgICBtYWluID0gIlNlcmllIGRlc2VzdGFjaW9uYWxpemFkYSB5IHRlbmRlbmNpYSIpCmFibGluZShkJHRlbmQsIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQpncmlkKCkKY29lZihkJHRlbmQpCmBgYAoKQWwgcXVpdGFyIGxhIGVzdGFjaW9uYWxpZGFkIHPDrSBxdWVkYSB1bmEgdGVuZGVuY2lhIGNyZWNpZW50ZSwgY29uIHVuYSBwZW5kaWVudGUgZGUgYXByb3guIGByIHJvdW5kKGNvZWYoZCR0ZW5kKVsyXSwgMylgIG1pbGVzIHBvciBtZXMuCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IDQuIFByb27Ds3N0aWNvIEHDsW8gNCDigJMgbcOpdG9kbyBkZSBkZXNjb21wb3NpY2nDs24gPC9zcGFuPgoKYGBge3IgdmludGFnZS1wcm9uLWRlc2N9CnRfZnV0IDwtIDM3OjQ4CnByb25fZGVzYyA8LSBhcy5udW1lcmljKHByb25fZGVzY29tcCh0X2Z1dCwgbWVzX2luaWNpbyA9IDEsIHRlbmQgPSBkJHRlbmQsIElFID0gSUUpKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gNS4gUHJvbsOzc3RpY28gQcOxbyA0IOKAkyByZWdyZXNpw7NuIGNvbiB2YXJpYWJsZXMgZmljdGljaWFzIDwvc3Bhbj4KCmBgYHtyIHZpbnRhZ2UtcHJvbi1yZWd9Cm1lc2YgICAgPC0gZmFjdG9yKG1lcywgbGV2ZWxzID0gMToxMiwgbGFiZWxzID0gbW9udGguYWJiKQptb2RfcmVnIDwtIGxtKHZpbnRhZ2UgfiB0ICsgbWVzZikKbnVldm9zICA8LSBkYXRhLmZyYW1lKHQgPSAzNzo0OCwgbWVzZiA9IGZhY3RvcigxOjEyLCBsZXZlbHMgPSAxOjEyLCBsYWJlbHMgPSBtb250aC5hYmIpKQpwcm9uX3JlZyA8LSBhcy5udW1lcmljKHByZWRpY3QobW9kX3JlZywgbmV3ZGF0YSA9IG51ZXZvcykpCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiA2LiBUYWJsYXMgcmVzdW1lbiB5IGdyw6FmaWNhcyA8L3NwYW4+CgpgYGB7ciB2aW50YWdlLXJlc3VtZW59CnJlc3VtZW4gPC0gZGF0YS5mcmFtZSgKICBNZXMgICAgICAgICAgICA9IG1vbnRoLm5hbWUsCiAgRGVzY29tcG9zaWNpb24gPSByb3VuZChwcm9uX2Rlc2MsIDIpLAogIFJlZ3Jlc2lvbiAgICAgID0gcm91bmQocHJvbl9yZWcsIDIpCikKa25pdHI6OmthYmxlKHJlc3VtZW4sIGNhcHRpb24gPSAiUHJvbsOzc3RpY28gZGUgdmVudGFzIEHDsW8gNCAobWlsZXMgJCkiKQoKcGxvdCgxOjQ4LCBjKHZpbnRhZ2UsIHJlcChOQSwgMTIpKSwgdHlwZSA9ICJvIiwgcGNoID0gMTYsIGNvbCA9ICJncmF5NDAiLAogICAgIHhsYWIgPSAiTWVzICh0KSIsIHlsYWIgPSAiVmVudGFzIChtaWxlcyAkKSIsIHlsaW0gPSBjKDEwMCwgMzIwKSwKICAgICBtYWluID0gIkhpc3TDs3JpY28geSBwcm9uw7NzdGljb3MgZGVsIEHDsW8gNCIpCmxpbmVzKDM3OjQ4LCBwcm9uX2Rlc2MsIHR5cGUgPSAibyIsIHBjaCA9IDE3LCBjb2wgPSAiYmx1ZSIpCmxpbmVzKDM3OjQ4LCBwcm9uX3JlZywgIHR5cGUgPSAibyIsIHBjaCA9IDE1LCBjb2wgPSAicmVkIikKbGVnZW5kKCJ0b3ByaWdodCIsIGMoIkhpc3TDs3JpY28iLCAiRGVzY29tcG9zaWNpw7NuIiwgIlJlZ3Jlc2nDs24iKSwKICAgICAgIGNvbCA9IGMoImdyYXk0MCIsICJibHVlIiwgInJlZCIpLCBwY2ggPSBjKDE2LCAxNywgMTUpLCBidHkgPSAibiIpCmdyaWQoKQpgYGAKCioqRXJyb3IgZGUgcHJvbsOzc3RpY28gZGUgZW5lcm8uKiogU2kgZW4gZW5lcm8gZGVsIEHDsW8gNCBsYXMgdmVudGFzIHJlYWxlcyBmdWVyb24gJDI5NSwwMDAgKDI5NSBtaWxlcyk6CgpgYGB7ciB2aW50YWdlLWVycm9yfQpyZWFsX2VuZSA8LSAyOTUKZGF0YS5mcmFtZShNZXRvZG8gPSBjKCJEZXNjb21wb3NpY2nDs24iLCAiUmVncmVzacOzbiIpLAogICAgICAgICAgIFByb25vc3RpY28gPSByb3VuZChjKHByb25fZGVzY1sxXSwgcHJvbl9yZWdbMV0pLCAyKSwKICAgICAgICAgICBFcnJvciA9IHJvdW5kKGMocmVhbF9lbmUgLSBwcm9uX2Rlc2NbMV0sIHJlYWxfZW5lIC0gcHJvbl9yZWdbMV0pLCAyKSkKYGBgCgpFbCBlcnJvciBkZSBsYSBkZXNjb21wb3NpY2nDs24gZXMgZGUgc29sbyBgciByb3VuZChyZWFsX2VuZSAtIHByb25fZGVzY1sxXSwgMilgIG1pbGVzIChhbHJlZGVkb3IgZGUgMS40JSksIGFzw60gcXVlIGVzIGNoaWNvIHkgbm8gZGViZXLDrWEgY29uZnVuZGlyIGEgS2FyZW4uIFBhcmEgbWFuZWphciBtZWpvciBsYSBpbmNlcnRpZHVtYnJlIHNlIHB1ZWRlIGNhbGN1bGFyIG1lZGlkYXMgZGUgZXJyb3IgY29tbyBNQUQsIE1TRSBvIE1BUEUsIHVzYXIgaW50ZXJ2YWxvcyBkZSBjb25maWFuemEgZW4gdmV6IGRlIHVuIHNvbG8gbsO6bWVybywgeSByZWVzdGltYXIgZWwgbW9kZWxvIGNvbmZvcm1lIGxsZWdhbiBkYXRvcyBudWV2b3MuCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IENvbmNsdXNpw7NuIDwvc3Bhbj4KCkxhcyB2ZW50YXMgZGUgVmludGFnZSB0aWVuZW4gdW5hIGVzdGFjaW9uYWxpZGFkIGZ1ZXJ0ZSAoYWx0YSBlbiBpbnZpZXJubywgYmFqYSBlbiB2ZXJhbm8pIHNvYnJlIHVuYSB0ZW5kZW5jaWEgY3JlY2llbnRlLiBMb3MgZG9zIG3DqXRvZG9zIGRhbiBwcm9uw7NzdGljb3MgbXV5IHBhcmVjaWRvcyB5IGVsIGRlIGVuZXJvIHByw6FjdGljYW1lbnRlIGNvaW5jaWRlIGNvbiBlbCByZWFsICgkMjk5IG1pbCB2cyAkMjk1IG1pbCksIGFzw60gcXVlIGVsIHByb2NlZGltaWVudG8gZXMgY29uZmlhYmxlLiBMYSByZWNvbWVuZGFjacOzbiBwYXJhIEthcmVuIGVzIHBsYW5lYXIgcGVyc29uYWwgZSBpbnZlbnRhcmlvIHNlZ8O6biBsb3Mgw61uZGljZXM6IHJlZm9yemFyIGRlIGRpY2llbWJyZSBhIG1hcnpvIHkgYWxpZ2VyYXIgZW4gdmVyYW5vLgoKIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IEVqZXJjaWNpbyA0LiBDYXJsc29uIERlcGFydG1lbnQgU3RvcmUgPC9zcGFuPgoKVW4gaHVyYWPDoW4gYXpvdMOzIGVsIDIxIGRlIGFnb3N0byB5IENhcmxzb24gY2VycsOzIGRlIHNlcHRpZW1icmUgYSBkaWNpZW1icmUuIEhheSBxdWUgZXN0aW1hciBjdcOhbnRvIGhhYnLDrWEgdmVuZGlkbyBsYSB0aWVuZGEgeSBlbCBjb25kYWRvIHNpbiBlbCBodXJhY8OhbiwgbGEgcMOpcmRpZGEgZGUgQ2FybHNvbiwgeSBzaSBodWJvIHVuIGV4Y2VzbyBkZSB2ZW50YXMgcG9yIGVsIGh1cmFjw6FuLiBUZW5nbyA0OCBtZXNlcyBwcmV2aW9zIGFsIGNpZXJyZSAoZGUgc2VwdGllbWJyZSBkZWwgQcOxbyAxIGEgYWdvc3RvIGRlbCBBw7FvIDUpLgoKYGBge3IgY2FybHNvbi1kYXRvc30KIyBUYWJsYSAxOC4yNyDigJMgdmVudGFzIENhcmxzb24gKCQgbWlsbG9uZXMpLCBkZXNkZSBTZXAgQcOxbzEKY2FybHNvbiA8LSBjKDEuNzEsMS45MCwyLjc0LDQuMjAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBBw7FvMSBTZXAtRGljCiAgICAgICAgICAgICAxLjQ1LDEuODAsMi4wMywxLjk5LDIuMzIsMi4yMCwyLjEzLDIuNDMsMS45MCwyLjEzLDIuNTYsNC4xNiwgICAgICMgQcOxbzIKICAgICAgICAgICAgIDIuMzEsMS44OSwyLjAyLDIuMjMsMi4zOSwyLjE0LDIuMjcsMi4yMSwxLjg5LDIuMjksMi44Myw0LjA0LCAgICAgIyBBw7FvMwogICAgICAgICAgICAgMi4zMSwxLjk5LDIuNDIsMi40NSwyLjU3LDIuNDIsMi40MCwyLjUwLDIuMDksMi41NCwyLjk3LDQuMzUsICAgICAjIEHDsW80CiAgICAgICAgICAgICAyLjU2LDIuMjgsMi42OSwyLjQ4LDIuNzMsMi4zNywyLjMxLDIuMjMpICAgICAgICAgICAgICAgICAgICAgICAgICMgQcOxbzUgRW5lLUFnbwoKIyBUYWJsYSAxOC4yOCDigJMgdmVudGFzIGRlbCBjb25kYWRvICgkIG1pbGxvbmVzKSwgbWlzbW9zIDQ4IG1lc2VzCmNvbmRhZG8gPC0gYyg1NS44MCw1Ni40MCw3MS40MCwxMTcuNjAsCiAgICAgICAgICAgICA0Ni44MCw0OC4wMCw2MC4wMCw1Ny42MCw2MS44MCw1OC4yMCw1Ni40MCw2My4wMCw1Ny42MCw1My40MCw3MS40MCwxMTQuMDAsCiAgICAgICAgICAgICA0Ni44MCw0OC42MCw1OS40MCw1OC4yMCw2MC42MCw1NS4yMCw1MS4wMCw1OC44MCw0OS44MCw1NC42MCw2NS40MCwxMDIuMDAsCiAgICAgICAgICAgICA0My44MCw0NS42MCw1Ny42MCw1My40MCw1Ni40MCw1Mi44MCw1NC4wMCw2MC42MCw0Ny40MCw1NC42MCw2Ny44MCwxMDAuMjAsCiAgICAgICAgICAgICA0OC4wMCw1MS42MCw1Ny42MCw1OC4yMCw2MC4wMCw1Ny4wMCw1Ny42MCw2MS44MCkKCiMgVmVudGFzIHJlYWxlcyBkZWwgY29uZGFkbyBkdXJhbnRlIGVsIGNpZXJyZSAoU2VwLURpYyBBw7FvNSkKY29uZGFkb19yZWFsIDwtIGMoNjkuMDAsIDc1LjAwLCA4NS4yMCwgMTIxLjgwKQpgYGAKCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4gMSB5IDIuIFZlbnRhcyBlc3RpbWFkYXMgc2luIGh1cmFjw6FuIDwvc3Bhbj4KCmBgYHtyIGNhcmxzb24tcHJvbn0KZEMgPC0gZGVzY29tcF9tdWx0KGNhcmxzb24sIG1lc19pbmljaW8gPSA5KSAgICMgZW1waWV6YSBlbiBzZXB0aWVtYnJlCmRLIDwtIGRlc2NvbXBfbXVsdChjb25kYWRvLCBtZXNfaW5pY2lvID0gOSkKCnRfY2llcnJlICAgICA8LSA0OTo1MiAgICAgICAgICAgICAgICAgICAgICAgICAgIyBTZXAsIE9jdCwgTm92LCBEaWMgZGVsIEHDsW8gNQpwcm9uX2Nhcmxzb24gPC0gYXMubnVtZXJpYyhwcm9uX2Rlc2NvbXAodF9jaWVycmUsIDksIGRDJHRlbmQsIGRDJElFKSkKcHJvbl9jb25kYWRvIDwtIGFzLm51bWVyaWMocHJvbl9kZXNjb21wKHRfY2llcnJlLCA5LCBkSyR0ZW5kLCBkSyRJRSkpCgp0YWJsYV9jIDwtIGRhdGEuZnJhbWUoCiAgTWVzICAgICAgICAgICAgICA9IGMoIlNlcHRpZW1icmUiLCJPY3R1YnJlIiwiTm92aWVtYnJlIiwiRGljaWVtYnJlIiksCiAgQ2FybHNvbl9lc3RpbWFkbyA9IHJvdW5kKHByb25fY2FybHNvbiwgMyksCiAgQ29uZGFkb19lc3RpbWFkbyA9IHJvdW5kKHByb25fY29uZGFkbywgMiksCiAgQ29uZGFkb19yZWFsICAgICA9IGNvbmRhZG9fcmVhbAopCmtuaXRyOjprYWJsZSh0YWJsYV9jLCBjYXB0aW9uID0gIkVzdGltYWRvIHNpbiBodXJhY8OhbiB2cyByZWFsIGRlbCBjb25kYWRvICgkIG1pbGxvbmVzKSIpCmBgYAoKIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPiAzLiBQw6lyZGlkYSBkZSB2ZW50YXMgZGUgQ2FybHNvbiA8L3NwYW4+CgpgYGB7ciBjYXJsc29uLXBlcmRpZGF9CnBlcmRpZGEgPC0gc3VtKHByb25fY2FybHNvbikKcGVyZGlkYQpgYGAKCkxhIHDDqXJkaWRhIGRlIHZlbnRhcyBkZSBDYXJsc29uIGRlIHNlcHRpZW1icmUgYSBkaWNpZW1icmUgZXMgZGUgYXByb3guICoqJGByIHJvdW5kKHBlcmRpZGEsMilgIG1pbGxvbmVzKiouCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IDQuIEV4Y2VzbyBkZSB2ZW50YXMgcG9yIGVsIGh1cmFjw6FuIDwvc3Bhbj4KCmBgYHtyIGNhcmxzb24tZXhjZXNvfQpleGNlc29fY29uZGFkbyA8LSBzdW0oY29uZGFkb19yZWFsKSAtIHN1bShwcm9uX2NvbmRhZG8pCnBhcnRpY2lwICAgICAgIDwtIG1lYW4oY2FybHNvbiAvIGNvbmRhZG8pCmV4Y2Vzb19jYXJsc29uIDwtIHBhcnRpY2lwICogZXhjZXNvX2NvbmRhZG8KCmRhdGEuZnJhbWUoCiAgQ29uZGFkb19lc3RpbWFkbyA9IHJvdW5kKHN1bShwcm9uX2NvbmRhZG8pLCAyKSwKICBDb25kYWRvX3JlYWwgICAgID0gc3VtKGNvbmRhZG9fcmVhbCksCiAgRXhjZXNvX2NvbmRhZG8gICA9IHJvdW5kKGV4Y2Vzb19jb25kYWRvLCAyKSwKICBQYXJ0aWNpcF9DYXJsc29uID0gcm91bmQocGFydGljaXAsIDQpLAogIEV4Y2Vzb19DYXJsc29uICAgPSByb3VuZChleGNlc29fY2FybHNvbiwgMykKKQpgYGAKCkxhcyB2ZW50YXMgcmVhbGVzIGRlbCBjb25kYWRvIGR1cmFudGUgZWwgY2llcnJlICgkYHIgc3VtKGNvbmRhZG9fcmVhbClgIG1pbGxvbmVzKSBzb24gbXVjaG8gbWF5b3JlcyBxdWUgbGFzIGVzcGVyYWRhcyBzaW4gaHVyYWPDoW4gKCRgciByb3VuZChzdW0ocHJvbl9jb25kYWRvKSwyKWAgbWlsbG9uZXMpLCB1biBleGNlc28gZGUgYXByb3guICRgciByb3VuZChleGNlc29fY29uZGFkbywyKWAgbWlsbG9uZXMgcG9yIGxhIGF5dWRhIGZlZGVyYWwgeSBsb3Mgc2VndXJvcy4gQ29tbyBDYXJsc29uIHJlcHJlc2VudGEgZW4gcHJvbWVkaW8gZWwgYHIgcm91bmQocGFydGljaXAqMTAwLDIpYCUgZGVsIGNvbmRhZG8sIGxlIGhhYnLDrWEgdG9jYWRvIHVuYSBwYXJ0ZSBkZSBlc2UgZXhjZXNvOiBhbHJlZGVkb3IgZGUgKiokYHIgcm91bmQoZXhjZXNvX2Nhcmxzb24sMylgIG1pbGxvbmVzKiouCgojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+IENvbmNsdXNpw7NuIDwvc3Bhbj4KCkNvbiBsb3MgNDggbWVzZXMgcHJldmlvcyBlc3RpbW8gcXVlIENhcmxzb24gcGVyZGnDsyBjZXJjYSBkZSAkMTIuNCBtaWxsb25lcyBkdXJhbnRlIGVsIGNpZXJyZS4gQWRlbcOhcywgZWwgY29uZGFkbyB2ZW5kacOzIGFscmVkZWRvciBkZSAkNzcgbWlsbG9uZXMgcG9yIGVuY2ltYSBkZSBsbyBub3JtYWwgZGVzcHXDqXMgZGVsIGh1cmFjw6FuLCB5IGNvbW8gQ2FybHNvbiBwYXJ0aWNpcGFiYSBjb24gfjQlIGRlbCBjb25kYWRvLCB0aWVuZSBiYXNlcyBwYXJhIHJlY2xhbWFyIHVub3MgJDMuMSBtaWxsb25lcyBtw6FzIHBvciBlbCBleGNlc28gcXVlIGhhYnLDrWEgY2FwdHVyYWRvIHNpIGh1YmllcmEgZXN0YWRvIGFiaWVydGEuIExlIGNvbnZpZW5lIHN1c3RlbnRhciBhbWJhcyBjaWZyYXMgYW50ZSBsYSBhc2VndXJhZG9yYS4K