Welcome to my very first Tidy Tuesday!
I hope you enjoy this journey from a very terrible graph to a beautiful plot. Maybe my notes and workflow help you learn a thing or two, I know I had to learn a few tricks today!
What I learned today that I didnt already know:
Manipulating the facet labels: this is one thing I’ve not done before.
I also got more familiar with mutate
in the tidyverse.
And playing around with adding text outside of the plot, such as customize labels and notes.
The github README and data can be found here
The Economist Article on “Greying of the Nobel laureates: Over the years, the committee has been bestowing the honour on older and older recipients” was published on Oct 3rd 2016.
My TidyTuesday goal is to recreate The Economists graph:
Lets load the data
library(tidyverse)
library(here)
library(janitor)
nobel_winners <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-05-14/nobel_winners.csv")
nobel_winner_all_pubs <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-05-14/nobel_winner_all_pubs.csv")
Since I want the x axis to be year awarded and the y axis to be the age of the laureate, I need to calculate age.
First stab at a plot
nobel_winners %>%
mutate(birth_year = substring(nobel_winners$birth_date, 1, 4), birth_year = as.integer(birth_year)) %>%
mutate(laureate_age = prize_year - birth_year) %>%
ggplot() +
geom_point(aes(x=prize_year, y=laureate_age))
Facet by Category
In the correct order that The Economist listed. And also add the smooth line.
require(gdata)
target <- c("Medicine", "Physics", "Chemistry","Economics","Literature","Peace") #Order defined
nobel_winners %>%
mutate(birth_year = substring(nobel_winners$birth_date, 1, 4), birth_year = as.integer(birth_year)) %>%
mutate(laureate_age = prize_year - birth_year) %>%
mutate(category = reorder.factor(category, new.order=target)) %>% #reorder by defined order
ggplot() +
geom_point(aes(x=prize_year, y=laureate_age))+
facet_grid(.~category)+
geom_smooth(aes(x=prize_year, y=laureate_age),se=FALSE)
Im getting closer!
Now I just need to tidy up the axis
ggplot() +
geom_point(aes(x=prize_year, y=laureate_age))+
facet_grid(.~category)+
geom_smooth(aes(x=prize_year, y=laureate_age),se=FALSE)+
scale_y_continuous(position = "right", limits = c(15,100)) + #update y axis
theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(), axis.title.y=element_blank()) #edit grid background and rm y axis label
Adjusting the facet labels
To blend in with plot + changes to the x axis
theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(),
axis.title.y=element_blank(),axis.title.x=element_blank(),
strip.background =element_rect(fill="grey92"), #change facet label background color
strip.text.x = element_text(angle = 0, hjust = 0)) + #move labelled text to the left
scale_x_continuous(limits = c(1900,2016), breaks = c(1900, 1950, 2000)) #adjust x axis increments
Colors Anyone?
I found this article on The Economist color schemes, but I still had to eyeball it for a couple, using this handy dandy color chart.
geom_point(aes(x=prize_year, y=laureate_age, colour = category), shape = 1)+ #add color and hollow point
geom_smooth(aes(x=prize_year, y=laureate_age, colour = category),se=FALSE, lwd=1.5)+ #add color and thicken line
theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(),
axis.title.y=element_blank(),axis.title.x=element_blank(),
strip.background =element_rect(fill="grey92"),
strip.text.x = element_text(angle = 0, hjust = 0),
legend.position="none") , #remove legend
strip.text = element_text(colour = "grey25")) + # change facet text color
scale_colour_manual(values = c("#014d64","#90353B","#EE6A50","#2D6D66","#EE9A00","#01A2D9")) #manual color
Unfortanetly, ggplot does not easily change the facet text colors by category. I read a forum post on this if you want to really change the plotting, however I decided to take the hit and not do it.
What one could try to do is make the text “invisible” by making it the same color as the background, and they overlay individually the category text with the correct color.
Adding additional text
The tricky part….. adding text of the oldest and youngest winners with a little line to the point. hmmmmmm
theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(),
axis.title.y=element_blank(),axis.title.x=element_blank(),
strip.background =element_rect(fill="grey92"),
strip.text.x = element_text(angle = 0, hjust = 0),
legend.position="none",
strip.text = element_text(colour = "grey24", face = 'bold'), #bold facet labels
plot.title = element_text(face = 'bold', hjust = 0), #change title to left align
plot.caption = element_text(hjust = 0), #change caption to left align
axis.text = element_text(face = 'bold')) +
labs(title = 'Senescience', subtitle ='Age of Nobel laureates, at date of award ', caption ='Source: Nobelprize.org ') + #add labels
annotate("text", x= Inf, y= 96, label = "Oldest winner \n Leonid Hurwicz, 90", hjust = 1, size = 2.5, colour = c("grey92","grey92","grey92","#2D6D66","grey92","grey92")) + #add Oldest
annotate("text", x= Inf, y= 25, label = "Youngest winner \n Malala Yousafzai, 17", hjust = 1, size = 2.5, colour = c("grey92","grey92","grey92","grey92","grey92","#01A2D9")) #add youngest
I cant get all the text outside of the plot, buts its very close. Also the legend is a little tricky
Not bad, not bad
S.MARTINEZ
THE ECONOMIST
Side note: our own favorite wheat hero, Norman E. Borlaug’s laureate_id
is 528
.
library(kableExtra)
nobel_winners %>%
filter(laureate_id == '528') %>%
kable(caption = "Table 1: Summary Norman E. Borlougs Nobel Peace Prize") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F)
Table 1: Summary Norman E. Borlougs Nobel Peace Prize
prize_year
|
category
|
prize
|
motivation
|
prize_share
|
laureate_id
|
laureate_type
|
full_name
|
birth_date
|
birth_city
|
birth_country
|
gender
|
organization_name
|
organization_city
|
organization_country
|
death_date
|
death_city
|
death_country
|
1970
|
Peace
|
The Nobel Peace Prize 1970
|
NA
|
1/1
|
528
|
Individual
|
Norman E. Borlaug
|
1914-03-25
|
Cresco, IA
|
United States of America
|
Male
|
NA
|
NA
|
NA
|
2009-09-12
|
Dallas, TX
|
United States of America
|
LS0tDQp0aXRsZTogIlRpZHlUdWVzZGF5V2syMCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0aGVtZTogZmxhdGx5DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJVkuJW0uJWQnKWAiDQphdXRob3I6IFMuQS4gTWFydGluZXoNCg0KLS0tDQoNCioqV2VsY29tZSB0byBteSB2ZXJ5IGZpcnN0IFRpZHkgVHVlc2RheSEqKiAgIA0KDQpJIGhvcGUgeW91IGVuam95IHRoaXMgam91cm5leSBmcm9tIGEgdmVyeSB0ZXJyaWJsZSBncmFwaCB0byBhIGJlYXV0aWZ1bCBwbG90LiBNYXliZSBteSBub3RlcyBhbmQgd29ya2Zsb3cgaGVscCB5b3UgbGVhcm4gYSB0aGluZyBvciB0d28sIEkga25vdyBJIGhhZCB0byBsZWFybiBhIGZldyB0cmlja3MgdG9kYXkhDQoNCioqV2hhdCBJIGxlYXJuZWQgdG9kYXkgdGhhdCBJIGRpZG50IGFscmVhZHkga25vdzoqKiAgDQoNCj4gTWFuaXB1bGF0aW5nIHRoZSBmYWNldCBsYWJlbHM6IHRoaXMgaXMgb25lIHRoaW5nIEkndmUgbm90IGRvbmUgYmVmb3JlLiAgDQo+IEkgYWxzbyBnb3QgbW9yZSBmYW1pbGlhciB3aXRoIGBtdXRhdGVgIGluIHRoZSB0aWR5dmVyc2UuICANCj4gQW5kIHBsYXlpbmcgYXJvdW5kIHdpdGggYWRkaW5nIHRleHQgb3V0c2lkZSBvZiB0aGUgcGxvdCwgc3VjaCBhcyBjdXN0b21pemUgbGFiZWxzIGFuZCBub3Rlcy4gIA0KDQotLS0tLQ0KDQpUaGUgZ2l0aHViIFtSRUFETUVdKGh0dHBzOi8vZ2l0aHViLmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvYmxvYi9tYXN0ZXIvZGF0YS8yMDE5LzIwMTktMDUtMTQvcmVhZG1lLm1kKSBhbmQgZGF0YSBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvdHJlZS9tYXN0ZXIvZGF0YS8yMDE5LzIwMTktMDUtMTQpICANCg0KVGhlIFtFY29ub21pc3QgQXJ0aWNsZV0oaHR0cHM6Ly93d3cuZWNvbm9taXN0LmNvbS9ncmFwaGljLWRldGFpbC8yMDE2LzEwLzAzL2dyZXlpbmctb2YtdGhlLW5vYmVsLWxhdXJlYXRlcykgb24gIkdyZXlpbmcgb2YgdGhlIE5vYmVsIGxhdXJlYXRlczogT3ZlciB0aGUgeWVhcnMsIHRoZSBjb21taXR0ZWUgaGFzIGJlZW4gYmVzdG93aW5nIHRoZSBob25vdXIgb24gb2xkZXIgYW5kIG9sZGVyIHJlY2lwaWVudHMiIHdhcyBwdWJsaXNoZWQgb24gT2N0IDNyZCAyMDE2LiAgDQoNCioqTXkgVGlkeVR1ZXNkYXkgZ29hbCBpcyB0byByZWNyZWF0ZSBUaGUgRWNvbm9taXN0cyBncmFwaDoqKiAgIA0KDQohW10oVGlkeVR1ZXNkYXlXazIwX0Vjb25vbWlzdFBsb3QucG5nKQ0KDQotLS0tLS0tDQoNCiMjIyBMZXRzIGxvYWQgdGhlIGRhdGEgIA0KYGBge3IgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UgfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGphbml0b3IpDQoNCm5vYmVsX3dpbm5lcnMgPC0gcmVhZHI6OnJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMTkvMjAxOS0wNS0xNC9ub2JlbF93aW5uZXJzLmNzdiIpDQpub2JlbF93aW5uZXJfYWxsX3B1YnMgPC0gcmVhZHI6OnJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMTkvMjAxOS0wNS0xNC9ub2JlbF93aW5uZXJfYWxsX3B1YnMuY3N2IikNCmBgYA0KDQpTaW5jZSBJIHdhbnQgdGhlIHggYXhpcyB0byBiZSB5ZWFyIGF3YXJkZWQgYW5kIHRoZSB5IGF4aXMgdG8gYmUgdGhlIGFnZSBvZiB0aGUgbGF1cmVhdGUsIEkgbmVlZCB0byBjYWxjdWxhdGUgYWdlLg0KDQojIyMgRmlyc3Qgc3RhYiBhdCBhIHBsb3QgDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0Kbm9iZWxfd2lubmVycyAlPiUgDQogIG11dGF0ZShiaXJ0aF95ZWFyID0gc3Vic3RyaW5nKG5vYmVsX3dpbm5lcnMkYmlydGhfZGF0ZSwgMSwgNCksIGJpcnRoX3llYXIgPSBhcy5pbnRlZ2VyKGJpcnRoX3llYXIpKSAlPiUNCiAgbXV0YXRlKGxhdXJlYXRlX2FnZSA9IHByaXplX3llYXIgLSBiaXJ0aF95ZWFyKSAlPiUNCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSkNCg0KYGBgDQoNCiMjIyBGYWNldCBieSBgQ2F0ZWdvcnlgIA0KSW4gdGhlIGNvcnJlY3Qgb3JkZXIgdGhhdCBUaGUgRWNvbm9taXN0IGxpc3RlZC4gQW5kIGFsc28gYWRkIHRoZSBzbW9vdGggbGluZS4gIA0KDQpgYGB7ciAgZXZhbD1GQUxTRX0NCnJlcXVpcmUoZ2RhdGEpDQp0YXJnZXQgPC0gYygiTWVkaWNpbmUiLCAiUGh5c2ljcyIsICJDaGVtaXN0cnkiLCJFY29ub21pY3MiLCJMaXRlcmF0dXJlIiwiUGVhY2UiKSAjT3JkZXIgZGVmaW5lZA0KDQpub2JlbF93aW5uZXJzICU+JSANCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBzdWJzdHJpbmcobm9iZWxfd2lubmVycyRiaXJ0aF9kYXRlLCAxLCA0KSwgYmlydGhfeWVhciA9IGFzLmludGVnZXIoYmlydGhfeWVhcikpICU+JQ0KICBtdXRhdGUobGF1cmVhdGVfYWdlID0gcHJpemVfeWVhciAtIGJpcnRoX3llYXIpICU+JQ0KICBtdXRhdGUoY2F0ZWdvcnkgPSByZW9yZGVyLmZhY3RvcihjYXRlZ29yeSwgbmV3Lm9yZGVyPXRhcmdldCkpICU+JSAgI3Jlb3JkZXIgYnkgZGVmaW5lZCBvcmRlcg0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSkpKw0KICAgIGZhY2V0X2dyaWQoLn5jYXRlZ29yeSkrDQogICAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UpLHNlPUZBTFNFKQ0KYGBgDQoNCmBgYHtyICBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShnZGF0YSkNCnRhcmdldCA8LSBjKCJNZWRpY2luZSIsICJQaHlzaWNzIiwgIkNoZW1pc3RyeSIsIkVjb25vbWljcyIsIkxpdGVyYXR1cmUiLCJQZWFjZSIpICNPcmRlciBkZWZpbmVkDQoNCm5vYmVsX3dpbm5lcnMgJT4lIA0KICBtdXRhdGUoYmlydGhfeWVhciA9IHN1YnN0cmluZyhub2JlbF93aW5uZXJzJGJpcnRoX2RhdGUsIDEsIDQpLCBiaXJ0aF95ZWFyID0gYXMuaW50ZWdlcihiaXJ0aF95ZWFyKSkgJT4lDQogIG11dGF0ZShsYXVyZWF0ZV9hZ2UgPSBwcml6ZV95ZWFyIC0gYmlydGhfeWVhcikgJT4lDQogIG11dGF0ZShjYXRlZ29yeSA9IHJlb3JkZXIuZmFjdG9yKGNhdGVnb3J5LCBuZXcub3JkZXI9dGFyZ2V0KSkgJT4lICAjcmVvcmRlciBieSBkZWZpbmVkIG9yZGVyDQogIGdncGxvdCgpICsNCiAgICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSkrDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSksc2U9RkFMU0UpDQpgYGANCg0KIyMjIEltIGdldHRpbmcgY2xvc2VyISAgIA0KDQpOb3cgSSBqdXN0IG5lZWQgdG8gdGlkeSB1cCB0aGUgYXhpcw0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSkpKw0KICAgIGZhY2V0X2dyaWQoLn5jYXRlZ29yeSkrDQogICAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UpLHNlPUZBTFNFKSsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMocG9zaXRpb24gPSAicmlnaHQiLCBsaW1pdHMgPSBjKDE1LDEwMCkpICsgICAjdXBkYXRlIHkgYXhpcyANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpICNlZGl0IGdyaWQgYmFja2dyb3VuZCBhbmQgcm0geSBheGlzIGxhYmVsDQpgYGANCg0KYGBge3IgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShnZGF0YSkNCnRhcmdldCA8LSBjKCJNZWRpY2luZSIsICJQaHlzaWNzIiwgIkNoZW1pc3RyeSIsIkVjb25vbWljcyIsIkxpdGVyYXR1cmUiLCJQZWFjZSIpIA0KDQpub2JlbF93aW5uZXJzICU+JSANCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBzdWJzdHJpbmcobm9iZWxfd2lubmVycyRiaXJ0aF9kYXRlLCAxLCA0KSwgYmlydGhfeWVhciA9IGFzLmludGVnZXIoYmlydGhfeWVhcikpICU+JQ0KICBtdXRhdGUobGF1cmVhdGVfYWdlID0gcHJpemVfeWVhciAtIGJpcnRoX3llYXIpICU+JQ0KICBtdXRhdGUoY2F0ZWdvcnkgPSByZW9yZGVyLmZhY3RvcihjYXRlZ29yeSwgbmV3Lm9yZGVyPXRhcmdldCkpICU+JSAgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSkrDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSksc2U9RkFMU0UpKw0KICAgIHNjYWxlX3lfY29udGludW91cyhwb3NpdGlvbiA9ICJyaWdodCIsIGxpbWl0cyA9IGMoMTUsMTAwKSkgKyAgICN1cGRhdGUgeSBheGlzIA0KICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkgI2VkaXQgZ3JpZCBiYWNrZ3JvdW5kIGFuZCBybSB5IGF4aXMgbGFiZWwNCmBgYA0KDQoNCiMjIyBBZGp1c3RpbmcgdGhlIGZhY2V0IGxhYmVscw0KVG8gYmxlbmQgaW4gd2l0aCBwbG90ICsgY2hhbmdlcyB0byB0aGUgeCBheGlzIA0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9ZWxlbWVudF9yZWN0KGZpbGw9ImdyZXk5MiIpLCAjY2hhbmdlIGZhY2V0IGxhYmVsIGJhY2tncm91bmQgY29sb3IgDQogICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwKSkgKyAjbW92ZSBsYWJlbGxlZCB0ZXh0IHRvIHRoZSBsZWZ0DQogICAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMTkwMCwyMDE2KSwgYnJlYWtzID0gYygxOTAwLCAxOTUwLCAyMDAwKSkgI2FkanVzdCB4IGF4aXMgaW5jcmVtZW50cyANCmBgYA0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpyZXF1aXJlKGdkYXRhKQ0KdGFyZ2V0IDwtIGMoIk1lZGljaW5lIiwgIlBoeXNpY3MiLCAiQ2hlbWlzdHJ5IiwiRWNvbm9taWNzIiwiTGl0ZXJhdHVyZSIsIlBlYWNlIikgDQoNCm5vYmVsX3dpbm5lcnMgJT4lIA0KICBtdXRhdGUoYmlydGhfeWVhciA9IHN1YnN0cmluZyhub2JlbF93aW5uZXJzJGJpcnRoX2RhdGUsIDEsIDQpLCBiaXJ0aF95ZWFyID0gYXMuaW50ZWdlcihiaXJ0aF95ZWFyKSkgJT4lDQogIG11dGF0ZShsYXVyZWF0ZV9hZ2UgPSBwcml6ZV95ZWFyIC0gYmlydGhfeWVhcikgJT4lDQogIG11dGF0ZShjYXRlZ29yeSA9IHJlb3JkZXIuZmFjdG9yKGNhdGVnb3J5LCBuZXcub3JkZXI9dGFyZ2V0KSkgJT4lICANCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UpKSsNCiAgICBmYWNldF9ncmlkKC5+Y2F0ZWdvcnkpKw0KICAgIGdlb21fc21vb3RoKGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSxzZT1GQUxTRSkrDQogICAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gInJpZ2h0IiwgbGltaXRzID0gYygxNSwxMDApKSArICANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJncmV5OTIiKSwgI2NoYW5nZSBmYWNldCBsYWJlbCBiYWNrZ3JvdW5kIGNvbG9yIA0KICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMCkpICsgI21vdmUgbGFiZWxsZWQgdGV4dCB0byB0aGUgbGVmdA0KICAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDE5MDAsMjAxNiksIGJyZWFrcyA9IGMoMTkwMCwgMTk1MCwgMjAwMCkpICNhZGp1c3QgeCBheGlzIGluY3JlbWVudHMgDQpgYGANCg0KLS0tLS0NCg0KIyMjIENvbG9ycyBBbnlvbmU/ICAgICANCkkgZm91bmQgdGhpcyBbYXJ0aWNsZV0oaHR0cHM6Ly95dXRhbm5paGlsYXRpb24uZ2l0aHViLmlvL2FsbFlvdXJGaWd1cmVBcmVCZWxvbmdUb1VzL2dndGhlbWVzL2Vjb25vbWlzdF9wYWwvKSBvbiBUaGUgRWNvbm9taXN0IGNvbG9yIHNjaGVtZXMsIGJ1dCBJIHN0aWxsIGhhZCB0byBleWViYWxsIGl0IGZvciBhIGNvdXBsZSwgdXNpbmcgdGhpcyBoYW5keSBkYW5keSBbY29sb3IgY2hhcnRdKGh0dHA6Ly9yZXNlYXJjaC5zdG93ZXJzLm9yZy9tY20vZWZnL1IvQ29sb3IvQ2hhcnQvQ29sb3JDaGFydC5wZGYpLiAgDQoNCmBgYHtyIGV2YWw9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KICAgIGdlb21fcG9pbnQoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UsIGNvbG91ciA9IGNhdGVnb3J5KSwgc2hhcGUgPSAxKSsgICNhZGQgY29sb3IgYW5kIGhvbGxvdyBwb2ludCANCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLHNlPUZBTFNFLCBsd2Q9MS41KSsgI2FkZCBjb2xvciBhbmQgdGhpY2tlbiBsaW5lDQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID1lbGVtZW50X3JlY3QoZmlsbD0iZ3JleTkyIiksIA0KICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMCksDQogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikgLCAjcmVtb3ZlIGxlZ2VuZA0KICAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImdyZXkyNSIpKSArICMgY2hhbmdlIGZhY2V0IHRleHQgY29sb3INCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiMwMTRkNjQiLCIjOTAzNTNCIiwiI0VFNkE1MCIsIiMyRDZENjYiLCIjRUU5QTAwIiwiIzAxQTJEOSIpKSAjbWFudWFsIGNvbG9yDQpgYGANCg0KYGBge3IgZWNobyAgPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCnJlcXVpcmUoZ2RhdGEpDQp0YXJnZXQgPC0gYygiTWVkaWNpbmUiLCAiUGh5c2ljcyIsICJDaGVtaXN0cnkiLCJFY29ub21pY3MiLCJMaXRlcmF0dXJlIiwiUGVhY2UiKSANCg0KbGlicmFyeShleHRyYWZvbnQpDQpub2JlbF93aW5uZXJzICU+JSANCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBzdWJzdHJpbmcobm9iZWxfd2lubmVycyRiaXJ0aF9kYXRlLCAxLCA0KSwgYmlydGhfeWVhciA9IGFzLmludGVnZXIoYmlydGhfeWVhcikpICU+JQ0KICBtdXRhdGUobGF1cmVhdGVfYWdlID0gcHJpemVfeWVhciAtIGJpcnRoX3llYXIpICU+JQ0KICBtdXRhdGUoY2F0ZWdvcnkgPSByZW9yZGVyLmZhY3RvcihjYXRlZ29yeSwgbmV3Lm9yZGVyPXRhcmdldCkpICU+JSAgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlLCBjb2xvdXIgPSBjYXRlZ29yeSksIHNoYXBlID0gMSkrICAjYWRkIGNvbG9yIGFuZCBob2xsb3cgcG9pbnQgDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLHNlPUZBTFNFLCBsd2Q9MS41KSsgI2FkZCBjb2xvciBhbmQgdGhpY2tlbiBsaW5lDQogICAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gInJpZ2h0IiwgbGltaXRzID0gYygxNSwxMDApKSArICANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJncmV5OTIiKSwgDQogICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwKSwNCiAgICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLCAjcmVtb3ZlIGxlZ2VuZA0KICAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImdyZXkyNSIpKSArICMgY2hhbmdlIGZhY2V0IHRleHQgY29sb3INCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygxOTAwLDIwMTYpLCBicmVha3MgPSBjKDE5MDAsIDE5NTAsIDIwMDApKSsgDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDE0ZDY0IiwiIzkwMzUzQiIsIiNFRTZBNTAiLCIjMkQ2RDY2IiwiI0VFOUEwMCIsIiMwMUEyRDkiKSkgDQpgYGANCg0KVW5mb3J0YW5ldGx5LCBnZ3Bsb3QgZG9lcyBub3QgZWFzaWx5IGNoYW5nZSB0aGUgZmFjZXQgdGV4dCBjb2xvcnMgYnkgY2F0ZWdvcnkuIEkgcmVhZCBhIFtmb3J1bSBwb3N0XShodHRwczovL2dpdGh1Yi5jb20vdGlkeXZlcnNlL2dncGxvdDIvaXNzdWVzLzIwOTYpIG9uIHRoaXMgaWYgeW91IHdhbnQgdG8gcmVhbGx5IGNoYW5nZSB0aGUgcGxvdHRpbmcsIGhvd2V2ZXIgSSBkZWNpZGVkIHRvIHRha2UgdGhlIGhpdCBhbmQgbm90IGRvIGl0LiAgDQoNCldoYXQgb25lIGNvdWxkIHRyeSB0byBkbyBpcyBtYWtlIHRoZSB0ZXh0ICJpbnZpc2libGUiIGJ5IG1ha2luZyBpdCB0aGUgc2FtZSBjb2xvciBhcyB0aGUgYmFja2dyb3VuZCwgYW5kIHRoZXkgb3ZlcmxheSBpbmRpdmlkdWFsbHkgdGhlIGNhdGVnb3J5IHRleHQgd2l0aCB0aGUgY29ycmVjdCBjb2xvci4gIA0KDQojIyMgQWRkaW5nIGFkZGl0aW9uYWwgdGV4dCAgDQpUaGUgdHJpY2t5IHBhcnQuLi4uLiBhZGRpbmcgdGV4dCBvZiB0aGUgb2xkZXN0IGFuZCB5b3VuZ2VzdCB3aW5uZXJzIHdpdGggYSBsaXR0bGUgbGluZSB0byB0aGUgcG9pbnQuIGhtbW1tbW0NCg0KYGBge3IgZXZhbD0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID1lbGVtZW50X3JlY3QoZmlsbD0iZ3JleTkyIiksIA0KICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMCksDQogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwgDQogICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiZ3JleTI0IiwgZmFjZSA9ICdib2xkJyksICNib2xkIGZhY2V0IGxhYmVscw0KICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICdib2xkJywgaGp1c3QgPSAwKSwgICNjaGFuZ2UgdGl0bGUgdG8gbGVmdCBhbGlnbg0KICAgICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApLCAjY2hhbmdlIGNhcHRpb24gdG8gbGVmdCBhbGlnbg0KICAgICAgICAgIGF4aXMudGV4dCA9ICBlbGVtZW50X3RleHQoZmFjZSA9ICdib2xkJykpICsNCiAgICBsYWJzKHRpdGxlID0gJ1NlbmVzY2llbmNlJywgIHN1YnRpdGxlID0nQWdlIG9mIE5vYmVsIGxhdXJlYXRlcywgYXQgZGF0ZSBvZiBhd2FyZCAnLCBjYXB0aW9uID0nU291cmNlOiBOb2JlbHByaXplLm9yZyAnKSArICNhZGQgbGFiZWxzDQogICAgYW5ub3RhdGUoInRleHQiLCB4PSBJbmYsIHk9IDk2LCBsYWJlbCA9ICJPbGRlc3Qgd2lubmVyIFxuIExlb25pZCBIdXJ3aWN6LCA5MCIsIGhqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgY29sb3VyID0gYygiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiIzJENkQ2NiIsImdyZXk5MiIsImdyZXk5MiIpKSArICNhZGQgT2xkZXN0DQogICAgYW5ub3RhdGUoInRleHQiLCB4PSBJbmYsIHk9IDI1LCBsYWJlbCA9ICJZb3VuZ2VzdCB3aW5uZXIgXG4gTWFsYWxhIFlvdXNhZnphaSwgMTciLCBoanVzdCA9IDEsIHNpemUgPSAyLjUsIGNvbG91ciA9IGMoImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsIiMwMUEyRDkiKSkgI2FkZCB5b3VuZ2VzdA0KICANCmBgYA0KDQpgYGB7ciBlY2hvICA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShnZGF0YSkNCnRhcmdldCA8LSBjKCJNZWRpY2luZSIsICJQaHlzaWNzIiwgIkNoZW1pc3RyeSIsIkVjb25vbWljcyIsIkxpdGVyYXR1cmUiLCJQZWFjZSIpIA0KDQpsaWJyYXJ5KGV4dHJhZm9udCkNCg0Kbm9iZWxfd2lubmVycyAlPiUgDQogIG11dGF0ZShiaXJ0aF95ZWFyID0gc3Vic3RyaW5nKG5vYmVsX3dpbm5lcnMkYmlydGhfZGF0ZSwgMSwgNCksIGJpcnRoX3llYXIgPSBhcy5pbnRlZ2VyKGJpcnRoX3llYXIpKSAlPiUNCiAgbXV0YXRlKGxhdXJlYXRlX2FnZSA9IHByaXplX3llYXIgLSBiaXJ0aF95ZWFyKSAlPiUNCiAgbXV0YXRlKGNhdGVnb3J5ID0gcmVvcmRlci5mYWN0b3IoY2F0ZWdvcnksIG5ldy5vcmRlcj10YXJnZXQpKSAlPiUgIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLCBzaGFwZSA9IDEpKyAgDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLHNlPUZBTFNFLCBsd2Q9MS41KSsgDQogICAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gInJpZ2h0IiwgbGltaXRzID0gYygxNSwxMDApKSArICANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJncmV5OTIiKSwgDQogICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwKSwNCiAgICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLCANCiAgICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJncmV5MjQiLCBmYWNlID0gJ2JvbGQnKSwgI2JvbGQgZmFjZXQgbGFiZWxzDQogICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gJ2JvbGQnLCBoanVzdCA9IDApLCAgI2NoYW5nZSB0aXRsZSB0byBsZWZ0IGFsaWduDQogICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCksICNjaGFuZ2UgY2FwdGlvbiB0byBsZWZ0IGFsaWduDQogICAgICAgICAgYXhpcy50ZXh0ID0gIGVsZW1lbnRfdGV4dChmYWNlID0gJ2JvbGQnKSkgKyANCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygxOTAwLDIwMTYpLCBicmVha3MgPSBjKDE5MDAsIDE5NTAsIDIwMDApKSsgDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDE0ZDY0IiwiIzkwMzUzQiIsIiNFRTZBNTAiLCIjMkQ2RDY2IiwiI0VFOUEwMCIsIiMwMUEyRDkiKSkgKw0KICBsYWJzKHRpdGxlID0gJ1NlbmVzY2llbmNlJywgIHN1YnRpdGxlID0nQWdlIG9mIE5vYmVsIGxhdXJlYXRlcywgYXQgZGF0ZSBvZiBhd2FyZCAnLCBjYXB0aW9uID0nU291cmNlOiBOb2JlbHByaXplLm9yZyAnKSArICNhZGQgbGFiZWxzDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0gSW5mLCB5PSA5NiwgbGFiZWwgPSAiT2xkZXN0IHdpbm5lciBcbiBMZW9uaWQgSHVyd2ljeiwgOTAiLCBoanVzdCA9IDEsIHNpemUgPSAyLjUsIGNvbG91ciA9IGMoImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsIiMyRDZENjYiLCJncmV5OTIiLCJncmV5OTIiKSkgKyAjYWRkIE9sZGVzdA0KICBhbm5vdGF0ZSgidGV4dCIsIHg9IEluZiwgeT0gMjUsIGxhYmVsID0gIllvdW5nZXN0IHdpbm5lciBcbiBNYWxhbGEgWW91c2FmemFpLCAxNyIsIGhqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgY29sb3VyID0gYygiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiIzAxQTJEOSIpKSsgI2FkZCB5b3VuZ2VzdA0KICBnZ3NhdmUoIlRpZHlUdWVzZGF5V2syMF9QbG90LnBuZyIpDQogICANCmBgYA0KDQoNCkkgY2FudCBnZXQgYWxsIHRoZSB0ZXh0IG91dHNpZGUgb2YgdGhlIHBsb3QsIGJ1dHMgaXRzIHZlcnkgY2xvc2UuIEFsc28gdGhlIGxlZ2VuZCBpcyBhIGxpdHRsZSB0cmlja3kgIA0KDQotLS0tLQ0KDQojIyMgTm90IGJhZCwgbm90IGJhZCAgIA0KDQoqKlMuTUFSVElORVoqKg0KIVtdKFRpZHlUdWVzZGF5V2syMF9QbG90LnBuZykgDQoNCioqVEhFIEVDT05PTUlTVCoqICANCiFbXShUaWR5VHVlc2RheVdrMjBfRWNvbm9taXN0UGxvdC5wbmcpIA0KDQoNCi0tLS0tLS0NCg0KU2lkZSBub3RlOiBvdXIgb3duIGZhdm9yaXRlIHdoZWF0IGhlcm8sIE5vcm1hbiBFLiBCb3JsYXVnJ3MgYGxhdXJlYXRlX2lkYCBpcyBgNTI4YC4gIA0KDQpgYGB7ciAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSB9DQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpub2JlbF93aW5uZXJzICU+JSANCiAgZmlsdGVyKGxhdXJlYXRlX2lkID09ICc1MjgnKSAlPiUNCiAga2FibGUoY2FwdGlvbiA9ICJUYWJsZSAxOiBTdW1tYXJ5IE5vcm1hbiBFLiBCb3Jsb3VncyBOb2JlbCBQZWFjZSBQcml6ZSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLCBmdWxsX3dpZHRoID0gRikgDQpgYGA=