View the
latest recording of this lecture
Sometimes it is unclear as to whether a particular explanatory
variable should be regarded as a factor (categorical explanatory
variable) or a numerical covariate.
For example, should the effect of a drug be modelled using a four
level factor (zero, low, medium and high doses) or as a numeric variable
(0, 10, 20, 30 ml doses)?
We will explore this issue in this lecture, and develop an
appropriate methodology to compare the two modelling approaches.
Vitamin C and Tooth Growth
We use an experiment into the effects of vitamin C on tooth growth to
illustrate this question.
30 guinea pigs were divided (at random) into three groups of ten and
dosed with vitamin C in mg (administered in orange juice). Group 1 dose
was low (0.5mg), group 2 dose was medium (1mg) and group 3 dose was high
(2mg). Length of odontoblasts (teeth) was measured as response
variable.
a guinea pig
Exploratory Data Analysis
We fetch the data from the datasets
package, and then
extract only the guinea pigs receiving the Vitamin C supplement. (We
could look at the other group later.)
data(ToothGrowth)
TG = ToothGrowth |>
filter(supp == "VC")
plot(len ~ as.factor(dose), data = TG, col = "grey")
bartlett.test(len ~ as.factor(dose), data = TG)
Bartlett test of homogeneity of variances
data: len by as.factor(dose)
Bartlett's K-squared = 4.5119, df = 2, p-value = 0.1048
Question
Could the dependence of tooth growth on vitamin C be adequately
modelled by a linear regression of len
on
dose
, or is a factorial model with len
and
as.factor(dose)
to be preferred?
Nesting of Linear Effects
Consider a one factor experiment in which the factor levels are
defined in terms of a numerical variable x. In other words, all
individuals at factor level j take the same value of x
for this variable (\(j=1,2,\ldots,K\)).
We could fit a simple linear regression model to the data:
\[M0: Y_i = \beta_0 + \beta_1 x_i +
\varepsilon_i~~~~~~(i=1,2,\ldots,n)\]
We could also fit a standard one-way factorial model which can be
written as a multiple regression model:
\[M1: Y_i = \mu + \alpha_2 z_{i2} + \cdots
+ \alpha_K z_{iK}+\varepsilon_i~~~~~~(i=1,2,\ldots,n)\]
where \(z_{ij}\) is the indicator
variable for unit i being at factor level j as
usual.
The difference between these models is that the simple regression
model (\(M0\)) assumes that the
expected values (means) of the response for each level of the factor
follow a straight line. On the contrary, the one-way model (\(M1\)) allows the mean response to vary
arbitrarily across the levels of the factor. Therefore, the \(M0\) model will be preferred if the
relationship between the factor and the response is linear. The \(M1\) model will be preferred if their
relationship is not linear.
We can show that model \(M0\) is
nested within model \(M1\). It follows
that we can compare models \(M0\) (the
simpler one) and \(M1\) (the more
complex one) using an F test.
Specifically, we will test H0: model \(M0\) adequate; versus
H1: model \(M0\)
not adequate, using the F test statistic:
\[F = \frac{[RSS_{M0} -
RSS_{M1}]/(K-2)}{RSS_{M1}/(n-K)}.\]
\(M1\) has n-K residual
degrees of freedom.
The difference in the number of parameters between the models is
K-2.
Hence the F-statistic has K-2, n-K degrees of
freedom.
If fobs is the observed value of the test
statistic, and X is a random variable from an
FK-2,n-K distribution, then the P-value is
given by
\[P= P(X \ge f_{obs})\]
Retention of H0 indicates that a simple linear
regression model is adequate; i.e. the effect of the variable x
is adequately modelled as linear.
Rejection of H0 indicates that any association
between y and x is non-linear.
Analysis of the Guinea Pig Tooth Data
R Code for Model \(M0\):
Tooth.lm.0 <- lm(len ~ dose, data = TG)
summary(Tooth.lm.0)
Call:
lm(formula = len ~ dose, data = TG)
Residuals:
Min 1Q Median 3Q Max
-8.2264 -2.6029 0.0814 2.2288 7.4893
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.295 1.427 2.309 0.0285 *
dose 11.716 1.079 10.860 1.51e-11 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 3.685 on 28 degrees of freedom
Multiple R-squared: 0.8082, Adjusted R-squared: 0.8013
F-statistic: 117.9 on 1 and 28 DF, p-value: 1.509e-11
R Code for Model \(M1\):
Tooth.lm.1 <- lm(len ~ as.factor(dose), data = TG)
summary(Tooth.lm.1)
Call:
lm(formula = len ~ as.factor(dose), data = TG)
Residuals:
Min 1Q Median 3Q Max
-7.640 -2.248 -0.455 2.027 7.760
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 7.980 1.109 7.196 9.71e-08 ***
as.factor(dose)1 8.790 1.568 5.605 6.02e-06 ***
as.factor(dose)2 18.160 1.568 11.580 5.58e-12 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 3.507 on 27 degrees of freedom
Multiple R-squared: 0.8324, Adjusted R-squared: 0.82
F-statistic: 67.07 on 2 and 27 DF, p-value: 3.357e-11
R Code to compare the models:
anova(Tooth.lm.0, Tooth.lm.1)
Analysis of Variance Table
Model 1: len ~ dose
Model 2: len ~ as.factor(dose)
Res.Df RSS Df Sum of Sq F Pr(>F)
1 28 380.15
2 27 332.00 1 48.146 3.9155 0.05813 .
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Conclusions
The relationship between tooth length and vitamin C is found to be
statistically significant using both the linear regression model
(P<0.0001) and the factor model (P<0.0001).
The F test for comparing the linear effect and factor model
gives an F-statistic of \(f=3.92\) on \(K -
2 = 1\) and \(n - K = 27\)
degrees of freedom.
The corresponding P-value is \(P=0.058\). We would retain
H0 at the 5% significance level, but there is
certainly some evidence to doubt that the relationship should be
modelled as a linear effect.
Example: North Shore Rents 2021
We consider the relationship between the asking rent and the number
of bedrooms available, for accommodation advertised on Auckland’s North
Shore, on 15 May 2021. (Source: Trademe). A few extremely high-priced
outliers have been excluded. One-bedroom accommodation includes studio
apartments. Is it reasonable to assume the relationship between rents
and the number of bedrooms is linear?
## NSrent = read.csv(file = "NSrent2021.csv", header = TRUE)
boxplot(rent ~ as.factor(bedrooms), data = NSrent)
The boxplots indicate the medians rise fairly linearly with the
number of bedrooms, so we might assume this is true for the means as
well. There is a problem with heteroscedasticity, but we will set that
aside for now.
lm1 = lm(rent ~ bedrooms, data = NSrent)
summary(lm1)
Call:
lm(formula = rent ~ bedrooms, data = NSrent)
Residuals:
Min 1Q Median 3Q Max
-482.00 -90.44 -38.88 30.49 1689.87
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 288.261 18.849 15.29 <2e-16 ***
bedrooms 140.623 6.178 22.76 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 191.3 on 709 degrees of freedom
Multiple R-squared: 0.4222, Adjusted R-squared: 0.4214
F-statistic: 518.1 on 1 and 709 DF, p-value: < 2.2e-16
lm2 = lm(rent ~ as.factor(bedrooms), data = NSrent)
anova(lm1, lm2)
Analysis of Variance Table
Model 1: rent ~ bedrooms
Model 2: rent ~ as.factor(bedrooms)
Res.Df RSS Df Sum of Sq F Pr(>F)
1 709 25933643
2 705 25697610 4 236033 1.6189 0.1676
The first lm indicates that there is a significant linear
relationship between rent and the number of bedrooms.
The anova comparison shows that we do not need to suppose the
relationship is nonlinear: i.e. the linear trend is sufficient to
describe the relationship (p-value of 0.1676). This is good, because a
simple straight-line model is easy to interpret.
As for the heteroscedasticity, we might be tempted to try to
stabilise the variance by a transforming the bedrooms
variable, but that would destroy the simplicity of the linear
relationship. Instead, in a later topic we will allow for the
heteroscedasticity by using a method called weighted least squares.
Analysis of Genetic Data
A haplotype is a unit of genetic information contained on a single
chromosome. Because chromosomes come in pairs (one inherited from each
parent), an individual may have either zero, one or two copies of any
given haplotype. The effects of a haplotype on some phenotype
(measurable physical attribute) may or may not be linear in the number
of copies of the haplotype.
a chromosome
A measure of cholesterol was recorded on 35 subjects. Of these, 8
have zero copies, 16 had one copy, and 11 had two copies of a particular
haplotype.
Fitting the number of copies of the haplotype as a linear effect gave
a residual sum of squares of \(153.2\).
Fitting the number of copies of the haplotype as a factor gave a
residual sum of squares of \(126.2\).
Question
What is the value of the F-statistic for testing whether the
effect of haplotype is linear in the number of copies of the
haplotype?
What are the degrees of freedom for this test statistic?
LS0tDQp0aXRsZTogIkxlY3R1cmUgMjE6IEZhY3RvciBvciBOdW1lcmljYWwgQ292YXJpYXRlPyINCnN1YnRpdGxlOiAxNjEuMjUxIFJlZ3Jlc3Npb24gTW9kZWxsaW5nDQphdXRob3I6ICJQcmVzZW50ZWQgYnkgSm9uYXRoYW4gR29kZnJleSA8YS5qLmdvZGZyZXlAbWFzc2V5LmFjLm56PiIgIA0KZGF0ZTogIldlZWsgNyBvZiBTZW1lc3RlciAyLCBgciBsdWJyaWRhdGU6OnllYXIobHVicmlkYXRlOjpub3coKSlgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogeWV0aQ0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgaHRtbF9ub3RlYm9vazoNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIGlvc2xpZGVzX3ByZXNlbnRhdGlvbjoNCiAgICB3aWRlc2NyZWVuOiB0cnVlDQogICAgc21hbGxlcjogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0DQogIHNsaWR5X3ByZXNlbnRhdGlvbjogDQogICAgdGhlbWU6IHlldGkNCiAgICBoaWdobGlnaHQ6IHRhbmdvDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoNCg0KDQoNCg0KW1ZpZXcgdGhlIGxhdGVzdCByZWNvcmRpbmcgb2YgdGhpcyBsZWN0dXJlXShodHRwczovL1ItUmVzb3VyY2VzLm1hc3NleS5hYy5uei92aWRlb3MvMjUxTDIxLm1wNCkNCjwhLS0tIERhdGEgaXMgb24NCmh0dHBzOi8vci1yZXNvdXJjZXMubWFzc2V5LmFjLm56L2RhdGEvMTYxMjUxLw0KLS0tPg0KDQpgYGB7ciBzZXR1cCwgcHVybD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldChkZXY9YygicG5nIiwgInBkZiIpKQ0Kb3B0c19jaHVuayRzZXQoZmlnLmhlaWdodD02LCBmaWcud2lkdGg9NywgZmlnLnBhdGg9IkZpZ3VyZXMvIiwgZmlnLmFsdD0idW5sYWJlbGxlZCIpDQpvcHRzX2NodW5rJHNldChjb21tZW50PSIiLCBmaWcuYWxpZ249ImNlbnRlciIsIHRpZHk9VFJVRSkNCm9wdGlvbnMoa25pdHIua2FibGUuTkEgPSAnJykNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCjwhLS0tIERvIG5vdCBlZGl0IGFueXRoaW5nIGFib3ZlIHRoaXMgbGluZS4gLS0tPg0K77u/DQo8IS0tLSBOLkIuIFdlIHVzZSBhIGNvbW1hbmQgZnJvbSB0aGUgYGJyb29tYCBwYWNrYWdlIGluIHRoZSBleGFtcGxlLiAtLS0+DQoNCmBgYHtyIGV4dHJhTGliLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShicm9vbSkNCmBgYA0KDQoNCmBgYHtyIEpHRnVuY3Rpb24sIGVjaG8gPSBGQUxTRX0NCiMgdGhpcyBmdW5jdGlvbiBnZXRzIHJpZCBvZiBzY2llbnRpZmljIG5vdGF0aW9uIHdoZW4gd2Ugd2FudCBQIHZhbHVlcyBpbiB0aGUgcGFyYWdyYXBocy4NClByZXR0eVBWYWwgPSBmdW5jdGlvbih4LCBkaWdpdHM9NCl7DQpSb3VuZGVkID0gcm91bmQoeCwgZGlnaXRzKQ0KVGhyZXNob2xkID0gMTBeKC1kaWdpdHMpDQpyZXR1cm4oaWZlbHNlKFJvdW5kZWQgPCBUaHJlc2hvbGQsIHBhc3RlMCgiUDwiLCBmb3JtYXQoVGhyZXNob2xkLCBzY2llbnRpZmljPUZBTFNFKSksIHBhc3RlMCgiUD0iLCBSb3VuZGVkKSkpDQp9DQpgYGANCg0KDQpTb21ldGltZXMgaXQgaXMgdW5jbGVhciBhcyB0byB3aGV0aGVyIGEgcGFydGljdWxhciBleHBsYW5hdG9yeQ0KICAgIHZhcmlhYmxlIHNob3VsZCBiZSByZWdhcmRlZCBhcyBhIGZhY3RvciAoY2F0ZWdvcmljYWwgZXhwbGFuYXRvcnkNCiAgICB2YXJpYWJsZSkgb3IgYSBudW1lcmljYWwgY292YXJpYXRlLg0KDQpGb3IgZXhhbXBsZSwgc2hvdWxkIHRoZSBlZmZlY3Qgb2YgYSBkcnVnIGJlIG1vZGVsbGVkIHVzaW5nIGEgZm91cg0KICAgIGxldmVsIGZhY3RvciAoemVybywgbG93LCBtZWRpdW0gYW5kIGhpZ2ggZG9zZXMpIG9yIGFzIGEgbnVtZXJpYw0KICAgIHZhcmlhYmxlICgwLCAxMCwgMjAsIDMwIG1sIGRvc2VzKT8NCg0KV2Ugd2lsbCBleHBsb3JlIHRoaXMgaXNzdWUgaW4gdGhpcyBsZWN0dXJlLCBhbmQgZGV2ZWxvcCBhbg0KICAgIGFwcHJvcHJpYXRlIG1ldGhvZG9sb2d5IHRvIGNvbXBhcmUgdGhlIHR3byBtb2RlbGxpbmcgYXBwcm9hY2hlcy4NCg0KIyMgVml0YW1pbiBDIGFuZCBUb290aCBHcm93dGgNCg0KDQoNCldlIHVzZSBhbiBleHBlcmltZW50IGludG8gdGhlIGVmZmVjdHMgb2Ygdml0YW1pbiBDIG9uIHRvb3RoIGdyb3d0aCB0byBpbGx1c3RyYXRlIHRoaXMgcXVlc3Rpb24uDQoNCjMwIGd1aW5lYSBwaWdzIHdlcmUgZGl2aWRlZCAoYXQgcmFuZG9tKSBpbnRvIHRocmVlIGdyb3VwcyBvZiB0ZW4gYW5kIGRvc2VkIHdpdGggdml0YW1pbiBDIGluIG1nIChhZG1pbmlzdGVyZWQgaW4gb3JhbmdlIGp1aWNlKS4NCkdyb3VwIDEgZG9zZSB3YXMgbG93ICgwLjVtZyksIGdyb3VwIDIgZG9zZSB3YXMgbWVkaXVtICgxbWcpIGFuZCBncm91cCAzIGRvc2Ugd2FzIGhpZ2ggKDJtZykuDQpMZW5ndGggb2Ygb2RvbnRvYmxhc3RzICh0ZWV0aCkgd2FzIG1lYXN1cmVkIGFzIHJlc3BvbnNlIHZhcmlhYmxlLg0KDQohW2EgZ3VpbmVhIHBpZ10oLi4vZ3JhcGhpY3MvZ3VpbmVhcGlnLmpwZykNCg0KDQoNCg0KIyMjIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KV2UgZmV0Y2ggdGhlIGRhdGEgZnJvbSB0aGUgYGRhdGFzZXRzYCBwYWNrYWdlLCBhbmQgdGhlbiBleHRyYWN0IG9ubHkgdGhlIGd1aW5lYSBwaWdzIHJlY2VpdmluZyB0aGUgVml0YW1pbiBDIHN1cHBsZW1lbnQuIChXZSBjb3VsZCBsb29rIGF0IHRoZSBvdGhlciBncm91cCBsYXRlci4pDQoNCmBgYHtyIGJveHBsb3RMZW5ndGhEb3NlfQ0KZGF0YShUb290aEdyb3d0aCkNClRHID0gVG9vdGhHcm93dGggfD4gDQogIGZpbHRlcihzdXBwID09ICJWQyIpDQpwbG90KGxlbiB+IGFzLmZhY3Rvcihkb3NlKSwgZGF0YT1URywgY29sPSJncmV5IikNCmJhcnRsZXR0LnRlc3QobGVuIH4gYXMuZmFjdG9yKGRvc2UpLCBkYXRhPVRHKQ0KYGBgDQoNCg0KIyMjIEluaXRpYWwgQ29tbWVudHMNCg0KVGhlICBgYXMuZmFjdG9yKClgIGZ1bmN0aW9uIHRlbGxzIFIgdG8gcmVnYXJkIHRoZSAobnVtZXJpYyANCiAgICB2YXJpYWJsZSkgYGRvc2VgIGFzIGEgZmFjdG9yLg0KDQpUaGUgbGV2ZWxzIGFyZSBvcmRlcmVkIGluIHRoZSBuYXR1cmFsIHdheS4NCg0KVGhlIGJveCBwbG90IGlzIHNsaWdodGx5IHN1Z2dlc3RpdmUgb2YgYSBjaGFuZ2Ugb2YgZGlzcGVyc2lvbg0KICAgIChzcHJlYWQpIGluIHRoZSByZXNwb25zZSBiZXR3ZWVuIHRoZSBncm91cHMsIGJ1dCBCYXJ0bGV0dOKAmXMgdGVzdA0KICAgIGRvZXMgbm90IHByb3ZpZGUgY2xlYXIgZXZpZGVuY2Ugb2YgaGV0ZXJvc2NlZGFzdGljaXR5ICgqUCotdmFsdWUgaXMNCiAgICAqUD0wLjEwNDgqKS4NCg0KRnJvbSB0aGUgcGxvdCBpdCBzZWVtcyBoaWdobHkgcGxhdXNpYmxlIHRoYXQgbWVhbiB0b290aCBncm93dGgNCiAgICBkZXBlbmRzIG9uIHZpdGFtaW4gQyBsZXZlbHMuDQoNCiMjIyBRdWVzdGlvbg0KDQogQ291bGQgdGhlIGRlcGVuZGVuY2Ugb2YgdG9vdGggZ3Jvd3RoIG9uICAgdml0YW1pbiBDIGJlIGFkZXF1YXRlbHkgbW9kZWxsZWQgYnkgYSBsaW5lYXIgcmVncmVzc2lvbiBvZiBgbGVuYCBvbiBgZG9zZWAsIG9yICAgaXMgYSBmYWN0b3JpYWwgbW9kZWwgd2l0aCBgbGVuYCBhbmQgYGFzLmZhY3Rvcihkb3NlKWAgdG8gYmUNCiAgICBwcmVmZXJyZWQ/DQoNCiMjIE5lc3Rpbmcgb2YgTGluZWFyIEVmZmVjdHMNCg0KQ29uc2lkZXIgYSBvbmUgZmFjdG9yIGV4cGVyaW1lbnQgaW4gd2hpY2ggdGhlIGZhY3RvciBsZXZlbHMgYXJlDQogICAgZGVmaW5lZCBpbiB0ZXJtcyBvZiBhIG51bWVyaWNhbCB2YXJpYWJsZSAqeCouIEluIG90aGVyIHdvcmRzLCBhbGwNCiAgICBpbmRpdmlkdWFscyBhdCBmYWN0b3IgbGV2ZWwgKmoqIHRha2UgdGhlIHNhbWUgdmFsdWUgb2YgKngqIGZvcg0KICAgIHRoaXMgdmFyaWFibGUgKCRqPTEsMixcbGRvdHMsSyQpLg0KDQpXZSBjb3VsZCBmaXQgYSBzaW1wbGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgdG8gdGhlIGRhdGE6DQoNCiQkTTA6IFlfaSA9IFxiZXRhXzAgKyBcYmV0YV8xIHhfaSArIFx2YXJlcHNpbG9uX2l+fn5+fn4oaT0xLDIsXGxkb3RzLG4pJCQNCg0KV2UgY291bGQgYWxzbyBmaXQgYSBzdGFuZGFyZCBvbmUtd2F5IGZhY3RvcmlhbCBtb2RlbCB3aGljaCBjYW4gYmUgd3JpdHRlbg0KICAgIGFzIGEgbXVsdGlwbGUgcmVncmVzc2lvbiBtb2RlbDoNCg0KJCRNMTogWV9pID0gXG11ICsgXGFscGhhXzIgel97aTJ9ICsgXGNkb3RzICsgXGFscGhhX0sgel97aUt9K1x2YXJlcHNpbG9uX2l+fn5+fn4oaT0xLDIsXGxkb3RzLG4pJCQNCg0Kd2hlcmUgJHpfe2lqfSQgaXMgdGhlIGluZGljYXRvciB2YXJpYWJsZSBmb3IgdW5pdCAqaSogYmVpbmcgYXQgIGZhY3RvciBsZXZlbCAqaiogYXMgdXN1YWwuDQoNClRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlc2UgbW9kZWxzIGlzIHRoYXQgdGhlIHNpbXBsZSByZWdyZXNzaW9uIG1vZGVsICgkTTAkKSBhc3N1bWVzIHRoYXQgdGhlIGV4cGVjdGVkIHZhbHVlcyAobWVhbnMpIG9mIHRoZSByZXNwb25zZSBmb3IgZWFjaCBsZXZlbCBvZiB0aGUgZmFjdG9yIGZvbGxvdyBhIHN0cmFpZ2h0IGxpbmUuIE9uIHRoZSBjb250cmFyeSwgdGhlIG9uZS13YXkgbW9kZWwgKCRNMSQpIGFsbG93cyB0aGUgbWVhbiByZXNwb25zZSB0byB2YXJ5IGFyYml0cmFyaWx5IGFjcm9zcyB0aGUgbGV2ZWxzIG9mIHRoZSBmYWN0b3IuIFRoZXJlZm9yZSwgdGhlICRNMCQgbW9kZWwgd2lsbCBiZSBwcmVmZXJyZWQgaWYgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBmYWN0b3IgYW5kIHRoZSByZXNwb25zZSBpcyBsaW5lYXIuIFRoZSAkTTEkIG1vZGVsIHdpbGwgYmUgcHJlZmVycmVkIGlmIHRoZWlyIHJlbGF0aW9uc2hpcCBpcyBub3QgbGluZWFyLg0KIA0KV2UgY2FuIHNob3cgdGhhdCBtb2RlbCAkTTAkIGlzIG5lc3RlZCB3aXRoaW4gbW9kZWwgJE0xJC4gSXQgZm9sbG93cyB0aGF0IHdlIGNhbiBjb21wYXJlIG1vZGVscyAkTTAkICh0aGUgc2ltcGxlciBvbmUpIGFuZCAkTTEkICh0aGUgbW9yZSBjb21wbGV4IG9uZSkgdXNpbmcgYW4gKkYqIHRlc3QuDQoNClNwZWNpZmljYWxseSwgd2Ugd2lsbCB0ZXN0ICAgICAqSH4wfio6IG1vZGVsICRNMCQgYWRlcXVhdGU7IHZlcnN1cyAqSH4xfio6IG1vZGVsICRNMCQgbm90IGFkZXF1YXRlLA0KICAgIHVzaW5nIHRoZSAqRiogdGVzdCBzdGF0aXN0aWM6DQoNCiQkRiA9IFxmcmFje1tSU1Nfe00wfSAtIFJTU197TTF9XS8oSy0yKX17UlNTX3tNMX0vKG4tSyl9LiQkDQoNCg0KJE0xJCBoYXMgKm4tSyogcmVzaWR1YWwgZGVncmVlcyBvZiBmcmVlZG9tLg0KDQpUaGUgZGlmZmVyZW5jZSBpbiB0aGUgbnVtYmVyIG9mIHBhcmFtZXRlcnMgYmV0d2VlbiB0aGUgbW9kZWxzIGlzICpLLTIqLg0KDQpIZW5jZSB0aGUgKkYqLXN0YXRpc3RpYyBoYXMgKkstMiwgbi1LKiBkZWdyZWVzIG9mIGZyZWVkb20uDQoNCklmICpmfm9ic34qIGlzIHRoZSBvYnNlcnZlZCB2YWx1ZSBvZiB0aGUgdGVzdCBzdGF0aXN0aWMsIGFuZA0KICAgICpYKiBpcyBhIHJhbmRvbSB2YXJpYWJsZSBmcm9tIGFuICpGfkstMixuLUt+KiBkaXN0cmlidXRpb24sDQogICAgdGhlbiB0aGUgKlAqLXZhbHVlIGlzIGdpdmVuIGJ5IA0KDQokJFA9IFAoWCBcZ2UgZl97b2JzfSkkJA0KDQpSZXRlbnRpb24gb2YgKkh+MH4qIGluZGljYXRlcyB0aGF0IGEgc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsDQogICAgaXMgYWRlcXVhdGU7IGkuZS4gdGhlIGVmZmVjdCBvZiB0aGUgdmFyaWFibGUgKngqIGlzIGFkZXF1YXRlbHkNCiAgICBtb2RlbGxlZCBhcyBsaW5lYXIuDQoNClJlamVjdGlvbiBvZiAqSH4wfiogaW5kaWNhdGVzIHRoYXQgYW55IGFzc29jaWF0aW9uIGJldHdlZW4gKnkqDQogICAgYW5kICp4KiBpcyBub24tbGluZWFyLg0KDQojIyBBbmFseXNpcyBvZiB0aGUgR3VpbmVhIFBpZyBUb290aCBEYXRhDQoNClIgQ29kZSBmb3IgTW9kZWwgJE0wJDoNCg0KYGBge3IgVG9vdGgubG0uMH0NClRvb3RoLmxtLjAgPC0gbG0obGVuIH4gZG9zZSwgZGF0YT1URykNCnN1bW1hcnkoVG9vdGgubG0uMCkNCmBgYA0KDQoNClIgQ29kZSBmb3IgTW9kZWwgJE0xJDoNCg0KYGBge3IgVG9vdGgubG0uMX0NClRvb3RoLmxtLjEgPC0gbG0obGVuIH4gIGFzLmZhY3Rvcihkb3NlKSwgZGF0YT1URykNCnN1bW1hcnkoVG9vdGgubG0uMSkNCmBgYA0KDQpSIENvZGUgdG8gY29tcGFyZSB0aGUgbW9kZWxzOg0KDQpgYGB7ciBhbm92YTF9DQphbm92YShUb290aC5sbS4wLCBUb290aC5sbS4xKQ0KYGBgDQoNCiMjIyBDb25jbHVzaW9ucw0KDQpUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdG9vdGggbGVuZ3RoIGFuZCB2aXRhbWluIEMgaXMgZm91bmQgdG8gYmUNCiAgICBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHVzaW5nIGJvdGggdGhlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsICgqYHIgUHJldHR5UFZhbChnbGFuY2UoVG9vdGgubG0uMCkkcC52YWx1ZSlgKikgYW5kIHRoZSBmYWN0b3IgbW9kZWwgKCpgciBQcmV0dHlQVmFsKGdsYW5jZShUb290aC5sbS4xKSRwLnZhbHVlKWAqKS4NCg0KVGhlICpGKiB0ZXN0IGZvciBjb21wYXJpbmcgdGhlIGxpbmVhciBlZmZlY3QgYW5kIGZhY3RvciBtb2RlbCBnaXZlcyBhbg0KICAgICpGKi1zdGF0aXN0aWMgb2YgJGY9My45MiQgb24gJEsgLSAyID0gMSQgYW5kICRuIC0gSyA9IDI3JA0KICAgIGRlZ3JlZXMgb2YgZnJlZWRvbS4NCg0KVGhlIGNvcnJlc3BvbmRpbmcgKlAqLXZhbHVlIGlzICRQPTAuMDU4JC4gV2Ugd291bGQgcmV0YWluICpIfjB+KiBhdA0KICAgIHRoZSA1JSBzaWduaWZpY2FuY2UgbGV2ZWwsIGJ1dCB0aGVyZSBpcyBjZXJ0YWlubHkgc29tZSBldmlkZW5jZSB0bw0KICAgIGRvdWJ0IHRoYXQgdGhlIHJlbGF0aW9uc2hpcCBzaG91bGQgYmUgbW9kZWxsZWQgYXMgYSBsaW5lYXIgZWZmZWN0Lg0KDQoNCiMjIEV4YW1wbGU6ICBOb3J0aCBTaG9yZSBSZW50cyAyMDIxDQoNCldlIGNvbnNpZGVyIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgYXNraW5nIHJlbnQgYW5kIHRoZSBudW1iZXIgb2YgYmVkcm9vbXMgYXZhaWxhYmxlLCBmb3IgYWNjb21tb2RhdGlvbiBhZHZlcnRpc2VkIG9uIEF1Y2tsYW5kJ3MgTm9ydGggU2hvcmUsIG9uIDE1IE1heSAyMDIxLiAgKFNvdXJjZTogVHJhZGVtZSkuICBBIGZldyBleHRyZW1lbHkgaGlnaC1wcmljZWQgb3V0bGllcnMgaGF2ZSBiZWVuIGV4Y2x1ZGVkLiBPbmUtYmVkcm9vbSBhY2NvbW1vZGF0aW9uIGluY2x1ZGVzIHN0dWRpbyBhcGFydG1lbnRzLg0KSXMgaXQgcmVhc29uYWJsZSB0byBhc3N1bWUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHJlbnRzIGFuZCB0aGUgbnVtYmVyIG9mIGJlZHJvb21zIGlzIGxpbmVhcj8gDQoNCmBgYHtyIGJlZHJvb21zLCBlY2hvID0gLTEsIGV2YWwgPSAtMn0NCk5TcmVudD1yZWFkLmNzdihmaWxlPSAiLi4vLi4vZGF0YS9OU3JlbnQyMDIxLmNzdiIsaGVhZGVyPVRSVUUpDQpOU3JlbnQgPSByZWFkLmNzdihmaWxlID0gIk5TcmVudDIwMjEuY3N2IiwgaGVhZGVyID0gVFJVRSkNCmJveHBsb3QocmVudCB+IGFzLmZhY3RvcihiZWRyb29tcyksIGRhdGEgPSBOU3JlbnQpDQpgYGANCg0KVGhlIGJveHBsb3RzIGluZGljYXRlIHRoZSBtZWRpYW5zIHJpc2UgZmFpcmx5IGxpbmVhcmx5IHdpdGggdGhlIG51bWJlciBvZiBiZWRyb29tcywgc28gd2UgbWlnaHQgYXNzdW1lIHRoaXMgaXMgdHJ1ZSBmb3IgdGhlIG1lYW5zIGFzIHdlbGwuICBUaGVyZSBpcyBhIHByb2JsZW0gd2l0aCBoZXRlcm9zY2VkYXN0aWNpdHksIGJ1dCB3ZSB3aWxsIHNldCB0aGF0IGFzaWRlIGZvciBub3cuIA0KDQpgYGB7ciBjb21wYXJlIGxtc30NCmxtMSA9IGxtKHJlbnR+IGJlZHJvb21zLCBkYXRhID0gTlNyZW50KQ0Kc3VtbWFyeShsbTEpDQpsbTIgPSBsbShyZW50IH4gYXMuZmFjdG9yKGJlZHJvb21zKSwgZGF0YSA9IE5TcmVudCkNCmFub3ZhKGxtMSwgbG0yKQ0KYGBgDQoNClRoZSBmaXJzdCBsbSBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBhIHNpZ25pZmljYW50IGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiByZW50IGFuZCB0aGUgbnVtYmVyIG9mIGJlZHJvb21zLiANCg0KVGhlIGFub3ZhIGNvbXBhcmlzb24gc2hvd3MgdGhhdCB3ZSBkbyBub3QgbmVlZCB0byBzdXBwb3NlIHRoZSByZWxhdGlvbnNoaXAgaXMgbm9ubGluZWFyOiBpLmUuIHRoZSBsaW5lYXIgdHJlbmQgaXMgc3VmZmljaWVudCB0byBkZXNjcmliZSB0aGUgcmVsYXRpb25zaGlwIChwLXZhbHVlIG9mIDAuMTY3NikuIFRoaXMgaXMgZ29vZCwgYmVjYXVzZSBhIHNpbXBsZSBzdHJhaWdodC1saW5lIG1vZGVsIGlzIGVhc3kgdG8gaW50ZXJwcmV0LiANCg0KQXMgZm9yIHRoZSBoZXRlcm9zY2VkYXN0aWNpdHksIHdlIG1pZ2h0IGJlIHRlbXB0ZWQgdG8gdHJ5IHRvIHN0YWJpbGlzZSB0aGUgdmFyaWFuY2UgYnkgYSB0cmFuc2Zvcm1pbmcgdGhlIGBiZWRyb29tc2AgdmFyaWFibGUsIGJ1dCB0aGF0IHdvdWxkIGRlc3Ryb3kgdGhlIHNpbXBsaWNpdHkgb2YgdGhlIGxpbmVhciByZWxhdGlvbnNoaXAuICBJbnN0ZWFkLCBpbiBhIGxhdGVyIHRvcGljIHdlIHdpbGwgYWxsb3cgZm9yIHRoZSBoZXRlcm9zY2VkYXN0aWNpdHkgYnkgdXNpbmcgYSBtZXRob2QgY2FsbGVkIHdlaWdodGVkIGxlYXN0IHNxdWFyZXMuIA0KDQoNCg0KIyMgQW5hbHlzaXMgb2YgR2VuZXRpYyBEYXRhDQoNCkEgaGFwbG90eXBlIGlzIGEgdW5pdCBvZiBnZW5ldGljIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBvbiBhIHNpbmdsZSBjaHJvbW9zb21lLg0KQmVjYXVzZSBjaHJvbW9zb21lcyBjb21lIGluIHBhaXJzIChvbmUgaW5oZXJpdGVkIGZyb20gZWFjaCBwYXJlbnQpLCBhbiBpbmRpdmlkdWFsIG1heSBoYXZlIGVpdGhlciB6ZXJvLCBvbmUgb3IgdHdvIGNvcGllcyBvZiBhbnkgZ2l2ZW4gaGFwbG90eXBlLg0KVGhlIGVmZmVjdHMgb2YgYSBoYXBsb3R5cGUgb24gc29tZSBwaGVub3R5cGUgKG1lYXN1cmFibGUgcGh5c2ljYWwgYXR0cmlidXRlKSBtYXkgb3IgbWF5IG5vdCBiZSBsaW5lYXIgaW4gdGhlIG51bWJlciBvZiBjb3BpZXMgb2YgdGhlIGhhcGxvdHlwZS4NCg0KIVthIGNocm9tb3NvbWVdKC4uL2dyYXBoaWNzL2Nocm9tb3NvbWUuanBnKQ0KDQoNCg0KDQoNCkEgbWVhc3VyZSBvZiBjaG9sZXN0ZXJvbCB3YXMgcmVjb3JkZWQgb24gMzUgc3ViamVjdHMuIE9mIHRoZXNlLCA4DQogICAgaGF2ZSB6ZXJvIGNvcGllcywgMTYgaGFkIG9uZSBjb3B5LCBhbmQgMTEgaGFkIHR3byBjb3BpZXMgb2YgYQ0KICAgIHBhcnRpY3VsYXIgaGFwbG90eXBlLg0KDQpGaXR0aW5nIHRoZSBudW1iZXIgb2YgY29waWVzIG9mIHRoZSBoYXBsb3R5cGUgYXMgYSBsaW5lYXIgZWZmZWN0DQogICAgZ2F2ZSBhIHJlc2lkdWFsIHN1bSBvZiBzcXVhcmVzIG9mICQxNTMuMiQuDQoNCkZpdHRpbmcgdGhlIG51bWJlciBvZiBjb3BpZXMgb2YgdGhlIGhhcGxvdHlwZSBhcyBhIGZhY3RvciBnYXZlIGENCiAgICByZXNpZHVhbCBzdW0gb2Ygc3F1YXJlcyBvZiAkMTI2LjIkLg0KDQoNCiMjIyBRdWVzdGlvbg0KDQoNCldoYXQgaXMgdGhlIHZhbHVlIG9mIHRoZSAqRiotc3RhdGlzdGljIGZvciB0ZXN0aW5nIHdoZXRoZXIgdGhlIGVmZmVjdCBvZg0KaGFwbG90eXBlIGlzIGxpbmVhciBpbiB0aGUgbnVtYmVyIG9mIGNvcGllcyBvZiB0aGUgaGFwbG90eXBlPyANCg0KV2hhdCBhcmUNCnRoZSBkZWdyZWVzIG9mIGZyZWVkb20gZm9yIHRoaXMgdGVzdCBzdGF0aXN0aWM/DQo=