1 Ejercicio en Clase

1.1 Concepto

Una Serie de Tiempo es una coleccion de observaciones sobre un determinado fenómeno, efectuadas en momento sucesivos, usualmente equiespaciados.

Algunos ejemplos de series de tiempo son: 1. Precios de acciones 2. Niveles de inventario 3. Rotacion de Personal 4. Ventas 5. PIB (GDP)

Mas informacion: link

1.2 Instalar paquetes y librerías

library(forecast)
## Warning: package 'forecast' was built under R version 4.3.2
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
library(readxl)
## Warning: package 'readxl' was built under R version 4.3.2

1.3 Crear Serie de Tiempo

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

produccion <- c(50,53,55,57,55,60)

ts<-ts(produccion,start = c(2020,1),frequency =  4)
ts
##      Qtr1 Qtr2 Qtr3 Qtr4
## 2020   50   53   55   57
## 2021   55   60

1.4 Crear Modelo ARIMA

ARIMA significa AutoRegressive Integrated Moving Average o Modelo Autorregresivo Integrado de Promedio Móvil

arima<-auto.arima(ts)
summary(arima)
## Series: ts 
## ARIMA(0,1,0) 
## 
## sigma^2 = 9.2:  log likelihood = -12.64
## AIC=27.29   AICc=28.62   BIC=26.89
## 
## Training set error measures:
##                 ME    RMSE      MAE      MPE     MAPE      MASE       ACF1
## Training set 1.675 2.76895 2.341667 2.933747 4.145868 0.3902778 -0.5152989

1.5 Generar el pronóstico

pronostico <- forecast(arima,level=c(95), h=5)
pronostico
##         Point Forecast    Lo 95    Hi 95
## 2021 Q3             60 54.05497 65.94503
## 2021 Q4             60 51.59246 68.40754
## 2022 Q1             60 49.70291 70.29709
## 2022 Q2             60 48.10995 71.89005
## 2022 Q3             60 46.70652 73.29348
plot(pronostico)

2 Actividad 2

2.1 Crear Serie de Tiempo

hershey <- read_excel("Ventas_Históricas_Lechitas.xlsx")
hershey$Ventas<-as.numeric(hershey$Ventas)

ts1<-ts(hershey$Ventas,start =c(2017,1),frequency =12)
ts1
##           Jan      Feb      Mar      Apr      May      Jun      Jul      Aug
## 2017 25520.51 23740.11 26253.58 25868.43 27072.87 27150.50 27067.10 28145.25
## 2018 28463.69 26996.11 29768.20 29292.51 29950.68 30099.17 30851.26 32271.76
## 2019 32496.44 31287.28 33376.02 32949.77 34004.11 33757.89 32927.30 34324.12
##           Sep      Oct      Nov      Dec
## 2017 27546.29 28400.37 27441.98 27852.47
## 2018 31940.74 32995.93 32197.12 31984.82
## 2019 35151.28 36133.07 34799.91 34846.17

2.2 Crear Modelo ARIMA

ARIMA significa AutoRegressive Integrated Moving Average o Modelo Autorregresivo Integrado de Promedio Móvil

arima2<-auto.arima(ts1, D=1)
summary(arima2)
## Series: ts1 
## ARIMA(1,0,0)(1,1,0)[12] with drift 
## 
## Coefficients:
##          ar1     sar1     drift
##       0.6383  -0.5517  288.8980
## s.e.  0.1551   0.2047   14.5026
## 
## sigma^2 = 202700:  log likelihood = -181.5
## AIC=371   AICc=373.11   BIC=375.72
## 
## Training set error measures:
##                    ME    RMSE      MAE        MPE      MAPE       MASE
## Training set 25.22163 343.863 227.1699 0.08059942 0.7069541 0.06491041
##                   ACF1
## Training set 0.2081043

2.3 Generar el pronóstico

pronostico2 <- forecast(arima2,level=c(95), h=12)
pronostico2
##          Point Forecast    Lo 95    Hi 95
## Jan 2020       35498.90 34616.48 36381.32
## Feb 2020       34202.17 33155.29 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.91 38246.40
## Jul 2020       37151.04 36005.74 38296.35
## Aug 2020       38564.65 37418.71 39710.59
## Sep 2020       38755.23 37609.03 39901.42
## Oct 2020       39779.03 38632.73 40925.33
## Nov 2020       38741.63 37595.29 39887.97
## Dec 2020       38645.86 37499.50 39792.22
plot(pronostico2)

3 Actividad 3. Finanzas Corporativas

Con la función de finerportr podemos obtener la siguiente información

  • CompanyInfo() = Brinda información general como Nombre, Ubicación, ZIP, etc.

  • AnnualReports() = Brinda el nombre, fecha y número de acceso

  • GetIncome()= Brinda el Estado de Resultados.

  • GetBalanceSheet() = Brinda el Balance General

  • GetCashFlow() = Brinda el Flujo de Efectivo.

options(HTTPUserAgent = "a a@gmail.com")
CompanyInfo("JPM")
##               company        CIK  SIC state state.inc FY.end     street.address
## 1 JPMORGAN CHASE & CO 0000019617 6021    NY        DE   1231 383 MADISON AVENUE
##          city.state
## 1 NEW YORK NY 10017
AnnualReports("BABA",foreign=TRUE)
##    filing.name filing.date         accession.no
## 1       20-F/A  2024-02-23 0001193125-24-044480
## 2         20-F  2023-07-21 0000950170-23-033752
## 3         20-F  2022-07-26 0001104659-22-082622
## 4         20-F  2021-07-27 0001104659-21-096092
## 5         20-F  2020-07-09 0001104659-20-082409
## 6         20-F  2019-06-05 0001047469-19-003492
## 7         20-F  2018-07-27 0001047469-18-005257
## 8         20-F  2017-06-15 0001047469-17-004019
## 9         20-F  2016-05-24 0001047469-16-013400
## 10        20-F  2015-06-25 0001047469-15-005768
google_income<-GetIncome("GOOG",2016)
amazon_balance <- GetBalanceSheet("AMZN",2015)
apple_cash<-GetCashFlow("AAPL",2014)

3.1 Conseguir los datos

options(HTTPUserAgent = "a a@gmail.com")
jpm_income_2015<-GetIncome("JPM",2015)
jpm_balance_2015 <- GetBalanceSheet("JPM",2015)
jpm_income_2018<-GetIncome("JPM",2018)
jpm_balance_2018 <- GetBalanceSheet("JPM",2018)
jpm_balance_2013<-GetBalanceSheet("JPM",2013)
jpm_balance_2016<-GetBalanceSheet("JPM",2016)

3.2 Manipulación de Datos

conjunto<-rbind(jpm_balance_2015,jpm_balance_2018,jpm_income_2015,jpm_income_2018,jpm_balance_2013,jpm_balance_2016)
conjunto<-conjunto%>%
  filter(Metric %in% c("Assets","Net Income (Loss) Attributable to Parent","Liabilities","Deposits"))
conjunto$endDate <- as.Date(conjunto$endDate)

conjunto_filtered <- conjunto %>%
  filter(endDate >= as.Date("2012-01-01") & endDate <= as.Date("2017-12-31")) %>%
  group_by(Metric, year = as.numeric(format(endDate, "%Y"))) %>%
  mutate(row_number = row_number()) %>%
  filter(row_number == 1) %>%
  select(-row_number) %>%
  ungroup()
conjunto_filtered<-conjunto_filtered%>%select(1,3,6)
df_pivot <- conjunto_filtered %>%
  spread(key = Metric, value = Amount)

# Opcional: Renombramos las columnas para que tengan nombres más descriptivos
names(df_pivot)[1] <- "Year"

df_pivot$Assets<-as.numeric(df_pivot$Assets)
df_pivot$Deposits<-as.numeric(df_pivot$Deposits)
df_pivot$Liabilities<-as.numeric(df_pivot$Liabilities)
df_pivot$`Net Income (Loss) Attributable to Parent`<-as.numeric(df_pivot$`Net Income (Loss) Attributable to Parent`)

3.3 Crear serie de tiempo

ts2<-ts(df_pivot$Deposits,start =c(2012,1),frequency =1)
ts2
## Time Series:
## Start = 2012 
## End = 2017 
## Frequency = 1 
## [1] 1.193593e+12 1.287765e+12 1.363427e+12 1.279715e+12 1.375179e+12
## [6] 1.443982e+12

3.4 Crear Modelo ARIMA

ARIMA significa AutoRegressive Integrated Moving Average o Modelo Autorregresivo Integrado de Promedio Móvil

arima3<-auto.arima(ts2,d=1)
summary(arima3)
## Series: ts2 
## ARIMA(0,1,0) 
## 
## sigma^2 = 7.09e+21:  log likelihood = -132.88
## AIC=267.75   AICc=269.09   BIC=267.36
## 
## Training set error measures:
##                       ME        RMSE         MAE      MPE     MAPE     MASE
## Training set 41930432067 76865093443 69834432067 3.021252 5.201737 0.835714
##                    ACF1
## Training set -0.3972446

3.5 Generar el pronóstico

pronostico3 <- forecast(arima3,level=c(95), h=5)
pronostico3
##      Point Forecast        Lo 95        Hi 95
## 2018   1.443982e+12 1.278950e+12 1.609014e+12
## 2019   1.443982e+12 1.210592e+12 1.677372e+12
## 2020   1.443982e+12 1.158138e+12 1.729826e+12
## 2021   1.443982e+12 1.113918e+12 1.774046e+12
## 2022   1.443982e+12 1.074959e+12 1.813005e+12
plot(pronostico3)

LS0tDQp0aXRsZTogIlNlcmllcyBkZSBUaWVtcG8iDQphdXRob3I6ICJKb3PDqSBHYWJyaWVsIFVzacOxYSBNb2dybyBBMDA4MzE0MzUNCkxvcmVuYSBWaWxsYXJyZWFsIFZlZ2EgQTAxNzIwODAyDQpYaW1lbmEgU29sw61zIElzbGFzIEEwMDgzMTM3MSINCmRhdGU6ICIyMDI0LTAyLTE2Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogdW5pdGVkDQogICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogMw0KICAgIG51bWJlcl9zZWN0aW9uczogVFJVRQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCg0KLS0tDQoNCiMgRWplcmNpY2lvIGVuIENsYXNlDQoNCiFbXShodHRwczovL21lZGlhLmdpcGh5LmNvbS9tZWRpYS90R2dMZ1RkTllVZ0VxdTJhQXYvZ2lwaHkuZ2lmKQ0KDQojIyBDb25jZXB0bw0KDQpVbmEgKipTZXJpZSBkZSBUaWVtcG8qKiBlcyB1bmEgY29sZWNjaW9uIGRlIG9ic2VydmFjaW9uZXMgc29icmUgdW4NCmRldGVybWluYWRvIGZlbsOzbWVubywgZWZlY3R1YWRhcyBlbiBtb21lbnRvIHN1Y2VzaXZvcywgdXN1YWxtZW50ZQ0KZXF1aWVzcGFjaWFkb3MuDQoNCkFsZ3Vub3MgZWplbXBsb3MgZGUgc2VyaWVzIGRlIHRpZW1wbyBzb246IDEuIFByZWNpb3MgZGUgYWNjaW9uZXMgMi4NCk5pdmVsZXMgZGUgaW52ZW50YXJpbyAzLiBSb3RhY2lvbiBkZSBQZXJzb25hbCA0LiBWZW50YXMgNS4gUElCICgqR0RQKikNCg0KTWFzIGluZm9ybWFjaW9uOiBbbGlua10oaHR0cHM6Ly9yNGRzLmhhZGxleS5uei8pDQoNCiMjIEluc3RhbGFyIHBhcXVldGVzIHkgbGlicmVyw61hcw0KDQpgYGB7cn0NCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KHJlYWR4bCkNCmBgYA0KDQojIyBDcmVhciBTZXJpZSBkZSBUaWVtcG8NCg0KKipFamVtcGxvOioqIExvcyBzaWd1aWVudGVzIGRlIGRhdG9zIGRlIHByb2R1Y2Npw7NuIHRyaW1lc3RyYWwgaW5pY2lhbiBlbg0KZWwgcHJpbWVyIHRyaW1lc3RyZSBkZSAyMDIwLiBTZSBidXNjYSBwcm9ub3N0aWNhciBsYSBwcm9kdWNjacOzbiBkZSBsb3MNCnNpZ3VpZW50ZXMgNSB0cmltZXN0cmVzDQoNCmBgYHtyfQ0KcHJvZHVjY2lvbiA8LSBjKDUwLDUzLDU1LDU3LDU1LDYwKQ0KDQp0czwtdHMocHJvZHVjY2lvbixzdGFydCA9IGMoMjAyMCwxKSxmcmVxdWVuY3kgPSAgNCkNCnRzDQpgYGANCg0KIyMgQ3JlYXIgTW9kZWxvIEFSSU1BDQoNCioqQVJJTUEqKiBzaWduaWZpY2EgKkF1dG9SZWdyZXNzaXZlIEludGVncmF0ZWQgTW92aW5nIEF2ZXJhZ2UqIG8gTW9kZWxvDQpBdXRvcnJlZ3Jlc2l2byBJbnRlZ3JhZG8gZGUgUHJvbWVkaW8gTcOzdmlsDQoNCmBgYHtyfQ0KYXJpbWE8LWF1dG8uYXJpbWEodHMpDQpzdW1tYXJ5KGFyaW1hKQ0KYGBgDQoNCiMjIEdlbmVyYXIgZWwgcHJvbsOzc3RpY28NCg0KYGBge3J9DQpwcm9ub3N0aWNvIDwtIGZvcmVjYXN0KGFyaW1hLGxldmVsPWMoOTUpLCBoPTUpDQpwcm9ub3N0aWNvDQpgYGANCg0KYGBge3J9DQpwbG90KHByb25vc3RpY28pDQpgYGANCg0KIyBBY3RpdmlkYWQgMg0KDQohW10oaHR0cHM6Ly9tZWRpYS5naXBoeS5jb20vbWVkaWEvaGt4NFJiamNGME5KNi9naXBoeS5naWYpDQoNCiMjIENyZWFyIFNlcmllIGRlIFRpZW1wbw0KDQpgYGB7cn0NCmhlcnNoZXkgPC0gcmVhZF9leGNlbCgiVmVudGFzX0hpc3TDs3JpY2FzX0xlY2hpdGFzLnhsc3giKQ0KaGVyc2hleSRWZW50YXM8LWFzLm51bWVyaWMoaGVyc2hleSRWZW50YXMpDQoNCnRzMTwtdHMoaGVyc2hleSRWZW50YXMsc3RhcnQgPWMoMjAxNywxKSxmcmVxdWVuY3kgPTEyKQ0KdHMxDQpgYGANCg0KIyMgQ3JlYXIgTW9kZWxvIEFSSU1BDQoNCioqQVJJTUEqKiBzaWduaWZpY2EgKkF1dG9SZWdyZXNzaXZlIEludGVncmF0ZWQgTW92aW5nIEF2ZXJhZ2UqIG8gTW9kZWxvDQpBdXRvcnJlZ3Jlc2l2byBJbnRlZ3JhZG8gZGUgUHJvbWVkaW8gTcOzdmlsDQoNCmBgYHtyfQ0KYXJpbWEyPC1hdXRvLmFyaW1hKHRzMSwgRD0xKQ0Kc3VtbWFyeShhcmltYTIpDQpgYGANCg0KIyMgR2VuZXJhciBlbCBwcm9uw7NzdGljbw0KDQpgYGB7cn0NCnByb25vc3RpY28yIDwtIGZvcmVjYXN0KGFyaW1hMixsZXZlbD1jKDk1KSwgaD0xMikNCnByb25vc3RpY28yDQpwbG90KHByb25vc3RpY28yKQ0KYGBgDQoNCiMgQWN0aXZpZGFkIDMuIEZpbmFuemFzIENvcnBvcmF0aXZhcw0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShmaW5yZXBvcnRyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkodGlkeXIpDQpgYGANCg0KQ29uIGxhIGZ1bmNpw7NuIGRlICpmaW5lcnBvcnRyKiBwb2RlbW9zIG9idGVuZXIgbGEgc2lndWllbnRlIGluZm9ybWFjacOzbg0KDQotICAgQ29tcGFueUluZm8oKSA9IEJyaW5kYSBpbmZvcm1hY2nDs24gZ2VuZXJhbCBjb21vIE5vbWJyZSwgVWJpY2FjacOzbiwNCiAgICBaSVAsIGV0Yy4NCg0KLSAgIEFubnVhbFJlcG9ydHMoKSA9IEJyaW5kYSBlbCBub21icmUsIGZlY2hhIHkgbsO6bWVybyBkZSBhY2Nlc28NCg0KLSAgIEdldEluY29tZSgpPSBCcmluZGEgZWwgRXN0YWRvIGRlIFJlc3VsdGFkb3MuDQoNCi0gICBHZXRCYWxhbmNlU2hlZXQoKSA9IEJyaW5kYSBlbCBCYWxhbmNlIEdlbmVyYWwNCg0KLSAgIEdldENhc2hGbG93KCkgPSBCcmluZGEgZWwgRmx1am8gZGUgRWZlY3Rpdm8uDQoNCmBgYHtyfQ0Kb3B0aW9ucyhIVFRQVXNlckFnZW50ID0gImEgYUBnbWFpbC5jb20iKQ0KQ29tcGFueUluZm8oIkpQTSIpDQpBbm51YWxSZXBvcnRzKCJCQUJBIixmb3JlaWduPVRSVUUpDQpnb29nbGVfaW5jb21lPC1HZXRJbmNvbWUoIkdPT0ciLDIwMTYpDQphbWF6b25fYmFsYW5jZSA8LSBHZXRCYWxhbmNlU2hlZXQoIkFNWk4iLDIwMTUpDQphcHBsZV9jYXNoPC1HZXRDYXNoRmxvdygiQUFQTCIsMjAxNCkNCmBgYA0KDQojIyBDb25zZWd1aXIgbG9zIGRhdG9zDQpgYGB7cn0NCm9wdGlvbnMoSFRUUFVzZXJBZ2VudCA9ICJhIGFAZ21haWwuY29tIikNCmpwbV9pbmNvbWVfMjAxNTwtR2V0SW5jb21lKCJKUE0iLDIwMTUpDQpqcG1fYmFsYW5jZV8yMDE1IDwtIEdldEJhbGFuY2VTaGVldCgiSlBNIiwyMDE1KQ0KanBtX2luY29tZV8yMDE4PC1HZXRJbmNvbWUoIkpQTSIsMjAxOCkNCmpwbV9iYWxhbmNlXzIwMTggPC0gR2V0QmFsYW5jZVNoZWV0KCJKUE0iLDIwMTgpDQpqcG1fYmFsYW5jZV8yMDEzPC1HZXRCYWxhbmNlU2hlZXQoIkpQTSIsMjAxMykNCmpwbV9iYWxhbmNlXzIwMTY8LUdldEJhbGFuY2VTaGVldCgiSlBNIiwyMDE2KQ0KYGBgDQoNCiMjIE1hbmlwdWxhY2nDs24gZGUgRGF0b3MNCmBgYHtyfQ0KY29uanVudG88LXJiaW5kKGpwbV9iYWxhbmNlXzIwMTUsanBtX2JhbGFuY2VfMjAxOCxqcG1faW5jb21lXzIwMTUsanBtX2luY29tZV8yMDE4LGpwbV9iYWxhbmNlXzIwMTMsanBtX2JhbGFuY2VfMjAxNikNCmNvbmp1bnRvPC1jb25qdW50byU+JQ0KICBmaWx0ZXIoTWV0cmljICVpbiUgYygiQXNzZXRzIiwiTmV0IEluY29tZSAoTG9zcykgQXR0cmlidXRhYmxlIHRvIFBhcmVudCIsIkxpYWJpbGl0aWVzIiwiRGVwb3NpdHMiKSkNCmBgYA0KDQpgYGB7cn0NCmNvbmp1bnRvJGVuZERhdGUgPC0gYXMuRGF0ZShjb25qdW50byRlbmREYXRlKQ0KDQpjb25qdW50b19maWx0ZXJlZCA8LSBjb25qdW50byAlPiUNCiAgZmlsdGVyKGVuZERhdGUgPj0gYXMuRGF0ZSgiMjAxMi0wMS0wMSIpICYgZW5kRGF0ZSA8PSBhcy5EYXRlKCIyMDE3LTEyLTMxIikpICU+JQ0KICBncm91cF9ieShNZXRyaWMsIHllYXIgPSBhcy5udW1lcmljKGZvcm1hdChlbmREYXRlLCAiJVkiKSkpICU+JQ0KICBtdXRhdGUocm93X251bWJlciA9IHJvd19udW1iZXIoKSkgJT4lDQogIGZpbHRlcihyb3dfbnVtYmVyID09IDEpICU+JQ0KICBzZWxlY3QoLXJvd19udW1iZXIpICU+JQ0KICB1bmdyb3VwKCkNCmBgYA0KDQpgYGB7cn0NCmNvbmp1bnRvX2ZpbHRlcmVkPC1jb25qdW50b19maWx0ZXJlZCU+JXNlbGVjdCgxLDMsNikNCmBgYA0KDQpgYGB7cn0NCmRmX3Bpdm90IDwtIGNvbmp1bnRvX2ZpbHRlcmVkICU+JQ0KICBzcHJlYWQoa2V5ID0gTWV0cmljLCB2YWx1ZSA9IEFtb3VudCkNCg0KIyBPcGNpb25hbDogUmVub21icmFtb3MgbGFzIGNvbHVtbmFzIHBhcmEgcXVlIHRlbmdhbiBub21icmVzIG3DoXMgZGVzY3JpcHRpdm9zDQpuYW1lcyhkZl9waXZvdClbMV0gPC0gIlllYXIiDQoNCmRmX3Bpdm90JEFzc2V0czwtYXMubnVtZXJpYyhkZl9waXZvdCRBc3NldHMpDQpkZl9waXZvdCREZXBvc2l0czwtYXMubnVtZXJpYyhkZl9waXZvdCREZXBvc2l0cykNCmRmX3Bpdm90JExpYWJpbGl0aWVzPC1hcy5udW1lcmljKGRmX3Bpdm90JExpYWJpbGl0aWVzKQ0KZGZfcGl2b3QkYE5ldCBJbmNvbWUgKExvc3MpIEF0dHJpYnV0YWJsZSB0byBQYXJlbnRgPC1hcy5udW1lcmljKGRmX3Bpdm90JGBOZXQgSW5jb21lIChMb3NzKSBBdHRyaWJ1dGFibGUgdG8gUGFyZW50YCkNCmBgYA0KDQojIyBDcmVhciBzZXJpZSBkZSB0aWVtcG8NCg0KDQpgYGB7cn0NCnRzMjwtdHMoZGZfcGl2b3QkRGVwb3NpdHMsc3RhcnQgPWMoMjAxMiwxKSxmcmVxdWVuY3kgPTEpDQp0czINCmBgYA0KDQojIyBDcmVhciBNb2RlbG8gQVJJTUENCg0KKipBUklNQSoqIHNpZ25pZmljYSAqQXV0b1JlZ3Jlc3NpdmUgSW50ZWdyYXRlZCBNb3ZpbmcgQXZlcmFnZSogbyBNb2RlbG8NCkF1dG9ycmVncmVzaXZvIEludGVncmFkbyBkZSBQcm9tZWRpbyBNw7N2aWwNCmBgYHtyfQ0KYXJpbWEzPC1hdXRvLmFyaW1hKHRzMixkPTEpDQpzdW1tYXJ5KGFyaW1hMykNCmBgYA0KDQojIyBHZW5lcmFyIGVsIHByb27Ds3N0aWNvDQoNCmBgYHtyfQ0KcHJvbm9zdGljbzMgPC0gZm9yZWNhc3QoYXJpbWEzLGxldmVsPWMoOTUpLCBoPTUpDQpwcm9ub3N0aWNvMw0KcGxvdChwcm9ub3N0aWNvMykNCmBgYA==