Fish tank dataset
In this experiment, 96 fish (dojofish, goldfish and zebrafish)
were placed separately in a tank with two liters of water and
a certain dose (in mg) of the poison EI-43,064. The resistance
of the fish against the poison was measured as the amount of
minutes the fish survived after being exposed to the poison (Surv_time
, in
minutes). Additionally, the weight of each fish was measured.
Goal
The research goal is to study the association between the dose of
the poison that was administered to the fish and their
survival time.
Load the required libraries
Import the data
poison <- read_csv("https://raw.githubusercontent.com/statOmics/PSLSData/main/poison.csv")
## Rows: 96
## Columns: 4
## $ species <dbl> 0, 2, 1, 2, 0, 0, 2, 1, 0, 1, 0, 1, 0, 0, 2, 0, 0, 0, 2, 0, …
## $ Weight <dbl> 1.884359, 1.732261, 2.830895, 1.748562, 2.114166, 1.854602, …
## $ Dose <dbl> 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, …
## $ Surv_time <dbl> 3.461493, 2.110417, 11.419131, 1.821191, 3.277619, 2.955556,…
Data tidying
We can see a couple of things in the data that can be improved:
Capitalise the fist column name. Hint: use the rename
function.
Set the Species column as a factor. Hint: use the mutate
and as.factor
functions.
Change the species factor levels from 0, 1 and 2 to
Dojofish, Goldfish and Zebrafish. Hint: use the fct_recode
function inside
the mutate
function.
poison <- poison %>%
rename("Species" = "species") %>%
mutate(Species = as.factor(Species)) %>%
mutate(
Species = fct_recode(Species,
Dojofish = "0", Goldfish = "1", Zebrafish = "2"
)
)
poison
Data exploration
How many fish do we have per species?
poison %>%
count(Species)
Make a suitable visualization of the association between
the dose and the survival time. Additionally, add the fish species
as a color to the plot.
poison %>%
ggplot(aes(x = Dose, y = Surv_time)) +
geom_point() +
stat_smooth(method = "loess") +
geom_smooth(method = "lm", col = "black") +
ylab("Survival time (min)") +
xlab("Dose (mg)") +
geom_point(aes(col = Species)) + ## not necessary, additional layer of information
scale_color_manual(values = c("red", "darkgoldenrod", "black")) +
theme_bw()
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'

The linear regression line (black) is a good approximation
of the best fitting smooth line (blue) through the data.
Based on this figure, it seems realistic to suggest a linear
relationship between dose and survival, where higher doses
have lower survival times (as expected). However, before we
start with the regression analysis we must check if all required
assumptions are met.
Important note on the dataset
In this dataset, there are multiple variables that can have an effect on the
survival time of the fish. The most obvious one is the dose of poison that was
administered (as displayed above). However, we could also imagine that heavier
fish are less prone to the poison than light fish. Additionally, one fish
species may be more resistant to the poison than the other.
As such, not taking into account species into the analysis will introduce
problems regarding the assumption of independence of the data. The assumption
of independence entails that knowing the response value of one observation
(fish) does not learn us anything about the response values for another
variable. This will not be the case here; the response values (survival times)
of fish of the same species will be much more alike compared to those of fish
from another species.
Thus, in order to correctly analyze this data, fish species
and weight
should be taken into consideration. For now, we will “avoid” taking into
account the effect of species into the analysis by only performing an
analysis for the dojofish. As such, we will filter the dataset so that
it only contains observations for the Dojofish.
# filter the data so it only contains dojofish
poison_dojo <- poison %>%
filter(Species == "Dojofish")
Later in the course, we will come back to this dataset and perform a analysis
that allows us to assess the different research hypotheses for all fish species
at once!
The second predictor variable, Weight
, still may influence our analysis; fish
with higher weight are expected to be more resistant to the poison. If there
would be a systematic bias in the experiment, e.g. if all lighter fish obtained
a low dose of poison and heavier fish obtained a high dose of poison
(so, if the dose was not correctly randomized accros the different weights),
then we would not be able to correctly estimate the linear association between
Dose
and survival
; indeed, this relationship would be confounded by the
effect of weight.
poison_dojo %>%
ggplot(aes(x = Dose, y = Weight)) +
geom_point() +
ggtitle("Association between dose and weight") +
theme_bw() +
stat_summary(
fun = mean, geom = "point",
col = "black", size = 4, shape = 24,
fill = "red"
)

In our dataset, there seems to be no systematic bias, i.e., no clear trend
in the association between Dose
and Weight
. However, we do notice that the
fish weights are not perfectly uniformly distributed across the different doses;
we don’t see a clear trend, but we do see some fluctuations. To check if
fluctuations of the size that we observe here could happen by random change if
we carefully randomise, we may use simulations where we simulate the allocation
of the fish to the different doses.
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
set.seed(1351)
plots <- lapply(
1:9,
function(x) {
poison_dojo %>%
mutate(Dose = sample(Dose)) %>% # randomization
ggplot(aes(x = Dose, y = Weight)) +
geom_point() +
theme_bw() +
stat_summary(
geom = "point",
fun = "mean",
col = "black",
size = 2,
shape = 24,
fill = "red"
)
}
)
do.call(gridExtra::grid.arrange, plots)

In the above simulation, we randomly assigned the different fish to different
poison doses. Even though we did this randomly, we still see that by random
chance there can be fluctuations as large as the ones observed in our real
dataset. As such, we may conclude that there is indeed no systematic bias,
i.e., no clear trend in the association between Dose
and Weight
.
Linear regression analysis
Assumptions of linear regression
List assumptions:
- The observations are independent of each other
- Linearity between the response and predictor variable
- The residues of the model must be normally distributed
- Homoscedasticity of the data
The first assumption is met based on the experimental design. In the
data exploration phase, we saw that there is no clear trend in the association
between Dose
and Weight
. With respect to species, we have “avoided” taking
into account the effect of species into the analysis by only performing an
analysis for the dojofish.
We will check the other assumptions by first fitting the linear
model and plotting the output. As such, we will get all the
required diagnostic plots.
# fit a linear regression model with 'Surv_time' as response variable and
# 'Dose' as predictor variabele
model <- lm(Surv_time ~ Dose, data = poison_dojo)
## display the diagnostic plots of the model
plot(model)




We have four diagnostic plots:
- Linearity with the Residuals vs fitted plot
- predictor of predictions \(\hat\beta_0+\hat\beta_1 x\) on \(X\)-axis
- residuals on \(Y\)-as
\[e_i=y_i-\hat{g}(x_i)=y_i-\hat\beta_0-\hat\beta_1\times x_i,\]
If there would be a linear relationship in the data,
the residuals are expected to be scattered at random around y=0 for
the entire range of predicted values. This is clearly
the case: the assumption of linearity is met.
- Normal Q-Q
- QQ-plot of the residuals \(e_i\).
The residuals of the linear regression model should be normally
distributed. Given the second diagnostic plot, this seems not
to be the case. In stead, we observe a short left tail and a
long right tail. The assumption of normal residues is not met.
- Homoscedasticity
- Square-root of the absolute value of standardized residuals
in function of the fitted values
To meet the third assumption of linear regression, the variance
on the Square-root of the absolute value of standardized residuals
must be similar over the entire range of fitted values. The smoother
in the plot helps us with looking at this; it should be nicely
horizontal over the entire range of fitted values. This seems not
to be the case: for larger fitted values, the variance increase slightly.
The assumption of homoscedasticity is not met.
Multiple assumptions are not met, so we may not continue by performing
a linear regression.
We can try to remediate these deviations by log-transforming the data. Indeed,
data with heavy right tails can often be normalized by applying this strategy.
Fit a (log-)linear model by log-transforming the response.Generate diagnostic
plots and assess the assumptions.
log.model <- lm(log10(Surv_time) ~ Dose, data = poison_dojo)
plot(log.model)




Arguably, there might be some deviation from normality in the left tail of the
distribution. However, when we would simulate data under the normality
assumption, it seems that deviations of this size may be expected when
normality is met:
set.seed(1406)
nobs <- nrow(poison_dojo)
data.frame(
y = c(log.model$res, rnorm(nobs * 8, sd = sigma(log.model))),
label = rep(c("orig", paste0("sim", 1:8)), each = nobs)
) %>%
ggplot(aes(sample = y)) +
geom_qq() +
geom_qq_line() +
facet_wrap(~label)

- The independence assumption is met.
- Upon log-transformation, the linearity assumption is still met.
- Upon log-transformation, the normality assumption is also met.
- Upon log-transformation, the homoscedasticity assumption is also met.
Look at the output of the log-linear model:
##
## Call:
## lm(formula = log10(Surv_time) ~ Dose, data = poison_dojo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.2074 -0.1145 -0.0324 0.1039 0.3268
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.91722 0.10423 8.800 1.33e-10 ***
## Dose -0.27282 0.06648 -4.104 0.000215 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1453 on 37 degrees of freedom
## Multiple R-squared: 0.3128, Adjusted R-squared: 0.2942
## F-statistic: 16.84 on 1 and 37 DF, p-value: 0.0002146
Compute the 95% confidence interval on the model parameters:
## 2.5 % 97.5 %
## (Intercept) 0.7060342 1.1284104
## Dose -0.4075255 -0.1381159
Interpretation on the log scale
Currently, all the outcomes should be interpreted on the log-scale.
Indeed, since we are now modelling the log\(_{10}\) of survival time, we
don’t have direct inference on survival time.
As such, we may interpret the output as follows:
Dojofish that are exposed to a higher dose of the poison will have a \(log_{10}\)
survival time that is on average 0.27
lower per gram of poison that was administered additionally
(95% CI [0.71, 0.41, 1.13, 0.14]). This decrease in
survival time is significant on the 5% significance level (p<0.001).
Note, that the study is an experimental study so we can conclude that there is
a causal effect of the poison dose and the survival time.
The average of the log10 of survival time for fish that
were given a dose of 0 mg is 0.92.
Interpretation on the original scale
The interpretation the log-scale is quite difficult. To ease
the interpretation, we will backtransform the results to the original
scale (time in minutes). This we can do by
10^(summary(log.model)$coefficients[, "Estimate"])
## (Intercept) Dose
## 8.2646094 0.5335551
and of their confidence intervals:
## 2.5 % 97.5 %
## (Intercept) 5.0819949 13.4403459
## Dose 0.3912681 0.7275855
Now, we can interpret the results in terms of the geometric mean:
Dojo fish that are exposed to a higher dose of the poison will have a geometric
mean of the survival time that is factor 0.53
(95% CI [0.39, 0.73]) per gram of poison that they
received more than fish exposed to a lower dose. This decrease is very
significant on the 5% significance level (p<0.001).
The geometric mean of the survival time for fish that were given a
dose of 0 mg is 8.26 minutes.
In other words, our analysis seems to suggest that fish in uncontaminated water
would only survive for about 8 minutes! This seems a little bit fishy…
Note, that this interpretation is not biologically relevant and is induced
because we extrapolated considerably because all fish in the experiment were
exposed to poison.
## Extract slope and intercept from the model
dojo_intercept <- coef(log.model)[1]
dojo_slope <- coef(log.model)[2]
ggplot(poison_dojo, aes(Dose, log10(Surv_time))) +
geom_point() +
geom_abline(
slope = dojo_slope, intercept = dojo_intercept,
color = "steelblue", size = 1.2
)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

We can see that the dose value of 0 mg does not fall within
the same range as our data. The model is only valid in the range of
data that we use to build the model on!
However, in most applications we will never test for the intercept term.
Conclusion
There is a very significant effect of the poison on survival of Dojofish
(p< 0.001). Dojofish that are exposed to a higher dose of the poison will
have a survival time that decrease on average with a factor
1.87 per gram of poison that
is added (95% CI [2.56, 1.37]).
In the tutorial of multiple regression, we will revisit this exercise.
More specifically, we will there study the association between dose and survival
for all the species in the dataset.
LS0tCnRpdGxlOiAiRXhlcmNpc2UgNi4xOiBMaW5lYXIgcmVncmVzc2lvbiBvbiB0aGUgZmlzaCB0YW5rIGRhdGFzZXQgLSBzb2x1dGlvbiIKYXV0aG9yOiAiTGlldmVuIENsZW1lbnQsIEplcm9lbiBHaWxpcyBhbmQgTWlsYW4gTWFsZmFpdCIKZGF0ZTogInN0YXRPbWljcywgR2hlbnQgVW5pdmVyc2l0eSAoaHR0cHM6Ly9zdGF0b21pY3MuZ2l0aHViLmlvKSIKLS0tCgojIEZpc2ggdGFuayBkYXRhc2V0CgpJbiB0aGlzIGV4cGVyaW1lbnQsIDk2IGZpc2ggKGRvam9maXNoLCBnb2xkZmlzaCBhbmQgemVicmFmaXNoKQp3ZXJlIHBsYWNlZCBzZXBhcmF0ZWx5IGluIGEgdGFuayB3aXRoIHR3byBsaXRlcnMgb2Ygd2F0ZXIgYW5kCmEgY2VydGFpbiBkb3NlIChpbiBtZykgb2YgdGhlIHBvaXNvbiBFSS00MywwNjQuIFRoZSByZXNpc3RhbmNlCm9mIHRoZSBmaXNoIGFnYWluc3QgdGhlIHBvaXNvbiB3YXMgbWVhc3VyZWQgYXMgdGhlIGFtb3VudCBvZgptaW51dGVzIHRoZSBmaXNoIHN1cnZpdmVkIGFmdGVyIGJlaW5nIGV4cG9zZWQgdG8gdGhlIHBvaXNvbiAoYFN1cnZfdGltZWAsIGluCm1pbnV0ZXMpLiBBZGRpdGlvbmFsbHksIHRoZSB3ZWlnaHQgb2YgZWFjaCBmaXNoIHdhcyBtZWFzdXJlZC4KCiMgR29hbAoKVGhlIHJlc2VhcmNoIGdvYWwgaXMgdG8gc3R1ZHkgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4gdGhlIGRvc2Ugb2YKdGhlIHBvaXNvbiB0aGF0IHdhcyBhZG1pbmlzdGVyZWQgdG8gdGhlIGZpc2ggYW5kIHRoZWlyCnN1cnZpdmFsIHRpbWUuCgpMb2FkIHRoZSByZXF1aXJlZCBsaWJyYXJpZXMKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKCiMgSW1wb3J0IHRoZSBkYXRhCgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KcG9pc29uIDwtIHJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3RhdE9taWNzL1BTTFNEYXRhL21haW4vcG9pc29uLmNzdiIpCmBgYAoKYGBge3J9CmdsaW1wc2UocG9pc29uKQpoZWFkKHBvaXNvbikKYGBgCgojIERhdGEgdGlkeWluZwoKV2UgY2FuIHNlZSBhIGNvdXBsZSBvZiB0aGluZ3MgaW4gdGhlIGRhdGEgdGhhdCBjYW4gYmUgaW1wcm92ZWQ6CgoxLiBDYXBpdGFsaXNlIHRoZSBmaXN0IGNvbHVtbiBuYW1lLiAqSGludCo6IHVzZSB0aGUgYHJlbmFtZWAgZnVuY3Rpb24uCgoyLiBTZXQgdGhlIFNwZWNpZXMgY29sdW1uIGFzIGEgZmFjdG9yLiAqSGludCo6IHVzZSB0aGUgYG11dGF0ZWAgYW5kIGBhcy5mYWN0b3JgCmZ1bmN0aW9ucy4KCjMuIENoYW5nZSB0aGUgc3BlY2llcyBmYWN0b3IgbGV2ZWxzIGZyb20gMCwgMSBhbmQgMiB0bwpEb2pvZmlzaCwgR29sZGZpc2ggYW5kIFplYnJhZmlzaC4gKkhpbnQqOiB1c2UgdGhlIGBmY3RfcmVjb2RlYCBmdW5jdGlvbiBpbnNpZGUKdGhlIGBtdXRhdGVgIGZ1bmN0aW9uLgoKYGBge3J9CnBvaXNvbiA8LSBwb2lzb24gJT4lCiAgcmVuYW1lKCJTcGVjaWVzIiA9ICJzcGVjaWVzIikgJT4lCiAgbXV0YXRlKFNwZWNpZXMgPSBhcy5mYWN0b3IoU3BlY2llcykpICU+JQogIG11dGF0ZSgKICAgIFNwZWNpZXMgPSBmY3RfcmVjb2RlKFNwZWNpZXMsCiAgICAgIERvam9maXNoID0gIjAiLCBHb2xkZmlzaCA9ICIxIiwgWmVicmFmaXNoID0gIjIiCiAgICApCiAgKQoKcG9pc29uCmBgYAoKIyBEYXRhIGV4cGxvcmF0aW9uCgpIb3cgbWFueSBmaXNoIGRvIHdlIGhhdmUgcGVyIHNwZWNpZXM/CgpgYGB7cn0KcG9pc29uICU+JQogIGNvdW50KFNwZWNpZXMpCmBgYAoKTWFrZSBhIHN1aXRhYmxlIHZpc3VhbGl6YXRpb24gb2YgdGhlIGFzc29jaWF0aW9uIGJldHdlZW4KdGhlIGRvc2UgYW5kIHRoZSBzdXJ2aXZhbCB0aW1lLiBBZGRpdGlvbmFsbHksIGFkZCB0aGUgZmlzaCBzcGVjaWVzCmFzIGEgY29sb3IgdG8gdGhlIHBsb3QuCgpgYGB7cn0KcG9pc29uICU+JQogIGdncGxvdChhZXMoeCA9IERvc2UsIHkgPSBTdXJ2X3RpbWUpKSArCiAgZ2VvbV9wb2ludCgpICsKICBzdGF0X3Ntb290aChtZXRob2QgPSAibG9lc3MiKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sID0gImJsYWNrIikgKwogIHlsYWIoIlN1cnZpdmFsIHRpbWUgKG1pbikiKSArCiAgeGxhYigiRG9zZSAobWcpIikgKwogIGdlb21fcG9pbnQoYWVzKGNvbCA9IFNwZWNpZXMpKSArICMjIG5vdCBuZWNlc3NhcnksIGFkZGl0aW9uYWwgbGF5ZXIgb2YgaW5mb3JtYXRpb24KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkIiwgImRhcmtnb2xkZW5yb2QiLCAiYmxhY2siKSkgKwogIHRoZW1lX2J3KCkKYGBgCgpUaGUgbGluZWFyIHJlZ3Jlc3Npb24gbGluZSAoYmxhY2spIGlzIGEgZ29vZCBhcHByb3hpbWF0aW9uCm9mIHRoZSBiZXN0IGZpdHRpbmcgc21vb3RoIGxpbmUgKGJsdWUpIHRocm91Z2ggdGhlIGRhdGEuCkJhc2VkIG9uIHRoaXMgZmlndXJlLCBpdCBzZWVtcyByZWFsaXN0aWMgdG8gc3VnZ2VzdCBhIGxpbmVhcgpyZWxhdGlvbnNoaXAgYmV0d2VlbiBkb3NlIGFuZCBzdXJ2aXZhbCwgd2hlcmUgaGlnaGVyIGRvc2VzCmhhdmUgbG93ZXIgc3Vydml2YWwgdGltZXMgKGFzIGV4cGVjdGVkKS4gSG93ZXZlciwgYmVmb3JlIHdlCnN0YXJ0IHdpdGggdGhlIHJlZ3Jlc3Npb24gYW5hbHlzaXMgd2UgbXVzdCBjaGVjayBpZiBhbGwgcmVxdWlyZWQKYXNzdW1wdGlvbnMgYXJlIG1ldC4KCiMgSW1wb3J0YW50IG5vdGUgb24gdGhlIGRhdGFzZXQKCkluIHRoaXMgZGF0YXNldCwgdGhlcmUgYXJlIG11bHRpcGxlIHZhcmlhYmxlcyB0aGF0IGNhbiBoYXZlIGFuIGVmZmVjdCBvbiB0aGUKc3Vydml2YWwgdGltZSBvZiB0aGUgZmlzaC4gVGhlIG1vc3Qgb2J2aW91cyBvbmUgaXMgdGhlIGRvc2Ugb2YgcG9pc29uIHRoYXQgd2FzCmFkbWluaXN0ZXJlZCAoYXMgZGlzcGxheWVkIGFib3ZlKS4gSG93ZXZlciwgd2UgY291bGQgYWxzbyBpbWFnaW5lIHRoYXQgaGVhdmllcgpmaXNoIGFyZSBsZXNzIHByb25lIHRvIHRoZSBwb2lzb24gdGhhbiBsaWdodCBmaXNoLiBBZGRpdGlvbmFsbHksIG9uZSBmaXNoCnNwZWNpZXMgbWF5IGJlIG1vcmUgcmVzaXN0YW50IHRvIHRoZSBwb2lzb24gdGhhbiB0aGUgb3RoZXIuCgpBcyBzdWNoLCBub3QgdGFraW5nIGludG8gYWNjb3VudCBzcGVjaWVzIGludG8gdGhlIGFuYWx5c2lzIHdpbGwgaW50cm9kdWNlCnByb2JsZW1zIHJlZ2FyZGluZyB0aGUgYXNzdW1wdGlvbiBvZiAqaW5kZXBlbmRlbmNlKiBvZiB0aGUgZGF0YS4gVGhlIGFzc3VtcHRpb24Kb2YgKmluZGVwZW5kZW5jZSogZW50YWlscyB0aGF0IGtub3dpbmcgdGhlIHJlc3BvbnNlIHZhbHVlIG9mIG9uZSBvYnNlcnZhdGlvbgooZmlzaCkgZG9lcyBub3QgbGVhcm4gdXMgYW55dGhpbmcgYWJvdXQgdGhlIHJlc3BvbnNlIHZhbHVlcyBmb3IgYW5vdGhlcgp2YXJpYWJsZS4gVGhpcyB3aWxsIG5vdCBiZSB0aGUgY2FzZSBoZXJlOyB0aGUgcmVzcG9uc2UgdmFsdWVzIChzdXJ2aXZhbCB0aW1lcykKb2YgZmlzaCBvZiB0aGUgc2FtZSBzcGVjaWVzIHdpbGwgYmUgbXVjaCBtb3JlIGFsaWtlIGNvbXBhcmVkIHRvIHRob3NlIG9mIGZpc2gKZnJvbSBhbm90aGVyIHNwZWNpZXMuCgpUaHVzLCBpbiBvcmRlciB0byBjb3JyZWN0bHkgYW5hbHl6ZSB0aGlzIGRhdGEsIGZpc2ggYHNwZWNpZXNgIGFuZCBgd2VpZ2h0YApzaG91bGQgYmUgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uLiAqKkZvciBub3csIHdlIHdpbGwgImF2b2lkIiB0YWtpbmcgaW50byoqCioqYWNjb3VudCB0aGUgZWZmZWN0IG9mIHNwZWNpZXMgaW50byB0aGUgYW5hbHlzaXMgYnkgb25seSBwZXJmb3JtaW5nIGFuKioKKiphbmFseXNpcyBmb3IgdGhlIGRvam9maXNoKiouIEFzIHN1Y2gsIHdlIHdpbGwgZmlsdGVyIHRoZSBkYXRhc2V0IHNvIHRoYXQKaXQgb25seSBjb250YWlucyBvYnNlcnZhdGlvbnMgZm9yIHRoZSBEb2pvZmlzaC4KCmBgYHtyfQojIGZpbHRlciB0aGUgZGF0YSBzbyBpdCBvbmx5IGNvbnRhaW5zIGRvam9maXNoCnBvaXNvbl9kb2pvIDwtIHBvaXNvbiAlPiUKICBmaWx0ZXIoU3BlY2llcyA9PSAiRG9qb2Zpc2giKQpgYGAKCkxhdGVyIGluIHRoZSBjb3Vyc2UsIHdlIHdpbGwgY29tZSBiYWNrIHRvIHRoaXMgZGF0YXNldCBhbmQgcGVyZm9ybSBhIGFuYWx5c2lzCnRoYXQgYWxsb3dzIHVzIHRvIGFzc2VzcyB0aGUgZGlmZmVyZW50IHJlc2VhcmNoIGh5cG90aGVzZXMgZm9yIGFsbCBmaXNoIHNwZWNpZXMKYXQgb25jZSEKClRoZSBzZWNvbmQgcHJlZGljdG9yIHZhcmlhYmxlLCBgV2VpZ2h0YCwgc3RpbGwgbWF5IGluZmx1ZW5jZSBvdXIgYW5hbHlzaXM7IGZpc2gKd2l0aCBoaWdoZXIgd2VpZ2h0IGFyZSBleHBlY3RlZCB0byBiZSBtb3JlIHJlc2lzdGFudCB0byB0aGUgcG9pc29uLiAqKklmKiogdGhlcmUKd291bGQgYmUgYSBzeXN0ZW1hdGljIGJpYXMgaW4gdGhlIGV4cGVyaW1lbnQsIGUuZy4gaWYgYWxsIGxpZ2h0ZXIgZmlzaCBvYnRhaW5lZAphIGxvdyBkb3NlICBvZiBwb2lzb24gYW5kIGhlYXZpZXIgZmlzaCBvYnRhaW5lZCBhIGhpZ2ggZG9zZSBvZiBwb2lzb24KKHNvLCBpZiB0aGUgZG9zZSB3YXMgbm90IGNvcnJlY3RseSByYW5kb21pemVkIGFjY3JvcyB0aGUgZGlmZmVyZW50IHdlaWdodHMpLAp0aGVuIHdlIHdvdWxkIG5vdCBiZSBhYmxlIHRvIGNvcnJlY3RseSBlc3RpbWF0ZSB0aGUgbGluZWFyIGFzc29jaWF0aW9uIGJldHdlZW4KYERvc2VgIGFuZCBgc3Vydml2YWxgOyBpbmRlZWQsIHRoaXMgcmVsYXRpb25zaGlwIHdvdWxkIGJlIGNvbmZvdW5kZWQgYnkgdGhlCmVmZmVjdCBvZiB3ZWlnaHQuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KcG9pc29uX2Rvam8gJT4lCiAgZ2dwbG90KGFlcyh4ID0gRG9zZSwgeSA9IFdlaWdodCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdndGl0bGUoIkFzc29jaWF0aW9uIGJldHdlZW4gZG9zZSBhbmQgd2VpZ2h0IikgKwogIHRoZW1lX2J3KCkgKwogIHN0YXRfc3VtbWFyeSgKICAgIGZ1biA9IG1lYW4sIGdlb20gPSAicG9pbnQiLAogICAgY29sID0gImJsYWNrIiwgc2l6ZSA9IDQsIHNoYXBlID0gMjQsCiAgICBmaWxsID0gInJlZCIKICApCmBgYAoKSW4gb3VyIGRhdGFzZXQsIHRoZXJlIHNlZW1zIHRvIGJlICoqbm8gc3lzdGVtYXRpYyBiaWFzKiosIGkuZS4sIG5vIGNsZWFyIHRyZW5kCmluIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIGBEb3NlYCBhbmQgYFdlaWdodGAuIEhvd2V2ZXIsIHdlIGRvIG5vdGljZSB0aGF0IHRoZQpmaXNoIHdlaWdodHMgYXJlIG5vdCBwZXJmZWN0bHkgdW5pZm9ybWx5IGRpc3RyaWJ1dGVkIGFjcm9zcyB0aGUgZGlmZmVyZW50IGRvc2VzOwp3ZSBkb24ndCBzZWUgYSBjbGVhciB0cmVuZCwgYnV0IHdlIGRvIHNlZSBzb21lIGZsdWN0dWF0aW9ucy4gVG8gY2hlY2sgaWYKZmx1Y3R1YXRpb25zIG9mIHRoZSBzaXplIHRoYXQgd2Ugb2JzZXJ2ZSBoZXJlIGNvdWxkIGhhcHBlbiBieSByYW5kb20gY2hhbmdlIGlmCndlIGNhcmVmdWxseSByYW5kb21pc2UsIHdlIG1heSB1c2Ugc2ltdWxhdGlvbnMgd2hlcmUgd2Ugc2ltdWxhdGUgdGhlIGFsbG9jYXRpb24Kb2YgdGhlIGZpc2ggdG8gdGhlIGRpZmZlcmVudCBkb3Nlcy4KCmBgYHtyfQpsaWJyYXJ5KGdyaWRFeHRyYSkKYGBgCgpgYGB7cn0Kc2V0LnNlZWQoMTM1MSkKCnBsb3RzIDwtIGxhcHBseSgKICAxOjksCiAgZnVuY3Rpb24oeCkgewogICAgcG9pc29uX2Rvam8gJT4lCiAgICAgIG11dGF0ZShEb3NlID0gc2FtcGxlKERvc2UpKSAlPiUgIyByYW5kb21pemF0aW9uCiAgICAgIGdncGxvdChhZXMoeCA9IERvc2UsIHkgPSBXZWlnaHQpKSArCiAgICAgIGdlb21fcG9pbnQoKSArCiAgICAgIHRoZW1lX2J3KCkgKwogICAgICBzdGF0X3N1bW1hcnkoCiAgICAgICAgZ2VvbSA9ICJwb2ludCIsCiAgICAgICAgZnVuID0gIm1lYW4iLAogICAgICAgIGNvbCA9ICJibGFjayIsCiAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgc2hhcGUgPSAyNCwKICAgICAgICBmaWxsID0gInJlZCIKICAgICAgKQogIH0KKQpkby5jYWxsKGdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlLCBwbG90cykKYGBgCgpJbiB0aGUgYWJvdmUgc2ltdWxhdGlvbiwgd2UgcmFuZG9tbHkgYXNzaWduZWQgdGhlIGRpZmZlcmVudCBmaXNoIHRvIGRpZmZlcmVudApwb2lzb24gZG9zZXMuIEV2ZW4gdGhvdWdoIHdlIGRpZCB0aGlzIHJhbmRvbWx5LCB3ZSBzdGlsbCBzZWUgdGhhdCBieSByYW5kb20KY2hhbmNlIHRoZXJlIGNhbiBiZSBmbHVjdHVhdGlvbnMgYXMgbGFyZ2UgYXMgdGhlIG9uZXMgb2JzZXJ2ZWQgaW4gb3VyIHJlYWwKZGF0YXNldC4gQXMgc3VjaCwgd2UgbWF5IGNvbmNsdWRlIHRoYXQgdGhlcmUgaXMgaW5kZWVkICoqbm8gc3lzdGVtYXRpYyBiaWFzKiosCmkuZS4sIG5vIGNsZWFyIHRyZW5kIGluIHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIGBEb3NlYCBhbmQgYFdlaWdodGAuCgojIExpbmVhciByZWdyZXNzaW9uIGFuYWx5c2lzCgojIyBBc3N1bXB0aW9ucyBvZiBsaW5lYXIgcmVncmVzc2lvbgoKTGlzdCBhc3N1bXB0aW9uczoKCjEuIFRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50IG9mIGVhY2ggb3RoZXIKMi4gTGluZWFyaXR5IGJldHdlZW4gdGhlIHJlc3BvbnNlIGFuZCBwcmVkaWN0b3IgdmFyaWFibGUKMy4gVGhlIHJlc2lkdWVzIG9mIHRoZSBtb2RlbCBtdXN0IGJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkCjQuIEhvbW9zY2VkYXN0aWNpdHkgb2YgdGhlIGRhdGEKClRoZSBmaXJzdCBhc3N1bXB0aW9uIGlzIG1ldCBiYXNlZCBvbiB0aGUgZXhwZXJpbWVudGFsIGRlc2lnbi4gSW4gdGhlCmRhdGEgZXhwbG9yYXRpb24gcGhhc2UsIHdlIHNhdyB0aGF0IHRoZXJlIGlzIG5vIGNsZWFyIHRyZW5kIGluIHRoZSBhc3NvY2lhdGlvbgpiZXR3ZWVuIGBEb3NlYCBhbmQgYFdlaWdodGAuIFdpdGggcmVzcGVjdCB0byBzcGVjaWVzLCB3ZSBoYXZlICJhdm9pZGVkIiB0YWtpbmcKaW50byBhY2NvdW50IHRoZSBlZmZlY3Qgb2Ygc3BlY2llcyBpbnRvIHRoZSBhbmFseXNpcyBieSBvbmx5IHBlcmZvcm1pbmcgYW4KYW5hbHlzaXMgZm9yIHRoZSBkb2pvZmlzaC4KCldlIHdpbGwgY2hlY2sgdGhlIG90aGVyIGFzc3VtcHRpb25zIGJ5IGZpcnN0IGZpdHRpbmcgdGhlIGxpbmVhcgptb2RlbCBhbmQgcGxvdHRpbmcgdGhlIG91dHB1dC4gQXMgc3VjaCwgd2Ugd2lsbCBnZXQgYWxsIHRoZQpyZXF1aXJlZCBkaWFnbm9zdGljIHBsb3RzLgoKYGBge3J9CiMgZml0IGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgd2l0aCAnU3Vydl90aW1lJyBhcyByZXNwb25zZSB2YXJpYWJsZSBhbmQKIyAnRG9zZScgYXMgcHJlZGljdG9yIHZhcmlhYmVsZQptb2RlbCA8LSBsbShTdXJ2X3RpbWUgfiBEb3NlLCBkYXRhID0gcG9pc29uX2Rvam8pCgojIyBkaXNwbGF5IHRoZSBkaWFnbm9zdGljIHBsb3RzIG9mIHRoZSBtb2RlbApwbG90KG1vZGVsKQpgYGAKCldlIGhhdmUgZm91ciBkaWFnbm9zdGljIHBsb3RzOgoKMi4gTGluZWFyaXR5IHdpdGggdGhlIFJlc2lkdWFscyB2cyBmaXR0ZWQgcGxvdAoKLSBwcmVkaWN0b3Igb2YgcHJlZGljdGlvbnMgJFxoYXRcYmV0YV8wK1xoYXRcYmV0YV8xIHgkIG9uICRYJC1heGlzCi0gKnJlc2lkdWFscyogb24gJFkkLWFzCiQkZV9pPXlfaS1caGF0e2d9KHhfaSk9eV9pLVxoYXRcYmV0YV8wLVxoYXRcYmV0YV8xXHRpbWVzIHhfaSwkJAoKSWYgdGhlcmUgd291bGQgYmUgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGluIHRoZSBkYXRhLAp0aGUgcmVzaWR1YWxzIGFyZSBleHBlY3RlZCB0byBiZSBzY2F0dGVyZWQgYXQgcmFuZG9tIGFyb3VuZCB5PTAgZm9yCnRoZSBlbnRpcmUgcmFuZ2Ugb2YgcHJlZGljdGVkIHZhbHVlcy4gVGhpcyBpcyBjbGVhcmx5CnRoZSBjYXNlOiB0aGUgYXNzdW1wdGlvbiBvZiBsaW5lYXJpdHkgaXMgbWV0LgoKMy4gTm9ybWFsIFEtUQoKLSBRUS1wbG90IG9mIHRoZSByZXNpZHVhbHMgJGVfaSQuCgpUaGUgcmVzaWR1YWxzIG9mIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCBzaG91bGQgYmUgbm9ybWFsbHkKZGlzdHJpYnV0ZWQuIEdpdmVuIHRoZSBzZWNvbmQgZGlhZ25vc3RpYyBwbG90LCB0aGlzIHNlZW1zIG5vdAp0byBiZSB0aGUgY2FzZS4gSW4gc3RlYWQsIHdlIG9ic2VydmUgYSBzaG9ydCBsZWZ0IHRhaWwgYW5kIGEKbG9uZyByaWdodCB0YWlsLiBUaGUgYXNzdW1wdGlvbiBvZiBub3JtYWwgcmVzaWR1ZXMgaXMgKipub3QgbWV0LioqCgo0LiBIb21vc2NlZGFzdGljaXR5CgotIFNxdWFyZS1yb290IG9mIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiBzdGFuZGFyZGl6ZWQgcmVzaWR1YWxzCmluIGZ1bmN0aW9uIG9mIHRoZSBmaXR0ZWQgdmFsdWVzCgpUbyBtZWV0IHRoZSB0aGlyZCBhc3N1bXB0aW9uIG9mIGxpbmVhciByZWdyZXNzaW9uLCB0aGUgdmFyaWFuY2UKb24gdGhlIF9TcXVhcmUtcm9vdCBvZiB0aGUgYWJzb2x1dGUgdmFsdWUgb2Ygc3RhbmRhcmRpemVkIHJlc2lkdWFsc18KbXVzdCBiZSBzaW1pbGFyIG92ZXIgdGhlIGVudGlyZSByYW5nZSBvZiBmaXR0ZWQgdmFsdWVzLiBUaGUgc21vb3RoZXIKaW4gdGhlIHBsb3QgaGVscHMgdXMgd2l0aCBsb29raW5nIGF0IHRoaXM7IGl0IHNob3VsZCBiZSBuaWNlbHkKaG9yaXpvbnRhbCBvdmVyIHRoZSBlbnRpcmUgcmFuZ2Ugb2YgZml0dGVkIHZhbHVlcy4gVGhpcyBzZWVtcyBub3QKdG8gYmUgdGhlIGNhc2U6IGZvciBsYXJnZXIgZml0dGVkIHZhbHVlcywgdGhlIHZhcmlhbmNlIGluY3JlYXNlIHNsaWdodGx5LgpUaGUgYXNzdW1wdGlvbiBvZiBob21vc2NlZGFzdGljaXR5IGlzICoqbm90IG1ldC4qKgoKTXVsdGlwbGUgYXNzdW1wdGlvbnMgYXJlIG5vdCBtZXQsIHNvIHdlIG1heSBub3QgY29udGludWUgYnkgcGVyZm9ybWluZwphIGxpbmVhciByZWdyZXNzaW9uLgoKV2UgY2FuIHRyeSB0byByZW1lZGlhdGUgdGhlc2UgZGV2aWF0aW9ucyBieSBsb2ctdHJhbnNmb3JtaW5nIHRoZSBkYXRhLiBJbmRlZWQsCmRhdGEgd2l0aCBoZWF2eSByaWdodCB0YWlscyBjYW4gb2Z0ZW4gYmUgbm9ybWFsaXplZCBieSBhcHBseWluZyB0aGlzIHN0cmF0ZWd5LgoKRml0IGEgKGxvZy0pbGluZWFyIG1vZGVsIGJ5IGxvZy10cmFuc2Zvcm1pbmcgdGhlIHJlc3BvbnNlLkdlbmVyYXRlIGRpYWdub3N0aWMKcGxvdHMgYW5kIGFzc2VzcyB0aGUgYXNzdW1wdGlvbnMuCgpgYGB7cn0KbG9nLm1vZGVsIDwtIGxtKGxvZzEwKFN1cnZfdGltZSkgfiBEb3NlLCBkYXRhID0gcG9pc29uX2Rvam8pCnBsb3QobG9nLm1vZGVsKQpgYGAKCkFyZ3VhYmx5LCB0aGVyZSBtaWdodCBiZSBzb21lIGRldmlhdGlvbiBmcm9tIG5vcm1hbGl0eSBpbiB0aGUgbGVmdCB0YWlsIG9mIHRoZQpkaXN0cmlidXRpb24uIEhvd2V2ZXIsIHdoZW4gd2Ugd291bGQgc2ltdWxhdGUgZGF0YSB1bmRlciB0aGUgbm9ybWFsaXR5CmFzc3VtcHRpb24sIGl0IHNlZW1zIHRoYXQgZGV2aWF0aW9ucyBvZiB0aGlzIHNpemUgbWF5IGJlIGV4cGVjdGVkIHdoZW4Kbm9ybWFsaXR5IGlzIG1ldDoKCmBgYHtyfQpzZXQuc2VlZCgxNDA2KQpub2JzIDwtIG5yb3cocG9pc29uX2Rvam8pCgpkYXRhLmZyYW1lKAogIHkgPSBjKGxvZy5tb2RlbCRyZXMsIHJub3JtKG5vYnMgKiA4LCBzZCA9IHNpZ21hKGxvZy5tb2RlbCkpKSwKICBsYWJlbCA9IHJlcChjKCJvcmlnIiwgcGFzdGUwKCJzaW0iLCAxOjgpKSwgZWFjaCA9IG5vYnMpCikgJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGUgPSB5KSkgKwogIGdlb21fcXEoKSArCiAgZ2VvbV9xcV9saW5lKCkgKwogIGZhY2V0X3dyYXAofmxhYmVsKQpgYGAKCjEuIFRoZSBpbmRlcGVuZGVuY2UgYXNzdW1wdGlvbiBpcyBtZXQuCjIuIFVwb24gbG9nLXRyYW5zZm9ybWF0aW9uLCB0aGUgbGluZWFyaXR5IGFzc3VtcHRpb24gaXMgc3RpbGwgbWV0LgozLiBVcG9uIGxvZy10cmFuc2Zvcm1hdGlvbiwgdGhlIG5vcm1hbGl0eSBhc3N1bXB0aW9uIGlzIGFsc28gbWV0Lgo0LiBVcG9uIGxvZy10cmFuc2Zvcm1hdGlvbiwgdGhlIGhvbW9zY2VkYXN0aWNpdHkgYXNzdW1wdGlvbiBpcyBhbHNvIG1ldC4KCkxvb2sgYXQgdGhlIG91dHB1dCBvZiB0aGUgbG9nLWxpbmVhciBtb2RlbDoKCmBgYHtyfQpzdW1tYXJ5KGxvZy5tb2RlbCkKYGBgCgpDb21wdXRlIHRoZSA5NSUgY29uZmlkZW5jZSBpbnRlcnZhbCBvbiB0aGUgbW9kZWwgcGFyYW1ldGVyczoKCmBgYHtyfQpjb25maW50KGxvZy5tb2RlbCkKYGBgCgojIyBJbnRlcnByZXRhdGlvbiBvbiB0aGUgbG9nIHNjYWxlCgpDdXJyZW50bHksIGFsbCB0aGUgb3V0Y29tZXMgc2hvdWxkIGJlIGludGVycHJldGVkIG9uIHRoZSBsb2ctc2NhbGUuCkluZGVlZCwgc2luY2Ugd2UgYXJlIG5vdyBtb2RlbGxpbmcgIF90aGUgbG9nJF97MTB9JCBvZiBzdXJ2aXZhbCB0aW1lXywgd2UKZG9uJ3QgaGF2ZSBkaXJlY3QgaW5mZXJlbmNlIG9uIHN1cnZpdmFsIHRpbWUuCgpBcyBzdWNoLCB3ZSBtYXkgaW50ZXJwcmV0IHRoZSBvdXRwdXQgYXMgZm9sbG93czoKCi0gVGhlIHNsb3BlOgoKRG9qb2Zpc2ggdGhhdCBhcmUgZXhwb3NlZCB0byBhIGhpZ2hlciBkb3NlIG9mIHRoZSBwb2lzb24gd2lsbCBoYXZlIGEgJGxvZ197MTB9JApzdXJ2aXZhbCB0aW1lIHRoYXQgaXMgb24gYXZlcmFnZSBgciBsb2cubW9kZWwkY29lZlsyXSAlPiUgYWJzICU+JSByb3VuZCguLDIpYApsb3dlciBwZXIgZ3JhbSBvZiBwb2lzb24gdGhhdCB3YXMgYWRtaW5pc3RlcmVkIGFkZGl0aW9uYWxseQooOTUlIENJIFtgciBjb25maW50KGxvZy5tb2RlbCkgJT4lIGFicyAlPiUgcm91bmQoLiwyKWBdKS4gVGhpcyBkZWNyZWFzZSBpbgpzdXJ2aXZhbCB0aW1lIGlzIHNpZ25pZmljYW50IG9uIHRoZSA1JSBzaWduaWZpY2FuY2UgbGV2ZWwgKHA8MC4wMDEpLgoKTm90ZSwgdGhhdCB0aGUgc3R1ZHkgaXMgYW4gZXhwZXJpbWVudGFsIHN0dWR5IHNvIHdlIGNhbiBjb25jbHVkZSB0aGF0IHRoZXJlIGlzCmEgY2F1c2FsIGVmZmVjdCBvZiB0aGUgcG9pc29uIGRvc2UgYW5kIHRoZSBzdXJ2aXZhbCB0aW1lLgoKLSBUaGUgaW50ZXJjZXB0OgoKVGhlIGF2ZXJhZ2Ugb2YgdGhlIGxvZzEwIG9mIHN1cnZpdmFsIHRpbWUgZm9yIGZpc2ggdGhhdAp3ZXJlIGdpdmVuIGEgZG9zZSBvZiAwIG1nIGlzIGByIGxvZy5tb2RlbCRjb2VmWzFdICU+JSBhYnMgJT4lIHJvdW5kKC4sMilgLgoKIyMgSW50ZXJwcmV0YXRpb24gb24gdGhlIG9yaWdpbmFsIHNjYWxlCgpUaGUgaW50ZXJwcmV0YXRpb24gdGhlIGxvZy1zY2FsZSBpcyBxdWl0ZSBkaWZmaWN1bHQuIFRvIGVhc2UKdGhlIGludGVycHJldGF0aW9uLCB3ZSB3aWxsIGJhY2t0cmFuc2Zvcm0gdGhlIHJlc3VsdHMgdG8gdGhlIG9yaWdpbmFsCnNjYWxlICh0aW1lIGluIG1pbnV0ZXMpLiBUaGlzIHdlIGNhbiBkbyBieQoKYGBge3J9CjEwXihzdW1tYXJ5KGxvZy5tb2RlbCkkY29lZmZpY2llbnRzWywgIkVzdGltYXRlIl0pCmBgYAoKYW5kIG9mIHRoZWlyIGNvbmZpZGVuY2UgaW50ZXJ2YWxzOgoKYGBge3J9CjEwXihjb25maW50KGxvZy5tb2RlbCkpCmBgYAoKTm93LCB3ZSBjYW4gaW50ZXJwcmV0IHRoZSByZXN1bHRzIGluIHRlcm1zIG9mIHRoZSBnZW9tZXRyaWMgbWVhbjoKCi0gVGhlIHNsb3BlOgoKRG9qbyBmaXNoIHRoYXQgYXJlIGV4cG9zZWQgdG8gYSBoaWdoZXIgZG9zZSBvZiB0aGUgcG9pc29uIHdpbGwgaGF2ZSBhIGdlb21ldHJpYwptZWFuIG9mIHRoZSBzdXJ2aXZhbCB0aW1lIHRoYXQgaXMgZmFjdG9yIGByIHJvdW5kKDEwXmxvZy5tb2RlbCRjb2VmWzJdLDIpYAooOTUlIENJIFtgciByb3VuZCgxMF4oY29uZmludChsb2cubW9kZWwpWzIsXSksMilgXSkgcGVyIGdyYW0gb2YgcG9pc29uIHRoYXQgdGhleQpyZWNlaXZlZCBtb3JlIHRoYW4gZmlzaCBleHBvc2VkIHRvIGEgbG93ZXIgZG9zZS4gVGhpcyBkZWNyZWFzZSBpcyB2ZXJ5CnNpZ25pZmljYW50IG9uIHRoZSA1JSBzaWduaWZpY2FuY2UgbGV2ZWwgKHA8MC4wMDEpLgoKLSBUaGUgaW50ZXJjZXB0OgoKVGhlIGdlb21ldHJpYyBtZWFuIG9mIHRoZSBzdXJ2aXZhbCB0aW1lIGZvciBmaXNoIHRoYXQgd2VyZSBnaXZlbiBhCmRvc2Ugb2YgMCBtZyBpcyBgciByb3VuZCgxMF5sb2cubW9kZWwkY29lZlsxXSwyKWAgbWludXRlcy4KCkluIG90aGVyIHdvcmRzLCBvdXIgYW5hbHlzaXMgc2VlbXMgdG8gc3VnZ2VzdCB0aGF0IGZpc2ggaW4gdW5jb250YW1pbmF0ZWQgd2F0ZXIKd291bGQgb25seSBzdXJ2aXZlIGZvciBhYm91dCA4IG1pbnV0ZXMhIFRoaXMgc2VlbXMgYSBsaXR0bGUgYml0IF9maXNoeV8uLi4KCk5vdGUsIHRoYXQgdGhpcyBpbnRlcnByZXRhdGlvbiBpcyBub3QgYmlvbG9naWNhbGx5IHJlbGV2YW50IGFuZCBpcyBpbmR1Y2VkCmJlY2F1c2Ugd2UgZXh0cmFwb2xhdGVkIGNvbnNpZGVyYWJseSBiZWNhdXNlIGFsbCBmaXNoIGluIHRoZSBleHBlcmltZW50IHdlcmUKZXhwb3NlZCB0byBwb2lzb24uCgpgYGB7cn0KIyMgRXh0cmFjdCBzbG9wZSBhbmQgaW50ZXJjZXB0IGZyb20gdGhlIG1vZGVsCmRvam9faW50ZXJjZXB0IDwtIGNvZWYobG9nLm1vZGVsKVsxXQpkb2pvX3Nsb3BlIDwtIGNvZWYobG9nLm1vZGVsKVsyXQoKZ2dwbG90KHBvaXNvbl9kb2pvLCBhZXMoRG9zZSwgbG9nMTAoU3Vydl90aW1lKSkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fYWJsaW5lKAogICAgc2xvcGUgPSBkb2pvX3Nsb3BlLCBpbnRlcmNlcHQgPSBkb2pvX2ludGVyY2VwdCwKICAgIGNvbG9yID0gInN0ZWVsYmx1ZSIsIHNpemUgPSAxLjIKICApCmBgYAoKV2UgY2FuIHNlZSB0aGF0IHRoZSBkb3NlIHZhbHVlIG9mIDAgbWcgZG9lcyBub3QgZmFsbCB3aXRoaW4KdGhlIHNhbWUgcmFuZ2UgYXMgb3VyIGRhdGEuIFRoZSBtb2RlbCBpcyBvbmx5IHZhbGlkIGluIHRoZSByYW5nZSBvZgpkYXRhIHRoYXQgd2UgdXNlIHRvIGJ1aWxkIHRoZSBtb2RlbCBvbiEKCkhvd2V2ZXIsIGluIG1vc3QgYXBwbGljYXRpb25zIHdlIHdpbGwgbmV2ZXIgdGVzdCBmb3IgdGhlIGludGVyY2VwdCB0ZXJtLgoKIyBDb25jbHVzaW9uCgpUaGVyZSBpcyBhIHZlcnkgc2lnbmlmaWNhbnQgZWZmZWN0IG9mIHRoZSBwb2lzb24gb24gc3Vydml2YWwgb2YgRG9qb2Zpc2gKKHA8IDAuMDAxKS4gRG9qb2Zpc2ggdGhhdCBhcmUgZXhwb3NlZCB0byBhIGhpZ2hlciBkb3NlIG9mIHRoZSBwb2lzb24gd2lsbApoYXZlIGEgc3Vydml2YWwgdGltZSB0aGF0IGRlY3JlYXNlIG9uIGF2ZXJhZ2Ugd2l0aCBhIGZhY3RvcgpgciBsb2cubW9kZWwkY29lZlsyXSAlPiUgYWJzICU+JSAxMF4uICU+JSByb3VuZCguLDIpYCBwZXIgZ3JhbSBvZiBwb2lzb24gdGhhdAppcyBhZGRlZCAoOTUlIENJIFtgciBjb25maW50KGxvZy5tb2RlbClbMixdICU+JSBhYnMgJT4lIDEwXi4gJT4lIHJvdW5kKC4sMilgXSkuCgpJbiB0aGUgdHV0b3JpYWwgb2YgbXVsdGlwbGUgcmVncmVzc2lvbiwgd2Ugd2lsbCByZXZpc2l0IHRoaXMgZXhlcmNpc2UuCk1vcmUgc3BlY2lmaWNhbGx5LCB3ZSB3aWxsIHRoZXJlIHN0dWR5IHRoZSBhc3NvY2lhdGlvbiBiZXR3ZWVuIGRvc2UgYW5kIHN1cnZpdmFsCmZvciBhbGwgdGhlIHNwZWNpZXMgaW4gdGhlIGRhdGFzZXQuCg==