1 Importing and Filtering Data

The code below performs the following steps on U.S. Presidential Election data from 2000 to 2020: It reads the data, ensuring no missing values are present, and formats the county FIPS codes with leading zeros to maintain standardization. It filters the dataset to include only the major parties, Democrat and Republican, and calculates the vote percentage to two decimal points for each candidate. The data is then grouped by state, county, and year for organized analysis. Within each group, the entry with the highest vote percentage is selected, indicating the winning party in each county. For the state election data, groups of the data by year, state, and party are created to calculate the sum of candidatevotes and totalvotes for each group. Then, it adds a new column percentage to store the percentage of votes each party received within a state for a given year. The data is filtered to identify the winning party for each state and year combination, defined as the party with the maximum percentage of votes. The data is exported to two new CSV files for visualization. Each step is executed to transform the raw data into insightful information that reveals electoral trends over the twenty-year period.

#Read the Presidential Election 2000 to 2020 data
electionData <- na.omit(read.csv("https://tkelleman.github.io/tkweb/Week9/PresidentialElection2000To2020.csv"))
electionData$county_fips <- sprintf("%05d", as.numeric(electionData$county_fips))
electionData$county_fips <- as.character(electionData$county_fips)
 
#Question 2A 
#Filter to only include Democrat and Republican and create a votePercentage variable with 2 decimal points
electionData <- filter(electionData, party == "DEMOCRAT" | party == "REPUBLICAN") %>%
mutate(votePercent = round((candidatevotes/totalvotes)*100, 2))

#Group Data by state_po and county_fips, year
groupedData <- group_by(electionData, state_po, county_fips, year)

#Use slice to keep only the row with the highest votePercent within each group
electionDataHighest <- groupedData %>%
  slice(which.max(votePercent))

#Export CSV
write.csv(electionDataHighest, "ElectionDataHighest.csv", row.names = FALSE)

# Question 2B
electionData <- electionData %>%
  group_by(year, state, party) %>%
  summarise(candidatevotes = sum(candidatevotes), totalvotes = sum(totalvotes)) %>%
  mutate(percentage = (candidatevotes / totalvotes) * 100) %>%
  ungroup()

# Filter for the winning party in each state
winningParties <- electionData %>%
  group_by(year, state) %>%
  filter(percentage == max(percentage)) %>%
  ungroup()
write.csv(winningParties, "ElectionDataState.csv", row.names = FALSE)

2 US Presidental Election Winner by County (2000-2020) - Tableau Interactive Map

This interactive choropleth map allows users to select U.S. Presidential election years from 2000 to 2020 to view the winning candidates by county. By hovering over the map, users can access details such as the year, state, county, winning party, winning candidate, vote percentage, and total votes. The map also enables users to compare different election cycles to identify counties that have switched parties. Incorporating additional data, like median salary and demographics, could provide deeper insights into the trends influencing electoral outcomes.

3 US Presidental Election Winner by State (2000-2020) - Tableau Interactive Map

This interactive choropleth map allows users to select U.S. Presidential election years from 2000 to 2020 to view the winning candidates by State By hovering over the map, users can access details such as the year, state, winning party, vote percentage, and total votes. The map also enables users to compare different election cycles to identify states that have switched parties.

LS0tDQp0aXRsZTogIldlZWsgOSAtIEludGVyYWN0aXZlIFZpc3VhbGl6YXRpb24gd2l0aCBUYWJsZWF1Ig0KYXV0aG9yOiAiVGltIEtlbGxlbWFuIg0KZGF0ZTogIjIwMjQtMDQtMyINCg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IG5vDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBmaWdfd2lkdGg6IDgNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlDQogICAgdGhlbWU6IHJlYWRhYmxlDQogICANCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IG5vDQogICAgdG9jX2RlcHRoOiA0DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgZmlnX3dpZHRoOiA1DQogICAgZmlnX2hlaWdodDogNA0KLS0tDQoNCmBgYHs9aHRtbH0NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQoNCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWNvbG9yOmxpZ2h0Z3JheTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQogICAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgY29sb3I6ICM3ODBjMGM7DQp9DQoNCi8qIG1vdXNlIG92ZXIgbGluayAqLw0KZGl2I1RPQyBhOmhvdmVyIHsNCiAgY29sb3I6IHJlZDsNCn0NCg0KLyogdW52aXNpdGVkIGxpbmsgKi8NCmRpdiNUT0MgYTpsaW5rIHsNCiAgY29sb3I6IGJsdWU7DQp9DQoNCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya2JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogIGZvbnQtdmFyaWFudC1jYXBzOiBub3JtYWw7DQp9DQpoNC5hdXRob3IgeyANCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsNCiAgICBmb250LXNpemU6IDI0cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgew0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IA0KICAgIGZvbnQtc2l6ZTogMTVweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIHVudmlzaXRlZCBsaW5rICovDQphOmxpbmsgew0KICBjb2xvcjogZ3JlZW47DQp9DQoNCi8qIHZpc2l0ZWQgbGluayAqLw0KYTp2aXNpdGVkIHsNCiAgY29sb3I6IGdyZWVuOw0KfQ0KDQovKiBtb3VzZSBvdmVyIGxpbmsgKi8NCmE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiBzZWxlY3RlZCBsaW5rICovDQphOmFjdGl2ZSB7DQogIGNvbG9yOiB5ZWxsb3c7DQp9DQo8L3N0eWxlPg0KYGBgDQotLS0NCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQpvcHRpb25zKHJlcG9zID0gbGlzdChDUkFOPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCiAgIGxpYnJhcnkoY293cGxvdCkNCn0NCmlmICghcmVxdWlyZSgibGF0ZXgyZXhwIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImxhdGV4MmV4cCIpDQogICBsaWJyYXJ5KGxhdGV4MmV4cCkNCn0NCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZ2FwbWluZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdhcG1pbmRlciIpDQogICBsaWJyYXJ5KGdhcG1pbmRlcikNCn0NCmlmICghcmVxdWlyZSgicG5nIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJwbmciKSAgICAgICAgICAgICAjIEluc3RhbGwgcG5nIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJwbmciKQ0KfQ0KaWYgKCFyZXF1aXJlKCJSQ3VybCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiUkN1cmwiKSAgICAgICAgICAgIyBJbnN0YWxsIFJDdXJsIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJSQ3VybCIpDQp9DQppZiAoIXJlcXVpcmUoImNvbG91cnBpY2tlciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImNvbG91cnBpY2tlciIpDQp9DQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdpZnNraSIpDQp9DQppZiAoIXJlcXVpcmUoIm1hZ2ljayIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm1hZ2ljayIpDQp9DQppZiAoIXJlcXVpcmUoImdyRGV2aWNlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JEZXZpY2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyRGV2aWNlcyIpDQp9DQojIyMgZ2dwbG90IGFuZCBleHRlbnNpb25zDQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dwbG90MiIpDQp9DQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdnYW5pbWF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoImdncmlkZ2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ3JpZGdlcyIpDQp9DQppZiAoIXJlcXVpcmUoImdyYXBoaWNzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJncmFwaGljcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJncmFwaGljcyIpDQp9DQppZiAoIXJlcXVpcmUoImRwbHlyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJkcGx5ciIpDQp9DQppZiAoIXJlcXVpcmUoImx1YnJpZGF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibHVicmlkYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImx1YnJpZGF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoInRtYXAiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInRtYXAiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgidG1hcCIpDQp9DQppZiAoIXJlcXVpcmUoInNmIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJzZiIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJzZiIpDQp9DQoNCmlmICghcmVxdWlyZSgibGVhZmxldCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibGVhZmxldCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJsZWFmbGV0IikNCn0NCmlmICghcmVxdWlyZSgibGVhZnBvcCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibGVhZnBvcCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJsZWFmcG9wIikNCn0NCmlmICghcmVxdWlyZSgiaHRtbHRvb2xzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJodG1sdG9vbHMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiaHRtbHRvb2xzIikNCn0NCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQojIEltcG9ydGluZyBhbmQgRmlsdGVyaW5nIERhdGENClRoZSBjb2RlIGJlbG93IHBlcmZvcm1zIHRoZSBmb2xsb3dpbmcgc3RlcHMgb24gVS5TLiBQcmVzaWRlbnRpYWwgRWxlY3Rpb24gZGF0YSBmcm9tIDIwMDAgdG8gMjAyMDogSXQgcmVhZHMgdGhlIGRhdGEsIGVuc3VyaW5nIG5vIG1pc3NpbmcgdmFsdWVzIGFyZSBwcmVzZW50LCBhbmQgZm9ybWF0cyB0aGUgY291bnR5IEZJUFMgY29kZXMgd2l0aCBsZWFkaW5nIHplcm9zIHRvIG1haW50YWluIHN0YW5kYXJkaXphdGlvbi4gSXQgZmlsdGVycyB0aGUgZGF0YXNldCB0byBpbmNsdWRlIG9ubHkgdGhlIG1ham9yIHBhcnRpZXMsIERlbW9jcmF0IGFuZCBSZXB1YmxpY2FuLCBhbmQgY2FsY3VsYXRlcyB0aGUgdm90ZSBwZXJjZW50YWdlIHRvIHR3byBkZWNpbWFsIHBvaW50cyBmb3IgZWFjaCBjYW5kaWRhdGUuIFRoZSBkYXRhIGlzIHRoZW4gZ3JvdXBlZCBieSBzdGF0ZSwgY291bnR5LCBhbmQgeWVhciBmb3Igb3JnYW5pemVkIGFuYWx5c2lzLiBXaXRoaW4gZWFjaCBncm91cCwgdGhlIGVudHJ5IHdpdGggdGhlIGhpZ2hlc3Qgdm90ZSBwZXJjZW50YWdlIGlzIHNlbGVjdGVkLCBpbmRpY2F0aW5nIHRoZSB3aW5uaW5nIHBhcnR5IGluIGVhY2ggY291bnR5LiBGb3IgdGhlIHN0YXRlIGVsZWN0aW9uIGRhdGEsICBncm91cHMgb2YgdGhlIGRhdGEgYnkgeWVhciwgc3RhdGUsIGFuZCBwYXJ0eSBhcmUgY3JlYXRlZCB0byBjYWxjdWxhdGUgdGhlIHN1bSBvZiBjYW5kaWRhdGV2b3RlcyBhbmQgdG90YWx2b3RlcyBmb3IgZWFjaCBncm91cC4gVGhlbiwgaXQgYWRkcyBhIG5ldyBjb2x1bW4gcGVyY2VudGFnZSB0byBzdG9yZSB0aGUgcGVyY2VudGFnZSBvZiB2b3RlcyBlYWNoIHBhcnR5IHJlY2VpdmVkIHdpdGhpbiBhIHN0YXRlIGZvciBhIGdpdmVuIHllYXIuIFRoZSBkYXRhIGlzIGZpbHRlcmVkIHRvIGlkZW50aWZ5IHRoZSB3aW5uaW5nIHBhcnR5IGZvciBlYWNoIHN0YXRlIGFuZCB5ZWFyIGNvbWJpbmF0aW9uLCBkZWZpbmVkIGFzIHRoZSBwYXJ0eSB3aXRoIHRoZSBtYXhpbXVtIHBlcmNlbnRhZ2Ugb2Ygdm90ZXMuIFRoZSBkYXRhIGlzIGV4cG9ydGVkIHRvIHR3byBuZXcgQ1NWIGZpbGVzIGZvciB2aXN1YWxpemF0aW9uLiBFYWNoIHN0ZXAgaXMgZXhlY3V0ZWQgdG8gdHJhbnNmb3JtIHRoZSByYXcgZGF0YSBpbnRvIGluc2lnaHRmdWwgaW5mb3JtYXRpb24gdGhhdCByZXZlYWxzIGVsZWN0b3JhbCB0cmVuZHMgb3ZlciB0aGUgdHdlbnR5LXllYXIgcGVyaW9kLg0KYGBge3IgZXZhbD1UUlVFfQ0KI1JlYWQgdGhlIFByZXNpZGVudGlhbCBFbGVjdGlvbiAyMDAwIHRvIDIwMjAgZGF0YQ0KZWxlY3Rpb25EYXRhIDwtIG5hLm9taXQocmVhZC5jc3YoImh0dHBzOi8vdGtlbGxlbWFuLmdpdGh1Yi5pby90a3dlYi9XZWVrOS9QcmVzaWRlbnRpYWxFbGVjdGlvbjIwMDBUbzIwMjAuY3N2IikpDQplbGVjdGlvbkRhdGEkY291bnR5X2ZpcHMgPC0gc3ByaW50ZigiJTA1ZCIsIGFzLm51bWVyaWMoZWxlY3Rpb25EYXRhJGNvdW50eV9maXBzKSkNCmVsZWN0aW9uRGF0YSRjb3VudHlfZmlwcyA8LSBhcy5jaGFyYWN0ZXIoZWxlY3Rpb25EYXRhJGNvdW50eV9maXBzKQ0KIA0KI1F1ZXN0aW9uIDJBIA0KI0ZpbHRlciB0byBvbmx5IGluY2x1ZGUgRGVtb2NyYXQgYW5kIFJlcHVibGljYW4gYW5kIGNyZWF0ZSBhIHZvdGVQZXJjZW50YWdlIHZhcmlhYmxlIHdpdGggMiBkZWNpbWFsIHBvaW50cw0KZWxlY3Rpb25EYXRhIDwtIGZpbHRlcihlbGVjdGlvbkRhdGEsIHBhcnR5ID09ICJERU1PQ1JBVCIgfCBwYXJ0eSA9PSAiUkVQVUJMSUNBTiIpICU+JQ0KbXV0YXRlKHZvdGVQZXJjZW50ID0gcm91bmQoKGNhbmRpZGF0ZXZvdGVzL3RvdGFsdm90ZXMpKjEwMCwgMikpDQoNCiNHcm91cCBEYXRhIGJ5IHN0YXRlX3BvIGFuZCBjb3VudHlfZmlwcywgeWVhcg0KZ3JvdXBlZERhdGEgPC0gZ3JvdXBfYnkoZWxlY3Rpb25EYXRhLCBzdGF0ZV9wbywgY291bnR5X2ZpcHMsIHllYXIpDQoNCiNVc2Ugc2xpY2UgdG8ga2VlcCBvbmx5IHRoZSByb3cgd2l0aCB0aGUgaGlnaGVzdCB2b3RlUGVyY2VudCB3aXRoaW4gZWFjaCBncm91cA0KZWxlY3Rpb25EYXRhSGlnaGVzdCA8LSBncm91cGVkRGF0YSAlPiUNCiAgc2xpY2Uod2hpY2gubWF4KHZvdGVQZXJjZW50KSkNCg0KI0V4cG9ydCBDU1YNCndyaXRlLmNzdihlbGVjdGlvbkRhdGFIaWdoZXN0LCAiRWxlY3Rpb25EYXRhSGlnaGVzdC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KIyBRdWVzdGlvbiAyQg0KZWxlY3Rpb25EYXRhIDwtIGVsZWN0aW9uRGF0YSAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgc3RhdGUsIHBhcnR5KSAlPiUNCiAgc3VtbWFyaXNlKGNhbmRpZGF0ZXZvdGVzID0gc3VtKGNhbmRpZGF0ZXZvdGVzKSwgdG90YWx2b3RlcyA9IHN1bSh0b3RhbHZvdGVzKSkgJT4lDQogIG11dGF0ZShwZXJjZW50YWdlID0gKGNhbmRpZGF0ZXZvdGVzIC8gdG90YWx2b3RlcykgKiAxMDApICU+JQ0KICB1bmdyb3VwKCkNCg0KIyBGaWx0ZXIgZm9yIHRoZSB3aW5uaW5nIHBhcnR5IGluIGVhY2ggc3RhdGUNCndpbm5pbmdQYXJ0aWVzIDwtIGVsZWN0aW9uRGF0YSAlPiUNCiAgZ3JvdXBfYnkoeWVhciwgc3RhdGUpICU+JQ0KICBmaWx0ZXIocGVyY2VudGFnZSA9PSBtYXgocGVyY2VudGFnZSkpICU+JQ0KICB1bmdyb3VwKCkNCndyaXRlLmNzdih3aW5uaW5nUGFydGllcywgIkVsZWN0aW9uRGF0YVN0YXRlLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQpgYGANCg0KDQojIFVTIFByZXNpZGVudGFsIEVsZWN0aW9uIFdpbm5lciBieSBDb3VudHkgKDIwMDAtMjAyMCkgLSBUYWJsZWF1IEludGVyYWN0aXZlIE1hcA0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Ka25pdHI6OmluY2x1ZGVfdXJsKCJodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9VU1ByZXNpZGVudGlhbEVsZWN0aW9uV2lubmVyYnlDb3VudHkyMDAwLTIwMjAvU2hlZXQxPzplbWJlZD15JjpzaG93Vml6SG9tZT1ubyY6aG9zdF91cmw9aHR0cHMlM0ElMkYlMkZwdWJsaWMudGFibGVhdS5jb20lMkYmOmVtYmVkX2NvZGVfdmVyc2lvbj0zJjp0YWJzPW5vJjp0b29sYmFyPXllcyY6YW5pbWF0ZV90cmFuc2l0aW9uPXllcyY6ZGlzcGxheV9zdGF0aWNfaW1hZ2U9bm8mOmRpc3BsYXlfc3Bpbm5lcj1ubyY6ZGlzcGxheV9vdmVybGF5PXllcyY6ZGlzcGxheV9jb3VudD15ZXMmOmxhbmd1YWdlPWVuLVVTJnB1Ymxpc2g9eWVzJjpsb2FkT3JkZXJJRD0wJjppbmNyZW1lbnRfdmlld19jb3VudD1ubyMxIiwgaGVpZ2h0ID0gIjUwMHB4IikNCmBgYA0KDQpUaGlzIGludGVyYWN0aXZlIGNob3JvcGxldGggbWFwIGFsbG93cyB1c2VycyB0byBzZWxlY3QgVS5TLiBQcmVzaWRlbnRpYWwgZWxlY3Rpb24geWVhcnMgZnJvbSAyMDAwIHRvIDIwMjAgdG8gdmlldyB0aGUgd2lubmluZyBjYW5kaWRhdGVzIGJ5IGNvdW50eS4gQnkgaG92ZXJpbmcgb3ZlciB0aGUgbWFwLCB1c2VycyBjYW4gYWNjZXNzIGRldGFpbHMgc3VjaCBhcyB0aGUgeWVhciwgc3RhdGUsIGNvdW50eSwgd2lubmluZyBwYXJ0eSwgd2lubmluZyBjYW5kaWRhdGUsIHZvdGUgcGVyY2VudGFnZSwgYW5kIHRvdGFsIHZvdGVzLiBUaGUgbWFwIGFsc28gZW5hYmxlcyB1c2VycyB0byBjb21wYXJlIGRpZmZlcmVudCBlbGVjdGlvbiBjeWNsZXMgdG8gaWRlbnRpZnkgY291bnRpZXMgdGhhdCBoYXZlIHN3aXRjaGVkIHBhcnRpZXMuIEluY29ycG9yYXRpbmcgYWRkaXRpb25hbCBkYXRhLCBsaWtlIG1lZGlhbiBzYWxhcnkgYW5kIGRlbW9ncmFwaGljcywgY291bGQgcHJvdmlkZSBkZWVwZXIgaW5zaWdodHMgaW50byB0aGUgdHJlbmRzIGluZmx1ZW5jaW5nIGVsZWN0b3JhbCBvdXRjb21lcy4NCg0KIyBVUyBQcmVzaWRlbnRhbCBFbGVjdGlvbiBXaW5uZXIgYnkgU3RhdGUgKDIwMDAtMjAyMCkgLSBUYWJsZWF1IEludGVyYWN0aXZlIE1hcA0KYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2FzaXMnfQ0Ka25pdHI6OmluY2x1ZGVfdXJsKCJodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9VU1ByZXNpZGVudGFsRWxlY3Rpb25XaW5uZXJieVN0YXRlMjAwMC0yMDIwL1NoZWV0MT86ZW1iZWQ9eSY6c2hvd1ZpekhvbWU9bm8mOmhvc3RfdXJsPWh0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJjplbWJlZF9jb2RlX3ZlcnNpb249MyY6dGFicz1ubyY6dG9vbGJhcj15ZXMmOmFuaW1hdGVfdHJhbnNpdGlvbj15ZXMmOmRpc3BsYXlfc3RhdGljX2ltYWdlPW5vJjpkaXNwbGF5X3NwaW5uZXI9bm8mOmRpc3BsYXlfb3ZlcmxheT15ZXMmOmRpc3BsYXlfY291bnQ9eWVzJjpsYW5ndWFnZT1lbi1VUyZwdWJsaXNoPXllcyIsIGhlaWdodCA9ICI1MDBweCIpDQpgYGANClRoaXMgaW50ZXJhY3RpdmUgY2hvcm9wbGV0aCBtYXAgYWxsb3dzIHVzZXJzIHRvIHNlbGVjdCBVLlMuIFByZXNpZGVudGlhbCBlbGVjdGlvbiB5ZWFycyBmcm9tIDIwMDAgdG8gMjAyMCB0byB2aWV3IHRoZSB3aW5uaW5nIGNhbmRpZGF0ZXMgYnkgU3RhdGUgQnkgaG92ZXJpbmcgb3ZlciB0aGUgbWFwLCB1c2VycyBjYW4gYWNjZXNzIGRldGFpbHMgc3VjaCBhcyB0aGUgeWVhciwgc3RhdGUsIHdpbm5pbmcgcGFydHksIHZvdGUgcGVyY2VudGFnZSwgYW5kIHRvdGFsIHZvdGVzLiBUaGUgbWFwIGFsc28gZW5hYmxlcyB1c2VycyB0byBjb21wYXJlIGRpZmZlcmVudCBlbGVjdGlvbiBjeWNsZXMgdG8gaWRlbnRpZnkgc3RhdGVzIHRoYXQgaGF2ZSBzd2l0Y2hlZCBwYXJ0aWVzLiANCg==