. Purpose of the
Quiz
This Quiz 4 focuses on logistic regression: building
a model, interpreting results, and giving managerial
recommendations.
We will follow these steps:
- Step 1 — Model construction: Define a binary
outcome (Subscribe: Yes=1) and choose two predictors
(Age, Gender).
- Step 2 — Interpretation: Interpret coefficients
using odds ratios and predicted
probabilities.
- Step 3 — Managerial recommendations: Translate
results into clear business actions.
- Step 4 — Value add: A simple predicted probability
plot and example profiles.
Important note: The goal is not advanced coding.
The goal is correct interpretation and manager-friendly insights.
. Load Libraries &
Read Data
# ==========================================================
# 2.1 Libraries
# - readxl: to read Excel
# - dplyr: data manipulation
# - ggplot2: visualization
# - broom: tidy model output into clean tables
# - tidyr: reshape data for plotting
# ==========================================================
library(readxl)
library(dplyr)
library(ggplot2)
library(broom)
library(tidyr)
# ==========================================================
# 2.2 Read Excel Data
# - We read the sheet named "data"
# ==========================================================
df_raw <- read_excel("Logitsubscribedata.xlsx", sheet = "data")
# Quick look at structure and first rows
str(df_raw)
## tibble [1,345 × 3] (S3: tbl_df/tbl/data.frame)
## $ Age : num [1:1345] 33 45 57 32 56 60 40 55 27 48 ...
## $ Gender (W=1) : num [1:1345] 0 1 0 1 0 1 0 0 0 1 ...
## $ Subscribe? (Yes=1): num [1:1345] 0 0 0 0 0 1 0 0 0 0 ...
## # A tibble: 6 × 3
## Age `Gender (W=1)` `Subscribe? (Yes=1)`
## <dbl> <dbl> <dbl>
## 1 33 0 0
## 2 45 1 0
## 3 57 0 0
## 4 32 1 0
## 5 56 0 0
## 6 60 1 1
Interpretation (Data check):
We confirm we have 3 columns: Age, Gender
(W=1), and Subscribe (Yes=1).
This is a binary classification problem because
Subscribe is 0/1.
. Data Preparation
(Clean names + types)
# ==========================================================
# 3.1 Rename columns to simpler names
# - gender_w: 1 if Woman, 0 if Man (based on the column name)
# - subscribe: 1 if Yes, 0 if No
# ==========================================================
df <- df_raw %>%
rename(
gender_w = `Gender (W=1)`,
subscribe = `Subscribe? (Yes=1)`
)
# ==========================================================
# 3.2 Ensure correct data types
# - Logistic regression expects the outcome as 0/1 numeric
# ==========================================================
df <- df %>%
mutate(
gender_w = as.integer(gender_w),
subscribe = as.integer(subscribe),
Age = as.numeric(Age)
)
# Confirm again
str(df)
## tibble [1,345 × 3] (S3: tbl_df/tbl/data.frame)
## $ Age : num [1:1345] 33 45 57 32 56 60 40 55 27 48 ...
## $ gender_w : int [1:1345] 0 1 0 1 0 1 0 0 0 1 ...
## $ subscribe: int [1:1345] 0 0 0 0 0 1 0 0 0 0 ...
## Age gender_w subscribe
## Min. :20.00 Min. :0.0000 Min. :0.0000
## 1st Qu.:29.00 1st Qu.:0.0000 1st Qu.:0.0000
## Median :40.00 Median :1.0000 Median :0.0000
## Mean :39.65 Mean :0.5078 Mean :0.2379
## 3rd Qu.:50.00 3rd Qu.:1.0000 3rd Qu.:0.0000
## Max. :60.00 Max. :1.0000 Max. :1.0000
Interpretation (Cleaning):
We renamed columns for easier coding and ensured Age is numeric and the
binary variables are integers (0/1).
This helps avoid common R issues (e.g., numbers read as text).
. Quick Descriptive
Statistics
# ==========================================================
# 4.1 Outcome distribution: how many subscribed vs not
# ==========================================================
table(df$subscribe)
##
## 0 1
## 1025 320
# ==========================================================
# 4.2 Age summary
# ==========================================================
summary(df$Age)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 20.00 29.00 40.00 39.65 50.00 60.00
# ==========================================================
# 4.3 Gender distribution
# ==========================================================
table(df$gender_w)
##
## 0 1
## 662 683
# Subscription rate (mean of 0/1)
mean(df$subscribe)
## [1] 0.2379182
Interpretation (Descriptives):
- The dataset has 1,345 observations.
- The subscription rate is about 24% (mean of
0/1).
- Age ranges from 20 to 60 (median around
40).
- Gender is balanced (similar counts for men vs women).
These statistics provide context before modeling.
. Step 1 — Logistic
Regression Model
We model subscription likelihood using two predictors:
- Age (continuous)
- Gender (Woman=1)
Logistic regression is appropriate because the outcome is binary
(0/1).
# ==========================================================
# 5.1 Logistic regression model
# glm(..., family = binomial) fits a logistic regression
#
# Model form:
# log(odds(subscribe)) = b0 + b1*Age + b2*gender_w
# ==========================================================
m1 <- glm(subscribe ~ Age + gender_w, data = df, family = binomial)
# Main model output
summary(m1)
##
## Call:
## glm(formula = subscribe ~ Age + gender_w, family = binomial,
## data = df)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.597628 0.230870 2.589 0.00964 **
## Age -0.052399 0.005895 -8.888 < 2e-16 ***
## gender_w 0.407014 0.133725 3.044 0.00234 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 1475.9 on 1344 degrees of freedom
## Residual deviance: 1381.1 on 1342 degrees of freedom
## AIC: 1387.1
##
## Number of Fisher Scoring iterations: 4
Interpretation (Model output – high level):
- Check the sign of coefficients
(positive/negative).
- Check p-values to see which predictors are
statistically significant.
From the output:
- Age coefficient is negative and highly
significant → older customers are less likely to
subscribe.
- Gender (Woman=1) coefficient is positive and
significant → women are more likely to subscribe.
. Step 2 — Odds
Ratios
Logistic coefficients are in log-odds. To interpret
in a simpler way, we convert them to odds ratios
(OR):
- OR > 1 → increases odds of subscribing
- OR < 1 → decreases odds of subscribing
# ==========================================================
# 6.1 Odds Ratios + Confidence Intervals
# exponentiate = TRUE means exp(coef) -> odds ratio
# ==========================================================
or_table <- tidy(m1, conf.int = TRUE, exponentiate = TRUE)
or_table
## # A tibble: 3 × 7
## term estimate std.error statistic p.value conf.low conf.high
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 (Intercept) 1.82 0.231 2.59 9.64e- 3 1.16 2.86
## 2 Age 0.949 0.00590 -8.89 6.22e-19 0.938 0.960
## 3 gender_w 1.50 0.134 3.04 2.34e- 3 1.16 1.95
Interpretation (Odds ratios):
- Age OR ≈ 0.95: each additional year decreases the
odds of subscribing by about 5% (1 - 0.95).
- Gender (Woman) OR ≈ 1.50: women have about
50% higher odds of subscribing than men.
Both predictors are statistically significant (small p-values).
. Predicted
Probabilities
Managers understand probabilities better than odds. We compute
predicted probabilities for example profiles:
- Ages: 25, 45, 65
- Gender: Man (0) vs Woman (1)
# ==========================================================
# 7.1 Example profiles
# predict(..., type="response") returns predicted probability (0-1)
# ==========================================================
profiles <- data.frame(
Age = c(25, 25, 45, 45, 65, 65),
gender_w = c(0, 1, 0, 1, 0, 1)
)
profiles$pred_prob <- predict(m1, newdata = profiles, type = "response")
profiles
## Age gender_w pred_prob
## 1 25 0 0.32908212
## 2 25 1 0.42425609
## 3 45 0 0.14675107
## 4 45 1 0.20533140
## 5 65 0 0.05687796
## 6 65 1 0.08307560
Interpretation (Predicted probabilities):
- Younger customers have much higher predicted subscription
probability.
- At every age, women have higher probability than men.
Example (from our output):
- Age 25: ~0.33 (men) vs ~0.42 (women)
- Age 45: ~0.15 (men) vs ~0.21 (women)
- Age 65: ~0.06 (men) vs ~0.08 (women)
. Visualization
We create a smooth probability curve by age for men vs women.
# ==========================================================
# 8.1 Create an age grid for predictions
# ==========================================================
age_grid_m <- data.frame(
Age = seq(min(df$Age), max(df$Age), by = 1),
gender_w = 0
)
age_grid_m$pred_prob <- predict(m1, newdata = age_grid_m, type = "response")
age_grid_m$Group <- "Men"
age_grid_w <- data.frame(
Age = seq(min(df$Age), max(df$Age), by = 1),
gender_w = 1
)
age_grid_w$pred_prob <- predict(m1, newdata = age_grid_w, type = "response")
age_grid_w$Group <- "Women"
plot_df <- bind_rows(age_grid_m, age_grid_w)
# ==========================================================
# 8.2 Plot
# ==========================================================
ggplot(plot_df, aes(x = Age, y = pred_prob, linetype = Group)) +
geom_line(linewidth = 1) +
labs(
title = "Predicted Subscription Probability by Age and Gender",
x = "Age",
y = "Predicted probability of subscribing",
linetype = "Group"
) +
theme_minimal()

Interpretation (Plot):
- The curve decreases with age → subscription probability decreases as
customers get older.
- The women curve is above the men curve → women are more likely to
subscribe at each age.
. Step 3 — Managerial
Recommendations
Based on the model:
- Focus acquisition campaigns on younger
customers
- Age is the strongest driver. Younger customers have the highest
conversion potential.
- Women are a higher-likelihood segment
- Women have ~50% higher odds of subscribing than men (OR ≈
1.50).
- Use channels and messaging that perform well for this segment.
- Improve conversion for older customers with targeted
actions
- For older customers, test clearer value communication, simpler
onboarding, and tailored offers.
Manager-friendly conclusion:
Age significantly reduces subscription likelihood, while being female
increases it. Therefore, marketing should prioritize younger segments
(especially women) for acquisition, and develop specific strategies to
improve conversion among older customers.
. Limitations
- We used only two predictors (as required by the
quiz). Real-world models may need more variables.
- This model shows association, not guaranteed
causation.
- We did not test interactions (e.g., Age × Gender). This can be
explored if required.
LS0tCnRpdGxlOiAiTWlNODExIFRIIFF1aXogNCDigJMgTG9naXN0aWMgUmVncmVzc2lvbiIKYXV0aG9yOiAiR8O8bMWfYWggw4dhbMSxxZ9rYW4iCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogZmxhdGx5CiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzCiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEdsb2JhbCBvcHRpb25zIGZvciBjbGVhbiBIVE1MCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBUUlVFLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UKKQpgYGAKCiMgLiBQdXJwb3NlIG9mIHRoZSBRdWl6CgpUaGlzIFF1aXogNCBmb2N1c2VzIG9uICoqbG9naXN0aWMgcmVncmVzc2lvbioqOiBidWlsZGluZyBhIG1vZGVsLCBpbnRlcnByZXRpbmcgcmVzdWx0cywgYW5kIGdpdmluZyAqKm1hbmFnZXJpYWwgcmVjb21tZW5kYXRpb25zKiouCgpXZSB3aWxsIGZvbGxvdyB0aGVzZSBzdGVwczoKCi0gKipTdGVwIDEg4oCUIE1vZGVsIGNvbnN0cnVjdGlvbjoqKiBEZWZpbmUgYSBiaW5hcnkgb3V0Y29tZSAoU3Vic2NyaWJlOiBZZXM9MSkgYW5kIGNob29zZSAqKnR3byBwcmVkaWN0b3JzKiogKEFnZSwgR2VuZGVyKS4KLSAqKlN0ZXAgMiDigJQgSW50ZXJwcmV0YXRpb246KiogSW50ZXJwcmV0IGNvZWZmaWNpZW50cyB1c2luZyAqKm9kZHMgcmF0aW9zKiogYW5kICoqcHJlZGljdGVkIHByb2JhYmlsaXRpZXMqKi4KLSAqKlN0ZXAgMyDigJQgTWFuYWdlcmlhbCByZWNvbW1lbmRhdGlvbnM6KiogVHJhbnNsYXRlIHJlc3VsdHMgaW50byBjbGVhciBidXNpbmVzcyBhY3Rpb25zLgotICoqU3RlcCA0IOKAlCBWYWx1ZSBhZGQ6KiogQSBzaW1wbGUgcHJlZGljdGVkIHByb2JhYmlsaXR5IHBsb3QgYW5kIGV4YW1wbGUgcHJvZmlsZXMuCgo+IEltcG9ydGFudCBub3RlOiBUaGUgZ29hbCBpcyBub3QgYWR2YW5jZWQgY29kaW5nLiAgCj4gVGhlIGdvYWwgaXMgY29ycmVjdCBpbnRlcnByZXRhdGlvbiBhbmQgbWFuYWdlci1mcmllbmRseSBpbnNpZ2h0cy4KCiMgLiBMb2FkIExpYnJhcmllcyAmIFJlYWQgRGF0YQoKYGBge3Igc3RlcDEtcmVhZC1kYXRhfQojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyAyLjEgTGlicmFyaWVzCiMgLSByZWFkeGw6IHRvIHJlYWQgRXhjZWwKIyAtIGRwbHlyOiBkYXRhIG1hbmlwdWxhdGlvbgojIC0gZ2dwbG90MjogdmlzdWFsaXphdGlvbgojIC0gYnJvb206IHRpZHkgbW9kZWwgb3V0cHV0IGludG8gY2xlYW4gdGFibGVzCiMgLSB0aWR5cjogcmVzaGFwZSBkYXRhIGZvciBwbG90dGluZwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkodGlkeXIpCgojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyAyLjIgUmVhZCBFeGNlbCBEYXRhCiMgLSBXZSByZWFkIHRoZSBzaGVldCBuYW1lZCAiZGF0YSIKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpkZl9yYXcgPC0gcmVhZF9leGNlbCgiTG9naXRzdWJzY3JpYmVkYXRhLnhsc3giLCBzaGVldCA9ICJkYXRhIikKCiMgUXVpY2sgbG9vayBhdCBzdHJ1Y3R1cmUgYW5kIGZpcnN0IHJvd3MKc3RyKGRmX3JhdykKaGVhZChkZl9yYXcpCmBgYAoKKipJbnRlcnByZXRhdGlvbiAoRGF0YSBjaGVjayk6KiogIApXZSBjb25maXJtIHdlIGhhdmUgMyBjb2x1bW5zOiAqKkFnZSoqLCAqKkdlbmRlciAoVz0xKSoqLCBhbmQgKipTdWJzY3JpYmUgKFllcz0xKSoqLiAgClRoaXMgaXMgYSBiaW5hcnkgY2xhc3NpZmljYXRpb24gcHJvYmxlbSBiZWNhdXNlICoqU3Vic2NyaWJlKiogaXMgMC8xLgoKIyAuIERhdGEgUHJlcGFyYXRpb24gKENsZWFuIG5hbWVzICsgdHlwZXMpCgpgYGB7ciBzdGVwMS1jbGVhbn0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgMy4xIFJlbmFtZSBjb2x1bW5zIHRvIHNpbXBsZXIgbmFtZXMKIyAtIGdlbmRlcl93OiAxIGlmIFdvbWFuLCAwIGlmIE1hbiAoYmFzZWQgb24gdGhlIGNvbHVtbiBuYW1lKQojIC0gc3Vic2NyaWJlOiAxIGlmIFllcywgMCBpZiBObwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmRmIDwtIGRmX3JhdyAlPiUKICByZW5hbWUoCiAgICBnZW5kZXJfdyAgPSBgR2VuZGVyIChXPTEpYCwKICAgIHN1YnNjcmliZSA9IGBTdWJzY3JpYmU/IChZZXM9MSlgCiAgKQoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgMy4yIEVuc3VyZSBjb3JyZWN0IGRhdGEgdHlwZXMKIyAtIExvZ2lzdGljIHJlZ3Jlc3Npb24gZXhwZWN0cyB0aGUgb3V0Y29tZSBhcyAwLzEgbnVtZXJpYwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmRmIDwtIGRmICU+JQogIG11dGF0ZSgKICAgIGdlbmRlcl93ICA9IGFzLmludGVnZXIoZ2VuZGVyX3cpLAogICAgc3Vic2NyaWJlID0gYXMuaW50ZWdlcihzdWJzY3JpYmUpLAogICAgQWdlICAgICAgID0gYXMubnVtZXJpYyhBZ2UpCiAgKQoKIyBDb25maXJtIGFnYWluCnN0cihkZikKc3VtbWFyeShkZikKYGBgCgoqKkludGVycHJldGF0aW9uIChDbGVhbmluZyk6KiogIApXZSByZW5hbWVkIGNvbHVtbnMgZm9yIGVhc2llciBjb2RpbmcgYW5kIGVuc3VyZWQgQWdlIGlzIG51bWVyaWMgYW5kIHRoZSBiaW5hcnkgdmFyaWFibGVzIGFyZSBpbnRlZ2VycyAoMC8xKS4gIApUaGlzIGhlbHBzIGF2b2lkIGNvbW1vbiBSIGlzc3VlcyAoZS5nLiwgbnVtYmVycyByZWFkIGFzIHRleHQpLgoKIyAuIFF1aWNrIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MKCmBgYHtyIHN0ZXAxLWRlc2NyaXB0aXZlc30KIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgNC4xIE91dGNvbWUgZGlzdHJpYnV0aW9uOiBob3cgbWFueSBzdWJzY3JpYmVkIHZzIG5vdAojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KdGFibGUoZGYkc3Vic2NyaWJlKQoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgNC4yIEFnZSBzdW1tYXJ5CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpzdW1tYXJ5KGRmJEFnZSkKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDQuMyBHZW5kZXIgZGlzdHJpYnV0aW9uCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQp0YWJsZShkZiRnZW5kZXJfdykKCiMgU3Vic2NyaXB0aW9uIHJhdGUgKG1lYW4gb2YgMC8xKQptZWFuKGRmJHN1YnNjcmliZSkKYGBgCgoqKkludGVycHJldGF0aW9uIChEZXNjcmlwdGl2ZXMpOioqICAKLSBUaGUgZGF0YXNldCBoYXMgKioxLDM0NSoqIG9ic2VydmF0aW9ucy4gIAotIFRoZSBzdWJzY3JpcHRpb24gcmF0ZSBpcyBhYm91dCAqKjI0JSoqIChtZWFuIG9mIDAvMSkuICAKLSBBZ2UgcmFuZ2VzIGZyb20gKioyMCB0byA2MCoqIChtZWRpYW4gYXJvdW5kICoqNDAqKikuICAKLSBHZW5kZXIgaXMgYmFsYW5jZWQgKHNpbWlsYXIgY291bnRzIGZvciBtZW4gdnMgd29tZW4pLiAgCgpUaGVzZSBzdGF0aXN0aWNzIHByb3ZpZGUgY29udGV4dCBiZWZvcmUgbW9kZWxpbmcuCgojIC4gU3RlcCAxIOKAlCBMb2dpc3RpYyBSZWdyZXNzaW9uIE1vZGVsCgpXZSBtb2RlbCBzdWJzY3JpcHRpb24gbGlrZWxpaG9vZCB1c2luZyB0d28gcHJlZGljdG9yczoKCi0gKipBZ2UqKiAoY29udGludW91cykKLSAqKkdlbmRlcioqIChXb21hbj0xKQoKTG9naXN0aWMgcmVncmVzc2lvbiBpcyBhcHByb3ByaWF0ZSBiZWNhdXNlIHRoZSBvdXRjb21lIGlzIGJpbmFyeSAoMC8xKS4KCmBgYHtyIHN0ZXAxLWxvZ2l0LW1vZGVsfQojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyA1LjEgTG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbAojIGdsbSguLi4sIGZhbWlseSA9IGJpbm9taWFsKSBmaXRzIGEgbG9naXN0aWMgcmVncmVzc2lvbgojCiMgTW9kZWwgZm9ybToKIyBsb2cob2RkcyhzdWJzY3JpYmUpKSA9IGIwICsgYjEqQWdlICsgYjIqZ2VuZGVyX3cKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgptMSA8LSBnbG0oc3Vic2NyaWJlIH4gQWdlICsgZ2VuZGVyX3csIGRhdGEgPSBkZiwgZmFtaWx5ID0gYmlub21pYWwpCgojIE1haW4gbW9kZWwgb3V0cHV0CnN1bW1hcnkobTEpCmBgYAoKKipJbnRlcnByZXRhdGlvbiAoTW9kZWwgb3V0cHV0IOKAkyBoaWdoIGxldmVsKToqKiAgCi0gQ2hlY2sgdGhlICoqc2lnbioqIG9mIGNvZWZmaWNpZW50cyAocG9zaXRpdmUvbmVnYXRpdmUpLiAgCi0gQ2hlY2sgKipwLXZhbHVlcyoqIHRvIHNlZSB3aGljaCBwcmVkaWN0b3JzIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LgoKRnJvbSB0aGUgb3V0cHV0OiAgCi0gKipBZ2UqKiBjb2VmZmljaWVudCBpcyAqKm5lZ2F0aXZlIGFuZCBoaWdobHkgc2lnbmlmaWNhbnQqKiDihpIgb2xkZXIgY3VzdG9tZXJzIGFyZSBsZXNzIGxpa2VseSB0byBzdWJzY3JpYmUuICAKLSAqKkdlbmRlciAoV29tYW49MSkqKiBjb2VmZmljaWVudCBpcyAqKnBvc2l0aXZlIGFuZCBzaWduaWZpY2FudCoqIOKGkiB3b21lbiBhcmUgbW9yZSBsaWtlbHkgdG8gc3Vic2NyaWJlLgoKIyAuIFN0ZXAgMiDigJQgT2RkcyBSYXRpb3MgCgpMb2dpc3RpYyBjb2VmZmljaWVudHMgYXJlIGluICoqbG9nLW9kZHMqKi4gVG8gaW50ZXJwcmV0IGluIGEgc2ltcGxlciB3YXksIHdlIGNvbnZlcnQgdGhlbSB0byAqKm9kZHMgcmF0aW9zIChPUikqKjoKCi0gT1IgPiAxIOKGkiBpbmNyZWFzZXMgb2RkcyBvZiBzdWJzY3JpYmluZyAgCi0gT1IgPCAxIOKGkiBkZWNyZWFzZXMgb2RkcyBvZiBzdWJzY3JpYmluZwoKYGBge3Igc3RlcDItb2Rkcy1yYXRpb3N9CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDYuMSBPZGRzIFJhdGlvcyArIENvbmZpZGVuY2UgSW50ZXJ2YWxzCiMgZXhwb25lbnRpYXRlID0gVFJVRSBtZWFucyBleHAoY29lZikgLT4gb2RkcyByYXRpbwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCm9yX3RhYmxlIDwtIHRpZHkobTEsIGNvbmYuaW50ID0gVFJVRSwgZXhwb25lbnRpYXRlID0gVFJVRSkKb3JfdGFibGUKYGBgCgoqKkludGVycHJldGF0aW9uIChPZGRzIHJhdGlvcyk6KiogIAotICoqQWdlIE9SIOKJiCAwLjk1OioqIGVhY2ggYWRkaXRpb25hbCB5ZWFyIGRlY3JlYXNlcyB0aGUgb2RkcyBvZiBzdWJzY3JpYmluZyBieSBhYm91dCAqKjUlKiogKDEgLSAwLjk1KS4gIAotICoqR2VuZGVyIChXb21hbikgT1Ig4omIIDEuNTA6Kiogd29tZW4gaGF2ZSBhYm91dCAqKjUwJSBoaWdoZXIgb2RkcyoqIG9mIHN1YnNjcmliaW5nIHRoYW4gbWVuLiAgCgpCb3RoIHByZWRpY3RvcnMgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHNtYWxsIHAtdmFsdWVzKS4KCiMgLiBQcmVkaWN0ZWQgUHJvYmFiaWxpdGllcyAKCk1hbmFnZXJzIHVuZGVyc3RhbmQgcHJvYmFiaWxpdGllcyBiZXR0ZXIgdGhhbiBvZGRzLiBXZSBjb21wdXRlIHByZWRpY3RlZCBwcm9iYWJpbGl0aWVzIGZvciBleGFtcGxlIHByb2ZpbGVzOgoKLSBBZ2VzOiAyNSwgNDUsIDY1ICAKLSBHZW5kZXI6IE1hbiAoMCkgdnMgV29tYW4gKDEpCgpgYGB7ciBzdGVwMi1wcmVkaWN0ZWQtcHJvZmlsZXN9CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDcuMSBFeGFtcGxlIHByb2ZpbGVzCiMgcHJlZGljdCguLi4sIHR5cGU9InJlc3BvbnNlIikgcmV0dXJucyBwcmVkaWN0ZWQgcHJvYmFiaWxpdHkgKDAtMSkKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Cgpwcm9maWxlcyA8LSBkYXRhLmZyYW1lKAogIEFnZSA9IGMoMjUsIDI1LCA0NSwgNDUsIDY1LCA2NSksCiAgZ2VuZGVyX3cgPSBjKDAsIDEsIDAsIDEsIDAsIDEpCikKCnByb2ZpbGVzJHByZWRfcHJvYiA8LSBwcmVkaWN0KG0xLCBuZXdkYXRhID0gcHJvZmlsZXMsIHR5cGUgPSAicmVzcG9uc2UiKQpwcm9maWxlcwpgYGAKCioqSW50ZXJwcmV0YXRpb24gKFByZWRpY3RlZCBwcm9iYWJpbGl0aWVzKToqKiAgCi0gWW91bmdlciBjdXN0b21lcnMgaGF2ZSBtdWNoIGhpZ2hlciBwcmVkaWN0ZWQgc3Vic2NyaXB0aW9uIHByb2JhYmlsaXR5LiAgCi0gQXQgZXZlcnkgYWdlLCB3b21lbiBoYXZlIGhpZ2hlciBwcm9iYWJpbGl0eSB0aGFuIG1lbi4gIAoKRXhhbXBsZSAoZnJvbSBvdXIgb3V0cHV0KTogIAotIEFnZSAyNTogfjAuMzMgKG1lbikgdnMgfjAuNDIgKHdvbWVuKSAgCi0gQWdlIDQ1OiB+MC4xNSAobWVuKSB2cyB+MC4yMSAod29tZW4pICAKLSBBZ2UgNjU6IH4wLjA2IChtZW4pIHZzIH4wLjA4ICh3b21lbikgIAoKIyAuIFZpc3VhbGl6YXRpb24KCldlIGNyZWF0ZSBhIHNtb290aCBwcm9iYWJpbGl0eSBjdXJ2ZSBieSBhZ2UgZm9yIG1lbiB2cyB3b21lbi4KCmBgYHtyIHN0ZXA0LXBsb3R9CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDguMSBDcmVhdGUgYW4gYWdlIGdyaWQgZm9yIHByZWRpY3Rpb25zCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKYWdlX2dyaWRfbSA8LSBkYXRhLmZyYW1lKAogIEFnZSA9IHNlcShtaW4oZGYkQWdlKSwgbWF4KGRmJEFnZSksIGJ5ID0gMSksCiAgZ2VuZGVyX3cgPSAwCikKYWdlX2dyaWRfbSRwcmVkX3Byb2IgPC0gcHJlZGljdChtMSwgbmV3ZGF0YSA9IGFnZV9ncmlkX20sIHR5cGUgPSAicmVzcG9uc2UiKQphZ2VfZ3JpZF9tJEdyb3VwIDwtICJNZW4iCgphZ2VfZ3JpZF93IDwtIGRhdGEuZnJhbWUoCiAgQWdlID0gc2VxKG1pbihkZiRBZ2UpLCBtYXgoZGYkQWdlKSwgYnkgPSAxKSwKICBnZW5kZXJfdyA9IDEKKQphZ2VfZ3JpZF93JHByZWRfcHJvYiA8LSBwcmVkaWN0KG0xLCBuZXdkYXRhID0gYWdlX2dyaWRfdywgdHlwZSA9ICJyZXNwb25zZSIpCmFnZV9ncmlkX3ckR3JvdXAgPC0gIldvbWVuIgoKcGxvdF9kZiA8LSBiaW5kX3Jvd3MoYWdlX2dyaWRfbSwgYWdlX2dyaWRfdykKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIDguMiBQbG90CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKZ2dwbG90KHBsb3RfZGYsIGFlcyh4ID0gQWdlLCB5ID0gcHJlZF9wcm9iLCBsaW5ldHlwZSA9IEdyb3VwKSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgbGFicygKICAgIHRpdGxlID0gIlByZWRpY3RlZCBTdWJzY3JpcHRpb24gUHJvYmFiaWxpdHkgYnkgQWdlIGFuZCBHZW5kZXIiLAogICAgeCA9ICJBZ2UiLAogICAgeSA9ICJQcmVkaWN0ZWQgcHJvYmFiaWxpdHkgb2Ygc3Vic2NyaWJpbmciLAogICAgbGluZXR5cGUgPSAiR3JvdXAiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKKipJbnRlcnByZXRhdGlvbiAoUGxvdCk6KiogIAotIFRoZSBjdXJ2ZSBkZWNyZWFzZXMgd2l0aCBhZ2Ug4oaSIHN1YnNjcmlwdGlvbiBwcm9iYWJpbGl0eSBkZWNyZWFzZXMgYXMgY3VzdG9tZXJzIGdldCBvbGRlci4gIAotIFRoZSB3b21lbiBjdXJ2ZSBpcyBhYm92ZSB0aGUgbWVuIGN1cnZlIOKGkiB3b21lbiBhcmUgbW9yZSBsaWtlbHkgdG8gc3Vic2NyaWJlIGF0IGVhY2ggYWdlLgoKIyAuIFN0ZXAgMyDigJQgTWFuYWdlcmlhbCBSZWNvbW1lbmRhdGlvbnMKCkJhc2VkIG9uIHRoZSBtb2RlbDoKCjEpICoqRm9jdXMgYWNxdWlzaXRpb24gY2FtcGFpZ25zIG9uIHlvdW5nZXIgY3VzdG9tZXJzKiogIAotIEFnZSBpcyB0aGUgc3Ryb25nZXN0IGRyaXZlci4gWW91bmdlciBjdXN0b21lcnMgaGF2ZSB0aGUgaGlnaGVzdCBjb252ZXJzaW9uIHBvdGVudGlhbC4KCjIpICoqV29tZW4gYXJlIGEgaGlnaGVyLWxpa2VsaWhvb2Qgc2VnbWVudCoqICAKLSBXb21lbiBoYXZlIH41MCUgaGlnaGVyIG9kZHMgb2Ygc3Vic2NyaWJpbmcgdGhhbiBtZW4gKE9SIOKJiCAxLjUwKS4gIAotIFVzZSBjaGFubmVscyBhbmQgbWVzc2FnaW5nIHRoYXQgcGVyZm9ybSB3ZWxsIGZvciB0aGlzIHNlZ21lbnQuCgozKSAqKkltcHJvdmUgY29udmVyc2lvbiBmb3Igb2xkZXIgY3VzdG9tZXJzIHdpdGggdGFyZ2V0ZWQgYWN0aW9ucyoqICAKLSBGb3Igb2xkZXIgY3VzdG9tZXJzLCB0ZXN0IGNsZWFyZXIgdmFsdWUgY29tbXVuaWNhdGlvbiwgc2ltcGxlciBvbmJvYXJkaW5nLCBhbmQgdGFpbG9yZWQgb2ZmZXJzLgoKKipNYW5hZ2VyLWZyaWVuZGx5IGNvbmNsdXNpb246KiogIApBZ2Ugc2lnbmlmaWNhbnRseSByZWR1Y2VzIHN1YnNjcmlwdGlvbiBsaWtlbGlob29kLCB3aGlsZSBiZWluZyBmZW1hbGUgaW5jcmVhc2VzIGl0LiBUaGVyZWZvcmUsIG1hcmtldGluZyBzaG91bGQgcHJpb3JpdGl6ZSB5b3VuZ2VyIHNlZ21lbnRzIChlc3BlY2lhbGx5IHdvbWVuKSBmb3IgYWNxdWlzaXRpb24sIGFuZCBkZXZlbG9wIHNwZWNpZmljIHN0cmF0ZWdpZXMgdG8gaW1wcm92ZSBjb252ZXJzaW9uIGFtb25nIG9sZGVyIGN1c3RvbWVycy4KCiMgLiBMaW1pdGF0aW9ucyAKCi0gV2UgdXNlZCBvbmx5ICoqdHdvIHByZWRpY3RvcnMqKiAoYXMgcmVxdWlyZWQgYnkgdGhlIHF1aXopLiBSZWFsLXdvcmxkIG1vZGVscyBtYXkgbmVlZCBtb3JlIHZhcmlhYmxlcy4gIAotIFRoaXMgbW9kZWwgc2hvd3MgKiphc3NvY2lhdGlvbioqLCBub3QgZ3VhcmFudGVlZCBjYXVzYXRpb24uICAKLSBXZSBkaWQgbm90IHRlc3QgaW50ZXJhY3Rpb25zIChlLmcuLCBBZ2Ugw5cgR2VuZGVyKS4gVGhpcyBjYW4gYmUgZXhwbG9yZWQgaWYgcmVxdWlyZWQuCgo=