Mendelian Randomization

Import Exposure

library(tidyverse)
library(TwoSampleMR)
library(LDlinkR)      # LD and proxy snps
library(ieugwasr)
library(fixtuRes)
exposure_path_A2 = "gwas_resources/A2EUR_GRCH38.tsv.gz"
exposure_c1 <- read_tsv(exposure_path_A2,comment = "##", 
                        col_select = c(1,2,3,4,5,6,7,8,9,14,15))
colnames(exposure_c1)<- c("CHR","POS","effect_allele.exposure","other_allele.exposure","SNP","N","beta.exposure","se.exposure","pval","eaf.exposure","rsid")
exposure_c1$exposure <- rep(c("A2_severe_respiratory_COVID19"),times=nrow(exposure_c1));
clump_id<- "a2grch"
#calculate z value
exposure_c1$z.exposure <- exposure_c1$beta.exposure/exposure_c1$se.exposure;
exposure_c1$id.exposure <- rep(c(clump_id),times=nrow(exposure_c1));


exposure_dat1 <- filter(exposure_c1, pval < 5e-8)
exposure_clump1 <-ld_clump(
    #dplyr::tibble(rsid=exposure_c1$rsid, pval=exposure_c1$pval, id=exposure_c1$trait_id),
    dat = exposure_dat1,
    plink_bin = genetics.binaRies::get_plink_binary(),
    bfile = "1kgv3/EUR"
    
)

write_csv(exposure_clump1, "data/exposure_A2GRCH38.csv", append = FALSE)
exposure_path_B2 = "gwas_resources/B2EUR_GRCH38.tsv.gz"
exposure_c2 <- read_tsv(exposure_path_B2,comment = "##", 
                        col_select = c(1,2,3,4,5,6,7,8,9,14,15))
colnames(exposure_c2)<- c("CHR","POS","effect_allele.exposure","other_allele.exposure","SNP","N","beta.exposure","se.exposure","pval","eaf.exposure","rsid")
exposure_c2$exposure <- rep(c("B2_hospitalized_COVID19"),times=nrow(exposure_c2));
clump_id<- "b2grch"
#calculate z value
exposure_c2$z.exposure <- exposure_c2$beta.exposure/exposure_c2$se.exposure;
exposure_c2$id.exposure <- rep(c(clump_id),times=nrow(exposure_c2));


exposure_dat2 <- filter(exposure_c2, pval < 5e-8)
exposure_clump2 <-ld_clump(
    #dplyr::tibble(rsid=exposure_c1$rsid, pval=exposure_c1$pval, id=exposure_c1$trait_id),
    dat = exposure_dat2,
    plink_bin = genetics.binaRies::get_plink_binary(),
    bfile = "1kgv3/EUR"
    
)

write_csv(exposure_clump2, "data/exposure_B2GRCH38.csv", append = FALSE)
exposure_path_C2 = "gwas_resources/C2EUR_GRCH38.tsv.gz"
exposure_c3 <- read_tsv(exposure_path_C2,comment = "##", 
                        col_select = c(1,2,3,4,5,6,7,8,9,14,15))
colnames(exposure_c3)<- c("CHR","POS","effect_allele.exposure","other_allele.exposure","SNP","N","beta.exposure","se.exposure","pval","eaf.exposure","rsid")
exposure_c3$exposure <- rep(c("C2_COVID19"),times=nrow(exposure_c3));
clump_id<- "c2grch"
#calculate z value
exposure_c3$z.exposure <- exposure_c3$beta.exposure/exposure_c3$se.exposure;
exposure_c3$id.exposure <- rep(c(clump_id),times=nrow(exposure_c3));


exposure_dat3 <- filter(exposure_c3, pval < 5e-8)
exposure_clump3 <-ld_clump(
    #dplyr::tibble(rsid=exposure_c1$rsid, pval=exposure_c1$pval, id=exposure_c1$trait_id),
    dat = exposure_dat3,
    plink_bin = genetics.binaRies::get_plink_binary(),
    bfile = "1kgv3/EUR"
    
)

write_csv(exposure_clump3, "data/exposure_C2GRCH38.csv", append = FALSE)

Import Outcome

outcome1 <- read_tsv('gwas_resources/AKIJiangL2021h.tsv.gz', col_select = c(2,3,4,5,6,7,11,12,18, 21,22))
colnames(outcome1)<- c("rsid","CHR","POS","other_allele.outcome","effect_allele.outcome","beta.outcome","eaf.outcome","code","N","se.outcome","pval.outcome")
outcome1$outcome <- rep(c("PheCode 585.1"),times=nrow(outcome1));
clump_id <- "jiangl2021";
outcome1$id.outcome <- rep(c(clump_id),times=nrow(outcome1));
exposure_snps <- read_csv("data/exposure_A2GRCH38.csv") 
#filter outcome on SNPs in the exposure
outcome_clumped <- filter(outcome1, rsid %in% exposure_snps$rsid)
#harmonise data
mr_dat <- harmonise_data(dplyr::tibble(SNP=exposure_snps$rsid, beta.exposure=exposure_snps$beta.exposure, se.exposure=exposure_snps$se.exposure, effect_allele.exposure = exposure_snps$effect_allele.exposure, other_allele.exposure = exposure_snps$other_allele.exposure,eaf.exposure = exposure_snps$eaf.exposure, id.exposure = exposure_snps$id.exposure, exposure = exposure_snps$exposure), dplyr::tibble(SNP=outcome_clumped$rsid, beta.outcome=outcome_clumped$beta.outcome, se.outcome=outcome_clumped$se.outcome, effect_allele.outcome = outcome_clumped$effect_allele.outcome, other_allele.outcome = outcome_clumped$other_allele.outcome,eaf.outcome = outcome_clumped$eaf.outcome , outcome = outcome_clumped$outcome, id.outcome = outcome_clumped$id.outcome), action = 2)
write_csv(mr_dat, "harmonized/harmonized_A2_JiangL")
outcome2 <- read_tsv('gwas_resources/DouvilleNJModel1h.tsv.gz', col_select = c(1,2,3,4,5,6,7,8,9,13))
colnames(outcome2)<- c("CHR","POS","effect_allele.outcome","other_allele.outcome","beta.outcome","se.outcome","eaf.outcome","pval.outcome","rsid","N")
outcome2$outcome <- rep(c("Sepsis AKI"),times=nrow(outcome2));
clump_id <- "DouvilleNJ2025";
outcome2$id.outcome <- rep(c(clump_id),times=nrow(outcome2));


exposure_snps <- read_csv("data/exposure_A2GRCH38.csv") 
#filter outcome on SNPs in the exposure
outcome_clumped <- filter(outcome2, rsid %in% exposure_snps$rsid)
#harmonise data
mr_dat <- harmonise_data(dplyr::tibble(SNP=exposure_snps$rsid, beta.exposure=exposure_snps$beta.exposure, se.exposure=exposure_snps$se.exposure, effect_allele.exposure = exposure_snps$effect_allele.exposure, other_allele.exposure = exposure_snps$other_allele.exposure,eaf.exposure = exposure_snps$eaf.exposure, id.exposure = exposure_snps$id.exposure, exposure = exposure_snps$exposure), dplyr::tibble(SNP=outcome_clumped$rsid, beta.outcome=outcome_clumped$beta.outcome, se.outcome=outcome_clumped$se.outcome, effect_allele.outcome = outcome_clumped$effect_allele.outcome, other_allele.outcome = outcome_clumped$other_allele.outcome,eaf.outcome = outcome_clumped$eaf.outcome , outcome = outcome_clumped$outcome, id.outcome = outcome_clumped$id.outcome), action = 2)
write_csv(mr_dat, "harmonized/harmonized_A2_Douville")
outcome3 <- read_tsv('gwas_resources/AKIVermaAh.tsv.gz', col_select = c(1,2,3,4,5,6,7,8,9,13))
colnames(outcome3)<- c("CHR","POS","effect_allele.outcome","other_allele.outcome","oddsratio.outcome","se.outcome","eaf.outcome","pval.outcome","rsid","N")
outcome3$outcome <- rep(c("PheCode 585.1 (Verma)"),times=nrow(outcome3));
clump_id <- "vermaA2024";
outcome3$id.outcome <- rep(c(clump_id),times=nrow(outcome3));
outcome3$beta.outcome <- log(outcome3$oddsratio.outcome)


exposure_snps <- read_csv("data/exposure_A2GRCH38.csv") 
#filter outcome on SNPs in the exposure
outcome_clumped <- filter(outcome3, rsid %in% exposure_snps$rsid)
#harmonise data
mr_dat <- harmonise_data(dplyr::tibble(SNP=exposure_snps$rsid, beta.exposure=exposure_snps$beta.exposure, se.exposure=exposure_snps$se.exposure, effect_allele.exposure = exposure_snps$effect_allele.exposure, other_allele.exposure = exposure_snps$other_allele.exposure,eaf.exposure = exposure_snps$eaf.exposure, id.exposure = exposure_snps$id.exposure, exposure = exposure_snps$exposure), dplyr::tibble(SNP=outcome_clumped$rsid, beta.outcome=outcome_clumped$beta.outcome, se.outcome=outcome_clumped$se.outcome, effect_allele.outcome = outcome_clumped$effect_allele.outcome, other_allele.outcome = outcome_clumped$other_allele.outcome,eaf.outcome = outcome_clumped$eaf.outcome , outcome = outcome_clumped$outcome, id.outcome = outcome_clumped$id.outcome), action = 2)
write_csv(mr_dat, "harmonized/harmonized_A2_VermaA")

MR Analysis

library(tidyverse)    # Data wrangling 
library(knitr)
library(TwoSampleMR)  # MR 
library(gt)
library(LDlinkR)      # LD and proxy snps
library(RadialMR)     # Radial MR sensetivity analysis 
library(phenoscanner)
mr_dat <- read_csv("harmonized/harmonized_A2_JiangL")
Rows: 28 Columns: 22── Column specification ──────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (9): SNP, effect_allele.exposure, other_allele.exposure, effect_allele.outcome, other_allele.outcome, ...
dbl (8): beta.exposure, beta.outcome, eaf.exposure, eaf.outcome, se.outcome, se.exposure, action, SNP_index
lgl (5): remove, palindromic, ambiguous, mr_keep, samplesize.outcome
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
mr_pleiotrophy_result <- mr_pleiotropy_test(mr_dat)
View(mr_pleiotrophy_result)
mr_res <- mr(mr_dat, method_list = c(
  "mr_two_sample_ml",  "mr_egger_regression", 
  "mr_simple_median", "mr_weighted_median", 
  "mr_ivw_fe", "mr_ivw_mre",
  "mr_simple_mode", "mr_weighted_mode"
  ))
Analysing 'a2grch' on 'jiangl2021'
res_single <- mr_singlesnp(mr_dat, all_method = c("mr_ivw_fe", "mr_egger_regression", "mr_weighted_median", "mr_weighted_mode")) %>% as_tibble()
View(res_single)
odd <- generate_odds_ratios(mr_res)
print("Finished Analyzing")
[1] "Finished Analyzing"
write.csv(odd,"results/A2/jiangla2_oddsratios.csv")
write.csv(res_single,"results/A2/jiangla2_res_single.csv")
scatter_p <- mr_scatter_plot(mr_res, mr_dat) 
scatter_out_p <- scatter_p[[1]] + theme_bw() + 
  guides(color=guide_legend(ncol =1)) + 
  theme(
    text = element_text(size = 8), 
  )

scatter_out_p
ggsave("results/A2/scatterplotA2JiangL.png", plot = scatter_out_p, units = 'in', height = 4, width = 9)

forrest_p <- mr_forest_plot(res_single)
forrest_p[[1]]
ggsave("results/A2/forrestplotA2JiangL.png", plot =forrest_p[[1]] + theme(text = element_text(size = 8)), units = 'in', height = 9, width = 9)


res_loo <- mr_leaveoneout(mr_dat, method = mr_ivw_fe) %>% as_tibble()
loo_p <- mr_leaveoneout_plot(res_loo)
loo_p[[1]]
ggsave("results/A2/looA2JiangL.png",plot = loo_p[[1]], units = 'in', height = 9, width = 9)


funnel_p <- mr_funnel_plot(res_single)
funnel_out_p <- funnel_p[[1]] + theme_bw() + 
  guides(color=guide_legend(ncol =1)) + 
  theme(
    text = element_text(size = 8), 
  )

funnel_out_p
ggsave("results/A2/funnelplotA2JiangL.png", plot = funnel_out_p, units = 'in', height = 4, width = 9)


mr_dat <- read_csv("harmonized/harmonized_A2_Douville")
Rows: 28 Columns: 22── Column specification ──────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (9): SNP, effect_allele.exposure, other_allele.exposure, effect_allele.outcome, other_allele.outcome, ...
dbl (8): beta.exposure, beta.outcome, eaf.exposure, eaf.outcome, se.outcome, se.exposure, action, SNP_index
lgl (5): remove, palindromic, ambiguous, mr_keep, samplesize.outcome
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
mr_res <- mr(mr_dat, method_list = c(
  "mr_two_sample_ml",  "mr_egger_regression", 
  "mr_simple_median", "mr_weighted_median", 
  "mr_ivw_fe", "mr_ivw_mre",
  "mr_simple_mode", "mr_weighted_mode"
  ))
Analysing 'a2grch' on 'DouvilleNJ2025'
res_single <- mr_singlesnp(mr_dat, all_method = c("mr_ivw_fe", "mr_egger_regression", "mr_weighted_median", "mr_weighted_mode")) %>% as_tibble()
View(res_single)
odd <- generate_odds_ratios(mr_res)
print("Finished Analyzing")
[1] "Finished Analyzing"
write.csv(odd,"results/A2/douvillea2_oddsratios.csv")
write.csv(res_single,"results/A2/douvillea2_res_single.csv")

scatter_p <- mr_scatter_plot(mr_res, mr_dat) 
scatter_out_p <- scatter_p[[1]] + theme_bw() + 
  guides(color=guide_legend(ncol =1)) + 
  theme(
    text = element_text(size = 8), 
  )

scatter_out_p
ggsave("results/A2/scatterplotA2Douville.png", plot = scatter_out_p, units = 'in', height = 4, width = 9)

forrest_p <- mr_forest_plot(res_single)
forrest_p[[1]]
ggsave("results/A2/forrestplotA2Douville.png", plot =forrest_p[[1]] + theme(text = element_text(size = 8)), units = 'in', height = 9, width = 9)


res_loo <- mr_leaveoneout(mr_dat, method = mr_ivw_fe) %>% as_tibble()
loo_p <- mr_leaveoneout_plot(res_loo)
loo_p[[1]]
ggsave("results/A2/looA2Douville.png",plot = loo_p[[1]], units = 'in', height = 9, width = 9)

ggman(filter(tc_ss, p_value < 0.05 & p_value > 1e-100), snp = "SNPID", bp = "base_pair_location", chrom = "chromosome", pvalue = "p_value", relative.positions = TRUE) + 
  theme_classic()
Warning: The `<scale>` argument of `guides()` cannot be `FALSE`. Use "none" instead as of ggplot2 3.3.4.

LS0tCnRpdGxlOiAiTVItQW5hbHlzaXMgMi0yNi0yMDI2IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIE1lbmRlbGlhbiBSYW5kb21pemF0aW9uCgojIyBJbXBvcnQgRXhwb3N1cmUKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShUd29TYW1wbGVNUikKbGlicmFyeShMRGxpbmtSKSAgICAgICMgTEQgYW5kIHByb3h5IHNucHMKbGlicmFyeShpZXVnd2FzcikKbGlicmFyeShmaXh0dVJlcykKYGBgCgpgYGB7cixldmFsPUZBTFNFfQoKZXhwb3N1cmVfcGF0aF9BMiA9ICJnd2FzX3Jlc291cmNlcy9BMkVVUl9HUkNIMzgudHN2Lmd6IgpleHBvc3VyZV9jMSA8LSByZWFkX3RzdihleHBvc3VyZV9wYXRoX0EyLGNvbW1lbnQgPSAiIyMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgY29sX3NlbGVjdCA9IGMoMSwyLDMsNCw1LDYsNyw4LDksMTQsMTUpKQpjb2xuYW1lcyhleHBvc3VyZV9jMSk8LSBjKCJDSFIiLCJQT1MiLCJlZmZlY3RfYWxsZWxlLmV4cG9zdXJlIiwib3RoZXJfYWxsZWxlLmV4cG9zdXJlIiwiU05QIiwiTiIsImJldGEuZXhwb3N1cmUiLCJzZS5leHBvc3VyZSIsInB2YWwiLCJlYWYuZXhwb3N1cmUiLCJyc2lkIikKZXhwb3N1cmVfYzEkZXhwb3N1cmUgPC0gcmVwKGMoIkEyX3NldmVyZV9yZXNwaXJhdG9yeV9DT1ZJRDE5IiksdGltZXM9bnJvdyhleHBvc3VyZV9jMSkpOwpjbHVtcF9pZDwtICJhMmdyY2giCiNjYWxjdWxhdGUgeiB2YWx1ZQpleHBvc3VyZV9jMSR6LmV4cG9zdXJlIDwtIGV4cG9zdXJlX2MxJGJldGEuZXhwb3N1cmUvZXhwb3N1cmVfYzEkc2UuZXhwb3N1cmU7CmV4cG9zdXJlX2MxJGlkLmV4cG9zdXJlIDwtIHJlcChjKGNsdW1wX2lkKSx0aW1lcz1ucm93KGV4cG9zdXJlX2MxKSk7CgoKZXhwb3N1cmVfZGF0MSA8LSBmaWx0ZXIoZXhwb3N1cmVfYzEsIHB2YWwgPCA1ZS04KQpleHBvc3VyZV9jbHVtcDEgPC1sZF9jbHVtcCgKICAgICNkcGx5cjo6dGliYmxlKHJzaWQ9ZXhwb3N1cmVfYzEkcnNpZCwgcHZhbD1leHBvc3VyZV9jMSRwdmFsLCBpZD1leHBvc3VyZV9jMSR0cmFpdF9pZCksCiAgICBkYXQgPSBleHBvc3VyZV9kYXQxLAogICAgcGxpbmtfYmluID0gZ2VuZXRpY3MuYmluYVJpZXM6OmdldF9wbGlua19iaW5hcnkoKSwKICAgIGJmaWxlID0gIjFrZ3YzL0VVUiIKICAgIAopCgp3cml0ZV9jc3YoZXhwb3N1cmVfY2x1bXAxLCAiZGF0YS9leHBvc3VyZV9BMkdSQ0gzOC5jc3YiLCBhcHBlbmQgPSBGQUxTRSkKCgpgYGAKCmBgYHtyLGV2YWw9RkFMU0V9CmV4cG9zdXJlX3BhdGhfQjIgPSAiZ3dhc19yZXNvdXJjZXMvQjJFVVJfR1JDSDM4LnRzdi5neiIKZXhwb3N1cmVfYzIgPC0gcmVhZF90c3YoZXhwb3N1cmVfcGF0aF9CMixjb21tZW50ID0gIiMjIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbF9zZWxlY3QgPSBjKDEsMiwzLDQsNSw2LDcsOCw5LDE0LDE1KSkKY29sbmFtZXMoZXhwb3N1cmVfYzIpPC0gYygiQ0hSIiwiUE9TIiwiZWZmZWN0X2FsbGVsZS5leHBvc3VyZSIsIm90aGVyX2FsbGVsZS5leHBvc3VyZSIsIlNOUCIsIk4iLCJiZXRhLmV4cG9zdXJlIiwic2UuZXhwb3N1cmUiLCJwdmFsIiwiZWFmLmV4cG9zdXJlIiwicnNpZCIpCmV4cG9zdXJlX2MyJGV4cG9zdXJlIDwtIHJlcChjKCJCMl9ob3NwaXRhbGl6ZWRfQ09WSUQxOSIpLHRpbWVzPW5yb3coZXhwb3N1cmVfYzIpKTsKY2x1bXBfaWQ8LSAiYjJncmNoIgojY2FsY3VsYXRlIHogdmFsdWUKZXhwb3N1cmVfYzIkei5leHBvc3VyZSA8LSBleHBvc3VyZV9jMiRiZXRhLmV4cG9zdXJlL2V4cG9zdXJlX2MyJHNlLmV4cG9zdXJlOwpleHBvc3VyZV9jMiRpZC5leHBvc3VyZSA8LSByZXAoYyhjbHVtcF9pZCksdGltZXM9bnJvdyhleHBvc3VyZV9jMikpOwoKCmV4cG9zdXJlX2RhdDIgPC0gZmlsdGVyKGV4cG9zdXJlX2MyLCBwdmFsIDwgNWUtOCkKZXhwb3N1cmVfY2x1bXAyIDwtbGRfY2x1bXAoCiAgICAjZHBseXI6OnRpYmJsZShyc2lkPWV4cG9zdXJlX2MxJHJzaWQsIHB2YWw9ZXhwb3N1cmVfYzEkcHZhbCwgaWQ9ZXhwb3N1cmVfYzEkdHJhaXRfaWQpLAogICAgZGF0ID0gZXhwb3N1cmVfZGF0MiwKICAgIHBsaW5rX2JpbiA9IGdlbmV0aWNzLmJpbmFSaWVzOjpnZXRfcGxpbmtfYmluYXJ5KCksCiAgICBiZmlsZSA9ICIxa2d2My9FVVIiCiAgICAKKQoKd3JpdGVfY3N2KGV4cG9zdXJlX2NsdW1wMiwgImRhdGEvZXhwb3N1cmVfQjJHUkNIMzguY3N2IiwgYXBwZW5kID0gRkFMU0UpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0KZXhwb3N1cmVfcGF0aF9DMiA9ICJnd2FzX3Jlc291cmNlcy9DMkVVUl9HUkNIMzgudHN2Lmd6IgpleHBvc3VyZV9jMyA8LSByZWFkX3RzdihleHBvc3VyZV9wYXRoX0MyLGNvbW1lbnQgPSAiIyMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgY29sX3NlbGVjdCA9IGMoMSwyLDMsNCw1LDYsNyw4LDksMTQsMTUpKQpjb2xuYW1lcyhleHBvc3VyZV9jMyk8LSBjKCJDSFIiLCJQT1MiLCJlZmZlY3RfYWxsZWxlLmV4cG9zdXJlIiwib3RoZXJfYWxsZWxlLmV4cG9zdXJlIiwiU05QIiwiTiIsImJldGEuZXhwb3N1cmUiLCJzZS5leHBvc3VyZSIsInB2YWwiLCJlYWYuZXhwb3N1cmUiLCJyc2lkIikKZXhwb3N1cmVfYzMkZXhwb3N1cmUgPC0gcmVwKGMoIkMyX0NPVklEMTkiKSx0aW1lcz1ucm93KGV4cG9zdXJlX2MzKSk7CmNsdW1wX2lkPC0gImMyZ3JjaCIKI2NhbGN1bGF0ZSB6IHZhbHVlCmV4cG9zdXJlX2MzJHouZXhwb3N1cmUgPC0gZXhwb3N1cmVfYzMkYmV0YS5leHBvc3VyZS9leHBvc3VyZV9jMyRzZS5leHBvc3VyZTsKZXhwb3N1cmVfYzMkaWQuZXhwb3N1cmUgPC0gcmVwKGMoY2x1bXBfaWQpLHRpbWVzPW5yb3coZXhwb3N1cmVfYzMpKTsKCgpleHBvc3VyZV9kYXQzIDwtIGZpbHRlcihleHBvc3VyZV9jMywgcHZhbCA8IDVlLTgpCmV4cG9zdXJlX2NsdW1wMyA8LWxkX2NsdW1wKAogICAgI2RwbHlyOjp0aWJibGUocnNpZD1leHBvc3VyZV9jMSRyc2lkLCBwdmFsPWV4cG9zdXJlX2MxJHB2YWwsIGlkPWV4cG9zdXJlX2MxJHRyYWl0X2lkKSwKICAgIGRhdCA9IGV4cG9zdXJlX2RhdDMsCiAgICBwbGlua19iaW4gPSBnZW5ldGljcy5iaW5hUmllczo6Z2V0X3BsaW5rX2JpbmFyeSgpLAogICAgYmZpbGUgPSAiMWtndjMvRVVSIgogICAgCikKCndyaXRlX2NzdihleHBvc3VyZV9jbHVtcDMsICJkYXRhL2V4cG9zdXJlX0MyR1JDSDM4LmNzdiIsIGFwcGVuZCA9IEZBTFNFKQpgYGAKCiMjIEltcG9ydCBPdXRjb21lCgpgYGB7cixldmFsPUZBTFNFfQpvdXRjb21lMSA8LSByZWFkX3RzdignZ3dhc19yZXNvdXJjZXMvQUtJSmlhbmdMMjAyMWgudHN2Lmd6JywgY29sX3NlbGVjdCA9IGMoMiwzLDQsNSw2LDcsMTEsMTIsMTgsIDIxLDIyKSkKY29sbmFtZXMob3V0Y29tZTEpPC0gYygicnNpZCIsIkNIUiIsIlBPUyIsIm90aGVyX2FsbGVsZS5vdXRjb21lIiwiZWZmZWN0X2FsbGVsZS5vdXRjb21lIiwiYmV0YS5vdXRjb21lIiwiZWFmLm91dGNvbWUiLCJjb2RlIiwiTiIsInNlLm91dGNvbWUiLCJwdmFsLm91dGNvbWUiKQpvdXRjb21lMSRvdXRjb21lIDwtIHJlcChjKCJQaGVDb2RlIDU4NS4xIiksdGltZXM9bnJvdyhvdXRjb21lMSkpOwpjbHVtcF9pZCA8LSAiamlhbmdsMjAyMSI7Cm91dGNvbWUxJGlkLm91dGNvbWUgPC0gcmVwKGMoY2x1bXBfaWQpLHRpbWVzPW5yb3cob3V0Y29tZTEpKTsKYGBgCgpgYGB7cixldmFsPUZBTFNFfQpleHBvc3VyZV9zbnBzIDwtIHJlYWRfY3N2KCJkYXRhL2V4cG9zdXJlX0EyR1JDSDM4LmNzdiIpIAojZmlsdGVyIG91dGNvbWUgb24gU05QcyBpbiB0aGUgZXhwb3N1cmUKb3V0Y29tZV9jbHVtcGVkIDwtIGZpbHRlcihvdXRjb21lMSwgcnNpZCAlaW4lIGV4cG9zdXJlX3NucHMkcnNpZCkKI2hhcm1vbmlzZSBkYXRhCm1yX2RhdCA8LSBoYXJtb25pc2VfZGF0YShkcGx5cjo6dGliYmxlKFNOUD1leHBvc3VyZV9zbnBzJHJzaWQsIGJldGEuZXhwb3N1cmU9ZXhwb3N1cmVfc25wcyRiZXRhLmV4cG9zdXJlLCBzZS5leHBvc3VyZT1leHBvc3VyZV9zbnBzJHNlLmV4cG9zdXJlLCBlZmZlY3RfYWxsZWxlLmV4cG9zdXJlID0gZXhwb3N1cmVfc25wcyRlZmZlY3RfYWxsZWxlLmV4cG9zdXJlLCBvdGhlcl9hbGxlbGUuZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJG90aGVyX2FsbGVsZS5leHBvc3VyZSxlYWYuZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJGVhZi5leHBvc3VyZSwgaWQuZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJGlkLmV4cG9zdXJlLCBleHBvc3VyZSA9IGV4cG9zdXJlX3NucHMkZXhwb3N1cmUpLCBkcGx5cjo6dGliYmxlKFNOUD1vdXRjb21lX2NsdW1wZWQkcnNpZCwgYmV0YS5vdXRjb21lPW91dGNvbWVfY2x1bXBlZCRiZXRhLm91dGNvbWUsIHNlLm91dGNvbWU9b3V0Y29tZV9jbHVtcGVkJHNlLm91dGNvbWUsIGVmZmVjdF9hbGxlbGUub3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRlZmZlY3RfYWxsZWxlLm91dGNvbWUsIG90aGVyX2FsbGVsZS5vdXRjb21lID0gb3V0Y29tZV9jbHVtcGVkJG90aGVyX2FsbGVsZS5vdXRjb21lLGVhZi5vdXRjb21lID0gb3V0Y29tZV9jbHVtcGVkJGVhZi5vdXRjb21lICwgb3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRvdXRjb21lLCBpZC5vdXRjb21lID0gb3V0Y29tZV9jbHVtcGVkJGlkLm91dGNvbWUpLCBhY3Rpb24gPSAyKQp3cml0ZV9jc3YobXJfZGF0LCAiaGFybW9uaXplZC9oYXJtb25pemVkX0EyX0ppYW5nTCIpCmBgYAoKYGBge3IsZXZhbD1GQUxTRX0Kb3V0Y29tZTIgPC0gcmVhZF90c3YoJ2d3YXNfcmVzb3VyY2VzL0RvdXZpbGxlTkpNb2RlbDFoLnRzdi5neicsIGNvbF9zZWxlY3QgPSBjKDEsMiwzLDQsNSw2LDcsOCw5LDEzKSkKY29sbmFtZXMob3V0Y29tZTIpPC0gYygiQ0hSIiwiUE9TIiwiZWZmZWN0X2FsbGVsZS5vdXRjb21lIiwib3RoZXJfYWxsZWxlLm91dGNvbWUiLCJiZXRhLm91dGNvbWUiLCJzZS5vdXRjb21lIiwiZWFmLm91dGNvbWUiLCJwdmFsLm91dGNvbWUiLCJyc2lkIiwiTiIpCm91dGNvbWUyJG91dGNvbWUgPC0gcmVwKGMoIlNlcHNpcyBBS0kiKSx0aW1lcz1ucm93KG91dGNvbWUyKSk7CmNsdW1wX2lkIDwtICJEb3V2aWxsZU5KMjAyNSI7Cm91dGNvbWUyJGlkLm91dGNvbWUgPC0gcmVwKGMoY2x1bXBfaWQpLHRpbWVzPW5yb3cob3V0Y29tZTIpKTsKCgpleHBvc3VyZV9zbnBzIDwtIHJlYWRfY3N2KCJkYXRhL2V4cG9zdXJlX0EyR1JDSDM4LmNzdiIpIAojZmlsdGVyIG91dGNvbWUgb24gU05QcyBpbiB0aGUgZXhwb3N1cmUKb3V0Y29tZV9jbHVtcGVkIDwtIGZpbHRlcihvdXRjb21lMiwgcnNpZCAlaW4lIGV4cG9zdXJlX3NucHMkcnNpZCkKI2hhcm1vbmlzZSBkYXRhCm1yX2RhdCA8LSBoYXJtb25pc2VfZGF0YShkcGx5cjo6dGliYmxlKFNOUD1leHBvc3VyZV9zbnBzJHJzaWQsIGJldGEuZXhwb3N1cmU9ZXhwb3N1cmVfc25wcyRiZXRhLmV4cG9zdXJlLCBzZS5leHBvc3VyZT1leHBvc3VyZV9zbnBzJHNlLmV4cG9zdXJlLCBlZmZlY3RfYWxsZWxlLmV4cG9zdXJlID0gZXhwb3N1cmVfc25wcyRlZmZlY3RfYWxsZWxlLmV4cG9zdXJlLCBvdGhlcl9hbGxlbGUuZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJG90aGVyX2FsbGVsZS5leHBvc3VyZSxlYWYuZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJGVhZi5leHBvc3VyZSwgaWQuZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJGlkLmV4cG9zdXJlLCBleHBvc3VyZSA9IGV4cG9zdXJlX3NucHMkZXhwb3N1cmUpLCBkcGx5cjo6dGliYmxlKFNOUD1vdXRjb21lX2NsdW1wZWQkcnNpZCwgYmV0YS5vdXRjb21lPW91dGNvbWVfY2x1bXBlZCRiZXRhLm91dGNvbWUsIHNlLm91dGNvbWU9b3V0Y29tZV9jbHVtcGVkJHNlLm91dGNvbWUsIGVmZmVjdF9hbGxlbGUub3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRlZmZlY3RfYWxsZWxlLm91dGNvbWUsIG90aGVyX2FsbGVsZS5vdXRjb21lID0gb3V0Y29tZV9jbHVtcGVkJG90aGVyX2FsbGVsZS5vdXRjb21lLGVhZi5vdXRjb21lID0gb3V0Y29tZV9jbHVtcGVkJGVhZi5vdXRjb21lICwgb3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRvdXRjb21lLCBpZC5vdXRjb21lID0gb3V0Y29tZV9jbHVtcGVkJGlkLm91dGNvbWUpLCBhY3Rpb24gPSAyKQp3cml0ZV9jc3YobXJfZGF0LCAiaGFybW9uaXplZC9oYXJtb25pemVkX0EyX0RvdXZpbGxlIikKYGBgCgpgYGB7cixldmFsPUZBTFNFfQpvdXRjb21lMyA8LSByZWFkX3RzdignZ3dhc19yZXNvdXJjZXMvQUtJVmVybWFBaC50c3YuZ3onLCBjb2xfc2VsZWN0ID0gYygxLDIsMyw0LDUsNiw3LDgsOSwxMykpCmNvbG5hbWVzKG91dGNvbWUzKTwtIGMoIkNIUiIsIlBPUyIsImVmZmVjdF9hbGxlbGUub3V0Y29tZSIsIm90aGVyX2FsbGVsZS5vdXRjb21lIiwib2Rkc3JhdGlvLm91dGNvbWUiLCJzZS5vdXRjb21lIiwiZWFmLm91dGNvbWUiLCJwdmFsLm91dGNvbWUiLCJyc2lkIiwiTiIpCm91dGNvbWUzJG91dGNvbWUgPC0gcmVwKGMoIlBoZUNvZGUgNTg1LjEgKFZlcm1hKSIpLHRpbWVzPW5yb3cob3V0Y29tZTMpKTsKY2x1bXBfaWQgPC0gInZlcm1hQTIwMjQiOwpvdXRjb21lMyRpZC5vdXRjb21lIDwtIHJlcChjKGNsdW1wX2lkKSx0aW1lcz1ucm93KG91dGNvbWUzKSk7Cm91dGNvbWUzJGJldGEub3V0Y29tZSA8LSBsb2cob3V0Y29tZTMkb2Rkc3JhdGlvLm91dGNvbWUpCgoKZXhwb3N1cmVfc25wcyA8LSByZWFkX2NzdigiZGF0YS9leHBvc3VyZV9BMkdSQ0gzOC5jc3YiKSAKI2ZpbHRlciBvdXRjb21lIG9uIFNOUHMgaW4gdGhlIGV4cG9zdXJlCm91dGNvbWVfY2x1bXBlZCA8LSBmaWx0ZXIob3V0Y29tZTMsIHJzaWQgJWluJSBleHBvc3VyZV9zbnBzJHJzaWQpCiNoYXJtb25pc2UgZGF0YQptcl9kYXQgPC0gaGFybW9uaXNlX2RhdGEoZHBseXI6OnRpYmJsZShTTlA9ZXhwb3N1cmVfc25wcyRyc2lkLCBiZXRhLmV4cG9zdXJlPWV4cG9zdXJlX3NucHMkYmV0YS5leHBvc3VyZSwgc2UuZXhwb3N1cmU9ZXhwb3N1cmVfc25wcyRzZS5leHBvc3VyZSwgZWZmZWN0X2FsbGVsZS5leHBvc3VyZSA9IGV4cG9zdXJlX3NucHMkZWZmZWN0X2FsbGVsZS5leHBvc3VyZSwgb3RoZXJfYWxsZWxlLmV4cG9zdXJlID0gZXhwb3N1cmVfc25wcyRvdGhlcl9hbGxlbGUuZXhwb3N1cmUsZWFmLmV4cG9zdXJlID0gZXhwb3N1cmVfc25wcyRlYWYuZXhwb3N1cmUsIGlkLmV4cG9zdXJlID0gZXhwb3N1cmVfc25wcyRpZC5leHBvc3VyZSwgZXhwb3N1cmUgPSBleHBvc3VyZV9zbnBzJGV4cG9zdXJlKSwgZHBseXI6OnRpYmJsZShTTlA9b3V0Y29tZV9jbHVtcGVkJHJzaWQsIGJldGEub3V0Y29tZT1vdXRjb21lX2NsdW1wZWQkYmV0YS5vdXRjb21lLCBzZS5vdXRjb21lPW91dGNvbWVfY2x1bXBlZCRzZS5vdXRjb21lLCBlZmZlY3RfYWxsZWxlLm91dGNvbWUgPSBvdXRjb21lX2NsdW1wZWQkZWZmZWN0X2FsbGVsZS5vdXRjb21lLCBvdGhlcl9hbGxlbGUub3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRvdGhlcl9hbGxlbGUub3V0Y29tZSxlYWYub3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRlYWYub3V0Y29tZSAsIG91dGNvbWUgPSBvdXRjb21lX2NsdW1wZWQkb3V0Y29tZSwgaWQub3V0Y29tZSA9IG91dGNvbWVfY2x1bXBlZCRpZC5vdXRjb21lKSwgYWN0aW9uID0gMikKd3JpdGVfY3N2KG1yX2RhdCwgImhhcm1vbml6ZWQvaGFybW9uaXplZF9BMl9WZXJtYUEiKQpgYGAKCiMgTVIgQW5hbHlzaXMKCmBgYHtyLGV2YWw9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKSAgICAjIERhdGEgd3JhbmdsaW5nIApsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KFR3b1NhbXBsZU1SKSAgIyBNUiAKbGlicmFyeShndCkKbGlicmFyeShMRGxpbmtSKSAgICAgICMgTEQgYW5kIHByb3h5IHNucHMKbGlicmFyeShSYWRpYWxNUikgICAgICMgUmFkaWFsIE1SIHNlbnNldGl2aXR5IGFuYWx5c2lzIApsaWJyYXJ5KHBoZW5vc2Nhbm5lcikKCmBgYAoKYGBge3J9Cm1yX2RhdCA8LSByZWFkX2NzdigiaGFybW9uaXplZC9oYXJtb25pemVkX0EyX0ppYW5nTCIpCm1yX3BsZWlvdHJvcGh5X3Jlc3VsdCA8LSBtcl9wbGVpb3Ryb3B5X3Rlc3QobXJfZGF0KQpWaWV3KG1yX3BsZWlvdHJvcGh5X3Jlc3VsdCkKbXJfcmVzIDwtIG1yKG1yX2RhdCwgbWV0aG9kX2xpc3QgPSBjKAogICJtcl90d29fc2FtcGxlX21sIiwgICJtcl9lZ2dlcl9yZWdyZXNzaW9uIiwgCiAgIm1yX3NpbXBsZV9tZWRpYW4iLCAibXJfd2VpZ2h0ZWRfbWVkaWFuIiwgCiAgIm1yX2l2d19mZSIsICJtcl9pdndfbXJlIiwKICAibXJfc2ltcGxlX21vZGUiLCAibXJfd2VpZ2h0ZWRfbW9kZSIKICApKQpyZXNfc2luZ2xlIDwtIG1yX3NpbmdsZXNucChtcl9kYXQsIGFsbF9tZXRob2QgPSBjKCJtcl9pdndfZmUiLCAibXJfZWdnZXJfcmVncmVzc2lvbiIsICJtcl93ZWlnaHRlZF9tZWRpYW4iLCAibXJfd2VpZ2h0ZWRfbW9kZSIpKSAlPiUgYXNfdGliYmxlKCkKVmlldyhyZXNfc2luZ2xlKQpvZGQgPC0gZ2VuZXJhdGVfb2Rkc19yYXRpb3MobXJfcmVzKQpwcmludCgiRmluaXNoZWQgQW5hbHl6aW5nIikKd3JpdGUuY3N2KG9kZCwicmVzdWx0cy9BMi9qaWFuZ2xhMl9vZGRzcmF0aW9zLmNzdiIpCndyaXRlLmNzdihyZXNfc2luZ2xlLCJyZXN1bHRzL0EyL2ppYW5nbGEyX3Jlc19zaW5nbGUuY3N2IikKc2NhdHRlcl9wIDwtIG1yX3NjYXR0ZXJfcGxvdChtcl9yZXMsIG1yX2RhdCkgCnNjYXR0ZXJfb3V0X3AgPC0gc2NhdHRlcl9wW1sxXV0gKyB0aGVtZV9idygpICsgCiAgZ3VpZGVzKGNvbG9yPWd1aWRlX2xlZ2VuZChuY29sID0xKSkgKyAKICB0aGVtZSgKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICApCgpzY2F0dGVyX291dF9wCmdnc2F2ZSgicmVzdWx0cy9BMi9zY2F0dGVycGxvdEEySmlhbmdMLnBuZyIsIHBsb3QgPSBzY2F0dGVyX291dF9wLCB1bml0cyA9ICdpbicsIGhlaWdodCA9IDQsIHdpZHRoID0gOSkKZm9ycmVzdF9wIDwtIG1yX2ZvcmVzdF9wbG90KHJlc19zaW5nbGUpCmZvcnJlc3RfcFtbMV1dCmdnc2F2ZSgicmVzdWx0cy9BMi9mb3JyZXN0cGxvdEEySmlhbmdMLnBuZyIsIHBsb3QgPWZvcnJlc3RfcFtbMV1dICsgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpLCB1bml0cyA9ICdpbicsIGhlaWdodCA9IDksIHdpZHRoID0gOSkKCnJlc19sb28gPC0gbXJfbGVhdmVvbmVvdXQobXJfZGF0LCBtZXRob2QgPSBtcl9pdndfZmUpICU+JSBhc190aWJibGUoKQpsb29fcCA8LSBtcl9sZWF2ZW9uZW91dF9wbG90KHJlc19sb28pCmxvb19wW1sxXV0KZ2dzYXZlKCJyZXN1bHRzL0EyL2xvb0EySmlhbmdMLnBuZyIscGxvdCA9IGxvb19wW1sxXV0sIHVuaXRzID0gJ2luJywgaGVpZ2h0ID0gOSwgd2lkdGggPSA5KQoKZnVubmVsX3AgPC0gbXJfZnVubmVsX3Bsb3QocmVzX3NpbmdsZSkKZnVubmVsX291dF9wIDwtIGZ1bm5lbF9wW1sxXV0gKyB0aGVtZV9idygpICsgCiAgZ3VpZGVzKGNvbG9yPWd1aWRlX2xlZ2VuZChuY29sID0xKSkgKyAKICB0aGVtZSgKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICApCgpmdW5uZWxfb3V0X3AKZ2dzYXZlKCJyZXN1bHRzL0EyL2Z1bm5lbHBsb3RBMkppYW5nTC5wbmciLCBwbG90ID0gZnVubmVsX291dF9wLCB1bml0cyA9ICdpbicsIGhlaWdodCA9IDQsIHdpZHRoID0gOSkKCmBgYAoKYGBge3J9Cgptcl9kYXQgPC0gcmVhZF9jc3YoImhhcm1vbml6ZWQvaGFybW9uaXplZF9BMl9Eb3V2aWxsZSIpCm1yX3JlcyA8LSBtcihtcl9kYXQsIG1ldGhvZF9saXN0ID0gYygKICAibXJfdHdvX3NhbXBsZV9tbCIsICAibXJfZWdnZXJfcmVncmVzc2lvbiIsIAogICJtcl9zaW1wbGVfbWVkaWFuIiwgIm1yX3dlaWdodGVkX21lZGlhbiIsIAogICJtcl9pdndfZmUiLCAibXJfaXZ3X21yZSIsCiAgIm1yX3NpbXBsZV9tb2RlIiwgIm1yX3dlaWdodGVkX21vZGUiCiAgKSkKcmVzX3NpbmdsZSA8LSBtcl9zaW5nbGVzbnAobXJfZGF0LCBhbGxfbWV0aG9kID0gYygibXJfaXZ3X2ZlIiwgIm1yX2VnZ2VyX3JlZ3Jlc3Npb24iLCAibXJfd2VpZ2h0ZWRfbWVkaWFuIiwgIm1yX3dlaWdodGVkX21vZGUiKSkgJT4lIGFzX3RpYmJsZSgpClZpZXcocmVzX3NpbmdsZSkKb2RkIDwtIGdlbmVyYXRlX29kZHNfcmF0aW9zKG1yX3JlcykKcHJpbnQoIkZpbmlzaGVkIEFuYWx5emluZyIpCndyaXRlLmNzdihvZGQsInJlc3VsdHMvQTIvZG91dmlsbGVhMl9vZGRzcmF0aW9zLmNzdiIpCndyaXRlLmNzdihyZXNfc2luZ2xlLCJyZXN1bHRzL0EyL2RvdXZpbGxlYTJfcmVzX3NpbmdsZS5jc3YiKQoKc2NhdHRlcl9wIDwtIG1yX3NjYXR0ZXJfcGxvdChtcl9yZXMsIG1yX2RhdCkgCnNjYXR0ZXJfb3V0X3AgPC0gc2NhdHRlcl9wW1sxXV0gKyB0aGVtZV9idygpICsgCiAgZ3VpZGVzKGNvbG9yPWd1aWRlX2xlZ2VuZChuY29sID0xKSkgKyAKICB0aGVtZSgKICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpLCAKICApCgpzY2F0dGVyX291dF9wCmdnc2F2ZSgicmVzdWx0cy9BMi9zY2F0dGVycGxvdEEyRG91dmlsbGUucG5nIiwgcGxvdCA9IHNjYXR0ZXJfb3V0X3AsIHVuaXRzID0gJ2luJywgaGVpZ2h0ID0gNCwgd2lkdGggPSA5KQpmb3JyZXN0X3AgPC0gbXJfZm9yZXN0X3Bsb3QocmVzX3NpbmdsZSkKZm9ycmVzdF9wW1sxXV0KZ2dzYXZlKCJyZXN1bHRzL0EyL2ZvcnJlc3RwbG90QTJEb3V2aWxsZS5wbmciLCBwbG90ID1mb3JyZXN0X3BbWzFdXSArIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSwgdW5pdHMgPSAnaW4nLCBoZWlnaHQgPSA5LCB3aWR0aCA9IDkpCgpyZXNfbG9vIDwtIG1yX2xlYXZlb25lb3V0KG1yX2RhdCwgbWV0aG9kID0gbXJfaXZ3X2ZlKSAlPiUgYXNfdGliYmxlKCkKbG9vX3AgPC0gbXJfbGVhdmVvbmVvdXRfcGxvdChyZXNfbG9vKQpsb29fcFtbMV1dCmdnc2F2ZSgicmVzdWx0cy9BMi9sb29BMkRvdXZpbGxlLnBuZyIscGxvdCA9IGxvb19wW1sxXV0sIHVuaXRzID0gJ2luJywgaGVpZ2h0ID0gOSwgd2lkdGggPSA5KQoKYGBgCgpgYGB7cn0KCgpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkgICAgIyBEYXRhIHdyYW5nbGluZyAKbGlicmFyeShUd29TYW1wbGVNUikgICMgTVIgCmxpYnJhcnkoZ2dtYW4pCnRjX3BhdGggPSAiZ3dhc19yZXNvdXJjZXMvRG91dmlsbGVOSk1vZGVsMWgudHN2Lmd6Igp0Y19zcyA8LSByZWFkX3Rzdih0Y19wYXRoKQoKIyBGaWx0ZXIgb24gcCA8IDAuNSB0byByZWR1Y2UgY29tcHV0ZQpnZ21hbihmaWx0ZXIodGNfc3MsIHBfdmFsdWUgPCAwLjA1ICYgcF92YWx1ZSA+IDFlLTEwMCksIHNucCA9ICJTTlBJRCIsIGJwID0gImJhc2VfcGFpcl9sb2NhdGlvbiIsIGNocm9tID0gImNocm9tb3NvbWUiLCBwdmFsdWUgPSAicF92YWx1ZSIsIHJlbGF0aXZlLnBvc2l0aW9ucyA9IFRSVUUpICsgCiAgdGhlbWVfY2xhc3NpYygpCmBgYAo=