Historia del pensamiento Económico
Sebastián Alonso Sosa Pérez

Fluctuaciones del tipo del cambio

Creado: 06-02-2021

Carga de las siguientes librerias

library("tidyverse")
library("data.table") 
library("XML")
library("httr")
library("xts")
library("DT")
library("rugarch")
library(quantmod)
library(tseries)
library(highcharter)

Creación de la función de extracción de datos

extraccion<- function(codigo=NULL,start=NULL,end=NULL){
  vector<- vector()
  datos<- NULL
  for(i in 1:length(codigo)){
                               ex<-  paste0("https://estadisticas.bcrp.gob.pe/estadisticas/series/api/", 
                                                       codigo[i], "/xml/",start,"/",end)
                               
  
                               ObjXML <- httr::GET(ex)
                               L_parseXML <- xmlParse(ObjXML)
                              
                               L_XML <- xmlToList(L_parseXML)
                               
                               dt_BCRP <- data.table::data.table()
                               for (a in 1:length(L_XML$periods)){
                                                                   dt_temp <- data.table(
                                                                                         serie= L_XML$periods[[a]]$v)
                                                                   dt_BCRP <- rbind(dt_BCRP,dt_temp)
                               }
                               vector[i]<- dt_BCRP[,serie:=as.numeric(serie)] 
  }
  for(i in  1: length(codigo)){
    datos<- cbind(datos,vector[[i]])
  }
  datos<- as.data.frame(datos)
  names(datos)<- codigo
  return(datos)
  }

Resultados

Extracción del tipo de cambio

Gráfico dinámico

Captura de las fluctuacciones del tipo de cambio

Especificación de los modelos Garch

  • Forward looking behaviour, requiere pronosticar adecuadamente la volatilidad y el riesgo de un activo.

  • La volatilidad no es una serie observable en el momento t, se requieren datos históricos para estimar la volatilidad.

  • Volatilidad histórica se estima con la varianza del rendimiento simple (cambio en el precio del activo).

Una opción: Exponantially Weigted Moving Average Models (EWMA) que es una extensión del promedio histórico pero haciendo que las observaciones más recientes tengan un mayor peso:

\[ \alpha_t^2=(1-\lambda)\sum_{j=0}^\infty\lambda_{j-1}R^2_{t-1-j} \\ R^2_{t-1-j}= Varianza \ de \ los \ rendimientos \\ \lambda= "decay \ factor" \]

La forma más sencilla es definida como:

\[ \sigma^2_{t+1}=\lambda\sigma_{t}^2+(1-\lambda) R^2_t \]

Implica que la varianza del periodo siguiente como un promedio ponderado de la varianza actual y el rendimiento actual al cuadrado.

Se asume un patrón sistemático en la evolución de la varianza.

Una generalización del modelo ARCH(m) fue desarrollada por Bollerslev (1986) al proponer que la varianza condicional dependa de sus propios rezagos:

\[ h_t=\alpha_0+\sum_{i=1}^m\alpha_i\epsilon^2_{t-i}+\sum_{j=1}^p\beta_jh_{t-i} \\ \epsilon \rightarrow N(0,h_t) \\ \epsilon_t\sqrt{h_tv_t} \\ v_t \sim iidN(0,1) \]

La especificación GARCH se define como un modelo ARCH de orden infinito (Bollerslev, 1986).

Modelo EGARCH(p,q)

En 1990, Pagan y Schwert (1990), y al año siguiente en 1991 Nelson (1991), desarrollaron una versión nueva del modelo GARCH, el EGARCH (modelo exponencial generalizado, auto-regresivo, condicionalmente heterocedástico).El nuevo modelo acaba con las asimetrías en la estimación del efecto de los shocks, al implementar una función 𝑔(𝜀𝑡 ) de las innovaciones 𝜀𝑡,que son variables igual e independientemente distribuidas de media cero, y en las que por tanto el valor de las innovaciones queda recogido por medio de la expresión:

\[ ln\sigma^2_t=w+\beta(\sigma^2_{t-1})+\gamma\frac{u_{t-1}}{\sqrt{\sigma_{t-1}}}+\alpha[\frac{|u_{t-1}|}{\sqrt{\sigma_{t-1}}}-\sqrt{\frac{2}{\sqrt{\pi}}}] \]

El modelo tiene varias ventajas sobre la especificación GARCH pura. En primer lugar, el \(ln(\sigma_t^2)\);es modelado, esto quiere decir, que aunque los parámetros sean negativos, \(\sigma_t^2\)será positivo. Por lo tanto, este modelo no tiene restricciones de no negatividad en los parámetros. En segundo lugar, las asimetrías se permiten bajo la formulación de EGARCH, ya que, si la relación entre la volatilidad y los rendimientos es negativa \(\gamma\) será negativa.

Modelo TGARCH(p,q)

La idea del modelo TGARCH (Treshold GARCH) es dividir la distribución de los shocks en intervalos disjuntos, para luego aproximar una función lineal por tramos bien para la desviación estándar condicional (Zakoian, 1994), bien la varianza condicional (Glosten, Jaganathan, & Runkle , 1993). Si sólo hay dos intervalos, la división es normalmente en un umbral identificado con el número cero, donde la influencia de los shocks positivos se identifica con valores por encima de cero y negativos por debajo de este valor.

Especificación del TGARCH:

\[ \sigma^2_t=w+\sum_{i=1}^s(\alpha_i+\gamma_iN_{t-i})\sigma^2_{t-i}\sum_{j=i}^m\beta_j\sigma^2_{t-j} \]

\[ N_{t-i} =\begin{cases} 1 \rightarrow \alpha_{t-i} <0\\0 \rightarrow \alpha_{t-i} \geqslant 0\end{cases} \]

Suposiciones de distribución del término de error

En la especificación del modelo GARCH, es más apropiado considerar la elección en el supuesto de distribución del término de error. Este ejercicio asumió tres supuestos de distribución; La distribución normal (NORM), la distribución de Student-t (STD) y la Distribución de errores generalizados (GED) para tener en cuenta las colas gruesas que son comunes en la mayoría de los datos financieros.

Distribución Normal (Norm)

Para que los modelos funcionen completamente, el término de error debe tener una media cero. Ahí es $_t N(0,1) $ donde el término de error en este caso se distribuye normalmente con media cero y varianza uno. La función de densidad para la distribución Normal viene dada por la Ecuación:

\[ f(z,\mu,\sigma)=\frac{1}{\sqrt{2\pi}^{e^{\frac{-z^2}{2}}}} \\ -\infty<z<\infty \]

Distribución de Student-t (STD)

Las colas más gruesas, frecuentemente observadas en series de tiempo financieras, están permitidas en la distribución t de Student, que está dada por la función de densidad que se muestra como la ecuación:

\[ f(z)= \frac{\Gamma[\frac{v+1}{2}]}{\sqrt{v\pi\Gamma[\frac{v}{2}]}}[1+\frac{z^2}{v}]^{[\frac{v+1}{2}]} \\ -\infty<z<\infty \]

donde v denota el número de grados de libertad y Γ denota la función Gamma.

Criterio de selección de modelo

Se utilizará el criterio de información para la selección del modelo en este ejercicio estudio. El Criterio de información de Akaike (AIC) se define como las ecuación siguiente:

\[ AIC= ln(\sigma^2)+\frac{2k}{s} \]

Resultados

Para esto se usara la función ya antes mostrada para extraer los datos del tipo de cambio desde el año 2000 al 2020.

Después de descargar los datos se crea un ciclo for el cuál nos ayudara a escoger el mejor modelo GARCH(p,q).

library(rugarch)
library(forecast)
library(PerformanceAnalytics)
retornos<- Return.calculate(ata,"log")[-1]
retornos1<- Return.calculate(ata,"log")[-1]
par(mfrow=c(1,2))
acf(retornos)
pacf(retornos)

par(mfrow=c(1,1))
modelo<- arima(ata,order = c(1,2,3))

GARCH.Mods = list()
GARCH.Fit  = list()
GARCH.BIC  = list()

for (q in 1:2) {
  for (p in 1:2) {
    GARCH.Mods[[paste("GARCH",q,p, sep = "")]] = ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(q,p)),
                                                            mean.model = list(armaOrder = c(1,3)))
    
    GARCH.Fit[[paste("GARCH",q,p, sep = "")]] = ugarchfit(spec = GARCH.Mods[[paste("GARCH",q,p, sep = "")]], data = retornos1)
    
    GARCH.BIC[[paste("GARCH",q,p, sep = "")]] = infocriteria(GARCH.Fit[[paste("GARCH",q,p, sep = "")]])
    GARCH.BIC[[paste("GARCH",q,p, sep = "")]] = GARCH.BIC[[paste("GARCH",q,p, sep = "")]][2,1]
  }
}

Resultado: El algoritmo nos arrojo según el criterio de AIC que el mejor modelo es un GARCH(1,1).

Ahora se van generar los modelos asímetricos los cuales son el modelo EGARCH y TGARCH, esto se realizára para comparar las curvas de impacto de noticias (NIC). Esto se hace para ver como es que afectan las noticias en el tipo de cambio.

EGARCH.Spec = ugarchspec(variance.model = list(model = "eGARCH", garchOrder = c(1,1)),
                         mean.model = list(armaOrder = c(1,3)))

EGARCH.Fit  = ugarchfit(EGARCH.Spec, data = retornos1)


TGARCH.Spec = ugarchspec(variance.model = list(model = "fGARCH", submodel = "TGARCH", garchOrder = c(1,1)),
                         mean.model = list(armaOrder = c(1,3)))

TGARCH.Fit  = ugarchfit(TGARCH.Spec, data = retornos1)
m<- matrix(c(1,2,1,3),2,2)
layout(m)
plot(GARCH.Fit$GARCH11,which=12)
plot(EGARCH.Fit,which=12)
plot(TGARCH.Fit,which=12)

layout(1)

Ahora se procede a capturar la volatilidad o las fluctuaciones las cuales no las dan los modelos creados. Se presentara los resultados que son obtenidos por el siguiente código:

GARCH.Vol = cbind(GARCH.Fit$GARCH11@fit$sigma, TGARCH.Fit@fit$sigma, EGARCH.Fit@fit$sigma)

GARCH.Vol = xts(GARCH.Vol, order.by = index(retornos1))
names(GARCH.Vol) = c("GARCH", "TGARCH", "EGARCH")            
layout(matrix(c(1,4,2,4,3,4),2,3))

chart.TimeSeries(GARCH.Vol$GARCH, main = "Volatilidad GARCH(2,1)", lwd = 1)
chart.TimeSeries(GARCH.Vol$TGARCH, main = "Volatilidad TGARCH(2,1)", lwd = 1)
chart.TimeSeries(GARCH.Vol$EGARCH, main = "Volatilidad EGARCH(2,1)", lwd = 1)
chart.TimeSeries(GARCH.Vol, main = "Volatilidades estimadas", legend.loc = "topleft", lwd = 1)

Ahora se procede a mostrar la proyecciones de la volatilidad o las fluctuacciones del tipo de cambio para 7 periodos o 7 meses:

GARCH.Forecast  = ugarchforecast(GARCH.Fit$GARCH11, data = SPY.Ret, n.ahead = 7)
TGARCH.Forecast = ugarchforecast(TGARCH.Fit, data = SPY.Ret, n.ahead = 7)
EGARCH.Forecast = ugarchforecast(EGARCH.Fit, data = SPY.Ret, n.ahead = 7)
VOL.Forecast = cbind(GARCH.Forecast@forecast$sigmaFor, TGARCH.Forecast@forecast$sigmaFor, EGARCH.Forecast@forecast$sigmaFor)
VOL.Forecast = ts(VOL.Forecast)
library(scales)
par(bg = "black")
par(mfrow = c(1,1))
plot(VOL.Forecast[,1], type="l", lwd=2, col = "blue", ylab=bquote(sigma[t]^2))
par(new = TRUE)
plot(VOL.Forecast[,2], type = "l", lwd = 2, col = "red", ylab=bquote(sigma[t]^2),axes=F)
par(new = TRUE)
plot(VOL.Forecast[,3], type = "l", lwd = 2, col = "green2", ylab=bquote(sigma[t]^2),axes=F)
par(bg=alpha("blue",0.4))
grid(col=alpha("purple",0.6))
box()
legend(x = 5, y = 0.008, legend = c("GARCH", "TGARCH", "EGARCH"), fill = c("blue", "red", "green2"), cex = 1,col="red")

LS0tDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAjIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGhpZ2hsaWdodDogemVuYnVybg0KICAgICMgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogImZsYXRseSINCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCi0tLQ0KDQpgYGB7ciBzZXR1cCxpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgY2FjaGUgPSBUUlVFKQ0KDQpgYGANCg0KPGNlbnRlcj4NCiFbXSh1bml2ZXJpZGFkLmpwZykNCjwvY2VudGVyPg0KPGNlbnRlcj4NCiAgICA8Yj5IaXN0b3JpYSBkZWwgcGVuc2FtaWVudG8gRWNvbsOzbWljbzwvYj48YnI+DQogICAgPGI+U2ViYXN0acOhbiBBbG9uc28gU29zYSBQw6lyZXo8L2I+DQo8YnI+DQo8aDE+PHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPipfX0ZsdWN0dWFjaW9uZXMgZGVsIHRpcG8gZGVsIGNhbWJpbyBfXyo8L3NwYW4+PC9oMT4NCjwvY2VudGVyPg0KPGNlbnRlcj4NCjxpPkNyZWFkbzogICAgIDA2LTAyLTIwMjEgDQo8L2NlbnRlcj4NCg0KDQoNCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fQ2FyZ2EgZGUgbGFzIHNpZ3VpZW50ZXMgbGlicmVyaWFzX18qPC9zcGFuPg0KDQoNCmBgYHtyLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoInRpZHl2ZXJzZSIpDQpsaWJyYXJ5KCJkYXRhLnRhYmxlIikgDQpsaWJyYXJ5KCJYTUwiKQ0KbGlicmFyeSgiaHR0ciIpDQpsaWJyYXJ5KCJ4dHMiKQ0KbGlicmFyeSgiRFQiKQ0KbGlicmFyeSgicnVnYXJjaCIpDQpsaWJyYXJ5KHF1YW50bW9kKQ0KbGlicmFyeSh0c2VyaWVzKQ0KbGlicmFyeShoaWdoY2hhcnRlcikNCg0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPipfX0NyZWFjacOzbiBkZSBsYSBmdW5jacOzbiBkZSBleHRyYWNjacOzbiBkZSBkYXRvcyBfXyo8L3NwYW4+DQoNCmBgYHtyfQ0KZXh0cmFjY2lvbjwtIGZ1bmN0aW9uKGNvZGlnbz1OVUxMLHN0YXJ0PU5VTEwsZW5kPU5VTEwpew0KICB2ZWN0b3I8LSB2ZWN0b3IoKQ0KICBkYXRvczwtIE5VTEwNCiAgZm9yKGkgaW4gMTpsZW5ndGgoY29kaWdvKSl7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXg8LSAgcGFzdGUwKCJodHRwczovL2VzdGFkaXN0aWNhcy5iY3JwLmdvYi5wZS9lc3RhZGlzdGljYXMvc2VyaWVzL2FwaS8iLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2RpZ29baV0sICIveG1sLyIsc3RhcnQsIi8iLGVuZCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqWE1MIDwtIGh0dHI6OkdFVChleCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMX3BhcnNlWE1MIDwtIHhtbFBhcnNlKE9ialhNTCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExfWE1MIDwtIHhtbFRvTGlzdChMX3BhcnNlWE1MKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR0X0JDUlAgPC0gZGF0YS50YWJsZTo6ZGF0YS50YWJsZSgpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChhIGluIDE6bGVuZ3RoKExfWE1MJHBlcmlvZHMpKXsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdF90ZW1wIDwtIGRhdGEudGFibGUoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcmllPSBMX1hNTCRwZXJpb2RzW1thXV0kdikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdF9CQ1JQIDwtIHJiaW5kKGR0X0JDUlAsZHRfdGVtcCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjdG9yW2ldPC0gZHRfQkNSUFssc2VyaWU6PWFzLm51bWVyaWMoc2VyaWUpXSANCiAgfQ0KICBmb3IoaSBpbiAgMTogbGVuZ3RoKGNvZGlnbykpew0KICAgIGRhdG9zPC0gY2JpbmQoZGF0b3MsdmVjdG9yW1tpXV0pDQogIH0NCiAgZGF0b3M8LSBhcy5kYXRhLmZyYW1lKGRhdG9zKQ0KICBuYW1lcyhkYXRvcyk8LSBjb2RpZ28NCiAgcmV0dXJuKGRhdG9zKQ0KICB9DQpgYGANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPipfX1Jlc3VsdGFkb3NfXyo8L3NwYW4+IA0KDQoNCiMjIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fRXh0cmFjY2nDs24gZGVsIHRpcG8gZGUgY2FtYmlvX18qPC9zcGFuPg0KDQoNCmBgYHtyLGVjaG89RkFMU0V9DQphdGE8LWV4dHJhY2Npb24oIlBOMDEyMTBQTSIsIjIwMDAtMSIsIjIwMjAtMTIiKQ0KbmFtZXMoYXRhKTwtICJUaXBvIGRlIGNhbWJpbyINCmZlY2hhPC0gYXMuRGF0ZSgiMjAwMC0wMS0wMSIsZm9ybWF0PSIlWS0lbS0lZCIpDQpmZWNoYTwtIHNlcShmZWNoYSxieT0iMSBtb250aCIsbGVuZ3RoPWxlbmd0aChhdGFbLDFdKSkNCmF0YTE8LSBjYmluZChmZWNoYSxyb3VuZChhdGEsZGlnaXRzID0zKSkNCmF0YTwtIHh0cyhhdGEsb3JkZXIuYnkgPSBmZWNoYSkNCmF0YTElPiUgZGF0YXRhYmxlKGV4dGVuc2lvbnMgPSAnQnV0dG9ucycsDQogICAgICAgICAgICBvcHRpb25zID0gbGlzdChkb20gPSAnQmxmcnRpcCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gYygnY29weScsICdjc3YnLCAnZXhjZWwnLCAncGRmJywgJ3ByaW50JyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGhNZW51ID0gbGlzdChjKDEwLDI1LDUwLC0xKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoMTAsMjUsNTAsIkFsbCIpKSkpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4qX19HcsOhZmljbyBkaW7DoW1pY29fXyo8L3NwYW4+ICANCg0KDQpgYGB7cixlY2hvPUZBTFNFfQ0KaGlnaGNoYXJ0KHR5cGUgPSAic3RvY2siKSAlPiUgDQogIGhjX2FkZF9zZXJpZXMoYXRhLGNvbG9yPSJibHVlIix0eXBlPSJsaW5lIikgJT4lIGhjX2FkZF90aGVtZShoY190aGVtZV9lY29ub21pc3QoKSkgJT4lIA0KICBoY190aXRsZSh0ZXh0ID0gIlRpcG8gZGUgY2FtYmlvIFVTRC9QRU4iLA0KICAgICAgICAgICAgIHN0eWxlID0gbGlzdChmb250V2VpZ2h0ID0gImJvbGQiLCBmb250U2l6ZSA9ICIyMHB4IiksDQogICAgICAgICAgICAgYWxpZ24gPSAiY2VudGVyIikgJT4lIA0KICAgaGNfY3JlZGl0cyhlbmFibGVkID0gVFJVRSx0ZXh0ID0gIkZ1ZW50ZSBCQ1JQICIpDQpgYGANCg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4qX19DYXB0dXJhIGRlIGxhcyBmbHVjdHVhY2Npb25lcyBkZWwgdGlwbyBkZSBjYW1iaW9fXyo8L3NwYW4+ICANCg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fRXNwZWNpZmljYWNpw7NuIGRlIGxvcyBtb2RlbG9zIEdhcmNoX18qPC9zcGFuPg0KDQoqIEZvcndhcmQgbG9va2luZyBiZWhhdmlvdXIsIHJlcXVpZXJlIHByb25vc3RpY2FyIGFkZWN1YWRhbWVudGUgbGEgdm9sYXRpbGlkYWQgeSBlbCByaWVzZ28gZGUgdW4gYWN0aXZvLg0KDQoqIExhIHZvbGF0aWxpZGFkIG5vIGVzIHVuYSBzZXJpZSBvYnNlcnZhYmxlIGVuIGVsIG1vbWVudG8gdCwgc2UgcmVxdWllcmVuIGRhdG9zIGhpc3TDs3JpY29zIHBhcmEgZXN0aW1hciBsYSB2b2xhdGlsaWRhZC4NCg0KKiBWb2xhdGlsaWRhZCBoaXN0w7NyaWNhIHNlIGVzdGltYSBjb24gbGEgdmFyaWFuemEgZGVsIHJlbmRpbWllbnRvIHNpbXBsZSAoY2FtYmlvIGVuIGVsIHByZWNpbyBkZWwgYWN0aXZvKS4NCg0KVW5hIG9wY2nDs246IEV4cG9uYW50aWFsbHkgV2VpZ3RlZCBNb3ZpbmcgQXZlcmFnZSBNb2RlbHMgKEVXTUEpIHF1ZSBlcyB1bmEgZXh0ZW5zacOzbiBkZWwgcHJvbWVkaW8gaGlzdMOzcmljbyBwZXJvIGhhY2llbmRvIHF1ZSBsYXMgb2JzZXJ2YWNpb25lcyBtw6FzIHJlY2llbnRlcyB0ZW5nYW4gdW4gbWF5b3IgcGVzbzoNCg0KJCQNClxhbHBoYV90XjI9KDEtXGxhbWJkYSlcc3VtX3tqPTB9XlxpbmZ0eVxsYW1iZGFfe2otMX1SXjJfe3QtMS1qfSBcXA0KUl4yX3t0LTEtan09IFZhcmlhbnphIFwgZGUgXCBsb3MgXCByZW5kaW1pZW50b3MgXFwNClxsYW1iZGE9ICJkZWNheSBcIGZhY3RvciINCiQkDQoNCkxhIGZvcm1hIG3DoXMgc2VuY2lsbGEgZXMgZGVmaW5pZGEgY29tbzoNCg0KJCQNClxzaWdtYV4yX3t0KzF9PVxsYW1iZGFcc2lnbWFfe3R9XjIrKDEtXGxhbWJkYSkgUl4yX3QNCiQkDQoNCkltcGxpY2EgcXVlIGxhIHZhcmlhbnphIGRlbCBwZXJpb2RvIHNpZ3VpZW50ZSBjb21vIHVuIHByb21lZGlvIHBvbmRlcmFkbyBkZSBsYSB2YXJpYW56YSBhY3R1YWwgeSBlbCByZW5kaW1pZW50byBhY3R1YWwgYWwgY3VhZHJhZG8uDQoNClNlIGFzdW1lIHVuIHBhdHLDs24gc2lzdGVtw6F0aWNvIGVuIGxhIGV2b2x1Y2nDs24gZGUgbGEgdmFyaWFuemEuDQoNClVuYSBnZW5lcmFsaXphY2nDs24gZGVsIG1vZGVsbyBBUkNIKG0pIGZ1ZSBkZXNhcnJvbGxhZGEgcG9yIEJvbGxlcnNsZXYgKDE5ODYpIGFsIHByb3BvbmVyIHF1ZSBsYSB2YXJpYW56YSBjb25kaWNpb25hbCBkZXBlbmRhIGRlIHN1cyBwcm9waW9zIHJlemFnb3M6DQoNCiQkDQpoX3Q9XGFscGhhXzArXHN1bV97aT0xfV5tXGFscGhhX2lcZXBzaWxvbl4yX3t0LWl9K1xzdW1fe2o9MX1ecFxiZXRhX2poX3t0LWl9IFxcDQpcZXBzaWxvbiAgXHJpZ2h0YXJyb3cgTigwLGhfdCkgIFxcDQpcZXBzaWxvbl90XHNxcnR7aF90dl90fSBcXA0Kdl90IFxzaW0gaWlkTigwLDEpDQokJA0KDQpMYSBlc3BlY2lmaWNhY2nDs24gR0FSQ0ggc2UgZGVmaW5lIGNvbW8gdW4gbW9kZWxvIEFSQ0ggZGUgb3JkZW4gaW5maW5pdG8gKEJvbGxlcnNsZXYsIDE5ODYpLg0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fTW9kZWxvIEVHQVJDSChwLHEpX18qPC9zcGFuPg0KDQpFbiAxOTkwLCBQYWdhbiB5IFNjaHdlcnQgKDE5OTApLCB5IGFsIGHDsW8gc2lndWllbnRlIGVuIDE5OTEgTmVsc29uICgxOTkxKSwgZGVzYXJyb2xsYXJvbiB1bmEgdmVyc2nDs24gbnVldmEgZGVsIG1vZGVsbyBHQVJDSCwgZWwgRUdBUkNIIChtb2RlbG8gZXhwb25lbmNpYWwgZ2VuZXJhbGl6YWRvLCBhdXRvLXJlZ3Jlc2l2bywgY29uZGljaW9uYWxtZW50ZSBoZXRlcm9jZWTDoXN0aWNvKS5FbCBudWV2byBtb2RlbG8gYWNhYmEgY29uIGxhcyBhc2ltZXRyw61hcyBlbiBsYSBlc3RpbWFjacOzbiBkZWwgZWZlY3RvIGRlIGxvcyBzaG9ja3MsIGFsIGltcGxlbWVudGFyIHVuYSBmdW5jacOzbiDwnZGUKPCdnIDwnZGhICkgZGUgbGFzIGlubm92YWNpb25lcyDwnZyA8J2RoSxxdWUgc29uIHZhcmlhYmxlcyBpZ3VhbCBlIGluZGVwZW5kaWVudGVtZW50ZSBkaXN0cmlidWlkYXMgZGUgbWVkaWEgY2VybywgeSBlbiBsYXMgcXVlIHBvciB0YW50byBlbCB2YWxvciBkZSBsYXMgaW5ub3ZhY2lvbmVzIHF1ZWRhIHJlY29naWRvIHBvciBtZWRpbyBkZSBsYSBleHByZXNpw7NuOg0KDQokJA0KbG5cc2lnbWFeMl90PXcrXGJldGEoXHNpZ21hXjJfe3QtMX0pK1xnYW1tYVxmcmFje3Vfe3QtMX19e1xzcXJ0e1xzaWdtYV97dC0xfX19K1xhbHBoYVtcZnJhY3t8dV97dC0xfXx9e1xzcXJ0e1xzaWdtYV97dC0xfX19LVxzcXJ0e1xmcmFjezJ9e1xzcXJ0e1xwaX19fV0NCiQkDQoNCkVsIG1vZGVsbyB0aWVuZSB2YXJpYXMgdmVudGFqYXMgc29icmUgbGEgZXNwZWNpZmljYWNpw7NuIEdBUkNIIHB1cmEuIEVuIHByaW1lciBsdWdhciwgZWwgJGxuKFxzaWdtYV90XjIpJDtlcyBtb2RlbGFkbywgZXN0byBxdWllcmUgZGVjaXIsIHF1ZSBhdW5xdWUgbG9zIHBhcsOhbWV0cm9zIHNlYW4gbmVnYXRpdm9zLCAkXHNpZ21hX3ReMiRzZXLDoSBwb3NpdGl2by4gUG9yIGxvIHRhbnRvLCBlc3RlIG1vZGVsbyBubyB0aWVuZSByZXN0cmljY2lvbmVzIGRlIG5vIG5lZ2F0aXZpZGFkIGVuIGxvcyBwYXLDoW1ldHJvcy4gRW4gc2VndW5kbyBsdWdhciwgbGFzIGFzaW1ldHLDrWFzIHNlIHBlcm1pdGVuIGJham8gbGEgZm9ybXVsYWNpw7NuIGRlIEVHQVJDSCwgeWEgcXVlLCBzaSBsYSByZWxhY2nDs24gZW50cmUgbGEgdm9sYXRpbGlkYWQgeSBsb3MgcmVuZGltaWVudG9zIGVzIG5lZ2F0aXZhICRcZ2FtbWEkIHNlcsOhIG5lZ2F0aXZhLiANCg0KIyMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPipfX01vZGVsbyBUR0FSQ0gocCxxKV9fKjwvc3Bhbj4NCg0KTGEgaWRlYSBkZWwgbW9kZWxvIFRHQVJDSCAoVHJlc2hvbGQgR0FSQ0gpIGVzIGRpdmlkaXIgbGEgZGlzdHJpYnVjacOzbiBkZSBsb3Mgc2hvY2tzIGVuIGludGVydmFsb3MgZGlzanVudG9zLCBwYXJhIGx1ZWdvIGFwcm94aW1hciB1bmEgZnVuY2nDs24gbGluZWFsIHBvciB0cmFtb3MgYmllbiBwYXJhIGxhIGRlc3ZpYWNpw7NuIGVzdMOhbmRhciBjb25kaWNpb25hbCAoWmFrb2lhbiwgMTk5NCksIGJpZW4gbGEgdmFyaWFuemEgY29uZGljaW9uYWwgKEdsb3N0ZW4sIEphZ2FuYXRoYW4sICYgUnVua2xlICwgMTk5MykuIFNpIHPDs2xvIGhheSBkb3MgaW50ZXJ2YWxvcywgbGEgZGl2aXNpw7NuIGVzIG5vcm1hbG1lbnRlIGVuIHVuIHVtYnJhbCBpZGVudGlmaWNhZG8gY29uIGVsIG7Dum1lcm8gY2VybywgZG9uZGUgbGEgaW5mbHVlbmNpYSBkZSBsb3Mgc2hvY2tzIHBvc2l0aXZvcyBzZSBpZGVudGlmaWNhIGNvbiB2YWxvcmVzIHBvciBlbmNpbWEgZGUgY2VybyB5IG5lZ2F0aXZvcyBwb3IgZGViYWpvIGRlIGVzdGUgdmFsb3IuDQoNCkVzcGVjaWZpY2FjacOzbiBkZWwgVEdBUkNIOg0KDQokJA0KXHNpZ21hXjJfdD13K1xzdW1fe2k9MX1ecyhcYWxwaGFfaStcZ2FtbWFfaU5fe3QtaX0pXHNpZ21hXjJfe3QtaX1cc3VtX3tqPWl9Xm1cYmV0YV9qXHNpZ21hXjJfe3Qtan0NCiQkDQoNCiQkDQpOX3t0LWl9ID1cYmVnaW57Y2FzZXN9IDEgIFxyaWdodGFycm93IFxhbHBoYV97dC1pfSA8MFxcMCAgXHJpZ2h0YXJyb3cgXGFscGhhX3t0LWl9IFxnZXFzbGFudCAwXGVuZHtjYXNlc30gDQokJA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fU3Vwb3NpY2lvbmVzIGRlIGRpc3RyaWJ1Y2nDs24gZGVsIHTDqXJtaW5vIGRlIGVycm9yX18qPC9zcGFuPg0KDQpFbiBsYSBlc3BlY2lmaWNhY2nDs24gZGVsIG1vZGVsbyBHQVJDSCwgZXMgbcOhcyBhcHJvcGlhZG8gY29uc2lkZXJhciBsYSBlbGVjY2nDs24gZW4gZWwgc3VwdWVzdG8gZGUgZGlzdHJpYnVjacOzbiBkZWwgdMOpcm1pbm8gZGUgZXJyb3IuIEVzdGUgZWplcmNpY2lvIGFzdW1pw7MgdHJlcyBzdXB1ZXN0b3MgZGUgZGlzdHJpYnVjacOzbjsgTGEgZGlzdHJpYnVjacOzbiBub3JtYWwgKE5PUk0pLCBsYSBkaXN0cmlidWNpw7NuIGRlIFN0dWRlbnQtdCAoU1REKSB5IGxhIERpc3RyaWJ1Y2nDs24gZGUgZXJyb3JlcyBnZW5lcmFsaXphZG9zIChHRUQpIHBhcmEgdGVuZXIgZW4gY3VlbnRhIGxhcyBjb2xhcyBncnVlc2FzIHF1ZSBzb24gY29tdW5lcyBlbiBsYSBtYXlvcsOtYSBkZSBsb3MgZGF0b3MgZmluYW5jaWVyb3MuDQoNCiMjIDxzcGFuIHN0eWxlPSJjb2xvcjpibHVlIj4qX19EaXN0cmlidWNpw7NuIE5vcm1hbCAoTm9ybSlfXyo8L3NwYW4+DQoNClBhcmEgcXVlIGxvcyBtb2RlbG9zIGZ1bmNpb25lbiBjb21wbGV0YW1lbnRlLCBlbCB0w6lybWlubyBkZSBlcnJvciBkZWJlIHRlbmVyIHVuYSBtZWRpYSBjZXJvLiBBaMOtIGVzICRcZXBzaWxvbl90ICBcc2ltIE4oMCwxKSAkIGRvbmRlIGVsIHTDqXJtaW5vIGRlIGVycm9yIGVuIGVzdGUgY2FzbyBzZSBkaXN0cmlidXllIG5vcm1hbG1lbnRlIGNvbiBtZWRpYSBjZXJvIHkgdmFyaWFuemEgdW5vLiBMYSBmdW5jacOzbiBkZSBkZW5zaWRhZCBwYXJhIGxhIGRpc3RyaWJ1Y2nDs24gTm9ybWFsIHZpZW5lIGRhZGEgcG9yIGxhIEVjdWFjacOzbjogDQoNCiQkDQpmKHosXG11LFxzaWdtYSk9XGZyYWN7MX17XHNxcnR7MlxwaX1ee2Vee1xmcmFjey16XjJ9ezJ9fX19IFxcDQotXGluZnR5PHo8XGluZnR5DQokJA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fRGlzdHJpYnVjacOzbiBkZSBTdHVkZW50LXQgKFNURClfXyo8L3NwYW4+DQoNCkxhcyBjb2xhcyBtw6FzIGdydWVzYXMsIGZyZWN1ZW50ZW1lbnRlIG9ic2VydmFkYXMgZW4gc2VyaWVzIGRlIHRpZW1wbyBmaW5hbmNpZXJhcywgZXN0w6FuIHBlcm1pdGlkYXMgZW4gbGEgZGlzdHJpYnVjacOzbiB0IGRlIFN0dWRlbnQsIHF1ZSBlc3TDoSBkYWRhIHBvciBsYSBmdW5jacOzbiBkZSBkZW5zaWRhZCBxdWUgc2UgbXVlc3RyYSBjb21vIGxhIGVjdWFjacOzbjogDQoNCiQkDQpmKHopPSBcZnJhY3tcR2FtbWFbXGZyYWN7disxfXsyfV19e1xzcXJ0e3ZccGlcR2FtbWFbXGZyYWN7dn17Mn1dfX1bMStcZnJhY3t6XjJ9e3Z9XV57W1xmcmFje3YrMX17Mn1dfSBcXA0KLVxpbmZ0eTx6PFxpbmZ0eQ0KJCQNCg0KZG9uZGUgdiBkZW5vdGEgZWwgbsO6bWVybyBkZSBncmFkb3MgZGUgbGliZXJ0YWQgeSDOkyBkZW5vdGEgbGEgZnVuY2nDs24gR2FtbWEuIA0KDQojIyA8c3BhbiBzdHlsZT0iY29sb3I6Ymx1ZSI+Kl9fQ3JpdGVyaW8gZGUgc2VsZWNjacOzbiBkZSBtb2RlbG9fXyo8L3NwYW4+DQoNClNlIHV0aWxpemFyw6EgZWwgY3JpdGVyaW8gZGUgaW5mb3JtYWNpw7NuIHBhcmEgbGEgc2VsZWNjacOzbiBkZWwgbW9kZWxvIGVuIGVzdGUgZWplcmNpY2lvIGVzdHVkaW8uIEVsIENyaXRlcmlvIGRlIGluZm9ybWFjacOzbiBkZSBBa2Fpa2UgKEFJQykgc2UgZGVmaW5lIGNvbW8gbGFzIGVjdWFjacOzbiBzaWd1aWVudGU6DQoNCiQkDQpBSUM9IGxuKFxzaWdtYV4yKStcZnJhY3sya317c30NCiQkDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOmJsdWUiPipfX1Jlc3VsdGFkb3NfXyo8L3NwYW4+DQoNClBhcmEgZXN0byBzZSB1c2FyYSBsYSBmdW5jacOzbiB5YSBhbnRlcyBtb3N0cmFkYSBwYXJhIGV4dHJhZXIgbG9zIGRhdG9zIGRlbCB0aXBvIGRlIGNhbWJpbyBkZXNkZSBlbCAqKmHDsW8gMjAwMCBhbCAyMDIwKiouIA0KDQpEZXNwdcOpcyBkZSBkZXNjYXJnYXIgbG9zIGRhdG9zIHNlIGNyZWEgdW4gY2ljbG8gZm9yIGVsIGN1w6FsIG5vcyBheXVkYXJhIGEgZXNjb2dlciBlbCBtZWpvciBtb2RlbG8gKipHQVJDSChwLHEpKiouDQoNCmBgYHtyLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRX0NCmxpYnJhcnkocnVnYXJjaCkNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KFBlcmZvcm1hbmNlQW5hbHl0aWNzKQ0KcmV0b3Jub3M8LSBSZXR1cm4uY2FsY3VsYXRlKGF0YSwibG9nIilbLTFdDQpyZXRvcm5vczE8LSBSZXR1cm4uY2FsY3VsYXRlKGF0YSwibG9nIilbLTFdDQpwYXIobWZyb3c9YygxLDIpKQ0KYWNmKHJldG9ybm9zKQ0KcGFjZihyZXRvcm5vcykNCnBhcihtZnJvdz1jKDEsMSkpDQptb2RlbG88LSBhcmltYShhdGEsb3JkZXIgPSBjKDEsMiwzKSkNCg0KR0FSQ0guTW9kcyA9IGxpc3QoKQ0KR0FSQ0guRml0ICA9IGxpc3QoKQ0KR0FSQ0guQklDICA9IGxpc3QoKQ0KDQpmb3IgKHEgaW4gMToyKSB7DQogIGZvciAocCBpbiAxOjIpIHsNCiAgICBHQVJDSC5Nb2RzW1twYXN0ZSgiR0FSQ0giLHEscCwgc2VwID0gIiIpXV0gPSB1Z2FyY2hzcGVjKHZhcmlhbmNlLm1vZGVsID0gbGlzdChtb2RlbCA9ICJzR0FSQ0giLCBnYXJjaE9yZGVyID0gYyhxLHApKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4ubW9kZWwgPSBsaXN0KGFybWFPcmRlciA9IGMoMSwzKSkpDQogICAgDQogICAgR0FSQ0guRml0W1twYXN0ZSgiR0FSQ0giLHEscCwgc2VwID0gIiIpXV0gPSB1Z2FyY2hmaXQoc3BlYyA9IEdBUkNILk1vZHNbW3Bhc3RlKCJHQVJDSCIscSxwLCBzZXAgPSAiIildXSwgZGF0YSA9IHJldG9ybm9zMSkNCiAgICANCiAgICBHQVJDSC5CSUNbW3Bhc3RlKCJHQVJDSCIscSxwLCBzZXAgPSAiIildXSA9IGluZm9jcml0ZXJpYShHQVJDSC5GaXRbW3Bhc3RlKCJHQVJDSCIscSxwLCBzZXAgPSAiIildXSkNCiAgICBHQVJDSC5CSUNbW3Bhc3RlKCJHQVJDSCIscSxwLCBzZXAgPSAiIildXSA9IEdBUkNILkJJQ1tbcGFzdGUoIkdBUkNIIixxLHAsIHNlcCA9ICIiKV1dWzIsMV0NCiAgfQ0KfQ0KYGBgDQoNCj4gUmVzdWx0YWRvOiBFbCBhbGdvcml0bW8gbm9zIGFycm9qbyBzZWfDum4gZWwgY3JpdGVyaW8gZGUgQUlDIHF1ZSBlbCBtZWpvciBtb2RlbG8gZXMgdW4gR0FSQ0goMSwxKS4NCg0KQWhvcmEgc2UgdmFuIGdlbmVyYXIgbG9zIG1vZGVsb3MgYXPDrW1ldHJpY29zIGxvcyBjdWFsZXMgc29uIGVsIG1vZGVsbyAqKkVHQVJDSCB5IFRHQVJDSCoqLCBlc3RvIHNlIHJlYWxpesOhcmEgcGFyYSBjb21wYXJhciBsYXMgY3VydmFzIGRlIGltcGFjdG8gZGUgbm90aWNpYXMgKE5JQykuIEVzdG8gc2UgaGFjZSBwYXJhIHZlciBjb21vIGVzIHF1ZSBhZmVjdGFuIGxhcyBub3RpY2lhcyBlbiBlbCB0aXBvIGRlIGNhbWJpby4NCg0KYGBge3J9DQpFR0FSQ0guU3BlYyA9IHVnYXJjaHNwZWModmFyaWFuY2UubW9kZWwgPSBsaXN0KG1vZGVsID0gImVHQVJDSCIsIGdhcmNoT3JkZXIgPSBjKDEsMSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4ubW9kZWwgPSBsaXN0KGFybWFPcmRlciA9IGMoMSwzKSkpDQoNCkVHQVJDSC5GaXQgID0gdWdhcmNoZml0KEVHQVJDSC5TcGVjLCBkYXRhID0gcmV0b3Jub3MxKQ0KDQoNClRHQVJDSC5TcGVjID0gdWdhcmNoc3BlYyh2YXJpYW5jZS5tb2RlbCA9IGxpc3QobW9kZWwgPSAiZkdBUkNIIiwgc3VibW9kZWwgPSAiVEdBUkNIIiwgZ2FyY2hPcmRlciA9IGMoMSwxKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgbWVhbi5tb2RlbCA9IGxpc3QoYXJtYU9yZGVyID0gYygxLDMpKSkNCg0KVEdBUkNILkZpdCAgPSB1Z2FyY2hmaXQoVEdBUkNILlNwZWMsIGRhdGEgPSByZXRvcm5vczEpDQptPC0gbWF0cml4KGMoMSwyLDEsMyksMiwyKQ0KbGF5b3V0KG0pDQpwbG90KEdBUkNILkZpdCRHQVJDSDExLHdoaWNoPTEyKQ0KcGxvdChFR0FSQ0guRml0LHdoaWNoPTEyKQ0KcGxvdChUR0FSQ0guRml0LHdoaWNoPTEyKQ0KbGF5b3V0KDEpDQpgYGANCg0KQWhvcmEgc2UgcHJvY2VkZSBhIGNhcHR1cmFyIGxhIHZvbGF0aWxpZGFkIG8gbGFzIGZsdWN0dWFjaW9uZXMgbGFzIGN1YWxlcyBubyBsYXMgZGFuIGxvcyBtb2RlbG9zIGNyZWFkb3MuIFNlIHByZXNlbnRhcmEgbG9zIHJlc3VsdGFkb3MgcXVlIHNvbiBvYnRlbmlkb3MgcG9yIGVsIHNpZ3VpZW50ZSBjw7NkaWdvOg0KDQpgYGB7cn0NCkdBUkNILlZvbCA9IGNiaW5kKEdBUkNILkZpdCRHQVJDSDExQGZpdCRzaWdtYSwgVEdBUkNILkZpdEBmaXQkc2lnbWEsIEVHQVJDSC5GaXRAZml0JHNpZ21hKQ0KDQpHQVJDSC5Wb2wgPSB4dHMoR0FSQ0guVm9sLCBvcmRlci5ieSA9IGluZGV4KHJldG9ybm9zMSkpDQpuYW1lcyhHQVJDSC5Wb2wpID0gYygiR0FSQ0giLCAiVEdBUkNIIiwgIkVHQVJDSCIpICAgICAgICAgICAgDQpsYXlvdXQobWF0cml4KGMoMSw0LDIsNCwzLDQpLDIsMykpDQoNCmNoYXJ0LlRpbWVTZXJpZXMoR0FSQ0guVm9sJEdBUkNILCBtYWluID0gIlZvbGF0aWxpZGFkIEdBUkNIKDIsMSkiLCBsd2QgPSAxKQ0KY2hhcnQuVGltZVNlcmllcyhHQVJDSC5Wb2wkVEdBUkNILCBtYWluID0gIlZvbGF0aWxpZGFkIFRHQVJDSCgyLDEpIiwgbHdkID0gMSkNCmNoYXJ0LlRpbWVTZXJpZXMoR0FSQ0guVm9sJEVHQVJDSCwgbWFpbiA9ICJWb2xhdGlsaWRhZCBFR0FSQ0goMiwxKSIsIGx3ZCA9IDEpDQpjaGFydC5UaW1lU2VyaWVzKEdBUkNILlZvbCwgbWFpbiA9ICJWb2xhdGlsaWRhZGVzIGVzdGltYWRhcyIsIGxlZ2VuZC5sb2MgPSAidG9wbGVmdCIsIGx3ZCA9IDEpDQoNCmBgYA0KDQpBaG9yYSBzZSBwcm9jZWRlIGEgbW9zdHJhciBsYSBwcm95ZWNjaW9uZXMgZGUgbGEgdm9sYXRpbGlkYWQgbyBsYXMgZmx1Y3R1YWNjaW9uZXMgZGVsIHRpcG8gZGUgY2FtYmlvIHBhcmEgNyBwZXJpb2RvcyBvIDcgbWVzZXM6IA0KDQpgYGB7cixtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0V9DQpHQVJDSC5Gb3JlY2FzdCAgPSB1Z2FyY2hmb3JlY2FzdChHQVJDSC5GaXQkR0FSQ0gxMSwgZGF0YSA9IFNQWS5SZXQsIG4uYWhlYWQgPSA3KQ0KVEdBUkNILkZvcmVjYXN0ID0gdWdhcmNoZm9yZWNhc3QoVEdBUkNILkZpdCwgZGF0YSA9IFNQWS5SZXQsIG4uYWhlYWQgPSA3KQ0KRUdBUkNILkZvcmVjYXN0ID0gdWdhcmNoZm9yZWNhc3QoRUdBUkNILkZpdCwgZGF0YSA9IFNQWS5SZXQsIG4uYWhlYWQgPSA3KQ0KVk9MLkZvcmVjYXN0ID0gY2JpbmQoR0FSQ0guRm9yZWNhc3RAZm9yZWNhc3Qkc2lnbWFGb3IsIFRHQVJDSC5Gb3JlY2FzdEBmb3JlY2FzdCRzaWdtYUZvciwgRUdBUkNILkZvcmVjYXN0QGZvcmVjYXN0JHNpZ21hRm9yKQ0KVk9MLkZvcmVjYXN0ID0gdHMoVk9MLkZvcmVjYXN0KQ0KbGlicmFyeShzY2FsZXMpDQpwYXIoYmcgPSAiYmxhY2siKQ0KcGFyKG1mcm93ID0gYygxLDEpKQ0KcGxvdChWT0wuRm9yZWNhc3RbLDFdLCB0eXBlPSJsIiwgbHdkPTIsIGNvbCA9ICJibHVlIiwgeWxhYj1icXVvdGUoc2lnbWFbdF1eMikpDQpwYXIobmV3ID0gVFJVRSkNCnBsb3QoVk9MLkZvcmVjYXN0WywyXSwgdHlwZSA9ICJsIiwgbHdkID0gMiwgY29sID0gInJlZCIsIHlsYWI9YnF1b3RlKHNpZ21hW3RdXjIpLGF4ZXM9RikNCnBhcihuZXcgPSBUUlVFKQ0KcGxvdChWT0wuRm9yZWNhc3RbLDNdLCB0eXBlID0gImwiLCBsd2QgPSAyLCBjb2wgPSAiZ3JlZW4yIiwgeWxhYj1icXVvdGUoc2lnbWFbdF1eMiksYXhlcz1GKQ0KcGFyKGJnPWFscGhhKCJibHVlIiwwLjQpKQ0KZ3JpZChjb2w9YWxwaGEoInB1cnBsZSIsMC42KSkNCmJveCgpDQpsZWdlbmQoeCA9IDUsIHkgPSAwLjAwOCwgbGVnZW5kID0gYygiR0FSQ0giLCAiVEdBUkNIIiwgIkVHQVJDSCIpLCBmaWxsID0gYygiYmx1ZSIsICJyZWQiLCAiZ3JlZW4yIiksIGNleCA9IDEsY29sPSJyZWQiKQ0KYGBgDQoNCg==