Regresión lineal simple

Estimación de los coeficientes de regresión

library(readxl)
datos <- read_excel("base de datos.xlsx")
head(datos)
## # A tibble: 6 x 14
##      crim    zn indus  chas   nox    rm   age   dis   rad   tax ptratio black
##     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>   <dbl> <dbl>
## 1 0.00632    18  2.31     0 0.538  6.58  65.2  4.09     1   296    15.3  397.
## 2 0.0273      0  7.07     0 0.469  6.42  78.9  4.97     2   242    17.8  397.
## 3 0.0273      0  7.07     0 0.469  7.18  61.1  4.97     2   242    17.8  393.
## 4 0.0324      0  2.18     0 0.458  7.00  45.8  6.06     3   222    18.7  395.
## 5 0.0690      0  2.18     0 0.458  7.15  54.2  6.06     3   222    18.7  397.
## 6 0.0298      0  2.18     0 0.458  6.43  58.7  6.06     3   222    18.7  394.
## # ... with 2 more variables: lstat <dbl>, medv <dbl>

Como se trata de regresión lineal simple, entonces vamos escoger solo dos variables:

Variable independiente X: promedio de habitaciones por vivienda.

Variable dependiente Y: Valor mediano de las casas ocupadas por el dueño en unidades de $1000s.

X<-datos$rm
Y<-datos$medv
data<-data.frame(X,Y)

Empleando la función lm() se genera un modelo de regresión lineal por mínimos cuadrados en el que la variable respuesta es medv (Y) y el predictor rm (X)

modelo <- lm(Y ~ X, data=data)
modelo$coefficients
## (Intercept)           X 
##  -34.670621    9.102109

De donde: bo = -34.67 y b1 = 9.10

Con estos datos, podemos decir que la ecuación de regresión estimada es:

y = -34.67 + 9.1x

El b1 = 9.10 significa que si el promedio de habitaciones por vivienda se incremente en 1%, entonces en promedio el valor mediano de las casas ocupadas aumenta en 9.10 unidades.

Luiggi Bravo

Intervalo de confianza para los coeficientes de regresión

Una forma sencilla de calcular los intervalos de confianza para los coeficientes es utilizar la función coefci(), de la paquetería lmtest, solo debemos indicar el objeto donde se encuentra la regresión y el nivel de confianza que sea desea:

library(lmtest)
coefci(modelo, level=.95)
##                  2.5 %     97.5 %
## (Intercept) -39.876641 -29.464601
## X             8.278855   9.925363

Luego el intervalo de confianza para b1 es 8.278 ≤ b1 ≤ 9.925363

La interpretación de este intervalo de confianza es: Dado el coeficiente de confianza de 95%, en 95 de cada 100 casos, los intervalos como 8.278 ≤ b1 ≤ 9.925363 contendrán al verdadero valor de b1.

Otra forma de obtener los coeficientes de regresión es mediante el siguiente código:

library(printr)
library(broom)
resultado<-modelo %>%
tidy()
names(resultado)<-c("Variable", "beta", "Error_estandar","t","p_value")
resultado
Variable beta Error_estandar t p_value
(Intercept) -34.670621 2.6498030 -13.08423 0
X 9.102109 0.4190266 21.72203 0

Prueba de hipótesis de la regresión

Ho: b1 = 0 (El promedio de habitaciones por vivienda no influye en el valor mediano de las casas ocupadas por el dueño.)

Ha: b1 != 0 (El promedio de habitaciones por vivienda influye en el valor mediano de las casas ocupadas por el dueño.)

modelo %>% aov() %>% summary()
##              Df Sum Sq Mean Sq F value              Pr(>F)    
## X             1  20654   20654   471.8 <0.0000000000000002 ***
## Residuals   504  22062      44                                
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

El punto crítico para esta prueba es F0.95,1,504 = 3.86 y dado que Fcal = 471.8 > F0.95,1,504 = 3.86, se rechaza la Ho; por lo tanto; al nivel de 0.05 de significancia, existe suficiente evidencia estadística para indicar que el valor mediano de las casas ocupadas por el dueño depende del porcentaje de población que se encuentra en condición de pobreza.

p − valor < 0.05, se rechaza la Ho.

Estimación de la variabilidad

Varianza de la regresión

summary(modelo)$sigma**2
## [1] 43.77357

Desviación estandar de regresión

summary(modelo)$sigma
## [1] 6.61616

Intervalo de confianza para la varianza de la regresión con α = 0.10

LI.var = sum(modelo$residuals**2)/qchisq(0.95,df=504)
LI.var
## [1] 39.58462
LS.var = sum(modelo$residuals**2)/qchisq(0.05,df=504)
LS.var
## [1] 48.70828

Ajuste del modelo

Coeficiente de determinación

summary(modelo)$r.squared
## [1] 0.4835255

R2 = 48.35 lo que significa que el predictor X (promedio de habitaciones por vivienda) empleado en el modelo es capaz de explicar el 48.35% de la variabilidad observada en el precio de las viviendas.

Estimación y predicción

Estimación de la media

predConf<-predict(modelo,interval="confidence",level=0.95)
ICMeanY<-cbind(X, Y,predConf)
head(ICMeanY)
X Y fit lwr upr
6.575 24.0 25.17575 24.55039 25.80110
6.421 21.6 23.77402 23.18536 24.36269
7.185 34.7 30.72803 29.78817 31.66790
6.998 33.4 29.02594 28.20203 29.84984
7.147 36.2 30.38215 29.46676 31.29755
6.430 28.7 23.85594 23.26582 24.44606

Por ejemplo para xo = 6.575 se obtiene el intervalo de confianza 24.55 ≤ µY /x0 ≤ 25.80.

Esto es, si el promedio de habitaciones por vivienda es de 6.58, se estima que en promedio el valor mediano de las casas ocupadas por el dueño se encuentre entre 24.55 y 25.80.

Tambien para un valor específico de xo se puede hacer la estimación; por ejemplo para xo = 7.1

modelo %>% predict(data.frame(X=7.1),
interval = "confidence",
level = 0.95)
fit lwr upr
29.95435 29.06863 30.84007

Lo que significa que para xo = 7.1 se obtiene el intervalo de confianza 29.07 ≤ µY /x0 ≤ 30.84. Esto es, si el promedio de habitaciones por vivienda es de 7.1, se estima que en promedio el valor mediano de las casas ocupadas por el dueño se encuentre entre 29.07 y 30.84.

Para ver la gráfica de dispersión ejecute las siguientes lineas de código.

ggplot(data = data, aes(x = X, y = Y)) + geom_point() + geom_smooth(formula = y ~ x,
method = "lm", se = TRUE, color = "firebrick") + theme_bw() + labs(x = "promedio de habitaciones por vivienda", y = "Valor mediano de las casas ocupadas")

Predicción para una nueva observación Yo

S<-data
head(S)
X Y
6.575 24.0
6.421 21.6
7.185 34.7
6.998 33.4
7.147 36.2
6.430 28.7
predY<-predict(modelo,S,interval="prediction",level=0.95)
IPY<-cbind(X, Y,predY)
head(IPY)
X Y fit lwr upr
6.575 24.0 25.17575 12.16206 38.18943
6.421 21.6 23.77402 10.76205 36.78599
7.185 34.7 30.72803 17.69545 43.76062
6.998 33.4 29.02594 16.00120 42.05067
7.147 36.2 30.38215 17.35131 43.41299
6.430 28.7 23.85594 10.84390 36.86798
xo<-data.frame(X=7.1)
predY<-predict(modelo,xo,interval="prediction",level=0.95)
cbind(xo, predY)
X fit lwr upr
7.1 29.95435 16.92556 42.98314

Para xo = 7.1 se obtiene el intervalo de confianza 16.93 ≤ µY /x0 ≤ 42.98. Esto es, si el promedio de habitaciones por vivienda es de 7.1, se estima que el valor mediano de las casas ocupadas por el dueño se encuentre entre 16.93 y 42.98.

LS0tDQp0aXRsZTogIlRyYWJham8gMDEgLSBBbsOhbGlzaXMgZGUgUmVncmVzacOzbiINCmF1dGhvcjogIkx1aWdnaSBCcmF2byBZYXRhY28gLSAyMDIxMTgwOSINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQpybShsaXN0ID0gbHMoKSkNCmNhdCgiXDAxNCIpDQpncmFwaGljcy5vZmYoKQ0Kb3B0aW9ucyhzY2lwZW49OTk5KQ0KDQojIFBhcXVldGVzDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShwYWNtYW4pDQpwX2xvYWQodGlkeXZlcnNlLCBwZGZ0b29scywgc3RyaW5nciwgcmVhZHhsLCB0aWR5dGV4dCwgdG0sIA0KICAgICAgIHdvcmRjbG91ZDIsIGZvcmNhdHMsIHBhdGNod29yaywgd29yZGNsb3VkKQ0KYGBgDQoNCiMjICoqKlJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSoqKg0KDQoqKkVzdGltYWNpw7NuIGRlIGxvcyBjb2VmaWNpZW50ZXMgZGUgcmVncmVzacOzbioqDQoNCmBgYHtyfQ0KbGlicmFyeShyZWFkeGwpDQpkYXRvcyA8LSByZWFkX2V4Y2VsKCJiYXNlIGRlIGRhdG9zLnhsc3giKQ0KaGVhZChkYXRvcykNCmBgYA0KDQpDb21vIHNlIHRyYXRhIGRlIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZSwgZW50b25jZXMgdmFtb3MgZXNjb2dlciBzb2xvIGRvcyB2YXJpYWJsZXM6DQoNCioqVmFyaWFibGUgaW5kZXBlbmRpZW50ZSBYKio6IHByb21lZGlvIGRlIGhhYml0YWNpb25lcyBwb3Igdml2aWVuZGEuDQoNCioqVmFyaWFibGUgZGVwZW5kaWVudGUgWSoqOiBWYWxvciBtZWRpYW5vIGRlIGxhcyBjYXNhcyBvY3VwYWRhcyBwb3IgZWwgZHVlw7FvIGVuIHVuaWRhZGVzIGRlICQxMDAwcy4NCg0KYGBge3J9DQpYPC1kYXRvcyRybQ0KWTwtZGF0b3MkbWVkdg0KZGF0YTwtZGF0YS5mcmFtZShYLFkpDQpgYGANCg0KRW1wbGVhbmRvIGxhIGZ1bmNpw7NuIGxtKCkgc2UgZ2VuZXJhIHVuIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBwb3IgbcOtbmltb3MgY3VhZHJhZG9zIGVuIGVsIHF1ZSBsYSB2YXJpYWJsZSByZXNwdWVzdGEgZXMgbWVkdiAoWSkgeSBlbCBwcmVkaWN0b3Igcm0gKFgpDQoNCmBgYHtyfQ0KbW9kZWxvIDwtIGxtKFkgfiBYLCBkYXRhPWRhdGEpDQptb2RlbG8kY29lZmZpY2llbnRzDQpgYGANCg0KRGUgZG9uZGU6IGJvID0gLTM0LjY3IHkgYjEgPSA5LjEwIA0KDQpDb24gZXN0b3MgZGF0b3MsIHBvZGVtb3MgZGVjaXIgcXVlIGxhIGVjdWFjacOzbiBkZSByZWdyZXNpw7NuIGVzdGltYWRhIGVzOg0KDQogICoqeSA9IC0zNC42NyArIDkuMXgqKg0KICANCkVsIGIxID0gOS4xMCBzaWduaWZpY2EgcXVlIHNpIGVsIHByb21lZGlvIGRlIGhhYml0YWNpb25lcyBwb3Igdml2aWVuZGEgc2UgKippbmNyZW1lbnRlIGVuIDElKiosIGVudG9uY2VzIGVuIHByb21lZGlvIGVsIHZhbG9yIG1lZGlhbm8gZGUgbGFzIGNhc2FzIG9jdXBhZGFzICoqYXVtZW50YSBlbiA5LjEwIHVuaWRhZGVzKiouDQoNCg0KTHVpZ2dpIEJyYXZvIFsyMDIxMTgwOVxAbGFtb2xpbmEuZWR1LnBlXShtYWlsdG86MjAyMTE4MDlAbGFtb2xpbmEuZWR1LnBlKXsuZW1haWx9DQoNCg0KKipJbnRlcnZhbG8gZGUgY29uZmlhbnphIHBhcmEgbG9zIGNvZWZpY2llbnRlcyBkZSByZWdyZXNpw7NuKioNCg0KVW5hIGZvcm1hIHNlbmNpbGxhIGRlIGNhbGN1bGFyIGxvcyBpbnRlcnZhbG9zIGRlIGNvbmZpYW56YSBwYXJhIGxvcyBjb2VmaWNpZW50ZXMgZXMgdXRpbGl6YXIgbGEgZnVuY2nDs24gY29lZmNpKCksDQpkZSBsYSBwYXF1ZXRlcsOtYSBsbXRlc3QsIHNvbG8gZGViZW1vcyBpbmRpY2FyIGVsIG9iamV0byBkb25kZSBzZSBlbmN1ZW50cmEgbGEgcmVncmVzacOzbiB5IGVsIG5pdmVsIGRlIGNvbmZpYW56YQ0KcXVlIHNlYSBkZXNlYToNCg0KYGBge3J9DQpsaWJyYXJ5KGxtdGVzdCkNCmNvZWZjaShtb2RlbG8sIGxldmVsPS45NSkNCmBgYA0KDQpMdWVnbyBlbCBpbnRlcnZhbG8gZGUgY29uZmlhbnphIHBhcmEgYjEgZXMgOC4yNzgg4omkIGIxIOKJpCA5LjkyNTM2Mw0KDQpMYSBpbnRlcnByZXRhY2nDs24gZGUgZXN0ZSBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGVzOiBEYWRvIGVsIGNvZWZpY2llbnRlIGRlIGNvbmZpYW56YSBkZSA5NSUsIGVuIDk1IGRlIGNhZGEgMTAwIGNhc29zLCBsb3MgaW50ZXJ2YWxvcyBjb21vIDguMjc4IOKJpCBiMSDiiaQgOS45MjUzNjMgY29udGVuZHLDoW4gYWwgdmVyZGFkZXJvIHZhbG9yIGRlIGIxLg0KDQoNCk90cmEgZm9ybWEgZGUgb2J0ZW5lciBsb3MgY29lZmljaWVudGVzIGRlIHJlZ3Jlc2nDs24gZXMgbWVkaWFudGUgZWwgc2lndWllbnRlIGPDs2RpZ286DQoNCmBgYHtyfQ0KbGlicmFyeShwcmludHIpDQpsaWJyYXJ5KGJyb29tKQ0KcmVzdWx0YWRvPC1tb2RlbG8gJT4lDQp0aWR5KCkNCm5hbWVzKHJlc3VsdGFkbyk8LWMoIlZhcmlhYmxlIiwgImJldGEiLCAiRXJyb3JfZXN0YW5kYXIiLCJ0IiwicF92YWx1ZSIpDQpyZXN1bHRhZG8NCmBgYA0KDQoNCioqUHJ1ZWJhIGRlIGhpcMOzdGVzaXMgZGUgbGEgcmVncmVzacOzbioqDQoNCkhvOiBiMSA9IDAgKEVsIHByb21lZGlvIGRlIGhhYml0YWNpb25lcyBwb3Igdml2aWVuZGEgbm8gaW5mbHV5ZSBlbiBlbCB2YWxvciBtZWRpYW5vIGRlIGxhcyBjYXNhcyBvY3VwYWRhcyBwb3IgZWwgZHVlw7FvLikNCg0KSGE6IGIxICE9IDAgKEVsIHByb21lZGlvIGRlIGhhYml0YWNpb25lcyBwb3Igdml2aWVuZGEgaW5mbHV5ZSBlbiBlbCB2YWxvciBtZWRpYW5vIGRlIGxhcyBjYXNhcyBvY3VwYWRhcyBwb3IgZWwgZHVlw7FvLikNCg0KYGBge3J9DQptb2RlbG8gJT4lIGFvdigpICU+JSBzdW1tYXJ5KCkNCmBgYA0KDQpFbCBwdW50byBjcsOtdGljbyBwYXJhIGVzdGEgcHJ1ZWJhIGVzIEYwLjk1LDEsNTA0ID0gMy44NiB5IGRhZG8gcXVlIEZjYWwgPSA0NzEuOCA+IEYwLjk1LDEsNTA0ID0gMy44Niwgc2UgcmVjaGF6YQ0KbGEgSG87IHBvciBsbyB0YW50bzsgYWwgbml2ZWwgZGUgMC4wNSBkZSBzaWduaWZpY2FuY2lhLCBleGlzdGUgc3VmaWNpZW50ZSBldmlkZW5jaWEgZXN0YWTDrXN0aWNhIHBhcmEgaW5kaWNhciBxdWUgZWwNCnZhbG9yIG1lZGlhbm8gZGUgbGFzIGNhc2FzIG9jdXBhZGFzIHBvciBlbCBkdWXDsW8gZGVwZW5kZSBkZWwgcG9yY2VudGFqZSBkZSBwb2JsYWNpw7NuIHF1ZSBzZSBlbmN1ZW50cmEgZW4NCmNvbmRpY2nDs24gZGUgcG9icmV6YS4NCg0KcCDiiJIgdmFsb3IgPCAwLjA1LCBzZSByZWNoYXphIGxhIEhvLg0KDQoNCioqRXN0aW1hY2nDs24gZGUgbGEgdmFyaWFiaWxpZGFkKioNCg0KVmFyaWFuemEgZGUgbGEgcmVncmVzacOzbg0KYGBge3J9DQpzdW1tYXJ5KG1vZGVsbykkc2lnbWEqKjINCmBgYA0KDQoNCg0KRGVzdmlhY2nDs24gZXN0YW5kYXIgZGUgcmVncmVzacOzbg0KYGBge3J9DQpzdW1tYXJ5KG1vZGVsbykkc2lnbWENCmBgYA0KDQoNCg0KKipJbnRlcnZhbG8gZGUgY29uZmlhbnphIHBhcmEgbGEgdmFyaWFuemEgZGUgbGEgcmVncmVzacOzbiBjb24gzrEgPSAwLjEwKioNCg0KYGBge3J9DQpMSS52YXIgPSBzdW0obW9kZWxvJHJlc2lkdWFscyoqMikvcWNoaXNxKDAuOTUsZGY9NTA0KQ0KTEkudmFyDQpgYGANCmBgYHtyfQ0KTFMudmFyID0gc3VtKG1vZGVsbyRyZXNpZHVhbHMqKjIpL3FjaGlzcSgwLjA1LGRmPTUwNCkNCkxTLnZhcg0KYGBgDQoNCg0KKipBanVzdGUgZGVsIG1vZGVsbyoqDQoNCkNvZWZpY2llbnRlIGRlIGRldGVybWluYWNpw7NuDQpgYGB7cn0NCnN1bW1hcnkobW9kZWxvKSRyLnNxdWFyZWQNCmBgYA0KUjIgPSA0OC4zNSBsbyBxdWUgc2lnbmlmaWNhIHF1ZSBlbCBwcmVkaWN0b3IgWCAocHJvbWVkaW8gZGUgaGFiaXRhY2lvbmVzIHBvciB2aXZpZW5kYSkgZW1wbGVhZG8gZW4gZWwgbW9kZWxvIGVzIGNhcGF6IGRlIGV4cGxpY2FyIGVsIDQ4LjM1JSBkZSBsYSB2YXJpYWJpbGlkYWQgb2JzZXJ2YWRhIGVuIGVsIHByZWNpbyBkZSBsYXMgdml2aWVuZGFzLg0KDQoNCioqRXN0aW1hY2nDs24geSBwcmVkaWNjacOzbioqDQoNCkVzdGltYWNpw7NuIGRlIGxhIG1lZGlhDQoNCmBgYHtyfQ0KcHJlZENvbmY8LXByZWRpY3QobW9kZWxvLGludGVydmFsPSJjb25maWRlbmNlIixsZXZlbD0wLjk1KQ0KSUNNZWFuWTwtY2JpbmQoWCwgWSxwcmVkQ29uZikNCmhlYWQoSUNNZWFuWSkNCmBgYA0KUG9yIGVqZW1wbG8gcGFyYSB4byA9IDYuNTc1IHNlIG9idGllbmUgZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSAyNC41NSDiiaQgwrVZIC94MCDiiaQgMjUuODAuDQoNCkVzdG8gZXMsIHNpIGVsIHByb21lZGlvIGRlIGhhYml0YWNpb25lcyBwb3Igdml2aWVuZGEgZXMgZGUgNi41OCwgc2UgZXN0aW1hIHF1ZSBlbiBwcm9tZWRpbyBlbCB2YWxvciBtZWRpYW5vIGRlDQpsYXMgY2FzYXMgb2N1cGFkYXMgcG9yIGVsIGR1ZcOxbyBzZSBlbmN1ZW50cmUgZW50cmUgMjQuNTUgeSAyNS44MC4NCg0KDQpUYW1iaWVuIHBhcmEgdW4gdmFsb3IgZXNwZWPDrWZpY28gZGUgeG8gc2UgcHVlZGUgaGFjZXIgbGEgZXN0aW1hY2nDs247IHBvciBlamVtcGxvIHBhcmEgeG8gPSA3LjENCg0KYGBge3J9DQptb2RlbG8gJT4lIHByZWRpY3QoZGF0YS5mcmFtZShYPTcuMSksDQppbnRlcnZhbCA9ICJjb25maWRlbmNlIiwNCmxldmVsID0gMC45NSkNCmBgYA0KTG8gcXVlIHNpZ25pZmljYSBxdWUgcGFyYSB4byA9IDcuMSBzZSBvYnRpZW5lIGVsIGludGVydmFsbyBkZSBjb25maWFuemEgMjkuMDcg4omkIMK1WSAveDAg4omkIDMwLjg0Lg0KRXN0byBlcywgc2kgZWwgcHJvbWVkaW8gZGUgaGFiaXRhY2lvbmVzIHBvciB2aXZpZW5kYSBlcyBkZSA3LjEsIHNlIGVzdGltYSBxdWUgZW4gcHJvbWVkaW8gZWwgdmFsb3IgbWVkaWFubyBkZQ0KbGFzIGNhc2FzIG9jdXBhZGFzIHBvciBlbCBkdWXDsW8gc2UgZW5jdWVudHJlIGVudHJlIDI5LjA3IHkgMzAuODQuDQoNCg0KDQpQYXJhIHZlciBsYSBncsOhZmljYSBkZSBkaXNwZXJzacOzbiBlamVjdXRlIGxhcyBzaWd1aWVudGVzIGxpbmVhcyBkZSBjw7NkaWdvLg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGRhdGEsIGFlcyh4ID0gWCwgeSA9IFkpKSArIGdlb21fcG9pbnQoKSArIGdlb21fc21vb3RoKGZvcm11bGEgPSB5IH4geCwNCm1ldGhvZCA9ICJsbSIsIHNlID0gVFJVRSwgY29sb3IgPSAiZmlyZWJyaWNrIikgKyB0aGVtZV9idygpICsgbGFicyh4ID0gInByb21lZGlvIGRlIGhhYml0YWNpb25lcyBwb3Igdml2aWVuZGEiLCB5ID0gIlZhbG9yIG1lZGlhbm8gZGUgbGFzIGNhc2FzIG9jdXBhZGFzIikNCmBgYA0KDQoNCioqUHJlZGljY2nDs24gcGFyYSB1bmEgbnVldmEgb2JzZXJ2YWNpw7NuIFlvKioNCg0KYGBge3J9DQpTPC1kYXRhDQpoZWFkKFMpDQpgYGANCg0KYGBge3J9DQpwcmVkWTwtcHJlZGljdChtb2RlbG8sUyxpbnRlcnZhbD0icHJlZGljdGlvbiIsbGV2ZWw9MC45NSkNCklQWTwtY2JpbmQoWCwgWSxwcmVkWSkNCmhlYWQoSVBZKQ0KYGBgDQoNCmBgYHtyfQ0KeG88LWRhdGEuZnJhbWUoWD03LjEpDQpwcmVkWTwtcHJlZGljdChtb2RlbG8seG8saW50ZXJ2YWw9InByZWRpY3Rpb24iLGxldmVsPTAuOTUpDQpjYmluZCh4bywgcHJlZFkpDQpgYGANCg0KUGFyYSB4byA9IDcuMSBzZSBvYnRpZW5lIGVsIGludGVydmFsbyBkZSBjb25maWFuemEgMTYuOTMg4omkIMK1WSAveDAg4omkIDQyLjk4Lg0KRXN0byBlcywgc2kgZWwgcHJvbWVkaW8gZGUgaGFiaXRhY2lvbmVzIHBvciB2aXZpZW5kYSBlcyBkZSA3LjEsIHNlIGVzdGltYSBxdWUgZWwgdmFsb3IgbWVkaWFubyBkZSBsYXMgY2FzYXMgb2N1cGFkYXMgcG9yIGVsIGR1ZcOxbyBzZSBlbmN1ZW50cmUgZW50cmUgMTYuOTMgeSA0Mi45OC4NCg0KDQoNCg0KPGRpdiBjbGFzcz0idG9jaWZ5LWV4dGVuZC1wYWdlIiBkYXRhLXVuaXF1ZT0idG9jaWZ5LWV4dGVuZC1wYWdlIiBzdHlsZT0iaGVpZ2h0OjA7Ij48L2Rpdj4NCg==