CI for Mean
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))
}

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))
}

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)

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
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)
}

CI for Proportion
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
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
CI for Variance
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
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