Student ID: 1A182901-2
- Set up
rm(list=ls(all=TRUE))
setwd("~/Desktop/R/polimetrics")
library(rtweet)
library(ggplot2)
library(dplyr)
library(quanteda)
library(rtweet)
library(ggplot2)
library(lattice)
library(syuzhet)
library(stm)
library(lubridate)
0.1. In the first time (Run in 11/14 evening)
token <- create_token(
app = "yenchenghsuan",
consumer_key = "VUk6UDizyDpi9xoUvcPqt2gFR",
consumer_secret = "e3X5JwD029oD8WymQgkVOwEdVK75EgrultGUOv2psyqBZcIxYL",
access_token = "1062396813330632704-DBt0K0EKo3BbJExDt2cIMgwELL8xso",
access_secret = "lUrbH9KGsl8C2hi6UTPDAgymEt9o5je4MSHaso4EeLS8t")
#Run in 11/14 evening:
#trumptweet <- get_timeline("realDonaldTrump", n = 3200)
#trumptweet1 <- trumptweet[1:3000,]
#write_as_csv(trumptweet1, "trumptweet.csv", prepend_ids = TRUE, na = "", fileEncoding = "UTF-8")
- Import data
trumptweet_n <- read.csv("trumptweet.csv",encoding = "UTF-8")
trumptweet_n$created_at_posixit <- as.POSIXct(trumptweet_n$created_at)
trumptweet_n$created_at <- as.numeric(as.Date(trumptweet_n$created_at))
since <- trumptweet_n$created_at_posixit[3000]
latest <- trumptweet_n$created_at_posixit[1]
trumptweet_n_f <- select(trumptweet_n,
status_id,
created_at,
created_at_posixit,
text)
trumptweet_n_f$text <- as.character(trumptweet_n_f$text)
mycorpus <- corpus(trumptweet_n_f)
cat("Twitter data","\n",paste("From:",since),"\n",paste(" To:",latest))
Twitter data
From: 2018-01-04 11:37:46
To: 2018-11-13 21:35:42
- Dictionaries
tweetdfm <- dfm(mycorpus ,
remove = stopwords("english"),
remove_punct = TRUE,
remove_numbers=TRUE,
tolower = TRUE,
stem = TRUE,
remove_twitter = TRUE,
remove_url = TRUE)
sentiment1 <- dfm(mycorpus ,
remove = stopwords("english"),
remove_punct = TRUE,
remove_numbers=TRUE,
tolower = TRUE,
stem = TRUE,
remove_twitter = TRUE,
remove_url = TRUE,
dictionary = data_dictionary_LSD2015[1:2])
dictfile <- tempfile()
download.file("https://provalisresearch.com/Download/LaverGarry.zip", dictfile, mode = "wb")
unzip(dictfile, exdir = (td <- tempdir()))
lgdict <- dictionary(file = paste(td, "LaverGarry.cat", sep = "/"))
sentiment2 <- dfm(mycorpus ,
remove = stopwords("english"),
remove_punct = TRUE,
remove_numbers=TRUE,
tolower = TRUE,
remove_twitter = TRUE,
remove_url = TRUE,
dictionary = lgdict)
sentimentdf <- convert(sentiment1 , to="data.frame")
sentimentlg <- convert(sentiment2 , to="data.frame")
sentimentdf$value <- sentimentdf$posit-sentimentdf$negat
sentimentdf$Date <- as.Date(trumptweet_n_f$created_at_posixit)
sentimentdf$time <- trumptweet_n_f$created_at_posixit
sentimentdf$month <- month(sentimentdf$Date)
sentimentlg_s <- select(sentimentlg,VALUES.LIBERAL,VALUES.CONSERVATIVE)
sentimentlg_s$Date <- as.Date(trumptweet_n_f$created_at_posixit)
sentimentlg_s$time <- trumptweet_n_f$created_at_posixit
sentimentlg_s$month <- month(sentimentlg_s$Date)
lib <- aggregate(sentimentlg_s$VALUES.LIBERAL, by=list(Category=sentimentlg_s$month), FUN=sum)
con <- aggregate(sentimentlg_s$VALUES.CONSERVATIVE, by=list(Category=sentimentlg_s$month), FUN=sum)
libcon <- data.frame(month=lib$Category,
lib=lib$x,
con=con$x)
2.1. Plot dictionaries’ result
2.1.B. Sentiment by month
g2 <- ggplot(sentimentdf,aes(x=reorder(month,Date),y=value,group=month))+
geom_boxplot()+
xlab("Month")+
ylab("Value")+
theme_grey()+
ggtitle("Sentiment by month")+
theme(plot.title = element_text(hjust = 0.5,size=20))
g2

- By applying sentiment dictionary in quanteda, this box plot showed the sentiment of tweets by month
- Overall, the median of tweets was positive.
- Even though the imagination of Trump was he often used twitter to threaten and blame his opponent, the general results were more positive tweets than negative. The possible explanation was he also used a lot of positive words to strengthen and defend his actions.
2.1.C. Lib-con by month
g3 <- ggplot(libcon,aes(x=month,y=con,color="Conservative"))+
geom_line()+
geom_point()+
geom_line(aes(y=lib,color="Liberal"))+
geom_point(aes(y=lib,color="Liberal"))+
scale_x_continuous(breaks = 1:11)+
ylab("Frequency")+
theme_grey()+
ggtitle("Lib-con by month")+
theme(plot.title = element_text(hjust = 0.5,size=18))+
labs(color="")
g3

- By applying the Laver and Garry dictionary, the strong tendency that Trump was a solid republican and conservative person was stable through almost the whole 2018.
- (Since he was first US leader who used twitter a lot, I had no other presidents to compare.)
- STM
3.1. SearchK at the fisrt time (NOT run it here)
#K <-c(4,5,6,7,8,9)
#storage <- searchK(Dfm_stm$documents,
# Dfm_stm$vocab,
# K = K,
# max.em.its = 50,
# prevalence = ~ created_at,
# data = Dfm_stm$meta,
# init.type = "Spectral")
#plot(storage$results$semcoh,
# storage$results$exclus,
# xlab= "Semantic coherence",
# ylab= "Exclusivity",
# col= "blue",
# pch = 19,
# cex = 1,
# lty = "solid",
# lwd = 2)
#text(storage$results$semcoh,
# storage$results$exclus,
# labels=storage$results$K,
# cex= 1,
# pos=2)
- The searchK function could not converge in this analysis. Under this restirction, the results suggested that K=7 would be a bwtter choice.
3.2. STM
Dfm_stm <- convert(tweetdfm, to = "stm")
stmFitted1 <- stm(Dfm_stm$documents,
Dfm_stm$vocab,
K = 7,
max.em.its = 100,
prevalence = ~ created_at,
data = Dfm_stm$meta,
init.type = "Spectral")
3.3. Result of Topic Prevalence
3.3.A. Summary of topics
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted1, type = "summary", labeltype = c("frex"))

- I would name the following topics:
- Topic 1: Economic issue
- Topic 4: Trade war
- Topic 5: Conflict with democrats
- Topic 6: Midterm election
3.3.B. Wordcloud of Topic 4
par(mfrow=c(1,1))
cloud(stmFitted1, topic = 4)

- Focusing on the topic 4, we could see more terms about protective trade policy.
3.3.C. Topic Prevalence across time
w <- labelTopics(stmFitted1, topics = 1, n = 3, frexweight = 0.5)
w_df <- as.data.frame(w$frex)
w_df$sum <- paste(w_df$V1,w_df$V2,w_df$V3,sep = " / ")
prep <- estimateEffect(1:7 ~ created_at,
stmFitted1,
meta = Dfm_stm$meta,
uncertainty = "Global")
par(mfrow=c(2,2),mar=c(2,2,2,2))
for(i in c(1,4,5,6)){
x <- w_df$sum[i]
plot(prep, "created_at", method = "continuous", topics = i,
model = stmFitted1, printlegend = FALSE, xaxt = "n", xlab = "Date",ylab = "")
seq <- seq(from = min(Dfm_stm$meta$created_at), to = max(Dfm_stm$meta$created_at))
axis(1, at = seq, labels = c(as.Date(seq,origin="1970/1/1")))
title(paste("Topic",i,x))
abline(h=0, col="#99CCFF")
abline(h=0.1, col="#336699")
abline(h=0.2, col="#003366")
}

- All 7 topics had the expected propotion above zero significantly regarless of the date.
- Plotting those four topics I have named, three of them decreased across time, even the trade-war-related topic decreased graduallly. On the other hand, election-related topic increase a lot as the mid-term election coming (11/6).
LS0tCnRpdGxlOiAiSG9tZSBBc3NpZ25tZW50IDYiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6IFllbiBDaGVuZyBIc3VhbgotLS0KIyMjI1N0dWRlbnQgSUQ6IDFBMTgyOTAxLTIKKioqCj4wLiBTZXQgdXAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpybShsaXN0PWxzKGFsbD1UUlVFKSkKc2V0d2QoIn4vRGVza3RvcC9SL3BvbGltZXRyaWNzIikKbGlicmFyeShydHdlZXQpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeShxdWFudGVkYSkKbGlicmFyeShydHdlZXQpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShsYXR0aWNlKQpsaWJyYXJ5KHN5dXpoZXQpCmxpYnJhcnkoc3RtKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKYGBgCgo+MC4xLiBJbiB0aGUgZmlyc3QgdGltZSAoUnVuIGluIDExLzE0IGV2ZW5pbmcpCgpgYGB7ciwgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnRva2VuIDwtIGNyZWF0ZV90b2tlbigKICBhcHAgPSAieWVuY2hlbmdoc3VhbiIsCiAgY29uc3VtZXJfa2V5ID0gIlZVazZVRGl6eURwaTl4b1V2Y1BxdDJnRlIiLCAKICBjb25zdW1lcl9zZWNyZXQgPSAiZTNYNUp3RDAyOW9EOFd5bVFna1ZPd0VkVks3NUVncnVsdEdVT3YycHN5cUJaY0l4WUwiLCAKICBhY2Nlc3NfdG9rZW4gPSAiMTA2MjM5NjgxMzMzMDYzMjcwNC1EQnQwSzBFS28zQmJKRXhEdDJjSU1nd0VMTDh4c28iLAogIGFjY2Vzc19zZWNyZXQgPSAibFVyYkg5S0dzbDhDMmhpNlVUUERBZ3ltRXQ5bzVqZTRNU0hhc280RWVMUzh0IikKCiNSdW4gaW4gMTEvMTQgZXZlbmluZzoKICAjdHJ1bXB0d2VldCA8LSBnZXRfdGltZWxpbmUoInJlYWxEb25hbGRUcnVtcCIsIG4gPSAzMjAwKQogICN0cnVtcHR3ZWV0MSA8LSB0cnVtcHR3ZWV0WzE6MzAwMCxdCiAgI3dyaXRlX2FzX2Nzdih0cnVtcHR3ZWV0MSwgInRydW1wdHdlZXQuY3N2IiwgcHJlcGVuZF9pZHMgPSBUUlVFLCBuYSA9ICIiLCBmaWxlRW5jb2RpbmcgPSAiVVRGLTgiKQpgYGAKCj4xLiBJbXBvcnQgZGF0YQoKYGBge3J9CnRydW1wdHdlZXRfbiA8LSByZWFkLmNzdigidHJ1bXB0d2VldC5jc3YiLGVuY29kaW5nID0gIlVURi04IikKdHJ1bXB0d2VldF9uJGNyZWF0ZWRfYXRfcG9zaXhpdCA8LSBhcy5QT1NJWGN0KHRydW1wdHdlZXRfbiRjcmVhdGVkX2F0KQp0cnVtcHR3ZWV0X24kY3JlYXRlZF9hdCA8LSBhcy5udW1lcmljKGFzLkRhdGUodHJ1bXB0d2VldF9uJGNyZWF0ZWRfYXQpKQpzaW5jZSA8LSB0cnVtcHR3ZWV0X24kY3JlYXRlZF9hdF9wb3NpeGl0WzMwMDBdCmxhdGVzdCA8LSB0cnVtcHR3ZWV0X24kY3JlYXRlZF9hdF9wb3NpeGl0WzFdCnRydW1wdHdlZXRfbl9mIDwtIHNlbGVjdCh0cnVtcHR3ZWV0X24sCiAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkX2F0LAogICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZF9hdF9wb3NpeGl0LAogICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCkKdHJ1bXB0d2VldF9uX2YkdGV4dCA8LSBhcy5jaGFyYWN0ZXIodHJ1bXB0d2VldF9uX2YkdGV4dCkKbXljb3JwdXMgPC0gY29ycHVzKHRydW1wdHdlZXRfbl9mKQpgYGAKCmBgYHtyfQpjYXQoIlR3aXR0ZXIgZGF0YSIsIlxuIixwYXN0ZSgiRnJvbToiLHNpbmNlKSwiXG4iLHBhc3RlKCIgIFRvOiIsbGF0ZXN0KSkKYGBgCgoqKioKCj4yLiBEaWN0aW9uYXJpZXMKCmBgYHtyIHJlc3VsdHM9ImhpZGUiLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0d2VldGRmbSA8LSBkZm0obXljb3JwdXMgLAogICAgICAgICAgICAgICAgcmVtb3ZlID0gc3RvcHdvcmRzKCJlbmdsaXNoIiksCiAgICAgICAgICAgICAgICByZW1vdmVfcHVuY3QgPSBUUlVFLAogICAgICAgICAgICAgICAgcmVtb3ZlX251bWJlcnM9VFJVRSwgCiAgICAgICAgICAgICAgICB0b2xvd2VyID0gVFJVRSwKICAgICAgICAgICAgICAgIHN0ZW0gPSBUUlVFLAogICAgICAgICAgICAgICAgcmVtb3ZlX3R3aXR0ZXIgPSBUUlVFLCAKICAgICAgICAgICAgICAgIHJlbW92ZV91cmwgPSBUUlVFKQoKc2VudGltZW50MSA8LSBkZm0obXljb3JwdXMgLAogICAgICAgICAgICAgICAgIHJlbW92ZSA9IHN0b3B3b3JkcygiZW5nbGlzaCIpLAogICAgICAgICAgICAgICAgIHJlbW92ZV9wdW5jdCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgcmVtb3ZlX251bWJlcnM9VFJVRSwgCiAgICAgICAgICAgICAgICAgdG9sb3dlciA9IFRSVUUsCiAgICAgICAgICAgICAgICAgc3RlbSA9IFRSVUUsCiAgICAgICAgICAgICAgICAgcmVtb3ZlX3R3aXR0ZXIgPSBUUlVFLCAKICAgICAgICAgICAgICAgICByZW1vdmVfdXJsID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgZGljdGlvbmFyeSA9IGRhdGFfZGljdGlvbmFyeV9MU0QyMDE1WzE6Ml0pCgpkaWN0ZmlsZSA8LSB0ZW1wZmlsZSgpCmRvd25sb2FkLmZpbGUoImh0dHBzOi8vcHJvdmFsaXNyZXNlYXJjaC5jb20vRG93bmxvYWQvTGF2ZXJHYXJyeS56aXAiLCBkaWN0ZmlsZSwgbW9kZSA9ICJ3YiIpCnVuemlwKGRpY3RmaWxlLCBleGRpciA9ICh0ZCA8LSB0ZW1wZGlyKCkpKQpsZ2RpY3QgPC0gZGljdGlvbmFyeShmaWxlID0gcGFzdGUodGQsICJMYXZlckdhcnJ5LmNhdCIsIHNlcCA9ICIvIikpCnNlbnRpbWVudDIgPC0gZGZtKG15Y29ycHVzICwKICAgICAgICAgICAgICAgICByZW1vdmUgPSBzdG9wd29yZHMoImVuZ2xpc2giKSwKICAgICAgICAgICAgICAgICByZW1vdmVfcHVuY3QgPSBUUlVFLAogICAgICAgICAgICAgICAgIHJlbW92ZV9udW1iZXJzPVRSVUUsIAogICAgICAgICAgICAgICAgIHRvbG93ZXIgPSBUUlVFLAogICAgICAgICAgICAgICAgIHJlbW92ZV90d2l0dGVyID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgcmVtb3ZlX3VybCA9IFRSVUUsIAogICAgICAgICAgICAgICAgIGRpY3Rpb25hcnkgPSBsZ2RpY3QpCgpzZW50aW1lbnRkZiA8LSBjb252ZXJ0KHNlbnRpbWVudDEgLCB0bz0iZGF0YS5mcmFtZSIpCnNlbnRpbWVudGxnIDwtIGNvbnZlcnQoc2VudGltZW50MiAsIHRvPSJkYXRhLmZyYW1lIikKc2VudGltZW50ZGYkdmFsdWUgPC0gc2VudGltZW50ZGYkcG9zaXQtc2VudGltZW50ZGYkbmVnYXQKc2VudGltZW50ZGYkRGF0ZSA8LSBhcy5EYXRlKHRydW1wdHdlZXRfbl9mJGNyZWF0ZWRfYXRfcG9zaXhpdCkKc2VudGltZW50ZGYkdGltZSA8LSB0cnVtcHR3ZWV0X25fZiRjcmVhdGVkX2F0X3Bvc2l4aXQKc2VudGltZW50ZGYkbW9udGggPC0gbW9udGgoc2VudGltZW50ZGYkRGF0ZSkKCnNlbnRpbWVudGxnX3MgPC0gc2VsZWN0KHNlbnRpbWVudGxnLFZBTFVFUy5MSUJFUkFMLFZBTFVFUy5DT05TRVJWQVRJVkUpCnNlbnRpbWVudGxnX3MkRGF0ZSA8LSBhcy5EYXRlKHRydW1wdHdlZXRfbl9mJGNyZWF0ZWRfYXRfcG9zaXhpdCkKc2VudGltZW50bGdfcyR0aW1lIDwtIHRydW1wdHdlZXRfbl9mJGNyZWF0ZWRfYXRfcG9zaXhpdApzZW50aW1lbnRsZ19zJG1vbnRoIDwtIG1vbnRoKHNlbnRpbWVudGxnX3MkRGF0ZSkKCmxpYiA8LSBhZ2dyZWdhdGUoc2VudGltZW50bGdfcyRWQUxVRVMuTElCRVJBTCwgYnk9bGlzdChDYXRlZ29yeT1zZW50aW1lbnRsZ19zJG1vbnRoKSwgRlVOPXN1bSkKY29uIDwtIGFnZ3JlZ2F0ZShzZW50aW1lbnRsZ19zJFZBTFVFUy5DT05TRVJWQVRJVkUsIGJ5PWxpc3QoQ2F0ZWdvcnk9c2VudGltZW50bGdfcyRtb250aCksIEZVTj1zdW0pCmxpYmNvbiA8LSBkYXRhLmZyYW1lKG1vbnRoPWxpYiRDYXRlZ29yeSwKICAgICAgICAgICAgICAgICAgICAgbGliPWxpYiR4LAogICAgICAgICAgICAgICAgICAgICBjb249Y29uJHgpCmBgYAoKPjIuMS4gUGxvdCBkaWN0aW9uYXJpZXMnIHJlc3VsdAoKIyMjIzIuMS5BLiBUcnVtcCdzIFR3ZWV0cyBieSBtb250aApgYGB7cn0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpnMSA8LSBnZ3Bsb3Qoc2VudGltZW50ZGYsIGFlcyhtb250aCkpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAxOjExKSsKICBnZW9tX2Jhcih3aWR0aCA9IDAuOCxmaWxsID0gIiM5OUNDNjYiKSsKICB0aGVtZV9ncmV5KCkrCiAgZ2d0aXRsZSgiVHJ1bXAncyBUd2VldHMgYnkgbW9udGgiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHNpemU9MjApKQpnMQpgYGAKCiogVGhpcyBpcyB0aGUgdG90YWwgb2JzZXJ2YXRpb25zIG9mIHRoZSBmb2xsb3dpbmcgYW5hbHlzaXMsIERvbmFsZCBUcnVtcCBwZXJzb25hbCB0d2l0dGVyIGhhZCBwb3N0ZWQgb3ZlciAxMDAgdHdlZXRzIGV2ZXJ5IG1vbnRoLiBBZnRlciBBcHJpbCwgVHJ1bXAgcG9zdGVkIG1vcmUgdGhhbiAzMDAgdHdlZXRzIHBlciBtb250aC4KCiMjIyMyLjEuQi4gU2VudGltZW50IGJ5IG1vbnRoCmBgYHtyfQpnMiA8LSBnZ3Bsb3Qoc2VudGltZW50ZGYsYWVzKHg9cmVvcmRlcihtb250aCxEYXRlKSx5PXZhbHVlLGdyb3VwPW1vbnRoKSkrCiAgZ2VvbV9ib3hwbG90KCkrCiAgeGxhYigiTW9udGgiKSsKICB5bGFiKCJWYWx1ZSIpKwogIHRoZW1lX2dyZXkoKSsKICBnZ3RpdGxlKCJTZW50aW1lbnQgYnkgbW9udGgiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LHNpemU9MjApKQpnMgpgYGAKCiogQnkgYXBwbHlpbmcgc2VudGltZW50IGRpY3Rpb25hcnkgaW4gcXVhbnRlZGEsIHRoaXMgYm94IHBsb3Qgc2hvd2VkIHRoZSBzZW50aW1lbnQgb2YgdHdlZXRzIGJ5IG1vbnRoCiAgICAxLiBPdmVyYWxsLCB0aGUgbWVkaWFuIG9mIHR3ZWV0cyB3YXMgcG9zaXRpdmUuCiAgICAyLiBFdmVuIHRob3VnaCB0aGUgaW1hZ2luYXRpb24gb2YgVHJ1bXAgd2FzIGhlIG9mdGVuIHVzZWQgdHdpdHRlciB0byB0aHJlYXRlbiBhbmQgYmxhbWUgaGlzIG9wcG9uZW50LCB0aGUgZ2VuZXJhbCByZXN1bHRzIHdlcmUgbW9yZSBwb3NpdGl2ZSB0d2VldHMgdGhhbiBuZWdhdGl2ZS4gVGhlIHBvc3NpYmxlIGV4cGxhbmF0aW9uIHdhcyBoZSBhbHNvIHVzZWQgYSBsb3Qgb2YgcG9zaXRpdmUgd29yZHMgdG8gc3RyZW5ndGhlbiBhbmQgZGVmZW5kIGhpcyBhY3Rpb25zLgoKIyMjIzIuMS5DLiBMaWItY29uIGJ5IG1vbnRoCmBgYHtyfQpnMyA8LSBnZ3Bsb3QobGliY29uLGFlcyh4PW1vbnRoLHk9Y29uLGNvbG9yPSJDb25zZXJ2YXRpdmUiKSkrCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIGdlb21fbGluZShhZXMoeT1saWIsY29sb3I9IkxpYmVyYWwiKSkrCiAgZ2VvbV9wb2ludChhZXMoeT1saWIsY29sb3I9IkxpYmVyYWwiKSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTEpKwogIHlsYWIoIkZyZXF1ZW5jeSIpKwogIHRoZW1lX2dyZXkoKSsKICBnZ3RpdGxlKCJMaWItY29uIGJ5IG1vbnRoIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSxzaXplPTE4KSkrCiAgbGFicyhjb2xvcj0iIikgCmczCgpgYGAKCiogQnkgYXBwbHlpbmcgdGhlIExhdmVyIGFuZCBHYXJyeSBkaWN0aW9uYXJ5LCB0aGUgc3Ryb25nIHRlbmRlbmN5IHRoYXQgVHJ1bXAgd2FzIGEgc29saWQgcmVwdWJsaWNhbiBhbmQgY29uc2VydmF0aXZlIHBlcnNvbiB3YXMgc3RhYmxlIHRocm91Z2ggYWxtb3N0IHRoZSB3aG9sZSAyMDE4LgoqIChTaW5jZSBoZSB3YXMgZmlyc3QgVVMgbGVhZGVyIHdobyB1c2VkIHR3aXR0ZXIgYSBsb3QsIEkgaGFkIG5vIG90aGVyIHByZXNpZGVudHMgdG8gY29tcGFyZS4pCgoqKioKCj4zLiBTVE0KCj4zLjEuIFNlYXJjaEsgYXQgdGhlIGZpc3J0IHRpbWUgKE5PVCBydW4gaXQgaGVyZSkKYGBge3IsIGV2YWw9RiwgZWNobz1UfQojSyA8LWMoNCw1LDYsNyw4LDkpCiNzdG9yYWdlICA8LSBzZWFyY2hLKERmbV9zdG0kZG9jdW1lbnRzLAojICAgICAgICAgICAgICAgICAgICBEZm1fc3RtJHZvY2FiLAojICAgICAgICAgICAgICAgICAgICBLID0gSywKIyAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDUwLAojICAgICAgICAgICAgICAgICAgICBwcmV2YWxlbmNlID0gfiBjcmVhdGVkX2F0LAojICAgICAgICAgICAgICAgICAgICBkYXRhID0gRGZtX3N0bSRtZXRhLAojICAgICAgICAgICAgICAgICAgICBpbml0LnR5cGUgPSAiU3BlY3RyYWwiKQojcGxvdChzdG9yYWdlJHJlc3VsdHMkc2VtY29oLAojICAgICBzdG9yYWdlJHJlc3VsdHMkZXhjbHVzLAojICAgICB4bGFiPSAiU2VtYW50aWMgY29oZXJlbmNlIiwKIyAgICAgeWxhYj0gIkV4Y2x1c2l2aXR5IiwKIyAgICAgY29sPSAiYmx1ZSIsCiMgICAgIHBjaCA9IDE5LAojICAgICBjZXggPSAxLAojICAgICBsdHkgPSAic29saWQiLAojICAgICBsd2QgPSAyKQojdGV4dChzdG9yYWdlJHJlc3VsdHMkc2VtY29oLAojICAgICBzdG9yYWdlJHJlc3VsdHMkZXhjbHVzLAojICAgICBsYWJlbHM9c3RvcmFnZSRyZXN1bHRzJEssCiMgICAgIGNleD0gMSwKIyAgICAgcG9zPTIpCmBgYAoKKiBUaGUgc2VhcmNoSyBmdW5jdGlvbiBjb3VsZCBub3QgY29udmVyZ2UgaW4gdGhpcyBhbmFseXNpcy4gVW5kZXIgdGhpcyByZXN0aXJjdGlvbiwgdGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgSz03IHdvdWxkIGJlIGEgYnd0dGVyIGNob2ljZS4KCj4zLjIuIFNUTQpgYGB7ciByZXN1bHRzPSJoaWRlIiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KRGZtX3N0bSA8LSBjb252ZXJ0KHR3ZWV0ZGZtLCB0byA9ICJzdG0iKQpzdG1GaXR0ZWQxIDwtIHN0bShEZm1fc3RtJGRvY3VtZW50cywKICAgICAgICAgICAgICAgICAgRGZtX3N0bSR2b2NhYiwKICAgICAgICAgICAgICAgICAgSyA9IDcsCiAgICAgICAgICAgICAgICAgIG1heC5lbS5pdHMgPSAxMDAsCiAgICAgICAgICAgICAgICAgIHByZXZhbGVuY2UgPSB+IGNyZWF0ZWRfYXQsCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBEZm1fc3RtJG1ldGEsCiAgICAgICAgICAgICAgICAgIGluaXQudHlwZSA9ICJTcGVjdHJhbCIpCmBgYAoKPjMuMy4gUmVzdWx0IG9mIFRvcGljIFByZXZhbGVuY2UKCiMjIyMzLjMuQS4gU3VtbWFyeSBvZiB0b3BpY3MKYGBge3J9CnBhcihtZnJvdz1jKDEsMSksbWFyPWMoNS4xLCA0LjEsIDQuMSwgMi4xKSkKcGxvdChzdG1GaXR0ZWQxLCB0eXBlID0gInN1bW1hcnkiLCBsYWJlbHR5cGUgPSBjKCJmcmV4IikpCmBgYAoKKiBJIHdvdWxkIG5hbWUgdGhlIGZvbGxvd2luZyB0b3BpY3M6IAogICAgMS4gVG9waWMgMTogRWNvbm9taWMgaXNzdWUKICAgIDIuIFRvcGljIDQ6IFRyYWRlIHdhcgogICAgMy4gVG9waWMgNTogQ29uZmxpY3Qgd2l0aCBkZW1vY3JhdHMKICAgIDQuIFRvcGljIDY6IE1pZHRlcm0gZWxlY3Rpb24KCiMjIyMzLjMuQi4gV29yZGNsb3VkIG9mIFRvcGljIDQKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBhcihtZnJvdz1jKDEsMSkpCmNsb3VkKHN0bUZpdHRlZDEsIHRvcGljID0gNCkKYGBgCgoqIEZvY3VzaW5nIG9uIHRoZSB0b3BpYyA0LCB3ZSBjb3VsZCBzZWUgbW9yZSB0ZXJtcyBhYm91dCBwcm90ZWN0aXZlIHRyYWRlIHBvbGljeS4KCiMjIyMzLjMuQy4gVG9waWMgUHJldmFsZW5jZSBhY3Jvc3MgdGltZQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KdyA8LSBsYWJlbFRvcGljcyhzdG1GaXR0ZWQxLCB0b3BpY3MgPSAxLCBuID0gMywgZnJleHdlaWdodCA9IDAuNSkKd19kZiA8LSBhcy5kYXRhLmZyYW1lKHckZnJleCkKd19kZiRzdW0gPC0gcGFzdGUod19kZiRWMSx3X2RmJFYyLHdfZGYkVjMsc2VwID0gIiAvICIpCgpwcmVwIDwtIGVzdGltYXRlRWZmZWN0KDE6NyB+IGNyZWF0ZWRfYXQsIAogICAgICAgICAgICAgICAgICAgICAgIHN0bUZpdHRlZDEsIAogICAgICAgICAgICAgICAgICAgICAgIG1ldGEgPSBEZm1fc3RtJG1ldGEsIAogICAgICAgICAgICAgICAgICAgICAgIHVuY2VydGFpbnR5ID0gIkdsb2JhbCIpCnBhcihtZnJvdz1jKDIsMiksbWFyPWMoMiwyLDIsMikpCmZvcihpIGluIGMoMSw0LDUsNikpewogIHggPC0gd19kZiRzdW1baV0KICBwbG90KHByZXAsICJjcmVhdGVkX2F0IiwgbWV0aG9kID0gImNvbnRpbnVvdXMiLCB0b3BpY3MgPSBpLAogICAgICAgbW9kZWwgPSBzdG1GaXR0ZWQxLCBwcmludGxlZ2VuZCA9IEZBTFNFLCB4YXh0ID0gIm4iLCB4bGFiID0gIkRhdGUiLHlsYWIgPSAiIikKICBzZXEgPC0gc2VxKGZyb20gPSBtaW4oRGZtX3N0bSRtZXRhJGNyZWF0ZWRfYXQpLCB0byA9IG1heChEZm1fc3RtJG1ldGEkY3JlYXRlZF9hdCkpCiAgYXhpcygxLCBhdCA9IHNlcSwgbGFiZWxzID0gYyhhcy5EYXRlKHNlcSxvcmlnaW49IjE5NzAvMS8xIikpKQogIHRpdGxlKHBhc3RlKCJUb3BpYyIsaSx4KSkKICBhYmxpbmUoaD0wLCBjb2w9IiM5OUNDRkYiKQogIGFibGluZShoPTAuMSwgY29sPSIjMzM2Njk5IikKICBhYmxpbmUoaD0wLjIsIGNvbD0iIzAwMzM2NiIpCn0KYGBgCgoqIEFsbCA3IHRvcGljcyBoYWQgdGhlIGV4cGVjdGVkIHByb3BvdGlvbiBhYm92ZSB6ZXJvIHNpZ25pZmljYW50bHkgcmVnYXJsZXNzIG9mIHRoZSBkYXRlLgoqIFBsb3R0aW5nIHRob3NlIGZvdXIgdG9waWNzIEkgaGF2ZSBuYW1lZCwgdGhyZWUgb2YgdGhlbSBkZWNyZWFzZWQgYWNyb3NzIHRpbWUsIGV2ZW4gdGhlIHRyYWRlLXdhci1yZWxhdGVkIHRvcGljIGRlY3JlYXNlZCBncmFkdWFsbGx5LiBPbiB0aGUgb3RoZXIgaGFuZCwgZWxlY3Rpb24tcmVsYXRlZCB0b3BpYyBpbmNyZWFzZSBhIGxvdCBhcyB0aGUgbWlkLXRlcm0gZWxlY3Rpb24gY29taW5nICgxMS82KS4KCioqKg==