Simulation Experiment Recipe

Objectives

Data Generation

Linear Gaussian DGP

Function

#> function(n, beta, rho, sigma) {
#>   cov_mat <- matrix(c(1, rho, rho, 1), byrow = T, nrow = 2, ncol = 2)
#>   X <- MASS::mvrnorm(n = n, mu = rep(0, 2), Sigma = cov_mat)
#>   y <- X %*% beta + rnorm(n, sd = sigma)
#>   return(list(X = X, y = y))
#> }
#> <bytecode: 0x55629159c770>

Input Parameters

#> $n
#> [1] 200
#> 
#> $beta
#> [1] 1 0
#> 
#> $rho
#> [1] 0
#> 
#> $sigma
#> [1] 1

Methods and Evaluation

Methods

OLS

Function

#> function(X, y, cols = c("X1", "X2")) {
#>   lm_fit <- lm(y ~ X)
#>   pvals <- summary(lm_fit)$coefficients[cols, "Pr(>|t|)"] %>%
#>     setNames(paste(names(.), "p-value"))
#>   return(pvals)
#> }
#> <bytecode: 0x556290686588>

Input Parameters

#> list()

Evaluation

Rejection Prob. (alpha = 0.1)

Function

#> function(fit_results, alpha = 0.05) {
#>   group_vars <- c(".dgp_name", ".method_name")
#>   eval_out <- fit_results %>%
#>     dplyr::group_by(across({{group_vars}})) %>%
#>     dplyr::summarise(
#>       `X1 Reject Prob.` = mean(`X1 p-value` < alpha),
#>       `X2 Reject Prob.` = mean(`X2 p-value` < alpha)
#>     )
#>   return(eval_out)
#> }

Input Parameters

#> $alpha
#> [1] 0.1

Visualizations

Power

Function

#> function(fit_results, col = "X1") {
#>   plt <- ggplot2::ggplot(fit_results) +
#>     ggplot2::aes(x = .data[[paste(col, "p-value")]],
#>                  color = as.factor(.method_name)) +
#>     ggplot2::geom_abline(slope = 1, intercept = 0,
#>                          color = "darkgray", linetype = "solid", size = 1) +
#>     ggplot2::stat_ecdf(size = 1) +
#>     ggplot2::scale_x_continuous(limits = c(0, 1)) +
#>     ggplot2::labs(x = "t", y = "P( p-value \u2264 t )",
#>                   linetype = "", color = "Method")
#>   return(plt)
#> }

Input Parameters

#> list()

Base Linear Regression Experiment

Rejection Prob. (alpha = 0.1)

Power

LS0tCnRpdGxlOiAiYHIgcGFyYW1zJHNpbV9uYW1lYCIKYXV0aG9yOiAiYHIgcGFyYW1zJGF1dGhvcmAiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVCICVkLCAlWScpYCIKaGVhZGVyLWluY2x1ZGVzOgogICAgLSBcdXNlcGFja2FnZXtmbG9hdH0KICAgIC0gXHVzZXBhY2thZ2V7YW1zbWF0aH0KICAgIC0gXHVzZXBhY2thZ2V7Z2Vuc3ltYn0Kb3V0cHV0OgogIHZ0aGVtZXM6OnZtb2Rlcm46CmNzczogY3NzL3NpbWNoZWYuY3NzCnBhcmFtczoKICBhdXRob3I6IAogICAgbGFiZWw6ICJBdXRob3I6IgogICAgdmFsdWU6ICIiCiAgc2ltX25hbWU6CiAgICBsYWJlbDogIlNpbXVsYXRpb24gRXhwZXJpbWVudCBOYW1lOiIKICAgIHZhbHVlOiAiIgogIHNpbV9wYXRoOgogICAgbGFiZWw6ICJQYXRoIHRvIFNpbXVsYXRpb24gRXhwZXJpbWVudCBGb2xkZXI6IgogICAgdmFsdWU6ICIiCiAgZXZhbF9vcmRlcjoKICAgIGxhYmVsOiAiT3JkZXIgb2YgRXZhbHVhdG9yczoiCiAgICB2YWx1ZTogTlVMTAogIHZpel9vcmRlcjoKICAgIGxhYmVsOiAiT3JkZXIgb2YgVmlzdWFsaXplcnM6IgogICAgdmFsdWU6IE5VTEwKICB2ZXJib3NlOgogICAgbGFiZWw6ICJWZXJib3NlIExldmVsOiIKICAgIHZhbHVlOiAyCi0tLQoKPHNjcmlwdCBzcmM9ImpzL3NpbWNoZWZOYXZDbGFzcy5qcyI+PC9zY3JpcHQ+CgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Kb3B0aW9ucyh3aWR0aCA9IDEwMDAwKQprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IEZBTFNFLAogIHdhcm5pbmcgPSBGQUxTRSwKICBtZXNzYWdlID0gRkFMU0UsCiAgY2FjaGUgPSBGQUxTRSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucG9zID0gIkgiLAogIGZpZy5oZWlnaHQgPSAxMiwKICBmaWcud2lkdGggPSAxMAopCgpvcHRpb25zKGtuaXRyLmthYmxlLk5BID0gJ05BJywKICAgICAgICBkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UpCgojIHNjcm9sbGFibGUgdGV4dCBvdXRwdXQKbG9jYWwoewogIGhvb2tfb3V0cHV0IDwtIGtuaXRyOjprbml0X2hvb2tzJGdldCgnb3V0cHV0JykKICBrbml0cjo6a25pdF9ob29rcyRzZXQob3V0cHV0ID0gZnVuY3Rpb24oeCwgb3B0aW9ucykgewogICAgaWYgKCFpcy5udWxsKG9wdGlvbnMkbWF4LmhlaWdodCkpIG9wdGlvbnMkYXR0ci5vdXRwdXQgPC0gYygKICAgICAgb3B0aW9ucyRhdHRyLm91dHB1dCwKICAgICAgc3ByaW50Zignc3R5bGU9Im1heC1oZWlnaHQ6ICVzOyInLCBvcHRpb25zJG1heC5oZWlnaHQpCiAgICApCiAgICBob29rX291dHB1dCh4LCBvcHRpb25zKQogIH0pCn0pCgpjaHVua19pZHggPC0gMQpkb2NfZGlyIDwtIGZpbGUucGF0aChwYXJhbXMkc2ltX3BhdGgsICJkb2NzIikKYGBgCgpgYGB7ciBoZWxwZXItZnVuc30KCiMnIEdldCBvcmRlciBvZiBvYmplY3RzIHRvIGRpc3BsYXkKIycKIycgQHBhcmFtIG9ial9uYW1lcyBWZWN0b3Igb2YgYWxsIG9iamVjdCBuYW1lcyB0aGF0IG5lZWQgdG8gYmUgZGlzcGxheWVkLgojJyBAcGFyYW0gb2JqX29yZGVyIFZlY3RvciBvZiBvYmplY3QgbmFtZXMgaW4gdGhlIGRlc2lyZWQgYXBwZWFyYW5jZSBvcmRlci4KIycgQHJldHVybiBWZWN0b3Igb2Ygb2JqZWN0IG5hbWVzIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IHdpbGwgYmUgZGlzcGxheWVkLgpnZXRPYmpPcmRlciA8LSBmdW5jdGlvbihvYmpfbmFtZXMsIG9ial9vcmRlciA9IE5VTEwpIHsKICBpZiAoaXMubnVsbChvYmpfb3JkZXIpKSB7CiAgICByZXR1cm4ob2JqX25hbWVzKQogIH0gZWxzZSB7CiAgICByZXR1cm4oaW50ZXJzZWN0KG9ial9vcmRlciwgb2JqX25hbWVzKSkKICB9Cn0KCiMnIEdldCBhbGwgZXhwZXJpbWVudHMgdW5kZXIgYSBnaXZlbiBkaXJlY3RvcnkgbmFtZQojJwojJyBAcGFyYW0gZGlyX25hbWUgbmFtZSBvZiBkaXJlY3RvcnkKIycgQHJldHVybiBsaXN0IG9mIG5hbWVkIGV4cGVyaW1lbnRzCmdldERlc2NlbmRhbnRzIDwtIGZ1bmN0aW9uKGRpcl9uYW1lKSB7CiAgZXhwZXJpbWVudHMgPC0gbGlzdCgpCiAgZm9yIChkIGluIGxpc3QuZGlycyhkaXJfbmFtZSkpIHsKICAgIGlmIChmaWxlLmV4aXN0cyhmaWxlLnBhdGgoZCwgImV4cGVyaW1lbnQucmRzIikpKSB7CiAgICAgIGlmIChpZGVudGljYWwoZCwgcGFyYW1zJHNpbV9wYXRoKSkgewogICAgICAgIGV4cF9uYW1lIDwtICJCYXNlIgogICAgICB9IGVsc2UgewogICAgICAgIGV4cF9uYW1lIDwtIHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCgKICAgICAgICAgIHN0cmluZ3I6OnN0cl9yZW1vdmUoZCwgcGFzdGUwKHBhcmFtcyRzaW1fcGF0aCwgIi8iKSksCiAgICAgICAgICAiLyIsICIgLSAiCiAgICAgICAgKQogICAgICB9CiAgICAgIGV4cGVyaW1lbnRzW1tleHBfbmFtZV1dIDwtIHJlYWRSRFMoZmlsZS5wYXRoKGQsICJleHBlcmltZW50LnJkcyIpKQogICAgfQogIH0KICByZXR1cm4oZXhwZXJpbWVudHMpCn0KCiMnIENoZWNrIGlmIGV4cGVyaW1lbnQgZXhpc3RzCiMnCiMnIEBwYXJhbSBkaXJfbmFtZSBuYW1lIG9mIGRpcmVjdG9yeSBvciB2ZWN0b3IgdGhlcmVvZgojJyBAcGFyYW0gcmVjdXJzaXZlIGxvZ2ljYWw7IGlmIFRSVUUsIGNoZWNrcyBpZiBleHBlcmltZW50IGV4aXN0cyB1bmRlciB0aGUKIycgICBnaXZlbiBkaXJlY3Rvcnkocyk7IGlmIEZBTFNFLCBjaGVja3MgaWYgYW55IGV4cGVyaW1lbnQgZXhpc3RzIHVuZGVyIHRoZQojJyAgIGRpcmVjdG9yeShzKSBhbmQgaXRzIGRlc2NlbmRhbnRzCiMnIEByZXR1cm4gVFJVRSBpZiBleHBlcmltZW50IGV4aXN0cyBhbmQgRkFMU0Ugb3RoZXJ3aXNlCmV4cGVyaW1lbnRFeGlzdHMgPC0gZnVuY3Rpb24oZGlyX25hbWUsIHJlY3Vyc2l2ZSA9IEZBTFNFKSB7CiAgcmVzIDwtIHB1cnJyOjptYXBfbGdsKGRpcl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZWN1cnNpdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cF9mbmFtZSA8LSBmaWxlLnBhdGgoZCwgImV4cGVyaW1lbnQucmRzIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybihmaWxlLmV4aXN0cyhleHBfZm5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjZW5kYW50cyA8LSBnZXREZXNjZW5kYW50cyhkKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuKGxlbmd0aChkZXNjZW5kYW50cykgPiAwKQogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSkKICByZXR1cm4oYW55KHJlcykpCn0KCiMnIERpc3BsYXlzIGNvbnRlbnQgZm9yIHNwZWNpZmllZCBwYXJ0IG9mIHJlY2lwZQojJwojJyBAcGFyYW0gZmllbGRfbmFtZSBwYXJ0IG9mIHJlY2lwZSB0byBzaG93OyBtdXN0IGJlIG9uZSBvZiAiZGdwIiwgIm1ldGhvZCIsCiMnICAgImV2YWx1YXRvciIsIG9yICJ2aXN1YWxpemVyIgojJyBAcmV0dXJuIGNvbnRlbnQgZm9yIHJlY2lwZQpzaG93UmVjaXBlUGFydCA8LSBmdW5jdGlvbihmaWVsZF9uYW1lID0gYygiZGdwIiwgIm1ldGhvZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJldmFsdWF0b3IiLCAidmlzdWFsaXplciIpKSB7CgogIGZpZWxkX25hbWUgPC0gbWF0Y2guYXJnKGZpZWxkX25hbWUpCiAgZnVuY19uYW1lIDwtIGRwbHlyOjpjYXNlX3doZW4oZmllbGRfbmFtZSA9PSAiZXZhbHVhdG9yIiB+ICJldmFsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9uYW1lID09ICJ2aXN1YWxpemVyIiB+ICJ2aXoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiBmaWVsZF9uYW1lKQogIGRlc2NlbmRhbnRzIDwtIGdldERlc2NlbmRhbnRzKGRpcl9uYW1lID0gcGFyYW1zJHNpbV9wYXRoKQogIG9ianMgPC0gcHVycnI6Om1hcChkZXNjZW5kYW50cywgfi54W1twYXN0ZTAoImdldF8iLCBmaWVsZF9uYW1lLCAicyIpXV0oKSkKICBvYmpfbmFtZXMgPC0gdW5pcXVlKHB1cnJyOjpyZWR1Y2Uoc2FwcGx5KG9ianMsIG5hbWVzKSwgYykpCgogIG9ial9oZWFkZXIgPC0gIjxwIHN0eWxlPSdmb250LXdlaWdodDogYm9sZDsgZm9udC1zaXplOiAyMHB4Jz4gJXMgPC9wPiIKICBpbnZpc19oZWFkZXIgPC0gIlxuXG4jIyMgJXMgey50YWJzZXQgLnRhYnNldC1waWxscyAudGFic2V0LXJlY2lwZSAudGFic2V0LWNpcmNsZX1cblxuIgogIHNob3d0eXBlX2hlYWRlciA8LSAiXG5cbiMjIyMgJXMgey50YWJzZXQgLnRhYnNldC1waWxsc31cblxuIgogIGV4cF9oZWFkZXIgPC0gIlxuXG4jIyMjIyAlcyBcblxuIgoKICBpZiAoYWxsKHNhcHBseShvYmpzLCBsZW5ndGgpID09IDApKSB7CiAgICByZXR1cm4oY2F0KCJOL0EiKSkKICB9CgogIGZvciAoaWR4IGluIDE6bGVuZ3RoKG9ial9uYW1lcykpIHsKICAgIGNhdChzcHJpbnRmKGludmlzX2hlYWRlciwgIiIpKQogICAgb2JqX25hbWUgPC0gb2JqX25hbWVzW2lkeF0KCiAgICBjYXQoIjxkaXYgY2xhc3M9J3BhbmVsIHBhbmVsLWRlZmF1bHQgcGFkZGVkLXBhbmVsJz4iKQogICAgY2F0KHNwcmludGYob2JqX2hlYWRlciwgb2JqX25hbWUpKQoKICAgIGNhdChzcHJpbnRmKHNob3d0eXBlX2hlYWRlciwgZm9udGF3ZXNvbWU6OmZhKCJyZWFkbWUiLCBmaWxsID0gIndoaXRlIikpKQogICAgcGFzdGVNZChmaWxlLnBhdGgoZG9jX2RpciwgcGFzdGUwKGZpZWxkX25hbWUsICJzIiksCiAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAob2JqX25hbWUsICIubWQiKSkpCgogICAgY2F0KHNwcmludGYoc2hvd3R5cGVfaGVhZGVyLCBmb250YXdlc29tZTo6ZmEoImNvZGUiLCBmaWxsID0gIndoaXRlIikpKQogICAga2VlcF9vYmpzIDwtIHB1cnJyOjptYXAob2Jqcywgb2JqX25hbWUpCiAgICBrZWVwX29ianNbc2FwcGx5KGtlZXBfb2JqcywgaXMubnVsbCldIDwtIE5VTEwKICAgIGlmIChhbGwocHVycnI6Om1hcF9sZ2woa2VlcF9vYmpzLAogICAgICAgICAgICAgICAgICAgICAgICAgICB+aXNUUlVFKGNoZWNrX2VxdWFsKC54LCBrZWVwX29ianNbWzFdXSkpKSkpIHsKICAgICAgb2JqIDwtIGtlZXBfb2Jqc1tbMV1dCiAgICAgIGNhdCgiPGI+RnVuY3Rpb248L2I+IikKICAgICAgdnRoZW1lczo6c3ViY2h1bmtpZnkob2JqW1twYXN0ZTAoZnVuY19uYW1lLCAiX2Z1biIpXV0sCiAgICAgICAgICAgICAgICAgIGNodW5rX2lkeCwgb3RoZXJfYXJncyA9ICJtYXguaGVpZ2h0PScyMDBweCciKQogICAgICBjaHVua19pZHggPDwtIGNodW5rX2lkeCArIDEKICAgICAgY2F0KCI8Yj5JbnB1dCBQYXJhbWV0ZXJzPC9iPiIpCiAgICAgIHZ0aGVtZXM6OnN1YmNodW5raWZ5KG9ialtbcGFzdGUwKGZ1bmNfbmFtZSwgIl9wYXJhbXMiKV1dLAogICAgICAgICAgICAgICAgICBjaHVua19pZHgsIG90aGVyX2FyZ3MgPSAibWF4LmhlaWdodD0nMjAwcHgnIikKICAgICAgY2h1bmtfaWR4IDw8LSBjaHVua19pZHggKyAxCiAgICB9IGVsc2UgewogICAgICBmb3IgKGV4cCBpbiBuYW1lcyhvYmpzKSkgewogICAgICAgIG9iaiA8LSBvYmpzW1tleHBdXVtbb2JqX25hbWVdXQogICAgICAgIGlmIChpcy5udWxsKG9iaikpIHsKICAgICAgICAgIG5leHQKICAgICAgICB9CiAgICAgICAgY2F0KHNwcmludGYoZXhwX2hlYWRlciwgZXhwKSkKICAgICAgICBjYXQoIjxiPkZ1bmN0aW9uPC9iPiIpCiAgICAgICAgdnRoZW1lczo6c3ViY2h1bmtpZnkob2JqW1twYXN0ZTAoZnVuY19uYW1lLCAiX2Z1biIpXV0sCiAgICAgICAgICAgICAgICAgICAgY2h1bmtfaWR4LCBvdGhlcl9hcmdzID0gIm1heC5oZWlnaHQ9JzIwMHB4JyIpCiAgICAgICAgY2h1bmtfaWR4IDw8LSBjaHVua19pZHggKyAxCiAgICAgICAgY2F0KCI8Yj5JbnB1dCBQYXJhbWV0ZXJzPC9iPiIpCiAgICAgICAgdnRoZW1lczo6c3ViY2h1bmtpZnkob2JqW1twYXN0ZTAoZnVuY19uYW1lLCAiX3BhcmFtcyIpXV0sCiAgICAgICAgICAgICAgICAgICAgY2h1bmtfaWR4LCBvdGhlcl9hcmdzID0gIm1heC5oZWlnaHQ9JzIwMHB4JyIpCiAgICAgICAgY2h1bmtfaWR4IDw8LSBjaHVua19pZHggKyAxCiAgICAgIH0KICAgIH0KICAgIGNhdCgiPC9kaXY+IikKICB9Cn0KCiMnIFJlYWRzIGluIGZpbGUgaWYgaXQgZXhpc3RzIGFuZCByZXR1cm5zIE5VTEwgaWYgdGhlIGZpbGUgZG9lcyBub3QgZXhpc3QKIycKIycgQHBhcmFtIGZpbGVuYW1lIG5hbWUgb2YgLnJkcyBmaWxlIHRvIHRyeSByZWFkaW5nIGluCiMnIEByZXR1cm4gb3V0cHV0IG9mIGZpbGVuYW1lLnJkcyBpZiB0aGUgZmlsZSBleGlzdHMgYW5kIE5VTEwgb3RoZXJ3aXNlCmdldFJlc3VsdHMgPC0gZnVuY3Rpb24oZmlsZW5hbWUpIHsKICBpZiAoZmlsZS5leGlzdHMoZmlsZW5hbWUpKSB7CiAgICByZXN1bHRzIDwtIHJlYWRSRFMoZmlsZW5hbWUpCiAgfSBlbHNlIHsKICAgIHJlc3VsdHMgPC0gTlVMTAogIH0KICByZXR1cm4ocmVzdWx0cykKfQoKIycgRGlzcGxheXMgb3V0cHV0IChib3RoIGZyb20gZXZhbHVhdGUoKSBhbmQgdmlzdWFsaXplKCkpIGZyb20gc2F2ZWQgcmVzdWx0cyB1bmRlcgojJyBhIHNwZWNpZmllZCBkaXJlY3RvcnkKIycKIycgQHBhcmFtIGRpcl9uYW1lIG5hbWUgb2YgZGlyZWN0b3J5CiMnIEBwYXJhbSBkZXB0aCBpbnRlZ2VyOyBkZXB0aCBvZiBkaXJlY3RvcnkgZnJvbSBwYXJlbnQvYmFzZSBleHBlcmltZW50J3MgZm9sZGVyCiMnIEBwYXJhbSBiYXNlIGxvZ2ljYWw7IHdoZXRoZXIgb3Igbm90IHRoaXMgaXMgYSBiYXNlIGV4cGVyaW1lbnQKIycgQHBhcmFtIHNob3dfaGVhZGVyIGxvZ2ljYWw7IHdoZXRoZXIgb3Igbm90IHRvIHNob3cgc2VjdGlvbiBoZWFkZXIKIycgQHBhcmFtIHZlcmJvc2UgaW50ZWdlcjsgMCA9IG5vIG1lc3NhZ2VzOyAxID0gcHJpbnQgb3V0IGRpcmVjdG9yeSBuYW1lIG9ubHk7CiMnICAgMiA9IHByaW50IG91dCBkaXJlY3RvcnkgbmFtZSBhbmQgbmFtZSBvZiBldmFsdWF0b3JzL3Zpc3VhbGl6ZXJzCiMnIEByZXR1cm4gY29udGVudCByZXN1bHRzIGZyb20gZXZhbHVhdGUoKSBhbmQgdmlzdWFsaXplKCkgZnJvbSB0aGUgZXhwZXJpbWVudApzaG93UmVzdWx0cyA8LSBmdW5jdGlvbihkaXJfbmFtZSwgZGVwdGgsIGJhc2UgPSBGQUxTRSwgc2hvd19oZWFkZXIgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gMSkgewogIGlmICh2ZXJib3NlID49IDEpIHsKICAgIG1lc3NhZ2UocmVwKCIqIiwgZGVwdGgpLCBiYXNlbmFtZShkaXJfbmFtZSkpCiAgfQoKICBpZiAoZGVwdGggPT0gMSkgewogICAgaGVhZGVyX3RlbXBsYXRlIDwtICJcblxuJXMgJXMgey50YWJzZXQgLnRhYnNldC1waWxscyAudGFic2V0LXZtb2Rlcm59XG5cbiIKICB9IGVsc2UgewogICAgaWYgKGJhc2UgfCAhZXhwZXJpbWVudEV4aXN0cyhkaXJfbmFtZSkpIHsKICAgICAgaGVhZGVyX3RlbXBsYXRlIDwtICJcblxuJXMgJXMgey50YWJzZXQgLnRhYnNldC1waWxsc30iCiAgICB9IGVsc2UgewogICAgICBoZWFkZXJfdGVtcGxhdGUgPC0gIlxuXG4lcyAlcyB7LnRhYnNldCAudGFic2V0LXBpbGxzIC50YWJzZXQtY2lyY2xlfSIKICAgIH0KICB9CgogIGlmIChzaG93X2hlYWRlcikgewogICAgY2F0KHNwcmludGYoaGVhZGVyX3RlbXBsYXRlLAogICAgICAgICAgICAgICAgcGFzdGUocmVwKCIjIiwgZGVwdGgpLCBjb2xsYXBzZSA9ICIiKSwKICAgICAgICAgICAgICAgIGJhc2VuYW1lKGRpcl9uYW1lKSkpCiAgfQoKICBpZiAoYmFzZSkgewogICAgY2F0KHBhc3RlMCgiXG5cbiIsCiAgICAgICAgICAgICAgIHBhc3RlKHJlcCgiIyIsIGRlcHRoICsgMSksIGNvbGxhcHNlID0gIiIpLAogICAgICAgICAgICAgICAiIEJhc2UgLSAiLCBiYXNlbmFtZShkaXJfbmFtZSksCiAgICAgICAgICAgICAgICIgey50YWJzZXQgLnRhYnNldC1waWxscyAudGFic2V0LWNpcmNsZX1cblxuIikpCiAgICBkZXB0aCA8LSBkZXB0aCArIDEKICB9CgogIHNob3d0eXBlX3RlbXBsYXRlIDwtIHBhc3RlMCgKICAgICJcblxuIiwgcGFzdGUocmVwKCIjIiwgZGVwdGggKyAxKSwgY29sbGFwc2UgPSAiIiksICIgJXNcblxuIgogICkKICBmaWduYW1lX3RlbXBsYXRlIDwtICI8aDMgc3R5bGU9J2ZvbnQtd2VpZ2h0OiBib2xkJz4gJXMgPC9oMz4iCiAgaW52aXNpYmxlX2hlYWRlciA8LSBwYXN0ZTAoCiAgICAiXG5cbiIsIHBhc3RlKHJlcCgiIyIsIGRlcHRoICsgMiksIGNvbGxhcHNlID0gIiIpLAogICAgIiB7LnRhYnNldCAudGFic2V0LXBpbGxzfVxuXG4iCiAgKQogIHBsdF90ZW1wbGF0ZSA8LSBwYXN0ZTAoCiAgICAiXG5cbiIsIHBhc3RlKHJlcCgiIyIsIGRlcHRoICsgMyksIGNvbGxhcHNlID0gIiIpLCAiICVzXG5cbiIKICApCgogIGV4cF9mbmFtZSA8LSBmaWxlLnBhdGgoZGlyX25hbWUsICJleHBlcmltZW50LnJkcyIpCiAgIyBmaXRfZm5hbWUgPC0gZmlsZS5wYXRoKGRpcl9uYW1lLCAiZml0X3Jlc3VsdHMucmRzIikKICBldmFsX2ZuYW1lIDwtIGZpbGUucGF0aChkaXJfbmFtZSwgImV2YWxfcmVzdWx0cy5yZHMiKQogIHZpel9mbmFtZSA8LSBmaWxlLnBhdGgoZGlyX25hbWUsICJ2aXpfcmVzdWx0cy5yZHMiKQoKICBleHAgPC0gZ2V0UmVzdWx0cyhleHBfZm5hbWUpCiAgIyBmaXRfcmVzdWx0cyA8LSBnZXRSZXN1bHRzKGZpdF9mbmFtZSkKICBldmFsX3Jlc3VsdHMgPC0gZ2V0UmVzdWx0cyhldmFsX2ZuYW1lKQogIHZpel9yZXN1bHRzIDwtIGdldFJlc3VsdHModml6X2ZuYW1lKQoKICBpZiAoIWlzLm51bGwoZXZhbF9yZXN1bHRzKSkgewogICAgY2F0KHNwcmludGYoc2hvd3R5cGVfdGVtcGxhdGUsIGZvbnRhd2Vzb21lOjpmYSgidGFibGUiLCBmaWxsID0gIndoaXRlIikpKQogICAgZXZhbF9uYW1lcyA8LSBnZXRPYmpPcmRlcihuYW1lcyhldmFsX3Jlc3VsdHMpLCBwYXJhbXMkZXZhbF9vcmRlcikKICAgIGZvciAoZXZhbF9uYW1lIGluIGV2YWxfbmFtZXMpIHsKICAgICAgaWYgKHZlcmJvc2UgPj0gMikgewogICAgICAgIG1lc3NhZ2UocmVwKCIgIiwgZGVwdGggKyAxKSwgZXZhbF9uYW1lKQogICAgICB9CiAgICAgIGV2YWx1YXRvciA8LSBleHAkZ2V0X2V2YWx1YXRvcnMoKVtbZXZhbF9uYW1lXV0KICAgICAgaWYgKGV2YWx1YXRvciRybWRfc2hvdykgewogICAgICAgIGNhdChzcHJpbnRmKGZpZ25hbWVfdGVtcGxhdGUsIGV2YWxfbmFtZSkpCiAgICAgICAgZG8uY2FsbCh2dGhlbWVzOjpwcmV0dHlfRFQsCiAgICAgICAgICAgICAgICBjKGxpc3QoZXZhbF9yZXN1bHRzW1tldmFsX25hbWVdXSksIGV2YWx1YXRvciRybWRfb3B0aW9ucykpICU+JQogICAgICAgICAgdnRoZW1lczo6c3ViY2h1bmtpZnkoaSA9IGNodW5rX2lkeCkKICAgICAgICBjaHVua19pZHggPDwtIGNodW5rX2lkeCArIDEKICAgICAgfQogICAgfQogIH0KCiAgaWYgKCFpcy5udWxsKHZpel9yZXN1bHRzKSkgewogICAgY2F0KHNwcmludGYoc2hvd3R5cGVfdGVtcGxhdGUsCiAgICAgICAgICAgICAgICBmb250YXdlc29tZTo6ZmEoImNoYXJ0LWJhciIsIGZpbGwgPSAid2hpdGUiKSkpCiAgICB2aXpfbmFtZXMgPC0gZ2V0T2JqT3JkZXIobmFtZXModml6X3Jlc3VsdHMpLCBwYXJhbXMkdml6X29yZGVyKQogICAgZm9yICh2aXpfbmFtZSBpbiB2aXpfbmFtZXMpIHsKICAgICAgaWYgKHZlcmJvc2UgPj0gMikgewogICAgICAgIG1lc3NhZ2UocmVwKCIgIiwgZGVwdGggKyAxKSwgdml6X25hbWUpCiAgICAgIH0KICAgICAgdmlzdWFsaXplciA8LSBleHAkZ2V0X3Zpc3VhbGl6ZXJzKClbW3Zpel9uYW1lXV0KICAgICAgaWYgKHZpc3VhbGl6ZXIkcm1kX3Nob3cpIHsKICAgICAgICBjYXQoaW52aXNpYmxlX2hlYWRlcikKICAgICAgICBjYXQoc3ByaW50ZihmaWduYW1lX3RlbXBsYXRlLCB2aXpfbmFtZSkpCiAgICAgICAgcGx0cyA8LSB2aXpfcmVzdWx0c1tbdml6X25hbWVdXQogICAgICAgIGlmICghaW5oZXJpdHMocGx0cywgImxpc3QiKSkgewogICAgICAgICAgcGx0cyA8LSBsaXN0KHBsdCA9IHBsdHMpCiAgICAgICAgfQogICAgICAgIGlmIChpcy5udWxsKG5hbWVzKHBsdHMpKSkgewogICAgICAgICAgbmFtZXMocGx0cykgPC0gMTpsZW5ndGgocGx0cykKICAgICAgICB9CiAgICAgICAgZm9yIChwbHRfbmFtZSBpbiBuYW1lcyhwbHRzKSkgewogICAgICAgICAgaWYgKGxlbmd0aChwbHRzKSAhPSAxKSB7CiAgICAgICAgICAgIGNhdChzcHJpbnRmKHBsdF90ZW1wbGF0ZSwgcGx0X25hbWUpKQogICAgICAgICAgfQogICAgICAgICAgcGx0IDwtIHBsdHNbW3BsdF9uYW1lXV0KICAgICAgICAgIGlmIChpbmhlcml0cyhwbHQsICJwbG90bHkiKSkgewogICAgICAgICAgICBhZGRfY2xhc3MgPC0gYygicGFuZWwgcGFuZWwtZGVmYXVsdCBwYWRkZWQtcGFuZWwiKQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYWRkX2NsYXNzIDwtIE5VTEwKICAgICAgICAgIH0KICAgICAgICAgIHZ0aGVtZXM6OnN1YmNodW5raWZ5KHBsdCwgaSA9IGNodW5rX2lkeCwKICAgICAgICAgICAgICAgICAgICAgIGZpZ19oZWlnaHQgPSB2aXN1YWxpemVyJHJtZF9vcHRpb25zJGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgIGZpZ193aWR0aCA9IHZpc3VhbGl6ZXIkcm1kX29wdGlvbnMkd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICBvdGhlcl9hcmdzID0gIm91dC53aWR0aCA9ICcxMDAlJyIsCiAgICAgICAgICAgICAgICAgICAgICBhZGRfY2xhc3MgPSBhZGRfY2xhc3MpCiAgICAgICAgICBjaHVua19pZHggPDwtIGNodW5rX2lkeCArIDEKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIGlmICghaXMubnVsbChleHApKSB7CiAgICBpZiAoKGxlbmd0aChleHAkZ2V0X3ZhcnlfYWNyb3NzKCkkZGdwKSAhPSAwKSB8CiAgICAgICAgKGxlbmd0aChleHAkZ2V0X3ZhcnlfYWNyb3NzKCkkbWV0aG9kKSAhPSAwKSkgewogICAgICBjYXQoc3ByaW50ZihzaG93dHlwZV90ZW1wbGF0ZSwgZm9udGF3ZXNvbWU6OmZhKCJjb2RlIiwgZmlsbCA9ICJ3aGl0ZSIpKSkKICAgICAgY2F0KCI8Yj5QYXJhbWV0ZXIgVmFsdWVzPC9iPiIpCiAgICAgIHZ0aGVtZXM6OnN1YmNodW5raWZ5KGV4cCRnZXRfdmFyeV9hY3Jvc3MoKSwKICAgICAgICAgICAgICAgICAgY2h1bmtfaWR4LCBvdGhlcl9hcmdzID0gIm1heC5oZWlnaHQ9JzIwMHB4JyIpCiAgICAgIGNodW5rX2lkeCA8PC0gY2h1bmtfaWR4ICsgMQogICAgfQogIH0KfQoKIycgRGlzcGxheXMgb3V0cHV0IG9mIGV4cGVyaW1lbnQgZm9yIGFsbCBvZiBpdHMgKHNhdmVkKSBkZXNjZW5kYW50cwojJwojJyBAcGFyYW0gZGlyX25hbWUgbmFtZSBvZiBwYXJlbnQgZXhwZXJpbWVudCBkaXJlY3RvcnkKIycgQHBhcmFtIGRlcHRoIHBsYWNlaG9sZGVyIGZvciByZWN1cnNpb247IHNob3VsZCBub3QgYmUgbWVzc2VkIHdpdGgKIycgQHBhcmFtIC4uLiBvdGhlciBhcmd1bWVudHMgdG8gcGFzcyBpbnRvIHNob3dSZXN1bHRzKCkKc2hvd0Rlc2NlbmRhbnRSZXN1bHRzIDwtIGZ1bmN0aW9uKGRpcl9uYW1lLCBkZXB0aCA9IDEsIC4uLikgewogIGNoaWxkcmVuIDwtIGxpc3QuZGlycyhkaXJfbmFtZSwgcmVjdXJzaXZlID0gRkFMU0UpCiAgaWYgKGxlbmd0aChjaGlsZHJlbikgPT0gMCkgewogICAgcmV0dXJuKCkKICB9CiAgZm9yIChjaGlsZF9pZHggaW4gMTpsZW5ndGgoY2hpbGRyZW4pKSB7CiAgICBjaGlsZCA8LSBjaGlsZHJlbltjaGlsZF9pZHhdCiAgICBpZiAoIWV4cGVyaW1lbnRFeGlzdHMoY2hpbGQsIHJlY3Vyc2l2ZSA9IFRSVUUpKSB7CiAgICAgIG5leHQKICAgIH0KICAgIGlmIChleHBlcmltZW50RXhpc3RzKGNoaWxkLCByZWN1cnNpdmUgPSBGQUxTRSkgJgogICAgICAgIChleHBlcmltZW50RXhpc3RzKGxpc3QuZGlycyhjaGlsZCwgcmVjdXJzaXZlID0gVFJVRSlbLTFdKSB8CiAgICAgICAgIChkZXB0aCA9PSAxKSkpIHsKICAgICAgYmFzZSA8LSBUUlVFCiAgICB9IGVsc2UgewogICAgICBiYXNlIDwtIEZBTFNFCiAgICB9CiAgICBzaG93UmVzdWx0cyhjaGlsZCwgZGVwdGgsIGJhc2UgPSBiYXNlLCAuLi4pCiAgICBzaG93RGVzY2VuZGFudFJlc3VsdHMoY2hpbGQsIGRlcHRoICsgMSwgLi4uKQogIH0KfQoKCmBgYAoKIyBTaW11bGF0aW9uIEV4cGVyaW1lbnQgUmVjaXBlIHsudGFic2V0IC50YWJzZXQtdm1vZGVybn0KCiMjIE9iamVjdGl2ZXMgey5wYW5lbCAucGFuZWwtZGVmYXVsdCAucGFkZGVkLXBhbmVsfQoKYGBge3Igb2JqZWN0aXZlcywgcmVzdWx0cyA9ICJhc2lzIn0KcGFzdGVNZChmaWxlLnBhdGgoZG9jX2RpciwgIm9iamVjdGl2ZXMubWQiKSkKYGBgCgojIyBEYXRhIEdlbmVyYXRpb24KCmBgYHtyIGRncHMsIHJlc3VsdHMgPSAiYXNpcyJ9CnNob3dSZWNpcGVQYXJ0KGZpZWxkX25hbWUgPSAiZGdwIikKYGBgCgojIyBNZXRob2RzIGFuZCBFdmFsdWF0aW9uCgojIyMgTWV0aG9kcwoKYGBge3IgbWV0aG9kcywgcmVzdWx0cyA9ICJhc2lzIn0Kc2hvd1JlY2lwZVBhcnQoZmllbGRfbmFtZSA9ICJtZXRob2QiKQpgYGAKCiMjIyBFdmFsdWF0aW9uCgpgYGB7ciBldmFsdWF0b3JzLCByZXN1bHRzID0gImFzaXMifQpzaG93UmVjaXBlUGFydChmaWVsZF9uYW1lID0gImV2YWx1YXRvciIpCmBgYAoKIyMgVmlzdWFsaXphdGlvbnMKCmBgYHtyIHZpc3VhbGl6ZXJzLCByZXN1bHRzID0gImFzaXMifQpzaG93UmVjaXBlUGFydChmaWVsZF9uYW1lID0gInZpc3VhbGl6ZXIiKQpgYGAKCgoKYGBge3IgcmVzLCByZXN1bHRzID0gImFzaXMifQoKIyBzaG93IHJlc3VsdHMKaWYgKGV4cGVyaW1lbnRFeGlzdHMocGFyYW1zJHNpbV9wYXRoKSkgewogIGNhdChzcHJpbnRmKCJcblxuIyBCYXNlICVzIFxuXG4iLCBwYXJhbXMkc2ltX25hbWUpKQogIGNhdCgiXG5cbiMjIHsudGFic2V0IC50YWJzZXQtcGlsbHMgLnRhYnNldC1jaXJjbGV9XG5cbiIpCiAgbWVzc2FnZShzcHJpbnRmKCJDcmVhdGluZyBSIE1hcmtkb3duIHJlcG9ydCBmb3IgJXMuLi4iLCBwYXJhbXMkc2ltX25hbWUpKQogIHNob3dSZXN1bHRzKHBhcmFtcyRzaW1fcGF0aCwgZGVwdGggPSAyLCBiYXNlID0gRkFMU0UsIHNob3dfaGVhZGVyID0gRkFMU0UsCiAgICAgICAgICAgICAgdmVyYm9zZSA9IDApCn0KCnNob3dEZXNjZW5kYW50UmVzdWx0cyhwYXJhbXMkc2ltX3BhdGgsIHZlcmJvc2UgPSBwYXJhbXMkdmVyYm9zZSkKCmBgYAo=