library(forecast)
library(tidyverse)
library(maps)

Descarga de archivo

poblacion <- read.csv("C:/Users/Adrian Quezada/Downloads/population.csv")

Entender la base de datos

summary(poblacion)
##     state                year        population      
##  Length:6020        Min.   :1900   Min.   :   43000  
##  Class :character   1st Qu.:1930   1st Qu.:  901483  
##  Mode  :character   Median :1960   Median : 2359000  
##                     Mean   :1960   Mean   : 3726003  
##                     3rd Qu.:1990   3rd Qu.: 4541883  
##                     Max.   :2019   Max.   :39512223
str(poblacion)
## 'data.frame':    6020 obs. of  3 variables:
##  $ state     : chr  "AK" "AK" "AK" "AK" ...
##  $ year      : int  1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 ...
##  $ population: int  135000 158000 189000 205000 215000 222000 224000 231000 224000 224000 ...
head(poblacion)
##   state year population
## 1    AK 1950     135000
## 2    AK 1951     158000
## 3    AK 1952     189000
## 4    AK 1953     205000
## 5    AK 1954     215000
## 6    AK 1955     222000

Serie de tiempo en Texas

poblacion_texas <- poblacion %>% filter(state=="TX")
ggplot(poblacion_texas, aes(x = year, y= population)) + geom_line() +
  labs(title = "Poblacion de Texas", x = "Año", y = "Población")

ts_texas <- ts(poblacion_texas$population, start = 1900, frequency = 1) # serie de tiempo anual

#ts_texas <- ts(poblacion_texas$population, start = c(1900, 4), frequency = 4) # serie de tiempo trumestral

#ts_texas <- ts(poblacion_texas$population, start = c(1900, 8), frequency = 12) # serie de tiempo Mensual

ts_texas
## Time Series:
## Start = 1900 
## End = 2019 
## Frequency = 1 
##   [1]  3055000  3132000  3210000  3291000  3374000  3459000  3546000  3636000
##   [9]  3727000  3821000  3922000  4016000  4107000  4207000  4300000  4368000
##  [17]  4444000  4563000  4666000  4631000  4723000  4853000  4955000  5077000
##  [25]  5210000  5332000  5453000  5577000  5675000  5762000  5844000  5907000
##  [33]  5961000  6014000  6053000  6123000  6192000  6250000  6301000  6360000
##  [41]  6425000  6585000  6711000  7012000  6876000  6826000  7197000  7388000
##  [49]  7626000  7623000  7776000  8111000  8314000  8336000  8382000  8660000
##  [57]  8830000  9070000  9252000  9405000  9624000  9820000 10053000 10159000
##  [65] 10270000 10378000 10492000 10599000 10819000 11045000 11198655 11509848
##  [73] 11759148 12019543 12268629 12568843 12904089 13193050 13500429 13888371
##  [81] 14338208 14746318 15331415 15751676 16007086 16272734 16561113 16621791
##  [89] 16667022 16806735 17044714 17339904 17650479 17996764 18338319 18679706
##  [97] 19006240 19355427 19712389 20044141 20944499 21319622 21690325 22030931
## [105] 22394023 22778123 23359580 23831983 24309039 24801761 25241971 25645629
## [113] 26084481 26480266 26964333 27470056 27914410 28295273 28628666 28995881
arima_texas <- auto.arima(ts_texas)
summary(arima_texas)
## Series: ts_texas 
## ARIMA(0,2,2) 
## 
## Coefficients:
##           ma1      ma2
##       -0.5950  -0.1798
## s.e.   0.0913   0.0951
## 
## sigma^2 = 1.031e+10:  log likelihood = -1527.14
## AIC=3060.28   AICc=3060.5   BIC=3068.6
## 
## Training set error measures:
##                    ME     RMSE      MAE       MPE      MAPE      MASE
## Training set 12147.62 99818.31 59257.39 0.1046163 0.5686743 0.2672197
##                     ACF1
## Training set -0.02136734
pronostico_texas <- forecast((arima_texas), level = 95, h = 10)
pronostico_texas
##      Point Forecast    Lo 95    Hi 95
## 2020       29398472 29199487 29597457
## 2021       29806827 29463665 30149990
## 2022       30215183 29742956 30687410
## 2023       30623538 30024100 31222977
## 2024       31031894 30303359 31760429
## 2025       31440249 30579246 32301253
## 2026       31848605 30851090 32846119
## 2027       32256960 31118581 33395339
## 2028       32665316 31381587 33949044
## 2029       33073671 31640070 34507272
plot(pronostico_texas, main= "Poblacion en Texas")

#Ejercicio en clase Lunes 17

Crear Mapa

## Crear Mapa de EUA por decada, con un gradiente de verde a rojo de la poblacion por estado desde 1950 hasta 2050

map(database = "state")
map(database = "state", regions = "Texas", col = "red", fill = TRUE, add = TRUE)
map(database = "state", regions = "New York", col = "green", fill = TRUE, add = TRUE)

library(ggplot2)
library(dplyr)
library(maps)
library(viridis)
## Cargando paquete requerido: viridisLite
## 
## Adjuntando el paquete: 'viridis'
## The following object is masked from 'package:maps':
## 
##     unemp
library(tidyr)

# Crear un dataframe con los nombres completos de los estados
state_names <- data.frame(
  state = state.abb,
  region = tolower(state.name)
)

# Unir los nombres completos al dataframe original
poblacion <- poblacion %>%
  left_join(state_names, by = "state")

# Pronóstico de población para años futuros (hasta 2050)
futuro <- poblacion %>%
  group_by(region) %>%
  do({
    modelo <- lm(population ~ year, data = .)
    años_futuros <- data.frame(year = seq(2020, 2050, by = 10))
    predicciones <- predict(modelo, newdata = años_futuros)
    data.frame(region = unique(.$region), year = años_futuros$year, population = predicciones)
  })

# Unir las proyecciones al dataset original
poblacion_completa <- bind_rows(poblacion, futuro)

# Filtrar solo las décadas
poblacion_decadas <- poblacion_completa %>%
  filter(year %% 10 == 0 & year >= 1950 & year <= 2050)

# Obtener datos del mapa de EE. UU.
states_map <- map_data("state")

# Unir el mapa con los datos de población
map_data_pop <- left_join(states_map, poblacion_decadas, by = "region")
## Warning in left_join(states_map, poblacion_decadas, by = "region"): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 1 of `x` matches multiple rows in `y`.
## ℹ Row 8 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
##   "many-to-many"` to silence this warning.
# Crear el mapa
ggplot(map_data_pop, aes(x = long, y = lat, group = group, fill = population)) +
  geom_polygon(color = "white") +
  coord_fixed(1.3) +
  scale_fill_gradient(low = "green", high = "red", name = "Población") +
  facet_wrap(~year) +
  labs(title = "Población de Estados Unidos por Estado (1950-2050) con Proyecciones",
       x = "Longitud", y = "Latitud") +
  theme_minimal()

Act 2 lechitas Hersheys

library(ggplot2)
library(tidyverse)
library(forecast)

Importar la base de datos

library(readxl)
ventas <- read_excel("C:/Users/Adrian Quezada/Downloads/Ventas_Históricas_Lechitas.xlsx")

1. Modelo AutoARIMA

ts_ventas<-ts(ventas$Ventas, start = c(2017,1), frequency=12) 
autoplot(ts_ventas) + labs(title= "Ventas de Leche Saborizada Hershey's", x="Tiempo", y=" Miles de dolares")

arima_ventas<-auto.arima(ts_ventas)
summary(arima_ventas)
## Series: ts_ventas 
## ARIMA(1,0,0)(1,1,0)[12] with drift 
## 
## Coefficients:
##          ar1     sar1     drift
##       0.6383  -0.5517  288.8979
## s.e.  0.1551   0.2047   14.5026
## 
## sigma^2 = 202701:  log likelihood = -181.5
## AIC=371   AICc=373.11   BIC=375.72
## 
## Training set error measures:
##                    ME    RMSE    MAE        MPE      MAPE       MASE      ACF1
## Training set 25.22158 343.864 227.17 0.08059932 0.7069542 0.06491044 0.2081026
pronostico_ventas<-(forecast(arima_ventas,level=95,h=12)) #Pronostico a 10 años h
pronostico_ventas
##          Point Forecast    Lo 95    Hi 95
## Jan 2020       35498.90 34616.48 36381.32
## Feb 2020       34202.17 33155.28 35249.05
## Mar 2020       36703.01 35596.10 37809.92
## Apr 2020       36271.90 35141.44 37402.36
## May 2020       37121.98 35982.07 38261.90
## Jun 2020       37102.65 35958.90 38246.40
## Jul 2020       37151.04 36005.73 38296.34
## Aug 2020       38564.64 37418.70 39710.58
## Sep 2020       38755.22 37609.03 39901.42
## Oct 2020       39779.02 38632.72 40925.32
## Nov 2020       38741.63 37595.28 39887.97
## Dec 2020       38645.86 37499.50 39792.22
autoplot(pronostico_ventas) + labs(title= "Pronóstico de ventas 2020 de Leche Saborizada Hershey's", x="Timepo", y="Miles de Dólares")

2. Modelo regresión lineal

ventas$Mes <- 1:36
regresion_ventas<-lm(Ventas ~ Mes, data = ventas)
summary(regresion_ventas)
## 
## Call:
## lm(formula = Ventas ~ Mes, data = ventas)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2075.79  -326.41    33.74   458.40  1537.04 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 24894.67     275.03   90.52   <2e-16 ***
## Mes           298.37      12.96   23.02   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 808 on 34 degrees of freedom
## Multiple R-squared:  0.9397, Adjusted R-squared:  0.9379 
## F-statistic: 529.8 on 1 and 34 DF,  p-value: < 2.2e-16
siguiente_anio <- data.frame(Mes=37:48)
prediccion_regresion <- predict(regresion_ventas, siguiente_anio)
prediccion_regresion
##        1        2        3        4        5        6        7        8 
## 35934.49 36232.86 36531.23 36829.61 37127.98 37426.35 37724.73 38023.10 
##        9       10       11       12 
## 38321.47 38619.85 38918.22 39216.59
plot(ventas$Mes, ventas$Ventas, main= "Pronóstico de ventas 2020 de Leche Saborizada Hershey's", xlab = "Timepo", ylab ="Miles de Dólares" )
abline(regresion_ventas, col = "blue")
points(siguiente_anio$Mes, prediccion_regresion, col = "red")

prediccion_reales <- predict(regresion_ventas, ventas)
MAPE <- mean(abs((ventas$Ventas - 
                    prediccion_reales)/ventas$Ventas))*100
MAPE
## [1] 2.011297

3. Conclusiones

El mejor modelo que se adapta a la serie es el SARIMA con un MAPE de 0.70, comparado con la regresion lineal que su MAPE es 2.01%

Para el siguiente año, la predicción de ventas es la siguiente

Mes-Año Ecs.Esperado Ecs.Pesimista Ecs.Optimista

Jan 2020 | 35498.90 | 34616.48 | 36381.32
Feb 2020 | 34202.17 | 33155.28 | 35249.05
Mar 2020 | 36703.01 | 35596.10 | 37809.92
Apr 2020 | 36271.90 | 35141.44 | 37402.36
May 2020 | 37121.98 | 35982.07 | 38261.90
Jun 2020 | 37102.65 | 35958.90 | 38246.40
Jul 2020 | 37151.04 | 36005.73 | 38296.34
Aug 2020 | 38564.64 | 37418.70 | 39710.58
Sep 2020 | 38755.22 | 37609.03 | 39901.42
Oct 202 | 39779.02 | 38632.72 | 40925.32
Nov 2020 | 38741.63 | 37595.28 | 39887.97
Dec 2020 | 38645.86 | 37499.50 | 39792.22

ventas_por_anio <- read.csv("C:/Users/Adrian Quezada/Downloads/ventas_por_anio (2).csv")
ggplot(ventas_por_anio, aes(x = mes, y = ventas, col= as.factor(anio), 
                            group = anio)) + geom_line() + labs(title = "Ventas de leche saborizada Hershey´s por Año", x= "MES", y= "Ventas")

Nuestra recomendación seria realizar campañas publicitatias para aumentar el consumo de leche saborizada Hersheys para los meses de invierno con climas frios

LS0tDQp0aXRsZTogIkFjdGl2aWRhZCAyIg0KYXV0aG9yOiAiQWRyaWFuIFF1ZXphZGEiDQpkYXRlOiAiMjAyNS0wMi0xNyINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiBUUlVFDQogICAgdG9jX2Zsb2F0OiBUUlVFDQogICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgIHRoZW1lOiBjZXJ1bGVhbg0KICAgIA0KLS0tDQoNCiFbXShDOi9Vc2Vycy9BZHJpYW4gUXVlemFkYS9Eb3dubG9hZHMvcG9ibGFjaW9uLmdpZikNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobWFwcykNCmBgYA0KDQoNCiMjIERlc2NhcmdhIGRlIGFyY2hpdm8NCmBgYHtyfQ0KcG9ibGFjaW9uIDwtIHJlYWQuY3N2KCJDOi9Vc2Vycy9BZHJpYW4gUXVlemFkYS9Eb3dubG9hZHMvcG9wdWxhdGlvbi5jc3YiKQ0KYGBgDQoNCg0KIyMgRW50ZW5kZXIgbGEgYmFzZSBkZSBkYXRvcw0KYGBge3J9DQpzdW1tYXJ5KHBvYmxhY2lvbikNCnN0cihwb2JsYWNpb24pDQpoZWFkKHBvYmxhY2lvbikNCmBgYA0KDQojIyBTZXJpZSBkZSB0aWVtcG8gZW4gVGV4YXMNCmBgYHtyfQ0KcG9ibGFjaW9uX3RleGFzIDwtIHBvYmxhY2lvbiAlPiUgZmlsdGVyKHN0YXRlPT0iVFgiKQ0KZ2dwbG90KHBvYmxhY2lvbl90ZXhhcywgYWVzKHggPSB5ZWFyLCB5PSBwb3B1bGF0aW9uKSkgKyBnZW9tX2xpbmUoKSArDQogIGxhYnModGl0bGUgPSAiUG9ibGFjaW9uIGRlIFRleGFzIiwgeCA9ICJBw7FvIiwgeSA9ICJQb2JsYWNpw7NuIikNCg0KdHNfdGV4YXMgPC0gdHMocG9ibGFjaW9uX3RleGFzJHBvcHVsYXRpb24sIHN0YXJ0ID0gMTkwMCwgZnJlcXVlbmN5ID0gMSkgIyBzZXJpZSBkZSB0aWVtcG8gYW51YWwNCg0KI3RzX3RleGFzIDwtIHRzKHBvYmxhY2lvbl90ZXhhcyRwb3B1bGF0aW9uLCBzdGFydCA9IGMoMTkwMCwgNCksIGZyZXF1ZW5jeSA9IDQpICMgc2VyaWUgZGUgdGllbXBvIHRydW1lc3RyYWwNCg0KI3RzX3RleGFzIDwtIHRzKHBvYmxhY2lvbl90ZXhhcyRwb3B1bGF0aW9uLCBzdGFydCA9IGMoMTkwMCwgOCksIGZyZXF1ZW5jeSA9IDEyKSAjIHNlcmllIGRlIHRpZW1wbyBNZW5zdWFsDQoNCnRzX3RleGFzDQoNCmBgYA0KYGBge3J9DQoNCmBgYA0KDQoNCmBgYHtyfQ0KYXJpbWFfdGV4YXMgPC0gYXV0by5hcmltYSh0c190ZXhhcykNCnN1bW1hcnkoYXJpbWFfdGV4YXMpDQpwcm9ub3N0aWNvX3RleGFzIDwtIGZvcmVjYXN0KChhcmltYV90ZXhhcyksIGxldmVsID0gOTUsIGggPSAxMCkNCnByb25vc3RpY29fdGV4YXMNCnBsb3QocHJvbm9zdGljb190ZXhhcywgbWFpbj0gIlBvYmxhY2lvbiBlbiBUZXhhcyIpDQoNCmBgYA0KDQojRWplcmNpY2lvIGVuIGNsYXNlIEx1bmVzIDE3DQoNCiMjIENyZWFyIE1hcGEgDQoNCmBgYHtyfQ0KDQojIyBDcmVhciBNYXBhIGRlIEVVQSBwb3IgZGVjYWRhLCBjb24gdW4gZ3JhZGllbnRlIGRlIHZlcmRlIGEgcm9qbyBkZSBsYSBwb2JsYWNpb24gcG9yIGVzdGFkbyBkZXNkZSAxOTUwIGhhc3RhIDIwNTANCg0KbWFwKGRhdGFiYXNlID0gInN0YXRlIikNCm1hcChkYXRhYmFzZSA9ICJzdGF0ZSIsIHJlZ2lvbnMgPSAiVGV4YXMiLCBjb2wgPSAicmVkIiwgZmlsbCA9IFRSVUUsIGFkZCA9IFRSVUUpDQptYXAoZGF0YWJhc2UgPSAic3RhdGUiLCByZWdpb25zID0gIk5ldyBZb3JrIiwgY29sID0gImdyZWVuIiwgZmlsbCA9IFRSVUUsIGFkZCA9IFRSVUUpDQoNCmBgYA0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShtYXBzKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeSh0aWR5cikNCg0KIyBDcmVhciB1biBkYXRhZnJhbWUgY29uIGxvcyBub21icmVzIGNvbXBsZXRvcyBkZSBsb3MgZXN0YWRvcw0Kc3RhdGVfbmFtZXMgPC0gZGF0YS5mcmFtZSgNCiAgc3RhdGUgPSBzdGF0ZS5hYmIsDQogIHJlZ2lvbiA9IHRvbG93ZXIoc3RhdGUubmFtZSkNCikNCg0KIyBVbmlyIGxvcyBub21icmVzIGNvbXBsZXRvcyBhbCBkYXRhZnJhbWUgb3JpZ2luYWwNCnBvYmxhY2lvbiA8LSBwb2JsYWNpb24gJT4lDQogIGxlZnRfam9pbihzdGF0ZV9uYW1lcywgYnkgPSAic3RhdGUiKQ0KDQojIFByb27Ds3N0aWNvIGRlIHBvYmxhY2nDs24gcGFyYSBhw7FvcyBmdXR1cm9zIChoYXN0YSAyMDUwKQ0KZnV0dXJvIDwtIHBvYmxhY2lvbiAlPiUNCiAgZ3JvdXBfYnkocmVnaW9uKSAlPiUNCiAgZG8oew0KICAgIG1vZGVsbyA8LSBsbShwb3B1bGF0aW9uIH4geWVhciwgZGF0YSA9IC4pDQogICAgYcOxb3NfZnV0dXJvcyA8LSBkYXRhLmZyYW1lKHllYXIgPSBzZXEoMjAyMCwgMjA1MCwgYnkgPSAxMCkpDQogICAgcHJlZGljY2lvbmVzIDwtIHByZWRpY3QobW9kZWxvLCBuZXdkYXRhID0gYcOxb3NfZnV0dXJvcykNCiAgICBkYXRhLmZyYW1lKHJlZ2lvbiA9IHVuaXF1ZSguJHJlZ2lvbiksIHllYXIgPSBhw7Fvc19mdXR1cm9zJHllYXIsIHBvcHVsYXRpb24gPSBwcmVkaWNjaW9uZXMpDQogIH0pDQoNCiMgVW5pciBsYXMgcHJveWVjY2lvbmVzIGFsIGRhdGFzZXQgb3JpZ2luYWwNCnBvYmxhY2lvbl9jb21wbGV0YSA8LSBiaW5kX3Jvd3MocG9ibGFjaW9uLCBmdXR1cm8pDQoNCiMgRmlsdHJhciBzb2xvIGxhcyBkw6ljYWRhcw0KcG9ibGFjaW9uX2RlY2FkYXMgPC0gcG9ibGFjaW9uX2NvbXBsZXRhICU+JQ0KICBmaWx0ZXIoeWVhciAlJSAxMCA9PSAwICYgeWVhciA+PSAxOTUwICYgeWVhciA8PSAyMDUwKQ0KDQojIE9idGVuZXIgZGF0b3MgZGVsIG1hcGEgZGUgRUUuIFVVLg0Kc3RhdGVzX21hcCA8LSBtYXBfZGF0YSgic3RhdGUiKQ0KDQojIFVuaXIgZWwgbWFwYSBjb24gbG9zIGRhdG9zIGRlIHBvYmxhY2nDs24NCm1hcF9kYXRhX3BvcCA8LSBsZWZ0X2pvaW4oc3RhdGVzX21hcCwgcG9ibGFjaW9uX2RlY2FkYXMsIGJ5ID0gInJlZ2lvbiIpDQoNCiMgQ3JlYXIgZWwgbWFwYQ0KZ2dwbG90KG1hcF9kYXRhX3BvcCwgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwLCBmaWxsID0gcG9wdWxhdGlvbikpICsNCiAgZ2VvbV9wb2x5Z29uKGNvbG9yID0gIndoaXRlIikgKw0KICBjb29yZF9maXhlZCgxLjMpICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiZ3JlZW4iLCBoaWdoID0gInJlZCIsIG5hbWUgPSAiUG9ibGFjacOzbiIpICsNCiAgZmFjZXRfd3JhcCh+eWVhcikgKw0KICBsYWJzKHRpdGxlID0gIlBvYmxhY2nDs24gZGUgRXN0YWRvcyBVbmlkb3MgcG9yIEVzdGFkbyAoMTk1MC0yMDUwKSBjb24gUHJveWVjY2lvbmVzIiwNCiAgICAgICB4ID0gIkxvbmdpdHVkIiwgeSA9ICJMYXRpdHVkIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KDQpgYGANCg0KDQojIyAgPHNwYW4gc3R5bGU9ImNvbG9yIDogYnJvd247Ij4gQWN0IDIgbGVjaGl0YXMgSGVyc2hleXMgPC9zcGFuPg0KDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KYGBgDQoNCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3IgOiBicm93bjsiPiBJbXBvcnRhciBsYSBiYXNlIGRlIGRhdG9zIDwvc3Bhbj4NCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCnZlbnRhcyA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9BZHJpYW4gUXVlemFkYS9Eb3dubG9hZHMvVmVudGFzX0hpc3TDs3JpY2FzX0xlY2hpdGFzLnhsc3giKQ0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPjEuIE1vZGVsbyBBdXRvQVJJTUE8L3NwYW4+DQpgYGB7cn0NCnRzX3ZlbnRhczwtdHModmVudGFzJFZlbnRhcywgc3RhcnQgPSBjKDIwMTcsMSksIGZyZXF1ZW5jeT0xMikgDQphdXRvcGxvdCh0c192ZW50YXMpICsgbGFicyh0aXRsZT0gIlZlbnRhcyBkZSBMZWNoZSBTYWJvcml6YWRhIEhlcnNoZXkncyIsIHg9IlRpZW1wbyIsIHk9IiBNaWxlcyBkZSBkb2xhcmVzIikNCg0KYXJpbWFfdmVudGFzPC1hdXRvLmFyaW1hKHRzX3ZlbnRhcykNCnN1bW1hcnkoYXJpbWFfdmVudGFzKQ0KDQpwcm9ub3N0aWNvX3ZlbnRhczwtKGZvcmVjYXN0KGFyaW1hX3ZlbnRhcyxsZXZlbD05NSxoPTEyKSkgI1Byb25vc3RpY28gYSAxMCBhw7FvcyBoDQpwcm9ub3N0aWNvX3ZlbnRhcw0KYXV0b3Bsb3QocHJvbm9zdGljb192ZW50YXMpICsgbGFicyh0aXRsZT0gIlByb27Ds3N0aWNvIGRlIHZlbnRhcyAyMDIwIGRlIExlY2hlIFNhYm9yaXphZGEgSGVyc2hleSdzIiwgeD0iVGltZXBvIiwgeT0iTWlsZXMgZGUgRMOzbGFyZXMiKQ0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOiBicm93bjsiPjIuIE1vZGVsbyByZWdyZXNpw7NuIGxpbmVhbDwvc3Bhbj4NCmBgYHtyfQ0KdmVudGFzJE1lcyA8LSAxOjM2DQpyZWdyZXNpb25fdmVudGFzPC1sbShWZW50YXMgfiBNZXMsIGRhdGEgPSB2ZW50YXMpDQpzdW1tYXJ5KHJlZ3Jlc2lvbl92ZW50YXMpDQoNCnNpZ3VpZW50ZV9hbmlvIDwtIGRhdGEuZnJhbWUoTWVzPTM3OjQ4KQ0KcHJlZGljY2lvbl9yZWdyZXNpb24gPC0gcHJlZGljdChyZWdyZXNpb25fdmVudGFzLCBzaWd1aWVudGVfYW5pbykNCnByZWRpY2Npb25fcmVncmVzaW9uDQoNCnBsb3QodmVudGFzJE1lcywgdmVudGFzJFZlbnRhcywgbWFpbj0gIlByb27Ds3N0aWNvIGRlIHZlbnRhcyAyMDIwIGRlIExlY2hlIFNhYm9yaXphZGEgSGVyc2hleSdzIiwgeGxhYiA9ICJUaW1lcG8iLCB5bGFiID0iTWlsZXMgZGUgRMOzbGFyZXMiICkNCmFibGluZShyZWdyZXNpb25fdmVudGFzLCBjb2wgPSAiYmx1ZSIpDQpwb2ludHMoc2lndWllbnRlX2FuaW8kTWVzLCBwcmVkaWNjaW9uX3JlZ3Jlc2lvbiwgY29sID0gInJlZCIpDQoNCnByZWRpY2Npb25fcmVhbGVzIDwtIHByZWRpY3QocmVncmVzaW9uX3ZlbnRhcywgdmVudGFzKQ0KTUFQRSA8LSBtZWFuKGFicygodmVudGFzJFZlbnRhcyAtIA0KICAgICAgICAgICAgICAgICAgICBwcmVkaWNjaW9uX3JlYWxlcykvdmVudGFzJFZlbnRhcykpKjEwMA0KTUFQRQ0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjogYnJvd247Ij4zLiBDb25jbHVzaW9uZXM8L3NwYW4+DQpFbCBtZWpvciBtb2RlbG8gcXVlIHNlIGFkYXB0YSBhIGxhIHNlcmllIGVzIGVsICoqU0FSSU1BKiogY29uIHVuIE1BUEUgZGUgMC43MCwgY29tcGFyYWRvIGNvbiBsYSByZWdyZXNpb24gbGluZWFsIHF1ZSBzdSBNQVBFIGVzIDIuMDElDQoNClBhcmEgZWwgc2lndWllbnRlIGHDsW8sIGxhIHByZWRpY2Npw7NuIGRlIHZlbnRhcyBlcyBsYSBzaWd1aWVudGUNCg0KDQpNZXMtQcOxbyAgICAgIEVjcy5Fc3BlcmFkbyAgICAgRWNzLlBlc2ltaXN0YSAgICAgRWNzLk9wdGltaXN0YQ0KDQpKYW4gMjAyMCAgfCAgCTM1NDk4LjkwICAgIHwgICAgCTM0NjE2LjQ4ICAgICB8ICAgCTM2MzgxLjMyCQ0KRmViIDIwMjAgIHwgIAkzNDIwMi4xNyAgICB8ICAgIAkzMzE1NS4yOCAgICAgfCAgIAkzNTI0OS4wNQkNCk1hciAyMDIwICB8ICAJMzY3MDMuMDEgICAgfCAgICAJMzU1OTYuMTAgICAgIHwgIAkzNzgwOS45MgkNCkFwciAyMDIwICB8ICAJMzYyNzEuOTAgICAgfCAgICAJMzUxNDEuNDQgICAgIHwgICAJMzc0MDIuMzYJDQpNYXkgMjAyMCAgfCAgCTM3MTIxLjk4ICAgIHwgICAgCTM1OTgyLjA3ICAgICB8ICAgCTM4MjYxLjkwCQ0KSnVuIDIwMjAgIHwgIAkzNzEwMi42NSAgICB8ICAgIAkzNTk1OC45MCAgICAgfCAgIAkzODI0Ni40MAkNCkp1bCAyMDIwICB8ICAJMzcxNTEuMDQgICAgfCAgICAJMzYwMDUuNzMgICAgIHwgICAJMzgyOTYuMzQJDQpBdWcgMjAyMCAgfCAgCTM4NTY0LjY0ICAgIHwJICAgIDM3NDE4LjcwICAgICB8ICAgCTM5NzEwLjU4CQ0KU2VwIDIwMjAgIHwgIAkzODc1NS4yMiAgICB8ICAgIAkzNzYwOS4wMyAgICAgfCAgIAkzOTkwMS40MgkNCk9jdCAyMDIgICB8ICAJMzk3NzkuMDIgICAgfCAgICAJMzg2MzIuNzIgICAgIHwgICAJNDA5MjUuMzIJDQpOb3YgMjAyMCAgfCAgCTM4NzQxLjYzICAgIHwgICAgCTM3NTk1LjI4ICAgICB8ICAgCTM5ODg3Ljk3CQ0KRGVjIDIwMjAgIHwgIAkzODY0NS44NiAgICB8ICAgIAkzNzQ5OS41MCAgICAgfCAgIAkzOTc5Mi4yMgkNCiANCg0KYGBge3J9DQp2ZW50YXNfcG9yX2FuaW8gPC0gcmVhZC5jc3YoIkM6L1VzZXJzL0FkcmlhbiBRdWV6YWRhL0Rvd25sb2Fkcy92ZW50YXNfcG9yX2FuaW8gKDIpLmNzdiIpDQpnZ3Bsb3QodmVudGFzX3Bvcl9hbmlvLCBhZXMoeCA9IG1lcywgeSA9IHZlbnRhcywgY29sPSBhcy5mYWN0b3IoYW5pbyksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gYW5pbykpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHRpdGxlID0gIlZlbnRhcyBkZSBsZWNoZSBzYWJvcml6YWRhIEhlcnNoZXnCtHMgcG9yIEHDsW8iLCB4PSAiTUVTIiwgeT0gIlZlbnRhcyIpDQoNCmBgYA0KDQoNCg0KDQpOdWVzdHJhIHJlY29tZW5kYWNpw7NuIHNlcmlhIHJlYWxpemFyIGNhbXBhw7FhcyBwdWJsaWNpdGF0aWFzIHBhcmEgYXVtZW50YXIgZWwgY29uc3VtbyBkZSBsZWNoZSBzYWJvcml6YWRhIEhlcnNoZXlzIHBhcmEgbG9zIG1lc2VzIGRlIGludmllcm5vIGNvbiBjbGltYXMgZnJpb3MNCiAgDQoNCiANCg0KIA0KDQoNCg==