Data generation

simulateJM <-   function (nsim, nsub, thetas, times, formulas, Data = NULL, censoring = NULL, max.FUtime = NULL) {

  if (is.null(max.FUtime))
    max.FUtime <-1e6

  # Function to compute the inverse survival function
  invS <- function (t, uu, i) {
    TD <- function (v) {
      # function to compute the time-dependent part for patient i at time v
      dd            <- Data[rep(i, length(v)), , drop = FALSE]
      dd[[timeVar]] <- pmax(v, 0)

      XX    <- model.matrix(formYx, data = dd)
      ZZ    <- model.matrix(formYz, data = dd)
      Y     <- as.vector(XX %*% betas +  rowSums(ZZ * b[rep(i, nrow(ZZ)), , drop = FALSE]))
      Y.aux <- 1/(1 + 1/exp(Y))
      out   <- (alpha ) * (nu + (1 - nu)*Y.aux)
      out
    }

    h <- function (s) {
      TD.i <- TD(s)
      exp(log(rho) + (rho - 1) * log(s) + eta.t[i] + TD.i)
    }
    integrate(h, lower = 0, upper = t)$value + log(uu)
  }

  # Coefficients
  betas  <- thetas$betas
  sigma  <- exp(thetas$sigma)
  D      <- exp(thetas$D)
  gamas  <- as.numeric(thetas$gamas)
  alpha  <- thetas$alpha
  Dalpha <- thetas$Dalpha
  rho    <- exp(thetas$rho)
  nu     <- exp(thetas$nu)/(1 + exp(thetas$nu))


  # Design matrices
  formYx  <- formulas$Yfixed
  formYz  <- formulas$Yrandom
  formT   <- formulas$Tfixed
  timeVar <- formulas$timeVar
  id      <- rep(1:nsub, each= length(times))
  times   <- rep(times, nsub)

  DD            <- Data[id, , drop = FALSE]
  DD[[timeVar]] <- times
  X   <- model.matrix(formYx, data = DD)
  Z   <- model.matrix(formYz, data = DD)
  W   <- model.matrix(formT, Data)
  ncz <- ncol(Z)


  # Simulate random effects
  b <- mvrnorm(nsub, rep(0, ncz), D)

  # Simulate event times
  eta.t <- if (!is.null(W)) as.vector(W %*% gamas) else rep(0, nsub)
  u     <- runif(nsub)
  trueTimes <- numeric(nsub)

  for (i in 1:nsub) {
    Root <- try(uniroot(invS, interval = c(1e-05, max.FUtime), uu = u[i], i = i)$root, TRUE)

    while(inherits(Root, "try-error")){
      b[i, ] <- c(mvrnorm(1, rep(0, ncz), D))
      Root   <- try(uniroot(invS, interval = c(1e-05, max.FUtime), uu =runif(1), i = i)$root, TRUE)
    }

    trueTimes[i] <- Root
  }

  # Simulate longitudinal responses
  eta.y    <- as.vector(X %*% betas + rowSums(Z * b[id, ]))
  mean.aux <- exp(eta.y)/(1 + exp(eta.y))
  y      <- rBEOI(nrow(DD), mean.aux, sigma, nu)
  Ctimes <- rep(censoring, length.out = nsub)
  Time   <- pmin(trueTimes, Ctimes)
  event  <- as.numeric(trueTimes <= Ctimes)

  ni            <- tapply(id, id, length)
  DD$EQ5D       <- y
  DD$tempo      <- rep(Time, ni)
  DD$delta      <- rep(event, ni)
  DD$X          <- id
  DD            <- DD[DD[[timeVar]] <= DD$tempo, ]
  row.names(DD) <- seq_len(nrow(DD))

  DD
}

Example

dadosSim = simulateJM(nsim       = 1,
                      nsub       = 500, 
                      thetas     = initi.theta.BEOI.sim, 
                      times      = c(0,15,90,180,360,540), 
                      formulas   = form, 
                      Data       = dadosLong,  
                      max.FUtime = NULL, 
                      censoring  = 570)

dadosSimB <- dadosSim

dadosSimB %<>%
    mutate(EQ5D = ifelse(EQ5D == 1, (nrow(dados) - 1 + 0.5)/nrow(dados), EQ5D), # substitui 1's por ((n-1) + 0.5)/n
           logito.EQ5D = log(EQ5D/(1-EQ5D))) %>%
    arrange(idpaciente, visita)


dadosSim.id <- dadosSim[!duplicated(dadosSim$X),]

head(dadosSim, n = 5)

Exploratory analysis:

Distribution of UI

Longitunial profiles

## `geom_smooth()` using formula = 'y ~ x'

Survival curve:

Model fitting

######################
# No scaling        #
######################
fit.betaJM.id  <- try(fit.JM(lmeObj.Beta, 
                              survObj, 
                              model = "beta", 
                              QH = 10, 
                              QL = 10, 
                              lag = 0,
                              timeVar = "visita", 
                              init.theta = initi.theta.beta, 
                              imp = FALSE), TRUE)

fit.BEOIJM.id  <- try(fit.JM(lmeObj, 
                             survObj,
                             model = "betaInf", 
                             QH = 10, 
                             QL = 10,
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.BEOI,
                             imp = FALSE), TRUE)

fit.lnJM.id    <- try(fit.JM(lmeObj.ln, 
                             survObj,
                             model = "normal",
                             QH = 10,
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.ln,
                             imp = FALSE), TRUE)

####################################
# Scaling factors: Typical values  #
#################################### 

fit.betaJM.vt  <- try(fit.JM(lmeObj.Beta,
                             survObj, 
                             model = "beta",
                             QH = 10, 
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.beta, 
                             imp = FALSE, 
                             precond = 'reescala'),TRUE)

fit.BEOIJM.vt  <- try(fit.JM(lmeObj, 
                             survObj,
                             model = "betaInf", 
                             QH = 10, 
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.BEOI, 
                             imp = FALSE,
                             precond = 'reescala'),TRUE)
  
fit.lnJM.vt    <- try(fit.JM(lmeObj.ln, 
                             survObj, 
                             model = "normal",
                             QH = 10, 
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.ln, 
                             imp = FALSE, 
                             precond = 'reescala'),TRUE)

############################
# Scaling factors: Jacobi  #
############################
  
fit.betaJM.jc  <- try(fit.JM(lmeObj.Beta, 
                             survObj, 
                             model = "beta",
                             QH = 10,
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.beta,
                             imp = FALSE,
                             precond = 'jacobi'),TRUE)

fit.BEOIJM.jc  <- try(fit.JM(lmeOb,
                             survObj,
                             model = "betaInf", 
                             QH = 10,
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.BEOI,
                             imp = FALSE,
                             precond = 'jacobi'),TRUE)

fit.lnJM.jc    <- try(fit.JM(lmeObj.ln, 
                             survObj, 
                             model = "normal",
                             QH = 10, 
                             QL = 10, 
                             lag = 0, 
                             timeVar = "visita", 
                             init.theta = initi.theta.ln,  
                             imp = FALSE, 
                             precond = 'jacobi'),TRUE)

Checking the output

fit.lnJM.jc 
## $fit
## $fit$par
##           betas.(Intercept)                betas.visita 
##                 0.586542727                 0.002556241 
##    betas.quimioSim-Curativa           gamas.(Intercept) 
##                 0.192065807                -2.360993353 
## gamas.tipo.adm.utiPlanejada                       alpha 
##                -0.914694044                -0.187746815 
##                         rho                           D 
##                -0.635201237                 1.771809639 
##                       sigma 
##                 1.427942553 
## attr(,"skeleton")
## $betas
##        (Intercept)             visita quimioSim-Curativa 
##        0.552344799        0.002523929        0.268761350 
## 
## $gamas
##           (Intercept) tipo.adm.utiPlanejada 
##            -2.5680063            -0.9497281 
## 
## $alpha
## [1] 1e-04
## 
## $rho
## [1] -0.5592707
## 
## $D
##                 [,1]
## (Intercept) 1.716548
## 
## $sigma
## [1] 1.431236
## 
## attr(,"class")
## [1] "relistable" "list"      
## 
## $fit$value
## [1] -7409.61
## 
## $fit$counts
## function gradient 
##       20       16 
## 
## $fit$convergence
## [1] 0
## 
## $fit$message
## NULL
## 
## $fit$hessian
##                             betas.(Intercept)  betas.visita
## betas.(Intercept)               -4.471656e+01    -4513.7898
## betas.visita                    -4.513790e+03 -3079043.9758
## betas.quimioSim-Curativa        -1.890355e+01    -1570.3777
## gamas.(Intercept)                2.679013e+01     2605.0495
## gamas.tipo.adm.utiPlanejada      1.089209e+01     1365.6734
## alpha                            5.584468e+01    25067.1316
## rho                              7.358830e+01    12417.5187
## D                               -7.826679e+00    -3566.3640
## sigma                            5.371893e-02     -173.3976
##                             betas.quimioSim-Curativa gamas.(Intercept)
## betas.(Intercept)                         -18.903548          26.79013
## betas.visita                            -1570.377712        2605.04953
## betas.quimioSim-Curativa                  -18.903548          13.24299
## gamas.(Intercept)                          13.242987        -325.99092
## gamas.tipo.adm.utiPlanejada                 2.263828        -147.24787
## alpha                                      31.457298        -225.79433
## rho                                        35.035417        -952.21364
## D                                          -3.357063         -11.19818
## sigma                                      -1.593202          11.54508
##                             gamas.tipo.adm.utiPlanejada       alpha         rho
## betas.(Intercept)                             10.892089    55.84468    73.58830
## betas.visita                                1365.673364 25067.13163 12417.51872
## betas.quimioSim-Curativa                       2.263828    31.45730    35.03542
## gamas.(Intercept)                           -147.247873  -225.79433  -952.21364
## gamas.tipo.adm.utiPlanejada                 -147.247874   -81.39342  -463.16754
## alpha                                        -81.393418 -1479.69051  -992.01336
## rho                                         -463.167544  -992.01336 -3111.50503
## D                                             -5.594832    90.73939   -13.96673
## sigma                                          4.186833  -148.09112    22.75321
##                                        D         sigma
## betas.(Intercept)              -7.826679  5.371893e-02
## betas.visita                -3566.364024 -1.733976e+02
## betas.quimioSim-Curativa       -3.357063 -1.593202e+00
## gamas.(Intercept)             -11.198182  1.154508e+01
## gamas.tipo.adm.utiPlanejada    -5.594832  4.186833e+00
## alpha                          90.739390 -1.480911e+02
## rho                           -13.966732  2.275321e+01
## D                             -62.630718 -1.247113e+02
## sigma                        -124.711309 -2.778801e+03
## 
## 
## $out
##                              Estimativas Erros padr?o      p-valor
## betas.(Intercept)            0.586542727 0.2126219618 5.804638e-03
## betas.visita                 0.002556241 0.0006633024 1.162945e-04
## betas.quimioSim-Curativa     0.192065807 0.3064218081 5.307890e-01
## gamas.(Intercept)           -2.360993353 0.1883708704 0.000000e+00
## gamas.tipo.adm.utiPlanejada -0.914694044 0.1165358677 4.218847e-15
## alpha                       -0.187746815 0.0366426830 2.995671e-07
## rho                         -0.635201237 0.0670636814 0.000000e+00
## D                            5.881487103 0.1467153368 0.000000e+00
## sigma                        4.170110580 0.0203847218 0.000000e+00
## 
## $cond
## [1] 112.8826
LS0tDQp0aXRsZTogIkpNIGNvZGVzIg0KYXV0aG9yOiAiQWxpbmUgQ0FNUE9TIg0KZGF0ZTogIjA0LzA0LzIwMjQiDQpvdXRwdXQ6IA0KICBodG1sX2RvY3VtZW50OiANCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogaGFkZG9jaw0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogDQogICAgICBjb2xsYXBzZWQ6IGZhbHNlDQogICAgICBTbW9vdGhfc2Nyb2xsOiBmYWxzZQ0KICAgIHRvY19kZXB0aDogMw0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlDQotLS0NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSxmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9OCwgd2FybmluZyA9RkFMU0UpDQpgYGANCg0KDQoNCmBgYHtyIGxvYWRpbmcsaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoInBhY21hbiIpDQoNCnBhY21hbjo6cF9sb2FkKGNvbXBpbGVyLCBKTSwgbG1lNCwgbmxtZSwgdGlkeXIsIGdncGxvdDIsIHh0YWJsZSwgcGx5ciwgc3Vydm1pbmVyLCBtdnRub3JtLCBiZXRhcmVnLCBzdGF0bW9kLA0KICAgICAgICAgICAgICAgZ2FtbHNzLmRpc3QsIGdhbWxzcywgb3B0aW14LCB0aWR5dmVyc2UsIGdyaWRFeHRyYSwgcHJhY21hLCBldm9wZXIsIGxhdHRpY2UsIHN1cnZpdmFsLCBTdXJ2UmVnQ2Vuc0NvdikNCg0KdGFiX2ZpbGVzX1IgPC0gbGlzdC5maWxlcyhwYXRoID0gICJmdW5jdGlvbnMiLCBmdWxsLm5hbWVzID0gVCkNCg0Kc3VwcHJlc3NNZXNzYWdlcyhsYXBwbHkodGFiX2ZpbGVzX1IsIHNvdXJjZSkpDQoNCmBgYA0KDQoNCg0KIyBEYXRhIGdlbmVyYXRpb24NCg0KYGBge3Igc2ltfQ0Kc2ltdWxhdGVKTSA8LSAgIGZ1bmN0aW9uIChuc2ltLCBuc3ViLCB0aGV0YXMsIHRpbWVzLCBmb3JtdWxhcywgRGF0YSA9IE5VTEwsIGNlbnNvcmluZyA9IE5VTEwsIG1heC5GVXRpbWUgPSBOVUxMKSB7DQoNCiAgaWYgKGlzLm51bGwobWF4LkZVdGltZSkpDQogICAgbWF4LkZVdGltZSA8LTFlNg0KDQogICMgRnVuY3Rpb24gdG8gY29tcHV0ZSB0aGUgaW52ZXJzZSBzdXJ2aXZhbCBmdW5jdGlvbg0KICBpbnZTIDwtIGZ1bmN0aW9uICh0LCB1dSwgaSkgew0KICAgIFREIDwtIGZ1bmN0aW9uICh2KSB7DQogICAgICAjIGZ1bmN0aW9uIHRvIGNvbXB1dGUgdGhlIHRpbWUtZGVwZW5kZW50IHBhcnQgZm9yIHBhdGllbnQgaSBhdCB0aW1lIHYNCiAgICAgIGRkICAgICAgICAgICAgPC0gRGF0YVtyZXAoaSwgbGVuZ3RoKHYpKSwgLCBkcm9wID0gRkFMU0VdDQogICAgICBkZFtbdGltZVZhcl1dIDwtIHBtYXgodiwgMCkNCg0KICAgICAgWFggICAgPC0gbW9kZWwubWF0cml4KGZvcm1ZeCwgZGF0YSA9IGRkKQ0KICAgICAgWlogICAgPC0gbW9kZWwubWF0cml4KGZvcm1ZeiwgZGF0YSA9IGRkKQ0KICAgICAgWSAgICAgPC0gYXMudmVjdG9yKFhYICUqJSBiZXRhcyArICByb3dTdW1zKFpaICogYltyZXAoaSwgbnJvdyhaWikpLCAsIGRyb3AgPSBGQUxTRV0pKQ0KICAgICAgWS5hdXggPC0gMS8oMSArIDEvZXhwKFkpKQ0KICAgICAgb3V0ICAgPC0gKGFscGhhICkgKiAobnUgKyAoMSAtIG51KSpZLmF1eCkNCiAgICAgIG91dA0KICAgIH0NCg0KICAgIGggPC0gZnVuY3Rpb24gKHMpIHsNCiAgICAgIFRELmkgPC0gVEQocykNCiAgICAgIGV4cChsb2cocmhvKSArIChyaG8gLSAxKSAqIGxvZyhzKSArIGV0YS50W2ldICsgVEQuaSkNCiAgICB9DQogICAgaW50ZWdyYXRlKGgsIGxvd2VyID0gMCwgdXBwZXIgPSB0KSR2YWx1ZSArIGxvZyh1dSkNCiAgfQ0KDQogICMgQ29lZmZpY2llbnRzDQogIGJldGFzICA8LSB0aGV0YXMkYmV0YXMNCiAgc2lnbWEgIDwtIGV4cCh0aGV0YXMkc2lnbWEpDQogIEQgICAgICA8LSBleHAodGhldGFzJEQpDQogIGdhbWFzICA8LSBhcy5udW1lcmljKHRoZXRhcyRnYW1hcykNCiAgYWxwaGEgIDwtIHRoZXRhcyRhbHBoYQ0KICBEYWxwaGEgPC0gdGhldGFzJERhbHBoYQ0KICByaG8gICAgPC0gZXhwKHRoZXRhcyRyaG8pDQogIG51ICAgICA8LSBleHAodGhldGFzJG51KS8oMSArIGV4cCh0aGV0YXMkbnUpKQ0KDQoNCiAgIyBEZXNpZ24gbWF0cmljZXMNCiAgZm9ybVl4ICA8LSBmb3JtdWxhcyRZZml4ZWQNCiAgZm9ybVl6ICA8LSBmb3JtdWxhcyRZcmFuZG9tDQogIGZvcm1UICAgPC0gZm9ybXVsYXMkVGZpeGVkDQogIHRpbWVWYXIgPC0gZm9ybXVsYXMkdGltZVZhcg0KICBpZCAgICAgIDwtIHJlcCgxOm5zdWIsIGVhY2g9IGxlbmd0aCh0aW1lcykpDQogIHRpbWVzICAgPC0gcmVwKHRpbWVzLCBuc3ViKQ0KDQogIEREICAgICAgICAgICAgPC0gRGF0YVtpZCwgLCBkcm9wID0gRkFMU0VdDQogIEREW1t0aW1lVmFyXV0gPC0gdGltZXMNCiAgWCAgIDwtIG1vZGVsLm1hdHJpeChmb3JtWXgsIGRhdGEgPSBERCkNCiAgWiAgIDwtIG1vZGVsLm1hdHJpeChmb3JtWXosIGRhdGEgPSBERCkNCiAgVyAgIDwtIG1vZGVsLm1hdHJpeChmb3JtVCwgRGF0YSkNCiAgbmN6IDwtIG5jb2woWikNCg0KDQogICMgU2ltdWxhdGUgcmFuZG9tIGVmZmVjdHMNCiAgYiA8LSBtdnJub3JtKG5zdWIsIHJlcCgwLCBuY3opLCBEKQ0KDQogICMgU2ltdWxhdGUgZXZlbnQgdGltZXMNCiAgZXRhLnQgPC0gaWYgKCFpcy5udWxsKFcpKSBhcy52ZWN0b3IoVyAlKiUgZ2FtYXMpIGVsc2UgcmVwKDAsIG5zdWIpDQogIHUgICAgIDwtIHJ1bmlmKG5zdWIpDQogIHRydWVUaW1lcyA8LSBudW1lcmljKG5zdWIpDQoNCiAgZm9yIChpIGluIDE6bnN1Yikgew0KICAgIFJvb3QgPC0gdHJ5KHVuaXJvb3QoaW52UywgaW50ZXJ2YWwgPSBjKDFlLTA1LCBtYXguRlV0aW1lKSwgdXUgPSB1W2ldLCBpID0gaSkkcm9vdCwgVFJVRSkNCg0KICAgIHdoaWxlKGluaGVyaXRzKFJvb3QsICJ0cnktZXJyb3IiKSl7DQogICAgICBiW2ksIF0gPC0gYyhtdnJub3JtKDEsIHJlcCgwLCBuY3opLCBEKSkNCiAgICAgIFJvb3QgICA8LSB0cnkodW5pcm9vdChpbnZTLCBpbnRlcnZhbCA9IGMoMWUtMDUsIG1heC5GVXRpbWUpLCB1dSA9cnVuaWYoMSksIGkgPSBpKSRyb290LCBUUlVFKQ0KICAgIH0NCg0KICAgIHRydWVUaW1lc1tpXSA8LSBSb290DQogIH0NCg0KICAjIFNpbXVsYXRlIGxvbmdpdHVkaW5hbCByZXNwb25zZXMNCiAgZXRhLnkgICAgPC0gYXMudmVjdG9yKFggJSolIGJldGFzICsgcm93U3VtcyhaICogYltpZCwgXSkpDQogIG1lYW4uYXV4IDwtIGV4cChldGEueSkvKDEgKyBleHAoZXRhLnkpKQ0KICB5ICAgICAgPC0gckJFT0kobnJvdyhERCksIG1lYW4uYXV4LCBzaWdtYSwgbnUpDQogIEN0aW1lcyA8LSByZXAoY2Vuc29yaW5nLCBsZW5ndGgub3V0ID0gbnN1YikNCiAgVGltZSAgIDwtIHBtaW4odHJ1ZVRpbWVzLCBDdGltZXMpDQogIGV2ZW50ICA8LSBhcy5udW1lcmljKHRydWVUaW1lcyA8PSBDdGltZXMpDQoNCiAgbmkgICAgICAgICAgICA8LSB0YXBwbHkoaWQsIGlkLCBsZW5ndGgpDQogIEREJEVRNUQgICAgICAgPC0geQ0KICBERCR0ZW1wbyAgICAgIDwtIHJlcChUaW1lLCBuaSkNCiAgREQkZGVsdGEgICAgICA8LSByZXAoZXZlbnQsIG5pKQ0KICBERCRYICAgICAgICAgIDwtIGlkDQogIEREICAgICAgICAgICAgPC0gRERbRERbW3RpbWVWYXJdXSA8PSBERCR0ZW1wbywgXQ0KICByb3cubmFtZXMoREQpIDwtIHNlcV9sZW4obnJvdyhERCkpDQoNCiAgREQNCn0NCg0KYGBgIA0KDQojIEV4YW1wbGUNCg0KYGBge3Igc2ltMiwgaW5jbHVkZSA9IEZBTFNFfQ0KDQojIyMjIyMjIyMjIyMjIyMjIw0KIyBGaXR0aW5nIEpNcyAgICMNCiMjIyMjIyMjIyMjIyMjIyMjDQpmb3JtIDwtIGxpc3QoWWZpeGVkID0gRVE1RCB+IHZpc2l0YSArIHF1aW1pbywgWXJhbmRvbSA9IH4xLCBUZml4ZWQgPSB0ZW1wbyB+ICB0aXBvLmFkbS51dGksIHRpbWVWYXI9ICJ2aXNpdGEiKQ0KDQptdS5mb3JtIDwtIEVRNUQgfiB2aXNpdGEgKyBxdWltaW8NCm11LmxuICAgPC0gbG9naXRvLkVRNUQgfiB2aXNpdGEgKyBxdWltaW8NCnN1cnYuZm9ybSAgICAgIDwtIFN1cnYodGVtcG8sIGRlbHRhKSB+IHRpcG8uYWRtLnV0aQ0KbXUucmFuZG9tLmZvcm0gPC0gfiAxfFgNCnNpZ21hLmZvcm0gICAgIDwtIH4gMQ0KbnUuZm9ybSAgICAgICAgPC0gfiAxDQoNCiMgQWp1c3RlIGRhZG9zIElDRVNQIHBhcmEgZ2VyYT8/byBkZSBkYWRvcyBhcnRpZmljaWFpcyBjb20gc3VhcyBjYXJhY3Rlcj9zdGljYXMNCmdhbS5CRU9JIDwtIGdhbWxzcyhtdS5mb3JtLCByYW5kb20gPSBtdS5yYW5kb20uZm9ybSwgc2lnbWEuZm9ybXVsYSA9IHNpZ21hLmZvcm0sIGZhbWlseSA9IEJFT0ksIGRhdGEgPSBuYS5vbWl0KGRhZG9zTG9uZykpDQpnYW0uQkVPSSRtdS5jb2VmZmljaWVudHNbM10gPC0gMC4wMQ0KZ2FtLkJFIDwtIGdhbWxzcyhtdS5mb3JtLCByYW5kb20gPSBtdS5yYW5kb20uZm9ybSwgc2lnbWEuZm9ybXVsYSA9IHNpZ21hLmZvcm0sIGZhbWlseSA9IEJFICAsIGRhdGEgPSBuYS5vbWl0KGRhZG9zTG9uZ0IpKQ0KZ2FtLkJFJG11LmNvZWZmaWNpZW50c1szXSA8LSAwLjAxDQoNCmxtZU9iai5CZXRhIDwtIGxtZShtdS5mb3JtLCByYW5kb20gPSB+IDF8WCwgZGF0YSA9IGRhZG9zTG9uZ0IpDQpsbWVPYmoubG4gICA8LSBsbWUobXUubG4sICAgcmFuZG9tID0gfiAxfFgsIGRhdGEgPSBkYWRvc0xvbmdCKQ0KbG1lT2JqICAgICAgPC0gbG1lKG11LmZvcm0sIHJhbmRvbSA9IH4gMXxYLCBkYXRhID0gZGFkb3NMb25nKQ0Kc3Vydk9iaiAgICAgPC0gY294cGgoc3Vydi5mb3JtLCBkYXRhID0gZGFkb3MuaWQsIHggPSBUUlVFKQ0KDQoNCkZpdC5KTS5sbiAgICA8LSBqb2ludE1vZGVsKGxtZU9iai5sbiwgc3Vydk9iaiwgdGltZVZhciA9ICJ2aXNpdGEiLCBtZXRob2QgPSAid2VpYnVsbC1QSC1HSCIsIGl0ZXIuRU0gPSAwLCBjb250cm9sID0gbGlzdChwYXJzY2FsZSA9IHJlcCgwLjAwMDEsOSkpLCB2ZXJib3NlID0gVFJVRSkNCkZpdC5KTS5JQ0VTUCA8LSBqb2ludE1vZGVsKGxtZU9iaiwgICAgc3Vydk9iaiwgdGltZVZhciA9ICJ2aXNpdGEiLCBtZXRob2QgPSAid2VpYnVsbC1QSC1HSCIsIGl0ZXIuRU0gPSAwLCBjb250cm9sID0gbGlzdChwYXJzY2FsZSA9IHJlcCgwLjAwMSw5KSkgLCB2ZXJib3NlID0gVFJVRSkNCg0KDQoNCg0KIyBWYWxvcmVzIGRvcyBwYXI/bWV0cm9zIHBhcmEgYSBnZXJhPz9vIGRvcyBkYWRvcw0KaW5pdGkudGhldGEuQkVPSS5zaW0gICA8LSBpbml0aS5CRU9JKEZpdC5KTS5sbiwgZ2FtLkJFT0kpDQppbml0aS50aGV0YS5CRU9JLnNpbSRhbHBoYSAgICA8LSAtNA0KaW5pdGkudGhldGEuQkVPSS5zaW0kbnUgICAgICAgPC0gLTEuNA0KaW5pdGkudGhldGEuQkVPSS5zaW0kYmV0YXNbMV0gPC0gLTAuNQ0KaW5pdGkudGhldGEuQkVPSS5zaW0kYmV0YXNbMl0gPC0gMC4wMDENCmluaXRpLnRoZXRhLkJFT0kuc2ltJGdhbWFzWzFdIDwtIC0xDQppbml0aS50aGV0YS5CRU9JLnNpbSRyaG8gICAgICA8LSAtMC40NQ0KaW5pdGkudGhldGEuQkVPSS5zaW0kc2lnbWEgICAgPC0gMC42DQpgYGANCg0KYGBge3Igc2ltM30NCg0KZGFkb3NTaW0gPSBzaW11bGF0ZUpNKG5zaW0gICAgICAgPSAxLA0KICAgICAgICAgICAgICAgICAgICAgIG5zdWIgICAgICAgPSA1MDAsIA0KICAgICAgICAgICAgICAgICAgICAgIHRoZXRhcyAgICAgPSBpbml0aS50aGV0YS5CRU9JLnNpbSwgDQogICAgICAgICAgICAgICAgICAgICAgdGltZXMgICAgICA9IGMoMCwxNSw5MCwxODAsMzYwLDU0MCksIA0KICAgICAgICAgICAgICAgICAgICAgIGZvcm11bGFzICAgPSBmb3JtLCANCiAgICAgICAgICAgICAgICAgICAgICBEYXRhICAgICAgID0gZGFkb3NMb25nLCAgDQogICAgICAgICAgICAgICAgICAgICAgbWF4LkZVdGltZSA9IE5VTEwsIA0KICAgICAgICAgICAgICAgICAgICAgIGNlbnNvcmluZyAgPSA1NzApDQoNCmRhZG9zU2ltQiA8LSBkYWRvc1NpbQ0KDQpkYWRvc1NpbUIgJTw+JQ0KICAgIG11dGF0ZShFUTVEID0gaWZlbHNlKEVRNUQgPT0gMSwgKG5yb3coZGFkb3MpIC0gMSArIDAuNSkvbnJvdyhkYWRvcyksIEVRNUQpLCAjIHN1YnN0aXR1aSAxJ3MgcG9yICgobi0xKSArIDAuNSkvbg0KICAgICAgICAgICBsb2dpdG8uRVE1RCA9IGxvZyhFUTVELygxLUVRNUQpKSkgJT4lDQogICAgYXJyYW5nZShpZHBhY2llbnRlLCB2aXNpdGEpDQoNCg0KZGFkb3NTaW0uaWQgPC0gZGFkb3NTaW1bIWR1cGxpY2F0ZWQoZGFkb3NTaW0kWCksXQ0KDQpoZWFkKGRhZG9zU2ltLCBuID0gNSkNCg0KYGBgDQoNCg0KDQojIyBFeHBsb3JhdG9yeSBhbmFseXNpczoNCg0KIyMjIERpc3RyaWJ1dGlvbiBvZiBVSQ0KYGBge3IgaGlzdHMsIGVjaG8gPSBGQUxTRX0NCiAgcGFyKG1mcm93ID0gYyg0LDMpKQ0KICBib3hwbG90KGRhZG9zU2ltJEVRNURbZGFkb3NTaW0kdmlzaXRhID09IDBdLCBob3Jpem9udGFsPVRSVUUseGxhYj0iIiwgeGF4dD0nbicsIGF4ZXM9RkFMU0UsYW5uPUZBTFNFLGNvbD0iZ3JleTY3Iixib3JkZXI9ImdyYXk1MCIpDQogIGJveHBsb3QoZGFkb3NTaW0kRVE1RFtkYWRvc1NpbSR2aXNpdGEgPT0gMTVdLGhvcml6b250YWw9VFJVRSx4bGFiPSIiLCB4YXh0PSduJywgYXhlcz1GQUxTRSxhbm49RkFMU0UsY29sPSJncmV5NjciLGJvcmRlcj0iZ3JheTUwIikNCiAgYm94cGxvdChkYWRvc1NpbSRFUTVEW2RhZG9zU2ltJHZpc2l0YSA9PSA5MF0saG9yaXpvbnRhbD1UUlVFLHhsYWI9IiIsIHhheHQ9J24nLCBheGVzPUZBTFNFLGFubj1GQUxTRSxjb2w9ImdyZXk2NyIsYm9yZGVyPSJncmF5NTAiKQ0KDQogIGhpc3QoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW0kdmlzaXRhPT0wXSx4bGltPWMoMCwxKSx5bGltID0gYygwLDE2MCkseGxhYj0iVXRpbGl0eSBpbmRleCIseWxhYiA9ICJGcmVxdWVuY3kiLCBtYWluPSJGVSB0aW1lICh0ID0gMCkiLGNleC5sYWI9MS4xLGNvbD0iZ3JleTY3Iixib3JkZXI9ImdyYXkiKQ0KICBwYXIobmV3PVRSVUUpDQogIHBvaW50cygxLGxlbmd0aChkYWRvc1NpbUIkRVE1RFtkYWRvc1NpbUIkdmlzaXRhPT0wJmRhZG9zU2ltJEVRNUQ9PTFdKSxjb2w9InJlZCIpDQogIHBvaW50cyhjKDEsMSksIGMoMCxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09MCZkYWRvc1NpbSRFUTVEPT0xXSkpLHR5cGU9ImwiLGNvbD0icmVkIikNCg0KICBoaXN0KGRhZG9zU2ltQiRFUTVEW2RhZG9zU2ltJHZpc2l0YT09MTVdLHhsaW09YygwLDEpLHlsaW0gPSBjKDAsMTYwKSx4bGFiPSJVdGlsaXR5IGluZGV4Iix5bGFiID0gIkZyZXF1ZW5jeSIsIG1haW49IkZVIHRpbWUgKHQgPSAxNSkiLGNleC5sYWI9MS4xLGNvbD0iZ3JleTY3Iixib3JkZXI9ImdyYXkiKQ0KICBwYXIobmV3PVRSVUUpDQogIHBvaW50cygxLGxlbmd0aChkYWRvc1NpbUIkRVE1RFtkYWRvc1NpbUIkdmlzaXRhPT0xNSZkYWRvc1NpbSRFUTVEPT0xXSksY29sPSJyZWQiKQ0KICBwb2ludHMoYygxLDEpLCBjKDAsbGVuZ3RoKGRhZG9zU2ltQiRFUTVEW2RhZG9zU2ltQiR2aXNpdGE9PTE1JmRhZG9zU2ltJEVRNUQ9PTFdKSksdHlwZT0ibCIsY29sPSJyZWQiKQ0KDQogIGhpc3QoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW0kdmlzaXRhPT05MF0seGxpbT1jKDAsMSkseWxpbSA9IGMoMCwxNjApLHhsYWI9IlV0aWxpdHkgaW5kZXgiLHlsYWIgPSAiRnJlcXVlbmN5IiwgbWFpbj0iRlUgdGltZSAodCA9IDkwKSIsY2V4LmxhYj0xLjEsY29sPSJncmV5NjciLGJvcmRlcj0iZ3JheSIpDQogIHBhcihuZXc9VFJVRSkNCiAgcG9pbnRzKDEsbGVuZ3RoKGRhZG9zU2ltQiRFUTVEW2RhZG9zU2ltQiR2aXNpdGE9PTkwJmRhZG9zU2ltJEVRNUQ9PTFdKSxjb2w9InJlZCIpDQogIHBvaW50cyhjKDEsMSksIGMoMCxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09OTAmZGFkb3NTaW0kRVE1RD09MV0pKSx0eXBlPSJsIixjb2w9InJlZCIpDQoNCiAgYm94cGxvdChkYWRvc1NpbSRFUTVEW2RhZG9zU2ltJHZpc2l0YT09MTgwXSxob3Jpem9udGFsPVRSVUUseGxhYj0iIiwgeGF4dD0nbicsIGF4ZXM9RkFMU0UsYW5uPUZBTFNFLGNvbD0iZ3JleTY3Iixib3JkZXI9ImdyYXk1MCIpDQogIGJveHBsb3QoZGFkb3NTaW0kRVE1RFtkYWRvc1NpbSR2aXNpdGE9PTM2MF0saG9yaXpvbnRhbD1UUlVFLHhsYWI9IiIsIHhheHQ9J24nLCBheGVzPUZBTFNFLGFubj1GQUxTRSxjb2w9ImdyZXk2NyIsYm9yZGVyPSJncmF5NTAiKQ0KICBib3hwbG90KGRhZG9zU2ltJEVRNURbZGFkb3NTaW0kdmlzaXRhPT01NDBdLGhvcml6b250YWw9VFJVRSx4bGFiPSIiLCB4YXh0PSduJywgYXhlcz1GQUxTRSxhbm49RkFMU0UsY29sPSJncmV5NjciLGJvcmRlcj0iZ3JheTUwIikNCg0KDQogIGhpc3QoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW0kdmlzaXRhPT0xODBdLHhsaW09YygwLDEpLHlsaW0gPSBjKDAsMTAwKSx4bGFiPSJVdGlsaXR5IGluZGV4Iix5bGFiID0gIkZyZXF1ZW5jeSIsIG1haW49IkZVIHRpbWUgKHQgPSAxODApIixjZXgubGFiPTEuMSxjb2w9ImdyZXk2NyIsYm9yZGVyPSJncmF5IikNCiAgcGFyKG5ldz1UUlVFKQ0KICBwb2ludHMoMSxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09MTgwJmRhZG9zU2ltJEVRNUQ9PTFdKSxjb2w9InJlZCIpDQogIHBvaW50cyhjKDEsMSksIGMoMCxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09MTgwJmRhZG9zU2ltJEVRNUQ9PTFdKSksdHlwZT0ibCIsY29sPSJyZWQiKQ0KDQogIGhpc3QoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW0kdmlzaXRhPT0zNjBdLHhsaW09YygwLDEpLHlsaW0gPSBjKDAsMTAwKSx4bGFiPSJVdGlsaXR5IGluZGV4Iix5bGFiID0gIkZyZXF1ZW5jeSIsIG1haW49IkZVIHRpbWUgKHQgPSAzNjApIixjZXgubGFiPTEuMSxjb2w9ImdyZXk2NyIsYm9yZGVyPSJncmF5IikNCiAgcGFyKG5ldz1UUlVFKQ0KICBwb2ludHMoMSxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09MzYwJmRhZG9zU2ltJEVRNUQ9PTFdKSxjb2w9InJlZCIpDQogIHBvaW50cyhjKDEsMSksIGMoMCxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09MzYwJmRhZG9zU2ltJEVRNUQ9PTFdKSksdHlwZT0ibCIsY29sPSJyZWQiKQ0KDQogIGhpc3QoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW0kdmlzaXRhPT01NDBdLHhsaW09YygwLDEpLHlsaW0gPSBjKDAsMTAwKSx4bGFiPSJVdGlsaXR5IGluZGV4Iix5bGFiID0gIkZyZXF1ZW5jeSIsIG1haW49IkZVIHRpbWUgKHQgPSA1NDApIixjZXgubGFiPTEuMSxjb2w9ImdyZXk2NyIsYm9yZGVyPSJncmF5IikNCiAgcGFyKG5ldz1UUlVFKQ0KICBwb2ludHMoMSxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09NTQwJmRhZG9zU2ltJEVRNUQ9PTFdKSxjb2w9InJlZCIpDQogIHBvaW50cyhjKDEsMSksIGMoMCxsZW5ndGgoZGFkb3NTaW1CJEVRNURbZGFkb3NTaW1CJHZpc2l0YT09NTQwJmRhZG9zU2ltJEVRNUQ9PTFdKSksdHlwZT0ibCIsY29sPSJyZWQiKQ0KICANCmBgYCANCg0KIyMjIExvbmdpdHVuaWFsIHByb2ZpbGVzDQoNCmBgYHtyIHByb2ZpbGVzLCBlY2hvID0gRkFMU0V9DQpnZ3Bsb3QoZGF0YSA9IGRhZG9zU2ltLCBhZXMoeCA9IHZpc2l0YSwgeSA9IEVRNUQsIGdyb3VwID0gWCApKSArIGdlb21fbGluZSgpKw0KICBzdGF0X3Ntb290aCggYWVzKGdyb3VwPWRlbHRhKSxtZXRob2QgPSAibG9lc3MiLCBzZSA9IEZBTFNFKSArIHRoZW1lX2J3KCkgKw0KICB5bGltKDAsMSkrIGZhY2V0X3dyYXAofmRlbHRhKSArIGxhYnModGl0bGUgPSJMb25naXR1ZGluYWwgdHJhamVjdG9yaWVzICIsICAgIHggPSAiVGltZSAoZGF5cykiLCAgICB5ID0gIlV0aWxpdHkgaW5kZXgiLCAgY29sb3IgPSBOVUxMKQ0KDQogIA0KICAgIA0KYGBgIA0KDQoNCg0KDQojIyMgIFN1cnZpdmFsIGN1cnZlOg0KDQoNCmBgYHtyIEtNLCBlY2hvID0gRkFMU0V9DQogICANCmVrbSA8LSBzdXJ2Zml0KFN1cnYodGVtcG8sIGRlbHRhKX4xLCBkYXRhID0gZGFkb3NTaW0uaWQpDQoNCmdnc3VydnBsb3QoZWttLCBkYXRhID0gZGFkb3MuaWQsIHN1cnYubWVkaWFuLmxpbmUgPSAiaHYiLA0KICAgICAgICAgICB5bGFiID0gIlModCkgZXN0aW1hZG8iLA0KICAgICAgICAgICB4bGFiID0gIlRlbXBvIGVtIGRpYXMiLA0KICAgICAgICAgICBwdmFsID0gVFJVRSwNCiAgICAgICAgICAgY29uZi5pbnQgPSBUUlVFLA0KICAgICAgICAgICByaXNrLnRhYmxlID0gRkFMU0UsDQogICAgICAgICAgIHRhYmxlcy5oZWlnaHQgPSAwLjIsDQogICAgICAgICAgIHRhYmxlcy50aGVtZSA9IHRoZW1lX2NsZWFudGFibGUoKSwNCiAgICAgICAgICAgZ3JpZD1UUlVFLA0KICAgICAgICAgICBwYWxldHRlID0gYygiI0U3QjgwMCIsICIjMkU5RkRGIiksDQogICAgICAgICAgIGdndGhlbWUgPSB0aGVtZV9idygpICApDQoNCmBgYCANCg0KIyMgey19DQoNCg0KIyBNb2RlbCBmaXR0aW5nDQoNCg0KYGBge3IgbW9kZWwsIGluY2x1ZGU9IEZBTFNFfQ0KICBnYW0uQkUgICA8LSBnYW1sc3MobXUuZm9ybSwgcmFuZG9tID0gbXUucmFuZG9tLmZvcm0sIHNpZ21hLmZvcm11bGEgPSBzaWdtYS5mb3JtLCBmYW1pbHkgPSBCRSwgZGF0YSA9IG5hLm9taXQoZGFkb3NTaW1CKSkNCiAgZ2FtLkJFJG11LmNvZWZmaWNpZW50c1t3aGljaChpcy5uYShnYW0uQkUkbXUuY29lZmZpY2llbnRzKSldIDwtIDAuMQ0KICBnYW0uQkVPSSA8LSBnYW1sc3MobXUuZm9ybSwgcmFuZG9tID0gbXUucmFuZG9tLmZvcm0sIHNpZ21hLmZvcm11bGEgPSBzaWdtYS5mb3JtLCBmYW1pbHkgPSBCRU9JLCBkYXRhID0gbmEub21pdChkYWRvc1NpbSkpDQogIGdhbS5CRU9JJG11LmNvZWZmaWNpZW50c1t3aGljaChpcy5uYShnYW0uQkVPSSRtdS5jb2VmZmljaWVudHMpKV0gPC0gMC4xDQoNCiAgbG1lT2JqLkJldGEgIDwtIGxtZShtdS5mb3JtLCByYW5kb20gPSB+IDF8WCwgZGF0YSA9IGRhZG9zU2ltQikNCiAgbG1lT2JqLmxuICAgIDwtIGxtZShtdS5sbiwgcmFuZG9tID0gfiAxfFgsIGRhdGEgPSBkYWRvc1NpbUIpDQogIGxtZU9iaiAgICAgICA8LSBsbWUobXUuZm9ybSwgcmFuZG9tID0gfiAxfFgsIGRhdGEgPSBkYWRvc1NpbSkNCiAgc3Vydk9iaiAgICAgIDwtIGNveHBoKHN1cnYuZm9ybSwgZGF0YSA9IGRhZG9zU2ltLmlkLCB4ID0gVFJVRSkNCg0KDQogIEZpdC5KTS5sbiAgICA8LSB0cnkoam9pbnRNb2RlbChsbWVPYmoubG4sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIndlaWJ1bGwtUEgtR0giLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIuRU0gPSAwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSAgbGlzdChwYXJzY2FsZSA9IHJlcCgwLjAxLDkpKSksIFRSVUUpDQogIA0KICBGaXQuSk0uSUNFU1AgPC0gdHJ5KGpvaW50TW9kZWwobG1lT2JqLCAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZPYmosIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZVZhciA9ICJ2aXNpdGEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICJ3ZWlidWxsLVBILUdIIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyLkVNID0gMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChwYXJzY2FsZSA9IHJlcCgwLjAwMSw5KSkpLCBUUlVFKQ0KDQogIGluaXRpLnRoZXRhLm5vcm1hbCA8LSBpbml0aS5ub3JtYWwoRml0LkpNLklDRVNQKQ0KICBpbml0aS50aGV0YS5iZXRhICAgPC0gaW5pdGkuYmV0YShGaXQuSk0uSUNFU1AsIGdhbS5CRSkNCiAgaW5pdGkudGhldGEuQkVPSSAgIDwtIGluaXRpLkJFT0koRml0LkpNLklDRVNQLCBnYW0uQkVPSSkNCiAgaW5pdGkudGhldGEubG4gICAgIDwtIGluaXRpLm5vcm1hbChGaXQuSk0ubG4pDQoNCiAgaW5pdGkudGhldGEubm9ybWFsJGFscGhhICA8LSAtMQ0KICBpbml0aS50aGV0YS5iZXRhJGFscGhhICAgIDwtIC0xDQogIGluaXRpLnRoZXRhLkJFT0kkYWxwaGEgICAgPC0gLTENCmBgYA0KDQpgYGB7ciBtb2RlbDJ9DQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIE5vIHNjYWxpbmcgICAgICAgICMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmZpdC5iZXRhSk0uaWQgIDwtIHRyeShmaXQuSk0obG1lT2JqLkJldGEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCA9ICJiZXRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFFMID0gMTAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFnID0gMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVWYXIgPSAidmlzaXRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEuYmV0YSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXAgPSBGQUxTRSksIFRSVUUpDQoNCmZpdC5CRU9JSk0uaWQgIDwtIHRyeShmaXQuSk0obG1lT2JqLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAiYmV0YUluZiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFnID0gMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVWYXIgPSAidmlzaXRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXQudGhldGEgPSBpbml0aS50aGV0YS5CRU9JLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXAgPSBGQUxTRSksIFRSVUUpDQoNCmZpdC5sbkpNLmlkICAgIDwtIHRyeShmaXQuSk0obG1lT2JqLmxuLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAibm9ybWFsIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUggPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhZyA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEubG4sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcCA9IEZBTFNFKSwgVFJVRSkNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIFNjYWxpbmcgZmFjdG9yczogVHlwaWNhbCB2YWx1ZXMgICMNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyANCg0KZml0LmJldGFKTS52dCAgPC0gdHJ5KGZpdC5KTShsbWVPYmouQmV0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsID0gImJldGEiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhZyA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEuYmV0YSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcCA9IEZBTFNFLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlY29uZCA9ICdyZWVzY2FsYScpLFRSVUUpDQoNCmZpdC5CRU9JSk0udnQgIDwtIHRyeShmaXQuSk0obG1lT2JqLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAiYmV0YUluZiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhZyA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEuQkVPSSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVjb25kID0gJ3JlZXNjYWxhJyksVFJVRSkNCiAgDQpmaXQubG5KTS52dCAgICA8LSB0cnkoZml0LkpNKGxtZU9iai5sbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZPYmosIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCA9ICJub3JtYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhZyA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEubG4sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXAgPSBGQUxTRSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWNvbmQgPSAncmVlc2NhbGEnKSxUUlVFKQ0KDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIFNjYWxpbmcgZmFjdG9yczogSmFjb2JpICAjDQojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQogIA0KZml0LmJldGFKTS5qYyAgPC0gdHJ5KGZpdC5KTShsbWVPYmouQmV0YSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZPYmosIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCA9ICJiZXRhIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUggPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhZyA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEuYmV0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWNvbmQgPSAnamFjb2JpJyksVFJVRSkNCg0KZml0LkJFT0lKTS5qYyAgPC0gdHJ5KGZpdC5KTShsbWVPYiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vydk9iaiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWwgPSAiYmV0YUluZiIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRTCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFnID0gMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVWYXIgPSAidmlzaXRhIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXQudGhldGEgPSBpbml0aS50aGV0YS5CRU9JLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbXAgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlY29uZCA9ICdqYWNvYmknKSxUUlVFKQ0KDQpmaXQubG5KTS5qYyAgICA8LSB0cnkoZml0LkpNKGxtZU9iai5sbiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZPYmosIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbCA9ICJub3JtYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRSCA9IDEwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUUwgPSAxMCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhZyA9IDAsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lVmFyID0gInZpc2l0YSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0LnRoZXRhID0gaW5pdGkudGhldGEubG4sICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1wID0gRkFMU0UsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVjb25kID0gJ2phY29iaScpLFRSVUUpDQoNCmBgYA0KDQoNCiMjIENoZWNraW5nIHRoZSBvdXRwdXQNCg0KYGBge3IgbW9kZWwzfQ0KZml0LmxuSk0uamMgDQpgYGAgDQoNCg0K