Trabajo elaborado para la asignatura “Programación y manejo de datos en la era del Big Data” de la Universitat de València durante el curso 2020-2021. El repo del trabajo está aquí. La página web de la asignatura y los trabajos de mis compañeros pueden verse aquí.


1. Introducción

El primer martes de Noviembre cada 4 años se celebran elecciones en EEUU. En el país norteamericano no se cuentan los votos totales que recibe un candidato, sino lo que importa son los votos que reciben en el Colegio Electoral. Cada Estado asigna un número de electores a dicho colegio en función de su población. Este número coincide con el número de representantes que manda a la Cámara del Congreso más dos senadores que tiene cada Estado. Por lo tanto, es un estilo de sistema de puntos, el candidato que gana en un Estado(aunque sea por un voto) consigue todos los electores de ese Estado. Para ganar los candidatos necesitan llegar a 270 electores. Por eso puede darse que un cadidato gane el voto popular pero no el electoral y pierda la Presidencia(como ocurrió en el año 2000 y 2016). En el trabajo compararemos los votos con el PIBpc de los difeentes Estados.

Paquetes utilizados

library(tidyverse)
library(gganimate)
library(plotly)
library(patchwork)
library(ggplot2)
library(RColorBrewer)
library(gt)
library(ggthemes)
library(gghighlight)

2. Datos utilizados

Lo primero que hice para buscar ideas de trabajos miré en https://www.kaggle.com/ donde pude encontrar dos datasets muy interesantes, los cuales he utilizado para el trabajo. Son US Election 2020 y GDP per capita in US states with tableau. En el primer trabajo pude encontrar los datos de todos los votos agrupados en cada uno de los estados y sus distritos.En el segundo encontré los datos del PIB per capita de todos los Estados.

df <- rio::import(here::here("datos", "president_county_candidate.csv"))

PIBpcUS <- read_csv("./datos/bea-gdp-by-state.csv", col_names = TRUE)

3. Tablas datos

El PIB per capita es un indicador macroeconómico de productividad y desarrollo económico, usado para entregar una visión respecto al rendimiento de las condiciones económicas y sociales de un país, esto en consideración del crecimiento real y la fuerza laboral. Generalmente también se utiliza como indicador de bienestar social. Es la relación que hay entre el PIB y la cantidad de habitantes de un país.

En la siguiente tabla tenemos los datos del PIB per capita de los diferentes Estados


PIBpcUS1 <- PIBpcUS %>% select(-Fips)

DT::datatable(PIBpcUS1)

En la tabla siguiente tenemos los datos de los votos de los diferentes partidos. He agrupado los difentes distritos que aparecían en el dataframe en los Estados pertenecientes. En la tabla podemos observar aparte de los votos por Estado, los diferentes candidatos que se presentan con sus respectivos partidos políticos. A parte de las dos principales candidaturas con los dos principales partidos(Republicano y Demócrata), vemos que también otros partidos como el Partido Libertario o el Partido Verde de los Estados Unidos.

Votos <- df %>%  group_by(state, candidate, party)%>%
  summarise(total_votes=sum(total_votes))

DT::datatable(Votos, filter = 'top', 
              options = list(pageLength = 5, autoWidth = TRUE ))

4. Análisis PIBpc

En el siguiente gráfico podemos ver los datos del PIBpc de los disferentes Estados en el año 2017.

df<- read_csv("./datos/bea-gdp-by-state.csv", col_names = TRUE)

PIBpcEst <- df %>% slice(c(2:53))%>% 
  rename( PIBpc2017 = "2017", PIBpc2016="2016",PIBpc2015="2015",
                     PIBpc2014="2014", PIBpc2013="2013")
p4 <- ggplot(PIBpcEst, aes(Area, PIBpc2017, size = PIBpc2017, color = PIBpc2017)) + geom_point()

ggplotly(p4+ theme(legend.position = "none") +theme_bw()+
           labs(title = "PIB per cápita USA", subtitle = "Año 2017", x = "Estados", y = "PIBpc"))

En estos gráficos he seleccionado y comparado los 6 primeros y últimos Estados en PIbpc

#6 primeros estados PIBpc


aa<- PIBpcEst %>% filter(Area %in% c("District of Columbia", "Massachusetts",
"New York", "North Dakota","Alaska","Connecticut" ))

p <- ggplot(aa, aes(Area,PIBpc2017))


#6 últimos estados en PIBpc

aa1<- PIBpcEst %>% filter(Area %in% c(" Mississippi", "Idaho",
    "Arkansas", "West Virginia","Alabama","South Carolina" ))

p1 <- ggplot(aa1, aes(Area,PIBpc2017))

p+ geom_col()+  ylim(c(NA, 200000))+ labs(title = "PIBpc por Estados", subtitle = "Estados ricos y pobres", x = "Estados", y = "PIBpc")+ 
  theme_solarized()+
  p1+ geom_col()+  ylim(c(NA, 200000))+
labs(x = "Estados", y = "PIBpc")+ theme_solarized()

4. Análisis votos por Estados

Las elecciones presidenciales de 2020 se celebraron el martes 3 de noviembre de 2020, y fueron las quincuagésimo novenas elecciones presidenciales en Estados Unidos. En los siguietes gráficos analizaremos cuales han sido los resultados de los principales candidatos en dos puntos muy distintos. Uno en los Estados con mayor PIBpc del país y otro en los Estados con menor PIBpc.

¿Que candidato ha tenido más apoyo en las zonas ricas?

#Tratamos los datos del candidato Joe Biden

df <- rio::import(here::here("datos", "president_county_candidate.csv"))


jb <- df %>% filter(party == "DEM") %>% select(-county) %>% 
  group_by(state, candidate)%>%
  summarise(total_votes=sum(total_votes))

jb1<- jb %>% mutate(Biden = total_votes)

jb2 <- jb1 %>%select(state, Biden)

#Tratamos los datos de Donald Trump

dt <- df %>% filter(party=="REP")  %>% select(-county) %>% 
  group_by(state, candidate)%>%
  summarise(total_votes=sum(total_votes))

dt1 <- dt %>% mutate(Trump = total_votes)

dt2 <- dt1 %>%select(state,Trump)

#Unimos los dos data

df_vot <- full_join(jb2, dt2)

rio::export(df_vot, "./Datos/df_vot.csv")

#Cogemos los 6 estados mas ricos

MR<- df_vot %>% filter(state %in% c("District of Columbia", "Massachusetts",
                                    "New York", "North Dakota","Alaska","Connecticut" ))

pMRB<- ggplot(MR, aes(state,Biden))


pMRT<- ggplot(MR, aes(state,Trump))


pMRB + geom_col(fill="blue") + ylim(NA,5500000)+theme_solarized()+
labs(title = "Estados ricos", subtitle = "Año 2020", x = "Estados", y = "Biden")+ 
  pMRT+ geom_col(fill="red")+ ylim(NA,5500000)+theme_solarized()+
  labs( x = "Estados", y = "Trump")

¿Que candidato ha tenido más apoyo en las zonas pobres?

#Cogemos los 6 estados con menos PIBpc

df_vot<- rio::import(here::here("Datos", "df_vot.csv"))


MP<- df_vot %>% filter(state %in% c("Mississippi", "Idaho",
      "Arkansas", "West Virginia","Alabama","South Carolina" ))

pMPB<- ggplot(MP, aes(state,Biden))

pMPT<- ggplot(MP, aes(state,Trump))

pMPB + geom_col(fill="blue") + 
  labs(title = "Estados pobres", subtitle = "Año 2020", x = "Estados", y = "Biden")+
  ylim(NA,2000000)+theme_solarized() + 
  pMPT+ geom_col(fill="red")+ ylim(NA,2000000)+theme_solarized()+
  labs(x = "Estados", y = "Trump")

4. Conclusión

Una de las principales característacas de estas elecciones es la movilización que han tenido. Donald Trump y Joe Biden son los candidatos que más votos han recibido en la historia. Una de las cosas que se dice,sobre la victoria de Joe Biden, es que ha conseguido movilizar a todo el electorado demócrata tradicionaly también ha conseguido ganar entre los independientes. Otra de las razones, que va enlazado con lo que he analizado, es la victoria en las grandes ciudades. Historicamente los suburbios de las grandes ciudades habian sido votantes del partido republicano pero en estas elecciones ha sido distinto. Los ciudadanos de rentas más bajas en las grandes ciudades han decantado su voto en Joe Biden.

LS0tDQp0aXRsZTogIlJlbGFjacOzbiBkZWwgUElCcGMgZGUgRUVVVSBjb24gbGFzIGVsZWNjaW9uZXMgZGUgMjAyMCINCnN1YnRpdGxlOiAiQW50b25pbyBMYW5nYSBMYWhveihhbmxhbmxhQGFsdW1uaS51di5lcykiICMtIHBvbmdvIHTDuiBub21icmUgYWjDrSBwYXJhIHEgYXBhcmV6Y2EgbcOhcyBncmFuZGUgcSBlbCBkZSBsYSBVVg0KYXV0aG9yOiAiVW5pdmVyc2l0YXQgZGUgVmFsw6huY2lhIg0KZGF0ZTogIkRpY2llbWJyZSBkZSAyMDIwIChhY3R1YWxpemFkbyBlbCBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkLSVtLSVZJylgKSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICAjY3NzOiAiLi9hc3NldHMvbXlfY3NzX2ZpbGUuY3NzIg0KICAgIHRoZW1lOiBwYXBlcg0KICAgIGhpZ2hsaWdodDogdGV4dG1hdGUgDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzIA0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICBzZWxmX2NvbnRhaW5lZDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UNCiAgICBkZl9wcmludDoga2FibGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlDQotLS0NCg0KYGBge3IgcGFja2FnZXMtc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShrbGlwcHkpICAjLSByZW1vdGVzOjppbnN0YWxsX2dpdGh1Yigicmxlc3VyL2tsaXBweSIpDQpsaWJyYXJ5KGtuaXRyKQ0KYGBgDQoNCmBgYHtyIGNodW5rLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgI3Jlc3VsdHMgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgY2FjaGUgPSBGQUxTRSwgY2FjaGUucGF0aCA9ICIvY2FjaGVzLyIsIGNvbW1lbnQgPSAiIz4iLA0KICAgICAgICAgICAgICAgICAgICAgICNmaWcud2lkdGggPSA3LCAjZmlnLmhlaWdodD0gNywgICANCiAgICAgICAgICAgICAgICAgICAgICAjb3V0LndpZHRoID0gNywgb3V0LmhlaWdodCA9IDcsDQogICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2UgPSBUUlVFLCAgZmlnLnNob3cgPSAiaG9sZCIsDQogICAgICAgICAgICAgICAgICAgICAgZmlnLmFzcCA9IDcvOSwgb3V0LndpZHRoID0gIjYwJSIsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRldiA9ICJwbmciLCBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICJjYWlyby1wbmciKSkNCmBgYA0KDQpgYGB7ciBvcHRpb25zLXNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgIy0gcGFyYSBxdWl0YXIgbGEgbm90YWNpw7NuIGNpZW50w61maWNhDQpvcHRpb25zKCJ5YW1sLmV2YWwuZXhwciIgPSBUUlVFKSANCmBgYA0KICAgICAgDQpgYGB7ciBrbGlwcHksIGVjaG8gPSBGQUxTRX0NCmtsaXBweTo6a2xpcHB5KHBvc2l0aW9uID0gYygidG9wIiwgInJpZ2h0IikpICMtIHJlbW90ZXM6Omluc3RhbGxfZ2l0aHViKCJybGVzdXIva2xpcHB5IikNCmBgYA0KDQo8aHIgY2xhc3M9ImxpbmVhLWJsYWNrIj4NCg0KVHJhYmFqbyBlbGFib3JhZG8gcGFyYSBsYSBhc2lnbmF0dXJhICJQcm9ncmFtYWNpw7NuIHkgbWFuZWpvIGRlIGRhdG9zIGVuIGxhIGVyYSBkZWwgQmlnIERhdGEiIGRlIGxhIFVuaXZlcnNpdGF0IGRlIFZhbMOobmNpYSBkdXJhbnRlIGVsIGN1cnNvIDIwMjAtMjAyMS4gRWwgcmVwbyBkZWwgdHJhYmFqbyBlc3TDoSBbYXF1w61dKGh0dHBzOi8vZ2l0aHViLmNvbS9BbnRvbmlvMjAyMDIxL3RyYWJham9fQmlnRGF0YSl7dGFyZ2V0PSJfYmxhbmsifS4gTGEgcMOhZ2luYSB3ZWIgZGUgbGEgYXNpZ25hdHVyYSB5IGxvcyB0cmFiYWpvcyBkZSBtaXMgY29tcGHDsWVyb3MgcHVlZGVuIHZlcnNlIFthcXXDrV0oaHR0cHM6Ly9wZXJlenA0NC5naXRodWIuaW8vaW50cm8tZHMtMjAtMjEtd2ViLzA3LXRyYWJham9zLmh0bWwpe3RhcmdldD0iX2JsYW5rIn0uDQoNCjwhLS0gRWwgcMOhcnJhZm8gZGUgYXJyaWJhIGhhcyBkZSBkZWphcmxvIGNhc2kgaWd1YWwsIA0KICAgICAgICBzb2xvIEhBUyBkZSBTVVNUSVRVSVIgbGFzIDIgdmVjZXMgcXVlIGFwYXJlY2UgInBlcmV6cDQ0IiBwb3IgdHUgdXN1YXJpbyBkZSBHaXRodWItLT4NCiAgICANCg0KDQo8aHIgY2xhc3M9ImxpbmVhLXJlZCI+DQoNCiMgMS4gSW50cm9kdWNjacOzbg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG89RkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJtYXBhZWxlY2Npb25lcy5qcGciKSkNCmBgYA0KDQpFbCBwcmltZXIgbWFydGVzIGRlIE5vdmllbWJyZSBjYWRhIDQgYcOxb3Mgc2UgY2VsZWJyYW4gZWxlY2Npb25lcyBlbiBFRVVVLiBFbiBlbCBwYcOtcyBub3J0ZWFtZXJpY2FubyBubyBzZSBjdWVudGFuIGxvcyB2b3RvcyB0b3RhbGVzIHF1ZSByZWNpYmUgdW4gY2FuZGlkYXRvLCBzaW5vIGxvIHF1ZSBpbXBvcnRhIHNvbiBsb3Mgdm90b3MgcXVlIHJlY2liZW4gZW4gZWwgQ29sZWdpbyBFbGVjdG9yYWwuIENhZGEgRXN0YWRvIGFzaWduYSB1biBuw7ptZXJvIGRlIGVsZWN0b3JlcyBhIGRpY2hvIGNvbGVnaW8gZW4gZnVuY2nDs24gZGUgc3UgcG9ibGFjacOzbi4gRXN0ZSBuw7ptZXJvIGNvaW5jaWRlIGNvbiBlbCBuw7ptZXJvIGRlIHJlcHJlc2VudGFudGVzIHF1ZSBtYW5kYSBhIGxhIEPDoW1hcmEgZGVsIENvbmdyZXNvIG3DoXMgZG9zIHNlbmFkb3JlcyBxdWUgdGllbmUgY2FkYSBFc3RhZG8uDQpQb3IgbG8gdGFudG8sIGVzIHVuIGVzdGlsbyBkZSBzaXN0ZW1hIGRlIHB1bnRvcywgZWwgY2FuZGlkYXRvIHF1ZSBnYW5hIGVuIHVuIEVzdGFkbyhhdW5xdWUgc2VhIHBvciB1biB2b3RvKSBjb25zaWd1ZSB0b2RvcyBsb3MgZWxlY3RvcmVzIGRlIGVzZSBFc3RhZG8uIFBhcmEgZ2FuYXIgbG9zIGNhbmRpZGF0b3MgbmVjZXNpdGFuIGxsZWdhciBhIDI3MCBlbGVjdG9yZXMuIFBvciBlc28gcHVlZGUgZGFyc2UgcXVlIHVuIGNhZGlkYXRvIGdhbmUgZWwgdm90byBwb3B1bGFyIHBlcm8gbm8gZWwgZWxlY3RvcmFsIHkgcGllcmRhIGxhIFByZXNpZGVuY2lhKGNvbW8gb2N1cnJpw7MgZW4gZWwgYcOxbyAyMDAwIHkgMjAxNikuIEVuIGVsIHRyYWJham8gY29tcGFyYXJlbW9zIGxvcyB2b3RvcyBjb24gZWwgUElCcGMgZGUgbG9zIGRpZmVlbnRlcyBFc3RhZG9zLg0KDQojIyBQYXF1ZXRlcyB1dGlsaXphZG9zDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdnYW5pbWF0ZSkNCmxpYnJhcnkocGxvdGx5KQ0KbGlicmFyeShwYXRjaHdvcmspDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmxpYnJhcnkoZ3QpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeShnZ2hpZ2hsaWdodCkNCmBgYA0KDQojIDIuIERhdG9zIHV0aWxpemFkb3MNCkxvIHByaW1lcm8gcXVlIGhpY2UgcGFyYSBidXNjYXIgaWRlYXMgZGUgdHJhYmFqb3MgbWlyw6kgZW4gPGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vPiBkb25kZSBwdWRlIGVuY29udHJhciBkb3MgZGF0YXNldHMgbXV5IGludGVyZXNhbnRlcywgbG9zIGN1YWxlcyBoZSB1dGlsaXphZG8gcGFyYSBlbCB0cmFiYWpvLiBTb24gW1VTIEVsZWN0aW9uIDIwMjBdKGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vdW5hbmltYWQvdXMtZWxlY3Rpb24tMjAyMCkgeSBbR0RQIHBlciBjYXBpdGEgaW4gVVMgc3RhdGVzIHdpdGggdGFibGVhdV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9tYXJpYXB1c2hrYXJldmEvZ2RwLXBlci1jYXBpdGEtaW4tdXMtc3RhdGVzLXdpdGgtdGFibGVhdS9kYXRhP3NlbGVjdD1iZWEtZ2RwLWJ5LXN0YXRlLmNzdikuIEVuIGVsIHByaW1lciB0cmFiYWpvIHB1ZGUgZW5jb250cmFyIGxvcyBkYXRvcyBkZSB0b2RvcyBsb3Mgdm90b3MgYWdydXBhZG9zIGVuIGNhZGEgdW5vICBkZSBsb3MgZXN0YWRvcyB5IHN1cyBkaXN0cml0b3MuRW4gZWwgc2VndW5kbyBlbmNvbnRyw6kgbG9zIGRhdG9zIGRlbCBQSUIgcGVyIGNhcGl0YSBkZSB0b2RvcyBsb3MgRXN0YWRvcy4NCg0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQpkZiA8LSByaW86OmltcG9ydChoZXJlOjpoZXJlKCJkYXRvcyIsICJwcmVzaWRlbnRfY291bnR5X2NhbmRpZGF0ZS5jc3YiKSkNCg0KUElCcGNVUyA8LSByZWFkX2NzdigiLi9kYXRvcy9iZWEtZ2RwLWJ5LXN0YXRlLmNzdiIsIGNvbF9uYW1lcyA9IFRSVUUpDQoNCmBgYA0KDQoNCiMjIDMuIFRhYmxhcyBkYXRvcw0KRWwgUElCIHBlciBjYXBpdGEgZXMgdW4gaW5kaWNhZG9yIG1hY3JvZWNvbsOzbWljbyBkZSBwcm9kdWN0aXZpZGFkIHkgZGVzYXJyb2xsbyBlY29uw7NtaWNvLCB1c2FkbyBwYXJhIGVudHJlZ2FyIHVuYSB2aXNpw7NuIHJlc3BlY3RvIGFsIHJlbmRpbWllbnRvIGRlIGxhcyBjb25kaWNpb25lcyBlY29uw7NtaWNhcyB5IHNvY2lhbGVzIGRlIHVuIHBhw61zLCBlc3RvIGVuIGNvbnNpZGVyYWNpw7NuIGRlbCBjcmVjaW1pZW50byByZWFsIHkgbGEgZnVlcnphIGxhYm9yYWwuIEdlbmVyYWxtZW50ZSB0YW1iacOpbiBzZSB1dGlsaXphIGNvbW8gaW5kaWNhZG9yIGRlIGJpZW5lc3RhciBzb2NpYWwuIEVzIGxhIHJlbGFjacOzbiBxdWUgaGF5IGVudHJlIGVsIFBJQiB5IGxhIGNhbnRpZGFkIGRlIGhhYml0YW50ZXMgZGUgdW4gcGHDrXMuDQoNCkVuIGxhIHNpZ3VpZW50ZSB0YWJsYSB0ZW5lbW9zIGxvcyBkYXRvcyBkZWwgUElCIHBlciBjYXBpdGEgZGUgbG9zIGRpZmVyZW50ZXMgRXN0YWRvcw0KDQpgYGB7ciwgZXZhbCA9IFRSVUV9DQoNClBJQnBjVVMxIDwtIFBJQnBjVVMgJT4lIHNlbGVjdCgtRmlwcykNCg0KRFQ6OmRhdGF0YWJsZShQSUJwY1VTMSkNCg0KYGBgDQoNCg0KRW4gbGEgdGFibGEgc2lndWllbnRlIHRlbmVtb3MgbG9zIGRhdG9zIGRlIGxvcyB2b3RvcyBkZSBsb3MgZGlmZXJlbnRlcyBwYXJ0aWRvcy4gSGUgYWdydXBhZG8gbG9zIGRpZmVudGVzIGRpc3RyaXRvcyBxdWUgYXBhcmVjw61hbiBlbiBlbCBkYXRhZnJhbWUgZW4gbG9zIEVzdGFkb3MgcGVydGVuZWNpZW50ZXMuIEVuIGxhIHRhYmxhIHBvZGVtb3Mgb2JzZXJ2YXIgYXBhcnRlIGRlIGxvcyB2b3RvcyBwb3IgRXN0YWRvLCBsb3MgZGlmZXJlbnRlcyBjYW5kaWRhdG9zIHF1ZSBzZSBwcmVzZW50YW4gY29uIHN1cyByZXNwZWN0aXZvcyBwYXJ0aWRvcyBwb2zDrXRpY29zLiBBIHBhcnRlIGRlIGxhcyBkb3MgcHJpbmNpcGFsZXMgY2FuZGlkYXR1cmFzIGNvbiBsb3MgZG9zIHByaW5jaXBhbGVzIHBhcnRpZG9zKFJlcHVibGljYW5vIHkgRGVtw7NjcmF0YSksIHZlbW9zIHF1ZSB0YW1iacOpbiBvdHJvcyBwYXJ0aWRvcyBjb21vIGVsIFBhcnRpZG8gTGliZXJ0YXJpbyBvIGVsIFBhcnRpZG8gVmVyZGUgZGUgbG9zIEVzdGFkb3MgVW5pZG9zLg0KDQoNCmBgYHtyLCBldmFsID0gVFJVRX0NClZvdG9zIDwtIGRmICU+JSAgZ3JvdXBfYnkoc3RhdGUsIGNhbmRpZGF0ZSwgcGFydHkpJT4lDQogIHN1bW1hcmlzZSh0b3RhbF92b3Rlcz1zdW0odG90YWxfdm90ZXMpKQ0KDQpEVDo6ZGF0YXRhYmxlKFZvdG9zLCBmaWx0ZXIgPSAndG9wJywgDQogICAgICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSA1LCBhdXRvV2lkdGggPSBUUlVFICkpDQoNCmBgYA0KDQojIDQuIEFuw6FsaXNpcyBQSUJwYw0KDQpFbiBlbCBzaWd1aWVudGUgZ3LDoWZpY28gcG9kZW1vcyB2ZXIgbG9zIGRhdG9zIGRlbCBQSUJwYyBkZSBsb3MgZGlzZmVyZW50ZXMgRXN0YWRvcyBlbiBlbCBhw7FvIDIwMTcuDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQpkZjwtIHJlYWRfY3N2KCIuL2RhdG9zL2JlYS1nZHAtYnktc3RhdGUuY3N2IiwgY29sX25hbWVzID0gVFJVRSkNCg0KUElCcGNFc3QgPC0gZGYgJT4lIHNsaWNlKGMoMjo1MykpJT4lIA0KICByZW5hbWUoIFBJQnBjMjAxNyA9ICIyMDE3IiwgUElCcGMyMDE2PSIyMDE2IixQSUJwYzIwMTU9IjIwMTUiLA0KICAgICAgICAgICAgICAgICAgICAgUElCcGMyMDE0PSIyMDE0IiwgUElCcGMyMDEzPSIyMDEzIikNCnA0IDwtIGdncGxvdChQSUJwY0VzdCwgYWVzKEFyZWEsIFBJQnBjMjAxNywgc2l6ZSA9IFBJQnBjMjAxNywgY29sb3IgPSBQSUJwYzIwMTcpKSArIGdlb21fcG9pbnQoKQ0KDQpnZ3Bsb3RseShwNCsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArdGhlbWVfYncoKSsNCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJQSUIgcGVyIGPDoXBpdGEgVVNBIiwgc3VidGl0bGUgPSAiQcOxbyAyMDE3IiwgeCA9ICJFc3RhZG9zIiwgeSA9ICJQSUJwYyIpKQ0KYGBgDQoNCkVuIGVzdG9zIGdyw6FmaWNvcyBoZSBzZWxlY2Npb25hZG8geSBjb21wYXJhZG8gbG9zIDYgcHJpbWVyb3MgeSDDumx0aW1vcyBFc3RhZG9zIGVuIFBJYnBjDQoNCmBgYHtyLCBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQojNiBwcmltZXJvcyBlc3RhZG9zIFBJQnBjDQoNCg0KYWE8LSBQSUJwY0VzdCAlPiUgZmlsdGVyKEFyZWEgJWluJSBjKCJEaXN0cmljdCBvZiBDb2x1bWJpYSIsICJNYXNzYWNodXNldHRzIiwNCiJOZXcgWW9yayIsICJOb3J0aCBEYWtvdGEiLCJBbGFza2EiLCJDb25uZWN0aWN1dCIgKSkNCg0KcCA8LSBnZ3Bsb3QoYWEsIGFlcyhBcmVhLFBJQnBjMjAxNykpDQoNCg0KIzYgw7psdGltb3MgZXN0YWRvcyBlbiBQSUJwYw0KDQphYTE8LSBQSUJwY0VzdCAlPiUgZmlsdGVyKEFyZWEgJWluJSBjKCIJTWlzc2lzc2lwcGkiLCAiSWRhaG8iLA0KICAgICJBcmthbnNhcyIsICJXZXN0IFZpcmdpbmlhIiwiQWxhYmFtYSIsIlNvdXRoIENhcm9saW5hIiApKQ0KDQpwMSA8LSBnZ3Bsb3QoYWExLCBhZXMoQXJlYSxQSUJwYzIwMTcpKQ0KDQpwKyBnZW9tX2NvbCgpKyAgeWxpbShjKE5BLCAyMDAwMDApKSsgbGFicyh0aXRsZSA9ICJQSUJwYyBwb3IgRXN0YWRvcyIsIHN1YnRpdGxlID0gIkVzdGFkb3Mgcmljb3MgeSBwb2JyZXMiLCB4ID0gIkVzdGFkb3MiLCB5ID0gIlBJQnBjIikrIA0KICB0aGVtZV9zb2xhcml6ZWQoKSsNCiAgcDErIGdlb21fY29sKCkrICB5bGltKGMoTkEsIDIwMDAwMCkpKw0KbGFicyh4ID0gIkVzdGFkb3MiLCB5ID0gIlBJQnBjIikrIHRoZW1lX3NvbGFyaXplZCgpDQoNCmBgYA0KDQojIDQuIEFuw6FsaXNpcyB2b3RvcyBwb3IgRXN0YWRvcw0KTGFzIGVsZWNjaW9uZXMgcHJlc2lkZW5jaWFsZXMgZGUgMjAyMCBzZSBjZWxlYnJhcm9uIGVsIG1hcnRlcyAzIGRlIG5vdmllbWJyZSBkZSAyMDIwLCB5IGZ1ZXJvbiBsYXMgcXVpbmN1YWfDqXNpbW8gbm92ZW5hcyBlbGVjY2lvbmVzIHByZXNpZGVuY2lhbGVzIGVuIEVzdGFkb3MgVW5pZG9zLiBFbiBsb3Mgc2lndWlldGVzIGdyw6FmaWNvcyBhbmFsaXphcmVtb3MgY3VhbGVzIGhhbiBzaWRvIGxvcyByZXN1bHRhZG9zIGRlIGxvcyBwcmluY2lwYWxlcyBjYW5kaWRhdG9zIGVuIGRvcyBwdW50b3MgbXV5IGRpc3RpbnRvcy4gVW5vIGVuIGxvcyBFc3RhZG9zIGNvbiBtYXlvciBQSUJwYyBkZWwgcGHDrXMgeSBvdHJvIGVuIGxvcyBFc3RhZG9zIGNvbiBtZW5vciBQSUJwYy4NCg0Kwr9RdWUgY2FuZGlkYXRvIGhhIHRlbmlkbyBtw6FzIGFwb3lvIGVuIGxhcyB6b25hcyByaWNhcz8NCmBgYHtyLCBlY2hvID0gVFJVRSwgZXZhbCA9IFRSVUV9DQojVHJhdGFtb3MgbG9zIGRhdG9zIGRlbCBjYW5kaWRhdG8gSm9lIEJpZGVuDQoNCmRmIDwtIHJpbzo6aW1wb3J0KGhlcmU6OmhlcmUoImRhdG9zIiwgInByZXNpZGVudF9jb3VudHlfY2FuZGlkYXRlLmNzdiIpKQ0KDQoNCmpiIDwtIGRmICU+JSBmaWx0ZXIocGFydHkgPT0gIkRFTSIpICU+JSBzZWxlY3QoLWNvdW50eSkgJT4lIA0KICBncm91cF9ieShzdGF0ZSwgY2FuZGlkYXRlKSU+JQ0KICBzdW1tYXJpc2UodG90YWxfdm90ZXM9c3VtKHRvdGFsX3ZvdGVzKSkNCg0KamIxPC0gamIgJT4lIG11dGF0ZShCaWRlbiA9IHRvdGFsX3ZvdGVzKQ0KDQpqYjIgPC0gamIxICU+JXNlbGVjdChzdGF0ZSwgQmlkZW4pDQoNCiNUcmF0YW1vcyBsb3MgZGF0b3MgZGUgRG9uYWxkIFRydW1wDQoNCmR0IDwtIGRmICU+JSBmaWx0ZXIocGFydHk9PSJSRVAiKSAgJT4lIHNlbGVjdCgtY291bnR5KSAlPiUgDQogIGdyb3VwX2J5KHN0YXRlLCBjYW5kaWRhdGUpJT4lDQogIHN1bW1hcmlzZSh0b3RhbF92b3Rlcz1zdW0odG90YWxfdm90ZXMpKQ0KDQpkdDEgPC0gZHQgJT4lIG11dGF0ZShUcnVtcCA9IHRvdGFsX3ZvdGVzKQ0KDQpkdDIgPC0gZHQxICU+JXNlbGVjdChzdGF0ZSxUcnVtcCkNCg0KI1VuaW1vcyBsb3MgZG9zIGRhdGENCg0KZGZfdm90IDwtIGZ1bGxfam9pbihqYjIsIGR0MikNCg0KcmlvOjpleHBvcnQoZGZfdm90LCAiLi9EYXRvcy9kZl92b3QuY3N2IikNCg0KI0NvZ2Vtb3MgbG9zIDYgZXN0YWRvcyBtYXMgcmljb3MNCg0KTVI8LSBkZl92b3QgJT4lIGZpbHRlcihzdGF0ZSAlaW4lIGMoIkRpc3RyaWN0IG9mIENvbHVtYmlhIiwgIk1hc3NhY2h1c2V0dHMiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5ldyBZb3JrIiwgIk5vcnRoIERha290YSIsIkFsYXNrYSIsIkNvbm5lY3RpY3V0IiApKQ0KDQpwTVJCPC0gZ2dwbG90KE1SLCBhZXMoc3RhdGUsQmlkZW4pKQ0KDQoNCnBNUlQ8LSBnZ3Bsb3QoTVIsIGFlcyhzdGF0ZSxUcnVtcCkpDQoNCg0KcE1SQiArIGdlb21fY29sKGZpbGw9ImJsdWUiKSArIHlsaW0oTkEsNTUwMDAwMCkrdGhlbWVfc29sYXJpemVkKCkrDQpsYWJzKHRpdGxlID0gIkVzdGFkb3Mgcmljb3MiLCBzdWJ0aXRsZSA9ICJBw7FvIDIwMjAiLCB4ID0gIkVzdGFkb3MiLCB5ID0gIkJpZGVuIikrIA0KICBwTVJUKyBnZW9tX2NvbChmaWxsPSJyZWQiKSsgeWxpbShOQSw1NTAwMDAwKSt0aGVtZV9zb2xhcml6ZWQoKSsNCiAgbGFicyggeCA9ICJFc3RhZG9zIiwgeSA9ICJUcnVtcCIpDQoNCmBgYA0KDQoNCsK/UXVlIGNhbmRpZGF0byBoYSB0ZW5pZG8gbcOhcyBhcG95byBlbiBsYXMgem9uYXMgcG9icmVzPw0KDQpgYGB7ciwgZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFfQ0KI0NvZ2Vtb3MgbG9zIDYgZXN0YWRvcyBjb24gbWVub3MgUElCcGMNCg0KZGZfdm90PC0gcmlvOjppbXBvcnQoaGVyZTo6aGVyZSgiRGF0b3MiLCAiZGZfdm90LmNzdiIpKQ0KDQoNCk1QPC0gZGZfdm90ICU+JSBmaWx0ZXIoc3RhdGUgJWluJSBjKCJNaXNzaXNzaXBwaSIsICJJZGFobyIsDQogICAgICAiQXJrYW5zYXMiLCAiV2VzdCBWaXJnaW5pYSIsIkFsYWJhbWEiLCJTb3V0aCBDYXJvbGluYSIgKSkNCg0KcE1QQjwtIGdncGxvdChNUCwgYWVzKHN0YXRlLEJpZGVuKSkNCg0KcE1QVDwtIGdncGxvdChNUCwgYWVzKHN0YXRlLFRydW1wKSkNCg0KcE1QQiArIGdlb21fY29sKGZpbGw9ImJsdWUiKSArIA0KICBsYWJzKHRpdGxlID0gIkVzdGFkb3MgcG9icmVzIiwgc3VidGl0bGUgPSAiQcOxbyAyMDIwIiwgeCA9ICJFc3RhZG9zIiwgeSA9ICJCaWRlbiIpKw0KICB5bGltKE5BLDIwMDAwMDApK3RoZW1lX3NvbGFyaXplZCgpICsgDQogIHBNUFQrIGdlb21fY29sKGZpbGw9InJlZCIpKyB5bGltKE5BLDIwMDAwMDApK3RoZW1lX3NvbGFyaXplZCgpKw0KICBsYWJzKHggPSAiRXN0YWRvcyIsIHkgPSAiVHJ1bXAiKQ0KDQpgYGANCg0KIyA0LiBDb25jbHVzacOzbg0KDQo8Y2VudGVyPg0KIVtdKEltYWdlbmVzL2dpZi5naWYpe3dpZHRoPSI0NSUifTwvY2VudGVyPg0KDQpVbmEgZGUgbGFzIHByaW5jaXBhbGVzIGNhcmFjdGVyw61zdGFjYXMgZGUgZXN0YXMgZWxlY2Npb25lcyBlcyBsYSBtb3ZpbGl6YWNpw7NuIHF1ZSBoYW4gdGVuaWRvLiBEb25hbGQgVHJ1bXAgeSBKb2UgQmlkZW4gc29uIGxvcyBjYW5kaWRhdG9zIHF1ZSBtw6FzIHZvdG9zIGhhbiByZWNpYmlkbyBlbiBsYSBoaXN0b3JpYS4gVW5hIGRlIGxhcyBjb3NhcyBxdWUgc2UgZGljZSxzb2JyZSBsYSB2aWN0b3JpYSBkZSBKb2UgQmlkZW4sIGVzIHF1ZSBoYSBjb25zZWd1aWRvIG1vdmlsaXphciBhIHRvZG8gZWwgZWxlY3RvcmFkbyBkZW3Ds2NyYXRhIHRyYWRpY2lvbmFseSB0YW1iacOpbiBoYSBjb25zZWd1aWRvIGdhbmFyIGVudHJlIGxvcyBpbmRlcGVuZGllbnRlcy4gT3RyYSBkZSBsYXMgcmF6b25lcywgcXVlIHZhIGVubGF6YWRvIGNvbiBsbyBxdWUgaGUgYW5hbGl6YWRvLCBlcyBsYSB2aWN0b3JpYSBlbiBsYXMgZ3JhbmRlcyBjaXVkYWRlcy4gSGlzdG9yaWNhbWVudGUgbG9zIHN1YnVyYmlvcyBkZSBsYXMgZ3JhbmRlcyBjaXVkYWRlcyBoYWJpYW4gc2lkbyB2b3RhbnRlcyBkZWwgcGFydGlkbyByZXB1YmxpY2FubyBwZXJvIGVuIGVzdGFzIGVsZWNjaW9uZXMgaGEgc2lkbyBkaXN0aW50by4gTG9zIGNpdWRhZGFub3MgZGUgcmVudGFzIG3DoXMgYmFqYXMgZW4gbGFzIGdyYW5kZXMgY2l1ZGFkZXMgaGFuIGRlY2FudGFkbyBzdSB2b3RvIGVuIEpvZSBCaWRlbi4NCg0KDQpgYGB7ciwgZXZhbCA9IFRSVUUsIGVjaG89RkFMU0V9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlOjpoZXJlKCJpbWFnZW5lcyIsICJ0cnVtcC5qcGciKSkNCmBgYA0KDQoNCg0KDQojIDUuIEJpYmxpb2dyYWbDrWENCg0KaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS91bmFuaW1hZC91cy1lbGVjdGlvbi0yMDIwDQoNCmh0dHBzOi8vd3d3LmthZ2dsZS5jb20vbWFyaWFwdXNoa2FyZXZhL2dkcC1wZXItY2FwaXRhLWluLXVzLXN0YXRlcy13aXRoLXRhYmxlYXUvZGF0YT9zZWxlY3Q9YmVhLWdkcC1ieS1zdGF0ZS5jc3Y=