# Paquete utilizado para el ajuste de modelos mixtos.
library(nlme)

# Paquete utilizado para realizar análisis descriptivo.
library(tidyverse)

# Paquete para el análisis de residuales
library(predictmeans)

# Paquete para gráficos
library(ggplot2)
library(ggpubr)

1. Descripción

La agricultura es una de las principales actividades económicas del departamento de Antioquia y el café es uno de los productos mas cultivados. Son 80.238 productores, de los 550 mil que tiene el país, que todos los días se levantan con sus hijos, esposas y trabajadores a recorrer 104 mil fincas que se extienden en 2.685 veredas de 93 de los 125 municipios del departamento. Adicionalmente es uno de los productos que representan un alto porcentaje de participación en la exportación, teniendo esto en cuenta en importante implementar modelos que expliquen el comportamiento de la producción de café en el departamento teniendo en cuenta variables como el área de producción y el municipio de cultivo.

1.1 Lectura de la base de datos

Los datos fueron tomados de la página web Datos Abiertos Colombia, el link de descarga es https://www.datos.gov.co/Agricultura-y-Desarrollo-Rural/Areas-cultivadas-y-produccion-agr-cola-en-Antioqui/t2ca-uae5https://www.datos.gov.co/Agricultura-y-Desarrollo-Rural/Areas-cultivadas-y-produccion-agr-cola-en-Antioqui/t2ca-uae5

agricola <- read.csv("Agricola.csv", encoding = "UTF-8")

El conjunto de datos contiene información de los cultivos en Antioquia desde el año 1990, entendiendo que la agricultura ha evolucionado se decide seleccionar para el análisis y ajuste de modelos la información desde el año 2014 hasta 2020 y únicamente los cultivos de café ya que es uno de los productos que se exporta en gran cantidad desde el departamento.

Selección de columnas relevantes, año y cultivo a analizar.

data <- agricola %>% 
  filter(Año %in% c("2014", "2015", "2016", "2017", "2018", "2019", "2020"))
cafe <- data %>% filter(str_detect(Rubro, "Café")) %>% 
  select(c("Municipio", "Área.Producción", "Volumen.Producción"))

1.2 Descripción de variables

La base de datos contiene 93 municipios del departamento de Antoquia donde se cultiva café y 634 registros uno por cada combinación de municipio y área de producción y se observa el volumen en toneladas producido.

1.3 Vista del conjunto de datos

2. Objetivos

  1. Encontrar el mejor modelo predictivo que explique la producción en toneladas de los cultivos de Café en el departamento de Antioquia entre los años 2014 a 2020 discriminando por los diferentes municipios del departamento, además de observar la significancia de los efectos fijos y aleatorios mediante pruebas de hipótesis para finalmente escoger el mejor modelo.

  2. Exhibir la utilidad e importancia de los modelos mixtos cuando se tienen datos agrupados.

3. Análisis descriptivo

Antes de iniciar con el ajuste de modelos es importante realizar un análisis descriptivo que nos permita visualizar las relaciones existentes entre la variable objetivo y las variables predictoras, en este caso se quiere observar el comportamiento del volumen de producción, para esto se crea un gráfico de dispersión.

ggplot(data = cafe, aes(x = Área.Producción, y = Volumen.Producción, 
                           color = Municipio)) +
  geom_point() +
  theme_bw() + 
  labs(y = "Volumen de Producción") +
  ggtitle ("Gráfico de dispersión de Área de Producción vs Volumen de Producción")

Se observa en la nube de puntos que el volumen de producción de los municipios de Antioquia crece conjuntamente cada vez que el área de producción se hace más grande. Además, parece que la variabilidad aumenta a medida que las áreas de producción son mas grandes, lo cual indica que ajustar un modelo de regresión lineal clásico presentaría problemas con el supuesto de varianza constante.

A continuación, se presenta un gráfico de dispersión por cada municipio, para analizar de una mejor manera el comportamiento de la producción en cada municipio.

ggplot(data = cafe, aes(x = Área.Producción, y = Volumen.Producción, 
                           color = Municipio)) +
  geom_point() +
  theme_bw() + 
  labs(y = "Volumen de Producción", x = "Área Producción") +
  ggtitle ("Gráfico de dispersión de Área de Producción vs Volumen de Producción") +
  facet_wrap(~ Municipio) +
  theme(legend.position = "none") 

En la figura anterior se observa que la nube de puntos es creciente para todos los municipios en los que se cultiva café, existen algunos municipios como Andes, Betania, Betulia, Cuidad Bolivar, Concordia y Salgar que poseen valores muy altos tanto de áreas cultivadas como de producción, esto nos indica que estos son los municipios que posiblemente mayores exportaciones de café generan.

También se observa que los interceptos son diferentes en cada municipio, por lo que la creación de modelos mixtos puede ser beneficiosa para explicar el comportamiento del volumen de producción en función del área cultivada.

4. Modelos a considerar

1. Modelo de regresión lineal clásico.

\[produccion_j \sim N(\mu, \sigma^2)\]

\[\mu_j = \beta_0 + \beta_1AreaProduccion_j\]

2. Modelo de regresión lineal mixto con intercepto aleatorio.

\[produccion_{ij} \sim N(\mu_{ij}, \sigma^2)\] \[\mu_{ij} = \beta_0 + \beta_1 AreaProduccion_{ij} + \beta_{0i}\]

\[b_{0} \sim N(0, \sigma^2_{b0})\]

\[i = 1,~2,...,~93\]

3. Modelo de regresión lineal mixto con interccepto y pendiente aleatoria.

\[produccion_{ij} \sim N(\mu_{ij}, \sigma^2)\]

\[\mu_{ij} = \beta_0 + \beta_1 AreaProduccion_{ij} + \beta_{0i} + \beta_{1i} ~AreaProduccion_{ij}\]

\[ {b_0 \choose b_1} \sim N \left({0 \choose 0},{\sigma^2_{b0} \ \ \sigma^2_{b01} \choose \sigma^2_{b01} \ \ \sigma^2_{b1}} \right)\]

\[i = 1,~2,...,~93\]

5. Ajuste de modelos

A continuación se presenta el código utilizado para el ajuste de los modelos propuestos en la sección 4, para esto es utilizado el paquete \(nmle\) que esta orientado a la creación de modelos lineales mixtos con respuesta distribuida normal.

# Modelo 1
fit1 <- gls(Volumen.Producción ~ 1 + Área.Producción, data = cafe)

# Modelo 2
fit2 <- lme(Volumen.Producción ~ 1 + Área.Producción, 
            random =~ 1 | Municipio,
             data = cafe)

# Modelo 3
fit3 <- lme(Volumen.Producción ~ 1 + Área.Producción, 
            random=~ 1 + Área.Producción | Municipio,
             data = cafe)

6. Comparación de modelos

6.1 Prueba de hipótesis sobre componente de varianza del intercepto aleatorio

Se quiere determinar si introducir una variable de agrupación en el intercepto del modelo es significativa, para esto la hipótesis a probar es

\[H_0 : \sigma^{2}_{b0} = 0 ~~~~~~ vs ~~~~~~ H_A:\sigma^{2}_{b0} > 0\] con estadístico de prueba

\[lrt=−2×(logLik(modelo 1)−logLik(modelo 2))\] donde \(lrt \sim \chi_1^2\), se rechaza \(H_0\) con un nivel de significancia \(\alpha = 0.05\) si \(P(\chi_1^2 >lrt) < \alpha\). Para realizar esta prueba de hipótesis sobre esta componente de varianza es posible utilizar una tabla anova, sin embargo esta es una prueba conservativa, por lo que se debe tener cuidado con \(Valores~P\) grandes.

anova1 <- anova(fit1, fit2)
anova1 %>% mutate(call = NULL)

De la tabla anterior se tiene que \(lrt=421.4642\) y \(P(\chi_1^2 >lrt)<0.0001\) por lo que se rechaza la hipótesis nula y se tiene que la componente de varianza para el intercepto aleatorio es significativa y contribuye a la explicación del volumen de producción de los cultivos de café en Antioquia.

6.2 Prueba de hipótesis sobre componente de varianza de la pendiente aleatoria y componente de covarianza entre pendientes e interceptos aleatorios

Luego de identificar que la inclusión de interceptos aleatorios es significativo para el modelo es momento de realizar la prueba sobre la componente de varianza de las pendientes aleatorias y covarianza entre pendientes e interceptos aleatorios. La hipótesis a probar es

\[H_{0}: {\sigma^2_{b0} \ \ \sigma^2_{b01} \choose \sigma^2_{b01} \ \ \sigma^2_{b1}} = {\sigma^2_{b0} \ \ 0 \choose 0 \ \ ~~0} ~~~ vs ~~~ H_{A}: {\sigma^2_{b0} \ \ \sigma^2_{b01} \choose \sigma^2_{b01} \ \ \sigma^2_{b1}} = {\sigma^2_{b0}~~~~~~ \ \ \sigma^2_{b01} \neq 0 \choose \sigma^2_{b01} \neq0 \ \ \sigma^2_{b1}>0 }\] con estadístico de prueba

\[lrt= -2 \times (logLik(mododelo ~2) - logLik(modelo~3))\]

donde \(lrt \sim \chi^2_2\), se rechaza \(H_0\) con un nivel de significancia \(\alpha = 0.05\) si \(P(\chi_2^2 >lrt) < \alpha\). Para realizar esta prueba de hipótesis sobre esta componente de varianza y covarianza es posible utilizar una tabla anova, sin embargo esta es una prueba conservativa, por lo que se debe tener cuidado con \(Valores~P\) grandes.

anova2 <- anova(fit2, fit3)
anova2 %>% mutate(call = NULL)

De la tabla anterior se tiene que \(lrt=156.7391\) y \(P(\chi_2^2>lrt)<0.0001\) por lo que se rechaza la hipótesis nula y se tiene que la componente de varianza para la pendiente aleatoria, además de la componente de covarianza entre el intercepto y la pendiente aleatoria son significativas, por lo tanto contribuyen a la explicación de las toneladas de café producidas en el departamento de Antioquia.

6.3 Correlación entre valores ajustados y valores observados

correlaciones <- data.frame(cor_fit1 = cor(fitted(fit1),cafe$Volumen.Producción),
                            cor_fit2 = cor(fitted(fit2),cafe$Volumen.Producción),
                            cor_fit3 = cor(fitted(fit3),cafe$Volumen.Producción))
correlaciones

En la tabla anterior se presenta la correlación entre los valores predichos y reales para los tres modelos considerados, se observa que todos obtuvieron un buen desempeño, sin emargo, la mayor correlación la presenta el modelo 3, el cual tiene pendiente e intercepto aleatorio.

6.4 Criterios AIC y BIC

anova3 <- anova(fit1, fit2, fit3)
anova3 %>% mutate(call = NULL)

La tabla anterior indica que el mejor desempeño en cuanto a las medidas de AIC y BIC lo obtiene el modelo 3, ya que los valores de estas medidas son menores para este modelo.

Finalmente, de todas las tablas presentadas anteriormente y los criterios considerados es posible concluir que el mejor modelo es el número 3, el cual incluye pendientes e interceptos aleatorios, se procede a realizar el análisis de residuales para este modelo.

7. Análisis de residuales

7.1 Gráficos de residuales

En el gráfico de Residuales vs Valores ajustados, se observa un patrón similar a un embudo lo que nos indica una posible carencia de ajuste del modelo y posible violación del supuesto de varianza constante ya que la varianza aumenta hacia el final del eje x.

El gráfico Normal QQPlot para los residuales permite evidenciar que el supuesto de normalidad al parecer tiene problemas, ya que en los extremos varios puntos se alejan de la recta de normalidad, lo mismo se puede evidenciar con el histograma, los residuales estan centrados alrededor del cero pero tiene colas pesadas a ambos extremos.

7.2 Pruebas para los efectos aleatorios

Para la normalidad de los efectos \(b0\) y \(b1\) se puede observar que hay problemas en el supuesto de que estos distribuyen normal, pues hay varios puntos que están alejados de la linea (para ambos efectos), se observan colas pesadas.

7.3 Modelo con respuesta transformada

La manera más sencilla de solucionar la carencia de ajuste y varianza no constante evidenciada en los gráficos de residuales es aplicar una transformación logarítmica a la variable respuesta, es decir, a la producción en toneladas, ajustar de nuevo el modelo con el volumen de producción en escala logarítmica y posteriormente aplicarle la transformación inversa para obterner los valores ajustados.

7.3.1 Ajuste del modelo

# Aplicar logaritmo a la variable respuesta.
cafe$log_produccion <- log(cafe$Volumen.Producción)

# Modelo 3 con el volumen de produccion transformado
new_model <- lme(log_produccion ~ 1 + Área.Producción, 
            random=~ 1 + Área.Producción | Municipio,
             data = cafe)

# Agregar valores ajustados a la base de datos
cafe$pred_new <- exp(predict(new_model, type = 'response', newdata = cafe))

7.3.2 Gráficos de residuales

En el gráfico de Residuales vs Valores ajustados, ya no se observan patrones obvios, lo que nos indica que la transformación aplicada mejora notablemente el modelo, tanto en ajuste como en varianza constante.

El gráfico Normal QQPlot para los residuales permite evidenciar que el supuesto de normalidad presenta problemas, sin embargo las colas ya no son tan pesadas como se envidenciaba en el modelo 3.

7.3.3 Pruebas para los efectos aleatorios

Los supuestos de normalidad para los efectos \(b0\) y \(b1\) siguen con problemas, pero en general la transformación aplicada mejoro el ajuste del modelo.

8. Mejor modelo

Mediante las pruebas de hipótesis se concluye que el mejor modelo para ajustar la producción de café en Antioquia es el modelo 3. Pero en el análisis de residuales se encontró un problema con el supuesto de normalidad sobre la el volumen de producción. Por lo tanto, se usa una trasnformación logarítmica sobre el volumen de producción y se crea un modelo sobre esta variable transformada para corregir los supuestos inválidos del modelo 3.

Finalmente el mejor modelo ajustado es el siguiente:

\[Log[~ \widehat{\mu}_{ij}~]= 5.666495 + 0.001775~ ÁreaProducción_{ij} + \tilde{b}_{0i} + \tilde{b}_{1i} ~ÁreaProducción_{ij}\] \[con ~~\widehat{\mu}_{ij} = \widehat{E}[Volumen~de~Producción_{ij}~]\]

\[ {b_0 \choose b_1} \sim aprox ~ N \left({0 \choose 0},{1.803 \ \ \ -0.0021 \choose -0.0021 \ \ 2.567\times10^{-6}} \right)\]

\[i = 1,~2,...,~93\]

8.1 Representación gráfica de los modelos ajustados

Mejor modelo

Modelo 1

Modelo 2

Modelo 3

Referencias

Freddy Hernández Barajas, Jorge Leonardo López Martínez (2020-03-15). Modelos Mixtos con R. https://fhernanb.github.io/libro_modelos_mixtos/

Andrew Gelman, Jennifer Hill (2007). Data Analysis Using Regression and Multilevel/Hierarchical Models.

Cómite de cafeteros de Antioquia. https://antioquia.federaciondecafeteros.org/cafe-de-antioquia/

LS0tDQp0aXRsZTogIkFwbGljYWNpw7NuIGRlIG1vZGVsb3MgbWl4dG9zIHBhcmEgYWp1c3RhciBlbCB2b2x1bWVuIGRlIHByb2R1Y2Npw7NuIGRlIGN1bHRpdm9zIGRlIGNhZsOpIGVuIEFudGlvcXVpYSINCmF1dGhvcjogIkNhbWlsYSBBY29zdGEgUmFtw61yZXoiDQpkYXRlOiAiMDMvMDIvMjAyMiINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0aGVtZTogZmxhdGx5DQogICAgaGlnaGxpZ2h0OiBrYXRlDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIFBhcXVldGUgdXRpbGl6YWRvIHBhcmEgZWwgYWp1c3RlIGRlIG1vZGVsb3MgbWl4dG9zLg0KbGlicmFyeShubG1lKQ0KDQojIFBhcXVldGUgdXRpbGl6YWRvIHBhcmEgcmVhbGl6YXIgYW7DoWxpc2lzIGRlc2NyaXB0aXZvLg0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCiMgUGFxdWV0ZSBwYXJhIGVsIGFuw6FsaXNpcyBkZSByZXNpZHVhbGVzDQpsaWJyYXJ5KHByZWRpY3RtZWFucykNCg0KIyBQYXF1ZXRlIHBhcmEgZ3LDoWZpY29zDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGdncHVicikNCg0KYGBgDQoNCiMjIDEuIERlc2NyaXBjacOzbg0KDQpMYSBhZ3JpY3VsdHVyYSBlcyB1bmEgZGUgbGFzIHByaW5jaXBhbGVzIGFjdGl2aWRhZGVzIGVjb27Ds21pY2FzIGRlbCBkZXBhcnRhbWVudG8gZGUgQW50aW9xdWlhIHkgZWwgY2Fmw6kgZXMgdW5vIGRlIGxvcyBwcm9kdWN0b3MgbWFzIGN1bHRpdmFkb3MuIFNvbiA4MC4yMzggcHJvZHVjdG9yZXMsIGRlIGxvcyA1NTAgbWlsIHF1ZSB0aWVuZSBlbCBwYcOtcywgcXVlIHRvZG9zIGxvcyBkw61hcyBzZSBsZXZhbnRhbiBjb24gc3VzIGhpam9zLCBlc3Bvc2FzIHkgdHJhYmFqYWRvcmVzIGEgcmVjb3JyZXIgMTA0IG1pbCBmaW5jYXMgcXVlIHNlIGV4dGllbmRlbiBlbiAyLjY4NSB2ZXJlZGFzIGRlIDkzIGRlIGxvcyAxMjUgbXVuaWNpcGlvcyBkZWwgZGVwYXJ0YW1lbnRvLiBBZGljaW9uYWxtZW50ZSBlcyB1bm8gZGUgbG9zIHByb2R1Y3RvcyBxdWUgcmVwcmVzZW50YW4gdW4gYWx0byBwb3JjZW50YWplIGRlIHBhcnRpY2lwYWNpw7NuIGVuIGxhIGV4cG9ydGFjacOzbiwgdGVuaWVuZG8gZXN0byBlbiBjdWVudGEgZW4gaW1wb3J0YW50ZSBpbXBsZW1lbnRhciBtb2RlbG9zIHF1ZSBleHBsaXF1ZW4gZWwgY29tcG9ydGFtaWVudG8gZGUgbGEgcHJvZHVjY2nDs24gZGUgY2Fmw6kgZW4gZWwgZGVwYXJ0YW1lbnRvIHRlbmllbmRvIGVuIGN1ZW50YSB2YXJpYWJsZXMgY29tbyBlbCDDoXJlYSBkZSBwcm9kdWNjacOzbiB5IGVsIG11bmljaXBpbyBkZSBjdWx0aXZvLg0KDQo8Y2VudGVyPg0KIVtdKGNhZmUuanBnKXt3aWR0aD00ODBweH0NCjwvY2VudGVyPg0KDQojIyMgMS4xIExlY3R1cmEgZGUgbGEgYmFzZSBkZSBkYXRvcw0KDQpMb3MgZGF0b3MgZnVlcm9uIHRvbWFkb3MgZGUgIGxhIHDDoWdpbmEgd2ViIERhdG9zIEFiaWVydG9zIENvbG9tYmlhLCBlbCBsaW5rIGRlIGRlc2NhcmdhIGVzIGh0dHBzOi8vd3d3LmRhdG9zLmdvdi5jby9BZ3JpY3VsdHVyYS15LURlc2Fycm9sbG8tUnVyYWwvQXJlYXMtY3VsdGl2YWRhcy15LXByb2R1Y2Npb24tYWdyLWNvbGEtZW4tQW50aW9xdWkvdDJjYS11YWU1aHR0cHM6Ly93d3cuZGF0b3MuZ292LmNvL0FncmljdWx0dXJhLXktRGVzYXJyb2xsby1SdXJhbC9BcmVhcy1jdWx0aXZhZGFzLXktcHJvZHVjY2lvbi1hZ3ItY29sYS1lbi1BbnRpb3F1aS90MmNhLXVhZTUNCg0KYGBge3J9DQphZ3JpY29sYSA8LSByZWFkLmNzdigiQWdyaWNvbGEuY3N2IiwgZW5jb2RpbmcgPSAiVVRGLTgiKQ0KYGBgDQoNCkVsIGNvbmp1bnRvIGRlIGRhdG9zIGNvbnRpZW5lIGluZm9ybWFjacOzbiBkZSBsb3MgY3VsdGl2b3MgZW4gQW50aW9xdWlhIGRlc2RlIGVsIGHDsW8gMTk5MCwgZW50ZW5kaWVuZG8gcXVlIGxhIGFncmljdWx0dXJhIGhhIGV2b2x1Y2lvbmFkbyBzZSBkZWNpZGUgc2VsZWNjaW9uYXIgcGFyYSBlbCBhbsOhbGlzaXMgeSBhanVzdGUgZGUgbW9kZWxvcyBsYSBpbmZvcm1hY2nDs24gZGVzZGUgZWwgYcOxbyAyMDE0IGhhc3RhIDIwMjAgeSDDum5pY2FtZW50ZSBsb3MgY3VsdGl2b3MgZGUgY2Fmw6kgeWEgcXVlIGVzIHVubyBkZSBsb3MgcHJvZHVjdG9zIHF1ZSBzZSBleHBvcnRhIGVuIGdyYW4gY2FudGlkYWQgZGVzZGUgZWwgZGVwYXJ0YW1lbnRvLg0KDQpTZWxlY2Npw7NuIGRlIGNvbHVtbmFzIHJlbGV2YW50ZXMsIGHDsW8geSBjdWx0aXZvIGEgYW5hbGl6YXIuDQoNCmBgYHtyfQ0KZGF0YSA8LSBhZ3JpY29sYSAlPiUgDQogIGZpbHRlcihBw7FvICVpbiUgYygiMjAxNCIsICIyMDE1IiwgIjIwMTYiLCAiMjAxNyIsICIyMDE4IiwgIjIwMTkiLCAiMjAyMCIpKQ0KY2FmZSA8LSBkYXRhICU+JSBmaWx0ZXIoc3RyX2RldGVjdChSdWJybywgIkNhZsOpIikpICU+JSANCiAgc2VsZWN0KGMoIk11bmljaXBpbyIsICLDgXJlYS5Qcm9kdWNjacOzbiIsICJWb2x1bWVuLlByb2R1Y2Npw7NuIikpDQpgYGANCg0KIyMjIDEuMiBEZXNjcmlwY2nDs24gZGUgdmFyaWFibGVzDQoNCmBgYHtyLCByb3dzLnByaW50ID0gMywgY29scy5wcmludCA9IDMsIGVjaG89RkFMU0V9DQooZGVzY3JpcGNpb24gPC0gZGF0YS5mcmFtZShub21icmVfdmFyaWFibGUgPSBjKCJNdW5pY2lwaW8iLCAiw4FyZWEuUHJvZHVjY2nDs24iLCAiVm9sdW1lbi5Qcm9kdWNjacOzbiIpLCBkZXNjcmlwY2lvbiA9IGMoIk11bmljaXBpbyBkZSBjdWx0aXZvIiwgIsOBcmVhIGVuIHByb2R1Y2Npw7NuIGVuIGhlY3TDoXJlYXMiLCAiUHJvZHVjY2nDs24gZW4gdG9uZWxhZGFzIiksIHRpcG9fZGVfdmFyaWFibGUgPSBjKCJGYWN0b3IgKDkzIGxldmVscykiLCAibnVtIiwgIm51bSIpKSkNCmBgYA0KDQpMYSBiYXNlIGRlIGRhdG9zIGNvbnRpZW5lIDkzIG11bmljaXBpb3MgZGVsIGRlcGFydGFtZW50byBkZSBBbnRvcXVpYSBkb25kZSBzZSBjdWx0aXZhIGNhZsOpIHkgNjM0IHJlZ2lzdHJvcyB1bm8gcG9yIGNhZGEgY29tYmluYWNpw7NuIGRlIG11bmljaXBpbyB5IMOhcmVhIGRlIHByb2R1Y2Npw7NuIHkgc2Ugb2JzZXJ2YSBlbCB2b2x1bWVuIGVuIHRvbmVsYWRhcyBwcm9kdWNpZG8uDQoNCiMjIyAxLjMgVmlzdGEgZGVsIGNvbmp1bnRvIGRlIGRhdG9zDQoNCmBgYHtyLCByb3dzLnByaW50ID0gNiwgY29scy5wcmludCA9IDMsIHBhZ2VzLnByaW50ID0gMTAwLCBlY2hvPUZBTFNFfQ0KY2FmZQ0KYGBgDQoNCiMjIDIuIE9iamV0aXZvcw0KDQoxLiBFbmNvbnRyYXIgZWwgbWVqb3IgbW9kZWxvIHByZWRpY3Rpdm8gcXVlIGV4cGxpcXVlIGxhIHByb2R1Y2Npw7NuIGVuIHRvbmVsYWRhcyBkZSBsb3MgY3VsdGl2b3MgZGUgQ2Fmw6kgZW4gZWwgZGVwYXJ0YW1lbnRvIGRlIEFudGlvcXVpYSBlbnRyZSBsb3MgYcOxb3MgMjAxNCBhIDIwMjAgZGlzY3JpbWluYW5kbyBwb3IgbG9zIGRpZmVyZW50ZXMgbXVuaWNpcGlvcyBkZWwgZGVwYXJ0YW1lbnRvLCBhZGVtw6FzIGRlIG9ic2VydmFyIGxhIHNpZ25pZmljYW5jaWEgZGUgbG9zIGVmZWN0b3MgZmlqb3MgeSBhbGVhdG9yaW9zIG1lZGlhbnRlIHBydWViYXMgZGUgaGlww7N0ZXNpcyBwYXJhIGZpbmFsbWVudGUgZXNjb2dlciBlbCBtZWpvciBtb2RlbG8uDQoNCjIuIEV4aGliaXIgbGEgdXRpbGlkYWQgZSBpbXBvcnRhbmNpYSBkZSBsb3MgbW9kZWxvcyBtaXh0b3MgY3VhbmRvIHNlIHRpZW5lbiBkYXRvcyBhZ3J1cGFkb3MuDQoNCiMjIDMuIEFuw6FsaXNpcyBkZXNjcmlwdGl2bw0KDQpBbnRlcyBkZSBpbmljaWFyIGNvbiBlbCBhanVzdGUgZGUgbW9kZWxvcyBlcyBpbXBvcnRhbnRlIHJlYWxpemFyIHVuIGFuw6FsaXNpcyBkZXNjcmlwdGl2byBxdWUgbm9zIHBlcm1pdGEgdmlzdWFsaXphciBsYXMgcmVsYWNpb25lcyBleGlzdGVudGVzIGVudHJlIGxhIHZhcmlhYmxlIG9iamV0aXZvIHkgbGFzIHZhcmlhYmxlcyBwcmVkaWN0b3JhcywgZW4gZXN0ZSBjYXNvIHNlIHF1aWVyZSBvYnNlcnZhciBlbCBjb21wb3J0YW1pZW50byBkZWwgdm9sdW1lbiBkZSBwcm9kdWNjacOzbiwgcGFyYSBlc3RvIHNlIGNyZWEgdW4gZ3LDoWZpY28gZGUgZGlzcGVyc2nDs24uDQoNCmBgYHtyLCBmaWcuaGVpZ2h0ID0gNiwgZmlnLndpZHRoID0gMTB9DQpnZ3Bsb3QoZGF0YSA9IGNhZmUsIGFlcyh4ID0gw4FyZWEuUHJvZHVjY2nDs24sIHkgPSBWb2x1bWVuLlByb2R1Y2Npw7NuLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gTXVuaWNpcGlvKSkgKw0KICBnZW9tX3BvaW50KCkgKw0KICB0aGVtZV9idygpICsgDQogIGxhYnMoeSA9ICJWb2x1bWVuIGRlIFByb2R1Y2Npw7NuIikgKw0KICBnZ3RpdGxlICgiR3LDoWZpY28gZGUgZGlzcGVyc2nDs24gZGUgw4FyZWEgZGUgUHJvZHVjY2nDs24gdnMgVm9sdW1lbiBkZSBQcm9kdWNjacOzbiIpDQpgYGANClNlIG9ic2VydmEgZW4gbGEgbnViZSBkZSBwdW50b3MgcXVlIGVsIHZvbHVtZW4gZGUgcHJvZHVjY2nDs24gZGUgbG9zIG11bmljaXBpb3MgZGUgQW50aW9xdWlhIGNyZWNlIGNvbmp1bnRhbWVudGUgY2FkYSB2ZXogcXVlIGVsIMOhcmVhIGRlIHByb2R1Y2Npw7NuIHNlIGhhY2UgbcOhcyBncmFuZGUuIEFkZW3DoXMsIHBhcmVjZSBxdWUgbGEgdmFyaWFiaWxpZGFkIGF1bWVudGEgYSBtZWRpZGEgcXVlIGxhcyDDoXJlYXMgZGUgcHJvZHVjY2nDs24gc29uIG1hcyBncmFuZGVzLCBsbyBjdWFsIGluZGljYSBxdWUgYWp1c3RhciB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgY2zDoXNpY28gcHJlc2VudGFyw61hIHByb2JsZW1hcyBjb24gZWwgc3VwdWVzdG8gZGUgdmFyaWFuemEgY29uc3RhbnRlLg0KDQpBIGNvbnRpbnVhY2nDs24sIHNlIHByZXNlbnRhIHVuIGdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIHBvciBjYWRhIG11bmljaXBpbywgcGFyYSBhbmFsaXphciBkZSB1bmEgbWVqb3IgbWFuZXJhIGVsIGNvbXBvcnRhbWllbnRvIGRlIGxhIHByb2R1Y2Npw7NuIGVuIGNhZGEgbXVuaWNpcGlvLg0KDQpgYGB7ciwgZmlnLmhlaWdodCA9IDEwLCBmaWcud2lkdGggPSAxMH0NCmdncGxvdChkYXRhID0gY2FmZSwgYWVzKHggPSDDgXJlYS5Qcm9kdWNjacOzbiwgeSA9IFZvbHVtZW4uUHJvZHVjY2nDs24sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBNdW5pY2lwaW8pKSArDQogIGdlb21fcG9pbnQoKSArDQogIHRoZW1lX2J3KCkgKyANCiAgbGFicyh5ID0gIlZvbHVtZW4gZGUgUHJvZHVjY2nDs24iLCB4ID0gIsOBcmVhIFByb2R1Y2Npw7NuIikgKw0KICBnZ3RpdGxlICgiR3LDoWZpY28gZGUgZGlzcGVyc2nDs24gZGUgw4FyZWEgZGUgUHJvZHVjY2nDs24gdnMgVm9sdW1lbiBkZSBQcm9kdWNjacOzbiIpICsNCiAgZmFjZXRfd3JhcCh+IE11bmljaXBpbykgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpIA0KYGBgDQoNCkVuIGxhIGZpZ3VyYSBhbnRlcmlvciBzZSBvYnNlcnZhIHF1ZSBsYSBudWJlIGRlIHB1bnRvcyBlcyBjcmVjaWVudGUgcGFyYSB0b2RvcyBsb3MgbXVuaWNpcGlvcyBlbiBsb3MgcXVlIHNlIGN1bHRpdmEgY2Fmw6ksIGV4aXN0ZW4gYWxndW5vcyBtdW5pY2lwaW9zIGNvbW8gQW5kZXMsIEJldGFuaWEsIEJldHVsaWEsIEN1aWRhZCBCb2xpdmFyLCBDb25jb3JkaWEgeSBTYWxnYXIgcXVlIHBvc2VlbiB2YWxvcmVzIG11eSBhbHRvcyB0YW50byBkZSDDoXJlYXMgY3VsdGl2YWRhcyBjb21vIGRlIHByb2R1Y2Npw7NuLCBlc3RvIG5vcyBpbmRpY2EgcXVlIGVzdG9zIHNvbiBsb3MgbXVuaWNpcGlvcyBxdWUgcG9zaWJsZW1lbnRlIG1heW9yZXMgZXhwb3J0YWNpb25lcyBkZSBjYWbDqSBnZW5lcmFuLg0KDQpUYW1iacOpbiBzZSBvYnNlcnZhIHF1ZSBsb3MgaW50ZXJjZXB0b3Mgc29uIGRpZmVyZW50ZXMgZW4gY2FkYSBtdW5pY2lwaW8sIHBvciBsbyBxdWUgbGEgY3JlYWNpw7NuIGRlIG1vZGVsb3MgbWl4dG9zIHB1ZWRlIHNlciBiZW5lZmljaW9zYSBwYXJhIGV4cGxpY2FyIGVsIGNvbXBvcnRhbWllbnRvIGRlbCB2b2x1bWVuIGRlIHByb2R1Y2Npw7NuIGVuIGZ1bmNpw7NuIGRlbCDDoXJlYSBjdWx0aXZhZGEuIA0KDQojIyA0LiBNb2RlbG9zIGEgY29uc2lkZXJhcg0KDQojIyMjIDEuIE1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBjbMOhc2ljby4NCg0KJCRwcm9kdWNjaW9uX2ogXHNpbSBOKFxtdSwgXHNpZ21hXjIpJCQNCg0KJCRcbXVfaiA9ICBcYmV0YV8wICsgXGJldGFfMUFyZWFQcm9kdWNjaW9uX2okJA0KDQpcdnNwYWNlezVwdH0NCg0KIyMjIyAyLiBNb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgbWl4dG8gY29uIGludGVyY2VwdG8gYWxlYXRvcmlvLg0KDQokJHByb2R1Y2Npb25fe2lqfSBcc2ltIE4oXG11X3tpan0sIFxzaWdtYV4yKSQkDQokJFxtdV97aWp9ID0gXGJldGFfMCArIFxiZXRhXzEgQXJlYVByb2R1Y2Npb25fe2lqfSArIFxiZXRhX3swaX0kJA0KDQokJGJfezB9IFxzaW0gTigwLCBcc2lnbWFeMl97YjB9KSQkDQoNCiQkaSA9IDEsfjIsLi4uLH45MyQkDQpcdnNwYWNlezVwdH0NCg0KIyMjIyAzLiBNb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgbWl4dG8gY29uIGludGVyY2NlcHRvIHkgcGVuZGllbnRlIGFsZWF0b3JpYS4NCg0KJCRwcm9kdWNjaW9uX3tpan0gXHNpbSBOKFxtdV97aWp9LCBcc2lnbWFeMikkJA0KDQokJFxtdV97aWp9ID0gXGJldGFfMCArIFxiZXRhXzEgQXJlYVByb2R1Y2Npb25fe2lqfSArIFxiZXRhX3swaX0gKyBcYmV0YV97MWl9IH5BcmVhUHJvZHVjY2lvbl97aWp9JCQNCg0KJCQge2JfMCBcY2hvb3NlIGJfMX0gXHNpbSBOIFxsZWZ0KHswIFxjaG9vc2UgMH0se1xzaWdtYV4yX3tiMH0gXCAgXCBcc2lnbWFeMl97YjAxfSBcY2hvb3NlIFxzaWdtYV4yX3tiMDF9IFwgXCBcc2lnbWFeMl97YjF9fSBccmlnaHQpJCQNCg0KJCRpID0gMSx+MiwuLi4sfjkzJCQNClx2c3BhY2V7NXB0fQ0KDQojIyA1LiBBanVzdGUgZGUgbW9kZWxvcw0KDQpBIGNvbnRpbnVhY2nDs24gc2UgcHJlc2VudGEgZWwgY8OzZGlnbyB1dGlsaXphZG8gcGFyYSBlbCBhanVzdGUgZGUgbG9zIG1vZGVsb3MgcHJvcHVlc3RvcyBlbiBsYSBzZWNjacOzbiA0LCBwYXJhIGVzdG8gZXMgdXRpbGl6YWRvIGVsIHBhcXVldGUgJG5tbGUkIHF1ZSBlc3RhIG9yaWVudGFkbyBhIGxhIGNyZWFjacOzbiBkZSBtb2RlbG9zIGxpbmVhbGVzIG1peHRvcyBjb24gcmVzcHVlc3RhIGRpc3RyaWJ1aWRhIG5vcm1hbC4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgTW9kZWxvIDENCmZpdDEgPC0gZ2xzKFZvbHVtZW4uUHJvZHVjY2nDs24gfiAxICsgw4FyZWEuUHJvZHVjY2nDs24sIGRhdGEgPSBjYWZlKQ0KDQojIE1vZGVsbyAyDQpmaXQyIDwtIGxtZShWb2x1bWVuLlByb2R1Y2Npw7NuIH4gMSArIMOBcmVhLlByb2R1Y2Npw7NuLCANCiAgICAgICAgICAgIHJhbmRvbSA9fiAxIHwgTXVuaWNpcGlvLA0KICAgICAgICAgICAgIGRhdGEgPSBjYWZlKQ0KDQojIE1vZGVsbyAzDQpmaXQzIDwtIGxtZShWb2x1bWVuLlByb2R1Y2Npw7NuIH4gMSArIMOBcmVhLlByb2R1Y2Npw7NuLCANCiAgICAgICAgICAgIHJhbmRvbT1+IDEgKyDDgXJlYS5Qcm9kdWNjacOzbiB8IE11bmljaXBpbywNCiAgICAgICAgICAgICBkYXRhID0gY2FmZSkNCmBgYA0KDQojIyA2LiBDb21wYXJhY2nDs24gZGUgbW9kZWxvcw0KDQojIyMgNi4xIFBydWViYSBkZSBoaXDDs3Rlc2lzIHNvYnJlIGNvbXBvbmVudGUgZGUgdmFyaWFuemEgZGVsIGludGVyY2VwdG8gYWxlYXRvcmlvDQoNClNlIHF1aWVyZSBkZXRlcm1pbmFyIHNpIGludHJvZHVjaXIgdW5hIHZhcmlhYmxlIGRlIGFncnVwYWNpw7NuIGVuIGVsIGludGVyY2VwdG8gZGVsIG1vZGVsbyBlcyBzaWduaWZpY2F0aXZhLCBwYXJhIGVzdG8gbGEgaGlww7N0ZXNpcyBhIHByb2JhciBlcw0KDQokJEhfMCA6IFxzaWdtYV57Mn1fe2IwfSA9IDAgfn5+fn5+IHZzIH5+fn5+fiBIX0E6XHNpZ21hXnsyfV97YjB9ID4gMCQkDQpjb24gZXN0YWTDrXN0aWNvIGRlIHBydWViYQ0KDQokJGxydD3iiJIyw5cobG9nTGlrKG1vZGVsbyAxKeKIkmxvZ0xpayhtb2RlbG8gMikpJCQNCmRvbmRlICRscnQgXHNpbSBcY2hpXzFeMiQsIHNlIHJlY2hhemEgJEhfMCQgY29uIHVuIG5pdmVsIGRlIHNpZ25pZmljYW5jaWEgJFxhbHBoYSA9IDAuMDUkIHNpICRQKFxjaGlfMV4yID5scnQpIDwgXGFscGhhJC4gUGFyYSByZWFsaXphciBlc3RhIHBydWViYSBkZSBoaXDDs3Rlc2lzIHNvYnJlIGVzdGEgY29tcG9uZW50ZSBkZSB2YXJpYW56YSBlcyBwb3NpYmxlIHV0aWxpemFyIHVuYSB0YWJsYSBhbm92YSwgc2luIGVtYmFyZ28gZXN0YSBlcyB1bmEgcHJ1ZWJhIGNvbnNlcnZhdGl2YSwgcG9yIGxvIHF1ZSBzZSBkZWJlIHRlbmVyIGN1aWRhZG8gY29uICRWYWxvcmVzflAkIGdyYW5kZXMuDQoNCmBgYHtyfQ0KYW5vdmExIDwtIGFub3ZhKGZpdDEsIGZpdDIpDQphbm92YTEgJT4lIG11dGF0ZShjYWxsID0gTlVMTCkNCmBgYA0KDQpEZSBsYSB0YWJsYSBhbnRlcmlvciBzZSB0aWVuZSBxdWUgJGxydD00MjEuNDY0MiQgeSAkUChcY2hpXzFeMiA+bHJ0KTwwLjAwMDEkIHBvciBsbyBxdWUgc2UgcmVjaGF6YSBsYSBoaXDDs3Rlc2lzIG51bGEgeSBzZSB0aWVuZSBxdWUgbGEgY29tcG9uZW50ZSBkZSB2YXJpYW56YSBwYXJhIGVsIGludGVyY2VwdG8gYWxlYXRvcmlvIGVzIHNpZ25pZmljYXRpdmEgeSBjb250cmlidXllIGEgbGEgZXhwbGljYWNpw7NuIGRlbCB2b2x1bWVuIGRlIHByb2R1Y2Npw7NuIGRlIGxvcyBjdWx0aXZvcyBkZSBjYWbDqSBlbiBBbnRpb3F1aWEuDQoNCiMjIyA2LjIgUHJ1ZWJhIGRlIGhpcMOzdGVzaXMgc29icmUgY29tcG9uZW50ZSBkZSB2YXJpYW56YSBkZSBsYSBwZW5kaWVudGUgYWxlYXRvcmlhIHkgY29tcG9uZW50ZSBkZSBjb3ZhcmlhbnphIGVudHJlIHBlbmRpZW50ZXMgZSBpbnRlcmNlcHRvcyBhbGVhdG9yaW9zDQoNCkx1ZWdvIGRlIGlkZW50aWZpY2FyIHF1ZSBsYSBpbmNsdXNpw7NuIGRlIGludGVyY2VwdG9zIGFsZWF0b3Jpb3MgZXMgc2lnbmlmaWNhdGl2byBwYXJhIGVsIG1vZGVsbyBlcyBtb21lbnRvIGRlIHJlYWxpemFyIGxhIHBydWViYSBzb2JyZSBsYSBjb21wb25lbnRlIGRlIHZhcmlhbnphIGRlIGxhcyBwZW5kaWVudGVzIGFsZWF0b3JpYXMgeSBjb3ZhcmlhbnphIGVudHJlIHBlbmRpZW50ZXMgZSBpbnRlcmNlcHRvcyBhbGVhdG9yaW9zLiBMYSBoaXDDs3Rlc2lzIGEgcHJvYmFyIGVzDQoNCiQkSF97MH06IHtcc2lnbWFeMl97YjB9IFwgIFwgXHNpZ21hXjJfe2IwMX0gXGNob29zZSBcc2lnbWFeMl97YjAxfSBcIFwgXHNpZ21hXjJfe2IxfX0gPSB7XHNpZ21hXjJfe2IwfSBcICBcIDAgXGNob29zZSAwIFwgXCB+fjB9IH5+fiB2cyB+fn4gSF97QX06IHtcc2lnbWFeMl97YjB9IFwgIFwgXHNpZ21hXjJfe2IwMX0gXGNob29zZSBcc2lnbWFeMl97YjAxfSBcIFwgXHNpZ21hXjJfe2IxfX0gPSB7XHNpZ21hXjJfe2IwfX5+fn5+fiBcICBcIFxzaWdtYV4yX3tiMDF9IFxuZXEgMCBcY2hvb3NlIFxzaWdtYV4yX3tiMDF9IFxuZXEwIFwgXCBcc2lnbWFeMl97YjF9PjAgfSQkDQpjb24gZXN0YWTDrXN0aWNvIGRlIHBydWViYSANCg0KJCRscnQ9IC0yIFx0aW1lcyAobG9nTGlrKG1vZG9kZWxvIH4yKSAtIGxvZ0xpayhtb2RlbG9+MykpJCQNCg0KZG9uZGUgJGxydCBcc2ltIFxjaGleMl8yJCwgc2UgcmVjaGF6YSAkSF8wJCBjb24gdW4gbml2ZWwgZGUgc2lnbmlmaWNhbmNpYSAkXGFscGhhID0gMC4wNSQgc2kgJFAoXGNoaV8yXjIgPmxydCkgPCBcYWxwaGEkLiBQYXJhIHJlYWxpemFyIGVzdGEgcHJ1ZWJhIGRlIGhpcMOzdGVzaXMgc29icmUgZXN0YSBjb21wb25lbnRlIGRlIHZhcmlhbnphIHkgY292YXJpYW56YSBlcyBwb3NpYmxlIHV0aWxpemFyIHVuYSB0YWJsYSBhbm92YSwgc2luIGVtYmFyZ28gZXN0YSBlcyB1bmEgcHJ1ZWJhIGNvbnNlcnZhdGl2YSwgcG9yIGxvIHF1ZSBzZSBkZWJlIHRlbmVyIGN1aWRhZG8gY29uICRWYWxvcmVzflAkIGdyYW5kZXMuDQoNCg0KYGBge3J9DQphbm92YTIgPC0gYW5vdmEoZml0MiwgZml0MykNCmFub3ZhMiAlPiUgbXV0YXRlKGNhbGwgPSBOVUxMKQ0KYGBgDQoNCkRlIGxhIHRhYmxhIGFudGVyaW9yIHNlIHRpZW5lIHF1ZSAkbHJ0PTE1Ni43MzkxJCB5ICRQKFxjaGlfMl4yPmxydCk8MC4wMDAxJCBwb3IgbG8gcXVlIHNlIHJlY2hhemEgbGEgaGlww7N0ZXNpcyBudWxhIHkgc2UgdGllbmUgcXVlIGxhIGNvbXBvbmVudGUgZGUgdmFyaWFuemEgcGFyYSBsYSBwZW5kaWVudGUgYWxlYXRvcmlhLCBhZGVtw6FzIGRlIGxhIGNvbXBvbmVudGUgZGUgY292YXJpYW56YSBlbnRyZSBlbCBpbnRlcmNlcHRvIHkgbGEgcGVuZGllbnRlIGFsZWF0b3JpYSBzb24gc2lnbmlmaWNhdGl2YXMsIHBvciBsbyB0YW50byBjb250cmlidXllbiBhIGxhIGV4cGxpY2FjacOzbiBkZSBsYXMgdG9uZWxhZGFzIGRlIGNhZsOpIHByb2R1Y2lkYXMgZW4gZWwgZGVwYXJ0YW1lbnRvIGRlIEFudGlvcXVpYS4NCg0KDQojIyMgNi4zIENvcnJlbGFjacOzbiBlbnRyZSB2YWxvcmVzIGFqdXN0YWRvcyB5IHZhbG9yZXMgb2JzZXJ2YWRvcw0KDQpgYGB7cn0NCmNvcnJlbGFjaW9uZXMgPC0gZGF0YS5mcmFtZShjb3JfZml0MSA9IGNvcihmaXR0ZWQoZml0MSksY2FmZSRWb2x1bWVuLlByb2R1Y2Npw7NuKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JfZml0MiA9IGNvcihmaXR0ZWQoZml0MiksY2FmZSRWb2x1bWVuLlByb2R1Y2Npw7NuKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JfZml0MyA9IGNvcihmaXR0ZWQoZml0MyksY2FmZSRWb2x1bWVuLlByb2R1Y2Npw7NuKSkNCmNvcnJlbGFjaW9uZXMNCmBgYA0KRW4gbGEgdGFibGEgYW50ZXJpb3Igc2UgcHJlc2VudGEgbGEgY29ycmVsYWNpw7NuIGVudHJlIGxvcyB2YWxvcmVzIHByZWRpY2hvcyB5IHJlYWxlcyBwYXJhIGxvcyB0cmVzIG1vZGVsb3MgY29uc2lkZXJhZG9zLCBzZSBvYnNlcnZhIHF1ZSB0b2RvcyBvYnR1dmllcm9uIHVuIGJ1ZW4gZGVzZW1wZcOxbywgc2luIGVtYXJnbywgbGEgbWF5b3IgY29ycmVsYWNpw7NuIGxhIHByZXNlbnRhIGVsIG1vZGVsbyAzLCBlbCBjdWFsIHRpZW5lIHBlbmRpZW50ZSBlIGludGVyY2VwdG8gYWxlYXRvcmlvLg0KDQojIyMgNi40IENyaXRlcmlvcyBBSUMgeSBCSUMNCg0KYGBge3J9DQphbm92YTMgPC0gYW5vdmEoZml0MSwgZml0MiwgZml0MykNCmFub3ZhMyAlPiUgbXV0YXRlKGNhbGwgPSBOVUxMKQ0KYGBgDQoNCkxhIHRhYmxhIGFudGVyaW9yIGluZGljYSBxdWUgZWwgbWVqb3IgZGVzZW1wZcOxbyBlbiBjdWFudG8gYSBsYXMgbWVkaWRhcyBkZSBBSUMgeSBCSUMgbG8gb2J0aWVuZSBlbCBtb2RlbG8gMywgeWEgcXVlIGxvcyB2YWxvcmVzIGRlIGVzdGFzIG1lZGlkYXMgc29uIG1lbm9yZXMgcGFyYSBlc3RlIG1vZGVsby4NCg0KRmluYWxtZW50ZSwgZGUgdG9kYXMgbGFzIHRhYmxhcyBwcmVzZW50YWRhcyBhbnRlcmlvcm1lbnRlIHkgbG9zIGNyaXRlcmlvcyBjb25zaWRlcmFkb3MgZXMgcG9zaWJsZSBjb25jbHVpciBxdWUgZWwgbWVqb3IgbW9kZWxvIGVzIGVsIG7Dum1lcm8gMywgZWwgY3VhbCBpbmNsdXllIHBlbmRpZW50ZXMgZSBpbnRlcmNlcHRvcyBhbGVhdG9yaW9zLCBzZSBwcm9jZWRlIGEgcmVhbGl6YXIgZWwgYW7DoWxpc2lzIGRlIHJlc2lkdWFsZXMgcGFyYSBlc3RlIG1vZGVsby4NCg0KIyMgNy4gQW7DoWxpc2lzIGRlIHJlc2lkdWFsZXMNCg0KIyMjIDcuMSBHcsOhZmljb3MgZGUgcmVzaWR1YWxlcw0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY2FmZSRyZXNpZHVhbHMzIDwtIHJlc2lkdWFscyhmaXQzKQ0KY2FmZSRmaXR0ZWQzIDwtIHByZWRpY3QoZml0MywgdHlwZSA9ICJyZXNwb25zZSIsIG5ld2RhdGEgPSBjYWZlKQ0KDQpyZXNfdnNfZml0dCA8LSBjYWZlICU+JSBnZ3Bsb3QoYWVzKHg9Zml0dGVkMywgeT1yZXNpZHVhbHMzKSkgKyANCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNiwgc2l6ZSA9IDEpKyANCiAgdGhlbWVfYncoKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsc2xvcGUgPSAwLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMSwgDQogICAgICAgICAgICAgIGFscGhhID0gMC44KSsNCiAgbGFicyh4ID0gIkFqdXN0YWRvcyIsIHkgPSAiUmVzaWR1YWxlcyIpDQoNCnJlc192c19ucm93IDwtIGNhZmUlPiUgZ2dwbG90KGFlcyh4PTE6bnJvdyhjYWZlKSwgeT1yZXNpZHVhbHMzKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBzaXplID0gMSkrIA0KICB0aGVtZV9idygpICsNCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAwLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMSwgDQogICAgICAgICAgICAgIGFscGhhID0gMC44KSArIA0KICBsYWJzKHggPSAibnJvdyIsIHkgPSAiUmVzaWR1YWxlcyIpDQoNCmRlbnNfcmVzIDwtIGdncGxvdChjYWZlLGFlcyh4PXJlc2lkdWFsczMpKSArDQogIGdlb21fZGVuc2l0eShhbHBoYT0wLjU1KSArDQogIHRoZW1lX2J3KCkgKyANCiAgbGFicyh4ID0gIlJlc2lkdWFsZXMiKQ0KDQpxcXBsb3RfUmVzIDwtIGdncGxvdChjYWZlLCBhZXMoc2FtcGxlID0gcmVzaWR1YWxzMykpICsNCiAgc3RhdF9xcSgpICsNCiAgc3RhdF9xcV9saW5lKGNvbG9yID0gInJlZCIpICsNCiAgdGhlbWVfYncoKQ0KDQpnZ2FycmFuZ2UocmVzX3ZzX2ZpdHQscmVzX3ZzX25yb3csZGVuc19yZXMscXFwbG90X1JlcykNCmBgYA0KDQpFbiBlbCBncsOhZmljbyBkZSBSZXNpZHVhbGVzIHZzIFZhbG9yZXMgYWp1c3RhZG9zLCBzZSBvYnNlcnZhIHVuIHBhdHLDs24gc2ltaWxhciBhIHVuIGVtYnVkbyBsbyBxdWUgbm9zIGluZGljYSB1bmEgcG9zaWJsZSBjYXJlbmNpYSBkZSBhanVzdGUgZGVsIG1vZGVsbyB5IHBvc2libGUgdmlvbGFjacOzbiBkZWwgc3VwdWVzdG8gZGUgdmFyaWFuemEgY29uc3RhbnRlIHlhIHF1ZSBsYSB2YXJpYW56YSBhdW1lbnRhIGhhY2lhIGVsIGZpbmFsIGRlbCBlamUgeC4NCg0KRWwgZ3LDoWZpY28gTm9ybWFsIFFRUGxvdCBwYXJhIGxvcyByZXNpZHVhbGVzIHBlcm1pdGUgZXZpZGVuY2lhciBxdWUgZWwgc3VwdWVzdG8gZGUgbm9ybWFsaWRhZCBhbCBwYXJlY2VyIHRpZW5lIHByb2JsZW1hcywgeWEgcXVlIGVuIGxvcyBleHRyZW1vcyB2YXJpb3MgcHVudG9zIHNlIGFsZWphbiBkZSBsYSByZWN0YSBkZSBub3JtYWxpZGFkLCBsbyBtaXNtbyBzZSBwdWVkZSBldmlkZW5jaWFyIGNvbiBlbCBoaXN0b2dyYW1hLCBsb3MgcmVzaWR1YWxlcyBlc3RhbiBjZW50cmFkb3MgYWxyZWRlZG9yIGRlbCBjZXJvIHBlcm8gdGllbmUgY29sYXMgcGVzYWRhcyBhIGFtYm9zIGV4dHJlbW9zLg0KDQojIyMgNy4yIFBydWViYXMgcGFyYSBsb3MgZWZlY3RvcyBhbGVhdG9yaW9zDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpiMCA8LSByYW5lZihmaXQzKVssMV0NCmIxIDwtIHJhbmVmKGZpdDMpWywyXQ0KbWl4X2VmZWMgPC0gZGF0YS5mcmFtZShiMD1iMCxiMT1iMSkNCg0KcXFwbG90X2IwIDwtIGdncGxvdChtaXhfZWZlYywgYWVzKHNhbXBsZSA9IGIwKSkgKw0KICBzdGF0X3FxKGFscGhhID0gMC42KSArDQogIHN0YXRfcXFfbGluZShjb2xvciA9ICJyZWQiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgZ2d0aXRsZSgiR3LDoWZpY28gZGUgbm9ybWFsaWRhZCBwYXJhIGludGVyY2VwdG8NCiAgICAgICAgICBhbGVhdG9yaW8iKQ0KDQpxcXBsb3RfYjEgPC0gZ2dwbG90KG1peF9lZmVjLCBhZXMoc2FtcGxlID0gYjEpKSArDQogIHN0YXRfcXEoYWxwaGE9MC42KSArDQogIHN0YXRfcXFfbGluZShjb2xvciA9ICJyZWQiKSArDQogIHRoZW1lX2J3KCkgKw0KICBnZ3RpdGxlKCJHcsOhZmljbyBkZSBub3JtYWxpZGFkIHBhcmEgcGVuZGllbnRlDQogICAgICAgICAgYWxlYXRvcmlvIikNCg0KZ2dhcnJhbmdlKHFxcGxvdF9iMCwgcXFwbG90X2IxKQ0KYGBgDQoNClBhcmEgbGEgbm9ybWFsaWRhZCBkZSBsb3MgZWZlY3RvcyAkYjAkIHkgJGIxJCBzZSBwdWVkZSBvYnNlcnZhciBxdWUgaGF5IHByb2JsZW1hcyBlbiBlbCBzdXB1ZXN0byBkZSBxdWUgZXN0b3MgZGlzdHJpYnV5ZW4gbm9ybWFsLCBwdWVzIGhheSB2YXJpb3MgcHVudG9zIHF1ZSBlc3TDoW4gYWxlamFkb3MgZGUgbGEgbGluZWEgKHBhcmEgYW1ib3MgZWZlY3RvcyksIHNlIG9ic2VydmFuIGNvbGFzIHBlc2FkYXMuDQoNCiMjIyA3LjMgTW9kZWxvIGNvbiByZXNwdWVzdGEgdHJhbnNmb3JtYWRhDQoNCkxhIG1hbmVyYSBtw6FzIHNlbmNpbGxhIGRlIHNvbHVjaW9uYXIgbGEgY2FyZW5jaWEgZGUgYWp1c3RlIHkgdmFyaWFuemEgbm8gY29uc3RhbnRlIGV2aWRlbmNpYWRhIGVuIGxvcyBncsOhZmljb3MgZGUgcmVzaWR1YWxlcyBlcyBhcGxpY2FyIHVuYSB0cmFuc2Zvcm1hY2nDs24gbG9nYXLDrXRtaWNhIGEgbGEgdmFyaWFibGUgcmVzcHVlc3RhLCBlcyBkZWNpciwgYSBsYSBwcm9kdWNjacOzbiBlbiB0b25lbGFkYXMsIGFqdXN0YXIgZGUgbnVldm8gZWwgbW9kZWxvIGNvbiBlbCB2b2x1bWVuIGRlIHByb2R1Y2Npw7NuIGVuIGVzY2FsYSBsb2dhcsOtdG1pY2EgeSBwb3N0ZXJpb3JtZW50ZSBhcGxpY2FybGUgbGEgdHJhbnNmb3JtYWNpw7NuIGludmVyc2EgcGFyYSBvYnRlcm5lciBsb3MgdmFsb3JlcyBhanVzdGFkb3MuDQoNCiMjIyMgNy4zLjEgQWp1c3RlIGRlbCBtb2RlbG8NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgQXBsaWNhciBsb2dhcml0bW8gYSBsYSB2YXJpYWJsZSByZXNwdWVzdGEuDQpjYWZlJGxvZ19wcm9kdWNjaW9uIDwtIGxvZyhjYWZlJFZvbHVtZW4uUHJvZHVjY2nDs24pDQoNCiMgTW9kZWxvIDMgY29uIGVsIHZvbHVtZW4gZGUgcHJvZHVjY2lvbiB0cmFuc2Zvcm1hZG8NCm5ld19tb2RlbCA8LSBsbWUobG9nX3Byb2R1Y2Npb24gfiAxICsgw4FyZWEuUHJvZHVjY2nDs24sIA0KICAgICAgICAgICAgcmFuZG9tPX4gMSArIMOBcmVhLlByb2R1Y2Npw7NuIHwgTXVuaWNpcGlvLA0KICAgICAgICAgICAgIGRhdGEgPSBjYWZlKQ0KDQojIEFncmVnYXIgdmFsb3JlcyBhanVzdGFkb3MgYSBsYSBiYXNlIGRlIGRhdG9zDQpjYWZlJHByZWRfbmV3IDwtIGV4cChwcmVkaWN0KG5ld19tb2RlbCwgdHlwZSA9ICdyZXNwb25zZScsIG5ld2RhdGEgPSBjYWZlKSkNCmBgYA0KDQojIyMjIDcuMy4yIEdyw6FmaWNvcyBkZSByZXNpZHVhbGVzDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpjYWZlJHJlc2lkdWFsc19sb2cgPC0gcmVzaWR1YWxzKG5ld19tb2RlbCkNCmNhZmUkZml0dGVkX2xvZyA8LSBwcmVkaWN0KG5ld19tb2RlbCwgdHlwZSA9ICJyZXNwb25zZSIsIG5ld2RhdGEgPSBjYWZlKQ0KDQpyZXNfdnNfZml0dCA8LSBjYWZlICU+JSBnZ3Bsb3QoYWVzKHg9Zml0dGVkX2xvZywgeT1yZXNpZHVhbHNfbG9nKSkgKyANCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNiwgc2l6ZSA9IDEpKyANCiAgdGhlbWVfYncoKSArDQogIGdlb21fYWJsaW5lKGludGVyY2VwdCA9IDAsc2xvcGUgPSAwLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMSwgDQogICAgICAgICAgICAgIGFscGhhID0gMC44KSArDQogIGxhYnMoeCA9ICJBanVzdGFkb3MiLCB5ID0gIlJlc2lkdWFsZXMiKQ0KDQpyZXNfdnNfbnJvdyA8LSBjYWZlICU+JSBnZ3Bsb3QoYWVzKHg9MTpucm93KGNhZmUpLCB5PXJlc2lkdWFsc19sb2cpKSArDQogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIHNpemUgPSAxKSsgDQogIHRoZW1lX2J3KCkgKw0KICBnZW9tX2FibGluZShpbnRlcmNlcHQgPSAwLCBzbG9wZSA9IDAsIGNvbG9yID0gInJlZCIsIHNpemUgPSAxLCANCiAgICAgICAgICAgICAgYWxwaGEgPSAwLjgpICsNCiAgbGFicyh4ID0gIm5yb3ciLCB5ID0gIlJlc2lkdWFsZXMiKQ0KDQpkZW5zX3JlcyA8LSBnZ3Bsb3QoY2FmZSwgYWVzKHggPSByZXNpZHVhbHNfbG9nKSkgKw0KICBnZW9tX2RlbnNpdHkoYWxwaGE9MC41NSkgKw0KICB0aGVtZV9idygpICsNCiAgbGFicyh4ID0gIlJlc2lkdWFsZXMiKQ0KDQpxcXBsb3RfUmVzIDwtIGdncGxvdChjYWZlLCBhZXMoc2FtcGxlID0gcmVzaWR1YWxzX2xvZykpICsNCiAgc3RhdF9xcSgpICsNCiAgc3RhdF9xcV9saW5lKGNvbG9yID0gInJlZCIpICsNCiAgdGhlbWVfYncoKQ0KDQpnZ2FycmFuZ2UocmVzX3ZzX2ZpdHQscmVzX3ZzX25yb3csZGVuc19yZXMscXFwbG90X1JlcykNCmBgYA0KDQpFbiBlbCBncsOhZmljbyBkZSBSZXNpZHVhbGVzIHZzIFZhbG9yZXMgYWp1c3RhZG9zLCB5YSBubyBzZSBvYnNlcnZhbiBwYXRyb25lcyBvYnZpb3MsIGxvIHF1ZSBub3MgaW5kaWNhIHF1ZSBsYSB0cmFuc2Zvcm1hY2nDs24gYXBsaWNhZGEgbWVqb3JhIG5vdGFibGVtZW50ZSBlbCBtb2RlbG8sIHRhbnRvIGVuIGFqdXN0ZSBjb21vIGVuIHZhcmlhbnphIGNvbnN0YW50ZS4NCg0KRWwgZ3LDoWZpY28gTm9ybWFsIFFRUGxvdCBwYXJhIGxvcyByZXNpZHVhbGVzIHBlcm1pdGUgZXZpZGVuY2lhciBxdWUgZWwgc3VwdWVzdG8gZGUgbm9ybWFsaWRhZCBwcmVzZW50YSBwcm9ibGVtYXMsIHNpbiBlbWJhcmdvIGxhcyBjb2xhcyB5YSBubyBzb24gdGFuIHBlc2FkYXMgY29tbyBzZSBlbnZpZGVuY2lhYmEgZW4gZWwgbW9kZWxvIDMuDQoNCiMjIyMgNy4zLjMgUHJ1ZWJhcyBwYXJhIGxvcyBlZmVjdG9zIGFsZWF0b3Jpb3MNCg0KYGBge3IgZWNobz1GQUxTRX0NCmIwIDwtIHJhbmVmKG5ld19tb2RlbClbLDFdDQpiMSA8LSByYW5lZihuZXdfbW9kZWwpWywyXQ0KbWl4X2VmZWMgPC0gZGF0YS5mcmFtZShiMD1iMCxiMT1iMSkNCg0KcXFwbG90X2IwIDwtIGdncGxvdChtaXhfZWZlYywgYWVzKHNhbXBsZSA9IGIwKSkgKw0KICBzdGF0X3FxKGFscGhhID0gMC42KSArDQogIHN0YXRfcXFfbGluZShjb2xvciA9ICJyZWQiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgZ2d0aXRsZSgiR3LDoWZpY28gZGUgbm9ybWFsaWRhZCBwYXJhIGludGVyY2VwdG8NCiAgICAgICAgICBhbGVhdG9yaW8iKQ0KDQpxcXBsb3RfYjEgPC0gZ2dwbG90KG1peF9lZmVjLCBhZXMoc2FtcGxlID0gYjEpKSArDQogIHN0YXRfcXEoYWxwaGE9MC42KSArDQogIHN0YXRfcXFfbGluZShjb2xvciA9ICJyZWQiKSArDQogIHRoZW1lX2J3KCkgKw0KICBnZ3RpdGxlKCJHcsOhZmljbyBkZSBub3JtYWxpZGFkIHBhcmEgcGVuZGllbnRlDQogICAgICAgICAgYWxlYXRvcmlvIikNCg0KZ2dhcnJhbmdlKHFxcGxvdF9iMCwgcXFwbG90X2IxKQ0KYGBgDQoNCkxvcyBzdXB1ZXN0b3MgZGUgbm9ybWFsaWRhZCBwYXJhIGxvcyBlZmVjdG9zICRiMCQgeSAkYjEkIHNpZ3VlbiBjb24gcHJvYmxlbWFzLCBwZXJvIGVuIGdlbmVyYWwgbGEgdHJhbnNmb3JtYWNpw7NuIGFwbGljYWRhIG1lam9ybyBlbCBhanVzdGUgZGVsIG1vZGVsby4NCg0KIyMgOC4gTWVqb3IgbW9kZWxvDQoNCk1lZGlhbnRlIGxhcyBwcnVlYmFzIGRlIGhpcMOzdGVzaXMgc2UgY29uY2x1eWUgcXVlIGVsIG1lam9yIG1vZGVsbyBwYXJhIGFqdXN0YXIgbGEgcHJvZHVjY2nDs24gZGUgY2Fmw6kgZW4gQW50aW9xdWlhIGVzIGVsIG1vZGVsbyAzLiBQZXJvIGVuIGVsIGFuw6FsaXNpcyBkZSByZXNpZHVhbGVzIHNlIGVuY29udHLDsyB1biBwcm9ibGVtYSBjb24gZWwgc3VwdWVzdG8gZGUgbm9ybWFsaWRhZCBzb2JyZSBsYSBlbCB2b2x1bWVuIGRlIHByb2R1Y2Npw7NuLiBQb3IgbG8gdGFudG8sIHNlIHVzYSB1bmEgdHJhc25mb3JtYWNpw7NuIGxvZ2Fyw610bWljYSBzb2JyZSBlbCB2b2x1bWVuIGRlIHByb2R1Y2Npw7NuIHkgc2UgY3JlYSB1biBtb2RlbG8gc29icmUgZXN0YSB2YXJpYWJsZSB0cmFuc2Zvcm1hZGEgcGFyYSBjb3JyZWdpciBsb3Mgc3VwdWVzdG9zIGludsOhbGlkb3MgZGVsIG1vZGVsbyAzLg0KDQpGaW5hbG1lbnRlIGVsIG1lam9yIG1vZGVsbyBhanVzdGFkbyBlcyBlbCBzaWd1aWVudGU6DQoNCmBgYHtyIGluY2x1ZGU9RkFMU0V9DQpzdW1tYXJ5KG5ld19tb2RlbCkNCmBgYA0KDQokJExvZ1t+IFx3aWRlaGF0e1xtdX1fe2lqfX5dPSA1LjY2NjQ5NSArIDAuMDAxNzc1fiDDgXJlYVByb2R1Y2Npw7NuX3tpan0gKyBcdGlsZGV7Yn1fezBpfSArIFx0aWxkZXtifV97MWl9IH7DgXJlYVByb2R1Y2Npw7NuX3tpan0kJA0KJCRjb24gfn5cd2lkZWhhdHtcbXV9X3tpan0gPSBcd2lkZWhhdHtFfVtWb2x1bWVufmRlflByb2R1Y2Npw7NuX3tpan1+XSQkDQoNCiQkIHtiXzAgXGNob29zZSBiXzF9IFxzaW0gYXByb3ggfiBOIFxsZWZ0KHswIFxjaG9vc2UgMH0sezEuODAzIFwgIFwgXCAtMC4wMDIxIFxjaG9vc2UgLTAuMDAyMSBcIFwgMi41NjdcdGltZXMxMF57LTZ9fSBccmlnaHQpJCQNCg0KJCRpID0gMSx+MiwuLi4sfjkzJCQNCg0KIyMjIDguMSBSZXByZXNlbnRhY2nDs24gZ3LDoWZpY2EgZGUgbG9zIG1vZGVsb3MgYWp1c3RhZG9zIHsudGFic2V0fQ0KDQpgYGB7ciBpbmNsdWRlPUZBTFNFfQ0KY2FmZSRwcmVkMSA8LSBwcmVkaWN0KGZpdDEsIHR5cGUgPSAncmVzcG9uc2UnLCBuZXdkYXRhID0gY2FmZSkNCmNhZmUkcHJlZDIgPC0gcHJlZGljdChmaXQyLCB0eXBlID0gJ3Jlc3BvbnNlJywgbmV3ZGF0YSA9IGNhZmUpDQpgYGANCg0KIyMjIyBNZWpvciBtb2RlbG8NCg0KYGBge3IgZWNobz1GQUxTRSwgIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMH0NCmdncGxvdChkYXRhID0gY2FmZSwgYWVzKHggPSDDgXJlYS5Qcm9kdWNjacOzbiwgeSA9IFZvbHVtZW4uUHJvZHVjY2nDs24sIA0KICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBNdW5pY2lwaW8pKSArDQogIGdlb21fcG9pbnQoKSArDQogIHRoZW1lX2J3KCkgKyANCiAgbGFicyh5ID0gIlZvbHVtZW4gZGUgUHJvZHVjY2nDs24iKSArDQogIGdndGl0bGUgKCJHcsOhZmljbyBkZSBkaXNwZXJzacOzbiBkZSDDgXJlYSBkZSBQcm9kdWNjacOzbiB2cyBWb2x1bWVuIGRlIFByb2R1Y2Npw7NuIikgKw0KICBmYWNldF93cmFwKH4gTXVuaWNpcGlvKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICBnZW9tX2xpbmUoYWVzKHkgPSBwcmVkX25ldywgeCA9IMOBcmVhLlByb2R1Y2Npw7NuKSwgY29sb3IgPSAiYmxhY2siKQ0KYGBgDQoNCg0KIyMjIyBNb2RlbG8gMQ0KDQpgYGB7ciBlY2hvPUZBTFNFLCAgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0KZ2dwbG90KGRhdGEgPSBjYWZlLCBhZXMoeCA9IMOBcmVhLlByb2R1Y2Npw7NuLCB5ID0gVm9sdW1lbi5Qcm9kdWNjacOzbiwgDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IE11bmljaXBpbykpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfYncoKSArIA0KICBsYWJzKHkgPSAiVm9sdW1lbiBkZSBQcm9kdWNjacOzbiIpICsNCiAgZ2d0aXRsZSAoIkdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIGRlIMOBcmVhIGRlIFByb2R1Y2Npw7NuIHZzIFZvbHVtZW4gZGUgUHJvZHVjY2nDs24iKSArDQogIGZhY2V0X3dyYXAofiBNdW5pY2lwaW8pICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGdlb21fbGluZShhZXMoeSA9IHByZWQxLCB4ID0gw4FyZWEuUHJvZHVjY2nDs24pLCBjb2xvciA9ICJibGFjayIpDQpgYGANCg0KIyMjIyBNb2RlbG8gMg0KDQpgYGB7ciBlY2hvPUZBTFNFLCAgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0KZ2dwbG90KGRhdGEgPSBjYWZlLCBhZXMoeCA9IMOBcmVhLlByb2R1Y2Npw7NuLCB5ID0gVm9sdW1lbi5Qcm9kdWNjacOzbiwgDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IE11bmljaXBpbykpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfYncoKSArIA0KICBsYWJzKHkgPSAiVm9sdW1lbiBkZSBQcm9kdWNjacOzbiIpICsNCiAgZ2d0aXRsZSAoIkdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIGRlIMOBcmVhIGRlIFByb2R1Y2Npw7NuIHZzIFZvbHVtZW4gZGUgUHJvZHVjY2nDs24iKSArDQogIGZhY2V0X3dyYXAofiBNdW5pY2lwaW8pICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGdlb21fbGluZShhZXMoeSA9IHByZWQyLCB4ID0gw4FyZWEuUHJvZHVjY2nDs24pLCBjb2xvciA9ICJibGFjayIpDQpgYGANCg0KIyMjIyBNb2RlbG8gMw0KDQpgYGB7ciBlY2hvPUZBTFNFLCAgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0KZ2dwbG90KGRhdGEgPSBjYWZlLCBhZXMoeCA9IMOBcmVhLlByb2R1Y2Npw7NuLCB5ID0gVm9sdW1lbi5Qcm9kdWNjacOzbiwgDQogICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IE11bmljaXBpbykpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgdGhlbWVfYncoKSArIA0KICBsYWJzKHkgPSAiVm9sdW1lbiBkZSBQcm9kdWNjacOzbiIpICsNCiAgZ2d0aXRsZSAoIkdyw6FmaWNvIGRlIGRpc3BlcnNpw7NuIGRlIMOBcmVhIGRlIFByb2R1Y2Npw7NuIHZzIFZvbHVtZW4gZGUgUHJvZHVjY2nDs24iKSArDQogIGZhY2V0X3dyYXAofiBNdW5pY2lwaW8pICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogIGdlb21fbGluZShhZXMoeSA9IGZpdHRlZDMsIHggPSDDgXJlYS5Qcm9kdWNjacOzbiksIGNvbG9yID0gImJsYWNrIikNCmBgYA0KDQojIyBSZWZlcmVuY2lhcw0KDQpGcmVkZHkgSGVybsOhbmRleiBCYXJhamFzLCBKb3JnZSBMZW9uYXJkbyBMw7NwZXogTWFydMOtbmV6ICgyMDIwLTAzLTE1KS4gTW9kZWxvcyBNaXh0b3MgY29uIFIuIA0KaHR0cHM6Ly9maGVybmFuYi5naXRodWIuaW8vbGlicm9fbW9kZWxvc19taXh0b3MvDQoNCkFuZHJldyBHZWxtYW4sIEplbm5pZmVyIEhpbGwgKDIwMDcpLiBEYXRhIEFuYWx5c2lzIFVzaW5nIFJlZ3Jlc3Npb24gYW5kIE11bHRpbGV2ZWwvSGllcmFyY2hpY2FsIE1vZGVscy4NCg0KQ8OzbWl0ZSBkZSBjYWZldGVyb3MgZGUgQW50aW9xdWlhLg0KaHR0cHM6Ly9hbnRpb3F1aWEuZmVkZXJhY2lvbmRlY2FmZXRlcm9zLm9yZy9jYWZlLWRlLWFudGlvcXVpYS8=