Diseño de un Estudio de Casos y Controles
En un estudio de casos y controles, identificamos un grupo de
personas con el desenlace de interés (casos) y otro grupo sin el
desenlace (controles). Luego, evaluamos y comparamos las exposiciones
previas entre ambos grupos para explorar asociaciones.
Ejemplo de Planteamiento
Pregunta de Investigación: ¿La hipertensión está
asociada con un mayor riesgo de desarrollar diabetes?
Casos: Personas con diagnóstico de
diabetes.
Controles: Personas sin diagnóstico de
diabetes.
Exposición de interés: Hipertensión.
Covariables: Edad, IMC, actividad física, nivel
educativo, hábito de fumar.
Planteamiento del Estudio
Objetivo del Estudio:
- Evaluar si la hipertensión aumenta el riesgo de diabetes.
Pregunta de Investigación:
- ¿Es más probable que las personas con hipertensión desarrollen
diabetes que aquellas sin hipertensión?
Variables:
Dependiente: Diabetes (Casos: Sí; Controles:
No).
Independiente: Hipertensión (Sí/No).
Covariables: Edad, IMC, actividad física, nivel educativo, hábito
de fumar.
Próximos Pasos
Limpieza de la base de datos simulada.
Exploración descriptiva (EDA) de las características de casos y
controles.
Análisis bivariado (Odds Ratio para hipertensión).
Ajustes multivariados usando regresión logística.
Este documento aborda el análisis de un estudio de casos y controles
para explorar la asociación entre hipertensión y diabetes. Iniciaremos
con:
Descargamos el data frame: https://colab.research.google.com/drive/1BPtDSgzEfWKysUBdbb2UFubOwQecEb8X?usp=sharing#scrollTo=Y6l8GwkV2dssestudio_casos_controles_errores.xlsx
lo guardamos como un objeto (datos)
1. Limpieza de una base de datos con errores
intencionados.
2. Exploración descriptiva de las variables.
3. Análisis bivariado y multivariado mediante regresión
logística.
# Instalar paquetes necesarios (si aún no están instalados)
#install.packages("readxl")
# install.packages("tidyverse")
# install.packages("janitor")
# install.packages("gtsummary")
# Cargar librerías
library(readxl)
library(tidyverse)
library(janitor)
library(gtsummary)
library(dlookr)
# Leer la base de datos desde Excel
#archivo <- "estudio_casos_controles_errores.xlsx"
library(readxl)
library(readxl)
estudio_casos_controles_errores <- read_excel("/Users/jesushernandez/Downloads/estudio_casos_controles_errores.xlsx")
#datos <- read_excel(archivo)
datos<-estudio_casos_controles_errores
# Visualizar las primeras filas
#head(datos)
Paso 2: Limpieza de la Base de Datos
En este paso, utilizaremos las funciones
de janitor y dplyr para:
Limpiar nombres de columnas.
Corregir inconsistencias en valores categóricos.
# Limpiar nombres de columnas
datos <- datos %>% clean_names()
names(datos)
[1] "id" "diabetes" "edad" "sexo"
[5] "imc" "hipertension" "actividad_fisica_min_sem" "fumador"
[9] "nivel_educativo"
# Corregir inconsistencias en valores categóricos
datos <- datos %>%
mutate(
sexo = str_to_title(trimws(sexo)), # Título (primera letra en mayúscula)
fumador = str_to_lower(trimws(fumador)), # Minúscula
hipertension = str_to_lower(trimws(hipertension)), # Minúscula
nivel_educativo = str_to_title(trimws(nivel_educativo)) # Título
)
# Visualizar los datos limpios
head(datos)
sapply(datos, unique)
$id
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
[33] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
[65] 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
[97] 97 98 99 100
$diabetes
[1] "Sí" "No"
$edad
[1] 75 32 58 64 68 47 49 72 52 63 62 79 77 39 76 55 44 66 46 34 33 50 69 78 37 71 65 51 60 57 42 70 35 30 41 40 43 48 45 73 74 36 56
[44] 31 67 53 59 54 38 61
$sexo
[1] "Masculino" "Femenino"
$imc
[1] 25.8 30.4 30.9 29.7 18.6 39.7 38.0 23.0 24.8 37.9 39.6 24.0 30.6 35.8 27.0 34.2 22.0 31.4 37.1 20.2 27.7 22.9 28.2 30.3 20.5
[26] 24.9 38.4 30.7 28.3 34.7 34.5 19.5 33.7 36.5 22.1 35.3 24.7 25.1 32.8 20.9 37.6 33.5 28.0 27.9 34.9 20.3 31.0 36.0 25.7 34.6
[51] 30.8 37.0 36.2 38.1 21.3 21.5 27.1 27.6 21.1 22.8 28.6 35.9 18.7 38.5 33.9 26.6 32.9 19.1 32.2 19.2 28.7 30.2 19.9 32.5 39.9
[76] 35.0 20.7 32.7 19.6 35.5 35.4 23.9 25.5 35.6 21.4 26.5 33.0 32.0 23.1 38.8 33.6 30.0 23.6 34.0 24.1 35.7 39.2 19.7 28.4 24.3
[101] 30.1 25.4 37.4 22.2 30.5 36.6 19.4 18.8 28.1 33.1 32.1 22.7 29.6 21.7 24.4 26.0 23.5 31.6 37.2 31.1 39.8 32.4 19.3 29.9 21.8
[126] 39.3 34.8 34.1 38.7 21.0 31.3 26.1 39.0 31.5 36.7
$hipertension
[1] "no" "sí" "si"
$actividad_fisica_min_sem
[1] 207 295 126 264 208 258 180 259 179 205 199 29 24 38 152 32 115 111 201 113 72 0 225 30 276 23 18 60 123 19 116 153
[33] 6 71 93 10 248 174 191 42 234 15 118 49 33 253 231 290 63 268 26 297 143 45 292 142 289 213 8 245 256 278 288 94
[65] 214 282 228 101 141 262 155 242 84 190 284 66 212 47 296 122 136 68 286 91 2 162 59 9 250 154 139 85 86 98 43 37
[97] 7 97 216 74 58 16 56 137 121 246 272 124 105 188 267 170 151 100 275 172 133 96 112 217 215 11 178 3 132 52 75 138
[129] 125 20 27 80 127 67 108 119 281 202 5 51 240 144
$fumador
[1] "no" "sí"
$nivel_educativo
[1] "Primaria" "Secundaria" "Universitario"
limpieza para evitar que se repitan elementos u homogenizarlos:
# Limpieza y homogenización de datos categóricos
datos <- datos %>%
mutate(
# Homogeneizar valores en `fumador`
hipertension = case_when(
hipertension %in% c("sí", "Sí", "SÍ", "si") ~ "Sí",
hipertension %in% c("no", "No", "NO") ~ "No",
TRUE ~ NA_character_
))
sapply(datos, unique)
$id
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
[33] 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
[65] 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
[97] 97 98 99 100
$diabetes
[1] "Sí" "No"
$edad
[1] 75 32 58 64 68 47 49 72 52 63 62 79 77 39 76 55 44 66 46 34 33 50 69 78 37 71 65 51 60 57 42 70 35 30 41 40 43 48 45 73 74 36 56
[44] 31 67 53 59 54 38 61
$sexo
[1] "Masculino" "Femenino"
$imc
[1] 25.8 30.4 30.9 29.7 18.6 39.7 38.0 23.0 24.8 37.9 39.6 24.0 30.6 35.8 27.0 34.2 22.0 31.4 37.1 20.2 27.7 22.9 28.2 30.3 20.5
[26] 24.9 38.4 30.7 28.3 34.7 34.5 19.5 33.7 36.5 22.1 35.3 24.7 25.1 32.8 20.9 37.6 33.5 28.0 27.9 34.9 20.3 31.0 36.0 25.7 34.6
[51] 30.8 37.0 36.2 38.1 21.3 21.5 27.1 27.6 21.1 22.8 28.6 35.9 18.7 38.5 33.9 26.6 32.9 19.1 32.2 19.2 28.7 30.2 19.9 32.5 39.9
[76] 35.0 20.7 32.7 19.6 35.5 35.4 23.9 25.5 35.6 21.4 26.5 33.0 32.0 23.1 38.8 33.6 30.0 23.6 34.0 24.1 35.7 39.2 19.7 28.4 24.3
[101] 30.1 25.4 37.4 22.2 30.5 36.6 19.4 18.8 28.1 33.1 32.1 22.7 29.6 21.7 24.4 26.0 23.5 31.6 37.2 31.1 39.8 32.4 19.3 29.9 21.8
[126] 39.3 34.8 34.1 38.7 21.0 31.3 26.1 39.0 31.5 36.7
$hipertension
[1] "No" "Sí"
$actividad_fisica_min_sem
[1] 207 295 126 264 208 258 180 259 179 205 199 29 24 38 152 32 115 111 201 113 72 0 225 30 276 23 18 60 123 19 116 153
[33] 6 71 93 10 248 174 191 42 234 15 118 49 33 253 231 290 63 268 26 297 143 45 292 142 289 213 8 245 256 278 288 94
[65] 214 282 228 101 141 262 155 242 84 190 284 66 212 47 296 122 136 68 286 91 2 162 59 9 250 154 139 85 86 98 43 37
[97] 7 97 216 74 58 16 56 137 121 246 272 124 105 188 267 170 151 100 275 172 133 96 112 217 215 11 178 3 132 52 75 138
[129] 125 20 27 80 127 67 108 119 281 202 5 51 240 144
$fumador
[1] "no" "sí"
$nivel_educativo
[1] "Primaria" "Secundaria" "Universitario"
Paso 3: Exploración de Datos (EDA)
Resumen Estadístico de Variables Cuantitativas
podemos usar los paquetes, dlookr, gtsummary o
simbplemete con base R:
# Resumen estadístico
datos %>%
select_if(is.numeric) %>%
summary()
id edad imc actividad_fisica_min_sem
Min. : 1.00 Min. :30.00 Min. :18.60 Min. : 0.0
1st Qu.: 25.75 1st Qu.:45.00 1st Qu.:24.38 1st Qu.: 71.0
Median : 50.50 Median :56.50 Median :30.30 Median :140.0
Mean : 50.50 Mean :55.81 Mean :29.53 Mean :145.5
3rd Qu.: 75.25 3rd Qu.:68.00 3rd Qu.:34.70 3rd Qu.:214.2
Max. :100.00 Max. :79.00 Max. :39.90 Max. :297.0
como lo harías con dlookr?
datos %>% describe()
datos %>% normality()
datos %>% plot_normality()




Distribución de Casos y Controles
# Frecuencia de diabetes
datos %>%
count(diabetes) %>%
mutate(porcentaje = n / sum(n) * 100)
# Gráfico de barras
datos %>%
ggplot(aes(x = diabetes, fill = diabetes)) +
geom_bar() +
labs(title = "Distribución de Casos y Controles", x = "Diabetes", y = "Frecuencia") +
theme_minimal()

Paso 4: Análisis Bivariado (Odds Ratios)
Usaremos tablas de contingencia para calcular las Odds Ratios de
hipertensión.
# Tabla de contingencia
datos2 <- datos %>%
mutate(
diabetes = factor(diabetes, levels = c("Sí", "No")), # Diabetes: "si" primero
hipertension = factor(hipertension, levels = c("Sí", "No")) # Hipertensión: "si" primero
)
tabla_contingencia <- datos2 %>%
count(diabetes, hipertension) %>%
pivot_wider(names_from = hipertension, values_from = n, values_fill = 0)
tabla_contingencia
# Calcular Odds Ratio manualmente
odds_ratio <- (tabla_contingencia$Sí[1] * tabla_contingencia$No[2]) /
(tabla_contingencia$Sí[2] * tabla_contingencia$No[1])
# Extraer valores de la tabla
a <- tabla_contingencia$Sí[1] # Diabetes "Sí" e Hipertensión "Sí"
b <- tabla_contingencia$No[1] # Diabetes "Sí" e Hipertensión "No"
c <- tabla_contingencia$Sí[2] # Diabetes "No" e Hipertensión "Sí"
d <- tabla_contingencia$No[2] # Diabetes "No" e Hipertensión "No"
# Calcular Odds Ratio
odds_ratio <- (a * d) / (b * c)
cat("Odds Ratio de hipertensión asociada a diabetes:", round(odds_ratio, 2))
Odds Ratio de hipertensión asociada a diabetes: 1.33
Determinar IC 95% a a los OR
# Logaritmo natural del OR
ln_or <- log(odds_ratio)
# Varianza del log(OR)
var_ln_or <- (1 / a) + (1 / b) + (1 / c) + (1 / d)
# Intervalo de confianza del 95%
z <- 1.96 # Valor crítico para 95%
se_ln_or <- sqrt(var_ln_or) # Error estándar del log(OR)
# Límites inferior y superior del IC
ic_lower <- exp(ln_or - z * se_ln_or)
ic_upper <- exp(ln_or + z * se_ln_or)
# Imprimir resultados
cat("OR =", round(odds_ratio, 2), "\n","IC95%:", round(ic_lower, 2), "-", round(ic_upper, 2), "\n")
OR = 1.33
IC95%: 0.76 - 2.32
Interpretación del Odds Ratio
OR>1: La hipertensión es más probable en personas con
diabetes.
OR=1 : No hay asociación entre diabetes e hipertensión.
OR<1: La hipertensión es menos probable en personas con
diabetes.
Interpretación del Resultado
Interpretación Práctica:
Existe una posible asociación positiva entre diabetes e
hipertensión (OR=1.33), pero esta asociación no es estadísticamente
significativa según el IC95%=[0.76, 2.32].
Más datos o estudios adicionales serían necesarios para confirmar
esta relación.
nrow(datos)
[1] 120
LS0tCnRpdGxlOiAiRXN0dWRpbyBkZSBjYXNvcyB5IGNvbnRyb2xlcyIKQXV0aG9yOiAiSmVzdXMgQW5nZWwgSGVybsOhbmRleiBDaMOhdmV6IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyMgKipEaXNlw7FvIGRlIHVuIEVzdHVkaW8gZGUgQ2Fzb3MgeSBDb250cm9sZXMqKgoKRW4gdW4gZXN0dWRpbyBkZSBjYXNvcyB5IGNvbnRyb2xlcywgaWRlbnRpZmljYW1vcyB1biBncnVwbyBkZSBwZXJzb25hcyBjb24gZWwgZGVzZW5sYWNlIGRlIGludGVyw6lzIChjYXNvcykgeSBvdHJvIGdydXBvIHNpbiBlbCBkZXNlbmxhY2UgKGNvbnRyb2xlcykuIEx1ZWdvLCBldmFsdWFtb3MgeSBjb21wYXJhbW9zIGxhcyBleHBvc2ljaW9uZXMgcHJldmlhcyBlbnRyZSBhbWJvcyBncnVwb3MgcGFyYSBleHBsb3JhciBhc29jaWFjaW9uZXMuCgojIyMjICoqRWplbXBsbyBkZSBQbGFudGVhbWllbnRvKioKCi0gICAqKlByZWd1bnRhIGRlIEludmVzdGlnYWNpw7NuOioqwqDCv0xhIGhpcGVydGVuc2nDs24gZXN0w6EgYXNvY2lhZGEgY29uIHVuIG1heW9yIHJpZXNnbyBkZSBkZXNhcnJvbGxhciBkaWFiZXRlcz8KCi0gICAqKkNhc29zOioqwqBQZXJzb25hcyBjb24gZGlhZ27Ds3N0aWNvIGRlIGRpYWJldGVzLgoKLSAgICoqQ29udHJvbGVzOioqwqBQZXJzb25hcyBzaW4gZGlhZ27Ds3N0aWNvIGRlIGRpYWJldGVzLgoKLSAgICoqRXhwb3NpY2nDs24gZGUgaW50ZXLDqXM6KirCoEhpcGVydGVuc2nDs24uCgotICAgKipDb3ZhcmlhYmxlczoqKsKgRWRhZCwgSU1DLCBhY3RpdmlkYWQgZsOtc2ljYSwgbml2ZWwgZWR1Y2F0aXZvLCBow6FiaXRvIGRlIGZ1bWFyLgoKIyMjICoqUGxhbnRlYW1pZW50byBkZWwgRXN0dWRpbyoqCgoxLiAgKipPYmpldGl2byBkZWwgRXN0dWRpbzoqKgoKICAgIC0gICBFdmFsdWFyIHNpIGxhIGhpcGVydGVuc2nDs24gYXVtZW50YSBlbCByaWVzZ28gZGUgZGlhYmV0ZXMuCgoyLiAgKipQcmVndW50YSBkZSBJbnZlc3RpZ2FjacOzbjoqKgoKICAgIC0gICDCv0VzIG3DoXMgcHJvYmFibGUgcXVlIGxhcyBwZXJzb25hcyBjb24gaGlwZXJ0ZW5zacOzbiBkZXNhcnJvbGxlbiBkaWFiZXRlcyBxdWUgYXF1ZWxsYXMgc2luIGhpcGVydGVuc2nDs24/CgozLiAgKipWYXJpYWJsZXM6KioKCiAgICAtICAgRGVwZW5kaWVudGU6wqAqKkRpYWJldGVzKirCoChDYXNvczogU8OtOyBDb250cm9sZXM6IE5vKS4KCiAgICAtICAgSW5kZXBlbmRpZW50ZTrCoCoqSGlwZXJ0ZW5zacOzbioqwqAoU8OtL05vKS4KCiAgICAtICAgQ292YXJpYWJsZXM6IEVkYWQsIElNQywgYWN0aXZpZGFkIGbDrXNpY2EsIG5pdmVsIGVkdWNhdGl2bywgaMOhYml0byBkZSBmdW1hci4KCiMjIyAqKlByw7N4aW1vcyBQYXNvcyoqCgotICAgTGltcGllemEgZGUgbGEgYmFzZSBkZSBkYXRvcyBzaW11bGFkYS4KCi0gICBFeHBsb3JhY2nDs24gZGVzY3JpcHRpdmEgKEVEQSkgZGUgbGFzIGNhcmFjdGVyw61zdGljYXMgZGUgY2Fzb3MgeSBjb250cm9sZXMuCgotICAgQW7DoWxpc2lzIGJpdmFyaWFkbyAoT2RkcyBSYXRpbyBwYXJhIGhpcGVydGVuc2nDs24pLgoKLSAgIEFqdXN0ZXMgbXVsdGl2YXJpYWRvcyB1c2FuZG8gcmVncmVzacOzbiBsb2fDrXN0aWNhLgoKRXN0ZSBkb2N1bWVudG8gYWJvcmRhIGVsIGFuw6FsaXNpcyBkZSB1biBlc3R1ZGlvIGRlIGNhc29zIHkgY29udHJvbGVzIHBhcmEgZXhwbG9yYXIgbGEgYXNvY2lhY2nDs24gZW50cmUgaGlwZXJ0ZW5zacOzbiB5IGRpYWJldGVzLiBJbmljaWFyZW1vcyBjb246CgpEZXNjYXJnYW1vcyBlbCBkYXRhIGZyYW1lOsKgPGh0dHBzOi8vY29sYWIucmVzZWFyY2guZ29vZ2xlLmNvbS9kcml2ZS8xQlB0RFNnekVmV0t5c1VCZGJiMlVGdWJPd1FlY0ViOFg/dXNwPXNoYXJpbmcjc2Nyb2xsVG89WTZsOEd3a1YyZHNzPltlc3R1ZGlvX2Nhc29zX2NvbnRyb2xlc19lcnJvcmVzLnhsc3hdKGh0dHBzOi8vcnN0dWRpby1wdWJzLXN0YXRpYy5zMy5hbWF6b25hd3MuY29tL2VzdHVkaW9fY2Fzb3NfY29udHJvbGVzX2Vycm9yZXMueGxzeCkKCmxvIGd1YXJkYW1vcyBjb21vIHVuIG9iamV0byAoZGF0b3MpCgpbMS5dey51bmRlcmxpbmV9wqBMaW1waWV6YSBkZSB1bmEgYmFzZSBkZSBkYXRvcyBjb24gZXJyb3JlcyBpbnRlbmNpb25hZG9zLsKgCgpbMi5dey51bmRlcmxpbmV9wqBFeHBsb3JhY2nDs24gZGVzY3JpcHRpdmEgZGUgbGFzIHZhcmlhYmxlcy7CoAoKWzMuXXsudW5kZXJsaW5lfcKgQW7DoWxpc2lzIGJpdmFyaWFkbyB5IG11bHRpdmFyaWFkbyBtZWRpYW50ZSByZWdyZXNpw7NuIGxvZ8Otc3RpY2EuCgpgYGB7cn0KIyBJbnN0YWxhciBwYXF1ZXRlcyBuZWNlc2FyaW9zIChzaSBhw7puIG5vIGVzdMOhbiBpbnN0YWxhZG9zKQojaW5zdGFsbC5wYWNrYWdlcygicmVhZHhsIikKIyBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQojIGluc3RhbGwucGFja2FnZXMoImphbml0b3IiKQojIGluc3RhbGwucGFja2FnZXMoImd0c3VtbWFyeSIpCgojIENhcmdhciBsaWJyZXLDrWFzCmxpYnJhcnkocmVhZHhsKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgpgYGB7cn0KbGlicmFyeShqYW5pdG9yKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KGd0c3VtbWFyeSkKbGlicmFyeShkbG9va3IpCmBgYAoKYGBge3J9CiMgTGVlciBsYSBiYXNlIGRlIGRhdG9zIGRlc2RlIEV4Y2VsCiNhcmNoaXZvIDwtICJlc3R1ZGlvX2Nhc29zX2NvbnRyb2xlc19lcnJvcmVzLnhsc3giCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KHJlYWR4bCkKCmVzdHVkaW9fY2Fzb3NfY29udHJvbGVzX2Vycm9yZXMgPC0gcmVhZF9leGNlbCgiL1VzZXJzL2plc3VzaGVybmFuZGV6L0Rvd25sb2Fkcy9lc3R1ZGlvX2Nhc29zX2NvbnRyb2xlc19lcnJvcmVzLnhsc3giKQoKCiNkYXRvcyA8LSByZWFkX2V4Y2VsKGFyY2hpdm8pCgpkYXRvczwtZXN0dWRpb19jYXNvc19jb250cm9sZXNfZXJyb3JlcwoKIyBWaXN1YWxpemFyIGxhcyBwcmltZXJhcyBmaWxhcwojaGVhZChkYXRvcykKYGBgCgojIyAqKlBhc28gMjogTGltcGllemEgZGUgbGEgQmFzZSBkZSBEYXRvcyoqCgpFbiBlc3RlIHBhc28sIHV0aWxpemFyZW1vcyBsYXMgZnVuY2lvbmVzIGRlwqBgamFuaXRvcmDCoHnCoGBkcGx5cmDCoHBhcmE6CgoxLiAgTGltcGlhciBub21icmVzIGRlIGNvbHVtbmFzLgoKMi4gIENvcnJlZ2lyIGluY29uc2lzdGVuY2lhcyBlbiB2YWxvcmVzIGNhdGVnw7NyaWNvcy4KCmBgYHtyfQojIExpbXBpYXIgbm9tYnJlcyBkZSBjb2x1bW5hcwpkYXRvcyA8LSBkYXRvcyAlPiUgY2xlYW5fbmFtZXMoKQoKbmFtZXMoZGF0b3MpCmBgYAoKYGBge3J9CiMgQ29ycmVnaXIgaW5jb25zaXN0ZW5jaWFzIGVuIHZhbG9yZXMgY2F0ZWfDs3JpY29zCmRhdG9zIDwtIGRhdG9zICU+JQogIG11dGF0ZSgKICAgIHNleG8gPSBzdHJfdG9fdGl0bGUodHJpbXdzKHNleG8pKSwgICMgVMOtdHVsbyAocHJpbWVyYSBsZXRyYSBlbiBtYXnDunNjdWxhKQogICAgZnVtYWRvciA9IHN0cl90b19sb3dlcih0cmltd3MoZnVtYWRvcikpLCAgIyBNaW7DunNjdWxhCiAgICBoaXBlcnRlbnNpb24gPSBzdHJfdG9fbG93ZXIodHJpbXdzKGhpcGVydGVuc2lvbikpLCAgIyBNaW7DunNjdWxhCiAgICBuaXZlbF9lZHVjYXRpdm8gPSBzdHJfdG9fdGl0bGUodHJpbXdzKG5pdmVsX2VkdWNhdGl2bykpICAjIFTDrXR1bG8KICApCgojIFZpc3VhbGl6YXIgbG9zIGRhdG9zIGxpbXBpb3MKaGVhZChkYXRvcykKYGBgCgpgYGB7cn0Kc2FwcGx5KGRhdG9zLCB1bmlxdWUpCmBgYAoKbGltcGllemEgcGFyYSBldml0YXIgcXVlIHNlIHJlcGl0YW4gZWxlbWVudG9zIHUgaG9tb2dlbml6YXJsb3M6CgpgYGB7cn0KIyBMaW1waWV6YSB5IGhvbW9nZW5pemFjacOzbiBkZSBkYXRvcyBjYXRlZ8Ozcmljb3MKZGF0b3MgPC0gZGF0b3MgJT4lCiAgbXV0YXRlKAogICAgIyBIb21vZ2VuZWl6YXIgdmFsb3JlcyBlbiBgZnVtYWRvcmAKICAgIGhpcGVydGVuc2lvbiA9IGNhc2Vfd2hlbigKICAgICAgaGlwZXJ0ZW5zaW9uICVpbiUgYygic8OtIiwgIlPDrSIsICJTw40iLCAic2kiKSB+ICJTw60iLAogICAgICBoaXBlcnRlbnNpb24gJWluJSBjKCJubyIsICJObyIsICJOTyIpIH4gIk5vIiwKICAgICAgVFJVRSB+IE5BX2NoYXJhY3Rlcl8KICAgICkpCgpzYXBwbHkoZGF0b3MsIHVuaXF1ZSkKYGBgCgojIyAqKlBhc28gMzogRXhwbG9yYWNpw7NuIGRlIERhdG9zIChFREEpKioKCiMjIyAqKlJlc3VtZW4gRXN0YWTDrXN0aWNvIGRlIFZhcmlhYmxlcyBDdWFudGl0YXRpdmFzKioKCnBvZGVtb3MgdXNhciBsb3MgcGFxdWV0ZXMswqAqKmRsb29rciwgZ3RzdW1tYXJ5KirCoG8gc2ltYnBsZW1ldGUgY29uIGJhc2UgUjoKCmBgYHtyfQojIFJlc3VtZW4gZXN0YWTDrXN0aWNvCmRhdG9zICU+JQogIHNlbGVjdF9pZihpcy5udW1lcmljKSAlPiUKICBzdW1tYXJ5KCkKYGBgCgoqKipjb21vIGxvIGhhcsOtYXMgY29uIGRsb29rcj8qKioKCmBgYHtyfQpkYXRvcyAlPiUgZGVzY3JpYmUoKQpgYGAKCmBgYHtyfQpkYXRvcyAlPiUgbm9ybWFsaXR5KCkKYGBgCgpgYGB7cn0KZGF0b3MgJT4lIHBsb3Rfbm9ybWFsaXR5KCkKYGBgCgpEaXN0cmlidWNpw7NuIGRlIENhc29zIHkgQ29udHJvbGVzCgpgYGB7cn0KIyBGcmVjdWVuY2lhIGRlIGRpYWJldGVzCmRhdG9zICU+JQogIGNvdW50KGRpYWJldGVzKSAlPiUKICBtdXRhdGUocG9yY2VudGFqZSA9IG4gLyBzdW0obikgKiAxMDApCmBgYAoKYGBge3J9CiMgR3LDoWZpY28gZGUgYmFycmFzCmRhdG9zICU+JQogIGdncGxvdChhZXMoeCA9IGRpYWJldGVzLCBmaWxsID0gZGlhYmV0ZXMpKSArCiAgZ2VvbV9iYXIoKSArCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlIENhc29zIHkgQ29udHJvbGVzIiwgeCA9ICJEaWFiZXRlcyIsIHkgPSAiRnJlY3VlbmNpYSIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgojIyAqKlBhc28gNDogQW7DoWxpc2lzIEJpdmFyaWFkbyAoT2RkcyBSYXRpb3MpKioKClVzYXJlbW9zIHRhYmxhcyBkZSBjb250aW5nZW5jaWEgcGFyYSBjYWxjdWxhciBsYXMgT2RkcyBSYXRpb3MgZGUgaGlwZXJ0ZW5zacOzbi4KCmBgYHtyfQojIFRhYmxhIGRlIGNvbnRpbmdlbmNpYQoKZGF0b3MyIDwtIGRhdG9zICU+JQogIG11dGF0ZSgKICAgIGRpYWJldGVzID0gZmFjdG9yKGRpYWJldGVzLCBsZXZlbHMgPSBjKCJTw60iLCAiTm8iKSksICAjIERpYWJldGVzOiAic2kiIHByaW1lcm8KICAgIGhpcGVydGVuc2lvbiA9IGZhY3RvcihoaXBlcnRlbnNpb24sIGxldmVscyA9IGMoIlPDrSIsICJObyIpKSAgIyBIaXBlcnRlbnNpw7NuOiAic2kiIHByaW1lcm8KICApCgp0YWJsYV9jb250aW5nZW5jaWEgPC0gZGF0b3MyICU+JQogIGNvdW50KGRpYWJldGVzLCBoaXBlcnRlbnNpb24pICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBoaXBlcnRlbnNpb24sIHZhbHVlc19mcm9tID0gbiwgdmFsdWVzX2ZpbGwgPSAwKQoKdGFibGFfY29udGluZ2VuY2lhCmBgYAoKYGBge3J9CiMgQ2FsY3VsYXIgT2RkcyBSYXRpbyBtYW51YWxtZW50ZQpvZGRzX3JhdGlvIDwtICh0YWJsYV9jb250aW5nZW5jaWEkU8OtWzFdICogdGFibGFfY29udGluZ2VuY2lhJE5vWzJdKSAvCiAgICAgICAgICAgICAgKHRhYmxhX2NvbnRpbmdlbmNpYSRTw61bMl0gKiB0YWJsYV9jb250aW5nZW5jaWEkTm9bMV0pCgoKIyBFeHRyYWVyIHZhbG9yZXMgZGUgbGEgdGFibGEKYSA8LSB0YWJsYV9jb250aW5nZW5jaWEkU8OtWzFdICAjIERpYWJldGVzICJTw60iIGUgSGlwZXJ0ZW5zacOzbiAiU8OtIgpiIDwtIHRhYmxhX2NvbnRpbmdlbmNpYSROb1sxXSAgIyBEaWFiZXRlcyAiU8OtIiBlIEhpcGVydGVuc2nDs24gIk5vIgpjIDwtIHRhYmxhX2NvbnRpbmdlbmNpYSRTw61bMl0gICMgRGlhYmV0ZXMgIk5vIiBlIEhpcGVydGVuc2nDs24gIlPDrSIKZCA8LSB0YWJsYV9jb250aW5nZW5jaWEkTm9bMl0gICMgRGlhYmV0ZXMgIk5vIiBlIEhpcGVydGVuc2nDs24gIk5vIgoKIyBDYWxjdWxhciBPZGRzIFJhdGlvCm9kZHNfcmF0aW8gPC0gKGEgKiBkKSAvIChiICogYykKCmNhdCgiT2RkcyBSYXRpbyBkZSBoaXBlcnRlbnNpw7NuIGFzb2NpYWRhIGEgZGlhYmV0ZXM6Iiwgcm91bmQob2Rkc19yYXRpbywgMikpCmBgYAoKRGV0ZXJtaW5hciBJQyA5NSUgYSBhIGxvcyBPUgoKYGBge3J9CiMgTG9nYXJpdG1vIG5hdHVyYWwgZGVsIE9SCmxuX29yIDwtIGxvZyhvZGRzX3JhdGlvKQoKIyBWYXJpYW56YSBkZWwgbG9nKE9SKQp2YXJfbG5fb3IgPC0gKDEgLyBhKSArICgxIC8gYikgKyAoMSAvIGMpICsgKDEgLyBkKQoKIyBJbnRlcnZhbG8gZGUgY29uZmlhbnphIGRlbCA5NSUKeiA8LSAxLjk2ICAjIFZhbG9yIGNyw610aWNvIHBhcmEgOTUlCnNlX2xuX29yIDwtIHNxcnQodmFyX2xuX29yKSAgIyBFcnJvciBlc3TDoW5kYXIgZGVsIGxvZyhPUikKCiMgTMOtbWl0ZXMgaW5mZXJpb3IgeSBzdXBlcmlvciBkZWwgSUMKaWNfbG93ZXIgPC0gZXhwKGxuX29yIC0geiAqIHNlX2xuX29yKQppY191cHBlciA8LSBleHAobG5fb3IgKyB6ICogc2VfbG5fb3IpCgojIEltcHJpbWlyIHJlc3VsdGFkb3MKY2F0KCJPUiA9Iiwgcm91bmQob2Rkc19yYXRpbywgMiksICJcbiIsIklDOTUlOiIsIHJvdW5kKGljX2xvd2VyLCAyKSwgIi0iLCByb3VuZChpY191cHBlciwgMiksICJcbiIpCmBgYAoKIyMjICoqSW50ZXJwcmV0YWNpw7NuIGRlbCBPZGRzIFJhdGlvKioKCi0gICBPUlw+MTogTGEgaGlwZXJ0ZW5zacOzbiBlcyBtw6FzIHByb2JhYmxlIGVuIHBlcnNvbmFzIGNvbiBkaWFiZXRlcy4KCi0gICBPUj0xIDogTm8gaGF5IGFzb2NpYWNpw7NuIGVudHJlIGRpYWJldGVzIGUgaGlwZXJ0ZW5zacOzbi4KCi0gICBPUlw8MTogTGEgaGlwZXJ0ZW5zacOzbiBlcyBtZW5vcyBwcm9iYWJsZSBlbiBwZXJzb25hcyBjb24gZGlhYmV0ZXMuCgo8IS0tIC0tPgoKLSAgICoqRnJlY3VlbmNpYXMgKCoqYSxiLGMsZCk6CgogICAgLSAgIFNlIGV4dHJhZW4gZGlyZWN0YW1lbnRlIGRlIGxhIHRhYmxhIGRlIGNvbnRpbmdlbmNpYSBjYWxjdWxhZGEgY29uwqBgcGl2b3Rfd2lkZXJgLgoKLSAgICoqT2RkcyBSYXRpbyAoYG9kZHNfcmF0aW9gKToqKgoKICAgIC0gICBFbCBjw6FsY3VsbyBkZWwgT1IgeWEgZXN0w6EgcmVhbGl6YWRvLgoKLSAgICoqTG9nYXJpdG1vIE5hdHVyYWwgZGVsIE9SIChgbG5fb3JgKToqKgoKICAgIC0gICBVdGlsaXphbW9zwqBgbG9nKG9kZHNfcmF0aW8pYMKgcGFyYSBjYWxjdWxhciBlbCBsb2dhcml0bW8gbmF0dXJhbCBkZWwgT1IuCgotICAgKipWYXJpYW56YSBkZWwgbG9nKE9SKSAoYHZhcl9sbl9vcmApOioqCgogICAgLSAgIEbDs3JtdWxhOgoKICAgICAgICAhW10oZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFRc0FBQUFpQ0FZQUFBQklnZndZQUFBTVpVbEVRVlI0QWUyYzFhdFZUeFRIL1FkVVZGQVFGUlVERlFNTEZBTVZUR3hGRkFOOUVCTzdBMFJVVkxBYnhUZFJ4TWJBZXJDN1VQRkJzVEd3RXdQbngyZGdYZWJNblgxcTlybm4vTTdkQzg3ZE5iRm03Vm5mV1RIN2xsQVJSUktJSkJCSklBa0psRWlpVEZRa2trQWtnVWdDS2dLTGFCS2tKSUczYjkrcUh6OStwRlFuVTRVL2ZmcWt2bno1a3FubVUybzNsM2o1L2Z1M2V2WHFWVXI4SjFNNEFvdGtwRlRNeXdBT0J3OGVWTU9HRFZPTkdqWEt5RVJNVnNSLy92eFJwMCtmVmhNbVRGQzFhOWRXTjIvZVRMWnE2T1Z5aVJjRzkrREJBN1Y4K1hMVm9FRUR0V0xGaXRESEc0RkY2Q0xOdndiLy92MnIzcjE3cHk1ZnZxeGF0bXlaVmJENDkrK2Zldi8rdlhyeTVJbm1KWnRna1V1OE1PdStmZnVtc0hCR2poeFp2TURpOCtmUENuTXFFOFRrLy9qeG8rSmxaNHZpalk5eDh6elhDTVhNTmxpSVREQ3o0U1diWUpHTHZNQlRzUUtMWThlT3FWbXpac1dBQmFqSml1S3I0Q2ppZ2dVTDFJRURCK1JkRnpyUzE1a3paOVMrZmZ2VWpSczNZdmdvVkRqTkc5ZXVYVk1qUm94d2dnSThUcDgrUFM2UGFYYnJWUzBDQzdmNGNnbTQ0RENqWURGanhneFZ1blJwVmJKa3lZTGZvRUdEMVBmdjN3dWtzM0hqeG9KbmxPdmR1M2ZNODRLQ25pZTNidDFTWGJ0MlZRVFNvTHQzNzZwcTFhcnB2cnQwNmFKTkxaOHUxcXhabzJiT25Pa0VIWUpsVTZaTVVmWHIxOWUrSDJBeGRlcFVWYjE2ZFVVOTI5TFp1bldycWxDaFFveGNhdGFzcWNxV0xhdmwyYk5uVDNYdTNEbG5YNHhoNTg2ZDJ2ZTIyK1Vad05pblR4OEZxT1FLUldEaGZoUEZDaXdRQVJOMjZOQ2hldUlIcmJxWExsMVNyVnExVWc4ZlBuUkx6Zk11Z2JRQkF3YW8zYnQzeDdRRWJ3TUhEbFMrWUhILy9uM1ZwazBiN2UvR2RLQ1VldkhpaFg3V3JWczM5ZUhEaDVqSGp4NDkwb0c5OGVQSEZ3SU1DaEpVQWtCMzdkcFZVQStldDIvZnJzcVVLYU1tVHB6b3JNZDQrL2Z2SDJoQm5EaHhRdlhvMGNNYklBdVk4anlKd01JdHdHSUhGb2dCSldYU0R4OCtYQkhwdFlubnJMeStyb0Rkcmx5akhDMWF0RkJ2M3J5Uld3VkhUQ3Nmc0lCbmVIZnhMMHFMVlFBd3VBamVzTDVXcmx4WmFQeEVucEhia1NOSFlxb2l3OEdEQit0bk5nQktRZTUzNk5EQjZZNFF0K0JaVUYxcG82aU9ZWUhGN05tejFaMDdkN3pZRGt0QmM0bVg5ZXZYcStQSGozdkpoY29aZFVPRU81UzBTWk1tT2lWRnROa2tKdjZZTVdQVWhRc1h6TnVobmFQTW8wYU4wbWEvcTFGZnNIajU4cVcyRGtpNzJRUVFsQ3BWU3ZjZkJJUUVSTEZLU05mWnNna0NDL3FCYjRDRVZKK0xIajkrckZOZFFYSWx2Z0xndU1EYjFWNG03NFVGRmdBMmJmbFFXR0NSUzd3d2ord0ZKeDBaRlFsWXlPckw1TjYyYlZzTW4rUndNWmxkVVhyOGEvTHdpeFl0VW52Mzd0WCt0bG41NTgrZk90MUcwUERxMWF2Nk9RajYvUG56Z21LazVwbzFheFpva3R0Z1FZcm8yYk5uV3JnQUFYM1FQc0tHSDVzQUNXSVJ1QnNtQ1VpNXhteVc0MXdVMzVaTkVGZ2tZMWtRRityZXZidDJaZXordUVaT2RlclVLY1MzcTJ5bTdpSHIrZlBucTQ0ZE8ycFE3ZGV2bjFxMWFwV1dlVHA5K2lnbzc1bSs0UUdBaHlkNGc4ZDBLSmQ0OFFVTDVncHp0R0xGaW5yT3NMamZ2bjA3SGJFNDZ4VGFaNEZTOFJKNjllb1ZzMU52OCtiTnp0d3RjWUNxVmF1cWVmUG1hVURZc1dPSERnaWFjUTlXa2ViTm0rc1Z0bDI3ZG5vRkovaEhQZXBEbEVFcGdsWWNHeXpXclZ1bktsV3FwTnRrOWNVcXdWd25JRm01Y3VWQ2dVRmVoTXVOSWZQQmZaY2JZVXRNWWhOang0Nk5lZVFDQzlLejhFUE1BbFBYRmNTVVJoZ2JtUkdYVllNOHNHYXVYNzh1eGYvM1J4OEZEWHZ3dWNTTEwxaUVMUnU3dlVKZ2dlV0FRcU9JOSs3ZDArWHg2Wm5NY20wMndrYWRjdVhLS1ZFZ3NVN3ExcTJyV1BHRlJDbkpiQkFnM2JScGsrcmN1WFBCaW9sRlVLTkdEWVZaN2lJYkxDaURBcFV2WHo0RzJMQWNVQzVBd3lUcXU4eDV6RmxBS2htd0VGQ2dMWlBrZnRPbVRUWHd0Ry9mWHNjM3NHUlFkaGNJMlBWZFFFWVo0UytSZVVxc3BYWHIxbm9zakNlWlg3WmlJYm1rb0xuRXkvOE9MSmlnaXhjdjFzckRFUUlRMk9xTENXZ1Rpa0Qyd0Z3NUdUUktiRm9KQWhaQlNvRXlNTUZSRGhlNXdJTDI2Y2QwQzBTNWJJWG0ycjVIUDErL2Z0V21iREpnQVFCUnptNUh3TUpVYU1tZzRHSzRYRGR6ak5RbkhrSmN4Q1laajVscHNjdGs4cHJ4eHZ2RjYxdmNUOFpnL2pDUFQ1NDhHWE9QNThuc284a0hYdEFWNG9PbVREaGZ1SENod2pLMzc3T05BRXMxSHFVcmwzaHQyczhLV1JZVXdJTEFzc0RDWUtJdldiSWtia1NlMVh6eTVNazZKb0J5c01JVkpWaVlTb3FnQVIxYm9ZUEFBckREaFVIWUtHMFFtZkdIdFd2WHhoUnpnUVVGQUxGRTdWS08rbGdocml5UWpNZnVNNGFCSEwxZ253cnBadnZYdUhGam5RcTM3L3ZFSGhLSklKZDRZUXVDUFhhdTBSdFM1ZmF6YWRPbXFhZFBueVlhWXNhZk84RUN0NE9ZQmJFTFRGVTJZTmtaQU9HTUZZS05TV3gwb2g3RTVBOENDMXVKcFIwZnk4SUhMT2lmTWFMVUxqZEYrTU9sd3JVeTNUTjVGZ1FXOEVXN1FmRUlzMzZReFNWZ1lZNVI2cGxIVmg1V0lIdFZpbmVOdFpjTjhqWDkyZWlHUXJHWjBQZXJVMTlld3BRZjh5alJlMDYyUDZ3MDRvaHNnMEJlWVpBVExHZ1lzNWVKWHF0V0xmMVNYSDQzWm1iZnZuMTF1dFZjRlFVc1lITDE2dFY2cDZlNElVRmdRZXFRZlE1QitYZnEyUW9sYm9ncFlGRXV1eCtDb0ZnOTVxNVVFU0M4Z2VnMndNbHpqdXkyUkI2WWlyWXNFb0VGRVh2Y25TQ0t4eHN4SE9TU0tQL091TmdtendxYTdJOE1WellvREFVbDJKd0loSk1aV3hpOEpOTlBNbVhDQkF2NlE1ZElMQVRGQVpQaHlTd1RDQlpZRWdRS3NTN1loK0FpQVFzem1Da2JuRkE4TWl1Z1A4b29ZQkdrc0V4Y2xNSzFENEsrWFdBaEFVNHo4eElFRnJnRXBHWkowYnFJTkN5ZlgzZnExRW05ZnYwNnBnaGJyckVvaGd3WjRvdy9TSmJFNUlNR0FFQ3lJUks0QlRBd3RaR0ZFTUREcExjRHN2S2NNZUtpWkV1eGhZOHdqNzRLS2k2aEdhdEtsejlmWHRMdDExVXZiTEE0ZlBpdy9uVENuRy8wRVM4MjZPSkw3Z1dDaGZqeVFZRTNhWUE4THQvUGcyQ1lobnhUQXBQc3hDU0ZTZFlEQU9DY2xaa2Y1N2d0SmdtWTJCT0FiME5RWXJPdWdKRDVQUXVLVFA3ZC9GYURldFNIc0VJYU5td1lWK2tBQ2JhOFY2bFNSUzFkdWxTdjBDZ3gxK3pjRkRkTCtPYmJFUGx1UmZnekFZOUFGbHU5QWR3NWMrWW92cS9CTkRRdEU0S2FiZHUyMVRLVGRzMGpGcDV0VVpuUGkvS2M4UkRNTnZsUHAzOWZCY1dLNWJPRGl4Y3ZhdkJQRlB5THg2TXZMOUkyTXNIME54VlRuaVY3REFzczJITUNIOHhkckZhVE1nSVdkTUJxeXlhcVJDU0NNcU8ydkVBelE1S29EWjZUZllrWE4waW1qYUF5a2hKT0pxdEEyVk9uVG1td1lLT1hLd3NVMUk5OUg5a1FuRHAwNkpBR1RSdHd5RFN4YTlZVkUySUZ4ZWVVckpUZGRsRmRNNGFqUjQrcWNlUEdLUUFTNjVDQU52eWxRNzRLaXNXR3BUZDY5R2kxWWNNR0RmQ0pNazVCZlByeVFydG56NTdWVmlldUt0ODJzVmltUTc1Z3dXTEhmTm15Wll0ZXBOaWNsUzR2THY0RExRdFg0VXpmSTkzSS95aHc3ZWNJbzI5ZUpsOXkyZ29iUnR2cHRJRVNFZ054eFVGb0QzbVFrZUtZVGNLU3d6MlRuYkc0aFBhS2xRcC9BQS91WXJwRVpvZ1BDMW1NV0VINVNqbFJUQ2VvTDE5ZUFDNnlHQ3dJV0R4WXMzdjI3QW5xTHU1OXNpVHB1cHZNYVlDS09RNWhTYlB2SjZ4NEJXM21GRmpBVUx4UHlMVVVQUDR3c2RnbUhCUVg4V2c2cmFxQUFLczBGcHhOQUFuYjUxMGZydGxsTTNrdGNTa0JCMUhPTUZlc1ZQaTM0eFh5bVlBWjVFNmxQWit5dG14ODJ2S3RTMXlSV0lTQUErOEhFT1Y5aFVVNUJ4YXNGcGlHKy9mdkQydU1NZTJnbUNDd1MwRmpDbWI0Z25HeXY4TU9pa3EzNTgrZjF5NVp1dWExdE9ON3hBSWcxaU1BeTJRa2pnWFEvZnIxeTdmNWxPc0REc1I0V05FaEFzRDE2dFhMbURVYWowRmtRM0EvWGFzbVh0dXBQc09GSVRNcExyUEVLNWhuUGpFZGs0K2NBd3VZSXcySWFTNG9hVEljeGptbUhxdDJOaWE3OE0vL3VnaktNckduZzVVODIwQUJyNWpXbU5tWXRSQm1MdHYwcjF5NW9tTTZNcDZpT2hJUUpzME5QK0xHRVVST04zN2l3emZBeGRaK0FFc0lkd1Izb3FnSjEweTJDK0F1NHI1aVhmQk5WMUFHTUZVZWN4SXNVaDFFVkQ1ekVrQWhjUTFacVpZdFc2YXRQckl6Z0szOUJXL211SWh0bWF3UzJUUVdGTEpNcnIwenNUVXlkNFZsU0FhTmpYMXo1ODdWTXNwR1RBeExHUmViQVBTa1NaUDBPVUZvdG8rSFJSRlloQ1hKUEc4SDMxZE1YSTV5bnExaHcwK1kvcmpQT0pDRm1RbjBhY3VuTHU0R2xoY0F6NDk5UFJ6RG9nZ3N3cEprMUU0a2dUeVhRQVFXZWY2Q28rRkZFZ2hMQWhGWWhDWEpxSjFJQW5rdWdRZ3M4dndGUjhPTEpCQ1dCQ0t3Q0V1U1VUdVJCUEpjQWhGWTVQa0xqb1lYU1NBc0NVUmdFWllrbzNZaUNlUzVCUDRES3liaU4wVTJnK2dBQUFBQVNVVk9SSzVDWUlJPSkKCi0gICAqKkludGVydmFsbyBkZSBDb25maWFuemE6KioKCiAgICAtICAgKipMw61taXRlIGluZmVyaW9yOioqCgogICAgICAgICFbXShkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUtJQUFBQWFDQVlBQUFBMGE0Y0RBQUFJQTBsRVFWUjRBZTJhK2F0TlhSakgvUVBJTDhxTkg0Z2tpWWd5cEZEWGxLRlFaSXBDbWJraE4wTXlsSlF4SkZPVW1aRE1Vc2FRZVpZcDg1QjVEbm5lUGl2UGFwMTkxajdPUHNmWmJyMzdxZE9lMWw3cldkLzFYYyswVHpsSkpFR2dEQ0JRcmd6b2tLaVFJQ0FKRVJNU2xBa0VZaVBpOCtmUDVkYXRXd1daOU5HalIrWHo1ODhGNlR1dVRuLzkraVZuenB5UmI5Kys1VHhrM0JnL2ZmcFVMbDY4bUxPKzdvdVJpUGpnd1FNWk4yNmNEQjgrWEc3Y3VPSDJrL0g4NGNPSE1ucjBhSG4vL3IxdDkvUG5UOW0yYlp0MDd0eFpoZ3daSXQyN2Q1Zmp4NDhMQzRMb1dDTkdqQkQ5alJrelJqWnUzQ2l2WDcrMi9XamJPWFBteVBmdjMxUHVSNzJnMzhtVEo5dnhkRnlPNjlhdFMrc09YYmR1M1NwdDI3WTE4MWkrZkxtc1hMbFNybDY5S212V3JQSDJvMzFldW5USjlrYy9peGN2bHAwN2Q5cDV4NEh4MTY5ZlpmNzgrV2w2enBzM1QyN2Z2bTNYQWtWWmp5REc2TDFpeFFvNWUvYXNuVXV1SjVHSXlDQlhybHlSaGcwYnlvVUxGN0lhODhlUEgxSmFXaXFuVDUrMjdiRmVnd2NQbGxtelpsbnlmUG55eFFCQ1d5VVV4Lzc5KzB2WHJsMkY1Ky9ldlpPOWUvZEs3ZHExemFMWkRrVU1BU0JCUG5MdzRFRnAyclNwWUdFL2ZmcGtGb0pGYWRTb2tiQ1pncko3OTI0Wk5XcVUxZmZVcVZOU3IxNDlndzI2SGpwMFNDcFhyaXpyMTYrWFo4K2VtZCtkTzNmTW5PYk9uV3U3dzZxTUhUdFd3QXFKRTJQSXRHWExGcWxhdGFwY3UzWk5JT2ZObXplbFhidDJ4bmpvV3FBWCtBWXhmdm55cFF3WU1FQTQ1aU9SaVFpZ3pabzF5NXFJVEc3Z3dJR0dTS3Jvd29VTHBWV3JWbW1XN2RHalI5S2dRUU5qOWJRdGhPWG5DdGVOR3plV1Y2OWUyZHRQbmp5UkhqMTZwTnl6RDdNOG1UMTd0bHkvZnQyMjNyRmpoOVNzV1ROMHg2TUhWa3lGUmNWajZDYmxDQkgzN05talRjengvdjM3eHJwd3dUc1RKa3dRTm9GSzNCaWpYNTA2ZGN4R1VSMjRWNkZDQlRsOCtMRGVrakNNMlZSQmd0cVhzanpKbTRqc0lGd2FnR0lGK0xteWFORWljWGMvNUlGRTA2Wk5jNXVaYy9xQXRPM2J0emNXaVp2WkVoRnJ3czUwZ1VzYklNT05EeDgreUtwVnE2dzdVaEppNWNKazJMQmgwckZqUjNuejVvMXRjdVRJRWVQR3VCRWtJdGRxYmRldVhXdkdldkhpaFhIckxMSktrSWlGeGpoYklvWmhmUExrU2VuYnQ2K3hwanFIcU1lOGlFaWMwN3AxYTJuU3BJbE1talRKbVBoZXZYb0pGZzlSWXJrV1FSZkhKYWVyTkhFSVZnaXJnYmhFeEUzczI3ZFA2dGV2THdjT0hIQmZNK2U4Qy9IekZXSWVkSUNNbVlSMnVMVHk1Y3RMeTVZdFpjbVNKUUtoVlhTdXVHWmNNdGJTeFlKMjU4NmRNNWFjVUVERkpXSWNHTHRFWk0zdTNyMHJIVHAwTVBHeTY1clJ6NGZ4NDhlUHpZWmtVK1VxZVJHUlFRR2J1QWdYakRBcHRXaUEyN05uVCt1cXREM3VLaE1ScTFTcElwY3ZYemI5UVVTU2dlM2J0eHNRNnRhdGE1SWNBQXNLZmZvc2JiQmRwbXRpUVdKQ1lzUGdHRndUUDdsa0kya2oyYXBSbzRZaFpJc1dMV3k4cEVRa0FTSU82OWF0V3hvUndZczV1dUlTa2Z1RnhoZ2QyRkNyVjY4MlNSWjRreXdSbHdmRmh6SDZ0bW5UeGhxUDREdlpYUDhWSWhJem9nenlKeUppNmJBMjdDeWZzQ2dRVzNlWGF4RnBqK3NqV1ZIaXUzMjRpNG9ibVRGamh0a1ViQXpmTDZpRGt0Qk5va2hJS0tzZ3pKRllpZ1FGSWVseXlZb2JaMEUzYmRwa25pc1IwUXZCK3FFL2dyWEZrcmc2bXdlL3gzSGpjUG9wSk1ibzRNYUloRnBzcUdYTGxxbEs5dWpUMTJkdzdBdFpuc1JPUkkwek5CTjI5WHo3OXExeGNTVWxKWGFCZzBUVXhkWEZkdC8zN1ZiM2VhWnpTa3VkT25VeW1idTZJeXpDbENsVEJMMlFvRVZrb1Q1Ky9HaTc1VGt4cmxwNzFWV0pxQTFwUjJKRXZPeGJXSjlGakVMRXFCZ0hpUWl4MkxoOSt2U3htYnpxN3NPNG9CYVJ4VGgvL3J6czJyVkx5R1pWb29Da0N4TmNpTEFZakJwaHNGUVNKQ0l1RzllTkN3WndzbHhxa29ndmZsRzlNeDJaSy9VOWlLaTFUdm9rZWFHY0ZDYlVOVStjT0dFZjAwKy9mdjFzQmh4R1JPYlB2RWhDL2hRajBua21pL2czTUE0U0VVc1BGc1M5Yk1KNzkrNVpYSHdZRnlSR0JFeUtuQ1FFUzVjdU5iRU5nU3ZaS0VWTmdDYXQ3OTI3dCt6ZnYxK0tpNHVsVXFWS01uTGtTTm04ZWJOSlhvZ0J4NDhmYnpKb2RwQmFDTHRpdjkwVUU1MDVjNmFwemsrZlB0MEV2SXlCY01ReTRzYUxpb3FNTytTZWtnWUxRY0t5WU1FQzB4NVNEaG8wU01qZ29nb3hYTVdLRlUzU01IVG9VT01HcTFXcmxsYStDUFpMMlFVOE9CTERUcHc0MGVpTWpoUzB3WVpFaHFLOUZyTEpzaG1MakJzaFcyYlJOV3VPRTJNMkFtdE53b21lZkZUUUpKRFFnVENEMkpZUUIzY2RoakdZZ3ozUGM1VVUxMHhITEQ0a1ZFTFFNUzRvMTJ6VVYwZFVaZG5ORkVJcGRuUGtPaHZSOXlnRXMrZ0lDMG41UmkxYU52M2syd1pMZ0ZDeXdsTm9HU3RLdjh3bFdFZU04ajV0QzRFeC9lS2k4VURNQ3duREdESkQySHdraFloWVBYWXJ3VHJDSXZOMW9FdVhMdDR2QzlrTURMa3BXN2hmVnJKNUwyb2JZa1pmM0JpMW4zL1JIdGRMQXBTclJmbVhHRU5TUWhRbGE2NzRwUkFSZDRHSnJsNjl1c2xjK2J5R2kzSExGYmtNNVB2V25Fcy9ZZTlndllsZDFEcUd0U3VyOTdHSytxMDVWeDMvQmNiby9kZS9OUk12VU9keTAvaGNRZkc5VjhoL2hoRHdKLysrRVlrYlk2eWcxbnQ5YXg3bG5yV0lzRHY0ZVUwN0lvUDBGVGYxZVhKTUVNZ1hBVXRFT2lMZ3JGV3JWa3FGSEFKT25UcFZObXpZa085WXlmdi9Fd1JJM1BDc3ZtcEpHQVFwUkNUR29wVFJ2SGx6VTI0Z1J1UmZNc2VPSFF0N1A3bWZJSkNHUU41RTFCNUoyK21NWXlJSkFuRWdrR0lSNHhnd0dTTkJ3SWRBUWtRZktzbTkyQkZJaUJnNzVNbUFQZ1FTSXZwUVNlN0Zqc0IvSXl0eFFCRmpKS29BQUFBQVNVVk9SSzVDWUlJPSkKCiAgICAtICAgKipMw61taXRlIHN1cGVyaW9yOioqCgogICAgICAgICFbXShkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUowQUFBQWpDQVlBQUFDTzVnalRBQUFIdVVsRVFWUjRBZTJheVdzVlFSREcvUWMwZUZHU2d5ZEZSQ1FoTGdkQlFjVzRCSTBHQlZkY3dDMWlZb2hlOUtUQmdKcW9jVGtJZWhCRVhGRVBMcWdJaWlpQ1lsUVV4WDFmY0Y5eHdaSmZZdzA5azNtK21ieThTUjUwUWRJelBUM1YxVjkvWFYzVjh6cUlFNGRBd2doMFNMZy8xNTFEUUJ6cEhBa1NSOENSTG5ISVhZZU9kSTREaVNQZ1NKYzQ1SzVEUnpySGdjUVJjS1JMSEhMWFlXS2tlL255cGR5K2ZUc3JpSjg5ZTFhK2Z2MmFGZDFKS2YzNDhhTTBOVFZsMUYzU0dOKzVjMGZ1M3IwYjIrWllwTHQ2OWFvc1dyUklxcXVyNWZYcjE1RTdlL3o0c1N4ZXZGZ0FWdVgzNzk5eTRNQUJHVHQyck15Yk4wOG1USmdnNTg2ZGt6OS8vcGdtang0OWtxVkxsNXIrNkZQNzNiMTd0N3g5KzFiVmVHM1hybDByUDMvKzlOWEh2YmwvLzc0c1diTEUxNmYyZmZyMDZXYnE2Ry9UcGsxU1VsSWk0OGVQbC8zNzk4djY5ZXZseVpNbnNtSERobEE5NkdOY2pFOEZYTUFIbkhJSlk4YS9aczBhWTdlT0pVb1ppM1FRNHVUSms5S3ZYejk1OGVKRkZQM3k2OWN2V2Jac21WeThlTkZyajFlYU8zZXUxTlhWZVVUNTl1MmJtU1RhS25rb1o4eVlJZVBHalJPZWYvandRWTRkT3lZOWUvYVV3NGNQZS9xNDJMNTl1L256VlZvMzJQN2p4dytycHZubDFxMWJaZVRJa1hMdDJqWDUvdjI3c1FPU2pCa3p4cmRnOU0yTkd6ZEtRME9EV1Nqb2gzUkZSVVh5L1BsenN6QjI3ZG9sWGJwMGtWT25UaG04d0F6ZHc0WU5rNk5IajZvYVExemVSWElONDVzM2I4ckNoUXZOL0hnRFNuTVJpM1RvdW5MbGlnd2NPREF5Nlc3Y3VDR3paOC8yR2NWa0RSa3lwSm5Id2tNd2FYZ3pGY2pKbnkzYzkrL2ZYOTY4ZWVOVlAzdjJUQ1pPbk9pcjh4NktHSHYzN3QxclYvbXVJZG55NWNzOUQ4N2s0N1g2OXUwYnVwSy9mUGxpK3J0OCtiS25oenBzMHdVSnNTQWRtTmx5L3Z4NWdaRElxMWV2Wk5xMGFhYlVOcm1FTVRpeE1NTjJBaDFQc015WWRIZ2Z3R2E3Wk10bDhteGgrMW0zYnAxWEJWRWd6SW9WSzd3NnZXQUFFSFRVcUZGR0ovVlJTWWRIblRWclZzckJRNFQva2U3cDA2ZXliOTgrWTRwTnVIdjM3cWw1dmhKdmpRY01ybkk4TUpnZ1FkSVJlMElvYkNHMFFFNmNPQ0VMRml6d3dncnFncVJyN3hqdjJiUEhoQ1ZtUUJIK1pVUTZ0clR1M2J1YmxicDY5V3JadVhPbkRCbzB5QXVJbFVUMlZnS2dySDZiaUxhZHhHYm9mUERnZ2FtMlNjZDJlL3o0Y1Nrc0xEU1RaYi9ITmU5QzhqQkpSenI3blVPSERoa2JMbDI2WkZjM3U2WmRYbDZlK1NzdExUV2tKZ3hRVWRLeHZlTHg1OHlaMDh6cllYTVFDNXQwdVlBeDNuN0tsQ21SazdtTVNBZTRBS1l4Ri9lUVJFSEVBMDZhTk1rSGRCVFM1ZWZubTloSDlZMFlNVUlPSGp4b1NOVzdkMi9qSlNCMFVPZzN6SVBTTGlycElCcWtoMUJCZ1ZEWHIxODNYcDFuMkVEeXcvYll0V3RYNmRpeG8weWRPdFVMSlNCZDU4NmREUjU0ZzlHalIvdXdRQWQ0Mll1U09wdDAzTGQzakxHWGhQRDkrL2VZbTFaYWhYUUFwNUtPZEhnd0pwVVZIaWE4MzZkUEh5L0c0ZDdXZitiTUdaTkk0RG1Dd3VScDJ3c1hMcGh0bXEyYXY2RkRoNXA0VWU4cEt5c3I1ZlBuejU0YUpSd2VXMG05YmRzMkw2WkRQOFFpbWVLNWZVekRQY2tBQzRhWURhRzlIZE1SOXpCQnlJNGRPK1RUcDArUlNhZmo0bDJ1Lzdld2s4TFlET1RmZ2daUEZuWVVTWngwR252WjNsRU5aYVVNSGp4WWFtcHF2RWtIWUJ0dzlaUjRqcUJrNHVrNHJpQnBJSGxRd2hIazR6bXhHYkU5SFY2Y2JGZmI4aHdDYzN5aW5pdElPcldYZG9RanhMK01UZHZyOHpCUFoyUEE5ZjlJbHpUR3JlYnBBSVRBRjBEc2M3RTRnREFoSkFaQlVOV2pCTGN3c3RaZ3RnakFOdUFjT2VCTmxBeWs3Q1F4U0V0ak9zN0pTQXJJd3ZTNEJvS3RYTGt5NVRFTXBHTnNkcUlCVG1WbFpTWit3NTVVcEdQY1pNcHFzeExJVktUWVhtME1iTksxQjR3emp1bllNamdnNVZpRUxZRFVmdmp3NGNMa2NuREpTaVpPWVd2YXZIbXo5T3JWeTJ5WFc3WnNrZnI2ZW5OZFhGeHMzZ1ZFQUEyQ1NqMkc0dFZXclZwbEVvL2EybG9oR05kRFUwbzhIbHR4UVVHQlZGVlZtV2VRQW5KZ0g1bGZZMk9qbVN0V040RzZibTA2Z1ZxbWl1bFlYTk9uVHpkam1qbHpwaUU0OWhPamRldldUVzdkdXFVcWZDV2tZL0tKNXpnZ0plWWtld1lUQ012aDhJQUJBNlJUcDA0eWVmSmtZek4yTTJhMmFFMTRqaHc1NHN0ZWN4RmpkcDFVc2JRUHRIODN2dTBWSU12THk0WEEzZjU2d09RendTMlJzSE02MWNNcTVaaUZnMk5LZTZ2U05tR2x2c2RuSS9WTW5OTXg2YmJkOXJ1cFNHZTNpWE1OeWRWbVBCejZPZHFJSzJIbmRIRjF0Q1hHekFYOHNBLy8wOW52SXgxQk15dFR6NnZ3QW5nNjB1RlVrNW11QXlhSHp6NXhqRXFuTSt3NXF5MHN6dE8yZ0pQdWk0UzJUYnJFS3lybUxlbTdMVEVtdkdCK2RmRkhzZDhqblI1MjR2cDc5T2doYkRFVkZSVm0yMkM3eUVUQ3ZyMW1vaS80TGxzeDhWeWNnUWQxdE9VOUMxcS92YmJVanJiQUdMd3ordmFxWHdwSWZkbG1XMXV5K1FzSTRrUDcrS0sxYlU5Q0g4UnJ6Nzh5Q2NNWW9qOTgrREEyUEo2bjAzVGZ6cEpVRzR4dXIxdVQydWpLM0VIQUl4MG04NnNQc2l2N1pQbmR1M2N5Zi83OGxGbGg3Z3pWV1pvVUFpUlZuR3FFblZwZ2c0OTB1SGd5UUg3ZVEzclBKeXcrM2ZCalBTY09nYWdJeENLZEtpWDE1MFd5VnljT2dkWkd3T2ZwV2x1NTArY1FDRVBBa1M0TUZWZVhWUVFjNmJJS3IxTWVob0FqWFJncXJpNnJDRGpTWlJWZXB6d01BVWU2TUZSY1hWWVJjS1RMS3J4T2VSZ0NqblJocUxpNnJDTHdGMUFtWG9wVE1oQldBQUFBQUVsRlRrU3VRbUNDKQoKICAgIC0gICAKCiMjIyAqKkludGVycHJldGFjacOzbiBkZWwgUmVzdWx0YWRvKioKCi0gICBFbCByZXN1bHRhZG8gZGUgUj0xLjMzIGNvbiB1biBpbnRlcnZhbG8gZGUgY29uZmlhbnphIGFsIDk1JSAoQzk1JTogMC43NiAtIDIuMzIpIHB1ZWRlIGludGVycHJldGFyc2UgZGUgbGEgc2lndWllbnRlIG1hbmVyYToKCiAgICAjIyMgKioxLiBWYWxvciBkZWwgT2RkcyBSYXRpbyAoT1IpKioKCiAgICAtICAgT1I9MS4zMyAoT1I9XD4xKQoKICAgICAgICAtICAgSW5kaWNhIHF1ZSBsYXMgcGVyc29uYXMgY29uIGRpYWJldGVzIHRpZW5lbiAxLjMzIHZlY2VzIG3DoXMgcHJvYmFiaWxpZGFkZXMgZGUgdGVuZXIgaGlwZXJ0ZW5zacOzbiBlbiBjb21wYXJhY2nDs24gY29uIGxhcyBwZXJzb25hcyBzaW4gZGlhYmV0ZXMuCgogICAgICAgIC0gICBTaW4gZW1iYXJnbywgZXN0ZSB2YWxvciBkZWJlIGV2YWx1YXJzZSBqdW50byBjb24gZWwgaW50ZXJ2YWxvIGRlIGNvbmZpYW56YSBwYXJhIGRldGVybWluYXIgc2kgbGEgYXNvY2lhY2nDs24gZXMgZXN0YWTDrXN0aWNhbWVudGUgc2lnbmlmaWNhdGl2YS4KCiAgICAjIyMgKioyLiBJbnRlcnZhbG8gZGUgQ29uZmlhbnphIGFsIDk1JSAoSUM5NSUpKioKCiAgICAtICAgSUM5NSU9WzAuNzYsIDIuMzJdOgoKICAgICAgICAtICAgRXN0ZSBpbnRlcnZhbG8gc2lnbmlmaWNhIHF1ZSwgY29uIHVuIDk1JSBkZSBjb25maWFuemEsIGVsIHZlcmRhZGVybyBPZGRzIFJhdGlvIHBvZHLDrWEgZXN0YXIgZW50cmUgMC43NiB5IDIuMzIuCgogICAgICAgIC0gICBJbmNsdXllIGVsIHZhbG9ywqAqKjEqKiwgbG8gcXVlIGltcGxpY2EgcXVlwqAqKmxhIGFzb2NpYWNpw7NuIG5vIGVzIGVzdGFkw61zdGljYW1lbnRlIHNpZ25pZmljYXRpdmEqKihlcyBwb3NpYmxlIHF1ZSBubyBoYXlhIGRpZmVyZW5jaWEgcmVhbCBlbiBsYXMgcHJvYmFiaWxpZGFkZXMgZGUgaGlwZXJ0ZW5zacOzbiBlbnRyZSBwZXJzb25hcyBjb24geSBzaW4gZGlhYmV0ZXMpLgoKKipJbnRlcnByZXRhY2nDs24gUHLDoWN0aWNhKio6CgotICAgRXhpc3RlIHVuYSBwb3NpYmxlIGFzb2NpYWNpw7NuIHBvc2l0aXZhIGVudHJlIGRpYWJldGVzIGUgaGlwZXJ0ZW5zacOzbiAoT1I9MS4zMyksIHBlcm8gZXN0YSBhc29jaWFjacOzbiBubyBlcyBlc3RhZMOtc3RpY2FtZW50ZSBzaWduaWZpY2F0aXZhIHNlZ8O6biBlbCBJQzk1JT1bMC43NiwgMi4zMl0uCgotICAgTcOhcyBkYXRvcyBvIGVzdHVkaW9zIGFkaWNpb25hbGVzIHNlcsOtYW4gbmVjZXNhcmlvcyBwYXJhIGNvbmZpcm1hciBlc3RhIHJlbGFjacOzbi4KCmBgYHtyfQpucm93KGRhdG9zKQpgYGAK