About this Notebook
The google search data on this notebook comes from a google account archive
The steps outlined here to collect and analyze the data may change at any time
Below are the steps to claim your google account data
Data Collection: Claming your Google Search Data
1) Sign into your google account, then Go to:
2) Find the link to download your data archive or Go to:
3) Select all Google products to create a complete archive of your data
4) After selecting the products, choose the file type and max archive size to make sure that all your account data is archive
Data Analysis: Visualizing Google Searches
To get an overall idea of the search volume, we can plot searches by year
p <- ggplot(search_data, aes(year))
p + geom_bar()
After determine the years with the largest search volume we can plot monthly searches
monthly <- search_data[(search_data$year > 2014 & search_data$year< 2018), ]
ggplot(monthly) + geom_bar(aes(x = month, group = year)) +
theme(axis.text.x = element_text(angle=90)) +
facet_grid(.~year, scales="free")
Another interesting metrict is searches by Hour
p <- ggplot(search_data, aes(hour))
p + geom_bar()
We can also plot the search data by day of the week to determine day are the most active
p <- ggplot(search_data, aes(day))
p + geom_bar()
We can take it an step further and group search time with day of the week.
ggplot(search_data) +
geom_bar(aes(x = hour, group = day) ) +
facet_grid(.~day, scales = "free")
We can group the search data by year and day of the week, to visualize the overall trend
wkday <- group_by(search_data, year, day) %>% summarize(count = n())
p <- ggplot(wkday, aes(day, count, fill = year))
p + geom_bar(stat = "identity") + labs(x = "", y = "Search Volume")
Reporting: A wordcloud from Google Search Data
First we need to extract the text and clean it using regular expressions
search <- tolower(search_data$search)
search <- iconv(search, "ASCII", "UTF-8", " ")
Error in iconv(search, "ASCII", "UTF-8", " ") :
embedded nul in string: 'glo-bus simulation C"B\0B\023 online ordering instructions discussed in class C"B\0B\023 cost $44.95/student'
After cleaning the text we can create a Text Corpus (a large and structured set of texts) and remove some words
search_corpus <- Corpus(VectorSource(search))
search_corpus <- tm_map(search_corpus, content_transformer(removePunctuation))
search_corpus <- tm_map(search_corpus, content_transformer(removeNumbers))
stopwords <- c(stopwords("english"), "chrome", "chicago", "jlroo", "google")
search_corpus <- tm_map(search_corpus, removeWords, stopwords)
search_tdm <- TermDocumentMatrix(search_corpus)
search_matrix <- as.matrix(search_tdm)
Set a threshold for the min frequency of the words to display as well as max frequency
wordcloud(d$word, d$freq, min.freq = 50, scale = c(3 , 0.5), max.words = 200)
LS0tDQp0aXRsZTogIkFuYWx5emluZyBHb29nbGUgU2VhcmNoIEhpc3RvcnkiDQphdXRob3I6ICJTdGVwaGFuaWUgTGFuY3oiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdA0KZGF0ZTogIkZlYnJ1YXJ5IDEsIDIwMTgiDQpzdWJ0aXRsZTogIkNNRSBHcm91cCBGb3VuZGF0aW9uIEJ1c2luZXNzIEFuYWx5dGljcyBMYWIiDQotLS0NCg0KPGJyPg0KDQotLS0tLS0tLS0tLS0tLQ0KDQojIyBBYm91dCB0aGlzIE5vdGVib29rDQoNCi0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KKiBUaGUgZ29vZ2xlIHNlYXJjaCBkYXRhIG9uIHRoaXMgbm90ZWJvb2sgY29tZXMgZnJvbSBhIGdvb2dsZSBhY2NvdW50IGFyY2hpdmUNCg0KKiBUaGUgc3RlcHMgb3V0bGluZWQgaGVyZSB0byBjb2xsZWN0IGFuZCBhbmFseXplIHRoZSBkYXRhIG1heSBjaGFuZ2UgYXQgYW55IHRpbWUNCg0KKiBCZWxvdyBhcmUgdGhlIHN0ZXBzIHRvIGNsYWltIHlvdXIgZ29vZ2xlIGFjY291bnQgZGF0YSANCg0KDQo8YnI+DQoNCi0tLS0tLS0tLS0tLS0tDQoNCiMjIEFuYWx5dGljcyBUb29sa2l0OiBSZXF1aXJlIFBhY2thZ2VzDQoNCi0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KKiBQYWNrYWdlOiB0aWR5dmVyc2UsIGx1YnJpZGF0ZSwgcnZlc3QsIHRtLCB3b3JkY2xvdWQNCg0KYGBge3IsIGVjaG89VFJVRX0NCg0KIyBIZXJlIHdlIGFyZSBjaGVja2luZyBpZiB0aGUgcGFja2FnZSBpcyBpbnN0YWxsZWQNCmlmKCFyZXF1aXJlKHJ2ZXN0LCBxdWlldGx5ID0gVFJVRSkpIA0KICAjIElmIHRoZSBwYWNrYWdlIGlzIG5vdCBpbiB0aGUgc3lzdGVtIHRoZW4gaXQgd2lsbCBiZSBpbnN0YWxsDQogIGluc3RhbGwucGFja2FnZXMocnZlc3QsIGRlcGVuZGVuY2llcyA9IFRSVUUsIHF1aWV0bHkgPSBUUlVFKQ0KICAjIEhlcmUgd2UgYXJlIGxvYWRpbmcgdGhlIHBhY2thZ2UNCiAgbGlicmFyeShydmVzdCwgcXVpZXRseSA9IFRSVUUpDQoNCmlmKCFyZXF1aXJlKGx1YnJpZGF0ZSwgcXVpZXRseSA9IFRSVUUpKSANCiAgaW5zdGFsbC5wYWNrYWdlcyhsdWJyaWRhdGUsIGRlcGVuZGVuY2llcyA9IFRSVUUsIHF1aWV0bHkgPSBUUlVFKQ0KICBsaWJyYXJ5KGx1YnJpZGF0ZSwgcXVpZXRseSA9IFRSVUUpDQoNCmlmKCFyZXF1aXJlKHdvcmRjbG91ZCwgcXVpZXRseSA9IFRSVUUpKSANCiAgaW5zdGFsbC5wYWNrYWdlcyh3b3JkY2xvdWQsIGRlcGVuZGVuY2llcyA9IFRSVUUsIHF1aWV0bHkgPSBUUlVFKQ0KICBsaWJyYXJ5KHdvcmRjbG91ZCwgcXVpZXRseSA9IFRSVUUpDQoNCmlmKCFyZXF1aXJlKHRtLCBxdWlldGx5ID0gVFJVRSkpIA0KICBpbnN0YWxsLnBhY2thZ2VzKHRtLCBkZXBlbmRlbmNpZXMgPSBUUlVFLCBxdWlldGx5ID0gVFJVRSkNCiAgbGlicmFyeSh0bSwgcXVpZXRseSA9IFRSVUUpDQoNCmlmKCFyZXF1aXJlKHRpZHl2ZXJzZSwgcXVpZXRseSA9IFRSVUUpKQ0KICBpbnN0YWxsLnBhY2thZ2VzKHRpZHl2ZXJzZSwgZGVwZW5kZW5jaWVzID0gVFJVRSwgcXVpZXRseSA9IFRSVUUpDQogIGxpYnJhcnkodGlkeXZlcnNlLCBxdWlldGx5ID0gVFJVRSkNCg0KYGBgDQoNCjxicj4NCg0KLS0tLS0tLS0tLS0tLS0NCg0KIyMgRGF0YSBDb2xsZWN0aW9uOiBDbGFtaW5nIHlvdXIgR29vZ2xlIFNlYXJjaCBEYXRhDQoNCi0tLS0tLS0tLS0tLS0tDQoNCjxicj4NCg0KIyMjIyAxKSBTaWduIGludG8geW91ciBnb29nbGUgYWNjb3VudCwgdGhlbiBHbyB0bzoNCiogaHR0cHM6Ly9teWFjY291bnQuZ29vZ2xlLmNvbS9wcml2YWN5DQoNCiMjIyMgMikgRmluZCB0aGUgbGluayB0byBkb3dubG9hZCB5b3VyIGRhdGEgYXJjaGl2ZSBvciBHbyB0bzogDQoqIGh0dHBzOi8vdGFrZW91dC5nb29nbGUuY29tL3NldHRpbmdzL3Rha2VvdXQNCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCdpbWdzL2ltZzAxLnBuZycpDQoNCmBgYA0KDQo8YnI+DQoNCiMjIyMgMykgU2VsZWN0IGFsbCBHb29nbGUgcHJvZHVjdHMgdG8gY3JlYXRlIGEgY29tcGxldGUgYXJjaGl2ZSBvZiB5b3VyIGRhdGENCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCdpbWdzL2ltZzAyLnBuZycpDQoNCmBgYA0KDQo8YnI+DQoNCiMjIyMgNCkgQWZ0ZXIgc2VsZWN0aW5nIHRoZSBwcm9kdWN0cywgY2hvb3NlIHRoZSBmaWxlIHR5cGUgYW5kIG1heCBhcmNoaXZlIHNpemUgdG8gbWFrZSBzdXJlIHRoYXQgYWxsIHlvdXIgYWNjb3VudCBkYXRhIGlzIGFyY2hpdmUNCg0KYGBge3IsIGVjaG89RkFMU0V9DQoNCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCdpbWdzL2ltZzAzLnBuZycpDQoNCmBgYA0KDQo8YnI+DQoNCi0tLS0tLS0tLS0tLS0tDQoNCiMjIERhdGEgUHJlcGFyYXRpb246IEV4dHJhY3RpbmcgR29vZ2xlIFNlYXJjaCBJbmZvcm1hdGlvbg0KDQotLS0tLS0tLS0tLS0tLQ0KDQo8YnI+DQoNCiMjIyBMb2NhdGUgdGhlIEdvb2dsZSBhcmNoaXZlLCB0aGVuIGZpbmQgdGhlIHNlYXJjaCBkYXRhLiBGb3IgdGhpcyBjYXNlLCBpdCBpcyBhbiBodG1sIGZpbGUgbG9jYXRlZCBpbiAiTXkgQWN0aXZpdHkiIGZvbGRlciIgdGhlbiBmaW5kIHRoZSAiU2VhcmNoIiBmb2xkZXIgYW5kIHRoZSBodG1sIGZpbGUgIk15QWN0aXZpdHkuaHRtbCIgc2hvdWxkIGJlIHRoZXJlOg0KDQoqIFRha2VvdXQgLT4gTXkgQWN0aXZpdHkgLT4gU2VhcmNoIC0+IE15QWN0aXZpdHkuaHRtbCANCg0KIyMjIFVzaW5nIHRoZSBydmVzdCBwYWNrYWdlIHdlIGNhbiByZWFkIHRoZSBodG1sIGRvY3VtZW50IHRoYXQgY29udGFpbnMgdGhlIHJlbGF0ZWQgZ29vZ2xlIHNlYXJjaCBkYXRhDQoNCmBgYHtyfQ0KDQpkb2MgPC0gInRha2VvdXQtMjAxODAxMzFUMDMwODEzei0wMDEvVGFrZW91dC9NeSBBY3Rpdml0eS9TZWFyY2gvTXlBY3Rpdml0eS5odG1sIg0Kc2VhcmNoX2FyY2hpdmUgPC0gcmVhZF9odG1sKGRvYykNCg0KYGBgDQoNCjxicj4NCg0KLS0tLS0tLS0tLS0tLS0NCg0KIyMjIExhdmVyYWdpbmcgcmVndWxhciBleHByZXNzaW9uIHdlIGNhbiBzZWFyY2ggdGhlIGh0bWwgZG9jdW1lbnQgdG8gZXh0cmFjdDoNCg0KPGJyPg0KDQojIyMjIEV4dHJhY3QgU2VhcmNoIFRpbWUNCmBgYHtyfQ0KDQpkYXRlX3NlYXJjaCA8LSBzZWFyY2hfYXJjaGl2ZSAlPiUgDQogIGh0bWxfbm9kZXMoeHBhdGggPSAnLy9kaXZbQGNsYXNzPSJtZGwtZ3JpZCJdL2Rpdi9kaXYnKSAlPiUgDQogIHN0cl9leHRyYWN0KHBhdHRlcm4gPSAiKD88PTxicj4pKC4qKSg/PD1QTXxBTSkiKSAlPiUNCiAgbWR5X2htcygpDQoNCmBgYA0KDQo8YnI+DQoNCiMjIyMgRXh0cmFjdCBTZWFyY2ggVGV4dA0KYGBge3J9DQoNCnRleHRfc2VhcmNoIDwtIHNlYXJjaF9hcmNoaXZlICU+JSANCiAgaHRtbF9ub2Rlcyh4cGF0aCA9ICcvL2RpdltAY2xhc3M9Im1kbC1ncmlkIl0vZGl2L2RpdicpICU+JQ0KICBzdHJfZXh0cmFjdChwYXR0ZXJuID0gJyg/PD08YSkoLiopKD89PC9hPiknKSAlPiUgDQogIHN0cl9leHRyYWN0KHBhdHRlcm4gPSAnKD88PVwiPikoLiopJykNCg0KYGBgDQoNCjxicj4NCg0KIyMjIyBFeHRyYWN0IFNlYXJjaCBUeXBlDQpgYGB7cn0NCg0KdHlwZV9zZWFyY2ggPC0gc2VhcmNoX2FyY2hpdmUgJT4lIA0KICBodG1sX25vZGVzKHhwYXRoID0gJy8vZGl2W0BjbGFzcz0ibWRsLWdyaWQiXS9kaXYvZGl2JykgJT4lIA0KICBzdHJfZXh0cmFjdChwYXR0ZXJuID0gIig/PD1tZGwtdHlwb2dyYXBoeS0tYm9keS0xXCI+KSguKikoPz08YSkiKSAlPiUgDQogIHN0cl9leHRyYWN0KHBhdHRlcm4gPSAiKFxcdyspKD89XFxzKSIpDQoNCmBgYA0KDQo8YnI+DQoNCiMjIyMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB1c2luZyB0aGUgZGF0YSBleHRyYWN0ZWQgZnJvbSB0aGUgaHRtbCBmaWxlDQpgYGB7cn0NCg0Kc2VhcmNoX2RhdGEgPC0gdGliYmxlKHRpbWVzdGFtcCA9IGRhdGVfc2VhcmNoLA0KICAgICAgICAgICAgICAgICAgICAgIGRhdGUgPSBhc19kYXRlKGRhdGVfc2VhcmNoKSwNCiAgICAgICAgICAgICAgICAgICAgICB5ZWFyID0geWVhcihkYXRlX3NlYXJjaCksDQogICAgICAgICAgICAgICAgICAgICAgbW9udGggPSBtb250aChkYXRlX3NlYXJjaCwgbGFiZWwgPSBUUlVFKSwNCiAgICAgICAgICAgICAgICAgICAgICBkYXkgPSB3ZWVrZGF5cyhkYXRlX3NlYXJjaCksDQogICAgICAgICAgICAgICAgICAgICAgaG91ciA9IGhvdXIoZGF0ZV9zZWFyY2gpLA0KICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSB0eXBlX3NlYXJjaCwNCiAgICAgICAgICAgICAgICAgICAgICBzZWFyY2ggPSB0ZXh0X3NlYXJjaCkNCg0Kc2VhcmNoX2RhdGEkZGF5IDwtIGZhY3RvcihzZWFyY2hfZGF0YSRkYXksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJTdW5kYXkiLCAiTW9uZGF5IiwgIlR1ZXNkYXkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXZWRuZXNkYXkiLCJUaHVyc2RheSIsICJGcmlkYXkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTYXR1cmRheSIpKQ0KDQpzZWFyY2hfZGF0YSA8LSBuYS5vbWl0KHNlYXJjaF9kYXRhKQ0KDQpoZWFkKHNlYXJjaF9kYXRhKQ0KDQpgYGANCg0KPGJyPg0KDQotLS0tLS0tLS0tLS0tLQ0KDQojIyBEYXRhIEFuYWx5c2lzOiBWaXN1YWxpemluZyBHb29nbGUgU2VhcmNoZXMNCg0KLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQojIyMjIFRvIGdldCBhbiBvdmVyYWxsIGlkZWEgb2YgdGhlIHNlYXJjaCB2b2x1bWUsIHdlIGNhbiBwbG90IHNlYXJjaGVzIGJ5IHllYXIgDQoNCmBgYHtyfQ0KDQpwIDwtIGdncGxvdChzZWFyY2hfZGF0YSwgYWVzKHllYXIpKQ0KcCArIGdlb21fYmFyKCkNCg0KYGBgDQoNCjxicj4NCg0KIyMjIyBBZnRlciBkZXRlcm1pbmUgdGhlIHllYXJzIHdpdGggdGhlIGxhcmdlc3Qgc2VhcmNoIHZvbHVtZSB3ZSBjYW4gcGxvdCBtb250aGx5IHNlYXJjaGVzDQpgYGB7cn0NCg0KbW9udGhseSA8LSBzZWFyY2hfZGF0YVsoc2VhcmNoX2RhdGEkeWVhciA+IDIwMTQgJiBzZWFyY2hfZGF0YSR5ZWFyPCAyMDE4KSwgXQ0KDQpnZ3Bsb3QobW9udGhseSkgKyBnZW9tX2JhcihhZXMoeCA9IG1vbnRoLCBncm91cCA9IHllYXIpKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTkwKSkgKw0KICBmYWNldF9ncmlkKC5+eWVhciwgc2NhbGVzPSJmcmVlIikNCg0KYGBgDQoNCjxicj4NCg0KIyMjIyBBbm90aGVyIGludGVyZXN0aW5nIG1ldHJpY3QgaXMgc2VhcmNoZXMgYnkgSG91cg0KYGBge3J9DQoNCnAgPC0gZ2dwbG90KHNlYXJjaF9kYXRhLCBhZXMoaG91cikpDQpwICsgZ2VvbV9iYXIoKQ0KDQpgYGANCg0KPGJyPg0KDQojIyMjIFdlIGNhbiBhbHNvIHBsb3QgdGhlIHNlYXJjaCBkYXRhIGJ5IGRheSBvZiB0aGUgd2VlayB0byBkZXRlcm1pbmUgZGF5IGFyZSB0aGUgbW9zdCBhY3RpdmUNCmBgYHtyfQ0KDQpwIDwtIGdncGxvdChzZWFyY2hfZGF0YSwgYWVzKGRheSkpDQpwICsgZ2VvbV9iYXIoKQ0KDQpgYGANCg0KPGJyPg0KDQojIyMjIFdlIGNhbiB0YWtlIGl0IGFuIHN0ZXAgZnVydGhlciBhbmQgZ3JvdXAgc2VhcmNoIHRpbWUgd2l0aCBkYXkgb2YgdGhlIHdlZWsuIA0KYGBge3J9DQoNCmdncGxvdChzZWFyY2hfZGF0YSkgKyANCiAgZ2VvbV9iYXIoYWVzKHggPSBob3VyLCBncm91cCA9IGRheSkgKSArDQogIGZhY2V0X2dyaWQoLn5kYXksIHNjYWxlcyA9ICJmcmVlIikNCg0KYGBgDQoNCjxicj4NCg0KIyMjIyBXZSBjYW4gZ3JvdXAgdGhlIHNlYXJjaCBkYXRhIGJ5IHllYXIgYW5kIGRheSBvZiB0aGUgd2VlaywgdG8gdmlzdWFsaXplIHRoZSBvdmVyYWxsIHRyZW5kIA0KYGBge3J9DQoNCndrZGF5IDwtIGdyb3VwX2J5KHNlYXJjaF9kYXRhLCB5ZWFyLCBkYXkpICU+JSBzdW1tYXJpemUoY291bnQgPSBuKCkpDQpwIDwtIGdncGxvdCh3a2RheSwgYWVzKGRheSwgY291bnQsIGZpbGwgPSB5ZWFyKSkgDQpwICsgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsgbGFicyh4ID0gIiIsIHkgPSAiU2VhcmNoIFZvbHVtZSIpDQoNCmBgYA0KDQo8YnI+DQoNCi0tLS0tLS0tLS0tLS0tDQoNCiMjIFJlcG9ydGluZzogQSB3b3JkY2xvdWQgZnJvbSBHb29nbGUgU2VhcmNoIERhdGENCg0KLS0tLS0tLS0tLS0tLS0NCg0KPGJyPg0KDQojIyMjIEZpcnN0IHdlIG5lZWQgdG8gZXh0cmFjdCB0aGUgdGV4dCBhbmQgY2xlYW4gaXQgdXNpbmcgcmVndWxhciBleHByZXNzaW9ucw0KYGBge3J9DQoNCnNlYXJjaCA8LSB0b2xvd2VyKHNlYXJjaF9kYXRhJHNlYXJjaCkNCnNlYXJjaCA8LSBpY29udihzZWFyY2gsICJBU0NJSSIsICJVVEYtOCIsICIgIikNCnNlYXJjaCA8LSBnc3ViKCcoaHR0cHxodHRwcylcXFMrXFxzKnwoI3xAKVxcUytcXHMqfFxcbnxcXCInLCAiICIsIHNlYXJjaCkNCnNlYXJjaCA8LSBnc3ViKCIoLiouKVxcLmNvbSguKi4pXFxTK1xcc3xbXls6YWxudW06XV0iLCAiICIsIHNlYXJjaCkNCnNlYXJjaCA8LSB0cmltd3Moc2VhcmNoKQ0KDQpgYGANCg0KPGJyPg0KDQojIyMjIEFmdGVyIGNsZWFuaW5nIHRoZSB0ZXh0IHdlIGNhbiBjcmVhdGUgYSBUZXh0IENvcnB1cyAoYSBsYXJnZSBhbmQgc3RydWN0dXJlZCBzZXQgb2YgdGV4dHMpIGFuZCByZW1vdmUgc29tZSB3b3JkcyANCmBgYHtyfQ0KDQpzZWFyY2hfY29ycHVzIDwtICBDb3JwdXMoVmVjdG9yU291cmNlKHNlYXJjaCkpDQpzZWFyY2hfY29ycHVzIDwtIHRtX21hcChzZWFyY2hfY29ycHVzLCBjb250ZW50X3RyYW5zZm9ybWVyKHJlbW92ZVB1bmN0dWF0aW9uKSkNCnNlYXJjaF9jb3JwdXMgPC0gdG1fbWFwKHNlYXJjaF9jb3JwdXMsIGNvbnRlbnRfdHJhbnNmb3JtZXIocmVtb3ZlTnVtYmVycykpDQpzdG9wd29yZHMgPC0gYyhzdG9wd29yZHMoImVuZ2xpc2giKSwgImNocm9tZSIsICJjaGljYWdvIiwgImpscm9vIiwgImdvb2dsZSIpDQpzZWFyY2hfY29ycHVzIDwtIHRtX21hcChzZWFyY2hfY29ycHVzLCByZW1vdmVXb3Jkcywgc3RvcHdvcmRzKQ0KDQpgYGANCg0KPGJyPg0KDQpgYGB7cn0NCg0Kc2VhcmNoX3RkbSA8LSBUZXJtRG9jdW1lbnRNYXRyaXgoc2VhcmNoX2NvcnB1cykNCnNlYXJjaF9tYXRyaXggPC0gYXMubWF0cml4KHNlYXJjaF90ZG0pDQoNCmBgYA0KDQoNCjxicj4NCg0KIyMjIyBVc2luZyB0aGUgVGVybSBEb2N1bWVudCBtYXRyaXggd2UgY2FuIGNyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCB0aGUgd29yZHMgYW5kIGl0cyByZWxhdGVkIGZyZXF1ZW5jaWVzIA0KYGBge3J9DQoNCnYgPC0gc29ydChyb3dTdW1zKHNlYXJjaF9tYXRyaXgpLCBkZWNyZWFzaW5nID0gVFJVRSkNCnR3X25hbWVzIDwtIG5hbWVzKHYpDQpkIDwtIGRhdGEuZnJhbWUod29yZCA9IHR3X25hbWVzLCBmcmVxID0gdikNCg0KYGBgDQoNCjxicj4NCg0KIyMjIyBTZXQgYSB0aHJlc2hvbGQgZm9yIHRoZSBtaW4gZnJlcXVlbmN5IG9mIHRoZSB3b3JkcyB0byBkaXNwbGF5IGFzIHdlbGwgYXMgbWF4IGZyZXF1ZW5jeQ0KYGBge3J9DQoNCndvcmRjbG91ZChkJHdvcmQsIGQkZnJlcSwgbWluLmZyZXEgPSA1MCwgc2NhbGUgPSBjKDMgLCAwLjUpLCBtYXgud29yZHMgPSAyMDApDQoNCmBgYA0K