Install packages
The version of R that you just downloaded is considered base R, which
provides you with good but basic statistical computing and graphics
powers. For analytical and graphical super-powers, you’ll need to
install add-on packages, which are user-written, to extend/expand your R
capabilities. Packages can live in one of two places:
- They may be carefully curated by CRAN (which involves a thorough
submission and review process), and thus are easy install using
install.packages("name_of_package", dependencies = TRUE)
in
your CONSOLE.
Place your cursor in the CONSOLE again (where you last typed
x
and [4]
printed on the screen). You can use
the first method to install the following packages directly from CRAN,
all of which we will use:
knitr
,
dplyr
,
ggplot2
,
babynames
To install a package, you put the name of the package
in quotes as in
install.packages("name_of_package")
. Mind your use of
quotes carefully with packages.
To use an already installed package, you must load it
first, as in library(name_of_package)
, leaving the name of
the package bare. You only need to do this once per
RStudio session.
You can download all of these at once, too:
install.packages(c("knitr", "dplyr", "ggplot2", "babynames"), dependencies = TRUE)
A brief aside: c()
is a command in R that allows us to
combine things into a vector
( one of the ways data is
represented in R)
c("hello", "my", "name", "is", "arvind")
## [1] "hello" "my" "name" "is" "arvind"
c(1:3, 20, 50)
## [1] 1 2 3 20 50
- If you want help, no quotes are needed:
help(name_of_package)
or
?name_of_package
.
- If you want the citation for a package (and you should give
credit where credit is due), ask R as in
citation("name_of_package")
.
install.packages("dplyr", dependencies = TRUE)
library(dplyr)
help("dplyr")
citation("ggplot2")
##
## To cite ggplot2 in publications, please use:
##
## H. Wickham. ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York, 2016.
##
## A BibTeX entry for LaTeX users is
##
## @Book{,
## author = {Hadley Wickham},
## title = {ggplot2: Elegant Graphics for Data Analysis},
## publisher = {Springer-Verlag New York},
## year = {2016},
## isbn = {978-3-319-24277-4},
## url = {https://ggplot2.tidyverse.org},
## }
Make a name plot
The webpage you are looking at is derived from a
R Markdown
doc that you can download, edit and compute
with. We will meet R Markdown
in the next class.
Download this .Rmd file using the Code->Download Rmd
button at the top right corner.
Change the author name to your own!
Hit the green “play” button to run this “load_packages”
chunk to include in your R session all the installed packages
you need:
Let us greet our data first !!
glimpse(babynames) # dplyr
Rows: 1,924,665
Columns: 5
$ year <dbl> 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1…
$ sex <chr> "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", …
$ name <chr> "Mary", "Anna", "Emma", "Elizabeth", "Minnie", "Margaret", "Ida", "Alice", "Bertha", "Sarah", "Annie", "Clara", "El…
$ n <int> 7065, 2604, 2003, 1939, 1746, 1578, 1472, 1414, 1320, 1288, 1258, 1226, 1156, 1063, 1045, 1040, 1012, 995, 982, 949…
$ prop <dbl> 0.07238359, 0.02667896, 0.02052149, 0.01986579, 0.01788843, 0.01616720, 0.01508119, 0.01448696, 0.01352390, 0.01319…
head(babynames) # base R
# A tibble: 6 × 5
year sex name n prop
<dbl> <chr> <chr> <int> <dbl>
1 1880 F Mary 7065 0.0724
2 1880 F Anna 2604 0.0267
3 1880 F Emma 2003 0.0205
4 1880 F Elizabeth 1939 0.0199
5 1880 F Minnie 1746 0.0179
6 1880 F Margaret 1578 0.0162
tail(babynames) # same
# A tibble: 6 × 5
year sex name n prop
<dbl> <chr> <chr> <int> <dbl>
1 2017 M Zyhier 5 0.00000255
2 2017 M Zykai 5 0.00000255
3 2017 M Zykeem 5 0.00000255
4 2017 M Zylin 5 0.00000255
5 2017 M Zylis 5 0.00000255
6 2017 M Zyrie 5 0.00000255
names(babynames) # same
[1] "year" "sex" "name" "n" "prop"
If you have done the above and produced sane-looking output, you are
ready for the next bit. Use the code below to create a new data frame
called arvind
.
my_name_data <- babynames %>%
filter(name == "Arvind" | name == "Aravind") %>%
filter(sex == "M")
The first bit makes a new dataset called
my_name_data
that is a copy of the babynames
dataset- the %>%
tells you we are doing some other stuff
to it later.
The second bit filters
our babynames
to
only keep rows where the name
is either Arvind or Aravind
(read |
as “or”.)
The third bit applies another filter
to keep only
those where sex is male.
Let’s check out the data.
my_name_data
# A tibble: 61 × 5
year sex name n prop
<dbl> <chr> <chr> <int> <dbl>
1 1970 M Arvind 5 0.00000262
2 1972 M Arvind 8 0.00000478
3 1975 M Arvind 7 0.00000431
4 1976 M Arvind 5 0.00000306
5 1977 M Arvind 9 0.00000526
6 1978 M Arvind 6 0.00000351
7 1979 M Arvind 7 0.00000391
8 1980 M Arvind 6 0.00000323
9 1981 M Arvind 8 0.0000043
10 1982 M Arvind 6 0.00000318
# … with 51 more rows
glimpse(my_name_data)
Rows: 61
Columns: 5
$ year <dbl> 1970, 1972, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1…
$ sex <chr> "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", …
$ name <chr> "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvind", "Arvi…
$ n <int> 5, 8, 7, 5, 9, 6, 7, 6, 8, 6, 7, 7, 7, 13, 8, 11, 6, 8, 12, 10, 17, 6, 14, 21, 21, 6, 20, 5, 24, 10, 25, 8, 26, 15,…
$ prop <dbl> 2.620e-06, 4.780e-06, 4.310e-06, 3.060e-06, 5.260e-06, 3.510e-06, 3.910e-06, 3.230e-06, 4.300e-06, 3.180e-06, 3.760…
Again, if you have sane-looking output here, move along to plotting
the data!
plot <- ggplot(my_name_data, aes(x = year,
y = prop,
group = name,
color = name)) +
geom_line()
Now if you did this right, you will not see your
plot!
Because we saved the ggplot
with a name
(plot
), R just saved the object for you. But check out the
top right pane in RStudio again: under the Environment
pane
you should see plot
, so it is there, you just have to ask
for it. Here’s how:
plot
LS0tDQp0aXRsZTogJ0xhYiAwMCAtIEludHJvZHVjZSBZb3Vyc2VsZicNCmF1dGhvcjogIkFydmluZCBWZW5rYXRhZHJpIg0KZGF0ZTogMDYvSnVseS8yMDIxDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGZsYXRseQ0KICAgIHRvYzogVFJVRQ0KICAgIHRvY19mbG9hdDogVFJVRQ0KICAgIHRvY19kZXB0aDogMg0KICAgIG51bWJlcl9zZWN0aW9uczogVFJVRQ0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IFRSVUUNCg0KYWJzdHJhY3Q6IFBhcnQgb2YgdGhlIGBSIGZvciBBcnRpc3RzIGFuZCBEZXNpZ25lcnNgIGNvdXJzZSBhdCB0aGUgU2Nob29sIG9mIEZvdW5kYXRpb24gU3R1ZGllcywgU3Jpc2h0aSBNYW5pcGFsIEluc3RpdHV0ZSBvZiBBcnQsIERlc2lnbiwgYW5kIFRlY2hub2xvZ3ksIEJhbmdhbG9yZS4NCi0tLQ0KDQojIEdvYWxzDQoNCkF0IHRoZSBlbmQgb2YgdGhpcyBMYWIsIHdlIHdpbGw6DQoNCi0gaGF2ZSBpbnN0YWxsZWQgUiBhbmQgUlN0dWRpbyBvbiBvdXIgbWFjaGluZXMNCi0gdW5kZXJzdG9vZCBob3cgdG8gYWRkIGFkZGl0aW9uYWwgUi1wYWNrYWdlcyBmb3Igc3BlY2lmaWMgZmVhdHVyZXMgYW5kIGdyYXBoaWMgY2FwYWJpbGl0eQ0KLSBydW4gY29kZSB3aXRoaW4gUlN0dWRpbyBhbmQgaW50ZXJwcmV0IHRoZSByZXN1bHRzDQotIGhhdmUgbGVhcm50IHRvIGxvb2sgZm9yIGhlbHAgd2l0aGluIFIgYW5kIFJTdHVkaW8NCg0KIyBJbnN0cnVjdGlvbnMNCg0KMS4gS2VlcCB0aGlzIHRhYiBvcGVuIGluIHlvdXIgYnJvd3NlciBhcyB5b3Ugd29yayB0aHJvdWdoIGl0LiBSZWFkIGFsbCB0aGUgd2F5IHRvIHRoZSBlbmQuDQoNCg0KIyBPdmVydmlldw0KDQpUaGlzIGd1aWRlIHdpbGwgbGVhZCB5b3UgdGhyb3VnaCB0aGUgc3RlcHMgdG8gaW5zdGFsbCBhbmQgdXNlIFtSLCBhIGZyZWUgYW5kIG9wZW4tc291cmNlIHNvZnR3YXJlIGVudmlyb25tZW50IGZvciBzdGF0aXN0aWNhbCBjb21wdXRpbmcgYW5kIGdyYXBoaWNzLl0oaHR0cHM6Ly93d3cuci1wcm9qZWN0Lm9yZykgDQoNCg0KV2hhdCBpcyBSPw0KDQoqICoqUioqIGlzIHRoZSBuYW1lIG9mIHRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZSBpdHNlbGYsIGJhc2VkIG9mZiBTIGZyb20gQmVsbCBMYWJzLCB3aGljaCB1c2VycyBhY2Nlc3MgdGhyb3VnaCBhIGNvbW1hbmQtbGluZSBpbnRlcnByZXRlciAoYD5gKQ0KDQpXaGF0IGlzIFJTdHVkaW8/DQoNCiogKipSU3R1ZGlvKiogaXMgYSBwb3dlcmZ1bCBhbmQgY29udmVuaWVudCB1c2VyIGludGVyZmFjZSB0aGF0IGFsbG93cyB5b3UgdG8gYWNjZXNzIHRoZSBSIHByb2dyYW1taW5nIGxhbmd1YWdlIGFsb25nIHdpdGggYSBsb3Qgb2Ygb3RoZXIgYmVsbHMgYW5kIHdoaXN0bGVzIHRoYXQgZW5oYW5jZSBmdW5jdGlvbmFsaXR5IChhbmQgc2FuaXR5KS4gDQoNCk91ciBlbmQgZ29hbCBpcyB0byBnZXQgeW91IGxvb2tpbmcgYXQgYSBzY3JlZW4gbGlrZSB0aGlzOg0KDQohW10oLi9pbWFnZXMvMDBfZmluYWwtc2NyZWVuc2hvdC5wbmcpDQoNCiMgSW5zdGFsbCBSDQoNCkluc3RhbGwgUiBmcm9tIFtDUkFOLCB0aGUgQ29tcHJlaGVuc2l2ZSBSIEFyY2hpdmUgTmV0d29ya10oaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tKS4gUGxlYXNlIGNob29zZSBhICoqcHJlY29tcGlsZWQgYmluYXJ5IGRpc3RyaWJ1dGlvbioqIGZvciB5b3VyIG9wZXJhdGluZyBzeXN0ZW0uDQoNCiMjIENoZWNrIGluDQoNCkxhdW5jaCBSLiBZb3Ugc2hvdWxkIHNlZSBvbmUgY29uc29sZSB3aXRoIGEgY29tbWFuZCBsaW5lIGludGVycHJldGVyIChgPmApLiBDbG9zZSBSLg0KDQojIEluc3RhbGwgUlN0dWRpbyANCg0KSW5zdGFsbCB0aGUgZnJlZSwgb3Blbi1zb3VyY2UgZWRpdGlvbiBvZiBSU3R1ZGlvOiBodHRwOi8vd3d3LnJzdHVkaW8uY29tL3Byb2R1Y3RzL3JzdHVkaW8vZG93bmxvYWQvDQoNClJTdHVkaW8gcHJvdmlkZXMgYSBwb3dlcmZ1bCB1c2VyIGludGVyZmFjZSBmb3IgUiwgY2FsbGVkIGFuICppbnRlZ3JhdGVkIGRldmVsb3BtZW50IGVudmlyb25tZW50Ki4gUlN0dWRpbyBpbmNsdWRlczoNCg0KKiBhIGNvbnNvbGUgKHRoZSBzdGFuZGFyZCBjb21tYW5kIGxpbmUgaW50ZXJmYWNlOiBgPmApLCANCiogYSBzeW50YXgtaGlnaGxpZ2h0aW5nIGVkaXRvciB0aGF0IHN1cHBvcnRzIGRpcmVjdCBjb2RlIGV4ZWN1dGlvbiwgYW5kIA0KKiB0b29scyBmb3IgcGxvdHRpbmcsIGhpc3RvcnksIGRlYnVnZ2luZyBhbmQgd29ya3NwYWNlIG1hbmFnZW1lbnQuDQoNCg0KIyMgQ2hlY2sgaW4NCg0KTGF1bmNoIFJTdHVkaW8uIFlvdSBzaG91bGQgZ2V0IGEgd2luZG93IHNpbWlsYXIgdG8gdGhlIHNjcmVlbnNob3QgeW91IHNlZSBbaGVyZV0oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMTQvMDQvcnN0dWRpby13b3JrYmVuY2gucG5nKSwgYnV0IHlvdXJzIHdpbGwgYmUgZW1wdHkuIExvb2sgYXQgdGhlIGJvdHRvbSBsZWZ0IHBhbmU6IHRoaXMgaXMgdGhlIHNhbWUgY29uc29sZSB3aW5kb3cgeW91IHNhdyB3aGVuIHlvdSBvcGVuZWQgUiBpbiBzdGVwIDEuMTUuIA0KDQoqIFBsYWNlIHlvdXIgY3Vyc29yIHdoZXJlIHlvdSBzZWUgYD5gIGFuZCB0eXBlIGB4IDwtIDIgKyAyYCwgaGl0IGVudGVyIG9yIHJldHVybiwgdGhlbiB0eXBlIGB4YCwgYW5kIGhpdCBlbnRlci9yZXR1cm4gYWdhaW4uIA0KKiBJZiBgWzFdIDRgIHByaW50cyB0byB0aGUgc2NyZWVuLCB5b3UgaGF2ZSBzdWNjZXNzZnVsbHkgaW5zdGFsbGVkIFIgYW5kIFJTdHVkaW8sIGFuZCB5b3UgY2FuIG1vdmUgb250byBpbnN0YWxsaW5nIHBhY2thZ2VzLg0KDQojIEluc3RhbGwgcGFja2FnZXMNCg0KVGhlIHZlcnNpb24gb2YgUiB0aGF0IHlvdSBqdXN0IGRvd25sb2FkZWQgaXMgY29uc2lkZXJlZCBiYXNlIFIsIHdoaWNoIHByb3ZpZGVzIHlvdSB3aXRoIGdvb2QgYnV0IGJhc2ljIHN0YXRpc3RpY2FsIGNvbXB1dGluZyBhbmQgZ3JhcGhpY3MgcG93ZXJzLiBGb3IgYW5hbHl0aWNhbCBhbmQgZ3JhcGhpY2FsIHN1cGVyLXBvd2VycywgeW91J2xsIG5lZWQgdG8gaW5zdGFsbCBhZGQtb24gcGFja2FnZXMsIHdoaWNoIGFyZSB1c2VyLXdyaXR0ZW4sIHRvIGV4dGVuZC9leHBhbmQgeW91ciBSIGNhcGFiaWxpdGllcy4gUGFja2FnZXMgY2FuIGxpdmUgaW4gb25lIG9mIHR3byBwbGFjZXM6DQoNCiogVGhleSBtYXkgYmUgY2FyZWZ1bGx5IGN1cmF0ZWQgYnkgQ1JBTiAod2hpY2ggaW52b2x2ZXMgYSB0aG9yb3VnaCBzdWJtaXNzaW9uIGFuZCByZXZpZXcgcHJvY2VzcyksIGFuZCB0aHVzIGFyZSBlYXN5IGluc3RhbGwgdXNpbmcgYGluc3RhbGwucGFja2FnZXMoIm5hbWVfb2ZfcGFja2FnZSIsIGRlcGVuZGVuY2llcyA9IFRSVUUpYCBpbiB5b3VyIENPTlNPTEUuIA0KDQpQbGFjZSB5b3VyIGN1cnNvciBpbiB0aGUgQ09OU09MRSBhZ2FpbiAod2hlcmUgeW91IGxhc3QgdHlwZWQgYHhgIGFuZCBgWzRdYCBwcmludGVkIG9uIHRoZSBzY3JlZW4pLiBZb3UgY2FuIHVzZSB0aGUgZmlyc3QgbWV0aG9kIHRvIGluc3RhbGwgdGhlIGZvbGxvd2luZyBwYWNrYWdlcyBkaXJlY3RseSBmcm9tIENSQU4sIGFsbCBvZiB3aGljaCB3ZSB3aWxsIHVzZToNCg0KICAqIFtga25pdHJgLF0oaHR0cHM6Ly95aWh1aS5vcmcva25pdHIvKQ0KICAqIFtgZHBseXJgLF0oaHR0cDovL2RwbHlyLnRpZHl2ZXJzZS5vcmcpDQogICogW2BnZ3Bsb3QyYCxdKGh0dHA6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcpDQogICogW2BiYWJ5bmFtZXNgXShodHRwczovL2dpdGh1Yi5jb20vaGFkbGV5L2JhYnluYW1lcykNCg0KKiBUbyAqaW5zdGFsbCogYSBwYWNrYWdlLCB5b3UgcHV0IHRoZSBuYW1lIG9mIHRoZSBwYWNrYWdlICoqaW4gcXVvdGVzKiogYXMgaW4gYGluc3RhbGwucGFja2FnZXMoIm5hbWVfb2ZfcGFja2FnZSIpYC4gDQpNaW5kIHlvdXIgdXNlIG9mIHF1b3RlcyBjYXJlZnVsbHkgd2l0aCBwYWNrYWdlcy4NCg0KKiBUbyAqdXNlKiBhbiBhbHJlYWR5IGluc3RhbGxlZCBwYWNrYWdlLCB5b3UgbXVzdCBsb2FkIGl0IGZpcnN0LCBhcyBpbiBgbGlicmFyeShuYW1lX29mX3BhY2thZ2UpYCwgbGVhdmluZyB0aGUgbmFtZSBvZiB0aGUgcGFja2FnZSBiYXJlLiBZb3Ugb25seSBuZWVkIHRvIGRvIHRoaXMgKipvbmNlKiogcGVyIFJTdHVkaW8gc2Vzc2lvbi4NCiAgDQpZb3UgY2FuIGRvd25sb2FkIGFsbCBvZiB0aGVzZSBhdCBvbmNlLCB0b286DQoNCmBgYHtyIGNfaW5zdGFsbCwgZXZhbCA9IEZBTFNFfQ0KaW5zdGFsbC5wYWNrYWdlcyhjKCJrbml0ciIsICJkcGx5ciIsICJnZ3Bsb3QyIiwgImJhYnluYW1lcyIpLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQ0KYGBgDQoNCkEgYnJpZWYgYXNpZGU6IA0KYGMoKWAgaXMgYSBjb21tYW5kIGluIFIgdGhhdCBhbGxvd3MgdXMgdG8gY29tYmluZSB0aGluZ3MgaW50byBhIGB2ZWN0b3JgICggb25lIG9mIHRoZSB3YXlzIGRhdGEgaXMgcmVwcmVzZW50ZWQgaW4gUikNCg0KYGBge3IgY19kZW1vfQ0KYygiaGVsbG8iLCAibXkiLCAibmFtZSIsICJpcyIsICJhcnZpbmQiKQ0KYygxOjMsIDIwLCA1MCkNCg0KYGBgDQoNCg0KKiBJZiB5b3Ugd2FudCAqaGVscCosIG5vIHF1b3RlcyBhcmUgbmVlZGVkOiBgaGVscChuYW1lX29mX3BhY2thZ2UpYCBvciBgP25hbWVfb2ZfcGFja2FnZWAuDQoqIElmIHlvdSB3YW50IHRoZSAqY2l0YXRpb24qIGZvciBhIHBhY2thZ2UgKGFuZCB5b3Ugc2hvdWxkIGdpdmUgY3JlZGl0IHdoZXJlIGNyZWRpdCBpcyBkdWUpLCBhc2sgUiBhcyBpbiBgY2l0YXRpb24oIm5hbWVfb2ZfcGFja2FnZSIpYC4NCg0KYGBge3Igc2hvd19kcGx5ciwgZXZhbCA9IEZ9DQppbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIsIGRlcGVuZGVuY2llcyA9IFRSVUUpDQpsaWJyYXJ5KGRwbHlyKQ0KaGVscCgiZHBseXIiKQ0KYGBgDQoNCmBgYHtyIGhlbHBfZHBseXJ9DQpjaXRhdGlvbigiZ2dwbG90MiIpDQpgYGANCg0KIyBNYWtlIGEgbmFtZSBwbG90DQoNClRoZSB3ZWJwYWdlIHlvdSBhcmUgbG9va2luZyBhdCBpcyBkZXJpdmVkIGZyb20gYSBgUiBNYXJrZG93bmAgZG9jIHRoYXQgeW91IGNhbiBkb3dubG9hZCwgZWRpdCBhbmQgY29tcHV0ZSB3aXRoLiBXZSB3aWxsIG1lZXQgYFIgTWFya2Rvd25gIGluIHRoZSBuZXh0IGNsYXNzLiANCg0KRG93bmxvYWQgdGhpcyAuUm1kIGZpbGUgdXNpbmcgdGhlIGBDb2RlLT5Eb3dubG9hZCBSbWRgIGJ1dHRvbiBhdCB0aGUgdG9wIHJpZ2h0IGNvcm5lci4NCg0KQ2hhbmdlIHRoZSBhdXRob3IgbmFtZSB0byB5b3VyIG93biENCg0KSGl0IHRoZSBncmVlbiAicGxheSIgYnV0dG9uIHRvIHJ1biB0aGlzICJsb2FkX3BhY2thZ2VzIiAqY2h1bmsqIHRvIGluY2x1ZGUgaW4geW91ciBSIHNlc3Npb24gYWxsIHRoZSBpbnN0YWxsZWQgcGFja2FnZXMgeW91IG5lZWQ6IA0KDQpgYGB7ciBsb2FkX3BhY2thZ2VzLCBpbmNsdWRlID0gRkFMU0UsIGNhY2hlID0gRkFMU0V9DQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlcnJvciA9IFRSVUUsIGNvbW1lbnQgPSBOQSwgd2FybmluZ3MgPSBGQUxTRSwgZXJyb3JzID0gRkFMU0UsIG1lc3NhZ2VzID0gRkFMU0UsIHRpZHkgPSBGQUxTRSkNCmxpYnJhcnkoa25pdHIpICMgdG8gdXNlIHRoaXMuLi4uZG9jdW1lbnQhIE1vcmUgbGF0ZXIhIQ0KbGlicmFyeShkcGx5cikgIyBmb3IgbWFuaXB1bGF0aW5nIGRhdGENCmxpYnJhcnkoZ2dwbG90MikgIyBmb3IgcGxvdHRpbmcgZGF0YQ0KbGlicmFyeShiYWJ5bmFtZXMpICMgQSBwYWNrYWdlIGNvbnRhaW5pbmcsIHllcywgQmFieSBOYW1lcw0KDQpgYGANCg0KTGV0IHVzIGdyZWV0IG91ciBkYXRhIGZpcnN0ICEhDQoNCmBgYHtyIGhsb19kYXRhc2V0fQ0KZ2xpbXBzZShiYWJ5bmFtZXMpICMgZHBseXINCmhlYWQoYmFieW5hbWVzKSAjIGJhc2UgUg0KdGFpbChiYWJ5bmFtZXMpICMgc2FtZQ0KbmFtZXMoYmFieW5hbWVzKSAjIHNhbWUNCmBgYA0KDQoNCklmIHlvdSBoYXZlIGRvbmUgdGhlIGFib3ZlIGFuZCBwcm9kdWNlZCBzYW5lLWxvb2tpbmcgb3V0cHV0LCB5b3UgYXJlIHJlYWR5IGZvciB0aGUgbmV4dCBiaXQuIFVzZSB0aGUgY29kZSBiZWxvdyB0byBjcmVhdGUgYSBuZXcgZGF0YSBmcmFtZSBjYWxsZWQgYGFydmluZGAuIA0KDQpgYGB7ciBtYW5pcHVsYXRlX25hbWVfZGF0YX0NCm15X25hbWVfZGF0YSA8LSBiYWJ5bmFtZXMgJT4lDQogIGZpbHRlcihuYW1lID09ICJBcnZpbmQiIHwgbmFtZSA9PSAiQXJhdmluZCIpICU+JSANCiAgZmlsdGVyKHNleCA9PSAiTSIpIA0KYGBgDQoNCiogVGhlIGZpcnN0IGJpdCBtYWtlcyBhIG5ldyBkYXRhc2V0IGNhbGxlZCBgbXlfbmFtZV9kYXRhYCB0aGF0IGlzIGEgY29weSBvZiB0aGUgYGJhYnluYW1lc2AgZGF0YXNldC0gdGhlIGAlPiVgIHRlbGxzIHlvdSB3ZSBhcmUgZG9pbmcgc29tZSBvdGhlciBzdHVmZiB0byBpdCBsYXRlci4NCg0KKiBUaGUgc2Vjb25kIGJpdCBgZmlsdGVyc2Agb3VyIGBiYWJ5bmFtZXNgIHRvIG9ubHkga2VlcCByb3dzIHdoZXJlIHRoZSBgbmFtZWAgaXMgZWl0aGVyIEFydmluZCBvciBBcmF2aW5kIChyZWFkIGB8YCBhcyBfIm9yIl8uKSANCg0KKiBUaGUgdGhpcmQgYml0IGFwcGxpZXMgYW5vdGhlciBgZmlsdGVyYCB0byBrZWVwIG9ubHkgdGhvc2Ugd2hlcmUgc2V4IGlzIG1hbGUuDQoNCkxldCdzIGNoZWNrIG91dCB0aGUgZGF0YS4NCg0KYGBge3J9DQpteV9uYW1lX2RhdGENCmdsaW1wc2UobXlfbmFtZV9kYXRhKQ0KYGBgDQoNCkFnYWluLCBpZiB5b3UgaGF2ZSBzYW5lLWxvb2tpbmcgb3V0cHV0IGhlcmUsIG1vdmUgYWxvbmcgdG8gcGxvdHRpbmcgdGhlIGRhdGEhDQoNCmBgYHtyIHBsb3RfbmFtZV9kYXRhfQ0KDQpwbG90IDwtIGdncGxvdChteV9uYW1lX2RhdGEsIGFlcyh4ID0geWVhciwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gcHJvcCwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBuYW1lLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gbmFtZSkpICsgDQogIGdlb21fbGluZSgpDQoNCmBgYA0KDQpOb3cgaWYgeW91IGRpZCB0aGlzIHJpZ2h0LCB5b3Ugd2lsbCAqKm5vdCBzZWUqKiB5b3VyIHBsb3QhDQoNCkJlY2F1c2Ugd2Ugc2F2ZWQgdGhlIGBnZ3Bsb3RgIHdpdGggYSBuYW1lIChgcGxvdGApLCBSIGp1c3Qgc2F2ZWQgdGhlIG9iamVjdCBmb3IgeW91LiBCdXQgY2hlY2sgb3V0IHRoZSB0b3AgcmlnaHQgcGFuZSBpbiBSU3R1ZGlvIGFnYWluOiB1bmRlciB0aGUgYEVudmlyb25tZW50YCBwYW5lIHlvdSBzaG91bGQgc2VlIGBwbG90YCwgc28gaXQgaXMgdGhlcmUsIHlvdSBqdXN0IGhhdmUgdG8gYXNrIGZvciBpdC4gSGVyZSdzIGhvdzoNCg0KYGBge3J9DQoNCnBsb3QgDQoNCmBgYA0KDQojIE1ha2UgYSBuZXcgbmFtZSBwbG90DQoNCkVkaXQgbXkgY29kZSBhYm92ZSB0byBjcmVhdGUgYSBuZXcgZGF0YXNldC4gUGljayAyIG5hbWVzIHRvIGNvbXBhcmUgaG93IHBvcHVsYXIgdGhleSBlYWNoIGFyZSAodGhlc2UgY291bGQgYmUgZGlmZmVyZW50IHNwZWxsaW5ncyBvZiB5b3VyIG93biBuYW1lLCBsaWtlIEkgZGlkLCBidXQgeW91IGNhbiBjaG9vc2UgYW55IDIgbmFtZXMgdGhhdCBhcmUgcHJlc2VudCBpbiB0aGUgZGF0YXNldCkuIE1ha2UgdGhlIG5ldyBwbG90LCBjaGFuZ2luZyB0aGUgbmFtZSBvZiB0aGUgZmlyc3QgYXJndW1lbnQgYGFydmluZGAgaW4gYGdncGxvdCgpYCB0byB0aGUgbmFtZSBvZiB5b3VyIG5ldyBkYXRhc2V0Lg0KDQoNCiMjIFNhdmUgYW5kIHNoYXJlIA0KDQpTYXZlIHlvdXIgd29yayBzbyB5b3UgY2FuIHNoYXJlIHlvdXIgZmF2b3JpdGUgcGxvdCB3aXRoIHVzLiBZb3Ugd2lsbCBub3QgbGlrZSB0aGUgbG9va3Mgb2YgeW91ciBwbG90IGlmIHlvdSBtb3VzZSBvdmVyIHRvIGBFeHBvcnRgIGFuZCBzYXZlIGl0LiBJbnN0ZWFkLCB1c2UgYGdncGxvdDJgJ3MgY29tbWFuZCBmb3Igc2F2aW5nIGEgcGxvdCB3aXRoIHNlbnNpYmxlIGRlZmF1bHRzOg0KDQpgYGB7ciBldmFsID0gRkFMU0V9DQoNCmhlbHAoZ2dzYXZlKQ0KDQpgYGANCg0KYGBge3IgZXZhbCA9IEZ9DQoNCmdnc2F2ZSgiZmlsZV9uYW1lX2hlcmUucGRmIiwgcGxvdCkgIyBwbGVhc2UgbWFrZSB0aGUgZmlsZW5hbWUgdW5pcXVlIQ0KDQpgYGANCg0KVXBsb2FkIHRoaXMgZXhwb3J0ZWQgcGxvdCB0byBUZWFtcyAtPiBBc3NpZ25tZW50cy4gDQoNCioqQmVmb3JlIHlvdSBkbyB0aGF0KiosIGNoZWNrIHRoYXQgeW91IGNhbiBzdWJtaXQgc3R1ZmYvYXNzaWdubWVudHMgb24gVGVhbXMgYnkgdXBsb2FkaW5nIGEgY2F0IHBpY3R1cmUgZmlyc3QsIGVzcGVjaWFsbHkgaWYgeW91IGFyZSBhbiAqKmFpbHVyb3BoaWxlKiogbGlrZSBtZS4gKEFjY2VwdGFibGUgQnJlZWRzOiBTY290dGlzaCBGb2xkcyBvciBNYWluZSBDb29ucykNCg0K