library(ggfortify)
library(forecast)
library(fpp2)
library(gridExtra)
library(seasonal)
library(TSA)
library(urca)
library(ggplot2)

Breve referencia a los datos, frecuencia, unidad de medida, fuente, etc.

La serie representa la producción de limones con una frecuencia mensual, la unidad de medida es en toneladas y los datos recopilados fueron obtenidos de la página de INEGI del año 2010 al 2016 (última actualización).

http://www.inegi.org.mx/

Graficar los datos, analizar patrones y observaciones atípicas. Apoye su análisis con una descomposición clásica.

base<-read.csv(file.choose("limones.csv"))
limones<-ts(base$limones,start = c(2010,1),frequency=12)
Preciolimon<-ts(base$Precio,start = c(2010,1),frequency=12)
View(base)
pl<-plot(limones,xlab="periodo",main="Producción de Limones")

Observamos que la serie presenta estacionalidad, y es completamente cíclica. Los comportamientos de la producción de limón son de manera atípica que se debe a diversos factores, el comportamiento en un año de la producción durante los primeros meses se observa en los cultivos ya que se preparan para que posteriormente los arboles den fruto, por lo que durante los primeros meses la producción, es la mas baja del año; otro de los factores del estiaje de la producción, es que el cítrico no se desarrolle con excelencia y los frutos no den jugo aunado con los problemas cada vez mas presentes de los cambios de temperatura, que afectan las cosechas y con ello directamente en el precio del producto y al sector alimentario.

Descomposición Clasica

limondesc<- decompose(limones, type='additive')
autoplot(limondesc)

Se realizó la descomposición clasica para observar los componentes de la serie (estacionalidad,tendencia y ciclo) por separado

Utilizar transformación Box-Cox / logaritmos para estabilizar la varianza.

Presentar grafica.

BoxCox.ar(limones)

En el caso de esta serie no es necesario aplicar logaritmos debido a que la serie muestra unicamente un comportamiento estacional.

Modelar la serie de tiempo elegida como función de una tendencia, tendencia cuadratica y/o medias estcionales.Presenta el Diagnostico del modelo elegido.

Usando la serie elegida como variable dependiente y el tiempo como independiente.

limones.lm<-lm(limones ~ time(limones))
summary(limones.lm)

Call:
lm(formula = limones ~ time(limones))

Residuals:
     Min       1Q   Median       3Q      Max 
-1060953  -612848   -49737   625882  1161898 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)
(Intercept)   -153408302   93041438  -1.649    0.104
time(limones)      76708      46221   1.660    0.101

Residual standard error: 679200 on 70 degrees of freedom
Multiple R-squared:  0.03786,   Adjusted R-squared:  0.02411 
F-statistic: 2.754 on 1 and 70 DF,  p-value: 0.1015

Graficamos

ggplot(limones, aes(y=limones, x=time(limones))) +
  geom_point() +
  geom_smooth(method = "lm")

Observamos que los residuos tienden a alejarse del componente de referencia lo que determina que el modelo no es el indicado, puede deberse este comportamiento de los residuos a que durante los primeros meses del año la producción es casi nula

Evaluación del Modelo

autoplot(limones.lm, which = 1:6, ncol = 2, label.size = 3)

La distancia de cook representa eventos no controlados, tales como la estacionalidad ya que cada año se da una ventana natural de menos producción de limón en los primeros meses del año, la afectación por las lluvias ya que los productores de los pricipales estados reportan lluvias, lo que tiene repercusiones en la floración y caida de los frutos.El retraso en la maduración ha provocado que se postergue la disponibilidad del producto y por ultimo las lluvias tardias generan entre otros efectos, la plaga conocida como antracnosis, la cual reduce temporalmente el rendimiento de la producción.

El grafico quantil-quantil nos da una referencia con respecto a la normalidad de nuestra serie; se observa una alta relación de los quantiles de los datos reales con los calculados. Por ultimo en la primer gráfica se observa que los residuos casi se ajustan al parametro.

Prueba Shapiro-Wilk

shapiro.test(rstudent(limones.lm))

    Shapiro-Wilk normality test

data:  rstudent(limones.lm)
W = 0.93868, p-value = 0.001626

En este caso el valo “p” < 0.5 por lo que podemos rechazar que ña distribuión sea de tipo normal.

Correlograma

autoplot(acf(rstudent(limones.lm),plot=F))

Se observa que las lineas horizontales representan los errores estandar las cuales se ven rebasadas notoriamente por los rezagos del modelo

En caso de estacionalidad de la serie de tiempo, aplicar diferencias estacionales.

Presentar gráfica.

ggtsdisplay(diff(limones,12),main="diferencia estacional")

ggtsdisplay(diff(diff(limones,12),main="Segunda Diferencia Estacional"))

difestacional<-(diff(diff(limones,12)))
Comprobamos que al aplicar una segunda diferencia estacional la serie se comporta de manera mas estable y los residuos permanecen dentro de la banda.

Usar prueba Dickey-Fuller para evaluar el orden de integración de la serie. Diferenciar hasta que la serie sea estacionaria.

Ho: Existe raíz unitaria Ha: No existe raíz unitaria

summary(ur.df(limones,type="trend",selectlags="AIC"))

############################################### 
# 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 
-1708080  -160783    99130   313299   680866 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  3.612e+05  1.556e+05   2.322 0.023335 *  
z.lag.1     -4.271e-01  1.050e-01  -4.068 0.000129 ***
tt           2.398e+03  3.113e+03   0.770 0.443771    
z.diff.lag   1.998e-01  1.224e-01   1.633 0.107267    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 521300 on 66 degrees of freedom
Multiple R-squared:  0.2012,    Adjusted R-squared:  0.1648 
F-statistic:  5.54 on 3 and 66 DF,  p-value: 0.001875


Value of test-statistic is: -4.0676 5.6098 8.2969 

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
summary(ur.df(limones,type="none",selectlags="AIC"))

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

Test regression none 


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

Residuals:
     Min       1Q   Median       3Q      Max 
-1914018   167553   274264   323151   674992 

Coefficients:
           Estimate Std. Error t value Pr(>|t|)
z.lag.1    -0.09093    0.05891  -1.543    0.127
z.diff.lag  0.03964    0.12436   0.319    0.751

Residual standard error: 565500 on 68 degrees of freedom
Multiple R-squared:  0.03406,   Adjusted R-squared:  0.005648 
F-statistic: 1.199 on 2 and 68 DF,  p-value: 0.3078


Value of test-statistic is: -1.5434 

Critical values for test statistics: 
     1pct  5pct 10pct
tau1 -2.6 -1.95 -1.61
adf.test(limones)
p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  limones
Dickey-Fuller = -5.3103, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary
adf.test(difestacional)
p-value smaller than printed p-value

    Augmented Dickey-Fuller Test

data:  difestacional
Dickey-Fuller = -4.6259, Lag order = 3, p-value = 0.01
alternative hypothesis: stationary

El valor de P=0.01 en ambos casos, tanto en la serie original como en la diferenciada, por lo que se rechaza la hipotesis nula, por lo tanto no existe raíz unitaria en ambos modelos lo que indica que nuestra serie es completamente estacionaria.

Usar herramientas ACF,PACF,EACF y/o criterios de Akaike/Bayes para construir propuestas de modelos.

acf(difestacional) 

pacf(difestacional)

eacf(difestacional)
AR/MA
  0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 x o o o o o o o o o o  o  o  o 
1 x o o o o o o o o o o  o  o  o 
2 x x o o o o o o o o o  o  o  o 
3 x o o o o o o o o o o  o  o  o 
4 x o o o o o o o o o o  o  o  o 
5 x o o o o o o o o o o  o  o  o 
6 o x o o x o o o o o o  o  x  o 
7 x o o o x o o o o o o  o  x  o 
De tal modo que proponemos tres modelos Arima
Ajuste1<-arima(difestacional,order=c(1,0,0))
checkresiduals(Ajuste1)

    Ljung-Box test

data:  Residuals from ARIMA(1,0,0) with non-zero mean
Q* = 14.568, df = 22, p-value = 0.8801

Model df: 2.   Total lags used: 24

Ajuste2<-arima(difestacional,order=c(0,0,1))
checkresiduals(Ajuste2)

    Ljung-Box test

data:  Residuals from ARIMA(0,0,1) with non-zero mean
Q* = 16.233, df = 22, p-value = 0.8042

Model df: 2.   Total lags used: 24

Ajuste3 <-arima(difestacional,order=c(1,1,1))
checkresiduals(Ajuste3)

    Ljung-Box test

data:  Residuals from ARIMA(1,1,1)
Q* = 13.948, df = 22, p-value = 0.9033

Model df: 2.   Total lags used: 24

Usar la función auto.arima y compare sus resultados con el inciso anterior

auto<-auto.arima(difestacional,stepwise = F,approximation = F)
auto
Series: difestacional 
ARIMA(1,0,1) with zero mean 

Coefficients:
         ar1      ma1
      0.5528  -0.9621
s.e.  0.1257   0.0662

sigma^2 estimated as 4.191e+09:  log likelihood=-737.03
AIC=1480.05   AICc=1480.49   BIC=1486.28
checkresiduals(auto)

    Ljung-Box test

data:  Residuals from ARIMA(1,0,1) with zero mean
Q* = 11.794, df = 22, p-value = 0.9615

Model df: 2.   Total lags used: 24

Se observa un ligero pero significativo movimiento en el estadistico Q. Mientras que los valores de p solo muestran una pegueña variabilidad, pero se observa que existen valores mas pequeños que en el modelo auto.arima aunque mayores en el estadistico Q.

Presenta la ecuación final y describa

Ajuste1<-arima(difestacional,order=c(1,0,0))
Ajuste1

Call:
arima(x = difestacional, order = c(1, 0, 0))

Coefficients:
          ar1  intercept
      -0.2649   2723.892
s.e.   0.1253   7054.358

sigma^2 estimated as 4.664e+09:  log likelihood = -740.51,  aic = 1485.03
checkresiduals(Ajuste1)

    Ljung-Box test

data:  Residuals from ARIMA(1,0,0) with non-zero mean
Q* = 14.568, df = 22, p-value = 0.8801

Model df: 2.   Total lags used: 24

Ajuste2<-arima(difestacional,order=c(0,0,1))
Ajuste2

Call:
arima(x = difestacional, order = c(0, 0, 1))

Coefficients:
          ma1  intercept
      -0.3770   2344.605
s.e.   0.1658   5539.689

sigma^2 estimated as 4.562e+09:  log likelihood = -739.91,  aic = 1483.81
checkresiduals(Ajuste2)

    Ljung-Box test

data:  Residuals from ARIMA(0,0,1) with non-zero mean
Q* = 16.233, df = 22, p-value = 0.8042

Model df: 2.   Total lags used: 24

Presenta la ecuación final y describa

Ajuste4<-arima(difestacional,order=c(1,0,1))
Ajuste4

Call:
arima(x = difestacional, order = c(1, 0, 1))

Coefficients:
         ar1      ma1  intercept
      0.5246  -0.9998  1452.7242
s.e.  0.1148   0.0483   917.9811

sigma^2 estimated as 3.806e+09:  log likelihood = -735.96,  aic = 1477.91
checkresiduals(Ajuste4)

    Ljung-Box test

data:  Residuals from ARIMA(1,0,1) with non-zero mean
Q* = 12.944, df = 21, p-value = 0.9106

Model df: 3.   Total lags used: 24

Al aplicar la función de auto.arima no pronostica el mejor modelo para la serie, se observa que el modelo sugerido por autoarima resulta ser mejor que los propouestos(Ajuste1, Ajuste2, Ajuste3),dado que el ACI es aun mas bajo, lo cual es mejor, por lo tanto ningun resago se sale de las bandas de los errores estandar, asi como los remanentes de los rezagos se encuentran dentro del parámetro, la prueba lJung Box nos indica que no hya correlación serial.Por lo tanto el mejor modelo es el auto arima.

Realizar el Pronóstico ARIMA para dos años

fit4<-Arima(limones,order=c(1,0,1))
fit4
Series: limones 
ARIMA(1,0,1) with non-zero mean 

Coefficients:
         ar1     ma1       mean
      0.5622  0.1907  1008492.8
s.e.  0.1375  0.1456   160935.6

sigma^2 estimated as 2.734e+11:  log likelihood=-1048.98
AIC=2105.96   AICc=2106.55   BIC=2115.06
autoplot(forecast(fit4))

Utilizando métodos de pronósticos simples y/o suavizamiento exponencial generar un pronóstico para dos años. Elegir el método que presente la raíz del error medio al cuadrado más pequeño.

limonW<-window(limones,start=c(2010,1),end=c(2015,12))
autoplot(limonW)

Luego de haber realizado el recorte de nuestra serie, procedemos a realizar el pronostico para los dos años siguientes mediante el uso de los metodos ya anteriormente mencionados.

autoplot(limonW) + 
  forecast::autolayer(meanf(limonW, h=24), PI=FALSE, series="Mean") + 
  forecast::autolayer(naive(limonW, h=24), PI=FALSE, series="Naïve") + 
  forecast::autolayer(snaive(limonW, h=24), PI=FALSE, series="Seasonal naïve") + 
  ggtitle("Pronostico de Producción de Limones") + 
  xlab("Año") + ylab("Producción de Limones") + 
  guides(colour=guide_legend(title="Tipo de Pronostico"))

Dado que la serie de producción de limones es completamente estacional y comparando el pronostico de los dos años, se concluye que el metodo de naive estacional presenta un comportamiento mas logico y razonable para los siguientes años.

Analizar un VAR, necesita incluir los puntos siguientes

a) Buscar otra variable (incluso más variables) y redactar la teoría que se encuentra detrás de la relación entre variables que propone.

El limón es uno de los citricos mas importante para la economía de México ya que se usa en hogares e industrias de alimentos. Recordando la ley de la oferta la cual nos indica que la oferta es directamente proporcional al precio (cuanto mas alto sea el precio del producto mas unidades se ofreceran a la venta) y por el contrario la ley de la demanda indica que la demanda es ivnersamente proporcional al precio (cuanto mas alto sea el precio, menos demandaran los consumidores).
Por lo tanto se reconoce que el precio esta directamente relacionado con la producción, cabe mencionar que existen fatores que intervienen en el precio de los citricos como por ejemplo la estacionalidad ya que cada año se da una ventana natural de menos producción de limón en los primeros meses del año, la afectación por las lluvias ya que los productores de los pricipales estados reportan lluvias, lo que tiene repercusiones en la floración y caida de los frutos.El retraso en la maduración ha provocado que se postergue la disponibilidad del producto y por ultimo las lluvias tardias generan entre otros efectos, la plaga conocida como antracnosis, la cual reduce temporalmente el rendimiento de la producción y como consecuencia existe un aumento en los precios del producto.

b) Evaluar la estacionalidad de la nueva variable.

autoplot(Preciolimon)

logprecio<-(log(Preciolimon))
difprecio<-(diff(log(Preciolimon,12)))
diffprecio<- (diff(diff(log(Preciolimon,12))))
autoplot(difprecio)

autoplot(diffprecio)

Se observa que el indice de precios por si solos tiene tendencia y muestra quiza un pcoo de estacionalidad pero encontramos que la varianza no es estable, por lo tanto se aplico do diferencias para estabilizar la serie.

Proponga el orden de Rezagos optimos para el VAR y presentar la estimación.

library(zoo)

Attaching package: <U+393C><U+3E31>zoo<U+393C><U+3E32>

The following objects are masked from <U+393C><U+3E31>package:base<U+393C><U+3E32>:

    as.Date, as.Date.numeric
library(vars)
Loading required package: MASS

Attaching package: <U+393C><U+3E31>MASS<U+393C><U+3E32>

The following objects are masked from <U+393C><U+3E31>package:fma<U+393C><U+3E32>:

    cement, housing, petrol

Loading required package: strucchange
Loading required package: sandwich
Loading required package: lmtest
library(dynlm)
library(lmtest)
limones2<- cbind.zoo(limones = difestacional, Precio = diffprecio) 
View(limones2)
autoplot(limones2[,1:2],facet=TRUE)

VARselect(limones2, lag.max = 2, type="const")[["selection"]]
Error in VARselect(limones2, lag.max = 2, type = "const") : 
NAs in y.

Evaluar la cointengración usando la metodología de Engle-Granger y Johansen

par(mfrow=c(1,2))
plot(limones, main="Producción de Limones")
plot(Preciolimon,main="Precio General")

ur.df(limones)

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

The value of the test statistic is: -1.5434 
ur.df(Preciolimon)

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

The value of the test statistic is: 1.1175 
Ho:La serie no es estacionaria
Según la prueba de cointegración, indica que el término del error es mayor a los criticos (y1=-1, y2=1) por lo tanto no son estacionarias
lp.reg <- dynlm(Preciolimon ~ L(Preciolimon) + limones + L(limones))
summary(lp.reg)

Time series regression with "ts" data:
Start = 2010(2), End = 2015(12)

Call:
dynlm(formula = Preciolimon ~ L(Preciolimon) + limones + L(limones))

Residuals:
     Min       1Q   Median       3Q      Max 
-15.2849  -3.2170  -0.4302   2.1711  19.4172 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)     1.599e+01  6.406e+00   2.496  0.01501 *  
L(Preciolimon)  8.754e-01  5.702e-02  15.354  < 2e-16 ***
limones         4.151e-06  1.540e-06   2.695  0.00889 ** 
L(limones)     -5.031e-06  1.567e-06  -3.210  0.00204 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.628 on 67 degrees of freedom
Multiple R-squared:  0.7982,    Adjusted R-squared:  0.7892 
F-statistic: 88.36 on 3 and 67 DF,  p-value: < 2.2e-16
dwtest(lp.reg)

    Durbin-Watson test

data:  lp.reg
DW = 2.7365, p-value = 0.9987
alternative hypothesis: true autocorrelation is greater than 0
Se observa que el valor p resulta ser significativo p>0.5 por lo tanto se rechaza la Ho aceptando la alterna por lo que las variables tienen verdadera autocorrelación entre ellas.
error <- residuals(lp.reg)
plot(error)
abline(h=0)

ur.df(error)

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

The value of the test statistic is: -7.862 
Ho:La serie no es estacionaria
Según la prueba de cointegración, indica que el término del error es mayor a los criticos p=-7.86 por lo tanto existe una relacion de cointegración.
limones3 <- ts.intersect(limones,Preciolimon, error)
dyn <- dynlm(d(Preciolimon) ~ L(error) + L(d(limones)) + L(d(Preciolimon)), data=data)
summary(dyn)

Time series regression with "zooreg" data:
Start = mar. 2010, End = dic. 2015

Call:
dynlm(formula = d(Preciolimon) ~ L(error) + L(d(limones)) + L(d(Preciolimon)), 
    data = data)

Residuals:
     Min       1Q   Median       3Q      Max 
-19.4016  -3.5103  -0.4213   3.3281  13.5639 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)  
(Intercept)        4.782e-01  8.191e-01   0.584   0.5613  
L(error)          -9.723e-01  4.087e-01  -2.379   0.0203 *
L(d(limones))     -2.955e-06  2.282e-06  -1.295   0.1999  
L(d(Preciolimon))  4.366e-01  3.939e-01   1.108   0.2717  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.499 on 66 degrees of freedom
Multiple R-squared:  0.2484,    Adjusted R-squared:  0.2142 
F-statistic: 7.269 on 3 and 66 DF,  p-value: 0.0002759
LS0tDQp0aXRsZTogIlByb2R1Y2Np824gZGUgTGltb25lcyINCmF1dGhvcjogIkZ1ZW50ZXMgUmFtaXJleiBWZXJvbmljYSB5IFJleWVzIERpYXogU3VzYW5hIEJlYXRyaXoiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCg0KLS0tDQoNCmBgYHtyfQ0KbGlicmFyeShnZ2ZvcnRpZnkpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeShmcHAyKQ0KbGlicmFyeShncmlkRXh0cmEpDQpsaWJyYXJ5KHNlYXNvbmFsKQ0KbGlicmFyeShUU0EpDQpsaWJyYXJ5KHVyY2EpDQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KI0JyZXZlIHJlZmVyZW5jaWEgYSBsb3MgZGF0b3MsIGZyZWN1ZW5jaWEsIHVuaWRhZCBkZSBtZWRpZGEsIGZ1ZW50ZSwgZXRjLg0KDQojIyMjI0xhIHNlcmllIHJlcHJlc2VudGEgbGEgcHJvZHVjY2nzbiBkZSBsaW1vbmVzIGNvbiB1bmEgZnJlY3VlbmNpYSBtZW5zdWFsLCBsYSB1bmlkYWQgZGUgbWVkaWRhIGVzIGVuIHRvbmVsYWRhcyB5IGxvcyBkYXRvcyByZWNvcGlsYWRvcyBmdWVyb24gb2J0ZW5pZG9zIGRlIGxhIHDhZ2luYSBkZSBJTkVHSSBkZWwgYfFvIDIwMTAgYWwgMjAxNiAo+mx0aW1hIGFjdHVhbGl6YWNp824pLg0KaHR0cDovL3d3dy5pbmVnaS5vcmcubXgvIA0KDQojR3JhZmljYXIgbG9zIGRhdG9zLCBhbmFsaXphciBwYXRyb25lcyB5IG9ic2VydmFjaW9uZXMgYXTtcGljYXMuIEFwb3llIHN1IGFu4Wxpc2lzIGNvbiB1bmEgZGVzY29tcG9zaWNp824gY2zhc2ljYS4NCg0KYGBge3J9DQpiYXNlPC1yZWFkLmNzdihmaWxlLmNob29zZSgibGltb25lcy5jc3YiKSkNCmxpbW9uZXM8LXRzKGJhc2UkbGltb25lcyxzdGFydCA9IGMoMjAxMCwxKSxmcmVxdWVuY3k9MTIpDQpQcmVjaW9saW1vbjwtdHMoYmFzZSRQcmVjaW8sc3RhcnQgPSBjKDIwMTAsMSksZnJlcXVlbmN5PTEyKQ0KYGBgDQoNCmBgYHtyfQ0KVmlldyhiYXNlKQ0KYGBgDQoNCg0KYGBge3J9DQpwbDwtcGxvdChsaW1vbmVzLHhsYWI9InBlcmlvZG8iLG1haW49IlByb2R1Y2Np824gZGUgTGltb25lcyIpDQpgYGANCiMjIyMjT2JzZXJ2YW1vcyBxdWUgbGEgc2VyaWUgcHJlc2VudGEgZXN0YWNpb25hbGlkYWQsIHkgZXMgY29tcGxldGFtZW50ZSBj7WNsaWNhLiBMb3MgY29tcG9ydGFtaWVudG9zIGRlIGxhIHByb2R1Y2Np824gZGUgbGlt824gc29uIGRlIG1hbmVyYSBhdO1waWNhIHF1ZSBzZSBkZWJlIGEgZGl2ZXJzb3MgZmFjdG9yZXMsIGVsIGNvbXBvcnRhbWllbnRvIGVuIHVuIGHxbyBkZSBsYSBwcm9kdWNjafNuIGR1cmFudGUgbG9zIHByaW1lcm9zIG1lc2VzIHNlIG9ic2VydmEgZW4gbG9zIGN1bHRpdm9zIHlhIHF1ZSBzZSBwcmVwYXJhbiBwYXJhIHF1ZSBwb3N0ZXJpb3JtZW50ZSBsb3MgYXJib2xlcyBkZW4gZnJ1dG8sIHBvciBsbyBxdWUgZHVyYW50ZSBsb3MgcHJpbWVyb3MgbWVzZXMgbGEgcHJvZHVjY2nzbiwgZXMgbGEgbWFzIGJhamEgZGVsIGHxbzsgb3RybyBkZSBsb3MgZmFjdG9yZXMgZGVsIGVzdGlhamUgZGUgbGEgcHJvZHVjY2nzbiwgZXMgcXVlIGVsIGPtdHJpY28gbm8gc2UgZGVzYXJyb2xsZSBjb24gZXhjZWxlbmNpYSB5IGxvcyBmcnV0b3Mgbm8gZGVuIGp1Z28gYXVuYWRvIGNvbiBsb3MgcHJvYmxlbWFzIGNhZGEgdmV6IG1hcyBwcmVzZW50ZXMgZGUgbG9zIGNhbWJpb3MgZGUgdGVtcGVyYXR1cmEsIHF1ZSBhZmVjdGFuIGxhcyBjb3NlY2hhcyB5IGNvbiBlbGxvIGRpcmVjdGFtZW50ZSBlbiBlbCBwcmVjaW8gZGVsIHByb2R1Y3RvIHkgYWwgc2VjdG9yIGFsaW1lbnRhcmlvLg0KDQoNCiMjIyNEZXNjb21wb3NpY2nzbiBDbGFzaWNhDQpgYGB7cn0NCmxpbW9uZGVzYzwtIGRlY29tcG9zZShsaW1vbmVzLCB0eXBlPSdhZGRpdGl2ZScpDQphdXRvcGxvdChsaW1vbmRlc2MpDQpgYGANCg0KIyMjI1NlIHJlYWxpevMgbGEgZGVzY29tcG9zaWNp824gY2xhc2ljYSBwYXJhIG9ic2VydmFyIGxvcyBjb21wb25lbnRlcyBkZSBsYSBzZXJpZSAoZXN0YWNpb25hbGlkYWQsdGVuZGVuY2lhIHkgY2ljbG8pIHBvciBzZXBhcmFkbyANCg0KDQoNCiNVdGlsaXphciB0cmFuc2Zvcm1hY2nzbiBCb3gtQ294IC8gbG9nYXJpdG1vcyBwYXJhIGVzdGFiaWxpemFyIGxhIHZhcmlhbnphLg0KI1ByZXNlbnRhciBncmFmaWNhLg0KYGBge3J9DQpCb3hDb3guYXIobGltb25lcykNCmBgYA0KDQoNCiMjIyMjRW4gZWwgY2FzbyBkZSBlc3RhIHNlcmllIG5vIGVzIG5lY2VzYXJpbyBhcGxpY2FyIGxvZ2FyaXRtb3MgZGViaWRvIGEgcXVlIGxhIHNlcmllIG11ZXN0cmEgdW5pY2FtZW50ZSB1biBjb21wb3J0YW1pZW50byBlc3RhY2lvbmFsLg0KDQojTW9kZWxhciBsYSBzZXJpZSBkZSB0aWVtcG8gZWxlZ2lkYSBjb21vIGZ1bmNp824gZGUgdW5hIHRlbmRlbmNpYSwgdGVuZGVuY2lhIGN1YWRyYXRpY2EgeS9vIG1lZGlhcyBlc3RjaW9uYWxlcy5QcmVzZW50YSBlbCBEaWFnbm9zdGljbyBkZWwgbW9kZWxvIGVsZWdpZG8uDQoNCiMjIyNVc2FuZG8gbGEgc2VyaWUgZWxlZ2lkYSBjb21vIHZhcmlhYmxlIGRlcGVuZGllbnRlIHkgZWwgdGllbXBvIGNvbW8gaW5kZXBlbmRpZW50ZS4NCmBgYHtyfQ0KbGltb25lcy5sbTwtbG0obGltb25lcyB+IHRpbWUobGltb25lcykpDQpzdW1tYXJ5KGxpbW9uZXMubG0pDQpgYGANCg0KIyMjI0dyYWZpY2Ftb3MgDQpgYGB7cn0NCmdncGxvdChsaW1vbmVzLCBhZXMoeT1saW1vbmVzLCB4PXRpbWUobGltb25lcykpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpDQpgYGANCiMjIyMjT2JzZXJ2YW1vcyBxdWUgbG9zIHJlc2lkdW9zIHRpZW5kZW4gYSBhbGVqYXJzZSBkZWwgY29tcG9uZW50ZSBkZSByZWZlcmVuY2lhIGxvIHF1ZSBkZXRlcm1pbmEgcXVlIGVsIG1vZGVsbyBubyBlcyBlbCBpbmRpY2FkbywgcHVlZGUgZGViZXJzZSBlc3RlIGNvbXBvcnRhbWllbnRvIGRlIGxvcyByZXNpZHVvcyBhIHF1ZSBkdXJhbnRlIGxvcyBwcmltZXJvcyBtZXNlcyBkZWwgYfFvIGxhIHByb2R1Y2Np824gZXMgY2FzaSBudWxhDQoNCiMjIyNFdmFsdWFjafNuIGRlbCBNb2RlbG8NCmBgYHtyfQ0KYXV0b3Bsb3QobGltb25lcy5sbSwgd2hpY2ggPSAxOjYsIG5jb2wgPSAyLCBsYWJlbC5zaXplID0gMykNCmBgYA0KIyMjIyNMYSBkaXN0YW5jaWEgZGUgY29vayByZXByZXNlbnRhIGV2ZW50b3Mgbm8gY29udHJvbGFkb3MsIHRhbGVzIGNvbW8gbGEgZXN0YWNpb25hbGlkYWQgeWEgcXVlIGNhZGEgYfFvIHNlIGRhIHVuYSB2ZW50YW5hIG5hdHVyYWwgZGUgbWVub3MgcHJvZHVjY2nzbiBkZSBsaW3zbiBlbiBsb3MgcHJpbWVyb3MgbWVzZXMgZGVsIGHxbywgbGEgYWZlY3RhY2nzbiBwb3IgbGFzIGxsdXZpYXMgeWEgcXVlIGxvcyBwcm9kdWN0b3JlcyBkZSBsb3MgcHJpY2lwYWxlcyBlc3RhZG9zIHJlcG9ydGFuIGxsdXZpYXMsIGxvIHF1ZSB0aWVuZSByZXBlcmN1c2lvbmVzIGVuIGxhIGZsb3JhY2nzbiB5IGNhaWRhIGRlIGxvcyBmcnV0b3MuRWwgcmV0cmFzbyBlbiBsYSBtYWR1cmFjafNuIGhhIHByb3ZvY2FkbyBxdWUgc2UgcG9zdGVyZ3VlIGxhIGRpc3BvbmliaWxpZGFkIGRlbCBwcm9kdWN0byB5IHBvciB1bHRpbW8gbGFzIGxsdXZpYXMgdGFyZGlhcyBnZW5lcmFuIGVudHJlIG90cm9zIGVmZWN0b3MsIGxhIHBsYWdhIGNvbm9jaWRhIGNvbW8gYW50cmFjbm9zaXMsIGxhIGN1YWwgcmVkdWNlIHRlbXBvcmFsbWVudGUgZWwgcmVuZGltaWVudG8gZGUgbGEgcHJvZHVjY2nzbi4NCiMjIyNFbCBncmFmaWNvIHF1YW50aWwtcXVhbnRpbCBub3MgZGEgdW5hIHJlZmVyZW5jaWEgY29uIHJlc3BlY3RvIGEgbGEgbm9ybWFsaWRhZCBkZSBudWVzdHJhIHNlcmllOyBzZSBvYnNlcnZhIHVuYSBhbHRhIHJlbGFjafNuIGRlIGxvcyBxdWFudGlsZXMgZGUgbG9zIGRhdG9zIHJlYWxlcyBjb24gbG9zIGNhbGN1bGFkb3MuIFBvciB1bHRpbW8gZW4gbGEgcHJpbWVyIGdy4WZpY2Egc2Ugb2JzZXJ2YSBxdWUgbG9zIHJlc2lkdW9zIGNhc2kgc2UgYWp1c3RhbiBhbCBwYXJhbWV0cm8uDQoNCiNQcnVlYmEgU2hhcGlyby1XaWxrDQpgYGB7cn0NCnNoYXBpcm8udGVzdChyc3R1ZGVudChsaW1vbmVzLmxtKSkNCmBgYA0KIyMjI0VuIGVzdGUgY2FzbyBlbCB2YWxvICJwIiA8IDAuNSBwb3IgbG8gcXVlIHBvZGVtb3MgcmVjaGF6YXIgcXVlIPFhIGRpc3RyaWJ1afNuIHNlYSBkZSB0aXBvIG5vcm1hbC4NCg0KI0NvcnJlbG9ncmFtYQ0KYGBge3J9DQphdXRvcGxvdChhY2YocnN0dWRlbnQobGltb25lcy5sbSkscGxvdD1GKSkNCmBgYA0KIyMjI1NlIG9ic2VydmEgcXVlIGxhcyBsaW5lYXMgaG9yaXpvbnRhbGVzIHJlcHJlc2VudGFuIGxvcyBlcnJvcmVzIGVzdGFuZGFyIGxhcyBjdWFsZXMgc2UgdmVuIHJlYmFzYWRhcyBub3RvcmlhbWVudGUgcG9yIGxvcyByZXphZ29zIGRlbCBtb2RlbG8NCg0KIyNFbiBjYXNvIGRlIGVzdGFjaW9uYWxpZGFkIGRlIGxhIHNlcmllIGRlIHRpZW1wbywgYXBsaWNhciBkaWZlcmVuY2lhcyBlc3RhY2lvbmFsZXMuDQojI1ByZXNlbnRhciBncuFmaWNhLg0KDQpgYGB7cn0NCmdndHNkaXNwbGF5KGRpZmYobGltb25lcywxMiksbWFpbj0iZGlmZXJlbmNpYSBlc3RhY2lvbmFsIikNCmBgYA0KYGBge3J9DQpnZ3RzZGlzcGxheShkaWZmKGRpZmYobGltb25lcywxMiksbWFpbj0iU2VndW5kYSBEaWZlcmVuY2lhIEVzdGFjaW9uYWwiKSkNCmRpZmVzdGFjaW9uYWw8LShkaWZmKGRpZmYobGltb25lcywxMikpKQ0KYGBgDQojIyMjI0NvbXByb2JhbW9zIHF1ZSBhbCBhcGxpY2FyIHVuYSBzZWd1bmRhIGRpZmVyZW5jaWEgZXN0YWNpb25hbCBsYSBzZXJpZSBzZSBjb21wb3J0YSBkZSBtYW5lcmEgbWFzIGVzdGFibGUgeSBsb3MgcmVzaWR1b3MgcGVybWFuZWNlbiBkZW50cm8gZGUgbGEgYmFuZGEuDQoNCiNVc2FyIHBydWViYSBEaWNrZXktRnVsbGVyIHBhcmEgZXZhbHVhciBlbCBvcmRlbiBkZSBpbnRlZ3JhY2nzbiBkZSBsYSBzZXJpZS4gRGlmZXJlbmNpYXIgaGFzdGEgcXVlIGxhIHNlcmllIHNlYSBlc3RhY2lvbmFyaWEuDQoNCkhvOiBFeGlzdGUgcmHteiB1bml0YXJpYQ0KSGE6IE5vIGV4aXN0ZSByYe16IHVuaXRhcmlhIA0KDQpgYGB7cn0NCnN1bW1hcnkodXIuZGYobGltb25lcyx0eXBlPSJ0cmVuZCIsc2VsZWN0bGFncz0iQUlDIikpDQpzdW1tYXJ5KHVyLmRmKGxpbW9uZXMsdHlwZT0ibm9uZSIsc2VsZWN0bGFncz0iQUlDIikpDQoNCmFkZi50ZXN0KGxpbW9uZXMpDQphZGYudGVzdChkaWZlc3RhY2lvbmFsKQ0KYGBgDQoNCiMjIyMgRWwgdmFsb3IgZGUgUD0wLjAxIGVuIGFtYm9zIGNhc29zLCB0YW50byBlbiBsYSBzZXJpZSBvcmlnaW5hbCBjb21vIGVuIGxhIGRpZmVyZW5jaWFkYSwgcG9yIGxvIHF1ZSBzZSByZWNoYXphIGxhIGhpcG90ZXNpcyBudWxhLCBwb3IgbG8gdGFudG8gbm8gZXhpc3RlIHJh7XogdW5pdGFyaWEgZW4gYW1ib3MgbW9kZWxvcyBsbyBxdWUgaW5kaWNhIHF1ZSBudWVzdHJhIHNlcmllIGVzIGNvbXBsZXRhbWVudGUgZXN0YWNpb25hcmlhLg0KDQoNCiNVc2FyIGhlcnJhbWllbnRhcyBBQ0YsUEFDRixFQUNGIHkvbyBjcml0ZXJpb3MgZGUgQWthaWtlL0JheWVzIHBhcmEgY29uc3RydWlyIHByb3B1ZXN0YXMgZGUgbW9kZWxvcy4NCg0KYGBge3J9DQphY2YoZGlmZXN0YWNpb25hbCkgDQpwYWNmKGRpZmVzdGFjaW9uYWwpDQplYWNmKGRpZmVzdGFjaW9uYWwpDQpgYGANCg0KIyMjIyNEZSB0YWwgbW9kbyBxdWUgcHJvcG9uZW1vcyB0cmVzIG1vZGVsb3MgQXJpbWEgDQoNCg0KYGBge3J9DQpBanVzdGUxPC1hcmltYShkaWZlc3RhY2lvbmFsLG9yZGVyPWMoMSwwLDApKQ0KY2hlY2tyZXNpZHVhbHMoQWp1c3RlMSkNCg0KQWp1c3RlMjwtYXJpbWEoZGlmZXN0YWNpb25hbCxvcmRlcj1jKDAsMCwxKSkNCmNoZWNrcmVzaWR1YWxzKEFqdXN0ZTIpDQoNCkFqdXN0ZTMgPC1hcmltYShkaWZlc3RhY2lvbmFsLG9yZGVyPWMoMSwxLDEpKQ0KY2hlY2tyZXNpZHVhbHMoQWp1c3RlMykNCmBgYA0KI1VzYXIgbGEgZnVuY2nzbiBhdXRvLmFyaW1hIHkgY29tcGFyZSBzdXMgcmVzdWx0YWRvcyBjb24gZWwgaW5jaXNvIGFudGVyaW9yIA0KDQpgYGB7cn0NCmF1dG88LWF1dG8uYXJpbWEoZGlmZXN0YWNpb25hbCxzdGVwd2lzZSA9IEYsYXBwcm94aW1hdGlvbiA9IEYpDQphdXRvDQpjaGVja3Jlc2lkdWFscyhhdXRvKQ0KYGBgDQojIyMjI1NlIG9ic2VydmEgdW4gbGlnZXJvIHBlcm8gc2lnbmlmaWNhdGl2byBtb3ZpbWllbnRvIGVuIGVsIGVzdGFkaXN0aWNvIFEuIE1pZW50cmFzIHF1ZSBsb3MgdmFsb3JlcyBkZSBwIHNvbG8gbXVlc3RyYW4gdW5hIHBlZ3Vl8WEgdmFyaWFiaWxpZGFkLCBwZXJvIHNlIG9ic2VydmEgcXVlIGV4aXN0ZW4gdmFsb3JlcyBtYXMgcGVxdWXxb3MgcXVlIGVuIGVsIG1vZGVsbyBhdXRvLmFyaW1hIGF1bnF1ZSBtYXlvcmVzIGVuIGVsIGVzdGFkaXN0aWNvIFEuDQoNCiNQcmVzZW50YSBsYSBlY3VhY2nzbiBmaW5hbCB5IGRlc2NyaWJhDQoNCmBgYHtyfQ0KQWp1c3RlMTwtYXJpbWEoZGlmZXN0YWNpb25hbCxvcmRlcj1jKDEsMCwwKSkNCkFqdXN0ZTENCmNoZWNrcmVzaWR1YWxzKEFqdXN0ZTEpDQpgYGANCg0KYGBge3J9DQpBanVzdGUyPC1hcmltYShkaWZlc3RhY2lvbmFsLG9yZGVyPWMoMCwwLDEpKQ0KQWp1c3RlMg0KY2hlY2tyZXNpZHVhbHMoQWp1c3RlMikNCmBgYA0KI1ByZXNlbnRhIGxhIGVjdWFjafNuIGZpbmFsIHkgZGVzY3JpYmENCg0KYGBge3J9DQpBanVzdGU0PC1hcmltYShkaWZlc3RhY2lvbmFsLG9yZGVyPWMoMSwwLDEpKQ0KQWp1c3RlNA0KY2hlY2tyZXNpZHVhbHMoQWp1c3RlNCkNCmBgYA0KIyMjIyNBbCBhcGxpY2FyIGxhIGZ1bmNp824gZGUgYXV0by5hcmltYSBubyBwcm9ub3N0aWNhIGVsIG1lam9yIG1vZGVsbyBwYXJhIGxhIHNlcmllLCBzZSBvYnNlcnZhIHF1ZSBlbCBtb2RlbG8gc3VnZXJpZG8gcG9yIGF1dG9hcmltYSByZXN1bHRhIHNlciBtZWpvciBxdWUgbG9zIHByb3BvdWVzdG9zKEFqdXN0ZTEsIEFqdXN0ZTIsIEFqdXN0ZTMpLGRhZG8gcXVlIGVsIEFDSSBlcyBhdW4gbWFzIGJham8sIGxvIGN1YWwgZXMgbWVqb3IsIHBvciBsbyB0YW50byBuaW5ndW4gcmVzYWdvIHNlIHNhbGUgZGUgbGFzIGJhbmRhcyBkZSBsb3MgZXJyb3JlcyBlc3RhbmRhciwgYXNpIGNvbW8gbG9zIHJlbWFuZW50ZXMgZGUgbG9zIHJlemFnb3Mgc2UgZW5jdWVudHJhbiBkZW50cm8gZGVsIHBhcuFtZXRybywgbGEgcHJ1ZWJhIGxKdW5nIEJveCBub3MgaW5kaWNhIHF1ZSBubyBoeWEgY29ycmVsYWNp824gc2VyaWFsLlBvciBsbyB0YW50byBlbCBtZWpvciBtb2RlbG8gZXMgZWwgYXV0byBhcmltYS4gDQoNCiNSZWFsaXphciBlbCBQcm9u83N0aWNvIEFSSU1BIHBhcmEgZG9zIGHxb3MgDQpgYGB7cn0NCmdldHJtc2UgPC0gZnVuY3Rpb24oeCxoLC4uLikgDQp7IA0KICB0cmFpbi5lbmQgPC0gdGltZSh4KVtsZW5ndGgoeCktaF0gDQogIHRlc3Quc3RhcnQgPC0gdGltZSh4KVtsZW5ndGgoeCktaCsxXSANCiAgdHJhaW4gPC0gd2luZG93KHgsZW5kPXRyYWluLmVuZCkNCiAgdGVzdCA8LSB3aW5kb3coeCxzdGFydD10ZXN0LnN0YXJ0KQ0KICBmaXQgPC0gQXJpbWEodHJhaW4sLi4uKSANCiAgZmMgPC0gZm9yZWNhc3QoZml0LGg9aCkNCiAgcmV0dXJuKGFjY3VyYWN5KGZjLHRlc3QpWzIsIlJNU0UiXSkgDQp9IA0KDQpnZXRybXNlKGRpZmVzdGFjaW9uYWwsaD0yNCxvcmRlcj1jKDEsMCwwKSkNCmdldHJtc2UoZGlmZXN0YWNpb25hbCxoPTI0LG9yZGVyPWMoMCwwLDEpKQ0KZ2V0cm1zZShkaWZlc3RhY2lvbmFsLGg9MjQsb3JkZXI9YygxLDEsMSkpDQpnZXRybXNlKGRpZmVzdGFjaW9uYWwsaD0yNCxvcmRlcj1jKDEsMCwxKSkNCmdldHJtc2UoZGlmZXN0YWNpb25hbCxoPTI0LG9yZGVyPWMoMiwwLDApKQ0KZ2V0cm1zZShkaWZlc3RhY2lvbmFsLGg9MjQsb3JkZXI9YygwLDAsMikpDQpnZXRybXNlKGRpZmVzdGFjaW9uYWwsaD0yNCxvcmRlcj1jKDIsMSwxKSkNCg0KYGBgDQoNCmBgYHtyfQ0KZml0NDwtQXJpbWEobGltb25lcyxvcmRlcj1jKDEsMCwxKSkNCmZpdDQNCmF1dG9wbG90KGZvcmVjYXN0KGZpdDQpKQ0KYGBgDQoNCiNVdGlsaXphbmRvIG3pdG9kb3MgZGUgcHJvbvNzdGljb3Mgc2ltcGxlcyB5L28gc3Vhdml6YW1pZW50byBleHBvbmVuY2lhbCBnZW5lcmFyIHVuIHByb27zc3RpY28gcGFyYSBkb3MgYfFvcy4gRWxlZ2lyIGVsIG3pdG9kbyBxdWUgcHJlc2VudGUgbGEgcmHteiBkZWwgZXJyb3IgbWVkaW8gYWwgY3VhZHJhZG8gbeFzIHBlcXVl8W8uDQoNCmBgYHtyfQ0KbGltb25XPC13aW5kb3cobGltb25lcyxzdGFydD1jKDIwMTAsMSksZW5kPWMoMjAxNSwxMikpDQphdXRvcGxvdChsaW1vblcpDQpgYGANCg0KI0x1ZWdvIGRlIGhhYmVyIHJlYWxpemFkbyBlbCByZWNvcnRlIGRlIG51ZXN0cmEgc2VyaWUsIHByb2NlZGVtb3MgYSByZWFsaXphciBlbCBwcm9ub3N0aWNvIHBhcmEgbG9zIGRvcyBh8W9zIHNpZ3VpZW50ZXMgbWVkaWFudGUgZWwgdXNvIGRlIGxvcyBtZXRvZG9zIHlhIGFudGVyaW9ybWVudGUgbWVuY2lvbmFkb3MuDQoNCmBgYHtyfQ0KYXV0b3Bsb3QobGltb25XKSArIA0KICBmb3JlY2FzdDo6YXV0b2xheWVyKG1lYW5mKGxpbW9uVywgaD0yNCksIFBJPUZBTFNFLCBzZXJpZXM9Ik1lYW4iKSArIA0KICBmb3JlY2FzdDo6YXV0b2xheWVyKG5haXZlKGxpbW9uVywgaD0yNCksIFBJPUZBTFNFLCBzZXJpZXM9Ik5h73ZlIikgKyANCiAgZm9yZWNhc3Q6OmF1dG9sYXllcihzbmFpdmUobGltb25XLCBoPTI0KSwgUEk9RkFMU0UsIHNlcmllcz0iU2Vhc29uYWwgbmHvdmUiKSArIA0KICBnZ3RpdGxlKCJQcm9ub3N0aWNvIGRlIFByb2R1Y2Np824gZGUgTGltb25lcyIpICsgDQogIHhsYWIoIkHxbyIpICsgeWxhYigiUHJvZHVjY2nzbiBkZSBMaW1vbmVzIikgKyANCiAgZ3VpZGVzKGNvbG91cj1ndWlkZV9sZWdlbmQodGl0bGU9IlRpcG8gZGUgUHJvbm9zdGljbyIpKQ0KYGBgDQoNCiMjIyMjRGFkbyBxdWUgbGEgc2VyaWUgZGUgcHJvZHVjY2nzbiBkZSBsaW1vbmVzIGVzIGNvbXBsZXRhbWVudGUgZXN0YWNpb25hbCB5IGNvbXBhcmFuZG8gZWwgcHJvbm9zdGljbyBkZSBsb3MgZG9zIGHxb3MsIHNlIGNvbmNsdXllIHF1ZSBlbCBtZXRvZG8gZGUgbmFpdmUgZXN0YWNpb25hbCBwcmVzZW50YSB1biBjb21wb3J0YW1pZW50byBtYXMgbG9naWNvIHkgcmF6b25hYmxlIHBhcmEgbG9zIHNpZ3VpZW50ZXMgYfFvcy4NCg0KI0FuYWxpemFyIHVuIFZBUiwgbmVjZXNpdGEgaW5jbHVpciBsb3MgcHVudG9zIHNpZ3VpZW50ZXMNCg0KIyNhKSBCdXNjYXIgb3RyYSB2YXJpYWJsZSAoaW5jbHVzbyBt4XMgdmFyaWFibGVzKSB5IHJlZGFjdGFyIGxhIHRlb3LtYSBxdWUgc2UgZW5jdWVudHJhIGRldHLhcyAgIGRlIGxhIHJlbGFjafNuIGVudHJlIHZhcmlhYmxlcyBxdWUgcHJvcG9uZS4NCg0KIyMjIyNFbCBsaW3zbiBlcyB1bm8gZGUgbG9zIGNpdHJpY29zIG1hcyBpbXBvcnRhbnRlIHBhcmEgbGEgZWNvbm9t7WEgZGUgTel4aWNvIHlhIHF1ZSBzZSB1c2EgZW4gaG9nYXJlcyBlIGluZHVzdHJpYXMgZGUgYWxpbWVudG9zLiBSZWNvcmRhbmRvIGxhIGxleSBkZSBsYSBvZmVydGEgbGEgY3VhbCBub3MgaW5kaWNhIHF1ZSBsYSBvZmVydGEgZXMgZGlyZWN0YW1lbnRlIHByb3BvcmNpb25hbCBhbCBwcmVjaW8gKGN1YW50byBtYXMgYWx0byBzZWEgZWwgcHJlY2lvIGRlbCBwcm9kdWN0byBtYXMgdW5pZGFkZXMgc2Ugb2ZyZWNlcmFuIGEgbGEgdmVudGEpIHkgcG9yIGVsIGNvbnRyYXJpbyBsYSBsZXkgZGUgbGEgZGVtYW5kYSBpbmRpY2EgcXVlIGxhIGRlbWFuZGEgZXMgaXZuZXJzYW1lbnRlIHByb3BvcmNpb25hbCBhbCBwcmVjaW8gKGN1YW50byBtYXMgYWx0byBzZWEgZWwgcHJlY2lvLCBtZW5vcyBkZW1hbmRhcmFuIGxvcyBjb25zdW1pZG9yZXMpLg0KIyMjIyNQb3IgbG8gdGFudG8gc2UgcmVjb25vY2UgcXVlIGVsIHByZWNpbyBlc3RhIGRpcmVjdGFtZW50ZSByZWxhY2lvbmFkbyBjb24gbGEgcHJvZHVjY2nzbiwgY2FiZSBtZW5jaW9uYXIgcXVlIGV4aXN0ZW4gZmF0b3JlcyBxdWUgaW50ZXJ2aWVuZW4gZW4gZWwgcHJlY2lvIGRlIGxvcyBjaXRyaWNvcyBjb21vIHBvciBlamVtcGxvIGxhIGVzdGFjaW9uYWxpZGFkIHlhIHF1ZSBjYWRhIGHxbyBzZSBkYSB1bmEgdmVudGFuYSBuYXR1cmFsIGRlIG1lbm9zIHByb2R1Y2Np824gZGUgbGlt824gZW4gbG9zIHByaW1lcm9zIG1lc2VzIGRlbCBh8W8sIGxhIGFmZWN0YWNp824gcG9yIGxhcyBsbHV2aWFzIHlhIHF1ZSBsb3MgcHJvZHVjdG9yZXMgZGUgbG9zIHByaWNpcGFsZXMgZXN0YWRvcyByZXBvcnRhbiBsbHV2aWFzLCBsbyBxdWUgdGllbmUgcmVwZXJjdXNpb25lcyBlbiBsYSBmbG9yYWNp824geSBjYWlkYSBkZSBsb3MgZnJ1dG9zLkVsIHJldHJhc28gZW4gbGEgbWFkdXJhY2nzbiBoYSBwcm92b2NhZG8gcXVlIHNlIHBvc3Rlcmd1ZSBsYSBkaXNwb25pYmlsaWRhZCBkZWwgcHJvZHVjdG8geSBwb3IgdWx0aW1vIGxhcyBsbHV2aWFzIHRhcmRpYXMgZ2VuZXJhbiBlbnRyZSBvdHJvcyBlZmVjdG9zLCBsYSBwbGFnYSBjb25vY2lkYSBjb21vIGFudHJhY25vc2lzLCBsYSBjdWFsIHJlZHVjZSB0ZW1wb3JhbG1lbnRlIGVsIHJlbmRpbWllbnRvIGRlIGxhIHByb2R1Y2Np824geSBjb21vIGNvbnNlY3VlbmNpYSBleGlzdGUgdW4gYXVtZW50byBlbiBsb3MgcHJlY2lvcyBkZWwgcHJvZHVjdG8uDQoNCiMjYikgRXZhbHVhciBsYSBlc3RhY2lvbmFsaWRhZCBkZSBsYSBudWV2YSB2YXJpYWJsZS4NCg0KYGBge3J9DQphdXRvcGxvdChQcmVjaW9saW1vbikNCmxvZ3ByZWNpbzwtKGxvZyhQcmVjaW9saW1vbikpDQpkaWZwcmVjaW88LShkaWZmKGxvZyhQcmVjaW9saW1vbiwxMikpKQ0KZGlmZnByZWNpbzwtIChkaWZmKGRpZmYobG9nKFByZWNpb2xpbW9uLDEyKSkpKQ0KYXV0b3Bsb3QoZGlmcHJlY2lvKQ0KYXV0b3Bsb3QoZGlmZnByZWNpbykNCmBgYA0KIyMjIyNTZSBvYnNlcnZhIHF1ZSBlbCBpbmRpY2UgZGUgcHJlY2lvcyBwb3Igc2kgc29sb3MgdGllbmUgdGVuZGVuY2lhIHkgbXVlc3RyYSBxdWl6YSB1biBwY29vIGRlIGVzdGFjaW9uYWxpZGFkIHBlcm8gZW5jb250cmFtb3MgcXVlIGxhIHZhcmlhbnphIG5vIGVzIGVzdGFibGUsIHBvciBsbyB0YW50byBzZSBhcGxpY28gZG8gZGlmZXJlbmNpYXMgcGFyYSBlc3RhYmlsaXphciBsYSBzZXJpZS4NCg0KI1Byb3BvbmdhIGVsIG9yZGVuIGRlIFJlemFnb3Mgb3B0aW1vcyBwYXJhIGVsIFZBUiB5IHByZXNlbnRhciBsYSBlc3RpbWFjafNuLg0KDQpgYGB7cn0NCmxpYnJhcnkoem9vKQ0KbGlicmFyeSh2YXJzKQ0KbGlicmFyeShkeW5sbSkNCmxpYnJhcnkobG10ZXN0KQ0KYGBgDQoNCg0KYGBge3J9DQpsaW1vbmVzMjwtIGNiaW5kLnpvbyhsaW1vbmVzID0gZGlmZXN0YWNpb25hbCwgUHJlY2lvID0gZGlmZnByZWNpbykgDQpWaWV3KGxpbW9uZXMyKQ0KYGBgDQoNCmBgYHtyfQ0KYXV0b3Bsb3QobGltb25lczJbLDE6Ml0sZmFjZXQ9VFJVRSkNCmBgYA0KDQoNCmBgYHtyfQ0KVkFSc2VsZWN0KGxpbW9uZXMyLCBsYWcubWF4ID0gOCwgdHlwZT0iY29uc3QiKVtbInNlbGVjdGlvbiJdXQ0KdmFyMTwtVkFSKGxpbW9uZXMyLHA9MSwgdHlwZSA9ICJjb25zdCIpDQpzZXJpYWwudGVzdCh2YXIxLCBsYWdzLnB0PTEwLCB0eXBlPSJQVC5hc3ltcHRvdGljIikNCnZhcjI8LVZBUihsaW1vbmVzMixwPTIsdHlwZSA9ICJjb25zdCIpDQpzZXJpYWwudGVzdCh2YXIyLCBsYWdzLnB0PTEwLCB0eXBlPSJQVC5hc3ltcHRvdGljIikNCnZhcjIuc2VyaWFsPC1zZXJpYWwudGVzdCh2YXIyLCBsYWdzLnB0PTEwLCB0eXBlPSJQVC5hc3ltcHRvdGljIikNCnBsb3QodmFyMi5zZXJpYWwsbmFtZXM9IlByb2R1Y2Np824gZGUgbGltb25lcyIpDQpwbG90KHZhcjIuc2VyaWFsLG5hbWVzPSJQcmVjaW8iKQ0KYGBgDQojRXZhbHVhciBsYSBjb2ludGVuZ3JhY2nzbiB1c2FuZG8gbGEgbWV0b2RvbG9n7WEgZGUgRW5nbGUtR3JhbmdlciB5IEpvaGFuc2VuDQoNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCnBsb3QobGltb25lcywgbWFpbj0iUHJvZHVjY2nzbiBkZSBMaW1vbmVzIikNCnBsb3QoUHJlY2lvbGltb24sbWFpbj0iUHJlY2lvIEdlbmVyYWwiKQ0KDQpgYGANCg0KYGBge3J9DQp1ci5kZihsaW1vbmVzKQ0KdXIuZGYoUHJlY2lvbGltb24pDQpgYGANCiMjIyMjSG86TGEgc2VyaWUgbm8gZXMgZXN0YWNpb25hcmlhDQojIyMjI1NlZ/puIGxhIHBydWViYSBkZSBjb2ludGVncmFjafNuLCBpbmRpY2EgcXVlIGVsIHTpcm1pbm8gZGVsIGVycm9yIGVzIG1heW9yIGEgbG9zIGNyaXRpY29zICh5MT0tMSwgeTI9MSkgcG9yIGxvIHRhbnRvIG5vIHNvbiBlc3RhY2lvbmFyaWFzDQoNCmBgYHtyfQ0KbHAucmVnIDwtIGR5bmxtKFByZWNpb2xpbW9uIH4gTChQcmVjaW9saW1vbikgKyBsaW1vbmVzICsgTChsaW1vbmVzKSkNCnN1bW1hcnkobHAucmVnKQ0KYGBgDQpgYGB7cn0NCmR3dGVzdChscC5yZWcpDQpgYGANCiMjIyMjU2Ugb2JzZXJ2YSBxdWUgZWwgdmFsb3IgcCByZXN1bHRhIHNlciBzaWduaWZpY2F0aXZvIHA+MC41IHBvciBsbyB0YW50byBzZSByZWNoYXphIGxhIEhvIGFjZXB0YW5kbyBsYSBhbHRlcm5hIHBvciBsbyBxdWUgbGFzIHZhcmlhYmxlcyB0aWVuZW4gdmVyZGFkZXJhIGF1dG9jb3JyZWxhY2nzbiBlbnRyZSBlbGxhcy4NCg0KYGBge3J9DQplcnJvciA8LSByZXNpZHVhbHMobHAucmVnKQ0KcGxvdChlcnJvcikNCmFibGluZShoPTApDQp1ci5kZihlcnJvcikNCmBgYA0KDQojIyMjI0hvOkxhIHNlcmllIG5vIGVzIGVzdGFjaW9uYXJpYQ0KIyMjIyNTZWf6biBsYSBwcnVlYmEgZGUgY29pbnRlZ3JhY2nzbiwgaW5kaWNhIHF1ZSBlbCB06XJtaW5vIGRlbCBlcnJvciBlcyBtYXlvciBhIGxvcyBjcml0aWNvcyBwPS03Ljg2IHBvciBsbyB0YW50byBleGlzdGUgdW5hIHJlbGFjaW9uIGRlIGNvaW50ZWdyYWNp824uIA0KDQoNCmBgYHtyfQ0KbGltb25lczMgPC0gdHMuaW50ZXJzZWN0KGxpbW9uZXMsUHJlY2lvbGltb24sIGVycm9yKQ0KZHluIDwtIGR5bmxtKGQoUHJlY2lvbGltb24pIH4gTChlcnJvcikgKyBMKGQobGltb25lcykpICsgTChkKFByZWNpb2xpbW9uKSksIGRhdGE9ZGF0YSkNCnN1bW1hcnkoZHluKQ0KYGBgDQoNCg==