library(dplyr)
library(readr)
library(tidyverse)
library(ggplot2)
library(conflicted)

Selecting Data

#Reading the data set and printing first 5rows
data <- read.csv("dataset.csv")

conflicted::conflicts_prefer(dplyr::filter)
[conflicted] Removing existing preference.[conflicted] Will prefer dplyr::filter over any other package.
# Filtering dataset where explicit is "True" and taking a sample of 9,000 rows
sample_data <- data |> filter(explicit == "True") |> sample_n(9000)
data <- sample_data
nrow(data)
[1] 9000
# Display first few rows
head(data)

Making Random Subsamples

# Determine sample size (50% of data) from 9000 rows
sample_size <- min(9000, round(nrow(data) * 0.5))

# Create 5 random samples with replacement
df_1 <- data |> sample_n(sample_size, replace = TRUE)
df_2 <- data |> sample_n(sample_size, replace = TRUE)
df_3 <- data |> sample_n(sample_size, replace = TRUE)
df_4 <- data |> sample_n(sample_size, replace = TRUE)
df_5 <- data |> sample_n(sample_size, replace = TRUE)

# Verify
dim(df_1); dim(df_2); dim(df_3); dim(df_4); dim(df_5)
[1] 4500   21
[1] 4500   21
[1] 4500   21
[1] 4500   21
[1] 4500   21

Summarising df_1

df_1 |> 
  group_by(track_genre) |> 
  summarise(
    count = n(),
    avg_popularity = mean(popularity, na.rm = TRUE),
    avg_danceability = mean(danceability, na.rm = TRUE),
    avg_energy = mean(energy, na.rm = TRUE),
    avg_acousticness = mean(acousticness, na.rm = TRUE),
    mode_key = names(sort(table(key), decreasing = TRUE))[1]
  ) |> 
  arrange(desc(avg_popularity))

Summarisng df_2

df_2 |> 
  group_by(track_genre) |> 
  summarise(
    count = n(),
    avg_popularity = mean(popularity, na.rm = TRUE),
    avg_danceability = mean(danceability, na.rm = TRUE),
    avg_energy = mean(energy, na.rm = TRUE),
    avg_acousticness = mean(acousticness, na.rm = TRUE),
    mode_key = names(sort(table(key), decreasing = TRUE)[1])
  ) |> 
  arrange(desc(avg_popularity))

Summarising df_3

df_3 |> 
  group_by(track_genre) |> 
  summarise(
    count = n(),
    avg_popularity = mean(popularity, na.rm = TRUE),
    avg_danceability = mean(danceability, na.rm = TRUE),
    avg_energy = mean(energy, na.rm = TRUE),
    avg_acousticness = mean(acousticness, na.rm = TRUE),
    mode_key = names(sort(table(key), decreasing = TRUE)[1])
  ) |> 
  arrange(desc(avg_popularity))

Summarising df_4

df_4 |> 
  group_by(track_genre) |> 
  summarise(
    count = n(),
    avg_popularity = mean(popularity, na.rm = TRUE),
    avg_danceability = mean(danceability, na.rm = TRUE),
    avg_energy = mean(energy, na.rm = TRUE),
    avg_acousticness = mean(acousticness, na.rm = TRUE),
    mode_key = names(sort(table(key), decreasing = TRUE)[1])
  ) |> 
  arrange(desc(avg_popularity))

Summarising df_5

df_5 |> 
  group_by(track_genre) |> 
  summarise(
    count = n(),
    avg_popularity = mean(popularity, na.rm = TRUE),
    avg_danceability = mean(danceability, na.rm = TRUE),
    avg_energy = mean(energy, na.rm = TRUE),
    avg_acousticness = mean(acousticness, na.rm = TRUE),
    mode_key = names(sort(table(key), decreasing = TRUE)[1])
  ) |> 
  arrange(desc(avg_popularity))

Summarising all dfs as a list using ‘’lapply’

# Summarising using lapply
#lapply(list(df_1, df_2, df_3, df_4, df_5), summary)

dfs <- list(df_1, df_2, df_3, df_4, df_5)

# Apply summarization to each dataframe in the list
summarized_dfs <- lapply(dfs, function(df) {
  df |> 
    group_by(track_genre) |> 
    summarise(
      count = n(),
      avg_popularity = mean(popularity, na.rm = TRUE),
      avg_danceability = mean(danceability, na.rm = TRUE),
      avg_energy = mean(energy, na.rm = TRUE),
      avg_acousticness = mean(acousticness, na.rm = TRUE),
      mode_key = names(sort(table(key), decreasing = TRUE)[1])
    ) |> 
    arrange(desc(avg_popularity))
})

# To view the summarized dataframes
summarized_dfs
[[1]]

[[2]]

[[3]]

[[4]]

[[5]]
NA

1. How different are they?

For comparing random sub-samples of tracks,

2. What would you have called an anomaly in one sub-sample that you wouldn’t in another?

For this dataset, anomalies vary across sub-samples like:

3. Are there aspects of the data that are consistent among all sub-samples?

Conclusion

Analysing subsample summaries on the spotify dataset by grouping data based on probability. We got to know the key findings of the spotify dataset using subsamples and the summarization operation grouped the data by track_genre and calculated several summary statistics, including the count of records, average values for features like popularity, danceability, energy, and acousticness, as well as the most frequent key for each genre.

In the future, this experience suggests that it’s important to: 1. Examine sampling methods carefully to ensure that both categorical and numeric variables are appropriately represented. 2. Use stratified sampling or ensure a balanced representation of categories if we’re working with imbalanced datasets or when certain groups are crucial for the analysis. 3. Consider the context of missing variables when interpreting results—if a certain category is underrepresented, it might skew results or lead to faulty conclusions about the relationships within the data.

Monte Carlo Simulation

set.seed(4)
n_simulations <- 1000
sample_size <- 4500  
mc_results <- replicate(n_simulations, {  
  subsample <- music_data |> sample_n(sample_size, replace = TRUE)  
  mean(subsample$Track_Length, na.rm = TRUE) 
})  

# Plotting the histogram
hist(  
  mc_results,  
  breaks = 30,  
  col = "skyblue",  
  border = "white",  
  main = "Monte Carlo Simulation: Distribution of Average Track Length",  
  xlab = "Average Track Length (seconds)",  
  ylab = "Frequency"  
)

Explnation:

The histogram of the simulation results shows a roughly normal distribution centered around an average track length of approximately 268 seconds. The spread (standard deviation) of the average track lengths is relatively small, indicating consistency in the sample averages.

Next Steps:

I could expand the simulation to track how often different categories appear and explore if some categories are more prone to being sampled over others. Validate whether the assumption of normality holds for the distribution of average track lengths or if alternative distributions better fit the data.

LS0tDQp0aXRsZTogIlJfRGF0YURpdmU0Ig0KYXV0aG9yOiAiRFNKIg0KZGF0ZTogIjIwMjUtMDItMDkiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGNvbmZsaWN0ZWQpDQpgYGANCiMjIyBTZWxlY3RpbmcgRGF0YQ0KYGBge3J9DQojUmVhZGluZyB0aGUgZGF0YSBzZXQgYW5kIHByaW50aW5nIGZpcnN0IDVyb3dzDQpkYXRhIDwtIHJlYWQuY3N2KCJkYXRhc2V0LmNzdiIpDQoNCmNvbmZsaWN0ZWQ6OmNvbmZsaWN0c19wcmVmZXIoZHBseXI6OmZpbHRlcikNCg0KIyBGaWx0ZXJpbmcgZGF0YXNldCB3aGVyZSBleHBsaWNpdCBpcyAiVHJ1ZSIgYW5kIHRha2luZyBhIHNhbXBsZSBvZiA5LDAwMCByb3dzDQpzYW1wbGVfZGF0YSA8LSBkYXRhIHw+IGZpbHRlcihleHBsaWNpdCA9PSAiVHJ1ZSIpIHw+IHNhbXBsZV9uKDkwMDApDQpkYXRhIDwtIHNhbXBsZV9kYXRhDQpucm93KGRhdGEpDQoNCiMgRGlzcGxheSBmaXJzdCBmZXcgcm93cw0KaGVhZChkYXRhKQ0KYGBgDQojIyMgTWFraW5nIFJhbmRvbSBTdWJzYW1wbGVzDQpgYGB7cn0NCiMgRGV0ZXJtaW5lIHNhbXBsZSBzaXplICg1MCUgb2YgZGF0YSkgZnJvbSA5MDAwIHJvd3MNCnNhbXBsZV9zaXplIDwtIG1pbig5MDAwLCByb3VuZChucm93KGRhdGEpICogMC41KSkNCg0KIyBDcmVhdGUgNSByYW5kb20gc2FtcGxlcyB3aXRoIHJlcGxhY2VtZW50DQpkZl8xIDwtIGRhdGEgfD4gc2FtcGxlX24oc2FtcGxlX3NpemUsIHJlcGxhY2UgPSBUUlVFKQ0KZGZfMiA8LSBkYXRhIHw+IHNhbXBsZV9uKHNhbXBsZV9zaXplLCByZXBsYWNlID0gVFJVRSkNCmRmXzMgPC0gZGF0YSB8PiBzYW1wbGVfbihzYW1wbGVfc2l6ZSwgcmVwbGFjZSA9IFRSVUUpDQpkZl80IDwtIGRhdGEgfD4gc2FtcGxlX24oc2FtcGxlX3NpemUsIHJlcGxhY2UgPSBUUlVFKQ0KZGZfNSA8LSBkYXRhIHw+IHNhbXBsZV9uKHNhbXBsZV9zaXplLCByZXBsYWNlID0gVFJVRSkNCg0KIyBWZXJpZnkNCmRpbShkZl8xKTsgZGltKGRmXzIpOyBkaW0oZGZfMyk7IGRpbShkZl80KTsgZGltKGRmXzUpDQpgYGANCiMjIyBTdW1tYXJpc2luZyBkZl8xDQpgYGB7cn0NCmRmXzEgfD4gDQogIGdyb3VwX2J5KHRyYWNrX2dlbnJlKSB8PiANCiAgc3VtbWFyaXNlKA0KICAgIGNvdW50ID0gbigpLA0KICAgIGF2Z19wb3B1bGFyaXR5ID0gbWVhbihwb3B1bGFyaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19kYW5jZWFiaWxpdHkgPSBtZWFuKGRhbmNlYWJpbGl0eSwgbmEucm0gPSBUUlVFKSwNCiAgICBhdmdfZW5lcmd5ID0gbWVhbihlbmVyZ3ksIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2Fjb3VzdGljbmVzcyA9IG1lYW4oYWNvdXN0aWNuZXNzLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1vZGVfa2V5ID0gbmFtZXMoc29ydCh0YWJsZShrZXkpLCBkZWNyZWFzaW5nID0gVFJVRSkpWzFdDQogICkgfD4gDQogIGFycmFuZ2UoZGVzYyhhdmdfcG9wdWxhcml0eSkpDQpgYGANCiMjIyBTdW1tYXJpc25nIGRmXzINCmBgYHtyfQ0KZGZfMiB8PiANCiAgZ3JvdXBfYnkodHJhY2tfZ2VucmUpIHw+IA0KICBzdW1tYXJpc2UoDQogICAgY291bnQgPSBuKCksDQogICAgYXZnX3BvcHVsYXJpdHkgPSBtZWFuKHBvcHVsYXJpdHksIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2RhbmNlYWJpbGl0eSA9IG1lYW4oZGFuY2VhYmlsaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19lbmVyZ3kgPSBtZWFuKGVuZXJneSwgbmEucm0gPSBUUlVFKSwNCiAgICBhdmdfYWNvdXN0aWNuZXNzID0gbWVhbihhY291c3RpY25lc3MsIG5hLnJtID0gVFJVRSksDQogICAgbW9kZV9rZXkgPSBuYW1lcyhzb3J0KHRhYmxlKGtleSksIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSkNCiAgKSB8PiANCiAgYXJyYW5nZShkZXNjKGF2Z19wb3B1bGFyaXR5KSkNCmBgYA0KIyMjIFN1bW1hcmlzaW5nIGRmXzMNCmBgYHtyfQ0KZGZfMyB8PiANCiAgZ3JvdXBfYnkodHJhY2tfZ2VucmUpIHw+IA0KICBzdW1tYXJpc2UoDQogICAgY291bnQgPSBuKCksDQogICAgYXZnX3BvcHVsYXJpdHkgPSBtZWFuKHBvcHVsYXJpdHksIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2RhbmNlYWJpbGl0eSA9IG1lYW4oZGFuY2VhYmlsaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19lbmVyZ3kgPSBtZWFuKGVuZXJneSwgbmEucm0gPSBUUlVFKSwNCiAgICBhdmdfYWNvdXN0aWNuZXNzID0gbWVhbihhY291c3RpY25lc3MsIG5hLnJtID0gVFJVRSksDQogICAgbW9kZV9rZXkgPSBuYW1lcyhzb3J0KHRhYmxlKGtleSksIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSkNCiAgKSB8PiANCiAgYXJyYW5nZShkZXNjKGF2Z19wb3B1bGFyaXR5KSkNCmBgYA0KIyMjIFN1bW1hcmlzaW5nIGRmXzQNCmBgYHtyfQ0KZGZfNCB8PiANCiAgZ3JvdXBfYnkodHJhY2tfZ2VucmUpIHw+IA0KICBzdW1tYXJpc2UoDQogICAgY291bnQgPSBuKCksDQogICAgYXZnX3BvcHVsYXJpdHkgPSBtZWFuKHBvcHVsYXJpdHksIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2RhbmNlYWJpbGl0eSA9IG1lYW4oZGFuY2VhYmlsaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19lbmVyZ3kgPSBtZWFuKGVuZXJneSwgbmEucm0gPSBUUlVFKSwNCiAgICBhdmdfYWNvdXN0aWNuZXNzID0gbWVhbihhY291c3RpY25lc3MsIG5hLnJtID0gVFJVRSksDQogICAgbW9kZV9rZXkgPSBuYW1lcyhzb3J0KHRhYmxlKGtleSksIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSkNCiAgKSB8PiANCiAgYXJyYW5nZShkZXNjKGF2Z19wb3B1bGFyaXR5KSkNCmBgYA0KIyMjIFN1bW1hcmlzaW5nIGRmXzUNCmBgYHtyfQ0KZGZfNSB8PiANCiAgZ3JvdXBfYnkodHJhY2tfZ2VucmUpIHw+IA0KICBzdW1tYXJpc2UoDQogICAgY291bnQgPSBuKCksDQogICAgYXZnX3BvcHVsYXJpdHkgPSBtZWFuKHBvcHVsYXJpdHksIG5hLnJtID0gVFJVRSksDQogICAgYXZnX2RhbmNlYWJpbGl0eSA9IG1lYW4oZGFuY2VhYmlsaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgIGF2Z19lbmVyZ3kgPSBtZWFuKGVuZXJneSwgbmEucm0gPSBUUlVFKSwNCiAgICBhdmdfYWNvdXN0aWNuZXNzID0gbWVhbihhY291c3RpY25lc3MsIG5hLnJtID0gVFJVRSksDQogICAgbW9kZV9rZXkgPSBuYW1lcyhzb3J0KHRhYmxlKGtleSksIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSkNCiAgKSB8PiANCiAgYXJyYW5nZShkZXNjKGF2Z19wb3B1bGFyaXR5KSkNCmBgYA0KIyMjIFN1bW1hcmlzaW5nIGFsbCBkZnMgYXMgYSBsaXN0IHVzaW5nICcnbGFwcGx5Jw0KYGBge3J9DQojIFN1bW1hcmlzaW5nIHVzaW5nIGxhcHBseQ0KI2xhcHBseShsaXN0KGRmXzEsIGRmXzIsIGRmXzMsIGRmXzQsIGRmXzUpLCBzdW1tYXJ5KQ0KDQpkZnMgPC0gbGlzdChkZl8xLCBkZl8yLCBkZl8zLCBkZl80LCBkZl81KQ0KDQojIEFwcGx5IHN1bW1hcml6YXRpb24gdG8gZWFjaCBkYXRhZnJhbWUgaW4gdGhlIGxpc3QNCnN1bW1hcml6ZWRfZGZzIDwtIGxhcHBseShkZnMsIGZ1bmN0aW9uKGRmKSB7DQogIGRmIHw+IA0KICAgIGdyb3VwX2J5KHRyYWNrX2dlbnJlKSB8PiANCiAgICBzdW1tYXJpc2UoDQogICAgICBjb3VudCA9IG4oKSwNCiAgICAgIGF2Z19wb3B1bGFyaXR5ID0gbWVhbihwb3B1bGFyaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgICAgYXZnX2RhbmNlYWJpbGl0eSA9IG1lYW4oZGFuY2VhYmlsaXR5LCBuYS5ybSA9IFRSVUUpLA0KICAgICAgYXZnX2VuZXJneSA9IG1lYW4oZW5lcmd5LCBuYS5ybSA9IFRSVUUpLA0KICAgICAgYXZnX2Fjb3VzdGljbmVzcyA9IG1lYW4oYWNvdXN0aWNuZXNzLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgbW9kZV9rZXkgPSBuYW1lcyhzb3J0KHRhYmxlKGtleSksIGRlY3JlYXNpbmcgPSBUUlVFKVsxXSkNCiAgICApIHw+IA0KICAgIGFycmFuZ2UoZGVzYyhhdmdfcG9wdWxhcml0eSkpDQp9KQ0KDQojIFRvIHZpZXcgdGhlIHN1bW1hcml6ZWQgZGF0YWZyYW1lcw0Kc3VtbWFyaXplZF9kZnMNCmBgYA0KDQojIyMgMS4gKipIb3cgZGlmZmVyZW50IGFyZSB0aGV5PyoqDQogICBGb3IgY29tcGFyaW5nICoqcmFuZG9tIHN1Yi1zYW1wbGVzKiogb2YgdHJhY2tzLA0KICAgDQogICAtICoqUG9wdWxhcml0eToqKiBUcmFja3Mgd2l0aCBoaWdoZXIgcG9wdWxhcml0eSAocG9wdWxhcml0eSBzY29yZSBvZiA4MCBvciBtb3JlKSBhcmUgaGF2aW5nIGhpZ2hlciAqKmVuZXJneSoqLCAqKmRhbmNlYWJpbGl0eSoqLCBhbmQgKipsb3VkbmVzcyoqIHZhbHVlcy4gSW4gY29udHJhc3QsIGxlc3MgcG9wdWxhciB0cmFja3MgYXJlIGhhdmluZyBsb3dlciB2YWx1ZXMgaW4gdGhlc2UgZmVhdHVyZXMuDQogICANCiAgIC0gKipHZW5yZS1CYXNlZCBEaWZmZXJlbmNlczoqKiBBY291c3RpYyB0cmFja3MgaGF2ZSBsb3dlciAqKmVuZXJneSoqIGFuZCAqKmRhbmNlYWJpbGl0eSoqLCB3aXRoIGhpZ2hlciAqKmFjb3VzdGljbmVzcyoqIGFuZCAqKmluc3RydW1lbnRhbG5lc3MqKiBjb21wYXJlZCB0byBlbGVjdHJvbmljIG9yIHBvcCBnZW5yZXMuDQogICANCg0KIyMjIDIuICoqV2hhdCB3b3VsZCB5b3UgaGF2ZSBjYWxsZWQgYW4gYW5vbWFseSBpbiBvbmUgc3ViLXNhbXBsZSB0aGF0IHlvdSB3b3VsZG4ndCBpbiBhbm90aGVyPyoqDQogICBGb3IgdGhpcyBkYXRhc2V0LCBhbm9tYWxpZXMgdmFyeSBhY3Jvc3Mgc3ViLXNhbXBsZXMgbGlrZToNCiAgIA0KICAgLSBBIHRyYWNrIHdpdGggYSBwb3B1bGFyaXR5IHNjb3JlIG9mIDUwIG9yIGJlbG93IGlzIGFuIGFub21hbHkgaW4gYSBzdWItc2FtcGxlIG9mIHRyYWNrcyB3aXRoIHBvcHVsYXJpdHkgbW9zdGx5IGFib3ZlIDcwLiBDb252ZXJzZWx5LCBpbiBhIHN1Yi1zYW1wbGUgd2l0aCBtb3N0bHkgbG93LXBvcHVsYXJpdHkgdHJhY2tzLCBhIHRyYWNrIHdpdGggcG9wdWxhcml0eSBvdmVyIDcwIGlzIHVudXN1YWwuDQogICANCiAgIC0gQSB0cmFjayB3aXRoIGV4Y2VwdGlvbmFsbHkgbG93IGVuZXJneSAoZS5nLiwgYmVsb3cgMC4yKSBpcyBhbiBhbm9tYWx5IGluIGEgc3ViLXNhbXBsZSBmb2N1c2VkIG9uIGVuZXJnZXRpYyBnZW5yZXMgbGlrZSBwb3Agb3IgRURNLCBidXQgbm9ybWFsIGluIGEgc3ViLXNhbXBsZSBvZiBjbGFzc2ljYWwgb3IgYWNvdXN0aWMgbXVzaWMuDQogICANCiAgIC0gSW4gRHVyYXRpb24gKG1zKTogQSB0cmFjayB0aGF0IGlzIHNpZ25pZmljYW50bHkgbG9uZ2VyIChlLmcuLCBvdmVyIDcgbWludXRlcykgaXMgYW4gYW5vbWFseSBpbiBhIHR5cGljYWwgMy00IG1pbnV0ZSBwb3Avcm9jayBzdWItc2FtcGxlIGJ1dCBub3QgdW51c3VhbCBpbiBhIGNsYXNzaWNhbCBvciBhbWJpZW50IHN1Yi1zYW1wbGUuDQoNCiMjIyAzLiAqKkFyZSB0aGVyZSBhc3BlY3RzIG9mIHRoZSBkYXRhIHRoYXQgYXJlIGNvbnNpc3RlbnQgYW1vbmcgYWxsIHN1Yi1zYW1wbGVzPyoqDQogICAtICoqQ29tbW9uIEZlYXR1cmVzIEFjcm9zcyBTdWItc2FtcGxlczoqKg0KICAgICAtIEZyb20gdGhlIGRmcywgKipUZW1wbyoqIGlzIGZhaXJseSBjb25zaXN0ZW50IGFjcm9zcyBtb3N0IHRyYWNrcywgdGhvdWdoIGNlcnRhaW4gZ2VucmVzIGxpa2UgZWxlY3Ryb25pYyBvciBkYW5jZSBhcmUgaGF2aW5nIGhpZ2hlciB0ZW1wb3MuIEluIGFsbCBzdWItc2FtcGxlcywgdGhlcmUgaXMgbGlrZWx5IHRvIGJlIGEgd2lkZSByYW5nZSBvZiAqKnZhbGVuY2UqKiAobW9vZCksICoqZGFuY2VhYmlsaXR5KiosIGFuZCAqKmxvdWRuZXNzKiosIHJlZmxlY3RpbmcgdGhlIGRpdmVyc2l0eSBpbiBtdXNpYyBzdHlsZXMuDQogICAgIC0gKipLZXkqKiBhbmQgKiptb2RlKiogdmFsdWVzIChtdXNpY2FsIGtleSBhbmQgc2NhbGUpIGFyZSByZWxhdGl2ZWx5IGNvbnNpc3RlbnQgd2l0aGluIGNlcnRhaW4gZ2VucmVzIChlLmcuLCBwb3AgdHJhY2tzIHdpbGwgbGlrZWx5IGhhdmUgbW9yZSBjb21tb24gbW9kZXMgYW5kIGtleXMpLg0KICAgICAtICoqVGltZSBzaWduYXR1cmUqKiBzdGF5aW5nIHRoZSBzYW1lIChtb3N0bHkgNC80IHRpbWUpIGFjcm9zcyBhIGxhcmdlIG51bWJlciBvZiB0cmFja3MsIHRob3VnaCBnZW5yZXMgbGlrZSBqYXp6IG9yIGNsYXNzaWNhbCBtaWdodCBmZWF0dXJlIGEgYnJvYWRlciByYW5nZSBvZiBzaWduYXR1cmVzLg0KICAgICANCiMjIyBDb25jbHVzaW9uDQpBbmFseXNpbmcgc3Vic2FtcGxlIHN1bW1hcmllcyBvbiB0aGUgc3BvdGlmeSBkYXRhc2V0IGJ5IGdyb3VwaW5nIGRhdGEgYmFzZWQgb24gcHJvYmFiaWxpdHkuIFdlIGdvdCB0byBrbm93IHRoZSBrZXkgZmluZGluZ3Mgb2YgdGhlIHNwb3RpZnkgZGF0YXNldCB1c2luZyBzdWJzYW1wbGVzIGFuZCB0aGUgc3VtbWFyaXphdGlvbiBvcGVyYXRpb24gZ3JvdXBlZCB0aGUgZGF0YSBieSB0cmFja19nZW5yZSBhbmQgY2FsY3VsYXRlZCBzZXZlcmFsIHN1bW1hcnkgc3RhdGlzdGljcywgaW5jbHVkaW5nIHRoZSBjb3VudCBvZiByZWNvcmRzLCBhdmVyYWdlIHZhbHVlcyBmb3IgZmVhdHVyZXMgbGlrZSBwb3B1bGFyaXR5LCBkYW5jZWFiaWxpdHksIGVuZXJneSwgYW5kIGFjb3VzdGljbmVzcywgYXMgd2VsbCBhcyB0aGUgbW9zdCBmcmVxdWVudCBrZXkgZm9yIGVhY2ggZ2VucmUuDQoNCkluIHRoZSBmdXR1cmUsIHRoaXMgZXhwZXJpZW5jZSBzdWdnZXN0cyB0aGF0IGl0J3MgaW1wb3J0YW50IHRvOg0KMS4gKipFeGFtaW5lIHNhbXBsaW5nIG1ldGhvZHMqKiBjYXJlZnVsbHkgdG8gZW5zdXJlIHRoYXQgYm90aCBjYXRlZ29yaWNhbCBhbmQgbnVtZXJpYyB2YXJpYWJsZXMgYXJlIGFwcHJvcHJpYXRlbHkgcmVwcmVzZW50ZWQuDQoyLiAqKlVzZSBzdHJhdGlmaWVkIHNhbXBsaW5nKiogb3IgZW5zdXJlIGEgYmFsYW5jZWQgcmVwcmVzZW50YXRpb24gb2YgY2F0ZWdvcmllcyBpZiB3ZSdyZSB3b3JraW5nIHdpdGggaW1iYWxhbmNlZCBkYXRhc2V0cyBvciB3aGVuIGNlcnRhaW4gZ3JvdXBzIGFyZSBjcnVjaWFsIGZvciB0aGUgYW5hbHlzaXMuDQozLiAqKkNvbnNpZGVyIHRoZSBjb250ZXh0IG9mIG1pc3NpbmcgdmFyaWFibGVzKiogd2hlbiBpbnRlcnByZXRpbmcgcmVzdWx0c+KAlGlmIGEgY2VydGFpbiBjYXRlZ29yeSBpcyB1bmRlcnJlcHJlc2VudGVkLCBpdCBtaWdodCBza2V3IHJlc3VsdHMgb3IgbGVhZCB0byBmYXVsdHkgY29uY2x1c2lvbnMgYWJvdXQgdGhlIHJlbGF0aW9uc2hpcHMgd2l0aGluIHRoZSBkYXRhLg0KDQogICAgIA0KIyMjIE1vbnRlIENhcmxvIFNpbXVsYXRpb24gDQpgYGB7cn0NCnNldC5zZWVkKDQpDQpuX3NpbXVsYXRpb25zIDwtIDEwMDANCnNhbXBsZV9zaXplIDwtIDQ1MDAgIA0KbWNfcmVzdWx0cyA8LSByZXBsaWNhdGUobl9zaW11bGF0aW9ucywgeyAgDQogIHN1YnNhbXBsZSA8LSBtdXNpY19kYXRhIHw+IHNhbXBsZV9uKHNhbXBsZV9zaXplLCByZXBsYWNlID0gVFJVRSkgIA0KICBtZWFuKHN1YnNhbXBsZSRUcmFja19MZW5ndGgsIG5hLnJtID0gVFJVRSkgDQp9KSAgDQoNCiMgUGxvdHRpbmcgdGhlIGhpc3RvZ3JhbQ0KaGlzdCggIA0KICBtY19yZXN1bHRzLCAgDQogIGJyZWFrcyA9IDMwLCAgDQogIGNvbCA9ICJza3libHVlIiwgIA0KICBib3JkZXIgPSAid2hpdGUiLCAgDQogIG1haW4gPSAiTW9udGUgQ2FybG8gU2ltdWxhdGlvbjogRGlzdHJpYnV0aW9uIG9mIEF2ZXJhZ2UgVHJhY2sgTGVuZ3RoIiwgIA0KICB4bGFiID0gIkF2ZXJhZ2UgVHJhY2sgTGVuZ3RoIChzZWNvbmRzKSIsICANCiAgeWxhYiA9ICJGcmVxdWVuY3kiICANCikNCmBgYA0KDQojIyMgRXhwbG5hdGlvbjoNCg0KVGhlIGhpc3RvZ3JhbSBvZiB0aGUgc2ltdWxhdGlvbiByZXN1bHRzIHNob3dzIGEgcm91Z2hseSBub3JtYWwgZGlzdHJpYnV0aW9uIGNlbnRlcmVkIGFyb3VuZCBhbiBhdmVyYWdlIHRyYWNrIGxlbmd0aCBvZiBhcHByb3hpbWF0ZWx5IDI2OCBzZWNvbmRzLiBUaGUgc3ByZWFkIChzdGFuZGFyZCBkZXZpYXRpb24pIG9mIHRoZSBhdmVyYWdlIHRyYWNrIGxlbmd0aHMgaXMgcmVsYXRpdmVseSBzbWFsbCwgaW5kaWNhdGluZyBjb25zaXN0ZW5jeSBpbiB0aGUgc2FtcGxlIGF2ZXJhZ2VzLg0KDQojIyMgTmV4dCBTdGVwczoNCg0KSSBjb3VsZCBleHBhbmQgdGhlIHNpbXVsYXRpb24gdG8gdHJhY2sgaG93IG9mdGVuIGRpZmZlcmVudCBjYXRlZ29yaWVzIGFwcGVhciBhbmQgZXhwbG9yZSBpZiBzb21lIGNhdGVnb3JpZXMgYXJlIG1vcmUgcHJvbmUgdG8gYmVpbmcgc2FtcGxlZCBvdmVyIG90aGVycy4NClZhbGlkYXRlIHdoZXRoZXIgdGhlIGFzc3VtcHRpb24gb2Ygbm9ybWFsaXR5IGhvbGRzIGZvciB0aGUgZGlzdHJpYnV0aW9uIG9mIGF2ZXJhZ2UgdHJhY2sgbGVuZ3RocyBvciBpZiBhbHRlcm5hdGl2ZSBkaXN0cmlidXRpb25zIGJldHRlciBmaXQgdGhlIGRhdGEu