Onderzoekers bestuderen of er een associatie tussen het de dikte van
de speklaag van varkens is met het percentage vlees van varkens
(permeat). Ze willen ook weten of deze associatie verschilt tussen
mannelijke en vrouwelijke varkens. Uit voorgaand onderzoek weten de
onderzoekers dat er een associatie is tussen het de lengte van het
varken en het percentage vlees.
Data exploratie
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
We lezen de data in, en filteren de data aangezien we het gewicht
niet als variabele zullen gebruiken.
pigs <- read.csv(file = "https://raw.githubusercontent.com/statOmics/biostatistics21/master/pigs.csv")
pigs <- pigs %>% subset(select = -weight)
## [1] 200 4
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
##
## Attaching package: 'GGally'
## The following object is masked _by_ '.GlobalEnv':
##
## pigs
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Hieruit zien we dat er een duidelijke lineaire associatie is tussen
het percentage vlees en de dikte van de speklaag. Er is geen duidelijke
associatie tussen het percentage vlees en de lengte van het varken. Wel
lijkt er een verschil van percentage vlees te zijn tussen de
verschillende geslachten.
We bekijken verder de associaties tussen het percentage vlees en de
dikte van de speklaag per geslacht. Dit doen we ook voor de associatie
met de lengte.
pigs %>% ggplot(aes(x=bacon,y=permeat)) +
geom_point() +
stat_smooth(method = "lm") +
facet_wrap(~sex)
## `geom_smooth()` using formula = 'y ~ x'
pigs %>% ggplot(aes(x=length,y=permeat)) +
geom_point() +
stat_smooth(method = "lm") +
facet_wrap(~sex)
## `geom_smooth()` using formula = 'y ~ x'
Het effect van zowel de dikte van de speklaag en de lengte lijkt
licht te verschillen tussen mannelijke en vrouwelijke varkens. Er is dus
mogelijks een interactie tussen dikte van de speklaag en gender en
lengte en gender.
Algemeen lineair model
opstellen
We modelleren eerst het percentage vlees in functie van alle
variabelen, samen met alle tweeweg interactietermen. We modelleren dus
eerst: \(E[permeat] = \beta_{bacon} x_{bacon}
+ \beta_{length} x_{length} + \beta_{sex} x_{sex} + \beta_{bacon:length}
x_{bacon} x_{length} + \beta_{bacon:sex} x_{bacon} x_{sex} +
\beta_{length:sex} x_{length} x_{sex}\)
Merk op dat je hier geen bacon * length * sex kunt gebruiken,
aangezien er dan ook de drieweg-interactie sex:bacon:length zou zijn,
wat buiten de scope van de cursus valt.
lm_1 <- lm(permeat ~ bacon + length + sex + bacon:length + bacon:sex + length:sex, data = pigs)
summary(lm_1)
##
## Call:
## lm(formula = permeat ~ bacon + length + sex + bacon:length +
## bacon:sex + length:sex, data = pigs)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.7348 -1.3624 0.0503 1.1857 4.4786
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 94.70945 23.94088 3.956 0.000107 ***
## bacon -2.08616 1.85825 -1.123 0.262984
## length -0.21988 0.29564 -0.744 0.457927
## sexmale 13.78461 13.65856 1.009 0.314129
## bacon:length 0.01105 0.02294 0.482 0.630650
## bacon:sexmale 0.31806 0.14579 2.182 0.030343 *
## length:sexmale -0.24927 0.16745 -1.489 0.138214
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.949 on 193 degrees of freedom
## Multiple R-squared: 0.786, Adjusted R-squared: 0.7794
## F-statistic: 118.2 on 6 and 193 DF, p-value: < 2.2e-16
We gaan de assumpties van het lineaire model na:
Alle assumpties lijken voldaan: De residuen zijn gemiddeld 0 voor
elke respons waarde, de residuen zijn normaal verdeeld en de variantie
is constant.
We gaan verder met het bekijken welke variabelen we in het model
behouden. We gaan via een anova met type 3 kwadratensommen na of de
variabelen significant zijn. We beginnen met enkel de interactietermen
te bekijken.
## Loading required package: carData
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
## The following object is masked from 'package:purrr':
##
## some
Anova(lm_1, type = "III")
Zowel de interactieterm bacon:length als de interactieterm length:sex
zijn niet significant op het 5% significantieniveau. We verwijderen de
minst significante, bacon:length, en voeren opnieuw een anova met type 3
kwadratensommen uit.
lm_2 <- lm(permeat ~ bacon + length + sex + bacon:sex + length:sex, data = pigs)
Anova(lm_2, type = "III")
De interactie length:sex is weer niet significant. We verwijderen
deze uit het model en voeren opnieuw een anova met type 3
kwadratensommen uit.
lm_3 <- lm(permeat ~ bacon + length + sex + bacon:sex , data = pigs)
Anova(lm_3, type = "III")
We zien dat de resterende variabelen en interactieterm allemaal
significant zijn. We behouden het model met de drie hoofdvariabelen en
een interactieterm tussen bacon en geslacht.
We bekijken of de modelassumpties voldaan zijn voor dit model.
De assumpties lijken weer voldaan.
Hypotheses testen
De onderzoekers wilden volgende hypotheses testen:
- Is er een associatie tussen het percentage vlees en de dikte van de
speklaag?
- Is er een verschil in de associatie tussen het percentage vlees en
de dikte van de speklaag bij de verschillende geslachten?
Dit vertaalt zich naar de volgende hypotheses:
\[1.\quad H_0: \beta_{bacon} = 0 :
\text{Er is geen lineaire associatie tussen het vleespercentage en de
dikte speklaag bij zeugen.}\] \[\updownarrow\] \[H_1: \beta_{bacon} \neq 0 : \text{Er is een
lineaire associatie tussen het vleespercentage en de dikte speklaag bij
zeugen}\]
\[2.\quad H_0: \beta_{bacon} +
\beta_{bacon:sex}= 0 : \text{Er is geen lineaire associatie tussen het
vleespercentage en de dikte speklaag bij beren (mannelijke
varkens).}\] \[\updownarrow\]
\[H_1: \beta_{bacon} + \beta_{bacon:sex} \neq
0 : \text{Er is een lineaire associatie tussen het vleespercentage en de
dikte speklaag bij beren (mannelijke varkens).}\]
\[3. \quad H_0:\beta_{bacon:sex} = 0 :
\text{De associatie tussen de dikte van de speklaag en het vetpercentage
is gelijk bij zeugen en beren.}\] \[\updownarrow\] \[H_1: \beta_{bacon:sex} \neq 0 : \text{De
associatie tussen de dikte van de speklaag en het vetpercentage is
verschillend bij zeugen en beren.}\]
We voeren eerst en omnibus test uit waarbij we alle nulhypotheses
simultaan falsifiëren, we kunnen dit door simultaan te testen voor het
hoofdeffect voor bacon en de bacon \(\times\) sex interactie:
\[H_0: \beta_{bacon} = \beta_{bacon:sex} =
0. \] \[\updownarrow\] \[H_1: \beta_{bacon} \neq 0 \text{ en, of }
\beta_{bacon:sex} \neq 0. \]
De omnibushypothese kunnen we evalueren met een F-test tussen het
volledig model en met het model dat enkel het hoofdeffect van lengte en
geslacht bevat.
lm_4 <- lm(permeat ~ length + sex , data = pigs)
anova(lm_3,lm_4)
Gezien we de omnibus hypothese heel extreem significant kunnen
verwerpen, evalueren we in een posthoc analyse of er een associatie is
tussen de dikte van de speklaag en het vleespercentage bij zeugen, beren
en of er een verschil is tussen de associatie bij zeugen en beren.
## Loading required package: mvtnorm
## Loading required package: survival
## Loading required package: TH.data
## Loading required package: MASS
##
## Attaching package: 'MASS'
## The following object is masked from 'package:dplyr':
##
## select
##
## Attaching package: 'TH.data'
## The following object is masked from 'package:MASS':
##
## geyser
mcp <- glht(lm_3,linfct = c("bacon = 0",
"bacon + bacon:sexmale = 0",
"bacon:sexmale = 0"
))
summary(mcp)
##
## Simultaneous Tests for General Linear Hypotheses
##
## Fit: lm(formula = permeat ~ bacon + length + sex + bacon:sex, data = pigs)
##
## Linear Hypotheses:
## Estimate Std. Error t value Pr(>|t|)
## bacon == 0 -1.19081 0.13182 -9.034 <0.001 ***
## bacon + bacon:sexmale == 0 -0.87572 0.06286 -13.930 <0.001 ***
## bacon:sexmale == 0 0.31509 0.14603 2.158 0.0733 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## (Adjusted p values reported -- single-step method)
confintModel <- confint(mcp)
confintModel
##
## Simultaneous Confidence Intervals
##
## Fit: lm(formula = permeat ~ bacon + length + sex + bacon:sex, data = pigs)
##
## Quantile = 2.3186
## 95% family-wise confidence level
##
##
## Linear Hypotheses:
## Estimate lwr upr
## bacon == 0 -1.19081 -1.49645 -0.88517
## bacon + bacon:sexmale == 0 -0.87572 -1.02148 -0.72996
## bacon:sexmale == 0 0.31509 -0.02349 0.65367
Conclusie
Er is een extreem significante lineaire associatie tussen de dikte
van de speklaag en het vleespercentage bij varkens (p << 0.001).
De lineaire associatie tussen de dikte van de speklaag en het
vleespercentage is heel sterk significant bij zowel vrouwelijke
(p<<0.001) als mannelijke varkens (p<0.001). Voor zeugen, die
een verschillende dikte van speklaag hebben, is het vleespercentage
gemiddeld 1.19 %/mm lager bij zeugen met de dikste speklaag (95% BI
[0.89 %/mm, 1.5 %/mm]). Voor beren (mannelijke varkens), die een
verschillende dikte van speklaag hebben, is het vleespercentage
gemiddeld 0.88 %/mm lager bij beren met de dikste speklaag (95% BI [0.73
%/mm, 1.02 %/mm]). Er is op het 5% significantieniveau geen significant
verschil in de associatie tussen de dikte van de speklaag en het
vleespercentage tussen vrouwelijke en mannelijke varkens na correctie
voor multiple testing (p = 0.0734).
LS0tCnRpdGxlOiAiRXhhbWVudm9vcmJlZWxkIHZyYWFnIDEiCmF1dGhvcjogIkxpZXZlbiBDbGVtZW50LCBBbGV4YW5kcmUgU2VnZXJzIgpkYXRlOiAic3RhdE9taWNzLCBHaGVudCBVbml2ZXJzaXR5IChodHRwczovL3N0YXRvbWljcy5naXRodWIuaW8pIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGxhdGV4X2VuZ2luZTogeGVsYXRleAotLS0KCgo8YSByZWw9ImxpY2Vuc2UiIGhyZWY9Imh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1uYy1zYS80LjAiPjxpbWcgYWx0PSJDcmVhdGl2ZSBDb21tb25zIExpY2Vuc2UiIHN0eWxlPSJib3JkZXItd2lkdGg6MCIgc3JjPSJodHRwczovL2kuY3JlYXRpdmVjb21tb25zLm9yZy9sL2J5LW5jLXNhLzQuMC84OHgzMS5wbmciIC8+PC9hPgoKCk9uZGVyem9la2VycyBiZXN0dWRlcmVuIG9mIGVyIGVlbiBhc3NvY2lhdGllIHR1c3NlbiBoZXQgZGUgZGlrdGUgdmFuIGRlIHNwZWtsYWFnIHZhbiB2YXJrZW5zIGlzIG1ldCBoZXQgcGVyY2VudGFnZSB2bGVlcyB2YW4gdmFya2VucyAocGVybWVhdCkuIFplIHdpbGxlbiBvb2sgd2V0ZW4gb2YgZGV6ZSBhc3NvY2lhdGllIHZlcnNjaGlsdCB0dXNzZW4gbWFubmVsaWprZSBlbiB2cm91d2VsaWprZSB2YXJrZW5zLiBVaXQgdm9vcmdhYW5kIG9uZGVyem9layB3ZXRlbiBkZSBvbmRlcnpvZWtlcnMgZGF0IGVyIGVlbiBhc3NvY2lhdGllIGlzIHR1c3NlbiBoZXQgZGUgbGVuZ3RlIHZhbiBoZXQgdmFya2VuIGVuIGhldCBwZXJjZW50YWdlIHZsZWVzLiAKCgoKIyBEYXRhIGV4cGxvcmF0aWUKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncGxvdDIpCmBgYAoKV2UgbGV6ZW4gZGUgZGF0YSBpbiwgZW4gZmlsdGVyZW4gZGUgZGF0YSBhYW5nZXppZW4gd2UgaGV0IGdld2ljaHQgbmlldCBhbHMgdmFyaWFiZWxlIHp1bGxlbiBnZWJydWlrZW4uCmBgYHtyfQpwaWdzIDwtIHJlYWQuY3N2KGZpbGUgPSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3N0YXRPbWljcy9iaW9zdGF0aXN0aWNzMjEvbWFzdGVyL3BpZ3MuY3N2IikKcGlncyA8LSBwaWdzICU+JSBzdWJzZXQoc2VsZWN0ID0gLXdlaWdodCkKYGBgCgpgYGB7cn0KaGVhZChwaWdzKQpkaW0ocGlncykKYGBgCgpgYGB7cn0KbGlicmFyeShHR2FsbHkpCnBpZ3MgJT4lCiAgZ2dwYWlycwpgYGAKCkhpZXJ1aXQgemllbiB3ZSBkYXQgZXIgZWVuIGR1aWRlbGlqa2UgbGluZWFpcmUgYXNzb2NpYXRpZSBpcyB0dXNzZW4gaGV0IHBlcmNlbnRhZ2UgdmxlZXMgZW4gZGUgZGlrdGUgdmFuIGRlIHNwZWtsYWFnLiBFciBpcyBnZWVuIGR1aWRlbGlqa2UgYXNzb2NpYXRpZSB0dXNzZW4gaGV0IHBlcmNlbnRhZ2UgdmxlZXMgZW4gZGUgbGVuZ3RlIHZhbiBoZXQgdmFya2VuLiBXZWwgbGlqa3QgZXIgZWVuIHZlcnNjaGlsIHZhbiBwZXJjZW50YWdlIHZsZWVzIHRlIHppam4gdHVzc2VuIGRlIHZlcnNjaGlsbGVuZGUgZ2VzbGFjaHRlbi4KCldlIGJla2lqa2VuIHZlcmRlciBkZSBhc3NvY2lhdGllcyB0dXNzZW4gaGV0IHBlcmNlbnRhZ2UgdmxlZXMgZW4gZGUgZGlrdGUgdmFuIGRlIHNwZWtsYWFnIHBlciBnZXNsYWNodC4gRGl0IGRvZW4gd2Ugb29rIHZvb3IgZGUgYXNzb2NpYXRpZSBtZXQgZGUgbGVuZ3RlLgoKYGBge3J9CnBpZ3MgJT4lIGdncGxvdChhZXMoeD1iYWNvbix5PXBlcm1lYXQpKSArIAogIGdlb21fcG9pbnQoKSArIAogIHN0YXRfc21vb3RoKG1ldGhvZCA9ICJsbSIpICsgCiAgZmFjZXRfd3JhcCh+c2V4KQpgYGAKCgoKYGBge3J9CnBpZ3MgJT4lIGdncGxvdChhZXMoeD1sZW5ndGgseT1wZXJtZWF0KSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzdGF0X3Ntb290aChtZXRob2QgPSAibG0iKSArIAogIGZhY2V0X3dyYXAofnNleCkKYGBgCgpIZXQgZWZmZWN0IHZhbiB6b3dlbCBkZSBkaWt0ZSB2YW4gZGUgc3Bla2xhYWcgZW4gZGUgbGVuZ3RlIGxpamt0IGxpY2h0IHRlIHZlcnNjaGlsbGVuIHR1c3NlbiBtYW5uZWxpamtlIGVuIHZyb3V3ZWxpamtlIHZhcmtlbnMuIEVyIGlzIGR1cyBtb2dlbGlqa3MgZWVuIGludGVyYWN0aWUgdHVzc2VuIGRpa3RlIHZhbiBkZSBzcGVrbGFhZyBlbiBnZW5kZXIgZW4gbGVuZ3RlIGVuIGdlbmRlci4KCiMgQWxnZW1lZW4gbGluZWFpciBtb2RlbCBvcHN0ZWxsZW4KCldlIG1vZGVsbGVyZW4gZWVyc3QgaGV0IHBlcmNlbnRhZ2UgdmxlZXMgaW4gZnVuY3RpZSB2YW4gYWxsZSB2YXJpYWJlbGVuLCBzYW1lbiBtZXQgYWxsZSB0d2Vld2VnIGludGVyYWN0aWV0ZXJtZW4uIFdlIG1vZGVsbGVyZW4gZHVzIGVlcnN0OgokRVtwZXJtZWF0XSA9IFxiZXRhX3tiYWNvbn0geF97YmFjb259ICsgXGJldGFfe2xlbmd0aH0geF97bGVuZ3RofSArIFxiZXRhX3tzZXh9IHhfe3NleH0gKyBcYmV0YV97YmFjb246bGVuZ3RofSB4X3tiYWNvbn0geF97bGVuZ3RofSArIFxiZXRhX3tiYWNvbjpzZXh9IHhfe2JhY29ufSB4X3tzZXh9ICsgXGJldGFfe2xlbmd0aDpzZXh9IHhfe2xlbmd0aH0geF97c2V4fSQKCk1lcmsgb3AgZGF0IGplIGhpZXIgZ2VlbiBiYWNvbiAqIGxlbmd0aCAqIHNleCBrdW50IGdlYnJ1aWtlbiwgYWFuZ2V6aWVuIGVyIGRhbiBvb2sgZGUgZHJpZXdlZy1pbnRlcmFjdGllIHNleDpiYWNvbjpsZW5ndGggem91IHppam4sIHdhdCBidWl0ZW4gZGUgc2NvcGUgdmFuIGRlIGN1cnN1cyB2YWx0LgoKYGBge3J9CmxtXzEgPC0gbG0ocGVybWVhdCB+IGJhY29uICsgbGVuZ3RoICsgc2V4ICsgYmFjb246bGVuZ3RoICsgYmFjb246c2V4ICsgbGVuZ3RoOnNleCwgZGF0YSA9IHBpZ3MpCnN1bW1hcnkobG1fMSkKYGBgCgoKV2UgZ2FhbiBkZSBhc3N1bXB0aWVzIHZhbiBoZXQgbGluZWFpcmUgbW9kZWwgbmE6CgpgYGB7cn0KcGxvdChsbV8xKQpgYGAKCkFsbGUgYXNzdW1wdGllcyBsaWprZW4gdm9sZGFhbjogRGUgcmVzaWR1ZW4gemlqbiBnZW1pZGRlbGQgMCB2b29yIGVsa2UgcmVzcG9ucyB3YWFyZGUsIGRlIHJlc2lkdWVuIHppam4gbm9ybWFhbCB2ZXJkZWVsZCBlbiBkZSB2YXJpYW50aWUgaXMgY29uc3RhbnQuCgpXZSBnYWFuIHZlcmRlciBtZXQgaGV0IGJla2lqa2VuIHdlbGtlIHZhcmlhYmVsZW4gd2UgaW4gaGV0IG1vZGVsIGJlaG91ZGVuLiBXZSBnYWFuIHZpYSBlZW4gYW5vdmEgbWV0IHR5cGUgMyBrd2FkcmF0ZW5zb21tZW4gbmEgb2YgZGUgdmFyaWFiZWxlbiBzaWduaWZpY2FudCB6aWpuLiBXZSBiZWdpbm5lbiBtZXQgZW5rZWwgZGUgaW50ZXJhY3RpZXRlcm1lbiB0ZSBiZWtpamtlbi4gCgpgYGB7cn0KbGlicmFyeShjYXIpCkFub3ZhKGxtXzEsIHR5cGUgPSAiSUlJIikKYGBgCgpab3dlbCBkZSBpbnRlcmFjdGlldGVybSBiYWNvbjpsZW5ndGggYWxzIGRlIGludGVyYWN0aWV0ZXJtIGxlbmd0aDpzZXggemlqbiBuaWV0IHNpZ25pZmljYW50IG9wIGhldCA1JSBzaWduaWZpY2FudGllbml2ZWF1LiBXZSB2ZXJ3aWpkZXJlbiBkZSBtaW5zdCBzaWduaWZpY2FudGUsIGJhY29uOmxlbmd0aCwgZW4gdm9lcmVuIG9wbmlldXcgZWVuIGFub3ZhIG1ldCB0eXBlIDMga3dhZHJhdGVuc29tbWVuIHVpdC4KCmBgYHtyfQpsbV8yIDwtIGxtKHBlcm1lYXQgfiBiYWNvbiArIGxlbmd0aCArIHNleCArIGJhY29uOnNleCArIGxlbmd0aDpzZXgsIGRhdGEgPSBwaWdzKQpBbm92YShsbV8yLCB0eXBlID0gIklJSSIpCmBgYAoKRGUgaW50ZXJhY3RpZSBsZW5ndGg6c2V4IGlzIHdlZXIgbmlldCBzaWduaWZpY2FudC4gV2UgdmVyd2lqZGVyZW4gZGV6ZSB1aXQgaGV0IG1vZGVsIGVuIHZvZXJlbiBvcG5pZXV3IGVlbiBhbm92YSBtZXQgdHlwZSAzIGt3YWRyYXRlbnNvbW1lbiB1aXQuIAoKYGBge3J9CmxtXzMgPC0gbG0ocGVybWVhdCB+IGJhY29uICsgbGVuZ3RoICsgc2V4ICsgYmFjb246c2V4ICwgZGF0YSA9IHBpZ3MpCkFub3ZhKGxtXzMsIHR5cGUgPSAiSUlJIikKCmBgYAoKV2UgemllbiBkYXQgZGUgcmVzdGVyZW5kZSB2YXJpYWJlbGVuIGVuIGludGVyYWN0aWV0ZXJtIGFsbGVtYWFsIHNpZ25pZmljYW50IHppam4uIFdlIGJlaG91ZGVuIGhldCBtb2RlbCBtZXQgZGUgZHJpZSBob29mZHZhcmlhYmVsZW4gZW4gZWVuIGludGVyYWN0aWV0ZXJtIHR1c3NlbiBiYWNvbiBlbiBnZXNsYWNodC4KCldlIGJla2lqa2VuIG9mIGRlIG1vZGVsYXNzdW1wdGllcyB2b2xkYWFuIHppam4gdm9vciBkaXQgbW9kZWwuCgpgYGB7cn0KcGxvdChsbV8zKQpgYGAKCkRlIGFzc3VtcHRpZXMgbGlqa2VuIHdlZXIgdm9sZGFhbi4gCgojIEh5cG90aGVzZXMgdGVzdGVuCgpEZSBvbmRlcnpvZWtlcnMgd2lsZGVuIHZvbGdlbmRlIGh5cG90aGVzZXMgdGVzdGVuOgoKLSBJcyBlciBlZW4gYXNzb2NpYXRpZSB0dXNzZW4gaGV0IHBlcmNlbnRhZ2UgdmxlZXMgZW4gZGUgZGlrdGUgdmFuIGRlIHNwZWtsYWFnPwotIElzIGVyIGVlbiB2ZXJzY2hpbCBpbiBkZSBhc3NvY2lhdGllIHR1c3NlbiBoZXQgcGVyY2VudGFnZSB2bGVlcyBlbiBkZSBkaWt0ZSB2YW4gZGUgc3Bla2xhYWcgYmlqIGRlIHZlcnNjaGlsbGVuZGUgZ2VzbGFjaHRlbj8KCkRpdCB2ZXJ0YWFsdCB6aWNoIG5hYXIgZGUgdm9sZ2VuZGUgaHlwb3RoZXNlczoKCiQkMS5ccXVhZCBIXzA6IFxiZXRhX3tiYWNvbn0gPSAwIDogXHRleHR7RXIgaXMgZ2VlbiBsaW5lYWlyZSBhc3NvY2lhdGllIHR1c3NlbiBoZXQgdmxlZXNwZXJjZW50YWdlIGVuIGRlIGRpa3RlIHNwZWtsYWFnIGJpaiB6ZXVnZW4ufSQkCiQkXHVwZG93bmFycm93JCQKJCRIXzE6IFxiZXRhX3tiYWNvbn0gXG5lcSAgMCA6IFx0ZXh0e0VyIGlzIGVlbiBsaW5lYWlyZSBhc3NvY2lhdGllIHR1c3NlbiBoZXQgdmxlZXNwZXJjZW50YWdlIGVuIGRlIGRpa3RlIHNwZWtsYWFnIGJpaiB6ZXVnZW59JCQKCiQkMi5ccXVhZCBIXzA6IFxiZXRhX3tiYWNvbn0gKyBcYmV0YV97YmFjb246c2V4fT0gMCA6IFx0ZXh0e0VyIGlzIGdlZW4gbGluZWFpcmUgYXNzb2NpYXRpZSB0dXNzZW4gaGV0IHZsZWVzcGVyY2VudGFnZSBlbiBkZSBkaWt0ZSBzcGVrbGFhZyBiaWogYmVyZW4gKG1hbm5lbGlqa2UgdmFya2VucykufSQkCiQkXHVwZG93bmFycm93JCQKJCRIXzE6IFxiZXRhX3tiYWNvbn0gKyBcYmV0YV97YmFjb246c2V4fSBcbmVxIDAgOiBcdGV4dHtFciBpcyBlZW4gbGluZWFpcmUgYXNzb2NpYXRpZSB0dXNzZW4gaGV0IHZsZWVzcGVyY2VudGFnZSBlbiBkZSBkaWt0ZSBzcGVrbGFhZyBiaWogYmVyZW4gKG1hbm5lbGlqa2UgdmFya2VucykufSQkCgoKJCQzLiBccXVhZCBIXzA6XGJldGFfe2JhY29uOnNleH0gPSAwIDogXHRleHR7RGUgYXNzb2NpYXRpZSB0dXNzZW4gZGUgZGlrdGUgdmFuIGRlIHNwZWtsYWFnIGVuIGhldCB2ZXRwZXJjZW50YWdlIGlzIGdlbGlqayBiaWogemV1Z2VuIGVuIGJlcmVuLn0kJAokJFx1cGRvd25hcnJvdyQkCiQkSF8xOiBcYmV0YV97YmFjb246c2V4fSBcbmVxIDAgOiBcdGV4dHtEZSBhc3NvY2lhdGllIHR1c3NlbiBkZSBkaWt0ZSB2YW4gZGUgc3Bla2xhYWcgZW4gaGV0IHZldHBlcmNlbnRhZ2UgaXMgdmVyc2NoaWxsZW5kIGJpaiB6ZXVnZW4gZW4gYmVyZW4ufSQkCgoKCldlIHZvZXJlbiBlZXJzdCBlbiBvbW5pYnVzIHRlc3QgdWl0IHdhYXJiaWogd2UgYWxsZSBudWxoeXBvdGhlc2VzIHNpbXVsdGFhbiBmYWxzaWZpw6tyZW4sIHdlIGt1bm5lbiBkaXQgZG9vciBzaW11bHRhYW4gdGUgdGVzdGVuIHZvb3IgaGV0IGhvb2ZkZWZmZWN0IHZvb3IgYmFjb24gZW4gZGUgYmFjb24gJFx0aW1lcyQgc2V4IGludGVyYWN0aWU6CgokJEhfMDogXGJldGFfe2JhY29ufSA9IFxiZXRhX3tiYWNvbjpzZXh9ID0gMC4gJCQKJCRcdXBkb3duYXJyb3ckJAokJEhfMTogXGJldGFfe2JhY29ufSBcbmVxIDAgXHRleHR7IGVuLCBvZiB9IFxiZXRhX3tiYWNvbjpzZXh9IFxuZXEgMC4gJCQKCgpEZSBvbW5pYnVzaHlwb3RoZXNlIGt1bm5lbiB3ZSBldmFsdWVyZW4gbWV0IGVlbiBGLXRlc3QgdHVzc2VuIGhldCB2b2xsZWRpZyBtb2RlbCBlbiBtZXQgaGV0IG1vZGVsIGRhdCBlbmtlbCBoZXQgaG9vZmRlZmZlY3QgdmFuIGxlbmd0ZSBlbiBnZXNsYWNodCBiZXZhdC4KCmBgYHtyfQpsbV80IDwtIGxtKHBlcm1lYXQgfiBsZW5ndGggKyBzZXggLCBkYXRhID0gcGlncykKYW5vdmEobG1fMyxsbV80KQpgYGAKCkdlemllbiB3ZSBkZSBvbW5pYnVzIGh5cG90aGVzZSBoZWVsIGV4dHJlZW0gc2lnbmlmaWNhbnQga3VubmVuIHZlcndlcnBlbiwgZXZhbHVlcmVuIHdlIGluIGVlbiBwb3N0aG9jIGFuYWx5c2Ugb2YgZXIgZWVuIGFzc29jaWF0aWUgaXMgdHVzc2VuIGRlIGRpa3RlIHZhbiBkZSBzcGVrbGFhZyBlbiBoZXQgdmxlZXNwZXJjZW50YWdlIGJpaiB6ZXVnZW4sIGJlcmVuIGVuIG9mIGVyIGVlbiB2ZXJzY2hpbCBpcyB0dXNzZW4gZGUgYXNzb2NpYXRpZSBiaWogemV1Z2VuIGVuIGJlcmVuLiAKCmBgYHtyfQpsaWJyYXJ5KG11bHRjb21wKQptY3AgPC0gZ2xodChsbV8zLGxpbmZjdCA9IGMoImJhY29uID0gMCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiYWNvbiArIGJhY29uOnNleG1hbGUgPSAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmFjb246c2V4bWFsZSA9IDAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKc3VtbWFyeShtY3ApCmBgYAoKYGBge3J9CmNvbmZpbnRNb2RlbCA8LSBjb25maW50KG1jcCkKY29uZmludE1vZGVsCmBgYAoKIyBDb25jbHVzaWUKCkVyIGlzIGVlbiBleHRyZWVtIHNpZ25pZmljYW50ZSBsaW5lYWlyZSBhc3NvY2lhdGllIHR1c3NlbiBkZSBkaWt0ZSB2YW4gZGUgc3Bla2xhYWcgZW4gaGV0IHZsZWVzcGVyY2VudGFnZSBiaWogdmFya2VucyAocCA8PCAwLjAwMSkuIApEZSBsaW5lYWlyZSBhc3NvY2lhdGllIHR1c3NlbiBkZSBkaWt0ZSB2YW4gZGUgc3Bla2xhYWcgZW4gaGV0IHZsZWVzcGVyY2VudGFnZSBpcyBoZWVsIHN0ZXJrIHNpZ25pZmljYW50IGJpaiB6b3dlbCB2cm91d2VsaWprZSAocDw8MC4wMDEpIGFscyBtYW5uZWxpamtlIHZhcmtlbnMgKHA8MC4wMDEpLiAKVm9vciB6ZXVnZW4sIGRpZSBlZW4gdmVyc2NoaWxsZW5kZSBkaWt0ZSB2YW4gc3Bla2xhYWcgaGViYmVuLCBpcyBoZXQgdmxlZXNwZXJjZW50YWdlIGdlbWlkZGVsZCBgciBjb25maW50TW9kZWwkY29uZmludFsxLDFdICU+JSBhYnMgJT4lIHNvcnQgJT4lIHJvdW5kKC4sMikgJT4lIHBhc3RlMCguLCIgJS9tbSIpYCBsYWdlciBiaWogemV1Z2VuIG1ldCBkZSBkaWtzdGUgc3Bla2xhYWcgKDk1JSBCSSBbYHIgY29uZmludE1vZGVsJGNvbmZpbnRbMSwtMV0gJT4lIGFicyAlPiUgc29ydCAlPiUgcm91bmQoLiwyKSAlPiUgcGFzdGUwKC4sIiAlL21tIilgXSkuIApWb29yIGJlcmVuIChtYW5uZWxpamtlIHZhcmtlbnMpLCBkaWUgZWVuIHZlcnNjaGlsbGVuZGUgZGlrdGUgdmFuIHNwZWtsYWFnIGhlYmJlbiwgaXMgaGV0IHZsZWVzcGVyY2VudGFnZSBnZW1pZGRlbGQgYHIgY29uZmludE1vZGVsJGNvbmZpbnRbMiwxXSAlPiUgYWJzICU+JSBzb3J0ICU+JSByb3VuZCguLDIpICU+JSBwYXN0ZTAoLiwiICUvbW0iKWAgbGFnZXIgYmlqIGJlcmVuIG1ldCBkZSBkaWtzdGUgc3Bla2xhYWcgKDk1JSBCSSBbYHIgY29uZmludE1vZGVsJGNvbmZpbnRbMiwtMV0gJT4lIGFicyAlPiUgc29ydCAlPiUgcm91bmQoLiwyKSAlPiUgcGFzdGUwKC4sIiAlL21tIilgXSkuCkVyIGlzIG9wIGhldCA1JSBzaWduaWZpY2FudGllbml2ZWF1IGdlZW4gc2lnbmlmaWNhbnQgdmVyc2NoaWwgaW4gZGUgYXNzb2NpYXRpZSB0dXNzZW4gZGUgZGlrdGUgdmFuIGRlIHNwZWtsYWFnIGVuIGhldCB2bGVlc3BlcmNlbnRhZ2UgdHVzc2VuIHZyb3V3ZWxpamtlIGVuIG1hbm5lbGlqa2UgdmFya2VucyBuYSBjb3JyZWN0aWUgdm9vciBtdWx0aXBsZSB0ZXN0aW5nIChwID0gMC4wNzM0KS4KCgoKCgo=