library(fda.usc)
library(randomForest)
library(caret)
library(dplyr)
library(tidyr)
G3;
Attaching package: ‘tidyr’

gG3;The following object is masked from ‘package:RCurl’:

    complete

g
NHANES <- readRDS('/Users/darrensummerlee/Library/CloudStorage/Dropbox/NHANES paper/data set/BP_stats_no_enhance.rds')
n <- nrow(NHANES)

# Smooth MIMS
MIMS <- NHANES$MIMS
MIMS <- unclass(MIMS)
argvals <- seq(0, 1440, length.out = 1440)
MIMS_basis <- create.bspline.basis(c(0, 1440), nbasis = 20)
MIMS_fd <- Data2fd(argvals = argvals, y = t(MIMS), basisobj = MIMS_basis)
set.seed(1)
folds <- createFolds(1:n, k = 10)
importance_list <- list()

cv_results <- data.frame(
  Fold = 1:10,
  RMSE = numeric(10),
  R_squared = numeric(10),
  Coverage = numeric(10)
)

for (i in 1:10) {
  set.seed(1)
  cat("Processing Fold:", i, "\n")
  
  # Train/Test split
  test_idx <- folds[[i]]
  train_idx <- setdiff(1:n, test_idx)
  
  scalar_train <- data.frame(
    bpS = NHANES$BPS_avg[train_idx],
    gender = NHANES$gender[train_idx],
    CHD = NHANES$CHD[train_idx],
    age = NHANES$age[train_idx],
    BMI = NHANES$BMI[train_idx]
  )
  scalar_test <- data.frame(
    bpS = NHANES$BPS_avg[test_idx],
    gender = NHANES$gender[test_idx],
    CHD = NHANES$CHD[test_idx],
    age = NHANES$age[test_idx],
    BMI = NHANES$BMI[test_idx]
  )
  
  MIMS_fd_train <- MIMS_fd[train_idx]
  MIMS_fd_test  <- MIMS_fd[test_idx]
  
  MIMS_coef_train <- t(MIMS_fd_train$coefs)
  MIMS_coef_test <- t(MIMS_fd_test$coefs)
  colnames(MIMS_coef_train) <- paste0("F", 1:ncol(MIMS_coef_train))
  colnames(MIMS_coef_test) <- paste0("F", 1:ncol(MIMS_coef_test))
  
  rf_data_train <- cbind(scalar_train, MIMS_coef_train)
  rf_data_test <- cbind(scalar_test, MIMS_coef_test)
  
  # Train Model
  set.seed(1)
  frf_model <- randomForest(bpS ~ ., data = rf_data_train, ntree = 500, mtry = 10, importance = TRUE, keep.inbag = TRUE)
  
  importance_list[[i]] <- importance(frf_model, type = 1)
  
  # Predict
  preds_frf <- predict(frf_model, newdata = rf_data_test, predict.all = TRUE)
  pred_vec <- preds_frf$aggregate
  
  # Metrics
  rmse <- sqrt(mean((scalar_test$bpS - pred_vec)^2))

  ss_total <- sum((scalar_test$bpS - mean(scalar_test$bpS))^2)
  ss_res <- sum((scalar_test$bpS - pred_vec)^2)
  r_squared <- 1 - (ss_res / ss_total)
  
  lower_bounds <- apply(preds_frf$individual, 1, quantile, probs = 0.025)
  upper_bounds <- apply(preds_frf$individual, 1, quantile, probs = 0.975)
  coverage <- mean(scalar_test$bpS >= lower_bounds & scalar_test$bpS <= upper_bounds)
  
  cv_results$RMSE[i] <- rmse
  cv_results$R_squared[i] <- r_squared
  cv_results$Coverage[i] <- coverage
}
Processing Fold: 1 
Processing Fold: 2 
Processing Fold: 3 
Processing Fold: 4 
Processing Fold: 5 
Processing Fold: 6 
Processing Fold: 7 
Processing Fold: 8 
Processing Fold: 9 
Processing Fold: 10 
print(cv_results)

avg_rmse <- mean(cv_results$RMSE)
sd_rmse <- sd(cv_results$RMSE)
avg_r_squared <- mean(cv_results$R_squared)
sd_r_squared <- sd(cv_results$R_squared)
avg_coverage <- mean(cv_results$Coverage)
sd_coverage <- sd(cv_results$Coverage)

cat("Average Test RMSE: ", round(avg_rmse, 3), " (SD:", round(sd_rmse, 3), ")\n")
Average Test RMSE:  16.115  (SD: 0.801 )
cat("Average Test R^2:", round(avg_r_squared, 3), " (SD:", round(sd_r_squared, 3), ")\n")
Average Test R^2: 0.219  (SD: 0.033 )
cat("Average Empirical 95% Coverage Rate:", round(avg_coverage * 100, 2), "% (SD:", round(sd_coverage * 100, 2), "%)\n")
Average Empirical 95% Coverage Rate: 94.39 % (SD: 0.99 %)
importance <- do.call(cbind, importance_list)
colnames(importance) <- paste0("Fold", seq_len(ncol(importance)))
importance_df <- importance %>%
  as.data.frame() %>%
  mutate(Variable = rownames(.)) %>%
  pivot_longer(
    cols = -Variable,
    names_to = "Fold",
    values_to = "Importance"
  )
avg_importance <- importance_df %>%
  group_by(Variable) %>%
  summarise(
    Avg_Importance = mean(Importance),
    Std_Dev = sd(Importance)
  )

cat("Average Variable Importance (10-Fold CV)")
Average Variable Importance (10-Fold CV)
print(avg_importance)

ggplot(avg_importance, aes(x = reorder(Variable, Avg_Importance), y = Avg_Importance)) +
  geom_col(fill = "darkgreen") +
  geom_errorbar(
    aes(ymin = Avg_Importance - Std_Dev, ymax = Avg_Importance + Std_Dev),
    width = 0.2
  ) +
  coord_flip() +
  labs(
    title = "Average Importance from 10-Fold CV",
    subtitle = "Error bars show standard deviation across folds",
    x = "Variable",
    y = "Average % Increase in MSE"
  ) +
  theme_minimal()

results <- data.frame(actual = scalar_test$bpS, predicted = pred_vec)
#2d color
zones <- data.frame(
  xmin = c(50, 100, 120, 130, 140),
  xmax = c(100, 120, 130, 140, Inf),
  fill = c("Low", "Normal", "Elevated", "ISH-S1", "S2"),
  color = c("lightblue", "green3", "yellow", "orange", "red")
)

zone_rects <- expand.grid(x = 1:nrow(zones), y = 1:nrow(zones))

max_risk_index <- pmax(zone_rects$x, zone_rects$y)
zone_rects <- cbind(
  zone_rects,
  xmin = zones$xmin[zone_rects$x],
  xmax = zones$xmax[zone_rects$x],
  ymin = zones$xmin[zone_rects$y],
  ymax = zones$xmax[zone_rects$y],
  fill = zones$color[max_risk_index]
)

ggplot() +
  geom_rect(data = zone_rects, aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax, fill = fill), alpha = 0.4) +
  scale_fill_identity() +
  geom_point(data = results, aes(x = predicted, y = actual), color = "blue", size = 0.5) +
  geom_abline(intercept = -20, slope = 1, linetype = "dashed", color = "black", linewidth = 0.4) +
  geom_abline(intercept = 20, slope = 1, linetype = "dashed", color = "black", linewidth = 0.4) +
  xlim(50, 150) +
  ylim(50, 250) +
  coord_cartesian(xlim = c(50, 200), ylim = c(50, 200), expand = FALSE) +
  scale_x_continuous(breaks = c(50, 80, 100, 120, 140, 150)) +
  scale_y_continuous(breaks = c(50, 80, 100, 120, 140, 150)) +
  labs(x = "Predicted BP", y = "True BP") +
  coord_fixed() +
  theme_minimal()
Scale for x is already present.
Adding another scale for x, which will replace the existing scale.
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
Coordinate system already present. Adding new coordinate system, which will replace the existing one.

LS0tCnRpdGxlOiAiMTAtRm9sZCBGUkYxIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBpbXBvcnR9CmxpYnJhcnkoZmRhLnVzYykKbGlicmFyeShyYW5kb21Gb3Jlc3QpCmxpYnJhcnkoY2FyZXQpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCgpOSEFORVMgPC0gcmVhZFJEUygnQlBfc3RhdHNfbm9fZW5oYW5jZS5yZHMnKQpgYGAKCmBgYHtyIGRhdGEgYWRqdXN0bWVudH0KbiA8LSBucm93KE5IQU5FUykKCiMgU21vb3RoIE1JTVMKTUlNUyA8LSBOSEFORVMkTUlNUwpNSU1TIDwtIHVuY2xhc3MoTUlNUykKYXJndmFscyA8LSBzZXEoMCwgMTQ0MCwgbGVuZ3RoLm91dCA9IDE0NDApCk1JTVNfYmFzaXMgPC0gY3JlYXRlLmJzcGxpbmUuYmFzaXMoYygwLCAxNDQwKSwgbmJhc2lzID0gMjApCk1JTVNfZmQgPC0gRGF0YTJmZChhcmd2YWxzID0gYXJndmFscywgeSA9IHQoTUlNUyksIGJhc2lzb2JqID0gTUlNU19iYXNpcykKYGBgCgpgYGB7ciAxMC1Gb2xkIENyb3NzIFZhbGlkYXRpb259CnNldC5zZWVkKDEpCmZvbGRzIDwtIGNyZWF0ZUZvbGRzKDE6biwgayA9IDEwKQppbXBvcnRhbmNlX2xpc3QgPC0gbGlzdCgpCgpjdl9yZXN1bHRzIDwtIGRhdGEuZnJhbWUoCiAgRm9sZCA9IDE6MTAsCiAgUk1TRSA9IG51bWVyaWMoMTApLAogIFJfc3F1YXJlZCA9IG51bWVyaWMoMTApLAogIENvdmVyYWdlID0gbnVtZXJpYygxMCkKKQoKZm9yIChpIGluIDE6MTApIHsKICBzZXQuc2VlZCgxKQogIGNhdCgiUHJvY2Vzc2luZyBGb2xkOiIsIGksICJcbiIpCiAgCiAgIyBUcmFpbi9UZXN0IHNwbGl0CiAgdGVzdF9pZHggPC0gZm9sZHNbW2ldXQogIHRyYWluX2lkeCA8LSBzZXRkaWZmKDE6biwgdGVzdF9pZHgpCiAgCiAgc2NhbGFyX3RyYWluIDwtIGRhdGEuZnJhbWUoCiAgICBicFMgPSBOSEFORVMkQlBTX2F2Z1t0cmFpbl9pZHhdLAogICAgZ2VuZGVyID0gTkhBTkVTJGdlbmRlclt0cmFpbl9pZHhdLAogICAgQ0hEID0gTkhBTkVTJENIRFt0cmFpbl9pZHhdLAogICAgYWdlID0gTkhBTkVTJGFnZVt0cmFpbl9pZHhdLAogICAgQk1JID0gTkhBTkVTJEJNSVt0cmFpbl9pZHhdCiAgKQogIHNjYWxhcl90ZXN0IDwtIGRhdGEuZnJhbWUoCiAgICBicFMgPSBOSEFORVMkQlBTX2F2Z1t0ZXN0X2lkeF0sCiAgICBnZW5kZXIgPSBOSEFORVMkZ2VuZGVyW3Rlc3RfaWR4XSwKICAgIENIRCA9IE5IQU5FUyRDSERbdGVzdF9pZHhdLAogICAgYWdlID0gTkhBTkVTJGFnZVt0ZXN0X2lkeF0sCiAgICBCTUkgPSBOSEFORVMkQk1JW3Rlc3RfaWR4XQogICkKICAKICBNSU1TX2ZkX3RyYWluIDwtIE1JTVNfZmRbdHJhaW5faWR4XQogIE1JTVNfZmRfdGVzdCAgPC0gTUlNU19mZFt0ZXN0X2lkeF0KICAKICBNSU1TX2NvZWZfdHJhaW4gPC0gdChNSU1TX2ZkX3RyYWluJGNvZWZzKQogIE1JTVNfY29lZl90ZXN0IDwtIHQoTUlNU19mZF90ZXN0JGNvZWZzKQogIGNvbG5hbWVzKE1JTVNfY29lZl90cmFpbikgPC0gcGFzdGUwKCJGIiwgMTpuY29sKE1JTVNfY29lZl90cmFpbikpCiAgY29sbmFtZXMoTUlNU19jb2VmX3Rlc3QpIDwtIHBhc3RlMCgiRiIsIDE6bmNvbChNSU1TX2NvZWZfdGVzdCkpCiAgCiAgcmZfZGF0YV90cmFpbiA8LSBjYmluZChzY2FsYXJfdHJhaW4sIE1JTVNfY29lZl90cmFpbikKICByZl9kYXRhX3Rlc3QgPC0gY2JpbmQoc2NhbGFyX3Rlc3QsIE1JTVNfY29lZl90ZXN0KQogIAogICMgVHJhaW4gTW9kZWwKICBzZXQuc2VlZCgxKQogIGZyZl9tb2RlbCA8LSByYW5kb21Gb3Jlc3QoYnBTIH4gLiwgZGF0YSA9IHJmX2RhdGFfdHJhaW4sIG50cmVlID0gNTAwLCBtdHJ5ID0gMTAsIGltcG9ydGFuY2UgPSBUUlVFLCBrZWVwLmluYmFnID0gVFJVRSkKICAKICBpbXBvcnRhbmNlX2xpc3RbW2ldXSA8LSBpbXBvcnRhbmNlKGZyZl9tb2RlbCwgdHlwZSA9IDEpCiAgCiAgIyBQcmVkaWN0CiAgcHJlZHNfZnJmIDwtIHByZWRpY3QoZnJmX21vZGVsLCBuZXdkYXRhID0gcmZfZGF0YV90ZXN0LCBwcmVkaWN0LmFsbCA9IFRSVUUpCiAgcHJlZF92ZWMgPC0gcHJlZHNfZnJmJGFnZ3JlZ2F0ZQogIAogICMgTWV0cmljcwogIHJtc2UgPC0gc3FydChtZWFuKChzY2FsYXJfdGVzdCRicFMgLSBwcmVkX3ZlYyleMikpCgogIHNzX3RvdGFsIDwtIHN1bSgoc2NhbGFyX3Rlc3QkYnBTIC0gbWVhbihzY2FsYXJfdGVzdCRicFMpKV4yKQogIHNzX3JlcyA8LSBzdW0oKHNjYWxhcl90ZXN0JGJwUyAtIHByZWRfdmVjKV4yKQogIHJfc3F1YXJlZCA8LSAxIC0gKHNzX3JlcyAvIHNzX3RvdGFsKQogIAogIGxvd2VyX2JvdW5kcyA8LSBhcHBseShwcmVkc19mcmYkaW5kaXZpZHVhbCwgMSwgcXVhbnRpbGUsIHByb2JzID0gMC4wMjUpCiAgdXBwZXJfYm91bmRzIDwtIGFwcGx5KHByZWRzX2ZyZiRpbmRpdmlkdWFsLCAxLCBxdWFudGlsZSwgcHJvYnMgPSAwLjk3NSkKICBjb3ZlcmFnZSA8LSBtZWFuKHNjYWxhcl90ZXN0JGJwUyA+PSBsb3dlcl9ib3VuZHMgJiBzY2FsYXJfdGVzdCRicFMgPD0gdXBwZXJfYm91bmRzKQogIAogIGN2X3Jlc3VsdHMkUk1TRVtpXSA8LSBybXNlCiAgY3ZfcmVzdWx0cyRSX3NxdWFyZWRbaV0gPC0gcl9zcXVhcmVkCiAgY3ZfcmVzdWx0cyRDb3ZlcmFnZVtpXSA8LSBjb3ZlcmFnZQp9CmBgYAoKYGBge3IgTWV0cmljc30KcHJpbnQoY3ZfcmVzdWx0cykKCmF2Z19ybXNlIDwtIG1lYW4oY3ZfcmVzdWx0cyRSTVNFKQpzZF9ybXNlIDwtIHNkKGN2X3Jlc3VsdHMkUk1TRSkKYXZnX3Jfc3F1YXJlZCA8LSBtZWFuKGN2X3Jlc3VsdHMkUl9zcXVhcmVkKQpzZF9yX3NxdWFyZWQgPC0gc2QoY3ZfcmVzdWx0cyRSX3NxdWFyZWQpCmF2Z19jb3ZlcmFnZSA8LSBtZWFuKGN2X3Jlc3VsdHMkQ292ZXJhZ2UpCnNkX2NvdmVyYWdlIDwtIHNkKGN2X3Jlc3VsdHMkQ292ZXJhZ2UpCgpjYXQoIkF2ZXJhZ2UgVGVzdCBSTVNFOiAiLCByb3VuZChhdmdfcm1zZSwgMyksICIgKFNEOiIsIHJvdW5kKHNkX3Jtc2UsIDMpLCAiKVxuIikKY2F0KCJBdmVyYWdlIFRlc3QgUl4yOiIsIHJvdW5kKGF2Z19yX3NxdWFyZWQsIDMpLCAiIChTRDoiLCByb3VuZChzZF9yX3NxdWFyZWQsIDMpLCAiKVxuIikKY2F0KCJBdmVyYWdlIEVtcGlyaWNhbCA5NSUgQ292ZXJhZ2UgUmF0ZToiLCByb3VuZChhdmdfY292ZXJhZ2UgKiAxMDAsIDIpLCAiJSAoU0Q6Iiwgcm91bmQoc2RfY292ZXJhZ2UgKiAxMDAsIDIpLCAiJSlcbiIpCmBgYAoKYGBge3IgVmFyaWFibGUgSW1wb3J0YW5jZX0KaW1wb3J0YW5jZSA8LSBkby5jYWxsKGNiaW5kLCBpbXBvcnRhbmNlX2xpc3QpCmNvbG5hbWVzKGltcG9ydGFuY2UpIDwtIHBhc3RlMCgiRm9sZCIsIHNlcV9sZW4obmNvbChpbXBvcnRhbmNlKSkpCmltcG9ydGFuY2VfZGYgPC0gaW1wb3J0YW5jZSAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgbXV0YXRlKFZhcmlhYmxlID0gcm93bmFtZXMoLikpICU+JQogIHBpdm90X2xvbmdlcigKICAgIGNvbHMgPSAtVmFyaWFibGUsCiAgICBuYW1lc190byA9ICJGb2xkIiwKICAgIHZhbHVlc190byA9ICJJbXBvcnRhbmNlIgogICkKYXZnX2ltcG9ydGFuY2UgPC0gaW1wb3J0YW5jZV9kZiAlPiUKICBncm91cF9ieShWYXJpYWJsZSkgJT4lCiAgc3VtbWFyaXNlKAogICAgQXZnX0ltcG9ydGFuY2UgPSBtZWFuKEltcG9ydGFuY2UpLAogICAgU3RkX0RldiA9IHNkKEltcG9ydGFuY2UpCiAgKQoKY2F0KCJBdmVyYWdlIFZhcmlhYmxlIEltcG9ydGFuY2UgKDEwLUZvbGQgQ1YpIikKcHJpbnQoYXZnX2ltcG9ydGFuY2UpCgpnZ3Bsb3QoYXZnX2ltcG9ydGFuY2UsIGFlcyh4ID0gcmVvcmRlcihWYXJpYWJsZSwgQXZnX0ltcG9ydGFuY2UpLCB5ID0gQXZnX0ltcG9ydGFuY2UpKSArCiAgZ2VvbV9jb2woZmlsbCA9ICJkYXJrZ3JlZW4iKSArCiAgZ2VvbV9lcnJvcmJhcigKICAgIGFlcyh5bWluID0gQXZnX0ltcG9ydGFuY2UgLSBTdGRfRGV2LCB5bWF4ID0gQXZnX0ltcG9ydGFuY2UgKyBTdGRfRGV2KSwKICAgIHdpZHRoID0gMC4yCiAgKSArCiAgY29vcmRfZmxpcCgpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQXZlcmFnZSBJbXBvcnRhbmNlIGZyb20gMTAtRm9sZCBDViIsCiAgICBzdWJ0aXRsZSA9ICJFcnJvciBiYXJzIHNob3cgc3RhbmRhcmQgZGV2aWF0aW9uIGFjcm9zcyBmb2xkcyIsCiAgICB4ID0gIlZhcmlhYmxlIiwKICAgIHkgPSAiQXZlcmFnZSAlIEluY3JlYXNlIGluIE1TRSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgoKYGBge3IgaGVhdG1hcH0KcmVzdWx0cyA8LSBkYXRhLmZyYW1lKGFjdHVhbCA9IHNjYWxhcl90ZXN0JGJwUywgcHJlZGljdGVkID0gcHJlZF92ZWMpCiMyZCBjb2xvcgp6b25lcyA8LSBkYXRhLmZyYW1lKAogIHhtaW4gPSBjKDUwLCAxMDAsIDEyMCwgMTMwLCAxNDApLAogIHhtYXggPSBjKDEwMCwgMTIwLCAxMzAsIDE0MCwgSW5mKSwKICBmaWxsID0gYygiTG93IiwgIk5vcm1hbCIsICJFbGV2YXRlZCIsICJJU0gtUzEiLCAiUzIiKSwKICBjb2xvciA9IGMoImxpZ2h0Ymx1ZSIsICJncmVlbjMiLCAieWVsbG93IiwgIm9yYW5nZSIsICJyZWQiKQopCgp6b25lX3JlY3RzIDwtIGV4cGFuZC5ncmlkKHggPSAxOm5yb3coem9uZXMpLCB5ID0gMTpucm93KHpvbmVzKSkKCm1heF9yaXNrX2luZGV4IDwtIHBtYXgoem9uZV9yZWN0cyR4LCB6b25lX3JlY3RzJHkpCnpvbmVfcmVjdHMgPC0gY2JpbmQoCiAgem9uZV9yZWN0cywKICB4bWluID0gem9uZXMkeG1pblt6b25lX3JlY3RzJHhdLAogIHhtYXggPSB6b25lcyR4bWF4W3pvbmVfcmVjdHMkeF0sCiAgeW1pbiA9IHpvbmVzJHhtaW5bem9uZV9yZWN0cyR5XSwKICB5bWF4ID0gem9uZXMkeG1heFt6b25lX3JlY3RzJHldLAogIGZpbGwgPSB6b25lcyRjb2xvclttYXhfcmlza19pbmRleF0KKQoKZ2dwbG90KCkgKwogIGdlb21fcmVjdChkYXRhID0gem9uZV9yZWN0cywgYWVzKHhtaW4gPSB4bWluLCB4bWF4ID0geG1heCwgeW1pbiA9IHltaW4sIHltYXggPSB5bWF4LCBmaWxsID0gZmlsbCksIGFscGhhID0gMC40KSArCiAgc2NhbGVfZmlsbF9pZGVudGl0eSgpICsKICBnZW9tX3BvaW50KGRhdGEgPSByZXN1bHRzLCBhZXMoeCA9IHByZWRpY3RlZCwgeSA9IGFjdHVhbCksIGNvbG9yID0gImJsdWUiLCBzaXplID0gMC41KSArCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gLTIwLCBzbG9wZSA9IDEsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gMjAsIHNsb3BlID0gMSwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3IgPSAiYmxhY2siLCBsaW5ld2lkdGggPSAwLjQpICsKICB4bGltKDUwLCAxNTApICsKICB5bGltKDUwLCAyNTApICsKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoNTAsIDIwMCksIHlsaW0gPSBjKDUwLCAyMDApLCBleHBhbmQgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDUwLCA4MCwgMTAwLCAxMjAsIDE0MCwgMTUwKSkgKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDUwLCA4MCwgMTAwLCAxMjAsIDE0MCwgMTUwKSkgKwogIGxhYnMoeCA9ICJQcmVkaWN0ZWQgQlAiLCB5ID0gIlRydWUgQlAiKSArCiAgY29vcmRfZml4ZWQoKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoK