Patient Demographics
deceased <- "Deceased/Hospice"
home <- "Home"
transfer <- "Transferred"
dispos <- list("Deceased" = deceased,
"Expired/Donor" = deceased,
"Hospice-Home" = deceased,
"Hospice-Medical Facility" = deceased,
"Home Care with Home Health" = home,
"Home or Self Care" = home,
"Left Against Medical Advise" = home,
"Skilled Nursing Facility" = transfer,
"DC/DISC TO REHAB" = transfer,
"Long Term Care" = transfer,
"Intermediate Care" = transfer,
"Acute Care" = transfer,
"Federal Healthcare Facility" = transfer,
"DC/TF To Psych Hosp" = transfer)
df <- data_demographics %>%
dmap_at("disposition", str_replace_all, pattern = dispos) %>%
dmap_at("race", factor) %>%
dmap_at("race", fct_lump, n = 4) %>%
select(-pie.id, Age = age, Sex = sex, Race = race, Disposition = disposition, `Hospital Length of Stay (days)` = length.stay, `ICU Location` = location)
vars <- names(df)
tbl <- CreateTableOne(vars, data = df)
ptbl <- print(tbl, printToggle = FALSE)
rownames(ptbl) <- str_replace_all(rownames(ptbl), " ", "- ")
knitr::kable(ptbl, caption = "Demographics")
| n |
200 |
| Age (mean (sd)) |
60.68 (16.54) |
| Sex = Male (%) |
123 (61.5) |
| Race (%) |
|
| - African American |
49 (28.0) |
| - Asian |
8 ( 4.6) |
| - White/Caucasian |
73 (41.7) |
| - Other |
45 (25.7) |
| Disposition (%) |
|
| - Deceased/Hospice |
37 (18.5) |
| - Home |
109 (54.5) |
| - Transferred |
54 (27.0) |
| Hospital Length of Stay (days) (mean (sd)) |
12.07 (12.04) |
| ICU Location (%) |
|
| - Cullen 2 E Medical Intensive Care Unit |
60 (30.0) |
| - Hermann 3 Shock Trauma Intensive Care Unit |
14 ( 7.0) |
| - Hermann 3 Transplant Surgical ICU |
19 ( 9.5) |
| - HVI Cardiac Care Unit |
20 (10.0) |
| - HVI Cardiovascular Intensive Care Unit |
34 (17.0) |
| - Jones 7 J Elective Neuro ICU |
53 (26.5) |
Primary endpoint
APACHE II
- Mean and median score for each comorbidity set
scores <- ls(pattern = "score_apache2")
all_scores <- map(scores, ~mutate(get(.x), score = .x)) %>%
map(~select(.x, pie.id, score, apache2)) %>%
map_df(~semi_join(.x, manual_patients, by = "pie.id")) %>%
arrange(pie.id, score) %>%
dmap_at("score", str_replace_all, pattern = "score_apache2_", replacement = "")
man <- filter(all_scores, score == "manual")$apache2
result <- all_scores %>%
select(-pie.id) %>%
group_by(score) %>%
summarize_all(funs(mean, sd, median, IQR_low = quantile(., 0.25), IQR_high = quantile(., 0.75)))
knitr::kable(result)
| ahrq |
20.20 |
6.858220 |
20 |
15 |
24.00 |
| ahrq_drg |
19.79 |
6.832225 |
19 |
15 |
24.00 |
| ek |
20.05 |
6.909865 |
20 |
15 |
24.00 |
| ek_drg |
19.65 |
6.866824 |
19 |
15 |
24.00 |
| elixhauser |
20.18 |
6.927304 |
20 |
15 |
24.00 |
| elixhauser_drg |
19.77 |
6.900375 |
19 |
15 |
24.00 |
| manual |
19.87 |
7.020651 |
19 |
15 |
24.25 |
| quan |
20.18 |
6.927304 |
20 |
15 |
24.00 |
| quan_drg |
19.78 |
6.891959 |
19 |
15 |
24.00 |
ggplot(all_scores, aes(x = score, y = apache2)) +
geom_boxplot()

# geom_jitter(color = "light blue", alpha = 0.6)
ggplot(all_scores, aes(x = apache2)) +
geom_histogram(binwidth = 0.5) +
facet_wrap(~ score)

df <- all_scores %>%
spread(score, apache2) %>%
gather(score, apache2, -pie.id, -manual)
# ggplot(df, aes(x = apache2, y = manual)) +
# geom_jitter(aes(color = score), alpha = 0.6)
ggplot(df, aes(x = apache2, y = manual)) +
geom_point() +
# geom_smooth() +
facet_wrap(~ score)

- Comparison of scores
- Results run using both the t-test and Wilcoxon signed rank test (assumes non-parametric data, is more difficult to achieve significance)
- To account for performing multiple comparisons, a BH (Benjamini and Hochberg) correction is applied to the p-values; use the bh.adjust value as the p-value
t <- all_scores[, -1] %>%
filter(score != "manual") %>%
group_by(score) %>%
do(tidy(t.test(.$apache2, man, paired = TRUE))) %>%
ungroup() %>%
mutate(bh.adjust = p.adjust(p.value, "BH")) %>%
select(score:p.value, bh.adjust, everything())
knitr::kable(t, digits = 4)
| ahrq |
0.33 |
2.0591 |
0.0408 |
0.1306 |
199 |
0.0140 |
0.6460 |
Paired t-test |
two.sided |
| ahrq_drg |
-0.08 |
-0.4981 |
0.6190 |
0.6190 |
199 |
-0.3967 |
0.2367 |
Paired t-test |
two.sided |
| ek |
0.18 |
1.1170 |
0.2653 |
0.4245 |
199 |
-0.1378 |
0.4978 |
Paired t-test |
two.sided |
| ek_drg |
-0.22 |
-1.3754 |
0.1706 |
0.3411 |
199 |
-0.5354 |
0.0954 |
Paired t-test |
two.sided |
| elixhauser |
0.31 |
1.9808 |
0.0490 |
0.1306 |
199 |
0.0014 |
0.6186 |
Paired t-test |
two.sided |
| elixhauser_drg |
-0.10 |
-0.6386 |
0.5238 |
0.6190 |
199 |
-0.4088 |
0.2088 |
Paired t-test |
two.sided |
| quan |
0.31 |
1.9808 |
0.0490 |
0.1306 |
199 |
0.0014 |
0.6186 |
Paired t-test |
two.sided |
| quan_drg |
-0.09 |
-0.5734 |
0.5670 |
0.6190 |
199 |
-0.3995 |
0.2195 |
Paired t-test |
two.sided |
mw <- all_scores[, -1] %>%
filter(score != "manual") %>%
group_by(score) %>%
do(tidy(wilcox.test(.$apache2, man, paired = TRUE, conf.int = TRUE, exact = FALSE))) %>%
ungroup() %>%
mutate(bh.adjust = p.adjust(p.value, "BH")) %>%
select(score:p.value, bh.adjust, everything())
knitr::kable(mw, digits = 4)
| ahrq |
1.5 |
1644.0 |
0.0563 |
0.1676 |
-0.0001 |
2.0000 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ahrq_drg |
0.0 |
1070.0 |
0.5179 |
0.5179 |
-1.5000 |
0.0000 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ek |
0.0 |
1448.5 |
0.3147 |
0.5036 |
-0.0001 |
2.0000 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ek_drg |
0.0 |
936.0 |
0.1357 |
0.2715 |
-1.5000 |
0.0000 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| elixhauser |
1.5 |
1551.0 |
0.0628 |
0.1676 |
-0.0001 |
1.9999 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| elixhauser_drg |
0.0 |
990.0 |
0.4483 |
0.5179 |
-1.5000 |
0.0001 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| quan |
1.5 |
1551.0 |
0.0628 |
0.1676 |
-0.0001 |
1.9999 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| quan_drg |
0.0 |
1030.5 |
0.4863 |
0.5179 |
-1.5000 |
0.0000 |
Wilcoxon signed rank test with continuity correction |
two.sided |
options(scipen = 999)
mw_pair <- all_scores %>%
dmap_at("score", factor) %>%
dmap_at("score", ~fct_relevel(.x, c("manual", "ek", "ek_drg"))) %>%
do(tidy(pairwise.wilcox.test(.$apache2, .$score, p.adj = "BH", paired = TRUE, exact = FALSE)))
Linear Regression Model
lm <- df %>%
group_by(score) %>%
do(fit = lm(manual ~ apache2, data = .))
knitr::kable(glance(lm, fit), digits = 4)
| ahrq |
0.8967 |
0.8962 |
2.2624 |
1718.366 |
0 |
2 |
-446.0658 |
898.1315 |
908.0265 |
1013.4322 |
198 |
| ahrq_drg |
0.8960 |
0.8955 |
2.2695 |
1706.410 |
0 |
2 |
-446.6916 |
899.3832 |
909.2782 |
1019.7944 |
198 |
| ek |
0.8960 |
0.8955 |
2.2693 |
1706.705 |
0 |
2 |
-446.6761 |
899.3522 |
909.2472 |
1019.6365 |
198 |
| ek_drg |
0.8971 |
0.8966 |
2.2574 |
1726.889 |
0 |
2 |
-445.6220 |
897.2440 |
907.1390 |
1008.9449 |
198 |
| elixhauser |
0.9020 |
0.9015 |
2.2035 |
1822.143 |
0 |
2 |
-440.7920 |
887.5840 |
897.4790 |
961.3710 |
198 |
| elixhauser_drg |
0.9016 |
0.9011 |
2.2078 |
1814.341 |
0 |
2 |
-441.1790 |
888.3579 |
898.2529 |
965.0983 |
198 |
| quan |
0.9020 |
0.9015 |
2.2035 |
1822.143 |
0 |
2 |
-440.7920 |
887.5840 |
897.4790 |
961.3710 |
198 |
| quan_drg |
0.9011 |
0.9006 |
2.2135 |
1804.009 |
0 |
2 |
-441.6937 |
889.3874 |
899.2824 |
970.0789 |
198 |
augment(lm, fit) %>%
ggplot(aes(x = .fitted, y = .resid)) +
geom_point() +
# geom_smooth(se = FALSE) +
facet_wrap(~ score)

mod_df <- df %>%
filter(score == "ek_drg")
mod <- lm(manual ~ apache2, data = mod_df)
par(mfrow = c(2, 2))
plot(mod)

- Compare differences in score from comorbidity sets vs. manual
- Column num_diff indicates the number of patients with a score that differed from manual
- Mean and median indicate the difference from the manual score
- These were only calculated for those patients whose score was different from manual
- If all patients were included, the number is skewed towards 0 by all the patients with the same scores
diff <- all_scores %>%
spread(score, apache2) %>%
mutate_at(vars(-pie.id, -manual), funs(abs(. - manual))) %>%
gather(score, apache2, -pie.id, -manual) %>%
select(-pie.id, -manual) %>%
filter(apache2 > 0) %>%
group_by(score) %>%
summarize_all(funs(num_diff = length, mean, sd, median, IQR_low = quantile(., 0.25), IQR_high = quantile(., 0.75)))
knitr::kable(diff, caption = "Differences in APACHE II Scores")
| ahrq |
72 |
3.500000 |
1.510526 |
3.5 |
2 |
5 |
| ahrq_drg |
68 |
3.588235 |
1.508536 |
5.0 |
2 |
5 |
| ek |
71 |
3.521127 |
1.510526 |
5.0 |
2 |
5 |
| ek_drg |
68 |
3.588235 |
1.508536 |
5.0 |
2 |
5 |
| elixhauser |
70 |
3.457143 |
1.510214 |
2.0 |
2 |
5 |
| elixhauser_drg |
66 |
3.545454 |
1.510800 |
5.0 |
2 |
5 |
| quan |
70 |
3.457143 |
1.510214 |
2.0 |
2 |
5 |
| quan_drg |
67 |
3.522388 |
1.511153 |
5.0 |
2 |
5 |
APACHE III
scores <- ls(pattern = "score_apache3")
all_scores <- map(scores, ~mutate(get(.x), score = .x)) %>%
map(~select(.x, pie.id, score, apache3)) %>%
map_df(~semi_join(.x, manual_patients, by = "pie.id")) %>%
arrange(pie.id, score) %>%
dmap_at("score", str_replace_all, pattern = "score_apache3_", replacement = "")
man <- filter(all_scores, score == "manual")$apache3
result <- all_scores %>%
select(-pie.id) %>%
group_by(score) %>%
summarize_all(funs(mean, sd, median, IQR_low = quantile(., 0.25), IQR_high = quantile(., 0.75)))
knitr::kable(result)
| ahrq |
85.715 |
29.29976 |
82.0 |
65.75 |
103.25 |
| ahrq_drg |
85.555 |
29.25932 |
82.0 |
65.00 |
103.25 |
| ek |
85.715 |
29.29976 |
82.0 |
65.75 |
103.25 |
| ek_drg |
85.555 |
29.25932 |
82.0 |
65.00 |
103.25 |
| elixhauser |
85.715 |
29.29976 |
82.0 |
65.75 |
103.25 |
| elixhauser_drg |
85.555 |
29.25932 |
82.0 |
65.00 |
103.25 |
| manual |
84.805 |
28.99847 |
81.5 |
63.75 |
103.00 |
| quan |
85.715 |
29.29976 |
82.0 |
65.75 |
103.25 |
| quan_drg |
85.555 |
29.25932 |
82.0 |
65.00 |
103.25 |
ggplot(all_scores, aes(x = score, y = apache3)) +
geom_boxplot()

df <- all_scores %>%
spread(score, apache3) %>%
gather(score, apache3, -pie.id, -manual)
ggplot(df, aes(x = apache3, y = manual)) +
geom_point() +
# geom_smooth() +
facet_wrap(~ score)

t <- all_scores[, -1] %>%
filter(score != "manual") %>%
group_by(score) %>%
do(tidy(t.test(.$apache3, man, paired = TRUE))) %>%
ungroup() %>%
mutate(bh.adjust = p.adjust(p.value, "BH")) %>%
select(score:p.value, bh.adjust, everything())
knitr::kable(t, digits = 4)
| ahrq |
0.91 |
2.9503 |
0.0036 |
0.0071 |
199 |
0.3018 |
1.5182 |
Paired t-test |
two.sided |
| ahrq_drg |
0.75 |
2.5453 |
0.0117 |
0.0117 |
199 |
0.1690 |
1.3310 |
Paired t-test |
two.sided |
| ek |
0.91 |
2.9503 |
0.0036 |
0.0071 |
199 |
0.3018 |
1.5182 |
Paired t-test |
two.sided |
| ek_drg |
0.75 |
2.5453 |
0.0117 |
0.0117 |
199 |
0.1690 |
1.3310 |
Paired t-test |
two.sided |
| elixhauser |
0.91 |
2.9503 |
0.0036 |
0.0071 |
199 |
0.3018 |
1.5182 |
Paired t-test |
two.sided |
| elixhauser_drg |
0.75 |
2.5453 |
0.0117 |
0.0117 |
199 |
0.1690 |
1.3310 |
Paired t-test |
two.sided |
| quan |
0.91 |
2.9503 |
0.0036 |
0.0071 |
199 |
0.3018 |
1.5182 |
Paired t-test |
two.sided |
| quan_drg |
0.75 |
2.5453 |
0.0117 |
0.0117 |
199 |
0.1690 |
1.3310 |
Paired t-test |
two.sided |
mw <- all_scores[, -1] %>%
filter(score != "manual") %>%
group_by(score) %>%
do(tidy(wilcox.test(.$apache3, man, paired = TRUE, conf.int = TRUE, exact = FALSE))) %>%
ungroup() %>%
mutate(bh.adjust = p.adjust(p.value, "BH")) %>%
select(score:p.value, bh.adjust, everything())
knitr::kable(mw, digits = 4)
| ahrq |
9.0000 |
283.5 |
0.0062 |
0.0123 |
2.9999 |
13.0 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ahrq_drg |
7.0001 |
251.0 |
0.0176 |
0.0176 |
1.5000 |
11.5 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ek |
9.0000 |
283.5 |
0.0062 |
0.0123 |
2.9999 |
13.0 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ek_drg |
7.0001 |
251.0 |
0.0176 |
0.0176 |
1.5000 |
11.5 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| elixhauser |
9.0000 |
283.5 |
0.0062 |
0.0123 |
2.9999 |
13.0 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| elixhauser_drg |
7.0001 |
251.0 |
0.0176 |
0.0176 |
1.5000 |
11.5 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| quan |
9.0000 |
283.5 |
0.0062 |
0.0123 |
2.9999 |
13.0 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| quan_drg |
7.0001 |
251.0 |
0.0176 |
0.0176 |
1.5000 |
11.5 |
Wilcoxon signed rank test with continuity correction |
two.sided |
Linear Regression Model
lm <- df %>%
group_by(score) %>%
do(fit = lm(manual ~ apache3, data = .))
knitr::kable(glance(lm, fit), digits = 4)
| ahrq |
0.9778 |
0.9777 |
4.3280 |
8735.812 |
0 |
2 |
-575.8020 |
1157.604 |
1167.499 |
3708.786 |
198 |
| ahrq_drg |
0.9797 |
0.9796 |
4.1402 |
9564.716 |
0 |
2 |
-566.9292 |
1139.858 |
1149.753 |
3393.891 |
198 |
| ek |
0.9778 |
0.9777 |
4.3280 |
8735.812 |
0 |
2 |
-575.8020 |
1157.604 |
1167.499 |
3708.786 |
198 |
| ek_drg |
0.9797 |
0.9796 |
4.1402 |
9564.716 |
0 |
2 |
-566.9292 |
1139.858 |
1149.753 |
3393.891 |
198 |
| elixhauser |
0.9778 |
0.9777 |
4.3280 |
8735.812 |
0 |
2 |
-575.8020 |
1157.604 |
1167.499 |
3708.786 |
198 |
| elixhauser_drg |
0.9797 |
0.9796 |
4.1402 |
9564.716 |
0 |
2 |
-566.9292 |
1139.858 |
1149.753 |
3393.891 |
198 |
| quan |
0.9778 |
0.9777 |
4.3280 |
8735.812 |
0 |
2 |
-575.8020 |
1157.604 |
1167.499 |
3708.786 |
198 |
| quan_drg |
0.9797 |
0.9796 |
4.1402 |
9564.716 |
0 |
2 |
-566.9292 |
1139.858 |
1149.753 |
3393.891 |
198 |
augment(lm, fit) %>%
ggplot(aes(x = .fitted, y = .resid)) +
geom_point() +
facet_wrap(~ score)

diff <- all_scores %>%
spread(score, apache3) %>%
mutate_at(vars(-pie.id, -manual), funs(abs(. - manual))) %>%
gather(score, apache3, -pie.id, -manual) %>%
select(-pie.id, -manual) %>%
filter(apache3 > 0) %>%
group_by(score) %>%
summarize_all(funs(num_diff = length, mean, sd, median, IQR_low = quantile(., 0.25), IQR_high = quantile(., 0.75)))
knitr::kable(diff, caption = "Difference in APACHE III Scores")
| ahrq |
26 |
11.38462 |
4.825573 |
12 |
10 |
16 |
| ahrq_drg |
25 |
10.88000 |
5.035871 |
12 |
6 |
16 |
| ek |
26 |
11.38462 |
4.825573 |
12 |
10 |
16 |
| ek_drg |
25 |
10.88000 |
5.035871 |
12 |
6 |
16 |
| elixhauser |
26 |
11.38462 |
4.825573 |
12 |
10 |
16 |
| elixhauser_drg |
25 |
10.88000 |
5.035871 |
12 |
6 |
16 |
| quan |
26 |
11.38462 |
4.825573 |
12 |
10 |
16 |
| quan_drg |
25 |
10.88000 |
5.035871 |
12 |
6 |
16 |
SAPS II
scores <- ls(pattern = "score_saps2")
all_scores <- map(scores, ~mutate(get(.x), score = .x)) %>%
map(~select(.x, pie.id, score, saps2)) %>%
map_df(~semi_join(.x, manual_patients, by = "pie.id")) %>%
arrange(pie.id, score) %>%
dmap_at("score", str_replace_all, pattern = "score_saps2_", replacement = "")
man <- filter(all_scores, score == "manual")$saps2
result <- all_scores %>%
select(-pie.id) %>%
group_by(score) %>%
summarize_all(funs(mean, sd, median, IQR_low = quantile(., 0.25), IQR_high = quantile(., 0.75)))
knitr::kable(result)
| ahrq |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| ahrq_drg |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| ek |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| ek_drg |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| elixhauser |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| elixhauser_drg |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| manual |
36.94 |
14.44888 |
34.5 |
26 |
46.25 |
| quan |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
| quan_drg |
37.12 |
14.56386 |
36.0 |
26 |
47.00 |
ggplot(all_scores, aes(x = score, y = saps2)) +
geom_boxplot()

df <- all_scores %>%
spread(score, saps2) %>%
gather(score, saps2, -pie.id, -manual)
ggplot(df, aes(x = saps2, y = manual)) +
geom_point() +
# geom_smooth() +
facet_wrap(~ score)

t <- all_scores[, -1] %>%
filter(score != "manual") %>%
group_by(score) %>%
do(tidy(t.test(.$saps2, man, paired = TRUE))) %>%
ungroup() %>%
mutate(bh.adjust = p.adjust(p.value, "BH")) %>%
select(score:p.value, bh.adjust, everything())
knitr::kable(t, digits = 4)
| ahrq |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| ahrq_drg |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| ek |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| ek_drg |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| elixhauser |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| elixhauser_drg |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| quan |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
| quan_drg |
0.18 |
1.3406 |
0.1816 |
0.1816 |
199 |
-0.0848 |
0.4448 |
Paired t-test |
two.sided |
- Confidence interval was unable to be calculated for Wilcoxon analysis here
mw <- all_scores[, -1] %>%
filter(score != "manual") %>%
group_by(score) %>%
do(tidy(wilcox.test(.$saps2, man, paired = TRUE, exact = FALSE))) %>%
ungroup() %>%
mutate(bh.adjust = p.adjust(p.value, "BH")) %>%
select(score:p.value, bh.adjust, everything())
knitr::kable(mw, digits = 4)
| ahrq |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ahrq_drg |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ek |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| ek_drg |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| elixhauser |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| elixhauser_drg |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| quan |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
| quan_drg |
23 |
0.5182 |
0.5182 |
Wilcoxon signed rank test with continuity correction |
two.sided |
Linear Regression Model
lm <- df %>%
group_by(score) %>%
do(fit = lm(manual ~ saps2, data = .))
knitr::kable(glance(lm, fit), digits = 4)
| ahrq |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| ahrq_drg |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| ek |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| ek_drg |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| elixhauser |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| elixhauser_drg |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| quan |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
| quan_drg |
0.983 |
0.9829 |
1.8886 |
11449.91 |
0 |
2 |
-409.9484 |
825.8968 |
835.7917 |
706.2182 |
198 |
augment(lm, fit) %>%
ggplot(aes(x = .fitted, y = .resid)) +
geom_point() +
facet_wrap(~ score)

diff <- all_scores %>%
spread(score, saps2) %>%
mutate_at(vars(-pie.id, -manual), funs(abs(. - manual))) %>%
gather(score, saps2, -pie.id, -manual) %>%
select(-pie.id, -manual) %>%
filter(saps2 > 0) %>%
group_by(score) %>%
summarize_all(funs(num_diff = length, mean, sd, median, IQR_low = quantile(., 0.25), IQR_high = quantile(., 0.75)))
knitr::kable(diff, caption = "Difference in SAPS II Scores")
| ahrq |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| ahrq_drg |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| ek |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| ek_drg |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| elixhauser |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| elixhauser_drg |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| quan |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
| quan_drg |
8 |
9.5 |
0.5345225 |
9.5 |
9 |
10 |
LS0tDQp0aXRsZTogVmFsaWRhdGlvbiBvZiBJQ0QtOS1DTS9JQ0QtMTAtQ00gQ29kZXMgZm9yIEF1dG9tYXRlZCBFbGVjdHJvbmljIFNjb3Jpbmcgb2YNCiAgQVBBQ0hFIElJLCBBUEFDSEUgSUlJLCBhbmQgU0FQUyBJSQ0Kc3VidGl0bGU6IEFuYWx5c2lzIGZvciBBU0hQIFBvc3Rlcg0KYXV0aG9yOiBFcmljIEthbywgQnJpYW4gR3VsYmlzDQpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCksICIlQiAlZCwgJVkiKWAnDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KGZvcmNhdHMpDQpsaWJyYXJ5KHRhYmxlb25lKQ0KbGlicmFyeShicm9vbSkNCg0KZGlycjo6Z2V0X3JkcygiLi4vZGF0YS9maW5hbCIpDQpgYGANCg0KIyMgUGF0aWVudCBTZWxlY3Rpb24NCg0KKiBQYXRpZW50cyBtZWV0aW5nIGluY2x1c2lvbiBjcml0ZXJpYTogYHIgZXhjbHVkZSRzY3JlZW5gDQoqIFJlYXNvbnMgZm9yIGV4Y2x1c2lvbjoNCiAgICAtIFByZWduYW50OiBgciBleGNsdWRlJHByZWduYW50YA0KICAgIC0gUHJpc29uZXI6IGByIGV4Y2x1ZGUkcHJpc29uZXJzYA0KICAgIC0gSUNVIHN0YXkgPCAxMiBob3VyczogYHIgZXhjbHVkZSRpY3Vfc2hvcnRgDQogICAgLSBEaWFnbm9zaXMgY29kaW5nIGNvbnRhaW5lZCBib3RoIElDRC05LUNNIGFuZCBJQ0QtMTAtQ006IGByIGV4Y2x1ZGUkbXVsdF9pY2RfdHlwZXNgDQogICAgLSBNaXNzaW5nIGRhdGEgbmVlZGVkIHRvIGNhbGN1bGF0ZSByaXNrIHNjb3JlczogYHIgZXhjbHVkZSRsYWJzX21pc3NpbmdgDQogICAgLSBSZS1lbmNvdW50ZXJzIChvbmx5IGluY2x1ZGVkIGVhY2ggcGF0aWVudCBvbmNlKSA6IGByIGV4Y2x1ZGUkcmVlbmNvdW50ZXJgDQoqIFRvdGFsIG51bWJlciBvZiBlbGlnaWJsZSBwYXRpZW50cyByZW1haW5pbmcgdG8gc2FtcGxlIGZyb206IGByIGZsYXR0ZW5faW50KGV4Y2x1ZGUpWzFdIC0gc3VtKGZsYXR0ZW5faW50KGV4Y2x1ZGUpWy0xXSlgDQoNCiMjIFBhdGllbnQgRGVtb2dyYXBoaWNzDQoNCmBgYHtyfQ0KZGVjZWFzZWQgPC0gIkRlY2Vhc2VkL0hvc3BpY2UiDQpob21lIDwtICJIb21lIg0KdHJhbnNmZXIgPC0gIlRyYW5zZmVycmVkIg0KDQpkaXNwb3MgPC0gbGlzdCgiRGVjZWFzZWQiID0gZGVjZWFzZWQsDQogICAgICAgICAgICAgICAiRXhwaXJlZC9Eb25vciIgPSBkZWNlYXNlZCwgDQogICAgICAgICAgICAgICAiSG9zcGljZS1Ib21lIiA9IGRlY2Vhc2VkLCANCiAgICAgICAgICAgICAgICJIb3NwaWNlLU1lZGljYWwgRmFjaWxpdHkiID0gZGVjZWFzZWQsDQogICAgICAgICAgICAgICAiSG9tZSBDYXJlIHdpdGggSG9tZSBIZWFsdGgiID0gaG9tZSwNCiAgICAgICAgICAgICAgICJIb21lIG9yIFNlbGYgQ2FyZSIgPSBob21lLA0KICAgICAgICAgICAgICAgIkxlZnQgQWdhaW5zdCBNZWRpY2FsIEFkdmlzZSIgPSBob21lLA0KICAgICAgICAgICAgICAgIlNraWxsZWQgTnVyc2luZyBGYWNpbGl0eSIgPSB0cmFuc2ZlciwNCiAgICAgICAgICAgICAgICJEQy9ESVNDIFRPIFJFSEFCIiA9IHRyYW5zZmVyLA0KICAgICAgICAgICAgICAgIkxvbmcgVGVybSBDYXJlIiA9IHRyYW5zZmVyLA0KICAgICAgICAgICAgICAgIkludGVybWVkaWF0ZSBDYXJlIiA9IHRyYW5zZmVyLA0KICAgICAgICAgICAgICAgIkFjdXRlIENhcmUiID0gdHJhbnNmZXIsDQogICAgICAgICAgICAgICAiRmVkZXJhbCBIZWFsdGhjYXJlIEZhY2lsaXR5IiA9IHRyYW5zZmVyLA0KICAgICAgICAgICAgICAgIkRDL1RGIFRvIFBzeWNoIEhvc3AiID0gdHJhbnNmZXIpDQoNCmRmIDwtIGRhdGFfZGVtb2dyYXBoaWNzICU+JQ0KICAgIGRtYXBfYXQoImRpc3Bvc2l0aW9uIiwgc3RyX3JlcGxhY2VfYWxsLCBwYXR0ZXJuID0gZGlzcG9zKSAlPiUNCiAgICBkbWFwX2F0KCJyYWNlIiwgZmFjdG9yKSAlPiUNCiAgICBkbWFwX2F0KCJyYWNlIiwgZmN0X2x1bXAsIG4gPSA0KSAlPiUNCiAgICBzZWxlY3QoLXBpZS5pZCwgQWdlID0gYWdlLCBTZXggPSBzZXgsIFJhY2UgPSByYWNlLCBEaXNwb3NpdGlvbiA9IGRpc3Bvc2l0aW9uLCBgSG9zcGl0YWwgTGVuZ3RoIG9mIFN0YXkgKGRheXMpYCA9IGxlbmd0aC5zdGF5LCBgSUNVIExvY2F0aW9uYCA9IGxvY2F0aW9uKSANCg0KdmFycyA8LSBuYW1lcyhkZikNCnRibCA8LSBDcmVhdGVUYWJsZU9uZSh2YXJzLCBkYXRhID0gZGYpDQpwdGJsIDwtIHByaW50KHRibCwgcHJpbnRUb2dnbGUgPSBGQUxTRSkNCnJvd25hbWVzKHB0YmwpIDwtIHN0cl9yZXBsYWNlX2FsbChyb3duYW1lcyhwdGJsKSwgIiAgICIsICItICIpDQprbml0cjo6a2FibGUocHRibCwgY2FwdGlvbiA9ICJEZW1vZ3JhcGhpY3MiKQ0KYGBgDQoNCg0KIyMgUHJpbWFyeSBlbmRwb2ludA0KDQojIyMgQVBBQ0hFIElJDQoNCiogTWVhbiBhbmQgbWVkaWFuIHNjb3JlIGZvciBlYWNoIGNvbW9yYmlkaXR5IHNldA0KDQpgYGB7cn0NCnNjb3JlcyA8LSBscyhwYXR0ZXJuID0gInNjb3JlX2FwYWNoZTIiKQ0KDQphbGxfc2NvcmVzIDwtIG1hcChzY29yZXMsIH5tdXRhdGUoZ2V0KC54KSwgc2NvcmUgPSAueCkpICU+JQ0KICAgIG1hcCh+c2VsZWN0KC54LCBwaWUuaWQsIHNjb3JlLCBhcGFjaGUyKSkgJT4lDQogICAgbWFwX2RmKH5zZW1pX2pvaW4oLngsIG1hbnVhbF9wYXRpZW50cywgYnkgPSAicGllLmlkIikpICU+JQ0KICAgIGFycmFuZ2UocGllLmlkLCBzY29yZSkgJT4lDQogICAgZG1hcF9hdCgic2NvcmUiLCBzdHJfcmVwbGFjZV9hbGwsIHBhdHRlcm4gPSAic2NvcmVfYXBhY2hlMl8iLCByZXBsYWNlbWVudCA9ICIiKSANCg0KbWFuIDwtIGZpbHRlcihhbGxfc2NvcmVzLCBzY29yZSA9PSAibWFudWFsIikkYXBhY2hlMg0KDQpyZXN1bHQgPC0gYWxsX3Njb3JlcyAlPiUNCiAgICBzZWxlY3QoLXBpZS5pZCkgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIHN1bW1hcml6ZV9hbGwoZnVucyhtZWFuLCBzZCwgbWVkaWFuLCBJUVJfbG93ID0gcXVhbnRpbGUoLiwgMC4yNSksIElRUl9oaWdoID0gcXVhbnRpbGUoLiwgMC43NSkpKQ0KDQprbml0cjo6a2FibGUocmVzdWx0KQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGFsbF9zY29yZXMsIGFlcyh4ID0gc2NvcmUsIHkgPSBhcGFjaGUyKSkgKw0KICAgIGdlb21fYm94cGxvdCgpIA0KICAgICMgZ2VvbV9qaXR0ZXIoY29sb3IgPSAibGlnaHQgYmx1ZSIsIGFscGhhID0gMC42KQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGFsbF9zY29yZXMsIGFlcyh4ID0gYXBhY2hlMikpICsNCiAgICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSkgKw0KICAgIGZhY2V0X3dyYXAofiBzY29yZSkNCmBgYA0KDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02fQ0KZGYgPC0gYWxsX3Njb3JlcyAlPiUNCiAgICBzcHJlYWQoc2NvcmUsIGFwYWNoZTIpICU+JQ0KICAgIGdhdGhlcihzY29yZSwgYXBhY2hlMiwgLXBpZS5pZCwgLW1hbnVhbCkNCg0KIyBnZ3Bsb3QoZGYsIGFlcyh4ID0gYXBhY2hlMiwgeSA9IG1hbnVhbCkpICsNCiMgICAgIGdlb21faml0dGVyKGFlcyhjb2xvciA9IHNjb3JlKSwgYWxwaGEgPSAwLjYpIA0KDQpnZ3Bsb3QoZGYsIGFlcyh4ID0gYXBhY2hlMiwgeSA9IG1hbnVhbCkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgICMgZ2VvbV9zbW9vdGgoKSArDQogICAgZmFjZXRfd3JhcCh+IHNjb3JlKQ0KYGBgDQoNCg0KKiBDb21wYXJpc29uIG9mIHNjb3Jlcw0KICAgIC0gUmVzdWx0cyBydW4gdXNpbmcgYm90aCB0aGUgdC10ZXN0IGFuZCBXaWxjb3hvbiBzaWduZWQgcmFuayB0ZXN0IChhc3N1bWVzIG5vbi1wYXJhbWV0cmljIGRhdGEsIGlzIG1vcmUgZGlmZmljdWx0IHRvIGFjaGlldmUgc2lnbmlmaWNhbmNlKQ0KICAgIC0gVG8gYWNjb3VudCBmb3IgcGVyZm9ybWluZyBtdWx0aXBsZSBjb21wYXJpc29ucywgYSBCSCAoQmVuamFtaW5pIGFuZCBIb2NoYmVyZykgY29ycmVjdGlvbiBpcyBhcHBsaWVkIHRvIHRoZSBwLXZhbHVlczsgKip1c2UgdGhlIGJoLmFkanVzdCB2YWx1ZSBhcyB0aGUgcC12YWx1ZSoqDQogICAgICAgICsgUmVmZXJlbmNlOiBodHRwOi8vaWVzLmVkLmdvdi9uY2VlL3B1YnMvMjAwODQwMTgvYXBwX2IuYXNwDQoNCmBgYHtyfQ0KdCA8LSBhbGxfc2NvcmVzWywgLTFdICU+JQ0KICAgIGZpbHRlcihzY29yZSAhPSAibWFudWFsIikgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIGRvKHRpZHkodC50ZXN0KC4kYXBhY2hlMiwgbWFuLCBwYWlyZWQgPSBUUlVFKSkpICU+JQ0KICAgIHVuZ3JvdXAoKSAlPiUNCiAgICBtdXRhdGUoYmguYWRqdXN0ID0gcC5hZGp1c3QocC52YWx1ZSwgIkJIIikpICU+JQ0KICAgIHNlbGVjdChzY29yZTpwLnZhbHVlLCBiaC5hZGp1c3QsIGV2ZXJ5dGhpbmcoKSkNCg0Ka25pdHI6OmthYmxlKHQsIGRpZ2l0cyA9IDQpDQpgYGANCg0KYGBge3J9DQptdyA8LSBhbGxfc2NvcmVzWywgLTFdICU+JQ0KICAgIGZpbHRlcihzY29yZSAhPSAibWFudWFsIikgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIGRvKHRpZHkod2lsY294LnRlc3QoLiRhcGFjaGUyLCBtYW4sIHBhaXJlZCA9IFRSVUUsIGNvbmYuaW50ID0gVFJVRSwgZXhhY3QgPSBGQUxTRSkpKSAlPiUNCiAgICB1bmdyb3VwKCkgJT4lDQogICAgbXV0YXRlKGJoLmFkanVzdCA9IHAuYWRqdXN0KHAudmFsdWUsICJCSCIpKSAlPiUNCiAgICBzZWxlY3Qoc2NvcmU6cC52YWx1ZSwgYmguYWRqdXN0LCBldmVyeXRoaW5nKCkpDQoNCmtuaXRyOjprYWJsZShtdywgZGlnaXRzID0gNCkNCmBgYA0KDQpgYGB7cn0NCm9wdGlvbnMoc2NpcGVuID0gOTk5KQ0KbXdfcGFpciA8LSBhbGxfc2NvcmVzICU+JQ0KICAgIGRtYXBfYXQoInNjb3JlIiwgZmFjdG9yKSAlPiUNCiAgICBkbWFwX2F0KCJzY29yZSIsIH5mY3RfcmVsZXZlbCgueCwgYygibWFudWFsIiwgImVrIiwgImVrX2RyZyIpKSkgJT4lDQogICAgZG8odGlkeShwYWlyd2lzZS53aWxjb3gudGVzdCguJGFwYWNoZTIsIC4kc2NvcmUsIHAuYWRqID0gIkJIIiwgcGFpcmVkID0gVFJVRSwgZXhhY3QgPSBGQUxTRSkpKQ0KYGBgDQoNCg0KIyMjIyBMaW5lYXIgUmVncmVzc2lvbiBNb2RlbA0KDQpgYGB7cn0NCmxtIDwtIGRmICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBkbyhmaXQgPSBsbShtYW51YWwgfiBhcGFjaGUyLCBkYXRhID0gLikpDQoNCmtuaXRyOjprYWJsZShnbGFuY2UobG0sIGZpdCksIGRpZ2l0cyA9IDQpDQpgYGANCg0KYGBge3J9DQphdWdtZW50KGxtLCBmaXQpICU+JQ0KICAgIGdncGxvdChhZXMoeCA9IC5maXR0ZWQsIHkgPSAucmVzaWQpKSArIA0KICAgIGdlb21fcG9pbnQoKSArDQogICAgIyBnZW9tX3Ntb290aChzZSA9IEZBTFNFKSArDQogICAgZmFjZXRfd3JhcCh+IHNjb3JlKQ0KYGBgDQoNCmBgYHtyfQ0KbW9kX2RmIDwtIGRmICU+JQ0KICAgIGZpbHRlcihzY29yZSA9PSAiZWtfZHJnIikNCg0KbW9kIDwtIGxtKG1hbnVhbCB+IGFwYWNoZTIsIGRhdGEgPSBtb2RfZGYpDQoNCnBhcihtZnJvdyA9IGMoMiwgMikpDQpwbG90KG1vZCkNCmBgYA0KDQoNCg0KKiBDb21wYXJlIGRpZmZlcmVuY2VzIGluIHNjb3JlIGZyb20gY29tb3JiaWRpdHkgc2V0cyB2cy4gbWFudWFsDQogICAgLSBDb2x1bW4gKm51bV9kaWZmKiBpbmRpY2F0ZXMgdGhlIG51bWJlciBvZiBwYXRpZW50cyB3aXRoIGEgc2NvcmUgdGhhdCBkaWZmZXJlZCBmcm9tIG1hbnVhbA0KICAgIC0gTWVhbiBhbmQgbWVkaWFuIGluZGljYXRlIHRoZSBkaWZmZXJlbmNlIGZyb20gdGhlIG1hbnVhbCBzY29yZQ0KICAgICAgICArIFRoZXNlIHdlcmUgb25seSBjYWxjdWxhdGVkIGZvciB0aG9zZSBwYXRpZW50cyB3aG9zZSBzY29yZSB3YXMgZGlmZmVyZW50IGZyb20gbWFudWFsDQogICAgICAgICsgSWYgYWxsIHBhdGllbnRzIHdlcmUgaW5jbHVkZWQsIHRoZSBudW1iZXIgaXMgc2tld2VkIHRvd2FyZHMgMCBieSBhbGwgdGhlIHBhdGllbnRzIHdpdGggdGhlIHNhbWUgc2NvcmVzDQoNCmBgYHtyfQ0KZGlmZiA8LSBhbGxfc2NvcmVzICU+JQ0KICAgIHNwcmVhZChzY29yZSwgYXBhY2hlMikgJT4lDQogICAgbXV0YXRlX2F0KHZhcnMoLXBpZS5pZCwgLW1hbnVhbCksIGZ1bnMoYWJzKC4gLSBtYW51YWwpKSkgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBhcGFjaGUyLCAtcGllLmlkLCAtbWFudWFsKSAlPiUNCiAgICBzZWxlY3QoLXBpZS5pZCwgLW1hbnVhbCkgJT4lDQogICAgZmlsdGVyKGFwYWNoZTIgPiAwKSAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgc3VtbWFyaXplX2FsbChmdW5zKG51bV9kaWZmID0gbGVuZ3RoLCBtZWFuLCBzZCwgbWVkaWFuLCBJUVJfbG93ID0gcXVhbnRpbGUoLiwgMC4yNSksIElRUl9oaWdoID0gcXVhbnRpbGUoLiwgMC43NSkpKQ0KDQprbml0cjo6a2FibGUoZGlmZiwgY2FwdGlvbiA9ICJEaWZmZXJlbmNlcyBpbiBBUEFDSEUgSUkgU2NvcmVzIikNCmBgYA0KDQojIyMgQVBBQ0hFIElJSQ0KDQpgYGB7cn0NCnNjb3JlcyA8LSBscyhwYXR0ZXJuID0gInNjb3JlX2FwYWNoZTMiKQ0KDQphbGxfc2NvcmVzIDwtIG1hcChzY29yZXMsIH5tdXRhdGUoZ2V0KC54KSwgc2NvcmUgPSAueCkpICU+JQ0KICAgIG1hcCh+c2VsZWN0KC54LCBwaWUuaWQsIHNjb3JlLCBhcGFjaGUzKSkgJT4lDQogICAgbWFwX2RmKH5zZW1pX2pvaW4oLngsIG1hbnVhbF9wYXRpZW50cywgYnkgPSAicGllLmlkIikpICU+JQ0KICAgIGFycmFuZ2UocGllLmlkLCBzY29yZSkgJT4lDQogICAgZG1hcF9hdCgic2NvcmUiLCBzdHJfcmVwbGFjZV9hbGwsIHBhdHRlcm4gPSAic2NvcmVfYXBhY2hlM18iLCByZXBsYWNlbWVudCA9ICIiKSANCg0KbWFuIDwtIGZpbHRlcihhbGxfc2NvcmVzLCBzY29yZSA9PSAibWFudWFsIikkYXBhY2hlMw0KDQpyZXN1bHQgPC0gYWxsX3Njb3JlcyAlPiUNCiAgICBzZWxlY3QoLXBpZS5pZCkgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIHN1bW1hcml6ZV9hbGwoZnVucyhtZWFuLCBzZCwgbWVkaWFuLCBJUVJfbG93ID0gcXVhbnRpbGUoLiwgMC4yNSksIElRUl9oaWdoID0gcXVhbnRpbGUoLiwgMC43NSkpKQ0KDQprbml0cjo6a2FibGUocmVzdWx0KQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGFsbF9zY29yZXMsIGFlcyh4ID0gc2NvcmUsIHkgPSBhcGFjaGUzKSkgKw0KICAgIGdlb21fYm94cGxvdCgpDQpgYGANCg0KYGBge3IsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTZ9DQpkZiA8LSBhbGxfc2NvcmVzICU+JQ0KICAgIHNwcmVhZChzY29yZSwgYXBhY2hlMykgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBhcGFjaGUzLCAtcGllLmlkLCAtbWFudWFsKQ0KDQpnZ3Bsb3QoZGYsIGFlcyh4ID0gYXBhY2hlMywgeSA9IG1hbnVhbCkpICsNCiAgICBnZW9tX3BvaW50KCkgKw0KICAgICMgZ2VvbV9zbW9vdGgoKSArDQogICAgZmFjZXRfd3JhcCh+IHNjb3JlKQ0KYGBgDQoNCiogQ29tcGFyaXNvbiBvZiBzY29yZXMNCg0KYGBge3J9DQp0IDwtIGFsbF9zY29yZXNbLCAtMV0gJT4lDQogICAgZmlsdGVyKHNjb3JlICE9ICJtYW51YWwiKSAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgZG8odGlkeSh0LnRlc3QoLiRhcGFjaGUzLCBtYW4sIHBhaXJlZCA9IFRSVUUpKSkgJT4lDQogICAgdW5ncm91cCgpICU+JQ0KICAgIG11dGF0ZShiaC5hZGp1c3QgPSBwLmFkanVzdChwLnZhbHVlLCAiQkgiKSkgJT4lDQogICAgc2VsZWN0KHNjb3JlOnAudmFsdWUsIGJoLmFkanVzdCwgZXZlcnl0aGluZygpKQ0KDQprbml0cjo6a2FibGUodCwgZGlnaXRzID0gNCkNCmBgYA0KDQpgYGB7cn0NCm13IDwtIGFsbF9zY29yZXNbLCAtMV0gJT4lDQogICAgZmlsdGVyKHNjb3JlICE9ICJtYW51YWwiKSAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgZG8odGlkeSh3aWxjb3gudGVzdCguJGFwYWNoZTMsIG1hbiwgcGFpcmVkID0gVFJVRSwgY29uZi5pbnQgPSBUUlVFLCBleGFjdCA9IEZBTFNFKSkpICU+JQ0KICAgIHVuZ3JvdXAoKSAlPiUNCiAgICBtdXRhdGUoYmguYWRqdXN0ID0gcC5hZGp1c3QocC52YWx1ZSwgIkJIIikpICU+JQ0KICAgIHNlbGVjdChzY29yZTpwLnZhbHVlLCBiaC5hZGp1c3QsIGV2ZXJ5dGhpbmcoKSkNCg0Ka25pdHI6OmthYmxlKG13LCBkaWdpdHMgPSA0KQ0KYGBgDQoNCiMjIyMgTGluZWFyIFJlZ3Jlc3Npb24gTW9kZWwNCg0KYGBge3J9DQpsbSA8LSBkZiAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgZG8oZml0ID0gbG0obWFudWFsIH4gYXBhY2hlMywgZGF0YSA9IC4pKQ0KDQprbml0cjo6a2FibGUoZ2xhbmNlKGxtLCBmaXQpLCBkaWdpdHMgPSA0KQ0KYGBgDQoNCmBgYHtyfQ0KYXVnbWVudChsbSwgZml0KSAlPiUNCiAgICBnZ3Bsb3QoYWVzKHggPSAuZml0dGVkLCB5ID0gLnJlc2lkKSkgKyANCiAgICBnZW9tX3BvaW50KCkgKw0KICAgIGZhY2V0X3dyYXAofiBzY29yZSkNCmBgYA0KDQoqIERpZmZlcmVuY2VzIGluIHNjb3JlDQoNCmBgYHtyfQ0KZGlmZiA8LSBhbGxfc2NvcmVzICU+JQ0KICAgIHNwcmVhZChzY29yZSwgYXBhY2hlMykgJT4lDQogICAgbXV0YXRlX2F0KHZhcnMoLXBpZS5pZCwgLW1hbnVhbCksIGZ1bnMoYWJzKC4gLSBtYW51YWwpKSkgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBhcGFjaGUzLCAtcGllLmlkLCAtbWFudWFsKSAlPiUNCiAgICBzZWxlY3QoLXBpZS5pZCwgLW1hbnVhbCkgJT4lDQogICAgZmlsdGVyKGFwYWNoZTMgPiAwKSAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgc3VtbWFyaXplX2FsbChmdW5zKG51bV9kaWZmID0gbGVuZ3RoLCBtZWFuLCBzZCwgbWVkaWFuLCBJUVJfbG93ID0gcXVhbnRpbGUoLiwgMC4yNSksIElRUl9oaWdoID0gcXVhbnRpbGUoLiwgMC43NSkpKQ0KDQprbml0cjo6a2FibGUoZGlmZiwgY2FwdGlvbiA9ICJEaWZmZXJlbmNlIGluIEFQQUNIRSBJSUkgU2NvcmVzIikNCmBgYA0KDQojIyMgU0FQUyBJSQ0KDQpgYGB7cn0NCnNjb3JlcyA8LSBscyhwYXR0ZXJuID0gInNjb3JlX3NhcHMyIikNCg0KYWxsX3Njb3JlcyA8LSBtYXAoc2NvcmVzLCB+bXV0YXRlKGdldCgueCksIHNjb3JlID0gLngpKSAlPiUNCiAgICBtYXAofnNlbGVjdCgueCwgcGllLmlkLCBzY29yZSwgc2FwczIpKSAlPiUNCiAgICBtYXBfZGYofnNlbWlfam9pbigueCwgbWFudWFsX3BhdGllbnRzLCBieSA9ICJwaWUuaWQiKSkgJT4lDQogICAgYXJyYW5nZShwaWUuaWQsIHNjb3JlKSAlPiUNCiAgICBkbWFwX2F0KCJzY29yZSIsIHN0cl9yZXBsYWNlX2FsbCwgcGF0dGVybiA9ICJzY29yZV9zYXBzMl8iLCByZXBsYWNlbWVudCA9ICIiKSANCg0KbWFuIDwtIGZpbHRlcihhbGxfc2NvcmVzLCBzY29yZSA9PSAibWFudWFsIikkc2FwczINCg0KcmVzdWx0IDwtIGFsbF9zY29yZXMgJT4lDQogICAgc2VsZWN0KC1waWUuaWQpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBzdW1tYXJpemVfYWxsKGZ1bnMobWVhbiwgc2QsIG1lZGlhbiwgSVFSX2xvdyA9IHF1YW50aWxlKC4sIDAuMjUpLCBJUVJfaGlnaCA9IHF1YW50aWxlKC4sIDAuNzUpKSkNCg0Ka25pdHI6OmthYmxlKHJlc3VsdCkNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChhbGxfc2NvcmVzLCBhZXMoeCA9IHNjb3JlLCB5ID0gc2FwczIpKSArDQogICAgZ2VvbV9ib3hwbG90KCkNCmBgYA0KDQpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCmRmIDwtIGFsbF9zY29yZXMgJT4lDQogICAgc3ByZWFkKHNjb3JlLCBzYXBzMikgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBzYXBzMiwgLXBpZS5pZCwgLW1hbnVhbCkNCg0KZ2dwbG90KGRmLCBhZXMoeCA9IHNhcHMyLCB5ID0gbWFudWFsKSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgIyBnZW9tX3Ntb290aCgpICsNCiAgICBmYWNldF93cmFwKH4gc2NvcmUpDQpgYGANCg0KKiBDb21wYXJpc29uIG9mIHNjb3Jlcw0KDQpgYGB7cn0NCnQgPC0gYWxsX3Njb3Jlc1ssIC0xXSAlPiUNCiAgICBmaWx0ZXIoc2NvcmUgIT0gIm1hbnVhbCIpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBkbyh0aWR5KHQudGVzdCguJHNhcHMyLCBtYW4sIHBhaXJlZCA9IFRSVUUpKSkgJT4lDQogICAgdW5ncm91cCgpICU+JQ0KICAgIG11dGF0ZShiaC5hZGp1c3QgPSBwLmFkanVzdChwLnZhbHVlLCAiQkgiKSkgJT4lDQogICAgc2VsZWN0KHNjb3JlOnAudmFsdWUsIGJoLmFkanVzdCwgZXZlcnl0aGluZygpKQ0KDQprbml0cjo6a2FibGUodCwgZGlnaXRzID0gNCkNCmBgYA0KDQoqIENvbmZpZGVuY2UgaW50ZXJ2YWwgd2FzIHVuYWJsZSB0byBiZSBjYWxjdWxhdGVkIGZvciBXaWxjb3hvbiBhbmFseXNpcyBoZXJlDQoNCmBgYHtyfQ0KbXcgPC0gYWxsX3Njb3Jlc1ssIC0xXSAlPiUNCiAgICBmaWx0ZXIoc2NvcmUgIT0gIm1hbnVhbCIpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBkbyh0aWR5KHdpbGNveC50ZXN0KC4kc2FwczIsIG1hbiwgcGFpcmVkID0gVFJVRSwgZXhhY3QgPSBGQUxTRSkpKSAlPiUNCiAgICB1bmdyb3VwKCkgJT4lDQogICAgbXV0YXRlKGJoLmFkanVzdCA9IHAuYWRqdXN0KHAudmFsdWUsICJCSCIpKSAlPiUNCiAgICBzZWxlY3Qoc2NvcmU6cC52YWx1ZSwgYmguYWRqdXN0LCBldmVyeXRoaW5nKCkpDQoNCmtuaXRyOjprYWJsZShtdywgZGlnaXRzID0gNCkNCmBgYA0KDQojIyMjIExpbmVhciBSZWdyZXNzaW9uIE1vZGVsDQoNCmBgYHtyfQ0KbG0gPC0gZGYgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIGRvKGZpdCA9IGxtKG1hbnVhbCB+IHNhcHMyLCBkYXRhID0gLikpDQoNCmtuaXRyOjprYWJsZShnbGFuY2UobG0sIGZpdCksIGRpZ2l0cyA9IDQpDQpgYGANCg0KYGBge3J9DQphdWdtZW50KGxtLCBmaXQpICU+JQ0KICAgIGdncGxvdChhZXMoeCA9IC5maXR0ZWQsIHkgPSAucmVzaWQpKSArIA0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZmFjZXRfd3JhcCh+IHNjb3JlKQ0KYGBgDQoNCiogRGlmZmVyZW5jZXMgaW4gc2NvcmUNCg0KYGBge3J9DQpkaWZmIDwtIGFsbF9zY29yZXMgJT4lDQogICAgc3ByZWFkKHNjb3JlLCBzYXBzMikgJT4lDQogICAgbXV0YXRlX2F0KHZhcnMoLXBpZS5pZCwgLW1hbnVhbCksIGZ1bnMoYWJzKC4gLSBtYW51YWwpKSkgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBzYXBzMiwgLXBpZS5pZCwgLW1hbnVhbCkgJT4lDQogICAgc2VsZWN0KC1waWUuaWQsIC1tYW51YWwpICU+JQ0KICAgIGZpbHRlcihzYXBzMiA+IDApICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBzdW1tYXJpemVfYWxsKGZ1bnMobnVtX2RpZmYgPSBsZW5ndGgsIG1lYW4sIHNkLCBtZWRpYW4sIElRUl9sb3cgPSBxdWFudGlsZSguLCAwLjI1KSwgSVFSX2hpZ2ggPSBxdWFudGlsZSguLCAwLjc1KSkpDQoNCmtuaXRyOjprYWJsZShkaWZmLCBjYXB0aW9uID0gIkRpZmZlcmVuY2UgaW4gU0FQUyBJSSBTY29yZXMiKQ0KYGBgDQoNCiMjIFNlY29uZGFyeSBlbmRwb2ludHMNCg0KIyMjIFByZWRpY3RlZCBtb3J0YWxpdHkNCg0KIyMjIyBTQVBTIElJDQoNCiogTWVhbiBhbmQgbWVkaWFuIHJpc2sgb2YgbW9ydGFsaXR5IChhcyBhIHBlcmNlbnQpIGZvciBlYWNoIGNvbW9yYmlkaXR5IHNldA0KDQpgYGB7cn0NCmNvbW9yYmlkIDwtIGxzKHBhdHRlcm4gPSAic2NvcmVfc2FwczJfIikNCg0KYWxsX2RmIDwtIG1hcChjb21vcmJpZCwgfm11dGF0ZShnZXQoLngpLCBzY29yZSA9IC54KSkgJT4lDQogICAgbWFwKH5zZWxlY3QoLngsIHBpZS5pZCwgc2NvcmUsIHNhcHMyKSkgJT4lDQogICAgbWFwX2RmKH5zZW1pX2pvaW4oLngsIG1hbnVhbF9wYXRpZW50cywgYnkgPSAicGllLmlkIikpICU+JQ0KICAgIGFycmFuZ2UocGllLmlkLCBzY29yZSkgJT4lDQogICAgZG1hcF9hdCgic2NvcmUiLCBzdHJfcmVwbGFjZV9hbGwsIHBhdHRlcm4gPSAic2NvcmVfc2FwczJfIiwgcmVwbGFjZW1lbnQgPSAiIikgJT4lDQogICAgZGlzdGluY3QocGllLmlkLCBzY29yZSwgLmtlZXBfYWxsID0gVFJVRSkgJT4lDQogICAgbXV0YXRlKGxvZ2l0ID0gLTcuNzYzICsgMC4wNzM3ICogc2FwczIgKyAwLjk5NzEgKiBsb2coc2FwczIgKyAxKSwNCiAgICAgICAgICAgbW9ydGFsaXR5ID0gZXhwKGxvZ2l0KSAvICgxICsgZXhwKGxvZ2l0KSkpICU+JQ0KICAgIHNlbGVjdChwaWUuaWQsIHNjb3JlLCBtb3J0YWxpdHkpIA0KDQptYW4gPC0gZmlsdGVyKGFsbF9kZiwgc2NvcmUgPT0gIm1hbnVhbCIpJG1vcnRhbGl0eQ0KDQpyZXN1bHQgPC0gYWxsX2RmICU+JQ0KICAgIHNlbGVjdCgtcGllLmlkKSAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgc3VtbWFyaXplX2FsbChmdW5zKG1lYW4sIHNkLCBtZWRpYW4sIElRUl9sb3cgPSBxdWFudGlsZSguLCAwLjI1KSwgSVFSX2hpZ2ggPSBxdWFudGlsZSguLCAwLjc1KSkpDQoNCmtuaXRyOjprYWJsZShyZXN1bHQsIGRpZ2l0cyA9IDQpDQpgYGANCg0KYGBge3J9DQp0IDwtIGFsbF9kZlssIC0xXSAlPiUNCiAgICBmaWx0ZXIoc2NvcmUgIT0gIm1hbnVhbCIpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUgDQogICAgZG8odGlkeSh0LnRlc3QoLiRtb3J0YWxpdHksIG1hbiwgcGFpcmVkID0gVFJVRSkpKSAlPiUNCiAgICB1bmdyb3VwKCkgJT4lDQogICAgbXV0YXRlKGJoLmFkanVzdCA9IHAuYWRqdXN0KHAudmFsdWUsICJCSCIpKSAlPiUNCiAgICBzZWxlY3Qoc2NvcmU6cC52YWx1ZSwgYmguYWRqdXN0LCBldmVyeXRoaW5nKCkpDQoNCmtuaXRyOjprYWJsZSh0LCBkaWdpdHMgPSA0KQ0KYGBgDQoNCmBgYHtyfQ0KbXcgPC0gYWxsX2RmWywgLTFdICU+JQ0KICAgIGZpbHRlcihzY29yZSAhPSAibWFudWFsIikgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIGRvKHRpZHkod2lsY294LnRlc3QoLiRtb3J0YWxpdHksIG1hbiwgcGFpcmVkID0gVFJVRSwgY29uZi5pbnQgPSBUUlVFLCBleGFjdCA9IEZBTFNFKSkpICU+JQ0KICAgIHVuZ3JvdXAoKSAlPiUNCiAgICBtdXRhdGUoYmguYWRqdXN0ID0gcC5hZGp1c3QocC52YWx1ZSwgIkJIIikpICU+JQ0KICAgIHNlbGVjdChzY29yZTpwLnZhbHVlLCBiaC5hZGp1c3QsIGV2ZXJ5dGhpbmcoKSkNCg0Ka25pdHI6OmthYmxlKG13LCBkaWdpdHMgPSA0KQ0KYGBgDQoNCiogRGlmZmVyZW5jZSBpbiByaXNrIG9mIG1vcnRhbGl0eQ0KICAgIC0gTWVhbiBhbmQgbWVkaWFuIGNhbGN1bGF0ZWQgdXNpbmcgb25seSB0aG9zZSBwYXRpZW50cyB3aG9zZSBwcmVkaWN0ZWQgbW9ydGFsaXR5IHNjb3JlIHdhcyBkaWZmZXJlbnQgZnJvbSBtYW51YWwNCiAgICANCmBgYHtyfQ0KZGlmZiA8LSBhbGxfZGYgJT4lDQogICAgc3ByZWFkKHNjb3JlLCBtb3J0YWxpdHkpICU+JQ0KICAgIG11dGF0ZV9hdCh2YXJzKC1waWUuaWQsIC1tYW51YWwpLCBmdW5zKGFicyguIC0gbWFudWFsKSkpICU+JQ0KICAgIGdhdGhlcihzY29yZSwgc2FwczIsIC1waWUuaWQsIC1tYW51YWwpICU+JQ0KICAgIHNlbGVjdCgtcGllLmlkLCAtbWFudWFsKSAlPiUNCiAgICBmaWx0ZXIoc2FwczIgPiAwKSAlPiUNCiAgICBncm91cF9ieShzY29yZSkgJT4lDQogICAgc3VtbWFyaXplX2FsbChmdW5zKG51bV9kaWZmID0gbGVuZ3RoLCBtZWFuLCBzZCwgbWVkaWFuLCBJUVJfbG93ID0gcXVhbnRpbGUoLiwgMC4yNSksIElRUl9oaWdoID0gcXVhbnRpbGUoLiwgMC43NSkpKQ0KDQprbml0cjo6a2FibGUoZGlmZiwgY2FwdGlvbiA9ICJEaWZmZXJlbmNlIGluIFByZWRpY3RlZCBNb3J0YWxpdHkgdXNpbmcgU0FQUyBJSSIpDQpgYGANCg0KIyMjIE51bWJlciBvZiBjb21vcmJpZGl0aWVzDQoNCiMjIyMgQVBBQ0hFIElJDQoNCiogTWVhbiByZXByZXNlbnRzIHRoZSBhdmVyYWdlIG51bWJlciBvZiBjb21vcmJpZGl0aWVzIHBlciBwYXRpZW50DQoNCmBgYHtyfQ0KY29tb3JiaWQgPC0gbHMocGF0dGVybiA9ICJkYXRhX2FwYWNoZTJfIikNCg0KYWxsX2RmIDwtIG1hcChjb21vcmJpZCwgfm11dGF0ZShnZXQoLngpLCBzY29yZSA9IC54KSkgJT4lDQogICAgbWFwKH5kaXN0aW5jdCgueCwgcGllLmlkLCBzY29yZSwgbGl2ZXIsIGNhcmRpb3Zhc2MsIHJlc3BpcmF0b3J5LCByZW5hbCwgaW1tdW5vY29tcCwgY29tb3JiaWRpdHkpKSAlPiUNCiAgICBtYXBfZGYofnNlbWlfam9pbigueCwgbWFudWFsX3BhdGllbnRzLCBieSA9ICJwaWUuaWQiKSkgJT4lDQogICAgYXJyYW5nZShwaWUuaWQsIHNjb3JlKSAlPiUNCiAgICBkbWFwX2F0KCJzY29yZSIsIHN0cl9yZXBsYWNlX2FsbCwgcGF0dGVybiA9ICJkYXRhX2FwYWNoZTJfIiwgcmVwbGFjZW1lbnQgPSAiIikgJT4lDQogICAgbXV0YXRlX2lmKGlzLmxvZ2ljYWwsIGFzLm51bWVyaWMpICU+JQ0KICAgIGJ5X3JvdyhmdW5jdGlvbih4KSBzdW0oeFssIDM6N10sIG5hLnJtID0gVFJVRSksIC5jb2xsYXRlID0gInJvd3MiLCAudG8gPSAibnVtX2NvbW9yYmlkIikgJT4lDQogICAgc2VsZWN0KHBpZS5pZCwgc2NvcmUsIG51bV9jb21vcmJpZCkgDQoNCm1hbiA8LSBmaWx0ZXIoYWxsX2RmLCBzY29yZSA9PSAibWFudWFsIikkbnVtX2NvbW9yYmlkDQoNCnJlc3VsdCA8LSBhbGxfZGYgJT4lDQogICAgc2VsZWN0KC1waWUuaWQpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBzdW1tYXJpemVfYWxsKGZ1bnMobWVhbiwgc2QsIG1lZGlhbiwgSVFSX2xvdyA9IHF1YW50aWxlKC4sIDAuMjUpLCBJUVJfaGlnaCA9IHF1YW50aWxlKC4sIDAuNzUpKSkNCg0Ka25pdHI6OmthYmxlKHJlc3VsdCkNCmBgYA0KDQpgYGB7cn0NCnQgPC0gYWxsX2RmWywgLTFdICU+JQ0KICAgIGZpbHRlcihzY29yZSAhPSAibWFudWFsIikgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIGRvKHRpZHkodC50ZXN0KC4kbnVtX2NvbW9yYmlkLCBtYW4sIHBhaXJlZCA9IFRSVUUpKSkgJT4lDQogICAgdW5ncm91cCgpICU+JQ0KICAgIG11dGF0ZShiaC5hZGp1c3QgPSBwLmFkanVzdChwLnZhbHVlLCAiQkgiKSkgJT4lDQogICAgc2VsZWN0KHNjb3JlOnAudmFsdWUsIGJoLmFkanVzdCwgZXZlcnl0aGluZygpKQ0KDQprbml0cjo6a2FibGUodCwgZGlnaXRzID0gNCkNCmBgYA0KDQpgYGB7cn0NCm13IDwtIGFsbF9kZlssIC0xXSAlPiUNCiAgICBmaWx0ZXIoc2NvcmUgIT0gIm1hbnVhbCIpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBkbyh0aWR5KHdpbGNveC50ZXN0KC4kbnVtX2NvbW9yYmlkLCBtYW4sIHBhaXJlZCA9IFRSVUUsIGNvbmYuaW50ID0gVFJVRSwgZXhhY3QgPSBGQUxTRSkpKSAlPiUNCiAgICB1bmdyb3VwKCkgJT4lDQogICAgbXV0YXRlKGJoLmFkanVzdCA9IHAuYWRqdXN0KHAudmFsdWUsICJCSCIpKSAlPiUNCiAgICBzZWxlY3Qoc2NvcmU6cC52YWx1ZSwgYmguYWRqdXN0LCBldmVyeXRoaW5nKCkpDQoNCmtuaXRyOjprYWJsZShtdywgZGlnaXRzID0gNCkNCmBgYA0KDQojIyMgUHJvcG9ydGlvbiB3aXRoIGRpZmZlcmluZyBjb21vcmJpZGl0eQ0KDQojIyMjIEFQQUNIRSBJSQ0KDQoqIFByb3BvcnRpb24gb2YgcGF0aWVudHMgd2hlcmUgYSBjb21vcmJpZGl0eSB3YXMgaWRlbnRpZmllZCBieSBJQ0Qgb3IgYnkgbWFudWFsLCBidXQgbm90IGJvdGgNCg0KYGBge3J9DQpjb21vcmJpZCA8LSBscyhwYXR0ZXJuID0gImRhdGFfYXBhY2hlMl8iKQ0KDQphbGxfZGYgPC0gbWFwKGNvbW9yYmlkLCB+bXV0YXRlKGdldCgueCksIHNjb3JlID0gLngpKSAlPiUNCiAgICBtYXAofmRpc3RpbmN0KC54LCBwaWUuaWQsIHNjb3JlLCBjb21vcmJpZGl0eSkpICU+JQ0KICAgIG1hcF9kZih+c2VtaV9qb2luKC54LCBtYW51YWxfcGF0aWVudHMsIGJ5ID0gInBpZS5pZCIpKSAlPiUNCiAgICBhcnJhbmdlKHBpZS5pZCwgc2NvcmUpICU+JQ0KICAgIGRtYXBfYXQoInNjb3JlIiwgc3RyX3JlcGxhY2VfYWxsLCBwYXR0ZXJuID0gImRhdGFfYXBhY2hlMl8iLCByZXBsYWNlbWVudCA9ICIiKSAlPiUNCiAgICBzcHJlYWQoc2NvcmUsIGNvbW9yYmlkaXR5KSAlPiUNCiAgICBtdXRhdGVfYXQodmFycygtcGllLmlkLCAtbWFudWFsKSwgZnVucyguICE9IG1hbnVhbCkpICU+JQ0KICAgIG11dGF0ZV9pZihpcy5sb2dpY2FsLCBhcy5udW1lcmljKSAlPiUNCiAgICB1bmdyb3VwKCkgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBjb21vcmJpZGl0eSwgLXBpZS5pZCwgLW1hbnVhbCkgJT4lDQogICAgc2VsZWN0KC1waWUuaWQsIC1tYW51YWwpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBzdW1tYXJpemVfYWxsKGZ1bnMobnVtX2RpZmYgPSBzdW0oLiA+IDApLCBwcm9wb3J0aW9uID0gbWVhbikpDQoNCmtuaXRyOjprYWJsZShhbGxfZGYpDQpgYGANCg0KIyMjIyBBUEFDSEUgSUlJDQoNCiogUHJvcG9ydGlvbiBvZiBwYXRpZW50cyB3aGVyZSB0aGUgcHJpbWFyeSBjb21vcmJpZGl0eSBpZGVudGlmaWVkIGJ5IElDRCB2YXJpZWQgZnJvbSBwcmltYXJ5IGNvbW9yYmlkaXR5IGlkZW50aWZpZWQgYnkgbWFudWFsDQoNCmBgYHtyfQ0KY29tb3JiaWQgPC0gbHMocGF0dGVybiA9ICJkYXRhX2FwYWNoZTNfIikNCg0KYWxsX2RmIDwtIG1hcChjb21vcmJpZCwgfm11dGF0ZShnZXQoLngpLCBzY29yZSA9IC54KSkgJT4lDQogICAgbWFwKH5kaXN0aW5jdCgueCwgcGllLmlkLCBzY29yZSwgY29tb3JiaWRpdHkpKSAlPiUNCiAgICBtYXBfZGYofnNlbWlfam9pbigueCwgbWFudWFsX3BhdGllbnRzLCBieSA9ICJwaWUuaWQiKSkgJT4lDQogICAgYXJyYW5nZShwaWUuaWQsIHNjb3JlKSAlPiUNCiAgICBkbWFwX2F0KCJzY29yZSIsIHN0cl9yZXBsYWNlX2FsbCwgcGF0dGVybiA9ICJkYXRhX2FwYWNoZTNfIiwgcmVwbGFjZW1lbnQgPSAiIikgJT4lDQogICAgc3ByZWFkKHNjb3JlLCBjb21vcmJpZGl0eSwgZmlsbCA9ICIiKSAlPiUNCiAgICBkbWFwKHN0cl9yZXBsYWNlX2FsbCwgcGF0dGVybiA9ICJub25lIiwgcmVwbGFjZW1lbnQgPSAiIikgJT4lDQogICAgbXV0YXRlX2F0KHZhcnMoLXBpZS5pZCwgLW1hbnVhbCksIGZ1bnMoLiAhPSBtYW51YWwpKSAlPiUNCiAgICBtdXRhdGVfaWYoaXMubG9naWNhbCwgYXMubnVtZXJpYykgJT4lDQogICAgZ2F0aGVyKHNjb3JlLCBjb21vcmJpZGl0eSwgLXBpZS5pZCwgLW1hbnVhbCkgJT4lDQogICAgc2VsZWN0KC1waWUuaWQsIC1tYW51YWwpICU+JQ0KICAgIGdyb3VwX2J5KHNjb3JlKSAlPiUNCiAgICBzdW1tYXJpemVfYWxsKGZ1bnMobnVtX2RpZmYgPSBzdW0oLiA+IDApLCBwcm9wb3J0aW9uID0gbWVhbikpDQoNCmtuaXRyOjprYWJsZShhbGxfZGYpDQpgYGANCg0KIyMjIyBTQVBTIElJDQoNCiogUHJvcG9ydGlvbiBvZiBwYXRpZW50cyB3aGVyZSB0aGUgcHJpbWFyeSBjb21vcmJpZGl0eSBpZGVudGlmaWVkIGJ5IElDRCB2YXJpZWQgZnJvbSBwcmltYXJ5IGNvbW9yYmlkaXR5IGlkZW50aWZpZWQgYnkgbWFudWFsDQoNCmBgYHtyfQ0KY29tb3JiaWQgPC0gbHMocGF0dGVybiA9ICJkYXRhX3NhcHMyXyIpDQoNCmFsbF9kZiA8LSBtYXAoY29tb3JiaWQsIH5tdXRhdGUoZ2V0KC54KSwgc2NvcmUgPSAueCkpICU+JQ0KICAgIG1hcCh+ZGlzdGluY3QoLngsIHBpZS5pZCwgc2NvcmUsIGNvbW9yYmlkaXR5KSkgJT4lDQogICAgbWFwX2RmKH5zZW1pX2pvaW4oLngsIG1hbnVhbF9wYXRpZW50cywgYnkgPSAicGllLmlkIikpICU+JQ0KICAgIGFycmFuZ2UocGllLmlkLCBzY29yZSkgJT4lDQogICAgZG1hcF9hdCgic2NvcmUiLCBzdHJfcmVwbGFjZV9hbGwsIHBhdHRlcm4gPSAiZGF0YV9zYXBzMl8iLCByZXBsYWNlbWVudCA9ICIiKSAlPiUNCiAgICBzcHJlYWQoc2NvcmUsIGNvbW9yYmlkaXR5LCBmaWxsID0gIiIpICU+JQ0KICAgIGRtYXAoc3RyX3JlcGxhY2VfYWxsLCBwYXR0ZXJuID0gIm5vbmUiLCByZXBsYWNlbWVudCA9ICIiKSAlPiUNCiAgICBtdXRhdGVfYXQodmFycygtcGllLmlkLCAtbWFudWFsKSwgZnVucyguICE9IG1hbnVhbCkpICU+JQ0KICAgIG11dGF0ZV9pZihpcy5sb2dpY2FsLCBhcy5udW1lcmljKSAlPiUNCiAgICBnYXRoZXIoc2NvcmUsIGNvbW9yYmlkaXR5LCAtcGllLmlkLCAtbWFudWFsKSAlPiUNCiAgICBzZWxlY3QoLXBpZS5pZCwgLW1hbnVhbCkgJT4lDQogICAgZ3JvdXBfYnkoc2NvcmUpICU+JQ0KICAgIHN1bW1hcml6ZV9hbGwoZnVucyhudW1fZGlmZiA9IHN1bSguID4gMCksIHByb3BvcnRpb24gPSBtZWFuKSkNCg0Ka25pdHI6OmthYmxlKGFsbF9kZikNCmBgYA0K