Extract model params

library(MplusAutomation)
# function for table with all params from DSEM models, 2months and one year
# mplodelnames: names of models for single events (situations) to fill the table with; adds1models: names of additional models for single events (situations) to fill the table with, if second model no confidence intervals; tablenames: names of columns, orders = rownames of  parameters of interest that should be extracted from mplus output; params: rownames/names of parameters for table; html: Output table in html; logtransparams: calculate betas for moodxevent based on hamaker and olivoto procedure; predtable: is it a table with prediction using between person independent variables or is it just within; noconf: no confidence intervals
table2func = function(mplodelnames,
                      adds1models = NA,
                      tablenames,
                      orders,
                      orders1,
                      params = NA ,
                      html = T,
                      logtransparams = F,
                      predtable = F,
                      noconf = NA) {
  if (length(adds1models) == 1) {
    # read mplus model
    mplodel = readModels(target = mplodelnames[1])
    #extract std params
    stdout = mplodel$parameters$stdyx.standardized
    #delete unnecessary rows
    stdout = stdout[-grep("esidual", stdout$paramHeader) , ]
    stdout = stdout[-grep("ntercept", stdout$paramHeader) , ]
    rownames(stdout) = 1:dim(stdout)[1]
    temp = stdout
    # reorder within, between, pred and extract only variables we are interested in
    stdout = stdout[orders, ]
    # check available N after removal of cases wo variance and or
    nocases = unlist(regmatches(unlist(mplodel$warnings), gregexpr('[0-9]+', unlist(
      mplodel$warnings
    ))))
    nocases = nocases[nchar(nocases) > 1]
    N = mplodel$data_summary$overall$NClusters - length(nocases)
    # create table
    table2 = stdout[, c("paramHeader", "est")]
    names(table2) = c("param", paste0(tablenames[1], " N=", N, "<br> stdyx."))
    if (length(is.na(params)) == 1) {
      #put params
      table2$param = paste(stdout$paramHeader, stdout$param)
    } else{
      table2$param = params
    }
    # create table with boldness when nonoverlapping ci
    if (predtable == T) {
      tablebolds = table2
      tablebolds[, 2] = FALSE
      # bold for non-overlapping PF and Dep conf int
      i = 1
      while (i < dim(stdout)[1]) {
        a1 = stdout$lower_2.5ci[i]
        a2 = stdout$upper_2.5ci[i]
        b1 = stdout$lower_2.5ci[i + 1]
        b2 = stdout$upper_2.5ci[i + 1]
        if (!((a1 <= b2) && (b1 <= a2))) {
          tablebolds[i, 2] = T
          tablebolds[i + 1, 2] = T
        }
        i = i + 2
      }
    } else{
      tablebolds = table2
      tablebolds[, 2:ncol(tablebolds)] = F
    }
    if (logtransparams == T) {
      #old procedure
      #  rawout =  mplodel$parameters$unstandardized
      # rawout = rawout[grep("ntercept",rawout$paramHeader) ,]
      # # exchange m_s, miv or siv params with log-backtransformed values from raw output
      # rawout = rawout[rawout$param %in% c("MIV","SIV","M_S"),]
      # stdout[grep("M_S_LV", stdout$param),"est"] = exp(rawout$est[rawout$param == "M_S"]) / (sqrt(exp(rawout$est[rawout$param == "MIV"])+exp(rawout$est[rawout$param == "M_S"]))*sqrt(exp(rawout$est[rawout$param == "SIV"])+exp(rawout$est[rawout$param == "M_S"])))
      # # if negative loading
      # if(temp < 0){stdout[grep("M_S_LV", stdout$param),"est"] = stdout[grep("M_S_LV", stdout$param),"est"] *-1}
      ###### procedure advised by Ellen Hamaker  #######
      # unique part of residual variances
      loadm =   temp[temp$paramHeader == "M_S_LV.BY", "est"][1]
      loads =  temp[temp$paramHeader == "M_S_LV.BY", "est"][2]
      # covariance between residual variances
      covms = loads * loadm
      # residual variances
      varresidm = temp[temp$paramHeader == "MIV.|", "est"] + loadm ^ 2
      varresids = temp[temp$paramHeader == "SIV.|", "est"] + loads ^ 2
      # correlation = cov / sqrt(varresidm * varresids)
      stdout[grep("M_S_LV", stdout$param), "est"] = covms / sqrt(varresidm * varresids)
      #confidence interval according to Olivoto et al. (2018)
      CI = (abs(stdout[grep("M_S_LV", stdout$param), "est"]) ^ .3) * 2.25152 * (N ^ -0.50089)
      stdout[grep("M_S_LV", stdout$param), "lower_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] - CI
      stdout[grep("M_S_LV", stdout$param), "upper_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] + CI
      # stdout[grep("SIV.", stdout$paramHeader),"est"] =exp(rawout$est[rawout$param == "SIV"])
      # stdout[grep("SIV.", stdout$paramHeader),"lower_2.5ci"] =exp(rawout$lower_2.5ci[rawout$param == "SIV"])
      # stdout[grep("SIV.", stdout$paramHeader),"upper_2.5ci"] =exp(rawout$upper_2.5ci[rawout$param == "SIV"])
      # if("&pi;m" %in% table2$param){
      #  stdout[grep("MIV.", stdout$paramHeader),"est"] =exp(rawout$est[rawout$param == "MIV"])
      #  stdout[grep("MIV.", stdout$paramHeader),"lower_2.5ci"] =exp(rawout$lower_2.5ci[rawout$param == "MIV"])
      # stdout[grep("MIV.", stdout$paramHeader),"upper_2.5ci"] =exp(rawout$upper_2.5ci[rawout$param == "MIV"])
      # }
    }
    
    # create noconf boolean
    if(length(noconf) == 1){ if(sum(is.na(noconf)) > 0) {noconf = rep(F,length(orders))} else if(noconf){noconf = rep(T,length(orders))}} 
  if (html == T){
        table2[!noconf, 2] = paste0(
          "<span style=\"",
          ifelse(stdout$pval[!noconf] < .005, yes = "font-weight: bold;", no = ";"),
          "\" >",
          round(stdout$est[!noconf], digits = 2),
          " <br> [",
          round(stdout$lower_2.5ci[!noconf], digits = 2),
          " ",
          round(stdout$upper_2.5ci[!noconf], digits = 2),
          "]</span>"
        )}
       if (html == F) {
        table2[!noconf, 2] = ifelse(
          stdout$pval < .005,
          yes = paste0(
            round(stdout$est[!noconf], digits = 2),
            " <br> [",
            round(stdout$lower_2.5ci[!noconf], digits = 2),
            " ",
            round(stdout$upper_2.5ci[!noconf], digits = 2),
            "]"
          ),
          no = ""
        )
      }
   
      table2[noconf, 2] = paste0(
        "<span style=\"",
        ifelse(stdout$pval[noconf] < .005, yes = "font-weight: bold;", no = ";"),
        "\" >",
        round(stdout$est[noconf], digits = 2),
        "</span>"
      )
    if (html == F) {
      table2[noconf, 2] = ifelse(stdout$pval[noconf] < .005, yes = paste0(round(stdout$est[noconf], digits = 2)), no = "")
    }
    #
    # table2[,2] = paste0("<span style=\"", ifelse(stdout$pval <.005,yes = "font-weight: bold; display:block;width:100%;background-color:yellow;", no = "display:block;width:100%;background-color:yellow;"),   "\" >",round(stdout$est,digits = 2)," <br> [",round(stdout$lower_2.5ci,digits = 2)," ",round(stdout$upper_2.5ci,digits = 2),"]</span>")
    #
    # table2[,2]= paste(round(stdout$est,digits = 2),paste0("<br>[",round(stdout$lower_2.5ci,digits = 2), " ",round(stdout$upper_2.5ci,digits = 2),"]"))
    # make table with significance
    table2p = table2[, 1:2]
    names(table2p)[2] = tablenames[1]
    table2p[, 2] = stdout$pval
    # make table with regressionweight
    table2r = table2[, 1:2]
    names(table2r)[2] = tablenames[1]
    table2r[, 2] = stdout$est
    # make table with all models
    for (i in 2:length(mplodelnames)) {
      # read mplus model
      mplodel = MplusAutomation::readModels(mplodelnames[i])
      #extract unstd params for miv, siv, m_e
      #extract std params
      stdout = mplodel$parameters$stdyx.standardized
      #delete unnecessary rows
      stdout = stdout[-grep("esidual", stdout$paramHeader) , ]
      stdout = stdout[-grep("ntercept", stdout$paramHeader) , ]
      rownames(stdout) = 1:dim(stdout)[1]
      temp = stdout
      # reorder within, between, pred
      stdout = stdout[orders, ]
      # check available N after removal of cases wo variance and or
      nocases = unlist(regmatches(unlist(mplodel$warnings), gregexpr(
        '[0-9]+', unlist(mplodel$warnings)
      )))
      nocases = nocases[nchar(nocases) > 1]
      N = mplodel$data_summary$overall$NClusters - length(nocases)
      if (logtransparams == T) {
        ###### procedure advised by Ellen Hamaker  #######
        # unique part of residual variances
        loadm =   temp[temp$paramHeader == "M_S_LV.BY", "est"][1]
        loads =  temp[temp$paramHeader == "M_S_LV.BY", "est"][2]
        # covariance between residual variances
        covms = loads * loadm
        # residual variances
        varresidm = temp[temp$paramHeader == "MIV.|", "est"] + loadm ^ 2
        varresids = temp[temp$paramHeader == "SIV.|", "est"] + loads ^ 2
        # correlation = cov / sqrt(varresidm * varresids)
        stdout[grep("M_S_LV", stdout$param), "est"] = covms / sqrt(varresidm * varresids)
        #confidence interval according to Olivoto et al. (2018)
        CI = (abs(stdout[grep("M_S_LV", stdout$param), "est"]) ^ .3) * 2.25152 * (N ^ -0.50089)
        stdout[grep("M_S_LV", stdout$param), "lower_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] - CI
        stdout[grep("M_S_LV", stdout$param), "upper_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] + CI
      }
      #put params
      #table2$param = paste(stdout$paramHeader, stdout$param)
        table2[!noconf, i + 1] = paste0(
          "<span style=\"",
          ifelse(stdout$pval[!noconf] < .005, yes = "font-weight: bold;", no = ";"),
          "\" >",
          round(stdout$est[!noconf], digits = 2),
          " <br> [",
          round(stdout$lower_2.5ci[!noconf], digits = 2),
          " ",
          round(stdout$upper_2.5ci[!noconf], digits = 2),
          "]</span>"
        )
       if (html == F) {
        table2[!noconf, i + 1] = ifelse(
          stdout$pval[!noconf] < .005,
          yes = paste0(
            round(stdout$est[!noconf], digits = 2),
            " <br> [",
            round(stdout$lower_2.5ci[!noconf], digits = 2),
            " ",
            round(stdout$upper_2.5ci[!noconf], digits = 2),
            "]"
          ),
          no = ""
        )
      }
   
      table2[noconf, i + 1] = paste0(
        "<span style=\"",
        ifelse(stdout$pval[noconf] < .005, yes = "font-weight: bold;", no = ";"),
        "\" >",
        round(stdout$est[noconf], digits = 2),
        "</span>"
      )
    if (html == F) {
      table2[noconf, i + 1] = ifelse(stdout$pval[noconf] < .005, yes = paste0(round(stdout$est[noconf], digits = 2)), no = "")
    }
      names(table2)[i + 1] = paste0(tablenames[i], " N=", N, "<br> stdyx.")
      # create table with boldness when nonoverlapping ci
      if (predtable == T) {
        # bold for non-overlapping PF and Dep conf int
        tablebolds[, i + 1] = FALSE
        d = 1
        while (d < dim(stdout)[1]) {
          a1 = stdout$lower_2.5ci[d]
          a2 = stdout$upper_2.5ci[d]
          b1 = stdout$lower_2.5ci[d + 1]
          b2 = stdout$upper_2.5ci[d + 1]
          if (!((a1 <= b2) && (b1 <= a2))) {
            tablebolds[d, i + 1] = T
            tablebolds[d + 1, i + 1] = T
          }
          d = d + 2
        }
      } else{
        tablebolds[, i + 1] = FALSE
      }
      # put in table with significance
      table2p[, i + 1] = stdout$pval
      names(table2p)[i + 1] = tablenames[i]
      # put in table with regression
      table2r[, i + 1] = stdout$est
      names(table2r)[i + 1] = tablenames[i]
    }
    rownames(table2) = NULL
    rownames(table2p) = NULL
    rownames(table2r) = NULL
  } else {
    
    
    #####################################################################################################
    #put results of two models in one cell
    # read mplus model
    mplodel = readModels(target = mplodelnames[1])
    #extract std params
    stdout = mplodel$parameters$stdyx.standardized
    # take unstandardized if std is not available
    if (is.null(stdout)) {
      stdout = mplodel$parameters$unstandardized
      # large p value for unstandardized so that it gets marked in final table
      stdout$pval = 1
    }
    #delete unnecessary rows
    stdout = stdout[-grep("esidual", stdout$paramHeader) , ]
    stdout = stdout[-grep("ntercept", stdout$paramHeader) , ]
    rownames(stdout) = 1:dim(stdout)[1]
    # for mxe calc
    temp = stdout
    # reorder within, between, pred and extract only variables we are interested in
    stdout = stdout[orders, ]
    if (length(adds1models) > 1) {
      # read additional S1 model
      # read mplus model
      adds1model = readModels(target = adds1models[1])
      #extract std params
      stdouts1 = adds1model$parameters$stdyx.standardized
      # take unstandardized if std is not available
      if (is.null(stdouts1)) {
        stdouts1 = adds1model$parameters$unstandardized
        # large p value for unstandardized so that it gets marked in final table
        stdouts1$pval = 1
        # stdouts1 = stdout
        # stdouts1[,3:ncol(stdouts1)] = NA
      }
      #delete unnecessary rows
      stdouts1 = stdouts1[-grep("esidual", stdouts1$paramHeader) , ]
      stdouts1 = stdouts1[-grep("ntercept", stdouts1$paramHeader) , ]
      rownames(stdouts1) = 1:dim(stdouts1)[1]
      # for mxe calc
      temps1 = stdouts1
      # reorder within, between, pred and extract only variables we are interested in
      stdouts1 = stdouts1[orders1, ]
    }
    # check available N after removal of cases wo variance and or
    nocases = unlist(regmatches(unlist(mplodel$warnings), gregexpr('[0-9]+', unlist(
      mplodel$warnings
    ))))
    nocases = nocases[nchar(nocases) > 1]
    N = mplodel$data_summary$overall$NClusters - length(nocases)
    # create table
    table2 = stdout[, c("paramHeader", "est")]
    names(table2) = c("param", paste0(tablenames[1], " N=", N, "<br> stdyx."))
    if (length(is.na(params)) == 1) {
      #put params
      table2$param = paste(stdout$paramHeader, stdout$param)
    } else{
      table2$param = params
    }
    # create table with boldness when nonoverlapping ci
    if (predtable == T) {
      tablebolds = table2
      tablebolds[, 2] = FALSE
      # bold for non-overlapping PF and Dep conf int
      i = 1
      while (i < dim(stdout)[1]) {
        a1 = stdout$lower_2.5ci[i]
        a2 = stdout$upper_2.5ci[i]
        b1 = stdout$lower_2.5ci[i + 1]
        b2 = stdout$upper_2.5ci[i + 1]
        if (!((a1 <= b2) && (b1 <= a2))) {
          tablebolds[i, 2] = T
          tablebolds[i + 1, 2] = T
        }
        i = i + 2
      }
    } else{
      tablebolds = table2
      tablebolds[, 2:ncol(tablebolds)] = F
    }
    if (logtransparams == T) {
      #old procedure
      #  rawout =  mplodel$parameters$unstandardized
      # rawout = rawout[grep("ntercept",rawout$paramHeader) ,]
      # # exchange m_s, miv or siv params with log-backtransformed values from raw output
      # rawout = rawout[rawout$param %in% c("MIV","SIV","M_S"),]
      # stdout[grep("M_S_LV", stdout$param),"est"] = exp(rawout$est[rawout$param == "M_S"]) / (sqrt(exp(rawout$est[rawout$param == "MIV"])+exp(rawout$est[rawout$param == "M_S"]))*sqrt(exp(rawout$est[rawout$param == "SIV"])+exp(rawout$est[rawout$param == "M_S"])))
      # # if negative loading
      # if(temp < 0){stdout[grep("M_S_LV", stdout$param),"est"] = stdout[grep("M_S_LV", stdout$param),"est"] *-1}
      ###### procedure advised by Ellen Hamaker  #######
      # unique part of residual variances
      loadm =   temp[temp$paramHeader == "M_S_LV.BY", "est"][1]
      loads =  temp[temp$paramHeader == "M_S_LV.BY", "est"][2]
      # covariance between residual variances
      covms = loads * loadm
      # residual variances
      varresidm = temp[temp$paramHeader == "MIV.|", "est"] + loadm ^ 2
      varresids = temp[temp$paramHeader == "SIV.|", "est"] + loads ^ 2
      # correlation = cov / sqrt(varresidm * varresids)
      stdout[grep("M_S_LV", stdout$param), "est"] = covms / sqrt(varresidm * varresids)
      #confidence interval according to Olivoto et al. (2018)
      CI = (abs(stdout[grep("M_S_LV", stdout$param), "est"]) ^ .3) * 2.25152 * (N ^ -0.50089)
      stdout[grep("M_S_LV", stdout$param), "lower_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] - CI
      stdout[grep("M_S_LV", stdout$param), "upper_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] + CI
      # stdout[grep("SIV.", stdout$paramHeader),"est"] =exp(rawout$est[rawout$param == "SIV"])
      # stdout[grep("SIV.", stdout$paramHeader),"lower_2.5ci"] =exp(rawout$lower_2.5ci[rawout$param == "SIV"])
      # stdout[grep("SIV.", stdout$paramHeader),"upper_2.5ci"] =exp(rawout$upper_2.5ci[rawout$param == "SIV"])
      # if("&pi;m" %in% table2$param){
      #  stdout[grep("MIV.", stdout$paramHeader),"est"] =exp(rawout$est[rawout$param == "MIV"])
      #  stdout[grep("MIV.", stdout$paramHeader),"lower_2.5ci"] =exp(rawout$lower_2.5ci[rawout$param == "MIV"])
      # stdout[grep("MIV.", stdout$paramHeader),"upper_2.5ci"] =exp(rawout$upper_2.5ci[rawout$param == "MIV"])
      # }
      # also for additional s1
      if (length(adds1models) > 1) {
        ###### procedure advised by Ellen Hamaker  #######
        # unique part of residual variances
        loadm =   temps1[temps1$paramHeader == "M_S_LV.BY", "est"][1]
        loads =  temps1[temps1$paramHeader == "M_S_LV.BY", "est"][2]
        # covariance between residual variances
        covms = loads * loadm
        # residual variances
        varresidm = temps1[temps1$paramHeader == "MIV.|", "est"] + loadm ^ 2
        varresids = temps1[temps1$paramHeader == "SIV.|", "est"] + loads ^ 2
        # correlation = cov / sqrt(varresidm * varresids)
        stdouts1[grep("M_S_LV", stdouts1$param), "est"] = covms / sqrt(varresidm * varresids)
        #confidence interval according to Olivoto et al. (2018)
        CI = (abs(stdouts1[grep("M_S_LV", stdouts1$param), "est"]) ^ .3) * 2.25152 * (N ^ -0.50089)
        stdouts1[grep("M_S_LV", stdouts1$param), "lower_2.5ci"] = stdouts1[grep("M_S_LV", stdouts1$param), "est"] - CI
        stdouts1[grep("M_S_LV", stdouts1$param), "upper_2.5ci"] = stdouts1[grep("M_S_LV", stdouts1$param), "est"] + CI
      }
    }
   # create noconf boolean
 if(length(noconf) == 1){ if(sum(is.na(noconf)) > 0) {noconf = rep(F,length(orders))} else if(noconf){noconf = rep(T,length(orders))}} 
if (html == T) {
 table2[!noconf, 2] = paste0(
    "<span style=\"",
    ifelse(stdout$pval[!noconf] < .005 & stdouts1$pval[!noconf] < .005, yes = "font-weight: bold;", no = ";"),
    "\" >",
    round(rowMeans(cbind(stdout$est[!noconf],stdouts1$est[!noconf])), digits = 2),
    " <br> [",
    round(rowMeans(cbind(stdout$lower_2.5ci[!noconf],stdouts1$lower_2.5ci[!noconf])), digits = 2),
    " ",
    round(rowMeans(cbind(stdout$upper_2.5ci[!noconf],stdouts1$upper_2.5ci[!noconf])), digits = 2),
    "]</span>"
)}
if (html == F) {
    table2[!noconf, 2] = ifelse(
        stdout$pval[!noconf] < .005 & stdouts1$pval[!noconf] < .005,
        yes = paste0(
            round(rowMeans(cbind(stdout$est[!noconf],stdouts1$est[!noconf])), digits = 2),
            " [",
            round(rowMeans(cbind(stdout$lower_2.5ci[!noconf],stdouts1$lower_2.5ci[!noconf])), digits = 2),
            " ",
            round(rowMeans(cbind(stdout$upper_2.5ci[!noconf],stdouts1$upper_2.5ci[!noconf])), digits = 2),
            "]"
        ),
        no = ""
    )
}
# 
# table2[noconf, 2] = paste0(
#     "<span style=\"",
#     ifelse(stdout$pval < .005, yes = "font-weight: bold;", no = ";"),
#     "\" >",
#     round(rowMeans(cbind(stdout$est,stdouts1$est)), digits = 2),
#     "</span>"
# )
# if (html == F) {
#     table2[noconf, 2] = ifelse(stdout$pval < .005, yes = paste0(round(rowMeans(cbind(stdout$est,stdouts1$est)), digits = 2)), no = "")
# }
    
    # if cells without confidence interval then use estimates of the two S-1 models in these cells
    if(sum(noconf) > 0){
    if (html == T) {
      table2[noconf, 2] = paste0(
        "<span style=\"",
        ifelse(stdout$pval[noconf] < .005 & stdouts1$pval[noconf] < .005 & !((pmin(stdout$est[noconf], stdouts1$est[noconf]) <= 0) & (0 <= pmax(stdout$est[noconf], stdouts1$est[noconf]))) , yes = "font-weight: bold;", no = ";"),
        "\" >",
        ifelse(!(pmin(stdout$est[noconf], stdouts1$est[noconf]) <= 0) & (0 <= pmax(stdout$est[noconf], stdouts1$est[noconf])), yes = "<b>", no = ""),
        round(rowMeans(cbind(stdout$est[noconf], stdouts1$est[noconf]), na.rm = T), digits = 2),
        "</b><br> [",
        ifelse(stdout$pval[noconf] < .005, yes = "<b>", no = ""),
        round(stdout$est[noconf], digits = 2),
        " ",
        ifelse(stdouts1$pval[noconf] < .005, yes = "</b><b>", no = "</b>"),
        round(stdouts1$est[noconf], digits = 2),
        "</b>]",
        "</span>"
      )}
    if (html == F) {
      table2[noconf, 2] = ifelse(stdout$pval[noconf] < .005, yes = paste0(round(rowMeans(cbind(stdout$est[noconf], stdouts1$est[noconf]), na.rm = T), digits = 2)), no = "")
    }
    }
    #
    # table2[,2] = paste0("<span style=\"", ifelse(stdout$pval <.005,yes = "font-weight: bold; display:block;width:100%;background-color:yellow;", no = "display:block;width:100%;background-color:yellow;"),   "\" >",round(stdout$est,digits = 2)," <br> [",round(stdout$lower_2.5ci,digits = 2)," ",round(stdout$upper_2.5ci,digits = 2),"]</span>")
    #
    # table2[,2]= paste(round(stdout$est,digits = 2),paste0("<br>[",round(stdout$lower_2.5ci,digits = 2), " ",round(stdout$upper_2.5ci,digits = 2),"]"))
    # make table with significance
    table2p = table2[, 1:2]
    names(table2p)[2] = tablenames[1]
    table2p[, 2] = apply(cbind(stdout$pval, stdouts1$pval), 1, function (x)
      max(x, na.rm = T))
    # make table with regressionweight
    table2r = table2[, 1:2]
    names(table2r)[2] = tablenames[1]
    table2r[, 2] = rowMeans(cbind(stdout$est, stdouts1$est), na.rm = T)
    # make table with all models
    for (i in 2:length(mplodelnames)) {
      # read mplus model
      mplodel = readModels(target = mplodelnames[i])
      #extract std params
      stdout = mplodel$parameters$stdyx.standardized
      # take unstandardized if std is not available
      if (is.null(stdout)) {
        stdout = mplodel$parameters$unstandardized
        # large p value for unstandardized so that it gets marked in final table
        stdout$pval = 1
        stdout$lower_2.5ci = -1
        stdout$upper_2.5ci = 1
      }
      #delete unnecessary rows
      stdout = stdout[-grep("esidual", stdout$paramHeader) , ]
      stdout = stdout[-grep("ntercept", stdout$paramHeader) , ]
      rownames(stdout) = 1:dim(stdout)[1]
      # for mxe calc
      temp = stdout
      # reorder within, between, pred and extract only variables we are interested in
      stdout = stdout[orders, ]
      if (length(adds1models) > 1) {
        # read additional S1 model
        # read mplus model
        adds1model = readModels(target = adds1models[i])
        #extract std params
        stdouts1 = adds1model$parameters$stdyx.standardized
        # take unstandardized if std is not available
        if (is.null(stdouts1)) {
          stdouts1 = adds1model$parameters$unstandardized
          # large p value for unstandardized so that it gets marked in final table
          stdouts1$pval = 1
          stdouts1$lower_2.5ci = -1
          stdouts1$upper_2.5ci = 1
          # stdouts1 = stdout
          # stdouts1[,3:ncol(stdouts1)] = NA
        }
        #delete unnecessary rows
        stdouts1 = stdouts1[-grep("esidual", stdouts1$paramHeader) , ]
        stdouts1 = stdouts1[-grep("ntercept", stdouts1$paramHeader) , ]
        rownames(stdouts1) = 1:dim(stdouts1)[1]
        # for mxe calc
        temps1 = stdouts1
        # reorder within, between, pred and extract only variables we are interested in
        stdouts1 = stdouts1[orders1, ]
      }
      # check available N after removal of cases wo variance and or
      nocases = unlist(regmatches(unlist(mplodel$warnings), gregexpr(
        '[0-9]+', unlist(mplodel$warnings)
      )))
      nocases = nocases[nchar(nocases) > 1]
      N = mplodel$data_summary$overall$NClusters - length(nocases)
      if (logtransparams == T) {
        ###### procedure advised by Ellen Hamaker  #######
        # unique part of residual variances
        loadm =   temp[temp$paramHeader == "M_S_LV.BY", "est"][1]
        loads =  temp[temp$paramHeader == "M_S_LV.BY", "est"][2]
        # covariance between residual variances
        covms = loads * loadm
        # residual variances
        varresidm = temp[temp$paramHeader == "MIV.|", "est"] + loadm ^ 2
        varresids = temp[temp$paramHeader == "SIV.|", "est"] + loads ^ 2
        # correlation = cov / sqrt(varresidm * varresids)
        stdout[grep("M_S_LV", stdout$param), "est"] = covms / sqrt(varresidm * varresids)
        #confidence interval according to Olivoto et al. (2018)
        CI = (abs(stdout[grep("M_S_LV", stdout$param), "est"]) ^ .3) * 2.25152 * (N ^ -0.50089)
        stdout[grep("M_S_LV", stdout$param), "lower_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] - CI
        stdout[grep("M_S_LV", stdout$param), "upper_2.5ci"] = stdout[grep("M_S_LV", stdout$param), "est"] + CI
        # also for additional s1
        if (length(adds1models) > 1) {
          ###### procedure advised by Ellen Hamaker  #######
          # unique part of residual variances
          loadm =   temps1[temps1$paramHeader == "M_S_LV.BY", "est"][1]
          loads =  temps1[temps1$paramHeader == "M_S_LV.BY", "est"][2]
          # covariance between residual variances
          covms = loads * loadm
          # residual variances
          varresidm = temps1[temps1$paramHeader == "MIV.|", "est"] + loadm ^ 2
          varresids = temps1[temps1$paramHeader == "SIV.|", "est"] + loads ^ 2
          # correlation = cov / sqrt(varresidm * varresids)
          stdouts1[grep("M_S_LV", stdouts1$param), "est"] = covms / sqrt(varresidm * varresids)
          #confidence interval according to Olivoto et al. (2018)
          CI = (abs(stdouts1[grep("M_S_LV", stdouts1$param), "est"]) ^ .3) * 2.25152 * (N ^ -0.50089)
          stdouts1[grep("M_S_LV", stdouts1$param), "lower_2.5ci"] = stdouts1[grep("M_S_LV", stdouts1$param), "est"] - CI
          stdouts1[grep("M_S_LV", stdouts1$param), "upper_2.5ci"] = stdouts1[grep("M_S_LV", stdouts1$param), "est"] + CI
        }
      }
      
#if there are cells with confints
  if(sum(!noconf)>0){
      
      if (html == T) {
      #put params
      table2[!noconf, i+1] = paste0(
    "<span style=\"",
    ifelse(stdout$pval[!noconf] < .005 & stdouts1$pval[!noconf] < .005, yes = "font-weight: bold;", no = ";"),
    "\" >",
    round(rowMeans(cbind(stdout$est,stdouts1$est))[!noconf], digits = 2),
    " <br> [",
    round(rowMeans(cbind(stdout$lower_2.5ci,stdouts1$lower_2.5ci))[!noconf], digits = 2),
    " ",
    round(rowMeans(cbind(stdout$upper_2.5ci,stdouts1$upper_2.5ci))[!noconf], digits = 2),
    "]</span>"
)}
if (html == F) {
    table2[!noconf, i +1] = ifelse(
        stdout$pval[!noconf] < .005 & stdouts1$pval[!noconf] < .005,
        yes = paste0(
            round(rowMeans(cbind(stdout$est,stdouts1$est))[!noconf], digits = 2),
            " <br> [",
            round(rowMeans(cbind(stdout$lower_2.5ci,stdouts1$lower_2.5ci))[!noconf], digits = 2),
            " ",
            round(rowMeans(cbind(stdout$upper_2.5ci,stdouts1$upper_2.5ci))[!noconf], digits = 2),
            "]"
        ),
        no = ""
    )
}}
# 
# table2[noconf, i +1] = paste0(
#     "<span style=\"",
#     ifelse(stdout$pval < .005, yes = "font-weight: bold;", no = ";"),
#     "\" >",
#     round(rowMeans(cbind(stdout$est,stdouts1$est)), digits = 2),
#     "</span>"
# )
# if (html == F) {
#     table2[noconf, 2] = ifelse(stdout$pval < .005, yes = paste0(round(rowMeans(cbind(stdout$est,stdouts1$est)), digits = 2)), no = "")
# }
      
  # if cells without confint use estimates from the two S-1 models    
   if(sum(noconf) > 0){
     if (html == T) {
      table2[noconf, i +1] = paste0(
        "<span style=\"",
        ifelse(stdout$pval[noconf] < .005 & stdouts1$pval[noconf] < .005 & !((pmin(stdout$est[noconf], stdouts1$est[noconf]) <= 0) & (0 <= pmax(stdout$est[noconf], stdouts1$est[noconf]))) , yes = "font-weight: bold;", no = ";"),
        "\" >",
        ifelse(!(pmin(stdout$est[noconf], stdouts1$est[noconf]) <= 0) & (0 <= pmax(stdout$est[noconf], stdouts1$est[noconf])), yes = "<b>", no = ""),
        round(rowMeans(cbind(stdout$est, stdouts1$est), na.rm = T)[noconf], digits = 2),
        "</b><br> [",
        ifelse(stdout$pval[noconf] < .005, yes = "<b>", no = ""),
        round(stdout$est[noconf], digits = 2),
        " ",
        ifelse(stdouts1$pval[noconf] < .005, yes = "</b><b>", no = "</b>"),
        round(stdouts1$est[noconf], digits = 2),
        "</b>]",
        "</span>"
      )}
    if (html == F) {
      table2[noconf, i +1] = ifelse(stdout$pval[noconf] < .005 & stdouts1$pval[noconf] < .005 & !((pmin(stdout$est[noconf], stdouts1$est[noconf]) <= 0) & (0 <= pmax(stdout$est[noconf], stdouts1$est[noconf]))),
                                    yes = paste0(round(rowMeans(cbind(stdout$est, stdouts1$est), na.rm = T)[noconf], digits = 2)), no = "")
    }}
      names(table2)[i + 1] = paste0(tablenames[i], " N=", N, "<br> stdyx.")
      # create table with boldness when nonoverlapping ci
      if (predtable == T) {
        # bold for non-overlapping PF and Dep conf int
        tablebolds[, i + 1] = FALSE
        d = 1
        while (d < dim(stdout)[1]) {
          a1 = stdout$lower_2.5ci[d]
          a2 = stdout$upper_2.5ci[d]
          b1 = stdout$lower_2.5ci[d + 1]
          b2 = stdout$upper_2.5ci[d + 1]
          if (!((a1 <= b2) && (b1 <= a2))) {
            tablebolds[d, i + 1] = T
            tablebolds[d + 1, i + 1] = T
          }
          d = d + 2
        }
      } else{
        tablebolds[, i + 1] = FALSE
      }
      # put in table with significance
      table2p[, i + 1] = apply(cbind(stdout$pval, stdouts1$pval), 1, function (x)
        max(x, na.rm = T))
      names(table2p)[i + 1] = tablenames[i]
      # put in table with regression
      table2r[, i + 1] = rowMeans(cbind(stdout$est, stdouts1$est), na.rm = T)
      names(table2r)[i + 1] = tablenames[i]
    }
    rownames(table2) = NULL
    rownames(table2p) = NULL
    rownames(table2r) = NULL
  }
  return(list(table2, table2p, table2r, tablebolds))
}

Tables



## within table dscrete situations without mood
table = table2func(mplodelnames = c("ModNoOutS1PFsit_ncnf.out","ModNoOutS1PFsit_nemp.out","ModNoOutS1PFsit_novl.out","ModNoOutS1PFsit_prel.out","ModNoOutS1PFsit_psuc.out","ModNoOutS1PFsit_pwo.out"), tablenames = c("conflict","emptiness or boredom","overwhelming <br> task","relaxation","achievement","good time with someone"),params = c("mm","ee","mxe","me1","em1","miv","eiv"),orders = c(3,5,7,4,6,8,9), html = T,logtransparams = T)

# log back transformation m_s, miv siv
#exp(m_s) / (sqrt(exp(miv)+exp(m_s))*sqrt(exp(siv)+exp(m_s)))

knitr::kable(table[[1]],escape = FALSE, align = "c",format = "html") %>%
      kable_paper() %>% 
  column_spec(2,
              background = spec_color(table[[3]][,2], scale_from = c(-.8,.8), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(3,
              background = spec_color(table[[3]][,3], scale_from = c(-.8,.8), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(4,
              background = spec_color(table[[3]][,4], scale_from = c(-.8,.8), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 

  column_spec(5,
              background = spec_color(table[[3]][,5], scale_from = c(-.8,.8), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
 
  column_spec(6,
              background = spec_color(table[[3]][,6], scale_from = c(-.8,.8), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  
   column_spec(7,
              background = spec_color(table[[3]][,7], scale_from = c(-.8,.8), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 

   add_header_above(c(" ", "Within-Person-Dynamics" = 6))
  



## Table with baseline PF, DEP and events with two averaged S1 mods
table = table2func(mplodelnames = c("ModNoOutS1PFsit_ncnf.out","ModNoOutS1PFsit_nemp.out","ModNoOutS1PFsit_novl.out","ModNoOutS1PFsit_prel.out","ModNoOutS1PFsit_psuc.out","ModNoOutS1PFsit_pwo.out"), adds1models = c("ModNoOutS1DEPsit_ncnf.out","ModNoOutS1DEPsit_nemp.out","ModNoOutS1DEPsit_novl.out","ModNoOutS1DEPsit_prel.out","ModNoOutS1DEPsit_psuc.out","ModNoOutS1DEPsit_pwo.out"), tablenames = c("conflict","emptiness or boredom","overwhelming <br> task","relaxation","achievement","good time with someone"),
params = c("PF~>mm",   "DEP~>mm","PF~>ss",   "DEP~>ss","PF~>mxe",   "DEP~>mxe" , "PF~>me1","DEP~>me1","PF~>em1",  "DEP~>em1", "PF~>miv" , "DEP~>miv","PF~>eiv" , "DEP~>eiv","PF~>&empty;mood" , "DEP~>&empty;mood" ,"PF~>&empty;event" , "DEP~>&empty;event"),orders = c(34,35,36,37,28,29,38,39,40,41,30,31,32,33,42,43,44,45), orders1 = c(43, 44, 45, 46, 37, 38, 47, 48, 49, 50, 39, 40, 41, 42, 51, 52, 53, 54), html = T, predtable = F, noconf = T)

table[[1]]%>% kable(escape = FALSE, align = "c",format = "html") %>%
kable_paper() %>%
column_spec(2,bold = table[[4]][,2],
background = spec_color(table[[3]][,2], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(3,bold = table[[4]][,3],
background = spec_color(table[[3]][,3], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(4,bold = table[[4]][,4],
background = spec_color(table[[3]][,4], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(5,bold = table[[4]][,5],
background = spec_color(table[[3]][,5], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(6,bold = table[[4]][,6],
background = spec_color(table[[3]][,6], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(7,bold = table[[4]][,7],
background = spec_color(table[[3]][,7], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
add_header_above(c(" ", "Prediction of averaged between-person differences in within-person affect-sitation dynamics" = 6))


## Prediction table
table2 = table2func(mplodelnames = c("Model1YncnfS1PCO.out","Model1YnempS1PCO.out","Model1YnovlS1PCO.out","Model1YprelS1PCO.out","Model1YpsucS1PCO.out","Model1YpwoS1PCO.out"), adds1models = c("Model1YncnfS1PCODep.out","Model1YnempS1PCODep.out","Model1YnovlS1PCODep.out","Model1YprelS1PCODep.out","Model1YpsucS1PCODep.out","Model1YpwoS1PCODep.out"), tablenames = c("conflict","emptiness or boredom","overwhelming <br> task","relaxation","achievement","good time with someone"),
params = c("mm~>OPF",   "mm~>ODEP","ss~>OPF",   "ss~>ODEP","mxe~>OPF",   "mxe~>ODEP" , "me1~>OPF","me1~>ODEP","em1~>OPF",  "em1~>ODEP", "miv~>OPF" , "miv~>ODEP","eiv~>OPF" , "eiv~>ODEP","&empty;mood~>OPF" , "&empty;mood~>ODEP" ,"&empty;event~>OPF" , "&empty;event~>ODEP","PF~>OPF *","DEP~>OPF *","PF~>ODEP *","DEP~>ODEP *"),orders = c(66,57,67,58,70,61,68,59,69,60,71,62,72,63,77,75,78,76,73,74,64,65), orders1 = c(75, 66, 76, 67, 79, 70, 77, 68, 78, 69, 80, 71, 81, 72, 86, 84, 87, 85, 82, 83, 73, 74), html = T, predtable = F, noconf = c(F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, T, T, T, T))


table2[[1]]%>% kable(escape = FALSE, align = "c",format = "html") %>%
kable_paper() %>%
column_spec(2,#bold = table2[[4]][,2],
background = spec_color(table2[[3]][,2], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(3,#bold = table2[[4]][,3],
background = spec_color(table2[[3]][,3], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(4,#bold = table2[[4]][,4],
background = spec_color(table2[[3]][,4], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(5,#bold = table2[[4]][,5],
background = spec_color(table2[[3]][,5], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(6,#bold = table2[[4]][,6],
background = spec_color(table2[[3]][,6], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
column_spec(7,#bold = table2[[4]][,7],
background = spec_color(table2[[3]][,7], scale_from = c(-.95,.95), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>%
add_header_above(c(" ", "Prediction of between-person differences in PF and depression (averaged over one year) using within-person affect-sitation dynamics" = 6))





## prediction within IN EACH CELL BOTH S1 PARAMS, CIs and correlated factors in SUPPLEMENT

table = table2func(mplodelnames = c("ModNoOutS1sit_ncnf.out","ModNoOutS1DEPsit_ncnf.out","ModNoOutS1sit_nemp.out","ModNoOutS1DEPsit_nemp.out","ModNoOutS1sit_novl.out","ModNoOutS1DEPsit_novl.out","ModNoOutS1sit_prel.out","ModNoOutS1DEPsit_prel.out","ModNoOutS1sit_psuc.out","ModNoOutS1DEPsit_psuc.out","ModNoOutS1sit_pwo.out","ModNoOutS1DEPsit_pwo.out"), tablenames = c("conflict","emptiness or boredom","overwhelming <br> task","relaxation","achievement","good time with someone"),
params = c("PF~>&Psi;me",   "DEP~>&Psi;me" , "PF~>&Phi;ee","DEP~>&Phi;ee","PF~>&Phi;me1",  "DEP~>&Phi;me1", "PF~>&Phi;em1" , "DEP~>&Phi;em1","PF~>&pi;e" , "DEP~>&pi;e" ,"PF~>&empty;SITS" , "DEP~>&empty;SITS"),orders = c(10,11,14,15,16,17,18,19,22,23,26,27), html = F, predtable = T)

table[[1]]%>% kable(escape = FALSE, align = "c",format = "html") %>%
      kable_paper() %>% 
  column_spec(2,bold = table[[4]][,2],
              background = spec_color(table[[3]][,2], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(3,bold = table[[4]][,3],
              background = spec_color(table[[3]][,3], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(4,bold = table[[4]][,4],
              background = spec_color(table[[3]][,4], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(5,bold = table[[4]][,5],
              background = spec_color(table[[3]][,5], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(6,bold = table[[4]][,6],
              background = spec_color(table[[3]][,6], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(7,bold = table[[4]][,7],
              background = spec_color(table[[3]][,7], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
   add_header_above(c(" ", "Prediction of averaged between-person differences in within-person affect-sitation dynamics" = 6))  %>% save_kable("table3.pdf")




## prediction within only correlated factors

table = table2func(mplodelnames = c("ModNoOutCORsit_ncnf.out","ModNoOutCORsit_nemp.out","ModNoOutCORsit_novl.out","ModNoOutCORsit_prel.out","ModNoOutCORsit_psuc.out","ModNoOutCORsit_pwo.out"), tablenames = c("conflict","emptiness or boredom","overwhelming <br> task","relaxation","achievement","good time with someone"),
params = c("PF~>&Psi;me",   "DEP~>&Psi;me" , "PF~>&Phi;ee","DEP~>&Phi;ee","PF~>&Phi;me1",  "DEP~>&Phi;me1", "PF~>&Phi;em1" , "DEP~>&Phi;em1","PF~>&pi;e" , "DEP~>&pi;e" ,"PF~>&empty;SITS" , "DEP~>&empty;SITS"), orders = c(10,11,14,15,16,17,18,19,22,23,26,27), html = F, predtable = T)

rownames(table[[1]]) = c("PF~>mxe",   "DEP~>mxe" , "PF~>ee","DEP~>ee","PF~>me1",  "DEP~>me1", "PF~>em1" , "DEP~>em1","PF~>&eiv" , "DEP~>eiv" ,"PF~>&empty;e" , "DEP~>&empty;e")

table[[1]]%>% kable(escape = FALSE, align = "c",format = "html") %>%
      kable_paper() %>% 
  column_spec(2,bold = table[[4]][,2],
              background = spec_color(table[[3]][,2], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(3,bold = table[[4]][,3],
              background = spec_color(table[[3]][,3], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(4,bold = table[[4]][,4],
              background = spec_color(table[[3]][,4], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(5,bold = table[[4]][,5],
              background = spec_color(table[[3]][,5], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(6,bold = table[[4]][,6],
              background = spec_color(table[[3]][,6], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
  column_spec(7,bold = table[[4]][,7],
              background = spec_color(table[[3]][,7], scale_from = c(-.6,.6), palette =colorRampPalette(c("#fde725","white","#21918c"))(256)))%>% 
   add_header_above(c(" ", "Prediction of averaged between-person differences in within-person affect-sitation dynamics" = 6))  %>% save_kable("table3.pdf")




# %>% 
#     DT::datatable(
#     extensions = 'Buttons',
#     options = list(dom = 'Bfrtip',
#                    buttons = list('excel', "csv")))
# 




  

# Function to apply bold formatting based on logical table
bold_if_true <- function(value, condition) {
  if (condition) {
    return(cell_spec(value, bold = TRUE))
  } else {
    return(value)
  }
}

# Apply the function to the data table
formatted_table <- table2[[1]]
for (col in 2: length(names(table2[[1]]))) {
  formatted_table[[col]] <- mapply(bold_if_true, formatted_table[[col]], table2[[2]][[col]] < .005)
}

# Generate the kable object with kableExtra
kable(formatted_table,escape = FALSE) %>%
      kable_classic_2() 
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCgoKIyBFeHRyYWN0IG1vZGVsIHBhcmFtcwpgYGB7cn0KbGlicmFyeShNcGx1c0F1dG9tYXRpb24pCiMgZnVuY3Rpb24gZm9yIHRhYmxlIHdpdGggYWxsIHBhcmFtcyBmcm9tIERTRU0gbW9kZWxzLCAybW9udGhzIGFuZCBvbmUgeWVhcgojIG1wbG9kZWxuYW1lczogbmFtZXMgb2YgbW9kZWxzIGZvciBzaW5nbGUgZXZlbnRzIChzaXR1YXRpb25zKSB0byBmaWxsIHRoZSB0YWJsZSB3aXRoOyBhZGRzMW1vZGVsczogbmFtZXMgb2YgYWRkaXRpb25hbCBtb2RlbHMgZm9yIHNpbmdsZSBldmVudHMgKHNpdHVhdGlvbnMpIHRvIGZpbGwgdGhlIHRhYmxlIHdpdGgsIGlmIHNlY29uZCBtb2RlbCBubyBjb25maWRlbmNlIGludGVydmFsczsgdGFibGVuYW1lczogbmFtZXMgb2YgY29sdW1ucywgb3JkZXJzID0gcm93bmFtZXMgb2YgIHBhcmFtZXRlcnMgb2YgaW50ZXJlc3QgdGhhdCBzaG91bGQgYmUgZXh0cmFjdGVkIGZyb20gbXBsdXMgb3V0cHV0OyBwYXJhbXM6IHJvd25hbWVzL25hbWVzIG9mIHBhcmFtZXRlcnMgZm9yIHRhYmxlOyBodG1sOiBPdXRwdXQgdGFibGUgaW4gaHRtbDsgbG9ndHJhbnNwYXJhbXM6IGNhbGN1bGF0ZSBiZXRhcyBmb3IgbW9vZHhldmVudCBiYXNlZCBvbiBoYW1ha2VyIGFuZCBvbGl2b3RvIHByb2NlZHVyZTsgcHJlZHRhYmxlOiBpcyBpdCBhIHRhYmxlIHdpdGggcHJlZGljdGlvbiB1c2luZyBiZXR3ZWVuIHBlcnNvbiBpbmRlcGVuZGVudCB2YXJpYWJsZXMgb3IgaXMgaXQganVzdCB3aXRoaW47IG5vY29uZjogbm8gY29uZmlkZW5jZSBpbnRlcnZhbHMKdGFibGUyZnVuYyA9IGZ1bmN0aW9uKG1wbG9kZWxuYW1lcywKICAgICAgICAgICAgICAgICAgICAgIGFkZHMxbW9kZWxzID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB0YWJsZW5hbWVzLAogICAgICAgICAgICAgICAgICAgICAgb3JkZXJzLAogICAgICAgICAgICAgICAgICAgICAgb3JkZXJzMSwKICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IE5BICwKICAgICAgICAgICAgICAgICAgICAgIGh0bWwgPSBULAogICAgICAgICAgICAgICAgICAgICAgbG9ndHJhbnNwYXJhbXMgPSBGLAogICAgICAgICAgICAgICAgICAgICAgcHJlZHRhYmxlID0gRiwKICAgICAgICAgICAgICAgICAgICAgIG5vY29uZiA9IE5BKSB7CiAgaWYgKGxlbmd0aChhZGRzMW1vZGVscykgPT0gMSkgewogICAgIyByZWFkIG1wbHVzIG1vZGVsCiAgICBtcGxvZGVsID0gcmVhZE1vZGVscyh0YXJnZXQgPSBtcGxvZGVsbmFtZXNbMV0pCiAgICAjZXh0cmFjdCBzdGQgcGFyYW1zCiAgICBzdGRvdXQgPSBtcGxvZGVsJHBhcmFtZXRlcnMkc3RkeXguc3RhbmRhcmRpemVkCiAgICAjZGVsZXRlIHVubmVjZXNzYXJ5IHJvd3MKICAgIHN0ZG91dCA9IHN0ZG91dFstZ3JlcCgiZXNpZHVhbCIsIHN0ZG91dCRwYXJhbUhlYWRlcikgLCBdCiAgICBzdGRvdXQgPSBzdGRvdXRbLWdyZXAoIm50ZXJjZXB0Iiwgc3Rkb3V0JHBhcmFtSGVhZGVyKSAsIF0KICAgIHJvd25hbWVzKHN0ZG91dCkgPSAxOmRpbShzdGRvdXQpWzFdCiAgICB0ZW1wID0gc3Rkb3V0CiAgICAjIHJlb3JkZXIgd2l0aGluLCBiZXR3ZWVuLCBwcmVkIGFuZCBleHRyYWN0IG9ubHkgdmFyaWFibGVzIHdlIGFyZSBpbnRlcmVzdGVkIGluCiAgICBzdGRvdXQgPSBzdGRvdXRbb3JkZXJzLCBdCiAgICAjIGNoZWNrIGF2YWlsYWJsZSBOIGFmdGVyIHJlbW92YWwgb2YgY2FzZXMgd28gdmFyaWFuY2UgYW5kIG9yCiAgICBub2Nhc2VzID0gdW5saXN0KHJlZ21hdGNoZXModW5saXN0KG1wbG9kZWwkd2FybmluZ3MpLCBncmVnZXhwcignWzAtOV0rJywgdW5saXN0KAogICAgICBtcGxvZGVsJHdhcm5pbmdzCiAgICApKSkpCiAgICBub2Nhc2VzID0gbm9jYXNlc1tuY2hhcihub2Nhc2VzKSA+IDFdCiAgICBOID0gbXBsb2RlbCRkYXRhX3N1bW1hcnkkb3ZlcmFsbCROQ2x1c3RlcnMgLSBsZW5ndGgobm9jYXNlcykKICAgICMgY3JlYXRlIHRhYmxlCiAgICB0YWJsZTIgPSBzdGRvdXRbLCBjKCJwYXJhbUhlYWRlciIsICJlc3QiKV0KICAgIG5hbWVzKHRhYmxlMikgPSBjKCJwYXJhbSIsIHBhc3RlMCh0YWJsZW5hbWVzWzFdLCAiIE49IiwgTiwgIjxicj4gc3RkeXguIikpCiAgICBpZiAobGVuZ3RoKGlzLm5hKHBhcmFtcykpID09IDEpIHsKICAgICAgI3B1dCBwYXJhbXMKICAgICAgdGFibGUyJHBhcmFtID0gcGFzdGUoc3Rkb3V0JHBhcmFtSGVhZGVyLCBzdGRvdXQkcGFyYW0pCiAgICB9IGVsc2V7CiAgICAgIHRhYmxlMiRwYXJhbSA9IHBhcmFtcwogICAgfQogICAgIyBjcmVhdGUgdGFibGUgd2l0aCBib2xkbmVzcyB3aGVuIG5vbm92ZXJsYXBwaW5nIGNpCiAgICBpZiAocHJlZHRhYmxlID09IFQpIHsKICAgICAgdGFibGVib2xkcyA9IHRhYmxlMgogICAgICB0YWJsZWJvbGRzWywgMl0gPSBGQUxTRQogICAgICAjIGJvbGQgZm9yIG5vbi1vdmVybGFwcGluZyBQRiBhbmQgRGVwIGNvbmYgaW50CiAgICAgIGkgPSAxCiAgICAgIHdoaWxlIChpIDwgZGltKHN0ZG91dClbMV0pIHsKICAgICAgICBhMSA9IHN0ZG91dCRsb3dlcl8yLjVjaVtpXQogICAgICAgIGEyID0gc3Rkb3V0JHVwcGVyXzIuNWNpW2ldCiAgICAgICAgYjEgPSBzdGRvdXQkbG93ZXJfMi41Y2lbaSArIDFdCiAgICAgICAgYjIgPSBzdGRvdXQkdXBwZXJfMi41Y2lbaSArIDFdCiAgICAgICAgaWYgKCEoKGExIDw9IGIyKSAmJiAoYjEgPD0gYTIpKSkgewogICAgICAgICAgdGFibGVib2xkc1tpLCAyXSA9IFQKICAgICAgICAgIHRhYmxlYm9sZHNbaSArIDEsIDJdID0gVAogICAgICAgIH0KICAgICAgICBpID0gaSArIDIKICAgICAgfQogICAgfSBlbHNlewogICAgICB0YWJsZWJvbGRzID0gdGFibGUyCiAgICAgIHRhYmxlYm9sZHNbLCAyOm5jb2wodGFibGVib2xkcyldID0gRgogICAgfQogICAgaWYgKGxvZ3RyYW5zcGFyYW1zID09IFQpIHsKICAgICAgI29sZCBwcm9jZWR1cmUKICAgICAgIyAgcmF3b3V0ID0gIG1wbG9kZWwkcGFyYW1ldGVycyR1bnN0YW5kYXJkaXplZAogICAgICAjIHJhd291dCA9IHJhd291dFtncmVwKCJudGVyY2VwdCIscmF3b3V0JHBhcmFtSGVhZGVyKSAsXQogICAgICAjICMgZXhjaGFuZ2UgbV9zLCBtaXYgb3Igc2l2IHBhcmFtcyB3aXRoIGxvZy1iYWNrdHJhbnNmb3JtZWQgdmFsdWVzIGZyb20gcmF3IG91dHB1dAogICAgICAjIHJhd291dCA9IHJhd291dFtyYXdvdXQkcGFyYW0gJWluJSBjKCJNSVYiLCJTSVYiLCJNX1MiKSxdCiAgICAgICMgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksImVzdCJdID0gZXhwKHJhd291dCRlc3RbcmF3b3V0JHBhcmFtID09ICJNX1MiXSkgLyAoc3FydChleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIk1JViJdKStleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIk1fUyJdKSkqc3FydChleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIlNJViJdKStleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIk1fUyJdKSkpCiAgICAgICMgIyBpZiBuZWdhdGl2ZSBsb2FkaW5nCiAgICAgICMgaWYodGVtcCA8IDApe3N0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCJlc3QiXSA9IHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCJlc3QiXSAqLTF9CiAgICAgICMjIyMjIyBwcm9jZWR1cmUgYWR2aXNlZCBieSBFbGxlbiBIYW1ha2VyICAjIyMjIyMjCiAgICAgICMgdW5pcXVlIHBhcnQgb2YgcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgIGxvYWRtID0gICB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsxXQogICAgICBsb2FkcyA9ICB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsyXQogICAgICAjIGNvdmFyaWFuY2UgYmV0d2VlbiByZXNpZHVhbCB2YXJpYW5jZXMKICAgICAgY292bXMgPSBsb2FkcyAqIGxvYWRtCiAgICAgICMgcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgIHZhcnJlc2lkbSA9IHRlbXBbdGVtcCRwYXJhbUhlYWRlciA9PSAiTUlWLnwiLCAiZXN0Il0gKyBsb2FkbSBeIDIKICAgICAgdmFycmVzaWRzID0gdGVtcFt0ZW1wJHBhcmFtSGVhZGVyID09ICJTSVYufCIsICJlc3QiXSArIGxvYWRzIF4gMgogICAgICAjIGNvcnJlbGF0aW9uID0gY292IC8gc3FydCh2YXJyZXNpZG0gKiB2YXJyZXNpZHMpCiAgICAgIHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAiZXN0Il0gPSBjb3ZtcyAvIHNxcnQodmFycmVzaWRtICogdmFycmVzaWRzKQogICAgICAjY29uZmlkZW5jZSBpbnRlcnZhbCBhY2NvcmRpbmcgdG8gT2xpdm90byBldCBhbC4gKDIwMTgpCiAgICAgIENJID0gKGFicyhzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImVzdCJdKSBeIC4zKSAqIDIuMjUxNTIgKiAoTiBeIC0wLjUwMDg5KQogICAgICBzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImxvd2VyXzIuNWNpIl0gPSBzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImVzdCJdIC0gQ0kKICAgICAgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJ1cHBlcl8yLjVjaSJdID0gc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJlc3QiXSArIENJCiAgICAgICMgc3Rkb3V0W2dyZXAoIlNJVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJlc3QiXSA9ZXhwKHJhd291dCRlc3RbcmF3b3V0JHBhcmFtID09ICJTSVYiXSkKICAgICAgIyBzdGRvdXRbZ3JlcCgiU0lWLiIsIHN0ZG91dCRwYXJhbUhlYWRlciksImxvd2VyXzIuNWNpIl0gPWV4cChyYXdvdXQkbG93ZXJfMi41Y2lbcmF3b3V0JHBhcmFtID09ICJTSVYiXSkKICAgICAgIyBzdGRvdXRbZ3JlcCgiU0lWLiIsIHN0ZG91dCRwYXJhbUhlYWRlciksInVwcGVyXzIuNWNpIl0gPWV4cChyYXdvdXQkdXBwZXJfMi41Y2lbcmF3b3V0JHBhcmFtID09ICJTSVYiXSkKICAgICAgIyBpZigiJnBpO20iICVpbiUgdGFibGUyJHBhcmFtKXsKICAgICAgIyAgc3Rkb3V0W2dyZXAoIk1JVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJlc3QiXSA9ZXhwKHJhd291dCRlc3RbcmF3b3V0JHBhcmFtID09ICJNSVYiXSkKICAgICAgIyAgc3Rkb3V0W2dyZXAoIk1JVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJsb3dlcl8yLjVjaSJdID1leHAocmF3b3V0JGxvd2VyXzIuNWNpW3Jhd291dCRwYXJhbSA9PSAiTUlWIl0pCiAgICAgICMgc3Rkb3V0W2dyZXAoIk1JVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJ1cHBlcl8yLjVjaSJdID1leHAocmF3b3V0JHVwcGVyXzIuNWNpW3Jhd291dCRwYXJhbSA9PSAiTUlWIl0pCiAgICAgICMgfQogICAgfQogICAgCiAgICAjIGNyZWF0ZSBub2NvbmYgYm9vbGVhbgogICAgaWYobGVuZ3RoKG5vY29uZikgPT0gMSl7IGlmKHN1bShpcy5uYShub2NvbmYpKSA+IDApIHtub2NvbmYgPSByZXAoRixsZW5ndGgob3JkZXJzKSl9IGVsc2UgaWYobm9jb25mKXtub2NvbmYgPSByZXAoVCxsZW5ndGgob3JkZXJzKSl9fSAKICBpZiAoaHRtbCA9PSBUKXsKICAgICAgICB0YWJsZTJbIW5vY29uZiwgMl0gPSBwYXN0ZTAoCiAgICAgICAgICAiPHNwYW4gc3R5bGU9XCIiLAogICAgICAgICAgaWZlbHNlKHN0ZG91dCRwdmFsWyFub2NvbmZdIDwgLjAwNSwgeWVzID0gImZvbnQtd2VpZ2h0OiBib2xkOyIsIG5vID0gIjsiKSwKICAgICAgICAgICJcIiA+IiwKICAgICAgICAgIHJvdW5kKHN0ZG91dCRlc3RbIW5vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICAgIiA8YnI+IFsiLAogICAgICAgICAgcm91bmQoc3Rkb3V0JGxvd2VyXzIuNWNpWyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAgICIgIiwKICAgICAgICAgIHJvdW5kKHN0ZG91dCR1cHBlcl8yLjVjaVshbm9jb25mXSwgZGlnaXRzID0gMiksCiAgICAgICAgICAiXTwvc3Bhbj4iCiAgICAgICAgKX0KICAgICAgIGlmIChodG1sID09IEYpIHsKICAgICAgICB0YWJsZTJbIW5vY29uZiwgMl0gPSBpZmVsc2UoCiAgICAgICAgICBzdGRvdXQkcHZhbCA8IC4wMDUsCiAgICAgICAgICB5ZXMgPSBwYXN0ZTAoCiAgICAgICAgICAgIHJvdW5kKHN0ZG91dCRlc3RbIW5vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICAgICAiIDxicj4gWyIsCiAgICAgICAgICAgIHJvdW5kKHN0ZG91dCRsb3dlcl8yLjVjaVshbm9jb25mXSwgZGlnaXRzID0gMiksCiAgICAgICAgICAgICIgIiwKICAgICAgICAgICAgcm91bmQoc3Rkb3V0JHVwcGVyXzIuNWNpWyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAgICAgIl0iCiAgICAgICAgICApLAogICAgICAgICAgbm8gPSAiIgogICAgICAgICkKICAgICAgfQogICAKICAgICAgdGFibGUyW25vY29uZiwgMl0gPSBwYXN0ZTAoCiAgICAgICAgIjxzcGFuIHN0eWxlPVwiIiwKICAgICAgICBpZmVsc2Uoc3Rkb3V0JHB2YWxbbm9jb25mXSA8IC4wMDUsIHllcyA9ICJmb250LXdlaWdodDogYm9sZDsiLCBubyA9ICI7IiksCiAgICAgICAgIlwiID4iLAogICAgICAgIHJvdW5kKHN0ZG91dCRlc3Rbbm9jb25mXSwgZGlnaXRzID0gMiksCiAgICAgICAgIjwvc3Bhbj4iCiAgICAgICkKICAgIGlmIChodG1sID09IEYpIHsKICAgICAgdGFibGUyW25vY29uZiwgMl0gPSBpZmVsc2Uoc3Rkb3V0JHB2YWxbbm9jb25mXSA8IC4wMDUsIHllcyA9IHBhc3RlMChyb3VuZChzdGRvdXQkZXN0W25vY29uZl0sIGRpZ2l0cyA9IDIpKSwgbm8gPSAiIikKICAgIH0KICAgICMKICAgICMgdGFibGUyWywyXSA9IHBhc3RlMCgiPHNwYW4gc3R5bGU9XCIiLCBpZmVsc2Uoc3Rkb3V0JHB2YWwgPC4wMDUseWVzID0gImZvbnQtd2VpZ2h0OiBib2xkOyBkaXNwbGF5OmJsb2NrO3dpZHRoOjEwMCU7YmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7Iiwgbm8gPSAiZGlzcGxheTpibG9jazt3aWR0aDoxMDAlO2JhY2tncm91bmQtY29sb3I6eWVsbG93OyIpLCAgICJcIiA+Iixyb3VuZChzdGRvdXQkZXN0LGRpZ2l0cyA9IDIpLCIgPGJyPiBbIixyb3VuZChzdGRvdXQkbG93ZXJfMi41Y2ksZGlnaXRzID0gMiksIiAiLHJvdW5kKHN0ZG91dCR1cHBlcl8yLjVjaSxkaWdpdHMgPSAyKSwiXTwvc3Bhbj4iKQogICAgIwogICAgIyB0YWJsZTJbLDJdPSBwYXN0ZShyb3VuZChzdGRvdXQkZXN0LGRpZ2l0cyA9IDIpLHBhc3RlMCgiPGJyPlsiLHJvdW5kKHN0ZG91dCRsb3dlcl8yLjVjaSxkaWdpdHMgPSAyKSwgIiAiLHJvdW5kKHN0ZG91dCR1cHBlcl8yLjVjaSxkaWdpdHMgPSAyKSwiXSIpKQogICAgIyBtYWtlIHRhYmxlIHdpdGggc2lnbmlmaWNhbmNlCiAgICB0YWJsZTJwID0gdGFibGUyWywgMToyXQogICAgbmFtZXModGFibGUycClbMl0gPSB0YWJsZW5hbWVzWzFdCiAgICB0YWJsZTJwWywgMl0gPSBzdGRvdXQkcHZhbAogICAgIyBtYWtlIHRhYmxlIHdpdGggcmVncmVzc2lvbndlaWdodAogICAgdGFibGUyciA9IHRhYmxlMlssIDE6Ml0KICAgIG5hbWVzKHRhYmxlMnIpWzJdID0gdGFibGVuYW1lc1sxXQogICAgdGFibGUyclssIDJdID0gc3Rkb3V0JGVzdAogICAgIyBtYWtlIHRhYmxlIHdpdGggYWxsIG1vZGVscwogICAgZm9yIChpIGluIDI6bGVuZ3RoKG1wbG9kZWxuYW1lcykpIHsKICAgICAgIyByZWFkIG1wbHVzIG1vZGVsCiAgICAgIG1wbG9kZWwgPSBNcGx1c0F1dG9tYXRpb246OnJlYWRNb2RlbHMobXBsb2RlbG5hbWVzW2ldKQogICAgICAjZXh0cmFjdCB1bnN0ZCBwYXJhbXMgZm9yIG1pdiwgc2l2LCBtX2UKICAgICAgI2V4dHJhY3Qgc3RkIHBhcmFtcwogICAgICBzdGRvdXQgPSBtcGxvZGVsJHBhcmFtZXRlcnMkc3RkeXguc3RhbmRhcmRpemVkCiAgICAgICNkZWxldGUgdW5uZWNlc3Nhcnkgcm93cwogICAgICBzdGRvdXQgPSBzdGRvdXRbLWdyZXAoImVzaWR1YWwiLCBzdGRvdXQkcGFyYW1IZWFkZXIpICwgXQogICAgICBzdGRvdXQgPSBzdGRvdXRbLWdyZXAoIm50ZXJjZXB0Iiwgc3Rkb3V0JHBhcmFtSGVhZGVyKSAsIF0KICAgICAgcm93bmFtZXMoc3Rkb3V0KSA9IDE6ZGltKHN0ZG91dClbMV0KICAgICAgdGVtcCA9IHN0ZG91dAogICAgICAjIHJlb3JkZXIgd2l0aGluLCBiZXR3ZWVuLCBwcmVkCiAgICAgIHN0ZG91dCA9IHN0ZG91dFtvcmRlcnMsIF0KICAgICAgIyBjaGVjayBhdmFpbGFibGUgTiBhZnRlciByZW1vdmFsIG9mIGNhc2VzIHdvIHZhcmlhbmNlIGFuZCBvcgogICAgICBub2Nhc2VzID0gdW5saXN0KHJlZ21hdGNoZXModW5saXN0KG1wbG9kZWwkd2FybmluZ3MpLCBncmVnZXhwcigKICAgICAgICAnWzAtOV0rJywgdW5saXN0KG1wbG9kZWwkd2FybmluZ3MpCiAgICAgICkpKQogICAgICBub2Nhc2VzID0gbm9jYXNlc1tuY2hhcihub2Nhc2VzKSA+IDFdCiAgICAgIE4gPSBtcGxvZGVsJGRhdGFfc3VtbWFyeSRvdmVyYWxsJE5DbHVzdGVycyAtIGxlbmd0aChub2Nhc2VzKQogICAgICBpZiAobG9ndHJhbnNwYXJhbXMgPT0gVCkgewogICAgICAgICMjIyMjIyBwcm9jZWR1cmUgYWR2aXNlZCBieSBFbGxlbiBIYW1ha2VyICAjIyMjIyMjCiAgICAgICAgIyB1bmlxdWUgcGFydCBvZiByZXNpZHVhbCB2YXJpYW5jZXMKICAgICAgICBsb2FkbSA9ICAgdGVtcFt0ZW1wJHBhcmFtSGVhZGVyID09ICJNX1NfTFYuQlkiLCAiZXN0Il1bMV0KICAgICAgICBsb2FkcyA9ICB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsyXQogICAgICAgICMgY292YXJpYW5jZSBiZXR3ZWVuIHJlc2lkdWFsIHZhcmlhbmNlcwogICAgICAgIGNvdm1zID0gbG9hZHMgKiBsb2FkbQogICAgICAgICMgcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgICAgdmFycmVzaWRtID0gdGVtcFt0ZW1wJHBhcmFtSGVhZGVyID09ICJNSVYufCIsICJlc3QiXSArIGxvYWRtIF4gMgogICAgICAgIHZhcnJlc2lkcyA9IHRlbXBbdGVtcCRwYXJhbUhlYWRlciA9PSAiU0lWLnwiLCAiZXN0Il0gKyBsb2FkcyBeIDIKICAgICAgICAjIGNvcnJlbGF0aW9uID0gY292IC8gc3FydCh2YXJyZXNpZG0gKiB2YXJyZXNpZHMpCiAgICAgICAgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJlc3QiXSA9IGNvdm1zIC8gc3FydCh2YXJyZXNpZG0gKiB2YXJyZXNpZHMpCiAgICAgICAgI2NvbmZpZGVuY2UgaW50ZXJ2YWwgYWNjb3JkaW5nIHRvIE9saXZvdG8gZXQgYWwuICgyMDE4KQogICAgICAgIENJID0gKGFicyhzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImVzdCJdKSBeIC4zKSAqIDIuMjUxNTIgKiAoTiBeIC0wLjUwMDg5KQogICAgICAgIHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAibG93ZXJfMi41Y2kiXSA9IHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAiZXN0Il0gLSBDSQogICAgICAgIHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAidXBwZXJfMi41Y2kiXSA9IHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAiZXN0Il0gKyBDSQogICAgICB9CiAgICAgICNwdXQgcGFyYW1zCiAgICAgICN0YWJsZTIkcGFyYW0gPSBwYXN0ZShzdGRvdXQkcGFyYW1IZWFkZXIsIHN0ZG91dCRwYXJhbSkKICAgICAgICB0YWJsZTJbIW5vY29uZiwgaSArIDFdID0gcGFzdGUwKAogICAgICAgICAgIjxzcGFuIHN0eWxlPVwiIiwKICAgICAgICAgIGlmZWxzZShzdGRvdXQkcHZhbFshbm9jb25mXSA8IC4wMDUsIHllcyA9ICJmb250LXdlaWdodDogYm9sZDsiLCBubyA9ICI7IiksCiAgICAgICAgICAiXCIgPiIsCiAgICAgICAgICByb3VuZChzdGRvdXQkZXN0WyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAgICIgPGJyPiBbIiwKICAgICAgICAgIHJvdW5kKHN0ZG91dCRsb3dlcl8yLjVjaVshbm9jb25mXSwgZGlnaXRzID0gMiksCiAgICAgICAgICAiICIsCiAgICAgICAgICByb3VuZChzdGRvdXQkdXBwZXJfMi41Y2lbIW5vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICAgIl08L3NwYW4+IgogICAgICAgICkKICAgICAgIGlmIChodG1sID09IEYpIHsKICAgICAgICB0YWJsZTJbIW5vY29uZiwgaSArIDFdID0gaWZlbHNlKAogICAgICAgICAgc3Rkb3V0JHB2YWxbIW5vY29uZl0gPCAuMDA1LAogICAgICAgICAgeWVzID0gcGFzdGUwKAogICAgICAgICAgICByb3VuZChzdGRvdXQkZXN0WyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAgICAgIiA8YnI+IFsiLAogICAgICAgICAgICByb3VuZChzdGRvdXQkbG93ZXJfMi41Y2lbIW5vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICAgICAiICIsCiAgICAgICAgICAgIHJvdW5kKHN0ZG91dCR1cHBlcl8yLjVjaVshbm9jb25mXSwgZGlnaXRzID0gMiksCiAgICAgICAgICAgICJdIgogICAgICAgICAgKSwKICAgICAgICAgIG5vID0gIiIKICAgICAgICApCiAgICAgIH0KICAgCiAgICAgIHRhYmxlMltub2NvbmYsIGkgKyAxXSA9IHBhc3RlMCgKICAgICAgICAiPHNwYW4gc3R5bGU9XCIiLAogICAgICAgIGlmZWxzZShzdGRvdXQkcHZhbFtub2NvbmZdIDwgLjAwNSwgeWVzID0gImZvbnQtd2VpZ2h0OiBib2xkOyIsIG5vID0gIjsiKSwKICAgICAgICAiXCIgPiIsCiAgICAgICAgcm91bmQoc3Rkb3V0JGVzdFtub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAiPC9zcGFuPiIKICAgICAgKQogICAgaWYgKGh0bWwgPT0gRikgewogICAgICB0YWJsZTJbbm9jb25mLCBpICsgMV0gPSBpZmVsc2Uoc3Rkb3V0JHB2YWxbbm9jb25mXSA8IC4wMDUsIHllcyA9IHBhc3RlMChyb3VuZChzdGRvdXQkZXN0W25vY29uZl0sIGRpZ2l0cyA9IDIpKSwgbm8gPSAiIikKICAgIH0KICAgICAgbmFtZXModGFibGUyKVtpICsgMV0gPSBwYXN0ZTAodGFibGVuYW1lc1tpXSwgIiBOPSIsIE4sICI8YnI+IHN0ZHl4LiIpCiAgICAgICMgY3JlYXRlIHRhYmxlIHdpdGggYm9sZG5lc3Mgd2hlbiBub25vdmVybGFwcGluZyBjaQogICAgICBpZiAocHJlZHRhYmxlID09IFQpIHsKICAgICAgICAjIGJvbGQgZm9yIG5vbi1vdmVybGFwcGluZyBQRiBhbmQgRGVwIGNvbmYgaW50CiAgICAgICAgdGFibGVib2xkc1ssIGkgKyAxXSA9IEZBTFNFCiAgICAgICAgZCA9IDEKICAgICAgICB3aGlsZSAoZCA8IGRpbShzdGRvdXQpWzFdKSB7CiAgICAgICAgICBhMSA9IHN0ZG91dCRsb3dlcl8yLjVjaVtkXQogICAgICAgICAgYTIgPSBzdGRvdXQkdXBwZXJfMi41Y2lbZF0KICAgICAgICAgIGIxID0gc3Rkb3V0JGxvd2VyXzIuNWNpW2QgKyAxXQogICAgICAgICAgYjIgPSBzdGRvdXQkdXBwZXJfMi41Y2lbZCArIDFdCiAgICAgICAgICBpZiAoISgoYTEgPD0gYjIpICYmIChiMSA8PSBhMikpKSB7CiAgICAgICAgICAgIHRhYmxlYm9sZHNbZCwgaSArIDFdID0gVAogICAgICAgICAgICB0YWJsZWJvbGRzW2QgKyAxLCBpICsgMV0gPSBUCiAgICAgICAgICB9CiAgICAgICAgICBkID0gZCArIDIKICAgICAgICB9CiAgICAgIH0gZWxzZXsKICAgICAgICB0YWJsZWJvbGRzWywgaSArIDFdID0gRkFMU0UKICAgICAgfQogICAgICAjIHB1dCBpbiB0YWJsZSB3aXRoIHNpZ25pZmljYW5jZQogICAgICB0YWJsZTJwWywgaSArIDFdID0gc3Rkb3V0JHB2YWwKICAgICAgbmFtZXModGFibGUycClbaSArIDFdID0gdGFibGVuYW1lc1tpXQogICAgICAjIHB1dCBpbiB0YWJsZSB3aXRoIHJlZ3Jlc3Npb24KICAgICAgdGFibGUyclssIGkgKyAxXSA9IHN0ZG91dCRlc3QKICAgICAgbmFtZXModGFibGUycilbaSArIDFdID0gdGFibGVuYW1lc1tpXQogICAgfQogICAgcm93bmFtZXModGFibGUyKSA9IE5VTEwKICAgIHJvd25hbWVzKHRhYmxlMnApID0gTlVMTAogICAgcm93bmFtZXModGFibGUycikgPSBOVUxMCiAgfSBlbHNlIHsKICAgIAogICAgCiAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwogICAgI3B1dCByZXN1bHRzIG9mIHR3byBtb2RlbHMgaW4gb25lIGNlbGwKICAgICMgcmVhZCBtcGx1cyBtb2RlbAogICAgbXBsb2RlbCA9IHJlYWRNb2RlbHModGFyZ2V0ID0gbXBsb2RlbG5hbWVzWzFdKQogICAgI2V4dHJhY3Qgc3RkIHBhcmFtcwogICAgc3Rkb3V0ID0gbXBsb2RlbCRwYXJhbWV0ZXJzJHN0ZHl4LnN0YW5kYXJkaXplZAogICAgIyB0YWtlIHVuc3RhbmRhcmRpemVkIGlmIHN0ZCBpcyBub3QgYXZhaWxhYmxlCiAgICBpZiAoaXMubnVsbChzdGRvdXQpKSB7CiAgICAgIHN0ZG91dCA9IG1wbG9kZWwkcGFyYW1ldGVycyR1bnN0YW5kYXJkaXplZAogICAgICAjIGxhcmdlIHAgdmFsdWUgZm9yIHVuc3RhbmRhcmRpemVkIHNvIHRoYXQgaXQgZ2V0cyBtYXJrZWQgaW4gZmluYWwgdGFibGUKICAgICAgc3Rkb3V0JHB2YWwgPSAxCiAgICB9CiAgICAjZGVsZXRlIHVubmVjZXNzYXJ5IHJvd3MKICAgIHN0ZG91dCA9IHN0ZG91dFstZ3JlcCgiZXNpZHVhbCIsIHN0ZG91dCRwYXJhbUhlYWRlcikgLCBdCiAgICBzdGRvdXQgPSBzdGRvdXRbLWdyZXAoIm50ZXJjZXB0Iiwgc3Rkb3V0JHBhcmFtSGVhZGVyKSAsIF0KICAgIHJvd25hbWVzKHN0ZG91dCkgPSAxOmRpbShzdGRvdXQpWzFdCiAgICAjIGZvciBteGUgY2FsYwogICAgdGVtcCA9IHN0ZG91dAogICAgIyByZW9yZGVyIHdpdGhpbiwgYmV0d2VlbiwgcHJlZCBhbmQgZXh0cmFjdCBvbmx5IHZhcmlhYmxlcyB3ZSBhcmUgaW50ZXJlc3RlZCBpbgogICAgc3Rkb3V0ID0gc3Rkb3V0W29yZGVycywgXQogICAgaWYgKGxlbmd0aChhZGRzMW1vZGVscykgPiAxKSB7CiAgICAgICMgcmVhZCBhZGRpdGlvbmFsIFMxIG1vZGVsCiAgICAgICMgcmVhZCBtcGx1cyBtb2RlbAogICAgICBhZGRzMW1vZGVsID0gcmVhZE1vZGVscyh0YXJnZXQgPSBhZGRzMW1vZGVsc1sxXSkKICAgICAgI2V4dHJhY3Qgc3RkIHBhcmFtcwogICAgICBzdGRvdXRzMSA9IGFkZHMxbW9kZWwkcGFyYW1ldGVycyRzdGR5eC5zdGFuZGFyZGl6ZWQKICAgICAgIyB0YWtlIHVuc3RhbmRhcmRpemVkIGlmIHN0ZCBpcyBub3QgYXZhaWxhYmxlCiAgICAgIGlmIChpcy5udWxsKHN0ZG91dHMxKSkgewogICAgICAgIHN0ZG91dHMxID0gYWRkczFtb2RlbCRwYXJhbWV0ZXJzJHVuc3RhbmRhcmRpemVkCiAgICAgICAgIyBsYXJnZSBwIHZhbHVlIGZvciB1bnN0YW5kYXJkaXplZCBzbyB0aGF0IGl0IGdldHMgbWFya2VkIGluIGZpbmFsIHRhYmxlCiAgICAgICAgc3Rkb3V0czEkcHZhbCA9IDEKICAgICAgICAjIHN0ZG91dHMxID0gc3Rkb3V0CiAgICAgICAgIyBzdGRvdXRzMVssMzpuY29sKHN0ZG91dHMxKV0gPSBOQQogICAgICB9CiAgICAgICNkZWxldGUgdW5uZWNlc3Nhcnkgcm93cwogICAgICBzdGRvdXRzMSA9IHN0ZG91dHMxWy1ncmVwKCJlc2lkdWFsIiwgc3Rkb3V0czEkcGFyYW1IZWFkZXIpICwgXQogICAgICBzdGRvdXRzMSA9IHN0ZG91dHMxWy1ncmVwKCJudGVyY2VwdCIsIHN0ZG91dHMxJHBhcmFtSGVhZGVyKSAsIF0KICAgICAgcm93bmFtZXMoc3Rkb3V0czEpID0gMTpkaW0oc3Rkb3V0czEpWzFdCiAgICAgICMgZm9yIG14ZSBjYWxjCiAgICAgIHRlbXBzMSA9IHN0ZG91dHMxCiAgICAgICMgcmVvcmRlciB3aXRoaW4sIGJldHdlZW4sIHByZWQgYW5kIGV4dHJhY3Qgb25seSB2YXJpYWJsZXMgd2UgYXJlIGludGVyZXN0ZWQgaW4KICAgICAgc3Rkb3V0czEgPSBzdGRvdXRzMVtvcmRlcnMxLCBdCiAgICB9CiAgICAjIGNoZWNrIGF2YWlsYWJsZSBOIGFmdGVyIHJlbW92YWwgb2YgY2FzZXMgd28gdmFyaWFuY2UgYW5kIG9yCiAgICBub2Nhc2VzID0gdW5saXN0KHJlZ21hdGNoZXModW5saXN0KG1wbG9kZWwkd2FybmluZ3MpLCBncmVnZXhwcignWzAtOV0rJywgdW5saXN0KAogICAgICBtcGxvZGVsJHdhcm5pbmdzCiAgICApKSkpCiAgICBub2Nhc2VzID0gbm9jYXNlc1tuY2hhcihub2Nhc2VzKSA+IDFdCiAgICBOID0gbXBsb2RlbCRkYXRhX3N1bW1hcnkkb3ZlcmFsbCROQ2x1c3RlcnMgLSBsZW5ndGgobm9jYXNlcykKICAgICMgY3JlYXRlIHRhYmxlCiAgICB0YWJsZTIgPSBzdGRvdXRbLCBjKCJwYXJhbUhlYWRlciIsICJlc3QiKV0KICAgIG5hbWVzKHRhYmxlMikgPSBjKCJwYXJhbSIsIHBhc3RlMCh0YWJsZW5hbWVzWzFdLCAiIE49IiwgTiwgIjxicj4gc3RkeXguIikpCiAgICBpZiAobGVuZ3RoKGlzLm5hKHBhcmFtcykpID09IDEpIHsKICAgICAgI3B1dCBwYXJhbXMKICAgICAgdGFibGUyJHBhcmFtID0gcGFzdGUoc3Rkb3V0JHBhcmFtSGVhZGVyLCBzdGRvdXQkcGFyYW0pCiAgICB9IGVsc2V7CiAgICAgIHRhYmxlMiRwYXJhbSA9IHBhcmFtcwogICAgfQogICAgIyBjcmVhdGUgdGFibGUgd2l0aCBib2xkbmVzcyB3aGVuIG5vbm92ZXJsYXBwaW5nIGNpCiAgICBpZiAocHJlZHRhYmxlID09IFQpIHsKICAgICAgdGFibGVib2xkcyA9IHRhYmxlMgogICAgICB0YWJsZWJvbGRzWywgMl0gPSBGQUxTRQogICAgICAjIGJvbGQgZm9yIG5vbi1vdmVybGFwcGluZyBQRiBhbmQgRGVwIGNvbmYgaW50CiAgICAgIGkgPSAxCiAgICAgIHdoaWxlIChpIDwgZGltKHN0ZG91dClbMV0pIHsKICAgICAgICBhMSA9IHN0ZG91dCRsb3dlcl8yLjVjaVtpXQogICAgICAgIGEyID0gc3Rkb3V0JHVwcGVyXzIuNWNpW2ldCiAgICAgICAgYjEgPSBzdGRvdXQkbG93ZXJfMi41Y2lbaSArIDFdCiAgICAgICAgYjIgPSBzdGRvdXQkdXBwZXJfMi41Y2lbaSArIDFdCiAgICAgICAgaWYgKCEoKGExIDw9IGIyKSAmJiAoYjEgPD0gYTIpKSkgewogICAgICAgICAgdGFibGVib2xkc1tpLCAyXSA9IFQKICAgICAgICAgIHRhYmxlYm9sZHNbaSArIDEsIDJdID0gVAogICAgICAgIH0KICAgICAgICBpID0gaSArIDIKICAgICAgfQogICAgfSBlbHNlewogICAgICB0YWJsZWJvbGRzID0gdGFibGUyCiAgICAgIHRhYmxlYm9sZHNbLCAyOm5jb2wodGFibGVib2xkcyldID0gRgogICAgfQogICAgaWYgKGxvZ3RyYW5zcGFyYW1zID09IFQpIHsKICAgICAgI29sZCBwcm9jZWR1cmUKICAgICAgIyAgcmF3b3V0ID0gIG1wbG9kZWwkcGFyYW1ldGVycyR1bnN0YW5kYXJkaXplZAogICAgICAjIHJhd291dCA9IHJhd291dFtncmVwKCJudGVyY2VwdCIscmF3b3V0JHBhcmFtSGVhZGVyKSAsXQogICAgICAjICMgZXhjaGFuZ2UgbV9zLCBtaXYgb3Igc2l2IHBhcmFtcyB3aXRoIGxvZy1iYWNrdHJhbnNmb3JtZWQgdmFsdWVzIGZyb20gcmF3IG91dHB1dAogICAgICAjIHJhd291dCA9IHJhd291dFtyYXdvdXQkcGFyYW0gJWluJSBjKCJNSVYiLCJTSVYiLCJNX1MiKSxdCiAgICAgICMgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksImVzdCJdID0gZXhwKHJhd291dCRlc3RbcmF3b3V0JHBhcmFtID09ICJNX1MiXSkgLyAoc3FydChleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIk1JViJdKStleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIk1fUyJdKSkqc3FydChleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIlNJViJdKStleHAocmF3b3V0JGVzdFtyYXdvdXQkcGFyYW0gPT0gIk1fUyJdKSkpCiAgICAgICMgIyBpZiBuZWdhdGl2ZSBsb2FkaW5nCiAgICAgICMgaWYodGVtcCA8IDApe3N0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCJlc3QiXSA9IHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCJlc3QiXSAqLTF9CiAgICAgICMjIyMjIyBwcm9jZWR1cmUgYWR2aXNlZCBieSBFbGxlbiBIYW1ha2VyICAjIyMjIyMjCiAgICAgICMgdW5pcXVlIHBhcnQgb2YgcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgIGxvYWRtID0gICB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsxXQogICAgICBsb2FkcyA9ICB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsyXQogICAgICAjIGNvdmFyaWFuY2UgYmV0d2VlbiByZXNpZHVhbCB2YXJpYW5jZXMKICAgICAgY292bXMgPSBsb2FkcyAqIGxvYWRtCiAgICAgICMgcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgIHZhcnJlc2lkbSA9IHRlbXBbdGVtcCRwYXJhbUhlYWRlciA9PSAiTUlWLnwiLCAiZXN0Il0gKyBsb2FkbSBeIDIKICAgICAgdmFycmVzaWRzID0gdGVtcFt0ZW1wJHBhcmFtSGVhZGVyID09ICJTSVYufCIsICJlc3QiXSArIGxvYWRzIF4gMgogICAgICAjIGNvcnJlbGF0aW9uID0gY292IC8gc3FydCh2YXJyZXNpZG0gKiB2YXJyZXNpZHMpCiAgICAgIHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAiZXN0Il0gPSBjb3ZtcyAvIHNxcnQodmFycmVzaWRtICogdmFycmVzaWRzKQogICAgICAjY29uZmlkZW5jZSBpbnRlcnZhbCBhY2NvcmRpbmcgdG8gT2xpdm90byBldCBhbC4gKDIwMTgpCiAgICAgIENJID0gKGFicyhzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImVzdCJdKSBeIC4zKSAqIDIuMjUxNTIgKiAoTiBeIC0wLjUwMDg5KQogICAgICBzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImxvd2VyXzIuNWNpIl0gPSBzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImVzdCJdIC0gQ0kKICAgICAgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJ1cHBlcl8yLjVjaSJdID0gc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJlc3QiXSArIENJCiAgICAgICMgc3Rkb3V0W2dyZXAoIlNJVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJlc3QiXSA9ZXhwKHJhd291dCRlc3RbcmF3b3V0JHBhcmFtID09ICJTSVYiXSkKICAgICAgIyBzdGRvdXRbZ3JlcCgiU0lWLiIsIHN0ZG91dCRwYXJhbUhlYWRlciksImxvd2VyXzIuNWNpIl0gPWV4cChyYXdvdXQkbG93ZXJfMi41Y2lbcmF3b3V0JHBhcmFtID09ICJTSVYiXSkKICAgICAgIyBzdGRvdXRbZ3JlcCgiU0lWLiIsIHN0ZG91dCRwYXJhbUhlYWRlciksInVwcGVyXzIuNWNpIl0gPWV4cChyYXdvdXQkdXBwZXJfMi41Y2lbcmF3b3V0JHBhcmFtID09ICJTSVYiXSkKICAgICAgIyBpZigiJnBpO20iICVpbiUgdGFibGUyJHBhcmFtKXsKICAgICAgIyAgc3Rkb3V0W2dyZXAoIk1JVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJlc3QiXSA9ZXhwKHJhd291dCRlc3RbcmF3b3V0JHBhcmFtID09ICJNSVYiXSkKICAgICAgIyAgc3Rkb3V0W2dyZXAoIk1JVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJsb3dlcl8yLjVjaSJdID1leHAocmF3b3V0JGxvd2VyXzIuNWNpW3Jhd291dCRwYXJhbSA9PSAiTUlWIl0pCiAgICAgICMgc3Rkb3V0W2dyZXAoIk1JVi4iLCBzdGRvdXQkcGFyYW1IZWFkZXIpLCJ1cHBlcl8yLjVjaSJdID1leHAocmF3b3V0JHVwcGVyXzIuNWNpW3Jhd291dCRwYXJhbSA9PSAiTUlWIl0pCiAgICAgICMgfQogICAgICAjIGFsc28gZm9yIGFkZGl0aW9uYWwgczEKICAgICAgaWYgKGxlbmd0aChhZGRzMW1vZGVscykgPiAxKSB7CiAgICAgICAgIyMjIyMjIHByb2NlZHVyZSBhZHZpc2VkIGJ5IEVsbGVuIEhhbWFrZXIgICMjIyMjIyMKICAgICAgICAjIHVuaXF1ZSBwYXJ0IG9mIHJlc2lkdWFsIHZhcmlhbmNlcwogICAgICAgIGxvYWRtID0gICB0ZW1wczFbdGVtcHMxJHBhcmFtSGVhZGVyID09ICJNX1NfTFYuQlkiLCAiZXN0Il1bMV0KICAgICAgICBsb2FkcyA9ICB0ZW1wczFbdGVtcHMxJHBhcmFtSGVhZGVyID09ICJNX1NfTFYuQlkiLCAiZXN0Il1bMl0KICAgICAgICAjIGNvdmFyaWFuY2UgYmV0d2VlbiByZXNpZHVhbCB2YXJpYW5jZXMKICAgICAgICBjb3ZtcyA9IGxvYWRzICogbG9hZG0KICAgICAgICAjIHJlc2lkdWFsIHZhcmlhbmNlcwogICAgICAgIHZhcnJlc2lkbSA9IHRlbXBzMVt0ZW1wczEkcGFyYW1IZWFkZXIgPT0gIk1JVi58IiwgImVzdCJdICsgbG9hZG0gXiAyCiAgICAgICAgdmFycmVzaWRzID0gdGVtcHMxW3RlbXBzMSRwYXJhbUhlYWRlciA9PSAiU0lWLnwiLCAiZXN0Il0gKyBsb2FkcyBeIDIKICAgICAgICAjIGNvcnJlbGF0aW9uID0gY292IC8gc3FydCh2YXJyZXNpZG0gKiB2YXJyZXNpZHMpCiAgICAgICAgc3Rkb3V0czFbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0czEkcGFyYW0pLCAiZXN0Il0gPSBjb3ZtcyAvIHNxcnQodmFycmVzaWRtICogdmFycmVzaWRzKQogICAgICAgICNjb25maWRlbmNlIGludGVydmFsIGFjY29yZGluZyB0byBPbGl2b3RvIGV0IGFsLiAoMjAxOCkKICAgICAgICBDSSA9IChhYnMoc3Rkb3V0czFbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0czEkcGFyYW0pLCAiZXN0Il0pIF4gLjMpICogMi4yNTE1MiAqIChOIF4gLTAuNTAwODkpCiAgICAgICAgc3Rkb3V0czFbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0czEkcGFyYW0pLCAibG93ZXJfMi41Y2kiXSA9IHN0ZG91dHMxW2dyZXAoIk1fU19MViIsIHN0ZG91dHMxJHBhcmFtKSwgImVzdCJdIC0gQ0kKICAgICAgICBzdGRvdXRzMVtncmVwKCJNX1NfTFYiLCBzdGRvdXRzMSRwYXJhbSksICJ1cHBlcl8yLjVjaSJdID0gc3Rkb3V0czFbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0czEkcGFyYW0pLCAiZXN0Il0gKyBDSQogICAgICB9CiAgICB9CiAgICMgY3JlYXRlIG5vY29uZiBib29sZWFuCiBpZihsZW5ndGgobm9jb25mKSA9PSAxKXsgaWYoc3VtKGlzLm5hKG5vY29uZikpID4gMCkge25vY29uZiA9IHJlcChGLGxlbmd0aChvcmRlcnMpKX0gZWxzZSBpZihub2NvbmYpe25vY29uZiA9IHJlcChULGxlbmd0aChvcmRlcnMpKX19IAppZiAoaHRtbCA9PSBUKSB7CiB0YWJsZTJbIW5vY29uZiwgMl0gPSBwYXN0ZTAoCiAgICAiPHNwYW4gc3R5bGU9XCIiLAogICAgaWZlbHNlKHN0ZG91dCRwdmFsWyFub2NvbmZdIDwgLjAwNSAmIHN0ZG91dHMxJHB2YWxbIW5vY29uZl0gPCAuMDA1LCB5ZXMgPSAiZm9udC13ZWlnaHQ6IGJvbGQ7Iiwgbm8gPSAiOyIpLAogICAgIlwiID4iLAogICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdFshbm9jb25mXSxzdGRvdXRzMSRlc3RbIW5vY29uZl0pKSwgZGlnaXRzID0gMiksCiAgICAiIDxicj4gWyIsCiAgICByb3VuZChyb3dNZWFucyhjYmluZChzdGRvdXQkbG93ZXJfMi41Y2lbIW5vY29uZl0sc3Rkb3V0czEkbG93ZXJfMi41Y2lbIW5vY29uZl0pKSwgZGlnaXRzID0gMiksCiAgICAiICIsCiAgICByb3VuZChyb3dNZWFucyhjYmluZChzdGRvdXQkdXBwZXJfMi41Y2lbIW5vY29uZl0sc3Rkb3V0czEkdXBwZXJfMi41Y2lbIW5vY29uZl0pKSwgZGlnaXRzID0gMiksCiAgICAiXTwvc3Bhbj4iCil9CmlmIChodG1sID09IEYpIHsKICAgIHRhYmxlMlshbm9jb25mLCAyXSA9IGlmZWxzZSgKICAgICAgICBzdGRvdXQkcHZhbFshbm9jb25mXSA8IC4wMDUgJiBzdGRvdXRzMSRwdmFsWyFub2NvbmZdIDwgLjAwNSwKICAgICAgICB5ZXMgPSBwYXN0ZTAoCiAgICAgICAgICAgIHJvdW5kKHJvd01lYW5zKGNiaW5kKHN0ZG91dCRlc3RbIW5vY29uZl0sc3Rkb3V0czEkZXN0WyFub2NvbmZdKSksIGRpZ2l0cyA9IDIpLAogICAgICAgICAgICAiIFsiLAogICAgICAgICAgICByb3VuZChyb3dNZWFucyhjYmluZChzdGRvdXQkbG93ZXJfMi41Y2lbIW5vY29uZl0sc3Rkb3V0czEkbG93ZXJfMi41Y2lbIW5vY29uZl0pKSwgZGlnaXRzID0gMiksCiAgICAgICAgICAgICIgIiwKICAgICAgICAgICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JHVwcGVyXzIuNWNpWyFub2NvbmZdLHN0ZG91dHMxJHVwcGVyXzIuNWNpWyFub2NvbmZdKSksIGRpZ2l0cyA9IDIpLAogICAgICAgICAgICAiXSIKICAgICAgICApLAogICAgICAgIG5vID0gIiIKICAgICkKfQojIAojIHRhYmxlMltub2NvbmYsIDJdID0gcGFzdGUwKAojICAgICAiPHNwYW4gc3R5bGU9XCIiLAojICAgICBpZmVsc2Uoc3Rkb3V0JHB2YWwgPCAuMDA1LCB5ZXMgPSAiZm9udC13ZWlnaHQ6IGJvbGQ7Iiwgbm8gPSAiOyIpLAojICAgICAiXCIgPiIsCiMgICAgIHJvdW5kKHJvd01lYW5zKGNiaW5kKHN0ZG91dCRlc3Qsc3Rkb3V0czEkZXN0KSksIGRpZ2l0cyA9IDIpLAojICAgICAiPC9zcGFuPiIKIyApCiMgaWYgKGh0bWwgPT0gRikgewojICAgICB0YWJsZTJbbm9jb25mLCAyXSA9IGlmZWxzZShzdGRvdXQkcHZhbCA8IC4wMDUsIHllcyA9IHBhc3RlMChyb3VuZChyb3dNZWFucyhjYmluZChzdGRvdXQkZXN0LHN0ZG91dHMxJGVzdCkpLCBkaWdpdHMgPSAyKSksIG5vID0gIiIpCiMgfQogICAgCiAgICAjIGlmIGNlbGxzIHdpdGhvdXQgY29uZmlkZW5jZSBpbnRlcnZhbCB0aGVuIHVzZSBlc3RpbWF0ZXMgb2YgdGhlIHR3byBTLTEgbW9kZWxzIGluIHRoZXNlIGNlbGxzCiAgICBpZihzdW0obm9jb25mKSA+IDApewogICAgaWYgKGh0bWwgPT0gVCkgewogICAgICB0YWJsZTJbbm9jb25mLCAyXSA9IHBhc3RlMCgKICAgICAgICAiPHNwYW4gc3R5bGU9XCIiLAogICAgICAgIGlmZWxzZShzdGRvdXQkcHZhbFtub2NvbmZdIDwgLjAwNSAmIHN0ZG91dHMxJHB2YWxbbm9jb25mXSA8IC4wMDUgJiAhKChwbWluKHN0ZG91dCRlc3Rbbm9jb25mXSwgc3Rkb3V0czEkZXN0W25vY29uZl0pIDw9IDApICYgKDAgPD0gcG1heChzdGRvdXQkZXN0W25vY29uZl0sIHN0ZG91dHMxJGVzdFtub2NvbmZdKSkpICwgeWVzID0gImZvbnQtd2VpZ2h0OiBib2xkOyIsIG5vID0gIjsiKSwKICAgICAgICAiXCIgPiIsCiAgICAgICAgaWZlbHNlKCEocG1pbihzdGRvdXQkZXN0W25vY29uZl0sIHN0ZG91dHMxJGVzdFtub2NvbmZdKSA8PSAwKSAmICgwIDw9IHBtYXgoc3Rkb3V0JGVzdFtub2NvbmZdLCBzdGRvdXRzMSRlc3Rbbm9jb25mXSkpLCB5ZXMgPSAiPGI+Iiwgbm8gPSAiIiksCiAgICAgICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdFtub2NvbmZdLCBzdGRvdXRzMSRlc3Rbbm9jb25mXSksIG5hLnJtID0gVCksIGRpZ2l0cyA9IDIpLAogICAgICAgICI8L2I+PGJyPiBbIiwKICAgICAgICBpZmVsc2Uoc3Rkb3V0JHB2YWxbbm9jb25mXSA8IC4wMDUsIHllcyA9ICI8Yj4iLCBubyA9ICIiKSwKICAgICAgICByb3VuZChzdGRvdXQkZXN0W25vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICIgIiwKICAgICAgICBpZmVsc2Uoc3Rkb3V0czEkcHZhbFtub2NvbmZdIDwgLjAwNSwgeWVzID0gIjwvYj48Yj4iLCBubyA9ICI8L2I+IiksCiAgICAgICAgcm91bmQoc3Rkb3V0czEkZXN0W25vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICI8L2I+XSIsCiAgICAgICAgIjwvc3Bhbj4iCiAgICAgICl9CiAgICBpZiAoaHRtbCA9PSBGKSB7CiAgICAgIHRhYmxlMltub2NvbmYsIDJdID0gaWZlbHNlKHN0ZG91dCRwdmFsW25vY29uZl0gPCAuMDA1LCB5ZXMgPSBwYXN0ZTAocm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdFtub2NvbmZdLCBzdGRvdXRzMSRlc3Rbbm9jb25mXSksIG5hLnJtID0gVCksIGRpZ2l0cyA9IDIpKSwgbm8gPSAiIikKICAgIH0KICAgIH0KICAgICMKICAgICMgdGFibGUyWywyXSA9IHBhc3RlMCgiPHNwYW4gc3R5bGU9XCIiLCBpZmVsc2Uoc3Rkb3V0JHB2YWwgPC4wMDUseWVzID0gImZvbnQtd2VpZ2h0OiBib2xkOyBkaXNwbGF5OmJsb2NrO3dpZHRoOjEwMCU7YmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7Iiwgbm8gPSAiZGlzcGxheTpibG9jazt3aWR0aDoxMDAlO2JhY2tncm91bmQtY29sb3I6eWVsbG93OyIpLCAgICJcIiA+Iixyb3VuZChzdGRvdXQkZXN0LGRpZ2l0cyA9IDIpLCIgPGJyPiBbIixyb3VuZChzdGRvdXQkbG93ZXJfMi41Y2ksZGlnaXRzID0gMiksIiAiLHJvdW5kKHN0ZG91dCR1cHBlcl8yLjVjaSxkaWdpdHMgPSAyKSwiXTwvc3Bhbj4iKQogICAgIwogICAgIyB0YWJsZTJbLDJdPSBwYXN0ZShyb3VuZChzdGRvdXQkZXN0LGRpZ2l0cyA9IDIpLHBhc3RlMCgiPGJyPlsiLHJvdW5kKHN0ZG91dCRsb3dlcl8yLjVjaSxkaWdpdHMgPSAyKSwgIiAiLHJvdW5kKHN0ZG91dCR1cHBlcl8yLjVjaSxkaWdpdHMgPSAyKSwiXSIpKQogICAgIyBtYWtlIHRhYmxlIHdpdGggc2lnbmlmaWNhbmNlCiAgICB0YWJsZTJwID0gdGFibGUyWywgMToyXQogICAgbmFtZXModGFibGUycClbMl0gPSB0YWJsZW5hbWVzWzFdCiAgICB0YWJsZTJwWywgMl0gPSBhcHBseShjYmluZChzdGRvdXQkcHZhbCwgc3Rkb3V0czEkcHZhbCksIDEsIGZ1bmN0aW9uICh4KQogICAgICBtYXgoeCwgbmEucm0gPSBUKSkKICAgICMgbWFrZSB0YWJsZSB3aXRoIHJlZ3Jlc3Npb253ZWlnaHQKICAgIHRhYmxlMnIgPSB0YWJsZTJbLCAxOjJdCiAgICBuYW1lcyh0YWJsZTJyKVsyXSA9IHRhYmxlbmFtZXNbMV0KICAgIHRhYmxlMnJbLCAyXSA9IHJvd01lYW5zKGNiaW5kKHN0ZG91dCRlc3QsIHN0ZG91dHMxJGVzdCksIG5hLnJtID0gVCkKICAgICMgbWFrZSB0YWJsZSB3aXRoIGFsbCBtb2RlbHMKICAgIGZvciAoaSBpbiAyOmxlbmd0aChtcGxvZGVsbmFtZXMpKSB7CiAgICAgICMgcmVhZCBtcGx1cyBtb2RlbAogICAgICBtcGxvZGVsID0gcmVhZE1vZGVscyh0YXJnZXQgPSBtcGxvZGVsbmFtZXNbaV0pCiAgICAgICNleHRyYWN0IHN0ZCBwYXJhbXMKICAgICAgc3Rkb3V0ID0gbXBsb2RlbCRwYXJhbWV0ZXJzJHN0ZHl4LnN0YW5kYXJkaXplZAogICAgICAjIHRha2UgdW5zdGFuZGFyZGl6ZWQgaWYgc3RkIGlzIG5vdCBhdmFpbGFibGUKICAgICAgaWYgKGlzLm51bGwoc3Rkb3V0KSkgewogICAgICAgIHN0ZG91dCA9IG1wbG9kZWwkcGFyYW1ldGVycyR1bnN0YW5kYXJkaXplZAogICAgICAgICMgbGFyZ2UgcCB2YWx1ZSBmb3IgdW5zdGFuZGFyZGl6ZWQgc28gdGhhdCBpdCBnZXRzIG1hcmtlZCBpbiBmaW5hbCB0YWJsZQogICAgICAgIHN0ZG91dCRwdmFsID0gMQogICAgICAgIHN0ZG91dCRsb3dlcl8yLjVjaSA9IC0xCiAgICAgICAgc3Rkb3V0JHVwcGVyXzIuNWNpID0gMQogICAgICB9CiAgICAgICNkZWxldGUgdW5uZWNlc3Nhcnkgcm93cwogICAgICBzdGRvdXQgPSBzdGRvdXRbLWdyZXAoImVzaWR1YWwiLCBzdGRvdXQkcGFyYW1IZWFkZXIpICwgXQogICAgICBzdGRvdXQgPSBzdGRvdXRbLWdyZXAoIm50ZXJjZXB0Iiwgc3Rkb3V0JHBhcmFtSGVhZGVyKSAsIF0KICAgICAgcm93bmFtZXMoc3Rkb3V0KSA9IDE6ZGltKHN0ZG91dClbMV0KICAgICAgIyBmb3IgbXhlIGNhbGMKICAgICAgdGVtcCA9IHN0ZG91dAogICAgICAjIHJlb3JkZXIgd2l0aGluLCBiZXR3ZWVuLCBwcmVkIGFuZCBleHRyYWN0IG9ubHkgdmFyaWFibGVzIHdlIGFyZSBpbnRlcmVzdGVkIGluCiAgICAgIHN0ZG91dCA9IHN0ZG91dFtvcmRlcnMsIF0KICAgICAgaWYgKGxlbmd0aChhZGRzMW1vZGVscykgPiAxKSB7CiAgICAgICAgIyByZWFkIGFkZGl0aW9uYWwgUzEgbW9kZWwKICAgICAgICAjIHJlYWQgbXBsdXMgbW9kZWwKICAgICAgICBhZGRzMW1vZGVsID0gcmVhZE1vZGVscyh0YXJnZXQgPSBhZGRzMW1vZGVsc1tpXSkKICAgICAgICAjZXh0cmFjdCBzdGQgcGFyYW1zCiAgICAgICAgc3Rkb3V0czEgPSBhZGRzMW1vZGVsJHBhcmFtZXRlcnMkc3RkeXguc3RhbmRhcmRpemVkCiAgICAgICAgIyB0YWtlIHVuc3RhbmRhcmRpemVkIGlmIHN0ZCBpcyBub3QgYXZhaWxhYmxlCiAgICAgICAgaWYgKGlzLm51bGwoc3Rkb3V0czEpKSB7CiAgICAgICAgICBzdGRvdXRzMSA9IGFkZHMxbW9kZWwkcGFyYW1ldGVycyR1bnN0YW5kYXJkaXplZAogICAgICAgICAgIyBsYXJnZSBwIHZhbHVlIGZvciB1bnN0YW5kYXJkaXplZCBzbyB0aGF0IGl0IGdldHMgbWFya2VkIGluIGZpbmFsIHRhYmxlCiAgICAgICAgICBzdGRvdXRzMSRwdmFsID0gMQogICAgICAgICAgc3Rkb3V0czEkbG93ZXJfMi41Y2kgPSAtMQogICAgICAgICAgc3Rkb3V0czEkdXBwZXJfMi41Y2kgPSAxCiAgICAgICAgICAjIHN0ZG91dHMxID0gc3Rkb3V0CiAgICAgICAgICAjIHN0ZG91dHMxWywzOm5jb2woc3Rkb3V0czEpXSA9IE5BCiAgICAgICAgfQogICAgICAgICNkZWxldGUgdW5uZWNlc3Nhcnkgcm93cwogICAgICAgIHN0ZG91dHMxID0gc3Rkb3V0czFbLWdyZXAoImVzaWR1YWwiLCBzdGRvdXRzMSRwYXJhbUhlYWRlcikgLCBdCiAgICAgICAgc3Rkb3V0czEgPSBzdGRvdXRzMVstZ3JlcCgibnRlcmNlcHQiLCBzdGRvdXRzMSRwYXJhbUhlYWRlcikgLCBdCiAgICAgICAgcm93bmFtZXMoc3Rkb3V0czEpID0gMTpkaW0oc3Rkb3V0czEpWzFdCiAgICAgICAgIyBmb3IgbXhlIGNhbGMKICAgICAgICB0ZW1wczEgPSBzdGRvdXRzMQogICAgICAgICMgcmVvcmRlciB3aXRoaW4sIGJldHdlZW4sIHByZWQgYW5kIGV4dHJhY3Qgb25seSB2YXJpYWJsZXMgd2UgYXJlIGludGVyZXN0ZWQgaW4KICAgICAgICBzdGRvdXRzMSA9IHN0ZG91dHMxW29yZGVyczEsIF0KICAgICAgfQogICAgICAjIGNoZWNrIGF2YWlsYWJsZSBOIGFmdGVyIHJlbW92YWwgb2YgY2FzZXMgd28gdmFyaWFuY2UgYW5kIG9yCiAgICAgIG5vY2FzZXMgPSB1bmxpc3QocmVnbWF0Y2hlcyh1bmxpc3QobXBsb2RlbCR3YXJuaW5ncyksIGdyZWdleHByKAogICAgICAgICdbMC05XSsnLCB1bmxpc3QobXBsb2RlbCR3YXJuaW5ncykKICAgICAgKSkpCiAgICAgIG5vY2FzZXMgPSBub2Nhc2VzW25jaGFyKG5vY2FzZXMpID4gMV0KICAgICAgTiA9IG1wbG9kZWwkZGF0YV9zdW1tYXJ5JG92ZXJhbGwkTkNsdXN0ZXJzIC0gbGVuZ3RoKG5vY2FzZXMpCiAgICAgIGlmIChsb2d0cmFuc3BhcmFtcyA9PSBUKSB7CiAgICAgICAgIyMjIyMjIHByb2NlZHVyZSBhZHZpc2VkIGJ5IEVsbGVuIEhhbWFrZXIgICMjIyMjIyMKICAgICAgICAjIHVuaXF1ZSBwYXJ0IG9mIHJlc2lkdWFsIHZhcmlhbmNlcwogICAgICAgIGxvYWRtID0gICB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsxXQogICAgICAgIGxvYWRzID0gIHRlbXBbdGVtcCRwYXJhbUhlYWRlciA9PSAiTV9TX0xWLkJZIiwgImVzdCJdWzJdCiAgICAgICAgIyBjb3ZhcmlhbmNlIGJldHdlZW4gcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgICAgY292bXMgPSBsb2FkcyAqIGxvYWRtCiAgICAgICAgIyByZXNpZHVhbCB2YXJpYW5jZXMKICAgICAgICB2YXJyZXNpZG0gPSB0ZW1wW3RlbXAkcGFyYW1IZWFkZXIgPT0gIk1JVi58IiwgImVzdCJdICsgbG9hZG0gXiAyCiAgICAgICAgdmFycmVzaWRzID0gdGVtcFt0ZW1wJHBhcmFtSGVhZGVyID09ICJTSVYufCIsICJlc3QiXSArIGxvYWRzIF4gMgogICAgICAgICMgY29ycmVsYXRpb24gPSBjb3YgLyBzcXJ0KHZhcnJlc2lkbSAqIHZhcnJlc2lkcykKICAgICAgICBzdGRvdXRbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0JHBhcmFtKSwgImVzdCJdID0gY292bXMgLyBzcXJ0KHZhcnJlc2lkbSAqIHZhcnJlc2lkcykKICAgICAgICAjY29uZmlkZW5jZSBpbnRlcnZhbCBhY2NvcmRpbmcgdG8gT2xpdm90byBldCBhbC4gKDIwMTgpCiAgICAgICAgQ0kgPSAoYWJzKHN0ZG91dFtncmVwKCJNX1NfTFYiLCBzdGRvdXQkcGFyYW0pLCAiZXN0Il0pIF4gLjMpICogMi4yNTE1MiAqIChOIF4gLTAuNTAwODkpCiAgICAgICAgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJsb3dlcl8yLjVjaSJdID0gc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJlc3QiXSAtIENJCiAgICAgICAgc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJ1cHBlcl8yLjVjaSJdID0gc3Rkb3V0W2dyZXAoIk1fU19MViIsIHN0ZG91dCRwYXJhbSksICJlc3QiXSArIENJCiAgICAgICAgIyBhbHNvIGZvciBhZGRpdGlvbmFsIHMxCiAgICAgICAgaWYgKGxlbmd0aChhZGRzMW1vZGVscykgPiAxKSB7CiAgICAgICAgICAjIyMjIyMgcHJvY2VkdXJlIGFkdmlzZWQgYnkgRWxsZW4gSGFtYWtlciAgIyMjIyMjIwogICAgICAgICAgIyB1bmlxdWUgcGFydCBvZiByZXNpZHVhbCB2YXJpYW5jZXMKICAgICAgICAgIGxvYWRtID0gICB0ZW1wczFbdGVtcHMxJHBhcmFtSGVhZGVyID09ICJNX1NfTFYuQlkiLCAiZXN0Il1bMV0KICAgICAgICAgIGxvYWRzID0gIHRlbXBzMVt0ZW1wczEkcGFyYW1IZWFkZXIgPT0gIk1fU19MVi5CWSIsICJlc3QiXVsyXQogICAgICAgICAgIyBjb3ZhcmlhbmNlIGJldHdlZW4gcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgICAgICBjb3ZtcyA9IGxvYWRzICogbG9hZG0KICAgICAgICAgICMgcmVzaWR1YWwgdmFyaWFuY2VzCiAgICAgICAgICB2YXJyZXNpZG0gPSB0ZW1wczFbdGVtcHMxJHBhcmFtSGVhZGVyID09ICJNSVYufCIsICJlc3QiXSArIGxvYWRtIF4gMgogICAgICAgICAgdmFycmVzaWRzID0gdGVtcHMxW3RlbXBzMSRwYXJhbUhlYWRlciA9PSAiU0lWLnwiLCAiZXN0Il0gKyBsb2FkcyBeIDIKICAgICAgICAgICMgY29ycmVsYXRpb24gPSBjb3YgLyBzcXJ0KHZhcnJlc2lkbSAqIHZhcnJlc2lkcykKICAgICAgICAgIHN0ZG91dHMxW2dyZXAoIk1fU19MViIsIHN0ZG91dHMxJHBhcmFtKSwgImVzdCJdID0gY292bXMgLyBzcXJ0KHZhcnJlc2lkbSAqIHZhcnJlc2lkcykKICAgICAgICAgICNjb25maWRlbmNlIGludGVydmFsIGFjY29yZGluZyB0byBPbGl2b3RvIGV0IGFsLiAoMjAxOCkKICAgICAgICAgIENJID0gKGFicyhzdGRvdXRzMVtncmVwKCJNX1NfTFYiLCBzdGRvdXRzMSRwYXJhbSksICJlc3QiXSkgXiAuMykgKiAyLjI1MTUyICogKE4gXiAtMC41MDA4OSkKICAgICAgICAgIHN0ZG91dHMxW2dyZXAoIk1fU19MViIsIHN0ZG91dHMxJHBhcmFtKSwgImxvd2VyXzIuNWNpIl0gPSBzdGRvdXRzMVtncmVwKCJNX1NfTFYiLCBzdGRvdXRzMSRwYXJhbSksICJlc3QiXSAtIENJCiAgICAgICAgICBzdGRvdXRzMVtncmVwKCJNX1NfTFYiLCBzdGRvdXRzMSRwYXJhbSksICJ1cHBlcl8yLjVjaSJdID0gc3Rkb3V0czFbZ3JlcCgiTV9TX0xWIiwgc3Rkb3V0czEkcGFyYW0pLCAiZXN0Il0gKyBDSQogICAgICAgIH0KICAgICAgfQogICAgICAKI2lmIHRoZXJlIGFyZSBjZWxscyB3aXRoIGNvbmZpbnRzCiAgaWYoc3VtKCFub2NvbmYpPjApewogICAgICAKICAgICAgaWYgKGh0bWwgPT0gVCkgewogICAgICAjcHV0IHBhcmFtcwogICAgICB0YWJsZTJbIW5vY29uZiwgaSsxXSA9IHBhc3RlMCgKICAgICI8c3BhbiBzdHlsZT1cIiIsCiAgICBpZmVsc2Uoc3Rkb3V0JHB2YWxbIW5vY29uZl0gPCAuMDA1ICYgc3Rkb3V0czEkcHZhbFshbm9jb25mXSA8IC4wMDUsIHllcyA9ICJmb250LXdlaWdodDogYm9sZDsiLCBubyA9ICI7IiksCiAgICAiXCIgPiIsCiAgICByb3VuZChyb3dNZWFucyhjYmluZChzdGRvdXQkZXN0LHN0ZG91dHMxJGVzdCkpWyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICIgPGJyPiBbIiwKICAgIHJvdW5kKHJvd01lYW5zKGNiaW5kKHN0ZG91dCRsb3dlcl8yLjVjaSxzdGRvdXRzMSRsb3dlcl8yLjVjaSkpWyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICIgIiwKICAgIHJvdW5kKHJvd01lYW5zKGNiaW5kKHN0ZG91dCR1cHBlcl8yLjVjaSxzdGRvdXRzMSR1cHBlcl8yLjVjaSkpWyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICJdPC9zcGFuPiIKKX0KaWYgKGh0bWwgPT0gRikgewogICAgdGFibGUyWyFub2NvbmYsIGkgKzFdID0gaWZlbHNlKAogICAgICAgIHN0ZG91dCRwdmFsWyFub2NvbmZdIDwgLjAwNSAmIHN0ZG91dHMxJHB2YWxbIW5vY29uZl0gPCAuMDA1LAogICAgICAgIHllcyA9IHBhc3RlMCgKICAgICAgICAgICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdCxzdGRvdXRzMSRlc3QpKVshbm9jb25mXSwgZGlnaXRzID0gMiksCiAgICAgICAgICAgICIgPGJyPiBbIiwKICAgICAgICAgICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGxvd2VyXzIuNWNpLHN0ZG91dHMxJGxvd2VyXzIuNWNpKSlbIW5vY29uZl0sIGRpZ2l0cyA9IDIpLAogICAgICAgICAgICAiICIsCiAgICAgICAgICAgIHJvdW5kKHJvd01lYW5zKGNiaW5kKHN0ZG91dCR1cHBlcl8yLjVjaSxzdGRvdXRzMSR1cHBlcl8yLjVjaSkpWyFub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAgICAgIl0iCiAgICAgICAgKSwKICAgICAgICBubyA9ICIiCiAgICApCn19CiMgCiMgdGFibGUyW25vY29uZiwgaSArMV0gPSBwYXN0ZTAoCiMgICAgICI8c3BhbiBzdHlsZT1cIiIsCiMgICAgIGlmZWxzZShzdGRvdXQkcHZhbCA8IC4wMDUsIHllcyA9ICJmb250LXdlaWdodDogYm9sZDsiLCBubyA9ICI7IiksCiMgICAgICJcIiA+IiwKIyAgICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdCxzdGRvdXRzMSRlc3QpKSwgZGlnaXRzID0gMiksCiMgICAgICI8L3NwYW4+IgojICkKIyBpZiAoaHRtbCA9PSBGKSB7CiMgICAgIHRhYmxlMltub2NvbmYsIDJdID0gaWZlbHNlKHN0ZG91dCRwdmFsIDwgLjAwNSwgeWVzID0gcGFzdGUwKHJvdW5kKHJvd01lYW5zKGNiaW5kKHN0ZG91dCRlc3Qsc3Rkb3V0czEkZXN0KSksIGRpZ2l0cyA9IDIpKSwgbm8gPSAiIikKIyB9CiAgICAgIAogICMgaWYgY2VsbHMgd2l0aG91dCBjb25maW50IHVzZSBlc3RpbWF0ZXMgZnJvbSB0aGUgdHdvIFMtMSBtb2RlbHMgICAgCiAgIGlmKHN1bShub2NvbmYpID4gMCl7CiAgICAgaWYgKGh0bWwgPT0gVCkgewogICAgICB0YWJsZTJbbm9jb25mLCBpICsxXSA9IHBhc3RlMCgKICAgICAgICAiPHNwYW4gc3R5bGU9XCIiLAogICAgICAgIGlmZWxzZShzdGRvdXQkcHZhbFtub2NvbmZdIDwgLjAwNSAmIHN0ZG91dHMxJHB2YWxbbm9jb25mXSA8IC4wMDUgJiAhKChwbWluKHN0ZG91dCRlc3Rbbm9jb25mXSwgc3Rkb3V0czEkZXN0W25vY29uZl0pIDw9IDApICYgKDAgPD0gcG1heChzdGRvdXQkZXN0W25vY29uZl0sIHN0ZG91dHMxJGVzdFtub2NvbmZdKSkpICwgeWVzID0gImZvbnQtd2VpZ2h0OiBib2xkOyIsIG5vID0gIjsiKSwKICAgICAgICAiXCIgPiIsCiAgICAgICAgaWZlbHNlKCEocG1pbihzdGRvdXQkZXN0W25vY29uZl0sIHN0ZG91dHMxJGVzdFtub2NvbmZdKSA8PSAwKSAmICgwIDw9IHBtYXgoc3Rkb3V0JGVzdFtub2NvbmZdLCBzdGRvdXRzMSRlc3Rbbm9jb25mXSkpLCB5ZXMgPSAiPGI+Iiwgbm8gPSAiIiksCiAgICAgICAgcm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdCwgc3Rkb3V0czEkZXN0KSwgbmEucm0gPSBUKVtub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAiPC9iPjxicj4gWyIsCiAgICAgICAgaWZlbHNlKHN0ZG91dCRwdmFsW25vY29uZl0gPCAuMDA1LCB5ZXMgPSAiPGI+Iiwgbm8gPSAiIiksCiAgICAgICAgcm91bmQoc3Rkb3V0JGVzdFtub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAiICIsCiAgICAgICAgaWZlbHNlKHN0ZG91dHMxJHB2YWxbbm9jb25mXSA8IC4wMDUsIHllcyA9ICI8L2I+PGI+Iiwgbm8gPSAiPC9iPiIpLAogICAgICAgIHJvdW5kKHN0ZG91dHMxJGVzdFtub2NvbmZdLCBkaWdpdHMgPSAyKSwKICAgICAgICAiPC9iPl0iLAogICAgICAgICI8L3NwYW4+IgogICAgICApfQogICAgaWYgKGh0bWwgPT0gRikgewogICAgICB0YWJsZTJbbm9jb25mLCBpICsxXSA9IGlmZWxzZShzdGRvdXQkcHZhbFtub2NvbmZdIDwgLjAwNSAmIHN0ZG91dHMxJHB2YWxbbm9jb25mXSA8IC4wMDUgJiAhKChwbWluKHN0ZG91dCRlc3Rbbm9jb25mXSwgc3Rkb3V0czEkZXN0W25vY29uZl0pIDw9IDApICYgKDAgPD0gcG1heChzdGRvdXQkZXN0W25vY29uZl0sIHN0ZG91dHMxJGVzdFtub2NvbmZdKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZXMgPSBwYXN0ZTAocm91bmQocm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdCwgc3Rkb3V0czEkZXN0KSwgbmEucm0gPSBUKVtub2NvbmZdLCBkaWdpdHMgPSAyKSksIG5vID0gIiIpCiAgICB9fQogICAgICBuYW1lcyh0YWJsZTIpW2kgKyAxXSA9IHBhc3RlMCh0YWJsZW5hbWVzW2ldLCAiIE49IiwgTiwgIjxicj4gc3RkeXguIikKICAgICAgIyBjcmVhdGUgdGFibGUgd2l0aCBib2xkbmVzcyB3aGVuIG5vbm92ZXJsYXBwaW5nIGNpCiAgICAgIGlmIChwcmVkdGFibGUgPT0gVCkgewogICAgICAgICMgYm9sZCBmb3Igbm9uLW92ZXJsYXBwaW5nIFBGIGFuZCBEZXAgY29uZiBpbnQKICAgICAgICB0YWJsZWJvbGRzWywgaSArIDFdID0gRkFMU0UKICAgICAgICBkID0gMQogICAgICAgIHdoaWxlIChkIDwgZGltKHN0ZG91dClbMV0pIHsKICAgICAgICAgIGExID0gc3Rkb3V0JGxvd2VyXzIuNWNpW2RdCiAgICAgICAgICBhMiA9IHN0ZG91dCR1cHBlcl8yLjVjaVtkXQogICAgICAgICAgYjEgPSBzdGRvdXQkbG93ZXJfMi41Y2lbZCArIDFdCiAgICAgICAgICBiMiA9IHN0ZG91dCR1cHBlcl8yLjVjaVtkICsgMV0KICAgICAgICAgIGlmICghKChhMSA8PSBiMikgJiYgKGIxIDw9IGEyKSkpIHsKICAgICAgICAgICAgdGFibGVib2xkc1tkLCBpICsgMV0gPSBUCiAgICAgICAgICAgIHRhYmxlYm9sZHNbZCArIDEsIGkgKyAxXSA9IFQKICAgICAgICAgIH0KICAgICAgICAgIGQgPSBkICsgMgogICAgICAgIH0KICAgICAgfSBlbHNlewogICAgICAgIHRhYmxlYm9sZHNbLCBpICsgMV0gPSBGQUxTRQogICAgICB9CiAgICAgICMgcHV0IGluIHRhYmxlIHdpdGggc2lnbmlmaWNhbmNlCiAgICAgIHRhYmxlMnBbLCBpICsgMV0gPSBhcHBseShjYmluZChzdGRvdXQkcHZhbCwgc3Rkb3V0czEkcHZhbCksIDEsIGZ1bmN0aW9uICh4KQogICAgICAgIG1heCh4LCBuYS5ybSA9IFQpKQogICAgICBuYW1lcyh0YWJsZTJwKVtpICsgMV0gPSB0YWJsZW5hbWVzW2ldCiAgICAgICMgcHV0IGluIHRhYmxlIHdpdGggcmVncmVzc2lvbgogICAgICB0YWJsZTJyWywgaSArIDFdID0gcm93TWVhbnMoY2JpbmQoc3Rkb3V0JGVzdCwgc3Rkb3V0czEkZXN0KSwgbmEucm0gPSBUKQogICAgICBuYW1lcyh0YWJsZTJyKVtpICsgMV0gPSB0YWJsZW5hbWVzW2ldCiAgICB9CiAgICByb3duYW1lcyh0YWJsZTIpID0gTlVMTAogICAgcm93bmFtZXModGFibGUycCkgPSBOVUxMCiAgICByb3duYW1lcyh0YWJsZTJyKSA9IE5VTEwKICB9CiAgcmV0dXJuKGxpc3QodGFibGUyLCB0YWJsZTJwLCB0YWJsZTJyLCB0YWJsZWJvbGRzKSkKfQoKCgpgYGAKCgoKIyMgVGFibGVzCmBgYHtyfQoKCiMjIHdpdGhpbiB0YWJsZSBkc2NyZXRlIHNpdHVhdGlvbnMgd2l0aG91dCBtb29kCnRhYmxlID0gdGFibGUyZnVuYyhtcGxvZGVsbmFtZXMgPSBjKCJNb2ROb091dFMxUEZzaXRfbmNuZi5vdXQiLCJNb2ROb091dFMxUEZzaXRfbmVtcC5vdXQiLCJNb2ROb091dFMxUEZzaXRfbm92bC5vdXQiLCJNb2ROb091dFMxUEZzaXRfcHJlbC5vdXQiLCJNb2ROb091dFMxUEZzaXRfcHN1Yy5vdXQiLCJNb2ROb091dFMxUEZzaXRfcHdvLm91dCIpLCB0YWJsZW5hbWVzID0gYygiY29uZmxpY3QiLCJlbXB0aW5lc3Mgb3IgYm9yZWRvbSIsIm92ZXJ3aGVsbWluZyA8YnI+IHRhc2siLCJyZWxheGF0aW9uIiwiYWNoaWV2ZW1lbnQiLCJnb29kIHRpbWUgd2l0aCBzb21lb25lIikscGFyYW1zID0gYygibW0iLCJlZSIsIm14ZSIsIm1lMSIsImVtMSIsIm1pdiIsImVpdiIpLG9yZGVycyA9IGMoMyw1LDcsNCw2LDgsOSksIGh0bWwgPSBULGxvZ3RyYW5zcGFyYW1zID0gVCkKCiMgbG9nIGJhY2sgdHJhbnNmb3JtYXRpb24gbV9zLCBtaXYgc2l2CiNleHAobV9zKSAvIChzcXJ0KGV4cChtaXYpK2V4cChtX3MpKSpzcXJ0KGV4cChzaXYpK2V4cChtX3MpKSkKCmtuaXRyOjprYWJsZSh0YWJsZVtbMV1dLGVzY2FwZSA9IEZBTFNFLCBhbGlnbiA9ICJjIixmb3JtYXQgPSAiaHRtbCIpICU+JQogICAgICBrYWJsZV9wYXBlcigpICU+JSAKICBjb2x1bW5fc3BlYygyLAogICAgICAgICAgICAgIGJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlW1szXV1bLDJdLCBzY2FsZV9mcm9tID0gYygtLjgsLjgpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lIAogIGNvbHVtbl9zcGVjKDMsCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssM10sIHNjYWxlX2Zyb20gPSBjKC0uOCwuOCksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgY29sdW1uX3NwZWMoNCwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw0XSwgc2NhbGVfZnJvbSA9IGMoLS44LC44KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKCiAgY29sdW1uX3NwZWMoNSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw1XSwgc2NhbGVfZnJvbSA9IGMoLS44LC44KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKIAogIGNvbHVtbl9zcGVjKDYsCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssNl0sIHNjYWxlX2Zyb20gPSBjKC0uOCwuOCksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgCiAgIGNvbHVtbl9zcGVjKDcsCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssN10sIHNjYWxlX2Zyb20gPSBjKC0uOCwuOCksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCgogICBhZGRfaGVhZGVyX2Fib3ZlKGMoIiAiLCAiV2l0aGluLVBlcnNvbi1EeW5hbWljcyIgPSA2KSkKICAKCgoKIyMgVGFibGUgd2l0aCBiYXNlbGluZSBQRiwgREVQIGFuZCBldmVudHMgd2l0aCB0d28gYXZlcmFnZWQgUzEgbW9kcwp0YWJsZSA9IHRhYmxlMmZ1bmMobXBsb2RlbG5hbWVzID0gYygiTW9kTm9PdXRTMVBGc2l0X25jbmYub3V0IiwiTW9kTm9PdXRTMVBGc2l0X25lbXAub3V0IiwiTW9kTm9PdXRTMVBGc2l0X25vdmwub3V0IiwiTW9kTm9PdXRTMVBGc2l0X3ByZWwub3V0IiwiTW9kTm9PdXRTMVBGc2l0X3BzdWMub3V0IiwiTW9kTm9PdXRTMVBGc2l0X3B3by5vdXQiKSwgYWRkczFtb2RlbHMgPSBjKCJNb2ROb091dFMxREVQc2l0X25jbmYub3V0IiwiTW9kTm9PdXRTMURFUHNpdF9uZW1wLm91dCIsIk1vZE5vT3V0UzFERVBzaXRfbm92bC5vdXQiLCJNb2ROb091dFMxREVQc2l0X3ByZWwub3V0IiwiTW9kTm9PdXRTMURFUHNpdF9wc3VjLm91dCIsIk1vZE5vT3V0UzFERVBzaXRfcHdvLm91dCIpLCB0YWJsZW5hbWVzID0gYygiY29uZmxpY3QiLCJlbXB0aW5lc3Mgb3IgYm9yZWRvbSIsIm92ZXJ3aGVsbWluZyA8YnI+IHRhc2siLCJyZWxheGF0aW9uIiwiYWNoaWV2ZW1lbnQiLCJnb29kIHRpbWUgd2l0aCBzb21lb25lIiksCnBhcmFtcyA9IGMoIlBGfj5tbSIsICAgIkRFUH4+bW0iLCJQRn4+c3MiLCAgICJERVB+PnNzIiwiUEZ+Pm14ZSIsICAgIkRFUH4+bXhlIiAsICJQRn4+bWUxIiwiREVQfj5tZTEiLCJQRn4+ZW0xIiwgICJERVB+PmVtMSIsICJQRn4+bWl2IiAsICJERVB+Pm1pdiIsIlBGfj5laXYiICwgIkRFUH4+ZWl2IiwiUEZ+PiZlbXB0eTttb29kIiAsICJERVB+PiZlbXB0eTttb29kIiAsIlBGfj4mZW1wdHk7ZXZlbnQiICwgIkRFUH4+JmVtcHR5O2V2ZW50Iiksb3JkZXJzID0gYygzNCwzNSwzNiwzNywyOCwyOSwzOCwzOSw0MCw0MSwzMCwzMSwzMiwzMyw0Miw0Myw0NCw0NSksIG9yZGVyczEgPSBjKDQzLCA0NCwgNDUsIDQ2LCAzNywgMzgsIDQ3LCA0OCwgNDksIDUwLCAzOSwgNDAsIDQxLCA0MiwgNTEsIDUyLCA1MywgNTQpLCBodG1sID0gVCwgcHJlZHRhYmxlID0gRiwgbm9jb25mID0gVCkKCnRhYmxlW1sxXV0lPiUga2FibGUoZXNjYXBlID0gRkFMU0UsIGFsaWduID0gImMiLGZvcm1hdCA9ICJodG1sIikgJT4lCmthYmxlX3BhcGVyKCkgJT4lCmNvbHVtbl9zcGVjKDIsYm9sZCA9IHRhYmxlW1s0XV1bLDJdLApiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWywyXSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDMsYm9sZCA9IHRhYmxlW1s0XV1bLDNdLApiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWywzXSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDQsYm9sZCA9IHRhYmxlW1s0XV1bLDRdLApiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw0XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDUsYm9sZCA9IHRhYmxlW1s0XV1bLDVdLApiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw1XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDYsYm9sZCA9IHRhYmxlW1s0XV1bLDZdLApiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw2XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDcsYm9sZCA9IHRhYmxlW1s0XV1bLDddLApiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw3XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmFkZF9oZWFkZXJfYWJvdmUoYygiICIsICJQcmVkaWN0aW9uIG9mIGF2ZXJhZ2VkIGJldHdlZW4tcGVyc29uIGRpZmZlcmVuY2VzIGluIHdpdGhpbi1wZXJzb24gYWZmZWN0LXNpdGF0aW9uIGR5bmFtaWNzIiA9IDYpKQoKCiMjIFByZWRpY3Rpb24gdGFibGUKdGFibGUyID0gdGFibGUyZnVuYyhtcGxvZGVsbmFtZXMgPSBjKCJNb2RlbDFZbmNuZlMxUENPLm91dCIsIk1vZGVsMVluZW1wUzFQQ08ub3V0IiwiTW9kZWwxWW5vdmxTMVBDTy5vdXQiLCJNb2RlbDFZcHJlbFMxUENPLm91dCIsIk1vZGVsMVlwc3VjUzFQQ08ub3V0IiwiTW9kZWwxWXB3b1MxUENPLm91dCIpLCBhZGRzMW1vZGVscyA9IGMoIk1vZGVsMVluY25mUzFQQ09EZXAub3V0IiwiTW9kZWwxWW5lbXBTMVBDT0RlcC5vdXQiLCJNb2RlbDFZbm92bFMxUENPRGVwLm91dCIsIk1vZGVsMVlwcmVsUzFQQ09EZXAub3V0IiwiTW9kZWwxWXBzdWNTMVBDT0RlcC5vdXQiLCJNb2RlbDFZcHdvUzFQQ09EZXAub3V0IiksIHRhYmxlbmFtZXMgPSBjKCJjb25mbGljdCIsImVtcHRpbmVzcyBvciBib3JlZG9tIiwib3ZlcndoZWxtaW5nIDxicj4gdGFzayIsInJlbGF4YXRpb24iLCJhY2hpZXZlbWVudCIsImdvb2QgdGltZSB3aXRoIHNvbWVvbmUiKSwKcGFyYW1zID0gYygibW1+Pk9QRiIsICAgIm1tfj5PREVQIiwic3N+Pk9QRiIsICAgInNzfj5PREVQIiwibXhlfj5PUEYiLCAgICJteGV+Pk9ERVAiICwgIm1lMX4+T1BGIiwibWUxfj5PREVQIiwiZW0xfj5PUEYiLCAgImVtMX4+T0RFUCIsICJtaXZ+Pk9QRiIgLCAibWl2fj5PREVQIiwiZWl2fj5PUEYiICwgImVpdn4+T0RFUCIsIiZlbXB0eTttb29kfj5PUEYiICwgIiZlbXB0eTttb29kfj5PREVQIiAsIiZlbXB0eTtldmVudH4+T1BGIiAsICImZW1wdHk7ZXZlbnR+Pk9ERVAiLCJQRn4+T1BGICoiLCJERVB+Pk9QRiAqIiwiUEZ+Pk9ERVAgKiIsIkRFUH4+T0RFUCAqIiksb3JkZXJzID0gYyg2Niw1Nyw2Nyw1OCw3MCw2MSw2OCw1OSw2OSw2MCw3MSw2Miw3Miw2Myw3Nyw3NSw3OCw3Niw3Myw3NCw2NCw2NSksIG9yZGVyczEgPSBjKDc1LCA2NiwgNzYsIDY3LCA3OSwgNzAsIDc3LCA2OCwgNzgsIDY5LCA4MCwgNzEsIDgxLCA3MiwgODYsIDg0LCA4NywgODUsIDgyLCA4MywgNzMsIDc0KSwgaHRtbCA9IFQsIHByZWR0YWJsZSA9IEYsIG5vY29uZiA9IGMoRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgRiwgVCwgVCwgVCwgVCkpCgoKdGFibGUyW1sxXV0lPiUga2FibGUoZXNjYXBlID0gRkFMU0UsIGFsaWduID0gImMiLGZvcm1hdCA9ICJodG1sIikgJT4lCmthYmxlX3BhcGVyKCkgJT4lCmNvbHVtbl9zcGVjKDIsI2JvbGQgPSB0YWJsZTJbWzRdXVssMl0sCmJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlMltbM11dWywyXSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDMsI2JvbGQgPSB0YWJsZTJbWzRdXVssM10sCmJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlMltbM11dWywzXSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDQsI2JvbGQgPSB0YWJsZTJbWzRdXVssNF0sCmJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlMltbM11dWyw0XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDUsI2JvbGQgPSB0YWJsZTJbWzRdXVssNV0sCmJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlMltbM11dWyw1XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDYsI2JvbGQgPSB0YWJsZTJbWzRdXVssNl0sCmJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlMltbM11dWyw2XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmNvbHVtbl9zcGVjKDcsI2JvbGQgPSB0YWJsZTJbWzRdXVssN10sCmJhY2tncm91bmQgPSBzcGVjX2NvbG9yKHRhYmxlMltbM11dWyw3XSwgc2NhbGVfZnJvbSA9IGMoLS45NSwuOTUpLCBwYWxldHRlID1jb2xvclJhbXBQYWxldHRlKGMoIiNmZGU3MjUiLCJ3aGl0ZSIsIiMyMTkxOGMiKSkoMjU2KSkpJT4lCmFkZF9oZWFkZXJfYWJvdmUoYygiICIsICJQcmVkaWN0aW9uIG9mIGJldHdlZW4tcGVyc29uIGRpZmZlcmVuY2VzIGluIFBGIGFuZCBkZXByZXNzaW9uIChhdmVyYWdlZCBvdmVyIG9uZSB5ZWFyKSB1c2luZyB3aXRoaW4tcGVyc29uIGFmZmVjdC1zaXRhdGlvbiBkeW5hbWljcyIgPSA2KSkKCgoKCgojIyBwcmVkaWN0aW9uIHdpdGhpbiBJTiBFQUNIIENFTEwgQk9USCBTMSBQQVJBTVMsIENJcyBhbmQgY29ycmVsYXRlZCBmYWN0b3JzIGluIFNVUFBMRU1FTlQKCnRhYmxlID0gdGFibGUyZnVuYyhtcGxvZGVsbmFtZXMgPSBjKCJNb2ROb091dFMxc2l0X25jbmYub3V0IiwiTW9kTm9PdXRTMURFUHNpdF9uY25mLm91dCIsIk1vZE5vT3V0UzFzaXRfbmVtcC5vdXQiLCJNb2ROb091dFMxREVQc2l0X25lbXAub3V0IiwiTW9kTm9PdXRTMXNpdF9ub3ZsLm91dCIsIk1vZE5vT3V0UzFERVBzaXRfbm92bC5vdXQiLCJNb2ROb091dFMxc2l0X3ByZWwub3V0IiwiTW9kTm9PdXRTMURFUHNpdF9wcmVsLm91dCIsIk1vZE5vT3V0UzFzaXRfcHN1Yy5vdXQiLCJNb2ROb091dFMxREVQc2l0X3BzdWMub3V0IiwiTW9kTm9PdXRTMXNpdF9wd28ub3V0IiwiTW9kTm9PdXRTMURFUHNpdF9wd28ub3V0IiksIHRhYmxlbmFtZXMgPSBjKCJjb25mbGljdCIsImVtcHRpbmVzcyBvciBib3JlZG9tIiwib3ZlcndoZWxtaW5nIDxicj4gdGFzayIsInJlbGF4YXRpb24iLCJhY2hpZXZlbWVudCIsImdvb2QgdGltZSB3aXRoIHNvbWVvbmUiKSwKcGFyYW1zID0gYygiUEZ+PiZQc2k7bWUiLCAgICJERVB+PiZQc2k7bWUiICwgIlBGfj4mUGhpO2VlIiwiREVQfj4mUGhpO2VlIiwiUEZ+PiZQaGk7bWUxIiwgICJERVB+PiZQaGk7bWUxIiwgIlBGfj4mUGhpO2VtMSIgLCAiREVQfj4mUGhpO2VtMSIsIlBGfj4mcGk7ZSIgLCAiREVQfj4mcGk7ZSIgLCJQRn4+JmVtcHR5O1NJVFMiICwgIkRFUH4+JmVtcHR5O1NJVFMiKSxvcmRlcnMgPSBjKDEwLDExLDE0LDE1LDE2LDE3LDE4LDE5LDIyLDIzLDI2LDI3KSwgaHRtbCA9IEYsIHByZWR0YWJsZSA9IFQpCgp0YWJsZVtbMV1dJT4lIGthYmxlKGVzY2FwZSA9IEZBTFNFLCBhbGlnbiA9ICJjIixmb3JtYXQgPSAiaHRtbCIpICU+JQogICAgICBrYWJsZV9wYXBlcigpICU+JSAKICBjb2x1bW5fc3BlYygyLGJvbGQgPSB0YWJsZVtbNF1dWywyXSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWywyXSwgc2NhbGVfZnJvbSA9IGMoLS42LC42KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKICBjb2x1bW5fc3BlYygzLGJvbGQgPSB0YWJsZVtbNF1dWywzXSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWywzXSwgc2NhbGVfZnJvbSA9IGMoLS42LC42KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKICBjb2x1bW5fc3BlYyg0LGJvbGQgPSB0YWJsZVtbNF1dWyw0XSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw0XSwgc2NhbGVfZnJvbSA9IGMoLS42LC42KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKICBjb2x1bW5fc3BlYyg1LGJvbGQgPSB0YWJsZVtbNF1dWyw1XSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw1XSwgc2NhbGVfZnJvbSA9IGMoLS42LC42KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKICBjb2x1bW5fc3BlYyg2LGJvbGQgPSB0YWJsZVtbNF1dWyw2XSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw2XSwgc2NhbGVfZnJvbSA9IGMoLS42LC42KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKICBjb2x1bW5fc3BlYyg3LGJvbGQgPSB0YWJsZVtbNF1dWyw3XSwKICAgICAgICAgICAgICBiYWNrZ3JvdW5kID0gc3BlY19jb2xvcih0YWJsZVtbM11dWyw3XSwgc2NhbGVfZnJvbSA9IGMoLS42LC42KSwgcGFsZXR0ZSA9Y29sb3JSYW1wUGFsZXR0ZShjKCIjZmRlNzI1Iiwid2hpdGUiLCIjMjE5MThjIikpKDI1NikpKSU+JSAKICAgYWRkX2hlYWRlcl9hYm92ZShjKCIgIiwgIlByZWRpY3Rpb24gb2YgYXZlcmFnZWQgYmV0d2Vlbi1wZXJzb24gZGlmZmVyZW5jZXMgaW4gd2l0aGluLXBlcnNvbiBhZmZlY3Qtc2l0YXRpb24gZHluYW1pY3MiID0gNikpICAlPiUgc2F2ZV9rYWJsZSgidGFibGUzLnBkZiIpCgoKCgojIyBwcmVkaWN0aW9uIHdpdGhpbiBvbmx5IGNvcnJlbGF0ZWQgZmFjdG9ycwoKdGFibGUgPSB0YWJsZTJmdW5jKG1wbG9kZWxuYW1lcyA9IGMoIk1vZE5vT3V0Q09Sc2l0X25jbmYub3V0IiwiTW9kTm9PdXRDT1JzaXRfbmVtcC5vdXQiLCJNb2ROb091dENPUnNpdF9ub3ZsLm91dCIsIk1vZE5vT3V0Q09Sc2l0X3ByZWwub3V0IiwiTW9kTm9PdXRDT1JzaXRfcHN1Yy5vdXQiLCJNb2ROb091dENPUnNpdF9wd28ub3V0IiksIHRhYmxlbmFtZXMgPSBjKCJjb25mbGljdCIsImVtcHRpbmVzcyBvciBib3JlZG9tIiwib3ZlcndoZWxtaW5nIDxicj4gdGFzayIsInJlbGF4YXRpb24iLCJhY2hpZXZlbWVudCIsImdvb2QgdGltZSB3aXRoIHNvbWVvbmUiKSwKcGFyYW1zID0gYygiUEZ+PiZQc2k7bWUiLCAgICJERVB+PiZQc2k7bWUiICwgIlBGfj4mUGhpO2VlIiwiREVQfj4mUGhpO2VlIiwiUEZ+PiZQaGk7bWUxIiwgICJERVB+PiZQaGk7bWUxIiwgIlBGfj4mUGhpO2VtMSIgLCAiREVQfj4mUGhpO2VtMSIsIlBGfj4mcGk7ZSIgLCAiREVQfj4mcGk7ZSIgLCJQRn4+JmVtcHR5O1NJVFMiICwgIkRFUH4+JmVtcHR5O1NJVFMiKSwgb3JkZXJzID0gYygxMCwxMSwxNCwxNSwxNiwxNywxOCwxOSwyMiwyMywyNiwyNyksIGh0bWwgPSBGLCBwcmVkdGFibGUgPSBUKQoKcm93bmFtZXModGFibGVbWzFdXSkgPSBjKCJQRn4+bXhlIiwgICAiREVQfj5teGUiICwgIlBGfj5lZSIsIkRFUH4+ZWUiLCJQRn4+bWUxIiwgICJERVB+Pm1lMSIsICJQRn4+ZW0xIiAsICJERVB+PmVtMSIsIlBGfj4mZWl2IiAsICJERVB+PmVpdiIgLCJQRn4+JmVtcHR5O2UiICwgIkRFUH4+JmVtcHR5O2UiKQoKdGFibGVbWzFdXSU+JSBrYWJsZShlc2NhcGUgPSBGQUxTRSwgYWxpZ24gPSAiYyIsZm9ybWF0ID0gImh0bWwiKSAlPiUKICAgICAga2FibGVfcGFwZXIoKSAlPiUgCiAgY29sdW1uX3NwZWMoMixib2xkID0gdGFibGVbWzRdXVssMl0sCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssMl0sIHNjYWxlX2Zyb20gPSBjKC0uNiwuNiksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgY29sdW1uX3NwZWMoMyxib2xkID0gdGFibGVbWzRdXVssM10sCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssM10sIHNjYWxlX2Zyb20gPSBjKC0uNiwuNiksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgY29sdW1uX3NwZWMoNCxib2xkID0gdGFibGVbWzRdXVssNF0sCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssNF0sIHNjYWxlX2Zyb20gPSBjKC0uNiwuNiksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgY29sdW1uX3NwZWMoNSxib2xkID0gdGFibGVbWzRdXVssNV0sCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssNV0sIHNjYWxlX2Zyb20gPSBjKC0uNiwuNiksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgY29sdW1uX3NwZWMoNixib2xkID0gdGFibGVbWzRdXVssNl0sCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssNl0sIHNjYWxlX2Zyb20gPSBjKC0uNiwuNiksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgY29sdW1uX3NwZWMoNyxib2xkID0gdGFibGVbWzRdXVssN10sCiAgICAgICAgICAgICAgYmFja2dyb3VuZCA9IHNwZWNfY29sb3IodGFibGVbWzNdXVssN10sIHNjYWxlX2Zyb20gPSBjKC0uNiwuNiksIHBhbGV0dGUgPWNvbG9yUmFtcFBhbGV0dGUoYygiI2ZkZTcyNSIsIndoaXRlIiwiIzIxOTE4YyIpKSgyNTYpKSklPiUgCiAgIGFkZF9oZWFkZXJfYWJvdmUoYygiICIsICJQcmVkaWN0aW9uIG9mIGF2ZXJhZ2VkIGJldHdlZW4tcGVyc29uIGRpZmZlcmVuY2VzIGluIHdpdGhpbi1wZXJzb24gYWZmZWN0LXNpdGF0aW9uIGR5bmFtaWNzIiA9IDYpKSAgJT4lIHNhdmVfa2FibGUoInRhYmxlMy5wZGYiKQoKCgoKIyAlPiUgCiMgICAgIERUOjpkYXRhdGFibGUoCiMgICAgIGV4dGVuc2lvbnMgPSAnQnV0dG9ucycsCiMgICAgIG9wdGlvbnMgPSBsaXN0KGRvbSA9ICdCZnJ0aXAnLAojICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gbGlzdCgnZXhjZWwnLCAiY3N2IikpKQojIAoKCgoKICAKCiMgRnVuY3Rpb24gdG8gYXBwbHkgYm9sZCBmb3JtYXR0aW5nIGJhc2VkIG9uIGxvZ2ljYWwgdGFibGUKYm9sZF9pZl90cnVlIDwtIGZ1bmN0aW9uKHZhbHVlLCBjb25kaXRpb24pIHsKICBpZiAoY29uZGl0aW9uKSB7CiAgICByZXR1cm4oY2VsbF9zcGVjKHZhbHVlLCBib2xkID0gVFJVRSkpCiAgfSBlbHNlIHsKICAgIHJldHVybih2YWx1ZSkKICB9Cn0KCiMgQXBwbHkgdGhlIGZ1bmN0aW9uIHRvIHRoZSBkYXRhIHRhYmxlCmZvcm1hdHRlZF90YWJsZSA8LSB0YWJsZTJbWzFdXQpmb3IgKGNvbCBpbiAyOiBsZW5ndGgobmFtZXModGFibGUyW1sxXV0pKSkgewogIGZvcm1hdHRlZF90YWJsZVtbY29sXV0gPC0gbWFwcGx5KGJvbGRfaWZfdHJ1ZSwgZm9ybWF0dGVkX3RhYmxlW1tjb2xdXSwgdGFibGUyW1syXV1bW2NvbF1dIDwgLjAwNSkKfQoKIyBHZW5lcmF0ZSB0aGUga2FibGUgb2JqZWN0IHdpdGgga2FibGVFeHRyYQprYWJsZShmb3JtYXR0ZWRfdGFibGUsZXNjYXBlID0gRkFMU0UpICU+JQogICAgICBrYWJsZV9jbGFzc2ljXzIoKSAKCgoKCgpgYGAKCgoK