RQ1: How often do changes and bugs occurin the history of methods?

projects <- unique(methods$Project)
typeMethodsData <- methods %>%
  group_by(Project, NtimeofCommits, typeMethod) %>%
  summarise(Changes = sum(Count)) %>% 
  mutate(Percentual = Changes / sum(Changes) * 100) %>% 
  ungroup()
#Amount
for (project in projects) {
  
print(ggplot(filter(typeMethodsData, Project == project, NtimeofCommits <= 10)) +
  geom_bar(aes(x = NtimeofCommits, y = Percentual, fill = typeMethod, group = typeMethod), position = "dodge", stat = "identity") +
  geom_text(aes(x = NtimeofCommits, y = Percentual, label = round(Percentual,2), group = typeMethod),  
            check_overlap = TRUE, position = position_dodge(width = 1), vjust = -0.5, size = 3) +  
  theme(legend.direction="vertical", legend.title = element_blank(), legend.text=element_text(size=6), 
        legend.background = element_rect(fill = "transparent", colour = NA), axis.ticks.x = ) +
  theme(panel.grid.minor = element_blank(), 
        panel.grid.major = element_blank(),
        plot.background = element_rect(fill = "transparent", colour = NA)) + 
  ggtitle(paste0("Project ", project)) + ylab("Percentual") + 
  scale_x_discrete(name ="Number of Commits", limits=c("1","2","3","4","5","6","7","8","9","10")) +
  scale_fill_manual(values=cbPalette))
}

#Summarize the type of methods by percentual
typeMethodsDataAll <- methods %>%
  group_by( NtimeofCommits, typeMethod) %>%
  summarise(Changes = sum(Count)) %>% 
  mutate(Percentual = Changes / sum(Changes) * 100) %>% 
  ungroup()
ggplot(filter(typeMethodsDataAll, NtimeofCommits <= 10)) +
    geom_bar(aes(x = NtimeofCommits, y = Percentual, fill = typeMethod, group = typeMethod), position = "dodge", stat = "identity") +
    geom_text(aes(x = NtimeofCommits, y = Percentual, label = round(Percentual,2), group = typeMethod),  
              check_overlap = TRUE, position = position_dodge(width = 1), vjust = -0.5, size = 3) +  
    theme(legend.direction="vertical", legend.title = element_blank(), legend.text=element_text(size=6), 
          legend.background = element_rect(fill = "transparent", colour = NA), axis.ticks.x = ) +
    theme(panel.grid.minor = element_blank(), 
          panel.grid.major = element_blank(),
          plot.background = element_rect(fill = "transparent", colour = NA)) + 
    ggtitle("Plots by Type of Methods") + ylab("Percentual") + 
    scale_x_discrete(name ="Number of Commits", limits=c("1","2","3","4","5","6","7","8","9","10")) +
    scale_fill_manual(values=cbPalette)

#Boxplots por Projetos:
projects <- unique(methods$Project)
ggplot(methods, aes(x=Project, y=NtimeofCommits)) + 
    geom_boxplot() +
    theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
    scale_x_discrete(name = project)

Explicar as constraints como esse comportamento ocorre ao longo das constraints de maneira profunda, ou seja, explicar porque algumas constraints diminui pouco a % e algumas muito.

resultsC1C4<-
  sqldf(
    "SELECT Project, SUM(Count) as TotalTimeSeries, 
     SUM(CASE WHEN (P2 = 1) AND (P1 = 1) THEN 1 ELSE 0 end) as 'C1',
     SUM(CASE WHEN (P2 = 1) AND (P1 = 1) AND (P4 = 1) THEN 1 ELSE 0 end) as 'C1-C2',
     SUM(CASE WHEN (P2 = 1) AND (P1 = 1) AND (P4 = 1) AND (P5 = 1) THEN 1 ELSE 0 end) as 'C1-C2-C3',
     SUM(CASE WHEN (P2 = 1) AND (P1 = 1) AND (P4 = 1) AND (P3 = 1) THEN 1 ELSE 0 end) as 'C1-C2-C4',
     SUM(CASE WHEN (P2 = 1) AND (P1 = 1) AND (P3 = 1) AND (P4 = 1) AND (P5 = 1) THEN 1 ELSE 0 end) as 'C1-C2-C3-C4'
     FROM methods
     GROUP BY Project"
  )
resultsC1C4
FALSE List of 3
FALSE  $ panel.grid.major: list()
FALSE   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
FALSE  $ panel.grid.minor: list()
FALSE   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
FALSE  $ plot.background :List of 5
FALSE   ..$ fill         : chr "transparent"
FALSE   ..$ colour       : logi NA
FALSE   ..$ size         : NULL
FALSE   ..$ linetype     : NULL
FALSE   ..$ inherit.blank: logi FALSE
FALSE   ..- attr(*, "class")= chr [1:2] "element_rect" "element"
FALSE  - attr(*, "class")= chr [1:2] "theme" "gg"
FALSE  - attr(*, "complete")= logi FALSE
FALSE  - attr(*, "validate")= logi TRUE
FALSE List of 3
FALSE  $ panel.grid.major: list()
FALSE   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
FALSE  $ panel.grid.minor: list()
FALSE   ..- attr(*, "class")= chr [1:2] "element_blank" "element"
FALSE  $ plot.background :List of 5
FALSE   ..$ fill         : chr "transparent"
FALSE   ..$ colour       : logi NA
FALSE   ..$ size         : NULL
FALSE   ..$ linetype     : NULL
FALSE   ..$ inherit.blank: logi FALSE
FALSE   ..- attr(*, "class")= chr [1:2] "element_rect" "element"
FALSE  - attr(*, "class")= chr [1:2] "theme" "gg"
FALSE  - attr(*, "complete")= logi FALSE
FALSE  - attr(*, "validate")= logi TRUE

RQ2: How close is the relationship betweenthe history of bugs and changes?

RQ3: Which kind of changes are mostlyrelated to the bugs insertion?

#IndividualMetrics
colMethods <- c("Project", "MethodName", "Metric", "groupMetric", "changeType" ,"P1", "P2", "P3", "P4", "P5", "elementsValue", "NtimeofCommits", "Count", "GrangerPos")
#resultsClasses <- subset( resultsClasses, select = c(colClasses) )
resultsMethods <- subset( methods, select = c(colMethods) )
#Filter:D
resultsMethods <- filter(resultsMethods, P2 == 1, groupMetric != "RM")
#IndividualMetrics
indMetrics<-
  sqldf(
    "SELECT Project, Metric, SUM(Count) as Changes
    FROM resultsMethods
    WHERE changeType <> 'All' 
    AND groupMetric <>'All'
    AND Metric <> 'All'
    GROUP BY Project, Metric"
  )
metrics <- c()
# Applying the function to the pareto function:
for (project in projects){
  df <- filter(indMetrics, Project == project)[,c(2,3)]
  i<-1
  for (x in 1:nrow(df)){
    for (y in 1:df$Changes[x]){
      metrics[i] <- df$Metric[x]
      i <- i + 1
    }
  }
  ggpareto(metrics, project)
}

#Groups metrics
grpMetrics <- read.csv(file = "~/R/analysis/methods/dataMetricsGranger.csv", stringsAsFactors = FALSE)


metrics <- c()
# Applying the function to the pareto function:
for (project in projects){
  df <- filter(grpMetrics, Project == project)[,c(3,4)]
  i<-1
  for (x in 1:nrow(df)){
    for (y in 1:df$Changes[x]){
      mylist[i] <- df$Metric[x]
      i <- i + 1
    }
  }
  ggpareto(mylist, project)
}

RQ4:

dfQuartils <- as.data.frame(methods %>%
  group_by(Project, typeMethod) %>%
  summarise(quartile1 = sum(quartile1), quartile2 = sum(quartile2), quartile3 = sum(quartile3), 
            quartile4 = sum(quartile4), quartile5 = sum(quartile5)))
tdfQuartils <- melt(dfQuartils, id=(c("Project", "typeMethod")))
colnames(tdfQuartils) <- c("Project", "typeMethod", "Quartiles", "Values")
#Summarize the type of methods by percentual
dfQuartilsProjects <- tdfQuartils %>%
  group_by( Project, Quartiles) %>%
  summarise(Values = sum(Values)) %>% 
  mutate(Percentual = Values / sum(Values) * 100) %>% 
  ungroup()
#Amount
#Changes over time by projects
  
ggplot(dfQuartilsProjects) +
geom_bar(aes(x = Quartiles, y = Percentual, fill = Project, group = Project), position = "dodge", stat = "identity") +
geom_text(aes(x = Quartiles, y = Percentual, label = round(Percentual,2), group = Project),  
          check_overlap = TRUE, position = position_dodge(width = 1), vjust = -0.5, size = 3) +  
theme(legend.direction="vertical", legend.title = element_blank(), legend.text=element_text(size=6), 
      legend.background = element_rect(fill = "transparent", colour = NA), axis.ticks.x = ) +
theme(panel.grid.minor = element_blank(), 
      panel.grid.major = element_blank(),
      plot.background = element_rect(fill = "transparent", colour = NA)) + 
ggtitle(paste0("Project ", project)) + ylab("Percentual") 

#scale_fill_manual(values=cbPalette)
#Summarize the type of methods by percentual
dfQuartilsTypes <- tdfQuartils %>%
  group_by( typeMethod, Quartiles ) %>%
  summarise(Values = sum(Values)) %>% 
  mutate(Percentual = Values / sum(Values) * 100) %>% 
  ungroup()
#Changes over time by types of methods
ggplot(dfQuartilsTypes) +
  geom_bar(aes(x = Quartiles, y = Percentual, fill = typeMethod, group = typeMethod), position = "dodge", stat = "identity") +
  geom_text(aes(x = Quartiles, y = Percentual, label = round(Percentual,2), group = typeMethod),  
            check_overlap = TRUE, position = position_dodge(width = 1), vjust = -0.5, size = 3) +  
  theme(legend.direction="vertical", legend.title = element_blank(), legend.text=element_text(size=6), 
        legend.background = element_rect(fill = "transparent", colour = NA), axis.ticks.x = ) +
  theme(panel.grid.minor = element_blank(), 
        panel.grid.major = element_blank(),
        plot.background = element_rect(fill = "transparent", colour = NA)) + 
  ggtitle(paste0("Project ", project)) + ylab("Percentual") +
  scale_fill_manual(values=cbPalette)

dfPeaks <- as.data.frame(methods %>%
                              group_by(Project, typeMethod) %>%
                              summarise(peaksMedian = sum(peaksMedian), peaks1Sd = sum(peaks1Sd), peaks2Sd = sum(peaks2Sd), 
                                        peaks3Sd = sum(peaks3Sd)))
tdfPeaks <- melt(dfPeaks, id=(c("Project", "typeMethod")))
colnames(tdfPeaks) <- c("Project", "typeMethod", "Peaks", "Values")
#Summarize the type of methods by percentual
dfPeaksProjects <- tdfPeaks %>%
  group_by( Project, Peaks) %>%
  summarise(Values = sum(Values)) %>% 
  mutate(Percentual = Values / sum(Values) * 100) %>% 
  ungroup()
#Amount
#Changes over time by projects
ggplot(dfPeaksProjects) +
  geom_bar(aes(x = Project, y = Percentual, fill = Peaks, group = Peaks), position = "dodge", stat = "identity") +
  geom_text(aes(x = Project, y = Percentual, label = round(Percentual,2), group = Peaks),  
            check_overlap = TRUE, position = position_dodge(width = 1), vjust = -0.5, size = 3) +  
  theme(legend.direction="vertical", legend.title = element_blank(), legend.text=element_text(size=6), 
        legend.background = element_rect(fill = "transparent", colour = NA), axis.ticks.x = ) +
  theme(panel.grid.minor = element_blank(), 
        panel.grid.major = element_blank(),
        plot.background = element_rect(fill = "transparent", colour = NA)) + 
  ggtitle(paste0("Project ", project)) + ylab("Percentual") +
  scale_fill_manual(values=cbPalette)

dfPeaksTypes <- tdfPeaks %>%
  group_by( typeMethod, Peaks ) %>%
  summarise(Values = sum(Values)) %>% 
  mutate(Percentual = Values / sum(Values) * 100) %>% 
  ungroup()
#Changes over time by types of methods
ggplot(dfPeaksTypes) +
  geom_bar(aes(x = typeMethod, y = Percentual, fill = Peaks, group = Peaks), position = "dodge", stat = "identity") +
  geom_text(aes(x = typeMethod, y = Percentual, label = round(Percentual,2), group = Peaks),  
            check_overlap = TRUE, position = position_dodge(width = 1), vjust = -0.5, size = 3) +  
  theme(legend.direction="vertical", legend.title = element_blank(), legend.text=element_text(size=6), 
        legend.background = element_rect(fill = "transparent", colour = NA), axis.ticks.x = ) +
  theme(panel.grid.minor = element_blank(), 
        panel.grid.major = element_blank(),
        plot.background = element_rect(fill = "transparent", colour = NA)) + 
  ggtitle(paste0("Project ", project)) + ylab("Percentual") + 
  scale_fill_manual(values=cbPalette)

LS0tCnRpdGxlOiAiT24gdGhlIFJlbGF0aW9uIEJldHdlZW4gdGhlIEhpc3Rvcnkgb2YgQ2hhbmdlcyBhbmQgQnVncyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIGNvbW1lbnQ9IEZBTFNFfQoKc3VwcHJlc3NXYXJuaW5ncyhsaWJyYXJ5KGRwbHlyKSkKc3VwcHJlc3NXYXJuaW5ncyhsaWJyYXJ5KHN0cmluZ3IpKQpzdXBwcmVzc1dhcm5pbmdzKGxpYnJhcnkoc3FsZGYpKQpzdXBwcmVzc1dhcm5pbmdzKGxpYnJhcnkoZ2dwbG90MikpCnN1cHByZXNzV2FybmluZ3MobGlicmFyeShiZWFucGxvdCkpCnN1cHByZXNzV2FybmluZ3MobGlicmFyeSh2aW9wbG90KSkKc3VwcHJlc3NXYXJuaW5ncyhsaWJyYXJ5KGdncHVicikpCnN1cHByZXNzV2FybmluZ3MobGlicmFyeShxY2MpKQpzdXBwcmVzc1dhcm5pbmdzKGxpYnJhcnkocmVzaGFwZSkpCgpnZXRUeXBlTWV0aG9kIDwtIGZ1bmN0aW9uICh4KXsKICAKICBzcGxpdFJlZiA8LSBzdHJzcGxpdCh4LCAiXFwuIikgI2RpdmlkZSBvIG5vbWUgZG8gbWV0b2RvIHBlbG8gcG9udG8KICAjc3BsaXRSZWYKICAKICBmb3IoZCBpbiBzcGxpdFJlZil7IAogICAgciA8LSBzdWIoIlsoXS4qIiwgIiIsIGQpICNyZW1vdmUgb3MgcGFyYW1lbnRyb3MgZG8gbWV0b2RvCiAgfQogICNyICNOZXNzYSB2YXIgdGVtIG9zIHZhbG9yZXMgc2VwYXJhZG9zLCBzw7MgZmF6ZXIgdW0gaWYgZSB2ZXJpZmljYXIgc2Ugb3MgZG9pcyB1bHRpbW9zIHPDo28gaWd1YWlzLCBhaSBjYWkgbm8gY2FzbyBkbyBjb25zdHJ1dG9yIAogIAogIG5vbWVNZXRvZG8gPC0gc3ViKCIuKlsuXSIsICIiLCB4KSAjc2VsZWNpb25hIG8gbm9tZSBkbyBtZXRvZG8KICBub21lTWV0b2RvU2VtUGFyYW0gPC0gc3ViKCJbKF0uKiIsICIiLCBub21lTWV0b2RvKSAjcmVtb3ZlIG9zIHBhcmFtZXRyb3MKICAjbm9tZU1ldG9kb1NlbVBhcmFtICNzw7MgdmVyaWZpY2FyIHNlIMOpIGlndWFsIGEgdG9TdHJpbmcgCiAgCiAgZ2V0T3VTZXQgPC0gc3Vic3RyaW5nKG5vbWVNZXRvZG9TZW1QYXJhbSwgMSwgMykgI3NlbGVjaW9uYSBvcyAzIHByaW1laXJvcyBlbGVtZW50b3MgZG8gbWV0b2RvCiAgI2dldE91U2V0ICMgc8OzIHZlcmlmaWNhciBzZSDDqSB1bSBnZXQgb3Ugc2V0CiAgCiAgaWYgKGdldE91U2V0ID09ICJzZXQiIHx8IGdldE91U2V0ID09ICJnZXQiKXsKICAgIHJldHVybiAoIkdldHRlcnMvU2V0dGVycyIpCiAgICAKICB9IGVsc2UgaWYgKG5vbWVNZXRvZG9TZW1QYXJhbSA9PSAidG9TdHJpbmciKXsKICAgIHJldHVybiAoInRvU3RyaW5nIikKICAgIAogIH0gZWxzZSBpZiAobm9tZU1ldG9kb1NlbVBhcmFtID09ICJoYXNoQ29kZSIpewogICAgcmV0dXJuICgiaGFzaENvZGUiKQogIAogIH0gZWxzZSBpZiAobm9tZU1ldG9kb1NlbVBhcmFtID09ICJlcXVhbHMiKXsKICAgIHJldHVybiAoImVxdWFscyIpCiAgICAKICB9IGVsc2UgaWYgKHJbbGVuZ3RoKHIpXSA9PSByW2xlbmd0aChyKS0xXSl7CiAgICByZXR1cm4gKCJDb25zdHJ1Y3RvciIpCiAgCiAgfSBlbHNlIHsKICAgIHJldHVybiAoIk5vcm1hbCIpCiAgfQogIAp9CgojIGltcGxlbWVudGluZyB0aGUgZnVuY3Rpb246CmdncGFyZXRvIDwtIGZ1bmN0aW9uKHgsIHRpdGxlKSB7CiAgCiAgI3RpdGxlIDwtIGRlcGFyc2Uoc3Vic3RpdHV0ZSh4KSkKICAKICB4IDwtIGRhdGEuZnJhbWUobW9kYWxpdHkgPSBuYS5vbWl0KHgpKQogIAogIERmIDwtIHggJT4lIGdyb3VwX2J5KG1vZGFsaXR5KSAlPiUgc3VtbWFyaXNlKGZyZXF1ZW5jeT1uKCkpICU+JSAKICAgIGFycmFuZ2UoZGVzYyhmcmVxdWVuY3kpKQogIAogIERmJG1vZGFsaXR5IDwtIG9yZGVyZWQoRGYkbW9kYWxpdHksIGxldmVscyA9IHVubGlzdChEZiRtb2RhbGl0eSwgdXNlLm5hbWVzID0gRikpCiAgCiAgRGYgPC0gRGYgJT4lIG11dGF0ZShtb2RhbGl0eV9pbnQgPSBhcy5pbnRlZ2VyKG1vZGFsaXR5KSwgCiAgICAgICAgICAgICAgICAgICAgICBjdW1mcmVxID0gY3Vtc3VtKGZyZXF1ZW5jeSksIGN1bXBlcmMgPSBjdW1mcmVxL25yb3coeCkgKiAxMDApCiAgbnIgPC0gbnJvdyhEZikKICBOIDwtIHN1bShEZiRmcmVxdWVuY3kpCiAgCiAgRGZfdGlja3MgPC0gZGF0YS5mcmFtZSh4dGljazAgPSByZXAobnIgKy41NSwgMTEpLCB4dGljazEgPSByZXAobnIgKy41OSwgMTEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHl0aWNrID0gc2VxKDAsIE4sIE4vMTApKQogIAogIHkyIDwtIGMoIiAgMCUiLCAiIDEwJSIsICIgMjAlIiwgIiAzMCUiLCAiIDQwJSIsICIgNTAlIiwgIiA2MCUiLCAiIDcwJSIsICIgODAlIiwgIiA5MCUiLCAiMTAwJSIpCiAgCiAgZyA8LSBnZ3Bsb3QoRGYsIGFlcyh4PW1vZGFsaXR5LCB5PWZyZXF1ZW5jeSkpICsgCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIsIGFlcyhmaWxsID0gbW9kYWxpdHlfaW50KSkgKwogICAgZ2VvbV9saW5lKGFlcyh4PW1vZGFsaXR5X2ludCwgeSA9IGN1bWZyZXEsIGNvbG9yID0gbW9kYWxpdHlfaW50KSkgKwogICAgZ2VvbV9wb2ludChhZXMoeD1tb2RhbGl0eV9pbnQsIHkgPSBjdW1mcmVxLCBjb2xvciA9IG1vZGFsaXR5X2ludCksIHBjaCA9IDE5KSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzPXNlcSgwLCBOLCBOLzEwKSwgbGltaXRzPWMoLS4wMiAqIE4sIE4gKiAxLjAyKSkgKyAKICAgIHNjYWxlX3hfZGlzY3JldGUoYnJlYWtzID0gRGYkbW9kYWxpdHkpICsKICAgIGd1aWRlcyhmaWxsID0gRkFMU0UsIGNvbG9yID0gRkFMU0UpICsgCiAgICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSBuciArIC41NSwgeG1heCA9IG5yICsgMSwgCiAgICAgICAgICAgICB5bWluID0gLS4wMiAqIE4sIHltYXggPSBOICogMS4wMiwgZmlsbCA9ICJ3aGl0ZSIpICsKICAgIGFubm90YXRlKCJ0ZXh0IiwgeCA9IG5yICsgLjgsIHkgPSBzZXEoMCwgTiwgTi8xMCksIGxhYmVsID0geTIsIHNpemUgPSAzLjUpICsKICAgIGdlb21fc2VnbWVudCh4ID0gbnIgKyAuNTUsIHhlbmQgPSBuciArIC41NSwgeSA9IC0uMDIgKiBOLCB5ZW5kID0gTiAqIDEuMDIsIGNvbG9yID0gImdyZXk1MCIpICsKICAgIGdlb21fc2VnbWVudChkYXRhID0gRGZfdGlja3MsIGFlcyh4ID0geHRpY2swLCB5ID0geXRpY2ssIHhlbmQgPSB4dGljazEsIHllbmQgPSB5dGljaykpICsKICAgIGxhYnModGl0bGUgPSBwYXN0ZTAoIlBhcmV0byBDaGFydCBvZiAiLCB0aXRsZSksIHkgPSAiRnJlcXVlbmN5IG9mIE1ldGhvZHMgV2l0aCBCdWdzIiwgeCA9ICJNZXRyaWNzIikgKwogICAgdGhlbWVfYncoKSArIAogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgCiAgCiAgcHJpbnQoZykKICAKICAjcmV0dXJuKGxpc3QoZ3JhcGggPSBnLCBEZiA9IERmWywgYygzLCAxLCAyLCA0LCA1KV0pKQogIHJldHVybiAoZ3JhcGggPSBnKQp9CgpnZXRTYXRpc2ZpZWRUcyA8LSBmdW5jdGlvbiAoeCwgbWVhc3VyZSkgewogIGlmICh4ID49IG1lYXN1cmUpIHsKICAgIDEKICB9IGVsc2V7CiAgICAwCiAgfQp9CgoKZ2V0U3RhdHNQcm9jZXNzIDwtIGZ1bmN0aW9uKHgpewogIAogIG1lZGlhbkhpZ2hlciA8LSBtZWRpYW4xU2QgPC0gbWVkaWFuMlNkIDwtIG1lZGlhbjNTZCA8LSAgMAogIHZhbHVlcyA8LSBhcy5pbnRlZ2VyKHVubGlzdChzdHJzcGxpdCh4LCIsIikpKQogIAogIGlmIChsZW5ndGgodmFsdWVzKSA+IDEpIHsKICAgIGZvcihpIGluIDE6bGVuZ3RoKHZhbHVlcykpewogICAgICBpZiAodmFsdWVzW2ldID4gbWVkaWFuKHZhbHVlcykpewogICAgICAgIG1lZGlhbkhpZ2hlciA8LSBtZWRpYW5IaWdoZXIgKyAxCiAgICAgIH0KICAgICAgaWYgKHZhbHVlc1tpXSA+IChtZWRpYW4odmFsdWVzKSArIHNkKHZhbHVlcykpKXsKICAgICAgICBtZWRpYW4xU2QgPC0gbWVkaWFuMVNkICsgMQogICAgICB9CiAgICAgIGlmICh2YWx1ZXNbaV0gPiAobWVkaWFuKHZhbHVlcykgKyAyKnNkKHZhbHVlcykpKXsKICAgICAgICBtZWRpYW4yU2QgPC0gbWVkaWFuMlNkICsgMQogICAgICB9CiAgICAgIGlmICh2YWx1ZXNbaV0gPiAobWVkaWFuKHZhbHVlcykgKyAzKnNkKHZhbHVlcykpKXsKICAgICAgICBtZWRpYW4zU2QgPC0gbWVkaWFuM1NkICsgMQogICAgICB9CiAgICB9CiAgfQogIAogICNwcmludChjKG1lZGlhbkhpZ2hlciwgbWVkaWFuMVNkLCBtZWRpYW4yU2QsIG1lZGlhbjNTZCkpCiAgcmV0dXJuKGMobWVkaWFuSGlnaGVyLCBtZWRpYW4xU2QsIG1lZGlhbjJTZCwgbWVkaWFuM1NkKSkKfQoKZ2V0VGltZXNQcm9jZXNzIDwtIGZ1bmN0aW9uKHgpewogIAogIHZhbHVlcyA8LSB1bmlxdWUoYXMuUE9TSVhsdCh1bmxpc3Qoc3Ryc3BsaXQoeCwiLCIpKSkpCiAgCiAgY291bnQxPDwtY291bnQxKzEKICBpZiAoY291bnQxICUlIDEwMDAwMCA9PSAwKXsKICAgIHByaW50KHBhc3RlMCgiTWV0aG9kOiAiLCBjb3VudDEpKQogIH0KICAKICBpZiAobGVuZ3RoKHZhbHVlcykgPiAxKXsKICAgIAogICAgZGlmZlNlYyA8LSBhYnMoYXMuaW50ZWdlcihkaWZmdGltZSh2YWx1ZXNbMV0gLHZhbHVlc1tsZW5ndGgodmFsdWVzKV0gLCB1bml0cyA9IGMoInNlY3MiKSkpKQogICAgI3F1b3RpZW50IG9mIGRpdmlzaW9uCiAgICBpZiAobGVuZ3RoKHZhbHVlcykgPiA1KXsKICAgICAgcXVhckRpdiA8LSBkaWZmU2VjICUvJSA0CiAgICB9IGVsc2V7CiAgICAgIHF1YXJEaXYgPC0gZGlmZlNlYyAlLyUgbGVuZ3RoKHZhbHVlcykKICAgIH0KICAgIAogICAgZnJhbWVzIDwtIGMoMCkKICAgIGZvciAoaSBpbiAxOjQpewogICAgICBmcmFtZXNbaV08LSB0YWlsKGZyYW1lc1sxOihpLTEpXSwgbj0xKSArIHF1YXJEaXYKICAgIH0KICAgIAogICAgZnJhbWVzIDwtIGMoMCxmcmFtZXMpCiAgICB2YWx1ZXM8LSBjKHZhbHVlc1sxXSwgdmFsdWVzKQogICAgcXVhcnRpbGVzIDwtIGMoMCwwLDAsMCwwKQogICAgCiAgICBmb3IgKGsgaW4gMToobGVuZ3RoKGZyYW1lcykpKXsKICAgICAgZm9yICh6IGluIDE6KGxlbmd0aCh2YWx1ZXMpLTEpKXsKICAgICAgICBzZWNzIDwtIGFicyhhcy5pbnRlZ2VyKGRpZmZ0aW1lKHZhbHVlc1sxXSAsdmFsdWVzW3orMV0gLCB1bml0cyA9IGMoInNlY3MiKSkpKQogICAgICAgIGlmIChrIDw9IDQpewogICAgICAgICAgaWYgKHNlY3MgPj0gZnJhbWVzW2tdICYmIHNlY3MgPCBmcmFtZXNbaysxXSkgewogICAgICAgICAgICBxdWFydGlsZXNba10gPC0gcXVhcnRpbGVzW2tdICsgMQogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoc2VjcyA+PSBmcmFtZXNba10pIHsKICAgICAgICAgIHF1YXJ0aWxlc1trXSA8LSBxdWFydGlsZXNba10gKyAxCiAgICAgICAgfQogICAgICAgIAogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIHF1YXJ0aWxlcyA8LSBjKDAsMCwwLDAsMCkKICB9CiAgCiAgcmV0dXJuIChjKHF1YXJ0aWxlcykpCiAgCn0KCgptZXRob2RzIDwtCiAgcmVhZC5jc3YoCiAgICAifi9SL2FuYWx5c2lzL21ldGhvZHMvYWxsTWV0aG9kc2FsbC5jc3YiLAogICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFCiAgKQoKbWV0aG9kcyR0eXBlTWV0aG9kIDwtIHNhcHBseShtZXRob2RzJE1ldGhvZE5hbWUsIGdldFR5cGVNZXRob2QpIAoKI1JlY2FsY3VsaW5nIFAxOgptZXRob2RzJFAxIDwtIG1hcHBseShnZXRTYXRpc2ZpZWRUcywgbWV0aG9kcyROdGltZW9mQ29tbWl0cywgMykKCiMgVGhlIHBhbGV0dGUgd2l0aCBibGFjazoKY2JQYWxldHRlIDwtIGMoIiNGMTU4NTQiLCAiIzVEQTVEQSIsICIjRkFBNDNBIiwgIiNCMjc2QjIiLCAiIzRENEQ0RCIsICIjMDA5RTczIikgICMiIyIsICIjRjE3Q0IwIiwgREVDRjNGCgojQ2FsY3VsaW5nIHBlYWtzCm1ldGhvZHNbLCBjKCJwZWFrc01lZGlhbiIsICJwZWFrczFTZCIsICJwZWFrczJTZCIgLCAicGVha3MzU2QiKV0gPC0gMCAKbWV0aG9kc1ssYygicGVha3NNZWRpYW4iLCAicGVha3MxU2QiLCAicGVha3MyU2QiLCAicGVha3MzU2QiKV0gPC0gIHBseXI6OmxkcGx5KG1ldGhvZHMkZWxlbWVudHNWYWx1ZSwgZ2V0U3RhdHNQcm9jZXNzKQoKI0NhbGN1bGluZyBxdWFydGlsZXMKbWV0aG9kc1ssYygicXVhcnRpbGUxIiwgInF1YXJ0aWxlMiIsICJxdWFydGlsZTMiLCAicXVhcnRpbGU0IiwgInF1YXJ0aWxlNSIpXSA8LSAwIAptZXRob2RzWyxjKCJxdWFydGlsZTEiLCAicXVhcnRpbGUyIiwgInF1YXJ0aWxlMyIsICJxdWFydGlsZTQiLCAicXVhcnRpbGU1IildIDwtIHBseXI6OmxkcGx5KG1ldGhvZHMkdGltZW9mQ29tbWl0cywgZ2V0VGltZXNQcm9jZXNzKQoKYGBgCgoKIyMjI1JRMTogSG93IG9mdGVuIGRvIGNoYW5nZXMgYW5kIGJ1Z3Mgb2NjdXJpbiB0aGUgaGlzdG9yeSBvZiBtZXRob2RzPwoKKiBHcsOhZmljbyBkb3MgcHJvamV0b3MgQ29udGVuZG8gYSBRdWFudGlkYWRlIGNvbW1pdHMgeCBUaXBvcyBkZSBNZXRvZG9zCmBgYHtyfQpwcm9qZWN0cyA8LSB1bmlxdWUobWV0aG9kcyRQcm9qZWN0KQoKdHlwZU1ldGhvZHNEYXRhIDwtIG1ldGhvZHMgJT4lCiAgZ3JvdXBfYnkoUHJvamVjdCwgTnRpbWVvZkNvbW1pdHMsIHR5cGVNZXRob2QpICU+JQogIHN1bW1hcmlzZShDaGFuZ2VzID0gc3VtKENvdW50KSkgJT4lIAogIG11dGF0ZShQZXJjZW50dWFsID0gQ2hhbmdlcyAvIHN1bShDaGFuZ2VzKSAqIDEwMCkgJT4lIAogIHVuZ3JvdXAoKQoKI0Ftb3VudApmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpIHsKICAKcHJpbnQoZ2dwbG90KGZpbHRlcih0eXBlTWV0aG9kc0RhdGEsIFByb2plY3QgPT0gcHJvamVjdCwgTnRpbWVvZkNvbW1pdHMgPD0gMTApKSArCiAgZ2VvbV9iYXIoYWVzKHggPSBOdGltZW9mQ29tbWl0cywgeSA9IFBlcmNlbnR1YWwsIGZpbGwgPSB0eXBlTWV0aG9kLCBncm91cCA9IHR5cGVNZXRob2QpLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZ2VvbV90ZXh0KGFlcyh4ID0gTnRpbWVvZkNvbW1pdHMsIHkgPSBQZXJjZW50dWFsLCBsYWJlbCA9IHJvdW5kKFBlcmNlbnR1YWwsMiksIGdyb3VwID0gdHlwZU1ldGhvZCksICAKICAgICAgICAgICAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwgdmp1c3QgPSAtMC41LCBzaXplID0gMykgKyAgCiAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbj0idmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpLCBheGlzLnRpY2tzLnggPSApICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpKSArIAogIGdndGl0bGUocGFzdGUwKCJQcm9qZWN0ICIsIHByb2plY3QpKSArIHlsYWIoIlBlcmNlbnR1YWwiKSArIAogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9Ik51bWJlciBvZiBDb21taXRzIiwgbGltaXRzPWMoIjEiLCIyIiwiMyIsIjQiLCI1IiwiNiIsIjciLCI4IiwiOSIsIjEwIikpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9Y2JQYWxldHRlKSkKfQoKCgpgYGAKCiogR3LDoWZpY28gZGUgVG9kb3Mgb3MgUHJvamV0b3MKYGBge3J9CiNTdW1tYXJpemUgdGhlIHR5cGUgb2YgbWV0aG9kcyBieSBwZXJjZW50dWFsCnR5cGVNZXRob2RzRGF0YUFsbCA8LSBtZXRob2RzICU+JQogIGdyb3VwX2J5KCBOdGltZW9mQ29tbWl0cywgdHlwZU1ldGhvZCkgJT4lCiAgc3VtbWFyaXNlKENoYW5nZXMgPSBzdW0oQ291bnQpKSAlPiUgCiAgbXV0YXRlKFBlcmNlbnR1YWwgPSBDaGFuZ2VzIC8gc3VtKENoYW5nZXMpICogMTAwKSAlPiUgCiAgdW5ncm91cCgpCgoKZ2dwbG90KGZpbHRlcih0eXBlTWV0aG9kc0RhdGFBbGwsIE50aW1lb2ZDb21taXRzIDw9IDEwKSkgKwogICAgZ2VvbV9iYXIoYWVzKHggPSBOdGltZW9mQ29tbWl0cywgeSA9IFBlcmNlbnR1YWwsIGZpbGwgPSB0eXBlTWV0aG9kLCBncm91cCA9IHR5cGVNZXRob2QpLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgICBnZW9tX3RleHQoYWVzKHggPSBOdGltZW9mQ29tbWl0cywgeSA9IFBlcmNlbnR1YWwsIGxhYmVsID0gcm91bmQoUGVyY2VudHVhbCwyKSwgZ3JvdXAgPSB0eXBlTWV0aG9kKSwgIAogICAgICAgICAgICAgIGNoZWNrX292ZXJsYXAgPSBUUlVFLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDMpICsgIAogICAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbj0idmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksIGF4aXMudGlja3MueCA9ICkgKwogICAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSkpICsgCiAgICBnZ3RpdGxlKCJQbG90cyBieSBUeXBlIG9mIE1ldGhvZHMiKSArIHlsYWIoIlBlcmNlbnR1YWwiKSArIAogICAgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0iTnVtYmVyIG9mIENvbW1pdHMiLCBsaW1pdHM9YygiMSIsIjIiLCIzIiwiNCIsIjUiLCI2IiwiNyIsIjgiLCI5IiwiMTAiKSkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNiUGFsZXR0ZSkKYGBgCgoqIEJveHBsb3QgZG9zIFByb2pldG9zCgpgYGB7cn0KCiNCb3hwbG90cyBwb3IgUHJvamV0b3M6CnByb2plY3RzIDwtIHVuaXF1ZShtZXRob2RzJFByb2plY3QpCgpnZ3Bsb3QobWV0aG9kcywgYWVzKHg9UHJvamVjdCwgeT1OdGltZW9mQ29tbWl0cykpICsgCiAgICBnZW9tX2JveHBsb3QoKSArCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgICBzY2FsZV94X2Rpc2NyZXRlKG5hbWUgPSBwcm9qZWN0KQpgYGAKCkV4cGxpY2FyIGFzIGNvbnN0cmFpbnRzIGNvbW8gZXNzZSBjb21wb3J0YW1lbnRvIG9jb3JyZSBhbyBsb25nbyBkYXMgY29uc3RyYWludHMgZGUgbWFuZWlyYSBwcm9mdW5kYSwgb3Ugc2VqYSwgZXhwbGljYXIgcG9ycXVlIGFsZ3VtYXMgY29uc3RyYWludHMgZGltaW51aSBwb3VjbyBhICUgZSBhbGd1bWFzIG11aXRvLgoKKiAqKlRPRE8qKiBOb3ZhIHRhYmVsYSBjb20gbyBrPTE6CmBgYHtyfQpyZXN1bHRzQzFDNDwtCiAgc3FsZGYoCiAgICAiU0VMRUNUIFByb2plY3QsIFNVTShDb3VudCkgYXMgVG90YWxUaW1lU2VyaWVzLCAKICAgICBTVU0oQ0FTRSBXSEVOIChQMiA9IDEpIEFORCAoUDEgPSAxKSBUSEVOIDEgRUxTRSAwIGVuZCkgYXMgJ0MxJywKICAgICBTVU0oQ0FTRSBXSEVOIChQMiA9IDEpIEFORCAoUDEgPSAxKSBBTkQgKFA0ID0gMSkgVEhFTiAxIEVMU0UgMCBlbmQpIGFzICdDMS1DMicsCiAgICAgU1VNKENBU0UgV0hFTiAoUDIgPSAxKSBBTkQgKFAxID0gMSkgQU5EIChQNCA9IDEpIEFORCAoUDUgPSAxKSBUSEVOIDEgRUxTRSAwIGVuZCkgYXMgJ0MxLUMyLUMzJywKICAgICBTVU0oQ0FTRSBXSEVOIChQMiA9IDEpIEFORCAoUDEgPSAxKSBBTkQgKFA0ID0gMSkgQU5EIChQMyA9IDEpIFRIRU4gMSBFTFNFIDAgZW5kKSBhcyAnQzEtQzItQzQnLAogICAgIFNVTShDQVNFIFdIRU4gKFAyID0gMSkgQU5EIChQMSA9IDEpIEFORCAoUDMgPSAxKSBBTkQgKFA0ID0gMSkgQU5EIChQNSA9IDEpIFRIRU4gMSBFTFNFIDAgZW5kKSBhcyAnQzEtQzItQzMtQzQnCiAgICAgRlJPTSBtZXRob2RzCiAgICAgR1JPVVAgQlkgUHJvamVjdCIKICApCgpyZXN1bHRzQzFDNApgYGAKCiogTm92byBncsOhZmljbyBjb250ZW5kbyBvcyBtZXRvZG9zIGNvbSAxIGUgMiBjb21taXRzIDoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0UsIGNvbW1lbnQ9IEZBTFNFfQoKCnRvdGFsSyA8LSBhcy5kYXRhLmZyYW1lKG1ldGhvZHMgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoUHJvamVjdCwgTnRpbWVvZkNvbW1pdHMpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShOdW1iZXJLID0gc3VtKENvdW50KSkpCgpzdW1UcyA8LSBhcy5kYXRhLmZyYW1lKG1ldGhvZHMgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF9ieShQcm9qZWN0KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZSggdG90YWxUcyA9IHN1bShDb3VudCkpKQoKZGF0YUsgPC0gaW5uZXJfam9pbih0b3RhbEssIHN1bVRzKQkJICAKZGF0YUtbLCAiUGVyYyJdIDwtIHJvdW5kKGRhdGFLJE51bWJlcksvZGF0YUskdG90YWxUcywyKQoKazEgPC0gZ2dwbG90KGZpbHRlcihkYXRhSywgTnRpbWVvZkNvbW1pdHMgPD0gMTAsIFByb2plY3QgJWluJSBwcm9qZWN0c1swOjVdKSkgKwogIGdlb21fYmFyKGFlcyh4PU50aW1lb2ZDb21taXRzLHk9UGVyYyxncm91cD1Qcm9qZWN0KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBzdGF0ID0gImlkZW50aXR5IikrCiAgZmFjZXRfZ3JpZCguflByb2plY3Qsc2NhbGVzPSJmcmVlIikgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249IGMoMC43LCAwLjk1KSwgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9NSksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSkgKSArCiAgeWxhYigiUGVyY2VudHVhbCIpICsgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0iTnVtYmVyIG9mIENvbW1pdHMiLCBsaW1pdHM9YygiMSIsIjIiLCIzIiwiNCIsIjUiLCI2IiwiNyIsIjgiLCI5IiwiMTAiKSkgCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG91ciA9IE5BKSkKCgprMiA8LSBnZ3Bsb3QoZmlsdGVyKGRhdGFLLCBOdGltZW9mQ29tbWl0cyA8PSAxMCwgUHJvamVjdCAlaW4lIHByb2plY3RzWzY6MTBdKSkgKwogIGdlb21fYmFyKGFlcyh4PU50aW1lb2ZDb21taXRzLHk9UGVyYyxncm91cD1Qcm9qZWN0KSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBzdGF0ID0gImlkZW50aXR5IikrCiAgZmFjZXRfZ3JpZCguflByb2plY3Qsc2NhbGVzPSJmcmVlIikgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249IGMoMC43LCAwLjk1KSwgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9NSksIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSkgKSArCiAgeWxhYigiUGVyY2VudHVhbCIpICsgc2NhbGVfeF9kaXNjcmV0ZShuYW1lID0iTnVtYmVyIG9mIENvbW1pdHMiLCBsaW1pdHM9YygiMSIsIjIiLCIzIiwiNCIsIjUiLCI2IiwiNyIsIjgiLCI5IiwiMTAiKSkgCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJ0cmFuc3BhcmVudCIsIGNvbG91ciA9IE5BKSkKCgpnZ2FycmFuZ2UoazEgLCBrMiAsIG5jb2wgPSAxLCBucm93ID0gMikKCmBgYAoKIyMjI1JRMjogSG93IGNsb3NlIGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbnRoZSBoaXN0b3J5IG9mIGJ1Z3MgYW5kIGNoYW5nZXM/CgoqIENvbXBhcmF0aXZvIGVudHJlIGFzIHRlY25pY2FzOgoKYGBge3Igd2FybmluZz1GQUxTRSwgZWNobz1GQUxTRSwgY29tbWVudD0gRkFMU0V9CgojR3JhbmdlciBQb3NpdGl2ZXMKbWV0aG9kc0dyYW5nZXJQb3MgPC0KICByZWFkLmNzdigKICAgICJ+L1IvYW5hbHlzaXMvbWV0aG9kcy9hbGxNZXRob2RzR3JhbmdlclBvc2l0aXZlcy5jc3YiLAogICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKbWV0aG9kc0dyYW5nZXJQb3MkVHlwZSA8LSAiR3JhbmdlciIKCiNSTCBQb3NpdGl2ZXMKbWV0aG9kc1JlZyA8LQogIHJlYWQuY3N2KAogICAgIn4vUi9hbmFseXNpcy9tZXRob2RzL2FsbE1ldGhvZHNSZWdyZXNzaW9uLmNzdiIsCiAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCgptZXRob2RzUmVnJFR5cGUgPC0gIkxpbmVhciIKCm1ldGhvZHNSZWckcHZhbHVlIDwtIE5VTEwKCmFsbE1ldGhvZHMgPC0gcmJpbmQobWV0aG9kc0dyYW5nZXJQb3MsIG1ldGhvZHNSZWcpCgojQm94cGxvdHMgR2VyYWw6CmdncGxvdChhbGxNZXRob2RzLCBhZXMoeD1UeXBlLCB5PU50aW1lb2ZDb21taXRzKSkgKyBnZW9tX2JveHBsb3QoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX3hfZGlzY3JldGUobmFtZSA9IkxpbmVhciBSZWcgeCBHcmFuZ2VyIikKCgojVmlvbGluIFBsb3QKd2l0aChhbGxNZXRob2RzLCB2aW9wbG90KE50aW1lb2ZDb21taXRzW1R5cGUgPT0gIkdyYW5nZXIiXSwKICAgICAgICAgICAgICAgICAgICAgIE50aW1lb2ZDb21taXRzW1R5cGUgPT0gIkxpbmVhciJdLAogICAgICAgICAgICAgICAgICAgICAgbmFtZXMgPSBjKCJHcmFuZ2VyIiwgIkxpbmVhciIpLAogICAgICAgICAgICAgICAgICAgICAgY29sID0gImdyYXkiLCBjb2xNZWQgPSByZ2IoMTE1LCAxNjUsIDIxNCwgbWF4Q29sb3JWYWx1ZSA9IDI1NSkpKQp0aXRsZShtYWluID0gIlZpb2xpbiBQbG90IiwgeWxhYiA9ICJOdW1iZXIgb2YgQ29tbWl0cyIsIHhsYWIgPSAiVHlwZSIpCmBgYAoKIyMjIyBSUTM6IFdoaWNoIGtpbmQgb2YgY2hhbmdlcyBhcmUgbW9zdGx5cmVsYXRlZCB0byB0aGUgYnVncyBpbnNlcnRpb24/CgoqIEdyw6FmaWNvIGRlIFBhcmV0byBkZSBNZXRyaWNhcyBJbmRpdmlkdWFpcyBkZSB0b2RvcyBvcyBtw6l0b2RvcyBxdWUgcG9zc3VlbSBidWdzOgoKYGBge3J9CgojSW5kaXZpZHVhbE1ldHJpY3MKY29sTWV0aG9kcyA8LSBjKCJQcm9qZWN0IiwgIk1ldGhvZE5hbWUiLCAiTWV0cmljIiwgImdyb3VwTWV0cmljIiwgImNoYW5nZVR5cGUiICwiUDEiLCAiUDIiLCAiUDMiLCAiUDQiLCAiUDUiLCAiZWxlbWVudHNWYWx1ZSIsICJOdGltZW9mQ29tbWl0cyIsICJDb3VudCIsICJHcmFuZ2VyUG9zIikKCiNyZXN1bHRzQ2xhc3NlcyA8LSBzdWJzZXQoIHJlc3VsdHNDbGFzc2VzLCBzZWxlY3QgPSBjKGNvbENsYXNzZXMpICkKcmVzdWx0c01ldGhvZHMgPC0gc3Vic2V0KCBtZXRob2RzLCBzZWxlY3QgPSBjKGNvbE1ldGhvZHMpICkKCiNGaWx0ZXI6RApyZXN1bHRzTWV0aG9kcyA8LSBmaWx0ZXIocmVzdWx0c01ldGhvZHMsIFAyID09IDEsIGdyb3VwTWV0cmljICE9ICJSTSIpCgojSW5kaXZpZHVhbE1ldHJpY3MKaW5kTWV0cmljczwtCiAgc3FsZGYoCiAgICAiU0VMRUNUIFByb2plY3QsIE1ldHJpYywgU1VNKENvdW50KSBhcyBDaGFuZ2VzCiAgICBGUk9NIHJlc3VsdHNNZXRob2RzCiAgICBXSEVSRSBjaGFuZ2VUeXBlIDw+ICdBbGwnIAogICAgQU5EIGdyb3VwTWV0cmljIDw+J0FsbCcKICAgIEFORCBNZXRyaWMgPD4gJ0FsbCcKICAgIEdST1VQIEJZIFByb2plY3QsIE1ldHJpYyIKICApCgptZXRyaWNzIDwtIGMoKQojIEFwcGx5aW5nIHRoZSBmdW5jdGlvbiB0byB0aGUgcGFyZXRvIGZ1bmN0aW9uOgpmb3IgKHByb2plY3QgaW4gcHJvamVjdHMpewogIGRmIDwtIGZpbHRlcihpbmRNZXRyaWNzLCBQcm9qZWN0ID09IHByb2plY3QpWyxjKDIsMyldCiAgaTwtMQogIGZvciAoeCBpbiAxOm5yb3coZGYpKXsKICAgIGZvciAoeSBpbiAxOmRmJENoYW5nZXNbeF0pewogICAgICBtZXRyaWNzW2ldIDwtIGRmJE1ldHJpY1t4XQogICAgICBpIDwtIGkgKyAxCiAgICB9CiAgfQogIGdncGFyZXRvKG1ldHJpY3MsIHByb2plY3QpCn0KCmBgYAoKKiBHcsOhZmljbyBkZSBQYXJldG8gZGUgTWV0cmljYXMgSW5kaXZpZHVhaXMgZG9zIG1ldG9kb3MgY29tIHJlc3VsdGFkb3MgZG8gdGVzdGUgZGUgR3JhbmdlciBwb3NpdGl2b3M6CgpgYGB7cn0KI0dyb3VwcyBtZXRyaWNzCmdycE1ldHJpY3MgPC0gcmVhZC5jc3YoZmlsZSA9ICJ+L1IvYW5hbHlzaXMvbWV0aG9kcy9kYXRhTWV0cmljc0dyYW5nZXIuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKCm1ldHJpY3MgPC0gYygpCiMgQXBwbHlpbmcgdGhlIGZ1bmN0aW9uIHRvIHRoZSBwYXJldG8gZnVuY3Rpb246CmZvciAocHJvamVjdCBpbiBwcm9qZWN0cyl7CiAgZGYgPC0gZmlsdGVyKGdycE1ldHJpY3MsIFByb2plY3QgPT0gcHJvamVjdClbLGMoMyw0KV0KICBpPC0xCiAgZm9yICh4IGluIDE6bnJvdyhkZikpewogICAgZm9yICh5IGluIDE6ZGYkQ2hhbmdlc1t4XSl7CiAgICAgIG15bGlzdFtpXSA8LSBkZiRNZXRyaWNbeF0KICAgICAgaSA8LSBpICsgMQogICAgfQogIH0KICBnZ3BhcmV0byhteWxpc3QsIHByb2plY3QpCn0KCmBgYAoKCiMjIyBSUTQ6IAoKKiBDaGFuZ2VzIGFvIGxvbmdvIGRvIHRlbXBvIHBvciBwcm9qZXRvczoKCmBgYHtyfQoKZGZRdWFydGlscyA8LSBhcy5kYXRhLmZyYW1lKG1ldGhvZHMgJT4lCiAgZ3JvdXBfYnkoUHJvamVjdCwgdHlwZU1ldGhvZCkgJT4lCiAgc3VtbWFyaXNlKHF1YXJ0aWxlMSA9IHN1bShxdWFydGlsZTEpLCBxdWFydGlsZTIgPSBzdW0ocXVhcnRpbGUyKSwgcXVhcnRpbGUzID0gc3VtKHF1YXJ0aWxlMyksIAogICAgICAgICAgICBxdWFydGlsZTQgPSBzdW0ocXVhcnRpbGU0KSwgcXVhcnRpbGU1ID0gc3VtKHF1YXJ0aWxlNSkpKQoKCnRkZlF1YXJ0aWxzIDwtIG1lbHQoZGZRdWFydGlscywgaWQ9KGMoIlByb2plY3QiLCAidHlwZU1ldGhvZCIpKSkKY29sbmFtZXModGRmUXVhcnRpbHMpIDwtIGMoIlByb2plY3QiLCAidHlwZU1ldGhvZCIsICJRdWFydGlsZXMiLCAiVmFsdWVzIikKCgojU3VtbWFyaXplIHRoZSB0eXBlIG9mIG1ldGhvZHMgYnkgcGVyY2VudHVhbApkZlF1YXJ0aWxzUHJvamVjdHMgPC0gdGRmUXVhcnRpbHMgJT4lCiAgZ3JvdXBfYnkoIFByb2plY3QsIFF1YXJ0aWxlcykgJT4lCiAgc3VtbWFyaXNlKFZhbHVlcyA9IHN1bShWYWx1ZXMpKSAlPiUgCiAgbXV0YXRlKFBlcmNlbnR1YWwgPSBWYWx1ZXMgLyBzdW0oVmFsdWVzKSAqIDEwMCkgJT4lIAogIHVuZ3JvdXAoKQoKI0Ftb3VudAojQ2hhbmdlcyBvdmVyIHRpbWUgYnkgcHJvamVjdHMKICAKZ2dwbG90KGRmUXVhcnRpbHNQcm9qZWN0cykgKwpnZW9tX2JhcihhZXMoeCA9IFF1YXJ0aWxlcywgeSA9IFBlcmNlbnR1YWwsIGZpbGwgPSBQcm9qZWN0LCBncm91cCA9IFByb2plY3QpLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHN0YXQgPSAiaWRlbnRpdHkiKSArCmdlb21fdGV4dChhZXMoeCA9IFF1YXJ0aWxlcywgeSA9IFBlcmNlbnR1YWwsIGxhYmVsID0gcm91bmQoUGVyY2VudHVhbCwyKSwgZ3JvdXAgPSBQcm9qZWN0KSwgIAogICAgICAgICAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwgdmp1c3QgPSAtMC41LCBzaXplID0gMykgKyAgCnRoZW1lKGxlZ2VuZC5kaXJlY3Rpb249InZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT02KSwgCiAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksIGF4aXMudGlja3MueCA9ICkgKwp0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSkpICsgCmdndGl0bGUocGFzdGUwKCJQcm9qZWN0ICIsIHByb2plY3QpKSArIHlsYWIoIlBlcmNlbnR1YWwiKSAKI3NjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jYlBhbGV0dGUpCmBgYAoKKiBNdWRhbsOnYXMgYW8gbG9uZ28gZG8gdGVtcG8gcG9yIHRpcG9zIGRlIG1ldG9kb3M6CgpgYGB7cn0KCiNTdW1tYXJpemUgdGhlIHR5cGUgb2YgbWV0aG9kcyBieSBwZXJjZW50dWFsCmRmUXVhcnRpbHNUeXBlcyA8LSB0ZGZRdWFydGlscyAlPiUKICBncm91cF9ieSggdHlwZU1ldGhvZCwgUXVhcnRpbGVzICkgJT4lCiAgc3VtbWFyaXNlKFZhbHVlcyA9IHN1bShWYWx1ZXMpKSAlPiUgCiAgbXV0YXRlKFBlcmNlbnR1YWwgPSBWYWx1ZXMgLyBzdW0oVmFsdWVzKSAqIDEwMCkgJT4lIAogIHVuZ3JvdXAoKQoKI0NoYW5nZXMgb3ZlciB0aW1lIGJ5IHR5cGVzIG9mIG1ldGhvZHMKZ2dwbG90KGRmUXVhcnRpbHNUeXBlcykgKwogIGdlb21fYmFyKGFlcyh4ID0gUXVhcnRpbGVzLCB5ID0gUGVyY2VudHVhbCwgZmlsbCA9IHR5cGVNZXRob2QsIGdyb3VwID0gdHlwZU1ldGhvZCksIHBvc2l0aW9uID0gImRvZGdlIiwgc3RhdCA9ICJpZGVudGl0eSIpICsKICBnZW9tX3RleHQoYWVzKHggPSBRdWFydGlsZXMsIHkgPSBQZXJjZW50dWFsLCBsYWJlbCA9IHJvdW5kKFBlcmNlbnR1YWwsMiksIGdyb3VwID0gdHlwZU1ldGhvZCksICAKICAgICAgICAgICAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwgdmp1c3QgPSAtMC41LCBzaXplID0gMykgKyAgCiAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbj0idmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpLCBheGlzLnRpY2tzLnggPSApICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpKSArIAogIGdndGl0bGUocGFzdGUwKCJQcm9qZWN0ICIsIHByb2plY3QpKSArIHlsYWIoIlBlcmNlbnR1YWwiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNiUGFsZXR0ZSkKYGBgCgoKKiBQaWNvcyBhbyBsb25nbyBkbyB0ZW1wbyBwb3IgcHJvamV0b3M6IAoKYGBge3J9CgpkZlBlYWtzIDwtIGFzLmRhdGEuZnJhbWUobWV0aG9kcyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoUHJvamVjdCwgdHlwZU1ldGhvZCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShwZWFrc01lZGlhbiA9IHN1bShwZWFrc01lZGlhbiksIHBlYWtzMVNkID0gc3VtKHBlYWtzMVNkKSwgcGVha3MyU2QgPSBzdW0ocGVha3MyU2QpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlYWtzM1NkID0gc3VtKHBlYWtzM1NkKSkpCgoKdGRmUGVha3MgPC0gbWVsdChkZlBlYWtzLCBpZD0oYygiUHJvamVjdCIsICJ0eXBlTWV0aG9kIikpKQpjb2xuYW1lcyh0ZGZQZWFrcykgPC0gYygiUHJvamVjdCIsICJ0eXBlTWV0aG9kIiwgIlBlYWtzIiwgIlZhbHVlcyIpCgoKI1N1bW1hcml6ZSB0aGUgdHlwZSBvZiBtZXRob2RzIGJ5IHBlcmNlbnR1YWwKZGZQZWFrc1Byb2plY3RzIDwtIHRkZlBlYWtzICU+JQogIGdyb3VwX2J5KCBQcm9qZWN0LCBQZWFrcykgJT4lCiAgc3VtbWFyaXNlKFZhbHVlcyA9IHN1bShWYWx1ZXMpKSAlPiUgCiAgbXV0YXRlKFBlcmNlbnR1YWwgPSBWYWx1ZXMgLyBzdW0oVmFsdWVzKSAqIDEwMCkgJT4lIAogIHVuZ3JvdXAoKQoKI0Ftb3VudAojQ2hhbmdlcyBvdmVyIHRpbWUgYnkgcHJvamVjdHMKCmdncGxvdChkZlBlYWtzUHJvamVjdHMpICsKICBnZW9tX2JhcihhZXMoeCA9IFByb2plY3QsIHkgPSBQZXJjZW50dWFsLCBmaWxsID0gUGVha3MsIGdyb3VwID0gUGVha3MpLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgZ2VvbV90ZXh0KGFlcyh4ID0gUHJvamVjdCwgeSA9IFBlcmNlbnR1YWwsIGxhYmVsID0gcm91bmQoUGVyY2VudHVhbCwyKSwgZ3JvdXAgPSBQZWFrcyksICAKICAgICAgICAgICAgY2hlY2tfb3ZlcmxhcCA9IFRSVUUsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwgdmp1c3QgPSAtMC41LCBzaXplID0gMykgKyAgCiAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbj0idmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTYpLCAKICAgICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpLCBheGlzLnRpY2tzLnggPSApICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IiwgY29sb3VyID0gTkEpKSArIAogIGdndGl0bGUocGFzdGUwKCJQcm9qZWN0ICIsIHByb2plY3QpKSArIHlsYWIoIlBlcmNlbnR1YWwiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNiUGFsZXR0ZSkKCmBgYAoKKiBQaWNvcyBhbyBsb25nbyBkbyB0ZW1wbyBwb3IgdGlwb3MgZGUgbWV0b2RvczoKCmBgYHtyfQpkZlBlYWtzVHlwZXMgPC0gdGRmUGVha3MgJT4lCiAgZ3JvdXBfYnkoIHR5cGVNZXRob2QsIFBlYWtzICkgJT4lCiAgc3VtbWFyaXNlKFZhbHVlcyA9IHN1bShWYWx1ZXMpKSAlPiUgCiAgbXV0YXRlKFBlcmNlbnR1YWwgPSBWYWx1ZXMgLyBzdW0oVmFsdWVzKSAqIDEwMCkgJT4lIAogIHVuZ3JvdXAoKQoKI0NoYW5nZXMgb3ZlciB0aW1lIGJ5IHR5cGVzIG9mIG1ldGhvZHMKZ2dwbG90KGRmUGVha3NUeXBlcykgKwogIGdlb21fYmFyKGFlcyh4ID0gdHlwZU1ldGhvZCwgeSA9IFBlcmNlbnR1YWwsIGZpbGwgPSBQZWFrcywgZ3JvdXAgPSBQZWFrcyksIHBvc2l0aW9uID0gImRvZGdlIiwgc3RhdCA9ICJpZGVudGl0eSIpICsKICBnZW9tX3RleHQoYWVzKHggPSB0eXBlTWV0aG9kLCB5ID0gUGVyY2VudHVhbCwgbGFiZWwgPSByb3VuZChQZXJjZW50dWFsLDIpLCBncm91cCA9IFBlYWtzKSwgIAogICAgICAgICAgICBjaGVja19vdmVybGFwID0gVFJVRSwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLCB2anVzdCA9IC0wLjUsIHNpemUgPSAzKSArICAKICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uPSJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9NiksIAogICAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSksIGF4aXMudGlja3MueCA9ICkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAidHJhbnNwYXJlbnQiLCBjb2xvdXIgPSBOQSkpICsgCiAgZ2d0aXRsZShwYXN0ZTAoIlByb2plY3QgIiwgcHJvamVjdCkpICsgeWxhYigiUGVyY2VudHVhbCIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWNiUGFsZXR0ZSkKYGBgCgo=