library(tidyverse)
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.1     ✓ purrr   0.3.4
✓ tibble  3.0.1     ✓ dplyr   1.0.0
✓ tidyr   1.1.0     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(leaflet)
library(sf)
Linking to GEOS 3.5.1, GDAL 2.2.2, PROJ 4.9.2
library(readxl)
library(DT)
library(plotly)

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
library(broom)
library(tidycensus)
senate_counties <- read_xlsx("Statewide Results.xlsx", sheet = 1)
New names:
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5

This loads the data.

senate_counties <- read_xlsx("Statewide Results.xlsx", sheet = 1, range = "B7:E63")

This loads the data.

glimpse(senate_counties)
Rows: 56
Columns: 4
$ County                             <chr> "Beaverhead", "Big Horn", "Blaine", "Broadwater", "Carbon", "Carter", "Cascade", "Chout…
$ `JON TESTER\r\nDemocrat`           <dbl> 1876, 3027, 1961, 1071, 2680, 128, 17435, 1275, 1942, 281, 1233, 2892, 281, 1964, 19652…
$ `MATT ROSENDALE\r\nRepublican`     <dbl> 2866, 1558, 982, 2086, 3209, 602, 15566, 1312, 2762, 631, 2700, 1208, 951, 3640, 26759,…
$ `RICK BRECKENRIDGE\r\nLibertarian` <dbl> 155, 91, 76, 104, 178, 22, 1008, 70, 179, 29, 140, 136, 57, 189, 1349, 1434, 30, 89, 21…

This shows a preview of data.

senate_counties <- senate_counties %>% 
  rename(Republican = "MATT ROSENDALE\r\nRepublican") %>% 
  rename(Democrat = "JON TESTER\r\nDemocrat") %>% 
  rename(Libertarian = "RICK BRECKENRIDGE\r\nLibertarian")

senate_counties <- senate_counties %>% 
  mutate(total_votes = Republican + Democrat + Libertarian) %>% 
  mutate(Repub_advantage = Republican/total_votes - Democrat/total_votes) %>% 
  mutate(Repub_advantage = round(Repub_advantage*100, 1))
  senate_counties %>% 
  arrange(-Repub_advantage)

This is a table showing the the votes for the candidates by county a long with the republican advantage of each county.

mt_counties <- get_acs(geography = "county",
                       variables = "B01003_001",
                       state = "MT",
                       geometry = TRUE) 
Getting data from the 2014-2018 5-year ACS
Downloading feature geometry from the Census website.  To cache shapefiles for use in future sessions, set `options(tigris_use_cache = TRUE)`.
Using FIPS code '30' for state 'MT'

This gets data for state.


senate_counties[25, "County"] <- "Lewis and Clark"              # Changes  "&" "and"

mt_counties <- mt_counties %>% 
  mutate(County = gsub(" County, Montana", "", NAME)) %>%      # Removes unnecessary words
  rename(Population = estimate)                                # Renames the 'estimate' to 'Population'

This is just replacing and with & from two mismatched titles.

senate_election <- mt_counties %>% 
  full_join(senate_counties)
Joining, by = "County"

This joins the data from mt counties with the senate race data.

senate_election %>%
  as_tibble() %>% 
  select(County, Population, Democrat, Republican, Libertarian, total_votes, Repub_advantage) %>% 
  datatable()

This is a table showing the counties with thier population and the votes per candidate with the republican advantage.


vote_colors <- colorNumeric(palette = "viridis", domain = senate_election$Repub_advantage)

senate_election %>%
  leaflet() %>% 
  addTiles() %>%
  addPolygons(weight = 1,
              fillColor = ~vote_colors(Repub_advantage), 
              label = ~paste0(County, ", Republican advantage = ", Repub_advantage),
              highlight = highlightOptions(weight = 2)) %>% 
  setView(-110, 47, zoom = 6) %>% 
  addLegend(pal = vote_colors, values = ~Repub_advantage)
sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs ).
Need '+proj=longlat +datum=WGS84'

This shows the republican advantage by county. The lighter or more toward yellow indicates a stronger advantage.

senate_election %>%
  plot_ly(x = ~Population, 
          y = ~Repub_advantage,
          hoverinfo = "text", 
          text = ~paste("County:", 
                        County, "<br>", 
                        "Population: ", Population, "<br>", 
                        "Republican advantage: ", Repub_advantage)) %>% 
  add_markers(marker = list(opacity = 0.7)) %>%
  layout(title = "Predicting Republican Vote Advantage from Population, by County",
         xaxis = list(title = "County population"),
         yaxis = list(title = "Republican vote advantage"))
`arrange_()` is deprecated as of dplyr 0.7.0.
Please use `arrange()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.

This is a plotly graph idicating a negative correllation.

pop_model <- lm(Repub_advantage ~ Population, data = senate_election)

This is a linear regression.

summary(pop_model)

Call:
lm(formula = Repub_advantage ~ Population, data = senate_election)

Residuals:
    Min      1Q  Median      3Q     Max 
-71.228 -12.013   3.247  15.782  47.948 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) 24.2809050  4.0835813   5.946 2.08e-07 ***
Population  -0.0003761  0.0001100  -3.418  0.00121 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 26.44 on 54 degrees of freedom
Multiple R-squared:  0.1779,    Adjusted R-squared:  0.1626 
F-statistic: 11.68 on 1 and 54 DF,  p-value: 0.001207

This is a summary of the regression results.

tidy(pop_model)
glance(pop_model)

This shows the information in a cleaner way.

senate_election %>%
  plot_ly(x = ~Population, 
          y = ~Repub_advantage,
          hoverinfo = "text", 
          text = ~paste("County:", 
                        County, "<br>", 
                        "Population: ", Population, "<br>", 
                        "Republican advantage: ", Repub_advantage)) %>% 
  add_markers(showlegend = F, marker = list(opacity = 0.7)) %>%
  layout(title = "Predicting Republican Vote Advantage from Population, by County",
         xaxis = list(title = "County population"),
         yaxis = list(title = "Republican vote advantage")) %>%
  add_lines(y = ~fitted(pop_model))

This predicts the republican vote advantage from population and by county.

senate_election <- senate_election %>% 
  mutate(Longitude = as_tibble(st_coordinates(st_centroid(senate_election$geometry)))$X) %>% 
  mutate(Latitude = as_tibble(st_coordinates(st_centroid(senate_election$geometry)))$Y)
st_centroid does not give correct centroids for longitude/latitude datast_centroid does not give correct centroids for longitude/latitude data
senate_election %>%
  leaflet() %>% 
  addTiles() %>%
  addPolygons(weight = 1) %>% 
  setView(-110, 47, zoom = 6) %>% 
addCircleMarkers(~Longitude, ~Latitude)
sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs ).
Need '+proj=longlat +datum=WGS84'

This is just another graph showing the center of counties.

senate_election %>%
  plot_ly(x = ~Longitude, y = ~Repub_advantage) %>% 
  add_markers()

This is a plotly graph of the longitute and republican vote indicating a positive correlation that the further east the more votes for republican.

longitude_lm <- lm(Repub_advantage ~ Longitude, data = senate_election)
tidy(longitude_lm)
glance(longitude_lm)

This is a regression predicting republican vote from longitude.

senate_election %>% 
  plot_ly(x = ~Longitude, 
          y = ~Repub_advantage,
          hoverinfo = "text", 
          text = ~paste("County:", County, "<br>", "Longitude: ", Longitude, "<br>", "Republican advantage: ", Repub_advantage)) %>% 
  add_markers(marker = list(opacity = 0.7), showlegend = F) %>%
  layout(title = "Predicting Republican Vote Advantage from Longitude, by County",
         xaxis = list(title = "County longitude"),
         yaxis = list(title = "Republican vote advantage")) %>% 
  add_lines(y = ~fitted(longitude_lm))

This is a plotly graph predicting the republican vote advantage from longitude, by county.

multiple_lm <- lm(Repub_advantage ~ Population + Longitude, data = senate_election)
tidy(multiple_lm)
glance(multiple_lm)

This is a multiple regression, predicting the Republican advantage from both Population and Longitude at the same time.

senate_election %>% 
  plot_ly(x = ~Longitude, y = ~Population, z = ~Repub_advantage, 
          text = ~County, hoverinfo = "text") %>% 
  add_markers(opacity = .7, showlegend = F)

This is a 3D scatterplot showing the republican advantage, population, and votes per longitudinal data.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CmVkaXRvcl9vcHRpb25zOgogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobGVhZmxldCkKbGlicmFyeShzZikKbGlicmFyeShyZWFkeGwpCmxpYnJhcnkoRFQpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KHRpZHljZW5zdXMpCmBgYAoKYGBge3J9CnNlbmF0ZV9jb3VudGllcyA8LSByZWFkX3hsc3goIlN0YXRld2lkZSBSZXN1bHRzLnhsc3giLCBzaGVldCA9IDEpCmBgYApUaGlzIGxvYWRzIHRoZSBkYXRhLgoKYGBge3J9CnNlbmF0ZV9jb3VudGllcyA8LSByZWFkX3hsc3goIlN0YXRld2lkZSBSZXN1bHRzLnhsc3giLCBzaGVldCA9IDEsIHJhbmdlID0gIkI3OkU2MyIpCmBgYApUaGlzIGxvYWRzIHRoZSBkYXRhLgoKYGBge3J9CmdsaW1wc2Uoc2VuYXRlX2NvdW50aWVzKQpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9CmNlbnN1c19hcGlfa2V5KCI0MTVjN2I5YjkzOGIyMDMyYmI0OGMyYTAyMDNiMDA1OWNlZWNlMjA5Iiwgb3ZlcndyaXRlID0gVFJVRSwgaW5zdGFsbCA9IFRSVUUpCgpgYGAKCmBgYHtyIGluY2x1ZGU9RkFMU0V9Cm10X2NvdW50aWVzIDwtIGdldF9hY3MoZ2VvZ3JhcGh5ID0gImNvdW50eSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGVzID0gIkIwMTAwM18wMDEiLAogICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gIk1UIiwKICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFRSVUUpIApgYGAKCgpUaGlzIHNob3dzIGEgcHJldmlldyBvZiBkYXRhLgoKYGBge3J9CnNlbmF0ZV9jb3VudGllcyA8LSBzZW5hdGVfY291bnRpZXMgJT4lIAogIHJlbmFtZShSZXB1YmxpY2FuID0gIk1BVFQgUk9TRU5EQUxFXHJcblJlcHVibGljYW4iKSAlPiUgCiAgcmVuYW1lKERlbW9jcmF0ID0gIkpPTiBURVNURVJcclxuRGVtb2NyYXQiKSAlPiUgCiAgcmVuYW1lKExpYmVydGFyaWFuID0gIlJJQ0sgQlJFQ0tFTlJJREdFXHJcbkxpYmVydGFyaWFuIikKYGBgCgpgYGB7cn0KCnNlbmF0ZV9jb3VudGllcyA8LSBzZW5hdGVfY291bnRpZXMgJT4lIAogIG11dGF0ZSh0b3RhbF92b3RlcyA9IFJlcHVibGljYW4gKyBEZW1vY3JhdCArIExpYmVydGFyaWFuKSAlPiUgCiAgbXV0YXRlKFJlcHViX2FkdmFudGFnZSA9IFJlcHVibGljYW4vdG90YWxfdm90ZXMgLSBEZW1vY3JhdC90b3RhbF92b3RlcykgJT4lIAogIG11dGF0ZShSZXB1Yl9hZHZhbnRhZ2UgPSByb3VuZChSZXB1Yl9hZHZhbnRhZ2UqMTAwLCAxKSkKICBzZW5hdGVfY291bnRpZXMgJT4lIAogIGFycmFuZ2UoLVJlcHViX2FkdmFudGFnZSkKYGBgClRoaXMgaXMgYSB0YWJsZSBzaG93aW5nIHRoZSB0aGUgdm90ZXMgZm9yIHRoZSBjYW5kaWRhdGVzIGJ5IGNvdW50eSBhIGxvbmcgd2l0aCB0aGUgcmVwdWJsaWNhbiBhZHZhbnRhZ2Ugb2YgZWFjaCBjb3VudHkuCgpgYGB7cn0KbXRfY291bnRpZXMgPC0gZ2V0X2FjcyhnZW9ncmFwaHkgPSAiY291bnR5IiwKICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXMgPSAiQjAxMDAzXzAwMSIsCiAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUgPSAiTVQiLAogICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5ID0gVFJVRSkgCmBgYApUaGlzIGdldHMgZGF0YSBmb3Igc3RhdGUuCmBgYHtyfQoKc2VuYXRlX2NvdW50aWVzWzI1LCAiQ291bnR5Il0gPC0gIkxld2lzIGFuZCBDbGFyayIgICAgICAgICAgICAgICMgQ2hhbmdlcyAgIiYiICJhbmQiCgptdF9jb3VudGllcyA8LSBtdF9jb3VudGllcyAlPiUgCiAgbXV0YXRlKENvdW50eSA9IGdzdWIoIiBDb3VudHksIE1vbnRhbmEiLCAiIiwgTkFNRSkpICU+JSAgICAgICMgUmVtb3ZlcyB1bm5lY2Vzc2FyeSB3b3JkcwogIHJlbmFtZShQb3B1bGF0aW9uID0gZXN0aW1hdGUpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlbmFtZXMgdGhlICdlc3RpbWF0ZScgdG8gJ1BvcHVsYXRpb24nCmBgYApUaGlzIGlzIGp1c3QgcmVwbGFjaW5nIGFuZCB3aXRoICYgZnJvbSB0d28gbWlzbWF0Y2hlZCB0aXRsZXMuCmBgYHtyfQpzZW5hdGVfZWxlY3Rpb24gPC0gbXRfY291bnRpZXMgJT4lIAogIGZ1bGxfam9pbihzZW5hdGVfY291bnRpZXMpCmBgYApUaGlzIGpvaW5zIHRoZSBkYXRhIGZyb20gbXQgY291bnRpZXMgd2l0aCB0aGUgc2VuYXRlIHJhY2UgZGF0YS4KYGBge3J9CnNlbmF0ZV9lbGVjdGlvbiAlPiUKICBhc190aWJibGUoKSAlPiUgCiAgc2VsZWN0KENvdW50eSwgUG9wdWxhdGlvbiwgRGVtb2NyYXQsIFJlcHVibGljYW4sIExpYmVydGFyaWFuLCB0b3RhbF92b3RlcywgUmVwdWJfYWR2YW50YWdlKSAlPiUgCiAgZGF0YXRhYmxlKCkKYGBgClRoaXMgaXMgYSB0YWJsZSBzaG93aW5nIHRoZSBjb3VudGllcyB3aXRoIHRoaWVyIHBvcHVsYXRpb24gYW5kIHRoZSB2b3RlcyBwZXIgY2FuZGlkYXRlIHdpdGggdGhlIHJlcHVibGljYW4gYWR2YW50YWdlLgpgYGB7cn0KCnZvdGVfY29sb3JzIDwtIGNvbG9yTnVtZXJpYyhwYWxldHRlID0gInZpcmlkaXMiLCBkb21haW4gPSBzZW5hdGVfZWxlY3Rpb24kUmVwdWJfYWR2YW50YWdlKQoKc2VuYXRlX2VsZWN0aW9uICU+JQogIGxlYWZsZXQoKSAlPiUgCiAgYWRkVGlsZXMoKSAlPiUKICBhZGRQb2x5Z29ucyh3ZWlnaHQgPSAxLAogICAgICAgICAgICAgIGZpbGxDb2xvciA9IH52b3RlX2NvbG9ycyhSZXB1Yl9hZHZhbnRhZ2UpLCAKICAgICAgICAgICAgICBsYWJlbCA9IH5wYXN0ZTAoQ291bnR5LCAiLCBSZXB1YmxpY2FuIGFkdmFudGFnZSA9ICIsIFJlcHViX2FkdmFudGFnZSksCiAgICAgICAgICAgICAgaGlnaGxpZ2h0ID0gaGlnaGxpZ2h0T3B0aW9ucyh3ZWlnaHQgPSAyKSkgJT4lIAogIHNldFZpZXcoLTExMCwgNDcsIHpvb20gPSA2KSAlPiUgCiAgYWRkTGVnZW5kKHBhbCA9IHZvdGVfY29sb3JzLCB2YWx1ZXMgPSB+UmVwdWJfYWR2YW50YWdlKQoKYGBgClRoaXMgc2hvd3MgdGhlIHJlcHVibGljYW4gYWR2YW50YWdlIGJ5IGNvdW50eS4gVGhlIGxpZ2h0ZXIgb3IgbW9yZSB0b3dhcmQgeWVsbG93IGluZGljYXRlcyBhIHN0cm9uZ2VyIGFkdmFudGFnZS4KCmBgYHtyfQpzZW5hdGVfZWxlY3Rpb24gJT4lCiAgcGxvdF9seSh4ID0gflBvcHVsYXRpb24sIAogICAgICAgICAgeSA9IH5SZXB1Yl9hZHZhbnRhZ2UsCiAgICAgICAgICBob3ZlcmluZm8gPSAidGV4dCIsIAogICAgICAgICAgdGV4dCA9IH5wYXN0ZSgiQ291bnR5OiIsIAogICAgICAgICAgICAgICAgICAgICAgICBDb3VudHksICI8YnI+IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICJQb3B1bGF0aW9uOiAiLCBQb3B1bGF0aW9uLCAiPGJyPiIsIAogICAgICAgICAgICAgICAgICAgICAgICAiUmVwdWJsaWNhbiBhZHZhbnRhZ2U6ICIsIFJlcHViX2FkdmFudGFnZSkpICU+JSAKICBhZGRfbWFya2VycyhtYXJrZXIgPSBsaXN0KG9wYWNpdHkgPSAwLjcpKSAlPiUKICBsYXlvdXQodGl0bGUgPSAiUHJlZGljdGluZyBSZXB1YmxpY2FuIFZvdGUgQWR2YW50YWdlIGZyb20gUG9wdWxhdGlvbiwgYnkgQ291bnR5IiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkNvdW50eSBwb3B1bGF0aW9uIiksCiAgICAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJSZXB1YmxpY2FuIHZvdGUgYWR2YW50YWdlIikpCmBgYApUaGlzIGlzIGEgcGxvdGx5IGdyYXBoIGlkaWNhdGluZyBhIG5lZ2F0aXZlIGNvcnJlbGxhdGlvbi4KYGBge3J9CnBvcF9tb2RlbCA8LSBsbShSZXB1Yl9hZHZhbnRhZ2UgfiBQb3B1bGF0aW9uLCBkYXRhID0gc2VuYXRlX2VsZWN0aW9uKQoKYGBgClRoaXMgaXMgYSBsaW5lYXIgcmVncmVzc2lvbi4KYGBge3J9CnN1bW1hcnkocG9wX21vZGVsKQpgYGAKVGhpcyBpcyBhIHN1bW1hcnkgb2YgdGhlIHJlZ3Jlc3Npb24gcmVzdWx0cy4KYGBge3J9CnRpZHkocG9wX21vZGVsKQpnbGFuY2UocG9wX21vZGVsKQpgYGAKVGhpcyBzaG93cyB0aGUgaW5mb3JtYXRpb24gaW4gYSBjbGVhbmVyIHdheS4KCmBgYHtyfQpzZW5hdGVfZWxlY3Rpb24gJT4lCiAgcGxvdF9seSh4ID0gflBvcHVsYXRpb24sIAogICAgICAgICAgeSA9IH5SZXB1Yl9hZHZhbnRhZ2UsCiAgICAgICAgICBob3ZlcmluZm8gPSAidGV4dCIsIAogICAgICAgICAgdGV4dCA9IH5wYXN0ZSgiQ291bnR5OiIsIAogICAgICAgICAgICAgICAgICAgICAgICBDb3VudHksICI8YnI+IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICJQb3B1bGF0aW9uOiAiLCBQb3B1bGF0aW9uLCAiPGJyPiIsIAogICAgICAgICAgICAgICAgICAgICAgICAiUmVwdWJsaWNhbiBhZHZhbnRhZ2U6ICIsIFJlcHViX2FkdmFudGFnZSkpICU+JSAKICBhZGRfbWFya2VycyhzaG93bGVnZW5kID0gRiwgbWFya2VyID0gbGlzdChvcGFjaXR5ID0gMC43KSkgJT4lCiAgbGF5b3V0KHRpdGxlID0gIlByZWRpY3RpbmcgUmVwdWJsaWNhbiBWb3RlIEFkdmFudGFnZSBmcm9tIFBvcHVsYXRpb24sIGJ5IENvdW50eSIsCiAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJDb3VudHkgcG9wdWxhdGlvbiIpLAogICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiUmVwdWJsaWNhbiB2b3RlIGFkdmFudGFnZSIpKSAlPiUKICBhZGRfbGluZXMoeSA9IH5maXR0ZWQocG9wX21vZGVsKSkKYGBgClRoaXMgcHJlZGljdHMgdGhlIHJlcHVibGljYW4gdm90ZSBhZHZhbnRhZ2UgZnJvbSBwb3B1bGF0aW9uIGFuZCBieSBjb3VudHkuCgpgYGB7ciBlY2hvPVRSVUV9CnNlbmF0ZV9lbGVjdGlvbiA8LSBzZW5hdGVfZWxlY3Rpb24gJT4lIAogIG11dGF0ZShMb25naXR1ZGUgPSBhc190aWJibGUoc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoc2VuYXRlX2VsZWN0aW9uJGdlb21ldHJ5KSkpJFgpICU+JSAKICBtdXRhdGUoTGF0aXR1ZGUgPSBhc190aWJibGUoc3RfY29vcmRpbmF0ZXMoc3RfY2VudHJvaWQoc2VuYXRlX2VsZWN0aW9uJGdlb21ldHJ5KSkpJFkpCmBgYApgYGB7cn0Kc2VuYXRlX2VsZWN0aW9uICU+JQogIGxlYWZsZXQoKSAlPiUgCiAgYWRkVGlsZXMoKSAlPiUKICBhZGRQb2x5Z29ucyh3ZWlnaHQgPSAxKSAlPiUgCiAgc2V0VmlldygtMTEwLCA0Nywgem9vbSA9IDYpICU+JSAKYWRkQ2lyY2xlTWFya2Vycyh+TG9uZ2l0dWRlLCB+TGF0aXR1ZGUpCmBgYApUaGlzIGlzIGp1c3QgYW5vdGhlciBncmFwaCBzaG93aW5nIHRoZSBjZW50ZXIgb2YgY291bnRpZXMuCmBgYHtyfQpzZW5hdGVfZWxlY3Rpb24gJT4lCiAgcGxvdF9seSh4ID0gfkxvbmdpdHVkZSwgeSA9IH5SZXB1Yl9hZHZhbnRhZ2UpICU+JSAKICBhZGRfbWFya2VycygpCmBgYApUaGlzIGlzIGEgcGxvdGx5IGdyYXBoIG9mIHRoZSBsb25naXR1dGUgYW5kIHJlcHVibGljYW4gdm90ZSBpbmRpY2F0aW5nIGEgcG9zaXRpdmUgY29ycmVsYXRpb24gdGhhdCB0aGUgZnVydGhlciBlYXN0IHRoZSBtb3JlIHZvdGVzIGZvciByZXB1YmxpY2FuLgpgYGB7cn0KbG9uZ2l0dWRlX2xtIDwtIGxtKFJlcHViX2FkdmFudGFnZSB+IExvbmdpdHVkZSwgZGF0YSA9IHNlbmF0ZV9lbGVjdGlvbikKdGlkeShsb25naXR1ZGVfbG0pCmdsYW5jZShsb25naXR1ZGVfbG0pCmBgYApUaGlzIGlzIGEgcmVncmVzc2lvbiBwcmVkaWN0aW5nIHJlcHVibGljYW4gdm90ZSBmcm9tIGxvbmdpdHVkZS4KYGBge3J9CnNlbmF0ZV9lbGVjdGlvbiAlPiUgCiAgcGxvdF9seSh4ID0gfkxvbmdpdHVkZSwgCiAgICAgICAgICB5ID0gflJlcHViX2FkdmFudGFnZSwKICAgICAgICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwgCiAgICAgICAgICB0ZXh0ID0gfnBhc3RlKCJDb3VudHk6IiwgQ291bnR5LCAiPGJyPiIsICJMb25naXR1ZGU6ICIsIExvbmdpdHVkZSwgIjxicj4iLCAiUmVwdWJsaWNhbiBhZHZhbnRhZ2U6ICIsIFJlcHViX2FkdmFudGFnZSkpICU+JSAKICBhZGRfbWFya2VycyhtYXJrZXIgPSBsaXN0KG9wYWNpdHkgPSAwLjcpLCBzaG93bGVnZW5kID0gRikgJT4lCiAgbGF5b3V0KHRpdGxlID0gIlByZWRpY3RpbmcgUmVwdWJsaWNhbiBWb3RlIEFkdmFudGFnZSBmcm9tIExvbmdpdHVkZSwgYnkgQ291bnR5IiwKICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkNvdW50eSBsb25naXR1ZGUiKSwKICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlJlcHVibGljYW4gdm90ZSBhZHZhbnRhZ2UiKSkgJT4lIAogIGFkZF9saW5lcyh5ID0gfmZpdHRlZChsb25naXR1ZGVfbG0pKQpgYGAKVGhpcyBpcyBhIHBsb3RseSBncmFwaCBwcmVkaWN0aW5nIHRoZSByZXB1YmxpY2FuIHZvdGUgYWR2YW50YWdlIGZyb20gbG9uZ2l0dWRlLCBieSBjb3VudHkuCmBgYHtyfQptdWx0aXBsZV9sbSA8LSBsbShSZXB1Yl9hZHZhbnRhZ2UgfiBQb3B1bGF0aW9uICsgTG9uZ2l0dWRlLCBkYXRhID0gc2VuYXRlX2VsZWN0aW9uKQp0aWR5KG11bHRpcGxlX2xtKQpnbGFuY2UobXVsdGlwbGVfbG0pCmBgYApUaGlzIGlzIGEgbXVsdGlwbGUgcmVncmVzc2lvbiwgcHJlZGljdGluZyB0aGUgUmVwdWJsaWNhbiBhZHZhbnRhZ2UgZnJvbSBib3RoIFBvcHVsYXRpb24gYW5kIExvbmdpdHVkZSBhdCB0aGUgc2FtZSB0aW1lLgpgYGB7cn0Kc2VuYXRlX2VsZWN0aW9uICU+JSAKICBwbG90X2x5KHggPSB+TG9uZ2l0dWRlLCB5ID0gflBvcHVsYXRpb24sIHogPSB+UmVwdWJfYWR2YW50YWdlLCAKICAgICAgICAgIHRleHQgPSB+Q291bnR5LCBob3ZlcmluZm8gPSAidGV4dCIpICU+JSAKICBhZGRfbWFya2VycyhvcGFjaXR5ID0gLjcsIHNob3dsZWdlbmQgPSBGKQpgYGAKVGhpcyBpcyBhIDNEIHNjYXR0ZXJwbG90IHNob3dpbmcgdGhlIHJlcHVibGljYW4gYWR2YW50YWdlLCBwb3B1bGF0aW9uLCBhbmQgdm90ZXMgcGVyIGxvbmdpdHVkaW5hbCBkYXRhLgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgo=