#A1

# Set parameters
N <- 1000
p <- 0.5
iterations <- 5000

# Initialize vector to store results
odds_ratios <- numeric(iterations)

# Simulate data and calculate odds ratios
for (i in 1:iterations) {
  # Generate sample of Bernoulli random variables
  sample_data <- rbinom(N, 1, p)
  
  # Calculate sample average
  sample_average <- mean(sample_data)
  
  # Calculate odds ratio
  odds_ratio <- sample_average / (1 - sample_average)
  
  # Store result
  odds_ratios[i] <- odds_ratio
}

# Plot histogram of simulated odds ratios
hist(odds_ratios, freq = FALSE, breaks = 30, main = "Histogram of Simulated Odds Ratios",
     xlab = "Odds Ratio", ylab = "Density")

# Calculate mean and variance of odds ratios
mean_odds_ratio <- mean(odds_ratios)
var_odds_ratio <- var(odds_ratios)

# Calculate standard error using Delta method
se_delta_method <- sqrt((1/(1-p)^3)*(p/N))

# Plot normal distribution with mean and standard error
curve(dnorm(x, mean = mean_odds_ratio, sd = se_delta_method), 
      col = "blue", lwd = 2, add = TRUE)

#A2

# Set parameters
N_values <- c(10, 30, 50, 100, 500)
p <- 0.5
iterations <- 5000

# Function to calculate standard error using Delta method
calculate_se_delta_method <- function(p, N) {
  return(sqrt((1/(1-p)^3)*(p/N)))
}

# Function to simulate data and plot histogram for given N
simulate_and_plot <- function(N) {
  # Initialize vector to store results
  odds_ratios <- numeric(iterations)
  
  # Simulate data and calculate odds ratios
  for (i in 1:iterations) {
    # Generate sample of Bernoulli random variables
    sample_data <- rbinom(N, 1, p)
    
    # Calculate sample average
    sample_average <- mean(sample_data)
    
    # Calculate odds ratio
    odds_ratio <- sample_average / (1 - sample_average)
    
    # Store result
    odds_ratios[i] <- odds_ratio
  }
  
  # Plot histogram of simulated odds ratios
  hist(odds_ratios, freq = FALSE, breaks = 30, 
       main = paste("Histogram of Simulated Odds Ratios (N =", N, ")"),
       xlab = "Odds Ratio", ylab = "Density")
  
  # Calculate mean and variance of odds ratios
  mean_odds_ratio <- mean(odds_ratios)
  var_odds_ratio <- var(odds_ratios)
  
  # Calculate standard error using Delta method
  se_delta_method <- calculate_se_delta_method(p, N)
  
  # Plot normal distribution with mean and standard error
  curve(dnorm(x, mean = mean_odds_ratio, sd = se_delta_method), 
        col = "blue", lwd = 2, add = TRUE)
  
  # Add legend
  legend("topright", legend = "Normal Curve", col = "blue", lwd = 2)
}

# Loop over different values of N
for (N in N_values) {
  simulate_and_plot(N)
}

#2(A)

# 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 for results
results_df <- data.frame(N = integer(),
                         P = numeric(),
                         N_P_set = character(),
                         Expectation = numeric(),
                         Variance = numeric(),
                         stringsAsFactors = FALSE) 

# Function to calculate delta method estimates
calculate_delta <- function(N, p_hat) {
  g_p_hat <- p_hat / (1 - p_hat) # Expected value approximation
  var_g_p_hat <- (1 / ((1 - p_hat)^2))^2 * (p_hat * (1 - p_hat) / N) # Variance approximation
  return(c(g_p_hat, var_g_p_hat))
}

# Loop over each N and p, simulate Bernoulli trials, and apply the delta method
for (N in sample_sizes) {
  for (p in true_ps) {
    for (i in 1:100) { # Repeat each configuration 100 times
      samples <- rbinom(N, 1, p) # Simulate N Bernoulli trials
      p_hat <- mean(samples) # Sample mean as estimator for p
      estimates <- calculate_delta(N, p_hat)
      # Create the combined N_P_set identifier
      N_P_set_value <- sprintf("N.%dp.%s.%d", N, gsub("0\\.", "", format(p, nsmall = 2)), i)
      # Append to results dataframe
      results_df <- rbind(results_df, data.frame(N = N,
                                                  P = p,
                                                  N_P_set = N_P_set_value,
                                                  Expectation = estimates[1],
                                                  Variance = estimates[2]))
    }
  }
}

# Save results to CSV file with specified headers
write.csv(results_df, "delta_method_results.csv", row.names = FALSE)

# Print confirmation message
print("Delta method results saved in the working directory")

#2(B)

# 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)
B <- 100 # Number of bootstrap realizations

# Initialize an empty dataframe for results
bootstrap_results_df <- data.frame(N = integer(),
                                   P = numeric(),
                                   N_P_set = character(),
                                   Bootstrap_Mean = numeric(),
                                   Bootstrap_Variance = numeric(),
                                   stringsAsFactors = FALSE)

# Function to calculate g(𝑋̄) for a given sample
calculate_g_x_bar <- function(samples) {
  p_hat <- mean(samples) # Sample mean as estimator for p
  g_p_hat <- p_hat / (1 - p_hat) # Expected value approximation
  return(g_p_hat)
}

# Function to perform bootstrap resampling
perform_bootstrap <- function(samples, B) {
  bootstrap_estimates <- replicate(B, {
    bootstrap_sample <- sample(samples, replace = TRUE) # Bootstrap resampling
    calculate_g_x_bar(bootstrap_sample) # Calculate g(𝑋̄) for bootstrap sample
  })
  return(bootstrap_estimates)
}

# Loop over each N and p, simulate Bernoulli trials, and apply bootstrap
for (N in sample_sizes) {
  for (p in true_ps) {
    for (i in 1:100) { # Repeat each configuration 100 times
      samples <- rbinom(N, 1, p) # Simulate N Bernoulli trials
      
      bootstrap_estimates <- perform_bootstrap(samples, B)
      
      bootstrap_mean <- mean(bootstrap_estimates) # Bootstrap mean
      bootstrap_variance <- var(bootstrap_estimates) * B / (B - 1) # Bootstrap variance
      
      # Create the combined N_P_set identifier
      N_P_set_value <- sprintf("N.%dp.%s.%d", N, gsub("0\\.", "", format(p, nsmall = 2)), i)
      
      # Append to results dataframe
      bootstrap_results_df <- rbind(bootstrap_results_df, data.frame(N = N,
                                                                     P = p,
                                                                     N_P_set = N_P_set_value,
                                                                     Bootstrap_Mean = bootstrap_mean,
                                                                     Bootstrap_Variance = bootstrap_variance))
    }
  }
}

# Save results to CSV file with specified headers
write.csv(bootstrap_results_df, "bootstrap_results.csv", row.names = FALSE)

#2(B)

# Define function to calculate g(X-bar)
calculate_g <- function(sample_average) {
  return(sample_average / (1 - sample_average))
}

# Define function to perform bootstrap
perform_bootstrap <- function(sample_data, B) {
  g_values <- numeric(B)
  for (b in 1:B) {
    bootstrap_sample <- sample(sample_data, replace = TRUE)
    sample_average <- mean(bootstrap_sample)
    g_values[b] <- calculate_g(sample_average)
  }
  return(g_values)
}

# Set parameters
B <- 100  # Number of bootstrap realizations
iterations <- 100  # Number of iterations
N <- 100  # Sample size
p <- 0.5  # True parameter value

# Initialize matrices to store results
expected_values <- matrix(NA, nrow = iterations, ncol = 1)
variances <- matrix(NA, nrow = iterations, ncol = 1)

# Perform iterations
for (iter in 1:iterations) {
  # Generate sample of Bernoulli random variables
  sample_data <- rbinom(N, 1, p)
  
  # Calculate sample average
  sample_average <- mean(sample_data)
  
  # Calculate g(X-bar)
  g <- calculate_g(sample_average)
  
  # Perform bootstrap
  bootstrap_g <- perform_bootstrap(sample_data, B)
  
  # Estimate expected value and variance of g(X-bar)
  expected_values[iter, 1] <- mean(bootstrap_g)
  variances[iter, 1] <- var(bootstrap_g) * B / (B - 1)
}

# Calculate mean and standard error of expected value and variance
mean_expected_value <- mean(expected_values)
mean_variance <- mean(variances)
standard_error_expected_value <- sd(expected_values) / sqrt(iterations)
standard_error_variance <- sd(variances) / sqrt(iterations)

# Print results
cat("Estimated Expected Value of g(X-bar):", mean_expected_value, "\n")
cat("Estimated Variance of g(X-bar):", mean_variance, "\n")
cat("Standard Error of Expected Value:", standard_error_expected_value, "\n")
cat("Standard Error of Variance:", standard_error_variance, "\n")

#3(D)

# Load required library
library(MASS)

# Function to calculate likelihood function for p
likelihood <- function(p, x) {
  prod(p^x / (1-p)^(1-x))
}

# Function to calculate posterior distribution for p
posterior_p <- function(prior_alpha, prior_beta, x) {
  sum_x <- sum(x)
  n <- length(x)
  posterior_alpha <- prior_alpha + sum_x
  posterior_beta <- prior_beta - n + sum_x
  return(list(alpha = posterior_alpha, beta = posterior_beta))
}

# Function to transform posterior distribution for p to obtain posterior distribution for z
posterior_z <- function(posterior_alpha, posterior_beta) {
  z_mean <- posterior_alpha / (posterior_alpha + posterior_beta)
  z_var <- (posterior_alpha * posterior_beta) / ((posterior_alpha + posterior_beta)^2 * (posterior_alpha + posterior_beta + 1))
  return(list(mean = z_mean, variance = z_var))
}

# Parameters
prior_alpha <- 0.5
prior_beta <- 0.5
N_values <- c(10, 30, 100, 1000)  # Different values of N
true_params <- c(0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99)  # True parameters for simulation
num_simulations <- 100  # Number of simulations per configuration

# Storage for results
results_list <- list()

# Perform simulations for each combination of N and true parameters
for (N in N_values) {
  for (p in true_params) {
    results <- matrix(NA, nrow = num_simulations, ncol = 2)
    
    for (i in 1:num_simulations) {
      # Generate N Bernoulli samples with parameter p
      x <- rbinom(N, 1, p)
      
      # Calculate posterior distribution for p
      posterior_params <- posterior_p(prior_alpha, prior_beta, x)
      
      # Calculate posterior distribution for z
      z_posterior <- posterior_z(posterior_params$alpha, posterior_params$beta)
      
      # Store mean and variance of z samples
      results[i, ] <- c(z_posterior$mean, z_posterior$variance)
    }
    
    # Store results for this configuration
    config_name <- paste("N", N, "p", gsub("\\.", "", as.character(p)), sep = "_")
    results_list[[config_name]] <- results
  }
}

# Print results for each configuration
#for (config_name in names(results_list)) {
  #cat("Results for configuration:", config_name, "\n")
 # print(results_list[[config_name]])
 # cat("\n")
# Flatten the results list into a data frame
results_df <- do.call(rbind, lapply(names(results_list), function(config_name) {
  config_results <- results_list[[config_name]]
  config_results <- cbind(config_name = rep(config_name, nrow(config_results)), config_results)
  return(as.data.frame(config_results))
}))

# Write the results to a CSV file
write.csv(results_df, "simulation_results.csv", row.names = FALSE)


# Flatten the results list into a data frame
results_df <- do.call(rbind, lapply(names(results_list), function(config_name) {
  config_results <- results_list[[config_name]]
  config_results <- cbind(config_name = rep(config_name, nrow(config_results)), config_results)
  return(as.data.frame(config_results))
}))

# Write the results to a CSV file
write.csv(results_df, "simulation_results_Posterior.csv", row.names = FALSE)
LS0tDQp0aXRsZTogIlN0YXRpc3RpY3MgNTExNDogT2RkcyBSYXRpb3M6IERlbHRhIE1ldGhvZCxCb290c3RyYXAgYW5kIEJheWVzIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQojQTENCmBgYHtyfQ0KIyBTZXQgcGFyYW1ldGVycw0KTiA8LSAxMDAwDQpwIDwtIDAuNQ0KaXRlcmF0aW9ucyA8LSA1MDAwDQoNCiMgSW5pdGlhbGl6ZSB2ZWN0b3IgdG8gc3RvcmUgcmVzdWx0cw0Kb2Rkc19yYXRpb3MgPC0gbnVtZXJpYyhpdGVyYXRpb25zKQ0KDQojIFNpbXVsYXRlIGRhdGEgYW5kIGNhbGN1bGF0ZSBvZGRzIHJhdGlvcw0KZm9yIChpIGluIDE6aXRlcmF0aW9ucykgew0KICAjIEdlbmVyYXRlIHNhbXBsZSBvZiBCZXJub3VsbGkgcmFuZG9tIHZhcmlhYmxlcw0KICBzYW1wbGVfZGF0YSA8LSByYmlub20oTiwgMSwgcCkNCiAgDQogICMgQ2FsY3VsYXRlIHNhbXBsZSBhdmVyYWdlDQogIHNhbXBsZV9hdmVyYWdlIDwtIG1lYW4oc2FtcGxlX2RhdGEpDQogIA0KICAjIENhbGN1bGF0ZSBvZGRzIHJhdGlvDQogIG9kZHNfcmF0aW8gPC0gc2FtcGxlX2F2ZXJhZ2UgLyAoMSAtIHNhbXBsZV9hdmVyYWdlKQ0KICANCiAgIyBTdG9yZSByZXN1bHQNCiAgb2Rkc19yYXRpb3NbaV0gPC0gb2Rkc19yYXRpbw0KfQ0KDQojIFBsb3QgaGlzdG9ncmFtIG9mIHNpbXVsYXRlZCBvZGRzIHJhdGlvcw0KaGlzdChvZGRzX3JhdGlvcywgZnJlcSA9IEZBTFNFLCBicmVha3MgPSAzMCwgbWFpbiA9ICJIaXN0b2dyYW0gb2YgU2ltdWxhdGVkIE9kZHMgUmF0aW9zIiwNCiAgICAgeGxhYiA9ICJPZGRzIFJhdGlvIiwgeWxhYiA9ICJEZW5zaXR5IikNCg0KIyBDYWxjdWxhdGUgbWVhbiBhbmQgdmFyaWFuY2Ugb2Ygb2RkcyByYXRpb3MNCm1lYW5fb2Rkc19yYXRpbyA8LSBtZWFuKG9kZHNfcmF0aW9zKQ0KdmFyX29kZHNfcmF0aW8gPC0gdmFyKG9kZHNfcmF0aW9zKQ0KDQojIENhbGN1bGF0ZSBzdGFuZGFyZCBlcnJvciB1c2luZyBEZWx0YSBtZXRob2QNCnNlX2RlbHRhX21ldGhvZCA8LSBzcXJ0KCgxLygxLXApXjMpKihwL04pKQ0KDQojIFBsb3Qgbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aXRoIG1lYW4gYW5kIHN0YW5kYXJkIGVycm9yDQpjdXJ2ZShkbm9ybSh4LCBtZWFuID0gbWVhbl9vZGRzX3JhdGlvLCBzZCA9IHNlX2RlbHRhX21ldGhvZCksIA0KICAgICAgY29sID0gImJsdWUiLCBsd2QgPSAyLCBhZGQgPSBUUlVFKQ0KDQpgYGANCiNBMg0KDQpgYGB7cn0NCiMgU2V0IHBhcmFtZXRlcnMNCk5fdmFsdWVzIDwtIGMoMTAsIDMwLCA1MCwgMTAwLCA1MDApDQpwIDwtIDAuNQ0KaXRlcmF0aW9ucyA8LSA1MDAwDQoNCiMgRnVuY3Rpb24gdG8gY2FsY3VsYXRlIHN0YW5kYXJkIGVycm9yIHVzaW5nIERlbHRhIG1ldGhvZA0KY2FsY3VsYXRlX3NlX2RlbHRhX21ldGhvZCA8LSBmdW5jdGlvbihwLCBOKSB7DQogIHJldHVybihzcXJ0KCgxLygxLXApXjMpKihwL04pKSkNCn0NCg0KIyBGdW5jdGlvbiB0byBzaW11bGF0ZSBkYXRhIGFuZCBwbG90IGhpc3RvZ3JhbSBmb3IgZ2l2ZW4gTg0Kc2ltdWxhdGVfYW5kX3Bsb3QgPC0gZnVuY3Rpb24oTikgew0KICAjIEluaXRpYWxpemUgdmVjdG9yIHRvIHN0b3JlIHJlc3VsdHMNCiAgb2Rkc19yYXRpb3MgPC0gbnVtZXJpYyhpdGVyYXRpb25zKQ0KICANCiAgIyBTaW11bGF0ZSBkYXRhIGFuZCBjYWxjdWxhdGUgb2RkcyByYXRpb3MNCiAgZm9yIChpIGluIDE6aXRlcmF0aW9ucykgew0KICAgICMgR2VuZXJhdGUgc2FtcGxlIG9mIEJlcm5vdWxsaSByYW5kb20gdmFyaWFibGVzDQogICAgc2FtcGxlX2RhdGEgPC0gcmJpbm9tKE4sIDEsIHApDQogICAgDQogICAgIyBDYWxjdWxhdGUgc2FtcGxlIGF2ZXJhZ2UNCiAgICBzYW1wbGVfYXZlcmFnZSA8LSBtZWFuKHNhbXBsZV9kYXRhKQ0KICAgIA0KICAgICMgQ2FsY3VsYXRlIG9kZHMgcmF0aW8NCiAgICBvZGRzX3JhdGlvIDwtIHNhbXBsZV9hdmVyYWdlIC8gKDEgLSBzYW1wbGVfYXZlcmFnZSkNCiAgICANCiAgICAjIFN0b3JlIHJlc3VsdA0KICAgIG9kZHNfcmF0aW9zW2ldIDwtIG9kZHNfcmF0aW8NCiAgfQ0KICANCiAgIyBQbG90IGhpc3RvZ3JhbSBvZiBzaW11bGF0ZWQgb2RkcyByYXRpb3MNCiAgaGlzdChvZGRzX3JhdGlvcywgZnJlcSA9IEZBTFNFLCBicmVha3MgPSAzMCwgDQogICAgICAgbWFpbiA9IHBhc3RlKCJIaXN0b2dyYW0gb2YgU2ltdWxhdGVkIE9kZHMgUmF0aW9zIChOID0iLCBOLCAiKSIpLA0KICAgICAgIHhsYWIgPSAiT2RkcyBSYXRpbyIsIHlsYWIgPSAiRGVuc2l0eSIpDQogIA0KICAjIENhbGN1bGF0ZSBtZWFuIGFuZCB2YXJpYW5jZSBvZiBvZGRzIHJhdGlvcw0KICBtZWFuX29kZHNfcmF0aW8gPC0gbWVhbihvZGRzX3JhdGlvcykNCiAgdmFyX29kZHNfcmF0aW8gPC0gdmFyKG9kZHNfcmF0aW9zKQ0KICANCiAgIyBDYWxjdWxhdGUgc3RhbmRhcmQgZXJyb3IgdXNpbmcgRGVsdGEgbWV0aG9kDQogIHNlX2RlbHRhX21ldGhvZCA8LSBjYWxjdWxhdGVfc2VfZGVsdGFfbWV0aG9kKHAsIE4pDQogIA0KICAjIFBsb3Qgbm9ybWFsIGRpc3RyaWJ1dGlvbiB3aXRoIG1lYW4gYW5kIHN0YW5kYXJkIGVycm9yDQogIGN1cnZlKGRub3JtKHgsIG1lYW4gPSBtZWFuX29kZHNfcmF0aW8sIHNkID0gc2VfZGVsdGFfbWV0aG9kKSwgDQogICAgICAgIGNvbCA9ICJibHVlIiwgbHdkID0gMiwgYWRkID0gVFJVRSkNCiAgDQogICMgQWRkIGxlZ2VuZA0KICBsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gIk5vcm1hbCBDdXJ2ZSIsIGNvbCA9ICJibHVlIiwgbHdkID0gMikNCn0NCg0KIyBMb29wIG92ZXIgZGlmZmVyZW50IHZhbHVlcyBvZiBODQpmb3IgKE4gaW4gTl92YWx1ZXMpIHsNCiAgc2ltdWxhdGVfYW5kX3Bsb3QoTikNCn0NCmBgYA0KDQoNCiMyKEEpDQoNCg0KYGBge3J9DQojIERlZmluZSB0aGUgc2FtcGxlIHNpemVzIGFuZCB0cnVlIHBhcmFtZXRlcnMNCnNhbXBsZV9zaXplcyA8LSBjKDEwLCAzMCwgMTAwLCAxMDAwKQ0KdHJ1ZV9wcyA8LSBjKDAuMDEsIDAuMSwgMC4yNSwgMC41LCAwLjc1LCAwLjksIDAuOTkpDQojIEluaXRpYWxpemUgYW4gZW1wdHkgZGF0YWZyYW1lIGZvciByZXN1bHRzDQpyZXN1bHRzX2RmIDwtIGRhdGEuZnJhbWUoTiA9IGludGVnZXIoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBQID0gbnVtZXJpYygpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIE5fUF9zZXQgPSBjaGFyYWN0ZXIoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBFeHBlY3RhdGlvbiA9IG51bWVyaWMoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBWYXJpYW5jZSA9IG51bWVyaWMoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpIA0KDQojIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBkZWx0YSBtZXRob2QgZXN0aW1hdGVzDQpjYWxjdWxhdGVfZGVsdGEgPC0gZnVuY3Rpb24oTiwgcF9oYXQpIHsNCiAgZ19wX2hhdCA8LSBwX2hhdCAvICgxIC0gcF9oYXQpICMgRXhwZWN0ZWQgdmFsdWUgYXBwcm94aW1hdGlvbg0KICB2YXJfZ19wX2hhdCA8LSAoMSAvICgoMSAtIHBfaGF0KV4yKSleMiAqIChwX2hhdCAqICgxIC0gcF9oYXQpIC8gTikgIyBWYXJpYW5jZSBhcHByb3hpbWF0aW9uDQogIHJldHVybihjKGdfcF9oYXQsIHZhcl9nX3BfaGF0KSkNCn0NCg0KIyBMb29wIG92ZXIgZWFjaCBOIGFuZCBwLCBzaW11bGF0ZSBCZXJub3VsbGkgdHJpYWxzLCBhbmQgYXBwbHkgdGhlIGRlbHRhIG1ldGhvZA0KZm9yIChOIGluIHNhbXBsZV9zaXplcykgew0KICBmb3IgKHAgaW4gdHJ1ZV9wcykgew0KICAgIGZvciAoaSBpbiAxOjEwMCkgeyAjIFJlcGVhdCBlYWNoIGNvbmZpZ3VyYXRpb24gMTAwIHRpbWVzDQogICAgICBzYW1wbGVzIDwtIHJiaW5vbShOLCAxLCBwKSAjIFNpbXVsYXRlIE4gQmVybm91bGxpIHRyaWFscw0KICAgICAgcF9oYXQgPC0gbWVhbihzYW1wbGVzKSAjIFNhbXBsZSBtZWFuIGFzIGVzdGltYXRvciBmb3IgcA0KICAgICAgZXN0aW1hdGVzIDwtIGNhbGN1bGF0ZV9kZWx0YShOLCBwX2hhdCkNCiAgICAgICMgQ3JlYXRlIHRoZSBjb21iaW5lZCBOX1Bfc2V0IGlkZW50aWZpZXINCiAgICAgIE5fUF9zZXRfdmFsdWUgPC0gc3ByaW50ZigiTi4lZHAuJXMuJWQiLCBOLCBnc3ViKCIwXFwuIiwgIiIsIGZvcm1hdChwLCBuc21hbGwgPSAyKSksIGkpDQogICAgICAjIEFwcGVuZCB0byByZXN1bHRzIGRhdGFmcmFtZQ0KICAgICAgcmVzdWx0c19kZiA8LSByYmluZChyZXN1bHRzX2RmLCBkYXRhLmZyYW1lKE4gPSBOLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQID0gcCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTl9QX3NldCA9IE5fUF9zZXRfdmFsdWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4cGVjdGF0aW9uID0gZXN0aW1hdGVzWzFdLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJpYW5jZSA9IGVzdGltYXRlc1syXSkpDQogICAgfQ0KICB9DQp9DQoNCiMgU2F2ZSByZXN1bHRzIHRvIENTViBmaWxlIHdpdGggc3BlY2lmaWVkIGhlYWRlcnMNCndyaXRlLmNzdihyZXN1bHRzX2RmLCAiZGVsdGFfbWV0aG9kX3Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCiMgUHJpbnQgY29uZmlybWF0aW9uIG1lc3NhZ2UNCnByaW50KCJEZWx0YSBtZXRob2QgcmVzdWx0cyBzYXZlZCBpbiB0aGUgd29ya2luZyBkaXJlY3RvcnkiKQ0KYGBgDQoNCg0KDQoNCiMyKEIpDQpgYGB7cn0NCiMgRGVmaW5lIHRoZSBzYW1wbGUgc2l6ZXMgYW5kIHRydWUgcGFyYW1ldGVycw0Kc2FtcGxlX3NpemVzIDwtIGMoMTAsIDMwLCAxMDAsIDEwMDApDQp0cnVlX3BzIDwtIGMoMC4wMSwgMC4xLCAwLjI1LCAwLjUsIDAuNzUsIDAuOSwgMC45OSkNCkIgPC0gMTAwICMgTnVtYmVyIG9mIGJvb3RzdHJhcCByZWFsaXphdGlvbnMNCg0KIyBJbml0aWFsaXplIGFuIGVtcHR5IGRhdGFmcmFtZSBmb3IgcmVzdWx0cw0KYm9vdHN0cmFwX3Jlc3VsdHNfZGYgPC0gZGF0YS5mcmFtZShOID0gaW50ZWdlcigpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQID0gbnVtZXJpYygpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOX1Bfc2V0ID0gY2hhcmFjdGVyKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJvb3RzdHJhcF9NZWFuID0gbnVtZXJpYygpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb290c3RyYXBfVmFyaWFuY2UgPSBudW1lcmljKCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCg0KIyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgZyjwnZGLzIQpIGZvciBhIGdpdmVuIHNhbXBsZQ0KY2FsY3VsYXRlX2dfeF9iYXIgPC0gZnVuY3Rpb24oc2FtcGxlcykgew0KICBwX2hhdCA8LSBtZWFuKHNhbXBsZXMpICMgU2FtcGxlIG1lYW4gYXMgZXN0aW1hdG9yIGZvciBwDQogIGdfcF9oYXQgPC0gcF9oYXQgLyAoMSAtIHBfaGF0KSAjIEV4cGVjdGVkIHZhbHVlIGFwcHJveGltYXRpb24NCiAgcmV0dXJuKGdfcF9oYXQpDQp9DQoNCiMgRnVuY3Rpb24gdG8gcGVyZm9ybSBib290c3RyYXAgcmVzYW1wbGluZw0KcGVyZm9ybV9ib290c3RyYXAgPC0gZnVuY3Rpb24oc2FtcGxlcywgQikgew0KICBib290c3RyYXBfZXN0aW1hdGVzIDwtIHJlcGxpY2F0ZShCLCB7DQogICAgYm9vdHN0cmFwX3NhbXBsZSA8LSBzYW1wbGUoc2FtcGxlcywgcmVwbGFjZSA9IFRSVUUpICMgQm9vdHN0cmFwIHJlc2FtcGxpbmcNCiAgICBjYWxjdWxhdGVfZ194X2Jhcihib290c3RyYXBfc2FtcGxlKSAjIENhbGN1bGF0ZSBnKPCdkYvMhCkgZm9yIGJvb3RzdHJhcCBzYW1wbGUNCiAgfSkNCiAgcmV0dXJuKGJvb3RzdHJhcF9lc3RpbWF0ZXMpDQp9DQoNCiMgTG9vcCBvdmVyIGVhY2ggTiBhbmQgcCwgc2ltdWxhdGUgQmVybm91bGxpIHRyaWFscywgYW5kIGFwcGx5IGJvb3RzdHJhcA0KZm9yIChOIGluIHNhbXBsZV9zaXplcykgew0KICBmb3IgKHAgaW4gdHJ1ZV9wcykgew0KICAgIGZvciAoaSBpbiAxOjEwMCkgeyAjIFJlcGVhdCBlYWNoIGNvbmZpZ3VyYXRpb24gMTAwIHRpbWVzDQogICAgICBzYW1wbGVzIDwtIHJiaW5vbShOLCAxLCBwKSAjIFNpbXVsYXRlIE4gQmVybm91bGxpIHRyaWFscw0KICAgICAgDQogICAgICBib290c3RyYXBfZXN0aW1hdGVzIDwtIHBlcmZvcm1fYm9vdHN0cmFwKHNhbXBsZXMsIEIpDQogICAgICANCiAgICAgIGJvb3RzdHJhcF9tZWFuIDwtIG1lYW4oYm9vdHN0cmFwX2VzdGltYXRlcykgIyBCb290c3RyYXAgbWVhbg0KICAgICAgYm9vdHN0cmFwX3ZhcmlhbmNlIDwtIHZhcihib290c3RyYXBfZXN0aW1hdGVzKSAqIEIgLyAoQiAtIDEpICMgQm9vdHN0cmFwIHZhcmlhbmNlDQogICAgICANCiAgICAgICMgQ3JlYXRlIHRoZSBjb21iaW5lZCBOX1Bfc2V0IGlkZW50aWZpZXINCiAgICAgIE5fUF9zZXRfdmFsdWUgPC0gc3ByaW50ZigiTi4lZHAuJXMuJWQiLCBOLCBnc3ViKCIwXFwuIiwgIiIsIGZvcm1hdChwLCBuc21hbGwgPSAyKSksIGkpDQogICAgICANCiAgICAgICMgQXBwZW5kIHRvIHJlc3VsdHMgZGF0YWZyYW1lDQogICAgICBib290c3RyYXBfcmVzdWx0c19kZiA8LSByYmluZChib290c3RyYXBfcmVzdWx0c19kZiwgZGF0YS5mcmFtZShOID0gTiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFAgPSBwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTl9QX3NldCA9IE5fUF9zZXRfdmFsdWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCb290c3RyYXBfTWVhbiA9IGJvb3RzdHJhcF9tZWFuLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQm9vdHN0cmFwX1ZhcmlhbmNlID0gYm9vdHN0cmFwX3ZhcmlhbmNlKSkNCiAgICB9DQogIH0NCn0NCg0KIyBTYXZlIHJlc3VsdHMgdG8gQ1NWIGZpbGUgd2l0aCBzcGVjaWZpZWQgaGVhZGVycw0Kd3JpdGUuY3N2KGJvb3RzdHJhcF9yZXN1bHRzX2RmLCAiYm9vdHN0cmFwX3Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCiMyKEIpDQpgYGB7cn0NCiMgRGVmaW5lIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBnKFgtYmFyKQ0KY2FsY3VsYXRlX2cgPC0gZnVuY3Rpb24oc2FtcGxlX2F2ZXJhZ2UpIHsNCiAgcmV0dXJuKHNhbXBsZV9hdmVyYWdlIC8gKDEgLSBzYW1wbGVfYXZlcmFnZSkpDQp9DQoNCiMgRGVmaW5lIGZ1bmN0aW9uIHRvIHBlcmZvcm0gYm9vdHN0cmFwDQpwZXJmb3JtX2Jvb3RzdHJhcCA8LSBmdW5jdGlvbihzYW1wbGVfZGF0YSwgQikgew0KICBnX3ZhbHVlcyA8LSBudW1lcmljKEIpDQogIGZvciAoYiBpbiAxOkIpIHsNCiAgICBib290c3RyYXBfc2FtcGxlIDwtIHNhbXBsZShzYW1wbGVfZGF0YSwgcmVwbGFjZSA9IFRSVUUpDQogICAgc2FtcGxlX2F2ZXJhZ2UgPC0gbWVhbihib290c3RyYXBfc2FtcGxlKQ0KICAgIGdfdmFsdWVzW2JdIDwtIGNhbGN1bGF0ZV9nKHNhbXBsZV9hdmVyYWdlKQ0KICB9DQogIHJldHVybihnX3ZhbHVlcykNCn0NCg0KIyBTZXQgcGFyYW1ldGVycw0KQiA8LSAxMDAgICMgTnVtYmVyIG9mIGJvb3RzdHJhcCByZWFsaXphdGlvbnMNCml0ZXJhdGlvbnMgPC0gMTAwICAjIE51bWJlciBvZiBpdGVyYXRpb25zDQpOIDwtIDEwMCAgIyBTYW1wbGUgc2l6ZQ0KcCA8LSAwLjUgICMgVHJ1ZSBwYXJhbWV0ZXIgdmFsdWUNCg0KIyBJbml0aWFsaXplIG1hdHJpY2VzIHRvIHN0b3JlIHJlc3VsdHMNCmV4cGVjdGVkX3ZhbHVlcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSBpdGVyYXRpb25zLCBuY29sID0gMSkNCnZhcmlhbmNlcyA8LSBtYXRyaXgoTkEsIG5yb3cgPSBpdGVyYXRpb25zLCBuY29sID0gMSkNCg0KIyBQZXJmb3JtIGl0ZXJhdGlvbnMNCmZvciAoaXRlciBpbiAxOml0ZXJhdGlvbnMpIHsNCiAgIyBHZW5lcmF0ZSBzYW1wbGUgb2YgQmVybm91bGxpIHJhbmRvbSB2YXJpYWJsZXMNCiAgc2FtcGxlX2RhdGEgPC0gcmJpbm9tKE4sIDEsIHApDQogIA0KICAjIENhbGN1bGF0ZSBzYW1wbGUgYXZlcmFnZQ0KICBzYW1wbGVfYXZlcmFnZSA8LSBtZWFuKHNhbXBsZV9kYXRhKQ0KICANCiAgIyBDYWxjdWxhdGUgZyhYLWJhcikNCiAgZyA8LSBjYWxjdWxhdGVfZyhzYW1wbGVfYXZlcmFnZSkNCiAgDQogICMgUGVyZm9ybSBib290c3RyYXANCiAgYm9vdHN0cmFwX2cgPC0gcGVyZm9ybV9ib290c3RyYXAoc2FtcGxlX2RhdGEsIEIpDQogIA0KICAjIEVzdGltYXRlIGV4cGVjdGVkIHZhbHVlIGFuZCB2YXJpYW5jZSBvZiBnKFgtYmFyKQ0KICBleHBlY3RlZF92YWx1ZXNbaXRlciwgMV0gPC0gbWVhbihib290c3RyYXBfZykNCiAgdmFyaWFuY2VzW2l0ZXIsIDFdIDwtIHZhcihib290c3RyYXBfZykgKiBCIC8gKEIgLSAxKQ0KfQ0KDQojIENhbGN1bGF0ZSBtZWFuIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBleHBlY3RlZCB2YWx1ZSBhbmQgdmFyaWFuY2UNCm1lYW5fZXhwZWN0ZWRfdmFsdWUgPC0gbWVhbihleHBlY3RlZF92YWx1ZXMpDQptZWFuX3ZhcmlhbmNlIDwtIG1lYW4odmFyaWFuY2VzKQ0Kc3RhbmRhcmRfZXJyb3JfZXhwZWN0ZWRfdmFsdWUgPC0gc2QoZXhwZWN0ZWRfdmFsdWVzKSAvIHNxcnQoaXRlcmF0aW9ucykNCnN0YW5kYXJkX2Vycm9yX3ZhcmlhbmNlIDwtIHNkKHZhcmlhbmNlcykgLyBzcXJ0KGl0ZXJhdGlvbnMpDQoNCiMgUHJpbnQgcmVzdWx0cw0KY2F0KCJFc3RpbWF0ZWQgRXhwZWN0ZWQgVmFsdWUgb2YgZyhYLWJhcik6IiwgbWVhbl9leHBlY3RlZF92YWx1ZSwgIlxuIikNCmNhdCgiRXN0aW1hdGVkIFZhcmlhbmNlIG9mIGcoWC1iYXIpOiIsIG1lYW5fdmFyaWFuY2UsICJcbiIpDQpjYXQoIlN0YW5kYXJkIEVycm9yIG9mIEV4cGVjdGVkIFZhbHVlOiIsIHN0YW5kYXJkX2Vycm9yX2V4cGVjdGVkX3ZhbHVlLCAiXG4iKQ0KY2F0KCJTdGFuZGFyZCBFcnJvciBvZiBWYXJpYW5jZToiLCBzdGFuZGFyZF9lcnJvcl92YXJpYW5jZSwgIlxuIikNCmBgYA0KDQoNCiMzKEQpDQpgYGB7cn0NCiMgTG9hZCByZXF1aXJlZCBsaWJyYXJ5DQpsaWJyYXJ5KE1BU1MpDQoNCiMgRnVuY3Rpb24gdG8gY2FsY3VsYXRlIGxpa2VsaWhvb2QgZnVuY3Rpb24gZm9yIHANCmxpa2VsaWhvb2QgPC0gZnVuY3Rpb24ocCwgeCkgew0KICBwcm9kKHBeeCAvICgxLXApXigxLXgpKQ0KfQ0KDQojIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGZvciBwDQpwb3N0ZXJpb3JfcCA8LSBmdW5jdGlvbihwcmlvcl9hbHBoYSwgcHJpb3JfYmV0YSwgeCkgew0KICBzdW1feCA8LSBzdW0oeCkNCiAgbiA8LSBsZW5ndGgoeCkNCiAgcG9zdGVyaW9yX2FscGhhIDwtIHByaW9yX2FscGhhICsgc3VtX3gNCiAgcG9zdGVyaW9yX2JldGEgPC0gcHJpb3JfYmV0YSAtIG4gKyBzdW1feA0KICByZXR1cm4obGlzdChhbHBoYSA9IHBvc3Rlcmlvcl9hbHBoYSwgYmV0YSA9IHBvc3Rlcmlvcl9iZXRhKSkNCn0NCg0KIyBGdW5jdGlvbiB0byB0cmFuc2Zvcm0gcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBmb3IgcCB0byBvYnRhaW4gcG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiBmb3Igeg0KcG9zdGVyaW9yX3ogPC0gZnVuY3Rpb24ocG9zdGVyaW9yX2FscGhhLCBwb3N0ZXJpb3JfYmV0YSkgew0KICB6X21lYW4gPC0gcG9zdGVyaW9yX2FscGhhIC8gKHBvc3Rlcmlvcl9hbHBoYSArIHBvc3Rlcmlvcl9iZXRhKQ0KICB6X3ZhciA8LSAocG9zdGVyaW9yX2FscGhhICogcG9zdGVyaW9yX2JldGEpIC8gKChwb3N0ZXJpb3JfYWxwaGEgKyBwb3N0ZXJpb3JfYmV0YSleMiAqIChwb3N0ZXJpb3JfYWxwaGEgKyBwb3N0ZXJpb3JfYmV0YSArIDEpKQ0KICByZXR1cm4obGlzdChtZWFuID0gel9tZWFuLCB2YXJpYW5jZSA9IHpfdmFyKSkNCn0NCg0KIyBQYXJhbWV0ZXJzDQpwcmlvcl9hbHBoYSA8LSAwLjUNCnByaW9yX2JldGEgPC0gMC41DQpOX3ZhbHVlcyA8LSBjKDEwLCAzMCwgMTAwLCAxMDAwKSAgIyBEaWZmZXJlbnQgdmFsdWVzIG9mIE4NCnRydWVfcGFyYW1zIDwtIGMoMC4wMSwgMC4xLCAwLjI1LCAwLjUsIDAuNzUsIDAuOSwgMC45OSkgICMgVHJ1ZSBwYXJhbWV0ZXJzIGZvciBzaW11bGF0aW9uDQpudW1fc2ltdWxhdGlvbnMgPC0gMTAwICAjIE51bWJlciBvZiBzaW11bGF0aW9ucyBwZXIgY29uZmlndXJhdGlvbg0KDQojIFN0b3JhZ2UgZm9yIHJlc3VsdHMNCnJlc3VsdHNfbGlzdCA8LSBsaXN0KCkNCg0KIyBQZXJmb3JtIHNpbXVsYXRpb25zIGZvciBlYWNoIGNvbWJpbmF0aW9uIG9mIE4gYW5kIHRydWUgcGFyYW1ldGVycw0KZm9yIChOIGluIE5fdmFsdWVzKSB7DQogIGZvciAocCBpbiB0cnVlX3BhcmFtcykgew0KICAgIHJlc3VsdHMgPC0gbWF0cml4KE5BLCBucm93ID0gbnVtX3NpbXVsYXRpb25zLCBuY29sID0gMikNCiAgICANCiAgICBmb3IgKGkgaW4gMTpudW1fc2ltdWxhdGlvbnMpIHsNCiAgICAgICMgR2VuZXJhdGUgTiBCZXJub3VsbGkgc2FtcGxlcyB3aXRoIHBhcmFtZXRlciBwDQogICAgICB4IDwtIHJiaW5vbShOLCAxLCBwKQ0KICAgICAgDQogICAgICAjIENhbGN1bGF0ZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGZvciBwDQogICAgICBwb3N0ZXJpb3JfcGFyYW1zIDwtIHBvc3Rlcmlvcl9wKHByaW9yX2FscGhhLCBwcmlvcl9iZXRhLCB4KQ0KICAgICAgDQogICAgICAjIENhbGN1bGF0ZSBwb3N0ZXJpb3IgZGlzdHJpYnV0aW9uIGZvciB6DQogICAgICB6X3Bvc3RlcmlvciA8LSBwb3N0ZXJpb3Jfeihwb3N0ZXJpb3JfcGFyYW1zJGFscGhhLCBwb3N0ZXJpb3JfcGFyYW1zJGJldGEpDQogICAgICANCiAgICAgICMgU3RvcmUgbWVhbiBhbmQgdmFyaWFuY2Ugb2YgeiBzYW1wbGVzDQogICAgICByZXN1bHRzW2ksIF0gPC0gYyh6X3Bvc3RlcmlvciRtZWFuLCB6X3Bvc3RlcmlvciR2YXJpYW5jZSkNCiAgICB9DQogICAgDQogICAgIyBTdG9yZSByZXN1bHRzIGZvciB0aGlzIGNvbmZpZ3VyYXRpb24NCiAgICBjb25maWdfbmFtZSA8LSBwYXN0ZSgiTiIsIE4sICJwIiwgZ3N1YigiXFwuIiwgIiIsIGFzLmNoYXJhY3RlcihwKSksIHNlcCA9ICJfIikNCiAgICByZXN1bHRzX2xpc3RbW2NvbmZpZ19uYW1lXV0gPC0gcmVzdWx0cw0KICB9DQp9DQoNCiMgUHJpbnQgcmVzdWx0cyBmb3IgZWFjaCBjb25maWd1cmF0aW9uDQojZm9yIChjb25maWdfbmFtZSBpbiBuYW1lcyhyZXN1bHRzX2xpc3QpKSB7DQogICNjYXQoIlJlc3VsdHMgZm9yIGNvbmZpZ3VyYXRpb246IiwgY29uZmlnX25hbWUsICJcbiIpDQogIyBwcmludChyZXN1bHRzX2xpc3RbW2NvbmZpZ19uYW1lXV0pDQogIyBjYXQoIlxuIikNCiMgRmxhdHRlbiB0aGUgcmVzdWx0cyBsaXN0IGludG8gYSBkYXRhIGZyYW1lDQpyZXN1bHRzX2RmIDwtIGRvLmNhbGwocmJpbmQsIGxhcHBseShuYW1lcyhyZXN1bHRzX2xpc3QpLCBmdW5jdGlvbihjb25maWdfbmFtZSkgew0KICBjb25maWdfcmVzdWx0cyA8LSByZXN1bHRzX2xpc3RbW2NvbmZpZ19uYW1lXV0NCiAgY29uZmlnX3Jlc3VsdHMgPC0gY2JpbmQoY29uZmlnX25hbWUgPSByZXAoY29uZmlnX25hbWUsIG5yb3coY29uZmlnX3Jlc3VsdHMpKSwgY29uZmlnX3Jlc3VsdHMpDQogIHJldHVybihhcy5kYXRhLmZyYW1lKGNvbmZpZ19yZXN1bHRzKSkNCn0pKQ0KDQojIFdyaXRlIHRoZSByZXN1bHRzIHRvIGEgQ1NWIGZpbGUNCndyaXRlLmNzdihyZXN1bHRzX2RmLCAic2ltdWxhdGlvbl9yZXN1bHRzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQ0KDQoNCiMgRmxhdHRlbiB0aGUgcmVzdWx0cyBsaXN0IGludG8gYSBkYXRhIGZyYW1lDQpyZXN1bHRzX2RmIDwtIGRvLmNhbGwocmJpbmQsIGxhcHBseShuYW1lcyhyZXN1bHRzX2xpc3QpLCBmdW5jdGlvbihjb25maWdfbmFtZSkgew0KICBjb25maWdfcmVzdWx0cyA8LSByZXN1bHRzX2xpc3RbW2NvbmZpZ19uYW1lXV0NCiAgY29uZmlnX3Jlc3VsdHMgPC0gY2JpbmQoY29uZmlnX25hbWUgPSByZXAoY29uZmlnX25hbWUsIG5yb3coY29uZmlnX3Jlc3VsdHMpKSwgY29uZmlnX3Jlc3VsdHMpDQogIHJldHVybihhcy5kYXRhLmZyYW1lKGNvbmZpZ19yZXN1bHRzKSkNCn0pKQ0KDQojIFdyaXRlIHRoZSByZXN1bHRzIHRvIGEgQ1NWIGZpbGUNCndyaXRlLmNzdihyZXN1bHRzX2RmLCAic2ltdWxhdGlvbl9yZXN1bHRzX1Bvc3Rlcmlvci5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkNCg0KYGBgDQoNCg==