Instalar paquetes y llamar librerías

#install.packages("forecast")
library(forecast)
#install.packages("tidyverse")
library(tidyverse)
#install.packages("readxl")
library(readxl)

Ejemplo 1: Producción

Contexto

Una serie de tiempo es una colección de observaciones sobre un determinado fenómeno efectuadas en momentos de tiempo sucesivos, usualmente equiespaciados.

Ejemplos de series de tiempo: 1. Precio de acciones 2. Niveles de inventario 3. Rotación de personal 4. Ventas 5. PIB(GDP)

Crear la serie de tiempo

Ejemplo: Los siguientes datos de producción trimestral inician en el primer trimestre de 2020. Se busca pronosticar la producción de los siguientes 5 trimestre.

produccion <- c(50,53,55,57,55,60)
#En "start" el primer argumento es el periodo de inicio, y el segundo
st_produccion <- ts(data = produccion, start = c(2020,1), frequency = 4) 
#En este caso la serie de tiempo inicia en 2020, en el 1° trimestre.

#mensual: st_produccion <- ts(data = produccion, start = c(2020,8,), frequency = 12)
#En este caso, la serie de tiempo inicia en 2020, en el 8° mes 

Crear el modelo ARIMA

ARIMA significa Modelo Autorregresivo Integrado de Promedios Moviles, en inglés

modelo_produccion <-auto.arima(st_produccion, D=1) #D: Diferenciación Estacional
modelo_produccion
## Series: st_produccion 
## ARIMA(0,0,0)(0,1,0)[4] with drift 
## 
## Coefficients:
##        drift
##       1.5000
## s.e.  0.1768
## 
## sigma^2 = 2.01:  log likelihood = -2.84
## AIC=9.68   AICc=-2.32   BIC=7.06
summary(modelo_produccion)
## Series: st_produccion 
## ARIMA(0,0,0)(0,1,0)[4] with drift 
## 
## Coefficients:
##        drift
##       1.5000
## s.e.  0.1768
## 
## sigma^2 = 2.01:  log likelihood = -2.84
## AIC=9.68   AICc=-2.32   BIC=7.06
## 
## Training set error measures:
##                      ME      RMSE       MAE        MPE      MAPE       MASE
## Training set 0.03333332 0.5787923 0.3666667 0.03685269 0.6429133 0.06111111
##                    ACF1
## Training set -0.5073047
#Al comparar modelos, seleccionamos el que tenga el menor MAPE(Porcentake de Error Promedio Absoluto)

Generar el pronóstico

pronostico_produccion <- forecast(modelo_produccion, level= c(95), h=5)
#Si no nos dicen otra cosa, el nivel de confiabilidad es de 95%. Los periodos a pronosticar es h.
pronostico_produccion
##         Point Forecast    Lo 95    Hi 95
## 2021 Q3             61 58.22127 63.77873
## 2021 Q4             63 60.22127 65.77873
## 2022 Q1             61 58.22127 63.77873
## 2022 Q2             66 63.22127 68.77873
## 2022 Q3             67 63.07028 70.92972
plot(pronostico_produccion)

Ejercicio 1: México rumbo al 2050

Contexto

En equipos de 2 o 3, seleccionar un estado de México, obtener los datos históricos de su población, generar un pronóstico hasta 2050.

Crear la serie de tiempo

poblacion <- c(1195059,1442662,1555296,1612899 ,1777227,1971520)
#En "start" el primer argumento es el periodo de inicio, y el segundo
st_poblacion <- ts(data = poblacion, start = c(1995,1), frequency = 0.2) 

Crear el modelo ARIMA

ARIMA significa Modelo Autorregresivo Integrado de Promedios Moviles, en inglés

modelo_poblacion <-auto.arima(st_poblacion) #D: Diferenciación Estacional
modelo_poblacion
## Series: st_poblacion 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       155292.20
## s.e.   29317.28
## 
## sigma^2 = 5.372e+09:  log likelihood = -62.55
## AIC=129.1   AICc=135.1   BIC=128.31
summary(modelo_poblacion)
## Series: st_poblacion 
## ARIMA(0,1,0) with drift 
## 
## Coefficients:
##           drift
##       155292.20
## s.e.   29317.28
## 
## sigma^2 = 5.372e+09:  log likelihood = -62.55
## AIC=129.1   AICc=135.1   BIC=128.31
## 
## Training set error measures:
##                    ME     RMSE      MAE        MPE     MAPE      MASE
## Training set 173.2944 59844.21 46955.76 0.02879387 2.961966 0.0294866
##                      ACF1
## Training set -0.009221679
#Al comparar modelos, seleccionamos el que tenga el menor MAPE(Porcentake de Error Promedio Absoluto)

Generar el pronóstico

pronostico_poblacion <- forecast(modelo_poblacion, level= c(95), h=6)
#Si no nos dicen otra cosa, el nivel de confiabilidad es de 95%. Los periodos a pronosticar es h.
pronostico_poblacion
##      Point Forecast   Lo 95   Hi 95
## 2025        2126812 1983159 2270466
## 2030        2282104 2078948 2485261
## 2035        2437397 2188582 2686212
## 2040        2592689 2305382 2879996
## 2045        2747981 2426762 3069200
## 2050        2903273 2551396 3255151
plot(pronostico_poblacion)

Ejercicio 2: ShinyApp

https://a01422749sam.shinyapps.io/Shinyapp8vo/

Contexto

Agregar una pestaña en la aplicación de shiny con el ejercicio México rumbo al 2050. EN el menú se debe sleccionar la cantidad de años a pronosticar.

Ejercicio 3: Reflexión de mis materias

  1. Conocimiento general de administración de negocios y KPIs, FODA, PESTEL,
  2. Manejo de Estados de resultados, Balance general.
  3. No me acuerdo
  4. Aprendí sobre mí y mis cualidades; además de aprender a compartirlo.
  5. Aprendí a realizar una campaña de marketing con herramientas como crm,
  6. Aprendí a realizar escenarios futuros pesimista, positiva y neutral. Aprendí a saldar un proyecto como viable o no dependiendo del wacc.
  7. Aprendí a usar el programa de R por primera vez.
  8. Aprendí herramientas como arboles de decisiones, clusters y redes neuronales. 9)Alguna semana tex de la que me acuerde fue una de piscología emocional.
  9. IA con enfoque empresarial. Aprendí a aplicar conocimiento de minería de datos y econometría en un ambito empresarial. En específico con la empresa NOVEM quien buscaba tener un mejor manejo de modelos de asignación de precios.

Actividad 2: Hershey’s

## Crear la serie de tiempo

ventas <- read_excel("C:\\Users\\aleja\\Documents\\00_Carrera_y_formación\\00_TEC_Por semestre_LIT\\SEMESTRE_8\\Bases_de_Datos\\Ventas_Históricas_Lechitas.xlsx")
str(ventas)
## tibble [36 × 1] (S3: tbl_df/tbl/data.frame)
##  $ Ventas: num [1:36] 25521 23740 26254 25868 27073 ...
st_ventas <- ts(data = ventas, start = c(2017,1), frequency = 12)

Crear el modelo ARIMA

modelo_ventas <-auto.arima(st_ventas) #D: Diferenciación Estacional
modelo_ventas
## Series: st_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
summary(modelo_ventas)
## Series: st_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
#Al comparar modelos, seleccionamos el que tenga el menor MAPE(Porcentake de Error Promedio Absoluto)

Generar el pronóstico

pronostico_ventas <- forecast(modelo_ventas, level= c(95), h=12)
#Si no nos dicen otra cosa, el nivel de confiabilidad es de 95%. Los periodos a pronosticar es 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
plot(pronostico_ventas)

LS0tDQp0aXRsZTogIkFjdGl2aWRhZDJfU2VyaWVzX2RlX1RpZW1wbyINCmF1dGhvcjogIlNhbWFudGhhIC0gQTAxNDIyNzQ5Ig0KZGF0ZTogIjIwMjUtMDgtMTQiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgIHRvYzogVFJVRQ0KICAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICAgY29kZV9kb3dubG9hZDogVFJVRQ0KICAgICB0aGVtZTogY2VydWxlYW4NCiAgICANCg0KLS0tDQoNCiFbXShodHRwczovL2kucGluaW1nLmNvbS9vcmlnaW5hbHMvNjYvMmUvNDYvNjYyZTQ2ZjY2OTdkNTVhNDQzNWQ5YzkwODI5ODM1MDguZ2lmKQ0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIDsiPiBJbnN0YWxhciBwYXF1ZXRlcyB5IGxsYW1hciBsaWJyZXLDrWFzIDwvc3Bhbj4NCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojaW5zdGFsbC5wYWNrYWdlcygiZm9yZWNhc3QiKQ0KbGlicmFyeShmb3JlY2FzdCkNCiNpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQojaW5zdGFsbC5wYWNrYWdlcygicmVhZHhsIikNCmxpYnJhcnkocmVhZHhsKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUgOyI+IEVqZW1wbG8gMTogUHJvZHVjY2nDs24gPC9zcGFuPg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIDsiPiBDb250ZXh0byA8L3NwYW4+DQpVbmEgKipzZXJpZSBkZSB0aWVtcG8qKiBlcyB1bmEgY29sZWNjacOzbiBkZSBvYnNlcnZhY2lvbmVzIHNvYnJlIHVuIGRldGVybWluYWRvIGZlbsOzbWVubyBlZmVjdHVhZGFzIGVuIG1vbWVudG9zIGRlIHRpZW1wbyBzdWNlc2l2b3MsIHVzdWFsbWVudGUgZXF1aWVzcGFjaWFkb3MuDQoNCkVqZW1wbG9zIGRlIHNlcmllcyBkZSB0aWVtcG86DQoxLiBQcmVjaW8gZGUgYWNjaW9uZXMNCjIuIE5pdmVsZXMgZGUgaW52ZW50YXJpbw0KMy4gUm90YWNpw7NuIGRlIHBlcnNvbmFsDQo0LiBWZW50YXMNCjUuIFBJQihHRFApDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibGFjayA7Ij4gQ3JlYXIgbGEgc2VyaWUgZGUgdGllbXBvIDwvc3Bhbj4NCkVqZW1wbG86IExvcyBzaWd1aWVudGVzIGRhdG9zIGRlIHByb2R1Y2Npw7NuIHRyaW1lc3RyYWwgaW5pY2lhbiBlbiBlbCBwcmltZXIgdHJpbWVzdHJlIGRlIDIwMjAuIFNlIGJ1c2NhIHByb25vc3RpY2FyIGxhIHByb2R1Y2Npw7NuIGRlIGxvcyBzaWd1aWVudGVzIDUgdHJpbWVzdHJlLg0KYGBge3J9DQpwcm9kdWNjaW9uIDwtIGMoNTAsNTMsNTUsNTcsNTUsNjApDQojRW4gInN0YXJ0IiBlbCBwcmltZXIgYXJndW1lbnRvIGVzIGVsIHBlcmlvZG8gZGUgaW5pY2lvLCB5IGVsIHNlZ3VuZG8NCnN0X3Byb2R1Y2Npb24gPC0gdHMoZGF0YSA9IHByb2R1Y2Npb24sIHN0YXJ0ID0gYygyMDIwLDEpLCBmcmVxdWVuY3kgPSA0KSANCiNFbiBlc3RlIGNhc28gbGEgc2VyaWUgZGUgdGllbXBvIGluaWNpYSBlbiAyMDIwLCBlbiBlbCAxwrAgdHJpbWVzdHJlLg0KDQojbWVuc3VhbDogc3RfcHJvZHVjY2lvbiA8LSB0cyhkYXRhID0gcHJvZHVjY2lvbiwgc3RhcnQgPSBjKDIwMjAsOCwpLCBmcmVxdWVuY3kgPSAxMikNCiNFbiBlc3RlIGNhc28sIGxhIHNlcmllIGRlIHRpZW1wbyBpbmljaWEgZW4gMjAyMCwgZW4gZWwgOMKwIG1lcyANCg0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibGFjayA7Ij4gQ3JlYXIgZWwgbW9kZWxvIEFSSU1BIDwvc3Bhbj4NCioqQVJJTUEgKiogc2lnbmlmaWNhIE1vZGVsbyBBdXRvcnJlZ3Jlc2l2byBJbnRlZ3JhZG8gZGUgUHJvbWVkaW9zIE1vdmlsZXMsICBlbiBpbmdsw6lzDQpgYGB7cn0NCm1vZGVsb19wcm9kdWNjaW9uIDwtYXV0by5hcmltYShzdF9wcm9kdWNjaW9uLCBEPTEpICNEOiBEaWZlcmVuY2lhY2nDs24gRXN0YWNpb25hbA0KbW9kZWxvX3Byb2R1Y2Npb24NCnN1bW1hcnkobW9kZWxvX3Byb2R1Y2Npb24pDQojQWwgY29tcGFyYXIgbW9kZWxvcywgc2VsZWNjaW9uYW1vcyBlbCBxdWUgdGVuZ2EgZWwgbWVub3IgTUFQRShQb3JjZW50YWtlIGRlIEVycm9yIFByb21lZGlvIEFic29sdXRvKQ0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIDsiPiBHZW5lcmFyIGVsIHByb27Ds3N0aWNvIDwvc3Bhbj4NCmBgYHtyfQ0KcHJvbm9zdGljb19wcm9kdWNjaW9uIDwtIGZvcmVjYXN0KG1vZGVsb19wcm9kdWNjaW9uLCBsZXZlbD0gYyg5NSksIGg9NSkNCiNTaSBubyBub3MgZGljZW4gb3RyYSBjb3NhLCBlbCBuaXZlbCBkZSBjb25maWFiaWxpZGFkIGVzIGRlIDk1JS4gTG9zIHBlcmlvZG9zIGEgcHJvbm9zdGljYXIgZXMgaC4NCnByb25vc3RpY29fcHJvZHVjY2lvbg0KcGxvdChwcm9ub3N0aWNvX3Byb2R1Y2Npb24pDQpgYGANCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEVqZXJjaWNpbyAxOiBNw6l4aWNvIHJ1bWJvIGFsIDIwNTAgPC9zcGFuPg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6b3JhbmdlIDsiPiBDb250ZXh0byA8L3NwYW4+DQpFbiBlcXVpcG9zIGRlIDIgbyAzLCBzZWxlY2Npb25hciB1biBlc3RhZG8gZGUgTcOpeGljbywgb2J0ZW5lciBsb3MgZGF0b3MgaGlzdMOzcmljb3MgZGUgc3UgcG9ibGFjacOzbiwgZ2VuZXJhciB1biBwcm9uw7NzdGljbyBoYXN0YSAyMDUwLiANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIDsiPiBDcmVhciBsYSBzZXJpZSBkZSB0aWVtcG8gPC9zcGFuPg0KYGBge3J9DQpwb2JsYWNpb24gPC0gYygxMTk1MDU5LDE0NDI2NjIsMTU1NTI5NiwxNjEyODk5ICwxNzc3MjI3LDE5NzE1MjApDQojRW4gInN0YXJ0IiBlbCBwcmltZXIgYXJndW1lbnRvIGVzIGVsIHBlcmlvZG8gZGUgaW5pY2lvLCB5IGVsIHNlZ3VuZG8NCnN0X3BvYmxhY2lvbiA8LSB0cyhkYXRhID0gcG9ibGFjaW9uLCBzdGFydCA9IGMoMTk5NSwxKSwgZnJlcXVlbmN5ID0gMC4yKSANCg0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibGFjayA7Ij4gQ3JlYXIgZWwgbW9kZWxvIEFSSU1BIDwvc3Bhbj4NCioqQVJJTUEgKiogc2lnbmlmaWNhIE1vZGVsbyBBdXRvcnJlZ3Jlc2l2byBJbnRlZ3JhZG8gZGUgUHJvbWVkaW9zIE1vdmlsZXMsICBlbiBpbmdsw6lzDQpgYGB7cn0NCm1vZGVsb19wb2JsYWNpb24gPC1hdXRvLmFyaW1hKHN0X3BvYmxhY2lvbikgI0Q6IERpZmVyZW5jaWFjacOzbiBFc3RhY2lvbmFsDQptb2RlbG9fcG9ibGFjaW9uDQpzdW1tYXJ5KG1vZGVsb19wb2JsYWNpb24pDQojQWwgY29tcGFyYXIgbW9kZWxvcywgc2VsZWNjaW9uYW1vcyBlbCBxdWUgdGVuZ2EgZWwgbWVub3IgTUFQRShQb3JjZW50YWtlIGRlIEVycm9yIFByb21lZGlvIEFic29sdXRvKQ0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIDsiPiBHZW5lcmFyIGVsIHByb27Ds3N0aWNvIDwvc3Bhbj4NCmBgYHtyfQ0KcHJvbm9zdGljb19wb2JsYWNpb24gPC0gZm9yZWNhc3QobW9kZWxvX3BvYmxhY2lvbiwgbGV2ZWw9IGMoOTUpLCBoPTYpDQojU2kgbm8gbm9zIGRpY2VuIG90cmEgY29zYSwgZWwgbml2ZWwgZGUgY29uZmlhYmlsaWRhZCBlcyBkZSA5NSUuIExvcyBwZXJpb2RvcyBhIHByb25vc3RpY2FyIGVzIGguDQpwcm9ub3N0aWNvX3BvYmxhY2lvbg0KcGxvdChwcm9ub3N0aWNvX3BvYmxhY2lvbikNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEVqZXJjaWNpbyAyOiBTaGlueUFwcCA8L3NwYW4+DQoNCmh0dHBzOi8vYTAxNDIyNzQ5c2FtLnNoaW55YXBwcy5pby9TaGlueWFwcDh2by8NCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOm9yYW5nZSA7Ij4gQ29udGV4dG8gPC9zcGFuPg0KQWdyZWdhciB1bmEgcGVzdGHDsWEgZW4gbGEgYXBsaWNhY2nDs24gZGUgc2hpbnkgY29uIGVsIGVqZXJjaWNpbyBNw6l4aWNvIHJ1bWJvIGFsIDIwNTAuIEVOIGVsIG1lbsO6IHNlIGRlYmUgc2xlY2Npb25hciBsYSBjYW50aWRhZCBkZSBhw7FvcyBhIHByb25vc3RpY2FyLiANCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEVqZXJjaWNpbyAzOiBSZWZsZXhpw7NuIGRlIG1pcyBtYXRlcmlhcyA8L3NwYW4+DQoNCjEpIENvbm9jaW1pZW50byBnZW5lcmFsIGRlIGFkbWluaXN0cmFjacOzbiBkZSBuZWdvY2lvcyB5IEtQSXMsIEZPREEsIFBFU1RFTCwgDQoyKSBNYW5lam8gZGUgRXN0YWRvcyBkZSByZXN1bHRhZG9zLCBCYWxhbmNlIGdlbmVyYWwuIA0KMykgTm8gbWUgYWN1ZXJkbyANCjQpIEFwcmVuZMOtIHNvYnJlIG3DrSB5IG1pcyBjdWFsaWRhZGVzOyBhZGVtw6FzIGRlIGFwcmVuZGVyIGEgY29tcGFydGlybG8uDQo1KSBBcHJlbmTDrSBhIHJlYWxpemFyIHVuYSBjYW1wYcOxYSBkZSBtYXJrZXRpbmcgY29uIGhlcnJhbWllbnRhcyBjb21vIGNybSwgDQo2KSBBcHJlbmTDrSBhIHJlYWxpemFyIGVzY2VuYXJpb3MgZnV0dXJvcyBwZXNpbWlzdGEsIHBvc2l0aXZhIHkgbmV1dHJhbC4gQXByZW5kw60gYSBzYWxkYXIgdW4gcHJveWVjdG8gY29tbyB2aWFibGUgbyBubyBkZXBlbmRpZW5kbyBkZWwgd2FjYy4NCjcpIEFwcmVuZMOtIGEgdXNhciBlbCBwcm9ncmFtYSBkZSBSIHBvciBwcmltZXJhIHZlei4NCjgpIEFwcmVuZMOtIGhlcnJhbWllbnRhcyBjb21vIGFyYm9sZXMgZGUgZGVjaXNpb25lcywgY2x1c3RlcnMgeSByZWRlcyBuZXVyb25hbGVzLiANCjkpQWxndW5hIHNlbWFuYSB0ZXggZGUgbGEgcXVlIG1lIGFjdWVyZGUgZnVlIHVuYSBkZSBwaXNjb2xvZ8OtYSBlbW9jaW9uYWwuDQoxMCkgSUEgY29uIGVuZm9xdWUgZW1wcmVzYXJpYWwuIEFwcmVuZMOtIGEgYXBsaWNhciBjb25vY2ltaWVudG8gZGUgbWluZXLDrWEgZGUgZGF0b3MgeSBlY29ub21ldHLDrWEgZW4gdW4gYW1iaXRvIGVtcHJlc2FyaWFsLiBFbiBlc3BlY8OtZmljbyBjb24gbGEgZW1wcmVzYSBOT1ZFTSBxdWllbiBidXNjYWJhIHRlbmVyIHVuIG1lam9yIG1hbmVqbyBkZSBtb2RlbG9zIGRlIGFzaWduYWNpw7NuIGRlIHByZWNpb3MuDQoNCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlOyI+IEFjdGl2aWRhZCAyOiBIZXJzaGV5J3MgIDwvc3Bhbj4NCg0KIyM8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZTsiPiBDcmVhciBsYSBzZXJpZSBkZSB0aWVtcG8gPC9zcGFuPg0KYGBge3J9DQp2ZW50YXMgPC0gcmVhZF9leGNlbCgiQzpcXFVzZXJzXFxhbGVqYVxcRG9jdW1lbnRzXFwwMF9DYXJyZXJhX3lfZm9ybWFjacOzblxcMDBfVEVDX1BvciBzZW1lc3RyZV9MSVRcXFNFTUVTVFJFXzhcXEJhc2VzX2RlX0RhdG9zXFxWZW50YXNfSGlzdMOzcmljYXNfTGVjaGl0YXMueGxzeCIpDQpzdHIodmVudGFzKQ0Kc3RfdmVudGFzIDwtIHRzKGRhdGEgPSB2ZW50YXMsIHN0YXJ0ID0gYygyMDE3LDEpLCBmcmVxdWVuY3kgPSAxMikNCmBgYA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6YmxhY2sgOyI+IENyZWFyIGVsIG1vZGVsbyBBUklNQSA8L3NwYW4+DQpgYGB7cn0NCm1vZGVsb192ZW50YXMgPC1hdXRvLmFyaW1hKHN0X3ZlbnRhcykgI0Q6IERpZmVyZW5jaWFjacOzbiBFc3RhY2lvbmFsDQptb2RlbG9fdmVudGFzDQpzdW1tYXJ5KG1vZGVsb192ZW50YXMpDQojQWwgY29tcGFyYXIgbW9kZWxvcywgc2VsZWNjaW9uYW1vcyBlbCBxdWUgdGVuZ2EgZWwgbWVub3IgTUFQRShQb3JjZW50YWtlIGRlIEVycm9yIFByb21lZGlvIEFic29sdXRvKQ0KDQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIDsiPiBHZW5lcmFyIGVsIHByb27Ds3N0aWNvIDwvc3Bhbj4NCmBgYHtyfQ0KcHJvbm9zdGljb192ZW50YXMgPC0gZm9yZWNhc3QobW9kZWxvX3ZlbnRhcywgbGV2ZWw9IGMoOTUpLCBoPTEyKQ0KI1NpIG5vIG5vcyBkaWNlbiBvdHJhIGNvc2EsIGVsIG5pdmVsIGRlIGNvbmZpYWJpbGlkYWQgZXMgZGUgOTUlLiBMb3MgcGVyaW9kb3MgYSBwcm9ub3N0aWNhciBlcyBoLg0KcHJvbm9zdGljb192ZW50YXMNCnBsb3QocHJvbm9zdGljb192ZW50YXMpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQo=