Importing and Inspecting Data

path    <- "/Users/frenandezlawrence/Downloads/Fall_2022-2024_Firsttime_Fulltime_Cohort_data_with_Unmet_Need.xlsx"
sheets  <- excel_sheets(path)
sheets
[1] "Variables"                      "Fall 2022 Financial Aid"        "Fall 2022 Enrollment"           "Fall 2023 Financial Aid"        "Fall 2023 Enrollment"           "Fall 2024 Financial Aid Prelim"
[7] "Fall 2024 Enrollment Prelim"    "Data Dictionary"               

Standardizing Columns Header and Values

df_example <- read_xlsx(path, sheet = sheets[2]) %>%
  clean_names()
head(df_example)

#The below is used to standardize Dependency Status column to ensure that all three years represented using the same format.
dep_lookup <- c(
  "0" = "Unkn",
  "1" = "Dependent",
  "2" = "Independent",
  "3" = "Unkn"
)

#The below is used to standardize Race column to ensure that all three years represented using the same format.
race_text_to_code <- c(
  "African-American"= 1,
  "Native-American" = 2,
  "Asian"           = 3,
  "Hispanic"        = 4,
  "White"           = 5,
  "Native-Hawaiian" = 6,
  "Mulitracial"     = 7,
  "International"   = 8
)

Reading and Type Casting Cohort 2022 to ustilize as the standard for the additional cohorts

## Enrollment 2022 Data

enr22_raw <- read_xlsx(path, sheet = "Fall 2022 Enrollment")
enr22     <- enr22_raw %>%
clean_names() %>%
{ if (!"cip_code" %in% names(.)) mutate(., cip_code = NA_character_) else . } %>%
  mutate(
    study_id                              = as.character(study_id),
    zip_code                              = str_pad(as.character(zip_code), 5, "left", "0"),
    retained_fall2023                     = case_when(retained_fall2023  %in% c("Yes","Y","TRUE")   ~ TRUE,
                                            retained_fall2023  %in% c("No","N","FALSE")             ~ FALSE,
                                            TRUE                                                    ~ NA),
    casa_student                          = case_when(casa_student   %in% c("Yes","Y","TRUE")       ~ TRUE,
                                            casa_student   %in% c("No","N","FALSE")                 ~ FALSE,
                                            TRUE                                                    ~ NA),
    returned_spring2023                   = case_when(returned_spring2023 %in% c("Yes","Y","TRUE")  ~ TRUE,
                                            returned_spring2023 %in% c("No","N","FALSE")            ~ FALSE,
                                            TRUE                                                    ~ NA),
    gender                                = factor(gender, levels = c("F","M")),
    tuition_status                        = as.factor(tuition_status),
    newrace                               = case_when(
    newrace %in% names(race_text_to_code) ~ race_text_to_code[newrace],
            TRUE                          ~ as.numeric(newrace)),
  
    high_school_gpa                       = as.numeric(high_school_gpa),
    sat_2016_math_score                   = as.numeric(sat_2016_math_score),
    sat_2016_ebrw_score                   = as.numeric(sat_2016_ebrw_score),
    age                                   = as.integer(age),
    cip_code                              = as.character(cip_code),
    admission_test_flag                   = as.integer(admission_test_flag),,
    distance_education_enrollment         = as.integer(distance_education_enrollment),
    act_math_score                        = as.integer(act_math_score),
    act_english_score                     = as.integer(act_english_score),
    act_reading_score                     = as.integer(act_reading_score),
    act_science_score                     = as.integer(act_science_score),
    act_composite_score                   = as.integer(act_composite_score),
    admission_exemption                   = as.integer(admission_exemption),
    math_remedial_assessment              = as.integer(math_remedial_assessment),
    english_remedial_assessment           = as.integer(english_remedial_assessment),
    reading_remedial_assessment           = as.integer(reading_remedial_assessment),
    military_status                       = as.integer(military_status),
    majors                                = as.character(majors),
    term_credit_hours_attempted2022fall   = as.integer(term_credit_hours_attempted2022fall),
    semesterhoursearned2022fall           = as.integer(semesterhoursearned2022fall),
    cumulativegpa2022fall                 = as.numeric(cumulativegpa2022fall),
    term_credit_hours_attempted2023spring = as.integer(term_credit_hours_attempted2023spring),
    semesterhoursearned2023spring         = as.integer(semesterhoursearned2023spring),
    semestergpa2023spring                 = as.numeric(semestergpa2023spring),
    cumulativehoursearned2023spring       = as.integer(cumulativehoursearned2023spring),
    cumulativegpa2023spring               = as.numeric(cumulativegpa2023spring),
    college                               = as.character(college),
    collection_term                       = "Fall",
    collection_year                       = 2022
  )

## Financial Aid 2022 Data
fa22_raw <- read_xlsx(path, sheet = "Fall 2022 Financial Aid")
fa22     <- fa22_raw %>%
  clean_names() %>%
    transmute(
    study_id                              = as.character(study_id),
    family_size                           = as.integer(family_size),
    dependency_status                     = factor(dependency_status, levels = c("Dependent","Independent","Unkn")),
    expected_family_contribution          = as.numeric(expected_family_contribution),
    cost_of_attendance                    = as.numeric(cost_of_attendance),
    financial_aid_disbursement_amount     = as.numeric(financial_aid_disbursement_amount),
    pell_recipient                        = case_when(pell_recipient  %in% c("Yes","Y","TRUE")  ~ TRUE,
                                            pell_recipient  %in% c("No","N","FALSE")            ~ FALSE,
                                            TRUE                                                ~ NA),
    unmetneed_amount                      = as.numeric(unmetneed_amount),
    unmetneed_category                    = as.integer(unmetneed_category),
    family_income_category                = as.integer(family_income_category),
    first_generation                      = factor(first_generation, levels = c("Yes","No","Unkn"))
  )

cohort22 <- left_join(enr22, fa22, by = "study_id")

##Looping and Data Cleansing of All Three Cohorts

year_sheets <- tribble(
  ~year, ~fa_sheet,                         ~enr_sheet,
  2022,  "Fall 2022 Financial Aid",         "Fall 2022 Enrollment",
  2023,  "Fall 2023 Financial Aid",         "Fall 2023 Enrollment",
  2024,  "Fall 2024 Financial Aid Prelim",  "Fall 2024 Enrollment Prelim"
)

vars_raw      <- read_xlsx(path, sheet = "Variables", col_names = FALSE)
New names:
• `` -> `...1`
• `` -> `...2`
all_cohorts   <- purrr::pmap_dfr(
  .l = list(
    year      = year_sheets$year,
    fa_sheet  = year_sheets$fa_sheet,
    enr_sheet = year_sheets$enr_sheet),
  
  .f = function(year, fa_sheet, enr_sheet) {
    next_retained                    <- paste0("retained_fall", year + 1)
    next_returned                    <- paste0("returned_spring", year + 1)
    next_termcreditattemptedfall     <- paste0("term_credit_hours_attempted", year,"fall")
    next_semesterhoursearnedfall     <- paste0("semesterhoursearned", year,"fall")
    next_cumulativegpafall           <- paste0("cumulativegpa", year,"fall")
    next_termcreditattemptedspring   <- paste0("term_credit_hours_attempted", year + 1,"spring")
    next_semesterhoursearnedspring   <- paste0("semesterhoursearned", year + 1,"spring")
    next_semestergpaspring           <- paste0("semestergpa", year + 1,"spring")
    next_cumulativehoursearnedspring <- paste0("cumulativehoursearned", year + 1,"spring")
    next_cumulativegpaspring         <- paste0("cumulativegpa", year + 1,"spring")
    
#Enrollment Fields Cleaning 
    
    enr_raw <- read_xlsx(path, sheet = enr_sheet)
    enr     <- enr_raw %>%
    clean_names() %>%
{ if (!"cip_code" %in% names(.)) mutate(., cip_code = NA_character_) else . } %>%
  mutate(
    across(
      any_of(next_retained),
        ~ case_when(
          .x %in% c("Yes","Y","TRUE")  ~ TRUE,
          .x %in% c("No","N","FALSE")  ~ FALSE,
          TRUE                         ~ NA)),
    
    study_id                     = as.character(study_id),
    zip_code                     = str_pad(as.character(zip_code), 5, "left", "0"),
    casa_student                 = (casa_student      == "Yes"),
    across(
      any_of(next_retained),
        ~ case_when(
        .x %in% c("Yes","Y","TRUE")  ~ TRUE,
        .x %in% c("No","N","FALSE")  ~ FALSE,
        TRUE                         ~ NA)),
    gender                       = factor(gender, levels = c("F","M")),
    tuition_status               = factor(tolower(as.character(tuition_status))),
    newrace_str                  = as.character(newrace),
    newrace                      = if_else(
                                    newrace_str %in% names(race_text_to_code),
                                    race_text_to_code[newrace_str],
                                    as.numeric(newrace_str)),
    
    high_school_gpa               = as.numeric(high_school_gpa),
    sat_2016_math_score           = as.numeric(sat_2016_math_score),
    sat_2016_ebrw_score           = as.numeric(sat_2016_ebrw_score),
    age                           = as.integer(age),
    cip_code                      = as.character(cip_code),
    admission_test_flag           = as.integer(admission_test_flag),
    admission_exemption           = as.character(admission_exemption),
    distance_education_enrollment = as.integer(distance_education_enrollment),
    act_math_score                = as.integer(act_math_score),
    act_english_score             = as.integer(act_english_score),
    act_reading_score             = as.integer(act_reading_score),
    act_science_score             = as.integer(act_science_score),
    act_composite_score           = as.integer(act_composite_score),
    admission_exemption           = as.integer(admission_exemption),
    math_remedial_assessment      = as.integer(math_remedial_assessment),
    english_remedial_assessment   = as.integer(english_remedial_assessment),
    reading_remedial_assessment   = as.integer(reading_remedial_assessment),
    military_status               = as.integer(military_status),
    majors                        = as.character(majors),
    
#Handling of Dynamic Column Term Credit Attempted Fall 2022-2024
    across(any_of(next_termcreditattemptedfall),
          as.integer),

#Handling of Dynamic Column Semester Hours Earned Fall 2022-2024
    across(any_of(next_semesterhoursearnedfall),
          as.integer),
       
#Handling of Dynamic Column Cumulative GPA Fall 2022-2024
    across(any_of(next_cumulativegpafall ),
          ~ round(as.numeric(.x), 2)),
       
#Handling of Dynamic Column Term Credit Attempted Spring 2023-2025
    across(any_of(next_termcreditattemptedspring),
          as.integer),
       
#Handling of Dynamic Column Semester Hours Earned Spring 2023-2025
    across(any_of( next_semesterhoursearnedspring),
          as.integer),
       
#Handling of Dynamic Column GPA Spring 2023-2025
    across(any_of(next_semestergpaspring),
          ~ round(as.numeric(.x), 2)),
       
#Handling of Dynamic Column Cumulative Hours Earned Spring 2023-2025
    across(any_of(next_cumulativehoursearnedspring),
          as.integer),
       
#Handling of Dynamic Column Cumulative GPA Spring 2023-2025
    across(any_of(next_cumulativegpaspring ),
          ~ round(as.numeric(.x), 2)),
       
    college = as.character(college),
    collection_term     = "Fall",
    collection_year     = year)


#Enrollment Data Cleaning 
    fa_raw <- read_xlsx(path, sheet = fa_sheet)
    fa     <- fa_raw %>%
    clean_names() %>%
    transmute(
      study_id                          = as.character(study_id),
      family_size                       = as.integer(family_size),
      dependency_status                 = as.character(dependency_status),
        
#Mapping any numeric values using dep_lookup, Otherwise we will keep text
      dependency_status                 = if_else(
                                           dependency_status %in% names(dep_lookup),
                                           dep_lookup[dependency_status],
                                           dependency_status), 
      dependency_status                 = factor(
                                           dependency_status,
                                           levels = c("Dependent","Independent","Unkn")),
      expected_family_contribution      = as.numeric(expected_family_contribution),
      cost_of_attendance                = as.numeric(cost_of_attendance),
      financial_aid_disbursement_amount = as.numeric(financial_aid_disbursement_amount),
      pell_recipient                    = case_when(pell_recipient  %in% c("Yes","Y","TRUE")  ~ TRUE,
                                        pell_recipient  %in% c("No","N","FALSE")  ~ FALSE,
                                        TRUE                                             ~ NA),
      unmetneed_amount                  = as.numeric(unmetneed_amount),
      unmetneed_category                = as.integer(unmetneed_category),
      family_income_category            = as.integer(family_income_category),
      first_generation                  = factor(first_generation, levels = c("Yes","No","Unkn")))

#Joining and Returning the data
    df_year <- left_join(enr, fa, by = "study_id")%>%

#Filtering Out the Columns that have over 70% of data missing 
    select(
      -sat_2016_math_score,
      -sat_2016_ebrw_score,
      -act_math_score,
      -act_english_score,
      -act_reading_score,
      -act_science_score,
      -act_composite_score,
      -newrace_str) %>%  

    mutate(
      admission_exemption = as.character(admission_exemption),
      admission_exemption = coalesce(na_if(admission_exemption, ""), "1"),
      admission_exemption = as.integer(admission_exemption)) %>%
    
#Replacing blanks with 9 which represents race as unknown   
    mutate(
      newrace = as.character(newrace),
      newrace = coalesce(na_if(newrace, ""), "9"),
      newrace = as.integer(newrace)) %>%
  
  
#Handling Dependency Status Blanks
    mutate(
      dependency_status = as.character(dependency_status),
      dependency_status = coalesce(na_if(dependency_status, ""), "Unkn"),
      dependency_status = factor(dependency_status,levels = c("Dependent","Independent","Unkn"))) %>%

#Identifying, Replacing Outliers and Imputing Missing Values with Mean   
      mutate(
        across(
          c(expected_family_contribution, unmetneed_amount, cost_of_attendance, financial_aid_disbursement_amount, high_school_gpa,family_size),
          ~ {

#Computing the mean for each column on a yearly basis
            med    <- median(.x, na.rm = TRUE)
            
#Imputing Missing Values
            x0   <- if_else(is.na(.x), med, .x)
            
#Computing IQR Boundaries
            q    <- quantile(x0, c(0.25, 0.75), na.rm = TRUE)
            iqr  <- diff(q)
            lower <- q[1] - 1.5 * iqr
            upper <- q[2] + 1.5 * iqr
            
#Replacing outliers with the year’s mean
            ifelse(x0 < lower | x0 > upper, med, x0)
            }
            )
            ) %>%

#Dropping Records which are NA since it is less than 5% of data set
    filter(
      if_all(
        any_of(c(
          paste0("term_credit_hours_attempted",  year + 1, "spring"),
          paste0("semestergpa",                  year + 1, "spring"),
          paste0("cumulativehoursearned",        year + 1, "spring"),
          paste0("cumulativegpa",                year + 1, "spring")
          )),
          ~ !is.na(.x)
            )
          )
    
    
##The Below Lines of Codes represents lookup tables for varibales.
##For Numeric Variables a label has been created
##For Text Fields a Code has been created to used for modelling 
    
  family_inc_lookup             <- tibble(
  family_income_category        = 1:10,
  family_income_label           = c("Lowest Thru 25,000", "25,001 Thru 50,000", "50,001 Thru 75,000",
                                    "75,001 Thru 100,000", "100,001 Thru 125,000", "125,001 Thru 150,000",
                                    "150,001 Thru 175,000", "175,001 Thru 200,000", "200,001 Thru 225,000",
                                    "225,001+"))

  unmetneed_cat_lookup          <- tibble(
  unmetneed_category            = 1:7,
  unmetneed_category_label      = c("$1 Thru $5000", "$5001 Thru $7500", "$7501 Thru $10000",
                                    "$10001 Thru $15000", "$15001 Thru Highest", "No Unmet Need",
                                    "Unknown Unmet Need"))
  
  distance_edu_lookup           <- tibble(
  distance_education_enrollment = 1:3,
  distance_education_label      = c("Enrolled Exclusively in Distance Education", "Enrolled in Some but Not All Distance Education", "Not Enrolled in Any Distance Education"))
  
  admission_test_lookup         <- tibble(
  admission_test_flag           = 0:5,
  admission_test_flag_label     = c("No Test Required for Admission", "SAT Test Required", "ACT Test Required",
                                    "Either ACT or SAT Required", "Institution Test Required", "Because of Admission Exemption"))
  
  military_status_lookup        <- tibble(
  military_status               = 1:5,
  military_status_label         = c("Active Duty Member of Any of the US Uniform Forces", "Veteran or Former Active Duty Member of Any of The US Uniformed Forces", "Reserve Duty Member of Any of The US                                                Armed Forces, Including The National Guard", "Spouse or Dependent Child of an Active, Reserve, or Former Member of The US Uniformed Forces", "None of the above"))
  
  frace_lookup                  <- tibble(
  newrace                       = 1:9,
  race_label                    = c("African-Americans", "Native-Americans", "Asian",
                                    "Hispanic", "White", "Native-Hawaiians",
                                    "MultiRacials", "International","Unknown"))
    
  dependency_status_lookup      <- tibble(
  dependency_status             = c("Unkn", "Dependent","Independent"),
  dependency_code               = 0:2)
   
  gender_lookup                 <- tibble(
  gender                        = c("M","F"),
  gender_code                   = 1:2)
    
  
  tuition_status_lookup         <- tibble(
  tuition_status                = c("in-state", "out-of-state"),
  tuition_status_code           = 2:3)
   
   
  first_generation_lookup       <- tibble(
  first_generation             = c("No", "Yes", "Unkn"),
  first_generation_code         = c(0,1,9))

#Adding the Additional Columns to dataset   
  df_year <- df_year %>%
  left_join(family_inc_lookup,        by = "family_income_category") %>%
  left_join(unmetneed_cat_lookup,     by = "unmetneed_category") %>%
  left_join(distance_edu_lookup,      by = "distance_education_enrollment") %>%
  left_join(admission_test_lookup,    by = "admission_test_flag") %>%
  left_join(military_status_lookup,   by = "military_status") %>%
  left_join(frace_lookup,             by = "newrace") %>%
  left_join(dependency_status_lookup, by = "dependency_status")  %>%
  left_join(gender_lookup,            by = "gender")  %>%
  left_join(tuition_status_lookup,    by = "tuition_status")  %>%
  left_join(first_generation_lookup,  by = "first_generation") 

#Writing Each Year Data to A separate CSV to Upload to Tableau        
  file_name <- paste0("/Users/frenandezlawrence/Downloads/Team_B",year,"Cleaned_Data.csv")
  write.csv(df_year, file      = file_name, row.names = FALSE)

  df_year
  }
)

Performing Final Quality Checks on Merged Dataset

#Performing Uniqueness Check
  all_cohorts %>%
    count(collection_year, study_id) %>%
    filter(n > 1)

# Performing Missingness Check
  all_cohorts %>%
    summarise_all(~ mean(is.na(.))) %>%
    pivot_longer(everything(), names_to = "var", values_to = "pct_missing")

# Perfoming a final look at dataset
#The NAs displaying in the glimpse is for the dynamic columns which are not not applicable for all years. 
glimpse(all_cohorts)
Rows: 5,957
Columns: 70
$ collection_term                       <chr> "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fall", "Fal…
$ collection_year                       <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, …
$ study_id                              <chr> "20227000000002", "20227000000004", "20227000000005", "20227000000006", "20227000000007", "20227000000008", "20227000000010", "20227000000012", "20227000000…
$ gender                                <chr> "F", "F", "F", "M", "F", "M", "F", "M", "F", "M", "F", "M", "M", "F", "F", "M", "F", "M", "M", "M", "F", "M", "M", "F", "F", "M", "F", "F", "F", "F", "M", "…
$ zip_code                              <chr> "21220", "10500", "21045", "21085", "21217", "21244", "21212", "21043", "21206", "08000", "20708", "21040", "20695", "21117", "21218", "21500", "21213", "19…
$ tuition_status                        <chr> "out-of-state", "out-of-state", "in-state", "in-state", "in-state", "in-state", "in-state", "in-state", "in-state", "out-of-state", "in-state", "in-state", …
$ high_school_gpa                       <dbl> 2.29, 3.00, 3.10, 1.97, 4.00, 2.71, 2.80, 2.76, 2.72, 3.30, 2.35, 2.45, 3.04, 3.88, 3.00, 3.50, 2.84, 2.96, 3.19, 2.67, 3.65, 2.81, 3.10, 3.08, 3.65, 3.20, …
$ distance_education_enrollment         <int> 2, 2, 2, 2, 3, 2, 2, 3, 2, 2, 3, 3, 3, 3, 2, 2, 1, 3, 2, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 2, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 2, 3, 2, 3, …
$ admission_test_flag                   <int> 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 3, 5, 3, 5, …
$ admission_exemption                   <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ math_remedial_assessment              <int> 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, …
$ english_remedial_assessment           <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ reading_remedial_assessment           <int> 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, …
$ military_status                       <int> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, …
$ majors                                <chr> "NURS", "PSYC", "SOWK", "AREN", "SWAN", "MKTG", "SWAN", "COSC", "SOCI", "ACCT", "NURS", "ACCT", "HLTH", "SOWK", "PSYC", "BUAD", "SWAN", "AREN", "EEGR", "PHE…
$ cip_code                              <chr> "51.3801", "42.0101", "44.0701", "4.0902", "10.0304", "52.1401", "10.0304", "11.0101", "45.1101", "52.0301", "51.3801", "52.0301", "51.2207", "44.0701", "42…
$ age                                   <int> 29, 18, 23, 19, 18, 19, 22, 20, 20, 20, 20, 20, 20, 21, 23, 19, 19, 19, 19, 19, 18, 19, 19, 20, 18, 19, 18, 19, 17, 18, 19, 18, 19, 18, 18, 19, 18, 18, 18, …
$ newrace                               <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 5, 7, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, …
$ term_credit_hours_attempted2022fall   <int> 15, 14, 12, 16, 14, 13, 14, 15, 14, 15, 18, 16, 15, 14, 17, 15, 17, 17, 12, 15, 16, 16, 13, 16, 15, 16, 15, 14, 16, 16, 13, 13, 14, 16, 16, 16, 16, 16, 14, …
$ semesterhoursearned2022fall           <int> 15, 14, 12, 10, 14, 13, 14, 14, 13, 0, 18, 16, 15, 14, 17, 15, 17, 14, 12, 11, 16, 10, 13, 13, 15, 3, 11, 7, 12, 10, 13, 10, 14, 16, 10, 16, 16, 1, 14, 17, …
$ cumulativegpa2022fall                 <dbl> 3.36, 3.43, 3.67, 1.15, 3.40, 1.92, 4.00, 3.20, 2.70, 0.00, 2.64, 2.44, 2.20, 3.10, 4.00, 2.50, 4.00, 2.18, 3.67, 1.45, 3.58, 1.90, 1.92, 2.46, 2.73, 0.69, …
$ retained_fall2023                     <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TR…
$ casa_student                          <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FAL…
$ returned_spring2023                   <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Yes", "Y…
$ term_credit_hours_attempted2023spring <int> 16, 16, 15, 12, 15, 15, 13, 14, 13, 12, 14, 12, 17, 13, 18, 17, 13, 12, 16, 12, 13, 13, 14, 16, 15, 13, 14, 13, 8, 15, 16, 9, 14, 16, 13, 20, 15, 13, 16, 13…
$ semesterhoursearned2023spring         <int> 16, 16, 9, 6, 14, 9, 13, 0, 7, 0, 14, 12, 6, 13, 18, 14, 13, 8, 16, 3, 13, 13, 10, 3, 15, 3, 14, 7, 0, 6, 16, 6, 10, 16, 7, 20, 15, 3, 16, 13, 12, 3, 8, 16,…
$ semestergpa2023spring                 <dbl> 3.12, 2.81, 2.75, 1.00, 2.73, 1.80, 3.60, 0.00, 1.23, 0.00, 1.93, 2.50, 0.46, 3.08, 4.00, 2.79, 3.77, 3.00, 3.19, 0.00, 3.77, 2.77, 3.20, 0.60, 2.67, 0.46, …
$ cumulativehoursearned2023spring       <int> 31, 30, 21, 16, 30, 16, 27, 14, 20, 0, 32, 28, 21, 27, 35, 32, 30, 22, 53, 14, 29, 23, 23, 16, 30, 6, 22, 11, 12, 19, 29, 16, 24, 32, 20, 36, 31, 4, 33, 33,…
$ cumulativegpa2023spring               <dbl> 3.22, 3.10, 3.21, 1.23, 3.08, 2.09, 3.83, 3.43, 1.87, 0.00, 2.29, 2.46, 1.39, 3.09, 4.00, 2.62, 3.90, 2.53, 3.39, 0.94, 3.68, 2.39, 2.48, 1.65, 2.70, 0.75, …
$ college                               <chr> "SCHP", "CLA", "SOWK", "SAP", "CLA", "SBM", "CLA", "SCMNS", "CLA", "SBM", "SCHP", "SBM", "SCHP", "SOWK", "CLA", "SBM", "CLA", "SAP", "SOE", "SEUS", "SCHP", …
$ family_size                           <dbl> 2, 3, 3, 3, 6, 2, 2, 4, 3, 2, 3, 3, 4, 3, 1, 3, 5, 5, 2, 2, 3, 4, 4, 3, 3, 1, 3, 6, 4, 3, 4, 2, 4, 3, 4, 2, 2, 4, 3, 6, 4, 2, 3, 2, 6, 3, 2, 3, 2, 3, 6, 4, …
$ dependency_status                     <chr> "Independent", "Dependent", "Unkn", "Independent", "Dependent", "Dependent", "Independent", "Dependent", "Dependent", "Dependent", "Dependent", "Dependent",…
$ expected_family_contribution          <dbl> 0, 6451, 2469, 2789, 15651, 0, 0, 26802, 0, 6443, 448, 0, 709, 12127, 0, 2469, 928, 2469, 1350, 10447, 10490, 0, 24413, 0, 0, 0, 9900, 0, 5483, 2469, 2469, …
$ cost_of_attendance                    <dbl> 39589, 39533, 38249, 39552, 29061, 39589, 39552, 29061, 21229, 39533, 27777, 27777, 38249, 29061, 29117, 24802, 21229, 39533, 29080, 39533, 39533, 38249, 29…
$ financial_aid_disbursement_amount     <dbl> 19797.0, 10444.0, 17910.5, 6845.0, 19872.0, 9695.0, 9409.0, 3000.0, 11359.0, 37021.0, 18447.0, 20297.0, 10145.0, 7444.0, 6895.0, 19623.0, 13289.0, 30358.0, …
$ pell_recipient                        <lgl> TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, TRUE, T…
$ unmetneed_amount                      <dbl> 19792.0, 22638.0, 8394.5, 29918.0, -6462.0, 29894.0, 30143.0, -741.0, 9870.0, -3931.0, 8882.0, 7480.0, 27395.0, 9490.0, 22222.0, 8394.5, 7012.0, 8394.5, 191…
$ unmetneed_category                    <int> 5, 5, 7, 5, 6, 5, 5, 6, 3, 6, 3, 2, 5, 3, 5, 7, 2, 6, 5, 1, 6, 1, 6, 5, 4, 4, 6, 6, 5, 6, 6, 6, 5, 4, 6, 6, 1, 6, 6, 6, 6, 1, 6, 3, 5, 4, 6, 6, 5, 4, 3, 5, …
$ family_income_category                <int> 2, 3, 10, 2, 7, 1, 1, 8, 2, 3, 3, 1, 1, 4, 10, 10, 3, 9, 2, 3, 3, 2, 5, 1, 2, 10, 3, 2, 3, 9, 9, 2, 1, 3, 9, 6, 1, 1, 5, 9, 8, 2, 2, 2, 3, 3, 6, 7, 4, 2, 3,…
$ first_generation                      <chr> "Yes", "Yes", "Yes", "No", "No", "Yes", "Yes", "No", "No", "No", "No", "Yes", "Yes", "No", "No", "Yes", "No", "No", "No", "No", "No", "Yes", "No", "Yes", "Y…
$ family_income_label                   <chr> "25,001 Thru 50,000", "50,001 Thru 75,000", "225,001+", "25,001 Thru 50,000", "150,001 Thru 175,000", "Lowest Thru 25,000", "Lowest Thru 25,000", "175,001 T…
$ unmetneed_category_label              <chr> "$15001 Thru Highest", "$15001 Thru Highest", "Unknown Unmet Need", "$15001 Thru Highest", "No Unmet Need", "$15001 Thru Highest", "$15001 Thru Highest", "N…
$ distance_education_label              <chr> "Enrolled in Some but Not All Distance Education", "Enrolled in Some but Not All Distance Education", "Enrolled in Some but Not All Distance Education", "En…
$ admission_test_flag_label             <chr> "Because of Admission Exemption", "Because of Admission Exemption", "Because of Admission Exemption", "Either ACT or SAT Required", "Because of Admission Ex…
$ military_status_label                 <chr> "None of the above", "None of the above", "None of the above", "None of the above", "None of the above", "None of the above", "None of the above", "None of …
$ race_label                            <chr> "African-Americans", "African-Americans", "African-Americans", "African-Americans", "African-Americans", "African-Americans", "African-Americans", "African-…
$ dependency_code                       <int> 2, 1, 0, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, …
$ gender_code                           <int> 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, …
$ tuition_status_code                   <int> 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 3, 2, 2, 2, 2, 3, 2, 3, 3, 3, 2, 3, 2, 2, 3, 2, 3, 3, 2, 3, 2, 3, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 2, 2, 2, 2, …
$ first_generation_code                 <dbl> 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, …
$ term_credit_hours_attempted2023fall   <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ semester_hoursearned2023fall          <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ cumulativegpa2023fall                 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ retained_fall2024                     <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ returned_in_2024spring                <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ term_credit_hours_attempted2024spring <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ semesterhoursearned2024spring         <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ semestergpa2024spring                 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ cumulativehoursearned2024spring       <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ cumulativegpa2024spring               <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ currenthoursattempted2024fall         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ semesterhoursearned2024fall           <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ cgpa2024fall                          <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ retained_fall2025                     <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ returned_spring2025                   <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ currenthoursattempted2025spring       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ semesterhoursearned2025spring         <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ semestergpa2025spring                 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ cumulativehoursearned2025spring       <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
$ cumulativegpa2025spring               <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …

Exporting Clean and Merge Data for Internal Analysis

write.csv(all_cohorts,
           file      = "/Users/frenandezlawrence/Downloads/Team_B_Cleaned_Cohort_Data_2022_2024.csv",
        row.names = FALSE)
LS0tCnRpdGxlOiAiVGVhbSBCIENsZWFuaW5nIFNjcmlwdCBmb3IgRmFsbCAyMDIy4oCTMjAyNCBDb2hvcnQgRGF0YSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpCmxpYnJhcnkocmVhZHhsKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGphbml0b3IpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShwdXJycikKbGlicmFyeSh0aWJibGUpCmxpYnJhcnkobmFuaWFyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KHdyaXRleGwpCmBgYAoKIyMgSW1wb3J0aW5nIGFuZCBJbnNwZWN0aW5nIERhdGEKCmBgYHtyfQpwYXRoICAgIDwtICIvVXNlcnMvZnJlbmFuZGV6bGF3cmVuY2UvRG93bmxvYWRzL0ZhbGxfMjAyMi0yMDI0X0ZpcnN0dGltZV9GdWxsdGltZV9Db2hvcnRfZGF0YV93aXRoX1VubWV0X05lZWQueGxzeCIKc2hlZXRzICA8LSBleGNlbF9zaGVldHMocGF0aCkKc2hlZXRzCmBgYAoKIyMgU3RhbmRhcmRpemluZyBDb2x1bW5zIEhlYWRlciBhbmQgVmFsdWVzIAoKYGBge3J9CmRmX2V4YW1wbGUgPC0gcmVhZF94bHN4KHBhdGgsIHNoZWV0ID0gc2hlZXRzWzJdKSAlPiUKICBjbGVhbl9uYW1lcygpCmhlYWQoZGZfZXhhbXBsZSkKCiNUaGUgYmVsb3cgaXMgdXNlZCB0byBzdGFuZGFyZGl6ZSBEZXBlbmRlbmN5IFN0YXR1cyBjb2x1bW4gdG8gZW5zdXJlIHRoYXQgYWxsIHRocmVlIHllYXJzIHJlcHJlc2VudGVkIHVzaW5nIHRoZSBzYW1lIGZvcm1hdC4KZGVwX2xvb2t1cCA8LSBjKAogICIwIiA9ICJVbmtuIiwKICAiMSIgPSAiRGVwZW5kZW50IiwKICAiMiIgPSAiSW5kZXBlbmRlbnQiLAogICIzIiA9ICJVbmtuIgopCgojVGhlIGJlbG93IGlzIHVzZWQgdG8gc3RhbmRhcmRpemUgUmFjZSBjb2x1bW4gdG8gZW5zdXJlIHRoYXQgYWxsIHRocmVlIHllYXJzIHJlcHJlc2VudGVkIHVzaW5nIHRoZSBzYW1lIGZvcm1hdC4KcmFjZV90ZXh0X3RvX2NvZGUgPC0gYygKICAiQWZyaWNhbi1BbWVyaWNhbiI9IDEsCiAgIk5hdGl2ZS1BbWVyaWNhbiIgPSAyLAogICJBc2lhbiIgICAgICAgICAgID0gMywKICAiSGlzcGFuaWMiICAgICAgICA9IDQsCiAgIldoaXRlIiAgICAgICAgICAgPSA1LAogICJOYXRpdmUtSGF3YWlpYW4iID0gNiwKICAiTXVsaXRyYWNpYWwiICAgICA9IDcsCiAgIkludGVybmF0aW9uYWwiICAgPSA4CikKYGBgCgojIyBSZWFkaW5nIGFuZCBUeXBlIENhc3RpbmcgQ29ob3J0IDIwMjIgdG8gdXN0aWxpemUgYXMgdGhlIHN0YW5kYXJkIGZvciB0aGUgYWRkaXRpb25hbCBjb2hvcnRzCgpgYGB7cn0KIyMgRW5yb2xsbWVudCAyMDIyIERhdGEKCmVucjIyX3JhdyA8LSByZWFkX3hsc3gocGF0aCwgc2hlZXQgPSAiRmFsbCAyMDIyIEVucm9sbG1lbnQiKQplbnIyMiAgICAgPC0gZW5yMjJfcmF3ICU+JQpjbGVhbl9uYW1lcygpICU+JQp7IGlmICghImNpcF9jb2RlIiAlaW4lIG5hbWVzKC4pKSBtdXRhdGUoLiwgY2lwX2NvZGUgPSBOQV9jaGFyYWN0ZXJfKSBlbHNlIC4gfSAlPiUKICBtdXRhdGUoCiAgICBzdHVkeV9pZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXMuY2hhcmFjdGVyKHN0dWR5X2lkKSwKICAgIHppcF9jb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBzdHJfcGFkKGFzLmNoYXJhY3Rlcih6aXBfY29kZSksIDUsICJsZWZ0IiwgIjAiKSwKICAgIHJldGFpbmVkX2ZhbGwyMDIzICAgICAgICAgICAgICAgICAgICAgPSBjYXNlX3doZW4ocmV0YWluZWRfZmFsbDIwMjMgICVpbiUgYygiWWVzIiwiWSIsIlRSVUUiKSAgIH4gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRhaW5lZF9mYWxsMjAyMyAgJWluJSBjKCJObyIsIk4iLCJGQUxTRSIpICAgICAgICAgICAgIH4gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+IE5BKSwKICAgIGNhc2Ffc3R1ZGVudCAgICAgICAgICAgICAgICAgICAgICAgICAgPSBjYXNlX3doZW4oY2FzYV9zdHVkZW50ICAgJWluJSBjKCJZZXMiLCJZIiwiVFJVRSIpICAgICAgIH4gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNhX3N0dWRlbnQgICAlaW4lIGMoIk5vIiwiTiIsIkZBTFNFIikgICAgICAgICAgICAgICAgIH4gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+IE5BKSwKICAgIHJldHVybmVkX3NwcmluZzIwMjMgICAgICAgICAgICAgICAgICAgPSBjYXNlX3doZW4ocmV0dXJuZWRfc3ByaW5nMjAyMyAlaW4lIGMoIlllcyIsIlkiLCJUUlVFIikgIH4gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5lZF9zcHJpbmcyMDIzICVpbiUgYygiTm8iLCJOIiwiRkFMU0UiKSAgICAgICAgICAgIH4gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+IE5BKSwKICAgIGdlbmRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBmYWN0b3IoZ2VuZGVyLCBsZXZlbHMgPSBjKCJGIiwiTSIpKSwKICAgIHR1aXRpb25fc3RhdHVzICAgICAgICAgICAgICAgICAgICAgICAgPSBhcy5mYWN0b3IodHVpdGlvbl9zdGF0dXMpLAogICAgbmV3cmFjZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGNhc2Vfd2hlbigKICAgIG5ld3JhY2UgJWluJSBuYW1lcyhyYWNlX3RleHRfdG9fY29kZSkgfiByYWNlX3RleHRfdG9fY29kZVtuZXdyYWNlXSwKICAgICAgICAgICAgVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICAgfiBhcy5udW1lcmljKG5ld3JhY2UpKSwKICAKICAgIGhpZ2hfc2Nob29sX2dwYSAgICAgICAgICAgICAgICAgICAgICAgPSBhcy5udW1lcmljKGhpZ2hfc2Nob29sX2dwYSksCiAgICBzYXRfMjAxNl9tYXRoX3Njb3JlICAgICAgICAgICAgICAgICAgID0gYXMubnVtZXJpYyhzYXRfMjAxNl9tYXRoX3Njb3JlKSwKICAgIHNhdF8yMDE2X2Vicndfc2NvcmUgICAgICAgICAgICAgICAgICAgPSBhcy5udW1lcmljKHNhdF8yMDE2X2Vicndfc2NvcmUpLAogICAgYWdlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWdlKSwKICAgIGNpcF9jb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBhcy5jaGFyYWN0ZXIoY2lwX2NvZGUpLAogICAgYWRtaXNzaW9uX3Rlc3RfZmxhZyAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWRtaXNzaW9uX3Rlc3RfZmxhZyksLAogICAgZGlzdGFuY2VfZWR1Y2F0aW9uX2Vucm9sbG1lbnQgICAgICAgICA9IGFzLmludGVnZXIoZGlzdGFuY2VfZWR1Y2F0aW9uX2Vucm9sbG1lbnQpLAogICAgYWN0X21hdGhfc2NvcmUgICAgICAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X21hdGhfc2NvcmUpLAogICAgYWN0X2VuZ2xpc2hfc2NvcmUgICAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X2VuZ2xpc2hfc2NvcmUpLAogICAgYWN0X3JlYWRpbmdfc2NvcmUgICAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X3JlYWRpbmdfc2NvcmUpLAogICAgYWN0X3NjaWVuY2Vfc2NvcmUgICAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X3NjaWVuY2Vfc2NvcmUpLAogICAgYWN0X2NvbXBvc2l0ZV9zY29yZSAgICAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X2NvbXBvc2l0ZV9zY29yZSksCiAgICBhZG1pc3Npb25fZXhlbXB0aW9uICAgICAgICAgICAgICAgICAgID0gYXMuaW50ZWdlcihhZG1pc3Npb25fZXhlbXB0aW9uKSwKICAgIG1hdGhfcmVtZWRpYWxfYXNzZXNzbWVudCAgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKG1hdGhfcmVtZWRpYWxfYXNzZXNzbWVudCksCiAgICBlbmdsaXNoX3JlbWVkaWFsX2Fzc2Vzc21lbnQgICAgICAgICAgID0gYXMuaW50ZWdlcihlbmdsaXNoX3JlbWVkaWFsX2Fzc2Vzc21lbnQpLAogICAgcmVhZGluZ19yZW1lZGlhbF9hc3Nlc3NtZW50ICAgICAgICAgICA9IGFzLmludGVnZXIocmVhZGluZ19yZW1lZGlhbF9hc3Nlc3NtZW50KSwKICAgIG1pbGl0YXJ5X3N0YXR1cyAgICAgICAgICAgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKG1pbGl0YXJ5X3N0YXR1cyksCiAgICBtYWpvcnMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXMuY2hhcmFjdGVyKG1ham9ycyksCiAgICB0ZXJtX2NyZWRpdF9ob3Vyc19hdHRlbXB0ZWQyMDIyZmFsbCAgID0gYXMuaW50ZWdlcih0ZXJtX2NyZWRpdF9ob3Vyc19hdHRlbXB0ZWQyMDIyZmFsbCksCiAgICBzZW1lc3RlcmhvdXJzZWFybmVkMjAyMmZhbGwgICAgICAgICAgID0gYXMuaW50ZWdlcihzZW1lc3RlcmhvdXJzZWFybmVkMjAyMmZhbGwpLAogICAgY3VtdWxhdGl2ZWdwYTIwMjJmYWxsICAgICAgICAgICAgICAgICA9IGFzLm51bWVyaWMoY3VtdWxhdGl2ZWdwYTIwMjJmYWxsKSwKICAgIHRlcm1fY3JlZGl0X2hvdXJzX2F0dGVtcHRlZDIwMjNzcHJpbmcgPSBhcy5pbnRlZ2VyKHRlcm1fY3JlZGl0X2hvdXJzX2F0dGVtcHRlZDIwMjNzcHJpbmcpLAogICAgc2VtZXN0ZXJob3Vyc2Vhcm5lZDIwMjNzcHJpbmcgICAgICAgICA9IGFzLmludGVnZXIoc2VtZXN0ZXJob3Vyc2Vhcm5lZDIwMjNzcHJpbmcpLAogICAgc2VtZXN0ZXJncGEyMDIzc3ByaW5nICAgICAgICAgICAgICAgICA9IGFzLm51bWVyaWMoc2VtZXN0ZXJncGEyMDIzc3ByaW5nKSwKICAgIGN1bXVsYXRpdmVob3Vyc2Vhcm5lZDIwMjNzcHJpbmcgICAgICAgPSBhcy5pbnRlZ2VyKGN1bXVsYXRpdmVob3Vyc2Vhcm5lZDIwMjNzcHJpbmcpLAogICAgY3VtdWxhdGl2ZWdwYTIwMjNzcHJpbmcgICAgICAgICAgICAgICA9IGFzLm51bWVyaWMoY3VtdWxhdGl2ZWdwYTIwMjNzcHJpbmcpLAogICAgY29sbGVnZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGFzLmNoYXJhY3Rlcihjb2xsZWdlKSwKICAgIGNvbGxlY3Rpb25fdGVybSAgICAgICAgICAgICAgICAgICAgICAgPSAiRmFsbCIsCiAgICBjb2xsZWN0aW9uX3llYXIgICAgICAgICAgICAgICAgICAgICAgID0gMjAyMgogICkKCiMjIEZpbmFuY2lhbCBBaWQgMjAyMiBEYXRhCmZhMjJfcmF3IDwtIHJlYWRfeGxzeChwYXRoLCBzaGVldCA9ICJGYWxsIDIwMjIgRmluYW5jaWFsIEFpZCIpCmZhMjIgICAgIDwtIGZhMjJfcmF3ICU+JQogIGNsZWFuX25hbWVzKCkgJT4lCiAgICB0cmFuc211dGUoCiAgICBzdHVkeV9pZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXMuY2hhcmFjdGVyKHN0dWR5X2lkKSwKICAgIGZhbWlseV9zaXplICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKGZhbWlseV9zaXplKSwKICAgIGRlcGVuZGVuY3lfc3RhdHVzICAgICAgICAgICAgICAgICAgICAgPSBmYWN0b3IoZGVwZW5kZW5jeV9zdGF0dXMsIGxldmVscyA9IGMoIkRlcGVuZGVudCIsIkluZGVwZW5kZW50IiwiVW5rbiIpKSwKICAgIGV4cGVjdGVkX2ZhbWlseV9jb250cmlidXRpb24gICAgICAgICAgPSBhcy5udW1lcmljKGV4cGVjdGVkX2ZhbWlseV9jb250cmlidXRpb24pLAogICAgY29zdF9vZl9hdHRlbmRhbmNlICAgICAgICAgICAgICAgICAgICA9IGFzLm51bWVyaWMoY29zdF9vZl9hdHRlbmRhbmNlKSwKICAgIGZpbmFuY2lhbF9haWRfZGlzYnVyc2VtZW50X2Ftb3VudCAgICAgPSBhcy5udW1lcmljKGZpbmFuY2lhbF9haWRfZGlzYnVyc2VtZW50X2Ftb3VudCksCiAgICBwZWxsX3JlY2lwaWVudCAgICAgICAgICAgICAgICAgICAgICAgID0gY2FzZV93aGVuKHBlbGxfcmVjaXBpZW50ICAlaW4lIGMoIlllcyIsIlkiLCJUUlVFIikgIH4gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWxsX3JlY2lwaWVudCAgJWluJSBjKCJObyIsIk4iLCJGQUxTRSIpICAgICAgICAgICAgfiBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfiBOQSksCiAgICB1bm1ldG5lZWRfYW1vdW50ICAgICAgICAgICAgICAgICAgICAgID0gYXMubnVtZXJpYyh1bm1ldG5lZWRfYW1vdW50KSwKICAgIHVubWV0bmVlZF9jYXRlZ29yeSAgICAgICAgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKHVubWV0bmVlZF9jYXRlZ29yeSksCiAgICBmYW1pbHlfaW5jb21lX2NhdGVnb3J5ICAgICAgICAgICAgICAgID0gYXMuaW50ZWdlcihmYW1pbHlfaW5jb21lX2NhdGVnb3J5KSwKICAgIGZpcnN0X2dlbmVyYXRpb24gICAgICAgICAgICAgICAgICAgICAgPSBmYWN0b3IoZmlyc3RfZ2VuZXJhdGlvbiwgbGV2ZWxzID0gYygiWWVzIiwiTm8iLCJVbmtuIikpCiAgKQoKY29ob3J0MjIgPC0gbGVmdF9qb2luKGVucjIyLCBmYTIyLCBieSA9ICJzdHVkeV9pZCIpCmBgYAoKIyNMb29waW5nIGFuZCBEYXRhIENsZWFuc2luZyBvZiBBbGwgVGhyZWUgQ29ob3J0cyAKCmBgYHtyfQp5ZWFyX3NoZWV0cyA8LSB0cmliYmxlKAogIH55ZWFyLCB+ZmFfc2hlZXQsICAgICAgICAgICAgICAgICAgICAgICAgIH5lbnJfc2hlZXQsCiAgMjAyMiwgICJGYWxsIDIwMjIgRmluYW5jaWFsIEFpZCIsICAgICAgICAgIkZhbGwgMjAyMiBFbnJvbGxtZW50IiwKICAyMDIzLCAgIkZhbGwgMjAyMyBGaW5hbmNpYWwgQWlkIiwgICAgICAgICAiRmFsbCAyMDIzIEVucm9sbG1lbnQiLAogIDIwMjQsICAiRmFsbCAyMDI0IEZpbmFuY2lhbCBBaWQgUHJlbGltIiwgICJGYWxsIDIwMjQgRW5yb2xsbWVudCBQcmVsaW0iCikKCnZhcnNfcmF3ICAgICAgPC0gcmVhZF94bHN4KHBhdGgsIHNoZWV0ID0gIlZhcmlhYmxlcyIsIGNvbF9uYW1lcyA9IEZBTFNFKQoKYWxsX2NvaG9ydHMgICA8LSBwdXJycjo6cG1hcF9kZnIoCiAgLmwgPSBsaXN0KAogICAgeWVhciAgICAgID0geWVhcl9zaGVldHMkeWVhciwKICAgIGZhX3NoZWV0ICA9IHllYXJfc2hlZXRzJGZhX3NoZWV0LAogICAgZW5yX3NoZWV0ID0geWVhcl9zaGVldHMkZW5yX3NoZWV0KSwKICAKICAuZiA9IGZ1bmN0aW9uKHllYXIsIGZhX3NoZWV0LCBlbnJfc2hlZXQpIHsKICAgIG5leHRfcmV0YWluZWQgICAgICAgICAgICAgICAgICAgIDwtIHBhc3RlMCgicmV0YWluZWRfZmFsbCIsIHllYXIgKyAxKQogICAgbmV4dF9yZXR1cm5lZCAgICAgICAgICAgICAgICAgICAgPC0gcGFzdGUwKCJyZXR1cm5lZF9zcHJpbmciLCB5ZWFyICsgMSkKICAgIG5leHRfdGVybWNyZWRpdGF0dGVtcHRlZGZhbGwgICAgIDwtIHBhc3RlMCgidGVybV9jcmVkaXRfaG91cnNfYXR0ZW1wdGVkIiwgeWVhciwiZmFsbCIpCiAgICBuZXh0X3NlbWVzdGVyaG91cnNlYXJuZWRmYWxsICAgICA8LSBwYXN0ZTAoInNlbWVzdGVyaG91cnNlYXJuZWQiLCB5ZWFyLCJmYWxsIikKICAgIG5leHRfY3VtdWxhdGl2ZWdwYWZhbGwgICAgICAgICAgIDwtIHBhc3RlMCgiY3VtdWxhdGl2ZWdwYSIsIHllYXIsImZhbGwiKQogICAgbmV4dF90ZXJtY3JlZGl0YXR0ZW1wdGVkc3ByaW5nICAgPC0gcGFzdGUwKCJ0ZXJtX2NyZWRpdF9ob3Vyc19hdHRlbXB0ZWQiLCB5ZWFyICsgMSwic3ByaW5nIikKICAgIG5leHRfc2VtZXN0ZXJob3Vyc2Vhcm5lZHNwcmluZyAgIDwtIHBhc3RlMCgic2VtZXN0ZXJob3Vyc2Vhcm5lZCIsIHllYXIgKyAxLCJzcHJpbmciKQogICAgbmV4dF9zZW1lc3RlcmdwYXNwcmluZyAgICAgICAgICAgPC0gcGFzdGUwKCJzZW1lc3RlcmdwYSIsIHllYXIgKyAxLCJzcHJpbmciKQogICAgbmV4dF9jdW11bGF0aXZlaG91cnNlYXJuZWRzcHJpbmcgPC0gcGFzdGUwKCJjdW11bGF0aXZlaG91cnNlYXJuZWQiLCB5ZWFyICsgMSwic3ByaW5nIikKICAgIG5leHRfY3VtdWxhdGl2ZWdwYXNwcmluZyAgICAgICAgIDwtIHBhc3RlMCgiY3VtdWxhdGl2ZWdwYSIsIHllYXIgKyAxLCJzcHJpbmciKQogICAgCiNFbnJvbGxtZW50IEZpZWxkcyBDbGVhbmluZyAKICAgIAogICAgZW5yX3JhdyA8LSByZWFkX3hsc3gocGF0aCwgc2hlZXQgPSBlbnJfc2hlZXQpCiAgICBlbnIgICAgIDwtIGVucl9yYXcgJT4lCiAgICBjbGVhbl9uYW1lcygpICU+JQp7IGlmICghImNpcF9jb2RlIiAlaW4lIG5hbWVzKC4pKSBtdXRhdGUoLiwgY2lwX2NvZGUgPSBOQV9jaGFyYWN0ZXJfKSBlbHNlIC4gfSAlPiUKICBtdXRhdGUoCiAgICBhY3Jvc3MoCiAgICAgIGFueV9vZihuZXh0X3JldGFpbmVkKSwKICAgICAgICB+IGNhc2Vfd2hlbigKICAgICAgICAgIC54ICVpbiUgYygiWWVzIiwiWSIsIlRSVUUiKSAgfiBUUlVFLAogICAgICAgICAgLnggJWluJSBjKCJObyIsIk4iLCJGQUxTRSIpICB+IEZBTFNFLAogICAgICAgICAgVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICB+IE5BKSksCiAgICAKICAgIHN0dWR5X2lkICAgICAgICAgICAgICAgICAgICAgPSBhcy5jaGFyYWN0ZXIoc3R1ZHlfaWQpLAogICAgemlwX2NvZGUgICAgICAgICAgICAgICAgICAgICA9IHN0cl9wYWQoYXMuY2hhcmFjdGVyKHppcF9jb2RlKSwgNSwgImxlZnQiLCAiMCIpLAogICAgY2FzYV9zdHVkZW50ICAgICAgICAgICAgICAgICA9IChjYXNhX3N0dWRlbnQgICAgICA9PSAiWWVzIiksCiAgICBhY3Jvc3MoCiAgICAgIGFueV9vZihuZXh0X3JldGFpbmVkKSwKICAgICAgICB+IGNhc2Vfd2hlbigKICAgICAgICAueCAlaW4lIGMoIlllcyIsIlkiLCJUUlVFIikgIH4gVFJVRSwKICAgICAgICAueCAlaW4lIGMoIk5vIiwiTiIsIkZBTFNFIikgIH4gRkFMU0UsCiAgICAgICAgVFJVRSAgICAgICAgICAgICAgICAgICAgICAgICB+IE5BKSksCiAgICBnZW5kZXIgICAgICAgICAgICAgICAgICAgICAgID0gZmFjdG9yKGdlbmRlciwgbGV2ZWxzID0gYygiRiIsIk0iKSksCiAgICB0dWl0aW9uX3N0YXR1cyAgICAgICAgICAgICAgID0gZmFjdG9yKHRvbG93ZXIoYXMuY2hhcmFjdGVyKHR1aXRpb25fc3RhdHVzKSkpLAogICAgbmV3cmFjZV9zdHIgICAgICAgICAgICAgICAgICA9IGFzLmNoYXJhY3RlcihuZXdyYWNlKSwKICAgIG5ld3JhY2UgICAgICAgICAgICAgICAgICAgICAgPSBpZl9lbHNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdyYWNlX3N0ciAlaW4lIG5hbWVzKHJhY2VfdGV4dF90b19jb2RlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFjZV90ZXh0X3RvX2NvZGVbbmV3cmFjZV9zdHJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcy5udW1lcmljKG5ld3JhY2Vfc3RyKSksCiAgICAKICAgIGhpZ2hfc2Nob29sX2dwYSAgICAgICAgICAgICAgID0gYXMubnVtZXJpYyhoaWdoX3NjaG9vbF9ncGEpLAogICAgc2F0XzIwMTZfbWF0aF9zY29yZSAgICAgICAgICAgPSBhcy5udW1lcmljKHNhdF8yMDE2X21hdGhfc2NvcmUpLAogICAgc2F0XzIwMTZfZWJyd19zY29yZSAgICAgICAgICAgPSBhcy5udW1lcmljKHNhdF8yMDE2X2Vicndfc2NvcmUpLAogICAgYWdlICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKGFnZSksCiAgICBjaXBfY29kZSAgICAgICAgICAgICAgICAgICAgICA9IGFzLmNoYXJhY3RlcihjaXBfY29kZSksCiAgICBhZG1pc3Npb25fdGVzdF9mbGFnICAgICAgICAgICA9IGFzLmludGVnZXIoYWRtaXNzaW9uX3Rlc3RfZmxhZyksCiAgICBhZG1pc3Npb25fZXhlbXB0aW9uICAgICAgICAgICA9IGFzLmNoYXJhY3RlcihhZG1pc3Npb25fZXhlbXB0aW9uKSwKICAgIGRpc3RhbmNlX2VkdWNhdGlvbl9lbnJvbGxtZW50ID0gYXMuaW50ZWdlcihkaXN0YW5jZV9lZHVjYXRpb25fZW5yb2xsbWVudCksCiAgICBhY3RfbWF0aF9zY29yZSAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X21hdGhfc2NvcmUpLAogICAgYWN0X2VuZ2xpc2hfc2NvcmUgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKGFjdF9lbmdsaXNoX3Njb3JlKSwKICAgIGFjdF9yZWFkaW5nX3Njb3JlICAgICAgICAgICAgID0gYXMuaW50ZWdlcihhY3RfcmVhZGluZ19zY29yZSksCiAgICBhY3Rfc2NpZW5jZV9zY29yZSAgICAgICAgICAgICA9IGFzLmludGVnZXIoYWN0X3NjaWVuY2Vfc2NvcmUpLAogICAgYWN0X2NvbXBvc2l0ZV9zY29yZSAgICAgICAgICAgPSBhcy5pbnRlZ2VyKGFjdF9jb21wb3NpdGVfc2NvcmUpLAogICAgYWRtaXNzaW9uX2V4ZW1wdGlvbiAgICAgICAgICAgPSBhcy5pbnRlZ2VyKGFkbWlzc2lvbl9leGVtcHRpb24pLAogICAgbWF0aF9yZW1lZGlhbF9hc3Nlc3NtZW50ICAgICAgPSBhcy5pbnRlZ2VyKG1hdGhfcmVtZWRpYWxfYXNzZXNzbWVudCksCiAgICBlbmdsaXNoX3JlbWVkaWFsX2Fzc2Vzc21lbnQgICA9IGFzLmludGVnZXIoZW5nbGlzaF9yZW1lZGlhbF9hc3Nlc3NtZW50KSwKICAgIHJlYWRpbmdfcmVtZWRpYWxfYXNzZXNzbWVudCAgID0gYXMuaW50ZWdlcihyZWFkaW5nX3JlbWVkaWFsX2Fzc2Vzc21lbnQpLAogICAgbWlsaXRhcnlfc3RhdHVzICAgICAgICAgICAgICAgPSBhcy5pbnRlZ2VyKG1pbGl0YXJ5X3N0YXR1cyksCiAgICBtYWpvcnMgICAgICAgICAgICAgICAgICAgICAgICA9IGFzLmNoYXJhY3RlcihtYWpvcnMpLAogICAgCiNIYW5kbGluZyBvZiBEeW5hbWljIENvbHVtbiBUZXJtIENyZWRpdCBBdHRlbXB0ZWQgRmFsbCAyMDIyLTIwMjQKICAgIGFjcm9zcyhhbnlfb2YobmV4dF90ZXJtY3JlZGl0YXR0ZW1wdGVkZmFsbCksCiAgICAgICAgICBhcy5pbnRlZ2VyKSwKCiNIYW5kbGluZyBvZiBEeW5hbWljIENvbHVtbiBTZW1lc3RlciBIb3VycyBFYXJuZWQgRmFsbCAyMDIyLTIwMjQKICAgIGFjcm9zcyhhbnlfb2YobmV4dF9zZW1lc3RlcmhvdXJzZWFybmVkZmFsbCksCiAgICAgICAgICBhcy5pbnRlZ2VyKSwKICAgICAgIAojSGFuZGxpbmcgb2YgRHluYW1pYyBDb2x1bW4gQ3VtdWxhdGl2ZSBHUEEgRmFsbCAyMDIyLTIwMjQKICAgIGFjcm9zcyhhbnlfb2YobmV4dF9jdW11bGF0aXZlZ3BhZmFsbCApLAogICAgICAgICAgfiByb3VuZChhcy5udW1lcmljKC54KSwgMikpLAogICAgICAgCiNIYW5kbGluZyBvZiBEeW5hbWljIENvbHVtbiBUZXJtIENyZWRpdCBBdHRlbXB0ZWQgU3ByaW5nIDIwMjMtMjAyNQogICAgYWNyb3NzKGFueV9vZihuZXh0X3Rlcm1jcmVkaXRhdHRlbXB0ZWRzcHJpbmcpLAogICAgICAgICAgYXMuaW50ZWdlciksCiAgICAgICAKI0hhbmRsaW5nIG9mIER5bmFtaWMgQ29sdW1uIFNlbWVzdGVyIEhvdXJzIEVhcm5lZCBTcHJpbmcgMjAyMy0yMDI1CiAgICBhY3Jvc3MoYW55X29mKCBuZXh0X3NlbWVzdGVyaG91cnNlYXJuZWRzcHJpbmcpLAogICAgICAgICAgYXMuaW50ZWdlciksCiAgICAgICAKI0hhbmRsaW5nIG9mIER5bmFtaWMgQ29sdW1uIEdQQSBTcHJpbmcgMjAyMy0yMDI1CiAgICBhY3Jvc3MoYW55X29mKG5leHRfc2VtZXN0ZXJncGFzcHJpbmcpLAogICAgICAgICAgfiByb3VuZChhcy5udW1lcmljKC54KSwgMikpLAogICAgICAgCiNIYW5kbGluZyBvZiBEeW5hbWljIENvbHVtbiBDdW11bGF0aXZlIEhvdXJzIEVhcm5lZCBTcHJpbmcgMjAyMy0yMDI1CiAgICBhY3Jvc3MoYW55X29mKG5leHRfY3VtdWxhdGl2ZWhvdXJzZWFybmVkc3ByaW5nKSwKICAgICAgICAgIGFzLmludGVnZXIpLAogICAgICAgCiNIYW5kbGluZyBvZiBEeW5hbWljIENvbHVtbiBDdW11bGF0aXZlIEdQQSBTcHJpbmcgMjAyMy0yMDI1CiAgICBhY3Jvc3MoYW55X29mKG5leHRfY3VtdWxhdGl2ZWdwYXNwcmluZyApLAogICAgICAgICAgfiByb3VuZChhcy5udW1lcmljKC54KSwgMikpLAogICAgICAgCiAgICBjb2xsZWdlID0gYXMuY2hhcmFjdGVyKGNvbGxlZ2UpLAogICAgY29sbGVjdGlvbl90ZXJtICAgICA9ICJGYWxsIiwKICAgIGNvbGxlY3Rpb25feWVhciAgICAgPSB5ZWFyKQoKCiNFbnJvbGxtZW50IERhdGEgQ2xlYW5pbmcgCiAgICBmYV9yYXcgPC0gcmVhZF94bHN4KHBhdGgsIHNoZWV0ID0gZmFfc2hlZXQpCiAgICBmYSAgICAgPC0gZmFfcmF3ICU+JQogICAgY2xlYW5fbmFtZXMoKSAlPiUKICAgIHRyYW5zbXV0ZSgKICAgICAgc3R1ZHlfaWQgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXMuY2hhcmFjdGVyKHN0dWR5X2lkKSwKICAgICAgZmFtaWx5X3NpemUgICAgICAgICAgICAgICAgICAgICAgID0gYXMuaW50ZWdlcihmYW1pbHlfc2l6ZSksCiAgICAgIGRlcGVuZGVuY3lfc3RhdHVzICAgICAgICAgICAgICAgICA9IGFzLmNoYXJhY3RlcihkZXBlbmRlbmN5X3N0YXR1cyksCiAgICAgICAgCiNNYXBwaW5nIGFueSBudW1lcmljIHZhbHVlcyB1c2luZyBkZXBfbG9va3VwLCBPdGhlcndpc2Ugd2Ugd2lsbCBrZWVwIHRleHQKICAgICAgZGVwZW5kZW5jeV9zdGF0dXMgICAgICAgICAgICAgICAgID0gaWZfZWxzZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3lfc3RhdHVzICVpbiUgbmFtZXMoZGVwX2xvb2t1cCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBfbG9va3VwW2RlcGVuZGVuY3lfc3RhdHVzXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3lfc3RhdHVzKSwgCiAgICAgIGRlcGVuZGVuY3lfc3RhdHVzICAgICAgICAgICAgICAgICA9IGZhY3RvcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcGVuZGVuY3lfc3RhdHVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiRGVwZW5kZW50IiwiSW5kZXBlbmRlbnQiLCJVbmtuIikpLAogICAgICBleHBlY3RlZF9mYW1pbHlfY29udHJpYnV0aW9uICAgICAgPSBhcy5udW1lcmljKGV4cGVjdGVkX2ZhbWlseV9jb250cmlidXRpb24pLAogICAgICBjb3N0X29mX2F0dGVuZGFuY2UgICAgICAgICAgICAgICAgPSBhcy5udW1lcmljKGNvc3Rfb2ZfYXR0ZW5kYW5jZSksCiAgICAgIGZpbmFuY2lhbF9haWRfZGlzYnVyc2VtZW50X2Ftb3VudCA9IGFzLm51bWVyaWMoZmluYW5jaWFsX2FpZF9kaXNidXJzZW1lbnRfYW1vdW50KSwKICAgICAgcGVsbF9yZWNpcGllbnQgICAgICAgICAgICAgICAgICAgID0gY2FzZV93aGVuKHBlbGxfcmVjaXBpZW50ICAlaW4lIGMoIlllcyIsIlkiLCJUUlVFIikgIH4gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlbGxfcmVjaXBpZW50ICAlaW4lIGMoIk5vIiwiTiIsIkZBTFNFIikgIH4gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfiBOQSksCiAgICAgIHVubWV0bmVlZF9hbW91bnQgICAgICAgICAgICAgICAgICA9IGFzLm51bWVyaWModW5tZXRuZWVkX2Ftb3VudCksCiAgICAgIHVubWV0bmVlZF9jYXRlZ29yeSAgICAgICAgICAgICAgICA9IGFzLmludGVnZXIodW5tZXRuZWVkX2NhdGVnb3J5KSwKICAgICAgZmFtaWx5X2luY29tZV9jYXRlZ29yeSAgICAgICAgICAgID0gYXMuaW50ZWdlcihmYW1pbHlfaW5jb21lX2NhdGVnb3J5KSwKICAgICAgZmlyc3RfZ2VuZXJhdGlvbiAgICAgICAgICAgICAgICAgID0gZmFjdG9yKGZpcnN0X2dlbmVyYXRpb24sIGxldmVscyA9IGMoIlllcyIsIk5vIiwiVW5rbiIpKSkKCiNKb2luaW5nIGFuZCBSZXR1cm5pbmcgdGhlIGRhdGEKICAgIGRmX3llYXIgPC0gbGVmdF9qb2luKGVuciwgZmEsIGJ5ID0gInN0dWR5X2lkIiklPiUKCiNGaWx0ZXJpbmcgT3V0IHRoZSBDb2x1bW5zIHRoYXQgaGF2ZSBvdmVyIDcwJSBvZiBkYXRhIG1pc3NpbmcgCiAgICBzZWxlY3QoCiAgICAgIC1zYXRfMjAxNl9tYXRoX3Njb3JlLAogICAgICAtc2F0XzIwMTZfZWJyd19zY29yZSwKICAgICAgLWFjdF9tYXRoX3Njb3JlLAogICAgICAtYWN0X2VuZ2xpc2hfc2NvcmUsCiAgICAgIC1hY3RfcmVhZGluZ19zY29yZSwKICAgICAgLWFjdF9zY2llbmNlX3Njb3JlLAogICAgICAtYWN0X2NvbXBvc2l0ZV9zY29yZSwKICAgICAgLW5ld3JhY2Vfc3RyKSAlPiUgIAoKICAgIG11dGF0ZSgKICAgICAgYWRtaXNzaW9uX2V4ZW1wdGlvbiA9IGFzLmNoYXJhY3RlcihhZG1pc3Npb25fZXhlbXB0aW9uKSwKICAgICAgYWRtaXNzaW9uX2V4ZW1wdGlvbiA9IGNvYWxlc2NlKG5hX2lmKGFkbWlzc2lvbl9leGVtcHRpb24sICIiKSwgIjEiKSwKICAgICAgYWRtaXNzaW9uX2V4ZW1wdGlvbiA9IGFzLmludGVnZXIoYWRtaXNzaW9uX2V4ZW1wdGlvbikpICU+JQogICAgCiNSZXBsYWNpbmcgYmxhbmtzIHdpdGggOSB3aGljaCByZXByZXNlbnRzIHJhY2UgYXMgdW5rbm93biAgIAogICAgbXV0YXRlKAogICAgICBuZXdyYWNlID0gYXMuY2hhcmFjdGVyKG5ld3JhY2UpLAogICAgICBuZXdyYWNlID0gY29hbGVzY2UobmFfaWYobmV3cmFjZSwgIiIpLCAiOSIpLAogICAgICBuZXdyYWNlID0gYXMuaW50ZWdlcihuZXdyYWNlKSkgJT4lCiAgCiAgCiNIYW5kbGluZyBEZXBlbmRlbmN5IFN0YXR1cyBCbGFua3MKICAgIG11dGF0ZSgKICAgICAgZGVwZW5kZW5jeV9zdGF0dXMgPSBhcy5jaGFyYWN0ZXIoZGVwZW5kZW5jeV9zdGF0dXMpLAogICAgICBkZXBlbmRlbmN5X3N0YXR1cyA9IGNvYWxlc2NlKG5hX2lmKGRlcGVuZGVuY3lfc3RhdHVzLCAiIiksICJVbmtuIiksCiAgICAgIGRlcGVuZGVuY3lfc3RhdHVzID0gZmFjdG9yKGRlcGVuZGVuY3lfc3RhdHVzLGxldmVscyA9IGMoIkRlcGVuZGVudCIsIkluZGVwZW5kZW50IiwiVW5rbiIpKSkgJT4lCgojSWRlbnRpZnlpbmcsIFJlcGxhY2luZyBPdXRsaWVycyBhbmQgSW1wdXRpbmcgTWlzc2luZyBWYWx1ZXMgd2l0aCBNZWFuICAgCiAgICAgIG11dGF0ZSgKICAgICAgICBhY3Jvc3MoCiAgICAgICAgICBjKGV4cGVjdGVkX2ZhbWlseV9jb250cmlidXRpb24sIHVubWV0bmVlZF9hbW91bnQsIGNvc3Rfb2ZfYXR0ZW5kYW5jZSwgZmluYW5jaWFsX2FpZF9kaXNidXJzZW1lbnRfYW1vdW50LCBoaWdoX3NjaG9vbF9ncGEsZmFtaWx5X3NpemUpLAogICAgICAgICAgfiB7CgojQ29tcHV0aW5nIHRoZSBtZWFuIGZvciBlYWNoIGNvbHVtbiBvbiBhIHllYXJseSBiYXNpcwogICAgICAgICAgICBtZWQgICAgPC0gbWVkaWFuKC54LCBuYS5ybSA9IFRSVUUpCiAgICAgICAgICAgIAojSW1wdXRpbmcgTWlzc2luZyBWYWx1ZXMKICAgICAgICAgICAgeDAgICA8LSBpZl9lbHNlKGlzLm5hKC54KSwgbWVkLCAueCkKICAgICAgICAgICAgCiNDb21wdXRpbmcgSVFSIEJvdW5kYXJpZXMKICAgICAgICAgICAgcSAgICA8LSBxdWFudGlsZSh4MCwgYygwLjI1LCAwLjc1KSwgbmEucm0gPSBUUlVFKQogICAgICAgICAgICBpcXIgIDwtIGRpZmYocSkKICAgICAgICAgICAgbG93ZXIgPC0gcVsxXSAtIDEuNSAqIGlxcgogICAgICAgICAgICB1cHBlciA8LSBxWzJdICsgMS41ICogaXFyCiAgICAgICAgICAgIAojUmVwbGFjaW5nIG91dGxpZXJzIHdpdGggdGhlIHllYXLigJlzIG1lYW4KICAgICAgICAgICAgaWZlbHNlKHgwIDwgbG93ZXIgfCB4MCA+IHVwcGVyLCBtZWQsIHgwKQogICAgICAgICAgICB9CiAgICAgICAgICAgICkKICAgICAgICAgICAgKSAlPiUKCiNEcm9wcGluZyBSZWNvcmRzIHdoaWNoIGFyZSBOQSBzaW5jZSBpdCBpcyBsZXNzIHRoYW4gNSUgb2YgZGF0YSBzZXQKICAgIGZpbHRlcigKICAgICAgaWZfYWxsKAogICAgICAgIGFueV9vZihjKAogICAgICAgICAgcGFzdGUwKCJ0ZXJtX2NyZWRpdF9ob3Vyc19hdHRlbXB0ZWQiLCAgeWVhciArIDEsICJzcHJpbmciKSwKICAgICAgICAgIHBhc3RlMCgic2VtZXN0ZXJncGEiLCAgICAgICAgICAgICAgICAgIHllYXIgKyAxLCAic3ByaW5nIiksCiAgICAgICAgICBwYXN0ZTAoImN1bXVsYXRpdmVob3Vyc2Vhcm5lZCIsICAgICAgICB5ZWFyICsgMSwgInNwcmluZyIpLAogICAgICAgICAgcGFzdGUwKCJjdW11bGF0aXZlZ3BhIiwgICAgICAgICAgICAgICAgeWVhciArIDEsICJzcHJpbmciKQogICAgICAgICAgKSksCiAgICAgICAgICB+ICFpcy5uYSgueCkKICAgICAgICAgICAgKQogICAgICAgICAgKQogICAgCiAgICAKIyNUaGUgQmVsb3cgTGluZXMgb2YgQ29kZXMgcmVwcmVzZW50cyBsb29rdXAgdGFibGVzIGZvciB2YXJpYmFsZXMuCiMjRm9yIE51bWVyaWMgVmFyaWFibGVzIGEgbGFiZWwgaGFzIGJlZW4gY3JlYXRlZAojI0ZvciBUZXh0IEZpZWxkcyBhIENvZGUgaGFzIGJlZW4gY3JlYXRlZCB0byB1c2VkIGZvciBtb2RlbGxpbmcgCiAgICAKICBmYW1pbHlfaW5jX2xvb2t1cCAgICAgICAgICAgICA8LSB0aWJibGUoCiAgZmFtaWx5X2luY29tZV9jYXRlZ29yeSAgICAgICAgPSAxOjEwLAogIGZhbWlseV9pbmNvbWVfbGFiZWwgICAgICAgICAgID0gYygiTG93ZXN0IFRocnUgMjUsMDAwIiwgIjI1LDAwMSBUaHJ1IDUwLDAwMCIsICI1MCwwMDEgVGhydSA3NSwwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiNzUsMDAxIFRocnUgMTAwLDAwMCIsICIxMDAsMDAxIFRocnUgMTI1LDAwMCIsICIxMjUsMDAxIFRocnUgMTUwLDAwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxNTAsMDAxIFRocnUgMTc1LDAwMCIsICIxNzUsMDAxIFRocnUgMjAwLDAwMCIsICIyMDAsMDAxIFRocnUgMjI1LDAwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyMjUsMDAxKyIpKQoKICB1bm1ldG5lZWRfY2F0X2xvb2t1cCAgICAgICAgICA8LSB0aWJibGUoCiAgdW5tZXRuZWVkX2NhdGVnb3J5ICAgICAgICAgICAgPSAxOjcsCiAgdW5tZXRuZWVkX2NhdGVnb3J5X2xhYmVsICAgICAgPSBjKCIkMSBUaHJ1ICQ1MDAwIiwgIiQ1MDAxIFRocnUgJDc1MDAiLCAiJDc1MDEgVGhydSAkMTAwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJDEwMDAxIFRocnUgJDE1MDAwIiwgIiQxNTAwMSBUaHJ1IEhpZ2hlc3QiLCAiTm8gVW5tZXQgTmVlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIFVubWV0IE5lZWQiKSkKICAKICBkaXN0YW5jZV9lZHVfbG9va3VwICAgICAgICAgICA8LSB0aWJibGUoCiAgZGlzdGFuY2VfZWR1Y2F0aW9uX2Vucm9sbG1lbnQgPSAxOjMsCiAgZGlzdGFuY2VfZWR1Y2F0aW9uX2xhYmVsICAgICAgPSBjKCJFbnJvbGxlZCBFeGNsdXNpdmVseSBpbiBEaXN0YW5jZSBFZHVjYXRpb24iLCAiRW5yb2xsZWQgaW4gU29tZSBidXQgTm90IEFsbCBEaXN0YW5jZSBFZHVjYXRpb24iLCAiTm90IEVucm9sbGVkIGluIEFueSBEaXN0YW5jZSBFZHVjYXRpb24iKSkKICAKICBhZG1pc3Npb25fdGVzdF9sb29rdXAgICAgICAgICA8LSB0aWJibGUoCiAgYWRtaXNzaW9uX3Rlc3RfZmxhZyAgICAgICAgICAgPSAwOjUsCiAgYWRtaXNzaW9uX3Rlc3RfZmxhZ19sYWJlbCAgICAgPSBjKCJObyBUZXN0IFJlcXVpcmVkIGZvciBBZG1pc3Npb24iLCAiU0FUIFRlc3QgUmVxdWlyZWQiLCAiQUNUIFRlc3QgUmVxdWlyZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWl0aGVyIEFDVCBvciBTQVQgUmVxdWlyZWQiLCAiSW5zdGl0dXRpb24gVGVzdCBSZXF1aXJlZCIsICJCZWNhdXNlIG9mIEFkbWlzc2lvbiBFeGVtcHRpb24iKSkKICAKICBtaWxpdGFyeV9zdGF0dXNfbG9va3VwICAgICAgICA8LSB0aWJibGUoCiAgbWlsaXRhcnlfc3RhdHVzICAgICAgICAgICAgICAgPSAxOjUsCiAgbWlsaXRhcnlfc3RhdHVzX2xhYmVsICAgICAgICAgPSBjKCJBY3RpdmUgRHV0eSBNZW1iZXIgb2YgQW55IG9mIHRoZSBVUyBVbmlmb3JtIEZvcmNlcyIsICJWZXRlcmFuIG9yIEZvcm1lciBBY3RpdmUgRHV0eSBNZW1iZXIgb2YgQW55IG9mIFRoZSBVUyBVbmlmb3JtZWQgRm9yY2VzIiwgIlJlc2VydmUgRHV0eSBNZW1iZXIgb2YgQW55IG9mIFRoZSBVUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFybWVkIEZvcmNlcywgSW5jbHVkaW5nIFRoZSBOYXRpb25hbCBHdWFyZCIsICJTcG91c2Ugb3IgRGVwZW5kZW50IENoaWxkIG9mIGFuIEFjdGl2ZSwgUmVzZXJ2ZSwgb3IgRm9ybWVyIE1lbWJlciBvZiBUaGUgVVMgVW5pZm9ybWVkIEZvcmNlcyIsICJOb25lIG9mIHRoZSBhYm92ZSIpKQogIAogIGZyYWNlX2xvb2t1cCAgICAgICAgICAgICAgICAgIDwtIHRpYmJsZSgKICBuZXdyYWNlICAgICAgICAgICAgICAgICAgICAgICA9IDE6OSwKICByYWNlX2xhYmVsICAgICAgICAgICAgICAgICAgICA9IGMoIkFmcmljYW4tQW1lcmljYW5zIiwgIk5hdGl2ZS1BbWVyaWNhbnMiLCAiQXNpYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSGlzcGFuaWMiLCAiV2hpdGUiLCAiTmF0aXZlLUhhd2FpaWFucyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNdWx0aVJhY2lhbHMiLCAiSW50ZXJuYXRpb25hbCIsIlVua25vd24iKSkKICAgIAogIGRlcGVuZGVuY3lfc3RhdHVzX2xvb2t1cCAgICAgIDwtIHRpYmJsZSgKICBkZXBlbmRlbmN5X3N0YXR1cyAgICAgICAgICAgICA9IGMoIlVua24iLCAiRGVwZW5kZW50IiwiSW5kZXBlbmRlbnQiKSwKICBkZXBlbmRlbmN5X2NvZGUgICAgICAgICAgICAgICA9IDA6MikKICAgCiAgZ2VuZGVyX2xvb2t1cCAgICAgICAgICAgICAgICAgPC0gdGliYmxlKAogIGdlbmRlciAgICAgICAgICAgICAgICAgICAgICAgID0gYygiTSIsIkYiKSwKICBnZW5kZXJfY29kZSAgICAgICAgICAgICAgICAgICA9IDE6MikKICAgIAogIAogIHR1aXRpb25fc3RhdHVzX2xvb2t1cCAgICAgICAgIDwtIHRpYmJsZSgKICB0dWl0aW9uX3N0YXR1cyAgICAgICAgICAgICAgICA9IGMoImluLXN0YXRlIiwgIm91dC1vZi1zdGF0ZSIpLAogIHR1aXRpb25fc3RhdHVzX2NvZGUgICAgICAgICAgID0gMjozKQogICAKICAgCiAgZmlyc3RfZ2VuZXJhdGlvbl9sb29rdXAgICAgICAgPC0gdGliYmxlKAogIGZpcnN0X2dlbmVyYXRpb24gICAgICAgICAgICAgPSBjKCJObyIsICJZZXMiLCAiVW5rbiIpLAogIGZpcnN0X2dlbmVyYXRpb25fY29kZSAgICAgICAgID0gYygwLDEsOSkpCgojQWRkaW5nIHRoZSBBZGRpdGlvbmFsIENvbHVtbnMgdG8gZGF0YXNldCAgIAogIGRmX3llYXIgPC0gZGZfeWVhciAlPiUKICBsZWZ0X2pvaW4oZmFtaWx5X2luY19sb29rdXAsICAgICAgICBieSA9ICJmYW1pbHlfaW5jb21lX2NhdGVnb3J5IikgJT4lCiAgbGVmdF9qb2luKHVubWV0bmVlZF9jYXRfbG9va3VwLCAgICAgYnkgPSAidW5tZXRuZWVkX2NhdGVnb3J5IikgJT4lCiAgbGVmdF9qb2luKGRpc3RhbmNlX2VkdV9sb29rdXAsICAgICAgYnkgPSAiZGlzdGFuY2VfZWR1Y2F0aW9uX2Vucm9sbG1lbnQiKSAlPiUKICBsZWZ0X2pvaW4oYWRtaXNzaW9uX3Rlc3RfbG9va3VwLCAgICBieSA9ICJhZG1pc3Npb25fdGVzdF9mbGFnIikgJT4lCiAgbGVmdF9qb2luKG1pbGl0YXJ5X3N0YXR1c19sb29rdXAsICAgYnkgPSAibWlsaXRhcnlfc3RhdHVzIikgJT4lCiAgbGVmdF9qb2luKGZyYWNlX2xvb2t1cCwgICAgICAgICAgICAgYnkgPSAibmV3cmFjZSIpICU+JQogIGxlZnRfam9pbihkZXBlbmRlbmN5X3N0YXR1c19sb29rdXAsIGJ5ID0gImRlcGVuZGVuY3lfc3RhdHVzIikgICU+JQogIGxlZnRfam9pbihnZW5kZXJfbG9va3VwLCAgICAgICAgICAgIGJ5ID0gImdlbmRlciIpICAlPiUKICBsZWZ0X2pvaW4odHVpdGlvbl9zdGF0dXNfbG9va3VwLCAgICBieSA9ICJ0dWl0aW9uX3N0YXR1cyIpICAlPiUKICBsZWZ0X2pvaW4oZmlyc3RfZ2VuZXJhdGlvbl9sb29rdXAsICBieSA9ICJmaXJzdF9nZW5lcmF0aW9uIikgCgojV3JpdGluZyBFYWNoIFllYXIgRGF0YSB0byBBIHNlcGFyYXRlIENTViB0byBVcGxvYWQgdG8gVGFibGVhdSAgICAgICAgCiAgZmlsZV9uYW1lIDwtIHBhc3RlMCgiL1VzZXJzL2ZyZW5hbmRlemxhd3JlbmNlL0Rvd25sb2Fkcy9UZWFtX0IiLHllYXIsIkNsZWFuZWRfRGF0YS5jc3YiKQogIHdyaXRlLmNzdihkZl95ZWFyLCBmaWxlICAgICAgPSBmaWxlX25hbWUsIHJvdy5uYW1lcyA9IEZBTFNFKQoKICBkZl95ZWFyCiAgfQopCmBgYAoKCiMjIFBlcmZvcm1pbmcgRmluYWwgUXVhbGl0eSBDaGVja3Mgb24gTWVyZ2VkIERhdGFzZXQKCmBgYHtyfQojUGVyZm9ybWluZyBVbmlxdWVuZXNzIENoZWNrCiAgYWxsX2NvaG9ydHMgJT4lCiAgICBjb3VudChjb2xsZWN0aW9uX3llYXIsIHN0dWR5X2lkKSAlPiUKICAgIGZpbHRlcihuID4gMSkKCiMgUGVyZm9ybWluZyBNaXNzaW5nbmVzcyBDaGVjawogIGFsbF9jb2hvcnRzICU+JQogICAgc3VtbWFyaXNlX2FsbCh+IG1lYW4oaXMubmEoLikpKSAlPiUKICAgIHBpdm90X2xvbmdlcihldmVyeXRoaW5nKCksIG5hbWVzX3RvID0gInZhciIsIHZhbHVlc190byA9ICJwY3RfbWlzc2luZyIpCgojIFBlcmZvbWluZyBhIGZpbmFsIGxvb2sgYXQgZGF0YXNldAojVGhlIE5BcyBkaXNwbGF5aW5nIGluIHRoZSBnbGltcHNlIGlzIGZvciB0aGUgZHluYW1pYyBjb2x1bW5zIHdoaWNoIGFyZSBub3Qgbm90IGFwcGxpY2FibGUgZm9yIGFsbCB5ZWFycy4gCmdsaW1wc2UoYWxsX2NvaG9ydHMpCmBgYAoKIyMgRXhwb3J0aW5nIENsZWFuIGFuZCBNZXJnZSBEYXRhIGZvciBJbnRlcm5hbCBBbmFseXNpcwoKYGBge3J9CndyaXRlLmNzdihhbGxfY29ob3J0cywKICAgICAgICAgICBmaWxlICAgICAgPSAiL1VzZXJzL2ZyZW5hbmRlemxhd3JlbmNlL0Rvd25sb2Fkcy9UZWFtX0JfQ2xlYW5lZF9Db2hvcnRfRGF0YV8yMDIyXzIwMjQuY3N2IiwKICAgICAgICByb3cubmFtZXMgPSBGQUxTRSkKYGBgCg==