Domenica Andrade, Brandon Flores, Mishell Orozco

Domenica Andrade, Brandon Flores, Mishell Orozco

ABSTRACT

Mishell Orozco

Mi nombre es Mishell Alejandra Orozco Vega, tengo 20 años, naci en Quito el 12 de Febrero de 1998, actualmente me encuentro cursando 5to semestre de la carrera de Ingenieria en Biotecnologia en la Universidad de las Fuerzas Armadas ESPE. Disfruto leer, ver peliculas, la danza, futbol y pasar tiempo con amigos.

Brandon Flores

Mi nombre es Brandon Alexander Flores Realpe, tengo 21 años, naci en la provincia de Imbabura especeficamente en la ciudad de Ibarra. Soy estudiante de la carrera Ingenieria en Biotecnologia de la Universidad de las Fuerzas Armadas - ESPE. En mi tiempo libre me gusta leer, ver series y cantar.

Domenica Andrade

Mi nombre es Domenica Sofia Andrade Nicolalde, tengo 20 años, naci en la provincia de Pichincha, en Quito, un hermoso 09 de Febrero de 1998. Me gusta pasar tiempo con mi perro que se llama Percy y es gordito, estudio Ingenieria en Biotecnologia en la Universidad de las Fuerzas Armadas, me apasiona mi carrera y espero especializarme en la parte medica. Saludos

ANALISIS ESTADISTICO

BASE DE DATOS

Descripcion de la base de datos

Para la realizacion del proyecto se ha escogido la base de datos “pacientes”, la cual contiene las siguientes variables:

Paciente: Caracter

Edad: Entero

Colesterol: Numerica

IMC (Indice de masa corporal):Numerico

TAD (Tension arterial distolica):Numerico

Genero:Factor

Lectura de la base de datos, nombres de columnas adecuados, definir tipo de varibles y etiquetas a las tipo factor

Los datos de “pacientes” se adecuan a los nombres correspondientes de sus variables

Analisis exploratorio de datos

Se muestra a continuacion el str de la base de datos y el resumen de la misma

'data.frame':   70 obs. of  6 variables:
 $ PACIENTE  : chr  "1" "2" "3" "4" ...
 $ EDAD      : num  42 64 47 56 54 48 57 52 67 46 ...
 $ COLESTEROL: num  292 235 200 200 300 215 216 254 310 237 ...
 $ IMC       : num  31.6 30.8 25.6 26.2 32 ...
 $ TAD       : num  97 90 80 75 100 67 NA 70 105 70 ...
 $ GENERO    : Factor w/ 2 levels "Hombre","Mujer": 1 1 1 2 1 1 2 1 1 2 ...
   PACIENTE              EDAD         COLESTEROL         IMC             TAD            GENERO  
 Length:70          Min.   :42.00   Min.   :175.0   Min.   :19.10   Min.   : 65.00   Hombre:41  
 Class :character   1st Qu.:49.00   1st Qu.:214.2   1st Qu.:22.36   1st Qu.: 75.00   Mujer :29  
 Mode  :character   Median :56.00   Median :230.0   Median :25.38   Median : 80.00              
                    Mean   :55.24   Mean   :236.8   Mean   :25.47   Mean   : 81.65              
                    3rd Qu.:60.00   3rd Qu.:254.0   3rd Qu.:27.81   3rd Qu.: 90.00              
                    Max.   :68.00   Max.   :315.0   Max.   :33.91   Max.   :105.00              
                                                    NA's   :2       NA's   :1                   

Generar diagramas de cajas y diagramas de barras para las variables

DIAGRAMA DE CAJA

Diagrama de caja para la variable EDAD:

Se puede observar que la media aproximada de la edad de los pacientes estudiados es 56 años

Diagrama de caja para la variable COLESTEROL:

El grafico ayuda determinar que la media del colesterol en los pacientes es 230 ademas posee un valor atipico el cual rebasa el cuarto cuartil y es aproximado a 320.

Diagrama de caja para variable IMC o Indice de Masa Corporal:

En el diagrama de caja se logra identificar que la media en el indice de la masa corporal de los pacientes es aproximadamente 26, adempas se observa gran variaci??n en los datos

DIAGRAMA DE BARRAS

Correlacion entre variable dependiente y variables independientes

LIMPIEZA DE DATOS

Se asigno a los datos NA, el valor de la media respectiva para cada columna de la base de datos con la finalidad de que no difieran los resultados.

Se verifica que la base de datos se encuentre libre de NA

Se comprobo que no existen datos perdidos en la base de datos que se esta empleando

Correlacion

La correlacion permite determinar la medida en que dos variables tienen una relacion lineal entre si.

corrplot(cor(select(pacientes,-c(PACIENTE,GENERO))))

La tension arterial diastolica o TAD aumenta cuando hay aumento en COLESTEROL (alto), IMC (medio) y EDAD (baja).

Graficos de densidad:

Grafico de densidad con ggplot:

Grafico de densidad con plotly:

Las visualizaciones anteriores revelan que las densidades maximas de TAD estan entre 70 y 80

Efecto de las variables

Los resultados del grafico anterior estan en correlacion con el corrplot.

Analisis ANOVA

ANOVA

Considere una variable categorica y realice un analisis ANOVA (como el revisado en clase), incluya resultados y conclusion al final

La hipotesis nula es que las medias de los valores de TAD de hombres y mujeres son iguales y la hipotesis alternativa que las medias de estos grupos son distintas.

ANOVA y pruebas post-hoc.

Peticion de un ANOVA

tad<-pacientes$TAD
genero<-pacientes$GENERO
lol=aov(lm(tad~ genero))

Resumen de la tabla del ANOVA

summary(lol)
            Df Sum Sq Mean Sq F value Pr(>F)
genero       1    155   154.7   1.228  0.272
Residuals   68   8565   126.0               

Elementos generados en el ANOVA:

names(lol)
 [1] "coefficients"  "residuals"     "effects"       "rank"          "fitted.values" "assign"       
 [7] "qr"            "df.residual"   "contrasts"     "xlevels"       "call"          "terms"        
[13] "model"        
  1. Grados de libertad del factor: 2-1

  2. Grados de libertad residuales: 70-2

  3. Suma de cuadrados de los grupos: 155

  4. Suma de cuadrados del error: 8565

  5. Media de la suma de cuadrados de los grupos: 154.7

  6. Media de la suma de cuadrados del error: 126.0

  7. El valor del estadistico F: 1.228

  8. Valor de P: 0.2272

  9. Nivel de significancia considerado: 0.05

Cuantil buscado

qf(0.05, 2-1, 70-2, lower.tail = F)
[1] 3.981896

Valores del estadistico > 3.981896 estaran incluidos en la region de rechazo.En este caso el valor F que se obtuvo es de 1.228.

Estimacion de la varianza comun de los datos

[1] 82.90244

Intervalos de confianza para las medias de la tension arterial diastolica de los pacientes.

Limite superior

[1] 83.79638

Limite Inferior

[1] 82.0085

Test HSD de Tukey

  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = lm(tad ~ genero))

$genero
                  diff       lwr      upr     p adj
Mujer-Hombre -3.017956 -8.451847 2.415934 0.2716482
plot(intervals)

Validacion del Modelo ANOVA

Independencia

plot(lol$residuals,ylab = "Residuos",xlab = "Pacientes")

Normalidad

summary(lol$residuals)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-17.902  -7.902  -2.902   0.000  10.116  22.098 
boxplot(lol$residuals,col = "yellow")

hist(lol$residuals, col=cm.colors(4,alpha = 1))

qqnorm(lol$residuals) 
qqline(lol$residuals)

Test de Shapiro-Wilk

shapiro.test(lol$residuals)

    Shapiro-Wilk normality test

data:  lol$residuals
W = 0.95157, p-value = 0.008765

Los valores de p son menores a 0,05 entonces la dist. no es normal

Homocedasticidad

boxplot(lol$residuals~genero, col = terrain.colors(2,alpha=1))

desviaciones <- tapply(lol$residuals, genero, sd)

Comparando la desviacion maxima con la minima obtenemos una orientacion sobre la falta de homocedasticidad (>2 aproximadamente) para que sea homocedastica.

max(desviaciones) / min(desviaciones)  
[1] 1.207771

La muestra no es homocedastica

Pruebas no parametricas puesto que no se verifico todas las condiciones del ANOVA

Prueba de Barlett

bartlett.test(lol$residuals ~ genero)

    Bartlett test of homogeneity of variances

data:  lol$residuals by genero
Bartlett's K-squared = 1.1247, df = 1, p-value = 0.2889

El test de Bartlett indica que tenemos evidencia suficiente para rechazar la hipotesis nula (las varianzas son iguales).

Kruskal-Wallis

Ho: la variable respuesta es la misma en todas las poblaciones valoradas.

Ha: la variable respuesta es mayor en alguna de las poblaciones.

kruskal.test(tad, genero)

    Kruskal-Wallis rank sum test

data:  tad and genero
Kruskal-Wallis chi-squared = 0.9036, df = 1, p-value = 0.3418

Bajo la Ho el estadistico de contraste H del test de Kruskal-Wallis se distribuye como una Chi-cuadrado de grados de libertad (2-1).

Cuantil buscado

qchisq(0.05, 2-1, lower.tail = F)
[1] 3.841459

Valores del estadistico > 3.841459 estaran incluidos en la region de rechazo.

Transformacion logaritmica de los datos de la variable Nivel de Colesterol

kruskal.test(log(tad), genero) 

    Kruskal-Wallis rank sum test

data:  log(tad) and genero
Kruskal-Wallis chi-squared = 0.9036, df = 1, p-value = 0.3418

PMCMR Determinacion de los grupos que generan diferencias significativas en la variable respuesta para las distintas poblaciones.

library(PMCMR)
library(PMCMRplus)
posthoc.kruskal.nemenyi.test(tad, genero, method = "Chisq")
      Hombre
Mujer 0.35  

CONSTRUCCION DEL MODELO Y PREDICCION

Generar modelo de regresion lineal Analice la significancia de las variables y los par?metros individuales

# establecer una semilla
set.seed(123)
#Seccionar los datos , `split ()` asigna un booleano a una nueva columna basada en el SplitRatio especificado.
split <- sample.split(pacientes,SplitRatio =0.75)
train <- subset(pacientes,split==TRUE)
test <- subset(pacientes,split==FALSE)

Entrenando nuestro modelo

Vamos a construir nuestro modelo teniendo en cuenta que COLESTEROL, IMC, EDAD son los principales influyentes en la variable objetivo TAD.

model <- lm(TAD ~ COLESTEROL + IMC + EDAD, data = train)
summary(model)

Call:
lm(formula = TAD ~ COLESTEROL + IMC + EDAD, data = train)

Residuals:
     Min       1Q   Median       3Q      Max 
-16.1807  -7.1103  -0.0403   6.1576  16.3887 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 13.98084   12.72198   1.099   0.2779    
COLESTEROL   0.17422    0.03964   4.395 7.13e-05 ***
IMC          0.63067    0.37086   1.701   0.0962 .  
EDAD         0.18637    0.18131   1.028   0.3098    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 8.189 on 43 degrees of freedom
Multiple R-squared:  0.4724,    Adjusted R-squared:  0.4356 
F-statistic: 12.83 on 3 and 43 DF,  p-value: 4.014e-06

Analisis detallado de los residuos

Visualizando nuestro modelo

Permite visualizar nuestro modelo de regresion lineal trazando los residuos. La diferencia entre el valor observado de la variable dependiente (y) y el valor predicho (y) se denomina residual (e).

res <- residuals(model)
res <- as.data.frame(res)
ggplot(res,aes(res)) +  geom_histogram(fill='purple',alpha=0.5)

plot(model)

Predicciones

Probemos nuestro modelo prediciendo en nuestro conjunto de datos de prueba.

test$predicted.TAD <- predict(model,test)
pl1 <-test %>% 
  ggplot(aes(TAD,predicted.TAD)) +
  geom_point(alpha=0.5) + 
  stat_smooth(aes(colour='red')) +
  xlab('Actual value of TAD') +
  ylab('Predicted value of TAD')+
  theme_bw()
ggplotly(pl1)

Evaluemos nuestro modelo

usando Root Mean Square Error, una medida estandarizada de cuan lejos estabamos con nuestros valores predichos.

error <- test$TAD-test$predicted.TAD
rmse <- sqrt(mean(error)^2)

Resultados y conclusiones

FORMULA

TAD = 0.17422COLESTEROL+ 0.63067IMC + 0.18637EDAD

CONCLUSIONES

El Root Mean Square Error (RMSE) para nuestro modelo es 0.18629348 y los resultados pueden mejorarse aun mas utilizando la extraccion de variables y entrenando el modelo.

LS0tDQp0aXRsZTogIlBST1lFQ1RPIEZJTkFMIg0Kc3VidGl0bGU6ICJEb21lbmljYSBBbmRyYWRlLCBCcmFuZG9uIEZsb3JlcywgTWlzaGVsbCBPcm96Y28iDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQohW0RvbWVuaWNhIEFuZHJhZGUsIEJyYW5kb24gRmxvcmVzLCBNaXNoZWxsIE9yb3pjb10obW9zcXVldGVyb3MuanBnKQ0KDQojQUJTVFJBQ1QNCg0KKk1pc2hlbGwgT3JvemNvKg0KDQpNaSBub21icmUgZXMgTWlzaGVsbCBBbGVqYW5kcmEgT3JvemNvIFZlZ2EsIHRlbmdvIDIwIGHxb3MsIG5hY2kgZW4gUXVpdG8gZWwgMTIgZGUgRmVicmVybyBkZSAxOTk4LCBhY3R1YWxtZW50ZSBtZSBlbmN1ZW50cm8gY3Vyc2FuZG8gNXRvIHNlbWVzdHJlIGRlIGxhIGNhcnJlcmEgZGUgSW5nZW5pZXJpYSBlbiBCaW90ZWNub2xvZ2lhIGVuIGxhIFVuaXZlcnNpZGFkIGRlIGxhcyBGdWVyemFzIEFybWFkYXMgRVNQRS4gRGlzZnJ1dG8gbGVlciwgdmVyIHBlbGljdWxhcywgbGEgZGFuemEsIGZ1dGJvbCB5IHBhc2FyIHRpZW1wbyBjb24gYW1pZ29zLg0KDQoqQnJhbmRvbiAgRmxvcmVzKg0KDQpNaSBub21icmUgZXMgQnJhbmRvbiBBbGV4YW5kZXIgRmxvcmVzIFJlYWxwZSwgdGVuZ28gMjEgYfFvcywgbmFjaSBlbiBsYSBwcm92aW5jaWEgZGUgSW1iYWJ1cmEgZXNwZWNlZmljYW1lbnRlIGVuIGxhIGNpdWRhZCBkZSBJYmFycmEuIFNveSBlc3R1ZGlhbnRlIGRlIGxhIGNhcnJlcmEgSW5nZW5pZXJpYSBlbiBCaW90ZWNub2xvZ2lhIGRlIGxhIFVuaXZlcnNpZGFkIGRlIGxhcyBGdWVyemFzIEFybWFkYXMgLSBFU1BFLiBFbiBtaSB0aWVtcG8gbGlicmUgbWUgZ3VzdGEgbGVlciwgdmVyIHNlcmllcyB5IGNhbnRhci4gDQoNCipEb21lbmljYSBBbmRyYWRlKg0KDQpNaSBub21icmUgZXMgRG9tZW5pY2EgU29maWEgQW5kcmFkZSBOaWNvbGFsZGUsIHRlbmdvIDIwIGHxb3MsIG5hY2kgZW4gbGEgcHJvdmluY2lhIGRlIFBpY2hpbmNoYSwgZW4gUXVpdG8sIHVuIGhlcm1vc28gMDkgZGUgRmVicmVybyBkZSAxOTk4LiBNZSBndXN0YSBwYXNhciB0aWVtcG8gY29uIG1pIHBlcnJvIHF1ZSBzZSBsbGFtYSBQZXJjeSB5IGVzIGdvcmRpdG8sIGVzdHVkaW8gSW5nZW5pZXJpYSBlbiBCaW90ZWNub2xvZ2lhIGVuIGxhIFVuaXZlcnNpZGFkIGRlIGxhcyBGdWVyemFzIEFybWFkYXMsIG1lIGFwYXNpb25hIG1pIGNhcnJlcmEgeSBlc3Blcm8gZXNwZWNpYWxpemFybWUgZW4gbGEgcGFydGUgbWVkaWNhLiBTYWx1ZG9zDQoNCiNBTkFMSVNJUyBFU1RBRElTVElDTw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0NCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGNvcnJwbG90KSANCmxpYnJhcnkobWxiZW5jaCkgDQpsaWJyYXJ5KEFtZWxpYSkgDQpsaWJyYXJ5KHBsb3RseSkgDQpsaWJyYXJ5KHJlc2hhcGUyKSANCmxpYnJhcnkoY2FyZXQpICANCmxpYnJhcnkoY2FUb29scykgDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShQTUNNUikNCmxpYnJhcnkoUE1DTVJwbHVzKQ0KYGBgDQojIEJBU0UgREUgREFUT1MNCg0KKipEZXNjcmlwY2lvbiBkZSBsYSBiYXNlIGRlIGRhdG9zKioNCg0KUGFyYSBsYSByZWFsaXphY2lvbiBkZWwgcHJveWVjdG8gc2UgaGEgZXNjb2dpZG8gbGEgYmFzZSBkZSBkYXRvcyAicGFjaWVudGVzIiwgbGEgY3VhbCBjb250aWVuZSBsYXMgc2lndWllbnRlcyB2YXJpYWJsZXM6DQoNClBhY2llbnRlOiBDYXJhY3Rlcg0KDQpFZGFkOiBFbnRlcm8NCg0KQ29sZXN0ZXJvbDogTnVtZXJpY2ENCg0KSU1DIChJbmRpY2UgZGUgbWFzYSBjb3Jwb3JhbCk6TnVtZXJpY28NCg0KVEFEIChUZW5zaW9uIGFydGVyaWFsIGRpc3RvbGljYSk6TnVtZXJpY28NCg0KR2VuZXJvOkZhY3Rvcg0KDQoqKkxlY3R1cmEgZGUgbGEgYmFzZSBkZSBkYXRvcywgbm9tYnJlcyBkZSBjb2x1bW5hcyBhZGVjdWFkb3MsIGRlZmluaXIgdGlwbyBkZSB2YXJpYmxlcyB5IGV0aXF1ZXRhcyBhIGxhcyB0aXBvIGZhY3RvcioqDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBMZWN0dXJhIGRlIGJhc2UgZGUgZGF0b3MNCmxpYnJhcnkocmVhZHhsKQ0KcGFjaWVudGVzIDwtIHJlYWRfZXhjZWwoIn4vRVNQRS9jdXJzbyBSL1Byb3llY3RvIGZpbmFsL3BhY2llbnRlcy54bHN4IiwgDQogICAgc2tpcCA9IDIpDQpwYWNpZW50ZXM8LWFzLmRhdGEuZnJhbWUocGFjaWVudGVzKQ0KYGBgDQoNCkxvcyBkYXRvcyBkZSAicGFjaWVudGVzIiBzZSBhZGVjdWFuIGEgbG9zIG5vbWJyZXMgY29ycmVzcG9uZGllbnRlcyBkZSBzdXMgdmFyaWFibGVzDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KDQojIERlZmluaXIgdmFyaWFibGVzIHkgZXRpcXVldGFyIGxhcyBkZSB0aXBvIGZhY3Rvcg0KDQpwYWNpZW50ZXMkUEFDSUVOVEU8LWFzLmNoYXJhY3RlcihwYWNpZW50ZXMkUEFDSUVOVEUpDQpwYWNpZW50ZXMkRURBRDwtYXMubnVtZXJpYyhwYWNpZW50ZXMkRURBRCkNCnBhY2llbnRlcyRJTUM8LWFzLm51bWVyaWMocGFjaWVudGVzJElNQykNCnBhY2llbnRlcyRUQUQ8LWFzLm51bWVyaWMocGFjaWVudGVzJFRBRCkNCnBhY2llbnRlcyRHRU5FUk88LWFzLmZhY3RvcihwYWNpZW50ZXMkR0VORVJPKQ0KYGBgDQoqKkFuYWxpc2lzIGV4cGxvcmF0b3JpbyBkZSBkYXRvcyoqDQoNCg0KKlNlIG11ZXN0cmEgYSBjb250aW51YWNpb24gZWwgc3RyIGRlIGxhIGJhc2UgZGUgZGF0b3MgeSBlbCByZXN1bWVuIGRlIGxhIG1pc21hKg0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnN0cihwYWNpZW50ZXMpDQpgYGANCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc3VtbWFyeShwYWNpZW50ZXMpDQpgYGANCioqR2VuZXJhciBkaWFncmFtYXMgZGUgY2FqYXMgeSBkaWFncmFtYXMgZGUgYmFycmFzIHBhcmEgbGFzIHZhcmlhYmxlcyoqDQoNCkRJQUdSQU1BIERFIENBSkENCg0KRGlhZ3JhbWEgZGUgY2FqYSBwYXJhIGxhIHZhcmlhYmxlIEVEQUQ6DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KYm94cGxvdChwYWNpZW50ZXMkRURBRCx4bGFiPSJFZGFkIGRlIGxvcyBwYWNpZW50ZXMiLGNvbD0icGluayIscGFycyA9IGxpc3QoYm94d2V4ID0gMC44LCBzdGFwbGV3ZXggPSAwLjUsIG91dHdleCA9IDAuNSkpDQpgYGANClNlIHB1ZWRlIG9ic2VydmFyIHF1ZSBsYSBtZWRpYSBhcHJveGltYWRhIGRlIGxhIGVkYWQgZGUgbG9zIHBhY2llbnRlcyBlc3R1ZGlhZG9zIGVzIDU2IGHxb3MNCg0KRGlhZ3JhbWEgZGUgY2FqYSBwYXJhIGxhIHZhcmlhYmxlIENPTEVTVEVST0w6DQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCg0KYm94cGxvdChwYWNpZW50ZXMkQ09MRVNURVJPTCx4bGFiPSJDb2xlc3Rlcm9sIGRlIGxvcyBwYWNpZW50ZXMiLGNvbD0iYmx1ZSIscGFycyA9IGxpc3QoYm94d2V4ID0gMC44LCBzdGFwbGV3ZXggPSAwLjUsIG91dHdleCA9IDAuNSkpDQpgYGANCg0KRWwgZ3JhZmljbyBheXVkYSBkZXRlcm1pbmFyIHF1ZSBsYSBtZWRpYSBkZWwgY29sZXN0ZXJvbCBlbiBsb3MgcGFjaWVudGVzIGVzIDIzMCBhZGVtYXMgcG9zZWUgdW4gdmFsb3IgYXRpcGljbyBlbCBjdWFsIHJlYmFzYSBlbCBjdWFydG8gY3VhcnRpbCB5IGVzIGFwcm94aW1hZG8gYSAzMjAuDQoNCkRpYWdyYW1hIGRlIGNhamEgcGFyYSB2YXJpYWJsZSBJTUMgbyBJbmRpY2UgZGUgTWFzYSBDb3Jwb3JhbDoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KYm94cGxvdChwYWNpZW50ZXMkSU1DLHhsYWI9IkluZGljZSBkZSBtYXNhIGNvcnBvcmFsIGRlIGxvcyBwYWNpZW50ZXMiLGNvbD0icHVycGxlIikNCmBgYA0KRW4gZWwgZGlhZ3JhbWEgZGUgY2FqYSBzZSBsb2dyYSBpZGVudGlmaWNhciBxdWUgbGEgbWVkaWEgZW4gZWwgaW5kaWNlIGRlIGxhIG1hc2EgY29ycG9yYWwgZGUgbG9zIHBhY2llbnRlcyBlcyBhcHJveGltYWRhbWVudGUgMjYsIGFkZW1wYXMgc2Ugb2JzZXJ2YSBncmFuIHZhcmlhY2k/P24gZW4gbG9zIGRhdG9zDQoNCkRJQUdSQU1BIERFIEJBUlJBUw0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmJhcnBsb3QocGFjaWVudGVzJFRBRCx4bGFiID0gInBhY2llbnRlcyIseWxhYiA9ICJUZW5zaW9uIGFydGVyaWFsIGRpYXN0b2xpY2EiLG5hbWVzLmFyZyA9IHJvd25hbWVzKHBhY2llbnRlcyksbWFpbiA9ICJEaWFncmFtYSBkZSBiYXJyYXMiLGNvbCA9aGVhdC5jb2xvcnMoNyxhbHBoYT0xKSkNCg0KYGBgDQoNCioqQ29ycmVsYWNpb24gZW50cmUgdmFyaWFibGUgZGVwZW5kaWVudGUgeSB2YXJpYWJsZXMgaW5kZXBlbmRpZW50ZXMqKg0KDQpMSU1QSUVaQSBERSBEQVRPUw0KDQpTZSBhc2lnbm8gYSBsb3MgZGF0b3MgTkEsIGVsIHZhbG9yIGRlIGxhIG1lZGlhIHJlc3BlY3RpdmEgcGFyYSBjYWRhIGNvbHVtbmEgZGUgbGEgYmFzZSBkZSBkYXRvcyBjb24gbGEgZmluYWxpZGFkIGRlIHF1ZSBubyBkaWZpZXJhbiBsb3MgcmVzdWx0YWRvcy4NCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpwYWNpZW50ZXMkVEFEW2lzLm5hKHBhY2llbnRlcyRUQUQpXT04MS42NQ0KcGFjaWVudGVzJFBBQ0lFTlRFW2lzLm5hKHBhY2llbnRlcyRQQUNJRU5URSldPTANCnBhY2llbnRlcyRDT0xFU1RFUk9MW2lzLm5hKHBhY2llbnRlcyRDT0xFU1RFUk9MKV09MA0KcGFjaWVudGVzJElNQ1tpcy5uYShwYWNpZW50ZXMkSU1DKV09MjUuNDcNCg0KYGBgDQoNClNlIHZlcmlmaWNhIHF1ZSBsYSBiYXNlIGRlIGRhdG9zIHNlIGVuY3VlbnRyZSBsaWJyZSBkZSBOQQ0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCm1pc3NtYXAocGFjaWVudGVzLGNvbD1jKCd5ZWxsb3cnLCdibGFjaycpLHkuYXQ9MSx5LmxhYmVscz0nJyxsZWdlbmQ9VFJVRSkNCmBgYA0KU2UgY29tcHJvYm8gcXVlIG5vIGV4aXN0ZW4gZGF0b3MgcGVyZGlkb3MgZW4gbGEgYmFzZSBkZSBkYXRvcyBxdWUgc2UgZXN0YSBlbXBsZWFuZG8NCg0KKkNvcnJlbGFjaW9uKg0KDQpMYSBjb3JyZWxhY2lvbiBwZXJtaXRlIGRldGVybWluYXIgbGEgbWVkaWRhIGVuIHF1ZSBkb3MgdmFyaWFibGVzIHRpZW5lbiB1bmEgcmVsYWNpb24gbGluZWFsIGVudHJlIHNpLg0KDQpgYGB7cn0NCmNvcnJwbG90KGNvcihzZWxlY3QocGFjaWVudGVzLC1jKFBBQ0lFTlRFLEdFTkVSTykpKSkNCmBgYA0KDQpMYSB0ZW5zaW9uIGFydGVyaWFsIGRpYXN0b2xpY2EgbyAgKipUQUQqKiBhdW1lbnRhIGN1YW5kbyBoYXkgYXVtZW50byBlbiBDT0xFU1RFUk9MIChhbHRvKSwgSU1DIChtZWRpbykgeSBFREFEIChiYWphKS4NCg0KKkdyYWZpY29zIGRlIGRlbnNpZGFkOioNCg0KR3JhZmljbyBkZSBkZW5zaWRhZCBjb24gZ2dwbG90Og0KDQpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBhY2llbnRlcyAlPiUgDQogIGdncGxvdChhZXMoVEFEKSkgKw0KICBzdGF0X2RlbnNpdHkoKSArIA0KICB0aGVtZV9idygpDQpgYGANCkdyYWZpY28gZGUgZGVuc2lkYWQgY29uIHBsb3RseToNCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpnZ3Bsb3RseShwYWNpZW50ZXMgJT4lIA0KICBnZ3Bsb3QoYWVzKFRBRCkpICsNCiAgc3RhdF9kZW5zaXR5KCkgKyANCiAgdGhlbWVfYncoKSkNCmBgYA0KTGFzIHZpc3VhbGl6YWNpb25lcyBhbnRlcmlvcmVzIHJldmVsYW4gcXVlIGxhcyBkZW5zaWRhZGVzIG1heGltYXMgZGUgVEFEIGVzdGFuIGVudHJlIDcwIHkgODANCg0KKipFZmVjdG8gZGUgbGFzIHZhcmlhYmxlcyoqDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KcGFjaWVudGVzICU+JQ0KICBzZWxlY3QoYyhFREFELCBJTUMsIENPTEVTVEVST0wsIFRBRCkpICU+JQ0KICBtZWx0KGlkLnZhcnMgPSAiVEFEIikgJT4lDQogIGdncGxvdChhZXMoeCA9IHZhbHVlLCB5ID0gVEFELCBjb2xvdXIgPSB2YXJpYWJsZSkpICsNCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNykgKw0KICBzdGF0X3Ntb290aChhZXMoY29sb3VyID0gImJsYWNrIikpICsNCiAgZmFjZXRfd3JhcCh+dmFyaWFibGUsIHNjYWxlcyA9ICJmcmVlIiwgbmNvbCA9IDMpICsNCiAgbGFicyh4ID0gIlZhcmlhYmxlIFZhbHVlIiwgeSA9ICJUZW5zaW9uIGFydGVyaWFsIGRpc3RvbGljYSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KTG9zIHJlc3VsdGFkb3MgZGVsIGdyYWZpY28gYW50ZXJpb3IgZXN0YW4gZW4gY29ycmVsYWNpb24gY29uIGVsIGNvcnJwbG90Lg0KDQojQW5hbGlzaXMgQU5PVkENCipBTk9WQSoNCg0KKipDb25zaWRlcmUgdW5hIHZhcmlhYmxlIGNhdGVnb3JpY2EgeSByZWFsaWNlIHVuIGFuYWxpc2lzIEFOT1ZBIChjb21vIGVsIHJldmlzYWRvIGVuIGNsYXNlKSwgaW5jbHV5YSByZXN1bHRhZG9zIHkgY29uY2x1c2lvbiBhbCBmaW5hbCoqDQoNCkxhIGhpcG90ZXNpcyBudWxhIGVzIHF1ZSBsYXMgbWVkaWFzIGRlIGxvcyB2YWxvcmVzIGRlIFRBRCBkZSBob21icmVzIHkgbXVqZXJlcyBzb24gaWd1YWxlcyB5IGxhIGhpcG90ZXNpcyBhbHRlcm5hdGl2YSBxdWUgbGFzIG1lZGlhcyBkZSBlc3RvcyBncnVwb3Mgc29uIGRpc3RpbnRhcy4NCg0KIyMjIEFOT1ZBIHkgcHJ1ZWJhcyBwb3N0LWhvYy4NCg0KKlBldGljaW9uIGRlIHVuIEFOT1ZBKg0KDQpgYGB7cn0NCnRhZDwtcGFjaWVudGVzJFRBRA0KZ2VuZXJvPC1wYWNpZW50ZXMkR0VORVJPDQpsb2w9YW92KGxtKHRhZH4gZ2VuZXJvKSkNCmBgYA0KKlJlc3VtZW4gZGUgbGEgdGFibGEgZGVsIEFOT1ZBKg0KDQpgYGB7cn0NCnN1bW1hcnkobG9sKQ0KDQpgYGANCipFbGVtZW50b3MgZ2VuZXJhZG9zIGVuIGVsIEFOT1ZBOioNCmBgYHtyfQ0KbmFtZXMobG9sKQ0KYGBgDQoNCjEuIEdyYWRvcyBkZSBsaWJlcnRhZCBkZWwgZmFjdG9yOiAyLTENCg0KMi4gR3JhZG9zIGRlIGxpYmVydGFkIHJlc2lkdWFsZXM6IDcwLTINCg0KMy4gU3VtYSBkZSBjdWFkcmFkb3MgZGUgbG9zIGdydXBvczogMTU1DQoNCjQuIFN1bWEgZGUgY3VhZHJhZG9zIGRlbCBlcnJvcjogODU2NQ0KDQo1LiBNZWRpYSBkZSBsYSBzdW1hIGRlIGN1YWRyYWRvcyBkZSBsb3MgZ3J1cG9zOiAxNTQuNyANCg0KNi4gTWVkaWEgZGUgbGEgc3VtYSBkZSBjdWFkcmFkb3MgZGVsIGVycm9yOiAxMjYuMA0KDQo3LiBFbCB2YWxvciBkZWwgZXN0YWRpc3RpY28gRjogMS4yMjgNCg0KOC4gVmFsb3IgZGUgUDogMC4yMjcyDQoNCjkuIE5pdmVsIGRlIHNpZ25pZmljYW5jaWEgY29uc2lkZXJhZG86IDAuMDUNCg0KKkN1YW50aWwgYnVzY2FkbyoNCg0KYGBge3J9DQpxZigwLjA1LCAyLTEsIDcwLTIsIGxvd2VyLnRhaWwgPSBGKQ0KYGBgDQpWYWxvcmVzIGRlbCBlc3RhZGlzdGljbyA+IDMuOTgxODk2IGVzdGFyYW4gaW5jbHVpZG9zIGVuIGxhIHJlZ2lvbiBkZSByZWNoYXpvLkVuIGVzdGUgY2FzbyBlbCB2YWxvciBGIHF1ZSBzZSBvYnR1dm8gZXMgZGUgMS4yMjguDQoNCipFc3RpbWFjaW9uIGRlIGxhIHZhcmlhbnphIGNvbXVuIGRlIGxvcyBkYXRvcyoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbWVkaWEgPC0gbWVhbih0YWRbZ2VuZXJvPT0iSG9tYnJlIl0pIA0KdmFsb3JfdCA8LSBwdCgwLjA1LzIsIDcwIC0gMikgDQpzcCA8LSBzcXJ0KDEyNikgICNkZXN2aWFjaT9uIHQ/cGljYSBkZSBsYSB2YXJpYW56YSBtdWVzdHJhbCBjb20/bg0KZWUgIDwtIHZhbG9yX3QgKiAoc3AvIHNxcnQoNDEpKSAgI2Vycm9yIGRlIGVzdGltYWNpP24gDQptZWRpYQ0KYGBgDQoNCipJbnRlcnZhbG9zIGRlIGNvbmZpYW56YSBwYXJhIGxhcyBtZWRpYXMgZGUgbGEgdGVuc2lvbiBhcnRlcmlhbCBkaWFzdG9saWNhIGRlIGxvcyBwYWNpZW50ZXMuKg0KDQpMaW1pdGUgc3VwZXJpb3INCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQptZWRpYStlZQ0KYGBgDQpMaW1pdGUgSW5mZXJpb3INCg0KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQptZWRpYS1lZQ0KYGBgDQoNCiMjI1Rlc3QgSFNEIGRlIFR1a2V5DQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KaW50ZXJ2YWxzID1UdWtleUhTRChsb2wpDQppbnRlcnZhbHMNCg0KYGBgDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBwYWdlZC5wcmludD1GQUxTRX0NCnBsb3QoaW50ZXJ2YWxzKQ0KYGBgDQoNCiMjIyBWYWxpZGFjaW9uIGRlbCBNb2RlbG8gQU5PVkENCg0KKipJbmRlcGVuZGVuY2lhKioNCmBgYHtyfQ0KcGxvdChsb2wkcmVzaWR1YWxzLHlsYWIgPSAiUmVzaWR1b3MiLHhsYWIgPSAiUGFjaWVudGVzIikNCmBgYA0KDQoqKk5vcm1hbGlkYWQqKg0KDQpgYGB7cn0NCnN1bW1hcnkobG9sJHJlc2lkdWFscykNCmJveHBsb3QobG9sJHJlc2lkdWFscyxjb2wgPSAieWVsbG93IikNCmBgYA0KYGBge3J9DQpoaXN0KGxvbCRyZXNpZHVhbHMsIGNvbD1jbS5jb2xvcnMoNCxhbHBoYSA9IDEpKQ0KYGBgDQoNCmBgYHtyfQ0KcXFub3JtKGxvbCRyZXNpZHVhbHMpIA0KcXFsaW5lKGxvbCRyZXNpZHVhbHMpDQoNCmBgYA0KDQoqVGVzdCBkZSBTaGFwaXJvLVdpbGsqDQpgYGB7cn0NCnNoYXBpcm8udGVzdChsb2wkcmVzaWR1YWxzKQ0KYGBgDQpMb3MgdmFsb3JlcyBkZSBwIHNvbiBtZW5vcmVzIGEgMCwwNSBlbnRvbmNlcyBsYSBkaXN0LiBubyBlcyBub3JtYWwNCg0KKipIb21vY2VkYXN0aWNpZGFkKioNCg0KYGBge3J9DQpib3hwbG90KGxvbCRyZXNpZHVhbHN+Z2VuZXJvLCBjb2wgPSB0ZXJyYWluLmNvbG9ycygyLGFscGhhPTEpKQ0KYGBgDQpgYGB7cn0NCmRlc3ZpYWNpb25lcyA8LSB0YXBwbHkobG9sJHJlc2lkdWFscywgZ2VuZXJvLCBzZCkNCmBgYA0KDQpDb21wYXJhbmRvIGxhIGRlc3ZpYWNpb24gbWF4aW1hIGNvbiBsYSBtaW5pbWEgb2J0ZW5lbW9zIHVuYSBvcmllbnRhY2lvbiBzb2JyZSBsYSBmYWx0YSBkZSBob21vY2VkYXN0aWNpZGFkICg+MiBhcHJveGltYWRhbWVudGUpIHBhcmEgcXVlIHNlYSBob21vY2VkYXN0aWNhLg0KDQpgYGB7cn0NCm1heChkZXN2aWFjaW9uZXMpIC8gbWluKGRlc3ZpYWNpb25lcykgIA0KYGBgDQpMYSBtdWVzdHJhIG5vIGVzIGhvbW9jZWRhc3RpY2EgDQoNCiMjIyBQcnVlYmFzIG5vIHBhcmFtZXRyaWNhcyBwdWVzdG8gcXVlIG5vIHNlIHZlcmlmaWNvIHRvZGFzIGxhcyBjb25kaWNpb25lcyBkZWwgQU5PVkENCg0KKipQcnVlYmEgZGUgQmFybGV0dCoqDQoNCmBgYHtyfQ0KYmFydGxldHQudGVzdChsb2wkcmVzaWR1YWxzIH4gZ2VuZXJvKQ0KYGBgDQpFbCB0ZXN0IGRlIEJhcnRsZXR0IGluZGljYSBxdWUgdGVuZW1vcyBldmlkZW5jaWEgc3VmaWNpZW50ZSBwYXJhIHJlY2hhemFyIGxhIGhpcG90ZXNpcyBudWxhIChsYXMgdmFyaWFuemFzIHNvbiBpZ3VhbGVzKS4NCg0KKipLcnVza2FsLVdhbGxpcyoqDQoNCioqSG8qKjogbGEgdmFyaWFibGUgcmVzcHVlc3RhIGVzIGxhIG1pc21hIGVuIHRvZGFzIGxhcyBwb2JsYWNpb25lcyB2YWxvcmFkYXMuDQoNCioqSGEqKjogbGEgdmFyaWFibGUgcmVzcHVlc3RhIGVzIG1heW9yIGVuIGFsZ3VuYSBkZSBsYXMgcG9ibGFjaW9uZXMuDQpgYGB7cn0NCmtydXNrYWwudGVzdCh0YWQsIGdlbmVybykNCmBgYA0KQmFqbyBsYSBIbyBlbCBlc3RhZGlzdGljbyBkZSBjb250cmFzdGUgSCBkZWwgdGVzdCBkZSBLcnVza2FsLVdhbGxpcyBzZSBkaXN0cmlidXllIGNvbW8gdW5hIENoaS1jdWFkcmFkbyBkZSBncmFkb3MgZGUgbGliZXJ0YWQgKDItMSkuDQoNCipDdWFudGlsIGJ1c2NhZG8qDQpgYGB7cn0NCnFjaGlzcSgwLjA1LCAyLTEsIGxvd2VyLnRhaWwgPSBGKQ0KYGBgDQpWYWxvcmVzIGRlbCBlc3RhZGlzdGljbyA+IDMuODQxNDU5IGVzdGFyYW4gaW5jbHVpZG9zIGVuIGxhIHJlZ2lvbiBkZSByZWNoYXpvLg0KDQoqVHJhbnNmb3JtYWNpb24gbG9nYXJpdG1pY2EgZGUgbG9zIGRhdG9zIGRlIGxhIHZhcmlhYmxlIE5pdmVsIGRlIENvbGVzdGVyb2wqDQpgYGB7cn0NCmtydXNrYWwudGVzdChsb2codGFkKSwgZ2VuZXJvKSANCmBgYA0KDQoqUE1DTVIqDQpEZXRlcm1pbmFjaW9uIGRlIGxvcyBncnVwb3MgcXVlIGdlbmVyYW4gZGlmZXJlbmNpYXMgc2lnbmlmaWNhdGl2YXMgZW4gbGEgdmFyaWFibGUgcmVzcHVlc3RhIHBhcmEgbGFzIGRpc3RpbnRhcyBwb2JsYWNpb25lcy4NCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShQTUNNUikNCmxpYnJhcnkoUE1DTVJwbHVzKQ0KcG9zdGhvYy5rcnVza2FsLm5lbWVueWkudGVzdCh0YWQsIGdlbmVybywgbWV0aG9kID0gIkNoaXNxIikNCmBgYA0KDQojQ09OU1RSVUNDSU9OIERFTCBNT0RFTE8gWSBQUkVESUNDSU9ODQoNCioqR2VuZXJhciBtb2RlbG8gZGUgcmVncmVzaW9uIGxpbmVhbCoqDQoqKkFuYWxpY2UgbGEgc2lnbmlmaWNhbmNpYSBkZSBsYXMgdmFyaWFibGVzIHkgbG9zIHBhcj9tZXRyb3MgaW5kaXZpZHVhbGVzKioNCmBgYHtyfQ0KIyBlc3RhYmxlY2VyIHVuYSBzZW1pbGxhDQpzZXQuc2VlZCgxMjMpDQoNCiNTZWNjaW9uYXIgbG9zIGRhdG9zICwgYHNwbGl0ICgpYCBhc2lnbmEgdW4gYm9vbGVhbm8gYSB1bmEgbnVldmEgY29sdW1uYSBiYXNhZGEgZW4gZWwgU3BsaXRSYXRpbyBlc3BlY2lmaWNhZG8uDQoNCnNwbGl0IDwtIHNhbXBsZS5zcGxpdChwYWNpZW50ZXMsU3BsaXRSYXRpbyA9MC43NSkNCg0KdHJhaW4gPC0gc3Vic2V0KHBhY2llbnRlcyxzcGxpdD09VFJVRSkNCnRlc3QgPC0gc3Vic2V0KHBhY2llbnRlcyxzcGxpdD09RkFMU0UpDQpgYGANCkVudHJlbmFuZG8gbnVlc3RybyBtb2RlbG8NCg0KVmFtb3MgYSBjb25zdHJ1aXIgbnVlc3RybyBtb2RlbG8gdGVuaWVuZG8gZW4gY3VlbnRhIHF1ZSBDT0xFU1RFUk9MLCBJTUMsIEVEQUQgc29uIGxvcyBwcmluY2lwYWxlcyBpbmZsdXllbnRlcyBlbiBsYSB2YXJpYWJsZSBvYmpldGl2byBUQUQuDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHBhZ2VkLnByaW50PUZBTFNFfQ0KbW9kZWwgPC0gbG0oVEFEIH4gQ09MRVNURVJPTCArIElNQyArIEVEQUQsIGRhdGEgPSB0cmFpbikNCnN1bW1hcnkobW9kZWwpDQpgYGANCg0KDQoNCioqQW5hbGlzaXMgZGV0YWxsYWRvIGRlIGxvcyByZXNpZHVvcyoqDQoNCg0KVmlzdWFsaXphbmRvIG51ZXN0cm8gbW9kZWxvDQoNClBlcm1pdGUgdmlzdWFsaXphciBudWVzdHJvIG1vZGVsbyBkZSByZWdyZXNpb24gbGluZWFsIHRyYXphbmRvIGxvcyByZXNpZHVvcy4gTGEgZGlmZXJlbmNpYSBlbnRyZSBlbCB2YWxvciBvYnNlcnZhZG8gZGUgbGEgdmFyaWFibGUgZGVwZW5kaWVudGUgKHkpIHkgZWwgdmFsb3IgcHJlZGljaG8gKHkpIHNlIGRlbm9taW5hIHJlc2lkdWFsIChlKS4NCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9DQpyZXMgPC0gcmVzaWR1YWxzKG1vZGVsKQ0KcmVzIDwtIGFzLmRhdGEuZnJhbWUocmVzKQ0KZ2dwbG90KHJlcyxhZXMocmVzKSkgKyAgZ2VvbV9oaXN0b2dyYW0oZmlsbD0ncHVycGxlJyxhbHBoYT0wLjUpDQpgYGANCmBgYHtyfQ0KcGxvdChtb2RlbCkNCmBgYA0KUHJlZGljY2lvbmVzDQoNClByb2JlbW9zIG51ZXN0cm8gbW9kZWxvIHByZWRpY2llbmRvIGVuIG51ZXN0cm8gY29uanVudG8gZGUgZGF0b3MgZGUgcHJ1ZWJhLg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9DQp0ZXN0JHByZWRpY3RlZC5UQUQgPC0gcHJlZGljdChtb2RlbCx0ZXN0KQ0KDQpwbDEgPC10ZXN0ICU+JSANCiAgZ2dwbG90KGFlcyhUQUQscHJlZGljdGVkLlRBRCkpICsNCiAgZ2VvbV9wb2ludChhbHBoYT0wLjUpICsgDQogIHN0YXRfc21vb3RoKGFlcyhjb2xvdXI9J3JlZCcpKSArDQogIHhsYWIoJ0FjdHVhbCB2YWx1ZSBvZiBUQUQnKSArDQogIHlsYWIoJ1ByZWRpY3RlZCB2YWx1ZSBvZiBUQUQnKSsNCiAgdGhlbWVfYncoKQ0KDQpnZ3Bsb3RseShwbDEpDQpgYGANCg0KRXZhbHVlbW9zIG51ZXN0cm8gbW9kZWxvDQoNCnVzYW5kbyBSb290IE1lYW4gU3F1YXJlIEVycm9yLCB1bmEgbWVkaWRhIGVzdGFuZGFyaXphZGEgZGUgY3VhbiBsZWpvcyBlc3RhYmFtb3MgY29uIG51ZXN0cm9zIHZhbG9yZXMgcHJlZGljaG9zLg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgcGFnZWQucHJpbnQ9RkFMU0V9DQplcnJvciA8LSB0ZXN0JFRBRC10ZXN0JHByZWRpY3RlZC5UQUQNCnJtc2UgPC0gc3FydChtZWFuKGVycm9yKV4yKQ0KYGBgDQoNCioqUmVzdWx0YWRvcyB5IGNvbmNsdXNpb25lcyoqDQoNCkZPUk1VTEENCg0KVEFEID0gMC4xNzQyMkNPTEVTVEVST0wrIDAuNjMwNjdJTUMgKyAwLjE4NjM3RURBRA0KDQpDT05DTFVTSU9ORVMNCg0KRWwgUm9vdCBNZWFuIFNxdWFyZSBFcnJvciAoUk1TRSkgcGFyYSBudWVzdHJvIG1vZGVsbyBlcyAwLjE4NjI5MzQ4IHkgbG9zIHJlc3VsdGFkb3MgcHVlZGVuIG1lam9yYXJzZSBhdW4gbWFzIHV0aWxpemFuZG8gbGEgZXh0cmFjY2lvbiBkZSB2YXJpYWJsZXMgeSBlbnRyZW5hbmRvIGVsIG1vZGVsby4NCg==