#=========================================================
There were 20 warnings (use warnings() to see them)
# PREAMBLE
#=========================================================
# load the plotting library
suppressMessages(library(ggplot2))
library(gridExtra)
library(tikzDevice)
theme_set(theme_bw())
options(scipen=999) # turn-off scientific notation like 1e+48
# size of point for scatterplots
POINT_SIZE = 0.5
#POINT_SIZE = 1
# timeout
TIMEOUT = params$timeout
TIMEOUT_VAL = 1.05 * TIMEOUT
TIME_MIN = 0.01 # seconds
# FUNCTIONS
read_file <- function(file) {
filename = paste0(file)
df <- read.csv2(filename,
header=TRUE,
sep=";",
dec=",",
comment.char="",
strip.white=TRUE,
stringsAsFactors=FALSE)
return(df)
}
plot_scatter_log <- function(df, xlab, ylab, xstring=xlab, ystring=ylab) {
pscat <- ggplot(df, aes_string(x=xlab, y=ylab)) +
geom_point(size=POINT_SIZE) +
geom_abline(size=0.1) +
geom_vline(size=0.1, xintercept=TIMEOUT_VAL, linetype="dashed") +
geom_hline(size=0.1, yintercept=TIMEOUT_VAL, linetype="dashed") +
scale_x_log10() +
scale_y_log10() +
theme(axis.text.y = element_text(angle = 90, hjust = 0.5)) +
#coord_fixed(xlim = c(TIME_MIN, TIMEOUT_VAL), ylim = c(0.1, TIMEOUT_VAL)) +
coord_fixed(xlim = c(TIME_MIN, TIMEOUT_VAL), ylim = c(TIME_MIN, TIMEOUT_VAL)) +
labs(
#title="Title",
#subtitle="Subtitle",
x=xstring,
y=ystring)
return(pscat)
}
make_tikz <- function(file, picture, width=2.5, height=2.5) {
font_size <- 1
tikz(file=file, onefile=T, width=width, height=height)
plot(picture)
garbage <- dev.off()
}
df <- read_file(params$file_cmp)
######################### SANITIZE ###############################
tools.times <- c("re2g", "cad", "grep", "srm", "dot.net")
tools.matches <- c("re2g.matches", "cad.matches", "grep.matches", "srm.matches", "dot.net.matches")
# change the type of columns other than the name
for (i in tools.times) {
df[,i] <- sub(",", ".", df[,i])
suppressWarnings(df[,i] <- as.numeric(df[,i]))
}
for (i in tools.matches) {
suppressWarnings(df[,i] <- as.integer(df[,i]))
}
# get rid of extremal values
df[tools.times][is.na(df[tools.times])] <- TIMEOUT_VAL
#df[is.na(df)] <- TIMEOUT_VAL
#df[df == 0.00] <- TIME_MIN
df[,tools.times][df[,tools.times] == 0] <- TIME_MIN
# clean the data
#df_new <- df[df$Lines != "ERROR WHILE CONVERTING TO DCA.",]
#print(paste0("Removing ", nrow(df) - nrow(df_new), " lines due to converting to DCA error"))
#df <- df_new
############################## COUNTING TIMEOUTS #######################
timeouts.re2 <- nrow(df[df$re2g == TIMEOUT_VAL,])
timeouts.ca <- nrow(df[df$cad == TIMEOUT_VAL,])
timeouts.grep <- nrow(df[df$grep == TIMEOUT_VAL,])
timeouts.srm <- nrow(df[df$srm == TIMEOUT_VAL,])
timeouts.dot.net <- nrow(df[df$dot.net == TIMEOUT_VAL,])
timeouts.re2.and.ca <- nrow(df[df$cad == TIMEOUT_VAL & df$re2g == TIMEOUT_VAL,])
These are results of the experiments for Counting Set Automata:
| File |
results-10-05-2020/table-ALL.csv |
| Timeout |
300 s |
| Benchmarks |
4315 |
| Timeouts CA |
0 |
| Timeouts RE2 |
25 |
| Timeouts SRM |
25 |
| Timeouts grep |
239 |
| Timeouts .NET |
42 |
df
Sanity checks
df$inconsistent <- df$re2g.matches != df$grep.matches | df$re2g.matches != df$srm.matches | df$re2g.matches != df$dot.net.matches | df$re2g.matches != df$cad.matches
df$grep.re2.mismatch <- !is.na(df$re2g.matches) & !is.na(df$grep.matches) & df$re2g.matches != df$grep.matches
df_grep_re2_mismatch <- df[df$grep.re2.mismatch,]
df$re2.ca.mismatch <- !is.na(df$re2g.matches) & !is.na(df$cad.matches) & df$re2g.matches != df$cad.matches
df_re2_ca_mismatch <- df[df$re2.ca.mismatch,]
| grep and RE2 mismatched |
1110 |
| CA and RE2 mismatched |
103 |
RE2 and CA mismatches
df_re2_ca_mismatch
Scatter Plots
plot.and.tikz <- function(df, xlab, ylab, xstring=xlab, ystring=ylab) {
pic <- plot_scatter_log(df, xlab, ylab, xstring, ystring)
make_tikz(paste0("figs/", xlab, "-vs-", ylab, ".tikz"), pic, width=4, height=4)
pic
}
plot1 <- plot.and.tikz(df, "re2g", "cad", xstring="RE2 [s]", ystring="CA [s]")
plot2 <- plot.and.tikz(df, "grep", "cad", xstring="grep [s]", ystring="CA [s]")
plot3 <- plot.and.tikz(df, "srm", "cad", xstring="SRM [s]", ystring="CA [s]")
plot4 <- plot.and.tikz(df, "dot.net", "cad", xstring=".NET [s]", ystring="CA [s]")
plot5 <- plot.and.tikz(df, "srm", "re2g")
plot6 <- plot.and.tikz(df, "grep", "re2g")
plot7 <- plot.and.tikz(df, "dot.net", "re2g")
plot8 <- plot.and.tikz(df, "srm", "grep")
plot9 <- plot.and.tikz(df, "dot.net", "grep")
plot10 <- plot.and.tikz(df, "dot.net", "srm")
grid.arrange(plot1, plot2, ncol = 2)

grid.arrange(plot3, plot4, ncol = 2)

grid.arrange(plot5, plot6, ncol = 2)

grid.arrange(plot7, plot8, ncol = 2)

grid.arrange(plot9, plot10, ncol = 2)

Histograms
hist1 <- ggplot(df, aes(x=re2g)) +
geom_histogram(color="blue", fill="lightblue") +
scale_y_log10()
hist2 <- ggplot(df, aes(x=cad)) +
geom_histogram(color="blue", fill="lightblue") +
scale_y_log10()
hist3 <- ggplot(df, aes(x=srm)) +
geom_histogram(color="blue", fill="lightblue") +
scale_y_log10()
hist4 <- ggplot(df, aes(x=grep)) +
geom_histogram(color="blue", fill="lightblue") +
scale_y_log10()
hist5 <- ggplot(df, aes(x=dot.net)) +
geom_histogram(color="blue", fill="lightblue") +
scale_y_log10()
grid.arrange(hist1, hist2, ncol = 2)

grid.arrange(hist3, hist4, ncol = 2)

grid.arrange(hist5, ncol = 2)

NA
NA
Finding winners
df$min <-pmin(df$grep, df$srm, df$re2g, df$dot.net, df$cad)
df$enemy.min <- pmin(df$grep, df$srm, df$re2g, df$dot.net)
winners.grep <- nrow(df[df$min == df$grep,])
winners.re2 <- nrow(df[df$min == df$re2g,])
winners.ca <- nrow(df[df$min == df$cad,])
winners.srm <- nrow(df[df$min == df$srm,])
winners.dot.net <- nrow(df[df$min == df$dot.net,])
| CA |
32 |
| RE2 |
3759 |
| SRM |
7 |
| grep |
1736 |
| .NET |
64 |
plot.and.tikz(df, "enemy.min", "cad", xstring="best enemy", ystring="CA [s]")

How much we are better than RE2
df$re2.vs.ca <- df$re2g / df$cad
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls
5: In readChar(file, size, TRUE) : truncating string with embedded nuls
6: In readChar(file, size, TRUE) : truncating string with embedded nuls
7: In readChar(file, size, TRUE) : truncating string with embedded nuls
8: In readChar(file, size, TRUE) : truncating string with embedded nuls
9: In readChar(file, size, TRUE) : truncating string with embedded nuls
10: In readChar(file, size, TRUE) : truncating string with embedded nuls
df_sorted <- df[order(df$re2.vs.ca, decreasing=TRUE),]
df_sorted[,c("src", "pattern", "file", "re2g", "cad", "re2.vs.ca")]
Experiments with increasing counter value
big <- read_file(params$file_big)
big$re2g <- sub(",", ".", big$re2g)
big$re2g <- as.numeric(big$re2g)
NAs introduced by coercion
big
together <- big[, c("Counter", "re2g")]
names(together)[2] <- "time"
together$approach <- "re2g"
tmp <- big[, c("Counter", "ca")]
names(tmp)[2] <- "time"
tmp$approach <- "ca"
together <- rbind(together, tmp)
big_plot <- ggplot(data=together, aes(x=Counter, y=time, colour=approach)) +
geom_line() +
xlim(NA,1250) +
theme(legend.position = c(.05, .95),
legend.justification = c("left", "top"),
#legend.box.background = element_rect(color="black", size=0.5),
legend.box.just = "right",
legend.margin = margin(1, 1, 1, 1),
legend.title = element_blank()) +
labs(
#title="Title",
#subtitle="Subtitle",
x="$k$",
y="time [s]")
# geom_line(data = big, aes(x = Counter, y = re2g), color = "red") +
# geom_line(data = big, aes(x = Counter, y = ca), color = "blue") +
# xlab('counter value') +
# ylab('time [s]')
make_tikz(paste0("figs/big_plot.tikz"), big_plot, width=2.7, height=2.7)
plot(big_plot)

# Information about DCAs
df_dcas = read.csv2(params$file_dca,
header=TRUE,
sep="\t",
dec=".",
comment.char="",
quote="",
strip.white=TRUE,
stringsAsFactors=FALSE)
# sanitize
df_dcas$timeouts.classical[is.na(df_dcas$timeouts.classical)] <- 0
#df_dcas
tms.classical <- df_dcas[df_dcas$timeouts.classical == 1,]
compute_timeouts <- function(df, col) {
tmp <- df[df[, col] == TIMEOUT_VAL,]
tmp
}
LS0tCnRpdGxlOiAiQ250LVNldC1NYXRhIEFuYWx5c2lzIgpwYXJhbXM6CiAgI2ZpbGVfY21wOiBkYXRhL3Jlc3VsdHMtMjMtMDQtMjAyMC5jc3YKICAjZmlsZV9jbXA6IHJlc3VsdHMtMDUtMDUtMjAyMC9iZXR3ZWVuL3Jlc3VsdHMuY3N2CiAgI2ZpbGVfY21wOiByZXN1bHRzLTA5LTA1LTIwMjAvYmV0d2Vlbi9SRVNVTFRTLUFMTC1iZXR3ZWVuLmNzdgogIGZpbGVfY21wOiByZXN1bHRzLTEwLTA1LTIwMjAvdGFibGUtQUxMLmNzdgogIGZpbGVfYmlnOiByZXN1bHRzLTA1LTA1LTIwMjAvdGFibGUtYmlnLTI1MDM2MTAyLmNzdgogIGZpbGVfZGNhOiBEQ0FzL3Jlc3VsdHMtdHJhbnNsYXRpb24udHN2CiAgdGltZW91dDogMzAwICMgc2Vjb25kcwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCi0tLQoKYGBge3J9CiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyBQUkVBTUJMRQojPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojIGxvYWQgdGhlIHBsb3R0aW5nIGxpYnJhcnkKc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGdncGxvdDIpKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeSh0aWt6RGV2aWNlKQoKCnRoZW1lX3NldCh0aGVtZV9idygpKQoKb3B0aW9ucyhzY2lwZW49OTk5KSAgIyB0dXJuLW9mZiBzY2llbnRpZmljIG5vdGF0aW9uIGxpa2UgMWUrNDgKCiMgc2l6ZSBvZiBwb2ludCBmb3Igc2NhdHRlcnBsb3RzClBPSU5UX1NJWkUgPSAwLjUKI1BPSU5UX1NJWkUgPSAxCgojIHRpbWVvdXQKVElNRU9VVCA9IHBhcmFtcyR0aW1lb3V0ClRJTUVPVVRfVkFMID0gMS4wNSAqIFRJTUVPVVQKClRJTUVfTUlOID0gMC4wMSAjIHNlY29uZHMKCiMgRlVOQ1RJT05TCnJlYWRfZmlsZSA8LSBmdW5jdGlvbihmaWxlKSB7CiAgZmlsZW5hbWUgPSBwYXN0ZTAoZmlsZSkKICBkZiA8LSByZWFkLmNzdjIoZmlsZW5hbWUsCiAgICAgICAgICAgICAgICAgIGhlYWRlcj1UUlVFLAogICAgICAgICAgICAgICAgICBzZXA9IjsiLAogICAgICAgICAgICAgICAgICBkZWM9IiwiLAogICAgICAgICAgICAgICAgICBjb21tZW50LmNoYXI9IiIsCiAgICAgICAgICAgICAgICAgIHN0cmlwLndoaXRlPVRSVUUsCiAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpCiAgCiAgCiAgcmV0dXJuKGRmKQp9CgpwbG90X3NjYXR0ZXJfbG9nIDwtIGZ1bmN0aW9uKGRmLCB4bGFiLCB5bGFiLCB4c3RyaW5nPXhsYWIsIHlzdHJpbmc9eWxhYikgewogIHBzY2F0IDwtIGdncGxvdChkZiwgYWVzX3N0cmluZyh4PXhsYWIsIHk9eWxhYikpICsKICAgIGdlb21fcG9pbnQoc2l6ZT1QT0lOVF9TSVpFKSArCiAgICBnZW9tX2FibGluZShzaXplPTAuMSkgKwogICAgZ2VvbV92bGluZShzaXplPTAuMSwgeGludGVyY2VwdD1USU1FT1VUX1ZBTCwgbGluZXR5cGU9ImRhc2hlZCIpICsKICAgIGdlb21faGxpbmUoc2l6ZT0wLjEsIHlpbnRlcmNlcHQ9VElNRU9VVF9WQUwsIGxpbmV0eXBlPSJkYXNoZWQiKSArCiAgICBzY2FsZV94X2xvZzEwKCkgKwogICAgc2NhbGVfeV9sb2cxMCgpICsKICAgIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMC41KSkgKwogICAgI2Nvb3JkX2ZpeGVkKHhsaW0gPSBjKFRJTUVfTUlOLCBUSU1FT1VUX1ZBTCksIHlsaW0gPSBjKDAuMSwgVElNRU9VVF9WQUwpKSArCiAgICBjb29yZF9maXhlZCh4bGltID0gYyhUSU1FX01JTiwgVElNRU9VVF9WQUwpLCB5bGltID0gYyhUSU1FX01JTiwgVElNRU9VVF9WQUwpKSArCgogICAgbGFicygKICAgICAgI3RpdGxlPSJUaXRsZSIsCiAgICAgICNzdWJ0aXRsZT0iU3VidGl0bGUiLAogICAgICB4PXhzdHJpbmcsCiAgICAgIHk9eXN0cmluZykKICByZXR1cm4ocHNjYXQpCn0KCm1ha2VfdGlreiA8LSBmdW5jdGlvbihmaWxlLCBwaWN0dXJlLCB3aWR0aD0yLjUsIGhlaWdodD0yLjUpIHsKICBmb250X3NpemUgPC0gMQogIHRpa3ooZmlsZT1maWxlLCBvbmVmaWxlPVQsIHdpZHRoPXdpZHRoLCBoZWlnaHQ9aGVpZ2h0KQogIHBsb3QocGljdHVyZSkKICBnYXJiYWdlIDwtIGRldi5vZmYoKQp9CmBgYAoKYGBge3J9CmRmIDwtIHJlYWRfZmlsZShwYXJhbXMkZmlsZV9jbXApCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFNBTklUSVpFICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKdG9vbHMudGltZXMgPC0gYygicmUyZyIsICJjYWQiLCAiZ3JlcCIsICJzcm0iLCAiZG90Lm5ldCIpCnRvb2xzLm1hdGNoZXMgPC0gYygicmUyZy5tYXRjaGVzIiwgImNhZC5tYXRjaGVzIiwgImdyZXAubWF0Y2hlcyIsICJzcm0ubWF0Y2hlcyIsICJkb3QubmV0Lm1hdGNoZXMiKQoKIyBjaGFuZ2UgdGhlIHR5cGUgb2YgY29sdW1ucyBvdGhlciB0aGFuIHRoZSBuYW1lCmZvciAoaSBpbiB0b29scy50aW1lcykgewogIGRmWyxpXSA8LSBzdWIoIiwiLCAiLiIsIGRmWyxpXSkKICBzdXBwcmVzc1dhcm5pbmdzKGRmWyxpXSA8LSBhcy5udW1lcmljKGRmWyxpXSkpCn0KCmZvciAoaSBpbiB0b29scy5tYXRjaGVzKSB7CiAgc3VwcHJlc3NXYXJuaW5ncyhkZlssaV0gPC0gYXMuaW50ZWdlcihkZlssaV0pKQp9CgojIGdldCByaWQgb2YgZXh0cmVtYWwgdmFsdWVzCmRmW3Rvb2xzLnRpbWVzXVtpcy5uYShkZlt0b29scy50aW1lc10pXSA8LSBUSU1FT1VUX1ZBTAojZGZbaXMubmEoZGYpXSA8LSBUSU1FT1VUX1ZBTAojZGZbZGYgPT0gMC4wMF0gPC0gVElNRV9NSU4KZGZbLHRvb2xzLnRpbWVzXVtkZlssdG9vbHMudGltZXNdID09IDBdIDwtIFRJTUVfTUlOCgojIGNsZWFuIHRoZSBkYXRhCiNkZl9uZXcgPC0gZGZbZGYkTGluZXMgIT0gIkVSUk9SIFdISUxFIENPTlZFUlRJTkcgVE8gRENBLiIsXQojcHJpbnQocGFzdGUwKCJSZW1vdmluZyAiLCBucm93KGRmKSAtIG5yb3coZGZfbmV3KSwgIiBsaW5lcyBkdWUgdG8gY29udmVydGluZyB0byBEQ0EgZXJyb3IiKSkKI2RmIDwtIGRmX25ldwoKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ09VTlRJTkcgVElNRU9VVFMgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKdGltZW91dHMucmUyIDwtIG5yb3coZGZbZGYkcmUyZyA9PSBUSU1FT1VUX1ZBTCxdKQp0aW1lb3V0cy5jYSA8LSBucm93KGRmW2RmJGNhZCA9PSBUSU1FT1VUX1ZBTCxdKQp0aW1lb3V0cy5ncmVwIDwtIG5yb3coZGZbZGYkZ3JlcCA9PSBUSU1FT1VUX1ZBTCxdKQp0aW1lb3V0cy5zcm0gPC0gbnJvdyhkZltkZiRzcm0gPT0gVElNRU9VVF9WQUwsXSkKdGltZW91dHMuZG90Lm5ldCA8LSBucm93KGRmW2RmJGRvdC5uZXQgPT0gVElNRU9VVF9WQUwsXSkKdGltZW91dHMucmUyLmFuZC5jYSA8LSBucm93KGRmW2RmJGNhZCA9PSBUSU1FT1VUX1ZBTCAmIGRmJHJlMmcgPT0gVElNRU9VVF9WQUwsXSkKYGBgCgpUaGVzZSBhcmUgcmVzdWx0cyBvZiB0aGUgZXhwZXJpbWVudHMgZm9yIENvdW50aW5nIFNldCBBdXRvbWF0YToKCnwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfAp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tOnwKfCAqKkZpbGUqKiAgICAgICAgICAgIHwgYHIgcGFyYW1zJGZpbGVfY21wYCB8CnwgKipUaW1lb3V0KiogICAgICAgICB8IGByIFRJTUVPVVRgIHMgICAgICAgfAp8ICoqQmVuY2htYXJrcyoqICAgICAgfCBgciBucm93KGRmKWAgICAgICAgIHwKfCAqKlRpbWVvdXRzIENBKiogICAgIHwgYHIgdGltZW91dHMuY2FgICAgICB8CnwgKipUaW1lb3V0cyBSRTIqKiAgICB8IGByIHRpbWVvdXRzLnJlMmAgICAgfAp8ICoqVGltZW91dHMgU1JNKiogICAgfCBgciB0aW1lb3V0cy5zcm1gICAgIHwgCnwgKipUaW1lb3V0cyBncmVwKiogICAgfCBgciB0aW1lb3V0cy5ncmVwYCAgfAp8ICoqVGltZW91dHMgLk5FVCoqICAgIHwgYHIgdGltZW91dHMuZG90Lm5ldGAgIHwKCgpgYGB7cn0KZGYKYGBgCgojIFNhbml0eSBjaGVja3MKCmBgYHtyfQpkZiRpbmNvbnNpc3RlbnQgPC0gZGYkcmUyZy5tYXRjaGVzICE9IGRmJGdyZXAubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRzcm0ubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRkb3QubmV0Lm1hdGNoZXMgfCBkZiRyZTJnLm1hdGNoZXMgIT0gZGYkY2FkLm1hdGNoZXMKCmRmJGdyZXAucmUyLm1pc21hdGNoIDwtICFpcy5uYShkZiRyZTJnLm1hdGNoZXMpICYgIWlzLm5hKGRmJGdyZXAubWF0Y2hlcykgJiBkZiRyZTJnLm1hdGNoZXMgIT0gZGYkZ3JlcC5tYXRjaGVzCmRmX2dyZXBfcmUyX21pc21hdGNoIDwtIGRmW2RmJGdyZXAucmUyLm1pc21hdGNoLF0KCmRmJHJlMi5jYS5taXNtYXRjaCA8LSAhaXMubmEoZGYkcmUyZy5tYXRjaGVzKSAmICFpcy5uYShkZiRjYWQubWF0Y2hlcykgJiBkZiRyZTJnLm1hdGNoZXMgIT0gZGYkY2FkLm1hdGNoZXMKZGZfcmUyX2NhX21pc21hdGNoIDwtIGRmW2RmJHJlMi5jYS5taXNtYXRjaCxdCgpgYGAKCnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fAp8ICoqZ3JlcCBhbmQgUkUyIG1pc21hdGNoZWQqKiB8IGByIG5yb3coZGZfZ3JlcF9yZTJfbWlzbWF0Y2gpYCB8CnwgKipDQSBhbmQgUkUyIG1pc21hdGNoZWQqKiAgIHwgYHIgbnJvdyhkZl9yZTJfY2FfbWlzbWF0Y2gpYCAgIHwKCiMjIFJFMiBhbmQgQ0EgbWlzbWF0Y2hlcwpgYGB7cn0KZGZfcmUyX2NhX21pc21hdGNoCmBgYAoKCgojIFNjYXR0ZXIgUGxvdHMKCmBgYHtyfQoKcGxvdC5hbmQudGlreiA8LSBmdW5jdGlvbihkZiwgeGxhYiwgeWxhYiwgeHN0cmluZz14bGFiLCB5c3RyaW5nPXlsYWIpIHsKICBwaWMgPC0gcGxvdF9zY2F0dGVyX2xvZyhkZiwgeGxhYiwgeWxhYiwgeHN0cmluZywgeXN0cmluZykKICBtYWtlX3Rpa3oocGFzdGUwKCJmaWdzLyIsIHhsYWIsICItdnMtIiwgeWxhYiwgIi50aWt6IiksIHBpYywgd2lkdGg9NCwgaGVpZ2h0PTQpCiAgcGljCn0KCnBsb3QxIDwtIHBsb3QuYW5kLnRpa3ooZGYsICJyZTJnIiwgImNhZCIsIHhzdHJpbmc9IlJFMiBbc10iLCB5c3RyaW5nPSJDQSBbc10iKQpwbG90MiA8LSBwbG90LmFuZC50aWt6KGRmLCAiZ3JlcCIsICJjYWQiLCB4c3RyaW5nPSJncmVwIFtzXSIsIHlzdHJpbmc9IkNBIFtzXSIpCnBsb3QzIDwtIHBsb3QuYW5kLnRpa3ooZGYsICJzcm0iLCAiY2FkIiwgeHN0cmluZz0iU1JNIFtzXSIsIHlzdHJpbmc9IkNBIFtzXSIpCnBsb3Q0IDwtIHBsb3QuYW5kLnRpa3ooZGYsICJkb3QubmV0IiwgImNhZCIsIHhzdHJpbmc9Ii5ORVQgW3NdIiwgeXN0cmluZz0iQ0EgW3NdIikKcGxvdDUgPC0gcGxvdC5hbmQudGlreihkZiwgInNybSIsICJyZTJnIikKcGxvdDYgPC0gcGxvdC5hbmQudGlreihkZiwgImdyZXAiLCAicmUyZyIpCnBsb3Q3IDwtIHBsb3QuYW5kLnRpa3ooZGYsICJkb3QubmV0IiwgInJlMmciKQpwbG90OCA8LSBwbG90LmFuZC50aWt6KGRmLCAic3JtIiwgImdyZXAiKQpwbG90OSA8LSBwbG90LmFuZC50aWt6KGRmLCAiZG90Lm5ldCIsICJncmVwIikKcGxvdDEwIDwtIHBsb3QuYW5kLnRpa3ooZGYsICJkb3QubmV0IiwgInNybSIpCgoKCmdyaWQuYXJyYW5nZShwbG90MSwgcGxvdDIsIG5jb2wgPSAyKQpncmlkLmFycmFuZ2UocGxvdDMsIHBsb3Q0LCBuY29sID0gMikKZ3JpZC5hcnJhbmdlKHBsb3Q1LCBwbG90NiwgbmNvbCA9IDIpCmdyaWQuYXJyYW5nZShwbG90NywgcGxvdDgsIG5jb2wgPSAyKQpncmlkLmFycmFuZ2UocGxvdDksIHBsb3QxMCwgbmNvbCA9IDIpCmBgYAoKCiMgSGlzdG9ncmFtcwoKYGBge3J9Cmhpc3QxIDwtIGdncGxvdChkZiwgYWVzKHg9cmUyZykpICsKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmx1ZSIsIGZpbGw9ImxpZ2h0Ymx1ZSIpICsKICBzY2FsZV95X2xvZzEwKCkKCmhpc3QyIDwtIGdncGxvdChkZiwgYWVzKHg9Y2FkKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmx1ZSIsIGZpbGw9ImxpZ2h0Ymx1ZSIpICsKICBzY2FsZV95X2xvZzEwKCkKCmhpc3QzIDwtIGdncGxvdChkZiwgYWVzKHg9c3JtKSkgKyAKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmx1ZSIsIGZpbGw9ImxpZ2h0Ymx1ZSIpICsKICBzY2FsZV95X2xvZzEwKCkKCmhpc3Q0IDwtIGdncGxvdChkZiwgYWVzKHg9Z3JlcCkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsdWUiLCBmaWxsPSJsaWdodGJsdWUiKSArCiAgc2NhbGVfeV9sb2cxMCgpCgpoaXN0NSA8LSBnZ3Bsb3QoZGYsIGFlcyh4PWRvdC5uZXQpKSArIAogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJibHVlIiwgZmlsbD0ibGlnaHRibHVlIikgKwogIHNjYWxlX3lfbG9nMTAoKQoKZ3JpZC5hcnJhbmdlKGhpc3QxLCBoaXN0MiwgbmNvbCA9IDIpCmdyaWQuYXJyYW5nZShoaXN0MywgaGlzdDQsIG5jb2wgPSAyKQpncmlkLmFycmFuZ2UoaGlzdDUsIG5jb2wgPSAyKQoKCmBgYAoKIyBGaW5kaW5nIHdpbm5lcnMKCmBgYHtyfQpkZiRtaW4gPC1wbWluKGRmJGdyZXAsIGRmJHNybSwgZGYkcmUyZywgZGYkZG90Lm5ldCwgZGYkY2FkKQpkZiRlbmVteS5taW4gPC0gcG1pbihkZiRncmVwLCBkZiRzcm0sIGRmJHJlMmcsIGRmJGRvdC5uZXQpCgp3aW5uZXJzLmdyZXAgPC0gbnJvdyhkZltkZiRtaW4gPT0gZGYkZ3JlcCxdKQp3aW5uZXJzLnJlMiA8LSBucm93KGRmW2RmJG1pbiA9PSBkZiRyZTJnLF0pCndpbm5lcnMuY2EgPC0gbnJvdyhkZltkZiRtaW4gPT0gZGYkY2FkLF0pCndpbm5lcnMuc3JtIDwtIG5yb3coZGZbZGYkbWluID09IGRmJHNybSxdKQp3aW5uZXJzLmRvdC5uZXQgPC0gbnJvdyhkZltkZiRtaW4gPT0gZGYkZG90Lm5ldCxdKQpgYGAKCnwgKipXaW5uZXIqKiAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfAp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tOnwKfCAqKkNBKiogICAgIHwgYHIgd2lubmVycy5jYWAgICAgIHwKfCAqKlJFMioqICAgIHwgYHIgd2lubmVycy5yZTJgICAgIHwKfCAqKlNSTSoqICAgIHwgYHIgd2lubmVycy5zcm1gICAgIHwgCnwgKipncmVwKiogICAgfCBgciB3aW5uZXJzLmdyZXBgICB8CnwgKiouTkVUKiogICAgfCBgciB3aW5uZXJzLmRvdC5uZXRgICB8CgpgYGB7cn0KcGxvdC5hbmQudGlreihkZiwgImVuZW15Lm1pbiIsICJjYWQiLCB4c3RyaW5nPSJiZXN0IGVuZW15IiwgeXN0cmluZz0iQ0EgW3NdIikKYGBgCgojIEhvdyBtdWNoIHdlIGFyZSBiZXR0ZXIgdGhhbiBSRTIKCmBgYHtyfQpkZiRyZTIudnMuY2EgPC0gZGYkcmUyZyAvIGRmJGNhZApkZl9zb3J0ZWQgPC0gZGZbb3JkZXIoZGYkcmUyLnZzLmNhLCBkZWNyZWFzaW5nPVRSVUUpLF0KCmRmX3NvcnRlZFssYygic3JjIiwgInBhdHRlcm4iLCAiZmlsZSIsICJyZTJnIiwgImNhZCIsICJyZTIudnMuY2EiKV0KYGBgCgoKIyBFeHBlcmltZW50cyB3aXRoIGluY3JlYXNpbmcgY291bnRlciB2YWx1ZQoKYGBge3J9CmJpZyA8LSByZWFkX2ZpbGUocGFyYW1zJGZpbGVfYmlnKQpiaWckcmUyZyA8LSBzdWIoIiwiLCAiLiIsIGJpZyRyZTJnKQpiaWckcmUyZyA8LSBhcy5udW1lcmljKGJpZyRyZTJnKQoKYmlnCmBgYAoKCmBgYHtyfQoKdG9nZXRoZXIgPC0gYmlnWywgYygiQ291bnRlciIsICJyZTJnIildCm5hbWVzKHRvZ2V0aGVyKVsyXSA8LSAidGltZSIKdG9nZXRoZXIkYXBwcm9hY2ggPC0gInJlMmciCgp0bXAgPC0gYmlnWywgYygiQ291bnRlciIsICJjYSIpXQpuYW1lcyh0bXApWzJdIDwtICJ0aW1lIgp0bXAkYXBwcm9hY2ggPC0gImNhIgoKdG9nZXRoZXIgPC0gcmJpbmQodG9nZXRoZXIsIHRtcCkKCmJpZ19wbG90IDwtIGdncGxvdChkYXRhPXRvZ2V0aGVyLCBhZXMoeD1Db3VudGVyLCB5PXRpbWUsIGNvbG91cj1hcHByb2FjaCkpICsKICBnZW9tX2xpbmUoKSArCiAgeGxpbShOQSwxMjUwKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gYyguMDUsIC45NSksCiAgICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKCJsZWZ0IiwgInRvcCIpLAogICAgICAgICNsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3I9ImJsYWNrIiwgc2l6ZT0wLjUpLAogICAgICAgIGxlZ2VuZC5ib3guanVzdCA9ICJyaWdodCIsCiAgICAgICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbigxLCAxLCAxLCAxKSwKICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsKICBsYWJzKAogICAgICAjdGl0bGU9IlRpdGxlIiwKICAgICAgI3N1YnRpdGxlPSJTdWJ0aXRsZSIsCiAgICAgIHg9IiRrJCIsCiAgICAgIHk9InRpbWUgW3NdIikKICAgICAgICAKCiAgIyBnZW9tX2xpbmUoZGF0YSA9IGJpZywgYWVzKHggPSBDb3VudGVyLCB5ID0gcmUyZyksIGNvbG9yID0gInJlZCIpICsKICAjIGdlb21fbGluZShkYXRhID0gYmlnLCBhZXMoeCA9IENvdW50ZXIsIHkgPSBjYSksIGNvbG9yID0gImJsdWUiKSArCiAgIyB4bGFiKCdjb3VudGVyIHZhbHVlJykgKwogICMgeWxhYigndGltZSBbc10nKQoKbWFrZV90aWt6KHBhc3RlMCgiZmlncy9iaWdfcGxvdC50aWt6IiksIGJpZ19wbG90LCB3aWR0aD0yLjcsIGhlaWdodD0yLjcpCgpwbG90KGJpZ19wbG90KQpgYGAKCgpgYGB7cn0KIyBJbmZvcm1hdGlvbiBhYm91dCBEQ0FzCgpkZl9kY2FzID0gcmVhZC5jc3YyKHBhcmFtcyRmaWxlX2RjYSwKICAgICAgICAgICAgICAgICAgaGVhZGVyPVRSVUUsCiAgICAgICAgICAgICAgICAgIHNlcD0iXHQiLAogICAgICAgICAgICAgICAgICBkZWM9Ii4iLAogICAgICAgICAgICAgICAgICBjb21tZW50LmNoYXI9IiIsCiAgICAgICAgICAgICAgICAgIHF1b3RlPSIiLAogICAgICAgICAgICAgICAgICBzdHJpcC53aGl0ZT1UUlVFLAogICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQoKIyBzYW5pdGl6ZQpkZl9kY2FzJHRpbWVvdXRzLmNsYXNzaWNhbFtpcy5uYShkZl9kY2FzJHRpbWVvdXRzLmNsYXNzaWNhbCldIDwtIDAKCiNkZl9kY2FzCmBgYAoKYGBge3J9CnRtcy5jbGFzc2ljYWwgPC0gZGZfZGNhc1tkZl9kY2FzJHRpbWVvdXRzLmNsYXNzaWNhbCA9PSAxLF0KYGBgCgoKCmBgYHtyfQpjb21wdXRlX3RpbWVvdXRzIDwtIGZ1bmN0aW9uKGRmLCBjb2wpIHsKICB0bXAgPC0gZGZbZGZbLCBjb2xdID09IFRJTUVPVVRfVkFMLF0KICB0bXAKfQoKYGBgCgo=