Creative Commons License

Onderzoekers hebben het proteoom van weefselbiopsieën van verschillende regio’s in het hart in kaart gebracht voor 3 patienten (patient 3, 4 en 8 genummerd). Ze hebben het proteoom gemeten in het linker atrium (LA), rechter atrium (RA), linker ventrikel (LV) en rechter ventrikel (RV) met massa-spectrometrie.

De intensiteiten zijn een goeie proxy voor de proteineconcentratie. Het is de conventie in massaspectrometrie gebasseerde proteomics om de intensiteiten op log-schaal te modelleren zodat de verschillen op log-schaal een interpretatie krijgen als log2-fold changes. De intensiteitsdata zijn reeds log2 getransformeerd.

In dit examen zijn we vooral geïnteresseerd in het proteïne Myosin light chain 3 (verder MyosinL3 genoemd) en wensen we volgende onderzoeksvragen te beantwoorden:

  1. Is er een verschil in de regulatie van MyosinL3 tussen het ventrikel en het atrium in de linkerzijde van het hart.
  2. Is er een verschil in de regulatie van MyosinL3 tussen het ventrikel en het atrium in de rechterzijde van het hart.
  3. Is de fold change van MyosinL3 tussen ventrikel en atrium verschillend tussen linker- en rechterzijde van het hart

1 Data exploratie

library(tidyverse)
## ── 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
library(ggplot2)

Merk op dat de intensiteiten nog niet log2 getranformeerd zijn!!!

hart <- read.csv(file = "https://raw.githubusercontent.com/statOmics/biostatistics21/master/hearthproteine.csv")
hart

We zien dat de data in “character” format staat voor location en tissue, en integer voor patient. We veranderen deze allemaal naar factor.

hart$location <- as.factor(hart$location)
hart$tissue <- as.factor(hart$tissue)
hart$patient <- as.factor(hart$patient)

Aangezien we de data per patient opnemen kunnen we verwachten dat de proteïneintensiteit per patient gecorreleerd is. Daarom bekijken we de data per patient, en vormen zo dus een geblocked design per patient.

hart %>% 
  ggplot(aes(x=location:tissue, y=intensity %>% log2)) +
    theme_bw() +
    geom_line(aes(group=patient, color=patient)) +
    geom_point(aes(color=patient))+
    ggtitle("log2 proteïne-intensiteit per hartcompartiment") +
    ylab("log2-proteïne-intensiteit") 

Zoals we vermoedden is de log2-proteïneintensiteit meer gelijkend per patient. Zo kan je bijvoorbeeld zien dat patient 8 op elk van de 4 verschillende metingen de laagste log2-proteïneintensiteit heeft. We zien ook dat er een groot verschil lijkt te zijn tussen het atrium en ventrikel, op zowel de linker als rechterkant van het hart. Het lijkt ook dat er een minder groot verschil is tussen het ventrikel en atrium aan de rechterkant van het hart tegenover de linkerkant.

Het is ook duidelijk dat er weinig data zijn om de aannames van het model goed te kunnen evalueren. Dat is jammergenoeg dikwijls het geval wanneer dure high-throughput technologiën worden gebruikt.

2 Algemeen lineair model opstellen

We modelleren de log2-proteïneintensiteit in functie van de locatie, het weefsel, de locatie \(\times\) weefsel-interactie en een blokfactor voor patient.

Merk op dat we geen interacties toevoegen voor patient. Dat is immers ook niet zinvol hier omdat we anders de resultaten niet kunnen veralgemenen naar de populatie toe. Bovendien laat de studie ook niet toe om dit te schatten, we hebben immers maar 1 meting per hartkamer per patient.

lm1 <- lm(intensity %>% log2 ~ location*tissue + patient, data = hart)
summary(lm1)
## 
## Call:
## lm(formula = intensity %>% log2 ~ location * tissue + patient, 
##     data = hart)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.61598 -0.36199  0.07983  0.29682  0.60435 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)       -2.03790    0.39252  -5.192  0.00203 ** 
## locationR          2.39826    0.45324   5.291  0.00185 ** 
## tissueV            7.96795    0.45324  17.580 2.17e-06 ***
## patient4          -0.09867    0.39252  -0.251  0.80991    
## patient8          -0.90152    0.39252  -2.297  0.06137 .  
## locationR:tissueV -2.46411    0.64098  -3.844  0.00852 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5551 on 6 degrees of freedom
## Multiple R-squared:  0.9876, Adjusted R-squared:  0.9772 
## F-statistic: 95.22 on 5 and 6 DF,  p-value: 1.247e-05
plot(lm1)

Er zijn onvoldoende data om de aannames na te gaan. We zien wel geen grote afwijkingen in de QQ-plot en de variantie lijkt min of meer constant en veronderstellen dat aan de aannames van het model is voldaan.

3 Hypotheses testen

We wensen drie onderzoeksvragen te evalueren en vertalen die als volgt naar de parameters van het model. Aangezien we een factorieel design hebben kunnen we de gemiddelde log2-proteïneintensiteit weergeven per groep:

library(ExploreModelMatrix)
ExploreModelMatrix::VisualizeDesign(hart, ~  location*tissue + patient)$plotlist
## $`location = L`

## 
## $`location = R`

  1. Is er een verschil in de regulatie van MyosinL3 tussen het ventrikel en het atrium in de linkerzijde van het hart.

\[ H_0: \beta_V = 0 \leftrightarrow H_1: \beta_V \neq 0 \]

  1. Is er een verschil in de regulatie van MyosinL3 tussen het ventrikel en het atrium in de rechterzijde van het hart.

\[ H_0: \beta_V + \beta_{V:R}= 0 \leftrightarrow H_1: \beta_V + \beta_{V:R} \neq 0 \]

  1. Is de fold change van MyosinL3 tussen ventrikel en atrium verschillend tussen linker- en rechterzijde van het hart \[ H_0: \beta_{V:R}= 0 \leftrightarrow H_1: \beta_{V:R} \neq 0 \]

Eerst zullen we een omnibustest uitvoeren om te testen voor alle hypothesen simultaan. Dat vertaalt zich in de volgende omnibus null hypothese: \[ H_0: \beta_V = \beta_V+\beta_{V:R} = \beta_{V:R} = 0 \rightarrow \beta_V = \beta_{V:R} = 0\] Wat leidt tot het testen van

\[ H_0: \beta_V = \beta_{V:R} = 0 \leftrightarrow H_1: \beta_V \neq 0 \text{ en, of } \beta_{V:R} \neq 0 \] De omnibushypothese kunnen we evalueren met een F-test tussen het volledig model en met het model dat enkel de blokfactor patient en het locatie-effect bevat.

lm0 <- lm(intensity %>% log2 ~ patient + location, data=hart)
anova(lm0, lm1)

We zien dat er een extreem significant verschil is in de regulatie van MyosinL3 tussen het ventrikel en atrium in het hart, ofwel links en/of rechts en/of dat er een interactie is.

We evalueren nu elke hypothese in een posthoc analyse:

library(multcomp)
## 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(lm1,linfct = c("tissueV = 0", 
                                "tissueV + locationR:tissueV = 0",
                                "locationR:tissueV = 0"
                                ))
summary(mcp)
## 
##   Simultaneous Tests for General Linear Hypotheses
## 
## Fit: lm(formula = intensity %>% log2 ~ location * tissue + patient, 
##     data = hart)
## 
## Linear Hypotheses:
##                                  Estimate Std. Error t value Pr(>|t|)    
## tissueV == 0                       7.9680     0.4532  17.580   <0.001 ***
## tissueV + locationR:tissueV == 0   5.5038     0.4532  12.143   <0.001 ***
## locationR:tissueV == 0            -2.4641     0.6410  -3.844   0.0185 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## (Adjusted p values reported -- single-step method)
confint(mcp)
## 
##   Simultaneous Confidence Intervals
## 
## Fit: lm(formula = intensity %>% log2 ~ location * tissue + patient, 
##     data = hart)
## 
## Quantile = 3.0191
## 95% family-wise confidence level
##  
## 
## Linear Hypotheses:
##                                  Estimate lwr     upr    
## tissueV == 0                      7.9680   6.5995  9.3364
## tissueV + locationR:tissueV == 0  5.5038   4.1354  6.8722
## locationR:tissueV == 0           -2.4641  -4.3993 -0.5289
2^confint(mcp)$confint
##                                Estimate         lwr         upr
## tissueV                     250.3757829 96.95585325 646.5626425
## tissueV + locationR:tissueV  45.3753769 17.57122167 117.1759634
## locationR:tissueV             0.1812291  0.04737466   0.6932818
## attr(,"conf.level")
## [1] 0.95
## attr(,"calpha")
## [1] 3.019772

4 Conclusie:

Er is een extreem significant verschil in de regulatie van het Myosin3L proteine tussen het ventrikel en atrium in het hart (p << 0.001).

Het geometrisch gemiddelde van de expressie van Myosin3L is een factor 250 hoger in het linkerventrikel dan in het linkeratrium (p < 0.001, 95% BI [96.7, 648.2]).

Het geometrisch gemiddelde van de expressie van Myosin3L is een factor 45 hoger in het rechterventrikel dan in het rechteratrium (p < 0.001, 95% BI [17.6, 117.3]).

De opregulatie van Myosin3L in ventrikel vs het atrium is gemiddeld een factor 6 hoger in de linker- dan in de rechterzijde (p = 0.019, 95% BI [1.4, 21.2] ).

LS0tCnRpdGxlOiAiRXhhbWVuIHZvb3JiZWVsZG9lZmVuaW5nIDIiCmF1dGhvcjogIkFsZXhhbmRyZSBTZWdlcnMgJiBMaWV2ZW4gQ2xlbWVudCIKZGF0ZTogInN0YXRPbWljcywgR2hlbnQgVW5pdmVyc2l0eSAoaHR0cHM6Ly9zdGF0b21pY3MuZ2l0aHViLmlvKSIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMKICAgIHRoZW1lOiBjb3NtbwogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBsYXRleF9lbmdpbmU6IHhlbGF0ZXgKbGlua2NvbG9yOiBibHVlCnVybGNvbG9yOiBibHVlCmNpdGVjb2xvcjogYmx1ZQoKLS0tCgo8YSByZWw9ImxpY2Vuc2UiIGhyZWY9Imh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1uYy1zYS80LjAiPjxpbWcgYWx0PSJDcmVhdGl2ZSBDb21tb25zIExpY2Vuc2UiIHN0eWxlPSJib3JkZXItd2lkdGg6MCIgc3JjPSJodHRwczovL2kuY3JlYXRpdmVjb21tb25zLm9yZy9sL2J5LW5jLXNhLzQuMC84OHgzMS5wbmciIC8+PC9hPgoKCgpPbmRlcnpvZWtlcnMgaGViYmVuIGhldCBwcm90ZW9vbSB2YW4gd2VlZnNlbGJpb3BzaWXDq24gdmFuIHZlcnNjaGlsbGVuZGUgcmVnaW8ncyBpbiBoZXQgaGFydCBpbiBrYWFydCBnZWJyYWNodCB2b29yIDMgcGF0aWVudGVuIChwYXRpZW50IDMsIDQgZW4gOCBnZW51bW1lcmQpLiBaZSBoZWJiZW4gaGV0IHByb3Rlb29tIGdlbWV0ZW4gaW4gaGV0IGxpbmtlciBhdHJpdW0gKExBKSwgcmVjaHRlciBhdHJpdW0gKFJBKSwgbGlua2VyIHZlbnRyaWtlbCAoTFYpIGVuIHJlY2h0ZXIgdmVudHJpa2VsIChSVikgbWV0IG1hc3NhLXNwZWN0cm9tZXRyaWUuIAoKRGUgaW50ZW5zaXRlaXRlbiAgemlqbiBlZW4gZ29laWUgcHJveHkgdm9vciBkZSBwcm90ZWluZWNvbmNlbnRyYXRpZS4gSGV0IGlzIGRlIGNvbnZlbnRpZSBpbiBtYXNzYXNwZWN0cm9tZXRyaWUgZ2ViYXNzZWVyZGUgcHJvdGVvbWljcyBvbSBkZSBpbnRlbnNpdGVpdGVuIG9wIGxvZy1zY2hhYWwgdGUgbW9kZWxsZXJlbiB6b2RhdCBkZSB2ZXJzY2hpbGxlbiBvcCBsb2ctc2NoYWFsIGVlbiBpbnRlcnByZXRhdGllIGtyaWpnZW4gYWxzIGxvZzItZm9sZCBjaGFuZ2VzLiBEZSBpbnRlbnNpdGVpdHNkYXRhIHppam4gcmVlZHMgbG9nMiBnZXRyYW5zZm9ybWVlcmQuICAKCkluIGRpdCBleGFtZW4gemlqbiB3ZSB2b29yYWwgZ2XDr250ZXJlc3NlZXJkIGluIGhldCBwcm90ZcOvbmUgTXlvc2luIGxpZ2h0IGNoYWluIDMgKHZlcmRlciBNeW9zaW5MMyBnZW5vZW1kKSBlbiB3ZW5zZW4gd2Ugdm9sZ2VuZGUgb25kZXJ6b2Vrc3ZyYWdlbiB0ZSBiZWFudHdvb3JkZW46IAoKMS4gSXMgZXIgZWVuIHZlcnNjaGlsIGluIGRlIHJlZ3VsYXRpZSB2YW4gTXlvc2luTDMgdHVzc2VuICBoZXQgdmVudHJpa2VsIGVuIGhldCBhdHJpdW0gaW4gZGUgbGlua2VyemlqZGUgdmFuIGhldCBoYXJ0LgoyLiBJcyBlciBlZW4gdmVyc2NoaWwgaW4gZGUgcmVndWxhdGllIHZhbiBNeW9zaW5MMyB0dXNzZW4gIGhldCB2ZW50cmlrZWwgZW4gaGV0IGF0cml1bSBpbiBkZSByZWNodGVyemlqZGUgdmFuIGhldCBoYXJ0LgozLiBJcyBkZSBmb2xkIGNoYW5nZSB2YW4gTXlvc2luTDMgdHVzc2VuICB2ZW50cmlrZWwgZW4gYXRyaXVtIHZlcnNjaGlsbGVuZCB0dXNzZW4gbGlua2VyLSBlbiByZWNodGVyemlqZGUgdmFuIGhldCBoYXJ0CgojIERhdGEgZXhwbG9yYXRpZQpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ2dwbG90MikKYGBgCgpNZXJrIG9wIGRhdCBkZSBpbnRlbnNpdGVpdGVuIG5vZyBuaWV0IGxvZzIgZ2V0cmFuZm9ybWVlcmQgemlqbiEhISAKCmBgYHtyfQpoYXJ0IDwtIHJlYWQuY3N2KGZpbGUgPSAiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3N0YXRPbWljcy9iaW9zdGF0aXN0aWNzMjEvbWFzdGVyL2hlYXJ0aHByb3RlaW5lLmNzdiIpCmhhcnQKYGBgCgpXZSB6aWVuIGRhdCBkZSBkYXRhIGluICJjaGFyYWN0ZXIiIGZvcm1hdCBzdGFhdCB2b29yIGxvY2F0aW9uIGVuIHRpc3N1ZSwgZW4gaW50ZWdlciB2b29yIHBhdGllbnQuIFdlIHZlcmFuZGVyZW4gZGV6ZSBhbGxlbWFhbCBuYWFyIGZhY3Rvci4gCgpgYGB7cn0KaGFydCRsb2NhdGlvbiA8LSBhcy5mYWN0b3IoaGFydCRsb2NhdGlvbikKaGFydCR0aXNzdWUgPC0gYXMuZmFjdG9yKGhhcnQkdGlzc3VlKQpoYXJ0JHBhdGllbnQgPC0gYXMuZmFjdG9yKGhhcnQkcGF0aWVudCkKYGBgCgpBYW5nZXppZW4gd2UgZGUgZGF0YSBwZXIgcGF0aWVudCBvcG5lbWVuIGt1bm5lbiB3ZSB2ZXJ3YWNodGVuIGRhdCBkZSBwcm90ZcOvbmVpbnRlbnNpdGVpdCBwZXIgcGF0aWVudCBnZWNvcnJlbGVlcmQgaXMuIERhYXJvbSBiZWtpamtlbiB3ZSBkZSBkYXRhIHBlciBwYXRpZW50LCBlbiB2b3JtZW4gem8gZHVzIGVlbiBnZWJsb2NrZWQgZGVzaWduIHBlciBwYXRpZW50LgoKYGBge3J9CmhhcnQgJT4lIAogIGdncGxvdChhZXMoeD1sb2NhdGlvbjp0aXNzdWUsIHk9aW50ZW5zaXR5ICU+JSBsb2cyKSkgKwogICAgdGhlbWVfYncoKSArCiAgICBnZW9tX2xpbmUoYWVzKGdyb3VwPXBhdGllbnQsIGNvbG9yPXBhdGllbnQpKSArCiAgICBnZW9tX3BvaW50KGFlcyhjb2xvcj1wYXRpZW50KSkrCiAgICBnZ3RpdGxlKCJsb2cyIHByb3Rlw69uZS1pbnRlbnNpdGVpdCBwZXIgaGFydGNvbXBhcnRpbWVudCIpICsKICAgIHlsYWIoImxvZzItcHJvdGXDr25lLWludGVuc2l0ZWl0IikgCmBgYAoKWm9hbHMgd2UgdmVybW9lZGRlbiBpcyBkZSBsb2cyLXByb3Rlw69uZWludGVuc2l0ZWl0IG1lZXIgZ2VsaWprZW5kIHBlciBwYXRpZW50LiBabyBrYW4gamUgYmlqdm9vcmJlZWxkIHppZW4gZGF0IHBhdGllbnQgOCBvcCBlbGsgdmFuIGRlIDQgdmVyc2NoaWxsZW5kZSBtZXRpbmdlbiBkZSBsYWFnc3RlIGxvZzItcHJvdGXDr25laW50ZW5zaXRlaXQgaGVlZnQuIFdlIHppZW4gb29rIGRhdCBlciBlZW4gZ3Jvb3QgdmVyc2NoaWwgbGlqa3QgdGUgemlqbiB0dXNzZW4gaGV0IGF0cml1bSBlbiB2ZW50cmlrZWwsIG9wIHpvd2VsIGRlIGxpbmtlciBhbHMgcmVjaHRlcmthbnQgdmFuIGhldCBoYXJ0LiBIZXQgbGlqa3Qgb29rIGRhdCBlciBlZW4gbWluZGVyIGdyb290IHZlcnNjaGlsIGlzIHR1c3NlbiBoZXQgdmVudHJpa2VsIGVuIGF0cml1bSBhYW4gZGUgcmVjaHRlcmthbnQgdmFuIGhldCBoYXJ0IHRlZ2Vub3ZlciBkZSBsaW5rZXJrYW50LiAKCkhldCBpcyBvb2sgZHVpZGVsaWprIGRhdCBlciB3ZWluaWcgZGF0YSB6aWpuIG9tIGRlIGFhbm5hbWVzIHZhbiBoZXQgbW9kZWwgZ29lZCB0ZSBrdW5uZW4gZXZhbHVlcmVuLiBEYXQgaXMgamFtbWVyZ2Vub2VnIGRpa3dpamxzIGhldCBnZXZhbCB3YW5uZWVyIGR1cmUgaGlnaC10aHJvdWdocHV0IHRlY2hub2xvZ2nDq24gd29yZGVuIGdlYnJ1aWt0LgoKIyBBbGdlbWVlbiBsaW5lYWlyIG1vZGVsIG9wc3RlbGxlbgoKV2UgbW9kZWxsZXJlbiBkZSBsb2cyLXByb3Rlw69uZWludGVuc2l0ZWl0IGluIGZ1bmN0aWUgdmFuIGRlIGxvY2F0aWUsIGhldCB3ZWVmc2VsLCBkZSBsb2NhdGllICRcdGltZXMkIHdlZWZzZWwtaW50ZXJhY3RpZSBlbiBlZW4gYmxva2ZhY3RvciB2b29yIHBhdGllbnQuIAoKTWVyayBvcCBkYXQgd2UgZ2VlbiBpbnRlcmFjdGllcyB0b2V2b2VnZW4gdm9vciBwYXRpZW50LiAKRGF0IGlzIGltbWVycyBvb2sgbmlldCB6aW52b2wgaGllciBvbWRhdCB3ZSBhbmRlcnMgZGUgcmVzdWx0YXRlbiBuaWV0IGt1bm5lbiB2ZXJhbGdlbWVuZW4gbmFhciBkZSBwb3B1bGF0aWUgdG9lLiAKQm92ZW5kaWVuIGxhYXQgZGUgc3R1ZGllIG9vayBuaWV0IHRvZSBvbSBkaXQgdGUgc2NoYXR0ZW4sIHdlIGhlYmJlbiBpbW1lcnMgbWFhciAxIG1ldGluZyBwZXIgaGFydGthbWVyIHBlciBwYXRpZW50LiAKCmBgYHtyfQpsbTEgPC0gbG0oaW50ZW5zaXR5ICU+JSBsb2cyIH4gbG9jYXRpb24qdGlzc3VlICsgcGF0aWVudCwgZGF0YSA9IGhhcnQpCnN1bW1hcnkobG0xKQpgYGAKCgpgYGB7cn0KcGxvdChsbTEpCmBgYAoKRXIgemlqbiBvbnZvbGRvZW5kZSBkYXRhIG9tIGRlIGFhbm5hbWVzIG5hIHRlIGdhYW4uIFdlIHppZW4gd2VsIGdlZW4gZ3JvdGUgYWZ3aWpraW5nZW4gaW4gZGUgUVEtcGxvdCBlbiBkZSB2YXJpYW50aWUgbGlqa3QgbWluIG9mIG1lZXIgY29uc3RhbnQgZW4gdmVyb25kZXJzdGVsbGVuIGRhdCBhYW4gZGUgYWFubmFtZXMgdmFuIGhldCBtb2RlbCBpcyB2b2xkYWFuLiAKCiMgSHlwb3RoZXNlcyB0ZXN0ZW4KCldlIHdlbnNlbiBkcmllIG9uZGVyem9la3N2cmFnZW4gdGUgZXZhbHVlcmVuIGVuIHZlcnRhbGVuIGRpZSBhbHMgdm9sZ3QgbmFhciBkZSBwYXJhbWV0ZXJzIHZhbiBoZXQgbW9kZWwuCkFhbmdlemllbiB3ZSBlZW4gZmFjdG9yaWVlbCBkZXNpZ24gaGViYmVuIGt1bm5lbiB3ZSBkZSBnZW1pZGRlbGRlIGxvZzItcHJvdGXDr25laW50ZW5zaXRlaXQgd2VlcmdldmVuIHBlciBncm9lcDoKCmBgYHtyfQpsaWJyYXJ5KEV4cGxvcmVNb2RlbE1hdHJpeCkKRXhwbG9yZU1vZGVsTWF0cml4OjpWaXN1YWxpemVEZXNpZ24oaGFydCwgfiAgbG9jYXRpb24qdGlzc3VlICsgcGF0aWVudCkkcGxvdGxpc3QKYGBgCgoxLiBJcyBlciBlZW4gdmVyc2NoaWwgaW4gZGUgcmVndWxhdGllIHZhbiBNeW9zaW5MMyB0dXNzZW4gIGhldCB2ZW50cmlrZWwgZW4gaGV0IGF0cml1bSBpbiBkZSBsaW5rZXJ6aWpkZSB2YW4gaGV0IGhhcnQuCgokJCBIXzA6IFxiZXRhX1YgPSAwIFxsZWZ0cmlnaHRhcnJvdyBIXzE6IFxiZXRhX1YgXG5lcSAwICQkCgoyLiBJcyBlciBlZW4gdmVyc2NoaWwgaW4gZGUgcmVndWxhdGllIHZhbiBNeW9zaW5MMyB0dXNzZW4gIGhldCB2ZW50cmlrZWwgZW4gaGV0IGF0cml1bSBpbiBkZSByZWNodGVyemlqZGUgdmFuIGhldCBoYXJ0LgoKJCQgSF8wOiBcYmV0YV9WICsgXGJldGFfe1Y6Un09IDAgXGxlZnRyaWdodGFycm93IEhfMTogXGJldGFfViAgKyBcYmV0YV97VjpSfSBcbmVxIDAgJCQKCjMuIElzIGRlIGZvbGQgY2hhbmdlIHZhbiBNeW9zaW5MMyB0dXNzZW4gIHZlbnRyaWtlbCBlbiBhdHJpdW0gdmVyc2NoaWxsZW5kIHR1c3NlbiBsaW5rZXItIGVuIHJlY2h0ZXJ6aWpkZSB2YW4gaGV0IGhhcnQKJCQgSF8wOiBcYmV0YV97VjpSfT0gMCBcbGVmdHJpZ2h0YXJyb3cgSF8xOiBcYmV0YV97VjpSfSBcbmVxIDAgJCQKCkVlcnN0IHp1bGxlbiB3ZSBlZW4gb21uaWJ1c3Rlc3QgdWl0dm9lcmVuIG9tIHRlIHRlc3RlbiB2b29yIGFsbGUgaHlwb3RoZXNlbiBzaW11bHRhYW4uIERhdCB2ZXJ0YWFsdCB6aWNoIGluIGRlIHZvbGdlbmRlIG9tbmlidXMgbnVsbCBoeXBvdGhlc2U6IAokJCBIXzA6IFxiZXRhX1YgPSBcYmV0YV9WK1xiZXRhX3tWOlJ9ID0gXGJldGFfe1Y6Un0gPSAwIFxyaWdodGFycm93IFxiZXRhX1YgPSBcYmV0YV97VjpSfSA9IDAkJApXYXQgbGVpZHQgdG90IGhldCB0ZXN0ZW4gdmFuCgokJCBIXzA6IFxiZXRhX1YgPSBcYmV0YV97VjpSfSA9IDAgXGxlZnRyaWdodGFycm93IEhfMTogXGJldGFfViBcbmVxIDAgXHRleHR7IGVuLCBvZiB9IFxiZXRhX3tWOlJ9IFxuZXEgMCAkJApEZSBvbW5pYnVzaHlwb3RoZXNlIGt1bm5lbiB3ZSBldmFsdWVyZW4gbWV0IGVlbiBGLXRlc3QgdHVzc2VuIGhldCB2b2xsZWRpZyBtb2RlbCBlbiBtZXQgaGV0IG1vZGVsIGRhdCBlbmtlbCBkZSBibG9rZmFjdG9yIHBhdGllbnQgZW4gaGV0IGxvY2F0aWUtZWZmZWN0IGJldmF0LgoKYGBge3J9CmxtMCA8LSBsbShpbnRlbnNpdHkgJT4lIGxvZzIgfiBwYXRpZW50ICsgbG9jYXRpb24sIGRhdGE9aGFydCkKYW5vdmEobG0wLCBsbTEpCmBgYAoKV2UgemllbiBkYXQgZXIgZWVuIGV4dHJlZW0gc2lnbmlmaWNhbnQgdmVyc2NoaWwgaXMgaW4gZGUgcmVndWxhdGllIHZhbiBNeW9zaW5MMyB0dXNzZW4gaGV0IHZlbnRyaWtlbCBlbiBhdHJpdW0gaW4gaGV0IGhhcnQsIG9md2VsIGxpbmtzIGVuL29mIHJlY2h0cyBlbi9vZiBkYXQgZXIgZWVuIGludGVyYWN0aWUgaXMuIAoKV2UgZXZhbHVlcmVuIG51IGVsa2UgaHlwb3RoZXNlIGluIGVlbiBwb3N0aG9jIGFuYWx5c2U6IAoKYGBge3J9CmxpYnJhcnkobXVsdGNvbXApCm1jcCA8LSBnbGh0KGxtMSxsaW5mY3QgPSBjKCJ0aXNzdWVWID0gMCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0aXNzdWVWICsgbG9jYXRpb25SOnRpc3N1ZVYgPSAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibG9jYXRpb25SOnRpc3N1ZVYgPSAwIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpCnN1bW1hcnkobWNwKQoKYGBgCgpgYGB7cn0KY29uZmludChtY3ApCmBgYAoKYGBge3J9CjJeY29uZmludChtY3ApJGNvbmZpbnQKYGBgCgoKIyBDb25jbHVzaWU6CgpFciBpcyBlZW4gZXh0cmVlbSBzaWduaWZpY2FudCB2ZXJzY2hpbCBpbiBkZSByZWd1bGF0aWUgdmFuIGhldCBNeW9zaW4zTCBwcm90ZWluZSB0dXNzZW4gaGV0IHZlbnRyaWtlbCBlbiBhdHJpdW0gaW4gaGV0IGhhcnQgKHAgPDwgMC4wMDEpLgoKSGV0IGdlb21ldHJpc2NoIGdlbWlkZGVsZGUgdmFuIGRlIGV4cHJlc3NpZSB2YW4gTXlvc2luM0wgaXMgZWVuIGZhY3RvciBgciBjb25maW50KG1jcCkkY29uZmludFsxLDFdICU+JSAyXi4gJT4lIHJvdW5kKC4sMClgIGhvZ2VyIGluIGhldCBsaW5rZXJ2ZW50cmlrZWwgZGFuIGluIGhldCBsaW5rZXJhdHJpdW0gKHAgPCAwLjAwMSwgOTUlIEJJIFtgciBjb25maW50KG1jcCkkY29uZmludFsxLC0xXSAlPiUgMl4uICU+JSByb3VuZCguLDEpYF0pLiAKCkhldCBnZW9tZXRyaXNjaCBnZW1pZGRlbGRlIHZhbiBkZSBleHByZXNzaWUgdmFuICBNeW9zaW4zTCBpcyBlZW4gZmFjdG9yIGByIGNvbmZpbnQobWNwKSRjb25maW50WzIsMV0gJT4lIDJeLiAlPiUgcm91bmQoLiwwKWAgaG9nZXIgaW4gaGV0IHJlY2h0ZXJ2ZW50cmlrZWwgZGFuIGluIGhldCByZWNodGVyYXRyaXVtIChwIDwgMC4wMDEsIDk1JSBCSSBbYHIgY29uZmludChtY3ApJGNvbmZpbnRbMiwtMV0gJT4lIDJeLiAlPiUgcm91bmQoLiwxKWBdKS4gCgpEZSBvcHJlZ3VsYXRpZSB2YW4gTXlvc2luM0wgaW4gdmVudHJpa2VsIHZzIGhldCBhdHJpdW0gaXMgZ2VtaWRkZWxkIGVlbiBmYWN0b3IgYHIgY29uZmludChtY3ApJGNvbmZpbnRbMywxXSAlPiUgYWJzICU+JSAyXi4gJT4lIHJvdW5kKC4sMClgIGhvZ2VyIGluIGRlIGxpbmtlci0gZGFuIGluIGRlIHJlY2h0ZXJ6aWpkZSAocCA9IGByIHN1bW1hcnkobWNwKSR0ZXN0JHB2YWx1ZXNbM10gJT4lIHJvdW5kKC4sMylgLCA5NSUgQkkgW2ByIGNvbmZpbnQobWNwKSRjb25maW50WzMsLTFdICU+JSBhYnMgJT4lIHNvcnQgJT4lICAyXi4gJT4lIHJvdW5kKC4sMSlgXSApLiAK