Student ID: 1A182901-2
- Set up environment
rm(list=ls(all=TRUE))
setwd("~/Desktop/R/polimetrics")
library(quanteda)
library(readtext)
library(stm)
library(ggplot2)
library(wordcloud)
library(cowplot)
- Import Data
myText <- readtext("~/Desktop/r/polimetrics/UK/*.txt",
docvarsfrom = "filenames", dvsep = " ", docvarnames = c("Party", "Year"))
mycorpus <- corpus(myText, docid_field = "doc_id")
docnames(mycorpus) <- gsub(".txt", "", docnames(mycorpus ))
myDfm <- dfm(mycorpus , remove = stopwords("english"), tolower = TRUE, stem = TRUE,
remove_punct = TRUE, remove_numbers=TRUE)
- Wordfish
reswf <- textmodel_wordfish(myDfm, dir = c(3, 1))
df_wf <- data.frame(v_wf = reswf$theta,
title = reswf$docs,
year = docvars(myDfm)$Year)
##Graph
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
gr_wf <- ggplot(df_wf,aes(y=reorder(title,v_wf),x=v_wf))
gr_wf_res <- gr_wf +
geom_point() +
ggtitle("Wordfish Result") +
ylab("") +
xlab("") +
theme_light() +
theme(legend.position="none",plot.title = element_text(hjust = 0.5))
gr_wf_res

- STM with wf score
mycorpus2 <- mycorpus
mycorpus2$documents$wf <- df_wf$v_wf
myDfm2 <- dfm(mycorpus2 , remove = stopwords("english"), tolower = TRUE, stem = TRUE,
remove_punct = TRUE, remove_numbers=TRUE)
#STM
Dfm_stm <- convert(myDfm2, to = "stm", docvars = docvars(mycorpus2))
Dfm_stm$meta$Year <- as.character(Dfm_stm$meta$Year)
stmFitted1 <- stm(Dfm_stm$documents,
Dfm_stm$vocab,
K = 6,
max.em.its = 50,
prevalence = ~ wf + Year,
data = Dfm_stm$meta,
init.type = "Spectral")
prep <- estimateEffect(1:6 ~ wf + Year,
stmFitted1,
meta = Dfm_stm$meta,
uncertainty = "Global")
4.1. Justify “K=6”
K <-c(5,6,7)
storage <- searchK(Dfm_stm$documents,
Dfm_stm$vocab,
K,
max.em.its = 75,
N = floor(0.2 * length(Dfm_stm$documents)),
prevalence = ~ Year + wf,
data = Dfm_stm$meta,
init.type = "Spectral")
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
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)

- As the plot of semantic coherence and exclusivity, K equal to 6 was the suggested setup.
4.2. Top Topics
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted1, type = "summary", labeltype = c("frex"))

par(mfrow=c(1,1),mar=c(0, 1, 0, 1))
plot(stmFitted1, type = "labels", labeltype = c("frex"))

- As the FREX result of those six topics, some of the topics could be represented as specific issues.
- Topic 4 might be the liberal democratic topic.
- Topic 5 might be the labor topic.
- Topic 6 might be the conservative topic.
- I chose to plot topic 4 and topic 6 across wordfish score as the following.
par(mfrow=c(2,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(prep, "wf", method = "continuous", topics = 4,
model = stmFitted1, printlegend = FALSE, xaxt = "n", xlab = "wf")
seq <- seq(from = as.numeric("-2"), to = as.numeric("2"))
axis(1, at = seq)
title("Topic 4")
abline(h=0, col="blue")
plot(prep, "wf", method = "continuous", topics = 6,
model = stmFitted1, printlegend = FALSE, xaxt = "n", xlab = "wf")
seq <- seq(from = as.numeric("-2"), to = as.numeric("2"))
axis(1, at = seq)
title("Topic 6")
abline(h=0, col="blue")

- As the wordfish position LIBDEM - LAB - CONS, the result showed contradictory patterns between topic 4 and topic 6.
- LIBDEM represented more topic 4, which including the terms of liberal democracy, and the proposion decreased gradually as wordfish score increased.
- On the other hand, the CONS in 1992 and 1997 talked more propotion of topic 6.
4.3. 92 versus 97
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(prep,
covariate = "Year",
topics = c(1, 2, 3, 4, 5,6),
model = stmFitted1, method = "difference",
cov.value1 = "97",
cov.value2 = "92",
xlim = c(-1, 1),
xlab = "More 1992 ... More 1997",
main = "Effect of 92 vs. 97",
labeltype = "custom",
custom.labels = c('Topic 1','Topic2', 'Topic 3','Topic 4', 'Topic 5','Topic 6'))

- Despite some difference of positions, all 6 topics were not significantly presented only in 1992 or 1997.
- STM with only Year
Dfm_stm2 <- convert(myDfm, to = "stm", docvars = docvars(mycorpus))
Dfm_stm2$meta$Year <- as.character(Dfm_stm2$meta$Year)
stmFitted2 <- stm(Dfm_stm2$documents,
Dfm_stm2$vocab,
K = 6,
max.em.its = 50,
prevalence = ~ Year,
data = Dfm_stm2$meta,
init.type = "Spectral")
prep2 <- estimateEffect(1:6 ~ Year,
stmFitted2,
meta = Dfm_stm2$meta,
uncertainty = "Global")
stmFitted2_content <- stm(Dfm_stm2$documents,
Dfm_stm2$vocab,
K = 6,
max.em.its = 75,
prevalence = ~ Year,
content = ~ Year,
data = Dfm_stm2$meta,
init.type = "Spectral")
5.1. Check K
K <-c(5,6,7)
storage2 <- searchK(Dfm_stm2$documents,
Dfm_stm2$vocab,
K,
max.em.its = 75,
N = floor(0.2 * length(Dfm_stm2$documents)),
prevalence = ~ Year,
data = Dfm_stm2$meta,
init.type = "Spectral")
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(storage2$results$semcoh,
storage2$results$exclus,
xlab= "Semantic coherence",
ylab= "Exclusivity",
col= "blue",
pch = 19,
cex = 1,
lty = "solid",
lwd = 2)
text(storage2$results$semcoh,
storage2$results$exclus,
labels=storage2$results$K,
cex= 1,
pos=2)

- As the graph above, K equal to 6 was still the suggested setup.
5.2. Result
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted2, type = "summary", labeltype = c("frex"))

par(mfrow=c(2,1),mar=c(1,1,1,1))
plot(stmFitted2_content, type = "perspectives", topics = 4,main = "Topic4")
plot(stmFitted2_content, type = "perspectives", topics = 6,main = "Topic6")

- The comparison between 1992 and 1997 in topic 4 and 6 showed the following patterns.
- The representative words were similar to the previous discussion including wordfish score.
- The word “school” was used more often in 1997, in both topic 4 and topic 6.
- Most of the representative words appeared in both 1992 and 1997 manifesto.
par(mfrow=c(1,1),mar=c(5.1, 4.1, 4.1, 2.1))
plot(stmFitted2, type = "perspectives", labeltype = c("frex"), topics = c(4, 6))

- Comparing Topic 4 and Topic 6, the pattern of Topic 4 as a democratic topic was more significant. On the other hand, the topic 6 did not show clear issue.
LS0tCnRpdGxlOiAiSG9tZSBBc3NpZ25tZW50IDQiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6IFllbiBDaGVuZyBIc3VhbgotLS0KIyMjI1N0dWRlbnQgSUQ6IDFBMTgyOTAxLTIKKioqCgo+MS4gU2V0IHVwIGVudmlyb25tZW50CgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Kcm0obGlzdD1scyhhbGw9VFJVRSkpCnNldHdkKCJ+L0Rlc2t0b3AvUi9wb2xpbWV0cmljcyIpCmxpYnJhcnkocXVhbnRlZGEpCmxpYnJhcnkocmVhZHRleHQpCmxpYnJhcnkoc3RtKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkod29yZGNsb3VkKQpsaWJyYXJ5KGNvd3Bsb3QpCmBgYAoKPjIuIEltcG9ydCBEYXRhCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbXlUZXh0IDwtIHJlYWR0ZXh0KCJ+L0Rlc2t0b3Avci9wb2xpbWV0cmljcy9VSy8qLnR4dCIsCiAgICAgICAgICAgICAgICAgICBkb2N2YXJzZnJvbSA9ICJmaWxlbmFtZXMiLCBkdnNlcCA9ICIgIiwgZG9jdmFybmFtZXMgPSBjKCJQYXJ0eSIsICJZZWFyIikpCgpteWNvcnB1cyA8LSBjb3JwdXMobXlUZXh0LCBkb2NpZF9maWVsZCA9ICJkb2NfaWQiKQpkb2NuYW1lcyhteWNvcnB1cykgPC0gZ3N1YigiLnR4dCIsICIiLCBkb2NuYW1lcyhteWNvcnB1cyApKQoKbXlEZm0gPC0gZGZtKG15Y29ycHVzICwgcmVtb3ZlID0gc3RvcHdvcmRzKCJlbmdsaXNoIiksIHRvbG93ZXIgPSBUUlVFLCBzdGVtID0gVFJVRSwKICAgICAgICAgICAgIHJlbW92ZV9wdW5jdCA9IFRSVUUsIHJlbW92ZV9udW1iZXJzPVRSVUUpCgpgYGAKCj4zLiBXb3JkZmlzaAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnJlc3dmIDwtIHRleHRtb2RlbF93b3JkZmlzaChteURmbSwgZGlyID0gYygzLCAxKSkKZGZfd2YgPC0gZGF0YS5mcmFtZSh2X3dmID0gcmVzd2YkdGhldGEsCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSByZXN3ZiRkb2NzLAogICAgICAgICAgICAgICAgICAgIHllYXIgPSBkb2N2YXJzKG15RGZtKSRZZWFyKQoKIyNHcmFwaApwYXIobWZyb3c9YygxLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCmdyX3dmIDwtIGdncGxvdChkZl93ZixhZXMoeT1yZW9yZGVyKHRpdGxlLHZfd2YpLHg9dl93ZikpCmdyX3dmX3JlcyA8LSBncl93ZiArCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2d0aXRsZSgiV29yZGZpc2ggUmVzdWx0IikgKwogIHlsYWIoIiIpICsgCiAgeGxhYigiIikgKyAKICB0aGVtZV9saWdodCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIixwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKZ3Jfd2ZfcmVzCmBgYAoKPjQuIFNUTSB3aXRoIHdmIHNjb3JlCgpgYGB7ciByZXN1bHRzPSJoaWRlIn0KbXljb3JwdXMyIDwtIG15Y29ycHVzCm15Y29ycHVzMiRkb2N1bWVudHMkd2YgPC0gZGZfd2Ykdl93ZgpteURmbTIgPC0gZGZtKG15Y29ycHVzMiAsIHJlbW92ZSA9IHN0b3B3b3JkcygiZW5nbGlzaCIpLCB0b2xvd2VyID0gVFJVRSwgc3RlbSA9IFRSVUUsCiAgICAgICAgICAgICByZW1vdmVfcHVuY3QgPSBUUlVFLCByZW1vdmVfbnVtYmVycz1UUlVFKQojU1RNCkRmbV9zdG0gPC0gY29udmVydChteURmbTIsIHRvID0gInN0bSIsIGRvY3ZhcnMgPSBkb2N2YXJzKG15Y29ycHVzMikpCkRmbV9zdG0kbWV0YSRZZWFyIDwtIGFzLmNoYXJhY3RlcihEZm1fc3RtJG1ldGEkWWVhcikKc3RtRml0dGVkMSA8LSBzdG0oRGZtX3N0bSRkb2N1bWVudHMsCiAgICAgICAgICAgICAgICAgRGZtX3N0bSR2b2NhYiwKICAgICAgICAgICAgICAgICBLID0gNiwKICAgICAgICAgICAgICAgICBtYXguZW0uaXRzID0gNTAsCiAgICAgICAgICAgICAgICAgcHJldmFsZW5jZSA9IH4gd2YgKyBZZWFyLAogICAgICAgICAgICAgICAgIGRhdGEgPSBEZm1fc3RtJG1ldGEsCiAgICAgICAgICAgICAgICAgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKcHJlcCA8LSBlc3RpbWF0ZUVmZmVjdCgxOjYgfiB3ZiArIFllYXIsIAogICAgICAgICAgICAgICAgICAgICAgIHN0bUZpdHRlZDEsIAogICAgICAgICAgICAgICAgICAgICAgIG1ldGEgPSBEZm1fc3RtJG1ldGEsIAogICAgICAgICAgICAgICAgICAgICAgIHVuY2VydGFpbnR5ID0gIkdsb2JhbCIpCgpgYGAKCj40LjEuIEp1c3RpZnkgIks9NiIKCmBgYHtyIHJlc3VsdHM9ImhpZGUifQpLIDwtYyg1LDYsNykKc3RvcmFnZSAgPC0gc2VhcmNoSyhEZm1fc3RtJGRvY3VtZW50cywKICAgICAgICAgICAgICAgICAgICBEZm1fc3RtJHZvY2FiLAogICAgICAgICAgICAgICAgICAgIEssCiAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDc1LAogICAgICAgICAgICAgICAgICAgIE4gPSBmbG9vcigwLjIgKiBsZW5ndGgoRGZtX3N0bSRkb2N1bWVudHMpKSwKICAgICAgICAgICAgICAgICAgICBwcmV2YWxlbmNlID0gfiBZZWFyICsgd2YsCiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IERmbV9zdG0kbWV0YSwKICAgICAgICAgICAgICAgICAgICBpbml0LnR5cGUgPSAiU3BlY3RyYWwiKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwYXIobWZyb3c9YygxLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCnBsb3Qoc3RvcmFnZSRyZXN1bHRzJHNlbWNvaCwKICAgICBzdG9yYWdlJHJlc3VsdHMkZXhjbHVzLAogICAgIHhsYWI9ICJTZW1hbnRpYyBjb2hlcmVuY2UiLAogICAgIHlsYWI9ICJFeGNsdXNpdml0eSIsCiAgICAgY29sPSAiYmx1ZSIsCiAgICAgcGNoID0gMTksCiAgICAgY2V4ID0gMSwKICAgICBsdHkgPSAic29saWQiLAogICAgIGx3ZCA9IDIpCnRleHQoc3RvcmFnZSRyZXN1bHRzJHNlbWNvaCwKICAgICBzdG9yYWdlJHJlc3VsdHMkZXhjbHVzLAogICAgIGxhYmVscz1zdG9yYWdlJHJlc3VsdHMkSywKICAgICBjZXg9IDEsCiAgICAgcG9zPTIpCmBgYAoKKiBBcyB0aGUgcGxvdCBvZiBzZW1hbnRpYyBjb2hlcmVuY2UgYW5kIGV4Y2x1c2l2aXR5LCBLIGVxdWFsIHRvIDYgd2FzIHRoZSBzdWdnZXN0ZWQgc2V0dXAuCgo+NC4yLiBUb3AgVG9waWNzCgpgYGB7cn0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpwbG90KHN0bUZpdHRlZDEsIHR5cGUgPSAic3VtbWFyeSIsIGxhYmVsdHlwZSA9IGMoImZyZXgiKSkKYGBgCmBgYHtyfQpwYXIobWZyb3c9YygxLDEpLG1hcj1jKDAsIDEsIDAsIDEpKQpwbG90KHN0bUZpdHRlZDEsIHR5cGUgPSAibGFiZWxzIiwgbGFiZWx0eXBlID0gYygiZnJleCIpKQpgYGAKCiogQXMgdGhlIEZSRVggcmVzdWx0IG9mIHRob3NlIHNpeCB0b3BpY3MsIHNvbWUgb2YgdGhlIHRvcGljcyBjb3VsZCBiZSByZXByZXNlbnRlZCBhcyBzcGVjaWZpYyBpc3N1ZXMuCiAgICAxLiBUb3BpYyA0IG1pZ2h0IGJlIHRoZSBsaWJlcmFsIGRlbW9jcmF0aWMgdG9waWMuCiAgICAyLiBUb3BpYyA1IG1pZ2h0IGJlIHRoZSBsYWJvciB0b3BpYy4KICAgIDMuIFRvcGljIDYgbWlnaHQgYmUgdGhlIGNvbnNlcnZhdGl2ZSB0b3BpYy4KCiogSSBjaG9zZSB0byBwbG90IHRvcGljIDQgYW5kIHRvcGljIDYgYWNyb3NzIHdvcmRmaXNoIHNjb3JlIGFzIHRoZSBmb2xsb3dpbmcuCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpwYXIobWZyb3c9YygyLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCgpwbG90KHByZXAsICJ3ZiIsIG1ldGhvZCA9ICJjb250aW51b3VzIiwgdG9waWNzID0gNCwKICAgICBtb2RlbCA9IHN0bUZpdHRlZDEsIHByaW50bGVnZW5kID0gRkFMU0UsIHhheHQgPSAibiIsIHhsYWIgPSAid2YiKQpzZXEgPC0gc2VxKGZyb20gPSBhcy5udW1lcmljKCItMiIpLCB0byA9IGFzLm51bWVyaWMoIjIiKSkKYXhpcygxLCBhdCA9IHNlcSkKdGl0bGUoIlRvcGljIDQiKQphYmxpbmUoaD0wLCBjb2w9ImJsdWUiKQoKcGxvdChwcmVwLCAid2YiLCBtZXRob2QgPSAiY29udGludW91cyIsIHRvcGljcyA9IDYsCiAgICAgbW9kZWwgPSBzdG1GaXR0ZWQxLCBwcmludGxlZ2VuZCA9IEZBTFNFLCB4YXh0ID0gIm4iLCB4bGFiID0gIndmIikKc2VxIDwtIHNlcShmcm9tID0gYXMubnVtZXJpYygiLTIiKSwgdG8gPSBhcy5udW1lcmljKCIyIikpCmF4aXMoMSwgYXQgPSBzZXEpCnRpdGxlKCJUb3BpYyA2IikKYWJsaW5lKGg9MCwgY29sPSJibHVlIikKYGBgCgoqIEFzIHRoZSB3b3JkZmlzaCBwb3NpdGlvbiBMSUJERU0gLSBMQUIgLSBDT05TLCB0aGUgcmVzdWx0IHNob3dlZCBjb250cmFkaWN0b3J5IHBhdHRlcm5zIGJldHdlZW4gdG9waWMgNCBhbmQgdG9waWMgNi4KICAgICsgTElCREVNIHJlcHJlc2VudGVkIG1vcmUgdG9waWMgNCwgd2hpY2ggaW5jbHVkaW5nIHRoZSB0ZXJtcyBvZiBsaWJlcmFsIGRlbW9jcmFjeSwgYW5kIHRoZSBwcm9wb3Npb24gZGVjcmVhc2VkIGdyYWR1YWxseSBhcyB3b3JkZmlzaCBzY29yZSBpbmNyZWFzZWQuCiAgICArIE9uIHRoZSBvdGhlciBoYW5kLCB0aGUgQ09OUyBpbiAxOTkyIGFuZCAxOTk3IHRhbGtlZCBtb3JlIHByb3BvdGlvbiBvZiB0b3BpYyA2LgoKPjQuMy4gOTIgdmVyc3VzIDk3CgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpwbG90KHByZXAsCiAgICAgY292YXJpYXRlID0gIlllYXIiLCAKICAgICB0b3BpY3MgPSBjKDEsIDIsIDMsIDQsIDUsNiksCiAgICAgbW9kZWwgPSBzdG1GaXR0ZWQxLCBtZXRob2QgPSAiZGlmZmVyZW5jZSIsCiAgICAgY292LnZhbHVlMSA9ICI5NyIsIAogICAgIGNvdi52YWx1ZTIgPSAiOTIiLAogICAgIHhsaW0gPSBjKC0xLCAxKSwKICAgICB4bGFiID0gIk1vcmUgMTk5MiAgICAgLi4uICAgIE1vcmUgMTk5NyIsCiAgICAgbWFpbiA9ICJFZmZlY3Qgb2YgOTIgdnMuIDk3IiwKICAgICBsYWJlbHR5cGUgPSAiY3VzdG9tIiwKICAgICBjdXN0b20ubGFiZWxzID0gYygnVG9waWMgMScsJ1RvcGljMicsICdUb3BpYyAzJywnVG9waWMgNCcsICdUb3BpYyA1JywnVG9waWMgNicpKQpgYGAKKiBEZXNwaXRlIHNvbWUgZGlmZmVyZW5jZSBvZiBwb3NpdGlvbnMsIGFsbCA2IHRvcGljcyB3ZXJlIG5vdCBzaWduaWZpY2FudGx5IHByZXNlbnRlZCBvbmx5IGluIDE5OTIgb3IgMTk5Ny4KCj41LiBTVE0gd2l0aCBvbmx5IFllYXIKCmBgYHtyIGVjaG89VCwgcmVzdWx0cz0iaGlkZSJ9CkRmbV9zdG0yIDwtIGNvbnZlcnQobXlEZm0sIHRvID0gInN0bSIsIGRvY3ZhcnMgPSBkb2N2YXJzKG15Y29ycHVzKSkKRGZtX3N0bTIkbWV0YSRZZWFyIDwtIGFzLmNoYXJhY3RlcihEZm1fc3RtMiRtZXRhJFllYXIpCgpzdG1GaXR0ZWQyIDwtIHN0bShEZm1fc3RtMiRkb2N1bWVudHMsCiAgICAgICAgICAgICAgICAgIERmbV9zdG0yJHZvY2FiLAogICAgICAgICAgICAgICAgICBLID0gNiwKICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDUwLAogICAgICAgICAgICAgICAgICBwcmV2YWxlbmNlID0gfiBZZWFyLAogICAgICAgICAgICAgICAgICBkYXRhID0gRGZtX3N0bTIkbWV0YSwKICAgICAgICAgICAgICAgICAgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKCnByZXAyIDwtIGVzdGltYXRlRWZmZWN0KDE6NiB+IFllYXIsIAogICAgICAgICAgICAgICAgICAgICAgIHN0bUZpdHRlZDIsIAogICAgICAgICAgICAgICAgICAgICAgIG1ldGEgPSBEZm1fc3RtMiRtZXRhLCAKICAgICAgICAgICAgICAgICAgICAgICB1bmNlcnRhaW50eSA9ICJHbG9iYWwiKQpzdG1GaXR0ZWQyX2NvbnRlbnQgPC0gc3RtKERmbV9zdG0yJGRvY3VtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgIERmbV9zdG0yJHZvY2FiLAogICAgICAgICAgICAgICAgICAgICAgICAgSyA9IDYsIAogICAgICAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDc1LCAKICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZhbGVuY2UgPSB+IFllYXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudCA9IH4gWWVhciwgIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IERmbV9zdG0yJG1ldGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKYGBgCgo+NS4xLiBDaGVjayBLCgpgYGB7ciBlY2hvPVQsIHJlc3VsdHM9ImhpZGUifQpLIDwtYyg1LDYsNykKc3RvcmFnZTIgIDwtIHNlYXJjaEsoRGZtX3N0bTIkZG9jdW1lbnRzLAogICAgICAgICAgICAgICAgICAgIERmbV9zdG0yJHZvY2FiLAogICAgICAgICAgICAgICAgICAgIEssCiAgICAgICAgICAgICAgICAgICAgbWF4LmVtLml0cyA9IDc1LAogICAgICAgICAgICAgICAgICAgIE4gPSBmbG9vcigwLjIgKiBsZW5ndGgoRGZtX3N0bTIkZG9jdW1lbnRzKSksCiAgICAgICAgICAgICAgICAgICAgcHJldmFsZW5jZSA9IH4gWWVhciwKICAgICAgICAgICAgICAgICAgICBkYXRhID0gRGZtX3N0bTIkbWV0YSwKICAgICAgICAgICAgICAgICAgICBpbml0LnR5cGUgPSAiU3BlY3RyYWwiKQpgYGAKCmBgYHtyfQpwYXIobWZyb3c9YygxLDEpLG1hcj1jKDUuMSwgNC4xLCA0LjEsIDIuMSkpCnBsb3Qoc3RvcmFnZTIkcmVzdWx0cyRzZW1jb2gsCiAgICAgc3RvcmFnZTIkcmVzdWx0cyRleGNsdXMsCiAgICAgeGxhYj0gIlNlbWFudGljIGNvaGVyZW5jZSIsCiAgICAgeWxhYj0gIkV4Y2x1c2l2aXR5IiwKICAgICBjb2w9ICJibHVlIiwKICAgICBwY2ggPSAxOSwKICAgICBjZXggPSAxLAogICAgIGx0eSA9ICJzb2xpZCIsCiAgICAgbHdkID0gMikKdGV4dChzdG9yYWdlMiRyZXN1bHRzJHNlbWNvaCwKICAgICBzdG9yYWdlMiRyZXN1bHRzJGV4Y2x1cywKICAgICBsYWJlbHM9c3RvcmFnZTIkcmVzdWx0cyRLLAogICAgIGNleD0gMSwKICAgICBwb3M9MikKYGBgCgoqIEFzIHRoZSBncmFwaCBhYm92ZSwgSyBlcXVhbCB0byA2IHdhcyBzdGlsbCB0aGUgc3VnZ2VzdGVkIHNldHVwLgoKPjUuMi4gUmVzdWx0CgpgYGB7cn0KcGFyKG1mcm93PWMoMSwxKSxtYXI9Yyg1LjEsIDQuMSwgNC4xLCAyLjEpKQpwbG90KHN0bUZpdHRlZDIsIHR5cGUgPSAic3VtbWFyeSIsIGxhYmVsdHlwZSA9IGMoImZyZXgiKSkKYGBgCmBgYHtyfQpwYXIobWZyb3c9YygyLDEpLG1hcj1jKDEsMSwxLDEpKQpwbG90KHN0bUZpdHRlZDJfY29udGVudCwgdHlwZSA9ICJwZXJzcGVjdGl2ZXMiLCB0b3BpY3MgPSA0LG1haW4gPSAiVG9waWM0IikKcGxvdChzdG1GaXR0ZWQyX2NvbnRlbnQsIHR5cGUgPSAicGVyc3BlY3RpdmVzIiwgdG9waWNzID0gNixtYWluID0gIlRvcGljNiIpCmBgYAoqIFRoZSBjb21wYXJpc29uIGJldHdlZW4gMTk5MiBhbmQgMTk5NyBpbiB0b3BpYyA0IGFuZCA2IHNob3dlZCB0aGUgZm9sbG93aW5nIHBhdHRlcm5zLgogICAgMS4gVGhlIHJlcHJlc2VudGF0aXZlIHdvcmRzIHdlcmUgc2ltaWxhciB0byB0aGUgcHJldmlvdXMgZGlzY3Vzc2lvbiBpbmNsdWRpbmcgd29yZGZpc2ggc2NvcmUuIAogICAgMi4gVGhlIHdvcmQgInNjaG9vbCIgd2FzIHVzZWQgbW9yZSBvZnRlbiBpbiAxOTk3LCBpbiBib3RoIHRvcGljIDQgYW5kIHRvcGljIDYuCiAgICAzLiBNb3N0IG9mIHRoZSByZXByZXNlbnRhdGl2ZSB3b3JkcyBhcHBlYXJlZCBpbiBib3RoIDE5OTIgYW5kIDE5OTcgbWFuaWZlc3RvLgoKYGBge3J9CnBhcihtZnJvdz1jKDEsMSksbWFyPWMoNS4xLCA0LjEsIDQuMSwgMi4xKSkKcGxvdChzdG1GaXR0ZWQyLCB0eXBlID0gInBlcnNwZWN0aXZlcyIsIGxhYmVsdHlwZSA9IGMoImZyZXgiKSwgdG9waWNzID0gYyg0LCA2KSkKYGBgCgoqIENvbXBhcmluZyBUb3BpYyA0IGFuZCBUb3BpYyA2LCB0aGUgcGF0dGVybiBvZiBUb3BpYyA0IGFzIGEgZGVtb2NyYXRpYyB0b3BpYyB3YXMgbW9yZSBzaWduaWZpY2FudC4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSB0b3BpYyA2IGRpZCBub3Qgc2hvdyBjbGVhciBpc3N1ZS4KCgoqKioKCgoK