Librerías
library(readxl)
library(dplyr)
library(ggplot2)
library(janitor)
library(qqplotr)
library(car)
library(sf)
library(digest)
library(viridisLite)
library(viridis)
library(rgeoda)
library(viridisLite)
library(viridis)
library(gridExtra)
library(dlookr)
library(spdep)
library(sp)
library(tidyverse)
library(sf)
library(corrplot)
file_path<- "/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/tourism_state_data.xlsx"
df <- read_excel("/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/tourism_state_data.xlsx")
mxstates <- sf::read_sf("/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/mx_shapefiles/states/mexlatlong.shp")

Preguntas

1) Brevemente, describir con sus propias palabras qué es un ESDA y cuál es su principal propósito en el proceso de analítica de datos.

ESDA son las siglas de Exploratory Spatial Data Analysis (Análisis Espacial Exploratorio de Datos, en español). Es una técnica de análisis de datos, que se utiliza principalemnte para explorar y analizar la estructura espacial de los datos, es decir, cómo se distribuyen los datos en el espacio. El propósito principal del ESDA es ayudar a identificar patrones espaciales y tendencias en los datos, lo que puede ser útil para entender mejor las relaciones espaciales entre las variables y para tomar decisiones informadas basadas en la ubicación geográfica.

2) Brevemente, describir con sus propias palabras el concepto de autocorrelación espacial así como 1-2 ejemplos relacionados con dicho concepto.

La autocorrelación espacial es la relación que existe entre los valores de una variable en ubicaciones geográficas cercanas. Es decir, si los valores similares (altos o bajos) de una variable tienden a agruparse en el espacio, habrá autocorrelación espacial positiva; si, por el contrario, valores altos están rodeados de bajos y viceversa, será negativa.

Ejemplos: - Contaminación del aire: Si en una ciudad las zonas industriales tienen altos niveles de contaminación y estas están agrupadas en una misma área, mientras que las zonas residenciales lejanas presentan valores bajos, existe autocorrelación espacial positiva.

  • Precios de viviendas: En un barrio con alta demanda, los precios tienden a ser similares y elevados (autocorrelación positiva), mientras que en áreas mixtas (residenciales-comerciales) pueden alternarse precios altos y bajos (posible autocorrelación negativa).

3) Con base en el archivo de datos asignado realizar selección de variables y elaborar ESDA que incluye:

a.Estadísticos Descripitvos (Global y Regional). Incluir elementos gráficos (histogramas,

gráfico de barras, etc.).

summary(df)
##     state                year         state_id     tourism_gdp    
##  Length:544         Min.   :2006   Min.   : 888   Min.   :  6240  
##  Class :character   1st Qu.:2010   1st Qu.:1047   1st Qu.: 22685  
##  Mode  :character   Median :2014   Median :1081   Median : 32482  
##                     Mean   :2014   Mean   :1219   Mean   : 56520  
##                     3rd Qu.:2018   3rd Qu.:1118   3rd Qu.: 59014  
##                     Max.   :2022   Max.   :2357   Max.   :472642  
##    crime_rate      college_education  unemployment       employment    
##  Min.   :  1.710   Min.   :0.08751   Min.   :0.01000   Min.   :0.8900  
##  1st Qu.:  8.107   1st Qu.:0.16703   1st Qu.:0.03000   1st Qu.:0.9500  
##  Median : 13.880   Median :0.20304   Median :0.04000   Median :0.9700  
##  Mean   : 22.163   Mean   :0.21106   Mean   :0.04251   Mean   :0.9639  
##  3rd Qu.: 26.314   3rd Qu.:0.25085   3rd Qu.:0.05000   3rd Qu.:0.9754  
##  Max.   :181.510   Max.   :0.43761   Max.   :0.10000   Max.   :0.9928  
##  business_activity   real_wage      pop_density      good_governance  
##  Min.   :-2.980    Min.   :239.3   Min.   :   7.74   Min.   :  0.000  
##  1st Qu.:-2.260    1st Qu.:282.5   1st Qu.:  39.56   1st Qu.:  0.180  
##  Median :-2.070    Median :306.2   Median :  61.77   Median :  0.500  
##  Mean   :-1.757    Mean   :314.9   Mean   : 299.46   Mean   :  2.362  
##  3rd Qu.:-1.768    3rd Qu.:335.4   3rd Qu.: 150.46   3rd Qu.:  1.350  
##  Max.   : 2.470    Max.   :481.7   Max.   :6211.45   Max.   :200.020  
##  ratio_public_investment exchange_rate        inpc        border_distance  
##  Min.   :0.000000        Min.   :10.85   Min.   : 62.69   Min.   :   8.83  
##  1st Qu.:0.000000        1st Qu.:12.87   1st Qu.: 74.93   1st Qu.: 613.26  
##  Median :0.000000        Median :14.51   Median : 87.19   Median : 751.64  
##  Mean   :0.005736        Mean   :15.91   Mean   : 89.08   Mean   : 704.92  
##  3rd Qu.:0.010000        3rd Qu.:19.47   3rd Qu.:103.02   3rd Qu.: 875.76  
##  Max.   :0.067644        Max.   :20.52   Max.   :126.48   Max.   :1252.66  
##  region...17         region...18   
##  Length:544         Min.   :1.000  
##  Class :character   1st Qu.:2.000  
##  Mode  :character   Median :3.000  
##                     Mean   :3.188  
##                     3rd Qu.:4.250  
##                     Max.   :5.000
# Estadísticos Descriptivos por Región
df%>%
  group_by(state) %>%
  summarise(across(
    .cols = c(tourism_gdp, crime_rate, college_education),
    .fns = list(media = mean, mediana = median, min = min, max = max),
    .names = "{.col}_{.fn}"
  ))
## # A tibble: 32 × 13
##    state   tourism_gdp_media tourism_gdp_mediana tourism_gdp_min tourism_gdp_max
##    <chr>               <dbl>               <dbl>           <dbl>           <dbl>
##  1 Aguasc…            14123.              14181.          11653.          17031.
##  2 Baja C…            54418.              53844.          45555.          69966.
##  3 Baja C…            28144.              28776.          22508.          33404.
##  4 Campec…            13426.              13444.          10338.          14840.
##  5 Chiapas            31402.              31250.          22730.          41871.
##  6 Chihua…            33688.              33296.          26120.          48140.
##  7 Ciudad…           392386.             390808.         262272.         472642.
##  8 Coahui…            28284.              27807.          22933.          31420.
##  9 Colima              8448.               8631.           6240.           9167.
## 10 Durango            11045.              11115.           8618.          13404.
## # ℹ 22 more rows
## # ℹ 8 more variables: crime_rate_media <dbl>, crime_rate_mediana <dbl>,
## #   crime_rate_min <dbl>, crime_rate_max <dbl>, college_education_media <dbl>,
## #   college_education_mediana <dbl>, college_education_min <dbl>,
## #   college_education_max <dbl>
# Histograma Global – PIB Turístico
  ggplot(df, aes(x = tourism_gdp)) +
    geom_histogram(fill = "skyblue", color = "black") +
    labs(title = "Distribución del PIB Turístico", x = "PIB Turístico", y = "Frecuencia")

  # Gráfico de Barras – PIB Promedio por Región
  
  ggplot(df, aes(x = state, y = tourism_gdp)) +
    stat_summary(fun = "mean", geom = "bar", fill = "pink", color = "black") +
    labs(title = "PIB Turístico Promedio por Región", x = "Región", y = "PIB Promedio") +
    theme(axis.text.x = element_text(angle = 45, hjust = 1))

  # Gráfico de Barrasstate# Gráfico de Barras – Tasa de Crimen por Región
  
  ggplot(df, aes(x = state, y = crime_rate)) +
    stat_summary(fun = "mean", geom = "bar", fill = "purple", color = "black") +
    labs(title = "Tasa de Crimen Promedio por Región", x = "Región", y = "Tasa de Crimen")

#### b.Estadísticos de Dispersión (Global y Regional). Incluir elementos gráficos (box plots, qq -plots, etc.).

# Estadísticos de dispersión globales
dispersion_global <- df%>%
  summarise(across(where(is.numeric), list(
    media = mean,
    mediana = median,
    sd = sd,
    var = var,
    iqr = IQR
  ), .names = "{.col}_{.fn}"))

print("Estadísticos de dispersión globales:")
## [1] "Estadísticos de dispersión globales:"
print(dispersion_global)
## # A tibble: 1 × 80
##   year_media year_mediana year_sd year_var year_iqr state_id_media
##        <dbl>        <dbl>   <dbl>    <dbl>    <dbl>          <dbl>
## 1       2014         2014    4.90     24.0        8          1219.
## # ℹ 74 more variables: state_id_mediana <dbl>, state_id_sd <dbl>,
## #   state_id_var <dbl>, state_id_iqr <dbl>, tourism_gdp_media <dbl>,
## #   tourism_gdp_mediana <dbl>, tourism_gdp_sd <dbl>, tourism_gdp_var <dbl>,
## #   tourism_gdp_iqr <dbl>, crime_rate_media <dbl>, crime_rate_mediana <dbl>,
## #   crime_rate_sd <dbl>, crime_rate_var <dbl>, crime_rate_iqr <dbl>,
## #   college_education_media <dbl>, college_education_mediana <dbl>,
## #   college_education_sd <dbl>, college_education_var <dbl>, …
#Estadísticos de dispersión por región

dispersion_regional <- df%>%
  group_by(state) %>%
  summarise(across(where(is.numeric), list(
    media = mean,
    mediana = median,
    sd = sd,
    var = var,
    iqr = IQR
  ), .names = "{.col}_{.fn}"))

print("Estadísticos de dispersión por región:")
## [1] "Estadísticos de dispersión por región:"
print(dispersion_regional)
## # A tibble: 32 × 81
##    state        year_media year_mediana year_sd year_var year_iqr state_id_media
##    <chr>             <dbl>        <dbl>   <dbl>    <dbl>    <dbl>          <dbl>
##  1 Aguascalien…       2014         2014    5.05     25.5        8           1057
##  2 Baja Califo…       2014         2014    5.05     25.5        8           2304
##  3 Baja Califo…       2014         2014    5.05     25.5        8           2327
##  4 Campeche           2014         2014    5.05     25.5        8           1086
##  5 Chiapas            2014         2014    5.05     25.5        8           1182
##  6 Chihuahua          2014         2014    5.05     25.5        8            888
##  7 Ciudad de M…       2014         2014    5.05     25.5        8           1114
##  8 Coahuila           2014         2014    5.05     25.5        8            933
##  9 Colima             2014         2014    5.05     25.5        8           1111
## 10 Durango            2014         2014    5.05     25.5        8           1004
## # ℹ 22 more rows
## # ℹ 74 more variables: state_id_mediana <dbl>, state_id_sd <dbl>,
## #   state_id_var <dbl>, state_id_iqr <dbl>, tourism_gdp_media <dbl>,
## #   tourism_gdp_mediana <dbl>, tourism_gdp_sd <dbl>, tourism_gdp_var <dbl>,
## #   tourism_gdp_iqr <dbl>, crime_rate_media <dbl>, crime_rate_mediana <dbl>,
## #   crime_rate_sd <dbl>, crime_rate_var <dbl>, crime_rate_iqr <dbl>,
## #   college_education_media <dbl>, college_education_mediana <dbl>, …
# Boxplots por región 

ggplot(df, aes(x = state, y = tourism_gdp)) +
  geom_boxplot(fill = "skyblue") +
  theme_minimal() +
  labs(title = "Boxplot del PIB turístico por región", y = "tourism_gdp")

# QQ-Plot para real_wage

qqPlot(df$real_wage,
       main = "QQ-Plot: real_wage",
       ylab = "Cuantiles reales",
       xlab = "Cuantiles teóricos")

## [1] 519 487
# QQ-plots por región

df%>%
  group_by(state) %>%
  do({
    region_data <- .
    qqPlot(region_data$real_wage, main = paste("QQ-Plot:", unique(region_data$region)))
    data.frame()
  })

## # A tibble: 0 × 1
## # Groups:   state [0]
## # ℹ 1 variable: state <chr>

c.Visualizar la distribución espacial de las variables seleccionadas usando mapas.

# 1. Cargar shapefile de México (previamente importado como objeto sf)
statesmx <- st_read("/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/mx_shapefiles/states/mexlatlong.shp")
## Reading layer `mexlatlong' from data source 
##   `/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/mx_shapefiles/states/mexlatlong.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 32 features and 19 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -118.4042 ymin: 14.55055 xmax: -86.73862 ymax: 32.71846
## Geodetic CRS:  WGS 84
names(df)[names(df) == "state_id"] <- "OBJECTID"

# Unir los datos con la geometría
data_sf <- merge(statesmx, df, by = "OBJECTID")

#GEOOOOO #fill cpn variable
# Mapa de una variable de interés
ggplot(data_sf) +
  geom_sf(aes(fill = tourism_gdp)) +
  scale_fill_viridis_c() +
  theme_minimal() +
  labs(title = "Distribución espacial de tourism_gdp", fill = "Valor")

d.Elaborar y visualizar 1–2 matrices de connectividad para estados / municipios de México.

library(sf)
#df <- st_as_sf(df)

library(sp)
turismo.tr <- as(data_sf, "Spatial")  # Conversión correcta
turismo_nb<-poly2nb(turismo.tr)

#Crear matriz de pesos espaciales (contigüidad Queen)
queen1 <- poly2nb(data_sf, queen = TRUE) ### queen approach 
queen2 <- poly2nb(data_sf, queen = FALSE) ### rook approach  

centroides<-coordinates(turismo.tr) 
mapa.linkW<-nb2listw(turismo_nb, style="W")  ###  
plot(turismo.tr,border="blue",axes=FALSE,las=1, main="Matriz de Conectividad - Turismo MX")
plot(turismo.tr,col="grey",border=grey(0.9),axes=T,add=T) 
plot(mapa.linkW,coords=centroides,pch=19,cex=0.1,col="red",add=T)

queen1 <- poly2nb(turismo.tr, queen = TRUE) ### queen approach 
queen2 <- poly2nb(turismo.tr, queen = FALSE) ### rook approach  

queenr <- nb2listw(queen1, style = "W", zero.policy = TRUE)
rook  <- nb2listw(queen2, style = "W", zero.policy = TRUE)

plot(turismo.tr,border="blue",axes=FALSE,las=1, main="Matriz Espacial de Conexión - Queen")
plot(turismo.tr,col="grey",border=grey(0.9),axes=T,add=T) 
plot(queenr,centroides, add=TRUE, col='blue')

plot(turismo.tr,border="blue",axes=FALSE,las=1, main="Matriz Espacial de Conexión - Rook")
plot(turismo.tr,col="grey",border=grey(0.9),axes=T,add=T) 
plot(rook,centroides, add=TRUE, col='dark green')

e.Detectar la presencia de autocorrelación espacial global para cada una de las variables seleccionadas.

# Hicimos una matriz de correlación para identificar las variables más relevantes en nuestro df.

numericas <- data_sf %>% 
  st_drop_geometry() %>% 
  select(where(is.numeric))

cor_matrix <- cor(numericas, use = "complete.obs")

corrplot(cor_matrix, method = "color", type = "upper", tl.col = "black")

La matriz de correlación revela relaciones significativas entre variables socioeconómicas clave. Destaca una correlación positiva entre el empleo, la educación universitaria y los salarios reales, lo que sugiere que las regiones con mayor nivel educativo tienden a tener mejores condiciones laborales y salariales. A su vez, el desempleo muestra correlaciones negativas con estas mismas variables, indicando que su aumento está asociado a contextos de menor desarrollo. También se observan asociaciones positivas entre la densidad poblacional, la actividad económica y el empleo, lo cual refuerza la idea de que las zonas más dinámicas y pobladas concentran mayores oportunidades laborales. En conjunto, estos patrones reflejan una estructura territorial donde el bienestar económico está fuertemente vinculado al acceso a la educación, el empleo y la calidad institucional.

# Instala los paquetes si no los tienes
#install.packages("spdep")
#install.packages("sf")

# Carga las librerías
library(sf)
library(spdep)

# 1. Crear matriz de vecinos espaciales
neighbors <- poly2nb(data_sf)  # contigüidad de tipo "queen"
weights_list <- nb2listw(neighbors, style = "W")  # matriz de pesos normalizada

# 2. Calcular el estadístico I de Moran para cada variable

# real_wage
moran_real_wage <- moran.test(data_sf$real_wage, listw = weights_list)
print(moran_real_wage)
## 
##  Moran I test under randomisation
## 
## data:  data_sf$real_wage  
## weights: weights_list    
## 
## Moran I statistic standard deviate = 36.399, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      2.259369e-01     -1.841621e-03      3.916019e-05
moran.plot(data_sf$real_wage, listw = weights_list, main = "Moran's Scatterplot: Real Wage")

# college_education
moran_college <- moran.test(data_sf$college_education, listw = weights_list)
print(moran_college)
## 
##  Moran I test under randomisation
## 
## data:  data_sf$college_education  
## weights: weights_list    
## 
## Moran I statistic standard deviate = 34.318, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      2.130708e-01     -1.841621e-03      3.921783e-05
moran.plot(data_sf$college_education, listw = weights_list, main = "Moran's Scatterplot: College Education")

# unemployment
moran_unemployment <- moran.test(data_sf$unemployment, listw = weights_list)
print(moran_unemployment)
## 
##  Moran I test under randomisation
## 
## data:  data_sf$unemployment  
## weights: weights_list    
## 
## Moran I statistic standard deviate = 8.5677, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic       Expectation          Variance 
##      5.179144e-02     -1.841621e-03      3.918674e-05
moran.plot(data_sf$unemployment, listw = weights_list, main = "Moran's Scatterplot: Unemployment")

Interpretación: Global MoranI: Es una medida de autocorrelación espacial, es decir, si los valores altos o bajos de una variable están agrupados en ciertas áreas o distribuidos aleatoriamente.

¿Qué indican estos resultados? Moran I Statistic: Un valor positivo significa que hay un patrón espacial, es decir, que las zonas con valores altos están cerca de otras zonas con valores altos y lo mismo con los valores bajos.

P-Values: Moran’s I mide autocorrelación espacial, por lo que el valor de una región se relaciona con los valores de las regiones vecinas.

  • Salarios reales (real_wage): La autocorrelación positiva significa que los lugares con salarios altos están rodeados de otros lugares con salarios altos, y los bajos con bajos.

  • Educación universitaria (college_education): Zonas con alto nivel educativo están cerca de otras con alto nivel educativo, y lo mismo para las de bajo nivel.

  • Desempleo (unemployment): Aunque el valor es menor, sigue indicando que las zonas con alto desempleo tienden a estar cerca unas de otras.

f.Detectar la presencia de autocorrelación espacial local para cada una de las variables seleccionadas y g. Identificar la posible presencia de clústers locales / regionales para cada una de las variables seleccionadas.

library(sf)
library(spdep)
library(ggplot2)
library(RColorBrewer)

# Variables a analizar
variables <- c("real_wage", "college_education", "unemployment")

# Crear una lista para guardar los gráficos
mapas <- list()

for (var in variables) {
  
  # Cálculo de Moran Local (LISA)
  lisa <- localmoran(data_sf[[var]], listw = weights_list)
  
  # Ver nombres de columnas para evitar errores
  print(colnames(lisa)) 
  
  p_colname <- if ("Pr(z > 0)" %in% colnames(lisa)) "Pr(z > 0)" else "Pr(z != E(Ii))"
  
  # Guardar valores en el dataframe
  data_sf[[paste0(var, "_lisa_I")]] <- lisa[, "Ii"]
  data_sf[[paste0(var, "_lisa_p")]] <- lisa[, p_colname]
  
  # Clasificación de clusters
  mean_var <- mean(data_sf[[var]], na.rm = TRUE)
  data_sf[[paste0(var, "_cluster")]] <- "No Significativo"
  
  data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 & 
                                      data_sf[[var]] > mean_var & 
                                      data_sf[[paste0(var, "_lisa_I")]] > 0] <- "High-High"
  
  data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 & 
                                      data_sf[[var]] < mean_var & 
                                      data_sf[[paste0(var, "_lisa_I")]] > 0] <- "Low-Low"
  
  data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 & 
                                      data_sf[[var]] > mean_var & 
                                      data_sf[[paste0(var, "_lisa_I")]] < 0] <- "High-Low"
  
  data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 & 
                                      data_sf[[var]] < mean_var & 
                                      data_sf[[paste0(var, "_lisa_I")]] < 0] <- "Low-High"
  
  # Convertir a factor
  data_sf[[paste0(var, "_cluster")]] <- as.factor(data_sf[[paste0(var, "_cluster")]])

  # Crear mapa
  mapa <- ggplot(data_sf) +
    geom_sf(aes(fill = !!sym(paste0(var, "_cluster"))), color = "white", size = 0.3) +  
    scale_fill_manual(
      values = c("No Significativo" = "lightgrey", 
                 "High-High" = "#D73027",   # Rojo oscuro elegante
                 "Low-Low" = "#4575B4",     # Azul sofisticado
                 "High-Low" = "#F46D43",    # Naranja tierra
                 "Low-High" = "#74ADD1"),   # Azul celeste suave
      labels = c("No Significativo", "Alto-Alto", "Bajo-Bajo", "Alto-Bajo", "Bajo-Alto")
    ) +
    labs(
      title = paste("Mapa de Clusters LISA -", var),
      fill = "Tipo de Clúster"
    ) +
    theme_minimal(base_size = 14) +
    theme(
      plot.title = element_text(face = "bold", hjust = 0.5, size = 16),
      legend.position = "right",
      legend.title = element_text(face = "bold"),
      legend.background = element_rect(fill = "white", color = NA)
    )
  
  # Guardar mapa en la lista
  mapas[[var]] <- mapa
}
## [1] "Ii"             "E.Ii"           "Var.Ii"         "Z.Ii"          
## [5] "Pr(z != E(Ii))"
## [1] "Ii"             "E.Ii"           "Var.Ii"         "Z.Ii"          
## [5] "Pr(z != E(Ii))"
## [1] "Ii"             "E.Ii"           "Var.Ii"         "Z.Ii"          
## [5] "Pr(z != E(Ii))"
# Mostrar los mapas
mapas
## $real_wage

## 
## $college_education

## 
## $unemployment

¿Cuáles son algunas de las características socioeconómicas y/o económicas de los estados / municipios que componen los clústers identificados?

🔴 High-High (Alto-Alto) Regiones con valores altos de la variable y rodeadas por regiones similares.

  • Estados con altos salarios reales, mayor educación universitaria o bajo desempleo.

  • Zonas con economías dinámicas y sectores industriales o de servicios bien desarrollados.

  • Alta concentración de talento y oportunidades laborales.

  • Infraestructura avanzada y acceso a servicios públicos de calidad.

🔵 Low-Low (Bajo-Bajo) - Regiones con valores bajos de la variable y rodeadas por regiones similares.

  • Áreas con bajos salarios reales, baja educación universitaria o alto desempleo.

  • Falta de inversión en infraestructura y educación.

  • Predominio de sectores económicos informales o de baja productividad.

  • Mayor vulnerabilidad a crisis económicas y dificultades para atraer inversión.

🟠 High-Low (Alto-Bajo) - Regiones con valores altos de la variable rodeadas por regiones con valores bajos.

  • Pueden ser centros urbanos o industriales rodeados por zonas rurales o menos desarrolladas.

  • Zonas con fuertes disparidades económicas entre municipios vecinos.

  • Atracción de migración interna por mejores oportunidades laborales y educativas.

  • Posibles efectos de gentrificación o desplazamiento de la población local.

🔵 Low-High (Bajo-Alto) - Regiones con valores bajos de la variable rodeadas por regiones con valores altos.

  • Municipios rezagados dentro de un entorno de alto desarrollo.

  • Puede indicar zonas que aún no han recibido inversiones o beneficios del crecimiento económico regional.

  • Oportunidad para estrategias de desarrollo dirigidas (infraestructura, educación, incentivos para inversión).

  • Posibles brechas en acceso a servicios públicos y conectividad con centros económicos cercanos.

4) Considerando el contexto de la situación problema, describir los principales 6-8 hallazgos encontrados a partir del ESDA.

  1. PIB turístico se concentra en destinos como Cancún, Los Cabos y CDMX.
  2. Salarios altos se agrupan en zonas metropolitanas e industriales.
  3. Más educación = menos desempleo, especialmente en ciudades grandes.
  4. Clústeres “High-High”: Turismo alto + desempleo bajo (beneficio económico local).
  5. Clústeres “Low-Low”: Zonas con bajos salarios, poca educación y alto desempleo (rezago).
  6. Desigualdades internas: Áreas ricas cerca de zonas pobres (“High-Low” y “Low-High”).
  7. Urbanización atrae oportunidades, pero deja atrás áreas rurales cercanas.
  8. Políticas focalizadas necesarias en zonas “Low-High” para reducir brechas.

El turismo y desarrollo económico son desiguales. Se requieren estrategias regionales para equilibrar crecimiento.

5) Citar referencias y/o otras fuentes de información consideradas para el desarrollo de la actividad.

•⁠ ⁠Siabato, W., & Guzmán-Manrique, J. (2019). La autocorrelación espacial y el desarrollo de la geografía cuantitativa. Cuadernos De Geografía Revista Colombiana De Geografía, 28(1), 1–22. https://doi.org/10.15446/rcdg.v28n1.76919

•⁠ ⁠Dall’erba, S. (2009). Exploratory Spatial data analysis. In Elsevier eBooks (pp. 683–690). https://doi.org/10.1016/b978-008044910-4.00433-8

LS0tCnRpdGxlOiAiQW7DoWxpc2lzIEV4cGxvcmF0b3JpbyBFc3BhY2lhbCAoRVNEQSkgLSBUdXJpc21vIGVuIE3DqXhpY28iCnN1YnRpdGxlOiAiQWN0aXZpZGFkIDEgfCBQbGFuZWFjacOzbiBFc3RyYXTDqWdpY2EgQmFzYWRhIGVuIEFuYWzDrXRpY2EgUHJlc2NyaXB0aXZhIgphdXRob3I6IAogIC0gSMOpY3RvciBHdWFkYWx1cGUgZGUgbGEgR2FyemEgVHJldmnDsW8gKEEwMTE3Nzk2MCkKICAtIE1hcmlhbmEgTGVhbCAoQTAxNTcwOTc3KQogIC0gRmVybmFuZGEgU2FuY2hleiBHdXRpZXJyZXogKEEwMTYxMzM2MCkKICAtIEplbmFybyBNYXJ0w61uZXogKEEwMTcyMTk1MSkKZGF0ZTogIkFicmlsIDIwMjUiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogaGFkZG9jawogICAgY3NzOiBzdHlsZXMuY3NzCi0tLQoKIVsgXShodHRwczovL2RyaXZlLmdvb2dsZS5jb20vdWM/aWQ9MXllUjNiRzRwUUIxY2tPUUJ3Qm5MVXM5dVQwT2ktb2RvKQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0gCmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkgCmBgYAoKCiMjIyMjIExpYnJlcsOtYXMKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KHFxcGxvdHIpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGRpZ2VzdCkKbGlicmFyeSh2aXJpZGlzTGl0ZSkKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KHJnZW9kYSkKbGlicmFyeSh2aXJpZGlzTGl0ZSkKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShkbG9va3IpCmxpYnJhcnkoc3BkZXApCmxpYnJhcnkoc3ApCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGNvcnJwbG90KQpgYGAKCmBgYHtyfQpmaWxlX3BhdGg8LSAiL1VzZXJzL21hcmlhbmFhbGVhbC9EZXNrdG9wL1RFQyAyMDI1L19QbGFuZWFjaW/MgW4gZXN0cmF0ZcyBZ2ljYSBiYXNhZGEgZW4gYW5hbGnMgXRpY2EgcHJlc2NyaXB0aXZhIC9NMS90b3VyaXNtX3N0YXRlX2RhdGEueGxzeCIKZGYgPC0gcmVhZF9leGNlbCgiL1VzZXJzL21hcmlhbmFhbGVhbC9EZXNrdG9wL1RFQyAyMDI1L19QbGFuZWFjaW/MgW4gZXN0cmF0ZcyBZ2ljYSBiYXNhZGEgZW4gYW5hbGnMgXRpY2EgcHJlc2NyaXB0aXZhIC9NMS90b3VyaXNtX3N0YXRlX2RhdGEueGxzeCIpCm14c3RhdGVzIDwtIHNmOjpyZWFkX3NmKCIvVXNlcnMvbWFyaWFuYWFsZWFsL0Rlc2t0b3AvVEVDIDIwMjUvX1BsYW5lYWNpb8yBbiBlc3RyYXRlzIFnaWNhIGJhc2FkYSBlbiBhbmFsacyBdGljYSBwcmVzY3JpcHRpdmEgL00xL214X3NoYXBlZmlsZXMvc3RhdGVzL21leGxhdGxvbmcuc2hwIikKYGBgCiMjIFByZWd1bnRhcyAKIyMjIDEpIEJyZXZlbWVudGUsIGRlc2NyaWJpciBjb24gc3VzIHByb3BpYXMgcGFsYWJyYXMgcXXDqSBlcyB1biBFU0RBIHkgY3XDoWwgZXMgc3UgcHJpbmNpcGFsIHByb3DDs3NpdG8gZW4gZWwgcHJvY2VzbyBkZSBhbmFsw610aWNhIGRlIGRhdG9zLgoKRVNEQSBzb24gbGFzIHNpZ2xhcyBkZSBFeHBsb3JhdG9yeSBTcGF0aWFsIERhdGEgQW5hbHlzaXMgKEFuw6FsaXNpcyBFc3BhY2lhbCBFeHBsb3JhdG9yaW8gZGUgRGF0b3MsIGVuIGVzcGHDsW9sKS4gRXMgdW5hIHTDqWNuaWNhIGRlIGFuw6FsaXNpcyBkZSBkYXRvcywgcXVlIHNlIHV0aWxpemEgcHJpbmNpcGFsZW1udGUgcGFyYSBleHBsb3JhciB5IGFuYWxpemFyIGxhIGVzdHJ1Y3R1cmEgZXNwYWNpYWwgZGUgbG9zIGRhdG9zLCBlcyBkZWNpciwgY8OzbW8gc2UgZGlzdHJpYnV5ZW4gbG9zIGRhdG9zIGVuIGVsIGVzcGFjaW8uIEVsIHByb3DDs3NpdG8gcHJpbmNpcGFsIGRlbCBFU0RBIGVzIGF5dWRhciBhIGlkZW50aWZpY2FyIHBhdHJvbmVzIGVzcGFjaWFsZXMgeSB0ZW5kZW5jaWFzIGVuIGxvcyBkYXRvcywgbG8gcXVlIHB1ZWRlIHNlciDDunRpbCBwYXJhIGVudGVuZGVyIG1lam9yIGxhcyByZWxhY2lvbmVzIGVzcGFjaWFsZXMgZW50cmUgbGFzIHZhcmlhYmxlcyB5IHBhcmEgdG9tYXIgZGVjaXNpb25lcyBpbmZvcm1hZGFzIGJhc2FkYXMgZW4gbGEgdWJpY2FjacOzbiBnZW9ncsOhZmljYS4KCiMjIyAyKSBCcmV2ZW1lbnRlLCBkZXNjcmliaXIgY29uIHN1cyBwcm9waWFzIHBhbGFicmFzIGVsIGNvbmNlcHRvIGRlIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgYXPDrSBjb21vIDEtMiBlamVtcGxvcyByZWxhY2lvbmFkb3MgY29uIGRpY2hvIGNvbmNlcHRvLgoKTGEgYXV0b2NvcnJlbGFjacOzbiBlc3BhY2lhbCBlcyBsYSByZWxhY2nDs24gcXVlIGV4aXN0ZSBlbnRyZSBsb3MgdmFsb3JlcyBkZSB1bmEgdmFyaWFibGUgZW4gdWJpY2FjaW9uZXMgZ2VvZ3LDoWZpY2FzIGNlcmNhbmFzLiBFcyBkZWNpciwgc2kgbG9zIHZhbG9yZXMgc2ltaWxhcmVzIChhbHRvcyBvIGJham9zKSBkZSB1bmEgdmFyaWFibGUgdGllbmRlbiBhIGFncnVwYXJzZSBlbiBlbCBlc3BhY2lvLCBoYWJyw6EgYXV0b2NvcnJlbGFjacOzbiBlc3BhY2lhbCBwb3NpdGl2YTsgc2ksIHBvciBlbCBjb250cmFyaW8sIHZhbG9yZXMgYWx0b3MgZXN0w6FuIHJvZGVhZG9zIGRlIGJham9zIHkgdmljZXZlcnNhLCBzZXLDoSBuZWdhdGl2YS4gCgpFamVtcGxvczogCi0gQ29udGFtaW5hY2nDs24gZGVsIGFpcmU6IFNpIGVuIHVuYSBjaXVkYWQgbGFzIHpvbmFzIGluZHVzdHJpYWxlcyB0aWVuZW4gYWx0b3Mgbml2ZWxlcyBkZSBjb250YW1pbmFjacOzbiB5IGVzdGFzIGVzdMOhbiBhZ3J1cGFkYXMgZW4gdW5hIG1pc21hIMOhcmVhLCBtaWVudHJhcyBxdWUgbGFzIHpvbmFzIHJlc2lkZW5jaWFsZXMgbGVqYW5hcyBwcmVzZW50YW4gdmFsb3JlcyBiYWpvcywgZXhpc3RlIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgcG9zaXRpdmEuCgoKLSBQcmVjaW9zIGRlIHZpdmllbmRhczogRW4gdW4gYmFycmlvIGNvbiBhbHRhIGRlbWFuZGEsIGxvcyBwcmVjaW9zIHRpZW5kZW4gYSBzZXIgc2ltaWxhcmVzIHkgZWxldmFkb3MgKGF1dG9jb3JyZWxhY2nDs24gcG9zaXRpdmEpLCBtaWVudHJhcyBxdWUgZW4gw6FyZWFzIG1peHRhcyAocmVzaWRlbmNpYWxlcy1jb21lcmNpYWxlcykgcHVlZGVuIGFsdGVybmFyc2UgcHJlY2lvcyBhbHRvcyB5IGJham9zIChwb3NpYmxlIGF1dG9jb3JyZWxhY2nDs24gbmVnYXRpdmEpLgoKCgojIyMgMykgQ29uIGJhc2UgZW4gZWwgYXJjaGl2byBkZSBkYXRvcyBhc2lnbmFkbyByZWFsaXphciBzZWxlY2Npw7NuIGRlIHZhcmlhYmxlcyB5IGVsYWJvcmFyIEVTREEgcXVlIGluY2x1eWU6CiMjIyMgYS5Fc3RhZMOtc3RpY29zIERlc2NyaXBpdHZvcyAoR2xvYmFsIHkgUmVnaW9uYWwpLiBJbmNsdWlyIGVsZW1lbnRvcyBncsOhZmljb3MgKGhpc3RvZ3JhbWFzLApncsOhZmljbyBkZSBiYXJyYXMsIGV0Yy4pLgpgYGB7cn0Kc3VtbWFyeShkZikKCiMgRXN0YWTDrXN0aWNvcyBEZXNjcmlwdGl2b3MgcG9yIFJlZ2nDs24KZGYlPiUKICBncm91cF9ieShzdGF0ZSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcygKICAgIC5jb2xzID0gYyh0b3VyaXNtX2dkcCwgY3JpbWVfcmF0ZSwgY29sbGVnZV9lZHVjYXRpb24pLAogICAgLmZucyA9IGxpc3QobWVkaWEgPSBtZWFuLCBtZWRpYW5hID0gbWVkaWFuLCBtaW4gPSBtaW4sIG1heCA9IG1heCksCiAgICAubmFtZXMgPSAiey5jb2x9X3suZm59IgogICkpCgojIEhpc3RvZ3JhbWEgR2xvYmFsIOKAkyBQSUIgVHVyw61zdGljbwogIGdncGxvdChkZiwgYWVzKHggPSB0b3VyaXNtX2dkcCkpICsKICAgIGdlb21faGlzdG9ncmFtKGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikgKwogICAgbGFicyh0aXRsZSA9ICJEaXN0cmlidWNpw7NuIGRlbCBQSUIgVHVyw61zdGljbyIsIHggPSAiUElCIFR1csOtc3RpY28iLCB5ID0gIkZyZWN1ZW5jaWEiKQogIAogIAogICMgR3LDoWZpY28gZGUgQmFycmFzIOKAkyBQSUIgUHJvbWVkaW8gcG9yIFJlZ2nDs24KICAKICBnZ3Bsb3QoZGYsIGFlcyh4ID0gc3RhdGUsIHkgPSB0b3VyaXNtX2dkcCkpICsKICAgIHN0YXRfc3VtbWFyeShmdW4gPSAibWVhbiIsIGdlb20gPSAiYmFyIiwgZmlsbCA9ICJwaW5rIiwgY29sb3IgPSAiYmxhY2siKSArCiAgICBsYWJzKHRpdGxlID0gIlBJQiBUdXLDrXN0aWNvIFByb21lZGlvIHBvciBSZWdpw7NuIiwgeCA9ICJSZWdpw7NuIiwgeSA9ICJQSUIgUHJvbWVkaW8iKSArCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQogIAogICMgR3LDoWZpY28gZGUgQmFycmFzc3RhdGUjIEdyw6FmaWNvIGRlIEJhcnJhcyDigJMgVGFzYSBkZSBDcmltZW4gcG9yIFJlZ2nDs24KICAKICBnZ3Bsb3QoZGYsIGFlcyh4ID0gc3RhdGUsIHkgPSBjcmltZV9yYXRlKSkgKwogICAgc3RhdF9zdW1tYXJ5KGZ1biA9ICJtZWFuIiwgZ2VvbSA9ICJiYXIiLCBmaWxsID0gInB1cnBsZSIsIGNvbG9yID0gImJsYWNrIikgKwogICAgbGFicyh0aXRsZSA9ICJUYXNhIGRlIENyaW1lbiBQcm9tZWRpbyBwb3IgUmVnacOzbiIsIHggPSAiUmVnacOzbiIsIHkgPSAiVGFzYSBkZSBDcmltZW4iKQoKYGBgCiMjIyMgYi5Fc3RhZMOtc3RpY29zIGRlIERpc3BlcnNpw7NuIChHbG9iYWwgeSBSZWdpb25hbCkuIEluY2x1aXIgZWxlbWVudG9zIGdyw6FmaWNvcyAoYm94IHBsb3RzLCBxcQotcGxvdHMsIGV0Yy4pLgoKYGBge3J9CiMgRXN0YWTDrXN0aWNvcyBkZSBkaXNwZXJzacOzbiBnbG9iYWxlcwpkaXNwZXJzaW9uX2dsb2JhbCA8LSBkZiU+JQogIHN1bW1hcmlzZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIGxpc3QoCiAgICBtZWRpYSA9IG1lYW4sCiAgICBtZWRpYW5hID0gbWVkaWFuLAogICAgc2QgPSBzZCwKICAgIHZhciA9IHZhciwKICAgIGlxciA9IElRUgogICksIC5uYW1lcyA9ICJ7LmNvbH1fey5mbn0iKSkKCnByaW50KCJFc3RhZMOtc3RpY29zIGRlIGRpc3BlcnNpw7NuIGdsb2JhbGVzOiIpCnByaW50KGRpc3BlcnNpb25fZ2xvYmFsKQoKI0VzdGFkw61zdGljb3MgZGUgZGlzcGVyc2nDs24gcG9yIHJlZ2nDs24KCmRpc3BlcnNpb25fcmVnaW9uYWwgPC0gZGYlPiUKICBncm91cF9ieShzdGF0ZSkgJT4lCiAgc3VtbWFyaXNlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgbGlzdCgKICAgIG1lZGlhID0gbWVhbiwKICAgIG1lZGlhbmEgPSBtZWRpYW4sCiAgICBzZCA9IHNkLAogICAgdmFyID0gdmFyLAogICAgaXFyID0gSVFSCiAgKSwgLm5hbWVzID0gInsuY29sfV97LmZufSIpKQoKcHJpbnQoIkVzdGFkw61zdGljb3MgZGUgZGlzcGVyc2nDs24gcG9yIHJlZ2nDs246IikKcHJpbnQoZGlzcGVyc2lvbl9yZWdpb25hbCkKCiMgQm94cGxvdHMgcG9yIHJlZ2nDs24gCgpnZ3Bsb3QoZGYsIGFlcyh4ID0gc3RhdGUsIHkgPSB0b3VyaXNtX2dkcCkpICsKICBnZW9tX2JveHBsb3QoZmlsbCA9ICJza3libHVlIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJCb3hwbG90IGRlbCBQSUIgdHVyw61zdGljbyBwb3IgcmVnacOzbiIsIHkgPSAidG91cmlzbV9nZHAiKQoKIyBRUS1QbG90IHBhcmEgcmVhbF93YWdlCgpxcVBsb3QoZGYkcmVhbF93YWdlLAogICAgICAgbWFpbiA9ICJRUS1QbG90OiByZWFsX3dhZ2UiLAogICAgICAgeWxhYiA9ICJDdWFudGlsZXMgcmVhbGVzIiwKICAgICAgIHhsYWIgPSAiQ3VhbnRpbGVzIHRlw7NyaWNvcyIpCgojIFFRLXBsb3RzIHBvciByZWdpw7NuCgpkZiU+JQogIGdyb3VwX2J5KHN0YXRlKSAlPiUKICBkbyh7CiAgICByZWdpb25fZGF0YSA8LSAuCiAgICBxcVBsb3QocmVnaW9uX2RhdGEkcmVhbF93YWdlLCBtYWluID0gcGFzdGUoIlFRLVBsb3Q6IiwgdW5pcXVlKHJlZ2lvbl9kYXRhJHJlZ2lvbikpKQogICAgZGF0YS5mcmFtZSgpCiAgfSkKYGBgCgojIyMjIGMuVmlzdWFsaXphciBsYSBkaXN0cmlidWNpw7NuIGVzcGFjaWFsIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcyB1c2FuZG8gbWFwYXMuCmBgYHtyfQojIDEuIENhcmdhciBzaGFwZWZpbGUgZGUgTcOpeGljbyAocHJldmlhbWVudGUgaW1wb3J0YWRvIGNvbW8gb2JqZXRvIHNmKQpzdGF0ZXNteCA8LSBzdF9yZWFkKCIvVXNlcnMvbWFyaWFuYWFsZWFsL0Rlc2t0b3AvVEVDIDIwMjUvX1BsYW5lYWNpb8yBbiBlc3RyYXRlzIFnaWNhIGJhc2FkYSBlbiBhbmFsacyBdGljYSBwcmVzY3JpcHRpdmEgL00xL214X3NoYXBlZmlsZXMvc3RhdGVzL21leGxhdGxvbmcuc2hwIikKCm5hbWVzKGRmKVtuYW1lcyhkZikgPT0gInN0YXRlX2lkIl0gPC0gIk9CSkVDVElEIgoKIyBVbmlyIGxvcyBkYXRvcyBjb24gbGEgZ2VvbWV0csOtYQpkYXRhX3NmIDwtIG1lcmdlKHN0YXRlc214LCBkZiwgYnkgPSAiT0JKRUNUSUQiKQoKI0dFT09PT08gI2ZpbGwgY3BuIHZhcmlhYmxlCiMgTWFwYSBkZSB1bmEgdmFyaWFibGUgZGUgaW50ZXLDqXMKZ2dwbG90KGRhdGFfc2YpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gdG91cmlzbV9nZHApKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1Y2nDs24gZXNwYWNpYWwgZGUgdG91cmlzbV9nZHAiLCBmaWxsID0gIlZhbG9yIikKYGBgCgoKCgoKIyMjIyBkLkVsYWJvcmFyIHkgdmlzdWFsaXphciAx4oCTMiBtYXRyaWNlcyBkZSBjb25uZWN0aXZpZGFkIHBhcmEgZXN0YWRvcyAvIG11bmljaXBpb3MgZGUgTcOpeGljby4KCmBgYHtyfQpsaWJyYXJ5KHNmKQojZGYgPC0gc3RfYXNfc2YoZGYpCgpsaWJyYXJ5KHNwKQp0dXJpc21vLnRyIDwtIGFzKGRhdGFfc2YsICJTcGF0aWFsIikgICMgQ29udmVyc2nDs24gY29ycmVjdGEKdHVyaXNtb19uYjwtcG9seTJuYih0dXJpc21vLnRyKQoKI0NyZWFyIG1hdHJpeiBkZSBwZXNvcyBlc3BhY2lhbGVzIChjb250aWfDvGlkYWQgUXVlZW4pCnF1ZWVuMSA8LSBwb2x5Mm5iKGRhdGFfc2YsIHF1ZWVuID0gVFJVRSkgIyMjIHF1ZWVuIGFwcHJvYWNoIApxdWVlbjIgPC0gcG9seTJuYihkYXRhX3NmLCBxdWVlbiA9IEZBTFNFKSAjIyMgcm9vayBhcHByb2FjaCAgCgpjZW50cm9pZGVzPC1jb29yZGluYXRlcyh0dXJpc21vLnRyKSAKbWFwYS5saW5rVzwtbmIybGlzdHcodHVyaXNtb19uYiwgc3R5bGU9IlciKSAgIyMjICAKcGxvdCh0dXJpc21vLnRyLGJvcmRlcj0iYmx1ZSIsYXhlcz1GQUxTRSxsYXM9MSwgbWFpbj0iTWF0cml6IGRlIENvbmVjdGl2aWRhZCAtIFR1cmlzbW8gTVgiKQpwbG90KHR1cmlzbW8udHIsY29sPSJncmV5Iixib3JkZXI9Z3JleSgwLjkpLGF4ZXM9VCxhZGQ9VCkgCnBsb3QobWFwYS5saW5rVyxjb29yZHM9Y2VudHJvaWRlcyxwY2g9MTksY2V4PTAuMSxjb2w9InJlZCIsYWRkPVQpCgpxdWVlbjEgPC0gcG9seTJuYih0dXJpc21vLnRyLCBxdWVlbiA9IFRSVUUpICMjIyBxdWVlbiBhcHByb2FjaCAKcXVlZW4yIDwtIHBvbHkybmIodHVyaXNtby50ciwgcXVlZW4gPSBGQUxTRSkgIyMjIHJvb2sgYXBwcm9hY2ggIAoKcXVlZW5yIDwtIG5iMmxpc3R3KHF1ZWVuMSwgc3R5bGUgPSAiVyIsIHplcm8ucG9saWN5ID0gVFJVRSkKcm9vayAgPC0gbmIybGlzdHcocXVlZW4yLCBzdHlsZSA9ICJXIiwgemVyby5wb2xpY3kgPSBUUlVFKQoKcGxvdCh0dXJpc21vLnRyLGJvcmRlcj0iYmx1ZSIsYXhlcz1GQUxTRSxsYXM9MSwgbWFpbj0iTWF0cml6IEVzcGFjaWFsIGRlIENvbmV4acOzbiAtIFF1ZWVuIikKcGxvdCh0dXJpc21vLnRyLGNvbD0iZ3JleSIsYm9yZGVyPWdyZXkoMC45KSxheGVzPVQsYWRkPVQpIApwbG90KHF1ZWVucixjZW50cm9pZGVzLCBhZGQ9VFJVRSwgY29sPSdibHVlJykKCnBsb3QodHVyaXNtby50cixib3JkZXI9ImJsdWUiLGF4ZXM9RkFMU0UsbGFzPTEsIG1haW49Ik1hdHJpeiBFc3BhY2lhbCBkZSBDb25leGnDs24gLSBSb29rIikKcGxvdCh0dXJpc21vLnRyLGNvbD0iZ3JleSIsYm9yZGVyPWdyZXkoMC45KSxheGVzPVQsYWRkPVQpIApwbG90KHJvb2ssY2VudHJvaWRlcywgYWRkPVRSVUUsIGNvbD0nZGFyayBncmVlbicpCmBgYAoKCgoKCgojIyMjIGUuRGV0ZWN0YXIgbGEgcHJlc2VuY2lhIGRlIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgZ2xvYmFsIHBhcmEgY2FkYSB1bmEgZGUgbGFzIHZhcmlhYmxlcyAgc2VsZWNjaW9uYWRhcy4KCmBgYHtyfQojIEhpY2ltb3MgdW5hIG1hdHJpeiBkZSBjb3JyZWxhY2nDs24gcGFyYSBpZGVudGlmaWNhciBsYXMgdmFyaWFibGVzIG3DoXMgcmVsZXZhbnRlcyBlbiBudWVzdHJvIGRmLgoKbnVtZXJpY2FzIDwtIGRhdGFfc2YgJT4lIAogIHN0X2Ryb3BfZ2VvbWV0cnkoKSAlPiUgCiAgc2VsZWN0KHdoZXJlKGlzLm51bWVyaWMpKQoKY29yX21hdHJpeCA8LSBjb3IobnVtZXJpY2FzLCB1c2UgPSAiY29tcGxldGUub2JzIikKCmNvcnJwbG90KGNvcl9tYXRyaXgsIG1ldGhvZCA9ICJjb2xvciIsIHR5cGUgPSAidXBwZXIiLCB0bC5jb2wgPSAiYmxhY2siKQpgYGAKCgoKTGEgbWF0cml6IGRlIGNvcnJlbGFjacOzbiByZXZlbGEgcmVsYWNpb25lcyBzaWduaWZpY2F0aXZhcyBlbnRyZSB2YXJpYWJsZXMgc29jaW9lY29uw7NtaWNhcyBjbGF2ZS4gRGVzdGFjYSB1bmEgY29ycmVsYWNpw7NuIHBvc2l0aXZhIGVudHJlIGVsIGVtcGxlbywgbGEgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIHkgbG9zIHNhbGFyaW9zIHJlYWxlcywgbG8gcXVlIHN1Z2llcmUgcXVlIGxhcyByZWdpb25lcyBjb24gbWF5b3Igbml2ZWwgZWR1Y2F0aXZvIHRpZW5kZW4gYSB0ZW5lciBtZWpvcmVzIGNvbmRpY2lvbmVzIGxhYm9yYWxlcyB5IHNhbGFyaWFsZXMuIEEgc3UgdmV6LCBlbCBkZXNlbXBsZW8gbXVlc3RyYSBjb3JyZWxhY2lvbmVzIG5lZ2F0aXZhcyBjb24gZXN0YXMgbWlzbWFzIHZhcmlhYmxlcywgaW5kaWNhbmRvIHF1ZSBzdSBhdW1lbnRvIGVzdMOhIGFzb2NpYWRvIGEgY29udGV4dG9zIGRlIG1lbm9yIGRlc2Fycm9sbG8uIFRhbWJpw6luIHNlIG9ic2VydmFuIGFzb2NpYWNpb25lcyBwb3NpdGl2YXMgZW50cmUgbGEgZGVuc2lkYWQgcG9ibGFjaW9uYWwsIGxhIGFjdGl2aWRhZCBlY29uw7NtaWNhIHkgZWwgZW1wbGVvLCBsbyBjdWFsIHJlZnVlcnphIGxhIGlkZWEgZGUgcXVlIGxhcyB6b25hcyBtw6FzIGRpbsOhbWljYXMgeSBwb2JsYWRhcyBjb25jZW50cmFuIG1heW9yZXMgb3BvcnR1bmlkYWRlcyBsYWJvcmFsZXMuIEVuIGNvbmp1bnRvLCBlc3RvcyBwYXRyb25lcyByZWZsZWphbiB1bmEgZXN0cnVjdHVyYSB0ZXJyaXRvcmlhbCBkb25kZSBlbCBiaWVuZXN0YXIgZWNvbsOzbWljbyBlc3TDoSBmdWVydGVtZW50ZSB2aW5jdWxhZG8gYWwgYWNjZXNvIGEgbGEgZWR1Y2FjacOzbiwgZWwgZW1wbGVvIHkgbGEgY2FsaWRhZCBpbnN0aXR1Y2lvbmFsLgoKYGBge3J9CiMgSW5zdGFsYSBsb3MgcGFxdWV0ZXMgc2kgbm8gbG9zIHRpZW5lcwojaW5zdGFsbC5wYWNrYWdlcygic3BkZXAiKQojaW5zdGFsbC5wYWNrYWdlcygic2YiKQoKIyBDYXJnYSBsYXMgbGlicmVyw61hcwpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHNwZGVwKQoKIyAxLiBDcmVhciBtYXRyaXogZGUgdmVjaW5vcyBlc3BhY2lhbGVzCm5laWdoYm9ycyA8LSBwb2x5Mm5iKGRhdGFfc2YpICAjIGNvbnRpZ8O8aWRhZCBkZSB0aXBvICJxdWVlbiIKd2VpZ2h0c19saXN0IDwtIG5iMmxpc3R3KG5laWdoYm9ycywgc3R5bGUgPSAiVyIpICAjIG1hdHJpeiBkZSBwZXNvcyBub3JtYWxpemFkYQoKIyAyLiBDYWxjdWxhciBlbCBlc3RhZMOtc3RpY28gSSBkZSBNb3JhbiBwYXJhIGNhZGEgdmFyaWFibGUKCiMgcmVhbF93YWdlCm1vcmFuX3JlYWxfd2FnZSA8LSBtb3Jhbi50ZXN0KGRhdGFfc2YkcmVhbF93YWdlLCBsaXN0dyA9IHdlaWdodHNfbGlzdCkKcHJpbnQobW9yYW5fcmVhbF93YWdlKQptb3Jhbi5wbG90KGRhdGFfc2YkcmVhbF93YWdlLCBsaXN0dyA9IHdlaWdodHNfbGlzdCwgbWFpbiA9ICJNb3JhbidzIFNjYXR0ZXJwbG90OiBSZWFsIFdhZ2UiKQoKIyBjb2xsZWdlX2VkdWNhdGlvbgptb3Jhbl9jb2xsZWdlIDwtIG1vcmFuLnRlc3QoZGF0YV9zZiRjb2xsZWdlX2VkdWNhdGlvbiwgbGlzdHcgPSB3ZWlnaHRzX2xpc3QpCnByaW50KG1vcmFuX2NvbGxlZ2UpCm1vcmFuLnBsb3QoZGF0YV9zZiRjb2xsZWdlX2VkdWNhdGlvbiwgbGlzdHcgPSB3ZWlnaHRzX2xpc3QsIG1haW4gPSAiTW9yYW4ncyBTY2F0dGVycGxvdDogQ29sbGVnZSBFZHVjYXRpb24iKQoKIyB1bmVtcGxveW1lbnQKbW9yYW5fdW5lbXBsb3ltZW50IDwtIG1vcmFuLnRlc3QoZGF0YV9zZiR1bmVtcGxveW1lbnQsIGxpc3R3ID0gd2VpZ2h0c19saXN0KQpwcmludChtb3Jhbl91bmVtcGxveW1lbnQpCm1vcmFuLnBsb3QoZGF0YV9zZiR1bmVtcGxveW1lbnQsIGxpc3R3ID0gd2VpZ2h0c19saXN0LCBtYWluID0gIk1vcmFuJ3MgU2NhdHRlcnBsb3Q6IFVuZW1wbG95bWVudCIpCgpgYGAKCkludGVycHJldGFjacOzbjogCkdsb2JhbCBNb3Jhbkk6IEVzIHVuYSBtZWRpZGEgZGUgYXV0b2NvcnJlbGFjacOzbiBlc3BhY2lhbCwgZXMgZGVjaXIsIHNpIGxvcyB2YWxvcmVzIGFsdG9zIG8gYmFqb3MgZGUgdW5hIHZhcmlhYmxlIGVzdMOhbiBhZ3J1cGFkb3MgZW4gY2llcnRhcyDDoXJlYXMgbyBkaXN0cmlidWlkb3MgYWxlYXRvcmlhbWVudGUuCgrCv1F1w6kgaW5kaWNhbiBlc3RvcyByZXN1bHRhZG9zPwpNb3JhbiBJIFN0YXRpc3RpYzogVW4gdmFsb3IgcG9zaXRpdm8gc2lnbmlmaWNhIHF1ZSBoYXkgdW4gcGF0csOzbiBlc3BhY2lhbCwgZXMgZGVjaXIsIHF1ZSBsYXMgem9uYXMgY29uIHZhbG9yZXMgYWx0b3MgZXN0w6FuIGNlcmNhIGRlIG90cmFzIHpvbmFzIGNvbiB2YWxvcmVzIGFsdG9zIHkgbG8gbWlzbW8gY29uIGxvcyB2YWxvcmVzIGJham9zLgoKUC1WYWx1ZXM6Ck1vcmFuJ3MgSSBtaWRlIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwsIHBvciBsbyBxdWUgZWwgdmFsb3IgZGUgdW5hIHJlZ2nDs24gc2UgcmVsYWNpb25hIGNvbiBsb3MgdmFsb3JlcyBkZSBsYXMgcmVnaW9uZXMgdmVjaW5hcy4KCi0gU2FsYXJpb3MgcmVhbGVzIChyZWFsX3dhZ2UpOiBMYSBhdXRvY29ycmVsYWNpw7NuIHBvc2l0aXZhIHNpZ25pZmljYSBxdWUgbG9zIGx1Z2FyZXMgY29uIHNhbGFyaW9zIGFsdG9zIGVzdMOhbiByb2RlYWRvcyBkZSBvdHJvcyBsdWdhcmVzIGNvbiBzYWxhcmlvcyBhbHRvcywgeSBsb3MgYmFqb3MgY29uIGJham9zLgoKLSBFZHVjYWNpw7NuIHVuaXZlcnNpdGFyaWEgKGNvbGxlZ2VfZWR1Y2F0aW9uKTogWm9uYXMgY29uIGFsdG8gbml2ZWwgZWR1Y2F0aXZvIGVzdMOhbiBjZXJjYSBkZSBvdHJhcyBjb24gYWx0byBuaXZlbCBlZHVjYXRpdm8sIHkgbG8gbWlzbW8gcGFyYSBsYXMgZGUgYmFqbyBuaXZlbC4KCi0gRGVzZW1wbGVvICh1bmVtcGxveW1lbnQpOiBBdW5xdWUgZWwgdmFsb3IgZXMgbWVub3IsIHNpZ3VlIGluZGljYW5kbyBxdWUgbGFzIHpvbmFzIGNvbiBhbHRvIGRlc2VtcGxlbyB0aWVuZGVuIGEgZXN0YXIgY2VyY2EgdW5hcyBkZSBvdHJhcy4KCiMjIyMgZi5EZXRlY3RhciBsYSBwcmVzZW5jaWEgZGUgYXV0b2NvcnJlbGFjacOzbiBlc3BhY2lhbCBsb2NhbCBwYXJhIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcyB5IGcuIElkZW50aWZpY2FyIGxhIHBvc2libGUgcHJlc2VuY2lhIGRlIGNsw7pzdGVycyBsb2NhbGVzIC8gcmVnaW9uYWxlcyBwYXJhIGNhZGEgdW5hIGRlIGxhcyB2YXJpYWJsZXMgc2VsZWNjaW9uYWRhcy4KCgpgYGB7cn0KbGlicmFyeShzZikKbGlicmFyeShzcGRlcCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKCiMgVmFyaWFibGVzIGEgYW5hbGl6YXIKdmFyaWFibGVzIDwtIGMoInJlYWxfd2FnZSIsICJjb2xsZWdlX2VkdWNhdGlvbiIsICJ1bmVtcGxveW1lbnQiKQoKIyBDcmVhciB1bmEgbGlzdGEgcGFyYSBndWFyZGFyIGxvcyBncsOhZmljb3MKbWFwYXMgPC0gbGlzdCgpCgpmb3IgKHZhciBpbiB2YXJpYWJsZXMpIHsKICAKICAjIEPDoWxjdWxvIGRlIE1vcmFuIExvY2FsIChMSVNBKQogIGxpc2EgPC0gbG9jYWxtb3JhbihkYXRhX3NmW1t2YXJdXSwgbGlzdHcgPSB3ZWlnaHRzX2xpc3QpCiAgCiAgIyBWZXIgbm9tYnJlcyBkZSBjb2x1bW5hcyBwYXJhIGV2aXRhciBlcnJvcmVzCiAgcHJpbnQoY29sbmFtZXMobGlzYSkpIAogIAogIHBfY29sbmFtZSA8LSBpZiAoIlByKHogPiAwKSIgJWluJSBjb2xuYW1lcyhsaXNhKSkgIlByKHogPiAwKSIgZWxzZSAiUHIoeiAhPSBFKElpKSkiCiAgCiAgIyBHdWFyZGFyIHZhbG9yZXMgZW4gZWwgZGF0YWZyYW1lCiAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9saXNhX0kiKV1dIDwtIGxpc2FbLCAiSWkiXQogIGRhdGFfc2ZbW3Bhc3RlMCh2YXIsICJfbGlzYV9wIildXSA8LSBsaXNhWywgcF9jb2xuYW1lXQogIAogICMgQ2xhc2lmaWNhY2nDs24gZGUgY2x1c3RlcnMKICBtZWFuX3ZhciA8LSBtZWFuKGRhdGFfc2ZbW3Zhcl1dLCBuYS5ybSA9IFRSVUUpCiAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9jbHVzdGVyIildXSA8LSAiTm8gU2lnbmlmaWNhdGl2byIKICAKICBkYXRhX3NmW1twYXN0ZTAodmFyLCAiX2NsdXN0ZXIiKV1dW2RhdGFfc2ZbW3Bhc3RlMCh2YXIsICJfbGlzYV9wIildXSA8IDAuMDUgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX3NmW1t2YXJdXSA+IG1lYW5fdmFyICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9saXNhX0kiKV1dID4gMF0gPC0gIkhpZ2gtSGlnaCIKICAKICBkYXRhX3NmW1twYXN0ZTAodmFyLCAiX2NsdXN0ZXIiKV1dW2RhdGFfc2ZbW3Bhc3RlMCh2YXIsICJfbGlzYV9wIildXSA8IDAuMDUgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX3NmW1t2YXJdXSA8IG1lYW5fdmFyICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9saXNhX0kiKV1dID4gMF0gPC0gIkxvdy1Mb3ciCiAgCiAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9jbHVzdGVyIildXVtkYXRhX3NmW1twYXN0ZTAodmFyLCAiX2xpc2FfcCIpXV0gPCAwLjA1ICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9zZltbdmFyXV0gPiBtZWFuX3ZhciAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFfc2ZbW3Bhc3RlMCh2YXIsICJfbGlzYV9JIildXSA8IDBdIDwtICJIaWdoLUxvdyIKICAKICBkYXRhX3NmW1twYXN0ZTAodmFyLCAiX2NsdXN0ZXIiKV1dW2RhdGFfc2ZbW3Bhc3RlMCh2YXIsICJfbGlzYV9wIildXSA8IDAuMDUgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhX3NmW1t2YXJdXSA8IG1lYW5fdmFyICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9saXNhX0kiKV1dIDwgMF0gPC0gIkxvdy1IaWdoIgogIAogICMgQ29udmVydGlyIGEgZmFjdG9yCiAgZGF0YV9zZltbcGFzdGUwKHZhciwgIl9jbHVzdGVyIildXSA8LSBhcy5mYWN0b3IoZGF0YV9zZltbcGFzdGUwKHZhciwgIl9jbHVzdGVyIildXSkKCiAgIyBDcmVhciBtYXBhCiAgbWFwYSA8LSBnZ3Bsb3QoZGF0YV9zZikgKwogICAgZ2VvbV9zZihhZXMoZmlsbCA9ICEhc3ltKHBhc3RlMCh2YXIsICJfY2x1c3RlciIpKSksIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDAuMykgKyAgCiAgICBzY2FsZV9maWxsX21hbnVhbCgKICAgICAgdmFsdWVzID0gYygiTm8gU2lnbmlmaWNhdGl2byIgPSAibGlnaHRncmV5IiwgCiAgICAgICAgICAgICAgICAgIkhpZ2gtSGlnaCIgPSAiI0Q3MzAyNyIsICAgIyBSb2pvIG9zY3VybyBlbGVnYW50ZQogICAgICAgICAgICAgICAgICJMb3ctTG93IiA9ICIjNDU3NUI0IiwgICAgICMgQXp1bCBzb2Zpc3RpY2FkbwogICAgICAgICAgICAgICAgICJIaWdoLUxvdyIgPSAiI0Y0NkQ0MyIsICAgICMgTmFyYW5qYSB0aWVycmEKICAgICAgICAgICAgICAgICAiTG93LUhpZ2giID0gIiM3NEFERDEiKSwgICAjIEF6dWwgY2VsZXN0ZSBzdWF2ZQogICAgICBsYWJlbHMgPSBjKCJObyBTaWduaWZpY2F0aXZvIiwgIkFsdG8tQWx0byIsICJCYWpvLUJham8iLCAiQWx0by1CYWpvIiwgIkJham8tQWx0byIpCiAgICApICsKICAgIGxhYnMoCiAgICAgIHRpdGxlID0gcGFzdGUoIk1hcGEgZGUgQ2x1c3RlcnMgTElTQSAtIiwgdmFyKSwKICAgICAgZmlsbCA9ICJUaXBvIGRlIENsw7pzdGVyIgogICAgKSArCiAgICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgICB0aGVtZSgKICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDE2KSwKICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIpLAogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIiwgY29sb3IgPSBOQSkKICAgICkKICAKICAjIEd1YXJkYXIgbWFwYSBlbiBsYSBsaXN0YQogIG1hcGFzW1t2YXJdXSA8LSBtYXBhCn0KCiMgTW9zdHJhciBsb3MgbWFwYXMKbWFwYXMKCmBgYAoKCgoKIyMjIyDCv0N1w6FsZXMgc29uIGFsZ3VuYXMgZGUgbGFzIGNhcmFjdGVyw61zdGljYXMgc29jaW9lY29uw7NtaWNhcyB5L28gZWNvbsOzbWljYXMgZGUgbG9zIGVzdGFkb3MgLyBtdW5pY2lwaW9zIHF1ZSBjb21wb25lbiBsb3MgY2zDunN0ZXJzIGlkZW50aWZpY2Fkb3M/Cgrwn5S0IEhpZ2gtSGlnaCAoQWx0by1BbHRvKQpSZWdpb25lcyBjb24gdmFsb3JlcyBhbHRvcyBkZSBsYSB2YXJpYWJsZSB5IHJvZGVhZGFzIHBvciByZWdpb25lcyBzaW1pbGFyZXMuCgotIEVzdGFkb3MgY29uIGFsdG9zIHNhbGFyaW9zIHJlYWxlcywgbWF5b3IgZWR1Y2FjacOzbiB1bml2ZXJzaXRhcmlhIG8gYmFqbyBkZXNlbXBsZW8uCgotIFpvbmFzIGNvbiBlY29ub23DrWFzIGRpbsOhbWljYXMgeSBzZWN0b3JlcyBpbmR1c3RyaWFsZXMgbyBkZSBzZXJ2aWNpb3MgYmllbiBkZXNhcnJvbGxhZG9zLgoKLSBBbHRhIGNvbmNlbnRyYWNpw7NuIGRlIHRhbGVudG8geSBvcG9ydHVuaWRhZGVzIGxhYm9yYWxlcy4KCi0gSW5mcmFlc3RydWN0dXJhIGF2YW56YWRhIHkgYWNjZXNvIGEgc2VydmljaW9zIHDDumJsaWNvcyBkZSBjYWxpZGFkLgoK8J+UtSBMb3ctTG93IChCYWpvLUJham8pCi0gUmVnaW9uZXMgY29uIHZhbG9yZXMgYmFqb3MgZGUgbGEgdmFyaWFibGUgeSByb2RlYWRhcyBwb3IgcmVnaW9uZXMgc2ltaWxhcmVzLgoKLSDDgXJlYXMgY29uIGJham9zIHNhbGFyaW9zIHJlYWxlcywgYmFqYSBlZHVjYWNpw7NuIHVuaXZlcnNpdGFyaWEgbyBhbHRvIGRlc2VtcGxlby4KCi0gRmFsdGEgZGUgaW52ZXJzacOzbiBlbiBpbmZyYWVzdHJ1Y3R1cmEgeSBlZHVjYWNpw7NuLgoKLSBQcmVkb21pbmlvIGRlIHNlY3RvcmVzIGVjb27Ds21pY29zIGluZm9ybWFsZXMgbyBkZSBiYWphIHByb2R1Y3RpdmlkYWQuCgotIE1heW9yIHZ1bG5lcmFiaWxpZGFkIGEgY3Jpc2lzIGVjb27Ds21pY2FzIHkgZGlmaWN1bHRhZGVzIHBhcmEgYXRyYWVyIGludmVyc2nDs24uCgrwn5+gIEhpZ2gtTG93IChBbHRvLUJham8pCi0gUmVnaW9uZXMgY29uIHZhbG9yZXMgYWx0b3MgZGUgbGEgdmFyaWFibGUgcm9kZWFkYXMgcG9yIHJlZ2lvbmVzIGNvbiB2YWxvcmVzIGJham9zLgoKLSBQdWVkZW4gc2VyIGNlbnRyb3MgdXJiYW5vcyBvIGluZHVzdHJpYWxlcyByb2RlYWRvcyBwb3Igem9uYXMgcnVyYWxlcyBvIG1lbm9zIGRlc2Fycm9sbGFkYXMuCgotIFpvbmFzIGNvbiBmdWVydGVzIGRpc3BhcmlkYWRlcyBlY29uw7NtaWNhcyBlbnRyZSBtdW5pY2lwaW9zIHZlY2lub3MuCgotIEF0cmFjY2nDs24gZGUgbWlncmFjacOzbiBpbnRlcm5hIHBvciBtZWpvcmVzIG9wb3J0dW5pZGFkZXMgbGFib3JhbGVzIHkgZWR1Y2F0aXZhcy4KCi0gUG9zaWJsZXMgZWZlY3RvcyBkZSBnZW50cmlmaWNhY2nDs24gbyBkZXNwbGF6YW1pZW50byBkZSBsYSBwb2JsYWNpw7NuIGxvY2FsLgoK8J+UtSBMb3ctSGlnaCAoQmFqby1BbHRvKQotIFJlZ2lvbmVzIGNvbiB2YWxvcmVzIGJham9zIGRlIGxhIHZhcmlhYmxlIHJvZGVhZGFzIHBvciByZWdpb25lcyBjb24gdmFsb3JlcyBhbHRvcy4KCi0gTXVuaWNpcGlvcyByZXphZ2Fkb3MgZGVudHJvIGRlIHVuIGVudG9ybm8gZGUgYWx0byBkZXNhcnJvbGxvLgoKLSBQdWVkZSBpbmRpY2FyIHpvbmFzIHF1ZSBhw7puIG5vIGhhbiByZWNpYmlkbyBpbnZlcnNpb25lcyBvIGJlbmVmaWNpb3MgZGVsIGNyZWNpbWllbnRvIGVjb27Ds21pY28gcmVnaW9uYWwuCgotIE9wb3J0dW5pZGFkIHBhcmEgZXN0cmF0ZWdpYXMgZGUgZGVzYXJyb2xsbyBkaXJpZ2lkYXMgKGluZnJhZXN0cnVjdHVyYSwgZWR1Y2FjacOzbiwgaW5jZW50aXZvcyBwYXJhIGludmVyc2nDs24pLgoKLSBQb3NpYmxlcyBicmVjaGFzIGVuIGFjY2VzbyBhIHNlcnZpY2lvcyBww7pibGljb3MgeSBjb25lY3RpdmlkYWQgY29uIGNlbnRyb3MgZWNvbsOzbWljb3MgY2VyY2Fub3MuCgoKCiMjIyA0KSBDb25zaWRlcmFuZG8gZWwgY29udGV4dG8gZGUgbGEgc2l0dWFjacOzbiBwcm9ibGVtYSwgZGVzY3JpYmlyIGxvcyBwcmluY2lwYWxlcyA2LTggaGFsbGF6Z29zIGVuY29udHJhZG9zIGEgcGFydGlyIGRlbCBFU0RBLgoKMS4gKipQSUIgdHVyw61zdGljbyoqIHNlIGNvbmNlbnRyYSBlbiBkZXN0aW5vcyBjb21vIENhbmPDum4sIExvcyBDYWJvcyB5IENETVguICAKMi4gKipTYWxhcmlvcyBhbHRvcyoqIHNlIGFncnVwYW4gZW4gem9uYXMgbWV0cm9wb2xpdGFuYXMgZSBpbmR1c3RyaWFsZXMuICAKMy4gKipNw6FzIGVkdWNhY2nDs24gPSBtZW5vcyBkZXNlbXBsZW8qKiwgZXNwZWNpYWxtZW50ZSBlbiBjaXVkYWRlcyBncmFuZGVzLiAgCjQuICoqQ2zDunN0ZXJlcyAiSGlnaC1IaWdoIioqOiBUdXJpc21vIGFsdG8gKyBkZXNlbXBsZW8gYmFqbyAoYmVuZWZpY2lvIGVjb27Ds21pY28gbG9jYWwpLiAgCjUuICoqQ2zDunN0ZXJlcyAiTG93LUxvdyIqKjogWm9uYXMgY29uIGJham9zIHNhbGFyaW9zLCBwb2NhIGVkdWNhY2nDs24geSBhbHRvIGRlc2VtcGxlbyAocmV6YWdvKS4gIAo2LiAqKkRlc2lndWFsZGFkZXMgaW50ZXJuYXMqKjogw4FyZWFzIHJpY2FzIGNlcmNhIGRlIHpvbmFzIHBvYnJlcyAoIkhpZ2gtTG93IiB5ICJMb3ctSGlnaCIpLiAgCjcuICoqVXJiYW5pemFjacOzbiBhdHJhZSBvcG9ydHVuaWRhZGVzKiosIHBlcm8gZGVqYSBhdHLDoXMgw6FyZWFzIHJ1cmFsZXMgY2VyY2FuYXMuICAKOC4gKipQb2zDrXRpY2FzIGZvY2FsaXphZGFzKiogbmVjZXNhcmlhcyBlbiB6b25hcyAiTG93LUhpZ2giIHBhcmEgcmVkdWNpciBicmVjaGFzLiAgCgpFbCB0dXJpc21vIHkgZGVzYXJyb2xsbyBlY29uw7NtaWNvIHNvbiBkZXNpZ3VhbGVzLiBTZSByZXF1aWVyZW4gZXN0cmF0ZWdpYXMgcmVnaW9uYWxlcyBwYXJhIGVxdWlsaWJyYXIgY3JlY2ltaWVudG8uCgojIyMgNSkgQ2l0YXIgcmVmZXJlbmNpYXMgeS9vIG90cmFzIGZ1ZW50ZXMgZGUgaW5mb3JtYWNpw7NuIGNvbnNpZGVyYWRhcyBwYXJhIGVsIGRlc2Fycm9sbG8gZGUgbGEgYWN0aXZpZGFkLgoK4oCi4oGgICDigaBTaWFiYXRvLCBXLiwgJiBHdXptw6FuLU1hbnJpcXVlLCBKLiAoMjAxOSkuIExhIGF1dG9jb3JyZWxhY2nDs24gZXNwYWNpYWwgeSBlbCBkZXNhcnJvbGxvIGRlIGxhIGdlb2dyYWbDrWEgY3VhbnRpdGF0aXZhLiBDdWFkZXJub3MgRGUgR2VvZ3JhZsOtYSBSZXZpc3RhIENvbG9tYmlhbmEgRGUgR2VvZ3JhZsOtYSwgMjgoMSksIDHigJMyMi4gaHR0cHM6Ly9kb2kub3JnLzEwLjE1NDQ2L3JjZGcudjI4bjEuNzY5MTkKCgrigKLigaAgIOKBoERhbGzigJllcmJhLCBTLiAoMjAwOSkuIEV4cGxvcmF0b3J5IFNwYXRpYWwgZGF0YSBhbmFseXNpcy4gSW4gRWxzZXZpZXIgZUJvb2tzIChwcC4gNjgz4oCTNjkwKS4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwMTYvYjk3OC0wMDgwNDQ5MTAtNC4wMDQzMy04Cg==