#=========================================================
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
# 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

# saturate
#TIME_MIN = 0.01 # seconds
TIME_MIN = 0.1 # seconds

BIG_SIZE=3
SMALL_SIZE=2


# FUNCTIONS
read_file <- function(file) {
  filename = paste0(file)
  df <- read.csv2(filename,
                  header=TRUE,
                  sep=";",
                  dec=",",
                  comment.char="",
                  quote="\"",
                  strip.white=TRUE,
                  allowEscapes=FALSE,
                  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)) +
        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()
}

make_pdf <- function(file, picture, width=5, height=5) {
  pdf(file=file, onefile=T, width, height)
  plot(picture)
  garbage <- dev.off()
}
df <- read_file(params$file_cmp)

colnames(df)[colnames(df) == "dot.net"] <- "dotnet"
colnames(df)[names(df) == "dot.net.matches"] <- "dotnet.matches"

######################### SANITIZE ###############################
# clean the data
df_new <- df[!grepl("File not found", df$srm.matches),]
print(paste0("Removing ", nrow(df) - nrow(df_new), " lines due to generation of input text"))
[1] "Removing 3214 lines due to generation of input text"
df <- df_new

tools.times <- c("re2g", "cad", "grep", "srm", "dotnet")
tools.times <- c("re2g", "cad", "srm", "dotnet")
tools.matches <- c("re2g.matches", "cad.matches", "grep.matches", "srm.matches", "dotnet.matches")
tools.matches <- c("re2g.matches", "cad.matches", "srm.matches", "dotnet.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]))
}

df$src <- as.factor(df$src)

# 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] < TIME_MIN] <- 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.dotnet <- nrow(df[df$dotnet == TIMEOUT_VAL,])
timeouts.re2.and.ca <- nrow(df[df$cad == TIMEOUT_VAL & df$re2g == TIMEOUT_VAL,])

# | **Timeouts grep**    | `r timeouts.grep`  |

These are results of the experiments for Counting Set Automata:

File results-11-05-2020/table-ALL-ondra-processed.csv
Timeout 600 s
TIMEOUT_VAL 630 s
TIME_MIN 0.1
Benchmarks 1111
Timeouts CA 0
Timeouts RE2 3
Timeouts SRM 14
Timeouts .NET 7
df

Summary of benchmarks

df_benches <- data.frame(summary(df$src))
df_benches

Sanity checks

#df$inconsistent <- df$re2g.matches != df$grep.matches | df$re2g.matches != df$srm.matches | df$re2g.matches != df$dotnet.matches | df$re2g.matches != df$cad.matches

df$inconsistent <- df$re2g.matches != df$srm.matches | df$re2g.matches != df$dotnet.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** | `r nrow(df_grep_re2_mismatch)` |
CA and RE2 mismatched 11

RE2 and CA mismatches

df_re2_ca_mismatch

Scatter Plots


plot.and.tikz <- function(df, xlab, ylab, xstring=xlab, ystring=ylab, width=4, height=width) {
  pic <- plot_scatter_log(df, xlab, ylab, xstring, ystring)
  #make_tikz(paste0("figs/", xlab, "-vs-", ylab, ".tikz"), pic, width, height)
  make_pdf(paste0("figs/", xlab, "-vs-", ylab, ".pdf"), pic, width, height)
  pic
}

plot1 <- plot.and.tikz(df, "re2g", "cad", xstring="RE2 [s]", ystring="CA [s]", width=BIG_SIZE)
#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]", width=SMALL_SIZE)
plot4 <- plot.and.tikz(df, "dotnet", "cad", xstring=".NET [s]", ystring="CA [s]", width=SMALL_SIZE)
plot5 <- plot.and.tikz(df, "srm", "re2g")
#plot6 <- plot.and.tikz(df, "grep", "re2g")
plot7 <- plot.and.tikz(df, "dotnet", "re2g")
#plot8 <- plot.and.tikz(df, "srm", "grep")
#plot9 <- plot.and.tikz(df, "dotnet", "grep")
plot10 <- plot.and.tikz(df, "dotnet", "srm")



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

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

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


#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=dotnet)) + 
  geom_histogram(color="blue", fill="lightblue") +
  scale_y_log10()

grid.arrange(hist1, hist2, ncol = 2)

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

#grid.arrange(hist5, ncol = 2)

Finding winners

#df$min <-pmin(df$grep, df$srm, df$re2g, df$dotnet, df$cad)
#df$enemy.min <- pmin(df$grep, df$srm, df$re2g, df$dotnet)
df$min <-pmin(df$srm, df$re2g, df$dotnet, df$cad)
df$enemy.min <- pmin(df$srm, df$re2g, df$dotnet)

#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.dotnet <- nrow(df[df$min == df$dotnet,])

# | **grep**    | `r winners.grep`  |
Winner
CA 72
RE2 961
SRM 27
.NET 54
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
df_sorted <- df[order(df$re2.vs.ca, decreasing=TRUE),]

#df_sorted[,c("src", "pattern", "file", "re2g", "cad", "re2.vs.ca", "re2.ca.mismatch")]
df_sorted
NA

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 <- "RE2"

tmp <- big[, c("Counter", "cad")]
names(tmp)[2] <- "time"
tmp$approach <- "CA"
together <- rbind(together, tmp)

tmp <- big[, c("Counter", "srm")]
names(tmp)[2] <- "time"
tmp$approach <- "SRM"
together <- rbind(together, tmp)

tmp <- big[, c("Counter", "dot.net")]
names(tmp)[2] <- "time"
tmp$approach <- ".NET"
together <- rbind(together, tmp)

tmp <- big[, c("Counter", "grep")]
names(tmp)[2] <- "time"
tmp$approach <- "grep"
together <- rbind(together, tmp)

BIG_STEP=100

# remove too many points
together <- together[together$Counter %% BIG_STEP == 0,]

big_plot <- ggplot(data=together, aes(x=Counter, y=time, colour=approach)) +
  geom_line() +
  geom_point(aes(shape=approach)) +
  xlim(NA,1250) +
  ylim(NA,75) +
  geom_hline(size=0.1, yintercept=0, linetype="dashed") +

  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)
make_pdf(paste0("figs/big_plot.pdf"), big_plot, width=BIG_SIZE, height=BIG_SIZE)


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
#}
LS0tCnRpdGxlOiAiQ250LVNldC1NYXRhIEFuYWx5c2lzIgpwYXJhbXM6CiAgI2ZpbGVfY21wOiBkYXRhL3Jlc3VsdHMtMjMtMDQtMjAyMC5jc3YKICAjZmlsZV9jbXA6IHJlc3VsdHMtMDUtMDUtMjAyMC9iZXR3ZWVuL3Jlc3VsdHMuY3N2CiAgI2ZpbGVfY21wOiByZXN1bHRzLTA5LTA1LTIwMjAvYmV0d2Vlbi9SRVNVTFRTLUFMTC1iZXR3ZWVuLmNzdgogICNmaWxlX2NtcDogcmVzdWx0cy0xMC0wNS0yMDIwL3RhYmxlLUFMTC5jc3YKICBmaWxlX2NtcDogcmVzdWx0cy0xMS0wNS0yMDIwL3RhYmxlLUFMTC1vbmRyYS1wcm9jZXNzZWQuY3N2CiAgI2ZpbGVfYmlnOiByZXN1bHRzLTA1LTA1LTIwMjAvdGFibGUtYmlnLTI1MDM2MTAyLmNzdgogIGZpbGVfYmlnOiByZXN1bHRzLTExLTA1LTIwMjAvZ3JhcGgvdGFibGUtYmlnLTEwNjUyODk3MDQuY3N2CiAgZmlsZV9kY2E6IERDQXMvcmVzdWx0cy10cmFuc2xhdGlvbi50c3YKICB0aW1lb3V0OiA2MDAgIyBzZWNvbmRzCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKLS0tCgpgYGB7cn0KIz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIFBSRUFNQkxFCiM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiMgbG9hZCB0aGUgcGxvdHRpbmcgbGlicmFyeQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZ2dwbG90MikpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KHRpa3pEZXZpY2UpCgoKdGhlbWVfc2V0KHRoZW1lX2J3KCkpCgpvcHRpb25zKHNjaXBlbj05OTkpICAjIHR1cm4tb2ZmIHNjaWVudGlmaWMgbm90YXRpb24gbGlrZSAxZSs0OAoKIyBzaXplIG9mIHBvaW50IGZvciBzY2F0dGVycGxvdHMKUE9JTlRfU0laRSA9IDAuNQojUE9JTlRfU0laRSA9IDEKCiMgdGltZW91dApUSU1FT1VUID0gcGFyYW1zJHRpbWVvdXQKVElNRU9VVF9WQUwgPSAxLjA1ICogVElNRU9VVAoKIyBzYXR1cmF0ZQojVElNRV9NSU4gPSAwLjAxICMgc2Vjb25kcwpUSU1FX01JTiA9IDAuMSAjIHNlY29uZHMKCkJJR19TSVpFPTMKU01BTExfU0laRT0yCgoKIyBGVU5DVElPTlMKcmVhZF9maWxlIDwtIGZ1bmN0aW9uKGZpbGUpIHsKICBmaWxlbmFtZSA9IHBhc3RlMChmaWxlKQogIGRmIDwtIHJlYWQuY3N2MihmaWxlbmFtZSwKICAgICAgICAgICAgICAgICAgaGVhZGVyPVRSVUUsCiAgICAgICAgICAgICAgICAgIHNlcD0iOyIsCiAgICAgICAgICAgICAgICAgIGRlYz0iLCIsCiAgICAgICAgICAgICAgICAgIGNvbW1lbnQuY2hhcj0iIiwKICAgICAgICAgICAgICAgICAgcXVvdGU9IlwiIiwKICAgICAgICAgICAgICAgICAgc3RyaXAud2hpdGU9VFJVRSwKICAgICAgICAgICAgICAgICAgYWxsb3dFc2NhcGVzPUZBTFNFLAogICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzPUZBTFNFKQogIAogIAogIHJldHVybihkZikKfQoKcGxvdF9zY2F0dGVyX2xvZyA8LSBmdW5jdGlvbihkZiwgeGxhYiwgeWxhYiwgeHN0cmluZz14bGFiLCB5c3RyaW5nPXlsYWIpIHsKICBwc2NhdCA8LSBnZ3Bsb3QoZGYsIGFlc19zdHJpbmcoeD14bGFiLCB5PXlsYWIpKSArCiAgICBnZW9tX3BvaW50KHNpemU9UE9JTlRfU0laRSkgKwogICAgZ2VvbV9hYmxpbmUoc2l6ZT0wLjEpICsKICAgIGdlb21fdmxpbmUoc2l6ZT0wLjEsIHhpbnRlcmNlcHQ9VElNRU9VVF9WQUwsIGxpbmV0eXBlPSJkYXNoZWQiKSArCiAgICBnZW9tX2hsaW5lKHNpemU9MC4xLCB5aW50ZXJjZXB0PVRJTUVPVVRfVkFMLCBsaW5ldHlwZT0iZGFzaGVkIikgKwogICAgc2NhbGVfeF9sb2cxMCgpICsKICAgIHNjYWxlX3lfbG9nMTAoKSArCiAgICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDAuNSkpICsKICAgICNjb29yZF9maXhlZCh4bGltID0gYyhUSU1FX01JTiwgVElNRU9VVF9WQUwpLCB5bGltID0gYygwLjEsIFRJTUVPVVRfVkFMKSkgKwogICAgI2Nvb3JkX2ZpeGVkKHhsaW0gPSBjKFRJTUVfTUlOLCBUSU1FT1VUX1ZBTCksIHlsaW0gPSBjKFRJTUVfTUlOLCBUSU1FT1VUX1ZBTCkpICsKICAgICAgICBjb29yZF9maXhlZCh4bGltID0gYyhUSU1FX01JTiwgVElNRU9VVF9WQUwpLCB5bGltID0gYyhUSU1FX01JTiwgVElNRU9VVF9WQUwpKSArCgoKICAgIGxhYnMoCiAgICAgICN0aXRsZT0iVGl0bGUiLAogICAgICAjc3VidGl0bGU9IlN1YnRpdGxlIiwKICAgICAgeD14c3RyaW5nLAogICAgICB5PXlzdHJpbmcpCiAgcmV0dXJuKHBzY2F0KQp9CgptYWtlX3Rpa3ogPC0gZnVuY3Rpb24oZmlsZSwgcGljdHVyZSwgd2lkdGg9Mi41LCBoZWlnaHQ9Mi41KSB7CiAgZm9udF9zaXplIDwtIDEKICB0aWt6KGZpbGU9ZmlsZSwgb25lZmlsZT1ULCB3aWR0aD13aWR0aCwgaGVpZ2h0PWhlaWdodCkKICBwbG90KHBpY3R1cmUpCiAgZ2FyYmFnZSA8LSBkZXYub2ZmKCkKfQoKbWFrZV9wZGYgPC0gZnVuY3Rpb24oZmlsZSwgcGljdHVyZSwgd2lkdGg9NSwgaGVpZ2h0PTUpIHsKICBwZGYoZmlsZT1maWxlLCBvbmVmaWxlPVQsIHdpZHRoLCBoZWlnaHQpCiAgcGxvdChwaWN0dXJlKQogIGdhcmJhZ2UgPC0gZGV2Lm9mZigpCn0KYGBgCgpgYGB7cn0KZGYgPC0gcmVhZF9maWxlKHBhcmFtcyRmaWxlX2NtcCkKCmNvbG5hbWVzKGRmKVtjb2xuYW1lcyhkZikgPT0gImRvdC5uZXQiXSA8LSAiZG90bmV0Igpjb2xuYW1lcyhkZilbbmFtZXMoZGYpID09ICJkb3QubmV0Lm1hdGNoZXMiXSA8LSAiZG90bmV0Lm1hdGNoZXMiCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFNBTklUSVpFICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBjbGVhbiB0aGUgZGF0YQpkZl9uZXcgPC0gZGZbIWdyZXBsKCJGaWxlIG5vdCBmb3VuZCIsIGRmJHNybS5tYXRjaGVzKSxdCnByaW50KHBhc3RlMCgiUmVtb3ZpbmcgIiwgbnJvdyhkZikgLSBucm93KGRmX25ldyksICIgbGluZXMgZHVlIHRvIGdlbmVyYXRpb24gb2YgaW5wdXQgdGV4dCIpKQpkZiA8LSBkZl9uZXcKCnRvb2xzLnRpbWVzIDwtIGMoInJlMmciLCAiY2FkIiwgImdyZXAiLCAic3JtIiwgImRvdG5ldCIpCnRvb2xzLnRpbWVzIDwtIGMoInJlMmciLCAiY2FkIiwgInNybSIsICJkb3RuZXQiKQp0b29scy5tYXRjaGVzIDwtIGMoInJlMmcubWF0Y2hlcyIsICJjYWQubWF0Y2hlcyIsICJncmVwLm1hdGNoZXMiLCAic3JtLm1hdGNoZXMiLCAiZG90bmV0Lm1hdGNoZXMiKQp0b29scy5tYXRjaGVzIDwtIGMoInJlMmcubWF0Y2hlcyIsICJjYWQubWF0Y2hlcyIsICJzcm0ubWF0Y2hlcyIsICJkb3RuZXQubWF0Y2hlcyIpCgoKIyBjaGFuZ2UgdGhlIHR5cGUgb2YgY29sdW1ucyBvdGhlciB0aGFuIHRoZSBuYW1lCmZvciAoaSBpbiB0b29scy50aW1lcykgewogIGRmWyxpXSA8LSBzdWIoIiwiLCAiLiIsIGRmWyxpXSkKICBzdXBwcmVzc1dhcm5pbmdzKGRmWyxpXSA8LSBhcy5udW1lcmljKGRmWyxpXSkpCn0KCmZvciAoaSBpbiB0b29scy5tYXRjaGVzKSB7CiAgc3VwcHJlc3NXYXJuaW5ncyhkZlssaV0gPC0gYXMuaW50ZWdlcihkZlssaV0pKQp9CgpkZiRzcmMgPC0gYXMuZmFjdG9yKGRmJHNyYykKCiMgZ2V0IHJpZCBvZiBleHRyZW1hbCB2YWx1ZXMKZGZbdG9vbHMudGltZXNdW2lzLm5hKGRmW3Rvb2xzLnRpbWVzXSldIDwtIFRJTUVPVVRfVkFMCiNkZltpcy5uYShkZildIDwtIFRJTUVPVVRfVkFMCiNkZltkZiA9PSAwLjAwXSA8LSBUSU1FX01JTgpkZlssdG9vbHMudGltZXNdW2RmWyx0b29scy50aW1lc10gPCBUSU1FX01JTl0gPC0gVElNRV9NSU4KCgoKIyBjbGVhbiB0aGUgZGF0YQojZGZfbmV3IDwtIGRmW2RmJExpbmVzICE9ICJFUlJPUiBXSElMRSBDT05WRVJUSU5HIFRPIERDQS4iLF0KI3ByaW50KHBhc3RlMCgiUmVtb3ZpbmcgIiwgbnJvdyhkZikgLSBucm93KGRmX25ldyksICIgbGluZXMgZHVlIHRvIGNvbnZlcnRpbmcgdG8gRENBIGVycm9yIikpCiNkZiA8LSBkZl9uZXcKCgoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIENPVU5USU5HIFRJTUVPVVRTICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCnRpbWVvdXRzLnJlMiA8LSBucm93KGRmW2RmJHJlMmcgPT0gVElNRU9VVF9WQUwsXSkKdGltZW91dHMuY2EgPC0gbnJvdyhkZltkZiRjYWQgPT0gVElNRU9VVF9WQUwsXSkKI3RpbWVvdXRzLmdyZXAgPC0gbnJvdyhkZltkZiRncmVwID09IFRJTUVPVVRfVkFMLF0pCnRpbWVvdXRzLnNybSA8LSBucm93KGRmW2RmJHNybSA9PSBUSU1FT1VUX1ZBTCxdKQp0aW1lb3V0cy5kb3RuZXQgPC0gbnJvdyhkZltkZiRkb3RuZXQgPT0gVElNRU9VVF9WQUwsXSkKdGltZW91dHMucmUyLmFuZC5jYSA8LSBucm93KGRmW2RmJGNhZCA9PSBUSU1FT1VUX1ZBTCAmIGRmJHJlMmcgPT0gVElNRU9VVF9WQUwsXSkKCiMgfCAqKlRpbWVvdXRzIGdyZXAqKiAgICB8IGByIHRpbWVvdXRzLmdyZXBgICB8CmBgYAoKVGhlc2UgYXJlIHJlc3VsdHMgb2YgdGhlIGV4cGVyaW1lbnRzIGZvciBDb3VudGluZyBTZXQgQXV0b21hdGE6Cgp8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLTp8CnwgKipGaWxlKiogICAgICAgICAgICB8IGByIHBhcmFtcyRmaWxlX2NtcGAgfAp8ICoqVGltZW91dCoqICAgICAgICAgfCBgciBUSU1FT1VUYCBzICAgICAgIHwKfCAqKlRJTUVPVVRfVkFMKiogICAgIHwgYHIgVElNRU9VVF9WQUxgIHMgICB8CnwgKipUSU1FX01JTioqICAgICAgICB8IGByIFRJTUVfTUlOYCAgICAgICAgfAp8ICoqQmVuY2htYXJrcyoqICAgICAgfCBgciBucm93KGRmKWAgICAgICAgIHwKfCAqKlRpbWVvdXRzIENBKiogICAgIHwgYHIgdGltZW91dHMuY2FgICAgICB8CnwgKipUaW1lb3V0cyBSRTIqKiAgICB8IGByIHRpbWVvdXRzLnJlMmAgICAgfAp8ICoqVGltZW91dHMgU1JNKiogICAgfCBgciB0aW1lb3V0cy5zcm1gICAgIHwgCnwgKipUaW1lb3V0cyAuTkVUKiogICAgfCBgciB0aW1lb3V0cy5kb3RuZXRgICB8CgoKCmBgYHtyfQpkZgpgYGAKCiMgU3VtbWFyeSBvZiBiZW5jaG1hcmtzCgpgYGB7cn0KZGZfYmVuY2hlcyA8LSBkYXRhLmZyYW1lKHN1bW1hcnkoZGYkc3JjKSkKZGZfYmVuY2hlcwpgYGAKCiMgU2FuaXR5IGNoZWNrcwoKYGBge3J9CiNkZiRpbmNvbnNpc3RlbnQgPC0gZGYkcmUyZy5tYXRjaGVzICE9IGRmJGdyZXAubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRzcm0ubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRkb3RuZXQubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRjYWQubWF0Y2hlcwoKZGYkaW5jb25zaXN0ZW50IDwtIGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRzcm0ubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRkb3RuZXQubWF0Y2hlcyB8IGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRjYWQubWF0Y2hlcwoKCiNkZiRncmVwLnJlMi5taXNtYXRjaCA8LSAhaXMubmEoZGYkcmUyZy5tYXRjaGVzKSAmICFpcy5uYShkZiRncmVwLm1hdGNoZXMpICYgZGYkcmUyZy5tYXRjaGVzICE9IGRmJGdyZXAubWF0Y2hlcwojZGZfZ3JlcF9yZTJfbWlzbWF0Y2ggPC0gZGZbZGYkZ3JlcC5yZTIubWlzbWF0Y2gsXQoKZGYkcmUyLmNhLm1pc21hdGNoIDwtICFpcy5uYShkZiRyZTJnLm1hdGNoZXMpICYgIWlzLm5hKGRmJGNhZC5tYXRjaGVzKSAmIGRmJHJlMmcubWF0Y2hlcyAhPSBkZiRjYWQubWF0Y2hlcwpkZl9yZTJfY2FfbWlzbWF0Y2ggPC0gZGZbZGYkcmUyLmNhLm1pc21hdGNoLF0KCiMgfCAqKmdyZXAgYW5kIFJFMiBtaXNtYXRjaGVkKiogfCBgciBucm93KGRmX2dyZXBfcmUyX21pc21hdGNoKWAgfApgYGAKCnwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fAp8ICoqQ0EgYW5kIFJFMiBtaXNtYXRjaGVkKiogICB8IGByIG5yb3coZGZfcmUyX2NhX21pc21hdGNoKWAgICB8CgojIyBSRTIgYW5kIENBIG1pc21hdGNoZXMKYGBge3J9CmRmX3JlMl9jYV9taXNtYXRjaApgYGAKCgoKIyBTY2F0dGVyIFBsb3RzCgpgYGB7cn0KCnBsb3QuYW5kLnRpa3ogPC0gZnVuY3Rpb24oZGYsIHhsYWIsIHlsYWIsIHhzdHJpbmc9eGxhYiwgeXN0cmluZz15bGFiLCB3aWR0aD00LCBoZWlnaHQ9d2lkdGgpIHsKICBwaWMgPC0gcGxvdF9zY2F0dGVyX2xvZyhkZiwgeGxhYiwgeWxhYiwgeHN0cmluZywgeXN0cmluZykKICAjbWFrZV90aWt6KHBhc3RlMCgiZmlncy8iLCB4bGFiLCAiLXZzLSIsIHlsYWIsICIudGlreiIpLCBwaWMsIHdpZHRoLCBoZWlnaHQpCiAgbWFrZV9wZGYocGFzdGUwKCJmaWdzLyIsIHhsYWIsICItdnMtIiwgeWxhYiwgIi5wZGYiKSwgcGljLCB3aWR0aCwgaGVpZ2h0KQogIHBpYwp9CgpwbG90MSA8LSBwbG90LmFuZC50aWt6KGRmLCAicmUyZyIsICJjYWQiLCB4c3RyaW5nPSJSRTIgW3NdIiwgeXN0cmluZz0iQ0EgW3NdIiwgd2lkdGg9QklHX1NJWkUpCiNwbG90MiA8LSBwbG90LmFuZC50aWt6KGRmLCAiZ3JlcCIsICJjYWQiLCB4c3RyaW5nPSJncmVwIFtzXSIsIHlzdHJpbmc9IkNBIFtzXSIpCnBsb3QzIDwtIHBsb3QuYW5kLnRpa3ooZGYsICJzcm0iLCAiY2FkIiwgeHN0cmluZz0iU1JNIFtzXSIsIHlzdHJpbmc9IkNBIFtzXSIsIHdpZHRoPVNNQUxMX1NJWkUpCnBsb3Q0IDwtIHBsb3QuYW5kLnRpa3ooZGYsICJkb3RuZXQiLCAiY2FkIiwgeHN0cmluZz0iLk5FVCBbc10iLCB5c3RyaW5nPSJDQSBbc10iLCB3aWR0aD1TTUFMTF9TSVpFKQpwbG90NSA8LSBwbG90LmFuZC50aWt6KGRmLCAic3JtIiwgInJlMmciKQojcGxvdDYgPC0gcGxvdC5hbmQudGlreihkZiwgImdyZXAiLCAicmUyZyIpCnBsb3Q3IDwtIHBsb3QuYW5kLnRpa3ooZGYsICJkb3RuZXQiLCAicmUyZyIpCiNwbG90OCA8LSBwbG90LmFuZC50aWt6KGRmLCAic3JtIiwgImdyZXAiKQojcGxvdDkgPC0gcGxvdC5hbmQudGlreihkZiwgImRvdG5ldCIsICJncmVwIikKcGxvdDEwIDwtIHBsb3QuYW5kLnRpa3ooZGYsICJkb3RuZXQiLCAic3JtIikKCgoKZ3JpZC5hcnJhbmdlKHBsb3QxLCBwbG90MywgbmNvbCA9IDIpCmdyaWQuYXJyYW5nZShwbG90NCwgcGxvdDUsIG5jb2wgPSAyKQpncmlkLmFycmFuZ2UocGxvdDcsIHBsb3QxMCwgbmNvbCA9IDIpCgojZ3JpZC5hcnJhbmdlKHBsb3QxLCBwbG90MiwgbmNvbCA9IDIpCiNncmlkLmFycmFuZ2UocGxvdDMsIHBsb3Q0LCBuY29sID0gMikKI2dyaWQuYXJyYW5nZShwbG90NSwgcGxvdDYsIG5jb2wgPSAyKQojZ3JpZC5hcnJhbmdlKHBsb3Q3LCBwbG90OCwgbmNvbCA9IDIpCiNncmlkLmFycmFuZ2UocGxvdDksIHBsb3QxMCwgbmNvbCA9IDIpCgpgYGAKCgojIEhpc3RvZ3JhbXMKCmBgYHtyfQpoaXN0MSA8LSBnZ3Bsb3QoZGYsIGFlcyh4PXJlMmcpKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsdWUiLCBmaWxsPSJsaWdodGJsdWUiKSArCiAgc2NhbGVfeV9sb2cxMCgpCgpoaXN0MiA8LSBnZ3Bsb3QoZGYsIGFlcyh4PWNhZCkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsdWUiLCBmaWxsPSJsaWdodGJsdWUiKSArCiAgc2NhbGVfeV9sb2cxMCgpCgpoaXN0MyA8LSBnZ3Bsb3QoZGYsIGFlcyh4PXNybSkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsdWUiLCBmaWxsPSJsaWdodGJsdWUiKSArCiAgc2NhbGVfeV9sb2cxMCgpCgojaGlzdDQgPC0gZ2dwbG90KGRmLCBhZXMoeD1ncmVwKSkgKyAKIyAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsdWUiLCBmaWxsPSJsaWdodGJsdWUiKSArCiMgIHNjYWxlX3lfbG9nMTAoKQoKaGlzdDUgPC0gZ2dwbG90KGRmLCBhZXMoeD1kb3RuZXQpKSArIAogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJibHVlIiwgZmlsbD0ibGlnaHRibHVlIikgKwogIHNjYWxlX3lfbG9nMTAoKQoKZ3JpZC5hcnJhbmdlKGhpc3QxLCBoaXN0MiwgbmNvbCA9IDIpCmdyaWQuYXJyYW5nZShoaXN0MywgaGlzdDUsIG5jb2wgPSAyKQojZ3JpZC5hcnJhbmdlKGhpc3Q1LCBuY29sID0gMikKCgpgYGAKCiMgRmluZGluZyB3aW5uZXJzCgpgYGB7cn0KI2RmJG1pbiA8LXBtaW4oZGYkZ3JlcCwgZGYkc3JtLCBkZiRyZTJnLCBkZiRkb3RuZXQsIGRmJGNhZCkKI2RmJGVuZW15Lm1pbiA8LSBwbWluKGRmJGdyZXAsIGRmJHNybSwgZGYkcmUyZywgZGYkZG90bmV0KQpkZiRtaW4gPC1wbWluKGRmJHNybSwgZGYkcmUyZywgZGYkZG90bmV0LCBkZiRjYWQpCmRmJGVuZW15Lm1pbiA8LSBwbWluKGRmJHNybSwgZGYkcmUyZywgZGYkZG90bmV0KQoKI3dpbm5lcnMuZ3JlcCA8LSBucm93KGRmW2RmJG1pbiA9PSBkZiRncmVwLF0pCndpbm5lcnMucmUyIDwtIG5yb3coZGZbZGYkbWluID09IGRmJHJlMmcsXSkKd2lubmVycy5jYSA8LSBucm93KGRmW2RmJG1pbiA9PSBkZiRjYWQsXSkKd2lubmVycy5zcm0gPC0gbnJvdyhkZltkZiRtaW4gPT0gZGYkc3JtLF0pCndpbm5lcnMuZG90bmV0IDwtIG5yb3coZGZbZGYkbWluID09IGRmJGRvdG5ldCxdKQoKIyB8ICoqZ3JlcCoqICAgIHwgYHIgd2lubmVycy5ncmVwYCAgfApgYGAKCnwgKipXaW5uZXIqKiAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfAp8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tOnwKfCAqKkNBKiogICAgIHwgYHIgd2lubmVycy5jYWAgICAgIHwKfCAqKlJFMioqICAgIHwgYHIgd2lubmVycy5yZTJgICAgIHwKfCAqKlNSTSoqICAgIHwgYHIgd2lubmVycy5zcm1gICAgIHwgCnwgKiouTkVUKiogICAgfCBgciB3aW5uZXJzLmRvdG5ldGAgIHwKCmBgYHtyfQpwbG90LmFuZC50aWt6KGRmLCAiZW5lbXkubWluIiwgImNhZCIsIHhzdHJpbmc9ImJlc3QgZW5lbXkiLCB5c3RyaW5nPSJDQSBbc10iKQpgYGAKCiMgSG93IG11Y2ggd2UgYXJlIGJldHRlciB0aGFuIFJFMgoKYGBge3J9CmRmJHJlMi52cy5jYSA8LSBkZiRyZTJnIC8gZGYkY2FkCmRmX3NvcnRlZCA8LSBkZltvcmRlcihkZiRyZTIudnMuY2EsIGRlY3JlYXNpbmc9VFJVRSksXQoKI2RmX3NvcnRlZFssYygic3JjIiwgInBhdHRlcm4iLCAiZmlsZSIsICJyZTJnIiwgImNhZCIsICJyZTIudnMuY2EiLCAicmUyLmNhLm1pc21hdGNoIildCmRmX3NvcnRlZAoKYGBgCgoKIyBFeHBlcmltZW50cyB3aXRoIGluY3JlYXNpbmcgY291bnRlciB2YWx1ZQoKYGBge3J9CmJpZyA8LSByZWFkX2ZpbGUocGFyYW1zJGZpbGVfYmlnKQpiaWckcmUyZyA8LSBzdWIoIiwiLCAiLiIsIGJpZyRyZTJnKQpiaWckcmUyZyA8LSBhcy5udW1lcmljKGJpZyRyZTJnKQoKYmlnCmBgYAoKCmBgYHtyfQoKdG9nZXRoZXIgPC0gYmlnWywgYygiQ291bnRlciIsICJyZTJnIildCm5hbWVzKHRvZ2V0aGVyKVsyXSA8LSAidGltZSIKdG9nZXRoZXIkYXBwcm9hY2ggPC0gIlJFMiIKCnRtcCA8LSBiaWdbLCBjKCJDb3VudGVyIiwgImNhZCIpXQpuYW1lcyh0bXApWzJdIDwtICJ0aW1lIgp0bXAkYXBwcm9hY2ggPC0gIkNBIgp0b2dldGhlciA8LSByYmluZCh0b2dldGhlciwgdG1wKQoKdG1wIDwtIGJpZ1ssIGMoIkNvdW50ZXIiLCAic3JtIildCm5hbWVzKHRtcClbMl0gPC0gInRpbWUiCnRtcCRhcHByb2FjaCA8LSAiU1JNIgp0b2dldGhlciA8LSByYmluZCh0b2dldGhlciwgdG1wKQoKdG1wIDwtIGJpZ1ssIGMoIkNvdW50ZXIiLCAiZG90Lm5ldCIpXQpuYW1lcyh0bXApWzJdIDwtICJ0aW1lIgp0bXAkYXBwcm9hY2ggPC0gIi5ORVQiCnRvZ2V0aGVyIDwtIHJiaW5kKHRvZ2V0aGVyLCB0bXApCgp0bXAgPC0gYmlnWywgYygiQ291bnRlciIsICJncmVwIildCm5hbWVzKHRtcClbMl0gPC0gInRpbWUiCnRtcCRhcHByb2FjaCA8LSAiZ3JlcCIKdG9nZXRoZXIgPC0gcmJpbmQodG9nZXRoZXIsIHRtcCkKCkJJR19TVEVQPTEwMAoKIyByZW1vdmUgdG9vIG1hbnkgcG9pbnRzCnRvZ2V0aGVyIDwtIHRvZ2V0aGVyW3RvZ2V0aGVyJENvdW50ZXIgJSUgQklHX1NURVAgPT0gMCxdCgpiaWdfcGxvdCA8LSBnZ3Bsb3QoZGF0YT10b2dldGhlciwgYWVzKHg9Q291bnRlciwgeT10aW1lLCBjb2xvdXI9YXBwcm9hY2gpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlPWFwcHJvYWNoKSkgKwogIHhsaW0oTkEsMTI1MCkgKwogIHlsaW0oTkEsNzUpICsKICBnZW9tX2hsaW5lKHNpemU9MC4xLCB5aW50ZXJjZXB0PTAsIGxpbmV0eXBlPSJkYXNoZWQiKSArCgogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoLjA1LCAuOTUpLAogICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygibGVmdCIsICJ0b3AiKSwKICAgICAgICAjbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yPSJibGFjayIsIHNpemU9MC41KSwKICAgICAgICBsZWdlbmQuYm94Lmp1c3QgPSAicmlnaHQiLAogICAgICAgIGxlZ2VuZC5tYXJnaW4gPSBtYXJnaW4oMSwgMSwgMSwgMSksCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArCiAgbGFicygKICAgICAgI3RpdGxlPSJUaXRsZSIsCiAgICAgICNzdWJ0aXRsZT0iU3VidGl0bGUiLAogICAgICB4PSJrIiwKICAgICAgeT0idGltZSBbc10iKQogICAgICAgIAoKICAjIGdlb21fbGluZShkYXRhID0gYmlnLCBhZXMoeCA9IENvdW50ZXIsIHkgPSByZTJnKSwgY29sb3IgPSAicmVkIikgKwogICMgZ2VvbV9saW5lKGRhdGEgPSBiaWcsIGFlcyh4ID0gQ291bnRlciwgeSA9IGNhKSwgY29sb3IgPSAiYmx1ZSIpICsKICAjIHhsYWIoJ2NvdW50ZXIgdmFsdWUnKSArCiAgIyB5bGFiKCd0aW1lIFtzXScpCgojbWFrZV90aWt6KHBhc3RlMCgiZmlncy9iaWdfcGxvdC50aWt6IiksIGJpZ19wbG90LCB3aWR0aD0yLjcsIGhlaWdodD0yLjcpCm1ha2VfcGRmKHBhc3RlMCgiZmlncy9iaWdfcGxvdC5wZGYiKSwgYmlnX3Bsb3QsIHdpZHRoPUJJR19TSVpFLCBoZWlnaHQ9QklHX1NJWkUpCgoKcGxvdChiaWdfcGxvdCkKYGBgCgoKYGBge3J9CiMgSW5mb3JtYXRpb24gYWJvdXQgRENBcwoKIyBkZl9kY2FzID0gcmVhZC5jc3YyKHBhcmFtcyRmaWxlX2RjYSwKIyAgICAgICAgICAgICAgICAgICBoZWFkZXI9VFJVRSwKIyAgICAgICAgICAgICAgICAgICBzZXA9Ilx0IiwKIyAgICAgICAgICAgICAgICAgICBkZWM9Ii4iLAojICAgICAgICAgICAgICAgICAgIGNvbW1lbnQuY2hhcj0iIiwKIyAgICAgICAgICAgICAgICAgICBxdW90ZT0iIiwKIyAgICAgICAgICAgICAgICAgICBzdHJpcC53aGl0ZT1UUlVFLAojICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnM9RkFMU0UpCiMgCiMgIyBzYW5pdGl6ZQojIGRmX2RjYXMkdGltZW91dHMuY2xhc3NpY2FsW2lzLm5hKGRmX2RjYXMkdGltZW91dHMuY2xhc3NpY2FsKV0gPC0gMAoKI2RmX2RjYXMKYGBgCgpgYGB7cn0KI3Rtcy5jbGFzc2ljYWwgPC0gZGZfZGNhc1tkZl9kY2FzJHRpbWVvdXRzLmNsYXNzaWNhbCA9PSAxLF0KYGBgCgoKCmBgYHtyfQojY29tcHV0ZV90aW1lb3V0cyA8LSBmdW5jdGlvbihkZiwgY29sKSB7CiMgIHRtcCA8LSBkZltkZlssIGNvbF0gPT0gVElNRU9VVF9WQUwsXQojICB0bXAKI30KCmBgYAoK