Social Analytics and Strategic Intelligence

Session 1: Explore and Query Let’s bring the data in long format (ByYear_LongStats):

rm(list = ls())
denguelink1='https://github.com/SocialAnalytics-StrategicIntelligence/TableOperations/raw/main/dataFiles/ByYear_LongStats.pkl'

library(reticulate)
use_python("C:/Users/jpnav/anaconda3")
py_install("pandas") # install pandas for R environment
+ "C:/Users/jpnav/anaconda3/condabin/conda.bat" "install" "--yes" "--prefix" "C:/Users/jpnav/anaconda3" "-c" "conda-forge" "pandas"
Collecting package metadata (current_repodata.json): ...working... done
Solving environment: ...working... done


==> WARNING: A newer version of conda exists. <==
  current version: 23.7.4
  latest version: 24.3.0

Please update conda by running

    $ conda update -n base -c defaults conda

Or to minimize the number of packages updated during conda update use

     conda install conda=24.3.0



## Package Plan ##

  environment location: C:\Users\jpnav\anaconda3

  added / updated specs:
    - pandas


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    ca-certificates-2024.2.2   |       h56e8100_0         152 KB  conda-forge
    certifi-2024.2.2           |     pyhd8ed1ab_0         157 KB  conda-forge
    pandas-2.1.4               |  py311hf62ec03_0        13.6 MB
    ------------------------------------------------------------
                                           Total:        13.9 MB

The following packages will be UPDATED:

  pandas                              2.0.3-py311hf62ec03_0 --> 2.1.4-py311hf62ec03_0 

The following packages will be SUPERSEDED by a higher-priority channel:

  ca-certificates    pkgs/main::ca-certificates-2024.3.11-~ --> conda-forge::ca-certificates-2024.2.2-h56e8100_0 
  certifi            pkgs/main/win-64::certifi-2024.2.2-py~ --> conda-forge/noarch::certifi-2024.2.2-pyhd8ed1ab_0 



Downloading and Extracting Packages

ca-certificates-2024 | 152 KB    |            |   0% 

certifi-2024.2.2     | 157 KB    |            |   0% 


pandas-2.1.4         | 13.6 MB   |            |   0% 
ca-certificates-2024 | 152 KB    | #          |  11% 


pandas-2.1.4         | 13.6 MB   |            |   0% 
ca-certificates-2024 | 152 KB    | ########## | 100% 
ca-certificates-2024 | 152 KB    | ########## | 100% 


pandas-2.1.4         | 13.6 MB   | 4          |   5% 


pandas-2.1.4         | 13.6 MB   | 9          |  10% 

certifi-2024.2.2     | 157 KB    | #          |  10% 


pandas-2.1.4         | 13.6 MB   | #5         |  16% 


pandas-2.1.4         | 13.6 MB   | ##4        |  24% 

certifi-2024.2.2     | 157 KB    | ########## | 100% 

certifi-2024.2.2     | 157 KB    | ########## | 100% 


pandas-2.1.4         | 13.6 MB   | ###1       |  32% 


pandas-2.1.4         | 13.6 MB   | ###8       |  39% 


pandas-2.1.4         | 13.6 MB   | ####5      |  45% 


pandas-2.1.4         | 13.6 MB   | #####      |  51% 


pandas-2.1.4         | 13.6 MB   | #####6     |  57% 


pandas-2.1.4         | 13.6 MB   | ######2    |  63% 


pandas-2.1.4         | 13.6 MB   | #######    |  70% 


pandas-2.1.4         | 13.6 MB   | #######6   |  77% 


pandas-2.1.4         | 13.6 MB   | ########2  |  83% 


pandas-2.1.4         | 13.6 MB   | ########7  |  88% 


pandas-2.1.4         | 13.6 MB   | #########2 |  93% 


pandas-2.1.4         | 13.6 MB   | #########7 |  98% 


pandas-2.1.4         | 13.6 MB   | ########## | 100% 
                                                     

                                                     

                                                     
Preparing transaction: ...working... done
Verifying transaction: ...working... done
Executing transaction: ...working... done
pd <- import("pandas")

dengueLongStats <- pd$read_pickle(denguelink1)

reticulate::py_last_error()
NULL
str(dengueLongStats) 
'data.frame':   177 obs. of  4 variables:
 $ ano       : num  2000 2000 2000 2001 2001 ...
 $ enfermedad: Ord.factor w/ 3 levels "SIN_SEÑALES"<..: 1 1 1 1 1 1 3 3 3 1 ...
 $ statsName : chr  "edad_mean" "edad_median" "case_sum" "edad_mean" ...
 $ statsValue: num  29.5 27 4324 30.6 28 ...
 - attr(*, "pandas.index")=RangeIndex(start=0, stop=177, step=1)

#Creación de subset para facilitar trabajo

datamean <- subset(dengueLongStats, statsName == "edad_mean")

#Gráfico

library(ggplot2)
library(dplyr)

last_mean <- datamean %>%
  group_by(enfermedad) %>%
  filter(ano == max(ano))

ggplot(data=datamean, aes(x=ano, y=statsValue, color=enfermedad)) +
  geom_smooth(se=TRUE, method="loess")+
  scale_y_log10(labels=scales::comma) +
  scale_color_manual(values=c("SIN_SEÑALES" = "yellow", "ALARMA" = "orange", "GRAVE" = "red")) +
  theme_light() +
  labs(title="Edad media del contagiado de dengue (2010-2022)",
       x="Año",
       y="Edad Promedio",
       color="Grado del Dengue")+
  theme(plot.title = element_text(hjust = 0.4, face="bold", size=18))+
  geom_text(data=last_mean, aes(label=round(statsValue)), hjust=-0.1, vjust=0.5, color="black", show.legend = FALSE)

La edad media del contagiado de dengue vario a través de los años? Fue lo mismo segun gravedad? Respuesta: Como se observa en el gráfico, la edad media del contagiado de dengue sí ha ido variando a través de los años. Las variaciones más notorias se dieron en años anteriores al 2010. Este fenómeno puede deberse a que anterior a dicho año la recopilación de datos referente al dengue era más bien pobre. Posterior al mencionado año, la edad promedio de los contagiados no ha variado de forma notoria, siendo los más afectados, al año 2022, los adultos jóvenes en sus 30 tempranos o 20 tardíos en los 3 grados del dengue: sin señal (sin síntomas), en alarma (con síntomas) y graves.

#Creación de subset para facilitar trabajo

datacase <- subset(dengueLongStats, statsName == "case_sum")

#Gráfico

library(ggplot2)
library(dplyr)

last_values <- datacase %>%
  group_by(enfermedad) %>%
  filter(ano == max(ano))

ggplot(data=datacase, aes(x=ano, y=statsValue, color=enfermedad)) +
  geom_smooth(se=TRUE, method="loess")+
  scale_y_log10(labels=scales::comma) +
  scale_color_manual(values=c("SIN_SEÑALES" = "yellow", "ALARMA" = "orange", "GRAVE" = "red")) +
  theme_light() +
  labs(title="Número de casos a lo largo del tiempo (2010-2022)",
       x="Año",
       y="Número de casos",
       color="Grado del dengue")+
  theme(plot.title = element_text(hjust = 0.5, face="bold", size=18))+
  geom_text(data=last_values, aes(label=statsValue), hjust=-0.1, vjust=0.5, color="black", show.legend = FALSE) +
  scale_x_continuous(limits = c(min(datacase$ano), max(datacase$ano) + 1.5))

La cantidad de casos varió a través de los años? Fue lo mismo según gravedad? Respuesta: Referente a la cantidad de casos, se observa en el gráfico que el dengue de grado alarma (con síntomas) vio un aumento significativo en su número de casos entre los años 2005 y 2015, siendo 7370 casos al año 2022. Pese a ello, el número de estos casos no se compara a la cantidad de casos sin señales (sin síntomas), que al año 2022 se registraban 48625 casos. Aún con ello, este tipo de casos no han variado en demasía a través de los años como sí lo hicieron los casos de alarma. Para añadir, los casos de dengue grave se han mantenido relativamente estables, sin aumentar ni disminuir de forma significativa.

Most affected provinces through the years?

The data worst_ProvYear_alarma_Frequency tell us the frequency of the worst province by region by year:

denguelink2='https://github.com/SocialAnalytics-StrategicIntelligence/TableOperations/raw/main/dataFiles/worst_ProvYear_alarma_Frequency.csv'

dengueProvWorst <- read.csv(denguelink2)


str(dengueProvWorst) 
'data.frame':   43 obs. of  3 variables:
 $ departamento: chr  "AMAZONAS" "AMAZONAS" "ANCASH" "ANCASH" ...
 $ provincia   : chr  "BAGUA" "UTCUBAMBA" "CASMA" "SANTA" ...
 $ case        : int  6 6 5 3 1 7 1 1 10 2 ...

For instance, LORETO has data for 14 years:

dengueProvWorst[dengueProvWorst$departamento=='LORETO',]

In one year, ALTO AMAZONAS was the worst case of people with alarm situation; while MAYNAS had that position for 13 years.

What is the worst cases?

dengueProvWorst[order(-dengueProvWorst$case),]

We could see the distribution of the worst provinces:

library(dplyr)

dengueProvWorst_peor <- dengueProvWorst %>% filter(case >= 10)

baseHeat  = ggplot(dengueProvWorst_peor, aes(x = reorder(departamento,case), y = reorder(provincia,case), fill=case)) + theme_classic()
heatDefault = baseHeat +  geom_tile()

heatBetter=heatDefault +scale_fill_gradient(low = 'yellow',high = 'black',name="Años con\nmayor cantidad\nde casos")
heatBetter + theme(axis.text.x = element_text(angle = 60,vjust = 1,hjust = 1, size=5), 
                   axis.text.y = element_text(size=5),
                   axis.title.x = element_text(size=10), 
                   axis.title.y = element_text(size=10)) +
                   geom_text(aes(label=case),
                             size=4,fontface='bold', color='white')+
                   labs(x="Departamento", y="Provincia", title="Peores provincias por año con más casos de dengue")+
                   theme(plot.title = element_text(hjust = 0.5, face="bold", size=15))

Cuales fueron las provincias mas afectadas con contagiados a lo largo de los años?

Respuesta: Como se puede ver en el gráfico, las provincias más afectadas a lo largo de los años han sido las provincias de Maynas y Tambopata, siendo en 13 ocasiones las provincias que más casos de dengue registraron en su departamento. Estas son seguidas de Tumbes y Coronel Portillo. En particular, se observa que estas provincias más afectadas son de la región selva, y si no, de climas sumamente cálidos así como lluviosos. Esto es evidente dada la naturaleza del aedes aegypti, quien se ve favorecido de este tipo de climas. Como conclusión, los departamentos de Madre de Dios y Loreto deben realizar un esfuerzo en la prevención y cuidado del dengue en las provincias de Tambopata y Maynas. En general, todos los departamentos presentes en el gráfico deben de prestar atención y cuidado a las provincias observables, dado que ser por 10 años o más la provincia con mayor cantidad de contagios del dengue no es un asunto menor y denota falta de acción por parte de los gobiernos locales.

Let’ see the info about rateAlarma:

denguelink3='https://raw.githubusercontent.com/SocialAnalytics-StrategicIntelligence/TableOperations/main/dataFiles/ByYearPlace.pkl'

dengueYearPlace <- pd$read_pickle(denguelink3)

str(dengueYearPlace) 
'data.frame':   203 obs. of  4 variables:
 $ ano           : num  2012 2012 2012 2012 2012 ...
 $ departamento  : chr  "AMAZONAS" "ANCASH" "CAJAMARCA" "HUANUCO" ...
 $ rateAlarma    : num  0.1263 0.0211 0.1772 0.3092 0.0613 ...
 $ rateAlarma.cut: Ord.factor w/ 6 levels "less10%"<"10-25%"<..: 2 1 2 3 1 1 2 2 2 1 ...
 - attr(*, "pandas.index")=RangeIndex(start=0, stop=203, step=1)

Basic stats:

summary(dengueYearPlace)
      ano       departamento         rateAlarma        rateAlarma.cut
 Min.   :2012   Length:203         Min.   :0.00000   less10%  :97    
 1st Qu.:2015   Class :character   1st Qu.:0.03673   10-25%   :46    
 Median :2017   Mode  :character   Median :0.10378   25-50    :47    
 Mean   :2017                      Mean   :0.19514   51-75%   : 5    
 3rd Qu.:2020                      3rd Qu.:0.28067   75-100%  : 5    
 Max.   :2022                      Max.   :1.58333   above100%: 3    

Where and when?

baseHeat  = ggplot(dengueYearPlace, aes(x = as.factor(ano),
                                       y = reorder(departamento, rateAlarma), 
                                       fill=rateAlarma.cut)) + theme_classic()
heatDefault = baseHeat +  geom_tile(show.legend = T) 

heatBetter=heatDefault +scale_fill_brewer(palette = "Reds")
heatBetter + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1, size=8), 
                   axis.text.y = element_text(size=4),
                   legend.text = element_text(size=8)) + 
                   labs(x = "Año", y = "Departamento", fill = "Casos alarmantes", title = "Evolución de los casos alarmantes de dengue por departamento")+
  theme(plot.title = element_text(hjust = 0.3, face="bold", size=12))

Qué relación habia entre los casos alarmantes no graves y los asintomaticos segun departamento a lo largo de los años? Respuesta: Los casos alarmantes no graves a lo largo de los años han ido bajando su porcentaje en proporción al número de casos asintomáticos.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KU29jaWFsIEFuYWx5dGljcyBhbmQgU3RyYXRlZ2ljIEludGVsbGlnZW5jZQ0KDQpTZXNzaW9uIDE6IEV4cGxvcmUgYW5kIFF1ZXJ5DQpMZXTigJlzIGJyaW5nIHRoZSBkYXRhIGluIGxvbmcgZm9ybWF0IChCeVllYXJfTG9uZ1N0YXRzKToNCmBgYHtyfQ0Kcm0obGlzdCA9IGxzKCkpDQpkZW5ndWVsaW5rMT0naHR0cHM6Ly9naXRodWIuY29tL1NvY2lhbEFuYWx5dGljcy1TdHJhdGVnaWNJbnRlbGxpZ2VuY2UvVGFibGVPcGVyYXRpb25zL3Jhdy9tYWluL2RhdGFGaWxlcy9CeVllYXJfTG9uZ1N0YXRzLnBrbCcNCg0KbGlicmFyeShyZXRpY3VsYXRlKQ0KdXNlX3B5dGhvbigiQzovVXNlcnMvanBuYXYvYW5hY29uZGEzIikNCmBgYA0KDQoNCmBgYHtyfQ0KI3B5X2luc3RhbGwoInBhbmRhcyIpICMgaW5zdGFsbCBwYW5kYXMgZm9yIFIgZW52aXJvbm1lbnQNCnBkIDwtIGltcG9ydCgicGFuZGFzIikNCg0KZGVuZ3VlTG9uZ1N0YXRzIDwtIHBkJHJlYWRfcGlja2xlKGRlbmd1ZWxpbmsxKQ0KDQpyZXRpY3VsYXRlOjpweV9sYXN0X2Vycm9yKCkNCg0Kc3RyKGRlbmd1ZUxvbmdTdGF0cykgDQpgYGANCiAgDQogIC0gVGhlIGF2ZXJhZ2UgYWdlIChtZWFuL21lZGlhbikgb2YgaW5mZWN0ZWQgdGhyb3VnaCB0aGUgeWVhcnM/IGJ5IHN5bXB0b21zIGxldmVsPw0KDQojQ3JlYWNpw7NuIGRlIHN1YnNldCBwYXJhIGZhY2lsaXRhciB0cmFiYWpvICANCmBgYHtyfQ0KZGF0YW1lYW4gPC0gc3Vic2V0KGRlbmd1ZUxvbmdTdGF0cywgc3RhdHNOYW1lID09ICJlZGFkX21lYW4iKQ0KYGBgDQoNCiNHcsOhZmljbw0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGRwbHlyKQ0KDQpsYXN0X21lYW4gPC0gZGF0YW1lYW4gJT4lDQogIGdyb3VwX2J5KGVuZmVybWVkYWQpICU+JQ0KICBmaWx0ZXIoYW5vID09IG1heChhbm8pKQ0KDQpnZ3Bsb3QoZGF0YT1kYXRhbWVhbiwgYWVzKHg9YW5vLCB5PXN0YXRzVmFsdWUsIGNvbG9yPWVuZmVybWVkYWQpKSArDQogIGdlb21fc21vb3RoKHNlPVRSVUUsIG1ldGhvZD0ibG9lc3MiKSsNCiAgc2NhbGVfeV9sb2cxMChsYWJlbHM9c2NhbGVzOjpjb21tYSkgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoIlNJTl9TRcORQUxFUyIgPSAieWVsbG93IiwgIkFMQVJNQSIgPSAib3JhbmdlIiwgIkdSQVZFIiA9ICJyZWQiKSkgKw0KICB0aGVtZV9saWdodCgpICsNCiAgbGFicyh0aXRsZT0iRWRhZCBtZWRpYSBkZWwgY29udGFnaWFkbyBkZSBkZW5ndWUgKDIwMTAtMjAyMikiLA0KICAgICAgIHg9IkHDsW8iLA0KICAgICAgIHk9IkVkYWQgUHJvbWVkaW8iLA0KICAgICAgIGNvbG9yPSJHcmFkbyBkZWwgRGVuZ3VlIikrDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjQsIGZhY2U9ImJvbGQiLCBzaXplPTE4KSkrDQogIGdlb21fdGV4dChkYXRhPWxhc3RfbWVhbiwgYWVzKGxhYmVsPXJvdW5kKHN0YXRzVmFsdWUpKSwgaGp1c3Q9LTAuMSwgdmp1c3Q9MC41LCBjb2xvcj0iYmxhY2siLCBzaG93LmxlZ2VuZCA9IEZBTFNFKQ0KDQpgYGANCkxhIGVkYWQgbWVkaWEgZGVsIGNvbnRhZ2lhZG8gZGUgZGVuZ3VlIHZhcmlvIGEgdHJhdsOpcyBkZSBsb3MgYcOxb3M/IEZ1ZSBsbyBtaXNtbyBzZWd1biBncmF2ZWRhZD8NClJlc3B1ZXN0YToNCkNvbW8gc2Ugb2JzZXJ2YSBlbiBlbCBncsOhZmljbywgbGEgZWRhZCBtZWRpYSBkZWwgY29udGFnaWFkbyBkZSBkZW5ndWUgc8OtIGhhIGlkbyB2YXJpYW5kbyBhIHRyYXbDqXMgZGUgbG9zIGHDsW9zLiBMYXMgdmFyaWFjaW9uZXMgbcOhcyBub3RvcmlhcyBzZSBkaWVyb24gZW4gYcOxb3MgYW50ZXJpb3JlcyBhbCAyMDEwLiBFc3RlIGZlbsOzbWVubyBwdWVkZSBkZWJlcnNlIGEgcXVlIGFudGVyaW9yIGEgZGljaG8gYcOxbyBsYSByZWNvcGlsYWNpw7NuIGRlIGRhdG9zIHJlZmVyZW50ZSBhbCBkZW5ndWUgZXJhIG3DoXMgYmllbiBwb2JyZS4gUG9zdGVyaW9yIGFsIG1lbmNpb25hZG8gYcOxbywgbGEgZWRhZCBwcm9tZWRpbyBkZSBsb3MgY29udGFnaWFkb3Mgbm8gaGEgdmFyaWFkbyBkZSBmb3JtYSBub3RvcmlhLCBzaWVuZG8gbG9zIG3DoXMgYWZlY3RhZG9zLCBhbCBhw7FvIDIwMjIsIGxvcyBhZHVsdG9zIGrDs3ZlbmVzIGVuIHN1cyAzMCB0ZW1wcmFub3MgbyAyMCB0YXJkw61vcyBlbiBsb3MgMyBncmFkb3MgZGVsIGRlbmd1ZTogc2luIHNlw7FhbCAoc2luIHPDrW50b21hcyksIGVuIGFsYXJtYSAoY29uIHPDrW50b21hcykgeSBncmF2ZXMuDQoNCiAgLSBUaGUgYW1vdW50IG9mIGluZmVjdGVkIHRocm91Z2ggdGhlIHllYXJzPyBieSBzeW1wdG9tcyBsZXZlbD8NCiAgDQojQ3JlYWNpw7NuIGRlIHN1YnNldCBwYXJhIGZhY2lsaXRhciB0cmFiYWpvICANCmBgYHtyfQ0KZGF0YWNhc2UgPC0gc3Vic2V0KGRlbmd1ZUxvbmdTdGF0cywgc3RhdHNOYW1lID09ICJjYXNlX3N1bSIpDQpgYGANCg0KI0dyw6FmaWNvDQpgYGB7cn0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQoNCmxhc3RfdmFsdWVzIDwtIGRhdGFjYXNlICU+JQ0KICBncm91cF9ieShlbmZlcm1lZGFkKSAlPiUNCiAgZmlsdGVyKGFubyA9PSBtYXgoYW5vKSkNCg0KZ2dwbG90KGRhdGE9ZGF0YWNhc2UsIGFlcyh4PWFubywgeT1zdGF0c1ZhbHVlLCBjb2xvcj1lbmZlcm1lZGFkKSkgKw0KICBnZW9tX3Ntb290aChzZT1UUlVFLCBtZXRob2Q9ImxvZXNzIikrDQogIHNjYWxlX3lfbG9nMTAobGFiZWxzPXNjYWxlczo6Y29tbWEpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJTSU5fU0XDkUFMRVMiID0gInllbGxvdyIsICJBTEFSTUEiID0gIm9yYW5nZSIsICJHUkFWRSIgPSAicmVkIikpICsNCiAgdGhlbWVfbGlnaHQoKSArDQogIGxhYnModGl0bGU9Ik7Dum1lcm8gZGUgY2Fzb3MgYSBsbyBsYXJnbyBkZWwgdGllbXBvICgyMDEwLTIwMjIpIiwNCiAgICAgICB4PSJBw7FvIiwNCiAgICAgICB5PSJOw7ptZXJvIGRlIGNhc29zIiwNCiAgICAgICBjb2xvcj0iR3JhZG8gZGVsIGRlbmd1ZSIpKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlPSJib2xkIiwgc2l6ZT0xOCkpKw0KICBnZW9tX3RleHQoZGF0YT1sYXN0X3ZhbHVlcywgYWVzKGxhYmVsPXN0YXRzVmFsdWUpLCBoanVzdD0tMC4xLCB2anVzdD0wLjUsIGNvbG9yPSJibGFjayIsIHNob3cubGVnZW5kID0gRkFMU0UpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMobWluKGRhdGFjYXNlJGFubyksIG1heChkYXRhY2FzZSRhbm8pICsgMS41KSkNCg0KYGBgDQpMYSBjYW50aWRhZCBkZSBjYXNvcyAgdmFyacOzIGEgdHJhdsOpcyBkZSBsb3MgYcOxb3M/IEZ1ZSBsbyBtaXNtbyBzZWfDum4gZ3JhdmVkYWQ/DQpSZXNwdWVzdGE6DQpSZWZlcmVudGUgYSBsYSBjYW50aWRhZCBkZSBjYXNvcywgc2Ugb2JzZXJ2YSBlbiBlbCBncsOhZmljbyBxdWUgZWwgZGVuZ3VlIGRlIGdyYWRvIGFsYXJtYSAoY29uIHPDrW50b21hcykgdmlvIHVuIGF1bWVudG8gc2lnbmlmaWNhdGl2byBlbiBzdSBuw7ptZXJvIGRlIGNhc29zIGVudHJlIGxvcyBhw7FvcyAyMDA1IHkgMjAxNSwgc2llbmRvIDczNzAgY2Fzb3MgYWwgYcOxbyAyMDIyLiBQZXNlIGEgZWxsbywgZWwgbsO6bWVybyBkZSBlc3RvcyBjYXNvcyBubyBzZSBjb21wYXJhIGEgbGEgY2FudGlkYWQgZGUgY2Fzb3Mgc2luIHNlw7FhbGVzIChzaW4gc8OtbnRvbWFzKSwgcXVlIGFsIGHDsW8gMjAyMiBzZSByZWdpc3RyYWJhbiA0ODYyNSBjYXNvcy4gQcO6biBjb24gZWxsbywgZXN0ZSB0aXBvIGRlIGNhc29zIG5vIGhhbiB2YXJpYWRvIGVuIGRlbWFzw61hIGEgdHJhdsOpcyBkZSBsb3MgYcOxb3MgY29tbyBzw60gbG8gaGljaWVyb24gbG9zIGNhc29zIGRlIGFsYXJtYS4gUGFyYSBhw7FhZGlyLCBsb3MgY2Fzb3MgZGUgZGVuZ3VlIGdyYXZlIHNlIGhhbiBtYW50ZW5pZG8gcmVsYXRpdmFtZW50ZSBlc3RhYmxlcywgc2luIGF1bWVudGFyIG5pIGRpc21pbnVpciBkZSBmb3JtYSBzaWduaWZpY2F0aXZhLiAgDQoNCk1vc3QgYWZmZWN0ZWQgcHJvdmluY2VzIHRocm91Z2ggdGhlIHllYXJzPw0KDQpUaGUgZGF0YSB3b3JzdF9Qcm92WWVhcl9hbGFybWFfRnJlcXVlbmN5IHRlbGwgdXMgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgd29yc3QgcHJvdmluY2UgYnkgcmVnaW9uIGJ5IHllYXI6DQoNCmBgYHtyfQ0KZGVuZ3VlbGluazI9J2h0dHBzOi8vZ2l0aHViLmNvbS9Tb2NpYWxBbmFseXRpY3MtU3RyYXRlZ2ljSW50ZWxsaWdlbmNlL1RhYmxlT3BlcmF0aW9ucy9yYXcvbWFpbi9kYXRhRmlsZXMvd29yc3RfUHJvdlllYXJfYWxhcm1hX0ZyZXF1ZW5jeS5jc3YnDQoNCmRlbmd1ZVByb3ZXb3JzdCA8LSByZWFkLmNzdihkZW5ndWVsaW5rMikNCg0KDQpzdHIoZGVuZ3VlUHJvdldvcnN0KSANCmBgYA0KDQpGb3IgaW5zdGFuY2UsIExPUkVUTyBoYXMgZGF0YSBmb3IgMTQgeWVhcnM6DQoNCmBgYHtyfQ0KZGVuZ3VlUHJvdldvcnN0W2Rlbmd1ZVByb3ZXb3JzdCRkZXBhcnRhbWVudG89PSdMT1JFVE8nLF0NCmBgYA0KDQpJbiBvbmUgeWVhciwgQUxUTyBBTUFaT05BUyB3YXMgdGhlIHdvcnN0IGNhc2Ugb2YgcGVvcGxlIHdpdGggYWxhcm0gc2l0dWF0aW9uOyB3aGlsZSBNQVlOQVMgaGFkIHRoYXQgcG9zaXRpb24gZm9yIDEzIHllYXJzLg0KDQpXaGF0IGlzIHRoZSB3b3JzdCBjYXNlcz8NCg0KYGBge3J9DQpkZW5ndWVQcm92V29yc3Rbb3JkZXIoLWRlbmd1ZVByb3ZXb3JzdCRjYXNlKSxdDQpgYGANCg0KV2UgY291bGQgc2VlIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHdvcnN0IHByb3ZpbmNlczoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQoNCmRlbmd1ZVByb3ZXb3JzdF9wZW9yIDwtIGRlbmd1ZVByb3ZXb3JzdCAlPiUgZmlsdGVyKGNhc2UgPj0gMTApDQoNCmJhc2VIZWF0ICA9IGdncGxvdChkZW5ndWVQcm92V29yc3RfcGVvciwgYWVzKHggPSByZW9yZGVyKGRlcGFydGFtZW50byxjYXNlKSwgeSA9IHJlb3JkZXIocHJvdmluY2lhLGNhc2UpLCBmaWxsPWNhc2UpKSArIHRoZW1lX2NsYXNzaWMoKQ0KaGVhdERlZmF1bHQgPSBiYXNlSGVhdCArICBnZW9tX3RpbGUoKQ0KDQpoZWF0QmV0dGVyPWhlYXREZWZhdWx0ICtzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICd5ZWxsb3cnLGhpZ2ggPSAnYmxhY2snLG5hbWU9IkHDsW9zIGNvblxubWF5b3IgY2FudGlkYWRcbmRlIGNhc29zIikNCmhlYXRCZXR0ZXIgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDYwLHZqdXN0ID0gMSxoanVzdCA9IDEsIHNpemU9NSksIA0KICAgICAgICAgICAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemU9NSksDQogICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MTApLCANCiAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCkpICsNCiAgICAgICAgICAgICAgICAgICBnZW9tX3RleHQoYWVzKGxhYmVsPWNhc2UpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPTQsZm9udGZhY2U9J2JvbGQnLCBjb2xvcj0nd2hpdGUnKSsNCiAgICAgICAgICAgICAgICAgICBsYWJzKHg9IkRlcGFydGFtZW50byIsIHk9IlByb3ZpbmNpYSIsIHRpdGxlPSJQZW9yZXMgcHJvdmluY2lhcyBwb3IgYcOxbyBjb24gbcOhcyBjYXNvcyBkZSBkZW5ndWUiKSsNCiAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBmYWNlPSJib2xkIiwgc2l6ZT0xNSkpDQoNCmBgYA0KDQpDdWFsZXMgZnVlcm9uIGxhcyBwcm92aW5jaWFzIG1hcyBhZmVjdGFkYXMgY29uIGNvbnRhZ2lhZG9zIGEgbG8gbGFyZ28gZGUgbG9zIGHDsW9zPw0KDQpSZXNwdWVzdGE6IENvbW8gc2UgcHVlZGUgdmVyIGVuIGVsIGdyw6FmaWNvLCBsYXMgcHJvdmluY2lhcyBtw6FzIGFmZWN0YWRhcyBhIGxvIGxhcmdvIGRlIGxvcyBhw7FvcyBoYW4gc2lkbyBsYXMgcHJvdmluY2lhcyBkZSBNYXluYXMgeSBUYW1ib3BhdGEsIHNpZW5kbyBlbiAxMyBvY2FzaW9uZXMgbGFzIHByb3ZpbmNpYXMgcXVlIG3DoXMgY2Fzb3MgZGUgZGVuZ3VlIHJlZ2lzdHJhcm9uIGVuIHN1IGRlcGFydGFtZW50by4gRXN0YXMgc29uIHNlZ3VpZGFzIGRlIFR1bWJlcyB5IENvcm9uZWwgUG9ydGlsbG8uIEVuIHBhcnRpY3VsYXIsIHNlIG9ic2VydmEgcXVlIGVzdGFzIHByb3ZpbmNpYXMgbcOhcyBhZmVjdGFkYXMgc29uIGRlIGxhIHJlZ2nDs24gc2VsdmEsIHkgc2kgbm8sIGRlIGNsaW1hcyBzdW1hbWVudGUgY8OhbGlkb3MgYXPDrSBjb21vIGxsdXZpb3Nvcy4gRXN0byBlcyBldmlkZW50ZSBkYWRhIGxhIG5hdHVyYWxlemEgZGVsIGFlZGVzIGFlZ3lwdGksIHF1aWVuIHNlIHZlIGZhdm9yZWNpZG8gZGUgZXN0ZSB0aXBvIGRlIGNsaW1hcy4gQ29tbyBjb25jbHVzacOzbiwgbG9zIGRlcGFydGFtZW50b3MgZGUgTWFkcmUgZGUgRGlvcyB5IExvcmV0byBkZWJlbiByZWFsaXphciB1biBlc2Z1ZXJ6byBlbiBsYSBwcmV2ZW5jacOzbiB5IGN1aWRhZG8gZGVsIGRlbmd1ZSBlbiBsYXMgcHJvdmluY2lhcyBkZSBUYW1ib3BhdGEgeSBNYXluYXMuIEVuIGdlbmVyYWwsIHRvZG9zIGxvcyBkZXBhcnRhbWVudG9zIHByZXNlbnRlcyBlbiBlbCBncsOhZmljbyBkZWJlbiBkZSBwcmVzdGFyIGF0ZW5jacOzbiB5IGN1aWRhZG8gYSBsYXMgcHJvdmluY2lhcyBvYnNlcnZhYmxlcywgZGFkbyBxdWUgc2VyIHBvciAxMCBhw7FvcyBvIG3DoXMgbGEgcHJvdmluY2lhIGNvbiBtYXlvciBjYW50aWRhZCBkZSBjb250YWdpb3MgZGVsIGRlbmd1ZSBubyBlcyB1biBhc3VudG8gbWVub3IgeSBkZW5vdGEgZmFsdGEgZGUgYWNjacOzbiBwb3IgcGFydGUgZGUgbG9zIGdvYmllcm5vcyBsb2NhbGVzLg0KDQpMZXTigJkgc2VlIHRoZSBpbmZvIGFib3V0IHJhdGVBbGFybWE6DQoNCmBgYHtyfQ0KZGVuZ3VlbGluazM9J2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9Tb2NpYWxBbmFseXRpY3MtU3RyYXRlZ2ljSW50ZWxsaWdlbmNlL1RhYmxlT3BlcmF0aW9ucy9tYWluL2RhdGFGaWxlcy9CeVllYXJQbGFjZS5wa2wnDQoNCmRlbmd1ZVllYXJQbGFjZSA8LSBwZCRyZWFkX3BpY2tsZShkZW5ndWVsaW5rMykNCg0Kc3RyKGRlbmd1ZVllYXJQbGFjZSkgDQpgYGANCg0KQmFzaWMgc3RhdHM6DQoNCmBgYHtyfQ0Kc3VtbWFyeShkZW5ndWVZZWFyUGxhY2UpDQpgYGANCg0KV2hlcmUgYW5kIHdoZW4/DQoNCmBgYHtyfQ0KYmFzZUhlYXQgID0gZ2dwbG90KGRlbmd1ZVllYXJQbGFjZSwgYWVzKHggPSBhcy5mYWN0b3IoYW5vKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSByZW9yZGVyKGRlcGFydGFtZW50bywgcmF0ZUFsYXJtYSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1yYXRlQWxhcm1hLmN1dCkpICsgdGhlbWVfY2xhc3NpYygpDQpoZWF0RGVmYXVsdCA9IGJhc2VIZWF0ICsgIGdlb21fdGlsZShzaG93LmxlZ2VuZCA9IFQpIA0KDQpoZWF0QmV0dGVyPWhlYXREZWZhdWx0ICtzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlJlZHMiKQ0KaGVhdEJldHRlciArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xLCBzaXplPTgpLCANCiAgICAgICAgICAgICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTQpLA0KICAgICAgICAgICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9OCkpICsgDQogICAgICAgICAgICAgICAgICAgbGFicyh4ID0gIkHDsW8iLCB5ID0gIkRlcGFydGFtZW50byIsIGZpbGwgPSAiQ2Fzb3MgYWxhcm1hbnRlcyIsIHRpdGxlID0gIkV2b2x1Y2nDs24gZGUgbG9zIGNhc29zIGFsYXJtYW50ZXMgZGUgZGVuZ3VlIHBvciBkZXBhcnRhbWVudG8iKSsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuMywgZmFjZT0iYm9sZCIsIHNpemU9MTIpKQ0KDQpgYGANClF1w6kgcmVsYWNpw7NuIGhhYmlhIGVudHJlIGxvcyBjYXNvcyBhbGFybWFudGVzIG5vIGdyYXZlcyB5IGxvcyBhc2ludG9tYXRpY29zIHNlZ3VuIGRlcGFydGFtZW50byBhIGxvIGxhcmdvIGRlIGxvcyBhw7Fvcz8NClJlc3B1ZXN0YTogTG9zIGNhc29zIGFsYXJtYW50ZXMgbm8gZ3JhdmVzIGEgbG8gbGFyZ28gZGUgbG9zIGHDsW9zIGhhbiBpZG8gYmFqYW5kbyBzdSBwb3JjZW50YWplIGVuIHByb3BvcmNpw7NuIGFsIG7Dum1lcm8gZGUgY2Fzb3MgYXNpbnRvbcOhdGljb3MuDQo=