Question 1
a.
The data set has 153 observations with 6 variables. The data set
contains 4 quantitative variables (Ozone, Solar.R, Wind, Temp). It also
contains 2 categorical yet numeric columns (Month, Day).
data <- read.csv("HW1data.csv")
glimpse(data)
b.
Ozone is missing 37 values. Solar.R is missing 7 values.
colSums(is.na(data))
Ozone Solar.R Wind Temp Month Day
37 7 0 0 0 0
c.
There are 111 complete cases. There are 35 observations missing Ozone
only. There are 5 observations missing Solar.R only. There are 2
observations missing both Ozone and Solar.R.
aggr(data, numbers = TRUE, prop = FALSE, sortVar = TRUE)

Variables sorted by number of missings:
Variable Count
Ozone 37
Solar.R 7
Wind 0
Temp 0
Month 0
Day 0
d.
The proportion of missing Ozone values is substantially higher in the
≤60 band and substantially lower in the 61–70 band, with moderate
variation across the remaining temperature ranges. This suggests that
missingness depends on temperature, indicating the missing values are
Missing At Random (MAR). In other words, the probability that an Ozone
value is missing is related to the observed temperature. Although the
largest swings in proportion occur in bands with smaller sample sizes,
meaningful differences remain in larger bands.
temp_p <- data %>%
mutate(temp_band = cut(Temp, breaks = c(0,60,70,80,90,Inf),
labels = c("<=60", "61–70", "71–80", "81-90", "90+"),
right = TRUE)) %>%
group_by(temp_band) %>%
summarise(proportion = sum(is.na(Ozone)) / n(),
band_total = n(),
na_total = sum(is.na(Ozone)))
kable(temp_p)
| <=60 |
0.5000000 |
8 |
4 |
| 61–70 |
0.0800000 |
25 |
2 |
| 71–80 |
0.3269231 |
52 |
17 |
| 81-90 |
0.1851852 |
54 |
10 |
| 90+ |
0.2857143 |
14 |
4 |
e.
new <- data %>% mutate(Ozone2 = ifelse(is.na(Ozone), mean(Ozone, na.rm = TRUE), Ozone))
plot_df_long <- new %>%
select(Ozone, Ozone2) %>%
pivot_longer(everything(),
names_to = "Type",
values_to = "Value")
Den.plt <- ggplot(plot_df_long, aes(x = Value, color = Type)) +
stat_density(geom = "line", linewidth = 1.2, position = "identity", na.rm = TRUE) +
scale_color_manual(values = c("Ozone" = "blue",
"Ozone2" = "red")) +
labs(
title = "Density: Original vs Mean-Imputed Ozone",
subtitle = "Comparison of Distributions",
x = "Ozone",
y = "Density"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5),
plot.margin = margin(t = 35, r = 20, b = 30, l = 30, unit = "pt")
)
ggplotly(Den.plt)
When comparing the density plot of Ozone vs Mean Imputed Ozone values
there is a clear spike in density in the Mean Imputed Ozone at the mean
ozone value.
f.
This visual shows the imputed values tend to follow the same
distribution as the non-missing ones.
mice_data <- mice(data, seed = 123)
mice_1 <- filter(complete(mice_data, 1), is.na(data$Ozone))
mice_2 <- filter(complete(mice_data, 2), is.na(data$Ozone))
ggplot() +
geom_point(data = data, aes(x = Temp, y = Ozone), color = "grey") +
geom_point(data = mice_1, aes(x = Temp, y = Ozone), color = "red", alpha = 0.5) +
geom_point(data = mice_2, aes(x = Temp, y = Ozone), color = "green", alpha = 0.5)

g.
The variables with the strongest positive linear relationship are
Temp and Ozone, with a correlation of 0.655. This relationship is
clearly reflected in their scatterplot, which shows a strong upward
trend with most points clustered together, indicating that higher temps
are associated with higher ozone levels. The strongest negative linear
relationship is between Wind and Ozone, with a correlation of −0.576.
Their scatterplot reflects this as well, with points forming a clear
decreasing pattern, indicating that higher wind speeds are associated
with lower ozone levels.
fmice <- complete(mice_data, 1)
ggpairs(fmice)

h.
The largest and darkest blue circle is between Temp and Ozone, and
the largest and darkest red circle is between Wind and Ozone, supporting
are above correlation findings.
cor_mat <- cor(fmice)
corrplot.mixed(cor_mat, upper = "circle", order = 'AOE')

i.
The Euclidean distance between these two observations is 1.
data_i <- fmice[1:2,c(5,6)]
ggplot() +
geom_point(data = data_i, aes(x = Month, y = Day))

as.matrix(dist(data_i))
1 2
1 0 1
2 1 0
j.
The Manhattan distance is also 1. The Euclidean distance is a
straight line measure, whereas, the Manhattan distance measures along
horizontal and vertical paths. Since the distance between the points is
one vertical path, their two distances are the same.
as.matrix(dist(data_i, method = "manhattan"))
1 2
1 0 1
2 1 0
k.
The Euclidean distance between the two observations is 1.414214,
while the Manhattan distance is 2. The Euclidean distance is shorter
because it measures the straight line distance between the two points.
In contrast, the Manhattan distance measures distance along horizontal
and vertical paths, meaning it cannot move diagonally, and in this case
the points are separated diagonally.
data_i <- fmice[c(1,33),c(5,6)]
ggplot() +
geom_point(data = data_i, aes(x = Month, y = Day))

as.matrix(dist(data_i))
1 33
1 0.000000 1.414214
33 1.414214 0.000000
as.matrix(dist(data_i, method = "manhattan"))
1 33
1 0 2
33 2 0
l.
s_data <- mutate(fmice, across(where(is.numeric), ~scale(.) %>% as.vector))
The first observation had an Ozone value of 41 standardized to
0.0106743. This standardized value means the original value was
0.0106743 standard deviations from the mean ozone value. We can check
this by getting the mean of Ozone, 40.6601307, and standard deviation of
ozone, 31.839888, and seeing how many standard deviations were from it.
Our point 41 - the mean 40.6601307 equals 0.3398693. This is the
distance from the mean, now divide by the standard deviation and we get,
0.0106743. Which is the same as the standardized score.
m.
The nearest neighbors to observation 1 are observations 2, 10, and 7,
with observation 2 being the closest. The nearest neighbors to
observation 2 are observations 1, 10, and 38, with observation 1 being
the closest.
d_z <- dist(s_data)
result <- kNN(x = d_z, k = 3, search = "dist")
result$id[1:4, ]
1 2 3
[1,] 2 10 7
[2,] 1 10 38
[3,] 38 10 2
[4,] 7 13 14
result$dist[1:4, ]
1 2 3
[1,] 0.9882166 1.422317 1.544303
[2,] 0.9882166 1.488389 1.491222
[3,] 1.5613885 1.561498 1.564420
[4,] 0.9701069 1.322249 1.379994
Question 2
My top preference would be analyzing economic/financial data,
especially looking at the relationship between money supply, inflation,
consumer prices, wages, etc.
My second preference would be working with mental health or survey
data, for example examining relationships between medication use,
habits, and well being outcomes.
My third preference would be sports analytics, would be fine with
anything.
LS0tCnRpdGxlOiAiSG9tZXdvcmsgMSIKYXV0aG9yOiAiQ2hhcmxpZSBNb3JnYW4iCmRhdGU6ICIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OiAKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICAgIHRvY19mbG9hdDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMKICAgIHRoZW1lOiBsdW1lbgogIHBkZl9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgZmlnX3dpZHRoOiAzCiAgICBmaWdfaGVpZ2h0OiAzCiAgd29yZF9kb2N1bWVudDogCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA0CiAgICBmaWdfY2FwdGlvbjogeWVzCiAgICBrZWVwX21kOiB5ZXMKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9CiNUT0M6OmJlZm9yZSB7CiAgY29udGVudDogIlRhYmxlIG9mIENvbnRlbnRzIjsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LXNpemU6IDEuMmVtOwogIGRpc3BsYXk6IGJsb2NrOwogIGNvbG9yOiBuYXZ5OwogIG1hcmdpbi1ib3R0b206IDEwcHg7Cn0KCgpkaXYjVE9DIGxpIHsgICAgIC8qIHRhYmxlIG9mIGNvbnRlbnQgICovCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOwogICAgYmFja2dyb3VuZC1pbWFnZTpub25lOwogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsKICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsKfQoKaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8KICBmb250LXNpemU6IDIycHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgY29sb3I6IERhcmtSZWQ7CiAgdGV4dC1hbGlnbjogY2VudGVyOwogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsKfQoKaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8KICBmb250LXNpemU6IDE1cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsKICBjb2xvcjogbmF2eTsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogIGZvbnQtc2l6ZTogMThweDsKICBmb250LXdlaWdodDogYm9sZDsKICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7CiAgY29sb3I6IERhcmtCbHVlOwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQoKaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLwogICAgZm9udC1zaXplOiAyMHB4OwogICAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogY2VudGVyOwp9CgpoMiB7IC8qIEhlYWRlciAyIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE4cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoMyB7IC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE2cHg7CiAgICBmb250LXdlaWdodDogYm9sZDsKICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOwogICAgY29sb3I6IG5hdnk7CiAgICB0ZXh0LWFsaWduOiBsZWZ0Owp9CgpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovCiAgICBmb250LXNpemU6IDE0cHg7CiAgZm9udC13ZWlnaHQ6IGJvbGQ7CiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsKICAgIGNvbG9yOiBkYXJrcmVkOwogICAgdGV4dC1hbGlnbjogbGVmdDsKfQoKLyogQWRkIGRvdHMgYWZ0ZXIgbnVtYmVyZWQgaGVhZGVycyAqLwouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7CiAgY29udGVudDogIi4iOwoKYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0KCi5oaWdobGlnaHRtZSB7IGJhY2tncm91bmQtY29sb3I6eWVsbG93OyB9CgpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQoKfQpgYGAKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQojIGNvZGUgY2h1bmsgc3BlY2lmaWVzIHdoZXRoZXIgdGhlIFIgY29kZSwgd2FybmluZ3MsIGFuZCBvdXRwdXQgCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLgppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQogICBsaWJyYXJ5KGtuaXRyKQp9CmlmICghcmVxdWlyZSgicGFuZGVyIikpIHsKICAgaW5zdGFsbC5wYWNrYWdlcygicGFuZGVyIikKICAgbGlicmFyeShwYW5kZXIpCn0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikKICBsaWJyYXJ5KGdncGxvdDIpCn0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgewogIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpCiAgbGlicmFyeSh0aWR5dmVyc2UpCn0KCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQogIGxpYnJhcnkocGxvdGx5KQp9CgppZiAoIXJlcXVpcmUoIlZJTSIpKSB7CiAgaW5zdGFsbC5wYWNrYWdlcygiVklNIikKICBsaWJyYXJ5KFZJTSkKfQoKaWYgKCFyZXF1aXJlKCJtaWNlIikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJtaWNlIikKICBsaWJyYXJ5KG1pY2UpCn0KCmlmICghcmVxdWlyZSgiR0dhbGx5IikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJHR2FsbHkiKQogIGxpYnJhcnkoR0dhbGx5KQp9CgppZiAoIXJlcXVpcmUoImNvcnJwbG90IikpIHsKICBpbnN0YWxsLnBhY2thZ2VzKCJjb3JycGxvdCIpCiAgbGlicmFyeShjb3JycGxvdCkKfQoKaWYgKCFyZXF1aXJlKCJkYnNjYW4iKSkgewogIGluc3RhbGwucGFja2FnZXMoImRic2NhbiIpCiAgbGlicmFyeShkYnNjYW4pCn0KCiMjIyMKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICAjIGluY2x1ZGUgY29kZSBjaHVuayBpbiB0aGUgb3V0cHV0IGZpbGUKICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICAjIHNvbWV0aW1lcywgeW91IGNvZGUgbWF5IHByb2R1Y2Ugd2FybmluZyBtZXNzYWdlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRoZSBvdXRwdXQgZmlsZS4gCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwgICAgIyB5b3UgY2FuIGFsc28gZGVjaWRlIHdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgb3V0cHV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEKICAgICAgICAgICAgICAgICAgICAgICkgIApgYGAKIAojIyBRdWVzdGlvbiAxCiMjIyBhLgpUaGUgZGF0YSBzZXQgaGFzIDE1MyBvYnNlcnZhdGlvbnMgd2l0aCA2IHZhcmlhYmxlcy4gVGhlIGRhdGEgc2V0IGNvbnRhaW5zIDQgcXVhbnRpdGF0aXZlIHZhcmlhYmxlcyAoT3pvbmUsIFNvbGFyLlIsIFdpbmQsIFRlbXApLiBJdCBhbHNvIGNvbnRhaW5zIDIgY2F0ZWdvcmljYWwgeWV0IG51bWVyaWMgY29sdW1ucyAoTW9udGgsIERheSkuCmBgYHtyLCByZXN1bHRzPSJoaWRlIn0KZGF0YSA8LSByZWFkLmNzdigiSFcxZGF0YS5jc3YiKQpnbGltcHNlKGRhdGEpCmBgYAoKIyMjIGIuCk96b25lIGlzIG1pc3NpbmcgYHIgc3VtKGlzLm5hKGRhdGEkT3pvbmUpKWAgdmFsdWVzLiBTb2xhci5SIGlzIG1pc3NpbmcgYHIgc3VtKGlzLm5hKGRhdGEkU29sYXIuUikpYCB2YWx1ZXMuCmBgYHtyfQpjb2xTdW1zKGlzLm5hKGRhdGEpKQpgYGAKCiMjIyBjLgpUaGVyZSBhcmUgMTExIGNvbXBsZXRlIGNhc2VzLiBUaGVyZSBhcmUgMzUgb2JzZXJ2YXRpb25zIG1pc3NpbmcgT3pvbmUgb25seS4gVGhlcmUgYXJlIDUgb2JzZXJ2YXRpb25zIG1pc3NpbmcgU29sYXIuUiBvbmx5LiBUaGVyZSBhcmUgMiBvYnNlcnZhdGlvbnMgbWlzc2luZyBib3RoIE96b25lIGFuZCBTb2xhci5SLgpgYGB7cn0KYWdncihkYXRhLCBudW1iZXJzID0gVFJVRSwgcHJvcCA9IEZBTFNFLCBzb3J0VmFyID0gVFJVRSkKYGBgCgojIyMgZC4KVGhlIHByb3BvcnRpb24gb2YgbWlzc2luZyBPem9uZSB2YWx1ZXMgaXMgc3Vic3RhbnRpYWxseSBoaWdoZXIgaW4gdGhlIOKJpDYwIGJhbmQgYW5kIHN1YnN0YW50aWFsbHkgbG93ZXIgaW4gdGhlIDYx4oCTNzAgYmFuZCwgd2l0aCBtb2RlcmF0ZSB2YXJpYXRpb24gYWNyb3NzIHRoZSByZW1haW5pbmcgdGVtcGVyYXR1cmUgcmFuZ2VzLiBUaGlzIHN1Z2dlc3RzIHRoYXQgbWlzc2luZ25lc3MgZGVwZW5kcyBvbiB0ZW1wZXJhdHVyZSwgaW5kaWNhdGluZyB0aGUgbWlzc2luZyB2YWx1ZXMgYXJlIE1pc3NpbmcgQXQgUmFuZG9tIChNQVIpLiBJbiBvdGhlciB3b3JkcywgdGhlIHByb2JhYmlsaXR5IHRoYXQgYW4gT3pvbmUgdmFsdWUgaXMgbWlzc2luZyBpcyByZWxhdGVkIHRvIHRoZSBvYnNlcnZlZCB0ZW1wZXJhdHVyZS4gQWx0aG91Z2ggdGhlIGxhcmdlc3Qgc3dpbmdzIGluIHByb3BvcnRpb24gb2NjdXIgaW4gYmFuZHMgd2l0aCBzbWFsbGVyIHNhbXBsZSBzaXplcywgbWVhbmluZ2Z1bCBkaWZmZXJlbmNlcyByZW1haW4gaW4gbGFyZ2VyIGJhbmRzLgpgYGB7cn0KdGVtcF9wIDwtIGRhdGEgJT4lIAogIG11dGF0ZSh0ZW1wX2JhbmQgPSBjdXQoVGVtcCwgYnJlYWtzID0gYygwLDYwLDcwLDgwLDkwLEluZiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCI8PTYwIiwgIjYx4oCTNzAiLCAiNzHigJM4MCIsICI4MS05MCIsICI5MCsiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSBUUlVFKSkgJT4lIAogIGdyb3VwX2J5KHRlbXBfYmFuZCkgJT4lIAogIHN1bW1hcmlzZShwcm9wb3J0aW9uID0gc3VtKGlzLm5hKE96b25lKSkgLyBuKCksCiAgICAgICAgICAgIGJhbmRfdG90YWwgPSBuKCksCiAgICAgICAgICAgIG5hX3RvdGFsID0gc3VtKGlzLm5hKE96b25lKSkpCgprYWJsZSh0ZW1wX3ApCmBgYAoKIyMjIGUuCmBgYHtyfQpuZXcgPC0gZGF0YSAlPiUgbXV0YXRlKE96b25lMiA9IGlmZWxzZShpcy5uYShPem9uZSksIG1lYW4oT3pvbmUsIG5hLnJtID0gVFJVRSksIE96b25lKSkKCnBsb3RfZGZfbG9uZyA8LSBuZXcgJT4lCiAgc2VsZWN0KE96b25lLCBPem9uZTIpICU+JQogIHBpdm90X2xvbmdlcihldmVyeXRoaW5nKCksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlR5cGUiLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiVmFsdWUiKQoKRGVuLnBsdCA8LSBnZ3Bsb3QocGxvdF9kZl9sb25nLCBhZXMoeCA9IFZhbHVlLCBjb2xvciA9IFR5cGUpKSArCiAgc3RhdF9kZW5zaXR5KGdlb20gPSAibGluZSIsIGxpbmV3aWR0aCA9IDEuMiwgcG9zaXRpb24gPSAiaWRlbnRpdHkiLCBuYS5ybSA9IFRSVUUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiT3pvbmUiID0gImJsdWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPem9uZTIiID0gInJlZCIpKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRlbnNpdHk6IE9yaWdpbmFsIHZzIE1lYW4tSW1wdXRlZCBPem9uZSIsCiAgICBzdWJ0aXRsZSA9ICJDb21wYXJpc29uIG9mIERpc3RyaWJ1dGlvbnMiLAogICAgeCA9ICJPem9uZSIsCiAgICB5ID0gIkRlbnNpdHkiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZSgKICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4odCA9IDM1LCByID0gMjAsIGIgPSAzMCwgbCA9IDMwLCB1bml0ID0gInB0IikKICApCgpnZ3Bsb3RseShEZW4ucGx0KQpgYGAKV2hlbiBjb21wYXJpbmcgdGhlIGRlbnNpdHkgcGxvdCBvZiBPem9uZSB2cyBNZWFuIEltcHV0ZWQgT3pvbmUgdmFsdWVzIHRoZXJlIGlzIGEgY2xlYXIgc3Bpa2UgaW4gZGVuc2l0eSBpbiB0aGUgTWVhbiBJbXB1dGVkIE96b25lIGF0IHRoZSBtZWFuIG96b25lIHZhbHVlLgoKCiMjIyBmLgpUaGlzIHZpc3VhbCBzaG93cyB0aGUgaW1wdXRlZCB2YWx1ZXMgdGVuZCB0byBmb2xsb3cgdGhlIHNhbWUgZGlzdHJpYnV0aW9uIGFzIHRoZSBub24tbWlzc2luZyBvbmVzLgpgYGB7ciwgcmVzdWx0cyA9ICJoaWRlIn0KbWljZV9kYXRhIDwtIG1pY2UoZGF0YSwgc2VlZCA9IDEyMykKCm1pY2VfMSA8LSBmaWx0ZXIoY29tcGxldGUobWljZV9kYXRhLCAxKSwgaXMubmEoZGF0YSRPem9uZSkpCm1pY2VfMiA8LSBmaWx0ZXIoY29tcGxldGUobWljZV9kYXRhLCAyKSwgaXMubmEoZGF0YSRPem9uZSkpCgpnZ3Bsb3QoKSArCmdlb21fcG9pbnQoZGF0YSA9IGRhdGEsIGFlcyh4ID0gVGVtcCwgeSA9IE96b25lKSwgY29sb3IgPSAiZ3JleSIpICsKZ2VvbV9wb2ludChkYXRhID0gbWljZV8xLCBhZXMoeCA9IFRlbXAsIHkgPSBPem9uZSksIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArCmdlb21fcG9pbnQoZGF0YSA9IG1pY2VfMiwgYWVzKHggPSBUZW1wLCB5ID0gT3pvbmUpLCBjb2xvciA9ICJncmVlbiIsIGFscGhhID0gMC41KQpgYGAKCiMjIyBnLgpUaGUgdmFyaWFibGVzIHdpdGggdGhlIHN0cm9uZ2VzdCBwb3NpdGl2ZSBsaW5lYXIgcmVsYXRpb25zaGlwIGFyZSBUZW1wIGFuZCBPem9uZSwgd2l0aCBhIGNvcnJlbGF0aW9uIG9mIDAuNjU1LiBUaGlzIHJlbGF0aW9uc2hpcCBpcyBjbGVhcmx5IHJlZmxlY3RlZCBpbiB0aGVpciBzY2F0dGVycGxvdCwgd2hpY2ggc2hvd3MgYSBzdHJvbmcgdXB3YXJkIHRyZW5kIHdpdGggbW9zdCBwb2ludHMgY2x1c3RlcmVkIHRvZ2V0aGVyLCBpbmRpY2F0aW5nIHRoYXQgaGlnaGVyIHRlbXBzIGFyZSBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIG96b25lIGxldmVscy4gVGhlIHN0cm9uZ2VzdCBuZWdhdGl2ZSBsaW5lYXIgcmVsYXRpb25zaGlwIGlzIGJldHdlZW4gV2luZCBhbmQgT3pvbmUsIHdpdGggYSBjb3JyZWxhdGlvbiBvZiDiiJIwLjU3Ni4gVGhlaXIgc2NhdHRlcnBsb3QgcmVmbGVjdHMgdGhpcyBhcyB3ZWxsLCB3aXRoIHBvaW50cyBmb3JtaW5nIGEgY2xlYXIgZGVjcmVhc2luZyBwYXR0ZXJuLCBpbmRpY2F0aW5nIHRoYXQgaGlnaGVyIHdpbmQgc3BlZWRzIGFyZSBhc3NvY2lhdGVkIHdpdGggbG93ZXIgb3pvbmUgbGV2ZWxzLgpgYGB7cn0KZm1pY2UgPC0gY29tcGxldGUobWljZV9kYXRhLCAxKQpnZ3BhaXJzKGZtaWNlKQpgYGAKCiMjIyBoLgpUaGUgbGFyZ2VzdCBhbmQgZGFya2VzdCBibHVlIGNpcmNsZSBpcyBiZXR3ZWVuIFRlbXAgYW5kIE96b25lLCBhbmQgdGhlIGxhcmdlc3QgYW5kIGRhcmtlc3QgcmVkIGNpcmNsZSBpcyBiZXR3ZWVuIFdpbmQgYW5kIE96b25lLCBzdXBwb3J0aW5nIGFyZSBhYm92ZSBjb3JyZWxhdGlvbiBmaW5kaW5ncy4KYGBge3J9CmNvcl9tYXQgPC0gY29yKGZtaWNlKQpjb3JycGxvdC5taXhlZChjb3JfbWF0LCB1cHBlciA9ICJjaXJjbGUiLCBvcmRlciA9ICdBT0UnKQpgYGAKCiMjIyBpLgpUaGUgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdGhlc2UgdHdvIG9ic2VydmF0aW9ucyBpcyAxLgpgYGB7cn0KZGF0YV9pIDwtIGZtaWNlWzE6MixjKDUsNildCgpnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gZGF0YV9pLCBhZXMoeCA9IE1vbnRoLCB5ID0gRGF5KSkKCmFzLm1hdHJpeChkaXN0KGRhdGFfaSkpCmBgYAoKIyMjIGouClRoZSBNYW5oYXR0YW4gZGlzdGFuY2UgaXMgYWxzbyAxLiBUaGUgRXVjbGlkZWFuIGRpc3RhbmNlIGlzIGEgc3RyYWlnaHQgbGluZSBtZWFzdXJlLCB3aGVyZWFzLCB0aGUgTWFuaGF0dGFuIGRpc3RhbmNlIG1lYXN1cmVzIGFsb25nIGhvcml6b250YWwgYW5kIHZlcnRpY2FsIHBhdGhzLiBTaW5jZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9pbnRzIGlzIG9uZSB2ZXJ0aWNhbCBwYXRoLCB0aGVpciB0d28gZGlzdGFuY2VzIGFyZSB0aGUgc2FtZS4KYGBge3J9CmFzLm1hdHJpeChkaXN0KGRhdGFfaSwgbWV0aG9kID0gIm1hbmhhdHRhbiIpKQpgYGAKCiMjIyBrLgpUaGUgRXVjbGlkZWFuIGRpc3RhbmNlIGJldHdlZW4gdGhlIHR3byBvYnNlcnZhdGlvbnMgaXMgMS40MTQyMTQsIHdoaWxlIHRoZSBNYW5oYXR0YW4gZGlzdGFuY2UgaXMgMi4gVGhlIEV1Y2xpZGVhbiBkaXN0YW5jZSBpcyBzaG9ydGVyIGJlY2F1c2UgaXQgbWVhc3VyZXMgdGhlIHN0cmFpZ2h0IGxpbmUgZGlzdGFuY2UgYmV0d2VlbiB0aGUgdHdvIHBvaW50cy4gSW4gY29udHJhc3QsIHRoZSBNYW5oYXR0YW4gZGlzdGFuY2UgbWVhc3VyZXMgZGlzdGFuY2UgYWxvbmcgaG9yaXpvbnRhbCBhbmQgdmVydGljYWwgcGF0aHMsIG1lYW5pbmcgaXQgY2Fubm90IG1vdmUgZGlhZ29uYWxseSwgYW5kIGluIHRoaXMgY2FzZSB0aGUgcG9pbnRzIGFyZSBzZXBhcmF0ZWQgZGlhZ29uYWxseS4KYGBge3J9CmRhdGFfaSA8LSBmbWljZVtjKDEsMzMpLGMoNSw2KV0KCmdncGxvdCgpICsKICBnZW9tX3BvaW50KGRhdGEgPSBkYXRhX2ksIGFlcyh4ID0gTW9udGgsIHkgPSBEYXkpKQoKYXMubWF0cml4KGRpc3QoZGF0YV9pKSkKYXMubWF0cml4KGRpc3QoZGF0YV9pLCBtZXRob2QgPSAibWFuaGF0dGFuIikpCmBgYAoKIyMjIGwuCmBgYHtyfQpzX2RhdGEgPC0gbXV0YXRlKGZtaWNlLCBhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH5zY2FsZSguKSAlPiUgYXMudmVjdG9yKSkKYGBgClRoZSBmaXJzdCBvYnNlcnZhdGlvbiBoYWQgYW4gT3pvbmUgdmFsdWUgb2YgYHIgZm1pY2VbMSwxXWAgc3RhbmRhcmRpemVkIHRvIGByIHNfZGF0YVsxLDFdYC4gVGhpcyBzdGFuZGFyZGl6ZWQgdmFsdWUgbWVhbnMgdGhlIG9yaWdpbmFsIHZhbHVlIHdhcyBgciBzX2RhdGFbMSwxXWAgc3RhbmRhcmQgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuIG96b25lIHZhbHVlLiBXZSBjYW4gY2hlY2sgdGhpcyBieSBnZXR0aW5nIHRoZSBtZWFuIG9mIE96b25lLCBgciBtZWFuKGZtaWNlJE96b25lKWAsIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2Ygb3pvbmUsIGByIHNkKGZtaWNlJE96b25lKWAsIGFuZCBzZWVpbmcgaG93IG1hbnkgc3RhbmRhcmQgZGV2aWF0aW9ucyB3ZXJlIGZyb20gaXQuIE91ciBwb2ludCBgciBmbWljZVsxLDFdYCAtIHRoZSBtZWFuIGByIG1lYW4oZm1pY2UkT3pvbmUpYCBlcXVhbHMgYHIgZm1pY2VbMSwxXSAtIG1lYW4oZm1pY2UkT3pvbmUpYC4gVGhpcyBpcyB0aGUgZGlzdGFuY2UgZnJvbSB0aGUgbWVhbiwgbm93IGRpdmlkZSBieSB0aGUgc3RhbmRhcmQgZGV2aWF0aW9uIGFuZCB3ZSBnZXQsIGByIChmbWljZVsxLDFdIC0gbWVhbihmbWljZSRPem9uZSkpIC8gc2QoZm1pY2UkT3pvbmUpIGAuIFdoaWNoIGlzIHRoZSBzYW1lIGFzIHRoZSBzdGFuZGFyZGl6ZWQgc2NvcmUuCgojIyMgbS4KVGhlIG5lYXJlc3QgbmVpZ2hib3JzIHRvIG9ic2VydmF0aW9uIDEgYXJlIG9ic2VydmF0aW9ucyAyLCAxMCwgYW5kIDcsIHdpdGggb2JzZXJ2YXRpb24gMiBiZWluZyB0aGUgY2xvc2VzdC4gVGhlIG5lYXJlc3QgbmVpZ2hib3JzIHRvIG9ic2VydmF0aW9uIDIgYXJlIG9ic2VydmF0aW9ucyAxLCAxMCwgYW5kIDM4LCB3aXRoIG9ic2VydmF0aW9uIDEgYmVpbmcgdGhlIGNsb3Nlc3QuCmBgYHtyfQpkX3ogPC0gZGlzdChzX2RhdGEpCnJlc3VsdCA8LSBrTk4oeCA9IGRfeiwgayA9IDMsIHNlYXJjaCA9ICJkaXN0IikKcmVzdWx0JGlkWzE6NCwgXSAgIApyZXN1bHQkZGlzdFsxOjQsIF0gCgpgYGAKIyMgUXVlc3Rpb24gMgoKTXkgdG9wIHByZWZlcmVuY2Ugd291bGQgYmUgYW5hbHl6aW5nIGVjb25vbWljL2ZpbmFuY2lhbCBkYXRhLCBlc3BlY2lhbGx5IGxvb2tpbmcgYXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIG1vbmV5IHN1cHBseSwgaW5mbGF0aW9uLCBjb25zdW1lciBwcmljZXMsIHdhZ2VzLCBldGMuCgpNeSBzZWNvbmQgcHJlZmVyZW5jZSB3b3VsZCBiZSB3b3JraW5nIHdpdGggbWVudGFsIGhlYWx0aCBvciBzdXJ2ZXkgZGF0YSwgZm9yIGV4YW1wbGUgZXhhbWluaW5nIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBtZWRpY2F0aW9uIHVzZSwgaGFiaXRzLCBhbmQgd2VsbCBiZWluZyBvdXRjb21lcy4KCk15IHRoaXJkIHByZWZlcmVuY2Ugd291bGQgYmUgc3BvcnRzIGFuYWx5dGljcywgd291bGQgYmUgZmluZSB3aXRoIGFueXRoaW5nLg==