library(ggplot2)

# Parameters
N <- 1000
p_true <- 0.5
samples <- 5000

# Simulate g(p_hat)
p_hats <- apply(matrix(rbinom(N * samples, 1, p_true), nrow=samples), 1, mean)
g_p_hats <- p_hats / (1 - p_hats)
g_p_hats <- pmax(pmin(g_p_hats, qnorm(0.999)), qnorm(0.001))

# Theoretical variance of g(p_hat) using the Delta method
var_g_p_hat_theoretical <- (1 / (1 - p_true)^4) * (p_true * (1 - p_true) / N)
std_g_p_hat_theoretical <- sqrt(var_g_p_hat_theoretical)

# Create data frame for plotting
data <- data.frame(g_p_hats)

# Plotting
ggplot(data, aes(x=g_p_hats)) +
  geom_histogram(bins=50, aes(y=..density..), fill='purple', alpha=0.6) +
  stat_function(fun=function(x) dnorm(x, mean(g_p_hats), std_g_p_hat_theoretical), 
                color='red', size=1.5) +
  labs(x='g(p_hat)', y='Density', title='Histogram of g(p_hat) with Theoretical Normal Overlay') +
  theme_minimal()

simulate_and_plot_g_p_hat <- function(N, p_true=0.5, samples=5000) {
  # Simulate g(p_hat)
  p_hats <- apply(matrix(rbinom(N * samples, 1, p_true), nrow=samples), 1, mean)
  g_p_hats <- p_hats / (1 - p_hats)
  g_p_hats <- pmax(pmin(g_p_hats, qnorm(0.999)), qnorm(0.001))

  # Theoretical variance of g(p_hat) using the Delta method
  var_g_p_hat_theoretical <- (1 / (1 - p_true)^4) * (p_true * (1 - p_true) / N)
  std_g_p_hat_theoretical <- sqrt(var_g_p_hat_theoretical)

  # Plotting
  hist(g_p_hats, breaks=50, freq=FALSE, col='lightblue', xlab='g(p_hat)', ylab='Density',
       main=paste('Histogram of g(p_hat) for N=', N, ' with Theoretical Normal Overlay'))
  
  # Overlay the normal curve
  x <- seq(min(g_p_hats), max(g_p_hats), length.out=1000)
  lines(x, dnorm(x, mean(g_p_hats), std_g_p_hat_theoretical), col='red', lwd=2)
  legend('topright', legend=c('Empirical', 'Theoretical Normal'), fill=c('lightblue', 'red'))
}

# List of different sample sizes to simulate
sample_sizes <- c(10, 30, 50, 100, 500)

for (N in sample_sizes) {
  simulate_and_plot_g_p_hat(N)
}

NA
NA

2(A)

# Define function for calculating variance using Delta method
delta_method_var <- function(p_hat, N) {
  g_prime_p_hat <- 1 / (1 - p_hat)^2
  var_p_hat <- p_hat * (1 - p_hat) / N
  return((g_prime_p_hat ^ 2) * var_p_hat)
}

# Configurations
N_values <- c(10, 30, 100, 1000)
p_values <- c(0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99)
repeats <- 100

# Store results
results <- matrix(NA, nrow = length(N_values) * length(p_values), ncol = 4)
row_index <- 1

for (N in N_values) {
  for (p in p_values) {
    e_g_p_hats <- numeric(repeats)
    var_g_p_hats <- numeric(repeats)
    for (i in 1:repeats) {
      # Simulate data
      data <- rbinom(N, 1, p)
      p_hat <- mean(data)
      g_p_hat <- p_hat / (1 - p_hat)
      
      # Calculate estimates using Delta method
      var_g_p_hat <- delta_method_var(p_hat, N)
      
      e_g_p_hats[i] <- g_p_hat
      var_g_p_hats[i] <- var_g_p_hat
    }
    # Aggregate results
    mean_e_g_p_hat <- mean(e_g_p_hats)
    mean_var_g_p_hat <- mean(var_g_p_hats)
    results[row_index, ] <- c(N, p, mean_e_g_p_hat, mean_var_g_p_hat)
    row_index <- row_index + 1
  }
}

# Display results
for (i in 1:nrow(results)) {
  cat("N=", results[i, 1], ", p=", sprintf("%.2f", results[i, 2]), ", E[g(p_hat)]=", sprintf("%.4f", results[i, 3]), ", Var[g(p_hat)]=", sprintf("%.4f", results[i, 4]), "\n")
}
N= 10 , p= 0.01 , E[g(p_hat)]= 0.0056 , Var[g(p_hat)]= 0.0007 
N= 10 , p= 0.10 , E[g(p_hat)]= 0.1117 , Var[g(p_hat)]= 0.0184 
N= 10 , p= 0.25 , E[g(p_hat)]= 0.3694 , Var[g(p_hat)]= 0.0940 
N= 10 , p= 0.50 , E[g(p_hat)]= 1.2874 , Var[g(p_hat)]= 1.1962 
N= 10 , p= 0.75 , E[g(p_hat)]= Inf , Var[g(p_hat)]= NaN 
N= 10 , p= 0.90 , E[g(p_hat)]= Inf , Var[g(p_hat)]= NaN 
N= 10 , p= 0.99 , E[g(p_hat)]= Inf , Var[g(p_hat)]= NaN 
N= 30 , p= 0.01 , E[g(p_hat)]= 0.0115 , Var[g(p_hat)]= 0.0004 
N= 30 , p= 0.10 , E[g(p_hat)]= 0.1181 , Var[g(p_hat)]= 0.0054 
N= 30 , p= 0.25 , E[g(p_hat)]= 0.3375 , Var[g(p_hat)]= 0.0218 
N= 30 , p= 0.50 , E[g(p_hat)]= 1.0774 , Var[g(p_hat)]= 0.1756 
N= 30 , p= 0.75 , E[g(p_hat)]= 4.1003 , Var[g(p_hat)]= 14.7857 
N= 30 , p= 0.90 , E[g(p_hat)]= Inf , Var[g(p_hat)]= NaN 
N= 30 , p= 0.99 , E[g(p_hat)]= Inf , Var[g(p_hat)]= NaN 
N= 100 , p= 0.01 , E[g(p_hat)]= 0.0104 , Var[g(p_hat)]= 0.0001 
N= 100 , p= 0.10 , E[g(p_hat)]= 0.1160 , Var[g(p_hat)]= 0.0015 
N= 100 , p= 0.25 , E[g(p_hat)]= 0.3482 , Var[g(p_hat)]= 0.0065 
N= 100 , p= 0.50 , E[g(p_hat)]= 1.0188 , Var[g(p_hat)]= 0.0450 
N= 100 , p= 0.75 , E[g(p_hat)]= 3.1650 , Var[g(p_hat)]= 0.6130 
N= 100 , p= 0.90 , E[g(p_hat)]= 10.4642 , Var[g(p_hat)]= 30.6328 
N= 100 , p= 0.99 , E[g(p_hat)]= Inf , Var[g(p_hat)]= NaN 
N= 1000 , p= 0.01 , E[g(p_hat)]= 0.0104 , Var[g(p_hat)]= 0.0000 
N= 1000 , p= 0.10 , E[g(p_hat)]= 0.1106 , Var[g(p_hat)]= 0.0001 
N= 1000 , p= 0.25 , E[g(p_hat)]= 0.3278 , Var[g(p_hat)]= 0.0006 
N= 1000 , p= 0.50 , E[g(p_hat)]= 1.0038 , Var[g(p_hat)]= 0.0041 
N= 1000 , p= 0.75 , E[g(p_hat)]= 3.0351 , Var[g(p_hat)]= 0.0500 
N= 1000 , p= 0.90 , E[g(p_hat)]= 9.2124 , Var[g(p_hat)]= 0.9847 
N= 1000 , p= 0.99 , E[g(p_hat)]= 108.4729 , Var[g(p_hat)]= 2856.9333 

#2(b)

bootstrap_g_x <- function(data, B=1000) {
  N <- length(data)
  g_x_bs <- numeric(B)

  for (b in 1:B) {
    sample_b <- sample(data, size=N, replace=TRUE)
    p_hat_b <- mean(sample_b)
    g_x_bs[b] <- p_hat_b / (1 - p_hat_b)
  }

  g_bar <- mean(g_x_bs)
  var_g <- var(g_x_bs)  # Use default ddof=1 for sample variance
  return(list(g_bar=g_bar, var_g=var_g))
}

# Example usage for a single configuration
N <- 1000
p <- 0.5  # True p value
data <- rbinom(N, 1, p)
B <- 1000  # Number of bootstrap samples

result <- bootstrap_g_x(data, B)

cat("Bootstrap estimates for N=", N, ", p=", p, ":\n")
Bootstrap estimates for N= 1000 , p= 0.5 :
cat("Mean of g(X_bar): ", sprintf("%.4f", result$g_bar), "\n")
Mean of g(X_bar):  1.0027 
cat("Variance of g(X_bar): ", sprintf("%.4f", result$var_g), "\n")
Variance of g(X_bar):  0.0038 
# Load necessary library
library(ggplot2)

# Define the bootstrap_g_x function
bootstrap_g_x <- function(data, B=1000) {
  N <- length(data)
  g_x_bs <- numeric(B)

  for (b in 1:B) {
    sample_b <- sample(data, size=N, replace=TRUE)
    p_hat_b <- mean(sample_b)
    g_x_bs[b] <- p_hat_b / (1 - p_hat_b)
  }

  g_bar <- mean(g_x_bs)
  var_g <- var(g_x_bs)  # Use default ddof=1 for sample variance
  return(list(g_bar=g_bar, var_g=var_g, g_x_bs=g_x_bs))
}

# Example usage for a single configuration
N <- 100
p <- 0.5  # True p value
data <- rbinom(N, 1, p)
B <- 1000  # Number of bootstrap samples

result <- bootstrap_g_x(data, B)

# Plot histogram of bootstrap estimates
ggplot(data.frame(g_x_bs = result$g_x_bs), aes(x = g_x_bs)) +
  geom_histogram(binwidth = 0.1, fill = "skyblue", color = "black", alpha = 0.8) +
  labs(title = "Histogram of Bootstrap Estimates of g(X_bar)",
       x = "Bootstrap Estimates of g(X_bar)",
       y = "Frequency")

#2(b) this is the code for 28 combinations

bootstrap_g_x <- function(data, B=1000) {
  N <- length(data)
  g_x_bs <- numeric(B)

  for (b in 1:B) {
    sample_b <- sample(data, size=N, replace=TRUE)
    p_hat_b <- mean(sample_b)
    g_x_bs[b] <- p_hat_b / (1 - p_hat_b)
  }

  g_bar <- mean(g_x_bs)
  var_g <- var(g_x_bs)  # Use default ddof=1 for sample variance
  return(list(g_bar=g_bar, var_g=var_g))
}

# Loop over sample sizes and true parameters
sample_sizes <- c(10, 30, 100, 1000)
true_parameters <- c(0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99)
B <- 1000  # Number of bootstrap samples

for (N in sample_sizes) {
  for (p in true_parameters) {
    data <- rbinom(N, 1, p)  # Generate Bernoulli realizations
    result <- bootstrap_g_x(data, B)
    cat("Bootstrap estimates for N=", N, ", p=", p, ":\n")
    cat("Mean of g(X_bar): ", sprintf("%.4f", result$g_bar), "\n")
    cat("Variance of g(X_bar): ", sprintf("%.4f", result$var_g), "\n\n")
  }
}
Bootstrap estimates for N= 10 , p= 0.01 :
Mean of g(X_bar):  0.0000 
Variance of g(X_bar):  0.0000 

Bootstrap estimates for N= 10 , p= 0.1 :
Mean of g(X_bar):  0.1263 
Variance of g(X_bar):  0.0186 

Bootstrap estimates for N= 10 , p= 0.25 :
Mean of g(X_bar):  0.8087 
Variance of g(X_bar):  0.3900 

Bootstrap estimates for N= 10 , p= 0.5 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 10 , p= 0.75 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 10 , p= 0.9 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 10 , p= 0.99 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 30 , p= 0.01 :
Mean of g(X_bar):  0.0000 
Variance of g(X_bar):  0.0000 

Bootstrap estimates for N= 30 , p= 0.1 :
Mean of g(X_bar):  0.2106 
Variance of g(X_bar):  0.0118 

Bootstrap estimates for N= 30 , p= 0.25 :
Mean of g(X_bar):  0.4472 
Variance of g(X_bar):  0.0340 

Bootstrap estimates for N= 30 , p= 0.5 :
Mean of g(X_bar):  1.4269 
Variance of g(X_bar):  0.3467 

Bootstrap estimates for N= 30 , p= 0.75 :
Mean of g(X_bar):  2.2880 
Variance of g(X_bar):  1.2825 

Bootstrap estimates for N= 30 , p= 0.9 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 30 , p= 0.99 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 100 , p= 0.01 :
Mean of g(X_bar):  0.0209 
Variance of g(X_bar):  0.0002 

Bootstrap estimates for N= 100 , p= 0.1 :
Mean of g(X_bar):  0.0889 
Variance of g(X_bar):  0.0010 

Bootstrap estimates for N= 100 , p= 0.25 :
Mean of g(X_bar):  0.3003 
Variance of g(X_bar):  0.0055 

Bootstrap estimates for N= 100 , p= 0.5 :
Mean of g(X_bar):  0.9807 
Variance of g(X_bar):  0.0384 

Bootstrap estimates for N= 100 , p= 0.75 :
Mean of g(X_bar):  2.9499 
Variance of g(X_bar):  0.5129 

Bootstrap estimates for N= 100 , p= 0.9 :
Mean of g(X_bar):  11.3745 
Variance of g(X_bar):  22.1051 

Bootstrap estimates for N= 100 , p= 0.99 :
Mean of g(X_bar):  Inf 
Variance of g(X_bar):  NaN 

Bootstrap estimates for N= 1000 , p= 0.01 :
Mean of g(X_bar):  0.0091 
Variance of g(X_bar):  0.0000 

Bootstrap estimates for N= 1000 , p= 0.1 :
Mean of g(X_bar):  0.1339 
Variance of g(X_bar):  0.0002 

Bootstrap estimates for N= 1000 , p= 0.25 :
Mean of g(X_bar):  0.3626 
Variance of g(X_bar):  0.0007 

Bootstrap estimates for N= 1000 , p= 0.5 :
Mean of g(X_bar):  0.9633 
Variance of g(X_bar):  0.0037 

Bootstrap estimates for N= 1000 , p= 0.75 :
Mean of g(X_bar):  2.7163 
Variance of g(X_bar):  0.0373 

Bootstrap estimates for N= 1000 , p= 0.9 :
Mean of g(X_bar):  8.3943 
Variance of g(X_bar):  0.7508 

Bootstrap estimates for N= 1000 , p= 0.99 :
Mean of g(X_bar):  143.1331 
Variance of g(X_bar):  4437.9260 

#3(c)

# Define the sample size and observed data
N <- 1000
p <- 0.5  # True value of p
x <- rbinom(N, 1, p)  # Simulate Bernoulli trials

# Define the number of Monte Carlo samples
num_samples <- 100000

# Function to calculate z given p
calculate_z <- function(p) {
  p / (1 - p)
}

# Function to perform Monte Carlo simulation
monte_carlo_simulation <- function(x, num_samples) {
  # Initialize vector to store z samples
  z_samples <- numeric(num_samples)
  
  # Perform Monte Carlo simulation
  for (i in 1:num_samples) {
    # Sample from the posterior distribution of p
    p_posterior <- rbeta(1, sum(x) + 0.5, N - sum(x) + 0.5)
    # Calculate z from sampled p
    z_samples[i] <- calculate_z(p_posterior)
  }
  
  return(z_samples)
}

# Perform Monte Carlo simulation
z_samples <- monte_carlo_simulation(x, num_samples)

# Calculate the expected value and variance of z
expected_z <- mean(z_samples)
variance_z <- var(z_samples)

# Print the results
cat("Estimated expected value of z:", expected_z, "\n")
Estimated expected value of z: 0.9743661 
cat("Estimated variance of z:", variance_z, "\n")
Estimated variance of z: 0.00376868 
# Define the sample size and observed data
N <- 10
p <- 0.5  # True value of p
x <- rbinom(N, 1, p)  # Simulate Bernoulli trials

# Define the number of Monte Carlo samples
num_samples <- 10000

# Function to calculate z given p
calculate_z <- function(p) {
  p / (1 - p)
}

# Function to perform Monte Carlo simulation
monte_carlo_simulation <- function(x, num_samples) {
  # Initialize vector to store z samples
  z_samples <- numeric(num_samples)
  
  # Perform Monte Carlo simulation
  for (i in 1:num_samples) {
    # Sample from the posterior distribution of p
    p_posterior <- rbeta(1, sum(x) + 0.5, N - sum(x) + 0.5)
    # Calculate z from sampled p
    z_samples[i] <- calculate_z(p_posterior)
  }
  
  return(z_samples)
}

# Perform Monte Carlo simulation
z_samples <- monte_carlo_simulation(x, num_samples)

# Plot histogram of z samples
hist(z_samples, breaks = 30, col = "skyblue", main = "Histogram of z", xlab = "z", ylab = "Frequency")

# Add vertical lines for mean and standard deviation
abline(v = mean(z_samples), col = "red", lwd = 2)
abline(v = mean(z_samples) + sd(z_samples), col = "blue", lwd = 2, lty = 2)
abline(v = mean(z_samples) - sd(z_samples), col = "blue", lwd = 2, lty = 2)

# Add legend
legend("topright", legend = c("Mean", "Mean + SD", "Mean - SD"), col = c("red", "blue", "blue"), lty = 1:2, cex = 0.8)

# Define the sample sizes and true parameters
sample_sizes <- c(10, 30, 100, 1000)
true_ps <- c(0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99)

# Initialize an empty dataframe to store results
results_df <- data.frame(N = integer(), P = numeric(), Expectation = numeric(), Variance = numeric(), stringsAsFactors = FALSE)

# Function to perform Monte Carlo simulation
monte_carlo_simulation <- function(N, p, num_samples) {
  # Simulate Bernoulli trials
  x <- rbinom(N, 1, p)
  
  # Calculate z_samples
  z_samples <- numeric(num_samples)
  for (i in 1:num_samples) {
    # Sample from the posterior distribution of p
    p_posterior <- rbeta(1, sum(x) + 0.5, N - sum(x) + 0.5)
    # Calculate z from sampled p
    z_samples[i] <- p_posterior / (1 - p_posterior)
  }
  
  return(z_samples)
}

# Loop over each combination of sample size and true parameter
for (N in sample_sizes) {
  for (p in true_ps) {
    # Perform Monte Carlo simulation
    z_samples <- monte_carlo_simulation(N, p, num_samples = 100000)
    
    # Calculate the expected value and variance of z
    expected_z <- mean(z_samples)
    variance_z <- var(z_samples)
    
    # Store the results
    results_df <- rbind(results_df, data.frame(N = N, P = p, Expectation = expected_z, Variance = variance_z))
  }
}

# Print the results
print(results_df)
NA
write.csv(results, "delta_method_totalfile.csv", row.names = FALSE)
write.csv(result, "bootstrap_method_totalfile.csv", row.names = FALSE)
write.csv(results_df, "bayesian_method_totalfile.csv", row.names = FALSE)
LS0tDQp0aXRsZTogIlB5dGhvbl90b19SIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgUGFyYW1ldGVycw0KTiA8LSAxMDAwDQpwX3RydWUgPC0gMC41DQpzYW1wbGVzIDwtIDUwMDANCg0KIyBTaW11bGF0ZSBnKHBfaGF0KQ0KcF9oYXRzIDwtIGFwcGx5KG1hdHJpeChyYmlub20oTiAqIHNhbXBsZXMsIDEsIHBfdHJ1ZSksIG5yb3c9c2FtcGxlcyksIDEsIG1lYW4pDQpnX3BfaGF0cyA8LSBwX2hhdHMgLyAoMSAtIHBfaGF0cykNCmdfcF9oYXRzIDwtIHBtYXgocG1pbihnX3BfaGF0cywgcW5vcm0oMC45OTkpKSwgcW5vcm0oMC4wMDEpKQ0KDQojIFRoZW9yZXRpY2FsIHZhcmlhbmNlIG9mIGcocF9oYXQpIHVzaW5nIHRoZSBEZWx0YSBtZXRob2QNCnZhcl9nX3BfaGF0X3RoZW9yZXRpY2FsIDwtICgxIC8gKDEgLSBwX3RydWUpXjQpICogKHBfdHJ1ZSAqICgxIC0gcF90cnVlKSAvIE4pDQpzdGRfZ19wX2hhdF90aGVvcmV0aWNhbCA8LSBzcXJ0KHZhcl9nX3BfaGF0X3RoZW9yZXRpY2FsKQ0KDQojIENyZWF0ZSBkYXRhIGZyYW1lIGZvciBwbG90dGluZw0KZGF0YSA8LSBkYXRhLmZyYW1lKGdfcF9oYXRzKQ0KDQojIFBsb3R0aW5nDQpnZ3Bsb3QoZGF0YSwgYWVzKHg9Z19wX2hhdHMpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbnM9NTAsIGFlcyh5PS4uZGVuc2l0eS4uKSwgZmlsbD0ncHVycGxlJywgYWxwaGE9MC42KSArDQogIHN0YXRfZnVuY3Rpb24oZnVuPWZ1bmN0aW9uKHgpIGRub3JtKHgsIG1lYW4oZ19wX2hhdHMpLCBzdGRfZ19wX2hhdF90aGVvcmV0aWNhbCksIA0KICAgICAgICAgICAgICAgIGNvbG9yPSdyZWQnLCBzaXplPTEuNSkgKw0KICBsYWJzKHg9J2cocF9oYXQpJywgeT0nRGVuc2l0eScsIHRpdGxlPSdIaXN0b2dyYW0gb2YgZyhwX2hhdCkgd2l0aCBUaGVvcmV0aWNhbCBOb3JtYWwgT3ZlcmxheScpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCnNpbXVsYXRlX2FuZF9wbG90X2dfcF9oYXQgPC0gZnVuY3Rpb24oTiwgcF90cnVlPTAuNSwgc2FtcGxlcz01MDAwKSB7DQogICMgU2ltdWxhdGUgZyhwX2hhdCkNCiAgcF9oYXRzIDwtIGFwcGx5KG1hdHJpeChyYmlub20oTiAqIHNhbXBsZXMsIDEsIHBfdHJ1ZSksIG5yb3c9c2FtcGxlcyksIDEsIG1lYW4pDQogIGdfcF9oYXRzIDwtIHBfaGF0cyAvICgxIC0gcF9oYXRzKQ0KICBnX3BfaGF0cyA8LSBwbWF4KHBtaW4oZ19wX2hhdHMsIHFub3JtKDAuOTk5KSksIHFub3JtKDAuMDAxKSkNCg0KICAjIFRoZW9yZXRpY2FsIHZhcmlhbmNlIG9mIGcocF9oYXQpIHVzaW5nIHRoZSBEZWx0YSBtZXRob2QNCiAgdmFyX2dfcF9oYXRfdGhlb3JldGljYWwgPC0gKDEgLyAoMSAtIHBfdHJ1ZSleNCkgKiAocF90cnVlICogKDEgLSBwX3RydWUpIC8gTikNCiAgc3RkX2dfcF9oYXRfdGhlb3JldGljYWwgPC0gc3FydCh2YXJfZ19wX2hhdF90aGVvcmV0aWNhbCkNCg0KICAjIFBsb3R0aW5nDQogIGhpc3QoZ19wX2hhdHMsIGJyZWFrcz01MCwgZnJlcT1GQUxTRSwgY29sPSdsaWdodGJsdWUnLCB4bGFiPSdnKHBfaGF0KScsIHlsYWI9J0RlbnNpdHknLA0KICAgICAgIG1haW49cGFzdGUoJ0hpc3RvZ3JhbSBvZiBnKHBfaGF0KSBmb3IgTj0nLCBOLCAnIHdpdGggVGhlb3JldGljYWwgTm9ybWFsIE92ZXJsYXknKSkNCiAgDQogICMgT3ZlcmxheSB0aGUgbm9ybWFsIGN1cnZlDQogIHggPC0gc2VxKG1pbihnX3BfaGF0cyksIG1heChnX3BfaGF0cyksIGxlbmd0aC5vdXQ9MTAwMCkNCiAgbGluZXMoeCwgZG5vcm0oeCwgbWVhbihnX3BfaGF0cyksIHN0ZF9nX3BfaGF0X3RoZW9yZXRpY2FsKSwgY29sPSdyZWQnLCBsd2Q9MikNCiAgbGVnZW5kKCd0b3ByaWdodCcsIGxlZ2VuZD1jKCdFbXBpcmljYWwnLCAnVGhlb3JldGljYWwgTm9ybWFsJyksIGZpbGw9YygnbGlnaHRibHVlJywgJ3JlZCcpKQ0KfQ0KDQojIExpc3Qgb2YgZGlmZmVyZW50IHNhbXBsZSBzaXplcyB0byBzaW11bGF0ZQ0Kc2FtcGxlX3NpemVzIDwtIGMoMTAsIDMwLCA1MCwgMTAwLCA1MDApDQoNCmZvciAoTiBpbiBzYW1wbGVfc2l6ZXMpIHsNCiAgc2ltdWxhdGVfYW5kX3Bsb3RfZ19wX2hhdChOKQ0KfQ0KDQoNCmBgYA0KMihBKQ0KYGBge3J9DQojIERlZmluZSBmdW5jdGlvbiBmb3IgY2FsY3VsYXRpbmcgdmFyaWFuY2UgdXNpbmcgRGVsdGEgbWV0aG9kDQpkZWx0YV9tZXRob2RfdmFyIDwtIGZ1bmN0aW9uKHBfaGF0LCBOKSB7DQogIGdfcHJpbWVfcF9oYXQgPC0gMSAvICgxIC0gcF9oYXQpXjINCiAgdmFyX3BfaGF0IDwtIHBfaGF0ICogKDEgLSBwX2hhdCkgLyBODQogIHJldHVybigoZ19wcmltZV9wX2hhdCBeIDIpICogdmFyX3BfaGF0KQ0KfQ0KDQojIENvbmZpZ3VyYXRpb25zDQpOX3ZhbHVlcyA8LSBjKDEwLCAzMCwgMTAwLCAxMDAwKQ0KcF92YWx1ZXMgPC0gYygwLjAxLCAwLjEsIDAuMjUsIDAuNSwgMC43NSwgMC45LCAwLjk5KQ0KcmVwZWF0cyA8LSAxMDANCg0KIyBTdG9yZSByZXN1bHRzDQpyZXN1bHRzIDwtIG1hdHJpeChOQSwgbnJvdyA9IGxlbmd0aChOX3ZhbHVlcykgKiBsZW5ndGgocF92YWx1ZXMpLCBuY29sID0gNCkNCnJvd19pbmRleCA8LSAxDQoNCmZvciAoTiBpbiBOX3ZhbHVlcykgew0KICBmb3IgKHAgaW4gcF92YWx1ZXMpIHsNCiAgICBlX2dfcF9oYXRzIDwtIG51bWVyaWMocmVwZWF0cykNCiAgICB2YXJfZ19wX2hhdHMgPC0gbnVtZXJpYyhyZXBlYXRzKQ0KICAgIGZvciAoaSBpbiAxOnJlcGVhdHMpIHsNCiAgICAgICMgU2ltdWxhdGUgZGF0YQ0KICAgICAgZGF0YSA8LSByYmlub20oTiwgMSwgcCkNCiAgICAgIHBfaGF0IDwtIG1lYW4oZGF0YSkNCiAgICAgIGdfcF9oYXQgPC0gcF9oYXQgLyAoMSAtIHBfaGF0KQ0KICAgICAgDQogICAgICAjIENhbGN1bGF0ZSBlc3RpbWF0ZXMgdXNpbmcgRGVsdGEgbWV0aG9kDQogICAgICB2YXJfZ19wX2hhdCA8LSBkZWx0YV9tZXRob2RfdmFyKHBfaGF0LCBOKQ0KICAgICAgDQogICAgICBlX2dfcF9oYXRzW2ldIDwtIGdfcF9oYXQNCiAgICAgIHZhcl9nX3BfaGF0c1tpXSA8LSB2YXJfZ19wX2hhdA0KICAgIH0NCiAgICAjIEFnZ3JlZ2F0ZSByZXN1bHRzDQogICAgbWVhbl9lX2dfcF9oYXQgPC0gbWVhbihlX2dfcF9oYXRzKQ0KICAgIG1lYW5fdmFyX2dfcF9oYXQgPC0gbWVhbih2YXJfZ19wX2hhdHMpDQogICAgcmVzdWx0c1tyb3dfaW5kZXgsIF0gPC0gYyhOLCBwLCBtZWFuX2VfZ19wX2hhdCwgbWVhbl92YXJfZ19wX2hhdCkNCiAgICByb3dfaW5kZXggPC0gcm93X2luZGV4ICsgMQ0KICB9DQp9DQoNCiMgRGlzcGxheSByZXN1bHRzDQpmb3IgKGkgaW4gMTpucm93KHJlc3VsdHMpKSB7DQogIGNhdCgiTj0iLCByZXN1bHRzW2ksIDFdLCAiLCBwPSIsIHNwcmludGYoIiUuMmYiLCByZXN1bHRzW2ksIDJdKSwgIiwgRVtnKHBfaGF0KV09Iiwgc3ByaW50ZigiJS40ZiIsIHJlc3VsdHNbaSwgM10pLCAiLCBWYXJbZyhwX2hhdCldPSIsIHNwcmludGYoIiUuNGYiLCByZXN1bHRzW2ksIDRdKSwgIlxuIikNCn0NCg0KYGBgDQojMihiKQ0KYGBge3J9DQpib290c3RyYXBfZ194IDwtIGZ1bmN0aW9uKGRhdGEsIEI9MTAwMCkgew0KICBOIDwtIGxlbmd0aChkYXRhKQ0KICBnX3hfYnMgPC0gbnVtZXJpYyhCKQ0KDQogIGZvciAoYiBpbiAxOkIpIHsNCiAgICBzYW1wbGVfYiA8LSBzYW1wbGUoZGF0YSwgc2l6ZT1OLCByZXBsYWNlPVRSVUUpDQogICAgcF9oYXRfYiA8LSBtZWFuKHNhbXBsZV9iKQ0KICAgIGdfeF9ic1tiXSA8LSBwX2hhdF9iIC8gKDEgLSBwX2hhdF9iKQ0KICB9DQoNCiAgZ19iYXIgPC0gbWVhbihnX3hfYnMpDQogIHZhcl9nIDwtIHZhcihnX3hfYnMpICAjIFVzZSBkZWZhdWx0IGRkb2Y9MSBmb3Igc2FtcGxlIHZhcmlhbmNlDQogIHJldHVybihsaXN0KGdfYmFyPWdfYmFyLCB2YXJfZz12YXJfZykpDQp9DQoNCiMgRXhhbXBsZSB1c2FnZSBmb3IgYSBzaW5nbGUgY29uZmlndXJhdGlvbg0KTiA8LSAxMDAwDQpwIDwtIDAuNSAgIyBUcnVlIHAgdmFsdWUNCmRhdGEgPC0gcmJpbm9tKE4sIDEsIHApDQpCIDwtIDEwMDAgICMgTnVtYmVyIG9mIGJvb3RzdHJhcCBzYW1wbGVzDQoNCnJlc3VsdCA8LSBib290c3RyYXBfZ194KGRhdGEsIEIpDQoNCmNhdCgiQm9vdHN0cmFwIGVzdGltYXRlcyBmb3IgTj0iLCBOLCAiLCBwPSIsIHAsICI6XG4iKQ0KY2F0KCJNZWFuIG9mIGcoWF9iYXIpOiAiLCBzcHJpbnRmKCIlLjRmIiwgcmVzdWx0JGdfYmFyKSwgIlxuIikNCmNhdCgiVmFyaWFuY2Ugb2YgZyhYX2Jhcik6ICIsIHNwcmludGYoIiUuNGYiLCByZXN1bHQkdmFyX2cpLCAiXG4iKQ0KDQpgYGANCmBgYHtyfQ0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJ5DQpsaWJyYXJ5KGdncGxvdDIpDQoNCiMgRGVmaW5lIHRoZSBib290c3RyYXBfZ194IGZ1bmN0aW9uDQpib290c3RyYXBfZ194IDwtIGZ1bmN0aW9uKGRhdGEsIEI9MTAwMCkgew0KICBOIDwtIGxlbmd0aChkYXRhKQ0KICBnX3hfYnMgPC0gbnVtZXJpYyhCKQ0KDQogIGZvciAoYiBpbiAxOkIpIHsNCiAgICBzYW1wbGVfYiA8LSBzYW1wbGUoZGF0YSwgc2l6ZT1OLCByZXBsYWNlPVRSVUUpDQogICAgcF9oYXRfYiA8LSBtZWFuKHNhbXBsZV9iKQ0KICAgIGdfeF9ic1tiXSA8LSBwX2hhdF9iIC8gKDEgLSBwX2hhdF9iKQ0KICB9DQoNCiAgZ19iYXIgPC0gbWVhbihnX3hfYnMpDQogIHZhcl9nIDwtIHZhcihnX3hfYnMpICAjIFVzZSBkZWZhdWx0IGRkb2Y9MSBmb3Igc2FtcGxlIHZhcmlhbmNlDQogIHJldHVybihsaXN0KGdfYmFyPWdfYmFyLCB2YXJfZz12YXJfZywgZ194X2JzPWdfeF9icykpDQp9DQoNCiMgRXhhbXBsZSB1c2FnZSBmb3IgYSBzaW5nbGUgY29uZmlndXJhdGlvbg0KTiA8LSAxMDANCnAgPC0gMC41ICAjIFRydWUgcCB2YWx1ZQ0KZGF0YSA8LSByYmlub20oTiwgMSwgcCkNCkIgPC0gMTAwMCAgIyBOdW1iZXIgb2YgYm9vdHN0cmFwIHNhbXBsZXMNCg0KcmVzdWx0IDwtIGJvb3RzdHJhcF9nX3goZGF0YSwgQikNCg0KIyBQbG90IGhpc3RvZ3JhbSBvZiBib290c3RyYXAgZXN0aW1hdGVzDQpnZ3Bsb3QoZGF0YS5mcmFtZShnX3hfYnMgPSByZXN1bHQkZ194X2JzKSwgYWVzKHggPSBnX3hfYnMpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4xLCBmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC44KSArDQogIGxhYnModGl0bGUgPSAiSGlzdG9ncmFtIG9mIEJvb3RzdHJhcCBFc3RpbWF0ZXMgb2YgZyhYX2JhcikiLA0KICAgICAgIHggPSAiQm9vdHN0cmFwIEVzdGltYXRlcyBvZiBnKFhfYmFyKSIsDQogICAgICAgeSA9ICJGcmVxdWVuY3kiKQ0KDQpgYGANCiMyKGIpIHRoaXMgaXMgdGhlIGNvZGUgZm9yIDI4IGNvbWJpbmF0aW9ucw0KDQoNCmBgYHtyfQ0KYm9vdHN0cmFwX2dfeCA8LSBmdW5jdGlvbihkYXRhLCBCPTEwMDApIHsNCiAgTiA8LSBsZW5ndGgoZGF0YSkNCiAgZ194X2JzIDwtIG51bWVyaWMoQikNCg0KICBmb3IgKGIgaW4gMTpCKSB7DQogICAgc2FtcGxlX2IgPC0gc2FtcGxlKGRhdGEsIHNpemU9TiwgcmVwbGFjZT1UUlVFKQ0KICAgIHBfaGF0X2IgPC0gbWVhbihzYW1wbGVfYikNCiAgICBnX3hfYnNbYl0gPC0gcF9oYXRfYiAvICgxIC0gcF9oYXRfYikNCiAgfQ0KDQogIGdfYmFyIDwtIG1lYW4oZ194X2JzKQ0KICB2YXJfZyA8LSB2YXIoZ194X2JzKSAgIyBVc2UgZGVmYXVsdCBkZG9mPTEgZm9yIHNhbXBsZSB2YXJpYW5jZQ0KICByZXR1cm4obGlzdChnX2Jhcj1nX2JhciwgdmFyX2c9dmFyX2cpKQ0KfQ0KDQojIExvb3Agb3ZlciBzYW1wbGUgc2l6ZXMgYW5kIHRydWUgcGFyYW1ldGVycw0Kc2FtcGxlX3NpemVzIDwtIGMoMTAsIDMwLCAxMDAsIDEwMDApDQp0cnVlX3BhcmFtZXRlcnMgPC0gYygwLjAxLCAwLjEsIDAuMjUsIDAuNSwgMC43NSwgMC45LCAwLjk5KQ0KQiA8LSAxMDAwICAjIE51bWJlciBvZiBib290c3RyYXAgc2FtcGxlcw0KDQpmb3IgKE4gaW4gc2FtcGxlX3NpemVzKSB7DQogIGZvciAocCBpbiB0cnVlX3BhcmFtZXRlcnMpIHsNCiAgICBkYXRhIDwtIHJiaW5vbShOLCAxLCBwKSAgIyBHZW5lcmF0ZSBCZXJub3VsbGkgcmVhbGl6YXRpb25zDQogICAgcmVzdWx0IDwtIGJvb3RzdHJhcF9nX3goZGF0YSwgQikNCiAgICBjYXQoIkJvb3RzdHJhcCBlc3RpbWF0ZXMgZm9yIE49IiwgTiwgIiwgcD0iLCBwLCAiOlxuIikNCiAgICBjYXQoIk1lYW4gb2YgZyhYX2Jhcik6ICIsIHNwcmludGYoIiUuNGYiLCByZXN1bHQkZ19iYXIpLCAiXG4iKQ0KICAgIGNhdCgiVmFyaWFuY2Ugb2YgZyhYX2Jhcik6ICIsIHNwcmludGYoIiUuNGYiLCByZXN1bHQkdmFyX2cpLCAiXG5cbiIpDQogIH0NCn0NCg0KYGBgDQoNCg0KIzMoYykNCmBgYHtyfQ0KIyBEZWZpbmUgdGhlIHNhbXBsZSBzaXplIGFuZCBvYnNlcnZlZCBkYXRhDQpOIDwtIDEwMDANCnAgPC0gMC41ICAjIFRydWUgdmFsdWUgb2YgcA0KeCA8LSByYmlub20oTiwgMSwgcCkgICMgU2ltdWxhdGUgQmVybm91bGxpIHRyaWFscw0KDQojIERlZmluZSB0aGUgbnVtYmVyIG9mIE1vbnRlIENhcmxvIHNhbXBsZXMNCm51bV9zYW1wbGVzIDwtIDEwMDAwMA0KDQojIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB6IGdpdmVuIHANCmNhbGN1bGF0ZV96IDwtIGZ1bmN0aW9uKHApIHsNCiAgcCAvICgxIC0gcCkNCn0NCg0KIyBGdW5jdGlvbiB0byBwZXJmb3JtIE1vbnRlIENhcmxvIHNpbXVsYXRpb24NCm1vbnRlX2NhcmxvX3NpbXVsYXRpb24gPC0gZnVuY3Rpb24oeCwgbnVtX3NhbXBsZXMpIHsNCiAgIyBJbml0aWFsaXplIHZlY3RvciB0byBzdG9yZSB6IHNhbXBsZXMNCiAgel9zYW1wbGVzIDwtIG51bWVyaWMobnVtX3NhbXBsZXMpDQogIA0KICAjIFBlcmZvcm0gTW9udGUgQ2FybG8gc2ltdWxhdGlvbg0KICBmb3IgKGkgaW4gMTpudW1fc2FtcGxlcykgew0KICAgICMgU2FtcGxlIGZyb20gdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gb2YgcA0KICAgIHBfcG9zdGVyaW9yIDwtIHJiZXRhKDEsIHN1bSh4KSArIDAuNSwgTiAtIHN1bSh4KSArIDAuNSkNCiAgICAjIENhbGN1bGF0ZSB6IGZyb20gc2FtcGxlZCBwDQogICAgel9zYW1wbGVzW2ldIDwtIGNhbGN1bGF0ZV96KHBfcG9zdGVyaW9yKQ0KICB9DQogIA0KICByZXR1cm4oel9zYW1wbGVzKQ0KfQ0KDQojIFBlcmZvcm0gTW9udGUgQ2FybG8gc2ltdWxhdGlvbg0Kel9zYW1wbGVzIDwtIG1vbnRlX2NhcmxvX3NpbXVsYXRpb24oeCwgbnVtX3NhbXBsZXMpDQoNCiMgQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCB2YWx1ZSBhbmQgdmFyaWFuY2Ugb2Ygeg0KZXhwZWN0ZWRfeiA8LSBtZWFuKHpfc2FtcGxlcykNCnZhcmlhbmNlX3ogPC0gdmFyKHpfc2FtcGxlcykNCg0KIyBQcmludCB0aGUgcmVzdWx0cw0KY2F0KCJFc3RpbWF0ZWQgZXhwZWN0ZWQgdmFsdWUgb2YgejoiLCBleHBlY3RlZF96LCAiXG4iKQ0KY2F0KCJFc3RpbWF0ZWQgdmFyaWFuY2Ugb2YgejoiLCB2YXJpYW5jZV96LCAiXG4iKQ0KYGBgDQpgYGB7cn0NCiMgRGVmaW5lIHRoZSBzYW1wbGUgc2l6ZSBhbmQgb2JzZXJ2ZWQgZGF0YQ0KTiA8LSAxMA0KcCA8LSAwLjUgICMgVHJ1ZSB2YWx1ZSBvZiBwDQp4IDwtIHJiaW5vbShOLCAxLCBwKSAgIyBTaW11bGF0ZSBCZXJub3VsbGkgdHJpYWxzDQoNCiMgRGVmaW5lIHRoZSBudW1iZXIgb2YgTW9udGUgQ2FybG8gc2FtcGxlcw0KbnVtX3NhbXBsZXMgPC0gMTAwMDANCg0KIyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgeiBnaXZlbiBwDQpjYWxjdWxhdGVfeiA8LSBmdW5jdGlvbihwKSB7DQogIHAgLyAoMSAtIHApDQp9DQoNCiMgRnVuY3Rpb24gdG8gcGVyZm9ybSBNb250ZSBDYXJsbyBzaW11bGF0aW9uDQptb250ZV9jYXJsb19zaW11bGF0aW9uIDwtIGZ1bmN0aW9uKHgsIG51bV9zYW1wbGVzKSB7DQogICMgSW5pdGlhbGl6ZSB2ZWN0b3IgdG8gc3RvcmUgeiBzYW1wbGVzDQogIHpfc2FtcGxlcyA8LSBudW1lcmljKG51bV9zYW1wbGVzKQ0KICANCiAgIyBQZXJmb3JtIE1vbnRlIENhcmxvIHNpbXVsYXRpb24NCiAgZm9yIChpIGluIDE6bnVtX3NhbXBsZXMpIHsNCiAgICAjIFNhbXBsZSBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHANCiAgICBwX3Bvc3RlcmlvciA8LSByYmV0YSgxLCBzdW0oeCkgKyAwLjUsIE4gLSBzdW0oeCkgKyAwLjUpDQogICAgIyBDYWxjdWxhdGUgeiBmcm9tIHNhbXBsZWQgcA0KICAgIHpfc2FtcGxlc1tpXSA8LSBjYWxjdWxhdGVfeihwX3Bvc3RlcmlvcikNCiAgfQ0KICANCiAgcmV0dXJuKHpfc2FtcGxlcykNCn0NCg0KIyBQZXJmb3JtIE1vbnRlIENhcmxvIHNpbXVsYXRpb24NCnpfc2FtcGxlcyA8LSBtb250ZV9jYXJsb19zaW11bGF0aW9uKHgsIG51bV9zYW1wbGVzKQ0KDQojIFBsb3QgaGlzdG9ncmFtIG9mIHogc2FtcGxlcw0KaGlzdCh6X3NhbXBsZXMsIGJyZWFrcyA9IDMwLCBjb2wgPSAic2t5Ymx1ZSIsIG1haW4gPSAiSGlzdG9ncmFtIG9mIHoiLCB4bGFiID0gInoiLCB5bGFiID0gIkZyZXF1ZW5jeSIpDQoNCiMgQWRkIHZlcnRpY2FsIGxpbmVzIGZvciBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24NCmFibGluZSh2ID0gbWVhbih6X3NhbXBsZXMpLCBjb2wgPSAicmVkIiwgbHdkID0gMikNCmFibGluZSh2ID0gbWVhbih6X3NhbXBsZXMpICsgc2Qoel9zYW1wbGVzKSwgY29sID0gImJsdWUiLCBsd2QgPSAyLCBsdHkgPSAyKQ0KYWJsaW5lKHYgPSBtZWFuKHpfc2FtcGxlcykgLSBzZCh6X3NhbXBsZXMpLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIsIGx0eSA9IDIpDQoNCiMgQWRkIGxlZ2VuZA0KbGVnZW5kKCJ0b3ByaWdodCIsIGxlZ2VuZCA9IGMoIk1lYW4iLCAiTWVhbiArIFNEIiwgIk1lYW4gLSBTRCIpLCBjb2wgPSBjKCJyZWQiLCAiYmx1ZSIsICJibHVlIiksIGx0eSA9IDE6MiwgY2V4ID0gMC44KQ0KDQpgYGANCg0KYGBge3J9DQojIERlZmluZSB0aGUgc2FtcGxlIHNpemVzIGFuZCB0cnVlIHBhcmFtZXRlcnMNCnNhbXBsZV9zaXplcyA8LSBjKDEwLCAzMCwgMTAwLCAxMDAwKQ0KdHJ1ZV9wcyA8LSBjKDAuMDEsIDAuMSwgMC4yNSwgMC41LCAwLjc1LCAwLjksIDAuOTkpDQoNCiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSBkYXRhZnJhbWUgdG8gc3RvcmUgcmVzdWx0cw0KcmVzdWx0c19kZiA8LSBkYXRhLmZyYW1lKE4gPSBpbnRlZ2VyKCksIFAgPSBudW1lcmljKCksIEV4cGVjdGF0aW9uID0gbnVtZXJpYygpLCBWYXJpYW5jZSA9IG51bWVyaWMoKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KDQojIEZ1bmN0aW9uIHRvIHBlcmZvcm0gTW9udGUgQ2FybG8gc2ltdWxhdGlvbg0KbW9udGVfY2FybG9fc2ltdWxhdGlvbiA8LSBmdW5jdGlvbihOLCBwLCBudW1fc2FtcGxlcykgew0KICAjIFNpbXVsYXRlIEJlcm5vdWxsaSB0cmlhbHMNCiAgeCA8LSByYmlub20oTiwgMSwgcCkNCiAgDQogICMgQ2FsY3VsYXRlIHpfc2FtcGxlcw0KICB6X3NhbXBsZXMgPC0gbnVtZXJpYyhudW1fc2FtcGxlcykNCiAgZm9yIChpIGluIDE6bnVtX3NhbXBsZXMpIHsNCiAgICAjIFNhbXBsZSBmcm9tIHRoZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIG9mIHANCiAgICBwX3Bvc3RlcmlvciA8LSByYmV0YSgxLCBzdW0oeCkgKyAwLjUsIE4gLSBzdW0oeCkgKyAwLjUpDQogICAgIyBDYWxjdWxhdGUgeiBmcm9tIHNhbXBsZWQgcA0KICAgIHpfc2FtcGxlc1tpXSA8LSBwX3Bvc3RlcmlvciAvICgxIC0gcF9wb3N0ZXJpb3IpDQogIH0NCiAgDQogIHJldHVybih6X3NhbXBsZXMpDQp9DQoNCiMgTG9vcCBvdmVyIGVhY2ggY29tYmluYXRpb24gb2Ygc2FtcGxlIHNpemUgYW5kIHRydWUgcGFyYW1ldGVyDQpmb3IgKE4gaW4gc2FtcGxlX3NpemVzKSB7DQogIGZvciAocCBpbiB0cnVlX3BzKSB7DQogICAgIyBQZXJmb3JtIE1vbnRlIENhcmxvIHNpbXVsYXRpb24NCiAgICB6X3NhbXBsZXMgPC0gbW9udGVfY2FybG9fc2ltdWxhdGlvbihOLCBwLCBudW1fc2FtcGxlcyA9IDEwMDAwMCkNCiAgICANCiAgICAjIENhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgdmFsdWUgYW5kIHZhcmlhbmNlIG9mIHoNCiAgICBleHBlY3RlZF96IDwtIG1lYW4oel9zYW1wbGVzKQ0KICAgIHZhcmlhbmNlX3ogPC0gdmFyKHpfc2FtcGxlcykNCiAgICANCiAgICAjIFN0b3JlIHRoZSByZXN1bHRzDQogICAgcmVzdWx0c19kZiA8LSByYmluZChyZXN1bHRzX2RmLCBkYXRhLmZyYW1lKE4gPSBOLCBQID0gcCwgRXhwZWN0YXRpb24gPSBleHBlY3RlZF96LCBWYXJpYW5jZSA9IHZhcmlhbmNlX3opKQ0KICB9DQp9DQoNCiMgUHJpbnQgdGhlIHJlc3VsdHMNCnByaW50KHJlc3VsdHNfZGYpDQoNCmBgYA0KDQpgYGB7cn0NCndyaXRlLmNzdihyZXN1bHRzLCAiZGVsdGFfbWV0aG9kX3RvdGFsZmlsZS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCndyaXRlLmNzdihyZXN1bHQsICJib290c3RyYXBfbWV0aG9kX3RvdGFsZmlsZS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCndyaXRlLmNzdihyZXN1bHRzX2RmLCAiYmF5ZXNpYW5fbWV0aG9kX3RvdGFsZmlsZS5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCmBgYA0KDQo=