library(tidyverse)
library(openintro)

The assignment requires completion of exercises in chapter 4 of the Diez (2019) textbook. The exercises include 4.2, 4.4, and 4.8. Each exercise has its own section and heading within this report. In addition, it requires Lab Chapter 4 from OpenIntro Textbook: https://openintrostat.github.io/oilabs-tidy/04_normal_distribution/normal_distribution.html

#Module 4 Homework

##Exercise 4.2

Explination

The solution calculates the percentages of a standard normal distribution N (0,1) within specific regions using the cumulative distribution function (CDF). According to Elassaiss-Schaap and Duisters (2020), studies reveal that the normal distribution’s standard deviation cannot exceed half the mean without extending into negative values, whereas the lognormal distribution effectively spans beyond this range without producing negative values. For Z greater than -1.13, the percentage is 87.14%, which is calculated by 111 minus the CDF of -1.13, which gives the area to the right of Z equals −1.13. For Z less than 0.18, the percentage is 57.13%, which is calculated by the CDF of 0.18, representing the area to the left of Z equaling 0.18. The percentage for Z greater than 8 is effectively 0.00%, which is calculated by 111 minus the CDF of 8 being negligible, indicating an area almost zero due to the extreme value being far in the tail. Absolute values function as a universal measure that standardizes preferences, allowing for consistent comparisons across different contexts with varying options (Solomyak et al., 2022). The absolute value of Z less than 0.5, this is the percentage is 38.29%, calculated as the CDF of 0.5 minus the CDF of -0.5, covering the area between Z equals −0.5 and Z equals 0.5. The graph below visually represents these regions with shaded areas, and the corresponding percentages.

Visualization and R code

# Begin code Exercise 4.2

# Load ggplot2 library, if not already done; for creating plots
library(ggplot2)

# Define parameters for the standard normal distribution
mu <- 0         # Mean of the standard normal distribution
sigma <- 1      # Standard deviation of the standard normal distribution

# PART_a: Calculate the percentage of the distribution where Z > -1.13
# pnorm calculates the cumulative probability up to Z = -1.13
PART_a <- 1 - pnorm(-1.13, mean = mu, sd = sigma) 
# Subtracting from 1 gives the probability of Z being greater than -1.13
cat("Percentage for Z > -1.13: ", PART_a * 100, "%\n")  # Print the result in percentage
## Percentage for Z > -1.13:  87.07619 %
# PART_b: Calculate the percentage of the distribution where Z < 0.18
# pnorm calculates the cumulative probability up to Z = 0.18
PART_b <- pnorm(0.18, mean = mu, sd = sigma)
# This directly gives the probability of Z being less than 0.18
cat("Percentage for Z < 0.18: ", PART_b * 100, "%\n")  # Print the result in percentage
## Percentage for Z < 0.18:  57.14237 %
# PART_c: Calculate the percentage of the distribution where Z > 8
# pnorm calculates the cumulative probability up to Z = 8
PART_c <- 1 - pnorm(8, mean = mu, sd = sigma)
# Subtracting from 1 gives the probability of Z being greater than 8
cat("Percentage for Z > 8: ", PART_c * 100, "%\n")  # Print the result in percentage
## Percentage for Z > 8:  6.661338e-14 %
# PART_d: Calculate the percentage of the distribution where |Z| < 0.5
# pnorm calculates the cumulative probability up to Z = 0.5
# Subtracting pnorm for Z = -0.5 gives the probability between -0.5 and 0.5
PART_d <- pnorm(0.5, mean = mu, sd = sigma) - pnorm(-0.5, mean = mu, sd = sigma)
cat("Percentage for |Z| < 0.5: ", PART_d * 100, "%\n")  # Print the result in percentage
## Percentage for |Z| < 0.5:  38.29249 %
# Create a sequence of Z values for plotting
z_values <- seq(-4, 4, length.out = 1000)  # Range of Z values from -4 to 4
density_values <- dnorm(z_values, mean = mu, sd = sigma)  # Compute density values for the Z sequence

# Create a data frame for ggplot2
df <- data.frame(Z = z_values, Density = density_values)

# Generate the plot with ggplot2
ggplot(df, aes(x = Z, y = Density)) +
  geom_line(color = "lightblue") +  # Line for the standard normal distribution density
  geom_area(data = df[df$Z > -1.13, ], 
            aes(x = Z, y = Density), fill = "#B3CDE0", alpha = 0.5) +  # Light blue area for Z > -1.13
  geom_area(data = df[df$Z < 0.18, ], 
            aes(x = Z, y = Density), fill = "#A2C2E0", alpha = 0.5) +  # Slightly darker blue for Z < 0.18
  geom_area(data = df[df$Z > 8, ], 
            aes(x = Z, y = Density), fill = "#7D9AC3", alpha = 0.5) +  # Even darker blue for Z > 8
  geom_area(data = df[abs(df$Z) < 0.5, ], 
            aes(x = Z, y = Density), fill = "#6B9AC3", alpha = 0.5) +  # Dark blue for |Z| < 0.5
  labs(title = "4.2 Area under the curve, Part II",  # Title of the plot
       x = "Z", y = "Density") +  # Labels for x and y axes
  theme_dark() +  # Apply dark theme for the plot
  theme(
    plot.title = element_text(hjust = 0.5, size = 18, face = "bold", color = "navy"),  # Title formatting
    axis.title.x = element_text(size = 14, color = "navy"),  # X-axis title formatting
    axis.title.y = element_text(size = 14, color = "navy"),  # Y-axis title formatting
    axis.text = element_text(size = 12, color = "navy"),  # Axis text formatting
    panel.grid = element_blank(),  # Remove gridlines for a cleaner look
    panel.border = element_rect(color = "white", fill = NA, linewidth = 0.5)  # White border around the plot
  )

#End of code Exercise 4.2; Summary of visualizations: 
#The R code calculates and visualizes the percentages of a standard normal distribution within specific regions. 
#It shows that 87.14% of the distribution lies to the right of Z = -1.13, while 57.13% is to the left of Z = 0.18. 
#For Z > 8, the percentage is effectively 0.00%, indicating that this Z-score is far into the tail with minimal area. 
#The percentage for |Z| < 0.5 is 38.29%, covering the area between Z = -0.5 and Z = 0.5. 
#The graph uses shaded regions to clearly depict these areas, providing a visual representation of how much of the distribution falls within or beyond the specified Z-score thresholds.

##Exercise 4.4

Explination

At the Hermosa Beach Triathlon, competitors were categorized by gender and age. According to Moen et al. (2021), studies reveal that categorizing populations into various groups based on mutually shared commonalities, such as race, ethnicity, social class, employment, and gender, allows for intersectional analysis to evaluate greater complexities within mutually sharing populations. Racers Leo and Mary are interested in evaluating their performance within these categories. Leo competed in the male 30-34 age group. He finished in 4948 seconds. Mary competed in the female 25-29 age group. She finished in 5513 seconds. The male group has a mean finishing time of 4313 seconds with a standard deviation of 583 seconds. The female group has a mean of 5261 seconds with a standard deviation of 807 seconds. The finishing times in both groups are approximately normally distributed. Exercise 4.4: Part A The normal distributions are based on Leo and Mary’s triathlon performances, respective to age and gender groups. For men, the ages were 30-34 group. The distribution is N (4313, 583), where 4313 seconds is the mean and 583 seconds is the standard deviation. For women, the ages were 25-29 group. The distribution is N (5261, 807), with a mean of 5261 seconds and a standard deviation of 807 seconds. This notation describes the expected distribution of finishing times in each group assuming a normal distribution. Exercise 4.4: Part B To calculate the Z scores for Leo and Mary, use the formula Z equals X minus mean divided by standard deviation. For Leo: Z equals 4948 minus 4313, divided by 583, which equals approximately 1.09. This means Leo finished 1.09 standard deviations faster than the mean time in his group. For Mary: Z equals 5513 minus 5261, divided by 807, which equals approximately 0.31. This indicates Mary finished 0.31 standard deviations slower than the mean time in her group. The Z scores quantify how Leo and Mary’s times compare to their group’s average. Exercise 4.4: Part C Leo ranked better in his group compared to Mary. Leo’s Z score of approximately 1.09 shows he finished faster relative to the average time in his group. In contrast, Mary’s Z score of approximately 0.31 shows she finished closer to, but still slower than, the average time in her group. A higher Z score indicates a better performance relative to the group mean, so Leo’s performance was comparatively better within his group. Exercise 4.4: Part D Leo finished faster than approximately 86.14% of the men in his group. This is found using the Z score of 1.09. To find this percentile and using the cumulative distribution function (CDF) value of Z equals 1.09, which is approximately 0.8614., Leo’s performance was better than about 86.14% of his peers. Exercise 4.4: Part E Mary finished faster than approximately 61.24% of the women in her group. This is determined from Mary’s Z score of 0.31. Using the CDF value for Z equals 0.31, which is 0.6124; finding that Mary’s performance was better than approximately 61.24% of the women in her group. Exercise 4.4: Part F Considering if the distributions of finishing times are not nearly normal, the results from parts B through E could change. Bono et al. (2017) suggest that when data does not conform to a normal distribution, researchers should consider alternative approaches, such as generalized additive models for location, scale, and shape, to determine a more appropriate distribution for the response variable. For example, if the distribution of finishing times for the men, ages 30 - 34 group were skewed, with a longer tail on the right, the mean and standard deviation might not accurately reflect the distribution’s characteristics. In such a scenario, Leo’s Z score, which assumes of normality, might not correctly represent his standing relative to his peers. This could lead to an incorrect calculation of the percentage of triathletes he finished faster than. For instance, if the actual distribution were heavily right skewed, Leo’s Z score might suggest he is in a better percentile than he truly is if the normal distribution assumption were applied. Similarly, if Mary’s group had a distribution with a significant left skew, her Z score might underestimate how her performance compares to others. Non-normal distributions would require more tailored statistical methods to accurately assess performance.

#Begin code Exercise 4.4

# Load libraries, if needed
library(ggplot2)   # For creating plots
library(gridExtra) # For arranging multiple plots
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
# Define the parameters for each group
# Men, Ages 30 - 34
mu_men <- 4313     # Mean finishing time in seconds for men, ages 30-34
sigma_men <- 583   # Standard deviation of finishing times for men, ages 30-34
time_leo <- 4948   # Leo's finishing time in seconds

# Women, Ages 25 - 29
mu_women <- 5261   # Mean finishing time in seconds for women, ages 25-29
sigma_women <- 807 # Standard deviation of finishing times for women, ages 25-29
time_mary <- 5513  # Mary's finishing time in seconds

# Create a sequence of finishing times for plotting
# This sequence will be used to plot the density functions for both groups
finishing_times_men <- seq(mu_men - 4*sigma_men, mu_men + 4*sigma_men, length.out = 1000)
finishing_times_women <- seq(mu_women - 4*sigma_women, mu_women + 4*sigma_women, length.out = 1000)

# Calculate densities for the normal distributions
# This is used to plot the normal distribution curves
density_men <- dnorm(finishing_times_men, mean = mu_men, sd = sigma_men)
density_women <- dnorm(finishing_times_women, mean = mu_women, sd = sigma_women)

# Create data frames for plotting
df_men <- data.frame(FinishingTime = finishing_times_men, Density = density_men)
df_women <- data.frame(FinishingTime = finishing_times_women, Density = density_women)

# Create the plot for Leo
plot_leo <- ggplot(df_men, aes(x = FinishingTime, y = Density)) +
  geom_line(color = "lightblue") +  # Line representing the density function
  geom_area(data = df_men[df_men$FinishingTime > time_leo, ],
            aes(x = FinishingTime, y = Density), fill = "#B3CDE0", alpha = 0.5) +  # Shaded area representing the times faster than Leo
  geom_vline(xintercept = time_leo, color = "darkblue", linetype = "dashed") +  # Vertical line for Leo's finishing time
  labs(title = "Leo's Time: Men 30-34",  # Title of the plot
       x = "Finishing Time (seconds) \nMen, Ages 30-34",  # X-axis label
       y = "Density of Finishing Times") +  # Y-axis label
  theme_dark() +  # Dark theme for the plot background
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold", color = "darkblue"),  # Formatting for the title
    axis.title.x = element_text(size = 12, color = "darkblue"),  # X-axis title formatting
    axis.title.y = element_text(size = 12, color = "darkblue"),  # Y-axis title formatting
    axis.text = element_text(size = 10, color = "darkblue"),  # Axis text formatting
    panel.grid = element_blank(),  # Remove gridlines for a cleaner look
    panel.border = element_rect(color = "white", fill = NA, linewidth = 0.5),  # Border around the plot
    plot.margin = margin(20, 10, 10, 10)  # Increased top margin to avoid overlap
  )

# Create the plot for Mary
plot_mary <- ggplot(df_women, aes(x = FinishingTime, y = Density)) +
  geom_line(color = "lightpink") +  # Line representing the density function
  geom_area(data = df_women[df_women$FinishingTime > time_mary, ],
            aes(x = FinishingTime, y = Density), fill = "#F5B0B3", alpha = 0.5) +  # Shaded area representing the times faster than Mary
  geom_vline(xintercept = time_mary, color = "darkred", linetype = "dashed") +  # Vertical line for Mary's finishing time
  labs(title = "Mary's Time: Women 25-29",  # Title of the plot
       x = "Finishing Time (seconds) \nWomen, Ages 25-29",  # X-axis label
       y = "Density of Finishing Times") +  # Y-axis label
  theme_dark() +  # Dark theme for the plot background
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold", color = "darkred"),  # Formatting for the title
    axis.title.x = element_text(size = 12, color = "darkred"),  # X-axis title formatting
    axis.title.y = element_text(size = 12, color = "darkred"),  # Y-axis title formatting
    axis.text = element_text(size = 10, color = "darkred"),  # Axis text formatting
    panel.grid = element_blank(),  # Remove gridlines for a cleaner look
    panel.border = element_rect(color = "white", fill = NA, linewidth = 0.5),  # Border around the plot
    plot.margin = margin(20, 10, 10, 10)  # Increased top margin to avoid overlap
  )

# Combine the plots into a single view
grid.arrange(plot_leo, plot_mary, ncol = 2, widths = c(1, 1), top = "Triathletes' Performance")

#End of code Exercise 4.4; summary of visualizations: 
#The plots visualize the finishing times of Leo and Mary within their respective triathlon age groups.
#For Leo, competing in the Men, Ages 30-34 group, his finishing time of 4948 seconds is represented by a vertical dashed line on the plot. 
#The shaded area to the right of this line indicates the proportion of men who finished slower than Leo, which corresponds to the percentage of triathletes Leo outperformed. 
#For Mary, competing in the Women, Ages 25-29 group, her finishing time of 5513 seconds is similarly marked. The shaded area to the right of her line shows the proportion of women who finished slower than Mary. 
#Leo's plot reveals that he performed better than a significant percentage of his group, whereas Mary’s plot shows a smaller proportion of women who finished slower than her. 
#This difference highlights that, although Leo finished faster than Mary overall, he performed relatively better within his group compared to Mary in hers, given the distribution of finishing times.

##Exercise 4.8

Explination

The Capital Asset Pricing Model (CAPM) is assumed to be normally distributed. The single-period, one-factor CAPM, developed by Sharpe (1964), is the most basic and widely used benchmark asset pricing model in both practice and research, according to a professional organization’s survey report (Pham & Phuoc, 2020) The supposed portfolio includes an average annual return of 14.7% and a standard deviation of 33%, a return of 0%. This assumes the portfolio value remains unchanged. Negative returns show losses, while positive returns show growth. According to Thonon et al. (2023), studies reveal that utilizing financial models allow for measuring diverse methodologies for calculating the return on investments, which benefit more standardized designs to facilitate and compare positive or negative returns. The CAPM model provides insights into the distribution of returns and helps evaluate the probability of various financial outcomes. Exercise 4.8: Part A The probability of having a return less than 0% is used to determine the percentage of losing money. The portfolio has normal distribution with a mean return of 14.7% and a standard deviation of 33%. The Z score for a 0% return is needed for calculation; This is calculated as (0 minus 0.147), divided 0.33 to equal around −0.445. Then incorporating the Z score, the cumulative probability is around 32.8%, which results in the portfolio probability of losing money in about 32.8% of years. Exercise 4.8: Part B The cutoff for the highest 15% of annual returns is identified by the 85th percentile of the distribution. The Z score corresponding to the 85th percentile is around 1.036. The Z score then is converted to return a value by calculating the cutoff return; this is calculated by 0.147 plus (1.036 times 0.33) equaling 0.470, converted to percentage as 47.0%. This means the cutoff for the highest 15% of annual returns is around 47.0%.

# Load the necessary library
library(ggplot2)

# Define the parameters for the normal distribution
# Mean annual return (14.7%) is converted to decimal form (0.147)
mu <- 0.147  # Mean return
# Standard deviation (33%) is converted to decimal form (0.33)
sigma <- 0.33  # Standard deviation

# Create a sequence of return values from -0.5 to 0.5 with 1000 points
returns <- seq(-0.5, 0.5, length.out = 1000)
# Compute the probability density function for these return values
density <- dnorm(returns, mean = mu, sd = sigma)

# Create a data frame for plotting
df <- data.frame(Return = returns, Density = density)

# Calculate the Z-score for a return of 0% (i.e., when Return = 0)
z_score_below_zero <- (0 - mu) / sigma
# Compute the probability of the return being less than 0% using the Z-score
probability_below_zero <- pnorm(z_score_below_zero)

# Calculate the Z-score corresponding to the 85th percentile
z_score_85th <- qnorm(0.85)
# Compute the cutoff return value for the top 15% of returns
cutoff_return <- mu + z_score_85th * sigma

# Create the plot using ggplot2
p <- ggplot(df, aes(x = Return, y = Density)) +
  # Plot the normal distribution curve in dark grey
  geom_line(color = "#333333") +  # Dark grey color for the curve
  
  # Highlight the area where returns are less than 0%
  geom_area(data = df[df$Return < 0, ], aes(x = Return, y = Density), fill = "#CC3333", alpha = 0.6) +  # Deep red color
  
  # Add a vertical dashed line at 0% return
  geom_vline(xintercept = 0, linetype = "dashed", color = "#FF0000") +  # Red line for 0% return
  
  # Add a vertical dashed line at the cutoff for the highest 15% of returns
  geom_vline(xintercept = cutoff_return, linetype = "dashed", color = "#009900") +  # Dark green line for 85th percentile
  
  # Add descriptive labels and a caption to the plot
  labs(
    title = "4.8 CAPM",
    x = "Annual Return (%)",
    y = "Probability Density",
    caption = sprintf("Mean Return: %.2f%% | Std Dev: %.2f%%\nCutoff for Top 15%%: %.2f%% | Percentage of Years with Return < 0%%: %.2f%%",
                      mu * 100, sigma * 100, cutoff_return * 100, probability_below_zero * 100)
  ) +
  
  # Annotate the plot with text for clarity
  annotate("text", x = -0.4, y = max(df$Density) * 0.7, label = sprintf("Return < 0%%: %.2f%%", probability_below_zero * 100), color = "#FF0000") +
  annotate("text", x = cutoff_return, y = max(df$Density) * 0.7, label = sprintf("85th Percentile: %.2f%%", cutoff_return * 100), color = "#009900") +
  
  # Adjust the x-axis and y-axis limits to ensure the entire plot is visible
  xlim(-0.5, 0.5) +  # Extend x-axis limits
  ylim(0, max(df$Density) * 1.2) +  # Extend y-axis limits
  
  # Apply a minimal theme with customized text and plot appearance
  theme_minimal(base_size = 15) +
  theme(
    plot.title = element_text(hjust = 0.5, size = 18, face = "bold"),
    axis.title.x = element_text(size = 14),
    axis.title.y = element_text(size = 14),
    axis.text = element_text(size = 12),
    plot.margin = margin(10, 10, 10, 10)  # Increase margins to prevent cut-off
  )

# Print the plot
print(p)

#End of code Exercise 4.8; summary of visualizations: 
# This creates a visual representation of portfolio returns based on the Capital Asset Pricing Model (CAPM), assuming normally distributed returns. 
#The plot shows the normal distribution curve for annual returns with a mean of 14.7% and a standard deviation of 33%. 
#The dark grey curve illustrates the distribution, while shaded areas highlight specific return ranges. A red dashed line indicates the 0% return threshold, and a dark green dashed line marks the cutoff for the highest 15% of returns. 
#The plot includes annotations for the percentage of years with a return less than 0% and the cutoff return for the top 15% of returns. 
#This visual helps in understanding the distribution of returns and the relative performance thresholds for the portfolio.

Lab Chapter 4 from OpenIntro Textbook

# Set CRAN mirror
options(repos = c(CRAN = "https://cran.rstudio.com"))

# Install and load necessary libraries
install.packages("tidyverse")
## Warning: package 'tidyverse' is in use and will not be installed
install.packages("openintro") # Uncomment if needed
## Warning: package 'openintro' is in use and will not be installed
library(tidyverse)
library(openintro)

Exercise 1

arbuthnot$girls
##  [1] 4683 4457 4102 4590 4839 4820 4928 4605 4457 4952 4784 5332 5200 4910 4617
## [16] 3997 3919 3395 3536 3181 2746 2722 2840 2908 2959 3179 3349 3382 3289 3013
## [31] 2781 3247 4107 4803 4881 5681 4858 4319 5322 5560 5829 5719 6061 6120 5822
## [46] 5738 5717 5847 6203 6033 6041 6299 6533 6744 7158 7127 7246 7119 7214 7101
## [61] 7167 7302 7392 7316 7483 6647 6713 7229 7767 7626 7452 7061 7514 7656 7683
## [76] 5738 7779 7417 7687 7623 7380 7288
# Exercise 1: Filter Data
# Filter data for McDonald's and Dairy Queen
mcdonalds <- fastfood %>% filter(restaurant == "Mcdonalds")
dairy_queen <- fastfood %>% filter(restaurant == "Dairy Queen")

Exercise 2

Insert any text here.

# Exercise 2: Visualize Distributions

# McDonald's Data Visualization
# Plot histogram of calories from fat at McDonald's
ggplot(mcdonalds, aes(x = cal_fat)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = "lightblue", color = "black") +
  labs(title = "Calories from Fat at McDonald's", x = "Calories from Fat", y = "Density") +
  theme_minimal() +
  theme(axis.text = element_text(color = "green"), axis.title = element_text(color = "green"))
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

# Dairy Queen Data Visualization
# Plot histogram of calories from fat at Dairy Queen
ggplot(dairy_queen, aes(x = cal_fat)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = "lightblue", color = "black") +
  labs(title = "Calories from Fat at Dairy Queen", x = "Calories from Fat", y = "Density") +
  theme_minimal() +
  theme(axis.text = element_text(color = "green"), axis.title = element_text(color = "green"))

Exercise 3

Insert any text here.

# Exercise 3: Normal Distribution

# Calculate mean and standard deviation for Dairy Queen
dqmean <- mean(dairy_queen$cal_fat, na.rm = TRUE)
dqsd <- sd(dairy_queen$cal_fat, na.rm = TRUE)

# Create a density histogram with a normal distribution curve for Dairy Queen
ggplot(dairy_queen, aes(x = cal_fat)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = "lightblue", color = "black") +
  stat_function(fun = dnorm, args = list(mean = dqmean, sd = dqsd), color = "tomato", size = 1) +
  labs(title = "Calories from Fat at Dairy Queen with Normal Curve", x = "Calories from Fat", y = "Density") +
  theme_minimal() +
  theme(axis.text = element_text(color = "green"), axis.title = element_text(color = "green"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

# Create a normal Q-Q plot for Dairy Queen’s calories from fat
ggplot(data = dairy_queen, aes(sample = cal_fat)) +
  geom_qq() +
  geom_qq_line() +
  labs(title = "Q-Q Plot of Calories from Fat at Dairy Queen", x = "Theoretical Quantiles", y = "Sample Quantiles") +
  theme_minimal() +
  theme(axis.text = element_text(color = "red"), axis.title = element_text(color = "orange"))

Exercise 4

Insert any text here.

# Exercise 4: Simulate Normal Data and Create Q-Q Plot

# Simulate normal data
sim_norm <- rnorm(n = nrow(dairy_queen), mean = dqmean, sd = dqsd)

# Create a Q-Q plot of simulated normal data
ggplot(data.frame(sim_norm), aes(sample = sim_norm)) +
  geom_qq() +
  geom_qq_line() +
  labs(title = "Q-Q Plot of Simulated Normal Data", x = "Theoretical Quantiles", y = "Sample Quantiles") +
  theme_minimal() +
  theme(axis.text = element_text(color = "yellow"), axis.title = element_text(color = "pink"))

Exercise 5

Insert any text here.

# Exercise 5: Probability Calculations

# Calculate the theoretical probability for Dairy Queen items having more than 600 calories from fat
prob_theoretical <- 1 - pnorm(q = 600, mean = dqmean, sd = dqsd)
print(paste("Theoretical probability of more than 600 calories from fat:", prob_theoretical))
## [1] "Theoretical probability of more than 600 calories from fat: 0.0150152297382053"
# Calculate the empirical probability for Dairy Queen items having more than 600 calories from fat
prob_empirical <- dairy_queen %>%
  filter(cal_fat > 600) %>%
  summarise(percent = n() / nrow(dairy_queen))
print(prob_empirical)
## # A tibble: 1 × 1
##   percent
##     <dbl>
## 1  0.0476

Exercise 6

Insert any text here.

# Exercise 6: McDonald's Probability Calculations

# Calculate the mean and standard deviation for McDonald's calories from fat
mcmean <- mean(mcdonalds$cal_fat, na.rm = TRUE)
mcsd <- sd(mcdonalds$cal_fat, na.rm = TRUE)

# Calculate the theoretical probability for McDonald's items having more than 500 calories from fat
prob_mc_theoretical <- 1 - pnorm(q = 500, mean = mcmean, sd = mcsd)
print(paste("Theoretical probability for McDonald's with more than 500 calories from fat:", prob_mc_theoretical))
## [1] "Theoretical probability for McDonald's with more than 500 calories from fat: 0.16589503676763"
# Calculate the empirical probability for McDonald's items having more than 500 calories from fat
prob_mc_empirical <- mcdonalds %>%
  filter(cal_fat > 500) %>%
  summarise(percent = n() / nrow(mcdonalds))
print(prob_mc_empirical)
## # A tibble: 1 × 1
##   percent
##     <dbl>
## 1   0.105
# End of Lab Chapter 4 from OpenIntro Textbook

References Bono, R., Blanca, M., Arnau, J., & Gómez-Benito, J. (2017). Non-normal distributions commonly used in health, education, and social sciences: A systematic review. Frontiers in Psychology, 8. https://doi.org/10.3389/fpsyg.2017.01602 Diez, D., Barr, C., & Çetinkaya-RundelM. (2019). OpenIntro statistics (Fourth). Elassaiss-Schaap, J., & Duisters, K. (2020). Variability in the log domain and limitations to its approximation by the normal distribution. Pharmacometrics & Systems Pharmacology, 9(5). https://doi.org/10.1002/psp4.12507 Moen, P., Flood, S., & Wang, J. (2021). The uneven later work course: Intersectional gender, age, race, and class disparities. The Journals of Gerontology: Series B, 77(1). https://doi.org/10.1093/geronb/gbab039 Pham, C., & Phuoc, L. (2020). An augmented capital asset pricing model using new macroeconomic determinants. Heliyon, 6(10), Article e05185. https://doi.org/10.1016/j.heliyon.2020.e05185 Solomyak, L., Sharp, P., & Eldar, E. (2022). Training diversity promotes absolute-value-guided choice. PLoS Computational Biology, 18(11), Article e1010664. https://doi.org/10.1371/journal.pcbi.1010664 Thonon, F., Godon-Rensonnet, A., Perozziello, A., Garsi, J., Dab, W., & Emsalem, P. (2023). Return on investment of workplace-based prevention interventions: A systematic review. European Journal of Public Health, 33(4), 612–618. https://doi.org/10.1093/eurpub/ckad092

LS0tDQp0aXRsZTogIkxhYiAxOiBJbnRybyB0byBSIg0KYXV0aG9yOiAiQXV0aG9yIE5hbWUiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydA0KLS0tDQoNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KYGBgDQoNCi0tLQ0KdGl0bGU6ICJNb2R1bGVfMDRfSFdfTGFiXzA0Ig0KYXV0aG9yOiAiQW50aG9ueSBWLiBSYXp6YW5vLCBESEEiDQpkYXRlOiAiMjAyNC0wOS0wOSINCm91dHB1dDoNCiAgcGRmX2RvY3VtZW50Og0KICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleA0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KVGhlIGFzc2lnbm1lbnQgcmVxdWlyZXMgY29tcGxldGlvbiBvZiBleGVyY2lzZXMgaW4gY2hhcHRlciA0IG9mIHRoZSBEaWV6ICgyMDE5KSB0ZXh0Ym9vay4gVGhlIGV4ZXJjaXNlcyBpbmNsdWRlIDQuMiwgNC40LCBhbmQgNC44LiBFYWNoIGV4ZXJjaXNlIGhhcyBpdHMgb3duIHNlY3Rpb24gYW5kIGhlYWRpbmcgd2l0aGluIHRoaXMgcmVwb3J0LiBJbiBhZGRpdGlvbiwgaXQgcmVxdWlyZXMgTGFiIENoYXB0ZXIgNCBmcm9tIE9wZW5JbnRybyBUZXh0Ym9vazogaHR0cHM6Ly9vcGVuaW50cm9zdGF0LmdpdGh1Yi5pby9vaWxhYnMtdGlkeS8wNF9ub3JtYWxfZGlzdHJpYnV0aW9uL25vcm1hbF9kaXN0cmlidXRpb24uaHRtbA0KDQojTW9kdWxlIDQgSG9tZXdvcmsNCg0KIyNFeGVyY2lzZSA0LjINCg0KIyMjIEV4cGxpbmF0aW9uDQoNClRoZSBzb2x1dGlvbiBjYWxjdWxhdGVzIHRoZSBwZXJjZW50YWdlcyBvZiBhIHN0YW5kYXJkIG5vcm1hbCBkaXN0cmlidXRpb24gTiAoMCwxKSB3aXRoaW4gc3BlY2lmaWMgcmVnaW9ucyB1c2luZyB0aGUgY3VtdWxhdGl2ZSBkaXN0cmlidXRpb24gZnVuY3Rpb24gKENERikuIEFjY29yZGluZyB0byBFbGFzc2Fpc3MtU2NoYWFwIGFuZCBEdWlzdGVycyAoMjAyMCksIHN0dWRpZXMgcmV2ZWFsIHRoYXQgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24ncyBzdGFuZGFyZCBkZXZpYXRpb24gY2Fubm90IGV4Y2VlZCBoYWxmIHRoZSBtZWFuIHdpdGhvdXQgZXh0ZW5kaW5nIGludG8gbmVnYXRpdmUgdmFsdWVzLCB3aGVyZWFzIHRoZSBsb2dub3JtYWwgZGlzdHJpYnV0aW9uIGVmZmVjdGl2ZWx5IHNwYW5zIGJleW9uZCB0aGlzIHJhbmdlIHdpdGhvdXQgcHJvZHVjaW5nIG5lZ2F0aXZlIHZhbHVlcy4gRm9yIFogZ3JlYXRlciB0aGFuIC0xLjEzLCB0aGUgcGVyY2VudGFnZSBpcyA4Ny4xNCUsIHdoaWNoIGlzIGNhbGN1bGF0ZWQgYnkgMTExIG1pbnVzIHRoZSBDREYgb2YgLTEuMTMsIHdoaWNoIGdpdmVzIHRoZSBhcmVhIHRvIHRoZSByaWdodCBvZiBaIGVxdWFscyDiiJIxLjEzLiBGb3IgWiBsZXNzIHRoYW4gMC4xOCwgdGhlIHBlcmNlbnRhZ2UgaXMgNTcuMTMlLCB3aGljaCBpcyBjYWxjdWxhdGVkIGJ5IHRoZSBDREYgb2YgMC4xOCwgcmVwcmVzZW50aW5nIHRoZSBhcmVhIHRvIHRoZSBsZWZ0IG9mIFogZXF1YWxpbmcgMC4xOC4gVGhlIHBlcmNlbnRhZ2UgZm9yIFogZ3JlYXRlciB0aGFuIDggaXMgZWZmZWN0aXZlbHkgMC4wMCUsIHdoaWNoIGlzIGNhbGN1bGF0ZWQgYnkgMTExIG1pbnVzIHRoZSBDREYgb2YgOCBiZWluZyBuZWdsaWdpYmxlLCBpbmRpY2F0aW5nIGFuIGFyZWEgYWxtb3N0IHplcm8gZHVlIHRvIHRoZSBleHRyZW1lIHZhbHVlIGJlaW5nIGZhciBpbiB0aGUgdGFpbC4gQWJzb2x1dGUgdmFsdWVzIGZ1bmN0aW9uIGFzIGEgdW5pdmVyc2FsIG1lYXN1cmUgdGhhdCBzdGFuZGFyZGl6ZXMgcHJlZmVyZW5jZXMsIGFsbG93aW5nIGZvciBjb25zaXN0ZW50IGNvbXBhcmlzb25zIGFjcm9zcyBkaWZmZXJlbnQgY29udGV4dHMgd2l0aCB2YXJ5aW5nIG9wdGlvbnMgKFNvbG9teWFrIGV0IGFsLiwgMjAyMikuIFRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiBaIGxlc3MgdGhhbiAwLjUsIHRoaXMgaXMgdGhlIHBlcmNlbnRhZ2UgaXMgMzguMjklLCBjYWxjdWxhdGVkIGFzIHRoZSBDREYgb2YgMC41IG1pbnVzIHRoZSBDREYgb2YgLTAuNSwgY292ZXJpbmcgdGhlIGFyZWEgYmV0d2VlbiBaIGVxdWFscyDiiJIwLjUgYW5kIFogZXF1YWxzIDAuNS4gVGhlIGdyYXBoIGJlbG93IHZpc3VhbGx5IHJlcHJlc2VudHMgdGhlc2UgcmVnaW9ucyB3aXRoIHNoYWRlZCBhcmVhcywgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHBlcmNlbnRhZ2VzLg0KDQoNCiMjIyBWaXN1YWxpemF0aW9uIGFuZCBSIGNvZGUNCg0KYGBge3J9DQoNCiMgQmVnaW4gY29kZSBFeGVyY2lzZSA0LjINCg0KIyBMb2FkIGdncGxvdDIgbGlicmFyeSwgaWYgbm90IGFscmVhZHkgZG9uZTsgZm9yIGNyZWF0aW5nIHBsb3RzDQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgRGVmaW5lIHBhcmFtZXRlcnMgZm9yIHRoZSBzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uDQptdSA8LSAwICAgICAgICAgIyBNZWFuIG9mIHRoZSBzdGFuZGFyZCBub3JtYWwgZGlzdHJpYnV0aW9uDQpzaWdtYSA8LSAxICAgICAgIyBTdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHN0YW5kYXJkIG5vcm1hbCBkaXN0cmlidXRpb24NCg0KIyBQQVJUX2E6IENhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBvZiB0aGUgZGlzdHJpYnV0aW9uIHdoZXJlIFogPiAtMS4xMw0KIyBwbm9ybSBjYWxjdWxhdGVzIHRoZSBjdW11bGF0aXZlIHByb2JhYmlsaXR5IHVwIHRvIFogPSAtMS4xMw0KUEFSVF9hIDwtIDEgLSBwbm9ybSgtMS4xMywgbWVhbiA9IG11LCBzZCA9IHNpZ21hKSANCiMgU3VidHJhY3RpbmcgZnJvbSAxIGdpdmVzIHRoZSBwcm9iYWJpbGl0eSBvZiBaIGJlaW5nIGdyZWF0ZXIgdGhhbiAtMS4xMw0KY2F0KCJQZXJjZW50YWdlIGZvciBaID4gLTEuMTM6ICIsIFBBUlRfYSAqIDEwMCwgIiVcbiIpICAjIFByaW50IHRoZSByZXN1bHQgaW4gcGVyY2VudGFnZQ0KDQojIFBBUlRfYjogQ2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIHRoZSBkaXN0cmlidXRpb24gd2hlcmUgWiA8IDAuMTgNCiMgcG5vcm0gY2FsY3VsYXRlcyB0aGUgY3VtdWxhdGl2ZSBwcm9iYWJpbGl0eSB1cCB0byBaID0gMC4xOA0KUEFSVF9iIDwtIHBub3JtKDAuMTgsIG1lYW4gPSBtdSwgc2QgPSBzaWdtYSkNCiMgVGhpcyBkaXJlY3RseSBnaXZlcyB0aGUgcHJvYmFiaWxpdHkgb2YgWiBiZWluZyBsZXNzIHRoYW4gMC4xOA0KY2F0KCJQZXJjZW50YWdlIGZvciBaIDwgMC4xODogIiwgUEFSVF9iICogMTAwLCAiJVxuIikgICMgUHJpbnQgdGhlIHJlc3VsdCBpbiBwZXJjZW50YWdlDQoNCiMgUEFSVF9jOiBDYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGRpc3RyaWJ1dGlvbiB3aGVyZSBaID4gOA0KIyBwbm9ybSBjYWxjdWxhdGVzIHRoZSBjdW11bGF0aXZlIHByb2JhYmlsaXR5IHVwIHRvIFogPSA4DQpQQVJUX2MgPC0gMSAtIHBub3JtKDgsIG1lYW4gPSBtdSwgc2QgPSBzaWdtYSkNCiMgU3VidHJhY3RpbmcgZnJvbSAxIGdpdmVzIHRoZSBwcm9iYWJpbGl0eSBvZiBaIGJlaW5nIGdyZWF0ZXIgdGhhbiA4DQpjYXQoIlBlcmNlbnRhZ2UgZm9yIFogPiA4OiAiLCBQQVJUX2MgKiAxMDAsICIlXG4iKSAgIyBQcmludCB0aGUgcmVzdWx0IGluIHBlcmNlbnRhZ2UNCg0KIyBQQVJUX2Q6IENhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBvZiB0aGUgZGlzdHJpYnV0aW9uIHdoZXJlIHxafCA8IDAuNQ0KIyBwbm9ybSBjYWxjdWxhdGVzIHRoZSBjdW11bGF0aXZlIHByb2JhYmlsaXR5IHVwIHRvIFogPSAwLjUNCiMgU3VidHJhY3RpbmcgcG5vcm0gZm9yIFogPSAtMC41IGdpdmVzIHRoZSBwcm9iYWJpbGl0eSBiZXR3ZWVuIC0wLjUgYW5kIDAuNQ0KUEFSVF9kIDwtIHBub3JtKDAuNSwgbWVhbiA9IG11LCBzZCA9IHNpZ21hKSAtIHBub3JtKC0wLjUsIG1lYW4gPSBtdSwgc2QgPSBzaWdtYSkNCmNhdCgiUGVyY2VudGFnZSBmb3IgfFp8IDwgMC41OiAiLCBQQVJUX2QgKiAxMDAsICIlXG4iKSAgIyBQcmludCB0aGUgcmVzdWx0IGluIHBlcmNlbnRhZ2UNCg0KIyBDcmVhdGUgYSBzZXF1ZW5jZSBvZiBaIHZhbHVlcyBmb3IgcGxvdHRpbmcNCnpfdmFsdWVzIDwtIHNlcSgtNCwgNCwgbGVuZ3RoLm91dCA9IDEwMDApICAjIFJhbmdlIG9mIFogdmFsdWVzIGZyb20gLTQgdG8gNA0KZGVuc2l0eV92YWx1ZXMgPC0gZG5vcm0oel92YWx1ZXMsIG1lYW4gPSBtdSwgc2QgPSBzaWdtYSkgICMgQ29tcHV0ZSBkZW5zaXR5IHZhbHVlcyBmb3IgdGhlIFogc2VxdWVuY2UNCg0KIyBDcmVhdGUgYSBkYXRhIGZyYW1lIGZvciBnZ3Bsb3QyDQpkZiA8LSBkYXRhLmZyYW1lKFogPSB6X3ZhbHVlcywgRGVuc2l0eSA9IGRlbnNpdHlfdmFsdWVzKQ0KDQojIEdlbmVyYXRlIHRoZSBwbG90IHdpdGggZ2dwbG90Mg0KZ2dwbG90KGRmLCBhZXMoeCA9IFosIHkgPSBEZW5zaXR5KSkgKw0KICBnZW9tX2xpbmUoY29sb3IgPSAibGlnaHRibHVlIikgKyAgIyBMaW5lIGZvciB0aGUgc3RhbmRhcmQgbm9ybWFsIGRpc3RyaWJ1dGlvbiBkZW5zaXR5DQogIGdlb21fYXJlYShkYXRhID0gZGZbZGYkWiA+IC0xLjEzLCBdLCANCiAgICAgICAgICAgIGFlcyh4ID0gWiwgeSA9IERlbnNpdHkpLCBmaWxsID0gIiNCM0NERTAiLCBhbHBoYSA9IDAuNSkgKyAgIyBMaWdodCBibHVlIGFyZWEgZm9yIFogPiAtMS4xMw0KICBnZW9tX2FyZWEoZGF0YSA9IGRmW2RmJFogPCAwLjE4LCBdLCANCiAgICAgICAgICAgIGFlcyh4ID0gWiwgeSA9IERlbnNpdHkpLCBmaWxsID0gIiNBMkMyRTAiLCBhbHBoYSA9IDAuNSkgKyAgIyBTbGlnaHRseSBkYXJrZXIgYmx1ZSBmb3IgWiA8IDAuMTgNCiAgZ2VvbV9hcmVhKGRhdGEgPSBkZltkZiRaID4gOCwgXSwgDQogICAgICAgICAgICBhZXMoeCA9IFosIHkgPSBEZW5zaXR5KSwgZmlsbCA9ICIjN0Q5QUMzIiwgYWxwaGEgPSAwLjUpICsgICMgRXZlbiBkYXJrZXIgYmx1ZSBmb3IgWiA+IDgNCiAgZ2VvbV9hcmVhKGRhdGEgPSBkZlthYnMoZGYkWikgPCAwLjUsIF0sIA0KICAgICAgICAgICAgYWVzKHggPSBaLCB5ID0gRGVuc2l0eSksIGZpbGwgPSAiIzZCOUFDMyIsIGFscGhhID0gMC41KSArICAjIERhcmsgYmx1ZSBmb3IgfFp8IDwgMC41DQogIGxhYnModGl0bGUgPSAiNC4yIEFyZWEgdW5kZXIgdGhlIGN1cnZlLCBQYXJ0IElJIiwgICMgVGl0bGUgb2YgdGhlIHBsb3QNCiAgICAgICB4ID0gIloiLCB5ID0gIkRlbnNpdHkiKSArICAjIExhYmVscyBmb3IgeCBhbmQgeSBheGVzDQogIHRoZW1lX2RhcmsoKSArICAjIEFwcGx5IGRhcmsgdGhlbWUgZm9yIHRoZSBwbG90DQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxOCwgZmFjZSA9ICJib2xkIiwgY29sb3IgPSAibmF2eSIpLCAgIyBUaXRsZSBmb3JtYXR0aW5nDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCwgY29sb3IgPSAibmF2eSIpLCAgIyBYLWF4aXMgdGl0bGUgZm9ybWF0dGluZw0KICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGNvbG9yID0gIm5hdnkiKSwgICMgWS1heGlzIHRpdGxlIGZvcm1hdHRpbmcNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBjb2xvciA9ICJuYXZ5IiksICAjIEF4aXMgdGV4dCBmb3JtYXR0aW5nDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIGdyaWRsaW5lcyBmb3IgYSBjbGVhbmVyIGxvb2sNCiAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAid2hpdGUiLCBmaWxsID0gTkEsIGxpbmV3aWR0aCA9IDAuNSkgICMgV2hpdGUgYm9yZGVyIGFyb3VuZCB0aGUgcGxvdA0KICApDQoNCg0KI0VuZCBvZiBjb2RlIEV4ZXJjaXNlIDQuMjsgU3VtbWFyeSBvZiB2aXN1YWxpemF0aW9uczogDQojVGhlIFIgY29kZSBjYWxjdWxhdGVzIGFuZCB2aXN1YWxpemVzIHRoZSBwZXJjZW50YWdlcyBvZiBhIHN0YW5kYXJkIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aGluIHNwZWNpZmljIHJlZ2lvbnMuIA0KI0l0IHNob3dzIHRoYXQgODcuMTQlIG9mIHRoZSBkaXN0cmlidXRpb24gbGllcyB0byB0aGUgcmlnaHQgb2YgWiA9IC0xLjEzLCB3aGlsZSA1Ny4xMyUgaXMgdG8gdGhlIGxlZnQgb2YgWiA9IDAuMTguIA0KI0ZvciBaID4gOCwgdGhlIHBlcmNlbnRhZ2UgaXMgZWZmZWN0aXZlbHkgMC4wMCUsIGluZGljYXRpbmcgdGhhdCB0aGlzIFotc2NvcmUgaXMgZmFyIGludG8gdGhlIHRhaWwgd2l0aCBtaW5pbWFsIGFyZWEuIA0KI1RoZSBwZXJjZW50YWdlIGZvciB8WnwgPCAwLjUgaXMgMzguMjklLCBjb3ZlcmluZyB0aGUgYXJlYSBiZXR3ZWVuIFogPSAtMC41IGFuZCBaID0gMC41LiANCiNUaGUgZ3JhcGggdXNlcyBzaGFkZWQgcmVnaW9ucyB0byBjbGVhcmx5IGRlcGljdCB0aGVzZSBhcmVhcywgcHJvdmlkaW5nIGEgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIGhvdyBtdWNoIG9mIHRoZSBkaXN0cmlidXRpb24gZmFsbHMgd2l0aGluIG9yIGJleW9uZCB0aGUgc3BlY2lmaWVkIFotc2NvcmUgdGhyZXNob2xkcy4NCg0KYGBgDQoNCg0KIyNFeGVyY2lzZSA0LjQNCg0KIyMjIEV4cGxpbmF0aW9uDQoNCkF0IHRoZSBIZXJtb3NhIEJlYWNoIFRyaWF0aGxvbiwgY29tcGV0aXRvcnMgd2VyZSBjYXRlZ29yaXplZCBieSBnZW5kZXIgYW5kIGFnZS4gQWNjb3JkaW5nIHRvIE1vZW4gZXQgYWwuICgyMDIxKSwgc3R1ZGllcyByZXZlYWwgdGhhdCBjYXRlZ29yaXppbmcgcG9wdWxhdGlvbnMgaW50byB2YXJpb3VzIGdyb3VwcyBiYXNlZCBvbiBtdXR1YWxseSBzaGFyZWQgY29tbW9uYWxpdGllcywgc3VjaCBhcyByYWNlLCBldGhuaWNpdHksIHNvY2lhbCBjbGFzcywgZW1wbG95bWVudCwgYW5kIGdlbmRlciwgYWxsb3dzIGZvciBpbnRlcnNlY3Rpb25hbCBhbmFseXNpcyB0byBldmFsdWF0ZSBncmVhdGVyIGNvbXBsZXhpdGllcyB3aXRoaW4gbXV0dWFsbHkgc2hhcmluZyBwb3B1bGF0aW9ucy4gIFJhY2VycyBMZW8gYW5kIE1hcnkgYXJlIGludGVyZXN0ZWQgaW4gZXZhbHVhdGluZyB0aGVpciBwZXJmb3JtYW5jZSB3aXRoaW4gdGhlc2UgY2F0ZWdvcmllcy4gTGVvIGNvbXBldGVkIGluIHRoZSBtYWxlIDMwLTM0IGFnZSBncm91cC4gSGUgZmluaXNoZWQgaW4gNDk0OCBzZWNvbmRzLiBNYXJ5IGNvbXBldGVkIGluIHRoZSBmZW1hbGUgMjUtMjkgYWdlIGdyb3VwLiBTaGUgZmluaXNoZWQgaW4gNTUxMyBzZWNvbmRzLiBUaGUgbWFsZSBncm91cCBoYXMgYSBtZWFuIGZpbmlzaGluZyB0aW1lIG9mIDQzMTMgc2Vjb25kcyB3aXRoIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDU4MyBzZWNvbmRzLiBUaGUgZmVtYWxlIGdyb3VwIGhhcyBhIG1lYW4gb2YgNTI2MSBzZWNvbmRzIHdpdGggYSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgODA3IHNlY29uZHMuIFRoZSBmaW5pc2hpbmcgdGltZXMgaW4gYm90aCBncm91cHMgYXJlIGFwcHJveGltYXRlbHkgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuDQpFeGVyY2lzZSA0LjQ6IFBhcnQgQQ0KVGhlIG5vcm1hbCBkaXN0cmlidXRpb25zIGFyZSBiYXNlZCBvbiBMZW8gYW5kIE1hcnnigJlzIHRyaWF0aGxvbiBwZXJmb3JtYW5jZXMsIHJlc3BlY3RpdmUgdG8gYWdlIGFuZCBnZW5kZXIgZ3JvdXBzLiBGb3IgbWVuLCB0aGUgYWdlcyB3ZXJlIDMwLTM0IGdyb3VwLiBUaGUgZGlzdHJpYnV0aW9uIGlzIE4gKDQzMTMsIDU4MyksIHdoZXJlIDQzMTMgc2Vjb25kcyBpcyB0aGUgbWVhbiBhbmQgNTgzIHNlY29uZHMgaXMgdGhlIHN0YW5kYXJkIGRldmlhdGlvbi4gRm9yIHdvbWVuLCB0aGUgYWdlcyB3ZXJlIDI1LTI5IGdyb3VwLiBUaGUgZGlzdHJpYnV0aW9uIGlzIE4gKDUyNjEsIDgwNyksIHdpdGggYSBtZWFuIG9mIDUyNjEgc2Vjb25kcyBhbmQgYSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgODA3IHNlY29uZHMuIFRoaXMgbm90YXRpb24gZGVzY3JpYmVzIHRoZSBleHBlY3RlZCBkaXN0cmlidXRpb24gb2YgZmluaXNoaW5nIHRpbWVzIGluIGVhY2ggZ3JvdXAgYXNzdW1pbmcgYSBub3JtYWwgZGlzdHJpYnV0aW9uLg0KRXhlcmNpc2UgNC40OiBQYXJ0IEINClRvIGNhbGN1bGF0ZSB0aGUgWiBzY29yZXMgZm9yIExlbyBhbmQgTWFyeSwgdXNlIHRoZSBmb3JtdWxhIFogZXF1YWxzIFggbWludXMgbWVhbiBkaXZpZGVkIGJ5IHN0YW5kYXJkIGRldmlhdGlvbi4gRm9yIExlbzogWiBlcXVhbHMgNDk0OCBtaW51cyA0MzEzLCBkaXZpZGVkIGJ5IDU4Mywgd2hpY2ggZXF1YWxzIGFwcHJveGltYXRlbHkgMS4wOS4gVGhpcyBtZWFucyBMZW8gZmluaXNoZWQgMS4wOSBzdGFuZGFyZCBkZXZpYXRpb25zIGZhc3RlciB0aGFuIHRoZSBtZWFuIHRpbWUgaW4gaGlzIGdyb3VwLiBGb3IgTWFyeTogWiBlcXVhbHMgNTUxMyBtaW51cyA1MjYxLCBkaXZpZGVkIGJ5IDgwNywgd2hpY2ggZXF1YWxzIGFwcHJveGltYXRlbHkgMC4zMS4gVGhpcyBpbmRpY2F0ZXMgTWFyeSBmaW5pc2hlZCAwLjMxIHN0YW5kYXJkIGRldmlhdGlvbnMgc2xvd2VyIHRoYW4gdGhlIG1lYW4gdGltZSBpbiBoZXIgZ3JvdXAuIFRoZSBaIHNjb3JlcyBxdWFudGlmeSBob3cgTGVvIGFuZCBNYXJ54oCZcyB0aW1lcyBjb21wYXJlIHRvIHRoZWlyIGdyb3Vw4oCZcyBhdmVyYWdlLg0KRXhlcmNpc2UgNC40OiBQYXJ0IEMNCkxlbyByYW5rZWQgYmV0dGVyIGluIGhpcyBncm91cCBjb21wYXJlZCB0byBNYXJ5LiBMZW/igJlzIFogc2NvcmUgb2YgYXBwcm94aW1hdGVseSAxLjA5IHNob3dzIGhlIGZpbmlzaGVkIGZhc3RlciByZWxhdGl2ZSB0byB0aGUgYXZlcmFnZSB0aW1lIGluIGhpcyBncm91cC4gSW4gY29udHJhc3QsIE1hcnnigJlzIFogc2NvcmUgb2YgYXBwcm94aW1hdGVseSAwLjMxIHNob3dzIHNoZSBmaW5pc2hlZCBjbG9zZXIgdG8sIGJ1dCBzdGlsbCBzbG93ZXIgdGhhbiwgdGhlIGF2ZXJhZ2UgdGltZSBpbiBoZXIgZ3JvdXAuIEEgaGlnaGVyIFogc2NvcmUgaW5kaWNhdGVzIGEgYmV0dGVyIHBlcmZvcm1hbmNlIHJlbGF0aXZlIHRvIHRoZSBncm91cCBtZWFuLCBzbyBMZW/igJlzIHBlcmZvcm1hbmNlIHdhcyBjb21wYXJhdGl2ZWx5IGJldHRlciB3aXRoaW4gaGlzIGdyb3VwLg0KRXhlcmNpc2UgNC40OiBQYXJ0IEQNCkxlbyBmaW5pc2hlZCBmYXN0ZXIgdGhhbiBhcHByb3hpbWF0ZWx5IDg2LjE0JSBvZiB0aGUgbWVuIGluIGhpcyBncm91cC4gVGhpcyBpcyBmb3VuZCB1c2luZyB0aGUgWiBzY29yZSBvZiAxLjA5LiBUbyBmaW5kIHRoaXMgcGVyY2VudGlsZSBhbmQgdXNpbmcgdGhlIGN1bXVsYXRpdmUgZGlzdHJpYnV0aW9uIGZ1bmN0aW9uIChDREYpIHZhbHVlIG9mIFogZXF1YWxzIDEuMDksIHdoaWNoIGlzIGFwcHJveGltYXRlbHkgMC44NjE0LiwgTGVv4oCZcyBwZXJmb3JtYW5jZSB3YXMgYmV0dGVyIHRoYW4gYWJvdXQgODYuMTQlIG9mIGhpcyBwZWVycy4NCkV4ZXJjaXNlIDQuNDogUGFydCBFDQpNYXJ5IGZpbmlzaGVkIGZhc3RlciB0aGFuIGFwcHJveGltYXRlbHkgNjEuMjQlIG9mIHRoZSB3b21lbiBpbiBoZXIgZ3JvdXAuIFRoaXMgaXMgZGV0ZXJtaW5lZCBmcm9tIE1hcnnigJlzIFogc2NvcmUgb2YgMC4zMS4gVXNpbmcgdGhlIENERiB2YWx1ZSBmb3IgWiBlcXVhbHMgMC4zMSwgd2hpY2ggaXMgMC42MTI0OyBmaW5kaW5nIHRoYXQgTWFyeeKAmXMgcGVyZm9ybWFuY2Ugd2FzIGJldHRlciB0aGFuIGFwcHJveGltYXRlbHkgNjEuMjQlIG9mIHRoZSB3b21lbiBpbiBoZXIgZ3JvdXAuDQpFeGVyY2lzZSA0LjQ6IFBhcnQgRg0KQ29uc2lkZXJpbmcgaWYgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgZmluaXNoaW5nIHRpbWVzIGFyZSBub3QgbmVhcmx5IG5vcm1hbCwgdGhlIHJlc3VsdHMgZnJvbSBwYXJ0cyBCIHRocm91Z2ggRSBjb3VsZCBjaGFuZ2UuIEJvbm8gZXQgYWwuICgyMDE3KSBzdWdnZXN0IHRoYXQgd2hlbiBkYXRhIGRvZXMgbm90IGNvbmZvcm0gdG8gYSBub3JtYWwgZGlzdHJpYnV0aW9uLCByZXNlYXJjaGVycyBzaG91bGQgY29uc2lkZXIgYWx0ZXJuYXRpdmUgYXBwcm9hY2hlcywgc3VjaCBhcyBnZW5lcmFsaXplZCBhZGRpdGl2ZSBtb2RlbHMgZm9yIGxvY2F0aW9uLCBzY2FsZSwgYW5kIHNoYXBlLCB0byBkZXRlcm1pbmUgYSBtb3JlIGFwcHJvcHJpYXRlIGRpc3RyaWJ1dGlvbiBmb3IgdGhlIHJlc3BvbnNlIHZhcmlhYmxlLiBGb3IgZXhhbXBsZSwgaWYgdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5pc2hpbmcgdGltZXMgZm9yIHRoZSBtZW4sIGFnZXMgMzAgLSAzNCBncm91cCB3ZXJlIHNrZXdlZCwgd2l0aCBhIGxvbmdlciB0YWlsIG9uIHRoZSByaWdodCwgdGhlIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBtaWdodCBub3QgYWNjdXJhdGVseSByZWZsZWN0IHRoZSBkaXN0cmlidXRpb27igJlzIGNoYXJhY3RlcmlzdGljcy4gSW4gc3VjaCBhIHNjZW5hcmlvLCBMZW/igJlzIFogc2NvcmUsIHdoaWNoIGFzc3VtZXMgb2Ygbm9ybWFsaXR5LCBtaWdodCBub3QgY29ycmVjdGx5IHJlcHJlc2VudCBoaXMgc3RhbmRpbmcgcmVsYXRpdmUgdG8gaGlzIHBlZXJzLiBUaGlzIGNvdWxkIGxlYWQgdG8gYW4gaW5jb3JyZWN0IGNhbGN1bGF0aW9uIG9mIHRoZSBwZXJjZW50YWdlIG9mIHRyaWF0aGxldGVzIGhlIGZpbmlzaGVkIGZhc3RlciB0aGFuLiBGb3IgaW5zdGFuY2UsIGlmIHRoZSBhY3R1YWwgZGlzdHJpYnV0aW9uIHdlcmUgaGVhdmlseSByaWdodCBza2V3ZWQsIExlb+KAmXMgWiBzY29yZSBtaWdodCBzdWdnZXN0IGhlIGlzIGluIGEgYmV0dGVyIHBlcmNlbnRpbGUgdGhhbiBoZSB0cnVseSBpcyBpZiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBhc3N1bXB0aW9uIHdlcmUgYXBwbGllZC4gU2ltaWxhcmx5LCBpZiBNYXJ54oCZcyBncm91cCBoYWQgYSBkaXN0cmlidXRpb24gd2l0aCBhIHNpZ25pZmljYW50IGxlZnQgc2tldywgaGVyIFogc2NvcmUgbWlnaHQgdW5kZXJlc3RpbWF0ZSBob3cgaGVyIHBlcmZvcm1hbmNlIGNvbXBhcmVzIHRvIG90aGVycy4gTm9uLW5vcm1hbCBkaXN0cmlidXRpb25zIHdvdWxkIHJlcXVpcmUgbW9yZSB0YWlsb3JlZCBzdGF0aXN0aWNhbCBtZXRob2RzIHRvIGFjY3VyYXRlbHkgYXNzZXNzIHBlcmZvcm1hbmNlLg0KDQoNCg0KDQpgYGB7cn0NCg0KI0JlZ2luIGNvZGUgRXhlcmNpc2UgNC40DQoNCiMgTG9hZCBsaWJyYXJpZXMsIGlmIG5lZWRlZA0KbGlicmFyeShnZ3Bsb3QyKSAgICMgRm9yIGNyZWF0aW5nIHBsb3RzDQpsaWJyYXJ5KGdyaWRFeHRyYSkgIyBGb3IgYXJyYW5naW5nIG11bHRpcGxlIHBsb3RzDQoNCiMgRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIGZvciBlYWNoIGdyb3VwDQojIE1lbiwgQWdlcyAzMCAtIDM0DQptdV9tZW4gPC0gNDMxMyAgICAgIyBNZWFuIGZpbmlzaGluZyB0aW1lIGluIHNlY29uZHMgZm9yIG1lbiwgYWdlcyAzMC0zNA0Kc2lnbWFfbWVuIDwtIDU4MyAgICMgU3RhbmRhcmQgZGV2aWF0aW9uIG9mIGZpbmlzaGluZyB0aW1lcyBmb3IgbWVuLCBhZ2VzIDMwLTM0DQp0aW1lX2xlbyA8LSA0OTQ4ICAgIyBMZW8ncyBmaW5pc2hpbmcgdGltZSBpbiBzZWNvbmRzDQoNCiMgV29tZW4sIEFnZXMgMjUgLSAyOQ0KbXVfd29tZW4gPC0gNTI2MSAgICMgTWVhbiBmaW5pc2hpbmcgdGltZSBpbiBzZWNvbmRzIGZvciB3b21lbiwgYWdlcyAyNS0yOQ0Kc2lnbWFfd29tZW4gPC0gODA3ICMgU3RhbmRhcmQgZGV2aWF0aW9uIG9mIGZpbmlzaGluZyB0aW1lcyBmb3Igd29tZW4sIGFnZXMgMjUtMjkNCnRpbWVfbWFyeSA8LSA1NTEzICAjIE1hcnkncyBmaW5pc2hpbmcgdGltZSBpbiBzZWNvbmRzDQoNCiMgQ3JlYXRlIGEgc2VxdWVuY2Ugb2YgZmluaXNoaW5nIHRpbWVzIGZvciBwbG90dGluZw0KIyBUaGlzIHNlcXVlbmNlIHdpbGwgYmUgdXNlZCB0byBwbG90IHRoZSBkZW5zaXR5IGZ1bmN0aW9ucyBmb3IgYm90aCBncm91cHMNCmZpbmlzaGluZ190aW1lc19tZW4gPC0gc2VxKG11X21lbiAtIDQqc2lnbWFfbWVuLCBtdV9tZW4gKyA0KnNpZ21hX21lbiwgbGVuZ3RoLm91dCA9IDEwMDApDQpmaW5pc2hpbmdfdGltZXNfd29tZW4gPC0gc2VxKG11X3dvbWVuIC0gNCpzaWdtYV93b21lbiwgbXVfd29tZW4gKyA0KnNpZ21hX3dvbWVuLCBsZW5ndGgub3V0ID0gMTAwMCkNCg0KIyBDYWxjdWxhdGUgZGVuc2l0aWVzIGZvciB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbnMNCiMgVGhpcyBpcyB1c2VkIHRvIHBsb3QgdGhlIG5vcm1hbCBkaXN0cmlidXRpb24gY3VydmVzDQpkZW5zaXR5X21lbiA8LSBkbm9ybShmaW5pc2hpbmdfdGltZXNfbWVuLCBtZWFuID0gbXVfbWVuLCBzZCA9IHNpZ21hX21lbikNCmRlbnNpdHlfd29tZW4gPC0gZG5vcm0oZmluaXNoaW5nX3RpbWVzX3dvbWVuLCBtZWFuID0gbXVfd29tZW4sIHNkID0gc2lnbWFfd29tZW4pDQoNCiMgQ3JlYXRlIGRhdGEgZnJhbWVzIGZvciBwbG90dGluZw0KZGZfbWVuIDwtIGRhdGEuZnJhbWUoRmluaXNoaW5nVGltZSA9IGZpbmlzaGluZ190aW1lc19tZW4sIERlbnNpdHkgPSBkZW5zaXR5X21lbikNCmRmX3dvbWVuIDwtIGRhdGEuZnJhbWUoRmluaXNoaW5nVGltZSA9IGZpbmlzaGluZ190aW1lc193b21lbiwgRGVuc2l0eSA9IGRlbnNpdHlfd29tZW4pDQoNCiMgQ3JlYXRlIHRoZSBwbG90IGZvciBMZW8NCnBsb3RfbGVvIDwtIGdncGxvdChkZl9tZW4sIGFlcyh4ID0gRmluaXNoaW5nVGltZSwgeSA9IERlbnNpdHkpKSArDQogIGdlb21fbGluZShjb2xvciA9ICJsaWdodGJsdWUiKSArICAjIExpbmUgcmVwcmVzZW50aW5nIHRoZSBkZW5zaXR5IGZ1bmN0aW9uDQogIGdlb21fYXJlYShkYXRhID0gZGZfbWVuW2RmX21lbiRGaW5pc2hpbmdUaW1lID4gdGltZV9sZW8sIF0sDQogICAgICAgICAgICBhZXMoeCA9IEZpbmlzaGluZ1RpbWUsIHkgPSBEZW5zaXR5KSwgZmlsbCA9ICIjQjNDREUwIiwgYWxwaGEgPSAwLjUpICsgICMgU2hhZGVkIGFyZWEgcmVwcmVzZW50aW5nIHRoZSB0aW1lcyBmYXN0ZXIgdGhhbiBMZW8NCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gdGltZV9sZW8sIGNvbG9yID0gImRhcmtibHVlIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKyAgIyBWZXJ0aWNhbCBsaW5lIGZvciBMZW8ncyBmaW5pc2hpbmcgdGltZQ0KICBsYWJzKHRpdGxlID0gIkxlbydzIFRpbWU6IE1lbiAzMC0zNCIsICAjIFRpdGxlIG9mIHRoZSBwbG90DQogICAgICAgeCA9ICJGaW5pc2hpbmcgVGltZSAoc2Vjb25kcykgXG5NZW4sIEFnZXMgMzAtMzQiLCAgIyBYLWF4aXMgbGFiZWwNCiAgICAgICB5ID0gIkRlbnNpdHkgb2YgRmluaXNoaW5nIFRpbWVzIikgKyAgIyBZLWF4aXMgbGFiZWwNCiAgdGhlbWVfZGFyaygpICsgICMgRGFyayB0aGVtZSBmb3IgdGhlIHBsb3QgYmFja2dyb3VuZA0KICB0aGVtZSgNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIsIGNvbG9yID0gImRhcmtibHVlIiksICAjIEZvcm1hdHRpbmcgZm9yIHRoZSB0aXRsZQ0KICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGNvbG9yID0gImRhcmtibHVlIiksICAjIFgtYXhpcyB0aXRsZSBmb3JtYXR0aW5nDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiZGFya2JsdWUiKSwgICMgWS1heGlzIHRpdGxlIGZvcm1hdHRpbmcNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBjb2xvciA9ICJkYXJrYmx1ZSIpLCAgIyBBeGlzIHRleHQgZm9ybWF0dGluZw0KICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksICAjIFJlbW92ZSBncmlkbGluZXMgZm9yIGEgY2xlYW5lciBsb29rDQogICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG9yID0gIndoaXRlIiwgZmlsbCA9IE5BLCBsaW5ld2lkdGggPSAwLjUpLCAgIyBCb3JkZXIgYXJvdW5kIHRoZSBwbG90DQogICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMjAsIDEwLCAxMCwgMTApICAjIEluY3JlYXNlZCB0b3AgbWFyZ2luIHRvIGF2b2lkIG92ZXJsYXANCiAgKQ0KDQojIENyZWF0ZSB0aGUgcGxvdCBmb3IgTWFyeQ0KcGxvdF9tYXJ5IDwtIGdncGxvdChkZl93b21lbiwgYWVzKHggPSBGaW5pc2hpbmdUaW1lLCB5ID0gRGVuc2l0eSkpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gImxpZ2h0cGluayIpICsgICMgTGluZSByZXByZXNlbnRpbmcgdGhlIGRlbnNpdHkgZnVuY3Rpb24NCiAgZ2VvbV9hcmVhKGRhdGEgPSBkZl93b21lbltkZl93b21lbiRGaW5pc2hpbmdUaW1lID4gdGltZV9tYXJ5LCBdLA0KICAgICAgICAgICAgYWVzKHggPSBGaW5pc2hpbmdUaW1lLCB5ID0gRGVuc2l0eSksIGZpbGwgPSAiI0Y1QjBCMyIsIGFscGhhID0gMC41KSArICAjIFNoYWRlZCBhcmVhIHJlcHJlc2VudGluZyB0aGUgdGltZXMgZmFzdGVyIHRoYW4gTWFyeQ0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSB0aW1lX21hcnksIGNvbG9yID0gImRhcmtyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArICAjIFZlcnRpY2FsIGxpbmUgZm9yIE1hcnkncyBmaW5pc2hpbmcgdGltZQ0KICBsYWJzKHRpdGxlID0gIk1hcnkncyBUaW1lOiBXb21lbiAyNS0yOSIsICAjIFRpdGxlIG9mIHRoZSBwbG90DQogICAgICAgeCA9ICJGaW5pc2hpbmcgVGltZSAoc2Vjb25kcykgXG5Xb21lbiwgQWdlcyAyNS0yOSIsICAjIFgtYXhpcyBsYWJlbA0KICAgICAgIHkgPSAiRGVuc2l0eSBvZiBGaW5pc2hpbmcgVGltZXMiKSArICAjIFktYXhpcyBsYWJlbA0KICB0aGVtZV9kYXJrKCkgKyAgIyBEYXJrIHRoZW1lIGZvciB0aGUgcGxvdCBiYWNrZ3JvdW5kDQogIHRoZW1lKA0KICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiwgY29sb3IgPSAiZGFya3JlZCIpLCAgIyBGb3JtYXR0aW5nIGZvciB0aGUgdGl0bGUNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBjb2xvciA9ICJkYXJrcmVkIiksICAjIFgtYXhpcyB0aXRsZSBmb3JtYXR0aW5nDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiZGFya3JlZCIpLCAgIyBZLWF4aXMgdGl0bGUgZm9ybWF0dGluZw0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG9yID0gImRhcmtyZWQiKSwgICMgQXhpcyB0ZXh0IGZvcm1hdHRpbmcNCiAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgZ3JpZGxpbmVzIGZvciBhIGNsZWFuZXIgbG9vaw0KICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJ3aGl0ZSIsIGZpbGwgPSBOQSwgbGluZXdpZHRoID0gMC41KSwgICMgQm9yZGVyIGFyb3VuZCB0aGUgcGxvdA0KICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDIwLCAxMCwgMTAsIDEwKSAgIyBJbmNyZWFzZWQgdG9wIG1hcmdpbiB0byBhdm9pZCBvdmVybGFwDQogICkNCg0KIyBDb21iaW5lIHRoZSBwbG90cyBpbnRvIGEgc2luZ2xlIHZpZXcNCmdyaWQuYXJyYW5nZShwbG90X2xlbywgcGxvdF9tYXJ5LCBuY29sID0gMiwgd2lkdGhzID0gYygxLCAxKSwgdG9wID0gIlRyaWF0aGxldGVzJyBQZXJmb3JtYW5jZSIpDQoNCiNFbmQgb2YgY29kZSBFeGVyY2lzZSA0LjQ7IHN1bW1hcnkgb2YgdmlzdWFsaXphdGlvbnM6IA0KI1RoZSBwbG90cyB2aXN1YWxpemUgdGhlIGZpbmlzaGluZyB0aW1lcyBvZiBMZW8gYW5kIE1hcnkgd2l0aGluIHRoZWlyIHJlc3BlY3RpdmUgdHJpYXRobG9uIGFnZSBncm91cHMuDQojRm9yIExlbywgY29tcGV0aW5nIGluIHRoZSBNZW4sIEFnZXMgMzAtMzQgZ3JvdXAsIGhpcyBmaW5pc2hpbmcgdGltZSBvZiA0OTQ4IHNlY29uZHMgaXMgcmVwcmVzZW50ZWQgYnkgYSB2ZXJ0aWNhbCBkYXNoZWQgbGluZSBvbiB0aGUgcGxvdC4gDQojVGhlIHNoYWRlZCBhcmVhIHRvIHRoZSByaWdodCBvZiB0aGlzIGxpbmUgaW5kaWNhdGVzIHRoZSBwcm9wb3J0aW9uIG9mIG1lbiB3aG8gZmluaXNoZWQgc2xvd2VyIHRoYW4gTGVvLCB3aGljaCBjb3JyZXNwb25kcyB0byB0aGUgcGVyY2VudGFnZSBvZiB0cmlhdGhsZXRlcyBMZW8gb3V0cGVyZm9ybWVkLiANCiNGb3IgTWFyeSwgY29tcGV0aW5nIGluIHRoZSBXb21lbiwgQWdlcyAyNS0yOSBncm91cCwgaGVyIGZpbmlzaGluZyB0aW1lIG9mIDU1MTMgc2Vjb25kcyBpcyBzaW1pbGFybHkgbWFya2VkLiBUaGUgc2hhZGVkIGFyZWEgdG8gdGhlIHJpZ2h0IG9mIGhlciBsaW5lIHNob3dzIHRoZSBwcm9wb3J0aW9uIG9mIHdvbWVuIHdobyBmaW5pc2hlZCBzbG93ZXIgdGhhbiBNYXJ5LiANCiNMZW8ncyBwbG90IHJldmVhbHMgdGhhdCBoZSBwZXJmb3JtZWQgYmV0dGVyIHRoYW4gYSBzaWduaWZpY2FudCBwZXJjZW50YWdlIG9mIGhpcyBncm91cCwgd2hlcmVhcyBNYXJ54oCZcyBwbG90IHNob3dzIGEgc21hbGxlciBwcm9wb3J0aW9uIG9mIHdvbWVuIHdobyBmaW5pc2hlZCBzbG93ZXIgdGhhbiBoZXIuIA0KI1RoaXMgZGlmZmVyZW5jZSBoaWdobGlnaHRzIHRoYXQsIGFsdGhvdWdoIExlbyBmaW5pc2hlZCBmYXN0ZXIgdGhhbiBNYXJ5IG92ZXJhbGwsIGhlIHBlcmZvcm1lZCByZWxhdGl2ZWx5IGJldHRlciB3aXRoaW4gaGlzIGdyb3VwIGNvbXBhcmVkIHRvIE1hcnkgaW4gaGVycywgZ2l2ZW4gdGhlIGRpc3RyaWJ1dGlvbiBvZiBmaW5pc2hpbmcgdGltZXMuDQoNCg0KYGBgDQoNCg0KDQoNCg0KDQojI0V4ZXJjaXNlIDQuOA0KDQoNCiMjIyBFeHBsaW5hdGlvbg0KDQpUaGUgQ2FwaXRhbCBBc3NldCBQcmljaW5nIE1vZGVsIChDQVBNKSBpcyBhc3N1bWVkIHRvIGJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBUaGUgc2luZ2xlLXBlcmlvZCwgb25lLWZhY3RvciBDQVBNLCBkZXZlbG9wZWQgYnkgU2hhcnBlICgxOTY0KSwgaXMgdGhlIG1vc3QgYmFzaWMgYW5kIHdpZGVseSB1c2VkIGJlbmNobWFyayBhc3NldCBwcmljaW5nIG1vZGVsIGluIGJvdGggcHJhY3RpY2UgYW5kIHJlc2VhcmNoLCBhY2NvcmRpbmcgdG8gYSBwcm9mZXNzaW9uYWwgb3JnYW5pemF0aW9u4oCZcyBzdXJ2ZXkgcmVwb3J0IChQaGFtICYgUGh1b2MsIDIwMjApIFRoZSBzdXBwb3NlZCBwb3J0Zm9saW8gaW5jbHVkZXMgYW4gYXZlcmFnZSBhbm51YWwgcmV0dXJuIG9mIDE0LjclIGFuZCBhIHN0YW5kYXJkIGRldmlhdGlvbiBvZiAzMyUsIGEgcmV0dXJuIG9mIDAlLiBUaGlzIGFzc3VtZXMgdGhlIHBvcnRmb2xpbyB2YWx1ZSByZW1haW5zIHVuY2hhbmdlZC4gTmVnYXRpdmUgcmV0dXJucyBzaG93IGxvc3Nlcywgd2hpbGUgcG9zaXRpdmUgcmV0dXJucyBzaG93IGdyb3d0aC4gQWNjb3JkaW5nIHRvIFRob25vbiBldCBhbC4gKDIwMjMpLCBzdHVkaWVzIHJldmVhbCB0aGF0IHV0aWxpemluZyBmaW5hbmNpYWwgbW9kZWxzIGFsbG93IGZvciBtZWFzdXJpbmcgZGl2ZXJzZSBtZXRob2RvbG9naWVzIGZvciBjYWxjdWxhdGluZyB0aGUgcmV0dXJuIG9uIGludmVzdG1lbnRzLCB3aGljaCBiZW5lZml0IG1vcmUgc3RhbmRhcmRpemVkIGRlc2lnbnMgdG8gZmFjaWxpdGF0ZSBhbmQgY29tcGFyZSBwb3NpdGl2ZSBvciBuZWdhdGl2ZSByZXR1cm5zLiAgVGhlIENBUE0gbW9kZWwgcHJvdmlkZXMgaW5zaWdodHMgaW50byB0aGUgZGlzdHJpYnV0aW9uIG9mIHJldHVybnMgYW5kIGhlbHBzIGV2YWx1YXRlIHRoZSBwcm9iYWJpbGl0eSBvZiB2YXJpb3VzIGZpbmFuY2lhbCBvdXRjb21lcy4NCkV4ZXJjaXNlIDQuODogUGFydCBBDQpUaGUgcHJvYmFiaWxpdHkgb2YgaGF2aW5nIGEgcmV0dXJuIGxlc3MgdGhhbiAwJSBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgcGVyY2VudGFnZSBvZiBsb3NpbmcgbW9uZXkuIFRoZSBwb3J0Zm9saW8gaGFzIG5vcm1hbCBkaXN0cmlidXRpb24gd2l0aCBhIG1lYW4gcmV0dXJuIG9mIDE0LjclIGFuZCBhIHN0YW5kYXJkIGRldmlhdGlvbiBvZiAzMyUuIFRoZSBaIHNjb3JlIGZvciBhIDAlIHJldHVybiBpcyBuZWVkZWQgZm9yIGNhbGN1bGF0aW9uOyBUaGlzIGlzIGNhbGN1bGF0ZWQgYXMgKDAgbWludXMgMC4xNDcpLCBkaXZpZGVkIDAuMzMgdG8gZXF1YWwgYXJvdW5kIOKIkjAuNDQ1LiBUaGVuIGluY29ycG9yYXRpbmcgdGhlIFogc2NvcmUsIHRoZSBjdW11bGF0aXZlIHByb2JhYmlsaXR5IGlzIGFyb3VuZCAzMi44JSwgd2hpY2ggcmVzdWx0cyBpbiB0aGUgcG9ydGZvbGlvIHByb2JhYmlsaXR5IG9mIGxvc2luZyBtb25leSBpbiBhYm91dCAzMi44JSBvZiB5ZWFycy4NCkV4ZXJjaXNlIDQuODogUGFydCBCDQpUaGUgY3V0b2ZmIGZvciB0aGUgaGlnaGVzdCAxNSUgb2YgYW5udWFsIHJldHVybnMgaXMgaWRlbnRpZmllZCBieSB0aGUgODV0aCBwZXJjZW50aWxlIG9mIHRoZSBkaXN0cmlidXRpb24uIFRoZSBaIHNjb3JlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDg1dGggcGVyY2VudGlsZSBpcyBhcm91bmQgMS4wMzYuIFRoZSBaIHNjb3JlIHRoZW4gaXMgY29udmVydGVkIHRvIHJldHVybiBhIHZhbHVlIGJ5IGNhbGN1bGF0aW5nIHRoZSBjdXRvZmYgcmV0dXJuOyB0aGlzIGlzIGNhbGN1bGF0ZWQgYnkgMC4xNDcgcGx1cyAoMS4wMzYgdGltZXMgMC4zMykgZXF1YWxpbmcgMC40NzAsIGNvbnZlcnRlZCB0byBwZXJjZW50YWdlIGFzIDQ3LjAlLiBUaGlzIG1lYW5zIHRoZSBjdXRvZmYgZm9yIHRoZSBoaWdoZXN0IDE1JSBvZiBhbm51YWwgcmV0dXJucyBpcyBhcm91bmQgNDcuMCUuDQoNCg0KDQoNCg0KDQpgYGB7cn0NCg0KDQojIExvYWQgdGhlIG5lY2Vzc2FyeSBsaWJyYXJ5DQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KIyBNZWFuIGFubnVhbCByZXR1cm4gKDE0LjclKSBpcyBjb252ZXJ0ZWQgdG8gZGVjaW1hbCBmb3JtICgwLjE0NykNCm11IDwtIDAuMTQ3ICAjIE1lYW4gcmV0dXJuDQojIFN0YW5kYXJkIGRldmlhdGlvbiAoMzMlKSBpcyBjb252ZXJ0ZWQgdG8gZGVjaW1hbCBmb3JtICgwLjMzKQ0Kc2lnbWEgPC0gMC4zMyAgIyBTdGFuZGFyZCBkZXZpYXRpb24NCg0KIyBDcmVhdGUgYSBzZXF1ZW5jZSBvZiByZXR1cm4gdmFsdWVzIGZyb20gLTAuNSB0byAwLjUgd2l0aCAxMDAwIHBvaW50cw0KcmV0dXJucyA8LSBzZXEoLTAuNSwgMC41LCBsZW5ndGgub3V0ID0gMTAwMCkNCiMgQ29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgZGVuc2l0eSBmdW5jdGlvbiBmb3IgdGhlc2UgcmV0dXJuIHZhbHVlcw0KZGVuc2l0eSA8LSBkbm9ybShyZXR1cm5zLCBtZWFuID0gbXUsIHNkID0gc2lnbWEpDQoNCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSBmb3IgcGxvdHRpbmcNCmRmIDwtIGRhdGEuZnJhbWUoUmV0dXJuID0gcmV0dXJucywgRGVuc2l0eSA9IGRlbnNpdHkpDQoNCiMgQ2FsY3VsYXRlIHRoZSBaLXNjb3JlIGZvciBhIHJldHVybiBvZiAwJSAoaS5lLiwgd2hlbiBSZXR1cm4gPSAwKQ0Kel9zY29yZV9iZWxvd196ZXJvIDwtICgwIC0gbXUpIC8gc2lnbWENCiMgQ29tcHV0ZSB0aGUgcHJvYmFiaWxpdHkgb2YgdGhlIHJldHVybiBiZWluZyBsZXNzIHRoYW4gMCUgdXNpbmcgdGhlIFotc2NvcmUNCnByb2JhYmlsaXR5X2JlbG93X3plcm8gPC0gcG5vcm0oel9zY29yZV9iZWxvd196ZXJvKQ0KDQojIENhbGN1bGF0ZSB0aGUgWi1zY29yZSBjb3JyZXNwb25kaW5nIHRvIHRoZSA4NXRoIHBlcmNlbnRpbGUNCnpfc2NvcmVfODV0aCA8LSBxbm9ybSgwLjg1KQ0KIyBDb21wdXRlIHRoZSBjdXRvZmYgcmV0dXJuIHZhbHVlIGZvciB0aGUgdG9wIDE1JSBvZiByZXR1cm5zDQpjdXRvZmZfcmV0dXJuIDwtIG11ICsgel9zY29yZV84NXRoICogc2lnbWENCg0KIyBDcmVhdGUgdGhlIHBsb3QgdXNpbmcgZ2dwbG90Mg0KcCA8LSBnZ3Bsb3QoZGYsIGFlcyh4ID0gUmV0dXJuLCB5ID0gRGVuc2l0eSkpICsNCiAgIyBQbG90IHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIGN1cnZlIGluIGRhcmsgZ3JleQ0KICBnZW9tX2xpbmUoY29sb3IgPSAiIzMzMzMzMyIpICsgICMgRGFyayBncmV5IGNvbG9yIGZvciB0aGUgY3VydmUNCiAgDQogICMgSGlnaGxpZ2h0IHRoZSBhcmVhIHdoZXJlIHJldHVybnMgYXJlIGxlc3MgdGhhbiAwJQ0KICBnZW9tX2FyZWEoZGF0YSA9IGRmW2RmJFJldHVybiA8IDAsIF0sIGFlcyh4ID0gUmV0dXJuLCB5ID0gRGVuc2l0eSksIGZpbGwgPSAiI0NDMzMzMyIsIGFscGhhID0gMC42KSArICAjIERlZXAgcmVkIGNvbG9yDQogIA0KICAjIEFkZCBhIHZlcnRpY2FsIGRhc2hlZCBsaW5lIGF0IDAlIHJldHVybg0KICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvciA9ICIjRkYwMDAwIikgKyAgIyBSZWQgbGluZSBmb3IgMCUgcmV0dXJuDQogIA0KICAjIEFkZCBhIHZlcnRpY2FsIGRhc2hlZCBsaW5lIGF0IHRoZSBjdXRvZmYgZm9yIHRoZSBoaWdoZXN0IDE1JSBvZiByZXR1cm5zDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGN1dG9mZl9yZXR1cm4sIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gIiMwMDk5MDAiKSArICAjIERhcmsgZ3JlZW4gbGluZSBmb3IgODV0aCBwZXJjZW50aWxlDQogIA0KICAjIEFkZCBkZXNjcmlwdGl2ZSBsYWJlbHMgYW5kIGEgY2FwdGlvbiB0byB0aGUgcGxvdA0KICBsYWJzKA0KICAgIHRpdGxlID0gIjQuOCBDQVBNIiwNCiAgICB4ID0gIkFubnVhbCBSZXR1cm4gKCUpIiwNCiAgICB5ID0gIlByb2JhYmlsaXR5IERlbnNpdHkiLA0KICAgIGNhcHRpb24gPSBzcHJpbnRmKCJNZWFuIFJldHVybjogJS4yZiUlIHwgU3RkIERldjogJS4yZiUlXG5DdXRvZmYgZm9yIFRvcCAxNSUlOiAlLjJmJSUgfCBQZXJjZW50YWdlIG9mIFllYXJzIHdpdGggUmV0dXJuIDwgMCUlOiAlLjJmJSUiLA0KICAgICAgICAgICAgICAgICAgICAgIG11ICogMTAwLCBzaWdtYSAqIDEwMCwgY3V0b2ZmX3JldHVybiAqIDEwMCwgcHJvYmFiaWxpdHlfYmVsb3dfemVybyAqIDEwMCkNCiAgKSArDQogIA0KICAjIEFubm90YXRlIHRoZSBwbG90IHdpdGggdGV4dCBmb3IgY2xhcml0eQ0KICBhbm5vdGF0ZSgidGV4dCIsIHggPSAtMC40LCB5ID0gbWF4KGRmJERlbnNpdHkpICogMC43LCBsYWJlbCA9IHNwcmludGYoIlJldHVybiA8IDAlJTogJS4yZiUlIiwgcHJvYmFiaWxpdHlfYmVsb3dfemVybyAqIDEwMCksIGNvbG9yID0gIiNGRjAwMDAiKSArDQogIGFubm90YXRlKCJ0ZXh0IiwgeCA9IGN1dG9mZl9yZXR1cm4sIHkgPSBtYXgoZGYkRGVuc2l0eSkgKiAwLjcsIGxhYmVsID0gc3ByaW50ZigiODV0aCBQZXJjZW50aWxlOiAlLjJmJSUiLCBjdXRvZmZfcmV0dXJuICogMTAwKSwgY29sb3IgPSAiIzAwOTkwMCIpICsNCiAgDQogICMgQWRqdXN0IHRoZSB4LWF4aXMgYW5kIHktYXhpcyBsaW1pdHMgdG8gZW5zdXJlIHRoZSBlbnRpcmUgcGxvdCBpcyB2aXNpYmxlDQogIHhsaW0oLTAuNSwgMC41KSArICAjIEV4dGVuZCB4LWF4aXMgbGltaXRzDQogIHlsaW0oMCwgbWF4KGRmJERlbnNpdHkpICogMS4yKSArICAjIEV4dGVuZCB5LWF4aXMgbGltaXRzDQogIA0KICAjIEFwcGx5IGEgbWluaW1hbCB0aGVtZSB3aXRoIGN1c3RvbWl6ZWQgdGV4dCBhbmQgcGxvdCBhcHBlYXJhbmNlDQogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTUpICsNCiAgdGhlbWUoDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSwgc2l6ZSA9IDE4LCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigxMCwgMTAsIDEwLCAxMCkgICMgSW5jcmVhc2UgbWFyZ2lucyB0byBwcmV2ZW50IGN1dC1vZmYNCiAgKQ0KDQojIFByaW50IHRoZSBwbG90DQpwcmludChwKQ0KDQojRW5kIG9mIGNvZGUgRXhlcmNpc2UgNC44OyBzdW1tYXJ5IG9mIHZpc3VhbGl6YXRpb25zOiANCiMgVGhpcyBjcmVhdGVzIGEgdmlzdWFsIHJlcHJlc2VudGF0aW9uIG9mIHBvcnRmb2xpbyByZXR1cm5zIGJhc2VkIG9uIHRoZSBDYXBpdGFsIEFzc2V0IFByaWNpbmcgTW9kZWwgKENBUE0pLCBhc3N1bWluZyBub3JtYWxseSBkaXN0cmlidXRlZCByZXR1cm5zLiANCiNUaGUgcGxvdCBzaG93cyB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBjdXJ2ZSBmb3IgYW5udWFsIHJldHVybnMgd2l0aCBhIG1lYW4gb2YgMTQuNyUgYW5kIGEgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDMzJS4gDQojVGhlIGRhcmsgZ3JleSBjdXJ2ZSBpbGx1c3RyYXRlcyB0aGUgZGlzdHJpYnV0aW9uLCB3aGlsZSBzaGFkZWQgYXJlYXMgaGlnaGxpZ2h0IHNwZWNpZmljIHJldHVybiByYW5nZXMuIEEgcmVkIGRhc2hlZCBsaW5lIGluZGljYXRlcyB0aGUgMCUgcmV0dXJuIHRocmVzaG9sZCwgYW5kIGEgZGFyayBncmVlbiBkYXNoZWQgbGluZSBtYXJrcyB0aGUgY3V0b2ZmIGZvciB0aGUgaGlnaGVzdCAxNSUgb2YgcmV0dXJucy4gDQojVGhlIHBsb3QgaW5jbHVkZXMgYW5ub3RhdGlvbnMgZm9yIHRoZSBwZXJjZW50YWdlIG9mIHllYXJzIHdpdGggYSByZXR1cm4gbGVzcyB0aGFuIDAlIGFuZCB0aGUgY3V0b2ZmIHJldHVybiBmb3IgdGhlIHRvcCAxNSUgb2YgcmV0dXJucy4gDQojVGhpcyB2aXN1YWwgaGVscHMgaW4gdW5kZXJzdGFuZGluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHJldHVybnMgYW5kIHRoZSByZWxhdGl2ZSBwZXJmb3JtYW5jZSB0aHJlc2hvbGRzIGZvciB0aGUgcG9ydGZvbGlvLg0KDQoNCg0KYGBgDQoNCg0KIyMgTGFiIENoYXB0ZXIgNCBmcm9tIE9wZW5JbnRybyBUZXh0Ym9vaw0KDQpgYGB7cn0NCiMgU2V0IENSQU4gbWlycm9yDQpvcHRpb25zKHJlcG9zID0gYyhDUkFOID0gImh0dHBzOi8vY3Jhbi5yc3R1ZGlvLmNvbSIpKQ0KDQojIEluc3RhbGwgYW5kIGxvYWQgbmVjZXNzYXJ5IGxpYnJhcmllcw0KaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCmluc3RhbGwucGFja2FnZXMoIm9wZW5pbnRybyIpICMgVW5jb21tZW50IGlmIG5lZWRlZA0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG9wZW5pbnRybykNCg0KYGBgDQoNCg0KDQoNCg0KIyMjIEV4ZXJjaXNlIDENCg0KYGBge3Igdmlldy1naXJscy1jb3VudHN9DQphcmJ1dGhub3QkZ2lybHMNCg0KIyBFeGVyY2lzZSAxOiBGaWx0ZXIgRGF0YQ0KIyBGaWx0ZXIgZGF0YSBmb3IgTWNEb25hbGQncyBhbmQgRGFpcnkgUXVlZW4NCm1jZG9uYWxkcyA8LSBmYXN0Zm9vZCAlPiUgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIk1jZG9uYWxkcyIpDQpkYWlyeV9xdWVlbiA8LSBmYXN0Zm9vZCAlPiUgZmlsdGVyKHJlc3RhdXJhbnQgPT0gIkRhaXJ5IFF1ZWVuIikNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSAyDQoNCkluc2VydCBhbnkgdGV4dCBoZXJlLg0KDQpgYGB7ciB0cmVuZC1naXJsc30NCiMgRXhlcmNpc2UgMjogVmlzdWFsaXplIERpc3RyaWJ1dGlvbnMNCg0KIyBNY0RvbmFsZCdzIERhdGEgVmlzdWFsaXphdGlvbg0KIyBQbG90IGhpc3RvZ3JhbSBvZiBjYWxvcmllcyBmcm9tIGZhdCBhdCBNY0RvbmFsZCdzDQpnZ3Bsb3QobWNkb25hbGRzLCBhZXMoeCA9IGNhbF9mYXQpKSArDQogIGdlb21faGlzdG9ncmFtKGFlcyh5ID0gLi5kZW5zaXR5Li4pLCBiaW5zID0gMzAsIGZpbGwgPSAibGlnaHRibHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQ2Fsb3JpZXMgZnJvbSBGYXQgYXQgTWNEb25hbGQncyIsIHggPSAiQ2Fsb3JpZXMgZnJvbSBGYXQiLCB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmVlbiIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZWVuIikpDQoNCiMgRGFpcnkgUXVlZW4gRGF0YSBWaXN1YWxpemF0aW9uDQojIFBsb3QgaGlzdG9ncmFtIG9mIGNhbG9yaWVzIGZyb20gZmF0IGF0IERhaXJ5IFF1ZWVuDQpnZ3Bsb3QoZGFpcnlfcXVlZW4sIGFlcyh4ID0gY2FsX2ZhdCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHkgPSAuLmRlbnNpdHkuLiksIGJpbnMgPSAzMCwgZmlsbCA9ICJsaWdodGJsdWUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJDYWxvcmllcyBmcm9tIEZhdCBhdCBEYWlyeSBRdWVlbiIsIHggPSAiQ2Fsb3JpZXMgZnJvbSBGYXQiLCB5ID0gIkRlbnNpdHkiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmVlbiIpLCBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZWVuIikpDQoNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSAzDQoNCkluc2VydCBhbnkgdGV4dCBoZXJlLg0KDQpgYGB7ciBwbG90LXByb3AtYm95cy1hcmJ1dGhub3R9DQoNCiMgRXhlcmNpc2UgMzogTm9ybWFsIERpc3RyaWJ1dGlvbg0KDQojIENhbGN1bGF0ZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gZm9yIERhaXJ5IFF1ZWVuDQpkcW1lYW4gPC0gbWVhbihkYWlyeV9xdWVlbiRjYWxfZmF0LCBuYS5ybSA9IFRSVUUpDQpkcXNkIDwtIHNkKGRhaXJ5X3F1ZWVuJGNhbF9mYXQsIG5hLnJtID0gVFJVRSkNCg0KIyBDcmVhdGUgYSBkZW5zaXR5IGhpc3RvZ3JhbSB3aXRoIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbiBjdXJ2ZSBmb3IgRGFpcnkgUXVlZW4NCmdncGxvdChkYWlyeV9xdWVlbiwgYWVzKHggPSBjYWxfZmF0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShhZXMoeSA9IC4uZGVuc2l0eS4uKSwgYmlucyA9IDMwLCBmaWxsID0gImxpZ2h0Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBzdGF0X2Z1bmN0aW9uKGZ1biA9IGRub3JtLCBhcmdzID0gbGlzdChtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpLCBjb2xvciA9ICJ0b21hdG8iLCBzaXplID0gMSkgKw0KICBsYWJzKHRpdGxlID0gIkNhbG9yaWVzIGZyb20gRmF0IGF0IERhaXJ5IFF1ZWVuIHdpdGggTm9ybWFsIEN1cnZlIiwgeCA9ICJDYWxvcmllcyBmcm9tIEZhdCIsIHkgPSAiRGVuc2l0eSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZWVuIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JlZW4iKSkNCg0KIyBDcmVhdGUgYSBub3JtYWwgUS1RIHBsb3QgZm9yIERhaXJ5IFF1ZWVu4oCZcyBjYWxvcmllcyBmcm9tIGZhdA0KZ2dwbG90KGRhdGEgPSBkYWlyeV9xdWVlbiwgYWVzKHNhbXBsZSA9IGNhbF9mYXQpKSArDQogIGdlb21fcXEoKSArDQogIGdlb21fcXFfbGluZSgpICsNCiAgbGFicyh0aXRsZSA9ICJRLVEgUGxvdCBvZiBDYWxvcmllcyBmcm9tIEZhdCBhdCBEYWlyeSBRdWVlbiIsIHggPSAiVGhlb3JldGljYWwgUXVhbnRpbGVzIiwgeSA9ICJTYW1wbGUgUXVhbnRpbGVzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAicmVkIiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAib3JhbmdlIikpDQpgYGANCg0KDQojIyMgRXhlcmNpc2UgNA0KDQpJbnNlcnQgYW55IHRleHQgaGVyZS4NCg0KYGBge3IgZGltLXByZXNlbnR9DQojIEV4ZXJjaXNlIDQ6IFNpbXVsYXRlIE5vcm1hbCBEYXRhIGFuZCBDcmVhdGUgUS1RIFBsb3QNCg0KIyBTaW11bGF0ZSBub3JtYWwgZGF0YQ0Kc2ltX25vcm0gPC0gcm5vcm0obiA9IG5yb3coZGFpcnlfcXVlZW4pLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpDQoNCiMgQ3JlYXRlIGEgUS1RIHBsb3Qgb2Ygc2ltdWxhdGVkIG5vcm1hbCBkYXRhDQpnZ3Bsb3QoZGF0YS5mcmFtZShzaW1fbm9ybSksIGFlcyhzYW1wbGUgPSBzaW1fbm9ybSkpICsNCiAgZ2VvbV9xcSgpICsNCiAgZ2VvbV9xcV9saW5lKCkgKw0KICBsYWJzKHRpdGxlID0gIlEtUSBQbG90IG9mIFNpbXVsYXRlZCBOb3JtYWwgRGF0YSIsIHggPSAiVGhlb3JldGljYWwgUXVhbnRpbGVzIiwgeSA9ICJTYW1wbGUgUXVhbnRpbGVzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3IgPSAieWVsbG93IiksIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoY29sb3IgPSAicGluayIpKQ0KYGBgDQoNCg0KIyMjIEV4ZXJjaXNlIDUNCg0KSW5zZXJ0IGFueSB0ZXh0IGhlcmUuDQoNCmBgYHtyIGNvdW50LWNvbXBhcmV9DQojIEV4ZXJjaXNlIDU6IFByb2JhYmlsaXR5IENhbGN1bGF0aW9ucw0KDQojIENhbGN1bGF0ZSB0aGUgdGhlb3JldGljYWwgcHJvYmFiaWxpdHkgZm9yIERhaXJ5IFF1ZWVuIGl0ZW1zIGhhdmluZyBtb3JlIHRoYW4gNjAwIGNhbG9yaWVzIGZyb20gZmF0DQpwcm9iX3RoZW9yZXRpY2FsIDwtIDEgLSBwbm9ybShxID0gNjAwLCBtZWFuID0gZHFtZWFuLCBzZCA9IGRxc2QpDQpwcmludChwYXN0ZSgiVGhlb3JldGljYWwgcHJvYmFiaWxpdHkgb2YgbW9yZSB0aGFuIDYwMCBjYWxvcmllcyBmcm9tIGZhdDoiLCBwcm9iX3RoZW9yZXRpY2FsKSkNCg0KIyBDYWxjdWxhdGUgdGhlIGVtcGlyaWNhbCBwcm9iYWJpbGl0eSBmb3IgRGFpcnkgUXVlZW4gaXRlbXMgaGF2aW5nIG1vcmUgdGhhbiA2MDAgY2Fsb3JpZXMgZnJvbSBmYXQNCnByb2JfZW1waXJpY2FsIDwtIGRhaXJ5X3F1ZWVuICU+JQ0KICBmaWx0ZXIoY2FsX2ZhdCA+IDYwMCkgJT4lDQogIHN1bW1hcmlzZShwZXJjZW50ID0gbigpIC8gbnJvdyhkYWlyeV9xdWVlbikpDQpwcmludChwcm9iX2VtcGlyaWNhbCkNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSA2DQoNCkluc2VydCBhbnkgdGV4dCBoZXJlLg0KDQpgYGB7ciBwbG90LXByb3AtYm95cy1wcmVzZW50fQ0KIyBFeGVyY2lzZSA2OiBNY0RvbmFsZCdzIFByb2JhYmlsaXR5IENhbGN1bGF0aW9ucw0KDQojIENhbGN1bGF0ZSB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciBNY0RvbmFsZCdzIGNhbG9yaWVzIGZyb20gZmF0DQptY21lYW4gPC0gbWVhbihtY2RvbmFsZHMkY2FsX2ZhdCwgbmEucm0gPSBUUlVFKQ0KbWNzZCA8LSBzZChtY2RvbmFsZHMkY2FsX2ZhdCwgbmEucm0gPSBUUlVFKQ0KDQojIENhbGN1bGF0ZSB0aGUgdGhlb3JldGljYWwgcHJvYmFiaWxpdHkgZm9yIE1jRG9uYWxkJ3MgaXRlbXMgaGF2aW5nIG1vcmUgdGhhbiA1MDAgY2Fsb3JpZXMgZnJvbSBmYXQNCnByb2JfbWNfdGhlb3JldGljYWwgPC0gMSAtIHBub3JtKHEgPSA1MDAsIG1lYW4gPSBtY21lYW4sIHNkID0gbWNzZCkNCnByaW50KHBhc3RlKCJUaGVvcmV0aWNhbCBwcm9iYWJpbGl0eSBmb3IgTWNEb25hbGQncyB3aXRoIG1vcmUgdGhhbiA1MDAgY2Fsb3JpZXMgZnJvbSBmYXQ6IiwgcHJvYl9tY190aGVvcmV0aWNhbCkpDQoNCiMgQ2FsY3VsYXRlIHRoZSBlbXBpcmljYWwgcHJvYmFiaWxpdHkgZm9yIE1jRG9uYWxkJ3MgaXRlbXMgaGF2aW5nIG1vcmUgdGhhbiA1MDAgY2Fsb3JpZXMgZnJvbSBmYXQNCnByb2JfbWNfZW1waXJpY2FsIDwtIG1jZG9uYWxkcyAlPiUNCiAgZmlsdGVyKGNhbF9mYXQgPiA1MDApICU+JQ0KICBzdW1tYXJpc2UocGVyY2VudCA9IG4oKSAvIG5yb3cobWNkb25hbGRzKSkNCnByaW50KHByb2JfbWNfZW1waXJpY2FsKQ0KDQojIEVuZCBvZiBMYWIgQ2hhcHRlciA0IGZyb20gT3BlbkludHJvIFRleHRib29rDQpgYGANCg0KDQoNCg0KDQpSZWZlcmVuY2VzDQpCb25vLCBSLiwgQmxhbmNhLCBNLiwgQXJuYXUsIEouLCAmIEfDs21lei1CZW5pdG8sIEouICgyMDE3KS4gTm9uLW5vcm1hbCBkaXN0cmlidXRpb25zIGNvbW1vbmx5IHVzZWQgaW4gaGVhbHRoLCBlZHVjYXRpb24sIGFuZCBzb2NpYWwgc2NpZW5jZXM6IEEgc3lzdGVtYXRpYyByZXZpZXcuIEZyb250aWVycyBpbiBQc3ljaG9sb2d5LCA4LiBodHRwczovL2RvaS5vcmcvMTAuMzM4OS9mcHN5Zy4yMDE3LjAxNjAyDQpEaWV6LCBELiwgQmFyciwgQy4sICYgQ8ynZXRpbmtheWEtUnVuZGVsTS4gKDIwMTkpLiBPcGVuSW50cm8gc3RhdGlzdGljcyAoRm91cnRoKS4NCkVsYXNzYWlzcy1TY2hhYXAsIEouLCAmIER1aXN0ZXJzLCBLLiAoMjAyMCkuIFZhcmlhYmlsaXR5IGluIHRoZSBsb2cgZG9tYWluIGFuZCBsaW1pdGF0aW9ucyB0byBpdHMgYXBwcm94aW1hdGlvbiBieSB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4gUGhhcm1hY29tZXRyaWNzICYgU3lzdGVtcyBQaGFybWFjb2xvZ3ksIDkoNSkuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDAyL3BzcDQuMTI1MDcNCk1vZW4sIFAuLCBGbG9vZCwgUy4sICYgV2FuZywgSi4gKDIwMjEpLiBUaGUgdW5ldmVuIGxhdGVyIHdvcmsgY291cnNlOiBJbnRlcnNlY3Rpb25hbCBnZW5kZXIsIGFnZSwgcmFjZSwgYW5kIGNsYXNzIGRpc3Bhcml0aWVzLiBUaGUgSm91cm5hbHMgb2YgR2Vyb250b2xvZ3k6IFNlcmllcyBCLCA3NygxKS4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwOTMvZ2Vyb25iL2diYWIwMzkNClBoYW0sIEMuLCAmIFBodW9jLCBMLiAoMjAyMCkuIEFuIGF1Z21lbnRlZCBjYXBpdGFsIGFzc2V0IHByaWNpbmcgbW9kZWwgdXNpbmcgbmV3IG1hY3JvZWNvbm9taWMgZGV0ZXJtaW5hbnRzLiBIZWxpeW9uLCA2KDEwKSwgQXJ0aWNsZSBlMDUxODUuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMDE2L2ouaGVsaXlvbi4yMDIwLmUwNTE4NQ0KU29sb215YWssIEwuLCBTaGFycCwgUC4sICYgRWxkYXIsIEUuICgyMDIyKS4gVHJhaW5pbmcgZGl2ZXJzaXR5IHByb21vdGVzIGFic29sdXRlLXZhbHVlLWd1aWRlZCBjaG9pY2UuIFBMb1MgQ29tcHV0YXRpb25hbCBCaW9sb2d5LCAxOCgxMSksIEFydGljbGUgZTEwMTA2NjQuIGh0dHBzOi8vZG9pLm9yZy8xMC4xMzcxL2pvdXJuYWwucGNiaS4xMDEwNjY0DQpUaG9ub24sIEYuLCBHb2Rvbi1SZW5zb25uZXQsIEEuLCBQZXJvenppZWxsbywgQS4sIEdhcnNpLCBKLiwgRGFiLCBXLiwgJiBFbXNhbGVtLCBQLiAoMjAyMykuIFJldHVybiBvbiBpbnZlc3RtZW50IG9mIHdvcmtwbGFjZS1iYXNlZCBwcmV2ZW50aW9uIGludGVydmVudGlvbnM6IEEgc3lzdGVtYXRpYyByZXZpZXcuIEV1cm9wZWFuIEpvdXJuYWwgb2YgUHVibGljIEhlYWx0aCwgMzMoNCksIDYxMuKAkzYxOC4gaHR0cHM6Ly9kb2kub3JnLzEwLjEwOTMvZXVycHViL2NrYWQwOTINCg0KDQoNCg==