1 Introduction

The RMS Titanic was a British luxury passenger liner that sank during its maiden voyage en route to New York City from Southampton, England, killing about 1,500 passengers and ship personnel. It is one of the most famous tragedies in modern history, it inspired numerous stories, several films, and a musical and has been the subject of much scholarship and scientific speculation.

This report will continue the scientific exploration of the Titanic. The estimated 2,224 passengers all have their own stories of escape or death in the wreck. It is believed, however, that studying the underlying information about these passengers can provide insight on why certain people survived.

2 Data Source

The data set used in this report is sourced from Kaggle.com. It was orignially created for a machine learning competition hosted by Kaggle. The link for this data set is https://www.kaggle.com/c/titanic. The data is originally split into seperate train and testing data sets for purposes of the competition. The train data is used in this report for more observations and the complete set of variables.

The data was uploaded to a GitHub repository for perpetual online access. This report will source the data from this repository (URL, https://raw.githubusercontent.com/ncbrechbill/STA321/refs/heads/main/STA321/titanic.csv)

This data contains 891 observations on 12 variables. Any observations of N/A in variables of interest will be removed. The variables are:

  1. PassengerID: A unique identifier
  2. Survived: The survival status of the passenger (0 = No, 1 = Yes)
  3. Pclass: The passenger’s ticket class (1st, 2nd, or 3rd)
  4. Name: The passenger’s name
  5. Sex: The passenger’s sex
  6. Age: The passenger’s age in years
  7. sibSp: Number of siblings/spouse aboard
  8. Parch: Number of parents/children aboard
  9. Ticket: Passenger’s ticket number
  10. Fare: Passenger’s boarding fare in USD
  11. Cabin: The passenger’s cabin
  12. Embarked: Location which passenger embarked (C = Cherbourg, Q = Queenstown, S = Southampton)
url = "https://raw.githubusercontent.com/ncbrechbill/STA321/refs/heads/main/STA321/titanic.csv"
titanic <- read.csv(url)
data <- na.omit(dplyr::select(titanic, Survived, Pclass, Age, Sex, SibSp, Parch, Fare))
data$Pclass <- as.factor(data$Pclass)

3 Research Question

This report investigates the relationship between a passenger’s age, ticket class, and sex with their likelihood of survival on the Titanic. To address this, a multiple logistic regression model is applied, with survival (survived vs. not survived) as the binary outcome variable and passenger age, sex, and ticket class as the predictors. This approach allows us to evaluate whether these factors significantly affected survival odds, estimate the direction and magnitude of the effects, and assess the model’s ability to explain variation in survival outcomes.

4 Exploratory Data Analysis

All observations with missing values in any of the variables were removed. This leaves 714 observations. Their distributions and potential correlations are provided in the figure below.

pairs.panels(data[,-9], 
             method = "pearson", # correlation method
             hist.col = "royalblue",
             density = TRUE,  # show density plots
             ellipses = TRUE # show correlation ellipses
             )

We can see that there are more deaths than survivals, more high class passengers than middle or low, and more men than women. Age is slightly skewed right, but no transformation will be applied. SibSP, Parch, and Fare are highly skewed. PassengerID, Name, Ticket, Cabin, and Embarked were not included for irrelevance.

5 Multiple Logistic Regression

The variables sex, Age, and Pclass will be used for logistic regression. Fare was not selected because it is already categorized by Pclass. Parch and SibSp were not selected because of a few confounding factors. For example a passenger could have at most 2 parents aboard, but any realistically possible amount of children could be aboard with a parent. Similarly, a passenger can have at most one spouse, but any number of siblings aboard. These variables can lead to any number of interpretations and their influence on a model would be obscured by these numerous possibilities.

5.1 Full Model

The first model contains all three factors.

full.model <- glm(Survived ~
                    Pclass+Age+Sex,
                  family = binomial(link = "logit"),
                  data = data)
pander(summary(full.model)$coef,
       caption="Summary of inferential statistics of the full model")
Summary of inferential statistics of the full model
  Estimate Std. Error z value Pr(>|z|)
(Intercept) 3.777 0.4011 9.416 4.682e-21
Pclass2 -1.31 0.2781 -4.71 2.472e-06
Pclass3 -2.581 0.2814 -9.169 4.761e-20
Age -0.03699 0.007656 -4.831 1.359e-06
Sexmale -2.523 0.2074 -12.16 4.811e-34

All values were statistically significant. Before creating a reduced model, we explore potential multicollinearity among the predictor variables. The following table shows the VIF for each individual variable.

pander(vif(full.model))
  GVIF Df GVIF^(1/(2*Df))
Pclass 1.417 2 1.091
Age 1.333 1 1.155
Sex 1.073 1 1.036

All GVIF values are under 1.5. This suggests no multicollinearity issues between these variables.

5.2 Reduced Model

The reduced model was constructed on the variable sex, determined by the correlation coefficients determined on the response variable during EDA. The coefficient remains similar for the sex variable, and in the same direction (negative towards male).

reduced.model <- glm(Survived~
                       Sex,
                     family = binomial(link = "logit"),
                     data = data)
pander(summary(reduced.model)$coef)
  Estimate Std. Error z value Pr(>|z|)
(Intercept) 1.124 0.1439 7.814 5.524e-15
Sexmale -2.478 0.185 -13.39 6.701e-41

5.3 Automatic Model Selection

The reduced model may use insufficient information, resulting in underfitting (missing important effects), while the full model can lead to overfitting (modeling noise and failing to generalize). To address this, we use automatic variable selection to find a simpler, more interpretable, and better-performing model by intelligently choosing a subset of predictors that includes the important variables from the reduced model while avoiding the noise of the full model.

final.model.forward = stepAIC(reduced.model, 
                      scope = list(lower=formula(reduced.model),upper=formula(full.model)),
                      direction = "forward",   # forward selection
                      trace = 0   # do not show the details
                      )
pander(summary(final.model.forward)$coef, 
      caption="Summary of inferential statistics of the final model")
Summary of inferential statistics of the final model
  Estimate Std. Error z value Pr(>|z|)
(Intercept) 3.777 0.4011 9.416 4.682e-21
Sexmale -2.523 0.2074 -12.16 4.811e-34
Pclass2 -1.31 0.2781 -4.71 2.472e-06
Pclass3 -2.581 0.2814 -9.169 4.761e-20
Age -0.03699 0.007656 -4.831 1.359e-06

5.4 Performance Comparison

The full model was automatically selected. Thus, their deviance is the same. With the full model utilizing only three predictors, the model remains relatively simple and parsimonious.

## Other global goodness-of-fit
global.measure=function(s.logit){
dev.resid = s.logit$deviance
dev.0.resid = s.logit$null.deviance
aic = s.logit$aic
goodness = cbind(Deviance.residual =dev.resid, Null.Deviance.Residual = dev.0.resid,
      AIC = aic)
goodness
}
goodness=rbind(full.model = global.measure(full.model),
      reduced.model=global.measure(reduced.model),
      final.model=global.measure(final.model.forward))
row.names(goodness) = c("full.model", "reduced.model", "auto.selected.model")
pander(goodness, caption ="Comparison of global goodness-of-fit statistics")
Comparison of global goodness-of-fit statistics
  Deviance.residual Null.Deviance.Residual AIC
full.model 647.3 964.5 657.3
reduced.model 750.7 964.5 754.7
auto.selected.model 647.3 964.5 657.3

6 Final Model

The final model is translated into an odds ratio for interpretation. Starting at a baseline 43.69 Odds ratio of survival, the ratio was reduced by a passenger being male and having a 2nd or 3rd class ticket. Every year of age also reduced survival odds.

# Odds ratio
model.coef.stats = summary(final.model.forward)$coef
odds.ratio = exp(coef(final.model.forward))
out.stats = cbind(model.coef.stats, odds.ratio = odds.ratio)                 
pander(out.stats,caption = "Summary Stats with Odds Ratios")
Summary Stats with Odds Ratios
  Estimate Std. Error z value Pr(>|z|) odds.ratio
(Intercept) 3.777 0.4011 9.416 4.682e-21 43.69
Sexmale -2.523 0.2074 -12.16 4.811e-34 0.08024
Pclass2 -1.31 0.2781 -4.71 2.472e-06 0.2699
Pclass3 -2.581 0.2814 -9.169 4.761e-20 0.07573
Age -0.03699 0.007656 -4.831 1.359e-06 0.9637

7 Analysis

The final model allows us to analyze the demographics that associate with survival the most. Of the passengers analyzed, the younger 1st class women had the best odds of survival. Older 3rd class men had the worst odds of survival. This provides insights into what the passengers found most important into factoring who’s survival was prioritized.

A popular excerpt from the Titanic’s wreck was “women and children first”. At a glance, the data supports this, as both women and younger passenger’s had better odds of survival. Additionally, we can see that higher class passengers had higher odds of survival. One can surmise that this narrative would be less popular than the relatively heroic “women and children first” rhetoric. In several instances, wealth helps people survive, and it seems the wreck of the titanic was no exception.

This model will be tweaked for prediction in a later report.

LS0tDQp0aXRsZTogIk11bHRpcGxlIExvZ2lzdGljIEFuYWx5c2lzIG9mIFJNUyBUaXRhbmljIFN1cnZpdm9ycyINCmF1dGhvcjogIk5vYWggQnJlY2hiaWxsIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfd2lkdGg6IDYNCiAgICBmaWdfaGVpZ2h0OiA2DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgdGhlbWU6IGx1bWVuDQotLS0NCg0KYGBge2NzcywgZWNobyA9IEZBTFNFfQ0KLyogQ2FzY2FkaW5nIFN0eWxlIFNoZWV0cyAoQ1NTKSBpcyBhIHN0eWxlc2hlZXQgbGFuZ3VhZ2UgdXNlZCB0byBkZXNjcmliZSB0aGUgcHJlc2VudGF0aW9uIG9mIGEgZG9jdW1lbnQgd3JpdHRlbiBpbiBIVE1MIG9yIFhNTC4gaXQgaXMgYSBzaW1wbGUgbWVjaGFuaXNtIGZvciBhZGRpbmcgc3R5bGUgKGUuZy4sIGZvbnRzLCBjb2xvcnMsIHNwYWNpbmcpIHRvIFdlYiBkb2N1bWVudHMuICovDQoNCmgxLnRpdGxlIHsgIC8qIFRpdGxlIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiB0aGUgcmVwb3J0IHRpdGxlICovDQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtZmFtaWx5OiAiR2lsbCBTYW5zIiwgc2Fucy1zZXJpZjsNCn0NCmg0LmF1dGhvciB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgYXV0aG9ycyAgKi8NCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBkYXRlICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsgLyogSGVhZGVyIDEgLSBmb250IHNwZWNpZmljYXRpb25zIGZvciBsZXZlbCAxIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAyMnB4Ow0KICAgIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQpoMiB7IC8qIEhlYWRlciAyIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBmb3IgbGV2ZWwgMiBzZWN0aW9uIHRpdGxlICovDQogICAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCAzIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCA0IHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpib2R5IHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQouaGlnaGxpZ2h0bWUgeyBiYWNrZ3JvdW5kLWNvbG9yOnllbGxvdzsgfQ0KDQpwIHsgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsgfQ0KDQpgYGANCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbG9hZF9wYWNrYWdlcyA8LSBmdW5jdGlvbihwa2dfbGlzdCkgew0KICBmb3IgKHBrZyBpbiBwa2dfbGlzdCkgew0KICAgIGlmICghcmVxdWlyZShwa2csIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsNCiAgICAgIGluc3RhbGwucGFja2FnZXMocGtnLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQ0KICAgICAgbGlicmFyeShwa2csIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkNCiAgICB9DQogIH0NCn0NCg0KcGFja2FnZXMgPC0gYygidGlkeXZlcnNlIiwgIkdHYWxseSIsICJwYW5kZXIiLCAiY2FyIiwgIk1BU1MiLCAicHN5Y2giKQ0KbG9hZF9wYWNrYWdlcyhwYWNrYWdlcykNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0gVFJVRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEsDQogICAgICAgICAgICAgICAgICAgICAgZmlnLmFsaWduID0gImNlbnRlciINCiAgICAgICAgICAgICAgICAgICAgICApICAgDQpgYGANCg0KIyBJbnRyb2R1Y3Rpb24NCg0KVGhlIFJNUyBUaXRhbmljIHdhcyBhIEJyaXRpc2ggbHV4dXJ5IHBhc3NlbmdlciBsaW5lciB0aGF0IHNhbmsgZHVyaW5nIGl0cyBtYWlkZW4gdm95YWdlIGVuIHJvdXRlIHRvIE5ldyBZb3JrIENpdHkgZnJvbSBTb3V0aGFtcHRvbiwgRW5nbGFuZCwga2lsbGluZyBhYm91dCAxLDUwMCBwYXNzZW5nZXJzIGFuZCBzaGlwIHBlcnNvbm5lbC4gSXQgaXMgb25lIG9mIHRoZSBtb3N0IGZhbW91cyB0cmFnZWRpZXMgaW4gbW9kZXJuIGhpc3RvcnksIGl0IGluc3BpcmVkIG51bWVyb3VzIHN0b3JpZXMsIHNldmVyYWwgZmlsbXMsIGFuZCBhIG11c2ljYWwgYW5kIGhhcyBiZWVuIHRoZSBzdWJqZWN0IG9mIG11Y2ggc2Nob2xhcnNoaXAgYW5kIHNjaWVudGlmaWMgc3BlY3VsYXRpb24uDQoNClRoaXMgcmVwb3J0IHdpbGwgY29udGludWUgdGhlIHNjaWVudGlmaWMgZXhwbG9yYXRpb24gb2YgdGhlIFRpdGFuaWMuIFRoZSBlc3RpbWF0ZWQgMiwyMjQgcGFzc2VuZ2VycyBhbGwgaGF2ZSB0aGVpciBvd24gc3RvcmllcyBvZiBlc2NhcGUgb3IgZGVhdGggaW4gdGhlIHdyZWNrLiBJdCBpcyBiZWxpZXZlZCwgaG93ZXZlciwgdGhhdCBzdHVkeWluZyB0aGUgdW5kZXJseWluZyBpbmZvcm1hdGlvbiBhYm91dCB0aGVzZSBwYXNzZW5nZXJzIGNhbiBwcm92aWRlIGluc2lnaHQgb24gd2h5IGNlcnRhaW4gcGVvcGxlIHN1cnZpdmVkLg0KDQojIERhdGEgU291cmNlDQoNClRoZSBkYXRhIHNldCB1c2VkIGluIHRoaXMgcmVwb3J0IGlzIHNvdXJjZWQgZnJvbSBLYWdnbGUuY29tLiBJdCB3YXMgb3JpZ25pYWxseSBjcmVhdGVkIGZvciBhIG1hY2hpbmUgbGVhcm5pbmcgY29tcGV0aXRpb24gaG9zdGVkIGJ5IEthZ2dsZS4gVGhlIGxpbmsgZm9yIHRoaXMgZGF0YSBzZXQgaXMgPGh0dHBzOi8vd3d3LmthZ2dsZS5jb20vYy90aXRhbmljPi4gVGhlIGRhdGEgaXMgb3JpZ2luYWxseSBzcGxpdCBpbnRvIHNlcGVyYXRlIHRyYWluIGFuZCB0ZXN0aW5nIGRhdGEgc2V0cyBmb3IgcHVycG9zZXMgb2YgdGhlIGNvbXBldGl0aW9uLiBUaGUgdHJhaW4gZGF0YSBpcyB1c2VkIGluIHRoaXMgcmVwb3J0IGZvciBtb3JlIG9ic2VydmF0aW9ucyBhbmQgdGhlIGNvbXBsZXRlIHNldCBvZiB2YXJpYWJsZXMuDQoNClRoZSBkYXRhIHdhcyB1cGxvYWRlZCB0byBhIEdpdEh1YiByZXBvc2l0b3J5IGZvciBwZXJwZXR1YWwgb25saW5lIGFjY2Vzcy4gVGhpcyByZXBvcnQgd2lsbCBzb3VyY2UgdGhlIGRhdGEgZnJvbSB0aGlzIHJlcG9zaXRvcnkgKFVSTCwgPGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uY2JyZWNoYmlsbC9TVEEzMjEvcmVmcy9oZWFkcy9tYWluL1NUQTMyMS90aXRhbmljLmNzdj4pDQoNClRoaXMgZGF0YSBjb250YWlucyA4OTEgb2JzZXJ2YXRpb25zIG9uIDEyIHZhcmlhYmxlcy4gQW55IG9ic2VydmF0aW9ucyBvZiBOL0EgaW4gdmFyaWFibGVzIG9mIGludGVyZXN0IHdpbGwgYmUgcmVtb3ZlZC4gVGhlIHZhcmlhYmxlcyBhcmU6DQoNCjEuICAqKlBhc3NlbmdlcklEKio6IEEgdW5pcXVlIGlkZW50aWZpZXINCjIuICAqKlN1cnZpdmVkKio6IFRoZSBzdXJ2aXZhbCBzdGF0dXMgb2YgdGhlIHBhc3NlbmdlciAoMCA9IE5vLCAxID0gWWVzKQ0KMy4gICoqUGNsYXNzKio6IFRoZSBwYXNzZW5nZXIncyB0aWNrZXQgY2xhc3MgKDFzdCwgMm5kLCBvciAzcmQpDQo0LiAgKipOYW1lKio6IFRoZSBwYXNzZW5nZXIncyBuYW1lDQo1LiAgKipTZXgqKjogVGhlIHBhc3NlbmdlcidzIHNleA0KNi4gICoqQWdlKio6IFRoZSBwYXNzZW5nZXIncyBhZ2UgaW4geWVhcnMNCjcuICAqKnNpYlNwKio6IE51bWJlciBvZiBzaWJsaW5ncy9zcG91c2UgYWJvYXJkDQo4LiAgKipQYXJjaCoqOiBOdW1iZXIgb2YgcGFyZW50cy9jaGlsZHJlbiBhYm9hcmQNCjkuICAqKlRpY2tldCoqOiBQYXNzZW5nZXIncyB0aWNrZXQgbnVtYmVyDQoxMC4gKipGYXJlKio6IFBhc3NlbmdlcidzIGJvYXJkaW5nIGZhcmUgaW4gVVNEDQoxMS4gKipDYWJpbioqOiBUaGUgcGFzc2VuZ2VyJ3MgY2FiaW4NCjEyLiAqKkVtYmFya2VkKio6IExvY2F0aW9uIHdoaWNoIHBhc3NlbmdlciBlbWJhcmtlZCAoQyA9IENoZXJib3VyZywgUSA9IFF1ZWVuc3Rvd24sIFMgPSBTb3V0aGFtcHRvbikNCg0KYGBge3IgZGF0YSBsb2FkaW5nfQ0KdXJsID0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9uY2JyZWNoYmlsbC9TVEEzMjEvcmVmcy9oZWFkcy9tYWluL1NUQTMyMS90aXRhbmljLmNzdiINCnRpdGFuaWMgPC0gcmVhZC5jc3YodXJsKQ0KZGF0YSA8LSBuYS5vbWl0KGRwbHlyOjpzZWxlY3QodGl0YW5pYywgU3Vydml2ZWQsIFBjbGFzcywgQWdlLCBTZXgsIFNpYlNwLCBQYXJjaCwgRmFyZSkpDQpkYXRhJFBjbGFzcyA8LSBhcy5mYWN0b3IoZGF0YSRQY2xhc3MpDQpgYGANCg0KIyBSZXNlYXJjaCBRdWVzdGlvbg0KDQpUaGlzIHJlcG9ydCBpbnZlc3RpZ2F0ZXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGEgcGFzc2VuZ2Vy4oCZcyBhZ2UsIHRpY2tldCBjbGFzcywgYW5kIHNleCB3aXRoIHRoZWlyIGxpa2VsaWhvb2Qgb2Ygc3Vydml2YWwgb24gdGhlIFRpdGFuaWMuIFRvIGFkZHJlc3MgdGhpcywgYSBtdWx0aXBsZSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIGlzIGFwcGxpZWQsIHdpdGggc3Vydml2YWwgKHN1cnZpdmVkIHZzLiBub3Qgc3Vydml2ZWQpIGFzIHRoZSBiaW5hcnkgb3V0Y29tZSB2YXJpYWJsZSBhbmQgcGFzc2VuZ2VyIGFnZSwgc2V4LCBhbmQgdGlja2V0IGNsYXNzIGFzIHRoZSBwcmVkaWN0b3JzLiBUaGlzIGFwcHJvYWNoIGFsbG93cyB1cyB0byBldmFsdWF0ZSB3aGV0aGVyIHRoZXNlIGZhY3RvcnMgc2lnbmlmaWNhbnRseSBhZmZlY3RlZCBzdXJ2aXZhbCBvZGRzLCBlc3RpbWF0ZSB0aGUgZGlyZWN0aW9uIGFuZCBtYWduaXR1ZGUgb2YgdGhlIGVmZmVjdHMsIGFuZCBhc3Nlc3MgdGhlIG1vZGVs4oCZcyBhYmlsaXR5IHRvIGV4cGxhaW4gdmFyaWF0aW9uIGluIHN1cnZpdmFsIG91dGNvbWVzLg0KDQojIEV4cGxvcmF0b3J5IERhdGEgQW5hbHlzaXMNCg0KQWxsIG9ic2VydmF0aW9ucyB3aXRoIG1pc3NpbmcgdmFsdWVzIGluIGFueSBvZiB0aGUgdmFyaWFibGVzIHdlcmUgcmVtb3ZlZC4gVGhpcyBsZWF2ZXMgNzE0IG9ic2VydmF0aW9ucy4gVGhlaXIgZGlzdHJpYnV0aW9ucyBhbmQgcG90ZW50aWFsIGNvcnJlbGF0aW9ucyBhcmUgcHJvdmlkZWQgaW4gdGhlIGZpZ3VyZSBiZWxvdy4NCg0KYGBge3J9DQpwYWlycy5wYW5lbHMoZGF0YVssLTldLCANCiAgICAgICAgICAgICBtZXRob2QgPSAicGVhcnNvbiIsICMgY29ycmVsYXRpb24gbWV0aG9kDQogICAgICAgICAgICAgaGlzdC5jb2wgPSAicm95YWxibHVlIiwNCiAgICAgICAgICAgICBkZW5zaXR5ID0gVFJVRSwgICMgc2hvdyBkZW5zaXR5IHBsb3RzDQogICAgICAgICAgICAgZWxsaXBzZXMgPSBUUlVFICMgc2hvdyBjb3JyZWxhdGlvbiBlbGxpcHNlcw0KICAgICAgICAgICAgICkNCmBgYA0KDQpXZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIG1vcmUgZGVhdGhzIHRoYW4gc3Vydml2YWxzLCBtb3JlIGhpZ2ggY2xhc3MgcGFzc2VuZ2VycyB0aGFuIG1pZGRsZSBvciBsb3csIGFuZCBtb3JlIG1lbiB0aGFuIHdvbWVuLiBBZ2UgaXMgc2xpZ2h0bHkgc2tld2VkIHJpZ2h0LCBidXQgbm8gdHJhbnNmb3JtYXRpb24gd2lsbCBiZSBhcHBsaWVkLiBTaWJTUCwgUGFyY2gsIGFuZCBGYXJlIGFyZSBoaWdobHkgc2tld2VkLiBQYXNzZW5nZXJJRCwgTmFtZSwgVGlja2V0LCBDYWJpbiwgYW5kIEVtYmFya2VkIHdlcmUgbm90IGluY2x1ZGVkIGZvciBpcnJlbGV2YW5jZS4NCg0KIyBNdWx0aXBsZSBMb2dpc3RpYyBSZWdyZXNzaW9uDQoNClRoZSB2YXJpYWJsZXMgc2V4LCBBZ2UsIGFuZCBQY2xhc3Mgd2lsbCBiZSB1c2VkIGZvciBsb2dpc3RpYyByZWdyZXNzaW9uLiBGYXJlIHdhcyBub3Qgc2VsZWN0ZWQgYmVjYXVzZSBpdCBpcyBhbHJlYWR5IGNhdGVnb3JpemVkIGJ5IFBjbGFzcy4gUGFyY2ggYW5kIFNpYlNwIHdlcmUgbm90IHNlbGVjdGVkIGJlY2F1c2Ugb2YgYSBmZXcgY29uZm91bmRpbmcgZmFjdG9ycy4gRm9yIGV4YW1wbGUgYSBwYXNzZW5nZXIgY291bGQgaGF2ZSBhdCBtb3N0IDIgcGFyZW50cyBhYm9hcmQsIGJ1dCBhbnkgcmVhbGlzdGljYWxseSBwb3NzaWJsZSBhbW91bnQgb2YgY2hpbGRyZW4gY291bGQgYmUgYWJvYXJkIHdpdGggYSBwYXJlbnQuIFNpbWlsYXJseSwgYSBwYXNzZW5nZXIgY2FuIGhhdmUgYXQgbW9zdCBvbmUgc3BvdXNlLCBidXQgYW55IG51bWJlciBvZiBzaWJsaW5ncyBhYm9hcmQuIFRoZXNlIHZhcmlhYmxlcyBjYW4gbGVhZCB0byBhbnkgbnVtYmVyIG9mIGludGVycHJldGF0aW9ucyBhbmQgdGhlaXIgaW5mbHVlbmNlIG9uIGEgbW9kZWwgd291bGQgYmUgb2JzY3VyZWQgYnkgdGhlc2UgbnVtZXJvdXMgcG9zc2liaWxpdGllcy4NCg0KIyMgRnVsbCBNb2RlbA0KDQpUaGUgZmlyc3QgbW9kZWwgY29udGFpbnMgYWxsIHRocmVlIGZhY3RvcnMuDQoNCmBgYHtyfQ0KZnVsbC5tb2RlbCA8LSBnbG0oU3Vydml2ZWQgfg0KICAgICAgICAgICAgICAgICAgICBQY2xhc3MrQWdlK1NleCwNCiAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAibG9naXQiKSwNCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhKQ0KcGFuZGVyKHN1bW1hcnkoZnVsbC5tb2RlbCkkY29lZiwNCiAgICAgICBjYXB0aW9uPSJTdW1tYXJ5IG9mIGluZmVyZW50aWFsIHN0YXRpc3RpY3Mgb2YgdGhlIGZ1bGwgbW9kZWwiKQ0KYGBgDQoNCkFsbCB2YWx1ZXMgd2VyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBCZWZvcmUgY3JlYXRpbmcgYSByZWR1Y2VkIG1vZGVsLCB3ZSBleHBsb3JlIHBvdGVudGlhbCBtdWx0aWNvbGxpbmVhcml0eSBhbW9uZyB0aGUgcHJlZGljdG9yIHZhcmlhYmxlcy4gVGhlIGZvbGxvd2luZyB0YWJsZSBzaG93cyB0aGUgVklGIGZvciBlYWNoIGluZGl2aWR1YWwgdmFyaWFibGUuDQoNCmBgYHtyfQ0KcGFuZGVyKHZpZihmdWxsLm1vZGVsKSkNCmBgYA0KDQpBbGwgR1ZJRiB2YWx1ZXMgYXJlIHVuZGVyIDEuNS4gVGhpcyBzdWdnZXN0cyBubyBtdWx0aWNvbGxpbmVhcml0eSBpc3N1ZXMgYmV0d2VlbiB0aGVzZSB2YXJpYWJsZXMuDQoNCiMjIFJlZHVjZWQgTW9kZWwNCg0KVGhlIHJlZHVjZWQgbW9kZWwgd2FzIGNvbnN0cnVjdGVkIG9uIHRoZSB2YXJpYWJsZSBzZXgsIGRldGVybWluZWQgYnkgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50cyBkZXRlcm1pbmVkIG9uIHRoZSByZXNwb25zZSB2YXJpYWJsZSBkdXJpbmcgRURBLiBUaGUgY29lZmZpY2llbnQgcmVtYWlucyBzaW1pbGFyIGZvciB0aGUgc2V4IHZhcmlhYmxlLCBhbmQgaW4gdGhlIHNhbWUgZGlyZWN0aW9uIChuZWdhdGl2ZSB0b3dhcmRzIG1hbGUpLg0KDQpgYGB7cn0NCnJlZHVjZWQubW9kZWwgPC0gZ2xtKFN1cnZpdmVkfg0KICAgICAgICAgICAgICAgICAgICAgICBTZXgsDQogICAgICAgICAgICAgICAgICAgICBmYW1pbHkgPSBiaW5vbWlhbChsaW5rID0gImxvZ2l0IiksDQogICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSkNCnBhbmRlcihzdW1tYXJ5KHJlZHVjZWQubW9kZWwpJGNvZWYpDQpgYGANCg0KIyMgQXV0b21hdGljIE1vZGVsIFNlbGVjdGlvbg0KDQpUaGUgcmVkdWNlZCBtb2RlbCBtYXkgdXNlIGluc3VmZmljaWVudCBpbmZvcm1hdGlvbiwgcmVzdWx0aW5nIGluIHVuZGVyZml0dGluZyAobWlzc2luZyBpbXBvcnRhbnQgZWZmZWN0cyksIHdoaWxlIHRoZSBmdWxsIG1vZGVsIGNhbiBsZWFkIHRvIG92ZXJmaXR0aW5nIChtb2RlbGluZyBub2lzZSBhbmQgZmFpbGluZyB0byBnZW5lcmFsaXplKS4gVG8gYWRkcmVzcyB0aGlzLCB3ZSB1c2UgYXV0b21hdGljIHZhcmlhYmxlIHNlbGVjdGlvbiB0byBmaW5kIGEgc2ltcGxlciwgbW9yZSBpbnRlcnByZXRhYmxlLCBhbmQgYmV0dGVyLXBlcmZvcm1pbmcgbW9kZWwgYnkgaW50ZWxsaWdlbnRseSBjaG9vc2luZyBhIHN1YnNldCBvZiBwcmVkaWN0b3JzIHRoYXQgaW5jbHVkZXMgdGhlIGltcG9ydGFudCB2YXJpYWJsZXMgZnJvbSB0aGUgcmVkdWNlZCBtb2RlbCB3aGlsZSBhdm9pZGluZyB0aGUgbm9pc2Ugb2YgdGhlIGZ1bGwgbW9kZWwuDQoNCmBgYHtyfQ0KZmluYWwubW9kZWwuZm9yd2FyZCA9IHN0ZXBBSUMocmVkdWNlZC5tb2RlbCwgDQogICAgICAgICAgICAgICAgICAgICAgc2NvcGUgPSBsaXN0KGxvd2VyPWZvcm11bGEocmVkdWNlZC5tb2RlbCksdXBwZXI9Zm9ybXVsYShmdWxsLm1vZGVsKSksDQogICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gImZvcndhcmQiLCAgICMgZm9yd2FyZCBzZWxlY3Rpb24NCiAgICAgICAgICAgICAgICAgICAgICB0cmFjZSA9IDAgICAjIGRvIG5vdCBzaG93IHRoZSBkZXRhaWxzDQogICAgICAgICAgICAgICAgICAgICAgKQ0KcGFuZGVyKHN1bW1hcnkoZmluYWwubW9kZWwuZm9yd2FyZCkkY29lZiwgDQogICAgICBjYXB0aW9uPSJTdW1tYXJ5IG9mIGluZmVyZW50aWFsIHN0YXRpc3RpY3Mgb2YgdGhlIGZpbmFsIG1vZGVsIikNCmBgYA0KDQojIyBQZXJmb3JtYW5jZSBDb21wYXJpc29uDQoNClRoZSBmdWxsIG1vZGVsIHdhcyBhdXRvbWF0aWNhbGx5IHNlbGVjdGVkLiBUaHVzLCB0aGVpciBkZXZpYW5jZSBpcyB0aGUgc2FtZS4gV2l0aCB0aGUgZnVsbCBtb2RlbCB1dGlsaXppbmcgb25seSB0aHJlZSBwcmVkaWN0b3JzLCB0aGUgbW9kZWwgcmVtYWlucyByZWxhdGl2ZWx5IHNpbXBsZSBhbmQgcGFyc2ltb25pb3VzLg0KDQpgYGB7cn0NCiMjIE90aGVyIGdsb2JhbCBnb29kbmVzcy1vZi1maXQNCmdsb2JhbC5tZWFzdXJlPWZ1bmN0aW9uKHMubG9naXQpew0KZGV2LnJlc2lkID0gcy5sb2dpdCRkZXZpYW5jZQ0KZGV2LjAucmVzaWQgPSBzLmxvZ2l0JG51bGwuZGV2aWFuY2UNCmFpYyA9IHMubG9naXQkYWljDQpnb29kbmVzcyA9IGNiaW5kKERldmlhbmNlLnJlc2lkdWFsID1kZXYucmVzaWQsIE51bGwuRGV2aWFuY2UuUmVzaWR1YWwgPSBkZXYuMC5yZXNpZCwNCiAgICAgIEFJQyA9IGFpYykNCmdvb2RuZXNzDQp9DQpnb29kbmVzcz1yYmluZChmdWxsLm1vZGVsID0gZ2xvYmFsLm1lYXN1cmUoZnVsbC5tb2RlbCksDQogICAgICByZWR1Y2VkLm1vZGVsPWdsb2JhbC5tZWFzdXJlKHJlZHVjZWQubW9kZWwpLA0KICAgICAgZmluYWwubW9kZWw9Z2xvYmFsLm1lYXN1cmUoZmluYWwubW9kZWwuZm9yd2FyZCkpDQpyb3cubmFtZXMoZ29vZG5lc3MpID0gYygiZnVsbC5tb2RlbCIsICJyZWR1Y2VkLm1vZGVsIiwgImF1dG8uc2VsZWN0ZWQubW9kZWwiKQ0KcGFuZGVyKGdvb2RuZXNzLCBjYXB0aW9uID0iQ29tcGFyaXNvbiBvZiBnbG9iYWwgZ29vZG5lc3Mtb2YtZml0IHN0YXRpc3RpY3MiKQ0KYGBgDQoNCiMgRmluYWwgTW9kZWwNCg0KVGhlIGZpbmFsIG1vZGVsIGlzIHRyYW5zbGF0ZWQgaW50byBhbiBvZGRzIHJhdGlvIGZvciBpbnRlcnByZXRhdGlvbi4gU3RhcnRpbmcgYXQgYSBiYXNlbGluZSA0My42OSBPZGRzIHJhdGlvIG9mIHN1cnZpdmFsLCB0aGUgcmF0aW8gd2FzIHJlZHVjZWQgYnkgYSBwYXNzZW5nZXIgYmVpbmcgbWFsZSBhbmQgaGF2aW5nIGEgMm5kIG9yIDNyZCBjbGFzcyB0aWNrZXQuIEV2ZXJ5IHllYXIgb2YgYWdlIGFsc28gcmVkdWNlZCBzdXJ2aXZhbCBvZGRzLg0KDQpgYGB7cn0NCiMgT2RkcyByYXRpbw0KbW9kZWwuY29lZi5zdGF0cyA9IHN1bW1hcnkoZmluYWwubW9kZWwuZm9yd2FyZCkkY29lZg0Kb2Rkcy5yYXRpbyA9IGV4cChjb2VmKGZpbmFsLm1vZGVsLmZvcndhcmQpKQ0Kb3V0LnN0YXRzID0gY2JpbmQobW9kZWwuY29lZi5zdGF0cywgb2Rkcy5yYXRpbyA9IG9kZHMucmF0aW8pICAgICAgICAgICAgICAgICANCnBhbmRlcihvdXQuc3RhdHMsY2FwdGlvbiA9ICJTdW1tYXJ5IFN0YXRzIHdpdGggT2RkcyBSYXRpb3MiKQ0KYGBgDQoNCiMgQW5hbHlzaXMNCg0KVGhlIGZpbmFsIG1vZGVsIGFsbG93cyB1cyB0byBhbmFseXplIHRoZSBkZW1vZ3JhcGhpY3MgdGhhdCBhc3NvY2lhdGUgd2l0aCBzdXJ2aXZhbCB0aGUgbW9zdC4gT2YgdGhlIHBhc3NlbmdlcnMgYW5hbHl6ZWQsIHRoZSB5b3VuZ2VyIDFzdCBjbGFzcyB3b21lbiBoYWQgdGhlIGJlc3Qgb2RkcyBvZiBzdXJ2aXZhbC4gT2xkZXIgM3JkIGNsYXNzIG1lbiBoYWQgdGhlIHdvcnN0IG9kZHMgb2Ygc3Vydml2YWwuIFRoaXMgcHJvdmlkZXMgaW5zaWdodHMgaW50byB3aGF0IHRoZSBwYXNzZW5nZXJzIGZvdW5kIG1vc3QgaW1wb3J0YW50IGludG8gZmFjdG9yaW5nIHdobydzIHN1cnZpdmFsIHdhcyBwcmlvcml0aXplZC4NCg0KQSBwb3B1bGFyIGV4Y2VycHQgZnJvbSB0aGUgVGl0YW5pYydzIHdyZWNrIHdhcyAid29tZW4gYW5kIGNoaWxkcmVuIGZpcnN0Ii4gQXQgYSBnbGFuY2UsIHRoZSBkYXRhIHN1cHBvcnRzIHRoaXMsIGFzIGJvdGggd29tZW4gYW5kIHlvdW5nZXIgcGFzc2VuZ2VyJ3MgaGFkIGJldHRlciBvZGRzIG9mIHN1cnZpdmFsLiBBZGRpdGlvbmFsbHksIHdlIGNhbiBzZWUgdGhhdCBoaWdoZXIgY2xhc3MgcGFzc2VuZ2VycyBoYWQgaGlnaGVyIG9kZHMgb2Ygc3Vydml2YWwuIE9uZSBjYW4gc3VybWlzZSB0aGF0IHRoaXMgbmFycmF0aXZlIHdvdWxkIGJlIGxlc3MgcG9wdWxhciB0aGFuIHRoZSByZWxhdGl2ZWx5IGhlcm9pYyAid29tZW4gYW5kIGNoaWxkcmVuIGZpcnN0IiByaGV0b3JpYy4gSW4gc2V2ZXJhbCBpbnN0YW5jZXMsIHdlYWx0aCBoZWxwcyBwZW9wbGUgc3Vydml2ZSwgYW5kIGl0IHNlZW1zIHRoZSB3cmVjayBvZiB0aGUgdGl0YW5pYyB3YXMgbm8gZXhjZXB0aW9uLg0KDQpUaGlzIG1vZGVsIHdpbGwgYmUgdHdlYWtlZCBmb3IgcHJlZGljdGlvbiBpbiBhIGxhdGVyIHJlcG9ydC4NCg==