IBM HR Analytics Employee Attrition & Performance - EDA

Objective:

Find out leading factors contributing to employee attrition

Approach:

Use of R programming to analyse the data set

View dataset

head(df)

It look like the dataset have categorical value which is encoded into numeric . Here are labels: Education 1 ‘Below College’ 2 ‘College’ 3 ‘Bachelor’ 4 ‘Master’ 5 ‘Doctor’

EnvironmentSatisfaction 1 ‘Low’ 2 ‘Medium’ 3 ‘High’ 4 ‘Very High’

JobInvolvement 1 ‘Low’ 2 ‘Medium’ 3 ‘High’ 4 ‘Very High’

JobSatisfaction 1 ‘Low’ 2 ‘Medium’ 3 ‘High’ 4 ‘Very High’

PerformanceRating 1 ‘Low’ 2 ‘Good’ 3 ‘Excellent’ 4 ‘Outstanding’

RelationshipSatisfaction 1 ‘Low’ 2 ‘Medium’ 3 ‘High’ 4 ‘Very High’

WorkLifeBalance 1 ‘Bad’ 2 ‘Good’ 3 ‘Better’ 4 ‘Best’

General Overview:

distribution of employees across different age groups?

library(ggplot2)

# Create a histogram
ggplot(df, aes(x = Age)) +
  geom_histogram(binwidth = 5, fill = "skyblue", color = "black", alpha = 0.7) +
  labs(title = "Distribution of Employees Across Age Groups",
       x = "Age",
       y = "Number of Employees") +
  theme_minimal()

How many employees have experienced attrition?


# Using sum() function
attrition_count <- sum(df$Attrition == "Yes")
print(paste("Number of employees who have experienced attrition: ", attrition_count))
[1] "Number of employees who have experienced attrition:  237"

Demographics:

What is the distribution of gender and marital status among employees?

ggplot(df, aes(x = MaritalStatus, fill = Gender)) +
  geom_bar(position = "dodge", color = "white") +
  labs(title = "Distribution of Gender and Marital Status Among Employees",
       x = "Marital Status",
       y = "Number of Employees",
       fill = "Gender") +
  theme_minimal()

Work Environment:

What is the distribution of business travel frequency?

ggplot(df, aes(x = BusinessTravel, fill = BusinessTravel)) +
  geom_bar() +
  labs(title = "Distribution of Business Travel Frequency",
       x = "Business Travel Frequency",
       y = "Number of Employees") +
  theme_minimal()

How does the departmental distribution look?

ggplot(df, aes(x = Department, fill = Department)) +
  geom_bar() +
  labs(title = "Departmental Distribution",
       x = "Department",
       y = "Number of Employees") +
  theme_minimal()

What is the average daily rate for employees?

average_daily_rate <- mean(df$DailyRate)
print(paste("Average Daily Rate for Employees: $", round(average_daily_rate, 2)))
[1] "Average Daily Rate for Employees: $ 802.49"

Employee Satisfaction:

How satisfied are employees with their work environment, relationships, and work-life balance?

ggplot(df, aes(x = factor(Attrition), fill = factor(Attrition))) +
  geom_bar(aes(y = EnvironmentSatisfaction), position = "dodge", stat = "summary", fun = "mean") +
  geom_bar(aes(y = RelationshipSatisfaction), position = "dodge", stat = "summary", fun = "mean") +
  geom_bar(aes(y = WorkLifeBalance), position = "dodge", stat = "summary", fun = "mean") +
  labs(title = "Satisfaction with Work Environment, Relationships, and Work-Life Balance",
       x = "Attrition",
       y = "Mean Satisfaction Score",
       fill = "Attrition") +
  scale_fill_manual(values = c("No" = "lightblue", "Yes" = "lightcoral")) +
  theme_minimal()

Does satisfaction with the work environment correlate with attrition?

ggplot(df, aes(x = Attrition, y = EnvironmentSatisfaction, fill = Attrition)) +
  geom_boxplot() +
  labs(title = "Environment Satisfaction by Attrition",
       x = "Attrition",
       y = "Environment Satisfaction",
       fill = "Attrition") +
  theme_minimal()

Performance Metrics:

What is the distribution of performance ratings?

ggplot(df, aes(x = PerformanceRating, fill = factor(PerformanceRating))) +
  geom_bar() +
  labs(title = "Distribution of Performance Ratings",
       x = "Performance Rating",
       y = "Number of Employees",
       fill = "Performance Rating") +
  theme_minimal()

How do performance ratings relate to attrition?

t_test_result <- t.test(PerformanceRating ~ Attrition, data = df)
# Display the result
print(t_test_result)

    Welch Two Sample t-test

data:  PerformanceRating by Attrition
t = -0.10999, df = 331.22, p-value = 0.9125
alternative hypothesis: true difference in means between group No and group Yes is not equal to 0
95 percent confidence interval:
 -0.05350780  0.04784086
sample estimates:
 mean in group No mean in group Yes 
         3.153285          3.156118 

Training and Development:

How many training sessions did employees undergo last year?

total_training_sessions <- sum(df$TrainingTimesLastYear)

# Display the result
print(paste("Total Training Sessions Last Year: ", total_training_sessions))
[1] "Total Training Sessions Last Year:  4115"

Is there a correlation between training and attrition?

t_test_result_2 <- t.test(TrainingTimesLastYear ~ Attrition, data = df)
# Display the result
print(t_test_result_2)

    Welch Two Sample t-test

data:  TrainingTimesLastYear by Attrition
t = 2.3305, df = 339.56, p-value = 0.02036
alternative hypothesis: true difference in means between group No and group Yes is not equal to 0
95 percent confidence interval:
 0.03251776 0.38439273
sample estimates:
 mean in group No mean in group Yes 
         2.832928          2.624473 

Temporal Analysis:

How do various factors change with the number of years an employee has spent in the current role or with the current manager?

ggplot(df, aes(x = YearsInCurrentRole, y = MonthlyIncome, color = Attrition)) +
  geom_point() +
  labs(title = "Relationship Between Monthly Income and Years in Current Role",
       x = "Years in Current Role",
       y = "Monthly Income",
       color = "Attrition") +
  theme_minimal()+ geom_jitter()

Overtime:

How many employees work overtime, and is there a correlation with attrition?

employees_overtime <- sum(df$OverTime == "Yes")

# Display the result
print(paste("Number of Employees Working Overtime: ", employees_overtime))
[1] "Number of Employees Working Overtime:  416"
ggplot(df, aes(x = OverTime, fill = Attrition)) +
  geom_bar(position = "fill") +
  labs(title = "Relationship Between Overtime and Attrition",
       x = "Overtime",
       y = "Proportion",
       fill = "Attrition") +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +  # Display y-axis in percentage
  theme_minimal()

Summary

It look like the leading factors of attrition are salary(income), job satisfaction , lack of work life balance. Increase in training hour could potentially decrease atttrition .

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIElCTSBIUiBBbmFseXRpY3MgRW1wbG95ZWUgQXR0cml0aW9uICYgUGVyZm9ybWFuY2UgLSBFREENCg0KDQojIyBPYmplY3RpdmU6DQpGaW5kIG91dCBsZWFkaW5nIGZhY3RvcnMgY29udHJpYnV0aW5nIHRvIGVtcGxveWVlIGF0dHJpdGlvbg0KDQoNCiMjICBBcHByb2FjaDoNClVzZSBvZiBSIHByb2dyYW1taW5nIHRvIGFuYWx5c2UgdGhlIGRhdGEgc2V0DQoNCiMjIyBWaWV3IGRhdGFzZXQNCg0KYGBge3J9DQpoZWFkKGRmKQ0KYGBgDQoNCkl0IGxvb2sgbGlrZSB0aGUgZGF0YXNldCBoYXZlIGNhdGVnb3JpY2FsIHZhbHVlIHdoaWNoIGlzIGVuY29kZWQgaW50byBudW1lcmljIC4NCkhlcmUgYXJlIGxhYmVsczoNCkVkdWNhdGlvbg0KMSAnQmVsb3cgQ29sbGVnZScNCjIgJ0NvbGxlZ2UnDQozICdCYWNoZWxvcicNCjQgJ01hc3RlcicNCjUgJ0RvY3RvcicNCg0KRW52aXJvbm1lbnRTYXRpc2ZhY3Rpb24NCjEgJ0xvdycNCjIgJ01lZGl1bScNCjMgJ0hpZ2gnDQo0ICdWZXJ5IEhpZ2gnDQoNCkpvYkludm9sdmVtZW50DQoxICdMb3cnDQoyICdNZWRpdW0nDQozICdIaWdoJw0KNCAnVmVyeSBIaWdoJw0KDQpKb2JTYXRpc2ZhY3Rpb24NCjEgJ0xvdycNCjIgJ01lZGl1bScNCjMgJ0hpZ2gnDQo0ICdWZXJ5IEhpZ2gnDQoNClBlcmZvcm1hbmNlUmF0aW5nDQoxICdMb3cnDQoyICdHb29kJw0KMyAnRXhjZWxsZW50Jw0KNCAnT3V0c3RhbmRpbmcnDQoNClJlbGF0aW9uc2hpcFNhdGlzZmFjdGlvbg0KMSAnTG93Jw0KMiAnTWVkaXVtJw0KMyAnSGlnaCcNCjQgJ1ZlcnkgSGlnaCcNCg0KV29ya0xpZmVCYWxhbmNlDQoxICdCYWQnDQoyICdHb29kJw0KMyAnQmV0dGVyJw0KNCAnQmVzdCcNCg0KDQojIyMgR2VuZXJhbCBPdmVydmlldzoNCg0KIyMjIyBkaXN0cmlidXRpb24gb2YgZW1wbG95ZWVzIGFjcm9zcyBkaWZmZXJlbnQgYWdlIGdyb3Vwcz8NCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIENyZWF0ZSBhIGhpc3RvZ3JhbQ0KZ2dwbG90KGRmLCBhZXMoeCA9IEFnZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1LCBmaWxsID0gInNreWJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC43KSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIEVtcGxveWVlcyBBY3Jvc3MgQWdlIEdyb3VwcyIsDQogICAgICAgeCA9ICJBZ2UiLA0KICAgICAgIHkgPSAiTnVtYmVyIG9mIEVtcGxveWVlcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMjIyBIb3cgbWFueSBlbXBsb3llZXMgaGF2ZSBleHBlcmllbmNlZCBhdHRyaXRpb24/DQpgYGB7cn0NCg0KIyBVc2luZyBzdW0oKSBmdW5jdGlvbg0KYXR0cml0aW9uX2NvdW50IDwtIHN1bShkZiRBdHRyaXRpb24gPT0gIlllcyIpDQpwcmludChwYXN0ZSgiTnVtYmVyIG9mIGVtcGxveWVlcyB3aG8gaGF2ZSBleHBlcmllbmNlZCBhdHRyaXRpb246ICIsIGF0dHJpdGlvbl9jb3VudCkpDQpgYGANCiAgICANCiMjIyBEZW1vZ3JhcGhpY3M6DQoNCiMjIyMgV2hhdCBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIGdlbmRlciBhbmQgbWFyaXRhbCBzdGF0dXMgYW1vbmcgZW1wbG95ZWVzPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gTWFyaXRhbFN0YXR1cywgZmlsbCA9IEdlbmRlcikpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgR2VuZGVyIGFuZCBNYXJpdGFsIFN0YXR1cyBBbW9uZyBFbXBsb3llZXMiLA0KICAgICAgIHggPSAiTWFyaXRhbCBTdGF0dXMiLA0KICAgICAgIHkgPSAiTnVtYmVyIG9mIEVtcGxveWVlcyIsDQogICAgICAgZmlsbCA9ICJHZW5kZXIiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMjIyMgSG93IGlzIGF0dHJpdGlvbiByZWxhdGVkIHRvIGdlbmRlciBhbmQgbWFyaXRhbCBzdGF0dXM/DQpgYGB7cn0NCmdncGxvdChkZiwgYWVzKHggPSBBdHRyaXRpb24sIGZpbGwgPSBHZW5kZXIpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAid2hpdGUiKSArDQogIGxhYnModGl0bGUgPSAiUmVsYXRpb24gb2YgQXR0cml0aW9uIGFuZCBHZW5kZXIgQW1vbmcgRW1wbG95ZWVzIiwNCiAgICAgICB4ID0gIkF0dHJpdGlvbiIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgRW1wbG95ZWVzIiwNCiAgICAgICBmaWxsID0gIkdlbmRlciIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCmBgYHtyfQ0KZ2dwbG90KGRmLCBhZXMoeCA9IEF0dHJpdGlvbiAsIGZpbGwgPSBNYXJpdGFsU3RhdHVzKSkrIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIiwgY29sb3IgPSAid2hpdGUiKStsYWJzKHRpdGxlID0gIlJlbGF0aW9uIG9mIEF0dHJpdGlvbiBhbmQgTWFyaXRpYWwgU3RhdHVzIEFtb25nIEVtcGxveWVlcyIsDQogICAgICAgeCA9ICJBdHRyaXRpb24iLA0KICAgICAgIHkgPSAiTnVtYmVyIG9mIEVtcGxveWVlcyIsDQogICAgICAgZmlsbCA9ICJHZW5kZXIiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQojIyMgV29yayBFbnZpcm9ubWVudDoNCg0KIyMjIyBXaGF0IGlzIHRoZSBkaXN0cmlidXRpb24gb2YgYnVzaW5lc3MgdHJhdmVsIGZyZXF1ZW5jeT8NCmBgYHtyfQ0KZ2dwbG90KGRmLCBhZXMoeCA9IEJ1c2luZXNzVHJhdmVsLCBmaWxsID0gQnVzaW5lc3NUcmF2ZWwpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBCdXNpbmVzcyBUcmF2ZWwgRnJlcXVlbmN5IiwNCiAgICAgICB4ID0gIkJ1c2luZXNzIFRyYXZlbCBGcmVxdWVuY3kiLA0KICAgICAgIHkgPSAiTnVtYmVyIG9mIEVtcGxveWVlcyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMjIyBIb3cgZG9lcyB0aGUgZGVwYXJ0bWVudGFsIGRpc3RyaWJ1dGlvbiBsb29rPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gRGVwYXJ0bWVudCwgZmlsbCA9IERlcGFydG1lbnQpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKHRpdGxlID0gIkRlcGFydG1lbnRhbCBEaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiRGVwYXJ0bWVudCIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgRW1wbG95ZWVzIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KIA0KIyMjIyBXaGF0IGlzIHRoZSBhdmVyYWdlIGRhaWx5IHJhdGUgZm9yIGVtcGxveWVlcz8NCmBgYHtyfQ0KYXZlcmFnZV9kYWlseV9yYXRlIDwtIG1lYW4oZGYkRGFpbHlSYXRlKQ0KcHJpbnQocGFzdGUoIkF2ZXJhZ2UgRGFpbHkgUmF0ZSBmb3IgRW1wbG95ZWVzOiAkIiwgcm91bmQoYXZlcmFnZV9kYWlseV9yYXRlLCAyKSkpDQpgYGANCiMjIyBKb2ItcmVsYXRlZCBGYWN0b3JzOg0KDQoNCiMjIyMgSG93IGRvZXMgam9iIHNhdGlzZmFjdGlvbiB2YXJ5IGFjcm9zcyBkaWZmZXJlbnQgcm9sZXMgYW5kIGxldmVscz8NCmBgYHtyfQ0KZ2dwbG90KGRmLGFlcyh4PUpvYlJvbGUgLCB5PSBKb2JMZXZlbCkpK2dlb21fbGluZSgpICsgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgSm9iIFJvbGVzIGFuZCBMZXZlbCIgLCB4PSAiSm9iIFJvbGUgIiAsIHkgPSAiSm9iIExldmVsIikgK3RoZW1lX21pbmltYWwoKSt0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKQ0KYGBgDQoNCiMjIyMgV2hhdCBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIGpvYiByb2xlcyBhbmQgbGV2ZWxzPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gSm9iUm9sZSwgZmlsbCA9IGZhY3RvcihKb2JMZXZlbCkpKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBKb2IgUm9sZXMgYW5kIExldmVscyIsDQogICAgICAgeCA9ICJKb2IgUm9sZSIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgRW1wbG95ZWVzIiwNCiAgICAgICBmaWxsID0gIkpvYiBMZXZlbCIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgIA0KYGBgDQoNCiMjIyMgQXJlIHRoZXJlIGFueSBwYXR0ZXJucyBpbiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gam9iIGludm9sdmVtZW50IGFuZCBhdHRyaXRpb24/DQpgYGB7cn0NCmdncGxvdChkZiwgYWVzKHggPSBKb2JJbnZvbHZlbWVudCwgZmlsbCA9IEF0dHJpdGlvbikpICsNCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siKSArDQogIGxhYnModGl0bGUgPSAiUmVsYXRpb25zaGlwIEJldHdlZW4gSm9iIEludm9sdmVtZW50IGFuZCBBdHRyaXRpb24iLA0KICAgICAgIHggPSAiSm9iIEludm9sdmVtZW50IiwNCiAgICAgICB5ID0gIk51bWJlciBvZiBFbXBsb3llZXMiLA0KICAgICAgIGZpbGwgPSAiQXR0cml0aW9uIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KIyMjIyBIb3cgZG9lcyBhdHRyaXRpb24gcmVsYXRlIHRvIG1vbnRobHkgaW5jb21lIGFuZCBvdGhlciBjb21wZW5zYXRpb24tcmVsYXRlZCBmYWN0b3JzPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gQXR0cml0aW9uLCB5ID0gTW9udGhseUluY29tZSwgZmlsbCA9IEF0dHJpdGlvbikpICsNCiAgZ2VvbV9ib3hwbG90KCkgKw0KICBsYWJzKHRpdGxlID0gIk1vbnRobHkgSW5jb21lIGJ5IEF0dHJpdGlvbiIsDQogICAgICAgeCA9ICJBdHRyaXRpb24iLA0KICAgICAgIHkgPSAiTW9udGhseSBJbmNvbWUiLA0KICAgICAgIGZpbGwgPSAiQXR0cml0aW9uIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KDQpgYGANCiMjIyBFbXBsb3llZSBTYXRpc2ZhY3Rpb246DQoNCiMjIyMgSG93IHNhdGlzZmllZCBhcmUgZW1wbG95ZWVzIHdpdGggdGhlaXIgd29yayBlbnZpcm9ubWVudCwgcmVsYXRpb25zaGlwcywgYW5kIHdvcmstbGlmZSBiYWxhbmNlPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gZmFjdG9yKEF0dHJpdGlvbiksIGZpbGwgPSBmYWN0b3IoQXR0cml0aW9uKSkpICsNCiAgZ2VvbV9iYXIoYWVzKHkgPSBFbnZpcm9ubWVudFNhdGlzZmFjdGlvbiksIHBvc2l0aW9uID0gImRvZGdlIiwgc3RhdCA9ICJzdW1tYXJ5IiwgZnVuID0gIm1lYW4iKSArDQogIGdlb21fYmFyKGFlcyh5ID0gUmVsYXRpb25zaGlwU2F0aXNmYWN0aW9uKSwgcG9zaXRpb24gPSAiZG9kZ2UiLCBzdGF0ID0gInN1bW1hcnkiLCBmdW4gPSAibWVhbiIpICsNCiAgZ2VvbV9iYXIoYWVzKHkgPSBXb3JrTGlmZUJhbGFuY2UpLCBwb3NpdGlvbiA9ICJkb2RnZSIsIHN0YXQgPSAic3VtbWFyeSIsIGZ1biA9ICJtZWFuIikgKw0KICBsYWJzKHRpdGxlID0gIlNhdGlzZmFjdGlvbiB3aXRoIFdvcmsgRW52aXJvbm1lbnQsIFJlbGF0aW9uc2hpcHMsIGFuZCBXb3JrLUxpZmUgQmFsYW5jZSIsDQogICAgICAgeCA9ICJBdHRyaXRpb24iLA0KICAgICAgIHkgPSAiTWVhbiBTYXRpc2ZhY3Rpb24gU2NvcmUiLA0KICAgICAgIGZpbGwgPSAiQXR0cml0aW9uIikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJObyIgPSAibGlnaHRibHVlIiwgIlllcyIgPSAibGlnaHRjb3JhbCIpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KIyMjIyBEb2VzIHNhdGlzZmFjdGlvbiB3aXRoIHRoZSB3b3JrIGVudmlyb25tZW50IGNvcnJlbGF0ZSB3aXRoIGF0dHJpdGlvbj8NCmBgYHtyfQ0KZ2dwbG90KGRmLCBhZXMoeCA9IEF0dHJpdGlvbiwgeSA9IEVudmlyb25tZW50U2F0aXNmYWN0aW9uLCBmaWxsID0gQXR0cml0aW9uKSkgKw0KICBnZW9tX2JveHBsb3QoKSArDQogIGxhYnModGl0bGUgPSAiRW52aXJvbm1lbnQgU2F0aXNmYWN0aW9uIGJ5IEF0dHJpdGlvbiIsDQogICAgICAgeCA9ICJBdHRyaXRpb24iLA0KICAgICAgIHkgPSAiRW52aXJvbm1lbnQgU2F0aXNmYWN0aW9uIiwNCiAgICAgICBmaWxsID0gIkF0dHJpdGlvbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KDQojIyMjIFBlcmZvcm1hbmNlIE1ldHJpY3M6DQoNCiMjIyMgV2hhdCBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIHBlcmZvcm1hbmNlIHJhdGluZ3M/DQpgYGB7cn0NCmdncGxvdChkZiwgYWVzKHggPSBQZXJmb3JtYW5jZVJhdGluZywgZmlsbCA9IGZhY3RvcihQZXJmb3JtYW5jZVJhdGluZykpKSArDQogIGdlb21fYmFyKCkgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBQZXJmb3JtYW5jZSBSYXRpbmdzIiwNCiAgICAgICB4ID0gIlBlcmZvcm1hbmNlIFJhdGluZyIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgRW1wbG95ZWVzIiwNCiAgICAgICBmaWxsID0gIlBlcmZvcm1hbmNlIFJhdGluZyIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMjIyBIb3cgZG8gcGVyZm9ybWFuY2UgcmF0aW5ncyByZWxhdGUgdG8gYXR0cml0aW9uPw0KYGBge3J9DQp0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdChQZXJmb3JtYW5jZVJhdGluZyB+IEF0dHJpdGlvbiwgZGF0YSA9IGRmKQ0KIyBEaXNwbGF5IHRoZSByZXN1bHQNCnByaW50KHRfdGVzdF9yZXN1bHQpDQpgYGANCg0KDQojIyMgVHJhaW5pbmcgYW5kIERldmVsb3BtZW50Og0KDQojIyMjIEhvdyBtYW55IHRyYWluaW5nIHNlc3Npb25zIGRpZCBlbXBsb3llZXMgdW5kZXJnbyBsYXN0IHllYXI/DQpgYGB7cn0NCnRvdGFsX3RyYWluaW5nX3Nlc3Npb25zIDwtIHN1bShkZiRUcmFpbmluZ1RpbWVzTGFzdFllYXIpDQoNCiMgRGlzcGxheSB0aGUgcmVzdWx0DQpwcmludChwYXN0ZSgiVG90YWwgVHJhaW5pbmcgU2Vzc2lvbnMgTGFzdCBZZWFyOiAiLCB0b3RhbF90cmFpbmluZ19zZXNzaW9ucykpDQpgYGANCg0KIyMjIyBJcyB0aGVyZSBhIGNvcnJlbGF0aW9uIGJldHdlZW4gdHJhaW5pbmcgYW5kIGF0dHJpdGlvbj8NCmBgYHtyfQ0KdF90ZXN0X3Jlc3VsdF8yIDwtIHQudGVzdChUcmFpbmluZ1RpbWVzTGFzdFllYXIgfiBBdHRyaXRpb24sIGRhdGEgPSBkZikNCiMgRGlzcGxheSB0aGUgcmVzdWx0DQpwcmludCh0X3Rlc3RfcmVzdWx0XzIpDQpgYGANCg0KDQojIyMgVGVtcG9yYWwgQW5hbHlzaXM6DQoNCiMjIyMgSGF2ZSB0aGVyZSBiZWVuIGFueSB0cmVuZHMgaW4gYXR0cml0aW9uIG92ZXIgdGhlIHllYXJzPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gWWVhcnNBdENvbXBhbnksIGZpbGwgPSBBdHRyaXRpb24pKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIikgKw0KICBsYWJzKHRpdGxlID0gIlRyZW5kcyBpbiBBdHRyaXRpb24gT3ZlciB0aGUgWWVhcnMiLA0KICAgICAgIHggPSAiWWVhcnMgYXQgQ29tcGFueSIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgRW1wbG95ZWVzIiwNCiAgICAgICBmaWxsID0gIkF0dHJpdGlvbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMjIyBIb3cgZG8gdmFyaW91cyBmYWN0b3JzIGNoYW5nZSB3aXRoIHRoZSBudW1iZXIgb2YgeWVhcnMgYW4gZW1wbG95ZWUgaGFzIHNwZW50IGluIHRoZSBjdXJyZW50IHJvbGUgb3Igd2l0aCB0aGUgY3VycmVudCBtYW5hZ2VyPw0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gWWVhcnNJbkN1cnJlbnRSb2xlLCB5ID0gTW9udGhseUluY29tZSwgY29sb3IgPSBBdHRyaXRpb24pKSArDQogIGdlb21fcG9pbnQoKSArDQogIGxhYnModGl0bGUgPSAiUmVsYXRpb25zaGlwIEJldHdlZW4gTW9udGhseSBJbmNvbWUgYW5kIFllYXJzIGluIEN1cnJlbnQgUm9sZSIsDQogICAgICAgeCA9ICJZZWFycyBpbiBDdXJyZW50IFJvbGUiLA0KICAgICAgIHkgPSAiTW9udGhseSBJbmNvbWUiLA0KICAgICAgIGNvbG9yID0gIkF0dHJpdGlvbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpKyBnZW9tX2ppdHRlcigpDQpgYGANCg0KDQojIyMgT3ZlcnRpbWU6DQoNCiMjIyBIb3cgbWFueSBlbXBsb3llZXMgd29yayBvdmVydGltZSwgYW5kIGlzIHRoZXJlIGEgY29ycmVsYXRpb24gd2l0aCBhdHRyaXRpb24/DQpgYGB7cn0NCmVtcGxveWVlc19vdmVydGltZSA8LSBzdW0oZGYkT3ZlclRpbWUgPT0gIlllcyIpDQoNCiMgRGlzcGxheSB0aGUgcmVzdWx0DQpwcmludChwYXN0ZSgiTnVtYmVyIG9mIEVtcGxveWVlcyBXb3JraW5nIE92ZXJ0aW1lOiAiLCBlbXBsb3llZXNfb3ZlcnRpbWUpKQ0KYGBgDQoNCg0KYGBge3J9DQpnZ3Bsb3QoZGYsIGFlcyh4ID0gT3ZlclRpbWUsIGZpbGwgPSBBdHRyaXRpb24pKSArDQogIGdlb21fYmFyKHBvc2l0aW9uID0gImZpbGwiKSArDQogIGxhYnModGl0bGUgPSAiUmVsYXRpb25zaGlwIEJldHdlZW4gT3ZlcnRpbWUgYW5kIEF0dHJpdGlvbiIsDQogICAgICAgeCA9ICJPdmVydGltZSIsDQogICAgICAgeSA9ICJQcm9wb3J0aW9uIiwNCiAgICAgICBmaWxsID0gIkF0dHJpdGlvbiIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoc2NhbGUgPSAxKSkgKyAgIyBEaXNwbGF5IHktYXhpcyBpbiBwZXJjZW50YWdlDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg0KIyMgU3VtbWFyeQ0KSXQgbG9vayBsaWtlIHRoZSBsZWFkaW5nIGZhY3RvcnMgb2YgYXR0cml0aW9uIGFyZSBzYWxhcnkoaW5jb21lKSwgam9iIHNhdGlzZmFjdGlvbiAsIGxhY2sgb2Ygd29yayBsaWZlIGJhbGFuY2UuDQpJbmNyZWFzZSBpbiB0cmFpbmluZyBob3VyIGNvdWxkIHBvdGVudGlhbGx5IGRlY3JlYXNlIGF0dHRyaXRpb24gLg0K