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

unlabelled

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

Initial Comments

The as.factor() function tells R to regard the (numeric variable) dose as a factor.

The levels are ordered in the natural way.

The box plot is slightly suggestive of a change of dispersion (spread) in the response between the groups, but Bartlett’s test does not provide clear evidence of heteroscedasticity (P-value is P=0.1048).

From the plot it seems highly plausible that mean tooth growth depends on vitamin C levels.

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)

unlabelled

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 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=