Introducción
El tema de la semana es la correlación y a la regresión lineal
simple. Este es un método para analizar la relación entre dos variables
cuantitativas: una dependiente y una independiente.
Recordemos que el método del chi-cuadrado se trataba de analizar la
relación entre dos variables cualitativas. La prueba t y ANOVA tienen
una variable dependiente cuantitativa y una variable independiente
cualitativa. La correlación es una extensión de esta serie de
relaciones. El método de regresión lineal es un método generalizado,
que, luego veremos, incluye a la prueba t y a ANOVA.
La correlación se trata de la evaluación del cambio sistemático en
las puntuaciones de dos variables numéricas (discretas o continuas, de
intervalo o de razón).
Con el método de la regresión lineal se puede responder las
siguientes preguntas:
Analizar si hay una asociación entre las
variables mediante un test de independencia estadística.
Analizar la dirección de la asociación (directa
o inversa).
Evaluar la fuerza de la asociación usando una
medida de asociación llamada correlación de
Pearson.
Estimar una ecuación de regresión que “predice”
los valores de la variable dependiente para valores de la variable
independiente.
Espacio cartesiano
Se trata de un espacio formado por dos ejes perpendiculares, el eje X
(horizontal) y el eje Y (vertical). Cada uno de estos ejes se puede
tratar como una regla donde se pueden mapear variables.
Por ejemplo:
En el eje X se puede mapear la variable edad (variable numérica
discreta). La regla podría partir desde cero si se recoge información
que incluye a niños o podría partir desde 18 si se recoge información de
mayores de edad.
En el eje Y se puede mapear la variable estatura (variable
numérica continua).
Si se combinan ambos ejes se forma el espacio, donde cada
individuo estará mapeado, con sus datos de peso y de estatura como
coordenadas de ubicación en este espacio.
El conjunto de individuos (o puntos) formará una “nube” de puntos
en este espacio. Este tipo de gráfico se llama Gráfico o Diagrama de
Dispersión.
Ahora presentaremos un ejemplo más político. Esta base incluye
información a nivel departamental, sociodemográfica y electoral de 2016,
todas variables numéricas.
library(rio)
data = import("bases/voto2021_v2.xlsx")
Para empezar usaremos dos variables para general el gráfico de
dispersión:
library(ggplot2)
ggplot(data, aes(x=Analfabetismo, y=VotoPL_1))+
geom_point()+
geom_text(data=data, aes(label=Departamento),
cex=2, nudge_y = 1.1, check_overlap = T)+ #Pata etiquetar los puntos, darles un tamaño, ubicación y prevenir que se sobrepongan
labs(x="Porcentaje de analfabetismo",
y="Voto a Perú Libre (1era vuelta)")+ #para etiquetar los ejes
theme_light()
Esta “nube” de puntos nos dan una idea visual de la probable relación
entre las variables. En estos casos vemos que las variables forman un
patrón ascendente positivo: a medida que los departamentos reportan un
mayor tasa de analfabetismo, también se observa un mayor porcentaje de
voto a PL en 2021.
Por ejemplo, en el libro “El Profe” (IEP, 2021) se examina la
relación entre el porcentaje de población autoidentificada como indígena
y el voto a Pedro Castillo. El gráfico que se obtiene a nivel provincial
es.
Cuando se trabaja con bases de datos con muchas más observaciones, a
veces no es fácil distinguir una tendencia en la “nube” de puntos. Dado
que nuestra percepción tiene esos límites, confiamos en el modelamiento
mediante una relación lineal para el establecimiento de relaciones.
Relación lineal
Esta probable relación entre estas dos variables se
resumen/simplifica mediante una aproximación lineal. Es decir, mediante
una recta de aproximación.
Ecuación de la recta
Se tiene que recordar que una recta tiene la forma \(Y = a + bX\), donde “a” es la constante y
“b” es la pendiente. Cualquier recta puede ser graficada con diferentes
valores de a y b.
La relación entre las variables depende de la pendiente:
Si b es positivo, Y aumenta cuando X aumenta. Es una relación
directa / positiva.
Si b es negativo, Y aumenta cuando X disminuye. Es una relación
inversa / negativa.
Si b es cero. Y no cambia cuando X varía. No existe relación
entre las variables.
Como dijimos, la “nube” de puntos se modela mediante una recta. Esta
recta de aproximación tiene la forma \(\hat{Y}
= \hat{\alpha} + \hat{\beta}*X\)
Los valores que tiene el “sombrero” son datos que se calculan con los
datos observados. Una vez estimados estos valores (se verá la lógica en
un momento), se puede estimar un Y (por eso tiene también “sombrero”)
para cualquier valor de X.
En nuestro ejemplo, se le puede pedir a ggplot
que
incluya la recta de aproximación en el gráfico de dispersión mediante el
comando geom_smooth(method=lm, se=F)
, que se usa para
calcular un modelo lineal (que veremos en un momento)
ggplot(data, aes(x=Analfabetismo, y=VotoPL_1))+
geom_point()+
geom_smooth(method=lm, se=F)+ #agregar línea de tendencia
geom_text(data=data, aes(label=Departamento),
cex=2, nudge_y = 1.1, check_overlap = T)+ #Pata etiquetar los puntos, darles un tamaño, ubicación y prevenir que se sobrepongan
labs(x="Porcentaje de analfabetismo",
y="Voto a Perú Libre (1era vuelta)")+ #para etiquetar los ejes
theme_light()
## `geom_smooth()` using formula =
## 'y ~ x'
¿Cómo se calcula que ESA es la recta de aproximación, y no otra? La
recta calculada se define como aquella que minimiza los residuos.
Residuos o errores
Se trata de la diferencia entre el valor observado y el valor
calculado por la recta: \(Y -
\hat{Y}\)
Es decir, cada observación tiene un residuo, que sería visualmente,
la distancia vertical del punto a la recta de aproximación.
#Este código de abajo no se evaluará
plot(data$Analfabetismo, data$VotoPL_1,
xlab="Porcentaje de analfabetismo por departamento",
ylab="Voto a PL (1era vuelta)",
pch=19, xlim=c(0,15), ylim=c(0, 55))
abline(lm(data$VotoPL_1 ~ data$Analfabetismo))
fitted = predict(lm(data$VotoPL_1 ~ data$Analfabetismo))
for (i in 1:25) {
lines( c(data$Analfabetismo[i], data$Analfabetismo[i]), c(data$VotoPL_1[i], fitted[i]), col="blue")
}
Cada punto se aproxima o se aleja más de la recta de aproximación.
Estas distancias se pueden sumar para darnos una idea de qué tan bien
esta recta “resume” la distribución de los datos.
Se define la recta de aproximación como la recta que minimiza esta
suma de residuos. Es decir, cualquier otra recta tendría una mayor suma
de esas líneas azules. Esta recta tiene una ecuación de la recta, con
una constante y una pendiente específica. De manera formal la suma se
hace de los residuos al cuadrado para evitar los valores negativos.
Para esto se tiene que calcular el modelo lineal con el comando
lm
, y esto modelo se guarda en un objeto “modelo1”.
modelo1 = lm(data$VotoPL_1 ~ data$Analfabetismo)
summary(modelo1)
##
## Call:
## lm(formula = data$VotoPL_1 ~ data$Analfabetismo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -21.023 -9.442 -4.795 9.798 19.872
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 6.5710 5.1709 1.271 0.216516
## data$Analfabetismo 3.0273 0.6716 4.507 0.000159 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 11.85 on 23 degrees of freedom
## Multiple R-squared: 0.469, Adjusted R-squared: 0.4459
## F-statistic: 20.32 on 1 and 23 DF, p-value: 0.0001589
Recta de aproximación
Los primeros datos a analizar están en la columna “Estimate”. Estos
datos definen la ecuación de la recta. Según estos datos se tendría
\[\hat{Y} = 6.57 + 3.03*X\]
Modelo lineal
Como indicamos, la relación entre dos variables cuantitativas se
modela mediante una recta de aproximación. Para evaluar una relación
entre dos variables numéricas, tenemos que responder las siguientes
preguntas:
Predicción
Con esta ecuación se puede estimar el valor de Y (es
decir, el voto a PL) para cualquier valor de X (de analfabetismo).
Por ejemplo, en Amazonas se tiene 8.03% de tasa de analfabetismo,
según la base de datos. De acuerdo a la ecuación, el voto estimado a PL
sería 6.57 + 3.03*8.03 = 30.9%.
El voto observado a PL en Amazonas fue 26.1%. Por lo tanto, el
residuo de esta observación es 26.1-30.9 = -4.8. Este es el error de
predicción.
El voto predicho a PL no solo se puede calcular para los valores
observados de acceso a internet, sino también para cualquier valor de
X.
¿Cuánto sería el voto predicho a PL en un departamento con cero
analfabetismo? ¿cuánto sería el voto predicho a PL en un departamento
con total analfabetismo?
Estas dos preguntas implican el cálculo de \(\hat{Y}\) para cuando X=0 (en la primera
pregunta) y para cuando X=100 (en la segunda pregunta). En la realidad
no tenemos dos departamentos con estos valores de X, pero estos se
pueden predecir a partir del modelo generado.
Correlación no es causalidad
Que se pueda graficar los datos de dos variables en un espacio
cartesiano y que se pueda calcular la mejor recta de aproximación NO
significa que ambas variables necesariamente están relacionadas o que
haya una relación de causalidad.
Para establecer una relación de causalidad hace falta:
Que haya consistencia entre varios estudios: un estudio (casi)
nunca es suficiente para definir un hallazgo. La convergencia entre
diferentes estudios (en diferentes lugares y tiempos) le da mayor
robustez a la relación entre dos variables.
Que haya una (fuerza de) asociación: que existe una correlación
es un primer paso para poder luego evaluar una probable causalidad. La
relación es una estadística y no una relación determinista.
Un mecanismo: una explicación basada en la teoría que defienda
porqué es plausible hablar de una probable relación entre esas dos
variables.
Temporalidad: que la causa preceda al efecto. Es decir que la
medición del X sea anterior a la del Y. En nuestro ejemplo, no se podría
hablar de causalidad si el X hubiera sido medido antes de 2021.
Un ejemplo que cumple estas condiciones es la relación entre consumo
de tabaco y desarrollo de cáncer de pulmón.
Para establecer una relación de causalidad entre ambas variables se
han realizado múltiples estudios, se tiene una relación estadística
robusta, se tiene un mecanismo en la nicotina y se tiene una secuencia
temporal, se fuma y luego se desarrolla el cáncer de pulmón.
Por ejemplo, puede existir una correlación entre el consumo de
chocolate en un país y el número de premios Nobel que cuente ese país.La
pregunta es cuál es el mecanismo explicativo entre una variable y la
otra. Pueden ver más correlaciones
locas es este link.
En algunos casos, la relación entre dos variables en realidad es
explicada por una tercera variable. En este tipo de casos se habla de
correlaciones espúreas. Por ejemplo:
De manera más gráfica:
¿Existe una asociación o relación entre las variables?
Según estos resultados la ecuación de la recta es:
\[\hat{Y} = 6.57 + 3.03*X\]
En esta ecuación, el dato que marca la relación entre ambas variables
es la pendiente. El \(\hat{\beta} =
+3.03\). Este dato es una aproximación desde los datos del
“verdadero” valor de \(\beta\). Como
toda aproximación a partir de datos, este valor de \(\hat{\beta}\) tiene un error estándar y por
lo tanto un intervalo de confianza de posibles valores del parámetro
poblacional. Con el estimado y el error estándar se puede usar la
distribución t para inferir a la población.
La H0: \(\beta = 0\)
La HA: \(\beta \not= 0\)
Es decir, se pone a prueba cuál es la probabilidad de observar una
pendiente de 3.03 si la “verdadera” pendiente es cero. Esta probabilidad
se mide, como siempre, con el p-value (o Pr(>|t|), en la tabla de
resultados).
En la fila correspondiente a la variable independiente se observa que
el p-value = 0.000159 (o 0.0159%). Es decir, que tenemos muy bajas
probabilidades de observar una pendiente de 3.03 si la verdadera
pendiente es cero. Como este valor es menor a 0.05, se puede rechazar la
H0.
Con esto se concluye que se puede decir que SÍ hay una (cor)relación
entre ambas variables.
Dirección
La dirección de la relación entre las variables está marcada por el
signo de la pendiente. Si el signo es positivo, la recta de aproximación
tiene pendiente positiva y eso indica una relación positiva entre las
variables (a mayor X, mayor Y). Si el signo es negativo, la recta de
aproximación tiene una pendiente negativa y eso indica una relación
negativa entre las variables (a mayor X, menor Y).
En nuestro ejemplo, la pendiente (es decir, el valor de \(\hat{\beta}\)) es positiva. Eso quiere
decir que departamentos que presentan mayores tasas de analfabetismo,
reportan, en promedio, un mayor voto hacia Pedro
Castillo.
Coeficiente de correlación de Pearson
El valor de \(\hat{\beta}\) indica
la tasa de cambio, es decir, por cada unidad de cambio en X, Y cambia
\(\hat{\beta}\) unidades. En nuestro
ejemplo, por cada 1% de aumento en la tasa de analfabetismo, el voto a
Pedro Castillo cambia 3%.
Pero la pendiente no es un buen indicador de la relación entre las
variables, pues depende de las unidades de medida de las variables. Para
poder evaluar la relación entre las variables, requerimos una versión
estandarizada de la pendiente, que mida el cambio en unidades de
desviación estándar.
Esta medida es el coeficiente de correlación de Pearson. Este
coeficiente no solo mide el cambio entre las variables en unidades de
desviación estándar, sino también el grado de ajuste de los puntos a la
recta. Este coeficiente tiene las siguientes características:
El coeficiente r de Pearson varía entre -1 y +1. El coeficiente r
tiene el mismo signo que la pendiente.
r=0 si la pendiente también es cero.
r=+1 o r=-1 si todos los puntos caen en la línea de predicción.
Es decir, que la predicción es “perfecta”. Esta situación es hipótetica,
nunca se da con datos en ciencias sociales.
En nuestro ejemplo r=0.685. Es decir, por cada unidad de desviación
estándar de cambio en X, Y cambia 0.685 desviaciones estándar.
cor.test(x=data$Analfabetismo, y=data$VotoPL_1, method="pearson")
##
## Pearson's product-moment correlation
##
## data: data$Analfabetismo and data$VotoPL_1
## t = 4.5073, df = 23, p-value = 0.0001589
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.3972054 0.8499737
## sample estimates:
## cor
## 0.6848503
Para tener una idea acerca de cómo interpretar este valor, la
siguiente imagen muestra ejemplos de distribuciones de puntos a
diferentes valores de r.
Como se observa, a medida que el valor de r se acerca a 1, los puntos
se encuentran más alineados a la recta de predicción, por lo que habría
menos residuos, llegando a cero, con puntos completamente ajustados a la
recta.
A medida que el valor de r se acerca a cero, los puntos se vuelven
más dispersos, formando una nube de puntos. Esos puntos se ajustan menos
a una recta de predicción.
Para tener una idea más lúdica de la distribución de puntos a
diferentes valores del coeficiente de Pearson, pueden entrar a este link
de Guess the Correlation,
que “gamifica” acertar con el valor de r para diferentes dispersiones de
puntos.
Coeficiente de determinación \(R^2\)
En el contexto del análisis de regresión lineal, también se analiza
qué tan bien X predice Y. Esta capacidad de X de predecir la variable Y
se mide mediante el coeficiente de determinación \(R^2\). Este valor no es otro que el
cuadrado del coeficiente de Pearson.
Pero, se interpreta como la reducción proporcional en el error al
usar la recta de predicción, en lugar de sólo usar \(\bar{Y}\) (el promedio de Y) para predecir
Y.
Se tiene que recordar que los errores (o residuos) son las distancias
de cada punto a la recta. Cada punto tiene una distancia a la recta de
\(\bar{Y}\) y también una distancia a
la recta de predicción.
En la imagen de la izquierda, se muestran las distancias de los
puntos a la recta de \(\bar{Y}\). Todas
estas distancias al cuadrado se pueden sumar. Esta suma es E1.
En la imagen de la derecha, se muestran las distancias de los puntos
a la recta de predicción \(\hat{Y}\).
Todas estas distancias al cuadrado se pueden sumar. Esa suma es E2.
Entonces, \(R^2 =
\frac{E1-E2}{E1}\). Este cálculo es igual al cuadrado del valor
de la correlación. Por lo tanto:
\(R^2\) varía entre 0 y
1.
\(R^2=1\) implica que E2 = 0, es
decir que todos los puntos caen en la recta.
\(R^2=0\) si la pendiente es
cero.
En nuestro ejemplo, \(R^2=0.47\).
Este valor se encuentra en la penúltima fila del summary
del modelo, con el nombre “Multiple R-squared”. Es decir, el modelo
reduce un 47% el error de usar solamente el promedio para estimar Y.
Validez del modelo
La última fila del summary
muestra los resultados de una
prueba F, con un estadístico de la prueba y un p-value. Esta prueba es
la que nos indica la validez del modelo en su conjunto.
Cuando analizamos relaciones bivariadas, este p-value es igual al
p-value de la pendiente, por lo que la validez se determina con
cualquiera de ellas.
Vamos a ver en la siguiente sección de análisis multivariado que el
análisis de la prueba F es el primer paso, que indica la validez del
modelo multivariado, y que se tiene que realizar antes de analizar los
siguientes pasos, de relaciones, direcciones y fuerza.
LS0tCnRpdGxlOiAiQ2xhc2UgMTEgeSAxMiIKYXV0aG9yOiAiQXJ0dXJvIE1hbGRvbmFkbyIKZGF0ZTogIjI5LzEwLzIwMjQiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGNvc21vCiAgICBoaWdobGlnaHQ6IHRleHRtYXRlCmVkaXRvcl9vcHRpb25zOgogIG1hcmtkb3duOgogICAgd3JhcDogc2VudGVuY2UKYmlibGlvZ3JhcGh5OiByZWZlcmVuY2VzLmJpYgotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCmBgYAoKIyBJbnRyb2R1Y2Npw7NuCgpFbCB0ZW1hIGRlIGxhIHNlbWFuYSBlcyBsYSBjb3JyZWxhY2nDs24geSBhIGxhIHJlZ3Jlc2nDs24gbGluZWFsIHNpbXBsZS4KRXN0ZSBlcyB1biBtw6l0b2RvIHBhcmEgYW5hbGl6YXIgbGEgcmVsYWNpw7NuIGVudHJlIGRvcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhczogdW5hIGRlcGVuZGllbnRlIHkgdW5hIGluZGVwZW5kaWVudGUuCgpSZWNvcmRlbW9zIHF1ZSBlbCBtw6l0b2RvIGRlbCBjaGktY3VhZHJhZG8gc2UgdHJhdGFiYSBkZSBhbmFsaXphciBsYSByZWxhY2nDs24gZW50cmUgZG9zIHZhcmlhYmxlcyBjdWFsaXRhdGl2YXMuCkxhIHBydWViYSB0IHkgQU5PVkEgdGllbmVuIHVuYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBjdWFudGl0YXRpdmEgeSB1bmEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSBjdWFsaXRhdGl2YS4KTGEgY29ycmVsYWNpw7NuIGVzIHVuYSBleHRlbnNpw7NuIGRlIGVzdGEgc2VyaWUgZGUgcmVsYWNpb25lcy4KRWwgbcOpdG9kbyBkZSByZWdyZXNpw7NuIGxpbmVhbCBlcyB1biBtw6l0b2RvIGdlbmVyYWxpemFkbywgcXVlLCBsdWVnbyB2ZXJlbW9zLCBpbmNsdXllIGEgbGEgcHJ1ZWJhIHQgeSBhIEFOT1ZBLgoKTGEgY29ycmVsYWNpw7NuIHNlIHRyYXRhIGRlIGxhIGV2YWx1YWNpw7NuIGRlbCBjYW1iaW8gc2lzdGVtw6F0aWNvIGVuIGxhcyBwdW50dWFjaW9uZXMgZGUgZG9zIHZhcmlhYmxlcyBudW3DqXJpY2FzIChkaXNjcmV0YXMgbyBjb250aW51YXMsIGRlIGludGVydmFsbyBvIGRlIHJhesOzbikuCgpDb24gZWwgbcOpdG9kbyBkZSBsYSByZWdyZXNpw7NuIGxpbmVhbCBzZSBwdWVkZSByZXNwb25kZXIgbGFzIHNpZ3VpZW50ZXMgcHJlZ3VudGFzOgoKLSAgIEFuYWxpemFyIHNpIGhheSB1bmEgKiphc29jaWFjacOzbioqIGVudHJlIGxhcyB2YXJpYWJsZXMgbWVkaWFudGUgdW4gdGVzdCBkZSBpbmRlcGVuZGVuY2lhIGVzdGFkw61zdGljYS4KCi0gICBBbmFsaXphciBsYSAqKmRpcmVjY2nDs24qKiBkZSBsYSBhc29jaWFjacOzbiAoZGlyZWN0YSBvIGludmVyc2EpLgoKLSAgIEV2YWx1YXIgbGEgKipmdWVyemEqKiBkZSBsYSBhc29jaWFjacOzbiB1c2FuZG8gdW5hIG1lZGlkYSBkZSBhc29jaWFjacOzbiBsbGFtYWRhICoqY29ycmVsYWNpw7NuIGRlIFBlYXJzb24uKioKCi0gICBFc3RpbWFyIHVuYSBlY3VhY2nDs24gZGUgcmVncmVzacOzbiBxdWUgIioqcHJlZGljZSoqIiBsb3MgdmFsb3JlcyBkZSBsYSB2YXJpYWJsZSBkZXBlbmRpZW50ZSBwYXJhIHZhbG9yZXMgZGUgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZS4KCiMgRXNwYWNpbyBjYXJ0ZXNpYW5vCgpTZSB0cmF0YSBkZSB1biBlc3BhY2lvIGZvcm1hZG8gcG9yIGRvcyBlamVzIHBlcnBlbmRpY3VsYXJlcywgZWwgZWplIFggKGhvcml6b250YWwpIHkgZWwgZWplIFkgKHZlcnRpY2FsKS4KQ2FkYSB1bm8gZGUgZXN0b3MgZWplcyBzZSBwdWVkZSB0cmF0YXIgY29tbyB1bmEgcmVnbGEgZG9uZGUgc2UgcHVlZGVuIG1hcGVhciB2YXJpYWJsZXMuCgpQb3IgZWplbXBsbzoKCi0gICBFbiBlbCBlamUgWCBzZSBwdWVkZSBtYXBlYXIgbGEgdmFyaWFibGUgZWRhZCAodmFyaWFibGUgbnVtw6lyaWNhIGRpc2NyZXRhKS4KICAgIExhIHJlZ2xhIHBvZHLDrWEgcGFydGlyIGRlc2RlIGNlcm8gc2kgc2UgcmVjb2dlIGluZm9ybWFjacOzbiBxdWUgaW5jbHV5ZSBhIG5pw7FvcyBvIHBvZHLDrWEgcGFydGlyIGRlc2RlIDE4IHNpIHNlIHJlY29nZSBpbmZvcm1hY2nDs24gZGUgbWF5b3JlcyBkZSBlZGFkLgoKLSAgIEVuIGVsIGVqZSBZIHNlIHB1ZWRlIG1hcGVhciBsYSB2YXJpYWJsZSBlc3RhdHVyYSAodmFyaWFibGUgbnVtw6lyaWNhIGNvbnRpbnVhKS4KCi0gICBTaSBzZSBjb21iaW5hbiBhbWJvcyBlamVzIHNlIGZvcm1hIGVsIGVzcGFjaW8sIGRvbmRlIGNhZGEgaW5kaXZpZHVvIGVzdGFyw6EgbWFwZWFkbywgY29uIHN1cyBkYXRvcyBkZSBwZXNvIHkgZGUgZXN0YXR1cmEgY29tbyBjb29yZGVuYWRhcyBkZSB1YmljYWNpw7NuIGVuIGVzdGUgZXNwYWNpby4KCi0gICBFbCBjb25qdW50byBkZSBpbmRpdmlkdW9zIChvIHB1bnRvcykgZm9ybWFyw6EgdW5hICJudWJlIiBkZSBwdW50b3MgZW4gZXN0ZSBlc3BhY2lvLgogICAgRXN0ZSB0aXBvIGRlIGdyw6FmaWNvIHNlIGxsYW1hIEdyw6FmaWNvIG8gRGlhZ3JhbWEgZGUgRGlzcGVyc2nDs24uCgohW10oSVpBV09MLjMzNi5nYS5wbmcpe3dpZHRoPSI1MjUifQoKQWhvcmEgcHJlc2VudGFyZW1vcyB1biBlamVtcGxvIG3DoXMgcG9sw610aWNvLgpFc3RhIGJhc2UgaW5jbHV5ZSBpbmZvcm1hY2nDs24gYSBuaXZlbCBkZXBhcnRhbWVudGFsLCBzb2Npb2RlbW9ncsOhZmljYSB5IGVsZWN0b3JhbCBkZSAyMDE2LCB0b2RhcyB2YXJpYWJsZXMgbnVtw6lyaWNhcy4KCmBgYHtyIGJhc2UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkocmlvKQpkYXRhID0gaW1wb3J0KCJiYXNlcy92b3RvMjAyMV92Mi54bHN4IikKYGBgCgpQYXJhIGVtcGV6YXIgdXNhcmVtb3MgZG9zIHZhcmlhYmxlcyBwYXJhIGdlbmVyYWwgZWwgZ3LDoWZpY28gZGUgZGlzcGVyc2nDs246CgotICAgRW4gZWwgZWplIFggc2UgbWFwZWFyw6EgZWwgcG9yY2VudGFqZSBkZSBhbmFsZmFiZXRpc21vICh2YXJpYWJsZTogQW5hbGZhYmV0aXNtbykuCgotICAgRW4gZWwgZWplIFkgc2UgbWFwZWFyw6EgZWwgcG9yY2VudGFqZSBkZSB2b3RvIGEgUGVyw7ogTGlicmUgZW4gcHJpbWVyYSB2dWVsdGEgZGUgMjAyMSAodmFyaWFibGU6IFZvdG9QTF8xKS4KCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmdncGxvdChkYXRhLCBhZXMoeD1BbmFsZmFiZXRpc21vLCB5PVZvdG9QTF8xKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fdGV4dChkYXRhPWRhdGEsIGFlcyhsYWJlbD1EZXBhcnRhbWVudG8pLCAKICAgICAgICAgICAgY2V4PTIsIG51ZGdlX3kgPSAxLjEsIGNoZWNrX292ZXJsYXAgPSBUKSsgI1BhdGEgZXRpcXVldGFyIGxvcyBwdW50b3MsIGRhcmxlcyB1biB0YW1hw7FvLCB1YmljYWNpw7NuIHkgcHJldmVuaXIgcXVlIHNlIHNvYnJlcG9uZ2FuCiAgbGFicyh4PSJQb3JjZW50YWplIGRlIGFuYWxmYWJldGlzbW8iLCAKICAgICAgIHk9IlZvdG8gYSBQZXLDuiBMaWJyZSAoMWVyYSB2dWVsdGEpIikrICNwYXJhIGV0aXF1ZXRhciBsb3MgZWplcwogIHRoZW1lX2xpZ2h0KCkKYGBgCgpFc3RhICJudWJlIiBkZSBwdW50b3Mgbm9zIGRhbiB1bmEgaWRlYSB2aXN1YWwgZGUgbGEgcHJvYmFibGUgcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXMuCkVuIGVzdG9zIGNhc29zIHZlbW9zIHF1ZSBsYXMgdmFyaWFibGVzIGZvcm1hbiB1biBwYXRyw7NuIGFzY2VuZGVudGUgcG9zaXRpdm86IGEgbWVkaWRhIHF1ZSBsb3MgZGVwYXJ0YW1lbnRvcyByZXBvcnRhbiB1biBtYXlvciB0YXNhIGRlIGFuYWxmYWJldGlzbW8sIHRhbWJpw6luIHNlIG9ic2VydmEgdW4gbWF5b3IgcG9yY2VudGFqZSBkZSB2b3RvIGEgUEwgZW4gMjAyMS4KClBvciBlamVtcGxvLCBlbiBlbCBsaWJybyAiRWwgUHJvZmUiIChJRVAsIDIwMjEpIHNlIGV4YW1pbmEgbGEgcmVsYWNpw7NuIGVudHJlIGVsIHBvcmNlbnRhamUgZGUgcG9ibGFjacOzbiBhdXRvaWRlbnRpZmljYWRhIGNvbW8gaW5kw61nZW5hIHkgZWwgdm90byBhIFBlZHJvIENhc3RpbGxvLgpFbCBncsOhZmljbyBxdWUgc2Ugb2J0aWVuZSBhIG5pdmVsIHByb3ZpbmNpYWwgZXMuCgohW10oRkFVYVRJblhFQVlZM2NuLnBuZykKCkN1YW5kbyBzZSB0cmFiYWphIGNvbiBiYXNlcyBkZSBkYXRvcyBjb24gbXVjaGFzIG3DoXMgb2JzZXJ2YWNpb25lcywgYSB2ZWNlcyBubyBlcyBmw6FjaWwgZGlzdGluZ3VpciB1bmEgdGVuZGVuY2lhIGVuIGxhICJudWJlIiBkZSBwdW50b3MuCkRhZG8gcXVlIG51ZXN0cmEgcGVyY2VwY2nDs24gdGllbmUgZXNvcyBsw61taXRlcywgY29uZmlhbW9zIGVuIGVsIG1vZGVsYW1pZW50byBtZWRpYW50ZSB1bmEgcmVsYWNpw7NuIGxpbmVhbCBwYXJhIGVsIGVzdGFibGVjaW1pZW50byBkZSByZWxhY2lvbmVzLgoKIyBSZWxhY2nDs24gbGluZWFsCgpFc3RhIHByb2JhYmxlIHJlbGFjacOzbiBlbnRyZSBlc3RhcyBkb3MgdmFyaWFibGVzIHNlIHJlc3VtZW4vc2ltcGxpZmljYSBtZWRpYW50ZSB1bmEgYXByb3hpbWFjacOzbiBsaW5lYWwuCkVzIGRlY2lyLCBtZWRpYW50ZSB1bmEgcmVjdGEgZGUgYXByb3hpbWFjacOzbi4KCiMjIEVjdWFjacOzbiBkZSBsYSByZWN0YQoKU2UgdGllbmUgcXVlIHJlY29yZGFyIHF1ZSB1bmEgcmVjdGEgdGllbmUgbGEgZm9ybWEgJFkgPSBhICsgYlgkLCBkb25kZSAiYSIgZXMgbGEgY29uc3RhbnRlIHkgImIiIGVzIGxhIHBlbmRpZW50ZS4KQ3VhbHF1aWVyIHJlY3RhIHB1ZWRlIHNlciBncmFmaWNhZGEgY29uIGRpZmVyZW50ZXMgdmFsb3JlcyBkZSBhIHkgYi4KCkxhIHJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzIGRlcGVuZGUgZGUgbGEgcGVuZGllbnRlOgoKLSAgIFNpIGIgZXMgcG9zaXRpdm8sIFkgYXVtZW50YSBjdWFuZG8gWCBhdW1lbnRhLgogICAgRXMgdW5hIHJlbGFjacOzbiBkaXJlY3RhIC8gcG9zaXRpdmEuCgotICAgU2kgYiBlcyBuZWdhdGl2bywgWSBhdW1lbnRhIGN1YW5kbyBYIGRpc21pbnV5ZS4KICAgIEVzIHVuYSByZWxhY2nDs24gaW52ZXJzYSAvIG5lZ2F0aXZhLgoKLSAgIFNpIGIgZXMgY2Vyby4KICAgIFkgbm8gY2FtYmlhIGN1YW5kbyBYIHZhcsOtYS4KICAgIE5vIGV4aXN0ZSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcy4KCkNvbW8gZGlqaW1vcywgbGEgIm51YmUiIGRlIHB1bnRvcyBzZSBtb2RlbGEgbWVkaWFudGUgdW5hIHJlY3RhLgpFc3RhIHJlY3RhIGRlIGFwcm94aW1hY2nDs24gdGllbmUgbGEgZm9ybWEgJFxoYXR7WX0gPSBcaGF0e1xhbHBoYX0gKyBcaGF0e1xiZXRhfSpYJAoKTG9zIHZhbG9yZXMgcXVlIHRpZW5lIGVsICJzb21icmVybyIgc29uIGRhdG9zIHF1ZSBzZSBjYWxjdWxhbiBjb24gbG9zIGRhdG9zIG9ic2VydmFkb3MuClVuYSB2ZXogZXN0aW1hZG9zIGVzdG9zIHZhbG9yZXMgKHNlIHZlcsOhIGxhIGzDs2dpY2EgZW4gdW4gbW9tZW50byksIHNlIHB1ZWRlIGVzdGltYXIgdW4gWSAocG9yIGVzbyB0aWVuZSB0YW1iacOpbiAic29tYnJlcm8iKSBwYXJhIGN1YWxxdWllciB2YWxvciBkZSBYLgoKRW4gbnVlc3RybyBlamVtcGxvLCBzZSBsZSBwdWVkZSBwZWRpciBhIGBnZ3Bsb3RgIHF1ZSBpbmNsdXlhIGxhIHJlY3RhIGRlIGFwcm94aW1hY2nDs24gZW4gZWwgZ3LDoWZpY28gZGUgZGlzcGVyc2nDs24gbWVkaWFudGUgZWwgY29tYW5kbyBgZ2VvbV9zbW9vdGgobWV0aG9kPWxtLCBzZT1GKWAsIHF1ZSBzZSB1c2EgcGFyYSBjYWxjdWxhciB1biBtb2RlbG8gbGluZWFsIChxdWUgdmVyZW1vcyBlbiB1biBtb21lbnRvKQoKYGBge3IgcmVjdGF9CmdncGxvdChkYXRhLCBhZXMoeD1BbmFsZmFiZXRpc21vLCB5PVZvdG9QTF8xKSkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fc21vb3RoKG1ldGhvZD1sbSwgc2U9RikrICNhZ3JlZ2FyIGzDrW5lYSBkZSB0ZW5kZW5jaWEKICBnZW9tX3RleHQoZGF0YT1kYXRhLCBhZXMobGFiZWw9RGVwYXJ0YW1lbnRvKSwgCiAgICAgICAgICAgIGNleD0yLCBudWRnZV95ID0gMS4xLCBjaGVja19vdmVybGFwID0gVCkrICNQYXRhIGV0aXF1ZXRhciBsb3MgcHVudG9zLCBkYXJsZXMgdW4gdGFtYcOxbywgdWJpY2FjacOzbiB5IHByZXZlbmlyIHF1ZSBzZSBzb2JyZXBvbmdhbgogIGxhYnMoeD0iUG9yY2VudGFqZSBkZSBhbmFsZmFiZXRpc21vIiwgCiAgICAgICB5PSJWb3RvIGEgUGVyw7ogTGlicmUgKDFlcmEgdnVlbHRhKSIpKyAjcGFyYSBldGlxdWV0YXIgbG9zIGVqZXMKICB0aGVtZV9saWdodCgpCmBgYAoKwr9Dw7NtbyBzZSBjYWxjdWxhIHF1ZSBFU0EgZXMgbGEgcmVjdGEgZGUgYXByb3hpbWFjacOzbiwgeSBubyBvdHJhPwpMYSByZWN0YSBjYWxjdWxhZGEgc2UgZGVmaW5lIGNvbW8gYXF1ZWxsYSBxdWUgbWluaW1pemEgbG9zIHJlc2lkdW9zLgoKIyBSZXNpZHVvcyBvIGVycm9yZXMKClNlIHRyYXRhIGRlIGxhIGRpZmVyZW5jaWEgZW50cmUgZWwgdmFsb3Igb2JzZXJ2YWRvIHkgZWwgdmFsb3IgY2FsY3VsYWRvIHBvciBsYSByZWN0YTogJFkgLSBcaGF0e1l9JAoKRXMgZGVjaXIsIGNhZGEgb2JzZXJ2YWNpw7NuIHRpZW5lIHVuIHJlc2lkdW8sIHF1ZSBzZXLDrWEgdmlzdWFsbWVudGUsIGxhIGRpc3RhbmNpYSB2ZXJ0aWNhbCBkZWwgcHVudG8gYSBsYSByZWN0YSBkZSBhcHJveGltYWNpw7NuLgoKYGBge3IgcmVzaWR1b3N9CiNFc3RlIGPDs2RpZ28gZGUgYWJham8gbm8gc2UgZXZhbHVhcsOhCnBsb3QoZGF0YSRBbmFsZmFiZXRpc21vLCBkYXRhJFZvdG9QTF8xLAogICAgIHhsYWI9IlBvcmNlbnRhamUgZGUgYW5hbGZhYmV0aXNtbyBwb3IgZGVwYXJ0YW1lbnRvIiwKICAgICB5bGFiPSJWb3RvIGEgUEwgKDFlcmEgdnVlbHRhKSIsCiAgICAgcGNoPTE5LCB4bGltPWMoMCwxNSksIHlsaW09YygwLCA1NSkpCmFibGluZShsbShkYXRhJFZvdG9QTF8xIH4gZGF0YSRBbmFsZmFiZXRpc21vKSkKZml0dGVkID0gcHJlZGljdChsbShkYXRhJFZvdG9QTF8xIH4gZGF0YSRBbmFsZmFiZXRpc21vKSkKZm9yIChpIGluIDE6MjUpIHsKICBsaW5lcyggYyhkYXRhJEFuYWxmYWJldGlzbW9baV0sIGRhdGEkQW5hbGZhYmV0aXNtb1tpXSksIGMoZGF0YSRWb3RvUExfMVtpXSwgZml0dGVkW2ldKSwgY29sPSJibHVlIikKfQpgYGAKCkNhZGEgcHVudG8gc2UgYXByb3hpbWEgbyBzZSBhbGVqYSBtw6FzIGRlIGxhIHJlY3RhIGRlIGFwcm94aW1hY2nDs24uCkVzdGFzIGRpc3RhbmNpYXMgc2UgcHVlZGVuIHN1bWFyIHBhcmEgZGFybm9zIHVuYSBpZGVhIGRlIHF1w6kgdGFuIGJpZW4gZXN0YSByZWN0YSAicmVzdW1lIiBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBkYXRvcy4KClNlIGRlZmluZSBsYSByZWN0YSBkZSBhcHJveGltYWNpw7NuIGNvbW8gbGEgcmVjdGEgcXVlIG1pbmltaXphIGVzdGEgc3VtYSBkZSByZXNpZHVvcy4KRXMgZGVjaXIsIGN1YWxxdWllciBvdHJhIHJlY3RhIHRlbmRyw61hIHVuYSBtYXlvciBzdW1hIGRlIGVzYXMgbMOtbmVhcyBhenVsZXMuCkVzdGEgcmVjdGEgdGllbmUgdW5hIGVjdWFjacOzbiBkZSBsYSByZWN0YSwgY29uIHVuYSBjb25zdGFudGUgeSB1bmEgcGVuZGllbnRlIGVzcGVjw61maWNhLgpEZSBtYW5lcmEgZm9ybWFsIGxhIHN1bWEgc2UgaGFjZSBkZSBsb3MgcmVzaWR1b3MgYWwgY3VhZHJhZG8gcGFyYSBldml0YXIgbG9zIHZhbG9yZXMgbmVnYXRpdm9zLgoKUGFyYSBlc3RvIHNlIHRpZW5lIHF1ZSBjYWxjdWxhciBlbCBtb2RlbG8gbGluZWFsIGNvbiBlbCBjb21hbmRvIGBsbWAsIHkgZXN0byBtb2RlbG8gc2UgZ3VhcmRhIGVuIHVuIG9iamV0byAibW9kZWxvMSIuCgpgYGB7ciBtb2RlbG99Cm1vZGVsbzEgPSBsbShkYXRhJFZvdG9QTF8xIH4gZGF0YSRBbmFsZmFiZXRpc21vKQpgYGAKCmBgYHtyfQpzdW1tYXJ5KG1vZGVsbzEpCmBgYAoKIyBSZWN0YSBkZSBhcHJveGltYWNpw7NuCgpMb3MgcHJpbWVyb3MgZGF0b3MgYSBhbmFsaXphciBlc3TDoW4gZW4gbGEgY29sdW1uYSAiRXN0aW1hdGUiLgpFc3RvcyBkYXRvcyBkZWZpbmVuIGxhIGVjdWFjacOzbiBkZSBsYSByZWN0YS4KU2Vnw7puIGVzdG9zIGRhdG9zIHNlIHRlbmRyw61hICQkXGhhdHtZfSA9IDYuNTcgKyAzLjAzKlgkJAoKIyBNb2RlbG8gbGluZWFsCgpDb21vIGluZGljYW1vcywgbGEgcmVsYWNpw7NuIGVudHJlIGRvcyB2YXJpYWJsZXMgY3VhbnRpdGF0aXZhcyBzZSBtb2RlbGEgbWVkaWFudGUgdW5hIHJlY3RhIGRlIGFwcm94aW1hY2nDs24uClBhcmEgZXZhbHVhciB1bmEgcmVsYWNpw7NuIGVudHJlIGRvcyB2YXJpYWJsZXMgbnVtw6lyaWNhcywgdGVuZW1vcyBxdWUgcmVzcG9uZGVyIGxhcyBzaWd1aWVudGVzIHByZWd1bnRhczoKCi0gICDCv0V4aXN0ZSBhc29jaWFjacOzbj8KCi0gICDCv0VuIHF1w6kgZGlyZWNjacOzbj8KCi0gICDCv0NvbiBxdcOpIGZ1ZXJ6YT8KCi0gICBQcmVkZWNpciBwYXJhIHZhbG9yZXMgc2lnbmlmaWNhdGl2b3MKCiMgUHJlZGljY2nDs24KCkNvbiBlc3RhIGVjdWFjacOzbiBzZSBwdWVkZSAqKmVzdGltYXIqKiBlbCB2YWxvciBkZSBZIChlcyBkZWNpciwgZWwgdm90byBhIFBMKSBwYXJhIGN1YWxxdWllciB2YWxvciBkZSBYIChkZSBhbmFsZmFiZXRpc21vKS4KClBvciBlamVtcGxvLCBlbiBBbWF6b25hcyBzZSB0aWVuZSA4LjAzJSBkZSB0YXNhIGRlIGFuYWxmYWJldGlzbW8sIHNlZ8O6biBsYSBiYXNlIGRlIGRhdG9zLgpEZSBhY3VlcmRvIGEgbGEgZWN1YWNpw7NuLCBlbCB2b3RvIGVzdGltYWRvIGEgUEwgc2Vyw61hIDYuNTcgKyAzLjAzXCo4LjAzID0gMzAuOSUuCgpFbCB2b3RvIG9ic2VydmFkbyBhIFBMIGVuIEFtYXpvbmFzIGZ1ZSAyNi4xJS4KUG9yIGxvIHRhbnRvLCBlbCByZXNpZHVvIGRlIGVzdGEgb2JzZXJ2YWNpw7NuIGVzIDI2LjEtMzAuOSA9IC00LjguCkVzdGUgZXMgZWwgZXJyb3IgZGUgcHJlZGljY2nDs24uCgpFbCB2b3RvIHByZWRpY2hvIGEgUEwgbm8gc29sbyBzZSBwdWVkZSBjYWxjdWxhciBwYXJhIGxvcyB2YWxvcmVzIG9ic2VydmFkb3MgZGUgYWNjZXNvIGEgaW50ZXJuZXQsIHNpbm8gdGFtYmnDqW4gcGFyYSBjdWFscXVpZXIgdmFsb3IgZGUgWC4KCsK/Q3XDoW50byBzZXLDrWEgZWwgdm90byBwcmVkaWNobyBhIFBMIGVuIHVuIGRlcGFydGFtZW50byBjb24gY2VybyBhbmFsZmFiZXRpc21vPwrCv2N1w6FudG8gc2Vyw61hIGVsIHZvdG8gcHJlZGljaG8gYSBQTCBlbiB1biBkZXBhcnRhbWVudG8gY29uIHRvdGFsIGFuYWxmYWJldGlzbW8/CgpFc3RhcyBkb3MgcHJlZ3VudGFzIGltcGxpY2FuIGVsIGPDoWxjdWxvIGRlICRcaGF0e1l9JCBwYXJhIGN1YW5kbyBYPTAgKGVuIGxhIHByaW1lcmEgcHJlZ3VudGEpIHkgcGFyYSBjdWFuZG8gWD0xMDAgKGVuIGxhIHNlZ3VuZGEgcHJlZ3VudGEpLgpFbiBsYSByZWFsaWRhZCBubyB0ZW5lbW9zIGRvcyBkZXBhcnRhbWVudG9zIGNvbiBlc3RvcyB2YWxvcmVzIGRlIFgsIHBlcm8gZXN0b3Mgc2UgcHVlZGVuICoqcHJlZGVjaXIqKiBhIHBhcnRpciBkZWwgbW9kZWxvIGdlbmVyYWRvLgoKIyBDb3JyZWxhY2nDs24gbm8gZXMgY2F1c2FsaWRhZAoKUXVlIHNlIHB1ZWRhIGdyYWZpY2FyIGxvcyBkYXRvcyBkZSBkb3MgdmFyaWFibGVzIGVuIHVuIGVzcGFjaW8gY2FydGVzaWFubyB5IHF1ZSBzZSBwdWVkYSBjYWxjdWxhciBsYSBtZWpvciByZWN0YSBkZSBhcHJveGltYWNpw7NuIE5PIHNpZ25pZmljYSBxdWUgYW1iYXMgdmFyaWFibGVzIG5lY2VzYXJpYW1lbnRlIGVzdMOhbiByZWxhY2lvbmFkYXMgbyBxdWUgaGF5YSB1bmEgcmVsYWNpw7NuIGRlIGNhdXNhbGlkYWQuCgpQYXJhIGVzdGFibGVjZXIgdW5hIHJlbGFjacOzbiBkZSBjYXVzYWxpZGFkIGhhY2UgZmFsdGE6CgotICAgUXVlIGhheWEgY29uc2lzdGVuY2lhIGVudHJlIHZhcmlvcyBlc3R1ZGlvczogdW4gZXN0dWRpbyAoY2FzaSkgbnVuY2EgZXMgc3VmaWNpZW50ZSBwYXJhIGRlZmluaXIgdW4gaGFsbGF6Z28uCiAgICBMYSBjb252ZXJnZW5jaWEgZW50cmUgZGlmZXJlbnRlcyBlc3R1ZGlvcyAoZW4gZGlmZXJlbnRlcyBsdWdhcmVzIHkgdGllbXBvcykgbGUgZGEgbWF5b3Igcm9idXN0ZXogYSBsYSByZWxhY2nDs24gZW50cmUgZG9zIHZhcmlhYmxlcy4KCi0gICBRdWUgaGF5YSB1bmEgKGZ1ZXJ6YSBkZSkgYXNvY2lhY2nDs246IHF1ZSBleGlzdGUgdW5hIGNvcnJlbGFjacOzbiBlcyB1biBwcmltZXIgcGFzbyBwYXJhIHBvZGVyIGx1ZWdvIGV2YWx1YXIgdW5hIHByb2JhYmxlIGNhdXNhbGlkYWQuCiAgICBMYSByZWxhY2nDs24gZXMgdW5hIGVzdGFkw61zdGljYSB5IG5vIHVuYSByZWxhY2nDs24gZGV0ZXJtaW5pc3RhLgoKLSAgIFVuIG1lY2FuaXNtbzogdW5hIGV4cGxpY2FjacOzbiBiYXNhZGEgZW4gbGEgdGVvcsOtYSBxdWUgZGVmaWVuZGEgcG9ycXXDqSBlcyBwbGF1c2libGUgaGFibGFyIGRlIHVuYSBwcm9iYWJsZSByZWxhY2nDs24gZW50cmUgZXNhcyBkb3MgdmFyaWFibGVzLgoKLSAgIFRlbXBvcmFsaWRhZDogcXVlIGxhIGNhdXNhIHByZWNlZGEgYWwgZWZlY3RvLgogICAgRXMgZGVjaXIgcXVlIGxhIG1lZGljacOzbiBkZWwgWCBzZWEgYW50ZXJpb3IgYSBsYSBkZWwgWS4KICAgIEVuIG51ZXN0cm8gZWplbXBsbywgbm8gc2UgcG9kcsOtYSBoYWJsYXIgZGUgY2F1c2FsaWRhZCBzaSBlbCBYIGh1YmllcmEgc2lkbyBtZWRpZG8gYW50ZXMgZGUgMjAyMS4KClVuIGVqZW1wbG8gcXVlIGN1bXBsZSBlc3RhcyBjb25kaWNpb25lcyBlcyBsYSByZWxhY2nDs24gZW50cmUgY29uc3VtbyBkZSB0YWJhY28geSBkZXNhcnJvbGxvIGRlIGPDoW5jZXIgZGUgcHVsbcOzbi4KCiFbXSh0b2JhY2NvX2FuZF9jYW5jZXIuZ2lmKQoKUGFyYSBlc3RhYmxlY2VyIHVuYSByZWxhY2nDs24gZGUgY2F1c2FsaWRhZCBlbnRyZSBhbWJhcyB2YXJpYWJsZXMgc2UgaGFuIHJlYWxpemFkbyBtw7psdGlwbGVzIGVzdHVkaW9zLCBzZSB0aWVuZSB1bmEgcmVsYWNpw7NuIGVzdGFkw61zdGljYSByb2J1c3RhLCBzZSB0aWVuZSB1biBtZWNhbmlzbW8gZW4gbGEgbmljb3RpbmEgeSBzZSB0aWVuZSB1bmEgc2VjdWVuY2lhIHRlbXBvcmFsLCBzZSBmdW1hIHkgbHVlZ28gc2UgZGVzYXJyb2xsYSBlbCBjw6FuY2VyIGRlIHB1bG3Ds24uCgpQb3IgZWplbXBsbywgcHVlZGUgZXhpc3RpciB1bmEgY29ycmVsYWNpw7NuIGVudHJlIGVsIGNvbnN1bW8gZGUgY2hvY29sYXRlIGVuIHVuIHBhw61zIHkgZWwgbsO6bWVybyBkZSBwcmVtaW9zIE5vYmVsIHF1ZSBjdWVudGUgZXNlIHBhw61zLkxhIHByZWd1bnRhIGVzIGN1w6FsIGVzIGVsIG1lY2FuaXNtbyBleHBsaWNhdGl2byBlbnRyZSB1bmEgdmFyaWFibGUgeSBsYSBvdHJhLgpQdWVkZW4gdmVyIG3DoXMgW2NvcnJlbGFjaW9uZXMgbG9jYXNdKGh0dHA6Ly93d3cudHlsZXJ2aWdlbi5jb20vc3B1cmlvdXMtY29ycmVsYXRpb25zKSBlcyBlc3RlIGxpbmsuCgohW10obm9iZWxfY2hvY28uanBlZyl7d2lkdGg9IjU1OCJ9CgpFbiBhbGd1bm9zIGNhc29zLCBsYSByZWxhY2nDs24gZW50cmUgZG9zIHZhcmlhYmxlcyBlbiByZWFsaWRhZCBlcyBleHBsaWNhZGEgcG9yIHVuYSB0ZXJjZXJhIHZhcmlhYmxlLgpFbiBlc3RlIHRpcG8gZGUgY2Fzb3Mgc2UgaGFibGEgZGUgY29ycmVsYWNpb25lcyBlc3DDunJlYXMuClBvciBlamVtcGxvOgoKIVtdKFNjcmVlbnNob3RfMjAxODEyMDMtMDgwMTA4LmpwZyl7d2lkdGg9IjIwNCJ9CgpEZSBtYW5lcmEgbcOhcyBncsOhZmljYToKCiFbXShub3RjYXVzYXRpb24ucG5nKXt3aWR0aD0iNDAwIn0KCiMgwr9FeGlzdGUgdW5hIGFzb2NpYWNpw7NuIG8gcmVsYWNpw7NuIGVudHJlIGxhcyB2YXJpYWJsZXM/CgpTZWfDum4gZXN0b3MgcmVzdWx0YWRvcyBsYSBlY3VhY2nDs24gZGUgbGEgcmVjdGEgZXM6XAokJFxoYXR7WX0gPSA2LjU3ICsgMy4wMypYJCQKCkVuIGVzdGEgZWN1YWNpw7NuLCBlbCBkYXRvIHF1ZSBtYXJjYSBsYSByZWxhY2nDs24gZW50cmUgYW1iYXMgdmFyaWFibGVzIGVzIGxhIHBlbmRpZW50ZS4KRWwgJFxoYXR7XGJldGF9ID0gKzMuMDMkLgpFc3RlIGRhdG8gZXMgdW5hIGFwcm94aW1hY2nDs24gZGVzZGUgbG9zIGRhdG9zIGRlbCAidmVyZGFkZXJvIiB2YWxvciBkZSAkXGJldGEkLgpDb21vIHRvZGEgYXByb3hpbWFjacOzbiBhIHBhcnRpciBkZSBkYXRvcywgZXN0ZSB2YWxvciBkZSAkXGhhdHtcYmV0YX0kIHRpZW5lIHVuIGVycm9yIGVzdMOhbmRhciB5IHBvciBsbyB0YW50byB1biBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlIHBvc2libGVzIHZhbG9yZXMgZGVsIHBhcsOhbWV0cm8gcG9ibGFjaW9uYWwuCkNvbiBlbCBlc3RpbWFkbyB5IGVsIGVycm9yIGVzdMOhbmRhciBzZSBwdWVkZSB1c2FyIGxhIGRpc3RyaWJ1Y2nDs24gdCBwYXJhIGluZmVyaXIgYSBsYSBwb2JsYWNpw7NuLgoKTGEgSDA6ICRcYmV0YSA9IDAkCgpMYSBIQTogJFxiZXRhIFxub3Q9IDAkCgpFcyBkZWNpciwgc2UgcG9uZSBhIHBydWViYSBjdcOhbCBlcyBsYSBwcm9iYWJpbGlkYWQgZGUgb2JzZXJ2YXIgdW5hIHBlbmRpZW50ZSBkZSAzLjAzIHNpIGxhICJ2ZXJkYWRlcmEiIHBlbmRpZW50ZSBlcyBjZXJvLgpFc3RhIHByb2JhYmlsaWRhZCBzZSBtaWRlLCBjb21vIHNpZW1wcmUsIGNvbiBlbCBwLXZhbHVlIChvIFByKFw+XHx0XHwpLCBlbiBsYSB0YWJsYSBkZSByZXN1bHRhZG9zKS4KCkVuIGxhIGZpbGEgY29ycmVzcG9uZGllbnRlIGEgbGEgdmFyaWFibGUgaW5kZXBlbmRpZW50ZSBzZSBvYnNlcnZhIHF1ZSBlbCBwLXZhbHVlID0gMC4wMDAxNTkgKG8gMC4wMTU5JSkuCkVzIGRlY2lyLCBxdWUgdGVuZW1vcyBtdXkgYmFqYXMgcHJvYmFiaWxpZGFkZXMgZGUgb2JzZXJ2YXIgdW5hIHBlbmRpZW50ZSBkZSAzLjAzIHNpIGxhIHZlcmRhZGVyYSBwZW5kaWVudGUgZXMgY2Vyby4KQ29tbyBlc3RlIHZhbG9yIGVzIG1lbm9yIGEgMC4wNSwgc2UgcHVlZGUgcmVjaGF6YXIgbGEgSDAuCgpDb24gZXN0byBzZSBjb25jbHV5ZSBxdWUgc2UgcHVlZGUgZGVjaXIgcXVlIFPDjSBoYXkgdW5hIChjb3IpcmVsYWNpw7NuIGVudHJlIGFtYmFzIHZhcmlhYmxlcy4KCiMgRGlyZWNjacOzbgoKTGEgZGlyZWNjacOzbiBkZSBsYSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcyBlc3TDoSBtYXJjYWRhIHBvciBlbCBzaWdubyBkZSBsYSBwZW5kaWVudGUuClNpIGVsIHNpZ25vIGVzIHBvc2l0aXZvLCBsYSByZWN0YSBkZSBhcHJveGltYWNpw7NuIHRpZW5lIHBlbmRpZW50ZSBwb3NpdGl2YSB5IGVzbyBpbmRpY2EgdW5hIHJlbGFjacOzbiBwb3NpdGl2YSBlbnRyZSBsYXMgdmFyaWFibGVzIChhIG1heW9yIFgsIG1heW9yIFkpLgpTaSBlbCBzaWdubyBlcyBuZWdhdGl2bywgbGEgcmVjdGEgZGUgYXByb3hpbWFjacOzbiB0aWVuZSB1bmEgcGVuZGllbnRlIG5lZ2F0aXZhIHkgZXNvIGluZGljYSB1bmEgcmVsYWNpw7NuIG5lZ2F0aXZhIGVudHJlIGxhcyB2YXJpYWJsZXMgKGEgbWF5b3IgWCwgbWVub3IgWSkuCgpFbiBudWVzdHJvIGVqZW1wbG8sIGxhIHBlbmRpZW50ZSAoZXMgZGVjaXIsIGVsIHZhbG9yIGRlICRcaGF0e1xiZXRhfSQpIGVzIHBvc2l0aXZhLgpFc28gcXVpZXJlIGRlY2lyIHF1ZSBkZXBhcnRhbWVudG9zIHF1ZSBwcmVzZW50YW4gbWF5b3JlcyB0YXNhcyBkZSBhbmFsZmFiZXRpc21vLCByZXBvcnRhbiwgZW4gKipwcm9tZWRpbyoqLCB1biBtYXlvciB2b3RvIGhhY2lhIFBlZHJvIENhc3RpbGxvLgoKIyBDb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gZGUgUGVhcnNvbgoKRWwgdmFsb3IgZGUgJFxoYXR7XGJldGF9JCBpbmRpY2EgbGEgdGFzYSBkZSBjYW1iaW8sIGVzIGRlY2lyLCBwb3IgY2FkYSB1bmlkYWQgZGUgY2FtYmlvIGVuIFgsIFkgY2FtYmlhICRcaGF0e1xiZXRhfSQgdW5pZGFkZXMuCkVuIG51ZXN0cm8gZWplbXBsbywgcG9yIGNhZGEgMSUgZGUgYXVtZW50byBlbiBsYSB0YXNhIGRlIGFuYWxmYWJldGlzbW8sIGVsIHZvdG8gYSBQZWRybyBDYXN0aWxsbyBjYW1iaWEgMyUuCgpQZXJvIGxhIHBlbmRpZW50ZSBubyBlcyB1biBidWVuIGluZGljYWRvciBkZSBsYSByZWxhY2nDs24gZW50cmUgbGFzIHZhcmlhYmxlcywgcHVlcyBkZXBlbmRlIGRlIGxhcyB1bmlkYWRlcyBkZSBtZWRpZGEgZGUgbGFzIHZhcmlhYmxlcy4KUGFyYSBwb2RlciBldmFsdWFyIGxhIHJlbGFjacOzbiBlbnRyZSBsYXMgdmFyaWFibGVzLCByZXF1ZXJpbW9zIHVuYSB2ZXJzacOzbiBlc3RhbmRhcml6YWRhIGRlIGxhIHBlbmRpZW50ZSwgcXVlIG1pZGEgZWwgY2FtYmlvIGVuIHVuaWRhZGVzIGRlIGRlc3ZpYWNpw7NuIGVzdMOhbmRhci4KCkVzdGEgbWVkaWRhIGVzIGVsIGNvZWZpY2llbnRlIGRlIGNvcnJlbGFjacOzbiBkZSBQZWFyc29uLgpFc3RlIGNvZWZpY2llbnRlIG5vIHNvbG8gbWlkZSBlbCBjYW1iaW8gZW50cmUgbGFzIHZhcmlhYmxlcyBlbiB1bmlkYWRlcyBkZSBkZXN2aWFjacOzbiBlc3TDoW5kYXIsIHNpbm8gdGFtYmnDqW4gZWwgZ3JhZG8gZGUgYWp1c3RlIGRlIGxvcyBwdW50b3MgYSBsYSByZWN0YS4KRXN0ZSBjb2VmaWNpZW50ZSB0aWVuZSBsYXMgc2lndWllbnRlcyBjYXJhY3RlcsOtc3RpY2FzOgoKLSAgIEVsIGNvZWZpY2llbnRlIHIgZGUgUGVhcnNvbiB2YXLDrWEgZW50cmUgLTEgeSArMS4KICAgIEVsIGNvZWZpY2llbnRlIHIgdGllbmUgZWwgbWlzbW8gc2lnbm8gcXVlIGxhIHBlbmRpZW50ZS4KCi0gICByPTAgc2kgbGEgcGVuZGllbnRlIHRhbWJpw6luIGVzIGNlcm8uCgotICAgcj0rMSBvIHI9LTEgc2kgdG9kb3MgbG9zIHB1bnRvcyBjYWVuIGVuIGxhIGzDrW5lYSBkZSBwcmVkaWNjacOzbi4KICAgIEVzIGRlY2lyLCBxdWUgbGEgcHJlZGljY2nDs24gZXMgInBlcmZlY3RhIi4KICAgIEVzdGEgc2l0dWFjacOzbiBlcyBoaXDDs3RldGljYSwgbnVuY2Egc2UgZGEgY29uIGRhdG9zIGVuIGNpZW5jaWFzIHNvY2lhbGVzLgoKRW4gbnVlc3RybyBlamVtcGxvIHI9MC42ODUuCkVzIGRlY2lyLCBwb3IgY2FkYSB1bmlkYWQgZGUgZGVzdmlhY2nDs24gZXN0w6FuZGFyIGRlIGNhbWJpbyBlbiBYLCBZIGNhbWJpYSAwLjY4NSBkZXN2aWFjaW9uZXMgZXN0w6FuZGFyLgoKYGBge3IgY29ycmVsYWNpb259CmNvci50ZXN0KHg9ZGF0YSRBbmFsZmFiZXRpc21vLCB5PWRhdGEkVm90b1BMXzEsIG1ldGhvZD0icGVhcnNvbiIpCmBgYAoKUGFyYSB0ZW5lciB1bmEgaWRlYSBhY2VyY2EgZGUgY8OzbW8gaW50ZXJwcmV0YXIgZXN0ZSB2YWxvciwgbGEgc2lndWllbnRlIGltYWdlbiBtdWVzdHJhIGVqZW1wbG9zIGRlIGRpc3RyaWJ1Y2lvbmVzIGRlIHB1bnRvcyBhIGRpZmVyZW50ZXMgdmFsb3JlcyBkZSByLgoKIVtdKHBlcnNvbi5wbmcpe3dpZHRoPSI1NDcifQoKQ29tbyBzZSBvYnNlcnZhLCBhIG1lZGlkYSBxdWUgZWwgdmFsb3IgZGUgciBzZSBhY2VyY2EgYSAxLCBsb3MgcHVudG9zIHNlIGVuY3VlbnRyYW4gbcOhcyBhbGluZWFkb3MgYSBsYSByZWN0YSBkZSBwcmVkaWNjacOzbiwgcG9yIGxvIHF1ZSBoYWJyw61hIG1lbm9zIHJlc2lkdW9zLCBsbGVnYW5kbyBhIGNlcm8sIGNvbiBwdW50b3MgY29tcGxldGFtZW50ZSBhanVzdGFkb3MgYSBsYSByZWN0YS4KCkEgbWVkaWRhIHF1ZSBlbCB2YWxvciBkZSByIHNlIGFjZXJjYSBhIGNlcm8sIGxvcyBwdW50b3Mgc2UgdnVlbHZlbiBtw6FzIGRpc3BlcnNvcywgZm9ybWFuZG8gdW5hIG51YmUgZGUgcHVudG9zLgpFc29zIHB1bnRvcyBzZSBhanVzdGFuIG1lbm9zIGEgdW5hIHJlY3RhIGRlIHByZWRpY2Npw7NuLgoKUGFyYSB0ZW5lciB1bmEgaWRlYSBtw6FzIGzDumRpY2EgZGUgbGEgZGlzdHJpYnVjacOzbiBkZSBwdW50b3MgYSBkaWZlcmVudGVzIHZhbG9yZXMgZGVsIGNvZWZpY2llbnRlIGRlIFBlYXJzb24sIHB1ZWRlbiBlbnRyYXIgYSBlc3RlIGxpbmsgZGUgW0d1ZXNzIHRoZSBDb3JyZWxhdGlvbl0oaHR0cDovL2d1ZXNzdGhlY29ycmVsYXRpb24uY29tLyksIHF1ZSAiZ2FtaWZpY2EiIGFjZXJ0YXIgY29uIGVsIHZhbG9yIGRlIHIgcGFyYSBkaWZlcmVudGVzIGRpc3BlcnNpb25lcyBkZSBwdW50b3MuCgojIENvZWZpY2llbnRlIGRlIGRldGVybWluYWNpw7NuICRSXjIkCgpFbiBlbCBjb250ZXh0byBkZWwgYW7DoWxpc2lzIGRlIHJlZ3Jlc2nDs24gbGluZWFsLCB0YW1iacOpbiBzZSBhbmFsaXphIHF1w6kgdGFuIGJpZW4gWCBwcmVkaWNlIFkuCkVzdGEgY2FwYWNpZGFkIGRlIFggZGUgcHJlZGVjaXIgbGEgdmFyaWFibGUgWSBzZSBtaWRlIG1lZGlhbnRlIGVsIGNvZWZpY2llbnRlIGRlIGRldGVybWluYWNpw7NuICRSXjIkLgpFc3RlIHZhbG9yIG5vIGVzIG90cm8gcXVlIGVsIGN1YWRyYWRvIGRlbCBjb2VmaWNpZW50ZSBkZSBQZWFyc29uLgoKUGVybywgc2UgaW50ZXJwcmV0YSBjb21vIGxhIHJlZHVjY2nDs24gcHJvcG9yY2lvbmFsIGVuIGVsIGVycm9yIGFsIHVzYXIgbGEgcmVjdGEgZGUgcHJlZGljY2nDs24sIGVuIGx1Z2FyIGRlIHPDs2xvIHVzYXIgJFxiYXJ7WX0kIChlbCBwcm9tZWRpbyBkZSBZKSBwYXJhIHByZWRlY2lyIFkuCgpTZSB0aWVuZSBxdWUgcmVjb3JkYXIgcXVlIGxvcyBlcnJvcmVzIChvIHJlc2lkdW9zKSBzb24gbGFzIGRpc3RhbmNpYXMgZGUgY2FkYSBwdW50byBhIGxhIHJlY3RhLgpDYWRhIHB1bnRvIHRpZW5lIHVuYSBkaXN0YW5jaWEgYSBsYSByZWN0YSBkZSAkXGJhcntZfSQgeSB0YW1iacOpbiB1bmEgZGlzdGFuY2lhIGEgbGEgcmVjdGEgZGUgcHJlZGljY2nDs24uCgpFbiBsYSBpbWFnZW4gZGUgbGEgaXpxdWllcmRhLCBzZSBtdWVzdHJhbiBsYXMgZGlzdGFuY2lhcyBkZSBsb3MgcHVudG9zIGEgbGEgcmVjdGEgZGUgJFxiYXJ7WX0kLgpUb2RhcyBlc3RhcyBkaXN0YW5jaWFzIGFsIGN1YWRyYWRvIHNlIHB1ZWRlbiBzdW1hci4KRXN0YSBzdW1hIGVzIEUxLgoKRW4gbGEgaW1hZ2VuIGRlIGxhIGRlcmVjaGEsIHNlIG11ZXN0cmFuIGxhcyBkaXN0YW5jaWFzIGRlIGxvcyBwdW50b3MgYSBsYSByZWN0YSBkZSBwcmVkaWNjacOzbiAkXGhhdHtZfSQuClRvZGFzIGVzdGFzIGRpc3RhbmNpYXMgYWwgY3VhZHJhZG8gc2UgcHVlZGVuIHN1bWFyLgpFc2Egc3VtYSBlcyBFMi4KCiFbXShkZXRlcm1pbmFjaW9uLnBuZykKCkVudG9uY2VzLCAkUl4yID0gXGZyYWN7RTEtRTJ9e0UxfSQuCkVzdGUgY8OhbGN1bG8gZXMgaWd1YWwgYWwgY3VhZHJhZG8gZGVsIHZhbG9yIGRlIGxhIGNvcnJlbGFjacOzbi4KUG9yIGxvIHRhbnRvOgoKLSAgICRSXjIkIHZhcsOtYSBlbnRyZSAwIHkgMS4KCi0gICAkUl4yPTEkIGltcGxpY2EgcXVlIEUyID0gMCwgZXMgZGVjaXIgcXVlIHRvZG9zIGxvcyBwdW50b3MgY2FlbiBlbiBsYSByZWN0YS4KCi0gICAkUl4yPTAkIHNpIGxhIHBlbmRpZW50ZSBlcyBjZXJvLgoKRW4gbnVlc3RybyBlamVtcGxvLCAkUl4yPTAuNDckLgpFc3RlIHZhbG9yIHNlIGVuY3VlbnRyYSBlbiBsYSBwZW7Dumx0aW1hIGZpbGEgZGVsIGBzdW1tYXJ5YCBkZWwgbW9kZWxvLCBjb24gZWwgbm9tYnJlICJNdWx0aXBsZSBSLXNxdWFyZWQiLgpFcyBkZWNpciwgZWwgbW9kZWxvIHJlZHVjZSB1biA0NyUgZWwgZXJyb3IgZGUgdXNhciBzb2xhbWVudGUgZWwgcHJvbWVkaW8gcGFyYSBlc3RpbWFyIFkuCgojIFZhbGlkZXogZGVsIG1vZGVsbwoKTGEgw7psdGltYSBmaWxhIGRlbCBgc3VtbWFyeWAgbXVlc3RyYSBsb3MgcmVzdWx0YWRvcyBkZSB1bmEgcHJ1ZWJhIEYsIGNvbiB1biBlc3RhZMOtc3RpY28gZGUgbGEgcHJ1ZWJhIHkgdW4gcC12YWx1ZS4KRXN0YSBwcnVlYmEgZXMgbGEgcXVlIG5vcyBpbmRpY2EgbGEgdmFsaWRleiBkZWwgbW9kZWxvIGVuIHN1IGNvbmp1bnRvLgoKQ3VhbmRvIGFuYWxpemFtb3MgcmVsYWNpb25lcyBiaXZhcmlhZGFzLCBlc3RlIHAtdmFsdWUgZXMgaWd1YWwgYWwgcC12YWx1ZSBkZSBsYSBwZW5kaWVudGUsIHBvciBsbyBxdWUgbGEgdmFsaWRleiBzZSBkZXRlcm1pbmEgY29uIGN1YWxxdWllcmEgZGUgZWxsYXMuCgpWYW1vcyBhIHZlciBlbiBsYSBzaWd1aWVudGUgc2VjY2nDs24gZGUgYW7DoWxpc2lzIG11bHRpdmFyaWFkbyBxdWUgZWwgYW7DoWxpc2lzIGRlIGxhIHBydWViYSBGIGVzIGVsIHByaW1lciBwYXNvLCBxdWUgaW5kaWNhIGxhIHZhbGlkZXogZGVsIG1vZGVsbyBtdWx0aXZhcmlhZG8sIHkgcXVlIHNlIHRpZW5lIHF1ZSByZWFsaXphciBhbnRlcyBkZSBhbmFsaXphciBsb3Mgc2lndWllbnRlcyBwYXNvcywgZGUgcmVsYWNpb25lcywgZGlyZWNjaW9uZXMgeSBmdWVyemEuCg==