1 CI for Mean

1.1 One Sample Mean - Z Interval

A (1−\alpha)100 \% confidence interval for \mu is:

\bar{x} \pm z_{\alpha / 2}\left(\frac{\sigma}{\sqrt{n}}\right)

z_interval <- function(data, conf_level = 0.95){
  
  # basic stats from data
  n <- length(data)
  xbar <- mean(data)
  sigma_hat <- sd(data)   # estimate sigma from data
  
  # critical value
  alpha <- 1 - conf_level
  z_crit <- qnorm(1 - alpha/2)
  
  # margin of error
  margin_error <- z_crit * (sigma_hat / sqrt(n))
  
  # interval
  lower <- xbar - margin_error
  upper <- xbar + margin_error
  
  return(list(
    n = n,
    mean = xbar,
    sd = sigma_hat,
    conf_level = conf_level,
    z_crit = z_crit,
    margin_error = margin_error,
    lower = lower,
    upper = upper
  ))
}
df1_url <- "https://github.com/novrisuhermi/dataset/raw/refs/heads/main/data_blood_lead_level.csv"
df1 <- read.csv(df1_url)
head(df1)
print(mean(df1$x))
[1] 29.28741
print(sd(df1$x))
[1] 6.716728
z_interval(df1$x, conf_level = 0.95)
$n
[1] 126

$mean
[1] 29.28741

$sd
[1] 6.716728

$conf_level
[1] 0.95

$z_crit
[1] 1.959964

$margin_error
[1] 1.172791

$lower
[1] 28.11461

$upper
[1] 30.4602
{
  mu <- mean(df1$x)
  sigma <- sd(df1$x)
  x_vals <- seq(mu - 4 * sigma, mu + 4 * sigma, length.out = 200)
  y_vals <- dnorm(x_vals, mean = mu, sd = sigma)

  hist(df1$x,
       breaks = 15,
       col    = "steelblue",
       border = "white",
       main   = "Distribution of Blood Lead Levels",
       xlab   = "Blood Lead Levels (micrograms / liter)",
       freq   = FALSE,
       xlim   = c(mu - 4 * sigma, mu + 4 * sigma))

  polygon(c(x_vals, rev(x_vals)),
          c(y_vals, rep(0, length(y_vals))),
          col = rgb(0, 0, 1, 0.2),
          border = NA)

  invisible(lines(x_vals, y_vals,
                  col = "blue",
                  lwd = 2))
}

1.2 One Sample Mean - t Interval

A (1−\alpha)100 \% confidence interval for \mu is:

\bar{x} \pm t_{\alpha / 2, n-1}\left(\frac{s}{\sqrt{n}}\right)

t_interval <- function(data, conf_level = 0.95){
  
  # basic stats from data
  n <- length(data)
  xbar <- mean(data)
  s <- sd(data)
  
  # degree of freedom
  df <- n - 1
  
  # critical value
  alpha <- 1 - conf_level
  t_crit <- qt(1 - alpha/2, df = df)
  
  # margin of error
  margin_error <- t_crit * (s / sqrt(n))
  
  # interval
  lower <- xbar - margin_error
  upper <- xbar + margin_error
  
  return(list(
    n = n,
    mean = xbar,
    sd = s,
    df = df,
    conf_level = conf_level,
    t_crit = t_crit,
    margin_error = margin_error,
    lower = lower,
    upper = upper
  ))
}
x <- c(118, 115, 125, 110, 112, 130, 117, 112, 
       115, 120, 113, 118, 119, 122, 123, 126)
t_interval(x, conf_level = 0.95)
$n
[1] 16

$mean
[1] 118.4375

$sd
[1] 5.656486

$df
[1] 15

$conf_level
[1] 0.95

$t_crit
[1] 2.13145

$margin_error
[1] 3.014129

$lower
[1] 115.4234

$upper
[1] 121.4516
# Base R function
t.test(x)[c("estimate","stderr","conf.int")]
$estimate
mean of x 
 118.4375 

$stderr
[1] 1.414121

$conf.int
[1] 115.4234 121.4516
attr(,"conf.level")
[1] 0.95
{
  mu <- mean(x)
  sigma <- sd(x)
  x_vals <- seq(mu - 4 * sigma, mu + 4 * sigma, length.out = 200)
  y_vals <- dnorm(x_vals, mean = mu, sd = sigma)

  hist(x,
       breaks = 8,
       col    = "steelblue",
       border = "white",
       main   = "Distribution of Beef Consumption",
       xlab   = "Beef Consumption (pounds / year)",
       freq   = FALSE,
       xlim   = c(mu - 4 * sigma, mu + 4 * sigma))

  polygon(c(x_vals, rev(x_vals)),
          c(y_vals, rep(0, length(y_vals))),
          col = rgb(0, 0, 1, 0.2),
          border = NA)

  invisible(lines(x_vals, y_vals,
                  col = "blue",
                  lwd = 2))
}

1.3 Two Sample Mean - Pooled t Interval

A (1−\alpha)100 \% confidence interval for \mu_X - \mu_Y is:

(\bar{X}-\bar{Y}) \pm t_{\alpha / 2, n+m-2} S_p \sqrt{\frac{1}{n}+\frac{1}{m}}

where the pooled sample variance is:

S_p^2=\frac{(n-1) S_X^2+(m-1) S_Y^2}{n+m-2}

is an unbiased estimator of the common \sigma^2.

t_interval_2sample_equal <- function(data1, data2, conf_level = 0.95){
  
  # sample size
  n1 <- length(data1); n2 <- length(data2)
  # statistic mean and sd
  xbar1 <- mean(data1); xbar2 <- mean(data2)
  s1 <- sd(data1); s2 <- sd(data2)
  # pooled variance
  sp2 <- ((n1 - 1)*s1^2 + (n2 - 1)*s2^2) / (n1 + n2 - 2)
  sp <- sqrt(sp2)
  # standard error
  SE <- sp * sqrt(1/n1 + 1/n2)
  # degree of freedom
  df <- n1 + n2 - 2
  # critical value
  alpha <- 1 - conf_level
  t_crit <- qt(1 - alpha/2, df)
  # margin of error
  margin_error <- t_crit * SE
  # difference in mean
  diff_mean <- xbar1 - xbar2
  # interval
  lower <- diff_mean - margin_error
  upper <- diff_mean + margin_error
  
  return(list(
    n1 = n1, n2 = n2,
    mean1 = xbar1, mean2 = xbar2,
    sd1 = s1, sd2 = s2,
    pooled_sd = sp,
    df = df,
    conf_level = conf_level,
    t_crit = t_crit,
    SE = SE,
    margin_error = margin_error,
    diff_mean = diff_mean,
    lower = lower,
    upper = upper
  ))
}
x1 <- c(12.9, 10.2, 7.4, 7.0, 10.5, 11.9, 7.1, 9.9, 14.4, 11.3)
x2 <- c(10.2, 6.9, 10.9, 11.0, 10.1, 5.3, 7.5, 10.3, 9.2, 8.8)
t_interval_2sample_equal(x1, x2, conf_level = 0.95)
$n1
[1] 10

$n2
[1] 10

$mean1
[1] 10.26

$mean2
[1] 9.02

$sd1
[1] 2.513607

$sd2
[1] 1.896664

$pooled_sd
[1] 2.226607

$df
[1] 18

$conf_level
[1] 0.95

$t_crit
[1] 2.100922

$SE
[1] 0.9957688

$margin_error
[1] 2.092033

$diff_mean
[1] 1.24

$lower
[1] -0.8520327

$upper
[1] 3.332033
# Base R function
t.test(x1,x2,var.equal = TRUE)[c("estimate","stderr","conf.int")]
$estimate
mean of x mean of y 
    10.26      9.02 

$stderr
[1] 0.9957688

$conf.int
[1] -0.8520327  3.3320327
attr(,"conf.level")
[1] 0.95
boxplot(x1, x2,
        names = c("deinopis", "menneus"),
        col   = c(rgb(0, 0, 1, 0.4), rgb(1, 0, 0, 0.4)),
        border = c("blue", "red"),
        main  = "Distribution of Spider Prey Sizes",
        ylab  = "size (mm)",
        notch = FALSE)

1.4 Two Sample Mean - Welch’s t Interval

If the data are approximately normal and \sigma^2_X \neq \sigma^2_Y, a (1−\alpha)100 \% confidence interval for \mu_X - \mu_Y is:

(\bar{X}-\bar{Y}) \pm t_{\alpha / 2, r} \sqrt{\frac{S_X^2}{n}+\frac{S_Y^2}{m}}

where the degree of freedom r are approximated by Welch-Satterthwaite:

r=\frac{\left(\frac{S_X^2}{n}+\frac{S_Y^2}{m}\right)^2}{\frac{\left(S_X^2 / n\right)^2}{n-1}+\frac{\left(S_Y^2 / m\right)^2}{m-1}}

t_interval_2sample_unequal <- function(data1, data2, conf_level = 0.95){
  
  # sample size
  n1 <- length(data1); n2 <- length(data2)
  # statistic mean & sd
  xbar1 <- mean(data1); xbar2 <- mean(data2)
  s1 <- sd(data1); s2 <- sd(data2)
  # standard error (Welch)
  SE <- sqrt((s1^2 / n1) + (s2^2 / n2))
  # Welch degrees of freedom
  df <- ((s1^2/n1 + s2^2/n2)^2) /
        (( (s1^2/n1)^2 / (n1 - 1) ) + ( (s2^2/n2)^2 / (n2 - 1) ))
  # critical value
  alpha <- 1 - conf_level
  t_crit <- qt(1 - alpha/2, df)
  # margin of error
  margin_error <- t_crit * SE
  # difference in mean
  diff_mean <- xbar1 - xbar2
  # interval
  lower <- diff_mean - margin_error
  upper <- diff_mean + margin_error
  
  return(list(
    n1 = n1,
    n2 = n2,
    mean1 = xbar1,
    mean2 = xbar2,
    sd1 = s1,
    sd2 = s2,
    df = df,
    conf_level = conf_level,
    t_crit = t_crit,
    SE = SE,
    margin_error = margin_error,
    diff_mean = diff_mean,
    lower = lower,
    upper = upper
  ))
}
x1 <- c(12.9, 10.2, 7.4, 7.0, 10.5, 11.9, 7.1, 9.9, 14.4, 11.3)
x2 <- c(10.2, 6.9, 10.9, 11.0, 10.1, 5.3, 7.5, 10.3, 9.2, 8.8)
t_interval_2sample_unequal(x1, x2, conf_level = 0.95)
$n1
[1] 10

$n2
[1] 10

$mean1
[1] 10.26

$mean2
[1] 9.02

$sd1
[1] 2.513607

$sd2
[1] 1.896664

$df
[1] 16.73953

$conf_level
[1] 0.95

$t_crit
[1] 2.112319

$SE
[1] 0.9957688

$margin_error
[1] 2.103382

$diff_mean
[1] 1.24

$lower
[1] -0.8633815

$upper
[1] 3.343382
# Base R function
t.test(x1,x2,var.equal = FALSE)[c("estimate","stderr","conf.int")]
$estimate
mean of x mean of y 
    10.26      9.02 

$stderr
[1] 0.9957688

$conf.int
[1] -0.8633815  3.3433815
attr(,"conf.level")
[1] 0.95

1.5 Dependent Sample Mean - Paired t Interval

Define differences D_i = X_i-Y-i for each pair i.

Assume the D_i are normally distributed with mean \mu_D = \mu_X-\mu_Y.

The differences are independent (one per pair), so we reduce to a one-sample problem!

A (1−\alpha)100 \% confidence interval for \mu_D=\mu_X - \mu_Y is simply the one-sample t-interval applied to the differences:

\bar{d} \pm t_{\alpha / 2, n-1}\left(\frac{s_d}{\sqrt{n}}\right)

where \bar{d}=\frac{1}{n} \sum_{i=1}^n d_i

and

s_d=\sqrt{\frac{1}{n-1} \sum_{i=1}^n\left(d_i-\bar{d}\right)^2}

paired_t_interval <- function(data1, data2, conf_level = 0.95) {
  
  # Check whether the two samples have the same length
  if (length(data1) != length(data2)) {
    stop("data1 and data2 must have the same length for a paired-sample analysis.")
  }
  # Compute paired differences
  differences <- data1 - data2
  # Basic summary statistics of the differences
  n <- length(differences)
  mean_diff <- mean(differences)
  sd_diff <- sd(differences)
  df <- n - 1
  # Significance level
  alpha <- 1 - conf_level
  # Critical t value
  t_critical <- qt(1 - alpha / 2, df = df)
  # Standard error
  standard_error <- sd_diff / sqrt(n)
  # Margin of error
  margin_of_error <- t_critical * standard_error
  # Confidence interval
  lower_bound <- mean_diff - margin_of_error
  upper_bound <- mean_diff + margin_of_error
  
  # Return results
  return(list(
    n = n,
    mean_difference = mean_diff,
    sd_difference = sd_diff,
    degrees_of_freedom = df,
    confidence_level = conf_level,
    t_critical = t_critical,
    standard_error = standard_error,
    margin_of_error = margin_of_error,
    lower_bound = lower_bound,
    upper_bound = upper_bound
  ))
}
unaffect <- c(1.94, 1.44, 1.56, 1.58, 2.06,
              1.66, 1.75, 1.77, 1.78, 1.92,
              1.25, 1.93, 2.04, 1.62, 2.08)

affect <- c(1.27, 1.63, 1.47, 1.39, 1.93,
            1.26, 1.71, 1.67, 1.28, 1.85,
            1.02, 1.34, 2.02, 1.59, 1.97)

paired_t_interval(unaffect, affect, conf_level = 0.95)
$n
[1] 15

$mean_difference
[1] 0.1986667

$sd_difference
[1] 0.2382935

$degrees_of_freedom
[1] 14

$confidence_level
[1] 0.95

$t_critical
[1] 2.144787

$standard_error
[1] 0.06152713

$margin_of_error
[1] 0.1319626

$lower_bound
[1] 0.0667041

$upper_bound
[1] 0.3306292
# Base R function
t.test(unaffect,affect,paired = TRUE)[c("estimate","stderr","conf.int")]
$estimate
mean difference 
      0.1986667 

$stderr
[1] 0.06152713

$conf.int
[1] 0.0667041 0.3306292
attr(,"conf.level")
[1] 0.95
{
  diff <- unaffect - affect
  par(mfrow = c(1,3), mar = c(4,6,3,1))
  
  # 🔹 1. Before–After Plot
  plot(c(1,2), range(c(unaffect, affect)),
       type = "n", xaxt = "n",
       xlab = "", ylab = expression(paste("Volume (cm"^3, ")")),
       main = "Before vs After")
  
  axis(1, at = c(1,2), labels = c("Unaffect", "Affect"))
  
  for(i in 1:length(unaffect)){
    lines(c(1,2), c(unaffect[i], affect[i]),
          col = rgb(0.5,0.5,0.5,0.5))
  }
  
  points(rep(1, length(unaffect)), unaffect,
         col = "blue", pch = 19)
  
  points(rep(2, length(affect)), affect,
         col = "red", pch = 19)
  
  # 🔹 2. Boxplot Comparison
  boxplot(unaffect, affect,
          names = c("Unaffect", "Affect"),
          col = c(rgb(0,0,1,0.4), rgb(1,0,0,0.4)),
          border = c("blue","red"),
          main = "Boxplot Comparison")
  
  # 🔹 3. Boxplot Differences
  boxplot(diff,
          col = rgb(0,0,1,0.3),
          border = "blue",
          main = "Difference (Unaffect - Affect)")
  
  abline(h = 0, col = "red", lwd = 2)
  
  # Reset layout
  par(mfrow = c(1,1))
  
  invisible(NULL)
}

2 CI for Proportion

2.1 CI for One Sample Proportion

Let X_i \sim \operatorname{Bernoulli}(p), we have

\mathrm{E}\left(X_i\right)=p \text{ and } \operatorname{Var}\left(X_i\right)=p(1-p)

By the Central Limit Theorem, for large n:

Z=\frac{\bar{X}-\mu}{\sigma / \sqrt{n}}=\frac{\hat{p}-p}{\sqrt{\frac{p(1-p)}{n}}} \sim N(0,1) \text{ (approximately)}

For large random samples, an approximate (1−\alpha)100\% confidence interval for a population proportion p is:

\hat{p} \pm z_{\alpha / 2} \sqrt{\frac{\hat{p}(1-\hat{p})}{n}}

z_interval_proportion <- function(x, n, conf_level = 0.95) {
  
  # Estimate the proportion
  p_hat <- x / n
  
  # Critical value
  alpha <- 1 - conf_level
  z_crit <- qnorm(1 - alpha / 2)
  
  # Standard error
  SE <- sqrt(p_hat * (1 - p_hat) / n)
  
  # Margin of error
  margin_error <- z_crit * SE
  
  # Confidence interval
  lower <- p_hat - margin_error
  upper <- p_hat + margin_error
  
  return(list(
    x = x,
    n = n,
    p_hat = p_hat,
    conf_level = conf_level,
    z_crit = z_crit,
    standard_error = SE,
    margin_error = margin_error,
    lower = lower,
    upper = upper
  ))
}
z_interval_proportion(280, 418, conf_level = 0.95)
$x
[1] 280

$n
[1] 418

$p_hat
[1] 0.6698565

$conf_level
[1] 0.95

$z_crit
[1] 1.959964

$standard_error
[1] 0.02300139

$margin_error
[1] 0.0450819

$lower
[1] 0.6247746

$upper
[1] 0.7149384
# Base R function
prop.test(x = 280, n = 418, conf.level = 0.95)[c("estimate","conf.int")]
$estimate
        p 
0.6698565 

$conf.int
[1] 0.6221809 0.7143568
attr(,"conf.level")
[1] 0.95

2.2 CI for Two Sample Proportion

For large random samples, an approximate (1−\alpha)100\% confidence interval for a population proportion p_1-p_2 is:

\left(\hat{p}_1-\hat{p}_2\right) \pm z_{\alpha / 2} \sqrt{\frac{\hat{p}_1\left(1-\hat{p}_1\right)}{n_1}+\frac{\hat{p}_2\left(1-\hat{p}_2\right)}{n_2}}

z_interval_2prop <- function(x1, n1, x2, n2, conf_level = 0.95) {

  # Estimate the proportion
  p1_hat <- x1 / n1; p2_hat <- x2 / n2
  # Proportion difference
  diff <- p1_hat - p2_hat
  # Critical value
  alpha <- 1 - conf_level
  z_crit <- qnorm(1 - alpha / 2)
  # Standard error
  SE <- sqrt((p1_hat * (1 - p1_hat) / n1) +
             (p2_hat * (1 - p2_hat) / n2))
  # Margin of error
  margin_error <- z_crit * SE
  # Confidence interval
  lower <- diff - margin_error
  upper <- diff + margin_error
  
  return(list(
    x1 = x1,
    n1 = n1,
    p1_hat = p1_hat,
    x2 = x2,
    n2 = n2,
    p2_hat = p2_hat,
    diff = diff,
    conf_level = conf_level,
    z_crit = z_crit,
    standard_error = SE,
    margin_error = margin_error,
    lower = lower,
    upper = upper
  ))
}
z_interval_2prop(x1 = 840, n1 = 2100,
                 x2 = 323, n2 = 1900,
                 conf_level = 0.95)
$x1
[1] 840

$n1
[1] 2100

$p1_hat
[1] 0.4

$x2
[1] 323

$n2
[1] 1900

$p2_hat
[1] 0.17

$diff
[1] 0.23

$conf_level
[1] 0.95

$z_crit
[1] 1.959964

$standard_error
[1] 0.01373131

$margin_error
[1] 0.02691287

$lower
[1] 0.2030871

$upper
[1] 0.2569129
# Base R function
prop.test(x = c(840, 323),
          n = c(2100, 1900),
          conf.level = 0.95,
          correct = FALSE)[c("estimate","conf.int")]
$estimate
prop 1 prop 2 
  0.40   0.17 

$conf.int
[1] 0.2030871 0.2569129
attr(,"conf.level")
[1] 0.95

3 CI for Variance

3.1 CI for One Variance

If X_1, \ldots, X_n \sim N\left(\mu, \sigma^2\right)

and

a=\chi_{1-\alpha / 2, n-1}^2, b=\chi_{\alpha / 2, n-1}^2,

then a (1-\alpha)100\% CI for \sigma^2 is:

\frac{(n-1) s^2}{b} \leq \sigma^2 \leq \frac{(n-1) s^2}{a}

And a (1-\alpha)100\% CI for \sigma is obtained by taking square roots:

\frac{\sqrt{(n-1)} s}{\sqrt{b}} \leq \sigma \leq \frac{\sqrt{(n-1)} s}{\sqrt{a}}

ci_variance <- function(data, conf_level = 0.95){
  
  # basic stats
  n <- length(data)
  s2 <- var(data)
  df <- n - 1
  
  alpha <- 1 - conf_level
  
  # chi-square critical values
  chi_lower <- qchisq(alpha/2, df)
  chi_upper <- qchisq(1 - alpha/2, df)
  
  # CI for variance
  lower_var <- (df * s2) / chi_upper
  upper_var <- (df * s2) / chi_lower
  
  # CI for standard deviation
  lower_sd <- sqrt(lower_var)
  upper_sd <- sqrt(upper_var)
  
  return(list(
    n = n,
    sample_variance = s2,
    df = df,
    conf_level = conf_level,
    chi_lower = chi_lower,
    chi_upper = chi_upper,
    variance_CI = c(lower_var, upper_var),
    sd_CI = c(lower_sd, upper_sd)
  ))
}
x <- c(52.48, 52.15, 50.02, 51.85, 54.96,
       52.92, 52.08, 51.13, 47.79, 54.31)

ci_variance(data = x, conf_level = 0.95)
$n
[1] 10

$sample_variance
[1] 4.179743

$df
[1] 9

$conf_level
[1] 0.95

$chi_lower
[1] 2.700389

$chi_upper
[1] 19.02277

$variance_CI
[1]  1.977509 13.930468

$sd_CI
[1] 1.406239 3.732354
# Verify results
EnvStats::varTest(x, conf.level = 0.95)[c("estimate","conf.int")]
$estimate
variance 
4.179743 

$conf.int
      LCL       UCL 
 1.977509 13.930468 
attr(,"conf.level")
[1] 0.95

3.2 CI for Two Variances

If X_1, \ldots, X_n \sim N\left(\mu_X, \sigma_X^2\right) and Y_1, \ldots, Y_m \sim N\left(\mu_Y, \sigma_Y^2\right) be independent random samples.

Since \frac{(n-1) S_X^2}{\sigma_X^2} \sim \chi_{n-1}^2 and \frac{(m-1) S_Y^2}{\sigma_Y^2} \sim \chi_{m-1}^2 independently, by the definition of the F-distribution:

F=\frac{(m-1) S_Y^2 / \sigma_Y^2 /(m-1)}{(n-1) S_X^2 / \sigma_X^2 /(n-1)}=\frac{\sigma_X^2}{\sigma_Y^2} \cdot \frac{S_Y^2}{S_X^2} \sim F(m-1, n-1)

This pivotal quantity contains the ratio \sigma^2_X / \sigma^2_Y, exactly the parameter we want to estimate.

A (1-\alpha)100\% CI for the ratio of two population variances \sigma^2_X / \sigma^2_Y is:

\frac{1}{F_{\alpha / 2}(n-1, m-1)} \cdot \frac{S_X^2}{S_Y^2} \leq \frac{\sigma_X^2}{\sigma_Y^2} \leq F_{\alpha / 2}(m-1, n-1) \cdot \frac{S_X^2}{S_Y^2}

ci_variance_ratio <- function(data1, data2, conf_level = 0.95){
  
  # basic stats
  n1 <- length(data1); n2 <- length(data2)
  s1_sq <- var(data1); s2_sq <- var(data2)
  
  df1 <- n1 - 1
  df2 <- n2 - 1
  
  alpha <- 1 - conf_level
  
  # F critical values
  F_lower <- qf(alpha/2, df1, df2)
  F_upper <- qf(1 - alpha/2, df1, df2)
  
  # ratio of variances
  ratio <- s1_sq / s2_sq
  
  # confidence interval
  lower <- ratio / F_upper
  upper <- ratio / F_lower
  
  return(list(
    n1 = n1,
    n2 = n2,
    var1 = s1_sq,
    var2 = s2_sq,
    ratio = ratio,
    df1 = df1,
    df2 = df2,
    conf_level = conf_level,
    F_lower = F_lower,
    F_upper = F_upper,
    lower = lower,
    upper = upper
  ))
}
ci_variance_ratio(x1, x2, conf_level = 0.95)
$n1
[1] 10

$n2
[1] 10

$var1
[1] 6.318222

$var2
[1] 3.597333

$ratio
[1] 1.756363

$df1
[1] 9

$df2
[1] 9

$conf_level
[1] 0.95

$F_lower
[1] 0.2483859

$F_upper
[1] 4.025994

$lower
[1] 0.4362557

$upper
[1] 7.071106
# Verify results
var.test(x1, x2, conf.level = 0.95)[c("estimate", "conf.int")]
$estimate
ratio of variances 
          1.756363 

$conf.int
[1] 0.4362557 7.0711061
attr(,"conf.level")
[1] 0.95
{
# Density value
d1 <- density(x1)
d2 <- density(x2)

# Data range
x_range <- range(c(d1$x, d2$x))
y_range <- range(c(d1$y, d2$y))

# Empty plot
plot(d1,
     col = "blue",
     lwd = 2,
     main = "Prey Sizes Distribution",
     xlab = "Size (mm)",
     xlim = x_range,
     ylim = y_range,
     type = "n")  

# 🔵 Fill Group 1
polygon(d1,
        col = rgb(0, 0, 1, 0.3),
        border = NA)

# 🔴 Fill Group 2
polygon(d2,
        col = rgb(1, 0, 0, 0.3),
        border = NA)

# Line colors
lines(d1, col = "blue", lwd = 2)
lines(d2, col = "red",  lwd = 2)
legend("topright",
       legend = c("deinopis", "menneus"),
       col = c("blue", "red"),
       lwd = 2,
       bty = "n")
}

LS0tCnRpdGxlOiAiQ29tcHV0YXRpb25hbCBTdGF0aXN0aWNzIFdlZWsgNCIKCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgbWF0aF9tZXRob2Q6IGthdGV4CiAgICB0aGVtZTogeWV0aQogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6CiAgICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgZGZfcHJpbnQ6IHBhZ2VkCi0tLQoKIyBDSSBmb3IgTWVhbgoKIyMgT25lIFNhbXBsZSBNZWFuIC0gWiBJbnRlcnZhbAoKQSAkKDHiiJJcYWxwaGEpMTAwIFwlJCBjb25maWRlbmNlIGludGVydmFsIGZvciAkXG11JCBpczoKCiQkClxiYXJ7eH0gXHBtIHpfe1xhbHBoYSAvIDJ9XGxlZnQoXGZyYWN7XHNpZ21hfXtcc3FydHtufX1ccmlnaHQpCiQkCgpgYGB7cn0Kel9pbnRlcnZhbCA8LSBmdW5jdGlvbihkYXRhLCBjb25mX2xldmVsID0gMC45NSl7CiAgCiAgIyBiYXNpYyBzdGF0cyBmcm9tIGRhdGEKICBuIDwtIGxlbmd0aChkYXRhKQogIHhiYXIgPC0gbWVhbihkYXRhKQogIHNpZ21hX2hhdCA8LSBzZChkYXRhKSAgICMgZXN0aW1hdGUgc2lnbWEgZnJvbSBkYXRhCiAgCiAgIyBjcml0aWNhbCB2YWx1ZQogIGFscGhhIDwtIDEgLSBjb25mX2xldmVsCiAgel9jcml0IDwtIHFub3JtKDEgLSBhbHBoYS8yKQogIAogICMgbWFyZ2luIG9mIGVycm9yCiAgbWFyZ2luX2Vycm9yIDwtIHpfY3JpdCAqIChzaWdtYV9oYXQgLyBzcXJ0KG4pKQogIAogICMgaW50ZXJ2YWwKICBsb3dlciA8LSB4YmFyIC0gbWFyZ2luX2Vycm9yCiAgdXBwZXIgPC0geGJhciArIG1hcmdpbl9lcnJvcgogIAogIHJldHVybihsaXN0KAogICAgbiA9IG4sCiAgICBtZWFuID0geGJhciwKICAgIHNkID0gc2lnbWFfaGF0LAogICAgY29uZl9sZXZlbCA9IGNvbmZfbGV2ZWwsCiAgICB6X2NyaXQgPSB6X2NyaXQsCiAgICBtYXJnaW5fZXJyb3IgPSBtYXJnaW5fZXJyb3IsCiAgICBsb3dlciA9IGxvd2VyLAogICAgdXBwZXIgPSB1cHBlcgogICkpCn0KYGBgCgpgYGB7cn0KZGYxX3VybCA8LSAiaHR0cHM6Ly9naXRodWIuY29tL25vdnJpc3VoZXJtaS9kYXRhc2V0L3Jhdy9yZWZzL2hlYWRzL21haW4vZGF0YV9ibG9vZF9sZWFkX2xldmVsLmNzdiIKZGYxIDwtIHJlYWQuY3N2KGRmMV91cmwpCmhlYWQoZGYxKQpgYGAKCmBgYHtyfQpwcmludChtZWFuKGRmMSR4KSkKcHJpbnQoc2QoZGYxJHgpKQpgYGAKCmBgYHtyfQp6X2ludGVydmFsKGRmMSR4LCBjb25mX2xldmVsID0gMC45NSkKYGBgCgpgYGB7cn0KewogIG11IDwtIG1lYW4oZGYxJHgpCiAgc2lnbWEgPC0gc2QoZGYxJHgpCiAgeF92YWxzIDwtIHNlcShtdSAtIDQgKiBzaWdtYSwgbXUgKyA0ICogc2lnbWEsIGxlbmd0aC5vdXQgPSAyMDApCiAgeV92YWxzIDwtIGRub3JtKHhfdmFscywgbWVhbiA9IG11LCBzZCA9IHNpZ21hKQoKICBoaXN0KGRmMSR4LAogICAgICAgYnJlYWtzID0gMTUsCiAgICAgICBjb2wgICAgPSAic3RlZWxibHVlIiwKICAgICAgIGJvcmRlciA9ICJ3aGl0ZSIsCiAgICAgICBtYWluICAgPSAiRGlzdHJpYnV0aW9uIG9mIEJsb29kIExlYWQgTGV2ZWxzIiwKICAgICAgIHhsYWIgICA9ICJCbG9vZCBMZWFkIExldmVscyAobWljcm9ncmFtcyAvIGxpdGVyKSIsCiAgICAgICBmcmVxICAgPSBGQUxTRSwKICAgICAgIHhsaW0gICA9IGMobXUgLSA0ICogc2lnbWEsIG11ICsgNCAqIHNpZ21hKSkKCiAgcG9seWdvbihjKHhfdmFscywgcmV2KHhfdmFscykpLAogICAgICAgICAgYyh5X3ZhbHMsIHJlcCgwLCBsZW5ndGgoeV92YWxzKSkpLAogICAgICAgICAgY29sID0gcmdiKDAsIDAsIDEsIDAuMiksCiAgICAgICAgICBib3JkZXIgPSBOQSkKCiAgaW52aXNpYmxlKGxpbmVzKHhfdmFscywgeV92YWxzLAogICAgICAgICAgICAgICAgICBjb2wgPSAiYmx1ZSIsCiAgICAgICAgICAgICAgICAgIGx3ZCA9IDIpKQp9CmBgYAoKIyMgT25lIFNhbXBsZSBNZWFuIC0gdCBJbnRlcnZhbAoKQSAkKDHiiJJcYWxwaGEpMTAwIFwlJCBjb25maWRlbmNlIGludGVydmFsIGZvciAkXG11JCBpczoKCiQkClxiYXJ7eH0gXHBtIHRfe1xhbHBoYSAvIDIsIG4tMX1cbGVmdChcZnJhY3tzfXtcc3FydHtufX1ccmlnaHQpCiQkCgpgYGB7cn0KdF9pbnRlcnZhbCA8LSBmdW5jdGlvbihkYXRhLCBjb25mX2xldmVsID0gMC45NSl7CiAgCiAgIyBiYXNpYyBzdGF0cyBmcm9tIGRhdGEKICBuIDwtIGxlbmd0aChkYXRhKQogIHhiYXIgPC0gbWVhbihkYXRhKQogIHMgPC0gc2QoZGF0YSkKICAKICAjIGRlZ3JlZSBvZiBmcmVlZG9tCiAgZGYgPC0gbiAtIDEKICAKICAjIGNyaXRpY2FsIHZhbHVlCiAgYWxwaGEgPC0gMSAtIGNvbmZfbGV2ZWwKICB0X2NyaXQgPC0gcXQoMSAtIGFscGhhLzIsIGRmID0gZGYpCiAgCiAgIyBtYXJnaW4gb2YgZXJyb3IKICBtYXJnaW5fZXJyb3IgPC0gdF9jcml0ICogKHMgLyBzcXJ0KG4pKQogIAogICMgaW50ZXJ2YWwKICBsb3dlciA8LSB4YmFyIC0gbWFyZ2luX2Vycm9yCiAgdXBwZXIgPC0geGJhciArIG1hcmdpbl9lcnJvcgogIAogIHJldHVybihsaXN0KAogICAgbiA9IG4sCiAgICBtZWFuID0geGJhciwKICAgIHNkID0gcywKICAgIGRmID0gZGYsCiAgICBjb25mX2xldmVsID0gY29uZl9sZXZlbCwKICAgIHRfY3JpdCA9IHRfY3JpdCwKICAgIG1hcmdpbl9lcnJvciA9IG1hcmdpbl9lcnJvciwKICAgIGxvd2VyID0gbG93ZXIsCiAgICB1cHBlciA9IHVwcGVyCiAgKSkKfQpgYGAKCmBgYHtyfQp4IDwtIGMoMTE4LCAxMTUsIDEyNSwgMTEwLCAxMTIsIDEzMCwgMTE3LCAxMTIsIAogICAgICAgMTE1LCAxMjAsIDExMywgMTE4LCAxMTksIDEyMiwgMTIzLCAxMjYpCnRfaW50ZXJ2YWwoeCwgY29uZl9sZXZlbCA9IDAuOTUpCmBgYAoKYGBge3J9CiMgQmFzZSBSIGZ1bmN0aW9uCnQudGVzdCh4KVtjKCJlc3RpbWF0ZSIsInN0ZGVyciIsImNvbmYuaW50IildCmBgYAoKYGBge3J9CnsKICBtdSA8LSBtZWFuKHgpCiAgc2lnbWEgPC0gc2QoeCkKICB4X3ZhbHMgPC0gc2VxKG11IC0gNCAqIHNpZ21hLCBtdSArIDQgKiBzaWdtYSwgbGVuZ3RoLm91dCA9IDIwMCkKICB5X3ZhbHMgPC0gZG5vcm0oeF92YWxzLCBtZWFuID0gbXUsIHNkID0gc2lnbWEpCgogIGhpc3QoeCwKICAgICAgIGJyZWFrcyA9IDgsCiAgICAgICBjb2wgICAgPSAic3RlZWxibHVlIiwKICAgICAgIGJvcmRlciA9ICJ3aGl0ZSIsCiAgICAgICBtYWluICAgPSAiRGlzdHJpYnV0aW9uIG9mIEJlZWYgQ29uc3VtcHRpb24iLAogICAgICAgeGxhYiAgID0gIkJlZWYgQ29uc3VtcHRpb24gKHBvdW5kcyAvIHllYXIpIiwKICAgICAgIGZyZXEgICA9IEZBTFNFLAogICAgICAgeGxpbSAgID0gYyhtdSAtIDQgKiBzaWdtYSwgbXUgKyA0ICogc2lnbWEpKQoKICBwb2x5Z29uKGMoeF92YWxzLCByZXYoeF92YWxzKSksCiAgICAgICAgICBjKHlfdmFscywgcmVwKDAsIGxlbmd0aCh5X3ZhbHMpKSksCiAgICAgICAgICBjb2wgPSByZ2IoMCwgMCwgMSwgMC4yKSwKICAgICAgICAgIGJvcmRlciA9IE5BKQoKICBpbnZpc2libGUobGluZXMoeF92YWxzLCB5X3ZhbHMsCiAgICAgICAgICAgICAgICAgIGNvbCA9ICJibHVlIiwKICAgICAgICAgICAgICAgICAgbHdkID0gMikpCn0KYGBgCgojIyBUd28gU2FtcGxlIE1lYW4gLSBQb29sZWQgdCBJbnRlcnZhbAoKQSAkKDHiiJJcYWxwaGEpMTAwIFwlJCBjb25maWRlbmNlIGludGVydmFsIGZvciAkXG11X1ggLSBcbXVfWSQgaXM6CgokJAooXGJhcntYfS1cYmFye1l9KSBccG0gdF97XGFscGhhIC8gMiwgbittLTJ9IFNfcCBcc3FydHtcZnJhY3sxfXtufStcZnJhY3sxfXttfX0KJCQKCndoZXJlIHRoZSBwb29sZWQgc2FtcGxlIHZhcmlhbmNlIGlzOgoKJCQKU19wXjI9XGZyYWN7KG4tMSkgU19YXjIrKG0tMSkgU19ZXjJ9e24rbS0yfQokJAoKaXMgYW4gdW5iaWFzZWQgZXN0aW1hdG9yIG9mIHRoZSBjb21tb24gJFxzaWdtYV4yJC4KCmBgYHtyfQp0X2ludGVydmFsXzJzYW1wbGVfZXF1YWwgPC0gZnVuY3Rpb24oZGF0YTEsIGRhdGEyLCBjb25mX2xldmVsID0gMC45NSl7CiAgCiAgIyBzYW1wbGUgc2l6ZQogIG4xIDwtIGxlbmd0aChkYXRhMSk7IG4yIDwtIGxlbmd0aChkYXRhMikKICAjIHN0YXRpc3RpYyBtZWFuIGFuZCBzZAogIHhiYXIxIDwtIG1lYW4oZGF0YTEpOyB4YmFyMiA8LSBtZWFuKGRhdGEyKQogIHMxIDwtIHNkKGRhdGExKTsgczIgPC0gc2QoZGF0YTIpCiAgIyBwb29sZWQgdmFyaWFuY2UKICBzcDIgPC0gKChuMSAtIDEpKnMxXjIgKyAobjIgLSAxKSpzMl4yKSAvIChuMSArIG4yIC0gMikKICBzcCA8LSBzcXJ0KHNwMikKICAjIHN0YW5kYXJkIGVycm9yCiAgU0UgPC0gc3AgKiBzcXJ0KDEvbjEgKyAxL24yKQogICMgZGVncmVlIG9mIGZyZWVkb20KICBkZiA8LSBuMSArIG4yIC0gMgogICMgY3JpdGljYWwgdmFsdWUKICBhbHBoYSA8LSAxIC0gY29uZl9sZXZlbAogIHRfY3JpdCA8LSBxdCgxIC0gYWxwaGEvMiwgZGYpCiAgIyBtYXJnaW4gb2YgZXJyb3IKICBtYXJnaW5fZXJyb3IgPC0gdF9jcml0ICogU0UKICAjIGRpZmZlcmVuY2UgaW4gbWVhbgogIGRpZmZfbWVhbiA8LSB4YmFyMSAtIHhiYXIyCiAgIyBpbnRlcnZhbAogIGxvd2VyIDwtIGRpZmZfbWVhbiAtIG1hcmdpbl9lcnJvcgogIHVwcGVyIDwtIGRpZmZfbWVhbiArIG1hcmdpbl9lcnJvcgogIAogIHJldHVybihsaXN0KAogICAgbjEgPSBuMSwgbjIgPSBuMiwKICAgIG1lYW4xID0geGJhcjEsIG1lYW4yID0geGJhcjIsCiAgICBzZDEgPSBzMSwgc2QyID0gczIsCiAgICBwb29sZWRfc2QgPSBzcCwKICAgIGRmID0gZGYsCiAgICBjb25mX2xldmVsID0gY29uZl9sZXZlbCwKICAgIHRfY3JpdCA9IHRfY3JpdCwKICAgIFNFID0gU0UsCiAgICBtYXJnaW5fZXJyb3IgPSBtYXJnaW5fZXJyb3IsCiAgICBkaWZmX21lYW4gPSBkaWZmX21lYW4sCiAgICBsb3dlciA9IGxvd2VyLAogICAgdXBwZXIgPSB1cHBlcgogICkpCn0KYGBgCgpgYGB7cn0KeDEgPC0gYygxMi45LCAxMC4yLCA3LjQsIDcuMCwgMTAuNSwgMTEuOSwgNy4xLCA5LjksIDE0LjQsIDExLjMpCngyIDwtIGMoMTAuMiwgNi45LCAxMC45LCAxMS4wLCAxMC4xLCA1LjMsIDcuNSwgMTAuMywgOS4yLCA4LjgpCnRfaW50ZXJ2YWxfMnNhbXBsZV9lcXVhbCh4MSwgeDIsIGNvbmZfbGV2ZWwgPSAwLjk1KQpgYGAKCmBgYHtyfQojIEJhc2UgUiBmdW5jdGlvbgp0LnRlc3QoeDEseDIsdmFyLmVxdWFsID0gVFJVRSlbYygiZXN0aW1hdGUiLCJzdGRlcnIiLCJjb25mLmludCIpXQpgYGAKCmBgYHtyfQpib3hwbG90KHgxLCB4MiwKICAgICAgICBuYW1lcyA9IGMoImRlaW5vcGlzIiwgIm1lbm5ldXMiKSwKICAgICAgICBjb2wgICA9IGMocmdiKDAsIDAsIDEsIDAuNCksIHJnYigxLCAwLCAwLCAwLjQpKSwKICAgICAgICBib3JkZXIgPSBjKCJibHVlIiwgInJlZCIpLAogICAgICAgIG1haW4gID0gIkRpc3RyaWJ1dGlvbiBvZiBTcGlkZXIgUHJleSBTaXplcyIsCiAgICAgICAgeWxhYiAgPSAic2l6ZSAobW0pIiwKICAgICAgICBub3RjaCA9IEZBTFNFKQpgYGAKCgojIyBUd28gU2FtcGxlIE1lYW4gLSBXZWxjaCdzIHQgSW50ZXJ2YWwKCklmIHRoZSBkYXRhIGFyZSBhcHByb3hpbWF0ZWx5IG5vcm1hbCBhbmQgJFxzaWdtYV4yX1ggXG5lcSBcc2lnbWFeMl9ZJCwgYSAkKDHiiJJcYWxwaGEpMTAwIFwlJCBjb25maWRlbmNlIGludGVydmFsIGZvciAkXG11X1ggLSBcbXVfWSQgaXM6CgokJAooXGJhcntYfS1cYmFye1l9KSBccG0gdF97XGFscGhhIC8gMiwgcn0gXHNxcnR7XGZyYWN7U19YXjJ9e259K1xmcmFje1NfWV4yfXttfX0KJCQKCndoZXJlIHRoZSBkZWdyZWUgb2YgZnJlZWRvbSAkciQgYXJlIGFwcHJveGltYXRlZCBieSBXZWxjaC1TYXR0ZXJ0aHdhaXRlOgoKJCQKcj1cZnJhY3tcbGVmdChcZnJhY3tTX1heMn17bn0rXGZyYWN7U19ZXjJ9e219XHJpZ2h0KV4yfXtcZnJhY3tcbGVmdChTX1heMiAvIG5ccmlnaHQpXjJ9e24tMX0rXGZyYWN7XGxlZnQoU19ZXjIgLyBtXHJpZ2h0KV4yfXttLTF9fQokJAoKYGBge3J9CnRfaW50ZXJ2YWxfMnNhbXBsZV91bmVxdWFsIDwtIGZ1bmN0aW9uKGRhdGExLCBkYXRhMiwgY29uZl9sZXZlbCA9IDAuOTUpewogIAogICMgc2FtcGxlIHNpemUKICBuMSA8LSBsZW5ndGgoZGF0YTEpOyBuMiA8LSBsZW5ndGgoZGF0YTIpCiAgIyBzdGF0aXN0aWMgbWVhbiAmIHNkCiAgeGJhcjEgPC0gbWVhbihkYXRhMSk7IHhiYXIyIDwtIG1lYW4oZGF0YTIpCiAgczEgPC0gc2QoZGF0YTEpOyBzMiA8LSBzZChkYXRhMikKICAjIHN0YW5kYXJkIGVycm9yIChXZWxjaCkKICBTRSA8LSBzcXJ0KChzMV4yIC8gbjEpICsgKHMyXjIgLyBuMikpCiAgIyBXZWxjaCBkZWdyZWVzIG9mIGZyZWVkb20KICBkZiA8LSAoKHMxXjIvbjEgKyBzMl4yL24yKV4yKSAvCiAgICAgICAgKCggKHMxXjIvbjEpXjIgLyAobjEgLSAxKSApICsgKCAoczJeMi9uMileMiAvIChuMiAtIDEpICkpCiAgIyBjcml0aWNhbCB2YWx1ZQogIGFscGhhIDwtIDEgLSBjb25mX2xldmVsCiAgdF9jcml0IDwtIHF0KDEgLSBhbHBoYS8yLCBkZikKICAjIG1hcmdpbiBvZiBlcnJvcgogIG1hcmdpbl9lcnJvciA8LSB0X2NyaXQgKiBTRQogICMgZGlmZmVyZW5jZSBpbiBtZWFuCiAgZGlmZl9tZWFuIDwtIHhiYXIxIC0geGJhcjIKICAjIGludGVydmFsCiAgbG93ZXIgPC0gZGlmZl9tZWFuIC0gbWFyZ2luX2Vycm9yCiAgdXBwZXIgPC0gZGlmZl9tZWFuICsgbWFyZ2luX2Vycm9yCiAgCiAgcmV0dXJuKGxpc3QoCiAgICBuMSA9IG4xLAogICAgbjIgPSBuMiwKICAgIG1lYW4xID0geGJhcjEsCiAgICBtZWFuMiA9IHhiYXIyLAogICAgc2QxID0gczEsCiAgICBzZDIgPSBzMiwKICAgIGRmID0gZGYsCiAgICBjb25mX2xldmVsID0gY29uZl9sZXZlbCwKICAgIHRfY3JpdCA9IHRfY3JpdCwKICAgIFNFID0gU0UsCiAgICBtYXJnaW5fZXJyb3IgPSBtYXJnaW5fZXJyb3IsCiAgICBkaWZmX21lYW4gPSBkaWZmX21lYW4sCiAgICBsb3dlciA9IGxvd2VyLAogICAgdXBwZXIgPSB1cHBlcgogICkpCn0KYGBgCgpgYGB7cn0KeDEgPC0gYygxMi45LCAxMC4yLCA3LjQsIDcuMCwgMTAuNSwgMTEuOSwgNy4xLCA5LjksIDE0LjQsIDExLjMpCngyIDwtIGMoMTAuMiwgNi45LCAxMC45LCAxMS4wLCAxMC4xLCA1LjMsIDcuNSwgMTAuMywgOS4yLCA4LjgpCnRfaW50ZXJ2YWxfMnNhbXBsZV91bmVxdWFsKHgxLCB4MiwgY29uZl9sZXZlbCA9IDAuOTUpCmBgYAoKYGBge3J9CiMgQmFzZSBSIGZ1bmN0aW9uCnQudGVzdCh4MSx4Mix2YXIuZXF1YWwgPSBGQUxTRSlbYygiZXN0aW1hdGUiLCJzdGRlcnIiLCJjb25mLmludCIpXQpgYGAKCiMjIERlcGVuZGVudCBTYW1wbGUgTWVhbiAtIFBhaXJlZCB0IEludGVydmFsCgpEZWZpbmUgZGlmZmVyZW5jZXMgJERfaSA9IFhfaS1ZLWkkIGZvciBlYWNoIHBhaXIgJGkkLgoKQXNzdW1lIHRoZSAkRF9pJCBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQgd2l0aCBtZWFuICRcbXVfRCA9IFxtdV9YLVxtdV9ZJC4KClRoZSBkaWZmZXJlbmNlcyBhcmUgaW5kZXBlbmRlbnQgKG9uZSBwZXIgcGFpciksIHNvIHdlIHJlZHVjZSB0byBhIG9uZS1zYW1wbGUgcHJvYmxlbSEKCkEgJCgx4oiSXGFscGhhKTEwMCBcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgJFxtdV9EPVxtdV9YIC0gXG11X1kkIGlzIHNpbXBseSB0aGUgb25lLXNhbXBsZSB0LWludGVydmFsIGFwcGxpZWQgdG8gdGhlIGRpZmZlcmVuY2VzOgoKJCQKXGJhcntkfSBccG0gdF97XGFscGhhIC8gMiwgbi0xfVxsZWZ0KFxmcmFje3NfZH17XHNxcnR7bn19XHJpZ2h0KQokJAoKd2hlcmUgJCQKXGJhcntkfT1cZnJhY3sxfXtufSBcc3VtX3tpPTF9Xm4gZF9pCiQkCgphbmQKCiQkCnNfZD1cc3FydHtcZnJhY3sxfXtuLTF9IFxzdW1fe2k9MX1eblxsZWZ0KGRfaS1cYmFye2R9XHJpZ2h0KV4yfQokJAoKYGBge3J9CnBhaXJlZF90X2ludGVydmFsIDwtIGZ1bmN0aW9uKGRhdGExLCBkYXRhMiwgY29uZl9sZXZlbCA9IDAuOTUpIHsKICAKICAjIENoZWNrIHdoZXRoZXIgdGhlIHR3byBzYW1wbGVzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoCiAgaWYgKGxlbmd0aChkYXRhMSkgIT0gbGVuZ3RoKGRhdGEyKSkgewogICAgc3RvcCgiZGF0YTEgYW5kIGRhdGEyIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGggZm9yIGEgcGFpcmVkLXNhbXBsZSBhbmFseXNpcy4iKQogIH0KICAjIENvbXB1dGUgcGFpcmVkIGRpZmZlcmVuY2VzCiAgZGlmZmVyZW5jZXMgPC0gZGF0YTEgLSBkYXRhMgogICMgQmFzaWMgc3VtbWFyeSBzdGF0aXN0aWNzIG9mIHRoZSBkaWZmZXJlbmNlcwogIG4gPC0gbGVuZ3RoKGRpZmZlcmVuY2VzKQogIG1lYW5fZGlmZiA8LSBtZWFuKGRpZmZlcmVuY2VzKQogIHNkX2RpZmYgPC0gc2QoZGlmZmVyZW5jZXMpCiAgZGYgPC0gbiAtIDEKICAjIFNpZ25pZmljYW5jZSBsZXZlbAogIGFscGhhIDwtIDEgLSBjb25mX2xldmVsCiAgIyBDcml0aWNhbCB0IHZhbHVlCiAgdF9jcml0aWNhbCA8LSBxdCgxIC0gYWxwaGEgLyAyLCBkZiA9IGRmKQogICMgU3RhbmRhcmQgZXJyb3IKICBzdGFuZGFyZF9lcnJvciA8LSBzZF9kaWZmIC8gc3FydChuKQogICMgTWFyZ2luIG9mIGVycm9yCiAgbWFyZ2luX29mX2Vycm9yIDwtIHRfY3JpdGljYWwgKiBzdGFuZGFyZF9lcnJvcgogICMgQ29uZmlkZW5jZSBpbnRlcnZhbAogIGxvd2VyX2JvdW5kIDwtIG1lYW5fZGlmZiAtIG1hcmdpbl9vZl9lcnJvcgogIHVwcGVyX2JvdW5kIDwtIG1lYW5fZGlmZiArIG1hcmdpbl9vZl9lcnJvcgogIAogICMgUmV0dXJuIHJlc3VsdHMKICByZXR1cm4obGlzdCgKICAgIG4gPSBuLAogICAgbWVhbl9kaWZmZXJlbmNlID0gbWVhbl9kaWZmLAogICAgc2RfZGlmZmVyZW5jZSA9IHNkX2RpZmYsCiAgICBkZWdyZWVzX29mX2ZyZWVkb20gPSBkZiwKICAgIGNvbmZpZGVuY2VfbGV2ZWwgPSBjb25mX2xldmVsLAogICAgdF9jcml0aWNhbCA9IHRfY3JpdGljYWwsCiAgICBzdGFuZGFyZF9lcnJvciA9IHN0YW5kYXJkX2Vycm9yLAogICAgbWFyZ2luX29mX2Vycm9yID0gbWFyZ2luX29mX2Vycm9yLAogICAgbG93ZXJfYm91bmQgPSBsb3dlcl9ib3VuZCwKICAgIHVwcGVyX2JvdW5kID0gdXBwZXJfYm91bmQKICApKQp9CmBgYAoKYGBge3J9CnVuYWZmZWN0IDwtIGMoMS45NCwgMS40NCwgMS41NiwgMS41OCwgMi4wNiwKICAgICAgICAgICAgICAxLjY2LCAxLjc1LCAxLjc3LCAxLjc4LCAxLjkyLAogICAgICAgICAgICAgIDEuMjUsIDEuOTMsIDIuMDQsIDEuNjIsIDIuMDgpCgphZmZlY3QgPC0gYygxLjI3LCAxLjYzLCAxLjQ3LCAxLjM5LCAxLjkzLAogICAgICAgICAgICAxLjI2LCAxLjcxLCAxLjY3LCAxLjI4LCAxLjg1LAogICAgICAgICAgICAxLjAyLCAxLjM0LCAyLjAyLCAxLjU5LCAxLjk3KQoKcGFpcmVkX3RfaW50ZXJ2YWwodW5hZmZlY3QsIGFmZmVjdCwgY29uZl9sZXZlbCA9IDAuOTUpCmBgYAoKYGBge3J9CiMgQmFzZSBSIGZ1bmN0aW9uCnQudGVzdCh1bmFmZmVjdCxhZmZlY3QscGFpcmVkID0gVFJVRSlbYygiZXN0aW1hdGUiLCJzdGRlcnIiLCJjb25mLmludCIpXQpgYGAKCgoKYGBge3J9CnsKICBkaWZmIDwtIHVuYWZmZWN0IC0gYWZmZWN0CiAgcGFyKG1mcm93ID0gYygxLDMpLCBtYXIgPSBjKDQsNiwzLDEpKQogIAogICMg8J+UuSAxLiBCZWZvcmXigJNBZnRlciBQbG90CiAgcGxvdChjKDEsMiksIHJhbmdlKGModW5hZmZlY3QsIGFmZmVjdCkpLAogICAgICAgdHlwZSA9ICJuIiwgeGF4dCA9ICJuIiwKICAgICAgIHhsYWIgPSAiIiwgeWxhYiA9IGV4cHJlc3Npb24ocGFzdGUoIlZvbHVtZSAoY20iXjMsICIpIikpLAogICAgICAgbWFpbiA9ICJCZWZvcmUgdnMgQWZ0ZXIiKQogIAogIGF4aXMoMSwgYXQgPSBjKDEsMiksIGxhYmVscyA9IGMoIlVuYWZmZWN0IiwgIkFmZmVjdCIpKQogIAogIGZvcihpIGluIDE6bGVuZ3RoKHVuYWZmZWN0KSl7CiAgICBsaW5lcyhjKDEsMiksIGModW5hZmZlY3RbaV0sIGFmZmVjdFtpXSksCiAgICAgICAgICBjb2wgPSByZ2IoMC41LDAuNSwwLjUsMC41KSkKICB9CiAgCiAgcG9pbnRzKHJlcCgxLCBsZW5ndGgodW5hZmZlY3QpKSwgdW5hZmZlY3QsCiAgICAgICAgIGNvbCA9ICJibHVlIiwgcGNoID0gMTkpCiAgCiAgcG9pbnRzKHJlcCgyLCBsZW5ndGgoYWZmZWN0KSksIGFmZmVjdCwKICAgICAgICAgY29sID0gInJlZCIsIHBjaCA9IDE5KQogIAogICMg8J+UuSAyLiBCb3hwbG90IENvbXBhcmlzb24KICBib3hwbG90KHVuYWZmZWN0LCBhZmZlY3QsCiAgICAgICAgICBuYW1lcyA9IGMoIlVuYWZmZWN0IiwgIkFmZmVjdCIpLAogICAgICAgICAgY29sID0gYyhyZ2IoMCwwLDEsMC40KSwgcmdiKDEsMCwwLDAuNCkpLAogICAgICAgICAgYm9yZGVyID0gYygiYmx1ZSIsInJlZCIpLAogICAgICAgICAgbWFpbiA9ICJCb3hwbG90IENvbXBhcmlzb24iKQogIAogICMg8J+UuSAzLiBCb3hwbG90IERpZmZlcmVuY2VzCiAgYm94cGxvdChkaWZmLAogICAgICAgICAgY29sID0gcmdiKDAsMCwxLDAuMyksCiAgICAgICAgICBib3JkZXIgPSAiYmx1ZSIsCiAgICAgICAgICBtYWluID0gIkRpZmZlcmVuY2UgKFVuYWZmZWN0IC0gQWZmZWN0KSIpCiAgCiAgYWJsaW5lKGggPSAwLCBjb2wgPSAicmVkIiwgbHdkID0gMikKICAKICAjIFJlc2V0IGxheW91dAogIHBhcihtZnJvdyA9IGMoMSwxKSkKICAKICBpbnZpc2libGUoTlVMTCkKfQpgYGAKCgojIENJIGZvciBQcm9wb3J0aW9uCgojIyBDSSBmb3IgT25lIFNhbXBsZSBQcm9wb3J0aW9uCgpMZXQgJFhfaSBcc2ltIFxvcGVyYXRvcm5hbWV7QmVybm91bGxpfShwKSQsIHdlIGhhdmUKCiQkClxtYXRocm17RX1cbGVmdChYX2lccmlnaHQpPXAgXHRleHR7IGFuZCB9IFxvcGVyYXRvcm5hbWV7VmFyfVxsZWZ0KFhfaVxyaWdodCk9cCgxLXApCiQkCgpCeSB0aGUgQ2VudHJhbCBMaW1pdCBUaGVvcmVtLCBmb3IgbGFyZ2UgJG4kOgoKJCQKWj1cZnJhY3tcYmFye1h9LVxtdX17XHNpZ21hIC8gXHNxcnR7bn19PVxmcmFje1xoYXR7cH0tcH17XHNxcnR7XGZyYWN7cCgxLXApfXtufX19IFxzaW0gTigwLDEpIFx0ZXh0eyAgKGFwcHJveGltYXRlbHkpfQokJAoKRm9yIGxhcmdlIHJhbmRvbSBzYW1wbGVzLCBhbiBhcHByb3hpbWF0ZSAkKDHiiJJcYWxwaGEpMTAwXCUkIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZm9yIGEgcG9wdWxhdGlvbiBwcm9wb3J0aW9uICRwJCBpczoKCiQkClxoYXR7cH0gXHBtIHpfe1xhbHBoYSAvIDJ9IFxzcXJ0e1xmcmFje1xoYXR7cH0oMS1caGF0e3B9KX17bn19CiQkCgpgYGB7cn0Kel9pbnRlcnZhbF9wcm9wb3J0aW9uIDwtIGZ1bmN0aW9uKHgsIG4sIGNvbmZfbGV2ZWwgPSAwLjk1KSB7CiAgCiAgIyBFc3RpbWF0ZSB0aGUgcHJvcG9ydGlvbgogIHBfaGF0IDwtIHggLyBuCiAgCiAgIyBDcml0aWNhbCB2YWx1ZQogIGFscGhhIDwtIDEgLSBjb25mX2xldmVsCiAgel9jcml0IDwtIHFub3JtKDEgLSBhbHBoYSAvIDIpCiAgCiAgIyBTdGFuZGFyZCBlcnJvcgogIFNFIDwtIHNxcnQocF9oYXQgKiAoMSAtIHBfaGF0KSAvIG4pCiAgCiAgIyBNYXJnaW4gb2YgZXJyb3IKICBtYXJnaW5fZXJyb3IgPC0gel9jcml0ICogU0UKICAKICAjIENvbmZpZGVuY2UgaW50ZXJ2YWwKICBsb3dlciA8LSBwX2hhdCAtIG1hcmdpbl9lcnJvcgogIHVwcGVyIDwtIHBfaGF0ICsgbWFyZ2luX2Vycm9yCiAgCiAgcmV0dXJuKGxpc3QoCiAgICB4ID0geCwKICAgIG4gPSBuLAogICAgcF9oYXQgPSBwX2hhdCwKICAgIGNvbmZfbGV2ZWwgPSBjb25mX2xldmVsLAogICAgel9jcml0ID0gel9jcml0LAogICAgc3RhbmRhcmRfZXJyb3IgPSBTRSwKICAgIG1hcmdpbl9lcnJvciA9IG1hcmdpbl9lcnJvciwKICAgIGxvd2VyID0gbG93ZXIsCiAgICB1cHBlciA9IHVwcGVyCiAgKSkKfQpgYGAKCmBgYHtyfQp6X2ludGVydmFsX3Byb3BvcnRpb24oMjgwLCA0MTgsIGNvbmZfbGV2ZWwgPSAwLjk1KQpgYGAKCmBgYHtyfQojIEJhc2UgUiBmdW5jdGlvbgpwcm9wLnRlc3QoeCA9IDI4MCwgbiA9IDQxOCwgY29uZi5sZXZlbCA9IDAuOTUpW2MoImVzdGltYXRlIiwiY29uZi5pbnQiKV0KYGBgCgoKCgojIyBDSSBmb3IgVHdvIFNhbXBsZSBQcm9wb3J0aW9uCgpGb3IgbGFyZ2UgcmFuZG9tIHNhbXBsZXMsIGFuIGFwcHJveGltYXRlICQoMeKIklxhbHBoYSkxMDBcJSQgY29uZmlkZW5jZSBpbnRlcnZhbCBmb3IgYSBwb3B1bGF0aW9uIHByb3BvcnRpb24gJHBfMS1wXzIkIGlzOgoKJCQKXGxlZnQoXGhhdHtwfV8xLVxoYXR7cH1fMlxyaWdodCkgXHBtIHpfe1xhbHBoYSAvIDJ9IFxzcXJ0e1xmcmFje1xoYXR7cH1fMVxsZWZ0KDEtXGhhdHtwfV8xXHJpZ2h0KX17bl8xfStcZnJhY3tcaGF0e3B9XzJcbGVmdCgxLVxoYXR7cH1fMlxyaWdodCl9e25fMn19CiQkCgpgYGB7cn0Kel9pbnRlcnZhbF8ycHJvcCA8LSBmdW5jdGlvbih4MSwgbjEsIHgyLCBuMiwgY29uZl9sZXZlbCA9IDAuOTUpIHsKCiAgIyBFc3RpbWF0ZSB0aGUgcHJvcG9ydGlvbgogIHAxX2hhdCA8LSB4MSAvIG4xOyBwMl9oYXQgPC0geDIgLyBuMgogICMgUHJvcG9ydGlvbiBkaWZmZXJlbmNlCiAgZGlmZiA8LSBwMV9oYXQgLSBwMl9oYXQKICAjIENyaXRpY2FsIHZhbHVlCiAgYWxwaGEgPC0gMSAtIGNvbmZfbGV2ZWwKICB6X2NyaXQgPC0gcW5vcm0oMSAtIGFscGhhIC8gMikKICAjIFN0YW5kYXJkIGVycm9yCiAgU0UgPC0gc3FydCgocDFfaGF0ICogKDEgLSBwMV9oYXQpIC8gbjEpICsKICAgICAgICAgICAgIChwMl9oYXQgKiAoMSAtIHAyX2hhdCkgLyBuMikpCiAgIyBNYXJnaW4gb2YgZXJyb3IKICBtYXJnaW5fZXJyb3IgPC0gel9jcml0ICogU0UKICAjIENvbmZpZGVuY2UgaW50ZXJ2YWwKICBsb3dlciA8LSBkaWZmIC0gbWFyZ2luX2Vycm9yCiAgdXBwZXIgPC0gZGlmZiArIG1hcmdpbl9lcnJvcgogIAogIHJldHVybihsaXN0KAogICAgeDEgPSB4MSwKICAgIG4xID0gbjEsCiAgICBwMV9oYXQgPSBwMV9oYXQsCiAgICB4MiA9IHgyLAogICAgbjIgPSBuMiwKICAgIHAyX2hhdCA9IHAyX2hhdCwKICAgIGRpZmYgPSBkaWZmLAogICAgY29uZl9sZXZlbCA9IGNvbmZfbGV2ZWwsCiAgICB6X2NyaXQgPSB6X2NyaXQsCiAgICBzdGFuZGFyZF9lcnJvciA9IFNFLAogICAgbWFyZ2luX2Vycm9yID0gbWFyZ2luX2Vycm9yLAogICAgbG93ZXIgPSBsb3dlciwKICAgIHVwcGVyID0gdXBwZXIKICApKQp9CmBgYAoKYGBge3J9CnpfaW50ZXJ2YWxfMnByb3AoeDEgPSA4NDAsIG4xID0gMjEwMCwKICAgICAgICAgICAgICAgICB4MiA9IDMyMywgbjIgPSAxOTAwLAogICAgICAgICAgICAgICAgIGNvbmZfbGV2ZWwgPSAwLjk1KQpgYGAKCmBgYHtyfQojIEJhc2UgUiBmdW5jdGlvbgpwcm9wLnRlc3QoeCA9IGMoODQwLCAzMjMpLAogICAgICAgICAgbiA9IGMoMjEwMCwgMTkwMCksCiAgICAgICAgICBjb25mLmxldmVsID0gMC45NSwKICAgICAgICAgIGNvcnJlY3QgPSBGQUxTRSlbYygiZXN0aW1hdGUiLCJjb25mLmludCIpXQpgYGAKCiMgQ0kgZm9yIFZhcmlhbmNlCgojIyBDSSBmb3IgT25lIFZhcmlhbmNlCgpJZiAkJFhfMSwgXGxkb3RzLCBYX24gXHNpbSBOXGxlZnQoXG11LCBcc2lnbWFeMlxyaWdodCkkJAoKYW5kCgokJAphPVxjaGlfezEtXGFscGhhIC8gMiwgbi0xfV4yLCBiPVxjaGlfe1xhbHBoYSAvIDIsIG4tMX1eMiwKJCQKCnRoZW4gYSAkKDEtXGFscGhhKTEwMFwlJCBDSSBmb3IgJFxzaWdtYV4yJCBpczoKCiQkClxmcmFjeyhuLTEpIHNeMn17Yn0gXGxlcSBcc2lnbWFeMiBcbGVxIFxmcmFjeyhuLTEpIHNeMn17YX0KJCQKCkFuZCBhICQoMS1cYWxwaGEpMTAwXCUkIENJIGZvciAkXHNpZ21hJCBpcyBvYnRhaW5lZCBieSB0YWtpbmcgc3F1YXJlIHJvb3RzOgoKJCQKXGZyYWN7XHNxcnR7KG4tMSl9IHN9e1xzcXJ0e2J9fSBcbGVxIFxzaWdtYSBcbGVxIFxmcmFje1xzcXJ0eyhuLTEpfSBzfXtcc3FydHthfX0KJCQKCmBgYHtyfQpjaV92YXJpYW5jZSA8LSBmdW5jdGlvbihkYXRhLCBjb25mX2xldmVsID0gMC45NSl7CiAgCiAgIyBiYXNpYyBzdGF0cwogIG4gPC0gbGVuZ3RoKGRhdGEpCiAgczIgPC0gdmFyKGRhdGEpCiAgZGYgPC0gbiAtIDEKICAKICBhbHBoYSA8LSAxIC0gY29uZl9sZXZlbAogIAogICMgY2hpLXNxdWFyZSBjcml0aWNhbCB2YWx1ZXMKICBjaGlfbG93ZXIgPC0gcWNoaXNxKGFscGhhLzIsIGRmKQogIGNoaV91cHBlciA8LSBxY2hpc3EoMSAtIGFscGhhLzIsIGRmKQogIAogICMgQ0kgZm9yIHZhcmlhbmNlCiAgbG93ZXJfdmFyIDwtIChkZiAqIHMyKSAvIGNoaV91cHBlcgogIHVwcGVyX3ZhciA8LSAoZGYgKiBzMikgLyBjaGlfbG93ZXIKICAKICAjIENJIGZvciBzdGFuZGFyZCBkZXZpYXRpb24KICBsb3dlcl9zZCA8LSBzcXJ0KGxvd2VyX3ZhcikKICB1cHBlcl9zZCA8LSBzcXJ0KHVwcGVyX3ZhcikKICAKICByZXR1cm4obGlzdCgKICAgIG4gPSBuLAogICAgc2FtcGxlX3ZhcmlhbmNlID0gczIsCiAgICBkZiA9IGRmLAogICAgY29uZl9sZXZlbCA9IGNvbmZfbGV2ZWwsCiAgICBjaGlfbG93ZXIgPSBjaGlfbG93ZXIsCiAgICBjaGlfdXBwZXIgPSBjaGlfdXBwZXIsCiAgICB2YXJpYW5jZV9DSSA9IGMobG93ZXJfdmFyLCB1cHBlcl92YXIpLAogICAgc2RfQ0kgPSBjKGxvd2VyX3NkLCB1cHBlcl9zZCkKICApKQp9CmBgYAoKYGBge3J9CnggPC0gYyg1Mi40OCwgNTIuMTUsIDUwLjAyLCA1MS44NSwgNTQuOTYsCiAgICAgICA1Mi45MiwgNTIuMDgsIDUxLjEzLCA0Ny43OSwgNTQuMzEpCgpjaV92YXJpYW5jZShkYXRhID0geCwgY29uZl9sZXZlbCA9IDAuOTUpCmBgYAoKYGBge3J9CiMgVmVyaWZ5IHJlc3VsdHMKRW52U3RhdHM6OnZhclRlc3QoeCwgY29uZi5sZXZlbCA9IDAuOTUpW2MoImVzdGltYXRlIiwiY29uZi5pbnQiKV0KYGBgCgojIyBDSSBmb3IgVHdvIFZhcmlhbmNlcwoKSWYgJFhfMSwgXGxkb3RzLCBYX24gXHNpbSBOXGxlZnQoXG11X1gsIFxzaWdtYV9YXjJccmlnaHQpJCBhbmQgJFlfMSwgXGxkb3RzLCBZX20gXHNpbSBOXGxlZnQoXG11X1ksIFxzaWdtYV9ZXjJccmlnaHQpJCBiZSBpbmRlcGVuZGVudCByYW5kb20gc2FtcGxlcy4KClNpbmNlICRcZnJhY3sobi0xKSBTX1heMn17XHNpZ21hX1heMn0gXHNpbSBcY2hpX3tuLTF9XjIkIGFuZCAkXGZyYWN7KG0tMSkgU19ZXjJ9e1xzaWdtYV9ZXjJ9IFxzaW0gXGNoaV97bS0xfV4yJCBpbmRlcGVuZGVudGx5LCBieSB0aGUgZGVmaW5pdGlvbiBvZiB0aGUgRi1kaXN0cmlidXRpb246CgokJApGPVxmcmFjeyhtLTEpIFNfWV4yIC8gXHNpZ21hX1leMiAvKG0tMSl9eyhuLTEpIFNfWF4yIC8gXHNpZ21hX1heMiAvKG4tMSl9PVxmcmFje1xzaWdtYV9YXjJ9e1xzaWdtYV9ZXjJ9IFxjZG90IFxmcmFje1NfWV4yfXtTX1heMn0gXHNpbSBGKG0tMSwgbi0xKQokJAoKVGhpcyBwaXZvdGFsIHF1YW50aXR5IGNvbnRhaW5zIHRoZSByYXRpbyAkXHNpZ21hXjJfWCAvIFxzaWdtYV4yX1kkLCBleGFjdGx5IHRoZSBwYXJhbWV0ZXIgd2Ugd2FudCB0byBlc3RpbWF0ZS4KCkEgJCgxLVxhbHBoYSkxMDBcJSQgQ0kgZm9yIHRoZSByYXRpbyBvZiB0d28gcG9wdWxhdGlvbiB2YXJpYW5jZXMgJFxzaWdtYV4yX1ggLyBcc2lnbWFeMl9ZJCBpczoKCiQkClxmcmFjezF9e0Zfe1xhbHBoYSAvIDJ9KG4tMSwgbS0xKX0gXGNkb3QgXGZyYWN7U19YXjJ9e1NfWV4yfSBcbGVxIFxmcmFje1xzaWdtYV9YXjJ9e1xzaWdtYV9ZXjJ9IFxsZXEgRl97XGFscGhhIC8gMn0obS0xLCBuLTEpIFxjZG90IFxmcmFje1NfWF4yfXtTX1leMn0KJCQKCmBgYHtyfQpjaV92YXJpYW5jZV9yYXRpbyA8LSBmdW5jdGlvbihkYXRhMSwgZGF0YTIsIGNvbmZfbGV2ZWwgPSAwLjk1KXsKICAKICAjIGJhc2ljIHN0YXRzCiAgbjEgPC0gbGVuZ3RoKGRhdGExKTsgbjIgPC0gbGVuZ3RoKGRhdGEyKQogIHMxX3NxIDwtIHZhcihkYXRhMSk7IHMyX3NxIDwtIHZhcihkYXRhMikKICAKICBkZjEgPC0gbjEgLSAxCiAgZGYyIDwtIG4yIC0gMQogIAogIGFscGhhIDwtIDEgLSBjb25mX2xldmVsCiAgCiAgIyBGIGNyaXRpY2FsIHZhbHVlcwogIEZfbG93ZXIgPC0gcWYoYWxwaGEvMiwgZGYxLCBkZjIpCiAgRl91cHBlciA8LSBxZigxIC0gYWxwaGEvMiwgZGYxLCBkZjIpCiAgCiAgIyByYXRpbyBvZiB2YXJpYW5jZXMKICByYXRpbyA8LSBzMV9zcSAvIHMyX3NxCiAgCiAgIyBjb25maWRlbmNlIGludGVydmFsCiAgbG93ZXIgPC0gcmF0aW8gLyBGX3VwcGVyCiAgdXBwZXIgPC0gcmF0aW8gLyBGX2xvd2VyCiAgCiAgcmV0dXJuKGxpc3QoCiAgICBuMSA9IG4xLAogICAgbjIgPSBuMiwKICAgIHZhcjEgPSBzMV9zcSwKICAgIHZhcjIgPSBzMl9zcSwKICAgIHJhdGlvID0gcmF0aW8sCiAgICBkZjEgPSBkZjEsCiAgICBkZjIgPSBkZjIsCiAgICBjb25mX2xldmVsID0gY29uZl9sZXZlbCwKICAgIEZfbG93ZXIgPSBGX2xvd2VyLAogICAgRl91cHBlciA9IEZfdXBwZXIsCiAgICBsb3dlciA9IGxvd2VyLAogICAgdXBwZXIgPSB1cHBlcgogICkpCn0KYGBgCgoKYGBge3J9CmNpX3ZhcmlhbmNlX3JhdGlvKHgxLCB4MiwgY29uZl9sZXZlbCA9IDAuOTUpCmBgYAoKYGBge3J9CiMgVmVyaWZ5IHJlc3VsdHMKdmFyLnRlc3QoeDEsIHgyLCBjb25mLmxldmVsID0gMC45NSlbYygiZXN0aW1hdGUiLCAiY29uZi5pbnQiKV0KYGBgCgpgYGB7cn0KewojIERlbnNpdHkgdmFsdWUKZDEgPC0gZGVuc2l0eSh4MSkKZDIgPC0gZGVuc2l0eSh4MikKCiMgRGF0YSByYW5nZQp4X3JhbmdlIDwtIHJhbmdlKGMoZDEkeCwgZDIkeCkpCnlfcmFuZ2UgPC0gcmFuZ2UoYyhkMSR5LCBkMiR5KSkKCiMgRW1wdHkgcGxvdApwbG90KGQxLAogICAgIGNvbCA9ICJibHVlIiwKICAgICBsd2QgPSAyLAogICAgIG1haW4gPSAiUHJleSBTaXplcyBEaXN0cmlidXRpb24iLAogICAgIHhsYWIgPSAiU2l6ZSAobW0pIiwKICAgICB4bGltID0geF9yYW5nZSwKICAgICB5bGltID0geV9yYW5nZSwKICAgICB0eXBlID0gIm4iKSAgCgojIPCflLUgRmlsbCBHcm91cCAxCnBvbHlnb24oZDEsCiAgICAgICAgY29sID0gcmdiKDAsIDAsIDEsIDAuMyksCiAgICAgICAgYm9yZGVyID0gTkEpCgojIPCflLQgRmlsbCBHcm91cCAyCnBvbHlnb24oZDIsCiAgICAgICAgY29sID0gcmdiKDEsIDAsIDAsIDAuMyksCiAgICAgICAgYm9yZGVyID0gTkEpCgojIExpbmUgY29sb3JzCmxpbmVzKGQxLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDIpCmxpbmVzKGQyLCBjb2wgPSAicmVkIiwgIGx3ZCA9IDIpCmxlZ2VuZCgidG9wcmlnaHQiLAogICAgICAgbGVnZW5kID0gYygiZGVpbm9waXMiLCAibWVubmV1cyIpLAogICAgICAgY29sID0gYygiYmx1ZSIsICJyZWQiKSwKICAgICAgIGx3ZCA9IDIsCiAgICAgICBidHkgPSAibiIpCn0KYGBgCgoK