Librerías y datos

El primer paso consiste la importación de las librerías y los datos. En el caso de las primeras, estas pertenecen a la paquetería estadística de R, y en el caso del segundo punto, estos fueron recabados de los precios de cierre de Refinitiv.

library(readxl)
library(readr)
library(xts)
library(dplyr)
library(janitor)
library(kableExtra)
library(PerformanceAnalytics)

setwd("/Users/rogelio/Desktop/R")

precios <- read_excel("~/Desktop/R/precioss.xlsx")

Con esto, se procede a la limpieza de los datos, la cual en este caso solo consiste en convertir la fecha de los precios al formato deseado:

precios <- precios %>%  
  mutate(Date = convert_to_date(Date, character_fun = lubridate::mdy))

precios #Resultado final

Cálculo del VaR

Con base en esto, como se percibe en la tabla anterior, se recopilaron datos a partir del 31 de mayo de 2020 hasta el 1 de junio de 2023. Para tener un análisis más profundo, se optó por tabajar con la base ompleta, es decir, a 3 años, y con una versión recortada a un año, con un nivel de confianza del 95% y del 99%. Esta elección se hizo para considerar los impactos de la pandemia del COVID-19 en el mercado de valores.

Resultados a 3 años

Comenzando con los datos a 3 años, los resultados y el proceso de su obtención se muestra a continuación:


ALFA_3 <- xts(precios[,2:13], order.by = (precios$Date),)

#Rendimientos
rendimientos <- na.omit(Return.calculate(ALFA_3), method = "log")

#Desviación estándar
sd_portafolio <- apply(rendimientos, 2, sd)

cor_portafolio <- cor(rendimientos, use = "complete.obs", method = "pearson")

cov_portafolio <- diag(sd_portafolio) %*%
  cor_portafolio %*%
  diag(sd_portafolio)

cov_portafolio <- cov(rendimientos, use = "complete.obs", method = "pearson")


#

weights <- c(0.11,0.14,0.08,0.13,0.12,0.08,0.04,0.05,0.08,0.08,0.09,0)
volport <- sqrt(t(as.matrix(weights)) %*%
                  cov_portafolio %*%
                  as.matrix(weights))
rport <- rendimientos %*%
  as.matrix(weights)

sd1 <- StdDev(rendimientos)
sd2 <- StdDev(rendimientos, weights = weights, portfolio_method = "component")

Cálculo a 95% de confianza:


alpha.p <- 0.025
h <- 1
pv <- 1000000 #dólares

# Parametrico - 0.025
varpn <- sd_portafolio * qnorm(alpha.p) * sqrt(h) * pv
varpn
varpn_port <- sd(rport) * qnorm(alpha.p) * sqrt(h) * pv
varpn_port
# Historico - 0.05
alpha.h <- 0.05
n <- 11
m <- nrow(rendimientos)
pnl <- data.frame(percentile = 0: (m-1)/(m-1))

for (i in 1:n){
  pnl <- cbind(pnl, sort(coredata(rendimientos[,i], decreasing = F)))
}

nombres <- c("ARCA", "AMXB","BIMBO","CEMEX","FEMSA","GCARSO","INBURSA","BANORTE",
             "GMEXICO","COCA","WALMART")
names(pnl)[2:(n+1)] <- nombres


varh <- apply(rendimientos, 2, quantile, alpha.h) * sqrt(h) * pv


varh_port <- quantile(rport, alpha.h) * sqrt(h) * pv

# Monte Carlo

a <- chol(cor_portafolio) #distribución cholesky
e <- matrix(rnorm(1000*11), ncol = 12)
r_mc <- e %*% a
cor_mc <- cor(r_mc)

rport_mc <- r_mc %*% as.matrix(weights)


varmc <- apply(r_mc, 2, quantile, alpha.h) * sqrt(h) * pv # individual


varmc_port <- quantile(rport_mc, alpha.h) * sqrt(h) * pv

Con el 95% de confianza, los resultados son:

VaR Paramétrico VaR Histórico VaR Montecarlo
Portafolio -9,549,193.07 -23,993.00 -1,040,226
IPC -27,824.69 -22,826.46 -1,587,463

Cálculo a 99% de confianza:


alpha.p <- 0.01/2
h <- 1
pv <- 1000000 #dólares

# Parametrico - 0.025
varpn <- sd_portafolio * qnorm(alpha.p) * sqrt(h) * pv
varpn
varpn_port <- sd(rport) * qnorm(alpha.p) * sqrt(h) * pv
varpn_port
# Historico - 0.05
alpha.h <- 0.01
n <- 11
m <- nrow(rendimientos)
pnl <- data.frame(percentile = 0: (m-1)/(m-1))

for (i in 1:n){
  pnl <- cbind(pnl, sort(coredata(rendimientos[,i], decreasing = F)))
}

nombres <- c("ARCA", "AMXB","BIMBO","CEMEX","FEMSA","GCARSO","INBURSA","BANORTE",
             "GMEXICO","COCA","WALMART")
names(pnl)[2:(n+1)] <- nombres


varh <- apply(rendimientos, 2, quantile, alpha.h) * sqrt(h) * pv
varh
varh_port <- quantile(rport, alpha.h) * sqrt(h) * pv
varh_port
# Monte Carlo

a <- chol(cor_portafolio) #distribución cholesky
e <- matrix(rnorm(1000*11), ncol = 12)
r_mc <- e %*% a
cor_mc <- cor(r_mc)

rport_mc <- r_mc %*% as.matrix(weights)


varmc <- apply(r_mc, 2, quantile, alpha.h) * sqrt(h) * pv # individual
varmc
varmc_port <- quantile(rport_mc, alpha.h) * sqrt(h) * pv
varmc_port

Con el 99% de confianza, los resultados son:

VaR Paramétrico VaR Histórico VaR Montecarlo
Portafolio -12,549,767.00 -38,497.97 -1,547,624
IPC -36,567.85 -31,675.31 -2,292,008

Resultados a 1 año

Siguiendo la misma metodología anterior, a continuación se muestran los resultados obtenidos para el VaR a 1 año.


ALFA_1 <- xts(precios[,2:13], order.by = (precios$Date),)

ALFA_1 <- ALFA_1["2022-05-31/"]

#Rendimientos
rendimientos <- na.omit(Return.calculate(ALFA_1), method = "log")

#Desviación estándar
sd_portafolio <- apply(rendimientos, 2, sd)

cor_portafolio <- cor(rendimientos, use = "complete.obs", method = "pearson")

cov_portafolio <- diag(sd_portafolio) %*%
  cor_portafolio %*%
  diag(sd_portafolio)

cov_portafolio <- cov(rendimientos, use = "complete.obs", method = "pearson")


#

weights <- c(0.11,0.14,0.08,0.13,0.12,0.08,0.04,0.05,0.08,0.08,0.09,0)
volport <- sqrt(t(as.matrix(weights)) %*%
                  cov_portafolio %*%
                  as.matrix(weights))
rport <- rendimientos %*%
  as.matrix(weights)

sd1 <- StdDev(rendimientos)
sd2 <- StdDev(rendimientos, weights = weights, portfolio_method = "component")

Cálculo a 95% de confianza:


alpha.p <- 0.025
h <- 1
pv <- 1000000 #dólares

# Parametrico - 0.025
varpn <- sd_portafolio * qnorm(alpha.p) * sqrt(h) * pv
varpn
varpn_port <- sd(rport) * qnorm(alpha.p) * sqrt(h) * pv
varpn_port
# Historico - 0.05
alpha.h <- 0.05
n <- 11
m <- nrow(rendimientos)
pnl <- data.frame(percentile = 0: (m-1)/(m-1))

for (i in 1:n){
  pnl <- cbind(pnl, sort(coredata(rendimientos[,i], decreasing = F)))
}

nombres <- c("ARCA", "AMXB","BIMBO","CEMEX","FEMSA","GCARSO","INBURSA","BANORTE",
             "GMEXICO","COCA","WALMART")
names(pnl)[2:(n+1)] <- nombres


varh <- apply(rendimientos, 2, quantile, alpha.h) * sqrt(h) * pv
varh
varh_port <- quantile(rport, alpha.h) * sqrt(h) * pv
varh_port
# Monte Carlo

a <- chol(cor_portafolio) #distribución cholesky
e <- matrix(rnorm(1000*11), ncol = 12)
r_mc <- e %*% a
cor_mc <- cor(r_mc)

rport_mc <- r_mc %*% as.matrix(weights)


varmc <- apply(r_mc, 2, quantile, alpha.h) * sqrt(h) * pv # individual
varmc
varmc_port <- quantile(rport_mc, alpha.h) * sqrt(h) * pv
varmc_port

Con el 95% de confianza, los resultados son:

VaR Paramétrico VaR Histórico VaR Montecarlo
Portafolio -26,099.97 -21,716.29 -1,054,526
IPC -26,368.42 -21,632.30 -1,583,998

Cálculo a 99% de confianza:


alpha.p <- 0.01/2
h <- 1
pv <- 1000000 #dólares

# Parametrico - 0.025
varpn <- sd_portafolio * qnorm(alpha.p) * sqrt(h) * pv
varpn
varpn_port <- sd(rport) * qnorm(alpha.p) * sqrt(h) * pv
varpn_port
# Historico - 0.05
alpha.h <- 0.01
n <- 11
m <- nrow(rendimientos)
pnl <- data.frame(percentile = 0: (m-1)/(m-1))

for (i in 1:n){
  pnl <- cbind(pnl, sort(coredata(rendimientos[,i], decreasing = F)))
}

nombres <- c("ARCA", "AMXB","BIMBO","CEMEX","FEMSA","GCARSO","INBURSA","BANORTE",
             "GMEXICO","COCA","WALMART")
names(pnl)[2:(n+1)] <- nombres


varh <- apply(rendimientos, 2, quantile, alpha.h) * sqrt(h) * pv
varh
varh_port <- quantile(rport, alpha.h) * sqrt(h) * pv
varh_port
# Monte Carlo

a <- chol(cor_portafolio) #distribución cholesky
e <- matrix(rnorm(1000*11), ncol = 12)
r_mc <- e %*% a
cor_mc <- cor(r_mc)

rport_mc <- r_mc %*% as.matrix(weights)


varmc <- apply(r_mc, 2, quantile, alpha.h) * sqrt(h) * pv # individual
varmc
varmc_port <- quantile(rport_mc, alpha.h) * sqrt(h) * pv
varmc_port

Con el 99% de confianza, los resultados son:

VaR Paramétrico VaR Histórico VaR Montecarlo
Portafolio -34,301.17 -29,203.91 -1,453,805
IPC -34,653.98 -30,042.33 -2,252,665
LS0tCnRpdGxlOiAiQ8OhbGN1bG8gZGVsIFZhUiIKYXV0aG9yOiAiRXF1aXBvIE5hY2lvbmFsIC0gUG9ydGFmb2xpbyBBTEZBIgpkYXRlOiAiNiBkZSBqdW5pbyBkZWwgMjAyMyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHllcwogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKIyMgTGlicmVyw61hcyB5IGRhdG9zCgpFbCBwcmltZXIgcGFzbyBjb25zaXN0ZSBsYSBpbXBvcnRhY2nDs24gZGUgbGFzIGxpYnJlcsOtYXMgeSBsb3MgZGF0b3MuIEVuIGVsIGNhc28gZGUgbGFzIHByaW1lcmFzLCBlc3RhcyBwZXJ0ZW5lY2VuIGEgbGEgcGFxdWV0ZXLDrWEgZXN0YWTDrXN0aWNhIGRlIFIsIHkgZW4gZWwgY2FzbyBkZWwgc2VndW5kbyBwdW50bywgZXN0b3MgZnVlcm9uIHJlY2FiYWRvcyBkZSBsb3MgcHJlY2lvcyBkZSBjaWVycmUgZGUgKioqUmVmaW5pdGl2KioqLgoKYGBge3J9CmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHh0cykKbGlicmFyeShkcGx5cikKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpCgpzZXR3ZCgiL1VzZXJzL3JvZ2VsaW8vRGVza3RvcC9SIikKCnByZWNpb3MgPC0gcmVhZF9leGNlbCgifi9EZXNrdG9wL1IvcHJlY2lvc3MueGxzeCIpCgoKYGBgCgpDb24gZXN0bywgc2UgcHJvY2VkZSBhIGxhIGxpbXBpZXphIGRlIGxvcyBkYXRvcywgbGEgY3VhbCBlbiBlc3RlIGNhc28gc29sbyBjb25zaXN0ZSBlbiBjb252ZXJ0aXIgbGEgZmVjaGEgZGUgbG9zIHByZWNpb3MgYWwgZm9ybWF0byBkZXNlYWRvOgoKYGBge3J9CnByZWNpb3MgPC0gcHJlY2lvcyAlPiUgIAogIG11dGF0ZShEYXRlID0gY29udmVydF90b19kYXRlKERhdGUsIGNoYXJhY3Rlcl9mdW4gPSBsdWJyaWRhdGU6Om1keSkpCgpwcmVjaW9zICNSZXN1bHRhZG8gZmluYWwKYGBgCiMjIEPDoWxjdWxvIGRlbCBWYVIKCkNvbiBiYXNlIGVuIGVzdG8sIGNvbW8gc2UgcGVyY2liZSBlbiBsYSB0YWJsYSBhbnRlcmlvciwgc2UgcmVjb3BpbGFyb24gZGF0b3MgYSBwYXJ0aXIgZGVsIDMxIGRlIG1heW8gZGUgMjAyMCBoYXN0YSBlbCAxIGRlIGp1bmlvIGRlIDIwMjMuIFBhcmEgdGVuZXIgdW4gYW7DoWxpc2lzIG3DoXMgcHJvZnVuZG8sIHNlIG9wdMOzIHBvciB0YWJhamFyIGNvbiBsYSBiYXNlIG9tcGxldGEsIGVzIGRlY2lyLCBhIDMgYcOxb3MsIHkgY29uIHVuYSB2ZXJzacOzbiByZWNvcnRhZGEgYSB1biBhw7FvLCBjb24gdW4gbml2ZWwgZGUgY29uZmlhbnphIGRlbCA5NSUgeSBkZWwgOTklLiBFc3RhIGVsZWNjacOzbiBzZSBoaXpvIHBhcmEgY29uc2lkZXJhciBsb3MgaW1wYWN0b3MgZGUgbGEgcGFuZGVtaWEgZGVsIENPVklELTE5IGVuIGVsIG1lcmNhZG8gZGUgdmFsb3Jlcy4KCgojIyMgUmVzdWx0YWRvcyBhIDMgYcOxb3MKCkNvbWVuemFuZG8gY29uIGxvcyBkYXRvcyBhIDMgYcOxb3MsIGxvcyByZXN1bHRhZG9zIHkgZWwgcHJvY2VzbyBkZSBzdSBvYnRlbmNpw7NuIHNlIG11ZXN0cmEgYSBjb250aW51YWNpw7NuOiAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQoKQUxGQV8zIDwtIHh0cyhwcmVjaW9zWywyOjEzXSwgb3JkZXIuYnkgPSAocHJlY2lvcyREYXRlKSwpCgojUmVuZGltaWVudG9zCnJlbmRpbWllbnRvcyA8LSBuYS5vbWl0KFJldHVybi5jYWxjdWxhdGUoQUxGQV8zKSwgbWV0aG9kID0gImxvZyIpCgojRGVzdmlhY2nDs24gZXN0w6FuZGFyCnNkX3BvcnRhZm9saW8gPC0gYXBwbHkocmVuZGltaWVudG9zLCAyLCBzZCkKCmNvcl9wb3J0YWZvbGlvIDwtIGNvcihyZW5kaW1pZW50b3MsIHVzZSA9ICJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAicGVhcnNvbiIpCgpjb3ZfcG9ydGFmb2xpbyA8LSBkaWFnKHNkX3BvcnRhZm9saW8pICUqJQogIGNvcl9wb3J0YWZvbGlvICUqJQogIGRpYWcoc2RfcG9ydGFmb2xpbykKCmNvdl9wb3J0YWZvbGlvIDwtIGNvdihyZW5kaW1pZW50b3MsIHVzZSA9ICJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAicGVhcnNvbiIpCgoKIwoKd2VpZ2h0cyA8LSBjKDAuMTEsMC4xNCwwLjA4LDAuMTMsMC4xMiwwLjA4LDAuMDQsMC4wNSwwLjA4LDAuMDgsMC4wOSwwKQp2b2xwb3J0IDwtIHNxcnQodChhcy5tYXRyaXgod2VpZ2h0cykpICUqJQogICAgICAgICAgICAgICAgICBjb3ZfcG9ydGFmb2xpbyAlKiUKICAgICAgICAgICAgICAgICAgYXMubWF0cml4KHdlaWdodHMpKQpycG9ydCA8LSByZW5kaW1pZW50b3MgJSolCiAgYXMubWF0cml4KHdlaWdodHMpCgpzZDEgPC0gU3RkRGV2KHJlbmRpbWllbnRvcykKc2QyIDwtIFN0ZERldihyZW5kaW1pZW50b3MsIHdlaWdodHMgPSB3ZWlnaHRzLCBwb3J0Zm9saW9fbWV0aG9kID0gImNvbXBvbmVudCIpCgoKYGBgCgojIyMjIEPDoWxjdWxvIGEgOTUlIGRlIGNvbmZpYW56YTogCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KCmFscGhhLnAgPC0gMC4wMjUKaCA8LSAxCnB2IDwtIDEwMDAwMDAgI2TDs2xhcmVzCgojIFBhcmFtZXRyaWNvIC0gMC4wMjUKdmFycG4gPC0gc2RfcG9ydGFmb2xpbyAqIHFub3JtKGFscGhhLnApICogc3FydChoKSAqIHB2CnZhcnBuCgp2YXJwbl9wb3J0IDwtIHNkKHJwb3J0KSAqIHFub3JtKGFscGhhLnApICogc3FydChoKSAqIHB2CnZhcnBuX3BvcnQKCiMgSGlzdG9yaWNvIC0gMC4wNQphbHBoYS5oIDwtIDAuMDUKbiA8LSAxMQptIDwtIG5yb3cocmVuZGltaWVudG9zKQpwbmwgPC0gZGF0YS5mcmFtZShwZXJjZW50aWxlID0gMDogKG0tMSkvKG0tMSkpCgpmb3IgKGkgaW4gMTpuKXsKICBwbmwgPC0gY2JpbmQocG5sLCBzb3J0KGNvcmVkYXRhKHJlbmRpbWllbnRvc1ssaV0sIGRlY3JlYXNpbmcgPSBGKSkpCn0KCm5vbWJyZXMgPC0gYygiQVJDQSIsICJBTVhCIiwiQklNQk8iLCJDRU1FWCIsIkZFTVNBIiwiR0NBUlNPIiwiSU5CVVJTQSIsIkJBTk9SVEUiLAogICAgICAgICAgICAgIkdNRVhJQ08iLCJDT0NBIiwiV0FMTUFSVCIpCm5hbWVzKHBubClbMjoobisxKV0gPC0gbm9tYnJlcwoKCnZhcmggPC0gYXBwbHkocmVuZGltaWVudG9zLCAyLCBxdWFudGlsZSwgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYKCgp2YXJoX3BvcnQgPC0gcXVhbnRpbGUocnBvcnQsIGFscGhhLmgpICogc3FydChoKSAqIHB2CgojIE1vbnRlIENhcmxvCgphIDwtIGNob2woY29yX3BvcnRhZm9saW8pICNkaXN0cmlidWNpw7NuIGNob2xlc2t5CmUgPC0gbWF0cml4KHJub3JtKDEwMDAqMTEpLCBuY29sID0gMTIpCnJfbWMgPC0gZSAlKiUgYQpjb3JfbWMgPC0gY29yKHJfbWMpCgpycG9ydF9tYyA8LSByX21jICUqJSBhcy5tYXRyaXgod2VpZ2h0cykKCgp2YXJtYyA8LSBhcHBseShyX21jLCAyLCBxdWFudGlsZSwgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYgIyBpbmRpdmlkdWFsCgoKdmFybWNfcG9ydCA8LSBxdWFudGlsZShycG9ydF9tYywgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYKCgpgYGAKCkNvbiBlbCA5NSUgZGUgY29uZmlhbnphLCBsb3MgcmVzdWx0YWRvcyBzb246CgoKYGBge3IsIGVjaG89RkFMU0V9CsONbmRpY2UgPC0gYygiUG9ydGFmb2xpbyIsICJJUEMiKQpWYVIucCA8LSBjKHZhcnBuX3BvcnQsIHZhcnBuW1siSVBDIl1dKQpWYVIuaCA8LSBjKHZhcmhfcG9ydCwgdmFyaFtbIklQQyJdXSkKVmFSLm1jIDwtIGModmFybWNfcG9ydCwgdmFybWNbWyJJUEMiXV0pCgpkYXRhIDwtIGRhdGEuZnJhbWUow61uZGljZSA9IMONbmRpY2UsIFZhUi5wID0gVmFSLnAsIFZhUi5oID0gVmFSLmgsIFZhUi5tYyA9IFZhUi5tYykKZGF0YSRWYVIucCA8LSBmb3JtYXQoZGF0YSRWYVIucCwgYmlnLm1hcmsgPSAiLCIpCmRhdGEkVmFSLmggPC0gZm9ybWF0KGRhdGEkVmFSLmgsIGJpZy5tYXJrID0gIiwiKQpkYXRhJFZhUi5tYyA8LSBmb3JtYXQoZGF0YSRWYVIubWMsIGJpZy5tYXJrID0gIiwiKQoKY29sbmFtZXMoZGF0YSkgPC0gYygiIiwgIlZhUiBQYXJhbcOpdHJpY28iLCAiVmFSIEhpc3TDs3JpY28iLCAiVmFSIE1vbnRlY2FybG8iKQoKIyBDcmVhdGUgdGhlIHRhYmxlIHVzaW5nIGthYmxlKCkKKHRhYmxlIDwtIGthYmxlKGRhdGEsIGZvcm1hdCA9ICJodG1sIiwgYWxpZ24gPSAiYyIsIHJvdy5uYW1lcyA9IEZBTFNFKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSwgZnVsbF93aWR0aCA9IEZBTFNFKSkKYGBgCgojIyMjIEPDoWxjdWxvIGEgOTklIGRlIGNvbmZpYW56YTogCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KCmFscGhhLnAgPC0gMC4wMS8yCmggPC0gMQpwdiA8LSAxMDAwMDAwICNkw7NsYXJlcwoKIyBQYXJhbWV0cmljbyAtIDAuMDI1CnZhcnBuIDwtIHNkX3BvcnRhZm9saW8gKiBxbm9ybShhbHBoYS5wKSAqIHNxcnQoaCkgKiBwdgp2YXJwbgoKdmFycG5fcG9ydCA8LSBzZChycG9ydCkgKiBxbm9ybShhbHBoYS5wKSAqIHNxcnQoaCkgKiBwdgp2YXJwbl9wb3J0CgojIEhpc3RvcmljbyAtIDAuMDUKYWxwaGEuaCA8LSAwLjAxCm4gPC0gMTEKbSA8LSBucm93KHJlbmRpbWllbnRvcykKcG5sIDwtIGRhdGEuZnJhbWUocGVyY2VudGlsZSA9IDA6IChtLTEpLyhtLTEpKQoKZm9yIChpIGluIDE6bil7CiAgcG5sIDwtIGNiaW5kKHBubCwgc29ydChjb3JlZGF0YShyZW5kaW1pZW50b3NbLGldLCBkZWNyZWFzaW5nID0gRikpKQp9Cgpub21icmVzIDwtIGMoIkFSQ0EiLCAiQU1YQiIsIkJJTUJPIiwiQ0VNRVgiLCJGRU1TQSIsIkdDQVJTTyIsIklOQlVSU0EiLCJCQU5PUlRFIiwKICAgICAgICAgICAgICJHTUVYSUNPIiwiQ09DQSIsIldBTE1BUlQiKQpuYW1lcyhwbmwpWzI6KG4rMSldIDwtIG5vbWJyZXMKCgp2YXJoIDwtIGFwcGx5KHJlbmRpbWllbnRvcywgMiwgcXVhbnRpbGUsIGFscGhhLmgpICogc3FydChoKSAqIHB2CnZhcmgKCnZhcmhfcG9ydCA8LSBxdWFudGlsZShycG9ydCwgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYKdmFyaF9wb3J0CiMgTW9udGUgQ2FybG8KCmEgPC0gY2hvbChjb3JfcG9ydGFmb2xpbykgI2Rpc3RyaWJ1Y2nDs24gY2hvbGVza3kKZSA8LSBtYXRyaXgocm5vcm0oMTAwMCoxMSksIG5jb2wgPSAxMikKcl9tYyA8LSBlICUqJSBhCmNvcl9tYyA8LSBjb3Iocl9tYykKCnJwb3J0X21jIDwtIHJfbWMgJSolIGFzLm1hdHJpeCh3ZWlnaHRzKQoKCnZhcm1jIDwtIGFwcGx5KHJfbWMsIDIsIHF1YW50aWxlLCBhbHBoYS5oKSAqIHNxcnQoaCkgKiBwdiAjIGluZGl2aWR1YWwKdmFybWMKCnZhcm1jX3BvcnQgPC0gcXVhbnRpbGUocnBvcnRfbWMsIGFscGhhLmgpICogc3FydChoKSAqIHB2CnZhcm1jX3BvcnQKCmBgYAoKQ29uIGVsIDk5JSBkZSBjb25maWFuemEsIGxvcyByZXN1bHRhZG9zIHNvbjoKCgpgYGB7ciwgZWNobz1GQUxTRX0Kw41uZGljZSA8LSBjKCJQb3J0YWZvbGlvIiwgIklQQyIpClZhUi5wIDwtIGModmFycG5fcG9ydCwgdmFycG5bWyJJUEMiXV0pClZhUi5oIDwtIGModmFyaF9wb3J0LCB2YXJoW1siSVBDIl1dKQpWYVIubWMgPC0gYyh2YXJtY19wb3J0LCB2YXJtY1tbIklQQyJdXSkKCmRhdGEgPC0gZGF0YS5mcmFtZSjDrW5kaWNlID0gw41uZGljZSwgVmFSLnAgPSBWYVIucCwgVmFSLmggPSBWYVIuaCwgVmFSLm1jID0gVmFSLm1jKQpkYXRhJFZhUi5wIDwtIGZvcm1hdChkYXRhJFZhUi5wLCBiaWcubWFyayA9ICIsIikKZGF0YSRWYVIuaCA8LSBmb3JtYXQoZGF0YSRWYVIuaCwgYmlnLm1hcmsgPSAiLCIpCmRhdGEkVmFSLm1jIDwtIGZvcm1hdChkYXRhJFZhUi5tYywgYmlnLm1hcmsgPSAiLCIpCgpjb2xuYW1lcyhkYXRhKSA8LSBjKCIiLCAiVmFSIFBhcmFtw6l0cmljbyIsICJWYVIgSGlzdMOzcmljbyIsICJWYVIgTW9udGVjYXJsbyIpCgojIENyZWF0ZSB0aGUgdGFibGUgdXNpbmcga2FibGUoKQoodGFibGUgPC0ga2FibGUoZGF0YSwgZm9ybWF0ID0gImh0bWwiLCBhbGlnbiA9ICJjIiwgcm93Lm5hbWVzID0gRkFMU0UpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmdWxsX3dpZHRoID0gRkFMU0UpKQpgYGAKCiMjIyBSZXN1bHRhZG9zIGEgMSBhw7FvCgpTaWd1aWVuZG8gbGEgbWlzbWEgbWV0b2RvbG9nw61hIGFudGVyaW9yLCBhIGNvbnRpbnVhY2nDs24gc2UgbXVlc3RyYW4gbG9zIHJlc3VsdGFkb3Mgb2J0ZW5pZG9zIHBhcmEgZWwgVmFSIGEgMSBhw7FvLiAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQoKQUxGQV8xIDwtIHh0cyhwcmVjaW9zWywyOjEzXSwgb3JkZXIuYnkgPSAocHJlY2lvcyREYXRlKSwpCgpBTEZBXzEgPC0gQUxGQV8xWyIyMDIyLTA1LTMxLyJdCgojUmVuZGltaWVudG9zCnJlbmRpbWllbnRvcyA8LSBuYS5vbWl0KFJldHVybi5jYWxjdWxhdGUoQUxGQV8xKSwgbWV0aG9kID0gImxvZyIpCgojRGVzdmlhY2nDs24gZXN0w6FuZGFyCnNkX3BvcnRhZm9saW8gPC0gYXBwbHkocmVuZGltaWVudG9zLCAyLCBzZCkKCmNvcl9wb3J0YWZvbGlvIDwtIGNvcihyZW5kaW1pZW50b3MsIHVzZSA9ICJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAicGVhcnNvbiIpCgpjb3ZfcG9ydGFmb2xpbyA8LSBkaWFnKHNkX3BvcnRhZm9saW8pICUqJQogIGNvcl9wb3J0YWZvbGlvICUqJQogIGRpYWcoc2RfcG9ydGFmb2xpbykKCmNvdl9wb3J0YWZvbGlvIDwtIGNvdihyZW5kaW1pZW50b3MsIHVzZSA9ICJjb21wbGV0ZS5vYnMiLCBtZXRob2QgPSAicGVhcnNvbiIpCgoKIwoKd2VpZ2h0cyA8LSBjKDAuMTEsMC4xNCwwLjA4LDAuMTMsMC4xMiwwLjA4LDAuMDQsMC4wNSwwLjA4LDAuMDgsMC4wOSwwKQp2b2xwb3J0IDwtIHNxcnQodChhcy5tYXRyaXgod2VpZ2h0cykpICUqJQogICAgICAgICAgICAgICAgICBjb3ZfcG9ydGFmb2xpbyAlKiUKICAgICAgICAgICAgICAgICAgYXMubWF0cml4KHdlaWdodHMpKQpycG9ydCA8LSByZW5kaW1pZW50b3MgJSolCiAgYXMubWF0cml4KHdlaWdodHMpCgpzZDEgPC0gU3RkRGV2KHJlbmRpbWllbnRvcykKc2QyIDwtIFN0ZERldihyZW5kaW1pZW50b3MsIHdlaWdodHMgPSB3ZWlnaHRzLCBwb3J0Zm9saW9fbWV0aG9kID0gImNvbXBvbmVudCIpCgoKYGBgCgojIyMjIEPDoWxjdWxvIGEgOTUlIGRlIGNvbmZpYW56YTogCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KCmFscGhhLnAgPC0gMC4wMjUKaCA8LSAxCnB2IDwtIDEwMDAwMDAgI2TDs2xhcmVzCgojIFBhcmFtZXRyaWNvIC0gMC4wMjUKdmFycG4gPC0gc2RfcG9ydGFmb2xpbyAqIHFub3JtKGFscGhhLnApICogc3FydChoKSAqIHB2CnZhcnBuCgp2YXJwbl9wb3J0IDwtIHNkKHJwb3J0KSAqIHFub3JtKGFscGhhLnApICogc3FydChoKSAqIHB2CnZhcnBuX3BvcnQKCiMgSGlzdG9yaWNvIC0gMC4wNQphbHBoYS5oIDwtIDAuMDUKbiA8LSAxMQptIDwtIG5yb3cocmVuZGltaWVudG9zKQpwbmwgPC0gZGF0YS5mcmFtZShwZXJjZW50aWxlID0gMDogKG0tMSkvKG0tMSkpCgpmb3IgKGkgaW4gMTpuKXsKICBwbmwgPC0gY2JpbmQocG5sLCBzb3J0KGNvcmVkYXRhKHJlbmRpbWllbnRvc1ssaV0sIGRlY3JlYXNpbmcgPSBGKSkpCn0KCm5vbWJyZXMgPC0gYygiQVJDQSIsICJBTVhCIiwiQklNQk8iLCJDRU1FWCIsIkZFTVNBIiwiR0NBUlNPIiwiSU5CVVJTQSIsIkJBTk9SVEUiLAogICAgICAgICAgICAgIkdNRVhJQ08iLCJDT0NBIiwiV0FMTUFSVCIpCm5hbWVzKHBubClbMjoobisxKV0gPC0gbm9tYnJlcwoKCnZhcmggPC0gYXBwbHkocmVuZGltaWVudG9zLCAyLCBxdWFudGlsZSwgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYKdmFyaAoKdmFyaF9wb3J0IDwtIHF1YW50aWxlKHJwb3J0LCBhbHBoYS5oKSAqIHNxcnQoaCkgKiBwdgp2YXJoX3BvcnQKIyBNb250ZSBDYXJsbwoKYSA8LSBjaG9sKGNvcl9wb3J0YWZvbGlvKSAjZGlzdHJpYnVjacOzbiBjaG9sZXNreQplIDwtIG1hdHJpeChybm9ybSgxMDAwKjExKSwgbmNvbCA9IDEyKQpyX21jIDwtIGUgJSolIGEKY29yX21jIDwtIGNvcihyX21jKQoKcnBvcnRfbWMgPC0gcl9tYyAlKiUgYXMubWF0cml4KHdlaWdodHMpCgoKdmFybWMgPC0gYXBwbHkocl9tYywgMiwgcXVhbnRpbGUsIGFscGhhLmgpICogc3FydChoKSAqIHB2ICMgaW5kaXZpZHVhbAp2YXJtYwoKdmFybWNfcG9ydCA8LSBxdWFudGlsZShycG9ydF9tYywgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYKdmFybWNfcG9ydAoKYGBgCgpDb24gZWwgOTUlIGRlIGNvbmZpYW56YSwgbG9zIHJlc3VsdGFkb3Mgc29uOgoKYGBge3IsIGVjaG89RkFMU0V9CsONbmRpY2UgPC0gYygiUG9ydGFmb2xpbyIsICJJUEMiKQpWYVIucCA8LSBjKHZhcnBuX3BvcnQsIHZhcnBuW1siSVBDIl1dKQpWYVIuaCA8LSBjKHZhcmhfcG9ydCwgdmFyaFtbIklQQyJdXSkKVmFSLm1jIDwtIGModmFybWNfcG9ydCwgdmFybWNbWyJJUEMiXV0pCgpkYXRhIDwtIGRhdGEuZnJhbWUow61uZGljZSA9IMONbmRpY2UsIFZhUi5wID0gVmFSLnAsIFZhUi5oID0gVmFSLmgsIFZhUi5tYyA9IFZhUi5tYykKZGF0YSRWYVIucCA8LSBmb3JtYXQoZGF0YSRWYVIucCwgYmlnLm1hcmsgPSAiLCIpCmRhdGEkVmFSLmggPC0gZm9ybWF0KGRhdGEkVmFSLmgsIGJpZy5tYXJrID0gIiwiKQpkYXRhJFZhUi5tYyA8LSBmb3JtYXQoZGF0YSRWYVIubWMsIGJpZy5tYXJrID0gIiwiKQoKY29sbmFtZXMoZGF0YSkgPC0gYygiIiwgIlZhUiBQYXJhbcOpdHJpY28iLCAiVmFSIEhpc3TDs3JpY28iLCAiVmFSIE1vbnRlY2FybG8iKQoKIyBDcmVhdGUgdGhlIHRhYmxlIHVzaW5nIGthYmxlKCkKKHRhYmxlIDwtIGthYmxlKGRhdGEsIGZvcm1hdCA9ICJodG1sIiwgYWxpZ24gPSAiYyIsIHJvdy5uYW1lcyA9IEZBTFNFKSAlPiUKICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIsICJjb25kZW5zZWQiKSwgZnVsbF93aWR0aCA9IEZBTFNFKSkKYGBgCgojIyMjIEPDoWxjdWxvIGEgOTklIGRlIGNvbmZpYW56YTogCmBgYHtyLCByZXN1bHRzPSdoaWRlJ30KCmFscGhhLnAgPC0gMC4wMS8yCmggPC0gMQpwdiA8LSAxMDAwMDAwICNkw7NsYXJlcwoKIyBQYXJhbWV0cmljbyAtIDAuMDI1CnZhcnBuIDwtIHNkX3BvcnRhZm9saW8gKiBxbm9ybShhbHBoYS5wKSAqIHNxcnQoaCkgKiBwdgp2YXJwbgoKdmFycG5fcG9ydCA8LSBzZChycG9ydCkgKiBxbm9ybShhbHBoYS5wKSAqIHNxcnQoaCkgKiBwdgp2YXJwbl9wb3J0CgojIEhpc3RvcmljbyAtIDAuMDUKYWxwaGEuaCA8LSAwLjAxCm4gPC0gMTEKbSA8LSBucm93KHJlbmRpbWllbnRvcykKcG5sIDwtIGRhdGEuZnJhbWUocGVyY2VudGlsZSA9IDA6IChtLTEpLyhtLTEpKQoKZm9yIChpIGluIDE6bil7CiAgcG5sIDwtIGNiaW5kKHBubCwgc29ydChjb3JlZGF0YShyZW5kaW1pZW50b3NbLGldLCBkZWNyZWFzaW5nID0gRikpKQp9Cgpub21icmVzIDwtIGMoIkFSQ0EiLCAiQU1YQiIsIkJJTUJPIiwiQ0VNRVgiLCJGRU1TQSIsIkdDQVJTTyIsIklOQlVSU0EiLCJCQU5PUlRFIiwKICAgICAgICAgICAgICJHTUVYSUNPIiwiQ09DQSIsIldBTE1BUlQiKQpuYW1lcyhwbmwpWzI6KG4rMSldIDwtIG5vbWJyZXMKCgp2YXJoIDwtIGFwcGx5KHJlbmRpbWllbnRvcywgMiwgcXVhbnRpbGUsIGFscGhhLmgpICogc3FydChoKSAqIHB2CnZhcmgKCnZhcmhfcG9ydCA8LSBxdWFudGlsZShycG9ydCwgYWxwaGEuaCkgKiBzcXJ0KGgpICogcHYKdmFyaF9wb3J0CiMgTW9udGUgQ2FybG8KCmEgPC0gY2hvbChjb3JfcG9ydGFmb2xpbykgI2Rpc3RyaWJ1Y2nDs24gY2hvbGVza3kKZSA8LSBtYXRyaXgocm5vcm0oMTAwMCoxMSksIG5jb2wgPSAxMikKcl9tYyA8LSBlICUqJSBhCmNvcl9tYyA8LSBjb3Iocl9tYykKCnJwb3J0X21jIDwtIHJfbWMgJSolIGFzLm1hdHJpeCh3ZWlnaHRzKQoKCnZhcm1jIDwtIGFwcGx5KHJfbWMsIDIsIHF1YW50aWxlLCBhbHBoYS5oKSAqIHNxcnQoaCkgKiBwdiAjIGluZGl2aWR1YWwKdmFybWMKCnZhcm1jX3BvcnQgPC0gcXVhbnRpbGUocnBvcnRfbWMsIGFscGhhLmgpICogc3FydChoKSAqIHB2CnZhcm1jX3BvcnQKCmBgYAoKQ29uIGVsIDk5JSBkZSBjb25maWFuemEsIGxvcyByZXN1bHRhZG9zIHNvbjoKCgpgYGB7ciwgZWNobz1GQUxTRX0Kw41uZGljZSA8LSBjKCJQb3J0YWZvbGlvIiwgIklQQyIpClZhUi5wIDwtIGModmFycG5fcG9ydCwgdmFycG5bWyJJUEMiXV0pClZhUi5oIDwtIGModmFyaF9wb3J0LCB2YXJoW1siSVBDIl1dKQpWYVIubWMgPC0gYyh2YXJtY19wb3J0LCB2YXJtY1tbIklQQyJdXSkKCmRhdGEgPC0gZGF0YS5mcmFtZSjDrW5kaWNlID0gw41uZGljZSwgVmFSLnAgPSBWYVIucCwgVmFSLmggPSBWYVIuaCwgVmFSLm1jID0gVmFSLm1jKQpkYXRhJFZhUi5wIDwtIGZvcm1hdChkYXRhJFZhUi5wLCBiaWcubWFyayA9ICIsIikKZGF0YSRWYVIuaCA8LSBmb3JtYXQoZGF0YSRWYVIuaCwgYmlnLm1hcmsgPSAiLCIpCmRhdGEkVmFSLm1jIDwtIGZvcm1hdChkYXRhJFZhUi5tYywgYmlnLm1hcmsgPSAiLCIpCgpjb2xuYW1lcyhkYXRhKSA8LSBjKCIiLCAiVmFSIFBhcmFtw6l0cmljbyIsICJWYVIgSGlzdMOzcmljbyIsICJWYVIgTW9udGVjYXJsbyIpCgojIENyZWF0ZSB0aGUgdGFibGUgdXNpbmcga2FibGUoKQoodGFibGUgPC0ga2FibGUoZGF0YSwgZm9ybWF0ID0gImh0bWwiLCBhbGlnbiA9ICJjIiwgcm93Lm5hbWVzID0gRkFMU0UpICU+JQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiwgImNvbmRlbnNlZCIpLCBmdWxsX3dpZHRoID0gRkFMU0UpKQpgYGAK