Elaborado por: Eliana Poveda

1. Predicción de los precios de las acciones. Analizar el comportamiento de los precios de las Acciones de Ecopetrol según la variación del precio del barril de petróleo WTI producido en Colombia. Se tienen los siguientes precios.

library(readxl)
datos=ecopetrol <- read_excel("C:/Users/asus/Desktop/ecopetrol.xlsx")
View(ecopetrol)
cor(datos$Precio_accion,datos$Precio_barril)
[1] 0.7074373

Resultado: El coeficiente de correlación sugiere que hay una relacion líneal fuerte y positiva entre las variables.Se observa que a mayor precio_acciones el precio_barril aumenta y su relación es positiva de acuerdo con el coeficiente de correlación de Pearson (0,7074).

ggplot(datos,aes(x=Precio_accion, y=Precio_barril))+geom_point()+theme_bw()+
  geom_smooth(method = "lm")
`geom_smooth()` using formula 'y ~ x'

En la grafica se observa que hay una relación entre esta dos variables, que inicialmente pareciera no ser necesariamente lineal

Ajuste del modelo

Punto a.Proponga un modelo de regresión lineal simple que permita predecir el valor de las Acciones de Ecopetrol con base en el Precio del barril de petróleo en Colombia. Indique la ecuación de regresión y el valor delR2.La regresión se estructuraría de la siguiente forma:

Precio_accion=β0+β1Precio_barril+ϵ

mod=lm(Precio_accion~Precio_barril,data = datos)
resumen=summary(mod)
resumen

Call:
lm(formula = Precio_accion ~ Precio_barril, data = datos)

Residuals:
   Min     1Q Median     3Q    Max 
-59.90 -40.74 -15.94  33.40 136.82 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)   
(Intercept)    177.768    232.828   0.764  0.45627   
Precio_barril   26.192      6.542   4.004  0.00102 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 57.13 on 16 degrees of freedom
Multiple R-squared:  0.5005,    Adjusted R-squared:  0.4692 
F-statistic: 16.03 on 1 and 16 DF,  p-value: 0.001024

resultado: El valor del R cuadrado = 0.50 significa que la variable precio_barril explica el 50% del precio de las acciones.

**B. Pruebe la significancia del modelo propuesto en “a)” plantee las hipótesis respectivas y use el concepto de Valor _p para tomar la decisión sobre las hipótesis. Use α = 0.05**

Resultado: El modelo de regresión propuesto para predecir el valor de las acciones de ecopetrol es precioacción=177.77+(26.19∗preciobarril) en donde β0=177 y β1=26.19 Ho = El modelo no es significativo Ha = El modelo si es significativo

resumen$coefficients[2, ]
    Estimate   Std. Error      t value     Pr(>|t|) 
26.192134618  6.541913749  4.003741966  0.001023938 

Teniendo en cuenta que el valor_p es igual a 0.001023938 < 0.05 = α, se debe rechazar Ho y aceptar Ha, con lo cual se concluye que el valor de la pendiente es un predictor significativo para la ecuación del precio de la acción de Ecopetrol.

Punto C. Interprete los coeficientes del modelo propuesto en “a)

mod$coefficients
  (Intercept) Precio_barril 
    177.76779      26.19213 

Resultado: Según el modelo propuesto, por cada dolar adicional que cueste un barril de petroleo el precio de la acción de Ecopetrol aumenta en el 26,19 pesos colombianos. También, consierando B0 si el precio del barril de petroleo fuera 0 entonces el precio de las acciones de Ecopetrol serían de 177 pesos.

Punto D. Haga un análisis de los residuos. ¿Qué supuesto no se cumple?

e=mod$residuals
par(mfrow=c(2,2))
plot(mod)

shapiro.test(mod$residuals)

    Shapiro-Wilk normality test

data:  mod$residuals
W = 0.89259, p-value = 0.04276

Resultado: Tanto lo que muestra la grafica Normal QQ como la prueba shapiro se concluye que los residuos no siguen una distribución normal. No se cumple la normalidad. También la graficas de residuales vs ajustados muestran que los residuos no se comportan de forma aleatoria como se esperaría. En conclusión no se cumplen los supuestos relacionados con la normalidad y la aleatoriedad de los residuos. Considerando los resultados obtenidos en el modelo propuesto, el uso de este modelo no es recomendable para predecir el precio de la acción en Ecopetrol, esto debido a que el modelo propuesto no cumple con los supuestos y además el porcentaje de R2 toma un valor muy bajo.Por tanto, se podría explorar una transformación de la variables con la finalidad de poder ver si este supuesto se puede corregise.

2 PUNTO.SLLMV VS INFLACIÓN. Se busca realizar la predicción del Salario Minimo (SMMLV) a partir de la variación de la inflación en colombia. Para esto se plantea realizar una regresión lineal. Se van a considerar los siguientes datos para su construcción

library(readxl)
datos2 <- read_excel("C:/Users/asus/Downloads/SMMLV.xlsx")
View(datos2)

Con la finalidad de observar la relación de estas dos variables, se realiza un diagrama de dispesión con el fin de ver si es posible explicar la variabilidad del salario minimo en funcion de la inflación anual.

ggplot(datos2,aes(x=datos2$INFLACION, y=datos2$SMLM))+geom_point()+theme_bw()+
  geom_smooth(method = "lm")
Warning: Use of `datos2$INFLACION` is discouraged. Use `INFLACION` instead.
Warning: Use of `datos2$SMLM` is discouraged. Use `SMLM` instead.
Warning: Use of `datos2$INFLACION` is discouraged. Use `INFLACION` instead.
Warning: Use of `datos2$SMLM` is discouraged. Use `SMLM` instead.
`geom_smooth()` using formula 'y ~ x'

Punto a. Escriba la ecuación del modelo de regresión lineal simple

SMMLM=β0+β1Inflación+ϵ

mod2 = lm(datos2$SMLM ~datos2$INFLACION)
resumen2 = summary(mod2)
resumen2

Call:
lm(formula = datos2$SMLM ~ datos2$INFLACION)

Residuals:
   Min     1Q Median     3Q    Max 
-75463 -63456 -42854  17623 263207 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)        648486      58947   11.00  1.4e-08 ***
datos2$INFLACION   -39489      10151   -3.89  0.00145 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 94130 on 15 degrees of freedom
Multiple R-squared:  0.5022,    Adjusted R-squared:  0.469 
F-statistic: 15.13 on 1 and 15 DF,  p-value: 0.00145

PuntoB. Plantee y valide las hipótesis correspondientes a la linealidad general del modelo propuesto en a)

mean(mod2$residuals)
[1] -1.491304e-12
shapiro.test(mod2$residuals)

    Shapiro-Wilk normality test

data:  mod2$residuals
W = 0.78826, p-value = 0.001407
library(lmtest)
bptest(mod2)

    studentized Breusch-Pagan test

data:  mod2
BP = 0.61478, df = 1, p-value = 0.433

Resultado: Por un lado, la prueba de Shapiro - Wilk arroja que el p_value es 0.001407 < 0.05, por lo tanto, se rechaza la hipotesis nula y se concluye que los residuos no vienen de una distribución normal.Frente a la media de los errores estos estan muy cercanos a cero . Asimismo, se detecta, según la prueba Breusch-Pagan, donde Ho = Homocedasticidad (los residuos se distibuyen con la misma varianza) y Ha = Heterocedasticidad (los residuos no se distribuyen con la misma varianza), que el un p-value de 0.433 > 0.05, por lo tanto, no se rechaza Ho, por lo que se evidencia que la varianza de los residuos es homocedastica. En conclusión, los residuales no cumplen con el supuesto de normalidad, por lo que los datos no se ajustan adecuadamente a un modelo lineal.

Punto C. Indique e interprete el coeficiente de correlación del modelo propuesto en a)

Resultado: coeficiente de correlación del modelo propuesto es de R2=0.5022, por lo que explica en un 50.22% la variabilidad del salario de acuerdo a la inflación

Punto D. Interprete cada uno de los coeficientes del modelo propuesto en a)

Resultado: Los que nos indica el modelo es que el B0 nos dice que si la inflacion es cero, entonces el salario minimo legal sera de $648.486 aproximadamente. Por otro lado, Lo que indica la pendiente b1, es cual es la disminucion del salario minimo legal por cada incremento en una unidad de inflacion, es decir, que si la inflacion aumenta en un 1% entonces, el salario minimo legal disminuira $39.489 aproximadamente. Por otro lado, los valores del valor P nos dice que el coeficiente b1 si es significativo porque este es igual a cero entonces se rechaza H0. Además, el R2 nos dice que la inflacion explica en un 46.9% el salario minimo

Punto E.Construya una gráfica de residuales y haga un análisis cualitativo de los supuestos del modelo propuesto en a

e=mod2$residuals
par(mfrow=c(2,2))
plot(mod2)

Resultado: Para el valor de la Media cero: Se cumple, no se presenta novedad.Frente a la Varianza Constante: Se puede observar que el modelo propuesto no cumple con este supuesto. Es posible identificar que los errores no son aleatorios y que el modelo no es lineal. Para la Normalidad: En el grafico se puede observar que los datos no se ajustan del todo a la línea de normalidad. Respecto la Independencia: Teniendo en cuenta que los registros corresponden a datos en el tiempo, se indica que son de orden temporal. En conclusión se debe transformar el modelo de regresion lineal, ya que en el grafico de ajuste no se cumple la aleatoridad de los errores.

Punto F.Comente sobre la conveniencia de usar el modelo propuesto en a) para predecir el SMLM para Colombia

Resultado: Considerando los resultados obtenidos en el modelo propuesto, se puede indicar que no es recomendable el uso de este modelo para predecir el SLML en Colombia, esto debido a que el modelo propuesto no cumple con los supuestos y además el porcentaje de R2 toma un valor muy bajo.

Punto 3. Con base en los datos de precios de vivienda de la actividad en clase realizar un informe que contenga los siguientes puntos utilizando R y RMarkdown (publicar el informe final en Rpubs presentando código, resultados e interpretaciones)

library(readxl)
datos_vivienda <- read_excel("Datos_Vivienda.xlsx")
View(datos_vivienda)

Punto a. Realice un filtro a la base de datos e incluya solo las ofertas de apartamentos, de la zona norte de la ciudad con precios inferiores a los 500 millones de pesos y áreas menores a 300 mt2. Presente los primeros 3 registros de la base y algunas tablas que comprueben la consulta. (¿Adicional un mapa con los puntos de la base, discutir si todos los puntos se ubican en la zona norte o se presentan valores en otras zonas, por qué?).

head(datos_vivienda)
 pos=which (datos_vivienda$Tipo== "Apartamento" & datos_vivienda$Zona == "Zona Norte" & datos_vivienda$precio_millon < 500 & datos_vivienda$Area_contruida < 300)
viviendas = datos_vivienda[pos,]
viviendas <- transform(viviendas, parqueaderos = as.numeric(parqueaderos))
Warning in eval(substitute(list(...)), `_data`, parent.frame()) :
  NAs introduced by coercion
viviendas[is.na(viviendas)] <- 0
head(viviendas, 15)
NA
require(leaflet)
Loading required package: leaflet
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
leaflet() %>% addCircleMarkers(lng = datos_vivienda$cordenada_longitud,lat = datos_vivienda$Cordenada_latitud,radius = 0.3,color = "black",label = datos_vivienda$ID) %>% addTiles()
Warning in validateCoords(lng, lat, funcName) :
  Data contains 3 rows with either missing or invalid lat/lon values and will be ignored
Warning: Unknown or uninitialised column: `ID`.

Punto b. Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio del apartamento) en función del área construida, estrato y si tiene parqueadero. Use gráficos interactivos con plotly e interprete los resultados

Grafico area construida vs precio

graf1 <- plot_ly(data = datos_vivienda, x =~datos_vivienda$Area_contruida , y = ~datos_vivienda$precio_millon ,
               marker = list(size = 10,
                             color = 'lightblue',
                             line = list(color = 'blue',
                                         width = 2)))
graf1 <- graf1 %>% layout(title = 'Precio Vivienda vs Area Construida',
         yaxis = list(zeroline = FALSE),
         xaxis = list(zeroline = FALSE))

graf1
No trace type specified:
  Based on info supplied, a 'scatter' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#scatter
No scatter mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Warning: Ignoring 3 observations
No trace type specified:
  Based on info supplied, a 'scatter' trace seems appropriate.
  Read more about this trace type -> https://plotly.com/r/reference/#scatter
No scatter mode specifed:
  Setting the mode to markers
  Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Warning: Ignoring 3 observations

Resultado: la correlacion nos dice que existen una relacion positiva entre el precio y el area construida, es decir que, mientras el area construida sea mayor el precio sera mas alto.

Precio_millon vs Estrato

require(ggplot2)
require(plotly)

graf2= ggplot(datos_vivienda = datos_vivienda, mapping = aes(x= datos_vivienda$Estrato, y=datos_vivienda$precio_millon))+ geom_point()+geom_smooth()
ggplotly(graf2)
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
Warning: Removed 3 rows containing non-finite values (stat_smooth).
Warning: Computation failed in `stat_smooth()`:
x has insufficient unique values to support 10 knots: reduce k.

Resultado:Es posible advertir, de acuerdo con el grafico, una relación directa entre las dos variables, es decir, entre mayor sea el estrato, mayor es el precio de la vivienda.

Grafica precios por millon vs # Parquederos

require(ggplot2)
require(plotly)

graf3= ggplot(datos_vivienda = datos_vivienda, mapping = aes(x=datos_vivienda$parqueaderos, y= datos_vivienda$precio_millon))+ geom_point()+geom_smooth()
ggplotly(graf3)
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
Warning: Removed 2 rows containing non-finite values (stat_smooth).

Resultado: El grafico no da cuenta de una relación existente entre el numero de parqueaderos vs el precio de la vivienda.

C. Estime un modelo de regresión lineal múltiple con las variables del punto anterior e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).


modelo_viviendas = lm(formula= precio_millon ~ Area_contruida + Estrato +  parqueaderos, data = viviendas )
summary(modelo_viviendas)

Call:
lm(formula = precio_millon ~ Area_contruida + Estrato + parqueaderos, 
    data = viviendas)

Residuals:
     Min       1Q   Median       3Q      Max 
-216.571  -31.564   -1.213   27.889  224.053 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)    -157.38220    7.71190 -20.408  < 2e-16 ***
Area_contruida    0.94938    0.06054  15.682  < 2e-16 ***
Estrato          68.99436    2.26623  30.445  < 2e-16 ***
parqueaderos     22.64906    2.73064   8.294 3.24e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 53.75 on 1073 degrees of freedom
Multiple R-squared:  0.7629,    Adjusted R-squared:  0.7623 
F-statistic:  1151 on 3 and 1073 DF,  p-value: < 2.2e-16

Resultado: Con los resultados anteriores se puede expresar el modelo ajustado como se muestra a continuación: Preciomillon=−157.38220+0.94938x1i+68.99436x3i+22.64906x2i R2=0.7623

a)El valor del R cuadrado = 0.7623 significa que la variables: area construida, estrato y parquaderos explican el 76% del precio del apartamento. b)Se pueden interpretar los efectos B de la siguiente forma: -Si el área construida de la vivienda aumenta 1mts2, se espera que el precio por millon de la vivienda aumente en -.94 millones. -Si el estrato de la vivienda aumenta en 1, el precio por millon de la vivienda aumente en 22.64 millones. -Por cada parqueadero adicional, se espera que el precio por millon de la vivienda aumente en 15.55661 millones. -En este contexto el intercepto de -157.38, lo que no es lógico porque no hay un costo de valor negativo para una vivienda -El coeficiente R2 ajustado de 0.76 lo que indica que el precio de la vivienda es explicado por el modelo en un 76%

Punto d. Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas solo realizar sugerencias de que se podría hacer).

par(mfrow = c(2, 2))
plot(modelo_viviendas)

library(lmtest)
bptest(modelo_viviendas)

    studentized Breusch-Pagan test

data:  modelo_viviendas
BP = 156.86, df = 3, p-value < 2.2e-16

Resultado:Según las gráficas se puede concluir lo siguiente: 1)Gràfica NormalQQ: d es posible evidenciar que los errores no siguen el supuesto de normalidad. 2)Asimismo, los residuales no son homocedasticos de acuerdo con la gráfica Scale Location y la prueba de Breush-Pagan, la cual dio un p_valor muy próximo a 0 por lo que se rechaza la hipotesis nula de homocedasticidad. Se concluye que los residuales no cumplen con el supuesto de normalidad ni homocedasticidad, por lo que los datos no se ajustan adecuadamente a un modelo lineal.

Punto e. Con el modelo identificado predecir el precio de un apartamento con 100 mt2, de estrato 4 y con parqueadero. ¿Si este apartamento lo están ofreciendo en 450 millones cual seria su opinión con base en el resultado del modelo considera que es una buena oferta?

-473.29+(0.9787*100)+(87.11*1)+(125.24*4)
[1] 212.65

Resultado: Considerando los valores obtenidos del modelo, no es buena opción comprar el apartamento que estan ofreciendo por 450 millones, dado que el modelo registra un valor de compra aproximado de 212 millones.

Punto f.Con las predicciones del modelo sugiera potenciales ofertas para una persona interesada en un apartamento en la zona norte con mas de 100 mt2 de área, de estrato 4, que tenga parqueadero y tenga encuenta que la persona tiene un crédito preaprobado de máximo 400 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir

oferta = which(datos_vivienda$Tipo=="Apartamento"& datos_vivienda$Zona=="Zona Norte"& datos_vivienda$precio_millon<=400 & datos_vivienda$Area_contruida>100 & datos_vivienda$Estrato == 4 & datos_vivienda$parqueaderos >= 1)
oferta_2=datos_vivienda[oferta,]
oferta_final = head(oferta_2,5)
oferta_final
oferta1 = predict(modelo_viviendas,list(Area_contruida=123,Estrato=4,parqueaderos=1))
oferta2 = predict(modelo_viviendas,list(Area_contruida=130,Estrato=4,parqueaderos=1))
oferta3 = predict(modelo_viviendas,list(Area_contruida=108,Estrato=4,parqueaderos=1))
oferta4 = predict(modelo_viviendas,list(Area_contruida=104,Estrato=4,parqueaderos=1))
oferta5 = predict(modelo_viviendas,list(Area_contruida=125,Estrato=4,parqueaderos=2))
data.frame(oferta1,oferta2,oferta3,oferta4,oferta5)
NA

Resultado: Considerando que la persona tiene un crédito preaprobado por un valor de 400 millones se sugiere al comprador ofertas de apartamento en zona norte, estrato 4 y con posibilidad de 1 o 2 parqueaderos y área construida mayor a 100mt2. Cualquiera de las ofertas alcanza al comprador, según el preaprobado con el que cuenta.

library(leaflet)
leaflet() %>% addCircleMarkers(lng = oferta_final$cordenada_longitud,lat = oferta_final$Cordenada_latitud,radius = 5,color = "red",label = oferta_def$ID) %>% addTiles()
Warning: Unknown or uninitialised column: `ID`.

Punto 4 Con base en los datos de arboles proponga un modelo de regresión lineal múltiple que permita predecir el peso del árbol en función de las covariables que considere importantes y seleccionándolas de acuerdo con un proceso adecuado. Tenga en cuenta realizar una evaluación de la significancia de los parámetros, interpretación y proponga un método de evaluación por medio de validación cruzada. Presente métricas apropiadas como el RMSE y MAE.


library(readxl)
dataarboles <- read_excel("C:/Users/asus/Desktop/dataarboles.xlsx", 
    col_types = c("text", "text", "numeric", 
        "numeric", "numeric"))
View(dataarboles)
dataarboles=dataarboles[, 3:5]
attach(dataarboles)
The following objects are masked from dataarboles (pos = 3):

    altura, diametro, peso

The following objects are masked from dataarboles (pos = 4):

    altura, diametro, peso

The following objects are masked from arboles:

    altura, diametro, peso

The following objects are masked from dataarboles (pos = 16):

    altura, diametro, peso

The following objects are masked from dataarboles (pos = 17):

    altura, diametro, peso

The following objects are masked from dataarboles (pos = 18):

    altura, diametro, peso

The following objects are masked from dataarboles (pos = 19):

    altura, diametro, peso
names(dataarboles)
[1] "peso"     "diametro" "altura"  
ggpairs(dataarboles, lower = list(continuous = "smooth"),
        diag = list(continuous = "barDiag"), axisLabels = "none")
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Resultado: de las gráficas se puede concluir que las variables que tienen una mayor relación lineal con la peso son el diametro (0.908), altura ( 0.858). Tambien, e diametro y altura están correlacionados ( 0.936).

Modelo de regresión multiple

set.seed(1)
train <- sample(x = 1:90, 72)
modelo_arboles <- lm(peso~diametro + altura, data = arboles, subset = train)
summary(modelo_arboles)

Call:
lm(formula = peso ~ diametro + altura, data = arboles, subset = train)

Residuals:
    Min      1Q  Median      3Q     Max 
-6.6550 -2.4204  0.4327  1.8321 10.6024 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -9.2952     1.6058  -5.788 1.91e-07 ***
diametro      4.0257     0.8240   4.886 6.43e-06 ***
altura        0.9855     0.6525   1.510    0.136    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 3.455 on 69 degrees of freedom
Multiple R-squared:  0.8375,    Adjusted R-squared:  0.8328 
F-statistic: 177.8 on 2 and 69 DF,  p-value: < 2.2e-16

Con los resultados anteriores se puede expresar el modelo ajustado como se muestra a continuación: Y()=−9.29+4.02∗X1(Diametro)+0.98∗X2(Altura) Se pueden interpretar los efectos β de la siguiente forma: _ De acuerdo a los cálculos observados si el diámetro del árbol aumenta en una unidad, se espera que el peso del árbol aumente en 4.02 unidades. _ De igual manera se puede indicar que por cada metro adicional en la altura del árbol, se esperaría que el peso del árbol aumente en 0.98 unidades. _ De esta manera el intercepto de -9.1205, no es un valor , dado que no debería existir un árbol con un peso negativo. _ De igual forma el coeficiente R2 ajustado toma un valor de 0.83, lo cual indica que el peso del árbol es explicado por el modelo con un 83%.

par(mfrow=c(2,2))
plot(modelo_arboles)

Validación del modelo

Resultado: 1. Media cero: Se cumple por defecto. 2. Varianza Constante: Se observa en la grafica 1 de residuales vs ajustados que el comportamiento es aleatorio mostrando una leve curva hacia abajo. 3. Normalidad: Se observa en la grafica 2 que los datos se ajustan bien a la linea de normalidad en el qqplot 4. Independencia: Dado que estos registros no corresponden a datos en el tiempo no se tiene un orden temporal para realizar la validación de este supuesto.

Hipótesis nula H0: Para este caso el coeficiente B1 no aporta al modelo propuesto, dado que el p-value es menor al 0.05 con valor correspondiente a.(6.43e-06 ), rechazamos la hipótesis nula, y se puede concluir que el coeficiente B1 si aporta al modelo de regresión propuesto.

_ Hipótesis nula H0: Para este caso el coeficiente B2 no aporta al modelo propuesto, como el p-value es mayor al 0.05 (0.136), NO rechazamos la hipótesis nula, y concluimos que el coeficiente B2 NO aporta al modelo de regresión propuesto.

Métricas RMSE y MAE

prediccion_arboles <- predict(object = modelo_arboles, newdata = dataarboles[-train, ])
error_arboles <- mean((dataarboles$peso[-train] - prediccion_arboles)^2)
error_arboles
[1] 13.47297
library(Metrics)
mae(arboles$peso[-train], prediccion_arboles)
[1] 3.01947

Resultado: Teniendo en cuenta las validaciones se puede indicar que el modelo se equivoca en un 13% del peso promedio de acuerdo al MAE y la desviación estándar de la varianza inexplicada es de 3.0 de acuerdo al RMSE.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCg0KLS0tDQpFbGFib3JhZG8gcG9yOiBFbGlhbmEgUG92ZWRhDQoNCg0KIyMgKioxLiBQcmVkaWNjacOzbiBkZSBsb3MgcHJlY2lvcyBkZSBsYXMgYWNjaW9uZXMuIEFuYWxpemFyIGVsIGNvbXBvcnRhbWllbnRvIGRlIGxvcyBwcmVjaW9zIGRlIGxhcyBBY2Npb25lcyBkZSBFY29wZXRyb2wgc2Vnw7puIGxhIHZhcmlhY2nDs24gZGVsIHByZWNpbyBkZWwgYmFycmlsIGRlIHBldHLDs2xlbyBXVEkgcHJvZHVjaWRvIGVuIENvbG9tYmlhLiBTZSB0aWVuZW4gbG9zIHNpZ3VpZW50ZXMgcHJlY2lvcyoqLg0KDQpgYGB7cn0NCmxpYnJhcnkocmVhZHhsKQ0KZGF0b3M9ZWNvcGV0cm9sIDwtIHJlYWRfZXhjZWwoIkM6L1VzZXJzL2FzdXMvRGVza3RvcC9lY29wZXRyb2wueGxzeCIpDQpWaWV3KGVjb3BldHJvbCkNCmBgYA0KDQpgYGB7cn0NCmNvcihkYXRvcyRQcmVjaW9fYWNjaW9uLGRhdG9zJFByZWNpb19iYXJyaWwpDQpgYGANClJlc3VsdGFkbzogRWwgY29lZmljaWVudGUgZGUgY29ycmVsYWNpw7NuIHN1Z2llcmUgcXVlIGhheSB1bmEgcmVsYWNpb24gbMOtbmVhbCBmdWVydGUgeSBwb3NpdGl2YSBlbnRyZSBsYXMgdmFyaWFibGVzLlNlIG9ic2VydmEgcXVlIGEgbWF5b3IgcHJlY2lvX2FjY2lvbmVzIGVsIHByZWNpb19iYXJyaWwgYXVtZW50YSB5IHN1IHJlbGFjacOzbiBlcyBwb3NpdGl2YSBkZSBhY3VlcmRvIGNvbiBlbCBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gZGUgUGVhcnNvbiAoMCw3MDc0KS4NCg0KYGBge3J9DQpnZ3Bsb3QoZGF0b3MsYWVzKHg9UHJlY2lvX2FjY2lvbiwgeT1QcmVjaW9fYmFycmlsKSkrZ2VvbV9wb2ludCgpK3RoZW1lX2J3KCkrDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpDQpgYGANCkVuIGxhIGdyYWZpY2Egc2Ugb2JzZXJ2YSBxdWUgaGF5IHVuYSByZWxhY2nDs24gZW50cmUgZXN0YSBkb3MgdmFyaWFibGVzLCBxdWUgaW5pY2lhbG1lbnRlIHBhcmVjaWVyYSBubyBzZXIgbmVjZXNhcmlhbWVudGUgbGluZWFsDQoNCg0KIyMgKipBanVzdGUgZGVsIG1vZGVsbyoqDQojIyAqKlB1bnRvIGEuUHJvcG9uZ2EgdW4gbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSBxdWUgcGVybWl0YSBwcmVkZWNpciBlbCB2YWxvciBkZSBsYXMgQWNjaW9uZXMgZGUgRWNvcGV0cm9sIGNvbiBiYXNlIGVuIGVsIFByZWNpbyBkZWwgYmFycmlsIGRlIHBldHLDs2xlbyBlbiBDb2xvbWJpYS4gSW5kaXF1ZSBsYSBlY3VhY2nDs24gZGUgcmVncmVzacOzbiB5IGVsIHZhbG9yIGRlbFIyLkxhIHJlZ3Jlc2nDs24gc2UgZXN0cnVjdHVyYXLDrWEgZGUgbGEgc2lndWllbnRlIGZvcm1hKio6IA0KIA0KUHJlY2lvX2FjY2lvbj3OsjArzrIxUHJlY2lvX2JhcnJpbCvPtQ0KIA0KYGBge3J9DQptb2Q9bG0oUHJlY2lvX2FjY2lvbn5QcmVjaW9fYmFycmlsLGRhdGEgPSBkYXRvcykNCnJlc3VtZW49c3VtbWFyeShtb2QpDQpyZXN1bWVuDQpgYGANCnJlc3VsdGFkbzogRWwgdmFsb3IgZGVsIFIgY3VhZHJhZG8gPSAwLjUwIHNpZ25pZmljYSBxdWUgbGEgdmFyaWFibGUgcHJlY2lvX2JhcnJpbCBleHBsaWNhIGVsIDUwJSBkZWwgcHJlY2lvIGRlIGxhcyBhY2Npb25lcy4NCg0KDQojIyAqKkIuIFBydWViZSBsYSBzaWduaWZpY2FuY2lhIGRlbCBtb2RlbG8gcHJvcHVlc3RvIGVuICJhKSIgcGxhbnRlZSBsYXMgaGlww7N0ZXNpcyByZXNwZWN0aXZhcyB5IHVzZSBlbCBjb25jZXB0byBkZSBWYWxvciBfcCBwYXJhIHRvbWFyIGxhIGRlY2lzacOzbiBzb2JyZSBsYXMgaGlww7N0ZXNpcy4gVXNlIM6xID0gMC4wNSoqDQoNClJlc3VsdGFkbzogRWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gcHJvcHVlc3RvIHBhcmEgcHJlZGVjaXIgZWwgdmFsb3IgZGUgbGFzIGFjY2lvbmVzIGRlIGVjb3BldHJvbCBlcyANCnByZWNpb2FjY2nDs249MTc3Ljc3KygyNi4xOeKIl3ByZWNpb2JhcnJpbCkgIGVuIGRvbmRlIM6yMD0xNzcgeSDOsjE9MjYuMTkNCkhvID0gRWwgbW9kZWxvIG5vIGVzIHNpZ25pZmljYXRpdm8gSGEgPSBFbCBtb2RlbG8gc2kgZXMgc2lnbmlmaWNhdGl2bw0KDQpgYGB7cn0NCnJlc3VtZW4kY29lZmZpY2llbnRzWzIsIF0NCmBgYA0KVGVuaWVuZG8gZW4gY3VlbnRhIHF1ZSBlbCB2YWxvcl9wIGVzIGlndWFsIGEgMC4wMDEwMjM5MzggPCAwLjA1ID0gzrEsICBzZSBkZWJlIHJlY2hhemFyIEhvIHkgYWNlcHRhciBIYSwgY29uIGxvIGN1YWwgc2UgY29uY2x1eWUgcXVlIGVsIHZhbG9yIGRlIGxhIHBlbmRpZW50ZSBlcyB1biBwcmVkaWN0b3Igc2lnbmlmaWNhdGl2byBwYXJhIGxhIGVjdWFjacOzbiBkZWwgcHJlY2lvIGRlIGxhIGFjY2nDs24gZGUgRWNvcGV0cm9sLg0KDQoNCiMjICoqUHVudG8gQy4gSW50ZXJwcmV0ZSBsb3MgY29lZmljaWVudGVzIGRlbCBtb2RlbG8gcHJvcHVlc3RvIGVuICJhKSoqDQoNCmBgYHtyfQ0KbW9kJGNvZWZmaWNpZW50cw0KDQpgYGANCg0KUmVzdWx0YWRvOiAgU2Vnw7puIGVsIG1vZGVsbyBwcm9wdWVzdG8sIHBvciBjYWRhIGRvbGFyIGFkaWNpb25hbCBxdWUgY3Vlc3RlIHVuIGJhcnJpbCBkZSBwZXRyb2xlbyBlbCBwcmVjaW8gZGUgbGEgYWNjacOzbiBkZSBFY29wZXRyb2wgYXVtZW50YSBlbiBlbCAyNiwxOSBwZXNvcyBjb2xvbWJpYW5vcy4gVGFtYmnDqW4sIGNvbnNpZXJhbmRvIEIwIHNpIGVsIHByZWNpbyBkZWwgYmFycmlsIGRlIHBldHJvbGVvIGZ1ZXJhIDAgZW50b25jZXMgZWwgcHJlY2lvIGRlIGxhcyBhY2Npb25lcyBkZSBFY29wZXRyb2wgc2Vyw61hbiBkZSAxNzcgcGVzb3MuIA0KDQojIyAqKlB1bnRvIEQuIEhhZ2EgdW4gYW7DoWxpc2lzIGRlIGxvcyByZXNpZHVvcy4gIMK/UXXDqSBzdXB1ZXN0byBubyBzZSBjdW1wbGU/KioNCmBgYHtyfQ0KZT1tb2QkcmVzaWR1YWxzDQpwYXIobWZyb3c9YygyLDIpKQ0KcGxvdChtb2QpDQpgYGANCmBgYHtyfQ0Kc2hhcGlyby50ZXN0KG1vZCRyZXNpZHVhbHMpDQpgYGANCg0KUmVzdWx0YWRvOiBUYW50byBsbyBxdWUgbXVlc3RyYSBsYSBncmFmaWNhIE5vcm1hbCBRUSBjb21vIGxhIHBydWViYSBzaGFwaXJvIHNlIGNvbmNsdXllIHF1ZSBsb3MgcmVzaWR1b3Mgbm8gc2lndWVuIHVuYSBkaXN0cmlidWNpw7NuIG5vcm1hbC4gTm8gc2UgY3VtcGxlIGxhIG5vcm1hbGlkYWQuIFRhbWJpw6luIGxhIGdyYWZpY2FzIGRlIHJlc2lkdWFsZXMgdnMgYWp1c3RhZG9zICBtdWVzdHJhbiBxdWUgbG9zIHJlc2lkdW9zIG5vIHNlIGNvbXBvcnRhbiBkZSBmb3JtYSBhbGVhdG9yaWEgY29tbyBzZSBlc3BlcmFyw61hLiBFbiBjb25jbHVzacOzbiBubyBzZSBjdW1wbGVuIGxvcyBzdXB1ZXN0b3MgcmVsYWNpb25hZG9zIGNvbiBsYSBub3JtYWxpZGFkIHkgbGEgYWxlYXRvcmllZGFkIGRlIGxvcyByZXNpZHVvcy4gIENvbnNpZGVyYW5kbyBsb3MgcmVzdWx0YWRvcyBvYnRlbmlkb3MgZW4gZWwgbW9kZWxvIHByb3B1ZXN0bywgIGVsIHVzbyBkZSBlc3RlIG1vZGVsbyBubyBlcyByZWNvbWVuZGFibGUgcGFyYSBwcmVkZWNpciBlbCBwcmVjaW8gZGUgbGEgYWNjacOzbiBlbiBFY29wZXRyb2wsIGVzdG8gZGViaWRvIGEgcXVlIGVsIG1vZGVsbyBwcm9wdWVzdG8gbm8gY3VtcGxlIGNvbiBsb3Mgc3VwdWVzdG9zIHkgYWRlbcOhcyBlbCBwb3JjZW50YWplIGRlIFIyIHRvbWEgdW4gdmFsb3IgbXV5IGJham8uUG9yIHRhbnRvLCBzZSBwb2Ryw61hIGV4cGxvcmFyIHVuYSB0cmFuc2Zvcm1hY2nDs24gZGUgbGEgdmFyaWFibGVzIGNvbiBsYSBmaW5hbGlkYWQgZGUgcG9kZXIgdmVyIHNpIGVzdGUgc3VwdWVzdG8gc2UgcHVlZGUgY29ycmVnaXNlLiANCg0KDQojIyAqKjIgUFVOVE8uU0xMTVYgVlMgSU5GTEFDScOTTi4gU2UgYnVzY2EgcmVhbGl6YXIgbGEgcHJlZGljY2nDs24gZGVsIFNhbGFyaW8gTWluaW1vIChTTU1MVikgYSBwYXJ0aXIgZGUgbGEgdmFyaWFjacOzbiBkZSBsYSBpbmZsYWNpw7NuIGVuIGNvbG9tYmlhLiBQYXJhIGVzdG8gc2UgcGxhbnRlYSByZWFsaXphciB1bmEgcmVncmVzacOzbiBsaW5lYWwuIFNlIHZhbiBhIGNvbnNpZGVyYXIgbG9zIHNpZ3VpZW50ZXMgZGF0b3MgcGFyYSBzdSBjb25zdHJ1Y2Npw7NuKioNCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmRhdG9zMiA8LSByZWFkX2V4Y2VsKCJDOi9Vc2Vycy9hc3VzL0Rvd25sb2Fkcy9TTU1MVi54bHN4IikNClZpZXcoZGF0b3MyKQ0KDQpgYGANCg0KQ29uIGxhIGZpbmFsaWRhZCBkZSBvYnNlcnZhciBsYSByZWxhY2nDs24gZGUgZXN0YXMgZG9zIHZhcmlhYmxlcywgc2UgcmVhbGl6YSB1biBkaWFncmFtYSBkZSBkaXNwZXNpw7NuIGNvbiBlbCBmaW4gZGUgdmVyIHNpIGVzIHBvc2libGUgZXhwbGljYXIgbGEgdmFyaWFiaWxpZGFkIGRlbCBzYWxhcmlvIG1pbmltbyBlbiBmdW5jaW9uIGRlIGxhIGluZmxhY2nDs24gYW51YWwuIA0KDQpgYGB7cn0NCmdncGxvdChkYXRvczIsYWVzKHg9ZGF0b3MyJElORkxBQ0lPTiwgeT1kYXRvczIkU01MTSkpK2dlb21fcG9pbnQoKSt0aGVtZV9idygpKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKQ0KYGBgDQojIyAqKlB1bnRvIGEuIEVzY3JpYmEgbGEgZWN1YWNpw7NuIGRlbCBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwgc2ltcGxlKioNCg0KIFNNTUxNPc6yMCvOsjFJbmZsYWNpw7NuK8+1DQogDQpgYGB7cn0NCm1vZDIgPSBsbShkYXRvczIkU01MTSB+ZGF0b3MyJElORkxBQ0lPTikNCnJlc3VtZW4yID0gc3VtbWFyeShtb2QyKQ0KcmVzdW1lbjINCmBgYA0KDQojIyAqKlB1bnRvQi4gUGxhbnRlZSB5IHZhbGlkZSBsYXMgaGlww7N0ZXNpcyBjb3JyZXNwb25kaWVudGVzIGEgbGEgbGluZWFsaWRhZCBnZW5lcmFsIGRlbCBtb2RlbG8gcHJvcHVlc3RvIGVuIGEpKioNCmBgYHtyfQ0KbWVhbihtb2QyJHJlc2lkdWFscykNCmBgYA0KYGBge3J9DQpzaGFwaXJvLnRlc3QobW9kMiRyZXNpZHVhbHMpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KGxtdGVzdCkNCmJwdGVzdChtb2QyKQ0KYGBgDQoNClJlc3VsdGFkbzogUG9yIHVuIGxhZG8sICBsYSBwcnVlYmEgZGUgU2hhcGlybyAtIFdpbGsgYXJyb2phIHF1ZSAgZWwgcF92YWx1ZSBlcyAwLjAwMTQwNyA8IDAuMDUsIHBvciBsbyB0YW50bywgIHNlIHJlY2hhemEgbGEgaGlwb3Rlc2lzIG51bGEgeSBzZSBjb25jbHV5ZSBxdWUgbG9zIHJlc2lkdW9zIG5vIHZpZW5lbiBkZSB1bmEgZGlzdHJpYnVjacOzbiBub3JtYWwuRnJlbnRlIGEgbGEgbWVkaWEgZGUgbG9zIGVycm9yZXMgZXN0b3MgZXN0YW4gbXV5IGNlcmNhbm9zIGEgY2VybyAuIEFzaW1pc21vLCBzZSBkZXRlY3RhLCBzZWfDum4gbGEgcHJ1ZWJhIEJyZXVzY2gtUGFnYW4sICBkb25kZSAgSG8gPSBIb21vY2VkYXN0aWNpZGFkIChsb3MgcmVzaWR1b3Mgc2UgZGlzdGlidXllbiBjb24gbGEgbWlzbWEgdmFyaWFuemEpIHkgSGEgPSBIZXRlcm9jZWRhc3RpY2lkYWQgKGxvcyByZXNpZHVvcyBubyBzZSBkaXN0cmlidXllbiBjb24gbGEgbWlzbWEgdmFyaWFuemEpLCBxdWUgZWwgIHVuIHAtdmFsdWUgZGUgMC40MzMgPiAwLjA1LCBwb3IgbG8gdGFudG8sICBubyBzZSByZWNoYXphIEhvLCBwb3IgbG8gcXVlIHNlIGV2aWRlbmNpYSBxdWUgbGEgdmFyaWFuemEgZGUgbG9zIHJlc2lkdW9zIGVzIGhvbW9jZWRhc3RpY2EuIEVuIGNvbmNsdXNpw7NuLCBsb3MgcmVzaWR1YWxlcyBubyBjdW1wbGVuIGNvbiBlbCBzdXB1ZXN0byBkZSBub3JtYWxpZGFkLCBwb3IgbG8gcXVlIGxvcyBkYXRvcyBubyBzZSBhanVzdGFuIGFkZWN1YWRhbWVudGUgYSB1biBtb2RlbG8gbGluZWFsLg0KDQojIyAqKlB1bnRvIEMuIEluZGlxdWUgZSBpbnRlcnByZXRlIGVsIGNvZWZpY2llbnRlIGRlIGNvcnJlbGFjacOzbiBkZWwgbW9kZWxvIHByb3B1ZXN0byBlbiBhKSoqDQoNClJlc3VsdGFkbzogIGNvZWZpY2llbnRlIGRlIGNvcnJlbGFjacOzbiBkZWwgbW9kZWxvIHByb3B1ZXN0byBlcyBkZSBSMj0wLjUwMjIsIHBvciBsbyBxdWUgZXhwbGljYSBlbiB1biA1MC4yMiUgbGEgdmFyaWFiaWxpZGFkIGRlbCBzYWxhcmlvIGRlIGFjdWVyZG8gYSBsYSBpbmZsYWNpw7NuDQoNCiMjICoqUHVudG8gRC4gSW50ZXJwcmV0ZSBjYWRhIHVubyBkZSBsb3MgY29lZmljaWVudGVzIGRlbCBtb2RlbG8gcHJvcHVlc3RvIGVuIGEpKioNCg0KUmVzdWx0YWRvOiBMb3MgcXVlIG5vcyBpbmRpY2EgZWwgbW9kZWxvIGVzIHF1ZSAgZWwgQjAgbm9zIGRpY2UgcXVlIHNpIGxhIGluZmxhY2lvbiBlcyBjZXJvLCBlbnRvbmNlcyBlbCBzYWxhcmlvIG1pbmltbyBsZWdhbCBzZXJhIGRlICQ2NDguNDg2IGFwcm94aW1hZGFtZW50ZS4gUG9yIG90cm8gbGFkbywgTG8gcXVlIGluZGljYSBsYSBwZW5kaWVudGUgYjEsIGVzIGN1YWwgZXMgbGEgZGlzbWludWNpb24gZGVsIHNhbGFyaW8gbWluaW1vIGxlZ2FsIHBvciBjYWRhIGluY3JlbWVudG8gZW4gdW5hIHVuaWRhZCBkZSBpbmZsYWNpb24sIGVzIGRlY2lyLCBxdWUgc2kgbGEgaW5mbGFjaW9uIGF1bWVudGEgZW4gdW4gMSUgZW50b25jZXMsIGVsIHNhbGFyaW8gbWluaW1vIGxlZ2FsIGRpc21pbnVpcmEgJDM5LjQ4OSBhcHJveGltYWRhbWVudGUuIFBvciBvdHJvIGxhZG8sIGxvcyB2YWxvcmVzIGRlbCB2YWxvciBQIG5vcyBkaWNlIHF1ZSBlbCBjb2VmaWNpZW50ZSBiMSBzaSBlcyBzaWduaWZpY2F0aXZvIHBvcnF1ZSBlc3RlIGVzIGlndWFsIGEgY2VybyBlbnRvbmNlcyBzZSByZWNoYXphIEgwLiBBZGVtw6FzLCBlbCBSMiBub3MgZGljZSBxdWUgbGEgaW5mbGFjaW9uIGV4cGxpY2EgZW4gdW4gNDYuOSUgZWwgc2FsYXJpbyBtaW5pbW8NCg0KIyMgKipQdW50byBFLkNvbnN0cnV5YSB1bmEgZ3LDoWZpY2EgZGUgcmVzaWR1YWxlcyB5IGhhZ2EgdW4gYW7DoWxpc2lzIGN1YWxpdGF0aXZvIGRlIGxvcyBzdXB1ZXN0b3MgZGVsIG1vZGVsbyBwcm9wdWVzdG8gZW4gYSoqDQpgYGB7cn0NCmU9bW9kMiRyZXNpZHVhbHMNCnBhcihtZnJvdz1jKDIsMikpDQpwbG90KG1vZDIpDQpgYGANClJlc3VsdGFkbzogUGFyYSBlbCB2YWxvciBkZSBsYSBNZWRpYSBjZXJvOiBTZSBjdW1wbGUsIG5vIHNlIHByZXNlbnRhIG5vdmVkYWQuRnJlbnRlIGEgbGEgVmFyaWFuemEgQ29uc3RhbnRlOiBTZSBwdWVkZSBvYnNlcnZhciBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBubyBjdW1wbGUgY29uIGVzdGUgc3VwdWVzdG8uIEVzIHBvc2libGUgaWRlbnRpZmljYXIgcXVlICBsb3MgZXJyb3JlcyBubyBzb24gYWxlYXRvcmlvcyB5IHF1ZSAgZWwgbW9kZWxvIG5vIGVzIGxpbmVhbC4gUGFyYSBsYSAgTm9ybWFsaWRhZDogRW4gZWwgZ3JhZmljbyBzZSBwdWVkZSBvYnNlcnZhciBxdWUgbG9zIGRhdG9zIG5vIHNlIGFqdXN0YW4gZGVsIHRvZG8gYSBsYSBsw61uZWEgZGUgbm9ybWFsaWRhZC4gUmVzcGVjdG8gIGxhICBJbmRlcGVuZGVuY2lhOiBUZW5pZW5kbyBlbiBjdWVudGEgcXVlIGxvcyByZWdpc3Ryb3MgY29ycmVzcG9uZGVuIGEgZGF0b3MgZW4gZWwgdGllbXBvLCBzZSBpbmRpY2EgcXVlIHNvbiBkZSBvcmRlbiB0ZW1wb3JhbC4gRW4gY29uY2x1c2nDs24gc2UgZGViZSB0cmFuc2Zvcm1hciBlbCBtb2RlbG8gZGUgcmVncmVzaW9uIGxpbmVhbCwgeWEgcXVlICBlbiBlbCAgZ3JhZmljbyBkZSBhanVzdGUgbm8gc2UgY3VtcGxlIGxhIGFsZWF0b3JpZGFkIGRlIGxvcyBlcnJvcmVzLiANCg0KIyMgKipQdW50byBGLkNvbWVudGUgc29icmUgbGEgY29udmVuaWVuY2lhIGRlIHVzYXIgZWwgbW9kZWxvIHByb3B1ZXN0byBlbiBhKSBwYXJhIHByZWRlY2lyIGVsIFNNTE0gcGFyYSBDb2xvbWJpYSoqDQoNClJlc3VsdGFkbzogQ29uc2lkZXJhbmRvIGxvcyByZXN1bHRhZG9zIG9idGVuaWRvcyBlbiBlbCBtb2RlbG8gcHJvcHVlc3RvLCBzZSBwdWVkZSBpbmRpY2FyIHF1ZSBubyBlcyByZWNvbWVuZGFibGUgZWwgdXNvIGRlIGVzdGUgbW9kZWxvIHBhcmEgcHJlZGVjaXIgZWwgU0xNTCBlbiBDb2xvbWJpYSwgZXN0byBkZWJpZG8gYSBxdWUgZWwgbW9kZWxvIHByb3B1ZXN0byBubyBjdW1wbGUgY29uIGxvcyBzdXB1ZXN0b3MgeSBhZGVtw6FzIGVsIHBvcmNlbnRhamUgZGUgUjIgdG9tYSB1biB2YWxvciBtdXkgYmFqby4NCg0KIyMgKipQdW50byAzLiAgQ29uIGJhc2UgZW4gbG9zIGRhdG9zIGRlIHByZWNpb3MgZGUgdml2aWVuZGEgZGUgbGEgYWN0aXZpZGFkIGVuIGNsYXNlIHJlYWxpemFyIHVuIGluZm9ybWUgcXVlIGNvbnRlbmdhIGxvcyBzaWd1aWVudGVzIHB1bnRvcyB1dGlsaXphbmRvIFIgeSBSTWFya2Rvd24gKHB1YmxpY2FyIGVsIGluZm9ybWUgZmluYWwgZW4gUnB1YnMgcHJlc2VudGFuZG8gY8OzZGlnbywgcmVzdWx0YWRvcyBlIGludGVycHJldGFjaW9uZXMpKioNCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmRhdG9zX3ZpdmllbmRhIDwtIHJlYWRfZXhjZWwoIkRhdG9zX1ZpdmllbmRhLnhsc3giKQ0KVmlldyhkYXRvc192aXZpZW5kYSkNCg0KYGBgDQoNCiMjICoqUHVudG8gYS4gUmVhbGljZSB1biBmaWx0cm8gYSBsYSBiYXNlIGRlIGRhdG9zIGUgaW5jbHV5YSBzb2xvIGxhcyBvZmVydGFzIGRlIGFwYXJ0YW1lbnRvcywgZGUgbGEgem9uYSBub3J0ZSBkZSBsYSBjaXVkYWQgY29uIHByZWNpb3MgaW5mZXJpb3JlcyBhIGxvcyA1MDAgbWlsbG9uZXMgZGUgcGVzb3MgeSDDoXJlYXMgbWVub3JlcyBhIDMwMCBtdDIuIFByZXNlbnRlIGxvcyBwcmltZXJvcyAzIHJlZ2lzdHJvcyBkZSBsYSBiYXNlIHkgYWxndW5hcyB0YWJsYXMgcXVlIGNvbXBydWViZW4gbGEgY29uc3VsdGEuICjCv0FkaWNpb25hbCB1biBtYXBhIGNvbiBsb3MgcHVudG9zIGRlIGxhIGJhc2UsIGRpc2N1dGlyIHNpIHRvZG9zIGxvcyBwdW50b3Mgc2UgdWJpY2FuIGVuIGxhIHpvbmEgbm9ydGUgbyBzZSBwcmVzZW50YW4gdmFsb3JlcyBlbiBvdHJhcyB6b25hcywgcG9yIHF1w6k/KSoqLg0KDQpgYGB7cn0NCmhlYWQoZGF0b3Nfdml2aWVuZGEpDQpgYGANCmBgYHtyfQ0KIHBvcz13aGljaCAoZGF0b3Nfdml2aWVuZGEkVGlwbz09ICJBcGFydGFtZW50byIgJiBkYXRvc192aXZpZW5kYSRab25hID09ICJab25hIE5vcnRlIiAmIGRhdG9zX3ZpdmllbmRhJHByZWNpb19taWxsb24gPCA1MDAgJiBkYXRvc192aXZpZW5kYSRBcmVhX2NvbnRydWlkYSA8IDMwMCkNCnZpdmllbmRhcyA9IGRhdG9zX3ZpdmllbmRhW3BvcyxdDQp2aXZpZW5kYXMgPC0gdHJhbnNmb3JtKHZpdmllbmRhcywgcGFycXVlYWRlcm9zID0gYXMubnVtZXJpYyhwYXJxdWVhZGVyb3MpKQ0Kdml2aWVuZGFzW2lzLm5hKHZpdmllbmRhcyldIDwtIDANCmhlYWQodml2aWVuZGFzLCAxNSkNCg0KYGBgDQpgYGB7cn0NCnJlcXVpcmUobGVhZmxldCkNCg0KbGVhZmxldCgpICU+JSBhZGRDaXJjbGVNYXJrZXJzKGxuZyA9IGRhdG9zX3ZpdmllbmRhJGNvcmRlbmFkYV9sb25naXR1ZCxsYXQgPSBkYXRvc192aXZpZW5kYSRDb3JkZW5hZGFfbGF0aXR1ZCxyYWRpdXMgPSAwLjMsY29sb3IgPSAiYmxhY2siLGxhYmVsID0gZGF0b3Nfdml2aWVuZGEkSUQpICU+JSBhZGRUaWxlcygpDQpgYGANCg0KIyMgKipQdW50byBiLiBSZWFsaWNlIHVuIGFuw6FsaXNpcyBleHBsb3JhdG9yaW8gZGUgZGF0b3MgZW5mb2NhZG8gZW4gbGEgY29ycmVsYWNpw7NuIGVudHJlIGxhIHZhcmlhYmxlIHJlc3B1ZXN0YSAocHJlY2lvIGRlbCBhcGFydGFtZW50bykgZW4gZnVuY2nDs24gZGVsIMOhcmVhIGNvbnN0cnVpZGEsIGVzdHJhdG8geSBzaSB0aWVuZSBwYXJxdWVhZGVyby4gVXNlIGdyw6FmaWNvcyBpbnRlcmFjdGl2b3MgY29uIHBsb3RseSBlIGludGVycHJldGUgbG9zIHJlc3VsdGFkb3MqKg0KDQojICpHcmFmaWNvIGFyZWEgY29uc3RydWlkYSB2cyBwcmVjaW8qIA0KDQpgYGB7cn0NCmdyYWYxIDwtIHBsb3RfbHkoZGF0YSA9IGRhdG9zX3ZpdmllbmRhLCB4ID1+ZGF0b3Nfdml2aWVuZGEkQXJlYV9jb250cnVpZGEgLCB5ID0gfmRhdG9zX3ZpdmllbmRhJHByZWNpb19taWxsb24gLA0KICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChzaXplID0gMTAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gJ2xpZ2h0Ymx1ZScsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJ2JsdWUnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDIpKSkNCmdyYWYxIDwtIGdyYWYxICU+JSBsYXlvdXQodGl0bGUgPSAnUHJlY2lvIFZpdmllbmRhIHZzIEFyZWEgQ29uc3RydWlkYScsDQogICAgICAgICB5YXhpcyA9IGxpc3QoemVyb2xpbmUgPSBGQUxTRSksDQogICAgICAgICB4YXhpcyA9IGxpc3QoemVyb2xpbmUgPSBGQUxTRSkpDQoNCmdyYWYxDQpgYGANCg0KUmVzdWx0YWRvOiBsYSBjb3JyZWxhY2lvbiBub3MgZGljZSBxdWUgZXhpc3RlbiB1bmEgcmVsYWNpb24gcG9zaXRpdmEgZW50cmUgZWwgcHJlY2lvICB5IGVsIGFyZWEgY29uc3RydWlkYSwgZXMgZGVjaXIgcXVlLCBtaWVudHJhcyBlbCBhcmVhIGNvbnN0cnVpZGEgc2VhIG1heW9yIGVsIHByZWNpbyBzZXJhIG1hcyBhbHRvLg0KDQojICpQcmVjaW9fbWlsbG9uIHZzIEVzdHJhdG8qDQoNCmBgYHtyfQ0KcmVxdWlyZShnZ3Bsb3QyKQ0KcmVxdWlyZShwbG90bHkpDQoNCmdyYWYyPSBnZ3Bsb3QoZGF0b3Nfdml2aWVuZGEgPSBkYXRvc192aXZpZW5kYSwgbWFwcGluZyA9IGFlcyh4PSBkYXRvc192aXZpZW5kYSRFc3RyYXRvLCB5PWRhdG9zX3ZpdmllbmRhJHByZWNpb19taWxsb24pKSsgZ2VvbV9wb2ludCgpK2dlb21fc21vb3RoKCkNCmdncGxvdGx5KGdyYWYyKQ0KDQoNCmBgYA0KDQpSZXN1bHRhZG86RXMgcG9zaWJsZSBhZHZlcnRpciwgZGUgYWN1ZXJkbyBjb24gZWwgZ3JhZmljbywgIHVuYSByZWxhY2nDs24gZGlyZWN0YSBlbnRyZSBsYXMgZG9zIHZhcmlhYmxlcywgZXMgZGVjaXIsICBlbnRyZSBtYXlvciBzZWEgZWwgZXN0cmF0bywgbWF5b3IgZXMgZWwgcHJlY2lvIGRlIGxhIHZpdmllbmRhLg0KDQojICpHcmFmaWNhIHByZWNpb3MgcG9yIG1pbGxvbiB2cyAjIFBhcnF1ZWRlcm9zKg0KYGBge3J9DQpyZXF1aXJlKGdncGxvdDIpDQpyZXF1aXJlKHBsb3RseSkNCg0KZ3JhZjM9IGdncGxvdChkYXRvc192aXZpZW5kYSA9IGRhdG9zX3ZpdmllbmRhLCBtYXBwaW5nID0gYWVzKHg9ZGF0b3Nfdml2aWVuZGEkcGFycXVlYWRlcm9zLCB5PSBkYXRvc192aXZpZW5kYSRwcmVjaW9fbWlsbG9uKSkrIGdlb21fcG9pbnQoKStnZW9tX3Ntb290aCgpDQpnZ3Bsb3RseShncmFmMykNCmBgYA0KDQpSZXN1bHRhZG86IEVsIGdyYWZpY28gbm8gZGEgY3VlbnRhIGRlICB1bmEgcmVsYWNpw7NuIGV4aXN0ZW50ZSBlbnRyZSBlbCBudW1lcm8gZGUgcGFycXVlYWRlcm9zIHZzIGVsIHByZWNpbyBkZSBsYSB2aXZpZW5kYS4NCg0KIyMgKipDLiBFc3RpbWUgdW4gbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZSBjb24gbGFzIHZhcmlhYmxlcyBkZWwgcHVudG8gYW50ZXJpb3IgZSBpbnRlcnByZXRlIGxvcyBjb2VmaWNpZW50ZXMgc2kgc29uIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdm9zLiBMYXMgaW50ZXJwcmV0YWNpb25lcyBkZWJlciBlc3TDoW4gY29udGV4dHVhbGl6YWRhcyB5IGRpc2N1dGlyIHNpIGxvcyByZXN1bHRhZG9zIHNvbiBsw7NnaWNvcy4gQWRpY2lvbmFsbWVudGUgaW50ZXJwcmV0ZSBlbCBjb2VmaWNpZW50ZSBSMiB5IGRpc2N1dGEgZWwgYWp1c3RlIGRlbCBtb2RlbG8gZSBpbXBsaWNhY2lvbmVzIChxdWUgcG9kcsOtYW4gaGFjZXIgcGFyYSBtZWpvcmFybG8pKiouDQoNCmBgYHtyfQ0KDQptb2RlbG9fdml2aWVuZGFzID0gbG0oZm9ybXVsYT0gcHJlY2lvX21pbGxvbiB+IEFyZWFfY29udHJ1aWRhICsgRXN0cmF0byArICBwYXJxdWVhZGVyb3MsIGRhdGEgPSB2aXZpZW5kYXMgKQ0Kc3VtbWFyeShtb2RlbG9fdml2aWVuZGFzKQ0KDQpgYGANClJlc3VsdGFkbzogIENvbiBsb3MgcmVzdWx0YWRvcyBhbnRlcmlvcmVzIHNlIHB1ZWRlIGV4cHJlc2FyIGVsIG1vZGVsbyBhanVzdGFkbyBjb21vIHNlIG11ZXN0cmEgYSBjb250aW51YWNpw7NuOg0KUHJlY2lvbWlsbG9uPeKIkjE1Ny4zODIyMCswLjk0OTM4eDFpKzY4Ljk5NDM2eDNpKzIyLjY0OTA2eDJpIFIyPTAuNzYyMw0KDQphKUVsIHZhbG9yIGRlbCBSIGN1YWRyYWRvID0gMC43NjIzIHNpZ25pZmljYSBxdWUgbGEgdmFyaWFibGVzOiBhcmVhIGNvbnN0cnVpZGEsIGVzdHJhdG8geSBwYXJxdWFkZXJvcyBleHBsaWNhbiBlbCA3NiUgZGVsIHByZWNpbyBkZWwgYXBhcnRhbWVudG8uDQpiKVNlIHB1ZWRlbiBpbnRlcnByZXRhciBsb3MgZWZlY3RvcyBCIGRlIGxhIHNpZ3VpZW50ZSBmb3JtYToNCi1TaSBlbCDDoXJlYSBjb25zdHJ1aWRhIGRlIGxhIHZpdmllbmRhIGF1bWVudGEgMW10czIsIHNlIGVzcGVyYSBxdWUgZWwgcHJlY2lvIHBvciBtaWxsb24gZGUgbGEgdml2aWVuZGEgYXVtZW50ZSBlbiAtLjk0IG1pbGxvbmVzLg0KLVNpIGVsIGVzdHJhdG8gZGUgbGEgdml2aWVuZGEgYXVtZW50YSBlbiAxLCBlbCBwcmVjaW8gcG9yIG1pbGxvbiBkZSBsYSB2aXZpZW5kYSBhdW1lbnRlIGVuIDIyLjY0IG1pbGxvbmVzLg0KLVBvciBjYWRhIHBhcnF1ZWFkZXJvIGFkaWNpb25hbCwgc2UgZXNwZXJhIHF1ZSBlbCBwcmVjaW8gcG9yIG1pbGxvbiBkZSBsYSB2aXZpZW5kYSBhdW1lbnRlIGVuIDE1LjU1NjYxIG1pbGxvbmVzLg0KLUVuIGVzdGUgY29udGV4dG8gZWwgaW50ZXJjZXB0byBkZSAtMTU3LjM4LCBsbyBxdWUgbm8gZXMgbMOzZ2ljbyBwb3JxdWUgbm8gaGF5IHVuIGNvc3RvIGRlIHZhbG9yIG5lZ2F0aXZvIHBhcmEgdW5hIHZpdmllbmRhDQotRWwgY29lZmljaWVudGUgUjIgYWp1c3RhZG8gZGUgMC43NiBsbyBxdWUgaW5kaWNhIHF1ZSBlbCBwcmVjaW8gZGUgbGEgdml2aWVuZGEgZXMgZXhwbGljYWRvIHBvciBlbCBtb2RlbG8gZW4gdW4gNzYlDQoNCg0KIyMgKipQdW50byBkLiBSZWFsaWNlIGxhIHZhbGlkYWNpw7NuIGRlIHN1cHVlc3RvcyBkZWwgbW9kZWxvIGUgaW50ZXJwcmV0ZSBsb3MgcmVzdWx0YWRvcyAobm8gZXMgbmVjZXNhcmlvIGNvcnJlZ2lyIGVuIGNhc28gZGUgcHJlc2VudGFyIHByb2JsZW1hcyBzb2xvIHJlYWxpemFyIHN1Z2VyZW5jaWFzIGRlIHF1ZSBzZSBwb2Ryw61hIGhhY2VyKS4qKg0KYGBge3J9DQpwYXIobWZyb3cgPSBjKDIsIDIpKQ0KcGxvdChtb2RlbG9fdml2aWVuZGFzKQ0KYGBgDQpgYGB7cn0NCmxpYnJhcnkobG10ZXN0KQ0KYnB0ZXN0KG1vZGVsb192aXZpZW5kYXMpDQpgYGANCg0KUmVzdWx0YWRvOlNlZ8O6biBsYXMgZ3LDoWZpY2FzIHNlIHB1ZWRlIGNvbmNsdWlyIGxvIHNpZ3VpZW50ZTogDQoxKUdyw6BmaWNhIE5vcm1hbFFROiBkIGVzIHBvc2libGUgZXZpZGVuY2lhciBxdWUgbG9zIGVycm9yZXMgbm8gc2lndWVuIGVsIHN1cHVlc3RvIGRlIG5vcm1hbGlkYWQuDQoyKUFzaW1pc21vLCBsb3MgcmVzaWR1YWxlcyAgbm8gc29uIGhvbW9jZWRhc3RpY29zIGRlIGFjdWVyZG8gY29uIGxhIGdyw6FmaWNhIFNjYWxlIExvY2F0aW9uIHkgbGEgcHJ1ZWJhIGRlIEJyZXVzaC1QYWdhbiwgbGEgY3VhbCBkaW8gdW4gcF92YWxvciBtdXkgcHLDs3hpbW8gYSAwIHBvciBsbyBxdWUgc2UgcmVjaGF6YSBsYSBoaXBvdGVzaXMgbnVsYSBkZSBob21vY2VkYXN0aWNpZGFkLiBTZSBjb25jbHV5ZSBxdWUgIGxvcyByZXNpZHVhbGVzIG5vIGN1bXBsZW4gY29uIGVsIHN1cHVlc3RvIGRlIG5vcm1hbGlkYWQgbmkgaG9tb2NlZGFzdGljaWRhZCwgcG9yIGxvIHF1ZSBsb3MgZGF0b3Mgbm8gc2UgYWp1c3RhbiBhZGVjdWFkYW1lbnRlIGEgdW4gbW9kZWxvIGxpbmVhbC4NCg0KDQojIyAqKlB1bnRvIGUuIENvbiBlbCBtb2RlbG8gaWRlbnRpZmljYWRvIHByZWRlY2lyIGVsIHByZWNpbyBkZSB1biBhcGFydGFtZW50byBjb24gMTAwIG10MiwgZGUgZXN0cmF0byA0IHkgY29uIHBhcnF1ZWFkZXJvLiDCv1NpIGVzdGUgYXBhcnRhbWVudG8gbG8gZXN0w6FuIG9mcmVjaWVuZG8gZW4gNDUwIG1pbGxvbmVzIGN1YWwgc2VyaWEgc3Ugb3BpbmnDs24gY29uIGJhc2UgZW4gZWwgcmVzdWx0YWRvIGRlbCBtb2RlbG8gY29uc2lkZXJhIHF1ZSBlcyB1bmEgYnVlbmEgb2ZlcnRhPyoqDQpgYGB7cn0NCi00NzMuMjkrKDAuOTc4NyoxMDApKyg4Ny4xMSoxKSsoMTI1LjI0KjQpDQpgYGANClJlc3VsdGFkbzogQ29uc2lkZXJhbmRvIGxvcyB2YWxvcmVzIG9idGVuaWRvcyBkZWwgbW9kZWxvLCBubyBlcyBidWVuYSBvcGNpw7NuIGNvbXByYXIgZWwgYXBhcnRhbWVudG8gcXVlIGVzdGFuIG9mcmVjaWVuZG8gcG9yIDQ1MCBtaWxsb25lcywgZGFkbyBxdWUgZWwgbW9kZWxvIHJlZ2lzdHJhIHVuIHZhbG9yIGRlIGNvbXByYSBhcHJveGltYWRvIGRlIDIxMiBtaWxsb25lcy4NCg0KIyMgKipQdW50byBmLkNvbiBsYXMgcHJlZGljY2lvbmVzIGRlbCBtb2RlbG8gc3VnaWVyYSBwb3RlbmNpYWxlcyBvZmVydGFzIHBhcmEgdW5hIHBlcnNvbmEgaW50ZXJlc2FkYSBlbiB1biBhcGFydGFtZW50byBlbiBsYSB6b25hIG5vcnRlIGNvbiBtYXMgZGUgMTAwIG10MiBkZSDDoXJlYSwgZGUgZXN0cmF0byA0LCBxdWUgdGVuZ2EgcGFycXVlYWRlcm8geSB0ZW5nYSBlbmN1ZW50YSBxdWUgbGEgcGVyc29uYSB0aWVuZSB1biBjcsOpZGl0byBwcmVhcHJvYmFkbyBkZSBtw6F4aW1vIDQwMCBtaWxsb25lcyBkZSBwZXNvcy4gUmVhbGljZSB1biBhbsOhbGlzaXMgeSBwcmVzZW50ZSBlbiB1biBtYXBhIGFsIG1lbm9zIDUgb2ZlcnRhcyBwb3RlbmNpYWxlcyBxdWUgZGViZSBkaXNjdXRpcioqDQoNCmBgYHtyfQ0Kb2ZlcnRhID0gd2hpY2goZGF0b3Nfdml2aWVuZGEkVGlwbz09IkFwYXJ0YW1lbnRvIiYgZGF0b3Nfdml2aWVuZGEkWm9uYT09IlpvbmEgTm9ydGUiJiBkYXRvc192aXZpZW5kYSRwcmVjaW9fbWlsbG9uPD00MDAgJiBkYXRvc192aXZpZW5kYSRBcmVhX2NvbnRydWlkYT4xMDAgJiBkYXRvc192aXZpZW5kYSRFc3RyYXRvID09IDQgJiBkYXRvc192aXZpZW5kYSRwYXJxdWVhZGVyb3MgPj0gMSkNCm9mZXJ0YV8yPWRhdG9zX3ZpdmllbmRhW29mZXJ0YSxdDQpvZmVydGFfZmluYWwgPSBoZWFkKG9mZXJ0YV8yLDUpDQpvZmVydGFfZmluYWwNCmBgYA0KDQpgYGB7cn0NCm9mZXJ0YTEgPSBwcmVkaWN0KG1vZGVsb192aXZpZW5kYXMsbGlzdChBcmVhX2NvbnRydWlkYT0xMjMsRXN0cmF0bz00LHBhcnF1ZWFkZXJvcz0xKSkNCm9mZXJ0YTIgPSBwcmVkaWN0KG1vZGVsb192aXZpZW5kYXMsbGlzdChBcmVhX2NvbnRydWlkYT0xMzAsRXN0cmF0bz00LHBhcnF1ZWFkZXJvcz0xKSkNCm9mZXJ0YTMgPSBwcmVkaWN0KG1vZGVsb192aXZpZW5kYXMsbGlzdChBcmVhX2NvbnRydWlkYT0xMDgsRXN0cmF0bz00LHBhcnF1ZWFkZXJvcz0xKSkNCm9mZXJ0YTQgPSBwcmVkaWN0KG1vZGVsb192aXZpZW5kYXMsbGlzdChBcmVhX2NvbnRydWlkYT0xMDQsRXN0cmF0bz00LHBhcnF1ZWFkZXJvcz0xKSkNCm9mZXJ0YTUgPSBwcmVkaWN0KG1vZGVsb192aXZpZW5kYXMsbGlzdChBcmVhX2NvbnRydWlkYT0xMjUsRXN0cmF0bz00LHBhcnF1ZWFkZXJvcz0yKSkNCmRhdGEuZnJhbWUob2ZlcnRhMSxvZmVydGEyLG9mZXJ0YTMsb2ZlcnRhNCxvZmVydGE1KQ0KDQpgYGANCg0KUmVzdWx0YWRvOiBDb25zaWRlcmFuZG8gcXVlIGxhIHBlcnNvbmEgdGllbmUgdW4gY3LDqWRpdG8gcHJlYXByb2JhZG8gcG9yIHVuIHZhbG9yIGRlIDQwMCBtaWxsb25lcyAgc2Ugc3VnaWVyZSBhbCBjb21wcmFkb3Igb2ZlcnRhcyBkZSBhcGFydGFtZW50byBlbiB6b25hIG5vcnRlLCBlc3RyYXRvIDQgeSBjb24gcG9zaWJpbGlkYWQgZGUgMSBvIDIgcGFycXVlYWRlcm9zIHkgw6FyZWEgY29uc3RydWlkYSBtYXlvciBhIDEwMG10Mi4gQ3VhbHF1aWVyYSBkZSBsYXMgb2ZlcnRhcyBhbGNhbnphIGFsIGNvbXByYWRvciwgc2Vnw7puIGVsIHByZWFwcm9iYWRvIGNvbiBlbCBxdWUgY3VlbnRhLiANCg0KYGBge3J9DQpsaWJyYXJ5KGxlYWZsZXQpDQpsZWFmbGV0KCkgJT4lIGFkZENpcmNsZU1hcmtlcnMobG5nID0gb2ZlcnRhX2ZpbmFsJGNvcmRlbmFkYV9sb25naXR1ZCxsYXQgPSBvZmVydGFfZmluYWwkQ29yZGVuYWRhX2xhdGl0dWQscmFkaXVzID0gNSxjb2xvciA9ICJyZWQiLGxhYmVsID0gb2ZlcnRhX2RlZiRJRCkgJT4lIGFkZFRpbGVzKCkNCmBgYA0KDQojIyAqKlB1bnRvIDQgQ29uIGJhc2UgZW4gbG9zIGRhdG9zIGRlIGFyYm9sZXMgcHJvcG9uZ2EgdW4gbW9kZWxvIGRlIHJlZ3Jlc2nDs24gbGluZWFsIG3Dumx0aXBsZSBxdWUgcGVybWl0YSBwcmVkZWNpciBlbCBwZXNvIGRlbCDDoXJib2wgZW4gZnVuY2nDs24gZGUgbGFzIGNvdmFyaWFibGVzIHF1ZSBjb25zaWRlcmUgaW1wb3J0YW50ZXMgeSBzZWxlY2Npb27DoW5kb2xhcyBkZSBhY3VlcmRvIGNvbiB1biBwcm9jZXNvIGFkZWN1YWRvLiBUZW5nYSBlbiBjdWVudGEgcmVhbGl6YXIgdW5hIGV2YWx1YWNpw7NuIGRlIGxhIHNpZ25pZmljYW5jaWEgZGUgbG9zIHBhcsOhbWV0cm9zLCBpbnRlcnByZXRhY2nDs24geSBwcm9wb25nYSB1biBtw6l0b2RvIGRlIGV2YWx1YWNpw7NuIHBvciBtZWRpbyBkZSB2YWxpZGFjacOzbiBjcnV6YWRhLiBQcmVzZW50ZSBtw6l0cmljYXMgYXByb3BpYWRhcyBjb21vIGVsIFJNU0UgeSBNQUUuKioNCg0KYGBge3J9DQoNCmxpYnJhcnkocmVhZHhsKQ0KZGF0YWFyYm9sZXMgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvYXN1cy9EZXNrdG9wL2RhdGFhcmJvbGVzLnhsc3giLCANCiAgICBjb2xfdHlwZXMgPSBjKCJ0ZXh0IiwgInRleHQiLCAibnVtZXJpYyIsIA0KICAgICAgICAibnVtZXJpYyIsICJudW1lcmljIikpDQpWaWV3KGRhdGFhcmJvbGVzKQ0KYGBgDQoNCmBgYHtyfQ0KZGF0YWFyYm9sZXM9ZGF0YWFyYm9sZXNbLCAzOjVdDQphdHRhY2goZGF0YWFyYm9sZXMpDQpuYW1lcyhkYXRhYXJib2xlcykNCmBgYA0KYGBge3J9DQpnZ3BhaXJzKGRhdGFhcmJvbGVzLCBsb3dlciA9IGxpc3QoY29udGludW91cyA9ICJzbW9vdGgiKSwNCiAgICAgICAgZGlhZyA9IGxpc3QoY29udGludW91cyA9ICJiYXJEaWFnIiksIGF4aXNMYWJlbHMgPSAibm9uZSIpDQpgYGANClJlc3VsdGFkbzogZGUgbGFzIGdyw6FmaWNhcyBzZSBwdWVkZSBjb25jbHVpciBxdWUgbGFzIHZhcmlhYmxlcyBxdWUgdGllbmVuIHVuYSBtYXlvciByZWxhY2nDs24gbGluZWFsIGNvbiBsYSBwZXNvIHNvbiBlbCBkaWFtZXRybyAoMC45MDgpLCBhbHR1cmEgKCAwLjg1OCkuIFRhbWJpZW4sIGUgZGlhbWV0cm8geSBhbHR1cmEgZXN0w6FuICBjb3JyZWxhY2lvbmFkb3MgKCAwLjkzNikuIA0KDQojIyAqKk1vZGVsbyBkZSByZWdyZXNpw7NuIG11bHRpcGxlKioNCg0KYGBge3J9DQpzZXQuc2VlZCgxKQ0KdHJhaW4gPC0gc2FtcGxlKHggPSAxOjkwLCA3MikNCm1vZGVsb19hcmJvbGVzIDwtIGxtKHBlc29+ZGlhbWV0cm8gKyBhbHR1cmEsIGRhdGEgPSBhcmJvbGVzLCBzdWJzZXQgPSB0cmFpbikNCnN1bW1hcnkobW9kZWxvX2FyYm9sZXMpDQpgYGANCkNvbiBsb3MgcmVzdWx0YWRvcyBhbnRlcmlvcmVzIHNlIHB1ZWRlIGV4cHJlc2FyIGVsIG1vZGVsbyBhanVzdGFkbyBjb21vIHNlIG11ZXN0cmEgYSBjb250aW51YWNpw7NuOg0KWSgpPeKIkjkuMjkrNC4wMuKIl1gxKERpYW1ldHJvKSswLjk44oiXWDIoQWx0dXJhKQ0KU2UgcHVlZGVuIGludGVycHJldGFyIGxvcyBlZmVjdG9zIM6yIGRlIGxhIHNpZ3VpZW50ZSBmb3JtYToNCl8gRGUgYWN1ZXJkbyBhIGxvcyBjw6FsY3Vsb3Mgb2JzZXJ2YWRvcyBzaSBlbCBkacOhbWV0cm8gZGVsIMOhcmJvbCBhdW1lbnRhIGVuIHVuYSB1bmlkYWQsIHNlIGVzcGVyYSBxdWUgZWwgcGVzbyBkZWwgw6FyYm9sIGF1bWVudGUgZW4gNC4wMiB1bmlkYWRlcy4NCl8gRGUgaWd1YWwgbWFuZXJhIHNlIHB1ZWRlIGluZGljYXIgcXVlIHBvciBjYWRhIG1ldHJvIGFkaWNpb25hbCBlbiBsYSBhbHR1cmEgZGVsIMOhcmJvbCwgc2UgZXNwZXJhcsOtYSBxdWUgZWwgcGVzbyBkZWwgw6FyYm9sIGF1bWVudGUgZW4gMC45OCB1bmlkYWRlcy4NCl8gRGUgZXN0YSBtYW5lcmEgZWwgaW50ZXJjZXB0byBkZSAtOS4xMjA1LCBubyBlcyB1biB2YWxvciAsIGRhZG8gcXVlIG5vIGRlYmVyw61hIGV4aXN0aXIgdW4gw6FyYm9sIGNvbiB1biBwZXNvIG5lZ2F0aXZvLg0KXyBEZSBpZ3VhbCBmb3JtYSBlbCBjb2VmaWNpZW50ZSBSMiBhanVzdGFkbyB0b21hIHVuIHZhbG9yIGRlIDAuODMsIGxvIGN1YWwgaW5kaWNhIHF1ZSBlbCBwZXNvIGRlbCDDoXJib2wgZXMgZXhwbGljYWRvIHBvciBlbCBtb2RlbG8gY29uIHVuIDgzJS4NCg0KDQpgYGB7cn0NCnBhcihtZnJvdz1jKDIsMikpDQpwbG90KG1vZGVsb19hcmJvbGVzKQ0KDQpgYGANCiMjICoqVmFsaWRhY2nDs24gZGVsIG1vZGVsbyoqDQpSZXN1bHRhZG86IDEuIE1lZGlhIGNlcm86IFNlIGN1bXBsZSBwb3IgZGVmZWN0by4gMi4gVmFyaWFuemEgQ29uc3RhbnRlOiBTZSBvYnNlcnZhIGVuIGxhIGdyYWZpY2EgMSBkZSByZXNpZHVhbGVzIHZzIGFqdXN0YWRvcyBxdWUgZWwgY29tcG9ydGFtaWVudG8gZXMgYWxlYXRvcmlvIG1vc3RyYW5kbyB1bmEgbGV2ZSBjdXJ2YSBoYWNpYSBhYmFqby4gMy4gTm9ybWFsaWRhZDogU2Ugb2JzZXJ2YSBlbiBsYSBncmFmaWNhIDIgcXVlIGxvcyBkYXRvcyBzZSBhanVzdGFuIGJpZW4gYSBsYSBsaW5lYSBkZSBub3JtYWxpZGFkIGVuIGVsIHFxcGxvdCA0LiBJbmRlcGVuZGVuY2lhOiBEYWRvIHF1ZSBlc3RvcyByZWdpc3Ryb3Mgbm8gY29ycmVzcG9uZGVuIGEgZGF0b3MgZW4gZWwgdGllbXBvIG5vIHNlIHRpZW5lIHVuIG9yZGVuIHRlbXBvcmFsIHBhcmEgcmVhbGl6YXIgbGEgdmFsaWRhY2nDs24gZGUgZXN0ZSBzdXB1ZXN0by4NCg0KIEhpcMOzdGVzaXMgbnVsYSBIMDogUGFyYSBlc3RlIGNhc28gZWwgY29lZmljaWVudGUgQjEgbm8gYXBvcnRhIGFsIG1vZGVsbyBwcm9wdWVzdG8sIGRhZG8gcXVlIGVsIHAtdmFsdWUgZXMgbWVub3IgYWwgMC4wNSBjb24gdmFsb3IgY29ycmVzcG9uZGllbnRlIGEuKDYuNDNlLTA2ICksIHJlY2hhemFtb3MgbGEgaGlww7N0ZXNpcyBudWxhLCB5IHNlIHB1ZWRlIGNvbmNsdWlyIHF1ZSBlbCBjb2VmaWNpZW50ZSBCMSBzaSBhcG9ydGEgYWwgbW9kZWxvIGRlIHJlZ3Jlc2nDs24gcHJvcHVlc3RvLg0KDQpfIEhpcMOzdGVzaXMgbnVsYSBIMDogUGFyYSBlc3RlIGNhc28gZWwgY29lZmljaWVudGUgQjIgbm8gYXBvcnRhIGFsIG1vZGVsbyBwcm9wdWVzdG8sIGNvbW8gZWwgcC12YWx1ZSBlcyBtYXlvciBhbCAwLjA1ICgwLjEzNiksIE5PIHJlY2hhemFtb3MgbGEgaGlww7N0ZXNpcyBudWxhLCB5IGNvbmNsdWltb3MgcXVlIGVsIGNvZWZpY2llbnRlIEIyIE5PIGFwb3J0YSBhbCBtb2RlbG8gZGUgcmVncmVzacOzbiBwcm9wdWVzdG8uDQoNCiMjICoqTcOpdHJpY2FzIFJNU0UgeSBNQUUqKg0KYGBge3J9DQpwcmVkaWNjaW9uX2FyYm9sZXMgPC0gcHJlZGljdChvYmplY3QgPSBtb2RlbG9fYXJib2xlcywgbmV3ZGF0YSA9IGRhdGFhcmJvbGVzWy10cmFpbiwgXSkNCmVycm9yX2FyYm9sZXMgPC0gbWVhbigoZGF0YWFyYm9sZXMkcGVzb1stdHJhaW5dIC0gcHJlZGljY2lvbl9hcmJvbGVzKV4yKQ0KZXJyb3JfYXJib2xlcw0KYGBgDQpgYGB7cn0NCmxpYnJhcnkoTWV0cmljcykNCm1hZShhcmJvbGVzJHBlc29bLXRyYWluXSwgcHJlZGljY2lvbl9hcmJvbGVzKQ0KYGBgDQpSZXN1bHRhZG86IFRlbmllbmRvIGVuIGN1ZW50YSBsYXMgdmFsaWRhY2lvbmVzIHNlIHB1ZWRlIGluZGljYXIgcXVlIGVsIG1vZGVsbyBzZSBlcXVpdm9jYSAgZW4gdW4gMTMlIGRlbCBwZXNvIHByb21lZGlvIGRlIGFjdWVyZG8gYWwgTUFFIHkgbGEgZGVzdmlhY2nDs24gZXN0w6FuZGFyIGRlIGxhIHZhcmlhbnphIGluZXhwbGljYWRhIGVzIGRlIDMuMCBkZSBhY3VlcmRvIGFsIFJNU0UuDQoNCg==