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)
temp_band proportion band_total na_total
<=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==