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!

  1. 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. \]

  1. Are the coefficients the same as they were in the model with only drv? Or with only displ? Why?
  2. 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.
  3. Plot this model. You will need to color by drv. There is something special about it … what?
  4. 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)

  1. 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. \]

  1. 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.
  2. What does adding an interaction term do? When would you add an interaction term?
  3. Plot this model. You will need to color by drv.
  4. 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=