Econometría 2

Grupo 102

EVIDENCIA PRONÓSTICOS DE LA ECONOMÍA

INTRODUCCIÓN

De acuerdo con la Organización Internacional del Trabajo (OIT), la subocupación es definida como la situación en la cual los trabajadores reducen sus horas de trabajo y laboran en empleos menos satisfactorios con el objetivo de evitar el desempleo (Morales, s.f.). De acuerdo con un estudio realizado por Clara Judisman, quién fungió como Directora General del Registro Nacional de Electores en México, en las naciones de menor desarrollo resulta más efectivo el análisis de la subocupación en lugar de el análisis del desempleo, esto sucede debido a que de acuerdo con B. Datta el problema principal en estos países “no es el volumen, número o proporción de personas empleadas, sino el grado del empleo” (Judisman,s.f, p.269). En México, gran porcentaje de la población carece de recursos financieros para poder laborar en un trabajo adecuado, o con un periodo largo, por lo tanto, los individuos prefieren tomar cualquier empleo antes de permanecer desempleados (Judisman,s.f,p. 275). Por otro lado, Bantegui plantea que “la inadecuada utilización de la fuerza de trabajo no se expresa por el desempleo, sino, en la carencia de empleos satisfactorios” (Judisman,s.f,p. 275). Debido a esto, en el presente trabajo se realizará un pronóstico de la variable de subocupación con el programa R Studio. En este caso se utilizará una base de datos obtenida del INEGI, la cual cuenta con 70 observaciones. Por otro lado, la serie es de la variación trimestral de la tasa de subocupación en México, y se tomaron datos desde el primer trimestre del año 2005, al segundo trimestre del año 2022.

DESARROLLO

  1. Modelar la serie de Tiempo
  • Representación Gráfica
  • Prueba Dickey Fuller
  • Identificar el Modelo
  • Validación de Modelo
  • Refinación del Modelo
  1. Pronóstico de la Tasa de Subocupación
  • Estimación Auto Arima
  • Generación de Grupos de Entrenamiento y Prueba
  • Comparación de Modelos - Prueba Diabold Mariano
  • Pronóstico

1. Modelar la Serie de Tiempo

Lectura de base de datos

datos <- read_excel("~/Desktop/MÉTODOS_ R/subocupacion.xlsx")
date = as.Date(datos$Fecha, format = "%Y/%m/%d")
subocupacion = datos$sub

Representación Gráfica

En primera instancia se realiza una representación gráfica para observar si la serie es estacionaria.

plot(datos$sub, type = "l", xlab = "", ylab = "%", main = "")

Sin embargo, el análisis gráfico no es suficiente para observar esta propiedad. Por lo tanto, se procede a realizar una prueba que contribuya a demostrar estacionariedad.

Prueba Dicky Fuller (nivel de significancia 5%)

El objetivo de esta prueba es observar si la serie a utilizar es estacionaria o no, esto quiere decir que los momentos estadísticos no dependan del tiempo. Esta prueba aumentada de Dickey-Fuller se estima con una regresión auxiliar. La ecuación asociada es:

\[\begin{align*} \Delta y_t = \beta_0 + \delta t + \phi y_{t-1} + \sum_{i=1}^{p}\beta \Delta y_{t-i}+e_t \end{align*}\]

La hipotesis asociada a la prueba es la siguiente: \[\begin{align*} H_0: \phi = 0 \\ H_a: \phi \neq 0 \end{align*}\]

Si se rechaza H0 la serie no tiene raíz unitaria, por lo tanto, la serie es estacionaria.

Se usará un nivel de significancia del 5%

Realizando por primera vez la prueba se observa lo siguiente:

sub.ts <- ts(datos ,start = c(2005,01), end = c(2022,02), frequency = 4)#Convirtiendo a series de tiempo
adf.sub.trend <- ur.df(sub.ts[,"sub"], type = "trend", selectlags = "BIC")
summary(adf.sub.trend)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression trend 


Call:
lm(formula = z.diff ~ z.lag.1 + 1 + tt + z.diff.lag)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.6583 -0.7816 -0.2154  0.1732 15.8679 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept)  2.48845    0.91843   2.709  0.00864 **
z.lag.1     -0.37481    0.11449  -3.274  0.00171 **
tt           0.02132    0.01487   1.433  0.15670   
z.diff.lag  -0.11018    0.12419  -0.887  0.37829   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.143 on 64 degrees of freedom
Multiple R-squared:  0.219, Adjusted R-squared:  0.1824 
F-statistic: 5.981 on 3 and 64 DF,  p-value: 0.001168


Value of test-statistic is: -3.2736 3.5754 5.3605 

Critical values for test statistics: 
      1pct  5pct 10pct
tau3 -4.04 -3.45 -3.15
phi2  6.50  4.88  4.16
phi3  8.73  6.49  5.47

Debido a que el valor de test-statistic no es más negativo que el valor de tau3 en un nivel de significancia al 5%, NO se rechaza H0. Por otro lado, ya que el valor test-statistic 3.57 no es mayor al valor de phi2, en un nivel de significancia de 5%, NO se rechaza H0.

Debido a que la serie sigo contando con raíz unitaria, se realiza otra prueba removiendo la tendencia con la función “drift”.

adf.sub.drift <- ur.df(sub.ts[,"sub"], type = "drift", selectlags = "BIC")
summary(adf.sub.drift)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression drift 


Call:
lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.3886 -0.5929 -0.2755 -0.0318 16.4390 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)   
(Intercept)   2.6016     0.9224   2.820  0.00635 **
z.lag.1      -0.3001     0.1027  -2.920  0.00480 **
z.diff.lag   -0.1464     0.1226  -1.195  0.23657   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.16 on 65 degrees of freedom
Multiple R-squared:  0.1939,    Adjusted R-squared:  0.1691 
F-statistic: 7.818 on 2 and 65 DF,  p-value: 0.000907


Value of test-statistic is: -2.9204 4.267 

Critical values for test statistics: 
      1pct  5pct 10pct
tau2 -3.51 -2.89 -2.58
phi1  6.70  4.71  3.86

Ya que el valor de test-statistic (-2.89) es más negativo que el valor de tau (-2.89) en un nivel de significancia al 5%, se rechaza H0.

Se concluye que la serie es estacionaria y NO tiene raíz unitaria. El modelo es estacionario y tiene un orden de integración de cero.

Identificar el Modelo

Correlograma

Con el objetivo de identificar el modelo adecuadamente se utilizará un correlograma, el cual permitirá observar si se cuenta con un modelo AR, MA o ARMA.

par(mfrow = c(1,2))
acf(subocupacion, lag = 20)
pacf(subocupacion, lag = 20)

Tomando en cuenta que el decaimiento geométrico se encuentra en ACF y ACP, se concluye que es un modelo ARMA (1,1). Por lo tanto, se estimará la función arima como un modelo de orden (1,0,1).

Validación Modelo ARMA (1,1)

Estimación Modelo ARMA(1,1)
modelo.arma <- arima(datos$sub, order = c(1, 0, 1)) 
modelo.arma

Call:
arima(x = datos$sub, order = c(1, 0, 1))

Coefficients:
         ar1      ma1  intercept
      0.7543  -0.1997     8.6170
s.e.  0.1099   0.1619     0.7814

sigma^2 estimated as 4.354:  log likelihood = -151.1,  aic = 310.19
summary(modelo.arma)

Call:
arima(x = datos$sub, order = c(1, 0, 1))

Coefficients:
         ar1      ma1  intercept
      0.7543  -0.1997     8.6170
s.e.  0.1099   0.1619     0.7814

sigma^2 estimated as 4.354:  log likelihood = -151.1,  aic = 310.19

Training set error measures:
                      ME     RMSE       MAE       MPE     MAPE      MASE
Training set 0.003161995 2.086719 0.7425833 -2.635958 7.224152 0.8729572
                     ACF1
Training set 0.0003464964
Prueba Individual
par(mfrow = c(1,2))
acf(modelo.arma$residuals, lag = 20)
pacf(modelo.arma$residuals, lag = 20)

Debido a que la estructura en el AC y ACP se encuentran dentro de las bandas de confianza, se concluye que es un modelo adecuado.

Prueba Conjunta

Por otro lado, en la Prueba Conjunta de Lyung, se busca observar si hay estructura de autocorrelación.

Box.test(modelo.arma$residuals, type = "Ljung", lag = 20)

    Box-Ljung test

data:  modelo.arma$residuals
X-squared = 2.1167, df = 20, p-value = 1

La hipotesis asociada a la prueba es la siguiente:

\[\begin{align*} H_0: \rho_1 = \rho_2 =0 \\ H_a: \textrm{Al menos un parámetro es distinto de 0} \end{align*}\]

Si p-valor > 0.05 NO se rechaza H0

Debido a que el p-valor (1) es mayor a 0.05, NO se rechaza H0, por lo tanto, NO hay estructura de autocorrelación en el modelo, lo cual lo hace un modelo válido.

Refinación del Modelo ARMA(1,1)

Mediante este proceso se busca observar si hay parámetros que no son significativos, lo cual significaría que no aportan al modelo en cuestión. Esto se realizará con la prueba “Coeftest”.

coeftest(modelo.arma, df = 67)

t test of coefficients:

          Estimate Std. Error t value  Pr(>|t|)    
ar1        0.75427    0.10985  6.8662 2.627e-09 ***
ma1       -0.19970    0.16191 -1.2334    0.2217    
intercept  8.61699    0.78141 11.0274 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#df = observaciones - parámetros
#df = 70 - 3

En esta prueba se observa que el MA es un parámetro NO significativo, por lo tanto, es necesario refinar el modelo. Esto se realizará asignando un cero a dicho parámetro NO significativo.

modelo.arma.ref <- arima(subocupacion, transform.pars = TRUE, order = c(1, 0, 1), fixed = c(NA,0,NA))
modelo.arma.ref

Call:
arima(x = subocupacion, order = c(1, 0, 1), transform.pars = TRUE, fixed = c(NA, 
    0, NA))

Coefficients:
         ar1  ma1  intercept
      0.6395    0     8.6172
s.e.  0.0895    0     0.6818

sigma^2 estimated as 4.442:  log likelihood = -151.78,  aic = 309.56
Correlograma de Modelo Refinado
par(mfrow = c(1,2))
acf(modelo.arma.ref$residuals, lag = 20)
pacf(modelo.arma.ref$residuals, lag = 20)

Debido a que se observa que todos las estructuras se encuentran dentro de las bandas de confianza, este será el nuevo modelo a utilizar. Es necesario mencionar que dicho modelo refinado se transforma en un modelo AR1, debido a que el MA no sale significativa.

Probar Estacionariedad

Finalmente, se realizará una prueba de estacionariedad mediante la obtención de las raíces del polinomio característico. En dicha prueba es necesario tomar en cuenta el valor de la raíz, debido a que si esta es mayor a 1, se considera que el modelo es estacionario.

pol.car.arma <-c(1,-modelo.arma.ref$coef[1])
raices <- polyroot(pol.car.arma)
abs(raices)
[1] 1.563666

Debido a que la raíz del polinomio característico es mayor a 1, se concluye que dicho modelo es estacionario.

2. Pronóstico de la Tasa de Subocupación

Con el objetivo de utilizar el mejor modelo adecuado para realizar un pronóstico óptimo, es necesario generar otro modelo en el cual se utilizará auto arima; una función automática que expone el mejor modelo a su consideración. Por lo tanto, dicho modelo estimado por auto arima, será comparado con el modelo ARMA (1,1) propuesto en la sección anterior.

Estimación Auto Arima

auto.sub <- auto.arima(subocupacion, d = 0, seasonal = F, ic = "bic")
auto.sub
Series: subocupacion 
ARIMA(1,0,0) with non-zero mean 

Coefficients:
         ar1    mean
      0.6395  8.6172
s.e.  0.0895  0.6818

sigma^2 = 4.573:  log likelihood = -151.78
AIC=309.56   AICc=309.92   BIC=316.31

El modelo propuesto por la función auto arima arroja una sugerencia de modelo AR1.

Es necesario mencionar que en la sección anterior se encontró como modelo refinado un AR(1), asimismo, el modelo autoarima arrojó AR(1). Con el objetivo de realizar una comparación óptima entre modelos distintos, se decidió utilizar el modelo original (ARMA(1,1)) y no el refinado, con el fin de realizar una comparación con el modelo autoarima (AR(1)).

Posteriormente, se validara el modelo mediante un correlograma, en donde se identifique si dicho modelo sigue un proceso de Ruido Blanco, lo cual, significaría que no tiene autocorrelación, por lo tanto, esta sería estadísticamente cero.

Validación Modelo Auto Arima
par(mfrow = c(1,2))
acf(auto.sub$residuals, lag = 20)
pacf(auto.sub$residuals, lag = 20)

Se observa que el modelo AR(1) sigue un proceso de Ruido Blanco, por lo tanto, es un modelo adecuado.

En la generación de pronósticos se puede presentar el “error sobreajuste”, el cual quiere decir que los valores de los pronósticos es generado conforme a valores de “y”. Por lo tanto, se debe de dividir la muestra en grupos de entrenamiento y prueba. El conjunto de entrenamiento sirve para realizar un pronóstico que después se comparará con los valores de prueba.

Generación de grupos de entrenamiento y prueba

entrenamiento <- subset(sub.ts[,"sub"], end = length(sub.ts[,"sub"])- 14)
prueba <- subset(sub.ts[,"sub"], start = length(sub.ts[,"sub"])- 13)
Estimación de Modelos
arma11.entrenamiento <- Arima(entrenamiento, order = c(1,0,1))
ar1.entrenamiento <- Arima(entrenamiento, order = c(1,0,0))
Representación Gráfica

Pronóstico del modelo ARMA (1,1):

#ARMA(1,1)

arma11.entrenamiento %>%
  forecast(h=20) %>%
autoplot(xlab = "", ylab = "Tasa de subocupación (%)") + autolayer(prueba)

Pronóstico del modelo AR(1):

#AR(1)
ar1.entrenamiento %>%
  forecast(h=20) %>%
autoplot(xlab = "", ylab = "Tasa de subocupación (%)") + autolayer(prueba)

Con el objetivo de comparar cuál de los pronósticos es mejor, se realiza lo siguiente.

Comparación de ambos modelos mediante la prueba Diebold Mariano

La prueba Diebold Mariano, tiene como objetivo analizar si existe una diferencia sistemática entre los errores de los modelos, en dado caso de que sí, se considera mejor modelo el cual tenga un error menor.

sub.pron.arma11 <- forecast(arma11.entrenamiento, h = 20)
sub.pron.ar1 <- forecast(ar1.entrenamiento, h = 20)
Error del pronóstico
e.arma11 <- prueba - sub.pron.arma11$mean
e.ar1 <- prueba - sub.pron.ar1$mean
Error absoluto medio (MAE)

El Error Absoluto Medio se calcula con la siguiente fórmula:

\[\begin{align*} MAE = \frac{1}{p} \sum_{i=1}^{p}\left|y_{1}-f_{i} \right| \end{align*}\]

options(digits = 4)
MAE.arma11 <- sum(abs(e.arma11))/length(prueba)
MAE.arma11
[1] 4.14
MAE.ar1 <- sum(abs(e.ar1))/length(prueba)
MAE.ar1
[1] 4.059

En este caso los errores reflejan un valor alto debido a la gráfica observada, puesto que durante la pandemia se observaron resultados que no siguieron la tendencia de dicha tasa de subocupación, ya que este evento se relaciona con la teoría black swan, en donde dicho evento desató un gran impacto en el país.

Prueba Diebold Mariano

Debido a que no es suficiente observar el mejor modelo solo comparando los MAE, es necesario realizar una prueba que arroje si existe una diferencia sistemática entre los errores.

#Adaptación a rolling window (se debe hacer previo a la prueba DM)
farma11 <- function(x, h){forecast(Arima(x, order=c(1,0,1)), h=h)}
far1 <- function(x, h){forecast(Arima(x, order=c(1,0,0)), h=h)}
e.arma11.rw <- tsCV(sub.ts[,"sub"], farma11, h = 1, window = 56)
e.ar1.rw <- tsCV(sub.ts[,"sub"], far1, h = 1, window = 56)
dm.test(abs(e.arma11.rw), abs(e.ar1.rw),
        alternative = "two.sided", h = 1, power = 1)

    Diebold-Mariano Test

data:  abs(e.arma11.rw)abs(e.ar1.rw)
DM = 0.77, Forecast horizon = 1, Loss function power = 1, p-value = 0.4
alternative hypothesis: two.sided

La hipotesis asociada a la prueba es la siguiente: \[\begin{align*} H_0: \bar{d} = 0 \\ H_a: \bar{d} \neq 0 \end{align*}\]

Debido a que el p-valor > 0.05, NO se rechaza H0. Por lo tanto, no hay una diferencia sistemática entre los errores.

Sin embargo, tomando en cuenta que se tomó ARMA(1,1) solo con el objetivo de realizar una comparación entre lo propuesto por auto arima, y que con el modelo refinado se obtuvo un AR(1), se tomará como mejor modelo AR(1).

Pronóstico

pron.ar1 = forecast(auto.sub, h = 20)
pron.ar1

ar1.entrenamiento %>%
  forecast(h=20) %>%
autoplot(xlab = "", ylab = "Tasa de subocupación (%)") + autolayer(prueba)

CONCLUSIÓN

De acuerdo con el modelo AR(1), el pronóstico para el siguiente trimestre de la tasa de subocupación en México, es de 8.695%, se observa que este porcentaje va disminuyendo a lo largo del tiempo, hasta que transcurren aproximadamente 12 periodos (trimestres), que es cuando tiende a la media (8.617%).

REFERENCIAS BIBLIOGRÁFICAS

ANEXOS

CÓDIGO RSTUDIO aquí

LS0tCnRpdGxlOiAiRXZpZGVuY2lhX2EwMTI4NDM1NCIKYXV0aG9yOiAiQW5nZWxhIE3DumppY2EgLyBBMDEyODQzNTQiCmRhdGU6ICcyMDIyLTEwLTE4JwpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCmBgYHtyLGluY2x1ZGU9RkFMU0V9CiNQYXF1ZXRlcsOtYSBuZWNlc2FyaWEKbGlicmFyeShmcHAyKQpsaWJyYXJ5KHVyY2EpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoZm9yZWNhc3QpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KE1MbWV0cmljcykKbGlicmFyeShzYW5kd2ljaCkKYGBgCgoKCiMjIyMgRWNvbm9tZXRyw61hIDIKCiMjIyMgR3J1cG8gMTAyCgojIDxiIHN0eWxlID0gJ2NvbG9yIDogYmxhY2s7IGZvbnQtc2l6ZTogNDBweDsnPgoqKkVWSURFTkNJQSBQUk9Ow5NTVElDT1MgREUgTEEgRUNPTk9Nw41BKio8L2I+CgojIyA8YiBzdHlsZSA9ICdjb2xvciA6IGJsYWNrOyc+KklOVFJPRFVDQ0nDk04qPC9iPgoKRGUgYWN1ZXJkbyBjb24gbGEgT3JnYW5pemFjacOzbiBJbnRlcm5hY2lvbmFsIGRlbCBUcmFiYWpvIChPSVQpLCBsYSBzdWJvY3VwYWNpw7NuIGVzIGRlZmluaWRhIGNvbW8gbGEgc2l0dWFjacOzbiBlbiBsYSBjdWFsIGxvcyB0cmFiYWphZG9yZXMgcmVkdWNlbiBzdXMgaG9yYXMgZGUgdHJhYmFqbyB5IGxhYm9yYW4gZW4gZW1wbGVvcyBtZW5vcyBzYXRpc2ZhY3RvcmlvcyBjb24gZWwgb2JqZXRpdm8gZGUgZXZpdGFyIGVsIGRlc2VtcGxlbyAoTW9yYWxlcywgcy5mLikuIERlIGFjdWVyZG8gY29uIHVuIGVzdHVkaW8gcmVhbGl6YWRvIHBvciBDbGFyYSBKdWRpc21hbiwgcXVpw6luIGZ1bmdpw7MgY29tbyBEaXJlY3RvcmEgR2VuZXJhbCBkZWwgUmVnaXN0cm8gTmFjaW9uYWwgZGUgRWxlY3RvcmVzIGVuIE3DqXhpY28sIGVuIGxhcyBuYWNpb25lcyBkZSBtZW5vciBkZXNhcnJvbGxvIHJlc3VsdGEgbcOhcyBlZmVjdGl2byBlbCBhbsOhbGlzaXMgZGUgbGEgc3Vib2N1cGFjacOzbiBlbiBsdWdhciBkZSBlbCBhbsOhbGlzaXMgZGVsIGRlc2VtcGxlbywgZXN0byBzdWNlZGUgZGViaWRvIGEgcXVlIGRlIGFjdWVyZG8gY29uIEIuIERhdHRhIGVsIHByb2JsZW1hIHByaW5jaXBhbCBlbiBlc3RvcyBwYcOtc2VzICJubyBlcyBlbCB2b2x1bWVuLCBuw7ptZXJvIG8gcHJvcG9yY2nDs24gZGUgcGVyc29uYXMgZW1wbGVhZGFzLCBzaW5vIGVsIGdyYWRvIGRlbCBlbXBsZW8iIChKdWRpc21hbixzLmYsIHAuMjY5KS4gRW4gTcOpeGljbywgZ3JhbiBwb3JjZW50YWplIGRlIGxhIHBvYmxhY2nDs24gY2FyZWNlIGRlIHJlY3Vyc29zIGZpbmFuY2llcm9zIHBhcmEgcG9kZXIgbGFib3JhciBlbiB1biB0cmFiYWpvIGFkZWN1YWRvLCBvIGNvbiB1biBwZXJpb2RvIGxhcmdvLCBwb3IgbG8gdGFudG8sIGxvcyBpbmRpdmlkdW9zIHByZWZpZXJlbiB0b21hciBjdWFscXVpZXIgZW1wbGVvIGFudGVzIGRlIHBlcm1hbmVjZXIgZGVzZW1wbGVhZG9zIChKdWRpc21hbixzLmYscC4gMjc1KS4gUG9yIG90cm8gbGFkbywgQmFudGVndWkgcGxhbnRlYSBxdWUgImxhIGluYWRlY3VhZGEgdXRpbGl6YWNpw7NuIGRlIGxhIGZ1ZXJ6YSBkZSB0cmFiYWpvIG5vIHNlIGV4cHJlc2EgcG9yIGVsIGRlc2VtcGxlbywgc2lubywgZW4gbGEgY2FyZW5jaWEgZGUgZW1wbGVvcyBzYXRpc2ZhY3RvcmlvcyIgKEp1ZGlzbWFuLHMuZixwLiAyNzUpLiBEZWJpZG8gYSBlc3RvLCBlbiBlbCBwcmVzZW50ZSB0cmFiYWpvIHNlIHJlYWxpemFyw6EgdW4gcHJvbsOzc3RpY28gZGUgbGEgdmFyaWFibGUgZGUgc3Vib2N1cGFjacOzbiBjb24gZWwgcHJvZ3JhbWEgUiBTdHVkaW8uIEVuIGVzdGUgY2FzbyBzZSB1dGlsaXphcsOhIHVuYSBiYXNlIGRlIGRhdG9zIG9idGVuaWRhIGRlbCBJTkVHSSwgbGEgY3VhbCBjdWVudGEgY29uIDcwIG9ic2VydmFjaW9uZXMuIFBvciBvdHJvIGxhZG8sIGxhIHNlcmllIGVzIGRlIGxhIHZhcmlhY2nDs24gdHJpbWVzdHJhbCBkZSBsYSB0YXNhIGRlIHN1Ym9jdXBhY2nDs24gZW4gTcOpeGljbywgeSBzZSB0b21hcm9uIGRhdG9zIGRlc2RlIGVsIHByaW1lciB0cmltZXN0cmUgZGVsIGHDsW8gMjAwNSwgYWwgc2VndW5kbyB0cmltZXN0cmUgZGVsIGHDsW8gMjAyMi4gCgoKIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBibGFjazsnPipERVNBUlJPTExPKjwvYj4KMS4gTW9kZWxhciBsYSBzZXJpZSBkZSBUaWVtcG8KICAqIFJlcHJlc2VudGFjacOzbiBHcsOhZmljYQogICogUHJ1ZWJhIERpY2tleSBGdWxsZXIKICAqIElkZW50aWZpY2FyIGVsIE1vZGVsbwogICogVmFsaWRhY2nDs24gZGUgTW9kZWxvCiAgKiBSZWZpbmFjacOzbiBkZWwgTW9kZWxvCjIuIFByb27Ds3N0aWNvIGRlIGxhIFRhc2EgZGUgU3Vib2N1cGFjacOzbgogICogRXN0aW1hY2nDs24gQXV0byBBcmltYQogICogR2VuZXJhY2nDs24gZGUgR3J1cG9zIGRlIEVudHJlbmFtaWVudG8geSBQcnVlYmEKICAqIENvbXBhcmFjacOzbiBkZSBNb2RlbG9zIC0gUHJ1ZWJhIERpYWJvbGQgTWFyaWFubwogICogUHJvbsOzc3RpY28KCiMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGJsYWNrOyc+KioxLiBNb2RlbGFyIGxhIFNlcmllIGRlIFRpZW1wbyoqPC9iPgoKIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGdyYXk7Jz5MZWN0dXJhIGRlIGJhc2UgZGUgZGF0b3MgPC9iPgpgYGB7cn0KZGF0b3MgPC0gcmVhZF9leGNlbCgifi9EZXNrdG9wL01FzIFUT0RPU18gUi9zdWJvY3VwYWNpb24ueGxzeCIpCmRhdGUgPSBhcy5EYXRlKGRhdG9zJEZlY2hhLCBmb3JtYXQgPSAiJVkvJW0vJWQiKQpzdWJvY3VwYWNpb24gPSBkYXRvcyRzdWIKYGBgCiMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiByZWQ7Jz4gUmVwcmVzZW50YWNpw7NuIEdyw6FmaWNhIDwvYj4gCkVuIHByaW1lcmEgaW5zdGFuY2lhIHNlIHJlYWxpemEgdW5hIHJlcHJlc2VudGFjacOzbiBncsOhZmljYSBwYXJhIG9ic2VydmFyIHNpIGxhIHNlcmllIGVzIGVzdGFjaW9uYXJpYS4gCgpgYGB7cn0KcGxvdChkYXRvcyRzdWIsIHR5cGUgPSAibCIsIHhsYWIgPSAiIiwgeWxhYiA9ICIlIiwgbWFpbiA9ICIiKQpgYGAKClNpbiBlbWJhcmdvLCBlbCBhbsOhbGlzaXMgZ3LDoWZpY28gbm8gZXMgc3VmaWNpZW50ZSBwYXJhIG9ic2VydmFyIGVzdGEgcHJvcGllZGFkLiAgIFBvciBsbyB0YW50bywgc2UgcHJvY2VkZSBhIHJlYWxpemFyIHVuYSBwcnVlYmEgcXVlIGNvbnRyaWJ1eWEgYSBkZW1vc3RyYXIgICAgICAgIGVzdGFjaW9uYXJpZWRhZC4gIAoKIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IHJlZDsnPiBQcnVlYmEgRGlja3kgRnVsbGVyIChuaXZlbCBkZSBzaWduaWZpY2FuY2lhIDUlKSA8L2I+IAoKRWwgb2JqZXRpdm8gZGUgZXN0YSBwcnVlYmEgZXMgb2JzZXJ2YXIgc2kgbGEgc2VyaWUgYSB1dGlsaXphciBlcyBlc3RhY2lvbmFyaWEgbyBubywgZXN0byBxdWllcmUgZGVjaXIgcXVlIGxvcyBtb21lbnRvcyBlc3RhZMOtc3RpY29zIG5vIGRlcGVuZGFuIGRlbCB0aWVtcG8uIEVzdGEgcHJ1ZWJhIGF1bWVudGFkYSBkZSBEaWNrZXktRnVsbGVyIHNlIGVzdGltYSBjb24gdW5hIHJlZ3Jlc2nDs24gYXV4aWxpYXIuIApMYSBlY3VhY2nDs24gYXNvY2lhZGEgZXM6CgpcYmVnaW57YWxpZ24qfQpcRGVsdGEgeV90ID0gXGJldGFfMCArIFxkZWx0YSB0ICsgXHBoaSB5X3t0LTF9ICsgXHN1bV97aT0xfV57cH1cYmV0YSBcRGVsdGEgeV97dC1pfStlX3QKXGVuZHthbGlnbip9CgpMYSBoaXBvdGVzaXMgYXNvY2lhZGEgYSBsYSBwcnVlYmEgZXMgbGEgc2lndWllbnRlOgpcYmVnaW57YWxpZ24qfQpIXzA6IFxwaGkgPSAwIFxcCkhfYTogXHBoaSBcbmVxIDAKClxlbmR7YWxpZ24qfQoKU2kgc2UgcmVjaGF6YSBIMCBsYSBzZXJpZSBubyB0aWVuZSByYcOteiB1bml0YXJpYSwgcG9yIGxvIHRhbnRvLCBsYSBzZXJpZSBlcyBlc3RhY2lvbmFyaWEuCgoqU2UgdXNhcsOhIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgZGVsIDUlKgoKUmVhbGl6YW5kbyBwb3IgcHJpbWVyYSB2ZXogbGEgcHJ1ZWJhIHNlIG9ic2VydmEgbG8gc2lndWllbnRlOgoKCmBgYHtyfQpzdWIudHMgPC0gdHMoZGF0b3MgLHN0YXJ0ID0gYygyMDA1LDAxKSwgZW5kID0gYygyMDIyLDAyKSwgZnJlcXVlbmN5ID0gNCkjQ29udmlydGllbmRvIGEgc2VyaWVzIGRlIHRpZW1wbwphZGYuc3ViLnRyZW5kIDwtIHVyLmRmKHN1Yi50c1ssInN1YiJdLCB0eXBlID0gInRyZW5kIiwgc2VsZWN0bGFncyA9ICJCSUMiKQpzdW1tYXJ5KGFkZi5zdWIudHJlbmQpCmBgYAoKRGViaWRvIGEgcXVlIGVsIHZhbG9yIGRlIHRlc3Qtc3RhdGlzdGljIG5vIGVzIG3DoXMgbmVnYXRpdm8gcXVlIGVsIHZhbG9yIGRlIHRhdTMgZW4gdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBhbCA1JSwgTk8gc2UgcmVjaGF6YSBIMC4gUG9yIG90cm8gbGFkbywgeWEgcXVlIGVsIHZhbG9yIHRlc3Qtc3RhdGlzdGljIDMuNTcgbm8gZXMgbWF5b3IgYWwgdmFsb3IgZGUgcGhpMiwgZW4gdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSBkZSA1JSwgTk8gc2UgcmVjaGF6YSBIMC4gCgpEZWJpZG8gYSBxdWUgbGEgc2VyaWUgc2lnbyBjb250YW5kbyBjb24gcmHDrXogdW5pdGFyaWEsIHNlIHJlYWxpemEgb3RyYSBwcnVlYmEgcmVtb3ZpZW5kbyBsYSB0ZW5kZW5jaWEgY29uIGxhIGZ1bmNpw7NuICJkcmlmdCIuCgpgYGB7cn0KYWRmLnN1Yi5kcmlmdCA8LSB1ci5kZihzdWIudHNbLCJzdWIiXSwgdHlwZSA9ICJkcmlmdCIsIHNlbGVjdGxhZ3MgPSAiQklDIikKc3VtbWFyeShhZGYuc3ViLmRyaWZ0KQpgYGAKCllhIHF1ZSBlbCB2YWxvciBkZSB0ZXN0LXN0YXRpc3RpYyAoLTIuODkpIGVzIG3DoXMgbmVnYXRpdm8gcXVlIGVsIHZhbG9yIGRlIHRhdSAoLTIuODkpIGVuIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgYWwgNSUsIHNlIHJlY2hhemEgSDAuIAoKKipTZSBjb25jbHV5ZSBxdWUgbGEgc2VyaWUgZXMgZXN0YWNpb25hcmlhIHkgTk8gdGllbmUgcmHDrXogdW5pdGFyaWEuKioKKipFbCBtb2RlbG8gZXMgZXN0YWNpb25hcmlvIHkgdGllbmUgdW4gb3JkZW4gZGUgaW50ZWdyYWNpw7NuIGRlIGNlcm8uKioKCiMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiByZWQ7Jz4gSWRlbnRpZmljYXIgZWwgTW9kZWxvIDwvYj4KIyMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBncmF5Oyc+IENvcnJlbG9ncmFtYSA8L2I+CgpDb24gZWwgb2JqZXRpdm8gZGUgaWRlbnRpZmljYXIgZWwgbW9kZWxvIGFkZWN1YWRhbWVudGUgc2UgdXRpbGl6YXLDoSB1biBjb3JyZWxvZ3JhbWEsIGVsIGN1YWwgcGVybWl0aXLDoSBvYnNlcnZhciBzaSBzZSBjdWVudGEgY29uIHVuIG1vZGVsbyBBUiwgTUEgbyBBUk1BLiAKCgpgYGB7cn0KcGFyKG1mcm93ID0gYygxLDIpKQphY2Yoc3Vib2N1cGFjaW9uLCBsYWcgPSAyMCkKcGFjZihzdWJvY3VwYWNpb24sIGxhZyA9IDIwKQpgYGAKClRvbWFuZG8gZW4gY3VlbnRhIHF1ZSBlbCBkZWNhaW1pZW50byBnZW9tw6l0cmljbyBzZSBlbmN1ZW50cmEgZW4gQUNGIHkgQUNQLCBzZSBjb25jbHV5ZSBxdWUgZXMgdW4gbW9kZWxvIEFSTUEgKDEsMSkuIFBvciBsbyB0YW50bywgc2UgZXN0aW1hcsOhIGxhIGZ1bmNpw7NuIGFyaW1hIGNvbW8gdW4gbW9kZWxvIGRlIG9yZGVuICgxLDAsMSkuCgojIyMjIDxiIHN0eWxlID0gJ2NvbG9yIDogcmVkOyc+IFZhbGlkYWNpw7NuIE1vZGVsbyBBUk1BICgxLDEpIDwvYj4gCgojIyMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBncmF5Oyc+IEVzdGltYWNpw7NuIE1vZGVsbyBBUk1BKDEsMSkgPC9iPiAKYGBge3J9Cm1vZGVsby5hcm1hIDwtIGFyaW1hKGRhdG9zJHN1Yiwgb3JkZXIgPSBjKDEsIDAsIDEpKSAKbW9kZWxvLmFybWEKc3VtbWFyeShtb2RlbG8uYXJtYSkKYGBgCgojIyMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBibHVlOyc+IFBydWViYSBJbmRpdmlkdWFsIDwvYj4gCmBgYHtyfQpwYXIobWZyb3cgPSBjKDEsMikpCmFjZihtb2RlbG8uYXJtYSRyZXNpZHVhbHMsIGxhZyA9IDIwKQpwYWNmKG1vZGVsby5hcm1hJHJlc2lkdWFscywgbGFnID0gMjApCmBgYAoKRGViaWRvIGEgcXVlIGxhIGVzdHJ1Y3R1cmEgZW4gZWwgQUMgeSBBQ1Agc2UgZW5jdWVudHJhbiBkZW50cm8gZGUgbGFzIGJhbmRhcyBkZSBjb25maWFuemEsIHNlIGNvbmNsdXllIHF1ZSBlcyB1biAqKm1vZGVsbyBhZGVjdWFkbyoqLiAKCiMjIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGJsdWU7Jz4gUHJ1ZWJhIENvbmp1bnRhIDwvYj4gCgpQb3Igb3RybyBsYWRvLCBlbiBsYSBQcnVlYmEgQ29uanVudGEgZGUgTHl1bmcsIHNlIGJ1c2NhIG9ic2VydmFyIHNpIGhheSBlc3RydWN0dXJhIGRlIGF1dG9jb3JyZWxhY2nDs24uCmBgYHtyfQpCb3gudGVzdChtb2RlbG8uYXJtYSRyZXNpZHVhbHMsIHR5cGUgPSAiTGp1bmciLCBsYWcgPSAyMCkKYGBgCgpMYSBoaXBvdGVzaXMgYXNvY2lhZGEgYSBsYSBwcnVlYmEgZXMgbGEgc2lndWllbnRlOgoKIApcYmVnaW57YWxpZ24qfQpIXzA6IFxyaG9fMSA9IFxyaG9fMiA9MCBcXApIX2E6IFx0ZXh0cm17QWwgbWVub3MgdW4gcGFyw6FtZXRybyBlcyBkaXN0aW50byBkZSAwfQpcZW5ke2FsaWduKn0KCjxkaXYgc3R5bGUgPSAndGV4dC1hbGlnbjogY2VudGVyJz4KU2kKcC12YWxvciA+IDAuMDUgICBOTyBzZSByZWNoYXphIEgwIAoKPGRpdi8+IAoKCjxkaXYgc3R5bGUgPSAndGV4dC1hbGlnbjogbGVmdCc+CgpEZWJpZG8gYSBxdWUgZWwgcC12YWxvciAoMSkgZXMgbWF5b3IgYSAwLjA1LCBOTyBzZSByZWNoYXphIEgwLCBwb3IgbG8gdGFudG8sICoqTk8gaGF5IGVzdHJ1Y3R1cmEgZGUgYXV0b2NvcnJlbGFjacOzbiBlbiBlbCBtb2RlbG8sIGxvIGN1YWwgbG8gaGFjZSB1biBtb2RlbG8gdsOhbGlkby4qKiAKPGRpdi8+IAoKIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IHJlZDsnPiBSZWZpbmFjacOzbiBkZWwgTW9kZWxvIEFSTUEoMSwxKSA8L2I+IApNZWRpYW50ZSBlc3RlIHByb2Nlc28gc2UgYnVzY2Egb2JzZXJ2YXIgc2kgaGF5IHBhcsOhbWV0cm9zIHF1ZSBubyBzb24gc2lnbmlmaWNhdGl2b3MsIGxvIGN1YWwgc2lnbmlmaWNhcsOtYSBxdWUgbm8gYXBvcnRhbiBhbCBtb2RlbG8gZW4gY3Vlc3Rpw7NuLiBFc3RvIHNlIHJlYWxpemFyw6EgY29uIGxhIHBydWViYSAiQ29lZnRlc3QiLiAKCmBgYHtyfQpjb2VmdGVzdChtb2RlbG8uYXJtYSwgZGYgPSA2NykKI2RmID0gb2JzZXJ2YWNpb25lcyAtIHBhcsOhbWV0cm9zCiNkZiA9IDcwIC0gMwpgYGAKCjxkaXYgc3R5bGUgPSAndGV4dC1hbGlnbjogbGVmdCc+CgpFbiBlc3RhIHBydWViYSBzZSBvYnNlcnZhIHF1ZSBlbCBNQSBlcyB1biBwYXLDoW1ldHJvIE5PIHNpZ25pZmljYXRpdm8sIHBvciBsbyB0YW50bywgZXMgKipuZWNlc2FyaW8gcmVmaW5hciBlbCBtb2RlbG8qKi4gRXN0byBzZSByZWFsaXphcsOhIGFzaWduYW5kbyB1biBjZXJvIGEgZGljaG8gcGFyw6FtZXRybyBOTyBzaWduaWZpY2F0aXZvLiAKCjxkaXYvPiAKCmBgYHtyfQptb2RlbG8uYXJtYS5yZWYgPC0gYXJpbWEoc3Vib2N1cGFjaW9uLCB0cmFuc2Zvcm0ucGFycyA9IFRSVUUsIG9yZGVyID0gYygxLCAwLCAxKSwgZml4ZWQgPSBjKE5BLDAsTkEpKQptb2RlbG8uYXJtYS5yZWYKYGBgCgojIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGdyYXk7Jz4gQ29ycmVsb2dyYW1hIGRlIE1vZGVsbyBSZWZpbmFkbyA8L2I+CgpgYGB7cn0KcGFyKG1mcm93ID0gYygxLDIpKQphY2YobW9kZWxvLmFybWEucmVmJHJlc2lkdWFscywgbGFnID0gMjApCnBhY2YobW9kZWxvLmFybWEucmVmJHJlc2lkdWFscywgbGFnID0gMjApCmBgYAoKRGViaWRvIGEgcXVlIHNlIG9ic2VydmEgcXVlIHRvZG9zIGxhcyBlc3RydWN0dXJhcyBzZSBlbmN1ZW50cmFuIGRlbnRybyBkZSBsYXMgYmFuZGFzIGRlIGNvbmZpYW56YSwgZXN0ZSBzZXLDoSBlbCBudWV2byBtb2RlbG8gYSB1dGlsaXphci4gCkVzIG5lY2VzYXJpbyBtZW5jaW9uYXIgcXVlIGRpY2hvIG1vZGVsbyByZWZpbmFkbyBzZSB0cmFuc2Zvcm1hIGVuIHVuIG1vZGVsbyBBUjEsIGRlYmlkbyBhIHF1ZSBlbCBNQSBubyBzYWxlIHNpZ25pZmljYXRpdmEuCgojIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGdyYXk7Jz4gUHJvYmFyIEVzdGFjaW9uYXJpZWRhZCA8L2I+CgpGaW5hbG1lbnRlLCBzZSByZWFsaXphcsOhIHVuYSBwcnVlYmEgZGUgZXN0YWNpb25hcmllZGFkIG1lZGlhbnRlIGxhIG9idGVuY2nDs24gZGUgbGFzIHJhw61jZXMgZGVsIHBvbGlub21pbyBjYXJhY3RlcsOtc3RpY28uIEVuIGRpY2hhIHBydWViYSBlcyBuZWNlc2FyaW8gdG9tYXIgZW4gY3VlbnRhIGVsIHZhbG9yIGRlIGxhIHJhw616LCBkZWJpZG8gYSBxdWUgc2kgZXN0YSBlcyBtYXlvciBhIDEsIHNlIGNvbnNpZGVyYSBxdWUgZWwgbW9kZWxvIGVzIGVzdGFjaW9uYXJpby4gCgpgYGB7cn0KcG9sLmNhci5hcm1hIDwtYygxLC1tb2RlbG8uYXJtYS5yZWYkY29lZlsxXSkKcmFpY2VzIDwtIHBvbHlyb290KHBvbC5jYXIuYXJtYSkKYWJzKHJhaWNlcykKYGBgCgpEZWJpZG8gYSBxdWUgbGEgcmHDrXogZGVsIHBvbGlub21pbyBjYXJhY3RlcsOtc3RpY28gZXMgbWF5b3IgYSAxLCBzZSBjb25jbHV5ZSBxdWUgZGljaG8gbW9kZWxvICoqZXMgZXN0YWNpb25hcmlvKiouCgojIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBibGFjazsnPiAyLiBQcm9uw7NzdGljbyBkZSBsYSBUYXNhIGRlIFN1Ym9jdXBhY2nDs24gPC9iPgoKQ29uIGVsIG9iamV0aXZvIGRlIHV0aWxpemFyIGVsIG1lam9yIG1vZGVsbyBhZGVjdWFkbyBwYXJhIHJlYWxpemFyIHVuIHByb27Ds3N0aWNvIMOzcHRpbW8sIGVzIG5lY2VzYXJpbyBnZW5lcmFyIG90cm8gbW9kZWxvIGVuIGVsIGN1YWwgc2UgdXRpbGl6YXLDoSBhdXRvIGFyaW1hOyB1bmEgZnVuY2nDs24gYXV0b23DoXRpY2EgcXVlIGV4cG9uZSBlbCBtZWpvciBtb2RlbG8gYSBzdSBjb25zaWRlcmFjacOzbi4gUG9yIGxvIHRhbnRvLCBkaWNobyBtb2RlbG8gZXN0aW1hZG8gcG9yIGF1dG8gYXJpbWEsIHNlcsOhIGNvbXBhcmFkbyBjb24gZWwgbW9kZWxvIEFSTUEgKDEsMSkgcHJvcHVlc3RvIGVuIGxhIHNlY2Npw7NuIGFudGVyaW9yLgoKIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IHJlZDsnPiBFc3RpbWFjacOzbiBBdXRvIEFyaW1hICA8L2I+IApgYGB7cn0KYXV0by5zdWIgPC0gYXV0by5hcmltYShzdWJvY3VwYWNpb24sIGQgPSAwLCBzZWFzb25hbCA9IEYsIGljID0gImJpYyIpCmF1dG8uc3ViCmBgYAoKRWwgbW9kZWxvIHByb3B1ZXN0byBwb3IgbGEgZnVuY2nDs24gYXV0byBhcmltYSBhcnJvamEgdW5hIHN1Z2VyZW5jaWEgZGUgbW9kZWxvIEFSMS4KCioqRXMgbmVjZXNhcmlvIG1lbmNpb25hciBxdWUgZW4gbGEgc2VjY2nDs24gYW50ZXJpb3Igc2UgZW5jb250csOzIGNvbW8gbW9kZWxvIHJlZmluYWRvIHVuIEFSKDEpLCBhc2ltaXNtbywgZWwgbW9kZWxvIGF1dG9hcmltYSBhcnJvasOzIEFSKDEpLiBDb24gZWwgb2JqZXRpdm8gZGUgcmVhbGl6YXIgdW5hIGNvbXBhcmFjacOzbiDDs3B0aW1hIGVudHJlIG1vZGVsb3MgZGlzdGludG9zLCBzZSBkZWNpZGnDsyB1dGlsaXphciBlbCBtb2RlbG8gb3JpZ2luYWwgKEFSTUEoMSwxKSkgeSBubyBlbCByZWZpbmFkbywgY29uIGVsIGZpbiBkZSByZWFsaXphciB1bmEgY29tcGFyYWNpw7NuIGNvbiBlbCBtb2RlbG8gYXV0b2FyaW1hIChBUigxKSkuKioKClBvc3Rlcmlvcm1lbnRlLCBzZSB2YWxpZGFyYSBlbCBtb2RlbG8gbWVkaWFudGUgdW4gY29ycmVsb2dyYW1hLCBlbiBkb25kZSBzZSBpZGVudGlmaXF1ZSBzaSBkaWNobyBtb2RlbG8gc2lndWUgdW4gcHJvY2VzbyBkZSBSdWlkbyBCbGFuY28sIGxvIGN1YWwsIHNpZ25pZmljYXLDrWEgcXVlIG5vIHRpZW5lIGF1dG9jb3JyZWxhY2nDs24sIHBvciBsbyB0YW50bywgZXN0YSBzZXLDrWEgZXN0YWTDrXN0aWNhbWVudGUgY2Vyby4gCgojIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGdyYXk7Jz4gVmFsaWRhY2nDs24gTW9kZWxvIEF1dG8gQXJpbWEgPC9iPiAKYGBge3J9CnBhcihtZnJvdyA9IGMoMSwyKSkKYWNmKGF1dG8uc3ViJHJlc2lkdWFscywgbGFnID0gMjApCnBhY2YoYXV0by5zdWIkcmVzaWR1YWxzLCBsYWcgPSAyMCkKYGBgCgpTZSBvYnNlcnZhIHF1ZSBlbCBtb2RlbG8gQVIoMSkgc2lndWUgdW4gcHJvY2VzbyBkZSBSdWlkbyBCbGFuY28sIHBvciBsbyB0YW50bywgZXMgdW4gbW9kZWxvIGFkZWN1YWRvLiAKCkVuIGxhIGdlbmVyYWNpw7NuIGRlIHByb27Ds3N0aWNvcyBzZSBwdWVkZSBwcmVzZW50YXIgZWwgImVycm9yIHNvYnJlYWp1c3RlIiwgZWwgY3VhbCBxdWllcmUgZGVjaXIgcXVlIGxvcyB2YWxvcmVzIGRlIGxvcyBwcm9uw7NzdGljb3MgZXMgZ2VuZXJhZG8gY29uZm9ybWUgYSB2YWxvcmVzIGRlICJ5Ii4gUG9yIGxvIHRhbnRvLCBzZSBkZWJlIGRlIGRpdmlkaXIgbGEgbXVlc3RyYSBlbiBncnVwb3MgZGUgZW50cmVuYW1pZW50byB5IHBydWViYS4gRWwgY29uanVudG8gZGUgZW50cmVuYW1pZW50byBzaXJ2ZSBwYXJhIHJlYWxpemFyIHVuIHByb27Ds3N0aWNvIHF1ZSBkZXNwdcOpcyBzZSBjb21wYXJhcsOhIGNvbiBsb3MgdmFsb3JlcyBkZSBwcnVlYmEuICAKCiMjIyMgIDxiIHN0eWxlID0gJ2NvbG9yIDogcmVkOyc+IEdlbmVyYWNpw7NuIGRlIGdydXBvcyBkZSBlbnRyZW5hbWllbnRvIHkgcHJ1ZWJhICA8L2I+CmBgYHtyfQplbnRyZW5hbWllbnRvIDwtIHN1YnNldChzdWIudHNbLCJzdWIiXSwgZW5kID0gbGVuZ3RoKHN1Yi50c1ssInN1YiJdKS0gMTQpCnBydWViYSA8LSBzdWJzZXQoc3ViLnRzWywic3ViIl0sIHN0YXJ0ID0gbGVuZ3RoKHN1Yi50c1ssInN1YiJdKS0gMTMpCmBgYAoKIyMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBncmF5Oyc+IEVzdGltYWNpw7NuIGRlIE1vZGVsb3MgPC9iPiAKYGBge3J9CmFybWExMS5lbnRyZW5hbWllbnRvIDwtIEFyaW1hKGVudHJlbmFtaWVudG8sIG9yZGVyID0gYygxLDAsMSkpCmFyMS5lbnRyZW5hbWllbnRvIDwtIEFyaW1hKGVudHJlbmFtaWVudG8sIG9yZGVyID0gYygxLDAsMCkpCmBgYAoKIyMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBncmF5Oyc+IFJlcHJlc2VudGFjacOzbiBHcsOhZmljYSAgPC9iPiAKClByb27Ds3N0aWNvIGRlbCBtb2RlbG8gQVJNQSAoMSwxKToKYGBge3J9CiNBUk1BKDEsMSkKCmFybWExMS5lbnRyZW5hbWllbnRvICU+JQogIGZvcmVjYXN0KGg9MjApICU+JQphdXRvcGxvdCh4bGFiID0gIiIsIHlsYWIgPSAiVGFzYSBkZSBzdWJvY3VwYWNpw7NuICglKSIpICsgYXV0b2xheWVyKHBydWViYSkKCmBgYAoKUHJvbsOzc3RpY28gZGVsIG1vZGVsbyBBUigxKToKYGBge3J9CiNBUigxKQphcjEuZW50cmVuYW1pZW50byAlPiUKICBmb3JlY2FzdChoPTIwKSAlPiUKYXV0b3Bsb3QoeGxhYiA9ICIiLCB5bGFiID0gIlRhc2EgZGUgc3Vib2N1cGFjacOzbiAoJSkiKSArIGF1dG9sYXllcihwcnVlYmEpCmBgYAoKCkNvbiBlbCBvYmpldGl2byBkZSBjb21wYXJhciBjdcOhbCBkZSBsb3MgcHJvbsOzc3RpY29zIGVzIG1lam9yLCBzZSByZWFsaXphIGxvIHNpZ3VpZW50ZS4gCgojIyMjIDxiIHN0eWxlID0gJ2NvbG9yIDogcmVkOyc+IENvbXBhcmFjacOzbiBkZSBhbWJvcyBtb2RlbG9zIG1lZGlhbnRlIGxhIHBydWViYSBEaWVib2xkIE1hcmlhbm8gPC9iPiAKCkxhIHBydWViYSBEaWVib2xkIE1hcmlhbm8sIHRpZW5lIGNvbW8gb2JqZXRpdm8gYW5hbGl6YXIgc2kgZXhpc3RlIHVuYSBkaWZlcmVuY2lhIHNpc3RlbcOhdGljYSBlbnRyZSBsb3MgZXJyb3JlcyBkZSBsb3MgbW9kZWxvcywgZW4gZGFkbyBjYXNvIGRlIHF1ZSBzw60sIHNlIGNvbnNpZGVyYSBtZWpvciBtb2RlbG8gZWwgY3VhbCB0ZW5nYSB1biBlcnJvciBtZW5vci4gCgpgYGB7cn0Kc3ViLnByb24uYXJtYTExIDwtIGZvcmVjYXN0KGFybWExMS5lbnRyZW5hbWllbnRvLCBoID0gMjApCnN1Yi5wcm9uLmFyMSA8LSBmb3JlY2FzdChhcjEuZW50cmVuYW1pZW50bywgaCA9IDIwKQpgYGAKCiMjIyMjIDxiIHN0eWxlID0gJ2NvbG9yIDogZ3JheTsnPiBFcnJvciBkZWwgcHJvbsOzc3RpY28gPC9iPiAKYGBge3J9CmUuYXJtYTExIDwtIHBydWViYSAtIHN1Yi5wcm9uLmFybWExMSRtZWFuCmUuYXIxIDwtIHBydWViYSAtIHN1Yi5wcm9uLmFyMSRtZWFuCmBgYAojIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IGdyYXk7Jz4gRXJyb3IgYWJzb2x1dG8gbWVkaW8gKE1BRSkgPC9iPiAKCkVsIEVycm9yIEFic29sdXRvIE1lZGlvIHNlIGNhbGN1bGEgY29uIGxhIHNpZ3VpZW50ZSBmw7NybXVsYToKClxiZWdpbnthbGlnbip9Ck1BRSA9IFxmcmFjezF9e3B9IFxzdW1fe2k9MX1ee3B9XGxlZnR8eV97MX0tZl97aX0gXHJpZ2h0fCAKXGVuZHthbGlnbip9CgoKYGBge3J9Cm9wdGlvbnMoZGlnaXRzID0gNCkKTUFFLmFybWExMSA8LSBzdW0oYWJzKGUuYXJtYTExKSkvbGVuZ3RoKHBydWViYSkKTUFFLmFybWExMQpNQUUuYXIxIDwtIHN1bShhYnMoZS5hcjEpKS9sZW5ndGgocHJ1ZWJhKQpNQUUuYXIxCmBgYAoKRW4gZXN0ZSBjYXNvIGxvcyBlcnJvcmVzIHJlZmxlamFuIHVuIHZhbG9yIGFsdG8gZGViaWRvIGEgbGEgZ3LDoWZpY2Egb2JzZXJ2YWRhLCBwdWVzdG8gcXVlIGR1cmFudGUgbGEgcGFuZGVtaWEgc2Ugb2JzZXJ2YXJvbiByZXN1bHRhZG9zIHF1ZSBubyBzaWd1aWVyb24gbGEgdGVuZGVuY2lhIGRlIGRpY2hhIHRhc2EgZGUgc3Vib2N1cGFjacOzbiwgeWEgcXVlIGVzdGUgZXZlbnRvIHNlIHJlbGFjaW9uYSBjb24gbGEgdGVvcsOtYSBibGFjayBzd2FuLCBlbiBkb25kZSBkaWNobyBldmVudG8gZGVzYXTDsyB1biBncmFuIGltcGFjdG8gZW4gZWwgcGHDrXMuCgoKIyMjIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBibHVlOyc+IFBydWViYSBEaWVib2xkIE1hcmlhbm8gPC9iPiAgCgpEZWJpZG8gYSBxdWUgbm8gZXMgc3VmaWNpZW50ZSBvYnNlcnZhciBlbCBtZWpvciBtb2RlbG8gc29sbyBjb21wYXJhbmRvIGxvcyBNQUUsIGVzIG5lY2VzYXJpbyByZWFsaXphciB1bmEgcHJ1ZWJhIHF1ZSBhcnJvamUgc2kgZXhpc3RlIHVuYSBkaWZlcmVuY2lhIHNpc3RlbcOhdGljYSBlbnRyZSBsb3MgZXJyb3Jlcy4KCmBgYHtyfQojQWRhcHRhY2nDs24gYSByb2xsaW5nIHdpbmRvdyAoc2UgZGViZSBoYWNlciBwcmV2aW8gYSBsYSBwcnVlYmEgRE0pCmZhcm1hMTEgPC0gZnVuY3Rpb24oeCwgaCl7Zm9yZWNhc3QoQXJpbWEoeCwgb3JkZXI9YygxLDAsMSkpLCBoPWgpfQpmYXIxIDwtIGZ1bmN0aW9uKHgsIGgpe2ZvcmVjYXN0KEFyaW1hKHgsIG9yZGVyPWMoMSwwLDApKSwgaD1oKX0KZS5hcm1hMTEucncgPC0gdHNDVihzdWIudHNbLCJzdWIiXSwgZmFybWExMSwgaCA9IDEsIHdpbmRvdyA9IDU2KQplLmFyMS5ydyA8LSB0c0NWKHN1Yi50c1ssInN1YiJdLCBmYXIxLCBoID0gMSwgd2luZG93ID0gNTYpCmRtLnRlc3QoYWJzKGUuYXJtYTExLnJ3KSwgYWJzKGUuYXIxLnJ3KSwKICAgICAgICBhbHRlcm5hdGl2ZSA9ICJ0d28uc2lkZWQiLCBoID0gMSwgcG93ZXIgPSAxKQpgYGAKTGEgaGlwb3Rlc2lzIGFzb2NpYWRhIGEgbGEgcHJ1ZWJhIGVzIGxhIHNpZ3VpZW50ZToKXGJlZ2lue2FsaWduKn0KSF8wOiBcYmFye2R9ID0gMCBcXApIX2E6IFxiYXJ7ZH0gXG5lcSAwCgpcZW5ke2FsaWduKn0KCkRlYmlkbyBhIHF1ZSBlbCBwLXZhbG9yID4gMC4wNSwgTk8gc2UgcmVjaGF6YSBIMC4KUG9yIGxvIHRhbnRvLCBubyBoYXkgdW5hIGRpZmVyZW5jaWEgc2lzdGVtw6F0aWNhIGVudHJlIGxvcyBlcnJvcmVzLgoKU2luIGVtYmFyZ28sIHRvbWFuZG8gZW4gY3VlbnRhIHF1ZSBzZSB0b23DsyBBUk1BKDEsMSkgc29sbyBjb24gZWwgb2JqZXRpdm8gZGUgcmVhbGl6YXIgdW5hIGNvbXBhcmFjacOzbiBlbnRyZSBsbyBwcm9wdWVzdG8gcG9yIGF1dG8gYXJpbWEsIHkgcXVlIGNvbiBlbCBtb2RlbG8gcmVmaW5hZG8gc2Ugb2J0dXZvIHVuIEFSKDEpLCBzZSB0b21hcsOhIGNvbW8gbWVqb3IgbW9kZWxvIEFSKDEpLgoKIyMjIyA8YiBzdHlsZSA9ICdjb2xvciA6IHJlZDsnPiBQcm9uw7NzdGljbyA8L2I+ICAKYGBge3J9CnByb24uYXIxID0gZm9yZWNhc3QoYXV0by5zdWIsIGggPSAyMCkKcHJvbi5hcjEKCmFyMS5lbnRyZW5hbWllbnRvICU+JQogIGZvcmVjYXN0KGg9MjApICU+JQphdXRvcGxvdCh4bGFiID0gIiIsIHlsYWIgPSAiVGFzYSBkZSBzdWJvY3VwYWNpw7NuICglKSIpICsgYXV0b2xheWVyKHBydWViYSkKYGBgCgoKIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBibGFjazsnPipDT05DTFVTScOTTio8L2I+CgoKRGUgYWN1ZXJkbyBjb24gZWwgbW9kZWxvIEFSKDEpLCBlbCBwcm9uw7NzdGljbyBwYXJhIGVsIHNpZ3VpZW50ZSB0cmltZXN0cmUgZGUgbGEgdGFzYSBkZSBzdWJvY3VwYWNpw7NuIGVuIE3DqXhpY28sIGVzIGRlIDguNjk1JSwgc2Ugb2JzZXJ2YSBxdWUgZXN0ZSBwb3JjZW50YWplIHZhIGRpc21pbnV5ZW5kbyBhIGxvIGxhcmdvIGRlbCB0aWVtcG8sIGhhc3RhIHF1ZSB0cmFuc2N1cnJlbiBhcHJveGltYWRhbWVudGUgMTIgcGVyaW9kb3MgKHRyaW1lc3RyZXMpLCBxdWUgZXMgY3VhbmRvIHRpZW5kZSBhIGxhIG1lZGlhICg4LjYxNyUpLiAKCiMjIDxiIHN0eWxlID0gJ2NvbG9yIDogYmxhY2s7Jz4qUkVGRVJFTkNJQVMgQklCTElPR1LDgUZJQ0FTKjwvYj4KCiogTW9yYWxlcywgRi4gKHMuZi4pLiBTdWJlbXBsZW8uIGh0dHBzOi8vZWNvbm9taXBlZGlhLmNvbS9kZWZpbmljaW9uZXMvc3ViZW1wbGVvLmh0bWwgCiogSnVkaXNtYW4sIEMuIChzLmYuKS4gQ29uY2VwdG9zIHkgRGVmaW5pY2lvbmVzIGVuIFJlbGFjacOzbiBjb24gZWwgRW1wbGVvLCBEZXNlbXBsZW8geSBlbCBTdWJlbXBsZW8uIGh0dHBzOi8vZXN0dWRpb3NkZW1vZ3JhZmljb3N5dXJiYW5vcy5jb2xtZXgubXggIAoqIElORUdJLiAocy5mLikuIEJhbmNvIGRlIGluZm9ybWFjacOzbiBFY29uw7NtaWNhIChCSUUpLiBodHRwOi8vZW4ud3d3LmluZWdpLm9yZy5teC9hcHAvaW5kaWNhZG9yZXMvP3RtPTAmdD0xMDAwMDIxNSNEMTAwMDAyMTUjRDQ5MzkxMiNENDkzOTExIAoKIyMgPGIgc3R5bGUgPSAnY29sb3IgOiBibGFjazsnPipBTkVYT1MqPC9iPgoKQ8OTRElHTyBSU1RVRElPIFthcXXDrV0oaHR0cHM6Ly9ycHVicy5jb20vQW5nZWxhTXVqaWNhMjcvOTYwMjUxKQoK