# Global options for R chunks
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, message = FALSE, cache = TRUE)

# Load essential libraries
library(ggplot2)
library(dplyr)

Introduction: Modeling Relationships

Welcome to this module on Simple Linear Regression (SLR). Our goal in regression is to formally model the linear relationship between two quantitative variables:

  1. Response Variable (\(y\)): The variable we are trying to predict or explain.

  2. Explanatory Variable (\(x\)): The variable used to predict the response.

We will use the built-in mtcars dataset for demonstration, examining the relationship between vehicle weight (wt, in 1000s of lbs) and fuel efficiency (mpg, miles per gallon).

# Display the first few rows and structure of the relevant variables
mtcars %>% 
  select(wt, mpg) %>%
  head()

1. Visualization: Scatterplots

Before modeling, we must always visualize the relationship. A scatterplot is the foundational tool for this, allowing us to assess the form (linear, curved), direction (positive, negative), and strength of the association, as well as identify potential outliers.

We use ggplot2 to create an elegant and informative scatterplot.

#R Code: Creating the Scatterplot
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(size = 3, color = "#0D47A1") +
  labs(
    title = "Fuel Efficiency vs. Vehicle Weight",
    x = "Vehicle Weight (1000s of lbs)",
    y = "Miles Per Gallon (MPG)"
  ) +
  theme_minimal(base_size = 14)

Observation: The plot suggests a strong, negative, and reasonably linear relationship. As weight increases, MPG tends to decrease.

2. Quantifying Association: Correlation

The Pearson product-moment correlation coefficient, r , quantifies the strength and direction of the linear association between two quantitative variables.

  • r is always between −1 and +1.

  • r > 0 indicates a positive association.

  • r < 0 indicates a negative association.

  • |r| close to 1 indicates a strong linear relationship.

  • |r| close to 0 indicates a weak linear relationship.

Formula (Theoretically):

\(r_{xy}=\frac{\sum{(X_i - \bar{X})(Y_i - \bar{Y})}}{\sqrt{\sum{(X_i - \bar{X})^2}\sum{(Y_i - \bar{Y})^2}}}\)

The correlation is the average product of the standardized values (z-scores) of x and y.

Correlation does not imply causation!

Let’s calculate r for our cars data.

# Calculate the correlation coefficient
correlation_r <- cor(cars$speed, cars$dist)

cat("The correlation coefficient (r) is:", round(correlation_r, 4), "\n")
The correlation coefficient (r) is: 0.8069 

Interpretation: An r close to 0.8 is a strong, positive linear relationship, confirming our visual inspection.

3. Simple Linear Regression (SLR): Modeling the Relationship

A Simple Linear Regression model fits a straight line to the data to predict a response variable (Y) from an explanatory variable (X).

The model is defined by the Least-Squares Regression Line (LSRL):

\[ \hat{y} = b_0 + b_1 x \]

  • \(\hat{y}\) is the predicted value of the response variable.

  • \(b_0\) is the y-intercept (the predicted value of Y when X=0).

  • \(b_1\) is the slope (the change in \(\hat{y}\) for a one-unit increase in \(X\)).

The line is found by minimizing the sum of the squared vertical distances (the residuals, \(e_i = y_i − \hat{y_i}\)) from the points to the line.

Calculating the Coefficients

The least-squares estimates for the slope (\(b_1\)) and intercept (\(b_0\)) are:

  • \(b_1 = r\left(\frac{s_x}{s_y}\right)\)

  • \(b_0 = \bar{y} - b_1\bar{x}\)

Running the Model in R

In R, we use the lm() (linear model) function.

# Fit the linear model: dist is predicted by speed
slr_model <- lm(dist ~ speed, data = cars)

# View the model summary
summary(slr_model)

Call:
lm(formula = dist ~ speed, data = cars)

Residuals:
    Min      1Q  Median      3Q     Max 
-29.069  -9.525  -2.272   9.215  43.201 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -17.5791     6.7584  -2.601   0.0123 *  
speed         3.9324     0.4155   9.464 1.49e-12 ***
---
Signif. codes:  
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 15.38 on 48 degrees of freedom
Multiple R-squared:  0.6511,    Adjusted R-squared:  0.6438 
F-statistic: 89.57 on 1 and 48 DF,  p-value: 1.49e-12

Focus on the Coefficients:

  • The Intercept (\(b_0\)) is the estimate for the baseline stopping distance.

  • The Slope (\(b_1\)) is the estimated increase in stopping distance for every 1 mph increase in speed.

Prediction Example

What is the predicted stopping distance for a car traveling at 15 mph?

\[ \hat{y} = b_0 + b_1(15) \]

# Use the predict function for a 15 mph car
new_data <- data.frame(speed = 15)
predicted_dist <- predict(slr_model, new_data)

cat("Predicted stopping distance at 15 mph:", round(predicted_dist, 2), "ft\n")
Predicted stopping distance at 15 mph: 41.41 ft

Visualizing the Model

It’s good practice to add the regression line to the scatterplot.

# R Markdown Chunk: Plot with Regression Line
ggplot(cars, aes(x = speed, y = dist)) +
  geom_point(color = "darkblue", size = 2) +
  geom_smooth(method = "lm", se = TRUE, color = "red") + # Add the LSRL
  labs(
    title = "SLR of Stopping Distance on Speed",
    x = "Speed (mph)",
    y = "Stopping Distance (ft)"
  ) +
  theme_minimal()

4. Inference for Regression: Making Generalizations

To move beyond describing the sample data to inferring about the larger population.

Assumptions (The “LINE” Conditions)

For valid inference, the simple linear regression model assumes:

  1. Linearity: The relationship between X and Y is linear.

  2. Independence: The observations are independent.

  3. Normality: For any fixed X, the distribution of Y (and thus the residuals) is normal.

  4. Equal Variance (Homoscedasticity): The variability of Y (and thus the residuals) is the same across all X values.

We check these assumptions primarily through residual plots and Normal Q-Q plots.

Hypothesis Testing for the Slope

The most common inference test is whether the slope in the population, \(\beta_1\), is zero. If \(\beta_1 = 0\), there is no linear relationship between \(X\) and \(Y\).

  • Null Hypothesis (\(H_0\)): \(\beta_1 = 0\) (No linear relationship)

  • Alternative Hypothesis (\(H_a\)): \(\beta_1 \ne 0\) (A linear relationship exists)

The summary(slr_model) output provides the t-statistic and p-value for this test.

T-statistic for \(\beta_1\)

\[ t = \frac{(b_1 - \beta_{1,0})}{SE_{b_1}}\]

where \(\beta_{1,0}\) is the hypothesized value (usually 0).

In the summary() output, look at the row for speed:

# R Markdown Chunk: Inference Interpretation
# Focus on the 'Coefficients' table from summary(slr_model)
#             Estimate Std. Error t value Pr(>|t|)
# (Intercept) -17.5791   6.7584  -2.601   0.0123 *
# speed         3.9324   0.4155   9.464   1.49e-12 ***
  • t-value (9.464): The number of standard errors the sample slope ($b_1) is from zero. A large absolute t is evidence against \(H_0\).

  • Pr(>|t|) (\(1.49×10^{−12}\)): The p-value. Since this is extremely small (much less than \(\alpha\)=0.05), we reject \(H_0\).

  • Conclusion: We have strong evidence that the true population slope (\(\beta_1\)) is not zero, meaning there is a statistically significant linear relationship between speed and stopping distance.

Confidence Intervals for the Slope

A Confidence Interval (CI) provides a range of plausible values for the true population slope \(\beta_1\)

# Calculate the 95% Confidence Interval for the coefficients
confint(slr_model, level = 0.95)
                 2.5 %    97.5 %
(Intercept) -31.167850 -3.990340
speed         3.096964  4.767853

Interpretation: We are 95% confident that for every 1 mph increase in speed, the true mean stopping distance increases by an amount between the lower and upper bounds of the interval for the speed coefficient.

Conclusion

We’ve covered the full framework of Simple Linear Regression:

  1. Visualize with a scatterplot.

  2. Quantify the linear relationship with correlation (r).

  3. Model the relationship with the LSRL using lm().

  4. Infer about the population slope (\(\beta_1\)) using t-tests and confidence intervals.

Now is to apply these steps to a new dataset and practice interpreting the summary() output.

LS0tDQp0aXRsZTogIlNpbXBsZSBMaW5lYXIgUmVncmVzc2lvbjogRnJvbSBWaXN1YWxpemF0aW9uIHRvIEluZmVyZW5jZSINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogIA0KLS0tDQoNCmBgYHtyfQ0KIyBHbG9iYWwgb3B0aW9ucyBmb3IgUiBjaHVua3MNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gVFJVRSkNCg0KIyBMb2FkIGVzc2VudGlhbCBsaWJyYXJpZXMNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpgYGANCg0KIyMgSW50cm9kdWN0aW9uOiBNb2RlbGluZyBSZWxhdGlvbnNoaXBzDQpXZWxjb21lIHRvIHRoaXMgbW9kdWxlIG9uIFNpbXBsZSBMaW5lYXIgUmVncmVzc2lvbiAoU0xSKS4gT3VyIGdvYWwgaW4gcmVncmVzc2lvbiBpcyB0byBmb3JtYWxseSBtb2RlbCB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHR3byBxdWFudGl0YXRpdmUgdmFyaWFibGVzOiAgDQoNCjEuIFJlc3BvbnNlIFZhcmlhYmxlICgkeSQpOiBUaGUgdmFyaWFibGUgd2UgYXJlIHRyeWluZyB0byBwcmVkaWN0IG9yIGV4cGxhaW4uICANCg0KMi4gRXhwbGFuYXRvcnkgVmFyaWFibGUgKCR4JCk6IFRoZSB2YXJpYWJsZSB1c2VkIHRvIHByZWRpY3QgdGhlIHJlc3BvbnNlLiANCg0KV2Ugd2lsbCB1c2UgdGhlIGJ1aWx0LWluIGBtdGNhcnNgIGRhdGFzZXQgZm9yIGRlbW9uc3RyYXRpb24sIGV4YW1pbmluZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdmVoaWNsZSB3ZWlnaHQgKHd0LCBpbiAxMDAwcyBvZiBsYnMpIGFuZCBmdWVsIGVmZmljaWVuY3kgKG1wZywgbWlsZXMgcGVyIGdhbGxvbikuDQoNCmBgYHtyfQ0KIyBEaXNwbGF5IHRoZSBmaXJzdCBmZXcgcm93cyBhbmQgc3RydWN0dXJlIG9mIHRoZSByZWxldmFudCB2YXJpYWJsZXMNCm10Y2FycyAlPiUgDQogIHNlbGVjdCh3dCwgbXBnKSAlPiUNCiAgaGVhZCgpDQpgYGANCg0KIyMgMS4gVmlzdWFsaXphdGlvbjogU2NhdHRlcnBsb3RzICANCkJlZm9yZSBtb2RlbGluZywgd2UgbXVzdCBhbHdheXMgdmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXAuIEEgc2NhdHRlcnBsb3QgaXMgdGhlIGZvdW5kYXRpb25hbCB0b29sIGZvciB0aGlzLCBhbGxvd2luZyB1cyB0byBhc3Nlc3MgdGhlIGZvcm0gKGxpbmVhciwgY3VydmVkKSwgZGlyZWN0aW9uIChwb3NpdGl2ZSwgbmVnYXRpdmUpLCBhbmQgc3RyZW5ndGggb2YgdGhlIGFzc29jaWF0aW9uLCBhcyB3ZWxsIGFzIGlkZW50aWZ5IHBvdGVudGlhbCBvdXRsaWVycy4NCg0KV2UgdXNlIGdncGxvdDIgdG8gY3JlYXRlIGFuIGVsZWdhbnQgYW5kIGluZm9ybWF0aXZlIHNjYXR0ZXJwbG90Lg0KDQpgYGB7cn0NCiNSIENvZGU6IENyZWF0aW5nIHRoZSBTY2F0dGVycGxvdA0KZ2dwbG90KG10Y2FycywgYWVzKHggPSB3dCwgeSA9IG1wZykpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMywgY29sb3IgPSAiIzBENDdBMSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJGdWVsIEVmZmljaWVuY3kgdnMuIFZlaGljbGUgV2VpZ2h0IiwNCiAgICB4ID0gIlZlaGljbGUgV2VpZ2h0ICgxMDAwcyBvZiBsYnMpIiwNCiAgICB5ID0gIk1pbGVzIFBlciBHYWxsb24gKE1QRykiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KQ0KYGBgDQoNCl9fT2JzZXJ2YXRpb246X18gVGhlIHBsb3Qgc3VnZ2VzdHMgYSBzdHJvbmcsIG5lZ2F0aXZlLCBhbmQgcmVhc29uYWJseSBsaW5lYXIgcmVsYXRpb25zaGlwLiBBcyB3ZWlnaHQgaW5jcmVhc2VzLCBNUEcgdGVuZHMgdG8gZGVjcmVhc2UuDQoNCiMjIDIuIFF1YW50aWZ5aW5nIEFzc29jaWF0aW9uOiBDb3JyZWxhdGlvbg0KVGhlIFBlYXJzb24gcHJvZHVjdC1tb21lbnQgY29ycmVsYXRpb24gY29lZmZpY2llbnQsICpyKiAsIHF1YW50aWZpZXMgdGhlIF9fc3RyZW5ndGhfXyBhbmQgX19kaXJlY3Rpb25fXyBvZiB0aGUgbGluZWFyIGFzc29jaWF0aW9uIGJldHdlZW4gdHdvIHF1YW50aXRhdGl2ZSB2YXJpYWJsZXMuDQoNCg0KIC0gX18qcipfXyBpcyBhbHdheXMgYmV0d2VlbiDiiJIxIGFuZCArMS4NCg0KIC0gX18qcipfXyA+IDAgaW5kaWNhdGVzIGEgcG9zaXRpdmUgYXNzb2NpYXRpb24uDQoNCiAtIF9fKnIqX18gPCAwIGluZGljYXRlcyBhIG5lZ2F0aXZlIGFzc29jaWF0aW9uLg0KDQogLSBfXyp8cnwqX18gY2xvc2UgdG8gMSBpbmRpY2F0ZXMgYSBzdHJvbmcgbGluZWFyIHJlbGF0aW9uc2hpcC4NCg0KIC0gX18qfHJ8Kl9fIGNsb3NlIHRvIDAgaW5kaWNhdGVzIGEgd2VhayBsaW5lYXIgcmVsYXRpb25zaGlwLg0KDQpGb3JtdWxhIChUaGVvcmV0aWNhbGx5KToNCg0KJHJfe3h5fT1cZnJhY3tcc3VteyhYX2kgLSBcYmFye1h9KShZX2kgLSBcYmFye1l9KX19e1xzcXJ0e1xzdW17KFhfaSAtIFxiYXJ7WH0pXjJ9XHN1bXsoWV9pIC0gXGJhcntZfSleMn19fSQNCg0KDQpUaGUgY29ycmVsYXRpb24gaXMgdGhlIGF2ZXJhZ2UgcHJvZHVjdCBvZiB0aGUgc3RhbmRhcmRpemVkIHZhbHVlcyAoei1zY29yZXMpIG9mIHggYW5kIHkuDQoNCkNvcnJlbGF0aW9uIGRvZXMgbm90IGltcGx5IFtjYXVzYXRpb25dKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9dDhBRG55dzVvdTgpIQ0KDQpMZXQncyBjYWxjdWxhdGUgciBmb3Igb3VyIGNhcnMgZGF0YS4NCg0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQNCmNvcnJlbGF0aW9uX3IgPC0gY29yKGNhcnMkc3BlZWQsIGNhcnMkZGlzdCkNCg0KY2F0KCJUaGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgKHIpIGlzOiIsIHJvdW5kKGNvcnJlbGF0aW9uX3IsIDQpLCAiXG4iKQ0KYGBgDQoNCkludGVycHJldGF0aW9uOiBBbiByIGNsb3NlIHRvIDAuOCBpcyBhIHN0cm9uZywgcG9zaXRpdmUgbGluZWFyIHJlbGF0aW9uc2hpcCwgY29uZmlybWluZyBvdXIgdmlzdWFsIGluc3BlY3Rpb24uDQoNCiMjIyAzLiBTaW1wbGUgTGluZWFyIFJlZ3Jlc3Npb24gKFNMUik6IE1vZGVsaW5nIHRoZSBSZWxhdGlvbnNoaXANCg0KQSBTaW1wbGUgTGluZWFyIFJlZ3Jlc3Npb24gbW9kZWwgZml0cyBhIHN0cmFpZ2h0IGxpbmUgdG8gdGhlIGRhdGEgdG8gcHJlZGljdCBhIHJlc3BvbnNlIHZhcmlhYmxlIChZKSBmcm9tIGFuIGV4cGxhbmF0b3J5IHZhcmlhYmxlIChYKS4NCg0KVGhlIG1vZGVsIGlzIGRlZmluZWQgYnkgdGhlIExlYXN0LVNxdWFyZXMgUmVncmVzc2lvbiBMaW5lIChMU1JMKToNCg0KDQokJCBcaGF0e3l9ID0gYl8wICsgYl8xIHggJCQNCg0KDQogLSAkXGhhdHt5fSQgIGlzIHRoZSBwcmVkaWN0ZWQgdmFsdWUgb2YgdGhlIHJlc3BvbnNlIHZhcmlhYmxlLg0KDQogLSAkYl8wJCBpcyB0aGUgeS1pbnRlcmNlcHQgKHRoZSBwcmVkaWN0ZWQgdmFsdWUgb2YgWSB3aGVuIFg9MCkuDQogDQogLSAkYl8xJCBpcyB0aGUgc2xvcGUgKHRoZSBjaGFuZ2UgaW4gJFxoYXR7eX0kIGZvciBhIG9uZS11bml0IGluY3JlYXNlIGluICRYJCkuDQoNClRoZSBsaW5lIGlzIGZvdW5kIGJ5IG1pbmltaXppbmcgdGhlIHN1bSBvZiB0aGUgc3F1YXJlZCB2ZXJ0aWNhbCBkaXN0YW5jZXMgKHRoZSByZXNpZHVhbHMsICRlX2kgPSB5X2kg4oiSIFxoYXR7eV9pfSQpIGZyb20gdGhlIHBvaW50cyB0byB0aGUgbGluZS4NCg0KIyMjIENhbGN1bGF0aW5nIHRoZSBDb2VmZmljaWVudHMNCg0KVGhlIGxlYXN0LXNxdWFyZXMgZXN0aW1hdGVzIGZvciB0aGUgc2xvcGUgKCRiXzEkKSBhbmQgaW50ZXJjZXB0ICgkYl8wJCkgYXJlOg0KDQogLSAkYl8xID0gclxsZWZ0KFxmcmFje3NfeH17c195fVxyaWdodCkkIA0KDQogLSAkYl8wID0gXGJhcnt5fSAtIGJfMVxiYXJ7eH0kDQogDQojIyMgUnVubmluZyB0aGUgTW9kZWwgaW4gUg0KDQpJbiBSLCB3ZSB1c2UgdGhlIGBsbSgpYCAobGluZWFyIG1vZGVsKSBmdW5jdGlvbi4NCg0KYGBge3J9DQojIEZpdCB0aGUgbGluZWFyIG1vZGVsOiBkaXN0IGlzIHByZWRpY3RlZCBieSBzcGVlZA0Kc2xyX21vZGVsIDwtIGxtKGRpc3QgfiBzcGVlZCwgZGF0YSA9IGNhcnMpDQoNCiMgVmlldyB0aGUgbW9kZWwgc3VtbWFyeQ0Kc3VtbWFyeShzbHJfbW9kZWwpDQpgYGANCg0KIyMjIEZvY3VzIG9uIHRoZSBDb2VmZmljaWVudHM6DQoNCiAtIFRoZSBJbnRlcmNlcHQgKCRiXzAkKSBpcyB0aGUgZXN0aW1hdGUgZm9yIHRoZSBiYXNlbGluZSBzdG9wcGluZyBkaXN0YW5jZS4NCg0KIC0gVGhlIFNsb3BlICgkYl8xJCkgaXMgdGhlIGVzdGltYXRlZCBpbmNyZWFzZSBpbiBzdG9wcGluZyBkaXN0YW5jZSBmb3IgZXZlcnkgMSBtcGggaW5jcmVhc2UgaW4gc3BlZWQuDQoNCiMjIyBQcmVkaWN0aW9uIEV4YW1wbGUgDQpXaGF0IGlzIHRoZSBwcmVkaWN0ZWQgc3RvcHBpbmcgZGlzdGFuY2UgZm9yIGEgY2FyIHRyYXZlbGluZyBhdCAxNSBtcGg/DQoNCiQkIFxoYXR7eX0gPSBiXzAgKyBiXzEoMTUpICQkDQoNCmBgYHtyfQ0KIyBVc2UgdGhlIHByZWRpY3QgZnVuY3Rpb24gZm9yIGEgMTUgbXBoIGNhcg0KbmV3X2RhdGEgPC0gZGF0YS5mcmFtZShzcGVlZCA9IDE1KQ0KcHJlZGljdGVkX2Rpc3QgPC0gcHJlZGljdChzbHJfbW9kZWwsIG5ld19kYXRhKQ0KDQpjYXQoIlByZWRpY3RlZCBzdG9wcGluZyBkaXN0YW5jZSBhdCAxNSBtcGg6Iiwgcm91bmQocHJlZGljdGVkX2Rpc3QsIDIpLCAiZnRcbiIpDQpgYGANCg0KIyMjIFZpc3VhbGl6aW5nIHRoZSBNb2RlbA0KSXQncyBnb29kIHByYWN0aWNlIHRvIGFkZCB0aGUgcmVncmVzc2lvbiBsaW5lIHRvIHRoZSBzY2F0dGVycGxvdC4NCg0KYGBge3J9DQojIFIgTWFya2Rvd24gQ2h1bms6IFBsb3Qgd2l0aCBSZWdyZXNzaW9uIExpbmUNCmdncGxvdChjYXJzLCBhZXMoeCA9IHNwZWVkLCB5ID0gZGlzdCkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJkYXJrYmx1ZSIsIHNpemUgPSAyKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVFJVRSwgY29sb3IgPSAicmVkIikgKyAjIEFkZCB0aGUgTFNSTA0KICBsYWJzKA0KICAgIHRpdGxlID0gIlNMUiBvZiBTdG9wcGluZyBEaXN0YW5jZSBvbiBTcGVlZCIsDQogICAgeCA9ICJTcGVlZCAobXBoKSIsDQogICAgeSA9ICJTdG9wcGluZyBEaXN0YW5jZSAoZnQpIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgNC4gSW5mZXJlbmNlIGZvciBSZWdyZXNzaW9uOiBNYWtpbmcgR2VuZXJhbGl6YXRpb25zDQpUbyBtb3ZlIGJleW9uZCBkZXNjcmliaW5nIHRoZSBzYW1wbGUgZGF0YSB0byBpbmZlcnJpbmcgYWJvdXQgdGhlIGxhcmdlciBwb3B1bGF0aW9uLg0KDQojIyMgQXNzdW1wdGlvbnMgKFRoZSAiTElORSIgQ29uZGl0aW9ucykNCg0KRm9yIHZhbGlkIGluZmVyZW5jZSwgdGhlIHNpbXBsZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCBhc3N1bWVzOg0KDQoxLiAqKkwqKmluZWFyaXR5OiBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gWCBhbmQgWSBpcyBsaW5lYXIuDQoNCjIuICoqSSoqbmRlcGVuZGVuY2U6IFRoZSBvYnNlcnZhdGlvbnMgYXJlIGluZGVwZW5kZW50Lg0KDQozLiAqKk4qKm9ybWFsaXR5OiBGb3IgYW55IGZpeGVkIFgsIHRoZSBkaXN0cmlidXRpb24gb2YgWSAoYW5kIHRodXMgdGhlIHJlc2lkdWFscykgaXMgbm9ybWFsLg0KDQo0LiAqKkUqKnF1YWwgVmFyaWFuY2UgKEhvbW9zY2VkYXN0aWNpdHkpOiBUaGUgdmFyaWFiaWxpdHkgb2YgWSAoYW5kIHRodXMgdGhlIHJlc2lkdWFscykgaXMgdGhlIHNhbWUgYWNyb3NzIGFsbCBYIHZhbHVlcy4NCg0KV2UgY2hlY2sgdGhlc2UgYXNzdW1wdGlvbnMgcHJpbWFyaWx5IHRocm91Z2ggcmVzaWR1YWwgcGxvdHMgYW5kIE5vcm1hbCBRLVEgcGxvdHMuDQoNCiMjIyBIeXBvdGhlc2lzIFRlc3RpbmcgZm9yIHRoZSBTbG9wZQ0KVGhlIG1vc3QgY29tbW9uIGluZmVyZW5jZSB0ZXN0IGlzIHdoZXRoZXIgdGhlIHNsb3BlIGluIHRoZSBwb3B1bGF0aW9uLCAkXGJldGFfMSQsIGlzIHplcm8uIElmICAkXGJldGFfMSA9IDAkLCB0aGVyZSBpcyBubyBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gJFgkIGFuZCAkWSQuDQoNCiAtIE51bGwgSHlwb3RoZXNpcyAoJEhfMCQpOiAkXGJldGFfMSA9IDAkIChObyBsaW5lYXIgcmVsYXRpb25zaGlwKQ0KDQogLSBBbHRlcm5hdGl2ZSBIeXBvdGhlc2lzICgkSF9hJCk6ICRcYmV0YV8xIFxuZSAwJCAoQSBsaW5lYXIgcmVsYXRpb25zaGlwIGV4aXN0cykNCg0KVGhlIHN1bW1hcnkoYHNscl9tb2RlbGApIG91dHB1dCBwcm92aWRlcyB0aGUgdC1zdGF0aXN0aWMgYW5kIHAtdmFsdWUgZm9yIHRoaXMgdGVzdC4NCg0KIyMjIFQtc3RhdGlzdGljIGZvciAkXGJldGFfMSQgDQoNCiQkIHQgPSBcZnJhY3soYl8xIC0gXGJldGFfezEsMH0pfXtTRV97Yl8xfX0kJA0KDQogDQogDQoNCndoZXJlICRcYmV0YV97MSwwfSQgaXMgdGhlIGh5cG90aGVzaXplZCB2YWx1ZSAodXN1YWxseSAwKS4NCg0KSW4gdGhlIGBzdW1tYXJ5KClgIG91dHB1dCwgbG9vayBhdCB0aGUgcm93IGZvciBzcGVlZDoNCg0KYGBge30NCiMgUiBNYXJrZG93biBDaHVuazogSW5mZXJlbmNlIEludGVycHJldGF0aW9uDQojIEZvY3VzIG9uIHRoZSAnQ29lZmZpY2llbnRzJyB0YWJsZSBmcm9tIHN1bW1hcnkoc2xyX21vZGVsKQ0KIyAgICAgICAgICAgICBFc3RpbWF0ZSBTdGQuIEVycm9yIHQgdmFsdWUgUHIoPnx0fCkNCiMgKEludGVyY2VwdCkgLTE3LjU3OTEgICA2Ljc1ODQgIC0yLjYwMSAgIDAuMDEyMyAqDQojIHNwZWVkICAgICAgICAgMy45MzI0ICAgMC40MTU1ICAgOS40NjQgICAxLjQ5ZS0xMiAqKioNCmBgYA0KDQogLSAqKl90Xy12YWx1ZSAoOS40NjQpKio6IFRoZSBudW1iZXIgb2Ygc3RhbmRhcmQgZXJyb3JzIHRoZSBzYW1wbGUgc2xvcGUgKCRiXzEpIGlzIGZyb20gemVyby4gQSBsYXJnZSBhYnNvbHV0ZSAqdCogaXMgZXZpZGVuY2UgYWdhaW5zdCAkSF8wJC4NCg0KIC0gKipQcig+fF90X3wpICgkMS40OcOXMTBee+KIkjEyfSQpKio6IFRoZSAqcCotdmFsdWUuIFNpbmNlIHRoaXMgaXMgZXh0cmVtZWx5IHNtYWxsIChtdWNoIGxlc3MgdGhhbiAkXGFscGhhJD0wLjA1KSwgd2UgcmVqZWN0ICRIXzAkLg0KDQogLSBfX0NvbmNsdXNpb25fXzogV2UgaGF2ZSBzdHJvbmcgZXZpZGVuY2UgdGhhdCB0aGUgdHJ1ZSBwb3B1bGF0aW9uIHNsb3BlICgkXGJldGFfMSQpIGlzIG5vdCB6ZXJvLCBtZWFuaW5nIHRoZXJlIGlzIGEgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gc3BlZWQgYW5kIHN0b3BwaW5nIGRpc3RhbmNlLg0KDQojIyMgQ29uZmlkZW5jZSBJbnRlcnZhbHMgZm9yIHRoZSBTbG9wZQ0KDQpBIENvbmZpZGVuY2UgSW50ZXJ2YWwgKENJKSBwcm92aWRlcyBhIHJhbmdlIG9mIHBsYXVzaWJsZSB2YWx1ZXMgZm9yIHRoZSB0cnVlIHBvcHVsYXRpb24gc2xvcGUgJFxiZXRhXzEkDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIDk1JSBDb25maWRlbmNlIEludGVydmFsIGZvciB0aGUgY29lZmZpY2llbnRzDQpjb25maW50KHNscl9tb2RlbCwgbGV2ZWwgPSAwLjk1KQ0KYGBgDQoNCl9fSW50ZXJwcmV0YXRpb246X18gV2UgYXJlIDk1JSBjb25maWRlbnQgdGhhdCBmb3IgZXZlcnkgMSBtcGggaW5jcmVhc2UgaW4gc3BlZWQsIHRoZSB0cnVlIG1lYW4gc3RvcHBpbmcgZGlzdGFuY2UgaW5jcmVhc2VzIGJ5IGFuIGFtb3VudCBiZXR3ZWVuIHRoZSBsb3dlciBhbmQgdXBwZXIgYm91bmRzIG9mIHRoZSBpbnRlcnZhbCBmb3IgdGhlIHNwZWVkIGNvZWZmaWNpZW50Lg0KDQojIyBDb25jbHVzaW9uDQoNCldlJ3ZlIGNvdmVyZWQgdGhlIGZ1bGwgZnJhbWV3b3JrIG9mIFNpbXBsZSBMaW5lYXIgUmVncmVzc2lvbjoNCg0KMS4gVmlzdWFsaXplIHdpdGggYSBzY2F0dGVycGxvdC4NCg0KMi4gUXVhbnRpZnkgdGhlIGxpbmVhciByZWxhdGlvbnNoaXAgd2l0aCBjb3JyZWxhdGlvbiAoKnIqKS4NCg0KMy4gTW9kZWwgdGhlIHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBMU1JMIHVzaW5nIGBsbSgpYC4NCg0KNC4gSW5mZXIgYWJvdXQgdGhlIHBvcHVsYXRpb24gc2xvcGUgKCRcYmV0YV8xJCkgdXNpbmcgdC10ZXN0cyBhbmQgY29uZmlkZW5jZSBpbnRlcnZhbHMuDQoNCk5vdyBpcyB0byBhcHBseSB0aGVzZSBzdGVwcyB0byBhIG5ldyBkYXRhc2V0IGFuZCBwcmFjdGljZSBpbnRlcnByZXRpbmcgdGhlIGBzdW1tYXJ5KClgIG91dHB1dC4=