library(tidyverse) # for plotting and summarizing
library(moderndive) # for nice model output
library(broom) # for nice model output
library(equatiomatic) # for writing model equations
theme_set(theme_minimal()) #changes the theme of ggplots to theme_minimal, my personal favorite
GOAL:
By the end of these notes and activities, you should be able to perform the following tasks.
- Fit a multiple regression model using
lm()
and obtain model output using tidy()
.
- Interpret the coefficients from a multiple linear regression model that uses both quantitative and categorical predictor variables.
- Use the
augment()
function to predict the response on new data.
- Plot the fitted line on top of the observed values, when possible.
Review
One quantitative variable
Interpret the estimated coefficients.
lm_displ <- lm(hwy ~ displ,
data=mpg)
tidy(lm_displ)
Predict new value:
augment(lm_displ, newdata = tibble(displ = 5))
Plotting the model:
augment(lm_displ, data=mpg) %>%
ggplot() +
geom_jitter(aes(x=displ, y=hwy, color=drv)) +
geom_line(aes(x=displ, y=.fitted))
One categorical variable
Interpret the estimated coefficients.
lm_drv <- lm(hwy ~ drv,
data=mpg)
tidy(lm_drv)
Predict new value:
augment(lm_drv, newdata = tibble(drv = "4"))
Plotting the model:
augment(lm_drv, data=mpg) %>%
ggplot() +
geom_jitter(aes(x=displ, y=hwy, color=drv)) +
geom_line(aes(x=displ, y=.fitted, color=drv))
We could also just do this plot. I plotted it as above because we will eventually be interested in using both variables, displ and drv, to predict hwy.
augment(lm_drv, data=mpg) %>%
ggplot() +
geom_jitter(aes(x=drv, y=hwy), width = .1) +
geom_point(aes(x=drv, y=.fitted), color="red")
More than one variable
Next, we would like to use both drv and displ to explain hwy.
lm_twovars <- lm(hwy ~ drv + displ,
data=mpg)
tidy(lm_twovars)
YOUR TURN!
- Write out the model equation using the form below. You can use the
extract_eq()
function to do this.
\[
\hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x_1 + \hat{\beta}_2 x_2 + ... + \hat{\beta}_p x_p.
\]
- Are the coefficients the same as they were in the model with only drv? Or with only displ? Why?
- Interpret each of the coefficients. It might be helpful to write the model equation for each of the three drives. That is, if you plug in
drv = 4
, you will end up with an equation that describes the relationship between displ
and hwy
. You can do the same for drv = f
and drv = r
.
- Plot this model. You will need to color by
drv
. There is something special about it … what?
- Use the model to predict
hwy
mpg for a 4 wheel drive car with a displacement of 5 and a front wheel drive car with a displacement of 2.5.
In a model with more than one variable, we are determining the affect of each variable, while accounting for all other variables in the model. This affect might change after accounting for those other variables. Let’s examine this visually first with this toy example (don’t worry about the code).
The relationship between x and y within each grp is different than the overall relationship. What might you expect the coefficient of the x term to be in a linear regression that includes both x and grp to model y? What if we only include x?
General Interpretation
In general, in a multiple linear regression model, the intercept is the average response when the explanatory variables are all equal to zero. If there are categorical variables in the model, the intercept then reflects the average response when the categorical variable(s) are at the baseline/reference level.
Coefficients of quantitative explanatory variables are the average change in the response variable for a one unit increase in the explanatory variable, with all other variables held fixed (this indicates that we’ve accounted for those variables being in the model).
Coefficients of categorical explanatory variables are the difference in average response between the level of the indicator variable and the reference level, holding all other variables constant.
Interactions
We could also use these same variables and add an additional term called an interaction term. We keep each of the “main” terms of displ and drv (these are called main effects) but also “multiply” the two together, written as drv:displ
in the R code. Let’s examine how to do this in R and what it means for our interpretations.
Rather than writing lm(hwy ~ drv + displ + drv:displ, data=mpg)
, we can write this shortcut.
lm_interaction <- lm(hwy ~ drv*displ,
data=mpg)
tidy(lm_interaction)
YOUR TURN! (Don’t look ahead)
- Write out the model equation using the form below. You can use the
extract_eq()
function to do this.
\[
\hat{y} = \hat{\beta}_0 + \hat{\beta}_1 x_1 + \hat{\beta}_2 x_2 + ... + \hat{\beta}_p x_p.
\]
- Interpret each of the coefficients in the model above. Be careful and precise in how you do this. Once again, it might be helpful to write the model equation for each of the three drives. That is, if you plug in
drv = 4
, you will end up with an equation that describes the relationship between displ
and hwy
. You can do the same for drv = f
and drv = r
.
- What does adding an interaction term do? When would you add an interaction term?
- Plot this model. You will need to color by
drv
.
- Use the model to predict
hwy
mpg for a 4 wheel drive car with a displacement of 5 and a front wheel drive car with a displacement of 2.5.
General Interpretation
Interaction effects allow one explanatory variable to modify how another explanatory variable effects the response variable. In the example above, we saw that the effect of displ
changed depending on the drv
(it is also true that the effect of drv
changes depending on displ
). Be careful in your interpretation as this DOES NOT mean that the two explanatory variables involved in the interaction effect are or need to be highly correlated.
The coefficients of interaction terms that involve a quantitative and categorical variable represent a change in the slope of the line in the model where the quantitative predictor is used to model the response between the level of the indicator variable and the reference level.
In the example above, the coefficient for the drvr:displ
term means that the slope of the line that uses displ
to model hwy
is 1.96 greater for rear wheel drive cars than 4 wheel drive cars. We could also say that the amount by which hwy mpg increases for a 1 unit increase in displacement is 1.96 MPG greater for rear wheel drive cars than 4 wheel drive cars.
The coefficients of the main effect terms have to be interpreted very carefully since those variables are also involved in the interaction terms. They often will be about the reference level or when the quantitative variable takes a value of 0. We are usually most interested in the coefficients of the interaction term.
Other models
Above, we had one categorical variable and one quantitative variable. We can fit models with only categorical or only quantitative or with MANY, MANY more variables and terms. Interpretations will stay more or less the same. The most important part to remember, is that whenever you are interpreting a coefficient, you must acknowledge the other variables that have been included in the model.
LS0tCnRpdGxlOiAiTXVsdGlwbGUgTGluZWFyIFJlZ3Jlc3Npb246IENyZWF0aW5nIG1vZGVscywgaW50ZXJwcmV0aW5nIG1vZGVscywgcG9pbnQgcHJlZGljdGlvbiIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKSAgICAgICMgZm9yIHBsb3R0aW5nIGFuZCBzdW1tYXJpemluZwpsaWJyYXJ5KG1vZGVybmRpdmUpICAgICAjIGZvciBuaWNlIG1vZGVsIG91dHB1dApsaWJyYXJ5KGJyb29tKSAgICAgICAgICAjIGZvciBuaWNlIG1vZGVsIG91dHB1dCAKbGlicmFyeShlcXVhdGlvbWF0aWMpICAgIyBmb3Igd3JpdGluZyBtb2RlbCBlcXVhdGlvbnMKdGhlbWVfc2V0KHRoZW1lX21pbmltYWwoKSkgI2NoYW5nZXMgdGhlIHRoZW1lIG9mIGdncGxvdHMgdG8gdGhlbWVfbWluaW1hbCwgbXkgcGVyc29uYWwgZmF2b3JpdGUKYGBgCgohW10oaW1hZ2VzL21vZGVybmRpdmVfZmxvd2NoYXJ0X21sci5wbmcpe3dpZHRoPTYwMHB4fQoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtc3VjY2VzcyI+CiAgPHN0cm9uZz5HT0FMOjwvc3Ryb25nPgoKQnkgdGhlIGVuZCBvZiB0aGVzZSBub3RlcyBhbmQgYWN0aXZpdGllcywgeW91IHNob3VsZCBiZSBhYmxlIHRvIHBlcmZvcm0gdGhlIGZvbGxvd2luZyB0YXNrcy4KCiogRml0IGEgbXVsdGlwbGUgcmVncmVzc2lvbiBtb2RlbCB1c2luZyBgbG0oKWAgYW5kIG9idGFpbiBtb2RlbCBvdXRwdXQgdXNpbmcgYHRpZHkoKWAuICAKKiBJbnRlcnByZXQgdGhlIGNvZWZmaWNpZW50cyBmcm9tIGEgbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgdGhhdCB1c2VzIGJvdGggcXVhbnRpdGF0aXZlIGFuZCBjYXRlZ29yaWNhbCBwcmVkaWN0b3IgdmFyaWFibGVzLiAgCiogVXNlIHRoZSBgYXVnbWVudCgpYCBmdW5jdGlvbiB0byBwcmVkaWN0IHRoZSByZXNwb25zZSBvbiBuZXcgZGF0YS4gIAoqIFBsb3QgdGhlIGZpdHRlZCBsaW5lIG9uIHRvcCBvZiB0aGUgb2JzZXJ2ZWQgdmFsdWVzLCB3aGVuIHBvc3NpYmxlLgoKPC9kaXY+CgojIFJldmlldwoKIyMgT25lIHF1YW50aXRhdGl2ZSB2YXJpYWJsZSAKCkludGVycHJldCB0aGUgZXN0aW1hdGVkIGNvZWZmaWNpZW50cy4KCmBgYHtyfQpsbV9kaXNwbCA8LSBsbShod3kgfiBkaXNwbCwKICAgICAgICAgICAgICAgICAgICAgZGF0YT1tcGcpCnRpZHkobG1fZGlzcGwpCmBgYAoKUHJlZGljdCBuZXcgdmFsdWU6CgpgYGB7cn0KYXVnbWVudChsbV9kaXNwbCwgbmV3ZGF0YSA9IHRpYmJsZShkaXNwbCA9IDUpKQpgYGAKCgpQbG90dGluZyB0aGUgbW9kZWw6CgpgYGB7cn0KYXVnbWVudChsbV9kaXNwbCwgZGF0YT1tcGcpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoYWVzKHg9ZGlzcGwsIHk9aHd5LCBjb2xvcj1kcnYpKSArCiAgZ2VvbV9saW5lKGFlcyh4PWRpc3BsLCB5PS5maXR0ZWQpKQpgYGAKCiMjIE9uZSBjYXRlZ29yaWNhbCB2YXJpYWJsZQoKSW50ZXJwcmV0IHRoZSBlc3RpbWF0ZWQgY29lZmZpY2llbnRzLgoKYGBge3J9CmxtX2RydiA8LSBsbShod3kgfiBkcnYsCiAgICAgICAgICAgICAgICAgZGF0YT1tcGcpCnRpZHkobG1fZHJ2KQpgYGAKClByZWRpY3QgbmV3IHZhbHVlOgoKYGBge3J9CmF1Z21lbnQobG1fZHJ2LCBuZXdkYXRhID0gdGliYmxlKGRydiA9ICI0IikpCmBgYAoKUGxvdHRpbmcgdGhlIG1vZGVsOgoKYGBge3J9CmF1Z21lbnQobG1fZHJ2LCBkYXRhPW1wZykgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX2ppdHRlcihhZXMoeD1kaXNwbCwgeT1od3ksIGNvbG9yPWRydikpICsKICBnZW9tX2xpbmUoYWVzKHg9ZGlzcGwsIHk9LmZpdHRlZCwgY29sb3I9ZHJ2KSkKYGBgCgpXZSBjb3VsZCBhbHNvIGp1c3QgZG8gdGhpcyBwbG90LiBJIHBsb3R0ZWQgaXQgYXMgYWJvdmUgYmVjYXVzZSB3ZSB3aWxsIGV2ZW50dWFsbHkgYmUgaW50ZXJlc3RlZCBpbiB1c2luZyBib3RoIHZhcmlhYmxlcywgKmRpc3BsKiBhbmQgKmRydiosIHRvIHByZWRpY3QgKmh3eSouCgpgYGB7cn0KYXVnbWVudChsbV9kcnYsIGRhdGE9bXBnKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21faml0dGVyKGFlcyh4PWRydiwgeT1od3kpLCB3aWR0aCA9IC4xKSArCiAgZ2VvbV9wb2ludChhZXMoeD1kcnYsIHk9LmZpdHRlZCksIGNvbG9yPSJyZWQiKQpgYGAKCgojIE1vcmUgdGhhbiBvbmUgdmFyaWFibGUKCk5leHQsIHdlIHdvdWxkIGxpa2UgdG8gdXNlIGJvdGggKmRydiogYW5kICpkaXNwbCogdG8gZXhwbGFpbiAqaHd5Ki4gCgpgYGB7cn0KbG1fdHdvdmFycyA8LSBsbShod3kgfiBkcnYgKyBkaXNwbCwKICAgICAgICAgICAgICAgICBkYXRhPW1wZykKdGlkeShsbV90d292YXJzKQpgYGAKCjxkaXYgY2xhc3M9ImFsZXJ0IGFsZXJ0LWluZm8iPgogIDxzdHJvbmc+WU9VUiBUVVJOITwvc3Ryb25nPgoKMS4gV3JpdGUgb3V0IHRoZSBtb2RlbCBlcXVhdGlvbiB1c2luZyB0aGUgZm9ybSBiZWxvdy4gWW91IGNhbiB1c2UgdGhlIGBleHRyYWN0X2VxKClgIGZ1bmN0aW9uIHRvIGRvIHRoaXMuCgokJApcaGF0e3l9ID0gXGhhdHtcYmV0YX1fMCArIFxoYXR7XGJldGF9XzEgeF8xICsgXGhhdHtcYmV0YX1fMiB4XzIgKyAuLi4gKyBcaGF0e1xiZXRhfV9wIHhfcC4KJCQKCjIuIEFyZSB0aGUgY29lZmZpY2llbnRzIHRoZSBzYW1lIGFzIHRoZXkgd2VyZSBpbiB0aGUgbW9kZWwgd2l0aCBvbmx5ICpkcnYqPyAgT3Igd2l0aCBvbmx5ICpkaXNwbCo/IFdoeT8gIAozLiBJbnRlcnByZXQgZWFjaCBvZiB0aGUgY29lZmZpY2llbnRzLiBJdCBtaWdodCBiZSBoZWxwZnVsIHRvIHdyaXRlIHRoZSBtb2RlbCBlcXVhdGlvbiBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgZHJpdmVzLiBUaGF0IGlzLCBpZiB5b3UgcGx1ZyBpbiBgZHJ2ID0gNGAsIHlvdSB3aWxsIGVuZCB1cCB3aXRoIGFuIGVxdWF0aW9uIHRoYXQgZGVzY3JpYmVzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBgZGlzcGxgIGFuZCBgaHd5YC4gWW91IGNhbiBkbyB0aGUgc2FtZSBmb3IgYGRydiA9IGZgIGFuZCBgZHJ2ID0gcmAuIAo0LiBQbG90IHRoaXMgbW9kZWwuIFlvdSB3aWxsIG5lZWQgdG8gY29sb3IgYnkgYGRydmAuIFRoZXJlIGlzIHNvbWV0aGluZyBzcGVjaWFsIGFib3V0IGl0IC4uLiB3aGF0PyAgCjUuIFVzZSB0aGUgbW9kZWwgdG8gcHJlZGljdCBgaHd5YCBtcGcgZm9yIGEgNCB3aGVlbCBkcml2ZSBjYXIgd2l0aCBhIGRpc3BsYWNlbWVudCBvZiA1IGFuZCBhIGZyb250IHdoZWVsIGRyaXZlIGNhciB3aXRoIGEgZGlzcGxhY2VtZW50IG9mIDIuNS4KCjwvZGl2PgoKXApcClwKXApcClwKXApcClwKCkluIGEgbW9kZWwgd2l0aCBtb3JlIHRoYW4gb25lIHZhcmlhYmxlLCB3ZSBhcmUgZGV0ZXJtaW5pbmcgdGhlIGFmZmVjdCBvZiBlYWNoIHZhcmlhYmxlLCB3aGlsZSBhY2NvdW50aW5nIGZvciBhbGwgb3RoZXIgdmFyaWFibGVzIGluIHRoZSBtb2RlbC4gVGhpcyBhZmZlY3QgbWlnaHQgY2hhbmdlIGFmdGVyIGFjY291bnRpbmcgZm9yIHRob3NlIG90aGVyIHZhcmlhYmxlcy4gTGV0J3MgZXhhbWluZSB0aGlzIHZpc3VhbGx5IGZpcnN0IHdpdGggdGhpcyB0b3kgZXhhbXBsZSAoZG9uJ3Qgd29ycnkgYWJvdXQgdGhlIGNvZGUpLgoKYGBge3IsIGVjaG89RkFMU0V9CnNldC5zZWVkKDEwKQoKeDEgPC0gcnVuaWYobiA9IDEwLCBtaW4gPSAwLCBtYXggPSAxMCkKeTEgPC0gNSArIHJub3JtKG4gPSAxMCwgbWVhbiA9IDAsIHNkID0gMikKCngyIDwtIHJ1bmlmKG4gPSAxMCwgbWluID0gMTAsIG1heCA9IDIwKQp5MiA8LSAxNSArIHJub3JtKG4gPSAxMCwgbWVhbiA9IDAsIHNkID0gMikKCngzIDwtIHJ1bmlmKG4gPSAxMCwgbWluID0gMjAsIG1heCA9IDMwKQp5MyA8LSAyNSArIHJub3JtKG4gPSAxMCwgbWVhbiA9IDAsIHNkID0gMikKCnRlc3RfZGF0YSA8LSB0aWJibGUoeCA9IGMoeDEsIHgyLCB4MyksCiAgICAgICAgICAgICAgICAgICAgeSA9IGMoeTEsIHkyLCB5MyksCiAgICAgICAgICAgICAgICAgICAgZ3JwID0gYyhyZXAoImEiLCAxMCksIHJlcCgiYiIsIDEwKSwgcmVwKCJjIiwgMTApKSkKCmdncGxvdCh0ZXN0X2RhdGEpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geCwgeSA9IHksIGNvbG9yID0gZ3JwKSkgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCgpUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gKngqIGFuZCAqeSogd2l0aGluIGVhY2ggKmdycCogaXMgZGlmZmVyZW50IHRoYW4gdGhlIG92ZXJhbGwgcmVsYXRpb25zaGlwLiBXaGF0IG1pZ2h0IHlvdSBleHBlY3QgdGhlIGNvZWZmaWNpZW50IG9mIHRoZSAqeCogdGVybSB0byBiZSBpbiBhIGxpbmVhciByZWdyZXNzaW9uIHRoYXQgaW5jbHVkZXMgYm90aCAqeCogYW5kICpncnAqIHRvIG1vZGVsICp5Kj8gV2hhdCBpZiB3ZSBvbmx5IGluY2x1ZGUgKngqPwoKXApcCgojIyBHZW5lcmFsIEludGVycHJldGF0aW9uCgpJbiBnZW5lcmFsLCBpbiBhIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIG1vZGVsLCB0aGUgaW50ZXJjZXB0IGlzIHRoZSAqYXZlcmFnZSogcmVzcG9uc2Ugd2hlbiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGFyZSBhbGwgZXF1YWwgdG8gemVyby4gSWYgdGhlcmUgYXJlIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBpbiB0aGUgbW9kZWwsIHRoZSBpbnRlcmNlcHQgdGhlbiByZWZsZWN0cyB0aGUgYXZlcmFnZSByZXNwb25zZSB3aGVuIHRoZSBjYXRlZ29yaWNhbCB2YXJpYWJsZShzKSBhcmUgYXQgdGhlIGJhc2VsaW5lL3JlZmVyZW5jZSBsZXZlbC4gCgpDb2VmZmljaWVudHMgb2YgcXVhbnRpdGF0aXZlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBhcmUgdGhlICphdmVyYWdlKiBjaGFuZ2UgaW4gdGhlIHJlc3BvbnNlIHZhcmlhYmxlIGZvciBhIG9uZSB1bml0IGluY3JlYXNlIGluIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZSwgd2l0aCBhbGwgb3RoZXIgdmFyaWFibGVzIGhlbGQgZml4ZWQgKHRoaXMgaW5kaWNhdGVzIHRoYXQgd2UndmUgYWNjb3VudGVkIGZvciB0aG9zZSB2YXJpYWJsZXMgYmVpbmcgaW4gdGhlIG1vZGVsKS4KCkNvZWZmaWNpZW50cyBvZiBjYXRlZ29yaWNhbCBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYXJlIHRoZSBkaWZmZXJlbmNlIGluIGF2ZXJhZ2UgcmVzcG9uc2UgYmV0d2VlbiB0aGUgbGV2ZWwgb2YgdGhlIGluZGljYXRvciB2YXJpYWJsZSBhbmQgdGhlIHJlZmVyZW5jZSBsZXZlbCwgaG9sZGluZyBhbGwgb3RoZXIgdmFyaWFibGVzIGNvbnN0YW50LiAKCgojIEludGVyYWN0aW9ucwoKCldlIGNvdWxkIGFsc28gdXNlIHRoZXNlIHNhbWUgdmFyaWFibGVzIGFuZCBhZGQgYW4gYWRkaXRpb25hbCB0ZXJtIGNhbGxlZCBhbiAqaW50ZXJhY3Rpb24gdGVybSouIFdlIGtlZXAgZWFjaCBvZiB0aGUgIm1haW4iIHRlcm1zIG9mICpkaXNwbCogYW5kICpkcnYqICh0aGVzZSBhcmUgY2FsbGVkICptYWluIGVmZmVjdHMqKSBidXQgYWxzbyAibXVsdGlwbHkiIHRoZSB0d28gdG9nZXRoZXIsIHdyaXR0ZW4gYXMgYGRydjpkaXNwbGAgaW4gdGhlIFIgY29kZS4gTGV0J3MgZXhhbWluZSBob3cgdG8gZG8gdGhpcyBpbiBSIGFuZCB3aGF0IGl0IG1lYW5zIGZvciBvdXIgaW50ZXJwcmV0YXRpb25zLiAKClJhdGhlciB0aGFuIHdyaXRpbmcgYGxtKGh3eSB+IGRydiArIGRpc3BsICsgZHJ2OmRpc3BsLCBkYXRhPW1wZylgLCB3ZSBjYW4gd3JpdGUgdGhpcyBzaG9ydGN1dC4KCmBgYHtyfQpsbV9pbnRlcmFjdGlvbiA8LSBsbShod3kgfiBkcnYqZGlzcGwsIAogICAgICAgICAgICAgICAgICAgICBkYXRhPW1wZykKdGlkeShsbV9pbnRlcmFjdGlvbikKYGBgCgoKPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtaW5mbyI+CiAgPHN0cm9uZz5ZT1VSIFRVUk4hIChEb24ndCBsb29rIGFoZWFkKTwvc3Ryb25nPgoKMS4gV3JpdGUgb3V0IHRoZSBtb2RlbCBlcXVhdGlvbiB1c2luZyB0aGUgZm9ybSBiZWxvdy4gWW91IGNhbiB1c2UgdGhlIGBleHRyYWN0X2VxKClgIGZ1bmN0aW9uIHRvIGRvIHRoaXMuCgokJApcaGF0e3l9ID0gXGhhdHtcYmV0YX1fMCArIFxoYXR7XGJldGF9XzEgeF8xICsgXGhhdHtcYmV0YX1fMiB4XzIgKyAuLi4gKyBcaGF0e1xiZXRhfV9wIHhfcC4KJCQKCjIuIEludGVycHJldCBlYWNoIG9mIHRoZSBjb2VmZmljaWVudHMgaW4gdGhlIG1vZGVsIGFib3ZlLiBCZSBjYXJlZnVsIGFuZCBwcmVjaXNlIGluIGhvdyB5b3UgZG8gdGhpcy4gT25jZSBhZ2FpbiwgaXQgbWlnaHQgYmUgaGVscGZ1bCB0byB3cml0ZSB0aGUgbW9kZWwgZXF1YXRpb24gZm9yIGVhY2ggb2YgdGhlIHRocmVlIGRyaXZlcy4gVGhhdCBpcywgaWYgeW91IHBsdWcgaW4gYGRydiA9IDRgLCB5b3Ugd2lsbCBlbmQgdXAgd2l0aCBhbiBlcXVhdGlvbiB0aGF0IGRlc2NyaWJlcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYGRpc3BsYCBhbmQgYGh3eWAuIFlvdSBjYW4gZG8gdGhlIHNhbWUgZm9yIGBkcnYgPSBmYCBhbmQgYGRydiA9IHJgLiAKMy4gV2hhdCBkb2VzIGFkZGluZyBhbiBpbnRlcmFjdGlvbiB0ZXJtIGRvPyBXaGVuIHdvdWxkIHlvdSBhZGQgYW4gaW50ZXJhY3Rpb24gdGVybT8gIAo0LiBQbG90IHRoaXMgbW9kZWwuIFlvdSB3aWxsIG5lZWQgdG8gY29sb3IgYnkgYGRydmAuICAKNS4gVXNlIHRoZSBtb2RlbCB0byBwcmVkaWN0IGBod3lgIG1wZyBmb3IgYSA0IHdoZWVsIGRyaXZlIGNhciB3aXRoIGEgZGlzcGxhY2VtZW50IG9mIDUgYW5kIGEgZnJvbnQgd2hlZWwgZHJpdmUgY2FyIHdpdGggYSBkaXNwbGFjZW1lbnQgb2YgMi41LgoKPC9kaXY+CgoKXApcClwKXApcClwKXApcClwKXApcClwKXApcClwKXApcClwKXApcClwKXApcClwKXAoKIyMgR2VuZXJhbCBJbnRlcnByZXRhdGlvbgoKSW50ZXJhY3Rpb24gZWZmZWN0cyBhbGxvdyBvbmUgZXhwbGFuYXRvcnkgdmFyaWFibGUgdG8gbW9kaWZ5IGhvdyBhbm90aGVyIGV4cGxhbmF0b3J5IHZhcmlhYmxlIGVmZmVjdHMgdGhlIHJlc3BvbnNlIHZhcmlhYmxlLiBJbiB0aGUgZXhhbXBsZSBhYm92ZSwgd2Ugc2F3IHRoYXQgdGhlIGVmZmVjdCBvZiBgZGlzcGxgIGNoYW5nZWQgZGVwZW5kaW5nIG9uIHRoZSBgZHJ2YCAoaXQgaXMgYWxzbyB0cnVlIHRoYXQgdGhlIGVmZmVjdCBvZiBgZHJ2YCBjaGFuZ2VzIGRlcGVuZGluZyBvbiBgZGlzcGxgKS4gQmUgY2FyZWZ1bCBpbiB5b3VyIGludGVycHJldGF0aW9uIGFzIHRoaXMgKipET0VTIE5PVCoqIG1lYW4gdGhhdCB0aGUgdHdvIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBpbnZvbHZlZCBpbiB0aGUgaW50ZXJhY3Rpb24gZWZmZWN0IGFyZSBvciBuZWVkIHRvIGJlIGhpZ2hseSBjb3JyZWxhdGVkLiAKClRoZSBjb2VmZmljaWVudHMgb2YgaW50ZXJhY3Rpb24gdGVybXMgdGhhdCBpbnZvbHZlIGEgcXVhbnRpdGF0aXZlIGFuZCBjYXRlZ29yaWNhbCB2YXJpYWJsZSByZXByZXNlbnQgYSBjaGFuZ2UgaW4gdGhlIHNsb3BlIG9mIHRoZSBsaW5lIGluIHRoZSBtb2RlbCB3aGVyZSB0aGUgcXVhbnRpdGF0aXZlIHByZWRpY3RvciBpcyB1c2VkIHRvIG1vZGVsIHRoZSByZXNwb25zZSBiZXR3ZWVuIHRoZSBsZXZlbCBvZiB0aGUgaW5kaWNhdG9yIHZhcmlhYmxlIGFuZCB0aGUgcmVmZXJlbmNlIGxldmVsLiAKCkluIHRoZSBleGFtcGxlIGFib3ZlLCB0aGUgY29lZmZpY2llbnQgZm9yIHRoZSBgZHJ2cjpkaXNwbGAgdGVybSBtZWFucyB0aGF0IHRoZSBzbG9wZSBvZiB0aGUgbGluZSB0aGF0IHVzZXMgYGRpc3BsYCB0byBtb2RlbCBgaHd5YCBpcyAxLjk2IGdyZWF0ZXIgZm9yIHJlYXIgd2hlZWwgZHJpdmUgY2FycyB0aGFuIDQgd2hlZWwgZHJpdmUgY2Fycy4gV2UgY291bGQgYWxzbyBzYXkgdGhhdCB0aGUgYW1vdW50IGJ5IHdoaWNoIGh3eSBtcGcgaW5jcmVhc2VzIGZvciBhIDEgdW5pdCBpbmNyZWFzZSBpbiBkaXNwbGFjZW1lbnQgaXMgMS45NiBNUEcgZ3JlYXRlciBmb3IgcmVhciB3aGVlbCBkcml2ZSBjYXJzIHRoYW4gNCB3aGVlbCBkcml2ZSBjYXJzLgoKVGhlIGNvZWZmaWNpZW50cyBvZiB0aGUgbWFpbiBlZmZlY3QgdGVybXMgaGF2ZSB0byBiZSBpbnRlcnByZXRlZCB2ZXJ5IGNhcmVmdWxseSBzaW5jZSB0aG9zZSB2YXJpYWJsZXMgYXJlIGFsc28gaW52b2x2ZWQgaW4gdGhlIGludGVyYWN0aW9uIHRlcm1zLiBUaGV5IG9mdGVuIHdpbGwgYmUgYWJvdXQgdGhlIHJlZmVyZW5jZSBsZXZlbCBvciB3aGVuIHRoZSBxdWFudGl0YXRpdmUgdmFyaWFibGUgdGFrZXMgYSB2YWx1ZSBvZiAwLiBXZSBhcmUgdXN1YWxseSBtb3N0IGludGVyZXN0ZWQgaW4gdGhlIGNvZWZmaWNpZW50cyBvZiB0aGUgaW50ZXJhY3Rpb24gdGVybS4KCiMgT3RoZXIgbW9kZWxzCgpBYm92ZSwgd2UgaGFkIG9uZSBjYXRlZ29yaWNhbCB2YXJpYWJsZSBhbmQgb25lIHF1YW50aXRhdGl2ZSB2YXJpYWJsZS4gV2UgY2FuIGZpdCBtb2RlbHMgd2l0aCBvbmx5IGNhdGVnb3JpY2FsIG9yIG9ubHkgcXVhbnRpdGF0aXZlIG9yIHdpdGggTUFOWSwgTUFOWSBtb3JlIHZhcmlhYmxlcyBhbmQgdGVybXMuIEludGVycHJldGF0aW9ucyB3aWxsIHN0YXkgbW9yZSBvciBsZXNzIHRoZSBzYW1lLiBUaGUgbW9zdCBpbXBvcnRhbnQgcGFydCB0byByZW1lbWJlciwgaXMgdGhhdCB3aGVuZXZlciB5b3UgYXJlIGludGVycHJldGluZyBhIGNvZWZmaWNpZW50LCB5b3UgbXVzdCBhY2tub3dsZWRnZSB0aGUgb3RoZXIgdmFyaWFibGVzIHRoYXQgaGF2ZSBiZWVuIGluY2x1ZGVkIGluIHRoZSBtb2RlbC4gCgoKCgo=