Population and Size of Cities Ca. 1800

Data used by Playfair on population and size of some major European cities around 1800 is available in a file at https://stat.uiowa.edu/~luke/data/Playfair.

This file can be read using read.table.

We can read it directly from the web as

Playfair <- read.table("https://stat.uiowa.edu/~luke/data/Playfair")

In an Rmarkdown file you might want to work on when you are not connected to the internet it might be a good idea to download a local copy if you dont have one and then use the local copy:

if (! file.exists("Playfair.dat"))
    download.file("https://stat.uiowa.edu/~luke/data/Playfair",
                  "Playfair.dat")

You can hide this chunk with the chunk option include = FALSE.

Using the local file:

Playfair <- read.table("Playfair.dat")
names(Playfair)
## [1] "population" "diameter"
head(Playfair, 2)
##           population diameter
## Edinburgh         60    9.144
## Stockholm         63    9.652

This data frame isn’t in tidy form if we want to be able to use the city names as a variable since read.table stores these as the row names.

One approach to tidying this data frame is to

Playfair$city <- rownames(Playfair)
rownames(Playfair) <- NULL
head(Playfair, 2)
##   population diameter      city
## 1         60    9.144 Edinburgh
## 2         63    9.652 Stockholm

Another option is to read the data as three variables by skipping the first row and then adding the variable names:

Playfair <- read.table("Playfair.dat", skip = 1)
names(Playfair)
## [1] "V1" "V2" "V3"
names(Playfair) <- c("city", "population", "diameter")

A third option is to use the rownames_to_column function in the tibble package.

Useful checks:

str can help:

str(Playfair)
## 'data.frame':    22 obs. of  3 variables:
##  $ city      : chr  "Edinburgh" "Stockholm" "Florence" "Genoa" ...
##  $ population: int  60 63 75 80 80 80 90 120 130 140 ...
##  $ diameter  : num  9.14 9.65 10.16 10.67 10.16 ...

One way to find the number of lines in the file:

length(readLines("Playfair.dat"))
## [1] 23

The number of lines in the file should be one more than the number of rows.

It is not a bad idea to put a check in your file:

stopifnot(nrow(Playfair) + 1 == length(readLines("Playfair.dat")))

City Temperatures

The website https://www.timeanddate.com/weather/ provides current temperatures for a number of cities around the world.

Values from January 13, 2023, were saved in a file you can download from https://stat.uiowa.edu/~luke/data/citytemps.dat.

citytemps <- read.table("citytemps.dat", header = TRUE)
dim(citytemps)
## [1] 140   2
head(citytemps)
##          city temp
## 1       Accra   81
## 2 Addis Ababa   55
## 3    Adelaide   85
## 4     Algiers   61
## 5      Almaty   -6
## 6       Amman   46

Gapminder Data

The gapminder variable from the gapminder package contains select data from the GapMinder project.

Additional data is available from the GapMinder web site

library(gapminder)
dim(gapminder)
## [1] 1704    6
head(gapminder)
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.

Barley

The barley data set available in the lattice package records total yield in bushels per acre for 10 varieties at 6 experimental sites in Minnesota in each of two years.

library(lattice)
dim(barley)
## [1] 120   4
head(barley)
##      yield   variety year            site
## 1 27.00000 Manchuria 1931 University Farm
## 2 48.86667 Manchuria 1931          Waseca
## 3 27.43334 Manchuria 1931          Morris
## 4 39.93333 Manchuria 1931       Crookston
## 5 32.96667 Manchuria 1931    Grand Rapids
## 6 28.96667 Manchuria 1931          Duluth

Diamonds

The diamonds data set available in the ggplot2 package contains prices and other attributes of almost 54,000 diamonds.

library(ggplot2)
dim(diamonds)
## [1] 53940    10
head(diamonds)
## # A tibble: 6 × 10
##   carat cut       color clarity depth table price     x     y     z
##   <dbl> <ord>     <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1  0.23 Ideal     E     SI2      61.5    55   326  3.95  3.98  2.43
## 2  0.21 Premium   E     SI1      59.8    61   326  3.89  3.84  2.31
## 3  0.23 Good      E     VS1      56.9    65   327  4.05  4.07  2.31
## 4  0.29 Premium   I     VS2      62.4    58   334  4.2   4.23  2.63
## 5  0.31 Good      J     SI2      63.3    58   335  4.34  4.35  2.75
## 6  0.24 Very Good J     VVS2     62.8    57   336  3.94  3.96  2.48

Palmer Penguins

The palmerpenguins package includes data for adult foraging Adélie, Chinstrap, and Gentoo penguins observed on islands in the Palmer Archipelago near Palmer Station, Antarctica.

Data were collected and made available by Dr. Kristen Gorman and the Palmer Station Long Term Ecological Research (LTER) Program.

library(palmerpenguins)
penguins
## # A tibble: 344 × 8
##    species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
##    <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
##  1 Adelie  Torgersen           39.1          18.7               181        3750
##  2 Adelie  Torgersen           39.5          17.4               186        3800
##  3 Adelie  Torgersen           40.3          18                 195        3250
##  4 Adelie  Torgersen           NA            NA                  NA          NA
##  5 Adelie  Torgersen           36.7          19.3               193        3450
##  6 Adelie  Torgersen           39.3          20.6               190        3650
##  7 Adelie  Torgersen           38.9          17.8               181        3625
##  8 Adelie  Torgersen           39.2          19.6               195        4675
##  9 Adelie  Torgersen           34.1          18.1               193        3475
## 10 Adelie  Torgersen           42            20.2               190        4250
## # ℹ 334 more rows
## # ℹ 2 more variables: sex <fct>, year <int>

Other Sources and Forms of Data

The Data Sources link contains pointers to a range of different data sources.

Data is available in many forms.

Some are intended for human reading or editing:

Other forms are designed for reading by programs but may still be human readable:

In some cases data has been wrapped in R packages, or an R package is available for working with a specific API.

Some tools that are available for human-friendly forms:

Some tools for machine-friendly forms:

Example: Reading a table from Wikipedia

A Wikipedia page (permanent link to an older version from 2017) contains a table with data on gun murders in the US by states.

url <- paste0("https://en.wikipedia.org/w/index.php?title=",
              "Gun_violence_in_the_United_States_by_state&",
              "direction=prev&oldid=810166167")
library(tidyverse)
library(rvest)
h <- read_html(url)
tbs <- html_table(html_nodes(h, "table"))
murders <- tbs[[1]]
names(murders) <- c("state", "pop", "murders", "rate")
murders <- mutate(murders,
                  across(2 : 3, function(x) as.numeric(gsub(",", "", x))))
p <- ggplot(murders, aes(x = pop, y = murders))
p + geom_point()
library(plotly)
ggplotly(p + geom_point(aes(text = state)))

Example: National Weather Service Data for Iowa City

Current weather data is available in JSON format from

https://forecast.weather.gov/MapClick.php?lat=41.7&lon=-91.5&FcstType=json

Getting current temperature:

icurl <-
    "http://forecast.weather.gov/MapClick.php?lat=41.7&lon=-91.5&FcstType=json"
icjson <- jsonlite::fromJSON(icurl)
icjson$currentobservation$Temp

Example: Local Area Unemployment Statistics

The Bureau of Labor Statistics provides data on unemployment by county for the most recent 14 months at

https://www.bls.gov/web/metro/laucntycur14.txt

This can be read using a read.table.

Example: Test Scores in an Excel Spreadsheet

A simple Excel file is available in the dslabs package (GitHub source):

score_file <-
    system.file("extdata", "2010_bigfive_regents.xls", package = "dslabs")
readxl::read_xls(score_file)

More complicated files will need more processing.

Reading

More information on data import is provided in the chapter Data Import of R for Data Science.

Another reference is the chapter Importing Data in Introduction to Data Science: Data Analysis and Prediction Algorithms with R.

Exercises

  1. Read in the Playfair data using the read.table function and tidy the result using the rownames_to_column function from the tibble package.
  1. The variables site, variety, and year in the barley data set are factors. How many levels do each of these variables have? [You can use the functions levels and length.]
LS0tCnRpdGxlOiAiU29tZSBVc2VmdWwgRGF0YSBTZXRzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJzdGF0NDU4MC5jc3MiIHR5cGU9InRleHQvY3NzIiAvPgoKYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0Kc291cmNlKGhlcmU6OmhlcmUoInNldHVwLlIiKSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGNvbGxhcHNlID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDYsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQpgYGAKCgojIyBQb3B1bGF0aW9uIGFuZCBTaXplIG9mIENpdGllcyBDYS4gMTgwMAoKRGF0YSB1c2VkIGJ5IFBsYXlmYWlyIG9uIHBvcHVsYXRpb24gYW5kIHNpemUgb2Ygc29tZSBtYWpvciBFdXJvcGVhbgpjaXRpZXMgYXJvdW5kIDE4MDAgaXMgYXZhaWxhYmxlIGluIGEgZmlsZSBhdAo8aHR0cHM6Ly9zdGF0LnVpb3dhLmVkdS9+bHVrZS9kYXRhL1BsYXlmYWlyPi4KClRoaXMgZmlsZSBjYW4gYmUgcmVhZCB1c2luZyBgcmVhZC50YWJsZWAuCgpXZSBjYW4gcmVhZCBpdCBkaXJlY3RseSBmcm9tIHRoZSB3ZWIgYXMKCmBgYHtyLCBldmFsID0gRkFMU0V9ClBsYXlmYWlyIDwtIHJlYWQudGFibGUoImh0dHBzOi8vc3RhdC51aW93YS5lZHUvfmx1a2UvZGF0YS9QbGF5ZmFpciIpCmBgYAoKSW4gYW4gUm1hcmtkb3duIGZpbGUgeW91IG1pZ2h0IHdhbnQgdG8gd29yayBvbiB3aGVuIHlvdSBhcmUgbm90CmNvbm5lY3RlZCB0byB0aGUgaW50ZXJuZXQgaXQgbWlnaHQgYmUgYSBnb29kIGlkZWEgdG8gZG93bmxvYWQgYSBsb2NhbApjb3B5IGlmIHlvdSBkb250IGhhdmUgb25lIGFuZCB0aGVuIHVzZSB0aGUgbG9jYWwgY29weToKCmBgYHtyfQppZiAoISBmaWxlLmV4aXN0cygiUGxheWZhaXIuZGF0IikpCiAgICBkb3dubG9hZC5maWxlKCJodHRwczovL3N0YXQudWlvd2EuZWR1L35sdWtlL2RhdGEvUGxheWZhaXIiLAogICAgICAgICAgICAgICAgICAiUGxheWZhaXIuZGF0IikKYGBgCgpZb3UgY2FuIGhpZGUgdGhpcyBjaHVuayB3aXRoIHRoZSBjaHVuayBvcHRpb24gYGluY2x1ZGUgPSBGQUxTRWAuCgpVc2luZyB0aGUgbG9jYWwgZmlsZToKYGBge3J9ClBsYXlmYWlyIDwtIHJlYWQudGFibGUoIlBsYXlmYWlyLmRhdCIpCm5hbWVzKFBsYXlmYWlyKQpoZWFkKFBsYXlmYWlyLCAyKQpgYGAKClRoaXMgZGF0YSBmcmFtZSBpc24ndCBpbiB0aWR5IGZvcm0gaWYgd2Ugd2FudCB0byBiZSBhYmxlIHRvIHVzZSB0aGUKY2l0eSBuYW1lcyBhcyBhIHZhcmlhYmxlIHNpbmNlIGByZWFkLnRhYmxlYCBzdG9yZXMgdGhlc2UgYXMgdGhlIHJvdwpuYW1lcy4KCk9uZSBhcHByb2FjaCB0byB0aWR5aW5nIHRoaXMgZGF0YSBmcmFtZSBpcyB0bwoKKiB1c2UgdGhlIHJvdyBuYW1lcyB0byBjcmVhdGUgYSBuZXcgYGNpdHlgIHZhcmlhYmxlOwoqIHJlbW92ZSB0aGUgbm93IHJlZHVuZGFudCByb3cgbmFtZXM6CgpgYGB7cn0KUGxheWZhaXIkY2l0eSA8LSByb3duYW1lcyhQbGF5ZmFpcikKcm93bmFtZXMoUGxheWZhaXIpIDwtIE5VTEwKaGVhZChQbGF5ZmFpciwgMikKYGBgCgpBbm90aGVyIG9wdGlvbiBpcyB0byByZWFkIHRoZSBkYXRhIGFzIHRocmVlIHZhcmlhYmxlcyBieSBza2lwcGluZyB0aGUKZmlyc3Qgcm93IGFuZCB0aGVuIGFkZGluZyB0aGUgdmFyaWFibGUgbmFtZXM6CmBgYHtyfQpQbGF5ZmFpciA8LSByZWFkLnRhYmxlKCJQbGF5ZmFpci5kYXQiLCBza2lwID0gMSkKbmFtZXMoUGxheWZhaXIpCm5hbWVzKFBsYXlmYWlyKSA8LSBjKCJjaXR5IiwgInBvcHVsYXRpb24iLCAiZGlhbWV0ZXIiKQpgYGAKCkEgdGhpcmQgb3B0aW9uIGlzIHRvIHVzZSB0aGUgYHJvd25hbWVzX3RvX2NvbHVtbmAgZnVuY3Rpb24gaW4gdGhlCmB0aWJibGVgIHBhY2thZ2UuCgpVc2VmdWwgY2hlY2tzOgoKKiBtYWtlIHN1cmUgdGhlIGJlZ2lubmluZyBhbmQgZW5kIG9mIHRoZSBmaWxlIG1hdGNoIGBoZWFkYCBhbmQgYHRhaWxgOwoKKiBtYWtlIHN1cmUgdGhlIHZhcmlhYmxlIHR5cGVzIGFyZSB3aGF0IHRoZXkgc2hvdWxkIGJlOwoKKiBtYWtlIHN1cmUgdGhlIG51bWJlciBvZiByb3dzIG1hdGNoZXMgdGhlIG51bWJlciBvZiBsaW5lcyBpbiB0aGUgZmlsZS4KCmBzdHJgIGNhbiBoZWxwOgoKYGBge3J9CnN0cihQbGF5ZmFpcikKYGBgCgpPbmUgd2F5IHRvIGZpbmQgdGhlIG51bWJlciBvZiBsaW5lcyBpbiB0aGUgZmlsZToKYGBge3J9Cmxlbmd0aChyZWFkTGluZXMoIlBsYXlmYWlyLmRhdCIpKQpgYGAKClRoZSBudW1iZXIgb2YgbGluZXMgaW4gdGhlIGZpbGUgc2hvdWxkIGJlIG9uZSBtb3JlIHRoYW4gdGhlIG51bWJlciBvZiByb3dzLgoKSXQgaXMgbm90IGEgYmFkIGlkZWEgdG8gcHV0IGEgY2hlY2sgaW4geW91ciBmaWxlOgoKYGBge3J9CnN0b3BpZm5vdChucm93KFBsYXlmYWlyKSArIDEgPT0gbGVuZ3RoKHJlYWRMaW5lcygiUGxheWZhaXIuZGF0IikpKQpgYGAKCgojIyBDaXR5IFRlbXBlcmF0dXJlcwoKYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IEZBTFNFfQojIyBzY3JhcGluZyBhbmQgY2xlYW5pbmcKbGlicmFyeShydmVzdCkKd2VhdGhlciA8LSByZWFkX2h0bWwoImh0dHBzOi8vd3d3LnRpbWVhbmRkYXRlLmNvbS93ZWF0aGVyLyIpCncgPC0gaHRtbF90YWJsZShodG1sX25vZGVzKHdlYXRoZXIsICJ0YWJsZSIpKVtbMV1dCgpuYW1lcyh3KSA8LSBwYXN0ZTAoIlYiLCAxIDogMTIpCncxIDwtIHdbMSA6IDRdCncyIDwtIHdbNSA6IDhdOyBuYW1lcyh3MikgPC0gcGFzdGUwKCJWIiwgMSA6IDQpCnczIDwtIHdbOSA6IDEyXTsgbmFtZXModzMpIDwtIHBhc3RlMCgiViIsIDEgOiA0KQp3dyA8LSByYmluZCh3MSwgdzIsIHczKQojIyBtYXliZSB0cnkgdG8gcGFyc2UgdGhlIGxvY2FsIHRpbWVzIGluIFYyPwojIyB0aGUgc3RhcnMgaW5kaWNhdGUgRFNUIC0tIHNvdXRoZXJuIGhlbWlzcGhlcmUgaW4gSmFudWFyeQp3d3cgPC0gZGF0YS5mcmFtZShjaXR5ID0gc3ViKCIgXFwqIiwgIiIsIHd3JFYxKSwKICAgICAgICAgICAgICAgICAgdGVtcCA9IGFzLm51bWVyaWMoc3ViKCIoWy0rXT9bWzpkaWdpdDpdXSspLioiLCAiXFwxIiwgd3ckVjQpKSkKd3d3IDwtIHd3d1tjb21wbGV0ZS5jYXNlcyh3d3cpLCBdCgp3cml0ZS50YWJsZSh3d3csIHJvdy5uYW1lcyA9IEZBTFNFLCBmaWxlID0gImNpdHl0ZW1wcy5kYXQiKQojIHNjcmFwZWQgZnJvbSBodHRwczovL3d3dy50aW1lYW5kZGF0ZS5jb20vd2VhdGhlci8gb24gMjAyMy0wMS0xMyAxNjowMzo0MSBDU1QKaGVhZChyZWFkLnRhYmxlKCJjaXR5dGVtcHMuZGF0IiwgaGVhZGVyID0gVFJVRSkpCmBgYAoKYGBge3IsIGVjaG8gPSBGQUxTRX0KaWYgKCEgZmlsZS5leGlzdHMoImNpdHl0ZW1wcy5kYXQiKSkKICAgIGRvd25sb2FkLmZpbGUoImh0dHBzOi8vc3RhdC51aW93YS5lZHUvfmx1a2UvZGF0YS9jaXR5dGVtcHMuZGF0IiwKICAgICAgICAgICAgICAgICAgImNpdHl0ZW1wcy5kYXQiKQpgYGAKClRoZSB3ZWJzaXRlIDxodHRwczovL3d3dy50aW1lYW5kZGF0ZS5jb20vd2VhdGhlci8+IHByb3ZpZGVzIGN1cnJlbnQKdGVtcGVyYXR1cmVzIGZvciBhIG51bWJlciBvZiBjaXRpZXMgYXJvdW5kIHRoZSB3b3JsZC4KClZhbHVlcyBmcm9tIEphbnVhcnkgMTMsIDIwMjMsIHdlcmUgc2F2ZWQgaW4gYSBmaWxlIHlvdSBjYW4gZG93bmxvYWQKZnJvbSA8aHR0cHM6Ly9zdGF0LnVpb3dhLmVkdS9+bHVrZS9kYXRhL2NpdHl0ZW1wcy5kYXQ+LgoKYGBge3J9CmNpdHl0ZW1wcyA8LSByZWFkLnRhYmxlKCJjaXR5dGVtcHMuZGF0IiwgaGVhZGVyID0gVFJVRSkKZGltKGNpdHl0ZW1wcykKaGVhZChjaXR5dGVtcHMpCmBgYAoKCiMjIEdhcG1pbmRlciBEYXRhCgpUaGUgYGdhcG1pbmRlcmAgdmFyaWFibGUgZnJvbSB0aGUgYGdhcG1pbmRlcmAgcGFja2FnZSBjb250YWlucyBzZWxlY3QKZGF0YSBmcm9tIHRoZSBbR2FwTWluZGVyXShodHRwczovL3d3dy5nYXBtaW5kZXIub3JnKSBwcm9qZWN0LgoKQWRkaXRpb25hbCBkYXRhIGlzIGF2YWlsYWJsZSBmcm9tIHRoZSBbR2FwTWluZGVyIHdlYgpzaXRlXShodHRwczovL3d3dy5nYXBtaW5kZXIub3JnKQoKYGBge3J9CmxpYnJhcnkoZ2FwbWluZGVyKQpkaW0oZ2FwbWluZGVyKQpoZWFkKGdhcG1pbmRlcikKYGBgCgoKIyMgQmFybGV5CgpUaGUgYGJhcmxleWAgZGF0YSBzZXQgYXZhaWxhYmxlIGluIHRoZSBgbGF0dGljZWAgcGFja2FnZSByZWNvcmRzIHRvdGFsCnlpZWxkIGluIGJ1c2hlbHMgcGVyIGFjcmUgZm9yIDEwIHZhcmlldGllcyBhdCA2IGV4cGVyaW1lbnRhbCBzaXRlcyBpbgpNaW5uZXNvdGEgaW4gZWFjaCBvZiB0d28geWVhcnMuCgpgYGB7cn0KbGlicmFyeShsYXR0aWNlKQpkaW0oYmFybGV5KQpoZWFkKGJhcmxleSkKYGBgCgoKIyMgRGlhbW9uZHMKClRoZSBgZGlhbW9uZHNgIGRhdGEgc2V0IGF2YWlsYWJsZSBpbiB0aGUgYGdncGxvdDJgIHBhY2thZ2UgY29udGFpbnMKcHJpY2VzIGFuZCBvdGhlciBhdHRyaWJ1dGVzIG9mIGFsbW9zdCA1NCwwMDAgZGlhbW9uZHMuCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpkaW0oZGlhbW9uZHMpCmhlYWQoZGlhbW9uZHMpCmBgYAoKCiMjIFBhbG1lciBQZW5ndWlucwoKVGhlIFtgcGFsbWVycGVuZ3VpbnNgCnBhY2thZ2VdKGh0dHBzOi8vYWxsaXNvbmhvcnN0LmdpdGh1Yi5pby9wYWxtZXJwZW5ndWlucy8pIGluY2x1ZGVzIGRhdGEKZm9yIGFkdWx0IGZvcmFnaW5nIEFkw6lsaWUsIENoaW5zdHJhcCwgYW5kIEdlbnRvbyBwZW5ndWlucyBvYnNlcnZlZCBvbgppc2xhbmRzIGluIHRoZSBQYWxtZXIgQXJjaGlwZWxhZ28gbmVhciBQYWxtZXIgU3RhdGlvbiwgQW50YXJjdGljYS4KCkRhdGEgd2VyZSBjb2xsZWN0ZWQgYW5kIG1hZGUgYXZhaWxhYmxlIGJ5CkRyLiBLcmlzdGVuIEdvcm1hbiBhbmQgdGhlIFBhbG1lciBTdGF0aW9uIExvbmcgVGVybSBFY29sb2dpY2FsClJlc2VhcmNoIChMVEVSKSBQcm9ncmFtLgoKYGBge3IsIGVjaG8gPSBUUlVFfQpsaWJyYXJ5KHBhbG1lcnBlbmd1aW5zKQpwZW5ndWlucwpgYGAKCgojIyBPdGhlciBTb3VyY2VzIGFuZCBGb3JtcyBvZiBEYXRhCgpUaGUgW0RhdGEgU291cmNlcyBsaW5rXShgciBXTE5LKCJkYXRhc291cmNlcy5odG1sIilgKSBjb250YWlucwpwb2ludGVycyB0byBhIHJhbmdlIG9mIGRpZmZlcmVudCBkYXRhIHNvdXJjZXMuCgpEYXRhIGlzIGF2YWlsYWJsZSBpbiBtYW55IGZvcm1zLgoKU29tZSBhcmUgaW50ZW5kZWQgZm9yIGh1bWFuIHJlYWRpbmcgb3IgZWRpdGluZzoKCiogVGV4dCBmaWxlcyBpbiB2YXJpb3VzIGZvcm1hdHMuCgoqIEV4Y2VsIHNwcmVhZHNoZWV0cy4KCiogVGFibGVzIGluIHdlYiBwYWdlcy4KCiogVGFibGVzIGluIFBERiBmaWxlcy4KCk90aGVyIGZvcm1zIGFyZSBkZXNpZ25lZCBmb3IgcmVhZGluZyBieSBwcm9ncmFtcyBidXQgbWF5IHN0aWxsIGJlCmh1bWFuIHJlYWRhYmxlOgoKKiBDU1YgZmlsZXMuCgoqIEpzb24gYW5kIEdlb0pzb24gZmlsZXMuCgoqIFdlYiBBUElzLgoKSW4gc29tZSBjYXNlcyBkYXRhIGhhcyBiZWVuIHdyYXBwZWQgaW4gUiBwYWNrYWdlcywgb3IgYW4gUiBwYWNrYWdlIGlzCmF2YWlsYWJsZSBmb3Igd29ya2luZyB3aXRoIGEgc3BlY2lmaWMgQVBJLgoKU29tZSB0b29scyB0aGF0IGFyZSBhdmFpbGFibGUgZm9yIGh1bWFuLWZyaWVuZGx5IGZvcm1zOgoKKiBUZXh0IGZpbGVzOiBgcmVhZC50YWJsZWAsIGByZWFkcjo6cmVhZF90YWJsZWAsIGByZWFkTGluZXNgLgoqIEV4Y2VsOiBgcmVhZHhsOjpyZWFkX3hsc2AKKiBXZWIgcGFnZXM6IGBydmVzdGAgcGFja2FnZS4KClNvbWUgdG9vbHMgZm9yIG1hY2hpbmUtZnJpZW5kbHkgZm9ybXM6CgoqIENTViBmaWxlczogYHJlYWQuY3N2YCwgYHJlYWRyOjpyZWFkX2NzdmAuCiogSnNvbjogYGpzb25saXRlOjpmcm9tSlNPTmAuCiogV2ViIEFQSXM6IGBodHRyYCBwYWNrYWdlLgoKCiMjIyBFeGFtcGxlOiBSZWFkaW5nIGEgdGFibGUgZnJvbSBXaWtpcGVkaWEKCjwhLS0gZnJvbSBSYWZhJ3MgYm9vayAtLT4KQSBXaWtpcGVkaWEgcGFnZSAoW3Blcm1hbmVudCBsaW5rIHRvIGFuIG9sZGVyCnZlcnNpb24gZnJvbSAyMDE3XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvdy9pbmRleC5waHA/dGl0bGU9R3VuX3Zpb2xlbmNlX2luX3RoZV9Vbml0ZWRfU3RhdGVzX2J5X3N0YXRlJmRpcmVjdGlvbj1wcmV2Jm9sZGlkPTgxMDE2NjE2NykpCmNvbnRhaW5zIGEgdGFibGUgd2l0aCBkYXRhIG9uIGd1biBtdXJkZXJzIGluIHRoZSBVUyBieSBzdGF0ZXMuCgpgYGB7ciwgZXZhbCA9IEZBTFNFfQp1cmwgPC0gcGFzdGUwKCJodHRwczovL2VuLndpa2lwZWRpYS5vcmcvdy9pbmRleC5waHA/dGl0bGU9IiwKICAgICAgICAgICAgICAiR3VuX3Zpb2xlbmNlX2luX3RoZV9Vbml0ZWRfU3RhdGVzX2J5X3N0YXRlJiIsCiAgICAgICAgICAgICAgImRpcmVjdGlvbj1wcmV2Jm9sZGlkPTgxMDE2NjE2NyIpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJ2ZXN0KQpoIDwtIHJlYWRfaHRtbCh1cmwpCnRicyA8LSBodG1sX3RhYmxlKGh0bWxfbm9kZXMoaCwgInRhYmxlIikpCm11cmRlcnMgPC0gdGJzW1sxXV0KbmFtZXMobXVyZGVycykgPC0gYygic3RhdGUiLCAicG9wIiwgIm11cmRlcnMiLCAicmF0ZSIpCm11cmRlcnMgPC0gbXV0YXRlKG11cmRlcnMsCiAgICAgICAgICAgICAgICAgIGFjcm9zcygyIDogMywgZnVuY3Rpb24oeCkgYXMubnVtZXJpYyhnc3ViKCIsIiwgIiIsIHgpKSkpCnAgPC0gZ2dwbG90KG11cmRlcnMsIGFlcyh4ID0gcG9wLCB5ID0gbXVyZGVycykpCnAgKyBnZW9tX3BvaW50KCkKbGlicmFyeShwbG90bHkpCmdncGxvdGx5KHAgKyBnZW9tX3BvaW50KGFlcyh0ZXh0ID0gc3RhdGUpKSkKYGBgCgoKIyMjIEV4YW1wbGU6IE5hdGlvbmFsIFdlYXRoZXIgU2VydmljZSBEYXRhIGZvciBJb3dhIENpdHkKCkN1cnJlbnQgd2VhdGhlciBkYXRhIGlzIGF2YWlsYWJsZSBpbiBKU09OIGZvcm1hdCBmcm9tCgo8aHR0cHM6Ly9mb3JlY2FzdC53ZWF0aGVyLmdvdi9NYXBDbGljay5waHA/bGF0PTQxLjcmbG9uPS05MS41JkZjc3RUeXBlPWpzb24+CgpHZXR0aW5nIGN1cnJlbnQgdGVtcGVyYXR1cmU6CgpgYGB7ciwgZXZhbCA9IEZBTFNFfQppY3VybCA8LQogICAgImh0dHA6Ly9mb3JlY2FzdC53ZWF0aGVyLmdvdi9NYXBDbGljay5waHA/bGF0PTQxLjcmbG9uPS05MS41JkZjc3RUeXBlPWpzb24iCmljanNvbiA8LSBqc29ubGl0ZTo6ZnJvbUpTT04oaWN1cmwpCmljanNvbiRjdXJyZW50b2JzZXJ2YXRpb24kVGVtcApgYGAKCgojIyMgRXhhbXBsZTogTG9jYWwgQXJlYSBVbmVtcGxveW1lbnQgU3RhdGlzdGljcwoKVGhlIEJ1cmVhdSBvZiBMYWJvciBTdGF0aXN0aWNzIHByb3ZpZGVzIFtkYXRhIG9uCnVuZW1wbG95bWVudF0oaHR0cHM6Ly93d3cuYmxzLmdvdi9sYXUvKSBieSBjb3VudHkgZm9yIHRoZSBtb3N0IHJlY2VudAoxNCBtb250aHMgYXQKCjxodHRwczovL3d3dy5ibHMuZ292L3dlYi9tZXRyby9sYXVjbnR5Y3VyMTQudHh0PgoKVGhpcyBjYW4gYmUgcmVhZCB1c2luZyBhIGByZWFkLnRhYmxlYC4KCgojIyMgRXhhbXBsZTogVGVzdCBTY29yZXMgaW4gYW4gRXhjZWwgU3ByZWFkc2hlZXQKCkEgc2ltcGxlIEV4Y2VsIGZpbGUgaXMgYXZhaWxhYmxlIGluIHRoZSBgZHNsYWJzYCBwYWNrYWdlIChbR2l0SHViCnNvdXJjZV0oaHR0cHM6Ly9naXRodWIuY29tL3JhZmFsYWIvZHNsYWJzL2Jsb2IvbWFzdGVyL2luc3QvZXh0ZGF0YS8yMDEwX2JpZ2ZpdmVfcmVnZW50cy54bHM/cmF3PXRydWUpKToKCmBgYHtyLCBldmFsID0gRkFMU0V9CnNjb3JlX2ZpbGUgPC0KICAgIHN5c3RlbS5maWxlKCJleHRkYXRhIiwgIjIwMTBfYmlnZml2ZV9yZWdlbnRzLnhscyIsIHBhY2thZ2UgPSAiZHNsYWJzIikKcmVhZHhsOjpyZWFkX3hscyhzY29yZV9maWxlKQpgYGAKCltNb3JlIGNvbXBsaWNhdGVkIGZpbGVzXShodHRwczovL3N0YXQudWlvd2EuZWR1L35sdWtlL2RhdGEvQXJyaXZhbHMtMjAxNy0wMS0wNi54bHMpIHdpbGwgbmVlZCBtb3JlIHByb2Nlc3NpbmcuCgoKIyMgUmVhZGluZwoKTW9yZSBpbmZvcm1hdGlvbiBvbiBkYXRhIGltcG9ydCBpcyBwcm92aWRlZCBpbiB0aGUgY2hhcHRlciBbX0RhdGEKSW1wb3J0X10oaHR0cHM6Ly9yNGRzLmhhZC5jby5uei9kYXRhLWltcG9ydC5odG1sKSBvZiBbX1IgZm9yIERhdGEKU2NpZW5jZV9dKGh0dHBzOi8vcjRkcy5oYWQuY28ubnopLgoKQW5vdGhlciByZWZlcmVuY2UgaXMgdGhlIGNoYXB0ZXIgW19JbXBvcnRpbmcKRGF0YV9dKGh0dHBzOi8vcmFmYWxhYi5kZmNpLmhhcnZhcmQuZWR1L2RzYm9vay9pbXBvcnRpbmctZGF0YS5odG1sKSBpbgpbX0ludHJvZHVjdGlvbiB0byBEYXRhIFNjaWVuY2U6IERhdGEgQW5hbHlzaXMgYW5kIFByZWRpY3Rpb24KQWxnb3JpdGhtcyB3aXRoIFJfXShodHRwczovL3JhZmFsYWIuZGZjaS5oYXJ2YXJkLmVkdS9kc2Jvb2svKS4KCgojIyBFeGVyY2lzZXMKCjEuIFJlYWQgaW4gdGhlIFBsYXlmYWlyIGRhdGEgdXNpbmcgdGhlIGByZWFkLnRhYmxlYCBmdW5jdGlvbiBhbmQgdGlkeQogICB0aGUgcmVzdWx0IHVzaW5nIHRoZSBgcm93bmFtZXNfdG9fY29sdW1uYCBmdW5jdGlvbiBmcm9tIHRoZQogICBgdGliYmxlYCBwYWNrYWdlLgoKPCEtLQpQbGF5ZmFpciA8LSByZWFkLnRhYmxlKCJodHRwOi8vd3d3LnN0YXQudWlvd2EuZWR1L35sdWtlL2RhdGEvUGxheWZhaXIiKQpyb3duYW1lc190b19jb2x1bW4oUGxheWZhaXIsICJjaXR5IikKLS0+CgoyLiBUaGUgdmFyaWFibGVzIGBzaXRlYCwgYHZhcmlldHlgLCBhbmQgYHllYXJgIGluIHRoZSBgYmFybGV5YCBkYXRhCiAgIHNldCBhcmUgX2ZhY3RvcnNfLiAgSG93IG1hbnkgX2xldmVsc18gZG8gZWFjaCBvZiB0aGVzZSB2YXJpYWJsZXMKICAgaGF2ZT8gW1lvdSBjYW4gdXNlIHRoZSBmdW5jdGlvbnMgYGxldmVsc2AgYW5kIGBsZW5ndGhgLl0K