Initial Data Preparation

raw_data <- read.csv("https://tinyurl.com/4736xjmw")

library(dplyr)

# Collapse the dataset to one observation per agreement (cas_id)
# We keep the row with the latest 'year' to capture the final outcome.
data <- raw_data %>%
  group_by(cas_id) %>%
  slice_max(order_by = year, n = 1) %>% # Selects the row with the highest year
  ungroup()

# ============ PREP VARIABLES IN ORIGINAL DATA =================
data$start_date_obj <- as.Date(data$strt_pa)
data$end_date_obj   <- as.Date(data$nd_pa)
data$start_date_num <- as.numeric(data$start_date_obj)
data$weeks_of_peace <- as.numeric(difftime(data$end_date_obj, data$start_date_obj, units = "weeks"))
data$days_of_peace  <- as.numeric(data$end_date_obj - data$start_date_obj)

# Check the new dimensions
str(data)
tibble [79 × 37] (S3: tbl_df/tbl/data.frame)
 $ PAID          : num [1:79] 7.0e+12 7.0e+12 7.0e+12 5.4e+12 5.4e+12 ...
 $ cas_id        : int [1:79] 1 2 3 4 5 6 7 8 9 10 ...
 $ new_con_id    : int [1:79] 333 333 333 387 327 327 322 398 389 287 ...
 $ iso3c         : chr [1:79] "AFG" "AFG" "AFG" "AGO" ...
 $ year          : int [1:79] 1993 1993 1996 2007 1998 2011 2011 2011 2011 2000 ...
 $ pa_name       : chr [1:79] "Islamabad accord" "Jalalabad agreement" "Mahipar agreement" "Memorandum of Understanding on Peace and National Reconciliation in Cabinda province" ...
 $ strt_pa       : chr [1:79] "1993-03-07" "1993-05-20" "1996-05-24" "2006-08-01" ...
 $ nd_pa         : chr [1:79] "1993-04-13" "1993-08-22" "1996-05-30" "2007-12-31" ...
 $ pc_nd         : int [1:79] 1 1 1 1 1 0 0 0 0 1 ...
 $ nd_pa_src     : chr [1:79] "GED" "GED" "GED" "ACD" ...
 $ strt_sgmnt    : chr [1:79] "1993-03-07" "1993-05-20" "1996-05-24" "2007-01-01" ...
 $ nd_sgmnt      : chr [1:79] "1993-04-13" "1993-08-22" "1996-05-30" "2007-12-31" ...
 $ fem_sig       : int [1:79] 0 0 0 0 0 0 0 0 0 0 ...
 $ con_dur       : int [1:79] 16 16 19 14 20 28 17 2 4 36 ...
 $ con_dur2      : int [1:79] 16 16 19 7 20 26 17 2 4 10 ...
 $ con_int       : num [1:79] 1 1 1 0 0.95 ...
 $ con_int2      : num [1:79] 1 1 1 0 0.95 ...
 $ con_int_bin   : int [1:79] 1 1 1 0 1 1 0 1 1 1 ...
 $ war_par       : int [1:79] 12 13 14 3 3 3 2 3 3 7 ...
 $ pow_sha       : int [1:79] 2 2 2 1 3 2 1 3 2 2 ...
 $ dem           : int [1:79] 0 0 0 0 0 0 1 0 0 0 ...
 $ gdp           : num [1:79] NA NA NA 3.31 2.7 ...
 $ hum_rig       : int [1:79] NA NA 3 5 3 4 7 6 6 5 ...
 $ cpa           : int [1:79] 0 0 0 0 1 0 1 0 1 0 ...
 $ con_iss       : int [1:79] 1 1 1 0 1 1 0 0 0 1 ...
 $ pea           : int [1:79] 0 0 0 0 1 0 0 0 0 0 ...
 $ fem_leg       : int [1:79] NA NA NA 2 2 3 2 2 2 1 ...
 $ fem_com       : int [1:79] 1 1 1 0 3 3 0 1 1 2 ...
 $ quo           : int [1:79] 0 0 0 0 0 0 1 0 0 1 ...
 $ lef_ide       : int [1:79] 0 0 0 0 0 0 0 0 0 0 ...
 $ civ_soc       : int [1:79] 0 0 0 0 0 0 1 0 1 1 ...
 $ un_pea_con    : num [1:79] 0 0 0 0 1216 ...
 $ start_date_obj: Date[1:79], format: "1993-03-07" "1993-05-20" ...
 $ end_date_obj  : Date[1:79], format: "1993-04-13" "1993-08-22" ...
 $ start_date_num: num [1:79] 8466 8540 9640 13361 9089 ...
 $ weeks_of_peace: num [1:79] 5.286 13.429 0.857 73.857 179.857 ...
 $ days_of_peace : num [1:79] 37 94 6 517 1259 ...

Hypothesis 1: Women participation impacts peace durability


# ===== CLEANING: Remove NAs from ALL necessary variables ====

# Define variables of interest

pretreatment_covariates <- c("con_dur", "con_int", "con_iss", "war_par", "gdp", "dem", "hum_rig", "fem_com", "lef_ide", "fem_leg", "start_date_num")

treatnent_var <- c("fem_sig")
outcome_vars <- c("days_of_peace", "pc_nd")

cleaning_vars <- c(treatnent_var, outcome_vars, pretreatment_covariates) # This list includes Y, Tr, and X. We use it ONLY for na.omit.

# Check which columns contain missing values
colSums(is.na(data[, cleaning_vars])) 

# Clean the data to enable genetic matching (cannot have NAs)
df_clean_H1 <- na.omit(data[, c("cas_id", cleaning_vars)])
df_clean_H1

cat("Number of control/treatment units in sample (before cleaning):")
table(data$fem_sig)

cat("Number of control/treatment units in sample (after cleaning):")
table(df_clean_H1$fem_sig)
library(rgenoud)
library(Matching)

set.seed(123)

# ====== DEFINE MATCHING OBJECTS ======

# Treatment 
Tr <- df_clean_H1$fem_sig

# Matching Matrix (X): ONLY contains pre-treatment covariates.
matching_vars <- pretreatment_covariates
X <- df_clean_H1[, matching_vars]
# Do not use outcome observations until matching is complete


# PREPARE CALIPER (for start_date_num)
# Calculate caliper value for start_date_num
desired_window_days <- 180
sd_date <- sd(df_clean_H1$start_date_num)
caliper_value <- desired_window_days / sd_date

# Create Caliper Vector
# We need a vector of Infs matching the number of columns in X
caliper_vec <- rep(Inf, ncol(X))

# Apply restriction ONLY to the start date column
date_index <- which(colnames(X) == "start_date_num")
caliper_vec[date_index] <- caliper_value

# ========== RUN GENMATCH ==============
genout_H1 <- GenMatch(Tr = Tr, X = X, BalanceMatrix = X, 
                   caliper = caliper_vec,
                   estimand = "ATT", pop.size = 5000, 
                   print.level = 0)

# ========== RUN MATCH ==============

m_out_H1 <- Match(Tr = Tr, X = X, Weight.matrix = genout_H1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Report on matching summary ======

# Count how many times each treated unit appears in the match list
matches_per_treated <- table(m_out_H1$index.treated)

# Check the distribution (e.g., how many got 1 match, how many got 2, etc.)
table(matches_per_treated)

# Total treated units in original data
total_treated <- sum(Tr)

# Total treated units that successfully found a match
matched_treated <- length(unique(m_out_H1$index.treated))

cat("Original Treated:", total_treated, "\n")
cat("Matched Treated: ", matched_treated, "\n")
cat("Dropped:         ", total_treated - matched_treated, "\n")
# ===== Report Balance and Lowest P-Value ======
set.seed(123)
# treatment indicator is the dependent variable, check balance for all covariates
mb_formula_H1 <- fem_sig ~ con_dur + con_int + con_iss +  war_par + gdp + dem + hum_rig + fem_leg + fem_com + lef_ide + start_date_num

MatchBalance(mb_formula_H1, data = df_clean_H1, match.out = m_out_H1, nboots = 500)
#install.packages("cobalt")
library(cobalt)

love.plot(mb_formula_H1, 
          data = df_clean_H1, 
          weights = m_out_H1, # Use the match object as the source of weights
          binary = "std",
          thresholds = c(m = .25),
          alpha = 0.7,
          title = "Covariate Balance (SMD)",
          grid = TRUE)

love.plot(mb_formula_H1, 
          data = df_clean_H1, 
          weights = m_out_H1, # Use the match object as the source of weights
          stats = "ks.statistics", # Change to KS statistics
          binary = "std",
          thresholds = c(ks = 0.1), 
          alpha = 0.7,
          grid = TRUE,
          title = "Covariate Balance (KS Statistics)")
library(ggplot2)
library(gridExtra) # Required for arranging plots

# Panel A: Good Balance (Continuous - ECDF)
p1 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "start_date_num", type = "ecdf") + 
      ggtitle("A. Good Balance: Start Date")

# Panel B: Poor Balance (Continuous - ECDF)
p2 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "gdp", type = "ecdf") + 
      ggtitle("B. Poor Balance: GDP")

# Panel C: Good Balance (Discrete - Histogram)
p3 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "dem", type = "histogram") + 
      ggtitle("C. Good Balance: Democracy")

# Panel D: Poor Balance (Discrete - Histogram)
p4 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "hum_rig", type = "histogram") + 
      ggtitle("D. Poor Balance: Human Rights")

# Arrange plots into a 2x2 grid
grid.arrange(p1, p2, p3, p4, nrow = 2)
bal.tab(mb_formula_H1, 
        data = df_clean_H1, 
        weights = m_out_H1, # Use the match object as the source of weights
        estimand = "ATT",
        binary = "std",      # <--- Forces binary vars to use SMD
        continuous = "std",  # <--- Forces continuous vars (default) to use SMD
        un = TRUE,
        stats = c("m", "v", "ks"),   # Mean diffs, Variance ratios, KS stats
        thresholds = c(m = 0.25, ks = 0.1))
library(Matching)

get_balance_table <- function(formula, data, match_out, nboots = 500) {
  
  # 1. Run MatchBalance
  mb <- MatchBalance(formula, data = data, match.out = match_out, nboots = nboots, print.level = 0)
  
  # 2. Define the "Nested" Null Coalescing Operator 
  #    (This allows us to chain checks: "Try A, if NULL try B, if NULL try C")
  `%||%` <- function(a, b) if (is.null(a)) b else a

  # 3. Define the Extractors
  #    T-Test: Simple check
  get_tt <- function(x) x$tt$p.value %||% NA
  
  #    KS-Test: The "Nested" Approach
  #    1. Try nested bootstrap (x$ks$ks.boot.pvalue) <--- PRIORITY
  #    2. Try top-level bootstrap (x$ks.boot.pvalue)
  #    3. Try standard KS (x$ks$p.value)
  get_ks <- function(x) x$ks$ks.boot.pvalue %||% x$ks.boot.pvalue %||% x$ks$p.value %||% NA

  # 4. Extract efficiently with sapply
  idx <- seq_along(mb$AfterMatching)
  vars <- all.vars(formula)[-1]
  final_names <- if(length(vars) == length(idx)) vars else paste0("Var_", idx)

  df <- data.frame(
    Variable  = final_names,
    Pre_T_P   = round(sapply(idx, function(i) get_tt(mb$BeforeMatching[[i]])), 3),
    Post_T_P  = round(sapply(idx, function(i) get_tt(mb$AfterMatching[[i]])), 3),
    Pre_KS_P  = round(sapply(idx, function(i) get_ks(mb$BeforeMatching[[i]])), 3),
    Post_KS_P = round(sapply(idx, function(i) get_ks(mb$AfterMatching[[i]])), 3)
  )
  
  # 5. Status: Pass if (KS is NA or >0.05) AND (T-test > 0.05)
  df$Status <- ifelse((is.na(df$Post_KS_P) | df$Post_KS_P > 0.1) & df$Post_T_P > 0.1, "PASS", "FAIL")
  
  return(df)
}
set.seed(123)
# --- Call Function ---
balance_table_H1 <- get_balance_table(
  formula = mb_formula_H1, 
  data = df_clean_H1, 
  match_out = m_out_H1, 
  nboots = 500
)

balance_table_H1

Hypothesis 1A: fem-sig on days_of_peace (peace duration)

# Include outcome variable for effect estimate
Y  <- df_clean_H1$days_of_peace
m_out_H1A <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_H1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ======
summary(m_out_H1A)

ATT_est <- m_out_H1A$est
ATT_se <- m_out_H1A$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 2)))
print(paste("Standard Error:", round(ATT_se, 2)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))

Hypothesis 1B: fem-sig on pc_nd (peace ends and conflict resumes)

# Outcome
Y  <- df_clean_H1$pc_nd
m_out_H1B <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_H1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ======

summary(m_out_H1B)

ATT_est <- m_out_H1B$est
ATT_se <- m_out_H1B$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 2)))
print(paste("Standard Error:", round(ATT_se, 2)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))

Model H1: Rosenbaum Bounds Sensitivity Analysis


# ===== CLEANING: Remove NAs from ALL necessary variables ====

# Define variables of interest

pretreatment_covariates <- c("con_dur", "con_int", "con_iss", "war_par", "gdp", "dem", "hum_rig", "fem_com", "lef_ide", "fem_leg", "start_date_num")

treatnent_var <- c("fem_sig")
outcome_vars <- c("days_of_peace", "pc_nd")

cleaning_vars <- c(treatnent_var, outcome_vars, pretreatment_covariates) # This list includes Y, Tr, and X. We use it ONLY for na.omit.

# Check which columns contain missing values
colSums(is.na(data[, cleaning_vars])) 
       fem_sig  days_of_peace          pc_nd        con_dur        con_int 
             0              0              0              0              0 
       con_iss        war_par            gdp            dem        hum_rig 
             0              0              9              0              9 
       fem_com        lef_ide        fem_leg start_date_num 
             9              2              9              0 
# Clean the data to enable genetic matching (cannot have NAs)
df_clean_H1 <- na.omit(data[, c("cas_id", cleaning_vars)])
df_clean_H1

cat("Number of control/treatment units in sample (before cleaning):")
Number of control/treatment units in sample (before cleaning):
table(data$fem_sig)

 0  1 
73  6 
cat("Number of control/treatment units in sample (after cleaning):")
Number of control/treatment units in sample (after cleaning):
table(df_clean_H1$fem_sig)

 0  1 
50  6 
library(rgenoud)
library(Matching)

set.seed(123)

# ====== DEFINE MATCHING OBJECTS ======

# Treatment 
Tr <- df_clean_H1$fem_sig

# Matching Matrix (X): ONLY contains pre-treatment covariates.
matching_vars <- pretreatment_covariates
X <- df_clean_H1[, matching_vars]
# Do not use outcome observations until matching is complete


# PREPARE CALIPER (for start_date_num)
# Calculate caliper value for start_date_num
desired_window_days <- 180
sd_date <- sd(df_clean_H1$start_date_num)
caliper_value <- desired_window_days / sd_date

# Create Caliper Vector
# We need a vector of Infs matching the number of columns in X
caliper_vec <- rep(Inf, ncol(X))

# Apply restriction ONLY to the start date column
date_index <- which(colnames(X) == "start_date_num")
caliper_vec[date_index] <- caliper_value

# ========== RUN GENMATCH ==============
genout_H1 <- GenMatch(Tr = Tr, X = X, BalanceMatrix = X, 
                   caliper = caliper_vec,
                   estimand = "ATT", pop.size = 5000, 
                   print.level = 0)

# ========== RUN MATCH ==============

m_out_H1 <- Match(Tr = Tr, X = X, Weight.matrix = genout_H1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Report on matching summary ======

# Count how many times each treated unit appears in the match list
matches_per_treated <- table(m_out_H1$index.treated)

# Check the distribution (e.g., how many got 1 match, how many got 2, etc.)
table(matches_per_treated)
matches_per_treated
1 
6 
# Total treated units in original data
total_treated <- sum(Tr)

# Total treated units that successfully found a match
matched_treated <- length(unique(m_out_H1$index.treated))

cat("Original Treated:", total_treated, "\n")
Original Treated: 6 
cat("Matched Treated: ", matched_treated, "\n")
Matched Treated:  6 
cat("Dropped:         ", total_treated - matched_treated, "\n")
Dropped:          0 

H1: Robustness check

# ============== Remove NAs from ALL necessary variables==================

# Specify variables of interest
pretreatment_covariates <- c("con_dur", "con_int", "con_iss", "war_par", "gdp", "dem", "hum_rig", "fem_com", "lef_ide", "fem_leg", "start_date_num")
treatnent_var <- c("fem_sig")
outcome_vars <- c("days_of_peace", "pc_nd")

# additional covariates for matching (used as controls by Krause et al.)
add_covariates <- c("pow_sha", "quo", "un_pea_con") 

cleaning_vars <- c(treatnent_var, outcome_vars, pretreatment_covariates, add_covariates)

# Check which columns contain missing values
colSums(is.na(data[, cleaning_vars])) 

# Clean the data to enable genetic matching (cannot have NAs)
df_clean_rb1 <- na.omit(data[, c("cas_id", cleaning_vars)])
df_clean_rb1

# Check for dropped units
cat("Number of control/treatment units in sample (before cleaning):")
table(data$fem_sig)

cat("Number of control/treatment units in sample (after cleaning):")
table(df_clean_rb1$fem_sig)
set.seed(123)
# ============ DEFINE MATCHING OBJECTS ================

# Treatment 
Tr <- df_clean_rb1$fem_sig

# Matching Matrix (X)
matching_vars <- c(pretreatment_covariates, add_covariates) #include additional covariates
X <- df_clean_rb1[, matching_vars]


# PREPARE CALIPER (For start_date_num)
desired_window_days <- 180 #90 causes treatment units to be dropped
sd_date <- sd(df_clean_rb1$start_date_num)
caliper_value <- desired_window_days / sd_date

# Create Caliper Vector
# We need a vector of Infs matching the number of columns in X
caliper_vec <- rep(Inf, ncol(X))

# Apply restriction ONLY to the date column
date_index <- which(colnames(X) == "start_date_num")
caliper_vec[date_index] <- caliper_value

# ================ RUN GENMATCH ===============
genout_rb1 <- GenMatch(Tr = Tr, X = X, BalanceMatrix = X,
                   caliper = caliper_vec,
                   estimand = "ATT", pop.size = 5000, 
                   print.level = 0)

# ================ RUN MATCH ===================
m_out_rb1 <- Match(Tr = Tr, X = X, Weight.matrix = genout_rb1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Report Summary of Matching Results ======
# Count how many times each treated unit appears in the match list
matches_per_treated <- table(m_out_rb1$index.treated)
# Check the distribution (e.g., how many got 1 match, how many got 2, etc.)
table(matches_per_treated)

# Total treated units in original data
total_treated <- sum(Tr)

# Total treated units that successfully found a match
matched_treated <- length(unique(m_out_rb1$index.treated))

cat("Original Treated:", total_treated, "\n")
cat("Matched Treated: ", matched_treated, "\n")
cat("Dropped:         ", total_treated - matched_treated, "\n")
# ===== Report Balance and Lowest P-Value ======
set.seed(123)
# treatment indicator is the dependent variable, check balance for all covariates
mb_formula_rb1 <- fem_sig ~ con_dur + con_int + con_iss +  war_par + gdp + dem + hum_rig + fem_leg + fem_com + lef_ide + start_date_num + pow_sha + quo + un_pea_con

MatchBalance(mb_formula_rb1, data = df_clean_rb1, match.out = m_out_rb1, nboots = 500)
#install.packages("cobalt")
library(cobalt)

love.plot(mb_formula_rb1, 
          data = df_clean_rb1, 
          weights = m_out_rb1, # Use the match object as the source of weights
          binary = "std",
          thresholds = c(m = .25),
          alpha = 0.7,
          title = "Covariate Balance (SMD)",
          grid = TRUE)

love.plot(mb_formula_rb1, 
          data = df_clean_rb1, 
          weights = m_out_rb1, # Use the match object as the source of weights
          stats = "ks.statistics", # Change to KS statistics
          binary = "std",
          thresholds = c(ks = 0.1), 
          alpha = 0.7,
          grid = TRUE,
          title = "Covariate Balance (KS Statistics)")
bal.tab(mb_formula_rb1, 
        data = df_clean_rb1, 
        weights = m_out_rb1, # Use the match object as the source of weights
        estimand = "ATT",
        binary = "std",      # <--- Forces binary vars to use SMD
        continuous = "std",  # <--- Forces continuous vars (default) to use SMD
        un = TRUE,
        stats = c("m", "v", "ks"),   # Mean diffs, Variance ratios, KS stats
        thresholds = c(m = 0.25, ks = 0.1))
set.seed(123)
# --- Call Function ---
balance_table_rb1 <- get_balance_table(
  formula = mb_formula_rb1, 
  data = df_clean_rb1, 
  match_out = m_out_rb1, 
  nboots = 500
)

balance_table_rb1

H1 vs R1: Comparison of Matching Results


matched_data_H1 <- rbind(
  df_clean_H1[m_out_H1$index.treated, ],
  df_clean_H1[m_out_H1$index.control, ]
)
n_pairs <- length(m_out_H1$index.treated)
matched_data_H1$pair_id <- c(1:n_pairs, 1:n_pairs)

matched_data_rb1 <- rbind(
  df_clean_rb1[m_out_rb1$index.treated, ],
  df_clean_rb1[m_out_rb1$index.control, ]
)
n_pairs <- length(m_out_rb1$index.treated)
matched_data_rb1$pair_id <- c(1:n_pairs, 1:n_pairs)

matches <- cbind(Pair_ID = matched_data_H1$pair_id, 
                 Treated = matched_data_H1$cas_id[matched_data_H1$fem_sig == 1], 
                 ModelH1_Matches = matched_data_H1$cas_id[matched_data_H1$fem_sig == 0], 
                 ModelR1_Matches = matched_data_rb1$cas_id[matched_data_rb1$fem_sig == 0])
matches[1:6, ]

# Compare outcome observations of matched units
matchcomp_days <- cbind(Pair_ID = matched_data_H1$pair_id,
                        cas_id = matched_data_H1$cas_id,
                        fem_sig = matched_data_H1$fem_sig,
                        days_of_peace_H1 = matched_data_H1$days_of_peace,
                        days_of_peace_rb1 = matched_data_rb1$days_of_peace)
matchcomp_pc <- cbind(Pair_ID = matched_data_H1$pair_id,
                      cas_id = matched_data_H1$cas_id,
                      fem_sig = matched_data_H1$fem_sig,
                      pc_nd_H1 = matched_data_H1$pc_nd,
                      pc_nd_rb1 = matched_data_rb1$pc_nd)
matchcomp_days
matchcomp_pc

H1 vs R1: Comparison of Treatment Effect Estimates


# ======== Run Match() with outcome variable =======

# Outcome
Y  <- df_clean_rb1$days_of_peace
m_out_rb1A <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_rb1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ======

summary(m_out_rb1A)

ATT_est <- m_out_rb1A$est
ATT_se <- m_out_rb1A$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 4)))
print(paste("Standard Error:", round(ATT_se, 4)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))

# ======== Run Match() with outcome variable =======
# Outcome
Y  <- df_clean_rb1$pc_nd
m_out_rb1B <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_rb1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ====

summary(m_out_rb1B)

ATT_est <- m_out_rb1B$est
ATT_se <- m_out_rb1B$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 4)))
print(paste("Standard Error:", round(ATT_se, 4)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))
print ("H1A vs. R1A")
summary(m_out_H1A)
summary(m_out_rb1A)
print ("H1B vs. R1B")
summary(m_out_H1B)
summary(m_out_rb1B)

Hypothesis 1: Survival Analysis

# ===== Report Balance and Lowest P-Value ======
set.seed(123)
# treatment indicator is the dependent variable, check balance for all covariates
mb_formula_H1 <- fem_sig ~ con_dur + con_int + con_iss +  war_par + gdp + dem + hum_rig + fem_leg + fem_com + lef_ide + start_date_num

MatchBalance(mb_formula_H1, data = df_clean_H1, match.out = m_out_H1, nboots = 500)

***** (V1) con_dur *****
                       Before Matching       After Matching
mean treatment........     27.333            27.333 
mean control..........      20.68              19.5 
std mean diff.........      47.54            55.971 

mean raw eQQ diff.....          6            7.8333 
med  raw eQQ diff.....        3.5               6.5 
max  raw eQQ diff.....         16                19 

mean eCDF diff........    0.14162           0.13636 
med  eCDF diff........    0.12667           0.16667 
max  eCDF diff........    0.35333           0.33333 

var ratio (Tr/Co).....    0.84093           0.76302 
T-test p-value........    0.31464           0.15974 
KS Bootstrap p-value..      0.382             0.826 
KS Naive p-value......    0.39891           0.93074 
KS Statistic..........    0.35333           0.33333 


***** (V2) con_int *****
                       Before Matching       After Matching
mean treatment........    0.11265           0.11265 
mean control..........    0.26814          0.082458 
std mean diff.........    -86.378             16.77 

mean raw eQQ diff.....    0.19184          0.040991 
med  raw eQQ diff.....    0.14263          0.016204 
max  raw eQQ diff.....       0.55           0.10729 

mean eCDF diff........    0.18784          0.071429 
med  eCDF diff........    0.18333                 0 
max  eCDF diff........    0.38667           0.16667 

var ratio (Tr/Co).....     0.3793            1.8253 
T-test p-value........   0.099899           0.72072 
KS Bootstrap p-value..      0.244             0.998 
KS Naive p-value......    0.30081                 1 
KS Statistic..........    0.38667           0.16667 


***** (V3) con_iss *****
                       Before Matching       After Matching
mean treatment........    0.66667           0.66667 
mean control..........       0.78               0.5 
std mean diff.........    -21.947            32.275 

mean raw eQQ diff.....          0           0.16667 
med  raw eQQ diff.....          0                 0 
max  raw eQQ diff.....          0                 1 

mean eCDF diff........   0.056667          0.083333 
med  eCDF diff........   0.056667          0.083333 
max  eCDF diff........    0.11333           0.16667 

var ratio (Tr/Co).....     1.5229           0.88889 
T-test p-value........    0.62384           0.57831 


***** (V4) war_par *****
                       Before Matching       After Matching
mean treatment........          5                 5 
mean control..........       6.86            6.1667 
std mean diff.........    -73.523           -46.117 

mean raw eQQ diff.....          3            2.1667 
med  raw eQQ diff.....        0.5               0.5 
max  raw eQQ diff.....         15                10 

mean eCDF diff........   0.086061          0.071429 
med  eCDF diff........        0.1                 0 
max  eCDF diff........       0.18           0.16667 

var ratio (Tr/Co).....    0.16592           0.17128 
T-test p-value........    0.19153           0.56147 
KS Bootstrap p-value..      0.858             0.994 
KS Naive p-value......    0.85647                 1 
KS Statistic..........       0.18           0.16667 


***** (V5) gdp *****
                       Before Matching       After Matching
mean treatment........     3.2898            3.2898 
mean control..........     2.7526            2.7601 
std mean diff.........     66.288            65.373 

mean raw eQQ diff.....    0.51179            0.5297 
med  raw eQQ diff.....    0.52796            0.5241 
max  raw eQQ diff.....    0.82098           0.93254 

mean eCDF diff........    0.20213           0.19444 
med  eCDF diff........    0.18667           0.16667 
max  eCDF diff........    0.46667               0.5 

var ratio (Tr/Co).....     2.2964            2.0773 
T-test p-value........    0.16866           0.11621 
KS Bootstrap p-value..      0.128             0.354 
KS Naive p-value......    0.13832           0.47403 
KS Statistic..........    0.46667               0.5 


***** (V6) dem *****
                       Before Matching       After Matching
mean treatment........    0.83333           0.83333 
mean control..........       0.32           0.66667 
std mean diff.........     68.192             22.14 

mean raw eQQ diff.....        0.5           0.16667 
med  raw eQQ diff.....        0.5                 0 
max  raw eQQ diff.....          1                 1 

mean eCDF diff........    0.17111          0.055556 
med  eCDF diff........    0.16667                 0 
max  eCDF diff........    0.34667           0.16667 

var ratio (Tr/Co).....     2.5521             2.125 
T-test p-value........    0.15838           0.57831 
KS Bootstrap p-value..      0.112             0.902 
KS Naive p-value......    0.17238                 1 
KS Statistic..........    0.34667           0.16667 


***** (V7) hum_rig *****
                       Before Matching       After Matching
mean treatment........     10.167            10.167 
mean control..........       6.32            8.8333 
std mean diff.........     106.82            37.028 

mean raw eQQ diff.....     3.8333                 2 
med  raw eQQ diff.....          4               1.5 
max  raw eQQ diff.....          6                 4 

mean eCDF diff........        0.3           0.16667 
med  eCDF diff........    0.27333           0.16667 
max  eCDF diff........    0.73333               0.5 

var ratio (Tr/Co).....     1.6682            1.4461 
T-test p-value........   0.046585           0.31494 
KS Bootstrap p-value.. < 2.22e-16              0.27 
KS Naive p-value......  0.0012302           0.35065 
KS Statistic..........    0.73333               0.5 


***** (V8) fem_leg *****
                       Before Matching       After Matching
mean treatment........     1.1667            1.1667 
mean control..........       1.46            1.6667 
std mean diff.........    -38.967           -66.421 

mean raw eQQ diff.....    0.33333               0.5 
med  raw eQQ diff.....          0               0.5 
max  raw eQQ diff.....          1                 1 

mean eCDF diff........       0.08             0.125 
med  eCDF diff........       0.08          0.083333 
max  eCDF diff........       0.16           0.33333 

var ratio (Tr/Co).....    0.59816           0.53125 
T-test p-value........    0.41188           0.45135 
KS Bootstrap p-value..      0.762             0.536 
KS Naive p-value......    0.87781           0.74026 
KS Statistic..........       0.16           0.33333 


***** (V9) fem_com *****
                       Before Matching       After Matching
mean treatment........     1.8333            1.8333 
mean control..........       1.12           0.83333 
std mean diff.........     61.018             85.54 

mean raw eQQ diff.....    0.83333                 1 
med  raw eQQ diff.....          1                 1 
max  raw eQQ diff.....          2                 2 

mean eCDF diff........    0.17833              0.25 
med  eCDF diff........    0.22333           0.33333 
max  eCDF diff........    0.26667           0.33333 

var ratio (Tr/Co).....     1.1691            1.4138 
T-test p-value........    0.20391           0.11626 
KS Bootstrap p-value..       0.39             0.648 
KS Naive p-value......    0.45736           0.84416 
KS Statistic..........    0.26667           0.33333 


***** (V10) lef_ide *****
                       Before Matching       After Matching
mean treatment........    0.33333           0.33333 
mean control..........       0.04                 0 
std mean diff.........     56.804             64.55 

mean raw eQQ diff.....    0.16667           0.33333 
med  raw eQQ diff.....          0                 0 
max  raw eQQ diff.....          1                 1 

mean eCDF diff........    0.14667           0.16667 
med  eCDF diff........    0.14667           0.16667 
max  eCDF diff........    0.29333           0.33333 

var ratio (Tr/Co).....     6.8056               Inf 
T-test p-value........    0.22441           0.14381 


***** (V11) start_date_num *****
                       Before Matching       After Matching
mean treatment........      10704             10704 
mean control..........      11066             10666 
std mean diff.........    -22.292            2.3179 

mean raw eQQ diff.....     647.83            83.333 
med  raw eQQ diff.....      432.5              92.5 
max  raw eQQ diff.....       1935               129 

mean eCDF diff........        0.1          0.083333 
med  eCDF diff........   0.076667          0.083333 
max  eCDF diff........       0.34           0.16667 

var ratio (Tr/Co).....    0.82872            1.0209 
T-test p-value........    0.62658           0.32108 
KS Bootstrap p-value..      0.436                 1 
KS Naive p-value......    0.46919                 1 
KS Statistic..........       0.34           0.16667 


Before Matching Minimum p.value: < 2.22e-16 
Variable Name(s): hum_rig  Number(s): 7 

After Matching Minimum p.value: 0.11621 
Variable Name(s): gdp  Number(s): 5 
#install.packages("cobalt")
library(cobalt)

love.plot(mb_formula_H1, 
          data = df_clean_H1, 
          weights = m_out_H1, # Use the match object as the source of weights
          binary = "std",
          thresholds = c(m = .25),
          alpha = 0.7,
          title = "Covariate Balance (SMD)",
          grid = TRUE)


love.plot(mb_formula_H1, 
          data = df_clean_H1, 
          weights = m_out_H1, # Use the match object as the source of weights
          stats = "ks.statistics", # Change to KS statistics
          binary = "std",
          thresholds = c(ks = 0.1), 
          alpha = 0.7,
          grid = TRUE,
          title = "Covariate Balance (KS Statistics)")

library(ggplot2)
library(gridExtra) # Required for arranging plots

# Panel A: Good Balance (Continuous - ECDF)
p1 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "start_date_num", type = "ecdf") + 
      ggtitle("A. Good Balance: Start Date")

# Panel B: Poor Balance (Continuous - ECDF)
p2 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "gdp", type = "ecdf") + 
      ggtitle("B. Poor Balance: GDP")

# Panel C: Good Balance (Discrete - Histogram)
p3 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "dem", type = "histogram") + 
      ggtitle("C. Good Balance: Democracy")

# Panel D: Poor Balance (Discrete - Histogram)
p4 <- bal.plot(m_out_H1, treat = Tr, covs = X, 
               var.name = "hum_rig", type = "histogram") + 
      ggtitle("D. Poor Balance: Human Rights")

# Arrange plots into a 2x2 grid
grid.arrange(p1, p2, p3, p4, nrow = 2)

bal.tab(mb_formula_H1, 
        data = df_clean_H1, 
        weights = m_out_H1, # Use the match object as the source of weights
        estimand = "ATT",
        binary = "std",      # <--- Forces binary vars to use SMD
        continuous = "std",  # <--- Forces continuous vars (default) to use SMD
        un = TRUE,
        stats = c("m", "v", "ks"),   # Mean diffs, Variance ratios, KS stats
        thresholds = c(m = 0.25, ks = 0.1))
Balance Measures
                  Type Diff.Un V.Ratio.Un  KS.Un Diff.Adj         M.Threshold V.Ratio.Adj KS.Adj
con_dur        Contin.  0.4754     0.8409 0.3533   0.5597 Not Balanced, >0.25      0.7630 0.3333
con_int        Contin. -0.8638     0.3793 0.3867   0.1677     Balanced, <0.25      1.8253 0.1667
con_iss         Binary -0.2404          . 0.1133   0.3536 Not Balanced, >0.25           . 0.1667
war_par        Contin. -0.7352     0.1659 0.1800  -0.4612 Not Balanced, >0.25      0.1713 0.1667
gdp            Contin.  0.6629     2.2964 0.4667   0.6537 Not Balanced, >0.25      2.0773 0.5000
dem            Contin.  0.6819     2.5521 0.3467   0.2214     Balanced, <0.25      2.1250 0.1667
hum_rig        Contin.  1.0682     1.6682 0.7333   0.3703 Not Balanced, >0.25      1.4461 0.5000
fem_leg        Contin. -0.3897     0.5982 0.1600  -0.6642 Not Balanced, >0.25      0.5312 0.3333
fem_com        Contin.  0.6102     1.1691 0.2667   0.8554 Not Balanced, >0.25      1.4138 0.3333
lef_ide         Binary  0.6223          . 0.2933   0.7071 Not Balanced, >0.25           . 0.3333
start_date_num Contin. -0.2229     0.8287 0.3400   0.0232     Balanced, <0.25      1.0209 0.1667
                     KS.Threshold
con_dur        Not Balanced, >0.1
con_int        Not Balanced, >0.1
con_iss        Not Balanced, >0.1
war_par        Not Balanced, >0.1
gdp            Not Balanced, >0.1
dem            Not Balanced, >0.1
hum_rig        Not Balanced, >0.1
fem_leg        Not Balanced, >0.1
fem_com        Not Balanced, >0.1
lef_ide        Not Balanced, >0.1
start_date_num Not Balanced, >0.1

Balance tally for mean differences
                    count
Balanced, <0.25         3
Not Balanced, >0.25     8

Variable with the greatest mean difference
 Variable Diff.Adj         M.Threshold
  fem_com   0.8554 Not Balanced, >0.25

Balance tally for KS statistics
                   count
Balanced, <0.1         0
Not Balanced, >0.1    11

Variable with the greatest KS statistic
 Variable KS.Adj       KS.Threshold
      gdp    0.5 Not Balanced, >0.1

Effective sample sizes
           Control Treated
Unadjusted      50       6
Adjusted         6       6
library(Matching)

get_balance_table <- function(formula, data, match_out, nboots = 500) {
  
  # 1. Run MatchBalance
  mb <- MatchBalance(formula, data = data, match.out = match_out, nboots = nboots, print.level = 0)
  
  # 2. Define the "Nested" Null Coalescing Operator 
  #    (This allows us to chain checks: "Try A, if NULL try B, if NULL try C")
  `%||%` <- function(a, b) if (is.null(a)) b else a

  # 3. Define the Extractors
  #    T-Test: Simple check
  get_tt <- function(x) x$tt$p.value %||% NA
  
  #    KS-Test: The "Nested" Approach
  #    1. Try nested bootstrap (x$ks$ks.boot.pvalue) <--- PRIORITY
  #    2. Try top-level bootstrap (x$ks.boot.pvalue)
  #    3. Try standard KS (x$ks$p.value)
  get_ks <- function(x) x$ks$ks.boot.pvalue %||% x$ks.boot.pvalue %||% x$ks$p.value %||% NA

  # 4. Extract efficiently with sapply
  idx <- seq_along(mb$AfterMatching)
  vars <- all.vars(formula)[-1]
  final_names <- if(length(vars) == length(idx)) vars else paste0("Var_", idx)

  df <- data.frame(
    Variable  = final_names,
    Pre_T_P   = round(sapply(idx, function(i) get_tt(mb$BeforeMatching[[i]])), 3),
    Post_T_P  = round(sapply(idx, function(i) get_tt(mb$AfterMatching[[i]])), 3),
    Pre_KS_P  = round(sapply(idx, function(i) get_ks(mb$BeforeMatching[[i]])), 3),
    Post_KS_P = round(sapply(idx, function(i) get_ks(mb$AfterMatching[[i]])), 3)
  )
  
  # 5. Status: Pass if (KS is NA or >0.05) AND (T-test > 0.05)
  df$Status <- ifelse((is.na(df$Post_KS_P) | df$Post_KS_P > 0.1) & df$Post_T_P > 0.1, "PASS", "FAIL")
  
  return(df)
}

sensmaker Sensitivity Test for Survival Analysis

set.seed(123)
# --- Call Function ---
balance_table_H1 <- get_balance_table(
  formula = mb_formula_H1, 
  data = df_clean_H1, 
  match_out = m_out_H1, 
  nboots = 500
)

balance_table_H1
# Include outcome variable for effect estimate
Y  <- df_clean_H1$days_of_peace
m_out_H1A <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_H1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ======
summary(m_out_H1A)

Estimate...  2624.2 
AI SE......  1031.8 
T-stat.....  2.5433 
p.val......  0.01098 

Original number of observations..............  56 
Original number of treated obs...............  6 
Matched number of observations...............  6 
Matched number of observations  (unweighted).  6 

Caliper (SDs)........................................   Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf 0.1023685 
Number of obs dropped by 'exact' or 'caliper'  0 
ATT_est <- m_out_H1A$est
ATT_se <- m_out_H1A$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 2)))
[1] "Estimated ATT: 2624.17"
print(paste("Standard Error:", round(ATT_se, 2)))
[1] "Standard Error: 1031.78"
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
[1] "95% CI: [ 601.876 , 4646.458 ]"
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))
[1] "99% CI: [ -33.701 , 5282.035 ]"

Hypothesis 2: Women participation and quality of peace agreement (content)


# ============ Remove NAs from ALL necessary variables =============

treatnent_var <- c("fem_sig")
outcome_vars <- c("cpa", "civ_soc")
pretreatment_covariates <- c("con_dur", "con_int", "con_iss", "war_par", "gdp", "dem", "hum_rig", "fem_com", "lef_ide", "fem_leg", "start_date_num") 

cleaning_vars <- c(treatnent_var, outcome_vars, pretreatment_covariates)

# Check which columns contain missing values
colSums(is.na(data[, cleaning_vars])) 

# Clean the data to enable genetic matching (cannot have NAs)
df_clean_H2 <- na.omit(data[, c("cas_id", cleaning_vars)])
df_clean_H2

#Check how many rows have been dropped
cat("Number of control/treatment units in sample (before cleaning):")
table(data$fem_sig)

cat("Number of control/treatment units in sample (after cleaning):")
table(df_clean_H2$fem_sig)
set.seed(123)

# ============== DEFINE MATCHING OBJECTS =============
# Treatment 
Tr <- df_clean_H2$fem_sig

# Matching Matrix (X)
matching_vars <- pretreatment_covariates
X <- df_clean_H2[, matching_vars]
# do not include outcomes

# ============= RUN GENMATCH ===============

genout_H2 <- GenMatch(Tr = Tr, X = X, BalanceMatrix = X, 
                   estimand = "ATT", pop.size = 5000, 
                   replace=FALSE,
                   print.level = 0)

# ============= RUN MATCH ===============

m_out_H2 <- Match(Tr = Tr, X = X, Weight.matrix = genout_H2, 
                  estimand = "ATT",
                  replace=FALSE)


# ===== Report on matching summary ======

# Count how many times each treated unit appears in the match list
matches_per_treated <- table(m_out_H2$index.treated)
# Check the distribution (e.g., how many got 1 match, how many got 2, etc.)
table(matches_per_treated)

# Total treated units in original data
total_treated <- sum(Tr)

# Total treated units that successfully found a match
matched_treated <- length(unique(m_out_H2$index.treated)) #all treated units have been matched

cat("Original Treated:", total_treated, "\n")
cat("Matched Treated: ", matched_treated, "\n")
cat("Dropped:         ", total_treated - matched_treated, "\n")

# ===== Report Balance and Lowest P-Value ======
set.seed(123)
# treatment indicator is the dependent variable, check balance for all covariates
mb_formula_H2 <- fem_sig ~ con_dur + con_int + con_iss +  war_par + gdp + dem + hum_rig + fem_leg + fem_com + lef_ide + start_date_num

MatchBalance(mb_formula_H2, data = df_clean_H2, match.out = m_out_H2, nboots = 500)

#install.packages("cobalt")
library(cobalt)

love.plot(mb_formula_H2, 
          data = df_clean_H2, 
          weights = m_out_H2, # Use the match object as the source of weights
          binary = "std",
          thresholds = c(m = .25),
          alpha = 0.7,
          title = "Covariate Balance (SMD)",
          grid = TRUE)

love.plot(mb_formula_H2, 
          data = df_clean_H2, 
          weights = m_out_H2, # Use the match object as the source of weights
          stats = "ks.statistics", # Change to KS statistics
          binary = "std",
          thresholds = c(ks = 0.1), 
          alpha = 0.7,
          grid = TRUE,
          title = "Covariate Balance (KS Statistics)")
bal.tab(mb_formula_H2, 
        data = df_clean_H2, 
        weights = m_out_H2, # Use the match object as the source of weights
        estimand = "ATT",
        binary = "std",      # <--- Forces binary vars to use SMD
        continuous = "std",  # <--- Forces continuous vars (default) to use SMD
        un = TRUE,
        stats = c("m", "v", "ks"),   # Mean diffs, Variance ratios, KS stats
        thresholds = c(m = 0.25, ks = 0.1))
set.seed(123)
# --- Call Function ---
balance_table_H2 <- get_balance_table(
  formula = mb_formula_H2, 
  data = df_clean_H2, 
  match_out = m_out_H2, 
  nboots = 500
)

balance_table_H2

Hypothesis 2A: fem_sig on cpa

set.seed(123)

# ========== Run Match() with outcome variable =======

Y  <- df_clean_H2$cpa # Outcome
m_out_H2A <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_H2, estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ======
summary(m_out_H2A)

ATT_est <- m_out_H2A$est
ATT_se <- m_out_H2A$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 4)))
print(paste("Standard Error:", round(ATT_se, 4)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))

Hypothesis 2B: fem_sig on civ_soc


set.seed(123)
# ========== Run Match() with outcome variable =======

Y  <- df_clean_H2$civ_soc # Outcome
m_out_H2B <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_H2, estimand = "ATT")


# ===== Estimate Treatment Effect, SE, and CI ======
summary(m_out_H2B)

ATT_est <- m_out_H2B$est
ATT_se <- m_out_H2B$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 2)))
print(paste("Standard Error:", round(ATT_se, 2)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))

Model H2: Rosenbaum Bounds Sensitivity Analysis

# Outcome
Y  <- df_clean_H1$pc_nd
m_out_H1B <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_H1, 
               caliper = caliper_vec, 
               estimand = "ATT")

# ===== Estimate Treatment Effect, SE, and CI ======

summary(m_out_H1B)

Estimate...  -0.5 
AI SE......  0.20412 
T-stat.....  -2.4495 
p.val......  0.014306 

Original number of observations..............  56 
Original number of treated obs...............  6 
Matched number of observations...............  6 
Matched number of observations  (unweighted).  6 

Caliper (SDs)........................................   Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf 0.1023685 
Number of obs dropped by 'exact' or 'caliper'  0 
ATT_est <- m_out_H1B$est
ATT_se <- m_out_H1B$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 2)))
[1] "Estimated ATT: -0.5"
print(paste("Standard Error:", round(ATT_se, 2)))
[1] "Standard Error: 0.2"
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
[1] "95% CI: [ -0.9 , -0.1 ]"
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))
[1] "99% CI: [ -1.026 , 0.026 ]"
# Run Sensitivity Analysis on Durability (Days of Peace)
#install.packages("rbounds")
library(rbounds)

# Obtain indexes for matched treatment and control units
treated_indices <- m_out_H1$index.treated
control_indices <- m_out_H1$index.control

# Extract 'Days of Peace' for both groups
days_Tr <- as.numeric(df_clean_H1$days_of_peace[m_out_H1$index.treated])
days_Co <- as.numeric(df_clean_H1$days_of_peace[m_out_H1$index.control])

# P-Value
psens_H1A <- psens(x = days_Tr, 
                   y = days_Co, 
                   Gamma = 3, # We check up to a "tripling" of the odds of hidden bias
                   GammaInc = 0.5) # We move in steps of 0.5
# The probability of assignment to treatment under hidden bias Gamma
# For Upper Bound (worst case), we assume bias helps the observed effect

# Hodges-Lehmann Estimate (non-parametric)
hlsens_H1A <- hlsens(x = days_Tr, 
                   y = days_Co, 
                   pr = 0.5,
                   Gamma = 10, 
                   GammaInc = 1) 
psens_H1A

 Rosenbaum Sensitivity Test for Wilcoxon Signed Rank P-Value 
 
Unconfounded estimate ....  0.0579 

 Note: Gamma is Odds of Differential Assignment To
 Treatment Due to Unobserved Factors 
 
# result is only "marginally significant" (p=0.06) assuming no hidden bias
# statistical significance disappears with even a tiny amount of hidden bias
hlsens_H1A

 Rosenbaum Sensitivity Test for Hodges-Lehmann Point Estimate 
 
Unconfounded estimate ....  2661 

 Note: Gamma is Odds of Differential Assignment To
 Treatment Due to Unobserved Factors 
 
# magnitude of the effect point estimate is quite robust
#it would take a massive amount of unobserved bias (Gamma = 7) to reduce the estimated effect to zero
# even if unobserved factors caused massive selection bias, the underlying signal still suggests a positive effect on duration

Robustness Check

# ============ Remove NAs from ALL necessary variables =============

# Check which columns contain missing values
colSums(is.na(data[, cleaning_vars])) 

# Clean the data to enable genetic matching (cannot have NAs)
pretreatment_covariates <- c("con_dur", "con_int", "con_iss", "war_par", "gdp", "dem", "hum_rig", "fem_com", "lef_ide", "fem_leg", "start_date_num")
treatnent_var <- c("fem_sig")
outcome_vars <- c("cpa", "civ_soc")

add_covariates <- c("pow_sha", "quo", "un_pea_con") # additional covariates

# This list includes Y, Tr, and X. We use it ONLY for na.omit.
cleaning_vars <- c(treatnent_var, outcome_vars, pretreatment_covariates, add_covariates)

df_clean_rb2 <- na.omit(data[, c("cas_id", cleaning_vars)])
df_clean_rb2

# Check how many rows have been dropped
cat("Number of control/treatment units in sample (before cleaning):")
table(data$fem_sig)
cat("Number of control/treatment units in sample (after cleaning):")
table(df_clean_rb2$fem_sig)
# ========== DEFINE MATCHING OBJECTS ===============

set.seed(123)

# Treatment 
Tr <- df_clean_rb2$fem_sig

# Matching Matrix (X)
matching_vars <- c(pretreatment_covariates, add_covariates) # include additional covariates
X <- df_clean_rb2[, matching_vars]

# =========== RUN GENMATCH =================

genout_rb2 <- GenMatch(Tr = Tr, X = X, BalanceMatrix = X,
                   replace=FALSE, 
                   estimand = "ATT", pop.size = 5000, 
                   print.level = 0)

# =============== RUN MATCH ===============

m_out_rb2 <- Match(Tr = Tr, X = X, Weight.matrix = genout_rb2, estimand = "ATT", replace=FALSE)


# ========== Report on matching summary =========
# Count how many times each treated unit appears in the match list
matches_per_treated <- table(m_out_rb2 $index.treated)
# Check the distribution (e.g., how many got 1 match, how many got 2, etc.)
table(matches_per_treated)

# Total treated units in original data
total_treated <- sum(Tr)

# Total treated units that successfully found a match
matched_treated <- length(unique(m_out_rb2 $index.treated)) #all treated units have been matched

cat("Original Treated:", total_treated, "\n")
cat("Matched Treated: ", matched_treated, "\n")
cat("Dropped:         ", total_treated - matched_treated, "\n")
set.seed(123)
# ===== Report Balance and Lowest P-Value ======

# treatment indicator is the dependent variable, check balance for all covariates
mb_formula_rb2 <- fem_sig ~ con_dur + con_int + con_iss +  war_par + gdp + dem + hum_rig + fem_leg + fem_com + lef_ide + pow_sha + quo + un_pea_con + start_date_num

MatchBalance(mb_formula_rb2, data = df_clean_rb2, match.out = m_out_rb2, nboots = 500)

H2 vs R2: Comparison of Matching Results

bal.tab(mb_formula_rb2, 
        data = df_clean_rb2, 
        weights = m_out_rb2, # Use the match object as the source of weights
        estimand = "ATT",
        binary = "std",      # <--- Forces binary vars to use SMD
        continuous = "std",  # <--- Forces continuous vars (default) to use SMD
        un = TRUE,
        stats = c("m", "v", "ks"),   # Mean diffs, Variance ratios, KS stats
        thresholds = c(m = 0.25, ks = 0.1))
set.seed(123)
# --- Call Function ---
balance_table_rb2 <- get_balance_table(
  formula = mb_formula_rb2, 
  data = df_clean_rb2, 
  match_out = m_out_rb2, 
  nboots = 500
)

balance_table_rb2
matched_data_H2 <- rbind(
  df_clean_H2[m_out_H2$index.treated, ],
  df_clean_H2[m_out_H2$index.control, ]
)
n_pairs <- length(m_out_H2$index.treated)
matched_data_H2$pair_id <- c(1:n_pairs, 1:n_pairs)

matched_data_rb2 <- rbind(
  df_clean_rb2[m_out_rb2$index.treated, ],
  df_clean_rb2[m_out_rb2$index.control, ]
)
n_pairs <- length(m_out_rb2$index.treated)
matched_data_rb2$pair_id <- c(1:n_pairs, 1:n_pairs)

matches <- cbind(Pair_ID = matched_data_H2$pair_id, 
                 Treated = matched_data_H2$cas_id[matched_data_H2$fem_sig == 1], 
                 ModelH2_Matches = matched_data_H2$cas_id[matched_data_H2$fem_sig == 0], 
                 ModelR2_Matches = matched_data_rb2$cas_id[matched_data_rb2$fem_sig == 0])
matches[1:6, ]

# Compare outcome observations of matched units
matchcomp_cpa <- cbind(Pair_ID = matched_data_H2$pair_id,
                        cas_id = matched_data_H2$cas_id,
                        fem_sig = matched_data_H2$fem_sig,
                        cpa_H2 = matched_data_H2$cpa,
                        cpa_rb2 = matched_data_rb2$cpa)
matchcomp_civ_soc <- cbind(Pair_ID = matched_data_H2$pair_id,
                      cas_id = matched_data_H2$cas_id,
                      fem_sig = matched_data_H2$fem_sig,
                      civ_soc_H2 = matched_data_H2$civ_soc,
                      civ_soc_rb2 = matched_data_rb2$civ_soc)
matchcomp_cpa
matchcomp_civ_soc

H2 vs R2: Comparison of Treatment Effect Estimates


# ========== Run Match() with outome variable (cpa) ==============
set.seed(123)
# Outcome
Y  <- df_clean_rb2$cpa
m_out_rb2A <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_rb2, estimand = "ATT", replace = FALSE)

# ===== Estimate Treatment Effect, SE, and CI ======

summary(m_out_rb2A)

ATT_est <- m_out_rb2A$est
ATT_se <- 0.20412#m_out_rb2A$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 2)))
print(paste("Standard Error:", round(ATT_se, 2)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))
set.seed(123)
# ========== Run Match() with outome variable (civ_soc) ==============
# Outcome
Y  <- df_clean_rb2$civ_soc
m_out_rb2B <- Match(Y = Y, Tr = Tr, X = X, Weight.matrix = genout_rb2, estimand = "ATT", replace = FALSE)

# ===== Estimate Treatment Effect, SE, and CI ======
summary(m_out_rb2B)

ATT_est <- m_out_rb2B$est
ATT_se <- 0.15215 #m_out_rb2B$se

#----- Get Confidence Intervals ------
# CI bounds given by point estimate +/- margin of error
# CV for 95% interval is 1.96
ci_lower95 <- ATT_est - 1.96 * ATT_se
ci_upper95 <- ATT_est + 1.96 * ATT_se
# CV for 99% interval is 2.576
ci_lower99 <- ATT_est - 2.576 * ATT_se
ci_upper99 <- ATT_est + 2.576 * ATT_se

print(paste("Estimated ATT:", round(ATT_est, 3)))
print(paste("Standard Error:", round(ATT_se, 3)))
print(paste("95% CI: [", round(ci_lower95, 3), ",", round(ci_upper95, 3), "]"))
print(paste("99% CI: [", round(ci_lower99, 3), ",", round(ci_upper99, 3), "]"))
print ("H2A vs. R2A")
summary(m_out_H2A)
summary(m_out_rb2A)
print ("H2B vs. R2B")
summary(m_out_H2B)
summary(m_out_rb2B)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgSW5pdGlhbCBEYXRhIFByZXBhcmF0aW9uCgpgYGB7cn0KcmF3X2RhdGEgPC0gcmVhZC5jc3YoImh0dHBzOi8vdGlueXVybC5jb20vNDczNnhqbXciKQoKbGlicmFyeShkcGx5cikKCiMgQ29sbGFwc2UgdGhlIGRhdGFzZXQgdG8gb25lIG9ic2VydmF0aW9uIHBlciBhZ3JlZW1lbnQgKGNhc19pZCkKIyBXZSBrZWVwIHRoZSByb3cgd2l0aCB0aGUgbGF0ZXN0ICd5ZWFyJyB0byBjYXB0dXJlIHRoZSBmaW5hbCBvdXRjb21lLgpkYXRhIDwtIHJhd19kYXRhICU+JQogIGdyb3VwX2J5KGNhc19pZCkgJT4lCiAgc2xpY2VfbWF4KG9yZGVyX2J5ID0geWVhciwgbiA9IDEpICU+JSAjIFNlbGVjdHMgdGhlIHJvdyB3aXRoIHRoZSBoaWdoZXN0IHllYXIKICB1bmdyb3VwKCkKCiMgPT09PT09PT09PT09IFBSRVAgVkFSSUFCTEVTIElOIE9SSUdJTkFMIERBVEEgPT09PT09PT09PT09PT09PT0KZGF0YSRzdGFydF9kYXRlX29iaiA8LSBhcy5EYXRlKGRhdGEkc3RydF9wYSkKZGF0YSRlbmRfZGF0ZV9vYmogICA8LSBhcy5EYXRlKGRhdGEkbmRfcGEpCmRhdGEkc3RhcnRfZGF0ZV9udW0gPC0gYXMubnVtZXJpYyhkYXRhJHN0YXJ0X2RhdGVfb2JqKQpkYXRhJHdlZWtzX29mX3BlYWNlIDwtIGFzLm51bWVyaWMoZGlmZnRpbWUoZGF0YSRlbmRfZGF0ZV9vYmosIGRhdGEkc3RhcnRfZGF0ZV9vYmosIHVuaXRzID0gIndlZWtzIikpCmRhdGEkZGF5c19vZl9wZWFjZSAgPC0gYXMubnVtZXJpYyhkYXRhJGVuZF9kYXRlX29iaiAtIGRhdGEkc3RhcnRfZGF0ZV9vYmopCgojIENoZWNrIHRoZSBuZXcgZGltZW5zaW9ucwpzdHIoZGF0YSkKYGBgCgojIyBIeXBvdGhlc2lzIDE6IFdvbWVuIHBhcnRpY2lwYXRpb24gaW1wYWN0cyBwZWFjZSBkdXJhYmlsaXR5CgpgYGB7ciwgTW9kZWwgSDE6IERhdGEgUHJlcH0KCiMgPT09PT0gQ0xFQU5JTkc6IFJlbW92ZSBOQXMgZnJvbSBBTEwgbmVjZXNzYXJ5IHZhcmlhYmxlcyA9PT09CgojIERlZmluZSB2YXJpYWJsZXMgb2YgaW50ZXJlc3QKCnByZXRyZWF0bWVudF9jb3ZhcmlhdGVzIDwtIGMoImNvbl9kdXIiLCAiY29uX2ludCIsICJjb25faXNzIiwgIndhcl9wYXIiLCAiZ2RwIiwgImRlbSIsICJodW1fcmlnIiwgImZlbV9jb20iLCAibGVmX2lkZSIsICJmZW1fbGVnIiwgInN0YXJ0X2RhdGVfbnVtIikKCnRyZWF0bmVudF92YXIgPC0gYygiZmVtX3NpZyIpCm91dGNvbWVfdmFycyA8LSBjKCJkYXlzX29mX3BlYWNlIiwgInBjX25kIikKCmNsZWFuaW5nX3ZhcnMgPC0gYyh0cmVhdG5lbnRfdmFyLCBvdXRjb21lX3ZhcnMsIHByZXRyZWF0bWVudF9jb3ZhcmlhdGVzKSAjIFRoaXMgbGlzdCBpbmNsdWRlcyBZLCBUciwgYW5kIFguIFdlIHVzZSBpdCBPTkxZIGZvciBuYS5vbWl0LgoKIyBDaGVjayB3aGljaCBjb2x1bW5zIGNvbnRhaW4gbWlzc2luZyB2YWx1ZXMKY29sU3Vtcyhpcy5uYShkYXRhWywgY2xlYW5pbmdfdmFyc10pKSAKCiMgQ2xlYW4gdGhlIGRhdGEgdG8gZW5hYmxlIGdlbmV0aWMgbWF0Y2hpbmcgKGNhbm5vdCBoYXZlIE5BcykKZGZfY2xlYW5fSDEgPC0gbmEub21pdChkYXRhWywgYygiY2FzX2lkIiwgY2xlYW5pbmdfdmFycyldKQpkZl9jbGVhbl9IMQoKY2F0KCJOdW1iZXIgb2YgY29udHJvbC90cmVhdG1lbnQgdW5pdHMgaW4gc2FtcGxlIChiZWZvcmUgY2xlYW5pbmcpOiIpCnRhYmxlKGRhdGEkZmVtX3NpZykKCmNhdCgiTnVtYmVyIG9mIGNvbnRyb2wvdHJlYXRtZW50IHVuaXRzIGluIHNhbXBsZSAoYWZ0ZXIgY2xlYW5pbmcpOiIpCnRhYmxlKGRmX2NsZWFuX0gxJGZlbV9zaWcpCmBgYAoKYGBge3IsIE1vZGVsIEgxOiBHZW5ldGljIE1hdGNoaW5nfQpsaWJyYXJ5KHJnZW5vdWQpCmxpYnJhcnkoTWF0Y2hpbmcpCgpzZXQuc2VlZCgxMjMpCgojID09PT09PSBERUZJTkUgTUFUQ0hJTkcgT0JKRUNUUyA9PT09PT0KCiMgVHJlYXRtZW50IApUciA8LSBkZl9jbGVhbl9IMSRmZW1fc2lnCgojIE1hdGNoaW5nIE1hdHJpeCAoWCk6IE9OTFkgY29udGFpbnMgcHJlLXRyZWF0bWVudCBjb3ZhcmlhdGVzLgptYXRjaGluZ192YXJzIDwtIHByZXRyZWF0bWVudF9jb3ZhcmlhdGVzClggPC0gZGZfY2xlYW5fSDFbLCBtYXRjaGluZ192YXJzXQojIERvIG5vdCB1c2Ugb3V0Y29tZSBvYnNlcnZhdGlvbnMgdW50aWwgbWF0Y2hpbmcgaXMgY29tcGxldGUKCgojIFBSRVBBUkUgQ0FMSVBFUiAoZm9yIHN0YXJ0X2RhdGVfbnVtKQojIENhbGN1bGF0ZSBjYWxpcGVyIHZhbHVlIGZvciBzdGFydF9kYXRlX251bQpkZXNpcmVkX3dpbmRvd19kYXlzIDwtIDE4MApzZF9kYXRlIDwtIHNkKGRmX2NsZWFuX0gxJHN0YXJ0X2RhdGVfbnVtKQpjYWxpcGVyX3ZhbHVlIDwtIGRlc2lyZWRfd2luZG93X2RheXMgLyBzZF9kYXRlCgojIENyZWF0ZSBDYWxpcGVyIFZlY3RvcgojIFdlIG5lZWQgYSB2ZWN0b3Igb2YgSW5mcyBtYXRjaGluZyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gWApjYWxpcGVyX3ZlYyA8LSByZXAoSW5mLCBuY29sKFgpKQoKIyBBcHBseSByZXN0cmljdGlvbiBPTkxZIHRvIHRoZSBzdGFydCBkYXRlIGNvbHVtbgpkYXRlX2luZGV4IDwtIHdoaWNoKGNvbG5hbWVzKFgpID09ICJzdGFydF9kYXRlX251bSIpCmNhbGlwZXJfdmVjW2RhdGVfaW5kZXhdIDwtIGNhbGlwZXJfdmFsdWUKCiMgPT09PT09PT09PSBSVU4gR0VOTUFUQ0ggPT09PT09PT09PT09PT0KZ2Vub3V0X0gxIDwtIEdlbk1hdGNoKFRyID0gVHIsIFggPSBYLCBCYWxhbmNlTWF0cml4ID0gWCwgCiAgICAgICAgICAgICAgICAgICBjYWxpcGVyID0gY2FsaXBlcl92ZWMsCiAgICAgICAgICAgICAgICAgICBlc3RpbWFuZCA9ICJBVFQiLCBwb3Auc2l6ZSA9IDUwMDAsIAogICAgICAgICAgICAgICAgICAgcHJpbnQubGV2ZWwgPSAwKQoKIyA9PT09PT09PT09IFJVTiBNQVRDSCA9PT09PT09PT09PT09PQoKbV9vdXRfSDEgPC0gTWF0Y2goVHIgPSBUciwgWCA9IFgsIFdlaWdodC5tYXRyaXggPSBnZW5vdXRfSDEsIAogICAgICAgICAgICAgICBjYWxpcGVyID0gY2FsaXBlcl92ZWMsIAogICAgICAgICAgICAgICBlc3RpbWFuZCA9ICJBVFQiKQoKIyA9PT09PSBSZXBvcnQgb24gbWF0Y2hpbmcgc3VtbWFyeSA9PT09PT0KCiMgQ291bnQgaG93IG1hbnkgdGltZXMgZWFjaCB0cmVhdGVkIHVuaXQgYXBwZWFycyBpbiB0aGUgbWF0Y2ggbGlzdAptYXRjaGVzX3Blcl90cmVhdGVkIDwtIHRhYmxlKG1fb3V0X0gxJGluZGV4LnRyZWF0ZWQpCgojIENoZWNrIHRoZSBkaXN0cmlidXRpb24gKGUuZy4sIGhvdyBtYW55IGdvdCAxIG1hdGNoLCBob3cgbWFueSBnb3QgMiwgZXRjLikKdGFibGUobWF0Y2hlc19wZXJfdHJlYXRlZCkKCiMgVG90YWwgdHJlYXRlZCB1bml0cyBpbiBvcmlnaW5hbCBkYXRhCnRvdGFsX3RyZWF0ZWQgPC0gc3VtKFRyKQoKIyBUb3RhbCB0cmVhdGVkIHVuaXRzIHRoYXQgc3VjY2Vzc2Z1bGx5IGZvdW5kIGEgbWF0Y2gKbWF0Y2hlZF90cmVhdGVkIDwtIGxlbmd0aCh1bmlxdWUobV9vdXRfSDEkaW5kZXgudHJlYXRlZCkpCgpjYXQoIk9yaWdpbmFsIFRyZWF0ZWQ6IiwgdG90YWxfdHJlYXRlZCwgIlxuIikKY2F0KCJNYXRjaGVkIFRyZWF0ZWQ6ICIsIG1hdGNoZWRfdHJlYXRlZCwgIlxuIikKY2F0KCJEcm9wcGVkOiAgICAgICAgICIsIHRvdGFsX3RyZWF0ZWQgLSBtYXRjaGVkX3RyZWF0ZWQsICJcbiIpCmBgYAoKYGBge3IsIE1vZGVsIEgxOiBHZW5ldGljIE1hdGNoaW5nIFJlc3VsdHN9CiMgPT09PT0gUmVwb3J0IEJhbGFuY2UgYW5kIExvd2VzdCBQLVZhbHVlID09PT09PQpzZXQuc2VlZCgxMjMpCiMgdHJlYXRtZW50IGluZGljYXRvciBpcyB0aGUgZGVwZW5kZW50IHZhcmlhYmxlLCBjaGVjayBiYWxhbmNlIGZvciBhbGwgY292YXJpYXRlcwptYl9mb3JtdWxhX0gxIDwtIGZlbV9zaWcgfiBjb25fZHVyICsgY29uX2ludCArIGNvbl9pc3MgKyAgd2FyX3BhciArIGdkcCArIGRlbSArIGh1bV9yaWcgKyBmZW1fbGVnICsgZmVtX2NvbSArIGxlZl9pZGUgKyBzdGFydF9kYXRlX251bQoKTWF0Y2hCYWxhbmNlKG1iX2Zvcm11bGFfSDEsIGRhdGEgPSBkZl9jbGVhbl9IMSwgbWF0Y2gub3V0ID0gbV9vdXRfSDEsIG5ib290cyA9IDUwMCkKYGBgCgpgYGB7ciwgTW9kZWwgSDE6IExvdmUgUGxvdHN9CiNpbnN0YWxsLnBhY2thZ2VzKCJjb2JhbHQiKQpsaWJyYXJ5KGNvYmFsdCkKCmxvdmUucGxvdChtYl9mb3JtdWxhX0gxLCAKICAgICAgICAgIGRhdGEgPSBkZl9jbGVhbl9IMSwgCiAgICAgICAgICB3ZWlnaHRzID0gbV9vdXRfSDEsICMgVXNlIHRoZSBtYXRjaCBvYmplY3QgYXMgdGhlIHNvdXJjZSBvZiB3ZWlnaHRzCiAgICAgICAgICBiaW5hcnkgPSAic3RkIiwKICAgICAgICAgIHRocmVzaG9sZHMgPSBjKG0gPSAuMjUpLAogICAgICAgICAgYWxwaGEgPSAwLjcsCiAgICAgICAgICB0aXRsZSA9ICJDb3ZhcmlhdGUgQmFsYW5jZSAoU01EKSIsCiAgICAgICAgICBncmlkID0gVFJVRSkKCmxvdmUucGxvdChtYl9mb3JtdWxhX0gxLCAKICAgICAgICAgIGRhdGEgPSBkZl9jbGVhbl9IMSwgCiAgICAgICAgICB3ZWlnaHRzID0gbV9vdXRfSDEsICMgVXNlIHRoZSBtYXRjaCBvYmplY3QgYXMgdGhlIHNvdXJjZSBvZiB3ZWlnaHRzCiAgICAgICAgICBzdGF0cyA9ICJrcy5zdGF0aXN0aWNzIiwgIyBDaGFuZ2UgdG8gS1Mgc3RhdGlzdGljcwogICAgICAgICAgYmluYXJ5ID0gInN0ZCIsCiAgICAgICAgICB0aHJlc2hvbGRzID0gYyhrcyA9IDAuMSksIAogICAgICAgICAgYWxwaGEgPSAwLjcsCiAgICAgICAgICBncmlkID0gVFJVRSwKICAgICAgICAgIHRpdGxlID0gIkNvdmFyaWF0ZSBCYWxhbmNlIChLUyBTdGF0aXN0aWNzKSIpCmBgYAoKYGBge3IsIE1vZGVsIEgxOiBDb3ZhcmlhdGUgRGlzdHJpYnV0aW9uYWwgQmFsYW5jZX0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkgIyBSZXF1aXJlZCBmb3IgYXJyYW5naW5nIHBsb3RzCgojIFBhbmVsIEE6IEdvb2QgQmFsYW5jZSAoQ29udGludW91cyAtIEVDREYpCnAxIDwtIGJhbC5wbG90KG1fb3V0X0gxLCB0cmVhdCA9IFRyLCBjb3ZzID0gWCwgCiAgICAgICAgICAgICAgIHZhci5uYW1lID0gInN0YXJ0X2RhdGVfbnVtIiwgdHlwZSA9ICJlY2RmIikgKyAKICAgICAgZ2d0aXRsZSgiQS4gR29vZCBCYWxhbmNlOiBTdGFydCBEYXRlIikKCiMgUGFuZWwgQjogUG9vciBCYWxhbmNlIChDb250aW51b3VzIC0gRUNERikKcDIgPC0gYmFsLnBsb3QobV9vdXRfSDEsIHRyZWF0ID0gVHIsIGNvdnMgPSBYLCAKICAgICAgICAgICAgICAgdmFyLm5hbWUgPSAiZ2RwIiwgdHlwZSA9ICJlY2RmIikgKyAKICAgICAgZ2d0aXRsZSgiQi4gUG9vciBCYWxhbmNlOiBHRFAiKQoKIyBQYW5lbCBDOiBHb29kIEJhbGFuY2UgKERpc2NyZXRlIC0gSGlzdG9ncmFtKQpwMyA8LSBiYWwucGxvdChtX291dF9IMSwgdHJlYXQgPSBUciwgY292cyA9IFgsIAogICAgICAgICAgICAgICB2YXIubmFtZSA9ICJkZW0iLCB0eXBlID0gImhpc3RvZ3JhbSIpICsgCiAgICAgIGdndGl0bGUoIkMuIEdvb2QgQmFsYW5jZTogRGVtb2NyYWN5IikKCiMgUGFuZWwgRDogUG9vciBCYWxhbmNlIChEaXNjcmV0ZSAtIEhpc3RvZ3JhbSkKcDQgPC0gYmFsLnBsb3QobV9vdXRfSDEsIHRyZWF0ID0gVHIsIGNvdnMgPSBYLCAKICAgICAgICAgICAgICAgdmFyLm5hbWUgPSAiaHVtX3JpZyIsIHR5cGUgPSAiaGlzdG9ncmFtIikgKyAKICAgICAgZ2d0aXRsZSgiRC4gUG9vciBCYWxhbmNlOiBIdW1hbiBSaWdodHMiKQoKIyBBcnJhbmdlIHBsb3RzIGludG8gYSAyeDIgZ3JpZApncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgcDQsIG5yb3cgPSAyKQpgYGAKCmBgYHtyLCBNb2RlbCBIMTogQ2hlY2sgQmFsYW5jZSBTdW1tYXJ5fQpiYWwudGFiKG1iX2Zvcm11bGFfSDEsIAogICAgICAgIGRhdGEgPSBkZl9jbGVhbl9IMSwgCiAgICAgICAgd2VpZ2h0cyA9IG1fb3V0X0gxLCAjIFVzZSB0aGUgbWF0Y2ggb2JqZWN0IGFzIHRoZSBzb3VyY2Ugb2Ygd2VpZ2h0cwogICAgICAgIGVzdGltYW5kID0gIkFUVCIsCiAgICAgICAgYmluYXJ5ID0gInN0ZCIsICAgICAgIyA8LS0tIEZvcmNlcyBiaW5hcnkgdmFycyB0byB1c2UgU01ECiAgICAgICAgY29udGludW91cyA9ICJzdGQiLCAgIyA8LS0tIEZvcmNlcyBjb250aW51b3VzIHZhcnMgKGRlZmF1bHQpIHRvIHVzZSBTTUQKICAgICAgICB1biA9IFRSVUUsCiAgICAgICAgc3RhdHMgPSBjKCJtIiwgInYiLCAia3MiKSwgICAjIE1lYW4gZGlmZnMsIFZhcmlhbmNlIHJhdGlvcywgS1Mgc3RhdHMKICAgICAgICB0aHJlc2hvbGRzID0gYyhtID0gMC4yNSwga3MgPSAwLjEpKQpgYGAKCmBgYHtyLCBGdW5jdGlvbiBmb3IgTWF0Y2hCYWxhbmNlIFAtdmFsdWUgVGFibGV9CmxpYnJhcnkoTWF0Y2hpbmcpCgpnZXRfYmFsYW5jZV90YWJsZSA8LSBmdW5jdGlvbihmb3JtdWxhLCBkYXRhLCBtYXRjaF9vdXQsIG5ib290cyA9IDUwMCkgewogIAogICMgMS4gUnVuIE1hdGNoQmFsYW5jZQogIG1iIDwtIE1hdGNoQmFsYW5jZShmb3JtdWxhLCBkYXRhID0gZGF0YSwgbWF0Y2gub3V0ID0gbWF0Y2hfb3V0LCBuYm9vdHMgPSBuYm9vdHMsIHByaW50LmxldmVsID0gMCkKICAKICAjIDIuIERlZmluZSB0aGUgIk5lc3RlZCIgTnVsbCBDb2FsZXNjaW5nIE9wZXJhdG9yIAogICMgICAgKFRoaXMgYWxsb3dzIHVzIHRvIGNoYWluIGNoZWNrczogIlRyeSBBLCBpZiBOVUxMIHRyeSBCLCBpZiBOVUxMIHRyeSBDIikKICBgJXx8JWAgPC0gZnVuY3Rpb24oYSwgYikgaWYgKGlzLm51bGwoYSkpIGIgZWxzZSBhCgogICMgMy4gRGVmaW5lIHRoZSBFeHRyYWN0b3JzCiAgIyAgICBULVRlc3Q6IFNpbXBsZSBjaGVjawogIGdldF90dCA8LSBmdW5jdGlvbih4KSB4JHR0JHAudmFsdWUgJXx8JSBOQQogIAogICMgICAgS1MtVGVzdDogVGhlICJOZXN0ZWQiIEFwcHJvYWNoCiAgIyAgICAxLiBUcnkgbmVzdGVkIGJvb3RzdHJhcCAoeCRrcyRrcy5ib290LnB2YWx1ZSkgPC0tLSBQUklPUklUWQogICMgICAgMi4gVHJ5IHRvcC1sZXZlbCBib290c3RyYXAgKHgka3MuYm9vdC5wdmFsdWUpCiAgIyAgICAzLiBUcnkgc3RhbmRhcmQgS1MgKHgka3MkcC52YWx1ZSkKICBnZXRfa3MgPC0gZnVuY3Rpb24oeCkgeCRrcyRrcy5ib290LnB2YWx1ZSAlfHwlIHgka3MuYm9vdC5wdmFsdWUgJXx8JSB4JGtzJHAudmFsdWUgJXx8JSBOQQoKICAjIDQuIEV4dHJhY3QgZWZmaWNpZW50bHkgd2l0aCBzYXBwbHkKICBpZHggPC0gc2VxX2Fsb25nKG1iJEFmdGVyTWF0Y2hpbmcpCiAgdmFycyA8LSBhbGwudmFycyhmb3JtdWxhKVstMV0KICBmaW5hbF9uYW1lcyA8LSBpZihsZW5ndGgodmFycykgPT0gbGVuZ3RoKGlkeCkpIHZhcnMgZWxzZSBwYXN0ZTAoIlZhcl8iLCBpZHgpCgogIGRmIDwtIGRhdGEuZnJhbWUoCiAgICBWYXJpYWJsZSAgPSBmaW5hbF9uYW1lcywKICAgIFByZV9UX1AgICA9IHJvdW5kKHNhcHBseShpZHgsIGZ1bmN0aW9uKGkpIGdldF90dChtYiRCZWZvcmVNYXRjaGluZ1tbaV1dKSksIDMpLAogICAgUG9zdF9UX1AgID0gcm91bmQoc2FwcGx5KGlkeCwgZnVuY3Rpb24oaSkgZ2V0X3R0KG1iJEFmdGVyTWF0Y2hpbmdbW2ldXSkpLCAzKSwKICAgIFByZV9LU19QICA9IHJvdW5kKHNhcHBseShpZHgsIGZ1bmN0aW9uKGkpIGdldF9rcyhtYiRCZWZvcmVNYXRjaGluZ1tbaV1dKSksIDMpLAogICAgUG9zdF9LU19QID0gcm91bmQoc2FwcGx5KGlkeCwgZnVuY3Rpb24oaSkgZ2V0X2tzKG1iJEFmdGVyTWF0Y2hpbmdbW2ldXSkpLCAzKQogICkKICAKICAjIDUuIFN0YXR1czogUGFzcyBpZiAoS1MgaXMgTkEgb3IgPjAuMDUpIEFORCAoVC10ZXN0ID4gMC4wNSkKICBkZiRTdGF0dXMgPC0gaWZlbHNlKChpcy5uYShkZiRQb3N0X0tTX1ApIHwgZGYkUG9zdF9LU19QID4gMC4xKSAmIGRmJFBvc3RfVF9QID4gMC4xLCAiUEFTUyIsICJGQUlMIikKICAKICByZXR1cm4oZGYpCn0KYGBgCgpgYGB7ciwgTW9kZWwgSDE6IE1hdGNoQmFsYW5jZSBwLXZhbHVlc30Kc2V0LnNlZWQoMTIzKQojIC0tLSBDYWxsIEZ1bmN0aW9uIC0tLQpiYWxhbmNlX3RhYmxlX0gxIDwtIGdldF9iYWxhbmNlX3RhYmxlKAogIGZvcm11bGEgPSBtYl9mb3JtdWxhX0gxLCAKICBkYXRhID0gZGZfY2xlYW5fSDEsIAogIG1hdGNoX291dCA9IG1fb3V0X0gxLCAKICBuYm9vdHMgPSA1MDAKKQoKYmFsYW5jZV90YWJsZV9IMQpgYGAKCiMjIyBIeXBvdGhlc2lzIDFBOiBmZW0tc2lnIG9uIGRheXNfb2ZfcGVhY2UgKHBlYWNlIGR1cmF0aW9uKQoKYGBge3IsIE1vZGVsIEgxQTogVHJlYXRtZW50IGVmZmVjdCBlc3RpbWF0ZX0KIyBJbmNsdWRlIG91dGNvbWUgdmFyaWFibGUgZm9yIGVmZmVjdCBlc3RpbWF0ZQpZICA8LSBkZl9jbGVhbl9IMSRkYXlzX29mX3BlYWNlCm1fb3V0X0gxQSA8LSBNYXRjaChZID0gWSwgVHIgPSBUciwgWCA9IFgsIFdlaWdodC5tYXRyaXggPSBnZW5vdXRfSDEsIAogICAgICAgICAgICAgICBjYWxpcGVyID0gY2FsaXBlcl92ZWMsIAogICAgICAgICAgICAgICBlc3RpbWFuZCA9ICJBVFQiKQoKIyA9PT09PSBFc3RpbWF0ZSBUcmVhdG1lbnQgRWZmZWN0LCBTRSwgYW5kIENJID09PT09PQpzdW1tYXJ5KG1fb3V0X0gxQSkKCkFUVF9lc3QgPC0gbV9vdXRfSDFBJGVzdApBVFRfc2UgPC0gbV9vdXRfSDFBJHNlCgojLS0tLS0gR2V0IENvbmZpZGVuY2UgSW50ZXJ2YWxzIC0tLS0tLQojIENJIGJvdW5kcyBnaXZlbiBieSBwb2ludCBlc3RpbWF0ZSArLy0gbWFyZ2luIG9mIGVycm9yCiMgQ1YgZm9yIDk1JSBpbnRlcnZhbCBpcyAxLjk2CmNpX2xvd2VyOTUgPC0gQVRUX2VzdCAtIDEuOTYgKiBBVFRfc2UKY2lfdXBwZXI5NSA8LSBBVFRfZXN0ICsgMS45NiAqIEFUVF9zZQojIENWIGZvciA5OSUgaW50ZXJ2YWwgaXMgMi41NzYKY2lfbG93ZXI5OSA8LSBBVFRfZXN0IC0gMi41NzYgKiBBVFRfc2UKY2lfdXBwZXI5OSA8LSBBVFRfZXN0ICsgMi41NzYgKiBBVFRfc2UKCnByaW50KHBhc3RlKCJFc3RpbWF0ZWQgQVRUOiIsIHJvdW5kKEFUVF9lc3QsIDIpKSkKcHJpbnQocGFzdGUoIlN0YW5kYXJkIEVycm9yOiIsIHJvdW5kKEFUVF9zZSwgMikpKQpwcmludChwYXN0ZSgiOTUlIENJOiBbIiwgcm91bmQoY2lfbG93ZXI5NSwgMyksICIsIiwgcm91bmQoY2lfdXBwZXI5NSwgMyksICJdIikpCnByaW50KHBhc3RlKCI5OSUgQ0k6IFsiLCByb3VuZChjaV9sb3dlcjk5LCAzKSwgIiwiLCByb3VuZChjaV91cHBlcjk5LCAzKSwgIl0iKSkKYGBgCgojIyMgSHlwb3RoZXNpcyAxQjogZmVtLXNpZyBvbiBwY19uZCAocGVhY2UgZW5kcyBhbmQgY29uZmxpY3QgcmVzdW1lcykKCmBgYHtyLCBNb2RlbCBIMUI6IFRyZWF0bWVudCBlZmZlY3QgZXN0aW1hdGV9CiMgT3V0Y29tZQpZICA8LSBkZl9jbGVhbl9IMSRwY19uZAptX291dF9IMUIgPC0gTWF0Y2goWSA9IFksIFRyID0gVHIsIFggPSBYLCBXZWlnaHQubWF0cml4ID0gZ2Vub3V0X0gxLCAKICAgICAgICAgICAgICAgY2FsaXBlciA9IGNhbGlwZXJfdmVjLCAKICAgICAgICAgICAgICAgZXN0aW1hbmQgPSAiQVRUIikKCiMgPT09PT0gRXN0aW1hdGUgVHJlYXRtZW50IEVmZmVjdCwgU0UsIGFuZCBDSSA9PT09PT0KCnN1bW1hcnkobV9vdXRfSDFCKQoKQVRUX2VzdCA8LSBtX291dF9IMUIkZXN0CkFUVF9zZSA8LSBtX291dF9IMUIkc2UKCiMtLS0tLSBHZXQgQ29uZmlkZW5jZSBJbnRlcnZhbHMgLS0tLS0tCiMgQ0kgYm91bmRzIGdpdmVuIGJ5IHBvaW50IGVzdGltYXRlICsvLSBtYXJnaW4gb2YgZXJyb3IKIyBDViBmb3IgOTUlIGludGVydmFsIGlzIDEuOTYKY2lfbG93ZXI5NSA8LSBBVFRfZXN0IC0gMS45NiAqIEFUVF9zZQpjaV91cHBlcjk1IDwtIEFUVF9lc3QgKyAxLjk2ICogQVRUX3NlCiMgQ1YgZm9yIDk5JSBpbnRlcnZhbCBpcyAyLjU3NgpjaV9sb3dlcjk5IDwtIEFUVF9lc3QgLSAyLjU3NiAqIEFUVF9zZQpjaV91cHBlcjk5IDwtIEFUVF9lc3QgKyAyLjU3NiAqIEFUVF9zZQoKcHJpbnQocGFzdGUoIkVzdGltYXRlZCBBVFQ6Iiwgcm91bmQoQVRUX2VzdCwgMikpKQpwcmludChwYXN0ZSgiU3RhbmRhcmQgRXJyb3I6Iiwgcm91bmQoQVRUX3NlLCAyKSkpCnByaW50KHBhc3RlKCI5NSUgQ0k6IFsiLCByb3VuZChjaV9sb3dlcjk1LCAzKSwgIiwiLCByb3VuZChjaV91cHBlcjk1LCAzKSwgIl0iKSkKcHJpbnQocGFzdGUoIjk5JSBDSTogWyIsIHJvdW5kKGNpX2xvd2VyOTksIDMpLCAiLCIsIHJvdW5kKGNpX3VwcGVyOTksIDMpLCAiXSIpKQpgYGAKCiMjIyBNb2RlbCBIMTogUm9zZW5iYXVtIEJvdW5kcyBTZW5zaXRpdml0eSBBbmFseXNpcwoKYGBge3J9CiMgUnVuIFNlbnNpdGl2aXR5IEFuYWx5c2lzIG9uIER1cmFiaWxpdHkgKERheXMgb2YgUGVhY2UpCiNpbnN0YWxsLnBhY2thZ2VzKCJyYm91bmRzIikKbGlicmFyeShyYm91bmRzKQoKIyBPYnRhaW4gaW5kZXhlcyBmb3IgbWF0Y2hlZCB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgdW5pdHMKdHJlYXRlZF9pbmRpY2VzIDwtIG1fb3V0X0gxJGluZGV4LnRyZWF0ZWQKY29udHJvbF9pbmRpY2VzIDwtIG1fb3V0X0gxJGluZGV4LmNvbnRyb2wKCiMgRXh0cmFjdCAnRGF5cyBvZiBQZWFjZScgZm9yIGJvdGggZ3JvdXBzCmRheXNfVHIgPC0gYXMubnVtZXJpYyhkZl9jbGVhbl9IMSRkYXlzX29mX3BlYWNlW21fb3V0X0gxJGluZGV4LnRyZWF0ZWRdKQpkYXlzX0NvIDwtIGFzLm51bWVyaWMoZGZfY2xlYW5fSDEkZGF5c19vZl9wZWFjZVttX291dF9IMSRpbmRleC5jb250cm9sXSkKCiMgUC1WYWx1ZQpwc2Vuc19IMUEgPC0gcHNlbnMoeCA9IGRheXNfVHIsIAogICAgICAgICAgICAgICAgICAgeSA9IGRheXNfQ28sIAogICAgICAgICAgICAgICAgICAgR2FtbWEgPSAzLCAjIFdlIGNoZWNrIHVwIHRvIGEgInRyaXBsaW5nIiBvZiB0aGUgb2RkcyBvZiBoaWRkZW4gYmlhcwogICAgICAgICAgICAgICAgICAgR2FtbWFJbmMgPSAwLjUpICMgV2UgbW92ZSBpbiBzdGVwcyBvZiAwLjUKIyBUaGUgcHJvYmFiaWxpdHkgb2YgYXNzaWdubWVudCB0byB0cmVhdG1lbnQgdW5kZXIgaGlkZGVuIGJpYXMgR2FtbWEKIyBGb3IgVXBwZXIgQm91bmQgKHdvcnN0IGNhc2UpLCB3ZSBhc3N1bWUgYmlhcyBoZWxwcyB0aGUgb2JzZXJ2ZWQgZWZmZWN0CgojIEhvZGdlcy1MZWhtYW5uIEVzdGltYXRlIChub24tcGFyYW1ldHJpYykKaGxzZW5zX0gxQSA8LSBobHNlbnMoeCA9IGRheXNfVHIsIAogICAgICAgICAgICAgICAgICAgeSA9IGRheXNfQ28sIAogICAgICAgICAgICAgICAgICAgcHIgPSAwLjUsCiAgICAgICAgICAgICAgICAgICBHYW1tYSA9IDEwLCAKICAgICAgICAgICAgICAgICAgIEdhbW1hSW5jID0gMSkgCnBzZW5zX0gxQQojIHJlc3VsdCBpcyBvbmx5ICJtYXJnaW5hbGx5IHNpZ25pZmljYW50IiAocD0wLjA2KSBhc3N1bWluZyBubyBoaWRkZW4gYmlhcwojIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBkaXNhcHBlYXJzIHdpdGggZXZlbiBhIHRpbnkgYW1vdW50IG9mIGhpZGRlbiBiaWFzCmhsc2Vuc19IMUEKIyBtYWduaXR1ZGUgb2YgdGhlIGVmZmVjdCBwb2ludCBlc3RpbWF0ZSBpcyBxdWl0ZSByb2J1c3QKI2l0IHdvdWxkIHRha2UgYSBtYXNzaXZlIGFtb3VudCBvZiB1bm9ic2VydmVkIGJpYXMgKEdhbW1hID0gNykgdG8gcmVkdWNlIHRoZSBlc3RpbWF0ZWQgZWZmZWN0IHRvIHplcm8KIyBldmVuIGlmIHVub2JzZXJ2ZWQgZmFjdG9ycyBjYXVzZWQgbWFzc2l2ZSBzZWxlY3Rpb24gYmlhcywgdGhlIHVuZGVybHlpbmcgc2lnbmFsIHN0aWxsIHN1Z2dlc3RzIGEgcG9zaXRpdmUgZWZmZWN0IG9uIGR1cmF0aW9uCgpgYGAKCmBgYHtyfQojIFJ1biBTZW5zaXRpdml0eSBBbmFseXNpcyBvbiBEdXJhYmlsaXR5IChQZWFjZSBFbmRlZCkKCiMgT2J0YWluIGluZGV4ZXMgZm9yIG1hdGNoZWQgdHJlYXRtZW50IGFuZCBjb250cm9sIHVuaXRzCnRyZWF0ZWRfaW5kaWNlcyA8LSBtX291dF9IMSRpbmRleC50cmVhdGVkCmNvbnRyb2xfaW5kaWNlcyA8LSBtX291dF9IMSRpbmRleC5jb250cm9sCgojIDIuIEV4dHJhY3QgJ1BlYWNlIEVuZGVkJyBmb3IgYm90aCBncm91cHMKcGNfVHIgPC0gYXMubnVtZXJpYyhkZl9jbGVhbl9IMSRwY19uZFttX291dF9IMSRpbmRleC50cmVhdGVkXSkKcGNfQ28gPC0gYXMubnVtZXJpYyhkZl9jbGVhbl9IMSRwY19uZFttX291dF9IMSRpbmRleC5jb250cm9sXSkKCmRpc19UMV9DMCA8LSBzdW0ocGNfVHIgPT0gMSAmIHBjX0NvID09IDApCmRpc19UMF9DMSA8LSBzdW0ocGNfVHIgPT0gMCAmIHBjX0NvID09IDEpCgpjYXQoIkRpc2NvcmRhbnQgUGFpcnMgKFRyZWF0PTEsIENvbnQ9MCk6IiwgZGlzX1QxX0MwLCAiXG4iKQpjYXQoIkRpc2NvcmRhbnQgUGFpcnMgKFRyZWF0PTAsIENvbnQ9MSk6IiwgZGlzX1QwX0MxLCAiXG4iKQoKIyBVc2UgYmluYXJ5c2VucyB3aXRoIHRoZSBjb3VudHMKIyBHYW1tYSAzLCBzdGVwIDAuMQpiaW5hcnlzZW5zKGRpc19UMV9DMCwgZGlzX1QwX0MxLCBHYW1tYT0zLCBHYW1tYUluYz0wLjUpCgojIHVuZGVycG93ZXJlZCBkdWUgdG8gc21hbGwgbnVtYmVyIG9mIGRpc2NvcmRhbnQgcGFpcnMKCmBgYAoKIyMjIEgxOiBSb2J1c3RuZXNzIGNoZWNrCgpgYGB7ciwgTW9kZWwgUjE6IERhdGEgUHJlcGFyYXRpb259CiMgPT09PT09PT09PT09PT0gUmVtb3ZlIE5BcyBmcm9tIEFMTCBuZWNlc3NhcnkgdmFyaWFibGVzPT09PT09PT09PT09PT09PT09CgojIFNwZWNpZnkgdmFyaWFibGVzIG9mIGludGVyZXN0CnByZXRyZWF0bWVudF9jb3ZhcmlhdGVzIDwtIGMoImNvbl9kdXIiLCAiY29uX2ludCIsICJjb25faXNzIiwgIndhcl9wYXIiLCAiZ2RwIiwgImRlbSIsICJodW1fcmlnIiwgImZlbV9jb20iLCAibGVmX2lkZSIsICJmZW1fbGVnIiwgInN0YXJ0X2RhdGVfbnVtIikKdHJlYXRuZW50X3ZhciA8LSBjKCJmZW1fc2lnIikKb3V0Y29tZV92YXJzIDwtIGMoImRheXNfb2ZfcGVhY2UiLCAicGNfbmQiKQoKIyBhZGRpdGlvbmFsIGNvdmFyaWF0ZXMgZm9yIG1hdGNoaW5nICh1c2VkIGFzIGNvbnRyb2xzIGJ5IEtyYXVzZSBldCBhbC4pCmFkZF9jb3ZhcmlhdGVzIDwtIGMoInBvd19zaGEiLCAicXVvIiwgInVuX3BlYV9jb24iKSAKCmNsZWFuaW5nX3ZhcnMgPC0gYyh0cmVhdG5lbnRfdmFyLCBvdXRjb21lX3ZhcnMsIHByZXRyZWF0bWVudF9jb3ZhcmlhdGVzLCBhZGRfY292YXJpYXRlcykKCiMgQ2hlY2sgd2hpY2ggY29sdW1ucyBjb250YWluIG1pc3NpbmcgdmFsdWVzCmNvbFN1bXMoaXMubmEoZGF0YVssIGNsZWFuaW5nX3ZhcnNdKSkgCgojIENsZWFuIHRoZSBkYXRhIHRvIGVuYWJsZSBnZW5ldGljIG1hdGNoaW5nIChjYW5ub3QgaGF2ZSBOQXMpCmRmX2NsZWFuX3JiMSA8LSBuYS5vbWl0KGRhdGFbLCBjKCJjYXNfaWQiLCBjbGVhbmluZ192YXJzKV0pCmRmX2NsZWFuX3JiMQoKIyBDaGVjayBmb3IgZHJvcHBlZCB1bml0cwpjYXQoIk51bWJlciBvZiBjb250cm9sL3RyZWF0bWVudCB1bml0cyBpbiBzYW1wbGUgKGJlZm9yZSBjbGVhbmluZyk6IikKdGFibGUoZGF0YSRmZW1fc2lnKQoKY2F0KCJOdW1iZXIgb2YgY29udHJvbC90cmVhdG1lbnQgdW5pdHMgaW4gc2FtcGxlIChhZnRlciBjbGVhbmluZyk6IikKdGFibGUoZGZfY2xlYW5fcmIxJGZlbV9zaWcpCmBgYAoKYGBge3IsIE1vZGVsIFIxOiBHZW5ldGljIE1hdGNoaW5nfQpzZXQuc2VlZCgxMjMpCiMgPT09PT09PT09PT09IERFRklORSBNQVRDSElORyBPQkpFQ1RTID09PT09PT09PT09PT09PT0KCiMgVHJlYXRtZW50IApUciA8LSBkZl9jbGVhbl9yYjEkZmVtX3NpZwoKIyBNYXRjaGluZyBNYXRyaXggKFgpCm1hdGNoaW5nX3ZhcnMgPC0gYyhwcmV0cmVhdG1lbnRfY292YXJpYXRlcywgYWRkX2NvdmFyaWF0ZXMpICNpbmNsdWRlIGFkZGl0aW9uYWwgY292YXJpYXRlcwpYIDwtIGRmX2NsZWFuX3JiMVssIG1hdGNoaW5nX3ZhcnNdCgoKIyBQUkVQQVJFIENBTElQRVIgKEZvciBzdGFydF9kYXRlX251bSkKZGVzaXJlZF93aW5kb3dfZGF5cyA8LSAxODAgIzkwIGNhdXNlcyB0cmVhdG1lbnQgdW5pdHMgdG8gYmUgZHJvcHBlZApzZF9kYXRlIDwtIHNkKGRmX2NsZWFuX3JiMSRzdGFydF9kYXRlX251bSkKY2FsaXBlcl92YWx1ZSA8LSBkZXNpcmVkX3dpbmRvd19kYXlzIC8gc2RfZGF0ZQoKIyBDcmVhdGUgQ2FsaXBlciBWZWN0b3IKIyBXZSBuZWVkIGEgdmVjdG9yIG9mIEluZnMgbWF0Y2hpbmcgdGhlIG51bWJlciBvZiBjb2x1bW5zIGluIFgKY2FsaXBlcl92ZWMgPC0gcmVwKEluZiwgbmNvbChYKSkKCiMgQXBwbHkgcmVzdHJpY3Rpb24gT05MWSB0byB0aGUgZGF0ZSBjb2x1bW4KZGF0ZV9pbmRleCA8LSB3aGljaChjb2xuYW1lcyhYKSA9PSAic3RhcnRfZGF0ZV9udW0iKQpjYWxpcGVyX3ZlY1tkYXRlX2luZGV4XSA8LSBjYWxpcGVyX3ZhbHVlCgojID09PT09PT09PT09PT09PT0gUlVOIEdFTk1BVENIID09PT09PT09PT09PT09PQpnZW5vdXRfcmIxIDwtIEdlbk1hdGNoKFRyID0gVHIsIFggPSBYLCBCYWxhbmNlTWF0cml4ID0gWCwKICAgICAgICAgICAgICAgICAgIGNhbGlwZXIgPSBjYWxpcGVyX3ZlYywKICAgICAgICAgICAgICAgICAgIGVzdGltYW5kID0gIkFUVCIsIHBvcC5zaXplID0gNTAwMCwgCiAgICAgICAgICAgICAgICAgICBwcmludC5sZXZlbCA9IDApCgojID09PT09PT09PT09PT09PT0gUlVOIE1BVENIID09PT09PT09PT09PT09PT09PT0KbV9vdXRfcmIxIDwtIE1hdGNoKFRyID0gVHIsIFggPSBYLCBXZWlnaHQubWF0cml4ID0gZ2Vub3V0X3JiMSwgCiAgICAgICAgICAgICAgIGNhbGlwZXIgPSBjYWxpcGVyX3ZlYywgCiAgICAgICAgICAgICAgIGVzdGltYW5kID0gIkFUVCIpCgojID09PT09IFJlcG9ydCBTdW1tYXJ5IG9mIE1hdGNoaW5nIFJlc3VsdHMgPT09PT09CiMgQ291bnQgaG93IG1hbnkgdGltZXMgZWFjaCB0cmVhdGVkIHVuaXQgYXBwZWFycyBpbiB0aGUgbWF0Y2ggbGlzdAptYXRjaGVzX3Blcl90cmVhdGVkIDwtIHRhYmxlKG1fb3V0X3JiMSRpbmRleC50cmVhdGVkKQojIENoZWNrIHRoZSBkaXN0cmlidXRpb24gKGUuZy4sIGhvdyBtYW55IGdvdCAxIG1hdGNoLCBob3cgbWFueSBnb3QgMiwgZXRjLikKdGFibGUobWF0Y2hlc19wZXJfdHJlYXRlZCkKCiMgVG90YWwgdHJlYXRlZCB1bml0cyBpbiBvcmlnaW5hbCBkYXRhCnRvdGFsX3RyZWF0ZWQgPC0gc3VtKFRyKQoKIyBUb3RhbCB0cmVhdGVkIHVuaXRzIHRoYXQgc3VjY2Vzc2Z1bGx5IGZvdW5kIGEgbWF0Y2gKbWF0Y2hlZF90cmVhdGVkIDwtIGxlbmd0aCh1bmlxdWUobV9vdXRfcmIxJGluZGV4LnRyZWF0ZWQpKQoKY2F0KCJPcmlnaW5hbCBUcmVhdGVkOiIsIHRvdGFsX3RyZWF0ZWQsICJcbiIpCmNhdCgiTWF0Y2hlZCBUcmVhdGVkOiAiLCBtYXRjaGVkX3RyZWF0ZWQsICJcbiIpCmNhdCgiRHJvcHBlZDogICAgICAgICAiLCB0b3RhbF90cmVhdGVkIC0gbWF0Y2hlZF90cmVhdGVkLCAiXG4iKQpgYGAKCmBgYHtyLCBNb2RlbCBSMTogR2VuZXRpYyBNYXRjaGluZyBSZXN1bHRzfQojID09PT09IFJlcG9ydCBCYWxhbmNlIGFuZCBMb3dlc3QgUC1WYWx1ZSA9PT09PT0Kc2V0LnNlZWQoMTIzKQojIHRyZWF0bWVudCBpbmRpY2F0b3IgaXMgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSwgY2hlY2sgYmFsYW5jZSBmb3IgYWxsIGNvdmFyaWF0ZXMKbWJfZm9ybXVsYV9yYjEgPC0gZmVtX3NpZyB+IGNvbl9kdXIgKyBjb25faW50ICsgY29uX2lzcyArICB3YXJfcGFyICsgZ2RwICsgZGVtICsgaHVtX3JpZyArIGZlbV9sZWcgKyBmZW1fY29tICsgbGVmX2lkZSArIHN0YXJ0X2RhdGVfbnVtICsgcG93X3NoYSArIHF1byArIHVuX3BlYV9jb24KCk1hdGNoQmFsYW5jZShtYl9mb3JtdWxhX3JiMSwgZGF0YSA9IGRmX2NsZWFuX3JiMSwgbWF0Y2gub3V0ID0gbV9vdXRfcmIxLCBuYm9vdHMgPSA1MDApCmBgYAoKYGBge3IsIE1vZGVsIFIxOiBMb3ZlIFBsb3RzfQojaW5zdGFsbC5wYWNrYWdlcygiY29iYWx0IikKbGlicmFyeShjb2JhbHQpCgpsb3ZlLnBsb3QobWJfZm9ybXVsYV9yYjEsIAogICAgICAgICAgZGF0YSA9IGRmX2NsZWFuX3JiMSwgCiAgICAgICAgICB3ZWlnaHRzID0gbV9vdXRfcmIxLCAjIFVzZSB0aGUgbWF0Y2ggb2JqZWN0IGFzIHRoZSBzb3VyY2Ugb2Ygd2VpZ2h0cwogICAgICAgICAgYmluYXJ5ID0gInN0ZCIsCiAgICAgICAgICB0aHJlc2hvbGRzID0gYyhtID0gLjI1KSwKICAgICAgICAgIGFscGhhID0gMC43LAogICAgICAgICAgdGl0bGUgPSAiQ292YXJpYXRlIEJhbGFuY2UgKFNNRCkiLAogICAgICAgICAgZ3JpZCA9IFRSVUUpCgpsb3ZlLnBsb3QobWJfZm9ybXVsYV9yYjEsIAogICAgICAgICAgZGF0YSA9IGRmX2NsZWFuX3JiMSwgCiAgICAgICAgICB3ZWlnaHRzID0gbV9vdXRfcmIxLCAjIFVzZSB0aGUgbWF0Y2ggb2JqZWN0IGFzIHRoZSBzb3VyY2Ugb2Ygd2VpZ2h0cwogICAgICAgICAgc3RhdHMgPSAia3Muc3RhdGlzdGljcyIsICMgQ2hhbmdlIHRvIEtTIHN0YXRpc3RpY3MKICAgICAgICAgIGJpbmFyeSA9ICJzdGQiLAogICAgICAgICAgdGhyZXNob2xkcyA9IGMoa3MgPSAwLjEpLCAKICAgICAgICAgIGFscGhhID0gMC43LAogICAgICAgICAgZ3JpZCA9IFRSVUUsCiAgICAgICAgICB0aXRsZSA9ICJDb3ZhcmlhdGUgQmFsYW5jZSAoS1MgU3RhdGlzdGljcykiKQpgYGAKCmBgYHtyLCBNb2RlbCBSMTogQ2hlY2sgQmFsYW5jZSBTdW1tYXJ5fQpiYWwudGFiKG1iX2Zvcm11bGFfcmIxLCAKICAgICAgICBkYXRhID0gZGZfY2xlYW5fcmIxLCAKICAgICAgICB3ZWlnaHRzID0gbV9vdXRfcmIxLCAjIFVzZSB0aGUgbWF0Y2ggb2JqZWN0IGFzIHRoZSBzb3VyY2Ugb2Ygd2VpZ2h0cwogICAgICAgIGVzdGltYW5kID0gIkFUVCIsCiAgICAgICAgYmluYXJ5ID0gInN0ZCIsICAgICAgIyA8LS0tIEZvcmNlcyBiaW5hcnkgdmFycyB0byB1c2UgU01ECiAgICAgICAgY29udGludW91cyA9ICJzdGQiLCAgIyA8LS0tIEZvcmNlcyBjb250aW51b3VzIHZhcnMgKGRlZmF1bHQpIHRvIHVzZSBTTUQKICAgICAgICB1biA9IFRSVUUsCiAgICAgICAgc3RhdHMgPSBjKCJtIiwgInYiLCAia3MiKSwgICAjIE1lYW4gZGlmZnMsIFZhcmlhbmNlIHJhdGlvcywgS1Mgc3RhdHMKICAgICAgICB0aHJlc2hvbGRzID0gYyhtID0gMC4yNSwga3MgPSAwLjEpKQpgYGAKCmBgYHtyLCBNb2RlbCBSMTogTWF0Y2hCYWxhbmNlIHAtdmFsdWVzfQpzZXQuc2VlZCgxMjMpCiMgLS0tIENhbGwgRnVuY3Rpb24gLS0tCmJhbGFuY2VfdGFibGVfcmIxIDwtIGdldF9iYWxhbmNlX3RhYmxlKAogIGZvcm11bGEgPSBtYl9mb3JtdWxhX3JiMSwgCiAgZGF0YSA9IGRmX2NsZWFuX3JiMSwgCiAgbWF0Y2hfb3V0ID0gbV9vdXRfcmIxLCAKICBuYm9vdHMgPSA1MDAKKQoKYmFsYW5jZV90YWJsZV9yYjEKYGBgCgojIyMjIEgxIHZzIFIxOiBDb21wYXJpc29uIG9mIE1hdGNoaW5nIFJlc3VsdHMKCmBgYHtyLCBSb2J1c3RuZXNzIENoZWNrIEgxIHZzLiBSMTogQ29tcGFyZSBNYXRjaGluZyBSZXN1bHRzfQoKbWF0Y2hlZF9kYXRhX0gxIDwtIHJiaW5kKAogIGRmX2NsZWFuX0gxW21fb3V0X0gxJGluZGV4LnRyZWF0ZWQsIF0sCiAgZGZfY2xlYW5fSDFbbV9vdXRfSDEkaW5kZXguY29udHJvbCwgXQopCm5fcGFpcnMgPC0gbGVuZ3RoKG1fb3V0X0gxJGluZGV4LnRyZWF0ZWQpCm1hdGNoZWRfZGF0YV9IMSRwYWlyX2lkIDwtIGMoMTpuX3BhaXJzLCAxOm5fcGFpcnMpCgptYXRjaGVkX2RhdGFfcmIxIDwtIHJiaW5kKAogIGRmX2NsZWFuX3JiMVttX291dF9yYjEkaW5kZXgudHJlYXRlZCwgXSwKICBkZl9jbGVhbl9yYjFbbV9vdXRfcmIxJGluZGV4LmNvbnRyb2wsIF0KKQpuX3BhaXJzIDwtIGxlbmd0aChtX291dF9yYjEkaW5kZXgudHJlYXRlZCkKbWF0Y2hlZF9kYXRhX3JiMSRwYWlyX2lkIDwtIGMoMTpuX3BhaXJzLCAxOm5fcGFpcnMpCgptYXRjaGVzIDwtIGNiaW5kKFBhaXJfSUQgPSBtYXRjaGVkX2RhdGFfSDEkcGFpcl9pZCwgCiAgICAgICAgICAgICAgICAgVHJlYXRlZCA9IG1hdGNoZWRfZGF0YV9IMSRjYXNfaWRbbWF0Y2hlZF9kYXRhX0gxJGZlbV9zaWcgPT0gMV0sIAogICAgICAgICAgICAgICAgIE1vZGVsSDFfTWF0Y2hlcyA9IG1hdGNoZWRfZGF0YV9IMSRjYXNfaWRbbWF0Y2hlZF9kYXRhX0gxJGZlbV9zaWcgPT0gMF0sIAogICAgICAgICAgICAgICAgIE1vZGVsUjFfTWF0Y2hlcyA9IG1hdGNoZWRfZGF0YV9yYjEkY2FzX2lkW21hdGNoZWRfZGF0YV9yYjEkZmVtX3NpZyA9PSAwXSkKbWF0Y2hlc1sxOjYsIF0KCiMgQ29tcGFyZSBvdXRjb21lIG9ic2VydmF0aW9ucyBvZiBtYXRjaGVkIHVuaXRzCm1hdGNoY29tcF9kYXlzIDwtIGNiaW5kKFBhaXJfSUQgPSBtYXRjaGVkX2RhdGFfSDEkcGFpcl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgY2FzX2lkID0gbWF0Y2hlZF9kYXRhX0gxJGNhc19pZCwKICAgICAgICAgICAgICAgICAgICAgICAgZmVtX3NpZyA9IG1hdGNoZWRfZGF0YV9IMSRmZW1fc2lnLAogICAgICAgICAgICAgICAgICAgICAgICBkYXlzX29mX3BlYWNlX0gxID0gbWF0Y2hlZF9kYXRhX0gxJGRheXNfb2ZfcGVhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGRheXNfb2ZfcGVhY2VfcmIxID0gbWF0Y2hlZF9kYXRhX3JiMSRkYXlzX29mX3BlYWNlKQptYXRjaGNvbXBfcGMgPC0gY2JpbmQoUGFpcl9JRCA9IG1hdGNoZWRfZGF0YV9IMSRwYWlyX2lkLAogICAgICAgICAgICAgICAgICAgICAgY2FzX2lkID0gbWF0Y2hlZF9kYXRhX0gxJGNhc19pZCwKICAgICAgICAgICAgICAgICAgICAgIGZlbV9zaWcgPSBtYXRjaGVkX2RhdGFfSDEkZmVtX3NpZywKICAgICAgICAgICAgICAgICAgICAgIHBjX25kX0gxID0gbWF0Y2hlZF9kYXRhX0gxJHBjX25kLAogICAgICAgICAgICAgICAgICAgICAgcGNfbmRfcmIxID0gbWF0Y2hlZF9kYXRhX3JiMSRwY19uZCkKbWF0Y2hjb21wX2RheXMKbWF0Y2hjb21wX3BjCmBgYAoKIyMjIyBIMSB2cyBSMTogQ29tcGFyaXNvbiBvZiBUcmVhdG1lbnQgRWZmZWN0IEVzdGltYXRlcwoKYGBge3IsIE1vZGVsIFIxQTogVHJlYXRtZW50IGVmZmVjdCBlc3RpbWF0ZSAoZGF5c19vZl9wZWFjZSl9CgojID09PT09PT09IFJ1biBNYXRjaCgpIHdpdGggb3V0Y29tZSB2YXJpYWJsZSA9PT09PT09CgojIE91dGNvbWUKWSAgPC0gZGZfY2xlYW5fcmIxJGRheXNfb2ZfcGVhY2UKbV9vdXRfcmIxQSA8LSBNYXRjaChZID0gWSwgVHIgPSBUciwgWCA9IFgsIFdlaWdodC5tYXRyaXggPSBnZW5vdXRfcmIxLCAKICAgICAgICAgICAgICAgY2FsaXBlciA9IGNhbGlwZXJfdmVjLCAKICAgICAgICAgICAgICAgZXN0aW1hbmQgPSAiQVRUIikKCiMgPT09PT0gRXN0aW1hdGUgVHJlYXRtZW50IEVmZmVjdCwgU0UsIGFuZCBDSSA9PT09PT0KCnN1bW1hcnkobV9vdXRfcmIxQSkKCkFUVF9lc3QgPC0gbV9vdXRfcmIxQSRlc3QKQVRUX3NlIDwtIG1fb3V0X3JiMUEkc2UKCiMtLS0tLSBHZXQgQ29uZmlkZW5jZSBJbnRlcnZhbHMgLS0tLS0tCiMgQ0kgYm91bmRzIGdpdmVuIGJ5IHBvaW50IGVzdGltYXRlICsvLSBtYXJnaW4gb2YgZXJyb3IKIyBDViBmb3IgOTUlIGludGVydmFsIGlzIDEuOTYKY2lfbG93ZXI5NSA8LSBBVFRfZXN0IC0gMS45NiAqIEFUVF9zZQpjaV91cHBlcjk1IDwtIEFUVF9lc3QgKyAxLjk2ICogQVRUX3NlCiMgQ1YgZm9yIDk5JSBpbnRlcnZhbCBpcyAyLjU3NgpjaV9sb3dlcjk5IDwtIEFUVF9lc3QgLSAyLjU3NiAqIEFUVF9zZQpjaV91cHBlcjk5IDwtIEFUVF9lc3QgKyAyLjU3NiAqIEFUVF9zZQoKcHJpbnQocGFzdGUoIkVzdGltYXRlZCBBVFQ6Iiwgcm91bmQoQVRUX2VzdCwgNCkpKQpwcmludChwYXN0ZSgiU3RhbmRhcmQgRXJyb3I6Iiwgcm91bmQoQVRUX3NlLCA0KSkpCnByaW50KHBhc3RlKCI5NSUgQ0k6IFsiLCByb3VuZChjaV9sb3dlcjk1LCAzKSwgIiwiLCByb3VuZChjaV91cHBlcjk1LCAzKSwgIl0iKSkKcHJpbnQocGFzdGUoIjk5JSBDSTogWyIsIHJvdW5kKGNpX2xvd2VyOTksIDMpLCAiLCIsIHJvdW5kKGNpX3VwcGVyOTksIDMpLCAiXSIpKQpgYGAKCmBgYHtyLCBNb2RlbCBSMUI6IFRyZWF0bWVudCBlZmZlY3QgZXN0aW1hdGUgKHBjX25kKX0KCiMgPT09PT09PT0gUnVuIE1hdGNoKCkgd2l0aCBvdXRjb21lIHZhcmlhYmxlID09PT09PT0KIyBPdXRjb21lClkgIDwtIGRmX2NsZWFuX3JiMSRwY19uZAptX291dF9yYjFCIDwtIE1hdGNoKFkgPSBZLCBUciA9IFRyLCBYID0gWCwgV2VpZ2h0Lm1hdHJpeCA9IGdlbm91dF9yYjEsIAogICAgICAgICAgICAgICBjYWxpcGVyID0gY2FsaXBlcl92ZWMsIAogICAgICAgICAgICAgICBlc3RpbWFuZCA9ICJBVFQiKQoKIyA9PT09PSBFc3RpbWF0ZSBUcmVhdG1lbnQgRWZmZWN0LCBTRSwgYW5kIENJID09PT0KCnN1bW1hcnkobV9vdXRfcmIxQikKCkFUVF9lc3QgPC0gbV9vdXRfcmIxQiRlc3QKQVRUX3NlIDwtIG1fb3V0X3JiMUIkc2UKCiMtLS0tLSBHZXQgQ29uZmlkZW5jZSBJbnRlcnZhbHMgLS0tLS0tCiMgQ0kgYm91bmRzIGdpdmVuIGJ5IHBvaW50IGVzdGltYXRlICsvLSBtYXJnaW4gb2YgZXJyb3IKIyBDViBmb3IgOTUlIGludGVydmFsIGlzIDEuOTYKY2lfbG93ZXI5NSA8LSBBVFRfZXN0IC0gMS45NiAqIEFUVF9zZQpjaV91cHBlcjk1IDwtIEFUVF9lc3QgKyAxLjk2ICogQVRUX3NlCiMgQ1YgZm9yIDk5JSBpbnRlcnZhbCBpcyAyLjU3NgpjaV9sb3dlcjk5IDwtIEFUVF9lc3QgLSAyLjU3NiAqIEFUVF9zZQpjaV91cHBlcjk5IDwtIEFUVF9lc3QgKyAyLjU3NiAqIEFUVF9zZQoKcHJpbnQocGFzdGUoIkVzdGltYXRlZCBBVFQ6Iiwgcm91bmQoQVRUX2VzdCwgNCkpKQpwcmludChwYXN0ZSgiU3RhbmRhcmQgRXJyb3I6Iiwgcm91bmQoQVRUX3NlLCA0KSkpCnByaW50KHBhc3RlKCI5NSUgQ0k6IFsiLCByb3VuZChjaV9sb3dlcjk1LCAzKSwgIiwiLCByb3VuZChjaV91cHBlcjk1LCAzKSwgIl0iKSkKcHJpbnQocGFzdGUoIjk5JSBDSTogWyIsIHJvdW5kKGNpX2xvd2VyOTksIDMpLCAiLCIsIHJvdW5kKGNpX3VwcGVyOTksIDMpLCAiXSIpKQpgYGAKCmBgYHtyLCBSb2J1c3RuZXNzIENoZWNrIEgxIHZzLiBSMTogQ29tcGFyZSBFc3RpbWF0ZXN9CnByaW50ICgiSDFBIHZzLiBSMUEiKQpzdW1tYXJ5KG1fb3V0X0gxQSkKc3VtbWFyeShtX291dF9yYjFBKQpwcmludCAoIkgxQiB2cy4gUjFCIikKc3VtbWFyeShtX291dF9IMUIpCnN1bW1hcnkobV9vdXRfcmIxQikKYGBgCgojIyMgSHlwb3RoZXNpcyAxOiBTdXJ2aXZhbCBBbmFseXNpcwoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJzdXJ2aXZhbCIsICJzdXJ2bWluZXIiKQoKbGlicmFyeShzdXJ2aXZhbCkKbGlicmFyeShzdXJ2bWluZXIpCiMgMS4gRXh0cmFjdCBpbmRpY2VzIGZyb20gdGhlIE1hdGNoIG9iamVjdAojIGluZGV4LnRyZWF0ZWQgY29udGFpbnMgdGhlIHJvdyBudW1iZXJzIG9mIHRyZWF0ZWQgdW5pdHMKIyBpbmRleC5jb250cm9sIGNvbnRhaW5zIHRoZSByb3cgbnVtYmVycyBvZiB0aGUgbWF0Y2hlZCBjb250cm9sIHVuaXRzCm1hdGNoZXNfdHIgPC0gZGZfY2xlYW5fSDFbbV9vdXRfSDEkaW5kZXgudHJlYXRlZCwgXQptYXRjaGVzX2NvIDwtIGRmX2NsZWFuX0gxW21fb3V0X0gxJGluZGV4LmNvbnRyb2wsIF0KCiMgMi4gQ29tYmluZSB0aGVtIGludG8gYSBuZXcgbWF0Y2hlZCBkYXRhZnJhbWUKbWF0Y2hlZF9kYXRhIDwtIHJiaW5kKG1hdGNoZXNfdHIsIG1hdGNoZXNfY28pCgojIDMuIENyZWF0ZSBhICJwYWlyX2lkIiB0byBoYW5kbGUgY2x1c3RlcmluZwojIFRoaXMgaGVscHMgdGhlIG1vZGVsIHVuZGVyc3RhbmQgd2hpY2ggdHJlYXRlZCB1bml0IGdvZXMgd2l0aCB3aGljaCBjb250cm9sIHVuaXQKbWF0Y2hlZF9kYXRhJHBhaXJfaWQgPC0gcmVwKDE6bGVuZ3RoKG1fb3V0X0gxJGluZGV4LnRyZWF0ZWQpLCAyKQpgYGAKCmBgYHtyfQojIENvbnZlcnQgdGhlIHRpYmJsZSB0byBhIHN0YW5kYXJkIGRhdGEgZnJhbWUKbWF0Y2hlZF9kYXRhIDwtIGFzLmRhdGEuZnJhbWUobWF0Y2hlZF9kYXRhKQoKbWF0Y2hlZF9kYXRhJGZlbV9zaWcgPC0gYXMuZmFjdG9yKG1hdGNoZWRfZGF0YSRmZW1fc2lnKQoKIyAzLiBGaXQgdGhlIG1vZGVsIHdpdGggdGhlIFN1cnYoKSBjYWxsIElOU0lERSB0aGUgZm9ybXVsYQojIERvIG5vdCB1c2UgYW4gZXh0ZXJuYWwgJ3Nfb2JqJy4gUHV0IHRoZSB2YXJpYWJsZXMgZGlyZWN0bHkgaGVyZS4Kc19maXQgPC0gc3VydmZpdChTdXJ2KGRheXNfb2ZfcGVhY2UsIHBjX25kKSB+IGZlbV9zaWcsIGRhdGEgPSBtYXRjaGVkX2RhdGEpCgojIEthcGxhbi1NZWllciBDdXJ2ZQpnZ3N1cnZwbG90KAogIHNfZml0LAogIGRhdGEgPSBtYXRjaGVkX2RhdGEsCiAgcHZhbCA9IFRSVUUsCiAgY29uZi5pbnQgPSBUUlVFLCAKICBwYWxldHRlID0gYygiI0U3QjgwMCIsICIjMkU5RkRGIiksCiAgbGVnZW5kLmxhYnMgPSBjKCJDb250cm9sIiwgIlRyZWF0ZWQiKSwKICB0aXRsZSA9ICJFZmZlY3Qgb2YgRmVtX1NpZyBvbiBEdXJhYmlsaXR5IG9mIFBlYWNlIiwKICB4bGFiID0gIkRheXMgb2YgUGVhY2UiLAogIHlsYWIgPSAiU3Vydml2YWwgUHJvYmFiaWxpdHkiCikKCiMgVHJlYXRlZCBjdXJ2ZSAoQmx1ZSkgc3RheXMgbmVhcmx5IGZsYXQgYXQgdGhlIHRvcCAoaW5kaWNhdGluZyBoaWdoIHN1cnZpdmFsL3BlYWNlIGR1cmF0aW9uKSwgIyBDb250cm9sIGN1cnZlIChZZWxsb3cpIGRyb3BzIHN0ZWVwbHkKYGBgCgpgYGB7cn0KIyBMb2ctUmFuayBUZXN0CnN1cnZkaWZmKFN1cnYoZGF5c19vZl9wZWFjZSwgcGNfbmQpIH4gZmVtX3NpZywgZGF0YSA9IG1hdGNoZWRfZGF0YSkKCiMgQ29udHJvbCBHcm91cCAoTm8gRmVtYWxlcyk6IG9ic2VydmUgNCBwZWFjZSBmYWlsdXJlcywgYnV0IGV4cGVjdGVkIGlzIDEuOTQuIFBlYWNlIGNvbGxhcHNlZCB0d2ljZSBhcyBvZnRlbiBhcyBleHBlY3RlZC4KCiNUcmVhdGVkIEdyb3VwIChGZW1hbGVzKTogb2JzZXJ2ZSBvbmx5IDEgcGVhY2UgZmFpbHVyZSwgYnV0IGV4cGVjdGVkIDMuMDYuIFBlYWNlIGNvbGxhcHNlZCBtdWNoIGxlc3Mgb2Z0ZW4gdGhhbiBleHBlY3RlZC4KYGBgCgpgYGB7cn0KIyBGaXQgdGhlIENveCBtb2RlbAojIFdlIGNsdXN0ZXIgYnkgJ3BhaXJfaWQnIGJlY2F1c2UgdGhlIHRyZWF0ZWQgYW5kIGNvbnRyb2wgdW5pdHMgYXJlIGxpbmtlZCBieSB0aGUgbWF0Y2gKY294X21vZGVsIDwtIGNveHBoKFN1cnYoZGF5c19vZl9wZWFjZSwgcGNfbmQpIH4gZmVtX3NpZywgCiAgICAgICAgICAgICAgICAgICBkYXRhID0gbWF0Y2hlZF9kYXRhLCAKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXIgPSBwYWlyX2lkKSAKCiMgVmlldyB0aGUgcmVzdWx0cwpzdW1tYXJ5KGNveF9tb2RlbCkKCiMgVGhlIHByZXNlbmNlIG9mIGZlbWFsZSBzaWduYXRvcmllcyBpcyBhc3NvY2lhdGVkIHdpdGggYSByZWR1Y2VkIHJpc2sgb2YgcGVhY2UgZmFpbHVyZS4KIyBIYXphcmQgcmF0aW86IDAuMTQ4NTogSW5jbHVkaW5nIGZlbWFsZSBzaWduYXRvcmllcyByZWR1Y2VzIHRoZSByaXNrIG9mIHRoZSBwZWFjZSBhZ3JlZW1lbnQgY29sbGFwc2luZyBieSBhcHByb3hpbWF0ZWx5IDg1JSAoMSAtIDAuMTQ4NSA9IDAuODUxNSkKCiMgcCA9IDAuMDE5IChzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlc3VsdHMgYWNjb3JkaW5nIHRvIHRoZSBjb3ggbW9kZWwpCgpgYGAKCmBgYHtyfQojID09PT09IENoZWNrIHZhbGlkaXR5IG9mIG1vZGVsID09PT09PQojIFRlc3QgZm9yIFByb3BvcnRpb25hbCBIYXphcmRzIGFzc3VtcHRpb24KdGVzdF9waCA8LSBjb3guenBoKGNveF9tb2RlbCkKcHJpbnQodGVzdF9waCkKIyBTY2hvZW5mZWxkIFJlc2lkdWFscyB0ZXN0OiBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRpbWUgYW5kIHRoZSByZXNpZHVhbHMKIyBOdWxsIEh5cDogaGF6YXJkcyBhcmUgcHJvcG9ydGlvbmFsIGFuZCBlZmZlY3QgaXMgY29uc3RhbnQKIyBsYXJnZSBwIHZhbHVlIGluZGljYXRlcyBubyBldmlkZW5jZSB0aGF0IGFzc3VtcHRpb25zIGFyZSB2aW9sYXRlZAoKCiMgUGxvdCB0aGUgU2Nob2VuZmVsZCByZXNpZHVhbHMKZ2djb3h6cGgodGVzdF9waCkKCiMgY2hlY2sgdGhhdCBlZmZlY3Qgb2YgdGhlIHRyZWF0bWVudCBpcyBjb25zdGFudCBvdmVyIHRpbWUKIyBFZmZlY3Qgc2l6ZSByZW1haW5zIHJlbGF0aXZlbHkgc3RhYmxlIG92ZXIgdGltZQoKYGBgCgojIyMjIHNlbnNtYWtlciBTZW5zaXRpdml0eSBUZXN0IGZvciBTdXJ2aXZhbCBBbmFseXNpcwoKYGBge3J9CmxpYnJhcnkoc2Vuc2VtYWtyKQojIDEuIEZpdCBhIHNpbXBsZSBsaW5lYXIgbW9kZWwgb24gdGhlIG1hdGNoZWQgZGF0YQojIChSZWdyZXNzaW5nIE91dGNvbWUgfiBUcmVhdG1lbnQpCmRheXNfbW9kZWwgPC0gbG0oZGF5c19vZl9wZWFjZSB+IGZlbV9zaWcsIGRhdGEgPSBkZl9jbGVhbl9IMSkKCiMgMi4gUnVuIFNlbnNlbWFrcgojIENoZWNrcyBob3cgc3Ryb25nIGhpZGRlbiBiaWFzIG11c3QgYmUgdG8gZXhwbGFpbiBhd2F5IHRoZSBlZmZlY3Qgc2l6ZQpzZW5zaXRpdml0eSA8LSBzZW5zZW1ha3IobW9kZWwgPSBkYXlzX21vZGVsLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWF0bWVudCA9ICJmZW1fc2lnIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGtkID0gMTozKSAjIENoZWNrIGJpYXMgMXgsIDJ4LCAzeCBhcyBzdHJvbmcKCiMgMy4gUGxvdCBhbmQgU3VtbWFyeQpwbG90KHNlbnNpdGl2aXR5KQpzdW1tYXJ5KHNlbnNpdGl2aXR5KQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHNlbnNlbWFrcikKIyAxLiBGaXQgYSBzaW1wbGUgbGluZWFyIG1vZGVsIG9uIHRoZSBtYXRjaGVkIGRhdGEKIyAoUmVncmVzc2luZyBPdXRjb21lIH4gVHJlYXRtZW50KQpwY19tb2RlbCA8LSBsbShwY19uZCB+IGZlbV9zaWcsIGRhdGEgPSBkZl9jbGVhbl9IMSkKCiMgMi4gUnVuIFNlbnNlbWFrcgojIENoZWNrcyBob3cgc3Ryb25nIGhpZGRlbiBiaWFzIG11c3QgYmUgdG8gZXhwbGFpbiBhd2F5IHRoZSBlZmZlY3Qgc2l6ZQpzZW5zaXRpdml0eSA8LSBzZW5zZW1ha3IobW9kZWwgPSBwY19tb2RlbCwgCiAgICAgICAgICAgICAgICAgICAgICAgICB0cmVhdG1lbnQgPSAiZmVtX3NpZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBrZCA9IDE6MykgIyBDaGVjayBiaWFzIDF4LCAyeCwgM3ggYXMgc3Ryb25nCgojIDMuIFBsb3QgYW5kIFN1bW1hcnkKcGxvdChzZW5zaXRpdml0eSkKc3VtbWFyeShzZW5zaXRpdml0eSkKYGBgCgojIyBIeXBvdGhlc2lzIDI6IFdvbWVuIHBhcnRpY2lwYXRpb24gYW5kIHF1YWxpdHkgb2YgcGVhY2UgYWdyZWVtZW50IChjb250ZW50KQoKYGBge3IsIE1vZGVsIEgyOiBEYXRhIFByZXBhcmF0aW9ufQoKIyA9PT09PT09PT09PT0gUmVtb3ZlIE5BcyBmcm9tIEFMTCBuZWNlc3NhcnkgdmFyaWFibGVzID09PT09PT09PT09PT0KCnRyZWF0bmVudF92YXIgPC0gYygiZmVtX3NpZyIpCm91dGNvbWVfdmFycyA8LSBjKCJjcGEiLCAiY2l2X3NvYyIpCnByZXRyZWF0bWVudF9jb3ZhcmlhdGVzIDwtIGMoImNvbl9kdXIiLCAiY29uX2ludCIsICJjb25faXNzIiwgIndhcl9wYXIiLCAiZ2RwIiwgImRlbSIsICJodW1fcmlnIiwgImZlbV9jb20iLCAibGVmX2lkZSIsICJmZW1fbGVnIiwgInN0YXJ0X2RhdGVfbnVtIikgCgpjbGVhbmluZ192YXJzIDwtIGModHJlYXRuZW50X3Zhciwgb3V0Y29tZV92YXJzLCBwcmV0cmVhdG1lbnRfY292YXJpYXRlcykKCiMgQ2hlY2sgd2hpY2ggY29sdW1ucyBjb250YWluIG1pc3NpbmcgdmFsdWVzCmNvbFN1bXMoaXMubmEoZGF0YVssIGNsZWFuaW5nX3ZhcnNdKSkgCgojIENsZWFuIHRoZSBkYXRhIHRvIGVuYWJsZSBnZW5ldGljIG1hdGNoaW5nIChjYW5ub3QgaGF2ZSBOQXMpCmRmX2NsZWFuX0gyIDwtIG5hLm9taXQoZGF0YVssIGMoImNhc19pZCIsIGNsZWFuaW5nX3ZhcnMpXSkKZGZfY2xlYW5fSDIKCiNDaGVjayBob3cgbWFueSByb3dzIGhhdmUgYmVlbiBkcm9wcGVkCmNhdCgiTnVtYmVyIG9mIGNvbnRyb2wvdHJlYXRtZW50IHVuaXRzIGluIHNhbXBsZSAoYmVmb3JlIGNsZWFuaW5nKToiKQp0YWJsZShkYXRhJGZlbV9zaWcpCgpjYXQoIk51bWJlciBvZiBjb250cm9sL3RyZWF0bWVudCB1bml0cyBpbiBzYW1wbGUgKGFmdGVyIGNsZWFuaW5nKToiKQp0YWJsZShkZl9jbGVhbl9IMiRmZW1fc2lnKQpgYGAKCmBgYHtyLCBNb2RlbCBIMjogR2VuZXRpYyBNYXRjaGluZ30Kc2V0LnNlZWQoMTIzKQoKIyA9PT09PT09PT09PT09PSBERUZJTkUgTUFUQ0hJTkcgT0JKRUNUUyA9PT09PT09PT09PT09CiMgVHJlYXRtZW50IApUciA8LSBkZl9jbGVhbl9IMiRmZW1fc2lnCgojIE1hdGNoaW5nIE1hdHJpeCAoWCkKbWF0Y2hpbmdfdmFycyA8LSBwcmV0cmVhdG1lbnRfY292YXJpYXRlcwpYIDwtIGRmX2NsZWFuX0gyWywgbWF0Y2hpbmdfdmFyc10KIyBkbyBub3QgaW5jbHVkZSBvdXRjb21lcwoKIyA9PT09PT09PT09PT09IFJVTiBHRU5NQVRDSCA9PT09PT09PT09PT09PT0KCmdlbm91dF9IMiA8LSBHZW5NYXRjaChUciA9IFRyLCBYID0gWCwgQmFsYW5jZU1hdHJpeCA9IFgsIAogICAgICAgICAgICAgICAgICAgZXN0aW1hbmQgPSAiQVRUIiwgcG9wLnNpemUgPSA1MDAwLCAKICAgICAgICAgICAgICAgICAgIHJlcGxhY2U9RkFMU0UsCiAgICAgICAgICAgICAgICAgICBwcmludC5sZXZlbCA9IDApCgojID09PT09PT09PT09PT0gUlVOIE1BVENIID09PT09PT09PT09PT09PQoKbV9vdXRfSDIgPC0gTWF0Y2goVHIgPSBUciwgWCA9IFgsIFdlaWdodC5tYXRyaXggPSBnZW5vdXRfSDIsIAogICAgICAgICAgICAgICAgICBlc3RpbWFuZCA9ICJBVFQiLAogICAgICAgICAgICAgICAgICByZXBsYWNlPUZBTFNFKQoKCiMgPT09PT0gUmVwb3J0IG9uIG1hdGNoaW5nIHN1bW1hcnkgPT09PT09CgojIENvdW50IGhvdyBtYW55IHRpbWVzIGVhY2ggdHJlYXRlZCB1bml0IGFwcGVhcnMgaW4gdGhlIG1hdGNoIGxpc3QKbWF0Y2hlc19wZXJfdHJlYXRlZCA8LSB0YWJsZShtX291dF9IMiRpbmRleC50cmVhdGVkKQojIENoZWNrIHRoZSBkaXN0cmlidXRpb24gKGUuZy4sIGhvdyBtYW55IGdvdCAxIG1hdGNoLCBob3cgbWFueSBnb3QgMiwgZXRjLikKdGFibGUobWF0Y2hlc19wZXJfdHJlYXRlZCkKCiMgVG90YWwgdHJlYXRlZCB1bml0cyBpbiBvcmlnaW5hbCBkYXRhCnRvdGFsX3RyZWF0ZWQgPC0gc3VtKFRyKQoKIyBUb3RhbCB0cmVhdGVkIHVuaXRzIHRoYXQgc3VjY2Vzc2Z1bGx5IGZvdW5kIGEgbWF0Y2gKbWF0Y2hlZF90cmVhdGVkIDwtIGxlbmd0aCh1bmlxdWUobV9vdXRfSDIkaW5kZXgudHJlYXRlZCkpICNhbGwgdHJlYXRlZCB1bml0cyBoYXZlIGJlZW4gbWF0Y2hlZAoKY2F0KCJPcmlnaW5hbCBUcmVhdGVkOiIsIHRvdGFsX3RyZWF0ZWQsICJcbiIpCmNhdCgiTWF0Y2hlZCBUcmVhdGVkOiAiLCBtYXRjaGVkX3RyZWF0ZWQsICJcbiIpCmNhdCgiRHJvcHBlZDogICAgICAgICAiLCB0b3RhbF90cmVhdGVkIC0gbWF0Y2hlZF90cmVhdGVkLCAiXG4iKQoKYGBgCgpgYGB7ciwgTW9kZWwgSDI6IE1hdGNoQmFsYW5jZSBSZXN1bHRzfQoKIyA9PT09PSBSZXBvcnQgQmFsYW5jZSBhbmQgTG93ZXN0IFAtVmFsdWUgPT09PT09CnNldC5zZWVkKDEyMykKIyB0cmVhdG1lbnQgaW5kaWNhdG9yIGlzIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsIGNoZWNrIGJhbGFuY2UgZm9yIGFsbCBjb3ZhcmlhdGVzCm1iX2Zvcm11bGFfSDIgPC0gZmVtX3NpZyB+IGNvbl9kdXIgKyBjb25faW50ICsgY29uX2lzcyArICB3YXJfcGFyICsgZ2RwICsgZGVtICsgaHVtX3JpZyArIGZlbV9sZWcgKyBmZW1fY29tICsgbGVmX2lkZSArIHN0YXJ0X2RhdGVfbnVtCgpNYXRjaEJhbGFuY2UobWJfZm9ybXVsYV9IMiwgZGF0YSA9IGRmX2NsZWFuX0gyLCBtYXRjaC5vdXQgPSBtX291dF9IMiwgbmJvb3RzID0gNTAwKQpgYGAKCmBgYHtyLCBNb2RlbCBIMjogTG92ZSBQbG90c30KCiNpbnN0YWxsLnBhY2thZ2VzKCJjb2JhbHQiKQpsaWJyYXJ5KGNvYmFsdCkKCmxvdmUucGxvdChtYl9mb3JtdWxhX0gyLCAKICAgICAgICAgIGRhdGEgPSBkZl9jbGVhbl9IMiwgCiAgICAgICAgICB3ZWlnaHRzID0gbV9vdXRfSDIsICMgVXNlIHRoZSBtYXRjaCBvYmplY3QgYXMgdGhlIHNvdXJjZSBvZiB3ZWlnaHRzCiAgICAgICAgICBiaW5hcnkgPSAic3RkIiwKICAgICAgICAgIHRocmVzaG9sZHMgPSBjKG0gPSAuMjUpLAogICAgICAgICAgYWxwaGEgPSAwLjcsCiAgICAgICAgICB0aXRsZSA9ICJDb3ZhcmlhdGUgQmFsYW5jZSAoU01EKSIsCiAgICAgICAgICBncmlkID0gVFJVRSkKCmxvdmUucGxvdChtYl9mb3JtdWxhX0gyLCAKICAgICAgICAgIGRhdGEgPSBkZl9jbGVhbl9IMiwgCiAgICAgICAgICB3ZWlnaHRzID0gbV9vdXRfSDIsICMgVXNlIHRoZSBtYXRjaCBvYmplY3QgYXMgdGhlIHNvdXJjZSBvZiB3ZWlnaHRzCiAgICAgICAgICBzdGF0cyA9ICJrcy5zdGF0aXN0aWNzIiwgIyBDaGFuZ2UgdG8gS1Mgc3RhdGlzdGljcwogICAgICAgICAgYmluYXJ5ID0gInN0ZCIsCiAgICAgICAgICB0aHJlc2hvbGRzID0gYyhrcyA9IDAuMSksIAogICAgICAgICAgYWxwaGEgPSAwLjcsCiAgICAgICAgICBncmlkID0gVFJVRSwKICAgICAgICAgIHRpdGxlID0gIkNvdmFyaWF0ZSBCYWxhbmNlIChLUyBTdGF0aXN0aWNzKSIpCmBgYAoKYGBge3IsIE1vZGVsIEgyOiBDaGVjayBCYWxhbmNlIFN1bW1hcnl9CmJhbC50YWIobWJfZm9ybXVsYV9IMiwgCiAgICAgICAgZGF0YSA9IGRmX2NsZWFuX0gyLCAKICAgICAgICB3ZWlnaHRzID0gbV9vdXRfSDIsICMgVXNlIHRoZSBtYXRjaCBvYmplY3QgYXMgdGhlIHNvdXJjZSBvZiB3ZWlnaHRzCiAgICAgICAgZXN0aW1hbmQgPSAiQVRUIiwKICAgICAgICBiaW5hcnkgPSAic3RkIiwgICAgICAjIDwtLS0gRm9yY2VzIGJpbmFyeSB2YXJzIHRvIHVzZSBTTUQKICAgICAgICBjb250aW51b3VzID0gInN0ZCIsICAjIDwtLS0gRm9yY2VzIGNvbnRpbnVvdXMgdmFycyAoZGVmYXVsdCkgdG8gdXNlIFNNRAogICAgICAgIHVuID0gVFJVRSwKICAgICAgICBzdGF0cyA9IGMoIm0iLCAidiIsICJrcyIpLCAgICMgTWVhbiBkaWZmcywgVmFyaWFuY2UgcmF0aW9zLCBLUyBzdGF0cwogICAgICAgIHRocmVzaG9sZHMgPSBjKG0gPSAwLjI1LCBrcyA9IDAuMSkpCmBgYAoKYGBge3IsIE1vZGVsIEgyOiBNYXRjaEJhbGFuY2UgcC12YWx1ZXN9CnNldC5zZWVkKDEyMykKIyAtLS0gQ2FsbCBGdW5jdGlvbiAtLS0KYmFsYW5jZV90YWJsZV9IMiA8LSBnZXRfYmFsYW5jZV90YWJsZSgKICBmb3JtdWxhID0gbWJfZm9ybXVsYV9IMiwgCiAgZGF0YSA9IGRmX2NsZWFuX0gyLCAKICBtYXRjaF9vdXQgPSBtX291dF9IMiwgCiAgbmJvb3RzID0gNTAwCikKCmJhbGFuY2VfdGFibGVfSDIKYGBgCgojIyMgSHlwb3RoZXNpcyAyQTogZmVtX3NpZyBvbiBjcGEKCmBgYHtyLCBNb2RlbCBIMkE6IFRyZWF0bWVudCBlZmZlY3QgZXN0aW1hdGUgKGNwYSl9CnNldC5zZWVkKDEyMykKCiMgPT09PT09PT09PSBSdW4gTWF0Y2goKSB3aXRoIG91dGNvbWUgdmFyaWFibGUgPT09PT09PQoKWSAgPC0gZGZfY2xlYW5fSDIkY3BhICMgT3V0Y29tZQptX291dF9IMkEgPC0gTWF0Y2goWSA9IFksIFRyID0gVHIsIFggPSBYLCBXZWlnaHQubWF0cml4ID0gZ2Vub3V0X0gyLCBlc3RpbWFuZCA9ICJBVFQiKQoKIyA9PT09PSBFc3RpbWF0ZSBUcmVhdG1lbnQgRWZmZWN0LCBTRSwgYW5kIENJID09PT09PQpzdW1tYXJ5KG1fb3V0X0gyQSkKCkFUVF9lc3QgPC0gbV9vdXRfSDJBJGVzdApBVFRfc2UgPC0gbV9vdXRfSDJBJHNlCgojLS0tLS0gR2V0IENvbmZpZGVuY2UgSW50ZXJ2YWxzIC0tLS0tLQojIENJIGJvdW5kcyBnaXZlbiBieSBwb2ludCBlc3RpbWF0ZSArLy0gbWFyZ2luIG9mIGVycm9yCiMgQ1YgZm9yIDk1JSBpbnRlcnZhbCBpcyAxLjk2CmNpX2xvd2VyOTUgPC0gQVRUX2VzdCAtIDEuOTYgKiBBVFRfc2UKY2lfdXBwZXI5NSA8LSBBVFRfZXN0ICsgMS45NiAqIEFUVF9zZQojIENWIGZvciA5OSUgaW50ZXJ2YWwgaXMgMi41NzYKY2lfbG93ZXI5OSA8LSBBVFRfZXN0IC0gMi41NzYgKiBBVFRfc2UKY2lfdXBwZXI5OSA8LSBBVFRfZXN0ICsgMi41NzYgKiBBVFRfc2UKCnByaW50KHBhc3RlKCJFc3RpbWF0ZWQgQVRUOiIsIHJvdW5kKEFUVF9lc3QsIDQpKSkKcHJpbnQocGFzdGUoIlN0YW5kYXJkIEVycm9yOiIsIHJvdW5kKEFUVF9zZSwgNCkpKQpwcmludChwYXN0ZSgiOTUlIENJOiBbIiwgcm91bmQoY2lfbG93ZXI5NSwgMyksICIsIiwgcm91bmQoY2lfdXBwZXI5NSwgMyksICJdIikpCnByaW50KHBhc3RlKCI5OSUgQ0k6IFsiLCByb3VuZChjaV9sb3dlcjk5LCAzKSwgIiwiLCByb3VuZChjaV91cHBlcjk5LCAzKSwgIl0iKSkKYGBgCgojIyMgSHlwb3RoZXNpcyAyQjogZmVtX3NpZyBvbiBjaXZfc29jCgpgYGB7ciwgTW9kZWwgSDJBOiBUcmVhdG1lbnQgZWZmZWN0IGVzdGltYXRlIChjaXZfc29jKX0KCnNldC5zZWVkKDEyMykKIyA9PT09PT09PT09IFJ1biBNYXRjaCgpIHdpdGggb3V0Y29tZSB2YXJpYWJsZSA9PT09PT09CgpZICA8LSBkZl9jbGVhbl9IMiRjaXZfc29jICMgT3V0Y29tZQptX291dF9IMkIgPC0gTWF0Y2goWSA9IFksIFRyID0gVHIsIFggPSBYLCBXZWlnaHQubWF0cml4ID0gZ2Vub3V0X0gyLCBlc3RpbWFuZCA9ICJBVFQiKQoKCiMgPT09PT0gRXN0aW1hdGUgVHJlYXRtZW50IEVmZmVjdCwgU0UsIGFuZCBDSSA9PT09PT0Kc3VtbWFyeShtX291dF9IMkIpCgpBVFRfZXN0IDwtIG1fb3V0X0gyQiRlc3QKQVRUX3NlIDwtIG1fb3V0X0gyQiRzZQoKIy0tLS0tIEdldCBDb25maWRlbmNlIEludGVydmFscyAtLS0tLS0KIyBDSSBib3VuZHMgZ2l2ZW4gYnkgcG9pbnQgZXN0aW1hdGUgKy8tIG1hcmdpbiBvZiBlcnJvcgojIENWIGZvciA5NSUgaW50ZXJ2YWwgaXMgMS45NgpjaV9sb3dlcjk1IDwtIEFUVF9lc3QgLSAxLjk2ICogQVRUX3NlCmNpX3VwcGVyOTUgPC0gQVRUX2VzdCArIDEuOTYgKiBBVFRfc2UKIyBDViBmb3IgOTklIGludGVydmFsIGlzIDIuNTc2CmNpX2xvd2VyOTkgPC0gQVRUX2VzdCAtIDIuNTc2ICogQVRUX3NlCmNpX3VwcGVyOTkgPC0gQVRUX2VzdCArIDIuNTc2ICogQVRUX3NlCgpwcmludChwYXN0ZSgiRXN0aW1hdGVkIEFUVDoiLCByb3VuZChBVFRfZXN0LCAyKSkpCnByaW50KHBhc3RlKCJTdGFuZGFyZCBFcnJvcjoiLCByb3VuZChBVFRfc2UsIDIpKSkKcHJpbnQocGFzdGUoIjk1JSBDSTogWyIsIHJvdW5kKGNpX2xvd2VyOTUsIDMpLCAiLCIsIHJvdW5kKGNpX3VwcGVyOTUsIDMpLCAiXSIpKQpwcmludChwYXN0ZSgiOTklIENJOiBbIiwgcm91bmQoY2lfbG93ZXI5OSwgMyksICIsIiwgcm91bmQoY2lfdXBwZXI5OSwgMyksICJdIikpCgpgYGAKCiMjIyBNb2RlbCBIMjogUm9zZW5iYXVtIEJvdW5kcyBTZW5zaXRpdml0eSBBbmFseXNpcwoKYGBge3J9CiMgUnVuIFNlbnNpdGl2aXR5IEFuYWx5c2lzIG9uIEFncmVlbWVudCBRdWFsaXR5IChjcGEpCgojIE9idGFpbiBpbmRleGVzIGZvciBtYXRjaGVkIHRyZWF0bWVudCBhbmQgY29udHJvbCB1bml0cwp0cmVhdGVkX2luZGljZXMgPC0gbV9vdXRfSDIkaW5kZXgudHJlYXRlZApjb250cm9sX2luZGljZXMgPC0gbV9vdXRfSDIkaW5kZXguY29udHJvbAoKIyAyLiBFeHRyYWN0ICdQZWFjZSBFbmRlZCcgZm9yIGJvdGggZ3JvdXBzCmNwYV9UciA8LSBhcy5udW1lcmljKGRmX2NsZWFuX0gyJGNwYVttX291dF9IMiRpbmRleC50cmVhdGVkXSkKY3BhX0NvIDwtIGFzLm51bWVyaWMoZGZfY2xlYW5fSDIkY3BhW21fb3V0X0gyJGluZGV4LmNvbnRyb2xdKQoKZGlzX1QxX0MwIDwtIHN1bShjcGFfVHIgPT0gMSAmIGNwYV9DbyA9PSAwKQpkaXNfVDBfQzEgPC0gc3VtKGNwYV9UciA9PSAwICYgY3BhX0NvID09IDEpCgpjYXQoIkRpc2NvcmRhbnQgUGFpcnMgKFRyZWF0PTEsIENvbnQ9MCk6IiwgZGlzX1QxX0MwLCAiXG4iKQpjYXQoIkRpc2NvcmRhbnQgUGFpcnMgKFRyZWF0PTAsIENvbnQ9MSk6IiwgZGlzX1QwX0MxLCAiXG4iKQoKIyBVc2UgYmluYXJ5c2VucyB3aXRoIHRoZSBjb3VudHMKIyBHYW1tYSAzLCBzdGVwIDAuMQpiaW5hcnlzZW5zKGRpc19UMV9DMCwgZGlzX1QwX0MxLCBHYW1tYT0zLCBHYW1tYUluYz0wLjUpCgojIHVuZGVycG93ZXJlZCBkdWUgdG8gc21hbGwgbnVtYmVyIG9mIGRpc2NvcmRhbnQgcGFpcnMKIyBtYW55IG1hdGNoZXMgYW5kIHNtYWxsIHNhbXBsZSBzaXplCmBgYAoKYGBge3J9CiMgUnVuIFNlbnNpdGl2aXR5IEFuYWx5c2lzIG9uIEFncmVlbWVudCBRdWFsaXR5IChjaXZfc29jKQoKIyBPYnRhaW4gaW5kZXhlcyBmb3IgbWF0Y2hlZCB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgdW5pdHMKdHJlYXRlZF9pbmRpY2VzIDwtIG1fb3V0X0gyJGluZGV4LnRyZWF0ZWQKY29udHJvbF9pbmRpY2VzIDwtIG1fb3V0X0gyJGluZGV4LmNvbnRyb2wKCiMgMi4gRXh0cmFjdCAnUGVhY2UgRW5kZWQnIGZvciBib3RoIGdyb3VwcwpjaXZfc29jX1RyIDwtIGFzLm51bWVyaWMoZGZfY2xlYW5fSDIkY2l2X3NvY1ttX291dF9IMiRpbmRleC50cmVhdGVkXSkKY2l2X3NvY19DbyA8LSBhcy5udW1lcmljKGRmX2NsZWFuX0gyJGNpdl9zb2NbbV9vdXRfSDIkaW5kZXguY29udHJvbF0pCgpkaXNfVDFfQzAgPC0gc3VtKGNpdl9zb2NfVHIgPT0gMSAmIGNpdl9zb2NfQ28gPT0gMCkKZGlzX1QwX0MxIDwtIHN1bShjaXZfc29jX1RyID09IDAgJiBjaXZfc29jX0NvID09IDEpCgpjYXQoIkRpc2NvcmRhbnQgUGFpcnMgKFRyZWF0PTEsIENvbnQ9MCk6IiwgZGlzX1QxX0MwLCAiXG4iKQpjYXQoIkRpc2NvcmRhbnQgUGFpcnMgKFRyZWF0PTAsIENvbnQ9MSk6IiwgZGlzX1QwX0MxLCAiXG4iKQoKIyBVc2UgYmluYXJ5c2VucyB3aXRoIHRoZSBjb3VudHMKIyBHYW1tYSAzLCBzdGVwIDAuMQpiaW5hcnlzZW5zKGRpc19UMV9DMCwgZGlzX1QwX0MxLCBHYW1tYT0zLCBHYW1tYUluYz0wLjUpCgojIHVuZGVycG93ZXJlZCBkdWUgdG8gc21hbGwgbnVtYmVyIG9mIGRpc2NvcmRhbnQgcGFpcnMKIyBtYW55IG1hdGNoZXMgYW5kIHNtYWxsIHNhbXBsZSBzaXplCmBgYAoKIyMjIFJvYnVzdG5lc3MgQ2hlY2sKCmBgYHtyLCBNb2RlbCBSMjogRGF0YSBQcmVwYXJhdGlvbn0KIyA9PT09PT09PT09PT0gUmVtb3ZlIE5BcyBmcm9tIEFMTCBuZWNlc3NhcnkgdmFyaWFibGVzID09PT09PT09PT09PT0KCiMgQ2hlY2sgd2hpY2ggY29sdW1ucyBjb250YWluIG1pc3NpbmcgdmFsdWVzCmNvbFN1bXMoaXMubmEoZGF0YVssIGNsZWFuaW5nX3ZhcnNdKSkgCgojIENsZWFuIHRoZSBkYXRhIHRvIGVuYWJsZSBnZW5ldGljIG1hdGNoaW5nIChjYW5ub3QgaGF2ZSBOQXMpCnByZXRyZWF0bWVudF9jb3ZhcmlhdGVzIDwtIGMoImNvbl9kdXIiLCAiY29uX2ludCIsICJjb25faXNzIiwgIndhcl9wYXIiLCAiZ2RwIiwgImRlbSIsICJodW1fcmlnIiwgImZlbV9jb20iLCAibGVmX2lkZSIsICJmZW1fbGVnIiwgInN0YXJ0X2RhdGVfbnVtIikKdHJlYXRuZW50X3ZhciA8LSBjKCJmZW1fc2lnIikKb3V0Y29tZV92YXJzIDwtIGMoImNwYSIsICJjaXZfc29jIikKCmFkZF9jb3ZhcmlhdGVzIDwtIGMoInBvd19zaGEiLCAicXVvIiwgInVuX3BlYV9jb24iKSAjIGFkZGl0aW9uYWwgY292YXJpYXRlcwoKIyBUaGlzIGxpc3QgaW5jbHVkZXMgWSwgVHIsIGFuZCBYLiBXZSB1c2UgaXQgT05MWSBmb3IgbmEub21pdC4KY2xlYW5pbmdfdmFycyA8LSBjKHRyZWF0bmVudF92YXIsIG91dGNvbWVfdmFycywgcHJldHJlYXRtZW50X2NvdmFyaWF0ZXMsIGFkZF9jb3ZhcmlhdGVzKQoKZGZfY2xlYW5fcmIyIDwtIG5hLm9taXQoZGF0YVssIGMoImNhc19pZCIsIGNsZWFuaW5nX3ZhcnMpXSkKZGZfY2xlYW5fcmIyCgojIENoZWNrIGhvdyBtYW55IHJvd3MgaGF2ZSBiZWVuIGRyb3BwZWQKY2F0KCJOdW1iZXIgb2YgY29udHJvbC90cmVhdG1lbnQgdW5pdHMgaW4gc2FtcGxlIChiZWZvcmUgY2xlYW5pbmcpOiIpCnRhYmxlKGRhdGEkZmVtX3NpZykKY2F0KCJOdW1iZXIgb2YgY29udHJvbC90cmVhdG1lbnQgdW5pdHMgaW4gc2FtcGxlIChhZnRlciBjbGVhbmluZyk6IikKdGFibGUoZGZfY2xlYW5fcmIyJGZlbV9zaWcpCgpgYGAKCmBgYHtyLCBNb2RlbCBSMjogR2VuZXRpYyBNYXRjaGluZ30KIyA9PT09PT09PT09IERFRklORSBNQVRDSElORyBPQkpFQ1RTID09PT09PT09PT09PT09PQoKc2V0LnNlZWQoMTIzKQoKIyBUcmVhdG1lbnQgClRyIDwtIGRmX2NsZWFuX3JiMiRmZW1fc2lnCgojIE1hdGNoaW5nIE1hdHJpeCAoWCkKbWF0Y2hpbmdfdmFycyA8LSBjKHByZXRyZWF0bWVudF9jb3ZhcmlhdGVzLCBhZGRfY292YXJpYXRlcykgIyBpbmNsdWRlIGFkZGl0aW9uYWwgY292YXJpYXRlcwpYIDwtIGRmX2NsZWFuX3JiMlssIG1hdGNoaW5nX3ZhcnNdCgojID09PT09PT09PT09IFJVTiBHRU5NQVRDSCA9PT09PT09PT09PT09PT09PQoKZ2Vub3V0X3JiMiA8LSBHZW5NYXRjaChUciA9IFRyLCBYID0gWCwgQmFsYW5jZU1hdHJpeCA9IFgsCiAgICAgICAgICAgICAgICAgICByZXBsYWNlPUZBTFNFLCAKICAgICAgICAgICAgICAgICAgIGVzdGltYW5kID0gIkFUVCIsIHBvcC5zaXplID0gNTAwMCwgCiAgICAgICAgICAgICAgICAgICBwcmludC5sZXZlbCA9IDApCgojID09PT09PT09PT09PT09PSBSVU4gTUFUQ0ggPT09PT09PT09PT09PT09CgptX291dF9yYjIgPC0gTWF0Y2goVHIgPSBUciwgWCA9IFgsIFdlaWdodC5tYXRyaXggPSBnZW5vdXRfcmIyLCBlc3RpbWFuZCA9ICJBVFQiLCByZXBsYWNlPUZBTFNFKQoKCiMgPT09PT09PT09PSBSZXBvcnQgb24gbWF0Y2hpbmcgc3VtbWFyeSA9PT09PT09PT0KIyBDb3VudCBob3cgbWFueSB0aW1lcyBlYWNoIHRyZWF0ZWQgdW5pdCBhcHBlYXJzIGluIHRoZSBtYXRjaCBsaXN0Cm1hdGNoZXNfcGVyX3RyZWF0ZWQgPC0gdGFibGUobV9vdXRfcmIyICRpbmRleC50cmVhdGVkKQojIENoZWNrIHRoZSBkaXN0cmlidXRpb24gKGUuZy4sIGhvdyBtYW55IGdvdCAxIG1hdGNoLCBob3cgbWFueSBnb3QgMiwgZXRjLikKdGFibGUobWF0Y2hlc19wZXJfdHJlYXRlZCkKCiMgVG90YWwgdHJlYXRlZCB1bml0cyBpbiBvcmlnaW5hbCBkYXRhCnRvdGFsX3RyZWF0ZWQgPC0gc3VtKFRyKQoKIyBUb3RhbCB0cmVhdGVkIHVuaXRzIHRoYXQgc3VjY2Vzc2Z1bGx5IGZvdW5kIGEgbWF0Y2gKbWF0Y2hlZF90cmVhdGVkIDwtIGxlbmd0aCh1bmlxdWUobV9vdXRfcmIyICRpbmRleC50cmVhdGVkKSkgI2FsbCB0cmVhdGVkIHVuaXRzIGhhdmUgYmVlbiBtYXRjaGVkCgpjYXQoIk9yaWdpbmFsIFRyZWF0ZWQ6IiwgdG90YWxfdHJlYXRlZCwgIlxuIikKY2F0KCJNYXRjaGVkIFRyZWF0ZWQ6ICIsIG1hdGNoZWRfdHJlYXRlZCwgIlxuIikKY2F0KCJEcm9wcGVkOiAgICAgICAgICIsIHRvdGFsX3RyZWF0ZWQgLSBtYXRjaGVkX3RyZWF0ZWQsICJcbiIpCgoKYGBgCgpgYGB7ciwgTW9kZWwgUjI6IE1hdGNoQmFsYW5jZSgpfQpzZXQuc2VlZCgxMjMpCiMgPT09PT0gUmVwb3J0IEJhbGFuY2UgYW5kIExvd2VzdCBQLVZhbHVlID09PT09PQoKIyB0cmVhdG1lbnQgaW5kaWNhdG9yIGlzIHRoZSBkZXBlbmRlbnQgdmFyaWFibGUsIGNoZWNrIGJhbGFuY2UgZm9yIGFsbCBjb3ZhcmlhdGVzCm1iX2Zvcm11bGFfcmIyIDwtIGZlbV9zaWcgfiBjb25fZHVyICsgY29uX2ludCArIGNvbl9pc3MgKyAgd2FyX3BhciArIGdkcCArIGRlbSArIGh1bV9yaWcgKyBmZW1fbGVnICsgZmVtX2NvbSArIGxlZl9pZGUgKyBwb3dfc2hhICsgcXVvICsgdW5fcGVhX2NvbiArIHN0YXJ0X2RhdGVfbnVtCgpNYXRjaEJhbGFuY2UobWJfZm9ybXVsYV9yYjIsIGRhdGEgPSBkZl9jbGVhbl9yYjIsIG1hdGNoLm91dCA9IG1fb3V0X3JiMiwgbmJvb3RzID0gNTAwKQpgYGAKCiMjIyMgSDIgdnMgUjI6IENvbXBhcmlzb24gb2YgTWF0Y2hpbmcgUmVzdWx0cwoKYGBge3IsIE1vZGVsIFIyOiBDaGVjayBCYWxhbmNlIFN1bW1hcnl9CmJhbC50YWIobWJfZm9ybXVsYV9yYjIsIAogICAgICAgIGRhdGEgPSBkZl9jbGVhbl9yYjIsIAogICAgICAgIHdlaWdodHMgPSBtX291dF9yYjIsICMgVXNlIHRoZSBtYXRjaCBvYmplY3QgYXMgdGhlIHNvdXJjZSBvZiB3ZWlnaHRzCiAgICAgICAgZXN0aW1hbmQgPSAiQVRUIiwKICAgICAgICBiaW5hcnkgPSAic3RkIiwgICAgICAjIDwtLS0gRm9yY2VzIGJpbmFyeSB2YXJzIHRvIHVzZSBTTUQKICAgICAgICBjb250aW51b3VzID0gInN0ZCIsICAjIDwtLS0gRm9yY2VzIGNvbnRpbnVvdXMgdmFycyAoZGVmYXVsdCkgdG8gdXNlIFNNRAogICAgICAgIHVuID0gVFJVRSwKICAgICAgICBzdGF0cyA9IGMoIm0iLCAidiIsICJrcyIpLCAgICMgTWVhbiBkaWZmcywgVmFyaWFuY2UgcmF0aW9zLCBLUyBzdGF0cwogICAgICAgIHRocmVzaG9sZHMgPSBjKG0gPSAwLjI1LCBrcyA9IDAuMSkpCmBgYAoKYGBge3IsIE1vZGVsIFIyOiBNYXRjaEJhbGFuY2UgcC12YWx1ZXN9CnNldC5zZWVkKDEyMykKIyAtLS0gQ2FsbCBGdW5jdGlvbiAtLS0KYmFsYW5jZV90YWJsZV9yYjIgPC0gZ2V0X2JhbGFuY2VfdGFibGUoCiAgZm9ybXVsYSA9IG1iX2Zvcm11bGFfcmIyLCAKICBkYXRhID0gZGZfY2xlYW5fcmIyLCAKICBtYXRjaF9vdXQgPSBtX291dF9yYjIsIAogIG5ib290cyA9IDUwMAopCgpiYWxhbmNlX3RhYmxlX3JiMgpgYGAKCmBgYHtyLCBNb2RlbCBIMiB2cyBSMjogQ29tcGFyZSBNYXRjaGluZyBSZXN1bHRzfQptYXRjaGVkX2RhdGFfSDIgPC0gcmJpbmQoCiAgZGZfY2xlYW5fSDJbbV9vdXRfSDIkaW5kZXgudHJlYXRlZCwgXSwKICBkZl9jbGVhbl9IMlttX291dF9IMiRpbmRleC5jb250cm9sLCBdCikKbl9wYWlycyA8LSBsZW5ndGgobV9vdXRfSDIkaW5kZXgudHJlYXRlZCkKbWF0Y2hlZF9kYXRhX0gyJHBhaXJfaWQgPC0gYygxOm5fcGFpcnMsIDE6bl9wYWlycykKCm1hdGNoZWRfZGF0YV9yYjIgPC0gcmJpbmQoCiAgZGZfY2xlYW5fcmIyW21fb3V0X3JiMiRpbmRleC50cmVhdGVkLCBdLAogIGRmX2NsZWFuX3JiMlttX291dF9yYjIkaW5kZXguY29udHJvbCwgXQopCm5fcGFpcnMgPC0gbGVuZ3RoKG1fb3V0X3JiMiRpbmRleC50cmVhdGVkKQptYXRjaGVkX2RhdGFfcmIyJHBhaXJfaWQgPC0gYygxOm5fcGFpcnMsIDE6bl9wYWlycykKCm1hdGNoZXMgPC0gY2JpbmQoUGFpcl9JRCA9IG1hdGNoZWRfZGF0YV9IMiRwYWlyX2lkLCAKICAgICAgICAgICAgICAgICBUcmVhdGVkID0gbWF0Y2hlZF9kYXRhX0gyJGNhc19pZFttYXRjaGVkX2RhdGFfSDIkZmVtX3NpZyA9PSAxXSwgCiAgICAgICAgICAgICAgICAgTW9kZWxIMl9NYXRjaGVzID0gbWF0Y2hlZF9kYXRhX0gyJGNhc19pZFttYXRjaGVkX2RhdGFfSDIkZmVtX3NpZyA9PSAwXSwgCiAgICAgICAgICAgICAgICAgTW9kZWxSMl9NYXRjaGVzID0gbWF0Y2hlZF9kYXRhX3JiMiRjYXNfaWRbbWF0Y2hlZF9kYXRhX3JiMiRmZW1fc2lnID09IDBdKQptYXRjaGVzWzE6NiwgXQoKIyBDb21wYXJlIG91dGNvbWUgb2JzZXJ2YXRpb25zIG9mIG1hdGNoZWQgdW5pdHMKbWF0Y2hjb21wX2NwYSA8LSBjYmluZChQYWlyX0lEID0gbWF0Y2hlZF9kYXRhX0gyJHBhaXJfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc19pZCA9IG1hdGNoZWRfZGF0YV9IMiRjYXNfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGZlbV9zaWcgPSBtYXRjaGVkX2RhdGFfSDIkZmVtX3NpZywKICAgICAgICAgICAgICAgICAgICAgICAgY3BhX0gyID0gbWF0Y2hlZF9kYXRhX0gyJGNwYSwKICAgICAgICAgICAgICAgICAgICAgICAgY3BhX3JiMiA9IG1hdGNoZWRfZGF0YV9yYjIkY3BhKQptYXRjaGNvbXBfY2l2X3NvYyA8LSBjYmluZChQYWlyX0lEID0gbWF0Y2hlZF9kYXRhX0gyJHBhaXJfaWQsCiAgICAgICAgICAgICAgICAgICAgICBjYXNfaWQgPSBtYXRjaGVkX2RhdGFfSDIkY2FzX2lkLAogICAgICAgICAgICAgICAgICAgICAgZmVtX3NpZyA9IG1hdGNoZWRfZGF0YV9IMiRmZW1fc2lnLAogICAgICAgICAgICAgICAgICAgICAgY2l2X3NvY19IMiA9IG1hdGNoZWRfZGF0YV9IMiRjaXZfc29jLAogICAgICAgICAgICAgICAgICAgICAgY2l2X3NvY19yYjIgPSBtYXRjaGVkX2RhdGFfcmIyJGNpdl9zb2MpCm1hdGNoY29tcF9jcGEKbWF0Y2hjb21wX2Npdl9zb2MKYGBgCgojIyMjIEgyIHZzIFIyOiBDb21wYXJpc29uIG9mIFRyZWF0bWVudCBFZmZlY3QgRXN0aW1hdGVzCgpgYGB7ciwgTW9kZWwgUjI6IFRyZWF0bWVudCBlZmZlY3QgZXN0aW1hdGUgKGNwYSl9CgojID09PT09PT09PT0gUnVuIE1hdGNoKCkgd2l0aCBvdXRvbWUgdmFyaWFibGUgKGNwYSkgPT09PT09PT09PT09PT0Kc2V0LnNlZWQoMTIzKQojIE91dGNvbWUKWSAgPC0gZGZfY2xlYW5fcmIyJGNwYQptX291dF9yYjJBIDwtIE1hdGNoKFkgPSBZLCBUciA9IFRyLCBYID0gWCwgV2VpZ2h0Lm1hdHJpeCA9IGdlbm91dF9yYjIsIGVzdGltYW5kID0gIkFUVCIsIHJlcGxhY2UgPSBGQUxTRSkKCiMgPT09PT0gRXN0aW1hdGUgVHJlYXRtZW50IEVmZmVjdCwgU0UsIGFuZCBDSSA9PT09PT0KCnN1bW1hcnkobV9vdXRfcmIyQSkKCkFUVF9lc3QgPC0gbV9vdXRfcmIyQSRlc3QKQVRUX3NlIDwtIDAuMjA0MTIjbV9vdXRfcmIyQSRzZQoKIy0tLS0tIEdldCBDb25maWRlbmNlIEludGVydmFscyAtLS0tLS0KIyBDSSBib3VuZHMgZ2l2ZW4gYnkgcG9pbnQgZXN0aW1hdGUgKy8tIG1hcmdpbiBvZiBlcnJvcgojIENWIGZvciA5NSUgaW50ZXJ2YWwgaXMgMS45NgpjaV9sb3dlcjk1IDwtIEFUVF9lc3QgLSAxLjk2ICogQVRUX3NlCmNpX3VwcGVyOTUgPC0gQVRUX2VzdCArIDEuOTYgKiBBVFRfc2UKIyBDViBmb3IgOTklIGludGVydmFsIGlzIDIuNTc2CmNpX2xvd2VyOTkgPC0gQVRUX2VzdCAtIDIuNTc2ICogQVRUX3NlCmNpX3VwcGVyOTkgPC0gQVRUX2VzdCArIDIuNTc2ICogQVRUX3NlCgpwcmludChwYXN0ZSgiRXN0aW1hdGVkIEFUVDoiLCByb3VuZChBVFRfZXN0LCAyKSkpCnByaW50KHBhc3RlKCJTdGFuZGFyZCBFcnJvcjoiLCByb3VuZChBVFRfc2UsIDIpKSkKcHJpbnQocGFzdGUoIjk1JSBDSTogWyIsIHJvdW5kKGNpX2xvd2VyOTUsIDMpLCAiLCIsIHJvdW5kKGNpX3VwcGVyOTUsIDMpLCAiXSIpKQpwcmludChwYXN0ZSgiOTklIENJOiBbIiwgcm91bmQoY2lfbG93ZXI5OSwgMyksICIsIiwgcm91bmQoY2lfdXBwZXI5OSwgMyksICJdIikpCmBgYAoKYGBge3IsIE1vZGVsIFIyOiBUcmVhdG1lbnQgZWZmZWN0IGVzdGltYXRlIChjaXZfc29jKX0Kc2V0LnNlZWQoMTIzKQojID09PT09PT09PT0gUnVuIE1hdGNoKCkgd2l0aCBvdXRvbWUgdmFyaWFibGUgKGNpdl9zb2MpID09PT09PT09PT09PT09CiMgT3V0Y29tZQpZICA8LSBkZl9jbGVhbl9yYjIkY2l2X3NvYwptX291dF9yYjJCIDwtIE1hdGNoKFkgPSBZLCBUciA9IFRyLCBYID0gWCwgV2VpZ2h0Lm1hdHJpeCA9IGdlbm91dF9yYjIsIGVzdGltYW5kID0gIkFUVCIsIHJlcGxhY2UgPSBGQUxTRSkKCiMgPT09PT0gRXN0aW1hdGUgVHJlYXRtZW50IEVmZmVjdCwgU0UsIGFuZCBDSSA9PT09PT0Kc3VtbWFyeShtX291dF9yYjJCKQoKQVRUX2VzdCA8LSBtX291dF9yYjJCJGVzdApBVFRfc2UgPC0gMC4xNTIxNSAjbV9vdXRfcmIyQiRzZQoKIy0tLS0tIEdldCBDb25maWRlbmNlIEludGVydmFscyAtLS0tLS0KIyBDSSBib3VuZHMgZ2l2ZW4gYnkgcG9pbnQgZXN0aW1hdGUgKy8tIG1hcmdpbiBvZiBlcnJvcgojIENWIGZvciA5NSUgaW50ZXJ2YWwgaXMgMS45NgpjaV9sb3dlcjk1IDwtIEFUVF9lc3QgLSAxLjk2ICogQVRUX3NlCmNpX3VwcGVyOTUgPC0gQVRUX2VzdCArIDEuOTYgKiBBVFRfc2UKIyBDViBmb3IgOTklIGludGVydmFsIGlzIDIuNTc2CmNpX2xvd2VyOTkgPC0gQVRUX2VzdCAtIDIuNTc2ICogQVRUX3NlCmNpX3VwcGVyOTkgPC0gQVRUX2VzdCArIDIuNTc2ICogQVRUX3NlCgpwcmludChwYXN0ZSgiRXN0aW1hdGVkIEFUVDoiLCByb3VuZChBVFRfZXN0LCAzKSkpCnByaW50KHBhc3RlKCJTdGFuZGFyZCBFcnJvcjoiLCByb3VuZChBVFRfc2UsIDMpKSkKcHJpbnQocGFzdGUoIjk1JSBDSTogWyIsIHJvdW5kKGNpX2xvd2VyOTUsIDMpLCAiLCIsIHJvdW5kKGNpX3VwcGVyOTUsIDMpLCAiXSIpKQpwcmludChwYXN0ZSgiOTklIENJOiBbIiwgcm91bmQoY2lfbG93ZXI5OSwgMyksICIsIiwgcm91bmQoY2lfdXBwZXI5OSwgMyksICJdIikpCmBgYAoKYGBge3IsIFJvYnVzdG5lc3MgQ2hlY2sgSDIgdnMuIFIyOiBDb21wYXJlIEVzdGltYXRlc30KcHJpbnQgKCJIMkEgdnMuIFIyQSIpCnN1bW1hcnkobV9vdXRfSDJBKQpzdW1tYXJ5KG1fb3V0X3JiMkEpCnByaW50ICgiSDJCIHZzLiBSMkIiKQpzdW1tYXJ5KG1fb3V0X0gyQikKc3VtbWFyeShtX291dF9yYjJCKQpgYGAK