5.1
Given the fitted response function
\[\begin{aligned}
\hat{y} = 72.0 + 3.6x_1 - 2.5x_2
\end{aligned}\]
which is found to fit well in a localized region of \((x_1, x_2)\).
- Plot contours of constant response, \(y\), in the \((x_1, x_2)\) plane.
library(plotly)
x1 <- seq(0, 10, by=0.1)
x2 <- seq(0, 10, by=0.1)
y <- 72 +3.6*x1-2.5*x2
z <- cbind(x1, x2, y)
p <- plot_ly(z = z) %>% add_surface()
p
- Calculate and plot the path of the steepest ascend generated from this response function. Use \(x_1\) to determine the path, with \(\Delta x_1 = 1\).
library(qualityTools)
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 72 +3.6*dset$A-2.5*dset$B
response(set) <- y
set
sa <- steepAscent(factors = c("A", "B"), response="y", data=set)
Steepest Ascent for set
sa_set <- as.data.frame(sa)
y_hat <- 72 +3.6*sa_set$A.real-2.5*sa_set$B.real
response(sa) <- y_hat
sa
plot(sa)

5.2
Suppose a fitted first-order model is given by:
\[\begin{aligned}
y=25+4x_1+3x_2-2.5x_3
\end{aligned}\]
Suppose we wish to maximize the response. Calculate several points along the path of the steepest ascent
set <- facDesign(k=3)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 25+4*dset$A+3*dset$B-2.5*dset$C
response(set) <- y
set
sa <- steepAscent(factors = c("A", "B", "C"), response="y", data=set)
Steepest Ascent for set
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
plot(sa)

5.3
Reconsider the model in Exercise 5.1. Construct a path of steepest ascent, using \(x_2\) to define the path, with \(\Delta x_2=1\)
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 72 +3.6*dset$A-2.5*dset$B
response(set) <- y
sa_1 <- steepAscent(factors = c("A", "B"), response="y", data=set)
Steepest Ascent for set
sa_1_set <- as.data.frame(sa_1)
y_hat <- 72 +3.6*sa_1_set$A.real-2.5*sa_1_set$B.real
response(sa_1) <- y_hat
sa_2 <- steepAscent(factors = c("B", "A"), response="y", data=set)
Steepest Ascent for set
sa_2_set <- as.data.frame(sa_2)
y_hat <- 72 +3.6*sa_2_set$A.real-2.5*sa_2_set$B.real
response(sa_2) <- y_hat
d_sa2 <- as.data.frame(sa_2)
plot(sa_1, type="b")
lines(d_sa2$Delta,d_sa2$y_hat, col="blue", type="b", lty=2)
legend(0, 76,legend = c("Delta X1", "Delta X2"), col=c("black", "blue"), lty=1:2)

- How different are the two paths that you have constructed?
\(\Delta x_2\) has bigger values faster than \(\Delta x_1\)
5.4
Consider the injection molding experiment in Example 5.2
- Use the coded design units to determine how far the points Base \(+4\Delta\) is from the design center.
set <- facDesign(k=3)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 25+4*dset$A+3*dset$B-2.5*dset$C
response(set) <- y
sa <- steepAscent(factors = c("A", "B", "C"), size=4, response="y", data=set)
Steepest Ascent for set
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
sa_original <- steepAscent(factors = c("A", "B", "C"), response="y", data=set)
Steepest Ascent for set
d_sa <- as.data.frame(sa_original)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa_original) <- y_hat
sa_original
d_sa_original <- as.data.frame(sa_original)
plot(sa, type="b")
lines(d_sa_original$Delta,d_sa_original$y_hat, col="blue", type="b", lty=2)
legend(0, 76,legend = c("+4 Delta", "+1 Delta"), col=c("black", "blue"), lty=1:2)

- Suppose that we had selected \(x_2\) to express the points on the path of steepest descent with \(\Delta x_2=1\). Recompute the points in Table E5.4. Use the point Base \(+4\Delta\), and compute the distance of this point from the design center.
set <- facDesign(k=3)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
dset <- as.data.frame(set)
y <- 25+4*dset$A+3*dset$B-2.5*dset$C
response(set) <- y
sa <- steepAscent(factors = c("B", "A", "C"), size=4, response="y", data=set)
Steepest Ascent for set
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
d_sa <- as.data.frame(sa)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa) <- y_hat
sa
sa_original <- steepAscent(factors = c("B", "A", "C"), response="y", data=set)
Steepest Ascent for set
d_sa <- as.data.frame(sa_original)
y_hat <- 25+4*d_sa$A.real+3*d_sa$B.real-2.5*d_sa$C.real
response(sa_original) <- y_hat
sa_original
d_sa_original <- as.data.frame(sa_original)
plot(sa, type="b")
lines(d_sa_original$Delta,d_sa_original$y_hat, col="blue", type="b", lty=2)
legend(0, 76,legend = c("+4 Delta", "+1 Delta"), col=c("black", "blue"), lty=1:2)

- How different are the two points you have computed?
The points have the same center in 25, but then the dispersion is really big being \(+4\Delta\) having a value of 225 units, meanwhile the default \(\Delta\) only reaches until 33 untis.
5.5
In a metallurgy experiment it is desired to test the effect of four factors and their interactions on the concentration (percent by weight) of a particular phosphorus compound in costing material. The variables are: A, percent phosphorus in the refinement; B, percent remelted material; C, fluxing time, and D, holding time. The four factors are varied in a 24 factorial experiment with two castings taken at each factor combination. The 32 castings were made in random order, and the data are shown in this table:
| (1) |
30.3 |
28.6 |
58.9 |
| a |
28.5 |
31.4 |
59.9 |
| b |
24.5 |
25.6 |
50.1 |
| ab |
25.9 |
27.2 |
53.1 |
| c |
24.8 |
23.4 |
48.2 |
| ac |
26.9 |
23.8 |
50.7 |
| bc |
24.8 |
27.8 |
52.6 |
| abc |
22.2 |
24.9 |
47.1 |
| d |
31.7 |
33.5 |
65.2 |
| ad |
24.6 |
26.2 |
50.8 |
| bd |
27.6 |
30.6 |
58.2 |
| abd |
26.3 |
27.8 |
54.1 |
| cd |
29.9 |
27.7 |
57.6 |
| acd |
26.8 |
24.2 |
51.0 |
| bcd |
26.4 |
24.9 |
51.3 |
| abcd |
26.9 |
29.3 |
56.2 |
| Total |
428.1 |
436.9 |
865.0 |
results <- c (58.9, 59.9, 50.1, 53.1, 48.2, 50.7, 52.6, 47.1, 65.2, 50.8, 58.2, 54.1, 57.6, 51, 51.3, 56.2, 865)
set <- facDesign(k=4)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
total <- results[unlist(runOrd(set))]
response(set) <- total
set
With the table we need to create the function using lm
df <- as.data.frame(data)
func <- lm(total ~ A + B + C + D, data=df)
func
Call:
lm(formula = total ~ A + B + C + D, data = df)
Coefficients:
(Intercept) A B C D
54.0625 -1.4375 -0.3750 0.3875 0.3500
With this we get the final equation which is:
\[\begin{aligned}
y = 54.0625 -1.4375x_1 - 0.3750x_2 + 0.3875x_3 + 0.3500x_4
\end{aligned}\]
- Construct a table of the path of steepest ascent in the coded design variables.
sa <- steepAscent(factors = c("A", "B", "C","D"), response="total", data=data)
Steepest Ascent for data
d_sa <- as.data.frame(sa)
y_hat <- 54.0625 - 1.4375*d_sa$A.coded - 0.3750*d_sa$B.coded + 0.3875*d_sa$C.coded + 0.35*d_sa$D.coded
response(sa) <- y_hat
sa
5.6
Consider the \(2^2\) factorial design featured in the illustration in Figure 3.1 in Chapter 3. Factor A is the concentration of a reactant, factor B is the feed rate, and the response is the viscosity of the output material. As one can tell by the computed effects and the analysis of variance shown, the main effects dominate in the analysis. Using the following table:
| A low, B low |
145 |
148 |
147 |
140 |
580 |
| A high, B low |
158 |
152 |
155 |
152 |
617 |
| A low, B high |
135 |
138 |
141 |
139 |
553 |
| A high, B high |
150 |
152 |
146 |
149 |
597 |
- Fit a first-order model
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
total <- c(553, 617, 597, 580)
response(set) <- total
set
Now we create the function using a lineal regresion
lm_source <- as.data.frame(set)
lm_model <- lm(total~A+B, data=lm_source)
lm_model
Call:
lm(formula = total ~ A + B, data = lm_source)
Coefficients:
(Intercept) A B
586.75 20.25 -11.75
So the function is:
\[\begin{aligned}
y = 586.75 + 20.25x_1 - 11.75x_2
\end{aligned}\]
- Compute and plot the path of steepest ascent.
sa <- steepAscent(factors = c("A", "B"), response="total", data=set)
Steepest Ascent for set
sa_source <- as.data.frame(sa)
y_hat <- 586.75 + 20.25*sa_source$A.real - 11.75*sa_source$B.real
response(sa) <- y_hat
sa
c)Suppose that in the metric of the coded variables, the concentration cannot exceed 3.5 and the feed rate cannot go below -2.7. Show the practical path of steepest ascent—that is, the path that takes account of these constraints.
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
total <- c(553, 617, 597, 580)
response(set) <- total
lows(set) <- c(-2.7, -2.7)
highs(set) <- c(3.5, 3.5)
set
sa <- steepAscent(factors = c("A", "B"), size=0.1, response="total", data=set)
Steepest Ascent for set
sa_source <- as.data.frame(sa)
y_hat <- 586.75 + 20.25*sa_source$A.real - 11.75*sa_source$B.real
response(sa) <- y_hat
sa
5.7
It is stated in the text that the development of the path of steepest ascent makes use of the assumption that the model is truly first-order in nature. However, even if there is a modest amount of curvature or interaction in the system, the use of steepest ascent can be extremely useful in determining a future experimental region. Suppose that in a system involving \(x_1\) and \(x_2\) the actual model is given by:
\[\begin{aligned}
E(y) = 14 + 5x_1 - 10x_2 + 3x_1x_2
\end{aligned}\]
Assume that \(x_1\) and \(x_2\) are in coded form:
- Show a plot of the path of steepest ascent (based on actual parameters) if the interaction is ignored.
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
set_source <- as.data.frame(set)
e_y <- 14 + 5*set_source$A - 10*set_source$B
response(set) <- e_y
sa_linear <- steepAscent(factors = c("A", "B"), response="e_y", data=set)
Steepest Ascent for set
sa_source <- as.data.frame(sa_linear)
y_hat <- 14 + 5*sa_source$A.coded - 10*sa_source$B.coded
response(sa_linear) <- y_hat
plot(sa_linear, type="b")

- Show a plot of the path of steepest ascent for the model with interaction. Note that this path is not linear
set <- facDesign(k=2)
implicit list embedding of S4 objects is deprecatedimplicit list embedding of S4 objects is deprecated
set_source <- as.data.frame(set)
e_y <- 14 + 5*set_source$A - 10*set_source$B + 3*set_source$A*set_source$B
response(set) <- e_y
sa_interaction <- steepAscent(factors = c("A", "B"), response="e_y", data=set)
Steepest Ascent for set
sa_source <- as.data.frame(sa_interaction)
y_hat <- 14 + 5*sa_source$A.coded - 10*sa_source$B.coded + 3*sa_source$A.coded*sa_source$B.coded
response(sa_interaction) <- y_hat
plot(sa_interaction, type="b")

- Comment on the difference in the two paths.
This Graph explains better the difference
sa_interaction_source <- as.data.frame(sa_interaction)
plot(sa_linear, type="b")
lines(sa_interaction_source$Delta,sa_interaction_source$y_hat, col="blue", type="b", lty=2)
legend(0, 35,legend = c("No Interaction", "Interaction"), col=c("black", "blue"), lty=1:2)

LS0tCnRpdGxlOiAiRWNvbm9tZXRyaWEgMiwgUHJveWVjdG8iCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMjIyA1LjEgCgpHaXZlbiB0aGUgZml0dGVkIHJlc3BvbnNlIGZ1bmN0aW9uCgpcYmVnaW57YWxpZ25lZH0KICBcaGF0e3l9ID0gNzIuMCArIDMuNnhfMSAtIDIuNXhfMgpcZW5ke2FsaWduZWR9Cgp3aGljaCBpcyBmb3VuZCB0byBmaXQgd2VsbCBpbiBhIGxvY2FsaXplZCByZWdpb24gb2YgJCh4XzEsIHhfMikkLgoKYSkgUGxvdCBjb250b3VycyBvZiBjb25zdGFudCByZXNwb25zZSwgJHkkLCBpbiB0aGUgJCh4XzEsIHhfMikkIHBsYW5lLgoKYGBge3J9CmxpYnJhcnkocGxvdGx5KQp4MSA8LSBzZXEoMCwgMTAsIGJ5PTAuMSkKeDIgPC0gc2VxKDAsIDEwLCBieT0wLjEpCnkgPC0gNzIgKzMuNip4MS0yLjUqeDIKCnogPC0gY2JpbmQoeDEsIHgyLCB5KQoKcCA8LSBwbG90X2x5KHogPSB6KSAlPiUgYWRkX3N1cmZhY2UoKQpwCmBgYAoKYikgQ2FsY3VsYXRlIGFuZCBwbG90IHRoZSBwYXRoIG9mIHRoZSBzdGVlcGVzdCBhc2NlbmQgZ2VuZXJhdGVkIGZyb20gdGhpcyByZXNwb25zZSBmdW5jdGlvbi4gVXNlICR4XzEkIHRvIGRldGVybWluZSB0aGUgcGF0aCwgd2l0aCAkXERlbHRhIHhfMSA9IDEkLgoKYGBge3J9CmxpYnJhcnkocXVhbGl0eVRvb2xzKQoKc2V0IDwtIGZhY0Rlc2lnbihrPTIpCgpkc2V0IDwtIGFzLmRhdGEuZnJhbWUoc2V0KQoKCnkgPC0gNzIgKzMuNipkc2V0JEEtMi41KmRzZXQkQgoKcmVzcG9uc2Uoc2V0KSA8LSB5CgpzZXQKYGBgCmBgYHtyfQpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpzYV9zZXQgPC0gYXMuZGF0YS5mcmFtZShzYSkKCnlfaGF0IDwtIDcyICszLjYqc2Ffc2V0JEEucmVhbC0yLjUqc2Ffc2V0JEIucmVhbAoKcmVzcG9uc2Uoc2EpIDwtIHlfaGF0CnNhCmBgYApgYGB7cn0KcGxvdChzYSkKYGBgCgojIyMgNS4yCgpTdXBwb3NlIGEgZml0dGVkIGZpcnN0LW9yZGVyIG1vZGVsIGlzIGdpdmVuIGJ5OgoKXGJlZ2lue2FsaWduZWR9CiAgeT0yNSs0eF8xKzN4XzItMi41eF8zClxlbmR7YWxpZ25lZH0KClN1cHBvc2Ugd2Ugd2lzaCB0byBtYXhpbWl6ZSB0aGUgcmVzcG9uc2UuIENhbGN1bGF0ZSBzZXZlcmFsIHBvaW50cyBhbG9uZyB0aGUgcGF0aCBvZiB0aGUgc3RlZXBlc3QgYXNjZW50CgpgYGB7cn0Kc2V0IDwtIGZhY0Rlc2lnbihrPTMpCmRzZXQgPC0gYXMuZGF0YS5mcmFtZShzZXQpCgp5IDwtIDI1KzQqZHNldCRBKzMqZHNldCRCLTIuNSpkc2V0JEMKCnJlc3BvbnNlKHNldCkgPC0geQoKc2V0CmBgYApgYGB7cn0Kc2EgPC0gc3RlZXBBc2NlbnQoZmFjdG9ycyA9IGMoIkEiLCAiQiIsICJDIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpkX3NhIDwtIGFzLmRhdGEuZnJhbWUoc2EpCgp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCgpyZXNwb25zZShzYSkgPC0geV9oYXQKCnNhCmBgYAoKYGBge3J9CnBsb3Qoc2EpCmBgYAoKIyMjIDUuMwoKUmVjb25zaWRlciB0aGUgbW9kZWwgaW4gRXhlcmNpc2UgNS4xLiBDb25zdHJ1Y3QgYSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudCwgdXNpbmcgJHhfMiQgdG8gZGVmaW5lIHRoZSBwYXRoLCB3aXRoICRcRGVsdGEgeF8yPTEkCgphKSAKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0yKQoKZHNldCA8LSBhcy5kYXRhLmZyYW1lKHNldCkKCgp5IDwtIDcyICszLjYqZHNldCRBLTIuNSpkc2V0JEIKCnJlc3BvbnNlKHNldCkgPC0geQoKc2FfMSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpzYV8xX3NldCA8LSBhcy5kYXRhLmZyYW1lKHNhXzEpCgp5X2hhdCA8LSA3MiArMy42KnNhXzFfc2V0JEEucmVhbC0yLjUqc2FfMV9zZXQkQi5yZWFsCgpyZXNwb25zZShzYV8xKSA8LSB5X2hhdAoKc2FfMiA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQiIsICJBIiksIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCgpzYV8yX3NldCA8LSBhcy5kYXRhLmZyYW1lKHNhXzIpCgp5X2hhdCA8LSA3MiArMy42KnNhXzJfc2V0JEEucmVhbC0yLjUqc2FfMl9zZXQkQi5yZWFsCgpyZXNwb25zZShzYV8yKSA8LSB5X2hhdAoKZF9zYTIgPC0gYXMuZGF0YS5mcmFtZShzYV8yKQoKcGxvdChzYV8xLCB0eXBlPSJiIikKbGluZXMoZF9zYTIkRGVsdGEsZF9zYTIkeV9oYXQsIGNvbD0iYmx1ZSIsIHR5cGU9ImIiLCBsdHk9MikKbGVnZW5kKDAsIDc2LGxlZ2VuZCA9IGMoIkRlbHRhIFgxIiwgIkRlbHRhIFgyIiksIGNvbD1jKCJibGFjayIsICJibHVlIiksIGx0eT0xOjIpCmBgYAoKYikgSG93IGRpZmZlcmVudCBhcmUgdGhlIHR3byBwYXRocyB0aGF0IHlvdSBoYXZlIGNvbnN0cnVjdGVkPwoKKiokXERlbHRhIHhfMiQgaGFzIGJpZ2dlciB2YWx1ZXMgZmFzdGVyIHRoYW4gJFxEZWx0YSB4XzEkKioKCiMjIyA1LjQKCkNvbnNpZGVyIHRoZSBpbmplY3Rpb24gbW9sZGluZyBleHBlcmltZW50IGluIEV4YW1wbGUgNS4yCgphKSBVc2UgdGhlIGNvZGVkIGRlc2lnbiB1bml0cyB0byBkZXRlcm1pbmUgaG93IGZhciB0aGUgcG9pbnRzIEJhc2UgJCs0XERlbHRhJCBpcyBmcm9tIHRoZSBkZXNpZ24gY2VudGVyLgoKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0zKQpkc2V0IDwtIGFzLmRhdGEuZnJhbWUoc2V0KQoKeSA8LSAyNSs0KmRzZXQkQSszKmRzZXQkQi0yLjUqZHNldCRDCgpyZXNwb25zZShzZXQpIDwtIHkKCnNhIDwtIHN0ZWVwQXNjZW50KGZhY3RvcnMgPSBjKCJBIiwgIkIiLCAiQyIpLCBzaXplPTQsIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCmRfc2EgPC0gYXMuZGF0YS5mcmFtZShzYSkKeV9oYXQgPC0gMjUrNCpkX3NhJEEucmVhbCszKmRfc2EkQi5yZWFsLTIuNSpkX3NhJEMucmVhbApyZXNwb25zZShzYSkgPC0geV9oYXQKc2EKYGBgCmBgYHtyfQpzYV9vcmlnaW5hbCA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiwgIkMiKSwgcmVzcG9uc2U9InkiLCBkYXRhPXNldCkKZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhX29yaWdpbmFsKQp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCnJlc3BvbnNlKHNhX29yaWdpbmFsKSA8LSB5X2hhdApzYV9vcmlnaW5hbApgYGAKCmBgYHtyfQpkX3NhX29yaWdpbmFsIDwtIGFzLmRhdGEuZnJhbWUoc2Ffb3JpZ2luYWwpCgpwbG90KHNhLCB0eXBlPSJiIikKbGluZXMoZF9zYV9vcmlnaW5hbCREZWx0YSxkX3NhX29yaWdpbmFsJHlfaGF0LCBjb2w9ImJsdWUiLCB0eXBlPSJiIiwgbHR5PTIpCmxlZ2VuZCgwLCA3NixsZWdlbmQgPSBjKCIrNCBEZWx0YSIsICIrMSBEZWx0YSIpLCBjb2w9YygiYmxhY2siLCAiYmx1ZSIpLCBsdHk9MToyKQpgYGAKCmIpIFN1cHBvc2UgdGhhdCB3ZSBoYWQgc2VsZWN0ZWQgJHhfMiQgdG8gZXhwcmVzcyB0aGUgcG9pbnRzIG9uIHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGRlc2NlbnQgd2l0aCAgJFxEZWx0YSB4XzI9MSQuIFJlY29tcHV0ZSB0aGUgcG9pbnRzIGluIFRhYmxlIEU1LjQuIFVzZSB0aGUgcG9pbnQgQmFzZSAkKzRcRGVsdGEkLCBhbmQgY29tcHV0ZSB0aGUgZGlzdGFuY2Ugb2YgdGhpcyBwb2ludCBmcm9tIHRoZSBkZXNpZ24gY2VudGVyLgoKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0zKQpkc2V0IDwtIGFzLmRhdGEuZnJhbWUoc2V0KQoKeSA8LSAyNSs0KmRzZXQkQSszKmRzZXQkQi0yLjUqZHNldCRDCgpyZXNwb25zZShzZXQpIDwtIHkKCnNhIDwtIHN0ZWVwQXNjZW50KGZhY3RvcnMgPSBjKCJCIiwgIkEiLCAiQyIpLCBzaXplPTQsIHJlc3BvbnNlPSJ5IiwgZGF0YT1zZXQpCmRfc2EgPC0gYXMuZGF0YS5mcmFtZShzYSkKeV9oYXQgPC0gMjUrNCpkX3NhJEEucmVhbCszKmRfc2EkQi5yZWFsLTIuNSpkX3NhJEMucmVhbApyZXNwb25zZShzYSkgPC0geV9oYXQKc2EKYGBgCgpgYGB7cn0KZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhKQp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCnJlc3BvbnNlKHNhKSA8LSB5X2hhdApzYQpgYGAKCmBgYHtyfQpzYV9vcmlnaW5hbCA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQiIsICJBIiwgIkMiKSwgcmVzcG9uc2U9InkiLCBkYXRhPXNldCkKZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhX29yaWdpbmFsKQp5X2hhdCA8LSAyNSs0KmRfc2EkQS5yZWFsKzMqZF9zYSRCLnJlYWwtMi41KmRfc2EkQy5yZWFsCnJlc3BvbnNlKHNhX29yaWdpbmFsKSA8LSB5X2hhdApzYV9vcmlnaW5hbApgYGAKCmBgYHtyfQpkX3NhX29yaWdpbmFsIDwtIGFzLmRhdGEuZnJhbWUoc2Ffb3JpZ2luYWwpCnBsb3Qoc2EsIHR5cGU9ImIiKQpsaW5lcyhkX3NhX29yaWdpbmFsJERlbHRhLGRfc2Ffb3JpZ2luYWwkeV9oYXQsIGNvbD0iYmx1ZSIsIHR5cGU9ImIiLCBsdHk9MikKbGVnZW5kKDAsIDc2LGxlZ2VuZCA9IGMoIis0IERlbHRhIiwgIisxIERlbHRhIiksIGNvbD1jKCJibGFjayIsICJibHVlIiksIGx0eT0xOjIpCmBgYAoKQykgSG93IGRpZmZlcmVudCBhcmUgdGhlIHR3byBwb2ludHMgeW91IGhhdmUgY29tcHV0ZWQ/CgoqKlRoZSBwb2ludHMgaGF2ZSB0aGUgc2FtZSBjZW50ZXIgaW4gMjUsIGJ1dCB0aGVuIHRoZSBkaXNwZXJzaW9uIGlzIHJlYWxseSBiaWcgYmVpbmcgJCs0XERlbHRhJCBoYXZpbmcgYSB2YWx1ZSBvZiAyMjUgdW5pdHMsIG1lYW53aGlsZSB0aGUgZGVmYXVsdCAkXERlbHRhJCBvbmx5IHJlYWNoZXMgdW50aWwgMzMgdW50aXMuKioKCiMjIyA1LjUKCkluIGEgbWV0YWxsdXJneSBleHBlcmltZW50IGl0IGlzIGRlc2lyZWQgdG8gdGVzdCB0aGUgZWZmZWN0IG9mIGZvdXIgZmFjdG9ycyBhbmQgdGhlaXIgaW50ZXJhY3Rpb25zIG9uIHRoZSBjb25jZW50cmF0aW9uIChwZXJjZW50IGJ5IHdlaWdodCkgb2YgYSBwYXJ0aWN1bGFyIHBob3NwaG9ydXMgY29tcG91bmQgaW4gY29zdGluZyBtYXRlcmlhbC4gVGhlIHZhcmlhYmxlcyBhcmU6IEEsIHBlcmNlbnQgcGhvc3Bob3J1cyBpbiB0aGUgcmVmaW5lbWVudDsgQiwgcGVyY2VudCByZW1lbHRlZCBtYXRlcmlhbDsgQywgZmx1eGluZyB0aW1lLCBhbmQgRCwgaG9sZGluZyB0aW1lLiBUaGUgZm91cgpmYWN0b3JzIGFyZSB2YXJpZWQgaW4gYSAyNCBmYWN0b3JpYWwgZXhwZXJpbWVudCB3aXRoIHR3byBjYXN0aW5ncyB0YWtlbiBhdCBlYWNoIGZhY3RvciBjb21iaW5hdGlvbi4gVGhlIDMyIGNhc3RpbmdzIHdlcmUgbWFkZSBpbiByYW5kb20gb3JkZXIsIGFuZCB0aGUgZGF0YSBhcmUgc2hvd24gaW4gdGhpcyB0YWJsZToKCnwgVHJlYXRtZW50IHwgUmVwbGljYXRpb24gSSB8IFJlcGxpY2F0aW9uIElJIHwgVG90YWwgfAp8Oi0tLS0tLS0tLTp8Oi0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLTp8Oi0tLS0tOnwKfCAoMSkgfCAzMC4zIHwgMjguNiB8IDU4LjkgfAp8IGEgfCAyOC41IHwgMzEuNCB8IDU5LjkgfAp8IGIgfCAyNC41IHwgMjUuNiB8IDUwLjEgfAp8IGFiIHwgMjUuOSB8IDI3LjIgfCA1My4xIHwKfCBjIHwgMjQuOCB8IDIzLjQgfCA0OC4yIHwKfCBhYyB8IDI2LjkgfCAyMy44IHwgNTAuNyB8CnwgYmMgfCAyNC44IHwgMjcuOCB8IDUyLjYgfAp8IGFiYyB8IDIyLjIgfCAyNC45IHwgNDcuMSB8CnwgZCB8IDMxLjcgfCAzMy41IHwgNjUuMiB8CnwgYWQgfCAyNC42IHwgMjYuMiB8IDUwLjggfAp8IGJkIHwgMjcuNiB8IDMwLjYgfCA1OC4yIHwKfCBhYmQgfCAyNi4zIHwgMjcuOCB8IDU0LjEgfAp8IGNkIHwgMjkuOSB8IDI3LjcgfCA1Ny42IHwKfCBhY2QgfCAyNi44IHwgMjQuMiB8IDUxLjAgfAp8IGJjZCB8IDI2LjQgfCAyNC45IHwgNTEuMyB8CnwgYWJjZCB8IDI2LjkgfCAyOS4zIHwgNTYuMiB8CnwgVG90YWwgfCA0MjguMSB8IDQzNi45IHwgODY1LjAgfAoKYGBge3J9CnJlc3VsdHMgPC0gYyAoNTguOSwgNTkuOSwgNTAuMSwgNTMuMSwgNDguMiwgNTAuNywgNTIuNiwgNDcuMSwgNjUuMiwgNTAuOCwgNTguMiwgNTQuMSwgNTcuNiwgNTEsIDUxLjMsIDU2LjIsIDg2NSkKCnNldCA8LSBmYWNEZXNpZ24oaz00KQoKdG90YWwgPC0gcmVzdWx0c1t1bmxpc3QocnVuT3JkKHNldCkpXQoKcmVzcG9uc2Uoc2V0KSA8LSB0b3RhbAoKc2V0CmBgYApXaXRoIHRoZSB0YWJsZSB3ZSBuZWVkIHRvIGNyZWF0ZSB0aGUgZnVuY3Rpb24gdXNpbmcgbG0KCmBgYHtyfQpkZiA8LSBhcy5kYXRhLmZyYW1lKGRhdGEpCgpmdW5jIDwtIGxtKHRvdGFsIH4gQSArIEIgKyBDICsgRCwgZGF0YT1kZikKZnVuYwpgYGAKV2l0aCB0aGlzIHdlIGdldCB0aGUgZmluYWwgZXF1YXRpb24gd2hpY2ggaXM6CgpcYmVnaW57YWxpZ25lZH0KICB5ID0gNTQuMDYyNSAtMS40Mzc1eF8xIC0gMC4zNzUweF8yICsgMC4zODc1eF8zICsgMC4zNTAweF80ClxlbmR7YWxpZ25lZH0KCmIpIENvbnN0cnVjdCBhIHRhYmxlIG9mIHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudCBpbiB0aGUgY29kZWQgZGVzaWduIHZhcmlhYmxlcy4KCmBgYHtyfQpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiwgIkMiLCJEIiksIHJlc3BvbnNlPSJ0b3RhbCIsIGRhdGE9ZGF0YSkKZF9zYSA8LSBhcy5kYXRhLmZyYW1lKHNhKQp5X2hhdCA8LSA1NC4wNjI1IC0gMS40Mzc1KmRfc2EkQS5jb2RlZCAtIDAuMzc1MCpkX3NhJEIuY29kZWQgKyAwLjM4NzUqZF9zYSRDLmNvZGVkICsgMC4zNSpkX3NhJEQuY29kZWQKcmVzcG9uc2Uoc2EpIDwtIHlfaGF0CnNhCmBgYAoKIyMjIDUuNgoKQ29uc2lkZXIgdGhlICQyXjIkIGZhY3RvcmlhbCBkZXNpZ24gZmVhdHVyZWQgaW4gdGhlIGlsbHVzdHJhdGlvbiBpbiBGaWd1cmUgMy4xIGluIENoYXB0ZXIgMy4gRmFjdG9yIEEgaXMgdGhlIGNvbmNlbnRyYXRpb24gb2YgYSByZWFjdGFudCwgZmFjdG9yIEIgaXMgdGhlIGZlZWQgcmF0ZSwgYW5kIHRoZSByZXNwb25zZSBpcyB0aGUgdmlzY29zaXR5IG9mIHRoZSBvdXRwdXQgbWF0ZXJpYWwuIEFzIG9uZSBjYW4gdGVsbCBieSB0aGUgY29tcHV0ZWQgZWZmZWN0cyBhbmQgdGhlIGFuYWx5c2lzIG9mIHZhcmlhbmNlIHNob3duLCB0aGUgbWFpbiBlZmZlY3RzIGRvbWluYXRlIGluIHRoZSBhbmFseXNpcy4gVXNpbmcgdGhlIGZvbGxvd2luZyB0YWJsZToKCnwgQ29tYmluYXRpb24gfCBJIHwgSUkgfCBJSUkgfCBJViB8IFRvdGFsIHwKfDotLS0tLS0tLS0tLTp8Oi06fDotLTp8Oi0tLTp8Oi0tOnw6LS0tLS06fAp8QSBsb3csIEIgbG93IHwgMTQ1IHwgMTQ4IHwgMTQ3IHwgMTQwIHwgNTgwIHwKfEEgaGlnaCwgQiBsb3cgfCAxNTggfCAxNTIgfCAxNTUgfCAxNTIgfCA2MTcgfAp8QSBsb3csIEIgaGlnaCB8IDEzNSB8IDEzOCB8IDE0MSB8IDEzOSB8IDU1MyB8CnxBIGhpZ2gsIEIgaGlnaCB8IDE1MCB8IDE1MiB8IDE0NiB8IDE0OSB8IDU5NyB8CgphKSBGaXQgYSBmaXJzdC1vcmRlciBtb2RlbAoKYGBge3J9CnNldCA8LSBmYWNEZXNpZ24oaz0yKQp0b3RhbCA8LSBjKDU1MywgNjE3LCA1OTcsIDU4MCkKcmVzcG9uc2Uoc2V0KSA8LSB0b3RhbApzZXQKYGBgCgpOb3cgd2UgY3JlYXRlIHRoZSBmdW5jdGlvbiB1c2luZyBhIGxpbmVhbCByZWdyZXNpb24KYGBge3J9CmxtX3NvdXJjZSA8LSBhcy5kYXRhLmZyYW1lKHNldCkKbG1fbW9kZWwgPC0gbG0odG90YWx+QStCLCBkYXRhPWxtX3NvdXJjZSkKbG1fbW9kZWwKYGBgCgpTbyB0aGUgZnVuY3Rpb24gaXM6CgpcYmVnaW57YWxpZ25lZH0KICB5ID0gNTg2Ljc1ICsgMjAuMjV4XzEgLSAxMS43NXhfMgpcZW5ke2FsaWduZWR9CgpiKSBDb21wdXRlIGFuZCBwbG90IHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudC4KCmBgYHtyfQpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHJlc3BvbnNlPSJ0b3RhbCIsIGRhdGE9c2V0KQpzYV9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzYSkKCnlfaGF0IDwtIDU4Ni43NSArIDIwLjI1KnNhX3NvdXJjZSRBLnJlYWwgLSAxMS43NSpzYV9zb3VyY2UkQi5yZWFsCgpyZXNwb25zZShzYSkgPC0geV9oYXQKc2EKYGBgCgpjKVN1cHBvc2UgdGhhdCBpbiB0aGUgbWV0cmljIG9mIHRoZSBjb2RlZCB2YXJpYWJsZXMsIHRoZSBjb25jZW50cmF0aW9uIGNhbm5vdCBleGNlZWQgMy41IGFuZCB0aGUgZmVlZCByYXRlIGNhbm5vdCBnbyBiZWxvdyAtMi43LiBTaG93IHRoZSBwcmFjdGljYWwgcGF0aCBvZiBzdGVlcGVzdCBhc2NlbnTigJR0aGF0IGlzLCB0aGUgcGF0aCB0aGF0IHRha2VzIGFjY291bnQgb2YgdGhlc2UgY29uc3RyYWludHMuCgpgYGB7cn0Kc2V0IDwtIGZhY0Rlc2lnbihrPTIpCnRvdGFsIDwtIGMoNTUzLCA2MTcsIDU5NywgNTgwKQpyZXNwb25zZShzZXQpIDwtIHRvdGFsCmxvd3Moc2V0KSA8LSBjKC0yLjcsIC0yLjcpCmhpZ2hzKHNldCkgPC0gYygzLjUsIDMuNSkKc2V0CgpzYSA8LSBzdGVlcEFzY2VudChmYWN0b3JzID0gYygiQSIsICJCIiksIHNpemU9MC4xLCByZXNwb25zZT0idG90YWwiLCBkYXRhPXNldCkKc2Ffc291cmNlIDwtIGFzLmRhdGEuZnJhbWUoc2EpCgp5X2hhdCA8LSA1ODYuNzUgKyAyMC4yNSpzYV9zb3VyY2UkQS5yZWFsIC0gMTEuNzUqc2Ffc291cmNlJEIucmVhbAoKcmVzcG9uc2Uoc2EpIDwtIHlfaGF0CnNhCmBgYAoKIyMjIDUuNwoKSXQgaXMgc3RhdGVkIGluIHRoZSB0ZXh0IHRoYXQgdGhlIGRldmVsb3BtZW50IG9mIHRoZSBwYXRoIG9mIHN0ZWVwZXN0IGFzY2VudCBtYWtlcyB1c2Ugb2YgdGhlIGFzc3VtcHRpb24gdGhhdCB0aGUgbW9kZWwgaXMgdHJ1bHkgZmlyc3Qtb3JkZXIgaW4gbmF0dXJlLiBIb3dldmVyLCBldmVuIGlmIHRoZXJlIGlzIGEgbW9kZXN0IGFtb3VudCBvZiBjdXJ2YXR1cmUgb3IgaW50ZXJhY3Rpb24gaW4gdGhlIHN5c3RlbSwgdGhlIHVzZSBvZiBzdGVlcGVzdCBhc2NlbnQgY2FuIGJlIGV4dHJlbWVseSB1c2VmdWwgaW4gZGV0ZXJtaW5pbmcgYSBmdXR1cmUgZXhwZXJpbWVudGFsIHJlZ2lvbi4gU3VwcG9zZSB0aGF0IGluIGEgc3lzdGVtIGludm9sdmluZyAkeF8xJCBhbmQgJHhfMiQgdGhlIGFjdHVhbCBtb2RlbCBpcyBnaXZlbiBieToKClxiZWdpbnthbGlnbmVkfQogIEUoeSkgPSAxNCArIDV4XzEgLSAxMHhfMiArIDN4XzF4XzIKXGVuZHthbGlnbmVkfQoKQXNzdW1lIHRoYXQgJHhfMSQgYW5kICR4XzIkIGFyZSBpbiBjb2RlZCBmb3JtOgoKYSkgU2hvdyBhIHBsb3Qgb2YgdGhlIHBhdGggb2Ygc3RlZXBlc3QgYXNjZW50IChiYXNlZCBvbiBhY3R1YWwgcGFyYW1ldGVycykgaWYgdGhlIGludGVyYWN0aW9uIGlzIGlnbm9yZWQuCgpgYGB7cn0Kc2V0IDwtIGZhY0Rlc2lnbihrPTIpCnNldF9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzZXQpCgplX3kgPC0gMTQgKyA1KnNldF9zb3VyY2UkQSAtIDEwKnNldF9zb3VyY2UkQiAKCnJlc3BvbnNlKHNldCkgPC0gZV95CgpzYV9saW5lYXIgPC0gc3RlZXBBc2NlbnQoZmFjdG9ycyA9IGMoIkEiLCAiQiIpLCByZXNwb25zZT0iZV95IiwgZGF0YT1zZXQpCgpzYV9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzYV9saW5lYXIpCgp5X2hhdCA8LSAxNCArIDUqc2Ffc291cmNlJEEuY29kZWQgLSAxMCpzYV9zb3VyY2UkQi5jb2RlZCAKCnJlc3BvbnNlKHNhX2xpbmVhcikgPC0geV9oYXQKCnBsb3Qoc2FfbGluZWFyLCB0eXBlPSJiIikKYGBgCgpiKSBTaG93IGEgcGxvdCBvZiB0aGUgcGF0aCBvZiBzdGVlcGVzdCBhc2NlbnQgZm9yIHRoZSBtb2RlbCB3aXRoIGludGVyYWN0aW9uLiBOb3RlIHRoYXQgdGhpcyBwYXRoIGlzIG5vdCBsaW5lYXIKCmBgYHtyfQpzZXQgPC0gZmFjRGVzaWduKGs9MikKc2V0X3NvdXJjZSA8LSBhcy5kYXRhLmZyYW1lKHNldCkKCmVfeSA8LSAxNCArIDUqc2V0X3NvdXJjZSRBIC0gMTAqc2V0X3NvdXJjZSRCICsgMypzZXRfc291cmNlJEEqc2V0X3NvdXJjZSRCCgpyZXNwb25zZShzZXQpIDwtIGVfeQoKc2FfaW50ZXJhY3Rpb24gPC0gc3RlZXBBc2NlbnQoZmFjdG9ycyA9IGMoIkEiLCAiQiIpLCByZXNwb25zZT0iZV95IiwgZGF0YT1zZXQpCgpzYV9zb3VyY2UgPC0gYXMuZGF0YS5mcmFtZShzYV9pbnRlcmFjdGlvbikKCnlfaGF0IDwtIDE0ICsgNSpzYV9zb3VyY2UkQS5jb2RlZCAtIDEwKnNhX3NvdXJjZSRCLmNvZGVkICsgMypzYV9zb3VyY2UkQS5jb2RlZCpzYV9zb3VyY2UkQi5jb2RlZAoKcmVzcG9uc2Uoc2FfaW50ZXJhY3Rpb24pIDwtIHlfaGF0CgpwbG90KHNhX2ludGVyYWN0aW9uLCB0eXBlPSJiIikKYGBgCgpjKSBDb21tZW50IG9uIHRoZSBkaWZmZXJlbmNlIGluIHRoZSB0d28gcGF0aHMuCgoqKlRoaXMgR3JhcGggZXhwbGFpbnMgYmV0dGVyIHRoZSBkaWZmZXJlbmNlKioKYGBge3J9CnNhX2ludGVyYWN0aW9uX3NvdXJjZSA8LSBhcy5kYXRhLmZyYW1lKHNhX2ludGVyYWN0aW9uKQpwbG90KHNhX2xpbmVhciwgdHlwZT0iYiIpCmxpbmVzKHNhX2ludGVyYWN0aW9uX3NvdXJjZSREZWx0YSxzYV9pbnRlcmFjdGlvbl9zb3VyY2UkeV9oYXQsIGNvbD0iYmx1ZSIsIHR5cGU9ImIiLCBsdHk9MikKbGVnZW5kKDAsIDM1LGxlZ2VuZCA9IGMoIk5vIEludGVyYWN0aW9uIiwgIkludGVyYWN0aW9uIiksIGNvbD1jKCJibGFjayIsICJibHVlIiksIGx0eT0xOjIpCmBgYAoK