# 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:
Response Variable (\(y\)): The
variable we are trying to predict or explain.
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:
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:
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:
Linearity: The relationship between X and Y is
linear.
Independence: The observations are
independent.
Normality: For any fixed X, the distribution of
Y (and thus the residuals) is normal.
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\).
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:
Visualize with a scatterplot.
Quantify the linear relationship with correlation
(r).
Model the relationship with the LSRL using
lm().
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=