setwd("/Users/joshuachang/desktop/ME330_Project")
# Steel
steel_1018CR_data = read.csv("M12_A_1018_CR_lab2.csv", header = TRUE)
steel_1045CR_data = read.csv("M12_C_1045_CR_lab2.csv", header = TRUE)
steel_1045NM_data = read.csv("M12_A_1045_NM_lab2.csv", header = TRUE)
steel_304_data = read.csv("M12_B_304_lab2.csv", header = TRUE)
#Aluminum
al_2024_data = read.csv("M12_A_2024_lab2.csv", header = TRUE)
al_7075_data = read.csv("M12_B_7075_lab2.csv", header = TRUE)
# Others
brass_data = read.csv("M12_A_Brass_lab2.csv", header = TRUE)
pmma_data = read.csv("M12_B_PMMA_lab2.csv", header = TRUE)
# lab 1 Compression Data
steel_1018_Compression_data = read.csv("M12_A_1018_lab1.csv", header = TRUE)
al_2024_Compression_data = read.csv("M12_A_7075_lab1.csv", header = TRUE)
# --- Steel 1018 Compression (Lab 1) ---
dis_1018_comp <- as.numeric(steel_1018_Compression_data$Displacement)
F_1018_comp <- as.numeric(steel_1018_Compression_data$Force)
eps_1018_comp <- as.numeric(steel_1018_Compression_data$Composite.strain)
gage_D_1018_comp <- 12.74 # [mm]
max_F_1018_comp <- 78.32 # [kN] — used only for reference
max_eps_1018_comp <- 0.482 # max strain — used only for reference
A_1018_comp <- pi/4 * gage_D_1018_comp^2 # cross-sectional area [mm^2]
sigma_eng_1018_comp <- F_1018_comp / A_1018_comp * 1000 # [MPa]
sigma_true_1018_comp <- sigma_eng_1018_comp * (1 + eps_1018_comp) # [MPa]
eps_true_1018_comp <- log(1 + eps_1018_comp)
ultimate_1018_comp <- max(sigma_eng_1018_comp, na.rm = TRUE) # [MPa]
fracture_idx_1018_comp <- length(sigma_eng_1018_comp) # last index
# --- Aluminum 2024 Compression (Lab 1) ---
dis_2024_comp <- as.numeric(al_2024_Compression_data$Displacement)
F_2024_comp <- as.numeric(al_2024_Compression_data$Force)
eps_2024_comp <- as.numeric(al_2024_Compression_data$Composite.strain)
gage_D_2024_comp <- 12.84
max_F_2024_comp <- max(F_2024_comp, na.rm = TRUE) # [kN]
max_eps_2024_comp <- max(eps_2024_comp, na.rm = TRUE)
A_2024_comp <- pi/4 * gage_D_2024_comp^2 # [mm^2]
sigma_eng_2024_comp <- F_2024_comp / A_2024_comp * 1000 # [MPa]
sigma_true_2024_comp <- sigma_eng_2024_comp * (1 + eps_2024_comp) # [MPa]
eps_true_2024_comp <- log(1 + eps_2024_comp)
ultimate_2024_comp <- max(sigma_eng_2024_comp, na.rm = TRUE) # [MPa]
fracture_idx_2024_comp <- length(sigma_eng_2024_comp) # assumed last point
# --- Steel 1018_CR ---
dis_1018 <- as.numeric(steel_1018CR_data$Displacement)
F_1018 <- as.numeric(steel_1018CR_data$Force)
eps_1018 <- as.numeric(steel_1018CR_data$Strain.1)
gage_D_1018 <- 7.26 # [mm]
max_F_1018 <- 28.15 # [kN]
max_eps_1018 <- 17.22
A_1018 <- pi/4 * gage_D_1018^2
sigma_eng_1018 <- F_1018 / A_1018 * 1000
sigma_true_1018 <- sigma_eng_1018 * (1 + eps_1018)
eps_true_1018 <- log(1 + eps_1018)
ultimate_1018 <- max(sigma_eng_1018, na.rm = TRUE)
fracture_1018 <- length(sigma_eng_1018)
# --- Steel 1045_CR ---
dis_1045_CR <- as.numeric(steel_1045CR_data$Displacement)
F_1045_CR <- as.numeric(steel_1045CR_data$Force)
eps_1045_CR <- as.numeric(steel_1045CR_data$Strain.1)
gage_D_1045_CR <- 7.18
max_F_1045_CR <- 41.15
max_eps_1045_CR <- 9.768
A_1045_CR <- pi/4 * gage_D_1045_CR^2
sigma_eng_1045_CR <- F_1045_CR / A_1045_CR * 1000
sigma_true_1045_CR <- sigma_eng_1045_CR * (1 + eps_1045_CR)
eps_true_1045_CR <- log(1 + eps_1045_CR)
ultimate_1045_CR <- max(sigma_eng_1045_CR, na.rm = TRUE)
fracture_1045_CR <- length(sigma_eng_1045_CR)
# --- Steel 1045_NM ---
dis_1045_NM <- as.numeric(steel_1045NM_data$Displacement)
F_1045_NM <- as.numeric(steel_1045NM_data$Force)
eps_1045_NM <- as.numeric(steel_1045NM_data$Strain.1)
gage_D_1045_NM <- 7.21
max_F_1045_NM <- 29
max_eps_1045_NM <- 28.01
A_1045_NM <- pi/4 * gage_D_1045_NM^2
sigma_eng_1045_NM <- F_1045_NM / A_1045_NM * 1000
sigma_true_1045_NM <- sigma_eng_1045_NM * (1 + eps_1045_NM)
eps_true_1045_NM <- log(1 + eps_1045_NM)
ultimate_1045_NM <- max(sigma_eng_1045_NM, na.rm = TRUE)
fracture_1045_NM <- length(sigma_eng_1045_NM)
# --- Steel 304 ---
dis_304 <- as.numeric(steel_304_data$Displacement)
F_304 <- as.numeric(steel_304_data$Force)
eps_304 <- as.numeric(steel_304_data$Strain.1)
gage_D_304 <- 7.18
max_F_304 <- 28.57
max_eps_304 <- 57.92
A_304 <- pi/4 * gage_D_304^2
sigma_eng_304 <- F_304 / A_304 * 1000
sigma_true_304 <- sigma_eng_304 * (1 + eps_304)
eps_true_304 <- log(1 + eps_304)
ultimate_304 <- max(sigma_eng_304, na.rm = TRUE)
fracture_304 <- length(sigma_eng_304)
# --- Aluminum 2024 ---
dis_2024 <- as.numeric(al_2024_data$Displacement)
F_2024 <- as.numeric(al_2024_data$Force)
eps_2024 <- as.numeric(al_2024_data$Strain.1)
gage_D_2024 <- 7.22
max_F_2024 <- 19.42
max_eps_2024 <- 20.1
A_2024 <- pi/4 * gage_D_2024^2
sigma_eng_2024 <- F_2024 / A_2024 * 1000
sigma_true_2024 <- sigma_eng_2024 * (1 + eps_2024)
eps_true_2024 <- log(1 + eps_2024)
ultimate_2024 <- max(sigma_eng_2024, na.rm = TRUE)
fracture_2024 <- length(sigma_eng_2024)
# --- Aluminum 7075 ---
dis_7075 <- as.numeric(al_7075_data$Displacement)
F_7075 <- as.numeric(al_7075_data$Force)
eps_7075 <- as.numeric(al_7075_data$Strain.1)
gage_D_7075 <- 6.11
max_F_7075 <- 22.6
max_eps_7075 <- 16.48
A_7075 <- pi/4 * gage_D_7075^2
sigma_eng_7075 <- F_7075 / A_7075 * 1000
sigma_true_7075 <- sigma_eng_7075 * (1 + eps_7075)
eps_true_7075 <- log(1 + eps_7075)
ultimate_7075 <- max(sigma_eng_7075, na.rm = TRUE)
fracture_7075 <- length(sigma_eng_7075)
# --- Brass ---
dis_brass <- as.numeric(brass_data$Displacement)
F_brass <- as.numeric(brass_data$Force)
eps_brass <- as.numeric(brass_data$Strain.1)
gage_D_brass <- 7.26
max_F_brass <- 14.47
max_eps_brass <- 33.82
A_brass <- pi/4 * gage_D_brass^2
sigma_eng_brass <- F_brass / A_brass * 1000
sigma_true_brass <- sigma_eng_brass * (1 + eps_brass)
eps_true_brass <- log(1 + eps_brass)
ultimate_brass <- max(sigma_eng_brass, na.rm = TRUE)
fracture_brass <- length(sigma_eng_brass)
# --- PMMA ---
dis_pmma <- as.numeric(pmma_data$Displacement)
F_pmma <- as.numeric(pmma_data$Force)
eps_pmma <- as.numeric(pmma_data$Strain.1)
gage_D_pmma <- 7
max_F_pmma <- 3.471
max_eps_pmma <- 3.397
A_pmma <- pi/4 * gage_D_pmma^2
sigma_eng_pmma <- F_pmma / A_pmma * 1000
sigma_true_pmma <- sigma_eng_pmma * (1 + eps_pmma)
eps_true_pmma <- log(1 + eps_pmma)
ultimate_pmma <- max(sigma_eng_pmma, na.rm = TRUE)
fracture_pmma <- length(sigma_eng_pmma)
colors <- c("firebrick", "darkorange", "steelblue", "black",
"green4", "purple", "goldenrod", "deeppink")
labels <- c("1018 Steel", "1045 Steel (CR)", "1045 Steel (NM)", "304 Steel",
"2024 Aluminum", "7075 Aluminum", "Brass", "PMMA")
# Global x/y limits
xmax <- max(1)
ymax <- max(1000)
# Plot base curve
par(mfrow = c(1, 1))
plot(eps_1018, sigma_eng_1018, type = "l", col = colors[1], lwd = 2,
xlim = c(0, xmax), ylim = c(0, ymax),
xlab = "Engineering Strain (-)", ylab = "Engineering Stress (MPa)",
main = "Engineering Stress-Strain Curves for All Materials")
# Overlay all other materials
lines(eps_1045_CR, sigma_eng_1045_CR, col = colors[2], lwd = 2)
lines(eps_1045_NM, sigma_eng_1045_NM, col = colors[3], lwd = 2)
lines(eps_304, sigma_eng_304, col = colors[4], lwd = 2)
lines(eps_2024, sigma_eng_2024, col = colors[5], lwd = 2)
lines(eps_7075, sigma_eng_7075, col = colors[6], lwd = 2)
lines(eps_brass, sigma_eng_brass, col = colors[7], lwd = 2)
lines(eps_pmma, sigma_eng_pmma, col = colors[8], lwd = 2)
# Add legend
legend("topright", legend = labels, col = colors, lwd = 2, bty = "n")
grid()

Engineering Stress-Strain vs. True Stress-Strain
par(mfrow = c(1, 2))
### 1018 Steel
plot(eps_1018, sigma_eng_1018, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "1018 Steel: Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_1018, sigma_eng_1018, col = "royalblue", pch = 16)
points(eps_true_1018, sigma_true_1018, col = "darkorange", pch = 16)
legend("bottomright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")
### 1045 Steel (Cold Rolled)
plot(eps_1045_CR, sigma_eng_1045_CR, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "1045 Steel (CR): Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_1045_CR, sigma_eng_1045_CR, col = "royalblue", pch = 16)
points(eps_true_1045_CR, sigma_true_1045_CR, col = "darkorange", pch = 16)
legend("bottomright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")

### 1045 Steel (Normalized)
plot(eps_1045_NM, sigma_eng_1045_NM, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "1045 Steel (NM): Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_1045_NM, sigma_eng_1045_NM, col = "royalblue", pch = 16)
points(eps_true_1045_NM, sigma_true_1045_NM, col = "darkorange", pch = 16)
legend("bottomright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")
### 304 Stainless Steel
plot(eps_304, sigma_eng_304, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "304 Stainless Steel: Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_304, sigma_eng_304, col = "royalblue", pch = 16)
points(eps_true_304, sigma_true_304, col = "darkorange", pch = 16)
legend("bottomright",
legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"),
pch = 16, bty = "n")

### 2024 Aluminum
plot(eps_2024, sigma_eng_2024, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "2024 Aluminum: Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_2024, sigma_eng_2024, col = "royalblue", pch = 16)
points(eps_true_2024, sigma_true_2024, col = "darkorange", pch = 16)
legend("bottomright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")
### 7075 Aluminum
plot(eps_7075, sigma_eng_7075, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "7075 Aluminum: Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_7075, sigma_eng_7075, col = "royalblue", pch = 16)
points(eps_true_7075, sigma_true_7075, col = "darkorange", pch = 16)
legend("bottomright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")

### Brass (Annealed)
plot(eps_brass, sigma_eng_brass, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "Annealed Brass: Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_brass, sigma_eng_brass, col = "royalblue", pch = 16)
points(eps_true_brass, sigma_true_brass, col = "darkorange", pch = 16)
legend("topright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")
### PMMA
plot(eps_pmma, sigma_eng_pmma, type = "n",
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "PMMA: Engineering vs True",
ylim = c(0, 1200))
grid()
points(eps_pmma, sigma_eng_pmma, col = "royalblue", pch = 16)
points(eps_true_pmma, sigma_true_pmma, col = "darkorange", pch = 16)
legend("topright", legend = c("Engineering σ–ε", "True σ–ε"),
col = c("royalblue", "darkorange"), pch = 16, bty = "n")

For the yield strain values for each materials below, I have eyeball
the approximate value, find the young’s modulus, and the 0.2%.
Update/adjust the yield strain based on the alignment of each graph
— 1018 Steel —
eps_yield_1018 <- 0.0026
# Fit linear elastic region up to yield (0 intercept)
fit_1018 <- lm(sigma_eng_1018[eps_1018 <= eps_yield_1018] ~ 0 + eps_1018[eps_1018 <= eps_yield_1018])
E_1018 <- coef(fit_1018)[1]
# Calculate 0.2% offset line: σ = E(ε − 0.002)
sigma_offset_1018 <- E_1018 * (eps_1018 - 0.002)
diff_1018 <- sigma_eng_1018 - sigma_offset_1018
i_1018 <- which(diff(sign(diff_1018)) != 0)[1]
yield_strain_1018 <- eps_1018[i_1018]
yield_stress_1018 <- sigma_eng_1018[i_1018]
# --- Plot ---
plot(eps_1018, sigma_eng_1018,
type = "l", col = "steelblue", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)",
main = "1018 Steel", ylim = c(0, 1200))
grid()
points(eps_1018, sigma_eng_1018, col = "steelblue", pch = 16)
abline(a = 0, b = E_1018, col = "purple", lwd = 2, lty = 2) # Original elastic line
abline(a = -E_1018 * 0.002, b = E_1018, col = "darkgreen", lwd = 2, lty = 3) # 0.2% offset line
points(yield_strain_1018, yield_stress_1018, pch = 19, col = "red", cex = 1.5)
text(x = yield_strain_1018,
y = yield_stress_1018,
labels = paste0(round(yield_stress_1018, 1), " MPa"),
pos = 3, col = "red", cex = 1.2)

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_1018, 5), "\n")
0.2% Offset Yield Strain = 0.00519
cat("0.2% Offset Yield Stress =", round(yield_stress_1018, 2), "MPa\n")
0.2% Offset Yield Stress = 660.2 MPa
— 1045 Steel (Cold Rolled) —
eps_yield_1045_CR <- 0.0033
fit_1045_CR <- lm(sigma_eng_1045_CR[eps_1045_CR <= eps_yield_1045_CR] ~ 0 + eps_1045_CR[eps_1045_CR <= eps_yield_1045_CR])
E_1045_CR <- coef(fit_1045_CR)[1]
sigma_offset_1045_CR <- E_1045_CR * (eps_1045_CR - 0.002)
i_1045_CR <- which(diff(sign(sigma_eng_1045_CR - sigma_offset_1045_CR)) != 0)[1]
yield_strain_1045_CR <- eps_1045_CR[i_1045_CR]
yield_stress_1045_CR <- sigma_eng_1045_CR[i_1045_CR]
plot(eps_1045_CR, sigma_eng_1045_CR, type = "l", col = "firebrick", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "1045 Steel (CR)", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_1045_CR, col = "purple", lwd = 2, lty = 2)
abline(a = -E_1045_CR * 0.002, b = E_1045_CR, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_1045_CR, yield_stress_1045_CR, col = "red", pch = 19, cex = 1.5)
text(yield_strain_1045_CR, yield_stress_1045_CR, labels = paste0(round(yield_stress_1045_CR, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_1045_CR, 5), "\n")
0.2% Offset Yield Strain = 0.0046
cat("0.2% Offset Yield Stress =", round(yield_stress_1045_CR, 2), "MPa\n")
0.2% Offset Yield Stress = 964.95 MPa
—1045 Steel (Normalized) —
eps_yield_1045_NM <- 0.0035
fit_1045_NM <- lm(sigma_eng_1045_NM[eps_1045_NM <= eps_yield_1045_NM] ~ 0 + eps_1045_NM[eps_1045_NM <= eps_yield_1045_NM])
E_1045_NM <- coef(fit_1045_NM)[1]
sigma_offset_1045_NM <- E_1045_NM * (eps_1045_NM - 0.002)
i_1045_NM <- which(diff(sign(sigma_eng_1045_NM - sigma_offset_1045_NM)) != 0)[1]
yield_strain_1045_NM <- eps_1045_NM[i_1045_NM]
yield_stress_1045_NM <- sigma_eng_1045_NM[i_1045_NM]
plot(eps_1045_NM, sigma_eng_1045_NM, type = "l", col = "indianred", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "1045 Steel (NM)", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_1045_NM, col = "purple", lwd = 2, lty = 2)
abline(a = -E_1045_NM * 0.002, b = E_1045_NM, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_1045_NM, yield_stress_1045_NM, col = "red", pch = 19, cex = 1.5)
text(yield_strain_1045_NM, yield_stress_1045_NM, labels = paste0(round(yield_stress_1045_NM, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_1045_NM, 5), "\n")
0.2% Offset Yield Strain = 0.00354
cat("0.2% Offset Yield Stress =", round(yield_stress_1045_NM, 2), "MPa\n")
0.2% Offset Yield Stress = 462.92 MPa
— 304 Stainless Steel —
eps_yield_304 <- 0.0030
fit_304 <- lm(sigma_eng_304[eps_304 <= eps_yield_304] ~ 0 + eps_304[eps_304 <= eps_yield_304])
E_304 <- coef(fit_304)[1]
sigma_offset_304 <- E_304 * (eps_304 - 0.002)
i_304 <- which(diff(sign(sigma_eng_304 - sigma_offset_304)) != 0)[1]
yield_strain_304 <- eps_304[i_304]
yield_stress_304 <- sigma_eng_304[i_304]
plot(eps_304, sigma_eng_304, type = "l", col = "forestgreen", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "304 Stainless Steel", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_304, col = "purple", lwd = 2, lty = 2)
abline(a = -E_304 * 0.002, b = E_304, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_304, yield_stress_304, col = "red", pch = 19, cex = 1.5)
text(yield_strain_304, yield_stress_304, labels = paste0(round(yield_stress_304, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_304, 5), "\n")
0.2% Offset Yield Strain = 0.00537
cat("0.2% Offset Yield Stress =", round(yield_stress_304, 2), "MPa\n")
0.2% Offset Yield Stress = 473.95 MPa
—2024 Aluminum —
eps_yield_2024 <- 0.005
fit_2024 <- lm(sigma_eng_2024[eps_2024 <= eps_yield_2024] ~ 0 + eps_2024[eps_2024 <= eps_yield_2024])
E_2024 <- coef(fit_2024)[1]
sigma_offset_2024 <- E_2024 * (eps_2024 - 0.002)
i_2024 <- which(diff(sign(sigma_eng_2024 - sigma_offset_2024)) != 0)[1]
yield_strain_2024 <- eps_2024[i_2024]
yield_stress_2024 <- sigma_eng_2024[i_2024]
plot(eps_2024, sigma_eng_2024, type = "l", col = "dodgerblue3", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "2024 Aluminum", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_2024, col = "purple", lwd = 2, lty = 2)
abline(a = -E_2024 * 0.002, b = E_2024, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_2024, yield_stress_2024, col = "red", pch = 19, cex = 1.5)
text(yield_strain_2024, yield_stress_2024, labels = paste0(round(yield_stress_2024, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_2024, 5), "\n")
0.2% Offset Yield Strain = 0.00638
cat("0.2% Offset Yield Stress =", round(yield_stress_2024, 2), "MPa\n")
0.2% Offset Yield Stress = 362.22 MPa
— 7075 Aluminum —
eps_yield_7075 <- 0.004
fit_7075 <- lm(sigma_eng_7075[eps_7075 <= eps_yield_7075] ~ 0 + eps_7075[eps_7075 <= eps_yield_7075])
E_7075 <- coef(fit_7075)[1]
sigma_offset_7075 <- E_7075 * (eps_7075 - 0.002)
i_7075 <- which(diff(sign(sigma_eng_7075 - sigma_offset_7075)) != 0)[1]
yield_strain_7075 <- eps_7075[i_7075]
yield_stress_7075 <- sigma_eng_7075[i_7075]
plot(eps_7075, sigma_eng_7075, type = "l", col = "darkorange", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "7075 Aluminum", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_7075, col = "purple", lwd = 2, lty = 2)
abline(a = -E_7075 * 0.002, b = E_7075, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_7075, yield_stress_7075, col = "red", pch = 19, cex = 1.5)
text(yield_strain_7075, yield_stress_7075, labels = paste0(round(yield_stress_7075, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_7075, 5), "\n")
0.2% Offset Yield Strain = 0.00885
cat("0.2% Offset Yield Stress =", round(yield_stress_7075, 2), "MPa\n")
0.2% Offset Yield Stress = 694.39 MPa
—Annealed Brass—
eps_yield_brass <- 0.007
fit_brass <- lm(sigma_eng_brass[eps_brass <= eps_yield_brass] ~ 0 + eps_brass[eps_brass <= eps_yield_brass])
E_brass <- coef(fit_brass)[1]
sigma_offset_brass <- E_brass * (eps_brass - 0.002)
i_brass <- which(diff(sign(sigma_eng_brass - sigma_offset_brass)) != 0)[1]
yield_strain_brass <- eps_brass[i_brass]
yield_stress_brass <- sigma_eng_brass[i_brass]
plot(eps_brass, sigma_eng_brass, type = "l", col = "goldenrod", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "Annealed Brass", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_brass, col = "purple", lwd = 2, lty = 2)
abline(a = -E_brass * 0.002, b = E_brass, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_brass, yield_stress_brass, col = "red", pch = 19, cex = 1.5)
text(yield_strain_brass, yield_stress_brass, labels = paste0(round(yield_stress_brass, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_brass, 5), "\n")
0.2% Offset Yield Strain = 0.0063
cat("0.2% Offset Yield Stress =", round(yield_stress_brass, 2), "MPa\n")
0.2% Offset Yield Stress = 238.93 MPa
—PMMA—
eps_yield_pmma <- 0.007
fit_pmma <- lm(sigma_eng_pmma[eps_pmma <= eps_yield_pmma] ~ 0 + eps_pmma[eps_pmma <= eps_yield_pmma])
E_pmma <- coef(fit_pmma)[1]
sigma_offset_pmma <- E_pmma * (eps_pmma - 0.002)
i_pmma <- which(diff(sign(sigma_eng_pmma - sigma_offset_pmma)) != 0)[1]
yield_strain_pmma <- eps_pmma[i_pmma]
yield_stress_pmma <- sigma_eng_pmma[i_pmma]
plot(eps_pmma, sigma_eng_pmma, type = "l", col = "black", lwd = 2,
xlab = "Strain (-)", ylab = "Stress (MPa)", main = "PMMA", ylim = c(0, 1200))
grid()
abline(a = 0, b = E_pmma, col = "purple", lwd = 2, lty = 2)
abline(a = -E_pmma * 0.002, b = E_pmma, col = "darkgreen", lwd = 2, lty = 3)
points(yield_strain_pmma, yield_stress_pmma, col = "red", pch = 19, cex = 1.5)
text(yield_strain_pmma, yield_stress_pmma, labels = paste0(round(yield_stress_pmma, 1), " MPa"), pos = 3, col = "red")

cat("Elastic Modulus (E) =", round(E_1018, 2), "MPa\n")
Elastic Modulus (E) = 202558.9 MPa
cat("0.2% Offset Yield Strain =", round(yield_strain_pmma, 5), "\n")
0.2% Offset Yield Strain = 0.01378
cat("0.2% Offset Yield Stress =", round(yield_stress_pmma, 2), "MPa\n")
0.2% Offset Yield Stress = 51.94 MPa
Elastic Region (Up to Yield Strain)
# Truncate to each material's elastic region (up to yield)
truncate_to_yield <- function(eps, sigma, strain_limit) {
idx <- which(eps <= strain_limit)
return(list(eps = eps[idx], sigma = sigma[idx]))
}
# Truncated curves
s1018 <- truncate_to_yield(eps_1018, sigma_eng_1018, eps_yield_1018)
s1045_CR <- truncate_to_yield(eps_1045_CR, sigma_eng_1045_CR, eps_yield_1045_CR)
s1045_NM <- truncate_to_yield(eps_1045_NM, sigma_eng_1045_NM, eps_yield_1045_NM)
s304 <- truncate_to_yield(eps_304, sigma_eng_304, eps_yield_304)
s2024 <- truncate_to_yield(eps_2024, sigma_eng_2024, eps_yield_2024)
s7075 <- truncate_to_yield(eps_7075, sigma_eng_7075, eps_yield_7075)
sbrass <- truncate_to_yield(eps_brass, sigma_eng_brass, eps_yield_brass)
spmma <- truncate_to_yield(eps_pmma, sigma_eng_pmma, eps_yield_pmma)
# Plot
plot(0, 0, type = "n", xlim = c(0, 0.015), ylim = c(0, 1200),
xlab = "Strain (mm/mm)", ylab = "Stress (MPa)",
main = "Elastic Region (Up to Yield Strain)")
grid()
# Add lines
lines(s1018$eps, s1018$sigma, col = "steelblue", lwd = 3)
lines(s1045_CR$eps,s1045_CR$sigma, col = "gray40", lwd = 3)
lines(s1045_NM$eps,s1045_NM$sigma, col = "darkorange", lwd = 3)
lines(s304$eps, s304$sigma, col = "gold", lwd = 3)
lines(s2024$eps, s2024$sigma, col = "skyblue", lwd = 3)
lines(s7075$eps, s7075$sigma, col = "dodgerblue", lwd = 3)
lines(sbrass$eps, sbrass$sigma, col = "chocolate", lwd = 3)
lines(spmma$eps, spmma$sigma, col = "forestgreen", lwd = 3)
# Legend
legend("bottomright",
legend = c("1018 CR", "1045 CR", "1045 NM", "304 SS",
"2024 Aluminum", "7075 Aluminum", "Brass", "PMMA"),
col = c("steelblue", "gray40", "darkorange", "gold",
"skyblue", "dodgerblue", "chocolate", "forestgreen"),
lwd = 3, bty = "n", cex = 0.9)

1018CR Steel: Tension vs Compression (Engineering
Stress-Strain)
plot(abs(eps_1018), abs(sigma_eng_1018), type = "l", lwd = 2, col = "blue",
xlab = "Strain (abs)", ylab = "Engineering Stress [MPa]",
main = "1018 Cold-Rolled Steel: Tension vs Compression")
lines(abs(eps_1018_comp), abs(sigma_eng_1018_comp), col = "red", lwd = 2, lty = 2)
legend("topleft", legend = c("Tension", "Compression"),
col = c("blue", "red"), lty = c(1, 2), lwd = 2)
grid()

2024 Aluminum: Tension vs Compression (Engineering
Stress-Strain)
plot(abs(eps_2024), abs(sigma_eng_2024), type = "l", lwd = 2, col = "blue",
xlab = "Strain (abs)", ylab = "Engineering Stress [MPa]",
main = "2024 Aluminum Alloy: Tension vs Compression")
lines(abs(eps_2024_comp), abs(sigma_eng_2024_comp), col = "red", lwd = 2, lty = 2)
legend("topleft", legend = c("Tension", "Compression"),
col = c("blue", "red"), lty = c(1, 2), lwd = 2)
grid()

Table Report Information
cat("Elastic Properties Summary (E in GPa, Stress in MPa):\n\n")
Elastic Properties Summary (E in GPa, Stress in MPa):
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"1018 Steel CR", E_1018 / 1000, yield_strain_1018, yield_stress_1018, ultimate_1018))
1018 Steel CR | E = 202.56 | Yield Strain = 0.00519 | Yield Stress = 660.20 | Ultimate Strength = 680.01
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"1045 Steel CR", E_1045_CR / 1000, yield_strain_1045_CR, yield_stress_1045_CR, ultimate_1045_CR))
1045 Steel CR | E = 354.83 | Yield Strain = 0.00460 | Yield Stress = 964.95 | Ultimate Strength = 1016.32
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"1045 Steel NM", E_1045_NM / 1000, yield_strain_1045_NM, yield_stress_1045_NM, ultimate_1045_NM))
1045 Steel NM | E = 189.27 | Yield Strain = 0.00354 | Yield Stress = 462.92 | Ultimate Strength = 710.29
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"304 SS", E_304 / 1000, yield_strain_304, yield_stress_304, ultimate_304))
304 SS | E = 136.35 | Yield Strain = 0.00537 | Yield Stress = 473.95 | Ultimate Strength = 705.62
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"2024 Aluminum", E_2024 / 1000, yield_strain_2024, yield_stress_2024, ultimate_2024))
2024 Aluminum | E = 75.30 | Yield Strain = 0.00638 | Yield Stress = 362.22 | Ultimate Strength = 474.33
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"7075 Aluminum", E_7075 / 1000, yield_strain_7075, yield_stress_7075, ultimate_7075))
7075 Aluminum | E = 97.05 | Yield Strain = 0.00885 | Yield Stress = 694.39 | Ultimate Strength = 770.79
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"Annealed Brass", E_brass / 1000, yield_strain_brass, yield_stress_brass, ultimate_brass))
Annealed Brass | E = 52.82 | Yield Strain = 0.00630 | Yield Stress = 238.93 | Ultimate Strength = 349.55
cat(sprintf("%-18s | E = %9.2f | Yield Strain = %.5f | Yield Stress = %7.2f | Ultimate Strength = %7.2f\n",
"PMMA", E_pmma / 1000, yield_strain_pmma, yield_stress_pmma, ultimate_pmma))
PMMA | E = 4.36 | Yield Strain = 0.01378 | Yield Stress = 51.94 | Ultimate Strength = 90.19
Helper Function: Compute K, n from true stress/true plastic strain
(Ramberg–Osgood)
fit_powerlaw = function(eps_eng, eps_true, sigma_true, E_MPa,
yield_strain, sigma_eng,
min_ep = 1e-5) {
# Index Interval from yield to UTS (pre-necking)
i_start <- which(eps_eng >= yield_strain)[1]
i_end <- which.max(sigma_eng)
# i_start: first index where engineering strain reaches yield → beginning of plastic deformation
# i_end: where engineering stress reaches its maximum → necking usually starts here
## pre-caution check
if (is.na(i_start)) i_start <- 1
if (is.na(i_end) || i_end < i_start) i_end <- length(eps_true)
# stress hardening phase index range
idx <- i_start:i_end
# True plastic strain{strain-hardening interval}
eps_p_true <- eps_true[idx] - sigma_true[idx] / E_MPa
sigma_t <- sigma_true[idx]
# pre-caution check, only keep valid and positive plastic strain
keep <- is.finite(eps_p_true) & is.finite(sigma_t) &
eps_p_true > min_ep & sigma_t > 0
eps_p_true <- eps_p_true[keep]
sigma_t <- sigma_t[keep]
# Linear fit in log-log space: log σ = log K + n log ε_p
fit <- lm(log(sigma_t) ~ log(eps_p_true))
n <- unname(coef(fit)[2])
K <- unname(exp(coef(fit)[1])) # MPa
list(K = K, n = n,
idx_range = c(i_start, i_end),
fit = fit,
eps_p_true = eps_p_true, sigma_t = sigma_t)
}
## ---- 7075 Aluminum ----
res_7075 <- fit_powerlaw(
eps_eng = eps_7075,
eps_true = eps_true_7075,
sigma_true = sigma_true_7075,
E_MPa = E_7075, # E in MPa
yield_strain = yield_strain_7075,
sigma_eng = sigma_eng_7075
)
## ---- Annealed Brass ----
res_brass <- fit_powerlaw(
eps_eng = eps_brass,
eps_true = eps_true_brass,
sigma_true = sigma_true_brass,
E_MPa = E_brass, # E in MPa
yield_strain = yield_strain_brass,
sigma_eng = sigma_eng_brass
)
## --- Plot: Annealed Brass log–log fit ---
# Scatter plot of log(true plastic strain) vs. log(true stress)
# This shows the experimental data in log-log space
plot(log(res_brass$eps_p_true), log(res_brass$sigma_t),
xlab = "log(True plastic strain)",
ylab = "log(True stress) [MPa]",
main = "Annealed Brass: log–log fit",
pch = 16)
# Add dashed line: linear regression fit to the log-log data
# This line represents log(σ_t) = log(K) + n * log(ε_p)
# The slope = n (strain hardening exponent), intercept = log(K)
abline(res_brass$fit, lwd = 2, lty = 2)

## --- Plot: 7075 Aluminum log–log fit ---
plot(log(res_7075$eps_p_true), log(res_7075$sigma_t),
xlab = "log(True plastic strain)",
ylab = "log(True stress) [MPa]",
main = "7075 Aluminum: log–log fit",
pch = 16)
abline(res_7075$fit, lwd = 2, lty = 2)

## Data Report
cat("\nRamberg–Osgood parameters (σ_true = K * ε_p_true^n):\n")
Ramberg–Osgood parameters (σ_true = K * ε_p_true^n):
cat(sprintf(" Annealed Brass : K = %.2f MPa, n = %.4f\n", res_brass$K, res_brass$n))
Annealed Brass : K = 595.62 MPa, n = 0.2890
cat(sprintf(" 7075 Aluminum : K = %.2f MPa, n = %.4f\n", res_7075$K, res_7075$n))
7075 Aluminum : K = 946.06 MPa, n = 0.0535
LS0tCnRpdGxlOiAiTUUzMzAobGFiMikiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KYGBge3J9CnNldHdkKCIvVXNlcnMvam9zaHVhY2hhbmcvZGVza3RvcC9NRTMzMF9Qcm9qZWN0IikKYGBgCgoKYGBge3IsIHdhcm5pbmc9RkFMU0V9CiMgU3RlZWwKc3RlZWxfMTAxOENSX2RhdGEgPSByZWFkLmNzdigiTTEyX0FfMTAxOF9DUl9sYWIyLmNzdiIsIGhlYWRlciA9IFRSVUUpCnN0ZWVsXzEwNDVDUl9kYXRhID0gcmVhZC5jc3YoIk0xMl9DXzEwNDVfQ1JfbGFiMi5jc3YiLCBoZWFkZXIgPSBUUlVFKQpzdGVlbF8xMDQ1Tk1fZGF0YSA9IHJlYWQuY3N2KCJNMTJfQV8xMDQ1X05NX2xhYjIuY3N2IiwgaGVhZGVyID0gVFJVRSkKc3RlZWxfMzA0X2RhdGEgPSByZWFkLmNzdigiTTEyX0JfMzA0X2xhYjIuY3N2IiwgaGVhZGVyID0gVFJVRSkKCiNBbHVtaW51bSAKYWxfMjAyNF9kYXRhID0gcmVhZC5jc3YoIk0xMl9BXzIwMjRfbGFiMi5jc3YiLCBoZWFkZXIgPSBUUlVFKQphbF83MDc1X2RhdGEgPSByZWFkLmNzdigiTTEyX0JfNzA3NV9sYWIyLmNzdiIsIGhlYWRlciA9IFRSVUUpCgojIE90aGVycwpicmFzc19kYXRhID0gcmVhZC5jc3YoIk0xMl9BX0JyYXNzX2xhYjIuY3N2IiwgaGVhZGVyID0gVFJVRSkKcG1tYV9kYXRhID0gcmVhZC5jc3YoIk0xMl9CX1BNTUFfbGFiMi5jc3YiLCBoZWFkZXIgPSBUUlVFKQoKIyBsYWIgMSBDb21wcmVzc2lvbiBEYXRhCnN0ZWVsXzEwMThfQ29tcHJlc3Npb25fZGF0YSA9IHJlYWQuY3N2KCJNMTJfQV8xMDE4X2xhYjEuY3N2IiwgaGVhZGVyID0gVFJVRSkKYWxfMjAyNF9Db21wcmVzc2lvbl9kYXRhID0gcmVhZC5jc3YoIk0xMl9BXzcwNzVfbGFiMS5jc3YiLCBoZWFkZXIgPSBUUlVFKQpgYGAKCgpgYGB7cix3YXJuaW5nPUZBTFNFfQojIC0tLSBTdGVlbCAxMDE4IENvbXByZXNzaW9uIChMYWIgMSkgLS0tCmRpc18xMDE4X2NvbXAgIDwtIGFzLm51bWVyaWMoc3RlZWxfMTAxOF9Db21wcmVzc2lvbl9kYXRhJERpc3BsYWNlbWVudCkKRl8xMDE4X2NvbXAgICAgPC0gYXMubnVtZXJpYyhzdGVlbF8xMDE4X0NvbXByZXNzaW9uX2RhdGEkRm9yY2UpCmVwc18xMDE4X2NvbXAgIDwtIGFzLm51bWVyaWMoc3RlZWxfMTAxOF9Db21wcmVzc2lvbl9kYXRhJENvbXBvc2l0ZS5zdHJhaW4pCmdhZ2VfRF8xMDE4X2NvbXAgICA8LSAxMi43NCAgICAgIyBbbW1dCm1heF9GXzEwMThfY29tcCAgICA8LSA3OC4zMiAgICAjIFtrTl0g4oCUIHVzZWQgb25seSBmb3IgcmVmZXJlbmNlCm1heF9lcHNfMTAxOF9jb21wICA8LSAwLjQ4MiAgICAjIG1heCBzdHJhaW4g4oCUIHVzZWQgb25seSBmb3IgcmVmZXJlbmNlCkFfMTAxOF9jb21wICAgICAgICA8LSBwaS80ICogZ2FnZV9EXzEwMThfY29tcF4yICAjIGNyb3NzLXNlY3Rpb25hbCBhcmVhIFttbV4yXQpzaWdtYV9lbmdfMTAxOF9jb21wICA8LSBGXzEwMThfY29tcCAvIEFfMTAxOF9jb21wICogMTAwMCAgICAgICAgICAgICAgICMgW01QYV0Kc2lnbWFfdHJ1ZV8xMDE4X2NvbXAgPC0gc2lnbWFfZW5nXzEwMThfY29tcCAqICgxICsgZXBzXzEwMThfY29tcCkgICAgICMgW01QYV0KZXBzX3RydWVfMTAxOF9jb21wICAgPC0gbG9nKDEgKyBlcHNfMTAxOF9jb21wKQp1bHRpbWF0ZV8xMDE4X2NvbXAgPC0gbWF4KHNpZ21hX2VuZ18xMDE4X2NvbXAsIG5hLnJtID0gVFJVRSkgICAgICAgICAjIFtNUGFdCmZyYWN0dXJlX2lkeF8xMDE4X2NvbXAgPC0gbGVuZ3RoKHNpZ21hX2VuZ18xMDE4X2NvbXApICMgbGFzdCBpbmRleAoKCiMgLS0tIEFsdW1pbnVtIDIwMjQgQ29tcHJlc3Npb24gKExhYiAxKSAtLS0KZGlzXzIwMjRfY29tcCAgPC0gYXMubnVtZXJpYyhhbF8yMDI0X0NvbXByZXNzaW9uX2RhdGEkRGlzcGxhY2VtZW50KQpGXzIwMjRfY29tcCAgICA8LSBhcy5udW1lcmljKGFsXzIwMjRfQ29tcHJlc3Npb25fZGF0YSRGb3JjZSkKZXBzXzIwMjRfY29tcCAgPC0gYXMubnVtZXJpYyhhbF8yMDI0X0NvbXByZXNzaW9uX2RhdGEkQ29tcG9zaXRlLnN0cmFpbikKZ2FnZV9EXzIwMjRfY29tcCAgIDwtIDEyLjg0Cm1heF9GXzIwMjRfY29tcCAgICA8LSBtYXgoRl8yMDI0X2NvbXAsIG5hLnJtID0gVFJVRSkgICAgIyBba05dIAptYXhfZXBzXzIwMjRfY29tcCAgPC0gbWF4KGVwc18yMDI0X2NvbXAsIG5hLnJtID0gVFJVRSkgCkFfMjAyNF9jb21wICAgICAgICA8LSBwaS80ICogZ2FnZV9EXzIwMjRfY29tcF4yICAgICAgICAgIyBbbW1eMl0Kc2lnbWFfZW5nXzIwMjRfY29tcCAgPC0gRl8yMDI0X2NvbXAgLyBBXzIwMjRfY29tcCAqIDEwMDAgICAgICAgICAgICAgICAjIFtNUGFdCnNpZ21hX3RydWVfMjAyNF9jb21wIDwtIHNpZ21hX2VuZ18yMDI0X2NvbXAgKiAoMSArIGVwc18yMDI0X2NvbXApICAgICAjIFtNUGFdCmVwc190cnVlXzIwMjRfY29tcCAgIDwtIGxvZygxICsgZXBzXzIwMjRfY29tcCkKdWx0aW1hdGVfMjAyNF9jb21wICAgICAgIDwtIG1heChzaWdtYV9lbmdfMjAyNF9jb21wLCBuYS5ybSA9IFRSVUUpICAgICAjIFtNUGFdCmZyYWN0dXJlX2lkeF8yMDI0X2NvbXAgICA8LSBsZW5ndGgoc2lnbWFfZW5nXzIwMjRfY29tcCkgICAgICAgICAgICAgICAgIyBhc3N1bWVkIGxhc3QgcG9pbnQKYGBgCgpgYGB7cix3YXJuaW5nPUZBTFNFfQojIC0tLSBTdGVlbCAxMDE4X0NSIC0tLQpkaXNfMTAxOCA8LSBhcy5udW1lcmljKHN0ZWVsXzEwMThDUl9kYXRhJERpc3BsYWNlbWVudCkKRl8xMDE4ICAgPC0gYXMubnVtZXJpYyhzdGVlbF8xMDE4Q1JfZGF0YSRGb3JjZSkKZXBzXzEwMTggPC0gYXMubnVtZXJpYyhzdGVlbF8xMDE4Q1JfZGF0YSRTdHJhaW4uMSkKZ2FnZV9EXzEwMTggPC0gNy4yNiAgIyBbbW1dCm1heF9GXzEwMTggIDwtIDI4LjE1ICMgW2tOXQptYXhfZXBzXzEwMTggPC0gMTcuMjIKQV8xMDE4IDwtIHBpLzQgKiBnYWdlX0RfMTAxOF4yCnNpZ21hX2VuZ18xMDE4IDwtIEZfMTAxOCAvIEFfMTAxOCAqIDEwMDAKc2lnbWFfdHJ1ZV8xMDE4IDwtIHNpZ21hX2VuZ18xMDE4ICogKDEgKyBlcHNfMTAxOCkKZXBzX3RydWVfMTAxOCA8LSBsb2coMSArIGVwc18xMDE4KQp1bHRpbWF0ZV8xMDE4IDwtIG1heChzaWdtYV9lbmdfMTAxOCwgbmEucm0gPSBUUlVFKQpmcmFjdHVyZV8xMDE4IDwtIGxlbmd0aChzaWdtYV9lbmdfMTAxOCkKCiMgLS0tIFN0ZWVsIDEwNDVfQ1IgLS0tCmRpc18xMDQ1X0NSIDwtIGFzLm51bWVyaWMoc3RlZWxfMTA0NUNSX2RhdGEkRGlzcGxhY2VtZW50KQpGXzEwNDVfQ1IgICA8LSBhcy5udW1lcmljKHN0ZWVsXzEwNDVDUl9kYXRhJEZvcmNlKQplcHNfMTA0NV9DUiA8LSBhcy5udW1lcmljKHN0ZWVsXzEwNDVDUl9kYXRhJFN0cmFpbi4xKQpnYWdlX0RfMTA0NV9DUiA8LSA3LjE4Cm1heF9GXzEwNDVfQ1IgPC0gNDEuMTUKbWF4X2Vwc18xMDQ1X0NSIDwtIDkuNzY4CkFfMTA0NV9DUiA8LSBwaS80ICogZ2FnZV9EXzEwNDVfQ1JeMgpzaWdtYV9lbmdfMTA0NV9DUiA8LSBGXzEwNDVfQ1IgLyBBXzEwNDVfQ1IgKiAxMDAwCnNpZ21hX3RydWVfMTA0NV9DUiA8LSBzaWdtYV9lbmdfMTA0NV9DUiAqICgxICsgZXBzXzEwNDVfQ1IpCmVwc190cnVlXzEwNDVfQ1IgPC0gbG9nKDEgKyBlcHNfMTA0NV9DUikKdWx0aW1hdGVfMTA0NV9DUiA8LSBtYXgoc2lnbWFfZW5nXzEwNDVfQ1IsIG5hLnJtID0gVFJVRSkKZnJhY3R1cmVfMTA0NV9DUiA8LSBsZW5ndGgoc2lnbWFfZW5nXzEwNDVfQ1IpCgojIC0tLSBTdGVlbCAxMDQ1X05NIC0tLQpkaXNfMTA0NV9OTSA8LSBhcy5udW1lcmljKHN0ZWVsXzEwNDVOTV9kYXRhJERpc3BsYWNlbWVudCkKRl8xMDQ1X05NICAgPC0gYXMubnVtZXJpYyhzdGVlbF8xMDQ1Tk1fZGF0YSRGb3JjZSkKZXBzXzEwNDVfTk0gPC0gYXMubnVtZXJpYyhzdGVlbF8xMDQ1Tk1fZGF0YSRTdHJhaW4uMSkKZ2FnZV9EXzEwNDVfTk0gPC0gNy4yMQptYXhfRl8xMDQ1X05NIDwtIDI5Cm1heF9lcHNfMTA0NV9OTSA8LSAyOC4wMQpBXzEwNDVfTk0gPC0gcGkvNCAqIGdhZ2VfRF8xMDQ1X05NXjIKc2lnbWFfZW5nXzEwNDVfTk0gPC0gRl8xMDQ1X05NIC8gQV8xMDQ1X05NICogMTAwMApzaWdtYV90cnVlXzEwNDVfTk0gPC0gc2lnbWFfZW5nXzEwNDVfTk0gKiAoMSArIGVwc18xMDQ1X05NKQplcHNfdHJ1ZV8xMDQ1X05NIDwtIGxvZygxICsgZXBzXzEwNDVfTk0pCnVsdGltYXRlXzEwNDVfTk0gPC0gbWF4KHNpZ21hX2VuZ18xMDQ1X05NLCBuYS5ybSA9IFRSVUUpCmZyYWN0dXJlXzEwNDVfTk0gPC0gbGVuZ3RoKHNpZ21hX2VuZ18xMDQ1X05NKQoKIyAtLS0gU3RlZWwgMzA0IC0tLQpkaXNfMzA0IDwtIGFzLm51bWVyaWMoc3RlZWxfMzA0X2RhdGEkRGlzcGxhY2VtZW50KQpGXzMwNCAgIDwtIGFzLm51bWVyaWMoc3RlZWxfMzA0X2RhdGEkRm9yY2UpCmVwc18zMDQgPC0gYXMubnVtZXJpYyhzdGVlbF8zMDRfZGF0YSRTdHJhaW4uMSkKZ2FnZV9EXzMwNCA8LSA3LjE4Cm1heF9GXzMwNCA8LSAyOC41NwptYXhfZXBzXzMwNCA8LSA1Ny45MgpBXzMwNCA8LSBwaS80ICogZ2FnZV9EXzMwNF4yCnNpZ21hX2VuZ18zMDQgPC0gRl8zMDQgLyBBXzMwNCAqIDEwMDAKc2lnbWFfdHJ1ZV8zMDQgPC0gc2lnbWFfZW5nXzMwNCAqICgxICsgZXBzXzMwNCkKZXBzX3RydWVfMzA0IDwtIGxvZygxICsgZXBzXzMwNCkKdWx0aW1hdGVfMzA0IDwtIG1heChzaWdtYV9lbmdfMzA0LCBuYS5ybSA9IFRSVUUpCmZyYWN0dXJlXzMwNCA8LSBsZW5ndGgoc2lnbWFfZW5nXzMwNCkKCiMgLS0tIEFsdW1pbnVtIDIwMjQgLS0tCmRpc18yMDI0IDwtIGFzLm51bWVyaWMoYWxfMjAyNF9kYXRhJERpc3BsYWNlbWVudCkKRl8yMDI0ICAgPC0gYXMubnVtZXJpYyhhbF8yMDI0X2RhdGEkRm9yY2UpCmVwc18yMDI0IDwtIGFzLm51bWVyaWMoYWxfMjAyNF9kYXRhJFN0cmFpbi4xKQpnYWdlX0RfMjAyNCA8LSA3LjIyCm1heF9GXzIwMjQgPC0gMTkuNDIKbWF4X2Vwc18yMDI0IDwtIDIwLjEKQV8yMDI0IDwtIHBpLzQgKiBnYWdlX0RfMjAyNF4yCnNpZ21hX2VuZ18yMDI0IDwtIEZfMjAyNCAvIEFfMjAyNCAqIDEwMDAKc2lnbWFfdHJ1ZV8yMDI0IDwtIHNpZ21hX2VuZ18yMDI0ICogKDEgKyBlcHNfMjAyNCkKZXBzX3RydWVfMjAyNCA8LSBsb2coMSArIGVwc18yMDI0KQp1bHRpbWF0ZV8yMDI0IDwtIG1heChzaWdtYV9lbmdfMjAyNCwgbmEucm0gPSBUUlVFKQpmcmFjdHVyZV8yMDI0IDwtIGxlbmd0aChzaWdtYV9lbmdfMjAyNCkKCiMgLS0tIEFsdW1pbnVtIDcwNzUgLS0tCmRpc183MDc1IDwtIGFzLm51bWVyaWMoYWxfNzA3NV9kYXRhJERpc3BsYWNlbWVudCkKRl83MDc1ICAgPC0gYXMubnVtZXJpYyhhbF83MDc1X2RhdGEkRm9yY2UpCmVwc183MDc1IDwtIGFzLm51bWVyaWMoYWxfNzA3NV9kYXRhJFN0cmFpbi4xKQpnYWdlX0RfNzA3NSA8LSA2LjExCm1heF9GXzcwNzUgPC0gMjIuNgptYXhfZXBzXzcwNzUgPC0gMTYuNDgKQV83MDc1IDwtIHBpLzQgKiBnYWdlX0RfNzA3NV4yCnNpZ21hX2VuZ183MDc1IDwtIEZfNzA3NSAvIEFfNzA3NSAqIDEwMDAKc2lnbWFfdHJ1ZV83MDc1IDwtIHNpZ21hX2VuZ183MDc1ICogKDEgKyBlcHNfNzA3NSkKZXBzX3RydWVfNzA3NSA8LSBsb2coMSArIGVwc183MDc1KQp1bHRpbWF0ZV83MDc1IDwtIG1heChzaWdtYV9lbmdfNzA3NSwgbmEucm0gPSBUUlVFKQpmcmFjdHVyZV83MDc1IDwtIGxlbmd0aChzaWdtYV9lbmdfNzA3NSkKCiMgLS0tIEJyYXNzIC0tLQpkaXNfYnJhc3MgPC0gYXMubnVtZXJpYyhicmFzc19kYXRhJERpc3BsYWNlbWVudCkKRl9icmFzcyAgIDwtIGFzLm51bWVyaWMoYnJhc3NfZGF0YSRGb3JjZSkKZXBzX2JyYXNzIDwtIGFzLm51bWVyaWMoYnJhc3NfZGF0YSRTdHJhaW4uMSkKZ2FnZV9EX2JyYXNzIDwtIDcuMjYKbWF4X0ZfYnJhc3MgPC0gMTQuNDcKbWF4X2Vwc19icmFzcyA8LSAzMy44MgpBX2JyYXNzIDwtIHBpLzQgKiBnYWdlX0RfYnJhc3NeMgpzaWdtYV9lbmdfYnJhc3MgPC0gRl9icmFzcyAvIEFfYnJhc3MgKiAxMDAwCnNpZ21hX3RydWVfYnJhc3MgPC0gc2lnbWFfZW5nX2JyYXNzICogKDEgKyBlcHNfYnJhc3MpCmVwc190cnVlX2JyYXNzIDwtIGxvZygxICsgZXBzX2JyYXNzKQp1bHRpbWF0ZV9icmFzcyA8LSBtYXgoc2lnbWFfZW5nX2JyYXNzLCBuYS5ybSA9IFRSVUUpCmZyYWN0dXJlX2JyYXNzIDwtIGxlbmd0aChzaWdtYV9lbmdfYnJhc3MpCgojIC0tLSBQTU1BIC0tLQpkaXNfcG1tYSA8LSBhcy5udW1lcmljKHBtbWFfZGF0YSREaXNwbGFjZW1lbnQpCkZfcG1tYSAgIDwtIGFzLm51bWVyaWMocG1tYV9kYXRhJEZvcmNlKQplcHNfcG1tYSA8LSBhcy5udW1lcmljKHBtbWFfZGF0YSRTdHJhaW4uMSkKZ2FnZV9EX3BtbWEgPC0gNwptYXhfRl9wbW1hIDwtIDMuNDcxCm1heF9lcHNfcG1tYSA8LSAzLjM5NwpBX3BtbWEgPC0gcGkvNCAqIGdhZ2VfRF9wbW1hXjIKc2lnbWFfZW5nX3BtbWEgPC0gRl9wbW1hIC8gQV9wbW1hICogMTAwMApzaWdtYV90cnVlX3BtbWEgPC0gc2lnbWFfZW5nX3BtbWEgKiAoMSArIGVwc19wbW1hKQplcHNfdHJ1ZV9wbW1hIDwtIGxvZygxICsgZXBzX3BtbWEpCnVsdGltYXRlX3BtbWEgPC0gbWF4KHNpZ21hX2VuZ19wbW1hLCBuYS5ybSA9IFRSVUUpCmZyYWN0dXJlX3BtbWEgPC0gbGVuZ3RoKHNpZ21hX2VuZ19wbW1hKQpgYGAKCmBgYHtyLHdhcm5pbmc9RkFMU0V9Cgpjb2xvcnMgPC0gYygiZmlyZWJyaWNrIiwgImRhcmtvcmFuZ2UiLCAic3RlZWxibHVlIiwgImJsYWNrIiwgCiAgICAgICAgICAgICJncmVlbjQiLCAicHVycGxlIiwgImdvbGRlbnJvZCIsICJkZWVwcGluayIpCmxhYmVscyA8LSBjKCIxMDE4IFN0ZWVsIiwgIjEwNDUgU3RlZWwgKENSKSIsICIxMDQ1IFN0ZWVsIChOTSkiLCAiMzA0IFN0ZWVsIiwKICAgICAgICAgICAgIjIwMjQgQWx1bWludW0iLCAiNzA3NSBBbHVtaW51bSIsICJCcmFzcyIsICJQTU1BIikKIyBHbG9iYWwgeC95IGxpbWl0cwp4bWF4IDwtIG1heCgxKQp5bWF4IDwtIG1heCgxMDAwKQoKIyBQbG90IGJhc2UgY3VydmUKcGFyKG1mcm93ID0gYygxLCAxKSkKcGxvdChlcHNfMTAxOCwgc2lnbWFfZW5nXzEwMTgsIHR5cGUgPSAibCIsIGNvbCA9IGNvbG9yc1sxXSwgbHdkID0gMiwKICAgICB4bGltID0gYygwLCB4bWF4KSwgeWxpbSA9IGMoMCwgeW1heCksCiAgICAgeGxhYiA9ICJFbmdpbmVlcmluZyBTdHJhaW4gKC0pIiwgeWxhYiA9ICJFbmdpbmVlcmluZyBTdHJlc3MgKE1QYSkiLAogICAgIG1haW4gPSAiRW5naW5lZXJpbmcgU3RyZXNzLVN0cmFpbiBDdXJ2ZXMgZm9yIEFsbCBNYXRlcmlhbHMiKQoKIyBPdmVybGF5IGFsbCBvdGhlciBtYXRlcmlhbHMKbGluZXMoZXBzXzEwNDVfQ1IsICAgc2lnbWFfZW5nXzEwNDVfQ1IsICAgY29sID0gY29sb3JzWzJdLCBsd2QgPSAyKQpsaW5lcyhlcHNfMTA0NV9OTSwgICBzaWdtYV9lbmdfMTA0NV9OTSwgICBjb2wgPSBjb2xvcnNbM10sIGx3ZCA9IDIpCmxpbmVzKGVwc18zMDQsICAgICAgIHNpZ21hX2VuZ18zMDQsICAgICAgIGNvbCA9IGNvbG9yc1s0XSwgbHdkID0gMikKbGluZXMoZXBzXzIwMjQsICAgICAgc2lnbWFfZW5nXzIwMjQsICAgICAgY29sID0gY29sb3JzWzVdLCBsd2QgPSAyKQpsaW5lcyhlcHNfNzA3NSwgICAgICBzaWdtYV9lbmdfNzA3NSwgICAgICBjb2wgPSBjb2xvcnNbNl0sIGx3ZCA9IDIpCmxpbmVzKGVwc19icmFzcywgICAgIHNpZ21hX2VuZ19icmFzcywgICAgIGNvbCA9IGNvbG9yc1s3XSwgbHdkID0gMikKbGluZXMoZXBzX3BtbWEsICAgICAgc2lnbWFfZW5nX3BtbWEsICAgICAgY29sID0gY29sb3JzWzhdLCBsd2QgPSAyKQoKIyBBZGQgbGVnZW5kCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBsYWJlbHMsIGNvbCA9IGNvbG9ycywgbHdkID0gMiwgYnR5ID0gIm4iKQpncmlkKCkKYGBgCiMjIyBFbmdpbmVlcmluZyBTdHJlc3MtU3RyYWluIHZzLiBUcnVlIFN0cmVzcy1TdHJhaW4KYGBge3Isd2FybmluZz1GQUxTRX0KcGFyKG1mcm93ID0gYygxLCAyKSkgCiMjIyAxMDE4IFN0ZWVsCnBsb3QoZXBzXzEwMTgsIHNpZ21hX2VuZ18xMDE4LCB0eXBlID0gIm4iLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICIxMDE4IFN0ZWVsOiBFbmdpbmVlcmluZyB2cyBUcnVlIiwKICAgICB5bGltID0gYygwLCAxMjAwKSkgCmdyaWQoKQpwb2ludHMoZXBzXzEwMTgsIHNpZ21hX2VuZ18xMDE4LCBjb2wgPSAicm95YWxibHVlIiwgcGNoID0gMTYpCnBvaW50cyhlcHNfdHJ1ZV8xMDE4LCBzaWdtYV90cnVlXzEwMTgsIGNvbCA9ICJkYXJrb3JhbmdlIiwgcGNoID0gMTYpCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQgPSBjKCJFbmdpbmVlcmluZyDPg+KAk861IiwgIlRydWUgz4PigJPOtSIpLAogICAgICAgY29sID0gYygicm95YWxibHVlIiwgImRhcmtvcmFuZ2UiKSwgcGNoID0gMTYsIGJ0eSA9ICJuIikKCiMjIyAxMDQ1IFN0ZWVsIChDb2xkIFJvbGxlZCkKcGxvdChlcHNfMTA0NV9DUiwgc2lnbWFfZW5nXzEwNDVfQ1IsIHR5cGUgPSAibiIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKG1tL21tKSIsIHlsYWIgPSAiU3RyZXNzIChNUGEpIiwKICAgICBtYWluID0gIjEwNDUgU3RlZWwgKENSKTogRW5naW5lZXJpbmcgdnMgVHJ1ZSIsCiAgICAgeWxpbSA9IGMoMCwgMTIwMCkpIApncmlkKCkKcG9pbnRzKGVwc18xMDQ1X0NSLCBzaWdtYV9lbmdfMTA0NV9DUiwgY29sID0gInJveWFsYmx1ZSIsIHBjaCA9IDE2KQpwb2ludHMoZXBzX3RydWVfMTA0NV9DUiwgc2lnbWFfdHJ1ZV8xMDQ1X0NSLCBjb2wgPSAiZGFya29yYW5nZSIsIHBjaCA9IDE2KQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiRW5naW5lZXJpbmcgz4PigJPOtSIsICJUcnVlIM+D4oCTzrUiKSwKICAgICAgIGNvbCA9IGMoInJveWFsYmx1ZSIsICJkYXJrb3JhbmdlIiksIHBjaCA9IDE2LCBidHkgPSAibiIpCgojIyMgMTA0NSBTdGVlbCAoTm9ybWFsaXplZCkKcGxvdChlcHNfMTA0NV9OTSwgc2lnbWFfZW5nXzEwNDVfTk0sIHR5cGUgPSAibiIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKG1tL21tKSIsIHlsYWIgPSAiU3RyZXNzIChNUGEpIiwKICAgICBtYWluID0gIjEwNDUgU3RlZWwgKE5NKTogRW5naW5lZXJpbmcgdnMgVHJ1ZSIsCiAgICAgeWxpbSA9IGMoMCwgMTIwMCkpIApncmlkKCkKcG9pbnRzKGVwc18xMDQ1X05NLCBzaWdtYV9lbmdfMTA0NV9OTSwgY29sID0gInJveWFsYmx1ZSIsIHBjaCA9IDE2KQpwb2ludHMoZXBzX3RydWVfMTA0NV9OTSwgc2lnbWFfdHJ1ZV8xMDQ1X05NLCBjb2wgPSAiZGFya29yYW5nZSIsIHBjaCA9IDE2KQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiRW5naW5lZXJpbmcgz4PigJPOtSIsICJUcnVlIM+D4oCTzrUiKSwKICAgICAgIGNvbCA9IGMoInJveWFsYmx1ZSIsICJkYXJrb3JhbmdlIiksIHBjaCA9IDE2LCBidHkgPSAibiIpCgojIyMgMzA0IFN0YWlubGVzcyBTdGVlbCAKcGxvdChlcHNfMzA0LCBzaWdtYV9lbmdfMzA0LCB0eXBlID0gIm4iLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICIzMDQgU3RhaW5sZXNzIFN0ZWVsOiBFbmdpbmVlcmluZyB2cyBUcnVlIiwKICAgICB5bGltID0gYygwLCAxMjAwKSkgIApncmlkKCkKcG9pbnRzKGVwc18zMDQsIHNpZ21hX2VuZ18zMDQsIGNvbCA9ICJyb3lhbGJsdWUiLCBwY2ggPSAxNikKcG9pbnRzKGVwc190cnVlXzMwNCwgc2lnbWFfdHJ1ZV8zMDQsIGNvbCA9ICJkYXJrb3JhbmdlIiwgcGNoID0gMTYpCmxlZ2VuZCgiYm90dG9tcmlnaHQiLAogICAgICAgbGVnZW5kID0gYygiRW5naW5lZXJpbmcgz4PigJPOtSIsICJUcnVlIM+D4oCTzrUiKSwKICAgICAgIGNvbCA9IGMoInJveWFsYmx1ZSIsICJkYXJrb3JhbmdlIiksCiAgICAgICBwY2ggPSAxNiwgYnR5ID0gIm4iKQoKCiMjIyAyMDI0IEFsdW1pbnVtCnBsb3QoZXBzXzIwMjQsIHNpZ21hX2VuZ18yMDI0LCB0eXBlID0gIm4iLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICIyMDI0IEFsdW1pbnVtOiBFbmdpbmVlcmluZyB2cyBUcnVlIiwKICAgICB5bGltID0gYygwLCAxMjAwKSkgCmdyaWQoKQpwb2ludHMoZXBzXzIwMjQsIHNpZ21hX2VuZ18yMDI0LCBjb2wgPSAicm95YWxibHVlIiwgcGNoID0gMTYpCnBvaW50cyhlcHNfdHJ1ZV8yMDI0LCBzaWdtYV90cnVlXzIwMjQsIGNvbCA9ICJkYXJrb3JhbmdlIiwgcGNoID0gMTYpCmxlZ2VuZCgiYm90dG9tcmlnaHQiLCBsZWdlbmQgPSBjKCJFbmdpbmVlcmluZyDPg+KAk861IiwgIlRydWUgz4PigJPOtSIpLAogICAgICAgY29sID0gYygicm95YWxibHVlIiwgImRhcmtvcmFuZ2UiKSwgcGNoID0gMTYsIGJ0eSA9ICJuIikKCiMjIyA3MDc1IEFsdW1pbnVtCnBsb3QoZXBzXzcwNzUsIHNpZ21hX2VuZ183MDc1LCB0eXBlID0gIm4iLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICI3MDc1IEFsdW1pbnVtOiBFbmdpbmVlcmluZyB2cyBUcnVlIiwKICAgICB5bGltID0gYygwLCAxMjAwKSkgIApncmlkKCkKcG9pbnRzKGVwc183MDc1LCBzaWdtYV9lbmdfNzA3NSwgY29sID0gInJveWFsYmx1ZSIsIHBjaCA9IDE2KQpwb2ludHMoZXBzX3RydWVfNzA3NSwgc2lnbWFfdHJ1ZV83MDc1LCBjb2wgPSAiZGFya29yYW5nZSIsIHBjaCA9IDE2KQpsZWdlbmQoImJvdHRvbXJpZ2h0IiwgbGVnZW5kID0gYygiRW5naW5lZXJpbmcgz4PigJPOtSIsICJUcnVlIM+D4oCTzrUiKSwKICAgICAgIGNvbCA9IGMoInJveWFsYmx1ZSIsICJkYXJrb3JhbmdlIiksIHBjaCA9IDE2LCBidHkgPSAibiIpCgojIyMgQnJhc3MgKEFubmVhbGVkKQpwbG90KGVwc19icmFzcywgc2lnbWFfZW5nX2JyYXNzLCB0eXBlID0gIm4iLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICJBbm5lYWxlZCBCcmFzczogRW5naW5lZXJpbmcgdnMgVHJ1ZSIsCiAgICAgeWxpbSA9IGMoMCwgMTIwMCkpICAKZ3JpZCgpCnBvaW50cyhlcHNfYnJhc3MsIHNpZ21hX2VuZ19icmFzcywgY29sID0gInJveWFsYmx1ZSIsIHBjaCA9IDE2KQpwb2ludHMoZXBzX3RydWVfYnJhc3MsIHNpZ21hX3RydWVfYnJhc3MsIGNvbCA9ICJkYXJrb3JhbmdlIiwgcGNoID0gMTYpCmxlZ2VuZCgidG9wcmlnaHQiLCBsZWdlbmQgPSBjKCJFbmdpbmVlcmluZyDPg+KAk861IiwgIlRydWUgz4PigJPOtSIpLAogICAgICAgY29sID0gYygicm95YWxibHVlIiwgImRhcmtvcmFuZ2UiKSwgcGNoID0gMTYsIGJ0eSA9ICJuIikKCiMjIyBQTU1BCnBsb3QoZXBzX3BtbWEsIHNpZ21hX2VuZ19wbW1hLCB0eXBlID0gIm4iLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICJQTU1BOiBFbmdpbmVlcmluZyB2cyBUcnVlIiwKICAgICB5bGltID0gYygwLCAxMjAwKSkgIApncmlkKCkKcG9pbnRzKGVwc19wbW1hLCBzaWdtYV9lbmdfcG1tYSwgY29sID0gInJveWFsYmx1ZSIsIHBjaCA9IDE2KQpwb2ludHMoZXBzX3RydWVfcG1tYSwgc2lnbWFfdHJ1ZV9wbW1hLCBjb2wgPSAiZGFya29yYW5nZSIsIHBjaCA9IDE2KQpsZWdlbmQoInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiRW5naW5lZXJpbmcgz4PigJPOtSIsICJUcnVlIM+D4oCTzrUiKSwKICAgICAgIGNvbCA9IGMoInJveWFsYmx1ZSIsICJkYXJrb3JhbmdlIiksIHBjaCA9IDE2LCBidHkgPSAibiIpCgpgYGAKCgpGb3IgdGhlIHlpZWxkIHN0cmFpbiB2YWx1ZXMgZm9yIGVhY2ggbWF0ZXJpYWxzIGJlbG93LCBJIGhhdmUgZXllYmFsbCB0aGUgYXBwcm94aW1hdGUgdmFsdWUsIGZpbmQgdGhlIHlvdW5nJ3MgbW9kdWx1cywgYW5kIHRoZSAwLjIlLiAKVXBkYXRlL2FkanVzdCB0aGUgeWllbGQgc3RyYWluIGJhc2VkIG9uIHRoZSBhbGlnbm1lbnQgb2YgZWFjaCBncmFwaAoKIyMjIC0tLSAxMDE4IFN0ZWVsIC0tLQpgYGB7cn0KZXBzX3lpZWxkXzEwMTggPC0gMC4wMDI2CiMgRml0IGxpbmVhciBlbGFzdGljIHJlZ2lvbiB1cCB0byB5aWVsZCAoMCBpbnRlcmNlcHQpCmZpdF8xMDE4IDwtIGxtKHNpZ21hX2VuZ18xMDE4W2Vwc18xMDE4IDw9IGVwc195aWVsZF8xMDE4XSB+IDAgKyBlcHNfMTAxOFtlcHNfMTAxOCA8PSBlcHNfeWllbGRfMTAxOF0pCkVfMTAxOCA8LSBjb2VmKGZpdF8xMDE4KVsxXQoKIyBDYWxjdWxhdGUgMC4yJSBvZmZzZXQgbGluZTogz4MgPSBFKM61IOKIkiAwLjAwMikKc2lnbWFfb2Zmc2V0XzEwMTggPC0gRV8xMDE4ICogKGVwc18xMDE4IC0gMC4wMDIpCmRpZmZfMTAxOCA8LSBzaWdtYV9lbmdfMTAxOCAtIHNpZ21hX29mZnNldF8xMDE4CmlfMTAxOCA8LSB3aGljaChkaWZmKHNpZ24oZGlmZl8xMDE4KSkgIT0gMClbMV0KeWllbGRfc3RyYWluXzEwMTggPC0gZXBzXzEwMThbaV8xMDE4XQp5aWVsZF9zdHJlc3NfMTAxOCA8LSBzaWdtYV9lbmdfMTAxOFtpXzEwMThdCgojIC0tLSBQbG90IC0tLQpwbG90KGVwc18xMDE4LCBzaWdtYV9lbmdfMTAxOCwKICAgICB0eXBlID0gImwiLCBjb2wgPSAic3RlZWxibHVlIiwgbHdkID0gMiwKICAgICB4bGFiID0gIlN0cmFpbiAoLSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICIxMDE4IFN0ZWVsIiwgeWxpbSA9IGMoMCwgMTIwMCkpCmdyaWQoKQpwb2ludHMoZXBzXzEwMTgsIHNpZ21hX2VuZ18xMDE4LCBjb2wgPSAic3RlZWxibHVlIiwgcGNoID0gMTYpCmFibGluZShhID0gMCwgYiA9IEVfMTAxOCwgY29sID0gInB1cnBsZSIsIGx3ZCA9IDIsIGx0eSA9IDIpICAgICAgICAgICAgICAgICMgT3JpZ2luYWwgZWxhc3RpYyBsaW5lCmFibGluZShhID0gLUVfMTAxOCAqIDAuMDAyLCBiID0gRV8xMDE4LCBjb2wgPSAiZGFya2dyZWVuIiwgbHdkID0gMiwgbHR5ID0gMykgIyAwLjIlIG9mZnNldCBsaW5lCnBvaW50cyh5aWVsZF9zdHJhaW5fMTAxOCwgeWllbGRfc3RyZXNzXzEwMTgsIHBjaCA9IDE5LCBjb2wgPSAicmVkIiwgY2V4ID0gMS41KQp0ZXh0KHggPSB5aWVsZF9zdHJhaW5fMTAxOCwKICAgICB5ID0geWllbGRfc3RyZXNzXzEwMTgsCiAgICAgbGFiZWxzID0gcGFzdGUwKHJvdW5kKHlpZWxkX3N0cmVzc18xMDE4LCAxKSwgIiBNUGEiKSwKICAgICBwb3MgPSAzLCBjb2wgPSAicmVkIiwgY2V4ID0gMS4yKQpjYXQoIkVsYXN0aWMgTW9kdWx1cyAoRSkgICAgICAgICA9Iiwgcm91bmQoRV8xMDE4LCAyKSwgIk1QYVxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJhaW4gICAgPSIsIHJvdW5kKHlpZWxkX3N0cmFpbl8xMDE4LCA1KSwgIlxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJlc3MgICAgPSIsIHJvdW5kKHlpZWxkX3N0cmVzc18xMDE4LCAyKSwgIk1QYVxuIikKCmBgYAoKIyMjIC0tLSAxMDQ1IFN0ZWVsIChDb2xkIFJvbGxlZCkgLS0tCmBgYHtyfQplcHNfeWllbGRfMTA0NV9DUiA8LSAwLjAwMzMKZml0XzEwNDVfQ1IgPC0gbG0oc2lnbWFfZW5nXzEwNDVfQ1JbZXBzXzEwNDVfQ1IgPD0gZXBzX3lpZWxkXzEwNDVfQ1JdIH4gMCArIGVwc18xMDQ1X0NSW2Vwc18xMDQ1X0NSIDw9IGVwc195aWVsZF8xMDQ1X0NSXSkKRV8xMDQ1X0NSIDwtIGNvZWYoZml0XzEwNDVfQ1IpWzFdCnNpZ21hX29mZnNldF8xMDQ1X0NSIDwtIEVfMTA0NV9DUiAqIChlcHNfMTA0NV9DUiAtIDAuMDAyKQppXzEwNDVfQ1IgPC0gd2hpY2goZGlmZihzaWduKHNpZ21hX2VuZ18xMDQ1X0NSIC0gc2lnbWFfb2Zmc2V0XzEwNDVfQ1IpKSAhPSAwKVsxXQp5aWVsZF9zdHJhaW5fMTA0NV9DUiA8LSBlcHNfMTA0NV9DUltpXzEwNDVfQ1JdCnlpZWxkX3N0cmVzc18xMDQ1X0NSIDwtIHNpZ21hX2VuZ18xMDQ1X0NSW2lfMTA0NV9DUl0KCnBsb3QoZXBzXzEwNDVfQ1IsIHNpZ21hX2VuZ18xMDQ1X0NSLCB0eXBlID0gImwiLCBjb2wgPSAiZmlyZWJyaWNrIiwgbHdkID0gMiwKICAgICB4bGFiID0gIlN0cmFpbiAoLSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsIG1haW4gPSAiMTA0NSBTdGVlbCAoQ1IpIiwgeWxpbSA9IGMoMCwgMTIwMCkpCmdyaWQoKQphYmxpbmUoYSA9IDAsIGIgPSBFXzEwNDVfQ1IsIGNvbCA9ICJwdXJwbGUiLCBsd2QgPSAyLCBsdHkgPSAyKQphYmxpbmUoYSA9IC1FXzEwNDVfQ1IgKiAwLjAwMiwgYiA9IEVfMTA0NV9DUiwgY29sID0gImRhcmtncmVlbiIsIGx3ZCA9IDIsIGx0eSA9IDMpCnBvaW50cyh5aWVsZF9zdHJhaW5fMTA0NV9DUiwgeWllbGRfc3RyZXNzXzEwNDVfQ1IsIGNvbCA9ICJyZWQiLCBwY2ggPSAxOSwgY2V4ID0gMS41KQp0ZXh0KHlpZWxkX3N0cmFpbl8xMDQ1X0NSLCB5aWVsZF9zdHJlc3NfMTA0NV9DUiwgbGFiZWxzID0gcGFzdGUwKHJvdW5kKHlpZWxkX3N0cmVzc18xMDQ1X0NSLCAxKSwgIiBNUGEiKSwgcG9zID0gMywgY29sID0gInJlZCIpCmNhdCgiRWxhc3RpYyBNb2R1bHVzIChFKSAgICAgICAgID0iLCByb3VuZChFXzEwMTgsIDIpLCAiTVBhXG4iKQpjYXQoIjAuMiUgT2Zmc2V0IFlpZWxkIFN0cmFpbiAgICA9Iiwgcm91bmQoeWllbGRfc3RyYWluXzEwNDVfQ1IsIDUpLCAiXG4iKQpjYXQoIjAuMiUgT2Zmc2V0IFlpZWxkIFN0cmVzcyAgICA9Iiwgcm91bmQoeWllbGRfc3RyZXNzXzEwNDVfQ1IsIDIpLCAiTVBhXG4iKQoKYGBgCgoKIyMjIC0tLTEwNDUgU3RlZWwgKE5vcm1hbGl6ZWQpIC0tLQpgYGB7cn0KZXBzX3lpZWxkXzEwNDVfTk0gPC0gMC4wMDM1CmZpdF8xMDQ1X05NIDwtIGxtKHNpZ21hX2VuZ18xMDQ1X05NW2Vwc18xMDQ1X05NIDw9IGVwc195aWVsZF8xMDQ1X05NXSB+IDAgKyBlcHNfMTA0NV9OTVtlcHNfMTA0NV9OTSA8PSBlcHNfeWllbGRfMTA0NV9OTV0pCkVfMTA0NV9OTSA8LSBjb2VmKGZpdF8xMDQ1X05NKVsxXQpzaWdtYV9vZmZzZXRfMTA0NV9OTSA8LSBFXzEwNDVfTk0gKiAoZXBzXzEwNDVfTk0gLSAwLjAwMikKaV8xMDQ1X05NIDwtIHdoaWNoKGRpZmYoc2lnbihzaWdtYV9lbmdfMTA0NV9OTSAtIHNpZ21hX29mZnNldF8xMDQ1X05NKSkgIT0gMClbMV0KeWllbGRfc3RyYWluXzEwNDVfTk0gPC0gZXBzXzEwNDVfTk1baV8xMDQ1X05NXQp5aWVsZF9zdHJlc3NfMTA0NV9OTSA8LSBzaWdtYV9lbmdfMTA0NV9OTVtpXzEwNDVfTk1dCgpwbG90KGVwc18xMDQ1X05NLCBzaWdtYV9lbmdfMTA0NV9OTSwgdHlwZSA9ICJsIiwgY29sID0gImluZGlhbnJlZCIsIGx3ZCA9IDIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKC0pIiwgeWxhYiA9ICJTdHJlc3MgKE1QYSkiLCBtYWluID0gIjEwNDUgU3RlZWwgKE5NKSIsIHlsaW0gPSBjKDAsIDEyMDApKQpncmlkKCkKYWJsaW5lKGEgPSAwLCBiID0gRV8xMDQ1X05NLCBjb2wgPSAicHVycGxlIiwgbHdkID0gMiwgbHR5ID0gMikKYWJsaW5lKGEgPSAtRV8xMDQ1X05NICogMC4wMDIsIGIgPSBFXzEwNDVfTk0sIGNvbCA9ICJkYXJrZ3JlZW4iLCBsd2QgPSAyLCBsdHkgPSAzKQpwb2ludHMoeWllbGRfc3RyYWluXzEwNDVfTk0sIHlpZWxkX3N0cmVzc18xMDQ1X05NLCBjb2wgPSAicmVkIiwgcGNoID0gMTksIGNleCA9IDEuNSkKdGV4dCh5aWVsZF9zdHJhaW5fMTA0NV9OTSwgeWllbGRfc3RyZXNzXzEwNDVfTk0sIGxhYmVscyA9IHBhc3RlMChyb3VuZCh5aWVsZF9zdHJlc3NfMTA0NV9OTSwgMSksICIgTVBhIiksIHBvcyA9IDMsIGNvbCA9ICJyZWQiKQpjYXQoIkVsYXN0aWMgTW9kdWx1cyAoRSkgICAgICAgICA9Iiwgcm91bmQoRV8xMDE4LCAyKSwgIk1QYVxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJhaW4gICAgPSIsIHJvdW5kKHlpZWxkX3N0cmFpbl8xMDQ1X05NLCA1KSwgIlxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJlc3MgICAgPSIsIHJvdW5kKHlpZWxkX3N0cmVzc18xMDQ1X05NLCAyKSwgIk1QYVxuIikKCmBgYAoKIyMjIC0tLSAzMDQgU3RhaW5sZXNzIFN0ZWVsICAtLS0KYGBge3J9CmVwc195aWVsZF8zMDQgPC0gMC4wMDMwCmZpdF8zMDQgPC0gbG0oc2lnbWFfZW5nXzMwNFtlcHNfMzA0IDw9IGVwc195aWVsZF8zMDRdIH4gMCArIGVwc18zMDRbZXBzXzMwNCA8PSBlcHNfeWllbGRfMzA0XSkKRV8zMDQgPC0gY29lZihmaXRfMzA0KVsxXQpzaWdtYV9vZmZzZXRfMzA0IDwtIEVfMzA0ICogKGVwc18zMDQgLSAwLjAwMikKaV8zMDQgPC0gd2hpY2goZGlmZihzaWduKHNpZ21hX2VuZ18zMDQgLSBzaWdtYV9vZmZzZXRfMzA0KSkgIT0gMClbMV0KeWllbGRfc3RyYWluXzMwNCA8LSBlcHNfMzA0W2lfMzA0XQp5aWVsZF9zdHJlc3NfMzA0IDwtIHNpZ21hX2VuZ18zMDRbaV8zMDRdCgpwbG90KGVwc18zMDQsIHNpZ21hX2VuZ18zMDQsIHR5cGUgPSAibCIsIGNvbCA9ICJmb3Jlc3RncmVlbiIsIGx3ZCA9IDIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKC0pIiwgeWxhYiA9ICJTdHJlc3MgKE1QYSkiLCBtYWluID0gIjMwNCBTdGFpbmxlc3MgU3RlZWwiLCB5bGltID0gYygwLCAxMjAwKSkKZ3JpZCgpCmFibGluZShhID0gMCwgYiA9IEVfMzA0LCBjb2wgPSAicHVycGxlIiwgbHdkID0gMiwgbHR5ID0gMikKYWJsaW5lKGEgPSAtRV8zMDQgKiAwLjAwMiwgYiA9IEVfMzA0LCBjb2wgPSAiZGFya2dyZWVuIiwgbHdkID0gMiwgbHR5ID0gMykKcG9pbnRzKHlpZWxkX3N0cmFpbl8zMDQsIHlpZWxkX3N0cmVzc18zMDQsIGNvbCA9ICJyZWQiLCBwY2ggPSAxOSwgY2V4ID0gMS41KQp0ZXh0KHlpZWxkX3N0cmFpbl8zMDQsIHlpZWxkX3N0cmVzc18zMDQsIGxhYmVscyA9IHBhc3RlMChyb3VuZCh5aWVsZF9zdHJlc3NfMzA0LCAxKSwgIiBNUGEiKSwgcG9zID0gMywgY29sID0gInJlZCIpCmNhdCgiRWxhc3RpYyBNb2R1bHVzIChFKSAgICAgICAgID0iLCByb3VuZChFXzEwMTgsIDIpLCAiTVBhXG4iKQpjYXQoIjAuMiUgT2Zmc2V0IFlpZWxkIFN0cmFpbiAgICA9Iiwgcm91bmQoeWllbGRfc3RyYWluXzMwNCwgNSksICJcbiIpCmNhdCgiMC4yJSBPZmZzZXQgWWllbGQgU3RyZXNzICAgID0iLCByb3VuZCh5aWVsZF9zdHJlc3NfMzA0LCAyKSwgIk1QYVxuIikKYGBgCgoKIyMjIC0tLTIwMjQgQWx1bWludW0gLS0tCmBgYHtyfQplcHNfeWllbGRfMjAyNCA8LSAwLjAwNQpmaXRfMjAyNCA8LSBsbShzaWdtYV9lbmdfMjAyNFtlcHNfMjAyNCA8PSBlcHNfeWllbGRfMjAyNF0gfiAwICsgZXBzXzIwMjRbZXBzXzIwMjQgPD0gZXBzX3lpZWxkXzIwMjRdKQpFXzIwMjQgPC0gY29lZihmaXRfMjAyNClbMV0Kc2lnbWFfb2Zmc2V0XzIwMjQgPC0gRV8yMDI0ICogKGVwc18yMDI0IC0gMC4wMDIpCmlfMjAyNCA8LSB3aGljaChkaWZmKHNpZ24oc2lnbWFfZW5nXzIwMjQgLSBzaWdtYV9vZmZzZXRfMjAyNCkpICE9IDApWzFdCnlpZWxkX3N0cmFpbl8yMDI0IDwtIGVwc18yMDI0W2lfMjAyNF0KeWllbGRfc3RyZXNzXzIwMjQgPC0gc2lnbWFfZW5nXzIwMjRbaV8yMDI0XQoKcGxvdChlcHNfMjAyNCwgc2lnbWFfZW5nXzIwMjQsIHR5cGUgPSAibCIsIGNvbCA9ICJkb2RnZXJibHVlMyIsIGx3ZCA9IDIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKC0pIiwgeWxhYiA9ICJTdHJlc3MgKE1QYSkiLCBtYWluID0gIjIwMjQgQWx1bWludW0iLCB5bGltID0gYygwLCAxMjAwKSkKZ3JpZCgpCmFibGluZShhID0gMCwgYiA9IEVfMjAyNCwgY29sID0gInB1cnBsZSIsIGx3ZCA9IDIsIGx0eSA9IDIpCmFibGluZShhID0gLUVfMjAyNCAqIDAuMDAyLCBiID0gRV8yMDI0LCBjb2wgPSAiZGFya2dyZWVuIiwgbHdkID0gMiwgbHR5ID0gMykKcG9pbnRzKHlpZWxkX3N0cmFpbl8yMDI0LCB5aWVsZF9zdHJlc3NfMjAyNCwgY29sID0gInJlZCIsIHBjaCA9IDE5LCBjZXggPSAxLjUpCnRleHQoeWllbGRfc3RyYWluXzIwMjQsIHlpZWxkX3N0cmVzc18yMDI0LCBsYWJlbHMgPSBwYXN0ZTAocm91bmQoeWllbGRfc3RyZXNzXzIwMjQsIDEpLCAiIE1QYSIpLCBwb3MgPSAzLCBjb2wgPSAicmVkIikKY2F0KCJFbGFzdGljIE1vZHVsdXMgKEUpICAgICAgICAgPSIsIHJvdW5kKEVfMTAxOCwgMiksICJNUGFcbiIpCmNhdCgiMC4yJSBPZmZzZXQgWWllbGQgU3RyYWluICAgID0iLCByb3VuZCh5aWVsZF9zdHJhaW5fMjAyNCwgNSksICJcbiIpCmNhdCgiMC4yJSBPZmZzZXQgWWllbGQgU3RyZXNzICAgID0iLCByb3VuZCh5aWVsZF9zdHJlc3NfMjAyNCwgMiksICJNUGFcbiIpCgpgYGAKCgojIyMgLS0tIDcwNzUgQWx1bWludW0gLS0tCmBgYHtyfQplcHNfeWllbGRfNzA3NSA8LSAwLjAwNApmaXRfNzA3NSA8LSBsbShzaWdtYV9lbmdfNzA3NVtlcHNfNzA3NSA8PSBlcHNfeWllbGRfNzA3NV0gfiAwICsgZXBzXzcwNzVbZXBzXzcwNzUgPD0gZXBzX3lpZWxkXzcwNzVdKQpFXzcwNzUgPC0gY29lZihmaXRfNzA3NSlbMV0Kc2lnbWFfb2Zmc2V0XzcwNzUgPC0gRV83MDc1ICogKGVwc183MDc1IC0gMC4wMDIpCmlfNzA3NSA8LSB3aGljaChkaWZmKHNpZ24oc2lnbWFfZW5nXzcwNzUgLSBzaWdtYV9vZmZzZXRfNzA3NSkpICE9IDApWzFdCnlpZWxkX3N0cmFpbl83MDc1IDwtIGVwc183MDc1W2lfNzA3NV0KeWllbGRfc3RyZXNzXzcwNzUgPC0gc2lnbWFfZW5nXzcwNzVbaV83MDc1XQoKcGxvdChlcHNfNzA3NSwgc2lnbWFfZW5nXzcwNzUsIHR5cGUgPSAibCIsIGNvbCA9ICJkYXJrb3JhbmdlIiwgbHdkID0gMiwKICAgICB4bGFiID0gIlN0cmFpbiAoLSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsIG1haW4gPSAiNzA3NSBBbHVtaW51bSIsIHlsaW0gPSBjKDAsIDEyMDApKQpncmlkKCkKYWJsaW5lKGEgPSAwLCBiID0gRV83MDc1LCBjb2wgPSAicHVycGxlIiwgbHdkID0gMiwgbHR5ID0gMikKYWJsaW5lKGEgPSAtRV83MDc1ICogMC4wMDIsIGIgPSBFXzcwNzUsIGNvbCA9ICJkYXJrZ3JlZW4iLCBsd2QgPSAyLCBsdHkgPSAzKQpwb2ludHMoeWllbGRfc3RyYWluXzcwNzUsIHlpZWxkX3N0cmVzc183MDc1LCBjb2wgPSAicmVkIiwgcGNoID0gMTksIGNleCA9IDEuNSkKdGV4dCh5aWVsZF9zdHJhaW5fNzA3NSwgeWllbGRfc3RyZXNzXzcwNzUsIGxhYmVscyA9IHBhc3RlMChyb3VuZCh5aWVsZF9zdHJlc3NfNzA3NSwgMSksICIgTVBhIiksIHBvcyA9IDMsIGNvbCA9ICJyZWQiKQpjYXQoIkVsYXN0aWMgTW9kdWx1cyAoRSkgICAgICAgICA9Iiwgcm91bmQoRV8xMDE4LCAyKSwgIk1QYVxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJhaW4gICAgPSIsIHJvdW5kKHlpZWxkX3N0cmFpbl83MDc1LCA1KSwgIlxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJlc3MgICAgPSIsIHJvdW5kKHlpZWxkX3N0cmVzc183MDc1LCAyKSwgIk1QYVxuIikKCmBgYAoKIyMjIC0tLUFubmVhbGVkIEJyYXNzLS0tCmBgYHtyfQplcHNfeWllbGRfYnJhc3MgPC0gMC4wMDcKZml0X2JyYXNzIDwtIGxtKHNpZ21hX2VuZ19icmFzc1tlcHNfYnJhc3MgPD0gZXBzX3lpZWxkX2JyYXNzXSB+IDAgKyBlcHNfYnJhc3NbZXBzX2JyYXNzIDw9IGVwc195aWVsZF9icmFzc10pCkVfYnJhc3MgPC0gY29lZihmaXRfYnJhc3MpWzFdCnNpZ21hX29mZnNldF9icmFzcyA8LSBFX2JyYXNzICogKGVwc19icmFzcyAtIDAuMDAyKQppX2JyYXNzIDwtIHdoaWNoKGRpZmYoc2lnbihzaWdtYV9lbmdfYnJhc3MgLSBzaWdtYV9vZmZzZXRfYnJhc3MpKSAhPSAwKVsxXQp5aWVsZF9zdHJhaW5fYnJhc3MgPC0gZXBzX2JyYXNzW2lfYnJhc3NdCnlpZWxkX3N0cmVzc19icmFzcyA8LSBzaWdtYV9lbmdfYnJhc3NbaV9icmFzc10KCnBsb3QoZXBzX2JyYXNzLCBzaWdtYV9lbmdfYnJhc3MsIHR5cGUgPSAibCIsIGNvbCA9ICJnb2xkZW5yb2QiLCBsd2QgPSAyLAogICAgIHhsYWIgPSAiU3RyYWluICgtKSIsIHlsYWIgPSAiU3RyZXNzIChNUGEpIiwgbWFpbiA9ICJBbm5lYWxlZCBCcmFzcyIsIHlsaW0gPSBjKDAsIDEyMDApKQpncmlkKCkKYWJsaW5lKGEgPSAwLCBiID0gRV9icmFzcywgY29sID0gInB1cnBsZSIsIGx3ZCA9IDIsIGx0eSA9IDIpCmFibGluZShhID0gLUVfYnJhc3MgKiAwLjAwMiwgYiA9IEVfYnJhc3MsIGNvbCA9ICJkYXJrZ3JlZW4iLCBsd2QgPSAyLCBsdHkgPSAzKQpwb2ludHMoeWllbGRfc3RyYWluX2JyYXNzLCB5aWVsZF9zdHJlc3NfYnJhc3MsIGNvbCA9ICJyZWQiLCBwY2ggPSAxOSwgY2V4ID0gMS41KQp0ZXh0KHlpZWxkX3N0cmFpbl9icmFzcywgeWllbGRfc3RyZXNzX2JyYXNzLCBsYWJlbHMgPSBwYXN0ZTAocm91bmQoeWllbGRfc3RyZXNzX2JyYXNzLCAxKSwgIiBNUGEiKSwgcG9zID0gMywgY29sID0gInJlZCIpCmNhdCgiRWxhc3RpYyBNb2R1bHVzIChFKSAgICAgICAgID0iLCByb3VuZChFXzEwMTgsIDIpLCAiTVBhXG4iKQpjYXQoIjAuMiUgT2Zmc2V0IFlpZWxkIFN0cmFpbiAgICA9Iiwgcm91bmQoeWllbGRfc3RyYWluX2JyYXNzLCA1KSwgIlxuIikKY2F0KCIwLjIlIE9mZnNldCBZaWVsZCBTdHJlc3MgICAgPSIsIHJvdW5kKHlpZWxkX3N0cmVzc19icmFzcywgMiksICJNUGFcbiIpCgpgYGAKCiMjIyAtLS1QTU1BLS0tCmBgYHtyfQplcHNfeWllbGRfcG1tYSA8LSAwLjAwNwpmaXRfcG1tYSA8LSBsbShzaWdtYV9lbmdfcG1tYVtlcHNfcG1tYSA8PSBlcHNfeWllbGRfcG1tYV0gfiAwICsgZXBzX3BtbWFbZXBzX3BtbWEgPD0gZXBzX3lpZWxkX3BtbWFdKQpFX3BtbWEgPC0gY29lZihmaXRfcG1tYSlbMV0Kc2lnbWFfb2Zmc2V0X3BtbWEgPC0gRV9wbW1hICogKGVwc19wbW1hIC0gMC4wMDIpCmlfcG1tYSA8LSB3aGljaChkaWZmKHNpZ24oc2lnbWFfZW5nX3BtbWEgLSBzaWdtYV9vZmZzZXRfcG1tYSkpICE9IDApWzFdCnlpZWxkX3N0cmFpbl9wbW1hIDwtIGVwc19wbW1hW2lfcG1tYV0KeWllbGRfc3RyZXNzX3BtbWEgPC0gc2lnbWFfZW5nX3BtbWFbaV9wbW1hXQoKcGxvdChlcHNfcG1tYSwgc2lnbWFfZW5nX3BtbWEsIHR5cGUgPSAibCIsIGNvbCA9ICJibGFjayIsIGx3ZCA9IDIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKC0pIiwgeWxhYiA9ICJTdHJlc3MgKE1QYSkiLCBtYWluID0gIlBNTUEiLCB5bGltID0gYygwLCAxMjAwKSkKZ3JpZCgpCmFibGluZShhID0gMCwgYiA9IEVfcG1tYSwgY29sID0gInB1cnBsZSIsIGx3ZCA9IDIsIGx0eSA9IDIpCmFibGluZShhID0gLUVfcG1tYSAqIDAuMDAyLCBiID0gRV9wbW1hLCBjb2wgPSAiZGFya2dyZWVuIiwgbHdkID0gMiwgbHR5ID0gMykKcG9pbnRzKHlpZWxkX3N0cmFpbl9wbW1hLCB5aWVsZF9zdHJlc3NfcG1tYSwgY29sID0gInJlZCIsIHBjaCA9IDE5LCBjZXggPSAxLjUpCnRleHQoeWllbGRfc3RyYWluX3BtbWEsIHlpZWxkX3N0cmVzc19wbW1hLCBsYWJlbHMgPSBwYXN0ZTAocm91bmQoeWllbGRfc3RyZXNzX3BtbWEsIDEpLCAiIE1QYSIpLCBwb3MgPSAzLCBjb2wgPSAicmVkIikKY2F0KCJFbGFzdGljIE1vZHVsdXMgKEUpICAgICAgICAgPSIsIHJvdW5kKEVfMTAxOCwgMiksICJNUGFcbiIpCmNhdCgiMC4yJSBPZmZzZXQgWWllbGQgU3RyYWluICAgID0iLCByb3VuZCh5aWVsZF9zdHJhaW5fcG1tYSwgNSksICJcbiIpCmNhdCgiMC4yJSBPZmZzZXQgWWllbGQgU3RyZXNzICAgID0iLCByb3VuZCh5aWVsZF9zdHJlc3NfcG1tYSwgMiksICJNUGFcbiIpCgpgYGAKCiMjIyBFbGFzdGljIFJlZ2lvbiAoVXAgdG8gWWllbGQgU3RyYWluKQpgYGB7cn0KIyBUcnVuY2F0ZSB0byBlYWNoIG1hdGVyaWFsJ3MgZWxhc3RpYyByZWdpb24gKHVwIHRvIHlpZWxkKQp0cnVuY2F0ZV90b195aWVsZCA8LSBmdW5jdGlvbihlcHMsIHNpZ21hLCBzdHJhaW5fbGltaXQpIHsKICBpZHggPC0gd2hpY2goZXBzIDw9IHN0cmFpbl9saW1pdCkKICByZXR1cm4obGlzdChlcHMgPSBlcHNbaWR4XSwgc2lnbWEgPSBzaWdtYVtpZHhdKSkKfQoKIyBUcnVuY2F0ZWQgY3VydmVzCnMxMDE4ICAgICA8LSB0cnVuY2F0ZV90b195aWVsZChlcHNfMTAxOCwgICAgIHNpZ21hX2VuZ18xMDE4LCAgICAgZXBzX3lpZWxkXzEwMTgpCnMxMDQ1X0NSICA8LSB0cnVuY2F0ZV90b195aWVsZChlcHNfMTA0NV9DUiwgIHNpZ21hX2VuZ18xMDQ1X0NSLCAgZXBzX3lpZWxkXzEwNDVfQ1IpCnMxMDQ1X05NICA8LSB0cnVuY2F0ZV90b195aWVsZChlcHNfMTA0NV9OTSwgIHNpZ21hX2VuZ18xMDQ1X05NLCAgZXBzX3lpZWxkXzEwNDVfTk0pCnMzMDQgICAgICA8LSB0cnVuY2F0ZV90b195aWVsZChlcHNfMzA0LCAgICAgIHNpZ21hX2VuZ18zMDQsICAgICAgZXBzX3lpZWxkXzMwNCkKczIwMjQgICAgIDwtIHRydW5jYXRlX3RvX3lpZWxkKGVwc18yMDI0LCAgICAgc2lnbWFfZW5nXzIwMjQsICAgICBlcHNfeWllbGRfMjAyNCkKczcwNzUgICAgIDwtIHRydW5jYXRlX3RvX3lpZWxkKGVwc183MDc1LCAgICAgc2lnbWFfZW5nXzcwNzUsICAgICBlcHNfeWllbGRfNzA3NSkKc2JyYXNzICAgIDwtIHRydW5jYXRlX3RvX3lpZWxkKGVwc19icmFzcywgICAgc2lnbWFfZW5nX2JyYXNzLCAgICBlcHNfeWllbGRfYnJhc3MpCnNwbW1hICAgICA8LSB0cnVuY2F0ZV90b195aWVsZChlcHNfcG1tYSwgICAgIHNpZ21hX2VuZ19wbW1hLCAgICAgZXBzX3lpZWxkX3BtbWEpCgojIFBsb3QKcGxvdCgwLCAwLCB0eXBlID0gIm4iLCB4bGltID0gYygwLCAwLjAxNSksIHlsaW0gPSBjKDAsIDEyMDApLAogICAgIHhsYWIgPSAiU3RyYWluIChtbS9tbSkiLCB5bGFiID0gIlN0cmVzcyAoTVBhKSIsCiAgICAgbWFpbiA9ICJFbGFzdGljIFJlZ2lvbiAoVXAgdG8gWWllbGQgU3RyYWluKSIpCmdyaWQoKQoKIyBBZGQgbGluZXMKbGluZXMoczEwMTgkZXBzLCAgICBzMTAxOCRzaWdtYSwgICAgY29sID0gInN0ZWVsYmx1ZSIsICAgbHdkID0gMykKbGluZXMoczEwNDVfQ1IkZXBzLHMxMDQ1X0NSJHNpZ21hLCBjb2wgPSAiZ3JheTQwIiwgICAgICBsd2QgPSAzKQpsaW5lcyhzMTA0NV9OTSRlcHMsczEwNDVfTk0kc2lnbWEsIGNvbCA9ICJkYXJrb3JhbmdlIiwgIGx3ZCA9IDMpCmxpbmVzKHMzMDQkZXBzLCAgICAgczMwNCRzaWdtYSwgICAgY29sID0gImdvbGQiLCAgICAgICAgbHdkID0gMykKbGluZXMoczIwMjQkZXBzLCAgICBzMjAyNCRzaWdtYSwgICBjb2wgPSAic2t5Ymx1ZSIsICAgICBsd2QgPSAzKQpsaW5lcyhzNzA3NSRlcHMsICAgIHM3MDc1JHNpZ21hLCAgIGNvbCA9ICJkb2RnZXJibHVlIiwgIGx3ZCA9IDMpCmxpbmVzKHNicmFzcyRlcHMsICAgc2JyYXNzJHNpZ21hLCAgY29sID0gImNob2NvbGF0ZSIsICAgbHdkID0gMykKbGluZXMoc3BtbWEkZXBzLCAgICBzcG1tYSRzaWdtYSwgICBjb2wgPSAiZm9yZXN0Z3JlZW4iLCBsd2QgPSAzKQoKIyBMZWdlbmQKbGVnZW5kKCJib3R0b21yaWdodCIsCiAgICAgICBsZWdlbmQgPSBjKCIxMDE4IENSIiwgIjEwNDUgQ1IiLCAiMTA0NSBOTSIsICIzMDQgU1MiLAogICAgICAgICAgICAgICAgICAiMjAyNCBBbHVtaW51bSIsICI3MDc1IEFsdW1pbnVtIiwgIkJyYXNzIiwgIlBNTUEiKSwKICAgICAgIGNvbCA9IGMoInN0ZWVsYmx1ZSIsICJncmF5NDAiLCAiZGFya29yYW5nZSIsICJnb2xkIiwKICAgICAgICAgICAgICAgInNreWJsdWUiLCAiZG9kZ2VyYmx1ZSIsICJjaG9jb2xhdGUiLCAiZm9yZXN0Z3JlZW4iKSwKICAgICAgIGx3ZCA9IDMsIGJ0eSA9ICJuIiwgY2V4ID0gMC45KQoKYGBgCgojIyMgMTAxOENSIFN0ZWVsOiBUZW5zaW9uIHZzIENvbXByZXNzaW9uIChFbmdpbmVlcmluZyBTdHJlc3MtU3RyYWluKQpgYGB7cn0KcGxvdChhYnMoZXBzXzEwMTgpLCBhYnMoc2lnbWFfZW5nXzEwMTgpLCB0eXBlID0gImwiLCBsd2QgPSAyLCBjb2wgPSAiYmx1ZSIsCiAgICAgeGxhYiA9ICJTdHJhaW4gKGFicykiLCB5bGFiID0gIkVuZ2luZWVyaW5nIFN0cmVzcyBbTVBhXSIsCiAgICAgbWFpbiA9ICIxMDE4IENvbGQtUm9sbGVkIFN0ZWVsOiBUZW5zaW9uIHZzIENvbXByZXNzaW9uIikKbGluZXMoYWJzKGVwc18xMDE4X2NvbXApLCBhYnMoc2lnbWFfZW5nXzEwMThfY29tcCksIGNvbCA9ICJyZWQiLCBsd2QgPSAyLCBsdHkgPSAyKQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCJUZW5zaW9uIiwgIkNvbXByZXNzaW9uIiksCiAgICAgICBjb2wgPSBjKCJibHVlIiwgInJlZCIpLCBsdHkgPSBjKDEsIDIpLCBsd2QgPSAyKQpncmlkKCkKYGBgCgojIyMgMjAyNCBBbHVtaW51bTogVGVuc2lvbiB2cyBDb21wcmVzc2lvbiAoRW5naW5lZXJpbmcgU3RyZXNzLVN0cmFpbikKYGBge3J9CnBsb3QoYWJzKGVwc18yMDI0KSwgYWJzKHNpZ21hX2VuZ18yMDI0KSwgdHlwZSA9ICJsIiwgbHdkID0gMiwgY29sID0gImJsdWUiLAogICAgIHhsYWIgPSAiU3RyYWluIChhYnMpIiwgeWxhYiA9ICJFbmdpbmVlcmluZyBTdHJlc3MgW01QYV0iLAogICAgIG1haW4gPSAiMjAyNCBBbHVtaW51bSBBbGxveTogVGVuc2lvbiB2cyBDb21wcmVzc2lvbiIpCmxpbmVzKGFicyhlcHNfMjAyNF9jb21wKSwgYWJzKHNpZ21hX2VuZ18yMDI0X2NvbXApLCBjb2wgPSAicmVkIiwgbHdkID0gMiwgbHR5ID0gMikKbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiVGVuc2lvbiIsICJDb21wcmVzc2lvbiIpLAogICAgICAgY29sID0gYygiYmx1ZSIsICJyZWQiKSwgbHR5ID0gYygxLCAyKSwgbHdkID0gMikKZ3JpZCgpCmBgYAoKCiMjIyBUYWJsZSBSZXBvcnQgSW5mb3JtYXRpb24KYGBge3J9CmNhdCgiRWxhc3RpYyBQcm9wZXJ0aWVzIFN1bW1hcnkgKEUgaW4gR1BhLCBTdHJlc3MgaW4gTVBhKTpcblxuIikKY2F0KHNwcmludGYoIiUtMThzIHwgRSA9ICU5LjJmIHwgWWllbGQgU3RyYWluID0gJS41ZiB8IFlpZWxkIFN0cmVzcyA9ICU3LjJmIHwgVWx0aW1hdGUgU3RyZW5ndGggPSAlNy4yZlxuIiwKICAgICIxMDE4IFN0ZWVsIENSIiwgICAgIEVfMTAxOCAvIDEwMDAsICAgICB5aWVsZF9zdHJhaW5fMTAxOCwgICAgIHlpZWxkX3N0cmVzc18xMDE4LCAgICAgdWx0aW1hdGVfMTAxOCkpCmNhdChzcHJpbnRmKCIlLTE4cyB8IEUgPSAlOS4yZiB8IFlpZWxkIFN0cmFpbiA9ICUuNWYgfCBZaWVsZCBTdHJlc3MgPSAlNy4yZiB8IFVsdGltYXRlIFN0cmVuZ3RoID0gJTcuMmZcbiIsCiAgICAiMTA0NSBTdGVlbCBDUiIsICAgICBFXzEwNDVfQ1IgLyAxMDAwLCAgeWllbGRfc3RyYWluXzEwNDVfQ1IsICB5aWVsZF9zdHJlc3NfMTA0NV9DUiwgIHVsdGltYXRlXzEwNDVfQ1IpKQpjYXQoc3ByaW50ZigiJS0xOHMgfCBFID0gJTkuMmYgfCBZaWVsZCBTdHJhaW4gPSAlLjVmIHwgWWllbGQgU3RyZXNzID0gJTcuMmYgfCBVbHRpbWF0ZSBTdHJlbmd0aCA9ICU3LjJmXG4iLAogICAgIjEwNDUgU3RlZWwgTk0iLCAgICAgRV8xMDQ1X05NIC8gMTAwMCwgIHlpZWxkX3N0cmFpbl8xMDQ1X05NLCAgeWllbGRfc3RyZXNzXzEwNDVfTk0sICB1bHRpbWF0ZV8xMDQ1X05NKSkKY2F0KHNwcmludGYoIiUtMThzIHwgRSA9ICU5LjJmIHwgWWllbGQgU3RyYWluID0gJS41ZiB8IFlpZWxkIFN0cmVzcyA9ICU3LjJmIHwgVWx0aW1hdGUgU3RyZW5ndGggPSAlNy4yZlxuIiwKICAgICIzMDQgU1MiLCAgICAgICAgICAgIEVfMzA0IC8gMTAwMCwgICAgICB5aWVsZF9zdHJhaW5fMzA0LCAgICAgIHlpZWxkX3N0cmVzc18zMDQsICAgICAgdWx0aW1hdGVfMzA0KSkKY2F0KHNwcmludGYoIiUtMThzIHwgRSA9ICU5LjJmIHwgWWllbGQgU3RyYWluID0gJS41ZiB8IFlpZWxkIFN0cmVzcyA9ICU3LjJmIHwgVWx0aW1hdGUgU3RyZW5ndGggPSAlNy4yZlxuIiwKICAgICIyMDI0IEFsdW1pbnVtIiwgICAgIEVfMjAyNCAvIDEwMDAsICAgICB5aWVsZF9zdHJhaW5fMjAyNCwgICAgIHlpZWxkX3N0cmVzc18yMDI0LCAgICAgdWx0aW1hdGVfMjAyNCkpCmNhdChzcHJpbnRmKCIlLTE4cyB8IEUgPSAlOS4yZiB8IFlpZWxkIFN0cmFpbiA9ICUuNWYgfCBZaWVsZCBTdHJlc3MgPSAlNy4yZiB8IFVsdGltYXRlIFN0cmVuZ3RoID0gJTcuMmZcbiIsCiAgICAiNzA3NSBBbHVtaW51bSIsICAgICBFXzcwNzUgLyAxMDAwLCAgICAgeWllbGRfc3RyYWluXzcwNzUsICAgICB5aWVsZF9zdHJlc3NfNzA3NSwgICAgIHVsdGltYXRlXzcwNzUpKQpjYXQoc3ByaW50ZigiJS0xOHMgfCBFID0gJTkuMmYgfCBZaWVsZCBTdHJhaW4gPSAlLjVmIHwgWWllbGQgU3RyZXNzID0gJTcuMmYgfCBVbHRpbWF0ZSBTdHJlbmd0aCA9ICU3LjJmXG4iLAogICAgIkFubmVhbGVkIEJyYXNzIiwgICAgRV9icmFzcyAvIDEwMDAsICAgIHlpZWxkX3N0cmFpbl9icmFzcywgICAgeWllbGRfc3RyZXNzX2JyYXNzLCAgICB1bHRpbWF0ZV9icmFzcykpCmNhdChzcHJpbnRmKCIlLTE4cyB8IEUgPSAlOS4yZiB8IFlpZWxkIFN0cmFpbiA9ICUuNWYgfCBZaWVsZCBTdHJlc3MgPSAlNy4yZiB8IFVsdGltYXRlIFN0cmVuZ3RoID0gJTcuMmZcbiIsCiAgICAiUE1NQSIsICAgICAgICAgICAgICBFX3BtbWEgLyAxMDAwLCAgICAgeWllbGRfc3RyYWluX3BtbWEsICAgICB5aWVsZF9zdHJlc3NfcG1tYSwgICAgIHVsdGltYXRlX3BtbWEpKQpgYGAKCiMjIyBIZWxwZXIgRnVuY3Rpb246IENvbXB1dGUgSywgbiBmcm9tIHRydWUgc3RyZXNzL3RydWUgcGxhc3RpYyBzdHJhaW4gKFJhbWJlcmfigJNPc2dvb2QpCmBgYHtyfQpmaXRfcG93ZXJsYXcgPSBmdW5jdGlvbihlcHNfZW5nLCBlcHNfdHJ1ZSwgc2lnbWFfdHJ1ZSwgRV9NUGEsCiAgICAgICAgICAgICAgICAgICAgICAgICB5aWVsZF9zdHJhaW4sIHNpZ21hX2VuZywKICAgICAgICAgICAgICAgICAgICAgICAgIG1pbl9lcCA9IDFlLTUpIHsKCiAgIyBJbmRleCBJbnRlcnZhbCBmcm9tIHlpZWxkIHRvIFVUUyAocHJlLW5lY2tpbmcpCiAgaV9zdGFydCA8LSB3aGljaChlcHNfZW5nID49IHlpZWxkX3N0cmFpbilbMV0KICBpX2VuZCAgIDwtIHdoaWNoLm1heChzaWdtYV9lbmcpCiAgIyBpX3N0YXJ0OiBmaXJzdCBpbmRleCB3aGVyZSBlbmdpbmVlcmluZyBzdHJhaW4gcmVhY2hlcyB5aWVsZCDihpIgYmVnaW5uaW5nIG9mIHBsYXN0aWMgZGVmb3JtYXRpb24KICAjIGlfZW5kOiB3aGVyZSBlbmdpbmVlcmluZyBzdHJlc3MgcmVhY2hlcyBpdHMgbWF4aW11bSDihpIgbmVja2luZyB1c3VhbGx5IHN0YXJ0cyBoZXJlCiAgCiAgIyMgcHJlLWNhdXRpb24gY2hlY2sKICBpZiAoaXMubmEoaV9zdGFydCkpIGlfc3RhcnQgPC0gMQogIGlmIChpcy5uYShpX2VuZCkgfHwgaV9lbmQgPCBpX3N0YXJ0KSBpX2VuZCA8LSBsZW5ndGgoZXBzX3RydWUpCgogICMgc3RyZXNzIGhhcmRlbmluZyBwaGFzZSBpbmRleCByYW5nZQogIGlkeCA8LSBpX3N0YXJ0OmlfZW5kCgogICMgVHJ1ZSBwbGFzdGljIHN0cmFpbntzdHJhaW4taGFyZGVuaW5nIGludGVydmFsfQogIGVwc19wX3RydWUgPC0gZXBzX3RydWVbaWR4XSAtIHNpZ21hX3RydWVbaWR4XSAvIEVfTVBhCiAgc2lnbWFfdCAgICA8LSBzaWdtYV90cnVlW2lkeF0KCiAgIyBwcmUtY2F1dGlvbiBjaGVjaywgb25seSBrZWVwIHZhbGlkIGFuZCBwb3NpdGl2ZSBwbGFzdGljIHN0cmFpbgogIGtlZXAgPC0gaXMuZmluaXRlKGVwc19wX3RydWUpICYgaXMuZmluaXRlKHNpZ21hX3QpICYKICAgICAgICAgIGVwc19wX3RydWUgPiBtaW5fZXAgJiBzaWdtYV90ID4gMAogIGVwc19wX3RydWUgPC0gZXBzX3BfdHJ1ZVtrZWVwXQogIHNpZ21hX3QgICAgPC0gc2lnbWFfdFtrZWVwXQoKICAjIExpbmVhciBmaXQgaW4gbG9nLWxvZyBzcGFjZTogbG9nIM+DID0gbG9nIEsgKyBuIGxvZyDOtV9wCiAgZml0IDwtIGxtKGxvZyhzaWdtYV90KSB+IGxvZyhlcHNfcF90cnVlKSkKICBuICAgPC0gdW5uYW1lKGNvZWYoZml0KVsyXSkKICBLICAgPC0gdW5uYW1lKGV4cChjb2VmKGZpdClbMV0pKSAjIE1QYQoKICBsaXN0KEsgPSBLLCBuID0gbiwKICAgICAgIGlkeF9yYW5nZSA9IGMoaV9zdGFydCwgaV9lbmQpLAogICAgICAgZml0ID0gZml0LAogICAgICAgZXBzX3BfdHJ1ZSA9IGVwc19wX3RydWUsIHNpZ21hX3QgPSBzaWdtYV90KQp9CmBgYAoKCmBgYHtyfQojIyAtLS0tIDcwNzUgQWx1bWludW0gLS0tLQpyZXNfNzA3NSA8LSBmaXRfcG93ZXJsYXcoCiAgZXBzX2VuZyAgICA9IGVwc183MDc1LAogIGVwc190cnVlICAgPSBlcHNfdHJ1ZV83MDc1LAogIHNpZ21hX3RydWUgPSBzaWdtYV90cnVlXzcwNzUsCiAgRV9NUGEgICAgICA9IEVfNzA3NSwgICAgICAgICAgICAgIyBFIGluIE1QYQogIHlpZWxkX3N0cmFpbiA9IHlpZWxkX3N0cmFpbl83MDc1LAogIHNpZ21hX2VuZyAgPSBzaWdtYV9lbmdfNzA3NQopCgojIyAtLS0tIEFubmVhbGVkIEJyYXNzIC0tLS0KcmVzX2JyYXNzIDwtIGZpdF9wb3dlcmxhdygKICBlcHNfZW5nICAgID0gZXBzX2JyYXNzLAogIGVwc190cnVlICAgPSBlcHNfdHJ1ZV9icmFzcywKICBzaWdtYV90cnVlID0gc2lnbWFfdHJ1ZV9icmFzcywKICBFX01QYSAgICAgID0gRV9icmFzcywgICAgICAgICAgICAjIEUgaW4gTVBhCiAgeWllbGRfc3RyYWluID0geWllbGRfc3RyYWluX2JyYXNzLAogIHNpZ21hX2VuZyAgPSBzaWdtYV9lbmdfYnJhc3MKKQpgYGAKCgpgYGB7cn0KIyMgLS0tIFBsb3Q6IEFubmVhbGVkIEJyYXNzIGxvZ+KAk2xvZyBmaXQgLS0tCiMgU2NhdHRlciBwbG90IG9mIGxvZyh0cnVlIHBsYXN0aWMgc3RyYWluKSB2cy4gbG9nKHRydWUgc3RyZXNzKQojIFRoaXMgc2hvd3MgdGhlIGV4cGVyaW1lbnRhbCBkYXRhIGluIGxvZy1sb2cgc3BhY2UKcGxvdChsb2cocmVzX2JyYXNzJGVwc19wX3RydWUpLCBsb2cocmVzX2JyYXNzJHNpZ21hX3QpLAogICAgIHhsYWIgPSAibG9nKFRydWUgcGxhc3RpYyBzdHJhaW4pIiwKICAgICB5bGFiID0gImxvZyhUcnVlIHN0cmVzcykgW01QYV0iLAogICAgIG1haW4gPSAiQW5uZWFsZWQgQnJhc3M6IGxvZ+KAk2xvZyBmaXQiLAogICAgIHBjaCA9IDE2KQoKIyBBZGQgZGFzaGVkIGxpbmU6IGxpbmVhciByZWdyZXNzaW9uIGZpdCB0byB0aGUgbG9nLWxvZyBkYXRhCiMgVGhpcyBsaW5lIHJlcHJlc2VudHMgbG9nKM+DX3QpID0gbG9nKEspICsgbiAqIGxvZyjOtV9wKQojIFRoZSBzbG9wZSA9IG4gKHN0cmFpbiBoYXJkZW5pbmcgZXhwb25lbnQpLCBpbnRlcmNlcHQgPSBsb2coSykKYWJsaW5lKHJlc19icmFzcyRmaXQsIGx3ZCA9IDIsIGx0eSA9IDIpCgojIyAtLS0gUGxvdDogNzA3NSBBbHVtaW51bSBsb2figJNsb2cgZml0IC0tLQpwbG90KGxvZyhyZXNfNzA3NSRlcHNfcF90cnVlKSwgbG9nKHJlc183MDc1JHNpZ21hX3QpLAogICAgIHhsYWIgPSAibG9nKFRydWUgcGxhc3RpYyBzdHJhaW4pIiwKICAgICB5bGFiID0gImxvZyhUcnVlIHN0cmVzcykgW01QYV0iLAogICAgIG1haW4gPSAiNzA3NSBBbHVtaW51bTogbG9n4oCTbG9nIGZpdCIsCiAgICAgcGNoID0gMTYpCmFibGluZShyZXNfNzA3NSRmaXQsIGx3ZCA9IDIsIGx0eSA9IDIpCgoKIyMgRGF0YSBSZXBvcnQKY2F0KCJcblJhbWJlcmfigJNPc2dvb2QgcGFyYW1ldGVycyAoz4NfdHJ1ZSA9IEsgKiDOtV9wX3RydWVebik6XG4iKQpjYXQoc3ByaW50ZigiICBBbm5lYWxlZCBCcmFzcyA6IEsgPSAlLjJmIE1QYSwgbiA9ICUuNGZcbiIsIHJlc19icmFzcyRLLCByZXNfYnJhc3MkbikpCmNhdChzcHJpbnRmKCIgIDcwNzUgQWx1bWludW0gIDogSyA9ICUuMmYgTVBhLCBuID0gJS40ZlxuIiwgcmVzXzcwNzUkSywgcmVzXzcwNzUkbikpCgpgYGAKCg==