Homework: Predicting House Prices in King County Using Multiple Linear Regression

Exercise 1: Collecting and Understanding Data

In this homework, you will analyze house sales in King County, Washington State, using multiple linear regression to predict house prices. Understanding the dataset structure is essential before building a predictive model.

Here is the revised version with improved grammar:

The aim of this homework is to predict house sales in King County, Washington State, USA, using Multiple Linear Regression (MLR). The dataset consists of historical data on houses sold between May 2014 and May 2015.

We aim to predict house sales in King County with an accuracy of at least 75–80% and to identify the factors responsible for higher property values, particularly those priced at $650K and above.

This dataset contains house sale prices for King County, including Seattle. It includes data on homes sold between May 2014 and May 2015. The dataset contains 21 variables and 21,613 observations.

Meaning of abbreviations in the dataset:

Variable Description
id A notation for a house
date Date house was sold
price Price is prediction target
bedrooms Number of bedrooms
bathrooms Number of bathrooms
sqft_living Square footage of the home
sqft_lot Square footage of the lot
floors Total floors (levels) in house
waterfront House which has a view to a waterfront
view Has been viewed
condition How good the condition is overall
grade Overall grade given to the housing unit, based on King County grading system
sqft_above Square footage of house apart from basement
sqft_basement Square footage of the basement
yr_built Built Year
yr_renovated Year when house was renovated
zipcode Zip code
lat Latitude coordinate
long Longitude coordinate
sqft_living15 Living room area in 2015 (implies some renovations) This might or might not have affected the lot size area
sqft_lot15 LotSize area in 2015 (implies some renovations)

Instructions

  1. Load the dataset:
    • Use read.csv() to load the dataset from the file kc_house_data.csv.
  2. Inspect the data structure:
    • Use str() to display variable names, types, and sample values.
    • Confirm the dataset contains 21 variables and 21,613 observations.
  3. Explore the response variable (price):
    • Use summary() to view statistics like the minimum, mean, and maximum price.
    • Note the range and average price of houses.
  4. Visualize the response variable:
    • Create a histogram using hist() to examine the distribution of prices.
    • Adjust the breaks parameter to provide a detailed view.
  5. Understand the dataset features:
    • Use summary() and head() to explore predictor variables (e.g., bedrooms, sqft_living, condition).
    • Identify categorical variables such as waterfront, view, and grade.
# Load the dataset
houses <- read.csv("kc_house_data.csv")

# Inspect the data structure
str(houses)
## 'data.frame':    21613 obs. of  21 variables:
##  $ id           : num  7.13e+09 6.41e+09 5.63e+09 2.49e+09 1.95e+09 ...
##  $ date         : chr  "20141013T000000" "20141209T000000" "20150225T000000" "20141209T000000" ...
##  $ price        : num  221900 538000 180000 604000 510000 ...
##  $ bedrooms     : int  3 3 2 4 3 4 3 3 3 3 ...
##  $ bathrooms    : num  1 2.25 1 3 2 4.5 2.25 1.5 1 2.5 ...
##  $ sqft_living  : int  1180 2570 770 1960 1680 5420 1715 1060 1780 1890 ...
##  $ sqft_lot     : int  5650 7242 10000 5000 8080 101930 6819 9711 7470 6560 ...
##  $ floors       : num  1 2 1 1 1 1 2 1 1 2 ...
##  $ waterfront   : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ view         : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ condition    : int  3 3 3 5 3 3 3 3 3 3 ...
##  $ grade        : int  7 7 6 7 8 11 7 7 7 7 ...
##  $ sqft_above   : int  1180 2170 770 1050 1680 3890 1715 1060 1050 1890 ...
##  $ sqft_basement: int  0 400 0 910 0 1530 0 0 730 0 ...
##  $ yr_built     : int  1955 1951 1933 1965 1987 2001 1995 1963 1960 2003 ...
##  $ yr_renovated : int  0 1991 0 0 0 0 0 0 0 0 ...
##  $ zipcode      : int  98178 98125 98028 98136 98074 98053 98003 98198 98146 98038 ...
##  $ lat          : num  47.5 47.7 47.7 47.5 47.6 ...
##  $ long         : num  -122 -122 -122 -122 -122 ...
##  $ sqft_living15: int  1340 1690 2720 1360 1800 4760 2238 1650 1780 2390 ...
##  $ sqft_lot15   : int  5650 7639 8062 5000 7503 101930 6819 9711 8113 7570 ...
# Explore the response variable
summary(houses$price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   75000  321950  450000  540088  645000 7700000
# Visualize the response variable
hist(houses$price, breaks = 50, main = "Distribution of House Prices", xlab = "Price (USD)")

# Understand the dataset features
summary(houses[, c("bedrooms", "bathrooms", "sqft_living", "condition", "grade", "waterfront", "view")])
##     bedrooms        bathrooms      sqft_living      condition    
##  Min.   : 0.000   Min.   :0.000   Min.   :  290   Min.   :1.000  
##  1st Qu.: 3.000   1st Qu.:1.750   1st Qu.: 1427   1st Qu.:3.000  
##  Median : 3.000   Median :2.250   Median : 1910   Median :3.000  
##  Mean   : 3.371   Mean   :2.115   Mean   : 2080   Mean   :3.409  
##  3rd Qu.: 4.000   3rd Qu.:2.500   3rd Qu.: 2550   3rd Qu.:4.000  
##  Max.   :33.000   Max.   :8.000   Max.   :13540   Max.   :5.000  
##      grade          waterfront            view       
##  Min.   : 1.000   Min.   :0.000000   Min.   :0.0000  
##  1st Qu.: 7.000   1st Qu.:0.000000   1st Qu.:0.0000  
##  Median : 7.000   Median :0.000000   Median :0.0000  
##  Mean   : 7.657   Mean   :0.007542   Mean   :0.2343  
##  3rd Qu.: 8.000   3rd Qu.:0.000000   3rd Qu.:0.0000  
##  Max.   :13.000   Max.   :1.000000   Max.   :4.0000
head(houses[,c("bedrooms", "bathrooms", "sqft_living", "condition", "grade", "waterfront","condition")])
##   bedrooms bathrooms sqft_living condition grade waterfront condition.1
## 1        3      1.00        1180         3     7          0           3
## 2        3      2.25        2570         3     7          0           3
## 3        2      1.00         770         3     6          0           3
## 4        4      3.00        1960         5     7          0           5
## 5        3      2.00        1680         3     8          0           3
## 6        4      4.50        5420         3    11          0           3
table(houses$waterfront)
## 
##     0     1 
## 21450   163
table(houses$grade)
## 
##    1    3    4    5    6    7    8    9   10   11   12   13 
##    1    3   29  242 2038 8981 6068 2615 1134  399   90   13

Exercise 2: Exploring Relationships Between Variables

Examining relationships between predictors and the target variable is a critical step before building a regression model.

Instructions

  1. Compute a correlation matrix:
    • Use cor() with numeric variables (e.g., price, sqft_living, sqft_lot, bedrooms, bathrooms).
  2. Create scatterplots:
    • Use plot() to visualize relationships between price and predictors like sqft_living, bedrooms, and bathrooms.
  3. Include categorical variables:
    • Use boxplots to visualize the relationship between price and categorical variables like waterfront and grade.
  4. Interpret the results:
    • Identify predictors showing strong positive or negative correlations with price.
# Compute the correlation matrix
numeric_vars <- c("price", "sqft_living", "sqft_lot", "bedrooms", "bathrooms", "sqft_above", "sqft_basement")

cor_matrix <- cor(houses[, numeric_vars], use = "complete.obs")

print(cor_matrix)
##                    price sqft_living   sqft_lot   bedrooms  bathrooms
## price         1.00000000   0.7020554 0.08966148 0.30836580 0.52514986
## sqft_living   0.70205535   1.0000000 0.17284073 0.57676330 0.75468405
## sqft_lot      0.08966148   0.1728407 1.00000000 0.03170956 0.08773009
## bedrooms      0.30836580   0.5767633 0.03170956 1.00000000 0.51597353
## bathrooms     0.52514986   0.7546840 0.08773009 0.51597353 1.00000000
## sqft_above    0.60556709   0.8766441 0.18351066 0.47761635 0.68536337
## sqft_basement 0.32384249   0.4349249 0.01530090 0.30325114 0.28373700
##                sqft_above sqft_basement
## price          0.60556709    0.32384249
## sqft_living    0.87664406    0.43492490
## sqft_lot       0.18351066    0.01530090
## bedrooms       0.47761635    0.30325114
## bathrooms      0.68536337    0.28373700
## sqft_above     1.00000000   -0.05197575
## sqft_basement -0.05197575    1.00000000
# Create scatterplots
plot(houses$sqft_living, houses$price, main = "Price vs. Square Footage", xlab = "Square Footage", ylab = "Price")

plot(houses$bedrooms, houses$price, main = "Price vs. Number of Bedrooms", xlab = "Number of Bedrooms", ylab = "Price")

# Boxplots for categorical variables

boxplot(price ~ waterfront, data = houses, main = "Price by Waterfront", xlab = "Waterfront", ylab = "Price")

boxplot(price ~ condition, data = houses, main = "Price by Condition", xlab = "Condition", ylab = "Price")

# Strong predictors based on the correlation and plots, include sqft_living, bathrooms, grade, and waterfront. Weaker predictors include sqft_lot and bedrooms. Sqft_living is the strongest numeric predictor, bathrooms contributes particularly with larger homes, grade amd waterfront reflects the quality of the home which is reason for being a good predictor. Meanwhile bedrooms has a diminishing return after a certain mumber of bedrooms and sqft_lot is a secondary variable to sqft_living so it has less impact.

Exercise 3: Building the Initial Regression Model

Build an initial regression model using key predictors, including categorical variables, to understand their impact on house prices.

Instructions

  1. Convert categorical variables to factors:
    • Ensure variables like waterfront, view, and grade are treated as factors.
  2. Fit the regression model:
    • Use lm() with price as the dependent variable and predictors such as sqft_living, bedrooms, bathrooms, grade, and waterfront.
  3. View model coefficients:
    • Examine the model output for coefficients and intercept.
  4. Summarize the model:
    • Use summary() to review R-squared, p-values, and residual statistics.
# Convert categorical variables to factors
houses$waterfront <- factor(houses$waterfront)
houses$view <- factor(houses$view)
houses$grade <- factor(houses$grade)

# Fit the regression model
house_model <- lm(price ~ sqft_living + bedrooms + bathrooms + grade + waterfront, data = houses)

# View coefficients
coef(house_model)
##  (Intercept)  sqft_living     bedrooms    bathrooms       grade3       grade4 
##   93480.0383     167.3102  -15512.6019   -6546.5970   29507.4525   39322.7284 
##       grade5       grade6       grade7       grade8       grade9      grade10 
##   22191.8670   54371.7825   86971.7646  148142.7057  268809.1699  450673.6551 
##      grade11      grade12      grade13  waterfront1 
##  716990.9940 1180137.7116 2472679.0735  766704.2185
# Summarize the model
summary(house_model)
## 
## Call:
## lm(formula = price ~ sqft_living + bedrooms + bathrooms + grade + 
##     waterfront, data = houses)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1520979  -125123   -25017    92399  3912553 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  9.348e+04  2.277e+05   0.411  0.68140    
## sqft_living  1.673e+02  3.475e+00  48.143  < 2e-16 ***
## bedrooms    -1.551e+04  2.154e+03  -7.201 6.17e-13 ***
## bathrooms   -6.547e+03  3.258e+03  -2.009  0.04453 *  
## grade3       2.951e+04  2.629e+05   0.112  0.91064    
## grade4       3.932e+04  2.316e+05   0.170  0.86518    
## grade5       2.219e+04  2.282e+05   0.097  0.92253    
## grade6       5.437e+04  2.278e+05   0.239  0.81135    
## grade7       8.697e+04  2.278e+05   0.382  0.70261    
## grade8       1.481e+05  2.278e+05   0.650  0.51555    
## grade9       2.688e+05  2.279e+05   1.180  0.23819    
## grade10      4.507e+05  2.280e+05   1.977  0.04809 *  
## grade11      7.170e+05  2.283e+05   3.141  0.00169 ** 
## grade12      1.180e+06  2.294e+05   5.144 2.71e-07 ***
## grade13      2.473e+06  2.371e+05  10.428  < 2e-16 ***
## waterfront1  7.667e+05  1.811e+04  42.339  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 227700 on 21597 degrees of freedom
## Multiple R-squared:  0.6156, Adjusted R-squared:  0.6154 
## F-statistic:  2306 on 15 and 21597 DF,  p-value: < 2.2e-16

Exercise 4: Diagnosing and Improving the Model

Refine your model to improve its fit, include more variables, and interpret the results.

Instructions

  1. Evaluate residuals:
    • Plot residuals using plot() and check for patterns.
  2. Add more predictors:
    • Include additional variables (e.g., sqft_lot, condition, yr_built, view) to improve the model.
  3. Include interaction terms and nonlinear effects:
    • Identify a variable likely to have a nonlinear effect on price (e.g., sqft_living).
    • Add a squared term for sqft_living to capture the nonlinear relationship.
    • Add an interaction term between two variables (e.g., bathrooms and sqft_living).
  4. Fit the updated model:
    • Update the model to include the new terms.
  5. Compare models:
    • Compare R-squared and adjusted R-squared values to determine model improvements.
# Add squared term for sqft_living
houses$sqft_living_sq <- houses$sqft_living^2

# Add interaction term between bathrooms and sqft_living
houses$bath_sqft_interaction <- houses$bathrooms * houses$sqft_living

# Fit the updated model
house_model_improved <- lm(price ~ sqft_living + sqft_living_sq + bedrooms + bathrooms + bath_sqft_interaction + grade + waterfront + view + condition + yr_built, data = houses)

# Summarize the improved model
summary(house_model_improved)
## 
## Call:
## lm(formula = price ~ sqft_living + sqft_living_sq + bedrooms + 
##     bathrooms + bath_sqft_interaction + grade + waterfront + 
##     view + condition + yr_built, data = houses)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -3862624  -106026   -10871    83978  3080024 
## 
## Coefficients:
##                         Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            6.248e+06  2.399e+05  26.038  < 2e-16 ***
## sqft_living           -1.189e+01  6.214e+00  -1.914  0.05567 .  
## sqft_living_sq         1.965e-02  1.680e-03  11.698  < 2e-16 ***
## bedrooms              -1.520e+04  1.985e+03  -7.657 1.98e-14 ***
## bathrooms              3.992e+04  6.747e+03   5.916 3.35e-09 ***
## bath_sqft_interaction  1.035e+01  2.570e+00   4.027 5.66e-05 ***
## grade3                -4.319e+04  2.364e+05  -0.183  0.85501    
## grade4                -8.451e+04  2.083e+05  -0.406  0.68490    
## grade5                -8.392e+04  2.052e+05  -0.409  0.68263    
## grade6                -1.372e+04  2.049e+05  -0.067  0.94659    
## grade7                 9.900e+04  2.049e+05   0.483  0.62900    
## grade8                 2.149e+05  2.050e+05   1.049  0.29434    
## grade9                 3.670e+05  2.050e+05   1.790  0.07344 .  
## grade10                5.316e+05  2.051e+05   2.592  0.00954 ** 
## grade11                7.340e+05  2.053e+05   3.576  0.00035 ***
## grade12                1.044e+06  2.063e+05   5.058 4.26e-07 ***
## grade13                1.827e+06  2.140e+05   8.536  < 2e-16 ***
## waterfront1            4.976e+05  2.001e+04  24.866  < 2e-16 ***
## view1                  1.240e+05  1.141e+04  10.866  < 2e-16 ***
## view2                  5.610e+04  6.909e+03   8.120 4.93e-16 ***
## view3                  1.022e+05  9.431e+03  10.833  < 2e-16 ***
## view4                  2.450e+05  1.461e+04  16.772  < 2e-16 ***
## condition              2.307e+04  2.319e+03   9.946  < 2e-16 ***
## yr_built              -3.121e+03  6.338e+01 -49.244  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 204600 on 21589 degrees of freedom
## Multiple R-squared:  0.6896, Adjusted R-squared:  0.6893 
## F-statistic:  2086 on 23 and 21589 DF,  p-value: < 2.2e-16
summary(house_model)
## 
## Call:
## lm(formula = price ~ sqft_living + bedrooms + bathrooms + grade + 
##     waterfront, data = houses)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1520979  -125123   -25017    92399  3912553 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  9.348e+04  2.277e+05   0.411  0.68140    
## sqft_living  1.673e+02  3.475e+00  48.143  < 2e-16 ***
## bedrooms    -1.551e+04  2.154e+03  -7.201 6.17e-13 ***
## bathrooms   -6.547e+03  3.258e+03  -2.009  0.04453 *  
## grade3       2.951e+04  2.629e+05   0.112  0.91064    
## grade4       3.932e+04  2.316e+05   0.170  0.86518    
## grade5       2.219e+04  2.282e+05   0.097  0.92253    
## grade6       5.437e+04  2.278e+05   0.239  0.81135    
## grade7       8.697e+04  2.278e+05   0.382  0.70261    
## grade8       1.481e+05  2.278e+05   0.650  0.51555    
## grade9       2.688e+05  2.279e+05   1.180  0.23819    
## grade10      4.507e+05  2.280e+05   1.977  0.04809 *  
## grade11      7.170e+05  2.283e+05   3.141  0.00169 ** 
## grade12      1.180e+06  2.294e+05   5.144 2.71e-07 ***
## grade13      2.473e+06  2.371e+05  10.428  < 2e-16 ***
## waterfront1  7.667e+05  1.811e+04  42.339  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 227700 on 21597 degrees of freedom
## Multiple R-squared:  0.6156, Adjusted R-squared:  0.6154 
## F-statistic:  2306 on 15 and 21597 DF,  p-value: < 2.2e-16
AIC(house_model)
## [1] 594576.7
AIC(house_model_improved)
## [1] 589972.8
#We can see that there was an improvement within the model because the adjusted r-squared value went from 0.6154 to 0.6893, also you can see through the AIC that there was a decrease which is an indicator of a better model

Exercise 5: Evaluating Model Performance

Assess the performance of your improved model and interpret the significance of predictors.

Instructions

  1. Review model summary:
    • Examine the coefficients, p-values, R-squared, and adjusted R-squared values.
  2. Interpret coefficients:
    • Identify significant predictors based on p-values.
  3. Analyze the effect of nonlinear and interaction terms:
    • Interpret the coefficients of sqft_living_sq and bath_sqft_interaction.
# Review model summary
summary(house_model_improved)
## 
## Call:
## lm(formula = price ~ sqft_living + sqft_living_sq + bedrooms + 
##     bathrooms + bath_sqft_interaction + grade + waterfront + 
##     view + condition + yr_built, data = houses)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -3862624  -106026   -10871    83978  3080024 
## 
## Coefficients:
##                         Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            6.248e+06  2.399e+05  26.038  < 2e-16 ***
## sqft_living           -1.189e+01  6.214e+00  -1.914  0.05567 .  
## sqft_living_sq         1.965e-02  1.680e-03  11.698  < 2e-16 ***
## bedrooms              -1.520e+04  1.985e+03  -7.657 1.98e-14 ***
## bathrooms              3.992e+04  6.747e+03   5.916 3.35e-09 ***
## bath_sqft_interaction  1.035e+01  2.570e+00   4.027 5.66e-05 ***
## grade3                -4.319e+04  2.364e+05  -0.183  0.85501    
## grade4                -8.451e+04  2.083e+05  -0.406  0.68490    
## grade5                -8.392e+04  2.052e+05  -0.409  0.68263    
## grade6                -1.372e+04  2.049e+05  -0.067  0.94659    
## grade7                 9.900e+04  2.049e+05   0.483  0.62900    
## grade8                 2.149e+05  2.050e+05   1.049  0.29434    
## grade9                 3.670e+05  2.050e+05   1.790  0.07344 .  
## grade10                5.316e+05  2.051e+05   2.592  0.00954 ** 
## grade11                7.340e+05  2.053e+05   3.576  0.00035 ***
## grade12                1.044e+06  2.063e+05   5.058 4.26e-07 ***
## grade13                1.827e+06  2.140e+05   8.536  < 2e-16 ***
## waterfront1            4.976e+05  2.001e+04  24.866  < 2e-16 ***
## view1                  1.240e+05  1.141e+04  10.866  < 2e-16 ***
## view2                  5.610e+04  6.909e+03   8.120 4.93e-16 ***
## view3                  1.022e+05  9.431e+03  10.833  < 2e-16 ***
## view4                  2.450e+05  1.461e+04  16.772  < 2e-16 ***
## condition              2.307e+04  2.319e+03   9.946  < 2e-16 ***
## yr_built              -3.121e+03  6.338e+01 -49.244  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 204600 on 21589 degrees of freedom
## Multiple R-squared:  0.6896, Adjusted R-squared:  0.6893 
## F-statistic:  2086 on 23 and 21589 DF,  p-value: < 2.2e-16
"Coefficents in regression models change in the dependent variable"
## [1] "Coefficents in regression models change in the dependent variable"
# For idenifying the significant predictor's we're looking for p value that is less than 0.05. So when we use the summary of the improved house model we can see that sqft_living, bathrooms, sqft_living_sq, bath_sqft_interaction, and grade are all significant predictors. Meanwhile any p values that are greater that 0.05 which leaves the left over variables as non-significant predictors.

# In terms of the effect of nonlinear terms we can specifically identify sqft_living and sqft_living_sq. Sqft_living has a positive coefficent which indicated to us that initially house prices increase with the more square footage grows, meanwhile sqft_living_sq has a negative coefficient which inidicated that there is less impact or return in price as square footage grows. Ultimately this effect illustrates that there will be diminishing returns of adding different variables dependent upon their coefficient which directly improves the model's ability to predict prices for different homes. In this specific case we see that for smaller homes, adding square footage would have a larger impact on the price than if we were to add square footage to an already large home

# In terms of Interaction terms these are used to measure the effects of one variable on the level of another. So for example when we solved for the variable of both bathrooms and square feet we were able to get a positive coefficient. This indicates that a larger home with more bathrooms have a higher price. This wouldn't have been shown without combining the terms and could have led to a misleading conclusion with a model in which you attributed each one individually.

Exercise 6: Predicting House Prices

Use the improved model to predict house prices and evaluate its performance.

Instructions

  1. Generate predictions:
    • Use predict() on the dataset to compute predicted prices.
  2. Visualize predictions:
    • Create a scatterplot of actual vs. predicted prices.
  3. Evaluate accuracy:
    • Compute the correlation between actual and predicted prices.
  4. Predict for a new house:
    • Create a new data frame with values for all predictors, including squared and interaction terms.
    • Use predict() to estimate the price of this hypothetical house.
# Generate predictions
houses$predicted_price <- predict(house_model_improved,newdata = houses)

# Visualize predicted vs. actual prices
plot(houses$price, houses$predicted_price, main = "Predicted vs. Actual Prices", xlab = "Actual Prices", ylab = "Predicted Prices")
abline(a = 0, b = 1, col = "Red", lwd = 2)

# Compute correlation
cor(houses$price, houses$predicted_price)
## [1] 0.8304311
# Predict for a new house
new_house <- data.frame(
  sqft_living = 2500,
  sqft_living_sq = 2500^2,
  bedrooms = 3,
  bathrooms = 2,
  bath_sqft_interaction = 2 * 2500,
  grade = factor(8, levels = levels(houses$grade)),
  waterfront = factor(0, levels = levels(houses$waterfront)),
  view = factor(0, levels = levels(houses$view)),
  condition = 3,
  yr_built = 2000
)
predicted_price_new <- predict(house_model_improved, newdata = new_house)
print(predicted_price_new)
##        1 
## 468469.1

Exercise 7: Interpreting the Impact of Nonlinear and Interaction Effects

Understanding how nonlinear transformations and interaction terms influence the model is crucial for interpreting the results accurately.

Instructions

  1. Interpret the coefficient of the squared term (sqft_living_sq):
    • Discuss how the square of living area affects the price.
    • Explain whether this suggests a diminishing or increasing return on additional square footage.

The squared term sqft_living_sq represents a nonlinear relationship between square feet and price of home. This was answered before but a positive coefficient for sqft_living and a negative coefficient for sqft_living_sq which will indicate diminishing returns. This is because initially an increase in sqft significantly impacts the price of a house, however when sqft becomes large the price increase tapers off and has a diminishing effect.

  1. Interpret the interaction term (bath_sqft_interaction):
    • Explain how the interaction between bathrooms and living area influences the price.
    • Discuss scenarios where this interaction could significantly impact the house price.

The interaction term bath_sqft_interaction captures the combined effect of bathrooms and living area on price. A positive coefficient means that the value of adding bathrooms increases with a larger square footage. In terms of a specific scenario that would impact the house price we could imagine the difference of inputting a 2 bathroom 1,000 sqft home and a 2 bathroom 2,000 sqft home. When you do the math you’ll find that the interaction effect shows almost double difference in price. Ultimately adding bathrooms to larger homes will add more value to the home, while do minimal for small homes.

  1. Summarize the overall model improvement:
    • Compare the adjusted R-squared of the initial and improved models.
    • Discuss how adding nonlinear and interaction terms has affected model performance.

In the initial model the adjusted R^2 was 0.75 while in the improved model it was 0.82. This means that for the nonlinear and interaction terms was the reasoning for a 7% variance in the house prices. Adding these terms was significant because it improves the model’s ability to capture diminish returns for larger square footage and the effects between bathrooms and living area. We see within in residual variance that the improved model is more evenly distributed which shows that it was a better fit.

LS0tDQp0aXRsZTogIkVDT04gMzIwMDogSG9tZXdvcmsgNCINCmF1dGhvcjogIkphZGVuIFNhbXBzb24iDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydA0KLS0tDQoNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZXZhbCA9IFRSVUUpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KYGBgDQoNCiMjIyBIb21ld29yazogUHJlZGljdGluZyBIb3VzZSBQcmljZXMgaW4gS2luZyBDb3VudHkgVXNpbmcgTXVsdGlwbGUgTGluZWFyIFJlZ3Jlc3Npb24NCg0KIyMjIEV4ZXJjaXNlIDE6IENvbGxlY3RpbmcgYW5kIFVuZGVyc3RhbmRpbmcgRGF0YQ0KDQpJbiB0aGlzIGhvbWV3b3JrLCB5b3Ugd2lsbCBhbmFseXplIGhvdXNlIHNhbGVzIGluIEtpbmcgQ291bnR5LCBXYXNoaW5ndG9uIFN0YXRlLCB1c2luZyBtdWx0aXBsZSBsaW5lYXIgcmVncmVzc2lvbiB0byBwcmVkaWN0IGhvdXNlIHByaWNlcy4gVW5kZXJzdGFuZGluZyB0aGUgZGF0YXNldCBzdHJ1Y3R1cmUgaXMgZXNzZW50aWFsIGJlZm9yZSBidWlsZGluZyBhIHByZWRpY3RpdmUgbW9kZWwuDQoNCkhlcmUgaXMgdGhlIHJldmlzZWQgdmVyc2lvbiB3aXRoIGltcHJvdmVkIGdyYW1tYXI6DQoNClRoZSBhaW0gb2YgdGhpcyBob21ld29yayBpcyB0byBwcmVkaWN0IGhvdXNlIHNhbGVzIGluIEtpbmcgQ291bnR5LCBXYXNoaW5ndG9uIFN0YXRlLCBVU0EsIHVzaW5nIE11bHRpcGxlIExpbmVhciBSZWdyZXNzaW9uIChNTFIpLiBUaGUgZGF0YXNldCBjb25zaXN0cyBvZiBoaXN0b3JpY2FsIGRhdGEgb24gaG91c2VzIHNvbGQgYmV0d2VlbiBNYXkgMjAxNCBhbmQgTWF5IDIwMTUuIA0KDQpXZSBhaW0gdG8gcHJlZGljdCBob3VzZSBzYWxlcyBpbiBLaW5nIENvdW50eSB3aXRoIGFuIGFjY3VyYWN5IG9mIGF0IGxlYXN0IDc14oCTODAlIGFuZCB0byBpZGVudGlmeSB0aGUgZmFjdG9ycyByZXNwb25zaWJsZSBmb3IgaGlnaGVyIHByb3BlcnR5IHZhbHVlcywgcGFydGljdWxhcmx5IHRob3NlIHByaWNlZCBhdCAkNjUwSyBhbmQgYWJvdmUuDQoNClRoaXMgZGF0YXNldCBjb250YWlucyBob3VzZSBzYWxlIHByaWNlcyBmb3IgS2luZyBDb3VudHksIGluY2x1ZGluZyBTZWF0dGxlLiBJdCBpbmNsdWRlcyBkYXRhIG9uIGhvbWVzIHNvbGQgYmV0d2VlbiBNYXkgMjAxNCBhbmQgTWF5IDIwMTUuIFRoZSBkYXRhc2V0IGNvbnRhaW5zIDIxIHZhcmlhYmxlcyBhbmQgMjEsNjEzIG9ic2VydmF0aW9ucy4NCg0KKipNZWFuaW5nIG9mIGFiYnJldmlhdGlvbnMgaW4gdGhlIGRhdGFzZXQ6KioNCg0KfCAqKlZhcmlhYmxlKiogICAgICAgfCAqKkRlc2NyaXB0aW9uKiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwNCnwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfA0KfCBpZCAgICAgICAgICAgICAgICAgfCBBIG5vdGF0aW9uIGZvciBhIGhvdXNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBkYXRlICAgICAgICAgICAgICAgfCBEYXRlIGhvdXNlIHdhcyBzb2xkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBwcmljZSAgICAgICAgICAgICAgfCBQcmljZSBpcyBwcmVkaWN0aW9uIHRhcmdldCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBiZWRyb29tcyAgICAgICAgICAgfCBOdW1iZXIgb2YgYmVkcm9vbXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBiYXRocm9vbXMgICAgICAgICAgfCBOdW1iZXIgb2YgYmF0aHJvb21zICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBzcWZ0X2xpdmluZyAgICAgICAgfCBTcXVhcmUgZm9vdGFnZSBvZiB0aGUgaG9tZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBzcWZ0X2xvdCAgICAgICAgICAgfCBTcXVhcmUgZm9vdGFnZSBvZiB0aGUgbG90ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBmbG9vcnMgICAgICAgICAgICAgfCBUb3RhbCBmbG9vcnMgKGxldmVscykgaW4gaG91c2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCB3YXRlcmZyb250ICAgICAgICAgfCBIb3VzZSB3aGljaCBoYXMgYSB2aWV3IHRvIGEgd2F0ZXJmcm9udCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCB2aWV3ICAgICAgICAgICAgICAgfCBIYXMgYmVlbiB2aWV3ZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBjb25kaXRpb24gICAgICAgICAgfCBIb3cgZ29vZCB0aGUgY29uZGl0aW9uIGlzIG92ZXJhbGwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBncmFkZSAgICAgICAgICAgICAgfCBPdmVyYWxsIGdyYWRlIGdpdmVuIHRvIHRoZSBob3VzaW5nIHVuaXQsIGJhc2VkIG9uIEtpbmcgQ291bnR5IGdyYWRpbmcgc3lzdGVtICAgfA0KfCBzcWZ0X2Fib3ZlICAgICAgICAgfCBTcXVhcmUgZm9vdGFnZSBvZiBob3VzZSBhcGFydCBmcm9tIGJhc2VtZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBzcWZ0X2Jhc2VtZW50ICAgICAgfCBTcXVhcmUgZm9vdGFnZSBvZiB0aGUgYmFzZW1lbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCB5cl9idWlsdCAgICAgICAgICAgfCBCdWlsdCBZZWFyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCB5cl9yZW5vdmF0ZWQgICAgICAgfCBZZWFyIHdoZW4gaG91c2Ugd2FzIHJlbm92YXRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCB6aXBjb2RlICAgICAgICAgICAgfCBaaXAgY29kZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBsYXQgICAgICAgICAgICAgICAgfCBMYXRpdHVkZSBjb29yZGluYXRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBsb25nICAgICAgICAgICAgICAgfCBMb25naXR1ZGUgY29vcmRpbmF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCBzcWZ0X2xpdmluZzE1ICAgICAgfCBMaXZpbmcgcm9vbSBhcmVhIGluIDIwMTUgKGltcGxpZXMgc29tZSByZW5vdmF0aW9ucykgVGhpcyBtaWdodCBvciBtaWdodCBub3QgaGF2ZSBhZmZlY3RlZCB0aGUgbG90IHNpemUgYXJlYSB8DQp8IHNxZnRfbG90MTUgICAgICAgICB8IExvdFNpemUgYXJlYSBpbiAyMDE1IChpbXBsaWVzIHNvbWUgcmVub3ZhdGlvbnMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQoNCiMjIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuICoqTG9hZCB0aGUgZGF0YXNldDoqKg0KICAgLSBVc2UgYHJlYWQuY3N2KClgIHRvIGxvYWQgdGhlIGRhdGFzZXQgZnJvbSB0aGUgZmlsZSBga2NfaG91c2VfZGF0YS5jc3ZgLg0KDQoyLiAqKkluc3BlY3QgdGhlIGRhdGEgc3RydWN0dXJlOioqDQogICAtIFVzZSBgc3RyKClgIHRvIGRpc3BsYXkgdmFyaWFibGUgbmFtZXMsIHR5cGVzLCBhbmQgc2FtcGxlIHZhbHVlcy4NCiAgIC0gQ29uZmlybSB0aGUgZGF0YXNldCBjb250YWlucyAyMSB2YXJpYWJsZXMgYW5kIDIxLDYxMyBvYnNlcnZhdGlvbnMuDQoNCjMuICoqRXhwbG9yZSB0aGUgcmVzcG9uc2UgdmFyaWFibGUgKHByaWNlKToqKg0KICAgLSBVc2UgYHN1bW1hcnkoKWAgdG8gdmlldyBzdGF0aXN0aWNzIGxpa2UgdGhlIG1pbmltdW0sIG1lYW4sIGFuZCBtYXhpbXVtIHByaWNlLg0KICAgLSBOb3RlIHRoZSByYW5nZSBhbmQgYXZlcmFnZSBwcmljZSBvZiBob3VzZXMuDQoNCjQuICoqVmlzdWFsaXplIHRoZSByZXNwb25zZSB2YXJpYWJsZToqKg0KICAgLSBDcmVhdGUgYSBoaXN0b2dyYW0gdXNpbmcgYGhpc3QoKWAgdG8gZXhhbWluZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHByaWNlcy4NCiAgIC0gQWRqdXN0IHRoZSBgYnJlYWtzYCBwYXJhbWV0ZXIgdG8gcHJvdmlkZSBhIGRldGFpbGVkIHZpZXcuDQoNCjUuICoqVW5kZXJzdGFuZCB0aGUgZGF0YXNldCBmZWF0dXJlczoqKg0KICAgLSBVc2UgYHN1bW1hcnkoKWAgYW5kIGBoZWFkKClgIHRvIGV4cGxvcmUgcHJlZGljdG9yIHZhcmlhYmxlcyAoZS5nLiwgYGJlZHJvb21zYCwgYHNxZnRfbGl2aW5nYCwgYGNvbmRpdGlvbmApLg0KICAgLSBJZGVudGlmeSBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgc3VjaCBhcyBgd2F0ZXJmcm9udGAsIGB2aWV3YCwgYW5kIGBncmFkZWAuDQoNCmBgYHtyIEV4ZXJjaXNlXzF9DQojIExvYWQgdGhlIGRhdGFzZXQNCmhvdXNlcyA8LSByZWFkLmNzdigia2NfaG91c2VfZGF0YS5jc3YiKQ0KDQojIEluc3BlY3QgdGhlIGRhdGEgc3RydWN0dXJlDQpzdHIoaG91c2VzKQ0KDQojIEV4cGxvcmUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlDQpzdW1tYXJ5KGhvdXNlcyRwcmljZSkNCg0KIyBWaXN1YWxpemUgdGhlIHJlc3BvbnNlIHZhcmlhYmxlDQpoaXN0KGhvdXNlcyRwcmljZSwgYnJlYWtzID0gNTAsIG1haW4gPSAiRGlzdHJpYnV0aW9uIG9mIEhvdXNlIFByaWNlcyIsIHhsYWIgPSAiUHJpY2UgKFVTRCkiKQ0KDQoNCiMgVW5kZXJzdGFuZCB0aGUgZGF0YXNldCBmZWF0dXJlcw0Kc3VtbWFyeShob3VzZXNbLCBjKCJiZWRyb29tcyIsICJiYXRocm9vbXMiLCAic3FmdF9saXZpbmciLCAiY29uZGl0aW9uIiwgImdyYWRlIiwgIndhdGVyZnJvbnQiLCAidmlldyIpXSkNCg0KaGVhZChob3VzZXNbLGMoImJlZHJvb21zIiwgImJhdGhyb29tcyIsICJzcWZ0X2xpdmluZyIsICJjb25kaXRpb24iLCAiZ3JhZGUiLCAid2F0ZXJmcm9udCIsImNvbmRpdGlvbiIpXSkNCg0KdGFibGUoaG91c2VzJHdhdGVyZnJvbnQpDQp0YWJsZShob3VzZXMkZ3JhZGUpDQoNCmBgYA0KDQotLS0NCg0KIyMjIEV4ZXJjaXNlIDI6IEV4cGxvcmluZyBSZWxhdGlvbnNoaXBzIEJldHdlZW4gVmFyaWFibGVzDQoNCkV4YW1pbmluZyByZWxhdGlvbnNoaXBzIGJldHdlZW4gcHJlZGljdG9ycyBhbmQgdGhlIHRhcmdldCB2YXJpYWJsZSBpcyBhIGNyaXRpY2FsIHN0ZXAgYmVmb3JlIGJ1aWxkaW5nIGEgcmVncmVzc2lvbiBtb2RlbC4NCg0KIyMjIyBJbnN0cnVjdGlvbnMNCg0KMS4gKipDb21wdXRlIGEgY29ycmVsYXRpb24gbWF0cml4OioqDQogICAtIFVzZSBgY29yKClgIHdpdGggbnVtZXJpYyB2YXJpYWJsZXMgKGUuZy4sIGBwcmljZWAsIGBzcWZ0X2xpdmluZ2AsIGBzcWZ0X2xvdGAsIGBiZWRyb29tc2AsIGBiYXRocm9vbXNgKS4NCg0KMi4gKipDcmVhdGUgc2NhdHRlcnBsb3RzOioqDQogICAtIFVzZSBgcGxvdCgpYCB0byB2aXN1YWxpemUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGBwcmljZWAgYW5kIHByZWRpY3RvcnMgbGlrZSBgc3FmdF9saXZpbmdgLCBgYmVkcm9vbXNgLCBhbmQgYGJhdGhyb29tc2AuDQoNCjMuICoqSW5jbHVkZSBjYXRlZ29yaWNhbCB2YXJpYWJsZXM6KioNCiAgIC0gVXNlIGJveHBsb3RzIHRvIHZpc3VhbGl6ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYHByaWNlYCBhbmQgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGxpa2UgYHdhdGVyZnJvbnRgIGFuZCBgZ3JhZGVgLg0KDQo0LiAqKkludGVycHJldCB0aGUgcmVzdWx0czoqKg0KICAgLSBJZGVudGlmeSBwcmVkaWN0b3JzIHNob3dpbmcgc3Ryb25nIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGNvcnJlbGF0aW9ucyB3aXRoIHByaWNlLg0KDQpgYGB7ciBFeGVyY2lzZV8yfQ0KIyBDb21wdXRlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXgNCm51bWVyaWNfdmFycyA8LSBjKCJwcmljZSIsICJzcWZ0X2xpdmluZyIsICJzcWZ0X2xvdCIsICJiZWRyb29tcyIsICJiYXRocm9vbXMiLCAic3FmdF9hYm92ZSIsICJzcWZ0X2Jhc2VtZW50IikNCg0KY29yX21hdHJpeCA8LSBjb3IoaG91c2VzWywgbnVtZXJpY192YXJzXSwgdXNlID0gImNvbXBsZXRlLm9icyIpDQoNCnByaW50KGNvcl9tYXRyaXgpDQoNCiMgQ3JlYXRlIHNjYXR0ZXJwbG90cw0KcGxvdChob3VzZXMkc3FmdF9saXZpbmcsIGhvdXNlcyRwcmljZSwgbWFpbiA9ICJQcmljZSB2cy4gU3F1YXJlIEZvb3RhZ2UiLCB4bGFiID0gIlNxdWFyZSBGb290YWdlIiwgeWxhYiA9ICJQcmljZSIpDQoNCnBsb3QoaG91c2VzJGJlZHJvb21zLCBob3VzZXMkcHJpY2UsIG1haW4gPSAiUHJpY2UgdnMuIE51bWJlciBvZiBCZWRyb29tcyIsIHhsYWIgPSAiTnVtYmVyIG9mIEJlZHJvb21zIiwgeWxhYiA9ICJQcmljZSIpDQoNCiMgQm94cGxvdHMgZm9yIGNhdGVnb3JpY2FsIHZhcmlhYmxlcw0KDQpib3hwbG90KHByaWNlIH4gd2F0ZXJmcm9udCwgZGF0YSA9IGhvdXNlcywgbWFpbiA9ICJQcmljZSBieSBXYXRlcmZyb250IiwgeGxhYiA9ICJXYXRlcmZyb250IiwgeWxhYiA9ICJQcmljZSIpDQpib3hwbG90KHByaWNlIH4gY29uZGl0aW9uLCBkYXRhID0gaG91c2VzLCBtYWluID0gIlByaWNlIGJ5IENvbmRpdGlvbiIsIHhsYWIgPSAiQ29uZGl0aW9uIiwgeWxhYiA9ICJQcmljZSIpDQoNCiMgU3Ryb25nIHByZWRpY3RvcnMgYmFzZWQgb24gdGhlIGNvcnJlbGF0aW9uIGFuZCBwbG90cywgaW5jbHVkZSBzcWZ0X2xpdmluZywgYmF0aHJvb21zLCBncmFkZSwgYW5kIHdhdGVyZnJvbnQuIFdlYWtlciBwcmVkaWN0b3JzIGluY2x1ZGUgc3FmdF9sb3QgYW5kIGJlZHJvb21zLiBTcWZ0X2xpdmluZyBpcyB0aGUgc3Ryb25nZXN0IG51bWVyaWMgcHJlZGljdG9yLCBiYXRocm9vbXMgY29udHJpYnV0ZXMgcGFydGljdWxhcmx5IHdpdGggbGFyZ2VyIGhvbWVzLCBncmFkZSBhbWQgd2F0ZXJmcm9udCByZWZsZWN0cyB0aGUgcXVhbGl0eSBvZiB0aGUgaG9tZSB3aGljaCBpcyByZWFzb24gZm9yIGJlaW5nIGEgZ29vZCBwcmVkaWN0b3IuIE1lYW53aGlsZSBiZWRyb29tcyBoYXMgYSBkaW1pbmlzaGluZyByZXR1cm4gYWZ0ZXIgYSBjZXJ0YWluIG11bWJlciBvZiBiZWRyb29tcyBhbmQgc3FmdF9sb3QgaXMgYSBzZWNvbmRhcnkgdmFyaWFibGUgdG8gc3FmdF9saXZpbmcgc28gaXQgaGFzIGxlc3MgaW1wYWN0Lg0KDQpgYGANCg0KLS0tDQoNCiMjIyBFeGVyY2lzZSAzOiBCdWlsZGluZyB0aGUgSW5pdGlhbCBSZWdyZXNzaW9uIE1vZGVsDQoNCkJ1aWxkIGFuIGluaXRpYWwgcmVncmVzc2lvbiBtb2RlbCB1c2luZyBrZXkgcHJlZGljdG9ycywgaW5jbHVkaW5nIGNhdGVnb3JpY2FsIHZhcmlhYmxlcywgdG8gdW5kZXJzdGFuZCB0aGVpciBpbXBhY3Qgb24gaG91c2UgcHJpY2VzLg0KDQojIyMjIEluc3RydWN0aW9ucw0KDQoxLiAqKkNvbnZlcnQgY2F0ZWdvcmljYWwgdmFyaWFibGVzIHRvIGZhY3RvcnM6KioNCiAgIC0gRW5zdXJlIHZhcmlhYmxlcyBsaWtlIGB3YXRlcmZyb250YCwgYHZpZXdgLCBhbmQgYGdyYWRlYCBhcmUgdHJlYXRlZCBhcyBmYWN0b3JzLg0KDQoyLiAqKkZpdCB0aGUgcmVncmVzc2lvbiBtb2RlbDoqKg0KICAgLSBVc2UgYGxtKClgIHdpdGggYHByaWNlYCBhcyB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGFuZCBwcmVkaWN0b3JzIHN1Y2ggYXMgYHNxZnRfbGl2aW5nYCwgYGJlZHJvb21zYCwgYGJhdGhyb29tc2AsIGBncmFkZWAsIGFuZCBgd2F0ZXJmcm9udGAuDQoNCjMuICoqVmlldyBtb2RlbCBjb2VmZmljaWVudHM6KioNCiAgIC0gRXhhbWluZSB0aGUgbW9kZWwgb3V0cHV0IGZvciBjb2VmZmljaWVudHMgYW5kIGludGVyY2VwdC4NCg0KNC4gKipTdW1tYXJpemUgdGhlIG1vZGVsOioqDQogICAtIFVzZSBgc3VtbWFyeSgpYCB0byByZXZpZXcgUi1zcXVhcmVkLCBwLXZhbHVlcywgYW5kIHJlc2lkdWFsIHN0YXRpc3RpY3MuDQoNCmBgYHtyIEV4ZXJjaXNlXzN9DQojIENvbnZlcnQgY2F0ZWdvcmljYWwgdmFyaWFibGVzIHRvIGZhY3RvcnMNCmhvdXNlcyR3YXRlcmZyb250IDwtIGZhY3Rvcihob3VzZXMkd2F0ZXJmcm9udCkNCmhvdXNlcyR2aWV3IDwtIGZhY3Rvcihob3VzZXMkdmlldykNCmhvdXNlcyRncmFkZSA8LSBmYWN0b3IoaG91c2VzJGdyYWRlKQ0KDQojIEZpdCB0aGUgcmVncmVzc2lvbiBtb2RlbA0KaG91c2VfbW9kZWwgPC0gbG0ocHJpY2UgfiBzcWZ0X2xpdmluZyArIGJlZHJvb21zICsgYmF0aHJvb21zICsgZ3JhZGUgKyB3YXRlcmZyb250LCBkYXRhID0gaG91c2VzKQ0KDQojIFZpZXcgY29lZmZpY2llbnRzDQpjb2VmKGhvdXNlX21vZGVsKQ0KDQojIFN1bW1hcml6ZSB0aGUgbW9kZWwNCnN1bW1hcnkoaG91c2VfbW9kZWwpDQpgYGANCg0KLS0tDQoNCiMjIyBFeGVyY2lzZSA0OiBEaWFnbm9zaW5nIGFuZCBJbXByb3ZpbmcgdGhlIE1vZGVsDQoNClJlZmluZSB5b3VyIG1vZGVsIHRvIGltcHJvdmUgaXRzIGZpdCwgaW5jbHVkZSBtb3JlIHZhcmlhYmxlcywgYW5kIGludGVycHJldCB0aGUgcmVzdWx0cy4NCg0KIyMjIyBJbnN0cnVjdGlvbnMNCg0KMS4gKipFdmFsdWF0ZSByZXNpZHVhbHM6KioNCiAgIC0gUGxvdCByZXNpZHVhbHMgdXNpbmcgYHBsb3QoKWAgYW5kIGNoZWNrIGZvciBwYXR0ZXJucy4NCg0KMi4gKipBZGQgbW9yZSBwcmVkaWN0b3JzOioqDQogICAtIEluY2x1ZGUgYWRkaXRpb25hbCB2YXJpYWJsZXMgKGUuZy4sIGBzcWZ0X2xvdGAsIGBjb25kaXRpb25gLCBgeXJfYnVpbHRgLCBgdmlld2ApIHRvIGltcHJvdmUgdGhlIG1vZGVsLg0KDQozLiAqKkluY2x1ZGUgaW50ZXJhY3Rpb24gdGVybXMgYW5kIG5vbmxpbmVhciBlZmZlY3RzOioqDQogICAtIElkZW50aWZ5IGEgdmFyaWFibGUgbGlrZWx5IHRvIGhhdmUgYSBub25saW5lYXIgZWZmZWN0IG9uIHByaWNlIChlLmcuLCBgc3FmdF9saXZpbmdgKS4NCiAgIC0gQWRkIGEgc3F1YXJlZCB0ZXJtIGZvciBgc3FmdF9saXZpbmdgIHRvIGNhcHR1cmUgdGhlIG5vbmxpbmVhciByZWxhdGlvbnNoaXAuDQogICAtIEFkZCBhbiBpbnRlcmFjdGlvbiB0ZXJtIGJldHdlZW4gdHdvIHZhcmlhYmxlcyAoZS5nLiwgYGJhdGhyb29tc2AgYW5kIGBzcWZ0X2xpdmluZ2ApLg0KDQo0LiAqKkZpdCB0aGUgdXBkYXRlZCBtb2RlbDoqKg0KICAgLSBVcGRhdGUgdGhlIG1vZGVsIHRvIGluY2x1ZGUgdGhlIG5ldyB0ZXJtcy4NCg0KNS4gKipDb21wYXJlIG1vZGVsczoqKg0KICAgLSBDb21wYXJlIFItc3F1YXJlZCBhbmQgYWRqdXN0ZWQgUi1zcXVhcmVkIHZhbHVlcyB0byBkZXRlcm1pbmUgbW9kZWwgaW1wcm92ZW1lbnRzLg0KDQpgYGB7ciBFeGVyY2lzZV80fQ0KIyBBZGQgc3F1YXJlZCB0ZXJtIGZvciBzcWZ0X2xpdmluZw0KaG91c2VzJHNxZnRfbGl2aW5nX3NxIDwtIGhvdXNlcyRzcWZ0X2xpdmluZ14yDQoNCiMgQWRkIGludGVyYWN0aW9uIHRlcm0gYmV0d2VlbiBiYXRocm9vbXMgYW5kIHNxZnRfbGl2aW5nDQpob3VzZXMkYmF0aF9zcWZ0X2ludGVyYWN0aW9uIDwtIGhvdXNlcyRiYXRocm9vbXMgKiBob3VzZXMkc3FmdF9saXZpbmcNCg0KIyBGaXQgdGhlIHVwZGF0ZWQgbW9kZWwNCmhvdXNlX21vZGVsX2ltcHJvdmVkIDwtIGxtKHByaWNlIH4gc3FmdF9saXZpbmcgKyBzcWZ0X2xpdmluZ19zcSArIGJlZHJvb21zICsgYmF0aHJvb21zICsgYmF0aF9zcWZ0X2ludGVyYWN0aW9uICsgZ3JhZGUgKyB3YXRlcmZyb250ICsgdmlldyArIGNvbmRpdGlvbiArIHlyX2J1aWx0LCBkYXRhID0gaG91c2VzKQ0KDQojIFN1bW1hcml6ZSB0aGUgaW1wcm92ZWQgbW9kZWwNCnN1bW1hcnkoaG91c2VfbW9kZWxfaW1wcm92ZWQpDQpzdW1tYXJ5KGhvdXNlX21vZGVsKQ0KDQpBSUMoaG91c2VfbW9kZWwpDQpBSUMoaG91c2VfbW9kZWxfaW1wcm92ZWQpDQoNCiNXZSBjYW4gc2VlIHRoYXQgdGhlcmUgd2FzIGFuIGltcHJvdmVtZW50IHdpdGhpbiB0aGUgbW9kZWwgYmVjYXVzZSB0aGUgYWRqdXN0ZWQgci1zcXVhcmVkIHZhbHVlIHdlbnQgZnJvbSAwLjYxNTQgdG8gMC42ODkzLCBhbHNvIHlvdSBjYW4gc2VlIHRocm91Z2ggdGhlIEFJQyB0aGF0IHRoZXJlIHdhcyBhIGRlY3JlYXNlIHdoaWNoIGlzIGFuIGluZGljYXRvciBvZiBhIGJldHRlciBtb2RlbA0KYGBgDQoNCi0tLQ0KDQojIyMgRXhlcmNpc2UgNTogRXZhbHVhdGluZyBNb2RlbCBQZXJmb3JtYW5jZQ0KDQpBc3Nlc3MgdGhlIHBlcmZvcm1hbmNlIG9mIHlvdXIgaW1wcm92ZWQgbW9kZWwgYW5kIGludGVycHJldCB0aGUgc2lnbmlmaWNhbmNlIG9mIHByZWRpY3RvcnMuDQoNCiMjIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuICoqUmV2aWV3IG1vZGVsIHN1bW1hcnk6KioNCiAgIC0gRXhhbWluZSB0aGUgY29lZmZpY2llbnRzLCBwLXZhbHVlcywgUi1zcXVhcmVkLCBhbmQgYWRqdXN0ZWQgUi1zcXVhcmVkIHZhbHVlcy4NCg0KMi4gKipJbnRlcnByZXQgY29lZmZpY2llbnRzOioqDQogICAtIElkZW50aWZ5IHNpZ25pZmljYW50IHByZWRpY3RvcnMgYmFzZWQgb24gcC12YWx1ZXMuDQoNCjMuICoqQW5hbHl6ZSB0aGUgZWZmZWN0IG9mIG5vbmxpbmVhciBhbmQgaW50ZXJhY3Rpb24gdGVybXM6KioNCiAgIC0gSW50ZXJwcmV0IHRoZSBjb2VmZmljaWVudHMgb2YgYHNxZnRfbGl2aW5nX3NxYCBhbmQgYGJhdGhfc3FmdF9pbnRlcmFjdGlvbmAuDQoNCmBgYHtyIEV4ZXJjaXNlXzV9DQojIFJldmlldyBtb2RlbCBzdW1tYXJ5DQpzdW1tYXJ5KGhvdXNlX21vZGVsX2ltcHJvdmVkKQ0KDQoiQ29lZmZpY2VudHMgaW4gcmVncmVzc2lvbiBtb2RlbHMgY2hhbmdlIGluIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUiDQoNCiMgRm9yIGlkZW5pZnlpbmcgdGhlIHNpZ25pZmljYW50IHByZWRpY3RvcidzIHdlJ3JlIGxvb2tpbmcgZm9yIHAgdmFsdWUgdGhhdCBpcyBsZXNzIHRoYW4gMC4wNS4gU28gd2hlbiB3ZSB1c2UgdGhlIHN1bW1hcnkgb2YgdGhlIGltcHJvdmVkIGhvdXNlIG1vZGVsIHdlIGNhbiBzZWUgdGhhdCBzcWZ0X2xpdmluZywgYmF0aHJvb21zLCBzcWZ0X2xpdmluZ19zcSwgYmF0aF9zcWZ0X2ludGVyYWN0aW9uLCBhbmQgZ3JhZGUgYXJlIGFsbCBzaWduaWZpY2FudCBwcmVkaWN0b3JzLiBNZWFud2hpbGUgYW55IHAgdmFsdWVzIHRoYXQgYXJlIGdyZWF0ZXIgdGhhdCAwLjA1IHdoaWNoIGxlYXZlcyB0aGUgbGVmdCBvdmVyIHZhcmlhYmxlcyBhcyBub24tc2lnbmlmaWNhbnQgcHJlZGljdG9ycy4NCg0KIyBJbiB0ZXJtcyBvZiB0aGUgZWZmZWN0IG9mIG5vbmxpbmVhciB0ZXJtcyB3ZSBjYW4gc3BlY2lmaWNhbGx5IGlkZW50aWZ5IHNxZnRfbGl2aW5nIGFuZCBzcWZ0X2xpdmluZ19zcS4gU3FmdF9saXZpbmcgaGFzIGEgcG9zaXRpdmUgY29lZmZpY2VudCB3aGljaCBpbmRpY2F0ZWQgdG8gdXMgdGhhdCBpbml0aWFsbHkgaG91c2UgcHJpY2VzIGluY3JlYXNlIHdpdGggdGhlIG1vcmUgc3F1YXJlIGZvb3RhZ2UgZ3Jvd3MsIG1lYW53aGlsZSBzcWZ0X2xpdmluZ19zcSBoYXMgYSBuZWdhdGl2ZSBjb2VmZmljaWVudCB3aGljaCBpbmlkaWNhdGVkIHRoYXQgdGhlcmUgaXMgbGVzcyBpbXBhY3Qgb3IgcmV0dXJuIGluIHByaWNlIGFzIHNxdWFyZSBmb290YWdlIGdyb3dzLiBVbHRpbWF0ZWx5IHRoaXMgZWZmZWN0IGlsbHVzdHJhdGVzIHRoYXQgdGhlcmUgd2lsbCBiZSBkaW1pbmlzaGluZyByZXR1cm5zIG9mIGFkZGluZyBkaWZmZXJlbnQgdmFyaWFibGVzIGRlcGVuZGVudCB1cG9uIHRoZWlyIGNvZWZmaWNpZW50IHdoaWNoIGRpcmVjdGx5IGltcHJvdmVzIHRoZSBtb2RlbCdzIGFiaWxpdHkgdG8gcHJlZGljdCBwcmljZXMgZm9yIGRpZmZlcmVudCBob21lcy4gSW4gdGhpcyBzcGVjaWZpYyBjYXNlIHdlIHNlZSB0aGF0IGZvciBzbWFsbGVyIGhvbWVzLCBhZGRpbmcgc3F1YXJlIGZvb3RhZ2Ugd291bGQgaGF2ZSBhIGxhcmdlciBpbXBhY3Qgb24gdGhlIHByaWNlIHRoYW4gaWYgd2Ugd2VyZSB0byBhZGQgc3F1YXJlIGZvb3RhZ2UgdG8gYW4gYWxyZWFkeSBsYXJnZSBob21lDQoNCiMgSW4gdGVybXMgb2YgSW50ZXJhY3Rpb24gdGVybXMgdGhlc2UgYXJlIHVzZWQgdG8gbWVhc3VyZSB0aGUgZWZmZWN0cyBvZiBvbmUgdmFyaWFibGUgb24gdGhlIGxldmVsIG9mIGFub3RoZXIuIFNvIGZvciBleGFtcGxlIHdoZW4gd2Ugc29sdmVkIGZvciB0aGUgdmFyaWFibGUgb2YgYm90aCBiYXRocm9vbXMgYW5kIHNxdWFyZSBmZWV0IHdlIHdlcmUgYWJsZSB0byBnZXQgYSBwb3NpdGl2ZSBjb2VmZmljaWVudC4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBhIGxhcmdlciBob21lIHdpdGggbW9yZSBiYXRocm9vbXMgaGF2ZSBhIGhpZ2hlciBwcmljZS4gVGhpcyB3b3VsZG4ndCBoYXZlIGJlZW4gc2hvd24gd2l0aG91dCBjb21iaW5pbmcgdGhlIHRlcm1zIGFuZCBjb3VsZCBoYXZlIGxlZCB0byBhIG1pc2xlYWRpbmcgY29uY2x1c2lvbiB3aXRoIGEgbW9kZWwgaW4gd2hpY2ggeW91IGF0dHJpYnV0ZWQgZWFjaCBvbmUgaW5kaXZpZHVhbGx5Lg0KDQpgYGANCg0KLS0tDQoNCiMjIyBFeGVyY2lzZSA2OiBQcmVkaWN0aW5nIEhvdXNlIFByaWNlcw0KDQpVc2UgdGhlIGltcHJvdmVkIG1vZGVsIHRvIHByZWRpY3QgaG91c2UgcHJpY2VzIGFuZCBldmFsdWF0ZSBpdHMgcGVyZm9ybWFuY2UuDQoNCiMjIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuICoqR2VuZXJhdGUgcHJlZGljdGlvbnM6KioNCiAgIC0gVXNlIGBwcmVkaWN0KClgIG9uIHRoZSBkYXRhc2V0IHRvIGNvbXB1dGUgcHJlZGljdGVkIHByaWNlcy4NCg0KMi4gKipWaXN1YWxpemUgcHJlZGljdGlvbnM6KioNCiAgIC0gQ3JlYXRlIGEgc2NhdHRlcnBsb3Qgb2YgYWN0dWFsIHZzLiBwcmVkaWN0ZWQgcHJpY2VzLg0KDQozLiAqKkV2YWx1YXRlIGFjY3VyYWN5OioqDQogICAtIENvbXB1dGUgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gYWN0dWFsIGFuZCBwcmVkaWN0ZWQgcHJpY2VzLg0KDQo0LiAqKlByZWRpY3QgZm9yIGEgbmV3IGhvdXNlOioqDQogICAtIENyZWF0ZSBhIG5ldyBkYXRhIGZyYW1lIHdpdGggdmFsdWVzIGZvciBhbGwgcHJlZGljdG9ycywgaW5jbHVkaW5nIHNxdWFyZWQgYW5kIGludGVyYWN0aW9uIHRlcm1zLg0KICAgLSBVc2UgYHByZWRpY3QoKWAgdG8gZXN0aW1hdGUgdGhlIHByaWNlIG9mIHRoaXMgaHlwb3RoZXRpY2FsIGhvdXNlLg0KDQoNCmBgYHtyIEV4ZXJjaXNlXzZ9DQojIEdlbmVyYXRlIHByZWRpY3Rpb25zDQpob3VzZXMkcHJlZGljdGVkX3ByaWNlIDwtIHByZWRpY3QoaG91c2VfbW9kZWxfaW1wcm92ZWQsbmV3ZGF0YSA9IGhvdXNlcykNCg0KIyBWaXN1YWxpemUgcHJlZGljdGVkIHZzLiBhY3R1YWwgcHJpY2VzDQpwbG90KGhvdXNlcyRwcmljZSwgaG91c2VzJHByZWRpY3RlZF9wcmljZSwgbWFpbiA9ICJQcmVkaWN0ZWQgdnMuIEFjdHVhbCBQcmljZXMiLCB4bGFiID0gIkFjdHVhbCBQcmljZXMiLCB5bGFiID0gIlByZWRpY3RlZCBQcmljZXMiKQ0KYWJsaW5lKGEgPSAwLCBiID0gMSwgY29sID0gIlJlZCIsIGx3ZCA9IDIpDQoNCiMgQ29tcHV0ZSBjb3JyZWxhdGlvbg0KY29yKGhvdXNlcyRwcmljZSwgaG91c2VzJHByZWRpY3RlZF9wcmljZSkNCg0KIyBQcmVkaWN0IGZvciBhIG5ldyBob3VzZQ0KbmV3X2hvdXNlIDwtIGRhdGEuZnJhbWUoDQogIHNxZnRfbGl2aW5nID0gMjUwMCwNCiAgc3FmdF9saXZpbmdfc3EgPSAyNTAwXjIsDQogIGJlZHJvb21zID0gMywNCiAgYmF0aHJvb21zID0gMiwNCiAgYmF0aF9zcWZ0X2ludGVyYWN0aW9uID0gMiAqIDI1MDAsDQogIGdyYWRlID0gZmFjdG9yKDgsIGxldmVscyA9IGxldmVscyhob3VzZXMkZ3JhZGUpKSwNCiAgd2F0ZXJmcm9udCA9IGZhY3RvcigwLCBsZXZlbHMgPSBsZXZlbHMoaG91c2VzJHdhdGVyZnJvbnQpKSwNCiAgdmlldyA9IGZhY3RvcigwLCBsZXZlbHMgPSBsZXZlbHMoaG91c2VzJHZpZXcpKSwNCiAgY29uZGl0aW9uID0gMywNCiAgeXJfYnVpbHQgPSAyMDAwDQopDQpwcmVkaWN0ZWRfcHJpY2VfbmV3IDwtIHByZWRpY3QoaG91c2VfbW9kZWxfaW1wcm92ZWQsIG5ld2RhdGEgPSBuZXdfaG91c2UpDQpwcmludChwcmVkaWN0ZWRfcHJpY2VfbmV3KQ0KYGBgDQoNCi0tLQ0KDQojIyMgRXhlcmNpc2UgNzogSW50ZXJwcmV0aW5nIHRoZSBJbXBhY3Qgb2YgTm9ubGluZWFyIGFuZCBJbnRlcmFjdGlvbiBFZmZlY3RzDQoNClVuZGVyc3RhbmRpbmcgaG93IG5vbmxpbmVhciB0cmFuc2Zvcm1hdGlvbnMgYW5kIGludGVyYWN0aW9uIHRlcm1zIGluZmx1ZW5jZSB0aGUgbW9kZWwgaXMgY3J1Y2lhbCBmb3IgaW50ZXJwcmV0aW5nIHRoZSByZXN1bHRzIGFjY3VyYXRlbHkuDQoNCiMjIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuICoqSW50ZXJwcmV0IHRoZSBjb2VmZmljaWVudCBvZiB0aGUgc3F1YXJlZCB0ZXJtIChgc3FmdF9saXZpbmdfc3FgKToqKg0KICAgLSBEaXNjdXNzIGhvdyB0aGUgc3F1YXJlIG9mIGxpdmluZyBhcmVhIGFmZmVjdHMgdGhlIHByaWNlLg0KICAgLSBFeHBsYWluIHdoZXRoZXIgdGhpcyBzdWdnZXN0cyBhIGRpbWluaXNoaW5nIG9yIGluY3JlYXNpbmcgcmV0dXJuIG9uIGFkZGl0aW9uYWwgc3F1YXJlIGZvb3RhZ2UuDQoNClRoZSBzcXVhcmVkIHRlcm0gc3FmdF9saXZpbmdfc3EgcmVwcmVzZW50cyBhIG5vbmxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBzcXVhcmUgZmVldCBhbmQgcHJpY2Ugb2YgaG9tZS4gVGhpcyB3YXMgYW5zd2VyZWQgYmVmb3JlIGJ1dCBhIHBvc2l0aXZlIGNvZWZmaWNpZW50IGZvciBzcWZ0X2xpdmluZyBhbmQgYSBuZWdhdGl2ZSBjb2VmZmljaWVudCBmb3Igc3FmdF9saXZpbmdfc3Egd2hpY2ggd2lsbCBpbmRpY2F0ZSBkaW1pbmlzaGluZyByZXR1cm5zLiBUaGlzIGlzIGJlY2F1c2UgaW5pdGlhbGx5IGFuIGluY3JlYXNlIGluIHNxZnQgc2lnbmlmaWNhbnRseSBpbXBhY3RzIHRoZSBwcmljZSBvZiBhIGhvdXNlLCBob3dldmVyIHdoZW4gc3FmdCBiZWNvbWVzIGxhcmdlIHRoZSBwcmljZSBpbmNyZWFzZSB0YXBlcnMgb2ZmIGFuZCBoYXMgYSBkaW1pbmlzaGluZyBlZmZlY3QuIA0KDQoNCjIuICoqSW50ZXJwcmV0IHRoZSBpbnRlcmFjdGlvbiB0ZXJtIChgYmF0aF9zcWZ0X2ludGVyYWN0aW9uYCk6KioNCiAgIC0gRXhwbGFpbiBob3cgdGhlIGludGVyYWN0aW9uIGJldHdlZW4gYmF0aHJvb21zIGFuZCBsaXZpbmcgYXJlYSBpbmZsdWVuY2VzIHRoZSBwcmljZS4NCiAgIC0gRGlzY3VzcyBzY2VuYXJpb3Mgd2hlcmUgdGhpcyBpbnRlcmFjdGlvbiBjb3VsZCBzaWduaWZpY2FudGx5IGltcGFjdCB0aGUgaG91c2UgcHJpY2UuDQogICANClRoZSBpbnRlcmFjdGlvbiB0ZXJtIGJhdGhfc3FmdF9pbnRlcmFjdGlvbiBjYXB0dXJlcyB0aGUgY29tYmluZWQgZWZmZWN0IG9mIGJhdGhyb29tcyBhbmQgbGl2aW5nIGFyZWEgb24gcHJpY2UuIEEgcG9zaXRpdmUgY29lZmZpY2llbnQgbWVhbnMgdGhhdCB0aGUgdmFsdWUgb2YgYWRkaW5nIGJhdGhyb29tcyBpbmNyZWFzZXMgd2l0aCBhIGxhcmdlciBzcXVhcmUgZm9vdGFnZS4gSW4gdGVybXMgb2YgYSBzcGVjaWZpYyBzY2VuYXJpbyB0aGF0IHdvdWxkIGltcGFjdCB0aGUgaG91c2UgcHJpY2Ugd2UgY291bGQgaW1hZ2luZSB0aGUgZGlmZmVyZW5jZSBvZiBpbnB1dHRpbmcgYSAyIGJhdGhyb29tIDEsMDAwIHNxZnQgaG9tZSBhbmQgYSAyIGJhdGhyb29tIDIsMDAwIHNxZnQgaG9tZS4gV2hlbiB5b3UgZG8gdGhlIG1hdGggeW91J2xsIGZpbmQgdGhhdCB0aGUgaW50ZXJhY3Rpb24gZWZmZWN0IHNob3dzIGFsbW9zdCBkb3VibGUgZGlmZmVyZW5jZSBpbiBwcmljZS4gVWx0aW1hdGVseSBhZGRpbmcgYmF0aHJvb21zIHRvIGxhcmdlciBob21lcyB3aWxsIGFkZCBtb3JlIHZhbHVlIHRvIHRoZSBob21lLCB3aGlsZSBkbyBtaW5pbWFsIGZvciBzbWFsbCBob21lcy4NCg0KMy4gKipTdW1tYXJpemUgdGhlIG92ZXJhbGwgbW9kZWwgaW1wcm92ZW1lbnQ6KioNCiAgIC0gQ29tcGFyZSB0aGUgYWRqdXN0ZWQgUi1zcXVhcmVkIG9mIHRoZSBpbml0aWFsIGFuZCBpbXByb3ZlZCBtb2RlbHMuDQogICAtIERpc2N1c3MgaG93IGFkZGluZyBub25saW5lYXIgYW5kIGludGVyYWN0aW9uIHRlcm1zIGhhcyBhZmZlY3RlZCBtb2RlbCBwZXJmb3JtYW5jZS4NCg0KSW4gdGhlIGluaXRpYWwgbW9kZWwgdGhlIGFkanVzdGVkIFJeMiB3YXMgMC43NSB3aGlsZSBpbiB0aGUgaW1wcm92ZWQgbW9kZWwgaXQgd2FzIDAuODIuIFRoaXMgbWVhbnMgdGhhdCBmb3IgdGhlIG5vbmxpbmVhciBhbmQgaW50ZXJhY3Rpb24gdGVybXMgd2FzIHRoZSByZWFzb25pbmcgZm9yIGEgNyUgdmFyaWFuY2UgaW4gdGhlIGhvdXNlIHByaWNlcy4gQWRkaW5nIHRoZXNlIHRlcm1zIHdhcyBzaWduaWZpY2FudCBiZWNhdXNlIGl0IGltcHJvdmVzIHRoZSBtb2RlbCdzIGFiaWxpdHkgdG8gY2FwdHVyZSBkaW1pbmlzaCByZXR1cm5zIGZvciBsYXJnZXIgc3F1YXJlIGZvb3RhZ2UgYW5kIHRoZSBlZmZlY3RzIGJldHdlZW4gYmF0aHJvb21zIGFuZCBsaXZpbmcgYXJlYS4gV2Ugc2VlIHdpdGhpbiBpbiByZXNpZHVhbCB2YXJpYW5jZSB0aGF0IHRoZSBpbXByb3ZlZCBtb2RlbCBpcyBtb3JlIGV2ZW5seSBkaXN0cmlidXRlZCB3aGljaCBzaG93cyB0aGF0IGl0IHdhcyBhIGJldHRlciBmaXQuIA0KDQo=