======================================================================================

TELKOMSEL

Extracting Tweets

Retrieve tweets from Twitter

# Retrieve tweets
tweets <- search_tweets("#Telkomsel", n = 8000, tweet_mode="extended")
tweets <- distinct(tweets, text, .keep_all=TRUE)

Tweets Description

tail(tweets, 20)

Text Cleaning

library(tm)

Build corpus

Frequent Words

Build Term Document Matrix

tdm1 <- TermDocumentMatrix(myCorpus, control = list(wordLengths = c(1, Inf)))
tdm1

Top Frequent Terms

freq.terms <- findFreqTerms(tdm1, lowfreq = 20)
freq.terms[1:50]
term.freq <- rowSums(as.matrix(tdm1))
term.freq <- subset(term.freq, term.freq >= 150)
df <- data.frame(term = names(term.freq), freq = term.freq)
ggplot(df, aes(x=term, y=freq)) + geom_bar(stat="identity") +
  xlab("Terms") + ylab("Count") + coord_flip() +
  theme(axis.text=element_text(size=7))

Wordcloud

Build Wordcloud

wordcloud(words = names(word.freq), freq = word.freq, min.freq = 100,
    random.order = F, colors = pal1)

INDOSAT

Extracting Tweets

Retrieve tweets from Twitter

# Retrieve tweets
tweets <- search_tweets("#Indosat", n = 8000, tweet_mode="extended")
tweets <- distinct(tweets, text, .keep_all=TRUE)

Tweets Description

ts_plot(tweets, "3 hours") +
  theme_minimal() +
  theme(plot.title = ggplot2::element_text(face = "bold")) +
  labs(
    x = NULL, y = NULL,
    title = "Frequency of indihome Twitter statuses from past 3 hours",
    subtitle = "Twitter status (tweet) counts aggregated using three-hour intervals",
    caption = "\nSource: Data collected from Twitter's REST API via rtweet"
  )
tail(tweets, 20)

Text Cleaning

library(tm)

Build corpus

# build a corpus, and specify the source to be character vectors 
myCorpus <- Corpus(VectorSource(tweets$text))
# convert to lower case
myCorpus <- tm_map(myCorpus, content_transformer(tolower))
# remove URLs
removeURL <- function(x) gsub("http[^[:space:]]*", "", x)
myCorpus <- tm_map(myCorpus, content_transformer(removeURL))
# remove anything other than English letters or space 
removeNumPunct <- function(x) gsub("[^[:alpha:][:space:]]*", "", x) 
myCorpus <- tm_map(myCorpus, content_transformer(removeNumPunct))
# remove stopwords
myStopwords <- c(setdiff(stopwords('english'), c("r", "big")), "use", "see", "used", "via", "amp", "indihome")
stopwords_id <- read.table("E://stopwords-id.txt", header = FALSE)
myStopwords <- c(myStopwords, as.matrix(stopwords_id$V1), "hi", "yg")
myCorpus <- tm_map(myCorpus, removeWords, myStopwords)
# remove extra whitespace
myCorpus <- tm_map(myCorpus, stripWhitespace)
# keep a copy for stem completion later
myCorpusCopy <- myCorpus

Frequent Words_2

Build Term Document Matrix_2

tdm <- TermDocumentMatrix(myCorpus, control = list(wordLengths = c(1, Inf)))
tdm

Top Frequent Terms_2

freq.terms <- findFreqTerms(tdm, lowfreq = 20)
freq.terms[1:50]
term.freq <- rowSums(as.matrix(tdm))
term.freq <- subset(term.freq, term.freq >= 150)
df <- data.frame(term = names(term.freq), freq = term.freq)
ggplot(df, aes(x=term, y=freq)) + geom_bar(stat="identity") +
  xlab("Terms") + ylab("Count") + coord_flip() +
  theme(axis.text=element_text(size=7))

Wordcloud_2

Build Wordcloud_2

library(wordcloud)
m <- as.matrix(tdm)
# calculate the frequency of words and sort it by frequency 
word.freq <- sort(rowSums(m), decreasing = T)
# colors
pal <- brewer.pal(9, "BuGn")[-(1:4)]
wordcloud(words = names(word.freq), freq = word.freq, min.freq = 100,
    random.order = F, colors = pal)
LS0tDQp0aXRsZTogIlRleHQgTWluaW5nIC0gYnkgUm9zaWtodSBJbG1pIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQoNCiNURUxLT01TRUwNCg0KIyMgRXh0cmFjdGluZyBUd2VldHMNCg0KIyMjIFJldHJpZXZlIHR3ZWV0cyBmcm9tIFR3aXR0ZXINCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIExvYWQgcGFja2FnZXMNCmxpYnJhcnkocnR3ZWV0KQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KYGBge3IsZWNobz1GQUxTRX0NCiMgQWNjZXNzIHRva2VuIGFuZCBBUElzDQpjb25zdW1lcl9rZXkgICAgPC0gInN4eGRtTXYwY2VFWFRGTjBabHFzZFRjZHUiDQpjb25zdW1lcl9zZWNyZXQgPC0gIjZZd3U2YUY5RDRmNjg0dHYzYmhUNmoyYnQzMVRlNnBVYkRxQ2ZVS2pvWFhpQ0cyTHE5Ig0KYWNjZXNzX3Rva2VuICAgIDwtICI0MTA3Mzk1ODktYTNEanJUckVPRDZMUXVSa1hPZmFIanh6Ym5zTVJwOVJlZUhPeFhDVCINCmFjY2Vzc19zZWNyZXQgICA8LSAiREZ5a1F3VkxhWHRJTFoyWXBoOGdtUzQ5WG9JcG9vYThBR0djUlViY215SW53Ig0KYGBgDQoNCmBgYHtyLGVjaG89RkFMU0V9DQojIFR3aXR0ZXIgYXV0aGVudGljYXRpb24NCmNyZWF0ZV90b2tlbigNCiAgYXBwICAgICAgICAgICAgID0gIm15X3R3aXR0ZXJfcmVzZWFyY2hfYXBwIiwNCiAgY29uc3VtZXJfa2V5ICAgID0gY29uc3VtZXJfa2V5LA0KICBjb25zdW1lcl9zZWNyZXQgPSBjb25zdW1lcl9zZWNyZXQsDQogIGFjY2Vzc190b2tlbiAgICA9IGFjY2Vzc190b2tlbiwNCiAgYWNjZXNzX3NlY3JldCAgID0gYWNjZXNzX3NlY3JldCkNCmBgYA0KDQpgYGB7cn0NCiMgUmV0cmlldmUgdHdlZXRzDQp0d2VldHMgPC0gc2VhcmNoX3R3ZWV0cygiI1RlbGtvbXNlbCIsIG4gPSA4MDAwLCB0d2VldF9tb2RlPSJleHRlbmRlZCIpDQp0d2VldHMgPC0gZGlzdGluY3QodHdlZXRzLCB0ZXh0LCAua2VlcF9hbGw9VFJVRSkNCmBgYA0KDQoNCiMjIyBUd2VldHMgRGVzY3JpcHRpb24NCg0KYGBge3IsIGVjaG89RkFMU0V9DQp0c19wbG90KHR3ZWV0cywgIjMgaG91cnMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBnZ3Bsb3QyOjplbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikpICsNCiAgbGFicygNCiAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgdGl0bGUgPSAiRnJlcXVlbmN5IG9mIGluZGlob21lIFR3aXR0ZXIgc3RhdHVzZXMgZnJvbSBwYXN0IDMgaG91cnMiLA0KICAgIHN1YnRpdGxlID0gIlR3aXR0ZXIgc3RhdHVzICh0d2VldCkgY291bnRzIGFnZ3JlZ2F0ZWQgdXNpbmcgdGhyZWUtaG91ciBpbnRlcnZhbHMiLA0KICAgIGNhcHRpb24gPSAiXG5Tb3VyY2U6IERhdGEgY29sbGVjdGVkIGZyb20gVHdpdHRlcidzIFJFU1QgQVBJIHZpYSBydHdlZXQiDQogICkNCmBgYA0KDQpgYGB7cn0NCnRhaWwodHdlZXRzLCAyMCkNCmBgYA0KDQoNCiMjIFRleHQgQ2xlYW5pbmcNCg0KYGBge3J9DQpsaWJyYXJ5KHRtKQ0KYGBgDQojIyMgQnVpbGQgY29ycHVzDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KIyBidWlsZCBhIGNvcnB1cywgYW5kIHNwZWNpZnkgdGhlIHNvdXJjZSB0byBiZSBjaGFyYWN0ZXIgdmVjdG9ycyANCm15Q29ycHVzIDwtIENvcnB1cyhWZWN0b3JTb3VyY2UodHdlZXRzJHRleHQpKQ0KIyBjb252ZXJ0IHRvIGxvd2VyIGNhc2UNCm15Q29ycHVzIDwtIHRtX21hcChteUNvcnB1cywgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkNCiMgcmVtb3ZlIFVSTHMNCnJlbW92ZVVSTCA8LSBmdW5jdGlvbih4KSBnc3ViKCJodHRwW15bOnNwYWNlOl1dKiIsICIiLCB4KQ0KbXlDb3JwdXMgPC0gdG1fbWFwKG15Q29ycHVzLCBjb250ZW50X3RyYW5zZm9ybWVyKHJlbW92ZVVSTCkpDQojIHJlbW92ZSBhbnl0aGluZyBvdGhlciB0aGFuIEVuZ2xpc2ggbGV0dGVycyBvciBzcGFjZSANCnJlbW92ZU51bVB1bmN0IDwtIGZ1bmN0aW9uKHgpIGdzdWIoIlteWzphbHBoYTpdWzpzcGFjZTpdXSoiLCAiIiwgeCkgDQpteUNvcnB1cyA8LSB0bV9tYXAobXlDb3JwdXMsIGNvbnRlbnRfdHJhbnNmb3JtZXIocmVtb3ZlTnVtUHVuY3QpKQ0KIyByZW1vdmUgc3RvcHdvcmRzDQpteVN0b3B3b3JkcyA8LSBjKHNldGRpZmYoc3RvcHdvcmRzKCdlbmdsaXNoJyksIGMoInIiLCAiYmlnIikpLCAidXNlIiwgInNlZSIsICJ1c2VkIiwgInZpYSIsICJhbXAiLCAiaW5kaWhvbWUiKQ0Kc3RvcHdvcmRzX2lkIDwtIHJlYWQudGFibGUoIkU6Ly9zdG9wd29yZHMtaWQudHh0IiwgaGVhZGVyID0gRkFMU0UpDQpteVN0b3B3b3JkcyA8LSBjKG15U3RvcHdvcmRzLCBhcy5tYXRyaXgoc3RvcHdvcmRzX2lkJFYxKSwgImhpIiwgInlnIikNCm15Q29ycHVzIDwtIHRtX21hcChteUNvcnB1cywgcmVtb3ZlV29yZHMsIG15U3RvcHdvcmRzKQ0KIyByZW1vdmUgZXh0cmEgd2hpdGVzcGFjZQ0KbXlDb3JwdXMgPC0gdG1fbWFwKG15Q29ycHVzLCBzdHJpcFdoaXRlc3BhY2UpDQojIGtlZXAgYSBjb3B5IGZvciBzdGVtIGNvbXBsZXRpb24gbGF0ZXINCm15Q29ycHVzQ29weSA8LSBteUNvcnB1cw0KYGBgDQojIyBGcmVxdWVudCBXb3Jkcw0KDQojIyMgQnVpbGQgVGVybSBEb2N1bWVudCBNYXRyaXgNCmBgYHtyfQ0KdGRtMSA8LSBUZXJtRG9jdW1lbnRNYXRyaXgobXlDb3JwdXMsIGNvbnRyb2wgPSBsaXN0KHdvcmRMZW5ndGhzID0gYygxLCBJbmYpKSkNCmBgYA0KDQpgYGB7cn0NCnRkbTENCmBgYA0KDQojIyMgVG9wIEZyZXF1ZW50IFRlcm1zDQoNCmBgYHtyfQ0KZnJlcS50ZXJtcyA8LSBmaW5kRnJlcVRlcm1zKHRkbTEsIGxvd2ZyZXEgPSAyMCkNCmBgYA0KYGBge3J9DQpmcmVxLnRlcm1zWzE6NTBdDQpgYGANCg0KYGBge3J9DQp0ZXJtLmZyZXEgPC0gcm93U3Vtcyhhcy5tYXRyaXgodGRtMSkpDQp0ZXJtLmZyZXEgPC0gc3Vic2V0KHRlcm0uZnJlcSwgdGVybS5mcmVxID49IDE1MCkNCmRmIDwtIGRhdGEuZnJhbWUodGVybSA9IG5hbWVzKHRlcm0uZnJlcSksIGZyZXEgPSB0ZXJtLmZyZXEpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4PXRlcm0sIHk9ZnJlcSkpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArDQogIHhsYWIoIlRlcm1zIikgKyB5bGFiKCJDb3VudCIpICsgY29vcmRfZmxpcCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTcpKQ0KYGBgDQoNCiMjIFdvcmRjbG91ZA0KDQojIyMgQnVpbGQgV29yZGNsb3VkDQpgYGB7ciwgZWNobz1GQUxTRX0NCmxpYnJhcnkod29yZGNsb3VkKQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KbTEgPC0gYXMubWF0cml4KHRkbTEpDQojIGNhbGN1bGF0ZSB0aGUgZnJlcXVlbmN5IG9mIHdvcmRzIGFuZCBzb3J0IGl0IGJ5IGZyZXF1ZW5jeSANCndvcmQuZnJlcSA8LSBzb3J0KHJvd1N1bXMobTEpLCBkZWNyZWFzaW5nID0gVCkNCiMgY29sb3JzDQpwYWwxIDwtIGJyZXdlci5wYWwoOSwgIkJ1R24iKVstKDE6NCldDQpgYGANCg0KDQpgYGB7cn0NCndvcmRjbG91ZCh3b3JkcyA9IG5hbWVzKHdvcmQuZnJlcSksIGZyZXEgPSB3b3JkLmZyZXEsIG1pbi5mcmVxID0gMTAwLA0KICAgIHJhbmRvbS5vcmRlciA9IEYsIGNvbG9ycyA9IHBhbDEpDQpgYGANCg0KI0lORE9TQVQNCg0KIyMgRXh0cmFjdGluZyBUd2VldHMNCg0KIyMjIFJldHJpZXZlIHR3ZWV0cyBmcm9tIFR3aXR0ZXINCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIExvYWQgcGFja2FnZXMNCmxpYnJhcnkocnR3ZWV0KQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KYGBge3IsIGVjaG89RkFMU0V9DQojIEFjY2VzcyB0b2tlbiBhbmQgQVBJcw0KY29uc3VtZXJfa2V5ICAgIDwtICJzeHhkbU12MGNlRVhURk4wWmxxc2RUY2R1Ig0KY29uc3VtZXJfc2VjcmV0IDwtICI2WXd1NmFGOUQ0ZjY4NHR2M2JoVDZqMmJ0MzFUZTZwVWJEcUNmVUtqb1hYaUNHMkxxOSINCmFjY2Vzc190b2tlbiAgICA8LSAiNDEwNzM5NTg5LWEzRGpyVHJFT0Q2TFF1UmtYT2ZhSGp4emJuc01ScDlSZWVIT3hYQ1QiDQphY2Nlc3Nfc2VjcmV0ICAgPC0gIkRGeWtRd1ZMYVh0SUxaMllwaDhnbVM0OVhvSXBvb2E4QUdHY1JVYmNteUludyINCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgVHdpdHRlciBhdXRoZW50aWNhdGlvbg0KY3JlYXRlX3Rva2VuKA0KICBhcHAgICAgICAgICAgICAgPSAibXlfdHdpdHRlcl9yZXNlYXJjaF9hcHAiLA0KICBjb25zdW1lcl9rZXkgICAgPSBjb25zdW1lcl9rZXksDQogIGNvbnN1bWVyX3NlY3JldCA9IGNvbnN1bWVyX3NlY3JldCwNCiAgYWNjZXNzX3Rva2VuICAgID0gYWNjZXNzX3Rva2VuLA0KICBhY2Nlc3Nfc2VjcmV0ICAgPSBhY2Nlc3Nfc2VjcmV0KQ0KYGBgDQoNCmBgYHtyfQ0KIyBSZXRyaWV2ZSB0d2VldHMNCnR3ZWV0cyA8LSBzZWFyY2hfdHdlZXRzKCIjSW5kb3NhdCIsIG4gPSA4MDAwLCB0d2VldF9tb2RlPSJleHRlbmRlZCIpDQp0d2VldHMgPC0gZGlzdGluY3QodHdlZXRzLCB0ZXh0LCAua2VlcF9hbGw9VFJVRSkNCmBgYA0KDQoNCiMjIyBUd2VldHMgRGVzY3JpcHRpb24NCg0KYGBge3J9DQp0c19wbG90KHR3ZWV0cywgIjMgaG91cnMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBnZ3Bsb3QyOjplbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIikpICsNCiAgbGFicygNCiAgICB4ID0gTlVMTCwgeSA9IE5VTEwsDQogICAgdGl0bGUgPSAiRnJlcXVlbmN5IG9mIGluZGlob21lIFR3aXR0ZXIgc3RhdHVzZXMgZnJvbSBwYXN0IDMgaG91cnMiLA0KICAgIHN1YnRpdGxlID0gIlR3aXR0ZXIgc3RhdHVzICh0d2VldCkgY291bnRzIGFnZ3JlZ2F0ZWQgdXNpbmcgdGhyZWUtaG91ciBpbnRlcnZhbHMiLA0KICAgIGNhcHRpb24gPSAiXG5Tb3VyY2U6IERhdGEgY29sbGVjdGVkIGZyb20gVHdpdHRlcidzIFJFU1QgQVBJIHZpYSBydHdlZXQiDQogICkNCmBgYA0KDQpgYGB7cn0NCnRhaWwodHdlZXRzLCAyMCkNCmBgYA0KDQoNCiMjIFRleHQgQ2xlYW5pbmcNCg0KYGBge3J9DQpsaWJyYXJ5KHRtKQ0KYGBgDQojIyMgQnVpbGQgY29ycHVzDQoNCmBgYHtyfQ0KIyBidWlsZCBhIGNvcnB1cywgYW5kIHNwZWNpZnkgdGhlIHNvdXJjZSB0byBiZSBjaGFyYWN0ZXIgdmVjdG9ycyANCm15Q29ycHVzIDwtIENvcnB1cyhWZWN0b3JTb3VyY2UodHdlZXRzJHRleHQpKQ0KIyBjb252ZXJ0IHRvIGxvd2VyIGNhc2UNCm15Q29ycHVzIDwtIHRtX21hcChteUNvcnB1cywgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkNCiMgcmVtb3ZlIFVSTHMNCnJlbW92ZVVSTCA8LSBmdW5jdGlvbih4KSBnc3ViKCJodHRwW15bOnNwYWNlOl1dKiIsICIiLCB4KQ0KbXlDb3JwdXMgPC0gdG1fbWFwKG15Q29ycHVzLCBjb250ZW50X3RyYW5zZm9ybWVyKHJlbW92ZVVSTCkpDQojIHJlbW92ZSBhbnl0aGluZyBvdGhlciB0aGFuIEVuZ2xpc2ggbGV0dGVycyBvciBzcGFjZSANCnJlbW92ZU51bVB1bmN0IDwtIGZ1bmN0aW9uKHgpIGdzdWIoIlteWzphbHBoYTpdWzpzcGFjZTpdXSoiLCAiIiwgeCkgDQpteUNvcnB1cyA8LSB0bV9tYXAobXlDb3JwdXMsIGNvbnRlbnRfdHJhbnNmb3JtZXIocmVtb3ZlTnVtUHVuY3QpKQ0KIyByZW1vdmUgc3RvcHdvcmRzDQpteVN0b3B3b3JkcyA8LSBjKHNldGRpZmYoc3RvcHdvcmRzKCdlbmdsaXNoJyksIGMoInIiLCAiYmlnIikpLCAidXNlIiwgInNlZSIsICJ1c2VkIiwgInZpYSIsICJhbXAiLCAiaW5kaWhvbWUiKQ0Kc3RvcHdvcmRzX2lkIDwtIHJlYWQudGFibGUoIkU6Ly9zdG9wd29yZHMtaWQudHh0IiwgaGVhZGVyID0gRkFMU0UpDQpteVN0b3B3b3JkcyA8LSBjKG15U3RvcHdvcmRzLCBhcy5tYXRyaXgoc3RvcHdvcmRzX2lkJFYxKSwgImhpIiwgInlnIikNCm15Q29ycHVzIDwtIHRtX21hcChteUNvcnB1cywgcmVtb3ZlV29yZHMsIG15U3RvcHdvcmRzKQ0KIyByZW1vdmUgZXh0cmEgd2hpdGVzcGFjZQ0KbXlDb3JwdXMgPC0gdG1fbWFwKG15Q29ycHVzLCBzdHJpcFdoaXRlc3BhY2UpDQojIGtlZXAgYSBjb3B5IGZvciBzdGVtIGNvbXBsZXRpb24gbGF0ZXINCm15Q29ycHVzQ29weSA8LSBteUNvcnB1cw0KYGBgDQojIyBGcmVxdWVudCBXb3Jkc18yDQoNCiMjIyBCdWlsZCBUZXJtIERvY3VtZW50IE1hdHJpeF8yDQpgYGB7cn0NCnRkbSA8LSBUZXJtRG9jdW1lbnRNYXRyaXgobXlDb3JwdXMsIGNvbnRyb2wgPSBsaXN0KHdvcmRMZW5ndGhzID0gYygxLCBJbmYpKSkNCmBgYA0KDQpgYGB7cn0NCnRkbQ0KYGBgDQoNCiMjIyBUb3AgRnJlcXVlbnQgVGVybXNfMg0KDQpgYGB7cn0NCmZyZXEudGVybXMgPC0gZmluZEZyZXFUZXJtcyh0ZG0sIGxvd2ZyZXEgPSAyMCkNCmBgYA0KYGBge3J9DQpmcmVxLnRlcm1zWzE6NTBdDQpgYGANCg0KYGBge3J9DQp0ZXJtLmZyZXEgPC0gcm93U3Vtcyhhcy5tYXRyaXgodGRtKSkNCnRlcm0uZnJlcSA8LSBzdWJzZXQodGVybS5mcmVxLCB0ZXJtLmZyZXEgPj0gMTUwKQ0KZGYgPC0gZGF0YS5mcmFtZSh0ZXJtID0gbmFtZXModGVybS5mcmVxKSwgZnJlcSA9IHRlcm0uZnJlcSkNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChkZiwgYWVzKHg9dGVybSwgeT1mcmVxKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsNCiAgeGxhYigiVGVybXMiKSArIHlsYWIoIkNvdW50IikgKyBjb29yZF9mbGlwKCkgKw0KICB0aGVtZShheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9NykpDQpgYGANCg0KIyMgV29yZGNsb3VkXzINCg0KIyMjIEJ1aWxkIFdvcmRjbG91ZF8yDQpgYGB7cn0NCmxpYnJhcnkod29yZGNsb3VkKQ0KYGBgDQoNCmBgYHtyfQ0KbSA8LSBhcy5tYXRyaXgodGRtKQ0KIyBjYWxjdWxhdGUgdGhlIGZyZXF1ZW5jeSBvZiB3b3JkcyBhbmQgc29ydCBpdCBieSBmcmVxdWVuY3kgDQp3b3JkLmZyZXEgPC0gc29ydChyb3dTdW1zKG0pLCBkZWNyZWFzaW5nID0gVCkNCiMgY29sb3JzDQpwYWwgPC0gYnJld2VyLnBhbCg5LCAiQnVHbiIpWy0oMTo0KV0NCmBgYA0KDQoNCg0KYGBge3J9DQp3b3JkY2xvdWQod29yZHMgPSBuYW1lcyh3b3JkLmZyZXEpLCBmcmVxID0gd29yZC5mcmVxLCBtaW4uZnJlcSA9IDEwMCwNCiAgICByYW5kb20ub3JkZXIgPSBGLCBjb2xvcnMgPSBwYWwpDQpgYGANCg0K