Introducción.

Para la realización de este proyecto, se pretende reproducir de manera parcial (de acuerdo a los datos disponibles) los resultados del artículo:

Gallagher R, McKinley S, Dracup K. Predictors of women’s attendance at cardiac rehabilitation programs. Prog Cardiovasc Nurs. 2003 Summer;18(3):121-6. doi: 10.1111/j.0889-7204.2003.02129.x. PMID: 12893973.

De este artículo, se realizó un estudio descriptivo para identificar los factores que influyen en la asistencia de las mujeres a los programas de rehabilitación cardíaca y la adherencia de las mujeres a la modificación de los factores de riesgo después de un evento cardíaco.


Metodología seguida en artículo.

El estudio utilizó un diseño descriptivo con medidas al alta hospitalaria y de 12 semanas después del alta. Una muestra de conveniencia de pacientes mujeres (N = 196) fue reclutado de cuatro hospitales metropolitanos en Sydney, Australia. Los programas de rehabilitación cardiaca incluyeron sesiones de ejercicio supervisadas, prescripciones para hacer ejercicio en el hogar y componentes de educación sobre modificación de factores de riesgo. Los programas variaron en duración de 6 a 12 semanas Las mujeres rechazaron la inscripción debido a síntomas (n = 6), falta de interés (n = 5) y falta de voluntad para firmar un formulario de consentimiento (n = 4). La mayoría de las mujeres (n = 183) completaron las 12 semanas de estudio. Las mujeres que no completaron fueron 13, ya que habían muerto (n = 5), retirados (n = 4), o se perdieron durante el seguimiento (n = 4). Para la recolección de datos, se les llamó a estas mujeres y se les preguntaron si habían completado los programas y el por qué no si es que no lo habían hecho.


Resultados del artículo.

Las mujeres (N = 196) ingresadas en el hospital por un evento cardíaco se les dio seguimiento a las 12 semanas después del alta. Solo el 64% (n = 112) había sido referido a programas de rehabilitación cardíaca. A las 12 semanas posteriores al alta, solo el 32% de la muestra total (n = 57) asistía a programas y el 12% de la muestra total (n = 21) había abandonado antes de la finalización. Las probabilidades de que una mujer asistiera a rehabilitación cardíaca disminuyeron por el diagnóstico de infarto de miocardio, la falta de empleo, <55 años o> 70 años, y experimentar un evento personal estresante durante el seguimiento. Es probable que las mujeres se adhieran a las pautas de modificación del tabaquismo, la medicación y el estrés, pero es poco probable que se adhieran a las pautas de modificación de la dieta y el ejercicio.


Análisis de los datos en el artículo.

Se calculó un tamaño de muestra de 180 para el análisis de regresión logística, basado en un mínimo de 10 pacientes por celda para las 10 variables y variables ficticias (dummy variables) adicionales ingresadas. Se realizó un análisis de regresión logística sobre la asistencia utilizando las 10 variables: edad, educación, tipo de hospital, trabajo, arreglos de vivienda, diagnóstico, control percibido, reingreso, complicación, y evento estresante personal durante el seguimiento. Los resultados de estos análisis se presentan como odds ratios con nivel de confianza del 95%. Las diferencias en la modificación de los factores de riesgo a lo largo del tiempo se analizaron utilizando análisis de varianza de medidas repetidas. Dado este analisis presentado, vamos a replicar la regresión logística y odds ratio para este proyecto.


Reproducción parcial de resultados.


Regresión logistica sobre la edad.

# Cargamos los datos
df <- read.csv('dataset1.csv')

# Visualizamos estructura del dataset
head(df, n = 10)

# Libreria para graficar
library(ggplot2)

ggplot(df, aes(x= AGE, y=ATT, color=ATT)) + 
    geom_point(size=3)

Realizamos la regresión logistica:

model <- glm(ATT ~ AGE, family = binomial("logit"), data = df)
summary(model)

Call:
glm(formula = ATT ~ AGE, family = binomial("logit"), data = df)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.4345  -0.8975  -0.7646   1.3674   1.7589  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)   
(Intercept)  1.87467    0.98088   1.911  0.05598 . 
AGE         -0.03788    0.01462  -2.590  0.00959 **
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 236.48  on 183  degrees of freedom
Residual deviance: 229.52  on 182  degrees of freedom
AIC: 233.52

Number of Fisher Scoring iterations: 4

Por lo tanto, tenemos que la ecuación de regresión es:

\[\ln { \frac {p}{1-p} } = -0.03788x + 1.8746\]

Y la ecuación para estimar \(p\) es:

\[p(x) = \frac{e^{-0.03788x + 1.8746}}{1+e^{-0.03788x + 1.8746}}\] Podemos graficar esta función junto con los datos:

# Creamos arreglo para gráfica
x = c(0:100)

# Función de regresión
p_log <- function(x){
  p <- (exp(-0.03788*x + 1.8746))/(1+exp(-0.03788*x + 1.8746))
}

# Probabilidades (odds)
y <- p_log(x)

# Graficamos la regresión
plot(x, y, type = 'l', 
     main = 'Logistic regresión and data', 
     col = 'blue', xlab = 'AGE',
     ylab = 'p', ylim = c(0, 1))

# Graficamos los datos
lines(df$AGE, df$ATT, type = 'p', col = 'red')

# Etiquetas de líneas.
legend("center", c("Logistic regression", "Data"), fill=c("blue", 'red'))

# Agregamos una cuadrícula.
grid()

Podemos hacer una prueba de hipótesis de \(H_0: \beta_1 = 0\), esto es, que la pendiente de la regresión logistica es cero. Para ello, del summary anterior tenemos que el estadístico de prueba es \(z = -2.59\). Consideramos una significancia de \(\alpha = 0.01\), y el valor crítico:

qnorm(0.005)
[1] -2.575829
qnorm(1-0.005)
[1] 2.575829

Por lo tanto, dado que el estadístico de prueba es menor al valor crítico inferior, rechazamos la hipótesis nula \(H_0\) y concluimos que el modelo es una buena manera de explicar los datos.

El odds ratio en este caso:

exp(-0.03788)
[1] 0.9628285

Esto es, hay un \(3.8\%\) mas de probabilidad de que una persona no asista a las sesiones.


Regresión logistica sobre el indice de ansiedad y depresión.

# Cargamos los datos
df <- read.csv('dataset2.csv')

# Visualizamos estructura del dataset
head(df, n = 10)

# Libreria para graficar
library(ggplot2)

ggplot(df, aes(x= INDEX, y=PART, color=PART)) + 
    geom_point(size=3)

Realizamos la regresión logistica:

model <- glm(PART ~ INDEX, family = binomial("logit"), data = df)
summary(model)

Call:
glm(formula = PART ~ INDEX, family = binomial("logit"), data = df)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.2774  -0.9236  -0.7704   1.2777   1.9591  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)    
(Intercept) -1.76027    0.45831  -3.841 0.000123 ***
INDEX        0.06641    0.02516   2.639 0.008308 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 236.48  on 183  degrees of freedom
Residual deviance: 229.14  on 182  degrees of freedom
AIC: 233.14

Number of Fisher Scoring iterations: 4

Por lo tanto, tenemos que la ecuación de regresión es:

\[\ln { \frac {p}{1-p} } = 0.06641x -1.76027\]

Y la ecuación para estimar \(p\) es:

\[p(x) = \frac{e^{0.06641x -1.76027}}{1+e^{0.06641x -1.76027}}\] Podemos graficar esta función junto con los datos:

# Creamos arreglo para gráfica
x = c(-20:60)

# Función de regresión
p_log <- function(x){
  p <- (exp(0.06641*x -1.76027))/(1+exp(0.06641*x -1.76027))
}

# Probabilidades (odds)
y <- p_log(x)

# Graficamos la regresión
plot(x, y, type = 'l', 
     main = 'Logistic regresión and data', 
     col = 'blue', xlab = 'INDEX',
     ylab = 'p', ylim = c(0, 1))

# Graficamos los datos
lines(df$INDEX, df$PART, type = 'p', col = 'red')

# Etiquetas de líneas.
legend("center", c("Logistic regression", "Data"), fill=c("blue", 'red'))

# Agregamos una cuadrícula.
grid()

Podemos hacer una prueba de hipótesis de \(H_0: \beta_2= 0\), esto es, que la pendiente de la regresión logistica es cero. Para ello, del summary anterior tenemos que el estadístico de prueba es \(z = 2.639\). Consideramos una significancia de \(\alpha = 0.01\), y el valor crítico:

qnorm(0.005)
[1] -2.575829
qnorm(1-0.005)
[1] 2.575829

Por lo tanto, dado que el estadístico de prueba es menor al valor crítico inferior, rechazamos la hipótesis nula \(H_0\) y concluimos que el modelo es una buena manera de explicar los datos.

Podemos obtener también explícitamente la probabilidad de participar en el estudio dado el indice de estrés medido:

INDEX <- df$INDEX

P <- p_log(INDEX)

REAL <- df$PART

probabilities <- data.frame(INDEX, P, REAL)
head(probabilities, n = 5)

tail(probabilities, n = 5)

El odds ratio en este caso:

exp(0.06641)
[1] 1.068665

Esto es, hay un \(6\%\) mas de probabilidad de que una persona asista a las sesiones.


Referencias.

  1. Gallagher R, McKinley S, Dracup K. Predictors of women’s attendance at cardiac rehabilitation programs. Prog Cardiovasc Nurs. 2003 Summer;18(3):121-6. doi: 10.1111/j.0889-7204.2003.02129.x. PMID: 12893973.
  2. Wayne W. Daniel y Chad L. Cross, Biostatistics: A Foundation for Analysis in the Health Sciences, 10° edition, Wiley.

Anexos.

Diapositivas de presentación de proyecto.

Se pueden encontrar en este link.

LS0tDQp0aXRsZTogIlByb3llY3RvIDIgLSBFc3RhZMOtc3RpY2EgYXZhbnphZGEuIg0KYXV0aG9yOiAiR2FicmllbCBNaXNzYWVsIEJhcmNvLiBOVUE6IDQyNzA3MSB8IExhdXJhIGRlbCBDYXJtZW4gQ2FiYWwgUGFyYW1vLiBOVUE6IDM5MTU4Ig0KZGF0ZTogIjIxIGRlIE9jdHVicmUgZGUgMjAyMSINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCjxzdHlsZT4NCmJvZHkge3RleHQtYWxpZ246IGp1c3RpZnk7IGZvbnQtc2l6ZTogMTJwdH0NCjwvc3R5bGU+DQoNCjxjZW50ZXI+DQogICAgPGltZyB3aWR0aD0iNjAlIiBzcmM9Imh0dHBzOi8vaS5pbWd1ci5jb20vVWFvOUNJeS5wbmciPg0KPC9jZW50ZXI+DQoNCiMjIEludHJvZHVjY2nDs24uDQoNClBhcmEgbGEgcmVhbGl6YWNpw7NuIGRlIGVzdGUgcHJveWVjdG8sIHNlIHByZXRlbmRlIHJlcHJvZHVjaXIgZGUgbWFuZXJhIHBhcmNpYWwgKGRlIGFjdWVyZG8gYSBsb3MgZGF0b3MgZGlzcG9uaWJsZXMpIGxvcyByZXN1bHRhZG9zIGRlbCBhcnTDrWN1bG86DQoNCj4gKkdhbGxhZ2hlciBSLCBNY0tpbmxleSBTLCBEcmFjdXAgSy4gKlByZWRpY3RvcnMgb2Ygd29tZW4ncyBhdHRlbmRhbmNlIGF0IGNhcmRpYWMgcmVoYWJpbGl0YXRpb24gcHJvZ3JhbXMuIFByb2cgQ2FyZGlvdmFzYyBOdXJzLiAyMDAzIFN1bW1lcjsxOCgzKToxMjEtNi4gZG9pOiAxMC4xMTExL2ouMDg4OS03MjA0LjIwMDMuMDIxMjkueC4gUE1JRDogMTI4OTM5NzMuDQoNCkRlIGVzdGUgYXJ0w61jdWxvLCBzZSByZWFsaXrDsyB1biBlc3R1ZGlvIGRlc2NyaXB0aXZvIHBhcmEgaWRlbnRpZmljYXIgbG9zIGZhY3RvcmVzIHF1ZSBpbmZsdXllbiBlbiBsYSBhc2lzdGVuY2lhIGRlIGxhcyBtdWplcmVzIGEgbG9zIHByb2dyYW1hcyBkZSByZWhhYmlsaXRhY2nDs24gY2FyZMOtYWNhIHkgbGEgYWRoZXJlbmNpYSBkZSBsYXMgbXVqZXJlcyBhIGxhIG1vZGlmaWNhY2nDs24gZGUgbG9zIGZhY3RvcmVzIGRlIHJpZXNnbyBkZXNwdcOpcyBkZSB1biBldmVudG8gY2FyZMOtYWNvLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIE1ldG9kb2xvZ8OtYSBzZWd1aWRhIGVuIGFydMOtY3Vsby4NCkVsIGVzdHVkaW8gdXRpbGl6w7MgdW4gZGlzZcOxbyBkZXNjcmlwdGl2byBjb24gbWVkaWRhcyBhbCBhbHRhIGhvc3BpdGFsYXJpYSB5IGRlIDEyIHNlbWFuYXMgZGVzcHXDqXMgZGVsIGFsdGEuIA0KVW5hIG11ZXN0cmEgZGUgY29udmVuaWVuY2lhIGRlIHBhY2llbnRlcyBtdWplcmVzIChOID0gMTk2KSBmdWUgcmVjbHV0YWRvIGRlIGN1YXRybyBob3NwaXRhbGVzIG1ldHJvcG9saXRhbm9zIGVuIFN5ZG5leSwgQXVzdHJhbGlhLiANCkxvcyBwcm9ncmFtYXMgZGUgcmVoYWJpbGl0YWNpw7NuIGNhcmRpYWNhIGluY2x1eWVyb24gc2VzaW9uZXMgZGUgZWplcmNpY2lvIHN1cGVydmlzYWRhcywgcHJlc2NyaXBjaW9uZXMgcGFyYSBoYWNlciBlamVyY2ljaW8gZW4gZWwgaG9nYXIgeSBjb21wb25lbnRlcyBkZSBlZHVjYWNpw7NuIHNvYnJlIG1vZGlmaWNhY2nDs24gZGUgZmFjdG9yZXMgZGUgcmllc2dvLiBMb3MgcHJvZ3JhbWFzIHZhcmlhcm9uIGVuIGR1cmFjacOzbiBkZSA2IGEgMTIgc2VtYW5hcw0KTGFzIG11amVyZXMgcmVjaGF6YXJvbiBsYSBpbnNjcmlwY2nDs24gZGViaWRvIGEgc8OtbnRvbWFzIChuID0gNiksIGZhbHRhIGRlIGludGVyw6lzIChuID0gNSkgeSBmYWx0YSBkZSB2b2x1bnRhZCBwYXJhIGZpcm1hciB1biBmb3JtdWxhcmlvIGRlIGNvbnNlbnRpbWllbnRvIChuID0gNCkuIExhIG1heW9yw61hIGRlIGxhcyBtdWplcmVzIChuID0gMTgzKSBjb21wbGV0YXJvbiBsYXMgMTIgc2VtYW5hcyBkZSBlc3R1ZGlvLiBMYXMgbXVqZXJlcyBxdWUgbm8gY29tcGxldGFyb24gZnVlcm9uIDEzLCB5YSBxdWUgaGFiw61hbiBtdWVydG8gKG4gPSA1KSwgcmV0aXJhZG9zIChuID0gNCksIG8gc2UgcGVyZGllcm9uIGR1cmFudGUgZWwgc2VndWltaWVudG8gKG4gPSA0KS4NClBhcmEgbGEgcmVjb2xlY2Npw7NuIGRlIGRhdG9zLCBzZSBsZXMgbGxhbcOzIGEgZXN0YXMgbXVqZXJlcyB5IHNlIGxlcyBwcmVndW50YXJvbiBzaSBoYWLDrWFuIGNvbXBsZXRhZG8gbG9zIHByb2dyYW1hcyB5IGVsIHBvciBxdcOpIG5vIHNpIGVzIHF1ZSBubyBsbyBoYWLDrWFuIGhlY2hvLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIFJlc3VsdGFkb3MgZGVsIGFydMOtY3Vsby4NCkxhcyBtdWplcmVzIChOID0gMTk2KSBpbmdyZXNhZGFzIGVuIGVsIGhvc3BpdGFsIHBvciB1biBldmVudG8gY2FyZMOtYWNvIHNlIGxlcyBkaW8gc2VndWltaWVudG8gYSBsYXMgMTIgc2VtYW5hcyBkZXNwdcOpcyBkZWwgYWx0YS4gU29sbyBlbCA2NCUgKG4gPSAxMTIpIGhhYsOtYSBzaWRvIHJlZmVyaWRvIGEgcHJvZ3JhbWFzIGRlIHJlaGFiaWxpdGFjacOzbiBjYXJkw61hY2EuIEEgbGFzIDEyIHNlbWFuYXMgcG9zdGVyaW9yZXMgYWwgYWx0YSwgc29sbyBlbCAzMiUgZGUgbGEgbXVlc3RyYSB0b3RhbCAobiA9IDU3KSBhc2lzdMOtYSBhIHByb2dyYW1hcyB5IGVsIDEyJSBkZSBsYSBtdWVzdHJhIHRvdGFsIChuID0gMjEpIGhhYsOtYSBhYmFuZG9uYWRvIGFudGVzIGRlIGxhIGZpbmFsaXphY2nDs24uIA0KTGFzIHByb2JhYmlsaWRhZGVzIGRlIHF1ZSB1bmEgbXVqZXIgYXNpc3RpZXJhIGEgcmVoYWJpbGl0YWNpw7NuIGNhcmTDrWFjYSBkaXNtaW51eWVyb24gcG9yIGVsIGRpYWduw7NzdGljbyBkZSBpbmZhcnRvIGRlIG1pb2NhcmRpbywgbGEgZmFsdGEgZGUgZW1wbGVvLCA8NTUgYcOxb3Mgbz4gNzAgYcOxb3MsIHkgZXhwZXJpbWVudGFyIHVuIGV2ZW50byBwZXJzb25hbCBlc3RyZXNhbnRlIGR1cmFudGUgZWwgc2VndWltaWVudG8uDQpFcyBwcm9iYWJsZSBxdWUgbGFzIG11amVyZXMgc2UgYWRoaWVyYW4gYSBsYXMgcGF1dGFzIGRlIG1vZGlmaWNhY2nDs24gZGVsIHRhYmFxdWlzbW8sIGxhIG1lZGljYWNpw7NuIHkgZWwgZXN0csOpcywgcGVybyBlcyBwb2NvIHByb2JhYmxlIHF1ZSBzZSBhZGhpZXJhbiBhIGxhcyBwYXV0YXMgZGUgbW9kaWZpY2FjacOzbiBkZSBsYSBkaWV0YSB5IGVsIGVqZXJjaWNpby4NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyBBbsOhbGlzaXMgZGUgbG9zIGRhdG9zIGVuIGVsIGFydMOtY3Vsby4NClNlIGNhbGN1bMOzIHVuIHRhbWHDsW8gZGUgbXVlc3RyYSBkZSAxODAgcGFyYSBlbCBhbsOhbGlzaXMgZGUgcmVncmVzacOzbiBsb2fDrXN0aWNhLCBiYXNhZG8gZW4gdW4gbcOtbmltbyBkZSAxMCBwYWNpZW50ZXMgcG9yIGNlbGRhIHBhcmEgbGFzIDEwIHZhcmlhYmxlcyB5IHZhcmlhYmxlcyBmaWN0aWNpYXMgIChkdW1teSB2YXJpYWJsZXMpIGFkaWNpb25hbGVzIGluZ3Jlc2FkYXMuIFNlIHJlYWxpesOzIHVuIGFuw6FsaXNpcyBkZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2Egc29icmUgbGEgYXNpc3RlbmNpYSB1dGlsaXphbmRvIGxhcyAxMCB2YXJpYWJsZXM6IGVkYWQsIGVkdWNhY2nDs24sIHRpcG8gZGUgaG9zcGl0YWwsIHRyYWJham8sIGFycmVnbG9zIGRlIHZpdmllbmRhLCBkaWFnbsOzc3RpY28sIGNvbnRyb2wgcGVyY2liaWRvLCByZWluZ3Jlc28sIGNvbXBsaWNhY2nDs24sIHkgZXZlbnRvIGVzdHJlc2FudGUgcGVyc29uYWwgZHVyYW50ZSBlbCBzZWd1aW1pZW50by4gTG9zIHJlc3VsdGFkb3MgZGUgZXN0b3MgYW7DoWxpc2lzIHNlIHByZXNlbnRhbiBjb21vIG9kZHMgcmF0aW9zIGNvbiBuaXZlbCBkZSBjb25maWFuemEgZGVsIDk1JS4gTGFzIGRpZmVyZW5jaWFzIGVuIGxhIG1vZGlmaWNhY2nDs24gZGUgbG9zIGZhY3RvcmVzIGRlIHJpZXNnbyBhIGxvIGxhcmdvIGRlbCB0aWVtcG8gc2UgYW5hbGl6YXJvbiB1dGlsaXphbmRvIGFuw6FsaXNpcyBkZSB2YXJpYW56YSBkZSBtZWRpZGFzIHJlcGV0aWRhcy4gRGFkbyBlc3RlIGFuYWxpc2lzIHByZXNlbnRhZG8sIHZhbW9zIGEgcmVwbGljYXIgbGEgcmVncmVzacOzbiBsb2fDrXN0aWNhIHkgb2RkcyByYXRpbyBwYXJhIGVzdGUgcHJveWVjdG8uDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMgUmVwcm9kdWNjacOzbiBwYXJjaWFsIGRlIHJlc3VsdGFkb3MuDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyMjIFJlZ3Jlc2nDs24gbG9naXN0aWNhIHNvYnJlIGxhIGVkYWQuDQoNCmBgYHtyfQ0KIyBDYXJnYW1vcyBsb3MgZGF0b3MNCmRmIDwtIHJlYWQuY3N2KCdkYXRhc2V0MS5jc3YnKQ0KDQojIFZpc3VhbGl6YW1vcyBlc3RydWN0dXJhIGRlbCBkYXRhc2V0DQpoZWFkKGRmLCBuID0gMTApDQoNCiMgTGlicmVyaWEgcGFyYSBncmFmaWNhcg0KbGlicmFyeShnZ3Bsb3QyKQ0KDQpnZ3Bsb3QoZGYsIGFlcyh4PSBBR0UsIHk9QVRULCBjb2xvcj1BVFQpKSArIA0KICAgIGdlb21fcG9pbnQoc2l6ZT0zKQ0KYGBgDQoNClJlYWxpemFtb3MgbGEgcmVncmVzacOzbiBsb2dpc3RpY2E6DQoNCmBgYHtyfQ0KbW9kZWwgPC0gZ2xtKEFUVCB+IEFHRSwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkZikNCnN1bW1hcnkobW9kZWwpDQpgYGANCg0KUG9yIGxvIHRhbnRvLCB0ZW5lbW9zIHF1ZSBsYSBlY3VhY2nDs24gZGUgcmVncmVzacOzbiBlczogDQoNCiQkXGxuIHsgXGZyYWMge3B9ezEtcH0gfSA9IC0wLjAzNzg4eCArIDEuODc0NiQkDQoNClkgbGEgZWN1YWNpw7NuIHBhcmEgZXN0aW1hciAkcCQgZXM6IA0KDQokJHAoeCkgPSBcZnJhY3tlXnstMC4wMzc4OHggKyAxLjg3NDZ9fXsxK2Veey0wLjAzNzg4eCArIDEuODc0Nn19JCQNClBvZGVtb3MgZ3JhZmljYXIgZXN0YSBmdW5jacOzbiBqdW50byBjb24gbG9zIGRhdG9zOiANCg0KDQpgYGB7cn0NCiMgQ3JlYW1vcyBhcnJlZ2xvIHBhcmEgZ3LDoWZpY2ENCnggPSBjKDA6MTAwKQ0KDQojIEZ1bmNpw7NuIGRlIHJlZ3Jlc2nDs24NCnBfbG9nIDwtIGZ1bmN0aW9uKHgpew0KICBwIDwtIChleHAoLTAuMDM3ODgqeCArIDEuODc0NikpLygxK2V4cCgtMC4wMzc4OCp4ICsgMS44NzQ2KSkNCn0NCg0KIyBQcm9iYWJpbGlkYWRlcyAob2RkcykNCnkgPC0gcF9sb2coeCkNCg0KIyBHcmFmaWNhbW9zIGxhIHJlZ3Jlc2nDs24NCnBsb3QoeCwgeSwgdHlwZSA9ICdsJywgDQogICAgIG1haW4gPSAnTG9naXN0aWMgcmVncmVzacOzbiBhbmQgZGF0YScsIA0KICAgICBjb2wgPSAnYmx1ZScsIHhsYWIgPSAnQUdFJywNCiAgICAgeWxhYiA9ICdwJywgeWxpbSA9IGMoMCwgMSkpDQoNCiMgR3JhZmljYW1vcyBsb3MgZGF0b3MNCmxpbmVzKGRmJEFHRSwgZGYkQVRULCB0eXBlID0gJ3AnLCBjb2wgPSAncmVkJykNCg0KIyBFdGlxdWV0YXMgZGUgbMOtbmVhcy4NCmxlZ2VuZCgiY2VudGVyIiwgYygiTG9naXN0aWMgcmVncmVzc2lvbiIsICJEYXRhIiksIGZpbGw9YygiYmx1ZSIsICdyZWQnKSkNCg0KIyBBZ3JlZ2Ftb3MgdW5hIGN1YWRyw61jdWxhLg0KZ3JpZCgpDQpgYGANCg0KDQpQb2RlbW9zIGhhY2VyIHVuYSBwcnVlYmEgZGUgaGlww7N0ZXNpcyBkZSAkSF8wOiBcYmV0YV8xID0gMCQsIGVzdG8gZXMsIHF1ZSBsYSBwZW5kaWVudGUgZGUgbGEgcmVncmVzacOzbiBsb2dpc3RpY2EgZXMgY2Vyby4gUGFyYSBlbGxvLCBkZWwgc3VtbWFyeSBhbnRlcmlvciB0ZW5lbW9zIHF1ZSBlbCBlc3RhZMOtc3RpY28gZGUgcHJ1ZWJhIGVzICR6ID0gLTIuNTkkLiBDb25zaWRlcmFtb3MgdW5hIHNpZ25pZmljYW5jaWEgZGUgJFxhbHBoYSA9IDAuMDEkLCB5IGVsIHZhbG9yIGNyw610aWNvOg0KDQpgYGB7cn0NCnFub3JtKDAuMDA1KQ0KcW5vcm0oMS0wLjAwNSkNCmBgYA0KUG9yIGxvIHRhbnRvLCBkYWRvIHF1ZSBlbCBlc3RhZMOtc3RpY28gZGUgcHJ1ZWJhIGVzIG1lbm9yIGFsIHZhbG9yIGNyw610aWNvIGluZmVyaW9yLCByZWNoYXphbW9zIGxhIGhpcMOzdGVzaXMgbnVsYSAkSF8wJCB5IGNvbmNsdWltb3MgcXVlIGVsIG1vZGVsbyBlcyB1bmEgYnVlbmEgbWFuZXJhIGRlIGV4cGxpY2FyIGxvcyBkYXRvcy4NCg0KRWwgb2RkcyByYXRpbyBlbiBlc3RlIGNhc286IA0KDQpgYGB7cn0NCmV4cCgtMC4wMzc4OCkNCmBgYA0KRXN0byBlcywgaGF5IHVuICQzLjhcJSQgbWFzIGRlIHByb2JhYmlsaWRhZCBkZSBxdWUgdW5hIHBlcnNvbmEgbm8gYXNpc3RhIGEgbGFzIHNlc2lvbmVzLg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyMgUmVncmVzacOzbiBsb2dpc3RpY2Egc29icmUgZWwgaW5kaWNlIGRlIGFuc2llZGFkIHkgZGVwcmVzacOzbi4NCg0KYGBge3J9DQojIENhcmdhbW9zIGxvcyBkYXRvcw0KZGYgPC0gcmVhZC5jc3YoJ2RhdGFzZXQyLmNzdicpDQoNCiMgVmlzdWFsaXphbW9zIGVzdHJ1Y3R1cmEgZGVsIGRhdGFzZXQNCmhlYWQoZGYsIG4gPSAxMCkNCg0KIyBMaWJyZXJpYSBwYXJhIGdyYWZpY2FyDQpsaWJyYXJ5KGdncGxvdDIpDQoNCmdncGxvdChkZiwgYWVzKHg9IElOREVYLCB5PVBBUlQsIGNvbG9yPVBBUlQpKSArIA0KICAgIGdlb21fcG9pbnQoc2l6ZT0zKQ0KYGBgDQoNClJlYWxpemFtb3MgbGEgcmVncmVzacOzbiBsb2dpc3RpY2E6DQoNCmBgYHtyfQ0KbW9kZWwgPC0gZ2xtKFBBUlQgfiBJTkRFWCwgZmFtaWx5ID0gYmlub21pYWwoImxvZ2l0IiksIGRhdGEgPSBkZikNCnN1bW1hcnkobW9kZWwpDQpgYGANCg0KUG9yIGxvIHRhbnRvLCB0ZW5lbW9zIHF1ZSBsYSBlY3VhY2nDs24gZGUgcmVncmVzacOzbiBlczogDQoNCiQkXGxuIHsgXGZyYWMge3B9ezEtcH0gfSA9IDAuMDY2NDF4IC0xLjc2MDI3JCQNCg0KWSBsYSBlY3VhY2nDs24gcGFyYSBlc3RpbWFyICRwJCBlczogDQoNCiQkcCh4KSA9IFxmcmFje2VeezAuMDY2NDF4IC0xLjc2MDI3fX17MStlXnswLjA2NjQxeCAtMS43NjAyN319JCQNClBvZGVtb3MgZ3JhZmljYXIgZXN0YSBmdW5jacOzbiBqdW50byBjb24gbG9zIGRhdG9zOiANCg0KDQpgYGB7cn0NCiMgQ3JlYW1vcyBhcnJlZ2xvIHBhcmEgZ3LDoWZpY2ENCnggPSBjKC0yMDo2MCkNCg0KIyBGdW5jacOzbiBkZSByZWdyZXNpw7NuDQpwX2xvZyA8LSBmdW5jdGlvbih4KXsNCiAgcCA8LSAoZXhwKDAuMDY2NDEqeCAtMS43NjAyNykpLygxK2V4cCgwLjA2NjQxKnggLTEuNzYwMjcpKQ0KfQ0KDQojIFByb2JhYmlsaWRhZGVzIChvZGRzKQ0KeSA8LSBwX2xvZyh4KQ0KDQojIEdyYWZpY2Ftb3MgbGEgcmVncmVzacOzbg0KcGxvdCh4LCB5LCB0eXBlID0gJ2wnLCANCiAgICAgbWFpbiA9ICdMb2dpc3RpYyByZWdyZXNpw7NuIGFuZCBkYXRhJywgDQogICAgIGNvbCA9ICdibHVlJywgeGxhYiA9ICdJTkRFWCcsDQogICAgIHlsYWIgPSAncCcsIHlsaW0gPSBjKDAsIDEpKQ0KDQojIEdyYWZpY2Ftb3MgbG9zIGRhdG9zDQpsaW5lcyhkZiRJTkRFWCwgZGYkUEFSVCwgdHlwZSA9ICdwJywgY29sID0gJ3JlZCcpDQoNCiMgRXRpcXVldGFzIGRlIGzDrW5lYXMuDQpsZWdlbmQoImNlbnRlciIsIGMoIkxvZ2lzdGljIHJlZ3Jlc3Npb24iLCAiRGF0YSIpLCBmaWxsPWMoImJsdWUiLCAncmVkJykpDQoNCiMgQWdyZWdhbW9zIHVuYSBjdWFkcsOtY3VsYS4NCmdyaWQoKQ0KYGBgDQoNCg0KUG9kZW1vcyBoYWNlciB1bmEgcHJ1ZWJhIGRlIGhpcMOzdGVzaXMgZGUgJEhfMDogXGJldGFfMj0gMCQsIGVzdG8gZXMsIHF1ZSBsYSBwZW5kaWVudGUgZGUgbGEgcmVncmVzacOzbiBsb2dpc3RpY2EgZXMgY2Vyby4gUGFyYSBlbGxvLCBkZWwgc3VtbWFyeSBhbnRlcmlvciB0ZW5lbW9zIHF1ZSBlbCBlc3RhZMOtc3RpY28gZGUgcHJ1ZWJhIGVzICR6ID0gMi42MzkkLiBDb25zaWRlcmFtb3MgdW5hIHNpZ25pZmljYW5jaWEgZGUgJFxhbHBoYSA9IDAuMDEkLCB5IGVsIHZhbG9yIGNyw610aWNvOg0KDQpgYGB7cn0NCnFub3JtKDAuMDA1KQ0KcW5vcm0oMS0wLjAwNSkNCmBgYA0KDQpQb3IgbG8gdGFudG8sIGRhZG8gcXVlIGVsIGVzdGFkw61zdGljbyBkZSBwcnVlYmEgZXMgbWVub3IgYWwgdmFsb3IgY3LDrXRpY28gaW5mZXJpb3IsIHJlY2hhemFtb3MgbGEgaGlww7N0ZXNpcyBudWxhICRIXzAkIHkgY29uY2x1aW1vcyBxdWUgZWwgbW9kZWxvIGVzIHVuYSBidWVuYSBtYW5lcmEgZGUgZXhwbGljYXIgbG9zIGRhdG9zLg0KDQpQb2RlbW9zIG9idGVuZXIgdGFtYmnDqW4gZXhwbMOtY2l0YW1lbnRlIGxhIHByb2JhYmlsaWRhZCBkZSBwYXJ0aWNpcGFyIGVuIGVsIGVzdHVkaW8gZGFkbyBlbCBpbmRpY2UgZGUgZXN0csOpcyBtZWRpZG86DQoNCmBgYHtyfQ0KSU5ERVggPC0gZGYkSU5ERVgNCg0KUCA8LSBwX2xvZyhJTkRFWCkNCg0KUkVBTCA8LSBkZiRQQVJUDQoNCnByb2JhYmlsaXRpZXMgPC0gZGF0YS5mcmFtZShJTkRFWCwgUCwgUkVBTCkNCmhlYWQocHJvYmFiaWxpdGllcywgbiA9IDUpDQoNCnRhaWwocHJvYmFiaWxpdGllcywgbiA9IDUpDQpgYGANCg0KRWwgb2RkcyByYXRpbyBlbiBlc3RlIGNhc286IA0KDQpgYGB7cn0NCmV4cCgwLjA2NjQxKQ0KYGBgDQpFc3RvIGVzLCBoYXkgdW4gJDZcJSQgbWFzIGRlIHByb2JhYmlsaWRhZCBkZSBxdWUgdW5hIHBlcnNvbmEgYXNpc3RhIGEgbGFzIHNlc2lvbmVzLiANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQojIyBSZWZlcmVuY2lhcy4NCg0KMS4gKipHYWxsYWdoZXIgUiwgTWNLaW5sZXkgUywgRHJhY3VwIEsqKi4gKlByZWRpY3RvcnMgb2Ygd29tZW4ncyBhdHRlbmRhbmNlIGF0IGNhcmRpYWMgcmVoYWJpbGl0YXRpb24gcHJvZ3JhbXMqLiBQcm9nIENhcmRpb3Zhc2MgTnVycy4gMjAwMyBTdW1tZXI7MTgoMyk6MTIxLTYuIGRvaTogMTAuMTExMS9qLjA4ODktNzIwNC4yMDAzLjAyMTI5LnguIFBNSUQ6IDEyODkzOTczLg0KMi4gKipXYXluZSBXLiBEYW5pZWwgeSBDaGFkIEwuIENyb3NzKiosICpCaW9zdGF0aXN0aWNzOiBBIEZvdW5kYXRpb24gZm9yIEFuYWx5c2lzIGluIHRoZSBIZWFsdGggU2NpZW5jZXMqLCAxMMKwIGVkaXRpb24sIFdpbGV5Lg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiMjIEFuZXhvcy4NCg0KIyMjIERpYXBvc2l0aXZhcyBkZSBwcmVzZW50YWNpw7NuIGRlIHByb3llY3RvLiANCg0KU2UgcHVlZGVuIGVuY29udHJhciBlbiBlc3RlIFtsaW5rXShodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9wcmVzZW50YXRpb24vZC9lLzJQQUNYLTF2UVNKdGxMWHUxYzRRUlZXSk12UDltZzRudnh1VzcyZTlLX2t2RmxPYWdqR2QtNmxnd0VZM3FxYkdhS0pVbDI1dEJoNWZzRlFKaHNYaER5L3B1Yj9zdGFydD10cnVlJmxvb3A9dHJ1ZSZkZWxheW1zPTYwMDAwKS4NCg0K