This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

# ==============================================================================
# MATH 345: Applied Statistics - Draft 1 Data Cleaning & Exploratory Analysis
# Project Title: Analyzing Daily Physical Activity, Sleep Quality, and Duration
# Author: Elad Bakshi
# Date: October 2026
# ==============================================================================

# 1. LOAD REQUIRED LIBRARIES
# ------------------------------------------------------------------------------
# Install packages if not already installed:
# install.packages(c("tidyverse", "corrplot", "gridExtra", "knitr"))

library(tidyverse)  # Includes ggplot2, dplyr, readr, tidyr
library(corrplot)   # For visual correlation matrices
library(gridExtra)  # For combining ggplot panel figures
library(knitr)      # For clean table formatting

# 2. DATA IMPORT & INITIAL PREPROCESSING
# ------------------------------------------------------------------------------
# Load the dataset (replace filename if stored locally or use direct URL)
dataset_url <- "https://raw.githubusercontent.com/miayulia/Sleep-and-Health-Lifestyle-Analysis/main/Sleep_health_and_lifestyle_dataset.csv"

# Load data into R dataframe
sleep_data <- read_csv(dataset_url)

# Inspect dataset structure
cat("\n--- DATASET OVERVIEW ---\n")

--- DATASET OVERVIEW ---
glimpse(sleep_data)
Rows: 374
Columns: 13
$ `Person ID`               <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, …
$ Gender                    <chr> "Male", "Male", "Male", "Male", "Male", "Ma…
$ Age                       <dbl> 27, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29,…
$ Occupation                <chr> "Software Engineer", "Doctor", "Doctor", "S…
$ `Sleep Duration`          <dbl> 6.1, 6.2, 6.2, 5.9, 5.9, 5.9, 6.3, 7.8, 7.8…
$ `Quality of Sleep`        <dbl> 6, 6, 6, 4, 4, 4, 6, 7, 7, 7, 6, 7, 6, 6, 6…
$ `Physical Activity Level` <dbl> 42, 60, 60, 30, 30, 30, 40, 75, 75, 75, 30,…
$ `Stress Level`            <dbl> 6, 8, 8, 8, 8, 8, 7, 6, 6, 6, 8, 6, 8, 8, 8…
$ `BMI Category`            <chr> "Overweight", "Normal", "Normal", "Obese", …
$ `Blood Pressure`          <chr> "126/83", "125/80", "125/80", "140/90", "14…
$ `Heart Rate`              <dbl> 77, 75, 75, 85, 85, 85, 82, 70, 70, 70, 70,…
$ `Daily Steps`             <dbl> 4200, 10000, 10000, 3000, 3000, 3000, 3500,…
$ `Sleep Disorder`          <chr> "None", "None", "None", "Sleep Apnea", "Sle…
summary(sleep_data)
   Person ID            Gender         Age            Occupation 
 Min.   :  1.00   Length   :374   Min.   :27.00   Length   :374  
 1st Qu.: 94.25   N.unique :  2   1st Qu.:35.25   N.unique : 11  
 Median :187.50   N.blank  :  0   Median :43.00   N.blank  :  0  
 Mean   :187.50   Min.nchar:  4   Mean   :42.18   Min.nchar:  5  
 3rd Qu.:280.75   Max.nchar:  6   3rd Qu.:50.00   Max.nchar: 20  
 Max.   :374.00                   Max.   :59.00                  
 Sleep Duration  Quality of Sleep Physical Activity Level  Stress Level  
 Min.   :5.800   Min.   :4.000    Min.   :30.00           Min.   :3.000  
 1st Qu.:6.400   1st Qu.:6.000    1st Qu.:45.00           1st Qu.:4.000  
 Median :7.200   Median :7.000    Median :60.00           Median :5.000  
 Mean   :7.132   Mean   :7.313    Mean   :59.17           Mean   :5.385  
 3rd Qu.:7.800   3rd Qu.:8.000    3rd Qu.:75.00           3rd Qu.:7.000  
 Max.   :8.500   Max.   :9.000    Max.   :90.00           Max.   :8.000  
    BMI Category   Blood Pressure   Heart Rate     Daily Steps   
 Length   :374   Length   :374    Min.   :65.00   Min.   : 3000  
 N.unique :  4   N.unique : 25    1st Qu.:68.00   1st Qu.: 5600  
 N.blank  :  0   N.blank  :  0    Median :70.00   Median : 7000  
 Min.nchar:  5   Min.nchar:  6    Mean   :70.17   Mean   : 6817  
 Max.nchar: 13   Max.nchar:  6    3rd Qu.:72.00   3rd Qu.: 8000  
                                  Max.   :86.00   Max.   :10000  
   Sleep Disorder
 Length   :374   
 N.unique :  3   
 N.blank  :  0   
 Min.nchar:  4   
 Max.nchar: 11   
                 
# Data Cleaning: Standardize categorical labels and check for missing values
sleep_data <- sleep_data %>%
  # Fix inconsistent category names in BMI
  mutate(`BMI Category` = ifelse(`BMI Category` == "Normal Weight", "Normal", `BMI Category`)) %>%
  # Convert categorical columns to factors
  mutate(
    Gender = as.factor(Gender),
    `BMI Category` = factor(`BMI Category`, levels = c("Normal", "Overweight", "Obese")),
    `Sleep Disorder` = as.factor(replace_na(`Sleep Disorder`, "None"))
  )

# Verify missing data count
cat("\nTotal Missing Values per Column:\n")

Total Missing Values per Column:
print(colSums(is.na(sleep_data)))
              Person ID                  Gender                     Age 
                      0                       0                       0 
             Occupation          Sleep Duration        Quality of Sleep 
                      0                       0                       0 
Physical Activity Level            Stress Level            BMI Category 
                      0                       0                       0 
         Blood Pressure              Heart Rate             Daily Steps 
                      0                       0                       0 
         Sleep Disorder 
                      0 
# 3. NUMERICAL SUMMARY STATISTICS (TABLE 1)
# ------------------------------------------------------------------------------
# Select quantitative variables for summary calculations
num_vars <- sleep_data %>%
  select(`Age`, `Sleep Duration`, `Quality of Sleep`, 
         `Physical Activity Level`, `Stress Level`, `Daily Steps`)

# Function to compute parametric and non-parametric summary statistics
get_summary_stats <- function(df) {
  df %>%
    pivot_longer(cols = everything(), names_to = "Variable", values_to = "Value") %>%
    group_by(Variable) %>%
    summarise(
      Mean     = round(mean(Value, na.rm = TRUE), 2),
      SD       = round(sd(Value, na.rm = TRUE), 2),
      Median   = round(median(Value, na.rm = TRUE), 2),
      Q1       = round(quantile(Value, 0.25, na.rm = TRUE), 2),
      Q3       = round(quantile(Value, 0.75, na.rm = TRUE), 2),
      IQR      = round(IQR(Value, na.rm = TRUE), 2),
      Min      = round(min(Value, na.rm = TRUE), 2),
      Max      = round(max(Value, na.rm = TRUE), 2)
    )
}

summary_table <- get_summary_stats(num_vars)
cat("\n--- SUMMARY STATISTICS TABLE ---\n")

--- SUMMARY STATISTICS TABLE ---
print(kable(summary_table, caption = "Summary Statistics for Quantitative Variables (N = 374)"))
Summary Statistics for Quantitative Variables (N = 374)
Variable Mean SD Median Q1 Q3 IQR Min Max
Age 42.18 8.67 43.0 35.25 50.0 14.75 27.0 59.0
Daily Steps 6816.84 1617.92 7000.0 5600.00 8000.0 2400.00 3000.0 10000.0
Physical Activity Level 59.17 20.83 60.0 45.00 75.0 30.00 30.0 90.0
Quality of Sleep 7.31 1.20 7.0 6.00 8.0 2.00 4.0 9.0
Sleep Duration 7.13 0.80 7.2 6.40 7.8 1.40 5.8 8.5
Stress Level 5.39 1.77 5.0 4.00 7.0 3.00 3.0 8.0
p1 <- ggplot(sleep_data, aes(x = `Physical Activity Level`)) +
  geom_histogram(binwidth = 5, fill = "blue", color = "white", alpha = 0.8) +
  theme_minimal() +
  labs(title = "Distribution of Daily Physical Activity", x = "Activity (mins/day)", y = "Frequency")

p2 <- ggplot(sleep_data, aes(x = `Quality of Sleep`)) +
  geom_histogram(binwidth = 1, fill = "blue", color = "white", alpha = 0.8) +
  scale_x_continuous(breaks = 1:10) +
  theme_minimal() +
  labs(title = "Distribution of Sleep Quality Rating", x = "Quality Score (1-10)", y = "Frequency")

p3 <- ggplot(sleep_data, aes(x = `Sleep Duration`)) +
  geom_histogram(binwidth = 0.5, fill = "blue", color = "white", alpha = 0.8) +
  theme_minimal() +
  labs(title = "Distribution of Sleep Duration", x = "Sleep Duration (Hours)", y = "Frequency")

# Combine univariate plots into a 1x3 panel
grid.arrange(p1, p2, p3, ncol = 3)

p_scatter1 <- ggplot(sleep_data, aes(x = `Physical Activity Level`, y = `Quality of Sleep`)) +
  geom_count(color = "#1f77b4", alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "#C0392B", fill = "#E74C3C", alpha = 0.15) +
  scale_size_area(max_size = 6) +
  theme_minimal() +
  labs(
    title = "Physical Activity vs. Quality of Sleep",
    x = "Physical Activity (mins/day)",
    y = "Quality of Sleep (1-10)",
    size = "Count"
  )
p_scatter2 <- ggplot(sleep_data, aes(x = `Physical Activity Level`, y = `Sleep Duration`)) +
  geom_count(color = "#2ca02c", alpha = 0.6) +
  geom_smooth(method = "lm", se = TRUE, color = "#C0392B", fill = "#E74C3C", alpha = 0.15) +
  scale_size_area(max_size = 6) +
  theme_minimal() +
  labs(
    title = "Physical Activity vs. Sleep Duration",
    x = "Physical Activity (mins/day)",
    y = "Sleep Duration (hours)",
    size = "Count"
  )
grid.arrange(p_scatter1, p_scatter2, ncol = 2)

Add a new chunk by clicking the *Insert Chunk* button on the toolbar or by pressing *Ctrl+Alt+I*.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the *Preview* button or press *Ctrl+Shift+K* to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike *Knit*, *Preview* does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQoNCiMgTUFUSCAzNDU6IEFwcGxpZWQgU3RhdGlzdGljcw0KIyBQcm9qZWN0IFRpdGxlOiBBbmFseXppbmcgRGFpbHkgUGh5c2ljYWwgQWN0aXZpdHksIFNsZWVwIFF1YWxpdHksIGFuZCBEdXJhdGlvbg0KIyBFbGFkIEJha3NoaQ0KIyAyMDI2DQoNCiMgMS4gTE9BRCBSRVFVSVJFRCBMSUJSQVJJRVMNCg0KbGlicmFyeSh0aWR5dmVyc2UpIA0KbGlicmFyeShjb3JycGxvdCkgICANCmxpYnJhcnkoZ3JpZEV4dHJhKSAgDQpsaWJyYXJ5KGtuaXRyKSAgICAgIA0KDQojIDIuIERBVEEgSU1QT1JUIEFORCBJTklUSUFMIFBSRVBST0NFU1NJTkcNCmRhdGFzZXRfdXJsIDwtICJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbWlheXVsaWEvU2xlZXAtYW5kLUhlYWx0aC1MaWZlc3R5bGUtQW5hbHlzaXMvbWFpbi9TbGVlcF9oZWFsdGhfYW5kX2xpZmVzdHlsZV9kYXRhc2V0LmNzdiINCg0KIyBMb2FkIGRhdGEgaW50byBSIGRhdGFmcmFtZQ0Kc2xlZXBfZGF0YSA8LSByZWFkX2NzdihkYXRhc2V0X3VybCkNCg0KIyBJbnNwZWN0IGRhdGFzZXQgc3RydWN0dXJlDQpjYXQoIlxuLS0tIERBVEFTRVQgT1ZFUlZJRVcgLS0tXG4iKQ0KZ2xpbXBzZShzbGVlcF9kYXRhKQ0Kc3VtbWFyeShzbGVlcF9kYXRhKQ0KDQojc3RhbmRhcmRpemUgY2F0ZWdvcmljYWwgbGFiZWxzIGFuZCBjaGVjayBmb3IgbWlzc2luZyB2YWx1ZXMNCnNsZWVwX2RhdGEgPC0gc2xlZXBfZGF0YSAlPiUNCiAgIyBmaXggaW5jb25zaXN0ZW50IGNhdGVnb3J5IG5hbWVzIGluIEJNSQ0KICBtdXRhdGUoYEJNSSBDYXRlZ29yeWAgPSBpZmVsc2UoYEJNSSBDYXRlZ29yeWAgPT0gIk5vcm1hbCBXZWlnaHQiLCAiTm9ybWFsIiwgYEJNSSBDYXRlZ29yeWApKSAlPiUNCiAgIyBDb252ZXJ0IGNhdGVnb3JpY2FsIGNvbHVtbnMgdG8gZmFjdG9ycw0KICBtdXRhdGUoDQogICAgR2VuZGVyID0gYXMuZmFjdG9yKEdlbmRlciksDQogICAgYEJNSSBDYXRlZ29yeWAgPSBmYWN0b3IoYEJNSSBDYXRlZ29yeWAsIGxldmVscyA9IGMoIk5vcm1hbCIsICJPdmVyd2VpZ2h0IiwgIk9iZXNlIikpLA0KICAgIGBTbGVlcCBEaXNvcmRlcmAgPSBhcy5mYWN0b3IocmVwbGFjZV9uYShgU2xlZXAgRGlzb3JkZXJgLCAiTm9uZSIpKQ0KICApDQoNCiMgdmVyaWZ5IG1pc3NpbmcgZGF0YSBjb3VudA0KY2F0KCJcblRvdGFsIE1pc3NpbmcgVmFsdWVzIHBlciBDb2x1bW46XG4iKQ0KcHJpbnQoY29sU3Vtcyhpcy5uYShzbGVlcF9kYXRhKSkpDQoNCg0KIyAzLiBOVU1FUklDQUwgU1VNTUFSWSBTVEFUSVNUSUNTIA0KIyBTZWxlY3QgcXVhbnRpdGF0aXZlIHZhcmlhYmxlcyBmb3Igc3VtbWFyeSBjYWxjdWxhdGlvbnMNCm51bV92YXJzIDwtIHNsZWVwX2RhdGEgJT4lDQogIHNlbGVjdChgQWdlYCwgYFNsZWVwIER1cmF0aW9uYCwgYFF1YWxpdHkgb2YgU2xlZXBgLCANCiAgICAgICAgIGBQaHlzaWNhbCBBY3Rpdml0eSBMZXZlbGAsIGBTdHJlc3MgTGV2ZWxgLCBgRGFpbHkgU3RlcHNgKQ0KDQojIEZ1bmN0aW9uIHRvIGNvbXB1dGUgcGFyYW1ldHJpYyBhbmQgbm9uLXBhcmFtZXRyaWMgc3VtbWFyeSBzdGF0aXN0aWNzDQpnZXRfc3VtbWFyeV9zdGF0cyA8LSBmdW5jdGlvbihkZikgew0KICBkZiAlPiUNCiAgICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgbmFtZXNfdG8gPSAiVmFyaWFibGUiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKSAlPiUNCiAgICBncm91cF9ieShWYXJpYWJsZSkgJT4lDQogICAgc3VtbWFyaXNlKA0KICAgICAgTWVhbiAgICAgPSByb3VuZChtZWFuKFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICAgIFNEICAgICAgID0gcm91bmQoc2QoVmFsdWUsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgICAgTWVkaWFuICAgPSByb3VuZChtZWRpYW4oVmFsdWUsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgICAgUTEgICAgICAgPSByb3VuZChxdWFudGlsZShWYWx1ZSwgMC4yNSwgbmEucm0gPSBUUlVFKSwgMiksDQogICAgICBRMyAgICAgICA9IHJvdW5kKHF1YW50aWxlKFZhbHVlLCAwLjc1LCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICAgIElRUiAgICAgID0gcm91bmQoSVFSKFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICAgIE1pbiAgICAgID0gcm91bmQobWluKFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICAgIE1heCAgICAgID0gcm91bmQobWF4KFZhbHVlLCBuYS5ybSA9IFRSVUUpLCAyKQ0KICAgICkNCn0NCg0Kc3VtbWFyeV90YWJsZSA8LSBnZXRfc3VtbWFyeV9zdGF0cyhudW1fdmFycykNCmNhdCgiXG4tLS0gU1VNTUFSWSBTVEFUSVNUSUNTIFRBQkxFIC0tLVxuIikNCnByaW50KGthYmxlKHN1bW1hcnlfdGFibGUsIGNhcHRpb24gPSAiU3VtbWFyeSBTdGF0aXN0aWNzIGZvciBRdWFudGl0YXRpdmUgVmFyaWFibGVzIChOID0gMzc0KSIpKQ0KYGBgDQoNCg0KYGBge3J9DQpwMSA8LSBnZ3Bsb3Qoc2xlZXBfZGF0YSwgYWVzKHggPSBgUGh5c2ljYWwgQWN0aXZpdHkgTGV2ZWxgKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUsIGZpbGwgPSAiYmx1ZSIsIGNvbG9yID0gIndoaXRlIiwgYWxwaGEgPSAwLjgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgRGFpbHkgUGh5c2ljYWwgQWN0aXZpdHkiLCB4ID0gIkFjdGl2aXR5IChtaW5zL2RheSkiLCB5ID0gIkZyZXF1ZW5jeSIpDQoNCnAyIDwtIGdncGxvdChzbGVlcF9kYXRhLCBhZXMoeCA9IGBRdWFsaXR5IG9mIFNsZWVwYCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxLCBmaWxsID0gImJsdWUiLCBjb2xvciA9ICJ3aGl0ZSIsIGFscGhhID0gMC44KSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSAxOjEwKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIFNsZWVwIFF1YWxpdHkgUmF0aW5nIiwgeCA9ICJRdWFsaXR5IFNjb3JlICgxLTEwKSIsIHkgPSAiRnJlcXVlbmN5IikNCg0KcDMgPC0gZ2dwbG90KHNsZWVwX2RhdGEsIGFlcyh4ID0gYFNsZWVwIER1cmF0aW9uYCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGZpbGwgPSAiYmx1ZSIsIGNvbG9yID0gIndoaXRlIiwgYWxwaGEgPSAwLjgpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgU2xlZXAgRHVyYXRpb24iLCB4ID0gIlNsZWVwIER1cmF0aW9uIChIb3VycykiLCB5ID0gIkZyZXF1ZW5jeSIpDQoNCiMgQ29tYmluZSB1bml2YXJpYXRlIHBsb3RzIGludG8gYSAxeDMgcGFuZWwNCmdyaWQuYXJyYW5nZShwMSwgcDIsIHAzLCBuY29sID0gMykNCmBgYA0KDQoNCmBgYHtyfQ0KcF9zY2F0dGVyMSA8LSBnZ3Bsb3Qoc2xlZXBfZGF0YSwgYWVzKHggPSBgUGh5c2ljYWwgQWN0aXZpdHkgTGV2ZWxgLCB5ID0gYFF1YWxpdHkgb2YgU2xlZXBgKSkgKw0KICBnZW9tX2NvdW50KGNvbG9yID0gIiMxZjc3YjQiLCBhbHBoYSA9IDAuNikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUsIGNvbG9yID0gIiNDMDM5MkIiLCBmaWxsID0gIiNFNzRDM0MiLCBhbHBoYSA9IDAuMTUpICsNCiAgc2NhbGVfc2l6ZV9hcmVhKG1heF9zaXplID0gNikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIlBoeXNpY2FsIEFjdGl2aXR5IHZzLiBRdWFsaXR5IG9mIFNsZWVwIiwNCiAgICB4ID0gIlBoeXNpY2FsIEFjdGl2aXR5IChtaW5zL2RheSkiLA0KICAgIHkgPSAiUXVhbGl0eSBvZiBTbGVlcCAoMS0xMCkiLA0KICAgIHNpemUgPSAiQ291bnQiDQogICkNCnBfc2NhdHRlcjIgPC0gZ2dwbG90KHNsZWVwX2RhdGEsIGFlcyh4ID0gYFBoeXNpY2FsIEFjdGl2aXR5IExldmVsYCwgeSA9IGBTbGVlcCBEdXJhdGlvbmApKSArDQogIGdlb21fY291bnQoY29sb3IgPSAiIzJjYTAyYyIsIGFscGhhID0gMC42KSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVFJVRSwgY29sb3IgPSAiI0MwMzkyQiIsIGZpbGwgPSAiI0U3NEMzQyIsIGFscGhhID0gMC4xNSkgKw0KICBzY2FsZV9zaXplX2FyZWEobWF4X3NpemUgPSA2KSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiUGh5c2ljYWwgQWN0aXZpdHkgdnMuIFNsZWVwIER1cmF0aW9uIiwNCiAgICB4ID0gIlBoeXNpY2FsIEFjdGl2aXR5IChtaW5zL2RheSkiLA0KICAgIHkgPSAiU2xlZXAgRHVyYXRpb24gKGhvdXJzKSIsDQogICAgc2l6ZSA9ICJDb3VudCINCiAgKQ0KZ3JpZC5hcnJhbmdlKHBfc2NhdHRlcjEsIHBfc2NhdHRlcjIsIG5jb2wgPSAyKQ0KYGBgDQoNCg0KYGBge3J9DQpgYGB7cn0NCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4NCg0KV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDdHJsK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuDQoNClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4=